From 652caa5b67b096b13c34f299db238e1daeab1f67 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 13:27:28 -0400 Subject: b43: update hw/fw version info in wiphy struct This makes the information available through ethtool... Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 20631ae2ddd7..294b68895822 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2280,6 +2280,7 @@ out: static int b43_upload_microcode(struct b43_wldev *dev) { + struct wiphy *wiphy = dev->wl->hw->wiphy; const size_t hdr_len = sizeof(struct b43_fw_header); const __be32 *data; unsigned int i, len; @@ -2405,6 +2406,10 @@ static int b43_upload_microcode(struct b43_wldev *dev) } } + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", + dev->fw.rev, dev->fw.patch); + wiphy->hw_version = dev->dev->id.coreid; + if (b43_is_old_txhdr_format(dev)) { /* We're over the deadline, but we keep support for old fw * until it turns out to be in major conflict with something new. */ -- cgit v1.2.3 From bcf3c7c5264f06cd2542e6bece94c65bf0ac482b Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 13:30:15 -0400 Subject: b43legacy: update hw/fw version info in wiphy struct This makes the information available through ethtool... Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1713f5f7a58b..67f18ecdb3bf 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1623,6 +1623,7 @@ error: static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) { + struct wiphy *wiphy = dev->wl->hw->wiphy; const size_t hdr_len = sizeof(struct b43legacy_fw_header); const __be32 *data; unsigned int i; @@ -1732,6 +1733,10 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) dev->fw.rev = fwrev; dev->fw.patch = fwpatch; + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", + dev->fw.rev, dev->fw.patch); + wiphy->hw_version = dev->dev->id.coreid; + return 0; error: -- cgit v1.2.3 From 37269e805267ba68fe8c5d693ccf0ec5727155fa Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 13:44:44 -0400 Subject: p54: update fw version info in wiphy struct This makes the information available through ethtool... Signed-off-by: John W. Linville --- drivers/net/wireless/p54/fwio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 47006bca4852..6f027ab4c775 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -123,10 +123,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) bootrec = (struct bootrec *)&bootrec->data[len]; } - if (fw_version) + if (fw_version) { wiphy_info(priv->hw->wiphy, "fw rev %s - softmac protocol %x.%x\n", fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); + snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version), + "%s - %x.%x", fw_version, + priv->fw_var >> 8, priv->fw_var & 0xff); + } if (priv->fw_var < 0x500) wiphy_info(priv->hw->wiphy, -- cgit v1.2.3 From dd358c9a45fc27f90e77992cf77117ab6e2fb467 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 13:50:39 -0400 Subject: rt2x00: update fw version info in wiphy struct This makes the information available through ethtool... Signed-off-by: John W. Linville Acked-by: Ivo van Doorn --- drivers/net/wireless/rt2x00/rt2x00firmware.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index b818a43c4672..f0e1eb72befc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", fw->data[fw->size - 4], fw->data[fw->size - 3]); + snprintf(rt2x00dev->hw->wiphy->fw_version, + sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", + fw->data[fw->size - 4], fw->data[fw->size - 3]); retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); switch (retval) { -- cgit v1.2.3 From 68e887ef21dfd9adcf896ef92a9676bf9036a0aa Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 13:58:48 -0400 Subject: zd1211rw: update fw version info in wiphy struct This makes the information available through ethtool... Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index b2af3c549bb3..87a95bcfee57 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -973,6 +973,7 @@ static void dump_fw_registers(struct zd_chip *chip) static int print_fw_version(struct zd_chip *chip) { + struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy; int r; u16 version; @@ -982,6 +983,10 @@ static int print_fw_version(struct zd_chip *chip) return r; dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version); + + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), + "%04hx", version); + return 0; } -- cgit v1.2.3 From 4e6cbfd09c66893e5134c9896e9af353c2322b66 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 16:14:13 -0400 Subject: mac80211: support use of NAPI for bottom-half processing This patch implement basic infrastructure to support use of NAPI by mac80211-based hardware drivers. Because mac80211 devices can support multiple netdevs, a dummy netdev is used for interfacing with the NAPI code in the core of the network stack. That structure is hidden from the hardware drivers, but the actual napi_struct is exposed in the ieee80211_hw structure so that the poll routines in drivers can retrieve that structure. Hardware drivers can also specify their own weight value for NAPI polling. Signed-off-by: John W. Linville --- include/net/mac80211.h | 24 ++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 5 +++++ net/mac80211/iface.c | 4 ++++ net/mac80211/main.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b0787a1dea90..3f1e03b521ec 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1102,6 +1102,10 @@ enum ieee80211_hw_flags { * * @max_rates: maximum number of alternate rate retry stages * @max_rate_tries: maximum number of tries for each stage + * + * @napi_weight: weight used for NAPI polling. You must specify an + * appropriate value here if a napi_poll operation is provided + * by your driver. */ struct ieee80211_hw { struct ieee80211_conf conf; @@ -1113,6 +1117,7 @@ struct ieee80211_hw { int channel_change_time; int vif_data_size; int sta_data_size; + int napi_weight; u16 queues; u16 max_listen_interval; s8 max_signal; @@ -1687,6 +1692,8 @@ enum ieee80211_ampdu_mlme_action { * switch operation for CSAs received from the AP may implement this * callback. They must then call ieee80211_chswitch_done() to indicate * completion of the channel switch. + * + * @napi_poll: Poll Rx queue for incoming data frames. */ struct ieee80211_ops { int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1752,6 +1759,7 @@ struct ieee80211_ops { void (*flush)(struct ieee80211_hw *hw, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch); + int (*napi_poll)(struct ieee80211_hw *hw, int budget); }; /** @@ -1897,6 +1905,22 @@ void ieee80211_free_hw(struct ieee80211_hw *hw); */ void ieee80211_restart_hw(struct ieee80211_hw *hw); +/** ieee80211_napi_schedule - schedule NAPI poll + * + * Use this function to schedule NAPI polling on a device. + * + * @hw: the hardware to start polling + */ +void ieee80211_napi_schedule(struct ieee80211_hw *hw); + +/** ieee80211_napi_complete - complete NAPI polling + * + * Use this function to finish NAPI polling on a device. + * + * @hw: the hardware to stop polling + */ +void ieee80211_napi_complete(struct ieee80211_hw *hw); + /** * ieee80211_rx - receive frame * diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 65e0ed6c2975..79d56454484a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -870,6 +870,11 @@ struct ieee80211_local { struct dentry *keys; } debugfs; #endif + + /* dummy netdev for use w/ NAPI */ + struct net_device napi_dev; + + struct napi_struct napi; }; static inline struct ieee80211_sub_if_data * diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ebbe264e2b0b..c1008a9d7bfb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -187,6 +187,8 @@ static int ieee80211_open(struct net_device *dev) res = drv_start(local); if (res) goto err_del_bss; + if (local->ops->napi_poll) + napi_enable(&local->napi); /* we're brought up, everything changes */ hw_reconf_flags = ~0; ieee80211_led_radio(local, true); @@ -519,6 +521,8 @@ static int ieee80211_stop(struct net_device *dev) ieee80211_recalc_ps(local, -1); if (local->open_count == 0) { + if (local->ops->napi_poll) + napi_disable(&local->napi); ieee80211_clear_tx_pending(local); ieee80211_stop_device(local); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 798a91b100cc..1ed956c9cb8b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -390,6 +390,30 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, } #endif +static int ieee80211_napi_poll(struct napi_struct *napi, int budget) +{ + struct ieee80211_local *local = + container_of(napi, struct ieee80211_local, napi); + + return local->ops->napi_poll(&local->hw, budget); +} + +void ieee80211_napi_schedule(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + napi_schedule(&local->napi); +} +EXPORT_SYMBOL(ieee80211_napi_schedule); + +void ieee80211_napi_complete(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + napi_complete(&local->napi); +} +EXPORT_SYMBOL(ieee80211_napi_complete); + struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -494,6 +518,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, skb_queue_head_init(&local->skb_queue); skb_queue_head_init(&local->skb_queue_unreliable); + /* init dummy netdev for use w/ NAPI */ + init_dummy_netdev(&local->napi_dev); + return local_to_hw(local); } EXPORT_SYMBOL(ieee80211_alloc_hw); @@ -683,6 +710,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) goto fail_ifa; #endif + netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, + local->hw.napi_weight); + return 0; #ifdef CONFIG_INET -- cgit v1.2.3 From 030725d2c7c1fafec7ede618647bf30ed79601f0 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 16:14:14 -0400 Subject: rtl8180: use NAPI for bottom-half processing Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 128 ++++++++++++++++------------- 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index b50c39aaec05..02d0f71d0faa 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -99,19 +99,66 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) } } -static void rtl8180_handle_rx(struct ieee80211_hw *dev) +static void rtl8180_handle_tx(struct ieee80211_hw *dev) { struct rtl8180_priv *priv = dev->priv; - unsigned int count = 32; + struct rtl8180_tx_ring *ring; + int prio; + + spin_lock(&priv->lock); + + for (prio = 3; prio >= 0; prio--) { + ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u32 flags = le32_to_cpu(entry->flags); + + if (flags & RTL818X_TX_DESC_FLAG_OWN) + break; + + ring->idx = (ring->idx + 1) % ring->entries; + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), + skb->len, PCI_DMA_TODEVICE); + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && + (flags & RTL818X_TX_DESC_FLAG_TX_OK)) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = (flags & 0xFF) + 1; + info->status.rates[1].idx = -1; + + ieee80211_tx_status(dev, skb); + if (ring->entries - skb_queue_len(&ring->queue) == 2) + ieee80211_wake_queue(dev, prio); + } + } + + spin_unlock(&priv->lock); +} + +static int rtl8180_poll(struct ieee80211_hw *dev, int budget) +{ + struct rtl8180_priv *priv = dev->priv; + unsigned int count = 0; u8 signal, agc, sq; - while (count--) { + /* handle pending Tx queue cleanup */ + rtl8180_handle_tx(dev); + + while (count++ < budget) { struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; u32 flags = le32_to_cpu(entry->flags); if (flags & RTL818X_RX_DESC_FLAG_OWN) - return; + break; if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | RTL818X_RX_DESC_FLAG_FOF | @@ -151,7 +198,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(dev, skb); + ieee80211_rx(dev, skb); skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; @@ -168,41 +215,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); priv->rx_idx = (priv->rx_idx + 1) % 32; } -} - -static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) -{ - struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - u32 flags = le32_to_cpu(entry->flags); - - if (flags & RTL818X_TX_DESC_FLAG_OWN) - return; - - ring->idx = (ring->idx + 1) % ring->entries; - skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), - skb->len, PCI_DMA_TODEVICE); - - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (flags & RTL818X_TX_DESC_FLAG_TX_OK)) - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.rates[0].count = (flags & 0xFF) + 1; - info->status.rates[1].idx = -1; + if (count < budget) { + /* disable polling */ + ieee80211_napi_complete(dev); - ieee80211_tx_status_irqsafe(dev, skb); - if (ring->entries - skb_queue_len(&ring->queue) == 2) - ieee80211_wake_queue(dev, prio); + /* enable interrupts */ + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); } + + return count; } static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) @@ -211,31 +233,17 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) struct rtl8180_priv *priv = dev->priv; u16 reg; - spin_lock(&priv->lock); reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); - if (unlikely(reg == 0xFFFF)) { - spin_unlock(&priv->lock); + if (unlikely(reg == 0xFFFF)) return IRQ_HANDLED; - } rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); - if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) - rtl8180_handle_tx(dev, 3); - - if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) - rtl8180_handle_tx(dev, 2); - - if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) - rtl8180_handle_tx(dev, 1); - - if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) - rtl8180_handle_tx(dev, 0); - - if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) - rtl8180_handle_rx(dev); + /* disable interrupts */ + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); - spin_unlock(&priv->lock); + /* enable polling */ + ieee80211_napi_schedule(dev); return IRQ_HANDLED; } @@ -247,7 +255,6 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) struct rtl8180_priv *priv = dev->priv; struct rtl8180_tx_ring *ring; struct rtl8180_tx_desc *entry; - unsigned long flags; unsigned int idx, prio; dma_addr_t mapping; u32 tx_flags; @@ -294,7 +301,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) plcp_len |= 1 << 15; } - spin_lock_irqsave(&priv->lock, flags); + spin_lock(&priv->lock); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) @@ -318,7 +325,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) if (ring->entries - skb_queue_len(&ring->queue) < 2) ieee80211_stop_queue(dev, prio); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock(&priv->lock); rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); @@ -861,6 +868,7 @@ static const struct ieee80211_ops rtl8180_ops = { .prepare_multicast = rtl8180_prepare_multicast, .configure_filter = rtl8180_configure_filter, .get_tsf = rtl8180_get_tsf, + .napi_poll = rtl8180_poll, }; static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) @@ -992,6 +1000,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, dev->queues = 1; dev->max_signal = 65; + dev->napi_weight = 64; + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); reg &= RTL818X_TX_CONF_HWVER_MASK; switch (reg) { -- cgit v1.2.3 From 0f956e7107fe5069767323a1bf2a522f5f37cc2c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 21:50:29 -0400 Subject: rtl8180: use RTL818X_MSR_ADHOC for IBSS connection Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 02d0f71d0faa..9544eb1a23dc 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -790,6 +790,7 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, struct rtl8180_priv *priv = dev->priv; struct rtl8180_vif *vif_priv; int i; + u8 reg; vif_priv = (struct rtl8180_vif *)&vif->drv_priv; @@ -798,12 +799,14 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, rtl818x_iowrite8(priv, &priv->map->BSSID[i], info->bssid[i]); - if (is_valid_ether_addr(info->bssid)) - rtl818x_iowrite8(priv, &priv->map->MSR, - RTL818X_MSR_INFRA); - else - rtl818x_iowrite8(priv, &priv->map->MSR, - RTL818X_MSR_NO_LINK); + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg = RTL818X_MSR_ADHOC; + else + reg = RTL818X_MSR_INFRA; + } else + reg = RTL818X_MSR_NO_LINK; + rtl818x_iowrite8(priv, &priv->map->MSR, reg); } if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) -- cgit v1.2.3 From 31a5cddaaed9c04ef653e3c2900cfb5a646fe686 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 29 Jul 2010 21:52:59 -0400 Subject: rtl8187: consolidate MSR writes in rtl8187_bss_info_changed Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5738a55c1b06..0801c1d7c8d4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, else reg = 0; - if (is_valid_ether_addr(info->bssid)) { + if (is_valid_ether_addr(info->bssid)) reg |= RTL818X_MSR_INFRA; - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - } else { + else reg |= RTL818X_MSR_NO_LINK; - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - } + + rtl818x_iowrite8(priv, &priv->map->MSR, reg); mutex_unlock(&priv->conf_mutex); } -- cgit v1.2.3 From c61029c77fb68d7a182c0ae010f0f9dcae4e196c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 5 Aug 2010 14:26:24 -0400 Subject: wireless: upcase alpha2 values in queue_regulatory_request This provides a little more flexibility for human users, and it allows us to use isalpha rather than the custom is_alpha_upper. Signed-off-by: John W. Linville --- net/wireless/reg.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index f180db0de66c..b0d9a08447c9 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -181,14 +182,6 @@ static bool is_alpha2_set(const char *alpha2) return false; } -static bool is_alpha_upper(char letter) -{ - /* ASCII A - Z */ - if (letter >= 65 && letter <= 90) - return true; - return false; -} - static bool is_unknown_alpha2(const char *alpha2) { if (!alpha2) @@ -220,7 +213,7 @@ static bool is_an_alpha2(const char *alpha2) { if (!alpha2) return false; - if (is_alpha_upper(alpha2[0]) && is_alpha_upper(alpha2[1])) + if (isalpha(alpha2[0]) && isalpha(alpha2[1])) return true; return false; } @@ -1399,6 +1392,11 @@ static DECLARE_WORK(reg_work, reg_todo); static void queue_regulatory_request(struct regulatory_request *request) { + if (isalpha(request->alpha2[0])) + request->alpha2[0] = toupper(request->alpha2[0]); + if (isalpha(request->alpha2[1])) + request->alpha2[1] = toupper(request->alpha2[1]); + spin_lock(®_requests_lock); list_add_tail(&request->list, ®_requests_list); spin_unlock(®_requests_lock); -- cgit v1.2.3 From 1a7123cdd9f49cf1c908fb2c16d26f279c88d8c9 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 5 Aug 2010 14:39:31 -0400 Subject: iwlwifi: disable aspm by default Some iwlwifi devices inexplicably disconnect themselves from the PCI-E bus causing the predictable failures. This seems to disappear if ASPM is disabled. Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 35337b1e7cac..49a7a9889c55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -3968,6 +3969,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /************************** * 2. Initializing PCI bus **************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + if (pci_enable_device(pdev)) { err = -ENODEV; goto out_ieee80211_free_hw; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d24eb47d3705..bc08242db2ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -3963,6 +3964,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e /*************************** * 2. Initializing PCI bus * *************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + if (pci_enable_device(pdev)) { err = -ENODEV; goto out_ieee80211_free_hw; -- cgit v1.2.3 From aa0d52c5e7f352ce9725c8940fe2458f2c04e049 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 10 Aug 2010 13:08:11 -0400 Subject: ipw2100: avoid warning from pointer cast in call to IPW_DEBUG_TX drivers/net/wireless/ipw2x00/ipw2100.c: In function 'ipw2100_tx_send_commands': drivers/net/wireless/ipw2x00/ipw2100.c:3063: warning: cast to pointer from integer of different size This changes the cast and the conversion to match other usage of the same value in calls to IPW_DEBUG_TX. Reported-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index a146240f7ddb..e4ed479c36f5 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -3064,9 +3064,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) packet = list_entry(element, struct ipw2100_tx_packet, list); - IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", + IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n", &txq->drv[txq->next], - (void *)(txq->nic + txq->next * + (u32) (txq->nic + txq->next * sizeof(struct ipw2100_bd))); packet->index = txq->next; -- cgit v1.2.3 From 13eb670c104e15e06d38f3a210cfaf467a9c66de Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 10 Aug 2010 13:22:24 -0400 Subject: iwm3200wifi: remove comparison to WIFI_IF_NTFY_MAX in iwm_ntf_wifi_if_wrapper drivers/net/wireless/iwmc3200wifi/rx.c: In function 'iwm_ntf_wifi_if_wrapper': drivers/net/wireless/iwmc3200wifi/rx.c:1198: warning: comparison is always true due to limited range of data type This is, of course, because the value of WIFI_IF_NTFY_MAX is 0xff and hdr->oid is a u8. This is obviously an attempt to verify the range on an input value, but since it has no effect it can simply be removed. Signed-off-by: John W. Linville Acked-by: Samuel Ortiz --- drivers/net/wireless/iwmc3200wifi/rx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index c02fcedea9fa..a944893ae3ca 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -1195,11 +1195,8 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf, IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: " "oid is 0x%x\n", hdr->oid); - if (hdr->oid <= WIFI_IF_NTFY_MAX) { - set_bit(hdr->oid, &iwm->wifi_ntfy[0]); - wake_up_interruptible(&iwm->wifi_ntfy_queue); - } else - return -EINVAL; + set_bit(hdr->oid, &iwm->wifi_ntfy[0]); + wake_up_interruptible(&iwm->wifi_ntfy_queue); switch (hdr->oid) { case UMAC_WIFI_IF_CMD_SET_PROFILE: -- cgit v1.2.3 From 84c164a34ffe67908a932a2d641ec1a80c2d5435 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 6 Aug 2010 15:31:45 -0400 Subject: b43: move hwrng registration driver to wireless core initialization ...and unregistration to core shutdown. Previously, the driver remained registered even when the hardware was shutdown. That causes the driver to return -ENODEV if the b43 device is IFF_DOWN. This change causes the driver to disappear in that case, allowing /dev/hwrng to still function if another hwrng device is available. Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 294b68895822..a3e2f2bfe3a7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4255,6 +4255,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED); if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) return; + + /* Unregister HW RNG driver */ + b43_rng_exit(dev->wl); + b43_set_status(dev, B43_STAT_UNINIT); /* Stop the microcode PSM. */ @@ -4384,6 +4388,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) b43_set_status(dev, B43_STAT_INITIALIZED); + /* Register HW RNG driver */ + b43_rng_init(dev->wl); + out: return err; @@ -4989,7 +4996,6 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id) if (err) goto err_one_core_detach; b43_leds_register(wl->current_dev); - b43_rng_init(wl); } out: @@ -5025,7 +5031,6 @@ static void b43_remove(struct ssb_device *dev) b43_one_core_detach(dev); if (list_empty(&wl->devlist)) { - b43_rng_exit(wl); b43_leds_unregister(wl); /* Last core on the chip unregistered. * We can destroy common struct b43_wl. -- cgit v1.2.3 From 4d7ede7f5ad58c5316335b9018ddef58bd687def Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 26 May 2010 13:33:31 -0400 Subject: rt2x00: do not shortcut rt2x00lib_config_antenna This function was exiting early if the existing diversity settings were unchanged. Unfortunately, in some cases the antenna configuration is not initialized at all. https://bugzilla.kernel.org/show_bug.cgi?id=14751 Signed-off-by: John W. Linville Acked-by: Ivo van Doorn Cc: Gertjan van Wingerde --- drivers/net/wireless/rt2x00/rt2x00config.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 953dc4f2c6af..fb23af40008b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -126,11 +126,6 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * ANTENNA_SW_DIVERSITY state to the driver. * If that happens, fallback to hardware defaults, * or our own default. - * If diversity handling is active for a particular antenna, - * we shouldn't overwrite that antenna. - * The calls to rt2x00lib_config_antenna_check() - * might have caused that we restore back to the already - * active setting. If that has happened we can quit. */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); @@ -142,9 +137,6 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, else config.tx = active->tx; - if (config.rx == active->rx && config.tx == active->tx) - return; - /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. -- cgit v1.2.3 From ffd2778bb984afe3cc264e22a125c06587020aa3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 29 Jul 2010 17:36:43 +0200 Subject: mac80211: fix driver offchannel notification when the channel does not change When running in client mode and associating to an AP, the channel change is usually performed with the offchannel flag still set. However after the assoc is complete, the following channel change event is suppressed because the run time channel is already set to the operating channel. Fix this by sending channel change notifications to the driver even if only the offchannel flag changes. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1ed956c9cb8b..18b8df922c60 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -99,11 +99,13 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) int ret = 0; int power; enum nl80211_channel_type channel_type; + u32 offchannel_flag; might_sleep(); scan_chan = local->scan_channel; + offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; if (scan_chan) { chan = scan_chan; channel_type = NL80211_CHAN_NO_HT; @@ -117,8 +119,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) channel_type = local->_oper_channel_type; local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; } + offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; - if (chan != local->hw.conf.channel || + if (offchannel_flag || chan != local->hw.conf.channel || channel_type != local->hw.conf.channel_type) { local->hw.conf.channel = chan; local->hw.conf.channel_type = channel_type; -- cgit v1.2.3 From 1e51b2ff0a33797476932a68d36136921e4e1b05 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 29 Jul 2010 22:56:22 -0400 Subject: ath9k: add fastcc to debug print for channel change This helps us debug channel changes better. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3caa32316e7b..2ab3df22fbb5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -226,9 +226,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, caldata = &aphy->caldata; ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", + "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", sc->sc_ah->curchan->channel, - channel->center_freq, conf_is_ht40(conf)); + channel->center_freq, conf_is_ht40(conf), + fastcc); spin_lock_bh(&sc->sc_resetlock); -- cgit v1.2.3 From 4083858c8b309068024ba43672d831999d69ba3f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 29 Jul 2010 23:12:53 -0700 Subject: libertas: better scan response debugging Make it a bit easier to debug scan results in the future. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 51a96f5a342d..8bf88fa43690 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -524,20 +524,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, pos = scanresp->bssdesc_and_tlvbuffer; + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer, + scanresp->bssdescriptsize); + tsfdesc = pos + bsssize; tsfsize = 4 + 8 * scanresp->nr_sets; + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize); /* Validity check: we expect a Marvell-Local TLV */ i = get_unaligned_le16(tsfdesc); tsfdesc += 2; - if (i != TLV_TYPE_TSFTIMESTAMP) + if (i != TLV_TYPE_TSFTIMESTAMP) { + lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i); goto done; + } + /* Validity check: the TLV holds TSF values with 8 bytes each, so * the size in the TLV must match the nr_sets value */ i = get_unaligned_le16(tsfdesc); tsfdesc += 2; - if (i / 8 != scanresp->nr_sets) + if (i / 8 != scanresp->nr_sets) { + lbs_deb_scan("scan response: invalid number of TSF timestamp " + "sets (expected %d got %d)\n", scanresp->nr_sets, + i / 8); goto done; + } for (i = 0; i < scanresp->nr_sets; i++) { const u8 *bssid; @@ -579,8 +590,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, id = *pos++; elen = *pos++; left -= 2; - if (elen > left || elen == 0) + if (elen > left || elen == 0) { + lbs_deb_scan("scan response: invalid IE fmt\n"); goto done; + } + if (id == WLAN_EID_DS_PARAMS) chan_no = *pos; if (id == WLAN_EID_SSID) { @@ -611,7 +625,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, capa, intvl, ie, ielen, LBS_SCAN_RSSI_TO_MBM(rssi), GFP_KERNEL); - } + } else + lbs_deb_scan("scan response: missing BSS channel IE\n"); + tsfdesc += 8; } ret = 0; -- cgit v1.2.3 From 86df5f7284ffdea9923153764691e490abf36081 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 29 Jul 2010 23:14:33 -0700 Subject: libertas: better association request debugging Bring back the comment about FW v5 status codes from the pre-cfg80211 driver, and let through status codes that aren't remapped by the firmware. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 8bf88fa43690..08487a848e05 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1117,7 +1117,7 @@ static int lbs_associate(struct lbs_private *priv, lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp); /* add auth type TLV */ - if (priv->fwrelease >= 0x09000000) + if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9) pos += lbs_add_auth_type_tlv(pos, sme->auth_type); /* add WPA/WPA2 TLV */ @@ -1128,6 +1128,9 @@ static int lbs_associate(struct lbs_private *priv, (u16)(pos - (u8 *) &cmd->iebuf); cmd->hdr.size = cpu_to_le16(len); + lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd, + le16_to_cpu(cmd->hdr.size)); + /* store for later use */ memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); @@ -1135,14 +1138,28 @@ static int lbs_associate(struct lbs_private *priv, if (ret) goto done; - /* generate connect message to cfg80211 */ resp = (void *) cmd; /* recast for easier field access */ status = le16_to_cpu(resp->statuscode); - /* Convert statis code of old firmware */ - if (priv->fwrelease < 0x09000000) + /* Older FW versions map the IEEE 802.11 Status Code in the association + * response to the following values returned in resp->statuscode: + * + * IEEE Status Code Marvell Status Code + * 0 -> 0x0000 ASSOC_RESULT_SUCCESS + * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * others -> 0x0003 ASSOC_RESULT_REFUSED + * + * Other response codes: + * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) + * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for + * association response from the AP) + */ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { switch (status) { case 0: break; @@ -1164,11 +1181,16 @@ static int lbs_associate(struct lbs_private *priv, break; default: lbs_deb_assoc("association failure %d\n", status); - status = WLAN_STATUS_UNSPECIFIED_FAILURE; + /* v5 OLPC firmware does return the AP status code if + * it's not one of the values above. Let that through. + */ + break; + } } - lbs_deb_assoc("status %d, capability 0x%04x\n", status, - le16_to_cpu(resp->capability)); + lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, " + "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode), + le16_to_cpu(resp->capability), le16_to_cpu(resp->aid)); resp_ie_len = le16_to_cpu(resp->hdr.size) - sizeof(resp->hdr) @@ -1188,7 +1210,6 @@ static int lbs_associate(struct lbs_private *priv, netif_tx_wake_all_queues(priv->dev); } - done: lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); return ret; -- cgit v1.2.3 From fc88518916793af8ad6a02e05ff254d95c36d875 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 30 Jul 2010 13:23:12 +0200 Subject: mac80211: don't check rates on PLCP error frames Frames that failed PLCP error checks are most likely microwave transmissions (well, maybe not ...) and don't have a proper rate detected, so ignore it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa0f37e4afe4..225e8ee682e3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2615,28 +2615,37 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (WARN_ON(!local->started)) goto drop; - if (status->flag & RX_FLAG_HT) { + if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { /* - * rate_idx is MCS index, which can be [0-76] as documented on: - * - * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n - * - * Anything else would be some sort of driver or hardware error. - * The driver should catch hardware errors. + * Validate the rate, unless a PLCP error means that + * we probably can't have a valid rate here anyway. */ - if (WARN((status->rate_idx < 0 || - status->rate_idx > 76), - "Rate marked as an HT rate but passed " - "status->rate_idx is not " - "an MCS index [0-76]: %d (0x%02x)\n", - status->rate_idx, - status->rate_idx)) - goto drop; - } else { - if (WARN_ON(status->rate_idx < 0 || - status->rate_idx >= sband->n_bitrates)) - goto drop; - rate = &sband->bitrates[status->rate_idx]; + + if (status->flag & RX_FLAG_HT) { + /* + * rate_idx is MCS index, which can be [0-76] + * as documented on: + * + * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n + * + * Anything else would be some sort of driver or + * hardware error. The driver should catch hardware + * errors. + */ + if (WARN((status->rate_idx < 0 || + status->rate_idx > 76), + "Rate marked as an HT rate but passed " + "status->rate_idx is not " + "an MCS index [0-76]: %d (0x%02x)\n", + status->rate_idx, + status->rate_idx)) + goto drop; + } else { + if (WARN_ON(status->rate_idx < 0 || + status->rate_idx >= sband->n_bitrates)) + goto drop; + rate = &sband->bitrates[status->rate_idx]; + } } /* -- cgit v1.2.3 From c240879f3488ae0904a7ba5bdaaa54638b2d8852 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 30 Jul 2010 16:41:08 +0200 Subject: iwlwifi: make scan workqueue functions static We do not need export iwl_bg.*scan.*() functions just for initialize workqueue in other module. Making that functions static helps with iwl-scan.c code review a bit. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-scan.c | 12 ++++-------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 ++---- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4a71dfb10a15..a8fa31f360ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -530,7 +530,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); -void iwl_bg_start_internal_scan(struct work_struct *work); void iwl_internal_short_hw_scan(struct iwl_priv *priv); int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, @@ -542,9 +541,6 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv, u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, struct ieee80211_vif *vif); -void iwl_bg_scan_check(struct work_struct *data); -void iwl_bg_abort_scan(struct work_struct *work); -void iwl_bg_scan_completed(struct work_struct *work); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); /* For faster active scanning, scan will move to the next channel if fewer than diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a4b3663a262f..ac510840519c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -378,7 +378,7 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->start_internal_scan); } -void iwl_bg_start_internal_scan(struct work_struct *work) +static void iwl_bg_start_internal_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, start_internal_scan); @@ -418,9 +418,8 @@ void iwl_bg_start_internal_scan(struct work_struct *work) unlock: mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_start_internal_scan); -void iwl_bg_scan_check(struct work_struct *data) +static void iwl_bg_scan_check(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, scan_check.work); @@ -439,7 +438,6 @@ void iwl_bg_scan_check(struct work_struct *data) } mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_scan_check); /** * iwl_fill_probe_req - fill in all required fields and IE for probe request @@ -489,7 +487,7 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, } EXPORT_SYMBOL(iwl_fill_probe_req); -void iwl_bg_abort_scan(struct work_struct *work) +static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); @@ -504,9 +502,8 @@ void iwl_bg_abort_scan(struct work_struct *work) iwl_send_scan_abort(priv); mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_abort_scan); -void iwl_bg_scan_completed(struct work_struct *work) +static void iwl_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); @@ -555,7 +552,6 @@ void iwl_bg_scan_completed(struct work_struct *work) if (!internal) ieee80211_scan_completed(priv->hw, false); } -EXPORT_SYMBOL(iwl_bg_scan_completed); void iwl_setup_scan_deferred_work(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index bb955d2013e3..de6d592af748 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3737,10 +3737,8 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); - INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); - INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); - INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); - INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); + + iwl_setup_scan_deferred_work(priv); iwl3945_hw_setup_deferred_work(priv); -- cgit v1.2.3 From a1699b75a1db31a1da2f0fc610ee696d02a19280 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 30 Jul 2010 16:46:07 +0200 Subject: mac80211: unify scan and work mutexes Having both scan and work mutexes is not just a bit too fine grained, it also creates issues when there's code that needs both since they then need to be acquired in the right order, which can be hard to do. Therefore, use just a single mutex for both. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/main.c | 4 ++-- net/mac80211/mlme.c | 8 ++++---- net/mac80211/scan.c | 30 +++++++++++++++--------------- net/mac80211/work.c | 35 +++++++++++++++-------------------- 5 files changed, 38 insertions(+), 43 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 79d56454484a..fb4363e148f2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -634,7 +634,6 @@ struct ieee80211_local { /* * work stuff, potentially off-channel (in the future) */ - struct mutex work_mtx; struct list_head work_list; struct timer_list work_timer; struct work_struct work_work; @@ -746,9 +745,10 @@ struct ieee80211_local { */ struct mutex key_mtx; + /* mutex for scan and work locking */ + struct mutex mtx; /* Scanning and BSS list */ - struct mutex scan_mtx; unsigned long scanning; struct cfg80211_ssid scan_ssid; struct cfg80211_scan_request *int_scan_req; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 18b8df922c60..06b9608a2130 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -482,7 +482,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, __hw_addr_init(&local->mc_list); mutex_init(&local->iflist_mtx); - mutex_init(&local->scan_mtx); + mutex_init(&local->mtx); mutex_init(&local->key_mtx); spin_lock_init(&local->filter_lock); @@ -791,7 +791,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) struct ieee80211_local *local = hw_to_local(hw); mutex_destroy(&local->iflist_mtx); - mutex_destroy(&local->scan_mtx); + mutex_destroy(&local->mtx); wiphy_free(local->hw.wiphy); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b6c163ac22da..17e9257a61d8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1751,7 +1751,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_work *wk; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -1783,7 +1783,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, free_work(wk); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); } @@ -2275,7 +2275,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, mutex_unlock(&ifmgd->mtx); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -2294,7 +2294,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, free_work(wk); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); /* * If somebody requests authentication and we haven't diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 872d7b6ef6b3..f31f549733b1 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -255,7 +255,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) trace_api_scan_completed(local, aborted); - mutex_lock(&local->scan_mtx); + mutex_lock(&local->mtx); /* * It's ok to abort a not-yet-running scan (that @@ -267,7 +267,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) aborted = true; if (WARN_ON(!local->scan_req)) { - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); return; } @@ -275,7 +275,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); return; } @@ -291,7 +291,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) local->scan_channel = NULL; /* we only have to protect scan_req and hw/sw scan */ - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); if (was_hw_scan) @@ -639,15 +639,15 @@ void ieee80211_scan_work(struct work_struct *work) struct ieee80211_sub_if_data *sdata = local->scan_sdata; unsigned long next_delay = 0; - mutex_lock(&local->scan_mtx); + mutex_lock(&local->mtx); if (!sdata || !local->scan_req) { - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); return; } if (local->hw_scan_req) { int rc = drv_hw_scan(local, sdata, local->hw_scan_req); - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); if (rc) ieee80211_scan_completed(&local->hw, true); return; @@ -661,14 +661,14 @@ void ieee80211_scan_work(struct work_struct *work) local->scan_sdata = NULL; rc = __ieee80211_start_scan(sdata, req); - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); if (rc) ieee80211_scan_completed(&local->hw, true); return; } - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); /* * Avoid re-scheduling when the sdata is going away. @@ -711,9 +711,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, { int res; - mutex_lock(&sdata->local->scan_mtx); + mutex_lock(&sdata->local->mtx); res = __ieee80211_start_scan(sdata, req); - mutex_unlock(&sdata->local->scan_mtx); + mutex_unlock(&sdata->local->mtx); return res; } @@ -726,7 +726,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, int ret = -EBUSY; enum ieee80211_band band; - mutex_lock(&local->scan_mtx); + mutex_lock(&local->mtx); /* busy scanning */ if (local->scan_req) @@ -761,7 +761,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); unlock: - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); return ret; } @@ -775,10 +775,10 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) * Only call this function when a scan can't be * queued -- mostly at suspend under RTNL. */ - mutex_lock(&local->scan_mtx); + mutex_lock(&local->mtx); abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || (!local->scanning && local->scan_req); - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); if (abortscan) ieee80211_scan_completed(&local->hw, true); diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 81d4ad64184a..b98af64f5862 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -43,7 +43,7 @@ enum work_action { /* utils */ static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) { - WARN_ON(!mutex_is_locked(&local->work_mtx)); + lockdep_assert_held(&local->mtx); } /* @@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, mgmt = (struct ieee80211_mgmt *) skb->data; fc = le16_to_cpu(mgmt->frame_control); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { const u8 *bssid = NULL; @@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, WARN(1, "unexpected: %d", rma); } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); if (rma != WORK_ACT_DONE) goto out; @@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, case WORK_DONE_REQUEUE: synchronize_rcu(); wk->started = false; /* restart */ - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_add_tail(&wk->list, &local->work_list); - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); } out: @@ -890,7 +890,7 @@ static void ieee80211_work_work(struct work_struct *work) ieee80211_recalc_idle(local); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry_safe(wk, tmp, &local->work_list, list) { bool started = wk->started; @@ -995,17 +995,13 @@ static void ieee80211_work_work(struct work_struct *work) run_again(local, jiffies + HZ/2); } - mutex_lock(&local->scan_mtx); - if (list_empty(&local->work_list) && local->scan_req && !local->scanning) ieee80211_queue_delayed_work(&local->hw, &local->scan_work, round_jiffies_relative(0)); - mutex_unlock(&local->scan_mtx); - - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); ieee80211_recalc_idle(local); @@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk) wk->started = false; local = wk->sdata->local; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_add_tail(&wk->list, &local->work_list); - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); ieee80211_queue_work(&local->hw, &local->work_work); } void ieee80211_work_init(struct ieee80211_local *local) { - mutex_init(&local->work_mtx); INIT_LIST_HEAD(&local->work_list); setup_timer(&local->work_timer, ieee80211_work_timer, (unsigned long)local); @@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local = sdata->local; struct ieee80211_work *wk; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) wk->started = true; wk->timeout = jiffies; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); /* run cleanups etc. */ ieee80211_work_work(&local->work_work); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; WARN_ON(1); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); } ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, @@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, struct ieee80211_work *wk, *tmp; bool found = false; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry_safe(wk, tmp, &local->work_list, list) { if ((unsigned long) wk == cookie) { wk->timeout = jiffies; @@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, break; } } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); if (!found) return -ENOENT; -- cgit v1.2.3 From 422f8d19d68d0530dfd37be97bac431ca7435e69 Mon Sep 17 00:00:00 2001 From: Thomas Klute Date: Sat, 31 Jul 2010 12:01:44 +0200 Subject: libertas_tf: if_usb.c: Whitespace cleanup Signed-off-by: Thomas Klute Signed-off-by: John W. Linville --- drivers/net/wireless/libertas_tf/if_usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index b172f5d87a3b..f93260b67fcf 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -54,7 +54,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); /** * if_usb_wrike_bulk_callback - call back to handle URB status * - * @param urb pointer to urb structure + * @param urb pointer to urb structure */ static void if_usb_write_bulk_callback(struct urb *urb) { @@ -187,7 +187,7 @@ static int if_usb_probe(struct usb_interface *intf, lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out); lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n", - cardp->ep_out_size); + cardp->ep_out_size); } } if (!cardp->ep_out_size || !cardp->ep_in_size) { @@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device); /** * usb_tx_block - transfer data to the device * - * @priv pointer to struct lbtf_private + * @priv pointer to struct lbtf_private * @payload pointer to payload data * @nb data length * @data non-zero for data, zero for commands @@ -689,7 +689,7 @@ static void if_usb_receive(struct urb *urb) } default: lbtf_deb_usbd(&cardp->udev->dev, - "libertastf: unknown command type 0x%X\n", recvtype); + "libertastf: unknown command type 0x%X\n", recvtype); kfree_skb(skb); break; } -- cgit v1.2.3 From 139455c3912bfed4bd42824d59c82113cc667f91 Mon Sep 17 00:00:00 2001 From: Thomas Klute Date: Sat, 31 Jul 2010 12:01:45 +0200 Subject: libertas_tf: if_usb.c: Some more formatting fixes Split some long lines to make checkpatch.pl happy. ;-) Signed-off-by: Thomas Klute Signed-off-by: John W. Linville --- drivers/net/wireless/libertas_tf/if_usb.c | 49 +++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index f93260b67fcf..1cf01acef5f0 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -178,14 +178,17 @@ static int if_usb_probe(struct usb_interface *intf, le16_to_cpu(endpoint->wMaxPacketSize); cardp->ep_in = usb_endpoint_num(endpoint); - lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in); - lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size); + lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", + cardp->ep_in); + lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", + cardp->ep_in_size); } else if (usb_endpoint_is_bulk_out(endpoint)) { cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize); cardp->ep_out = usb_endpoint_num(endpoint); - lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out); + lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", + cardp->ep_out); lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size); } @@ -318,10 +321,12 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) { lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n"); - lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n", - cardp->fwseqnum, cardp->totalbytes); + lbtf_deb_usb2(&cardp->udev->dev, + "seqnum = %d totalbytes = %d\n", + cardp->fwseqnum, cardp->totalbytes); } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { - lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n"); + lbtf_deb_usb2(&cardp->udev->dev, + "Host has finished FW downloading\n"); lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n"); /* Host has finished FW downloading @@ -400,7 +405,8 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, urb->transfer_flags |= URB_ZERO_PACKET; if (usb_submit_urb(urb, GFP_ATOMIC)) { - lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); + lbtf_deb_usbd(&cardp->udev->dev, + "usb_submit_urb failed: %d\n", ret); goto tx_ret; } @@ -438,10 +444,12 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; - lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); + lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", + cardp->rx_urb); ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC); if (ret) { - lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); + lbtf_deb_usbd(&cardp->udev->dev, + "Submit Rx URB failed: %d\n", ret); kfree_skb(skb); cardp->rx_skb = NULL; lbtf_deb_leave(LBTF_DEB_USB); @@ -522,14 +530,14 @@ static void if_usb_receive_fwload(struct urb *urb) } } else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) { pr_info("boot cmd response cmd_tag error (%d)\n", - bcmdresp.cmd); + bcmdresp.cmd); } else if (bcmdresp.result != BOOT_CMD_RESP_OK) { pr_info("boot cmd response result error (%d)\n", - bcmdresp.result); + bcmdresp.result); } else { cardp->bootcmdresp = 1; lbtf_deb_usbd(&cardp->udev->dev, - "Received valid boot command response\n"); + "Received valid boot command response\n"); } kfree_skb(skb); @@ -541,19 +549,23 @@ static void if_usb_receive_fwload(struct urb *urb) syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader), GFP_ATOMIC); if (!syncfwheader) { - lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); + lbtf_deb_usbd(&cardp->udev->dev, + "Failure to allocate syncfwheader\n"); kfree_skb(skb); lbtf_deb_leave(LBTF_DEB_USB); return; } if (!syncfwheader->cmd) { - lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); - lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", - le32_to_cpu(syncfwheader->seqnum)); + lbtf_deb_usb2(&cardp->udev->dev, + "FW received Blk with correct CRC\n"); + lbtf_deb_usb2(&cardp->udev->dev, + "FW received Blk seqnum = %d\n", + le32_to_cpu(syncfwheader->seqnum)); cardp->CRC_OK = 1; } else { - lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n"); + lbtf_deb_usbd(&cardp->udev->dev, + "FW received Blk with CRC error\n"); cardp->CRC_OK = 0; } @@ -666,7 +678,8 @@ static void if_usb_receive(struct urb *urb) { /* Event cause handling */ u32 event_cause = le32_to_cpu(pkt[1]); - lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause); + lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", + event_cause); /* Icky undocumented magic special case */ if (event_cause & 0xffff0000) { -- cgit v1.2.3 From 3867fe0477a1e23df3d05131320d7b0075a9bed0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 31 Jul 2010 08:34:05 -0700 Subject: iwlwifi: make iwl_hw_detect static to _agn iwl_hw_detect() only used by _agn, make it static Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 8 -------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d3de5096a620..8d4a2b569f05 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3883,6 +3883,13 @@ static struct ieee80211_ops iwl_hw_ops = { .flush = iwl_mac_flush, }; +static void iwl_hw_detect(struct iwl_priv *priv) +{ + priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); + priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); +} + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2c03c6e20a72..db8f15f3df46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -183,14 +183,6 @@ out: } EXPORT_SYMBOL(iwl_alloc_all); -void iwl_hw_detect(struct iwl_priv *priv) -{ - priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); - priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); -} -EXPORT_SYMBOL(iwl_hw_detect); - /* * QoS support */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a8fa31f360ea..ac16f582d6d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -347,7 +347,6 @@ struct iwl_cfg { struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, struct ieee80211_ops *hw_ops); -void iwl_hw_detect(struct iwl_priv *priv); void iwl_activate_qos(struct iwl_priv *priv); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); -- cgit v1.2.3 From 49ded76bd52f1341671f767a2f5121cb4eb8cf6e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 31 Jul 2010 08:34:06 -0700 Subject: iwlagn: log pci revision id Log the information after reading the PCI_REVISION_ID from pci config space, Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8d4a2b569f05..5c1ea0b2c6a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3888,6 +3888,7 @@ static void iwl_hw_detect(struct iwl_priv *priv) priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); } static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3 From 07d4f1ad2c21273f0f89a3d2202d22fcaf901439 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 31 Jul 2010 08:34:08 -0700 Subject: iwlwifi: make iwl_set_hw_params static to _agn iwl_set_hw_params() only used by _agn, make it static Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 19 ------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5c1ea0b2c6a2..8684f2639716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3891,6 +3891,24 @@ static void iwl_hw_detect(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); } +static int iwl_set_hw_params(struct iwl_priv *priv) +{ + priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; + priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; + if (priv->cfg->mod_params->amsdu_size_8K) + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); + else + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); + + priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; + + if (priv->cfg->mod_params->disable_11n) + priv->cfg->sku &= ~IWL_SKU_N; + + /* Device-specific setup */ + return priv->cfg->ops->lib->set_hw_params(priv); +} + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index db8f15f3df46..78882f9ab459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1365,25 +1365,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_configure_filter); -int iwl_set_hw_params(struct iwl_priv *priv) -{ - priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; - priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; - if (priv->cfg->mod_params->amsdu_size_8K) - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); - else - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); - - priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; - - if (priv->cfg->mod_params->disable_11n) - priv->cfg->sku &= ~IWL_SKU_N; - - /* Device-specific setup */ - return priv->cfg->ops->lib->set_hw_params(priv); -} -EXPORT_SYMBOL(iwl_set_hw_params); - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ac16f582d6d3..cca7428c238f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -374,7 +374,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv); void iwl_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast); -int iwl_set_hw_params(struct iwl_priv *priv); void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- cgit v1.2.3 From a85d7cca1204f2dba86d2f61693f0fe8c48f0fa5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 31 Jul 2010 08:34:10 -0700 Subject: iwlwifi: track IBSS manager status Only the IBSS manager, ie. the station that sent the IBSS beacon last, should be replying to probe responses. This requires implementing the mac80211 tx_last_beacon callback, which we can do thanks to the ucode beacon notification. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-commands.h | 5 +++++ drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 ++++- 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8684f2639716..43e078b87378 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -764,10 +764,10 @@ static void iwl_bg_ucode_trace(unsigned long data) static void iwl_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl4965_beacon_notif *beacon = (struct iwl4965_beacon_notif *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_DEBUG u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " @@ -779,6 +779,8 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, le32_to_cpu(beacon->low_tsf), rate); #endif + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + if ((priv->iw_mode == NL80211_IFTYPE_AP) && (!test_bit(STATUS_EXIT_PENDING, &priv->status))) queue_work(priv->workqueue, &priv->beacon_update); @@ -3881,6 +3883,7 @@ static struct ieee80211_ops iwl_hw_ops = { .sta_remove = iwl_mac_sta_remove, .channel_switch = iwl_mac_channel_switch, .flush = iwl_mac_flush, + .tx_last_beacon = iwl_mac_tx_last_beacon, }; static void iwl_hw_detect(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 60725a5c1b69..9435fd934d5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2919,6 +2919,11 @@ struct iwl_scancomplete_notification { * *****************************************************************************/ +enum iwl_ibss_manager { + IWL_NOT_IBSS_MANAGER = 0, + IWL_IBSS_MANAGER = 1, +}; + /* * BEACON_NOTIFICATION = 0x90 (notification only, not a command) */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 78882f9ab459..ccdf3c02bb3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1666,6 +1666,14 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, } EXPORT_SYMBOL(iwl_mac_conf_tx); +int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + return priv->ibss_manager == IWL_IBSS_MANAGER; +} +EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); + static void iwl_ht_conf(struct iwl_priv *priv, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index cca7428c238f..7f1aaf206078 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -350,6 +350,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, void iwl_activate_qos(struct iwl_priv *priv); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); +int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); int iwl_check_rxon_cmd(struct iwl_priv *priv); int iwl_full_rxon_required(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f35bcad56e36..599635547021 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1109,6 +1109,9 @@ struct iwl_priv { u32 ucode_beacon_time; int missed_beacon_threshold; + /* track IBSS manager (last beacon) status */ + u32 ibss_manager; + /* storing the jiffies when the plcp error rate is received */ unsigned long plcp_jiffies; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index de6d592af748..b14eaf91c7c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -814,9 +814,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWLWIFI_DEBUG u8 rate = beacon->beacon_notify_hdr.rate; IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " @@ -828,6 +828,8 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, le32_to_cpu(beacon->low_tsf), rate); #endif + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + if ((priv->iw_mode == NL80211_IFTYPE_AP) && (!test_bit(STATUS_EXIT_PENDING, &priv->status))) queue_work(priv->workqueue, &priv->beacon_update); @@ -3803,6 +3805,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .hw_scan = iwl_mac_hw_scan, .sta_add = iwl3945_mac_sta_add, .sta_remove = iwl_mac_sta_remove, + .tx_last_beacon = iwl_mac_tx_last_beacon, }; static int iwl3945_init_drv(struct iwl_priv *priv) -- cgit v1.2.3 From 1ac62ba7c985109868a18d959986425148481f47 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 1 Aug 2010 17:37:03 +0100 Subject: mac80211: Don't squash error codes in key setup functions ieee80211_add_key() currently returns -ENOMEM in case of any error, including a missing crypto algorithm. Change ieee80211_key_alloc() and ieee80211_aes_{key_setup_encrypt,cmac_key_setup}() to encode errors with ERR_PTR() rather than returning NULL, and change ieee80211_add_key() accordingly. Compile-tested only. Reported-by: Marcin Owsiany Signed-off-by: Ben Hutchings Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/aes_ccm.c | 6 ++---- net/mac80211/aes_cmac.c | 6 ++---- net/mac80211/cfg.c | 4 ++-- net/mac80211/key.c | 14 ++++++++------ 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index a87cb3ba2df6..d2b03e0851ef 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -138,10 +138,8 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) struct crypto_cipher *tfm; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return NULL; - - crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); + if (!IS_ERR(tfm)) + crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); return tfm; } diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index 3d097b3d7b62..b4d66cca76d6 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -119,10 +119,8 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) struct crypto_cipher *tfm; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return NULL; - - crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); + if (!IS_ERR(tfm)) + crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); return tfm; } diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 29ac8e1a509e..19c6146010b7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -150,8 +150,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, params->seq_len, params->seq); - if (!key) - return -ENOMEM; + if (IS_ERR(key)) + return PTR_ERR(key); mutex_lock(&sdata->local->sta_mtx); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1b9d87ed143a..d6dbc8ea4ead 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -234,13 +234,13 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, size_t seq_len, const u8 *seq) { struct ieee80211_key *key; - int i, j; + int i, j, err; BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); if (!key) - return NULL; + return ERR_PTR(-ENOMEM); /* * Default to software encryption; we'll later upload the @@ -296,9 +296,10 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, * it does not need to be initialized for every packet. */ key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); - if (!key->u.ccmp.tfm) { + if (IS_ERR(key->u.ccmp.tfm)) { + err = PTR_ERR(key->u.ccmp.tfm); kfree(key); - return NULL; + key = ERR_PTR(err); } } @@ -309,9 +310,10 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, */ key->u.aes_cmac.tfm = ieee80211_aes_cmac_key_setup(key_data); - if (!key->u.aes_cmac.tfm) { + if (IS_ERR(key->u.aes_cmac.tfm)) { + err = PTR_ERR(key->u.aes_cmac.tfm); kfree(key); - return NULL; + key = ERR_PTR(err); } } -- cgit v1.2.3 From 6252fcb9f802a992c697edf105e30271a4ae3246 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Aug 2010 15:53:12 +0200 Subject: ath9k: add a separate debug level for stuck beacons Stuck beacons are a useful indicator for debugging various PHY issues such as calibration. Putting them on the same debug level as the other beacon stuff makes it hard to spot them in huge amounts of spam. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 6 +++--- drivers/net/wireless/ath/debug.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 4d4b22d52dfd..102f1234f794 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -359,11 +359,11 @@ void ath_beacon_tasklet(unsigned long data) sc->beacon.bmisscnt++; if (sc->beacon.bmisscnt < BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; ath_reset(sc, false); @@ -373,7 +373,7 @@ void ath_beacon_tasklet(unsigned long data) } if (sc->beacon.bmisscnt != 0) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "resume beacon xmit after %u misses\n", sc->beacon.bmisscnt); sc->beacon.bmisscnt = 0; diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index 873bf526e11f..fd3a020682dc 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -36,6 +36,7 @@ * @ATH_DBG_PS: power save processing * @ATH_DBG_HWTIMER: hardware timer handling * @ATH_DBG_BTCOEX: bluetooth coexistance + * @ATH_DBG_BSTUCK: stuck beacons * @ATH_DBG_ANY: enable all debugging * * The debug level is used to control the amount and type of debugging output @@ -60,6 +61,7 @@ enum ATH_DEBUG { ATH_DBG_HWTIMER = 0x00001000, ATH_DBG_BTCOEX = 0x00002000, ATH_DBG_WMI = 0x00004000, + ATH_DBG_BSTUCK = 0x00008000, ATH_DBG_ANY = 0xffffffff }; -- cgit v1.2.3 From 2292ca6d783d3c79b58591bb3ee795bf0144e5ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Aug 2010 15:53:13 +0200 Subject: ath9k_hw: apply the noise floor validation to the median instead of single Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 51 +++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 45208690c0ec..ccb1b2eae85e 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -19,8 +19,7 @@ /* Common calibration code */ -/* We can tune this as we go by monitoring really low values */ -#define ATH9K_NF_TOO_LOW -60 +#define ATH9K_NF_TOO_HIGH -60 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) { @@ -45,11 +44,35 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) return nfval; } -static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, +static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + struct ath_nf_limits *limit; + + if (!chan || IS_CHAN_2GHZ(chan)) + limit = &ah->nf_2g; + else + limit = &ah->nf_5g; + + return limit; +} + +static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + return ath9k_hw_get_nf_limits(ah, chan)->nominal; +} + + +static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, + struct ath9k_nfcal_hist *h, int16_t *nfarray) { + struct ath_nf_limits *limit; int i; + limit = ath9k_hw_get_nf_limits(ah, ah->curchan); + for (i = 0; i < NUM_NF_READINGS; i++) { h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; @@ -63,6 +86,9 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, h[i].privNF = ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); } + + if (h[i].privNF > limit->max) + h[i].privNF = limit->max; } } @@ -104,19 +130,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah, ah->cal_samples = 0; } -static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ath_nf_limits *limit; - - if (!chan || IS_CHAN_2GHZ(chan)) - limit = &ah->nf_2g; - else - limit = &ah->nf_5g; - - return limit->nominal; -} - /* This is done for the currently configured channel */ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) { @@ -277,10 +290,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) "NF calibrated [%s] [chain %d] is %d\n", (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); - if (nf[i] > limit->max) { + if (nf[i] > ATH9K_NF_TOO_HIGH) { ath_print(common, ATH_DBG_CALIBRATE, "NF[%d] (%d) > MAX (%d), correcting to MAX", - i, nf[i], limit->max); + i, nf[i], ATH9K_NF_TOO_HIGH); nf[i] = limit->max; } else if (nf[i] < limit->min) { ath_print(common, ATH_DBG_CALIBRATE, @@ -326,7 +339,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) h = caldata->nfCalHist; caldata->nfcal_pending = false; - ath9k_hw_update_nfcal_hist_buffer(h, nfarray); + ath9k_hw_update_nfcal_hist_buffer(ah, h, nfarray); caldata->rawNoiseFloor = h[0].privNF; return true; } -- cgit v1.2.3 From 70cf15335eb35d562a4ec6d8860611c87f775cf2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Aug 2010 15:53:14 +0200 Subject: ath9k: use AP beacon miss as a trigger for fast recalibration When beacons get stuck in AP mode, the most likely cause is interference. Such interference can often go on for a while, and too many consecutive beacon misses can lead to connected clients getting dropped. Since connected clients might not be subjected to the same interference if that happens to be very local, the AP should try to deal with it as good as it can. One way to do this is to trigger an NF calibration with automatic baseband update right after the beacon miss. In my tests with very strong interference, this allowed the AP to continue transmitting beacons after only 2-3 misses, which allows a normal client to stay connected. With some of the newer - really sensitive - chips, the maximum noise floor limit is very low, which can be problematic during very strong interference. To avoid an endless loop of stuck beacons -> nfcal -> periodic calibration -> stuck beacons, the beacon miss event also sets a flag, which allows the calibration code to bypass the chip specific maximum NF value. This flag is automatically cleared, as soon as the first NF median goes back below the limits for all chains. In my tests, this allowed an ath9k AP to survive very strong interference (measured NF: -68, or sometimes even higher) without losing connectivity to its clients. Even under these conditions, I was able to transmit several mbits/s through the interface. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + drivers/net/wireless/ath/ath9k/calib.c | 66 +++++++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/calib.h | 1 + drivers/net/wireless/ath/ath9k/hw.h | 1 + 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 102f1234f794..081192e78a46 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -362,6 +362,7 @@ void ath_beacon_tasklet(unsigned long data) ath_print(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); + ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ath_print(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index ccb1b2eae85e..67ee5d735cc1 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -65,12 +65,16 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, - struct ath9k_nfcal_hist *h, + struct ath9k_hw_cal_data *cal, int16_t *nfarray) { + struct ath_common *common = ath9k_hw_common(ah); struct ath_nf_limits *limit; + struct ath9k_nfcal_hist *h; + bool high_nf_mid = false; int i; + h = cal->nfCalHist; limit = ath9k_hw_get_nf_limits(ah, ah->curchan); for (i = 0; i < NUM_NF_READINGS; i++) { @@ -87,9 +91,38 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); } - if (h[i].privNF > limit->max) - h[i].privNF = limit->max; + if (!h[i].privNF) + continue; + + if (h[i].privNF > limit->max) { + high_nf_mid = true; + + ath_print(common, ATH_DBG_CALIBRATE, + "NFmid[%d] (%d) > MAX (%d), %s\n", + i, h[i].privNF, limit->max, + (cal->nfcal_interference ? + "not corrected (due to interference)" : + "correcting to MAX")); + + /* + * Normally we limit the average noise floor by the + * hardware specific maximum here. However if we have + * encountered stuck beacons because of interference, + * we bypass this limit here in order to better deal + * with our environment. + */ + if (!cal->nfcal_interference) + h[i].privNF = limit->max; + } } + + /* + * If the noise floor seems normal for all chains, assume that + * there is no significant interference in the environment anymore. + * Re-enable the enforcement of the NF maximum again. + */ + if (!high_nf_mid) + cal->nfcal_interference = false; } static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah, @@ -339,7 +372,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) h = caldata->nfCalHist; caldata->nfcal_pending = false; - ath9k_hw_update_nfcal_hist_buffer(ah, h, nfarray); + ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); caldata->rawNoiseFloor = h[0].privNF; return true; } @@ -374,3 +407,28 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) return ah->caldata->rawNoiseFloor; } EXPORT_SYMBOL(ath9k_hw_getchan_noise); + +void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) +{ + struct ath9k_hw_cal_data *caldata = ah->caldata; + + if (unlikely(!caldata)) + return; + + /* + * If beacons are stuck, the most likely cause is interference. + * Triggering a noise floor calibration at this point helps the + * hardware adapt to a noisy environment much faster. + * To ensure that we recover from stuck beacons quickly, let + * the baseband update the internal NF value itself, similar to + * what is being done after a full reset. + */ + if (!caldata->nfcal_pending) + ath9k_hw_start_nfcal(ah, true); + else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)) + ath9k_hw_getnf(ah, ah->curchan); + + caldata->nfcal_interference = true; +} +EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal); + diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 0a304b3eeeb6..5b053a6260b2 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -113,6 +113,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, struct ath9k_channel *chan); +void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_hw_reset_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 399f7c1283cd..1601dd439890 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -355,6 +355,7 @@ struct ath9k_hw_cal_data { int16_t rawNoiseFloor; bool paprd_done; bool nfcal_pending; + bool nfcal_interference; u16 small_signal_gain[AR9300_MAX_CHAINS]; u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; -- cgit v1.2.3 From 6044474ed86484b899d46e040ade3872e83fc9f7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 2 Aug 2010 15:53:15 +0200 Subject: ath9k: shorten the calibration interval during strong interference When the noise floor limits are being bypassed because of strong interference, sensitivity is also reduced. In order to recover from this as quickly as possible, trigger a long periodic calibration every second instead of every 30 seconds, until the NF median is within limits again. This is especially important if the interference lasts for a while, since it takes multiple clean NF calibrations to bring the median back to normal. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 07f26ee7a723..def0cd308fdd 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -423,6 +423,7 @@ int ath_beaconq_config(struct ath_softc *sc); #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */ +#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2ab3df22fbb5..a3b0ea90439d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -396,7 +396,12 @@ void ath_ani_calibrate(unsigned long data) bool shortcal = false; bool aniflag = false; unsigned int timestamp = jiffies_to_msecs(jiffies); - u32 cal_interval, short_cal_interval; + u32 cal_interval, short_cal_interval, long_cal_interval; + + if (ah->caldata && ah->caldata->nfcal_interference) + long_cal_interval = ATH_LONG_CALINTERVAL_INT; + else + long_cal_interval = ATH_LONG_CALINTERVAL; short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; @@ -408,7 +413,7 @@ void ath_ani_calibrate(unsigned long data) ath9k_ps_wakeup(sc); /* Long calibration runs independently of short calibration. */ - if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { + if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { longcal = true; ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); common->ani.longcal_timer = timestamp; -- cgit v1.2.3 From aa0c86364f925c6f12195072562b18c5609ff082 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 5 Aug 2010 01:36:04 +0200 Subject: mac80211: put rx handlers into separate functions This patch takes the reorder logic from the RX path and moves it into separate routines to make the expired frame release accessible. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 214 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 128 insertions(+), 86 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 225e8ee682e3..8301b4a980a2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -583,6 +583,57 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) +static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, + struct tid_ampdu_rx *tid_agg_rx, + struct sk_buff_head *frames) +{ + int index; + + /* release the buffer until next missing frame */ + index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + tid_agg_rx->buf_size; + if (!tid_agg_rx->reorder_buf[index] && + tid_agg_rx->stored_mpdu_num > 1) { + /* + * No buffers ready to be released, but check whether any + * frames in the reorder buffer have timed out. + */ + int j; + int skipped = 1; + for (j = (index + 1) % tid_agg_rx->buf_size; j != index; + j = (j + 1) % tid_agg_rx->buf_size) { + if (!tid_agg_rx->reorder_buf[j]) { + skipped++; + continue; + } + if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + + HT_RX_REORDER_BUF_TIMEOUT)) + break; + +#ifdef CONFIG_MAC80211_HT_DEBUG + if (net_ratelimit()) + printk(KERN_DEBUG "%s: release an RX reorder " + "frame due to timeout on earlier " + "frames\n", + wiphy_name(hw->wiphy)); +#endif + ieee80211_release_reorder_frame(hw, tid_agg_rx, + j, frames); + + /* + * Increment the head seq# also for the skipped slots. + */ + tid_agg_rx->head_seq_num = + (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; + skipped = 0; + } + } else while (tid_agg_rx->reorder_buf[index]) { + ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); + index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + tid_agg_rx->buf_size; + } +} + /* * As this function belongs to the RX path it must be under * rcu_read_lock protection. It returns false if the frame @@ -643,49 +694,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - /* release the buffer until next missing frame */ - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % - tid_agg_rx->buf_size; - if (!tid_agg_rx->reorder_buf[index] && - tid_agg_rx->stored_mpdu_num > 1) { - /* - * No buffers ready to be released, but check whether any - * frames in the reorder buffer have timed out. - */ - int j; - int skipped = 1; - for (j = (index + 1) % tid_agg_rx->buf_size; j != index; - j = (j + 1) % tid_agg_rx->buf_size) { - if (!tid_agg_rx->reorder_buf[j]) { - skipped++; - continue; - } - if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + - HT_RX_REORDER_BUF_TIMEOUT)) - break; - -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: release an RX reorder " - "frame due to timeout on earlier " - "frames\n", - wiphy_name(hw->wiphy)); -#endif - ieee80211_release_reorder_frame(hw, tid_agg_rx, - j, frames); - - /* - * Increment the head seq# also for the skipped slots. - */ - tid_agg_rx->head_seq_num = - (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; - skipped = 0; - } - } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % - tid_agg_rx->buf_size; - } + ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); return true; } @@ -2267,19 +2276,46 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, dev_kfree_skb(skb); } - -static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, - struct ieee80211_rx_data *rx, - struct sk_buff *skb, - struct ieee80211_rate *rate) +static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, + ieee80211_rx_result res) { - struct sk_buff_head reorder_release; - ieee80211_rx_result res = RX_DROP_MONITOR; + switch (res) { + case RX_DROP_MONITOR: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); + if (rx->sta) + rx->sta->rx_dropped++; + /* fall through */ + case RX_CONTINUE: { + struct ieee80211_rate *rate = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_rx_status *status; + + status = IEEE80211_SKB_RXCB((rx->skb)); + + sband = rx->local->hw.wiphy->bands[status->band]; + if (!(status->flag & RX_FLAG_HT)) + rate = &sband->bitrates[status->rate_idx]; - __skb_queue_head_init(&reorder_release); + ieee80211_rx_cooked_monitor(rx, rate); + break; + } + case RX_DROP_UNUSABLE: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); + if (rx->sta) + rx->sta->rx_dropped++; + dev_kfree_skb(rx->skb); + break; + case RX_QUEUED: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued); + break; + } +} - rx->skb = skb; - rx->sdata = sdata; +static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, + struct sk_buff_head *frames) +{ + ieee80211_rx_result res = RX_DROP_MONITOR; + struct sk_buff *skb; #define CALL_RXH(rxh) \ do { \ @@ -2288,17 +2324,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, goto rxh_next; \ } while (0); - /* - * NB: the rxh_next label works even if we jump - * to it from here because then the list will - * be empty, which is a trivial check - */ - CALL_RXH(ieee80211_rx_h_passive_scan) - CALL_RXH(ieee80211_rx_h_check) - - ieee80211_rx_reorder_ampdu(rx, &reorder_release); - - while ((skb = __skb_dequeue(&reorder_release))) { + while ((skb = __skb_dequeue(frames))) { /* * all the other fields are valid across frames * that belong to an aMPDU since they are on the @@ -2316,42 +2342,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, CALL_RXH(ieee80211_rx_h_remove_qos_control) CALL_RXH(ieee80211_rx_h_amsdu) #ifdef CONFIG_MAC80211_MESH - if (ieee80211_vif_is_mesh(&sdata->vif)) + if (ieee80211_vif_is_mesh(&rx->sdata->vif)) CALL_RXH(ieee80211_rx_h_mesh_fwding); #endif CALL_RXH(ieee80211_rx_h_data) /* special treatment -- needs the queue */ - res = ieee80211_rx_h_ctrl(rx, &reorder_release); + res = ieee80211_rx_h_ctrl(rx, frames); if (res != RX_CONTINUE) goto rxh_next; CALL_RXH(ieee80211_rx_h_action) CALL_RXH(ieee80211_rx_h_mgmt) + rxh_next: + ieee80211_rx_handlers_result(rx, res); + #undef CALL_RXH + } +} + +static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, + struct ieee80211_rx_data *rx, + struct sk_buff *skb, + struct ieee80211_rate *rate) +{ + struct sk_buff_head reorder_release; + ieee80211_rx_result res = RX_DROP_MONITOR; + + __skb_queue_head_init(&reorder_release); + + rx->skb = skb; + rx->sdata = sdata; + +#define CALL_RXH(rxh) \ + do { \ + res = rxh(rx); \ + if (res != RX_CONTINUE) \ + goto rxh_next; \ + } while (0); + + CALL_RXH(ieee80211_rx_h_passive_scan) + CALL_RXH(ieee80211_rx_h_check) + + ieee80211_rx_reorder_ampdu(rx, &reorder_release); + + ieee80211_rx_handlers(rx, &reorder_release); + return; rxh_next: - switch (res) { - case RX_DROP_MONITOR: - I802_DEBUG_INC(sdata->local->rx_handlers_drop); - if (rx->sta) - rx->sta->rx_dropped++; - /* fall through */ - case RX_CONTINUE: - ieee80211_rx_cooked_monitor(rx, rate); - break; - case RX_DROP_UNUSABLE: - I802_DEBUG_INC(sdata->local->rx_handlers_drop); - if (rx->sta) - rx->sta->rx_dropped++; - dev_kfree_skb(rx->skb); - break; - case RX_QUEUED: - I802_DEBUG_INC(sdata->local->rx_handlers_queued); - break; - } - } + ieee80211_rx_handlers_result(rx, res); + +#undef CALL_RXH } /* main receive path */ -- cgit v1.2.3 From 071d9ac253ff51154beb7e33967168e30bc96053 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 5 Aug 2010 01:36:36 +0200 Subject: mac80211: remove unused rate function parameter This patch removes a few stale parameters and variables which survived the last, large rx-path reorganization: "mac80211: correctly place aMPDU RX reorder code" Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8301b4a980a2..d5b91b6eb120 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -538,20 +538,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, int index, struct sk_buff_head *frames) { - struct ieee80211_supported_band *sband; - struct ieee80211_rate *rate = NULL; struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; - struct ieee80211_rx_status *status; if (!skb) goto no_frame; - status = IEEE80211_SKB_RXCB(skb); - - /* release the reordered frames to stack */ - sband = hw->wiphy->bands[status->band]; - if (!(status->flag & RX_FLAG_HT)) - rate = &sband->bitrates[status->rate_idx]; + /* release the frame from the reorder ring buffer */ tid_agg_rx->stored_mpdu_num--; tid_agg_rx->reorder_buf[index] = NULL; __skb_queue_tail(frames, skb); @@ -2364,8 +2356,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, struct ieee80211_rx_data *rx, - struct sk_buff *skb, - struct ieee80211_rate *rate) + struct sk_buff *skb) { struct sk_buff_head reorder_release; ieee80211_rx_result res = RX_DROP_MONITOR; @@ -2489,8 +2480,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, * be called with rcu_read_lock protection. */ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ieee80211_rate *rate) + struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_local *local = hw_to_local(hw); @@ -2598,7 +2588,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, prev->name); goto next; } - ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); + ieee80211_invoke_rx_handlers(prev, &rx, skb_new); next: prev = sdata; } @@ -2614,7 +2604,7 @@ next: } } if (prev) - ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); + ieee80211_invoke_rx_handlers(prev, &rx, skb); else dev_kfree_skb(skb); } @@ -2709,7 +2699,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) return; } - __ieee80211_rx_handle_packet(hw, skb, rate); + __ieee80211_rx_handle_packet(hw, skb); rcu_read_unlock(); -- cgit v1.2.3 From 2bff8ebf32a7c5ec9e5f5eeffef94a8cb622f5f0 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 5 Aug 2010 01:36:41 +0200 Subject: mac80211: AMPDU rx reorder timeout timer This patch introduces a new timer, which will release queued-up MPDUs from the reorder buffer, whenever they've waited for more than HT_RX_REORDER_BUF_TIMEOUT (which is at around 100 ms). The advantage of having a dedicated timer, instead of relying on a constant stream of freshly arriving aMPDUs to release the old ones, is particularly observable when even a small fraction of MPDUs are forever lost at low network speeds. Previously under these circumstances frames would become stuck in the reorder buffer and the network stack of both HT peers throttled back, instead of revving up and gunning the pipes. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 22 +++++++++++++++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/rx.c | 70 +++++++++++++++++++++++++++++++++++++++++----- net/mac80211/sta_info.h | 16 +++++++---- 4 files changed, 97 insertions(+), 12 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 965b272499fd..58eab9e8e4ee 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -86,6 +86,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, tid, 0, reason); del_timer_sync(&tid_rx->session_timer); + del_timer_sync(&tid_rx->reorder_timer); call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); } @@ -120,6 +121,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); } +static void sta_rx_agg_reorder_timer_expired(unsigned long data) +{ + u8 *ptid = (u8 *)data; + u8 *timer_to_id = ptid - *ptid; + struct sta_info *sta = container_of(timer_to_id, struct sta_info, + timer_to_tid[0]); + + rcu_read_lock(); + spin_lock(&sta->lock); + ieee80211_release_reorder_timeout(sta, *ptid); + spin_unlock(&sta->lock); + rcu_read_unlock(); +} + static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, u8 dialog_token, u16 status, u16 policy, u16 buf_size, u16 timeout) @@ -251,11 +266,18 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, goto end; } + spin_lock_init(&tid_agg_rx->reorder_lock); + /* rx timer */ tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired; tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid]; init_timer(&tid_agg_rx->session_timer); + /* rx reorder timer */ + tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired; + tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid]; + init_timer(&tid_agg_rx->reorder_timer); + /* prepare reordering buffer */ tid_agg_rx->reorder_buf = kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fb4363e148f2..b44e03a02da9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1136,6 +1136,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); +void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); /* Spectrum management */ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d5b91b6eb120..f24a0a1cff1a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -572,6 +572,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, * frames that have not yet been received are assumed to be lost and the skb * can be released for processing. This may also release other skb's from the * reorder buffer if there are no additional gaps between the frames. + * + * Callers must hold tid_agg_rx->reorder_lock. */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) @@ -579,7 +581,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff_head *frames) { - int index; + int index, j; /* release the buffer until next missing frame */ index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % @@ -590,7 +592,6 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, * No buffers ready to be released, but check whether any * frames in the reorder buffer have timed out. */ - int j; int skipped = 1; for (j = (index + 1) % tid_agg_rx->buf_size; j != index; j = (j + 1) % tid_agg_rx->buf_size) { @@ -600,7 +601,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, } if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + HT_RX_REORDER_BUF_TIMEOUT)) - break; + goto set_release_timer; #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) @@ -624,6 +625,25 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; } + + if (tid_agg_rx->stored_mpdu_num) { + j = index = seq_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; + + for (; j != (index - 1) % tid_agg_rx->buf_size; + j = (j + 1) % tid_agg_rx->buf_size) { + if (tid_agg_rx->reorder_buf[j]) + break; + } + + set_release_timer: + + mod_timer(&tid_agg_rx->reorder_timer, + tid_agg_rx->reorder_time[j] + + HT_RX_REORDER_BUF_TIMEOUT); + } else { + del_timer(&tid_agg_rx->reorder_timer); + } } /* @@ -641,14 +661,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; u16 head_seq_num, buf_size; int index; + bool ret = true; buf_size = tid_agg_rx->buf_size; head_seq_num = tid_agg_rx->head_seq_num; + spin_lock(&tid_agg_rx->reorder_lock); /* frame with out of date sequence number */ if (seq_less(mpdu_seq_num, head_seq_num)) { dev_kfree_skb(skb); - return true; + goto out; } /* @@ -669,7 +691,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, /* check if we already stored this frame */ if (tid_agg_rx->reorder_buf[index]) { dev_kfree_skb(skb); - return true; + goto out; } /* @@ -679,7 +701,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, if (mpdu_seq_num == tid_agg_rx->head_seq_num && tid_agg_rx->stored_mpdu_num == 0) { tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); - return false; + ret = false; + goto out; } /* put the frame in the reordering buffer */ @@ -688,7 +711,9 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, tid_agg_rx->stored_mpdu_num++; ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); - return true; + out: + spin_unlock(&tid_agg_rx->reorder_lock); + return ret; } /* @@ -2387,6 +2412,37 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, #undef CALL_RXH } +/* + * This function makes calls into the RX path. Therefore the + * caller must hold the sta_info->lock and everything has to + * be under rcu_read_lock protection as well. + */ +void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) +{ + struct sk_buff_head frames; + struct ieee80211_rx_data rx = { }; + + __skb_queue_head_init(&frames); + + /* construct rx struct */ + rx.sta = sta; + rx.sdata = sta->sdata; + rx.local = sta->local; + rx.queue = tid; + rx.flags |= IEEE80211_RX_RA_MATCH; + + if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) || + test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning))) + rx.flags |= IEEE80211_RX_IN_SCAN; + + spin_lock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); + ieee80211_sta_reorder_release(&sta->local->hw, + sta->ampdu_mlme.tid_rx[tid], &frames); + spin_unlock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); + + ieee80211_rx_handlers(&rx, &frames); +} + /* main receive path */ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 54262e72376d..810c5ce98316 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -103,6 +103,7 @@ struct tid_ampdu_tx { * @reorder_buf: buffer to reorder incoming aggregated MPDUs * @reorder_time: jiffies when skb was added * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) + * @reorder_timer: releases expired frames from the reorder buffer. * @head_seq_num: head sequence number in reordering buffer. * @stored_mpdu_num: number of MPDUs in reordering buffer * @ssn: Starting Sequence Number expected to be aggregated. @@ -110,20 +111,25 @@ struct tid_ampdu_tx { * @timeout: reset timer value (in TUs). * @dialog_token: dialog token for aggregation session * @rcu_head: RCU head used for freeing this struct + * @reorder_lock: serializes access to reorder buffer, see below. * * This structure is protected by RCU and the per-station * spinlock. Assignments to the array holding it must hold - * the spinlock, only the RX path can access it under RCU - * lock-free. The RX path, since it is single-threaded, - * can even modify the structure without locking since the - * only other modifications to it are done when the struct - * can not yet or no longer be found by the RX path. + * the spinlock. + * + * The @reorder_lock is used to protect the variables and + * arrays such as @reorder_buf, @reorder_time, @head_seq_num, + * @stored_mpdu_num and @reorder_time from being corrupted by + * concurrent access of the RX path and the expired frame + * release timer. */ struct tid_ampdu_rx { struct rcu_head rcu_head; + spinlock_t reorder_lock; struct sk_buff **reorder_buf; unsigned long *reorder_time; struct timer_list session_timer; + struct timer_list reorder_timer; u16 head_seq_num; u16 stored_mpdu_num; u16 ssn; -- cgit v1.2.3 From 3f3b6a8d90b6e762e2bb83e6a9e86d9534b56cdc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 5 Aug 2010 10:20:27 +0200 Subject: cfg80211: deauth doesn't always imply disconnect When an AP sends a deauth frame, or we send one to an AP, that only means we lost our connection if we were actually connected to that AP. Check this to avoid sending spurious "disconnected" events and breaking "iw ... link" reporting. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/mlme.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index d1a3fb99fdf2..ee0af32ed59e 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -149,7 +149,7 @@ void __cfg80211_send_deauth(struct net_device *dev, struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; const u8 *bssid = mgmt->bssid; int i; - bool found = false; + bool found = false, was_current = false; ASSERT_WDEV_LOCK(wdev); @@ -159,6 +159,7 @@ void __cfg80211_send_deauth(struct net_device *dev, cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; found = true; + was_current = true; } else for (i = 0; i < MAX_AUTH_BSSES; i++) { if (wdev->auth_bsses[i] && memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { @@ -183,7 +184,7 @@ void __cfg80211_send_deauth(struct net_device *dev, nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL); - if (wdev->sme_state == CFG80211_SME_CONNECTED) { + if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) { u16 reason_code; bool from_ap; -- cgit v1.2.3 From 1fdaa46e9f26ccbab5e0eb8c4d4f8e1fbf32c7df Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 5 Aug 2010 15:51:35 +0200 Subject: net: mac80211: Fix a typo. "userpace" -> "userspace" Signed-off-by: Andrea Gelmini Signed-off-by: John W. Linville --- net/mac80211/rc80211_pid_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 47438b4a9af5..135f36fd4d5d 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c @@ -162,7 +162,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, file_info->next_entry = (file_info->next_entry + 1) % RC_PID_EVENT_RING_SIZE; - /* Print information about the event. Note that userpace needs to + /* Print information about the event. Note that userspace needs to * provide large enough buffers. */ length = length < RC_PID_PRINT_BUF_SIZE ? length : RC_PID_PRINT_BUF_SIZE; -- cgit v1.2.3 From 7da7cc1d42d8ce02cca16df8c021e6d657f1f8fd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 5 Aug 2010 17:02:38 +0200 Subject: mac80211: per interface idle notification Sometimes we don't just need to know whether or not the device is idle, but also per interface. This adds that reporting capability to mac80211. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 6 ++++++ net/mac80211/ibss.c | 8 +++++-- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/iface.c | 53 +++++++++++++++++++++++++++++++++++++++------- net/mac80211/mlme.c | 17 +++++++++++++-- net/mac80211/scan.c | 2 ++ net/mac80211/work.c | 8 +++---- 7 files changed, 81 insertions(+), 16 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3f1e03b521ec..3a3c26f647b7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -149,6 +149,7 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed. * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note * that it is only ever disabled for station mode. + * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -165,6 +166,7 @@ enum ieee80211_bss_change { BSS_CHANGED_IBSS = 1<<11, BSS_CHANGED_ARP_FILTER = 1<<12, BSS_CHANGED_QOS = 1<<13, + BSS_CHANGED_IDLE = 1<<14, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -223,6 +225,9 @@ enum ieee80211_bss_change { * hardware must not perform any ARP filtering. Note, that the filter will * be enabled also in promiscuous mode. * @qos: This is a QoS-enabled BSS. + * @idle: This interface is idle. There's also a global idle flag in the + * hardware config which may be more appropriate depending on what + * your driver/device needs to do. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -247,6 +252,7 @@ struct ieee80211_bss_conf { u8 arp_addr_cnt; bool arp_filter_enabled; bool qos; + bool idle; }; /** diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index c691780725a7..32af97108425 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -920,12 +920,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; + mutex_unlock(&sdata->u.ibss.mtx); + + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); ieee80211_queue_work(&sdata->local->hw, &sdata->work); - mutex_unlock(&sdata->u.ibss.mtx); - return 0; } @@ -980,7 +982,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_unlock(&sdata->u.ibss.mtx); + mutex_lock(&local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&local->mtx); return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b44e03a02da9..98e783c6a363 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -497,6 +497,9 @@ struct ieee80211_sub_if_data { */ bool ht_opmode_valid; + /* to detect idle changes */ + bool old_idle; + /* Fragment table for host-based reassembly */ struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; unsigned int fragment_next; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index c1008a9d7bfb..9459aeee0ddc 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -309,7 +309,9 @@ static int ieee80211_open(struct net_device *dev) if (sdata->flags & IEEE80211_SDATA_PROMISC) atomic_inc(&local->iff_promiscs); + mutex_lock(&local->mtx); hw_reconf_flags |= __ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); local->open_count++; if (hw_reconf_flags) { @@ -516,7 +518,9 @@ static int ieee80211_stop(struct net_device *dev) sdata->bss = NULL; + mutex_lock(&local->mtx); hw_reconf_flags |= __ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); ieee80211_recalc_ps(local, -1); @@ -1199,28 +1203,61 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int count = 0; + bool working = false, scanning = false; + struct ieee80211_work *wk; - if (!list_empty(&local->work_list)) - return ieee80211_idle_off(local, "working"); - - if (local->scanning) - return ieee80211_idle_off(local, "scanning"); +#ifdef CONFIG_PROVE_LOCKING + WARN_ON(debug_locks && !lockdep_rtnl_is_held() && + !lockdep_is_held(&local->iflist_mtx)); +#endif + lockdep_assert_held(&local->mtx); list_for_each_entry(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) + if (!ieee80211_sdata_running(sdata)) { + sdata->vif.bss_conf.idle = true; continue; + } + + sdata->old_idle = sdata->vif.bss_conf.idle; + /* do not count disabled managed interfaces */ if (sdata->vif.type == NL80211_IFTYPE_STATION && - !sdata->u.mgd.associated) + !sdata->u.mgd.associated) { + sdata->vif.bss_conf.idle = true; continue; + } /* do not count unused IBSS interfaces */ if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - !sdata->u.ibss.ssid_len) + !sdata->u.ibss.ssid_len) { + sdata->vif.bss_conf.idle = true; continue; + } /* count everything else */ count++; } + list_for_each_entry(wk, &local->work_list, list) { + working = true; + wk->sdata->vif.bss_conf.idle = false; + } + + if (local->scan_sdata) { + scanning = true; + local->scan_sdata->vif.bss_conf.idle = false; + } + + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->old_idle == sdata->vif.bss_conf.idle) + continue; + if (!ieee80211_sdata_running(sdata)) + continue; + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); + } + + if (working) + return ieee80211_idle_off(local, "working"); + if (scanning) + return ieee80211_idle_off(local, "scanning"); if (!count) return ieee80211_idle_on(local); else diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 17e9257a61d8..82e7cec5179c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1103,8 +1103,11 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); ieee80211_set_disassoc(sdata, true); - ieee80211_recalc_idle(local); mutex_unlock(&ifmgd->mtx); + + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -1173,7 +1176,9 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, sdata->name, bssid, reason_code); ieee80211_set_disassoc(sdata, true); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return RX_MGMT_CFG80211_DEAUTH; } @@ -1203,7 +1208,9 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, sdata->name, mgmt->sa, reason_code); ieee80211_set_disassoc(sdata, true); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return RX_MGMT_CFG80211_DISASSOC; } @@ -1840,8 +1847,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) " after %dms, disconnecting.\n", bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); ieee80211_set_disassoc(sdata, true); - ieee80211_recalc_idle(local); mutex_unlock(&ifmgd->mtx); + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -2319,7 +2328,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, if (assoc_bss) sta_info_destroy_addr(sdata, bssid); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return 0; } @@ -2357,7 +2368,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, cookie, !req->local_state_change); sta_info_destroy_addr(sdata, bssid); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return 0; } diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index f31f549733b1..31f233f7f51a 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -304,7 +304,9 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) ieee80211_offchannel_return(local, true); done: + mutex_lock(&local->mtx); ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); ieee80211_mlme_notify_scan_completed(local); ieee80211_ibss_notify_scan_completed(local); ieee80211_mesh_notify_scan_completed(local); diff --git a/net/mac80211/work.c b/net/mac80211/work.c index b98af64f5862..ae344d1ba056 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -888,10 +888,10 @@ static void ieee80211_work_work(struct work_struct *work) while ((skb = skb_dequeue(&local->work_skb_queue))) ieee80211_work_rx_queued_mgmt(local, skb); - ieee80211_recalc_idle(local); - mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + list_for_each_entry_safe(wk, tmp, &local->work_list, list) { bool started = wk->started; @@ -1001,10 +1001,10 @@ static void ieee80211_work_work(struct work_struct *work) &local->scan_work, round_jiffies_relative(0)); - mutex_unlock(&local->mtx); - ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); + list_for_each_entry_safe(wk, tmp, &free_work, list) { wk->done(wk, NULL); list_del(&wk->list); -- cgit v1.2.3 From d1f5b7a34aa5ff703c4966ea2652d4212ac75940 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 5 Aug 2010 17:05:55 +0200 Subject: mac80211: allow drivers to request SM PS mode change Sometimes drivers have more information than the stack about how their antennas/chains are used, and may require that the SM PS mode be changed. This could happen, for example, when detecting that the user disconnected an antenna. Thus this patch introduces API to allow drivers to request SM PS mode changes. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 12 ++++++++++++ net/mac80211/ht.c | 28 ++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 6 +++++- net/mac80211/mlme.c | 3 +++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3a3c26f647b7..871ed1de736a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2548,6 +2548,18 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, */ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); +/** + * ieee80211_request_smps - request SM PS transition + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @mode: new SM PS mode + * + * This allows the driver to request an SM PS transition in managed + * mode. This is useful when the driver has more information than + * the stack about possible interference, for example by bluetooth. + */ +void ieee80211_request_smps(struct ieee80211_vif *vif, + enum ieee80211_smps_mode smps_mode); + /* Rate control API */ /** diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9d101fb33861..11f74f5f7b2f 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -265,3 +265,31 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, return 0; } + +void ieee80211_request_smps_work(struct work_struct *work) +{ + struct ieee80211_sub_if_data *sdata = + container_of(work, struct ieee80211_sub_if_data, + u.mgd.request_smps_work); + + mutex_lock(&sdata->u.mgd.mtx); + __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); + mutex_unlock(&sdata->u.mgd.mtx); +} + +void ieee80211_request_smps(struct ieee80211_vif *vif, + enum ieee80211_smps_mode smps_mode) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + + if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) + return; + + if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) + smps_mode = IEEE80211_SMPS_AUTOMATIC; + + ieee80211_queue_work(&sdata->local->hw, + &sdata->u.mgd.request_smps_work); +} +/* this might change ... don't want non-open drivers using it */ +EXPORT_SYMBOL_GPL(ieee80211_request_smps); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 98e783c6a363..1bf05bfd149d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -343,7 +343,10 @@ struct ieee80211_if_managed { unsigned long timers_running; /* used for quiesce/restart */ bool powersave; /* powersave requested for this iface */ enum ieee80211_smps_mode req_smps, /* requested smps mode */ - ap_smps; /* smps mode AP thinks we're in */ + ap_smps, /* smps mode AP thinks we're in */ + driver_smps_mode; /* smps mode request */ + + struct work_struct request_smps_work; unsigned int flags; @@ -1113,6 +1116,7 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps, const u8 *da, const u8 *bssid); +void ieee80211_request_smps_work(struct work_struct *work); void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, u16 initiator, u16 reason); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 82e7cec5179c..38996a44aa8e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1926,6 +1926,8 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) * time -- the code here is properly synchronised. */ + cancel_work_sync(&ifmgd->request_smps_work); + cancel_work_sync(&ifmgd->beacon_connection_loss_work); if (del_timer_sync(&ifmgd->timer)) set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); @@ -1961,6 +1963,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); INIT_WORK(&ifmgd->beacon_connection_loss_work, ieee80211_beacon_connection_loss_work); + INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work); setup_timer(&ifmgd->timer, ieee80211_sta_timer, (unsigned long) sdata); setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, -- cgit v1.2.3 From 04600794958f1833f5571c6cde40f260ab557f55 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 5 Aug 2010 17:45:15 +0200 Subject: cfg80211: support sysfs namespaces Enable using network namespaces with wireless devices even when sysfs is enabled using the same infrastructure that was built for netdevs. Signed-off-by: Johannes Berg Acked-by: "Eric W. Biederman" Signed-off-by: John W. Linville --- include/linux/netdevice.h | 2 ++ net/core/net-sysfs.c | 3 ++- net/wireless/core.c | 7 ++++++- net/wireless/sysfs.c | 9 +++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 46c36ffe20ee..a4b14fd81c6a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2171,6 +2171,8 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern int netdev_class_create_file(struct class_attribute *class_attr); extern void netdev_class_remove_file(struct class_attribute *class_attr); +extern struct kobj_ns_type_operations net_ns_type_operations; + extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len); extern void linkwatch_run_queue(void); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index af4dfbadf2a0..7d748542d97e 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -789,12 +789,13 @@ static const void *net_netlink_ns(struct sock *sk) return sock_net(sk); } -static struct kobj_ns_type_operations net_ns_type_operations = { +struct kobj_ns_type_operations net_ns_type_operations = { .type = KOBJ_NS_TYPE_NET, .current_ns = net_current_ns, .netlink_ns = net_netlink_ns, .initial_ns = net_initial_ns, }; +EXPORT_SYMBOL_GPL(net_ns_type_operations); static void net_kobj_ns_exit(struct net *net) { diff --git a/net/wireless/core.c b/net/wireless/core.c index 541e2fff5e9c..c70909c3eae4 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -253,11 +253,16 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, WARN_ON(err); wdev->netdev->features |= NETIF_F_NETNS_LOCAL; } + + return err; } wiphy_net_set(&rdev->wiphy, net); - return err; + err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev)); + WARN_ON(err); + + return 0; } static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 9f2cef3e0ca0..74a9e3cce452 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -110,6 +110,13 @@ static int wiphy_resume(struct device *dev) return ret; } +static const void *wiphy_namespace(struct device *d) +{ + struct wiphy *wiphy = container_of(d, struct wiphy, dev); + + return wiphy_net(wiphy); +} + struct class ieee80211_class = { .name = "ieee80211", .owner = THIS_MODULE, @@ -120,6 +127,8 @@ struct class ieee80211_class = { #endif .suspend = wiphy_suspend, .resume = wiphy_resume, + .ns_type = &net_ns_type_operations, + .namespace = wiphy_namespace, }; int wiphy_sysfs_init(void) -- cgit v1.2.3 From 2674f82d3eef97df98fd5dbd4224ce1ce4800a3b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 22:23:54 +0200 Subject: drivers/net/wireless/libertas: Adjust confusing if indentation At the point of the patched code, err has already been tested, so it is only worthwhile to test it again in the if branches where it is changed. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index fe3f08028eb3..3965c6cf504a 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -800,14 +800,16 @@ static int lbs_spi_thread(void *data) goto err; } - if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) + if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) { err = if_spi_c2h_cmd(card); if (err) goto err; - if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) + } + if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) { err = if_spi_c2h_data(card); if (err) goto err; + } /* workaround: in PS mode, the card does not set the Command * Download Ready bit, but it sets TX Download Ready. */ -- cgit v1.2.3 From a3d558355e7695ca78fc3f0df611af482096bd87 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 22:26:04 +0200 Subject: drivers/net/wireless/prism54: Adjust confusing if indentation Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- drivers/net/wireless/prism54/isl_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 77cd65db8500..d97a2caf582b 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -3234,7 +3234,7 @@ prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) switch (cmd) { case PRISM54_HOSTAPD: if (!capable(CAP_NET_ADMIN)) - return -EPERM; + return -EPERM; ret = prism54_hostapd(ndev, &wrq->u.data); return ret; } -- cgit v1.2.3 From 6fe140024ff66d7eccde1a151a08c262dc7a1e6f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 22:26:56 +0200 Subject: drivers/net/wireless/ath/ath9k: Adjust confusing if indentation Outdent the code following the if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 5b995bee70ae..a462da23e87e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -185,7 +185,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ath_print(common, ATH_DBG_INTERRUPT, "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); - REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); + REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); } -- cgit v1.2.3 From c17512d846a4b063c8d3e708d82c0664d9c7182e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 5 Aug 2010 17:56:54 -0400 Subject: ath9k: remove duplicate get_hw_crypto_keytype() Use ath9k_cmn_get_hw_crypto_keytype() instead which is already exported and shared, and does exactly the same thing. Reported-by: Johannes Berg Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 4dda14e36227..457f07692ac7 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1407,22 +1407,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static int get_hw_crypto_keytype(struct sk_buff *skb) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - - if (tx_info->control.hw_key) { - if (tx_info->control.hw_key->alg == ALG_WEP) - return ATH9K_KEY_TYPE_WEP; - else if (tx_info->control.hw_key->alg == ALG_TKIP) - return ATH9K_KEY_TYPE_TKIP; - else if (tx_info->control.hw_key->alg == ALG_CCMP) - return ATH9K_KEY_TYPE_AES; - } - - return ATH9K_KEY_TYPE_CLEAR; -} - static void assign_aggr_tid_seqno(struct sk_buff *skb, struct ath_buf *bf) { @@ -1661,7 +1645,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_state.bfs_paprd_timestamp = jiffies; bf->bf_flags = setup_tx_flags(skb, use_ldpc); - bf->bf_keytype = get_hw_crypto_keytype(skb); + bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { bf->bf_frmlen += tx_info->control.hw_key->icv_len; bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; -- cgit v1.2.3 From 7e613e1666d59b5364f7918b3427bf328ac5f9ca Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:45:38 +0200 Subject: rt2x00: Move USB tx/rx done handling to workqueue Move all TX and RX completion handling into a work structure, which is handeled on the mac80211 workqueue. This simplifies the code in rt2x00lib since it no longer needs to check if the device is USB or PCI to decide which mac80211 function should be used. In the watchdog some changes are needed since it can no longer rely on the TX completion function to be run while looping through the entries. (Both functions now work on the same workqueue, so this would deadlock). So the watchdog now waits for the URB to return, and handle the TX status report directly. As a side-effect, the debugfs entry for the RX queue now correctly displays the positions of the INDEX and INDEX_DONE counters. This also implies that it is not possible to perform checks like queue_empty() and queue_full() on the RX queue. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 9 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 35 +++----- drivers/net/wireless/rt2x00/rt2x00queue.c | 7 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 6 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 133 ++++++++++++++++++++++-------- 5 files changed, 128 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c21af38cc5af..5276c19f380a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn Copyright (C) 2004 - 2009 Gertjan van Wingerde @@ -862,6 +863,12 @@ struct rt2x00_dev { */ struct work_struct intf_work; + /** + * Scheduled work for TX/RX done handling (USB devices) + */ + struct work_struct rxdone_work; + struct work_struct txdone_work; + /* * Data queue arrays for RX, TX and Beacon. * The Beacon array also contains the Atim queue diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 585e8166f22a..94621bd4fb9b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -383,15 +384,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * send the status report back. */ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - /* - * Only PCI and SOC devices process the tx status in process - * context. Hence use ieee80211_tx_status for PCI and SOC - * devices and stick to ieee80211_tx_status_irqsafe for USB. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_tx_status(rt2x00dev->hw, entry->skb); + ieee80211_tx_status(rt2x00dev->hw, entry->skb); else dev_kfree_skb_any(entry->skb); @@ -403,7 +396,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00dev->ops->lib->clear_entry(entry); - clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* @@ -463,6 +455,10 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; unsigned int header_length; int rate_idx; + + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + goto submit_entry; + /* * Allocate a new sk_buffer. If no new buffer available, drop the * received frame and reuse the existing buffer. @@ -540,26 +536,17 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, */ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); - - /* - * Currently only PCI and SOC devices handle rx interrupts in process - * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni - * for PCI and SOC devices. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_rx_ni(rt2x00dev->hw, entry->skb); + ieee80211_rx_ni(rt2x00dev->hw, entry->skb); /* * Replace the skb with the freshly allocated one. */ entry->skb = skb; - entry->flags = 0; +submit_entry: rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -1017,6 +1004,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); + cancel_work_sync(&rt2x00dev->rxdone_work); + cancel_work_sync(&rt2x00dev->txdone_work); /* * Uninitialize device. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a3401d301058..18220953851e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn Copyright (C) 2004 - 2009 Gertjan van Wingerde @@ -730,9 +731,9 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00queue_reset(queue); for (i = 0; i < queue->limit; i++) { - queue->entries[i].flags = 0; - rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); + if (queue->qid == QID_RX) + rt2x00queue_index_inc(queue, Q_INDEX); } } } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 191e7775a9c0..38b47919c868 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -363,12 +363,16 @@ struct txentry_desc { * the device has signaled it is done with it. * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting * for the signal to start sending. + * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured + * while transfering the data to the hardware. No TX status report will + * be expected from the hardware. */ enum queue_entry_flags { ENTRY_BCN_ASSIGNED, ENTRY_OWNER_DEVICE_DATA, ENTRY_OWNER_DEVICE_CRYPTO, ENTRY_DATA_PENDING, + ENTRY_DATA_IO_FAILED }; /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ff3a36622d1b..3f131017fd21 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -167,19 +168,12 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); /* * TX data handlers. */ -static void rt2x00usb_interrupt_txdone(struct urb *urb) +static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) { - struct queue_entry *entry = (struct queue_entry *)urb->context; - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) - return; - /* - * Obtain the status about this packet. - * Note that when the status is 0 it does not mean the + * If the transfer to hardware succeeded, it does not mean the * frame was send out correctly. It only means the frame * was succesfully pushed to the hardware, we have no * way to determine the transmission status right now. @@ -187,15 +181,56 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * in the register). */ txdesc.flags = 0; - if (!urb->status) - __set_bit(TXDONE_UNKNOWN, &txdesc.flags); - else + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) __set_bit(TXDONE_FAILURE, &txdesc.flags); + else + __set_bit(TXDONE_UNKNOWN, &txdesc.flags); txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); } +static void rt2x00usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + struct data_queue *queue; + struct queue_entry *entry; + + tx_queue_for_each(rt2x00dev, queue) { + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; + + rt2x00usb_work_txdone_entry(entry); + } + } +} + +static void rt2x00usb_interrupt_txdone(struct urb *urb) +{ + struct queue_entry *entry = (struct queue_entry *)urb->context; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || + !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; + + /* + * Check if the frame was correctly uploaded + */ + if (urb->status) + __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + + /* + * Schedule the delayed work for reading the TX status + * from the device. + */ + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); +} + static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; @@ -294,6 +329,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) { + struct queue_entry *entry; struct queue_entry_priv_usb *entry_priv; unsigned short threshold = queue->threshold; @@ -313,14 +349,22 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) * Reset all currently uploaded TX frames. */ while (!rt2x00queue_empty(queue)) { - entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data; + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + entry_priv = entry->priv_data; usb_kill_urb(entry_priv->urb); /* * We need a short delay here to wait for - * the URB to be canceled and invoked the tx_done handler. + * the URB to be canceled */ - udelay(200); + do { + udelay(100); + } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); + + /* + * Invoke the TX done handler + */ + rt2x00usb_work_txdone_entry(entry); } /* @@ -345,15 +389,41 @@ EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); /* * RX data handlers. */ +static void rt2x00usb_work_rxdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, rxdone_work); + struct queue_entry *entry; + struct skb_frame_desc *skbdesc; + u8 rxd[32]; + + while (!rt2x00queue_empty(rt2x00dev->rx)) { + entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; + + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = rxd; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(rt2x00dev, entry); + } +} + static void rt2x00usb_interrupt_rxdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - u8 rxd[32]; if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -361,22 +431,14 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * to be actually valid, or if the urb is signaling * a problem. */ - if (urb->actual_length < entry->queue->desc_size || urb->status) { - set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(urb, GFP_ATOMIC); - return; - } - - /* - * Fill in desc fields of the skb descriptor - */ - skbdesc->desc = rxd; - skbdesc->desc_len = entry->queue->desc_size; + if (urb->actual_length < entry->queue->desc_size || urb->status) + __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); /* - * Send the frame to rt2x00lib for further processing. + * Schedule the delayed work for reading the RX status + * from the device. */ - rt2x00lib_rxdone(rt2x00dev, entry); + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); } /* @@ -405,6 +467,8 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) struct queue_entry_priv_usb *entry_priv = entry->priv_data; int pipe; + entry->flags = 0; + if (entry->queue->qid == QID_RX) { pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, @@ -413,8 +477,6 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); usb_submit_urb(entry_priv->urb, GFP_ATOMIC); - } else { - entry->flags = 0; } } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); @@ -659,6 +721,9 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); + INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); + INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); + retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) goto exit_free_device; -- cgit v1.2.3 From 84804cdca043e2315bf5eae60807ac105929073f Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:46:19 +0200 Subject: rt2x00: Set MIMO PS flag in tx descriptor for STAs in dynamic SMPS mode Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- drivers/net/wireless/rt2x00/rt2x00ht.c | 10 ++++++++++ drivers/net/wireless/rt2x00/rt2x00queue.h | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b66e0fd8f0fa..833b15751292 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -437,7 +437,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) rt2x00_desc_read(txwi, 0, &word); rt2x00_set_field32(&word, TXWI_W0_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); - rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); + rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, + test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags)); rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); rt2x00_set_field32(&word, TXWI_W0_TS, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index c004cd3a8847..ad3c7ff4837b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -54,6 +54,16 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, */ if (txrate->flags & IEEE80211_TX_RC_MCS) { txdesc->mcs = txrate->idx; + + /* + * MIMO PS should be set to 1 for STA's using dynamic SM PS + * when using more then one tx stream (>MCS7). + */ + if (tx_info->control.sta && txdesc->mcs > 7 && + (tx_info->control.sta->ht_cap.cap & + (WLAN_HT_CAP_SM_PS_DYNAMIC << + IEEE80211_HT_CAP_SM_PS_SHIFT))) + __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); } else { txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 38b47919c868..2d3bf843735f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -268,6 +268,7 @@ struct txdone_entry_desc { * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU. * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth. * @ENTRY_TXD_HT_SHORT_GI: Use short GI. + * @ENTRY_TXD_HT_MIMO_PS: The receiving STA is in dynamic SM PS mode. */ enum txentry_desc_flags { ENTRY_TXD_RTS_FRAME, @@ -286,6 +287,7 @@ enum txentry_desc_flags { ENTRY_TXD_HT_AMPDU, ENTRY_TXD_HT_BW_40, ENTRY_TXD_HT_SHORT_GI, + ENTRY_TXD_HT_MIMO_PS, }; /** -- cgit v1.2.3 From 3392beced38f67615b7fc88374940cecec6a0e4f Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:46:53 +0200 Subject: rt2x00: Add helper function for reporting tx status At some points, some drivers can't report the full TX status information. This can happen for the UNKNOWN state, or the FAILURE state (in case the URB failed). Add a wrapper function to simplify reporting the empty TX information. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00dev.c | 12 ++++++++++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 10 ++-------- drivers/net/wireless/rt2x00/rt61pci.c | 6 +----- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 5276c19f380a..edfc2b759282 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1078,6 +1078,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); +void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 94621bd4fb9b..6499cc416ca3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -408,6 +408,18 @@ void rt2x00lib_txdone(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); +void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) +{ + struct txdone_entry_desc txdesc; + + txdesc.flags = 0; + __set_bit(status, &txdesc.flags); + txdesc.retry = 0; + + rt2x00lib_txdone(entry, &txdesc); +} +EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); + static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, struct rxdone_entry_desc *rxdesc) { diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 3f131017fd21..f76014f732ce 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -170,8 +170,6 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); */ static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) { - struct txdone_entry_desc txdesc; - /* * If the transfer to hardware succeeded, it does not mean the * frame was send out correctly. It only means the frame @@ -180,14 +178,10 @@ static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) * (Only indirectly by looking at the failed TX counters * in the register). */ - txdesc.flags = 0; if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) - __set_bit(TXDONE_FAILURE, &txdesc.flags); + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); else - __set_bit(TXDONE_UNKNOWN, &txdesc.flags); - txdesc.retry = 0; - - rt2x00lib_txdone(entry, &txdesc); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); } static void rt2x00usb_work_txdone(struct work_struct *work) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e539c6cb636f..dc6f3ebb8376 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2107,11 +2107,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) "TX status report missed for entry %d\n", entry_done->entry_idx); - txdesc.flags = 0; - __set_bit(TXDONE_UNKNOWN, &txdesc.flags); - txdesc.retry = 0; - - rt2x00lib_txdone(entry_done, &txdesc); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); } -- cgit v1.2.3 From 0c5879bc62f9b8eb31520a86213466f3a68ec794 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:47:20 +0200 Subject: rt2x00: Request TXWI pointer from driver The only reason why the write_tx_data callback function is needed inside the driver, is because the location of the TXWI descriptor is different on PCI and USB hardware. Except for the beacon, where the TXWI is always at the start of the SKB buffer. In both cases the drivers write_tx_data function only wrap around the function rt2800_write_txwi. Move write_tx_data completely into the rt2800lib library, and add a callback function to obtain the TXWI pointer. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 8 +++++--- drivers/net/wireless/rt2x00/rt2800lib.h | 11 ++++++++++- drivers/net/wireless/rt2x00/rt2800pci.c | 11 ++++------- drivers/net/wireless/rt2x00/rt2800usb.c | 14 +++++++------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 833b15751292..6f1eb5824d2d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -427,8 +427,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2800_load_firmware); -void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) +void rt2800_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc) { + __le32 *txwi = rt2800_drv_get_txwi(entry); u32 word; /* @@ -479,7 +481,7 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); } -EXPORT_SYMBOL_GPL(rt2800_write_txwi); +EXPORT_SYMBOL_GPL(rt2800_write_tx_data); static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) { @@ -601,7 +603,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) /* * Add the TXWI for the beacon to the skb. */ - rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); + rt2800_write_tx_data(entry, txdesc); /* * Dump beacon to userspace through debugfs. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 091641e3c5e2..8f975180727f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -44,6 +44,7 @@ struct rt2800_ops { int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); + __le32 *(*drv_get_txwi)(struct queue_entry *entry); }; static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, @@ -126,6 +127,13 @@ static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev) return rt2800ops->drv_init_registers(rt2x00dev); } +static inline __le32 *rt2800_drv_get_txwi(struct queue_entry *entry) +{ + const struct rt2800_ops *rt2800ops = entry->queue->rt2x00dev->ops->drv; + + return rt2800ops->drv_get_txwi(entry); +} + void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1); @@ -135,7 +143,8 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); -void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc); +void rt2800_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc); void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 39b3846fa340..f415f6d5f601 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -566,15 +566,11 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2800pci_write_tx_data(struct queue_entry* entry, - struct txentry_desc *txdesc) +static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) { - __le32 *txwi = (__le32 *) entry->skb->data; - - rt2800_write_txwi(txwi, txdesc); + return (__le32 *) entry->skb->data; } - static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc) @@ -1011,6 +1007,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { .regbusy_read = rt2x00pci_regbusy_read, .drv_write_firmware = rt2800pci_write_firmware, .drv_init_registers = rt2800pci_init_registers, + .drv_get_txwi = rt2800pci_get_txwi, }; static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { @@ -1030,7 +1027,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, .write_tx_desc = rt2800pci_write_tx_desc, - .write_tx_data = rt2800pci_write_tx_data, + .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .kick_tx_queue = rt2800pci_kick_tx_queue, .kill_tx_queue = rt2800pci_kill_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5a2dfe87c6b6..9084b9a36b57 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -320,15 +320,14 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2800usb_write_tx_data(struct queue_entry* entry, - struct txentry_desc *txdesc) +static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) { - __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); - - rt2800_write_txwi(txwi, txdesc); + if (entry->queue->qid == QID_BEACON) + return (__le32 *) (entry->skb->data); + else + return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); } - static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc) @@ -549,6 +548,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { .regbusy_read = rt2x00usb_regbusy_read, .drv_write_firmware = rt2800usb_write_firmware, .drv_init_registers = rt2800usb_init_registers, + .drv_get_txwi = rt2800usb_get_txwi, }; static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { @@ -566,7 +566,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .watchdog = rt2x00usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2800usb_write_tx_data, + .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, -- cgit v1.2.3 From 96481b20f4d6df7021867ae9a9deaa989ec32e40 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:47:57 +0200 Subject: rt2x00: Implement TX status reporting for rt2800usb The TX_STA_FIFO register which is used for per-frame TX frame status reporting is also valid on rt2800usb. We can move the rt2800pci_txdone function into rt2800lib where it can also be used by rt2800usb. rt2800usb needs to overwrite the txdone work handler to a different function. Both rt2800usb as rt2800_txdone need to take into account that IO failures can occur while uploading the URB, which means that when obtaining the new entry the IO status must be checked. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 117 ++++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.h | 4 ++ drivers/net/wireless/rt2x00/rt2800pci.c | 108 +---------------------------- drivers/net/wireless/rt2x00/rt2800usb.c | 40 ++++++++++- 4 files changed, 162 insertions(+), 107 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6f1eb5824d2d..827a2580893b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1,4 +1,5 @@ /* + Copyright (C) 2010 Willow Garage Copyright (C) 2010 Ivo van Doorn Copyright (C) 2009 Bartlomiej Zolnierkiewicz Copyright (C) 2009 Gertjan van Wingerde @@ -572,6 +573,122 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); +void rt2800_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + __le32 *txwi; + struct txdone_entry_desc txdesc; + u32 word; + u32 reg; + int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; + u16 mcs, real_mcs; + int i; + + /* + * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO + * at most X times and also stop processing once the TX_STA_FIFO_VALID + * flag is not set anymore. + * + * The legacy drivers use X=TX_RING_SIZE but state in a comment + * that the TX_STA_FIFO stack has a size of 16. We stick to our + * tx ring size for now. + */ + for (i = 0; i < TX_ENTRIES; i++) { + rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); + if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) + break; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + + /* + * Skip this entry when it contains an invalid + * queue identication number. + */ + if (pid <= 0 || pid > QID_RX) + continue; + + queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); + if (unlikely(!queue)) + continue; + + /* + * Inside each queue, we process each entry in a chronological + * order. We first check that the queue is not empty. + */ + entry = NULL; + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (!test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + break; + + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + } + + if (!entry || rt2x00queue_empty(queue)) + break; + + /* + * Check if we got a match by looking at WCID/ACK/PID + * fields + */ + txwi = rt2800_drv_get_txwi(entry); + + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); + + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) + WARNING(rt2x00dev, "invalid TX_STA_FIFO content"); + + /* + * Obtain the status about this packet. + */ + txdesc.flags = 0; + rt2x00_desc_read(txwi, 0, &word); + mcs = rt2x00_get_field32(word, TXWI_W0_MCS); + mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); + real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); + + /* + * Ralink has a retry mechanism using a global fallback + * table. We setup this fallback table to try the immediate + * lower rate for all rates. In the TX_STA_FIFO, the MCS field + * always contains the MCS used for the last transmission, be + * it successful or not. + */ + if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { + /* + * Transmission succeeded. The number of retries is + * mcs - real_mcs + */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); + } else { + /* + * Transmission failed. The number of retries is + * always 7 in this case (for a total number of 8 + * frames sent). + */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + txdesc.retry = rt2x00dev->long_retry; + } + + /* + * the frame was retried at least once + * -> hw used fallback rates + */ + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); + + rt2x00lib_txdone(entry, &txdesc); + } +} +EXPORT_SYMBOL_GPL(rt2800_txdone); + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 8f975180727f..3b572c63382d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -1,4 +1,6 @@ /* + Copyright (C) 2010 Willow Garage + Copyright (C) 2010 Ivo van Doorn Copyright (C) 2009 Bartlomiej Zolnierkiewicz This program is free software; you can redistribute it and/or modify @@ -147,6 +149,8 @@ void rt2800_write_tx_data(struct queue_entry *entry, struct txentry_desc *txdesc); void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); +void rt2800_txdone(struct rt2x00_dev *rt2x00dev); + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); extern const struct rt2x00debug rt2800_rt2x00debug; diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index f415f6d5f601..4390f2b74b2e 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Ivo van Doorn + Copyright (C) 2009 - 2010 Ivo van Doorn Copyright (C) 2009 Alban Browaeys Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Luis Correia @@ -724,110 +724,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, /* * Interrupt functions. */ -static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - struct queue_entry *entry; - __le32 *txwi; - struct txdone_entry_desc txdesc; - u32 word; - u32 reg; - int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; - u16 mcs, real_mcs; - int i; - - /* - * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO - * at most X times and also stop processing once the TX_STA_FIFO_VALID - * flag is not set anymore. - * - * The legacy drivers use X=TX_RING_SIZE but state in a comment - * that the TX_STA_FIFO stack has a size of 16. We stick to our - * tx ring size for now. - */ - for (i = 0; i < TX_ENTRIES; i++) { - rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); - if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) - break; - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - - /* - * Skip this entry when it contains an invalid - * queue identication number. - */ - if (pid <= 0 || pid > QID_RX) - continue; - - queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); - if (unlikely(!queue)) - continue; - - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - if (rt2x00queue_empty(queue)) - continue; - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - - /* Check if we got a match by looking at WCID/ACK/PID - * fields */ - txwi = (__le32 *) entry->skb->data; - - rt2x00_desc_read(txwi, 1, &word); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) - WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n"); - - /* - * Obtain the status about this packet. - */ - txdesc.flags = 0; - rt2x00_desc_read(txwi, 0, &word); - mcs = rt2x00_get_field32(word, TXWI_W0_MCS); - real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); - - /* - * Ralink has a retry mechanism using a global fallback - * table. We setup this fallback table to try the immediate - * lower rate for all rates. In the TX_STA_FIFO, the MCS field - * always contains the MCS used for the last transmission, be - * it successful or not. - */ - if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { - /* - * Transmission succeeded. The number of retries is - * mcs - real_mcs - */ - __set_bit(TXDONE_SUCCESS, &txdesc.flags); - txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); - } else { - /* - * Transmission failed. The number of retries is - * always 7 in this case (for a total number of 8 - * frames sent). - */ - __set_bit(TXDONE_FAILURE, &txdesc.flags); - txdesc.retry = 7; - } - - /* - * the frame was retried at least once - * -> hw used fallback rates - */ - if (txdesc.retry) - __set_bit(TXDONE_FALLBACK, &txdesc.flags); - - rt2x00lib_txdone(entry, &txdesc); - } -} - static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) { struct ieee80211_conf conf = { .flags = 0 }; @@ -863,7 +759,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) * 4 - Tx done interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800pci_txdone(rt2x00dev); + rt2800_txdone(rt2x00dev); /* * 5 - Auto wakeup interrupt. diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9084b9a36b57..9ad28be294eb 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2009 - 2010 Ivo van Doorn Copyright (C) 2009 Mattias Nissler Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Xose Vazquez Perez @@ -377,6 +378,38 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) return length; } +/* + * TX control handlers + */ +static void rt2800usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + struct data_queue *queue; + struct queue_entry *entry; + + rt2800_txdone(rt2x00dev); + + /* + * Process any trailing TX status reports for IO failures, + * we loop until we find the first non-IO error entry. This + * can either be a frame which is free, is being uploaded, + * or has completed the upload but didn't have an entry + * in the TX_STAT_FIFO register yet. + */ + tx_queue_for_each(rt2x00dev, queue) { + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + break; + + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + } + } +} + /* * RX control handlers */ @@ -513,6 +546,11 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; + /* + * Overwrite TX done handler + */ + PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); + return 0; } -- cgit v1.2.3 From 0856d9c04a1655612abd96793c1e8b1c1792457e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 6 Aug 2010 20:48:27 +0200 Subject: rt2x00: Update comments regarding TXWI and TX_STA_FIFO Add some comments about the TXWI fields and the TX_STA_FIFO register. Especially describe the relationship between the TXWI field PACKETID and the PID field in the TX_STA_FIFO register. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ed4ebcdde7c9..cf1f16bfcd5e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1318,7 +1318,25 @@ #define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000) /* - * TX_STA_FIFO: TX Result for specific PID status fifo register + * TX_STA_FIFO: TX Result for specific PID status fifo register. + * + * This register is implemented as FIFO with 16 entries in the HW. Each + * register read fetches the next tx result. If the FIFO is full because + * it wasn't read fast enough after the according interrupt (TX_FIFO_STATUS) + * triggered, the hw seems to simply drop further tx results. + * + * VALID: 1: this tx result is valid + * 0: no valid tx result -> driver should stop reading + * PID_TYPE: The PID latched from the PID field in the TXWI, can be used + * to match a frame with its tx result (even though the PID is + * only 4 bits wide). + * TX_SUCCESS: Indicates tx success (1) or failure (0) + * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) + * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) + * WCID: The wireless client ID. + * MCS: The tx rate used during the last transmission of this frame, be it + * successful or not. + * PHYMODE: The phymode used for the transmission. */ #define TX_STA_FIFO 0x1718 #define TX_STA_FIFO_VALID FIELD32(0x00000001) @@ -1945,6 +1963,13 @@ struct mac_iveiv_entry { /* * Word1 + * ACK: 0: No Ack needed, 1: Ack needed + * NSEQ: 0: Don't assign hw sequence number, 1: Assign hw sequence number + * BW_WIN_SIZE: BA windows size of the recipient + * WIRELESS_CLI_ID: Client ID for WCID table access + * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame + * PACKETID: Will be latched into the TX_STA_FIFO register once the according + * frame was processed. 0: Don't report tx status for this frame. */ #define TXWI_W1_ACK FIELD32(0x00000001) #define TXWI_W1_NSEQ FIELD32(0x00000002) -- cgit v1.2.3 From e5ef5bad345f97f1fef7ccdc01a88c298629a5d9 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Fri, 6 Aug 2010 20:49:27 +0200 Subject: rt2x00: Remove ieee80211_rx_status from rt2x00_dev rt2x00 was keeping a copy of ieee80211_rx_status embedded into the rt2x00_dev structure. For each RX frame, this structure was copied into the skb->cb where mac80211 would handle it further. However at the moment only the fields current band, and frequency were updated. Whereas the band was already provided directly within the rt2x00_dev structure. Save a memcpy action, and reduce memory a bit, by adding a curr_freq field to rt2x00_dev, and completely remove the ieee80211_rx_status structure from rt2x00_dev. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 6 +----- drivers/net/wireless/rt2x00/rt2x00config.c | 4 +--- drivers/net/wireless/rt2x00/rt2x00dev.c | 16 +++++++++------- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 4 ++-- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 827a2580893b..3a150d3a9d9f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -494,7 +494,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) u8 offset1; u8 offset2; - if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index edfc2b759282..8c65244a847a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -699,6 +699,7 @@ struct rt2x00_dev { struct ieee80211_hw *hw; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; enum ieee80211_band curr_band; + int curr_freq; /* * If enabled, the debugfs interface structures @@ -850,11 +851,6 @@ struct rt2x00_dev { */ struct ieee80211_low_level_stats low_level_stats; - /* - * RX configuration information. - */ - struct ieee80211_rx_status rx_status; - /* * Scheduled work. * NOTE: intf_work will use ieee80211_iterate_active_interfaces() diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index fb23af40008b..34f34fa7f53a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -201,10 +201,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, rt2x00link_reset_tuner(rt2x00dev, false); rt2x00dev->curr_band = conf->channel->band; + rt2x00dev->curr_freq = conf->channel->center_freq; rt2x00dev->tx_power = conf->power_level; rt2x00dev->short_retry = conf->short_frame_max_tx_count; rt2x00dev->long_retry = conf->long_frame_max_tx_count; - - rt2x00dev->rx_status.band = conf->channel->band; - rt2x00dev->rx_status.freq = conf->channel->center_freq; } diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 6499cc416ca3..e692608bee8b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -464,7 +464,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, { struct rxdone_entry_desc rxdesc; struct sk_buff *skb; - struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; + struct ieee80211_rx_status *rx_status; unsigned int header_length; int rate_idx; @@ -535,19 +535,21 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, */ rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); rt2x00debug_update_crypto(rt2x00dev, &rxdesc); + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); + /* + * Initialize RX status information, and send frame + * to mac80211. + */ + rx_status = IEEE80211_SKB_RXCB(entry->skb); rx_status->mactime = rxdesc.timestamp; + rx_status->band = rt2x00dev->curr_band; + rx_status->freq = rt2x00dev->curr_freq; rx_status->rate_idx = rate_idx; rx_status->signal = rxdesc.rssi; rx_status->flag = rxdesc.flags; rx_status->antenna = rt2x00dev->link.ant.active.rx; - /* - * Send frame to mac80211 & debugfs. - * mac80211 will clean up the skb structure. - */ - rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); - memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); ieee80211_rx_ni(rt2x00dev->hw, entry->skb); /* diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index dc6f3ebb8376..cff503faac65 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1050,7 +1050,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, /* * Determine r17 bounds. */ - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { @@ -1972,7 +1972,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) return 0; } - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { if (lna == 3 || lna == 2) offset += 10; } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9de18fd410..c65529678fbd 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -929,7 +929,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, /* * Determine r17 bounds. */ - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; @@ -1597,7 +1597,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) return 0; } - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { if (lna == 3 || lna == 2) offset += 10; -- cgit v1.2.3 From 5cddea816eec8b5f6ab76d3fafcbb1533c8c2b9d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 Aug 2010 21:13:57 -0500 Subject: libertas: [usb] use new firmware locations Look for firmware where the linux-firmware tree actually puts it, but fall back to original firmware name & location when the new location doesn't exist. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_usb.c | 60 ++++++++++++++++++++++++++++++---- drivers/net/wireless/libertas/if_usb.h | 1 + 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 07ece9d26c63..238de10a4b57 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -26,15 +26,25 @@ #define MESSAGE_HEADER_LEN 4 -static char *lbs_fw_name = "usb8388.bin"; +static char *lbs_fw_name = NULL; module_param_named(fw_name, lbs_fw_name, charp, 0644); +MODULE_FIRMWARE("libertas/usb8388_v9.bin"); +MODULE_FIRMWARE("libertas/usb8388_v5.bin"); +MODULE_FIRMWARE("libertas/usb8388.bin"); +MODULE_FIRMWARE("libertas/usb8682.bin"); MODULE_FIRMWARE("usb8388.bin"); +enum { + MODEL_UNKNOWN = 0x0, + MODEL_8388 = 0x1, + MODEL_8682 = 0x2 +}; + static struct usb_device_id if_usb_table[] = { /* Enter the device signature inside */ - { USB_DEVICE(0x1286, 0x2001) }, - { USB_DEVICE(0x05a3, 0x8388) }, + { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 }, + { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 }, {} /* Terminating entry */ }; @@ -66,6 +76,8 @@ static ssize_t if_usb_firmware_set(struct device *dev, struct if_usb_card *cardp = priv->card; int ret; + BUG_ON(buf == NULL); + ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW); if (ret == 0) return count; @@ -91,6 +103,8 @@ static ssize_t if_usb_boot2_set(struct device *dev, struct if_usb_card *cardp = priv->card; int ret; + BUG_ON(buf == NULL); + ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2); if (ret == 0) return count; @@ -244,6 +258,7 @@ static int if_usb_probe(struct usb_interface *intf, init_waitqueue_head(&cardp->fw_wq); cardp->udev = udev; + cardp->model = (uint32_t) id->driver_info; iface_desc = intf->cur_altsetting; lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" @@ -921,6 +936,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp, return ret; } +/* table of firmware file names */ +static const struct { + u32 model; + const char *fwname; +} fw_table[] = { + { MODEL_8388, "libertas/usb8388_v9.bin" }, + { MODEL_8388, "libertas/usb8388_v5.bin" }, + { MODEL_8388, "libertas/usb8388.bin" }, + { MODEL_8388, "usb8388.bin" }, + { MODEL_8682, "libertas/usb8682.bin" } +}; + +static int get_fw(struct if_usb_card *cardp, const char *fwname) +{ + int i; + + /* Try user-specified firmware first */ + if (fwname) + return request_firmware(&cardp->fw, fwname, &cardp->udev->dev); + + /* Otherwise search for firmware to use */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (fw_table[i].model != cardp->model) + continue; + if (request_firmware(&cardp->fw, fw_table[i].fwname, + &cardp->udev->dev) == 0) + return 0; + } + + return -ENOENT; +} + static int __if_usb_prog_firmware(struct if_usb_card *cardp, const char *fwname, int cmd) { @@ -930,10 +977,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp, lbs_deb_enter(LBS_DEB_USB); - ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev); - if (ret < 0) { - lbs_pr_err("request_firmware() failed with %#x\n", ret); - lbs_pr_err("firmware %s not found\n", fwname); + ret = get_fw(cardp, fwname); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); goto done; } diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index 5ba0aee0eb2f..d819e7e3c9aa 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h @@ -43,6 +43,7 @@ struct bootcmdresp /** USB card description structure*/ struct if_usb_card { struct usb_device *udev; + uint32_t model; /* MODEL_* */ struct urb *rx_urb, *tx_urb; struct lbs_private *priv; -- cgit v1.2.3 From 72f7a6671e8a1433467757e94c883d39eeccd4ba Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 Aug 2010 21:14:33 -0500 Subject: libertas: add two-stage firmware request helper SDIO, GSPI, and CS all use 2-stage firmware and the loading process and logic should be the same. Allow module parameters to override the automatic firmware choice, otherwise just walk the bus driver's firmware table and pick out the first firmware pair that exists for the given model. Some special care is taken to allow overriding of just the helper or the main firmware, but let the other of the pair be chosen automatically. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/decl.h | 13 +++++ drivers/net/wireless/libertas/main.c | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 1d141fefd767..2ae752d10065 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -8,7 +8,14 @@ #define _LBS_DECL_H_ #include +#include +/* Should be terminated by a NULL entry */ +struct lbs_fw_table { + int model; + const char *helper; + const char *fwname; +}; struct lbs_private; struct sk_buff; @@ -53,4 +60,10 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv); u32 lbs_fw_index_to_data_rate(u8 index); u8 lbs_data_rate_to_fw_index(u32 rate); +int lbs_get_firmware(struct device *dev, const char *user_helper, + const char *user_mainfw, u32 card_model, + const struct lbs_fw_table *fw_table, + const struct firmware **helper, + const struct firmware **mainfw); + #endif diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 24958a86747b..47ce5a6ba120 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1047,6 +1047,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx) } EXPORT_SYMBOL_GPL(lbs_notify_command_response); +/** + * @brief Retrieves two-stage firmware + * + * @param dev A pointer to device structure + * @param user_helper User-defined helper firmware file + * @param user_mainfw User-defined main firmware file + * @param card_model Bus-specific card model ID used to filter firmware table + * elements + * @param fw_table Table of firmware file names and device model numbers + * terminated by an entry with a NULL helper name + * @param helper On success, the helper firmware; caller must free + * @param mainfw On success, the main firmware; caller must free + * + * @return 0 on success, non-zero on failure + */ +int lbs_get_firmware(struct device *dev, const char *user_helper, + const char *user_mainfw, u32 card_model, + const struct lbs_fw_table *fw_table, + const struct firmware **helper, + const struct firmware **mainfw) +{ + const struct lbs_fw_table *iter; + int ret; + + BUG_ON(helper == NULL); + BUG_ON(mainfw == NULL); + + /* Try user-specified firmware first */ + if (user_helper) { + ret = request_firmware(helper, user_helper, dev); + if (ret) { + lbs_pr_err("couldn't find helper firmware %s", + user_helper); + goto fail; + } + } + if (user_mainfw) { + ret = request_firmware(mainfw, user_mainfw, dev); + if (ret) { + lbs_pr_err("couldn't find main firmware %s", + user_mainfw); + goto fail; + } + } + + if (*helper && *mainfw) + return 0; + + /* Otherwise search for firmware to use. If neither the helper or + * the main firmware were specified by the user, then we need to + * make sure that found helper & main are from the same entry in + * fw_table. + */ + iter = fw_table; + while (iter && iter->helper) { + if (iter->model != card_model) + goto next; + + if (*helper == NULL) { + ret = request_firmware(helper, iter->helper, dev); + if (ret) + goto next; + + /* If the device has one-stage firmware (ie cf8305) and + * we've got it then we don't need to bother with the + * main firmware. + */ + if (iter->fwname == NULL) + return 0; + } + + if (*mainfw == NULL) { + ret = request_firmware(mainfw, iter->fwname, dev); + if (ret && !user_helper) { + /* Clear the helper if it wasn't user-specified + * and the main firmware load failed, to ensure + * we don't have mismatched firmware pairs. + */ + release_firmware(*helper); + *helper = NULL; + } + } + + if (*helper && *mainfw) + return 0; + + next: + iter++; + } + + fail: + /* Failed */ + if (*helper) { + release_firmware(*helper); + *helper = NULL; + } + if (*mainfw) { + release_firmware(*mainfw); + *mainfw = NULL; + } + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(lbs_get_firmware); + static int __init lbs_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); -- cgit v1.2.3 From 82222e9ba75298e5bcd89803b6a11e2d7dfae70e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 Aug 2010 21:15:19 -0500 Subject: libertas: [cs] use common firmware request helper and new firmware locations linux-firmware puts libertas firmware in /libertas. Fix the driver to look there first, but fall back to the old firmware names if the new ones don't exist. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_cs.c | 130 +++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 08e4e3908003..a6fd70404c3d 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -49,7 +49,6 @@ MODULE_AUTHOR("Holger Schurig "); MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("libertas_cs_helper.fw"); @@ -62,9 +61,34 @@ struct if_cs_card { struct lbs_private *priv; void __iomem *iobase; bool align_regs; + u32 model; }; +enum { + MODEL_UNKNOWN = 0x00, + MODEL_8305 = 0x01, + MODEL_8381 = 0x02, + MODEL_8385 = 0x03 +}; + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8305, "libertas/cf8305.bin", NULL }, + { MODEL_8305, "libertas_cs_helper.fw", NULL }, + { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" }, + { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" }, + { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" }, + { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" }, + { 0, NULL, NULL } +}; +MODULE_FIRMWARE("libertas/cf8305.bin"); +MODULE_FIRMWARE("libertas/cf8381_helper.bin"); +MODULE_FIRMWARE("libertas/cf8381.bin"); +MODULE_FIRMWARE("libertas/cf8385_helper.bin"); +MODULE_FIRMWARE("libertas/cf8385.bin"); +MODULE_FIRMWARE("libertas_cs_helper.fw"); +MODULE_FIRMWARE("libertas_cs.fw"); + /********************************************************************/ /* Hardware access */ @@ -290,22 +314,19 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r #define CF8385_MANFID 0x02df #define CF8385_CARDID 0x8103 -static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev) -{ - return (p_dev->manf_id == CF8305_MANFID && - p_dev->card_id == CF8305_CARDID); -} - -static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev) -{ - return (p_dev->manf_id == CF8381_MANFID && - p_dev->card_id == CF8381_CARDID); -} - -static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev) +/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when + * that gets fixed. Currently there's no way to access it from the probe hook. + */ +static inline u32 get_model(u16 manf_id, u16 card_id) { - return (p_dev->manf_id == CF8385_MANFID && - p_dev->card_id == CF8385_CARDID); + /* NOTE: keep in sync with if_cs_ids */ + if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID) + return MODEL_8305; + else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID) + return MODEL_8381; + else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID) + return MODEL_8385; + return MODEL_UNKNOWN; } /********************************************************************/ @@ -559,12 +580,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) * * Return 0 on success */ -static int if_cs_prog_helper(struct if_cs_card *card) +static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) { int ret = 0; int sent = 0; u8 scratch; - const struct firmware *fw; lbs_deb_enter(LBS_DEB_CS); @@ -590,14 +610,6 @@ static int if_cs_prog_helper(struct if_cs_card *card) goto done; } - /* TODO: make firmware file configurable */ - ret = request_firmware(&fw, "libertas_cs_helper.fw", - &card->p_dev->dev); - if (ret) { - lbs_pr_err("can't load helper firmware\n"); - ret = -ENODEV; - goto done; - } lbs_deb_cs("helper size %td\n", fw->size); /* "Set the 5 bytes of the helper image to 0" */ @@ -636,7 +648,7 @@ static int if_cs_prog_helper(struct if_cs_card *card) if (ret < 0) { lbs_pr_err("can't download helper at 0x%x, ret %d\n", sent, ret); - goto err_release; + goto done; } if (count == 0) @@ -645,17 +657,14 @@ static int if_cs_prog_helper(struct if_cs_card *card) sent += count; } -err_release: - release_firmware(fw); done: lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; } -static int if_cs_prog_real(struct if_cs_card *card) +static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw) { - const struct firmware *fw; int ret = 0; int retry = 0; int len = 0; @@ -663,21 +672,13 @@ static int if_cs_prog_real(struct if_cs_card *card) lbs_deb_enter(LBS_DEB_CS); - /* TODO: make firmware file configurable */ - ret = request_firmware(&fw, "libertas_cs.fw", - &card->p_dev->dev); - if (ret) { - lbs_pr_err("can't load firmware\n"); - ret = -ENODEV; - goto done; - } lbs_deb_cs("fw size %td\n", fw->size); ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, IF_CS_SQ_HELPER_OK); if (ret < 0) { lbs_pr_err("helper firmware doesn't answer\n"); - goto err_release; + goto done; } for (sent = 0; sent < fw->size; sent += len) { @@ -692,7 +693,7 @@ static int if_cs_prog_real(struct if_cs_card *card) if (retry > 20) { lbs_pr_err("could not download firmware\n"); ret = -ENODEV; - goto err_release; + goto done; } if (retry) { sent -= len; @@ -711,7 +712,7 @@ static int if_cs_prog_real(struct if_cs_card *card) IF_CS_BIT_COMMAND); if (ret < 0) { lbs_pr_err("can't download firmware at 0x%x\n", sent); - goto err_release; + goto done; } } @@ -719,9 +720,6 @@ static int if_cs_prog_real(struct if_cs_card *card) if (ret < 0) lbs_pr_err("firmware download failed\n"); -err_release: - release_firmware(fw); - done: lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; @@ -825,6 +823,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) unsigned int prod_id; struct lbs_private *priv; struct if_cs_card *card; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_CS); @@ -844,7 +844,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out1; } - /* * Allocate an interrupt line. Note that this does not assign * a handler to the interrupt, unless the 'Handler' member of @@ -883,34 +882,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev) */ card->align_regs = 0; + card->model = get_model(p_dev->manf_id, p_dev->card_id); + if (card->model == MODEL_UNKNOWN) { + lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n", + p_dev->manf_id, p_dev->card_id); + goto out2; + } + /* Check if we have a current silicon */ prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); - if (if_cs_hw_is_cf8305(p_dev)) { + if (card->model == MODEL_8305) { card->align_regs = 1; if (prod_id < IF_CS_CF8305_B1_REV) { - lbs_pr_err("old chips like 8305 rev B3 " - "aren't supported\n"); + lbs_pr_err("8305 rev B0 and older are not supported\n"); ret = -ENODEV; goto out2; } } - if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { - lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); + if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) { + lbs_pr_err("8381 rev B2 and older are not supported\n"); ret = -ENODEV; goto out2; } - if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { - lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); + if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) { + lbs_pr_err("8385 rev B0 and older are not supported\n"); ret = -ENODEV; goto out2; } + ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, + &fw_table[0], &helper, &mainfw); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); + goto out2; + } + /* Load the firmware early, before calling into libertas.ko */ - ret = if_cs_prog_helper(card); - if (ret == 0 && !if_cs_hw_is_cf8305(p_dev)) - ret = if_cs_prog_real(card); + ret = if_cs_prog_helper(card, helper); + if (ret == 0 && (card->model != MODEL_8305)) + ret = if_cs_prog_real(card, mainfw); if (ret) goto out2; @@ -959,6 +971,11 @@ out2: out1: pcmcia_disable_device(p_dev); out: + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; } @@ -995,6 +1012,7 @@ static struct pcmcia_device_id if_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), + /* NOTE: keep in sync with get_model() */ PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); -- cgit v1.2.3 From 3d32a58b87cd251b50842f93b87d5458061c0cfc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 Aug 2010 21:15:52 -0500 Subject: libertas: [sdio] use common firmware request helper and new firmware locations linux-firmware puts libertas firmware in /libertas. Fix the driver to look there first, but fall back to the old firmware names if the new ones don't exist. Add preference for newer firmware versions too. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_sdio.c | 143 ++++++++++++++------------------ drivers/net/wireless/libertas/if_sdio.h | 4 - 2 files changed, 60 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 6e71346a7550..024e5ca7b7f3 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -76,36 +76,32 @@ static const struct sdio_device_id if_sdio_ids[] = { MODULE_DEVICE_TABLE(sdio, if_sdio_ids); -struct if_sdio_model { - int model; - const char *helper; - const char *firmware; -}; - -static struct if_sdio_model if_sdio_models[] = { - { - /* 8385 */ - .model = IF_SDIO_MODEL_8385, - .helper = "sd8385_helper.bin", - .firmware = "sd8385.bin", - }, - { - /* 8686 */ - .model = IF_SDIO_MODEL_8686, - .helper = "sd8686_helper.bin", - .firmware = "sd8686.bin", - }, - { - /* 8688 */ - .model = IF_SDIO_MODEL_8688, - .helper = "sd8688_helper.bin", - .firmware = "sd8688.bin", - }, +#define MODEL_8385 0x04 +#define MODEL_8686 0x0b +#define MODEL_8688 0x10 + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" }, + { MODEL_8385, "sd8385_helper.bin", "sd8385.bin" }, + { MODEL_8686, "libertas/sd8686_v9_helper.bin", "libertas/sd8686_v9.bin" }, + { MODEL_8686, "libertas/sd8686_v8_helper.bin", "libertas/sd8686_v8.bin" }, + { MODEL_8686, "sd8686_helper.bin", "sd8686.bin" }, + { MODEL_8688, "libertas/sd8688_helper.bin", "libertas/sd8688.bin" }, + { MODEL_8688, "sd8688_helper.bin", "sd8688.bin" }, + { 0, NULL, NULL } }; +MODULE_FIRMWARE("libertas/sd8385_helper.bin"); +MODULE_FIRMWARE("libertas/sd8385.bin"); MODULE_FIRMWARE("sd8385_helper.bin"); MODULE_FIRMWARE("sd8385.bin"); +MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin"); +MODULE_FIRMWARE("libertas/sd8686_v9.bin"); +MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin"); +MODULE_FIRMWARE("libertas/sd8686_v8.bin"); MODULE_FIRMWARE("sd8686_helper.bin"); MODULE_FIRMWARE("sd8686.bin"); +MODULE_FIRMWARE("libertas/sd8688_helper.bin"); +MODULE_FIRMWARE("libertas/sd8688.bin"); MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688.bin"); @@ -185,11 +181,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err) u16 rx_len; switch (card->model) { - case IF_SDIO_MODEL_8385: - case IF_SDIO_MODEL_8686: + case MODEL_8385: + case MODEL_8686: rx_len = if_sdio_read_scratch(card, &ret); break; - case IF_SDIO_MODEL_8688: + case MODEL_8688: default: /* for newer chipsets */ rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret); if (!ret) @@ -286,7 +282,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card, lbs_deb_enter(LBS_DEB_SDIO); - if (card->model == IF_SDIO_MODEL_8385) { + if (card->model == MODEL_8385) { event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); if (ret) goto out; @@ -464,10 +460,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) #define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) -static int if_sdio_prog_helper(struct if_sdio_card *card) +static int if_sdio_prog_helper(struct if_sdio_card *card, + const struct firmware *fw) { int ret; - const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; @@ -476,16 +472,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) lbs_deb_enter(LBS_DEB_SDIO); - ret = request_firmware(&fw, card->helper, &card->func->dev); - if (ret) { - lbs_pr_err("can't load helper firmware\n"); - goto out; - } - chunk_buffer = kzalloc(64, GFP_KERNEL); if (!chunk_buffer) { ret = -ENOMEM; - goto release_fw; + goto out; } sdio_claim_host(card->func); @@ -560,22 +550,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) release: sdio_release_host(card->func); kfree(chunk_buffer); -release_fw: - release_firmware(fw); out: if (ret) lbs_pr_err("failed to load helper firmware\n"); lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - return ret; } -static int if_sdio_prog_real(struct if_sdio_card *card) +static int if_sdio_prog_real(struct if_sdio_card *card, + const struct firmware *fw) { int ret; - const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; @@ -584,16 +571,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card) lbs_deb_enter(LBS_DEB_SDIO); - ret = request_firmware(&fw, card->firmware, &card->func->dev); - if (ret) { - lbs_pr_err("can't load firmware\n"); - goto out; - } - chunk_buffer = kzalloc(512, GFP_KERNEL); if (!chunk_buffer) { ret = -ENOMEM; - goto release_fw; + goto out; } sdio_claim_host(card->func); @@ -683,15 +664,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card) release: sdio_release_host(card->func); kfree(chunk_buffer); -release_fw: - release_firmware(fw); out: if (ret) lbs_pr_err("failed to load firmware\n"); lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - return ret; } @@ -699,6 +677,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) { int ret; u16 scratch; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_SDIO); @@ -716,11 +696,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) goto success; } - ret = if_sdio_prog_helper(card); + ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, + card->model, &fw_table[0], &helper, &mainfw); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); + goto out; + } + + ret = if_sdio_prog_helper(card, helper); if (ret) goto out; - ret = if_sdio_prog_real(card); + ret = if_sdio_prog_real(card, mainfw); if (ret) goto out; @@ -731,8 +718,12 @@ success: ret = 0; out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); return ret; } @@ -936,7 +927,7 @@ static int if_sdio_probe(struct sdio_func *func, "ID: %x", &model) == 1) break; if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { - model = IF_SDIO_MODEL_8385; + model = MODEL_8385; break; } } @@ -954,13 +945,13 @@ static int if_sdio_probe(struct sdio_func *func, card->model = model; switch (card->model) { - case IF_SDIO_MODEL_8385: + case MODEL_8385: card->scratch_reg = IF_SDIO_SCRATCH_OLD; break; - case IF_SDIO_MODEL_8686: + case MODEL_8686: card->scratch_reg = IF_SDIO_SCRATCH; break; - case IF_SDIO_MODEL_8688: + case MODEL_8688: default: /* for newer chipsets */ card->scratch_reg = IF_SDIO_FW_STATUS; break; @@ -970,31 +961,17 @@ static int if_sdio_probe(struct sdio_func *func, card->workqueue = create_workqueue("libertas_sdio"); INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); - for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { - if (card->model == if_sdio_models[i].model) + /* Check if we support this card */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (card->model == fw_table[i].model) break; } - - if (i == ARRAY_SIZE(if_sdio_models)) { + if (i == ARRAY_SIZE(fw_table)) { lbs_pr_err("unknown card model 0x%x\n", card->model); ret = -ENODEV; goto free; } - card->helper = if_sdio_models[i].helper; - card->firmware = if_sdio_models[i].firmware; - - if (lbs_helper_name) { - lbs_deb_sdio("overriding helper firmware: %s\n", - lbs_helper_name); - card->helper = lbs_helper_name; - } - - if (lbs_fw_name) { - lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); - card->firmware = lbs_fw_name; - } - sdio_claim_host(func); ret = sdio_enable_func(func); @@ -1008,7 +985,7 @@ static int if_sdio_probe(struct sdio_func *func, /* For 1-bit transfers to the 8686 model, we need to enable the * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 * bit to allow access to non-vendor registers. */ - if ((card->model == IF_SDIO_MODEL_8686) && + if ((card->model == MODEL_8686) && (host->caps & MMC_CAP_SDIO_IRQ) && (host->ios.bus_width == MMC_BUS_WIDTH_1)) { u8 reg; @@ -1071,8 +1048,8 @@ static int if_sdio_probe(struct sdio_func *func, * Get rx_unit if the chip is SD8688 or newer. * SD8385 & SD8686 do not have rx_unit. */ - if ((card->model != IF_SDIO_MODEL_8385) - && (card->model != IF_SDIO_MODEL_8686)) + if ((card->model != MODEL_8385) + && (card->model != MODEL_8686)) card->rx_unit = if_sdio_read_rx_unit(card); else card->rx_unit = 0; @@ -1088,7 +1065,7 @@ static int if_sdio_probe(struct sdio_func *func, /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ - if (card->model == IF_SDIO_MODEL_8688) { + if (card->model == MODEL_8688) { struct cmd_header cmd; memset(&cmd, 0, sizeof(cmd)); @@ -1141,7 +1118,7 @@ static void if_sdio_remove(struct sdio_func *func) card = sdio_get_drvdata(func); - if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) { + if (user_rmmod && (card->model == MODEL_8688)) { /* * FUNC_SHUTDOWN is required for SD8688 WLAN/BT * multiple functions diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h index 12179c1dc9c9..62fda3592f67 100644 --- a/drivers/net/wireless/libertas/if_sdio.h +++ b/drivers/net/wireless/libertas/if_sdio.h @@ -12,10 +12,6 @@ #ifndef _LBS_IF_SDIO_H #define _LBS_IF_SDIO_H -#define IF_SDIO_MODEL_8385 0x04 -#define IF_SDIO_MODEL_8686 0x0b -#define IF_SDIO_MODEL_8688 0x10 - #define IF_SDIO_IOPORT 0x00 #define IF_SDIO_H_INT_MASK 0x04 -- cgit v1.2.3 From 915a824e30c503157c38115eb6a85f60bb653738 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 7 Aug 2010 21:16:30 -0500 Subject: libertas: [spi] use common firmware request helper and new firmware locations linux-firmware puts libertas firmware in /libertas. Fix the driver to look there first, but fall back to the old firmware names if the new ones don't exist. Add preference for newer firmware versions too. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 144 ++++++++++++++++----------------- drivers/net/wireless/libertas/if_spi.h | 5 -- 2 files changed, 69 insertions(+), 80 deletions(-) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 3965c6cf504a..79bcb4e5d2ca 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -39,9 +39,6 @@ struct if_spi_card { struct lbs_private *priv; struct libertas_spi_platform_data *pdata; - char helper_fw_name[IF_SPI_FW_NAME_MAX]; - char main_fw_name[IF_SPI_FW_NAME_MAX]; - /* The card ID and card revision, as reported by the hardware. */ u16 card_id; u8 card_rev; @@ -70,10 +67,28 @@ static void free_if_spi_card(struct if_spi_card *card) kfree(card); } -static struct chip_ident chip_id_to_device_name[] = { - { .chip_id = 0x04, .name = 8385 }, - { .chip_id = 0x0b, .name = 8686 }, +#define MODEL_8385 0x04 +#define MODEL_8686 0x0b +#define MODEL_8688 0x10 + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" }, + { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" }, + { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" }, + { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" }, + { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" }, + { 0, NULL, NULL } }; +MODULE_FIRMWARE("libertas/gspi8385_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); +MODULE_FIRMWARE("libertas/gspi8385.bin"); +MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8686_v9.bin"); +MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); +MODULE_FIRMWARE("libertas/gspi8686.bin"); +MODULE_FIRMWARE("libertas/gspi8688_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8688.bin"); + /* * SPI Interface Unit Routines @@ -399,26 +414,20 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) * Firmware Loading */ -static int if_spi_prog_helper_firmware(struct if_spi_card *card) +static int if_spi_prog_helper_firmware(struct if_spi_card *card, + const struct firmware *firmware) { int err = 0; - const struct firmware *firmware = NULL; int bytes_remaining; const u8 *fw; u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; - struct spi_device *spi = card->spi; lbs_deb_enter(LBS_DEB_SPI); err = spu_set_interrupt_mode(card, 1, 0); if (err) goto out; - /* Get helper firmware image */ - err = request_firmware(&firmware, card->helper_fw_name, &spi->dev); - if (err) { - lbs_pr_err("request_firmware failed with err = %d\n", err); - goto out; - } + bytes_remaining = firmware->size; fw = firmware->data; @@ -429,13 +438,13 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, HELPER_FW_LOAD_CHUNK_SZ); if (err) - goto release_firmware; + goto out; err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, IF_SPI_HIST_CMD_DOWNLOAD_RDY, IF_SPI_HIST_CMD_DOWNLOAD_RDY); if (err) - goto release_firmware; + goto out; /* Feed the data into the command read/write port reg * in chunks of 64 bytes */ @@ -446,16 +455,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, temp, HELPER_FW_LOAD_CHUNK_SZ); if (err) - goto release_firmware; + goto out; /* Interrupt the boot code */ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_CMD_DOWNLOAD_OVER); if (err) - goto release_firmware; + goto out; bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; fw += HELPER_FW_LOAD_CHUNK_SZ; } @@ -465,18 +474,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) * bootloader. This completes the helper download. */ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_CMD_DOWNLOAD_OVER); - goto release_firmware; + goto out; lbs_deb_spi("waiting for helper to boot...\n"); -release_firmware: - release_firmware(firmware); out: if (err) lbs_pr_err("failed to load helper firmware (err=%d)\n", err); @@ -523,13 +530,12 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, return len; } -static int if_spi_prog_main_firmware(struct if_spi_card *card) +static int if_spi_prog_main_firmware(struct if_spi_card *card, + const struct firmware *firmware) { int len, prev_len; int bytes, crc_err = 0, err = 0; - const struct firmware *firmware = NULL; const u8 *fw; - struct spi_device *spi = card->spi; u16 num_crc_errs; lbs_deb_enter(LBS_DEB_SPI); @@ -538,19 +544,11 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) if (err) goto out; - /* Get firmware image */ - err = request_firmware(&firmware, card->main_fw_name, &spi->dev); - if (err) { - lbs_pr_err("%s: can't get firmware '%s' from kernel. " - "err = %d\n", __func__, card->main_fw_name, err); - goto out; - } - err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); if (err) { lbs_pr_err("%s: timed out waiting for initial " "scratch reg = 0\n", __func__); - goto release_firmware; + goto out; } num_crc_errs = 0; @@ -560,7 +558,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) { if (len < 0) { err = len; - goto release_firmware; + goto out; } if (bytes < 0) { /* If there are no more bytes left, we would normally @@ -575,7 +573,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) lbs_pr_err("Too many CRC errors encountered " "in firmware load.\n"); err = -EIO; - goto release_firmware; + goto out; } } else { /* Previous transfer succeeded. Advance counters. */ @@ -590,15 +588,15 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, card->cmd_buffer, len); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , IF_SPI_CIC_CMD_DOWNLOAD_OVER); if (err) - goto release_firmware; + goto out; prev_len = len; } if (bytes > prev_len) { @@ -611,12 +609,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) SUCCESSFUL_FW_DOWNLOAD_MAGIC); if (err) { lbs_pr_err("failed to confirm the firmware download\n"); - goto release_firmware; + goto out; } -release_firmware: - release_firmware(firmware); - out: if (err) lbs_pr_err("failed to load firmware (err=%d)\n", err); @@ -888,37 +883,16 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) * SPI callbacks */ -static int if_spi_calculate_fw_names(u16 card_id, - char *helper_fw, char *main_fw) -{ - int i; - for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) { - if (card_id == chip_id_to_device_name[i].chip_id) - break; - } - if (i == ARRAY_SIZE(chip_id_to_device_name)) { - lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id); - return -EAFNOSUPPORT; - } - snprintf(helper_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d_hlp.bin", - chip_id_to_device_name[i].name); - snprintf(main_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d.bin", - chip_id_to_device_name[i].name); - return 0; -} -MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); -MODULE_FIRMWARE("libertas/gspi8385.bin"); -MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); -MODULE_FIRMWARE("libertas/gspi8686.bin"); - static int __devinit if_spi_probe(struct spi_device *spi) { struct if_spi_card *card; struct lbs_private *priv = NULL; struct libertas_spi_platform_data *pdata = spi->dev.platform_data; - int err = 0; + int err = 0, i; u32 scratch; struct sched_param param = { .sched_priority = 1 }; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_SPI); @@ -963,10 +937,25 @@ static int __devinit if_spi_probe(struct spi_device *spi) lbs_deb_spi("Firmware is already loaded for " "Marvell WLAN 802.11 adapter\n"); else { - err = if_spi_calculate_fw_names(card->card_id, - card->helper_fw_name, card->main_fw_name); - if (err) + /* Check if we support this card */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (card->card_id == fw_table[i].model) + break; + } + if (i == ARRAY_SIZE(fw_table)) { + lbs_pr_err("Unsupported chip_id: 0x%02x\n", + card->card_id); + err = -ENODEV; goto free_card; + } + + err = lbs_get_firmware(&card->spi->dev, NULL, NULL, + card->card_id, &fw_table[0], &helper, + &mainfw); + if (err) { + lbs_pr_err("failed to find firmware (%d)\n", err); + goto free_card; + } lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " "(chip_id = 0x%04x, chip_rev = 0x%02x) " @@ -975,10 +964,10 @@ static int __devinit if_spi_probe(struct spi_device *spi) card->card_id, card->card_rev, spi->master->bus_num, spi->chip_select, spi->max_speed_hz); - err = if_spi_prog_helper_firmware(card); + err = if_spi_prog_helper_firmware(card, helper); if (err) goto free_card; - err = if_spi_prog_main_firmware(card); + err = if_spi_prog_main_firmware(card, mainfw); if (err) goto free_card; lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); @@ -1046,6 +1035,11 @@ remove_card: free_card: free_if_spi_card(card); out: + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); return err; } diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h index f87eec410848..8b1417d3b71b 100644 --- a/drivers/net/wireless/libertas/if_spi.h +++ b/drivers/net/wireless/libertas/if_spi.h @@ -25,11 +25,6 @@ #define IF_SPI_FW_NAME_MAX 30 -struct chip_ident { - u16 chip_id; - u16 name; -}; - #define MAX_MAIN_FW_LOAD_CRC_ERR 10 /* Chunk size when loading the helper firmware */ -- cgit v1.2.3 From 97359d1235eaf634fe706c9faa6e40181cc95fb8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Aug 2010 09:46:38 +0200 Subject: mac80211: use cipher suite selectors Currently, mac80211 translates the cfg80211 cipher suite selectors into ALG_* values. That isn't all too useful, and some drivers benefit from the distinction between WEP40 and WEP104 as well. Therefore, convert it all to use the cipher suite selectors. Signed-off-by: Johannes Berg Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.c | 7 ++-- drivers/net/wireless/ath/ar9170/main.c | 31 ++++++++------- drivers/net/wireless/ath/ath5k/base.c | 9 +++-- drivers/net/wireless/ath/ath5k/pcu.c | 19 ++++----- drivers/net/wireless/ath/ath9k/common.c | 36 ++++++++++-------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++- drivers/net/wireless/ath/ath9k/main.c | 5 ++- drivers/net/wireless/b43/main.c | 16 ++++---- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 16 ++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 24 ++++++------ drivers/net/wireless/iwlwifi/iwl3945-base.c | 43 ++++++++++++--------- drivers/net/wireless/p54/main.c | 9 +++-- drivers/net/wireless/p54/txrx.c | 17 +++++---- drivers/net/wireless/rt2x00/rt2500usb.c | 4 +- drivers/net/wireless/rt2x00/rt2x00crypto.c | 17 ++++----- drivers/net/wireless/wl12xx/wl1251_main.c | 13 ++++--- drivers/net/wireless/wl12xx/wl1251_tx.c | 4 +- drivers/net/wireless/wl12xx/wl1271_main.c | 13 ++++--- drivers/net/wireless/wl12xx/wl1271_tx.c | 4 +- include/net/mac80211.h | 18 +-------- net/mac80211/cfg.c | 44 ++++++--------------- net/mac80211/debugfs_key.c | 55 +++++++++++---------------- net/mac80211/driver-trace.h | 4 +- net/mac80211/key.c | 25 ++++++------ net/mac80211/key.h | 4 +- net/mac80211/rx.c | 18 +++++---- net/mac80211/tx.c | 22 ++++++----- net/mac80211/wep.c | 2 +- net/mac80211/wpa.c | 6 +-- 31 files changed, 236 insertions(+), 260 deletions(-) diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index d5140a87f073..a267bf55574c 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -2061,11 +2061,12 @@ static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, int i; - at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " + at76_dbg(DBG_MAC80211, "%s(): cmd %d key->cipher %d key->keyidx %d " "key->keylen %d", - __func__, cmd, key->alg, key->keyidx, key->keylen); + __func__, cmd, key->cipher, key->keyidx, key->keylen); - if (key->alg != ALG_WEP) + if ((key->cipher != WLAN_CIPHER_SUITE_WEP40) && + (key->cipher != WLAN_CIPHER_SUITE_WEP104)) return -EOPNOTSUPP; key->hw_key_idx = key->keyidx; diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c67b05f3bcbd..29d2253ad7e4 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1190,14 +1190,13 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (info->control.hw_key) { icv = info->control.hw_key->icv_len; - switch (info->control.hw_key->alg) { - case ALG_WEP: + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: keytype = AR9170_TX_MAC_ENCR_RC4; break; - case ALG_TKIP: - keytype = AR9170_TX_MAC_ENCR_RC4; - break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: keytype = AR9170_TX_MAC_ENCR_AES; break; default: @@ -1778,17 +1777,17 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if ((!ar->vif) || (ar->disable_offload)) return -EOPNOTSUPP; - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - ktype = AR9170_ENC_ALG_WEP64; - else - ktype = AR9170_ENC_ALG_WEP128; + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + ktype = AR9170_ENC_ALG_WEP64; + break; + case WLAN_CIPHER_SUITE_WEP104: + ktype = AR9170_ENC_ALG_WEP128; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: ktype = AR9170_ENC_ALG_TKIP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: ktype = AR9170_ENC_ALG_AESCCMP; break; default: @@ -1827,7 +1826,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (err) goto out; - if (key->alg == ALG_TKIP) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 1, key->key + 16, 16); if (err) @@ -1864,7 +1863,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (err) goto out; - if (key->alg == ALG_TKIP) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { err = ar9170_upload_key(ar, key->hw_key_idx, NULL, AR9170_ENC_ALG_NONE, 1, diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 373dcfec689c..a729b8774670 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3297,11 +3297,12 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (sc->opmode == NL80211_IFTYPE_AP) return -EOPNOTSUPP; - switch (key->alg) { - case ALG_WEP: - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (sc->ah->ah_aes_support) break; diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 86fdb6ddfaaa..af273358c7cb 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -695,21 +695,18 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) static int ath5k_keycache_type(const struct ieee80211_key_conf *key) { - switch (key->alg) { - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: return AR5K_KEYTABLE_TYPE_TKIP; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return AR5K_KEYTABLE_TYPE_CCM; - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - return AR5K_KEYTABLE_TYPE_40; - else if (key->keylen == WLAN_KEY_LEN_WEP104) - return AR5K_KEYTABLE_TYPE_104; - return -EINVAL; + case WLAN_CIPHER_SUITE_WEP40: + return AR5K_KEYTABLE_TYPE_40; + case WLAN_CIPHER_SUITE_WEP104: + return AR5K_KEYTABLE_TYPE_104; default: return -EINVAL; } - return -EINVAL; } /* @@ -728,7 +725,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, bool is_tkip; const u8 *key_ptr; - is_tkip = (key->alg == ALG_TKIP); + is_tkip = (key->cipher == WLAN_CIPHER_SUITE_TKIP); /* * key->keylen comes in from mac80211 in bytes. diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index c86f7d3593ab..3100c87a4fcd 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -46,12 +46,17 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); if (tx_info->control.hw_key) { - if (tx_info->control.hw_key->alg == ALG_WEP) + switch (tx_info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return ATH9K_KEY_TYPE_WEP; - else if (tx_info->control.hw_key->alg == ALG_TKIP) + case WLAN_CIPHER_SUITE_TKIP: return ATH9K_KEY_TYPE_TKIP; - else if (tx_info->control.hw_key->alg == ALG_CCMP) + case WLAN_CIPHER_SUITE_CCMP: return ATH9K_KEY_TYPE_AES; + default: + break; + } } return ATH9K_KEY_TYPE_CLEAR; @@ -212,11 +217,11 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) } static int ath_reserve_key_cache_slot(struct ath_common *common, - enum ieee80211_key_alg alg) + u32 cipher) { int i; - if (alg == ALG_TKIP) + if (cipher == WLAN_CIPHER_SUITE_TKIP) return ath_reserve_key_cache_slot_tkip(common); /* First, try to find slots that would not be available for TKIP. */ @@ -293,14 +298,15 @@ int ath9k_cmn_key_config(struct ath_common *common, memset(&hk, 0, sizeof(hk)); - switch (key->alg) { - case ALG_WEP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: hk.kv_type = ATH9K_CIPHER_WEP; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: hk.kv_type = ATH9K_CIPHER_TKIP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: hk.kv_type = ATH9K_CIPHER_AES_CCM; break; default: @@ -316,7 +322,7 @@ int ath9k_cmn_key_config(struct ath_common *common, memcpy(gmac, vif->addr, ETH_ALEN); gmac[0] |= 0x01; mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->alg); + idx = ath_reserve_key_cache_slot(common, key->cipher); break; case NL80211_IFTYPE_ADHOC: if (!sta) { @@ -326,7 +332,7 @@ int ath9k_cmn_key_config(struct ath_common *common, memcpy(gmac, sta->addr, ETH_ALEN); gmac[0] |= 0x01; mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->alg); + idx = ath_reserve_key_cache_slot(common, key->cipher); break; default: idx = key->keyidx; @@ -348,13 +354,13 @@ int ath9k_cmn_key_config(struct ath_common *common, return -EOPNOTSUPP; mac = sta->addr; - idx = ath_reserve_key_cache_slot(common, key->alg); + idx = ath_reserve_key_cache_slot(common, key->cipher); } if (idx < 0) return -ENOSPC; /* no free key cache entries */ - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, vif->type == NL80211_IFTYPE_AP); else @@ -364,7 +370,7 @@ int ath9k_cmn_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); - if (key->alg == ALG_TKIP) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); if (common->splitmic) { set_bit(idx + 32, common->keymap); @@ -389,7 +395,7 @@ void ath9k_cmn_key_delete(struct ath_common *common, return; clear_bit(key->hw_key_idx, common->keymap); - if (key->alg != ALG_TKIP) + if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; clear_bit(key->hw_key_idx + 64, common->keymap); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 7d09b4b17bbd..4e345be62435 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1585,9 +1585,10 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP) + if (priv->ah->sw_mgmt_crypto && + key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; ret = 0; } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a3b0ea90439d..1165f909ef04 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1782,9 +1782,10 @@ static int ath9k_set_key(struct ieee80211_hw *hw, key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP) + if (sc->sc_ah->sw_mgmt_crypto && + key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; ret = 0; } diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index a3e2f2bfe3a7..a1186525c70d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3759,17 +3759,17 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } err = -EINVAL; - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - algorithm = B43_SEC_ALGO_WEP40; - else - algorithm = B43_SEC_ALGO_WEP104; + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + algorithm = B43_SEC_ALGO_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + algorithm = B43_SEC_ALGO_WEP104; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: algorithm = B43_SEC_ALGO_TKIP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: algorithm = B43_SEC_ALGO_AES; break; default: diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 69155aa448fb..3fc982e87921 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -470,8 +470,8 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, { struct ieee80211_key_conf *keyconf = info->control.hw_key; - switch (keyconf->alg) { - case ALG_CCMP: + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: tx_cmd->sec_ctl = TX_CMD_SEC_CCM; memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); if (info->flags & IEEE80211_TX_CTL_AMPDU) @@ -479,20 +479,20 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; ieee80211_get_tkip_key(keyconf, skb_frag, IEEE80211_TKIP_P2_KEY, tx_cmd->key); IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP | (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); - if (keyconf->keylen == WEP_KEY_LEN_128) - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen); IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " @@ -500,7 +500,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, break; default: - IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg); + IWL_ERR(priv, "Unknown encode cipher %x\n", keyconf->cipher); break; } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 43e078b87378..21a52ae05c0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3389,7 +3389,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * in 1X mode. * In legacy wep mode, we use another host command to the uCode. */ - if (key->alg == ALG_WEP && !sta && vif->type != NL80211_IFTYPE_AP) { + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) && + !sta && vif->type != NL80211_IFTYPE_AP) { if (cmd == SET_KEY) is_default_wep_key = !priv->key_mapping_key; else diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 599635547021..149619fb1c07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -420,7 +420,7 @@ struct iwl_tid_data { }; struct iwl_hw_key { - enum ieee80211_key_alg alg; + u32 cipher; int keylen; u8 keyidx; u8 key[32]; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7e0829be5e78..d5e8db37b86e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -818,7 +818,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->hw_key_idx = HW_KEY_DEFAULT; - priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; + priv->stations[IWL_AP_ID].keyinfo.cipher = keyconf->cipher; priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, @@ -856,7 +856,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; @@ -906,7 +906,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, @@ -955,7 +955,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; priv->stations[sta_id].keyinfo.keylen = 16; if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) @@ -1090,24 +1090,26 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, priv->key_mapping_key++; keyconf->hw_key_idx = HW_KEY_DYNAMIC; - switch (keyconf->alg) { - case ALG_CCMP: + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); break; default: IWL_ERR(priv, - "Unknown alg: %s alg = %d\n", __func__, keyconf->alg); + "Unknown alg: %s cipher = %x\n", __func__, + keyconf->cipher); ret = -EINVAL; } - IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", - keyconf->alg, keyconf->keylen, keyconf->keyidx, + IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, sta_id, ret); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index b14eaf91c7c2..faa2e0037e10 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -152,7 +152,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags &= ~STA_KEY_FLG_INVALID; spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, keyconf->keylen); @@ -223,23 +223,25 @@ static int iwl3945_set_dynamic_key(struct iwl_priv *priv, keyconf->hw_key_idx = HW_KEY_DYNAMIC; - switch (keyconf->alg) { - case ALG_CCMP: + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); break; default: - IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg); + IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, + keyconf->cipher); ret = -EINVAL; } - IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", - keyconf->alg, keyconf->keylen, keyconf->keyidx, + IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, sta_id, ret); return ret; @@ -255,10 +257,11 @@ static int iwl3945_remove_static_key(struct iwl_priv *priv) static int iwl3945_set_static_key(struct iwl_priv *priv, struct ieee80211_key_conf *key) { - if (key->alg == ALG_WEP) + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) return -EOPNOTSUPP; - IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg); + IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); return -EINVAL; } @@ -370,23 +373,25 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; - switch (keyinfo->alg) { - case ALG_CCMP: + tx_cmd->sec_ctl = 0; + + switch (keyinfo->cipher) { + case WLAN_CIPHER_SUITE_CCMP: tx_cmd->sec_ctl = TX_CMD_SEC_CCM; memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: break; - case ALG_WEP: - tx_cmd->sec_ctl = TX_CMD_SEC_WEP | + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: + tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; - if (keyinfo->keylen == 13) - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " @@ -394,7 +399,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, break; default: - IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg); + IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); break; } } diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 47db439b63bf..622d27b6d8f2 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -429,8 +429,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, mutex_lock(&priv->conf_mutex); if (cmd == SET_KEY) { - switch (key->alg) { - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL | BR_DESC_PRIV_CAP_TKIP))) { ret = -EOPNOTSUPP; @@ -439,7 +439,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_TKIPMICHAEL; break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) { ret = -EOPNOTSUPP; goto out_unlock; @@ -447,7 +448,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_WEP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) { ret = -EOPNOTSUPP; goto out_unlock; diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 427b46f558ed..e53f8cec7798 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -683,14 +683,15 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, } } -static u8 p54_convert_algo(enum ieee80211_key_alg alg) +static u8 p54_convert_algo(u32 cipher) { - switch (alg) { - case ALG_WEP: + switch (cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return P54_CRYPTO_WEP; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: return P54_CRYPTO_TKIPMICHAEL; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return P54_CRYPTO_AESCCMP; default: return 0; @@ -731,7 +732,7 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) if (info->control.hw_key) { crypt_offset = ieee80211_get_hdrlen_from_skb(skb); - if (info->control.hw_key->alg == ALG_TKIP) { + if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { u8 *iv = (u8 *)(skb->data + crypt_offset); /* * The firmware excepts that the IV has to have @@ -827,10 +828,10 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) hdr->tries = ridx; txhdr->rts_rate_idx = 0; if (info->control.hw_key) { - txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); + txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher); txhdr->key_len = min((u8)16, info->control.hw_key->keylen); memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); - if (info->control.hw_key->alg == ALG_TKIP) { + if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { /* reserve space for the MIC key */ len += 8; memcpy(skb_put(skb, 8), &(info->control.hw_key->key diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f48263..97cf72f8bc12 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, * it is known that not work at least on some hardware. * SW crypto will be used in that case. */ - if (key->alg == ALG_WEP && key->keyidx != 0) + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) && + key->keyidx != 0) return -EOPNOTSUPP; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 583dacd8d241..5e9074bf2b8e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -31,15 +31,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) { - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - return CIPHER_WEP64; - else - return CIPHER_WEP128; - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + return CIPHER_WEP64; + case WLAN_CIPHER_SUITE_WEP104: + return CIPHER_WEP128; + case WLAN_CIPHER_SUITE_TKIP: return CIPHER_TKIP; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return CIPHER_AES; default: return CIPHER_NONE; @@ -95,7 +94,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, overhead += key->iv_len; if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) overhead += 8; } diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 861a5f33761e..6d31c855fcfe 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -725,8 +725,9 @@ static int wl1251_set_key_type(struct wl1251 *wl, struct ieee80211_key_conf *mac80211_key, const u8 *addr) { - switch (mac80211_key->alg) { - case ALG_WEP: + switch (mac80211_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_WEP_DEFAULT; else @@ -734,7 +735,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->hw_key_idx = mac80211_key->keyidx; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_TKIP_MIC_GROUP; else @@ -742,7 +743,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->hw_key_idx = mac80211_key->keyidx; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_AES_GROUP; else @@ -750,7 +751,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; break; default: - wl1251_error("Unknown key algo 0x%x", mac80211_key->alg); + wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher); return -EOPNOTSUPP; } @@ -783,7 +784,7 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key->alg, key->keyidx, key->keylen, key->flags); + key->cipher, key->keyidx, key->keylen, key->flags); wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); if (is_zero_ether_addr(addr)) { diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c index a38ec199187a..6634b3e27cfc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/drivers/net/wireless/wl12xx/wl1251_tx.c @@ -189,7 +189,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, tx_hdr = (struct tx_double_buffer_desc *) skb->data; if (control->control.hw_key && - control->control.hw_key->alg == ALG_TKIP) { + control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen; __le16 fc; u16 length; @@ -399,7 +399,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, */ frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc)); if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) { + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen); skb_pull(skb, WL1251_TKIP_IV_SPACE); diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 9d68f0012f05..30194c0f36a9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1439,7 +1439,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key_conf->alg, key_conf->keyidx, + key_conf->cipher, key_conf->keyidx, key_conf->keylen, key_conf->flags); wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); @@ -1455,20 +1455,21 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ret < 0) goto out_unlock; - switch (key_conf->alg) { - case ALG_WEP: + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: key_type = KEY_WEP; key_conf->hw_key_idx = key_conf->keyidx; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: key_type = KEY_TKIP; key_conf->hw_key_idx = key_conf->keyidx; tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: key_type = KEY_AES; key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -1476,7 +1477,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); break; default: - wl1271_error("Unknown key algo 0x%x", key_conf->alg); + wl1271_error("Unknown key algo 0x%x", key_conf->cipher); ret = -EOPNOTSUPP; goto out_sleep; diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index c592cc2e9fe8..dc0b46c93c4b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -193,7 +193,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) extra = WL1271_TKIP_IV_SPACE; if (info->control.hw_key) { @@ -347,7 +347,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* remove TKIP header space if present */ if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) { + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); skb_pull(skb, WL1271_TKIP_IV_SPACE); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 871ed1de736a..914c747ac3a0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -788,20 +788,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) return false; } -/** - * enum ieee80211_key_alg - key algorithm - * @ALG_WEP: WEP40 or WEP104 - * @ALG_TKIP: TKIP - * @ALG_CCMP: CCMP (AES) - * @ALG_AES_CMAC: AES-128-CMAC - */ -enum ieee80211_key_alg { - ALG_WEP, - ALG_TKIP, - ALG_CCMP, - ALG_AES_CMAC, -}; - /** * enum ieee80211_key_flags - key flags * @@ -839,7 +825,7 @@ enum ieee80211_key_flags { * @hw_key_idx: To be set by the driver, this is the key index the driver * wants to be given when a frame is transmitted and needs to be * encrypted in hardware. - * @alg: The key algorithm. + * @cipher: The key's cipher suite selector. * @flags: key flags, see &enum ieee80211_key_flags. * @keyidx: the key index (0-3) * @keylen: key material length @@ -852,7 +838,7 @@ enum ieee80211_key_flags { * @iv_len: The IV length for this key type */ struct ieee80211_key_conf { - enum ieee80211_key_alg alg; + u32 cipher; u8 icv_len; u8 iv_len; u8 hw_key_idx; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 19c6146010b7..9a35d9e7efd7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -116,7 +116,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata; struct sta_info *sta = NULL; - enum ieee80211_key_alg alg; struct ieee80211_key *key; int err; @@ -125,31 +124,20 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, sdata = IEEE80211_DEV_TO_SUB_IF(dev); + /* reject WEP and TKIP keys if WEP failed to initialize */ switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - alg = ALG_WEP; - break; case WLAN_CIPHER_SUITE_TKIP: - alg = ALG_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - alg = ALG_CCMP; - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - alg = ALG_AES_CMAC; + case WLAN_CIPHER_SUITE_WEP104: + if (IS_ERR(sdata->local->wep_tx_tfm)) + return -EINVAL; break; default: - return -EINVAL; + break; } - /* reject WEP and TKIP keys if WEP failed to initialize */ - if ((alg == ALG_WEP || alg == ALG_TKIP) && - IS_ERR(sdata->local->wep_tx_tfm)) - return -EINVAL; - - key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, - params->seq_len, params->seq); + key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, + params->key, params->seq_len, params->seq); if (IS_ERR(key)) return PTR_ERR(key); @@ -247,10 +235,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, memset(¶ms, 0, sizeof(params)); - switch (key->conf.alg) { - case ALG_TKIP: - params.cipher = WLAN_CIPHER_SUITE_TKIP; + params.cipher = key->conf.cipher; + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_TKIP: iv32 = key->u.tkip.tx.iv32; iv16 = key->u.tkip.tx.iv16; @@ -268,8 +256,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.seq = seq; params.seq_len = 6; break; - case ALG_CCMP: - params.cipher = WLAN_CIPHER_SUITE_CCMP; + case WLAN_CIPHER_SUITE_CCMP: seq[0] = key->u.ccmp.tx_pn[5]; seq[1] = key->u.ccmp.tx_pn[4]; seq[2] = key->u.ccmp.tx_pn[3]; @@ -279,14 +266,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.seq = seq; params.seq_len = 6; break; - case ALG_WEP: - if (key->conf.keylen == 5) - params.cipher = WLAN_CIPHER_SUITE_WEP40; - else - params.cipher = WLAN_CIPHER_SUITE_WEP104; - break; - case ALG_AES_CMAC: - params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + case WLAN_CIPHER_SUITE_AES_CMAC: seq[0] = key->u.aes_cmac.tx_pn[5]; seq[1] = key->u.aes_cmac.tx_pn[4]; seq[2] = key->u.aes_cmac.tx_pn[3]; diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index fa5e76e658ef..1647f8dc5cda 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -64,26 +64,13 @@ static ssize_t key_algorithm_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - char *alg; + char buf[15]; struct ieee80211_key *key = file->private_data; + u32 c = key->conf.cipher; - switch (key->conf.alg) { - case ALG_WEP: - alg = "WEP\n"; - break; - case ALG_TKIP: - alg = "TKIP\n"; - break; - case ALG_CCMP: - alg = "CCMP\n"; - break; - case ALG_AES_CMAC: - alg = "AES-128-CMAC\n"; - break; - default: - return 0; - } - return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg)); + sprintf(buf, "%.2x-%.2x-%.2x:%d\n", + c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff); + return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); } KEY_OPS(algorithm); @@ -95,21 +82,22 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, int len; struct ieee80211_key *key = file->private_data; - switch (key->conf.alg) { - case ALG_WEP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: len = scnprintf(buf, sizeof(buf), "\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: len = scnprintf(buf, sizeof(buf), "%08x %04x\n", key->u.tkip.tx.iv32, key->u.tkip.tx.iv16); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: tpn = key->u.ccmp.tx_pn; len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: tpn = key->u.aes_cmac.tx_pn; len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], @@ -130,11 +118,12 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, int i, len; const u8 *rpn; - switch (key->conf.alg) { - case ALG_WEP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: len = scnprintf(buf, sizeof(buf), "\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: for (i = 0; i < NUM_RX_DATA_QUEUES; i++) p += scnprintf(p, sizeof(buf)+buf-p, "%08x %04x\n", @@ -142,7 +131,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, key->u.tkip.rx[i].iv16); len = p - buf; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { rpn = key->u.ccmp.rx_pn[i]; p += scnprintf(p, sizeof(buf)+buf-p, @@ -152,7 +141,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, } len = p - buf; break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: rpn = key->u.aes_cmac.rx_pn; p += scnprintf(p, sizeof(buf)+buf-p, "%02x%02x%02x%02x%02x%02x\n", @@ -174,11 +163,11 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf, char buf[20]; int len; - switch (key->conf.alg) { - case ALG_CCMP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_CCMP: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.replays); break; @@ -196,8 +185,8 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf, char buf[20]; int len; - switch (key->conf.alg) { - case ALG_AES_CMAC: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_AES_CMAC: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.icverrors); break; diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 5d5d2a974668..b5a95582d816 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -336,7 +336,7 @@ TRACE_EVENT(drv_set_key, LOCAL_ENTRY VIF_ENTRY STA_ENTRY - __field(enum ieee80211_key_alg, alg) + __field(u32, cipher) __field(u8, hw_key_idx) __field(u8, flags) __field(s8, keyidx) @@ -346,7 +346,7 @@ TRACE_EVENT(drv_set_key, LOCAL_ASSIGN; VIF_ASSIGN; STA_ASSIGN; - __entry->alg = key->alg; + __entry->cipher = key->cipher; __entry->flags = key->flags; __entry->keyidx = key->keyidx; __entry->hw_key_idx = key->hw_key_idx; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index d6dbc8ea4ead..3203d1d3cd38 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -227,9 +227,7 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, } } -struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, - int idx, - size_t key_len, +struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, const u8 *key_data, size_t seq_len, const u8 *seq) { @@ -249,15 +247,16 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, key->conf.flags = 0; key->flags = 0; - key->conf.alg = alg; + key->conf.cipher = cipher; key->conf.keyidx = idx; key->conf.keylen = key_len; - switch (alg) { - case ALG_WEP: + switch (cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: key->conf.iv_len = WEP_IV_LEN; key->conf.icv_len = WEP_ICV_LEN; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: key->conf.iv_len = TKIP_IV_LEN; key->conf.icv_len = TKIP_ICV_LEN; if (seq) { @@ -269,7 +268,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, } } break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: key->conf.iv_len = CCMP_HDR_LEN; key->conf.icv_len = CCMP_MIC_LEN; if (seq) { @@ -279,7 +278,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, seq[CCMP_PN_LEN - j - 1]; } break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: key->conf.iv_len = 0; key->conf.icv_len = sizeof(struct ieee80211_mmie); if (seq) @@ -290,7 +289,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, memcpy(key->conf.key, key_data, key_len); INIT_LIST_HEAD(&key->list); - if (alg == ALG_CCMP) { + if (cipher == WLAN_CIPHER_SUITE_CCMP) { /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. @@ -303,7 +302,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, } } - if (alg == ALG_AES_CMAC) { + if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) { /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. @@ -328,9 +327,9 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) if (key->local) ieee80211_key_disable_hw_accel(key); - if (key->conf.alg == ALG_CCMP) + if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) ieee80211_aes_key_free(key->u.ccmp.tfm); - if (key->conf.alg == ALG_AES_CMAC) + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); if (key->local) ieee80211_debugfs_key_remove(key); diff --git a/net/mac80211/key.h b/net/mac80211/key.h index b665bbb7a471..53b5ce12536f 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -123,9 +123,7 @@ struct ieee80211_key { struct ieee80211_key_conf conf; }; -struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, - int idx, - size_t key_len, +struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, const u8 *key_data, size_t seq_len, const u8 *seq); /* diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f24a0a1cff1a..ad2427021b26 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -961,7 +961,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) * pairwise or station-to-station keys, but for WEP we allow * using a key index as well. */ - if (rx->key && rx->key->conf.alg != ALG_WEP && + if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && + rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && !is_multicast_ether_addr(hdr->addr1)) rx->key = NULL; } @@ -977,8 +978,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_UNUSABLE; /* the hdr variable is invalid now! */ - switch (rx->key->conf.alg) { - case ALG_WEP: + switch (rx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: /* Check for weak IVs if possible */ if (rx->sta && ieee80211_is_data(fc) && (!(status->flag & RX_FLAG_IV_STRIPPED) || @@ -988,13 +990,13 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) result = ieee80211_crypto_wep_decrypt(rx); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: result = ieee80211_crypto_tkip_decrypt(rx); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: result = ieee80211_crypto_ccmp_decrypt(rx); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: result = ieee80211_crypto_aes_cmac_decrypt(rx); break; } @@ -1291,7 +1293,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) /* This is the first fragment of a new frame. */ entry = ieee80211_reassemble_add(rx->sdata, frag, seq, rx->queue, &(rx->skb)); - if (rx->key && rx->key->conf.alg == ALG_CCMP && + if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && ieee80211_has_protected(fc)) { int queue = ieee80211_is_mgmt(fc) ? NUM_RX_DATA_QUEUES : rx->queue; @@ -1320,7 +1322,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) int i; u8 pn[CCMP_PN_LEN], *rpn; int queue; - if (!rx->key || rx->key->conf.alg != ALG_CCMP) + if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) return RX_DROP_UNUSABLE; memcpy(pn, entry->last_pn, CCMP_PN_LEN); for (i = CCMP_PN_LEN - 1; i >= 0; i--) { diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926b..bc4fefc91663 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -543,15 +543,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) tx->key->tx_rx_count++; /* TODO: add threshold stuff again */ - switch (tx->key->conf.alg) { - case ALG_WEP: + switch (tx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (ieee80211_is_auth(hdr->frame_control)) break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: if (!ieee80211_is_data_present(hdr->frame_control)) tx->key = NULL; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (!ieee80211_is_data_present(hdr->frame_control) && !ieee80211_use_mfp(hdr->frame_control, tx->sta, tx->skb)) @@ -561,7 +562,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) IEEE80211_KEY_FLAG_SW_MGMT) && ieee80211_is_mgmt(hdr->frame_control); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: if (!ieee80211_is_mgmt(hdr->frame_control)) tx->key = NULL; break; @@ -949,14 +950,15 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) if (!tx->key) return TX_CONTINUE; - switch (tx->key->conf.alg) { - case ALG_WEP: + switch (tx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return ieee80211_crypto_wep_encrypt(tx); - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: return ieee80211_crypto_tkip_encrypt(tx); - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return ieee80211_crypto_ccmp_encrypt(tx); - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: return ieee80211_crypto_aes_cmac_encrypt(tx); } diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9ebc8d8a1f5b..f27484c22b9f 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -240,7 +240,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, keyidx = skb->data[hdrlen + 3] >> 6; - if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP) + if (!key || keyidx != key->conf.keyidx) return -1; klen = 3 + key->conf.keylen; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 8d59d27d887e..b08ad94b56da 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -36,8 +36,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) int tail; hdr = (struct ieee80211_hdr *)skb->data; - if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || - !ieee80211_is_data_present(hdr->frame_control)) + if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) return TX_CONTINUE; hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -94,7 +94,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_MMIC_STRIPPED) return RX_CONTINUE; - if (!rx->key || rx->key->conf.alg != ALG_TKIP || + if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || !ieee80211_has_protected(hdr->frame_control) || !ieee80211_is_data_present(hdr->frame_control)) return RX_CONTINUE; -- cgit v1.2.3 From 60ae0f20058d19ada94093dc3ef7ae0737597fba Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Aug 2010 09:46:39 +0200 Subject: mac80211: move key tfm setup There's no need to keep separate if statements for setting up the CCMP/AES-CMAC tfm structs; move that into the existing switch statement. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/key.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 3203d1d3cd38..9c27c53cfae5 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -277,19 +277,6 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, key->u.ccmp.rx_pn[i][j] = seq[CCMP_PN_LEN - j - 1]; } - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - key->conf.iv_len = 0; - key->conf.icv_len = sizeof(struct ieee80211_mmie); - if (seq) - for (j = 0; j < 6; j++) - key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; - break; - } - memcpy(key->conf.key, key_data, key_len); - INIT_LIST_HEAD(&key->list); - - if (cipher == WLAN_CIPHER_SUITE_CCMP) { /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. @@ -300,9 +287,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, kfree(key); key = ERR_PTR(err); } - } - - if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + key->conf.iv_len = 0; + key->conf.icv_len = sizeof(struct ieee80211_mmie); + if (seq) + for (j = 0; j < 6; j++) + key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. @@ -314,7 +305,10 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, kfree(key); key = ERR_PTR(err); } + break; } + memcpy(key->conf.key, key_data, key_len); + INIT_LIST_HEAD(&key->list); return key; } -- cgit v1.2.3 From dc1580ddfc1f70636f6ef80a385902f7e8278deb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Aug 2010 09:46:40 +0200 Subject: mac80211: remove unused status flag checks The decryption code verifies whether or not a given frame was decrypted and verified by hardware. This is unnecessary, as the crypto RX handler already does it long before the decryption code is even invoked, so remove that code to avoid confusion. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 3 +++ net/mac80211/wpa.c | 26 ++++++-------------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ad2427021b26..4fdbed58ca2f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -899,6 +899,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) if (!is_multicast_ether_addr(hdr->addr1) && stakey) { rx->key = stakey; + if ((status->flag & RX_FLAG_DECRYPTED) && + (status->flag & RX_FLAG_IV_STRIPPED)) + return RX_CONTINUE; /* Skip decryption if the frame is not protected. */ if (!ieee80211_has_protected(fc)) return RX_CONTINUE; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index b08ad94b56da..43882b36da55 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -221,19 +221,13 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || skb->len - hdrlen < 12) return RX_DROP_UNUSABLE; - if (status->flag & RX_FLAG_DECRYPTED) { - if (status->flag & RX_FLAG_IV_STRIPPED) { - /* - * Hardware took care of all processing, including - * replay protection, and stripped the ICV/IV so - * we cannot do any checks here. - */ - return RX_CONTINUE; - } - - /* let TKIP code verify IV, but skip decryption */ + /* + * Let TKIP code verify IV, but skip decryption. + * In the case where hardware checks the IV as well, + * we don't even get here, see ieee80211_rx_h_decrypt() + */ + if (status->flag & RX_FLAG_DECRYPTED) hwaccel = 1; - } res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, key, skb->data + hdrlen, @@ -447,10 +441,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || data_len < 0) return RX_DROP_UNUSABLE; - if ((status->flag & RX_FLAG_DECRYPTED) && - (status->flag & RX_FLAG_IV_STRIPPED)) - return RX_CONTINUE; - ccmp_hdr2pn(pn, skb->data + hdrlen); queue = ieee80211_is_mgmt(hdr->frame_control) ? @@ -564,10 +554,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) if (!ieee80211_is_mgmt(hdr->frame_control)) return RX_CONTINUE; - if ((status->flag & RX_FLAG_DECRYPTED) && - (status->flag & RX_FLAG_IV_STRIPPED)) - return RX_CONTINUE; - if (skb->len < 24 + sizeof(*mmie)) return RX_DROP_UNUSABLE; -- cgit v1.2.3 From 5daa8a8e691e28c6c725e7e91319b160b555c615 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Aug 2010 09:46:41 +0200 Subject: mac80211: dont advertise WEP if unavailable When WEP is unavailable, don't advertise it to cfg80211. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 06b9608a2130..0afccda42a24 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -536,6 +536,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) int channels, max_bitrates; bool supp_ht; static const u32 cipher_suites[] = { + /* keep WEP first, it may be removed below */ WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, @@ -623,6 +624,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) local->hw.wiphy->n_cipher_suites--; + if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { + local->hw.wiphy->cipher_suites += 2; + local->hw.wiphy->n_cipher_suites -= 2; + } result = wiphy_register(local->hw.wiphy); if (result < 0) -- cgit v1.2.3 From afea0b7af7a0c070da8b2029d721abc930e5f96f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Aug 2010 09:46:42 +0200 Subject: cfg80211: check if WEP is available for shared key auth When shared key auth is requested, cfg80211 should verify that the device is capable of WEP crypto which is required. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 37902a54e9c1..bb5b78eebeb2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3572,6 +3572,21 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; + if (key.idx >= 0) { + int i; + bool ok = false; + for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) { + if (key.p.cipher == rdev->wiphy.cipher_suites[i]) { + ok = true; + break; + } + } + if (!ok) { + err = -EINVAL; + goto out; + } + } + if (!rdev->ops->auth) { err = -EOPNOTSUPP; goto out; -- cgit v1.2.3 From b68b3c4d92ff2440414137763477648e6db6c96f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 10 Aug 2010 18:01:06 -0700 Subject: drivers/net/wireless/libertas/cfg.c: needs sched.h i386 allmodconfig: drivers/net/wireless/libertas/cfg.c: In function 'lbs_scan_worker': drivers/net/wireless/libertas/cfg.c:722: error: 'TASK_NORMAL' undeclared (first use in this function) drivers/net/wireless/libertas/cfg.c:722: error: (Each undeclared identifier is reported only once drivers/net/wireless/libertas/cfg.c:722: error: for each function it appears in.) drivers/net/wireless/libertas/cfg.c: In function 'lbs_cfg_connect': drivers/net/wireless/libertas/cfg.c:1267: error: 'TASK_INTERRUPTIBLE' undeclared (first use in this function) drivers/net/wireless/libertas/cfg.c:1267: error: implicit declaration of function 'signal_pending' drivers/net/wireless/libertas/cfg.c:1267: error: implicit declaration of function 'schedule_timeout' So wait.h has a dependency on sched.h, but doesn't include sched.h. This patch doesn't fix that. Cc: Dan Williams Cc: "John W. Linville" Cc: Ingo Molnar Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 08487a848e05..03b7108505e7 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 6891dd25d3f82e50979b27fde1980aa96320b975 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 3 Aug 2010 21:49:40 +0000 Subject: bnx2x: Load firmware in open() instead of probe() Loading firmware when actually bringing eth device up. This also will allow driver to be insmoded when filesystem with firmware files is not available yet. Suggested by Stephen Hemminger Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 20 ++++++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 9 +++++++++ drivers/net/bnx2x/bnx2x_main.c | 26 +++++++------------------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 02bf710629a3..da96d1a18c20 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "bnx2x_cmn.h" #ifdef BCM_VLAN @@ -1206,12 +1207,27 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) return rc; } +static void bnx2x_release_firmware(struct bnx2x *bp) +{ + kfree(bp->init_ops_offsets); + kfree(bp->init_ops); + kfree(bp->init_data); + release_firmware(bp->firmware); +} + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { u32 load_code; int i, rc; + /* Set init arrays */ + rc = bnx2x_init_firmware(bp); + if (rc) { + BNX2X_ERR("Error loading firmware\n"); + return rc; + } + #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -EPERM; @@ -1427,6 +1443,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif bnx2x_inc_load_cnt(bp); + bnx2x_release_firmware(bp); + return 0; #ifdef BCM_CNIC @@ -1454,6 +1472,8 @@ load_error1: netif_napi_del(&bnx2x_fp(bp, i, napi)); bnx2x_free_mem(bp); + bnx2x_release_firmware(bp); + return rc; } diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index d1979b1a7ed2..32543c32805c 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -114,6 +114,15 @@ void bnx2x_int_enable(struct bnx2x *bp); */ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); +/** + * Loads device firmware + * + * @param bp + * + * @return int + */ +int bnx2x_init_firmware(struct bnx2x *bp); + /** * Init HW blocks according to current initialization stage: * COMMON, PORT or FUNCTION. diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b4ec2b02a465..13309f1717b9 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -7254,7 +7254,7 @@ static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp, *speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; } -static int __devinit bnx2x_check_firmware(struct bnx2x *bp) +static int bnx2x_check_firmware(struct bnx2x *bp) { const struct firmware *firmware = bp->firmware; struct bnx2x_fw_file_hdr *fw_hdr; @@ -7365,7 +7365,7 @@ do { \ (u8 *)bp->arr, len); \ } while (0) -static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) +int bnx2x_init_firmware(struct bnx2x *bp) { const char *fw_file_name; struct bnx2x_fw_file_hdr *fw_hdr; @@ -7376,21 +7376,21 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) else if (CHIP_IS_E1H(bp)) fw_file_name = FW_FILE_NAME_E1H; else { - dev_err(dev, "Unsupported chip revision\n"); + BNX2X_ERR("Unsupported chip revision\n"); return -EINVAL; } - dev_info(dev, "Loading %s\n", fw_file_name); + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); - rc = request_firmware(&bp->firmware, fw_file_name, dev); + rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); if (rc) { - dev_err(dev, "Can't load firmware file %s\n", fw_file_name); + BNX2X_ERR("Can't load firmware file %s\n", fw_file_name); goto request_firmware_exit; } rc = bnx2x_check_firmware(bp); if (rc) { - dev_err(dev, "Corrupt firmware file %s\n", fw_file_name); + BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); goto request_firmware_exit; } @@ -7468,13 +7468,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (rc) goto init_one_exit; - /* Set init arrays */ - rc = bnx2x_init_firmware(bp, &pdev->dev); - if (rc) { - dev_err(&pdev->dev, "Error loading firmware\n"); - goto init_one_exit; - } - rc = register_netdev(dev); if (rc) { dev_err(&pdev->dev, "Cannot register net device\n"); @@ -7525,11 +7518,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); - kfree(bp->init_ops_offsets); - kfree(bp->init_ops); - kfree(bp->init_data); - release_firmware(bp->firmware); - if (bp->regview) iounmap(bp->regview); -- cgit v1.2.3 From bfb564e7391340638afe4ad67744a8f3858e7566 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Wed, 4 Aug 2010 06:15:52 +0000 Subject: core: Factor out flow calculation from get_rps_cpu Factor out flow calculation code from get_rps_cpu, since other functions can use the same code. Revisions: v2 (Ben): Separate flow calcuation out and use in select queue. v3 (Arnd): Don't re-implement MIN. v4 (Changli): skb->data points to ethernet header in macvtap, and make a fast path. Tested macvtap with this patch. v5 (Changli): - Cache skb->rxhash in skb_get_rxhash - macvtap may not have pow(2) queues, so change code for queue selection. (Arnd): - Use first available queue if all fails. Signed-off-by: Krishna Kumar Signed-off-by: David S. Miller --- include/linux/skbuff.h | 9 +++++ net/core/dev.c | 106 +++++++++++++++++++++++++++++-------------------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 77eb60d2b496..d8050382b189 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -558,6 +558,15 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, unsigned int to, struct ts_config *config, struct ts_state *state); +extern __u32 __skb_get_rxhash(struct sk_buff *skb); +static inline __u32 skb_get_rxhash(struct sk_buff *skb) +{ + if (!skb->rxhash) + skb->rxhash = __skb_get_rxhash(skb); + + return skb->rxhash; +} + #ifdef NET_SKBUFF_DATA_USES_OFFSET static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) { diff --git a/net/core/dev.c b/net/core/dev.c index 1ae654391442..586a11cb4398 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2259,69 +2259,41 @@ static inline void ____napi_schedule(struct softnet_data *sd, __raise_softirq_irqoff(NET_RX_SOFTIRQ); } -#ifdef CONFIG_RPS - -/* One global table that all flow-based protocols share. */ -struct rps_sock_flow_table *rps_sock_flow_table __read_mostly; -EXPORT_SYMBOL(rps_sock_flow_table); - /* - * get_rps_cpu is called from netif_receive_skb and returns the target - * CPU from the RPS map of the receiving queue for a given skb. - * rcu_read_lock must be held on entry. + * __skb_get_rxhash: calculate a flow hash based on src/dst addresses + * and src/dst port numbers. Returns a non-zero hash number on success + * and 0 on failure. */ -static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, - struct rps_dev_flow **rflowp) +__u32 __skb_get_rxhash(struct sk_buff *skb) { + int nhoff, hash = 0; struct ipv6hdr *ip6; struct iphdr *ip; - struct netdev_rx_queue *rxqueue; - struct rps_map *map; - struct rps_dev_flow_table *flow_table; - struct rps_sock_flow_table *sock_flow_table; - int cpu = -1; u8 ip_proto; - u16 tcpu; u32 addr1, addr2, ihl; union { u32 v32; u16 v16[2]; } ports; - if (skb_rx_queue_recorded(skb)) { - u16 index = skb_get_rx_queue(skb); - if (unlikely(index >= dev->num_rx_queues)) { - WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " - "on queue %u, but number of RX queues is %u\n", - dev->name, index, dev->num_rx_queues); - goto done; - } - rxqueue = dev->_rx + index; - } else - rxqueue = dev->_rx; - - if (!rxqueue->rps_map && !rxqueue->rps_flow_table) - goto done; - - if (skb->rxhash) - goto got_hash; /* Skip hash computation on packet header */ + nhoff = skb_network_offset(skb); switch (skb->protocol) { case __constant_htons(ETH_P_IP): - if (!pskb_may_pull(skb, sizeof(*ip))) + if (!pskb_may_pull(skb, sizeof(*ip) + nhoff)) goto done; - ip = (struct iphdr *) skb->data; + ip = (struct iphdr *) skb->data + nhoff; ip_proto = ip->protocol; addr1 = (__force u32) ip->saddr; addr2 = (__force u32) ip->daddr; ihl = ip->ihl; break; case __constant_htons(ETH_P_IPV6): - if (!pskb_may_pull(skb, sizeof(*ip6))) + if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff)) goto done; - ip6 = (struct ipv6hdr *) skb->data; + ip6 = (struct ipv6hdr *) skb->data + nhoff; ip_proto = ip6->nexthdr; addr1 = (__force u32) ip6->saddr.s6_addr32[3]; addr2 = (__force u32) ip6->daddr.s6_addr32[3]; @@ -2330,6 +2302,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, default: goto done; } + switch (ip_proto) { case IPPROTO_TCP: case IPPROTO_UDP: @@ -2338,8 +2311,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, case IPPROTO_AH: case IPPROTO_SCTP: case IPPROTO_UDPLITE: - if (pskb_may_pull(skb, (ihl * 4) + 4)) { - ports.v32 = * (__force u32 *) (skb->data + (ihl * 4)); + if (pskb_may_pull(skb, (ihl * 4) + 4 + nhoff)) { + ports.v32 = * (__force u32 *) (skb->data + nhoff + + (ihl * 4)); if (ports.v16[1] < ports.v16[0]) swap(ports.v16[0], ports.v16[1]); break; @@ -2352,11 +2326,55 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, /* get a consistent hash (same value on both flow directions) */ if (addr2 < addr1) swap(addr1, addr2); - skb->rxhash = jhash_3words(addr1, addr2, ports.v32, hashrnd); - if (!skb->rxhash) - skb->rxhash = 1; -got_hash: + hash = jhash_3words(addr1, addr2, ports.v32, hashrnd); + if (!hash) + hash = 1; + +done: + return hash; +} +EXPORT_SYMBOL(__skb_get_rxhash); + +#ifdef CONFIG_RPS + +/* One global table that all flow-based protocols share. */ +struct rps_sock_flow_table *rps_sock_flow_table __read_mostly; +EXPORT_SYMBOL(rps_sock_flow_table); + +/* + * get_rps_cpu is called from netif_receive_skb and returns the target + * CPU from the RPS map of the receiving queue for a given skb. + * rcu_read_lock must be held on entry. + */ +static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, + struct rps_dev_flow **rflowp) +{ + struct netdev_rx_queue *rxqueue; + struct rps_map *map; + struct rps_dev_flow_table *flow_table; + struct rps_sock_flow_table *sock_flow_table; + int cpu = -1; + u16 tcpu; + + if (skb_rx_queue_recorded(skb)) { + u16 index = skb_get_rx_queue(skb); + if (unlikely(index >= dev->num_rx_queues)) { + WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " + "on queue %u, but number of RX queues is %u\n", + dev->name, index, dev->num_rx_queues); + goto done; + } + rxqueue = dev->_rx + index; + } else + rxqueue = dev->_rx; + + if (!rxqueue->rps_map && !rxqueue->rps_flow_table) + goto done; + + if (!skb_get_rxhash(skb)) + goto done; + flow_table = rcu_dereference(rxqueue->rps_flow_table); sock_flow_table = rcu_dereference(rps_sock_flow_table); if (flow_table && sock_flow_table) { -- cgit v1.2.3 From 1565c7c1c4c8e931bdba66abc8aa6f141a406872 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Wed, 4 Aug 2010 06:15:59 +0000 Subject: macvtap: Implement multiqueue for macvtap driver Implement multiqueue facility for macvtap driver. The idea is that a macvtap device can be opened multiple times and the fd's can be used to register eg, as backend for vhost. Signed-off-by: Krishna Kumar Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 99 ++++++++++++++++++++++++++++++++++++++-------- include/linux/if_macvlan.h | 9 ++++- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 3b1c54a9c6ef..42567279843e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -84,26 +84,45 @@ static const struct proto_ops macvtap_socket_ops; static DEFINE_SPINLOCK(macvtap_lock); /* - * Choose the next free queue, for now there is only one + * get_slot: return a [unused/occupied] slot in vlan->taps[]: + * - if 'q' is NULL, return the first empty slot; + * - otherwise, return the slot this pointer occupies. */ +static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q) +{ + int i; + + for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { + if (rcu_dereference(vlan->taps[i]) == q) + return i; + } + + /* Should never happen */ + BUG_ON(1); +} + static int macvtap_set_queue(struct net_device *dev, struct file *file, struct macvtap_queue *q) { struct macvlan_dev *vlan = netdev_priv(dev); + int index; int err = -EBUSY; spin_lock(&macvtap_lock); - if (rcu_dereference(vlan->tap)) + if (vlan->numvtaps == MAX_MACVTAP_QUEUES) goto out; err = 0; + index = get_slot(vlan, NULL); rcu_assign_pointer(q->vlan, vlan); - rcu_assign_pointer(vlan->tap, q); + rcu_assign_pointer(vlan->taps[index], q); sock_hold(&q->sk); q->file = file; file->private_data = q; + vlan->numvtaps++; + out: spin_unlock(&macvtap_lock); return err; @@ -124,9 +143,12 @@ static void macvtap_put_queue(struct macvtap_queue *q) spin_lock(&macvtap_lock); vlan = rcu_dereference(q->vlan); if (vlan) { - rcu_assign_pointer(vlan->tap, NULL); + int index = get_slot(vlan, q); + + rcu_assign_pointer(vlan->taps[index], NULL); rcu_assign_pointer(q->vlan, NULL); sock_put(&q->sk); + --vlan->numvtaps; } spin_unlock(&macvtap_lock); @@ -136,39 +158,82 @@ static void macvtap_put_queue(struct macvtap_queue *q) } /* - * Since we only support one queue, just dereference the pointer. + * Select a queue based on the rxq of the device on which this packet + * arrived. If the incoming device is not mq, calculate a flow hash + * to select a queue. If all fails, find the first available queue. + * Cache vlan->numvtaps since it can become zero during the execution + * of this function. */ static struct macvtap_queue *macvtap_get_queue(struct net_device *dev, struct sk_buff *skb) { struct macvlan_dev *vlan = netdev_priv(dev); + struct macvtap_queue *tap = NULL; + int numvtaps = vlan->numvtaps; + __u32 rxq; + + if (!numvtaps) + goto out; + + if (likely(skb_rx_queue_recorded(skb))) { + rxq = skb_get_rx_queue(skb); + + while (unlikely(rxq >= numvtaps)) + rxq -= numvtaps; + + tap = rcu_dereference(vlan->taps[rxq]); + if (tap) + goto out; + } + + /* Check if we can use flow to select a queue */ + rxq = skb_get_rxhash(skb); + if (rxq) { + tap = rcu_dereference(vlan->taps[rxq % numvtaps]); + if (tap) + goto out; + } - return rcu_dereference(vlan->tap); + /* Everything failed - find first available queue */ + for (rxq = 0; rxq < MAX_MACVTAP_QUEUES; rxq++) { + tap = rcu_dereference(vlan->taps[rxq]); + if (tap) + break; + } + +out: + return tap; } /* * The net_device is going away, give up the reference - * that it holds on the queue (all the queues one day) - * and safely set the pointer from the queues to NULL. + * that it holds on all queues and safely set the pointer + * from the queues to NULL. */ static void macvtap_del_queues(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); - struct macvtap_queue *q; + struct macvtap_queue *q, *qlist[MAX_MACVTAP_QUEUES]; + int i, j = 0; + /* macvtap_put_queue can free some slots, so go through all slots */ spin_lock(&macvtap_lock); - q = rcu_dereference(vlan->tap); - if (!q) { - spin_unlock(&macvtap_lock); - return; + for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) { + q = rcu_dereference(vlan->taps[i]); + if (q) { + qlist[j++] = q; + rcu_assign_pointer(vlan->taps[i], NULL); + rcu_assign_pointer(q->vlan, NULL); + vlan->numvtaps--; + } } - - rcu_assign_pointer(vlan->tap, NULL); - rcu_assign_pointer(q->vlan, NULL); + BUG_ON(vlan->numvtaps != 0); spin_unlock(&macvtap_lock); synchronize_rcu(); - sock_put(&q->sk); + + for (--j; j >= 0; j--) + sock_put(&qlist[j]->sk); } /* diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 35280b302290..8a2fd66a8b5f 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -40,6 +40,12 @@ struct macvlan_rx_stats { unsigned long rx_errors; }; +/* + * Maximum times a macvtap device can be opened. This can be used to + * configure the number of receive queue, e.g. for multiqueue virtio. + */ +#define MAX_MACVTAP_QUEUES (NR_CPUS < 16 ? NR_CPUS : 16) + struct macvlan_dev { struct net_device *dev; struct list_head list; @@ -50,7 +56,8 @@ struct macvlan_dev { enum macvlan_mode mode; int (*receive)(struct sk_buff *skb); int (*forward)(struct net_device *dev, struct sk_buff *skb); - struct macvtap_queue *tap; + struct macvtap_queue *taps[MAX_MACVTAP_QUEUES]; + int numvtaps; }; static inline void macvlan_count_rx(const struct macvlan_dev *vlan, -- cgit v1.2.3 From 354c8e3104a8513dbbdc4dea1ffbefe714371e88 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:17:00 +0000 Subject: drivers/net/wan: Adjust confusing if indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Acked-by: Krzysztof HaÅ‚asa Signed-off-by: David S. Miller --- drivers/net/wan/c101.c | 2 +- drivers/net/wan/n2.c | 2 +- drivers/net/wan/pci200syn.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 0bd898c94759..4ac85a09c5a6 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -264,7 +264,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 5394b51bdb2f..7a3720f09ce3 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -282,7 +282,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index e2cff64a446a..fd7375955e41 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -220,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; -- cgit v1.2.3 From 510a05edce43ec29ceb105677ad8e6ff58f02c72 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:19:00 +0000 Subject: net/atm: Adjust confusing if indentation Outdent the code following an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- net/atm/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/atm/common.c b/net/atm/common.c index 940404a73b3d..1b9c52a02cd3 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -792,7 +792,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, default: if (level == SOL_SOCKET) return -EINVAL; - break; + break; } if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL; -- cgit v1.2.3 From 9b0f1d85968334c9bbe8675a0fc676c6e15ba577 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:22:00 +0000 Subject: drivers/net/irda: Adjust confusing if indentation Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/irda/mcs7780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 5b1036ac38d7..74b20f179cea 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -734,7 +734,7 @@ static int mcs_net_open(struct net_device *netdev) } if (!mcs_setup_urbs(mcs)) - goto error3; + goto error3; ret = mcs_receive_start(mcs); if (ret) -- cgit v1.2.3 From 022484c17253aea84aa2603068ea065ca59bb5e5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:22:20 +0000 Subject: drivers/net: Adjust confusing if indentation In amd8111e.c, indent the branch of an if. In eepro.c, outdent the code following the if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/amd8111e.c | 4 ++-- drivers/net/eepro.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 585c25f4b60c..1f5fc64b3224 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -396,7 +396,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod) event_count = coal_conf->rx_event_count; if( timeout > MAX_TIMEOUT || event_count > MAX_EVENT_COUNT ) - return -EINVAL; + return -EINVAL; timeout = timeout * DELAY_TIMER_CONV; writel(VAL0|STINTEN, mmio+INTEN0); @@ -409,7 +409,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod) event_count = coal_conf->tx_event_count; if( timeout > MAX_TIMEOUT || event_count > MAX_EVENT_COUNT ) - return -EINVAL; + return -EINVAL; timeout = timeout * DELAY_TIMER_CONV; diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 8d97f168f018..7c826319ee5a 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1457,11 +1457,11 @@ hardware_send_packet(struct net_device *dev, void *buf, short length) if (net_debug > 5) printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name); - /* determine how much of the transmit buffer space is available */ - if (lp->tx_end > lp->tx_start) + /* determine how much of the transmit buffer space is available */ + if (lp->tx_end > lp->tx_start) tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start); - else if (lp->tx_end < lp->tx_start) - tx_available = lp->tx_start - lp->tx_end; + else if (lp->tx_end < lp->tx_start) + tx_available = lp->tx_start - lp->tx_end; else tx_available = lp->xmt_ram; if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) { -- cgit v1.2.3 From 6f74dbbc29df6f53bc0deaa8e5a6ff81a4f91534 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:25:24 +0000 Subject: drivers/atm: Adjust confusing if indentation Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/atm/iphase.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index ee9ddeb53417..8b358d7d958f 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -220,7 +220,7 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) { while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) { dev->ffL.tcq_rd += 2; if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) - dev->ffL.tcq_rd = dev->ffL.tcq_st; + dev->ffL.tcq_rd = dev->ffL.tcq_st; if (dev->ffL.tcq_rd == dev->host_tcq_wr) return 0xFFFF; desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd); -- cgit v1.2.3 From 2145f1afc6b2abe97d983e90c53a1dc17e2da831 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:26:20 +0000 Subject: drivers/net: Adjust confusing if indentation Outdent the code following the if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4f7c3f3ca234..3d9f958ebd2c 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1859,7 +1859,7 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) printk(KERN_ERR "%s: Can't get IRQ %d\n", dev->name, grp->interruptError); - goto err_irq_fail; + goto err_irq_fail; } if ((err = request_irq(grp->interruptTransmit, gfar_transmit, -- cgit v1.2.3 From cc81735e8099deaed7436418f6d83a98be2c2101 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:26:38 +0000 Subject: drivers/net/bnx2x: Adjust confusing if indentation Outdent the code following the if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 0383e3066313..0fa09913051d 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1254,11 +1254,11 @@ static void bnx2x_set_autoneg(struct link_params *params, PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV2, - reg_val); + CL45_WR_OVER_CL22(bp, params->port, + params->phy_addr, + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV2, + reg_val); /* CL73 Autoneg Enabled */ reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; -- cgit v1.2.3 From 1f1d47ef4779fb45e8cccde6f31c76c3cdabbec1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:28:12 +0000 Subject: drivers/net/hamradio: Adjust confusing if indentation Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/hamradio/scc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 9f64c8637208..33655814448e 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1069,7 +1069,8 @@ static void scc_tx_done(struct scc_channel *scc) case KISS_DUPLEX_LINK: scc->stat.tx_state = TXS_IDLE2; if (scc->kiss.idletime != TIMER_OFF) - scc_start_tx_timer(scc, t_idle, scc->kiss.idletime*100); + scc_start_tx_timer(scc, t_idle, + scc->kiss.idletime*100); break; case KISS_DUPLEX_OPTIMA: scc_notify(scc, HWEV_ALL_SENT); -- cgit v1.2.3 From 9e1634a734bdd2dac5687f57dd427bef083e4659 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:28:31 +0000 Subject: drivers/net: Adjust confusing if indentation Outdent the code following the if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index e1f6156b3710..ac3985ceb5f7 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -506,7 +506,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget) "restart rx from a descriptor that's " "not free: %p\n", priv->dev->name, restart); - goto fatal_error; + goto fatal_error; } cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); -- cgit v1.2.3 From f7df0b8d924ad2f39852ea397d39a51fbb955212 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:29:19 +0000 Subject: drivers/isdn: Adjust confusing if indentation In hisax/hfc_sx.c and mISDN/l1oip_core.c, the code after the if is outdented so that it is not aligned with the if branch. In mISDN/dsp_cmx.c, an else is added between the original if branch and the following statement, in line with the code following it. Without this change, the first assignment to dsp->rx_W has no useful effect. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/isdn/hisax/hfc_sx.c | 13 +++++++------ drivers/isdn/mISDN/dsp_cmx.c | 1 + drivers/isdn/mISDN/l1oip_core.c | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index be5faf4aa868..5aa138eb0b3c 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -234,13 +234,14 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) count++; if (count > trans_max) count = trans_max; /* limit length */ - if ((skb = dev_alloc_skb(count))) { - dst = skb_put(skb, count); - while (count--) + skb = dev_alloc_skb(count); + if (skb) { + dst = skb_put(skb, count); + while (count--) *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); - return(skb); - } - else return(NULL); /* no memory */ + return skb; + } else + return NULL; /* no memory */ } do { diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 713ef2b805a2..76d9e673b4e1 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -1237,6 +1237,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb) if (dsp->cmx_delay) dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) & CMX_BUFF_MASK; + else dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) & CMX_BUFF_MASK; } else { diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 22f38e48ac4e..5b59796ed250 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -972,7 +972,7 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) if (debug & DEBUG_L1OIP_SOCKET) printk(KERN_DEBUG "%s: got new ip address from user " "space.\n", __func__); - l1oip_socket_open(hc); + l1oip_socket_open(hc); break; case MISDN_CTRL_UNSETPEER: if (debug & DEBUG_L1OIP_SOCKET) -- cgit v1.2.3 From bb8a10bbd10a45db0eb45bac520489bdbc0917ef Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 5 Aug 2010 10:29:38 +0000 Subject: net/decnet: Adjust confusing if indentation Indent the branch of an if. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r disable braces4@ position p1,p2; statement S1,S2; @@ ( if (...) { ... } | if (...) S1@p1 S2@p2 ) @script:python@ p1 << r.p1; p2 << r.p2; @@ if (p1[0].column == p2[0].column): cocci.print_main("branch",p1) cocci.print_secs("after",p2) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- net/decnet/dn_nsp_out.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index baeb1eaf011b..2ef115277bea 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -693,22 +693,22 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) aux = scp->accessdata.acc_userl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux); aux = scp->accessdata.acc_passl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux); aux = scp->accessdata.acc_accl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux); aux = (__u8)le16_to_cpu(scp->conndata_out.opt_optl); *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux); + memcpy(skb_put(skb, aux), scp->conndata_out.opt_data, aux); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_retrans_conninit; -- cgit v1.2.3 From 01414802054c382072b6cb9a1bdc6e243c74b2d5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 17 Aug 2010 02:31:15 -0700 Subject: ethtool: Provide a default implementation of ethtool_ops::get_drvinfo The driver name and bus address for a net_device can normally be found through the driver model now. Instead of requiring drivers to provide this information redundantly through the ethtool_ops::get_drvinfo operation, use the driver model to do so if the driver does not define the operation. Since ETHTOOL_GDRVINFO no longer requires the driver to implement any operations, do not require net_device::ethtool_ops to be set either. Remove implementations of get_drvinfo and ethtool_ops that provide only this information. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/firewire/net.c | 13 ------------- drivers/ieee1394/eth1394.c | 16 ---------------- drivers/net/bmac.c | 7 ------- drivers/net/fec_mpc52xx.c | 6 ------ drivers/net/pasemi_mac_ethtool.c | 16 ---------------- drivers/net/pcmcia/3c574_cs.c | 13 ------------- drivers/net/pcmcia/axnet_cs.c | 13 ------------- drivers/net/pcmcia/ibmtr_cs.c | 13 ------------- drivers/net/pcmcia/pcnet_cs.c | 16 ---------------- drivers/net/sc92031.c | 11 ----------- drivers/net/tulip/xircom_cb.c | 15 --------------- drivers/net/usb/hso.c | 9 --------- drivers/net/usb/kaweth.c | 9 --------- drivers/net/virtio_net.c | 14 -------------- drivers/net/wireless/ray_cs.c | 16 ---------------- drivers/net/wireless/wl3501_cs.c | 11 ----------- net/core/ethtool.c | 33 +++++++++++++++++++++++---------- 17 files changed, 23 insertions(+), 208 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index da17d409a244..51e8a35ebd7e 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -1359,17 +1358,6 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) return 0; } -static void fwnet_get_drvinfo(struct net_device *net, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, KBUILD_MODNAME); - strcpy(info->bus_info, "ieee1394"); -} - -static const struct ethtool_ops fwnet_ethtool_ops = { - .get_drvinfo = fwnet_get_drvinfo, -}; - static const struct net_device_ops fwnet_netdev_ops = { .ndo_open = fwnet_open, .ndo_stop = fwnet_stop, @@ -1388,7 +1376,6 @@ static void fwnet_init_dev(struct net_device *net) net->hard_header_len = FWNET_HLEN; net->type = ARPHRD_IEEE1394; net->tx_queue_len = 10; - SET_ETHTOOL_OPS(net, &fwnet_ethtool_ops); } /* caller must hold fwnet_device_mutex */ diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index bc289e367e30..63403822330e 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -173,8 +172,6 @@ static netdev_tx_t ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); -static const struct ethtool_ops ethtool_ops; - static int ether1394_write(struct hpsb_host *host, int srcid, int destid, quadlet_t *data, u64 addr, size_t len, u16 flags); static void ether1394_add_host(struct hpsb_host *host); @@ -525,8 +522,6 @@ static void ether1394_init_dev(struct net_device *dev) dev->header_ops = ðer1394_header_ops; dev->netdev_ops = ðer1394_netdev_ops; - SET_ETHTOOL_OPS(dev, ðtool_ops); - dev->watchdog_timeo = ETHER1394_TIMEOUT; dev->flags = IFF_BROADCAST | IFF_MULTICAST; dev->features = NETIF_F_HIGHDMA; @@ -1695,17 +1690,6 @@ fail: return NETDEV_TX_OK; } -static void ether1394_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, driver_name); - strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */ -} - -static const struct ethtool_ops ethtool_ops = { - .get_drvinfo = ether1394_get_drvinfo -}; - static int __init ether1394_init_module(void) { int err; diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 959add2410bf..9322699bb31c 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1233,15 +1233,8 @@ static void bmac_reset_and_enable(struct net_device *dev) } spin_unlock_irqrestore(&bp->lock, flags); } -static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct bmac_data *bp = netdev_priv(dev); - strcpy(info->driver, "bmac"); - strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev)); -} static const struct ethtool_ops bmac_ethtool_ops = { - .get_drvinfo = bmac_get_drvinfo, .get_link = ethtool_op_get_link, }; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index e3e10b4add9c..e9f5d030bc26 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -771,11 +771,6 @@ static void mpc52xx_fec_reset(struct net_device *dev) /* ethtool interface */ -static void mpc52xx_fec_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRIVER_NAME); -} static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -810,7 +805,6 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level) } static const struct ethtool_ops mpc52xx_fec_ethtool_ops = { - .get_drvinfo = mpc52xx_fec_get_drvinfo, .get_settings = mpc52xx_fec_get_settings, .set_settings = mpc52xx_fec_set_settings, .get_link = ethtool_op_get_link, diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c index fefa79e34b95..4825959a0efe 100644 --- a/drivers/net/pasemi_mac_ethtool.c +++ b/drivers/net/pasemi_mac_ethtool.c @@ -90,21 +90,6 @@ pasemi_mac_ethtool_set_settings(struct net_device *netdev, return phy_ethtool_sset(phydev, cmd); } -static void -pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) -{ - struct pasemi_mac *mac; - mac = netdev_priv(netdev); - - /* clear and fill out info */ - memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); - strncpy(drvinfo->driver, "pasemi_mac", 12); - strcpy(drvinfo->version, "N/A"); - strcpy(drvinfo->fw_version, "N/A"); - strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32); -} - static u32 pasemi_mac_ethtool_get_msglevel(struct net_device *netdev) { @@ -164,7 +149,6 @@ static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset, const struct ethtool_ops pasemi_mac_ethtool_ops = { .get_settings = pasemi_mac_ethtool_get_settings, .set_settings = pasemi_mac_ethtool_set_settings, - .get_drvinfo = pasemi_mac_ethtool_get_drvinfo, .get_msglevel = pasemi_mac_ethtool_get_msglevel, .set_msglevel = pasemi_mac_ethtool_set_msglevel, .get_link = ethtool_op_get_link, diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index c683f77c6f42..9a1840b67e78 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -83,7 +83,6 @@ earlier 3Com products. #include #include #include -#include #include #include @@ -238,7 +237,6 @@ static int el3_rx(struct net_device *dev, int worklimit); static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static const struct ethtool_ops netdev_ethtool_ops; static void set_rx_mode(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -285,7 +283,6 @@ static int tc574_probe(struct pcmcia_device *link) link->conf.ConfigIndex = 1; dev->netdev_ops = &el3_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->watchdog_timeo = TX_TIMEOUT; return tc574_config(link); @@ -1065,16 +1062,6 @@ static int el3_rx(struct net_device *dev, int worklimit) return worklimit; } -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "3c574_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /* Provide ioctl() calls to examine the MII xcvr state. */ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 5f05ffb240cc..a6e37b29e3bf 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -86,7 +85,6 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, static struct net_device_stats *get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void axnet_tx_timeout(struct net_device *dev); -static const struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); static void ei_watchdog(u_long arg); static void axnet_reset_8390(struct net_device *dev); @@ -171,7 +169,6 @@ static int axnet_probe(struct pcmcia_device *link) dev->netdev_ops = &axnet_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->watchdog_timeo = TX_TIMEOUT; return axnet_config(link); @@ -658,16 +655,6 @@ reschedule: add_timer(&info->watchdog); } -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "axnet_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /*====================================================================*/ static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index b0d06a3d962f..cbcda123b1bf 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -107,16 +106,6 @@ typedef struct ibmtr_dev_t { struct tok_info *ti; } ibmtr_dev_t; -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "ibmtr_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { ibmtr_dev_t *info = dev_id; struct net_device *dev = info->dev; @@ -159,8 +148,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) info->dev = dev; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return ibmtr_config(link); } /* ibmtr_attach */ diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index c3edfe4c2651..2e1348c0033e 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -100,7 +99,6 @@ static void pcnet_release(struct pcmcia_device *link); static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static const struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); @@ -628,8 +626,6 @@ static int pcnet_config(struct pcmcia_device *link) ei_status.word16 = 1; ei_status.reset_8390 = &pcnet_reset_8390; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - if (info->flags & (IS_DL10019|IS_DL10022)) mii_phy_probe(dev); @@ -1143,18 +1139,6 @@ reschedule: /*====================================================================*/ -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "pcnet_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - -/*====================================================================*/ - static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 8c4067af32b0..31b92f5f32cb 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -1251,16 +1251,6 @@ static int sc92031_ethtool_set_settings(struct net_device *dev, return 0; } -static void sc92031_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *drvinfo) -{ - struct sc92031_priv *priv = netdev_priv(dev); - struct pci_dev *pdev = priv->pdev; - - strcpy(drvinfo->driver, SC92031_NAME); - strcpy(drvinfo->bus_info, pci_name(pdev)); -} - static void sc92031_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) { @@ -1382,7 +1372,6 @@ static void sc92031_ethtool_get_ethtool_stats(struct net_device *dev, static const struct ethtool_ops sc92031_ethtool_ops = { .get_settings = sc92031_ethtool_get_settings, .set_settings = sc92031_ethtool_set_settings, - .get_drvinfo = sc92031_ethtool_get_drvinfo, .get_wol = sc92031_ethtool_get_wol, .set_wol = sc92031_ethtool_set_wol, .nway_reset = sc92031_ethtool_nway_reset, diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index a439e93be22d..5a73752be2ca 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -181,19 +180,6 @@ static void print_binary(unsigned int number) } #endif -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct xircom_private *private = netdev_priv(dev); - - strcpy(info->driver, "xircom_cb"); - strcpy(info->bus_info, pci_name(private->pdev)); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - static const struct net_device_ops netdev_ops = { .ndo_open = xircom_open, .ndo_stop = xircom_close, @@ -279,7 +265,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ setup_descriptors(private); dev->netdev_ops = &netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); pci_set_drvdata(pdev, dev); if (register_netdev(dev)) { diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6efca66b8766..4f123f869bdc 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -843,16 +843,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } -static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -{ - struct hso_net *odev = netdev_priv(net); - - strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN); - usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info); -} - static const struct ethtool_ops ops = { - .get_drvinfo = hso_get_drvinfo, .get_link = ethtool_op_get_link }; diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 2b7b39cad1ce..5e98643a4a21 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -759,14 +759,6 @@ static int kaweth_close(struct net_device *net) return 0; } -static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct kaweth_device *kaweth = netdev_priv(dev); - - strlcpy(info->driver, driver_name, sizeof(info->driver)); - usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info)); -} - static u32 kaweth_get_link(struct net_device *dev) { struct kaweth_device *kaweth = netdev_priv(dev); @@ -775,7 +767,6 @@ static u32 kaweth_get_link(struct net_device *dev) } static const struct ethtool_ops ops = { - .get_drvinfo = kaweth_get_drvinfo, .get_link = kaweth_get_link }; diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4598e9d2608f..bb6b67f6b0cc 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -705,19 +705,6 @@ static int virtnet_close(struct net_device *dev) return 0; } -static void virtnet_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *drvinfo) -{ - struct virtnet_info *vi = netdev_priv(dev); - struct virtio_device *vdev = vi->vdev; - - strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver)); - strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version)); - strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version)); - strncpy(drvinfo->bus_info, dev_name(&vdev->dev), - ARRAY_SIZE(drvinfo->bus_info)); -} - static int virtnet_set_tx_csum(struct net_device *dev, u32 data) { struct virtnet_info *vi = netdev_priv(dev); @@ -830,7 +817,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) } static const struct ethtool_ops virtnet_ethtool_ops = { - .get_drvinfo = virtnet_get_drvinfo, .set_tx_csum = virtnet_set_tx_csum, .set_sg = ethtool_op_set_sg, .set_tso = ethtool_op_set_tso, diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 88560d0ae50a..3bd9cf76517d 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -80,8 +79,6 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map); static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); -static const struct ethtool_ops netdev_ethtool_ops; - static int ray_open(struct net_device *dev); static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); @@ -333,7 +330,6 @@ static int ray_probe(struct pcmcia_device *p_dev) /* Raylink entries in the device structure */ dev->netdev_ops = &ray_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->wireless_handlers = &ray_handler_def; #ifdef WIRELESS_SPY local->wireless_data.spy_data = &local->spy_data; @@ -1062,18 +1058,6 @@ AP to AP 1 1 dest AP src AP dest source } } /* end encapsulate_frame */ -/*===========================================================================*/ - -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "ray_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /*====================================================================*/ /*------------------------------------------------------------------*/ diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index a1cc2d498a1c..420e9e986a18 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -1411,15 +1410,6 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) return wstats; } -static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - strlcpy(info->driver, "wl3501_cs", sizeof(info->driver)); -} - -static const struct ethtool_ops ops = { - .get_drvinfo = wl3501_get_drvinfo -}; - /** * wl3501_detach - deletes a driver "instance" * @link - FILL_IN @@ -1905,7 +1895,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev) this->p_dev = p_dev; dev->wireless_data = &this->wireless_data; dev->wireless_handlers = &wl3501_handler_def; - SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); p_dev->priv = dev; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 7a85367b3c2f..d2c4da5a6a4f 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -205,18 +205,24 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo info; const struct ethtool_ops *ops = dev->ethtool_ops; - if (!ops->get_drvinfo) - return -EOPNOTSUPP; - memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GDRVINFO; - ops->get_drvinfo(dev, &info); + if (ops && ops->get_drvinfo) { + ops->get_drvinfo(dev, &info); + } else if (dev->dev.parent && dev->dev.parent->driver) { + strlcpy(info.bus_info, dev_name(dev->dev.parent), + sizeof(info.bus_info)); + strlcpy(info.driver, dev->dev.parent->driver->name, + sizeof(info.driver)); + } else { + return -EOPNOTSUPP; + } /* * this method of obtaining string set info is deprecated; * Use ETHTOOL_GSSET_INFO instead. */ - if (ops->get_sset_count) { + if (ops && ops->get_sset_count) { int rc; rc = ops->get_sset_count(dev, ETH_SS_TEST); @@ -229,9 +235,9 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, if (rc >= 0) info.n_priv_flags = rc; } - if (ops->get_regs_len) + if (ops && ops->get_regs_len) info.regdump_len = ops->get_regs_len(dev); - if (ops->get_eeprom_len) + if (ops && ops->get_eeprom_len) info.eedump_len = ops->get_eeprom_len(dev); if (copy_to_user(useraddr, &info, sizeof(info))) @@ -1402,12 +1408,19 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) if (!dev || !netif_device_present(dev)) return -ENODEV; - if (!dev->ethtool_ops) - return -EOPNOTSUPP; - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; + if (!dev->ethtool_ops) { + /* ETHTOOL_GDRVINFO does not require any driver support. + * It is also unprivileged and does not change anything, + * so we can take a shortcut to it. */ + if (ethcmd == ETHTOOL_GDRVINFO) + return ethtool_get_drvinfo(dev, useraddr); + else + return -EOPNOTSUPP; + } + /* Allow some commands to be done by anyone */ switch (ethcmd) { case ETHTOOL_GDRVINFO: -- cgit v1.2.3 From ea0a52c4fd8eb2c8e0586b939c484e160fb4a721 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 8 Aug 2010 02:32:05 +0000 Subject: pcnet_cs: Use proper netdev_*-printouts To prevent broken messages like: [ 204.024291] eth%d: pcnet_reset_8390() did not complete. Signed-off-by: Wolfram Sang Cc: Dominik Brodowski Cc: Joe Perches Cc: David Miller Signed-off-by: David S. Miller --- drivers/net/pcmcia/pcnet_cs.c | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 2e1348c0033e..296f8a8e57ca 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -638,12 +638,12 @@ static int pcnet_config(struct pcmcia_device *link) if (info->flags & (IS_DL10019|IS_DL10022)) { u_char id = inb(dev->base_addr + 0x1a); - printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ", - dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id); + netdev_info(dev, "NE2000 (DL100%d rev %02x): ", + (info->flags & IS_DL10022) ? 22 : 19, id); if (info->pna_phy) printk("PNA, "); } else { - printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name); + netdev_info(dev, "NE2000 Compatible: "); } printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); if (info->flags & USE_SHMEM) @@ -924,7 +924,7 @@ static void mii_phy_probe(struct net_device *dev) phyid = tmp << 16; phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2); phyid &= MII_PHYID_REV_MASK; - pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid); + netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid); if (phyid == AM79C9XX_HOME_PHY) { info->pna_phy = i; } else if (phyid != AM79C9XX_ETH_PHY) { @@ -1010,8 +1010,8 @@ static void pcnet_reset_8390(struct net_device *dev) outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ if (i == 100) - printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n", - dev->name); + netdev_err(dev, "pcnet_reset_8390() did not complete.\n"); + set_misc_reg(dev); } /* pcnet_reset_8390 */ @@ -1027,8 +1027,7 @@ static int set_config(struct net_device *dev, struct ifmap *map) else if ((map->port < 1) || (map->port > 2)) return -EINVAL; dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); NS8390_init(dev, 1); } return 0; @@ -1063,7 +1062,7 @@ static void ei_watchdog(u_long arg) this, we can limp along even if the interrupt is blocked */ if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); ei_irq_wrapper(dev->irq, dev); info->fast_poll = HZ; } @@ -1083,7 +1082,7 @@ static void ei_watchdog(u_long arg) if (info->eth_phy) { info->phy_id = info->eth_phy = 0; } else { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); info->flags &= ~HAS_MII; } goto reschedule; @@ -1092,8 +1091,7 @@ static void ei_watchdog(u_long arg) link &= 0x0004; if (link != info->link_status) { u_short p = mdio_read(mii_addr, info->phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); @@ -1104,13 +1102,12 @@ static void ei_watchdog(u_long arg) if (link) { if (info->phy_id == info->eth_phy) { if (p) - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, + netdev_info(dev, "autonegotiation complete: " + "%sbaseT-%cD selected\n", ((p & 0x0180) ? "100" : "10"), ((p & 0x0140) ? 'F' : 'H')); else - printk(KERN_INFO "%s: link partner did not " - "autonegotiate\n", dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); } NS8390_init(dev, 1); } @@ -1123,7 +1120,7 @@ static void ei_watchdog(u_long arg) /* isolate this MII and try flipping to the other one */ mdio_write(mii_addr, info->phy_id, 0, 0x0400); info->phy_id ^= info->pna_phy ^ info->eth_phy; - printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name, + netdev_info(dev, "switched to %s transceiver\n", (info->phy_id == info->eth_phy) ? "ethernet" : "PNA"); mdio_write(mii_addr, info->phy_id, 0, (info->phy_id == info->eth_phy) ? 0x1000 : 0); @@ -1171,9 +1168,9 @@ static void dma_get_8390_hdr(struct net_device *dev, unsigned int nic_base = dev->base_addr; if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + netdev_notice(dev, "DMAing conflict in dma_block_input." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } @@ -1204,11 +1201,11 @@ static void dma_block_input(struct net_device *dev, int count, char *buf = skb->data; if ((ei_debug > 4) && (count != 4)) - pr_debug("%s: [bi=%d]\n", dev->name, count+4); + netdev_dbg(dev, "[bi=%d]\n", count+4); if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + netdev_notice(dev, "DMAing conflict in dma_block_input." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; @@ -1238,9 +1235,9 @@ static void dma_block_input(struct net_device *dev, int count, break; } while (--tries > 0); if (tries <= 0) - printk(KERN_NOTICE "%s: RX transfer address mismatch," + netdev_notice(dev, "RX transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, ring_offset + xfer_count, addr); + ring_offset + xfer_count, addr); } #endif outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ @@ -1261,7 +1258,7 @@ static void dma_block_output(struct net_device *dev, int count, #ifdef PCMCIA_DEBUG if (ei_debug > 4) - printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count); + netdev_dbg(dev, "[bo=%d]\n", count); #endif /* Round the count up for word writes. Do we need to do this? @@ -1270,9 +1267,9 @@ static void dma_block_output(struct net_device *dev, int count, if (count & 0x01) count++; if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output." + netdev_notice(dev, "DMAing conflict in dma_block_output." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; @@ -1309,9 +1306,9 @@ static void dma_block_output(struct net_device *dev, int count, break; } while (--tries > 0); if (tries <= 0) { - printk(KERN_NOTICE "%s: Tx packet transfer address mismatch," + netdev_notice(dev, "Tx packet transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, (start_page << 8) + count, addr); + (start_page << 8) + count, addr); if (retries++ == 0) goto retry; } @@ -1320,8 +1317,7 @@ static void dma_block_output(struct net_device *dev, int count, while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) { - printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n", - dev->name); + netdev_notice(dev, "timeout waiting for Tx RDC.\n"); pcnet_reset_8390(dev); NS8390_init(dev, 1); break; -- cgit v1.2.3 From 7136e11e0cf520ab3fc7b55a20e60c2ec5ea88e1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 8 Aug 2010 04:50:36 +0000 Subject: pcnet_cs: Use pr_fmt and pr_ It looks as if the printks in get_ax88190 are incorrect and were duplicated and superceded by a test in pcnet_config, so I removed them. Changed the level of the ax88190 test to KERN_NOTICE to match the other message styles in pcnet_config. Compiled but untested. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/pcmcia/pcnet_cs.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 296f8a8e57ca..1815b2644b96 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -28,6 +28,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -432,8 +434,6 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link) dev->dev_addr[i] = j & 0xff; dev->dev_addr[i+1] = j >> 8; } - printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n"); - printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n"); return NULL; } @@ -568,15 +568,15 @@ static int pcnet_config(struct pcmcia_device *link) if ((if_port == 1) || (if_port == 2)) dev->if_port = if_port; else - printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n"); + pr_notice("invalid if_port requested\n"); } else { dev->if_port = 0; } if ((link->conf.ConfigBase == 0x03c0) && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { - printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); - printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); + pr_notice("this is an AX88190 card!\n"); + pr_notice("use axnet_cs instead.\n"); goto failed; } @@ -591,8 +591,8 @@ static int pcnet_config(struct pcmcia_device *link) local_hw_info = get_hwired(link); if (local_hw_info == NULL) { - printk(KERN_NOTICE "pcnet_cs: unable to read hardware net" - " address for io base %#3lx\n", dev->base_addr); + pr_notice("unable to read hardware net address for io base %#3lx\n", + dev->base_addr); goto failed; } @@ -632,7 +632,7 @@ static int pcnet_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } @@ -641,16 +641,16 @@ static int pcnet_config(struct pcmcia_device *link) netdev_info(dev, "NE2000 (DL100%d rev %02x): ", (info->flags & IS_DL10022) ? 22 : 19, id); if (info->pna_phy) - printk("PNA, "); + pr_cont("PNA, "); } else { netdev_info(dev, "NE2000 Compatible: "); } - printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); + pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq); if (info->flags & USE_SHMEM) - printk (" mem %#5lx,", dev->mem_start); + pr_cont(" mem %#5lx,", dev->mem_start); if (info->flags & HAS_MISC_REG) - printk(" %s xcvr,", if_names[dev->if_port]); - printk(" hw_addr %pM\n", dev->dev_addr); + pr_cont(" %s xcvr,", if_names[dev->if_port]); + pr_cont(" hw_addr %pM\n", dev->dev_addr); return 0; failed: -- cgit v1.2.3 From 2154c704c7240379fae4633359e06e8df875c1fd Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 8 Aug 2010 10:08:44 +0000 Subject: r6040: fix all checkpatch errors and warnings This patch fixes a couple of errors and warnings spotted by checkpatch.pl: - some lines were over 80 columns - there were some whitespaces left The call to printk is now replaced by a call to pr_info and the log-level included in the driver version is now removed, so there are no longer false positives on this warning. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 142c381e1d73..0a00850da79d 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -200,7 +200,7 @@ struct r6040_private { int old_duplex; }; -static char version[] __devinitdata = KERN_INFO DRV_NAME +static char version[] __devinitdata = DRV_NAME ": RDC R6040 NAPI net driver," "version "DRV_VERSION " (" DRV_RELDATE ")"; @@ -224,7 +224,8 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg) } /* Write a word data from PHY Chip */ -static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) +static void r6040_phy_write(void __iomem *ioaddr, + int phy_addr, int reg, u16 val) { int limit = 2048; u16 cmd; @@ -348,8 +349,8 @@ static int r6040_alloc_rxbufs(struct net_device *dev) } desc->skb_ptr = skb; desc->buf = cpu_to_le32(pci_map_single(lp->pdev, - desc->skb_ptr->data, - MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); + desc->skb_ptr->data, + MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); desc->status = DSC_OWNER_MAC; desc = desc->vndescp; } while (desc != lp->rx_ring); @@ -491,12 +492,14 @@ static int r6040_close(struct net_device *dev) /* Free Descriptor memory */ if (lp->rx_ring) { - pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); + pci_free_consistent(pdev, + RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); lp->rx_ring = NULL; } if (lp->tx_ring) { - pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); + pci_free_consistent(pdev, + TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); lp->tx_ring = NULL; } @@ -547,7 +550,7 @@ static int r6040_rx(struct net_device *dev, int limit) } goto next_descr; } - + /* Packet successfully received */ new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); if (!new_skb) { @@ -556,13 +559,13 @@ static int r6040_rx(struct net_device *dev, int limit) } skb_ptr = descptr->skb_ptr; skb_ptr->dev = priv->dev; - + /* Do not count the CRC */ skb_put(skb_ptr, descptr->len - 4); pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); - + /* Send to upper layer */ netif_receive_skb(skb_ptr); dev->stats.rx_packets++; @@ -710,8 +713,10 @@ static int r6040_up(struct net_device *dev) return ret; /* improve performance (by RDC guys) */ - r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); - r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000)); + r6040_phy_write(ioaddr, 30, 17, + (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); + r6040_phy_write(ioaddr, 30, 17, + ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000)); r6040_phy_write(ioaddr, 0, 19, 0x0000); r6040_phy_write(ioaddr, 0, 30, 0x01F0); @@ -946,7 +951,7 @@ static const struct net_device_ops r6040_netdev_ops = { .ndo_set_multicast_list = r6040_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = r6040_ioctl, .ndo_tx_timeout = r6040_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1039,7 +1044,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, u16 *adrp; int i; - printk("%s\n", version); + pr_info("%s\n", version); err = pci_enable_device(pdev); if (err) @@ -1113,7 +1118,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, /* Some bootloader/BIOSes do not initialize * MAC address, warn about that */ if (!(adrp[0] || adrp[1] || adrp[2])) { - netdev_warn(dev, "MAC address not initialized, generating random\n"); + netdev_warn(dev, "MAC address not initialized, " + "generating random\n"); random_ether_addr(dev->dev_addr); } -- cgit v1.2.3 From 264fd77a67f1a4fe102477d824014459c7ff61f3 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 9 Aug 2010 05:04:34 +0000 Subject: am79c961a: Use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so we can use this one instead of a private copy in the dev_priv struct. Cc: Kulikov Vasiliy Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/arm/am79c961a.c | 35 ++++++++++++++++------------------- drivers/net/arm/am79c961a.h | 1 - 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 8c496fb1ac9e..62f21106efec 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -300,8 +300,6 @@ am79c961_open(struct net_device *dev) struct dev_priv *priv = netdev_priv(dev); int ret; - memset (&priv->stats, 0, sizeof (priv->stats)); - ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev); if (ret) return ret; @@ -347,8 +345,7 @@ am79c961_close(struct net_device *dev) */ static struct net_device_stats *am79c961_getstats (struct net_device *dev) { - struct dev_priv *priv = netdev_priv(dev); - return &priv->stats; + return &dev->stats; } static void am79c961_mc_hash(char *addr, unsigned short *hash) @@ -510,14 +507,14 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) { am_writeword (dev, hdraddr + 2, RMD_OWN); - priv->stats.rx_errors ++; + dev->stats.rx_errors++; if (status & RMD_ERR) { if (status & RMD_FRAM) - priv->stats.rx_frame_errors ++; + dev->stats.rx_frame_errors++; if (status & RMD_CRC) - priv->stats.rx_crc_errors ++; + dev->stats.rx_crc_errors++; } else if (status & RMD_STP) - priv->stats.rx_length_errors ++; + dev->stats.rx_length_errors++; continue; } @@ -531,12 +528,12 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) am_writeword(dev, hdraddr + 2, RMD_OWN); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - priv->stats.rx_bytes += len; - priv->stats.rx_packets ++; + dev->stats.rx_bytes += len; + dev->stats.rx_packets++; } else { am_writeword (dev, hdraddr + 2, RMD_OWN); printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); - priv->stats.rx_dropped ++; + dev->stats.rx_dropped++; break; } } while (1); @@ -565,7 +562,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) if (status & TMD_ERR) { u_int status2; - priv->stats.tx_errors ++; + dev->stats.tx_errors++; status2 = am_readword (dev, hdraddr + 6); @@ -575,18 +572,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) am_writeword (dev, hdraddr + 6, 0); if (status2 & TST_RTRY) - priv->stats.collisions += 16; + dev->stats.collisions += 16; if (status2 & TST_LCOL) - priv->stats.tx_window_errors ++; + dev->stats.tx_window_errors++; if (status2 & TST_LCAR) - priv->stats.tx_carrier_errors ++; + dev->stats.tx_carrier_errors++; if (status2 & TST_UFLO) - priv->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; continue; } - priv->stats.tx_packets ++; + dev->stats.tx_packets++; len = am_readword (dev, hdraddr + 4); - priv->stats.tx_bytes += -len; + dev->stats.tx_bytes += -len; } while (priv->txtail != priv->txhead); netif_wake_queue(dev); @@ -616,7 +613,7 @@ am79c961_interrupt(int irq, void *dev_id) } if (status & CSR0_MISS) { handled = 1; - priv->stats.rx_dropped ++; + dev->stats.rx_dropped++; } if (status & CSR0_CERR) { handled = 1; diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h index 483009fe6ec2..fd634d32756b 100644 --- a/drivers/net/arm/am79c961a.h +++ b/drivers/net/arm/am79c961a.h @@ -130,7 +130,6 @@ #define ISALED0_LNKST 0x8000 struct dev_priv { - struct net_device_stats stats; unsigned long rxbuffer[RX_BUFFERS]; unsigned long txbuffer[TX_BUFFERS]; unsigned char txhead; -- cgit v1.2.3 From 559764d1996e6ae769feb07918687b0806f2d975 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 8 Aug 2010 10:09:39 +0000 Subject: cpmac: fix all checkpatch errors and warnings This patches fixes a couple of checkpatch warnings and errors: - lines over 80 columns - printk() instead of pr_cont() - assignments in tests (if ((foo == bar()))) Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index ac3985ceb5f7..8e142aaa05d4 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include MODULE_AUTHOR("Eugene Konev "); @@ -108,7 +108,7 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); #define CPMAC_RX_INT_CLEAR 0x019c #define CPMAC_MAC_INT_ENABLE 0x01a8 #define CPMAC_MAC_INT_CLEAR 0x01ac -#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4) +#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4) #define CPMAC_MAC_ADDR_MID 0x01d0 #define CPMAC_MAC_ADDR_HI 0x01d4 #define CPMAC_MAC_HASH_LO 0x01d8 @@ -227,7 +227,7 @@ static void cpmac_dump_regs(struct net_device *dev) for (i = 0; i < CPMAC_REG_END; i += 4) { if (i % 16 == 0) { if (i) - printk("\n"); + pr_cont("\n"); printk(KERN_DEBUG "%s: reg[%p]:", dev->name, priv->regs + i); } @@ -262,7 +262,7 @@ static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) for (i = 0; i < skb->len; i++) { if (i % 16 == 0) { if (i) - printk("\n"); + pr_cont("\n"); printk(KERN_DEBUG "%s: data[%p]:", dev->name, skb->data + i); } @@ -873,7 +873,8 @@ static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } -static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) +static void cpmac_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) { struct cpmac_priv *priv = netdev_priv(dev); @@ -888,7 +889,8 @@ static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam ring->tx_pending = 1; } -static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) +static int cpmac_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) { struct cpmac_priv *priv = netdev_priv(dev); @@ -1012,8 +1014,8 @@ static int cpmac_open(struct net_device *dev) priv->rx_head->prev->hw_next = (u32)0; - if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, - dev->name, dev))) { + res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev); + if (res) { if (netif_msg_drv(priv)) printk(KERN_ERR "%s: failed to obtain irq\n", dev->name); @@ -1133,7 +1135,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } if (phy_id == PHY_MAX_ADDR) { - dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); + dev_err(&pdev->dev, "no PHY present, falling back " + "to switch on MDIO bus 0\n"); strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ phy_id = pdev->id; } @@ -1169,7 +1172,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) priv->msg_enable = netif_msg_init(debug_level, 0xff); memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr)); - snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); + snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, + mdio_bus_id, phy_id); priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); @@ -1182,7 +1186,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) goto fail; } - if ((rc = register_netdev(dev))) { + rc = register_netdev(dev); + if (rc) { printk(KERN_ERR "cpmac: error %i registering device %s\n", rc, dev->name); goto fail; @@ -1248,11 +1253,13 @@ int __devinit cpmac_init(void) cpmac_mii->reset(cpmac_mii); - for (i = 0; i < 300; i++) - if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE))) + for (i = 0; i < 300; i++) { + mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE); + if (mask) break; else msleep(10); + } mask &= 0x7fffffff; if (mask & (mask - 1)) { -- cgit v1.2.3 From 294dab25e7068f9df80af53aceed332f9621c970 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:54:55 +0000 Subject: enic: Add set mac address This patch implements the ndo_set_mac_address netdev operation for an enic device Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f239aa8c6f4c..75869ed7226f 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.1" +#define DRV_VERSION "1.4.1.2" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9aab85366d21..6f6c5dc36197 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -911,7 +911,9 @@ static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p) static int enic_set_mac_address(struct net_device *netdev, void *p) { - return -EOPNOTSUPP; + struct sockaddr *saddr = p; + + return enic_set_mac_addr(netdev, (char *)saddr->sa_data); } static int enic_dev_packet_filter(struct enic *enic, int directed, -- cgit v1.2.3 From 90cf0b53d74ebca4f62d865ae39d21ed3bdbf877 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:00 +0000 Subject: enic: Add support for firmware management device This patch adds support for firmware management device in enic driver. A management device is a virtual PCIe device that firmware can present to the host as its management endpoint. It provides the interface between the host and adapter firmware for all management operations. Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/vnic_dev.c | 25 ++++++++++++++++++------- drivers/net/enic/vnic_resource.h | 13 +++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 6a5b578a69e1..08d5d42da260 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -74,6 +74,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, struct vnic_dev_bar *bar, unsigned int num_bars) { struct vnic_resource_header __iomem *rh; + struct mgmt_barmap_hdr __iomem *mrh; struct vnic_resource __iomem *r; u8 type; @@ -85,22 +86,32 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, return -EINVAL; } - rh = bar->vaddr; + rh = bar->vaddr; + mrh = bar->vaddr; if (!rh) { pr_err("vNIC BAR0 res hdr not mem-mapped\n"); return -EINVAL; } - if (ioread32(&rh->magic) != VNIC_RES_MAGIC || - ioread32(&rh->version) != VNIC_RES_VERSION) { - pr_err("vNIC BAR0 res magic/version error " - "exp (%lx/%lx) curr (%x/%x)\n", + /* Check for mgmt vnic in addition to normal vnic */ + if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) || + (ioread32(&rh->version) != VNIC_RES_VERSION)) { + if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) || + (ioread32(&mrh->version) != MGMTVNIC_VERSION)) { + pr_err("vNIC BAR0 res magic/version error " + "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n", VNIC_RES_MAGIC, VNIC_RES_VERSION, + MGMTVNIC_MAGIC, MGMTVNIC_VERSION, ioread32(&rh->magic), ioread32(&rh->version)); - return -EINVAL; + return -EINVAL; + } } - r = (struct vnic_resource __iomem *)(rh + 1); + if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC) + r = (struct vnic_resource __iomem *)(mrh + 1); + else + r = (struct vnic_resource __iomem *)(rh + 1); + while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h index 810287beff14..e0a73f1ca6f4 100644 --- a/drivers/net/enic/vnic_resource.h +++ b/drivers/net/enic/vnic_resource.h @@ -22,6 +22,11 @@ #define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */ #define VNIC_RES_VERSION 0x00000000L +#define MGMTVNIC_MAGIC 0x544d474dL /* 'MGMT' */ +#define MGMTVNIC_VERSION 0x00000000L + +/* The MAC address assigned to the CFG vNIC is fixed. */ +#define MGMTVNIC_MAC { 0x02, 0x00, 0x54, 0x4d, 0x47, 0x4d } /* vNIC resource types */ enum vnic_res_type { @@ -52,6 +57,14 @@ struct vnic_resource_header { u32 version; }; +struct mgmt_barmap_hdr { + u32 magic; /* magic number */ + u32 version; /* header format version */ + u16 lif; /* loopback lif for mgmt frames */ + u16 pci_slot; /* installed pci slot */ + char serial[16]; /* card serial number */ +}; + struct vnic_resource { u8 type; u8 bar; -- cgit v1.2.3 From ae94abe1687871d9772494b3d378c6d3decd7f75 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:05 +0000 Subject: enic: Add new firmware devcmds Add new firmware devcmds: CMD_PROXY_BY_INDEX, CMD_CONFIG_INFO_GET Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/vnic_devcmd.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index 20661755df6b..9abb3d51dea1 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h @@ -238,6 +238,18 @@ enum vnic_devcmd_cmd { * out: (u32)a0=status of proxied cmd * a1-a15=out args of proxied cmd */ CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42), + + /* + * As for BY_BDF except a0 is index of hvnlink subordinate vnic + * or SR-IOV virtual vnic */ + CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43), + + /* + * in: (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in + * (u32)a1=length of buffer in a0 + * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV + * (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */ + CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44), }; /* flags for CMD_OPEN */ -- cgit v1.2.3 From 7c46835e4845fed5f348f5845a3a6165874e2f05 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:10 +0000 Subject: enic: Use offsetof macro in vic tlv length calculation Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/vnic_vic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c index 197c9d24af82..4725b79de0ef 100644 --- a/drivers/net/enic/vnic_vic.c +++ b/drivers/net/enic/vnic_vic.c @@ -54,8 +54,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, if (!vp || !value) return -EINVAL; - if (ntohl(vp->length) + sizeof(*tlv) + length > - VIC_PROVINFO_MAX_TLV_DATA) + if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) + + length > VIC_PROVINFO_MAX_TLV_DATA) return -ENOMEM; tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + @@ -66,7 +66,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, memcpy(tlv->value, value, length); vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); - vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length); + vp->length = htonl(ntohl(vp->length) + + offsetof(struct vic_provinfo_tlv, value) + length); return 0; } -- cgit v1.2.3 From ce16cc02f9fe21d4e42116305e5ea9d12e51635d Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:15 +0000 Subject: enic: Clean up: remove enic_dev_stats_clear Remove function enic_dev_stats_clear and its reference in enic device init code. Firmware clears device stats on device open. So, no need for the driver to do it again. Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 6f6c5dc36197..711077a2e345 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2154,17 +2154,6 @@ void enic_dev_deinit(struct enic *enic) enic_clear_intr_mode(enic); } -static int enic_dev_stats_clear(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_stats_clear(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - int enic_dev_init(struct enic *enic) { struct device *dev = enic_get_dev(enic); @@ -2207,10 +2196,6 @@ int enic_dev_init(struct enic *enic) enic_init_vnic_resources(enic); - /* Clear LIF stats - */ - enic_dev_stats_clear(enic); - err = enic_set_rq_alloc_buf(enic); if (err) { dev_err(dev, "Failed to set RQ buffer allocator, aborting\n"); -- cgit v1.2.3 From 832177901a61aeda1f2122e323c39881ec84af65 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:20 +0000 Subject: enic: Check if rq/wq buf not NULL before freeing them Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/vnic_rq.c | 6 ++++-- drivers/net/enic/vnic_wq.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c index dbb2aca258b9..b236d7cbc137 100644 --- a/drivers/net/enic/vnic_rq.c +++ b/drivers/net/enic/vnic_rq.c @@ -77,8 +77,10 @@ void vnic_rq_free(struct vnic_rq *rq) vnic_dev_free_desc_ring(vdev, &rq->ring); for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) { - kfree(rq->bufs[i]); - rq->bufs[i] = NULL; + if (rq->bufs[i]) { + kfree(rq->bufs[i]); + rq->bufs[i] = NULL; + } } rq->ctrl = NULL; diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c index 122e33bcc578..4b2a6c6a569b 100644 --- a/drivers/net/enic/vnic_wq.c +++ b/drivers/net/enic/vnic_wq.c @@ -77,8 +77,10 @@ void vnic_wq_free(struct vnic_wq *wq) vnic_dev_free_desc_ring(vdev, &wq->ring); for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) { - kfree(wq->bufs[i]); - wq->bufs[i] = NULL; + if (wq->bufs[i]) { + kfree(wq->bufs[i]); + wq->bufs[i] = NULL; + } } wq->ctrl = NULL; -- cgit v1.2.3 From 1f76da51f58eda3a027e71e98404b80fcad2d80d Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Aug 2010 18:55:26 +0000 Subject: enic: Mark intr_timer in vnic_enet_config as deprecated Signed-off-by: Scott Feldman Signed-off-by: Roopa Prabhu Signed-off-by: Vasanthy Kolluri Signed-off-by: David S. Miller --- drivers/net/enic/vnic_enet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h index 3b3291248956..e8740e3704e4 100644 --- a/drivers/net/enic/vnic_enet.h +++ b/drivers/net/enic/vnic_enet.h @@ -30,7 +30,7 @@ struct vnic_enet_config { u32 wq_desc_count; u32 rq_desc_count; u16 mtu; - u16 intr_timer; + u16 intr_timer_deprecated; u8 intr_timer_type; u8 intr_mode; char devname[16]; -- cgit v1.2.3 From 933fce12a33f219e9021a9ab7b2f9cff94fa8b0e Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 17 Aug 2010 00:34:19 +0000 Subject: qlcnic: fix aer for virtual func Virtual function are not privilge to initialize firmware. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index bf6d87adda4f..4ecbf41230cb 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2733,7 +2733,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (qlcnic_api_lock(adapter)) return -EINVAL; - if (first_func) { + if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { adapter->need_fw_reset = 1; set_bit(__QLCNIC_START_FW, &adapter->state); QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING); -- cgit v1.2.3 From 3c4b23b1be212d1b8494655182c0d4cef0a37be3 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 17 Aug 2010 00:34:20 +0000 Subject: qlcnic: device state management fixes for virtual func o NPAR state should be set to operationl by Mangement function only. o NPAR state should be set to non operational before device reset. o VF function should wait for NPAR state to be operational. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_hdr.h | 5 ++- drivers/net/qlcnic/qlcnic_main.c | 80 ++++++++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 15fc32070be3..bd346d9aac94 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -718,8 +718,9 @@ enum { #define QLCNIC_DEV_FAILED 0x6 #define QLCNIC_DEV_QUISCENT 0x7 -#define QLCNIC_DEV_NPAR_NOT_RDY 0 -#define QLCNIC_DEV_NPAR_RDY 1 +#define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */ +#define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */ +#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */ #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4ecbf41230cb..70c4b6b0031e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2398,7 +2398,7 @@ qlcnic_fwinit_work(struct work_struct *work) { struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter, fw_work.work); - u32 dev_state = 0xf, npar_state; + u32 dev_state = 0xf; if (qlcnic_api_lock(adapter)) goto err_ret; @@ -2412,16 +2412,8 @@ qlcnic_fwinit_work(struct work_struct *work) } if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { - npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - if (npar_state == QLCNIC_DEV_NPAR_RDY) { - qlcnic_api_unlock(adapter); - goto wait_npar; - } else { - qlcnic_schedule_work(adapter, qlcnic_fwinit_work, - FW_POLL_DELAY); - qlcnic_api_unlock(adapter); - return; - } + qlcnic_api_unlock(adapter); + goto wait_npar; } if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { @@ -2470,20 +2462,17 @@ wait_npar: QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); switch (dev_state) { - case QLCNIC_DEV_QUISCENT: - case QLCNIC_DEV_NEED_QUISCENT: - case QLCNIC_DEV_NEED_RESET: - qlcnic_schedule_work(adapter, - qlcnic_fwinit_work, FW_POLL_DELAY); - return; - case QLCNIC_DEV_FAILED: - break; - - default: + case QLCNIC_DEV_READY: if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); return; } + case QLCNIC_DEV_FAILED: + break; + default: + qlcnic_schedule_work(adapter, + qlcnic_fwinit_work, FW_POLL_DELAY); + return; } err_ret: @@ -2530,6 +2519,22 @@ err_ret: } +/*Transit NPAR state to NON Operational */ +static void +qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) +{ + u32 state; + + state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + if (state == QLCNIC_DEV_NPAR_NON_OPER) + return; + + if (qlcnic_api_lock(adapter)) + return; + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); + qlcnic_api_unlock(adapter); +} + /*Transit to RESET state from READY state only */ static void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) @@ -2548,6 +2553,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) qlcnic_idc_debug_info(adapter, 0); } + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); qlcnic_api_unlock(adapter); } @@ -2555,21 +2561,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) { - u32 state; - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode == QLCNIC_NON_PRIV_FUNC) + adapter->op_mode != QLCNIC_MGMT_FUNC) return; if (qlcnic_api_lock(adapter)) return; - state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - - if (state != QLCNIC_DEV_NPAR_RDY) { - QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, - QLCNIC_DEV_NPAR_RDY); - QLCDB(adapter, DRV, "NPAR READY state set\n"); - } + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER); + QLCDB(adapter, DRV, "NPAR operational state set\n"); qlcnic_api_unlock(adapter); } @@ -2631,8 +2630,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) qlcnic_dev_request_reset(adapter); state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT) + if (state == QLCNIC_DEV_NEED_RESET || + state == QLCNIC_DEV_NEED_QUISCENT) { + qlcnic_set_npar_non_operational(adapter); adapter->need_fw_reset = 1; + } heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); if (heartbit != adapter->heartbit) { @@ -2822,11 +2824,25 @@ static int qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) { int err; + u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; + u32 npar_state; err = qlcnic_can_start_firmware(adapter); if (err) return err; + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { + msleep(1000); + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + } + + if (!npar_opt_timeo) { + dev_err(&adapter->pdev->dev, + "Waiting for NPAR state to opertional timeout\n"); + return -EIO; + } + qlcnic_check_options(adapter); adapter->need_fw_reset = 0; -- cgit v1.2.3 From ecd7d31038e2e0e95b4596eec021e02ba67a0a37 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 17 Aug 2010 00:34:21 +0000 Subject: qlcnic: fix for setting function modes function modes was not working with CNA device, in CNA mode other function(FCOE) can be enabled before nic. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 70c4b6b0031e..06ffd7637f87 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -543,8 +543,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) ret = qlcnic_api_lock(adapter); if (ret) goto err_lock; - if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func)) - goto err_npar; if (qlcnic_config_npars) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { @@ -562,7 +560,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) adapter->ahw.pci_func)); } writel(data, priv_op); -err_npar: qlcnic_api_unlock(adapter); err_lock: return ret; -- cgit v1.2.3 From b6021212291d1eb1e7d1245bbd8c53bcbe2355d7 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 17 Aug 2010 00:34:22 +0000 Subject: qlcnic: add eswitch statistics support Adding eswitch statistics support. User can get whole eswitch stats or stats of func belong to that eswitch. Added: o command to get statistics of eswitch and function. o sysfs support to export eswitch and func statatistics. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 31 +++++++++ drivers/net/qlcnic/qlcnic_ctx.c | 125 ++++++++++++++++++++++++++++++++++++ drivers/net/qlcnic/qlcnic_main.c | 132 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 287 insertions(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 970389331bbc..7f4e11bd4cd4 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -555,6 +555,7 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 +#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a #define QLCNIC_RCODE_SUCCESS 0 #define QLCNIC_RCODE_TIMEOUT 17 @@ -1126,6 +1127,31 @@ struct qlcnic_esw_func_cfg { u8 reserved; }; +#define QLCNIC_STATS_VERSION 1 +#define QLCNIC_STATS_PORT 1 +#define QLCNIC_STATS_ESWITCH 2 +#define QLCNIC_QUERY_RX_COUNTER 0 +#define QLCNIC_QUERY_TX_COUNTER 1 +struct __qlcnic_esw_statistics { + __le16 context_id; + __le16 version; + __le16 size; + __le16 unused; + __le64 unicast_frames; + __le64 multicast_frames; + __le64 broadcast_frames; + __le64 dropped_frames; + __le64 errors; + __le64 local_frames; + __le64 numbytes; + __le64 rsvd[3]; +}; + +struct qlcnic_esw_statistics { + struct __qlcnic_esw_statistics rx; + struct __qlcnic_esw_statistics tx; +}; + int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); @@ -1252,6 +1278,11 @@ int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, u8, u8, u16); int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); +int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8, + struct __qlcnic_esw_statistics *); +int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8, + struct __qlcnic_esw_statistics *); +int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8); extern int qlcnic_config_tso; /* diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index cc5d861d9a12..57c9b09bd16a 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -983,3 +983,128 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, return err; } + +int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, + const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { + + size_t stats_size = sizeof(struct __qlcnic_esw_statistics); + dma_addr_t stats_dma_t; + void *stats_addr; + u32 arg1; + int err; + + if (esw_stats == NULL) + return -ENOMEM; + + if (adapter->op_mode != QLCNIC_MGMT_FUNC && + func != adapter->ahw.pci_func) { + dev_err(&adapter->pdev->dev, + "Not privilege to query stats for func=%d", func); + return -EIO; + } + + stats_addr = pci_alloc_consistent(adapter->pdev, stats_size, + &stats_dma_t); + if (!stats_addr) { + dev_err(&adapter->pdev->dev, "Unable to allocate memory\n"); + return -ENOMEM; + } + memset(stats_addr, 0, stats_size); + + arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; + arg1 |= rx_tx << 15 | stats_size << 16; + + err = qlcnic_issue_cmd(adapter, + adapter->ahw.pci_func, + adapter->fw_hal_version, + arg1, + MSD(stats_dma_t), + LSD(stats_dma_t), + QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); + + if (!err) + memcpy(esw_stats, stats_addr, stats_size); + + pci_free_consistent(adapter->pdev, stats_size, stats_addr, + stats_dma_t); + return err; +} + +int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, + const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { + + struct __qlcnic_esw_statistics port_stats; + u8 i; + int ret = -EIO; + + if (esw_stats == NULL) + return -ENOMEM; + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + return -EIO; + if (adapter->npars == NULL) + return -EIO; + + memset(esw_stats, 0, sizeof(struct __qlcnic_esw_statistics)); + esw_stats->context_id = eswitch; + + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + if (adapter->npars[i].phy_port != eswitch) + continue; + + memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics)); + if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats)) + continue; + + esw_stats->size = port_stats.size; + esw_stats->version = port_stats.version; + esw_stats->unicast_frames += port_stats.unicast_frames; + esw_stats->multicast_frames += port_stats.multicast_frames; + esw_stats->broadcast_frames += port_stats.broadcast_frames; + esw_stats->dropped_frames += port_stats.dropped_frames; + esw_stats->errors += port_stats.errors; + esw_stats->local_frames += port_stats.local_frames; + esw_stats->numbytes += port_stats.numbytes; + + ret = 0; + } + return ret; +} + +int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, + const u8 port, const u8 rx_tx) +{ + + u32 arg1; + + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + return -EIO; + + if (func_esw == QLCNIC_STATS_PORT) { + if (port >= QLCNIC_MAX_PCI_FUNC) + goto err_ret; + } else if (func_esw == QLCNIC_STATS_ESWITCH) { + if (port >= QLCNIC_NIU_MAX_XG_PORTS) + goto err_ret; + } else { + goto err_ret; + } + + if (rx_tx > QLCNIC_QUERY_TX_COUNTER) + goto err_ret; + + arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12; + arg1 |= BIT_14 | rx_tx << 15; + + return qlcnic_issue_cmd(adapter, + adapter->ahw.pci_func, + adapter->fw_hal_version, + arg1, + 0, + 0, + QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); + +err_ret: + dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d" + "rx_ctx=%d\n", func_esw, port, rx_tx); + return -EIO; +} diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 06ffd7637f87..a30bde52d40b 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -3377,6 +3377,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj, return size; } +static ssize_t +qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + struct qlcnic_esw_statistics port_stats; + int ret; + + if (size != sizeof(struct qlcnic_esw_statistics)) + return QL_STATUS_INVALID_PARAM; + + if (offset >= QLCNIC_MAX_PCI_FUNC) + return QL_STATUS_INVALID_PARAM; + + memset(&port_stats, 0, size); + ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER, + &port_stats.rx); + if (ret) + return ret; + + ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER, + &port_stats.tx); + if (ret) + return ret; + + memcpy(buf, &port_stats, size); + return size; +} + +static ssize_t +qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + struct qlcnic_esw_statistics esw_stats; + int ret; + + if (size != sizeof(struct qlcnic_esw_statistics)) + return QL_STATUS_INVALID_PARAM; + + if (offset >= QLCNIC_NIU_MAX_XG_PORTS) + return QL_STATUS_INVALID_PARAM; + + memset(&esw_stats, 0, size); + ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER, + &esw_stats.rx); + if (ret) + return ret; + + ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER, + &esw_stats.tx); + if (ret) + return ret; + + memcpy(buf, &esw_stats, size); + return size; +} + +static ssize_t +qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + int ret; + + if (offset >= QLCNIC_NIU_MAX_XG_PORTS) + return QL_STATUS_INVALID_PARAM; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset, + QLCNIC_QUERY_RX_COUNTER); + if (ret) + return ret; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset, + QLCNIC_QUERY_TX_COUNTER); + if (ret) + return ret; + + return size; +} + +static ssize_t +qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + int ret; + + if (offset >= QLCNIC_MAX_PCI_FUNC) + return QL_STATUS_INVALID_PARAM; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, + QLCNIC_QUERY_RX_COUNTER); + if (ret) + return ret; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, + QLCNIC_QUERY_TX_COUNTER); + if (ret) + return ret; + + return size; +} + static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t size) @@ -3426,6 +3535,20 @@ static struct bin_attribute bin_attr_pci_config = { .write = NULL, }; +static struct bin_attribute bin_attr_port_stats = { + .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)}, + .size = 0, + .read = qlcnic_sysfs_get_port_stats, + .write = qlcnic_sysfs_clear_port_stats, +}; + +static struct bin_attribute bin_attr_esw_stats = { + .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)}, + .size = 0, + .read = qlcnic_sysfs_get_esw_stats, + .write = qlcnic_sysfs_clear_esw_stats, +}; + static struct bin_attribute bin_attr_esw_config = { .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)}, .size = 0, @@ -3465,6 +3588,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + if (device_create_bin_file(dev, &bin_attr_port_stats)) + dev_info(dev, "failed to create port stats sysfs entry"); + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return; if (device_create_file(dev, &dev_attr_diag_mode)) @@ -3484,7 +3610,8 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) dev_info(dev, "failed to create esw config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_pm_config)) dev_info(dev, "failed to create pm config sysfs entry"); - + if (device_create_bin_file(dev, &bin_attr_esw_stats)) + dev_info(dev, "failed to create eswitch stats sysfs entry"); } static void @@ -3492,6 +3619,8 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + device_remove_bin_file(dev, &bin_attr_port_stats); + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return; device_remove_file(dev, &dev_attr_diag_mode); @@ -3504,6 +3633,7 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) device_remove_bin_file(dev, &bin_attr_npar_config); device_remove_bin_file(dev, &bin_attr_esw_config); device_remove_bin_file(dev, &bin_attr_pm_config); + device_remove_bin_file(dev, &bin_attr_esw_stats); } #ifdef CONFIG_INET -- cgit v1.2.3 From 69324275de07584fbd0e77a517f9b43e82eaf9d6 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Tue, 17 Aug 2010 00:34:23 +0000 Subject: qlcnic: fix link status message Display interface name with netdev_info() for link status message. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a30bde52d40b..bf4077a1e824 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1944,14 +1944,14 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) struct net_device *netdev = adapter->netdev; if (adapter->ahw.linkup && !linkup) { - dev_info(&netdev->dev, "NIC Link is down\n"); + netdev_info(netdev, "NIC Link is down\n"); adapter->ahw.linkup = 0; if (netif_running(netdev)) { netif_carrier_off(netdev); netif_stop_queue(netdev); } } else if (!adapter->ahw.linkup && linkup) { - dev_info(&netdev->dev, "NIC Link is up\n"); + netdev_info(netdev, "NIC Link is up\n"); adapter->ahw.linkup = 1; if (netif_running(netdev)) { netif_carrier_on(netdev); -- cgit v1.2.3 From 8dec32cc421864702912c4341934fe0c737a9798 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Tue, 17 Aug 2010 00:34:24 +0000 Subject: qlcnic: fix link diag test o Give sufficient time for all makes of PHY modules to establish the link after loopback test. o Perform online test before offline test. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 17 ++++++++--------- drivers/net/qlcnic/qlcnic_hw.c | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 9328d59e21e0..3d4655dce4b5 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -747,6 +747,14 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, { memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN); + data[0] = qlcnic_reg_test(dev); + if (data[0]) + eth_test->flags |= ETH_TEST_FL_FAILED; + + data[1] = (u64) qlcnic_test_link(dev); + if (data[1]) + eth_test->flags |= ETH_TEST_FL_FAILED; + if (eth_test->flags == ETH_TEST_FL_OFFLINE) { data[2] = qlcnic_irq_test(dev); if (data[2]) @@ -757,15 +765,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, eth_test->flags |= ETH_TEST_FL_FAILED; } - - data[0] = qlcnic_reg_test(dev); - if (data[0]) - eth_test->flags |= ETH_TEST_FL_FAILED; - - /* link test */ - data[1] = (u64) qlcnic_test_link(dev); - if (data[1]) - eth_test->flags |= ETH_TEST_FL_FAILED; } static void diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index e08c8b0556a4..9d40ce05cb17 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -1245,4 +1245,5 @@ void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) mode = VPORT_MISS_MODE_ACCEPT_MULTI; qlcnic_nic_set_promisc(adapter, mode); + msleep(1000); } -- cgit v1.2.3 From 24763d80fbb45aaf477d53c2203c929f6c41b5fc Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Tue, 17 Aug 2010 00:34:25 +0000 Subject: qlcnic: turn off lro when rxcsum is disabled. o Also dont allow lro to be turn on, if rx csum is disabled Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_ethtool.c | 23 +++++++++++++++++++++++ drivers/net/qlcnic/qlcnic_main.c | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 7f4e11bd4cd4..f6b887d409d5 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -894,6 +894,7 @@ struct qlcnic_mac_req { #define QLCNIC_MSI_ENABLED 0x02 #define QLCNIC_MSIX_ENABLED 0x04 #define QLCNIC_LRO_ENABLED 0x08 +#define QLCNIC_LRO_DISABLED 0x00 #define QLCNIC_BRIDGE_ENABLED 0X10 #define QLCNIC_DIAG_ENABLED 0x20 #define QLCNIC_ESWITCH_ENABLED 0x40 diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 3d4655dce4b5..e38fc3d96d43 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -818,7 +818,21 @@ static u32 qlcnic_get_rx_csum(struct net_device *dev) static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) { struct qlcnic_adapter *adapter = netdev_priv(dev); + + if (!!data) { + adapter->rx_csum = !!data; + return 0; + } + + if (adapter->flags & QLCNIC_LRO_ENABLED) { + if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED)) + return -EIO; + + dev->features &= ~NETIF_F_LRO; + qlcnic_send_lro_cleanup(adapter); + } adapter->rx_csum = !!data; + dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n"); return 0; } @@ -1001,6 +1015,15 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) return -EINVAL; + if (!adapter->rx_csum) { + dev_info(&adapter->pdev->dev, "rx csum is off, " + "cannot toggle lro\n"); + return -EINVAL; + } + + if ((data & ETH_FLAG_LRO) && (adapter->flags & QLCNIC_LRO_ENABLED)) + return 0; + if (data & ETH_FLAG_LRO) { hw_lro = QLCNIC_LRO_ENABLED; netdev->features |= NETIF_F_LRO; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index bf4077a1e824..abd7cd6db6fd 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -995,7 +995,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_config_intr_coalesce(adapter); - if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) + if (netdev->features & NETIF_F_LRO) qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); qlcnic_napi_enable(adapter); -- cgit v1.2.3 From f81380925209bc60732a57eef41ab440c056aacf Mon Sep 17 00:00:00 2001 From: Anders Kaseorg <[andersk@ksplice.com]> Date: Tue, 17 Aug 2010 11:00:03 +0000 Subject: tipc: Fix log buffer memory leak if initialization fails Moves log buffer cleanup into tipc_core_stop() so that memory allocated for the log buffer is freed if tipc_core_start() is unsuccessful. Signed-off-by: Anders Kaseorg Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/tipc/core.c b/net/tipc/core.c index 696468117985..466b861dab91 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -169,6 +169,7 @@ void tipc_core_stop(void) tipc_nametbl_stop(); tipc_ref_table_stop(); tipc_socket_stop(); + tipc_log_resize(0); } /** @@ -203,7 +204,9 @@ static int __init tipc_init(void) { int res; - tipc_log_resize(CONFIG_TIPC_LOG); + if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) + warn("Unable to create log buffer\n"); + info("Activated (version " TIPC_MOD_VER " compiled " __DATE__ " " __TIME__ ")\n"); @@ -230,7 +233,6 @@ static void __exit tipc_exit(void) tipc_core_stop_net(); tipc_core_stop(); info("Deactivated\n"); - tipc_log_resize(0); } module_init(tipc_init); -- cgit v1.2.3 From 3720d40b201fe82dce1d8a64a31bfbf49c221771 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 17 Aug 2010 11:00:04 +0000 Subject: tipc: add SO_RCVLOWAT support to stream socket receive path Add support for the SO_RCVLOWAT socket option to TIPC's stream socket type. Signed-off-by: Florian Westphal Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/socket.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 66e889ba48fd..69d0fd1f3920 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1026,9 +1026,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, struct sk_buff *buf; struct tipc_msg *msg; unsigned int sz; - int sz_to_copy; + int sz_to_copy, target, needed; int sz_copied = 0; - int needed; char __user *crs = m->msg_iov->iov_base; unsigned char *buf_crs; u32 err; @@ -1050,6 +1049,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, goto exit; } + target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); + restart: /* Look for a message in receive queue; wait if necessary */ @@ -1138,7 +1139,7 @@ restart: if ((sz_copied < buf_len) && /* didn't get all requested data */ (!skb_queue_empty(&sk->sk_receive_queue) || - (flags & MSG_WAITALL)) && /* and more is ready or required */ + (sz_copied < target)) && /* and more is ready or required */ (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ (!err)) /* and haven't reached a FIN */ goto restart; -- cgit v1.2.3 From 35997e3157eba16c6124d440bdf9272087129b2a Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:05 +0000 Subject: tipc: Provide correct error code for unsupported connect() operation Modify TIPC to return EOPNOTSUPP if an application attempts to perform a non-blocking connect() operation, which is not supported by TIPC. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 69d0fd1f3920..b89c7b1a0d09 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1380,7 +1380,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, /* For now, TIPC does not support the non-blocking form of connect() */ if (flags & O_NONBLOCK) { - res = -EWOULDBLOCK; + res = -EOPNOTSUPP; goto exit; } -- cgit v1.2.3 From f662c07058f7e6365ae65080d772f9122f6f50a9 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:06 +0000 Subject: tipc: correct problems with misleading flags returned using poll() Prevent TIPC from incorrectly setting returned flags to poll() in the following cases: - an unconnected socket no longer indicates that it is always readable - an unconnected, connecting, or listening socket no longer indicates that it is always writable Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/socket.c | 61 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b89c7b1a0d09..7b81fdd4f6d6 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -429,36 +429,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, * to handle any preventable race conditions, so TIPC will do the same ... * * TIPC sets the returned events as follows: - * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty - * or if a connection-oriented socket is does not have an active connection - * (i.e. a read operation will not block). - * b) POLLOUT is set except when a socket's connection has been terminated - * (i.e. a write operation will not block). - * c) POLLHUP is set when a socket's connection has been terminated. - * - * IMPORTANT: The fact that a read or write operation will not block does NOT - * imply that the operation will succeed! + * + * socket state flags set + * ------------ --------- + * unconnected no read flags + * no write flags + * + * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue + * no write flags + * + * connected POLLIN/POLLRDNORM if data in rx queue + * POLLOUT if port is not congested + * + * disconnecting POLLIN/POLLRDNORM/POLLHUP + * no write flags + * + * listening POLLIN if SYN in rx queue + * no write flags + * + * ready POLLIN/POLLRDNORM if data in rx queue + * [connectionless] POLLOUT (since port cannot be congested) + * + * IMPORTANT: The fact that a read or write operation is indicated does NOT + * imply that the operation will succeed, merely that it should be performed + * and will not block. */ static unsigned int poll(struct file *file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; - u32 mask; + u32 mask = 0; poll_wait(file, sk_sleep(sk), wait); - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sock->state == SS_UNCONNECTED) || - (sock->state == SS_DISCONNECTING)) - mask = (POLLRDNORM | POLLIN); - else - mask = 0; - - if (sock->state == SS_DISCONNECTING) - mask |= POLLHUP; - else - mask |= POLLOUT; + switch ((int)sock->state) { + case SS_READY: + case SS_CONNECTED: + if (!tipc_sk_port(sk)->congested) + mask |= POLLOUT; + /* fall thru' */ + case SS_CONNECTING: + case SS_LISTENING: + if (!skb_queue_empty(&sk->sk_receive_queue)) + mask |= (POLLIN | POLLRDNORM); + break; + case SS_DISCONNECTING: + mask = (POLLIN | POLLRDNORM | POLLHUP); + break; + } return mask; } -- cgit v1.2.3 From b02b69c8a403859ec72090742727e853d606a325 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:07 +0000 Subject: tipc: Check for disabled bearer when processing incoming messages Add a check to tipc_recv_msg() to ensure it discards messages arriving on a newly disabled bearer. This is needed to deal with a race condition that can arise if the bearer is in the midst of being disabled when it receives a message. Performing the check after tipc_net_lock has been taken ensures that TIPC's bearers are in a stable state while the message is being processed. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/link.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529b..9d18c9b7638b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1802,6 +1802,15 @@ static int link_recv_buf_validate(struct sk_buff *buf) return pskb_may_pull(buf, hdr_size); } +/** + * tipc_recv_msg - process TIPC messages arriving from off-node + * @head: pointer to message buffer chain + * @tb_ptr: pointer to bearer message arrived on + * + * Invoked with no locks held. Bearer pointer must point to a valid bearer + * structure (i.e. cannot be NULL), but bearer can be inactive. + */ + void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) { read_lock_bh(&tipc_net_lock); @@ -1819,6 +1828,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) head = head->next; + /* Ensure bearer is still enabled */ + + if (unlikely(!b_ptr->active)) + goto cont; + /* Ensure message is well-formed */ if (unlikely(!link_recv_buf_validate(buf))) -- cgit v1.2.3 From 7e3e5d0950559d1118dccbdff3c765fffcf04fd5 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:08 +0000 Subject: tipc: Prevent crash when broadcast link cannot send to all nodes Allow TIPC's broadcast link to continue operation when it is unable to send a message to all nodes in the cluster. Previously, the broadcast link attempted to put the broadcast pseudo-bearer into a blocked state; however, this caused a crash because the associated bearer structure is only partially initialized. Further investigation has revealed some conceptual problems with blocking the pseudo-bearer; consequently, this functionality has been disabled for the time being and the undelivered message is eventually resent by the broadcast link's existing message retransmission mechanism (if possible). Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a008c6689305..42b1737f0dcf 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -609,11 +609,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf, bcbearer->remains = bcbearer->remains_new; } - /* Unable to reach all targets */ + /* + * Unable to reach all targets (indicate success, since currently + * there isn't code in place to properly block & unblock the + * pseudo-bearer used by the broadcast link) + */ - bcbearer->bearer.publ.blocked = 1; - bcl->stats.bearer_congs++; - return 1; + return TIPC_OK; } /** -- cgit v1.2.3 From 5b1f7bdeb698547cc319c7a302a5acf585227a92 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:09 +0000 Subject: tipc: Fix premature broadcast advertisement by sending node Prevent a TIPC node from sending out a LINK_STATE message advertising a broadcast message that it is in the process of sending, but has not yet actually sent. Previously, it was possible for a link timeout to occur in between the time the broadcast link updated its "last message sent" counter and the time the broadcast message was passed to the broadcast bearer for transmission. This ensures that the code which issues the LINK_STATE message isn't informed of the new message until the broadcast bearer has had a chance to send it. Note: The "last message sent" value is stored in the "fsm_msg_count" field of the link structure used by the broadcast link. Since the broadcast link doesn't utilize the normal link FSM, this field can be re-used rather than adding a new field to the broadcast link. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 42b1737f0dcf..eefdd1a85f4f 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -143,6 +143,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf) } +static void bclink_set_last_sent(void) +{ + if (bcl->next_out) + bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1); + else + bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1); +} + +u32 tipc_bclink_get_last_sent(void) +{ + return bcl->fsm_msg_cnt; +} + /** * bclink_set_gap - set gap according to contents of current deferred pkt queue * @@ -237,8 +250,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) /* Try resolving broadcast link congestion, if necessary */ - if (unlikely(bcl->next_out)) + if (unlikely(bcl->next_out)) { tipc_link_push_queue(bcl); + bclink_set_last_sent(); + } if (unlikely(released && !list_empty(&bcl->waiting_ports))) tipc_link_wakeup_ports(bcl, 0); spin_unlock_bh(&bc_lock); @@ -394,8 +409,10 @@ int tipc_bclink_send_msg(struct sk_buff *buf) res = tipc_link_send_buf(bcl, buf); if (unlikely(res == -ELINKCONG)) buf_discard(buf); - else + else { bcl->stats.sent_info++; + bclink_set_last_sent(); + } if (bcl->out_queue_size > bcl->stats.max_queue_sz) bcl->stats.max_queue_sz = bcl->out_queue_size; @@ -529,15 +546,6 @@ receive: tipc_node_unlock(node); } -u32 tipc_bclink_get_last_sent(void) -{ - u32 last_sent = mod(bcl->next_out_no - 1); - - if (bcl->next_out) - last_sent = mod(buf_seqno(bcl->next_out) - 1); - return last_sent; -} - u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) { return (n_ptr->bclink.supported && -- cgit v1.2.3 From 0048b826afae7c47afdc47c3854707581cafe3d8 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:10 +0000 Subject: tipc: Fix bug in broadcast link transmit statistics computation Modify TIPC's broadcast link so that it counts each piece of a fragmented message individually, rather than as treating the group as a single message. This ensures that proper correlation of sent and received traffic can be done when the broadcast link statistics are displayed, and is consistent with the way fragments are counted by TIPC's unicast links. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/bcast.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index eefdd1a85f4f..b11248c2d788 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -409,10 +409,8 @@ int tipc_bclink_send_msg(struct sk_buff *buf) res = tipc_link_send_buf(bcl, buf); if (unlikely(res == -ELINKCONG)) buf_discard(buf); - else { - bcl->stats.sent_info++; + else bclink_set_last_sent(); - } if (bcl->out_queue_size > bcl->stats.max_queue_sz) bcl->stats.max_queue_sz = bcl->out_queue_size; @@ -578,6 +576,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, msg = buf_msg(buf); msg_set_non_seq(msg, 1); msg_set_mc_netid(msg, tipc_net_id); + bcl->stats.sent_info++; } /* Send buffer over bearers until all targets reached */ -- cgit v1.2.3 From 96d841b7038b8091af3530a008793f5577337d3a Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:11 +0000 Subject: tipc: Remove per-connection sequence number logic Remove validation of the per-connection sequence numbers on routable connections, since routable connections are not supported by TIPC. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/port.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/net/tipc/port.c b/net/tipc/port.c index 0737680e9266..ebcbc21d8f98 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -588,19 +588,10 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) if (!p_ptr) { err = TIPC_ERR_NO_PORT; } else if (p_ptr->publ.connected) { - if (port_peernode(p_ptr) != msg_orignode(msg)) + if ((port_peernode(p_ptr) != msg_orignode(msg)) || + (port_peerport(p_ptr) != msg_origport(msg))) { err = TIPC_ERR_NO_PORT; - if (port_peerport(p_ptr) != msg_origport(msg)) - err = TIPC_ERR_NO_PORT; - if (!err && msg_routed(msg)) { - u32 seqno = msg_transp_seqno(msg); - u32 myno = ++p_ptr->last_in_seqno; - if (seqno != myno) { - err = TIPC_ERR_NO_PORT; - abort_buf = port_build_self_abort_msg(p_ptr, err); - } - } - if (msg_type(msg) == CONN_ACK) { + } else if (msg_type(msg) == CONN_ACK) { int wakeup = tipc_port_congested(p_ptr) && p_ptr->publ.congested && p_ptr->wakeup; -- cgit v1.2.3 From 76ae0d71d839b365faa7fdca0eec85a6d1a20d95 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:12 +0000 Subject: tipc: Optimize tipc_node_has_active_links() Eliminate unnecessary checking for null node pointer and redundant check of second active link array entry. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/node.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/tipc/node.c b/net/tipc/node.c index b634942caba5..940851797615 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -237,8 +237,7 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr) int tipc_node_has_active_links(struct tipc_node *n_ptr) { - return (n_ptr && - ((n_ptr->active_links[0]) || (n_ptr->active_links[1]))); + return n_ptr->active_links[0] != NULL; } int tipc_node_has_redundant_links(struct tipc_node *n_ptr) -- cgit v1.2.3 From c2de58140a380172610b6a0f07f975abb2fbb311 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:14 +0000 Subject: tipc: Minor enhancements to name table display format Eliminate printing of dashes after name table column headers (to adhere more closely to the standard format used in tipc-config), and simplify name table display logic using array lookups rather than if-then-else logic. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/name_table.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 8ba79620db3f..d504e490fd02 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -877,7 +877,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, u32 index) { char portIdStr[27]; - char *scopeStr; + const char *scope_str[] = {"", " zone", " cluster", " node"}; struct publication *publ = sseq->zone_list; tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); @@ -893,15 +893,8 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, tipc_node(publ->node), publ->ref); tipc_printf(buf, "%-26s ", portIdStr); if (depth > 3) { - if (publ->node != tipc_own_addr) - scopeStr = ""; - else if (publ->scope == TIPC_NODE_SCOPE) - scopeStr = "node"; - else if (publ->scope == TIPC_CLUSTER_SCOPE) - scopeStr = "cluster"; - else - scopeStr = "zone"; - tipc_printf(buf, "%-10u %s", publ->key, scopeStr); + tipc_printf(buf, "%-10u %s", publ->key, + scope_str[publ->scope]); } publ = publ->zone_list_next; @@ -951,24 +944,19 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, static void nametbl_header(struct print_buf *buf, u32 depth) { - tipc_printf(buf, "Type "); - - if (depth > 1) - tipc_printf(buf, "Lower Upper "); - if (depth > 2) - tipc_printf(buf, "Port Identity "); - if (depth > 3) - tipc_printf(buf, "Publication"); - - tipc_printf(buf, "\n-----------"); - - if (depth > 1) - tipc_printf(buf, "--------------------- "); - if (depth > 2) - tipc_printf(buf, "-------------------------- "); - if (depth > 3) - tipc_printf(buf, "------------------"); - + const char *header[] = { + "Type ", + "Lower Upper ", + "Port Identity ", + "Publication Scope" + }; + + int i; + + if (depth > 4) + depth = 4; + for (i = 0; i < depth; i++) + tipc_printf(buf, header[i]); tipc_printf(buf, "\n"); } -- cgit v1.2.3 From 564e83b51a12b794e3f63a2d872398e1ee21616f Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:15 +0000 Subject: tipc: Allow connect() to wait indefinitely Cause a socket whose TIPC_CONN_TIMEOUT option is zero to wait indefinitely for a response to a connection request using connect(). Previously, specifying a timeout of 0 ms resulted in an immediate timeout, which was inconsistent with the behavior specified by Posix for a socket's receive and send timeout. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/socket.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 7b81fdd4f6d6..f7ac94de24fe 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -64,6 +64,7 @@ struct tipc_sock { struct sock sk; struct tipc_port *p; struct tipc_portid peer_name; + long conn_timeout; }; #define tipc_sk(sk) ((struct tipc_sock *)(sk)) @@ -240,9 +241,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, sock->state = state; sock_init_data(sock, sk); - sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); sk->sk_backlog_rcv = backlog_rcv; tipc_sk(sk)->p = tp_ptr; + tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); spin_unlock_bh(tp_ptr->lock); @@ -1385,6 +1386,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, struct msghdr m = {NULL,}; struct sk_buff *buf; struct tipc_msg *msg; + long timeout; int res; lock_sock(sk); @@ -1445,11 +1447,12 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ + timeout = tipc_sk(sk)->conn_timeout; release_sock(sk); res = wait_event_interruptible_timeout(*sk_sleep(sk), (!skb_queue_empty(&sk->sk_receive_queue) || (sock->state != SS_CONNECTING)), - sk->sk_rcvtimeo); + timeout ? timeout : MAX_SCHEDULE_TIMEOUT); lock_sock(sk); if (res > 0) { @@ -1712,7 +1715,7 @@ static int setsockopt(struct socket *sock, res = tipc_set_portunreturnable(tport->ref, value); break; case TIPC_CONN_TIMEOUT: - sk->sk_rcvtimeo = msecs_to_jiffies(value); + tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); /* no need to set "res", since already 0 at this point */ break; default: @@ -1767,7 +1770,7 @@ static int getsockopt(struct socket *sock, res = tipc_portunreturnable(tport->ref, &value); break; case TIPC_CONN_TIMEOUT: - value = jiffies_to_msecs(sk->sk_rcvtimeo); + value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); /* no need to set "res", since already 0 at this point */ break; case TIPC_NODE_RECVQ_DEPTH: -- cgit v1.2.3 From 5a68d5ee000bb784c4856391b4861739c8bbd341 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 17 Aug 2010 11:00:16 +0000 Subject: tipc: Prevent missing name table entries when link flip-flops rapidly Ensure that TIPC does not re-establish communication with a neighboring node until it has finished updating all data structures containing information about that node to reflect the earlier loss of contact. Previously, it was possible for TIPC to perform its purge of name table entries relating to the node once contact had already been re-established, resulting in the unwanted removal of valid name table entries. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/discover.c | 8 ++++++++ net/tipc/link.c | 11 ++++++++++- net/tipc/node.c | 19 +++++++++++++++++++ net/tipc/node.h | 2 ++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/net/tipc/discover.c b/net/tipc/discover.c index fc1fcf5e6b53..f28d1ae93125 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -203,6 +203,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) return; } spin_lock_bh(&n_ptr->lock); + + /* Don't talk to neighbor during cleanup after last session */ + + if (n_ptr->cleanup_required) { + spin_unlock_bh(&n_ptr->lock); + return; + } + link = n_ptr->links[b_ptr->identity]; if (!link) { dbg("creating link\n"); diff --git a/net/tipc/link.c b/net/tipc/link.c index 9d18c9b7638b..a6a3102bb4d6 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1869,13 +1869,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) goto cont; } - /* Locate unicast link endpoint that should handle message */ + /* Locate neighboring node that sent message */ n_ptr = tipc_node_find(msg_prevnode(msg)); if (unlikely(!n_ptr)) goto cont; tipc_node_lock(n_ptr); + /* Don't talk to neighbor during cleanup after last session */ + + if (n_ptr->cleanup_required) { + tipc_node_unlock(n_ptr); + goto cont; + } + + /* Locate unicast link endpoint that should handle message */ + l_ptr = n_ptr->links[b_ptr->identity]; if (unlikely(!l_ptr)) { tipc_node_unlock(n_ptr); diff --git a/net/tipc/node.c b/net/tipc/node.c index 940851797615..b702c7bf580f 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -383,6 +383,20 @@ static void node_established_contact(struct tipc_node *n_ptr) tipc_highest_allowed_slave); } +static void node_cleanup_finished(unsigned long node_addr) +{ + struct tipc_node *n_ptr; + + read_lock_bh(&tipc_net_lock); + n_ptr = tipc_node_find(node_addr); + if (n_ptr) { + tipc_node_lock(n_ptr); + n_ptr->cleanup_required = 0; + tipc_node_unlock(n_ptr); + } + read_unlock_bh(&tipc_net_lock); +} + static void node_lost_contact(struct tipc_node *n_ptr) { struct cluster *c_ptr; @@ -457,6 +471,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) tipc_k_signal((Handler)ns->handle_node_down, (unsigned long)ns->usr_handle); } + + /* Prevent re-contact with node until all cleanup is done */ + + n_ptr->cleanup_required = 1; + tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); } /** diff --git a/net/tipc/node.h b/net/tipc/node.h index 6f990da5d143..45f3db3a595d 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -52,6 +52,7 @@ * @active_links: pointers to active links to node * @links: pointers to all links to node * @working_links: number of working links to node (both active and standby) + * @cleanup_required: non-zero if cleaning up after a prior loss of contact * @link_cnt: number of links to node * @permit_changeover: non-zero if node has redundant links to this system * @routers: bitmap (used for multicluster communication) @@ -78,6 +79,7 @@ struct tipc_node { struct link *links[MAX_BEARERS]; int link_cnt; int working_links; + int cleanup_required; int permit_changeover; u32 routers[512/32]; int last_router; -- cgit v1.2.3 From baeb2ffab4e67bb9174e6166e070a9a8ec94b0f6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 11 Aug 2010 07:02:48 +0000 Subject: drivers/net: Convert unbounded kzalloc calls to kcalloc These changes may be slightly safer in some instances. There are other kzalloc calls with a multiply, but those calls are typically "small fixed #" * sizeof(some pointer)" and those are not converted. Signed-off-by: Joe Perches Acked-by: Gertjan van Wingerde Acked-by: Luciano Coelho Signed-off-by: David S. Miller --- drivers/net/cnic.c | 2 +- drivers/net/ehea/ehea_main.c | 4 ++-- drivers/net/mlx4/alloc.c | 2 +- drivers/net/mlx4/en_rx.c | 2 +- drivers/net/mlx4/profile.c | 2 +- drivers/net/myri10ge/myri10ge.c | 4 ++-- drivers/net/niu.c | 4 ++-- drivers/net/vxge/vxge-main.c | 10 +++++----- drivers/net/wireless/airo.c | 5 ++--- drivers/net/wireless/b43/phy_n.c | 2 +- drivers/net/wireless/ipw2x00/ipw2100.c | 6 +++--- drivers/net/wireless/ipw2x00/ipw2200.c | 12 ++++++------ drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2x00debug.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 2 +- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- drivers/net/wireless/wl12xx/wl1271_scan.c | 2 +- 21 files changed, 37 insertions(+), 38 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 09610323a948..2ab6a7c4ffc1 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1022,7 +1022,7 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev) if (blks > cp->ethdev->ctx_tbl_len) return -ENOMEM; - cp->ctx_arr = kzalloc(blks * sizeof(struct cnic_ctx), GFP_KERNEL); + cp->ctx_arr = kcalloc(blks, sizeof(struct cnic_ctx), GFP_KERNEL); if (cp->ctx_arr == NULL) return -ENOMEM; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 897719b49f96..0f9b27b93a71 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -180,7 +180,7 @@ static void ehea_update_firmware_handles(void) num_portres * EHEA_NUM_PORTRES_FW_HANDLES; if (num_fw_handles) { - arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL); + arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL); if (!arr) goto out; /* Keep the existing array */ } else @@ -265,7 +265,7 @@ static void ehea_update_bcmc_registrations(void) } if (num_registrations) { - arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC); + arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC); if (!arr) goto out; /* Keep the existing array */ } else diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 8c8515619b8e..537997f9443e 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c @@ -188,7 +188,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; buf->npages = buf->nbufs; buf->page_shift = PAGE_SHIFT; - buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list, + buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list), GFP_KERNEL); if (!buf->page_list) return -ENOMEM; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 8e2fcb7103c3..efc3fad468db 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -322,7 +322,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY; ring->lro.max_desc = mdev->profile.num_lro; ring->lro.max_aggr = MAX_SKB_FRAGS; - ring->lro.lro_arr = kzalloc(mdev->profile.num_lro * + ring->lro.lro_arr = kcalloc(mdev->profile.num_lro, sizeof(struct net_lro_desc), GFP_KERNEL); if (!ring->lro.lro_arr) { diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c index 5caf0115fa5b..e749f82865fe 100644 --- a/drivers/net/mlx4/profile.c +++ b/drivers/net/mlx4/profile.c @@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, struct mlx4_resource tmp; int i, j; - profile = kzalloc(MLX4_RES_NUM * sizeof *profile, GFP_KERNEL); + profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL); if (!profile) return -ENOMEM; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index fb2c0927d3cc..24ab8a43c777 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3753,8 +3753,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) * slices. We give up on MSI-X if we can only get a single * vector. */ - mgp->msix_vectors = kzalloc(mgp->num_slices * - sizeof(*mgp->msix_vectors), GFP_KERNEL); + mgp->msix_vectors = kcalloc(mgp->num_slices, sizeof(*mgp->msix_vectors), + GFP_KERNEL); if (mgp->msix_vectors == NULL) goto disable_msix; for (i = 0; i < mgp->num_slices; i++) { diff --git a/drivers/net/niu.c b/drivers/net/niu.c index bc695d53cdcc..b4cc61f1fc59 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -4504,7 +4504,7 @@ static int niu_alloc_channels(struct niu *np) np->dev->real_num_tx_queues = np->num_tx_rings; - np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info), + np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), GFP_KERNEL); err = -ENOMEM; if (!np->rx_rings) @@ -4538,7 +4538,7 @@ static int niu_alloc_channels(struct niu *np) return err; } - np->tx_rings = kzalloc(np->num_tx_rings * sizeof(struct tx_ring_info), + np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), GFP_KERNEL); err = -ENOMEM; if (!np->tx_rings) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index c7c5605b3728..f5334b287fdb 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2159,8 +2159,8 @@ start: /* Alarm MSIX Vectors count */ vdev->intr_cnt++; - vdev->entries = kzalloc(vdev->intr_cnt * sizeof(struct msix_entry), - GFP_KERNEL); + vdev->entries = kcalloc(vdev->intr_cnt, sizeof(struct msix_entry), + GFP_KERNEL); if (!vdev->entries) { vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", @@ -2169,9 +2169,9 @@ start: goto alloc_entries_failed; } - vdev->vxge_entries = - kzalloc(vdev->intr_cnt * sizeof(struct vxge_msix_entry), - GFP_KERNEL); + vdev->vxge_entries = kcalloc(vdev->intr_cnt, + sizeof(struct vxge_msix_entry), + GFP_KERNEL); if (!vdev->vxge_entries) { vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", VXGE_DRIVER_NAME); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1d05445d4ba3..7d26506957d7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2723,9 +2723,8 @@ static int airo_networks_allocate(struct airo_info *ai) if (ai->networks) return 0; - ai->networks = - kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement), - GFP_KERNEL); + ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement), + GFP_KERNEL); if (!ai->networks) { airo_print_warn("", "Out of memory allocating beacons"); return -ENOMEM; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 5a725703770c..e288c559481d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1182,7 +1182,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, len = bw << 1; } - samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); + samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL); if (!samples) { b43err(dev->wl, "allocation for samples generation failed\n"); return 0; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 1189dbb6e2a6..0c67b172d4c6 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1921,9 +1921,9 @@ static int ipw2100_net_init(struct net_device *dev) bg_band->band = IEEE80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = - kzalloc(geo->bg_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + bg_band->channels = kcalloc(geo->bg_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); if (!bg_band->channels) { ipw2100_down(priv); return -ENOMEM; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index cb2552a6777c..0f2508384c75 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11467,9 +11467,9 @@ static int ipw_net_init(struct net_device *dev) bg_band->band = IEEE80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = - kzalloc(geo->bg_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + bg_band->channels = kcalloc(geo->bg_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); /* translate geo->bg to bg_band.channels */ for (i = 0; i < geo->bg_channels; i++) { bg_band->channels[i].band = IEEE80211_BAND_2GHZ; @@ -11502,9 +11502,9 @@ static int ipw_net_init(struct net_device *dev) a_band->band = IEEE80211_BAND_5GHZ; a_band->n_channels = geo->a_channels; - a_band->channels = - kzalloc(geo->a_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + a_band->channels = kcalloc(geo->a_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); /* translate geo->bg to a_band.channels */ for (i = 0; i < geo->a_channels; i++) { a_band->channels[i].band = IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5063e01410e5..8e3fbdf48889 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1481,7 +1481,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c2a555d5376b..1d174e42f11e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1795,7 +1795,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f48263..8ddaae44d7fb 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1698,7 +1698,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b66e0fd8f0fa..8c00fbda8664 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2865,7 +2865,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b0498e7e7aae..2d018ceffc54 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -333,7 +333,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, if (*offset) return 0; - data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); + data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a3401d301058..9c609be95083 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -755,7 +755,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, * Allocate all queue entries. */ entry_size = sizeof(*entries) + qdesc->priv_size; - entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); + entries = kcalloc(queue->limit, entry_size, GFP_KERNEL); if (!entries) return -ENOMEM; @@ -891,7 +891,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; - queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); + queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); if (!queue) { ERROR(rt2x00dev, "Queue allocation failed.\n"); return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e539c6cb636f..f226582dbc87 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2654,7 +2654,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9de18fd410..99985a218653 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2084,7 +2084,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index fec43eed8c55..30dc1000f563 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -248,7 +248,7 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, wl->scan.req = req; - wl->scan.scanned_ch = kzalloc(req->n_channels * + wl->scan.scanned_ch = kcalloc(req->n_channels, sizeof(*wl->scan.scanned_ch), GFP_KERNEL); wl1271_scan_stm(wl); -- cgit v1.2.3 From be265e9bae343d803145bbe910a8b00bc4bea3cc Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 12 Aug 2010 05:03:03 +0000 Subject: s2io: remove unused code usr_addrs is never referenced outside the initial struct population during open, thus making it unnecessary. Remove it, the code that references it, and the struct that it is the only user of. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 2 -- drivers/net/s2io.h | 8 -------- 2 files changed, 10 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 18bc5b718bbb..0124f1201d97 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5124,8 +5124,6 @@ static void s2io_set_multicast(struct net_device *dev) /* Create the new Rx filter list and update the same in H/W. */ i = 0; netdev_for_each_mc_addr(ha, dev) { - memcpy(sp->usr_addrs[i].addr, ha->addr, - ETH_ALEN); mac_addr = 0; for (j = 0; j < ETH_ALEN; j++) { mac_addr |= ha->addr[j]; diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 0af033533905..924f618f2397 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -816,12 +816,6 @@ struct mac_info { struct stat_block *stats_info; /* Logical address of the stat block */ }; -/* structure representing the user defined MAC addresses */ -struct usr_addr { - char addr[ETH_ALEN]; - int usage_cnt; -}; - /* Default Tunable parameters of the NIC. */ #define DEFAULT_FIFO_0_LEN 4096 #define DEFAULT_FIFO_1_7_LEN 512 @@ -894,9 +888,7 @@ struct s2io_nic { #define ALL_MULTI 2 #define MAX_ADDRS_SUPPORTED 64 - u16 usr_addr_count; u16 mc_addr_count; - struct usr_addr usr_addrs[256]; u16 m_cast_flg; u16 all_multi_pos; -- cgit v1.2.3 From 666be4298bd8f9508b32833b17a686dde630f2a5 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Thu, 12 Aug 2010 05:03:04 +0000 Subject: s2io: Update driver version Update s2io driver's version to reflect the series of patches. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 0124f1201d97..5f062ddfd5c5 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -90,7 +90,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.26" +#define DRV_VERSION "2.0.26.27" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; -- cgit v1.2.3 From 00093fab980d0a8950a64bdf9e346d0497b9a7e4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 14 Aug 2010 11:09:49 +0000 Subject: net/sched: remove unneeded NULL check There is no need to check "s". nla_data() doesn't return NULL. Also we already dereferenced "s" at this point so it would have oopsed ealier if it were NULL. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/sched/sch_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 408eea7086aa..6fb3d41c0e41 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -360,7 +360,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt) tsize = nla_len(tb[TCA_STAB_DATA]) / sizeof(u16); } - if (!s || tsize != s->tsize || (!tab && tsize > 0)) + if (tsize != s->tsize || (!tab && tsize > 0)) return ERR_PTR(-EINVAL); spin_lock(&qdisc_stab_lock); -- cgit v1.2.3 From 636b8116d4e116eca1ac978f546b16fadfc15a6c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 12 Aug 2010 12:22:51 +0000 Subject: drivers/net/pcmcia: Use pr_ and netdev_ On Mon, 2010-08-09 at 17:34 +0200, Dominik Brodowski wrote: > look good from a PCMCIA point of view, therefore: > Signed-off-by: Dominik Brodowski If PCMCIA is still being looked after, then here's another for you, maybe for 2.6.37. Use the more descriptive logging message styles. There are whitespace/indentation errors in the original sources that these changes do not modify, so checkpatch errors were cheerfully ignored. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/pcmcia/3c574_cs.c | 73 +++++++++-------- drivers/net/pcmcia/3c589_cs.c | 13 ++-- drivers/net/pcmcia/axnet_cs.c | 164 +++++++++++++++++++++------------------ drivers/net/pcmcia/com20020_cs.c | 32 ++++---- drivers/net/pcmcia/fmvj18x_cs.c | 60 +++++++------- drivers/net/pcmcia/ibmtr_cs.c | 13 ++-- drivers/net/pcmcia/nmclan_cs.c | 54 +++++++------ drivers/net/pcmcia/smc91c92_cs.c | 99 +++++++++++------------ drivers/net/pcmcia/xirc2ps_cs.c | 104 +++++++++++-------------- 9 files changed, 298 insertions(+), 314 deletions(-) diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 9a1840b67e78..9b319be7f1d2 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -69,6 +69,8 @@ earlier 3Com products. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -373,8 +375,8 @@ static int tc574_config(struct pcmcia_device *link) for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i + 10)); if (phys_addr[0] == htons(0x6060)) { - printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx" - "-0x%03lx\n", dev->base_addr, dev->base_addr+15); + pr_notice("IO port conflict at 0x%03lx-0x%03lx\n", + dev->base_addr, dev->base_addr+15); goto failed; } } @@ -388,7 +390,7 @@ static int tc574_config(struct pcmcia_device *link) outw(2<<11, ioaddr + RunnerRdCtrl); mcr = inb(ioaddr + 2); outw(0<<11, ioaddr + RunnerRdCtrl); - printk(KERN_INFO " ASIC rev %d,", mcr>>3); + pr_info(" ASIC rev %d,", mcr>>3); EL3WINDOW(3); config = inl(ioaddr + Wn3_Config); lp->default_media = (config & Xcvr) >> Xcvr_shift; @@ -425,7 +427,7 @@ static int tc574_config(struct pcmcia_device *link) } } if (phy > 32) { - printk(KERN_NOTICE " No MII transceivers found!\n"); + pr_notice(" No MII transceivers found!\n"); goto failed; } i = mdio_read(ioaddr, lp->phys, 16) | 0x40; @@ -441,18 +443,16 @@ static int tc574_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " - "hw_addr %pM.\n", - dev->name, cardname, dev->base_addr, dev->irq, - dev->dev_addr); - printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", - 8 << config & Ram_size, - ram_split[(config & Ram_split) >> Ram_split_shift], - config & Autoselect ? "autoselect " : ""); + netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n", + cardname, dev->base_addr, dev->irq, dev->dev_addr); + netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n", + 8 << config & Ram_size, + ram_split[(config & Ram_split) >> Ram_split_shift], + config & Autoselect ? "autoselect " : ""); return 0; @@ -499,14 +499,14 @@ static void dump_status(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; EL3WINDOW(1); - printk(KERN_INFO " irq status %04x, rx status %04x, tx status " - "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS), - inw(ioaddr+RxStatus), inb(ioaddr+TxStatus), - inw(ioaddr+TxFree)); + netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x, tx free %04x\n", + inw(ioaddr+EL3_STATUS), + inw(ioaddr+RxStatus), inb(ioaddr+TxStatus), + inw(ioaddr+TxFree)); EL3WINDOW(4); - printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x" - " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06), - inw(ioaddr+0x08), inw(ioaddr+0x0a)); + netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n", + inw(ioaddr+0x04), inw(ioaddr+0x06), + inw(ioaddr+0x08), inw(ioaddr+0x0a)); EL3WINDOW(1); } @@ -520,7 +520,7 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd) while (--i > 0) if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break; if (i == 0) - printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd); + netdev_notice(dev, "command 0x%04x did not complete!\n", cmd); } /* Read a word from the EEPROM using the regular EEPROM access register. @@ -722,7 +722,7 @@ static void el3_tx_timeout(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name); + netdev_notice(dev, "Transmit timed out!\n"); dump_status(dev); dev->stats.tx_errors++; dev->trans_start = jiffies; /* prevent tx timeout */ @@ -845,8 +845,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) EL3WINDOW(4); fifo_diag = inw(ioaddr + Wn4_FIFODiag); EL3WINDOW(1); - printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic" - " register %04x.\n", dev->name, fifo_diag); + netdev_notice(dev, "adapter failure, FIFO diagnostic register %04x\n", + fifo_diag); if (fifo_diag & 0x0400) { /* Tx overrun */ tc574_wait_for_completion(dev, TxReset); @@ -900,7 +900,7 @@ static void media_check(unsigned long arg) this, we can limp along even if the interrupt is blocked */ if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) { if (!lp->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); local_irq_save(flags); el3_interrupt(dev->irq, dev); @@ -923,23 +923,21 @@ static void media_check(unsigned long arg) if (media != lp->media_status) { if ((media ^ lp->media_status) & 0x0004) - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (lp->media_status & 0x0004) ? "lost" : "found"); + netdev_info(dev, "%s link beat\n", + (lp->media_status & 0x0004) ? "lost" : "found"); if ((media ^ lp->media_status) & 0x0020) { lp->partner = 0; if (lp->media_status & 0x0020) { - printk(KERN_INFO "%s: autonegotiation restarted\n", - dev->name); + netdev_info(dev, "autonegotiation restarted\n"); } else if (partner) { partner &= lp->advertising; lp->partner = partner; - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((partner & 0x0180) ? "100" : "10"), - ((partner & 0x0140) ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: " + "%dbaseT-%cD selected\n", + (partner & 0x0180) ? 100 : 10, + (partner & 0x0140) ? 'F' : 'H'); } else { - printk(KERN_INFO "%s: link partner did not autonegotiate\n", - dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); } EL3WINDOW(3); @@ -949,10 +947,9 @@ static void media_check(unsigned long arg) } if (media & 0x0010) - printk(KERN_INFO "%s: remote fault detected\n", - dev->name); + netdev_info(dev, "remote fault detected\n"); if (media & 0x0002) - printk(KERN_INFO "%s: jabber detected\n", dev->name); + netdev_info(dev, "jabber detected\n"); lp->media_status = media; } spin_unlock_irqrestore(&lp->window_lock, flags); diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 61f9cf2100ff..1c534f392474 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -19,6 +19,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "3c589_cs" #define DRV_VERSION "1.162-ac" @@ -273,8 +275,7 @@ static int tc589_config(struct pcmcia_device *link) phys_addr = (__be16 *)dev->dev_addr; /* Is this a 3c562? */ if (link->manf_id != MANFID_3COM) - printk(KERN_INFO "3c589_cs: hmmm, is this really a " - "3Com card??\n"); + dev_info(&link->dev, "hmmm, is this really a 3Com card??\n"); multi = (link->card_id == PRODID_3COM_3C562); link->io_lines = 16; @@ -315,8 +316,8 @@ static int tc589_config(struct pcmcia_device *link) for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); if (phys_addr[0] == htons(0x6060)) { - printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx" - "-0x%03lx\n", dev->base_addr, dev->base_addr+15); + dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n", + dev->base_addr, dev->base_addr+15); goto failed; } } @@ -330,12 +331,12 @@ static int tc589_config(struct pcmcia_device *link) if ((if_port >= 0) && (if_port <= 3)) dev->if_port = if_port; else - printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); + dev_err(&link->dev, "invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); + dev_err(&link->dev, "register_netdev() failed\n"); goto failed; } diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index a6e37b29e3bf..e97f1519a15f 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -24,6 +24,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -344,8 +346,8 @@ static int axnet_config(struct pcmcia_device *link) dev->base_addr = link->resource[0]->start; if (!get_prom(link)) { - printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n"); - printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n"); + pr_notice("this is not an AX88190 card!\n"); + pr_notice("use pcnet_cs instead.\n"); goto failed; } @@ -390,19 +392,18 @@ static int axnet_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, ((info->flags & IS_AX88790) ? 7 : 1), - dev->base_addr, dev->irq, - dev->dev_addr); + netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n", + ((info->flags & IS_AX88790) ? 7 : 1), + dev->base_addr, dev->irq, dev->dev_addr); if (info->phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j); + netdev_dbg(dev, " MII transceiver at index %d, status %x\n", + info->phy_id, j); } else { - printk(KERN_NOTICE " No MII transceivers found!\n"); + netdev_notice(dev, " No MII transceivers found!\n"); } return 0; @@ -582,8 +583,7 @@ static void axnet_reset_8390(struct net_device *dev) outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ if (i == 100) - printk(KERN_ERR "%s: axnet_reset_8390() did not complete.\n", - dev->name); + netdev_err(dev, "axnet_reset_8390() did not complete\n"); } /* axnet_reset_8390 */ @@ -610,7 +610,7 @@ static void ei_watchdog(u_long arg) this, we can limp along even if the interrupt is blocked */ if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); ei_irq_wrapper(dev->irq, dev); info->fast_poll = HZ; } @@ -625,7 +625,7 @@ static void ei_watchdog(u_long arg) goto reschedule; link = mdio_read(mii_addr, info->phy_id, 1); if (!link || (link == 0xffff)) { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); info->phy_id = -1; goto reschedule; } @@ -633,18 +633,14 @@ static void ei_watchdog(u_long arg) link &= 0x0004; if (link != info->link_status) { u_short p = mdio_read(mii_addr, info->phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); if (link) { info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00; if (p) - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((p & 0x0180) ? "100" : "10"), - ((p & 0x0140) ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n", + (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H'); else - printk(KERN_INFO "%s: link partner did not autonegotiate\n", - dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); AX88190_init(dev, 1); } info->link_status = link; @@ -842,9 +838,6 @@ module_exit(exit_axnet_cs); */ -static const char version_8390[] = KERN_INFO \ - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n"; - #include #include #include @@ -991,9 +984,11 @@ static void axnet_tx_timeout(struct net_device *dev) isr = inb(e8390_base+EN0_ISR); spin_unlock_irqrestore(&ei_local->page_lock, flags); - printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", - dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); + netdev_printk(KERN_DEBUG, dev, + "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", + (txsr & ENTSR_ABT) ? "excess collisions." : + (isr) ? "lost interrupt?" : "cable problem?", + txsr, isr, tickssofar); if (!isr && !dev->stats.tx_packets) { @@ -1063,22 +1058,28 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, output_page = ei_local->tx_start_page; ei_local->tx1 = send_length; if (ei_debug && ei_local->tx2 > 0) - printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing); + netdev_printk(KERN_DEBUG, dev, + "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", + ei_local->tx2, ei_local->lasttx, + ei_local->txing); } else if (ei_local->tx2 == 0) { output_page = ei_local->tx_start_page + TX_PAGES/2; ei_local->tx2 = send_length; if (ei_debug && ei_local->tx1 > 0) - printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing); + netdev_printk(KERN_DEBUG, dev, + "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", + ei_local->tx1, ei_local->lasttx, + ei_local->txing); } else { /* We should never get here. */ if (ei_debug) - printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n", - dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx); + netdev_printk(KERN_DEBUG, dev, + "No Tx buffers free! tx1=%d tx2=%d last=%d\n", + ei_local->tx1, ei_local->tx2, + ei_local->lasttx); ei_local->irqlock = 0; netif_stop_queue(dev); outb_p(ENISR_ALL, e8390_base + EN0_IMR); @@ -1166,23 +1167,26 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) spin_lock_irqsave(&ei_local->page_lock, flags); - if (ei_local->irqlock) - { + if (ei_local->irqlock) { #if 1 /* This might just be an interrupt for a PCI device sharing this line */ + const char *msg; /* The "irqlock" check is only for testing. */ - printk(ei_local->irqlock - ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n" - : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n", - dev->name, inb_p(e8390_base + EN0_ISR), - inb_p(e8390_base + EN0_IMR)); + if (ei_local->irqlock) + msg = "Interrupted while interrupts are masked!"; + else + msg = "Reentering the interrupt handler!"; + netdev_info(dev, "%s, isr=%#2x imr=%#2x\n", + msg, + inb_p(e8390_base + EN0_ISR), + inb_p(e8390_base + EN0_IMR)); #endif spin_unlock_irqrestore(&ei_local->page_lock, flags); return IRQ_NONE; } if (ei_debug > 3) - printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name, - inb_p(e8390_base + EN0_ISR)); + netdev_printk(KERN_DEBUG, dev, "interrupt(isr=%#2.2x)\n", + inb_p(e8390_base + EN0_ISR)); outb_p(0x00, e8390_base + EN0_ISR); ei_local->irqlock = 1; @@ -1193,7 +1197,8 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) { if (!netif_running(dev) || (interrupts == 0xff)) { if (ei_debug > 1) - printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name); + netdev_warn(dev, + "interrupt from stopped card\n"); outb_p(interrupts, e8390_base + EN0_ISR); interrupts = 0; break; @@ -1236,11 +1241,12 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) { /* 0xFF is valid for a card removal */ if(interrupts!=0xFF) - printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n", - dev->name, interrupts); + netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", + interrupts); outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ } else { - printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts); + netdev_warn(dev, "unknown interrupt %#2x\n", + interrupts); outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ } } @@ -1274,18 +1280,19 @@ static void ei_tx_err(struct net_device *dev) unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); #ifdef VERBOSE_ERROR_DUMP - printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr); + netdev_printk(KERN_DEBUG, dev, + "transmitter error (%#2x):", txsr); if (txsr & ENTSR_ABT) - printk("excess-collisions "); + pr_cont(" excess-collisions"); if (txsr & ENTSR_ND) - printk("non-deferral "); + pr_cont(" non-deferral"); if (txsr & ENTSR_CRS) - printk("lost-carrier "); + pr_cont(" lost-carrier"); if (txsr & ENTSR_FU) - printk("FIFO-underrun "); + pr_cont(" FIFO-underrun"); if (txsr & ENTSR_CDH) - printk("lost-heartbeat "); - printk("\n"); + pr_cont(" lost-heartbeat"); + pr_cont("\n"); #endif if (tx_was_aborted) @@ -1322,8 +1329,9 @@ static void ei_tx_intr(struct net_device *dev) if (ei_local->tx1 < 0) { if (ei_local->lasttx != 1 && ei_local->lasttx != -1) - printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx1); + netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n", + ei_local->name, ei_local->lasttx, + ei_local->tx1); ei_local->tx1 = 0; if (ei_local->tx2 > 0) { @@ -1338,8 +1346,9 @@ static void ei_tx_intr(struct net_device *dev) else if (ei_local->tx2 < 0) { if (ei_local->lasttx != 2 && ei_local->lasttx != -2) - printk("%s: bogus last_tx_buffer %d, tx2=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx2); + netdev_info(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n", + ei_local->name, ei_local->lasttx, + ei_local->tx2); ei_local->tx2 = 0; if (ei_local->tx1 > 0) { @@ -1352,8 +1361,9 @@ static void ei_tx_intr(struct net_device *dev) else ei_local->lasttx = 10, ei_local->txing = 0; } -// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n", -// dev->name, ei_local->lasttx); +// else +// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", +// ei_local->lasttx); /* Minimize Tx latency: update the statistics after we restart TXing. */ if (status & ENTSR_COL) @@ -1416,8 +1426,8 @@ static void ei_receive(struct net_device *dev) is that some clones crash in roughly the same way. */ if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF)) - printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n", - dev->name, this_frame, ei_local->current_page); + netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", + this_frame, ei_local->current_page); if (this_frame == rxing_page) /* Read all the frames? */ break; /* Done for now */ @@ -1433,9 +1443,10 @@ static void ei_receive(struct net_device *dev) if (pkt_len < 60 || pkt_len > 1518) { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n", - dev->name, rx_frame.count, rx_frame.status, - rx_frame.next); + netdev_printk(KERN_DEBUG, dev, + "bogus packet size: %d, status=%#2x nxpg=%#2x\n", + rx_frame.count, rx_frame.status, + rx_frame.next); dev->stats.rx_errors++; dev->stats.rx_length_errors++; } @@ -1447,8 +1458,9 @@ static void ei_receive(struct net_device *dev) if (skb == NULL) { if (ei_debug > 1) - printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n", - dev->name, pkt_len); + netdev_printk(KERN_DEBUG, dev, + "Couldn't allocate a sk_buff of size %d\n", + pkt_len); dev->stats.rx_dropped++; break; } @@ -1468,9 +1480,10 @@ static void ei_receive(struct net_device *dev) else { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", - dev->name, rx_frame.status, rx_frame.next, - rx_frame.count); + netdev_printk(KERN_DEBUG, dev, + "bogus packet: status=%#2x nxpg=%#2x size=%d\n", + rx_frame.status, rx_frame.next, + rx_frame.count); dev->stats.rx_errors++; /* NB: The NIC counts CRC, frame and missed errors. */ if (pkt_stat & ENRSR_FO) @@ -1480,8 +1493,8 @@ static void ei_receive(struct net_device *dev) /* This _should_ never happen: it's here for avoiding bad clones. */ if (next_frame >= ei_local->stop_page) { - printk("%s: next frame inconsistency, %#2x\n", dev->name, - next_frame); + netdev_info(dev, "next frame inconsistency, %#2x\n", + next_frame); next_frame = ei_local->rx_start_page; } ei_local->current_page = next_frame; @@ -1516,7 +1529,7 @@ static void ei_rx_overrun(struct net_device *dev) outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); if (ei_debug > 1) - printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name); + netdev_printk(KERN_DEBUG, dev, "Receiver overrun\n"); dev->stats.rx_over_errors++; /* @@ -1713,7 +1726,7 @@ static void AX88190_init(struct net_device *dev, int startp) { outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) - printk(KERN_ERR "Hw. address read/write mismap %d\n",i); + netdev_err(dev, "Hw. address read/write mismap %d\n", i); } outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); @@ -1750,8 +1763,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, if (inb_p(e8390_base) & E8390_TRANS) { - printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n", - dev->name); + netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); return; } outb_p(length & 0xff, e8390_base + EN0_TCNTLO); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 3c400cfa82ae..f065c35cd4b7 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -52,23 +52,23 @@ #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n" -#ifdef DEBUG static void regdump(struct net_device *dev) { +#ifdef DEBUG int ioaddr = dev->base_addr; int count; - printk("com20020 register dump:\n"); + netdev_dbg(dev, "register dump:\n"); for (count = ioaddr; count < ioaddr + 16; count++) { if (!(count % 16)) - printk("\n%04X: ", count); - printk("%02X ", inb(count)); + pr_cont("%04X:", count); + pr_cont(" %02X", inb(count)); } - printk("\n"); + pr_cont("\n"); - printk("buffer0 dump:\n"); + netdev_dbg(dev, "buffer0 dump:\n"); /* set up the address register */ count = 0; outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI); @@ -77,19 +77,15 @@ static void regdump(struct net_device *dev) for (count = 0; count < 256+32; count++) { if (!(count % 16)) - printk("\n%04X: ", count); + pr_cont("%04X:", count); /* copy the data */ - printk("%02X ", inb(_MEMDATA)); + pr_cont(" %02X", inb(_MEMDATA)); } - printk("\n"); + pr_cont("\n"); +#endif } -#else - -static inline void regdump(struct net_device *dev) { } - -#endif /*====================================================================*/ @@ -301,13 +297,13 @@ static int com20020_config(struct pcmcia_device *link) i = com20020_found(dev, 0); /* calls register_netdev */ if (i != 0) { - dev_printk(KERN_NOTICE, &link->dev, - "com20020_cs: com20020_found() failed\n"); + dev_notice(&link->dev, + "com20020_found() failed\n"); goto failed; } - dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", - dev->name, dev->base_addr, dev->irq); + netdev_dbg(dev, "port %#3lx, irq %d\n", + dev->base_addr, dev->irq); return 0; failed: diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 98fffb03ecd7..8f26d548d1bb 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -28,6 +28,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "fmvj18x_cs" #define DRV_VERSION "2.9" @@ -291,7 +293,7 @@ static int mfc_try_io_port(struct pcmcia_device *link) link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; if (link->resource[1]->start == 0) { link->resource[1]->end = 0; - printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); + pr_notice("out of resource for serial\n"); } ret = pcmcia_request_io(link); if (ret == 0) @@ -503,7 +505,7 @@ static int fmvj18x_config(struct pcmcia_device *link) case XXX10304: /* Read MACID from Buggy CIS */ if (fmvj18x_get_hwinfo(link, buggybuf) == -1) { - printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n"); + pr_notice("unable to read hardware net address\n"); goto failed; } for (i = 0 ; i < 6; i++) { @@ -524,15 +526,14 @@ static int fmvj18x_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } /* print current configuration */ - printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", - dev->base_addr, dev->irq, dev->dev_addr); + netdev_info(dev, "%s, sram %s, port %#3lx, irq %d, hw_addr %pM\n", + card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", + dev->base_addr, dev->irq, dev->dev_addr); return 0; @@ -606,7 +607,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) lp->base = ioremap(req.Base, req.Size); if (lp->base == NULL) { - printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n"); + netdev_notice(dev, "ioremap failed\n"); return -1; } @@ -800,17 +801,16 @@ static void fjn_tx_timeout(struct net_device *dev) struct local_info_t *lp = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n", - dev->name, htons(inw(ioaddr + TX_STATUS)), - inb(ioaddr + TX_STATUS) & F_TMT_RDY - ? "IRQ conflict" : "network cable problem"); - printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x " - "%04x %04x %04x %04x %04x.\n", - dev->name, htons(inw(ioaddr + 0)), - htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)), - htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)), - htons(inw(ioaddr +10)), htons(inw(ioaddr +12)), - htons(inw(ioaddr +14))); + netdev_notice(dev, "transmit timed out with status %04x, %s?\n", + htons(inw(ioaddr + TX_STATUS)), + inb(ioaddr + TX_STATUS) & F_TMT_RDY + ? "IRQ conflict" : "network cable problem"); + netdev_notice(dev, "timeout registers: %04x %04x %04x " + "%04x %04x %04x %04x %04x.\n", + htons(inw(ioaddr + 0)), htons(inw(ioaddr + 2)), + htons(inw(ioaddr + 4)), htons(inw(ioaddr + 6)), + htons(inw(ioaddr + 8)), htons(inw(ioaddr + 10)), + htons(inw(ioaddr + 12)), htons(inw(ioaddr + 14))); dev->stats.tx_errors++; /* ToDo: We should try to restart the adaptor... */ local_irq_disable(); @@ -845,13 +845,13 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb, unsigned char *buf = skb->data; if (length > ETH_FRAME_LEN) { - printk(KERN_NOTICE "%s: Attempting to send a large packet" - " (%d bytes).\n", dev->name, length); + netdev_notice(dev, "Attempting to send a large packet (%d bytes)\n", + length); return NETDEV_TX_BUSY; } - pr_debug("%s: Transmitting a packet of length %lu.\n", - dev->name, (unsigned long)skb->len); + netdev_dbg(dev, "Transmitting a packet of length %lu\n", + (unsigned long)skb->len); dev->stats.tx_bytes += skb->len; /* Disable both interrupts. */ @@ -904,7 +904,7 @@ static void fjn_reset(struct net_device *dev) unsigned int ioaddr = dev->base_addr; int i; - pr_debug("fjn_reset(%s) called.\n",dev->name); + netdev_dbg(dev, "fjn_reset() called\n"); /* Reset controller */ if( sram_config == 0 ) @@ -988,8 +988,8 @@ static void fjn_rx(struct net_device *dev) while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { u_short status = inw(ioaddr + DATAPORT); - pr_debug("%s: Rxing packet mode %02x status %04x.\n", - dev->name, inb(ioaddr + RX_MODE), status); + netdev_dbg(dev, "Rxing packet mode %02x status %04x.\n", + inb(ioaddr + RX_MODE), status); #ifndef final_version if (status == 0) { outb(F_SKP_PKT, ioaddr + RX_SKIP); @@ -1008,16 +1008,16 @@ static void fjn_rx(struct net_device *dev) struct sk_buff *skb; if (pkt_len > 1550) { - printk(KERN_NOTICE "%s: The FMV-18x claimed a very " - "large packet, size %d.\n", dev->name, pkt_len); + netdev_notice(dev, "The FMV-18x claimed a very large packet, size %d\n", + pkt_len); outb(F_SKP_PKT, ioaddr + RX_SKIP); dev->stats.rx_errors++; break; } skb = dev_alloc_skb(pkt_len+2); if (skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping " - "packet (len %d).\n", dev->name, pkt_len); + netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n", + pkt_len); outb(F_SKP_PKT, ioaddr + RX_SKIP); dev->stats.rx_dropped++; break; diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index cbcda123b1bf..dc85282193bf 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -45,6 +45,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -272,15 +274,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) i = ibmtr_probe_card(dev); if (i != 0) { - printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO - "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", - dev->name, dev->base_addr, dev->irq, - (u_long)ti->mmio, (u_long)(ti->sram_base << 12), - dev->dev_addr); + netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", + dev->base_addr, dev->irq, + (u_long)ti->mmio, (u_long)(ti->sram_base << 12), + dev->dev_addr); return 0; failed: diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 68f2deeb3ade..89cf63bb8c91 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -111,6 +111,8 @@ Log: nmclan_cs.c,v ---------------------------------------------------------------------------- */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "nmclan_cs" #define DRV_VERSION "0.16" @@ -563,7 +565,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr) /* Wait for reset bit to be cleared automatically after <= 200ns */; if(++ct > 500) { - printk(KERN_ERR "mace: reset failed, card removed ?\n"); + pr_err("reset failed, card removed?\n"); return -1; } udelay(1); @@ -610,7 +612,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr) { if(++ ct > 500) { - printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n"); + pr_err("ADDRCHG timeout, card removed?\n"); return -1; } } @@ -678,8 +680,8 @@ static int nmclan_config(struct pcmcia_device *link) dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { - printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" - " be 0x40 0x?9\n", sig[0], sig[1]); + pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", + sig[0], sig[1]); return -ENODEV; } } @@ -691,20 +693,18 @@ static int nmclan_config(struct pcmcia_device *link) if (if_port <= 2) dev->if_port = if_port; else - printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); + pr_notice("invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); i = register_netdev(dev); if (i != 0) { - printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," - " hw_addr %pM\n", - dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], - dev->dev_addr); + netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n", + dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr); return 0; failed: @@ -798,8 +798,7 @@ static int mace_config(struct net_device *dev, struct ifmap *map) if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { if (map->port <= 2) { dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", dev->name, - if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); } else return -EINVAL; } @@ -878,12 +877,12 @@ static void mace_tx_timeout(struct net_device *dev) mace_private *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); + netdev_notice(dev, "transmit timed out -- "); #if RESET_ON_TIMEOUT - printk("resetting card\n"); + pr_cont("resetting card\n"); pcmcia_reset_card(link->socket); #else /* #if RESET_ON_TIMEOUT */ - printk("NOT resetting card\n"); + pr_cont("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ dev->trans_start = jiffies; /* prevent tx timeout */ netif_wake_queue(dev); @@ -965,22 +964,21 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) ioaddr = dev->base_addr; if (lp->tx_irq_disabled) { - printk( - (lp->tx_irq_disabled? - KERN_NOTICE "%s: Interrupt with tx_irq_disabled " - "[isr=%02X, imr=%02X]\n": - KERN_NOTICE "%s: Re-entering the interrupt handler " - "[isr=%02X, imr=%02X]\n"), - dev->name, - inb(ioaddr + AM2150_MACE_BASE + MACE_IR), - inb(ioaddr + AM2150_MACE_BASE + MACE_IMR) - ); + const char *msg; + if (lp->tx_irq_disabled) + msg = "Interrupt with tx_irq_disabled"; + else + msg = "Re-entering the interrupt handler"; + netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n", + msg, + inb(ioaddr + AM2150_MACE_BASE + MACE_IR), + inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)); /* WARNING: MACE_IR has been read! */ return IRQ_NONE; } if (!netif_device_present(dev)) { - pr_debug("%s: interrupt from dead card\n", dev->name); + netdev_dbg(dev, "interrupt from dead card\n"); return IRQ_NONE; } @@ -1378,8 +1376,8 @@ static void BuildLAF(int *ladrf, int *adr) printk(KERN_DEBUG " adr =%pM\n", adr); printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode); for (i = 0; i < 8; i++) - printk(KERN_CONT " %02X", ladrf[i]); - printk(KERN_CONT "\n"); + pr_cont(" %02X", ladrf[i]); + pr_cont("\n"); #endif } /* BuildLAF */ diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 377367d03b41..cc7a357feac9 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -25,6 +25,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -820,7 +822,7 @@ static int check_sig(struct pcmcia_device *link) modconf_t mod = { .Attributes = CONF_IO_CHANGE_WIDTH, }; - printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); + pr_info("using 8-bit IO window\n"); smc91c92_suspend(link); pcmcia_modify_configuration(link, &mod); @@ -881,7 +883,7 @@ static int smc91c92_config(struct pcmcia_device *link) if ((if_port >= 0) && (if_port <= 2)) dev->if_port = if_port; else - printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n"); + dev_notice(&link->dev, "invalid if_port requested\n"); switch (smc->manfid) { case MANFID_OSITECH: @@ -899,7 +901,7 @@ static int smc91c92_config(struct pcmcia_device *link) } if (i != 0) { - printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n"); + dev_notice(&link->dev, "Unable to find hardware address.\n"); goto config_failed; } @@ -952,30 +954,28 @@ static int smc91c92_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); + dev_err(&link->dev, "register_netdev() failed\n"); goto config_undo; } - printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, - dev->dev_addr); + netdev_info(dev, "smc91c%s rev %d: io %#3lx, irq %d, hw_addr %pM\n", + name, (rev & 0x0f), dev->base_addr, dev->irq, dev->dev_addr); if (rev > 0) { if (mir & 0x3ff) - printk(KERN_INFO " %lu byte", mir); + netdev_info(dev, " %lu byte", mir); else - printk(KERN_INFO " %lu kb", mir>>10); - printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ? - "MII" : if_names[dev->if_port]); + netdev_info(dev, " %lu kb", mir>>10); + pr_cont(" buffer, %s xcvr\n", + (smc->cfg & CFG_MII_SELECT) ? "MII" : if_names[dev->if_port]); } if (smc->cfg & CFG_MII_SELECT) { if (smc->mii_if.phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", - smc->mii_if.phy_id, j); + netdev_dbg(dev, " MII transceiver at index %d, status %x\n", + smc->mii_if.phy_id, j); } else { - printk(KERN_NOTICE " No MII transceivers found!\n"); + netdev_notice(dev, " No MII transceivers found!\n"); } } return 0; @@ -1081,10 +1081,10 @@ static void smc_dump(struct net_device *dev) save = inw(ioaddr + BANK_SELECT); for (w = 0; w < 4; w++) { SMC_SELECT_BANK(w); - printk(KERN_DEBUG "bank %d: ", w); + netdev_printk(KERN_DEBUG, dev, "bank %d: ", w); for (i = 0; i < 14; i += 2) - printk(" %04x", inw(ioaddr + i)); - printk("\n"); + pr_cont(" %04x", inw(ioaddr + i)); + pr_cont("\n"); } outw(save, ioaddr + BANK_SELECT); } @@ -1106,7 +1106,7 @@ static int smc_open(struct net_device *dev) return -ENODEV; /* Physical device present signature. */ if (check_sig(link) < 0) { - printk("smc91c92_cs: Yikes! Bad chip signature!\n"); + netdev_info(dev, "Yikes! Bad chip signature!\n"); return -ENODEV; } link->open++; @@ -1172,7 +1172,7 @@ static void smc_hardware_send_packet(struct net_device * dev) u_char packet_no; if (!skb) { - printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name); + netdev_err(dev, "In XMIT with no packet to send\n"); return; } @@ -1180,8 +1180,8 @@ static void smc_hardware_send_packet(struct net_device * dev) packet_no = inw(ioaddr + PNR_ARR) >> 8; if (packet_no & 0x80) { /* If not, there is a hardware problem! Likely an ejected card. */ - printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation" - " failed, status %#2.2x.\n", dev->name, packet_no); + netdev_warn(dev, "hardware Tx buffer allocation failed, status %#2.2x\n", + packet_no); dev_kfree_skb_irq(skb); smc->saved_skb = NULL; netif_start_queue(dev); @@ -1200,8 +1200,7 @@ static void smc_hardware_send_packet(struct net_device * dev) u_char *buf = skb->data; u_int length = skb->len; /* The chip will pad to ethernet min. */ - pr_debug("%s: Trying to xmit packet of length %d.\n", - dev->name, length); + netdev_dbg(dev, "Trying to xmit packet of length %d\n", length); /* send the packet length: +6 for status word, length, and ctl */ outw(0, ioaddr + DATA_1); @@ -1233,9 +1232,8 @@ static void smc_tx_timeout(struct net_device *dev) struct smc_private *smc = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " - "Tx_status %2.2x status %4.4x.\n", - dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2)); + netdev_notice(dev, "transmit timed out, Tx_status %2.2x status %4.4x.\n", + inw(ioaddr)&0xff, inw(ioaddr + 2)); dev->stats.tx_errors++; smc_reset(dev); dev->trans_start = jiffies; /* prevent tx timeout */ @@ -1254,14 +1252,14 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); - pr_debug("%s: smc_start_xmit(length = %d) called," - " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2)); + netdev_dbg(dev, "smc_start_xmit(length = %d) called, status %04x\n", + skb->len, inw(ioaddr + 2)); if (smc->saved_skb) { /* THIS SHOULD NEVER HAPPEN. */ dev->stats.tx_aborted_errors++; - printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n", - dev->name); + netdev_printk(KERN_DEBUG, dev, + "Internal error -- sent packet while busy\n"); return NETDEV_TX_BUSY; } smc->saved_skb = skb; @@ -1269,7 +1267,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, num_pages = skb->len >> 8; if (num_pages > 7) { - printk(KERN_ERR "%s: Far too big packet error.\n", dev->name); + netdev_err(dev, "Far too big packet error: %d pages\n", num_pages); dev_kfree_skb (skb); smc->saved_skb = NULL; dev->stats.tx_dropped++; @@ -1339,8 +1337,7 @@ static void smc_tx_err(struct net_device * dev) } if (tx_status & TS_SUCCESS) { - printk(KERN_NOTICE "%s: Successful packet caused error " - "interrupt?\n", dev->name); + netdev_notice(dev, "Successful packet caused error interrupt?\n"); } /* re-enable transmit */ SMC_SELECT_BANK(0); @@ -1530,8 +1527,7 @@ static void smc_rx(struct net_device *dev) /* Assertion: we are in Window 2. */ if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) { - printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n", - dev->name); + netdev_err(dev, "smc_rx() with nothing on Rx FIFO\n"); return; } @@ -1646,8 +1642,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) else if (map->port > 2) return -EINVAL; dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); smc_reset(dev); } return 0; @@ -1798,7 +1793,7 @@ static void media_check(u_long arg) this, we can limp along even if the interrupt is blocked */ if (smc->watchdog++ && ((i>>8) & i)) { if (!smc->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); local_irq_save(flags); smc_interrupt(dev->irq, dev); local_irq_restore(flags); @@ -1822,7 +1817,7 @@ static void media_check(u_long arg) SMC_SELECT_BANK(3); link = mdio_read(dev, smc->mii_if.phy_id, 1); if (!link || (link == 0xffff)) { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); smc->mii_if.phy_id = -1; goto reschedule; } @@ -1830,15 +1825,13 @@ static void media_check(u_long arg) link &= 0x0004; if (link != smc->link_status) { u_short p = mdio_read(dev, smc->mii_if.phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40)) ? TCR_FDUPLX : 0); if (link) { - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((p & 0x0180) ? "100" : "10"), - (smc->duplex ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: " + "%dbaseT-%cD selected\n", + (p & 0x0180) ? 100 : 10, smc->duplex ? 'F' : 'H'); } SMC_SELECT_BANK(0); outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR); @@ -1857,25 +1850,23 @@ static void media_check(u_long arg) if (media != smc->media_status) { if ((media & smc->media_status & 1) && ((smc->media_status ^ media) & EPH_LINK_OK)) - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (smc->media_status & EPH_LINK_OK ? "lost" : "found")); + netdev_info(dev, "%s link beat\n", + smc->media_status & EPH_LINK_OK ? "lost" : "found"); else if ((media & smc->media_status & 2) && ((smc->media_status ^ media) & EPH_16COL)) - printk(KERN_INFO "%s: coax cable %s\n", dev->name, - (media & EPH_16COL ? "problem" : "ok")); + netdev_info(dev, "coax cable %s\n", + media & EPH_16COL ? "problem" : "ok"); if (dev->if_port == 0) { if (media & 1) { if (media & EPH_LINK_OK) - printk(KERN_INFO "%s: flipped to 10baseT\n", - dev->name); + netdev_info(dev, "flipped to 10baseT\n"); else smc_set_xcvr(dev, 2); } else { if (media & EPH_16COL) smc_set_xcvr(dev, 1); else - printk(KERN_INFO "%s: flipped to 10base2\n", - dev->name); + netdev_info(dev, "flipped to 10base2\n"); } } smc->media_status = media; diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index f5819526b5ee..d858b5e4c4a7 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -63,6 +63,8 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -210,13 +212,6 @@ enum xirc_cmd { /* Commands */ static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" }; - -#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: " -#define KERR_XIRC KERN_ERR "xirc2ps_cs: " -#define KWRN_XIRC KERN_WARNING "xirc2ps_cs: " -#define KNOT_XIRC KERN_NOTICE "xirc2ps_cs: " -#define KINF_XIRC KERN_INFO "xirc2ps_cs: " - /* card types */ #define XIR_UNKNOWN 0 /* unknown: not supported */ #define XIR_CE 1 /* (prodid 1) different hardware: not supported */ @@ -350,26 +345,26 @@ PrintRegisters(struct net_device *dev) if (pc_debug > 1) { int i, page; - printk(KDBG_XIRC "Register common: "); + printk(KERN_DEBUG pr_fmt("Register common: ")); for (i = 0; i < 8; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); for (page = 0; page <= 8; page++) { - printk(KDBG_XIRC "Register page %2x: ", page); + printk(KERN_DEBUG pr_fmt("Register page %2x: "), page); SelectPage(page); for (i = 8; i < 16; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); } for (page=0x40 ; page <= 0x5f; page++) { if (page == 0x43 || (page >= 0x46 && page <= 0x4f) || (page >= 0x51 && page <=0x5e)) continue; - printk(KDBG_XIRC "Register page %2x: ", page); + printk(KERN_DEBUG pr_fmt("Register page %2x: "), page); SelectPage(page); for (i = 8; i < 16; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); } } } @@ -608,11 +603,11 @@ set_card_type(struct pcmcia_device *link) local->modem = 0; local->card_type = XIR_UNKNOWN; if (!(prodid & 0x40)) { - printk(KNOT_XIRC "Ooops: Not a creditcard\n"); + pr_notice("Oops: Not a creditcard\n"); return 0; } if (!(mediaid & 0x01)) { - printk(KNOT_XIRC "Not an Ethernet card\n"); + pr_notice("Not an Ethernet card\n"); return 0; } if (mediaid & 0x10) { @@ -643,12 +638,11 @@ set_card_type(struct pcmcia_device *link) } } if (local->card_type == XIR_CE || local->card_type == XIR_CEM) { - printk(KNOT_XIRC "Sorry, this is an old CE card\n"); + pr_notice("Sorry, this is an old CE card\n"); return 0; } if (local->card_type == XIR_UNKNOWN) - printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n", - mediaid, prodid); + pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid); return 1; } @@ -748,7 +742,7 @@ xirc2ps_config(struct pcmcia_device * link) /* Is this a valid card */ if (link->has_manf_id == 0) { - printk(KNOT_XIRC "manfid not found in CIS\n"); + pr_notice("manfid not found in CIS\n"); goto failure; } @@ -770,14 +764,14 @@ xirc2ps_config(struct pcmcia_device * link) local->manf_str = "Toshiba"; break; default: - printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", - (unsigned)link->manf_id); + pr_notice("Unknown Card Manufacturer ID: 0x%04x\n", + (unsigned)link->manf_id); goto failure; } dev_dbg(&link->dev, "found %s card\n", local->manf_str); if (!set_card_type(link)) { - printk(KNOT_XIRC "this card is not supported\n"); + pr_notice("this card is not supported\n"); goto failure; } @@ -803,7 +797,7 @@ xirc2ps_config(struct pcmcia_device * link) err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev); if (err) { - printk(KNOT_XIRC "node-id not found in CIS\n"); + pr_notice("node-id not found in CIS\n"); goto failure; } @@ -838,7 +832,7 @@ xirc2ps_config(struct pcmcia_device * link) * try to configure as Ethernet only. * .... */ } - printk(KNOT_XIRC "no ports available\n"); + pr_notice("no ports available\n"); } else { link->resource[0]->end = 16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { @@ -911,24 +905,24 @@ xirc2ps_config(struct pcmcia_device * link) #if 0 { u_char tmp; - printk(KERN_INFO "ECOR:"); + pr_info("ECOR:"); for (i=0; i < 7; i++) { tmp = readb(local->dingo_ccr + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); - printk(KERN_INFO "DCOR:"); + pr_cont("\n"); + pr_info("DCOR:"); for (i=0; i < 4; i++) { tmp = readb(local->dingo_ccr + 0x20 + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); - printk(KERN_INFO "SCOR:"); + pr_cont("\n"); + pr_info("SCOR:"); for (i=0; i < 10; i++) { tmp = readb(local->dingo_ccr + 0x40 + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); + pr_cont("\n"); } #endif @@ -947,7 +941,7 @@ xirc2ps_config(struct pcmcia_device * link) (local->mohawk && if_port==4)) dev->if_port = if_port; else - printk(KNOT_XIRC "invalid if_port requested\n"); + pr_notice("invalid if_port requested\n"); /* we can now register the device with the net subsystem */ dev->irq = link->irq; @@ -959,14 +953,14 @@ xirc2ps_config(struct pcmcia_device * link) SET_NETDEV_DEV(dev, &link->dev); if ((err=register_netdev(dev))) { - printk(KNOT_XIRC "register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto config_error; } /* give some infos about the hardware */ - printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n", - dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, - dev->dev_addr); + netdev_info(dev, "%s: port %#3lx, irq %d, hwaddr %pM\n", + local->manf_str, (u_long)dev->base_addr, (int)dev->irq, + dev->dev_addr); return 0; @@ -1098,8 +1092,7 @@ xirc2ps_interrupt(int irq, void *dev_id) skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */ if (!skb) { - printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n", - pktlen); + pr_notice("low memory, packet dropped (size=%u)\n", pktlen); dev->stats.rx_dropped++; } else { /* okay get the packet */ skb_reserve(skb, 2); @@ -1268,7 +1261,7 @@ xirc_tx_timeout(struct net_device *dev) { local_info_t *lp = netdev_priv(dev); dev->stats.tx_errors++; - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); + netdev_notice(dev, "transmit timed out\n"); schedule_work(&lp->tx_timeout_task); } @@ -1435,8 +1428,7 @@ do_config(struct net_device *dev, struct ifmap *map) local->probe_port = 0; dev->if_port = map->port; } - printk(KERN_INFO "%s: switching to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switching to %s port\n", if_names[dev->if_port]); do_reset(dev,1); /* not the fine way :-) */ } return 0; @@ -1576,7 +1568,7 @@ do_reset(struct net_device *dev, int full) { SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ - printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value); + pr_debug("%s: ESR is: %#02x\n", dev->name, value); } #endif @@ -1626,13 +1618,12 @@ do_reset(struct net_device *dev, int full) if (full && local->mohawk && init_mii(dev)) { if (dev->if_port == 4 || local->dingo || local->new_mii) { - printk(KERN_INFO "%s: MII selected\n", dev->name); + netdev_info(dev, "MII selected\n"); SelectPage(2); PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08); msleep(20); } else { - printk(KERN_INFO "%s: MII detected; using 10mbs\n", - dev->name); + netdev_info(dev, "MII detected; using 10mbs\n"); SelectPage(0x42); if (dev->if_port == 2) /* enable 10Base2 */ PutByte(XIRCREG42_SWC1, 0xC0); @@ -1677,8 +1668,8 @@ do_reset(struct net_device *dev, int full) } if (full) - printk(KERN_INFO "%s: media %s, silicon revision %d\n", - dev->name, if_names[dev->if_port], local->silicon); + netdev_info(dev, "media %s, silicon revision %d\n", + if_names[dev->if_port], local->silicon); /* We should switch back to page 0 to avoid a bug in revision 0 * where regs with offset below 8 can't be read after an access * to the MAC registers */ @@ -1720,8 +1711,7 @@ init_mii(struct net_device *dev) control = mii_rd(ioaddr, 0, 0); if (control & 0x0400) { - printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n", - dev->name); + netdev_notice(dev, "can't take PHY out of isolation mode\n"); local->probe_port = 0; return 0; } @@ -1739,8 +1729,7 @@ init_mii(struct net_device *dev) } if (!(status & 0x0020)) { - printk(KERN_INFO "%s: autonegotiation failed;" - " using 10mbs\n", dev->name); + netdev_info(dev, "autonegotiation failed; using 10mbs\n"); if (!local->new_mii) { control = 0x0000; mii_wr(ioaddr, 0, 0, control, 16); @@ -1750,8 +1739,7 @@ init_mii(struct net_device *dev) } } else { linkpartner = mii_rd(ioaddr, 0, 5); - printk(KERN_INFO "%s: MII link partner: %04x\n", - dev->name, linkpartner); + netdev_info(dev, "MII link partner: %04x\n", linkpartner); if (linkpartner & 0x0080) { dev->if_port = 4; } else -- cgit v1.2.3 From b3d18f15092a7db2f229cd7bc69fc40eac0774f4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Aug 2010 06:26:57 +0000 Subject: net/ax25: Use available error codes Error codes are stored in err, but the return value is always 0. Return err instead. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ local idexpression x; constant C; @@ if (...) { ... x = -C ... when != x ( return <+...x...+>; | return NULL; | return; | * return ...; ) } // Signed-off-by: Julia Lawall Acked-by: Ralf Baechle Signed-off-by: David S. Miller --- net/ax25/ax25_route.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 7805945a5fd6..a1690845dc6e 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -412,7 +412,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) { ax25_uid_assoc *user; ax25_route *ax25_rt; - int err; + int err = 0; if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) return -EHOSTUNREACH; @@ -453,7 +453,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) put: ax25_put_route(ax25_rt); - return 0; + return err; } struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, -- cgit v1.2.3 From 49339ccae5ba361b62e829886117dbce4b77194f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Aug 2010 06:28:19 +0000 Subject: net/ax25: Use available error codes Error codes are stored in err, but the return value is always 0. Return err instead. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ local idexpression x; constant C; @@ if (...) { ... x = -C ... when != x ( return <+...x...+>; | return NULL; | return; | * return ...; ) } // Signed-off-by: Julia Lawall Acked-by: Ralf Baechle Signed-off-by: David S. Miller --- net/ax25/af_ax25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index cfdfd7e2a172..26eaebf4aaa9 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1103,7 +1103,7 @@ done: out: release_sock(sk); - return 0; + return err; } /* -- cgit v1.2.3 From 900853a4db7098b0e58ddcb732632ac43a7b2148 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Aug 2010 10:23:51 +0000 Subject: drivers/net/qlcnic: Use available error codes The error code is stored in the variable err, but it is the variable ret that is returned instead. So store the error code in ret. Err is then useless. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ local idexpression x; constant C; @@ if (...) { ... x = -C ... when != x ( return <+...x...+>; | return NULL; | return; | * return ...; ) } // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index abd7cd6db6fd..384cc52a9c3e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -474,7 +474,7 @@ static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) { struct qlcnic_pci_info *pci_info; - int i, ret = 0, err; + int i, ret = 0; u8 pfn; pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); @@ -484,14 +484,14 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); if (!adapter->npars) { - err = -ENOMEM; + ret = -ENOMEM; goto err_pci_info; } adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); if (!adapter->eswitch) { - err = -ENOMEM; + ret = -ENOMEM; goto err_npars; } -- cgit v1.2.3 From cb5d991a99104565f7b622b1b97587f4b1effa82 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 17 Aug 2010 06:11:24 +0000 Subject: greth: Use return value of register_netdev Use the return value provided by register_netdev on error instead of hard setting it to -ENOMEM. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/greth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f15c64f1cd38..fbeaf70d1727 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1547,10 +1547,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev, const struct dev->netdev_ops = &greth_netdev_ops; dev->ethtool_ops = &greth_ethtool_ops; - if (register_netdev(dev)) { + err = register_netdev(dev); + if (err) { if (netif_msg_probe(greth)) dev_err(greth->dev, "netdevice registration failed.\n"); - err = -ENOMEM; goto error5; } -- cgit v1.2.3 From 0b29b894b17747f7fa0c5668281c68b8cde7647b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 17 Aug 2010 06:13:05 +0000 Subject: sunhme: Use return value of register_netdev Use the return value provided by register_netdev on error instead of using a previously set value. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/sunhme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index bd0df1c14955..d96431eb698b 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2808,7 +2808,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i happy_meal_set_initial_advertisement(hp); spin_unlock_irq(&hp->happy_lock); - if (register_netdev(hp->dev)) { + err = register_netdev(hp->dev); + if (err) { printk(KERN_ERR "happymeal: Cannot register net device, " "aborting.\n"); goto err_out_free_coherent; @@ -3130,7 +3131,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, happy_meal_set_initial_advertisement(hp); spin_unlock_irq(&hp->happy_lock); - if (register_netdev(hp->dev)) { + err = register_netdev(hp->dev); + if (err) { printk(KERN_ERR "happymeal(PCI): Cannot register net device, " "aborting.\n"); goto err_out_iounmap; -- cgit v1.2.3 From c6c759884b05c7449a19d39c763a7482180e2def Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 17 Aug 2010 07:55:04 +0000 Subject: drivers/net/sungem: Use netdev_, netif_ and pr_ Use the current logging message styles. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/sungem.c | 211 +++++++++++++++++++---------------------------- drivers/net/sungem_phy.c | 3 +- 2 files changed, 85 insertions(+), 129 deletions(-) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 434f9d735333..4ceb3cf6a9a9 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -31,6 +31,8 @@ * about when we can start taking interrupts or get xmit() called... */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -105,7 +107,6 @@ MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver"); MODULE_LICENSE("GPL"); #define GEM_MODULE_NAME "gem" -#define PFX GEM_MODULE_NAME ": " static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = { { PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM, @@ -262,8 +263,7 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta gp->dev->name, pcs_istat); if (!(pcs_istat & PCS_ISTAT_LSC)) { - printk(KERN_ERR "%s: PCS irq but no link status change???\n", - dev->name); + netdev_err(dev, "PCS irq but no link status change???\n"); return 0; } @@ -282,20 +282,16 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta * when autoneg has completed. */ if (pcs_miistat & PCS_MIISTAT_RF) - printk(KERN_INFO "%s: PCS AutoNEG complete, " - "RemoteFault\n", dev->name); + netdev_info(dev, "PCS AutoNEG complete, RemoteFault\n"); else - printk(KERN_INFO "%s: PCS AutoNEG complete.\n", - dev->name); + netdev_info(dev, "PCS AutoNEG complete\n"); } if (pcs_miistat & PCS_MIISTAT_LS) { - printk(KERN_INFO "%s: PCS link is now up.\n", - dev->name); + netdev_info(dev, "PCS link is now up\n"); netif_carrier_on(gp->dev); } else { - printk(KERN_INFO "%s: PCS link is now down.\n", - dev->name); + netdev_info(dev, "PCS link is now down\n"); netif_carrier_off(gp->dev); /* If this happens and the link timer is not running, * reset so we re-negotiate. @@ -323,14 +319,12 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s return 0; if (txmac_stat & MAC_TXSTAT_URUN) { - printk(KERN_ERR "%s: TX MAC xmit underrun.\n", - dev->name); + netdev_err(dev, "TX MAC xmit underrun\n"); gp->net_stats.tx_fifo_errors++; } if (txmac_stat & MAC_TXSTAT_MPE) { - printk(KERN_ERR "%s: TX MAC max packet size error.\n", - dev->name); + netdev_err(dev, "TX MAC max packet size error\n"); gp->net_stats.tx_errors++; } @@ -377,8 +371,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX MAC will not reset, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX MAC will not reset, resetting whole chip\n"); return 1; } @@ -390,8 +383,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX MAC will not disable, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX MAC will not disable, resetting whole chip\n"); return 1; } @@ -403,8 +395,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX DMA will not disable, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX DMA will not disable, resetting whole chip\n"); return 1; } @@ -419,8 +410,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX reset command will not execute, resetting " - "whole chip.\n", dev->name); + netdev_err(dev, "RX reset command will not execute, resetting whole chip\n"); return 1; } @@ -429,8 +419,7 @@ static int gem_rxmac_reset(struct gem *gp) struct gem_rxd *rxd = &gp->init_block->rxd[i]; if (gp->rx_skbs[i] == NULL) { - printk(KERN_ERR "%s: Parts of RX ring empty, resetting " - "whole chip.\n", dev->name); + netdev_err(dev, "Parts of RX ring empty, resetting whole chip\n"); return 1; } @@ -479,8 +468,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s if (rxmac_stat & MAC_RXSTAT_OFLW) { u32 smac = readl(gp->regs + MAC_SMACHINE); - printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n", - dev->name, smac); + netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac); gp->net_stats.rx_over_errors++; gp->net_stats.rx_fifo_errors++; @@ -542,19 +530,18 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta if (gp->pdev->vendor == PCI_VENDOR_ID_SUN && gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) { - printk(KERN_ERR "%s: PCI error [%04x] ", - dev->name, pci_estat); + netdev_err(dev, "PCI error [%04x]", pci_estat); if (pci_estat & GREG_PCIESTAT_BADACK) - printk(" "); + pr_cont(" "); if (pci_estat & GREG_PCIESTAT_DTRTO) - printk(" "); + pr_cont(" "); if (pci_estat & GREG_PCIESTAT_OTHER) - printk(""); - printk("\n"); + pr_cont(" "); + pr_cont("\n"); } else { pci_estat |= GREG_PCIESTAT_OTHER; - printk(KERN_ERR "%s: PCI error\n", dev->name); + netdev_err(dev, "PCI error\n"); } if (pci_estat & GREG_PCIESTAT_OTHER) { @@ -565,26 +552,20 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta */ pci_read_config_word(gp->pdev, PCI_STATUS, &pci_cfg_stat); - printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n", - dev->name, pci_cfg_stat); + netdev_err(dev, "Read PCI cfg space status [%04x]\n", + pci_cfg_stat); if (pci_cfg_stat & PCI_STATUS_PARITY) - printk(KERN_ERR "%s: PCI parity error detected.\n", - dev->name); + netdev_err(dev, "PCI parity error detected\n"); if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT) - printk(KERN_ERR "%s: PCI target abort.\n", - dev->name); + netdev_err(dev, "PCI target abort\n"); if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT) - printk(KERN_ERR "%s: PCI master acks target abort.\n", - dev->name); + netdev_err(dev, "PCI master acks target abort\n"); if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT) - printk(KERN_ERR "%s: PCI master abort.\n", - dev->name); + netdev_err(dev, "PCI master abort\n"); if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR) - printk(KERN_ERR "%s: PCI system error SERR#.\n", - dev->name); + netdev_err(dev, "PCI system error SERR#\n"); if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY) - printk(KERN_ERR "%s: PCI parity error.\n", - dev->name); + netdev_err(dev, "PCI parity error\n"); /* Write the error bits back to clear them. */ pci_cfg_stat &= (PCI_STATUS_PARITY | @@ -874,8 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do) gp->rx_new = entry; if (drops) - printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", - gp->dev->name); + netdev_info(gp->dev, "Memory squeeze, deferring packet\n"); return work_done; } @@ -981,21 +961,19 @@ static void gem_tx_timeout(struct net_device *dev) { struct gem *gp = netdev_priv(dev); - printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name); + netdev_err(dev, "transmit timed out, resetting\n"); if (!gp->running) { - printk("%s: hrm.. hw not running !\n", dev->name); + netdev_err(dev, "hrm.. hw not running !\n"); return; } - printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n", - dev->name, - readl(gp->regs + TXDMA_CFG), - readl(gp->regs + MAC_TXSTAT), - readl(gp->regs + MAC_TXCFG)); - printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n", - dev->name, - readl(gp->regs + RXDMA_CFG), - readl(gp->regs + MAC_RXSTAT), - readl(gp->regs + MAC_RXCFG)); + netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n", + readl(gp->regs + TXDMA_CFG), + readl(gp->regs + MAC_TXSTAT), + readl(gp->regs + MAC_TXCFG)); + netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n", + readl(gp->regs + RXDMA_CFG), + readl(gp->regs + MAC_RXSTAT), + readl(gp->regs + MAC_RXCFG)); spin_lock_irq(&gp->lock); spin_lock(&gp->tx_lock); @@ -1048,8 +1026,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); spin_unlock_irqrestore(&gp->tx_lock, flags); - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); return NETDEV_TX_BUSY; } @@ -1158,8 +1135,7 @@ static void gem_pcs_reset(struct gem *gp) break; } if (limit < 0) - printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", - gp->dev->name); + netdev_warn(gp->dev, "PCS reset bit would not clear\n"); } static void gem_pcs_reinit_adv(struct gem *gp) @@ -1230,7 +1206,7 @@ static void gem_reset(struct gem *gp) } while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST)); if (limit < 0) - printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); + netdev_err(gp->dev, "SW reset is ghetto\n"); if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) gem_pcs_reinit_adv(gp); @@ -1395,9 +1371,8 @@ static int gem_set_link_modes(struct gem *gp) speed = SPEED_1000; } - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n", - gp->dev->name, speed, (full_duplex ? "full" : "half")); + netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n", + speed, (full_duplex ? "full" : "half")); if (!gp->running) return 0; @@ -1451,15 +1426,13 @@ static int gem_set_link_modes(struct gem *gp) if (netif_msg_link(gp)) { if (pause) { - printk(KERN_INFO "%s: Pause is enabled " - "(rxfifo: %d off: %d on: %d)\n", - gp->dev->name, - gp->rx_fifo_sz, - gp->rx_pause_off, - gp->rx_pause_on); + netdev_info(gp->dev, + "Pause is enabled (rxfifo: %d off: %d on: %d)\n", + gp->rx_fifo_sz, + gp->rx_pause_off, + gp->rx_pause_on); } else { - printk(KERN_INFO "%s: Pause is disabled\n", - gp->dev->name); + netdev_info(gp->dev, "Pause is disabled\n"); } } @@ -1484,9 +1457,8 @@ static int gem_mdio_link_not_up(struct gem *gp) { switch (gp->lstate) { case link_force_ret: - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Autoneg failed again, keeping" - " forced mode\n", gp->dev->name); + netif_info(gp, link, gp->dev, + "Autoneg failed again, keeping forced mode\n"); gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, gp->last_forced_speed, DUPLEX_HALF); gp->timer_ticks = 5; @@ -1499,9 +1471,7 @@ static int gem_mdio_link_not_up(struct gem *gp) */ if (gp->phy_mii.def->magic_aneg) return 1; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: switching to forced 100bt\n", - gp->dev->name); + netif_info(gp, link, gp->dev, "switching to forced 100bt\n"); /* Try forced modes. */ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100, DUPLEX_HALF); @@ -1517,9 +1487,8 @@ static int gem_mdio_link_not_up(struct gem *gp) gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10, DUPLEX_HALF); gp->timer_ticks = 5; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: switching to forced 10bt\n", - gp->dev->name); + netif_info(gp, link, gp->dev, + "switching to forced 10bt\n"); return 0; } else return 1; @@ -1574,8 +1543,8 @@ static void gem_link_timer(unsigned long data) gp->last_forced_speed = gp->phy_mii.speed; gp->timer_ticks = 5; if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Got link after fallback, retrying" - " autoneg once...\n", gp->dev->name); + netdev_info(gp->dev, + "Got link after fallback, retrying autoneg once...\n"); gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising); } else if (gp->lstate != link_up) { gp->lstate = link_up; @@ -1589,9 +1558,7 @@ static void gem_link_timer(unsigned long data) */ if (gp->lstate == link_up) { gp->lstate = link_down; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Link down\n", - gp->dev->name); + netif_info(gp, link, gp->dev, "Link down\n"); netif_carrier_off(gp->dev); gp->reset_task_pending = 1; schedule_work(&gp->reset_task); @@ -1746,8 +1713,7 @@ static void gem_init_phy(struct gem *gp) if (phy_read(gp, MII_BMCR) != 0xffff) break; if (i == 2) - printk(KERN_WARNING "%s: GMAC PHY not responding !\n", - gp->dev->name); + netdev_warn(gp->dev, "GMAC PHY not responding !\n"); } } @@ -2038,7 +2004,7 @@ static int gem_check_invariants(struct gem *gp) * as this chip has no gigabit PHY. */ if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) { - printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n", + pr_err("RIO GEM lacks MII phy, mif_cfg[%08x]\n", mif_cfg); return -1; } @@ -2078,7 +2044,7 @@ static int gem_check_invariants(struct gem *gp) } if (i == 32) { if (pdev->device != PCI_DEVICE_ID_SUN_GEM) { - printk(KERN_ERR PFX "RIO MII phy will not respond.\n"); + pr_err("RIO MII phy will not respond\n"); return -1; } gp->phy_type = phy_serdes; @@ -2093,7 +2059,7 @@ static int gem_check_invariants(struct gem *gp) if (pdev->device == PCI_DEVICE_ID_SUN_GEM) { if (gp->tx_fifo_sz != (9 * 1024) || gp->rx_fifo_sz != (20 * 1024)) { - printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n", + pr_err("GEM has bogus fifo sizes tx(%d) rx(%d)\n", gp->tx_fifo_sz, gp->rx_fifo_sz); return -1; } @@ -2101,7 +2067,7 @@ static int gem_check_invariants(struct gem *gp) } else { if (gp->tx_fifo_sz != (2 * 1024) || gp->rx_fifo_sz != (2 * 1024)) { - printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n", + pr_err("RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n", gp->tx_fifo_sz, gp->rx_fifo_sz); return -1; } @@ -2239,7 +2205,7 @@ static int gem_do_start(struct net_device *dev) if (request_irq(gp->pdev->irq, gem_interrupt, IRQF_SHARED, dev->name, (void *)dev)) { - printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name); + netdev_err(dev, "failed to request irq !\n"); spin_lock_irqsave(&gp->lock, flags); spin_lock(&gp->tx_lock); @@ -2378,9 +2344,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) mutex_lock(&gp->pm_mutex); - printk(KERN_INFO "%s: suspending, WakeOnLan %s\n", - dev->name, - (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled"); + netdev_info(dev, "suspending, WakeOnLan %s\n", + (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled"); /* Keep the cell enabled during the entire operation */ spin_lock_irqsave(&gp->lock, flags); @@ -2440,7 +2405,7 @@ static int gem_resume(struct pci_dev *pdev) struct gem *gp = netdev_priv(dev); unsigned long flags; - printk(KERN_INFO "%s: resuming\n", dev->name); + netdev_info(dev, "resuming\n"); mutex_lock(&gp->pm_mutex); @@ -2452,8 +2417,7 @@ static int gem_resume(struct pci_dev *pdev) /* Make sure PCI access and bus master are enabled */ if (pci_enable_device(gp->pdev)) { - printk(KERN_ERR "%s: Can't re-enable chip !\n", - dev->name); + netdev_err(dev, "Can't re-enable chip !\n"); /* Put cell and forget it for now, it will be considered as * still asleep, a new sleep cycle may bring it back */ @@ -2938,7 +2902,7 @@ static int __devinit gem_get_device_address(struct gem *gp) addr = idprom->id_ethaddr; #else printk("\n"); - printk(KERN_ERR "%s: can't get mac-address\n", dev->name); + pr_err("%s: can't get mac-address\n", dev->name); return -1; #endif } @@ -3009,14 +2973,12 @@ static const struct net_device_ops gem_netdev_ops = { static int __devinit gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int gem_version_printed = 0; unsigned long gemreg_base, gemreg_len; struct net_device *dev; struct gem *gp; int err, pci_using_dac; - if (gem_version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk_once(KERN_INFO "%s", version); /* Apple gmac note: during probe, the chip is powered up by * the arch code to allow the code below to work (and to let @@ -3026,8 +2988,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, */ err = pci_enable_device(pdev); if (err) { - printk(KERN_ERR PFX "Cannot enable MMIO operation, " - "aborting.\n"); + pr_err("Cannot enable MMIO operation, aborting\n"); return err; } pci_set_master(pdev); @@ -3048,8 +3009,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, } else { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " - "aborting.\n"); + pr_err("No usable DMA configuration, aborting\n"); goto err_disable_device; } pci_using_dac = 0; @@ -3059,15 +3019,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gemreg_len = pci_resource_len(pdev, 0); if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) { - printk(KERN_ERR PFX "Cannot find proper PCI device " - "base address, aborting.\n"); + pr_err("Cannot find proper PCI device base address, aborting\n"); err = -ENODEV; goto err_disable_device; } dev = alloc_etherdev(sizeof(*gp)); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + pr_err("Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_disable_device; } @@ -3077,8 +3036,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, err = pci_request_regions(pdev, DRV_NAME); if (err) { - printk(KERN_ERR PFX "Cannot obtain PCI resources, " - "aborting.\n"); + pr_err("Cannot obtain PCI resources, aborting\n"); goto err_out_free_netdev; } @@ -3104,8 +3062,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->regs = ioremap(gemreg_base, gemreg_len); if (!gp->regs) { - printk(KERN_ERR PFX "Cannot map device registers, " - "aborting.\n"); + pr_err("Cannot map device registers, aborting\n"); err = -EIO; goto err_out_free_res; } @@ -3150,8 +3107,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, pci_alloc_consistent(pdev, sizeof(struct gem_init_block), &gp->gblock_dvma); if (!gp->init_block) { - printk(KERN_ERR PFX "Cannot allocate init block, " - "aborting.\n"); + pr_err("Cannot allocate init block, aborting\n"); err = -ENOMEM; goto err_out_iounmap; } @@ -3180,19 +3136,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev, /* Register with kernel */ if (register_netdev(dev)) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + pr_err("Cannot register net device, aborting\n"); err = -ENOMEM; goto err_out_free_consistent; } - printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n", - dev->name, dev->dev_addr); + netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n", + dev->dev_addr); if (gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) - printk(KERN_INFO "%s: Found %s PHY\n", dev->name, - gp->phy_mii.def ? gp->phy_mii.def->name : "no"); + netdev_info(dev, "Found %s PHY\n", + gp->phy_mii.def ? gp->phy_mii.def->name : "no"); /* GEM can do it all... */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX; diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index 78f8cee5fd74..4a4fac630337 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -1175,7 +1175,8 @@ int mii_phy_probe(struct mii_phy *phy, int mii_id) /* Read ID and find matching entry */ id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)); - printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id); + printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n", + id, mii_id); for (i=0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; -- cgit v1.2.3 From 4d5870ec103e6569851b9710f0093f072b08439a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 17 Aug 2010 07:55:05 +0000 Subject: drivers/net/sunvnet.c: Use pr_ and netdev_ Use the current message logging styles. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/sunvnet.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index d281a7b34701..bf3c762de620 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -3,6 +3,8 @@ * Copyright (C) 2007, 2008 David S. Miller */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -20,7 +22,6 @@ #include "sunvnet.h" #define DRV_MODULE_NAME "sunvnet" -#define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.0" #define DRV_MODULE_RELDATE "June 25, 2007" @@ -45,9 +46,9 @@ static int vnet_handle_unknown(struct vnet_port *port, void *arg) { struct vio_msg_tag *pkt = arg; - printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n", + pr_err("Received unknown msg [%02x:%02x:%04x:%08x]\n", pkt->type, pkt->stype, pkt->stype_env, pkt->sid); - printk(KERN_ERR PFX "Resetting connection.\n"); + pr_err("Resetting connection\n"); ldc_disconnect(port->vio.lp); @@ -400,8 +401,8 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf) if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) return 0; if (unlikely(pkt->seq != dr->rcv_nxt)) { - printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] " - "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt); + pr_err("RX out of sequence seq[0x%llx] rcv_nxt[0x%llx]\n", + pkt->seq, dr->rcv_nxt); return 0; } @@ -464,8 +465,7 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf) struct vio_net_mcast_info *pkt = msgbuf; if (pkt->tag.stype != VIO_SUBTYPE_ACK) - printk(KERN_ERR PFX "%s: Got unexpected MCAST reply " - "[%02x:%02x:%04x:%08x]\n", + pr_err("%s: Got unexpected MCAST reply [%02x:%02x:%04x:%08x]\n", port->vp->dev->name, pkt->tag.type, pkt->tag.stype, @@ -520,7 +520,7 @@ static void vnet_event(void *arg, int event) } if (unlikely(event != LDC_EVENT_DATA_READY)) { - printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); + pr_warning("Unexpected LDC event %d\n", event); spin_unlock_irqrestore(&vio->lock, flags); return; } @@ -662,8 +662,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* This is a hard error, log it. */ - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " - "queue awake!\n", dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); dev->stats.tx_errors++; } spin_unlock_irqrestore(&port->vio.lock, flags); @@ -696,8 +695,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) err = __vnet_tx_trigger(port); if (unlikely(err < 0)) { - printk(KERN_INFO PFX "%s: TX trigger error %d\n", - dev->name, err); + netdev_info(dev, "TX trigger error %d\n", err); d->hdr.state = VIO_DESC_FREE; dev->stats.tx_carrier_errors++; goto out_dropped_unlock; @@ -952,12 +950,12 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port) err = -ENOMEM; if (!buf) { - printk(KERN_ERR "TX buffer allocation failure\n"); + pr_err("TX buffer allocation failure\n"); goto err_out; } err = -EFAULT; if ((unsigned long)buf & (8UL - 1)) { - printk(KERN_ERR "TX buffer misaligned\n"); + pr_err("TX buffer misaligned\n"); kfree(buf); goto err_out; } @@ -1030,7 +1028,7 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) dev = alloc_etherdev(sizeof(*vp)); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + pr_err("Etherdev alloc failed, aborting\n"); return ERR_PTR(-ENOMEM); } @@ -1056,12 +1054,11 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) err = register_netdev(dev); if (err) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + pr_err("Cannot register net device, aborting\n"); goto err_out_free_dev; } - printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr); + netdev_info(dev, "Sun LDOM vnet %pM\n", dev->dev_addr); list_add(&vp->list, &vnet_list); @@ -1133,10 +1130,7 @@ static struct vio_driver_ops vnet_vio_ops = { static void __devinit print_version(void) { - static int version_printed; - - if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk_once(KERN_INFO "%s", version); } const char *remote_macaddr_prop = "remote-mac-address"; @@ -1157,7 +1151,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, vp = vnet_find_parent(hp, vdev->mp); if (IS_ERR(vp)) { - printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); + pr_err("Cannot find port parent vnet\n"); err = PTR_ERR(vp); goto err_out_put_mdesc; } @@ -1165,15 +1159,14 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); err = -ENODEV; if (!rmac) { - printk(KERN_ERR PFX "Port lacks %s property.\n", - remote_macaddr_prop); + pr_err("Port lacks %s property\n", remote_macaddr_prop); goto err_out_put_mdesc; } port = kzalloc(sizeof(*port), GFP_KERNEL); err = -ENOMEM; if (!port) { - printk(KERN_ERR PFX "Cannot allocate vnet_port.\n"); + pr_err("Cannot allocate vnet_port\n"); goto err_out_put_mdesc; } @@ -1214,9 +1207,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, dev_set_drvdata(&vdev->dev, port); - printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n", - vp->dev->name, port->raddr, - switch_port ? " switch-port" : ""); + pr_info("%s: PORT ( remote-mac %pM%s )\n", + vp->dev->name, port->raddr, switch_port ? " switch-port" : ""); vio_port_up(&port->vio); -- cgit v1.2.3 From 2244d07bfa2097cb00600da91c715a8aa547917e Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 17 Aug 2010 08:59:14 +0000 Subject: net: simplify flags for tx timestamping This patch removes the abstraction introduced by the union skb_shared_tx in the shared skb data. The access of the different union elements at several places led to some confusion about accessing the shared tx_flags e.g. in skb_orphan_try(). http://marc.info/?l=linux-netdev&m=128084897415886&w=2 Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- Documentation/networking/timestamping.txt | 22 +++++++++------- drivers/net/bfin_mac.c | 10 +++---- drivers/net/gianfar.c | 15 +++++------ drivers/net/igb/igb.h | 2 +- drivers/net/igb/igb_main.c | 11 ++++---- include/linux/skbuff.h | 44 +++++++++++-------------------- include/net/ip.h | 2 +- include/net/sock.h | 8 ++---- net/can/raw.c | 4 +-- net/core/dev.c | 6 ++--- net/core/skbuff.c | 2 +- net/ipv4/icmp.c | 4 +-- net/ipv4/ip_output.c | 6 ++--- net/ipv4/raw.c | 2 +- net/ipv4/udp.c | 4 +-- net/packet/af_packet.c | 4 +-- net/socket.c | 9 +++---- 17 files changed, 68 insertions(+), 87 deletions(-) diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index e8c8f4f06c67..98097d8cb910 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt @@ -172,15 +172,19 @@ struct skb_shared_hwtstamps { }; Time stamps for outgoing packets are to be generated as follows: -- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero. - If yes, then the driver is expected to do hardware time stamping. +- In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) + is set no-zero. If yes, then the driver is expected to do hardware time + stamping. - If this is possible for the skb and requested, then declare - that the driver is doing the time stamping by setting the field - skb_tx(skb)->in_progress non-zero. You might want to keep a pointer - to the associated skb for the next step and not free the skb. A driver - not supporting hardware time stamping doesn't do that. A driver must - never touch sk_buff::tstamp! It is used to store software generated - time stamps by the network subsystem. + that the driver is doing the time stamping by setting the flag + SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with + + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + You might want to keep a pointer to the associated skb for the next step + and not free the skb. A driver not supporting hardware time stamping doesn't + do that. A driver must never touch sk_buff::tstamp! It is used to store + software generated time stamps by the network subsystem. - As soon as the driver has sent the packet and/or obtained a hardware time stamp for it, it passes the time stamp back by calling skb_hwtstamp_tx() with the original skb, the raw @@ -191,6 +195,6 @@ Time stamps for outgoing packets are to be generated as follows: this would occur at a later time in the processing pipeline than other software time stamping and therefore could lead to unexpected deltas between time stamps. -- If the driver did not call set skb_tx(skb)->in_progress, then +- If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then dev_hard_start_xmit() checks whether software time stamping is wanted as fallback and potentially generates the time stamp. diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 012613fde3f4..7a0e4156fade 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -803,15 +803,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) { struct bfin_mac_local *lp = netdev_priv(netdev); - union skb_shared_tx *shtx = skb_tx(skb); - if (shtx->hardware) { + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { int timeout_cnt = MAX_TIMEOUT_CNT; /* When doing time stamping, keep the connection to the socket * a while longer */ - shtx->in_progress = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; /* * The timestamping is done at the EMAC module's MII/RMII interface @@ -991,7 +990,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, struct bfin_mac_local *lp = netdev_priv(dev); u16 *data; u32 data_align = (unsigned long)(skb->data) & 0x3; - union skb_shared_tx *shtx = skb_tx(skb); current_tx_ptr->skb = skb; @@ -1005,7 +1003,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, * of this field are the length of the packet payload in bytes and the higher * 4 bits are the timestamping enable field. */ - if (shtx->hardware) + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) *data |= 0x1000; current_tx_ptr->desc_a.start_addr = (u32)data; @@ -1015,7 +1013,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, } else { *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); /* enable timestamping for the sent packet */ - if (shtx->hardware) + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) *((u16 *)(current_tx_ptr->packet)) |= 0x1000; memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 3d9f958ebd2c..e6048d6ab0ea 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2048,7 +2048,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 bufaddr; unsigned long flags; unsigned int nr_frags, nr_txbds, length; - union skb_shared_tx *shtx; /* * TOE=1 frames larger than 2500 bytes may see excess delays @@ -2069,10 +2068,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txq = netdev_get_tx_queue(dev, rq); base = tx_queue->tx_bd_base; regs = tx_queue->grp->regs; - shtx = skb_tx(skb); /* check if time stamp should be generated */ - if (unlikely(shtx->hardware && priv->hwts_tx_en)) + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + priv->hwts_tx_en)) do_tstamp = 1; /* make space for additional header when fcb is needed */ @@ -2174,7 +2173,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Setup tx hardware time stamping if requested */ if (unlikely(do_tstamp)) { - shtx->in_progress = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; if (fcb == NULL) fcb = gfar_add_fcb(skb); fcb->ptp = 1; @@ -2446,7 +2445,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) int howmany = 0; u32 lstatus; size_t buflen; - union skb_shared_tx *shtx; rx_queue = priv->rx_queue[tx_queue->qindex]; bdp = tx_queue->dirty_tx; @@ -2461,8 +2459,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) * When time stamping, one additional TxBD must be freed. * Also, we need to dma_unmap_single() the TxPAL. */ - shtx = skb_tx(skb); - if (unlikely(shtx->in_progress)) + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) nr_txbds = frags + 2; else nr_txbds = frags + 1; @@ -2476,7 +2473,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) (lstatus & BD_LENGTH_MASK)) break; - if (unlikely(shtx->in_progress)) { + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { next = next_txbd(bdp, base, tx_ring_size); buflen = next->length + GMAC_FCB_LEN; } else @@ -2485,7 +2482,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, buflen, DMA_TO_DEVICE); - if (unlikely(shtx->in_progress)) { + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { struct skb_shared_hwtstamps shhwtstamps; u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); memset(&shhwtstamps, 0, sizeof(shhwtstamps)); diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 6e63d9a7fc75..44e0ff1494e0 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -143,7 +143,7 @@ struct igb_buffer { u16 next_to_watch; unsigned int bytecount; u16 gso_segs; - union skb_shared_tx shtx; + u8 tx_flags; u8 mapped_as_page; }; /* RX */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9b4e5895f5f9..985e37cf17b6 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3954,7 +3954,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb, } tx_ring->buffer_info[i].skb = skb; - tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags; + tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags; /* multiply data chunks by size of headers */ tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len; tx_ring->buffer_info[i].gso_segs = gso_segs; @@ -4088,7 +4088,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, u32 tx_flags = 0; u16 first; u8 hdr_len = 0; - union skb_shared_tx *shtx = skb_tx(skb); /* need: 1 descriptor per page, * + 2 desc gap to keep tail from touching head, @@ -4100,8 +4099,8 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, return NETDEV_TX_BUSY; } - if (unlikely(shtx->hardware)) { - shtx->in_progress = 1; + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IGB_TX_FLAGS_TSTAMP; } @@ -5319,7 +5318,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu u64 regval; /* if skb does not support hw timestamp or TX stamp not valid exit */ - if (likely(!buffer_info->shtx.hardware) || + if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) || !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) return; @@ -5500,7 +5499,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, * values must belong to this one here and therefore we don't need to * compare any of the additional attributes stored for it. * - * If nothing went wrong, then it should have a skb_shared_tx that we + * If nothing went wrong, then it should have a shared tx_flags that we * can turn into a skb_shared_hwtstamps. */ if (staterr & E1000_RXDADV_STAT_TSIP) { diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d8050382b189..f067c95cf18a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -163,26 +163,19 @@ struct skb_shared_hwtstamps { ktime_t syststamp; }; -/** - * struct skb_shared_tx - instructions for time stamping of outgoing packets - * @hardware: generate hardware time stamp - * @software: generate software time stamp - * @in_progress: device driver is going to provide - * hardware time stamp - * @prevent_sk_orphan: make sk reference available on driver level - * @flags: all shared_tx flags - * - * These flags are attached to packets as part of the - * &skb_shared_info. Use skb_tx() to get a pointer. - */ -union skb_shared_tx { - struct { - __u8 hardware:1, - software:1, - in_progress:1, - prevent_sk_orphan:1; - }; - __u8 flags; +/* Definitions for tx_flags in struct skb_shared_info */ +enum { + /* generate hardware time stamp */ + SKBTX_HW_TSTAMP = 1 << 0, + + /* generate software time stamp */ + SKBTX_SW_TSTAMP = 1 << 1, + + /* device driver is going to provide hardware time stamp */ + SKBTX_IN_PROGRESS = 1 << 2, + + /* ensure the originating sk reference is available on driver level */ + SKBTX_DRV_NEEDS_SK_REF = 1 << 3, }; /* This data is invariant across clones and lives at @@ -195,7 +188,7 @@ struct skb_shared_info { unsigned short gso_segs; unsigned short gso_type; __be32 ip6_frag_id; - union skb_shared_tx tx_flags; + __u8 tx_flags; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; @@ -587,11 +580,6 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) return &skb_shinfo(skb)->hwtstamps; } -static inline union skb_shared_tx *skb_tx(struct sk_buff *skb) -{ - return &skb_shinfo(skb)->tx_flags; -} - /** * skb_queue_empty - check if a queue is empty * @list: queue head @@ -1996,8 +1984,8 @@ extern void skb_tstamp_tx(struct sk_buff *orig_skb, static inline void sw_tx_timestamp(struct sk_buff *skb) { - union skb_shared_tx *shtx = skb_tx(skb); - if (shtx->software && !shtx->in_progress) + if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP && + !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) skb_tstamp_tx(skb, NULL); } diff --git a/include/net/ip.h b/include/net/ip.h index 890f9725d681..7691aca133db 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -53,7 +53,7 @@ struct ipcm_cookie { __be32 addr; int oif; struct ip_options *opt; - union skb_shared_tx shtx; + __u8 tx_flags; }; #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) diff --git a/include/net/sock.h b/include/net/sock.h index ac53bfbdfe16..100e43bf95fb 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1669,17 +1669,13 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, /** * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped - * @msg: outgoing packet * @sk: socket sending this packet - * @shtx: filled with instructions for time stamping + * @tx_flags: filled with instructions for time stamping * * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if * parameters are invalid. */ -extern int sock_tx_timestamp(struct msghdr *msg, - struct sock *sk, - union skb_shared_tx *shtx); - +extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); /** * sk_eat_skb - Release a skb if it is no longer needed diff --git a/net/can/raw.c b/net/can/raw.c index a10e3338f084..7d77e67e57af 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -647,12 +647,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); if (err < 0) goto free_skb; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto free_skb; /* to be able to check the received tx sock reference in raw_rcv() */ - skb_tx(skb)->prevent_sk_orphan = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; skb->dev = dev; skb->sk = sk; diff --git a/net/core/dev.c b/net/core/dev.c index 586a11cb4398..c1dc8a95f6ff 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1902,14 +1902,14 @@ static int dev_gso_segment(struct sk_buff *skb) /* * Try to orphan skb early, right before transmission by the device. - * We cannot orphan skb if tx timestamp is requested, since - * drivers need to call skb_tstamp_tx() to send the timestamp. + * We cannot orphan skb if tx timestamp is requested or the sk-reference + * is needed on driver level for other reasons, e.g. see net/can/raw.c */ static inline void skb_orphan_try(struct sk_buff *skb) { struct sock *sk = skb->sk; - if (sk && !skb_tx(skb)->flags) { + if (sk && !skb_shinfo(skb)->tx_flags) { /* skb_tx_hash() wont be able to get sk. * We copy sk_hash into skb->rxhash */ diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3a2513f0d0c3..99ef721f773d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3016,7 +3016,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, } else { /* * no hardware time stamps available, - * so keep the skb_shared_tx and only + * so keep the shared tx_flags and only * store software time stamp */ skb->tstamp = ktime_get_real(); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a0d847c7cba5..96bc7f9475a3 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -379,7 +379,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) inet->tos = ip_hdr(skb)->tos; daddr = ipc.addr = rt->rt_src; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (icmp_param->replyopts.optlen) { ipc.opt = &icmp_param->replyopts; if (ipc.opt->srr) @@ -538,7 +538,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) inet_sk(sk)->tos = tos; ipc.addr = iph->saddr; ipc.opt = &icmp_param.replyopts; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; { struct flowi fl = { diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 04b69896df5f..e807492f1777 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -953,7 +953,7 @@ alloc_new_skb: else /* only the initial fragment is time stamped */ - ipc->shtx.flags = 0; + ipc->tx_flags = 0; } if (skb == NULL) goto error; @@ -964,7 +964,7 @@ alloc_new_skb: skb->ip_summed = csummode; skb->csum = 0; skb_reserve(skb, hh_len); - *skb_tx(skb) = ipc->shtx; + skb_shinfo(skb)->tx_flags = ipc->tx_flags; /* * Find where to start putting bytes. @@ -1384,7 +1384,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar daddr = ipc.addr = rt->rt_src; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (replyopts.opt.optlen) { ipc.opt = &replyopts.opt; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 009a7b2aa1ef..1f85ef289895 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -505,7 +505,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.addr = inet->inet_saddr; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; ipc.oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 32e0bef60d0a..86e757e162ee 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -797,7 +797,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, return -EOPNOTSUPP; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (up->pending) { /* @@ -845,7 +845,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.addr = inet->inet_saddr; ipc.oif = sk->sk_bound_dev_if; - err = sock_tx_timestamp(msg, sk, &ipc.shtx); + err = sock_tx_timestamp(sk, &ipc.tx_flags); if (err) return err; if (msg->msg_controllen) { diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9a17f28b1253..3616f27b9d46 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -488,7 +488,7 @@ retry: skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto out_unlock; @@ -1209,7 +1209,7 @@ static int packet_snd(struct socket *sock, err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); if (err) goto out_free; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto out_free; diff --git a/net/socket.c b/net/socket.c index 2270b941bcc7..7848d12f5e4d 100644 --- a/net/socket.c +++ b/net/socket.c @@ -535,14 +535,13 @@ void sock_release(struct socket *sock) } EXPORT_SYMBOL(sock_release); -int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, - union skb_shared_tx *shtx) +int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) { - shtx->flags = 0; + *tx_flags = 0; if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE)) - shtx->hardware = 1; + *tx_flags |= SKBTX_HW_TSTAMP; if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) - shtx->software = 1; + *tx_flags |= SKBTX_SW_TSTAMP; return 0; } EXPORT_SYMBOL(sock_tx_timestamp); -- cgit v1.2.3 From 25aec76a3bd962f0aae1d7980ab1efa56cb24b43 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 18 Aug 2010 20:15:04 +0000 Subject: ether1: Use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the ether1_priv struct. As the new ndo_get_stats function would just return dev->stats we can omit it. This patch also removes an incorrect memset of the stats on open. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/arm/ether1.c | 34 ++++++++++++---------------------- drivers/net/arm/ether1.h | 1 - 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index b17ab5153f51..b00781c02d5d 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -68,7 +68,6 @@ static int ether1_open(struct net_device *dev); static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); static irqreturn_t ether1_interrupt(int irq, void *dev_id); static int ether1_close(struct net_device *dev); -static struct net_device_stats *ether1_getstats(struct net_device *dev); static void ether1_setmulticastlist(struct net_device *dev); static void ether1_timeout(struct net_device *dev); @@ -649,8 +648,6 @@ ether1_open (struct net_device *dev) if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) return -EAGAIN; - memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats)); - if (ether1_init_for_open (dev)) { free_irq (dev->irq, dev); return -EAGAIN; @@ -673,7 +670,7 @@ ether1_timeout(struct net_device *dev) if (ether1_init_for_open (dev)) printk (KERN_ERR "%s: unable to restart interface\n", dev->name); - priv(dev)->stats.tx_errors++; + dev->stats.tx_errors++; netif_wake_queue(dev); } @@ -802,21 +799,21 @@ again: while (nop.nop_status & STAT_COMPLETE) { if (nop.nop_status & STAT_OK) { - priv(dev)->stats.tx_packets ++; - priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS); + dev->stats.tx_packets++; + dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS); } else { - priv(dev)->stats.tx_errors ++; + dev->stats.tx_errors++; if (nop.nop_status & STAT_COLLAFTERTX) - priv(dev)->stats.collisions ++; + dev->stats.collisions++; if (nop.nop_status & STAT_NOCARRIER) - priv(dev)->stats.tx_carrier_errors ++; + dev->stats.tx_carrier_errors++; if (nop.nop_status & STAT_TXLOSTCTS) printk (KERN_WARNING "%s: cts lost\n", dev->name); if (nop.nop_status & STAT_TXSLOWDMA) - priv(dev)->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; if (nop.nop_status & STAT_COLLEXCESSIVE) - priv(dev)->stats.collisions += 16; + dev->stats.collisions += 16; } if (nop.nop_link == caddr) { @@ -879,13 +876,13 @@ ether1_recv_done (struct net_device *dev) skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); - priv(dev)->stats.rx_packets ++; + dev->stats.rx_packets++; } else - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; } else { printk(KERN_WARNING "%s: %s\n", dev->name, (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid"); - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; } nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS); @@ -939,7 +936,7 @@ ether1_interrupt (int irq, void *dev_id) printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name); ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS); writeb(CTRL_CA, REG_CONTROL); - priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */ + dev->stats.rx_dropped++; /* we suspended due to lack of buffer space */ } else printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name, ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS)); @@ -962,12 +959,6 @@ ether1_close (struct net_device *dev) return 0; } -static struct net_device_stats * -ether1_getstats (struct net_device *dev) -{ - return &priv(dev)->stats; -} - /* * Set or clear the multicast filter for this adaptor. * num_addrs == -1 Promiscuous mode, receive all packets. @@ -994,7 +985,6 @@ static const struct net_device_ops ether1_netdev_ops = { .ndo_open = ether1_open, .ndo_stop = ether1_close, .ndo_start_xmit = ether1_sendpacket, - .ndo_get_stats = ether1_getstats, .ndo_set_multicast_list = ether1_setmulticastlist, .ndo_tx_timeout = ether1_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h index c8a4b2389d85..3a5830ab3dc7 100644 --- a/drivers/net/arm/ether1.h +++ b/drivers/net/arm/ether1.h @@ -38,7 +38,6 @@ struct ether1_priv { void __iomem *base; - struct net_device_stats stats; unsigned int tx_link; unsigned int tx_head; volatile unsigned int tx_tail; -- cgit v1.2.3 From bb2537f1e76b3fb18c3fc1dff1df98ebc10af633 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 18 Aug 2010 20:15:31 +0000 Subject: ether3: Use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the ether1_priv struct. As the new ndo_get_stats function would just return dev->stats we can omit it. This patch also removes an incorrect memset of the stats on open. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/arm/ether3.c | 33 ++++++++++----------------------- drivers/net/arm/ether3.h | 1 - 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 1361b7367c28..44a8746f4014 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -81,7 +81,6 @@ static int ether3_open (struct net_device *dev); static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); static irqreturn_t ether3_interrupt (int irq, void *dev_id); static int ether3_close (struct net_device *dev); -static struct net_device_stats *ether3_getstats (struct net_device *dev); static void ether3_setmulticastlist (struct net_device *dev); static void ether3_timeout(struct net_device *dev); @@ -323,8 +322,6 @@ ether3_init_for_open(struct net_device *dev) { int i; - memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats)); - /* Reset the chip */ ether3_outw(CFG2_RESET, REG_CONFIG2); udelay(4); @@ -441,15 +438,6 @@ ether3_close(struct net_device *dev) return 0; } -/* - * Get the current statistics. This may be called with the card open or - * closed. - */ -static struct net_device_stats *ether3_getstats(struct net_device *dev) -{ - return &priv(dev)->stats; -} - /* * Set or clear promiscuous/multicast mode filter for this adaptor. * @@ -490,7 +478,7 @@ static void ether3_timeout(struct net_device *dev) local_irq_restore(flags); priv(dev)->regs.config2 |= CFG2_CTRLO; - priv(dev)->stats.tx_errors += 1; + dev->stats.tx_errors += 1; ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); priv(dev)->tx_head = priv(dev)->tx_tail = 0; @@ -509,7 +497,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) if (priv(dev)->broken) { dev_kfree_skb(skb); - priv(dev)->stats.tx_dropped ++; + dev->stats.tx_dropped++; netif_start_queue(dev); return NETDEV_TX_OK; } @@ -673,7 +661,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { } else goto dropping; } else { - struct net_device_stats *stats = &priv(dev)->stats; + struct net_device_stats *stats = &dev->stats; ether3_outw(next_ptr >> 8, REG_RECVEND); if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; @@ -685,14 +673,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { while (-- maxcnt); done: - priv(dev)->stats.rx_packets += received; + dev->stats.rx_packets += received; priv(dev)->rx_head = next_ptr; /* * If rx went off line, then that means that the buffer may be full. We * have dropped at least one packet. */ if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; ether3_outw(next_ptr, REG_RECVPTR); ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); } @@ -710,7 +698,7 @@ dropping:{ last_warned = jiffies; printk("%s: memory squeeze, dropping packet.\n", dev->name); } - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; goto done; } } @@ -743,13 +731,13 @@ static void ether3_tx(struct net_device *dev) * Update errors */ if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS))) - priv(dev)->stats.tx_packets++; + dev->stats.tx_packets++; else { - priv(dev)->stats.tx_errors ++; + dev->stats.tx_errors++; if (status & TXSTAT_16COLLISIONS) - priv(dev)->stats.collisions += 16; + dev->stats.collisions += 16; if (status & TXSTAT_BABBLED) - priv(dev)->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; } tx_tail = (tx_tail + 1) & 15; @@ -773,7 +761,6 @@ static const struct net_device_ops ether3_netdev_ops = { .ndo_open = ether3_open, .ndo_stop = ether3_close, .ndo_start_xmit = ether3_sendpacket, - .ndo_get_stats = ether3_getstats, .ndo_set_multicast_list = ether3_setmulticastlist, .ndo_tx_timeout = ether3_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h index 1921a3a07da7..2db63b08bdf3 100644 --- a/drivers/net/arm/ether3.h +++ b/drivers/net/arm/ether3.h @@ -164,7 +164,6 @@ struct dev_priv { unsigned char tx_head; /* buffer nr to insert next packet */ unsigned char tx_tail; /* buffer nr of transmitting packet */ unsigned int rx_head; /* address to fetch next packet from */ - struct net_device_stats stats; struct timer_list timer; int broken; /* 0 = ok, 1 = something went wrong */ }; -- cgit v1.2.3 From b92840900fb575004cac694e56fd0a43f54dc344 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Aug 2010 10:44:34 +0000 Subject: atm: remove a net_device_stats clear No need to clear device stats in lec_open() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/atm/lec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/atm/lec.c b/net/atm/lec.c index d98bde1a0ac8..181d70c73d70 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -220,7 +220,6 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) static int lec_open(struct net_device *dev) { netif_start_queue(dev); - memset(&dev->stats, 0, sizeof(struct net_device_stats)); return 0; } -- cgit v1.2.3 From dd57f970f91e2371040db709b3731ac34e43ccdb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Aug 2010 03:42:54 +0000 Subject: vxge: Implement 64bit stats vxge_get_stats() is racy, since it clears a block of memory (net_stats) possibly still used by other cpus. We can update this driver to full 64bit stats, since ndo_get_stats64() provides a private block to store results, and driver maintains 64bit counters already. We also remove net_stats field from struct vxge_sw_stats Signed-off-by: Eric Dumazet Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 22 +++++++--------------- drivers/net/vxge/vxge-main.h | 1 - 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index f5334b287fdb..01cdec712b64 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2914,26 +2914,18 @@ static int vxge_change_mtu(struct net_device *dev, int new_mtu) } /** - * vxge_get_stats + * vxge_get_stats64 * @dev: pointer to the device structure + * @stats: pointer to struct rtnl_link_stats64 * - * Updates the device statistics structure. This function updates the device - * statistics structure in the net_device structure and returns a pointer - * to the same. */ -static struct net_device_stats * -vxge_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 * +vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) { - struct vxgedev *vdev; - struct net_device_stats *net_stats; + struct vxgedev *vdev = netdev_priv(dev); int k; - vdev = netdev_priv(dev); - - net_stats = &vdev->stats.net_stats; - - memset(net_stats, 0, sizeof(struct net_device_stats)); - + /* net_stats already zeroed by caller */ for (k = 0; k < vdev->no_of_vpath; k++) { net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms; net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes; @@ -3102,7 +3094,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static const struct net_device_ops vxge_netdev_ops = { .ndo_open = vxge_open, .ndo_stop = vxge_close, - .ndo_get_stats = vxge_get_stats, + .ndo_get_stats64 = vxge_get_stats64, .ndo_start_xmit = vxge_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = vxge_set_multicast, diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 2e3b064b8e4b..d4be07eaacd7 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -172,7 +172,6 @@ struct vxge_msix_entry { struct vxge_sw_stats { /* Network Stats (interface stats) */ - struct net_device_stats net_stats; /* Tx */ u64 tx_frms; -- cgit v1.2.3 From 6f0bee16d0840c272229f2038a23a9a02dfc803d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Aug 2010 03:13:08 +0000 Subject: slip: fix get_stats() method Use integrated net_device_stats instead of a static one, and make sure no transient values are feeded. ndo_get_stats() can be called by concurrent cpus. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/slip.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/net/slip.c b/drivers/net/slip.c index fa434fb8fb7c..d5a36f5417cc 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -561,36 +561,36 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu) static struct net_device_stats * sl_get_stats(struct net_device *dev) { - static struct net_device_stats stats; + struct net_device_stats *stats = &dev->stats; struct slip *sl = netdev_priv(dev); + unsigned long c_rx_dropped = 0; #ifdef SL_INCLUDE_CSLIP - struct slcompress *comp; -#endif + unsigned long c_rx_fifo_errors = 0; + unsigned long c_tx_fifo_errors = 0; + unsigned long c_collisions = 0; + struct slcompress *comp = sl->slcomp; - memset(&stats, 0, sizeof(struct net_device_stats)); - - stats.rx_packets = sl->rx_packets; - stats.tx_packets = sl->tx_packets; - stats.rx_bytes = sl->rx_bytes; - stats.tx_bytes = sl->tx_bytes; - stats.rx_dropped = sl->rx_dropped; - stats.tx_dropped = sl->tx_dropped; - stats.tx_errors = sl->tx_errors; - stats.rx_errors = sl->rx_errors; - stats.rx_over_errors = sl->rx_over_errors; -#ifdef SL_INCLUDE_CSLIP - stats.rx_fifo_errors = sl->rx_compressed; - stats.tx_fifo_errors = sl->tx_compressed; - stats.collisions = sl->tx_misses; - comp = sl->slcomp; if (comp) { - stats.rx_fifo_errors += comp->sls_i_compressed; - stats.rx_dropped += comp->sls_i_tossed; - stats.tx_fifo_errors += comp->sls_o_compressed; - stats.collisions += comp->sls_o_misses; + c_rx_fifo_errors = comp->sls_i_compressed; + c_rx_dropped = comp->sls_i_tossed; + c_tx_fifo_errors = comp->sls_o_compressed; + c_collisions = comp->sls_o_misses; } -#endif /* CONFIG_INET */ - return (&stats); + stats->rx_fifo_errors = sl->rx_compressed + c_rx_fifo_errors; + stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors; + stats->collisions = sl->tx_misses + c_collisions; +#endif + + stats->rx_packets = sl->rx_packets; + stats->tx_packets = sl->tx_packets; + stats->rx_bytes = sl->rx_bytes; + stats->tx_bytes = sl->tx_bytes; + stats->rx_dropped = sl->rx_dropped + c_rx_dropped; + stats->tx_dropped = sl->tx_dropped; + stats->tx_errors = sl->tx_errors; + stats->rx_errors = sl->rx_errors; + stats->rx_over_errors = sl->rx_over_errors; + return stats; } /* Netdevice register callback */ -- cgit v1.2.3 From 357e8b5f723ba9e1d0a0f8ffb1361d607e43e19a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 18 Aug 2010 01:22:49 +0000 Subject: xilinx_emaclite: netpoll support Netconsole requires poll support. Signed-off-by: Michal Simek Signed-off-by: David S. Miller --- drivers/net/xilinx_emaclite.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index ecbbb688eba0..71122ee4e830 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1269,6 +1269,16 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev) return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void +xemaclite_poll_controller(struct net_device *ndev) +{ + disable_irq(ndev->irq); + xemaclite_interrupt(ndev->irq, ndev); + enable_irq(ndev->irq); +} +#endif + static struct net_device_ops xemaclite_netdev_ops = { .ndo_open = xemaclite_open, .ndo_stop = xemaclite_close, @@ -1276,6 +1286,9 @@ static struct net_device_ops xemaclite_netdev_ops = { .ndo_set_mac_address = xemaclite_set_mac_address, .ndo_tx_timeout = xemaclite_tx_timeout, .ndo_get_stats = xemaclite_get_stats, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xemaclite_poll_controller, +#endif }; /* Match table for OF platform binding */ -- cgit v1.2.3 From 083fc582b8752c64b0ae73935ddb45a1dd794b4c Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 19 Aug 2010 13:33:16 +0000 Subject: ixgbe: cleanup ixgbe_get_drvinfo to be extra careful with buffer boundaries Make the code in ixgbe_get_drvinfo more protected against buffer overflow boundaries by using snprintf and sizeof with snprintf. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index dcebc82c6f4d..fb6d8e88eb05 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -820,16 +820,19 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); char firmware_version[32]; - strncpy(drvinfo->driver, ixgbe_driver_name, 32); - strncpy(drvinfo->version, ixgbe_driver_version, 32); - - sprintf(firmware_version, "%d.%d-%d", - (adapter->eeprom_version & 0xF000) >> 12, - (adapter->eeprom_version & 0x0FF0) >> 4, - adapter->eeprom_version & 0x000F); - - strncpy(drvinfo->fw_version, firmware_version, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); + strncpy(drvinfo->version, ixgbe_driver_version, + sizeof(drvinfo->version)); + + snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", + (adapter->eeprom_version & 0xF000) >> 12, + (adapter->eeprom_version & 0x0FF0) >> 4, + adapter->eeprom_version & 0x000F); + + strncpy(drvinfo->fw_version, firmware_version, + sizeof(drvinfo->fw_version)); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); drvinfo->n_stats = IXGBE_STATS_LEN; drvinfo->testinfo_len = IXGBE_TEST_LEN; drvinfo->regdump_len = ixgbe_get_regs_len(netdev); -- cgit v1.2.3 From d716a7d88549c99f9afbfc1f75dda1c390e2dc3a Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:33:41 +0000 Subject: ixgbe: remove redundant DMA alignment code This patch removes the redundant DMA alignment code from the Rx buffer allocation path. This code is no longer necessary since all x86 buffers are now DMA aligned due to recent changes to NET_IP_ALIGN and NET_SKB_PAD. It also moves the setting of the Rx queue value into the allocation path since it is more likely that the queue mapping will still be in the cache at the time of allocation. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e32af434cc9d..5dceaf3dbb7f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -955,7 +955,6 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, bool is_vlan = (status & IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - skb_record_rx_queue(skb, ring->queue_index); if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) vlan_gro_receive(napi, adapter->vlgrp, tag, skb); @@ -1037,10 +1036,12 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, int cleaned_count) { + struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; unsigned int i; + unsigned int bufsz = rx_ring->rx_buf_len; i = rx_ring->next_to_use; bi = &rx_ring->rx_buffer_info[i]; @@ -1051,7 +1052,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->page_dma && (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) { if (!bi->page) { - bi->page = alloc_page(GFP_ATOMIC); + bi->page = netdev_alloc_page(netdev); if (!bi->page) { adapter->alloc_rx_page_failed++; goto no_buffers; @@ -1069,22 +1070,21 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, } if (!bi->skb) { - struct sk_buff *skb; - /* netdev_alloc_skb reserves 32 bytes up front!! */ - uint bufsz = rx_ring->rx_buf_len + SMP_CACHE_BYTES; - skb = netdev_alloc_skb(adapter->netdev, bufsz); + struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, + bufsz); + bi->skb = skb; if (!skb) { adapter->alloc_rx_buff_failed++; goto no_buffers; } + /* initialize queue mapping */ + skb_record_rx_queue(skb, rx_ring->queue_index); + } - /* advance the data pointer to the next cache line */ - skb_reserve(skb, (PTR_ALIGN(skb->data, SMP_CACHE_BYTES) - - skb->data)); - - bi->skb = skb; - bi->dma = dma_map_single(&pdev->dev, skb->data, + if (!bi->dma) { + bi->dma = dma_map_single(&pdev->dev, + bi->skb->data, rx_ring->rx_buf_len, DMA_FROM_DEVICE); } -- cgit v1.2.3 From 67ebd79141e2dd503b0bc4898d06d07f07fc2635 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:34:04 +0000 Subject: ixgbe: move setting of GSO size for 82598 into ixgbe_configure_dcb We are unnecessarily modifying the GSO size for all HW when we don't need to. The code can be simplified by moving the check for DCB and the adjustment of the GSO size for 82598 into ixgbe_configure_dcb. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5dceaf3dbb7f..fffb1ce4f6ea 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3157,6 +3157,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) u32 txdctl; int i, j; + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) { + if (hw->mac.type == ixgbe_mac_82598EB) + netif_set_gso_max_size(adapter->netdev, 65536); + return; + } + + if (hw->mac.type == ixgbe_mac_82598EB) + netif_set_gso_max_size(adapter->netdev, 32768); + ixgbe_dcb_check_config(&adapter->dcb_cfg); ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); @@ -3188,17 +3197,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) ixgbe_restore_vlan(adapter); #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - if (hw->mac.type == ixgbe_mac_82598EB) - netif_set_gso_max_size(netdev, 32768); - else - netif_set_gso_max_size(netdev, 65536); - ixgbe_configure_dcb(adapter); - } else { - netif_set_gso_max_size(netdev, 65536); - } -#else - netif_set_gso_max_size(netdev, 65536); + ixgbe_configure_dcb(adapter); #endif #ifdef IXGBE_FCOE -- cgit v1.2.3 From 179b4096e25c190fc987832e0037b40507cc7ca0 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:34:27 +0000 Subject: ixgbe: combine two modifications of TXDCTL into one In ixgbe_up_complete we were doing a read-modify-write of TXDCTL followed by another one just a few lines further down. Instead of performing two separate read-modify-writes it would make more sense to combine the two into one. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fffb1ce4f6ea..5d90f699fa78 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3411,6 +3411,12 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); } + if (hw->mac.type == ixgbe_mac_82599EB) { + /* DMATXCTL.EN must be set after all Tx queue config is done */ + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + } for (i = 0; i < adapter->num_tx_queues; i++) { j = adapter->tx_ring[i]->reg_idx; txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); @@ -3421,18 +3427,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* enable WTHRESH=8 descriptors, to encourage burst writeback */ txdctl |= (8 << 16); } - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); - } - - if (hw->mac.type == ixgbe_mac_82599EB) { - /* DMATXCTL.EN must be set after all Tx queue config is done */ - dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); - dmatxctl |= IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); - } - for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); txdctl |= IXGBE_TXDCTL_ENABLE; IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); if (hw->mac.type == ixgbe_mac_82599EB) { -- cgit v1.2.3 From 120ff942cc6357b08fc817d89a5458038942edeb Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:34:50 +0000 Subject: ixgbe: move configuration of the MTQC register into it's own function This patch moves the configuration of the MTQC register into it's own function call similar to ixgbe_setup_mrqc. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 73 +++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5d90f699fa78..c4e42075335a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2424,6 +2424,45 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) e_info(hw, "Legacy interrupt IVAR setup done\n"); } +static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rttdcs; + u32 mask; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + /* disable the arbiter while setting MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + + /* set transmit pool layout */ + mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED); + switch (adapter->flags & mask) { + + case (IXGBE_FLAG_SRIOV_ENABLED): + IXGBE_WRITE_REG(hw, IXGBE_MTQC, + (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF)); + break; + + case (IXGBE_FLAG_DCB_ENABLED): + /* We enable 8 traffic classes, DCB only */ + IXGBE_WRITE_REG(hw, IXGBE_MTQC, + (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); + break; + + default: + IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); + break; + } + + /* re-enable the arbiter */ + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); +} + /** * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset * @adapter: board private structure @@ -2475,39 +2514,7 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) } } - if (hw->mac.type == ixgbe_mac_82599EB) { - u32 rttdcs; - u32 mask; - - /* disable the arbiter while setting MTQC */ - rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); - rttdcs |= IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); - - /* set transmit pool layout */ - mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED); - switch (adapter->flags & mask) { - - case (IXGBE_FLAG_SRIOV_ENABLED): - IXGBE_WRITE_REG(hw, IXGBE_MTQC, - (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF)); - break; - - case (IXGBE_FLAG_DCB_ENABLED): - /* We enable 8 traffic classes, DCB only */ - IXGBE_WRITE_REG(hw, IXGBE_MTQC, - (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); - break; - - default: - IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); - break; - } - - /* re-eable the arbiter */ - rttdcs &= ~IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); - } + ixgbe_setup_mtqc(adapter); } #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 -- cgit v1.2.3 From 43e69bf0f0df2691001dbd055ab8d4f795d1900c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:35:12 +0000 Subject: ixgbe: move Tx ring configuration into a separate function This patch moves the Tx ring configuration into a separate function. In addition the function drops the setting of the head writeback RO bit since head writeback is no longer used within ixgbe. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 69 ++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c4e42075335a..37d1f64a34d5 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2424,6 +2424,32 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) e_info(hw, "Legacy interrupt IVAR setup done\n"); } +/** + * ixgbe_configure_tx_ring - Configure 8259x Tx ring after Reset + * @adapter: board private structure + * @ring: structure containing ring specific data + * + * Configure the Tx descriptor ring after a reset. + **/ + static void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 tdba = ring->dma; + u16 reg_idx = ring->reg_idx; + + IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx), + (tdba & DMA_BIT_MASK(32))); + IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_tx_desc)); + IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0); + ring->head = IXGBE_TDH(reg_idx); + ring->tail = IXGBE_TDT(reg_idx); + +} + static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -2471,48 +2497,11 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) **/ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) { - u64 tdba; - struct ixgbe_hw *hw = &adapter->hw; - u32 i, j, tdlen, txctrl; + u32 i; /* Setup the HW Tx Head and Tail descriptor pointers */ - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *ring = adapter->tx_ring[i]; - j = ring->reg_idx; - tdba = ring->dma; - tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc); - IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j), - (tdba & DMA_BIT_MASK(32))); - IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen); - IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); - adapter->tx_ring[i]->head = IXGBE_TDH(j); - adapter->tx_ring[i]->tail = IXGBE_TDT(j); - /* - * Disable Tx Head Writeback RO bit, since this hoses - * bookkeeping if things aren't delivered in order. - */ - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); - break; - case ixgbe_mac_82599EB: - default: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j)); - break; - } - txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); - break; - case ixgbe_mac_82599EB: - default: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl); - break; - } - } + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); ixgbe_setup_mtqc(adapter); } -- cgit v1.2.3 From 05abb126c148b081ee9da5a611960e2a80205ea2 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:35:41 +0000 Subject: ixgbe: consolidate all setting of MRQC into one function This change simplifies the configuration of MRQC by consolidating the setting of it into one function. As such the register is no longer set in multiple places which should make any future changes easier to work with. In addition we can combine RSS related register writes into the call since enabling all of those bits without enabling RSS itself in MRQC should have no effect. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 100 ++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 57 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 37d1f64a34d5..f5d890239ac6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2545,20 +2545,46 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl); } -static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) +static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) { - u32 mrqc = 0; + struct ixgbe_hw *hw = &adapter->hw; + static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, + 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, + 0x6A3E67EA, 0x14364D17, 0x3BED200D}; + u32 mrqc = 0, reta = 0; + u32 rxcsum; + int i, j; int mask; - if (!(adapter->hw.mac.type == ixgbe_mac_82599EB)) - return mrqc; + /* Fill out hash function seeds */ + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]); + + /* Fill out redirection table */ + for (i = 0, j = 0; i < 128; i++, j++) { + if (j == adapter->ring_feature[RING_F_RSS].indices) + j = 0; + /* reta = 4-byte sliding window of + * 0x00..(indices-1)(indices-1)00..etc. */ + reta = (reta << 8) | (j * 0x11); + if ((i & 3) == 3) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); + } + + /* Disable indicating checksum in descriptor, enables RSS hash */ + rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + rxcsum |= IXGBE_RXCSUM_PCSD; + IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); - mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + mask = adapter->flags & IXGBE_FLAG_RSS_ENABLED; + else + mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED #ifdef CONFIG_IXGBE_DCB - | IXGBE_FLAG_DCB_ENABLED + | IXGBE_FLAG_DCB_ENABLED #endif - | IXGBE_FLAG_SRIOV_ENABLED - ); + | IXGBE_FLAG_SRIOV_ENABLED + ); switch (mask) { case (IXGBE_FLAG_RSS_ENABLED): @@ -2576,7 +2602,13 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) break; } - return mrqc; + /* Perform hash on these packet types */ + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 + | IXGBE_MRQC_RSS_FIELD_IPV4_TCP + | IXGBE_MRQC_RSS_FIELD_IPV6 + | IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } /** @@ -2637,12 +2669,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) struct net_device *netdev = adapter->netdev; int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; int i, j; - u32 rdlen, rxctrl, rxcsum; - static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, - 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, - 0x6A3E67EA, 0x14364D17, 0x3BED200D}; + u32 rdlen, rxctrl; u32 fctrl, hlreg0; - u32 reta = 0, mrqc = 0; u32 rdrxctl; int rx_buf_len; @@ -2774,33 +2802,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) } /* Program MRQC for the distribution of queues */ - mrqc = ixgbe_setup_mrqc(adapter); - - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - /* Fill out redirection table */ - for (i = 0, j = 0; i < 128; i++, j++) { - if (j == adapter->ring_feature[RING_F_RSS].indices) - j = 0; - /* reta = 4-byte sliding window of - * 0x00..(indices-1)(indices-1)00..etc. */ - reta = (reta << 8) | (j * 0x11); - if ((i & 3) == 3) - IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); - } - - /* Fill out hash function seeds */ - for (i = 0; i < 10; i++) - IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]); - - if (hw->mac.type == ixgbe_mac_82598EB) - mrqc |= IXGBE_MRQC_RSSEN; - /* Perform hash on these packet types */ - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 - | IXGBE_MRQC_RSS_FIELD_IPV4_TCP - | IXGBE_MRQC_RSS_FIELD_IPV6 - | IXGBE_MRQC_RSS_FIELD_IPV6_TCP; - } - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + ixgbe_setup_mrqc(adapter); if (adapter->num_vfs) { u32 reg; @@ -2816,22 +2818,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg); } - rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); - - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED || - adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) { - /* Disable indicating checksum in descriptor, enables - * RSS hash */ - rxcsum |= IXGBE_RXCSUM_PCSD; - } - if (!(rxcsum & IXGBE_RXCSUM_PCSD)) { - /* Enable IPv4 payload checksum for UDP fragments - * if PCSD is not set */ - rxcsum |= IXGBE_RXCSUM_IPPCSE; - } - - IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); - if (hw->mac.type == ixgbe_mac_82599EB) { rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; -- cgit v1.2.3 From acd37177cc2e034ecb6cbb784a8b998229fa85c4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:36:05 +0000 Subject: ixgbe: pull ring configuration into it's own function These changes add ixgbe_configure_rx_ring which is used to setup the base function pointers for the ring. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f5d890239ac6..ddabe14bbbca 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2655,6 +2655,23 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl); } +static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 rdba = ring->dma; + u16 reg_idx = ring->reg_idx; + + IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); + IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_rx_desc)); + IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); + ring->head = IXGBE_RDH(reg_idx); + ring->tail = IXGBE_RDT(reg_idx); +} + /** * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset * @adapter: board private structure @@ -2663,13 +2680,12 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) **/ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) { - u64 rdba; struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_ring *rx_ring; struct net_device *netdev = adapter->netdev; int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int i, j; - u32 rdlen, rxctrl; + int i; + u32 rxctrl; u32 fctrl, hlreg0; u32 rdrxctl; int rx_buf_len; @@ -2718,7 +2734,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) #endif IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); - rdlen = adapter->rx_ring[0]->count * sizeof(union ixgbe_adv_rx_desc); /* disable receives while setting up the descriptors */ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); @@ -2729,15 +2744,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) */ for (i = 0; i < adapter->num_rx_queues; i++) { rx_ring = adapter->rx_ring[i]; - rdba = rx_ring->dma; - j = rx_ring->reg_idx; - IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32))); - IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen); - IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); - rx_ring->head = IXGBE_RDH(j); - rx_ring->tail = IXGBE_RDT(j); rx_ring->rx_buf_len = rx_buf_len; if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) @@ -2758,6 +2764,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) } #endif /* IXGBE_FCOE */ + ixgbe_configure_rx_ring(adapter, rx_ring); ixgbe_configure_srrctl(adapter, rx_ring); } -- cgit v1.2.3 From 486545216472d67c16e3d3d60c5f21f60959c855 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:36:27 +0000 Subject: ixgbe: pull PSRTYPE configuration into a separate function The configuration of PSRTYPE was being done conditionally on if packet split is enabled or not. It can be configured always since it will not have any effect when packet split is not enabled. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index ddabe14bbbca..88e6936a1579 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2672,6 +2672,29 @@ static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, ring->tail = IXGBE_RDT(reg_idx); } +static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int p; + + /* PSRTYPE must be initialized in non 82598 adapters */ + u32 psrtype = IXGBE_PSRTYPE_TCPHDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_L2HDR | + IXGBE_PSRTYPE_IPV6HDR; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) + psrtype |= (adapter->num_rx_queues_per_pool << 29); + + for (p = 0; p < adapter->num_rx_pools; p++) + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(adapter->num_vfs + p), + psrtype); +} + /** * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset * @adapter: board private structure @@ -2690,6 +2713,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) u32 rdrxctl; int rx_buf_len; + ixgbe_setup_psrtype(adapter); + /* Decide whether to use packet split mode or not */ /* Do not use packet split if we're in SR-IOV Mode */ if (!adapter->num_vfs) @@ -2698,17 +2723,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) /* Set the RX buffer length according to the mode */ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { rx_buf_len = IXGBE_RX_HDR_SIZE; - if (hw->mac.type == ixgbe_mac_82599EB) { - /* PSRTYPE must be initialized in 82599 */ - u32 psrtype = IXGBE_PSRTYPE_TCPHDR | - IXGBE_PSRTYPE_UDPHDR | - IXGBE_PSRTYPE_IPV4HDR | - IXGBE_PSRTYPE_IPV6HDR | - IXGBE_PSRTYPE_L2HDR; - IXGBE_WRITE_REG(hw, - IXGBE_PSRTYPE(adapter->num_vfs), - psrtype); - } } else { if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && (netdev->mtu <= ETH_DATA_LEN)) -- cgit v1.2.3 From f5dc442b4671e2961c2e5bb3e16a86ce7da86cd3 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:36:49 +0000 Subject: ixgbe: combine accesses to FCTRL register into ixgbe_set_rx_mode We are accessing the FCTRL register in multiple spots in the init path and we can simplify things by combining the configuration all into ixgbe_set_rx_mode. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 88e6936a1579..b7553643f9ad 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2709,7 +2709,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; int i; u32 rxctrl; - u32 fctrl, hlreg0; + u32 hlreg0; u32 rdrxctl; int rx_buf_len; @@ -2731,12 +2731,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) rx_buf_len = ALIGN(max_frame, 1024); } - fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - fctrl |= IXGBE_FCTRL_BAM; - fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ - fctrl |= IXGBE_FCTRL_PMCF; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl); - hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); if (adapter->netdev->mtu <= ETH_DATA_LEN) hlreg0 &= ~IXGBE_HLREG0_JUMBOEN; @@ -3055,6 +3049,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev) fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + /* set all bits that we expect to always be set */ + fctrl |= IXGBE_FCTRL_BAM; + fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ + fctrl |= IXGBE_FCTRL_PMCF; + /* clear the bits we are changing the status of */ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); -- cgit v1.2.3 From 1395807091300b84789316cad2a9142b58f9092a Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:37:21 +0000 Subject: ixgbe: bump PS header size to 512 bytes Bump the header size for packet split to 512 bytes since this makes the best use of the 1k buffer that is allocated for any skb 512 bytes or smaller. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 9e15eb93860e..7233fef7e9b8 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -69,15 +69,20 @@ #define IXGBE_MAX_FCPAUSE 0xFFFF /* Supported Rx Buffer Sizes */ -#define IXGBE_RXBUFFER_64 64 /* Used for packet split */ -#define IXGBE_RXBUFFER_128 128 /* Used for packet split */ -#define IXGBE_RXBUFFER_256 256 /* Used for packet split */ +#define IXGBE_RXBUFFER_512 512 /* Used for packet split */ #define IXGBE_RXBUFFER_2048 2048 #define IXGBE_RXBUFFER_4096 4096 #define IXGBE_RXBUFFER_8192 8192 #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ -#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256 +/* + * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we + * reserve 2 more, and skb_shared_info adds an additional 384 bytes more, + * this adds up to 512 bytes of extra data meaning the smallest allocation + * we could have is 1K. + * i.e. RXBUFFER_512 --> size-1024 slab + */ +#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512 #define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) -- cgit v1.2.3 From 826437d3de43174a8199776b5c1178bafa0b6634 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:37:48 +0000 Subject: ixgbe: remove redundant configuration of vmolr, rename generic variable The vmolr is configured already in ixgbe_set_rx_mode for the PF so there is no need to set it again in ixgbe_configure_rx. Instead of using the variable name reg, it is easier to just rename it to gcr_ext to reflect the register contents that the variable holds. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b7553643f9ad..520b95fc4d41 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2709,7 +2709,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; int i; u32 rxctrl; - u32 hlreg0; + u32 hlreg0, gcr_ext; u32 rdrxctl; int rx_buf_len; @@ -2813,24 +2813,21 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift)); IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift)); IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); - ixgbe_set_vmolr(hw, adapter->num_vfs, true); } /* Program MRQC for the distribution of queues */ ixgbe_setup_mrqc(adapter); if (adapter->num_vfs) { - u32 reg; - /* Map PF MAC address in RAR Entry 0 to first pool * following VFs */ hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs); /* Set up VF register offsets for selected VT Mode, i.e. * 64 VFs for SR-IOV */ - reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); - reg |= IXGBE_GCR_EXT_SRIOV; - IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg); + gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + gcr_ext |= IXGBE_GCR_EXT_SRIOV; + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); } if (hw->mac.type == ixgbe_mac_82599EB) { -- cgit v1.2.3 From 477de6ed027dbbeb0424a4d1a978429037287d22 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:38:11 +0000 Subject: ixgbe: Move max frame size and Rx buffer length configuration into a function This change consolidates all of the Rx max frame size and Rx buffer length configuration into a single function. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 108 +++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 520b95fc4d41..841ef9827ec6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2695,25 +2695,15 @@ static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) psrtype); } -/** - * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset - * @adapter: board private structure - * - * Configure the Rx unit of the MAC after a reset. - **/ -static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) +static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_ring *rx_ring; struct net_device *netdev = adapter->netdev; int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int i; - u32 rxctrl; - u32 hlreg0, gcr_ext; - u32 rdrxctl; int rx_buf_len; - - ixgbe_setup_psrtype(adapter); + struct ixgbe_ring *rx_ring; + int i; + u32 mhadd, hlreg0; /* Decide whether to use packet split mode or not */ /* Do not use packet split if we're in SR-IOV Mode */ @@ -2728,23 +2718,28 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else - rx_buf_len = ALIGN(max_frame, 1024); + rx_buf_len = ALIGN(max_frame + VLAN_HLEN, 1024); } - hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); - if (adapter->netdev->mtu <= ETH_DATA_LEN) - hlreg0 &= ~IXGBE_HLREG0_JUMBOEN; - else - hlreg0 |= IXGBE_HLREG0_JUMBOEN; #ifdef IXGBE_FCOE - if (netdev->features & NETIF_F_FCOE_MTU) - hlreg0 |= IXGBE_HLREG0_JUMBOEN; -#endif - IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); + /* adjust max frame to be able to do baby jumbo for FCoE */ + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE)) + max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; - /* disable receives while setting up the descriptors */ - rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); +#endif /* IXGBE_FCOE */ + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); + if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { + mhadd &= ~IXGBE_MHADD_MFS_MASK; + mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; + + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); + } + + hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); + /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */ + hlreg0 |= IXGBE_HLREG0_JUMBOEN; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); /* * Setup the HW Rx Head and Tail Descriptor Pointers and @@ -2760,7 +2755,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; #ifdef IXGBE_FCOE - if (netdev->features & NETIF_F_FCOE_MTU) { + if (netdev->features & NETIF_F_FCOE_MTU) + { struct ixgbe_ring_feature *f; f = &adapter->ring_feature[RING_F_FCOE]; if ((i >= f->mask) && (i < f->mask + f->indices)) { @@ -2770,8 +2766,41 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_FCOE_JUMBO_FRAME_SIZE; } } - #endif /* IXGBE_FCOE */ + } + +} + +/** + * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Rx unit of the MAC after a reset. + **/ +static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring *rx_ring; + int i; + u32 rxctrl; + u32 gcr_ext; + u32 rdrxctl; + + /* disable receives while setting up the descriptors */ + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); + + ixgbe_setup_psrtype(adapter); + + /* set_rx_buffer_len must be called before ring initialization */ + ixgbe_set_rx_buffer_len(adapter); + + /* + * Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring + */ + for (i = 0; i < adapter->num_rx_queues; i++) { + rx_ring = adapter->rx_ring[i]; ixgbe_configure_rx_ring(adapter, rx_ring); ixgbe_configure_srrctl(adapter, rx_ring); } @@ -3322,13 +3351,11 @@ static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, static int ixgbe_up_complete(struct ixgbe_adapter *adapter) { - struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; int i, j = 0; int num_rx_rings = adapter->num_rx_queues; int err; - int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - u32 txdctl, rxdctl, mhadd; + u32 txdctl, rxdctl; u32 dmatxctl; u32 gpie; u32 ctrl_ext; @@ -3395,21 +3422,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); } -#ifdef IXGBE_FCOE - /* adjust max frame to be able to do baby jumbo for FCoE */ - if ((netdev->features & NETIF_F_FCOE_MTU) && - (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE)) - max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; - -#endif /* IXGBE_FCOE */ - mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); - if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { - mhadd &= ~IXGBE_MHADD_MFS_MASK; - mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; - - IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); - } - if (hw->mac.type == ixgbe_mac_82599EB) { /* DMATXCTL.EN must be set after all Tx queue config is done */ dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); @@ -3522,7 +3534,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) &(adapter->tx_ring[i]->reinit_state)); /* enable transmits */ - netif_tx_start_all_queues(netdev); + netif_tx_start_all_queues(adapter->netdev); /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ -- cgit v1.2.3 From 7367096a43259c9b461ec3120dcaaf674a092132 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:38:34 +0000 Subject: ixgbe: move all Rx DMA control register writes to one central location This change moves all of the Rx DMA control register writes to one central location. This should help to avoid accidentally overwriting existing settings. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 91 ++++++++++++++++++++++-------------------- drivers/net/ixgbe/ixgbe_type.h | 2 + 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 841ef9827ec6..f8cdc992f24d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2616,25 +2616,26 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) * @adapter: address of board private structure * @index: index of ring to set **/ -static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) +static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) { - struct ixgbe_ring *rx_ring; struct ixgbe_hw *hw = &adapter->hw; - int j; u32 rscctrl; int rx_buf_len; + u16 reg_idx = ring->reg_idx; + + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) + return; - rx_ring = adapter->rx_ring[index]; - j = rx_ring->reg_idx; - rx_buf_len = rx_ring->rx_buf_len; - rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j)); + rx_buf_len = ring->rx_buf_len; + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); rscctrl |= IXGBE_RSCCTL_RSCEN; /* * we must limit the number of descriptors so that the * total size of max desc * buf_len is not greater * than 65535 */ - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring->flags & IXGBE_RING_RX_PS_ENABLED) { #if (MAX_SKB_FRAGS > 16) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; #elif (MAX_SKB_FRAGS > 8) @@ -2652,7 +2653,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) else rscctrl |= IXGBE_RSCCTL_MAXDESC_4; } - IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl); + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); } static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, @@ -2771,6 +2772,42 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) } +static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + /* + * For VMDq support of different descriptor types or + * buffer sizes through the use of multiple SRRCTL + * registers, RDRXCTL.MVMEN must be set to 1 + * + * also, the manual doesn't mention it clearly but DCA hints + * will only use queue 0's tags unless this bit is set. Side + * effects of setting this bit are only that SRRCTL must be + * fully programmed [0..15] + */ + rdrxctl |= IXGBE_RDRXCTL_MVMEN; + break; + case ixgbe_mac_82599EB: + /* Disable RSC for ACK packets */ + IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, + (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + /* hardware requires some bits to be set by default */ + rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX); + rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + break; + default: + /* We should do nothing since we don't know this hardware */ + return; + } + + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); +} + /** * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset * @adapter: board private structure @@ -2784,13 +2821,13 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) int i; u32 rxctrl; u32 gcr_ext; - u32 rdrxctl; /* disable receives while setting up the descriptors */ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); ixgbe_setup_psrtype(adapter); + ixgbe_setup_rdrxctl(adapter); /* set_rx_buffer_len must be called before ring initialization */ ixgbe_set_rx_buffer_len(adapter); @@ -2803,22 +2840,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) rx_ring = adapter->rx_ring[i]; ixgbe_configure_rx_ring(adapter, rx_ring); ixgbe_configure_srrctl(adapter, rx_ring); - } - - if (hw->mac.type == ixgbe_mac_82598EB) { - /* - * For VMDq support of different descriptor types or - * buffer sizes through the use of multiple SRRCTL - * registers, RDRXCTL.MVMEN must be set to 1 - * - * also, the manual doesn't mention it clearly but DCA hints - * will only use queue 0's tags unless this bit is set. Side - * effects of setting this bit are only that SRRCTL must be - * fully programmed [0..15] - */ - rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); - rdrxctl |= IXGBE_RDRXCTL_MVMEN; - IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); + ixgbe_configure_rscctl(adapter, rx_ring); } if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { @@ -2858,23 +2880,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) gcr_ext |= IXGBE_GCR_EXT_SRIOV; IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); } - - if (hw->mac.type == ixgbe_mac_82599EB) { - rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); - rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; - rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; - IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); - } - - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - /* Enable 82599 HW-RSC */ - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_configure_rscctl(adapter, i); - - /* Disable RSC for ACK packets */ - IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, - (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); - } } static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 9587d975d66c..d3cc6ce7c973 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -871,6 +871,8 @@ #define IXGBE_RDRXCTL_MVMEN 0x00000020 #define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */ #define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */ +#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */ +#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */ /* RQTC Bit Masks and Shifts */ #define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) -- cgit v1.2.3 From f5b4a52e81d46b51ba07a983036739dc0c2c6c1c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:38:57 +0000 Subject: ixgbe: Move virtualization config into a separate function This change moves the configuration that was done in configure_rx into a separate virtualization configuration function. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 84 +++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f8cdc992f24d..d358beff57fc 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2696,6 +2696,48 @@ static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) psrtype); } +static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 gcr_ext; + u32 vt_reg_bits; + u32 reg_offset, vf_shift; + u32 vmdctl; + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return; + + vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); + vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN | IXGBE_VT_CTL_REPLEN; + vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT); + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits); + + vf_shift = adapter->num_vfs % 32; + reg_offset = (adapter->num_vfs > 32) ? 1 : 0; + + /* Enable only the PF's pool for Tx/Rx */ + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift)); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), 0); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift)); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), 0); + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + + /* Map PF MAC address in RAR Entry 0 to first pool following VFs */ + hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs); + + /* + * Set up VF register offsets for selected VT Mode, + * i.e. 32 or 64 VFs for SR-IOV + */ + gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + gcr_ext |= IXGBE_GCR_EXT_MSIX_EN; + gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64; + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); + + /* enable Tx loopback for VF/PF communication */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); +} + static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -2820,7 +2862,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) struct ixgbe_ring *rx_ring; int i; u32 rxctrl; - u32 gcr_ext; /* disable receives while setting up the descriptors */ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); @@ -2829,6 +2870,10 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) ixgbe_setup_psrtype(adapter); ixgbe_setup_rdrxctl(adapter); + /* Program MRQC for the distribution of queues */ + ixgbe_setup_mrqc(adapter); + ixgbe_configure_virtualization(adapter); + /* set_rx_buffer_len must be called before ring initialization */ ixgbe_set_rx_buffer_len(adapter); @@ -2843,43 +2888,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) ixgbe_configure_rscctl(adapter, rx_ring); } - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - u32 vt_reg_bits; - u32 reg_offset, vf_shift; - u32 vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); - vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN - | IXGBE_VT_CTL_REPLEN; - vt_reg_bits |= (adapter->num_vfs << - IXGBE_VT_CTL_POOL_SHIFT); - IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits); - IXGBE_WRITE_REG(hw, IXGBE_MRQC, 0); - - vf_shift = adapter->num_vfs % 32; - reg_offset = adapter->num_vfs / 32; - IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0); - /* Enable only the PF's pool for Tx/Rx */ - IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift)); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift)); - IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); - } - - /* Program MRQC for the distribution of queues */ - ixgbe_setup_mrqc(adapter); - - if (adapter->num_vfs) { - /* Map PF MAC address in RAR Entry 0 to first pool - * following VFs */ - hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs); - - /* Set up VF register offsets for selected VT Mode, i.e. - * 64 VFs for SR-IOV */ - gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); - gcr_ext |= IXGBE_GCR_EXT_SRIOV; - IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); - } } static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -- cgit v1.2.3 From a34bcfffae8ebbba9dcbacbc3de718cca66689dd Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:39:20 +0000 Subject: ixgbe: move all GPIE register config into a single function This change moves all GPIE register configuration into a single function. The advantage of this is that we can avoid a number of unnecessary read/modify/write cycles on the register. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 72 ++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d358beff57fc..0b235221f14c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3362,38 +3362,15 @@ static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, (adapter->rx_ring[rxr]->count - 1)); } -static int ixgbe_up_complete(struct ixgbe_adapter *adapter) +static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - int i, j = 0; - int num_rx_rings = adapter->num_rx_queues; - int err; - u32 txdctl, rxdctl; - u32 dmatxctl; - u32 gpie; - u32 ctrl_ext; - - ixgbe_get_hw_control(adapter); - - if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) || - (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) { - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME | - IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD); - } else { - /* MSI only */ - gpie = 0; - } - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - gpie &= ~IXGBE_GPIE_VTMODE_MASK; - gpie |= IXGBE_GPIE_VTMODE_64; - } - /* XXX: to interrupt immediately for EICS writes, enable this */ - /* gpie |= IXGBE_GPIE_EIMEN; */ - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } + u32 gpie = 0; if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + gpie = IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT | + IXGBE_GPIE_OCD; + gpie |= IXGBE_GPIE_EIAME; /* * use EIAM to auto-mask when MSI-X interrupt is asserted * this saves a register write for every interrupt @@ -3414,26 +3391,37 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); } - /* Enable Thermal over heat sensor interrupt */ - if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); - gpie |= IXGBE_SDP0_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + /* XXX: to interrupt immediately for EICS writes, enable this */ + /* gpie |= IXGBE_GPIE_EIMEN; */ + + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + gpie &= ~IXGBE_GPIE_VTMODE_MASK; + gpie |= IXGBE_GPIE_VTMODE_64; } - /* Enable fan failure interrupt if media type is copper */ - if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + /* Enable fan failure interrupt */ + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) gpie |= IXGBE_SDP1_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } - if (hw->mac.type == ixgbe_mac_82599EB) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + if (hw->mac.type == ixgbe_mac_82599EB) gpie |= IXGBE_SDP1_GPIEN; gpie |= IXGBE_SDP2_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } + + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); +} + +static int ixgbe_up_complete(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i, j = 0; + int num_rx_rings = adapter->num_rx_queues; + int err; + u32 txdctl, rxdctl; + u32 dmatxctl; + u32 ctrl_ext; + + ixgbe_get_hw_control(adapter); + ixgbe_setup_gpie(adapter); if (hw->mac.type == ixgbe_mac_82599EB) { /* DMATXCTL.EN must be set after all Tx queue config is done */ -- cgit v1.2.3 From 2f1860b8d94a4457e401895be6fc9b9ffa2c8b2c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:39:43 +0000 Subject: ixgbe: pull all Tx init into ixgbe_configure_tx The Tx init was spread out over ixgbe_configure, ixgbe_configure_tx, and ixgbe_up_complete. This change combines all of that into the ixgbe_configure_tx function in order to simplify the Tx init path. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 91 ++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0b235221f14c..fd2026efae88 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2436,8 +2436,16 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u64 tdba = ring->dma; + int wait_loop = 10; + u32 txdctl; u16 reg_idx = ring->reg_idx; + /* disable queue to avoid issues while updating state */ + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), + txdctl & ~IXGBE_TXDCTL_ENABLE); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx), (tdba & DMA_BIT_MASK(32))); IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32)); @@ -2448,6 +2456,38 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) ring->head = IXGBE_TDH(reg_idx); ring->tail = IXGBE_TDT(reg_idx); + /* configure fetching thresholds */ + if (adapter->rx_itr_setting == 0) { + /* cannot set wthresh when itr==0 */ + txdctl &= ~0x007F0000; + } else { + /* enable WTHRESH=8 descriptors, to encourage burst writeback */ + txdctl |= (8 << 16); + } + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + /* PThresh workaround for Tx hang with DFP enabled. */ + txdctl |= 32; + } + + /* reinitialize flowdirector state */ + set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state); + + /* enable queue */ + txdctl |= IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); + + /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + /* poll to verify queue is enabled */ + do { + msleep(1); + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); + if (!wait_loop) + e_err(drv, "Could not enable Tx Queue %d\n", reg_idx); } static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) @@ -2497,13 +2537,22 @@ static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) **/ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) { + struct ixgbe_hw *hw = &adapter->hw; + u32 dmatxctl; u32 i; + ixgbe_setup_mtqc(adapter); + + if (hw->mac.type != ixgbe_mac_82598EB) { + /* DMATXCTL.EN must be before Tx queues are enabled */ + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + } + /* Setup the HW Tx Head and Tail descriptor pointers */ for (i = 0; i < adapter->num_tx_queues; i++) ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); - - ixgbe_setup_mtqc(adapter); } #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 @@ -3416,44 +3465,12 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) int i, j = 0; int num_rx_rings = adapter->num_rx_queues; int err; - u32 txdctl, rxdctl; - u32 dmatxctl; + u32 rxdctl; u32 ctrl_ext; ixgbe_get_hw_control(adapter); ixgbe_setup_gpie(adapter); - if (hw->mac.type == ixgbe_mac_82599EB) { - /* DMATXCTL.EN must be set after all Tx queue config is done */ - dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); - dmatxctl |= IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); - } - for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - if (adapter->rx_itr_setting == 0) { - /* cannot set wthresh when itr==0 */ - txdctl &= ~0x007F0000; - } else { - /* enable WTHRESH=8 descriptors, to encourage burst writeback */ - txdctl |= (8 << 16); - } - txdctl |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); - if (hw->mac.type == ixgbe_mac_82599EB) { - int wait_loop = 10; - /* poll for Tx Enable ready */ - do { - msleep(1); - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - } while (--wait_loop && - !(txdctl & IXGBE_TXDCTL_ENABLE)); - if (!wait_loop) - e_err(drv, "Could not enable Tx Queue %d\n", j); - } - } - for (i = 0; i < num_rx_rings; i++) { j = adapter->rx_ring[i]->reg_idx; rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3530,10 +3547,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) e_err(probe, "link_config FAILED %d\n", err); } - for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->reinit_state)); - /* enable transmits */ netif_tx_start_all_queues(adapter->netdev); -- cgit v1.2.3 From 9e10e045f8223e09f2c70cd6849ff86803d50c88 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:40:06 +0000 Subject: ixgbe: combine Rx into into ixgbe_configure_rx The Rx init is currently split over ixgbe_configure, ixgbe_configure_rx, and ixgbe_up_complete. Instead of leaving it split over 3 function it is easier to consolidate them all into ixgbe_configure_rx. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 152 +++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 57 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fd2026efae88..c88ba13c1131 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2574,6 +2574,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; + if (adapter->num_vfs) + srrctl |= IXGBE_SRRCTL_DROP_EN; srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK; @@ -2705,13 +2707,72 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); } +/** + * ixgbe_set_uta - Set unicast filter table address + * @adapter: board private structure + * + * The unicast table address is a register array of 32-bit registers. + * The table is meant to be used in a way similar to how the MTA is used + * however due to certain limitations in the hardware it is necessary to + * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous + * enable bit to allow vlan tag stripping when promiscuous mode is enabled + **/ +static void ixgbe_set_uta(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + + /* The UTA table only exists on 82599 hardware and newer */ + if (hw->mac.type < ixgbe_mac_82599EB) + return; + + /* we only need to do this if VMDq is enabled */ + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return; + + for (i = 0; i < 128; i++) + IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0); +} + +#define IXGBE_MAX_RX_DESC_POLL 10 +static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + int reg_idx = ring->reg_idx; + int wait_loop = IXGBE_MAX_RX_DESC_POLL; + u32 rxdctl; + + /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + do { + msleep(1); + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE)); + + if (!wait_loop) { + e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within " + "the polling period\n", reg_idx); + } +} + static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; u64 rdba = ring->dma; + u32 rxdctl; u16 reg_idx = ring->reg_idx; + /* disable queue to avoid issues while updating state */ + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), + rxdctl & ~IXGBE_RXDCTL_ENABLE); + IXGBE_WRITE_FLUSH(hw); + IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx), @@ -2720,6 +2781,28 @@ static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); ring->head = IXGBE_RDH(reg_idx); ring->tail = IXGBE_RDT(reg_idx); + + ixgbe_configure_srrctl(adapter, ring); + ixgbe_configure_rscctl(adapter, ring); + + if (hw->mac.type == ixgbe_mac_82598EB) { + /* + * enable cache line friendly hardware writes: + * PTHRESH=32 descriptors (half the internal cache), + * this also removes ugly rx_no_buffer_count increment + * HTHRESH=4 descriptors (to minimize latency on fetch) + * WTHRESH=8 burst writeback up to two cache lines + */ + rxdctl &= ~0x3FFFFF; + rxdctl |= 0x080420; + } + + /* enable receive descriptor ring */ + rxdctl |= IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + + ixgbe_rx_desc_queue_enable(adapter, ring); + ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring)); } static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) @@ -2908,7 +2991,6 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_ring *rx_ring; int i; u32 rxctrl; @@ -2919,10 +3001,12 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) ixgbe_setup_psrtype(adapter); ixgbe_setup_rdrxctl(adapter); - /* Program MRQC for the distribution of queues */ + /* Program registers for the distribution of queues */ ixgbe_setup_mrqc(adapter); ixgbe_configure_virtualization(adapter); + ixgbe_set_uta(adapter); + /* set_rx_buffer_len must be called before ring initialization */ ixgbe_set_rx_buffer_len(adapter); @@ -2930,13 +3014,16 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) * Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ - for (i = 0; i < adapter->num_rx_queues; i++) { - rx_ring = adapter->rx_ring[i]; - ixgbe_configure_rx_ring(adapter, rx_ring); - ixgbe_configure_srrctl(adapter, rx_ring); - ixgbe_configure_rscctl(adapter, rx_ring); - } + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]); + /* disable drop enable for 82598 parts */ + if (hw->mac.type == ixgbe_mac_82598EB) + rxctrl |= IXGBE_RXCTRL_DMBYPS; + + /* enable all receives */ + rxctrl |= IXGBE_RXCTRL_RXEN; + hw->mac.ops.enable_rx_dma(hw, rxctrl); } static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) @@ -3306,9 +3393,6 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) ixgbe_configure_tx(adapter); ixgbe_configure_rx(adapter); - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i], - (adapter->rx_ring[i]->count - 1)); } static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw) @@ -3389,28 +3473,6 @@ link_cfg_out: return ret; } -#define IXGBE_MAX_RX_DESC_POLL 10 -static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, - int rxr) -{ - int j = adapter->rx_ring[rxr]->reg_idx; - int k; - - for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) { - if (IXGBE_READ_REG(&adapter->hw, - IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - if (k >= IXGBE_MAX_RX_DESC_POLL) { - e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within " - "the polling period\n", rxr); - } - ixgbe_release_rx_desc(&adapter->hw, adapter->rx_ring[rxr], - (adapter->rx_ring[rxr]->count - 1)); -} - static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -3462,35 +3524,12 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) static int ixgbe_up_complete(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - int i, j = 0; - int num_rx_rings = adapter->num_rx_queues; int err; - u32 rxdctl; u32 ctrl_ext; ixgbe_get_hw_control(adapter); ixgbe_setup_gpie(adapter); - for (i = 0; i < num_rx_rings; i++) { - j = adapter->rx_ring[i]->reg_idx; - rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); - /* enable PTHRESH=32 descriptors (half the internal cache) - * and HTHRESH=0 descriptors (to minimize latency on fetch), - * this also removes a pesky rx_no_buffer_count increment */ - rxdctl |= 0x0020; - rxdctl |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl); - if (hw->mac.type == ixgbe_mac_82599EB) - ixgbe_rx_desc_queue_enable(adapter, i); - } - /* enable all receives */ - rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - if (hw->mac.type == ixgbe_mac_82598EB) - rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN); - else - rxdctl |= IXGBE_RXCTRL_RXEN; - hw->mac.ops.enable_rx_dma(hw, rxdctl); - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) ixgbe_configure_msix(adapter); else @@ -3505,7 +3544,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_EICR); - ixgbe_irq_enable(adapter); /* -- cgit v1.2.3 From 31f05a2d875327ef133ac4b62261c4b875d1d10c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:40:31 +0000 Subject: ixgbe: update all DESC_ADV macros to accept a ring pointer All of the DESC_ADV macros are currently needing the pointers to be de-referenced before accessing the ring. Instead of having to add all of the asterisks it is easier to just update the macro to expect a pointer to the ring. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 6 +++--- drivers/net/ixgbe/ixgbe_ethtool.c | 4 ++-- drivers/net/ixgbe/ixgbe_fcoe.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 24 ++++++++++++------------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 7233fef7e9b8..ac4b90edb58e 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -256,11 +256,11 @@ struct ixgbe_q_vector { (R)->next_to_clean - (R)->next_to_use - 1) #define IXGBE_RX_DESC_ADV(R, i) \ - (&(((union ixgbe_adv_rx_desc *)((R).desc))[i])) + (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) #define IXGBE_TX_DESC_ADV(R, i) \ - (&(((union ixgbe_adv_tx_desc *)((R).desc))[i])) + (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) #define IXGBE_TX_CTXTDESC_ADV(R, i) \ - (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i])) + (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i])) #define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 #ifdef IXGBE_FCOE diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index fb6d8e88eb05..4d74f4bc7a01 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1560,7 +1560,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data); for (i = 0; i < tx_ring->count; i++) { - union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(tx_ring, i); struct sk_buff *skb; unsigned int size = 1024; @@ -1661,7 +1661,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) for (i = 0; i < rx_ring->count; i++) { union ixgbe_adv_rx_desc *rx_desc = - IXGBE_RX_DESC_ADV(*rx_ring, i); + IXGBE_RX_DESC_ADV(rx_ring, i); struct sk_buff *skb; skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 072327c5e41a..86fa07cb061d 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -471,7 +471,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, /* write context desc */ i = tx_ring->next_to_use; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c88ba13c1131..85ecf0e39b99 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -385,7 +385,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) "leng ntw timestamp bi->skb\n"); for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; u0 = (struct my_u0 *)tx_desc; printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX" @@ -466,7 +466,7 @@ rx_ring_summary: for (i = 0; i < rx_ring->count; i++) { rx_buffer_info = &rx_ring->rx_buffer_info[i]; - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); u0 = (struct my_u0 *)rx_desc; staterr = le32_to_cpu(rx_desc->wb.upper.status_error); if (staterr & IXGBE_RXD_STAT_DD) { @@ -695,7 +695,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, ixgbe_tx_xon_state(adapter, tx_ring)) { /* detected Tx unit hang */ union ixgbe_adv_tx_desc *tx_desc; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); e_err(drv, "Detected Tx Unit Hang\n" " Tx Queue <%d>\n" " TDH, TDT <%x>, <%x>\n" @@ -743,7 +743,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, i = tx_ring->next_to_clean; eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && (count < tx_ring->work_limit)) { @@ -751,7 +751,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { struct sk_buff *skb; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; cleaned = (i == eop); skb = tx_buffer_info->skb; @@ -791,7 +791,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); } tx_ring->next_to_clean = i; @@ -1047,7 +1047,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, bi = &rx_ring->rx_buffer_info[i]; while (cleaned_count--) { - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); if (!bi->page_dma && (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) { @@ -1188,7 +1188,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #endif /* IXGBE_FCOE */ i = rx_ring->next_to_clean; - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); rx_buffer_info = &rx_ring->rx_buffer_info[i]; @@ -1263,7 +1263,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (i == rx_ring->count) i = 0; - next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i); + next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i); prefetch(next_rxd); cleaned_count++; @@ -5813,7 +5813,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, i = tx_ring->next_to_use; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); /* VLAN MACLEN IPLEN */ if (tx_flags & IXGBE_TX_FLAGS_VLAN) @@ -5872,7 +5872,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, (tx_flags & IXGBE_TX_FLAGS_VLAN)) { i = tx_ring->next_to_use; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); if (tx_flags & IXGBE_TX_FLAGS_VLAN) vlan_macip_lens |= @@ -6101,7 +6101,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, i = tx_ring->next_to_use; while (count--) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma); tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type_len | tx_buffer_info->length); -- cgit v1.2.3 From 84418e3b10b5ba43eb5b85f725e75fd9c9730670 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 19 Aug 2010 13:40:54 +0000 Subject: ixgbe: rewrite ethtool test to use standard config functions This change makes it so that the ethtool loopback test uses the standard ring configuration and allocation functions. As a result the loopback test will be much more effective at testing core driver functionality. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 11 ++ drivers/net/ixgbe/ixgbe_ethtool.c | 362 +++++++++++++------------------------- drivers/net/ixgbe/ixgbe_main.c | 49 ++++-- 3 files changed, 169 insertions(+), 253 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index ac4b90edb58e..5cebc3755b64 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -453,9 +453,20 @@ extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *) extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); +extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); +extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, + struct net_device *, + struct ixgbe_adapter *, + struct ixgbe_ring *); +extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *, + struct ixgbe_tx_buffer *); +extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 4d74f4bc7a01..25ef8b197373 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1438,9 +1438,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; struct ixgbe_hw *hw = &adapter->hw; - struct pci_dev *pdev = adapter->pdev; u32 reg_ctl; - int i; /* shut down the DMA engines now so they can be reinitialized later */ @@ -1448,14 +1446,15 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); reg_ctl &= ~IXGBE_RXCTRL_RXEN; IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); - reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0)); + reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx)); reg_ctl &= ~IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl); + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl); /* now Tx */ - reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0)); + reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); reg_ctl &= ~IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl); + if (hw->mac.type == ixgbe_mac_82599EB) { reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; @@ -1464,221 +1463,57 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) ixgbe_reset(adapter); - if (tx_ring->desc && tx_ring->tx_buffer_info) { - for (i = 0; i < tx_ring->count; i++) { - struct ixgbe_tx_buffer *buf = - &(tx_ring->tx_buffer_info[i]); - if (buf->dma) - dma_unmap_single(&pdev->dev, buf->dma, - buf->length, DMA_TO_DEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (rx_ring->desc && rx_ring->rx_buffer_info) { - for (i = 0; i < rx_ring->count; i++) { - struct ixgbe_rx_buffer *buf = - &(rx_ring->rx_buffer_info[i]); - if (buf->dma) - dma_unmap_single(&pdev->dev, buf->dma, - IXGBE_RXBUFFER_2048, - DMA_FROM_DEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (tx_ring->desc) { - dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, - tx_ring->dma); - tx_ring->desc = NULL; - } - if (rx_ring->desc) { - dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, - rx_ring->dma); - rx_ring->desc = NULL; - } - - kfree(tx_ring->tx_buffer_info); - tx_ring->tx_buffer_info = NULL; - kfree(rx_ring->rx_buffer_info); - rx_ring->rx_buffer_info = NULL; + ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring); + ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring); } static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) { struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; u32 rctl, reg_data; - int i, ret_val; + int ret_val; + int err; /* Setup Tx descriptor ring and Tx buffers */ + tx_ring->count = IXGBE_DEFAULT_TXD; + tx_ring->queue_index = 0; + tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; + tx_ring->numa_node = adapter->node; - if (!tx_ring->count) - tx_ring->count = IXGBE_DEFAULT_TXD; - - tx_ring->tx_buffer_info = kcalloc(tx_ring->count, - sizeof(struct ixgbe_tx_buffer), - GFP_KERNEL); - if (!(tx_ring->tx_buffer_info)) { - ret_val = 1; - goto err_nomem; - } - - tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); - tx_ring->size = ALIGN(tx_ring->size, 4096); - tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, - &tx_ring->dma, GFP_KERNEL); - if (!(tx_ring->desc)) { - ret_val = 2; - goto err_nomem; - } - tx_ring->next_to_use = tx_ring->next_to_clean = 0; - - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0), - ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0), - ((u64) tx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0), - tx_ring->count * sizeof(union ixgbe_adv_tx_desc)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data |= IXGBE_HLREG0_TXPADEN; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); + err = ixgbe_setup_tx_resources(adapter, tx_ring); + if (err) + return 1; if (adapter->hw.mac.type == ixgbe_mac_82599EB) { reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); } - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0)); - reg_data |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data); - - for (i = 0; i < tx_ring->count; i++) { - union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(tx_ring, i); - struct sk_buff *skb; - unsigned int size = 1024; - - skb = alloc_skb(size, GFP_KERNEL); - if (!skb) { - ret_val = 3; - goto err_nomem; - } - skb_put(skb, size); - tx_ring->tx_buffer_info[i].skb = skb; - tx_ring->tx_buffer_info[i].length = skb->len; - tx_ring->tx_buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, skb->len, - DMA_TO_DEVICE); - desc->read.buffer_addr = - cpu_to_le64(tx_ring->tx_buffer_info[i].dma); - desc->read.cmd_type_len = cpu_to_le32(skb->len); - desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD_EOP | - IXGBE_TXD_CMD_IFCS | - IXGBE_TXD_CMD_RS); - desc->read.olinfo_status = 0; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) - desc->read.olinfo_status |= - (skb->len << IXGBE_ADVTXD_PAYLEN_SHIFT); - } + ixgbe_configure_tx_ring(adapter, tx_ring); /* Setup Rx Descriptor ring and Rx buffers */ - - if (!rx_ring->count) - rx_ring->count = IXGBE_DEFAULT_RXD; - - rx_ring->rx_buffer_info = kcalloc(rx_ring->count, - sizeof(struct ixgbe_rx_buffer), - GFP_KERNEL); - if (!(rx_ring->rx_buffer_info)) { + rx_ring->count = IXGBE_DEFAULT_RXD; + rx_ring->queue_index = 0; + rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; + rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048; + rx_ring->numa_node = adapter->node; + + err = ixgbe_setup_rx_resources(adapter, rx_ring); + if (err) { ret_val = 4; goto err_nomem; } - rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); - rx_ring->size = ALIGN(rx_ring->size, 4096); - rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, - &rx_ring->dma, GFP_KERNEL); - if (!(rx_ring->desc)) { - ret_val = 5; - goto err_nomem; - } - rx_ring->next_to_use = rx_ring->next_to_clean = 0; - rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0), - ((u64)rx_ring->dma & 0xFFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0), - ((u64) rx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0); - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data &= ~IXGBE_HLREG0_LPBK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL); -#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum - Threshold Size mask */ - reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL); -#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */ - reg_data &= ~IXGBE_MCSTCTRL_MO_MASK; - reg_data |= adapter->hw.mac.mc_filter_type; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0)); - reg_data |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - int j = adapter->rx_ring[0]->reg_idx; - u32 k; - for (k = 0; k < 10; k++) { - if (IXGBE_READ_REG(&adapter->hw, - IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - } + ixgbe_configure_rx_ring(adapter, rx_ring); rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS; IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl); - for (i = 0; i < rx_ring->count; i++) { - union ixgbe_adv_rx_desc *rx_desc = - IXGBE_RX_DESC_ADV(rx_ring, i); - struct sk_buff *skb; - - skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); - if (!skb) { - ret_val = 6; - goto err_nomem; - } - skb_reserve(skb, NET_IP_ALIGN); - rx_ring->rx_buffer_info[i].skb = skb; - rx_ring->rx_buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, - IXGBE_RXBUFFER_2048, DMA_FROM_DEVICE); - rx_desc->read.pkt_addr = - cpu_to_le64(rx_ring->rx_buffer_info[i].dma); - memset(skb->data, 0x00, skb->len); - } - return 0; err_nomem: @@ -1692,16 +1527,21 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) u32 reg_data; /* right now we only support MAC loopback in the driver */ - - /* Setup MAC loopback */ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); + /* Setup MAC loopback */ reg_data |= IXGBE_HLREG0_LPBK; IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); + reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC); reg_data &= ~IXGBE_AUTOC_LMS_MASK; reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data); + IXGBE_WRITE_FLUSH(&adapter->hw); + msleep(10); /* Disable Atlas Tx lanes; re-enabled in reset path */ if (hw->mac.type == ixgbe_mac_82598EB) { @@ -1759,15 +1599,81 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb, return 13; } +static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + struct ixgbe_ring *tx_ring, + unsigned int size) +{ + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *rx_buffer_info; + struct ixgbe_tx_buffer *tx_buffer_info; + const int bufsz = rx_ring->rx_buf_len; + u32 staterr; + u16 rx_ntc, tx_ntc, count = 0; + + /* initialize next to clean and descriptor values */ + rx_ntc = rx_ring->next_to_clean; + tx_ntc = tx_ring->next_to_clean; + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + + while (staterr & IXGBE_RXD_STAT_DD) { + /* check Rx buffer */ + rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; + + /* unmap Rx buffer, will be remapped by alloc_rx_buffers */ + dma_unmap_single(&adapter->pdev->dev, + rx_buffer_info->dma, + bufsz, + DMA_FROM_DEVICE); + rx_buffer_info->dma = 0; + + /* verify contents of skb */ + if (!ixgbe_check_lbtest_frame(rx_buffer_info->skb, size)) + count++; + + /* unmap buffer on Tx side */ + tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + + /* increment Rx/Tx next to clean counters */ + rx_ntc++; + if (rx_ntc == rx_ring->count) + rx_ntc = 0; + tx_ntc++; + if (tx_ntc == tx_ring->count) + tx_ntc = 0; + + /* fetch next descriptor */ + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + } + + /* re-map buffers to ring, store next to clean values */ + ixgbe_alloc_rx_buffers(adapter, rx_ring, count); + rx_ring->next_to_clean = rx_ntc; + tx_ring->next_to_clean = tx_ntc; + + return count; +} + static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) { struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; - int i, j, k, l, lc, good_cnt, ret_val = 0; - unsigned long time; + int i, j, lc, good_cnt, ret_val = 0; + unsigned int size = 1024; + netdev_tx_t tx_ret_val; + struct sk_buff *skb; + + /* allocate test skb */ + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return 11; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1); + /* place data into test skb */ + ixgbe_create_lbtest_frame(skb, size); + skb_put(skb, size); /* * Calculate the loop count based on the largest descriptor ring @@ -1780,54 +1686,40 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) else lc = ((rx_ring->count / 64) * 2) + 1; - k = l = 0; for (j = 0; j <= lc; j++) { - for (i = 0; i < 64; i++) { - ixgbe_create_lbtest_frame( - tx_ring->tx_buffer_info[k].skb, - 1024); - dma_sync_single_for_device(&pdev->dev, - tx_ring->tx_buffer_info[k].dma, - tx_ring->tx_buffer_info[k].length, - DMA_TO_DEVICE); - if (unlikely(++k == tx_ring->count)) - k = 0; - } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k); - msleep(200); - /* set the start time for the receive */ - time = jiffies; + /* reset count of good packets */ good_cnt = 0; - do { - /* receive the sent packets */ - dma_sync_single_for_cpu(&pdev->dev, - rx_ring->rx_buffer_info[l].dma, - IXGBE_RXBUFFER_2048, - DMA_FROM_DEVICE); - ret_val = ixgbe_check_lbtest_frame( - rx_ring->rx_buffer_info[l].skb, 1024); - if (!ret_val) + + /* place 64 packets on the transmit queue*/ + for (i = 0; i < 64; i++) { + skb_get(skb); + tx_ret_val = ixgbe_xmit_frame_ring(skb, + adapter->netdev, + adapter, + tx_ring); + if (tx_ret_val == NETDEV_TX_OK) good_cnt++; - if (++l == rx_ring->count) - l = 0; - /* - * time + 20 msecs (200 msecs on 2.4) is more than - * enough time to complete the receives, if it's - * exceeded, break and error off - */ - } while (good_cnt < 64 && jiffies < (time + 20)); + } + if (good_cnt != 64) { - /* ret_val is the same as mis-compare */ - ret_val = 13; + ret_val = 12; break; } - if (jiffies >= (time + 20)) { - /* Error code for time out error */ - ret_val = 14; + + /* allow 200 milliseconds for packets to go from Tx to Rx */ + msleep(200); + + good_cnt = ixgbe_clean_test_rings(adapter, rx_ring, + tx_ring, size); + if (good_cnt != 64) { + ret_val = 13; break; } } + /* free the original skb */ + kfree_skb(skb); + return ret_val; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 85ecf0e39b99..18163e312a39 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -601,9 +601,9 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, } } -static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, - struct ixgbe_tx_buffer - *tx_buffer_info) +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, + struct ixgbe_tx_buffer + *tx_buffer_info) { if (tx_buffer_info->dma) { if (tx_buffer_info->mapped_as_page) @@ -1032,9 +1032,9 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split * @adapter: address of board private structure **/ -static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - int cleaned_count) +void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -1095,6 +1095,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); } else { rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + rx_desc->read.hdr_addr = 0; } i++; @@ -2431,8 +2432,8 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) * * Configure the Tx descriptor ring after a reset. **/ - static void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) +void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; u64 tdba = ring->dma; @@ -2759,8 +2760,8 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, } } -static void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) +void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; u64 rdba = ring->dma; @@ -3671,8 +3672,11 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, unsigned long size; unsigned int i; - /* Free all the Rx ring sk_buffs */ + /* ring already cleared, nothing to do */ + if (!rx_ring->rx_buffer_info) + return; + /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { struct ixgbe_rx_buffer *rx_buffer_info; @@ -3739,8 +3743,11 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, unsigned long size; unsigned int i; - /* Free all the Tx ring sk_buffs */ + /* ring already cleared, nothing to do */ + if (!tx_ring->tx_buffer_info) + return; + /* Free all the Tx ring sk_buffs */ for (i = 0; i < tx_ring->count; i++) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); @@ -6239,11 +6246,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) return skb_tx_hash(dev, skb); } -static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, - struct net_device *netdev) +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev, + struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_ring *tx_ring; struct netdev_queue *txq; unsigned int first; unsigned int tx_flags = 0; @@ -6267,8 +6273,6 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_VLAN; } - tx_ring = adapter->tx_ring[skb->queue_mapping]; - #ifdef IXGBE_FCOE /* for FCoE with DCB, we force the priority to what * was specified by the switch */ @@ -6362,6 +6366,15 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } +static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_ring *tx_ring; + + tx_ring = adapter->tx_ring[skb->queue_mapping]; + return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring); +} + /** * ixgbe_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure -- cgit v1.2.3 From f1bf7a5247a0f8e42025d19d732cbc70a57e6342 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 19 Aug 2010 05:08:22 +0000 Subject: qlcnic: fix inconsistent lock state Spin_lock(rds_ring->lock) is not required while posting buffers from qlcnic_open and freeing buffers from qlcnic_down. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 75ba744b173c..08da25895fad 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -136,8 +136,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - spin_lock(&rds_ring->lock); - INIT_LIST_HEAD(&rds_ring->free_list); rx_buf = rds_ring->rx_buf_arr; @@ -146,8 +144,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter) &rds_ring->free_list); rx_buf++; } - - spin_unlock(&rds_ring->lock); } } @@ -1587,8 +1583,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, int producer, count = 0; struct list_head *head; - spin_lock(&rds_ring->lock); - producer = rds_ring->producer; head = &rds_ring->free_list; @@ -1618,7 +1612,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, writel((producer-1) & (rds_ring->num_desc-1), rds_ring->crb_rcv_producer); } - spin_unlock(&rds_ring->lock); } static void -- cgit v1.2.3 From 39895e07ca8ce13d8b38d00bf66236b93907c027 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 19 Aug 2010 05:08:23 +0000 Subject: qlcnic: remove unused code Serial number references are not used in driver. Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 - drivers/net/qlcnic/qlcnic_main.c | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index f6b887d409d5..5c549c5c2dd7 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -933,7 +933,6 @@ struct qlcnic_adapter { u8 max_rds_rings; u8 max_sds_rings; - u8 driver_mismatch; u8 msix_supported; u8 rx_csum; u8 portnum; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 384cc52a9c3e..beadf2e41130 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -709,24 +709,8 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) { u32 fw_major, fw_minor, fw_build; char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; - char serial_num[32]; - int i, offset, val; - int *ptr32; struct pci_dev *pdev = adapter->pdev; struct qlcnic_info nic_info; - adapter->driver_mismatch = 0; - - ptr32 = (int *)&serial_num; - offset = QLCNIC_FW_SERIAL_NUM_OFFSET; - for (i = 0; i < 8; i++) { - if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) { - dev_err(&pdev->dev, "error reading board info\n"); - adapter->driver_mismatch = 1; - return; - } - ptr32[i] = cpu_to_le32(val); - offset += sizeof(u32); - } fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); @@ -1584,9 +1568,6 @@ static int qlcnic_open(struct net_device *netdev) struct qlcnic_adapter *adapter = netdev_priv(netdev); int err; - if (adapter->driver_mismatch) - return -EIO; - err = qlcnic_attach(adapter); if (err) return err; -- cgit v1.2.3 From 251b036a22f530aff26cf70f5cdb0cf64a072e46 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 19 Aug 2010 05:08:24 +0000 Subject: qlcnic: replace magic numbers with defines Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_hdr.h | 4 ++++ drivers/net/qlcnic/qlcnic_init.c | 4 ++-- drivers/net/qlcnic/qlcnic_main.c | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 5c549c5c2dd7..d19836758c6e 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -148,6 +148,7 @@ #define DEFAULT_RCV_DESCRIPTORS_1G 2048 #define DEFAULT_RCV_DESCRIPTORS_10G 4096 +#define MAX_RDS_RINGS 2 #define get_next_index(index, length) \ (((index) + 1) & ((length) - 1)) diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index bd346d9aac94..39db4df0f650 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -745,6 +745,10 @@ enum { #define FW_POLL_DELAY (1 * HZ) #define FW_FAIL_THRESH 2 +#define QLCNIC_RESET_TIMEOUT_SECS 10 +#define QLCNIC_INIT_TIMEOUT_SECS 30 + + #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 08da25895fad..90766757c314 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -553,12 +553,12 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { } adapter->physical_port = (val >> 2); if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo)) - timeo = 30; + timeo = QLCNIC_INIT_TIMEOUT_SECS; adapter->dev_init_timeo = timeo; if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DRV_RESET_TIMEOUT, &timeo)) - timeo = 10; + timeo = QLCNIC_RESET_TIMEOUT_SECS; adapter->reset_ack_timeo = timeo; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index beadf2e41130..c6f19c961c3d 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -754,7 +754,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->num_txd = MAX_CMD_DESCRIPTORS; - adapter->max_rds_rings = 2; + adapter->max_rds_rings = MAX_RDS_RINGS; } static int -- cgit v1.2.3 From 4e8acb011f0e9e86e29b53ff051e699ba0c5726d Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Thu, 19 Aug 2010 05:08:25 +0000 Subject: qlcnic: configure port on eswitch o Nic partition capable devices has embedded switch, this needs to support various features like external switch. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 22 +++-- drivers/net/qlcnic/qlcnic_ctx.c | 174 ++++++++++++++++++++++++++---------- drivers/net/qlcnic/qlcnic_hdr.h | 7 ++ drivers/net/qlcnic/qlcnic_main.c | 185 +++++++++++++++++++++------------------ 4 files changed, 254 insertions(+), 134 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index d19836758c6e..9433a05555f1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -556,6 +556,7 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 +#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a #define QLCNIC_RCODE_SUCCESS 0 @@ -1044,7 +1045,7 @@ struct qlcnic_pci_info { }; struct qlcnic_npar_info { - u16 vlan_id; + u16 pvid; u16 min_bw; u16 max_bw; u8 phy_port; @@ -1052,11 +1053,13 @@ struct qlcnic_npar_info { u8 active; u8 enable_pm; u8 dest_npar; - u8 host_vlan_tag; - u8 promisc_mode; u8 discard_tagged; u8 mac_learning; + u8 mac_anti_spoof; + u8 promisc_mode; + u8 offload_flags; }; + struct qlcnic_eswitch { u8 port; u8 active_vports; @@ -1088,7 +1091,6 @@ struct qlcnic_eswitch { #define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) -#define IS_VALID_MODE(mode) (mode == 0 || mode == 1) struct qlcnic_pci_func_cfg { u16 func_type; @@ -1120,12 +1122,16 @@ struct qlcnic_pm_func_cfg { struct qlcnic_esw_func_cfg { u16 vlan_id; + u8 op_mode; + u8 op_type; u8 pci_func; u8 host_vlan_tag; u8 promisc_mode; u8 discard_tagged; u8 mac_learning; - u8 reserved; + u8 mac_anti_spoof; + u8 offload_flags; + u8 reserved[5]; }; #define QLCNIC_STATS_VERSION 1 @@ -1276,8 +1282,10 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8, int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, struct qlcnic_eswitch *); int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); -int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, - u8, u8, u16); +int qlcnic_config_switch_port(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); +int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8, struct __qlcnic_esw_statistics *); diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 57c9b09bd16a..74ae3b0a5ea8 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -813,9 +813,8 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); eswitch->port = arg1 & 0xf; - eswitch->active_vports = LSB(arg2); - eswitch->max_ucast_filters = MSB(arg2); - eswitch->max_active_vlans = LSB(MSW(arg2)); + eswitch->max_ucast_filters = LSW(arg2); + eswitch->max_active_vlans = MSW(arg2) & 0xfff; if (arg1 & BIT_6) eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; if (arg1 & BIT_7) @@ -943,47 +942,6 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, return err; } -/* Configure eSwitch port */ -int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, - int vlan_tagging, u8 discard_tagged, u8 promsc_mode, - u8 mac_learn, u8 pci_func, u16 vlan_id) -{ - int err = -EIO; - u32 arg1; - struct qlcnic_eswitch *eswitch; - - if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; - - eswitch = &adapter->eswitch[id]; - if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE)) - return err; - - arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0); - arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0); - arg1 |= pci_func << 8; - if (vlan_tagging) - arg1 |= BIT_5 | (vlan_id << 16); - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - arg1, - 0, - 0, - QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to configure eswitch port%d\n", eswitch->port); - } else { - dev_info(&adapter->pdev->dev, - "Configured eSwitch for port %d\n", eswitch->port); - } - - return err; -} - int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { @@ -1108,3 +1066,131 @@ err_ret: "rx_ctx=%d\n", func_esw, port, rx_tx); return -EIO; } + +static int +__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, + u32 *arg1, u32 *arg2) +{ + int err = -EIO; + u8 pci_func; + pci_func = (*arg1 >> 8); + err = qlcnic_issue_cmd(adapter, + adapter->ahw.pci_func, + adapter->fw_hal_version, + *arg1, + 0, + 0, + QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG); + + if (err == QLCNIC_RCODE_SUCCESS) { + *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); + *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); + dev_info(&adapter->pdev->dev, + "eSwitch port config for pci func%d\n", pci_func); + } else { + dev_err(&adapter->pdev->dev, + "Failed to get eswitch port config%d\n", pci_func); + } + return err; +} +/* Configure eSwitch port +op_mode = 0 for setting default port behavior +op_mode = 1 for setting vlan id +op_mode = 2 for deleting vlan id +op_type = 0 for vlan_id +op_type = 1 for port vlan_id +*/ +int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + int err = -EIO; + u32 arg1, arg2 = 0; + u8 pci_func; + + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + return err; + pci_func = esw_cfg->pci_func; + arg1 = (adapter->npars[pci_func].phy_port & BIT_0); + arg1 |= (pci_func << 8); + + if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) + return err; + arg1 &= ~(0x0ff << 8); + arg1 |= (pci_func << 8); + arg1 &= ~(BIT_2 | BIT_3); + switch (esw_cfg->op_mode) { + case QLCNIC_PORT_DEFAULTS: + arg1 |= (BIT_4 | BIT_6 | BIT_7); + arg2 |= (BIT_0 | BIT_1); + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) + arg2 |= (BIT_2 | BIT_3); + if (!(esw_cfg->discard_tagged)) + arg1 &= ~BIT_4; + if (!(esw_cfg->promisc_mode)) + arg1 &= ~BIT_6; + if (!(esw_cfg->mac_learning)) + arg1 &= ~BIT_7; + if (!(esw_cfg->mac_anti_spoof)) + arg2 &= ~BIT_0; + if (!(esw_cfg->offload_flags & BIT_0)) + arg2 &= ~(BIT_1 | BIT_2 | BIT_3); + if (!(esw_cfg->offload_flags & BIT_1)) + arg2 &= ~BIT_2; + if (!(esw_cfg->offload_flags & BIT_2)) + arg2 &= ~BIT_3; + break; + case QLCNIC_ADD_VLAN: + arg1 |= (BIT_2 | BIT_5); + arg1 |= (esw_cfg->vlan_id << 16); + break; + case QLCNIC_DEL_VLAN: + arg1 |= (BIT_3 | BIT_5); + arg1 &= ~(0x0ffff << 16); + default: + return err; + } + + err = qlcnic_issue_cmd(adapter, + adapter->ahw.pci_func, + adapter->fw_hal_version, + arg1, + arg2, + 0, + QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH); + + if (err != QLCNIC_RCODE_SUCCESS) { + dev_err(&adapter->pdev->dev, + "Failed to configure eswitch port%d\n", pci_func); + } else { + dev_info(&adapter->pdev->dev, + "Configured eSwitch for port %d\n", pci_func); + } + + return err; +} + +int +qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + u32 arg1, arg2; + u8 phy_port; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + phy_port = adapter->npars[esw_cfg->pci_func].phy_port; + else + phy_port = adapter->physical_port; + arg1 = phy_port; + arg1 |= (esw_cfg->pci_func << 8); + if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) + return -EIO; + + esw_cfg->discard_tagged = !!(arg1 & BIT_4); + esw_cfg->host_vlan_tag = !!(arg1 & BIT_5); + esw_cfg->promisc_mode = !!(arg1 & BIT_6); + esw_cfg->mac_learning = !!(arg1 & BIT_7); + esw_cfg->vlan_id = LSW(arg1 >> 16); + esw_cfg->mac_anti_spoof = (arg2 & 0x1); + esw_cfg->offload_flags = ((arg2 >> 1) & 0x7); + + return 0; +} diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 39db4df0f650..eae03b5b0323 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -775,6 +775,7 @@ struct qlcnic_legacy_intr_set { #define QLCNIC_DRV_OP_MODE 0x1b2170 #define QLCNIC_MSIX_BASE 0x132110 #define QLCNIC_MAX_PCI_FUNC 8 +#define QLCNIC_MAX_VLAN_FILTERS 64 /* PCI function operational mode */ enum { @@ -783,6 +784,12 @@ enum { QLCNIC_NON_PRIV_FUNC = 2 }; +enum { + QLCNIC_PORT_DEFAULTS = 0, + QLCNIC_ADD_VLAN = 1, + QLCNIC_DEL_VLAN = 2 +}; + #define QLC_DEV_DRV_DEFAULT 0x11111111 #define LSB(x) ((uint8_t)(x)) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index c6f19c961c3d..7bb32859b928 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -506,7 +506,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) adapter->npars[pfn].active = pci_info[i].active; adapter->npars[pfn].type = pci_info[i].type; adapter->npars[pfn].phy_port = pci_info[i].default_port; - adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN; adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; } @@ -757,48 +756,65 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->max_rds_rings = MAX_RDS_RINGS; } +static int +qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, + struct qlcnic_npar_info *npar, int pci_func) +{ + struct qlcnic_esw_func_cfg esw_cfg; + esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; + esw_cfg.pci_func = pci_func; + esw_cfg.vlan_id = npar->pvid; + esw_cfg.mac_learning = npar->mac_learning; + esw_cfg.discard_tagged = npar->discard_tagged; + esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; + esw_cfg.offload_flags = npar->offload_flags; + esw_cfg.promisc_mode = npar->promisc_mode; + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + + esw_cfg.op_mode = QLCNIC_ADD_VLAN; + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + + return 0; +} + static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) { - int i, err = 0; + int i, err; struct qlcnic_npar_info *npar; struct qlcnic_info nic_info; if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - !adapter->need_fw_reset) + !adapter->need_fw_reset || adapter->op_mode != QLCNIC_MGMT_FUNC) return 0; - if (adapter->op_mode == QLCNIC_MGMT_FUNC) { - /* Set the NPAR config data after FW reset */ - for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { - npar = &adapter->npars[i]; - if (npar->type != QLCNIC_TYPE_NIC) - continue; - err = qlcnic_get_nic_info(adapter, &nic_info, i); - if (err) - goto err_out; - nic_info.min_tx_bw = npar->min_bw; - nic_info.max_tx_bw = npar->max_bw; - err = qlcnic_set_nic_info(adapter, &nic_info); - if (err) - goto err_out; - - if (npar->enable_pm) { - err = qlcnic_config_port_mirroring(adapter, - npar->dest_npar, 1, i); - if (err) - goto err_out; + /* Set the NPAR config data after FW reset */ + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + npar = &adapter->npars[i]; + if (npar->type != QLCNIC_TYPE_NIC) + continue; + err = qlcnic_get_nic_info(adapter, &nic_info, i); + if (err) + return err; + nic_info.min_tx_bw = npar->min_bw; + nic_info.max_tx_bw = npar->max_bw; + err = qlcnic_set_nic_info(adapter, &nic_info); + if (err) + return err; - } - npar->mac_learning = DEFAULT_MAC_LEARN; - npar->host_vlan_tag = 0; - npar->promisc_mode = 0; - npar->discard_tagged = 0; - npar->vlan_id = 0; + if (npar->enable_pm) { + err = qlcnic_config_port_mirroring(adapter, + npar->dest_npar, 1, i); + if (err) + return err; } + err = qlcnic_reset_eswitch_config(adapter, npar, i); + if (err) + return err; } -err_out: - return err; + return 0; } static int @@ -863,12 +879,10 @@ wait_init: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); - - qlcnic_check_options(adapter); if (qlcnic_reset_npar_config(adapter)) goto err_out; qlcnic_dev_set_npar_ready(adapter); - + qlcnic_check_options(adapter); adapter->need_fw_reset = 0; qlcnic_release_firmware(adapter); @@ -3082,9 +3096,6 @@ validate_pm_config(struct qlcnic_adapter *adapter, if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) return QL_STATUS_INVALID_PARAM; - if (!IS_VALID_MODE(pm_cfg[i].action)) - return QL_STATUS_INVALID_PARAM; - s_esw_id = adapter->npars[src_pci_func].phy_port; d_esw_id = adapter->npars[dest_pci_func].phy_port; @@ -3118,7 +3129,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, return ret; for (i = 0; i < count; i++) { pci_func = pm_cfg[i].pci_func; - action = pm_cfg[i].action; + action = !!pm_cfg[i].action; id = adapter->npars[pci_func].phy_port; ret = qlcnic_config_port_mirroring(adapter, id, action, pci_func); @@ -3129,7 +3140,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, for (i = 0; i < count; i++) { pci_func = pm_cfg[i].pci_func; id = adapter->npars[pci_func].phy_port; - adapter->npars[pci_func].enable_pm = pm_cfg[i].action; + adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action; adapter->npars[pci_func].dest_npar = id; } return size; @@ -3161,30 +3172,38 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj, static int validate_esw_config(struct qlcnic_adapter *adapter, - struct qlcnic_esw_func_cfg *esw_cfg, int count) + struct qlcnic_esw_func_cfg *esw_cfg, int count) { u8 pci_func; int i; - for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; if (pci_func >= QLCNIC_MAX_PCI_FUNC) return QL_STATUS_INVALID_PARAM; - if (adapter->npars[i].type != QLCNIC_TYPE_NIC) - return QL_STATUS_INVALID_PARAM; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) + return QL_STATUS_INVALID_PARAM; - if (esw_cfg->host_vlan_tag == 1) + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + break; + case QLCNIC_ADD_VLAN: if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) return QL_STATUS_INVALID_PARAM; - - if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) - || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) - || !IS_VALID_MODE(esw_cfg[i].mac_learning) - || !IS_VALID_MODE(esw_cfg[i].discard_tagged)) + if (!esw_cfg[i].op_type) + return QL_STATUS_INVALID_PARAM; + break; + case QLCNIC_DEL_VLAN: + if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) + return QL_STATUS_INVALID_PARAM; + if (!esw_cfg[i].op_type) + return QL_STATUS_INVALID_PARAM; + break; + default: return QL_STATUS_INVALID_PARAM; + } } - return 0; } @@ -3195,8 +3214,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_esw_func_cfg *esw_cfg; + struct qlcnic_npar_info *npar; int count, rem, i, ret; - u8 id, pci_func; + u8 pci_func; count = size / sizeof(struct qlcnic_esw_func_cfg); rem = size % sizeof(struct qlcnic_esw_func_cfg); @@ -3209,28 +3229,28 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, return ret; for (i = 0; i < count; i++) { - pci_func = esw_cfg[i].pci_func; - id = adapter->npars[pci_func].phy_port; - ret = qlcnic_config_switch_port(adapter, id, - esw_cfg[i].host_vlan_tag, - esw_cfg[i].discard_tagged, - esw_cfg[i].promisc_mode, - esw_cfg[i].mac_learning, - esw_cfg[i].pci_func, - esw_cfg[i].vlan_id); - if (ret) - return ret; + if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) + return QL_STATUS_INVALID_PARAM; } for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; - adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; - adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; - adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; - adapter->npars[pci_func].discard_tagged = - esw_cfg[i].discard_tagged; - adapter->npars[pci_func].host_vlan_tag = - esw_cfg[i].host_vlan_tag; + npar = &adapter->npars[pci_func]; + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + npar->promisc_mode = esw_cfg[i].promisc_mode; + npar->mac_learning = esw_cfg[i].mac_learning; + npar->offload_flags = esw_cfg[i].offload_flags; + npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof; + npar->discard_tagged = esw_cfg[i].discard_tagged; + break; + case QLCNIC_ADD_VLAN: + npar->pvid = esw_cfg[i].vlan_id; + break; + case QLCNIC_DEL_VLAN: + npar->pvid = 0; + break; + } } return size; @@ -3243,7 +3263,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; - int i; + u8 i; if (size != sizeof(esw_cfg)) return QL_STATUS_INVALID_PARAM; @@ -3251,12 +3271,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { if (adapter->npars[i].type != QLCNIC_TYPE_NIC) continue; - - esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; - esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; - esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged; - esw_cfg[i].vlan_id = adapter->npars[i].vlan_id; - esw_cfg[i].mac_learning = adapter->npars[i].mac_learning; + esw_cfg[i].pci_func = i; + if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i])) + return QL_STATUS_INVALID_PARAM; } memcpy(buf, &esw_cfg, size); @@ -3580,15 +3597,16 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) dev_info(dev, "failed to create crb sysfs entry\n"); if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode != QLCNIC_MGMT_FUNC) + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + if (device_create_bin_file(dev, &bin_attr_esw_config)) + dev_info(dev, "failed to create esw config sysfs entry"); + if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; if (device_create_bin_file(dev, &bin_attr_pci_config)) dev_info(dev, "failed to create pci config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_npar_config)) dev_info(dev, "failed to create npar config sysfs entry"); - if (device_create_bin_file(dev, &bin_attr_esw_config)) - dev_info(dev, "failed to create esw config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_pm_config)) dev_info(dev, "failed to create pm config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_esw_stats)) @@ -3607,12 +3625,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode != QLCNIC_MGMT_FUNC) + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + device_remove_bin_file(dev, &bin_attr_esw_config); + if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; device_remove_bin_file(dev, &bin_attr_pci_config); device_remove_bin_file(dev, &bin_attr_npar_config); - device_remove_bin_file(dev, &bin_attr_esw_config); device_remove_bin_file(dev, &bin_attr_pm_config); device_remove_bin_file(dev, &bin_attr_esw_stats); } -- cgit v1.2.3 From 0325d69b2a1feb72f11413dbfcc1705ccfc203c1 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Thu, 19 Aug 2010 05:08:26 +0000 Subject: qlcnic: configure offload setting on eswitch Device is not capable of enabling/disabling offload setting per port in case of Nic Partition.So offload settings needs to be enabled/disabled per eswitch and it will affect all the function on that eswitch. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 18 +++++- drivers/net/qlcnic/qlcnic_main.c | 121 ++++++++++++++++++++++++++++++++++-- 2 files changed, 133 insertions(+), 6 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index e38fc3d96d43..2805f88aaf7c 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -804,6 +804,20 @@ qlcnic_get_ethtool_stats(struct net_device *dev, } } +static int qlcnic_set_tx_csum(struct net_device *dev, u32 data) +{ + struct qlcnic_adapter *adapter = netdev_priv(dev); + + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return -EOPNOTSUPP; + if (data) + dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + else + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + + return 0; + +} static u32 qlcnic_get_tx_csum(struct net_device *dev) { return dev->features & NETIF_F_IP_CSUM; @@ -819,6 +833,8 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) { struct qlcnic_adapter *adapter = netdev_priv(dev); + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return -EOPNOTSUPP; if (!!data) { adapter->rx_csum = !!data; return 0; @@ -1070,7 +1086,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { .get_pauseparam = qlcnic_get_pauseparam, .set_pauseparam = qlcnic_set_pauseparam, .get_tx_csum = qlcnic_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .set_tx_csum = qlcnic_set_tx_csum, .set_sg = ethtool_op_set_sg, .get_tso = qlcnic_get_tso, .set_tso = qlcnic_set_tso, diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 7bb32859b928..aa1f6b3c3b80 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -110,6 +110,8 @@ static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); static int qlcnicvf_start_firmware(struct qlcnic_adapter *); +static void qlcnic_set_netdev_features(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); /* PCI Device ID Table */ #define ENTRY(device) \ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ @@ -756,6 +758,98 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->max_rds_rings = MAX_RDS_RINGS; } +static void +qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + qlcnic_set_netdev_features(adapter, esw_cfg); +} + +static int +qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) +{ + struct qlcnic_esw_func_cfg esw_cfg; + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return 0; + + esw_cfg.pci_func = adapter->ahw.pci_func; + if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) + return -EIO; + qlcnic_set_eswitch_port_features(adapter, &esw_cfg); + + return 0; +} + +static void +qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + struct net_device *netdev = adapter->netdev; + unsigned long features, vlan_features; + + features = (NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_GRO); + vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM); + + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) { + features |= (NETIF_F_TSO | NETIF_F_TSO6); + vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); + } + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) + features |= NETIF_F_LRO; + + if (esw_cfg->offload_flags & BIT_0) { + netdev->features |= features; + adapter->rx_csum = 1; + if (!(esw_cfg->offload_flags & BIT_1)) + netdev->features &= ~NETIF_F_TSO; + if (!(esw_cfg->offload_flags & BIT_2)) + netdev->features &= ~NETIF_F_TSO6; + } else { + netdev->features &= ~features; + adapter->rx_csum = 0; + } + + netdev->vlan_features = (features & vlan_features); +} + +static int +qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) +{ + struct qlcnic_esw_func_cfg esw_cfg; + struct qlcnic_npar_info *npar; + u8 i; + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || + adapter->need_fw_reset || + adapter->op_mode != QLCNIC_MGMT_FUNC) + return 0; + + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + if (adapter->npars[i].type != QLCNIC_TYPE_NIC) + continue; + memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); + esw_cfg.pci_func = i; + esw_cfg.offload_flags = BIT_0; + esw_cfg.mac_learning = BIT_0; + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) + esw_cfg.offload_flags |= (BIT_1 | BIT_2); + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + npar = &adapter->npars[i]; + npar->pvid = esw_cfg.vlan_id; + npar->mac_learning = esw_cfg.offload_flags; + npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; + npar->discard_tagged = esw_cfg.discard_tagged; + npar->promisc_mode = esw_cfg.promisc_mode; + npar->offload_flags = esw_cfg.offload_flags; + } + + return 0; +} + static int qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, struct qlcnic_npar_info *npar, int pci_func) @@ -879,6 +973,8 @@ wait_init: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); + if (qlcnic_set_default_offload_settings(adapter)) + goto err_out; if (qlcnic_reset_npar_config(adapter)) goto err_out; qlcnic_dev_set_npar_ready(adapter); @@ -974,6 +1070,8 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) return 0; + if (qlcnic_set_eswitch_port_config(adapter)) + return -EIO; if (qlcnic_fw_create_ctx(adapter)) return -EIO; @@ -1291,7 +1389,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) netdev->features |= NETIF_F_LRO; - netdev->irq = adapter->msix_entries[0].vector; if (qlcnic_read_mac_addr(adapter)) @@ -3216,7 +3313,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, struct qlcnic_esw_func_cfg *esw_cfg; struct qlcnic_npar_info *npar; int count, rem, i, ret; - u8 pci_func; + u8 pci_func, op_mode = 0; count = size / sizeof(struct qlcnic_esw_func_cfg); rem = size % sizeof(struct qlcnic_esw_func_cfg); @@ -3229,10 +3326,24 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, return ret; for (i = 0; i < count; i++) { - if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) - return QL_STATUS_INVALID_PARAM; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) + return QL_STATUS_INVALID_PARAM; + if (adapter->ahw.pci_func == esw_cfg[i].pci_func) + op_mode = esw_cfg[i].op_mode; + qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]); + esw_cfg[i].op_mode = op_mode; + esw_cfg[i].pci_func = adapter->ahw.pci_func; + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + qlcnic_set_eswitch_port_features(adapter, + &esw_cfg[i]); + break; + } } + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + goto out; for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; npar = &adapter->npars[pci_func]; @@ -3252,7 +3363,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, break; } } - +out: return size; } -- cgit v1.2.3 From fe4d434da8e96142e36eb22fc5cf29ef2c2df9c2 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 19 Aug 2010 05:08:27 +0000 Subject: qlcnic: support anti mac spoofing Administrator can configure to drop packet in transmit, if it doesn't match interface mac address, in case of virtual function. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_main.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9433a05555f1..b58c4119f279 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -900,6 +900,7 @@ struct qlcnic_mac_req { #define QLCNIC_BRIDGE_ENABLED 0X10 #define QLCNIC_DIAG_ENABLED 0x20 #define QLCNIC_ESWITCH_ENABLED 0x40 +#define QLCNIC_MACSPOOF 0x200 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index aa1f6b3c3b80..de4be00e31e5 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -762,6 +762,11 @@ static void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { + adapter->flags &= ~QLCNIC_MACSPOOF; + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) + if (esw_cfg->mac_anti_spoof) + adapter->flags |= QLCNIC_MACSPOOF; + qlcnic_set_netdev_features(adapter, esw_cfg); } @@ -1912,6 +1917,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_BUSY; } + if (adapter->flags & QLCNIC_MACSPOOF) { + if (compare_ether_addr(eth_hdr(skb)->h_source, + adapter->mac_addr)) + goto drop_packet; + } + frag_count = skb_shinfo(skb)->nr_frags + 1; /* 4 fragments per cmd des */ -- cgit v1.2.3 From 78f84e1a7028a77b72aebc769642a5e93d32b4f9 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 19 Aug 2010 05:08:28 +0000 Subject: qlcnic: fix npar state Privilege functions should wait for npar state to be operational. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 43 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index de4be00e31e5..6a8e9702c7b7 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -916,6 +916,27 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) return 0; } +static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) +{ + u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; + u32 npar_state; + + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + return 0; + + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { + msleep(1000); + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + } + if (!npar_opt_timeo) { + dev_err(&adapter->pdev->dev, + "Waiting for NPAR state to opertional timeout\n"); + return -EIO; + } + return 0; +} + static int qlcnic_start_firmware(struct qlcnic_adapter *adapter) { @@ -978,6 +999,11 @@ wait_init: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); + err = qlcnic_check_npar_opertional(adapter); + if (err) { + qlcnic_release_firmware(adapter); + return err; + } if (qlcnic_set_default_offload_settings(adapter)) goto err_out; if (qlcnic_reset_npar_config(adapter)) @@ -2919,29 +2945,18 @@ static void qlcnic_io_resume(struct pci_dev *pdev) FW_POLL_DELAY); } - static int qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) { int err; - u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; - u32 npar_state; err = qlcnic_can_start_firmware(adapter); if (err) return err; - npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { - msleep(1000); - npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - } - - if (!npar_opt_timeo) { - dev_err(&adapter->pdev->dev, - "Waiting for NPAR state to opertional timeout\n"); - return -EIO; - } + err = qlcnic_check_npar_opertional(adapter); + if (err) + return err; qlcnic_check_options(adapter); -- cgit v1.2.3 From 21854f029da525b5bef1dbd63c622e16a2eb2f90 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 19 Aug 2010 05:08:29 +0000 Subject: qlcnic: mark device state as failed Mark device state failed in error path. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6a8e9702c7b7..6e246c819204 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -94,7 +94,7 @@ static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding); -static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter); +static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8); static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter); static irqreturn_t qlcnic_tmp_intr(int irq, void *data); @@ -1561,7 +1561,7 @@ err_out_disable_msi: qlcnic_teardown_intr(adapter); err_out_decr_ref: - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); err_out_iounmap: qlcnic_cleanup_pci_map(adapter); @@ -1600,7 +1600,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) if (adapter->eswitch != NULL) kfree(adapter->eswitch); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); clear_bit(__QLCNIC_RESETTING, &adapter->state); @@ -1632,7 +1632,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev) if (netif_running(netdev)) qlcnic_down(adapter, netdev); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); clear_bit(__QLCNIC_RESETTING, &adapter->state); @@ -2379,7 +2379,7 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) } static void -qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter) +qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) { u32 val; @@ -2390,7 +2390,11 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter) QLC_DEV_CLR_REF_CNT(val, adapter->portnum); QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); - if (!(val & 0x11111111)) + if (failed) { + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); + dev_info(&adapter->pdev->dev, + "Device state set to Failed. Please Reboot\n"); + } else if (!(val & 0x11111111)) QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); @@ -2605,7 +2609,7 @@ err_ret: dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); netif_device_attach(adapter->netdev); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); } static void @@ -2641,8 +2645,7 @@ err_ret: dev_err(&adapter->pdev->dev, "detach failed; status=%d temp=%d\n", status, adapter->temp); netif_device_attach(netdev); - qlcnic_clr_all_drv_state(adapter); - + qlcnic_clr_all_drv_state(adapter, 1); } /*Transit NPAR state to NON Operational */ @@ -2879,7 +2882,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (netif_running(netdev)) { err = qlcnic_attach(adapter); if (err) { - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 1); clear_bit(__QLCNIC_AER, &adapter->state); netif_device_attach(netdev); return err; -- cgit v1.2.3 From 63e74e9cb7944b073c49159db934f69ca98a4ae6 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 19 Aug 2010 05:08:30 +0000 Subject: qlcnic: fix endiness in eswitch statistics Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ctx.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 74ae3b0a5ea8..315705b22be2 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -946,6 +946,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { size_t stats_size = sizeof(struct __qlcnic_esw_statistics); + struct __qlcnic_esw_statistics *stats; dma_addr_t stats_dma_t; void *stats_addr; u32 arg1; @@ -980,8 +981,21 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, LSD(stats_dma_t), QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); - if (!err) - memcpy(esw_stats, stats_addr, stats_size); + if (!err) { + stats = (struct __qlcnic_esw_statistics *)stats_addr; + esw_stats->context_id = le16_to_cpu(stats->context_id); + esw_stats->version = le16_to_cpu(stats->version); + esw_stats->size = le16_to_cpu(stats->size); + esw_stats->multicast_frames = + le64_to_cpu(stats->multicast_frames); + esw_stats->broadcast_frames = + le64_to_cpu(stats->broadcast_frames); + esw_stats->unicast_frames = le64_to_cpu(stats->unicast_frames); + esw_stats->dropped_frames = le64_to_cpu(stats->dropped_frames); + esw_stats->local_frames = le64_to_cpu(stats->local_frames); + esw_stats->errors = le64_to_cpu(stats->errors); + esw_stats->numbytes = le64_to_cpu(stats->numbytes); + } pci_free_consistent(adapter->pdev, stats_size, stats_addr, stats_dma_t); -- cgit v1.2.3 From d4066833bb1b35fefb1dd45eb2b10659d46bf151 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 19 Aug 2010 05:08:31 +0000 Subject: qlcnic: firmware initialization update Cleanup legacy code which is not valid for Qlogic CNA adapters. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 +- drivers/net/qlcnic/qlcnic_hdr.h | 3 +- drivers/net/qlcnic/qlcnic_init.c | 133 ++++++++++----------------------------- drivers/net/qlcnic/qlcnic_main.c | 38 +++-------- 4 files changed, 47 insertions(+), 131 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index b58c4119f279..43cb925fd77b 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -54,6 +54,8 @@ #define _QLCNIC_LINUX_SUBVERSION 7 #define QLCNIC_LINUX_VERSIONID "5.0.7" #define QLCNIC_DRV_IDC_VER 0x01 +#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ + (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) #define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -1233,7 +1235,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter); void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter); void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter); -int qlcnic_init_firmware(struct qlcnic_adapter *adapter); +int qlcnic_check_fw_status(struct qlcnic_adapter *adapter); void qlcnic_watchdog_task(struct work_struct *work); void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, struct qlcnic_host_rds_ring *rds_ring); diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index eae03b5b0323..794f6572e8fd 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -747,7 +747,8 @@ enum { #define QLCNIC_RESET_TIMEOUT_SECS 10 #define QLCNIC_INIT_TIMEOUT_SECS 30 - +#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 +#define QLCNIC_HEARTBEAT_RETRY_COUNT 30 #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 90766757c314..e7a399f90326 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -435,11 +435,14 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) u32 off; struct pci_dev *pdev = adapter->pdev; - /* resetall */ + QLCWR32(adapter, CRB_CMDPEG_STATE, 0); + QLCWR32(adapter, CRB_RCVPEG_STATE, 0); + qlcnic_rom_lock(adapter); QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff); qlcnic_rom_unlock(adapter); + /* Init HW CRB block */ if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) || qlcnic_rom_fast_read(adapter, 4, &n) != 0) { dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n); @@ -520,13 +523,10 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) } kfree(buf); - /* p2dn replyCount */ + /* Initialize protocol process engine */ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e); - /* disable_peg_cache 0 & 1*/ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8); - - /* peg_clr_all */ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0); @@ -535,9 +535,35 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0); + QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0); + QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0); + msleep(1); + QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); + QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); return 0; } +int +qlcnic_check_fw_status(struct qlcnic_adapter *adapter) +{ + u32 heartbit, ret = -EIO; + int retries = QLCNIC_HEARTBEAT_RETRY_COUNT; + + adapter->heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + do { + msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); + heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + if (heartbit != adapter->heartbit) { + /* Complete firmware handshake */ + QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + ret = QLCNIC_RCODE_SUCCESS; + break; + } + } while (--retries); + + return ret; +} + int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { @@ -905,35 +931,12 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) { - u32 count, old_count; u32 val, version, major, minor, build; - int i, timeout; if (adapter->need_fw_reset) return 1; - /* last attempt had failed */ - if (QLCRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) - return 1; - - old_count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - - for (i = 0; i < 10; i++) { - - timeout = msleep_interruptible(200); - if (timeout) { - QLCWR32(adapter, CRB_CMDPEG_STATE, - PHAN_INITIALIZE_FAILED); - return -EINTR; - } - - count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - if (count != old_count) - break; - } - - /* firmware is dead */ - if (count == old_count) + if (qlcnic_check_fw_status(adapter)) return 1; /* check if we have got newer or different file firmware */ @@ -1158,78 +1161,6 @@ qlcnic_release_firmware(struct qlcnic_adapter *adapter) adapter->fw = NULL; } -static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter) -{ - u32 val; - int retries = 60; - - do { - val = QLCRD32(adapter, CRB_CMDPEG_STATE); - - switch (val) { - case PHAN_INITIALIZE_COMPLETE: - case PHAN_INITIALIZE_ACK: - return 0; - case PHAN_INITIALIZE_FAILED: - goto out_err; - default: - break; - } - - msleep(500); - - } while (--retries); - - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); - -out_err: - dev_err(&adapter->pdev->dev, "Command Peg initialization not " - "complete, state: 0x%x.\n", val); - return -EIO; -} - -static int -qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter) -{ - u32 val; - int retries = 2000; - - do { - val = QLCRD32(adapter, CRB_RCVPEG_STATE); - - if (val == PHAN_PEG_RCV_INITIALIZED) - return 0; - - msleep(10); - - } while (--retries); - - if (!retries) { - dev_err(&adapter->pdev->dev, "Receive Peg initialization not " - "complete, state: 0x%x.\n", val); - return -EIO; - } - - return 0; -} - -int qlcnic_init_firmware(struct qlcnic_adapter *adapter) -{ - int err; - - err = qlcnic_cmd_peg_ready(adapter); - if (err) - return err; - - err = qlcnic_receive_peg_ready(adapter); - if (err) - return err; - - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); - - return err; -} - static void qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, struct qlcnic_fw_msg *msg) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6e246c819204..fa87a9633939 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -940,18 +940,13 @@ static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) static int qlcnic_start_firmware(struct qlcnic_adapter *adapter) { - int val, err, first_boot; + int err; err = qlcnic_can_start_firmware(adapter); if (err < 0) return err; else if (!err) - goto wait_init; - - first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc)); - if (first_boot == 0x55555555) - /* This is the first boot after power up */ - QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC); + goto check_fw_status; if (load_fw_file) qlcnic_request_firmware(adapter); @@ -963,21 +958,12 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) } err = qlcnic_need_fw_reset(adapter); - if (err < 0) - goto err_out; if (err == 0) - goto wait_init; - - if (first_boot != 0x55555555) { - QLCWR32(adapter, CRB_CMDPEG_STATE, 0); - QLCWR32(adapter, CRB_RCVPEG_STATE, 0); - qlcnic_pinit_from_rom(adapter); - msleep(1); - } - - QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); - QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); + goto set_dev_ready; + err = qlcnic_pinit_from_rom(adapter); + if (err) + goto err_out; qlcnic_set_port_mode(adapter); err = qlcnic_load_firmware(adapter); @@ -985,18 +971,14 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) goto err_out; qlcnic_release_firmware(adapter); + QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); - val = (_QLCNIC_LINUX_MAJOR << 16) - | ((_QLCNIC_LINUX_MINOR << 8)) - | (_QLCNIC_LINUX_SUBVERSION); - QLCWR32(adapter, CRB_DRIVER_VERSION, val); - -wait_init: - /* Handshake with the card before we register the devices. */ - err = qlcnic_init_firmware(adapter); +check_fw_status: + err = qlcnic_check_fw_status(adapter); if (err) goto err_out; +set_dev_ready: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); err = qlcnic_check_npar_opertional(adapter); -- cgit v1.2.3 From 091754a1652fad24664f1357ee7616e66953dd30 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Thu, 19 Aug 2010 05:08:32 +0000 Subject: qlcnic: rom lock recovery Fw can get stuck while holding pci semaphore. Driver will not be able to perform fw initialization, without this lock. Release semaphore forcefully in that case. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_hw.c | 4 ++-- drivers/net/qlcnic/qlcnic_init.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 9d40ce05cb17..5e6f4864df94 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -297,8 +297,8 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) break; if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { dev_err(&adapter->pdev->dev, - "Failed to acquire sem=%d lock;reg_id=%d\n", - sem, id_reg); + "Failed to acquire sem=%d lock; holdby=%d\n", + sem, id_reg ? QLCRD32(adapter, id_reg) : -1); return -EIO; } msleep(1); diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index e7a399f90326..a174521daa63 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -928,15 +928,25 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); } +static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter) +{ + if (qlcnic_pcie_sem_lock(adapter, 2, QLCNIC_ROM_LOCK_ID)) + dev_info(&adapter->pdev->dev, "Resetting rom_lock\n"); + + qlcnic_pcie_sem_unlock(adapter, 2); +} + int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) { u32 val, version, major, minor, build; - if (adapter->need_fw_reset) + if (qlcnic_check_fw_status(adapter)) { + qlcnic_rom_lock_recovery(adapter); return 1; + } - if (qlcnic_check_fw_status(adapter)) + if (adapter->need_fw_reset) return 1; /* check if we have got newer or different file firmware */ -- cgit v1.2.3 From 91fe8173be4f4e330c6c3ab3fd4de96c11c98444 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 19 Aug 2010 05:08:33 +0000 Subject: qlcnic: update version 5.0.8 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 43cb925fd77b..508d531a55e5 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 7 -#define QLCNIC_LINUX_VERSIONID "5.0.7" +#define _QLCNIC_LINUX_SUBVERSION 8 +#define QLCNIC_LINUX_VERSIONID "5.0.8" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3 From 2d47b45951af087c1a4439c559309b0bf90a0718 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:00:56 +0000 Subject: net: rps: reset network header before calling skb_get_rxhash() skb_get_rxhash() assumes the network header pointer of the skb is set properly after the commit: commit bfb564e7391340638afe4ad67744a8f3858e7566 Author: Krishna Kumar Date: Wed Aug 4 06:15:52 2010 +0000 core: Factor out flow calculation from get_rps_cpu Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index c1dc8a95f6ff..cf87fde3a29b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2372,6 +2372,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (!rxqueue->rps_map && !rxqueue->rps_flow_table) goto done; + skb_reset_network_header(skb); if (!skb_get_rxhash(skb)) goto done; -- cgit v1.2.3 From dbe5775bbc00116ed5699babfe17c54f32eb34c3 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:01:38 +0000 Subject: net: rps: skip fragment when computing rxhash Fragmented IP packets may have no transfer header, so when computing rxhash, we should skip them. Signed-off-by: Changli Gao Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index cf87fde3a29b..7e97e891636e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2284,7 +2284,10 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) goto done; ip = (struct iphdr *) skb->data + nhoff; - ip_proto = ip->protocol; + if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + ip_proto = 0; + else + ip_proto = ip->protocol; addr1 = (__force u32) ip->saddr; addr2 = (__force u32) ip->daddr; ihl = ip->ihl; -- cgit v1.2.3 From e760702ed8333588f9f21e7bf6597873993006f1 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:03:44 +0000 Subject: net: introduce proto_ports_offset() Introduce proto_ports_offset() for getting the position of the ports or SPI in the message of a protocol. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/in.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/in.h b/include/linux/in.h index 41d88a4689af..beeb6dee2b49 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -250,6 +250,25 @@ struct sockaddr_in { #ifdef __KERNEL__ +#include + +static inline int proto_ports_offset(int proto) +{ + switch (proto) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_DCCP: + case IPPROTO_ESP: /* SPI */ + case IPPROTO_SCTP: + case IPPROTO_UDPLITE: + return 0; + case IPPROTO_AH: /* SPI */ + return 4; + default: + return -EINVAL; + } +} + static inline bool ipv4_is_loopback(__be32 addr) { return (addr & htonl(0xff000000)) == htonl(0x7f000000); -- cgit v1.2.3 From 12fcdefb3643607c47f39906a49056cf608bb545 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:04:32 +0000 Subject: net: rps: use proto_ports_offset() to handle the AH message correctly The SPI isn't at the beginning of an AH message. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/core/dev.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 7e97e891636e..da584f5ab3d2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2266,7 +2266,7 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ __u32 __skb_get_rxhash(struct sk_buff *skb) { - int nhoff, hash = 0; + int nhoff, hash = 0, poff; struct ipv6hdr *ip6; struct iphdr *ip; u8 ip_proto; @@ -2306,24 +2306,15 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) goto done; } - switch (ip_proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_DCCP: - case IPPROTO_ESP: - case IPPROTO_AH: - case IPPROTO_SCTP: - case IPPROTO_UDPLITE: - if (pskb_may_pull(skb, (ihl * 4) + 4 + nhoff)) { - ports.v32 = * (__force u32 *) (skb->data + nhoff + - (ihl * 4)); + ports.v32 = 0; + poff = proto_ports_offset(ip_proto); + if (poff >= 0) { + nhoff += ihl * 4 + poff; + if (pskb_may_pull(skb, nhoff + 4)) { + ports.v32 = * (__force u32 *) (skb->data + nhoff); if (ports.v16[1] < ports.v16[0]) swap(ports.v16[0], ports.v16[1]); - break; } - default: - ports.v32 = 0; - break; } /* get a consistent hash (same value on both flow directions) */ -- cgit v1.2.3 From 78d3307eded853f01c5e9aaa8c0768c2f75825a3 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:05:08 +0000 Subject: net_sched: cls_flow: use proto_ports_offset() to support AH message Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/sched/cls_flow.c | 67 +++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index e17096e3913c..cd709f1294df 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -111,44 +111,41 @@ static u32 flow_get_proto(struct sk_buff *skb) } } -static int has_ports(u8 protocol) -{ - switch (protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - case IPPROTO_ESP: - return 1; - default: - return 0; - } -} - static u32 flow_get_proto_src(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): { struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol) && - pskb_network_may_pull(skb, iph->ihl * 4 + 2)) - return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 2 + poff)) { + iph = ip_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + + poff)); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; - if (!pskb_network_may_pull(skb, sizeof(*iph) + 2)) + if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ipv6_hdr(skb); - if (has_ports(iph->nexthdr)) - return ntohs(*(__be16 *)&iph[1]); + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + poff + 2)) { + iph = ipv6_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) + + poff)); + } break; } } @@ -161,24 +158,36 @@ static u32 flow_get_proto_dst(struct sk_buff *skb) switch (skb->protocol) { case htons(ETH_P_IP): { struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol) && - pskb_network_may_pull(skb, iph->ihl * 4 + 4)) - return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) { + iph = ip_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + + 2 + poff)); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; - if (!pskb_network_may_pull(skb, sizeof(*iph) + 4)) + if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ipv6_hdr(skb); - if (has_ports(iph->nexthdr)) - return ntohs(*(__be16 *)((void *)&iph[1] + 2)); + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + poff + 4)) { + iph = ipv6_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) + + poff + 2)); + } break; } } -- cgit v1.2.3 From 3d04ebb6ab2ac9a3bea7644f0d13cdf65002b870 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 20:34:40 +0000 Subject: netfilter: ipt_CLUSTERIP: use proto_ports_offset() to support AH message Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 3a43cf36db87..1e26a4897655 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -29,6 +29,7 @@ #include #include #include +#include #define CLUSTERIP_VERSION "0.8" @@ -231,24 +232,22 @@ clusterip_hashfn(const struct sk_buff *skb, { const struct iphdr *iph = ip_hdr(skb); unsigned long hashval; - u_int16_t sport, dport; - const u_int16_t *ports; - - switch (iph->protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - case IPPROTO_ICMP: - ports = (const void *)iph+iph->ihl*4; - sport = ports[0]; - dport = ports[1]; - break; - default: + u_int16_t sport = 0, dport = 0; + int poff; + + poff = proto_ports_offset(iph->protocol); + if (poff >= 0) { + const u_int16_t *ports; + u16 _ports[2]; + + ports = skb_header_pointer(skb, iph->ihl * 4 + poff, 4, _ports); + if (ports) { + sport = ports[0]; + dport = ports[1]; + } + } else { if (net_ratelimit()) pr_info("unknown protocol %u\n", iph->protocol); - sport = dport = 0; } switch (config->hash_mode) { -- cgit v1.2.3 From aca071c1c1c07bcc0b100b7c58e59790d6be6a69 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:06:39 +0000 Subject: netfilter: xt_hashlimit: use proto_ports_offset() to support AH message Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/netfilter/xt_hashlimit.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index b46a8390896d..9228ee0dc11a 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -448,6 +448,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo, { __be16 _ports[2], *ports; u8 nexthdr; + int poff; memset(dst, 0, sizeof(*dst)); @@ -492,19 +493,13 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo, return 0; } - switch (nexthdr) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - ports = skb_header_pointer(skb, protoff, sizeof(_ports), + poff = proto_ports_offset(nexthdr); + if (poff >= 0) { + ports = skb_header_pointer(skb, protoff + poff, sizeof(_ports), &_ports); - break; - default: + } else { _ports[0] = _ports[1] = 0; ports = _ports; - break; } if (!ports) return -1; -- cgit v1.2.3 From b9959c2e4460b1df1d113d829180398588bb04b4 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Aug 2010 19:07:35 +0000 Subject: net_sched: sch_sfq: use proto_ports_offset() to support AH message Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/sched/sch_sfq.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 201cbac2b32c..3cf478d012dd 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -123,40 +123,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) case htons(ETH_P_IP): { const struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) goto err; iph = ip_hdr(skb); h = (__force u32)iph->daddr; h2 = (__force u32)iph->saddr ^ iph->protocol; - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - (iph->protocol == IPPROTO_TCP || - iph->protocol == IPPROTO_UDP || - iph->protocol == IPPROTO_UDPLITE || - iph->protocol == IPPROTO_SCTP || - iph->protocol == IPPROTO_DCCP || - iph->protocol == IPPROTO_ESP) && - pskb_network_may_pull(skb, iph->ihl * 4 + 4)) - h2 ^= *(((u32*)iph) + iph->ihl); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) { + iph = ip_hdr(skb); + h2 ^= *(u32*)((void *)iph + iph->ihl * 4 + poff); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) goto err; iph = ipv6_hdr(skb); h = (__force u32)iph->daddr.s6_addr32[3]; h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; - if ((iph->nexthdr == IPPROTO_TCP || - iph->nexthdr == IPPROTO_UDP || - iph->nexthdr == IPPROTO_UDPLITE || - iph->nexthdr == IPPROTO_SCTP || - iph->nexthdr == IPPROTO_DCCP || - iph->nexthdr == IPPROTO_ESP) && - pskb_network_may_pull(skb, sizeof(*iph) + 4)) - h2 ^= *(u32*)&iph[1]; + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + 4 + poff)) { + iph = ipv6_hdr(skb); + h2 ^= *(u32*)((void *)iph + sizeof(*iph) + poff); + } break; } default: -- cgit v1.2.3 From 5dbfbc4027f819c3da92844f34f241524f99c9eb Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 18 Aug 2010 22:10:34 +0000 Subject: ep93xx_eth: Use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the ep93xx_priv struct. As the new ndo_get_stats function would just return dev->stats we can omit it. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/arm/ep93xx_eth.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 4a5ec9470aa1..5a77001b6d10 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -175,8 +175,6 @@ struct ep93xx_priv struct net_device *dev; struct napi_struct napi; - struct net_device_stats stats; - struct mii_if_info mii; u8 mdc_divisor; }; @@ -230,12 +228,6 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d pr_info("mdio write timed out\n"); } -static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) -{ - struct ep93xx_priv *ep = netdev_priv(dev); - return &(ep->stats); -} - static int ep93xx_rx(struct net_device *dev, int processed, int budget) { struct ep93xx_priv *ep = netdev_priv(dev); @@ -267,15 +259,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_RWE)) { - ep->stats.rx_errors++; + dev->stats.rx_errors++; if (rstat0 & RSTAT0_OE) - ep->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rstat0 & RSTAT0_FE) - ep->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA)) - ep->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (rstat0 & RSTAT0_CRCE) - ep->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; goto err; } @@ -300,10 +292,10 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) netif_receive_skb(skb); - ep->stats.rx_packets++; - ep->stats.rx_bytes += length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; } else { - ep->stats.rx_dropped++; + dev->stats.rx_dropped++; } err: @@ -359,7 +351,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) int entry; if (unlikely(skb->len > MAX_PKT_SIZE)) { - ep->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -415,17 +407,17 @@ static void ep93xx_tx_complete(struct net_device *dev) if (tstat0 & TSTAT0_TXWE) { int length = ep->descs->tdesc[entry].tdesc1 & 0xfff; - ep->stats.tx_packets++; - ep->stats.tx_bytes += length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += length; } else { - ep->stats.tx_errors++; + dev->stats.tx_errors++; } if (tstat0 & TSTAT0_OW) - ep->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (tstat0 & TSTAT0_TXU) - ep->stats.tx_fifo_errors++; - ep->stats.collisions += (tstat0 >> 16) & 0x1f; + dev->stats.tx_fifo_errors++; + dev->stats.collisions += (tstat0 >> 16) & 0x1f; ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1); if (ep->tx_pending == TX_QUEUE_ENTRIES) @@ -758,7 +750,6 @@ static const struct net_device_ops ep93xx_netdev_ops = { .ndo_open = ep93xx_open, .ndo_stop = ep93xx_close, .ndo_start_xmit = ep93xx_xmit, - .ndo_get_stats = ep93xx_get_stats, .ndo_do_ioctl = ep93xx_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, -- cgit v1.2.3 From 0add79e3134a618c10acabe58834ac647075111a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 18 Aug 2010 22:11:25 +0000 Subject: tehuti: Use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the bdx_priv struct. Signed-off-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/tehuti.c | 21 +++++++-------------- drivers/net/tehuti.h | 1 - 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 737df6032bbc..d808f95a87ca 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -927,13 +927,6 @@ static void bdx_update_stats(struct bdx_priv *priv) BDX_ASSERT((sizeof(struct bdx_stats) / sizeof(u64)) != i); } -static struct net_device_stats *bdx_get_stats(struct net_device *ndev) -{ - struct bdx_priv *priv = netdev_priv(ndev); - struct net_device_stats *net_stat = &priv->net_stats; - return net_stat; -} - static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len, u16 rxd_vlan); static void print_rxfd(struct rxf_desc *rxfd); @@ -1220,6 +1213,7 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) { + struct net_device *ndev = priv->ndev; struct sk_buff *skb, *skb2; struct rxd_desc *rxdd; struct rx_map *dm; @@ -1273,7 +1267,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) if (unlikely(GET_RXD_ERR(rxd_val1))) { DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1)); - priv->net_stats.rx_errors++; + ndev->stats.rx_errors++; bdx_recycle_skb(priv, rxdd); continue; } @@ -1300,11 +1294,11 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) bdx_rxdb_free_elem(db, rxdd->va_lo); } - priv->net_stats.rx_bytes += len; + ndev->stats.rx_bytes += len; skb_put(skb, len); skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->protocol = eth_type_trans(skb, priv->ndev); + skb->protocol = eth_type_trans(skb, ndev); /* Non-IP packets aren't checksum-offloaded */ if (GET_RXD_PKT_ID(rxd_val1) == 0) @@ -1316,7 +1310,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) break; } - priv->net_stats.rx_packets += done; + ndev->stats.rx_packets += done; /* FIXME: do smth to minimize pci accesses */ WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR); @@ -1712,8 +1706,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb, #ifdef BDX_LLTX ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ #endif - priv->net_stats.tx_packets++; - priv->net_stats.tx_bytes += skb->len; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; if (priv->tx_level < BDX_MIN_TX_LEVEL) { DBG("%s: %s: TX Q STOP level %d\n", @@ -1888,7 +1882,6 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = bdx_ioctl, .ndo_set_multicast_list = bdx_setmulti, - .ndo_get_stats = bdx_get_stats, .ndo_change_mtu = bdx_change_mtu, .ndo_set_mac_address = bdx_set_mac, .ndo_vlan_rx_register = bdx_vlan_rx_register, diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index 67e3b71bf705..b6ba8601e2b5 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -269,7 +269,6 @@ struct bdx_priv { u32 msg_enable; int stats_flag; struct bdx_stats hw_stats; - struct net_device_stats net_stats; struct pci_dev *pdev; struct pci_nic *nic; -- cgit v1.2.3 From 4da79504b2b41410dd56e9268c9ad403aa65e89c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 19 Aug 2010 08:52:44 +0000 Subject: qlge: pull NULL check ahead of dereference There was a dereference before NULL check issue introduced in 1e213303d "qlge: Add tx multiqueue support." I've pulled the NULL check of "net_rsp" forward a couple lines to avoid that. Also Ron Mercer says that the early exit should be above the index write. ql_write_cq_idx(rx_ring); Signed-off-by: Dan Carpenter Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 8d63f69b27d9..c9f9754f0784 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2222,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) ql_update_cq(rx_ring); prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); } + if (!net_rsp) + return 0; ql_write_cq_idx(rx_ring); tx_ring = &qdev->tx_ring[net_rsp->txq_idx]; - if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) && - net_rsp != NULL) { + if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) { if (atomic_read(&tx_ring->queue_stopped) && (atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) /* -- cgit v1.2.3 From 49e8ab03ebcacd8e37660ffec20c0c46721a2800 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 Aug 2010 06:10:45 +0000 Subject: net: build_ehash_secret() and rt_bind_peer() cleanups Now cmpxchg() is available on all arches, we can use it in build_ehash_secret() and rt_bind_peer() instead of using spinlocks. Signed-off-by: Eric Dumazet CC: Mathieu Desnoyers Signed-off-by: David S. Miller --- net/ipv4/af_inet.c | 8 +++----- net/ipv4/route.c | 9 +-------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 6a1100c25a9f..f581f77d1097 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -227,18 +227,16 @@ EXPORT_SYMBOL(inet_ehash_secret); /* * inet_ehash_secret must be set exactly once - * Instead of using a dedicated spinlock, we (ab)use inetsw_lock */ void build_ehash_secret(void) { u32 rnd; + do { get_random_bytes(&rnd, sizeof(rnd)); } while (rnd == 0); - spin_lock_bh(&inetsw_lock); - if (!inet_ehash_secret) - inet_ehash_secret = rnd; - spin_unlock_bh(&inetsw_lock); + + cmpxchg(&inet_ehash_secret, 0, rnd); } EXPORT_SYMBOL(build_ehash_secret); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3f56b6e6c6aa..85a67c9d5982 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1268,18 +1268,11 @@ skip_hashing: void rt_bind_peer(struct rtable *rt, int create) { - static DEFINE_SPINLOCK(rt_peer_lock); struct inet_peer *peer; peer = inet_getpeer(rt->rt_dst, create); - spin_lock_bh(&rt_peer_lock); - if (rt->peer == NULL) { - rt->peer = peer; - peer = NULL; - } - spin_unlock_bh(&rt_peer_lock); - if (peer) + if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) inet_putpeer(peer); } -- cgit v1.2.3 From eb4d40654505e47aa9d2035bb97f631fa61d14b4 Mon Sep 17 00:00:00 2001 From: Grégoire Baron Date: Wed, 18 Aug 2010 13:10:35 +0000 Subject: net/sched: add ACT_CSUM action to update packets checksums net/sched: add ACT_CSUM action to update packets checksums ACT_CSUM can be called just after ACT_PEDIT in order to re-compute some altered checksums in IPv4 and IPv6 packets. The following checksums are supported by this patch: - IPv4: IPv4 header, ICMP, IGMP, TCP, UDP & UDPLite - IPv6: ICMPv6, TCP, UDP & UDPLite It's possible to request in the same action to update different kind of checksums, if the packets flow mix TCP, UDP and UDPLite, ... An example of usage is done in the associated iproute2 patch. Version 3 changes: - remove useless goto instructions - improve IPv6 hop options decoding Version 2 changes: - coding style correction - remove useless arguments of some functions - use stack in tcf_csum_dump() - add tcf_csum_skb_nextlayer() to factor code Signed-off-by: Gregoire Baron Acked-by: jamal Signed-off-by: David S. Miller --- include/linux/tc_act/Kbuild | 1 + include/linux/tc_act/tc_csum.h | 32 +++ include/net/tc_act/tc_csum.h | 15 ++ net/sched/Kconfig | 10 + net/sched/Makefile | 1 + net/sched/act_csum.c | 595 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 654 insertions(+) create mode 100644 include/linux/tc_act/tc_csum.h create mode 100644 include/net/tc_act/tc_csum.h create mode 100644 net/sched/act_csum.c diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild index 76990937f4c9..67b501c302b2 100644 --- a/include/linux/tc_act/Kbuild +++ b/include/linux/tc_act/Kbuild @@ -4,3 +4,4 @@ header-y += tc_mirred.h header-y += tc_pedit.h header-y += tc_nat.h header-y += tc_skbedit.h +header-y += tc_csum.h diff --git a/include/linux/tc_act/tc_csum.h b/include/linux/tc_act/tc_csum.h new file mode 100644 index 000000000000..a047c49a3153 --- /dev/null +++ b/include/linux/tc_act/tc_csum.h @@ -0,0 +1,32 @@ +#ifndef __LINUX_TC_CSUM_H +#define __LINUX_TC_CSUM_H + +#include +#include + +#define TCA_ACT_CSUM 16 + +enum { + TCA_CSUM_UNSPEC, + TCA_CSUM_PARMS, + TCA_CSUM_TM, + __TCA_CSUM_MAX +}; +#define TCA_CSUM_MAX (__TCA_CSUM_MAX - 1) + +enum { + TCA_CSUM_UPDATE_FLAG_IPV4HDR = 1, + TCA_CSUM_UPDATE_FLAG_ICMP = 2, + TCA_CSUM_UPDATE_FLAG_IGMP = 4, + TCA_CSUM_UPDATE_FLAG_TCP = 8, + TCA_CSUM_UPDATE_FLAG_UDP = 16, + TCA_CSUM_UPDATE_FLAG_UDPLITE = 32 +}; + +struct tc_csum { + tc_gen; + + __u32 update_flags; +}; + +#endif /* __LINUX_TC_CSUM_H */ diff --git a/include/net/tc_act/tc_csum.h b/include/net/tc_act/tc_csum.h new file mode 100644 index 000000000000..9e8710be7a04 --- /dev/null +++ b/include/net/tc_act/tc_csum.h @@ -0,0 +1,15 @@ +#ifndef __NET_TC_CSUM_H +#define __NET_TC_CSUM_H + +#include +#include + +struct tcf_csum { + struct tcf_common common; + + u32 update_flags; +}; +#define to_tcf_csum(pc) \ + container_of(pc,struct tcf_csum,common) + +#endif /* __NET_TC_CSUM_H */ diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 2f691fb180d1..522d5a9a2825 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -518,6 +518,16 @@ config NET_ACT_SKBEDIT To compile this code as a module, choose M here: the module will be called act_skbedit. +config NET_ACT_CSUM + tristate "Checksum Updating" + depends on NET_CLS_ACT + ---help--- + Say Y here to update some common checksum after some direct + packet alterations. + + To compile this code as a module, choose M here: the + module will be called act_csum. + config NET_CLS_IND bool "Incoming device classification" depends on NET_CLS_U32 || NET_CLS_FW diff --git a/net/sched/Makefile b/net/sched/Makefile index f14e71bfa58f..960f5dba6304 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT) += act_nat.o obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o +obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c new file mode 100644 index 000000000000..58d7f36949da --- /dev/null +++ b/net/sched/act_csum.c @@ -0,0 +1,595 @@ +/* + * Checksum updating actions + * + * Copyright (c) 2010 Gregoire Baron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define CSUM_TAB_MASK 15 +static struct tcf_common *tcf_csum_ht[CSUM_TAB_MASK + 1]; +static u32 csum_idx_gen; +static DEFINE_RWLOCK(csum_lock); + +static struct tcf_hashinfo csum_hash_info = { + .htab = tcf_csum_ht, + .hmask = CSUM_TAB_MASK, + .lock = &csum_lock, +}; + +static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { + [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), }, +}; + +static int tcf_csum_init(struct nlattr *nla, struct nlattr *est, + struct tc_action *a, int ovr, int bind) +{ + struct nlattr *tb[TCA_CSUM_MAX + 1]; + struct tc_csum *parm; + struct tcf_common *pc; + struct tcf_csum *p; + int ret = 0, err; + + if (nla == NULL) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_CSUM_MAX, nla,csum_policy); + if (err < 0) + return err; + + if (tb[TCA_CSUM_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_CSUM_PARMS]); + + pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); + if (!pc) { + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, &csum_idx_gen, &csum_hash_info); + if (IS_ERR(pc)) + return PTR_ERR(pc); + p = to_tcf_csum(pc); + ret = ACT_P_CREATED; + } else { + p = to_tcf_csum(pc); + if (!ovr) { + tcf_hash_release(pc, bind, &csum_hash_info); + return -EEXIST; + } + } + + spin_lock_bh(&p->tcf_lock); + p->tcf_action = parm->action; + p->update_flags = parm->update_flags; + spin_unlock_bh(&p->tcf_lock); + + if (ret == ACT_P_CREATED) + tcf_hash_insert(pc, &csum_hash_info); + + return ret; +} + +static int tcf_csum_cleanup(struct tc_action *a, int bind) +{ + struct tcf_csum *p = a->priv; + return tcf_hash_release(&p->common, bind, &csum_hash_info); +} + +/** + * tcf_csum_skb_nextlayer - Get next layer pointer + * @skb: sk_buff to use + * @ihl: previous summed headers length + * @ipl: complete packet length + * @jhl: next header length + * + * Check the expected next layer availability in the specified sk_buff. + * Return the next layer pointer if pass, NULL otherwise. + */ +static void *tcf_csum_skb_nextlayer(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl, + unsigned int jhl) +{ + int ntkoff = skb_network_offset(skb); + int hl = ihl + jhl; + + if (!pskb_may_pull(skb, ipl + ntkoff) || (ipl < hl) || + (skb_cloned(skb) && + !skb_clone_writable(skb, hl + ntkoff) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) + return NULL; + else + return (void *)(skb_network_header(skb) + ihl); +} + +static int tcf_csum_ipv4_icmp(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl) +{ + struct icmphdr *icmph; + + icmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmph)); + if (icmph == NULL) + return 0; + + icmph->checksum = 0; + skb->csum = csum_partial(icmph, ipl - ihl, 0); + icmph->checksum = csum_fold(skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_igmp(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl) +{ + struct igmphdr *igmph; + + igmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*igmph)); + if (igmph == NULL) + return 0; + + igmph->csum = 0; + skb->csum = csum_partial(igmph, ipl - ihl, 0); + igmph->csum = csum_fold(skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl) +{ + struct icmp6hdr *icmp6h; + + icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h)); + if (icmp6h == NULL) + return 0; + + icmp6h->icmp6_cksum = 0; + skb->csum = csum_partial(icmp6h, ipl - ihl, 0); + icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + ipl - ihl, IPPROTO_ICMPV6, + skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph, + unsigned int ihl, unsigned int ipl) +{ + struct tcphdr *tcph; + + tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); + if (tcph == NULL) + return 0; + + tcph->check = 0; + skb->csum = csum_partial(tcph, ipl - ihl, 0); + tcph->check = tcp_v4_check(ipl - ihl, + iph->saddr, iph->daddr, skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl) +{ + struct tcphdr *tcph; + + tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); + if (tcph == NULL) + return 0; + + tcph->check = 0; + skb->csum = csum_partial(tcph, ipl - ihl, 0); + tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + ipl - ihl, IPPROTO_TCP, + skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, + unsigned int ihl, unsigned int ipl, int udplite) +{ + struct udphdr *udph; + u16 ul; + + /* Support both UDP and UDPLITE checksum algorithms, + * Don't use udph->len to get the real length without any protocol check, + * UDPLITE uses udph->len for another thing, + * Use iph->tot_len, or just ipl. + */ + + udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph)); + if (udph == NULL) + return 0; + + ul = ntohs(udph->len); + + if (udplite || udph->check) { + + udph->check = 0; + + if (udplite) { + if (ul == 0) + skb->csum = csum_partial(udph, ipl - ihl, 0); + + else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl)) + skb->csum = csum_partial(udph, ul, 0); + + else + goto ignore_obscure_skb; + } else { + if (ul != ipl - ihl) + goto ignore_obscure_skb; + + skb->csum = csum_partial(udph, ul, 0); + } + + udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, + ul, iph->protocol, + skb->csum); + + if (!udph->check) + udph->check = CSUM_MANGLED_0; + } + + skb->ip_summed = CHECKSUM_NONE; + +ignore_obscure_skb: + return 1; +} + +static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl, int udplite) +{ + struct udphdr *udph; + u16 ul; + + /* Support both UDP and UDPLITE checksum algorithms, + * Don't use udph->len to get the real length without any protocol check, + * UDPLITE uses udph->len for another thing, + * Use ip6h->payload_len + sizeof(*ip6h) ... , or just ipl. + */ + + udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph)); + if (udph == NULL) + return 0; + + ul = ntohs(udph->len); + + udph->check = 0; + + if (udplite) { + if (ul == 0) + skb->csum = csum_partial(udph, ipl - ihl, 0); + + else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl)) + skb->csum = csum_partial(udph, ul, 0); + + else + goto ignore_obscure_skb; + } else { + if (ul != ipl - ihl) + goto ignore_obscure_skb; + + skb->csum = csum_partial(udph, ul, 0); + } + + udph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ul, + udplite ? IPPROTO_UDPLITE : IPPROTO_UDP, + skb->csum); + + if (!udph->check) + udph->check = CSUM_MANGLED_0; + + skb->ip_summed = CHECKSUM_NONE; + +ignore_obscure_skb: + return 1; +} + +static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) +{ + struct iphdr *iph; + int ntkoff; + + ntkoff = skb_network_offset(skb); + + if (!pskb_may_pull(skb, sizeof(*iph) + ntkoff)) + goto fail; + + iph = ip_hdr(skb); + + switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) { + case IPPROTO_ICMP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) + if (!tcf_csum_ipv4_icmp(skb, + iph->ihl * 4, ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_IGMP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_IGMP) + if (!tcf_csum_ipv4_igmp(skb, + iph->ihl * 4, ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_TCP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) + if (!tcf_csum_ipv4_tcp(skb, iph, + iph->ihl * 4, ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_UDP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) + if (!tcf_csum_ipv4_udp(skb, iph, + iph->ihl * 4, ntohs(iph->tot_len), 0)) + goto fail; + break; + case IPPROTO_UDPLITE: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) + if (!tcf_csum_ipv4_udp(skb, iph, + iph->ihl * 4, ntohs(iph->tot_len), 1)) + goto fail; + break; + } + + if (update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) { + if (skb_cloned(skb) && + !skb_clone_writable(skb, sizeof(*iph) + ntkoff) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto fail; + + ip_send_check(iph); + } + + return 1; + +fail: + return 0; +} + +static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh, + unsigned int ixhl, unsigned int *pl) +{ + int off, len, optlen; + unsigned char *xh = (void *)ip6xh; + + off = sizeof(*ip6xh); + len = ixhl - off; + + while (len > 1) { + switch (xh[off]) + { + case IPV6_TLV_PAD0: + optlen = 1; + break; + case IPV6_TLV_JUMBO: + optlen = xh[off + 1] + 2; + if (optlen != 6 || len < 6 || (off & 3) != 2) + /* wrong jumbo option length/alignment */ + return 0; + *pl = ntohl(*(__be32 *)(xh + off + 2)); + goto done; + default: + optlen = xh[off + 1] + 2; + if (optlen > len) + /* ignore obscure options */ + goto done; + break; + } + off += optlen; + len -= optlen; + } + +done: + return 1; +} + +static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags) +{ + struct ipv6hdr *ip6h; + struct ipv6_opt_hdr *ip6xh; + unsigned int hl, ixhl; + unsigned int pl; + int ntkoff; + u8 nexthdr; + + ntkoff = skb_network_offset(skb); + + hl = sizeof(*ip6h); + + if (!pskb_may_pull(skb, hl + ntkoff)) + goto fail; + + ip6h = ipv6_hdr(skb); + + pl = ntohs(ip6h->payload_len); + nexthdr = ip6h->nexthdr; + + do { + switch (nexthdr) { + case NEXTHDR_FRAGMENT: + goto ignore_skb; + case NEXTHDR_ROUTING: + case NEXTHDR_HOP: + case NEXTHDR_DEST: + if (!pskb_may_pull(skb, hl + sizeof(*ip6xh) + ntkoff)) + goto fail; + ip6xh = (void *)(skb_network_header(skb) + hl); + ixhl = ipv6_optlen(ip6xh); + if (!pskb_may_pull(skb, hl + ixhl + ntkoff)) + goto fail; + if ((nexthdr == NEXTHDR_HOP) && + !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl))) + goto fail; + nexthdr = ip6xh->nexthdr; + hl += ixhl; + break; + case IPPROTO_ICMPV6: + if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) + if (!tcf_csum_ipv6_icmp(skb, ip6h, + hl, pl + sizeof(*ip6h))) + goto fail; + goto done; + case IPPROTO_TCP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) + if (!tcf_csum_ipv6_tcp(skb, ip6h, + hl, pl + sizeof(*ip6h))) + goto fail; + goto done; + case IPPROTO_UDP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) + if (!tcf_csum_ipv6_udp(skb, ip6h, + hl, pl + sizeof(*ip6h), 0)) + goto fail; + goto done; + case IPPROTO_UDPLITE: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) + if (!tcf_csum_ipv6_udp(skb, ip6h, + hl, pl + sizeof(*ip6h), 1)) + goto fail; + goto done; + default: + goto ignore_skb; + } + } while (pskb_may_pull(skb, hl + 1 + ntkoff)); + +done: +ignore_skb: + return 1; + +fail: + return 0; +} + +static int tcf_csum(struct sk_buff *skb, + struct tc_action *a, struct tcf_result *res) +{ + struct tcf_csum *p = a->priv; + int action; + u32 update_flags; + + spin_lock(&p->tcf_lock); + p->tcf_tm.lastuse = jiffies; + p->tcf_bstats.bytes += qdisc_pkt_len(skb); + p->tcf_bstats.packets++; + action = p->tcf_action; + update_flags = p->update_flags; + spin_unlock(&p->tcf_lock); + + if (unlikely(action == TC_ACT_SHOT)) + goto drop; + + switch (skb->protocol) { + case cpu_to_be16(ETH_P_IP): + if (!tcf_csum_ipv4(skb, update_flags)) + goto drop; + break; + case cpu_to_be16(ETH_P_IPV6): + if (!tcf_csum_ipv6(skb, update_flags)) + goto drop; + break; + } + + return action; + +drop: + spin_lock(&p->tcf_lock); + p->tcf_qstats.drops++; + spin_unlock(&p->tcf_lock); + return TC_ACT_SHOT; +} + +static int tcf_csum_dump(struct sk_buff *skb, + struct tc_action *a, int bind, int ref) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tcf_csum *p = a->priv; + struct tc_csum opt = { + .update_flags = p->update_flags, + + .index = p->tcf_index, + .action = p->tcf_action, + .refcnt = p->tcf_refcnt - ref, + .bindcnt = p->tcf_bindcnt - bind, + }; + struct tcf_t t; + + NLA_PUT(skb, TCA_CSUM_PARMS, sizeof(opt), &opt); + t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse); + t.expires = jiffies_to_clock_t(p->tcf_tm.expires); + NLA_PUT(skb, TCA_CSUM_TM, sizeof(t), &t); + + return skb->len; + +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static struct tc_action_ops act_csum_ops = { + .kind = "csum", + .hinfo = &csum_hash_info, + .type = TCA_ACT_CSUM, + .capab = TCA_CAP_NONE, + .owner = THIS_MODULE, + .act = tcf_csum, + .dump = tcf_csum_dump, + .cleanup = tcf_csum_cleanup, + .lookup = tcf_hash_search, + .init = tcf_csum_init, + .walk = tcf_generic_walker +}; + +MODULE_DESCRIPTION("Checksum updating actions"); +MODULE_LICENSE("GPL"); + +static int __init csum_init_module(void) +{ + return tcf_register_action(&act_csum_ops); +} + +static void __exit csum_cleanup_module(void) +{ + tcf_unregister_action(&act_csum_ops); +} + +module_init(csum_init_module); +module_exit(csum_cleanup_module); -- cgit v1.2.3 From 1003489e06c04d807c783a8958f2ccc9aed7a244 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 21 Aug 2010 06:13:28 +0000 Subject: net: rps: fix the wrong network header pointer __skb_get_rxhash() was broken after the commit: commit bfb564e7391340638afe4ad67744a8f3858e7566 Author: Krishna Kumar Date: Wed Aug 4 06:15:52 2010 +0000 core: Factor out flow calculation from get_rps_cpu Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/core/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index da584f5ab3d2..4d74d26b8e1a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2283,7 +2283,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(*ip) + nhoff)) goto done; - ip = (struct iphdr *) skb->data + nhoff; + ip = (struct iphdr *) (skb->data + nhoff); if (ip->frag_off & htons(IP_MF | IP_OFFSET)) ip_proto = 0; else @@ -2296,7 +2296,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff)) goto done; - ip6 = (struct ipv6hdr *) skb->data + nhoff; + ip6 = (struct ipv6hdr *) (skb->data + nhoff); ip_proto = ip6->nexthdr; addr1 = (__force u32) ip6->saddr.s6_addr32[3]; addr2 = (__force u32) ip6->daddr.s6_addr32[3]; -- cgit v1.2.3 From 00959ade36acadc00e757f87060bf6e4501d545f Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Sat, 21 Aug 2010 23:05:39 -0700 Subject: PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol) PPP: introduce "pptp" module which implements point-to-point tunneling protocol using pppox framework NET: introduce the "gre" module for demultiplexing GRE packets on version criteria (required to pptp and ip_gre may coexists) NET: ip_gre: update to use the "gre" module This patch introduces then pptp support to the linux kernel which dramatically speeds up pptp vpn connections and decreases cpu usage in comparison of existing user-space implementation (poptop/pptpclient). There is accel-pptp project (https://sourceforge.net/projects/accel-pptp/) to utilize this module, it contains plugin for pppd to use pptp in client-mode and modified pptpd (poptop) to build high-performance pptp NAS. There was many changes from initial submitted patch, most important are: 1. using rcu instead of read-write locks 2. using static bitmap instead of dynamically allocated 3. using vmalloc for memory allocation instead of BITS_PER_LONG + __get_free_pages 4. fixed many coding style issues Thanks to Eric Dumazet. Signed-off-by: Dmitry Kozlov Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- MAINTAINERS | 14 + drivers/net/Kconfig | 11 + drivers/net/Makefile | 1 + drivers/net/pptp.c | 726 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/if_pppox.h | 52 ++-- include/net/gre.h | 18 ++ net/ipv4/Kconfig | 7 + net/ipv4/Makefile | 1 + net/ipv4/gre.c | 151 ++++++++++ net/ipv4/ip_gre.c | 14 +- 10 files changed, 971 insertions(+), 24 deletions(-) create mode 100644 drivers/net/pptp.c create mode 100644 include/net/gre.h create mode 100644 net/ipv4/gre.c diff --git a/MAINTAINERS b/MAINTAINERS index b5b8baa1d70e..43c9efcd8e10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6528,6 +6528,20 @@ M: "Maciej W. Rozycki" S: Maintained F: drivers/serial/zs.* +GRE DEMULTIPLEXER DRIVER +M: Dmitry Kozlov +L: netdev@vger.kernel.org +S: Maintained +F: net/ipv4/gre.c +F: include/net/gre.h + +PPTP DRIVER +M: Dmitry Kozlov +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/pptp.c +W: http://sourceforge.net/projects/accel-pptp + THE REST M: Linus Torvalds L: linux-kernel@vger.kernel.org diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5a6895320b48..9b2a72089a68 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3192,6 +3192,17 @@ config PPPOE which contains instruction on how to use this driver (under the heading "Kernel mode PPPoE"). +config PPTP + tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)" + depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX + help + Support for PPP over IPv4.(Point-to-Point Tunneling Protocol) + + This driver requires pppd plugin to work in client mode or + modified pptpd (poptop) to work in server mode. + See http://accel-pptp.sourceforge.net/ for information how to + utilize this module. + config PPPOATM tristate "PPP over ATM" depends on ATM && PPP diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 56e8c27f77ce..0b371083d481 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -162,6 +162,7 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_PPPOL2TP) += pppox.o +obj-$(CONFIG_PPTP) += pppox.o pptp.o obj-$(CONFIG_SLIP) += slip.o obj-$(CONFIG_SLHC) += slhc.o diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c new file mode 100644 index 000000000000..761f0eced724 --- /dev/null +++ b/drivers/net/pptp.c @@ -0,0 +1,726 @@ +/* + * Point-to-Point Tunneling Protocol for Linux + * + * Authors: Dmitry Kozlov + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define PPTP_DRIVER_VERSION "0.8.5" + +#define MAX_CALLID 65535 + +static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1); +static struct pppox_sock **callid_sock; + +static DEFINE_SPINLOCK(chan_lock); + +static struct proto pptp_sk_proto __read_mostly; +static struct ppp_channel_ops pptp_chan_ops; +static const struct proto_ops pptp_ops; + +#define PPP_LCP_ECHOREQ 0x09 +#define PPP_LCP_ECHOREP 0x0A +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +#define MISSING_WINDOW 20 +#define WRAPPED(curseq, lastseq)\ + ((((curseq) & 0xffffff00) == 0) &&\ + (((lastseq) & 0xffffff00) == 0xffffff00)) + +#define PPTP_GRE_PROTO 0x880B +#define PPTP_GRE_VER 0x1 + +#define PPTP_GRE_FLAG_C 0x80 +#define PPTP_GRE_FLAG_R 0x40 +#define PPTP_GRE_FLAG_K 0x20 +#define PPTP_GRE_FLAG_S 0x10 +#define PPTP_GRE_FLAG_A 0x80 + +#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C) +#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R) +#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K) +#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S) +#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A) + +#define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header)) +struct pptp_gre_header { + u8 flags; + u8 ver; + u16 protocol; + u16 payload_len; + u16 call_id; + u32 seq; + u32 ack; +} __packed; + +static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) +{ + struct pppox_sock *sock; + struct pptp_opt *opt; + + rcu_read_lock(); + sock = rcu_dereference(callid_sock[call_id]); + if (sock) { + opt = &sock->proto.pptp; + if (opt->dst_addr.sin_addr.s_addr != s_addr) + sock = NULL; + else + sock_hold(sk_pppox(sock)); + } + rcu_read_unlock(); + + return sock; +} + +static int lookup_chan_dst(u16 call_id, __be32 d_addr) +{ + struct pppox_sock *sock; + struct pptp_opt *opt; + int i; + + rcu_read_lock(); + for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID; + i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) { + sock = rcu_dereference(callid_sock[i]); + if (!sock) + continue; + opt = &sock->proto.pptp; + if (opt->dst_addr.call_id == call_id && + opt->dst_addr.sin_addr.s_addr == d_addr) + break; + } + rcu_read_unlock(); + + return i < MAX_CALLID; +} + +static int add_chan(struct pppox_sock *sock) +{ + static int call_id; + + spin_lock(&chan_lock); + if (!sock->proto.pptp.src_addr.call_id) { + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1); + if (call_id == MAX_CALLID) { + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1); + if (call_id == MAX_CALLID) + goto out_err; + } + sock->proto.pptp.src_addr.call_id = call_id; + } else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap)) + goto out_err; + + set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock); + spin_unlock(&chan_lock); + + return 0; + +out_err: + spin_unlock(&chan_lock); + return -1; +} + +static void del_chan(struct pppox_sock *sock) +{ + spin_lock(&chan_lock); + clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL); + spin_unlock(&chan_lock); + synchronize_rcu(); +} + +static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) +{ + struct sock *sk = (struct sock *) chan->private; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + struct pptp_gre_header *hdr; + unsigned int header_len = sizeof(*hdr); + int err = 0; + int islcp; + int len; + unsigned char *data; + __u32 seq_recv; + + + struct rtable *rt; + struct net_device *tdev; + struct iphdr *iph; + int max_headroom; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; + + { + struct flowi fl = { .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = opt->dst_addr.sin_addr.s_addr, + .saddr = opt->src_addr.sin_addr.s_addr, + .tos = RT_TOS(0) } }, + .proto = IPPROTO_GRE }; + err = ip_route_output_key(&init_net, &rt, &fl); + if (err) + goto tx_error; + } + tdev = rt->dst.dev; + + max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2; + + if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { + struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); + if (!new_skb) { + ip_rt_put(rt); + goto tx_error; + } + if (skb->sk) + skb_set_owner_w(new_skb, skb->sk); + kfree_skb(skb); + skb = new_skb; + } + + data = skb->data; + islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; + + /* compress protocol field */ + if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp) + skb_pull(skb, 1); + + /* Put in the address/control bytes if necessary */ + if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) { + data = skb_push(skb, 2); + data[0] = PPP_ALLSTATIONS; + data[1] = PPP_UI; + } + + len = skb->len; + + seq_recv = opt->seq_recv; + + if (opt->ack_sent == seq_recv) + header_len -= sizeof(hdr->ack); + + /* Push down and install GRE header */ + skb_push(skb, header_len); + hdr = (struct pptp_gre_header *)(skb->data); + + hdr->flags = PPTP_GRE_FLAG_K; + hdr->ver = PPTP_GRE_VER; + hdr->protocol = htons(PPTP_GRE_PROTO); + hdr->call_id = htons(opt->dst_addr.call_id); + + hdr->flags |= PPTP_GRE_FLAG_S; + hdr->seq = htonl(++opt->seq_sent); + if (opt->ack_sent != seq_recv) { + /* send ack with this message */ + hdr->ver |= PPTP_GRE_FLAG_A; + hdr->ack = htonl(seq_recv); + opt->ack_sent = seq_recv; + } + hdr->payload_len = htons(len); + + /* Push down and install the IP header. */ + + skb_reset_transport_header(skb); + skb_push(skb, sizeof(*iph)); + skb_reset_network_header(skb); + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); + + iph = ip_hdr(skb); + iph->version = 4; + iph->ihl = sizeof(struct iphdr) >> 2; + if (ip_dont_fragment(sk, &rt->dst)) + iph->frag_off = htons(IP_DF); + else + iph->frag_off = 0; + iph->protocol = IPPROTO_GRE; + iph->tos = 0; + iph->daddr = rt->rt_dst; + iph->saddr = rt->rt_src; + iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT); + iph->tot_len = htons(skb->len); + + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; + ip_select_ident(iph, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); + +tx_error: + return 1; +} + +static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) +{ + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + int headersize, payload_len, seq; + __u8 *payload; + struct pptp_gre_header *header; + + if (!(sk->sk_state & PPPOX_CONNECTED)) { + if (sock_queue_rcv_skb(sk, skb)) + goto drop; + return NET_RX_SUCCESS; + } + + header = (struct pptp_gre_header *)(skb->data); + + /* test if acknowledgement present */ + if (PPTP_GRE_IS_A(header->ver)) { + __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? + header->ack : header->seq; /* ack in different place if S = 0 */ + + ack = ntohl(ack); + + if (ack > opt->ack_recv) + opt->ack_recv = ack; + /* also handle sequence number wrap-around */ + if (WRAPPED(ack, opt->ack_recv)) + opt->ack_recv = ack; + } + + /* test if payload present */ + if (!PPTP_GRE_IS_S(header->flags)) + goto drop; + + headersize = sizeof(*header); + payload_len = ntohs(header->payload_len); + seq = ntohl(header->seq); + + /* no ack present? */ + if (!PPTP_GRE_IS_A(header->ver)) + headersize -= sizeof(header->ack); + /* check for incomplete packet (length smaller than expected) */ + if (skb->len - headersize < payload_len) + goto drop; + + payload = skb->data + headersize; + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && + (PPP_PROTOCOL(payload) == PPP_LCP) && + ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP))) + goto allow_packet; + } else { + opt->seq_recv = seq; +allow_packet: + skb_pull(skb, headersize); + + if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto drop; + skb_pull(skb, 2); + } + + if ((*skb->data) & 1) { + /* protocol is compressed */ + skb_push(skb, 1)[0] = 0; + } + + skb->ip_summed = CHECKSUM_NONE; + skb_set_network_header(skb, skb->head-skb->data); + ppp_input(&po->chan, skb); + + return NET_RX_SUCCESS; + } +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static int pptp_rcv(struct sk_buff *skb) +{ + struct pppox_sock *po; + struct pptp_gre_header *header; + struct iphdr *iph; + + if (skb->pkt_type != PACKET_HOST) + goto drop; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + iph = ip_hdr(skb); + + header = (struct pptp_gre_header *)skb->data; + + if (ntohs(header->protocol) != PPTP_GRE_PROTO || /* PPTP-GRE protocol for PPTP */ + PPTP_GRE_IS_C(header->flags) || /* flag C should be clear */ + PPTP_GRE_IS_R(header->flags) || /* flag R should be clear */ + !PPTP_GRE_IS_K(header->flags) || /* flag K should be set */ + (header->flags&0xF) != 0) /* routing and recursion ctrl = 0 */ + /* if invalid, discard this packet */ + goto drop; + + po = lookup_chan(htons(header->call_id), iph->saddr); + if (po) { + skb_dst_drop(skb); + nf_reset(skb); + return sk_receive_skb(sk_pppox(po), skb, 0); + } +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr, + int sockaddr_len) +{ + struct sock *sk = sock->sk; + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + int error = 0; + + lock_sock(sk); + + opt->src_addr = sp->sa_addr.pptp; + if (add_chan(po)) { + release_sock(sk); + error = -EBUSY; + } + + release_sock(sk); + return error; +} + +static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, + int sockaddr_len, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + struct rtable *rt; + int error = 0; + + if (sp->sa_protocol != PX_PROTO_PPTP) + return -EINVAL; + + if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr)) + return -EALREADY; + + lock_sock(sk); + /* Check for already bound sockets */ + if (sk->sk_state & PPPOX_CONNECTED) { + error = -EBUSY; + goto end; + } + + /* Check for already disconnected sockets, on attempts to disconnect */ + if (sk->sk_state & PPPOX_DEAD) { + error = -EALREADY; + goto end; + } + + if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr) { + error = -EINVAL; + goto end; + } + + po->chan.private = sk; + po->chan.ops = &pptp_chan_ops; + + { + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = opt->dst_addr.sin_addr.s_addr, + .saddr = opt->src_addr.sin_addr.s_addr, + .tos = RT_CONN_FLAGS(sk) } }, + .proto = IPPROTO_GRE }; + security_sk_classify_flow(sk, &fl); + if (ip_route_output_key(&init_net, &rt, &fl)) { + error = -EHOSTUNREACH; + goto end; + } + sk_setup_caps(sk, &rt->dst); + } + po->chan.mtu = dst_mtu(&rt->dst); + if (!po->chan.mtu) + po->chan.mtu = PPP_MTU; + ip_rt_put(rt); + po->chan.mtu -= PPTP_HEADER_OVERHEAD; + + po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); + error = ppp_register_channel(&po->chan); + if (error) { + pr_err("PPTP: failed to register PPP channel (%d)\n", error); + goto end; + } + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state = PPPOX_CONNECTED; + + end: + release_sock(sk); + return error; +} + +static int pptp_getname(struct socket *sock, struct sockaddr *uaddr, + int *usockaddr_len, int peer) +{ + int len = sizeof(struct sockaddr_pppox); + struct sockaddr_pppox sp; + + sp.sa_family = AF_PPPOX; + sp.sa_protocol = PX_PROTO_PPTP; + sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr; + + memcpy(uaddr, &sp, len); + + *usockaddr_len = len; + + return 0; +} + +static int pptp_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + struct pppox_sock *po; + struct pptp_opt *opt; + int error = 0; + + if (!sk) + return 0; + + lock_sock(sk); + + if (sock_flag(sk, SOCK_DEAD)) { + release_sock(sk); + return -EBADF; + } + + po = pppox_sk(sk); + opt = &po->proto.pptp; + del_chan(po); + + pppox_unbind_sock(sk); + sk->sk_state = PPPOX_DEAD; + + sock_orphan(sk); + sock->sk = NULL; + + release_sock(sk); + sock_put(sk); + + return error; +} + +static void pptp_sock_destruct(struct sock *sk) +{ + if (!(sk->sk_state & PPPOX_DEAD)) { + del_chan(pppox_sk(sk)); + pppox_unbind_sock(sk); + } + skb_queue_purge(&sk->sk_receive_queue); +} + +static int pptp_create(struct net *net, struct socket *sock) +{ + int error = -ENOMEM; + struct sock *sk; + struct pppox_sock *po; + struct pptp_opt *opt; + + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto); + if (!sk) + goto out; + + sock_init_data(sock, sk); + + sock->state = SS_UNCONNECTED; + sock->ops = &pptp_ops; + + sk->sk_backlog_rcv = pptp_rcv_core; + sk->sk_state = PPPOX_NONE; + sk->sk_type = SOCK_STREAM; + sk->sk_family = PF_PPPOX; + sk->sk_protocol = PX_PROTO_PPTP; + sk->sk_destruct = pptp_sock_destruct; + + po = pppox_sk(sk); + opt = &po->proto.pptp; + + opt->seq_sent = 0; opt->seq_recv = 0; + opt->ack_recv = 0; opt->ack_sent = 0; + + error = 0; +out: + return error; +} + +static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd, + unsigned long arg) +{ + struct sock *sk = (struct sock *) chan->private; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + void __user *argp = (void __user *)arg; + int __user *p = argp; + int err, val; + + err = -EFAULT; + switch (cmd) { + case PPPIOCGFLAGS: + val = opt->ppp_flags; + if (put_user(val, p)) + break; + err = 0; + break; + case PPPIOCSFLAGS: + if (get_user(val, p)) + break; + opt->ppp_flags = val & ~SC_RCV_BITS; + err = 0; + break; + default: + err = -ENOTTY; + } + + return err; +} + +static struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, +}; + +static struct proto pptp_sk_proto __read_mostly = { + .name = "PPTP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct pppox_sock), +}; + +static const struct proto_ops pptp_ops = { + .family = AF_PPPOX, + .owner = THIS_MODULE, + .release = pptp_release, + .bind = pptp_bind, + .connect = pptp_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = pptp_getname, + .poll = sock_no_poll, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = sock_no_sendmsg, + .recvmsg = sock_no_recvmsg, + .mmap = sock_no_mmap, + .ioctl = pppox_ioctl, +}; + +static struct pppox_proto pppox_pptp_proto = { + .create = pptp_create, + .owner = THIS_MODULE, +}; + +static struct gre_protocol gre_pptp_protocol = { + .handler = pptp_rcv, +}; + +static int __init pptp_init_module(void) +{ + int err = 0; + pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); + + callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *), + GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); + if (!callid_sock) { + pr_err("PPTP: cann't allocate memory\n"); + return -ENOMEM; + } + + err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); + if (err) { + pr_err("PPTP: can't add gre protocol\n"); + goto out_mem_free; + } + + err = proto_register(&pptp_sk_proto, 0); + if (err) { + pr_err("PPTP: can't register sk_proto\n"); + goto out_gre_del_protocol; + } + + err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto); + if (err) { + pr_err("PPTP: can't register pppox_proto\n"); + goto out_unregister_sk_proto; + } + + return 0; + +out_unregister_sk_proto: + proto_unregister(&pptp_sk_proto); +out_gre_del_protocol: + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); +out_mem_free: + vfree(callid_sock); + + return err; +} + +static void __exit pptp_exit_module(void) +{ + unregister_pppox_proto(PX_PROTO_PPTP); + proto_unregister(&pptp_sk_proto); + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); + vfree(callid_sock); +} + +module_init(pptp_init_module); +module_exit(pptp_exit_module); + +MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol"); +MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 1925e0c3f162..1525b2156b2a 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -40,25 +40,35 @@ * PPPoE addressing definition */ typedef __be16 sid_t; -struct pppoe_addr{ - sid_t sid; /* Session identifier */ - unsigned char remote[ETH_ALEN]; /* Remote address */ - char dev[IFNAMSIZ]; /* Local device to use */ +struct pppoe_addr { + sid_t sid; /* Session identifier */ + unsigned char remote[ETH_ALEN]; /* Remote address */ + char dev[IFNAMSIZ]; /* Local device to use */ }; /************************************************************************ - * Protocols supported by AF_PPPOX - */ + * PPTP addressing definition + */ +struct pptp_addr { + u16 call_id; + struct in_addr sin_addr; +}; + +/************************************************************************ + * Protocols supported by AF_PPPOX + */ #define PX_PROTO_OE 0 /* Currently just PPPoE */ #define PX_PROTO_OL2TP 1 /* Now L2TP also */ -#define PX_MAX_PROTO 2 - -struct sockaddr_pppox { - sa_family_t sa_family; /* address family, AF_PPPOX */ - unsigned int sa_protocol; /* protocol identifier */ - union{ - struct pppoe_addr pppoe; - }sa_addr; +#define PX_PROTO_PPTP 2 +#define PX_MAX_PROTO 3 + +struct sockaddr_pppox { + sa_family_t sa_family; /* address family, AF_PPPOX */ + unsigned int sa_protocol; /* protocol identifier */ + union { + struct pppoe_addr pppoe; + struct pptp_addr pptp; + } sa_addr; } __packed; /* The use of the above union isn't viable because the size of this @@ -101,7 +111,7 @@ struct pppoe_tag { __be16 tag_type; __be16 tag_len; char tag_data[0]; -} __attribute ((packed)); +} __packed; /* Tag identifiers */ #define PTT_EOL __cpu_to_be16(0x0000) @@ -150,15 +160,23 @@ struct pppoe_opt { relayed to (PPPoE relaying) */ }; +struct pptp_opt { + struct pptp_addr src_addr; + struct pptp_addr dst_addr; + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; +}; #include struct pppox_sock { /* struct sock must be the first member of pppox_sock */ - struct sock sk; - struct ppp_channel chan; + struct sock sk; + struct ppp_channel chan; struct pppox_sock *next; /* for hash table */ union { struct pppoe_opt pppoe; + struct pptp_opt pptp; } proto; __be16 num; }; diff --git a/include/net/gre.h b/include/net/gre.h new file mode 100644 index 000000000000..82665474bcb7 --- /dev/null +++ b/include/net/gre.h @@ -0,0 +1,18 @@ +#ifndef __LINUX_GRE_H +#define __LINUX_GRE_H + +#include + +#define GREPROTO_CISCO 0 +#define GREPROTO_PPTP 1 +#define GREPROTO_MAX 2 + +struct gre_protocol { + int (*handler)(struct sk_buff *skb); + void (*err_handler)(struct sk_buff *skb, u32 info); +}; + +int gre_add_protocol(const struct gre_protocol *proto, u8 version); +int gre_del_protocol(const struct gre_protocol *proto, u8 version); + +#endif diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7c3a7d191249..7458bdae7e9f 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -215,8 +215,15 @@ config NET_IPIP be inserted in and removed from the running kernel whenever you want). Most people won't need this and can say N. +config NET_IPGRE_DEMUX + tristate "IP: GRE demultiplexer" + help + This is helper module to demultiplex GRE packets on GRE version field criteria. + Required by ip_gre and pptp modules. + config NET_IPGRE tristate "IP: GRE tunnels over IP" + depends on NET_IPGRE_DEMUX help Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 80ff87ce43aa..4978d22f9a75 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_NET_IPIP) += ipip.o +obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o obj-$(CONFIG_SYN_COOKIES) += syncookies.o obj-$(CONFIG_INET_AH) += ah4.o diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c new file mode 100644 index 000000000000..b546736da2e1 --- /dev/null +++ b/net/ipv4/gre.c @@ -0,0 +1,151 @@ +/* + * GRE over IPv4 demultiplexer driver + * + * Authors: Dmitry Kozlov (xeb@mail.ru) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; +static DEFINE_SPINLOCK(gre_proto_lock); + +int gre_add_protocol(const struct gre_protocol *proto, u8 version) +{ + if (version >= GREPROTO_MAX) + goto err_out; + + spin_lock(&gre_proto_lock); + if (gre_proto[version]) + goto err_out_unlock; + + rcu_assign_pointer(gre_proto[version], proto); + spin_unlock(&gre_proto_lock); + return 0; + +err_out_unlock: + spin_unlock(&gre_proto_lock); +err_out: + return -1; +} +EXPORT_SYMBOL_GPL(gre_add_protocol); + +int gre_del_protocol(const struct gre_protocol *proto, u8 version) +{ + if (version >= GREPROTO_MAX) + goto err_out; + + spin_lock(&gre_proto_lock); + if (gre_proto[version] != proto) + goto err_out_unlock; + rcu_assign_pointer(gre_proto[version], NULL); + spin_unlock(&gre_proto_lock); + synchronize_rcu(); + return 0; + +err_out_unlock: + spin_unlock(&gre_proto_lock); +err_out: + return -1; +} +EXPORT_SYMBOL_GPL(gre_del_protocol); + +static int gre_rcv(struct sk_buff *skb) +{ + const struct gre_protocol *proto; + u8 ver; + int ret; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) + goto drop; + + rcu_read_lock(); + proto = rcu_dereference(gre_proto[ver]); + if (!proto || !proto->handler) + goto drop_unlock; + ret = proto->handler(skb); + rcu_read_unlock(); + return ret; + +drop_unlock: + rcu_read_unlock(); +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static void gre_err(struct sk_buff *skb, u32 info) +{ + const struct gre_protocol *proto; + u8 ver; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) + goto drop; + + rcu_read_lock(); + proto = rcu_dereference(gre_proto[ver]); + if (!proto || !proto->err_handler) + goto drop_unlock; + proto->err_handler(skb, info); + rcu_read_unlock(); + return; + +drop_unlock: + rcu_read_unlock(); +drop: + kfree_skb(skb); +} + +static const struct net_protocol net_gre_protocol = { + .handler = gre_rcv, + .err_handler = gre_err, + .netns_ok = 1, +}; + +static int __init gre_init(void) +{ + pr_info("GRE over IPv4 demultiplexor driver"); + + if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) { + pr_err("gre: can't add protocol\n"); + return -EAGAIN; + } + + return 0; +} + +static void __exit gre_exit(void) +{ + inet_del_protocol(&net_gre_protocol, IPPROTO_GRE); +} + +module_init(gre_init); +module_exit(gre_exit); + +MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver"); +MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); +MODULE_LICENSE("GPL"); + diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 945b20a5ad50..85176895495a 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -44,6 +44,7 @@ #include #include #include +#include #ifdef CONFIG_IPV6 #include @@ -1278,10 +1279,9 @@ static void ipgre_fb_tunnel_init(struct net_device *dev) } -static const struct net_protocol ipgre_protocol = { - .handler = ipgre_rcv, - .err_handler = ipgre_err, - .netns_ok = 1, +static const struct gre_protocol ipgre_protocol = { + .handler = ipgre_rcv, + .err_handler = ipgre_err, }; static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) @@ -1663,7 +1663,7 @@ static int __init ipgre_init(void) if (err < 0) return err; - err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE); + err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); if (err < 0) { printk(KERN_INFO "ipgre init: can't add protocol\n"); goto add_proto_failed; @@ -1683,7 +1683,7 @@ out: tap_ops_failed: rtnl_link_unregister(&ipgre_link_ops); rtnl_link_failed: - inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); + gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); add_proto_failed: unregister_pernet_device(&ipgre_net_ops); goto out; @@ -1693,7 +1693,7 @@ static void __exit ipgre_fini(void) { rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_link_ops); - if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) + if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) printk(KERN_INFO "ipgre close: can't remove protocol\n"); unregister_pernet_device(&ipgre_net_ops); } -- cgit v1.2.3 From a2c483a19a96cf5cb9465f42cca34548b9211954 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 20 Aug 2010 02:55:16 +0000 Subject: atl1c: use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the atl1c_adapter struct. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c.h | 1 - drivers/net/atl1c/atl1c_main.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 52abbbdf8a08..ef4115b897bf 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -559,7 +559,6 @@ struct atl1c_adapter { struct napi_struct napi; struct atl1c_hw hw; struct atl1c_hw_stats hw_stats; - struct net_device_stats net_stats; struct mii_if_info mii; /* MII interface info */ u16 rx_buffer_len; diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index c7b8ef507ebd..61f1634ab3f8 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1562,7 +1562,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) { struct atl1c_adapter *adapter = netdev_priv(netdev); struct atl1c_hw_stats *hw_stats = &adapter->hw_stats; - struct net_device_stats *net_stats = &adapter->net_stats; + struct net_device_stats *net_stats = &netdev->stats; atl1c_update_hw_stats(adapter); net_stats->rx_packets = hw_stats->rx_ok; @@ -1590,7 +1590,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) net_stats->tx_aborted_errors = hw_stats->tx_abort_col; net_stats->tx_window_errors = hw_stats->tx_late_col; - return &adapter->net_stats; + return net_stats; } static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) @@ -1700,7 +1700,7 @@ static irqreturn_t atl1c_intr(int irq, void *data) /* link event */ if (status & (ISR_GPHY | ISR_MANUAL)) { - adapter->net_stats.tx_carrier_errors++; + netdev->stats.tx_carrier_errors++; atl1c_link_chg_event(adapter); break; } -- cgit v1.2.3 From c3227e546c574172e77616270a16a04eae561b8f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 20 Aug 2010 03:08:23 +0000 Subject: amd8111e: use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the amd8111e_priv struct. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/amd8111e.c | 14 +++++++------- drivers/net/amd8111e.h | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 1f5fc64b3224..58a0ab4923ee 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -903,18 +903,18 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER) } /* -This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values. -*/ -static struct net_device_stats *amd8111e_get_stats(struct net_device * dev) + * This function reads the mib registers and returns the hardware statistics. + * It updates previous internal driver statistics with new values. + */ +static struct net_device_stats *amd8111e_get_stats(struct net_device *dev) { struct amd8111e_priv *lp = netdev_priv(dev); void __iomem *mmio = lp->mmio; unsigned long flags; - /* struct net_device_stats *prev_stats = &lp->prev_stats; */ - struct net_device_stats* new_stats = &lp->stats; + struct net_device_stats *new_stats = &dev->stats; - if(!lp->opened) - return &lp->stats; + if (!lp->opened) + return new_stats; spin_lock_irqsave (&lp->lock, flags); /* stats.rx_packets */ diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index ac36eb6981e3..b5926af03a7e 100644 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -787,7 +787,6 @@ struct amd8111e_priv{ struct vlan_group *vlgrp; #endif char opened; - struct net_device_stats stats; unsigned int drv_rx_errors; struct amd8111e_coalesce_conf coal_conf; -- cgit v1.2.3 From 81ce790bd75d49a0d119f5d7b27405e1d9b1bd57 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 Aug 2010 23:51:33 +0000 Subject: irda: use net_device_stats from struct net_device struct net_device has its own struct net_device_stats member, so use this one instead of a private copy in the irlan_cb struct. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/irda/irlan_common.h | 1 - net/irda/irlan/irlan_eth.c | 32 +++++++++----------------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h index 73cacb3ac16c..0af8b8dfbc22 100644 --- a/include/net/irda/irlan_common.h +++ b/include/net/irda/irlan_common.h @@ -171,7 +171,6 @@ struct irlan_cb { int magic; struct list_head dev_list; struct net_device *dev; /* Ethernet device structure*/ - struct net_device_stats stats; __u32 saddr; /* Source device address */ __u32 daddr; /* Destination device address */ diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 5bb8353105cc..8ee1ff6c742f 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -45,13 +45,11 @@ static int irlan_eth_close(struct net_device *dev); static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev); static void irlan_eth_set_multicast_list( struct net_device *dev); -static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev); static const struct net_device_ops irlan_eth_netdev_ops = { .ndo_open = irlan_eth_open, .ndo_stop = irlan_eth_close, .ndo_start_xmit = irlan_eth_xmit, - .ndo_get_stats = irlan_eth_get_stats, .ndo_set_multicast_list = irlan_eth_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, @@ -208,10 +206,10 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, * tried :-) DB */ /* irttp_data_request already free the packet */ - self->stats.tx_dropped++; + dev->stats.tx_dropped++; } else { - self->stats.tx_packets++; - self->stats.tx_bytes += len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; } return NETDEV_TX_OK; @@ -226,15 +224,16 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) { struct irlan_cb *self = instance; + struct net_device *dev = self->dev; if (skb == NULL) { - ++self->stats.rx_dropped; + dev->stats.rx_dropped++; return 0; } if (skb->len < ETH_HLEN) { IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n", __func__, skb->len); - ++self->stats.rx_dropped; + dev->stats.rx_dropped++; dev_kfree_skb(skb); return 0; } @@ -244,10 +243,10 @@ int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) * might have been previously set by the low level IrDA network * device driver */ - skb->protocol = eth_type_trans(skb, self->dev); /* Remove eth header */ + skb->protocol = eth_type_trans(skb, dev); /* Remove eth header */ - self->stats.rx_packets++; - self->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; netif_rx(skb); /* Eat it! */ @@ -348,16 +347,3 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) else irlan_set_broadcast_filter(self, FALSE); } - -/* - * Function irlan_get_stats (dev) - * - * Get the current statistics for this device - * - */ -static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) -{ - struct irlan_cb *self = netdev_priv(dev); - - return &self->stats; -} -- cgit v1.2.3 From 739a91ef0625e0e4a40b835f4f891313c47915df Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 21 Aug 2010 06:23:15 +0000 Subject: net_sched: cls_flow: add key rxhash We can use rxhash to classify the traffic into flows. As rxhash maybe supplied by NIC or RPS, it is cheaper. Signed-off-by: Changli Gao Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/pkt_cls.h | 1 + net/sched/cls_flow.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 7f6ba8658abe..defbde203d07 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -332,6 +332,7 @@ enum { FLOW_KEY_SKUID, FLOW_KEY_SKGID, FLOW_KEY_VLAN_TAG, + FLOW_KEY_RXHASH, __FLOW_KEY_MAX, }; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index cd709f1294df..5b271a18bc3a 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -306,6 +306,11 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb) return tag & VLAN_VID_MASK; } +static u32 flow_get_rxhash(struct sk_buff *skb) +{ + return skb_get_rxhash(skb); +} + static u32 flow_key_get(struct sk_buff *skb, int key) { switch (key) { @@ -343,6 +348,8 @@ static u32 flow_key_get(struct sk_buff *skb, int key) return flow_get_skgid(skb); case FLOW_KEY_VLAN_TAG: return flow_get_vlan_tag(skb); + case FLOW_KEY_RXHASH: + return flow_get_rxhash(skb); default: WARN_ON(1); return 0; -- cgit v1.2.3 From 773bc97397ea2cfc2ff3c075f712aaf376ed7cb0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 22 Aug 2010 00:54:30 -0700 Subject: tokenring: remove unneeded NULL checks "fw_entry" is always non-NULL at this point and anyway release_firmware() handles NULL parameters. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/tokenring/tms380tr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 435ef7d5470f..08182fde3dcd 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -1321,14 +1321,12 @@ static int tms380tr_reset_adapter(struct net_device *dev) /* Clear CPHALT and start BUD */ SIFWRITEW(c, SIFACL); - if (fw_entry) - release_firmware(fw_entry); + release_firmware(fw_entry); return (1); } } while(count == 0); - if (fw_entry) - release_firmware(fw_entry); + release_firmware(fw_entry); printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); return (-1); } -- cgit v1.2.3 From d8287fc864643beaf1623c92aceb1ab38eae0648 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sun, 22 Aug 2010 18:37:27 -0700 Subject: net: use __be16 instead of u16 for the userspace code Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/if_pppox.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 1525b2156b2a..770e8fa669d2 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -50,8 +50,8 @@ struct pppoe_addr { * PPTP addressing definition */ struct pptp_addr { - u16 call_id; - struct in_addr sin_addr; + __be16 call_id; + struct in_addr sin_addr; }; /************************************************************************ -- cgit v1.2.3 From 2436243a39de56f03d38c74139261cc61bea8456 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Sun, 22 Aug 2010 20:31:14 -0700 Subject: net/sched: need to include net/ip6_checksum.h for the declararion of csum_ipv6_magic. Fixes this build error on PowerPC (at least): net/sched/act_csum.c: In function 'tcf_csum_ipv6_icmp': net/sched/act_csum.c:178: error: implicit declaration of function 'csum_ipv6_magic' Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/sched/act_csum.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 58d7f36949da..be41f1cc10ee 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -29,6 +29,7 @@ #include #include #include +#include #include -- cgit v1.2.3 From 05532121da0728eaedac2a0a5c3cecad3a95d765 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sun, 22 Aug 2010 21:03:33 -0700 Subject: net: 802.1q: make vlan_hwaccel_do_receive() return void vlan_hwaccel_do_receive() always returns 0, so make it return void. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 5 ++--- net/8021q/vlan_core.c | 3 +-- net/core/dev.c | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 3d870fda8c4f..a52320751bfc 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -119,7 +119,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); -extern int vlan_hwaccel_do_receive(struct sk_buff *skb); +extern void vlan_hwaccel_do_receive(struct sk_buff *skb); extern gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); @@ -147,9 +147,8 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_XMIT_SUCCESS; } -static inline int vlan_hwaccel_do_receive(struct sk_buff *skb) +static inline void vlan_hwaccel_do_receive(struct sk_buff *skb) { - return 0; } static inline gro_result_t diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 01ddb0472f86..07eeb5b99dce 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -35,7 +35,7 @@ drop: } EXPORT_SYMBOL(__vlan_hwaccel_rx); -int vlan_hwaccel_do_receive(struct sk_buff *skb) +void vlan_hwaccel_do_receive(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct vlan_rx_stats *rx_stats; @@ -69,7 +69,6 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb) break; } u64_stats_update_end(&rx_stats->syncp); - return 0; } struct net_device *vlan_dev_real_dev(const struct net_device *dev) diff --git a/net/core/dev.c b/net/core/dev.c index 7cd5237d9822..d569f88bcf80 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2841,8 +2841,8 @@ static int __netif_receive_skb(struct sk_buff *skb) if (!netdev_tstamp_prequeue) net_timestamp_check(skb); - if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb)) - return NET_RX_SUCCESS; + if (vlan_tx_tag_present(skb)) + vlan_hwaccel_do_receive(skb); /* if we've gotten here through NAPI, check netpoll */ if (netpoll_receive_skb(skb)) -- cgit v1.2.3 From cd709aa90648195e5b5823fa90eb0b3fb0e78ee4 Mon Sep 17 00:00:00 2001 From: John Feeney Date: Sun, 22 Aug 2010 17:45:53 +0000 Subject: bnx2: Add PCI Advanced Error Reporting support. Signed-off-by: John Feeney Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index e6a803f1c507..a0e02aa42214 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -49,6 +49,7 @@ #include #include #include +#include #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 @@ -7890,6 +7891,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) int rc, i, j; u32 reg; u64 dma_mask, persist_dma_mask; + int err; SET_NETDEV_DEV(dev, &pdev->dev); bp = netdev_priv(dev); @@ -7925,6 +7927,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) goto err_out_disable; } + /* AER (Advanced Error Reporting) hooks */ + err = pci_enable_pcie_error_reporting(pdev); + if (err) { + dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed " + "0x%x\n", err); + /* non-fatal, continue */ + } + pci_set_master(pdev); pci_save_state(pdev); @@ -8246,6 +8256,7 @@ err_out_unmap: } err_out_release: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable: @@ -8436,6 +8447,9 @@ bnx2_remove_one(struct pci_dev *pdev) kfree(bp->temp_stats_blk); free_netdev(dev); + + pci_disable_pcie_error_reporting(pdev); + pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); @@ -8527,25 +8541,35 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = netdev_priv(dev); + pci_ers_result_t result; + int err; rtnl_lock(); if (pci_enable_device(pdev)) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset\n"); - rtnl_unlock(); - return PCI_ERS_RESULT_DISCONNECT; + result = PCI_ERS_RESULT_DISCONNECT; + } else { + pci_set_master(pdev); + pci_restore_state(pdev); + pci_save_state(pdev); + + if (netif_running(dev)) { + bnx2_set_power_state(bp, PCI_D0); + bnx2_init_nic(bp, 1); + } + result = PCI_ERS_RESULT_RECOVERED; } - pci_set_master(pdev); - pci_restore_state(pdev); - pci_save_state(pdev); + rtnl_unlock(); - if (netif_running(dev)) { - bnx2_set_power_state(bp, PCI_D0); - bnx2_init_nic(bp, 1); + err = pci_cleanup_aer_uncorrect_error_status(pdev); + if (err) { + dev_err(&pdev->dev, + "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n", + err); /* non-fatal, continue */ } - rtnl_unlock(); - return PCI_ERS_RESULT_RECOVERED; + return result; } /** -- cgit v1.2.3 From fcb12fd2236f49aa8fdc1568ed4ebdfe4fddc6b5 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sun, 22 Aug 2010 16:41:59 +0000 Subject: net: rds: remove duplication type definitions __be* are defined in linux/types.h now, and in fact, rds.h isn't exported to user space even. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/linux/rds.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index 24bce3ded9ea..7f3971d9fc5c 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -36,15 +36,6 @@ #include -/* These sparse annotated types shouldn't be in any user - * visible header file. We should clean this up rather - * than kludging around them. */ -#ifndef __KERNEL__ -#define __be16 u_int16_t -#define __be32 u_int32_t -#define __be64 u_int64_t -#endif - #define RDS_IB_ABI_VERSION 0x301 /* -- cgit v1.2.3 From c2368e795cec561229ef66a04ac51629b918a9e8 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 17:35:32 +0000 Subject: bridge: is PACKET_LOOPBACK unlikely()? While looking at using netdev_rx_handler_register for openvswitch Jesse Gross suggested that an unlikely() might be worthwhile in that code. I'm interested to see if its appropriate for the bridge code. Cc: Jesse Gross Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/bridge/br_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 826cd5221536..6d04cfdf4541 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -141,7 +141,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) const unsigned char *dest = eth_hdr(skb)->h_dest; int (*rhook)(struct sk_buff *skb); - if (skb->pkt_type == PACKET_LOOPBACK) + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return skb; if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) -- cgit v1.2.3 From e88c64f0a42575e01c7ace903d0570bc0b7fcf85 Mon Sep 17 00:00:00 2001 From: Hagen Paul Pfeifer Date: Thu, 19 Aug 2010 06:33:05 +0000 Subject: tcp: allow effective reduction of TCP's rcv-buffer via setsockopt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Via setsockopt it is possible to reduce the socket RX buffer (SO_RCVBUF). TCP method to select the initial window and window scaling option in tcp_select_initial_window() currently misbehaves and do not consider a reduced RX socket buffer via setsockopt. Even though the server's RX buffer is reduced via setsockopt() to 256 byte (Initial Window 384 byte => 256 * 2 - (256 * 2 / 4)) the window scale option is still 7: 192.168.1.38.40676 > 78.47.222.210.5001: Flags [S], seq 2577214362, win 5840, options [mss 1460,sackOK,TS val 338417 ecr 0,nop,wscale 0], length 0 78.47.222.210.5001 > 192.168.1.38.40676: Flags [S.], seq 1570631029, ack 2577214363, win 384, options [mss 1452,sackOK,TS val 2435248895 ecr 338417,nop,wscale 7], length 0 192.168.1.38.40676 > 78.47.222.210.5001: Flags [.], ack 1, win 5840, options [nop,nop,TS val 338421 ecr 2435248895], length 0 Within tcp_select_initial_window() the original space argument - a representation of the rx buffer size - is expanded during tcp_select_initial_window(). Only sysctl_tcp_rmem[2], sysctl_rmem_max and window_clamp are considered to calculate the initial window. This patch adjust the window_clamp argument if the user explicitly reduce the receive buffer. Signed-off-by: Hagen Paul Pfeifer Cc: David S. Miller Cc: Patrick McHardy Cc: Eric Dumazet Cc: Ilpo Järvinen Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index de3bd8458588..01b94b8d9ec9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2429,6 +2429,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, __u8 rcv_wscale; /* Set this up on the first call only */ req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); + + /* limit the window selection if the user enforce a smaller rx buffer */ + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && + (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0)) + req->window_clamp = tcp_full_space(sk); + /* tcp_full_space because it is guaranteed to be the first packet */ tcp_select_initial_window(tcp_full_space(sk), mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), @@ -2555,6 +2561,11 @@ static void tcp_connect_init(struct sock *sk) tcp_initialize_rcv_mss(sk); + /* limit the window selection if the user enforce a smaller rx buffer */ + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && + (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) + tp->window_clamp = tcp_full_space(sk); + tcp_select_initial_window(tcp_full_space(sk), tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), &tp->rcv_wnd, -- cgit v1.2.3 From f502bf2bc0de4795e8dd081a2095006021c00a0f Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 18 Aug 2010 23:27:49 +0000 Subject: xen: use less generic names in netfront driver. All Xen frontend drivers have a couple of identically named functions which makes figuring out which device went wrong from a stacktrace harder than it needs to be. Rename them to something specificto the device type. Signed-off-by: Ian Campbell Cc: Jeremy Fitzhardinge Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b50fedcef8ac..788a9bc1dbac 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1395,7 +1395,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) } /* Common code used when first setting up, and when resuming. */ -static int talk_to_backend(struct xenbus_device *dev, +static int talk_to_netback(struct xenbus_device *dev, struct netfront_info *info) { const char *message; @@ -1545,7 +1545,7 @@ static int xennet_connect(struct net_device *dev) return -ENODEV; } - err = talk_to_backend(np->xbdev, np); + err = talk_to_netback(np->xbdev, np); if (err) return err; @@ -1599,7 +1599,7 @@ static int xennet_connect(struct net_device *dev) /** * Callback received when the backend's state changes. */ -static void backend_changed(struct xenbus_device *dev, +static void netback_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { struct netfront_info *np = dev_get_drvdata(&dev->dev); @@ -1801,7 +1801,7 @@ static struct xenbus_driver netfront_driver = { .probe = netfront_probe, .remove = __devexit_p(xennet_remove), .resume = netfront_resume, - .otherend_changed = backend_changed, + .otherend_changed = netback_changed, }; static int __init netif_init(void) -- cgit v1.2.3 From f3c58aceaa3f237ba43735805f4677950327b8ee Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Tue, 17 Aug 2010 21:51:18 +0000 Subject: mlx4: remove num_lro parameter As suggested by David, this parameter can die, we can use ethtool to turn LRO on/off. Compile tests only. Signed-off-by: WANG Cong Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 2 -- drivers/net/mlx4/en_main.c | 5 ----- drivers/net/mlx4/en_netdev.c | 3 +-- drivers/net/mlx4/en_rx.c | 4 ++-- drivers/net/mlx4/mlx4_en.h | 1 - 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index b275238fe70d..398d54136967 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -398,8 +398,6 @@ static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data) return -EOPNOTSUPP; if (data & ETH_FLAG_LRO) { - if (mdev->profile.num_lro == 0) - return -EOPNOTSUPP; if (!(dev->features & NETIF_F_LRO)) changed = 1; } else if (dev->features & NETIF_F_LRO) { diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 97934f1ec53a..cacac4e966ee 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -69,10 +69,6 @@ MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); /* RSS hash type mask - default to */ MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); -/* Number of LRO sessions per Rx ring (rounded up to a power of two) */ -MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS, - "Number of LRO sessions per ring or disabled (0)"); - /* Priority pausing */ MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." " Per priority bit mask"); @@ -109,7 +105,6 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) params->rss_xor = (rss_xor != 0); params->rss_mask = rss_mask & 0x1f; - params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); for (i = 1; i <= MLX4_MAX_PORTS; i++) { params->prof[i].rx_pause = 1; params->prof[i].rx_ppp = pfcrx; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index a0d8a26f5a02..d00bfe250b05 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -1038,8 +1038,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - if (mdev->profile.num_lro) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_LRO; if (mdev->LSO_support) { dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index efc3fad468db..2add04025fd0 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -320,9 +320,9 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, ring->lro.frag_align_pad = NET_IP_ALIGN; ring->lro.ip_summed = CHECKSUM_UNNECESSARY; ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY; - ring->lro.max_desc = mdev->profile.num_lro; + ring->lro.max_desc = MLX4_EN_MAX_LRO_DESCRIPTORS; ring->lro.max_aggr = MAX_SKB_FRAGS; - ring->lro.lro_arr = kcalloc(mdev->profile.num_lro, + ring->lro.lro_arr = kcalloc(MLX4_EN_MAX_LRO_DESCRIPTORS, sizeof(struct net_lro_desc), GFP_KERNEL); if (!ring->lro.lro_arr) { diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 449210994ee9..9d0932348b96 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -313,7 +313,6 @@ struct mlx4_en_port_profile { struct mlx4_en_profile { int rss_xor; - int num_lro; u8 rss_mask; u32 active_ports; u32 small_pkt_int; -- cgit v1.2.3 From 21dc330157454046dd7c494961277d76e1c957fe Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 Aug 2010 00:13:46 -0700 Subject: net: Rename skb_has_frags to skb_has_frag_list SKBs can be "fragmented" in two ways, via a page array (called skb_shinfo(skb)->frags[]) and via a list of SKBs (called skb_shinfo(skb)->frag_list). Since skb_has_frags() tests the latter, it's name is confusing since it sounds more like it's testing the former. Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- include/linux/skbuff.h | 4 ++-- net/core/dev.c | 4 ++-- net/core/skbuff.c | 18 +++++++++--------- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv6/ip6_output.c | 2 +- net/ipv6/netfilter/nf_conntrack_reasm.c | 2 +- net/ipv6/reassembly.c | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 46c36ffe20ee..ce2de8b64083 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2191,7 +2191,7 @@ static inline int net_gso_ok(int features, int gso_type) static inline int skb_gso_ok(struct sk_buff *skb, int features) { return net_gso_ok(features, skb_shinfo(skb)->gso_type) && - (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST)); + (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); } static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f067c95cf18a..f900ffcd847e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1120,7 +1120,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size); #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) -#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb)) +#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frag_list(skb)) #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) #ifdef NET_SKBUFF_DATA_USES_OFFSET @@ -1784,7 +1784,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = skb->prev) -static inline bool skb_has_frags(const struct sk_buff *skb) +static inline bool skb_has_frag_list(const struct sk_buff *skb) { return skb_shinfo(skb)->frag_list != NULL; } diff --git a/net/core/dev.c b/net/core/dev.c index d569f88bcf80..859e30ff044a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1930,7 +1930,7 @@ static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { return skb_is_nonlinear(skb) && - ((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) || + ((skb_has_frag_list(skb) && !(dev->features & NETIF_F_FRAGLIST)) || (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)))); } @@ -3090,7 +3090,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb)) goto normal; - if (skb_is_gso(skb) || skb_has_frags(skb)) + if (skb_is_gso(skb) || skb_has_frag_list(skb)) goto normal; rcu_read_lock(); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 99ef721f773d..e2535fb4985d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -340,7 +340,7 @@ static void skb_release_data(struct sk_buff *skb) put_page(skb_shinfo(skb)->frags[i].page); } - if (skb_has_frags(skb)) + if (skb_has_frag_list(skb)) skb_drop_fraglist(skb); kfree(skb->head); @@ -759,7 +759,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) skb_shinfo(n)->nr_frags = i; } - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; skb_clone_fraglist(n); } @@ -822,7 +822,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) get_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_has_frag_list(skb)) skb_clone_fraglist(skb); skb_release_data(skb); @@ -1099,7 +1099,7 @@ drop_pages: for (; i < nfrags; i++) put_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_has_frag_list(skb)) skb_drop_fraglist(skb); goto done; } @@ -1194,7 +1194,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) /* Optimization: no fragments, no reasons to preestimate * size of pulled pages. Superb. */ - if (!skb_has_frags(skb)) + if (!skb_has_frag_list(skb)) goto pull_pages; /* Estimate size of pulled pages. */ @@ -2323,7 +2323,7 @@ next_skb: st->frag_data = NULL; } - if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { + if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; @@ -2889,7 +2889,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return -ENOMEM; /* Easy case. Most of packets will go this way. */ - if (!skb_has_frags(skb)) { + if (!skb_has_frag_list(skb)) { /* A little of trouble, not enough of space for trailer. * This should not happen, when stack is tuned to generate * good frames. OK, on miss we reallocate and reserve even more @@ -2924,7 +2924,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) if (skb1->next == NULL && tailbits) { if (skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1) || + skb_has_frag_list(skb1) || skb_tailroom(skb1) < tailbits) ntail = tailbits + 128; } @@ -2933,7 +2933,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) skb_cloned(skb1) || ntail || skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1)) { + skb_has_frag_list(skb1)) { struct sk_buff *skb2; /* Fuck, we are miserable poor guys... */ diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index b7c41654dde5..f4dc879e258e 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -542,7 +542,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e807492f1777..6d2753c7ffdd 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -487,7 +487,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * LATER: this step can be merged to real generation of fragments, * we can switch to copy when see the first bad fragment. */ - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { struct sk_buff *frag; int first_len = skb_pagelen(skb); int truesizes = 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d40b330c0ee6..1838927a2243 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -637,7 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } mtu -= hlen + sizeof(struct frag_hdr); - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { int first_len = skb_pagelen(skb); int truesizes = 0; diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 13ef5bc05cf5..089c598773c7 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -413,7 +413,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 545c4141b755..8aea3f3f18d7 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -499,7 +499,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; -- cgit v1.2.3 From 67b67e365f07d6dc70f3bb266af3268bac0a4836 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 22 Aug 2010 19:41:36 +0000 Subject: ccid: ccid-2/3 code cosmetics This patch collects cosmetics-only changes to separate these from code changes: * update with regard to CodingStyle and whitespace changes, * documentation: - adding/revising comments, - remove CCID-3 RX socket documentation which is either duplicate or refers to fields that no longer exist, * expand embedded tfrc_tx_info struct inline for consistency, removing indirections via #define. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 4 ++-- net/dccp/ccids/ccid3.c | 30 ++++++++++++++++++------------ net/dccp/ccids/ccid3.h | 19 +++++++------------ 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 9b3ae9922be1..f564211c3885 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -193,8 +193,8 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) hc->tx_ssthresh = hc->tx_cwnd / 2; if (hc->tx_ssthresh < 2) hc->tx_ssthresh = 2; - hc->tx_cwnd = 1; - hc->tx_pipe = 0; + hc->tx_cwnd = 1; + hc->tx_pipe = 0; /* clear state about stuff we sent */ hc->tx_seqt = hc->tx_seqh; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 95f752986497..a666f3febf2b 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -218,9 +218,9 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) /* * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 + * RTO is 0 if and only if no feedback has been received yet. */ - if (hc->tx_t_rto == 0 || /* no feedback received yet */ - hc->tx_p == 0) { + if (hc->tx_t_rto == 0 || hc->tx_p == 0) { /* halve send rate directly */ hc->tx_x = max(hc->tx_x / 2, @@ -256,7 +256,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) * Set new timeout for the nofeedback timer. * See comments in packet_recv() regarding the value of t_RTO. */ - if (unlikely(hc->tx_t_rto == 0)) /* no feedback yet */ + if (unlikely(hc->tx_t_rto == 0)) /* no feedback received yet */ t_nfb = TFRC_INITIAL_TIMEOUT; else t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi); @@ -372,7 +372,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv; + struct ccid3_options_received *opt_recv = &hc->tx_options_received; ktime_t now; unsigned long t_nfb; u32 pinv, r_sample; @@ -386,7 +386,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_state != TFRC_SSTATE_NO_FBACK) return; - opt_recv = &hc->tx_options_received; now = ktime_get_real(); /* Estimate RTT from history if ACK number is valid */ @@ -489,11 +488,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, int rc = 0; const struct dccp_sock *dp = dccp_sk(sk); struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv; + struct ccid3_options_received *opt_recv = &hc->tx_options_received; __be32 opt_val; - opt_recv = &hc->tx_options_received; - if (opt_recv->ccid3or_seqno != dp->dccps_gsr) { opt_recv->ccid3or_seqno = dp->dccps_gsr; opt_recv->ccid3or_loss_event_rate = ~0; @@ -582,6 +579,7 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { const struct ccid3_hc_tx_sock *hc; + struct tfrc_tx_info tfrc; const void *val; /* Listen socks doesn't have a private CCID block */ @@ -591,10 +589,17 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, hc = ccid3_hc_tx_sk(sk); switch (optname) { case DCCP_SOCKOPT_CCID_TX_INFO: - if (len < sizeof(hc->tx_tfrc)) + if (len < sizeof(tfrc)) return -EINVAL; - len = sizeof(hc->tx_tfrc); - val = &hc->tx_tfrc; + tfrc.tfrctx_x = hc->tx_x; + tfrc.tfrctx_x_recv = hc->tx_x_recv; + tfrc.tfrctx_x_calc = hc->tx_x_calc; + tfrc.tfrctx_rtt = hc->tx_rtt; + tfrc.tfrctx_p = hc->tx_p; + tfrc.tfrctx_rto = hc->tx_t_rto; + tfrc.tfrctx_ipi = hc->tx_t_ipi; + len = sizeof(tfrc); + val = &tfrc; break; default: return -ENOPROTOOPT; @@ -749,10 +754,11 @@ static u32 ccid3_first_li(struct sock *sk) x_recv = scaled_div32(hc->rx_bytes_recv, delta); if (x_recv == 0) { /* would also trigger divide-by-zero */ DCCP_WARN("X_recv==0\n"); - if ((x_recv = hc->rx_x_recv) == 0) { + if (hc->rx_x_recv == 0) { DCCP_BUG("stored value of X_recv is zero"); return ~0U; } + x_recv = hc->rx_x_recv; } fval = scaled_div(hc->rx_s, hc->rx_rtt); diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 032635776653..b1864243be07 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -95,14 +95,13 @@ enum ccid3_hc_tx_states { * @tx_options_received: Parsed set of retrieved options */ struct ccid3_hc_tx_sock { - struct tfrc_tx_info tx_tfrc; -#define tx_x tx_tfrc.tfrctx_x -#define tx_x_recv tx_tfrc.tfrctx_x_recv -#define tx_x_calc tx_tfrc.tfrctx_x_calc -#define tx_rtt tx_tfrc.tfrctx_rtt -#define tx_p tx_tfrc.tfrctx_p -#define tx_t_rto tx_tfrc.tfrctx_rto -#define tx_t_ipi tx_tfrc.tfrctx_ipi + u64 tx_x; + u64 tx_x_recv; + u32 tx_x_calc; + u32 tx_rtt; + u32 tx_p; + u32 tx_t_rto; + u32 tx_t_ipi; u16 tx_s; enum ccid3_hc_tx_states tx_state:8; u8 tx_last_win_count; @@ -131,16 +130,12 @@ enum ccid3_hc_rx_states { /** * struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket - * @rx_x_recv: Receiver estimate of send rate (RFC 3448 4.3) - * @rx_rtt: Receiver estimate of rtt (non-standard) - * @rx_p: Current loss event rate (RFC 3448 5.4) * @rx_last_counter: Tracks window counter (RFC 4342, 8.1) * @rx_state: Receiver state, one of %ccid3_hc_rx_states * @rx_bytes_recv: Total sum of DCCP payload bytes * @rx_x_recv: Receiver estimate of send rate (RFC 3448, sec. 4.3) * @rx_rtt: Receiver estimate of RTT * @rx_tstamp_last_feedback: Time at which last feedback was sent - * @rx_tstamp_last_ack: Time at which last feedback was sent * @rx_hist: Packet history (loss detection + RTT sampling) * @rx_li_hist: Loss Interval database * @rx_s: Received packet size in bytes -- cgit v1.2.3 From 51c22bb510fefbb1a87c02dbd835383e6e7e3d36 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 22 Aug 2010 19:41:37 +0000 Subject: dccp ccid-3: No more CCID control blocks in LISTEN state The CCIDs are activated as last of the features, at the end of the handshake, were the LISTEN state of the master socket is inherited into the server state of the child socket. Thus, the only states visible to CCIDs now are OPEN/PARTOPEN, and the closing states. This allows to remove tests which were previously necessary to protect against referencing a socket in the listening state (in CCID-3), but which now have become redundant. As a further byproduct of enabling the CCIDs only after the connection has been fully established, several typecast-initialisations of ccid3_hc_{rx,tx}_sock can now be eliminated: * the CCID is loaded, so it is not necessary to test if it is NULL, * if it is possible to load a CCID and leave the private area NULL, then this is a bug, which should crash loudly - and earlier, * the test for state==OPEN || state==PARTOPEN now reduces only to the closing phase (e.g. when the node has received an unexpected Reset). Signed-off-by: Gerrit Renker Acked-by: Ian McDonald Signed-off-by: David S. Miller --- net/dccp/ccids/ccid3.c | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index a666f3febf2b..4340672a817c 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -564,29 +564,17 @@ static void ccid3_hc_tx_exit(struct sock *sk) static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) { - struct ccid3_hc_tx_sock *hc; - - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return; - - hc = ccid3_hc_tx_sk(sk); - info->tcpi_rto = hc->tx_t_rto; - info->tcpi_rtt = hc->tx_rtt; + info->tcpi_rto = ccid3_hc_tx_sk(sk)->tx_t_rto; + info->tcpi_rtt = ccid3_hc_tx_sk(sk)->tx_rtt; } static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { - const struct ccid3_hc_tx_sock *hc; + const struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); struct tfrc_tx_info tfrc; const void *val; - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return -EINVAL; - - hc = ccid3_hc_tx_sk(sk); switch (optname) { case DCCP_SOCKOPT_CCID_TX_INFO: if (len < sizeof(tfrc)) @@ -706,14 +694,12 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) { - const struct ccid3_hc_rx_sock *hc; + const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); __be32 x_recv, pinv; if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) return 0; - hc = ccid3_hc_rx_sk(sk); - if (dccp_packet_without_ack(skb)) return 0; @@ -876,30 +862,18 @@ static void ccid3_hc_rx_exit(struct sock *sk) static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) { - const struct ccid3_hc_rx_sock *hc; - - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return; - - hc = ccid3_hc_rx_sk(sk); - info->tcpi_ca_state = hc->rx_state; + info->tcpi_ca_state = ccid3_hc_rx_sk(sk)->rx_state; info->tcpi_options |= TCPI_OPT_TIMESTAMPS; - info->tcpi_rcv_rtt = hc->rx_rtt; + info->tcpi_rcv_rtt = ccid3_hc_rx_sk(sk)->rx_rtt; } static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { - const struct ccid3_hc_rx_sock *hc; + const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); struct tfrc_rx_info rx_info; const void *val; - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return -EINVAL; - - hc = ccid3_hc_rx_sk(sk); switch (optname) { case DCCP_SOCKOPT_CCID_RX_INFO: if (len < sizeof(rx_info)) -- cgit v1.2.3 From 30564e355511b434613aa42375317b5a07fc9f23 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 22 Aug 2010 19:41:38 +0000 Subject: dccp ccid-2: Remove redundant sanity tests This removes the ccid2_hc_tx_check_sanity function: it is redundant. Details: The tx_check_sanity function performs three tests: 1) it checks that the circular TX list is sorted - in ascending order of sequence number (ccid2s_seq) - and time (ccid2s_sent), - in the direction from `tail' (hctx_seqt) to `head' (hctx_seqh); 2) it ensures that the entire list has the length seqbufc * CCID2_SEQBUF_LEN; 3) it ensures that pipe equals the number of packets that were not marked `acked' (ccid2s_acked) between `tail' and `head'. The following argues that each of these tests is redundant, this can be verified by going through the code. (1) is not necessary, since both time and GSS increase from one packet to the next, so that subsequent insertions in tx_packet_sent (which advance the `head' pointer) will be in ascending order of time and sequence number. In (2), the length of the list is always equal to seqbufc times CCID2_SEQBUF_LEN (set to 1024) unless allocation caused an earlier failure, because: * at initialisation (tx_init), there is one chunk of size 1024 and seqbufc=1; * subsequent calls to tx_alloc_seq take place whenever head->next == tail in tx_packet_sent; then a new chunk of size 1024 is inserted between head and tail, and seqbufc is incremented by one. To show that (3) is redundant requires looking at two cases. The `pipe' variable of the TX socket is incremented only in tx_packet_sent, and decremented in tx_packet_recv. When head == tail (TX history empty) then pipe should be 0, which is the case directly after initialisation and after a retransmission timeout has occurred (ccid2_hc_tx_rto_expire). The first case involves parsing Ack Vectors for packets recorded in the live portion of the buffer, between tail and head. For each packet marked by the receiver as received (state 0) or ECN-marked (state 1), pipe is decremented by one, so for all such packets the BUG_ON in tx_check_sanity will not trigger. The second case is the loss detection in the second half of tx_packet_recv, below the comment "Check for NUMDUPACK". The first while-loop here ensures that the sequence number of `seqp' is either above or equal to `high_ack', or otherwise equal to the highest sequence number sent so far (of the entry head->prev, as head points to the next unsent entry). The next while-loop ("while (1)") counts the number of acked packets starting from that position of seqp, going backwards in the direction from head->prev to tail. If NUMDUPACK=3 such packets were counted within this loop, `seqp' points to the last acknowledged packet of these, and the "if (done == NUMDUPACK)" block is entered next. The while-loop contained within that block in turn traverses the list backwards, from head to tail; the position of `seqp' is saved in the variable `last_acked'. For each packet not marked as `acked', a congestion event is triggered within the loop, and pipe is decremented. The loop terminates when `seqp' has reached `tail', whereupon tail is set to the position previously stored in `last_acked'. Thus, between `last_acked' and the previous position of `tail', - pipe has been decremented earlier if the packet was marked as state 0 or 1; - pipe was decremented if the packet was not marked as acked. That is, pipe has been decremented by the number of packets between `last_acked' and the previous position of `tail'. As a consequence, pipe now again reflects the number of packets which have not (yet) been acked between the new position of tail (at `last_acked') and head->prev, or 0 if head==tail. The result is that the BUG_ON condition in check_sanity will also not be triggered, hence the test (3) is also redundant. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 52 -------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index f564211c3885..28499e030f33 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -33,51 +33,8 @@ #ifdef CONFIG_IP_DCCP_CCID2_DEBUG static int ccid2_debug; #define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a) - -static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hc) -{ - int len = 0; - int pipe = 0; - struct ccid2_seq *seqp = hc->tx_seqh; - - /* there is data in the chain */ - if (seqp != hc->tx_seqt) { - seqp = seqp->ccid2s_prev; - len++; - if (!seqp->ccid2s_acked) - pipe++; - - while (seqp != hc->tx_seqt) { - struct ccid2_seq *prev = seqp->ccid2s_prev; - - len++; - if (!prev->ccid2s_acked) - pipe++; - - /* packets are sent sequentially */ - BUG_ON(dccp_delta_seqno(seqp->ccid2s_seq, - prev->ccid2s_seq ) >= 0); - BUG_ON(time_before(seqp->ccid2s_sent, - prev->ccid2s_sent)); - - seqp = prev; - } - } - - BUG_ON(pipe != hc->tx_pipe); - ccid2_pr_debug("len of chain=%d\n", len); - - do { - seqp = seqp->ccid2s_prev; - len++; - } while (seqp != hc->tx_seqh); - - ccid2_pr_debug("total len=%d\n", len); - BUG_ON(len != hc->tx_seqbufc * CCID2_SEQBUF_LEN); -} #else #define ccid2_pr_debug(format, a...) -#define ccid2_hc_tx_check_sanity(hc) #endif static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc) @@ -178,8 +135,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) ccid2_pr_debug("RTO_EXPIRE\n"); - ccid2_hc_tx_check_sanity(hc); - /* back-off timer */ hc->tx_rto <<= 1; @@ -204,7 +159,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) hc->tx_rpseq = 0; hc->tx_rpdupack = -1; ccid2_change_l_ack_ratio(sk, 1); - ccid2_hc_tx_check_sanity(hc); out: bh_unlock_sock(sk); sock_put(sk); @@ -312,7 +266,6 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) } } while (0); ccid2_pr_debug("=========\n"); - ccid2_hc_tx_check_sanity(hc); #endif } @@ -510,7 +463,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) int done = 0; unsigned int maxincr = 0; - ccid2_hc_tx_check_sanity(hc); /* check reverse path congestion */ seqno = DCCP_SKB_CB(skb)->dccpd_seq; @@ -694,8 +646,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_seqt = hc->tx_seqt->ccid2s_next; } - - ccid2_hc_tx_check_sanity(hc); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) @@ -730,8 +680,6 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_last_cong = jiffies; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk); - - ccid2_hc_tx_check_sanity(hc); return 0; } -- cgit v1.2.3 From c38c92a84a9291a3d0eaf6a13650a11961ae964f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 22 Aug 2010 19:41:39 +0000 Subject: dccp ccid-2: Simplify dec_pipe and rearming of RTO timer This removes the dec_pipe function and improves the way the RTO timer is rearmed when a new acknowledgment comes in. Details and justification for removal: -------------------------------------- 1) The BUG_ON in dec_pipe is never triggered: pipe is only decremented for TX history entries between tail and head, for which it had previously been incremented in tx_packet_sent; and it is not decremented twice for the same entry, since it is - either decremented when a corresponding Ack Vector cell in state 0 or 1 was received (and then ccid2s_acked==1), - or it is decremented when ccid2s_acked==0, as part of the loss detection in tx_packet_recv (and hence it can not have been decremented earlier). 2) Restarting the RTO timer happens for every single entry in each Ack Vector parsed by tx_packet_recv (according to RFC 4340, 11.4 this can happen up to 16192 times per Ack Vector). 3) The RTO timer should not be restarted when all outstanding data has been acknowledged. This is currently done similar to (2), in dec_pipe, when pipe has reached 0. The patch onsolidates the code which rearms the RTO timer, combining the segments from new_ack and dec_pipe. As a result, the code becomes clearer (compare with tcp_rearm_rto()). Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 28499e030f33..f7f5069b1e84 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -413,23 +413,6 @@ static inline void ccid2_new_ack(struct sock *sk, hc->tx_srtt, hc->tx_rttvar, hc->tx_rto, HZ, r); } - - /* we got a new ack, so re-start RTO timer */ - ccid2_hc_tx_kill_rto_timer(sk); - ccid2_start_rto_timer(sk); -} - -static void ccid2_hc_tx_dec_pipe(struct sock *sk) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - if (hc->tx_pipe == 0) - DCCP_BUG("pipe == 0"); - else - hc->tx_pipe--; - - if (hc->tx_pipe == 0) - ccid2_hc_tx_kill_rto_timer(sk); } static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) @@ -572,7 +555,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) seqp->ccid2s_acked = 1; ccid2_pr_debug("Got ack for %llu\n", (unsigned long long)seqp->ccid2s_seq); - ccid2_hc_tx_dec_pipe(sk); + hc->tx_pipe--; } if (seqp == hc->tx_seqt) { done = 1; @@ -629,7 +612,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) * one ack vector. */ ccid2_congestion_event(sk, seqp); - ccid2_hc_tx_dec_pipe(sk); + hc->tx_pipe--; } if (seqp == hc->tx_seqt) break; @@ -646,6 +629,12 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_seqt = hc->tx_seqt->ccid2s_next; } + + /* restart RTO timer if not all outstanding data has been acked */ + if (hc->tx_pipe == 0) + sk_stop_timer(sk, &hc->tx_rtotimer); + else + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) -- cgit v1.2.3 From 231cc2aaf14bad3b2325be0b19b8385ff5e75485 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 22 Aug 2010 19:41:40 +0000 Subject: dccp ccid-2: Replace broken RTT estimator with better algorithm The current CCID-2 RTT estimator code is in parts broken and lags behind the suggestions in RFC2988 of using scaled variants for SRTT/RTTVAR. That code is replaced by the present patch, which reuses the Linux TCP RTT estimator code. Further details: ---------------- 1. The minimum RTO of previously one second has been replaced with TCP's, since RFC4341, sec. 5 says that the minimum of 1 sec. (suggested in RFC2988, 2.4) is not necessary. Instead, the TCP_RTO_MIN is used, which agrees with DCCP's concept of a default RTT (RFC 4340, 3.4). 2. The maximum RTO has been set to DCCP_RTO_MAX (64 sec), which agrees with RFC2988, (2.5). 3. De-inlined the function ccid2_new_ack(). 4. Added a FIXME: the RTT is sampled several times per Ack Vector, which will give the wrong estimate. It should be replaced with one sample per Ack. However, at the moment this can not be resolved easily, since - it depends on TX history code (which also needs some work), - the cleanest solution is not to use the `sent' time at all (saves 4 bytes per entry) and use DCCP timestamps / elapsed time to estimated the RTT, which however is non-trivial to get right (but needs to be done). Reasons for reusing the Linux TCP estimator algorithm: ------------------------------------------------------ Some time was spent to find a better alternative, using basic RFC2988 as a first step. Further analysis and experimentation showed that the Linux TCP RTO estimator is superior to a basic RFC2988 implementation. A summary is on http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/ccid2/rto_estimator/ In addition, this estimator fared well in a recent empirical evaluation: Rewaskar, Sushant, Jasleen Kaur and F. Donelson Smith. A Performance Study of Loss Detection/Recovery in Real-world TCP Implementations. Proceedings of 15th IEEE International Conference on Network Protocols (ICNP-07), 2007. Thus there is significant benefit in reusing the existing TCP code. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 169 +++++++++++++++++++++++++++---------------------- net/dccp/ccids/ccid2.h | 20 ++++-- 2 files changed, 108 insertions(+), 81 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index f7f5069b1e84..7af3106c1f94 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -113,19 +113,12 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) dp->dccps_l_ack_ratio = val; } -static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hc, long val) -{ - ccid2_pr_debug("change SRTT to %ld\n", val); - hc->tx_srtt = val; -} - static void ccid2_start_rto_timer(struct sock *sk); static void ccid2_hc_tx_rto_expire(unsigned long data) { struct sock *sk = (struct sock *)data; struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - long s; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -137,10 +130,8 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) /* back-off timer */ hc->tx_rto <<= 1; - - s = hc->tx_rto / HZ; - if (s > 60) - hc->tx_rto = 60 * HZ; + if (hc->tx_rto > DCCP_RTO_MAX) + hc->tx_rto = DCCP_RTO_MAX; ccid2_start_rto_timer(sk); @@ -168,7 +159,7 @@ static void ccid2_start_rto_timer(struct sock *sk) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - ccid2_pr_debug("setting RTO timeout=%ld\n", hc->tx_rto); + ccid2_pr_debug("setting RTO timeout=%u\n", hc->tx_rto); BUG_ON(timer_pending(&hc->tx_rtotimer)); sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); @@ -339,9 +330,86 @@ static void ccid2_hc_tx_kill_rto_timer(struct sock *sk) ccid2_pr_debug("deleted RTO timer\n"); } -static inline void ccid2_new_ack(struct sock *sk, - struct ccid2_seq *seqp, - unsigned int *maxincr) +/** + * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm + * This code is almost identical with TCP's tcp_rtt_estimator(), since + * - it has a higher sampling frequency (recommended by RFC 1323), + * - the RTO does not collapse into RTT due to RTTVAR going towards zero, + * - it is simple (cf. more complex proposals such as Eifel timer or research + * which suggests that the gain should be set according to window size), + * - in tests it was found to work well with CCID2 [gerrit]. + */ +static void ccid2_rtt_estimator(struct sock *sk, const long mrtt) +{ + struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + long m = mrtt ? : 1; + + if (hc->tx_srtt == 0) { + /* First measurement m */ + hc->tx_srtt = m << 3; + hc->tx_mdev = m << 1; + + hc->tx_mdev_max = max(TCP_RTO_MIN, hc->tx_mdev); + hc->tx_rttvar = hc->tx_mdev_max; + hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; + } else { + /* Update scaled SRTT as SRTT += 1/8 * (m - SRTT) */ + m -= (hc->tx_srtt >> 3); + hc->tx_srtt += m; + + /* Similarly, update scaled mdev with regard to |m| */ + if (m < 0) { + m = -m; + m -= (hc->tx_mdev >> 2); + /* + * This neutralises RTO increase when RTT < SRTT - mdev + * (see P. Sarolahti, A. Kuznetsov,"Congestion Control + * in Linux TCP", USENIX 2002, pp. 49-62). + */ + if (m > 0) + m >>= 3; + } else { + m -= (hc->tx_mdev >> 2); + } + hc->tx_mdev += m; + + if (hc->tx_mdev > hc->tx_mdev_max) { + hc->tx_mdev_max = hc->tx_mdev; + if (hc->tx_mdev_max > hc->tx_rttvar) + hc->tx_rttvar = hc->tx_mdev_max; + } + + /* + * Decay RTTVAR at most once per flight, exploiting that + * 1) pipe <= cwnd <= Sequence_Window = W (RFC 4340, 7.5.2) + * 2) AWL = GSS-W+1 <= GAR <= GSS (RFC 4340, 7.5.1) + * GAR is a useful bound for FlightSize = pipe. + * AWL is probably too low here, as it over-estimates pipe. + */ + if (after48(dccp_sk(sk)->dccps_gar, hc->tx_rtt_seq)) { + if (hc->tx_mdev_max < hc->tx_rttvar) + hc->tx_rttvar -= (hc->tx_rttvar - + hc->tx_mdev_max) >> 2; + hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; + hc->tx_mdev_max = TCP_RTO_MIN; + } + } + + /* + * Set RTO from SRTT and RTTVAR + * As in TCP, 4 * RTTVAR >= TCP_RTO_MIN, giving a minimum RTO of 200 ms. + * This agrees with RFC 4341, 5: + * "Because DCCP does not retransmit data, DCCP does not require + * TCP's recommended minimum timeout of one second". + */ + hc->tx_rto = (hc->tx_srtt >> 3) + hc->tx_rttvar; + + if (hc->tx_rto > DCCP_RTO_MAX) + hc->tx_rto = DCCP_RTO_MAX; +} + +static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp, + unsigned int *maxincr) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); @@ -355,64 +423,15 @@ static inline void ccid2_new_ack(struct sock *sk, hc->tx_cwnd += 1; hc->tx_packets_acked = 0; } - - /* update RTO */ - if (hc->tx_srtt == -1 || - time_after(jiffies, hc->tx_lastrtt + hc->tx_srtt)) { - unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent; - int s; - - /* first measurement */ - if (hc->tx_srtt == -1) { - ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", - r, jiffies, - (unsigned long long)seqp->ccid2s_seq); - ccid2_change_srtt(hc, r); - hc->tx_rttvar = r >> 1; - } else { - /* RTTVAR */ - long tmp = hc->tx_srtt - r; - long srtt; - - if (tmp < 0) - tmp *= -1; - - tmp >>= 2; - hc->tx_rttvar *= 3; - hc->tx_rttvar >>= 2; - hc->tx_rttvar += tmp; - - /* SRTT */ - srtt = hc->tx_srtt; - srtt *= 7; - srtt >>= 3; - tmp = r >> 3; - srtt += tmp; - ccid2_change_srtt(hc, srtt); - } - s = hc->tx_rttvar << 2; - /* clock granularity is 1 when based on jiffies */ - if (!s) - s = 1; - hc->tx_rto = hc->tx_srtt + s; - - /* must be at least a second */ - s = hc->tx_rto / HZ; - /* DCCP doesn't require this [but I like it cuz my code sux] */ -#if 1 - if (s < 1) - hc->tx_rto = HZ; -#endif - /* max 60 seconds */ - if (s > 60) - hc->tx_rto = HZ * 60; - - hc->tx_lastrtt = jiffies; - - ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n", - hc->tx_srtt, hc->tx_rttvar, - hc->tx_rto, HZ, r); - } + /* + * FIXME: RTT is sampled several times per acknowledgment (for each + * entry in the Ack Vector), instead of once per Ack (as in TCP SACK). + * This causes the RTT to be over-estimated, since the older entries + * in the Ack Vector have earlier sending times. + * The cleanest solution is to not use the ccid2s_sent field at all + * and instead use DCCP timestamps: requires changes in other places. + */ + ccid2_rtt_estimator(sk, jiffies - seqp->ccid2s_sent); } static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) @@ -662,9 +681,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) if (ccid2_hc_tx_alloc_seq(hc)) return -ENOMEM; - hc->tx_rto = 3 * HZ; - ccid2_change_srtt(hc, -1); - hc->tx_rttvar = -1; + hc->tx_rto = DCCP_TIMEOUT_INIT; hc->tx_rpdupack = -1; hc->tx_last_cong = jiffies; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 1ec6a30103bb..b017843ba44d 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -42,7 +42,12 @@ struct ccid2_seq { * struct ccid2_hc_tx_sock - CCID2 TX half connection * @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5 * @tx_packets_acked: Ack counter for deriving cwnd growth (RFC 3465) - * @tx_lastrtt: time RTT was last measured + * @tx_srtt: smoothed RTT estimate, scaled by 2^3 + * @tx_mdev: smoothed RTT variation, scaled by 2^2 + * @tx_mdev_max: maximum of @mdev during one flight + * @tx_rttvar: moving average/maximum of @mdev_max + * @tx_rto: RTO value deriving from SRTT and RTTVAR (RFC 2988) + * @tx_rtt_seq: to decay RTTVAR at most once per flight * @tx_rpseq: last consecutive seqno * @tx_rpdupack: dupacks since rpseq */ @@ -55,11 +60,16 @@ struct ccid2_hc_tx_sock { int tx_seqbufc; struct ccid2_seq *tx_seqh; struct ccid2_seq *tx_seqt; - long tx_rto; - long tx_srtt; - long tx_rttvar; - unsigned long tx_lastrtt; + + /* RTT measurement: variables/principles are the same as in TCP */ + u32 tx_srtt, + tx_mdev, + tx_mdev_max, + tx_rttvar, + tx_rto; + u64 tx_rtt_seq:48; struct timer_list tx_rtotimer; + u64 tx_rpseq; int tx_rpdupack; unsigned long tx_last_cong; -- cgit v1.2.3 From 8b230ed8ec96c933047dd0625cf95f739e4939a6 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Mon, 23 Aug 2010 20:24:12 -0700 Subject: bna: Brocade 10Gb Ethernet device driver This is patch 1/6 which contains linux driver source for Brocade's BR1010/BR1020 10Gb CEE capable ethernet adapter. Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- MAINTAINERS | 7 + drivers/net/Kconfig | 14 + drivers/net/Makefile | 1 + drivers/net/bna/Makefile | 11 + drivers/net/bna/bfa_cee.c | 407 ++++ drivers/net/bna/bfa_cee.h | 72 + drivers/net/bna/bfa_defs.h | 243 ++ drivers/net/bna/bfa_defs_cna.h | 223 ++ drivers/net/bna/bfa_defs_mfg_comm.h | 244 ++ drivers/net/bna/bfa_defs_status.h | 216 ++ drivers/net/bna/bfa_ioc.c | 1839 +++++++++++++++ drivers/net/bna/bfa_ioc.h | 343 +++ drivers/net/bna/bfa_ioc_ct.c | 391 ++++ drivers/net/bna/bfa_sm.h | 88 + drivers/net/bna/bfa_wc.h | 69 + drivers/net/bna/bfi.h | 392 ++++ drivers/net/bna/bfi_cna.h | 199 ++ drivers/net/bna/bfi_ctreg.h | 637 ++++++ drivers/net/bna/bfi_ll.h | 438 ++++ drivers/net/bna/bna.h | 654 ++++++ drivers/net/bna/bna_ctrl.c | 3626 ++++++++++++++++++++++++++++++ drivers/net/bna/bna_hw.h | 1491 +++++++++++++ drivers/net/bna/bna_txrx.c | 4209 +++++++++++++++++++++++++++++++++++ drivers/net/bna/bna_types.h | 1128 ++++++++++ drivers/net/bna/bnad.c | 3270 +++++++++++++++++++++++++++ drivers/net/bna/bnad.h | 334 +++ drivers/net/bna/bnad_ethtool.c | 1282 +++++++++++ drivers/net/bna/cna.h | 81 + drivers/net/bna/cna_fwimg.c | 64 + include/linux/pci_ids.h | 3 + 30 files changed, 21976 insertions(+) create mode 100644 drivers/net/bna/Makefile create mode 100644 drivers/net/bna/bfa_cee.c create mode 100644 drivers/net/bna/bfa_cee.h create mode 100644 drivers/net/bna/bfa_defs.h create mode 100644 drivers/net/bna/bfa_defs_cna.h create mode 100644 drivers/net/bna/bfa_defs_mfg_comm.h create mode 100644 drivers/net/bna/bfa_defs_status.h create mode 100644 drivers/net/bna/bfa_ioc.c create mode 100644 drivers/net/bna/bfa_ioc.h create mode 100644 drivers/net/bna/bfa_ioc_ct.c create mode 100644 drivers/net/bna/bfa_sm.h create mode 100644 drivers/net/bna/bfa_wc.h create mode 100644 drivers/net/bna/bfi.h create mode 100644 drivers/net/bna/bfi_cna.h create mode 100644 drivers/net/bna/bfi_ctreg.h create mode 100644 drivers/net/bna/bfi_ll.h create mode 100644 drivers/net/bna/bna.h create mode 100644 drivers/net/bna/bna_ctrl.c create mode 100644 drivers/net/bna/bna_hw.h create mode 100644 drivers/net/bna/bna_txrx.c create mode 100644 drivers/net/bna/bna_types.h create mode 100644 drivers/net/bna/bnad.c create mode 100644 drivers/net/bna/bnad.h create mode 100644 drivers/net/bna/bnad_ethtool.c create mode 100644 drivers/net/bna/cna.h create mode 100644 drivers/net/bna/cna_fwimg.c diff --git a/MAINTAINERS b/MAINTAINERS index 43c9efcd8e10..93198c1980a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1387,6 +1387,13 @@ L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/bfa/ +BROCADE BNA 10 GIGABIT ETHERNET DRIVER +M: Rasesh Mody +M: Debashis Dutt +L: netdev@vger.kernel.org +S: Supported +F: drivers/net/bna/ + BSG (block layer generic sg v4 driver) M: FUJITA Tomonori L: linux-scsi@vger.kernel.org diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 85485287192a..53c4810b119e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2869,6 +2869,20 @@ config QLGE To compile this driver as a module, choose M here: the module will be called qlge. +config BNA + tristate "Brocade 1010/1020 10Gb Ethernet Driver support" + depends on PCI + ---help--- + This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet + cards. + To compile this driver as a module, choose M here: the module + will be called bna. + + For general information and support, go to the Brocade support + website at: + + + source "drivers/net/sfc/Kconfig" source "drivers/net/benet/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f34b3baf7ee6..18a277709a2a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_ENIC) += enic/ obj-$(CONFIG_JME) += jme.o obj-$(CONFIG_BE2NET) += benet/ obj-$(CONFIG_VMXNET3) += vmxnet3/ +obj-$(CONFIG_BNA) += bna/ gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o \ diff --git a/drivers/net/bna/Makefile b/drivers/net/bna/Makefile new file mode 100644 index 000000000000..a5d604de7fea --- /dev/null +++ b/drivers/net/bna/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (c) 2005-2010 Brocade Communications Systems, Inc. +# All rights reserved. +# + +obj-$(CONFIG_BNA) += bna.o + +bna-objs := bnad.o bnad_ethtool.o bna_ctrl.o bna_txrx.o +bna-objs += bfa_ioc.o bfa_ioc_ct.o bfa_cee.o cna_fwimg.o + +EXTRA_CFLAGS := -Idrivers/net/bna diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c new file mode 100644 index 000000000000..1545fc9720f8 --- /dev/null +++ b/drivers/net/bna/bfa_cee.c @@ -0,0 +1,407 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_defs_cna.h" +#include "cna.h" +#include "bfa_cee.h" +#include "bfi_cna.h" +#include "bfa_ioc.h" + +#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) +#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc) + +static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg); +static void bfa_cee_format_cee_cfg(void *buffer); + +static void +bfa_cee_format_cee_cfg(void *buffer) +{ + struct bfa_cee_attr *cee_cfg = buffer; + bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote); +} + +static void +bfa_cee_stats_swap(struct bfa_cee_stats *stats) +{ + u32 *buffer = (u32 *)stats; + int i; + + for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32)); + i++) { + buffer[i] = ntohl(buffer[i]); + } +} + +static void +bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg) +{ + lldp_cfg->time_to_live = + ntohs(lldp_cfg->time_to_live); + lldp_cfg->enabled_system_cap = + ntohs(lldp_cfg->enabled_system_cap); +} + +/** + * bfa_cee_attr_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE attributes + * + * @param[in] void + * + * @return Size of DMA region + */ +static u32 +bfa_cee_attr_meminfo(void) +{ + return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ); +} +/** + * bfa_cee_stats_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE stats + * + * @param[in] void + * + * @return Size of DMA region + */ +static u32 +bfa_cee_stats_meminfo(void) +{ + return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for get-attributes responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->get_attr_status = status; + if (status == BFA_STATUS_OK) { + memcpy(cee->attr, cee->attr_dma.kva, + sizeof(struct bfa_cee_attr)); + bfa_cee_format_cee_cfg(cee->attr); + } + cee->get_attr_pending = false; + if (cee->cbfn.get_attr_cbfn) + cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for get-stats responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->get_stats_status = status; + if (status == BFA_STATUS_OK) { + memcpy(cee->stats, cee->stats_dma.kva, + sizeof(struct bfa_cee_stats)); + bfa_cee_stats_swap(cee->stats); + } + cee->get_stats_pending = false; + if (cee->cbfn.get_stats_cbfn) + cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for reset-stats responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->reset_stats_status = status; + cee->reset_stats_pending = false; + if (cee->cbfn.reset_stats_cbfn) + cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); +} +/** + * bfa_cee_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE module + * + * @param[in] void + * + * @return Size of DMA region + */ +u32 +bfa_cee_meminfo(void) +{ + return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo(); +} + +/** + * bfa_cee_mem_claim() + * + * @brief Initialized CEE DMA Memory + * + * @param[in] cee CEE module pointer + * dma_kva Kernel Virtual Address of CEE DMA Memory + * dma_pa Physical Address of CEE DMA Memory + * + * @return void + */ +void +bfa_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) +{ + cee->attr_dma.kva = dma_kva; + cee->attr_dma.pa = dma_pa; + cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo(); + cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo(); + cee->attr = (struct bfa_cee_attr *) dma_kva; + cee->stats = (struct bfa_cee_stats *) + (dma_kva + bfa_cee_attr_meminfo()); +} + +/** + * bfa_cee_get_attr() + * + * @brief + * Send the request to the f/w to fetch CEE attributes. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return Status + */ + +enum bfa_status +bfa_cee_get_attr(struct bfa_cee *cee, struct bfa_cee_attr *attr, + bfa_cee_get_attr_cbfn_t cbfn, void *cbarg) +{ + struct bfi_cee_get_req *cmd; + + BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); + if (!bfa_ioc_is_operational(cee->ioc)) + return BFA_STATUS_IOC_FAILURE; + if (cee->get_attr_pending == true) + return BFA_STATUS_DEVBUSY; + cee->get_attr_pending = true; + cmd = (struct bfi_cee_get_req *) cee->get_cfg_mb.msg; + cee->attr = attr; + cee->cbfn.get_attr_cbfn = cbfn; + cee->cbfn.get_attr_cbarg = cbarg; + bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ, + bfa_ioc_portid(cee->ioc)); + bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa); + bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb); + + return BFA_STATUS_OK; +} + +/** + * bfa_cee_get_stats() + * + * @brief + * Send the request to the f/w to fetch CEE statistics. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return Status + */ + +enum bfa_status +bfa_cee_get_stats(struct bfa_cee *cee, struct bfa_cee_stats *stats, + bfa_cee_get_stats_cbfn_t cbfn, void *cbarg) +{ + struct bfi_cee_get_req *cmd; + + BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); + + if (!bfa_ioc_is_operational(cee->ioc)) + return BFA_STATUS_IOC_FAILURE; + if (cee->get_stats_pending == true) + return BFA_STATUS_DEVBUSY; + cee->get_stats_pending = true; + cmd = (struct bfi_cee_get_req *) cee->get_stats_mb.msg; + cee->stats = stats; + cee->cbfn.get_stats_cbfn = cbfn; + cee->cbfn.get_stats_cbarg = cbarg; + bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ, + bfa_ioc_portid(cee->ioc)); + bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa); + bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb); + + return BFA_STATUS_OK; +} + +/** + * bfa_cee_reset_stats() + * + * @brief Clears CEE Stats in the f/w. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return Status + */ + +enum bfa_status +bfa_cee_reset_stats(struct bfa_cee *cee, bfa_cee_reset_stats_cbfn_t cbfn, + void *cbarg) +{ + struct bfi_cee_reset_stats *cmd; + + BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); + if (!bfa_ioc_is_operational(cee->ioc)) + return BFA_STATUS_IOC_FAILURE; + if (cee->reset_stats_pending == true) + return BFA_STATUS_DEVBUSY; + cee->reset_stats_pending = true; + cmd = (struct bfi_cee_reset_stats *) cee->reset_stats_mb.msg; + cee->cbfn.reset_stats_cbfn = cbfn; + cee->cbfn.reset_stats_cbarg = cbarg; + bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS, + bfa_ioc_portid(cee->ioc)); + bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb); + return BFA_STATUS_OK; +} + +/** + * bfa_cee_isrs() + * + * @brief Handles Mail-box interrupts for CEE module. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return void + */ + +void +bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) +{ + union bfi_cee_i2h_msg_u *msg; + struct bfi_cee_get_rsp *get_rsp; + struct bfa_cee *cee = (struct bfa_cee *) cbarg; + msg = (union bfi_cee_i2h_msg_u *) m; + get_rsp = (struct bfi_cee_get_rsp *) m; + switch (msg->mh.msg_id) { + case BFI_CEE_I2H_GET_CFG_RSP: + bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); + break; + case BFI_CEE_I2H_GET_STATS_RSP: + bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); + break; + case BFI_CEE_I2H_RESET_STATS_RSP: + bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); + break; + default: + BUG_ON(1); + } +} + +/** + * bfa_cee_hbfail() + * + * @brief CEE module heart-beat failure handler. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return void + */ + +void +bfa_cee_hbfail(void *arg) +{ + struct bfa_cee *cee; + cee = (struct bfa_cee *) arg; + + if (cee->get_attr_pending == true) { + cee->get_attr_status = BFA_STATUS_FAILED; + cee->get_attr_pending = false; + if (cee->cbfn.get_attr_cbfn) { + cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, + BFA_STATUS_FAILED); + } + } + if (cee->get_stats_pending == true) { + cee->get_stats_status = BFA_STATUS_FAILED; + cee->get_stats_pending = false; + if (cee->cbfn.get_stats_cbfn) { + cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, + BFA_STATUS_FAILED); + } + } + if (cee->reset_stats_pending == true) { + cee->reset_stats_status = BFA_STATUS_FAILED; + cee->reset_stats_pending = false; + if (cee->cbfn.reset_stats_cbfn) { + cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, + BFA_STATUS_FAILED); + } + } +} + +/** + * bfa_cee_attach() + * + * @brief CEE module-attach API + * + * @param[in] cee - Pointer to the CEE module data structure + * ioc - Pointer to the ioc module data structure + * dev - Pointer to the device driver module data structure + * The device driver specific mbox ISR functions have + * this pointer as one of the parameters. + * + * @return void + */ +void +bfa_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, + void *dev) +{ + BUG_ON(!(cee != NULL)); + cee->dev = dev; + cee->ioc = ioc; + + bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); + bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee); + bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail); +} + +/** + * bfa_cee_detach() + * + * @brief CEE module-detach API + * + * @param[in] cee - Pointer to the CEE module data structure + * + * @return void + */ +void +bfa_cee_detach(struct bfa_cee *cee) +{ +} diff --git a/drivers/net/bna/bfa_cee.h b/drivers/net/bna/bfa_cee.h new file mode 100644 index 000000000000..1208cadeceed --- /dev/null +++ b/drivers/net/bna/bfa_cee.h @@ -0,0 +1,72 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_CEE_H__ +#define __BFA_CEE_H__ + +#include "bfa_defs_cna.h" +#include "bfa_ioc.h" + +typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status); + +struct bfa_cee_cbfn { + bfa_cee_get_attr_cbfn_t get_attr_cbfn; + void *get_attr_cbarg; + bfa_cee_get_stats_cbfn_t get_stats_cbfn; + void *get_stats_cbarg; + bfa_cee_reset_stats_cbfn_t reset_stats_cbfn; + void *reset_stats_cbarg; +}; + +struct bfa_cee { + void *dev; + bool get_attr_pending; + bool get_stats_pending; + bool reset_stats_pending; + enum bfa_status get_attr_status; + enum bfa_status get_stats_status; + enum bfa_status reset_stats_status; + struct bfa_cee_cbfn cbfn; + struct bfa_ioc_hbfail_notify hbfail; + struct bfa_cee_attr *attr; + struct bfa_cee_stats *stats; + struct bfa_dma attr_dma; + struct bfa_dma stats_dma; + struct bfa_ioc *ioc; + struct bfa_mbox_cmd get_cfg_mb; + struct bfa_mbox_cmd get_stats_mb; + struct bfa_mbox_cmd reset_stats_mb; +}; + +u32 bfa_cee_meminfo(void); +void bfa_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, + u64 dma_pa); +void bfa_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev); +void bfa_cee_detach(struct bfa_cee *cee); +enum bfa_status bfa_cee_get_attr(struct bfa_cee *cee, + struct bfa_cee_attr *attr, bfa_cee_get_attr_cbfn_t cbfn, void *cbarg); +enum bfa_status bfa_cee_get_stats(struct bfa_cee *cee, + struct bfa_cee_stats *stats, bfa_cee_get_stats_cbfn_t cbfn, + void *cbarg); +enum bfa_status bfa_cee_reset_stats(struct bfa_cee *cee, + bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg); + +#endif /* __BFA_CEE_H__ */ diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h new file mode 100644 index 000000000000..29c1b8de2c2d --- /dev/null +++ b/drivers/net/bna/bfa_defs.h @@ -0,0 +1,243 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_DEFS_H__ +#define __BFA_DEFS_H__ + +#include "cna.h" +#include "bfa_defs_status.h" +#include "bfa_defs_mfg_comm.h" + +#define BFA_STRING_32 32 +#define BFA_VERSION_LEN 64 + +/** + * ---------------------- adapter definitions ------------ + */ + +/** + * BFA adapter level attributes. + */ +enum { + BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE), + /* + *!< adapter serial num length + */ + BFA_ADAPTER_MODEL_NAME_LEN = 16, /*!< model name length */ + BFA_ADAPTER_MODEL_DESCR_LEN = 128, /*!< model description length */ + BFA_ADAPTER_MFG_NAME_LEN = 8, /*!< manufacturer name length */ + BFA_ADAPTER_SYM_NAME_LEN = 64, /*!< adapter symbolic name length */ + BFA_ADAPTER_OS_TYPE_LEN = 64, /*!< adapter os type length */ +}; + +struct bfa_adapter_attr { + char manufacturer[BFA_ADAPTER_MFG_NAME_LEN]; + char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; + u32 card_type; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; + char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; + u64 pwwn; + char node_symname[FC_SYMNAME_MAX]; + char hw_ver[BFA_VERSION_LEN]; + char fw_ver[BFA_VERSION_LEN]; + char optrom_ver[BFA_VERSION_LEN]; + char os_type[BFA_ADAPTER_OS_TYPE_LEN]; + struct bfa_mfg_vpd vpd; + struct mac mac; + + u8 nports; + u8 max_speed; + u8 prototype; + char asic_rev; + + u8 pcie_gen; + u8 pcie_lanes_orig; + u8 pcie_lanes; + u8 cna_capable; + + u8 is_mezz; + u8 trunk_capable; +}; + +/** + * ---------------------- IOC definitions ------------ + */ + +enum { + BFA_IOC_DRIVER_LEN = 16, + BFA_IOC_CHIP_REV_LEN = 8, +}; + +/** + * Driver and firmware versions. + */ +struct bfa_ioc_driver_attr { + char driver[BFA_IOC_DRIVER_LEN]; /*!< driver name */ + char driver_ver[BFA_VERSION_LEN]; /*!< driver version */ + char fw_ver[BFA_VERSION_LEN]; /*!< firmware version */ + char bios_ver[BFA_VERSION_LEN]; /*!< bios version */ + char efi_ver[BFA_VERSION_LEN]; /*!< EFI version */ + char ob_ver[BFA_VERSION_LEN]; /*!< openboot version */ +}; + +/** + * IOC PCI device attributes + */ +struct bfa_ioc_pci_attr { + u16 vendor_id; /*!< PCI vendor ID */ + u16 device_id; /*!< PCI device ID */ + u16 ssid; /*!< subsystem ID */ + u16 ssvid; /*!< subsystem vendor ID */ + u32 pcifn; /*!< PCI device function */ + u32 rsvd; /* padding */ + char chip_rev[BFA_IOC_CHIP_REV_LEN]; /*!< chip revision */ +}; + +/** + * IOC states + */ +enum bfa_ioc_state { + BFA_IOC_RESET = 1, /*!< IOC is in reset state */ + BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ + BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */ + BFA_IOC_GETATTR = 4, /*!< IOC is being configured */ + BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */ + BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */ + BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */ + BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */ + BFA_IOC_DISABLED = 9, /*!< IOC is disabled */ + BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */ +}; + +/** + * IOC firmware stats + */ +struct bfa_fw_ioc_stats { + u32 enable_reqs; + u32 disable_reqs; + u32 get_attr_reqs; + u32 dbg_sync; + u32 dbg_dump; + u32 unknown_reqs; +}; + +/** + * IOC driver stats + */ +struct bfa_ioc_drv_stats { + u32 ioc_isrs; + u32 ioc_enables; + u32 ioc_disables; + u32 ioc_hbfails; + u32 ioc_boots; + u32 stats_tmos; + u32 hb_count; + u32 disable_reqs; + u32 enable_reqs; + u32 disable_replies; + u32 enable_replies; +}; + +/** + * IOC statistics + */ +struct bfa_ioc_stats { + struct bfa_ioc_drv_stats drv_stats; /*!< driver IOC stats */ + struct bfa_fw_ioc_stats fw_stats; /*!< firmware IOC stats */ +}; + +enum bfa_ioc_type { + BFA_IOC_TYPE_FC = 1, + BFA_IOC_TYPE_FCoE = 2, + BFA_IOC_TYPE_LL = 3, +}; + +/** + * IOC attributes returned in queries + */ +struct bfa_ioc_attr { + enum bfa_ioc_type ioc_type; + enum bfa_ioc_state state; /*!< IOC state */ + struct bfa_adapter_attr adapter_attr; /*!< HBA attributes */ + struct bfa_ioc_driver_attr driver_attr; /*!< driver attr */ + struct bfa_ioc_pci_attr pci_attr; + u8 port_id; /*!< port number */ + u8 rsvd[7]; /*!< 64bit align */ +}; + +/** + * ---------------------- mfg definitions ------------ + */ + +/** + * Checksum size + */ +#define BFA_MFG_CHKSUM_SIZE 16 + +#define BFA_MFG_PARTNUM_SIZE 14 +#define BFA_MFG_SUPPLIER_ID_SIZE 10 +#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 + +#pragma pack(1) + +/** + * @brief BFA adapter manufacturing block definition. + * + * All numerical fields are in big-endian format. + */ +struct bfa_mfg_block { + u8 version; /*!< manufacturing block version */ + u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */ + u16 mfgsize; /*!< mfg block size */ + u16 u16_chksum; /*!< old u16 checksum */ + char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; + char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; + u8 mfg_day; /*!< manufacturing day */ + u8 mfg_month; /*!< manufacturing month */ + u16 mfg_year; /*!< manufacturing year */ + u64 mfg_wwn; /*!< wwn base for this adapter */ + u8 num_wwn; /*!< number of wwns assigned */ + u8 mfg_speeds; /*!< speeds allowed for this adapter */ + u8 rsv[2]; + char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; + char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; + char + supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; + char + supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; + mac_t mfg_mac; /*!< mac address */ + u8 num_mac; /*!< number of mac addresses */ + u8 rsv2; + u32 mfg_type; /*!< card type */ + u8 rsv3[108]; + u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */ +}; + +#pragma pack() + +/** + * ---------------------- pci definitions ------------ + */ + +#define bfa_asic_id_ct(devid) \ + ((devid) == PCI_DEVICE_ID_BROCADE_CT || \ + (devid) == PCI_DEVICE_ID_BROCADE_CT_FC) + +#endif /* __BFA_DEFS_H__ */ diff --git a/drivers/net/bna/bfa_defs_cna.h b/drivers/net/bna/bfa_defs_cna.h new file mode 100644 index 000000000000..7e0a9187bdd5 --- /dev/null +++ b/drivers/net/bna/bfa_defs_cna.h @@ -0,0 +1,223 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_DEFS_CNA_H__ +#define __BFA_DEFS_CNA_H__ + +#include "bfa_defs.h" + +/** + * @brief + * FC physical port statistics. + */ +struct bfa_port_fc_stats { + u64 secs_reset; /*!< Seconds since stats is reset */ + u64 tx_frames; /*!< Tx frames */ + u64 tx_words; /*!< Tx words */ + u64 tx_lip; /*!< Tx LIP */ + u64 tx_nos; /*!< Tx NOS */ + u64 tx_ols; /*!< Tx OLS */ + u64 tx_lr; /*!< Tx LR */ + u64 tx_lrr; /*!< Tx LRR */ + u64 rx_frames; /*!< Rx frames */ + u64 rx_words; /*!< Rx words */ + u64 lip_count; /*!< Rx LIP */ + u64 nos_count; /*!< Rx NOS */ + u64 ols_count; /*!< Rx OLS */ + u64 lr_count; /*!< Rx LR */ + u64 lrr_count; /*!< Rx LRR */ + u64 invalid_crcs; /*!< Rx CRC err frames */ + u64 invalid_crc_gd_eof; /*!< Rx CRC err good EOF frames */ + u64 undersized_frm; /*!< Rx undersized frames */ + u64 oversized_frm; /*!< Rx oversized frames */ + u64 bad_eof_frm; /*!< Rx frames with bad EOF */ + u64 error_frames; /*!< Errored frames */ + u64 dropped_frames; /*!< Dropped frames */ + u64 link_failures; /*!< Link Failure (LF) count */ + u64 loss_of_syncs; /*!< Loss of sync count */ + u64 loss_of_signals; /*!< Loss of signal count */ + u64 primseq_errs; /*!< Primitive sequence protocol err. */ + u64 bad_os_count; /*!< Invalid ordered sets */ + u64 err_enc_out; /*!< Encoding err nonframe_8b10b */ + u64 err_enc; /*!< Encoding err frame_8b10b */ +}; + +/** + * @brief + * Eth Physical Port statistics. + */ +struct bfa_port_eth_stats { + u64 secs_reset; /*!< Seconds since stats is reset */ + u64 frame_64; /*!< Frames 64 bytes */ + u64 frame_65_127; /*!< Frames 65-127 bytes */ + u64 frame_128_255; /*!< Frames 128-255 bytes */ + u64 frame_256_511; /*!< Frames 256-511 bytes */ + u64 frame_512_1023; /*!< Frames 512-1023 bytes */ + u64 frame_1024_1518; /*!< Frames 1024-1518 bytes */ + u64 frame_1519_1522; /*!< Frames 1519-1522 bytes */ + u64 tx_bytes; /*!< Tx bytes */ + u64 tx_packets; /*!< Tx packets */ + u64 tx_mcast_packets; /*!< Tx multicast packets */ + u64 tx_bcast_packets; /*!< Tx broadcast packets */ + u64 tx_control_frame; /*!< Tx control frame */ + u64 tx_drop; /*!< Tx drops */ + u64 tx_jabber; /*!< Tx jabber */ + u64 tx_fcs_error; /*!< Tx FCS errors */ + u64 tx_fragments; /*!< Tx fragments */ + u64 rx_bytes; /*!< Rx bytes */ + u64 rx_packets; /*!< Rx packets */ + u64 rx_mcast_packets; /*!< Rx multicast packets */ + u64 rx_bcast_packets; /*!< Rx broadcast packets */ + u64 rx_control_frames; /*!< Rx control frames */ + u64 rx_unknown_opcode; /*!< Rx unknown opcode */ + u64 rx_drop; /*!< Rx drops */ + u64 rx_jabber; /*!< Rx jabber */ + u64 rx_fcs_error; /*!< Rx FCS errors */ + u64 rx_alignment_error; /*!< Rx alignment errors */ + u64 rx_frame_length_error; /*!< Rx frame len errors */ + u64 rx_code_error; /*!< Rx code errors */ + u64 rx_fragments; /*!< Rx fragments */ + u64 rx_pause; /*!< Rx pause */ + u64 rx_zero_pause; /*!< Rx zero pause */ + u64 tx_pause; /*!< Tx pause */ + u64 tx_zero_pause; /*!< Tx zero pause */ + u64 rx_fcoe_pause; /*!< Rx FCoE pause */ + u64 rx_fcoe_zero_pause; /*!< Rx FCoE zero pause */ + u64 tx_fcoe_pause; /*!< Tx FCoE pause */ + u64 tx_fcoe_zero_pause; /*!< Tx FCoE zero pause */ +}; + +/** + * @brief + * Port statistics. + */ +union bfa_port_stats_u { + struct bfa_port_fc_stats fc; + struct bfa_port_eth_stats eth; +}; + +#pragma pack(1) + +#define BFA_CEE_LLDP_MAX_STRING_LEN (128) +#define BFA_CEE_DCBX_MAX_PRIORITY (8) +#define BFA_CEE_DCBX_MAX_PGID (8) + +#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 +#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 +#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 +#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008 +#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010 +#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020 +#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040 +#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080 +#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100 +#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200 +#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400 + +/* LLDP string type */ +struct bfa_cee_lldp_str { + u8 sub_type; + u8 len; + u8 rsvd[2]; + u8 value[BFA_CEE_LLDP_MAX_STRING_LEN]; +}; + +/* LLDP paramters */ +struct bfa_cee_lldp_cfg { + struct bfa_cee_lldp_str chassis_id; + struct bfa_cee_lldp_str port_id; + struct bfa_cee_lldp_str port_desc; + struct bfa_cee_lldp_str sys_name; + struct bfa_cee_lldp_str sys_desc; + struct bfa_cee_lldp_str mgmt_addr; + u16 time_to_live; + u16 enabled_system_cap; +}; + +enum bfa_cee_dcbx_version { + DCBX_PROTOCOL_PRECEE = 1, + DCBX_PROTOCOL_CEE = 2, +}; + +enum bfa_cee_lls { + /* LLS is down because the TLV not sent by the peer */ + CEE_LLS_DOWN_NO_TLV = 0, + /* LLS is down as advertised by the peer */ + CEE_LLS_DOWN = 1, + CEE_LLS_UP = 2, +}; + +/* CEE/DCBX parameters */ +struct bfa_cee_dcbx_cfg { + u8 pgid[BFA_CEE_DCBX_MAX_PRIORITY]; + u8 pg_percentage[BFA_CEE_DCBX_MAX_PGID]; + u8 pfc_primap; /* bitmap of priorties with PFC enabled */ + u8 fcoe_primap; /* bitmap of priorities used for FcoE traffic */ + u8 iscsi_primap; /* bitmap of priorities used for iSCSI traffic */ + u8 dcbx_version; /* operating version:CEE or preCEE */ + u8 lls_fcoe; /* FCoE Logical Link Status */ + u8 lls_lan; /* LAN Logical Link Status */ + u8 rsvd[2]; +}; + +/* CEE status */ +/* Making this to tri-state for the benefit of port list command */ +enum bfa_cee_status { + CEE_UP = 0, + CEE_PHY_UP = 1, + CEE_LOOPBACK = 2, + CEE_PHY_DOWN = 3, +}; + +/* CEE Query */ +struct bfa_cee_attr { + u8 cee_status; + u8 error_reason; + struct bfa_cee_lldp_cfg lldp_remote; + struct bfa_cee_dcbx_cfg dcbx_remote; + mac_t src_mac; + u8 link_speed; + u8 nw_priority; + u8 filler[2]; +}; + +/* LLDP/DCBX/CEE Statistics */ +struct bfa_cee_stats { + u32 lldp_tx_frames; /*!< LLDP Tx Frames */ + u32 lldp_rx_frames; /*!< LLDP Rx Frames */ + u32 lldp_rx_frames_invalid; /*!< LLDP Rx Frames invalid */ + u32 lldp_rx_frames_new; /*!< LLDP Rx Frames new */ + u32 lldp_tlvs_unrecognized; /*!< LLDP Rx unrecognized TLVs */ + u32 lldp_rx_shutdown_tlvs; /*!< LLDP Rx shutdown TLVs */ + u32 lldp_info_aged_out; /*!< LLDP remote info aged out */ + u32 dcbx_phylink_ups; /*!< DCBX phy link ups */ + u32 dcbx_phylink_downs; /*!< DCBX phy link downs */ + u32 dcbx_rx_tlvs; /*!< DCBX Rx TLVs */ + u32 dcbx_rx_tlvs_invalid; /*!< DCBX Rx TLVs invalid */ + u32 dcbx_control_tlv_error; /*!< DCBX control TLV errors */ + u32 dcbx_feature_tlv_error; /*!< DCBX feature TLV errors */ + u32 dcbx_cee_cfg_new; /*!< DCBX new CEE cfg rcvd */ + u32 cee_status_down; /*!< CEE status down */ + u32 cee_status_up; /*!< CEE status up */ + u32 cee_hw_cfg_changed; /*!< CEE hw cfg changed */ + u32 cee_rx_invalid_cfg; /*!< CEE invalid cfg */ +}; + +#pragma pack() + +#endif /* __BFA_DEFS_CNA_H__ */ diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h new file mode 100644 index 000000000000..987978fcb3fe --- /dev/null +++ b/drivers/net/bna/bfa_defs_mfg_comm.h @@ -0,0 +1,244 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFA_DEFS_MFG_COMM_H__ +#define __BFA_DEFS_MFG_COMM_H__ + +#include "cna.h" + +/** + * Manufacturing block version + */ +#define BFA_MFG_VERSION 2 +#define BFA_MFG_VERSION_UNINIT 0xFF + +/** + * Manufacturing block encrypted version + */ +#define BFA_MFG_ENC_VER 2 + +/** + * Manufacturing block version 1 length + */ +#define BFA_MFG_VER1_LEN 128 + +/** + * Manufacturing block header length + */ +#define BFA_MFG_HDR_LEN 4 + +#define BFA_MFG_SERIALNUM_SIZE 11 +#define STRSZ(_n) (((_n) + 4) & ~3) + +/** + * Manufacturing card type + */ +enum { + BFA_MFG_TYPE_CB_MAX = 825, /*!< Crossbow card type max */ + BFA_MFG_TYPE_FC8P2 = 825, /*!< 8G 2port FC card */ + BFA_MFG_TYPE_FC8P1 = 815, /*!< 8G 1port FC card */ + BFA_MFG_TYPE_FC4P2 = 425, /*!< 4G 2port FC card */ + BFA_MFG_TYPE_FC4P1 = 415, /*!< 4G 1port FC card */ + BFA_MFG_TYPE_CNA10P2 = 1020, /*!< 10G 2port CNA card */ + BFA_MFG_TYPE_CNA10P1 = 1010, /*!< 10G 1port CNA card */ + BFA_MFG_TYPE_JAYHAWK = 804, /*!< Jayhawk mezz card */ + BFA_MFG_TYPE_WANCHESE = 1007, /*!< Wanchese mezz card */ + BFA_MFG_TYPE_ASTRA = 807, /*!< Astra mezz card */ + BFA_MFG_TYPE_LIGHTNING_P0 = 902, /*!< Lightning mezz card - old */ + BFA_MFG_TYPE_LIGHTNING = 1741, /*!< Lightning mezz card */ + BFA_MFG_TYPE_INVALID = 0, /*!< Invalid card type */ +}; + +#pragma pack(1) + +/** + * Check if 1-port card + */ +#define bfa_mfg_is_1port(type) (( \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P1)) + +/** + * Check if Mezz card + */ +#define bfa_mfg_is_mezz(type) (( \ + (type) == BFA_MFG_TYPE_JAYHAWK || \ + (type) == BFA_MFG_TYPE_WANCHESE || \ + (type) == BFA_MFG_TYPE_ASTRA || \ + (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \ + (type) == BFA_MFG_TYPE_LIGHTNING)) + +/** + * Check if card type valid + */ +#define bfa_mfg_is_card_type_valid(type) (( \ + (type) == BFA_MFG_TYPE_FC8P2 || \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P2 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P2 || \ + (type) == BFA_MFG_TYPE_CNA10P1 || \ + bfa_mfg_is_mezz(type))) + +/** + * Check if the card having old wwn/mac handling + */ +#define bfa_mfg_is_old_wwn_mac_model(type) (( \ + (type) == BFA_MFG_TYPE_FC8P2 || \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P2 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P2 || \ + (type) == BFA_MFG_TYPE_CNA10P1 || \ + (type) == BFA_MFG_TYPE_JAYHAWK || \ + (type) == BFA_MFG_TYPE_WANCHESE)) + +#define bfa_mfg_increment_wwn_mac(m, i) \ +do { \ + u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \ + t += (i); \ + (m)[0] = (t >> 16) & 0xFF; \ + (m)[1] = (t >> 8) & 0xFF; \ + (m)[2] = t & 0xFF; \ +} while (0) + +#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \ +do { \ + switch ((card_type)) { \ + case BFA_MFG_TYPE_FC8P2: \ + case BFA_MFG_TYPE_JAYHAWK: \ + case BFA_MFG_TYPE_ASTRA: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \ + BFI_ADAPTER_SETP(SPEED, 8); \ + break; \ + case BFA_MFG_TYPE_FC8P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \ + BFI_ADAPTER_SETP(SPEED, 8); \ + break; \ + case BFA_MFG_TYPE_FC4P2: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \ + BFI_ADAPTER_SETP(SPEED, 4); \ + break; \ + case BFA_MFG_TYPE_FC4P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \ + BFI_ADAPTER_SETP(SPEED, 4); \ + break; \ + case BFA_MFG_TYPE_CNA10P2: \ + case BFA_MFG_TYPE_WANCHESE: \ + case BFA_MFG_TYPE_LIGHTNING_P0: \ + case BFA_MFG_TYPE_LIGHTNING: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \ + break; \ + case BFA_MFG_TYPE_CNA10P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \ + break; \ + default: \ + (prop) = BFI_ADAPTER_UNSUPP; \ + } \ +} while (0) + +enum { + CB_GPIO_TTV = (1), /*!< TTV debug capable cards */ + CB_GPIO_FC8P2 = (2), /*!< 8G 2port FC card */ + CB_GPIO_FC8P1 = (3), /*!< 8G 1port FC card */ + CB_GPIO_FC4P2 = (4), /*!< 4G 2port FC card */ + CB_GPIO_FC4P1 = (5), /*!< 4G 1port FC card */ + CB_GPIO_DFLY = (6), /*!< 8G 2port FC mezzanine card */ + CB_GPIO_PROTO = (1 << 7) /*!< 8G 2port FC prototypes */ +}; + +#define bfa_mfg_adapter_prop_init_gpio(gpio, card_type, prop) \ +do { \ + if ((gpio) & CB_GPIO_PROTO) { \ + (prop) |= BFI_ADAPTER_PROTO; \ + (gpio) &= ~CB_GPIO_PROTO; \ + } \ + switch ((gpio)) { \ + case CB_GPIO_TTV: \ + (prop) |= BFI_ADAPTER_TTV; \ + case CB_GPIO_DFLY: \ + case CB_GPIO_FC8P2: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \ + (card_type) = BFA_MFG_TYPE_FC8P2; \ + break; \ + case CB_GPIO_FC8P1: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \ + (card_type) = BFA_MFG_TYPE_FC8P1; \ + break; \ + case CB_GPIO_FC4P2: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \ + (card_type) = BFA_MFG_TYPE_FC4P2; \ + break; \ + case CB_GPIO_FC4P1: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \ + (card_type) = BFA_MFG_TYPE_FC4P1; \ + break; \ + default: \ + (prop) |= BFI_ADAPTER_UNSUPP; \ + (card_type) = BFA_MFG_TYPE_INVALID; \ + } \ +} while (0) + +/** + * VPD data length + */ +#define BFA_MFG_VPD_LEN 512 +#define BFA_MFG_VPD_LEN_INVALID 0 + +#define BFA_MFG_VPD_PCI_HDR_OFF 137 +#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /*!< version mask 3 bits */ +#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /*!< vendor mask 5 bits */ + +/** + * VPD vendor tag + */ +enum { + BFA_MFG_VPD_UNKNOWN = 0, /*!< vendor unknown */ + BFA_MFG_VPD_IBM = 1, /*!< vendor IBM */ + BFA_MFG_VPD_HP = 2, /*!< vendor HP */ + BFA_MFG_VPD_DELL = 3, /*!< vendor DELL */ + BFA_MFG_VPD_PCI_IBM = 0x08, /*!< PCI VPD IBM */ + BFA_MFG_VPD_PCI_HP = 0x10, /*!< PCI VPD HP */ + BFA_MFG_VPD_PCI_DELL = 0x20, /*!< PCI VPD DELL */ + BFA_MFG_VPD_PCI_BRCD = 0xf8, /*!< PCI VPD Brocade */ +}; + +/** + * @brief BFA adapter flash vpd data definition. + * + * All numerical fields are in big-endian format. + */ +struct bfa_mfg_vpd { + u8 version; /*!< vpd data version */ + u8 vpd_sig[3]; /*!< characters 'V', 'P', 'D' */ + u8 chksum; /*!< u8 checksum */ + u8 vendor; /*!< vendor */ + u8 len; /*!< vpd data length excluding header */ + u8 rsv; + u8 data[BFA_MFG_VPD_LEN]; /*!< vpd data */ +}; + +#pragma pack() + +#endif /* __BFA_DEFS_MFG_H__ */ diff --git a/drivers/net/bna/bfa_defs_status.h b/drivers/net/bna/bfa_defs_status.h new file mode 100644 index 000000000000..af951126375c --- /dev/null +++ b/drivers/net/bna/bfa_defs_status.h @@ -0,0 +1,216 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFA_DEFS_STATUS_H__ +#define __BFA_DEFS_STATUS_H__ + +/** + * API status return values + * + * NOTE: The error msgs are auto generated from the comments. Only singe line + * comments are supported + */ +enum bfa_status { + BFA_STATUS_OK = 0, + BFA_STATUS_FAILED = 1, + BFA_STATUS_EINVAL = 2, + BFA_STATUS_ENOMEM = 3, + BFA_STATUS_ENOSYS = 4, + BFA_STATUS_ETIMER = 5, + BFA_STATUS_EPROTOCOL = 6, + BFA_STATUS_ENOFCPORTS = 7, + BFA_STATUS_NOFLASH = 8, + BFA_STATUS_BADFLASH = 9, + BFA_STATUS_SFP_UNSUPP = 10, + BFA_STATUS_UNKNOWN_VFID = 11, + BFA_STATUS_DATACORRUPTED = 12, + BFA_STATUS_DEVBUSY = 13, + BFA_STATUS_ABORTED = 14, + BFA_STATUS_NODEV = 15, + BFA_STATUS_HDMA_FAILED = 16, + BFA_STATUS_FLASH_BAD_LEN = 17, + BFA_STATUS_UNKNOWN_LWWN = 18, + BFA_STATUS_UNKNOWN_RWWN = 19, + BFA_STATUS_FCPT_LS_RJT = 20, + BFA_STATUS_VPORT_EXISTS = 21, + BFA_STATUS_VPORT_MAX = 22, + BFA_STATUS_UNSUPP_SPEED = 23, + BFA_STATUS_INVLD_DFSZ = 24, + BFA_STATUS_CNFG_FAILED = 25, + BFA_STATUS_CMD_NOTSUPP = 26, + BFA_STATUS_NO_ADAPTER = 27, + BFA_STATUS_LINKDOWN = 28, + BFA_STATUS_FABRIC_RJT = 29, + BFA_STATUS_UNKNOWN_VWWN = 30, + BFA_STATUS_NSLOGIN_FAILED = 31, + BFA_STATUS_NO_RPORTS = 32, + BFA_STATUS_NSQUERY_FAILED = 33, + BFA_STATUS_PORT_OFFLINE = 34, + BFA_STATUS_RPORT_OFFLINE = 35, + BFA_STATUS_TGTOPEN_FAILED = 36, + BFA_STATUS_BAD_LUNS = 37, + BFA_STATUS_IO_FAILURE = 38, + BFA_STATUS_NO_FABRIC = 39, + BFA_STATUS_EBADF = 40, + BFA_STATUS_EINTR = 41, + BFA_STATUS_EIO = 42, + BFA_STATUS_ENOTTY = 43, + BFA_STATUS_ENXIO = 44, + BFA_STATUS_EFOPEN = 45, + BFA_STATUS_VPORT_WWN_BP = 46, + BFA_STATUS_PORT_NOT_DISABLED = 47, + BFA_STATUS_BADFRMHDR = 48, + BFA_STATUS_BADFRMSZ = 49, + BFA_STATUS_MISSINGFRM = 50, + BFA_STATUS_LINKTIMEOUT = 51, + BFA_STATUS_NO_FCPIM_NEXUS = 52, + BFA_STATUS_CHECKSUM_FAIL = 53, + BFA_STATUS_GZME_FAILED = 54, + BFA_STATUS_SCSISTART_REQD = 55, + BFA_STATUS_IOC_FAILURE = 56, + BFA_STATUS_INVALID_WWN = 57, + BFA_STATUS_MISMATCH = 58, + BFA_STATUS_IOC_ENABLED = 59, + BFA_STATUS_ADAPTER_ENABLED = 60, + BFA_STATUS_IOC_NON_OP = 61, + BFA_STATUS_ADDR_MAP_FAILURE = 62, + BFA_STATUS_SAME_NAME = 63, + BFA_STATUS_PENDING = 64, + BFA_STATUS_8G_SPD = 65, + BFA_STATUS_4G_SPD = 66, + BFA_STATUS_AD_IS_ENABLE = 67, + BFA_STATUS_EINVAL_TOV = 68, + BFA_STATUS_EINVAL_QDEPTH = 69, + BFA_STATUS_VERSION_FAIL = 70, + BFA_STATUS_DIAG_BUSY = 71, + BFA_STATUS_BEACON_ON = 72, + BFA_STATUS_BEACON_OFF = 73, + BFA_STATUS_LBEACON_ON = 74, + BFA_STATUS_LBEACON_OFF = 75, + BFA_STATUS_PORT_NOT_INITED = 76, + BFA_STATUS_RPSC_ENABLED = 77, + BFA_STATUS_ENOFSAVE = 78, + BFA_STATUS_BAD_FILE = 79, + BFA_STATUS_RLIM_EN = 80, + BFA_STATUS_RLIM_DIS = 81, + BFA_STATUS_IOC_DISABLED = 82, + BFA_STATUS_ADAPTER_DISABLED = 83, + BFA_STATUS_BIOS_DISABLED = 84, + BFA_STATUS_AUTH_ENABLED = 85, + BFA_STATUS_AUTH_DISABLED = 86, + BFA_STATUS_ERROR_TRL_ENABLED = 87, + BFA_STATUS_ERROR_QOS_ENABLED = 88, + BFA_STATUS_NO_SFP_DEV = 89, + BFA_STATUS_MEMTEST_FAILED = 90, + BFA_STATUS_INVALID_DEVID = 91, + BFA_STATUS_QOS_ENABLED = 92, + BFA_STATUS_QOS_DISABLED = 93, + BFA_STATUS_INCORRECT_DRV_CONFIG = 94, + BFA_STATUS_REG_FAIL = 95, + BFA_STATUS_IM_INV_CODE = 96, + BFA_STATUS_IM_INV_VLAN = 97, + BFA_STATUS_IM_INV_ADAPT_NAME = 98, + BFA_STATUS_IM_LOW_RESOURCES = 99, + BFA_STATUS_IM_VLANID_IS_PVID = 100, + BFA_STATUS_IM_VLANID_EXISTS = 101, + BFA_STATUS_IM_FW_UPDATE_FAIL = 102, + BFA_STATUS_PORTLOG_ENABLED = 103, + BFA_STATUS_PORTLOG_DISABLED = 104, + BFA_STATUS_FILE_NOT_FOUND = 105, + BFA_STATUS_QOS_FC_ONLY = 106, + BFA_STATUS_RLIM_FC_ONLY = 107, + BFA_STATUS_CT_SPD = 108, + BFA_STATUS_LEDTEST_OP = 109, + BFA_STATUS_CEE_NOT_DN = 110, + BFA_STATUS_10G_SPD = 111, + BFA_STATUS_IM_INV_TEAM_NAME = 112, + BFA_STATUS_IM_DUP_TEAM_NAME = 113, + BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, + BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, + BFA_STATUS_IM_PVID_MISMATCH = 116, + BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, + BFA_STATUS_IM_MTU_MISMATCH = 118, + BFA_STATUS_IM_RSS_MISMATCH = 119, + BFA_STATUS_IM_HDS_MISMATCH = 120, + BFA_STATUS_IM_OFFLOAD_MISMATCH = 121, + BFA_STATUS_IM_PORT_PARAMS = 122, + BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123, + BFA_STATUS_IM_CANNOT_REM_PRI = 124, + BFA_STATUS_IM_MAX_PORTS_REACHED = 125, + BFA_STATUS_IM_LAST_PORT_DELETE = 126, + BFA_STATUS_IM_NO_DRIVER = 127, + BFA_STATUS_IM_MAX_VLANS_REACHED = 128, + BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129, + BFA_STATUS_NO_MINPORT_DRIVER = 130, + BFA_STATUS_CARD_TYPE_MISMATCH = 131, + BFA_STATUS_BAD_ASICBLK = 132, + BFA_STATUS_NO_DRIVER = 133, + BFA_STATUS_INVALID_MAC = 134, + BFA_STATUS_IM_NO_VLAN = 135, + BFA_STATUS_IM_ETH_LB_FAILED = 136, + BFA_STATUS_IM_PVID_REMOVE = 137, + BFA_STATUS_IM_PVID_EDIT = 138, + BFA_STATUS_CNA_NO_BOOT = 139, + BFA_STATUS_IM_PVID_NON_ZERO = 140, + BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141, + BFA_STATUS_IM_GET_INETCFG_FAILED = 142, + BFA_STATUS_IM_NOT_BOUND = 143, + BFA_STATUS_INSUFFICIENT_PERMS = 144, + BFA_STATUS_IM_INV_VLAN_NAME = 145, + BFA_STATUS_CMD_NOTSUPP_CNA = 146, + BFA_STATUS_IM_PASSTHRU_EDIT = 147, + BFA_STATUS_IM_BIND_FAILED = 148, + BFA_STATUS_IM_UNBIND_FAILED = 149, + BFA_STATUS_IM_PORT_IN_TEAM = 150, + BFA_STATUS_IM_VLAN_NOT_FOUND = 151, + BFA_STATUS_IM_TEAM_NOT_FOUND = 152, + BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, + BFA_STATUS_PBC = 154, + BFA_STATUS_DEVID_MISSING = 155, + BFA_STATUS_BAD_FWCFG = 156, + BFA_STATUS_CREATE_FILE = 157, + BFA_STATUS_INVALID_VENDOR = 158, + BFA_STATUS_SFP_NOT_READY = 159, + BFA_STATUS_FLASH_UNINIT = 160, + BFA_STATUS_FLASH_EMPTY = 161, + BFA_STATUS_FLASH_CKFAIL = 162, + BFA_STATUS_TRUNK_UNSUPP = 163, + BFA_STATUS_TRUNK_ENABLED = 164, + BFA_STATUS_TRUNK_DISABLED = 165, + BFA_STATUS_TRUNK_ERROR_TRL_ENABLED = 166, + BFA_STATUS_BOOT_CODE_UPDATED = 167, + BFA_STATUS_BOOT_VERSION = 168, + BFA_STATUS_CARDTYPE_MISSING = 169, + BFA_STATUS_INVALID_CARDTYPE = 170, + BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 171, + BFA_STATUS_IM_VLAN_OVER_TEAM_DELETE_FAILED = 172, + BFA_STATUS_ETHBOOT_ENABLED = 173, + BFA_STATUS_ETHBOOT_DISABLED = 174, + BFA_STATUS_IOPROFILE_OFF = 175, + BFA_STATUS_NO_PORT_INSTANCE = 176, + BFA_STATUS_BOOT_CODE_TIMEDOUT = 177, + BFA_STATUS_NO_VPORT_LOCK = 178, + BFA_STATUS_VPORT_NO_CNFG = 179, + BFA_STATUS_MAX_VAL +}; + +enum bfa_eproto_status { + BFA_EPROTO_BAD_ACCEPT = 0, + BFA_EPROTO_UNKNOWN_RSP = 1 +}; + +#endif /* __BFA_DEFS_STATUS_H__ */ diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c new file mode 100644 index 000000000000..cdc2cb1597ec --- /dev/null +++ b/drivers/net/bna/bfa_ioc.c @@ -0,0 +1,1839 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_ioc.h" +#include "cna.h" +#include "bfi.h" +#include "bfi_ctreg.h" +#include "bfa_defs.h" + +/** + * IOC local definitions + */ + +#define bfa_ioc_timer_start(__ioc) \ + mod_timer(&(__ioc)->ioc_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_TOV)) +#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer) + +#define bfa_ioc_recovery_timer_start(__ioc) \ + mod_timer(&(__ioc)->ioc_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_TOV_RECOVER)) + +#define bfa_sem_timer_start(__ioc) \ + mod_timer(&(__ioc)->sem_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)) +#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer) + +#define bfa_hb_timer_start(__ioc) \ + mod_timer(&(__ioc)->hb_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_HB_TOV)) +#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer) + +/** + * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. + */ + +#define bfa_ioc_firmware_lock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) +#define bfa_ioc_firmware_unlock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) +#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) +#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) +#define bfa_ioc_notify_hbfail(__ioc) \ + ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) + +#define bfa_ioc_is_optrom(__ioc) \ + (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ) + +#define bfa_ioc_mbox_cmd_pending(__ioc) \ + (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ + readl((__ioc)->ioc_regs.hfn_mbox_cmd)) + +bool bfa_auto_recover = true; + +/* + * forward declarations + */ +static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc); +static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc); +static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force); +static void bfa_ioc_send_enable(struct bfa_ioc *ioc); +static void bfa_ioc_send_disable(struct bfa_ioc *ioc); +static void bfa_ioc_send_getattr(struct bfa_ioc *ioc); +static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc); +static void bfa_ioc_hb_stop(struct bfa_ioc *ioc); +static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force); +static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc); +static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc); +static void bfa_ioc_recover(struct bfa_ioc *ioc); +static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc); +static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); +static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); + +/** + * IOC state machine events + */ +enum ioc_event { + IOC_E_ENABLE = 1, /*!< IOC enable request */ + IOC_E_DISABLE = 2, /*!< IOC disable request */ + IOC_E_TIMEOUT = 3, /*!< f/w response timeout */ + IOC_E_FWREADY = 4, /*!< f/w initialization done */ + IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */ + IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */ + IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */ + IOC_E_HBFAIL = 8, /*!< heartbeat failure */ + IOC_E_HWERROR = 9, /*!< hardware error interrupt */ + IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ + IOC_E_DETACH = 11, /*!< driver detach cleanup */ +}; + +bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); + +static struct bfa_sm_table ioc_sm_table[] = { + {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, + {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH}, + {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH}, + {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT}, + {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT}, + {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT}, + {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, + {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, + {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL}, + {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL}, + {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, + {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, +}; + +/** + * Reset entry actions -- initialize state machine + */ +static void +bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) +{ + ioc->retry_count = 0; + ioc->auto_recover = bfa_auto_recover; +} + +/** + * Beginning state. IOC is in reset state. + */ +static void +bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + break; + + case IOC_E_DETACH: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Semaphore should be acquired for version check. + */ +static void +bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_hw_sem_get(ioc); +} + +/** + * Awaiting h/w semaphore to continue with version check. + */ +static void +bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_SEMLOCKED: + if (bfa_ioc_firmware_lock(ioc)) { + ioc->retry_count = 0; + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + } else { + bfa_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch); + } + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + /* fall through */ + + case IOC_E_DETACH: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_FWREADY: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Notify enable completion callback and generate mismatch AEN. + */ +static void +bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc) +{ + /** + * Provide enable completion callback and AEN notification only once. + */ + if (ioc->retry_count == 0) + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + ioc->retry_count++; + bfa_ioc_timer_start(ioc); +} + +/** + * Awaiting firmware version match. + */ +static void +bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + /* fall through */ + + case IOC_E_DETACH: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_FWREADY: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Request for semaphore. + */ +static void +bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_hw_sem_get(ioc); +} + +/** + * Awaiting semaphore for h/w initialzation. + */ +static void +bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_SEMLOCKED: + ioc->retry_count = 0; + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + break; + + case IOC_E_DISABLE: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_reset(ioc, false); +} + +/** + * @brief + * Hardware is being initialized. Interrupts are enabled. + * Holding hardware semaphore lock. + */ +static void +bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWREADY: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + ioc->retry_count++; + if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { + bfa_ioc_timer_start(ioc); + bfa_ioc_reset(ioc, true); + break; + } + + bfa_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_ioc_hw_sem_release(ioc); + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_enable(ioc); +} + +/** + * Host IOC function is being enabled, awaiting response from firmware. + * Semaphore is acquired. + */ +static void +bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_ENABLE: + bfa_ioc_timer_stop(ioc); + bfa_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + ioc->retry_count++; + if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { + writel(BFI_IOC_UNINIT, + ioc->ioc_regs.ioc_fwstate); + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + break; + } + + bfa_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_FWREADY: + bfa_ioc_send_enable(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_getattr(ioc); +} + +/** + * @brief + * IOC configuration in progress. Timer is active. + */ +static void +bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_GETATTR: + bfa_ioc_timer_stop(ioc); + bfa_ioc_check_attr_wwns(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_op); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) +{ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); + bfa_ioc_hb_monitor(ioc); +} + +static void +bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + break; + + case IOC_E_DISABLE: + bfa_ioc_hb_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_HWERROR: + case IOC_E_FWREADY: + /** + * Hard error or IOC recovery by other function. + * Treat it same as heartbeat failure. + */ + bfa_ioc_hb_stop(ioc); + /* !!! fall through !!! */ + + case IOC_E_HBFAIL: + bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_disable(ioc); +} + +/** + * IOC is being disabled + */ +static void +bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* + * !!! fall through !!! + */ + + case IOC_E_TIMEOUT: + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * IOC disable completion entry. + */ +static void +bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_disable_comp(ioc); +} + +static void +bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + case IOC_E_DISABLE: + ioc->cbfn->disable_cbfn(ioc->bfa); + break; + + case IOC_E_FWREADY: + break; + + case IOC_E_DETACH: + bfa_ioc_firmware_unlock(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc) +{ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + bfa_ioc_timer_start(ioc); +} + +/** + * @brief + * Hardware initialization failed. + */ +static void +bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_DETACH: + bfa_ioc_timer_stop(ioc); + bfa_ioc_firmware_unlock(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc) +{ + struct list_head *qe; + struct bfa_ioc_hbfail_notify *notify; + + /** + * Mark IOC as failed in hardware and stop firmware. + */ + bfa_ioc_lpu_stop(ioc); + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + + /** + * Notify other functions on HB failure. + */ + bfa_ioc_notify_hbfail(ioc); + + /** + * Notify driver and common modules registered for notification. + */ + ioc->cbfn->hbfail_cbfn(ioc->bfa); + list_for_each(qe, &ioc->hb_notify_q) { + notify = (struct bfa_ioc_hbfail_notify *) qe; + notify->cbfn(notify->cbarg); + } + + /** + * Flush any queued up mailbox requests. + */ + bfa_ioc_mbox_hbfail(ioc); + + /** + * Trigger auto-recovery after a delay. + */ + if (ioc->auto_recover) + mod_timer(&ioc->ioc_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV_RECOVER)); +} + +/** + * @brief + * IOC heartbeat failure. + */ +static void +bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + + case IOC_E_ENABLE: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + break; + + case IOC_E_DISABLE: + if (ioc->auto_recover) + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + case IOC_E_FWREADY: + /** + * Recovery is already initiated by other function. + */ + break; + + case IOC_E_HWERROR: + /* + * HB failure notification, ignore. + */ + break; + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * BFA IOC private functions + */ + +static void +bfa_ioc_disable_comp(struct bfa_ioc *ioc) +{ + struct list_head *qe; + struct bfa_ioc_hbfail_notify *notify; + + ioc->cbfn->disable_cbfn(ioc->bfa); + + /** + * Notify common modules registered for notification. + */ + list_for_each(qe, &ioc->hb_notify_q) { + notify = (struct bfa_ioc_hbfail_notify *) qe; + notify->cbfn(notify->cbarg); + } +} + +void +bfa_ioc_sem_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_ioc_hw_sem_get(ioc); +} + +bool +bfa_ioc_sem_get(void __iomem *sem_reg) +{ + u32 r32; + int cnt = 0; +#define BFA_SEM_SPINCNT 3000 + + r32 = readl(sem_reg); + + while (r32 && (cnt < BFA_SEM_SPINCNT)) { + cnt++; + udelay(2); + r32 = readl(sem_reg); + } + + if (r32 == 0) + return true; + + BUG_ON(!(cnt < BFA_SEM_SPINCNT)); + return false; +} + +void +bfa_ioc_sem_release(void __iomem *sem_reg) +{ + writel(1, sem_reg); +} + +static void +bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) +{ + u32 r32; + + /** + * First read to the semaphore register will return 0, subsequent reads + * will return 1. Semaphore is released by writing 1 to the register + */ + r32 = readl(ioc->ioc_regs.ioc_sem_reg); + if (r32 == 0) { + bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED); + return; + } + + mod_timer(&ioc->sem_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); +} + +void +bfa_ioc_hw_sem_release(struct bfa_ioc *ioc) +{ + writel(1, ioc->ioc_regs.ioc_sem_reg); +} + +static void +bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc) +{ + del_timer(&ioc->sem_timer); +} + +/** + * @brief + * Initialize LPU local memory (aka secondary memory / SRAM) + */ +static void +bfa_ioc_lmem_init(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + int i; +#define PSS_LMEM_INIT_TIME 10000 + + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl &= ~__PSS_LMEM_RESET; + pss_ctl |= __PSS_LMEM_INIT_EN; + + /* + * i2c workaround 12.5khz clock + */ + pss_ctl |= __PSS_I2C_CLK_DIV(3UL); + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); + + /** + * wait for memory initialization to be complete + */ + i = 0; + do { + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + i++; + } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); + + /** + * If memory initialization is not successful, IOC timeout will catch + * such failures. + */ + BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); + + pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +static void +bfa_ioc_lpu_start(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + + /** + * Take processor out of reset. + */ + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl &= ~__PSS_LPU0_RESET; + + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +static void +bfa_ioc_lpu_stop(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + + /** + * Put processors in reset. + */ + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); + + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +/** + * Get driver and firmware versions. + */ +void +bfa_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +{ + u32 pgnum, pgoff; + u32 loff = 0; + int i; + u32 *fwsig = (u32 *) fwhdr; + + pgnum = bfa_ioc_smem_pgnum(ioc, loff); + pgoff = bfa_ioc_smem_pgoff(ioc, loff); + writel(pgnum, ioc->ioc_regs.host_page_num_fn); + + for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); + i++) { + fwsig[i] = + swab32(readl((loff) + (ioc->ioc_regs.smem_page_start))); + loff += sizeof(u32); + } +} + +/** + * Returns TRUE if same. + */ +bool +bfa_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +{ + struct bfi_ioc_image_hdr *drv_fwhdr; + int i; + + drv_fwhdr = (struct bfi_ioc_image_hdr *) + bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + + for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { + if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) + return false; + } + + return true; +} + +/** + * Return true if current running version is valid. Firmware signature and + * execution context (driver/bios) must match. + */ +static bool +bfa_ioc_fwver_valid(struct bfa_ioc *ioc) +{ + struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; + + /** + * If bios/efi boot (flash based) -- return true + */ + if (bfa_ioc_is_optrom(ioc)) + return true; + + bfa_ioc_fwver_get(ioc, &fwhdr); + drv_fwhdr = (struct bfi_ioc_image_hdr *) + bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + + if (fwhdr.signature != drv_fwhdr->signature) + return false; + + if (fwhdr.exec != drv_fwhdr->exec) + return false; + + return bfa_ioc_fwver_cmp(ioc, &fwhdr); +} + +/** + * Conditionally flush any pending message from firmware at start. + */ +static void +bfa_ioc_msgflush(struct bfa_ioc *ioc) +{ + u32 r32; + + r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); + if (r32) + writel(1, ioc->ioc_regs.lpu_mbox_cmd); +} + +/** + * @img ioc_init_logic.jpg + */ +static void +bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) +{ + enum bfi_ioc_state ioc_fwstate; + bool fwvalid; + + ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + + if (force) + ioc_fwstate = BFI_IOC_UNINIT; + + /** + * check if firmware is valid + */ + fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? + false : bfa_ioc_fwver_valid(ioc); + + if (!fwvalid) { + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); + return; + } + + /** + * If hardware initialization is in progress (initialized by other IOC), + * just wait for an initialization completion interrupt. + */ + if (ioc_fwstate == BFI_IOC_INITING) { + ioc->cbfn->reset_cbfn(ioc->bfa); + return; + } + + /** + * If IOC function is disabled and firmware version is same, + * just re-enable IOC. + * + * If option rom, IOC must not be in operational state. With + * convergence, IOC will be in operational state when 2nd driver + * is loaded. + */ + if (ioc_fwstate == BFI_IOC_DISABLED || + (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) { + /** + * When using MSI-X any pending firmware ready event should + * be flushed. Otherwise MSI-X interrupts are not delivered. + */ + bfa_ioc_msgflush(ioc); + ioc->cbfn->reset_cbfn(ioc->bfa); + bfa_fsm_send_event(ioc, IOC_E_FWREADY); + return; + } + + /** + * Initialize the h/w for any other states. + */ + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); +} + +void +bfa_ioc_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); +} + +void +bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len) +{ + u32 *msgp = (u32 *) ioc_msg; + u32 i; + + BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX)); + + /* + * first write msg to mailbox registers + */ + for (i = 0; i < len / sizeof(u32); i++) + writel(cpu_to_le32(msgp[i]), + ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); + + for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) + writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); + + /* + * write 1 to mailbox CMD to trigger LPU event + */ + writel(1, ioc->ioc_regs.hfn_mbox_cmd); + (void) readl(ioc->ioc_regs.hfn_mbox_cmd); +} + +static void +bfa_ioc_send_enable(struct bfa_ioc *ioc) +{ + struct bfi_ioc_ctrl_req enable_req; + struct timeval tv; + + bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, + bfa_ioc_portid(ioc)); + enable_req.ioc_class = ioc->ioc_mc; + do_gettimeofday(&tv); + enable_req.tv_sec = ntohl(tv.tv_sec); + bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req)); +} + +static void +bfa_ioc_send_disable(struct bfa_ioc *ioc) +{ + struct bfi_ioc_ctrl_req disable_req; + + bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, + bfa_ioc_portid(ioc)); + bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req)); +} + +static void +bfa_ioc_send_getattr(struct bfa_ioc *ioc) +{ + struct bfi_ioc_getattr_req attr_req; + + bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, + bfa_ioc_portid(ioc)); + bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); + bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); +} + +void +bfa_ioc_hb_check(void *cbarg) +{ + struct bfa_ioc *ioc = cbarg; + u32 hb_count; + + hb_count = readl(ioc->ioc_regs.heartbeat); + if (ioc->hb_count == hb_count) { + pr_crit("Firmware heartbeat failure at %d", hb_count); + bfa_ioc_recover(ioc); + return; + } else { + ioc->hb_count = hb_count; + } + + bfa_ioc_mbox_poll(ioc); + mod_timer(&ioc->hb_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HB_TOV)); +} + +static void +bfa_ioc_hb_monitor(struct bfa_ioc *ioc) +{ + ioc->hb_count = readl(ioc->ioc_regs.heartbeat); + mod_timer(&ioc->hb_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HB_TOV)); +} + +static void +bfa_ioc_hb_stop(struct bfa_ioc *ioc) +{ + del_timer(&ioc->hb_timer); +} + +/** + * @brief + * Initiate a full firmware download. + */ +static void +bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, + u32 boot_param) +{ + u32 *fwimg; + u32 pgnum, pgoff; + u32 loff = 0; + u32 chunkno = 0; + u32 i; + + /** + * Initialize LMEM first before code download + */ + bfa_ioc_lmem_init(ioc); + + /** + * Flash based firmware boot + */ + if (bfa_ioc_is_optrom(ioc)) + boot_type = BFI_BOOT_TYPE_FLASH; + fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); + + pgnum = bfa_ioc_smem_pgnum(ioc, loff); + pgoff = bfa_ioc_smem_pgoff(ioc, loff); + + writel(pgnum, ioc->ioc_regs.host_page_num_fn); + + for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) { + if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { + chunkno = BFA_IOC_FLASH_CHUNK_NO(i); + fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), + BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); + } + + /** + * write smem + */ + writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])), + ((ioc->ioc_regs.smem_page_start) + (loff))); + + loff += sizeof(u32); + + /** + * handle page offset wrap around + */ + loff = PSS_SMEM_PGOFF(loff); + if (loff == 0) { + pgnum++; + writel(pgnum, + ioc->ioc_regs.host_page_num_fn); + } + } + + writel(bfa_ioc_smem_pgnum(ioc, 0), + ioc->ioc_regs.host_page_num_fn); + + /* + * Set boot type and boot param at the end. + */ + writel((swab32(swab32(boot_type))), ((ioc->ioc_regs.smem_page_start) + + (BFI_BOOT_TYPE_OFF))); + writel((swab32(swab32(boot_param))), ((ioc->ioc_regs.smem_page_start) + + (BFI_BOOT_PARAM_OFF))); +} + +static void +bfa_ioc_reset(struct bfa_ioc *ioc, bool force) +{ + bfa_ioc_hwinit(ioc, force); +} + +/** + * @brief + * Update BFA configuration from firmware configuration. + */ +static void +bfa_ioc_getattr_reply(struct bfa_ioc *ioc) +{ + struct bfi_ioc_attr *attr = ioc->attr; + + attr->adapter_prop = ntohl(attr->adapter_prop); + attr->card_type = ntohl(attr->card_type); + attr->maxfrsize = ntohs(attr->maxfrsize); + + bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); +} + +/** + * Attach time initialization of mbox logic. + */ +static void +bfa_ioc_mbox_attach(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + int mc; + + INIT_LIST_HEAD(&mod->cmd_q); + for (mc = 0; mc < BFI_MC_MAX; mc++) { + mod->mbhdlr[mc].cbfn = NULL; + mod->mbhdlr[mc].cbarg = ioc->bfa; + } +} + +/** + * Mbox poll timer -- restarts any pending mailbox requests. + */ +static void +bfa_ioc_mbox_poll(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfa_mbox_cmd *cmd; + u32 stat; + + /** + * If no command pending, do nothing + */ + if (list_empty(&mod->cmd_q)) + return; + + /** + * If previous command is not yet fetched by firmware, do nothing + */ + stat = readl(ioc->ioc_regs.hfn_mbox_cmd); + if (stat) + return; + + /** + * Enqueue command to firmware. + */ + bfa_q_deq(&mod->cmd_q, &cmd); + bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); +} + +/** + * Cleanup any pending requests. + */ +static void +bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfa_mbox_cmd *cmd; + + while (!list_empty(&mod->cmd_q)) + bfa_q_deq(&mod->cmd_q, &cmd); +} + +/** + * IOC public + */ +enum bfa_status +bfa_ioc_pll_init(struct bfa_ioc *ioc) +{ + /* + * Hold semaphore so that nobody can access the chip during init. + */ + bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); + + bfa_ioc_pll_init_asic(ioc); + + ioc->pllinit = true; + /* + * release semaphore. + */ + bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + + return BFA_STATUS_OK; +} + +/** + * Interface used by diag module to do firmware boot with memory test + * as the entry vector. + */ +void +bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) +{ + void __iomem *rb; + + bfa_ioc_stats(ioc, ioc_boots); + + if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) + return; + + /** + * Initialize IOC state of all functions on a chip reset. + */ + rb = ioc->pcidev.pci_bar_kva; + if (boot_param == BFI_BOOT_TYPE_MEMTEST) { + writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); + } else { + writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG)); + } + + bfa_ioc_msgflush(ioc); + bfa_ioc_download_fw(ioc, boot_type, boot_param); + + /** + * Enable interrupts just before starting LPU + */ + ioc->cbfn->reset_cbfn(ioc->bfa); + bfa_ioc_lpu_start(ioc); +} + +/** + * Enable/disable IOC failure auto recovery. + */ +void +bfa_ioc_auto_recover(bool auto_recover) +{ + bfa_auto_recover = auto_recover; +} + +bool +bfa_ioc_is_operational(struct bfa_ioc *ioc) +{ + return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); +} + +bool +bfa_ioc_is_initialized(struct bfa_ioc *ioc) +{ + u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); + + return ((r32 != BFI_IOC_UNINIT) && + (r32 != BFI_IOC_INITING) && + (r32 != BFI_IOC_MEMTEST)); +} + +void +bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) +{ + u32 *msgp = mbmsg; + u32 r32; + int i; + + /** + * read the MBOX msg + */ + for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); + i++) { + r32 = readl(ioc->ioc_regs.lpu_mbox + + i * sizeof(u32)); + msgp[i] = htonl(r32); + } + + /** + * turn off mailbox interrupt by clearing mailbox status + */ + writel(1, ioc->ioc_regs.lpu_mbox_cmd); + readl(ioc->ioc_regs.lpu_mbox_cmd); +} + +void +bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) +{ + union bfi_ioc_i2h_msg_u *msg; + + msg = (union bfi_ioc_i2h_msg_u *) m; + + bfa_ioc_stats(ioc, ioc_isrs); + + switch (msg->mh.msg_id) { + case BFI_IOC_I2H_HBEAT: + break; + + case BFI_IOC_I2H_READY_EVENT: + bfa_fsm_send_event(ioc, IOC_E_FWREADY); + break; + + case BFI_IOC_I2H_ENABLE_REPLY: + bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE); + break; + + case BFI_IOC_I2H_DISABLE_REPLY: + bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE); + break; + + case BFI_IOC_I2H_GETATTR_REPLY: + bfa_ioc_getattr_reply(ioc); + break; + + default: + BUG_ON(1); + } +} + +/** + * IOC attach time initialization and setup. + * + * @param[in] ioc memory for IOC + * @param[in] bfa driver instance structure + */ +void +bfa_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) +{ + ioc->bfa = bfa; + ioc->cbfn = cbfn; + ioc->fcmode = false; + ioc->pllinit = false; + ioc->dbg_fwsave_once = true; + + bfa_ioc_mbox_attach(ioc); + INIT_LIST_HEAD(&ioc->hb_notify_q); + + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); +} + +/** + * Driver detach time IOC cleanup. + */ +void +bfa_ioc_detach(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_DETACH); +} + +/** + * Setup IOC PCI properties. + * + * @param[in] pcidev PCI device information for this IOC + */ +void +bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, + enum bfi_mclass mc) +{ + ioc->ioc_mc = mc; + ioc->pcidev = *pcidev; + ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); + ioc->cna = ioc->ctdev && !ioc->fcmode; + + bfa_ioc_set_ct_hwif(ioc); + + bfa_ioc_map_port(ioc); + bfa_ioc_reg_init(ioc); +} + +/** + * Initialize IOC dma memory + * + * @param[in] dm_kva kernel virtual address of IOC dma memory + * @param[in] dm_pa physical address of IOC dma memory + */ +void +bfa_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) +{ + /** + * dma memory for firmware attribute + */ + ioc->attr_dma.kva = dm_kva; + ioc->attr_dma.pa = dm_pa; + ioc->attr = (struct bfi_ioc_attr *) dm_kva; +} + +/** + * Return size of dma memory required. + */ +u32 +bfa_ioc_meminfo(void) +{ + return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ); +} + +void +bfa_ioc_enable(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_enables); + ioc->dbg_fwsave_once = true; + + bfa_fsm_send_event(ioc, IOC_E_ENABLE); +} + +void +bfa_ioc_disable(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_disables); + bfa_fsm_send_event(ioc, IOC_E_DISABLE); +} + +u32 +bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr) +{ + return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); +} + +u32 +bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr) +{ + return PSS_SMEM_PGOFF(fmaddr); +} + +/** + * Register mailbox message handler functions + * + * @param[in] ioc IOC instance + * @param[in] mcfuncs message class handler functions + */ +void +bfa_ioc_mbox_register(struct bfa_ioc *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + int mc; + + for (mc = 0; mc < BFI_MC_MAX; mc++) + mod->mbhdlr[mc].cbfn = mcfuncs[mc]; +} + +/** + * Register mailbox message handler function, to be called by common modules + */ +void +bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, + bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + + mod->mbhdlr[mc].cbfn = cbfn; + mod->mbhdlr[mc].cbarg = cbarg; +} + +/** + * Queue a mailbox command request to firmware. Waits if mailbox is busy. + * Responsibility of caller to serialize + * + * @param[in] ioc IOC instance + * @param[i] cmd Mailbox command + */ +void +bfa_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + u32 stat; + + /** + * If a previous command is pending, queue new command + */ + if (!list_empty(&mod->cmd_q)) { + list_add_tail(&cmd->qe, &mod->cmd_q); + return; + } + + /** + * If mailbox is busy, queue command for poll timer + */ + stat = readl(ioc->ioc_regs.hfn_mbox_cmd); + if (stat) { + list_add_tail(&cmd->qe, &mod->cmd_q); + return; + } + + /** + * mailbox is free -- queue command to firmware + */ + bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); +} + +/** + * Handle mailbox interrupts + */ +void +bfa_ioc_mbox_isr(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfi_mbmsg m; + int mc; + + bfa_ioc_msgget(ioc, &m); + + /** + * Treat IOC message class as special. + */ + mc = m.mh.msg_class; + if (mc == BFI_MC_IOC) { + bfa_ioc_isr(ioc, &m); + return; + } + + if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) + return; + + mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); +} + +void +bfa_ioc_error_isr(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_HWERROR); +} + +void +bfa_ioc_set_fcmode(struct bfa_ioc *ioc) +{ + ioc->fcmode = true; + ioc->port_id = bfa_ioc_pcifn(ioc); +} + +/** + * return true if IOC is disabled + */ +bool +bfa_ioc_is_disabled(struct bfa_ioc *ioc) +{ + return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || + bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); +} + +/** + * return true if IOC firmware is different. + */ +bool +bfa_ioc_fw_mismatch(struct bfa_ioc *ioc) +{ + return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) || + bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck) || + bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch); +} + +#define bfa_ioc_state_disabled(__sm) \ + (((__sm) == BFI_IOC_UNINIT) || \ + ((__sm) == BFI_IOC_INITING) || \ + ((__sm) == BFI_IOC_HWINIT) || \ + ((__sm) == BFI_IOC_DISABLED) || \ + ((__sm) == BFI_IOC_FAIL) || \ + ((__sm) == BFI_IOC_CFG_DISABLED)) + +/** + * Check if adapter is disabled -- both IOCs should be in a disabled + * state. + */ +bool +bfa_ioc_adapter_is_disabled(struct bfa_ioc *ioc) +{ + u32 ioc_state; + void __iomem *rb = ioc->pcidev.pci_bar_kva; + + if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) + return false; + + ioc_state = readl(rb + BFA_IOC0_STATE_REG); + if (!bfa_ioc_state_disabled(ioc_state)) + return false; + + if (ioc->pcidev.device_id != PCI_DEVICE_ID_BROCADE_FC_8G1P) { + ioc_state = readl(rb + BFA_IOC1_STATE_REG); + if (!bfa_ioc_state_disabled(ioc_state)) + return false; + } + + return true; +} + +/** + * Add to IOC heartbeat failure notification queue. To be used by common + * modules such as cee, port, diag. + */ +void +bfa_ioc_hbfail_register(struct bfa_ioc *ioc, + struct bfa_ioc_hbfail_notify *notify) +{ + list_add_tail(¬ify->qe, &ioc->hb_notify_q); +} + +#define BFA_MFG_NAME "Brocade" +void +bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, + struct bfa_adapter_attr *ad_attr) +{ + struct bfi_ioc_attr *ioc_attr; + + ioc_attr = ioc->attr; + + bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); + bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); + bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); + bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); + memcpy(&ad_attr->vpd, &ioc_attr->vpd, + sizeof(struct bfa_mfg_vpd)); + + ad_attr->nports = bfa_ioc_get_nports(ioc); + ad_attr->max_speed = bfa_ioc_speed_sup(ioc); + + bfa_ioc_get_adapter_model(ioc, ad_attr->model); + /* For now, model descr uses same model string */ + bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); + + ad_attr->card_type = ioc_attr->card_type; + ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); + + if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) + ad_attr->prototype = 1; + else + ad_attr->prototype = 0; + + ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); + ad_attr->mac = bfa_ioc_get_mac(ioc); + + ad_attr->pcie_gen = ioc_attr->pcie_gen; + ad_attr->pcie_lanes = ioc_attr->pcie_lanes; + ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; + ad_attr->asic_rev = ioc_attr->asic_rev; + + bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); + + ad_attr->cna_capable = ioc->cna; + ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna; +} + +enum bfa_ioc_type +bfa_ioc_get_type(struct bfa_ioc *ioc) +{ + if (!ioc->ctdev || ioc->fcmode) + return BFA_IOC_TYPE_FC; + else if (ioc->ioc_mc == BFI_MC_IOCFC) + return BFA_IOC_TYPE_FCoE; + else if (ioc->ioc_mc == BFI_MC_LL) + return BFA_IOC_TYPE_LL; + else { + BUG_ON(!(ioc->ioc_mc == BFI_MC_LL)); + return BFA_IOC_TYPE_LL; + } +} + +void +bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) +{ + memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); + memcpy(serial_num, + (void *)ioc->attr->brcd_serialnum, + BFA_ADAPTER_SERIAL_NUM_LEN); +} + +void +bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver) +{ + memset(fw_ver, 0, BFA_VERSION_LEN); + memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); +} + +void +bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) +{ + BUG_ON(!(chip_rev)); + + memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN); + + chip_rev[0] = 'R'; + chip_rev[1] = 'e'; + chip_rev[2] = 'v'; + chip_rev[3] = '-'; + chip_rev[4] = ioc->attr->asic_rev; + chip_rev[5] = '\0'; +} + +void +bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) +{ + memset(optrom_ver, 0, BFA_VERSION_LEN); + memcpy(optrom_ver, ioc->attr->optrom_version, + BFA_VERSION_LEN); +} + +void +bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) +{ + memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); + memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); +} + +void +bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) +{ + struct bfi_ioc_attr *ioc_attr; + + BUG_ON(!(model)); + memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN); + + ioc_attr = ioc->attr; + + /** + * model name + */ + snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", + BFA_MFG_NAME, ioc_attr->card_type); +} + +enum bfa_ioc_state +bfa_ioc_get_state(struct bfa_ioc *ioc) +{ + return bfa_sm_to_state(ioc_sm_table, ioc->fsm); +} + +void +bfa_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) +{ + memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr)); + + ioc_attr->state = bfa_ioc_get_state(ioc); + ioc_attr->port_id = ioc->port_id; + + ioc_attr->ioc_type = bfa_ioc_get_type(ioc); + + bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); + + ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; + ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; + bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); +} + +/** + * WWN public + */ +u64 +bfa_ioc_get_pwwn(struct bfa_ioc *ioc) +{ + return ioc->attr->pwwn; +} + +u64 +bfa_ioc_get_nwwn(struct bfa_ioc *ioc) +{ + return ioc->attr->nwwn; +} + +u64 +bfa_ioc_get_adid(struct bfa_ioc *ioc) +{ + return ioc->attr->mfg_pwwn; +} + +mac_t +bfa_ioc_get_mac(struct bfa_ioc *ioc) +{ + /* + * Currently mfg mac is used as FCoE enode mac (not configured by PBC) + */ + if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) + return bfa_ioc_get_mfg_mac(ioc); + else + return ioc->attr->mac; +} + +u64 +bfa_ioc_get_mfg_pwwn(struct bfa_ioc *ioc) +{ + return ioc->attr->mfg_pwwn; +} + +u64 +bfa_ioc_get_mfg_nwwn(struct bfa_ioc *ioc) +{ + return ioc->attr->mfg_nwwn; +} + +mac_t +bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc) +{ + mac_t m; + + m = ioc->attr->mfg_mac; + if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) + m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); + else + bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), + bfa_ioc_pcifn(ioc)); + + return m; +} + +bool +bfa_ioc_get_fcmode(struct bfa_ioc *ioc) +{ + return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id); +} + +/** + * Firmware failure detected. Start recovery actions. + */ +static void +bfa_ioc_recover(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_hbfails); + bfa_fsm_send_event(ioc, IOC_E_HBFAIL); +} + +static void +bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc) +{ + if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) + return; + +} diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h new file mode 100644 index 000000000000..2e5c0adef899 --- /dev/null +++ b/drivers/net/bna/bfa_ioc.h @@ -0,0 +1,343 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_IOC_H__ +#define __BFA_IOC_H__ + +#include "bfa_sm.h" +#include "bfi.h" +#include "cna.h" + +#define BFA_IOC_TOV 3000 /* msecs */ +#define BFA_IOC_HWSEM_TOV 500 /* msecs */ +#define BFA_IOC_HB_TOV 500 /* msecs */ +#define BFA_IOC_HWINIT_MAX 2 +#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV + +/** + * Generic Scatter Gather Element used by driver + */ +struct bfa_sge { + u32 sg_len; + void *sg_addr; +}; + +/** + * PCI device information required by IOC + */ +struct bfa_pcidev { + int pci_slot; + u8 pci_func; + u16 device_id; + void __iomem *pci_bar_kva; +}; + +/** + * Structure used to remember the DMA-able memory block's KVA and Physical + * Address + */ +struct bfa_dma { + void *kva; /* ! Kernel virtual address */ + u64 pa; /* ! Physical address */ +}; + +#define BFA_DMA_ALIGN_SZ 256 + +/** + * smem size for Crossbow and Catapult + */ +#define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */ +#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */ + +/** + * @brief BFA dma address assignment macro + */ +#define bfa_dma_addr_set(dma_addr, pa) \ + __bfa_dma_addr_set(&dma_addr, (u64)pa) + +static inline void +__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa) +{ + dma_addr->a32.addr_lo = (u32) pa; + dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa)); +} + +/** + * @brief BFA dma address assignment macro. (big endian format) + */ +#define bfa_dma_be_addr_set(dma_addr, pa) \ + __bfa_dma_be_addr_set(&dma_addr, (u64)pa) +static inline void +__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa) +{ + dma_addr->a32.addr_lo = (u32) htonl(pa); + dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa)); +} + +struct bfa_ioc_regs { + void __iomem *hfn_mbox_cmd; + void __iomem *hfn_mbox; + void __iomem *lpu_mbox_cmd; + void __iomem *lpu_mbox; + void __iomem *pss_ctl_reg; + void __iomem *pss_err_status_reg; + void __iomem *app_pll_fast_ctl_reg; + void __iomem *app_pll_slow_ctl_reg; + void __iomem *ioc_sem_reg; + void __iomem *ioc_usage_sem_reg; + void __iomem *ioc_init_sem_reg; + void __iomem *ioc_usage_reg; + void __iomem *host_page_num_fn; + void __iomem *heartbeat; + void __iomem *ioc_fwstate; + void __iomem *ll_halt; + void __iomem *err_set; + void __iomem *shirq_isr_next; + void __iomem *shirq_msk_next; + void __iomem *smem_page_start; + u32 smem_pg0; +}; + +/** + * IOC Mailbox structures + */ +struct bfa_mbox_cmd { + struct list_head qe; + u32 msg[BFI_IOC_MSGSZ]; +}; + +/** + * IOC mailbox module + */ +typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg *m); +struct bfa_ioc_mbox_mod { + struct list_head cmd_q; /*!< pending mbox queue */ + int nmclass; /*!< number of handlers */ + struct { + bfa_ioc_mbox_mcfunc_t cbfn; /*!< message handlers */ + void *cbarg; + } mbhdlr[BFI_MC_MAX]; +}; + +/** + * IOC callback function interfaces + */ +typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status); +typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa); +typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa); +typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa); +struct bfa_ioc_cbfn { + bfa_ioc_enable_cbfn_t enable_cbfn; + bfa_ioc_disable_cbfn_t disable_cbfn; + bfa_ioc_hbfail_cbfn_t hbfail_cbfn; + bfa_ioc_reset_cbfn_t reset_cbfn; +}; + +/** + * Heartbeat failure notification queue element. + */ +struct bfa_ioc_hbfail_notify { + struct list_head qe; + bfa_ioc_hbfail_cbfn_t cbfn; + void *cbarg; +}; + +/** + * Initialize a heartbeat failure notification structure + */ +#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \ + (__notify)->cbfn = (__cbfn); \ + (__notify)->cbarg = (__cbarg); \ +} while (0) + +struct bfa_ioc { + bfa_fsm_t fsm; + struct bfa *bfa; + struct bfa_pcidev pcidev; + struct bfa_timer_mod *timer_mod; + struct timer_list ioc_timer; + struct timer_list sem_timer; + struct timer_list hb_timer; + u32 hb_count; + u32 retry_count; + struct list_head hb_notify_q; + void *dbg_fwsave; + int dbg_fwsave_len; + bool dbg_fwsave_once; + enum bfi_mclass ioc_mc; + struct bfa_ioc_regs ioc_regs; + struct bfa_ioc_drv_stats stats; + bool auto_recover; + bool fcmode; + bool ctdev; + bool cna; + bool pllinit; + bool stats_busy; /*!< outstanding stats */ + u8 port_id; + + struct bfa_dma attr_dma; + struct bfi_ioc_attr *attr; + struct bfa_ioc_cbfn *cbfn; + struct bfa_ioc_mbox_mod mbox_mod; + struct bfa_ioc_hwif *ioc_hwif; +}; + +struct bfa_ioc_hwif { + enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode); + bool (*ioc_firmware_lock) (struct bfa_ioc *ioc); + void (*ioc_firmware_unlock) (struct bfa_ioc *ioc); + void (*ioc_reg_init) (struct bfa_ioc *ioc); + void (*ioc_map_port) (struct bfa_ioc *ioc); + void (*ioc_isr_mode_set) (struct bfa_ioc *ioc, + bool msix); + void (*ioc_notify_hbfail) (struct bfa_ioc *ioc); + void (*ioc_ownership_reset) (struct bfa_ioc *ioc); +}; + +#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) +#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) +#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) +#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) +#define bfa_ioc_fetch_stats(__ioc, __stats) \ + (((__stats)->drv_stats) = (__ioc)->stats) +#define bfa_ioc_clr_stats(__ioc) \ + memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats)) +#define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize) +#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) +#define bfa_ioc_speed_sup(__ioc) \ + BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) +#define bfa_ioc_get_nports(__ioc) \ + BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) + +#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) +#define BFA_IOC_FWIMG_MINSZ (16 * 1024) +#define BFA_IOC_FWIMG_TYPE(__ioc) \ + (((__ioc)->ctdev) ? \ + (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \ + BFI_IMAGE_CB_FC) +#define BFA_IOC_FW_SMEM_SIZE(__ioc) \ + (((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE) +#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) + +/** + * IOC mailbox interface + */ +void bfa_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd); +void bfa_ioc_mbox_register(struct bfa_ioc *ioc, + bfa_ioc_mbox_mcfunc_t *mcfuncs); +void bfa_ioc_mbox_isr(struct bfa_ioc *ioc); +void bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len); +void bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg); +void bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, + bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg); + +/** + * IOC interfaces + */ + +#define bfa_ioc_pll_init_asic(__ioc) \ + ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \ + (__ioc)->fcmode)) + +enum bfa_status bfa_ioc_pll_init(struct bfa_ioc *ioc); +enum bfa_status bfa_ioc_cb_pll_init(void __iomem *rb, bool fcmode); +enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); + +#define bfa_ioc_isr_mode_set(__ioc, __msix) \ + ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix)) +#define bfa_ioc_ownership_reset(__ioc) \ + ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc)) + +void bfa_ioc_set_ct_hwif(struct bfa_ioc *ioc); + +void bfa_ioc_attach(struct bfa_ioc *ioc, void *bfa, + struct bfa_ioc_cbfn *cbfn); +void bfa_ioc_auto_recover(bool auto_recover); +void bfa_ioc_detach(struct bfa_ioc *ioc); +void bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, + enum bfi_mclass mc); +u32 bfa_ioc_meminfo(void); +void bfa_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa); +void bfa_ioc_enable(struct bfa_ioc *ioc); +void bfa_ioc_disable(struct bfa_ioc *ioc); +bool bfa_ioc_intx_claim(struct bfa_ioc *ioc); + +void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, + u32 boot_param); +void bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *msg); +void bfa_ioc_error_isr(struct bfa_ioc *ioc); +bool bfa_ioc_is_operational(struct bfa_ioc *ioc); +bool bfa_ioc_is_initialized(struct bfa_ioc *ioc); +bool bfa_ioc_is_disabled(struct bfa_ioc *ioc); +bool bfa_ioc_fw_mismatch(struct bfa_ioc *ioc); +bool bfa_ioc_adapter_is_disabled(struct bfa_ioc *ioc); +void bfa_ioc_cfg_complete(struct bfa_ioc *ioc); +enum bfa_ioc_type bfa_ioc_get_type(struct bfa_ioc *ioc); +void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num); +void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver); +void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver); +void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); +void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, + char *manufacturer); +void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev); +enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc *ioc); + +void bfa_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); +void bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, + struct bfa_adapter_attr *ad_attr); +u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); +u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr); +void bfa_ioc_set_fcmode(struct bfa_ioc *ioc); +bool bfa_ioc_get_fcmode(struct bfa_ioc *ioc); +void bfa_ioc_hbfail_register(struct bfa_ioc *ioc, + struct bfa_ioc_hbfail_notify *notify); +bool bfa_ioc_sem_get(void __iomem *sem_reg); +void bfa_ioc_sem_release(void __iomem *sem_reg); +void bfa_ioc_hw_sem_release(struct bfa_ioc *ioc); +void bfa_ioc_fwver_get(struct bfa_ioc *ioc, + struct bfi_ioc_image_hdr *fwhdr); +bool bfa_ioc_fwver_cmp(struct bfa_ioc *ioc, + struct bfi_ioc_image_hdr *fwhdr); + +/* + * Timeout APIs + */ +void bfa_ioc_timeout(void *ioc); +void bfa_ioc_hb_check(void *ioc); +void bfa_ioc_sem_timeout(void *ioc); + +/* + * bfa mfg wwn API functions + */ +u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); +u64 bfa_ioc_get_nwwn(struct bfa_ioc *ioc); +mac_t bfa_ioc_get_mac(struct bfa_ioc *ioc); +u64 bfa_ioc_get_mfg_pwwn(struct bfa_ioc *ioc); +u64 bfa_ioc_get_mfg_nwwn(struct bfa_ioc *ioc); +mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc); +u64 bfa_ioc_get_adid(struct bfa_ioc *ioc); + +/* + * F/W Image Size & Chunk + */ +u32 *bfa_cb_image_get_chunk(int type, u32 off); +u32 bfa_cb_image_get_size(int type); + +#endif /* __BFA_IOC_H__ */ diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c new file mode 100644 index 000000000000..870046e32c8d --- /dev/null +++ b/drivers/net/bna/bfa_ioc_ct.c @@ -0,0 +1,391 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_ioc.h" +#include "cna.h" +#include "bfi.h" +#include "bfi_ctreg.h" +#include "bfa_defs.h" + +/* + * forward declarations + */ +static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc); +static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc); +static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc); +static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc); +static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix); +static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc); +static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); + +struct bfa_ioc_hwif hwif_ct; + +/** + * Called from bfa_ioc_attach() to map asic specific calls. + */ +void +bfa_ioc_set_ct_hwif(struct bfa_ioc *ioc) +{ + hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; + hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock; + hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; + hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; + hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; + hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; + hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail; + hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; + + ioc->ioc_hwif = &hwif_ct; +} + +/** + * Return true if firmware of current driver matches the running firmware. + */ +static bool +bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) +{ + enum bfi_ioc_state ioc_fwstate; + u32 usecnt; + struct bfi_ioc_image_hdr fwhdr; + + /** + * Firmware match check is relevant only for CNA. + */ + if (!ioc->cna) + return true; + + /** + * If bios boot (flash based) -- do not increment usage count + */ + if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < + BFA_IOC_FWIMG_MINSZ) + return true; + + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = readl(ioc->ioc_regs.ioc_usage_reg); + + /** + * If usage count is 0, always return TRUE. + */ + if (usecnt == 0) { + writel(1, ioc->ioc_regs.ioc_usage_reg); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return true; + } + + ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + + /** + * Use count cannot be non-zero and chip in uninitialized state. + */ + BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT)); + + /** + * Check if another driver with a different firmware is active + */ + bfa_ioc_fwver_get(ioc, &fwhdr); + if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return false; + } + + /** + * Same firmware version. Increment the reference count. + */ + usecnt++; + writel(usecnt, ioc->ioc_regs.ioc_usage_reg); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return true; +} + +static void +bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc) +{ + u32 usecnt; + + /** + * Firmware lock is relevant only for CNA. + */ + if (!ioc->cna) + return; + + /** + * If bios boot (flash based) -- do not decrement usage count + */ + if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < + BFA_IOC_FWIMG_MINSZ) + return; + + /** + * decrement usage count + */ + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = readl(ioc->ioc_regs.ioc_usage_reg); + BUG_ON(!(usecnt > 0)); + + usecnt--; + writel(usecnt, ioc->ioc_regs.ioc_usage_reg); + + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); +} + +/** + * Notify other functions on HB failure. + */ +static void +bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc) +{ + if (ioc->cna) { + writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt); + /* Wait for halt to take effect */ + readl(ioc->ioc_regs.ll_halt); + } else { + writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set); + readl(ioc->ioc_regs.err_set); + } +} + +/** + * Host to LPU mailbox message addresses + */ +static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { + { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, + { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, + { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, + { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 0 + */ +static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = { + { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 1 + */ +static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = { + { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } +}; + +static void +bfa_ioc_ct_reg_init(struct bfa_ioc *ioc) +{ + void __iomem *rb; + int pcifn = bfa_ioc_pcifn(ioc); + + rb = bfa_ioc_bar0(ioc); + + ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; + ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; + ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; + + if (ioc->port_id == 0) { + ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; + ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; + } else { + ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); + ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; + } + + /* + * PSS control registers + */ + ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); + ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); + ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); + + /* + * IOC semaphore registers and serialization + */ + ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); + ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); + ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); + ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); + + /** + * sram memory access + */ + ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); + ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; + + /* + * err set reg : for notification of hb failure in fcmode + */ + ioc->ioc_regs.err_set = (rb + ERR_SET_REG); +} + +/** + * Initialize IOC to port mapping. + */ + +#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) +static void +bfa_ioc_ct_map_port(struct bfa_ioc *ioc) +{ + void __iomem *rb = ioc->pcidev.pci_bar_kva; + u32 r32; + + /** + * For catapult, base port id on personality register and IOC type + */ + r32 = readl(rb + FNC_PERS_REG); + r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); + ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; + +} + +/** + * Set interrupt mode for a function: INTX or MSIX + */ +static void +bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix) +{ + void __iomem *rb = ioc->pcidev.pci_bar_kva; + u32 r32, mode; + + r32 = readl(rb + FNC_PERS_REG); + + mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & + __F0_INTX_STATUS; + + /** + * If already in desired mode, do not change anything + */ + if (!msix && mode) + return; + + if (msix) + mode = __F0_INTX_STATUS_MSIX; + else + mode = __F0_INTX_STATUS_INTA; + + r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + + writel(r32, rb + FNC_PERS_REG); +} + +/** + * Cleanup hw semaphore and usecnt registers + */ +static void +bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) +{ + if (ioc->cna) { + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + writel(0, ioc->ioc_regs.ioc_usage_reg); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + } + + /* + * Read the hw sem reg to make sure that it is locked + * before we clear it. If it is not locked, writing 1 + * will lock it instead of clearing it. + */ + readl(ioc->ioc_regs.ioc_sem_reg); + bfa_ioc_hw_sem_release(ioc); +} + +enum bfa_status +bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode) +{ + u32 pll_sclk, pll_fclk, r32; + + pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST | + __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) | + __APP_PLL_312_JITLMT0_1(3U) | + __APP_PLL_312_CNTLMT0_1(1U); + pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST | + __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | + __APP_PLL_425_JITLMT0_1(3U) | + __APP_PLL_425_CNTLMT0_1(1U); + if (fcmode) { + writel(0, (rb + OP_MODE)); + writel(__APP_EMS_CMLCKSEL | + __APP_EMS_REFCKBUFEN2 | + __APP_EMS_CHANNEL_SEL, + (rb + ETH_MAC_SER_REG)); + } else { + writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE)); + writel(__APP_EMS_REFCKBUFEN1, + (rb + ETH_MAC_SER_REG)); + } + writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG)); + writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); + writel(pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET, + rb + APP_PLL_425_CTL_REG); + writel(pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE, + rb + APP_PLL_425_CTL_REG); + readl(rb + HOSTFN0_INT_MSK); + udelay(2000); + writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); + writel(pll_sclk | + __APP_PLL_312_ENABLE, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_ENABLE, + rb + APP_PLL_425_CTL_REG); + if (!fcmode) { + writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0)); + writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1)); + } + r32 = readl((rb + PSS_CTL_REG)); + r32 &= ~__PSS_LMEM_RESET; + writel(r32, (rb + PSS_CTL_REG)); + udelay(1000); + if (!fcmode) { + writel(0, (rb + PMM_1T_RESET_REG_P0)); + writel(0, (rb + PMM_1T_RESET_REG_P1)); + } + + writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG)); + udelay(1000); + r32 = readl((rb + MBIST_STAT_REG)); + writel(0, (rb + MBIST_CTL_REG)); + return BFA_STATUS_OK; +} diff --git a/drivers/net/bna/bfa_sm.h b/drivers/net/bna/bfa_sm.h new file mode 100644 index 000000000000..1d3d975d6f68 --- /dev/null +++ b/drivers/net/bna/bfa_sm.h @@ -0,0 +1,88 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/** + * @file bfasm.h State machine defines + */ + +#ifndef __BFA_SM_H__ +#define __BFA_SM_H__ + +#include "cna.h" + +typedef void (*bfa_sm_t)(void *sm, int event); + +/** + * oc - object class eg. bfa_ioc + * st - state, eg. reset + * otype - object type, eg. struct bfa_ioc + * etype - object type, eg. enum ioc_event + */ +#define bfa_sm_state_decl(oc, st, otype, etype) \ + static void oc ## _sm_ ## st(otype * fsm, etype event) + +#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) +#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) +#define bfa_sm_get_state(_sm) ((_sm)->sm) +#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state)) + +/** + * For converting from state machine function to state encoding. + */ +struct bfa_sm_table { + bfa_sm_t sm; /*!< state machine function */ + int state; /*!< state machine encoding */ + char *name; /*!< state name for display */ +}; +#define BFA_SM(_sm) ((bfa_sm_t)(_sm)) + +/** + * State machine with entry actions. + */ +typedef void (*bfa_fsm_t)(void *fsm, int event); + +/** + * oc - object class eg. bfa_ioc + * st - state, eg. reset + * otype - object type, eg. struct bfa_ioc + * etype - object type, eg. enum ioc_event + */ +#define bfa_fsm_state_decl(oc, st, otype, etype) \ + static void oc ## _sm_ ## st(otype * fsm, etype event); \ + static void oc ## _sm_ ## st ## _entry(otype * fsm) + +#define bfa_fsm_set_state(_fsm, _state) do { \ + (_fsm)->fsm = (bfa_fsm_t)(_state); \ + _state ## _entry(_fsm); \ +} while (0) + +#define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event))) +#define bfa_fsm_get_state(_fsm) ((_fsm)->fsm) +#define bfa_fsm_cmp_state(_fsm, _state) \ + ((_fsm)->fsm == (bfa_fsm_t)(_state)) + +static inline int +bfa_sm_to_state(struct bfa_sm_table *smt, bfa_sm_t sm) +{ + int i = 0; + + while (smt[i].sm && smt[i].sm != sm) + i++; + return smt[i].state; +} +#endif diff --git a/drivers/net/bna/bfa_wc.h b/drivers/net/bna/bfa_wc.h new file mode 100644 index 000000000000..d0e4caee67b0 --- /dev/null +++ b/drivers/net/bna/bfa_wc.h @@ -0,0 +1,69 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/** + * @file bfa_wc.h Generic wait counter. + */ + +#ifndef __BFA_WC_H__ +#define __BFA_WC_H__ + +typedef void (*bfa_wc_resume_t) (void *cbarg); + +struct bfa_wc { + bfa_wc_resume_t wc_resume; + void *wc_cbarg; + int wc_count; +}; + +static inline void +bfa_wc_up(struct bfa_wc *wc) +{ + wc->wc_count++; +} + +static inline void +bfa_wc_down(struct bfa_wc *wc) +{ + wc->wc_count--; + if (wc->wc_count == 0) + wc->wc_resume(wc->wc_cbarg); +} + +/** + * Initialize a waiting counter. + */ +static inline void +bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg) +{ + wc->wc_resume = wc_resume; + wc->wc_cbarg = wc_cbarg; + wc->wc_count = 0; + bfa_wc_up(wc); +} + +/** + * Wait for counter to reach zero + */ +static inline void +bfa_wc_wait(struct bfa_wc *wc) +{ + bfa_wc_down(wc); +} + +#endif diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h new file mode 100644 index 000000000000..a97396811050 --- /dev/null +++ b/drivers/net/bna/bfi.h @@ -0,0 +1,392 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFI_H__ +#define __BFI_H__ + +#include "bfa_defs.h" + +#pragma pack(1) + +/** + * BFI FW image type + */ +#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */ +#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32)) +enum { + BFI_IMAGE_CB_FC, + BFI_IMAGE_CT_FC, + BFI_IMAGE_CT_CNA, + BFI_IMAGE_MAX, +}; + +/** + * Msg header common to all msgs + */ +struct bfi_mhdr { + u8 msg_class; /*!< @ref enum bfi_mclass */ + u8 msg_id; /*!< msg opcode with in the class */ + union { + struct { + u8 rsvd; + u8 lpu_id; /*!< msg destination */ + } h2i; + u16 i2htok; /*!< token in msgs to host */ + } mtag; +}; + +#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \ + (_mh).msg_class = (_mc); \ + (_mh).msg_id = (_op); \ + (_mh).mtag.h2i.lpu_id = (_lpuid); \ +} while (0) + +#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \ + (_mh).msg_class = (_mc); \ + (_mh).msg_id = (_op); \ + (_mh).mtag.i2htok = (_i2htok); \ +} while (0) + +/* + * Message opcodes: 0-127 to firmware, 128-255 to host + */ +#define BFI_I2H_OPCODE_BASE 128 +#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE) + +/** + **************************************************************************** + * + * Scatter Gather Element and Page definition + * + **************************************************************************** + */ + +#define BFI_SGE_INLINE 1 +#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1) + +/** + * SG Flags + */ +enum { + BFI_SGE_DATA = 0, /*!< data address, not last */ + BFI_SGE_DATA_CPL = 1, /*!< data addr, last in current page */ + BFI_SGE_DATA_LAST = 3, /*!< data address, last */ + BFI_SGE_LINK = 2, /*!< link address */ + BFI_SGE_PGDLEN = 2, /*!< cumulative data length for page */ +}; + +/** + * DMA addresses + */ +union bfi_addr_u { + struct { + u32 addr_lo; + u32 addr_hi; + } a32; +}; + +/** + * Scatter Gather Element + */ +struct bfi_sge { +#ifdef __BIGENDIAN + u32 flags:2, + rsvd:2, + sg_len:28; +#else + u32 sg_len:28, + rsvd:2, + flags:2; +#endif + union bfi_addr_u sga; +}; + +/** + * Scatter Gather Page + */ +#define BFI_SGPG_DATA_SGES 7 +#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1) +#define BFI_SGPG_RSVD_WD_LEN 8 +struct bfi_sgpg { + struct bfi_sge sges[BFI_SGPG_SGES_MAX]; + u32 rsvd[BFI_SGPG_RSVD_WD_LEN]; +}; + +/* + * Large Message structure - 128 Bytes size Msgs + */ +#define BFI_LMSG_SZ 128 +#define BFI_LMSG_PL_WSZ \ + ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr)) / 4) + +struct bfi_msg { + struct bfi_mhdr mhdr; + u32 pl[BFI_LMSG_PL_WSZ]; +}; + +/** + * Mailbox message structure + */ +#define BFI_MBMSG_SZ 7 +struct bfi_mbmsg { + struct bfi_mhdr mh; + u32 pl[BFI_MBMSG_SZ]; +}; + +/** + * Message Classes + */ +enum bfi_mclass { + BFI_MC_IOC = 1, /*!< IO Controller (IOC) */ + BFI_MC_DIAG = 2, /*!< Diagnostic Msgs */ + BFI_MC_FLASH = 3, /*!< Flash message class */ + BFI_MC_CEE = 4, /*!< CEE */ + BFI_MC_FCPORT = 5, /*!< FC port */ + BFI_MC_IOCFC = 6, /*!< FC - IO Controller (IOC) */ + BFI_MC_LL = 7, /*!< Link Layer */ + BFI_MC_UF = 8, /*!< Unsolicited frame receive */ + BFI_MC_FCXP = 9, /*!< FC Transport */ + BFI_MC_LPS = 10, /*!< lport fc login services */ + BFI_MC_RPORT = 11, /*!< Remote port */ + BFI_MC_ITNIM = 12, /*!< I-T nexus (Initiator mode) */ + BFI_MC_IOIM_READ = 13, /*!< read IO (Initiator mode) */ + BFI_MC_IOIM_WRITE = 14, /*!< write IO (Initiator mode) */ + BFI_MC_IOIM_IO = 15, /*!< IO (Initiator mode) */ + BFI_MC_IOIM = 16, /*!< IO (Initiator mode) */ + BFI_MC_IOIM_IOCOM = 17, /*!< good IO completion */ + BFI_MC_TSKIM = 18, /*!< Initiator Task management */ + BFI_MC_SBOOT = 19, /*!< SAN boot services */ + BFI_MC_IPFC = 20, /*!< IP over FC Msgs */ + BFI_MC_PORT = 21, /*!< Physical port */ + BFI_MC_SFP = 22, /*!< SFP module */ + BFI_MC_MSGQ = 23, /*!< MSGQ */ + BFI_MC_ENET = 24, /*!< ENET commands/responses */ + BFI_MC_MAX = 32 +}; + +#define BFI_IOC_MAX_CQS 4 +#define BFI_IOC_MAX_CQS_ASIC 8 +#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */ + +#define BFI_BOOT_TYPE_OFF 8 +#define BFI_BOOT_PARAM_OFF 12 + +#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */ +#define BFI_BOOT_TYPE_FLASH 1 +#define BFI_BOOT_TYPE_MEMTEST 2 + +#define BFI_BOOT_MEMTEST_RES_ADDR 0x900 +#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3 + +/** + *---------------------------------------------------------------------- + * IOC + *---------------------------------------------------------------------- + */ + +enum bfi_ioc_h2i_msgs { + BFI_IOC_H2I_ENABLE_REQ = 1, + BFI_IOC_H2I_DISABLE_REQ = 2, + BFI_IOC_H2I_GETATTR_REQ = 3, + BFI_IOC_H2I_DBG_SYNC = 4, + BFI_IOC_H2I_DBG_DUMP = 5, +}; + +enum bfi_ioc_i2h_msgs { + BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1), + BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2), + BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3), + BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4), + BFI_IOC_I2H_HBEAT = BFA_I2HM(5), +}; + +/** + * BFI_IOC_H2I_GETATTR_REQ message + */ +struct bfi_ioc_getattr_req { + struct bfi_mhdr mh; + union bfi_addr_u attr_addr; +}; + +struct bfi_ioc_attr { + u64 mfg_pwwn; /*!< Mfg port wwn */ + u64 mfg_nwwn; /*!< Mfg node wwn */ + mac_t mfg_mac; /*!< Mfg mac */ + u16 rsvd_a; + u64 pwwn; + u64 nwwn; + mac_t mac; /*!< PBC or Mfg mac */ + u16 rsvd_b; + mac_t fcoe_mac; + u16 rsvd_c; + char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; + u8 pcie_gen; + u8 pcie_lanes_orig; + u8 pcie_lanes; + u8 rx_bbcredit; /*!< receive buffer credits */ + u32 adapter_prop; /*!< adapter properties */ + u16 maxfrsize; /*!< max receive frame size */ + char asic_rev; + u8 rsvd_d; + char fw_version[BFA_VERSION_LEN]; + char optrom_version[BFA_VERSION_LEN]; + struct bfa_mfg_vpd vpd; + u32 card_type; /*!< card type */ +}; + +/** + * BFI_IOC_I2H_GETATTR_REPLY message + */ +struct bfi_ioc_getattr_reply { + struct bfi_mhdr mh; /*!< Common msg header */ + u8 status; /*!< cfg reply status */ + u8 rsvd[3]; +}; + +/** + * Firmware memory page offsets + */ +#define BFI_IOC_SMEM_PG0_CB (0x40) +#define BFI_IOC_SMEM_PG0_CT (0x180) + +/** + * Firmware statistic offset + */ +#define BFI_IOC_FWSTATS_OFF (0x6B40) +#define BFI_IOC_FWSTATS_SZ (4096) + +/** + * Firmware trace offset + */ +#define BFI_IOC_TRC_OFF (0x4b00) +#define BFI_IOC_TRC_ENTS 256 + +#define BFI_IOC_FW_SIGNATURE (0xbfadbfad) +#define BFI_IOC_MD5SUM_SZ 4 +struct bfi_ioc_image_hdr { + u32 signature; /*!< constant signature */ + u32 rsvd_a; + u32 exec; /*!< exec vector */ + u32 param; /*!< parameters */ + u32 rsvd_b[4]; + u32 md5sum[BFI_IOC_MD5SUM_SZ]; +}; + +/** + * BFI_IOC_I2H_READY_EVENT message + */ +struct bfi_ioc_rdy_event { + struct bfi_mhdr mh; /*!< common msg header */ + u8 init_status; /*!< init event status */ + u8 rsvd[3]; +}; + +struct bfi_ioc_hbeat { + struct bfi_mhdr mh; /*!< common msg header */ + u32 hb_count; /*!< current heart beat count */ +}; + +/** + * IOC hardware/firmware state + */ +enum bfi_ioc_state { + BFI_IOC_UNINIT = 0, /*!< not initialized */ + BFI_IOC_INITING = 1, /*!< h/w is being initialized */ + BFI_IOC_HWINIT = 2, /*!< h/w is initialized */ + BFI_IOC_CFG = 3, /*!< IOC configuration in progress */ + BFI_IOC_OP = 4, /*!< IOC is operational */ + BFI_IOC_DISABLING = 5, /*!< IOC is being disabled */ + BFI_IOC_DISABLED = 6, /*!< IOC is disabled */ + BFI_IOC_CFG_DISABLED = 7, /*!< IOC is being disabled;transient */ + BFI_IOC_FAIL = 8, /*!< IOC heart-beat failure */ + BFI_IOC_MEMTEST = 9, /*!< IOC is doing memtest */ +}; + +#define BFI_IOC_ENDIAN_SIG 0x12345678 + +enum { + BFI_ADAPTER_TYPE_FC = 0x01, /*!< FC adapters */ + BFI_ADAPTER_TYPE_MK = 0x0f0000, /*!< adapter type mask */ + BFI_ADAPTER_TYPE_SH = 16, /*!< adapter type shift */ + BFI_ADAPTER_NPORTS_MK = 0xff00, /*!< number of ports mask */ + BFI_ADAPTER_NPORTS_SH = 8, /*!< number of ports shift */ + BFI_ADAPTER_SPEED_MK = 0xff, /*!< adapter speed mask */ + BFI_ADAPTER_SPEED_SH = 0, /*!< adapter speed shift */ + BFI_ADAPTER_PROTO = 0x100000, /*!< prototype adapaters */ + BFI_ADAPTER_TTV = 0x200000, /*!< TTV debug capable */ + BFI_ADAPTER_UNSUPP = 0x400000, /*!< unknown adapter type */ +}; + +#define BFI_ADAPTER_GETP(__prop, __adap_prop) \ + (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \ + BFI_ADAPTER_ ## __prop ## _SH) +#define BFI_ADAPTER_SETP(__prop, __val) \ + ((__val) << BFI_ADAPTER_ ## __prop ## _SH) +#define BFI_ADAPTER_IS_PROTO(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_PROTO) +#define BFI_ADAPTER_IS_TTV(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_TTV) +#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_UNSUPP) +#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \ + ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \ + BFI_ADAPTER_UNSUPP)) + +/** + * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages + */ +struct bfi_ioc_ctrl_req { + struct bfi_mhdr mh; + u8 ioc_class; + u8 rsvd[3]; + u32 tv_sec; +}; + +/** + * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages + */ +struct bfi_ioc_ctrl_reply { + struct bfi_mhdr mh; /*!< Common msg header */ + u8 status; /*!< enable/disable status */ + u8 rsvd[3]; +}; + +#define BFI_IOC_MSGSZ 8 +/** + * H2I Messages + */ +union bfi_ioc_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_ioc_ctrl_req enable_req; + struct bfi_ioc_ctrl_req disable_req; + struct bfi_ioc_getattr_req getattr_req; + u32 mboxmsg[BFI_IOC_MSGSZ]; +}; + +/** + * I2H Messages + */ +union bfi_ioc_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_ioc_rdy_event rdy_event; + u32 mboxmsg[BFI_IOC_MSGSZ]; +}; + +#pragma pack() + +#endif /* __BFI_H__ */ diff --git a/drivers/net/bna/bfi_cna.h b/drivers/net/bna/bfi_cna.h new file mode 100644 index 000000000000..4eecabea397b --- /dev/null +++ b/drivers/net/bna/bfi_cna.h @@ -0,0 +1,199 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFI_CNA_H__ +#define __BFI_CNA_H__ + +#include "bfi.h" +#include "bfa_defs_cna.h" + +#pragma pack(1) + +enum bfi_port_h2i { + BFI_PORT_H2I_ENABLE_REQ = (1), + BFI_PORT_H2I_DISABLE_REQ = (2), + BFI_PORT_H2I_GET_STATS_REQ = (3), + BFI_PORT_H2I_CLEAR_STATS_REQ = (4), +}; + +enum bfi_port_i2h { + BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1), + BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2), + BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3), + BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), +}; + +/** + * Generic REQ type + */ +struct bfi_port_generic_req { + struct bfi_mhdr mh; /*!< msg header */ + u32 msgtag; /*!< msgtag for reply */ + u32 rsvd; +}; + +/** + * Generic RSP type + */ +struct bfi_port_generic_rsp { + struct bfi_mhdr mh; /*!< common msg header */ + u8 status; /*!< port enable status */ + u8 rsvd[3]; + u32 msgtag; /*!< msgtag for reply */ +}; + +/** + * @todo + * BFI_PORT_H2I_ENABLE_REQ + */ + +/** + * @todo + * BFI_PORT_I2H_ENABLE_RSP + */ + +/** + * BFI_PORT_H2I_DISABLE_REQ + */ + +/** + * BFI_PORT_I2H_DISABLE_RSP + */ + +/** + * BFI_PORT_H2I_GET_STATS_REQ + */ +struct bfi_port_get_stats_req { + struct bfi_mhdr mh; /*!< common msg header */ + union bfi_addr_u dma_addr; +}; + +/** + * BFI_PORT_I2H_GET_STATS_RSP + */ + +/** + * BFI_PORT_H2I_CLEAR_STATS_REQ + */ + +/** + * BFI_PORT_I2H_CLEAR_STATS_RSP + */ + +union bfi_port_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_port_generic_req enable_req; + struct bfi_port_generic_req disable_req; + struct bfi_port_get_stats_req getstats_req; + struct bfi_port_generic_req clearstats_req; +}; + +union bfi_port_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_port_generic_rsp enable_rsp; + struct bfi_port_generic_rsp disable_rsp; + struct bfi_port_generic_rsp getstats_rsp; + struct bfi_port_generic_rsp clearstats_rsp; +}; + +/* @brief Mailbox commands from host to (DCBX/LLDP) firmware */ +enum bfi_cee_h2i_msgs { + BFI_CEE_H2I_GET_CFG_REQ = 1, + BFI_CEE_H2I_RESET_STATS = 2, + BFI_CEE_H2I_GET_STATS_REQ = 3, +}; + +/* @brief Mailbox reply and AEN messages from DCBX/LLDP firmware to host */ +enum bfi_cee_i2h_msgs { + BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1), + BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2), + BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3), +}; + +/* Data structures */ + +/* + * @brief H2I command structure for resetting the stats. + * BFI_CEE_H2I_RESET_STATS + */ +struct bfi_lldp_reset_stats { + struct bfi_mhdr mh; +}; + +/* + * @brief H2I command structure for resetting the stats. + * BFI_CEE_H2I_RESET_STATS + */ +struct bfi_cee_reset_stats { + struct bfi_mhdr mh; +}; + +/* + * @brief get configuration command from host + * BFI_CEE_H2I_GET_CFG_REQ + */ +struct bfi_cee_get_req { + struct bfi_mhdr mh; + union bfi_addr_u dma_addr; +}; + +/* + * @brief reply message from firmware + * BFI_CEE_I2H_GET_CFG_RSP + */ +struct bfi_cee_get_rsp { + struct bfi_mhdr mh; + u8 cmd_status; + u8 rsvd[3]; +}; + +/* + * @brief get configuration command from host + * BFI_CEE_H2I_GET_STATS_REQ + */ +struct bfi_cee_stats_req { + struct bfi_mhdr mh; + union bfi_addr_u dma_addr; +}; + +/* + * @brief reply message from firmware + * BFI_CEE_I2H_GET_STATS_RSP + */ +struct bfi_cee_stats_rsp { + struct bfi_mhdr mh; + u8 cmd_status; + u8 rsvd[3]; +}; + +/* @brief mailbox command structures from host to firmware */ +union bfi_cee_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_cee_get_req get_req; + struct bfi_cee_stats_req stats_req; +}; + +/* @brief mailbox message structures from firmware to host */ +union bfi_cee_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_cee_get_rsp get_rsp; + struct bfi_cee_stats_rsp stats_rsp; +}; + +#pragma pack() + +#endif /* __BFI_CNA_H__ */ diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h new file mode 100644 index 000000000000..404ea351d4a1 --- /dev/null +++ b/drivers/net/bna/bfi_ctreg.h @@ -0,0 +1,637 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/* + * bfi_ctreg.h catapult host block register definitions + * + * !!! Do not edit. Auto generated. !!! + */ + +#ifndef __BFI_CTREG_H__ +#define __BFI_CTREG_H__ + +#define HOSTFN0_LPU_MBOX0_0 0x00019200 +#define HOSTFN1_LPU_MBOX0_8 0x00019260 +#define LPU_HOSTFN0_MBOX0_0 0x00019280 +#define LPU_HOSTFN1_MBOX0_8 0x000192e0 +#define HOSTFN2_LPU_MBOX0_0 0x00019400 +#define HOSTFN3_LPU_MBOX0_8 0x00019460 +#define LPU_HOSTFN2_MBOX0_0 0x00019480 +#define LPU_HOSTFN3_MBOX0_8 0x000194e0 +#define HOSTFN0_INT_STATUS 0x00014000 +#define __HOSTFN0_HALT_OCCURRED 0x01000000 +#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN0_INT_STATUS_LVL_SH 20 +#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH) +#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN0_INT_STATUS_P_SH 16 +#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH) +#define __HOSTFN0_INT_STATUS_F 0x0000ffff +#define HOSTFN0_INT_MSK 0x00014004 +#define HOST_PAGE_NUM_FN0 0x00014008 +#define __HOST_PAGE_NUM_FN 0x000001ff +#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c +#define __MSIX_ERR_INDEX_FN 0x000001ff +#define HOSTFN1_INT_STATUS 0x00014100 +#define __HOSTFN1_HALT_OCCURRED 0x01000000 +#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN1_INT_STATUS_LVL_SH 20 +#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH) +#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN1_INT_STATUS_P_SH 16 +#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH) +#define __HOSTFN1_INT_STATUS_F 0x0000ffff +#define HOSTFN1_INT_MSK 0x00014104 +#define HOST_PAGE_NUM_FN1 0x00014108 +#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c +#define APP_PLL_425_CTL_REG 0x00014204 +#define __P_425_PLL_LOCK 0x80000000 +#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000 +#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000 +#define __APP_PLL_425_RESET_TIMER_SH 17 +#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH) +#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000 +#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000 +#define __APP_PLL_425_CNTLMT0_1_SH 14 +#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH) +#define __APP_PLL_425_JITLMT0_1_MK 0x00003000 +#define __APP_PLL_425_JITLMT0_1_SH 12 +#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH) +#define __APP_PLL_425_HREF 0x00000800 +#define __APP_PLL_425_HDIV 0x00000400 +#define __APP_PLL_425_P0_1_MK 0x00000300 +#define __APP_PLL_425_P0_1_SH 8 +#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH) +#define __APP_PLL_425_Z0_2_MK 0x000000e0 +#define __APP_PLL_425_Z0_2_SH 5 +#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH) +#define __APP_PLL_425_RSEL200500 0x00000010 +#define __APP_PLL_425_ENARST 0x00000008 +#define __APP_PLL_425_BYPASS 0x00000004 +#define __APP_PLL_425_LRESETN 0x00000002 +#define __APP_PLL_425_ENABLE 0x00000001 +#define APP_PLL_312_CTL_REG 0x00014208 +#define __P_312_PLL_LOCK 0x80000000 +#define __ENABLE_MAC_AHB_1 0x00800000 +#define __ENABLE_MAC_AHB_0 0x00400000 +#define __ENABLE_MAC_1 0x00200000 +#define __ENABLE_MAC_0 0x00100000 +#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000 +#define __APP_PLL_312_RESET_TIMER_SH 17 +#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH) +#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000 +#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000 +#define __APP_PLL_312_CNTLMT0_1_SH 14 +#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH) +#define __APP_PLL_312_JITLMT0_1_MK 0x00003000 +#define __APP_PLL_312_JITLMT0_1_SH 12 +#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH) +#define __APP_PLL_312_HREF 0x00000800 +#define __APP_PLL_312_HDIV 0x00000400 +#define __APP_PLL_312_P0_1_MK 0x00000300 +#define __APP_PLL_312_P0_1_SH 8 +#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH) +#define __APP_PLL_312_Z0_2_MK 0x000000e0 +#define __APP_PLL_312_Z0_2_SH 5 +#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH) +#define __APP_PLL_312_RSEL200500 0x00000010 +#define __APP_PLL_312_ENARST 0x00000008 +#define __APP_PLL_312_BYPASS 0x00000004 +#define __APP_PLL_312_LRESETN 0x00000002 +#define __APP_PLL_312_ENABLE 0x00000001 +#define MBIST_CTL_REG 0x00014220 +#define __EDRAM_BISTR_START 0x00000004 +#define __MBIST_RESET 0x00000002 +#define __MBIST_START 0x00000001 +#define MBIST_STAT_REG 0x00014224 +#define __EDRAM_BISTR_STATUS 0x00000008 +#define __EDRAM_BISTR_DONE 0x00000004 +#define __MEM_BIT_STATUS 0x00000002 +#define __MBIST_DONE 0x00000001 +#define HOST_SEM0_REG 0x00014230 +#define __HOST_SEMAPHORE 0x00000001 +#define HOST_SEM1_REG 0x00014234 +#define HOST_SEM2_REG 0x00014238 +#define HOST_SEM3_REG 0x0001423c +#define HOST_SEM0_INFO_REG 0x00014240 +#define HOST_SEM1_INFO_REG 0x00014244 +#define HOST_SEM2_INFO_REG 0x00014248 +#define HOST_SEM3_INFO_REG 0x0001424c +#define ETH_MAC_SER_REG 0x00014288 +#define __APP_EMS_CKBUFAMPIN 0x00000020 +#define __APP_EMS_REFCLKSEL 0x00000010 +#define __APP_EMS_CMLCKSEL 0x00000008 +#define __APP_EMS_REFCKBUFEN2 0x00000004 +#define __APP_EMS_REFCKBUFEN1 0x00000002 +#define __APP_EMS_CHANNEL_SEL 0x00000001 +#define HOSTFN2_INT_STATUS 0x00014300 +#define __HOSTFN2_HALT_OCCURRED 0x01000000 +#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN2_INT_STATUS_LVL_SH 20 +#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH) +#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN2_INT_STATUS_P_SH 16 +#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH) +#define __HOSTFN2_INT_STATUS_F 0x0000ffff +#define HOSTFN2_INT_MSK 0x00014304 +#define HOST_PAGE_NUM_FN2 0x00014308 +#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c +#define HOSTFN3_INT_STATUS 0x00014400 +#define __HALT_OCCURRED 0x01000000 +#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN3_INT_STATUS_LVL_SH 20 +#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH) +#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN3_INT_STATUS_P_SH 16 +#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH) +#define __HOSTFN3_INT_STATUS_F 0x0000ffff +#define HOSTFN3_INT_MSK 0x00014404 +#define HOST_PAGE_NUM_FN3 0x00014408 +#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c +#define FNC_ID_REG 0x00014600 +#define __FUNCTION_NUMBER 0x00000007 +#define FNC_PERS_REG 0x00014604 +#define __F3_FUNCTION_ACTIVE 0x80000000 +#define __F3_FUNCTION_MODE 0x40000000 +#define __F3_PORT_MAP_MK 0x30000000 +#define __F3_PORT_MAP_SH 28 +#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH) +#define __F3_VM_MODE 0x08000000 +#define __F3_INTX_STATUS_MK 0x07000000 +#define __F3_INTX_STATUS_SH 24 +#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH) +#define __F2_FUNCTION_ACTIVE 0x00800000 +#define __F2_FUNCTION_MODE 0x00400000 +#define __F2_PORT_MAP_MK 0x00300000 +#define __F2_PORT_MAP_SH 20 +#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH) +#define __F2_VM_MODE 0x00080000 +#define __F2_INTX_STATUS_MK 0x00070000 +#define __F2_INTX_STATUS_SH 16 +#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH) +#define __F1_FUNCTION_ACTIVE 0x00008000 +#define __F1_FUNCTION_MODE 0x00004000 +#define __F1_PORT_MAP_MK 0x00003000 +#define __F1_PORT_MAP_SH 12 +#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH) +#define __F1_VM_MODE 0x00000800 +#define __F1_INTX_STATUS_MK 0x00000700 +#define __F1_INTX_STATUS_SH 8 +#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH) +#define __F0_FUNCTION_ACTIVE 0x00000080 +#define __F0_FUNCTION_MODE 0x00000040 +#define __F0_PORT_MAP_MK 0x00000030 +#define __F0_PORT_MAP_SH 4 +#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH) +#define __F0_VM_MODE 0x00000008 +#define __F0_INTX_STATUS 0x00000007 +enum { + __F0_INTX_STATUS_MSIX = 0x0, + __F0_INTX_STATUS_INTA = 0x1, + __F0_INTX_STATUS_INTB = 0x2, + __F0_INTX_STATUS_INTC = 0x3, + __F0_INTX_STATUS_INTD = 0x4, +}; +#define OP_MODE 0x0001460c +#define __APP_ETH_CLK_LOWSPEED 0x00000004 +#define __GLOBAL_CORECLK_HALFSPEED 0x00000002 +#define __GLOBAL_FCOE_MODE 0x00000001 +#define HOST_SEM4_REG 0x00014610 +#define HOST_SEM5_REG 0x00014614 +#define HOST_SEM6_REG 0x00014618 +#define HOST_SEM7_REG 0x0001461c +#define HOST_SEM4_INFO_REG 0x00014620 +#define HOST_SEM5_INFO_REG 0x00014624 +#define HOST_SEM6_INFO_REG 0x00014628 +#define HOST_SEM7_INFO_REG 0x0001462c +#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000 +#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH) +#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004 +#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH) +#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008 +#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH) +#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c +#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH) +#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010 +#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH) +#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014 +#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH) +#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018 +#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH) +#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c +#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH) +#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150 +#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH) +#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154 +#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH) +#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158 +#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH) +#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c +#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH) +#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160 +#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH) +#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164 +#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH) +#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168 +#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH) +#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c +#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH) +#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 +#define FW_INIT_HALT_P0 0x000191ac +#define __FW_INIT_HALT_P 0x00000001 +#define FW_INIT_HALT_P1 0x000191bc +#define CPE_PI_PTR_Q0 0x00038000 +#define __CPE_PI_UNUSED_MK 0xffff0000 +#define __CPE_PI_UNUSED_SH 16 +#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH) +#define __CPE_PI_PTR 0x0000ffff +#define CPE_PI_PTR_Q1 0x00038040 +#define CPE_CI_PTR_Q0 0x00038004 +#define __CPE_CI_UNUSED_MK 0xffff0000 +#define __CPE_CI_UNUSED_SH 16 +#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH) +#define __CPE_CI_PTR 0x0000ffff +#define CPE_CI_PTR_Q1 0x00038044 +#define CPE_DEPTH_Q0 0x00038008 +#define __CPE_DEPTH_UNUSED_MK 0xf8000000 +#define __CPE_DEPTH_UNUSED_SH 27 +#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH) +#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000 +#define __CPE_MSIX_VEC_INDEX_SH 16 +#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH) +#define __CPE_DEPTH 0x0000ffff +#define CPE_DEPTH_Q1 0x00038048 +#define CPE_QCTRL_Q0 0x0003800c +#define __CPE_CTRL_UNUSED30_MK 0xfc000000 +#define __CPE_CTRL_UNUSED30_SH 26 +#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH) +#define __CPE_FUNC_INT_CTRL_MK 0x03000000 +#define __CPE_FUNC_INT_CTRL_SH 24 +#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH) +enum { + __CPE_FUNC_INT_CTRL_DISABLE = 0x0, + __CPE_FUNC_INT_CTRL_F2NF = 0x1, + __CPE_FUNC_INT_CTRL_3QUART = 0x2, + __CPE_FUNC_INT_CTRL_HALF = 0x3, +}; +#define __CPE_CTRL_UNUSED20_MK 0x00f00000 +#define __CPE_CTRL_UNUSED20_SH 20 +#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH) +#define __CPE_SCI_TH_MK 0x000f0000 +#define __CPE_SCI_TH_SH 16 +#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH) +#define __CPE_CTRL_UNUSED10_MK 0x0000c000 +#define __CPE_CTRL_UNUSED10_SH 14 +#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH) +#define __CPE_ACK_PENDING 0x00002000 +#define __CPE_CTRL_UNUSED40_MK 0x00001c00 +#define __CPE_CTRL_UNUSED40_SH 10 +#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH) +#define __CPE_PCIEID_MK 0x00000300 +#define __CPE_PCIEID_SH 8 +#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH) +#define __CPE_CTRL_UNUSED00_MK 0x000000fe +#define __CPE_CTRL_UNUSED00_SH 1 +#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH) +#define __CPE_ESIZE 0x00000001 +#define CPE_QCTRL_Q1 0x0003804c +#define __CPE_CTRL_UNUSED31_MK 0xfc000000 +#define __CPE_CTRL_UNUSED31_SH 26 +#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH) +#define __CPE_CTRL_UNUSED21_MK 0x00f00000 +#define __CPE_CTRL_UNUSED21_SH 20 +#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH) +#define __CPE_CTRL_UNUSED11_MK 0x0000c000 +#define __CPE_CTRL_UNUSED11_SH 14 +#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH) +#define __CPE_CTRL_UNUSED41_MK 0x00001c00 +#define __CPE_CTRL_UNUSED41_SH 10 +#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH) +#define __CPE_CTRL_UNUSED01_MK 0x000000fe +#define __CPE_CTRL_UNUSED01_SH 1 +#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH) +#define RME_PI_PTR_Q0 0x00038020 +#define __LATENCY_TIME_STAMP_MK 0xffff0000 +#define __LATENCY_TIME_STAMP_SH 16 +#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH) +#define __RME_PI_PTR 0x0000ffff +#define RME_PI_PTR_Q1 0x00038060 +#define RME_CI_PTR_Q0 0x00038024 +#define __DELAY_TIME_STAMP_MK 0xffff0000 +#define __DELAY_TIME_STAMP_SH 16 +#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH) +#define __RME_CI_PTR 0x0000ffff +#define RME_CI_PTR_Q1 0x00038064 +#define RME_DEPTH_Q0 0x00038028 +#define __RME_DEPTH_UNUSED_MK 0xf8000000 +#define __RME_DEPTH_UNUSED_SH 27 +#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH) +#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000 +#define __RME_MSIX_VEC_INDEX_SH 16 +#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH) +#define __RME_DEPTH 0x0000ffff +#define RME_DEPTH_Q1 0x00038068 +#define RME_QCTRL_Q0 0x0003802c +#define __RME_INT_LATENCY_TIMER_MK 0xff000000 +#define __RME_INT_LATENCY_TIMER_SH 24 +#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH) +#define __RME_INT_DELAY_TIMER_MK 0x00ff0000 +#define __RME_INT_DELAY_TIMER_SH 16 +#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH) +#define __RME_INT_DELAY_DISABLE 0x00008000 +#define __RME_DLY_DELAY_DISABLE 0x00004000 +#define __RME_ACK_PENDING 0x00002000 +#define __RME_FULL_INTERRUPT_DISABLE 0x00001000 +#define __RME_CTRL_UNUSED10_MK 0x00000c00 +#define __RME_CTRL_UNUSED10_SH 10 +#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH) +#define __RME_PCIEID_MK 0x00000300 +#define __RME_PCIEID_SH 8 +#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH) +#define __RME_CTRL_UNUSED00_MK 0x000000fe +#define __RME_CTRL_UNUSED00_SH 1 +#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH) +#define __RME_ESIZE 0x00000001 +#define RME_QCTRL_Q1 0x0003806c +#define __RME_CTRL_UNUSED11_MK 0x00000c00 +#define __RME_CTRL_UNUSED11_SH 10 +#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH) +#define __RME_CTRL_UNUSED01_MK 0x000000fe +#define __RME_CTRL_UNUSED01_SH 1 +#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH) +#define PSS_CTL_REG 0x00018800 +#define __PSS_I2C_CLK_DIV_MK 0x007f0000 +#define __PSS_I2C_CLK_DIV_SH 16 +#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH) +#define __PSS_LMEM_INIT_DONE 0x00001000 +#define __PSS_LMEM_RESET 0x00000200 +#define __PSS_LMEM_INIT_EN 0x00000100 +#define __PSS_LPU1_RESET 0x00000002 +#define __PSS_LPU0_RESET 0x00000001 +#define PSS_ERR_STATUS_REG 0x00018810 +#define __PSS_LPU1_TCM_READ_ERR 0x00200000 +#define __PSS_LPU0_TCM_READ_ERR 0x00100000 +#define __PSS_LMEM5_CORR_ERR 0x00080000 +#define __PSS_LMEM4_CORR_ERR 0x00040000 +#define __PSS_LMEM3_CORR_ERR 0x00020000 +#define __PSS_LMEM2_CORR_ERR 0x00010000 +#define __PSS_LMEM1_CORR_ERR 0x00008000 +#define __PSS_LMEM0_CORR_ERR 0x00004000 +#define __PSS_LMEM5_UNCORR_ERR 0x00002000 +#define __PSS_LMEM4_UNCORR_ERR 0x00001000 +#define __PSS_LMEM3_UNCORR_ERR 0x00000800 +#define __PSS_LMEM2_UNCORR_ERR 0x00000400 +#define __PSS_LMEM1_UNCORR_ERR 0x00000200 +#define __PSS_LMEM0_UNCORR_ERR 0x00000100 +#define __PSS_BAL_PERR 0x00000080 +#define __PSS_DIP_IF_ERR 0x00000040 +#define __PSS_IOH_IF_ERR 0x00000020 +#define __PSS_TDS_IF_ERR 0x00000010 +#define __PSS_RDS_IF_ERR 0x00000008 +#define __PSS_SGM_IF_ERR 0x00000004 +#define __PSS_LPU1_RAM_ERR 0x00000002 +#define __PSS_LPU0_RAM_ERR 0x00000001 +#define ERR_SET_REG 0x00018818 +#define __PSS_ERR_STATUS_SET 0x003fffff +#define PMM_1T_RESET_REG_P0 0x0002381c +#define __PMM_1T_RESET_P 0x00000001 +#define PMM_1T_RESET_REG_P1 0x00023c1c +#define HQM_QSET0_RXQ_DRBL_P0 0x00038000 +#define __RXQ0_ADD_VECTORS_P 0x80000000 +#define __RXQ0_STOP_P 0x40000000 +#define __RXQ0_PRD_PTR_P 0x0000ffff +#define HQM_QSET1_RXQ_DRBL_P0 0x00038080 +#define __RXQ1_ADD_VECTORS_P 0x80000000 +#define __RXQ1_STOP_P 0x40000000 +#define __RXQ1_PRD_PTR_P 0x0000ffff +#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000 +#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080 +#define HQM_QSET0_TXQ_DRBL_P0 0x00038020 +#define __TXQ0_ADD_VECTORS_P 0x80000000 +#define __TXQ0_STOP_P 0x40000000 +#define __TXQ0_PRD_PTR_P 0x0000ffff +#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0 +#define __TXQ1_ADD_VECTORS_P 0x80000000 +#define __TXQ1_STOP_P 0x40000000 +#define __TXQ1_PRD_PTR_P 0x0000ffff +#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020 +#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0 +#define HQM_QSET0_IB_DRBL_1_P0 0x00038040 +#define __IB1_0_ACK_P 0x80000000 +#define __IB1_0_DISABLE_P 0x40000000 +#define __IB1_0_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB1_0_COALESCING_CFG_P_SH 16 +#define __IB1_0_COALESCING_CFG_P(_v) ((_v) << __IB1_0_COALESCING_CFG_P_SH) +#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0 +#define __IB1_1_ACK_P 0x80000000 +#define __IB1_1_DISABLE_P 0x40000000 +#define __IB1_1_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB1_1_COALESCING_CFG_P_SH 16 +#define __IB1_1_COALESCING_CFG_P(_v) ((_v) << __IB1_1_COALESCING_CFG_P_SH) +#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040 +#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0 +#define HQM_QSET0_IB_DRBL_2_P0 0x00038060 +#define __IB2_0_ACK_P 0x80000000 +#define __IB2_0_DISABLE_P 0x40000000 +#define __IB2_0_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB2_0_COALESCING_CFG_P_SH 16 +#define __IB2_0_COALESCING_CFG_P(_v) ((_v) << __IB2_0_COALESCING_CFG_P_SH) +#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0 +#define __IB2_1_ACK_P 0x80000000 +#define __IB2_1_DISABLE_P 0x40000000 +#define __IB2_1_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB2_1_COALESCING_CFG_P_SH 16 +#define __IB2_1_COALESCING_CFG_P(_v) ((_v) << __IB2_1_COALESCING_CFG_P_SH) +#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060 +#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0 + +/* + * These definitions are either in error/missing in spec. Its auto-generated + * from hard coded values in regparse.pl. + */ +#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c +#define __EMPHPOST_AT_4G_SH_FIX 0x00000002 +#define __EMPHPRE_AT_4G_FIX 0x00000003 +#define __SFP_TXRATE_EN_FIX 0x00000100 +#define __SFP_RXRATE_EN_FIX 0x00000080 + +/* + * These register definitions are auto-generated from hard coded values + * in regparse.pl. + */ + +/* + * These register mapping definitions are auto-generated from mapping tables + * in regparse.pl. + */ +#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG +#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG +#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG +#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG +#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG + +#define CPE_DEPTH_Q(__n) \ + (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0)) +#define CPE_QCTRL_Q(__n) \ + (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0)) +#define CPE_PI_PTR_Q(__n) \ + (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0)) +#define CPE_CI_PTR_Q(__n) \ + (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0)) +#define RME_DEPTH_Q(__n) \ + (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0)) +#define RME_QCTRL_Q(__n) \ + (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0)) +#define RME_PI_PTR_Q(__n) \ + (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0)) +#define RME_CI_PTR_Q(__n) \ + (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0)) +#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \ + * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0)) +#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \ + * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0)) +#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \ + * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0)) +#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \ + * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0)) +#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \ + * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1)) +#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \ + * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1)) +#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \ + * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1)) +#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \ + * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1)) + +#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) +#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) +#define CPE_Q_MASK(__q) ((__q) & 0x3) +#define RME_Q_MASK(__q) ((__q) & 0x3) + +/* + * PCI MSI-X vector defines + */ +enum { + BFA_MSIX_CPE_Q0 = 0, + BFA_MSIX_CPE_Q1 = 1, + BFA_MSIX_CPE_Q2 = 2, + BFA_MSIX_CPE_Q3 = 3, + BFA_MSIX_RME_Q0 = 4, + BFA_MSIX_RME_Q1 = 5, + BFA_MSIX_RME_Q2 = 6, + BFA_MSIX_RME_Q3 = 7, + BFA_MSIX_LPU_ERR = 8, + BFA_MSIX_CT_MAX = 9, +}; + +/* + * And corresponding host interrupt status bit field defines + */ +#define __HFN_INT_CPE_Q0 0x00000001U +#define __HFN_INT_CPE_Q1 0x00000002U +#define __HFN_INT_CPE_Q2 0x00000004U +#define __HFN_INT_CPE_Q3 0x00000008U +#define __HFN_INT_CPE_Q4 0x00000010U +#define __HFN_INT_CPE_Q5 0x00000020U +#define __HFN_INT_CPE_Q6 0x00000040U +#define __HFN_INT_CPE_Q7 0x00000080U +#define __HFN_INT_RME_Q0 0x00000100U +#define __HFN_INT_RME_Q1 0x00000200U +#define __HFN_INT_RME_Q2 0x00000400U +#define __HFN_INT_RME_Q3 0x00000800U +#define __HFN_INT_RME_Q4 0x00001000U +#define __HFN_INT_RME_Q5 0x00002000U +#define __HFN_INT_RME_Q6 0x00004000U +#define __HFN_INT_RME_Q7 0x00008000U +#define __HFN_INT_ERR_EMC 0x00010000U +#define __HFN_INT_ERR_LPU0 0x00020000U +#define __HFN_INT_ERR_LPU1 0x00040000U +#define __HFN_INT_ERR_PSS 0x00080000U +#define __HFN_INT_MBOX_LPU0 0x00100000U +#define __HFN_INT_MBOX_LPU1 0x00200000U +#define __HFN_INT_MBOX1_LPU0 0x00400000U +#define __HFN_INT_MBOX1_LPU1 0x00800000U +#define __HFN_INT_LL_HALT 0x01000000U +#define __HFN_INT_CPE_MASK 0x000000ffU +#define __HFN_INT_RME_MASK 0x0000ff00U + +/* + * catapult memory map. + */ +#define LL_PGN_HQM0 0x0096 +#define LL_PGN_HQM1 0x0097 +#define PSS_SMEM_PAGE_START 0x8000 +#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15)) +#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff) + +/* + * End of catapult memory map + */ + +#endif /* __BFI_CTREG_H__ */ diff --git a/drivers/net/bna/bfi_ll.h b/drivers/net/bna/bfi_ll.h new file mode 100644 index 000000000000..bee4d054066a --- /dev/null +++ b/drivers/net/bna/bfi_ll.h @@ -0,0 +1,438 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFI_LL_H__ +#define __BFI_LL_H__ + +#include "bfi.h" + +#pragma pack(1) + +/** + * @brief + * "enums" for all LL mailbox messages other than IOC + */ +enum { + BFI_LL_H2I_MAC_UCAST_SET_REQ = 1, + BFI_LL_H2I_MAC_UCAST_ADD_REQ = 2, + BFI_LL_H2I_MAC_UCAST_DEL_REQ = 3, + + BFI_LL_H2I_MAC_MCAST_ADD_REQ = 4, + BFI_LL_H2I_MAC_MCAST_DEL_REQ = 5, + BFI_LL_H2I_MAC_MCAST_FILTER_REQ = 6, + BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ = 7, + + BFI_LL_H2I_PORT_ADMIN_REQ = 8, + BFI_LL_H2I_STATS_GET_REQ = 9, + BFI_LL_H2I_STATS_CLEAR_REQ = 10, + + BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ = 11, + BFI_LL_H2I_RXF_DEFAULT_SET_REQ = 12, + + BFI_LL_H2I_TXQ_STOP_REQ = 13, + BFI_LL_H2I_RXQ_STOP_REQ = 14, + + BFI_LL_H2I_DIAG_LOOPBACK_REQ = 15, + + BFI_LL_H2I_SET_PAUSE_REQ = 16, + BFI_LL_H2I_MTU_INFO_REQ = 17, + + BFI_LL_H2I_RX_REQ = 18, +} ; + +enum { + BFI_LL_I2H_MAC_UCAST_SET_RSP = BFA_I2HM(1), + BFI_LL_I2H_MAC_UCAST_ADD_RSP = BFA_I2HM(2), + BFI_LL_I2H_MAC_UCAST_DEL_RSP = BFA_I2HM(3), + + BFI_LL_I2H_MAC_MCAST_ADD_RSP = BFA_I2HM(4), + BFI_LL_I2H_MAC_MCAST_DEL_RSP = BFA_I2HM(5), + BFI_LL_I2H_MAC_MCAST_FILTER_RSP = BFA_I2HM(6), + BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP = BFA_I2HM(7), + + BFI_LL_I2H_PORT_ADMIN_RSP = BFA_I2HM(8), + BFI_LL_I2H_STATS_GET_RSP = BFA_I2HM(9), + BFI_LL_I2H_STATS_CLEAR_RSP = BFA_I2HM(10), + + BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP = BFA_I2HM(11), + BFI_LL_I2H_RXF_DEFAULT_SET_RSP = BFA_I2HM(12), + + BFI_LL_I2H_TXQ_STOP_RSP = BFA_I2HM(13), + BFI_LL_I2H_RXQ_STOP_RSP = BFA_I2HM(14), + + BFI_LL_I2H_DIAG_LOOPBACK_RSP = BFA_I2HM(15), + + BFI_LL_I2H_SET_PAUSE_RSP = BFA_I2HM(16), + + BFI_LL_I2H_MTU_INFO_RSP = BFA_I2HM(17), + BFI_LL_I2H_RX_RSP = BFA_I2HM(18), + + BFI_LL_I2H_LINK_DOWN_AEN = BFA_I2HM(19), + BFI_LL_I2H_LINK_UP_AEN = BFA_I2HM(20), + + BFI_LL_I2H_PORT_ENABLE_AEN = BFA_I2HM(21), + BFI_LL_I2H_PORT_DISABLE_AEN = BFA_I2HM(22), +} ; + +/** + * @brief bfi_ll_mac_addr_req is used by: + * BFI_LL_H2I_MAC_UCAST_SET_REQ + * BFI_LL_H2I_MAC_UCAST_ADD_REQ + * BFI_LL_H2I_MAC_UCAST_DEL_REQ + * BFI_LL_H2I_MAC_MCAST_ADD_REQ + * BFI_LL_H2I_MAC_MCAST_DEL_REQ + */ +struct bfi_ll_mac_addr_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 rsvd1[3]; + mac_t mac_addr; + u8 rsvd2[2]; +}; + +/** + * @brief bfi_ll_mcast_filter_req is used by: + * BFI_LL_H2I_MAC_MCAST_FILTER_REQ + */ +struct bfi_ll_mcast_filter_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 enable; + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_mcast_del_all is used by: + * BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ + */ +struct bfi_ll_mcast_del_all_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_q_stop_req is used by: + * BFI_LL_H2I_TXQ_STOP_REQ + * BFI_LL_H2I_RXQ_STOP_REQ + */ +struct bfi_ll_q_stop_req { + struct bfi_mhdr mh; /*!< common msg header */ + u32 q_id_mask[2]; /* !< bit-mask for queue ids */ +}; + +/** + * @brief bfi_ll_stats_req is used by: + * BFI_LL_I2H_STATS_GET_REQ + * BFI_LL_I2H_STATS_CLEAR_REQ + */ +struct bfi_ll_stats_req { + struct bfi_mhdr mh; /*!< common msg header */ + u16 stats_mask; /* !< bit-mask for non-function statistics */ + u8 rsvd[2]; + u32 rxf_id_mask[2]; /* !< bit-mask for RxF Statistics */ + u32 txf_id_mask[2]; /* !< bit-mask for TxF Statistics */ + union bfi_addr_u host_buffer; /* !< where statistics are returned */ +}; + +/** + * @brief defines for "stats_mask" above. + */ +#define BFI_LL_STATS_MAC (1 << 0) /* !< MAC Statistics */ +#define BFI_LL_STATS_BPC (1 << 1) /* !< Pause Stats from BPC */ +#define BFI_LL_STATS_RAD (1 << 2) /* !< Rx Admission Statistics */ +#define BFI_LL_STATS_RX_FC (1 << 3) /* !< Rx FC Stats from RxA */ +#define BFI_LL_STATS_TX_FC (1 << 4) /* !< Tx FC Stats from TxA */ + +#define BFI_LL_STATS_ALL 0x1f + +/** + * @brief bfi_ll_port_admin_req + */ +struct bfi_ll_port_admin_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 up; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_rxf_req is used by: + * BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ + * BFI_LL_H2I_RXF_DEFAULT_SET_REQ + */ +struct bfi_ll_rxf_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 enable; + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_rxf_multi_req is used by: + * BFI_LL_H2I_RX_REQ + */ +struct bfi_ll_rxf_multi_req { + struct bfi_mhdr mh; /*!< common msg header */ + u32 rxf_id_mask[2]; + u8 enable; + u8 rsvd[3]; +}; + +/** + * @brief enum for Loopback opmodes + */ +enum { + BFI_LL_DIAG_LB_OPMODE_EXT = 0, + BFI_LL_DIAG_LB_OPMODE_CBL = 1, +}; + +/** + * @brief bfi_ll_set_pause_req is used by: + * BFI_LL_H2I_SET_PAUSE_REQ + */ +struct bfi_ll_set_pause_req { + struct bfi_mhdr mh; + u8 tx_pause; /* 1 = enable, 0 = disable */ + u8 rx_pause; /* 1 = enable, 0 = disable */ + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_mtu_info_req is used by: + * BFI_LL_H2I_MTU_INFO_REQ + */ +struct bfi_ll_mtu_info_req { + struct bfi_mhdr mh; + u16 mtu; + u8 rsvd[2]; +}; + +/** + * @brief + * Response header format used by all responses + * For both responses and asynchronous notifications + */ +struct bfi_ll_rsp { + struct bfi_mhdr mh; /*!< common msg header */ + u8 error; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_cee_aen is used by: + * BFI_LL_I2H_LINK_DOWN_AEN + * BFI_LL_I2H_LINK_UP_AEN + */ +struct bfi_ll_aen { + struct bfi_mhdr mh; /*!< common msg header */ + u32 reason; + u8 cee_linkup; + u8 prio_map; /*!< LL priority bit-map */ + u8 rsvd[2]; +}; + +/** + * @brief + * The following error codes can be returned + * by the mbox commands + */ +enum { + BFI_LL_CMD_OK = 0, + BFI_LL_CMD_FAIL = 1, + BFI_LL_CMD_DUP_ENTRY = 2, /* !< Duplicate entry in CAM */ + BFI_LL_CMD_CAM_FULL = 3, /* !< CAM is full */ + BFI_LL_CMD_NOT_OWNER = 4, /* !< Not permitted, b'cos not owner */ + BFI_LL_CMD_NOT_EXEC = 5, /* !< Was not sent to f/w at all */ + BFI_LL_CMD_WAITING = 6, /* !< Waiting for completion (VMware) */ + BFI_LL_CMD_PORT_DISABLED = 7, /* !< port in disabled state */ +} ; + +/* Statistics */ +#define BFI_LL_TXF_ID_MAX 64 +#define BFI_LL_RXF_ID_MAX 64 + +/* TxF Frame Statistics */ +struct bfi_ll_stats_txf { + u64 ucast_octets; + u64 ucast; + u64 ucast_vlan; + + u64 mcast_octets; + u64 mcast; + u64 mcast_vlan; + + u64 bcast_octets; + u64 bcast; + u64 bcast_vlan; + + u64 errors; + u64 filter_vlan; /* frames filtered due to VLAN */ + u64 filter_mac_sa; /* frames filtered due to SA check */ +}; + +/* RxF Frame Statistics */ +struct bfi_ll_stats_rxf { + u64 ucast_octets; + u64 ucast; + u64 ucast_vlan; + + u64 mcast_octets; + u64 mcast; + u64 mcast_vlan; + + u64 bcast_octets; + u64 bcast; + u64 bcast_vlan; + u64 frame_drops; +}; + +/* FC Tx Frame Statistics */ +struct bfi_ll_stats_fc_tx { + u64 txf_ucast_octets; + u64 txf_ucast; + u64 txf_ucast_vlan; + + u64 txf_mcast_octets; + u64 txf_mcast; + u64 txf_mcast_vlan; + + u64 txf_bcast_octets; + u64 txf_bcast; + u64 txf_bcast_vlan; + + u64 txf_parity_errors; + u64 txf_timeout; + u64 txf_fid_parity_errors; +}; + +/* FC Rx Frame Statistics */ +struct bfi_ll_stats_fc_rx { + u64 rxf_ucast_octets; + u64 rxf_ucast; + u64 rxf_ucast_vlan; + + u64 rxf_mcast_octets; + u64 rxf_mcast; + u64 rxf_mcast_vlan; + + u64 rxf_bcast_octets; + u64 rxf_bcast; + u64 rxf_bcast_vlan; +}; + +/* RAD Frame Statistics */ +struct bfi_ll_stats_rad { + u64 rx_frames; + u64 rx_octets; + u64 rx_vlan_frames; + + u64 rx_ucast; + u64 rx_ucast_octets; + u64 rx_ucast_vlan; + + u64 rx_mcast; + u64 rx_mcast_octets; + u64 rx_mcast_vlan; + + u64 rx_bcast; + u64 rx_bcast_octets; + u64 rx_bcast_vlan; + + u64 rx_drops; +}; + +/* BPC Tx Registers */ +struct bfi_ll_stats_bpc { + /* transmit stats */ + u64 tx_pause[8]; + u64 tx_zero_pause[8]; /*!< Pause cancellation */ + /*!timer_mod)) + +/* MBOX API for PORT, TX, RX */ +#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \ +do { \ + memcpy(&((_qe)->cmd.msg[0]), (_cmd), (_cmd_len)); \ + (_qe)->cbfn = (_cbfn); \ + (_qe)->cbarg = (_cbarg); \ +} while (0) + +#define bna_is_small_rxq(rcb) ((rcb)->id == 1) + +#define BNA_MAC_IS_EQUAL(_mac1, _mac2) \ + (!memcmp((_mac1), (_mac2), sizeof(mac_t))) + +#define BNA_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) + +#define BNA_TO_POWER_OF_2(x) \ +do { \ + int _shift = 0; \ + while ((x) && (x) != 1) { \ + (x) >>= 1; \ + _shift++; \ + } \ + (x) <<= _shift; \ +} while (0) + +#define BNA_TO_POWER_OF_2_HIGH(x) \ +do { \ + int n = 1; \ + while (n < (x)) \ + n <<= 1; \ + (x) = n; \ +} while (0) + +/* + * input : _addr-> os dma addr in host endian format, + * output : _bna_dma_addr-> pointer to hw dma addr + */ +#define BNA_SET_DMA_ADDR(_addr, _bna_dma_addr) \ +do { \ + u64 tmp_addr = \ + cpu_to_be64((u64)(_addr)); \ + (_bna_dma_addr)->msb = ((struct bna_dma_addr *)&tmp_addr)->msb; \ + (_bna_dma_addr)->lsb = ((struct bna_dma_addr *)&tmp_addr)->lsb; \ +} while (0) + +/* + * input : _bna_dma_addr-> pointer to hw dma addr + * output : _addr-> os dma addr in host endian format + */ +#define BNA_GET_DMA_ADDR(_bna_dma_addr, _addr) \ +do { \ + (_addr) = ((((u64)ntohl((_bna_dma_addr)->msb))) << 32) \ + | ((ntohl((_bna_dma_addr)->lsb) & 0xffffffff)); \ +} while (0) + +#define containing_rec(addr, type, field) \ + ((type *)((unsigned char *)(addr) - \ + (unsigned char *)(&((type *)0)->field))) + +#define BNA_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2) + +/* TxQ element is 64 bytes */ +#define BNA_TXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 6) +#define BNA_TXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 6) + +#define BNA_TXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> BNA_TXQ_PAGE_INDEX_MAX_SHIFT)];\ + (_qe_ptr) = &((struct bna_txq_entry *)(page_addr))[page_index]; \ +} + +/* RxQ element is 8 bytes */ +#define BNA_RXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 3) +#define BNA_RXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 3) + +#define BNA_RXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + page_index = (_qe_idx) & (BNA_RXQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_RXQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> \ + BNA_RXQ_PAGE_INDEX_MAX_SHIFT)]; \ + (_qe_ptr) = &((struct bna_rxq_entry *)(page_addr))[page_index]; \ +} + +/* CQ element is 16 bytes */ +#define BNA_CQ_PAGE_INDEX_MAX (PAGE_SIZE >> 4) +#define BNA_CQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 4) + +#define BNA_CQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + \ + page_index = (_qe_idx) & (BNA_CQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_CQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> \ + BNA_CQ_PAGE_INDEX_MAX_SHIFT)]; \ + (_qe_ptr) = &((struct bna_cq_entry *)(page_addr))[page_index];\ +} + +#define BNA_QE_INDX_2_PTR(_cast, _qe_idx, _q_base) \ + (&((_cast *)(_q_base))[(_qe_idx)]) + +#define BNA_QE_INDX_RANGE(_qe_idx, _q_depth) ((_q_depth) - (_qe_idx)) + +#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \ + ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1)) + +#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \ + (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1)) + +#define BNA_QE_FREE_CNT(_q_ptr, _q_depth) \ + (((_q_ptr)->consumer_index - (_q_ptr)->producer_index - 1) & \ + ((_q_depth) - 1)) + +#define BNA_QE_IN_USE_CNT(_q_ptr, _q_depth) \ + ((((_q_ptr)->producer_index - (_q_ptr)->consumer_index)) & \ + (_q_depth - 1)) + +#define BNA_Q_GET_CI(_q_ptr) ((_q_ptr)->q.consumer_index) + +#define BNA_Q_GET_PI(_q_ptr) ((_q_ptr)->q.producer_index) + +#define BNA_Q_PI_ADD(_q_ptr, _num) \ + (_q_ptr)->q.producer_index = \ + (((_q_ptr)->q.producer_index + (_num)) & \ + ((_q_ptr)->q.q_depth - 1)) + +#define BNA_Q_CI_ADD(_q_ptr, _num) \ + (_q_ptr)->q.consumer_index = \ + (((_q_ptr)->q.consumer_index + (_num)) \ + & ((_q_ptr)->q.q_depth - 1)) + +#define BNA_Q_FREE_COUNT(_q_ptr) \ + (BNA_QE_FREE_CNT(&((_q_ptr)->q), (_q_ptr)->q.q_depth)) + +#define BNA_Q_IN_USE_COUNT(_q_ptr) \ + (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth)) + +/* These macros build the data portion of the TxQ/RxQ doorbell */ +#define BNA_DOORBELL_Q_PRD_IDX(_pi) (0x80000000 | (_pi)) +#define BNA_DOORBELL_Q_STOP (0x40000000) + +/* These macros build the data portion of the IB doorbell */ +#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \ + (0x80000000 | ((_timeout) << 16) | (_events)) +#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000) + +/* Set the coalescing timer for the given ib */ +#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer) \ + ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0)); + +/* Acks 'events' # of events for a given ib */ +#define bna_ib_ack(_i_dbell, _events) \ + (writel(((_i_dbell)->doorbell_ack | (_events)), \ + (_i_dbell)->doorbell_addr)); + +#define bna_txq_prod_indx_doorbell(_tcb) \ + (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \ + (_tcb)->q_dbell)); + +#define bna_rxq_prod_indx_doorbell(_rcb) \ + (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \ + (_rcb)->q_dbell)); + +#define BNA_LARGE_PKT_SIZE 1000 + +#define BNA_UPDATE_PKT_CNT(_pkt, _len) \ +do { \ + if ((_len) > BNA_LARGE_PKT_SIZE) { \ + (_pkt)->large_pkt_cnt++; \ + } else { \ + (_pkt)->small_pkt_cnt++; \ + } \ +} while (0) + +#define call_rxf_stop_cbfn(rxf, status) \ + if ((rxf)->stop_cbfn) { \ + (*(rxf)->stop_cbfn)((rxf)->stop_cbarg, (status)); \ + (rxf)->stop_cbfn = NULL; \ + (rxf)->stop_cbarg = NULL; \ + } + +#define call_rxf_start_cbfn(rxf, status) \ + if ((rxf)->start_cbfn) { \ + (*(rxf)->start_cbfn)((rxf)->start_cbarg, (status)); \ + (rxf)->start_cbfn = NULL; \ + (rxf)->start_cbarg = NULL; \ + } + +#define call_rxf_cam_fltr_cbfn(rxf, status) \ + if ((rxf)->cam_fltr_cbfn) { \ + (*(rxf)->cam_fltr_cbfn)((rxf)->cam_fltr_cbarg, rxf->rx, \ + (status)); \ + (rxf)->cam_fltr_cbfn = NULL; \ + (rxf)->cam_fltr_cbarg = NULL; \ + } + +#define call_rxf_pause_cbfn(rxf, status) \ + if ((rxf)->oper_state_cbfn) { \ + (*(rxf)->oper_state_cbfn)((rxf)->oper_state_cbarg, rxf->rx,\ + (status)); \ + (rxf)->rxf_flags &= ~BNA_RXF_FL_OPERSTATE_CHANGED; \ + (rxf)->oper_state_cbfn = NULL; \ + (rxf)->oper_state_cbarg = NULL; \ + } + +#define call_rxf_resume_cbfn(rxf, status) call_rxf_pause_cbfn(rxf, status) + +#define is_xxx_enable(mode, bitmask, xxx) ((bitmask & xxx) && (mode & xxx)) + +#define is_xxx_disable(mode, bitmask, xxx) ((bitmask & xxx) && !(mode & xxx)) + +#define xxx_enable(mode, bitmask, xxx) \ +do { \ + bitmask |= xxx; \ + mode |= xxx; \ +} while (0) + +#define xxx_disable(mode, bitmask, xxx) \ +do { \ + bitmask |= xxx; \ + mode &= ~xxx; \ +} while (0) + +#define xxx_inactive(mode, bitmask, xxx) \ +do { \ + bitmask &= ~xxx; \ + mode &= ~xxx; \ +} while (0) + +#define is_promisc_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define is_promisc_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_PROMISC) + +#define is_default_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define is_default_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define is_allmulti_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define is_allmulti_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define GET_RXQS(rxp, q0, q1) do { \ + switch ((rxp)->type) { \ + case BNA_RXP_SINGLE: \ + (q0) = rxp->rxq.single.only; \ + (q1) = NULL; \ + break; \ + case BNA_RXP_SLR: \ + (q0) = rxp->rxq.slr.large; \ + (q1) = rxp->rxq.slr.small; \ + break; \ + case BNA_RXP_HDS: \ + (q0) = rxp->rxq.hds.data; \ + (q1) = rxp->rxq.hds.hdr; \ + break; \ + } \ +} while (0) + +/** + * + * Function prototypes + * + */ + +/** + * BNA + */ + +/* Internal APIs */ +void bna_adv_res_req(struct bna_res_info *res_info); + +/* APIs for BNAD */ +void bna_res_req(struct bna_res_info *res_info); +void bna_init(struct bna *bna, struct bnad *bnad, + struct bfa_pcidev *pcidev, + struct bna_res_info *res_info); +void bna_uninit(struct bna *bna); +void bna_stats_get(struct bna *bna); +void bna_stats_clr(struct bna *bna); +void bna_get_perm_mac(struct bna *bna, u8 *mac); + +/* APIs for Rx */ +int bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size); + +/* APIs for RxF */ +struct bna_mac *bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod); +void bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, + struct bna_mac *mac); +struct bna_mac *bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod); +void bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, + struct bna_mac *mac); +struct bna_rit_segment * +bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size); +void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod, + struct bna_rit_segment *seg); + +/** + * DEVICE + */ + +/* Interanl APIs */ +void bna_adv_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info); + +/* APIs for BNA */ +void bna_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info); +void bna_device_uninit(struct bna_device *device); +void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status); +int bna_device_status_get(struct bna_device *device); +int bna_device_state_get(struct bna_device *device); + +/* APIs for BNAD */ +void bna_device_enable(struct bna_device *device); +void bna_device_disable(struct bna_device *device, + enum bna_cleanup_type type); + +/** + * MBOX + */ + +/* APIs for DEVICE */ +void bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna); +void bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod); +void bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod); +void bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod); + +/* APIs for PORT, TX, RX */ +void bna_mbox_handler(struct bna *bna, u32 intr_status); +void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe); + +/** + * PORT + */ + +/* APIs for BNA */ +void bna_port_init(struct bna_port *port, struct bna *bna); +void bna_port_uninit(struct bna_port *port); +int bna_port_state_get(struct bna_port *port); +int bna_llport_state_get(struct bna_llport *llport); + +/* APIs for DEVICE */ +void bna_port_start(struct bna_port *port); +void bna_port_stop(struct bna_port *port); +void bna_port_fail(struct bna_port *port); + +/* API for RX */ +int bna_port_mtu_get(struct bna_port *port); +void bna_llport_admin_up(struct bna_llport *llport); +void bna_llport_admin_down(struct bna_llport *llport); + +/* API for BNAD */ +void bna_port_enable(struct bna_port *port); +void bna_port_disable(struct bna_port *port, enum bna_cleanup_type type, + void (*cbfn)(void *, enum bna_cb_status)); +void bna_port_pause_config(struct bna_port *port, + struct bna_pause_config *pause_config, + void (*cbfn)(struct bnad *, enum bna_cb_status)); +void bna_port_mtu_set(struct bna_port *port, int mtu, + void (*cbfn)(struct bnad *, enum bna_cb_status)); +void bna_port_mac_get(struct bna_port *port, mac_t *mac); +void bna_port_type_set(struct bna_port *port, enum bna_port_type type); +void bna_port_linkcbfn_set(struct bna_port *port, + void (*linkcbfn)(struct bnad *, + enum bna_link_status)); +void bna_port_admin_up(struct bna_port *port); +void bna_port_admin_down(struct bna_port *port); + +/* Callbacks for TX, RX */ +void bna_port_cb_tx_stopped(struct bna_port *port, + enum bna_cb_status status); +void bna_port_cb_rx_stopped(struct bna_port *port, + enum bna_cb_status status); + +/* Callbacks for MBOX */ +void bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, + int status); +void bna_port_cb_link_down(struct bna_port *port, int status); + +/** + * IB + */ + +/* APIs for BNA */ +void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod); + +/* APIs for TX, RX */ +struct bna_ib *bna_ib_get(struct bna_ib_mod *ib_mod, + enum bna_intr_type intr_type, int vector); +void bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib); +int bna_ib_reserve_idx(struct bna_ib *ib); +void bna_ib_release_idx(struct bna_ib *ib, int idx); +int bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config); +void bna_ib_start(struct bna_ib *ib); +void bna_ib_stop(struct bna_ib *ib); +void bna_ib_fail(struct bna_ib *ib); +void bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo); + +/** + * TX MODULE AND TX + */ + +/* Internal APIs */ +void bna_tx_prio_changed(struct bna_tx *tx, int prio); + +/* APIs for BNA */ +void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_tx_mod_uninit(struct bna_tx_mod *tx_mod); +int bna_tx_state_get(struct bna_tx *tx); + +/* APIs for PORT */ +void bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type); +void bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type); +void bna_tx_mod_fail(struct bna_tx_mod *tx_mod); +void bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio); +void bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link); + +/* APIs for BNAD */ +void bna_tx_res_req(int num_txq, int txq_depth, + struct bna_res_info *res_info); +struct bna_tx *bna_tx_create(struct bna *bna, struct bnad *bnad, + struct bna_tx_config *tx_cfg, + struct bna_tx_event_cbfn *tx_cbfn, + struct bna_res_info *res_info, void *priv); +void bna_tx_destroy(struct bna_tx *tx); +void bna_tx_enable(struct bna_tx *tx); +void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_tx *, + enum bna_cb_status)); +enum bna_cb_status +bna_tx_prio_set(struct bna_tx *tx, int prio, + void (*cbfn)(struct bnad *, struct bna_tx *, + enum bna_cb_status)); +void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo); + +/** + * RX MODULE, RX, RXF + */ + +/* Internal APIs */ +void rxf_cb_cam_fltr_mbox_cmd(void *arg, int status); +void rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd, + const struct bna_mac *mac_addr); +void __rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status); +void bna_rxf_adv_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config); +int rxf_process_packet_filter_ucast(struct bna_rxf *rxf); +int rxf_process_packet_filter_promisc(struct bna_rxf *rxf); +int rxf_process_packet_filter_default(struct bna_rxf *rxf); +int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf); +int rxf_clear_packet_filter_ucast(struct bna_rxf *rxf); +int rxf_clear_packet_filter_promisc(struct bna_rxf *rxf); +int rxf_clear_packet_filter_default(struct bna_rxf *rxf); +int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf); +void rxf_reset_packet_filter_ucast(struct bna_rxf *rxf); +void rxf_reset_packet_filter_promisc(struct bna_rxf *rxf); +void rxf_reset_packet_filter_default(struct bna_rxf *rxf); +void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf); + +/* APIs for BNA */ +void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_rx_mod_uninit(struct bna_rx_mod *rx_mod); +int bna_rx_state_get(struct bna_rx *rx); +int bna_rxf_state_get(struct bna_rxf *rxf); + +/* APIs for PORT */ +void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type); +void bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type); +void bna_rx_mod_fail(struct bna_rx_mod *rx_mod); + +/* APIs for BNAD */ +void bna_rx_res_req(struct bna_rx_config *rx_config, + struct bna_res_info *res_info); +struct bna_rx *bna_rx_create(struct bna *bna, struct bnad *bnad, + struct bna_rx_config *rx_cfg, + struct bna_rx_event_cbfn *rx_cbfn, + struct bna_res_info *res_info, void *priv); +void bna_rx_destroy(struct bna_rx *rx); +void bna_rx_enable(struct bna_rx *rx); +void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo); +void bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX]); +void bna_rx_dim_update(struct bna_ccb *ccb); +enum bna_cb_status +bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_ucast_add(struct bna_rx *rx, u8* ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_ucast_del(struct bna_rx *rx, u8 *ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mcast_del(struct bna_rx *rx, u8 *mcmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_mcast_delall(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode, + enum bna_rxmode bitmask, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id); +void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id); +void bna_rx_vlanfilter_enable(struct bna_rx *rx); +void bna_rx_vlanfilter_disable(struct bna_rx *rx); +void bna_rx_rss_enable(struct bna_rx *rx); +void bna_rx_rss_disable(struct bna_rx *rx); +void bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config); +void bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors, + int nvectors); +void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_hds_disable(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_receive_pause(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_receive_resume(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); + +/* RxF APIs for RX */ +void bna_rxf_start(struct bna_rxf *rxf); +void bna_rxf_stop(struct bna_rxf *rxf); +void bna_rxf_fail(struct bna_rxf *rxf); +void bna_rxf_init(struct bna_rxf *rxf, struct bna_rx *rx, + struct bna_rx_config *q_config); +void bna_rxf_uninit(struct bna_rxf *rxf); + +/* Callback from RXF to RX */ +void bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status); +void bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status); + +/** + * BNAD + */ + +/* Callbacks for BNA */ +void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, + struct bna_stats *stats); +void bnad_cb_stats_clr(struct bnad *bnad); + +/* Callbacks for DEVICE */ +void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status); +void bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status); +void bnad_cb_device_enable_mbox_intr(struct bnad *bnad); +void bnad_cb_device_disable_mbox_intr(struct bnad *bnad); + +/* Callbacks for port */ +void bnad_cb_port_link_status(struct bnad *bnad, + enum bna_link_status status); + +#endif /* __BNA_H__ */ diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c new file mode 100644 index 000000000000..9d41ebf41cf4 --- /dev/null +++ b/drivers/net/bna/bna_ctrl.c @@ -0,0 +1,3626 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include "bna.h" +#include "bfa_sm.h" +#include "bfa_wc.h" + +/** + * MBOX + */ +static int +bna_is_aen(u8 msg_id) +{ + return (msg_id == BFI_LL_I2H_LINK_DOWN_AEN || + msg_id == BFI_LL_I2H_LINK_UP_AEN); +} + +static void +bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg) +{ + struct bfi_ll_aen *aen = (struct bfi_ll_aen *)(msg); + + switch (aen->mh.msg_id) { + case BFI_LL_I2H_LINK_UP_AEN: + bna_port_cb_link_up(&bna->port, aen, aen->reason); + break; + case BFI_LL_I2H_LINK_DOWN_AEN: + bna_port_cb_link_down(&bna->port, aen->reason); + break; + default: + break; + } +} + +static void +bna_ll_isr(void *llarg, struct bfi_mbmsg *msg) +{ + struct bna *bna = (struct bna *)(llarg); + struct bfi_ll_rsp *mb_rsp = (struct bfi_ll_rsp *)(msg); + struct bfi_mhdr *cmd_h, *rsp_h; + struct bna_mbox_qe *mb_qe = NULL; + int to_post = 0; + u8 aen = 0; + char message[BNA_MESSAGE_SIZE]; + + aen = bna_is_aen(mb_rsp->mh.msg_id); + + if (!aen) { + mb_qe = bfa_q_first(&bna->mbox_mod.posted_q); + cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]); + rsp_h = (struct bfi_mhdr *)(&mb_rsp->mh); + + if ((BFA_I2HM(cmd_h->msg_id) == rsp_h->msg_id) && + (cmd_h->mtag.i2htok == rsp_h->mtag.i2htok)) { + /* Remove the request from posted_q, update state */ + list_del(&mb_qe->qe); + bna->mbox_mod.msg_pending--; + if (list_empty(&bna->mbox_mod.posted_q)) + bna->mbox_mod.state = BNA_MBOX_FREE; + else + to_post = 1; + + /* Dispatch the cbfn */ + if (mb_qe->cbfn) + mb_qe->cbfn(mb_qe->cbarg, mb_rsp->error); + + /* Post the next entry, if needed */ + if (to_post) { + mb_qe = bfa_q_first(&bna->mbox_mod.posted_q); + bfa_ioc_mbox_queue(&bna->device.ioc, + &mb_qe->cmd); + } + } else { + snprintf(message, BNA_MESSAGE_SIZE, + "No matching rsp for [%d:%d:%d]\n", + mb_rsp->mh.msg_class, mb_rsp->mh.msg_id, + mb_rsp->mh.mtag.i2htok); + pr_info("%s", message); + } + + } else + bna_mbox_aen_callback(bna, msg); +} + +void +bna_err_handler(struct bna *bna, u32 intr_status) +{ + u32 init_halt; + + if (intr_status & __HALT_STATUS_BITS) { + init_halt = readl(bna->device.ioc.ioc_regs.ll_halt); + init_halt &= ~__FW_INIT_HALT_P; + writel(init_halt, bna->device.ioc.ioc_regs.ll_halt); + } + + bfa_ioc_error_isr(&bna->device.ioc); +} + +void +bna_mbox_handler(struct bna *bna, u32 intr_status) +{ + if (BNA_IS_ERR_INTR(intr_status)) { + bna_err_handler(bna, intr_status); + return; + } + if (BNA_IS_MBOX_INTR(intr_status)) + bfa_ioc_mbox_isr(&bna->device.ioc); +} + +void +bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe) +{ + struct bfi_mhdr *mh; + + mh = (struct bfi_mhdr *)(&mbox_qe->cmd.msg[0]); + + mh->mtag.i2htok = htons(bna->mbox_mod.msg_ctr); + bna->mbox_mod.msg_ctr++; + bna->mbox_mod.msg_pending++; + if (bna->mbox_mod.state == BNA_MBOX_FREE) { + list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); + bfa_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd); + bna->mbox_mod.state = BNA_MBOX_POSTED; + } else { + list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); + } +} + +void +bna_mbox_flush_q(struct bna *bna, struct list_head *q) +{ + struct bna_mbox_qe *mb_qe = NULL; + struct bfi_mhdr *cmd_h; + struct list_head *mb_q; + void (*cbfn)(void *arg, int status); + void *cbarg; + + mb_q = &bna->mbox_mod.posted_q; + + while (!list_empty(mb_q)) { + bfa_q_deq(mb_q, &mb_qe); + cbfn = mb_qe->cbfn; + cbarg = mb_qe->cbarg; + bfa_q_qe_init(mb_qe); + bna->mbox_mod.msg_pending--; + + cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]); + if (cbfn) + cbfn(cbarg, BNA_CB_NOT_EXEC); + } + + bna->mbox_mod.state = BNA_MBOX_FREE; +} + +void +bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod) +{ +} + +void +bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod) +{ + bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q); +} + +void +bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna) +{ + bfa_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna); + mbox_mod->state = BNA_MBOX_FREE; + mbox_mod->msg_ctr = mbox_mod->msg_pending = 0; + INIT_LIST_HEAD(&mbox_mod->posted_q); + mbox_mod->bna = bna; +} + +void +bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod) +{ + mbox_mod->bna = NULL; +} + +/** + * LLPORT + */ +#define call_llport_stop_cbfn(llport, status)\ +do {\ + if ((llport)->stop_cbfn)\ + (llport)->stop_cbfn(&(llport)->bna->port, status);\ + (llport)->stop_cbfn = NULL;\ +} while (0) + +static void bna_fw_llport_up(struct bna_llport *llport); +static void bna_fw_cb_llport_up(void *arg, int status); +static void bna_fw_llport_down(struct bna_llport *llport); +static void bna_fw_cb_llport_down(void *arg, int status); +static void bna_llport_start(struct bna_llport *llport); +static void bna_llport_stop(struct bna_llport *llport); +static void bna_llport_fail(struct bna_llport *llport); + +enum bna_llport_event { + LLPORT_E_START = 1, + LLPORT_E_STOP = 2, + LLPORT_E_FAIL = 3, + LLPORT_E_UP = 4, + LLPORT_E_DOWN = 5, + LLPORT_E_FWRESP_UP = 6, + LLPORT_E_FWRESP_DOWN = 7 +}; + +enum bna_llport_state { + BNA_LLPORT_STOPPED = 1, + BNA_LLPORT_DOWN = 2, + BNA_LLPORT_UP_RESP_WAIT = 3, + BNA_LLPORT_DOWN_RESP_WAIT = 4, + BNA_LLPORT_UP = 5, + BNA_LLPORT_LAST_RESP_WAIT = 6 +}; + +bfa_fsm_state_decl(bna_llport, stopped, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, down, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, up_resp_wait, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, down_resp_wait, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, up, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, last_resp_wait, struct bna_llport, + enum bna_llport_event); + +static struct bfa_sm_table llport_sm_table[] = { + {BFA_SM(bna_llport_sm_stopped), BNA_LLPORT_STOPPED}, + {BFA_SM(bna_llport_sm_down), BNA_LLPORT_DOWN}, + {BFA_SM(bna_llport_sm_up_resp_wait), BNA_LLPORT_UP_RESP_WAIT}, + {BFA_SM(bna_llport_sm_down_resp_wait), BNA_LLPORT_DOWN_RESP_WAIT}, + {BFA_SM(bna_llport_sm_up), BNA_LLPORT_UP}, + {BFA_SM(bna_llport_sm_last_resp_wait), BNA_LLPORT_LAST_RESP_WAIT} +}; + +static void +bna_llport_sm_stopped_entry(struct bna_llport *llport) +{ + llport->bna->port.link_cbfn((llport)->bna->bnad, BNA_LINK_DOWN); + call_llport_stop_cbfn(llport, BNA_CB_SUCCESS); +} + +static void +bna_llport_sm_stopped(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_START: + bfa_fsm_set_state(llport, bna_llport_sm_down); + break; + + case LLPORT_E_STOP: + call_llport_stop_cbfn(llport, BNA_CB_SUCCESS); + break; + + case LLPORT_E_FAIL: + break; + + case LLPORT_E_DOWN: + /* This event is received due to Rx objects failing */ + /* No-op */ + break; + + case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_DOWN: + /** + * These events are received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_down_entry(struct bna_llport *llport) +{ + bnad_cb_port_link_status((llport)->bna->bnad, BNA_LINK_DOWN); +} + +static void +bna_llport_sm_down(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait); + bna_fw_llport_up(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport) +{ + /** + * NOTE: Do not call bna_fw_llport_up() here. That will over step + * mbox due to down_resp_wait -> up_resp_wait transition on event + * LLPORT_E_UP + */ +} + +static void +bna_llport_sm_up_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait); + break; + + case LLPORT_E_FWRESP_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up); + break; + + case LLPORT_E_FWRESP_DOWN: + /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */ + bna_fw_llport_up(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_down_resp_wait_entry(struct bna_llport *llport) +{ + /** + * NOTE: Do not call bna_fw_llport_down() here. That will over step + * mbox due to up_resp_wait -> down_resp_wait transition on event + * LLPORT_E_DOWN + */ +} + +static void +bna_llport_sm_down_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait); + break; + + case LLPORT_E_FWRESP_UP: + /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */ + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FWRESP_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_up_entry(struct bna_llport *llport) +{ +} + +static void +bna_llport_sm_up(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait); + bna_fw_llport_down(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_last_resp_wait_entry(struct bna_llport *llport) +{ +} + +static void +bna_llport_sm_last_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + /** + * This event is received due to Rx objects stopping in + * parallel to llport + */ + /* No-op */ + break; + + case LLPORT_E_FWRESP_UP: + /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */ + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FWRESP_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_fw_llport_admin_up(struct bna_llport *llport) +{ + struct bfi_ll_port_admin_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.up = BNA_STATUS_T_ENABLED; + + bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_llport_up, llport); + + bna_mbox_send(llport->bna, &llport->mbox_qe); +} + +static void +bna_fw_llport_up(struct bna_llport *llport) +{ + if (llport->type == BNA_PORT_T_REGULAR) + bna_fw_llport_admin_up(llport); +} + +static void +bna_fw_cb_llport_up(void *arg, int status) +{ + struct bna_llport *llport = (struct bna_llport *)arg; + + bfa_q_qe_init(&llport->mbox_qe.qe); + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP); +} + +static void +bna_fw_llport_admin_down(struct bna_llport *llport) +{ + struct bfi_ll_port_admin_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.up = BNA_STATUS_T_DISABLED; + + bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_llport_down, llport); + + bna_mbox_send(llport->bna, &llport->mbox_qe); +} + +static void +bna_fw_llport_down(struct bna_llport *llport) +{ + if (llport->type == BNA_PORT_T_REGULAR) + bna_fw_llport_admin_down(llport); +} + +static void +bna_fw_cb_llport_down(void *arg, int status) +{ + struct bna_llport *llport = (struct bna_llport *)arg; + + bfa_q_qe_init(&llport->mbox_qe.qe); + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN); +} + +void +bna_port_cb_llport_stopped(struct bna_port *port, + enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +static void +bna_llport_init(struct bna_llport *llport, struct bna *bna) +{ + llport->flags |= BNA_LLPORT_F_ENABLED; + llport->type = BNA_PORT_T_REGULAR; + llport->bna = bna; + + llport->link_status = BNA_LINK_DOWN; + + llport->admin_up_count = 0; + + llport->stop_cbfn = NULL; + + bfa_q_qe_init(&llport->mbox_qe.qe); + + bfa_fsm_set_state(llport, bna_llport_sm_stopped); +} + +static void +bna_llport_uninit(struct bna_llport *llport) +{ + llport->flags &= ~BNA_LLPORT_F_ENABLED; + + llport->bna = NULL; +} + +static void +bna_llport_start(struct bna_llport *llport) +{ + bfa_fsm_send_event(llport, LLPORT_E_START); +} + +static void +bna_llport_stop(struct bna_llport *llport) +{ + llport->stop_cbfn = bna_port_cb_llport_stopped; + + bfa_fsm_send_event(llport, LLPORT_E_STOP); +} + +static void +bna_llport_fail(struct bna_llport *llport) +{ + bfa_fsm_send_event(llport, LLPORT_E_FAIL); +} + +int +bna_llport_state_get(struct bna_llport *llport) +{ + return bfa_sm_to_state(llport_sm_table, llport->fsm); +} + +void +bna_llport_admin_up(struct bna_llport *llport) +{ + llport->admin_up_count++; + + if (llport->admin_up_count == 1) { + llport->flags |= BNA_LLPORT_F_RX_ENABLED; + if (llport->flags & BNA_LLPORT_F_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_UP); + } +} + +void +bna_llport_admin_down(struct bna_llport *llport) +{ + llport->admin_up_count--; + + if (llport->admin_up_count == 0) { + llport->flags &= ~BNA_LLPORT_F_RX_ENABLED; + if (llport->flags & BNA_LLPORT_F_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_DOWN); + } +} + +/** + * PORT + */ +#define bna_port_chld_start(port)\ +do {\ + enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bna_llport_start(&(port)->llport);\ + bna_tx_mod_start(&(port)->bna->tx_mod, tx_type);\ + bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_chld_stop(port)\ +do {\ + enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bna_llport_stop(&(port)->llport);\ + bna_tx_mod_stop(&(port)->bna->tx_mod, tx_type);\ + bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_chld_fail(port)\ +do {\ + bna_llport_fail(&(port)->llport);\ + bna_tx_mod_fail(&(port)->bna->tx_mod);\ + bna_rx_mod_fail(&(port)->bna->rx_mod);\ +} while (0) + +#define bna_port_rx_start(port)\ +do {\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_rx_stop(port)\ +do {\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define call_port_stop_cbfn(port, status)\ +do {\ + if ((port)->stop_cbfn)\ + (port)->stop_cbfn((port)->stop_cbarg, status);\ + (port)->stop_cbfn = NULL;\ + (port)->stop_cbarg = NULL;\ +} while (0) + +#define call_port_pause_cbfn(port, status)\ +do {\ + if ((port)->pause_cbfn)\ + (port)->pause_cbfn((port)->bna->bnad, status);\ + (port)->pause_cbfn = NULL;\ +} while (0) + +#define call_port_mtu_cbfn(port, status)\ +do {\ + if ((port)->mtu_cbfn)\ + (port)->mtu_cbfn((port)->bna->bnad, status);\ + (port)->mtu_cbfn = NULL;\ +} while (0) + +static void bna_fw_pause_set(struct bna_port *port); +static void bna_fw_cb_pause_set(void *arg, int status); +static void bna_fw_mtu_set(struct bna_port *port); +static void bna_fw_cb_mtu_set(void *arg, int status); + +enum bna_port_event { + PORT_E_START = 1, + PORT_E_STOP = 2, + PORT_E_FAIL = 3, + PORT_E_PAUSE_CFG = 4, + PORT_E_MTU_CFG = 5, + PORT_E_CHLD_STOPPED = 6, + PORT_E_FWRESP_PAUSE = 7, + PORT_E_FWRESP_MTU = 8 +}; + +enum bna_port_state { + BNA_PORT_STOPPED = 1, + BNA_PORT_MTU_INIT_WAIT = 2, + BNA_PORT_PAUSE_INIT_WAIT = 3, + BNA_PORT_LAST_RESP_WAIT = 4, + BNA_PORT_STARTED = 5, + BNA_PORT_PAUSE_CFG_WAIT = 6, + BNA_PORT_RX_STOP_WAIT = 7, + BNA_PORT_MTU_CFG_WAIT = 8, + BNA_PORT_CHLD_STOP_WAIT = 9 +}; + +bfa_fsm_state_decl(bna_port, stopped, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, mtu_init_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, pause_init_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, last_resp_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, started, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, pause_cfg_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, rx_stop_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, mtu_cfg_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, chld_stop_wait, struct bna_port, + enum bna_port_event); + +static struct bfa_sm_table port_sm_table[] = { + {BFA_SM(bna_port_sm_stopped), BNA_PORT_STOPPED}, + {BFA_SM(bna_port_sm_mtu_init_wait), BNA_PORT_MTU_INIT_WAIT}, + {BFA_SM(bna_port_sm_pause_init_wait), BNA_PORT_PAUSE_INIT_WAIT}, + {BFA_SM(bna_port_sm_last_resp_wait), BNA_PORT_LAST_RESP_WAIT}, + {BFA_SM(bna_port_sm_started), BNA_PORT_STARTED}, + {BFA_SM(bna_port_sm_pause_cfg_wait), BNA_PORT_PAUSE_CFG_WAIT}, + {BFA_SM(bna_port_sm_rx_stop_wait), BNA_PORT_RX_STOP_WAIT}, + {BFA_SM(bna_port_sm_mtu_cfg_wait), BNA_PORT_MTU_CFG_WAIT}, + {BFA_SM(bna_port_sm_chld_stop_wait), BNA_PORT_CHLD_STOP_WAIT} +}; + +static void +bna_port_sm_stopped_entry(struct bna_port *port) +{ + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); + call_port_stop_cbfn(port, BNA_CB_SUCCESS); +} + +static void +bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_START: + bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait); + break; + + case PORT_E_STOP: + call_port_stop_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_FAIL: + /* No-op */ + break; + + case PORT_E_PAUSE_CFG: + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_MTU_CFG: + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_CHLD_STOPPED: + /** + * This event is received due to LLPort, Tx and Rx objects + * failing + */ + /* No-op */ + break; + + case PORT_E_FWRESP_PAUSE: + case PORT_E_FWRESP_MTU: + /** + * These events are received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_mtu_init_wait_entry(struct bna_port *port) +{ + bna_fw_mtu_set(port); +} + +static void +bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_last_resp_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + case PORT_E_PAUSE_CFG: + /* No-op */ + break; + + case PORT_E_MTU_CFG: + port->flags |= BNA_PORT_F_MTU_CHANGED; + break; + + case PORT_E_FWRESP_MTU: + if (port->flags & BNA_PORT_F_MTU_CHANGED) { + port->flags &= ~BNA_PORT_F_MTU_CHANGED; + bna_fw_mtu_set(port); + } else { + bfa_fsm_set_state(port, bna_port_sm_pause_init_wait); + } + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_pause_init_wait_entry(struct bna_port *port) +{ + bna_fw_pause_set(port); +} + +static void +bna_port_sm_pause_init_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_last_resp_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + case PORT_E_PAUSE_CFG: + port->flags |= BNA_PORT_F_PAUSE_CHANGED; + break; + + case PORT_E_MTU_CFG: + port->flags |= BNA_PORT_F_MTU_CHANGED; + break; + + case PORT_E_FWRESP_PAUSE: + if (port->flags & BNA_PORT_F_PAUSE_CHANGED) { + port->flags &= ~BNA_PORT_F_PAUSE_CHANGED; + bna_fw_pause_set(port); + } else if (port->flags & BNA_PORT_F_MTU_CHANGED) { + port->flags &= ~BNA_PORT_F_MTU_CHANGED; + bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait); + } else { + bfa_fsm_set_state(port, bna_port_sm_started); + bna_port_chld_start(port); + } + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_last_resp_wait_entry(struct bna_port *port) +{ +} + +static void +bna_port_sm_last_resp_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + case PORT_E_FWRESP_PAUSE: + case PORT_E_FWRESP_MTU: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_started_entry(struct bna_port *port) +{ + /** + * NOTE: Do not call bna_port_chld_start() here, since it will be + * inadvertently called during pause_cfg_wait->started transition + * as well + */ + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); +} + +static void +bna_port_sm_started(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_chld_stop_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_PAUSE_CFG: + bfa_fsm_set_state(port, bna_port_sm_pause_cfg_wait); + break; + + case PORT_E_MTU_CFG: + bfa_fsm_set_state(port, bna_port_sm_rx_stop_wait); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_pause_cfg_wait_entry(struct bna_port *port) +{ + bna_fw_pause_set(port); +} + +static void +bna_port_sm_pause_cfg_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_FWRESP_PAUSE: + bfa_fsm_set_state(port, bna_port_sm_started); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_rx_stop_wait_entry(struct bna_port *port) +{ + bna_port_rx_stop(port); +} + +static void +bna_port_sm_rx_stop_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_CHLD_STOPPED: + bfa_fsm_set_state(port, bna_port_sm_mtu_cfg_wait); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_mtu_cfg_wait_entry(struct bna_port *port) +{ + bna_fw_mtu_set(port); +} + +static void +bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_FWRESP_MTU: + bfa_fsm_set_state(port, bna_port_sm_started); + bna_port_rx_start(port); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_chld_stop_wait_entry(struct bna_port *port) +{ + bna_port_chld_stop(port); +} + +static void +bna_port_sm_chld_stop_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_CHLD_STOPPED: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_fw_pause_set(struct bna_port *port) +{ + struct bfi_ll_set_pause_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_SET_PAUSE_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.tx_pause = port->pause_config.tx_pause; + ll_req.rx_pause = port->pause_config.rx_pause; + + bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_pause_set, port); + + bna_mbox_send(port->bna, &port->mbox_qe); +} + +static void +bna_fw_cb_pause_set(void *arg, int status) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_q_qe_init(&port->mbox_qe.qe); + bfa_fsm_send_event(port, PORT_E_FWRESP_PAUSE); +} + +void +bna_fw_mtu_set(struct bna_port *port) +{ + struct bfi_ll_mtu_info_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_MTU_INFO_REQ, 0); + ll_req.mtu = htons((u16)port->mtu); + + bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_mtu_set, port); + bna_mbox_send(port->bna, &port->mbox_qe); +} + +void +bna_fw_cb_mtu_set(void *arg, int status) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_q_qe_init(&port->mbox_qe.qe); + bfa_fsm_send_event(port, PORT_E_FWRESP_MTU); +} + +static void +bna_port_cb_chld_stopped(void *arg) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED); +} + +void +bna_port_init(struct bna_port *port, struct bna *bna) +{ + port->bna = bna; + port->flags = 0; + port->mtu = 0; + port->type = BNA_PORT_T_REGULAR; + + port->link_cbfn = bnad_cb_port_link_status; + + port->chld_stop_wc.wc_resume = bna_port_cb_chld_stopped; + port->chld_stop_wc.wc_cbarg = port; + port->chld_stop_wc.wc_count = 0; + + port->stop_cbfn = NULL; + port->stop_cbarg = NULL; + + port->pause_cbfn = NULL; + + port->mtu_cbfn = NULL; + + bfa_q_qe_init(&port->mbox_qe.qe); + + bfa_fsm_set_state(port, bna_port_sm_stopped); + + bna_llport_init(&port->llport, bna); +} + +void +bna_port_uninit(struct bna_port *port) +{ + bna_llport_uninit(&port->llport); + + port->flags = 0; + + port->bna = NULL; +} + +int +bna_port_state_get(struct bna_port *port) +{ + return bfa_sm_to_state(port_sm_table, port->fsm); +} + +void +bna_port_start(struct bna_port *port) +{ + port->flags |= BNA_PORT_F_DEVICE_READY; + if (port->flags & BNA_PORT_F_ENABLED) + bfa_fsm_send_event(port, PORT_E_START); +} + +void +bna_port_stop(struct bna_port *port) +{ + port->stop_cbfn = bna_device_cb_port_stopped; + port->stop_cbarg = &port->bna->device; + + port->flags &= ~BNA_PORT_F_DEVICE_READY; + bfa_fsm_send_event(port, PORT_E_STOP); +} + +void +bna_port_fail(struct bna_port *port) +{ + port->flags &= ~BNA_PORT_F_DEVICE_READY; + bfa_fsm_send_event(port, PORT_E_FAIL); +} + +void +bna_port_cb_tx_stopped(struct bna_port *port, enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +void +bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +void +bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, + int status) +{ + int i; + u8 prio_map; + + port->llport.link_status = BNA_LINK_UP; + if (aen->cee_linkup) + port->llport.link_status = BNA_CEE_UP; + + /* Compute the priority */ + prio_map = aen->prio_map; + if (prio_map) { + for (i = 0; i < 8; i++) { + if ((prio_map >> i) & 0x1) + break; + } + port->priority = i; + } else + port->priority = 0; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup); + bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority); + port->link_cbfn(port->bna->bnad, port->llport.link_status); +} + +void +bna_port_cb_link_down(struct bna_port *port, int status) +{ + port->llport.link_status = BNA_LINK_DOWN; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN); + port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN); +} + +int +bna_port_mtu_get(struct bna_port *port) +{ + return port->mtu; +} + +void +bna_port_enable(struct bna_port *port) +{ + if (port->fsm != (bfa_sm_t)bna_port_sm_stopped) + return; + + port->flags |= BNA_PORT_F_ENABLED; + + if (port->flags & BNA_PORT_F_DEVICE_READY) + bfa_fsm_send_event(port, PORT_E_START); +} + +void +bna_port_disable(struct bna_port *port, enum bna_cleanup_type type, + void (*cbfn)(void *, enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + (*cbfn)(port->bna->bnad, BNA_CB_SUCCESS); + return; + } + + port->stop_cbfn = cbfn; + port->stop_cbarg = port->bna->bnad; + + port->flags &= ~BNA_PORT_F_ENABLED; + + bfa_fsm_send_event(port, PORT_E_STOP); +} + +void +bna_port_pause_config(struct bna_port *port, + struct bna_pause_config *pause_config, + void (*cbfn)(struct bnad *, enum bna_cb_status)) +{ + port->pause_config = *pause_config; + + port->pause_cbfn = cbfn; + + bfa_fsm_send_event(port, PORT_E_PAUSE_CFG); +} + +void +bna_port_mtu_set(struct bna_port *port, int mtu, + void (*cbfn)(struct bnad *, enum bna_cb_status)) +{ + port->mtu = mtu; + + port->mtu_cbfn = cbfn; + + bfa_fsm_send_event(port, PORT_E_MTU_CFG); +} + +void +bna_port_mac_get(struct bna_port *port, mac_t *mac) +{ + *mac = bfa_ioc_get_mac(&port->bna->device.ioc); +} + +/** + * Should be called only when port is disabled + */ +void +bna_port_type_set(struct bna_port *port, enum bna_port_type type) +{ + port->type = type; + port->llport.type = type; +} + +/** + * Should be called only when port is disabled + */ +void +bna_port_linkcbfn_set(struct bna_port *port, + void (*linkcbfn)(struct bnad *, enum bna_link_status)) +{ + port->link_cbfn = linkcbfn; +} + +void +bna_port_admin_up(struct bna_port *port) +{ + struct bna_llport *llport = &port->llport; + + if (llport->flags & BNA_LLPORT_F_ENABLED) + return; + + llport->flags |= BNA_LLPORT_F_ENABLED; + + if (llport->flags & BNA_LLPORT_F_RX_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_UP); +} + +void +bna_port_admin_down(struct bna_port *port) +{ + struct bna_llport *llport = &port->llport; + + if (!(llport->flags & BNA_LLPORT_F_ENABLED)) + return; + + llport->flags &= ~BNA_LLPORT_F_ENABLED; + + if (llport->flags & BNA_LLPORT_F_RX_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_DOWN); +} + +/** + * DEVICE + */ +#define enable_mbox_intr(_device)\ +do {\ + u32 intr_status;\ + bna_intr_status_get((_device)->bna, intr_status);\ + bnad_cb_device_enable_mbox_intr((_device)->bna->bnad);\ + bna_mbox_intr_enable((_device)->bna);\ +} while (0) + +#define disable_mbox_intr(_device)\ +do {\ + bna_mbox_intr_disable((_device)->bna);\ + bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\ +} while (0) + +const struct bna_chip_regs_offset reg_offset[] = +{{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS, + HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0}, +{HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS, + HOSTFN1_INT_MASK, HOST_MSIX_ERR_INDEX_FN1}, +{HOST_PAGE_NUM_FN2, HOSTFN2_INT_STATUS, + HOSTFN2_INT_MASK, HOST_MSIX_ERR_INDEX_FN2}, +{HOST_PAGE_NUM_FN3, HOSTFN3_INT_STATUS, + HOSTFN3_INT_MASK, HOST_MSIX_ERR_INDEX_FN3}, +}; + +enum bna_device_event { + DEVICE_E_ENABLE = 1, + DEVICE_E_DISABLE = 2, + DEVICE_E_IOC_READY = 3, + DEVICE_E_IOC_FAILED = 4, + DEVICE_E_IOC_DISABLED = 5, + DEVICE_E_IOC_RESET = 6, + DEVICE_E_PORT_STOPPED = 7, +}; + +enum bna_device_state { + BNA_DEVICE_STOPPED = 1, + BNA_DEVICE_IOC_READY_WAIT = 2, + BNA_DEVICE_READY = 3, + BNA_DEVICE_PORT_STOP_WAIT = 4, + BNA_DEVICE_IOC_DISABLE_WAIT = 5, + BNA_DEVICE_FAILED = 6 +}; + +bfa_fsm_state_decl(bna_device, stopped, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ioc_ready_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ready, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, port_stop_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ioc_disable_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, failed, struct bna_device, + enum bna_device_event); + +static struct bfa_sm_table device_sm_table[] = { + {BFA_SM(bna_device_sm_stopped), BNA_DEVICE_STOPPED}, + {BFA_SM(bna_device_sm_ioc_ready_wait), BNA_DEVICE_IOC_READY_WAIT}, + {BFA_SM(bna_device_sm_ready), BNA_DEVICE_READY}, + {BFA_SM(bna_device_sm_port_stop_wait), BNA_DEVICE_PORT_STOP_WAIT}, + {BFA_SM(bna_device_sm_ioc_disable_wait), BNA_DEVICE_IOC_DISABLE_WAIT}, + {BFA_SM(bna_device_sm_failed), BNA_DEVICE_FAILED}, +}; + +static void +bna_device_sm_stopped_entry(struct bna_device *device) +{ + if (device->stop_cbfn) + device->stop_cbfn(device->stop_cbarg, BNA_CB_SUCCESS); + + device->stop_cbfn = NULL; + device->stop_cbarg = NULL; +} + +static void +bna_device_sm_stopped(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_ENABLE: + if (device->intr_type == BNA_INTR_T_MSIX) + bna_mbox_msix_idx_set(device); + bfa_ioc_enable(&device->ioc); + bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait); + break; + + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_stopped); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ioc_ready_wait_entry(struct bna_device *device) +{ + /** + * Do not call bfa_ioc_enable() here. It must be called in the + * previous state due to failed -> ioc_ready_wait transition. + */ +} + +static void +bna_device_sm_ioc_ready_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_INTERRUPT); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_READY: + bfa_fsm_set_state(device, bna_device_sm_ready); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ready_entry(struct bna_device *device) +{ + bna_mbox_mod_start(&device->bna->mbox_mod); + bna_port_start(&device->bna->port); + + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_SUCCESS); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; +} + +static void +bna_device_sm_ready(struct bna_device *device, enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_port_stop_wait); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_port_stop_wait_entry(struct bna_device *device) +{ + bna_port_stop(&device->bna->port); +} + +static void +bna_device_sm_port_stop_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_PORT_STOPPED: + bna_mbox_mod_stop(&device->bna->mbox_mod); + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_FAILED: + disable_mbox_intr(device); + bna_port_fail(&device->bna->port); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ioc_disable_wait_entry(struct bna_device *device) +{ + bfa_ioc_disable(&device->ioc); +} + +static void +bna_device_sm_ioc_disable_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_IOC_DISABLED: + disable_mbox_intr(device); + bfa_fsm_set_state(device, bna_device_sm_stopped); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_failed_entry(struct bna_device *device) +{ + disable_mbox_intr(device); + bna_port_fail(&device->bna->port); + bna_mbox_mod_stop(&device->bna->mbox_mod); + + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_FAIL); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; +} + +static void +bna_device_sm_failed(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +/* IOC callback functions */ + +static void +bna_device_cb_iocll_ready(void *dev, enum bfa_status error) +{ + struct bna_device *device = (struct bna_device *)dev; + + if (error) + bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED); + else + bfa_fsm_send_event(device, DEVICE_E_IOC_READY); +} + +static void +bna_device_cb_iocll_disabled(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_DISABLED); +} + +static void +bna_device_cb_iocll_failed(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED); +} + +static void +bna_device_cb_iocll_reset(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_RESET); +} + +static struct bfa_ioc_cbfn bfa_iocll_cbfn = { + bna_device_cb_iocll_ready, + bna_device_cb_iocll_disabled, + bna_device_cb_iocll_failed, + bna_device_cb_iocll_reset +}; + +void +bna_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info) +{ + u64 dma; + + device->bna = bna; + + /** + * Attach IOC and claim: + * 1. DMA memory for IOC attributes + * 2. Kernel memory for FW trace + */ + bfa_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn); + bfa_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL); + + BNA_GET_DMA_ADDR( + &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma); + bfa_ioc_mem_claim(&device->ioc, + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva, + dma); + + bna_adv_device_init(device, bna, res_info); + /* + * Initialize mbox_mod only after IOC, so that mbox handler + * registration goes through + */ + device->intr_type = + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type; + device->vector = + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.idl[0].vector; + bna_mbox_mod_init(&bna->mbox_mod, bna); + + device->ready_cbfn = device->stop_cbfn = NULL; + device->ready_cbarg = device->stop_cbarg = NULL; + + bfa_fsm_set_state(device, bna_device_sm_stopped); +} + +void +bna_device_uninit(struct bna_device *device) +{ + bna_mbox_mod_uninit(&device->bna->mbox_mod); + + bfa_cee_detach(&device->bna->cee); + + bfa_ioc_detach(&device->ioc); + + device->bna = NULL; +} + +void +bna_device_cb_port_stopped(void *arg, enum bna_cb_status status) +{ + struct bna_device *device = (struct bna_device *)arg; + + bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED); +} + +int +bna_device_status_get(struct bna_device *device) +{ + return (device->fsm == (bfa_fsm_t)bna_device_sm_ready); +} + +void +bna_device_enable(struct bna_device *device) +{ + if (device->fsm != (bfa_fsm_t)bna_device_sm_stopped) { + bnad_cb_device_enabled(device->bna->bnad, BNA_CB_BUSY); + return; + } + + device->ready_cbfn = bnad_cb_device_enabled; + device->ready_cbarg = device->bna->bnad; + + bfa_fsm_send_event(device, DEVICE_E_ENABLE); +} + +void +bna_device_disable(struct bna_device *device, enum bna_cleanup_type type) +{ + if (type == BNA_SOFT_CLEANUP) { + bnad_cb_device_disabled(device->bna->bnad, BNA_CB_SUCCESS); + return; + } + + device->stop_cbfn = bnad_cb_device_disabled; + device->stop_cbarg = device->bna->bnad; + + bfa_fsm_send_event(device, DEVICE_E_DISABLE); +} + +int +bna_device_state_get(struct bna_device *device) +{ + return bfa_sm_to_state(device_sm_table, device->fsm); +} + +u32 bna_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { + {12, 20}, + {10, 18}, + {8, 16}, + {6, 12}, + {4, 8}, + {3, 6}, + {2, 4}, + {1, 2}, +}; + +u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { + {12, 12}, + {6, 10}, + {5, 10}, + {4, 8}, + {3, 6}, + {3, 6}, + {2, 4}, + {1, 2}, +}; + +/* device */ +void +bna_adv_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info) +{ + u8 *kva; + u64 dma; + + device->bna = bna; + + kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva; + + /** + * Attach common modules (Diag, SFP, CEE, Port) and claim respective + * DMA memory. + */ + BNA_GET_DMA_ADDR( + &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); + kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; + + bfa_cee_attach(&bna->cee, &device->ioc, bna); + bfa_cee_mem_claim(&bna->cee, kva, dma); + kva += bfa_cee_meminfo(); + dma += bfa_cee_meminfo(); + +} + +/* utils */ + +void +bna_adv_res_req(struct bna_res_info *res_info) +{ + /* DMA memory for COMMON_MODULE */ + res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( + bfa_cee_meminfo(), PAGE_SIZE); + + /* Virtual memory for retreiving fw_trc */ + res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0; + + /* DMA memory for retreiving stats */ + res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len = + ALIGN(BFI_HW_STATS_SIZE, PAGE_SIZE); + + /* Virtual memory for soft stats */ + res_info[BNA_RES_MEM_T_SWSTATS].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mem_type = BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.len = + sizeof(struct bna_sw_stats); +} + +static void +bna_sw_stats_get(struct bna *bna, struct bna_sw_stats *sw_stats) +{ + struct bna_tx *tx; + struct bna_txq *txq; + struct bna_rx *rx; + struct bna_rxp *rxp; + struct list_head *qe; + struct list_head *txq_qe; + struct list_head *rxp_qe; + struct list_head *mac_qe; + int i; + + sw_stats->device_state = bna_device_state_get(&bna->device); + sw_stats->port_state = bna_port_state_get(&bna->port); + sw_stats->port_flags = bna->port.flags; + sw_stats->llport_state = bna_llport_state_get(&bna->port.llport); + sw_stats->priority = bna->port.priority; + + i = 0; + list_for_each(qe, &bna->tx_mod.tx_active_q) { + tx = (struct bna_tx *)qe; + sw_stats->tx_stats[i].tx_state = bna_tx_state_get(tx); + sw_stats->tx_stats[i].tx_flags = tx->flags; + + sw_stats->tx_stats[i].num_txqs = 0; + sw_stats->tx_stats[i].txq_bmap[0] = 0; + sw_stats->tx_stats[i].txq_bmap[1] = 0; + list_for_each(txq_qe, &tx->txq_q) { + txq = (struct bna_txq *)txq_qe; + if (txq->txq_id < 32) + sw_stats->tx_stats[i].txq_bmap[0] |= + ((u32)1 << txq->txq_id); + else + sw_stats->tx_stats[i].txq_bmap[1] |= + ((u32) + 1 << (txq->txq_id - 32)); + sw_stats->tx_stats[i].num_txqs++; + } + + sw_stats->tx_stats[i].txf_id = tx->txf.txf_id; + + i++; + } + sw_stats->num_active_tx = i; + + i = 0; + list_for_each(qe, &bna->rx_mod.rx_active_q) { + rx = (struct bna_rx *)qe; + sw_stats->rx_stats[i].rx_state = bna_rx_state_get(rx); + sw_stats->rx_stats[i].rx_flags = rx->rx_flags; + + sw_stats->rx_stats[i].num_rxps = 0; + sw_stats->rx_stats[i].num_rxqs = 0; + sw_stats->rx_stats[i].rxq_bmap[0] = 0; + sw_stats->rx_stats[i].rxq_bmap[1] = 0; + sw_stats->rx_stats[i].cq_bmap[0] = 0; + sw_stats->rx_stats[i].cq_bmap[1] = 0; + list_for_each(rxp_qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)rxp_qe; + + sw_stats->rx_stats[i].num_rxqs += 1; + + if (rxp->type == BNA_RXP_SINGLE) { + if (rxp->rxq.single.only->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.single.only->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.single.only->rxq_id - 32)); + } + } else { + if (rxp->rxq.slr.large->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.slr.large->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.slr.large->rxq_id - 32)); + } + + if (rxp->rxq.slr.small->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.slr.small->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.slr.small->rxq_id - 32)); + } + sw_stats->rx_stats[i].num_rxqs += 1; + } + + if (rxp->cq.cq_id < 32) + sw_stats->rx_stats[i].cq_bmap[0] |= + (1 << rxp->cq.cq_id); + else + sw_stats->rx_stats[i].cq_bmap[1] |= + (1 << (rxp->cq.cq_id - 32)); + + sw_stats->rx_stats[i].num_rxps++; + } + + sw_stats->rx_stats[i].rxf_id = rx->rxf.rxf_id; + sw_stats->rx_stats[i].rxf_state = bna_rxf_state_get(&rx->rxf); + sw_stats->rx_stats[i].rxf_oper_state = rx->rxf.rxf_oper_state; + + sw_stats->rx_stats[i].num_active_ucast = 0; + if (rx->rxf.ucast_active_mac) + sw_stats->rx_stats[i].num_active_ucast++; + list_for_each(mac_qe, &rx->rxf.ucast_active_q) + sw_stats->rx_stats[i].num_active_ucast++; + + sw_stats->rx_stats[i].num_active_mcast = 0; + list_for_each(mac_qe, &rx->rxf.mcast_active_q) + sw_stats->rx_stats[i].num_active_mcast++; + + sw_stats->rx_stats[i].rxmode_active = rx->rxf.rxmode_active; + sw_stats->rx_stats[i].vlan_filter_status = + rx->rxf.vlan_filter_status; + memcpy(sw_stats->rx_stats[i].vlan_filter_table, + rx->rxf.vlan_filter_table, + sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)); + + sw_stats->rx_stats[i].rss_status = rx->rxf.rss_status; + sw_stats->rx_stats[i].hds_status = rx->rxf.hds_status; + + i++; + } + sw_stats->num_active_rx = i; +} + +static void +bna_fw_cb_stats_get(void *arg, int status) +{ + struct bna *bna = (struct bna *)arg; + u64 *p_stats; + int i, count; + int rxf_count, txf_count; + u64 rxf_bmap, txf_bmap; + + bfa_q_qe_init(&bna->mbox_qe.qe); + + if (status == 0) { + p_stats = (u64 *)bna->stats.hw_stats; + count = sizeof(struct bfi_ll_stats) / sizeof(u64); + for (i = 0; i < count; i++) + p_stats[i] = cpu_to_be64(p_stats[i]); + + rxf_count = 0; + rxf_bmap = (u64)bna->stats.rxf_bmap[0] | + ((u64)bna->stats.rxf_bmap[1] << 32); + for (i = 0; i < BFI_LL_RXF_ID_MAX; i++) + if (rxf_bmap & ((u64)1 << i)) + rxf_count++; + + txf_count = 0; + txf_bmap = (u64)bna->stats.txf_bmap[0] | + ((u64)bna->stats.txf_bmap[1] << 32); + for (i = 0; i < BFI_LL_TXF_ID_MAX; i++) + if (txf_bmap & ((u64)1 << i)) + txf_count++; + + p_stats = (u64 *)&bna->stats.hw_stats->rxf_stats[0] + + ((rxf_count * sizeof(struct bfi_ll_stats_rxf) + + txf_count * sizeof(struct bfi_ll_stats_txf))/ + sizeof(u64)); + + /* Populate the TXF stats from the firmware DMAed copy */ + for (i = (BFI_LL_TXF_ID_MAX - 1); i >= 0; i--) + if (txf_bmap & ((u64)1 << i)) { + p_stats -= sizeof(struct bfi_ll_stats_txf)/ + sizeof(u64); + memcpy(&bna->stats.hw_stats->txf_stats[i], + p_stats, + sizeof(struct bfi_ll_stats_txf)); + } + + /* Populate the RXF stats from the firmware DMAed copy */ + for (i = (BFI_LL_RXF_ID_MAX - 1); i >= 0; i--) + if (rxf_bmap & ((u64)1 << i)) { + p_stats -= sizeof(struct bfi_ll_stats_rxf)/ + sizeof(u64); + memcpy(&bna->stats.hw_stats->rxf_stats[i], + p_stats, + sizeof(struct bfi_ll_stats_rxf)); + } + + bna_sw_stats_get(bna, bna->stats.sw_stats); + bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats); + } else + bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); +} + +static void +bna_fw_stats_get(struct bna *bna) +{ + struct bfi_ll_stats_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_GET_REQ, 0); + ll_req.stats_mask = htons(BFI_LL_STATS_ALL); + + ll_req.rxf_id_mask[0] = htonl(bna->rx_mod.rxf_bmap[0]); + ll_req.rxf_id_mask[1] = htonl(bna->rx_mod.rxf_bmap[1]); + ll_req.txf_id_mask[0] = htonl(bna->tx_mod.txf_bmap[0]); + ll_req.txf_id_mask[1] = htonl(bna->tx_mod.txf_bmap[1]); + + ll_req.host_buffer.a32.addr_hi = bna->hw_stats_dma.msb; + ll_req.host_buffer.a32.addr_lo = bna->hw_stats_dma.lsb; + + bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_stats_get, bna); + bna_mbox_send(bna, &bna->mbox_qe); + + bna->stats.rxf_bmap[0] = bna->rx_mod.rxf_bmap[0]; + bna->stats.rxf_bmap[1] = bna->rx_mod.rxf_bmap[1]; + bna->stats.txf_bmap[0] = bna->tx_mod.txf_bmap[0]; + bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1]; +} + +static void +bna_fw_cb_stats_clr(void *arg, int status) +{ + struct bna *bna = (struct bna *)arg; + + bfa_q_qe_init(&bna->mbox_qe.qe); + + memset(bna->stats.sw_stats, 0, sizeof(struct bna_sw_stats)); + memset(bna->stats.hw_stats, 0, sizeof(struct bfi_ll_stats)); + + bnad_cb_stats_clr(bna->bnad); +} + +static void +bna_fw_stats_clr(struct bna *bna) +{ + struct bfi_ll_stats_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); + ll_req.stats_mask = htons(BFI_LL_STATS_ALL); + ll_req.rxf_id_mask[0] = htonl(0xffffffff); + ll_req.rxf_id_mask[1] = htonl(0xffffffff); + ll_req.txf_id_mask[0] = htonl(0xffffffff); + ll_req.txf_id_mask[1] = htonl(0xffffffff); + + bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_stats_clr, bna); + bna_mbox_send(bna, &bna->mbox_qe); +} + +void +bna_stats_get(struct bna *bna) +{ + if (bna_device_status_get(&bna->device)) + bna_fw_stats_get(bna); + else + bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); +} + +void +bna_stats_clr(struct bna *bna) +{ + if (bna_device_status_get(&bna->device)) + bna_fw_stats_clr(bna); + else { + memset(&bna->stats.sw_stats, 0, + sizeof(struct bna_sw_stats)); + memset(bna->stats.hw_stats, 0, + sizeof(struct bfi_ll_stats)); + bnad_cb_stats_clr(bna->bnad); + } +} + +/* IB */ +void +bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo) +{ + ib->ib_config.coalescing_timeo = coalescing_timeo; + + if (ib->start_count) + ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK( + (u32)ib->ib_config.coalescing_timeo, 0); +} + +/* RxF */ +void +bna_rxf_adv_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config) +{ + switch (q_config->rxp_type) { + case BNA_RXP_SINGLE: + /* No-op */ + break; + case BNA_RXP_SLR: + rxf->ctrl_flags |= BNA_RXF_CF_SM_LG_RXQ; + break; + case BNA_RXP_HDS: + rxf->hds_cfg.hdr_type = q_config->hds_config.hdr_type; + rxf->hds_cfg.header_size = + q_config->hds_config.header_size; + rxf->forced_offset = 0; + break; + default: + break; + } + + if (q_config->rss_status == BNA_STATUS_T_ENABLED) { + rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE; + rxf->rss_cfg.hash_type = q_config->rss_config.hash_type; + rxf->rss_cfg.hash_mask = q_config->rss_config.hash_mask; + memcpy(&rxf->rss_cfg.toeplitz_hash_key[0], + &q_config->rss_config.toeplitz_hash_key[0], + sizeof(rxf->rss_cfg.toeplitz_hash_key)); + } +} + +static void +rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status) +{ + struct bfi_ll_rxf_req req; + + bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0); + + req.rxf_id = rxf->rxf_id; + req.enable = status; + + bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req), + rxf_cb_cam_fltr_mbox_cmd, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +void +__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status) +{ + struct bna_rx_fndb_ram *rx_fndb_ram; + u32 ctrl_flags; + int i; + + rx_fndb_ram = (struct bna_rx_fndb_ram *) + BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva, + RX_FNDB_RAM_BASE_OFFSET); + + for (i = 0; i < BFI_MAX_RXF; i++) { + if (status == BNA_STATUS_T_ENABLED) { + if (i == rxf->rxf_id) + continue; + + ctrl_flags = + readl(&rx_fndb_ram[i].control_flags); + ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; + writel(ctrl_flags, + &rx_fndb_ram[i].control_flags); + } else { + ctrl_flags = + readl(&rx_fndb_ram[i].control_flags); + ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; + writel(ctrl_flags, + &rx_fndb_ram[i].control_flags); + } + } +} + +int +rxf_process_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* Add additional MAC entries */ + if (!list_empty(&rxf->ucast_pending_add_q)) { + bfa_q_deq(&rxf->ucast_pending_add_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_ADD_REQ, mac); + list_add_tail(&mac->qe, &rxf->ucast_active_q); + return 1; + } + + /* Delete MAC addresses previousely added */ + if (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* Enable/disable promiscuous mode */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_PROMISC; + + /* Disable VLAN filter to allow all VLANs */ + __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* Enable/disable default mode */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_DEFAULT; + + /* Disable VLAN filter to allow all VLANs */ + __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED); + /* Redirect all other RxF vlan filtering to this one */ + __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* Enable/disable allmulti mode */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_ALLMULTI; + + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* 1. delete pending ucast entries */ + if (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + return 1; + } + + /* 2. clear active ucast entries; move them to pending_add_q */ + if (!list_empty(&rxf->ucast_active_q)) { + bfa_q_deq(&rxf->ucast_active_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + list_add_tail(&mac->qe, &rxf->ucast_pending_add_q); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 6. Execute pending promisc mode disable command */ + if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 7. Clear active promisc mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + /* move promisc configuration from active -> pending */ + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 8. Execute pending default mode disable command */ + if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 9. Clear active default mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + /* move default configuration from active -> pending */ + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* 10. Execute pending allmulti mode disable command */ + if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 11. Clear active allmulti mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + /* move allmulti configuration from active -> pending */ + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +void +rxf_reset_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct list_head *qe; + struct bna_mac *mac; + + /* 1. Move active ucast entries to pending_add_q */ + while (!list_empty(&rxf->ucast_active_q)) { + bfa_q_deq(&rxf->ucast_active_q, &qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->ucast_pending_add_q); + } + + /* 2. Throw away delete pending ucast entries */ + while (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + } +} + +void +rxf_reset_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 6. Clear pending promisc mode disable */ + if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + } + + /* 7. Move promisc mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + } + +} + +void +rxf_reset_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 8. Clear pending default mode disable */ + if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + } + + /* 9. Move default mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + } +} + +void +rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* 10. Clear pending allmulti mode disable */ + if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + } + + /* 11. Move allmulti mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + } +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_promisc_enable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_PROMISC)) { + /* Schedule enable */ + } else { + /* Promisc mode should not be active in the system */ + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + bna->rxf_promisc_id = rxf->rxf_id; + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_promisc_disable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Promisc mode should not be active */ + /* system promisc state should be pending */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + /* Remove the promisc state from the system */ + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + /* Promisc mode should be active in the system */ + promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + + /* Do nothing if already disabled */ + } else { + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_default_enable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) { + /* Schedule enable */ + } else { + /* Default mode should not be active in the system */ + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + bna->rxf_default_id = rxf->rxf_id; + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_default_disable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Promisc mode should not be active */ + /* system default state should be pending */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + /* Remove the default state from the system */ + bna->rxf_default_id = BFI_MAX_RXF; + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + /* Default mode should be active in the system */ + default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + + /* Do nothing if already disabled */ + } else { + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_allmulti_enable(struct bna_rxf *rxf) +{ + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) { + /* Schedule enable */ + } else { + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +int +rxf_allmulti_disable(struct bna_rxf *rxf) +{ + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Allmulti mode should not be active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + } + + return ret; +} + +/* RxF <- bnad */ +void +bna_rx_mcast_delall(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + int need_hw_config = 0; + + /* Purge all entries from pending_add_q */ + while (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } + + /* Schedule all entries in active_q for deletion */ + while (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + list_add_tail(&mac->qe, &rxf->mcast_pending_del_q); + need_hw_config = 1; + } + + if (need_hw_config) { + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + return; + } + + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); +} + +/* RxF <- Rx */ +void +bna_rx_receive_resume(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) { + rxf->oper_state_cbfn = cbfn; + rxf->oper_state_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_RESUME); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); +} + +void +bna_rx_receive_pause(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_RUNNING) { + rxf->oper_state_cbfn = cbfn; + rxf->oper_state_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_PAUSE); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); +} + +/* RxF <- bnad */ +enum bna_cb_status +bna_rx_ucast_add(struct bna_rx *rx, u8 *addr, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + + /* Check if already added */ + list_for_each(qe, &rxf->ucast_active_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + /* Check if pending addition */ + list_for_each(qe, &rxf->ucast_pending_add_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + mac = bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod); + if (mac == NULL) + return BNA_CB_UCAST_CAM_FULL; + bfa_q_qe_init(&mac->qe); + memcpy(mac->addr, addr, ETH_ALEN); + list_add_tail(&mac->qe, &rxf->ucast_pending_add_q); + + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + + return BNA_CB_SUCCESS; +} + +/* RxF <- bnad */ +enum bna_cb_status +bna_rx_ucast_del(struct bna_rx *rx, u8 *addr, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + + list_for_each(qe, &rxf->ucast_pending_add_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + list_del(qe); + bfa_q_qe_init(qe); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + list_for_each(qe, &rxf->ucast_active_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + list_del(qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->ucast_pending_del_q); + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + return BNA_CB_SUCCESS; + } + } + + return BNA_CB_INVALID_MAC; +} + +/* RxF <- bnad */ +enum bna_cb_status +bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode, + enum bna_rxmode bitmask, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + int need_hw_config = 0; + + /* Error checks */ + + if (is_promisc_enable(new_mode, bitmask)) { + /* If promisc mode is already enabled elsewhere in the system */ + if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) && + (rx->bna->rxf_promisc_id != rxf->rxf_id)) + goto err_return; + + /* If default mode is already enabled in the system */ + if (rx->bna->rxf_default_id != BFI_MAX_RXF) + goto err_return; + + /* Trying to enable promiscuous and default mode together */ + if (is_default_enable(new_mode, bitmask)) + goto err_return; + } + + if (is_default_enable(new_mode, bitmask)) { + /* If default mode is already enabled elsewhere in the system */ + if ((rx->bna->rxf_default_id != BFI_MAX_RXF) && + (rx->bna->rxf_default_id != rxf->rxf_id)) { + goto err_return; + } + + /* If promiscuous mode is already enabled in the system */ + if (rx->bna->rxf_promisc_id != BFI_MAX_RXF) + goto err_return; + } + + /* Process the commands */ + + if (is_promisc_enable(new_mode, bitmask)) { + if (rxf_promisc_enable(rxf)) + need_hw_config = 1; + } else if (is_promisc_disable(new_mode, bitmask)) { + if (rxf_promisc_disable(rxf)) + need_hw_config = 1; + } + + if (is_default_enable(new_mode, bitmask)) { + if (rxf_default_enable(rxf)) + need_hw_config = 1; + } else if (is_default_disable(new_mode, bitmask)) { + if (rxf_default_disable(rxf)) + need_hw_config = 1; + } + + if (is_allmulti_enable(new_mode, bitmask)) { + if (rxf_allmulti_enable(rxf)) + need_hw_config = 1; + } else if (is_allmulti_disable(new_mode, bitmask)) { + if (rxf_allmulti_disable(rxf)) + need_hw_config = 1; + } + + /* Trigger h/w if needed */ + + if (need_hw_config) { + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + + return BNA_CB_SUCCESS; + +err_return: + return BNA_CB_FAIL; +} + +/* RxF <- bnad */ +void +bna_rx_rss_enable(struct bna_rx *rx) +{ + struct bna_rxf *rxf = &rx->rxf; + + rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; + rxf->rss_status = BNA_STATUS_T_ENABLED; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); +} + +/* RxF <- bnad */ +void +bna_rx_rss_disable(struct bna_rx *rx) +{ + struct bna_rxf *rxf = &rx->rxf; + + rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; + rxf->rss_status = BNA_STATUS_T_DISABLED; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); +} + +/* RxF <- bnad */ +void +bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config) +{ + struct bna_rxf *rxf = &rx->rxf; + rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; + rxf->rss_status = BNA_STATUS_T_ENABLED; + rxf->rss_cfg = *rss_config; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); +} + +void +/* RxF <- bnad */ +bna_rx_vlanfilter_enable(struct bna_rx *rx) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + rxf->vlan_filter_status = BNA_STATUS_T_ENABLED; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +/* RxF <- bnad */ +void +bna_rx_vlanfilter_disable(struct bna_rx *rx) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + rxf->vlan_filter_status = BNA_STATUS_T_DISABLED; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +/* Rx */ + +struct bna_rxp * +bna_rx_get_rxp(struct bna_rx *rx, int vector) +{ + struct bna_rxp *rxp; + struct list_head *qe; + + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + if (rxp->vector == vector) + return rxp; + } + return NULL; +} + +/* + * bna_rx_rss_rit_set() + * Sets the Q ids for the specified msi-x vectors in the RIT. + * Maximum rit size supported is 64, which should be the max size of the + * vectors array. + */ + +void +bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors, int nvectors) +{ + int i; + struct bna_rxp *rxp; + struct bna_rxq *q0 = NULL, *q1 = NULL; + struct bna *bna; + struct bna_rxf *rxf; + + /* Build the RIT contents for this RX */ + bna = rx->bna; + + rxf = &rx->rxf; + for (i = 0; i < nvectors; i++) { + rxp = bna_rx_get_rxp(rx, vectors[i]); + + GET_RXQS(rxp, q0, q1); + rxf->rit_segment->rit[i].large_rxq_id = q0->rxq_id; + rxf->rit_segment->rit[i].small_rxq_id = (q1 ? q1->rxq_id : 0); + } + + rxf->rit_segment->rit_size = nvectors; + + /* Subsequent call to enable/reconfig RSS will update the RIT in h/w */ +} + +/* Rx <- bnad */ +void +bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo) +{ + struct bna_rxp *rxp; + struct list_head *qe; + + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo; + bna_ib_coalescing_timeo_set(rxp->cq.ib, coalescing_timeo); + } +} + +/* Rx <- bnad */ +void +bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX]) +{ + int i, j; + + for (i = 0; i < BNA_LOAD_T_MAX; i++) + for (j = 0; j < BNA_BIAS_T_MAX; j++) + bna->rx_mod.dim_vector[i][j] = vector[i][j]; +} + +/* Rx <- bnad */ +void +bna_rx_dim_update(struct bna_ccb *ccb) +{ + struct bna *bna = ccb->cq->rx->bna; + u32 load, bias; + u32 pkt_rt, small_rt, large_rt; + u8 coalescing_timeo; + + if ((ccb->pkt_rate.small_pkt_cnt == 0) && + (ccb->pkt_rate.large_pkt_cnt == 0)) + return; + + /* Arrive at preconfigured coalescing timeo value based on pkt rate */ + + small_rt = ccb->pkt_rate.small_pkt_cnt; + large_rt = ccb->pkt_rate.large_pkt_cnt; + + pkt_rt = small_rt + large_rt; + + if (pkt_rt < BNA_PKT_RATE_10K) + load = BNA_LOAD_T_LOW_4; + else if (pkt_rt < BNA_PKT_RATE_20K) + load = BNA_LOAD_T_LOW_3; + else if (pkt_rt < BNA_PKT_RATE_30K) + load = BNA_LOAD_T_LOW_2; + else if (pkt_rt < BNA_PKT_RATE_40K) + load = BNA_LOAD_T_LOW_1; + else if (pkt_rt < BNA_PKT_RATE_50K) + load = BNA_LOAD_T_HIGH_1; + else if (pkt_rt < BNA_PKT_RATE_60K) + load = BNA_LOAD_T_HIGH_2; + else if (pkt_rt < BNA_PKT_RATE_80K) + load = BNA_LOAD_T_HIGH_3; + else + load = BNA_LOAD_T_HIGH_4; + + if (small_rt > (large_rt << 1)) + bias = 0; + else + bias = 1; + + ccb->pkt_rate.small_pkt_cnt = 0; + ccb->pkt_rate.large_pkt_cnt = 0; + + coalescing_timeo = bna->rx_mod.dim_vector[load][bias]; + ccb->rx_coalescing_timeo = coalescing_timeo; + + /* Set it to IB */ + bna_ib_coalescing_timeo_set(ccb->cq->ib, coalescing_timeo); +} + +/* Tx */ +/* TX <- bnad */ +enum bna_cb_status +bna_tx_prio_set(struct bna_tx *tx, int prio, + void (*cbfn)(struct bnad *, struct bna_tx *, + enum bna_cb_status)) +{ + if (tx->flags & BNA_TX_F_PRIO_LOCK) + return BNA_CB_FAIL; + else { + tx->prio_change_cbfn = cbfn; + bna_tx_prio_changed(tx, prio); + } + + return BNA_CB_SUCCESS; +} + +/* TX <- bnad */ +void +bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_coalescing_timeo_set(txq->ib, coalescing_timeo); + } +} + +/* + * Private data + */ + +struct bna_ritseg_pool_cfg { + u32 pool_size; + u32 pool_entry_size; +}; +init_ritseg_pool(ritseg_pool_cfg); + +/* + * Private functions + */ +static void +bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + ucam_mod->ucmac = (struct bna_mac *) + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&ucam_mod->free_q); + for (i = 0; i < BFI_MAX_UCMAC; i++) { + bfa_q_qe_init(&ucam_mod->ucmac[i].qe); + list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q); + } + + ucam_mod->bna = bna; +} + +static void +bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod) +{ + struct list_head *qe; + int i = 0; + + list_for_each(qe, &ucam_mod->free_q) + i++; + + ucam_mod->bna = NULL; +} + +static void +bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + mcam_mod->mcmac = (struct bna_mac *) + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&mcam_mod->free_q); + for (i = 0; i < BFI_MAX_MCMAC; i++) { + bfa_q_qe_init(&mcam_mod->mcmac[i].qe); + list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q); + } + + mcam_mod->bna = bna; +} + +static void +bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod) +{ + struct list_head *qe; + int i = 0; + + list_for_each(qe, &mcam_mod->free_q) + i++; + + mcam_mod->bna = NULL; +} + +static void +bna_rit_mod_init(struct bna_rit_mod *rit_mod, + struct bna_res_info *res_info) +{ + int i; + int j; + int count; + int offset; + + rit_mod->rit = (struct bna_rit_entry *) + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mdl[0].kva; + rit_mod->rit_segment = (struct bna_rit_segment *) + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mdl[0].kva; + + count = 0; + offset = 0; + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + INIT_LIST_HEAD(&rit_mod->rit_seg_pool[i]); + for (j = 0; j < ritseg_pool_cfg[i].pool_size; j++) { + bfa_q_qe_init(&rit_mod->rit_segment[count].qe); + rit_mod->rit_segment[count].max_rit_size = + ritseg_pool_cfg[i].pool_entry_size; + rit_mod->rit_segment[count].rit_offset = offset; + rit_mod->rit_segment[count].rit = + &rit_mod->rit[offset]; + list_add_tail(&rit_mod->rit_segment[count].qe, + &rit_mod->rit_seg_pool[i]); + count++; + offset += ritseg_pool_cfg[i].pool_entry_size; + } + } +} + +static void +bna_rit_mod_uninit(struct bna_rit_mod *rit_mod) +{ + struct bna_rit_segment *rit_segment; + struct list_head *qe; + int i; + int j; + + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + j = 0; + list_for_each(qe, &rit_mod->rit_seg_pool[i]) { + rit_segment = (struct bna_rit_segment *)qe; + j++; + } + } +} + +/* + * Public functions + */ + +/* Called during probe(), before calling bna_init() */ +void +bna_res_req(struct bna_res_info *res_info) +{ + bna_adv_res_req(res_info); + + /* DMA memory for retrieving IOC attributes */ + res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len = + ALIGN(bfa_ioc_meminfo(), PAGE_SIZE); + + /* DMA memory for index segment of an IB */ + res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.len = + BFI_IBIDX_SIZE * BFI_IBIDX_MAX_SEGSIZE; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.num = BFI_MAX_IB; + + /* Virtual memory for IB objects - stored by IB module */ + res_info[BNA_RES_MEM_T_IB_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.len = + BFI_MAX_IB * sizeof(struct bna_ib); + + /* Virtual memory for intr objects - stored by IB module */ + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.len = + BFI_MAX_IB * sizeof(struct bna_intr); + + /* Virtual memory for idx_seg objects - stored by IB module */ + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.len = + BFI_IBIDX_TOTAL_SEGS * sizeof(struct bna_ibidx_seg); + + /* Virtual memory for Tx objects - stored by Tx module */ + res_info[BNA_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.len = + BFI_MAX_TXQ * sizeof(struct bna_tx); + + /* Virtual memory for TxQ - stored by Tx module */ + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len = + BFI_MAX_TXQ * sizeof(struct bna_txq); + + /* Virtual memory for Rx objects - stored by Rx module */ + res_info[BNA_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rx); + + /* Virtual memory for RxPath - stored by Rx module */ + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rxp); + + /* Virtual memory for RxQ - stored by Rx module */ + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rxq); + + /* Virtual memory for Unicast MAC address - stored by ucam module */ + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len = + BFI_MAX_UCMAC * sizeof(struct bna_mac); + + /* Virtual memory for Multicast MAC address - stored by mcam module */ + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len = + BFI_MAX_MCMAC * sizeof(struct bna_mac); + + /* Virtual memory for RIT entries */ + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.len = + BFI_MAX_RIT_SIZE * sizeof(struct bna_rit_entry); + + /* Virtual memory for RIT segment table */ + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.len = + BFI_RIT_TOTAL_SEGS * sizeof(struct bna_rit_segment); + + /* Interrupt resource for mailbox interrupt */ + res_info[BNA_RES_INTR_T_MBOX].res_type = BNA_RES_T_INTR; + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type = + BNA_INTR_T_MSIX; + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.num = 1; +} + +/* Called during probe() */ +void +bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev, + struct bna_res_info *res_info) +{ + bna->bnad = bnad; + bna->pcidev = *pcidev; + + bna->stats.hw_stats = (struct bfi_ll_stats *) + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva; + bna->hw_stats_dma.msb = + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb; + bna->hw_stats_dma.lsb = + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb; + bna->stats.sw_stats = (struct bna_sw_stats *) + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mdl[0].kva; + + bna->regs.page_addr = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].page_addr; + bna->regs.fn_int_status = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].fn_int_status; + bna->regs.fn_int_mask = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].fn_int_mask; + + if (bna->pcidev.pci_func < 3) + bna->port_num = 0; + else + bna->port_num = 1; + + /* Also initializes diag, cee, sfp, phy_port and mbox_mod */ + bna_device_init(&bna->device, bna, res_info); + + bna_port_init(&bna->port, bna); + + bna_tx_mod_init(&bna->tx_mod, bna, res_info); + + bna_rx_mod_init(&bna->rx_mod, bna, res_info); + + bna_ib_mod_init(&bna->ib_mod, bna, res_info); + + bna_rit_mod_init(&bna->rit_mod, res_info); + + bna_ucam_mod_init(&bna->ucam_mod, bna, res_info); + + bna_mcam_mod_init(&bna->mcam_mod, bna, res_info); + + bna->rxf_default_id = BFI_MAX_RXF; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Mbox q element for posting stat request to f/w */ + bfa_q_qe_init(&bna->mbox_qe.qe); +} + +void +bna_uninit(struct bna *bna) +{ + bna_mcam_mod_uninit(&bna->mcam_mod); + + bna_ucam_mod_uninit(&bna->ucam_mod); + + bna_rit_mod_uninit(&bna->rit_mod); + + bna_ib_mod_uninit(&bna->ib_mod); + + bna_rx_mod_uninit(&bna->rx_mod); + + bna_tx_mod_uninit(&bna->tx_mod); + + bna_port_uninit(&bna->port); + + bna_device_uninit(&bna->device); + + bna->bnad = NULL; +} + +struct bna_mac * +bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod) +{ + struct list_head *qe; + + if (list_empty(&ucam_mod->free_q)) + return NULL; + + bfa_q_deq(&ucam_mod->free_q, &qe); + + return (struct bna_mac *)qe; +} + +void +bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac) +{ + list_add_tail(&mac->qe, &ucam_mod->free_q); +} + +struct bna_mac * +bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod) +{ + struct list_head *qe; + + if (list_empty(&mcam_mod->free_q)) + return NULL; + + bfa_q_deq(&mcam_mod->free_q, &qe); + + return (struct bna_mac *)qe; +} + +void +bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac) +{ + list_add_tail(&mac->qe, &mcam_mod->free_q); +} + +/** + * Note: This should be called in the same locking context as the call to + * bna_rit_mod_seg_get() + */ +int +bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size) +{ + int i; + + /* Select the pool for seg_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg_size <= ritseg_pool_cfg[i].pool_entry_size) + break; + } + + if (i == BFI_RIT_SEG_TOTAL_POOLS) + return 0; + + if (list_empty(&rit_mod->rit_seg_pool[i])) + return 0; + + return 1; +} + +struct bna_rit_segment * +bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size) +{ + struct bna_rit_segment *seg; + struct list_head *qe; + int i; + + /* Select the pool for seg_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg_size <= ritseg_pool_cfg[i].pool_entry_size) + break; + } + + if (i == BFI_RIT_SEG_TOTAL_POOLS) + return NULL; + + if (list_empty(&rit_mod->rit_seg_pool[i])) + return NULL; + + bfa_q_deq(&rit_mod->rit_seg_pool[i], &qe); + seg = (struct bna_rit_segment *)qe; + bfa_q_qe_init(&seg->qe); + seg->rit_size = seg_size; + + return seg; +} + +void +bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod, + struct bna_rit_segment *seg) +{ + int i; + + /* Select the pool for seg->max_rit_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg->max_rit_size == ritseg_pool_cfg[i].pool_entry_size) + break; + } + + seg->rit_size = 0; + list_add_tail(&seg->qe, &rit_mod->rit_seg_pool[i]); +} diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h new file mode 100644 index 000000000000..67eb376c5c7e --- /dev/null +++ b/drivers/net/bna/bna_hw.h @@ -0,0 +1,1491 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + * + * File for interrupt macros and functions + */ + +#ifndef __BNA_HW_H__ +#define __BNA_HW_H__ + +#include "bfi_ctreg.h" + +/** + * + * SW imposed limits + * + */ + +#ifndef BNA_BIOS_BUILD + +#define BFI_MAX_TXQ 64 +#define BFI_MAX_RXQ 64 +#define BFI_MAX_RXF 64 +#define BFI_MAX_IB 128 +#define BFI_MAX_RIT_SIZE 256 +#define BFI_RSS_RIT_SIZE 64 +#define BFI_NONRSS_RIT_SIZE 1 +#define BFI_MAX_UCMAC 256 +#define BFI_MAX_MCMAC 512 +#define BFI_IBIDX_SIZE 4 +#define BFI_MAX_VLAN 4095 + +/** + * There are 2 free IB index pools: + * pool1: 120 segments of 1 index each + * pool8: 1 segment of 8 indexes + */ +#define BFI_IBIDX_POOL1_SIZE 116 +#define BFI_IBIDX_POOL1_ENTRY_SIZE 1 +#define BFI_IBIDX_POOL2_SIZE 2 +#define BFI_IBIDX_POOL2_ENTRY_SIZE 2 +#define BFI_IBIDX_POOL8_SIZE 1 +#define BFI_IBIDX_POOL8_ENTRY_SIZE 8 +#define BFI_IBIDX_TOTAL_POOLS 3 +#define BFI_IBIDX_TOTAL_SEGS 119 /* (POOL1 + POOL2 + POOL8)_SIZE */ +#define BFI_IBIDX_MAX_SEGSIZE 8 +#define init_ibidx_pool(name) \ +static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \ +{ \ + { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE }, \ + { BFI_IBIDX_POOL2_SIZE, BFI_IBIDX_POOL2_ENTRY_SIZE }, \ + { BFI_IBIDX_POOL8_SIZE, BFI_IBIDX_POOL8_ENTRY_SIZE } \ +} + +/** + * There are 2 free RIT segment pools: + * Pool1: 192 segments of 1 RIT entry each + * Pool2: 1 segment of 64 RIT entry + */ +#define BFI_RIT_SEG_POOL1_SIZE 192 +#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1 +#define BFI_RIT_SEG_POOLRSS_SIZE 1 +#define BFI_RIT_SEG_POOLRSS_ENTRY_SIZE 64 +#define BFI_RIT_SEG_TOTAL_POOLS 2 +#define BFI_RIT_TOTAL_SEGS 193 /* POOL1_SIZE + POOLRSS_SIZE */ +#define init_ritseg_pool(name) \ +static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \ +{ \ + { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE }, \ + { BFI_RIT_SEG_POOLRSS_SIZE, BFI_RIT_SEG_POOLRSS_ENTRY_SIZE } \ +} + +#else /* BNA_BIOS_BUILD */ + +#define BFI_MAX_TXQ 1 +#define BFI_MAX_RXQ 1 +#define BFI_MAX_RXF 1 +#define BFI_MAX_IB 2 +#define BFI_MAX_RIT_SIZE 2 +#define BFI_RSS_RIT_SIZE 64 +#define BFI_NONRSS_RIT_SIZE 1 +#define BFI_MAX_UCMAC 1 +#define BFI_MAX_MCMAC 8 +#define BFI_IBIDX_SIZE 4 +#define BFI_MAX_VLAN 4095 +/* There is one free pool: 2 segments of 1 index each */ +#define BFI_IBIDX_POOL1_SIZE 2 +#define BFI_IBIDX_POOL1_ENTRY_SIZE 1 +#define BFI_IBIDX_TOTAL_POOLS 1 +#define BFI_IBIDX_TOTAL_SEGS 2 /* POOL1_SIZE */ +#define BFI_IBIDX_MAX_SEGSIZE 1 +#define init_ibidx_pool(name) \ +static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \ +{ \ + { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE } \ +} + +#define BFI_RIT_SEG_POOL1_SIZE 1 +#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1 +#define BFI_RIT_SEG_TOTAL_POOLS 1 +#define BFI_RIT_TOTAL_SEGS 1 /* POOL1_SIZE */ +#define init_ritseg_pool(name) \ +static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \ +{ \ + { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE } \ +} + +#endif /* BNA_BIOS_BUILD */ + +#define BFI_RSS_HASH_KEY_LEN 10 + +#define BFI_COALESCING_TIMER_UNIT 5 /* 5us */ +#define BFI_MAX_COALESCING_TIMEO 0xFF /* in 5us units */ +#define BFI_MAX_INTERPKT_COUNT 0xFF +#define BFI_MAX_INTERPKT_TIMEO 0xF /* in 0.5us units */ +#define BFI_TX_COALESCING_TIMEO 20 /* 20 * 5 = 100us */ +#define BFI_TX_INTERPKT_COUNT 32 +#define BFI_RX_COALESCING_TIMEO 12 /* 12 * 5 = 60us */ +#define BFI_RX_INTERPKT_COUNT 6 /* Pkt Cnt = 6 */ +#define BFI_RX_INTERPKT_TIMEO 3 /* 3 * 0.5 = 1.5us */ + +#define BFI_TXQ_WI_SIZE 64 /* bytes */ +#define BFI_RXQ_WI_SIZE 8 /* bytes */ +#define BFI_CQ_WI_SIZE 16 /* bytes */ +#define BFI_TX_MAX_WRR_QUOTA 0xFFF + +#define BFI_TX_MAX_VECTORS_PER_WI 4 +#define BFI_TX_MAX_VECTORS_PER_PKT 0xFF +#define BFI_TX_MAX_DATA_PER_VECTOR 0xFFFF +#define BFI_TX_MAX_DATA_PER_PKT 0xFFFFFF + +/* Small Q buffer size */ +#define BFI_SMALL_RXBUF_SIZE 128 + +/* Defined separately since BFA_FLASH_DMA_BUF_SZ is in bfa_flash.c */ +#define BFI_FLASH_DMA_BUF_SZ 0x010000 /* 64K DMA */ +#define BFI_HW_STATS_SIZE 0x4000 /* 16K DMA */ + +/** + * + * HW register offsets, macros + * + */ + +/* DMA Block Register Host Window Start Address */ +#define DMA_BLK_REG_ADDR 0x00013000 + +/* DMA Block Internal Registers */ +#define DMA_CTRL_REG0 (DMA_BLK_REG_ADDR + 0x000) +#define DMA_CTRL_REG1 (DMA_BLK_REG_ADDR + 0x004) +#define DMA_ERR_INT_STATUS (DMA_BLK_REG_ADDR + 0x008) +#define DMA_ERR_INT_ENABLE (DMA_BLK_REG_ADDR + 0x00c) +#define DMA_ERR_INT_STATUS_SET (DMA_BLK_REG_ADDR + 0x010) + +/* APP Block Register Address Offset from BAR0 */ +#define APP_BLK_REG_ADDR 0x00014000 + +/* Host Function Interrupt Mask Registers */ +#define HOSTFN0_INT_MASK (APP_BLK_REG_ADDR + 0x004) +#define HOSTFN1_INT_MASK (APP_BLK_REG_ADDR + 0x104) +#define HOSTFN2_INT_MASK (APP_BLK_REG_ADDR + 0x304) +#define HOSTFN3_INT_MASK (APP_BLK_REG_ADDR + 0x404) + +/** + * Host Function PCIe Error Registers + * Duplicates "Correctable" & "Uncorrectable" + * registers in PCIe Config space. + */ +#define FN0_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x014) +#define FN1_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x114) +#define FN2_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x314) +#define FN3_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x414) + +/* Host Function Error Type Status Registers */ +#define FN0_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x018) +#define FN1_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x118) +#define FN2_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x318) +#define FN3_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x418) + +/* Host Function Error Type Mask Registers */ +#define FN0_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x01c) +#define FN1_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x11c) +#define FN2_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x31c) +#define FN3_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x41c) + +/* Catapult Host Semaphore Status Registers (App block) */ +#define HOST_SEM_STS0_REG (APP_BLK_REG_ADDR + 0x630) +#define HOST_SEM_STS1_REG (APP_BLK_REG_ADDR + 0x634) +#define HOST_SEM_STS2_REG (APP_BLK_REG_ADDR + 0x638) +#define HOST_SEM_STS3_REG (APP_BLK_REG_ADDR + 0x63c) +#define HOST_SEM_STS4_REG (APP_BLK_REG_ADDR + 0x640) +#define HOST_SEM_STS5_REG (APP_BLK_REG_ADDR + 0x644) +#define HOST_SEM_STS6_REG (APP_BLK_REG_ADDR + 0x648) +#define HOST_SEM_STS7_REG (APP_BLK_REG_ADDR + 0x64c) + +/* PCIe Misc Register */ +#define PCIE_MISC_REG (APP_BLK_REG_ADDR + 0x200) + +/* Temp Sensor Control Registers */ +#define TEMPSENSE_CNTL_REG (APP_BLK_REG_ADDR + 0x250) +#define TEMPSENSE_STAT_REG (APP_BLK_REG_ADDR + 0x254) + +/* APP Block local error registers */ +#define APP_LOCAL_ERR_STAT (APP_BLK_REG_ADDR + 0x258) +#define APP_LOCAL_ERR_MSK (APP_BLK_REG_ADDR + 0x25c) + +/* PCIe Link Error registers */ +#define PCIE_LNK_ERR_STAT (APP_BLK_REG_ADDR + 0x260) +#define PCIE_LNK_ERR_MSK (APP_BLK_REG_ADDR + 0x264) + +/** + * FCoE/FIP Ethertype Register + * 31:16 -- Chip wide value for FIP type + * 15:0 -- Chip wide value for FCoE type + */ +#define FCOE_FIP_ETH_TYPE (APP_BLK_REG_ADDR + 0x280) + +/** + * Reserved Ethertype Register + * 31:16 -- Reserved + * 15:0 -- Other ethertype + */ +#define RESV_ETH_TYPE (APP_BLK_REG_ADDR + 0x284) + +/** + * Host Command Status Registers + * Each set consists of 3 registers : + * clear, set, cmd + * 16 such register sets in all + * See catapult_spec.pdf for detailed functionality + * Put each type in a single macro accessed by _num ? + */ +#define HOST_CMDSTS0_CLR_REG (APP_BLK_REG_ADDR + 0x500) +#define HOST_CMDSTS0_SET_REG (APP_BLK_REG_ADDR + 0x504) +#define HOST_CMDSTS0_REG (APP_BLK_REG_ADDR + 0x508) +#define HOST_CMDSTS1_CLR_REG (APP_BLK_REG_ADDR + 0x510) +#define HOST_CMDSTS1_SET_REG (APP_BLK_REG_ADDR + 0x514) +#define HOST_CMDSTS1_REG (APP_BLK_REG_ADDR + 0x518) +#define HOST_CMDSTS2_CLR_REG (APP_BLK_REG_ADDR + 0x520) +#define HOST_CMDSTS2_SET_REG (APP_BLK_REG_ADDR + 0x524) +#define HOST_CMDSTS2_REG (APP_BLK_REG_ADDR + 0x528) +#define HOST_CMDSTS3_CLR_REG (APP_BLK_REG_ADDR + 0x530) +#define HOST_CMDSTS3_SET_REG (APP_BLK_REG_ADDR + 0x534) +#define HOST_CMDSTS3_REG (APP_BLK_REG_ADDR + 0x538) +#define HOST_CMDSTS4_CLR_REG (APP_BLK_REG_ADDR + 0x540) +#define HOST_CMDSTS4_SET_REG (APP_BLK_REG_ADDR + 0x544) +#define HOST_CMDSTS4_REG (APP_BLK_REG_ADDR + 0x548) +#define HOST_CMDSTS5_CLR_REG (APP_BLK_REG_ADDR + 0x550) +#define HOST_CMDSTS5_SET_REG (APP_BLK_REG_ADDR + 0x554) +#define HOST_CMDSTS5_REG (APP_BLK_REG_ADDR + 0x558) +#define HOST_CMDSTS6_CLR_REG (APP_BLK_REG_ADDR + 0x560) +#define HOST_CMDSTS6_SET_REG (APP_BLK_REG_ADDR + 0x564) +#define HOST_CMDSTS6_REG (APP_BLK_REG_ADDR + 0x568) +#define HOST_CMDSTS7_CLR_REG (APP_BLK_REG_ADDR + 0x570) +#define HOST_CMDSTS7_SET_REG (APP_BLK_REG_ADDR + 0x574) +#define HOST_CMDSTS7_REG (APP_BLK_REG_ADDR + 0x578) +#define HOST_CMDSTS8_CLR_REG (APP_BLK_REG_ADDR + 0x580) +#define HOST_CMDSTS8_SET_REG (APP_BLK_REG_ADDR + 0x584) +#define HOST_CMDSTS8_REG (APP_BLK_REG_ADDR + 0x588) +#define HOST_CMDSTS9_CLR_REG (APP_BLK_REG_ADDR + 0x590) +#define HOST_CMDSTS9_SET_REG (APP_BLK_REG_ADDR + 0x594) +#define HOST_CMDSTS9_REG (APP_BLK_REG_ADDR + 0x598) +#define HOST_CMDSTS10_CLR_REG (APP_BLK_REG_ADDR + 0x5A0) +#define HOST_CMDSTS10_SET_REG (APP_BLK_REG_ADDR + 0x5A4) +#define HOST_CMDSTS10_REG (APP_BLK_REG_ADDR + 0x5A8) +#define HOST_CMDSTS11_CLR_REG (APP_BLK_REG_ADDR + 0x5B0) +#define HOST_CMDSTS11_SET_REG (APP_BLK_REG_ADDR + 0x5B4) +#define HOST_CMDSTS11_REG (APP_BLK_REG_ADDR + 0x5B8) +#define HOST_CMDSTS12_CLR_REG (APP_BLK_REG_ADDR + 0x5C0) +#define HOST_CMDSTS12_SET_REG (APP_BLK_REG_ADDR + 0x5C4) +#define HOST_CMDSTS12_REG (APP_BLK_REG_ADDR + 0x5C8) +#define HOST_CMDSTS13_CLR_REG (APP_BLK_REG_ADDR + 0x5D0) +#define HOST_CMDSTS13_SET_REG (APP_BLK_REG_ADDR + 0x5D4) +#define HOST_CMDSTS13_REG (APP_BLK_REG_ADDR + 0x5D8) +#define HOST_CMDSTS14_CLR_REG (APP_BLK_REG_ADDR + 0x5E0) +#define HOST_CMDSTS14_SET_REG (APP_BLK_REG_ADDR + 0x5E4) +#define HOST_CMDSTS14_REG (APP_BLK_REG_ADDR + 0x5E8) +#define HOST_CMDSTS15_CLR_REG (APP_BLK_REG_ADDR + 0x5F0) +#define HOST_CMDSTS15_SET_REG (APP_BLK_REG_ADDR + 0x5F4) +#define HOST_CMDSTS15_REG (APP_BLK_REG_ADDR + 0x5F8) + +/** + * LPU0 Block Register Address Offset from BAR0 + * Range 0x18000 - 0x18033 + */ +#define LPU0_BLK_REG_ADDR 0x00018000 + +/** + * LPU0 Registers + * Should they be directly used from host, + * except for diagnostics ? + * CTL_REG : Control register + * CMD_REG : Triggers exec. of cmd. in + * Mailbox memory + */ +#define LPU0_MBOX_CTL_REG (LPU0_BLK_REG_ADDR + 0x000) +#define LPU0_MBOX_CMD_REG (LPU0_BLK_REG_ADDR + 0x004) +#define LPU0_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x008) +#define LPU1_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x00c) +#define LPU0_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x010) +#define LPU1_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x014) +#define LPU0_ERR_STATUS_REG (LPU0_BLK_REG_ADDR + 0x018) +#define LPU0_ERR_SET_REG (LPU0_BLK_REG_ADDR + 0x020) + +/** + * LPU1 Block Register Address Offset from BAR0 + * Range 0x18400 - 0x18433 + */ +#define LPU1_BLK_REG_ADDR 0x00018400 + +/** + * LPU1 Registers + * Same as LPU0 registers above + */ +#define LPU1_MBOX_CTL_REG (LPU1_BLK_REG_ADDR + 0x000) +#define LPU1_MBOX_CMD_REG (LPU1_BLK_REG_ADDR + 0x004) +#define LPU0_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x008) +#define LPU1_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x00c) +#define LPU0_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x010) +#define LPU1_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x014) +#define LPU1_ERR_STATUS_REG (LPU1_BLK_REG_ADDR + 0x018) +#define LPU1_ERR_SET_REG (LPU1_BLK_REG_ADDR + 0x020) + +/** + * PSS Block Register Address Offset from BAR0 + * Range 0x18800 - 0x188DB + */ +#define PSS_BLK_REG_ADDR 0x00018800 + +/** + * PSS Registers + * For details, see catapult_spec.pdf + * ERR_STATUS_REG : Indicates error in PSS module + * RAM_ERR_STATUS_REG : Indicates RAM module that detected error + */ +#define ERR_STATUS_SET (PSS_BLK_REG_ADDR + 0x018) +#define PSS_RAM_ERR_STATUS_REG (PSS_BLK_REG_ADDR + 0x01C) + +/** + * PSS Semaphore Lock Registers, total 16 + * First read when unlocked returns 0, + * and is set to 1, atomically. + * Subsequent reads returns 1. + * To clear set the value to 0. + * Range : 0x20 to 0x5c + */ +#define PSS_SEM_LOCK_REG(_num) \ + (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +/** + * PSS Semaphore Status Registers, + * corresponding to the lock registers above + */ +#define PSS_SEM_STATUS_REG(_num) \ + (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2)) + +/** + * Catapult CPQ Registers + * Defines for Mailbox Registers + * Used to send mailbox commands to firmware from + * host. The data part is written to the MBox + * memory, registers are used to indicate that + * a commnad is resident in memory. + * + * Note : LPU0<->LPU1 mailboxes are not listed here + */ +#define CPQ_BLK_REG_ADDR 0x00019000 + +#define HOSTFN0_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x130) +#define HOSTFN0_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x134) +#define LPU0_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x138) +#define LPU1_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x13C) + +#define HOSTFN1_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x140) +#define HOSTFN1_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x144) +#define LPU0_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x148) +#define LPU1_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x14C) + +#define HOSTFN2_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x170) +#define HOSTFN2_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x174) +#define LPU0_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x178) +#define LPU1_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x17C) + +#define HOSTFN3_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x180) +#define HOSTFN3_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x184) +#define LPU0_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x188) +#define LPU1_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x18C) + +/* Host Function Force Parity Error Registers */ +#define HOSTFN0_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x120) +#define HOSTFN1_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x124) +#define HOSTFN2_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x128) +#define HOSTFN3_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x12C) + +/* LL Port[0|1] Halt Mask Registers */ +#define LL_HALT_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1A0) +#define LL_HALT_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1B0) + +/* LL Port[0|1] Error Mask Registers */ +#define LL_ERR_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1D0) +#define LL_ERR_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1D4) + +/* EMC FLI (Flash Controller) Block Register Address Offset from BAR0 */ +#define FLI_BLK_REG_ADDR 0x0001D000 + +/* EMC FLI Registers */ +#define FLI_CMD_REG (FLI_BLK_REG_ADDR + 0x000) +#define FLI_ADDR_REG (FLI_BLK_REG_ADDR + 0x004) +#define FLI_CTL_REG (FLI_BLK_REG_ADDR + 0x008) +#define FLI_WRDATA_REG (FLI_BLK_REG_ADDR + 0x00C) +#define FLI_RDDATA_REG (FLI_BLK_REG_ADDR + 0x010) +#define FLI_DEV_STATUS_REG (FLI_BLK_REG_ADDR + 0x014) +#define FLI_SIG_WD_REG (FLI_BLK_REG_ADDR + 0x018) + +/** + * RO register + * 31:16 -- Vendor Id + * 15:0 -- Device Id + */ +#define FLI_DEV_VENDOR_REG (FLI_BLK_REG_ADDR + 0x01C) +#define FLI_ERR_STATUS_REG (FLI_BLK_REG_ADDR + 0x020) + +/** + * RAD (RxAdm) Block Register Address Offset from BAR0 + * RAD0 Range : 0x20000 - 0x203FF + * RAD1 Range : 0x20400 - 0x207FF + */ +#define RAD0_BLK_REG_ADDR 0x00020000 +#define RAD1_BLK_REG_ADDR 0x00020400 + +/* RAD0 Registers */ +#define RAD0_CTL_REG (RAD0_BLK_REG_ADDR + 0x000) +#define RAD0_PE_PARM_REG (RAD0_BLK_REG_ADDR + 0x004) +#define RAD0_BCN_REG (RAD0_BLK_REG_ADDR + 0x008) + +/* Default function ID register */ +#define RAD0_DEFAULT_REG (RAD0_BLK_REG_ADDR + 0x00C) + +/* Default promiscuous ID register */ +#define RAD0_PROMISC_REG (RAD0_BLK_REG_ADDR + 0x010) + +#define RAD0_BCNQ_REG (RAD0_BLK_REG_ADDR + 0x014) + +/* + * This register selects 1 of 8 PM Q's using + * VLAN pri, for non-BCN packets without a VLAN tag + */ +#define RAD0_DEFAULTQ_REG (RAD0_BLK_REG_ADDR + 0x018) + +#define RAD0_ERR_STS (RAD0_BLK_REG_ADDR + 0x01C) +#define RAD0_SET_ERR_STS (RAD0_BLK_REG_ADDR + 0x020) +#define RAD0_ERR_INT_EN (RAD0_BLK_REG_ADDR + 0x024) +#define RAD0_FIRST_ERR (RAD0_BLK_REG_ADDR + 0x028) +#define RAD0_FORCE_ERR (RAD0_BLK_REG_ADDR + 0x02C) + +#define RAD0_IF_RCVD (RAD0_BLK_REG_ADDR + 0x030) +#define RAD0_IF_RCVD_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x034) +#define RAD0_IF_RCVD_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x038) +#define RAD0_IF_RCVD_VLAN (RAD0_BLK_REG_ADDR + 0x03C) +#define RAD0_IF_RCVD_UCAST (RAD0_BLK_REG_ADDR + 0x040) +#define RAD0_IF_RCVD_UCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x044) +#define RAD0_IF_RCVD_UCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x048) +#define RAD0_IF_RCVD_UCAST_VLAN (RAD0_BLK_REG_ADDR + 0x04C) +#define RAD0_IF_RCVD_MCAST (RAD0_BLK_REG_ADDR + 0x050) +#define RAD0_IF_RCVD_MCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x054) +#define RAD0_IF_RCVD_MCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x058) +#define RAD0_IF_RCVD_MCAST_VLAN (RAD0_BLK_REG_ADDR + 0x05C) +#define RAD0_IF_RCVD_BCAST (RAD0_BLK_REG_ADDR + 0x060) +#define RAD0_IF_RCVD_BCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x064) +#define RAD0_IF_RCVD_BCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x068) +#define RAD0_IF_RCVD_BCAST_VLAN (RAD0_BLK_REG_ADDR + 0x06C) +#define RAD0_DROPPED_FRAMES (RAD0_BLK_REG_ADDR + 0x070) + +#define RAD0_MAC_MAN_1H (RAD0_BLK_REG_ADDR + 0x080) +#define RAD0_MAC_MAN_1L (RAD0_BLK_REG_ADDR + 0x084) +#define RAD0_MAC_MAN_2H (RAD0_BLK_REG_ADDR + 0x088) +#define RAD0_MAC_MAN_2L (RAD0_BLK_REG_ADDR + 0x08C) +#define RAD0_MAC_MAN_3H (RAD0_BLK_REG_ADDR + 0x090) +#define RAD0_MAC_MAN_3L (RAD0_BLK_REG_ADDR + 0x094) +#define RAD0_MAC_MAN_4H (RAD0_BLK_REG_ADDR + 0x098) +#define RAD0_MAC_MAN_4L (RAD0_BLK_REG_ADDR + 0x09C) + +#define RAD0_LAST4_IP (RAD0_BLK_REG_ADDR + 0x100) + +/* RAD1 Registers */ +#define RAD1_CTL_REG (RAD1_BLK_REG_ADDR + 0x000) +#define RAD1_PE_PARM_REG (RAD1_BLK_REG_ADDR + 0x004) +#define RAD1_BCN_REG (RAD1_BLK_REG_ADDR + 0x008) + +/* Default function ID register */ +#define RAD1_DEFAULT_REG (RAD1_BLK_REG_ADDR + 0x00C) + +/* Promiscuous function ID register */ +#define RAD1_PROMISC_REG (RAD1_BLK_REG_ADDR + 0x010) + +#define RAD1_BCNQ_REG (RAD1_BLK_REG_ADDR + 0x014) + +/* + * This register selects 1 of 8 PM Q's using + * VLAN pri, for non-BCN packets without a VLAN tag + */ +#define RAD1_DEFAULTQ_REG (RAD1_BLK_REG_ADDR + 0x018) + +#define RAD1_ERR_STS (RAD1_BLK_REG_ADDR + 0x01C) +#define RAD1_SET_ERR_STS (RAD1_BLK_REG_ADDR + 0x020) +#define RAD1_ERR_INT_EN (RAD1_BLK_REG_ADDR + 0x024) + +/** + * TXA Block Register Address Offset from BAR0 + * TXA0 Range : 0x21000 - 0x213FF + * TXA1 Range : 0x21400 - 0x217FF + */ +#define TXA0_BLK_REG_ADDR 0x00021000 +#define TXA1_BLK_REG_ADDR 0x00021400 + +/* TXA Registers */ +#define TXA0_CTRL_REG (TXA0_BLK_REG_ADDR + 0x000) +#define TXA1_CTRL_REG (TXA1_BLK_REG_ADDR + 0x000) + +/** + * TSO Sequence # Registers (RO) + * Total 8 (for 8 queues) + * Holds the last seq.# for TSO frames + * See catapult_spec.pdf for more details + */ +#define TXA0_TSO_TCP_SEQ_REG(_num) \ + (TXA0_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +#define TXA1_TSO_TCP_SEQ_REG(_num) \ + (TXA1_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +/** + * TSO IP ID # Registers (RO) + * Total 8 (for 8 queues) + * Holds the last IP ID for TSO frames + * See catapult_spec.pdf for more details + */ +#define TXA0_TSO_IP_INFO_REG(_num) \ + (TXA0_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +#define TXA1_TSO_IP_INFO_REG(_num) \ + (TXA1_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +/** + * RXA Block Register Address Offset from BAR0 + * RXA0 Range : 0x21800 - 0x21BFF + * RXA1 Range : 0x21C00 - 0x21FFF + */ +#define RXA0_BLK_REG_ADDR 0x00021800 +#define RXA1_BLK_REG_ADDR 0x00021C00 + +/* RXA Registers */ +#define RXA0_CTL_REG (RXA0_BLK_REG_ADDR + 0x040) +#define RXA1_CTL_REG (RXA1_BLK_REG_ADDR + 0x040) + +/** + * PPLB Block Register Address Offset from BAR0 + * PPLB0 Range : 0x22000 - 0x223FF + * PPLB1 Range : 0x22400 - 0x227FF + */ +#define PLB0_BLK_REG_ADDR 0x00022000 +#define PLB1_BLK_REG_ADDR 0x00022400 + +/** + * PLB Registers + * Holds RL timer used time stamps in RLT tagged frames + */ +#define PLB0_ECM_TIMER_REG (PLB0_BLK_REG_ADDR + 0x05C) +#define PLB1_ECM_TIMER_REG (PLB1_BLK_REG_ADDR + 0x05C) + +/* Controls the rate-limiter on each of the priority class */ +#define PLB0_RL_CTL (PLB0_BLK_REG_ADDR + 0x060) +#define PLB1_RL_CTL (PLB1_BLK_REG_ADDR + 0x060) + +/** + * Max byte register, total 8, 0-7 + * see catapult_spec.pdf for details + */ +#define PLB0_RL_MAX_BC(_num) \ + (PLB0_BLK_REG_ADDR + 0x064 + ((_num) << 2)) +#define PLB1_RL_MAX_BC(_num) \ + (PLB1_BLK_REG_ADDR + 0x064 + ((_num) << 2)) + +/** + * RL Time Unit Register for priority 0-7 + * 4 bits per priority + * (2^rl_unit)*1us is the actual time period + */ +#define PLB0_RL_TU_PRIO (PLB0_BLK_REG_ADDR + 0x084) +#define PLB1_RL_TU_PRIO (PLB1_BLK_REG_ADDR + 0x084) + +/** + * RL byte count register, + * bytes transmitted in (rl_unit*1)us time period + * 1 per priority, 8 in all, 0-7. + */ +#define PLB0_RL_BYTE_CNT(_num) \ + (PLB0_BLK_REG_ADDR + 0x088 + ((_num) << 2)) +#define PLB1_RL_BYTE_CNT(_num) \ + (PLB1_BLK_REG_ADDR + 0x088 + ((_num) << 2)) + +/** + * RL Min factor register + * 2 bits per priority, + * 4 factors possible: 1, 0.5, 0.25, 0 + * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1 + */ +#define PLB0_RL_MIN_REG (PLB0_BLK_REG_ADDR + 0x0A8) +#define PLB1_RL_MIN_REG (PLB1_BLK_REG_ADDR + 0x0A8) + +/** + * RL Max factor register + * 2 bits per priority, + * 4 factors possible: 1, 0.5, 0.25, 0 + * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1 + */ +#define PLB0_RL_MAX_REG (PLB0_BLK_REG_ADDR + 0x0AC) +#define PLB1_RL_MAX_REG (PLB1_BLK_REG_ADDR + 0x0AC) + +/* MAC SERDES Address Paging register */ +#define PLB0_EMS_ADD_REG (PLB0_BLK_REG_ADDR + 0xD0) +#define PLB1_EMS_ADD_REG (PLB1_BLK_REG_ADDR + 0xD0) + +/* LL EMS Registers */ +#define LL_EMS0_BLK_REG_ADDR 0x00026800 +#define LL_EMS1_BLK_REG_ADDR 0x00026C00 + +/** + * BPC Block Register Address Offset from BAR0 + * BPC0 Range : 0x23000 - 0x233FF + * BPC1 Range : 0x23400 - 0x237FF + */ +#define BPC0_BLK_REG_ADDR 0x00023000 +#define BPC1_BLK_REG_ADDR 0x00023400 + +/** + * PMM Block Register Address Offset from BAR0 + * PMM0 Range : 0x23800 - 0x23BFF + * PMM1 Range : 0x23C00 - 0x23FFF + */ +#define PMM0_BLK_REG_ADDR 0x00023800 +#define PMM1_BLK_REG_ADDR 0x00023C00 + +/** + * HQM Block Register Address Offset from BAR0 + * HQM0 Range : 0x24000 - 0x243FF + * HQM1 Range : 0x24400 - 0x247FF + */ +#define HQM0_BLK_REG_ADDR 0x00024000 +#define HQM1_BLK_REG_ADDR 0x00024400 + +/** + * HQM Control Register + * Controls some aspects of IB + * See catapult_spec.pdf for details + */ +#define HQM0_CTL_REG (HQM0_BLK_REG_ADDR + 0x000) +#define HQM1_CTL_REG (HQM1_BLK_REG_ADDR + 0x000) + +/** + * HQM Stop Q Semaphore Registers. + * Only one Queue resource can be stopped at + * any given time. This register controls access + * to the single stop Q resource. + * See catapult_spec.pdf for details + */ +#define HQM0_RXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x028) +#define HQM0_TXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x02C) +#define HQM1_RXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x028) +#define HQM1_TXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x02C) + +/** + * LUT Block Register Address Offset from BAR0 + * LUT0 Range : 0x25800 - 0x25BFF + * LUT1 Range : 0x25C00 - 0x25FFF + */ +#define LUT0_BLK_REG_ADDR 0x00025800 +#define LUT1_BLK_REG_ADDR 0x00025C00 + +/** + * LUT Registers + * See catapult_spec.pdf for details + */ +#define LUT0_ERR_STS (LUT0_BLK_REG_ADDR + 0x000) +#define LUT1_ERR_STS (LUT1_BLK_REG_ADDR + 0x000) +#define LUT0_SET_ERR_STS (LUT0_BLK_REG_ADDR + 0x004) +#define LUT1_SET_ERR_STS (LUT1_BLK_REG_ADDR + 0x004) + +/** + * TRC (Debug/Trace) Register Offset from BAR0 + * Range : 0x26000 -- 0x263FFF + */ +#define TRC_BLK_REG_ADDR 0x00026000 + +/** + * TRC Registers + * See catapult_spec.pdf for details of each + */ +#define TRC_CTL_REG (TRC_BLK_REG_ADDR + 0x000) +#define TRC_MODS_REG (TRC_BLK_REG_ADDR + 0x004) +#define TRC_TRGC_REG (TRC_BLK_REG_ADDR + 0x008) +#define TRC_CNT1_REG (TRC_BLK_REG_ADDR + 0x010) +#define TRC_CNT2_REG (TRC_BLK_REG_ADDR + 0x014) +#define TRC_NXTS_REG (TRC_BLK_REG_ADDR + 0x018) +#define TRC_DIRR_REG (TRC_BLK_REG_ADDR + 0x01C) + +/** + * TRC Trigger match filters, total 10 + * Determines the trigger condition + */ +#define TRC_TRGM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +/** + * TRC Next State filters, total 10 + * Determines the next state conditions + */ +#define TRC_NXTM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x080 + ((_num) << 2)) + +/** + * TRC Store Match filters, total 10 + * Determines the store conditions + */ +#define TRC_STRM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x0C0 + ((_num) << 2)) + +/* DOORBELLS ACCESS */ + +/** + * Catapult doorbells + * Each doorbell-queue set has + * 1 RxQ, 1 TxQ, 2 IBs in that order + * Size of each entry in 32 bytes, even though only 1 word + * is used. For Non-VM case each doorbell-q set is + * separated by 128 bytes, for VM case it is separated + * by 4K bytes + * Non VM case Range : 0x38000 - 0x39FFF + * VM case Range : 0x100000 - 0x11FFFF + * The range applies to both HQMs + */ +#define HQM_DOORBELL_BLK_BASE_ADDR 0x00038000 +#define HQM_DOORBELL_VM_BLK_BASE_ADDR 0x00100000 + +/* MEMORY ACCESS */ + +/** + * Catapult H/W Block Memory Access Address + * To the host a memory space of 32K (page) is visible + * at a time. The address range is from 0x08000 to 0x0FFFF + */ +#define HW_BLK_HOST_MEM_ADDR 0x08000 + +/** + * Catapult LUT Memory Access Page Numbers + * Range : LUT0 0xa0-0xa1 + * LUT1 0xa2-0xa3 + */ +#define LUT0_MEM_BLK_BASE_PG_NUM 0x000000A0 +#define LUT1_MEM_BLK_BASE_PG_NUM 0x000000A2 + +/** + * Catapult RxFn Database Memory Block Base Offset + * + * The Rx function database exists in LUT block. + * In PCIe space this is accessible as a 256x32 + * bit block. Each entry in this database is 4 + * (4 byte) words. Max. entries is 64. + * Address of an entry corresponding to a function + * = base_addr + (function_no. * 16) + */ +#define RX_FNDB_RAM_BASE_OFFSET 0x0000B400 + +/** + * Catapult TxFn Database Memory Block Base Offset Address + * + * The Tx function database exists in LUT block. + * In PCIe space this is accessible as a 64x32 + * bit block. Each entry in this database is 1 + * (4 byte) word. Max. entries is 64. + * Address of an entry corresponding to a function + * = base_addr + (function_no. * 4) + */ +#define TX_FNDB_RAM_BASE_OFFSET 0x0000B800 + +/** + * Catapult Unicast CAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x48 bits; mapped to PCIe space + * 512x32 bit blocks. For each address, bits + * are written in the order : [47:32] and then + * [31:0]. + */ +#define UCAST_CAM_BASE_OFFSET 0x0000A800 + +/** + * Catapult Unicast RAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x9 bits. + */ +#define UCAST_RAM_BASE_OFFSET 0x0000B000 + +/** + * Catapult Mulicast CAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x48 bits; mapped to PCIe space + * 512x32 bit blocks. For each address, bits + * are written in the order : [47:32] and then + * [31:0]. + */ +#define MCAST_CAM_BASE_OFFSET 0x0000A000 + +/** + * Catapult VLAN RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 4096x66 bits; mapped to PCIe space as + * 8192x32 bit blocks. + * All the 4K entries are within the address range + * 0x0000 to 0x8000, so in the first LUT page. + */ +#define VLAN_RAM_BASE_OFFSET 0x00000000 + +/** + * Catapult Tx Stats RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 1024x33 bits; + * Each Tx function has 64 bytes of space + */ +#define TX_STATS_RAM_BASE_OFFSET 0x00009000 + +/** + * Catapult Rx Stats RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 1024x33 bits; + * Each Rx function has 64 bytes of space + */ +#define RX_STATS_RAM_BASE_OFFSET 0x00008000 + +/* Catapult RXA Memory Access Page Numbers */ +#define RXA0_MEM_BLK_BASE_PG_NUM 0x0000008C +#define RXA1_MEM_BLK_BASE_PG_NUM 0x0000008D + +/** + * Catapult Multicast Vector Table Base Offset Address + * + * Exists in RxA memory space. + * Organized as 512x65 bit block. + * However for each entry 16 bytes allocated (power of 2) + * Total size 512*16 bytes. + * There are two logical divisions, 256 entries each : + * a) Entries 0x00 to 0xff (256) -- Approx. MVT + * Offset 0x000 to 0xFFF + * b) Entries 0x100 to 0x1ff (256) -- Exact MVT + * Offsets 0x1000 to 0x1FFF + */ +#define MCAST_APPROX_MVT_BASE_OFFSET 0x00000000 +#define MCAST_EXACT_MVT_BASE_OFFSET 0x00001000 + +/** + * Catapult RxQ Translate Table (RIT) Base Offset Address + * + * Exists in RxA memory space + * Total no. of entries 64 + * Each entry is 1 (4 byte) word. + * 31:12 -- Reserved + * 11:0 -- Two 6 bit RxQ Ids + */ +#define FUNCTION_TO_RXQ_TRANSLATE 0x00002000 + +/* Catapult RxAdm (RAD) Memory Access Page Numbers */ +#define RAD0_MEM_BLK_BASE_PG_NUM 0x00000086 +#define RAD1_MEM_BLK_BASE_PG_NUM 0x00000087 + +/** + * Catapult RSS Table Base Offset Address + * + * Exists in RAD memory space. + * Each entry is 352 bits, but alligned on + * 64 byte (512 bit) boundary. Accessed + * 4 byte words, the whole entry can be + * broken into 11 word accesses. + */ +#define RSS_TABLE_BASE_OFFSET 0x00000800 + +/** + * Catapult CPQ Block Page Number + * This value is written to the page number registers + * to access the memory associated with the mailboxes. + */ +#define CPQ_BLK_PG_NUM 0x00000005 + +/** + * Clarification : + * LL functions are 2 & 3; can HostFn0/HostFn1 + * <-> LPU0/LPU1 memories be used ? + */ +/** + * Catapult HostFn0/HostFn1 to LPU0/LPU1 Mbox memory + * Per catapult_spec.pdf, the offset of the mbox + * memory is in the register space at an offset of 0x200 + */ +#define CPQ_BLK_REG_MBOX_ADDR (CPQ_BLK_REG_ADDR + 0x200) + +#define HOSTFN_LPU_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x000) + +/* Catapult LPU0/LPU1 to HostFn0/HostFn1 Mbox memory */ +#define LPU_HOSTFN_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x080) + +/** + * Catapult HQM Block Page Number + * This is written to the page number register for + * the appropriate function to access the memory + * associated with HQM + */ +#define HQM0_BLK_PG_NUM 0x00000096 +#define HQM1_BLK_PG_NUM 0x00000097 + +/** + * Note that TxQ and RxQ entries are interlaced + * the HQM memory, i.e RXQ0, TXQ0, RXQ1, TXQ1.. etc. + */ + +#define HQM_RXTX_Q_RAM_BASE_OFFSET 0x00004000 + +/** + * CQ Memory + * Exists in HQM Memory space + * Each entry is 16 (4 byte) words of which + * only 12 words are used for configuration + * Total 64 entries per HQM memory space + */ +#define HQM_CQ_RAM_BASE_OFFSET 0x00006000 + +/** + * Interrupt Block (IB) Memory + * Exists in HQM Memory space + * Each entry is 8 (4 byte) words of which + * only 5 words are used for configuration + * Total 128 entries per HQM memory space + */ +#define HQM_IB_RAM_BASE_OFFSET 0x00001000 + +/** + * Index Table (IT) Memory + * Exists in HQM Memory space + * Each entry is 1 (4 byte) word which + * is used for configuration + * Total 128 entries per HQM memory space + */ +#define HQM_INDX_TBL_RAM_BASE_OFFSET 0x00002000 + +/** + * PSS Block Memory Page Number + * This is written to the appropriate page number + * register to access the CPU memory. + * Also known as the PSS secondary memory (SMEM). + * Range : 0x180 to 0x1CF + * See catapult_spec.pdf for details + */ +#define PSS_BLK_PG_NUM 0x00000180 + +/** + * Offsets of different instances of PSS SMEM + * 2.5M of continuous 1T memory space : 2 blocks + * of 1M each (32 pages each, page=32KB) and 4 smaller + * blocks of 128K each (4 pages each, page=32KB) + * PSS_LMEM_INST0 is used for firmware download + */ +#define PSS_LMEM_INST0 0x00000000 +#define PSS_LMEM_INST1 0x00100000 +#define PSS_LMEM_INST2 0x00200000 +#define PSS_LMEM_INST3 0x00220000 +#define PSS_LMEM_INST4 0x00240000 +#define PSS_LMEM_INST5 0x00260000 + +#define BNA_PCI_REG_CT_ADDRSZ (0x40000) + +#define BNA_GET_PAGE_NUM(_base_page, _offset) \ + ((_base_page) + ((_offset) >> 15)) + +#define BNA_GET_PAGE_OFFSET(_offset) \ + ((_offset) & 0x7fff) + +#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset) \ + ((_bar0) + HW_BLK_HOST_MEM_ADDR \ + + BNA_GET_PAGE_OFFSET((_base_offset))) + +#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\ + (_bar0 + (HW_BLK_HOST_MEM_ADDR) \ + + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET)) \ + + (((_fn_id) & 0x3f) << 9) \ + + (((_vlan_id) & 0xfe0) >> 3)) + +/** + * + * Interrupt related bits, flags and macros + * + */ + +#define __LPU02HOST_MBOX0_STATUS_BITS 0x00100000 +#define __LPU12HOST_MBOX0_STATUS_BITS 0x00200000 +#define __LPU02HOST_MBOX1_STATUS_BITS 0x00400000 +#define __LPU12HOST_MBOX1_STATUS_BITS 0x00800000 + +#define __LPU02HOST_MBOX0_MASK_BITS 0x00100000 +#define __LPU12HOST_MBOX0_MASK_BITS 0x00200000 +#define __LPU02HOST_MBOX1_MASK_BITS 0x00400000 +#define __LPU12HOST_MBOX1_MASK_BITS 0x00800000 + +#define __LPU2HOST_MBOX_MASK_BITS \ + (__LPU02HOST_MBOX0_MASK_BITS | __LPU02HOST_MBOX1_MASK_BITS | \ + __LPU12HOST_MBOX0_MASK_BITS | __LPU12HOST_MBOX1_MASK_BITS) + +#define __LPU2HOST_IB_STATUS_BITS 0x0000ffff + +#define BNA_IS_LPU0_MBOX_INTR(_intr_status) \ + ((_intr_status) & (__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS)) + +#define BNA_IS_LPU1_MBOX_INTR(_intr_status) \ + ((_intr_status) & (__LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS)) + +#define BNA_IS_MBOX_INTR(_intr_status) \ + ((_intr_status) & \ + (__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS | \ + __LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS)) + +#define __EMC_ERROR_STATUS_BITS 0x00010000 +#define __LPU0_ERROR_STATUS_BITS 0x00020000 +#define __LPU1_ERROR_STATUS_BITS 0x00040000 +#define __PSS_ERROR_STATUS_BITS 0x00080000 + +#define __HALT_STATUS_BITS 0x01000000 + +#define __EMC_ERROR_MASK_BITS 0x00010000 +#define __LPU0_ERROR_MASK_BITS 0x00020000 +#define __LPU1_ERROR_MASK_BITS 0x00040000 +#define __PSS_ERROR_MASK_BITS 0x00080000 + +#define __HALT_MASK_BITS 0x01000000 + +#define __ERROR_MASK_BITS \ + (__EMC_ERROR_MASK_BITS | __LPU0_ERROR_MASK_BITS | \ + __LPU1_ERROR_MASK_BITS | __PSS_ERROR_MASK_BITS | \ + __HALT_MASK_BITS) + +#define BNA_IS_ERR_INTR(_intr_status) \ + ((_intr_status) & \ + (__EMC_ERROR_STATUS_BITS | \ + __LPU0_ERROR_STATUS_BITS | \ + __LPU1_ERROR_STATUS_BITS | \ + __PSS_ERROR_STATUS_BITS | \ + __HALT_STATUS_BITS)) + +#define BNA_IS_MBOX_ERR_INTR(_intr_status) \ + (BNA_IS_MBOX_INTR((_intr_status)) | \ + BNA_IS_ERR_INTR((_intr_status))) + +#define BNA_IS_INTX_DATA_INTR(_intr_status) \ + ((_intr_status) & __LPU2HOST_IB_STATUS_BITS) + +#define BNA_INTR_STATUS_MBOX_CLR(_intr_status) \ +do { \ + (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS | \ + __LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS); \ +} while (0) + +#define BNA_INTR_STATUS_ERR_CLR(_intr_status) \ +do { \ + (_intr_status) &= ~(__EMC_ERROR_STATUS_BITS | \ + __LPU0_ERROR_STATUS_BITS | \ + __LPU1_ERROR_STATUS_BITS | \ + __PSS_ERROR_STATUS_BITS | \ + __HALT_STATUS_BITS); \ +} while (0) + +#define bna_intx_disable(_bna, _cur_mask) \ +{ \ + (_cur_mask) = readl((_bna)->regs.fn_int_mask);\ + writel(0xffffffff, (_bna)->regs.fn_int_mask);\ +} + +#define bna_intx_enable(bna, new_mask) \ + writel((new_mask), (bna)->regs.fn_int_mask) + +#define bna_mbox_intr_disable(bna) \ + writel((readl((bna)->regs.fn_int_mask) | \ + (__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \ + (bna)->regs.fn_int_mask) + +#define bna_mbox_intr_enable(bna) \ + writel((readl((bna)->regs.fn_int_mask) & \ + ~(__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \ + (bna)->regs.fn_int_mask) + +#define bna_intr_status_get(_bna, _status) \ +{ \ + (_status) = readl((_bna)->regs.fn_int_status); \ + if ((_status)) { \ + writel((_status) & ~(__LPU02HOST_MBOX0_STATUS_BITS |\ + __LPU02HOST_MBOX1_STATUS_BITS |\ + __LPU12HOST_MBOX0_STATUS_BITS |\ + __LPU12HOST_MBOX1_STATUS_BITS), \ + (_bna)->regs.fn_int_status);\ + } \ +} + +#define bna_intr_status_get_no_clr(_bna, _status) \ + (_status) = readl((_bna)->regs.fn_int_status) + +#define bna_intr_mask_get(bna, mask) \ + (*mask) = readl((bna)->regs.fn_int_mask) + +#define bna_intr_ack(bna, intr_bmap) \ + writel((intr_bmap), (bna)->regs.fn_int_status) + +#define bna_ib_intx_disable(bna, ib_id) \ + writel(readl((bna)->regs.fn_int_mask) | \ + (1 << (ib_id)), \ + (bna)->regs.fn_int_mask) + +#define bna_ib_intx_enable(bna, ib_id) \ + writel(readl((bna)->regs.fn_int_mask) & \ + ~(1 << (ib_id)), \ + (bna)->regs.fn_int_mask) + +#define bna_mbox_msix_idx_set(_device) \ +do {\ + writel(((_device)->vector & 0x000001FF), \ + (_device)->bna->pcidev.pci_bar_kva + \ + reg_offset[(_device)->bna->pcidev.pci_func].msix_idx);\ +} while (0) + +/** + * + * TxQ, RxQ, CQ related bits, offsets, macros + * + */ + +#define BNA_Q_IDLE_STATE 0x00008001 + +#define BNA_GET_DOORBELL_BASE_ADDR(_bar0) \ + ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR) + +#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry) \ + ((HQM_DOORBELL_BLK_BASE_ADDR) \ + + (_entry << 7)) + +#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \ + (0x80000000 | ((_timeout) << 16) | (_events)) + +#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000) + +/* TxQ Entry Opcodes */ +#define BNA_TXQ_WI_SEND (0x402) /* Single Frame Transmission */ +#define BNA_TXQ_WI_SEND_LSO (0x403) /* Multi-Frame Transmission */ +#define BNA_TXQ_WI_EXTENSION (0x104) /* Extension WI */ + +/* TxQ Entry Control Flags */ +#define BNA_TXQ_WI_CF_FCOE_CRC (1 << 8) +#define BNA_TXQ_WI_CF_IPID_MODE (1 << 5) +#define BNA_TXQ_WI_CF_INS_PRIO (1 << 4) +#define BNA_TXQ_WI_CF_INS_VLAN (1 << 3) +#define BNA_TXQ_WI_CF_UDP_CKSUM (1 << 2) +#define BNA_TXQ_WI_CF_TCP_CKSUM (1 << 1) +#define BNA_TXQ_WI_CF_IP_CKSUM (1 << 0) + +#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \ + (((_hdr_size) << 10) | ((_offset) & 0x3FF)) + +/* + * Completion Q defines + */ +/* CQ Entry Flags */ +#define BNA_CQ_EF_MAC_ERROR (1 << 0) +#define BNA_CQ_EF_FCS_ERROR (1 << 1) +#define BNA_CQ_EF_TOO_LONG (1 << 2) +#define BNA_CQ_EF_FC_CRC_OK (1 << 3) + +#define BNA_CQ_EF_RSVD1 (1 << 4) +#define BNA_CQ_EF_L4_CKSUM_OK (1 << 5) +#define BNA_CQ_EF_L3_CKSUM_OK (1 << 6) +#define BNA_CQ_EF_HDS_HEADER (1 << 7) + +#define BNA_CQ_EF_UDP (1 << 8) +#define BNA_CQ_EF_TCP (1 << 9) +#define BNA_CQ_EF_IP_OPTIONS (1 << 10) +#define BNA_CQ_EF_IPV6 (1 << 11) + +#define BNA_CQ_EF_IPV4 (1 << 12) +#define BNA_CQ_EF_VLAN (1 << 13) +#define BNA_CQ_EF_RSS (1 << 14) +#define BNA_CQ_EF_RSVD2 (1 << 15) + +#define BNA_CQ_EF_MCAST_MATCH (1 << 16) +#define BNA_CQ_EF_MCAST (1 << 17) +#define BNA_CQ_EF_BCAST (1 << 18) +#define BNA_CQ_EF_REMOTE (1 << 19) + +#define BNA_CQ_EF_LOCAL (1 << 20) + +/** + * + * Data structures + * + */ + +enum txf_flags { + BFI_TXF_CF_ENABLE = 1 << 0, + BFI_TXF_CF_VLAN_FILTER = 1 << 8, + BFI_TXF_CF_VLAN_ADMIT = 1 << 9, + BFI_TXF_CF_VLAN_INSERT = 1 << 10, + BFI_TXF_CF_RSVD1 = 1 << 11, + BFI_TXF_CF_MAC_SA_CHECK = 1 << 12, + BFI_TXF_CF_VLAN_WI_BASED = 1 << 13, + BFI_TXF_CF_VSWITCH_MCAST = 1 << 14, + BFI_TXF_CF_VSWITCH_UCAST = 1 << 15, + BFI_TXF_CF_RSVD2 = 0x7F << 1 +}; + +enum ib_flags { + BFI_IB_CF_MASTER_ENABLE = (1 << 0), + BFI_IB_CF_MSIX_MODE = (1 << 1), + BFI_IB_CF_COALESCING_MODE = (1 << 2), + BFI_IB_CF_INTER_PKT_ENABLE = (1 << 3), + BFI_IB_CF_INT_ENABLE = (1 << 4), + BFI_IB_CF_INTER_PKT_DMA = (1 << 5), + BFI_IB_CF_ACK_PENDING = (1 << 6), + BFI_IB_CF_RESERVED1 = (1 << 7) +}; + +enum rss_hash_type { + BFI_RSS_T_V4_TCP = (1 << 11), + BFI_RSS_T_V4_IP = (1 << 10), + BFI_RSS_T_V6_TCP = (1 << 9), + BFI_RSS_T_V6_IP = (1 << 8) +}; +enum hds_header_type { + BNA_HDS_T_V4_TCP = (1 << 11), + BNA_HDS_T_V4_UDP = (1 << 10), + BNA_HDS_T_V6_TCP = (1 << 9), + BNA_HDS_T_V6_UDP = (1 << 8), + BNA_HDS_FORCED = (1 << 7), +}; +enum rxf_flags { + BNA_RXF_CF_SM_LG_RXQ = (1 << 15), + BNA_RXF_CF_DEFAULT_VLAN = (1 << 14), + BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE = (1 << 13), + BNA_RXF_CF_VLAN_STRIP = (1 << 12), + BNA_RXF_CF_RSS_ENABLE = (1 << 8) +}; +struct bna_chip_regs_offset { + u32 page_addr; + u32 fn_int_status; + u32 fn_int_mask; + u32 msix_idx; +}; +extern const struct bna_chip_regs_offset reg_offset[]; + +struct bna_chip_regs { + void __iomem *page_addr; + void __iomem *fn_int_status; + void __iomem *fn_int_mask; +}; + +struct bna_txq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */ + /* 23:16->Int Blk Offset */ + /* 15:0 ->consumer pointer(index?) */ + u32 cns_ptr2_n_q_state; /* 31:16->cons. ptr 2; 15:0-> Q state */ + u32 nxt_qid_n_fid_n_pri; /* 17:10->next */ + /* QId;9:3->FID;2:0->Priority */ + u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count; */ + /* 23:12->Cfg Quota; */ + /* 11:0 ->Run Quota */ + u32 reserved3[4]; +}; + +struct bna_rxq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 sg_n_cq_n_cns_ptr; /* 31:28->reserved; 27:24->sg count */ + /* 23:16->CQ; */ + /* 15:0->consumer pointer(index?) */ + u32 buf_sz_n_q_state; /* 31:16->buffer size; 15:0-> Q state */ + u32 next_qid; /* 17:10->next QId */ + u32 reserved3; + u32 reserved4[4]; +}; + +struct bna_rxtx_q_mem { + struct bna_rxq_mem rxq; + struct bna_txq_mem txq; +}; + +struct bna_cq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */ + /* 23:16->Int Blk Offset */ + /* 15:0 ->consumer pointer(index?) */ + u32 q_state; /* 31:16->reserved; 15:0-> Q state */ + u32 reserved3[2]; + u32 reserved4[4]; +}; + +struct bna_ib_blk_mem { + u32 host_addr_lo; + u32 host_addr_hi; + u32 clsc_n_ctrl_n_msix; /* 31:24->coalescing; */ + /* 23:16->coalescing cfg; */ + /* 15:8 ->control; */ + /* 7:0 ->msix; */ + u32 ipkt_n_ent_n_idxof; + u32 ipkt_cnt_cfg_n_unacked; + + u32 reserved[3]; +}; + +struct bna_idx_tbl_mem { + u32 idx; /* !< 31:16->res;15:0->idx; */ +}; + +struct bna_doorbell_qset { + u32 rxq[0x20 >> 2]; + u32 txq[0x20 >> 2]; + u32 ib0[0x20 >> 2]; + u32 ib1[0x20 >> 2]; +}; + +struct bna_rx_fndb_ram { + u32 rss_prop; + u32 size_routing_props; + u32 rit_hds_mcastq; + u32 control_flags; +}; + +struct bna_tx_fndb_ram { + u32 vlan_n_ctrl_flags; +}; + +/** + * @brief + * Structure which maps to RxFn Indirection Table (RIT) + * Size : 1 word + * See catapult_spec.pdf, RxA for details + */ +struct bna_rit_mem { + u32 rxq_ids; /* !< 31:12->res;11:0->two 6 bit RxQ Ids */ +}; + +/** + * @brief + * Structure which maps to RSS Table entry + * Size : 16 words + * See catapult_spec.pdf, RAD for details + */ +struct bna_rss_mem { + /* + * 31:12-> res + * 11:8 -> protocol type + * 7:0 -> hash index + */ + u32 type_n_hash; + u32 hash_key[10]; /* !< 40 byte Toeplitz hash key */ + u32 reserved[5]; +}; + +/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */ +struct bna_dma_addr { + u32 msb; + u32 lsb; +}; + +struct bna_txq_wi_vector { + u16 reserved; + u16 length; /* Only 14 LSB are valid */ + struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */ +}; + +typedef u16 bna_txq_wi_opcode_t; + +typedef u16 bna_txq_wi_ctrl_flag_t; + +/** + * TxQ Entry Structure + * + * BEWARE: Load values into this structure with correct endianess. + */ +struct bna_txq_entry { + union { + struct { + u8 reserved; + u8 num_vectors; /* number of vectors present */ + bna_txq_wi_opcode_t opcode; /* Either */ + /* BNA_TXQ_WI_SEND or */ + /* BNA_TXQ_WI_SEND_LSO */ + bna_txq_wi_ctrl_flag_t flags; /* OR of all the flags */ + u16 l4_hdr_size_n_offset; + u16 vlan_tag; + u16 lso_mss; /* Only 14 LSB are valid */ + u32 frame_length; /* Only 24 LSB are valid */ + } wi; + + struct { + u16 reserved; + bna_txq_wi_opcode_t opcode; /* Must be */ + /* BNA_TXQ_WI_EXTENSION */ + u32 reserved2[3]; /* Place holder for */ + /* removed vector (12 bytes) */ + } wi_ext; + } hdr; + struct bna_txq_wi_vector vector[4]; +}; +#define wi_hdr hdr.wi +#define wi_ext_hdr hdr.wi_ext + +/* RxQ Entry Structure */ +struct bna_rxq_entry { /* Rx-Buffer */ + struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */ +}; + +typedef u32 bna_cq_e_flag_t; + +/* CQ Entry Structure */ +struct bna_cq_entry { + bna_cq_e_flag_t flags; + u16 vlan_tag; + u16 length; + u32 rss_hash; + u8 valid; + u8 reserved1; + u8 reserved2; + u8 rxq_id; +}; + +#endif /* __BNA_HW_H__ */ diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c new file mode 100644 index 000000000000..890846d55502 --- /dev/null +++ b/drivers/net/bna/bna_txrx.c @@ -0,0 +1,4209 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include "bna.h" +#include "bfa_sm.h" +#include "bfi.h" + +/** + * IB + */ +#define bna_ib_find_free_ibidx(_mask, _pos)\ +do {\ + (_pos) = 0;\ + while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\ + ((1 << (_pos)) & (_mask)))\ + (_pos)++;\ +} while (0) + +#define bna_ib_count_ibidx(_mask, _count)\ +do {\ + int pos = 0;\ + (_count) = 0;\ + while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\ + if ((1 << pos) & (_mask))\ + (_count) = pos + 1;\ + pos++;\ + } \ +} while (0) + +#define bna_ib_select_segpool(_count, _q_idx)\ +do {\ + int i;\ + (_q_idx) = -1;\ + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\ + if ((_count <= ibidx_pool[i].pool_entry_size)) {\ + (_q_idx) = i;\ + break;\ + } \ + } \ +} while (0) + +struct bna_ibidx_pool { + int pool_size; + int pool_entry_size; +}; +init_ibidx_pool(ibidx_pool); + +static struct bna_intr * +bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type, + int vector) +{ + struct bna_intr *intr; + struct list_head *qe; + + list_for_each(qe, &ib_mod->intr_active_q) { + intr = (struct bna_intr *)qe; + + if ((intr->intr_type == intr_type) && + (intr->vector == vector)) { + intr->ref_count++; + return intr; + } + } + + if (list_empty(&ib_mod->intr_free_q)) + return NULL; + + bfa_q_deq(&ib_mod->intr_free_q, &intr); + bfa_q_qe_init(&intr->qe); + + intr->ref_count = 1; + intr->intr_type = intr_type; + intr->vector = vector; + + list_add_tail(&intr->qe, &ib_mod->intr_active_q); + + return intr; +} + +static void +bna_intr_put(struct bna_ib_mod *ib_mod, + struct bna_intr *intr) +{ + intr->ref_count--; + + if (intr->ref_count == 0) { + intr->ib = NULL; + list_del(&intr->qe); + bfa_q_qe_init(&intr->qe); + list_add_tail(&intr->qe, &ib_mod->intr_free_q); + } +} + +void +bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + int j; + int count; + u8 offset; + struct bna_doorbell_qset *qset; + unsigned long off; + + ib_mod->bna = bna; + + ib_mod->ib = (struct bna_ib *) + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva; + ib_mod->intr = (struct bna_intr *) + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva; + ib_mod->idx_seg = (struct bna_ibidx_seg *) + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&ib_mod->ib_free_q); + INIT_LIST_HEAD(&ib_mod->intr_free_q); + INIT_LIST_HEAD(&ib_mod->intr_active_q); + + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) + INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]); + + for (i = 0; i < BFI_MAX_IB; i++) { + ib_mod->ib[i].ib_id = i; + + ib_mod->ib[i].ib_seg_host_addr_kva = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva; + ib_mod->ib[i].ib_seg_host_addr.lsb = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb; + ib_mod->ib[i].ib_seg_host_addr.msb = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb; + + qset = (struct bna_doorbell_qset *)0; + off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1) + * (0x20 >> 2)]); + ib_mod->ib[i].door_bell.doorbell_addr = off + + BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva); + + bfa_q_qe_init(&ib_mod->ib[i].qe); + list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q); + + bfa_q_qe_init(&ib_mod->intr[i].qe); + list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q); + } + + count = 0; + offset = 0; + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) { + for (j = 0; j < ibidx_pool[i].pool_size; j++) { + bfa_q_qe_init(&ib_mod->idx_seg[count]); + ib_mod->idx_seg[count].ib_seg_size = + ibidx_pool[i].pool_entry_size; + ib_mod->idx_seg[count].ib_idx_tbl_offset = offset; + list_add_tail(&ib_mod->idx_seg[count].qe, + &ib_mod->ibidx_seg_pool[i]); + count++; + offset += ibidx_pool[i].pool_entry_size; + } + } +} + +void +bna_ib_mod_uninit(struct bna_ib_mod *ib_mod) +{ + int i; + int j; + struct list_head *qe; + + i = 0; + list_for_each(qe, &ib_mod->ib_free_q) + i++; + + i = 0; + list_for_each(qe, &ib_mod->intr_free_q) + i++; + + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) { + j = 0; + list_for_each(qe, &ib_mod->ibidx_seg_pool[i]) + j++; + } + + ib_mod->bna = NULL; +} + +struct bna_ib * +bna_ib_get(struct bna_ib_mod *ib_mod, + enum bna_intr_type intr_type, + int vector) +{ + struct bna_ib *ib; + struct bna_intr *intr; + + if (intr_type == BNA_INTR_T_INTX) + vector = (1 << vector); + + intr = bna_intr_get(ib_mod, intr_type, vector); + if (intr == NULL) + return NULL; + + if (intr->ib) { + if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) { + bna_intr_put(ib_mod, intr); + return NULL; + } + intr->ib->ref_count++; + return intr->ib; + } + + if (list_empty(&ib_mod->ib_free_q)) { + bna_intr_put(ib_mod, intr); + return NULL; + } + + bfa_q_deq(&ib_mod->ib_free_q, &ib); + bfa_q_qe_init(&ib->qe); + + ib->ref_count = 1; + ib->start_count = 0; + ib->idx_mask = 0; + + ib->intr = intr; + ib->idx_seg = NULL; + intr->ib = ib; + + ib->bna = ib_mod->bna; + + return ib; +} + +void +bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib) +{ + bna_intr_put(ib_mod, ib->intr); + + ib->ref_count--; + + if (ib->ref_count == 0) { + ib->intr = NULL; + ib->bna = NULL; + list_add_tail(&ib->qe, &ib_mod->ib_free_q); + } +} + +/* Returns index offset - starting from 0 */ +int +bna_ib_reserve_idx(struct bna_ib *ib) +{ + struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; + struct bna_ibidx_seg *idx_seg; + int idx; + int num_idx; + int q_idx; + + /* Find the first free index position */ + bna_ib_find_free_ibidx(ib->idx_mask, idx); + if (idx == BFI_IBIDX_MAX_SEGSIZE) + return -1; + + /* + * Calculate the total number of indexes held by this IB, + * including the index newly reserved above. + */ + bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx); + + /* See if there is a free space in the index segment held by this IB */ + if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) { + ib->idx_mask |= (1 << idx); + return idx; + } + + if (ib->start_count) + return -1; + + /* Allocate a new segment */ + bna_ib_select_segpool(num_idx, q_idx); + while (1) { + if (q_idx == BFI_IBIDX_TOTAL_POOLS) + return -1; + if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx])) + break; + q_idx++; + } + bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg); + bfa_q_qe_init(&idx_seg->qe); + + /* Free the old segment */ + if (ib->idx_seg) { + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx); + list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]); + } + + ib->idx_seg = idx_seg; + + ib->idx_mask |= (1 << idx); + + return idx; +} + +void +bna_ib_release_idx(struct bna_ib *ib, int idx) +{ + struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; + struct bna_ibidx_seg *idx_seg; + int num_idx; + int cur_q_idx; + int new_q_idx; + + ib->idx_mask &= ~(1 << idx); + + if (ib->start_count) + return; + + bna_ib_count_ibidx(ib->idx_mask, num_idx); + + /* + * Free the segment, if there are no more indexes in the segment + * held by this IB + */ + if (!num_idx) { + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx); + list_add_tail(&ib->idx_seg->qe, + &ib_mod->ibidx_seg_pool[cur_q_idx]); + ib->idx_seg = NULL; + return; + } + + /* See if we can move to a smaller segment */ + bna_ib_select_segpool(num_idx, new_q_idx); + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx); + while (new_q_idx < cur_q_idx) { + if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx])) + break; + new_q_idx++; + } + if (new_q_idx < cur_q_idx) { + /* Select the new smaller segment */ + bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg); + bfa_q_qe_init(&idx_seg->qe); + /* Free the old segment */ + list_add_tail(&ib->idx_seg->qe, + &ib_mod->ibidx_seg_pool[cur_q_idx]); + ib->idx_seg = idx_seg; + } +} + +int +bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config) +{ + if (ib->start_count) + return -1; + + ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo; + ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo; + ib->ib_config.interpkt_count = ib_config->interpkt_count; + ib->ib_config.ctrl_flags = ib_config->ctrl_flags; + + ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE; + if (ib->intr->intr_type == BNA_INTR_T_MSIX) + ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE; + + return 0; +} + +void +bna_ib_start(struct bna_ib *ib) +{ + struct bna_ib_blk_mem ib_cfg; + struct bna_ib_blk_mem *ib_mem; + u32 pg_num; + u32 intx_mask; + int i; + void __iomem *base_addr; + unsigned long off; + + ib->start_count++; + + if (ib->start_count > 1) + return; + + ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb); + ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb); + + ib_cfg.clsc_n_ctrl_n_msix = (((u32) + ib->ib_config.coalescing_timeo << 16) | + ((u32)ib->ib_config.ctrl_flags << 8) | + (ib->intr->vector)); + ib_cfg.ipkt_n_ent_n_idxof = + ((u32) + (ib->ib_config.interpkt_timeo & 0xf) << 16) | + ((u32)ib->idx_seg->ib_seg_size << 8) | + (ib->idx_seg->ib_idx_tbl_offset); + ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32) + ib->ib_config.interpkt_count << 24); + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num, + HQM_IB_RAM_BASE_OFFSET); + writel(pg_num, ib->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva, + HQM_IB_RAM_BASE_OFFSET); + + ib_mem = (struct bna_ib_blk_mem *)0; + off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo; + writel(htonl(ib_cfg.host_addr_lo), base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi; + writel(htonl(ib_cfg.host_addr_hi), base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix; + writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof; + writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked; + writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off); + + ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK( + (u32)ib->ib_config.coalescing_timeo, 0); + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num, + HQM_INDX_TBL_RAM_BASE_OFFSET); + writel(pg_num, ib->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva, + HQM_INDX_TBL_RAM_BASE_OFFSET); + for (i = 0; i < ib->idx_seg->ib_seg_size; i++) { + off = (unsigned long) + ((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE); + writel(0, base_addr + off); + } + + if (ib->intr->intr_type == BNA_INTR_T_INTX) { + bna_intx_disable(ib->bna, intx_mask); + intx_mask &= ~(ib->intr->vector); + bna_intx_enable(ib->bna, intx_mask); + } +} + +void +bna_ib_stop(struct bna_ib *ib) +{ + u32 intx_mask; + + ib->start_count--; + + if (ib->start_count == 0) { + writel(BNA_DOORBELL_IB_INT_DISABLE, + ib->door_bell.doorbell_addr); + if (ib->intr->intr_type == BNA_INTR_T_INTX) { + bna_intx_disable(ib->bna, intx_mask); + intx_mask |= (ib->intr->vector); + bna_intx_enable(ib->bna, intx_mask); + } + } +} + +void +bna_ib_fail(struct bna_ib *ib) +{ + ib->start_count = 0; +} + +/** + * RXF + */ +static void rxf_enable(struct bna_rxf *rxf); +static void rxf_disable(struct bna_rxf *rxf); +static void __rxf_config_set(struct bna_rxf *rxf); +static void __rxf_rit_set(struct bna_rxf *rxf); +static void __bna_rxf_stat_clr(struct bna_rxf *rxf); +static int rxf_process_packet_filter(struct bna_rxf *rxf); +static int rxf_clear_packet_filter(struct bna_rxf *rxf); +static void rxf_reset_packet_filter(struct bna_rxf *rxf); +static void rxf_cb_enabled(void *arg, int status); +static void rxf_cb_disabled(void *arg, int status); +static void bna_rxf_cb_stats_cleared(void *arg, int status); +static void __rxf_enable(struct bna_rxf *rxf); +static void __rxf_disable(struct bna_rxf *rxf); + +bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf, + enum bna_rxf_event); + +static struct bfa_sm_table rxf_sm_table[] = { + {BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED}, + {BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT}, + {BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT}, + {BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED}, + {BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT}, + {BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT}, + {BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT}, + {BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT}, + {BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT} +}; + +static void +bna_rxf_sm_stopped_entry(struct bna_rxf *rxf) +{ + call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS); +} + +static void +bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_START: + bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait); + break; + + case RXF_E_STOP: + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_FAIL: + /* No-op */ + break; + + case RXF_E_CAM_FLTR_MOD: + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + break; + + case RXF_E_STARTED: + case RXF_E_STOPPED: + case RXF_E_CAM_FLTR_RESP: + /** + * These events are received due to flushing of mbox + * when device fails + */ + /* No-op */ + break; + + case RXF_E_PAUSE: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS); + break; + + case RXF_E_RESUME: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf) +{ + __rxf_config_set(rxf); + __rxf_rit_set(rxf); + rxf_enable(rxf); +} + +static void +bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + /** + * STOP is originated from bnad. When this happens, + * it can not be waiting for filter update + */ + call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT); + bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait); + break; + + case RXF_E_FAIL: + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + call_rxf_start_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + /* No-op */ + break; + + case RXF_E_STARTED: + /** + * Force rxf_process_filter() to go through initial + * config + */ + if ((rxf->ucast_active_mac != NULL) && + (rxf->ucast_pending_set == 0)) + rxf->ucast_pending_set = 1; + + if (rxf->rss_status == BNA_STATUS_T_ENABLED) + rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; + + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait); + break; + + case RXF_E_PAUSE: + case RXF_E_RESUME: + rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf) +{ + if (!rxf_process_packet_filter(rxf)) { + /* No more pending CAM entries to update */ + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + } +} + +static void +bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + /** + * STOP is originated from bnad. When this happens, + * it can not be waiting for filter update + */ + call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT); + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait); + break; + + case RXF_E_FAIL: + rxf_reset_packet_filter(rxf); + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + call_rxf_start_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + /* No-op */ + break; + + case RXF_E_CAM_FLTR_RESP: + if (!rxf_process_packet_filter(rxf)) { + /* No more pending CAM entries to update */ + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + } + break; + + case RXF_E_PAUSE: + case RXF_E_RESUME: + rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_started_entry(struct bna_rxf *rxf) +{ + call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS); + + if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) { + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_PAUSE); + else + bfa_fsm_send_event(rxf, RXF_E_RESUME); + } + +} + +static void +bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait); + /* Hack to get FSM start clearing CAM entries */ + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP); + break; + + case RXF_E_FAIL: + rxf_reset_packet_filter(rxf); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait); + break; + + case RXF_E_PAUSE: + bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait); + break; + + case RXF_E_RESUME: + bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf) +{ + /** + * Note: Do not add rxf_clear_packet_filter here. + * It will overstep mbox when this transition happens: + * cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event + */ +} + +static void +bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + rxf_reset_packet_filter(rxf); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_RESP: + if (!rxf_clear_packet_filter(rxf)) { + /* No more pending CAM entries to clear */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait); + rxf_disable(rxf); + } + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf) +{ + /** + * NOTE: Do not add rxf_disable here. + * It will overstep mbox when this transition happens: + * start_wait -> stop_wait on RXF_E_STOP event + */ +} + +static void +bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STARTED: + /** + * This event is received due to abrupt transition from + * bna_rxf_sm_start_wait state on receiving + * RXF_E_STOP event + */ + rxf_disable(rxf); + break; + + case RXF_E_STOPPED: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait); + break; + + case RXF_E_PAUSE: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + break; + + case RXF_E_RESUME: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf) +{ + rxf->rxf_flags &= + ~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED); + __rxf_disable(rxf); +} + +static void +bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of disabling rxf, initiated by + * bnad. + */ + call_rxf_pause_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STOPPED: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + break; + + /* + * Since PAUSE/RESUME can only be sent by bnad, we don't expect + * any other event during these states + */ + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf) +{ + rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED); + rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED; + __rxf_enable(rxf); +} + +static void +bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of disabling rxf, initiated by + * bnad. + */ + call_rxf_resume_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STARTED: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + break; + + /* + * Since PAUSE/RESUME can only be sent by bnad, we don't expect + * any other event during these states + */ + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf) +{ + __bna_rxf_stat_clr(rxf); +} + +static void +bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + case RXF_E_STAT_CLEARED: + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +__rxf_enable(struct bna_rxf *rxf) +{ + struct bfi_ll_rxf_multi_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0); + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + ll_req.enable = 1; + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + rxf_cb_enabled, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +__rxf_disable(struct bna_rxf *rxf) +{ + struct bfi_ll_rxf_multi_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0); + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + ll_req.enable = 0; + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + rxf_cb_disabled, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +__rxf_config_set(struct bna_rxf *rxf) +{ + u32 i; + struct bna_rss_mem *rss_mem; + struct bna_rx_fndb_ram *rx_fndb_ram; + struct bna *bna = rxf->rx->bna; + void __iomem *base_addr; + unsigned long off; + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + RSS_TABLE_BASE_OFFSET); + + rss_mem = (struct bna_rss_mem *)0; + + /* Configure RSS if required */ + if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) { + /* configure RSS Table */ + writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM + + bna->port_num, RSS_TABLE_BASE_OFFSET), + bna->regs.page_addr); + + /* temporarily disable RSS, while hash value is written */ + off = (unsigned long)&rss_mem[0].type_n_hash; + writel(0, base_addr + off); + + for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) { + off = (unsigned long) + &rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i]; + writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]), + base_addr + off); + } + + off = (unsigned long)&rss_mem[0].type_n_hash; + writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask, + base_addr + off); + } + + /* Configure RxF */ + writel(BNA_GET_PAGE_NUM( + LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2), + RX_FNDB_RAM_BASE_OFFSET), + bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + RX_FNDB_RAM_BASE_OFFSET); + + rx_fndb_ram = (struct bna_rx_fndb_ram *)0; + + /* We always use RSS table 0 */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop; + writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE, + base_addr + off); + + /* small large buffer enable/disable */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props; + writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80, + base_addr + off); + + /* RIT offset, HDS forced offset, multicast RxQ Id */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq; + writel((rxf->rit_segment->rit_offset << 16) | + (rxf->forced_offset << 8) | + (rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id, + base_addr + off); + + /* + * default vlan tag, default function enable, strip vlan bytes, + * HDS type, header size + */ + + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags; + writel(((u32)rxf->default_vlan_tag << 16) | + (rxf->ctrl_flags & + (BNA_RXF_CF_DEFAULT_VLAN | + BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE | + BNA_RXF_CF_VLAN_STRIP)) | + (rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) | + rxf->hds_cfg.header_size, + base_addr + off); +} + +void +__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status) +{ + struct bna *bna = rxf->rx->bna; + int i; + + writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (bna->port_num * 2), VLAN_RAM_BASE_OFFSET), + bna->regs.page_addr); + + if (status == BNA_STATUS_T_ENABLED) { + /* enable VLAN filtering on this function */ + for (i = 0; i <= BFI_MAX_VLAN / 32; i++) { + writel(rxf->vlan_filter_table[i], + BNA_GET_VLAN_MEM_ENTRY_ADDR + (bna->pcidev.pci_bar_kva, rxf->rxf_id, + i * 32)); + } + } else { + /* disable VLAN filtering on this function */ + for (i = 0; i <= BFI_MAX_VLAN / 32; i++) { + writel(0xffffffff, + BNA_GET_VLAN_MEM_ENTRY_ADDR + (bna->pcidev.pci_bar_kva, rxf->rxf_id, + i * 32)); + } + } +} + +static void +__rxf_rit_set(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + struct bna_rit_mem *rit_mem; + int i; + void __iomem *base_addr; + unsigned long off; + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + FUNCTION_TO_RXQ_TRANSLATE); + + rit_mem = (struct bna_rit_mem *)0; + + writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num, + FUNCTION_TO_RXQ_TRANSLATE), + bna->regs.page_addr); + + for (i = 0; i < rxf->rit_segment->rit_size; i++) { + off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset]; + writel(rxf->rit_segment->rit[i].large_rxq_id << 6 | + rxf->rit_segment->rit[i].small_rxq_id, + base_addr + off); + } +} + +static void +__bna_rxf_stat_clr(struct bna_rxf *rxf) +{ + struct bfi_ll_stats_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); + ll_req.stats_mask = 0; + ll_req.txf_id_mask[0] = 0; + ll_req.txf_id_mask[1] = 0; + + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + bna_rxf_cb_stats_cleared, rxf); + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +rxf_enable(struct bna_rxf *rxf) +{ + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_STARTED); + else { + rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED; + __rxf_enable(rxf); + } +} + +static void +rxf_cb_enabled(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STARTED); +} + +static void +rxf_disable(struct bna_rxf *rxf) +{ + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_STOPPED); + else + rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED; + __rxf_disable(rxf); +} + +static void +rxf_cb_disabled(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STOPPED); +} + +void +rxf_cb_cam_fltr_mbox_cmd(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP); +} + +static void +bna_rxf_cb_stats_cleared(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED); +} + +void +rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd, + const struct bna_mac *mac_addr) +{ + struct bfi_ll_mac_addr_req req; + + bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0); + + req.rxf_id = rxf->rxf_id; + memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN); + + bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req), + rxf_cb_cam_fltr_mbox_cmd, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static int +rxf_process_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* Add multicast entries */ + if (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac); + list_add_tail(&mac->qe, &rxf->mcast_active_q); + return 1; + } + + /* Delete multicast entries previousely added */ + if (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + return 1; + } + + return 0; +} + +static int +rxf_process_packet_filter_vlan(struct bna_rxf *rxf) +{ + /* Apply the VLAN filter */ + if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) { + rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING; + if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) && + !(rxf->rxmode_active & BNA_RXMODE_DEFAULT)) + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + } + + /* Apply RSS configuration */ + if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) { + rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING; + if (rxf->rss_status == BNA_STATUS_T_DISABLED) { + /* RSS is being disabled */ + rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE; + __rxf_rit_set(rxf); + __rxf_config_set(rxf); + } else { + /* RSS is being enabled or reconfigured */ + rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE; + __rxf_rit_set(rxf); + __rxf_config_set(rxf); + } + } + + return 0; +} + +/** + * Processes pending ucast, mcast entry addition/deletion and issues mailbox + * command. Also processes pending filter configuration - promiscuous mode, + * default mode, allmutli mode and issues mailbox command or directly applies + * to h/w + */ +static int +rxf_process_packet_filter(struct bna_rxf *rxf) +{ + /* Set the default MAC first */ + if (rxf->ucast_pending_set > 0) { + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ, + rxf->ucast_active_mac); + rxf->ucast_pending_set--; + return 1; + } + + if (rxf_process_packet_filter_ucast(rxf)) + return 1; + + if (rxf_process_packet_filter_mcast(rxf)) + return 1; + + if (rxf_process_packet_filter_promisc(rxf)) + return 1; + + if (rxf_process_packet_filter_default(rxf)) + return 1; + + if (rxf_process_packet_filter_allmulti(rxf)) + return 1; + + if (rxf_process_packet_filter_vlan(rxf)) + return 1; + + return 0; +} + +static int +rxf_clear_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* 3. delete pending mcast entries */ + if (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + return 1; + } + + /* 4. clear active mcast entries; move them to pending_add_q */ + if (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + return 1; + } + + return 0; +} + +/** + * In the rxf stop path, processes pending ucast/mcast delete queue and issues + * the mailbox command. Moves the active ucast/mcast entries to pending add q, + * so that they are added to CAM again in the rxf start path. Moves the current + * filter settings - promiscuous, default, allmutli - to pending filter + * configuration + */ +static int +rxf_clear_packet_filter(struct bna_rxf *rxf) +{ + if (rxf_clear_packet_filter_ucast(rxf)) + return 1; + + if (rxf_clear_packet_filter_mcast(rxf)) + return 1; + + /* 5. clear active default MAC in the CAM */ + if (rxf->ucast_pending_set > 0) + rxf->ucast_pending_set = 0; + + if (rxf_clear_packet_filter_promisc(rxf)) + return 1; + + if (rxf_clear_packet_filter_default(rxf)) + return 1; + + if (rxf_clear_packet_filter_allmulti(rxf)) + return 1; + + return 0; +} + +static void +rxf_reset_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct list_head *qe; + struct bna_mac *mac; + + /* 3. Move active mcast entries to pending_add_q */ + while (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->mcast_pending_add_q); + } + + /* 4. Throw away delete pending mcast entries */ + while (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } +} + +/** + * In the rxf fail path, throws away the ucast/mcast entries pending for + * deletion, moves all active ucast/mcast entries to pending queue so that + * they are added back to CAM in the rxf start path. Also moves the current + * filter configuration to pending filter configuration. + */ +static void +rxf_reset_packet_filter(struct bna_rxf *rxf) +{ + rxf_reset_packet_filter_ucast(rxf); + + rxf_reset_packet_filter_mcast(rxf); + + /* 5. Turn off ucast set flag */ + rxf->ucast_pending_set = 0; + + rxf_reset_packet_filter_promisc(rxf); + + rxf_reset_packet_filter_default(rxf); + + rxf_reset_packet_filter_allmulti(rxf); +} + +void +bna_rxf_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config) +{ + struct list_head *qe; + struct bna_rxp *rxp; + + /* rxf_id is initialized during rx_mod init */ + rxf->rx = rx; + + INIT_LIST_HEAD(&rxf->ucast_pending_add_q); + INIT_LIST_HEAD(&rxf->ucast_pending_del_q); + rxf->ucast_pending_set = 0; + INIT_LIST_HEAD(&rxf->ucast_active_q); + rxf->ucast_active_mac = NULL; + + INIT_LIST_HEAD(&rxf->mcast_pending_add_q); + INIT_LIST_HEAD(&rxf->mcast_pending_del_q); + INIT_LIST_HEAD(&rxf->mcast_active_q); + + bfa_q_qe_init(&rxf->mbox_qe.qe); + + if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED) + rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP; + + rxf->rxf_oper_state = (q_config->paused) ? + BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING; + + bna_rxf_adv_init(rxf, rx, q_config); + + rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod, + q_config->num_paths); + + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + if (q_config->rxp_type == BNA_RXP_SINGLE) + rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id; + else + rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id; + break; + } + + rxf->vlan_filter_status = BNA_STATUS_T_DISABLED; + memset(rxf->vlan_filter_table, 0, + (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32))); + + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); +} + +void +bna_rxf_uninit(struct bna_rxf *rxf) +{ + struct bna_mac *mac; + + bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment); + rxf->rit_segment = NULL; + + rxf->ucast_pending_set = 0; + + while (!list_empty(&rxf->ucast_pending_add_q)) { + bfa_q_deq(&rxf->ucast_pending_add_q, &mac); + bfa_q_qe_init(&mac->qe); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + } + + if (rxf->ucast_active_mac) { + bfa_q_qe_init(&rxf->ucast_active_mac->qe); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, + rxf->ucast_active_mac); + rxf->ucast_active_mac = NULL; + } + + while (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &mac); + bfa_q_qe_init(&mac->qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } + + rxf->rx = NULL; +} + +void +bna_rxf_start(struct bna_rxf *rxf) +{ + rxf->start_cbfn = bna_rx_cb_rxf_started; + rxf->start_cbarg = rxf->rx; + rxf->rxf_flags &= ~BNA_RXF_FL_FAILED; + bfa_fsm_send_event(rxf, RXF_E_START); +} + +void +bna_rxf_stop(struct bna_rxf *rxf) +{ + rxf->stop_cbfn = bna_rx_cb_rxf_stopped; + rxf->stop_cbarg = rxf->rx; + bfa_fsm_send_event(rxf, RXF_E_STOP); +} + +void +bna_rxf_fail(struct bna_rxf *rxf) +{ + rxf->rxf_flags |= BNA_RXF_FL_FAILED; + bfa_fsm_send_event(rxf, RXF_E_FAIL); +} + +int +bna_rxf_state_get(struct bna_rxf *rxf) +{ + return bfa_sm_to_state(rxf_sm_table, rxf->fsm); +} + +enum bna_cb_status +bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->ucast_active_mac == NULL) { + rxf->ucast_active_mac = + bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod); + if (rxf->ucast_active_mac == NULL) + return BNA_CB_UCAST_CAM_FULL; + bfa_q_qe_init(&rxf->ucast_active_mac->qe); + } + + memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN); + rxf->ucast_pending_set++; + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + + return BNA_CB_SUCCESS; +} + +enum bna_cb_status +bna_rx_mcast_add(struct bna_rx *rx, u8 *addr, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + + /* Check if already added */ + list_for_each(qe, &rxf->mcast_active_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + /* Check if pending addition */ + list_for_each(qe, &rxf->mcast_pending_add_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod); + if (mac == NULL) + return BNA_CB_MCAST_LIST_FULL; + bfa_q_qe_init(&mac->qe); + memcpy(mac->addr, addr, ETH_ALEN); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + + return BNA_CB_SUCCESS; +} + +enum bna_cb_status +bna_rx_mcast_del(struct bna_rx *rx, u8 *addr, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + + list_for_each(qe, &rxf->mcast_pending_add_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + list_del(qe); + bfa_q_qe_init(qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + list_for_each(qe, &rxf->mcast_active_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + list_del(qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->mcast_pending_del_q); + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + return BNA_CB_SUCCESS; + } + } + + return BNA_CB_INVALID_MAC; +} + +enum bna_cb_status +bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head list_head; + struct list_head *qe; + u8 *mcaddr; + struct bna_mac *mac; + struct bna_mac *mac1; + int skip; + int delete; + int need_hw_config = 0; + int i; + + /* Allocate nodes */ + INIT_LIST_HEAD(&list_head); + for (i = 0, mcaddr = mclist; i < count; i++) { + mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod); + if (mac == NULL) + goto err_return; + bfa_q_qe_init(&mac->qe); + memcpy(mac->addr, mcaddr, ETH_ALEN); + list_add_tail(&mac->qe, &list_head); + + mcaddr += ETH_ALEN; + } + + /* Schedule for addition */ + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + + skip = 0; + + /* Skip if already added */ + list_for_each(qe, &rxf->mcast_active_q) { + mac1 = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) { + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, + mac); + skip = 1; + break; + } + } + + if (skip) + continue; + + /* Skip if pending addition */ + list_for_each(qe, &rxf->mcast_pending_add_q) { + mac1 = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) { + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, + mac); + skip = 1; + break; + } + } + + if (skip) + continue; + + need_hw_config = 1; + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + } + + /** + * Delete the entries that are in the pending_add_q but not + * in the new list + */ + while (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) { + if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) { + delete = 0; + break; + } + mcaddr += ETH_ALEN; + } + if (delete) + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + else + list_add_tail(&mac->qe, &list_head); + } + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + } + + /** + * Schedule entries for deletion that are in the active_q but not + * in the new list + */ + while (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) { + if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) { + delete = 0; + break; + } + mcaddr += ETH_ALEN; + } + if (delete) { + list_add_tail(&mac->qe, &rxf->mcast_pending_del_q); + need_hw_config = 1; + } else { + list_add_tail(&mac->qe, &list_head); + } + } + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + list_add_tail(&mac->qe, &rxf->mcast_active_q); + } + + if (need_hw_config) { + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + + return BNA_CB_SUCCESS; + +err_return: + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } + + return BNA_CB_MCAST_LIST_FULL; +} + +void +bna_rx_vlan_add(struct bna_rx *rx, int vlan_id) +{ + struct bna_rxf *rxf = &rx->rxf; + int index = (vlan_id >> 5); + int bit = (1 << (vlan_id & 0x1F)); + + rxf->vlan_filter_table[index] |= bit; + if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +void +bna_rx_vlan_del(struct bna_rx *rx, int vlan_id) +{ + struct bna_rxf *rxf = &rx->rxf; + int index = (vlan_id >> 5); + int bit = (1 << (vlan_id & 0x1F)); + + rxf->vlan_filter_table[index] &= ~bit; + if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +/** + * RX + */ +#define RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem) do { \ + struct bna_doorbell_qset *_qset; \ + unsigned long off; \ + (q)->rcb->producer_index = (q)->rcb->consumer_index = 0; \ + (q)->rcb->q_depth = (qdepth); \ + (q)->rcb->unmap_q = unmapq_mem; \ + (q)->rcb->rxq = (q); \ + (q)->rcb->cq = &(rxp)->cq; \ + (q)->rcb->bnad = (bna)->bnad; \ + _qset = (struct bna_doorbell_qset *)0; \ + off = (unsigned long)&_qset[(q)->rxq_id].rxq[0]; \ + (q)->rcb->q_dbell = off + \ + BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva); \ + (q)->rcb->id = _id; \ +} while (0) + +#define BNA_GET_RXQS(qcfg) (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \ + (qcfg)->num_paths : ((qcfg)->num_paths * 2)) + +#define SIZE_TO_PAGES(size) (((size) >> PAGE_SHIFT) + ((((size) &\ + (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) + +#define call_rx_stop_callback(rx, status) \ + if ((rx)->stop_cbfn) { \ + (*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status)); \ + (rx)->stop_cbfn = NULL; \ + (rx)->stop_cbarg = NULL; \ + } + +/* + * Since rx_enable is synchronous callback, there is no start_cbfn required. + * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers + * for each rxpath. + */ + +#define call_rx_disable_cbfn(rx, status) \ + if ((rx)->disable_cbfn) { \ + (*(rx)->disable_cbfn)((rx)->disable_cbarg, \ + status); \ + (rx)->disable_cbfn = NULL; \ + (rx)->disable_cbarg = NULL; \ + } \ + +#define rxqs_reqd(type, num_rxqs) \ + (((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2)) + +#define rx_ib_fail(rx) \ +do { \ + struct bna_rxp *rxp; \ + struct list_head *qe; \ + list_for_each(qe, &(rx)->rxp_q) { \ + rxp = (struct bna_rxp *)qe; \ + bna_ib_fail(rxp->cq.ib); \ + } \ +} while (0) + +static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *); +static void __bna_rxq_start(struct bna_rxq *rxq); +static void __bna_cq_start(struct bna_cq *cq); +static void bna_rit_create(struct bna_rx *rx); +static void bna_rx_cb_multi_rxq_stopped(void *arg, int status); +static void bna_rx_cb_rxq_stopped_all(void *arg); + +bfa_fsm_state_decl(bna_rx, stopped, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxf_start_wait, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, started, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxf_stop_wait, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxq_stop_wait, + struct bna_rx, enum bna_rx_event); + +static struct bfa_sm_table rx_sm_table[] = { + {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED}, + {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT}, + {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED}, + {BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT}, + {BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT}, +}; + +static void bna_rx_sm_stopped_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb); + } + + call_rx_stop_callback(rx, BNA_CB_SUCCESS); +} + +static void bna_rx_sm_stopped(struct bna_rx *rx, + enum bna_rx_event event) +{ + switch (event) { + case RX_E_START: + bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait); + break; + case RX_E_STOP: + call_rx_stop_callback(rx, BNA_CB_SUCCESS); + break; + case RX_E_FAIL: + /* no-op */ + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } + +} + +static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + struct bna_rxq *q0 = NULL, *q1 = NULL; + + /* Setup the RIT */ + bna_rit_create(rx); + + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + bna_ib_start(rxp->cq.ib); + GET_RXQS(rxp, q0, q1); + q0->buffer_size = bna_port_mtu_get(&rx->bna->port); + __bna_rxq_start(q0); + rx->rx_post_cbfn(rx->bna->bnad, q0->rcb); + if (q1) { + __bna_rxq_start(q1); + rx->rx_post_cbfn(rx->bna->bnad, q1->rcb); + } + __bna_cq_start(&rxp->cq); + } + + bna_rxf_start(&rx->rxf); +} + +static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx, + enum bna_rx_event event) +{ + switch (event) { + case RX_E_STOP: + bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait); + break; + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + case RX_E_RXF_STARTED: + bfa_fsm_set_state(rx, bna_rx_sm_started); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +bna_rx_sm_started_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + + /* Start IB */ + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + bna_ib_ack(&rxp->cq.ib->door_bell, 0); + } + + bna_llport_admin_up(&rx->bna->port.llport); +} + +void +bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event) +{ + switch (event) { + case RX_E_FAIL: + bna_llport_admin_down(&rx->bna->port.llport); + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + case RX_E_STOP: + bna_llport_admin_down(&rx->bna->port.llport); + bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx) +{ + bna_rxf_stop(&rx->rxf); +} + +void +bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event) +{ + switch (event) { + case RX_E_RXF_STOPPED: + bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait); + break; + case RX_E_RXF_STARTED: + /** + * RxF was in the process of starting up when + * RXF_E_STOP was issued. Ignore this event + */ + break; + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } + +} + +void +bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp = NULL; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + struct list_head *qe; + u32 rxq_mask[2] = {0, 0}; + + /* Only one call to multi-rxq-stop for all RXPs in this RX */ + bfa_wc_up(&rx->rxq_stop_wc); + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + GET_RXQS(rxp, q0, q1); + if (q0->rxq_id < 32) + rxq_mask[0] |= ((u32)1 << q0->rxq_id); + else + rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32)); + if (q1) { + if (q1->rxq_id < 32) + rxq_mask[0] |= ((u32)1 << q1->rxq_id); + else + rxq_mask[1] |= ((u32) + 1 << (q1->rxq_id - 32)); + } + } + + __bna_multi_rxq_stop(rxp, rxq_mask); +} + +void +bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event) +{ + struct bna_rxp *rxp = NULL; + struct list_head *qe; + + switch (event) { + case RX_E_RXQ_STOPPED: + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + bna_ib_stop(rxp->cq.ib); + } + /* Fall through */ + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask) +{ + struct bfi_ll_q_stop_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0); + ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]); + ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]); + bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req), + bna_rx_cb_multi_rxq_stopped, rxp); + bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe); +} + +void +__bna_rxq_start(struct bna_rxq *rxq) +{ + struct bna_rxtx_q_mem *q_mem; + struct bna_rxq_mem rxq_cfg, *rxq_mem; + struct bna_dma_addr cur_q_addr; + /* struct bna_doorbell_qset *qset; */ + struct bna_qpt *qpt; + u32 pg_num; + struct bna *bna = rxq->rx->bna; + void __iomem *base_addr; + unsigned long off; + + qpt = &rxq->qpt; + cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr)); + + rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb; + rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb; + rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + rxq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0; + rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) | + (qpt->page_size >> 2); + rxq_cfg.sg_n_cq_n_cns_ptr = + ((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0; + rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) | + BNA_Q_IDLE_STATE; + rxq_cfg.next_qid = 0x0 | (0x3 << 8); + + /* Write the page number register */ + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num, + HQM_RXTX_Q_RAM_BASE_OFFSET); + writel(pg_num, bna->regs.page_addr); + + /* Write to h/w */ + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + HQM_RXTX_Q_RAM_BASE_OFFSET); + + q_mem = (struct bna_rxtx_q_mem *)0; + rxq_mem = &q_mem[rxq->rxq_id].rxq; + + off = (unsigned long)&rxq_mem->pg_tbl_addr_lo; + writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&rxq_mem->pg_tbl_addr_hi; + writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&rxq_mem->cur_q_entry_lo; + writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&rxq_mem->cur_q_entry_hi; + writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr; + writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&rxq_mem->entry_n_pg_size; + writel(rxq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr; + writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off); + + off = (unsigned long)&rxq_mem->buf_sz_n_q_state; + writel(rxq_cfg.buf_sz_n_q_state, base_addr + off); + + off = (unsigned long)&rxq_mem->next_qid; + writel(rxq_cfg.next_qid, base_addr + off); + + rxq->rcb->producer_index = 0; + rxq->rcb->consumer_index = 0; +} + +void +__bna_cq_start(struct bna_cq *cq) +{ + struct bna_cq_mem cq_cfg, *cq_mem; + const struct bna_qpt *qpt; + struct bna_dma_addr cur_q_addr; + u32 pg_num; + struct bna *bna = cq->rx->bna; + void __iomem *base_addr; + unsigned long off; + + qpt = &cq->qpt; + cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr)); + + /* + * Fill out structure, to be subsequently written + * to hardware + */ + cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb; + cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb; + cq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + cq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0; + cq_cfg.entry_n_pg_size = + ((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2); + cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) | + ((u32)(cq->ib->ib_id & 0xff) << 16) | 0x0); + cq_cfg.q_state = BNA_Q_IDLE_STATE; + + /* Write the page number register */ + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num, + HQM_CQ_RAM_BASE_OFFSET); + + writel(pg_num, bna->regs.page_addr); + + /* H/W write */ + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + HQM_CQ_RAM_BASE_OFFSET); + + cq_mem = (struct bna_cq_mem *)0; + + off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo; + writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi; + writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo; + writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi; + writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr; + writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size; + writel(cq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr; + writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].q_state; + writel(cq_cfg.q_state, base_addr + off); + + cq->ccb->producer_index = 0; + *(cq->ccb->hw_producer_index) = 0; +} + +void +bna_rit_create(struct bna_rx *rx) +{ + struct list_head *qe_rxp; + struct bna *bna; + struct bna_rxp *rxp; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + int offset; + + bna = rx->bna; + + offset = 0; + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + GET_RXQS(rxp, q0, q1); + rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id; + rx->rxf.rit_segment->rit[offset].small_rxq_id = + (q1 ? q1->rxq_id : 0); + offset++; + } +} + +int +_rx_can_satisfy(struct bna_rx_mod *rx_mod, + struct bna_rx_config *rx_cfg) +{ + if ((rx_mod->rx_free_count == 0) || + (rx_mod->rxp_free_count == 0) || + (rx_mod->rxq_free_count == 0)) + return 0; + + if (rx_cfg->rxp_type == BNA_RXP_SINGLE) { + if ((rx_mod->rxp_free_count < rx_cfg->num_paths) || + (rx_mod->rxq_free_count < rx_cfg->num_paths)) + return 0; + } else { + if ((rx_mod->rxp_free_count < rx_cfg->num_paths) || + (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths))) + return 0; + } + + if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths)) + return 0; + + return 1; +} + +struct bna_rxq * +_get_free_rxq(struct bna_rx_mod *rx_mod) +{ + struct bna_rxq *rxq = NULL; + struct list_head *qe = NULL; + + bfa_q_deq(&rx_mod->rxq_free_q, &qe); + if (qe) { + rx_mod->rxq_free_count--; + rxq = (struct bna_rxq *)qe; + } + return rxq; +} + +void +_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq) +{ + bfa_q_qe_init(&rxq->qe); + list_add_tail(&rxq->qe, &rx_mod->rxq_free_q); + rx_mod->rxq_free_count++; +} + +struct bna_rxp * +_get_free_rxp(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe = NULL; + struct bna_rxp *rxp = NULL; + + bfa_q_deq(&rx_mod->rxp_free_q, &qe); + if (qe) { + rx_mod->rxp_free_count--; + + rxp = (struct bna_rxp *)qe; + } + + return rxp; +} + +void +_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp) +{ + bfa_q_qe_init(&rxp->qe); + list_add_tail(&rxp->qe, &rx_mod->rxp_free_q); + rx_mod->rxp_free_count++; +} + +struct bna_rx * +_get_free_rx(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe = NULL; + struct bna_rx *rx = NULL; + + bfa_q_deq(&rx_mod->rx_free_q, &qe); + if (qe) { + rx_mod->rx_free_count--; + + rx = (struct bna_rx *)qe; + bfa_q_qe_init(qe); + list_add_tail(&rx->qe, &rx_mod->rx_active_q); + } + + return rx; +} + +void +_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx) +{ + bfa_q_qe_init(&rx->qe); + list_add_tail(&rx->qe, &rx_mod->rx_free_q); + rx_mod->rx_free_count++; +} + +void +_rx_init(struct bna_rx *rx, struct bna *bna) +{ + rx->bna = bna; + rx->rx_flags = 0; + + INIT_LIST_HEAD(&rx->rxp_q); + + rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all; + rx->rxq_stop_wc.wc_cbarg = rx; + rx->rxq_stop_wc.wc_count = 0; + + rx->stop_cbfn = NULL; + rx->stop_cbarg = NULL; +} + +void +_rxp_add_rxqs(struct bna_rxp *rxp, + struct bna_rxq *q0, + struct bna_rxq *q1) +{ + switch (rxp->type) { + case BNA_RXP_SINGLE: + rxp->rxq.single.only = q0; + rxp->rxq.single.reserved = NULL; + break; + case BNA_RXP_SLR: + rxp->rxq.slr.large = q0; + rxp->rxq.slr.small = q1; + break; + case BNA_RXP_HDS: + rxp->rxq.hds.data = q0; + rxp->rxq.hds.hdr = q1; + break; + default: + break; + } +} + +void +_rxq_qpt_init(struct bna_rxq *rxq, + struct bna_rxp *rxp, + u32 page_count, + u32 page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + rxq->qpt.kv_qpt_ptr = qpt_mem->kva; + rxq->qpt.page_count = page_count; + rxq->qpt.page_size = page_size; + + rxq->rcb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < rxq->qpt.page_count; i++) { + rxq->rcb->sw_qpt[i] = page_mem[i].kva; + ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +void +_rxp_cqpt_setup(struct bna_rxp *rxp, + u32 page_count, + u32 page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva; + rxp->cq.qpt.page_count = page_count; + rxp->cq.qpt.page_size = page_size; + + rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < rxp->cq.qpt.page_count; i++) { + rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva; + + ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +void +_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp) +{ + list_add_tail(&rxp->qe, &rx->rxp_q); +} + +void +_init_rxmod_queues(struct bna_rx_mod *rx_mod) +{ + INIT_LIST_HEAD(&rx_mod->rx_free_q); + INIT_LIST_HEAD(&rx_mod->rxq_free_q); + INIT_LIST_HEAD(&rx_mod->rxp_free_q); + INIT_LIST_HEAD(&rx_mod->rx_active_q); + + rx_mod->rx_free_count = 0; + rx_mod->rxq_free_count = 0; + rx_mod->rxp_free_count = 0; +} + +void +_rx_ctor(struct bna_rx *rx, int id) +{ + bfa_q_qe_init(&rx->qe); + INIT_LIST_HEAD(&rx->rxp_q); + rx->bna = NULL; + + rx->rxf.rxf_id = id; + + /* FIXME: mbox_qe ctor()?? */ + bfa_q_qe_init(&rx->mbox_qe.qe); + + rx->stop_cbfn = NULL; + rx->stop_cbarg = NULL; +} + +void +bna_rx_cb_multi_rxq_stopped(void *arg, int status) +{ + struct bna_rxp *rxp = (struct bna_rxp *)arg; + + bfa_wc_down(&rxp->rx->rxq_stop_wc); +} + +void +bna_rx_cb_rxq_stopped_all(void *arg) +{ + struct bna_rx *rx = (struct bna_rx *)arg; + + bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED); +} + +void +bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx, + enum bna_cb_status status) +{ + struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg; + + bfa_wc_down(&rx_mod->rx_stop_wc); +} + +void +bna_rx_mod_cb_rx_stopped_all(void *arg) +{ + struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg; + + if (rx_mod->stop_cbfn) + rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS); + rx_mod->stop_cbfn = NULL; +} + +void +bna_rx_start(struct bna_rx *rx) +{ + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + if (rx->rx_flags & BNA_RX_F_ENABLE) + bfa_fsm_send_event(rx, RX_E_START); +} + +void +bna_rx_stop(struct bna_rx *rx) +{ + rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED; + if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped) + bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS); + else { + rx->stop_cbfn = bna_rx_mod_cb_rx_stopped; + rx->stop_cbarg = &rx->bna->rx_mod; + bfa_fsm_send_event(rx, RX_E_STOP); + } +} + +void +bna_rx_fail(struct bna_rx *rx) +{ + /* Indicate port is not enabled, and failed */ + rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED; + rx->rx_flags |= BNA_RX_F_PORT_FAILED; + bfa_fsm_send_event(rx, RX_E_FAIL); +} + +void +bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STARTED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id); + else + rx->bna->rx_mod.rxf_bmap[1] |= ((u32) + 1 << (rx->rxf.rxf_id - 32)); +} + +void +bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STOPPED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id; + else + rx->bna->rx_mod.rxf_bmap[1] &= ~(u32) + 1 << (rx->rxf.rxf_id - 32); +} + +void +bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED; + if (type == BNA_RX_T_LOOPBACK) + rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bna_rx_start(rx); + } +} + +void +bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED; + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK; + + rx_mod->stop_cbfn = bna_port_cb_rx_stopped; + + /** + * Before calling bna_rx_stop(), increment rx_stop_wc as many times + * as we are going to call bna_rx_stop + */ + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bfa_wc_up(&rx_mod->rx_stop_wc); + } + + if (rx_mod->rx_stop_wc.wc_count == 0) { + rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS); + rx_mod->stop_cbfn = NULL; + return; + } + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bna_rx_stop(rx); + } +} + +void +bna_rx_mod_fail(struct bna_rx_mod *rx_mod) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED; + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + bna_rx_fail(rx); + } +} + +void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int index; + struct bna_rx *rx_ptr; + struct bna_rxp *rxp_ptr; + struct bna_rxq *rxq_ptr; + + rx_mod->bna = bna; + rx_mod->flags = 0; + + rx_mod->rx = (struct bna_rx *) + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva; + rx_mod->rxp = (struct bna_rxp *) + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva; + rx_mod->rxq = (struct bna_rxq *) + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva; + + /* Initialize the queues */ + _init_rxmod_queues(rx_mod); + + /* Build RX queues */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rx_ptr = &rx_mod->rx[index]; + _rx_ctor(rx_ptr, index); + list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q); + rx_mod->rx_free_count++; + } + + /* build RX-path queue */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rxp_ptr = &rx_mod->rxp[index]; + rxp_ptr->cq.cq_id = index; + bfa_q_qe_init(&rxp_ptr->qe); + list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q); + rx_mod->rxp_free_count++; + } + + /* build RXQ queue */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rxq_ptr = &rx_mod->rxq[index]; + rxq_ptr->rxq_id = index; + + bfa_q_qe_init(&rxq_ptr->qe); + list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q); + rx_mod->rxq_free_count++; + } + + rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all; + rx_mod->rx_stop_wc.wc_cbarg = rx_mod; + rx_mod->rx_stop_wc.wc_count = 0; +} + +void +bna_rx_mod_uninit(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe; + int i; + + i = 0; + list_for_each(qe, &rx_mod->rx_free_q) + i++; + + i = 0; + list_for_each(qe, &rx_mod->rxp_free_q) + i++; + + i = 0; + list_for_each(qe, &rx_mod->rxq_free_q) + i++; + + rx_mod->bna = NULL; +} + +int +bna_rx_state_get(struct bna_rx *rx) +{ + return bfa_sm_to_state(rx_sm_table, rx->fsm); +} + +void +bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info) +{ + u32 cq_size, hq_size, dq_size; + u32 cpage_count, hpage_count, dpage_count; + struct bna_mem_info *mem_info; + u32 cq_depth; + u32 hq_depth; + u32 dq_depth; + + dq_depth = q_cfg->q_depth; + hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth); + cq_depth = dq_depth + hq_depth; + + BNA_TO_POWER_OF_2_HIGH(cq_depth); + cq_size = cq_depth * BFI_CQ_WI_SIZE; + cq_size = ALIGN(cq_size, PAGE_SIZE); + cpage_count = SIZE_TO_PAGES(cq_size); + + BNA_TO_POWER_OF_2_HIGH(dq_depth); + dq_size = dq_depth * BFI_RXQ_WI_SIZE; + dq_size = ALIGN(dq_size, PAGE_SIZE); + dpage_count = SIZE_TO_PAGES(dq_size); + + if (BNA_RXP_SINGLE != q_cfg->rxp_type) { + BNA_TO_POWER_OF_2_HIGH(hq_depth); + hq_size = hq_depth * BFI_RXQ_WI_SIZE; + hq_size = ALIGN(hq_size, PAGE_SIZE); + hpage_count = SIZE_TO_PAGES(hq_size); + } else { + hpage_count = 0; + } + + /* CCB structures */ + res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_ccb); + mem_info->num = q_cfg->num_paths; + + /* RCB structures */ + res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_rcb); + mem_info->num = BNA_GET_RXQS(q_cfg); + + /* Completion QPT */ + res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = cpage_count * sizeof(struct bna_dma_addr); + mem_info->num = q_cfg->num_paths; + + /* Completion s/w QPT */ + res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = cpage_count * sizeof(void *); + mem_info->num = q_cfg->num_paths; + + /* Completion QPT pages */ + res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = cpage_count * q_cfg->num_paths; + + /* Data QPTs */ + res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = dpage_count * sizeof(struct bna_dma_addr); + mem_info->num = q_cfg->num_paths; + + /* Data s/w QPTs */ + res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = dpage_count * sizeof(void *); + mem_info->num = q_cfg->num_paths; + + /* Data QPT pages */ + res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = dpage_count * q_cfg->num_paths; + + /* Hdr QPTs */ + res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = hpage_count * sizeof(struct bna_dma_addr); + mem_info->num = (hpage_count ? q_cfg->num_paths : 0); + + /* Hdr s/w QPTs */ + res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = hpage_count * sizeof(void *); + mem_info->num = (hpage_count ? q_cfg->num_paths : 0); + + /* Hdr QPT pages */ + res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = (hpage_count ? PAGE_SIZE : 0); + mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0); + + /* RX Interrupts */ + res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR; + res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX; + res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths; +} + +struct bna_rx * +bna_rx_create(struct bna *bna, struct bnad *bnad, + struct bna_rx_config *rx_cfg, + struct bna_rx_event_cbfn *rx_cbfn, + struct bna_res_info *res_info, + void *priv) +{ + struct bna_rx_mod *rx_mod = &bna->rx_mod; + struct bna_rx *rx; + struct bna_rxp *rxp; + struct bna_rxq *q0; + struct bna_rxq *q1; + struct bna_intr_info *intr_info; + u32 page_count; + struct bna_mem_descr *ccb_mem; + struct bna_mem_descr *rcb_mem; + struct bna_mem_descr *unmapq_mem; + struct bna_mem_descr *cqpt_mem; + struct bna_mem_descr *cswqpt_mem; + struct bna_mem_descr *cpage_mem; + struct bna_mem_descr *hqpt_mem; /* Header/Small Q qpt */ + struct bna_mem_descr *dqpt_mem; /* Data/Large Q qpt */ + struct bna_mem_descr *hsqpt_mem; /* s/w qpt for hdr */ + struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */ + struct bna_mem_descr *hpage_mem; /* hdr page mem */ + struct bna_mem_descr *dpage_mem; /* data page mem */ + int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret; + int dpage_count, hpage_count, rcb_idx; + struct bna_ib_config ibcfg; + /* Fail if we don't have enough RXPs, RXQs */ + if (!_rx_can_satisfy(rx_mod, rx_cfg)) + return NULL; + + /* Initialize resource pointers */ + intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info; + ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0]; + rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0]; + unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0]; + cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0]; + cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0]; + cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0]; + hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0]; + dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0]; + hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0]; + dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0]; + hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0]; + dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0]; + + /* Compute q depth & page count */ + page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num / + rx_cfg->num_paths; + + dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num / + rx_cfg->num_paths; + + hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num / + rx_cfg->num_paths; + /* Get RX pointer */ + rx = _get_free_rx(rx_mod); + _rx_init(rx, bna); + rx->priv = priv; + rx->type = rx_cfg->rx_type; + + rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn; + rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn; + rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn; + rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn; + /* Following callbacks are mandatory */ + rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn; + rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn; + + if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) { + switch (rx->type) { + case BNA_RX_T_REGULAR: + if (!(rx->bna->rx_mod.flags & + BNA_RX_MOD_F_PORT_LOOPBACK)) + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + break; + case BNA_RX_T_LOOPBACK: + if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK) + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + break; + } + } + + for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) { + rxp = _get_free_rxp(rx_mod); + rxp->type = rx_cfg->rxp_type; + rxp->rx = rx; + rxp->cq.rx = rx; + + /* Get required RXQs, and queue them to rx-path */ + q0 = _get_free_rxq(rx_mod); + if (BNA_RXP_SINGLE == rx_cfg->rxp_type) + q1 = NULL; + else + q1 = _get_free_rxq(rx_mod); + + /* Initialize IB */ + if (1 == intr_info->num) { + rxp->cq.ib = bna_ib_get(&bna->ib_mod, + intr_info->intr_type, + intr_info->idl[0].vector); + rxp->vector = intr_info->idl[0].vector; + } else { + rxp->cq.ib = bna_ib_get(&bna->ib_mod, + intr_info->intr_type, + intr_info->idl[i].vector); + + /* Map the MSI-x vector used for this RXP */ + rxp->vector = intr_info->idl[i].vector; + } + + rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib); + + ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO; + ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT; + ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO; + ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE; + + ret = bna_ib_config(rxp->cq.ib, &ibcfg); + + /* Link rxqs to rxp */ + _rxp_add_rxqs(rxp, q0, q1); + + /* Link rxp to rx */ + _rx_add_rxp(rx, rxp); + + q0->rx = rx; + q0->rxp = rxp; + + /* Initialize RCB for the large / data q */ + q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva; + RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0, + (void *)unmapq_mem[rcb_idx].kva); + rcb_idx++; + (q0)->rx_packets = (q0)->rx_bytes = 0; + (q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0; + + /* Initialize RXQs */ + _rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE, + &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]); + q0->rcb->page_idx = dpage_idx; + q0->rcb->page_count = dpage_count; + dpage_idx += dpage_count; + + /* Call bnad to complete rcb setup */ + if (rx->rcb_setup_cbfn) + rx->rcb_setup_cbfn(bnad, q0->rcb); + + if (q1) { + q1->rx = rx; + q1->rxp = rxp; + + q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva; + RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1, + (void *)unmapq_mem[rcb_idx].kva); + rcb_idx++; + (q1)->buffer_size = (rx_cfg)->small_buff_size; + (q1)->rx_packets = (q1)->rx_bytes = 0; + (q1)->rx_packets_with_error = + (q1)->rxbuf_alloc_failed = 0; + + _rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE, + &hqpt_mem[i], &hsqpt_mem[i], + &hpage_mem[hpage_idx]); + q1->rcb->page_idx = hpage_idx; + q1->rcb->page_count = hpage_count; + hpage_idx += hpage_count; + + /* Call bnad to complete rcb setup */ + if (rx->rcb_setup_cbfn) + rx->rcb_setup_cbfn(bnad, q1->rcb); + } + /* Setup RXP::CQ */ + rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva; + _rxp_cqpt_setup(rxp, page_count, PAGE_SIZE, + &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]); + rxp->cq.ccb->page_idx = cpage_idx; + rxp->cq.ccb->page_count = page_count; + cpage_idx += page_count; + + rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0; + rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0; + + rxp->cq.ccb->producer_index = 0; + rxp->cq.ccb->q_depth = rx_cfg->q_depth + + ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ? + 0 : rx_cfg->q_depth); + rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell; + rxp->cq.ccb->rcb[0] = q0->rcb; + if (q1) + rxp->cq.ccb->rcb[1] = q1->rcb; + rxp->cq.ccb->cq = &rxp->cq; + rxp->cq.ccb->bnad = bna->bnad; + rxp->cq.ccb->hw_producer_index = + ((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva + + (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE)); + *(rxp->cq.ccb->hw_producer_index) = 0; + rxp->cq.ccb->intr_type = intr_info->intr_type; + rxp->cq.ccb->intr_vector = (intr_info->num == 1) ? + intr_info->idl[0].vector : + intr_info->idl[i].vector; + rxp->cq.ccb->rx_coalescing_timeo = + rxp->cq.ib->ib_config.coalescing_timeo; + rxp->cq.ccb->id = i; + + /* Call bnad to complete CCB setup */ + if (rx->ccb_setup_cbfn) + rx->ccb_setup_cbfn(bnad, rxp->cq.ccb); + + } /* for each rx-path */ + + bna_rxf_init(&rx->rxf, rx, rx_cfg); + + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + + return rx; +} + +void +bna_rx_destroy(struct bna_rx *rx) +{ + struct bna_rx_mod *rx_mod = &rx->bna->rx_mod; + struct bna_ib_mod *ib_mod = &rx->bna->ib_mod; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + struct bna_rxp *rxp; + struct list_head *qe; + + bna_rxf_uninit(&rx->rxf); + + while (!list_empty(&rx->rxp_q)) { + bfa_q_deq(&rx->rxp_q, &rxp); + GET_RXQS(rxp, q0, q1); + /* Callback to bnad for destroying RCB */ + if (rx->rcb_destroy_cbfn) + rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb); + q0->rcb = NULL; + q0->rxp = NULL; + q0->rx = NULL; + _put_free_rxq(rx_mod, q0); + if (q1) { + /* Callback to bnad for destroying RCB */ + if (rx->rcb_destroy_cbfn) + rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb); + q1->rcb = NULL; + q1->rxp = NULL; + q1->rx = NULL; + _put_free_rxq(rx_mod, q1); + } + rxp->rxq.slr.large = NULL; + rxp->rxq.slr.small = NULL; + if (rxp->cq.ib) { + if (rxp->cq.ib_seg_offset != 0xff) + bna_ib_release_idx(rxp->cq.ib, + rxp->cq.ib_seg_offset); + bna_ib_put(ib_mod, rxp->cq.ib); + rxp->cq.ib = NULL; + } + /* Callback to bnad for destroying CCB */ + if (rx->ccb_destroy_cbfn) + rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb); + rxp->cq.ccb = NULL; + rxp->rx = NULL; + _put_free_rxp(rx_mod, rxp); + } + + list_for_each(qe, &rx_mod->rx_active_q) { + if (qe == &rx->qe) { + list_del(&rx->qe); + bfa_q_qe_init(&rx->qe); + break; + } + } + + rx->bna = NULL; + rx->priv = NULL; + _put_free_rx(rx_mod, rx); +} + +void +bna_rx_enable(struct bna_rx *rx) +{ + if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped) + return; + + rx->rx_flags |= BNA_RX_F_ENABLE; + if (rx->rx_flags & BNA_RX_F_PORT_ENABLED) + bfa_fsm_send_event(rx, RX_E_START); +} + +void +bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_rx *, + enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + /* h/w should not be accessed. Treat we're stopped */ + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + } else { + rx->stop_cbfn = cbfn; + rx->stop_cbarg = rx->bna->bnad; + + rx->rx_flags &= ~BNA_RX_F_ENABLE; + + bfa_fsm_send_event(rx, RX_E_STOP); + } +} + +/** + * TX + */ +#define call_tx_stop_cbfn(tx, status)\ +do {\ + if ((tx)->stop_cbfn)\ + (tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\ + (tx)->stop_cbfn = NULL;\ + (tx)->stop_cbarg = NULL;\ +} while (0) + +#define call_tx_prio_change_cbfn(tx, status)\ +do {\ + if ((tx)->prio_change_cbfn)\ + (tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\ + (tx)->prio_change_cbfn = NULL;\ +} while (0) + +static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx, + enum bna_cb_status status); +static void bna_tx_cb_txq_stopped(void *arg, int status); +static void bna_tx_cb_stats_cleared(void *arg, int status); +static void __bna_tx_stop(struct bna_tx *tx); +static void __bna_tx_start(struct bna_tx *tx); +static void __bna_txf_stat_clr(struct bna_tx *tx); + +enum bna_tx_event { + TX_E_START = 1, + TX_E_STOP = 2, + TX_E_FAIL = 3, + TX_E_TXQ_STOPPED = 4, + TX_E_PRIO_CHANGE = 5, + TX_E_STAT_CLEARED = 6, +}; + +enum bna_tx_state { + BNA_TX_STOPPED = 1, + BNA_TX_STARTED = 2, + BNA_TX_TXQ_STOP_WAIT = 3, + BNA_TX_PRIO_STOP_WAIT = 4, + BNA_TX_STAT_CLR_WAIT = 5, +}; + +bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, started, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx, + enum bna_tx_event); + +static struct bfa_sm_table tx_sm_table[] = { + {BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED}, + {BFA_SM(bna_tx_sm_started), BNA_TX_STARTED}, + {BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT}, + {BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT}, + {BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT}, +}; + +static void +bna_tx_sm_stopped_entry(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb); + } + + call_tx_stop_cbfn(tx, BNA_CB_SUCCESS); +} + +static void +bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event) +{ + switch (event) { + case TX_E_START: + bfa_fsm_set_state(tx, bna_tx_sm_started); + break; + + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_FAIL: + /* No-op */ + break; + + case TX_E_PRIO_CHANGE: + call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS); + break; + + case TX_E_TXQ_STOPPED: + /** + * This event is received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_started_entry(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + __bna_tx_start(tx); + + /* Start IB */ + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_ack(&txq->ib->door_bell, 0); + } +} + +static void +bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait); + __bna_tx_stop(tx); + break; + + case TX_E_FAIL: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_fail(txq->ib); + (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb); + } + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_PRIO_CHANGE: + bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait); + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx) +{ +} + +static void +bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_FAIL: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_TXQ_STOPPED: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_stop(txq->ib); + } + bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait); + break; + + case TX_E_PRIO_CHANGE: + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx) +{ + __bna_tx_stop(tx); +} + +static void +bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait); + break; + + case TX_E_FAIL: + call_tx_prio_change_cbfn(tx, BNA_CB_FAIL); + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_TXQ_STOPPED: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_stop(txq->ib); + (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb); + } + call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS); + bfa_fsm_set_state(tx, bna_tx_sm_started); + break; + + case TX_E_PRIO_CHANGE: + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx) +{ + __bna_txf_stat_clr(tx); +} + +static void +bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + switch (event) { + case TX_E_FAIL: + case TX_E_STAT_CLEARED: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq) +{ + struct bna_rxtx_q_mem *q_mem; + struct bna_txq_mem txq_cfg; + struct bna_txq_mem *txq_mem; + struct bna_dma_addr cur_q_addr; + u32 pg_num; + void __iomem *base_addr; + unsigned long off; + + /* Fill out structure, to be subsequently written to hardware */ + txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb; + txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb; + cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr)); + txq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + txq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0; + + txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) | + (txq->qpt.page_size >> 2); + txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) | + ((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0); + + txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE; + txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) | + (txq->priority & 0x3)); + txq_cfg.wvc_n_cquota_n_rquota = + ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) | + (BFI_TX_MAX_WRR_QUOTA & 0xfff)); + + /* Setup the page and write to H/W */ + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num, + HQM_RXTX_Q_RAM_BASE_OFFSET); + writel(pg_num, tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + HQM_RXTX_Q_RAM_BASE_OFFSET); + q_mem = (struct bna_rxtx_q_mem *)0; + txq_mem = &q_mem[txq->txq_id].txq; + + /* + * The following 4 lines, is a hack b'cos the H/W needs to read + * these DMA addresses as little endian + */ + + off = (unsigned long)&txq_mem->pg_tbl_addr_lo; + writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&txq_mem->pg_tbl_addr_hi; + writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&txq_mem->cur_q_entry_lo; + writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&txq_mem->cur_q_entry_hi; + writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr; + writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&txq_mem->entry_n_pg_size; + writel(txq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&txq_mem->int_blk_n_cns_ptr; + writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off); + + off = (unsigned long)&txq_mem->cns_ptr2_n_q_state; + writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off); + + off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri; + writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off); + + off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota; + writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off); + + txq->tcb->producer_index = 0; + txq->tcb->consumer_index = 0; + *(txq->tcb->hw_consumer_index) = 0; + +} + +static void +__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq) +{ + struct bfi_ll_q_stop_req ll_req; + u32 bit_mask[2] = {0, 0}; + if (txq->txq_id < 32) + bit_mask[0] = (u32)1 << txq->txq_id; + else + bit_mask[1] = (u32)1 << (txq->txq_id - 32); + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + ll_req.q_id_mask[0] = htonl(bit_mask[0]); + ll_req.q_id_mask[1] = htonl(bit_mask[1]); + + bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req), + bna_tx_cb_txq_stopped, tx); + + bna_mbox_send(tx->bna, &tx->mbox_qe); +} + +static void +__bna_txf_start(struct bna_tx *tx) +{ + struct bna_tx_fndb_ram *tx_fndb; + struct bna_txf *txf = &tx->txf; + void __iomem *base_addr; + unsigned long off; + + writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET), + tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + TX_FNDB_RAM_BASE_OFFSET); + + tx_fndb = (struct bna_tx_fndb_ram *)0; + off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags; + + writel(((u32)txf->vlan << 16) | txf->ctrl_flags, + base_addr + off); + + if (tx->txf.txf_id < 32) + tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id); + else + tx->bna->tx_mod.txf_bmap[1] |= ((u32) + 1 << (tx->txf.txf_id - 32)); +} + +static void +__bna_txf_stop(struct bna_tx *tx) +{ + struct bna_tx_fndb_ram *tx_fndb; + u32 page_num; + u32 ctl_flags; + struct bna_txf *txf = &tx->txf; + void __iomem *base_addr; + unsigned long off; + + /* retrieve the running txf_flags & turn off enable bit */ + page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET); + writel(page_num, tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + TX_FNDB_RAM_BASE_OFFSET); + tx_fndb = (struct bna_tx_fndb_ram *)0; + off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags; + + ctl_flags = readl(base_addr + off); + ctl_flags &= ~BFI_TXF_CF_ENABLE; + + writel(ctl_flags, base_addr + off); + + if (tx->txf.txf_id < 32) + tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id); + else + tx->bna->tx_mod.txf_bmap[0] &= ~((u32) + 1 << (tx->txf.txf_id - 32)); +} + +static void +__bna_txf_stat_clr(struct bna_tx *tx) +{ + struct bfi_ll_stats_req ll_req; + u32 txf_bmap[2] = {0, 0}; + if (tx->txf.txf_id < 32) + txf_bmap[0] = ((u32)1 << tx->txf.txf_id); + else + txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32)); + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); + ll_req.stats_mask = 0; + ll_req.rxf_id_mask[0] = 0; + ll_req.rxf_id_mask[1] = 0; + ll_req.txf_id_mask[0] = htonl(txf_bmap[0]); + ll_req.txf_id_mask[1] = htonl(txf_bmap[1]); + + bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req), + bna_tx_cb_stats_cleared, tx); + bna_mbox_send(tx->bna, &tx->mbox_qe); +} + +static void +__bna_tx_start(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_start(txq->ib); + __bna_txq_start(tx, txq); + } + + __bna_txf_start(tx); + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->tcb->priority = txq->priority; + (tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb); + } +} + +static void +__bna_tx_stop(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb); + } + + __bna_txf_stop(tx); + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bfa_wc_up(&tx->txq_stop_wc); + } + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + __bna_txq_stop(tx, txq); + } +} + +static void +bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + txq->qpt.kv_qpt_ptr = qpt_mem->kva; + txq->qpt.page_count = page_count; + txq->qpt.page_size = page_size; + + txq->tcb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < page_count; i++) { + txq->tcb->sw_qpt[i] = page_mem[i].kva; + + ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +static void +bna_tx_free(struct bna_tx *tx) +{ + struct bna_tx_mod *tx_mod = &tx->bna->tx_mod; + struct bna_txq *txq; + struct bna_ib_mod *ib_mod = &tx->bna->ib_mod; + struct list_head *qe; + + while (!list_empty(&tx->txq_q)) { + bfa_q_deq(&tx->txq_q, &txq); + bfa_q_qe_init(&txq->qe); + if (txq->ib) { + if (txq->ib_seg_offset != -1) + bna_ib_release_idx(txq->ib, + txq->ib_seg_offset); + bna_ib_put(ib_mod, txq->ib); + txq->ib = NULL; + } + txq->tcb = NULL; + txq->tx = NULL; + list_add_tail(&txq->qe, &tx_mod->txq_free_q); + } + + list_for_each(qe, &tx_mod->tx_active_q) { + if (qe == &tx->qe) { + list_del(&tx->qe); + bfa_q_qe_init(&tx->qe); + break; + } + } + + tx->bna = NULL; + tx->priv = NULL; + list_add_tail(&tx->qe, &tx_mod->tx_free_q); +} + +static void +bna_tx_cb_txq_stopped(void *arg, int status) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_q_qe_init(&tx->mbox_qe.qe); + bfa_wc_down(&tx->txq_stop_wc); +} + +static void +bna_tx_cb_txq_stopped_all(void *arg) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED); +} + +static void +bna_tx_cb_stats_cleared(void *arg, int status) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_q_qe_init(&tx->mbox_qe.qe); + + bfa_fsm_send_event(tx, TX_E_STAT_CLEARED); +} + +static void +bna_tx_start(struct bna_tx *tx) +{ + tx->flags |= BNA_TX_F_PORT_STARTED; + if (tx->flags & BNA_TX_F_ENABLED) + bfa_fsm_send_event(tx, TX_E_START); +} + +static void +bna_tx_stop(struct bna_tx *tx) +{ + tx->stop_cbfn = bna_tx_mod_cb_tx_stopped; + tx->stop_cbarg = &tx->bna->tx_mod; + + tx->flags &= ~BNA_TX_F_PORT_STARTED; + bfa_fsm_send_event(tx, TX_E_STOP); +} + +static void +bna_tx_fail(struct bna_tx *tx) +{ + tx->flags &= ~BNA_TX_F_PORT_STARTED; + bfa_fsm_send_event(tx, TX_E_FAIL); +} + +void +bna_tx_prio_changed(struct bna_tx *tx, int prio) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->priority = prio; + } + + bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE); +} + +static void +bna_tx_cee_link_status(struct bna_tx *tx, int cee_link) +{ + if (cee_link) + tx->flags |= BNA_TX_F_PRIO_LOCK; + else + tx->flags &= ~BNA_TX_F_PRIO_LOCK; +} + +static void +bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx, + enum bna_cb_status status) +{ + struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg; + + bfa_wc_down(&tx_mod->tx_stop_wc); +} + +static void +bna_tx_mod_cb_tx_stopped_all(void *arg) +{ + struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg; + + if (tx_mod->stop_cbfn) + tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS); + tx_mod->stop_cbfn = NULL; +} + +void +bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info) +{ + u32 q_size; + u32 page_count; + struct bna_mem_info *mem_info; + + res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_tcb); + mem_info->num = num_txq; + + q_size = txq_depth * BFI_TXQ_WI_SIZE; + q_size = ALIGN(q_size, PAGE_SIZE); + page_count = q_size >> PAGE_SHIFT; + + res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = page_count * sizeof(struct bna_dma_addr); + mem_info->num = num_txq; + + res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = page_count * sizeof(void *); + mem_info->num = num_txq; + + res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = num_txq * page_count; + + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR; + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type = + BNA_INTR_T_MSIX; + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq; +} + +struct bna_tx * +bna_tx_create(struct bna *bna, struct bnad *bnad, + struct bna_tx_config *tx_cfg, + struct bna_tx_event_cbfn *tx_cbfn, + struct bna_res_info *res_info, void *priv) +{ + struct bna_intr_info *intr_info; + struct bna_tx_mod *tx_mod = &bna->tx_mod; + struct bna_tx *tx; + struct bna_txq *txq; + struct list_head *qe; + struct bna_ib_mod *ib_mod = &bna->ib_mod; + struct bna_doorbell_qset *qset; + struct bna_ib_config ib_config; + int page_count; + int page_size; + int page_idx; + int i; + unsigned long off; + + intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info; + page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) / + tx_cfg->num_txq; + page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len; + + /** + * Get resources + */ + + if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq)) + return NULL; + + /* Tx */ + + if (list_empty(&tx_mod->tx_free_q)) + return NULL; + bfa_q_deq(&tx_mod->tx_free_q, &tx); + bfa_q_qe_init(&tx->qe); + + /* TxQs */ + + INIT_LIST_HEAD(&tx->txq_q); + for (i = 0; i < tx_cfg->num_txq; i++) { + if (list_empty(&tx_mod->txq_free_q)) + goto err_return; + + bfa_q_deq(&tx_mod->txq_free_q, &txq); + bfa_q_qe_init(&txq->qe); + list_add_tail(&txq->qe, &tx->txq_q); + txq->ib = NULL; + txq->ib_seg_offset = -1; + txq->tx = tx; + } + + /* IBs */ + i = 0; + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + + if (intr_info->num == 1) + txq->ib = bna_ib_get(ib_mod, intr_info->intr_type, + intr_info->idl[0].vector); + else + txq->ib = bna_ib_get(ib_mod, intr_info->intr_type, + intr_info->idl[i].vector); + + if (txq->ib == NULL) + goto err_return; + + txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib); + if (txq->ib_seg_offset == -1) + goto err_return; + + i++; + } + + /* + * Initialize + */ + + /* Tx */ + + tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn; + tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn; + /* Following callbacks are mandatory */ + tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn; + tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn; + tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn; + + list_add_tail(&tx->qe, &tx_mod->tx_active_q); + tx->bna = bna; + tx->priv = priv; + tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all; + tx->txq_stop_wc.wc_cbarg = tx; + tx->txq_stop_wc.wc_count = 0; + + tx->type = tx_cfg->tx_type; + + tx->flags = 0; + if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) { + switch (tx->type) { + case BNA_TX_T_REGULAR: + if (!(tx->bna->tx_mod.flags & + BNA_TX_MOD_F_PORT_LOOPBACK)) + tx->flags |= BNA_TX_F_PORT_STARTED; + break; + case BNA_TX_T_LOOPBACK: + if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK) + tx->flags |= BNA_TX_F_PORT_STARTED; + break; + } + } + if (tx->bna->tx_mod.cee_link) + tx->flags |= BNA_TX_F_PRIO_LOCK; + + /* TxQ */ + + i = 0; + page_idx = 0; + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->priority = tx_mod->priority; + txq->tcb = (struct bna_tcb *) + res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva; + txq->tx_packets = 0; + txq->tx_bytes = 0; + + /* IB */ + + ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO; + ib_config.interpkt_timeo = 0; /* Not used */ + ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT; + ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA | + BFI_IB_CF_INT_ENABLE | + BFI_IB_CF_COALESCING_MODE); + bna_ib_config(txq->ib, &ib_config); + + /* TCB */ + + txq->tcb->producer_index = 0; + txq->tcb->consumer_index = 0; + txq->tcb->hw_consumer_index = (volatile u32 *) + ((volatile u8 *)txq->ib->ib_seg_host_addr_kva + + (txq->ib_seg_offset * BFI_IBIDX_SIZE)); + *(txq->tcb->hw_consumer_index) = 0; + txq->tcb->q_depth = tx_cfg->txq_depth; + txq->tcb->unmap_q = (void *) + res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva; + qset = (struct bna_doorbell_qset *)0; + off = (unsigned long)&qset[txq->txq_id].txq[0]; + txq->tcb->q_dbell = off + + BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva); + txq->tcb->i_dbell = &txq->ib->door_bell; + txq->tcb->intr_type = intr_info->intr_type; + txq->tcb->intr_vector = (intr_info->num == 1) ? + intr_info->idl[0].vector : + intr_info->idl[i].vector; + txq->tcb->txq = txq; + txq->tcb->bnad = bnad; + txq->tcb->id = i; + + /* QPT, SWQPT, Pages */ + bna_txq_qpt_setup(txq, page_count, page_size, + &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i], + &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i], + &res_info[BNA_TX_RES_MEM_T_PAGE]. + res_u.mem_info.mdl[page_idx]); + txq->tcb->page_idx = page_idx; + txq->tcb->page_count = page_count; + page_idx += page_count; + + /* Callback to bnad for setting up TCB */ + if (tx->tcb_setup_cbfn) + (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb); + + i++; + } + + /* TxF */ + + tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED; + tx->txf.vlan = 0; + + /* Mbox element */ + bfa_q_qe_init(&tx->mbox_qe.qe); + + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + + return tx; + +err_return: + bna_tx_free(tx); + return NULL; +} + +void +bna_tx_destroy(struct bna_tx *tx) +{ + /* Callback to bnad for destroying TCB */ + if (tx->tcb_destroy_cbfn) { + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb); + } + } + + bna_tx_free(tx); +} + +void +bna_tx_enable(struct bna_tx *tx) +{ + if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped) + return; + + tx->flags |= BNA_TX_F_ENABLED; + + if (tx->flags & BNA_TX_F_PORT_STARTED) + bfa_fsm_send_event(tx, TX_E_START); +} + +void +bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + (*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS); + return; + } + + tx->stop_cbfn = cbfn; + tx->stop_cbarg = tx->bna->bnad; + + tx->flags &= ~BNA_TX_F_ENABLED; + + bfa_fsm_send_event(tx, TX_E_STOP); +} + +int +bna_tx_state_get(struct bna_tx *tx) +{ + return bfa_sm_to_state(tx_sm_table, tx->fsm); +} + +void +bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + tx_mod->bna = bna; + tx_mod->flags = 0; + + tx_mod->tx = (struct bna_tx *) + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva; + tx_mod->txq = (struct bna_txq *) + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&tx_mod->tx_free_q); + INIT_LIST_HEAD(&tx_mod->tx_active_q); + + INIT_LIST_HEAD(&tx_mod->txq_free_q); + + for (i = 0; i < BFI_MAX_TXQ; i++) { + tx_mod->tx[i].txf.txf_id = i; + bfa_q_qe_init(&tx_mod->tx[i].qe); + list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q); + + tx_mod->txq[i].txq_id = i; + bfa_q_qe_init(&tx_mod->txq[i].qe); + list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q); + } + + tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all; + tx_mod->tx_stop_wc.wc_cbarg = tx_mod; + tx_mod->tx_stop_wc.wc_count = 0; +} + +void +bna_tx_mod_uninit(struct bna_tx_mod *tx_mod) +{ + struct list_head *qe; + int i; + + i = 0; + list_for_each(qe, &tx_mod->tx_free_q) + i++; + + i = 0; + list_for_each(qe, &tx_mod->txq_free_q) + i++; + + tx_mod->bna = NULL; +} + +void +bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED; + if (type == BNA_TX_T_LOOPBACK) + tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bna_tx_start(tx); + } +} + +void +bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED; + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK; + + tx_mod->stop_cbfn = bna_port_cb_tx_stopped; + + /** + * Before calling bna_tx_stop(), increment tx_stop_wc as many times + * as we are going to call bna_tx_stop + */ + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bfa_wc_up(&tx_mod->tx_stop_wc); + } + + if (tx_mod->tx_stop_wc.wc_count == 0) { + tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS); + tx_mod->stop_cbfn = NULL; + return; + } + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bna_tx_stop(tx); + } +} + +void +bna_tx_mod_fail(struct bna_tx_mod *tx_mod) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED; + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_fail(tx); + } +} + +void +bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio) +{ + struct bna_tx *tx; + struct list_head *qe; + + if (prio != tx_mod->priority) { + tx_mod->priority = prio; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_prio_changed(tx, prio); + } + } +} + +void +bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->cee_link = cee_link; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_cee_link_status(tx, cee_link); + } +} diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h new file mode 100644 index 000000000000..6877310f6ef4 --- /dev/null +++ b/drivers/net/bna/bna_types.h @@ -0,0 +1,1128 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BNA_TYPES_H__ +#define __BNA_TYPES_H__ + +#include "cna.h" +#include "bna_hw.h" +#include "bfa_cee.h" + +/** + * + * Forward declarations + * + */ + +struct bna_txq; +struct bna_tx; +struct bna_rxq; +struct bna_cq; +struct bna_rx; +struct bna_rxf; +struct bna_port; +struct bna; +struct bnad; + +/** + * + * Enums, primitive data types + * + */ + +enum bna_status { + BNA_STATUS_T_DISABLED = 0, + BNA_STATUS_T_ENABLED = 1 +}; + +enum bna_cleanup_type { + BNA_HARD_CLEANUP = 0, + BNA_SOFT_CLEANUP = 1 +}; + +enum bna_cb_status { + BNA_CB_SUCCESS = 0, + BNA_CB_FAIL = 1, + BNA_CB_INTERRUPT = 2, + BNA_CB_BUSY = 3, + BNA_CB_INVALID_MAC = 4, + BNA_CB_MCAST_LIST_FULL = 5, + BNA_CB_UCAST_CAM_FULL = 6, + BNA_CB_WAITING = 7, + BNA_CB_NOT_EXEC = 8 +}; + +enum bna_res_type { + BNA_RES_T_MEM = 1, + BNA_RES_T_INTR = 2 +}; + +enum bna_mem_type { + BNA_MEM_T_KVA = 1, + BNA_MEM_T_DMA = 2 +}; + +enum bna_intr_type { + BNA_INTR_T_INTX = 1, + BNA_INTR_T_MSIX = 2 +}; + +enum bna_res_req_type { + BNA_RES_MEM_T_COM = 0, + BNA_RES_MEM_T_ATTR = 1, + BNA_RES_MEM_T_FWTRC = 2, + BNA_RES_MEM_T_STATS = 3, + BNA_RES_MEM_T_SWSTATS = 4, + BNA_RES_MEM_T_IBIDX = 5, + BNA_RES_MEM_T_IB_ARRAY = 6, + BNA_RES_MEM_T_INTR_ARRAY = 7, + BNA_RES_MEM_T_IDXSEG_ARRAY = 8, + BNA_RES_MEM_T_TX_ARRAY = 9, + BNA_RES_MEM_T_TXQ_ARRAY = 10, + BNA_RES_MEM_T_RX_ARRAY = 11, + BNA_RES_MEM_T_RXP_ARRAY = 12, + BNA_RES_MEM_T_RXQ_ARRAY = 13, + BNA_RES_MEM_T_UCMAC_ARRAY = 14, + BNA_RES_MEM_T_MCMAC_ARRAY = 15, + BNA_RES_MEM_T_RIT_ENTRY = 16, + BNA_RES_MEM_T_RIT_SEGMENT = 17, + BNA_RES_INTR_T_MBOX = 18, + BNA_RES_T_MAX +}; + +enum bna_tx_res_req_type { + BNA_TX_RES_MEM_T_TCB = 0, + BNA_TX_RES_MEM_T_UNMAPQ = 1, + BNA_TX_RES_MEM_T_QPT = 2, + BNA_TX_RES_MEM_T_SWQPT = 3, + BNA_TX_RES_MEM_T_PAGE = 4, + BNA_TX_RES_INTR_T_TXCMPL = 5, + BNA_TX_RES_T_MAX, +}; + +enum bna_rx_mem_type { + BNA_RX_RES_MEM_T_CCB = 0, /* CQ context */ + BNA_RX_RES_MEM_T_RCB = 1, /* CQ context */ + BNA_RX_RES_MEM_T_UNMAPQ = 2, /* UnmapQ for RxQs */ + BNA_RX_RES_MEM_T_CQPT = 3, /* CQ QPT */ + BNA_RX_RES_MEM_T_CSWQPT = 4, /* S/W QPT */ + BNA_RX_RES_MEM_T_CQPT_PAGE = 5, /* CQPT page */ + BNA_RX_RES_MEM_T_HQPT = 6, /* RX QPT */ + BNA_RX_RES_MEM_T_DQPT = 7, /* RX QPT */ + BNA_RX_RES_MEM_T_HSWQPT = 8, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_DSWQPT = 9, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_DPAGE = 10, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_HPAGE = 11, /* RX s/w QPT */ + BNA_RX_RES_T_INTR = 12, /* Rx interrupts */ + BNA_RX_RES_T_MAX = 13 +}; + +enum bna_mbox_state { + BNA_MBOX_FREE = 0, + BNA_MBOX_POSTED = 1 +}; + +enum bna_tx_type { + BNA_TX_T_REGULAR = 0, + BNA_TX_T_LOOPBACK = 1, +}; + +enum bna_tx_flags { + BNA_TX_F_PORT_STARTED = 1, + BNA_TX_F_ENABLED = 2, + BNA_TX_F_PRIO_LOCK = 4, +}; + +enum bna_tx_mod_flags { + BNA_TX_MOD_F_PORT_STARTED = 1, + BNA_TX_MOD_F_PORT_LOOPBACK = 2, +}; + +enum bna_rx_type { + BNA_RX_T_REGULAR = 0, + BNA_RX_T_LOOPBACK = 1, +}; + +enum bna_rxp_type { + BNA_RXP_SINGLE = 1, + BNA_RXP_SLR = 2, + BNA_RXP_HDS = 3 +}; + +enum bna_rxmode { + BNA_RXMODE_PROMISC = 1, + BNA_RXMODE_DEFAULT = 2, + BNA_RXMODE_ALLMULTI = 4 +}; + +enum bna_rx_event { + RX_E_START = 1, + RX_E_STOP = 2, + RX_E_FAIL = 3, + RX_E_RXF_STARTED = 4, + RX_E_RXF_STOPPED = 5, + RX_E_RXQ_STOPPED = 6, +}; + +enum bna_rx_state { + BNA_RX_STOPPED = 1, + BNA_RX_RXF_START_WAIT = 2, + BNA_RX_STARTED = 3, + BNA_RX_RXF_STOP_WAIT = 4, + BNA_RX_RXQ_STOP_WAIT = 5, +}; + +enum bna_rx_flags { + BNA_RX_F_ENABLE = 0x01, /* bnad enabled rxf */ + BNA_RX_F_PORT_ENABLED = 0x02, /* Port object is enabled */ + BNA_RX_F_PORT_FAILED = 0x04, /* Port in failed state */ +}; + +enum bna_rx_mod_flags { + BNA_RX_MOD_F_PORT_STARTED = 1, + BNA_RX_MOD_F_PORT_LOOPBACK = 2, +}; + +enum bna_rxf_oper_state { + BNA_RXF_OPER_STATE_RUNNING = 0x01, /* rxf operational */ + BNA_RXF_OPER_STATE_PAUSED = 0x02, /* rxf in PAUSED state */ +}; + +enum bna_rxf_flags { + BNA_RXF_FL_STOP_PENDING = 0x01, + BNA_RXF_FL_FAILED = 0x02, + BNA_RXF_FL_RSS_CONFIG_PENDING = 0x04, + BNA_RXF_FL_OPERSTATE_CHANGED = 0x08, + BNA_RXF_FL_RXF_ENABLED = 0x10, + BNA_RXF_FL_VLAN_CONFIG_PENDING = 0x20, +}; + +enum bna_rxf_event { + RXF_E_START = 1, + RXF_E_STOP = 2, + RXF_E_FAIL = 3, + RXF_E_CAM_FLTR_MOD = 4, + RXF_E_STARTED = 5, + RXF_E_STOPPED = 6, + RXF_E_CAM_FLTR_RESP = 7, + RXF_E_PAUSE = 8, + RXF_E_RESUME = 9, + RXF_E_STAT_CLEARED = 10, +}; + +enum bna_rxf_state { + BNA_RXF_STOPPED = 1, + BNA_RXF_START_WAIT = 2, + BNA_RXF_CAM_FLTR_MOD_WAIT = 3, + BNA_RXF_STARTED = 4, + BNA_RXF_CAM_FLTR_CLR_WAIT = 5, + BNA_RXF_STOP_WAIT = 6, + BNA_RXF_PAUSE_WAIT = 7, + BNA_RXF_RESUME_WAIT = 8, + BNA_RXF_STAT_CLR_WAIT = 9, +}; + +enum bna_port_type { + BNA_PORT_T_REGULAR = 0, + BNA_PORT_T_LOOPBACK_INTERNAL = 1, + BNA_PORT_T_LOOPBACK_EXTERNAL = 2, +}; + +enum bna_link_status { + BNA_LINK_DOWN = 0, + BNA_LINK_UP = 1, + BNA_CEE_UP = 2 +}; + +enum bna_llport_flags { + BNA_LLPORT_F_ENABLED = 1, + BNA_LLPORT_F_RX_ENABLED = 2 +}; + +enum bna_port_flags { + BNA_PORT_F_DEVICE_READY = 1, + BNA_PORT_F_ENABLED = 2, + BNA_PORT_F_PAUSE_CHANGED = 4, + BNA_PORT_F_MTU_CHANGED = 8 +}; + +enum bna_pkt_rates { + BNA_PKT_RATE_10K = 10000, + BNA_PKT_RATE_20K = 20000, + BNA_PKT_RATE_30K = 30000, + BNA_PKT_RATE_40K = 40000, + BNA_PKT_RATE_50K = 50000, + BNA_PKT_RATE_60K = 60000, + BNA_PKT_RATE_70K = 70000, + BNA_PKT_RATE_80K = 80000, +}; + +enum bna_dim_load_types { + BNA_LOAD_T_HIGH_4 = 0, /* 80K <= r */ + BNA_LOAD_T_HIGH_3 = 1, /* 60K <= r < 80K */ + BNA_LOAD_T_HIGH_2 = 2, /* 50K <= r < 60K */ + BNA_LOAD_T_HIGH_1 = 3, /* 40K <= r < 50K */ + BNA_LOAD_T_LOW_1 = 4, /* 30K <= r < 40K */ + BNA_LOAD_T_LOW_2 = 5, /* 20K <= r < 30K */ + BNA_LOAD_T_LOW_3 = 6, /* 10K <= r < 20K */ + BNA_LOAD_T_LOW_4 = 7, /* r < 10K */ + BNA_LOAD_T_MAX = 8 +}; + +enum bna_dim_bias_types { + BNA_BIAS_T_SMALL = 0, /* small pkts > (large pkts * 2) */ + BNA_BIAS_T_LARGE = 1, /* Not BNA_BIAS_T_SMALL */ + BNA_BIAS_T_MAX = 2 +}; + +struct bna_mac { + /* This should be the first one */ + struct list_head qe; + u8 addr[ETH_ALEN]; +}; + +struct bna_mem_descr { + u32 len; + void *kva; + struct bna_dma_addr dma; +}; + +struct bna_mem_info { + enum bna_mem_type mem_type; + u32 len; + u32 num; + u32 align_sz; /* 0/1 = no alignment */ + struct bna_mem_descr *mdl; + void *cookie; /* For bnad to unmap dma later */ +}; + +struct bna_intr_descr { + int vector; +}; + +struct bna_intr_info { + enum bna_intr_type intr_type; + int num; + struct bna_intr_descr *idl; +}; + +union bna_res_u { + struct bna_mem_info mem_info; + struct bna_intr_info intr_info; +}; + +struct bna_res_info { + enum bna_res_type res_type; + union bna_res_u res_u; +}; + +/* HW QPT */ +struct bna_qpt { + struct bna_dma_addr hw_qpt_ptr; + void *kv_qpt_ptr; + u32 page_count; + u32 page_size; +}; + +/** + * + * Device + * + */ + +struct bna_device { + bfa_fsm_t fsm; + struct bfa_ioc ioc; + + enum bna_intr_type intr_type; + int vector; + + void (*ready_cbfn)(struct bnad *bnad, enum bna_cb_status status); + struct bnad *ready_cbarg; + + void (*stop_cbfn)(struct bnad *bnad, enum bna_cb_status status); + struct bnad *stop_cbarg; + + struct bna *bna; +}; + +/** + * + * Mail box + * + */ + +struct bna_mbox_qe { + /* This should be the first one */ + struct list_head qe; + + struct bfa_mbox_cmd cmd; + u32 cmd_len; + /* Callback for port, tx, rx, rxf */ + void (*cbfn)(void *arg, int status); + void *cbarg; +}; + +struct bna_mbox_mod { + enum bna_mbox_state state; + struct list_head posted_q; + u32 msg_pending; + u32 msg_ctr; + struct bna *bna; +}; + +/** + * + * Port + * + */ + +/* Pause configuration */ +struct bna_pause_config { + enum bna_status tx_pause; + enum bna_status rx_pause; +}; + +struct bna_llport { + bfa_fsm_t fsm; + enum bna_llport_flags flags; + + enum bna_port_type type; + + enum bna_link_status link_status; + + int admin_up_count; + + void (*stop_cbfn)(struct bna_port *, enum bna_cb_status); + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; +}; + +struct bna_port { + bfa_fsm_t fsm; + enum bna_port_flags flags; + + enum bna_port_type type; + + struct bna_llport llport; + + struct bna_pause_config pause_config; + u8 priority; + int mtu; + + /* Callback for bna_port_disable(), port_stop() */ + void (*stop_cbfn)(void *, enum bna_cb_status); + void *stop_cbarg; + + /* Callback for bna_port_pause_config() */ + void (*pause_cbfn)(struct bnad *, enum bna_cb_status); + + /* Callback for bna_port_mtu_set() */ + void (*mtu_cbfn)(struct bnad *, enum bna_cb_status); + + void (*link_cbfn)(struct bnad *, enum bna_link_status); + + struct bfa_wc chld_stop_wc; + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; +}; + +/** + * + * Interrupt Block + * + */ + +/* IB index segment structure */ +struct bna_ibidx_seg { + /* This should be the first one */ + struct list_head qe; + + u8 ib_seg_size; + u8 ib_idx_tbl_offset; +}; + +/* Interrupt structure */ +struct bna_intr { + /* This should be the first one */ + struct list_head qe; + int ref_count; + + enum bna_intr_type intr_type; + int vector; + + struct bna_ib *ib; +}; + +/* Doorbell structure */ +struct bna_ib_dbell { + void *__iomem doorbell_addr; + u32 doorbell_ack; +}; + +/* Interrupt timer configuration */ +struct bna_ib_config { + u8 coalescing_timeo; /* Unit is 5usec. */ + + int interpkt_count; + int interpkt_timeo; + + enum ib_flags ctrl_flags; +}; + +/* IB structure */ +struct bna_ib { + /* This should be the first one */ + struct list_head qe; + + int ib_id; + + int ref_count; + int start_count; + + struct bna_dma_addr ib_seg_host_addr; + void *ib_seg_host_addr_kva; + u32 idx_mask; /* Size >= BNA_IBIDX_MAX_SEGSIZE */ + + struct bna_ibidx_seg *idx_seg; + + struct bna_ib_dbell door_bell; + + struct bna_intr *intr; + + struct bna_ib_config ib_config; + + struct bna *bna; +}; + +/* IB module - keeps track of IBs and interrupts */ +struct bna_ib_mod { + struct bna_ib *ib; /* BFI_MAX_IB entries */ + struct bna_intr *intr; /* BFI_MAX_IB entries */ + struct bna_ibidx_seg *idx_seg; /* BNA_IBIDX_TOTAL_SEGS */ + + struct list_head ib_free_q; + + struct list_head ibidx_seg_pool[BFI_IBIDX_TOTAL_POOLS]; + + struct list_head intr_free_q; + struct list_head intr_active_q; + + struct bna *bna; +}; + +/** + * + * Tx object + * + */ + +/* Tx datapath control structure */ +#define BNA_Q_NAME_SIZE 16 +struct bna_tcb { + /* Fast path */ + void **sw_qpt; + void *unmap_q; + u32 producer_index; + u32 consumer_index; + volatile u32 *hw_consumer_index; + u32 q_depth; + void *__iomem q_dbell; + struct bna_ib_dbell *i_dbell; + int page_idx; + int page_count; + /* Control path */ + struct bna_txq *txq; + struct bnad *bnad; + enum bna_intr_type intr_type; + int intr_vector; + u8 priority; /* Current priority */ + unsigned long flags; /* Used by bnad as required */ + int id; + char name[BNA_Q_NAME_SIZE]; +}; + +/* TxQ QPT and configuration */ +struct bna_txq { + /* This should be the first one */ + struct list_head qe; + + int txq_id; + + u8 priority; + + struct bna_qpt qpt; + struct bna_tcb *tcb; + struct bna_ib *ib; + int ib_seg_offset; + + struct bna_tx *tx; + + u64 tx_packets; + u64 tx_bytes; +}; + +/* TxF structure (hardware Tx Function) */ +struct bna_txf { + int txf_id; + enum txf_flags ctrl_flags; + u16 vlan; +}; + +/* Tx object */ +struct bna_tx { + /* This should be the first one */ + struct list_head qe; + + bfa_fsm_t fsm; + enum bna_tx_flags flags; + + enum bna_tx_type type; + + struct list_head txq_q; + struct bna_txf txf; + + /* Tx event handlers */ + void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *); + void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *); + + /* callback for bna_tx_disable(), bna_tx_stop() */ + void (*stop_cbfn)(void *arg, struct bna_tx *tx, + enum bna_cb_status status); + void *stop_cbarg; + + /* callback for bna_tx_prio_set() */ + void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx, + enum bna_cb_status status); + + struct bfa_wc txq_stop_wc; + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; + void *priv; /* bnad's cookie */ +}; + +struct bna_tx_config { + int num_txq; + int txq_depth; + enum bna_tx_type tx_type; +}; + +struct bna_tx_event_cbfn { + /* Optional */ + void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *); + void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *); + /* Mandatory */ + void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *); +}; + +/* Tx module - keeps track of free, active tx objects */ +struct bna_tx_mod { + struct bna_tx *tx; /* BFI_MAX_TXQ entries */ + struct bna_txq *txq; /* BFI_MAX_TXQ entries */ + + struct list_head tx_free_q; + struct list_head tx_active_q; + + struct list_head txq_free_q; + + /* callback for bna_tx_mod_stop() */ + void (*stop_cbfn)(struct bna_port *port, + enum bna_cb_status status); + + struct bfa_wc tx_stop_wc; + + enum bna_tx_mod_flags flags; + + int priority; + int cee_link; + + u32 txf_bmap[2]; + + struct bna *bna; +}; + +/** + * + * Receive Indirection Table + * + */ + +/* One row of RIT table */ +struct bna_rit_entry { + u8 large_rxq_id; /* used for either large or data buffers */ + u8 small_rxq_id; /* used for either small or header buffers */ +}; + +/* RIT segment */ +struct bna_rit_segment { + struct list_head qe; + + u32 rit_offset; + u32 rit_size; + /** + * max_rit_size: Varies per RIT segment depending on how RIT is + * partitioned + */ + u32 max_rit_size; + + struct bna_rit_entry *rit; +}; + +struct bna_rit_mod { + struct bna_rit_entry *rit; + struct bna_rit_segment *rit_segment; + + struct list_head rit_seg_pool[BFI_RIT_SEG_TOTAL_POOLS]; +}; + +/** + * + * Rx object + * + */ + +/* Rx datapath control structure */ +struct bna_rcb { + /* Fast path */ + void **sw_qpt; + void *unmap_q; + u32 producer_index; + u32 consumer_index; + u32 q_depth; + void *__iomem q_dbell; + int page_idx; + int page_count; + /* Control path */ + struct bna_rxq *rxq; + struct bna_cq *cq; + struct bnad *bnad; + unsigned long flags; + int id; +}; + +/* RxQ structure - QPT, configuration */ +struct bna_rxq { + struct list_head qe; + int rxq_id; + + int buffer_size; + int q_depth; + + struct bna_qpt qpt; + struct bna_rcb *rcb; + + struct bna_rxp *rxp; + struct bna_rx *rx; + + u64 rx_packets; + u64 rx_bytes; + u64 rx_packets_with_error; + u64 rxbuf_alloc_failed; +}; + +/* RxQ pair */ +union bna_rxq_u { + struct { + struct bna_rxq *hdr; + struct bna_rxq *data; + } hds; + struct { + struct bna_rxq *small; + struct bna_rxq *large; + } slr; + struct { + struct bna_rxq *only; + struct bna_rxq *reserved; + } single; +}; + +/* Packet rate for Dynamic Interrupt Moderation */ +struct bna_pkt_rate { + u32 small_pkt_cnt; + u32 large_pkt_cnt; +}; + +/* Completion control structure */ +struct bna_ccb { + /* Fast path */ + void **sw_qpt; + u32 producer_index; + volatile u32 *hw_producer_index; + u32 q_depth; + struct bna_ib_dbell *i_dbell; + struct bna_rcb *rcb[2]; + void *ctrl; /* For bnad */ + struct bna_pkt_rate pkt_rate; + int page_idx; + int page_count; + + /* Control path */ + struct bna_cq *cq; + struct bnad *bnad; + enum bna_intr_type intr_type; + int intr_vector; + u8 rx_coalescing_timeo; /* For NAPI */ + int id; + char name[BNA_Q_NAME_SIZE]; +}; + +/* CQ QPT, configuration */ +struct bna_cq { + int cq_id; + + struct bna_qpt qpt; + struct bna_ccb *ccb; + + struct bna_ib *ib; + u8 ib_seg_offset; + + struct bna_rx *rx; +}; + +struct bna_rss_config { + enum rss_hash_type hash_type; + u8 hash_mask; + u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN]; +}; + +struct bna_hds_config { + enum hds_header_type hdr_type; + int header_size; +}; + +/* This structure is used during RX creation */ +struct bna_rx_config { + enum bna_rx_type rx_type; + int num_paths; + enum bna_rxp_type rxp_type; + int paused; + int q_depth; + /* + * Small/Large (or Header/Data) buffer size to be configured + * for SLR and HDS queue type. Large buffer size comes from + * port->mtu. + */ + int small_buff_size; + + enum bna_status rss_status; + struct bna_rss_config rss_config; + + enum bna_status hds_status; + struct bna_hds_config hds_config; + + enum bna_status vlan_strip_status; +}; + +/* Rx Path structure - one per MSIX vector/CPU */ +struct bna_rxp { + /* This should be the first one */ + struct list_head qe; + + enum bna_rxp_type type; + union bna_rxq_u rxq; + struct bna_cq cq; + + struct bna_rx *rx; + + /* MSI-x vector number for configuring RSS */ + int vector; + + struct bna_mbox_qe mbox_qe; +}; + +/* HDS configuration structure */ +struct bna_rxf_hds { + enum hds_header_type hdr_type; + int header_size; +}; + +/* RSS configuration structure */ +struct bna_rxf_rss { + enum rss_hash_type hash_type; + u8 hash_mask; + u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN]; +}; + +/* RxF structure (hardware Rx Function) */ +struct bna_rxf { + bfa_fsm_t fsm; + int rxf_id; + enum rxf_flags ctrl_flags; + u16 default_vlan_tag; + enum bna_rxf_oper_state rxf_oper_state; + enum bna_status hds_status; + struct bna_rxf_hds hds_cfg; + enum bna_status rss_status; + struct bna_rxf_rss rss_cfg; + struct bna_rit_segment *rit_segment; + struct bna_rx *rx; + u32 forced_offset; + struct bna_mbox_qe mbox_qe; + int mcast_rxq_id; + + /* callback for bna_rxf_start() */ + void (*start_cbfn) (struct bna_rx *rx, enum bna_cb_status status); + struct bna_rx *start_cbarg; + + /* callback for bna_rxf_stop() */ + void (*stop_cbfn) (struct bna_rx *rx, enum bna_cb_status status); + struct bna_rx *stop_cbarg; + + /* callback for bna_rxf_receive_enable() / bna_rxf_receive_disable() */ + void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status); + struct bnad *oper_state_cbarg; + + /** + * callback for: + * bna_rxf_ucast_set() + * bna_rxf_{ucast/mcast}_add(), + * bna_rxf_{ucast/mcast}_del(), + * bna_rxf_mode_set() + */ + void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status); + struct bnad *cam_fltr_cbarg; + + enum bna_rxf_flags rxf_flags; + + /* List of unicast addresses yet to be applied to h/w */ + struct list_head ucast_pending_add_q; + struct list_head ucast_pending_del_q; + int ucast_pending_set; + /* ucast addresses applied to the h/w */ + struct list_head ucast_active_q; + struct bna_mac *ucast_active_mac; + + /* List of multicast addresses yet to be applied to h/w */ + struct list_head mcast_pending_add_q; + struct list_head mcast_pending_del_q; + /* multicast addresses applied to the h/w */ + struct list_head mcast_active_q; + + /* Rx modes yet to be applied to h/w */ + enum bna_rxmode rxmode_pending; + enum bna_rxmode rxmode_pending_bitmask; + /* Rx modes applied to h/w */ + enum bna_rxmode rxmode_active; + + enum bna_status vlan_filter_status; + u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32]; +}; + +/* Rx object */ +struct bna_rx { + /* This should be the first one */ + struct list_head qe; + + bfa_fsm_t fsm; + + enum bna_rx_type type; + + /* list-head for RX path objects */ + struct list_head rxp_q; + + struct bna_rxf rxf; + + enum bna_rx_flags rx_flags; + + struct bna_mbox_qe mbox_qe; + + struct bfa_wc rxq_stop_wc; + + /* Rx event handlers */ + void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *); + void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); + void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); + void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *); + + /* callback for bna_rx_disable(), bna_rx_stop() */ + void (*stop_cbfn)(void *arg, struct bna_rx *rx, + enum bna_cb_status status); + void *stop_cbarg; + + struct bna *bna; + void *priv; /* bnad's cookie */ +}; + +struct bna_rx_event_cbfn { + /* Optional */ + void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *); + void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); + void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); + void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); + /* Mandatory */ + void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *); +}; + +/* Rx module - keeps track of free, active rx objects */ +struct bna_rx_mod { + struct bna *bna; /* back pointer to parent */ + struct bna_rx *rx; /* BFI_MAX_RXQ entries */ + struct bna_rxp *rxp; /* BFI_MAX_RXQ entries */ + struct bna_rxq *rxq; /* BFI_MAX_RXQ entries */ + + struct list_head rx_free_q; + struct list_head rx_active_q; + int rx_free_count; + + struct list_head rxp_free_q; + int rxp_free_count; + + struct list_head rxq_free_q; + int rxq_free_count; + + enum bna_rx_mod_flags flags; + + /* callback for bna_rx_mod_stop() */ + void (*stop_cbfn)(struct bna_port *port, + enum bna_cb_status status); + + struct bfa_wc rx_stop_wc; + u32 dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX]; + u32 rxf_bmap[2]; +}; + +/** + * + * CAM + * + */ + +struct bna_ucam_mod { + struct bna_mac *ucmac; /* BFI_MAX_UCMAC entries */ + struct list_head free_q; + + struct bna *bna; +}; + +struct bna_mcam_mod { + struct bna_mac *mcmac; /* BFI_MAX_MCMAC entries */ + struct list_head free_q; + + struct bna *bna; +}; + +/** + * + * Statistics + * + */ + +struct bna_tx_stats { + int tx_state; + int tx_flags; + int num_txqs; + u32 txq_bmap[2]; + int txf_id; +}; + +struct bna_rx_stats { + int rx_state; + int rx_flags; + int num_rxps; + int num_rxqs; + u32 rxq_bmap[2]; + u32 cq_bmap[2]; + int rxf_id; + int rxf_state; + int rxf_oper_state; + int num_active_ucast; + int num_active_mcast; + int rxmode_active; + int vlan_filter_status; + u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32]; + int rss_status; + int hds_status; +}; + +struct bna_sw_stats { + int device_state; + int port_state; + int port_flags; + int llport_state; + int priority; + int num_active_tx; + int num_active_rx; + struct bna_tx_stats tx_stats[BFI_MAX_TXQ]; + struct bna_rx_stats rx_stats[BFI_MAX_RXQ]; +}; + +struct bna_stats { + u32 txf_bmap[2]; + u32 rxf_bmap[2]; + struct bfi_ll_stats *hw_stats; + struct bna_sw_stats *sw_stats; +}; + +/** + * + * BNA + * + */ + +struct bna { + struct bfa_pcidev pcidev; + + int port_num; + + struct bna_chip_regs regs; + + struct bna_dma_addr hw_stats_dma; + struct bna_stats stats; + + struct bna_device device; + struct bfa_cee cee; + + struct bna_mbox_mod mbox_mod; + + struct bna_port port; + + struct bna_tx_mod tx_mod; + + struct bna_rx_mod rx_mod; + + struct bna_ib_mod ib_mod; + + struct bna_ucam_mod ucam_mod; + struct bna_mcam_mod mcam_mod; + + struct bna_rit_mod rit_mod; + + int rxf_default_id; + int rxf_promisc_id; + + struct bna_mbox_qe mbox_qe; + + struct bnad *bnad; +}; + +#endif /* __BNA_TYPES_H__ */ diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c new file mode 100644 index 000000000000..491d148f88ae --- /dev/null +++ b/drivers/net/bna/bnad.c @@ -0,0 +1,3270 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bnad.h" +#include "bna.h" +#include "cna.h" + +DEFINE_MUTEX(bnad_fwimg_mutex); + +/* + * Module params + */ +static uint bnad_msix_disable; +module_param(bnad_msix_disable, uint, 0444); +MODULE_PARM_DESC(bnad_msix_disable, "Disable MSIX mode"); + +static uint bnad_ioc_auto_recover = 1; +module_param(bnad_ioc_auto_recover, uint, 0444); +MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery"); + +/* + * Global variables + */ +u32 bnad_rxqs_per_cq = 2; + +const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +/* + * Local MACROS + */ +#define BNAD_TX_UNMAPQ_DEPTH (bnad->txq_depth * 2) + +#define BNAD_RX_UNMAPQ_DEPTH (bnad->rxq_depth) + +#define BNAD_GET_MBOX_IRQ(_bnad) \ + (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \ + ((_bnad)->msix_table[(_bnad)->msix_num - 1].vector) : \ + ((_bnad)->pcidev->irq)) + +#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth) \ +do { \ + (_res_info)->res_type = BNA_RES_T_MEM; \ + (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \ + (_res_info)->res_u.mem_info.num = (_num); \ + (_res_info)->res_u.mem_info.len = \ + sizeof(struct bnad_unmap_q) + \ + (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \ +} while (0) + +/* + * Reinitialize completions in CQ, once Rx is taken down + */ +static void +bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bna_cq_entry *cmpl, *next_cmpl; + unsigned int wi_range, wis = 0, ccb_prod = 0; + int i; + + BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, cmpl, + wi_range); + + for (i = 0; i < ccb->q_depth; i++) { + wis++; + if (likely(--wi_range)) + next_cmpl = cmpl + 1; + else { + BNA_QE_INDX_ADD(ccb_prod, wis, ccb->q_depth); + wis = 0; + BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, + next_cmpl, wi_range); + } + cmpl->valid = 0; + cmpl = next_cmpl; + } +} + +/* + * Frees all pending Tx Bufs + * At this point no activity is expected on the Q, + * so DMA unmap & freeing is fine. + */ +static void +bnad_free_all_txbufs(struct bnad *bnad, + struct bna_tcb *tcb) +{ + u16 unmap_cons; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct sk_buff *skb = NULL; + int i; + + unmap_array = unmap_q->unmap_array; + + unmap_cons = 0; + while (unmap_cons < unmap_q->q_depth) { + skb = unmap_array[unmap_cons].skb; + if (!skb) { + unmap_cons++; + continue; + } + unmap_array[unmap_cons].skb = NULL; + + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), skb_headlen(skb), + PCI_DMA_TODEVICE); + + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + unmap_cons++; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pci_unmap_page(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + 0); + unmap_cons++; + } + dev_kfree_skb_any(skb); + } +} + +/* Data Path Handlers */ + +/* + * bnad_free_txbufs : Frees the Tx bufs on Tx completion + * Can be called in a) Interrupt context + * b) Sending context + * c) Tasklet context + */ +static u32 +bnad_free_txbufs(struct bnad *bnad, + struct bna_tcb *tcb) +{ + u32 sent_packets = 0, sent_bytes = 0; + u16 wis, unmap_cons, updated_hw_cons; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct sk_buff *skb; + int i; + + /* + * Just return if TX is stopped. This check is useful + * when bnad_free_txbufs() runs out of a tasklet scheduled + * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit + * but this routine runs actually after the cleanup has been + * executed. + */ + if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) + return 0; + + updated_hw_cons = *(tcb->hw_consumer_index); + + wis = BNA_Q_INDEX_CHANGE(tcb->consumer_index, + updated_hw_cons, tcb->q_depth); + + BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth))); + + unmap_array = unmap_q->unmap_array; + unmap_cons = unmap_q->consumer_index; + + prefetch(&unmap_array[unmap_cons + 1]); + while (wis) { + skb = unmap_array[unmap_cons].skb; + + unmap_array[unmap_cons].skb = NULL; + + sent_packets++; + sent_bytes += skb->len; + wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags); + + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), skb_headlen(skb), + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); + + prefetch(&unmap_array[unmap_cons + 1]); + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + prefetch(&unmap_array[unmap_cons + 1]); + + pci_unmap_page(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + 0); + BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); + } + dev_kfree_skb_any(skb); + } + + /* Update consumer pointers. */ + tcb->consumer_index = updated_hw_cons; + unmap_q->consumer_index = unmap_cons; + + tcb->txq->tx_packets += sent_packets; + tcb->txq->tx_bytes += sent_bytes; + + return sent_packets; +} + +/* Tx Free Tasklet function */ +/* Frees for all the tcb's in all the Tx's */ +/* + * Scheduled from sending context, so that + * the fat Tx lock is not held for too long + * in the sending context. + */ +static void +bnad_tx_free_tasklet(unsigned long bnad_ptr) +{ + struct bnad *bnad = (struct bnad *)bnad_ptr; + struct bna_tcb *tcb; + u32 acked; + int i, j; + + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + tcb = bnad->tx_info[i].tcb[j]; + if (!tcb) + continue; + if (((u16) (*tcb->hw_consumer_index) != + tcb->consumer_index) && + (!test_and_set_bit(BNAD_TXQ_FREE_SENT, + &tcb->flags))) { + acked = bnad_free_txbufs(bnad, tcb); + bna_ib_ack(tcb->i_dbell, acked); + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + } + } + } +} + +static u32 +bnad_tx(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct net_device *netdev = bnad->netdev; + u32 sent; + + if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + return 0; + + sent = bnad_free_txbufs(bnad, tcb); + if (sent) { + if (netif_queue_stopped(netdev) && + netif_carrier_ok(netdev) && + BNA_QE_FREE_CNT(tcb, tcb->q_depth) >= + BNAD_NETIF_WAKE_THRESHOLD) { + netif_wake_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } + bna_ib_ack(tcb->i_dbell, sent); + } else + bna_ib_ack(tcb->i_dbell, 0); + + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + + return sent; +} + +/* MSIX Tx Completion Handler */ +static irqreturn_t +bnad_msix_tx(int irq, void *data) +{ + struct bna_tcb *tcb = (struct bna_tcb *)data; + struct bnad *bnad = tcb->bnad; + + bnad_tx(bnad, tcb); + + return IRQ_HANDLED; +} + +static void +bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + rcb->producer_index = 0; + rcb->consumer_index = 0; + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; +} + +static void +bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q; + struct sk_buff *skb; + + unmap_q = rcb->unmap_q; + while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) { + skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; + BUG_ON(!(skb)); + unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; + pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q-> + unmap_array[unmap_q->consumer_index], + dma_addr), rcb->rxq->buffer_size + + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + dev_kfree_skb(skb); + BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); + BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); + } + + bnad_reset_rcb(bnad, rcb); +} + +static void +bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) +{ + u16 to_alloc, alloced, unmap_prod, wi_range; + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct bna_rxq_entry *rxent; + struct sk_buff *skb; + dma_addr_t dma_addr; + + alloced = 0; + to_alloc = + BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth); + + unmap_array = unmap_q->unmap_array; + unmap_prod = unmap_q->producer_index; + + BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range); + + while (to_alloc--) { + if (!wi_range) { + BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, + wi_range); + } + skb = alloc_skb(rcb->rxq->buffer_size + NET_IP_ALIGN, + GFP_ATOMIC); + if (unlikely(!skb)) { + BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed); + goto finishing; + } + skb->dev = bnad->netdev; + skb_reserve(skb, NET_IP_ALIGN); + unmap_array[unmap_prod].skb = skb; + dma_addr = pci_map_single(bnad->pcidev, skb->data, + rcb->rxq->buffer_size, PCI_DMA_FROMDEVICE); + pci_unmap_addr_set(&unmap_array[unmap_prod], dma_addr, + dma_addr); + BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + + rxent++; + wi_range--; + alloced++; + } + +finishing: + if (likely(alloced)) { + unmap_q->producer_index = unmap_prod; + rcb->producer_index = unmap_prod; + smp_mb(); + bna_rxq_prod_indx_doorbell(rcb); + } +} + +/* + * Locking is required in the enable path + * because it is called from a napi poll + * context, where the bna_lock is not held + * unlike the IRQ context. + */ +static void +bnad_enable_txrx_irqs(struct bnad *bnad) +{ + struct bna_tcb *tcb; + struct bna_ccb *ccb; + int i, j; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + tcb = bnad->tx_info[i].tcb[j]; + bna_ib_coalescing_timer_set(tcb->i_dbell, + tcb->txq->ib->ib_config.coalescing_timeo); + bna_ib_ack(tcb->i_dbell, 0); + } + } + + for (i = 0; i < bnad->num_rx; i++) { + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + ccb = bnad->rx_info[i].rx_ctrl[j].ccb; + bnad_enable_rx_irq_unsafe(ccb); + } + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static inline void +bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) { + if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth) + >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT) + bnad_alloc_n_post_rxbufs(bnad, rcb); + smp_mb__before_clear_bit(); + clear_bit(BNAD_RXQ_REFILL, &rcb->flags); + } +} + +static u32 +bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) +{ + struct bna_cq_entry *cmpl, *next_cmpl; + struct bna_rcb *rcb = NULL; + unsigned int wi_range, packets = 0, wis = 0; + struct bnad_unmap_q *unmap_q; + struct sk_buff *skb; + u32 flags; + u32 qid0 = ccb->rcb[0]->rxq->rxq_id; + struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate; + + prefetch(bnad->netdev); + BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl, + wi_range); + BUG_ON(!(wi_range <= ccb->q_depth)); + while (cmpl->valid && packets < budget) { + packets++; + BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length)); + + if (qid0 == cmpl->rxq_id) + rcb = ccb->rcb[0]; + else + rcb = ccb->rcb[1]; + + unmap_q = rcb->unmap_q; + + skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; + BUG_ON(!(skb)); + unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_q-> + unmap_array[unmap_q-> + consumer_index], + dma_addr), + rcb->rxq->buffer_size, + PCI_DMA_FROMDEVICE); + BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); + + /* Should be more efficient ? Performance ? */ + BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); + + wis++; + if (likely(--wi_range)) + next_cmpl = cmpl + 1; + else { + BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); + wis = 0; + BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, + next_cmpl, wi_range); + BUG_ON(!(wi_range <= ccb->q_depth)); + } + prefetch(next_cmpl); + + flags = ntohl(cmpl->flags); + if (unlikely + (flags & + (BNA_CQ_EF_MAC_ERROR | BNA_CQ_EF_FCS_ERROR | + BNA_CQ_EF_TOO_LONG))) { + dev_kfree_skb_any(skb); + rcb->rxq->rx_packets_with_error++; + goto next; + } + + skb_put(skb, ntohs(cmpl->length)); + if (likely + (bnad->rx_csum && + (((flags & BNA_CQ_EF_IPV4) && + (flags & BNA_CQ_EF_L3_CKSUM_OK)) || + (flags & BNA_CQ_EF_IPV6)) && + (flags & (BNA_CQ_EF_TCP | BNA_CQ_EF_UDP)) && + (flags & BNA_CQ_EF_L4_CKSUM_OK))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + + rcb->rxq->rx_packets++; + rcb->rxq->rx_bytes += skb->len; + skb->protocol = eth_type_trans(skb, bnad->netdev); + + if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) { + struct bnad_rx_ctrl *rx_ctrl = + (struct bnad_rx_ctrl *)ccb->ctrl; + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp, + ntohs(cmpl->vlan_tag), skb); + else + vlan_hwaccel_receive_skb(skb, + bnad->vlan_grp, + ntohs(cmpl->vlan_tag)); + + } else { /* Not VLAN tagged/stripped */ + struct bnad_rx_ctrl *rx_ctrl = + (struct bnad_rx_ctrl *)ccb->ctrl; + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ctrl->napi, skb); + else + netif_receive_skb(skb); + } + +next: + cmpl->valid = 0; + cmpl = next_cmpl; + } + + BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); + + if (likely(ccb)) { + bna_ib_ack(ccb->i_dbell, packets); + bnad_refill_rxq(bnad, ccb->rcb[0]); + if (ccb->rcb[1]) + bnad_refill_rxq(bnad, ccb->rcb[1]); + } else + bna_ib_ack(ccb->i_dbell, 0); + + return packets; +} + +static void +bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) +{ + bna_ib_coalescing_timer_set(ccb->i_dbell, 0); + bna_ib_ack(ccb->i_dbell, 0); +} + +static void +bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) +{ + spin_lock_irq(&bnad->bna_lock); /* Because of polling context */ + bnad_enable_rx_irq_unsafe(ccb); + spin_unlock_irq(&bnad->bna_lock); +} + +static void +bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl); + if (likely(napi_schedule_prep((&rx_ctrl->napi)))) { + bnad_disable_rx_irq(bnad, ccb); + __napi_schedule((&rx_ctrl->napi)); + } + BNAD_UPDATE_CTR(bnad, netif_rx_schedule); +} + +/* MSIX Rx Path Handler */ +static irqreturn_t +bnad_msix_rx(int irq, void *data) +{ + struct bna_ccb *ccb = (struct bna_ccb *)data; + struct bnad *bnad = ccb->bnad; + + bnad_netif_rx_schedule_poll(bnad, ccb); + + return IRQ_HANDLED; +} + +/* Interrupt handlers */ + +/* Mbox Interrupt Handlers */ +static irqreturn_t +bnad_msix_mbox_handler(int irq, void *data) +{ + u32 intr_status; + unsigned long flags; + struct net_device *netdev = data; + struct bnad *bnad; + + bnad = netdev_priv(netdev); + + /* BNA_ISR_GET(bnad); Inc Ref count */ + spin_lock_irqsave(&bnad->bna_lock, flags); + + bna_intr_status_get(&bnad->bna, intr_status); + + if (BNA_IS_MBOX_ERR_INTR(intr_status)) + bna_mbox_handler(&bnad->bna, intr_status); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* BNAD_ISR_PUT(bnad); Dec Ref count */ + return IRQ_HANDLED; +} + +static irqreturn_t +bnad_isr(int irq, void *data) +{ + int i, j; + u32 intr_status; + unsigned long flags; + struct net_device *netdev = data; + struct bnad *bnad = netdev_priv(netdev); + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + bna_intr_status_get(&bnad->bna, intr_status); + if (!intr_status) { + spin_unlock_irqrestore(&bnad->bna_lock, flags); + return IRQ_NONE; + } + + if (BNA_IS_MBOX_ERR_INTR(intr_status)) { + bna_mbox_handler(&bnad->bna, intr_status); + if (!BNA_IS_INTX_DATA_INTR(intr_status)) { + spin_unlock_irqrestore(&bnad->bna_lock, flags); + goto done; + } + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Process data interrupts */ + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (rx_ctrl->ccb) + bnad_netif_rx_schedule_poll(bnad, + rx_ctrl->ccb); + } + } +done: + return IRQ_HANDLED; +} + +/* + * Called in interrupt / callback context + * with bna_lock held, so cfg_flags access is OK + */ +static void +bnad_enable_mbox_irq(struct bnad *bnad) +{ + int irq = BNAD_GET_MBOX_IRQ(bnad); + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) + return; + + if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) + enable_irq(irq); + BNAD_UPDATE_CTR(bnad, mbox_intr_enabled); +} + +/* + * Called with bnad->bna_lock held b'cos of + * bnad->cfg_flags access. + */ +void +bnad_disable_mbox_irq(struct bnad *bnad) +{ + int irq = BNAD_GET_MBOX_IRQ(bnad); + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) + return; + + if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) + disable_irq_nosync(irq); + BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); +} + +/* Control Path Handlers */ + +/* Callbacks */ +void +bnad_cb_device_enable_mbox_intr(struct bnad *bnad) +{ + bnad_enable_mbox_irq(bnad); +} + +void +bnad_cb_device_disable_mbox_intr(struct bnad *bnad) +{ + bnad_disable_mbox_irq(bnad); +} + +void +bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status) +{ + complete(&bnad->bnad_completions.ioc_comp); + bnad->bnad_completions.ioc_comp_status = status; +} + +void +bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status) +{ + complete(&bnad->bnad_completions.ioc_comp); + bnad->bnad_completions.ioc_comp_status = status; +} + +static void +bnad_cb_port_disabled(void *arg, enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.port_comp); + + netif_carrier_off(bnad->netdev); +} + +void +bnad_cb_port_link_status(struct bnad *bnad, + enum bna_link_status link_status) +{ + bool link_up = 0; + + link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP); + + if (link_status == BNA_CEE_UP) { + set_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags); + BNAD_UPDATE_CTR(bnad, cee_up); + } else + clear_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags); + + if (link_up) { + if (!netif_carrier_ok(bnad->netdev)) { + pr_warn("bna: %s link up\n", + bnad->netdev->name); + netif_carrier_on(bnad->netdev); + BNAD_UPDATE_CTR(bnad, link_toggle); + if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) { + /* Force an immediate Transmit Schedule */ + pr_info("bna: %s TX_STARTED\n", + bnad->netdev->name); + netif_wake_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } else { + netif_stop_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + } + } + } else { + if (netif_carrier_ok(bnad->netdev)) { + pr_warn("bna: %s link down\n", + bnad->netdev->name); + netif_carrier_off(bnad->netdev); + BNAD_UPDATE_CTR(bnad, link_toggle); + } + } +} + +static void +bnad_cb_tx_disabled(void *arg, struct bna_tx *tx, + enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.tx_comp); +} + +static void +bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + + tx_info->tcb[tcb->id] = tcb; + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH; +} + +static void +bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + + tx_info->tcb[tcb->id] = NULL; +} + +static void +bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH; +} + +static void +bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_info *rx_info = + (struct bnad_rx_info *)ccb->cq->rx->priv; + + rx_info->rx_ctrl[ccb->id].ccb = ccb; + ccb->ctrl = &rx_info->rx_ctrl[ccb->id]; +} + +static void +bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_info *rx_info = + (struct bnad_rx_info *)ccb->cq->rx->priv; + + rx_info->rx_ctrl[ccb->id].ccb = NULL; +} + +static void +bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + + if (tx_info != &bnad->tx_info[0]) + return; + + clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags); + netif_stop_queue(bnad->netdev); + pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name); +} + +static void +bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb) +{ + if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) + return; + + if (netif_carrier_ok(bnad->netdev)) { + pr_info("bna: %s TX_STARTED\n", bnad->netdev->name); + netif_wake_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } +} + +static void +bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + + if (!tcb || (!tcb->unmap_q)) + return; + + if (!unmap_q->unmap_array) + return; + + if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + return; + + bnad_free_all_txbufs(bnad, tcb); + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); +} + +static void +bnad_cb_rx_cleanup(struct bnad *bnad, + struct bna_ccb *ccb) +{ + bnad_cq_cmpl_init(bnad, ccb); + + bnad_free_rxbufs(bnad, ccb->rcb[0]); + clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags); + + if (ccb->rcb[1]) { + bnad_free_rxbufs(bnad, ccb->rcb[1]); + clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags); + } +} + +static void +bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + set_bit(BNAD_RXQ_STARTED, &rcb->flags); + + /* Now allocate & post buffers for this RCB */ + /* !!Allocation in callback context */ + if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) { + if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth) + >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT) + bnad_alloc_n_post_rxbufs(bnad, rcb); + smp_mb__before_clear_bit(); + clear_bit(BNAD_RXQ_REFILL, &rcb->flags); + } +} + +static void +bnad_cb_rx_disabled(void *arg, struct bna_rx *rx, + enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.rx_comp); +} + +static void +bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status) +{ + bnad->bnad_completions.mcast_comp_status = status; + complete(&bnad->bnad_completions.mcast_comp); +} + +void +bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, + struct bna_stats *stats) +{ + if (status == BNA_CB_SUCCESS) + BNAD_UPDATE_CTR(bnad, hw_stats_updates); + + if (!netif_running(bnad->netdev) || + !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + return; + + mod_timer(&bnad->stats_timer, + jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); +} + +void +bnad_cb_stats_clr(struct bnad *bnad) +{ +} + +/* Resource allocation, free functions */ + +static void +bnad_mem_free(struct bnad *bnad, + struct bna_mem_info *mem_info) +{ + int i; + dma_addr_t dma_pa; + + if (mem_info->mdl == NULL) + return; + + for (i = 0; i < mem_info->num; i++) { + if (mem_info->mdl[i].kva != NULL) { + if (mem_info->mem_type == BNA_MEM_T_DMA) { + BNA_GET_DMA_ADDR(&(mem_info->mdl[i].dma), + dma_pa); + pci_free_consistent(bnad->pcidev, + mem_info->mdl[i].len, + mem_info->mdl[i].kva, dma_pa); + } else + kfree(mem_info->mdl[i].kva); + } + } + kfree(mem_info->mdl); + mem_info->mdl = NULL; +} + +static int +bnad_mem_alloc(struct bnad *bnad, + struct bna_mem_info *mem_info) +{ + int i; + dma_addr_t dma_pa; + + if ((mem_info->num == 0) || (mem_info->len == 0)) { + mem_info->mdl = NULL; + return 0; + } + + mem_info->mdl = kcalloc(mem_info->num, sizeof(struct bna_mem_descr), + GFP_KERNEL); + if (mem_info->mdl == NULL) + return -ENOMEM; + + if (mem_info->mem_type == BNA_MEM_T_DMA) { + for (i = 0; i < mem_info->num; i++) { + mem_info->mdl[i].len = mem_info->len; + mem_info->mdl[i].kva = + pci_alloc_consistent(bnad->pcidev, + mem_info->len, &dma_pa); + + if (mem_info->mdl[i].kva == NULL) + goto err_return; + + BNA_SET_DMA_ADDR(dma_pa, + &(mem_info->mdl[i].dma)); + } + } else { + for (i = 0; i < mem_info->num; i++) { + mem_info->mdl[i].len = mem_info->len; + mem_info->mdl[i].kva = kzalloc(mem_info->len, + GFP_KERNEL); + if (mem_info->mdl[i].kva == NULL) + goto err_return; + } + } + + return 0; + +err_return: + bnad_mem_free(bnad, mem_info); + return -ENOMEM; +} + +/* Free IRQ for Mailbox */ +static void +bnad_mbox_irq_free(struct bnad *bnad, + struct bna_intr_info *intr_info) +{ + int irq; + unsigned long flags; + + if (intr_info->idl == NULL) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + bnad_disable_mbox_irq(bnad); + + irq = BNAD_GET_MBOX_IRQ(bnad); + free_irq(irq, bnad->netdev); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + kfree(intr_info->idl); +} + +/* + * Allocates IRQ for Mailbox, but keep it disabled + * This will be enabled once we get the mbox enable callback + * from bna + */ +static int +bnad_mbox_irq_alloc(struct bnad *bnad, + struct bna_intr_info *intr_info) +{ + int err; + unsigned long flags; + u32 irq; + irq_handler_t irq_handler; + + /* Mbox should use only 1 vector */ + + intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) { + irq_handler = (irq_handler_t)bnad_msix_mbox_handler; + irq = bnad->msix_table[bnad->msix_num - 1].vector; + flags = 0; + intr_info->intr_type = BNA_INTR_T_MSIX; + intr_info->idl[0].vector = bnad->msix_num - 1; + } else { + irq_handler = (irq_handler_t)bnad_isr; + irq = bnad->pcidev->irq; + flags = IRQF_SHARED; + intr_info->intr_type = BNA_INTR_T_INTX; + /* intr_info->idl.vector = 0 ? */ + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); + + err = request_irq(irq, irq_handler, flags, + bnad->mbox_irq_name, bnad->netdev); + if (err) { + kfree(intr_info->idl); + intr_info->idl = NULL; + return err; + } + + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad_disable_mbox_irq(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + return 0; +} + +static void +bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info) +{ + kfree(intr_info->idl); + intr_info->idl = NULL; +} + +/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */ +static int +bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src, + uint txrx_id, struct bna_intr_info *intr_info) +{ + int i, vector_start = 0; + u32 cfg_flags; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + cfg_flags = bnad->cfg_flags; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (cfg_flags & BNAD_CF_MSIX) { + intr_info->intr_type = BNA_INTR_T_MSIX; + intr_info->idl = kcalloc(intr_info->num, + sizeof(struct bna_intr_descr), + GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + switch (src) { + case BNAD_INTR_TX: + vector_start = txrx_id; + break; + + case BNAD_INTR_RX: + vector_start = bnad->num_tx * bnad->num_txq_per_tx + + txrx_id; + break; + + default: + BUG(); + } + + for (i = 0; i < intr_info->num; i++) + intr_info->idl[i].vector = vector_start + i; + } else { + intr_info->intr_type = BNA_INTR_T_INTX; + intr_info->num = 1; + intr_info->idl = kcalloc(intr_info->num, + sizeof(struct bna_intr_descr), + GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + switch (src) { + case BNAD_INTR_TX: + intr_info->idl[0].vector = 0x1; /* Bit mask : Tx IB */ + break; + + case BNAD_INTR_RX: + intr_info->idl[0].vector = 0x2; /* Bit mask : Rx IB */ + break; + } + } + return 0; +} + +/** + * NOTE: Should be called for MSIX only + * Unregisters Tx MSIX vector(s) from the kernel + */ +static void +bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info, + int num_txqs) +{ + int i; + int vector_num; + + for (i = 0; i < num_txqs; i++) { + if (tx_info->tcb[i] == NULL) + continue; + + vector_num = tx_info->tcb[i]->intr_vector; + free_irq(bnad->msix_table[vector_num].vector, tx_info->tcb[i]); + } +} + +/** + * NOTE: Should be called for MSIX only + * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel + */ +static int +bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info, + uint tx_id, int num_txqs) +{ + int i; + int err; + int vector_num; + + for (i = 0; i < num_txqs; i++) { + vector_num = tx_info->tcb[i]->intr_vector; + sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name, + tx_id + tx_info->tcb[i]->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_tx, 0, + tx_info->tcb[i]->name, + tx_info->tcb[i]); + if (err) + goto err_return; + } + + return 0; + +err_return: + if (i > 0) + bnad_tx_msix_unregister(bnad, tx_info, (i - 1)); + return -1; +} + +/** + * NOTE: Should be called for MSIX only + * Unregisters Rx MSIX vector(s) from the kernel + */ +static void +bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info, + int num_rxps) +{ + int i; + int vector_num; + + for (i = 0; i < num_rxps; i++) { + if (rx_info->rx_ctrl[i].ccb == NULL) + continue; + + vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; + free_irq(bnad->msix_table[vector_num].vector, + rx_info->rx_ctrl[i].ccb); + } +} + +/** + * NOTE: Should be called for MSIX only + * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel + */ +static int +bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info, + uint rx_id, int num_rxps) +{ + int i; + int err; + int vector_num; + + for (i = 0; i < num_rxps; i++) { + vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; + sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d", + bnad->netdev->name, + rx_id + rx_info->rx_ctrl[i].ccb->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_rx, 0, + rx_info->rx_ctrl[i].ccb->name, + rx_info->rx_ctrl[i].ccb); + if (err) + goto err_return; + } + + return 0; + +err_return: + if (i > 0) + bnad_rx_msix_unregister(bnad, rx_info, (i - 1)); + return -1; +} + +/* Free Tx object Resources */ +static void +bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info) +{ + int i; + + for (i = 0; i < BNA_TX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for Tx object */ +static int +bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info, + uint tx_id) +{ + int i, err = 0; + + for (i = 0; i < BNA_TX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, + &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_TX, tx_id, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_tx_res_free(bnad, res_info); + return err; +} + +/* Free Rx object Resources */ +static void +bnad_rx_res_free(struct bnad *bnad, struct bna_res_info *res_info) +{ + int i; + + for (i = 0; i < BNA_RX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for Rx object */ +static int +bnad_rx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info, + uint rx_id) +{ + int i, err = 0; + + /* All memory needs to be allocated before setup_ccbs */ + for (i = 0; i < BNA_RX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, + &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_RX, rx_id, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_rx_res_free(bnad, res_info); + return err; +} + +/* Timer callbacks */ +/* a) IOC timer */ +static void +bnad_ioc_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_ioc_timeout((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_ioc_hb_check(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_ioc_hb_check((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_ioc_sem_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_ioc_sem_timeout((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * All timer routines use bnad->bna_lock to protect against + * the following race, which may occur in case of no locking: + * Time CPU m CPU n + * 0 1 = test_bit + * 1 clear_bit + * 2 del_timer_sync + * 3 mod_timer + */ + +/* b) Dynamic Interrupt Moderation Timer */ +static void +bnad_dim_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + int i, j; + unsigned long flags; + + if (!netif_carrier_ok(bnad->netdev)) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (!rx_ctrl->ccb) + continue; + bna_rx_dim_update(rx_ctrl->ccb); + } + } + + /* Check for BNAD_CF_DIM_ENABLED, does not eleminate a race */ + if (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) + mod_timer(&bnad->dim_timer, + jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ)); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* c) Statistics Timer */ +static void +bnad_stats_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + if (!netif_running(bnad->netdev) || + !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_stats_get(&bnad->bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * Set up timer for DIM + * Called with bnad->bna_lock held + */ +void +bnad_dim_timer_start(struct bnad *bnad) +{ + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED && + !test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) { + setup_timer(&bnad->dim_timer, bnad_dim_timeout, + (unsigned long)bnad); + set_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags); + mod_timer(&bnad->dim_timer, + jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ)); + } +} + +/* + * Set up timer for statistics + * Called with mutex_lock(&bnad->conf_mutex) held + */ +static void +bnad_stats_timer_start(struct bnad *bnad) +{ + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!test_and_set_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) { + setup_timer(&bnad->stats_timer, bnad_stats_timeout, + (unsigned long)bnad); + mod_timer(&bnad->stats_timer, + jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + +} + +/* + * Stops the stats timer + * Called with mutex_lock(&bnad->conf_mutex) held + */ +static void +bnad_stats_timer_stop(struct bnad *bnad) +{ + int to_del = 0; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (test_and_clear_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + to_del = 1; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (to_del) + del_timer_sync(&bnad->stats_timer); +} + +/* Utilities */ + +static void +bnad_netdev_mc_list_get(struct net_device *netdev, u8 *mc_list) +{ + int i = 1; /* Index 0 has broadcast address */ + struct netdev_hw_addr *mc_addr; + + netdev_for_each_mc_addr(mc_addr, netdev) { + memcpy(&mc_list[i * ETH_ALEN], &mc_addr->addr[0], + ETH_ALEN); + i++; + } +} + +static int +bnad_napi_poll_rx(struct napi_struct *napi, int budget) +{ + struct bnad_rx_ctrl *rx_ctrl = + container_of(napi, struct bnad_rx_ctrl, napi); + struct bna_ccb *ccb; + struct bnad *bnad; + int rcvd = 0; + + ccb = rx_ctrl->ccb; + + bnad = ccb->bnad; + + if (!netif_carrier_ok(bnad->netdev)) + goto poll_exit; + + rcvd = bnad_poll_cq(bnad, ccb, budget); + if (rcvd == budget) + return rcvd; + +poll_exit: + napi_complete((napi)); + + BNAD_UPDATE_CTR(bnad, netif_rx_complete); + + bnad_enable_rx_irq(bnad, ccb); + return rcvd; +} + +static int +bnad_napi_poll_txrx(struct napi_struct *napi, int budget) +{ + struct bnad_rx_ctrl *rx_ctrl = + container_of(napi, struct bnad_rx_ctrl, napi); + struct bna_ccb *ccb; + struct bnad *bnad; + int rcvd = 0; + int i, j; + + ccb = rx_ctrl->ccb; + + bnad = ccb->bnad; + + if (!netif_carrier_ok(bnad->netdev)) + goto poll_exit; + + /* Handle Tx Completions, if any */ + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) + bnad_tx(bnad, bnad->tx_info[i].tcb[j]); + } + + /* Handle Rx Completions */ + rcvd = bnad_poll_cq(bnad, ccb, budget); + if (rcvd == budget) + return rcvd; +poll_exit: + napi_complete((napi)); + + BNAD_UPDATE_CTR(bnad, netif_rx_complete); + + bnad_enable_txrx_irqs(bnad); + return rcvd; +} + +static void +bnad_napi_enable(struct bnad *bnad, u32 rx_id) +{ + int (*napi_poll) (struct napi_struct *, int); + struct bnad_rx_ctrl *rx_ctrl; + int i; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) + napi_poll = bnad_napi_poll_rx; + else + napi_poll = bnad_napi_poll_txrx; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Initialize & enable NAPI */ + for (i = 0; i < bnad->num_rxp_per_rx; i++) { + rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i]; + netif_napi_add(bnad->netdev, &rx_ctrl->napi, + napi_poll, 64); + napi_enable(&rx_ctrl->napi); + } +} + +static void +bnad_napi_disable(struct bnad *bnad, u32 rx_id) +{ + int i; + + /* First disable and then clean up */ + for (i = 0; i < bnad->num_rxp_per_rx; i++) { + napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi); + netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi); + } +} + +/* Should be held with conf_lock held */ +void +bnad_cleanup_tx(struct bnad *bnad, uint tx_id) +{ + struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id]; + struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0]; + unsigned long flags; + + if (!tx_info->tx) + return; + + init_completion(&bnad->bnad_completions.tx_comp); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_disable(tx_info->tx, BNA_HARD_CLEANUP, bnad_cb_tx_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + wait_for_completion(&bnad->bnad_completions.tx_comp); + + if (tx_info->tcb[0]->intr_type == BNA_INTR_T_MSIX) + bnad_tx_msix_unregister(bnad, tx_info, + bnad->num_txq_per_tx); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_destroy(tx_info->tx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + tx_info->tx = NULL; + + if (0 == tx_id) + tasklet_kill(&bnad->tx_free_tasklet); + + bnad_tx_res_free(bnad, res_info); +} + +/* Should be held with conf_lock held */ +int +bnad_setup_tx(struct bnad *bnad, uint tx_id) +{ + int err; + struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id]; + struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0]; + struct bna_intr_info *intr_info = + &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info; + struct bna_tx_config *tx_config = &bnad->tx_config[tx_id]; + struct bna_tx_event_cbfn tx_cbfn; + struct bna_tx *tx; + unsigned long flags; + + /* Initialize the Tx object configuration */ + tx_config->num_txq = bnad->num_txq_per_tx; + tx_config->txq_depth = bnad->txq_depth; + tx_config->tx_type = BNA_TX_T_REGULAR; + + /* Initialize the tx event handlers */ + tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup; + tx_cbfn.tcb_destroy_cbfn = bnad_cb_tcb_destroy; + tx_cbfn.tx_stall_cbfn = bnad_cb_tx_stall; + tx_cbfn.tx_resume_cbfn = bnad_cb_tx_resume; + tx_cbfn.tx_cleanup_cbfn = bnad_cb_tx_cleanup; + + /* Get BNA's resource requirement for one tx object */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_res_req(bnad->num_txq_per_tx, + bnad->txq_depth, res_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Fill Unmap Q memory requirements */ + BNAD_FILL_UNMAPQ_MEM_REQ( + &res_info[BNA_TX_RES_MEM_T_UNMAPQ], + bnad->num_txq_per_tx, + BNAD_TX_UNMAPQ_DEPTH); + + /* Allocate resources */ + err = bnad_tx_res_alloc(bnad, res_info, tx_id); + if (err) + return err; + + /* Ask BNA to create one Tx object, supplying required resources */ + spin_lock_irqsave(&bnad->bna_lock, flags); + tx = bna_tx_create(&bnad->bna, bnad, tx_config, &tx_cbfn, res_info, + tx_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (!tx) + goto err_return; + tx_info->tx = tx; + + /* Register ISR for the Tx object */ + if (intr_info->intr_type == BNA_INTR_T_MSIX) { + err = bnad_tx_msix_register(bnad, tx_info, + tx_id, bnad->num_txq_per_tx); + if (err) + goto err_return; + } + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_enable(tx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return 0; + +err_return: + bnad_tx_res_free(bnad, res_info); + return err; +} + +/* Setup the rx config for bna_rx_create */ +/* bnad decides the configuration */ +static void +bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config) +{ + rx_config->rx_type = BNA_RX_T_REGULAR; + rx_config->num_paths = bnad->num_rxp_per_rx; + + if (bnad->num_rxp_per_rx > 1) { + rx_config->rss_status = BNA_STATUS_T_ENABLED; + rx_config->rss_config.hash_type = + (BFI_RSS_T_V4_TCP | + BFI_RSS_T_V6_TCP | + BFI_RSS_T_V4_IP | + BFI_RSS_T_V6_IP); + rx_config->rss_config.hash_mask = + bnad->num_rxp_per_rx - 1; + get_random_bytes(rx_config->rss_config.toeplitz_hash_key, + sizeof(rx_config->rss_config.toeplitz_hash_key)); + } else { + rx_config->rss_status = BNA_STATUS_T_DISABLED; + memset(&rx_config->rss_config, 0, + sizeof(rx_config->rss_config)); + } + rx_config->rxp_type = BNA_RXP_SLR; + rx_config->q_depth = bnad->rxq_depth; + + rx_config->small_buff_size = BFI_SMALL_RXBUF_SIZE; + + rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; +} + +/* Called with mutex_lock(&bnad->conf_mutex) held */ +void +bnad_cleanup_rx(struct bnad *bnad, uint rx_id) +{ + struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id]; + struct bna_rx_config *rx_config = &bnad->rx_config[rx_id]; + struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0]; + unsigned long flags; + int dim_timer_del = 0; + + if (!rx_info->rx) + return; + + if (0 == rx_id) { + spin_lock_irqsave(&bnad->bna_lock, flags); + dim_timer_del = bnad_dim_timer_running(bnad); + if (dim_timer_del) + clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (dim_timer_del) + del_timer_sync(&bnad->dim_timer); + } + + bnad_napi_disable(bnad, rx_id); + + init_completion(&bnad->bnad_completions.rx_comp); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + wait_for_completion(&bnad->bnad_completions.rx_comp); + + if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX) + bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_destroy(rx_info->rx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + rx_info->rx = NULL; + + bnad_rx_res_free(bnad, res_info); +} + +/* Called with mutex_lock(&bnad->conf_mutex) held */ +int +bnad_setup_rx(struct bnad *bnad, uint rx_id) +{ + int err; + struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id]; + struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0]; + struct bna_intr_info *intr_info = + &res_info[BNA_RX_RES_T_INTR].res_u.intr_info; + struct bna_rx_config *rx_config = &bnad->rx_config[rx_id]; + struct bna_rx_event_cbfn rx_cbfn; + struct bna_rx *rx; + unsigned long flags; + + /* Initialize the Rx object configuration */ + bnad_init_rx_config(bnad, rx_config); + + /* Initialize the Rx event handlers */ + rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup; + rx_cbfn.rcb_destroy_cbfn = NULL; + rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup; + rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy; + rx_cbfn.rx_cleanup_cbfn = bnad_cb_rx_cleanup; + rx_cbfn.rx_post_cbfn = bnad_cb_rx_post; + + /* Get BNA's resource requirement for one Rx object */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_res_req(rx_config, res_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Fill Unmap Q memory requirements */ + BNAD_FILL_UNMAPQ_MEM_REQ( + &res_info[BNA_RX_RES_MEM_T_UNMAPQ], + rx_config->num_paths + + ((rx_config->rxp_type == BNA_RXP_SINGLE) ? 0 : + rx_config->num_paths), BNAD_RX_UNMAPQ_DEPTH); + + /* Allocate resource */ + err = bnad_rx_res_alloc(bnad, res_info, rx_id); + if (err) + return err; + + /* Ask BNA to create one Rx object, supplying required resources */ + spin_lock_irqsave(&bnad->bna_lock, flags); + rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info, + rx_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (!rx) + goto err_return; + rx_info->rx = rx; + + /* Register ISR for the Rx object */ + if (intr_info->intr_type == BNA_INTR_T_MSIX) { + err = bnad_rx_msix_register(bnad, rx_info, rx_id, + rx_config->num_paths); + if (err) + goto err_return; + } + + /* Enable NAPI */ + bnad_napi_enable(bnad, rx_id); + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (0 == rx_id) { + /* Set up Dynamic Interrupt Moderation Vector */ + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) + bna_rx_dim_reconfig(&bnad->bna, bna_napi_dim_vector); + + /* Enable VLAN filtering only on the default Rx */ + bna_rx_vlanfilter_enable(rx); + + /* Start the DIM timer */ + bnad_dim_timer_start(bnad); + } + + bna_rx_enable(rx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return 0; + +err_return: + bnad_cleanup_rx(bnad, rx_id); + return err; +} + +/* Called with conf_lock & bnad->bna_lock held */ +void +bnad_tx_coalescing_timeo_set(struct bnad *bnad) +{ + struct bnad_tx_info *tx_info; + + tx_info = &bnad->tx_info[0]; + if (!tx_info->tx) + return; + + bna_tx_coalescing_timeo_set(tx_info->tx, bnad->tx_coalescing_timeo); +} + +/* Called with conf_lock & bnad->bna_lock held */ +void +bnad_rx_coalescing_timeo_set(struct bnad *bnad) +{ + struct bnad_rx_info *rx_info; + int i; + + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + bna_rx_coalescing_timeo_set(rx_info->rx, + bnad->rx_coalescing_timeo); + } +} + +/* + * Called with bnad->bna_lock held + */ +static int +bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr) +{ + int ret; + + if (!is_valid_ether_addr(mac_addr)) + return -EADDRNOTAVAIL; + + /* If datapath is down, pretend everything went through */ + if (!bnad->rx_info[0].rx) + return 0; + + ret = bna_rx_ucast_set(bnad->rx_info[0].rx, mac_addr, NULL); + if (ret != BNA_CB_SUCCESS) + return -EADDRNOTAVAIL; + + return 0; +} + +/* Should be called with conf_lock held */ +static int +bnad_enable_default_bcast(struct bnad *bnad) +{ + struct bnad_rx_info *rx_info = &bnad->rx_info[0]; + int ret; + unsigned long flags; + + init_completion(&bnad->bnad_completions.mcast_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + ret = bna_rx_mcast_add(rx_info->rx, (u8 *)bnad_bcast_addr, + bnad_cb_rx_mcast_add); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (ret == BNA_CB_SUCCESS) + wait_for_completion(&bnad->bnad_completions.mcast_comp); + else + return -ENODEV; + + if (bnad->bnad_completions.mcast_comp_status != BNA_CB_SUCCESS) + return -ENODEV; + + return 0; +} + +/* Statistics utilities */ +void +bnad_netdev_qstats_fill(struct bnad *bnad) +{ + struct net_device_stats *net_stats = &bnad->net_stats; + int i, j; + + for (i = 0; i < bnad->num_rx; i++) { + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + if (bnad->rx_info[i].rx_ctrl[j].ccb) { + net_stats->rx_packets += bnad->rx_info[i]. + rx_ctrl[j].ccb->rcb[0]->rxq->rx_packets; + net_stats->rx_bytes += bnad->rx_info[i]. + rx_ctrl[j].ccb->rcb[0]->rxq->rx_bytes; + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + net_stats->rx_packets += + bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]->rxq->rx_packets; + net_stats->rx_bytes += + bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]->rxq->rx_bytes; + } + } + } + } + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + if (bnad->tx_info[i].tcb[j]) { + net_stats->tx_packets += + bnad->tx_info[i].tcb[j]->txq->tx_packets; + net_stats->tx_bytes += + bnad->tx_info[i].tcb[j]->txq->tx_bytes; + } + } + } +} + +/* + * Must be called with the bna_lock held. + */ +void +bnad_netdev_hwstats_fill(struct bnad *bnad) +{ + struct bfi_ll_stats_mac *mac_stats; + struct net_device_stats *net_stats = &bnad->net_stats; + u64 bmap; + int i; + + mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats; + net_stats->rx_errors = + mac_stats->rx_fcs_error + mac_stats->rx_alignment_error + + mac_stats->rx_frame_length_error + mac_stats->rx_code_error + + mac_stats->rx_undersize; + net_stats->tx_errors = mac_stats->tx_fcs_error + + mac_stats->tx_undersize; + net_stats->rx_dropped = mac_stats->rx_drop; + net_stats->tx_dropped = mac_stats->tx_drop; + net_stats->multicast = mac_stats->rx_multicast; + net_stats->collisions = mac_stats->tx_total_collision; + + net_stats->rx_length_errors = mac_stats->rx_frame_length_error; + + /* receive ring buffer overflow ?? */ + + net_stats->rx_crc_errors = mac_stats->rx_fcs_error; + net_stats->rx_frame_errors = mac_stats->rx_alignment_error; + /* recv'r fifo overrun */ + bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] | + ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + net_stats->rx_fifo_errors = + bnad->stats.bna_stats-> + hw_stats->rxf_stats[i].frame_drops; + break; + } + bmap >>= 1; + } +} + +static void +bnad_mbox_irq_sync(struct bnad *bnad) +{ + u32 irq; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) + irq = bnad->msix_table[bnad->msix_num - 1].vector; + else + irq = bnad->pcidev->irq; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + synchronize_irq(irq); +} + +/* Utility used by bnad_start_xmit, for doing TSO */ +static int +bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb) +{ + int err; + + /* SKB_GSO_TCPV4 and SKB_GSO_TCPV6 is defined since 2.6.18. */ + BUG_ON(!(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4 || + skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)); + if (skb_header_cloned(skb)) { + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (err) { + BNAD_UPDATE_CTR(bnad, tso_err); + return err; + } + } + + /* + * For TSO, the TCP checksum field is seeded with pseudo-header sum + * excluding the length field. + */ + if (skb->protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); + + /* Do we really need these? */ + iph->tot_len = 0; + iph->check = 0; + + tcp_hdr(skb)->check = + ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, + IPPROTO_TCP, 0); + BNAD_UPDATE_CTR(bnad, tso4); + } else { + struct ipv6hdr *ipv6h = ipv6_hdr(skb); + + BUG_ON(!(skb->protocol == htons(ETH_P_IPV6))); + ipv6h->payload_len = 0; + tcp_hdr(skb)->check = + ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 0, + IPPROTO_TCP, 0); + BNAD_UPDATE_CTR(bnad, tso6); + } + + return 0; +} + +/* + * Initialize Q numbers depending on Rx Paths + * Called with bnad->bna_lock held, because of cfg_flags + * access. + */ +static void +bnad_q_num_init(struct bnad *bnad) +{ + int rxps; + + rxps = min((uint)num_online_cpus(), + (uint)(BNAD_MAX_RXS * BNAD_MAX_RXPS_PER_RX)); + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) + rxps = 1; /* INTx */ + + bnad->num_rx = 1; + bnad->num_tx = 1; + bnad->num_rxp_per_rx = rxps; + bnad->num_txq_per_tx = BNAD_TXQ_NUM; +} + +/* + * Adjusts the Q numbers, given a number of msix vectors + * Give preference to RSS as opposed to Tx priority Queues, + * in such a case, just use 1 Tx Q + * Called with bnad->bna_lock held b'cos of cfg_flags access + */ +static void +bnad_q_num_adjust(struct bnad *bnad, int msix_vectors) +{ + bnad->num_txq_per_tx = 1; + if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) + + bnad_rxqs_per_cq + BNAD_MAILBOX_MSIX_VECTORS) && + (bnad->cfg_flags & BNAD_CF_MSIX)) { + bnad->num_rxp_per_rx = msix_vectors - + (bnad->num_tx * bnad->num_txq_per_tx) - + BNAD_MAILBOX_MSIX_VECTORS; + } else + bnad->num_rxp_per_rx = 1; +} + +static void +bnad_set_netdev_perm_addr(struct bnad *bnad) +{ + struct net_device *netdev = bnad->netdev; + + memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len); + if (is_zero_ether_addr(netdev->dev_addr)) + memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len); +} + +/* Enable / disable device */ +static void +bnad_device_disable(struct bnad *bnad) +{ + unsigned long flags; + + init_completion(&bnad->bnad_completions.ioc_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_device_disable(&bnad->bna.device, BNA_HARD_CLEANUP); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.ioc_comp); + +} + +static int +bnad_device_enable(struct bnad *bnad) +{ + int err = 0; + unsigned long flags; + + init_completion(&bnad->bnad_completions.ioc_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_device_enable(&bnad->bna.device); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.ioc_comp); + + if (bnad->bnad_completions.ioc_comp_status) + err = bnad->bnad_completions.ioc_comp_status; + + return err; +} + +/* Free BNA resources */ +static void +bnad_res_free(struct bnad *bnad) +{ + int i; + struct bna_res_info *res_info = &bnad->res_info[0]; + + for (i = 0; i < BNA_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else + bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for BNA */ +static int +bnad_res_alloc(struct bnad *bnad) +{ + int i, err; + struct bna_res_info *res_info = &bnad->res_info[0]; + + for (i = 0; i < BNA_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info); + else + err = bnad_mbox_irq_alloc(bnad, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_res_free(bnad); + return err; +} + +/* Interrupt enable / disable */ +static void +bnad_enable_msix(struct bnad *bnad) +{ + int i, ret; + u32 tot_msix_num; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) { + spin_unlock_irqrestore(&bnad->bna_lock, flags); + return; + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (bnad->msix_table) + return; + + tot_msix_num = bnad->msix_num + bnad->msix_diag_num; + + bnad->msix_table = + kcalloc(tot_msix_num, sizeof(struct msix_entry), GFP_KERNEL); + + if (!bnad->msix_table) + goto intx_mode; + + for (i = 0; i < tot_msix_num; i++) + bnad->msix_table[i].entry = i; + + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, tot_msix_num); + if (ret > 0) { + /* Not enough MSI-X vectors. */ + + spin_lock_irqsave(&bnad->bna_lock, flags); + /* ret = #of vectors that we got */ + bnad_q_num_adjust(bnad, ret); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) + + (bnad->num_rx + * bnad->num_rxp_per_rx) + + BNAD_MAILBOX_MSIX_VECTORS; + tot_msix_num = bnad->msix_num + bnad->msix_diag_num; + + /* Try once more with adjusted numbers */ + /* If this fails, fall back to INTx */ + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, + tot_msix_num); + if (ret) + goto intx_mode; + + } else if (ret < 0) + goto intx_mode; + return; + +intx_mode: + + kfree(bnad->msix_table); + bnad->msix_table = NULL; + bnad->msix_num = 0; + bnad->msix_diag_num = 0; + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad->cfg_flags &= ~BNAD_CF_MSIX; + bnad_q_num_init(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_disable_msix(struct bnad *bnad) +{ + u32 cfg_flags; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + cfg_flags = bnad->cfg_flags; + if (bnad->cfg_flags & BNAD_CF_MSIX) + bnad->cfg_flags &= ~BNAD_CF_MSIX; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (cfg_flags & BNAD_CF_MSIX) { + pci_disable_msix(bnad->pcidev); + kfree(bnad->msix_table); + bnad->msix_table = NULL; + } +} + +/* Netdev entry points */ +static int +bnad_open(struct net_device *netdev) +{ + int err; + struct bnad *bnad = netdev_priv(netdev); + struct bna_pause_config pause_config; + int mtu; + unsigned long flags; + + mutex_lock(&bnad->conf_mutex); + + /* Tx */ + err = bnad_setup_tx(bnad, 0); + if (err) + goto err_return; + + /* Rx */ + err = bnad_setup_rx(bnad, 0); + if (err) + goto cleanup_tx; + + /* Port */ + pause_config.tx_pause = 0; + pause_config.rx_pause = 0; + + mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mtu_set(&bnad->bna.port, mtu, NULL); + bna_port_pause_config(&bnad->bna.port, &pause_config, NULL); + bna_port_enable(&bnad->bna.port); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Enable broadcast */ + bnad_enable_default_bcast(bnad); + + /* Set the UCAST address */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad_mac_addr_set_locked(bnad, netdev->dev_addr); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Start the stats timer */ + bnad_stats_timer_start(bnad); + + mutex_unlock(&bnad->conf_mutex); + + return 0; + +cleanup_tx: + bnad_cleanup_tx(bnad, 0); + +err_return: + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static int +bnad_stop(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + mutex_lock(&bnad->conf_mutex); + + /* Stop the stats timer */ + bnad_stats_timer_stop(bnad); + + init_completion(&bnad->bnad_completions.port_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_disable(&bnad->bna.port, BNA_HARD_CLEANUP, + bnad_cb_port_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.port_comp); + + bnad_cleanup_tx(bnad, 0); + bnad_cleanup_rx(bnad, 0); + + /* Synchronize mailbox IRQ */ + bnad_mbox_irq_sync(bnad); + + mutex_unlock(&bnad->conf_mutex); + + return 0; +} + +/* TX */ +/* + * bnad_start_xmit : Netdev entry point for Transmit + * Called under lock held by net_device + */ +static netdev_tx_t +bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + + u16 txq_prod, vlan_tag = 0; + u32 unmap_prod, wis, wis_used, wi_range; + u32 vectors, vect_id, i, acked; + u32 tx_id; + int err; + + struct bnad_tx_info *tx_info; + struct bna_tcb *tcb; + struct bnad_unmap_q *unmap_q; + dma_addr_t dma_addr; + struct bna_txq_entry *txqent; + bna_txq_wi_ctrl_flag_t flags; + + if (unlikely + (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + /* + * Takes care of the Tx that is scheduled between clearing the flag + * and the netif_stop_queue() call. + */ + if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + tx_id = 0; + + tx_info = &bnad->tx_info[tx_id]; + tcb = tx_info->tcb[tx_id]; + unmap_q = tcb->unmap_q; + + vectors = 1 + skb_shinfo(skb)->nr_frags; + if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */ + acked = 0; + if (unlikely + (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) || + vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) { + if ((u16) (*tcb->hw_consumer_index) != + tcb->consumer_index && + !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) { + acked = bnad_free_txbufs(bnad, tcb); + bna_ib_ack(tcb->i_dbell, acked); + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + } else { + netif_stop_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + } + + smp_mb(); + /* + * Check again to deal with race condition between + * netif_stop_queue here, and netif_wake_queue in + * interrupt handler which is not inside netif tx lock. + */ + if (likely + (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) || + vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) { + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + return NETDEV_TX_BUSY; + } else { + netif_wake_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } + } + + unmap_prod = unmap_q->producer_index; + wis_used = 1; + vect_id = 0; + flags = 0; + + txq_prod = tcb->producer_index; + BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, txqent, wi_range); + BUG_ON(!(wi_range <= tcb->q_depth)); + txqent->hdr.wi.reserved = 0; + txqent->hdr.wi.num_vectors = vectors; + txqent->hdr.wi.opcode = + htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO : + BNA_TXQ_WI_SEND)); + + if (bnad->vlan_grp && vlan_tx_tag_present(skb)) { + vlan_tag = (u16) vlan_tx_tag_get(skb); + flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); + } + if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) { + vlan_tag = + (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff); + flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); + } + + txqent->hdr.wi.vlan_tag = htons(vlan_tag); + + if (skb_is_gso(skb)) { + err = bnad_tso_prepare(bnad, skb); + if (err) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb)); + flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM); + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (tcp_hdrlen(skb) >> 2, + skb_transport_offset(skb))); + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + u8 proto = 0; + + txqent->hdr.wi.lso_mss = 0; + + if (skb->protocol == htons(ETH_P_IP)) + proto = ip_hdr(skb)->protocol; + else if (skb->protocol == htons(ETH_P_IPV6)) { + /* nexthdr may not be TCP immediately. */ + proto = ipv6_hdr(skb)->nexthdr; + } + if (proto == IPPROTO_TCP) { + flags |= BNA_TXQ_WI_CF_TCP_CKSUM; + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (0, skb_transport_offset(skb))); + + BNAD_UPDATE_CTR(bnad, tcpcsum_offload); + + BUG_ON(!(skb_headlen(skb) >= + skb_transport_offset(skb) + tcp_hdrlen(skb))); + + } else if (proto == IPPROTO_UDP) { + flags |= BNA_TXQ_WI_CF_UDP_CKSUM; + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (0, skb_transport_offset(skb))); + + BNAD_UPDATE_CTR(bnad, udpcsum_offload); + + BUG_ON(!(skb_headlen(skb) >= + skb_transport_offset(skb) + + sizeof(struct udphdr))); + } else { + err = skb_checksum_help(skb); + BNAD_UPDATE_CTR(bnad, csum_help); + if (err) { + dev_kfree_skb(skb); + BNAD_UPDATE_CTR(bnad, csum_help_err); + return NETDEV_TX_OK; + } + } + } else { + txqent->hdr.wi.lso_mss = 0; + txqent->hdr.wi.l4_hdr_size_n_offset = 0; + } + + txqent->hdr.wi.flags = htons(flags); + + txqent->hdr.wi.frame_length = htonl(skb->len); + + unmap_q->unmap_array[unmap_prod].skb = skb; + BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR)); + txqent->vector[vect_id].length = htons(skb_headlen(skb)); + dma_addr = pci_map_single(bnad->pcidev, skb->data, skb_headlen(skb), + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr); + + BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + u32 size = frag->size; + + if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) { + vect_id = 0; + if (--wi_range) + txqent++; + else { + BNA_QE_INDX_ADD(txq_prod, wis_used, + tcb->q_depth); + wis_used = 0; + BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, + txqent, wi_range); + BUG_ON(!(wi_range <= tcb->q_depth)); + } + wis_used++; + txqent->hdr.wi_ext.opcode = htons(BNA_TXQ_WI_EXTENSION); + } + + BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR)); + txqent->vector[vect_id].length = htons(size); + dma_addr = + pci_map_page(bnad->pcidev, frag->page, + frag->page_offset, size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr); + BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + } + + unmap_q->producer_index = unmap_prod; + BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth); + tcb->producer_index = txq_prod; + + smp_mb(); + bna_txq_prod_indx_doorbell(tcb); + + if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index) + tasklet_schedule(&bnad->tx_free_tasklet); + + return NETDEV_TX_OK; +} + +/* + * Used spin_lock to synchronize reading of stats structures, which + * is written by BNA under the same lock. + */ +static struct net_device_stats * +bnad_get_netdev_stats(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); + + bnad_netdev_qstats_fill(bnad); + bnad_netdev_hwstats_fill(bnad); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return &bnad->net_stats; +} + +static void +bnad_set_rx_mode(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + u32 new_mask, valid_mask; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + new_mask = valid_mask = 0; + + if (netdev->flags & IFF_PROMISC) { + if (!(bnad->cfg_flags & BNAD_CF_PROMISC)) { + new_mask = BNAD_RXMODE_PROMISC_DEFAULT; + valid_mask = BNAD_RXMODE_PROMISC_DEFAULT; + bnad->cfg_flags |= BNAD_CF_PROMISC; + } + } else { + if (bnad->cfg_flags & BNAD_CF_PROMISC) { + new_mask = ~BNAD_RXMODE_PROMISC_DEFAULT; + valid_mask = BNAD_RXMODE_PROMISC_DEFAULT; + bnad->cfg_flags &= ~BNAD_CF_PROMISC; + } + } + + if (netdev->flags & IFF_ALLMULTI) { + if (!(bnad->cfg_flags & BNAD_CF_ALLMULTI)) { + new_mask |= BNA_RXMODE_ALLMULTI; + valid_mask |= BNA_RXMODE_ALLMULTI; + bnad->cfg_flags |= BNAD_CF_ALLMULTI; + } + } else { + if (bnad->cfg_flags & BNAD_CF_ALLMULTI) { + new_mask &= ~BNA_RXMODE_ALLMULTI; + valid_mask |= BNA_RXMODE_ALLMULTI; + bnad->cfg_flags &= ~BNAD_CF_ALLMULTI; + } + } + + bna_rx_mode_set(bnad->rx_info[0].rx, new_mask, valid_mask, NULL); + + if (!netdev_mc_empty(netdev)) { + u8 *mcaddr_list; + int mc_count = netdev_mc_count(netdev); + + /* Index 0 holds the broadcast address */ + mcaddr_list = + kzalloc((mc_count + 1) * ETH_ALEN, + GFP_ATOMIC); + if (!mcaddr_list) + return; + + memcpy(&mcaddr_list[0], &bnad_bcast_addr[0], ETH_ALEN); + + /* Copy rest of the MC addresses */ + bnad_netdev_mc_list_get(netdev, mcaddr_list); + + bna_rx_mcast_listset(bnad->rx_info[0].rx, mc_count + 1, + mcaddr_list, NULL); + + /* Should we enable BNAD_CF_ALLMULTI for err != 0 ? */ + kfree(mcaddr_list); + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * bna_lock is used to sync writes to netdev->addr + * conf_lock cannot be used since this call may be made + * in a non-blocking context. + */ +static int +bnad_set_mac_address(struct net_device *netdev, void *mac_addr) +{ + int err; + struct bnad *bnad = netdev_priv(netdev); + struct sockaddr *sa = (struct sockaddr *)mac_addr; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + err = bnad_mac_addr_set_locked(bnad, sa->sa_data); + + if (!err) + memcpy(netdev->dev_addr, sa->sa_data, netdev->addr_len); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return err; +} + +static int +bnad_change_mtu(struct net_device *netdev, int new_mtu) +{ + int mtu, err = 0; + unsigned long flags; + + struct bnad *bnad = netdev_priv(netdev); + + if (new_mtu + ETH_HLEN < ETH_ZLEN || new_mtu > BNAD_JUMBO_MTU) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + + netdev->mtu = new_mtu; + + mtu = ETH_HLEN + new_mtu + ETH_FCS_LEN; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mtu_set(&bnad->bna.port, mtu, NULL); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static void +bnad_vlan_rx_register(struct net_device *netdev, + struct vlan_group *vlan_grp) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad->vlan_grp = vlan_grp; + mutex_unlock(&bnad->conf_mutex); +} + +static void +bnad_vlan_rx_add_vid(struct net_device *netdev, + unsigned short vid) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + if (!bnad->rx_info[0].rx) + return; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_vlan_add(bnad->rx_info[0].rx, vid); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +static void +bnad_vlan_rx_kill_vid(struct net_device *netdev, + unsigned short vid) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + if (!bnad->rx_info[0].rx) + return; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_vlan_del(bnad->rx_info[0].rx, vid); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void +bnad_netpoll(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + u32 curr_mask; + int i, j; + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) { + bna_intx_disable(&bnad->bna, curr_mask); + bnad_isr(bnad->pcidev->irq, netdev); + bna_intx_enable(&bnad->bna, curr_mask); + } else { + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (rx_ctrl->ccb) { + bnad_disable_rx_irq(bnad, + rx_ctrl->ccb); + bnad_netif_rx_schedule_poll(bnad, + rx_ctrl->ccb); + } + } + } + } +} +#endif + +static const struct net_device_ops bnad_netdev_ops = { + .ndo_open = bnad_open, + .ndo_stop = bnad_stop, + .ndo_start_xmit = bnad_start_xmit, + .ndo_get_stats = bnad_get_netdev_stats, + .ndo_set_rx_mode = bnad_set_rx_mode, + .ndo_set_multicast_list = bnad_set_rx_mode, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = bnad_set_mac_address, + .ndo_change_mtu = bnad_change_mtu, + .ndo_vlan_rx_register = bnad_vlan_rx_register, + .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bnad_netpoll +#endif +}; + +static void +bnad_netdev_init(struct bnad *bnad, bool using_dac) +{ + struct net_device *netdev = bnad->netdev; + + netdev->features |= NETIF_F_IPV6_CSUM; + netdev->features |= NETIF_F_TSO; + netdev->features |= NETIF_F_TSO6; + + netdev->features |= NETIF_F_GRO; + pr_warn("bna: GRO enabled, using kernel stack GRO\n"); + + netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + + if (using_dac) + netdev->features |= NETIF_F_HIGHDMA; + + netdev->features |= + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; + + netdev->vlan_features = netdev->features; + netdev->mem_start = bnad->mmio_start; + netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1; + + netdev->netdev_ops = &bnad_netdev_ops; + bnad_set_ethtool_ops(netdev); +} + +/* + * 1. Initialize the bnad structure + * 2. Setup netdev pointer in pci_dev + * 3. Initialze Tx free tasklet + * 4. Initialize no. of TxQ & CQs & MSIX vectors + */ +static int +bnad_init(struct bnad *bnad, + struct pci_dev *pdev, struct net_device *netdev) +{ + unsigned long flags; + + SET_NETDEV_DEV(netdev, &pdev->dev); + pci_set_drvdata(pdev, netdev); + + bnad->netdev = netdev; + bnad->pcidev = pdev; + bnad->mmio_start = pci_resource_start(pdev, 0); + bnad->mmio_len = pci_resource_len(pdev, 0); + bnad->bar0 = ioremap_nocache(bnad->mmio_start, bnad->mmio_len); + if (!bnad->bar0) { + dev_err(&pdev->dev, "ioremap for bar0 failed\n"); + pci_set_drvdata(pdev, NULL); + return -ENOMEM; + } + pr_info("bar0 mapped to %p, len %llu\n", bnad->bar0, + (unsigned long long) bnad->mmio_len); + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!bnad_msix_disable) + bnad->cfg_flags = BNAD_CF_MSIX; + + bnad->cfg_flags |= BNAD_CF_DIM_ENABLED; + + bnad_q_num_init(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) + + (bnad->num_rx * bnad->num_rxp_per_rx) + + BNAD_MAILBOX_MSIX_VECTORS; + bnad->msix_diag_num = 2; /* 1 for Tx, 1 for Rx */ + + bnad->txq_depth = BNAD_TXQ_DEPTH; + bnad->rxq_depth = BNAD_RXQ_DEPTH; + bnad->rx_csum = true; + + bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO; + bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO; + + tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet, + (unsigned long)bnad); + + return 0; +} + +/* + * Must be called after bnad_pci_uninit() + * so that iounmap() and pci_set_drvdata(NULL) + * happens only after PCI uninitialization. + */ +static void +bnad_uninit(struct bnad *bnad) +{ + if (bnad->bar0) + iounmap(bnad->bar0); + pci_set_drvdata(bnad->pcidev, NULL); +} + +/* + * Initialize locks + a) Per device mutes used for serializing configuration + changes from OS interface + b) spin lock used to protect bna state machine + */ +static void +bnad_lock_init(struct bnad *bnad) +{ + spin_lock_init(&bnad->bna_lock); + mutex_init(&bnad->conf_mutex); +} + +static void +bnad_lock_uninit(struct bnad *bnad) +{ + mutex_destroy(&bnad->conf_mutex); +} + +/* PCI Initialization */ +static int +bnad_pci_init(struct bnad *bnad, + struct pci_dev *pdev, bool *using_dac) +{ + int err; + + err = pci_enable_device(pdev); + if (err) + return err; + err = pci_request_regions(pdev, BNAD_NAME); + if (err) + goto disable_device; + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && + !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + *using_dac = 1; + } else { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + if (err) + goto release_regions; + } + *using_dac = 0; + } + pci_set_master(pdev); + return 0; + +release_regions: + pci_release_regions(pdev); +disable_device: + pci_disable_device(pdev); + + return err; +} + +static void +bnad_pci_uninit(struct pci_dev *pdev) +{ + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static int __devinit +bnad_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pcidev_id) +{ + bool using_dac; + int err; + struct bnad *bnad; + struct bna *bna; + struct net_device *netdev; + struct bfa_pcidev pcidev_info; + unsigned long flags; + + pr_info("bnad_pci_probe : (0x%p, 0x%p) PCI Func : (%d)\n", + pdev, pcidev_id, PCI_FUNC(pdev->devfn)); + + mutex_lock(&bnad_fwimg_mutex); + if (!cna_get_firmware_buf(pdev)) { + mutex_unlock(&bnad_fwimg_mutex); + pr_warn("Failed to load Firmware Image!\n"); + return -ENODEV; + } + mutex_unlock(&bnad_fwimg_mutex); + + /* + * Allocates sizeof(struct net_device + struct bnad) + * bnad = netdev->priv + */ + netdev = alloc_etherdev(sizeof(struct bnad)); + if (!netdev) { + dev_err(&pdev->dev, "alloc_etherdev failed\n"); + err = -ENOMEM; + return err; + } + bnad = netdev_priv(netdev); + + + /* + * PCI initialization + * Output : using_dac = 1 for 64 bit DMA + * = 0 for 32 bit DMA + */ + err = bnad_pci_init(bnad, pdev, &using_dac); + if (err) + goto free_netdev; + + bnad_lock_init(bnad); + /* + * Initialize bnad structure + * Setup relation between pci_dev & netdev + * Init Tx free tasklet + */ + err = bnad_init(bnad, pdev, netdev); + if (err) + goto pci_uninit; + /* Initialize netdev structure, set up ethtool ops */ + bnad_netdev_init(bnad, using_dac); + + bnad_enable_msix(bnad); + + /* Get resource requirement form bna */ + bna_res_req(&bnad->res_info[0]); + + /* Allocate resources from bna */ + err = bnad_res_alloc(bnad); + if (err) + goto free_netdev; + + bna = &bnad->bna; + + /* Setup pcidev_info for bna_init() */ + pcidev_info.pci_slot = PCI_SLOT(bnad->pcidev->devfn); + pcidev_info.pci_func = PCI_FUNC(bnad->pcidev->devfn); + pcidev_info.device_id = bnad->pcidev->device; + pcidev_info.pci_bar_kva = bnad->bar0; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->stats.bna_stats = &bna->stats; + + /* Set up timers */ + setup_timer(&bnad->bna.device.ioc.ioc_timer, bnad_ioc_timeout, + ((unsigned long)bnad)); + setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check, + ((unsigned long)bnad)); + setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout, + ((unsigned long)bnad)); + + /* Now start the timer before calling IOC */ + mod_timer(&bnad->bna.device.ioc.ioc_timer, + jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ)); + + /* + * Start the chip + * Don't care even if err != 0, bna state machine will + * deal with it + */ + err = bnad_device_enable(bnad); + + /* Get the burnt-in mac */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mac_get(&bna->port, &bnad->perm_addr); + bnad_set_netdev_perm_addr(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + + /* + * Make sure the link appears down to the stack + */ + netif_carrier_off(netdev); + + /* Finally, reguister with net_device layer */ + err = register_netdev(netdev); + if (err) { + pr_err("BNA : Registering with netdev failed\n"); + goto disable_device; + } + + return 0; + +disable_device: + mutex_lock(&bnad->conf_mutex); + bnad_device_disable(bnad); + del_timer_sync(&bnad->bna.device.ioc.ioc_timer); + del_timer_sync(&bnad->bna.device.ioc.sem_timer); + del_timer_sync(&bnad->bna.device.ioc.hb_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_uninit(bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + mutex_unlock(&bnad->conf_mutex); + + bnad_res_free(bnad); + bnad_disable_msix(bnad); +pci_uninit: + bnad_pci_uninit(pdev); + bnad_lock_uninit(bnad); + bnad_uninit(bnad); +free_netdev: + free_netdev(netdev); + return err; +} + +static void __devexit +bnad_pci_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct bnad *bnad; + struct bna *bna; + unsigned long flags; + + if (!netdev) + return; + + pr_info("%s bnad_pci_remove\n", netdev->name); + bnad = netdev_priv(netdev); + bna = &bnad->bna; + + unregister_netdev(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad_device_disable(bnad); + del_timer_sync(&bnad->bna.device.ioc.ioc_timer); + del_timer_sync(&bnad->bna.device.ioc.sem_timer); + del_timer_sync(&bnad->bna.device.ioc.hb_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_uninit(bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + mutex_unlock(&bnad->conf_mutex); + + bnad_res_free(bnad); + bnad_disable_msix(bnad); + bnad_pci_uninit(pdev); + bnad_lock_uninit(bnad); + bnad_uninit(bnad); + free_netdev(netdev); +} + +const struct pci_device_id bnad_pci_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_BROCADE, + PCI_DEVICE_ID_BROCADE_CT), + .class = PCI_CLASS_NETWORK_ETHERNET << 8, + .class_mask = 0xffff00 + }, {0, } +}; + +MODULE_DEVICE_TABLE(pci, bnad_pci_id_table); + +static struct pci_driver bnad_pci_driver = { + .name = BNAD_NAME, + .id_table = bnad_pci_id_table, + .probe = bnad_pci_probe, + .remove = __devexit_p(bnad_pci_remove), +}; + +static int __init +bnad_module_init(void) +{ + int err; + + pr_info("Brocade 10G Ethernet driver\n"); + + bfa_ioc_auto_recover(bnad_ioc_auto_recover); + + err = pci_register_driver(&bnad_pci_driver); + if (err < 0) { + pr_err("bna : PCI registration failed in module init " + "(%d)\n", err); + return err; + } + + return 0; +} + +static void __exit +bnad_module_exit(void) +{ + pci_unregister_driver(&bnad_pci_driver); + + if (bfi_fw) + release_firmware(bfi_fw); +} + +module_init(bnad_module_init); +module_exit(bnad_module_exit); + +MODULE_AUTHOR("Brocade"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver"); +MODULE_VERSION(BNAD_VERSION); +MODULE_FIRMWARE(CNA_FW_FILE_CT); diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h new file mode 100644 index 000000000000..3261401e35cb --- /dev/null +++ b/drivers/net/bna/bnad.h @@ -0,0 +1,334 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BNAD_H__ +#define __BNAD_H__ + +#include +#include +#include +#include +#include +#include + +/* Fix for IA64 */ +#include +#include + +#include +#include + +#include "bna.h" + +#define BNAD_TXQ_DEPTH 2048 +#define BNAD_RXQ_DEPTH 2048 + +#define BNAD_MAX_TXS 1 +#define BNAD_MAX_TXQ_PER_TX 8 /* 8 priority queues */ +#define BNAD_TXQ_NUM 1 + +#define BNAD_MAX_RXS 1 +#define BNAD_MAX_RXPS_PER_RX 16 + +/* + * Control structure pointed to ccb->ctrl, which + * determines the NAPI / LRO behavior CCB + * There is 1:1 corres. between ccb & ctrl + */ +struct bnad_rx_ctrl { + struct bna_ccb *ccb; + struct napi_struct napi; +}; + +#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC + +#define BNAD_GET_TX_ID(_skb) (0) + +/* + * GLOBAL #defines (CONSTANTS) + */ +#define BNAD_NAME "bna" +#define BNAD_NAME_LEN 64 + +#define BNAD_VERSION "2.3.2.0" + +#define BNAD_MAILBOX_MSIX_VECTORS 1 + +#define BNAD_STATS_TIMER_FREQ 1000 /* in msecs */ +#define BNAD_DIM_TIMER_FREQ 1000 /* in msecs */ + +#define BNAD_MAX_Q_DEPTH 0x10000 +#define BNAD_MIN_Q_DEPTH 0x200 + +#define BNAD_JUMBO_MTU 9000 + +#define BNAD_NETIF_WAKE_THRESHOLD 8 + +#define BNAD_RXQ_REFILL_THRESHOLD_SHIFT 3 + +/* Bit positions for tcb->flags */ +#define BNAD_TXQ_FREE_SENT 0 + +/* Bit positions for rcb->flags */ +#define BNAD_RXQ_REFILL 0 +#define BNAD_RXQ_STARTED 1 + +/* + * DATA STRUCTURES + */ + +/* enums */ +enum bnad_intr_source { + BNAD_INTR_TX = 1, + BNAD_INTR_RX = 2 +}; + +enum bnad_link_state { + BNAD_LS_DOWN = 0, + BNAD_LS_UP = 1 +}; + +struct bnad_completion { + struct completion ioc_comp; + struct completion ucast_comp; + struct completion mcast_comp; + struct completion tx_comp; + struct completion rx_comp; + struct completion stats_comp; + struct completion port_comp; + + u8 ioc_comp_status; + u8 ucast_comp_status; + u8 mcast_comp_status; + u8 tx_comp_status; + u8 rx_comp_status; + u8 stats_comp_status; + u8 port_comp_status; +}; + +/* Tx Rx Control Stats */ +struct bnad_drv_stats { + u64 netif_queue_stop; + u64 netif_queue_wakeup; + u64 tso4; + u64 tso6; + u64 tso_err; + u64 tcpcsum_offload; + u64 udpcsum_offload; + u64 csum_help; + u64 csum_help_err; + + u64 hw_stats_updates; + u64 netif_rx_schedule; + u64 netif_rx_complete; + u64 netif_rx_dropped; + + u64 link_toggle; + u64 cee_up; + + u64 rxp_info_alloc_failed; + u64 mbox_intr_disabled; + u64 mbox_intr_enabled; + u64 tx_unmap_q_alloc_failed; + u64 rx_unmap_q_alloc_failed; + + u64 rxbuf_alloc_failed; +}; + +/* Complete driver stats */ +struct bnad_stats { + struct bnad_drv_stats drv_stats; + struct bna_stats *bna_stats; +}; + +/* Tx / Rx Resources */ +struct bnad_tx_res_info { + struct bna_res_info res_info[BNA_TX_RES_T_MAX]; +}; + +struct bnad_rx_res_info { + struct bna_res_info res_info[BNA_RX_RES_T_MAX]; +}; + +struct bnad_tx_info { + struct bna_tx *tx; /* 1:1 between tx_info & tx */ + struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX]; +} ____cacheline_aligned; + +struct bnad_rx_info { + struct bna_rx *rx; /* 1:1 between rx_info & rx */ + + struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXPS_PER_RX]; +} ____cacheline_aligned; + +/* Unmap queues for Tx / Rx cleanup */ +struct bnad_skb_unmap { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(dma_addr) +}; + +struct bnad_unmap_q { + u32 producer_index; + u32 consumer_index; + u32 q_depth; + /* This should be the last one */ + struct bnad_skb_unmap unmap_array[1]; +}; + +/* Bit mask values for bnad->cfg_flags */ +#define BNAD_CF_DIM_ENABLED 0x01 /* DIM */ +#define BNAD_CF_PROMISC 0x02 +#define BNAD_CF_ALLMULTI 0x04 +#define BNAD_CF_MSIX 0x08 /* If in MSIx mode */ + +/* Defines for run_flags bit-mask */ +/* Set, tested & cleared using xxx_bit() functions */ +/* Values indicated bit positions */ +#define BNAD_RF_CEE_RUNNING 1 +#define BNAD_RF_HW_ERROR 2 +#define BNAD_RF_MBOX_IRQ_DISABLED 3 +#define BNAD_RF_TX_STARTED 4 +#define BNAD_RF_RX_STARTED 5 +#define BNAD_RF_DIM_TIMER_RUNNING 6 +#define BNAD_RF_STATS_TIMER_RUNNING 7 + +struct bnad { + struct net_device *netdev; + + /* Data path */ + struct bnad_tx_info tx_info[BNAD_MAX_TXS]; + struct bnad_rx_info rx_info[BNAD_MAX_RXS]; + + struct vlan_group *vlan_grp; + /* + * These q numbers are global only because + * they are used to calculate MSIx vectors. + * Actually the exact # of queues are per Tx/Rx + * object. + */ + u32 num_tx; + u32 num_rx; + u32 num_txq_per_tx; + u32 num_rxp_per_rx; + + u32 txq_depth; + u32 rxq_depth; + + u8 tx_coalescing_timeo; + u8 rx_coalescing_timeo; + + struct bna_rx_config rx_config[BNAD_MAX_RXS]; + struct bna_tx_config tx_config[BNAD_MAX_TXS]; + + u32 rx_csum; + + void __iomem *bar0; /* BAR0 address */ + + struct bna bna; + + u32 cfg_flags; + unsigned long run_flags; + + struct pci_dev *pcidev; + u64 mmio_start; + u64 mmio_len; + + u32 msix_num; + u32 msix_diag_num; + struct msix_entry *msix_table; + + struct mutex conf_mutex; + spinlock_t bna_lock ____cacheline_aligned; + + /* Timers */ + struct timer_list ioc_timer; + struct timer_list dim_timer; + struct timer_list stats_timer; + + /* Control path resources, memory & irq */ + struct bna_res_info res_info[BNA_RES_T_MAX]; + struct bnad_tx_res_info tx_res_info[BNAD_MAX_TXS]; + struct bnad_rx_res_info rx_res_info[BNAD_MAX_RXS]; + + struct bnad_completion bnad_completions; + + /* Burnt in MAC address */ + mac_t perm_addr; + + struct tasklet_struct tx_free_tasklet; + + /* Statistics */ + struct bnad_stats stats; + struct net_device_stats net_stats; + + struct bnad_diag *diag; + + char adapter_name[BNAD_NAME_LEN]; + char port_name[BNAD_NAME_LEN]; + char mbox_irq_name[BNAD_NAME_LEN]; +}; + +/* + * EXTERN VARIABLES + */ +extern struct firmware *bfi_fw; +extern u32 bnad_rxqs_per_cq; + +/* + * EXTERN PROTOTYPES + */ +extern u32 *cna_get_firmware_buf(struct pci_dev *pdev); +/* Netdev entry point prototypes */ +extern void bnad_set_ethtool_ops(struct net_device *netdev); + +/* Configuration & setup */ +extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad); +extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad); + +extern int bnad_setup_rx(struct bnad *bnad, uint rx_id); +extern int bnad_setup_tx(struct bnad *bnad, uint tx_id); +extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id); +extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id); + +/* Timer start/stop protos */ +extern void bnad_dim_timer_start(struct bnad *bnad); + +/* Statistics */ +extern void bnad_netdev_qstats_fill(struct bnad *bnad); +extern void bnad_netdev_hwstats_fill(struct bnad *bnad); + +/** + * MACROS + */ +/* To set & get the stats counters */ +#define BNAD_UPDATE_CTR(_bnad, _ctr) \ + (((_bnad)->stats.drv_stats._ctr)++) + +#define BNAD_GET_CTR(_bnad, _ctr) ((_bnad)->stats.drv_stats._ctr) + +#define bnad_enable_rx_irq_unsafe(_ccb) \ +{ \ + bna_ib_coalescing_timer_set((_ccb)->i_dbell, \ + (_ccb)->rx_coalescing_timeo); \ + bna_ib_ack((_ccb)->i_dbell, 0); \ +} + +#define bnad_dim_timer_running(_bnad) \ + (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) && \ + (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags)))) + +#endif /* __BNAD_H__ */ diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c new file mode 100644 index 000000000000..e982785b6b25 --- /dev/null +++ b/drivers/net/bna/bnad_ethtool.c @@ -0,0 +1,1282 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "cna.h" + +#include +#include +#include +#include + +#include "bna.h" + +#include "bnad.h" + +#define BNAD_NUM_TXF_COUNTERS 12 +#define BNAD_NUM_RXF_COUNTERS 10 +#define BNAD_NUM_CQ_COUNTERS 3 +#define BNAD_NUM_RXQ_COUNTERS 6 +#define BNAD_NUM_TXQ_COUNTERS 5 + +#define BNAD_ETHTOOL_STATS_NUM \ + (sizeof(struct net_device_stats) / sizeof(unsigned long) + \ + sizeof(struct bnad_drv_stats) / sizeof(u64) + \ + offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) + +static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { + "rx_packets", + "tx_packets", + "rx_bytes", + "tx_bytes", + "rx_errors", + "tx_errors", + "rx_dropped", + "tx_dropped", + "multicast", + "collisions", + + "rx_length_errors", + "rx_over_errors", + "rx_crc_errors", + "rx_frame_errors", + "rx_fifo_errors", + "rx_missed_errors", + + "tx_aborted_errors", + "tx_carrier_errors", + "tx_fifo_errors", + "tx_heartbeat_errors", + "tx_window_errors", + + "rx_compressed", + "tx_compressed", + + "netif_queue_stop", + "netif_queue_wakeup", + "tso4", + "tso6", + "tso_err", + "tcpcsum_offload", + "udpcsum_offload", + "csum_help", + "csum_help_err", + "hw_stats_updates", + "netif_rx_schedule", + "netif_rx_complete", + "netif_rx_dropped", + + "link_toggle", + "cee_up", + + "rxp_info_alloc_failed", + "mbox_intr_disabled", + "mbox_intr_enabled", + "tx_unmap_q_alloc_failed", + "rx_unmap_q_alloc_failed", + "rxbuf_alloc_failed", + + "mac_frame_64", + "mac_frame_65_127", + "mac_frame_128_255", + "mac_frame_256_511", + "mac_frame_512_1023", + "mac_frame_1024_1518", + "mac_frame_1518_1522", + "mac_rx_bytes", + "mac_rx_packets", + "mac_rx_fcs_error", + "mac_rx_multicast", + "mac_rx_broadcast", + "mac_rx_control_frames", + "mac_rx_pause", + "mac_rx_unknown_opcode", + "mac_rx_alignment_error", + "mac_rx_frame_length_error", + "mac_rx_code_error", + "mac_rx_carrier_sense_error", + "mac_rx_undersize", + "mac_rx_oversize", + "mac_rx_fragments", + "mac_rx_jabber", + "mac_rx_drop", + + "mac_tx_bytes", + "mac_tx_packets", + "mac_tx_multicast", + "mac_tx_broadcast", + "mac_tx_pause", + "mac_tx_deferral", + "mac_tx_excessive_deferral", + "mac_tx_single_collision", + "mac_tx_muliple_collision", + "mac_tx_late_collision", + "mac_tx_excessive_collision", + "mac_tx_total_collision", + "mac_tx_pause_honored", + "mac_tx_drop", + "mac_tx_jabber", + "mac_tx_fcs_error", + "mac_tx_control_frame", + "mac_tx_oversize", + "mac_tx_undersize", + "mac_tx_fragments", + + "bpc_tx_pause_0", + "bpc_tx_pause_1", + "bpc_tx_pause_2", + "bpc_tx_pause_3", + "bpc_tx_pause_4", + "bpc_tx_pause_5", + "bpc_tx_pause_6", + "bpc_tx_pause_7", + "bpc_tx_zero_pause_0", + "bpc_tx_zero_pause_1", + "bpc_tx_zero_pause_2", + "bpc_tx_zero_pause_3", + "bpc_tx_zero_pause_4", + "bpc_tx_zero_pause_5", + "bpc_tx_zero_pause_6", + "bpc_tx_zero_pause_7", + "bpc_tx_first_pause_0", + "bpc_tx_first_pause_1", + "bpc_tx_first_pause_2", + "bpc_tx_first_pause_3", + "bpc_tx_first_pause_4", + "bpc_tx_first_pause_5", + "bpc_tx_first_pause_6", + "bpc_tx_first_pause_7", + + "bpc_rx_pause_0", + "bpc_rx_pause_1", + "bpc_rx_pause_2", + "bpc_rx_pause_3", + "bpc_rx_pause_4", + "bpc_rx_pause_5", + "bpc_rx_pause_6", + "bpc_rx_pause_7", + "bpc_rx_zero_pause_0", + "bpc_rx_zero_pause_1", + "bpc_rx_zero_pause_2", + "bpc_rx_zero_pause_3", + "bpc_rx_zero_pause_4", + "bpc_rx_zero_pause_5", + "bpc_rx_zero_pause_6", + "bpc_rx_zero_pause_7", + "bpc_rx_first_pause_0", + "bpc_rx_first_pause_1", + "bpc_rx_first_pause_2", + "bpc_rx_first_pause_3", + "bpc_rx_first_pause_4", + "bpc_rx_first_pause_5", + "bpc_rx_first_pause_6", + "bpc_rx_first_pause_7", + + "rad_rx_frames", + "rad_rx_octets", + "rad_rx_vlan_frames", + "rad_rx_ucast", + "rad_rx_ucast_octets", + "rad_rx_ucast_vlan", + "rad_rx_mcast", + "rad_rx_mcast_octets", + "rad_rx_mcast_vlan", + "rad_rx_bcast", + "rad_rx_bcast_octets", + "rad_rx_bcast_vlan", + "rad_rx_drops", + + "fc_rx_ucast_octets", + "fc_rx_ucast", + "fc_rx_ucast_vlan", + "fc_rx_mcast_octets", + "fc_rx_mcast", + "fc_rx_mcast_vlan", + "fc_rx_bcast_octets", + "fc_rx_bcast", + "fc_rx_bcast_vlan", + + "fc_tx_ucast_octets", + "fc_tx_ucast", + "fc_tx_ucast_vlan", + "fc_tx_mcast_octets", + "fc_tx_mcast", + "fc_tx_mcast_vlan", + "fc_tx_bcast_octets", + "fc_tx_bcast", + "fc_tx_bcast_vlan", + "fc_tx_parity_errors", + "fc_tx_timeout", + "fc_tx_fid_parity_errors", +}; + +static int +bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + cmd->supported = SUPPORTED_10000baseT_Full; + cmd->advertising = ADVERTISED_10000baseT_Full; + cmd->autoneg = AUTONEG_DISABLE; + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + cmd->port = PORT_FIBRE; + cmd->phy_address = 0; + + if (netif_carrier_ok(netdev)) { + cmd->speed = SPEED_10000; + cmd->duplex = DUPLEX_FULL; + } else { + cmd->speed = -1; + cmd->duplex = -1; + } + cmd->transceiver = XCVR_EXTERNAL; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + + return 0; +} + +static int +bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + /* 10G full duplex setting supported only */ + if (cmd->autoneg == AUTONEG_ENABLE) + return -EOPNOTSUPP; else { + if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL)) + return 0; + } + + return -EOPNOTSUPP; +} + +static void +bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bfa_ioc_attr *ioc_attr; + unsigned long flags; + + strcpy(drvinfo->driver, BNAD_NAME); + strcpy(drvinfo->version, BNAD_VERSION); + + ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); + if (ioc_attr) { + memset(ioc_attr, 0, sizeof(*ioc_attr)); + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, + sizeof(drvinfo->fw_version) - 1); + kfree(ioc_attr); + } + + strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN); +} + +static int +get_regs(struct bnad *bnad, u32 * regs) +{ + int num = 0, i; + u32 reg_addr; + unsigned long flags; + +#define BNAD_GET_REG(addr) \ +do { \ + if (regs) \ + regs[num++] = readl(bnad->bar0 + (addr)); \ + else \ + num++; \ +} while (0) + + spin_lock_irqsave(&bnad->bna_lock, flags); + + /* DMA Block Internal Registers */ + BNAD_GET_REG(DMA_CTRL_REG0); + BNAD_GET_REG(DMA_CTRL_REG1); + BNAD_GET_REG(DMA_ERR_INT_STATUS); + BNAD_GET_REG(DMA_ERR_INT_ENABLE); + BNAD_GET_REG(DMA_ERR_INT_STATUS_SET); + + /* APP Block Register Address Offset from BAR0 */ + BNAD_GET_REG(HOSTFN0_INT_STATUS); + BNAD_GET_REG(HOSTFN0_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN0); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN0); + BNAD_GET_REG(FN0_PCIE_ERR_REG); + BNAD_GET_REG(FN0_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN0_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(HOSTFN1_INT_STATUS); + BNAD_GET_REG(HOSTFN1_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN1); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN1); + BNAD_GET_REG(FN1_PCIE_ERR_REG); + BNAD_GET_REG(FN1_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN1_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(PCIE_MISC_REG); + + BNAD_GET_REG(HOST_SEM0_REG); + BNAD_GET_REG(HOST_SEM1_REG); + BNAD_GET_REG(HOST_SEM2_REG); + BNAD_GET_REG(HOST_SEM3_REG); + BNAD_GET_REG(HOST_SEM0_INFO_REG); + BNAD_GET_REG(HOST_SEM1_INFO_REG); + BNAD_GET_REG(HOST_SEM2_INFO_REG); + BNAD_GET_REG(HOST_SEM3_INFO_REG); + + BNAD_GET_REG(TEMPSENSE_CNTL_REG); + BNAD_GET_REG(TEMPSENSE_STAT_REG); + + BNAD_GET_REG(APP_LOCAL_ERR_STAT); + BNAD_GET_REG(APP_LOCAL_ERR_MSK); + + BNAD_GET_REG(PCIE_LNK_ERR_STAT); + BNAD_GET_REG(PCIE_LNK_ERR_MSK); + + BNAD_GET_REG(FCOE_FIP_ETH_TYPE); + BNAD_GET_REG(RESV_ETH_TYPE); + + BNAD_GET_REG(HOSTFN2_INT_STATUS); + BNAD_GET_REG(HOSTFN2_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN2); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN2); + BNAD_GET_REG(FN2_PCIE_ERR_REG); + BNAD_GET_REG(FN2_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN2_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(HOSTFN3_INT_STATUS); + BNAD_GET_REG(HOSTFN3_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN3); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN3); + BNAD_GET_REG(FN3_PCIE_ERR_REG); + BNAD_GET_REG(FN3_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN3_ERR_TYPE_MSK_STATUS_REG); + + /* Host Command Status Registers */ + reg_addr = HOST_CMDSTS0_CLR_REG; + for (i = 0; i < 16; i++) { + BNAD_GET_REG(reg_addr); + BNAD_GET_REG(reg_addr + 4); + BNAD_GET_REG(reg_addr + 8); + reg_addr += 0x10; + } + + /* Function ID register */ + BNAD_GET_REG(FNC_ID_REG); + + /* Function personality register */ + BNAD_GET_REG(FNC_PERS_REG); + + /* Operation mode register */ + BNAD_GET_REG(OP_MODE); + + /* LPU0 Registers */ + BNAD_GET_REG(LPU0_MBOX_CTL_REG); + BNAD_GET_REG(LPU0_MBOX_CMD_REG); + BNAD_GET_REG(LPU0_MBOX_LINK_0REG); + BNAD_GET_REG(LPU1_MBOX_LINK_0REG); + BNAD_GET_REG(LPU0_MBOX_STATUS_0REG); + BNAD_GET_REG(LPU1_MBOX_STATUS_0REG); + BNAD_GET_REG(LPU0_ERR_STATUS_REG); + BNAD_GET_REG(LPU0_ERR_SET_REG); + + /* LPU1 Registers */ + BNAD_GET_REG(LPU1_MBOX_CTL_REG); + BNAD_GET_REG(LPU1_MBOX_CMD_REG); + BNAD_GET_REG(LPU0_MBOX_LINK_1REG); + BNAD_GET_REG(LPU1_MBOX_LINK_1REG); + BNAD_GET_REG(LPU0_MBOX_STATUS_1REG); + BNAD_GET_REG(LPU1_MBOX_STATUS_1REG); + BNAD_GET_REG(LPU1_ERR_STATUS_REG); + BNAD_GET_REG(LPU1_ERR_SET_REG); + + /* PSS Registers */ + BNAD_GET_REG(PSS_CTL_REG); + BNAD_GET_REG(PSS_ERR_STATUS_REG); + BNAD_GET_REG(ERR_STATUS_SET); + BNAD_GET_REG(PSS_RAM_ERR_STATUS_REG); + + /* Catapult CPQ Registers */ + BNAD_GET_REG(HOSTFN0_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN0_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN0_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN0_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN0_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN0_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN0_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN0_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN1_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN1_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN1_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN1_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN1_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN1_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN2_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN2_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN2_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN2_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN2_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN2_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN2_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN2_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN3_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN3_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN3_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN3_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN3_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN3_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN3_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN3_MBOX1_CMD_STAT); + + /* Host Function Force Parity Error Registers */ + BNAD_GET_REG(HOSTFN0_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN1_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN2_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN3_LPU_FORCE_PERR); + + /* LL Port[0|1] Halt Mask Registers */ + BNAD_GET_REG(LL_HALT_MSK_P0); + BNAD_GET_REG(LL_HALT_MSK_P1); + + /* LL Port[0|1] Error Mask Registers */ + BNAD_GET_REG(LL_ERR_MSK_P0); + BNAD_GET_REG(LL_ERR_MSK_P1); + + /* EMC FLI Registers */ + BNAD_GET_REG(FLI_CMD_REG); + BNAD_GET_REG(FLI_ADDR_REG); + BNAD_GET_REG(FLI_CTL_REG); + BNAD_GET_REG(FLI_WRDATA_REG); + BNAD_GET_REG(FLI_RDDATA_REG); + BNAD_GET_REG(FLI_DEV_STATUS_REG); + BNAD_GET_REG(FLI_SIG_WD_REG); + + BNAD_GET_REG(FLI_DEV_VENDOR_REG); + BNAD_GET_REG(FLI_ERR_STATUS_REG); + + /* RxAdm 0 Registers */ + BNAD_GET_REG(RAD0_CTL_REG); + BNAD_GET_REG(RAD0_PE_PARM_REG); + BNAD_GET_REG(RAD0_BCN_REG); + BNAD_GET_REG(RAD0_DEFAULT_REG); + BNAD_GET_REG(RAD0_PROMISC_REG); + BNAD_GET_REG(RAD0_BCNQ_REG); + BNAD_GET_REG(RAD0_DEFAULTQ_REG); + + BNAD_GET_REG(RAD0_ERR_STS); + BNAD_GET_REG(RAD0_SET_ERR_STS); + BNAD_GET_REG(RAD0_ERR_INT_EN); + BNAD_GET_REG(RAD0_FIRST_ERR); + BNAD_GET_REG(RAD0_FORCE_ERR); + + BNAD_GET_REG(RAD0_MAC_MAN_1H); + BNAD_GET_REG(RAD0_MAC_MAN_1L); + BNAD_GET_REG(RAD0_MAC_MAN_2H); + BNAD_GET_REG(RAD0_MAC_MAN_2L); + BNAD_GET_REG(RAD0_MAC_MAN_3H); + BNAD_GET_REG(RAD0_MAC_MAN_3L); + BNAD_GET_REG(RAD0_MAC_MAN_4H); + BNAD_GET_REG(RAD0_MAC_MAN_4L); + + BNAD_GET_REG(RAD0_LAST4_IP); + + /* RxAdm 1 Registers */ + BNAD_GET_REG(RAD1_CTL_REG); + BNAD_GET_REG(RAD1_PE_PARM_REG); + BNAD_GET_REG(RAD1_BCN_REG); + BNAD_GET_REG(RAD1_DEFAULT_REG); + BNAD_GET_REG(RAD1_PROMISC_REG); + BNAD_GET_REG(RAD1_BCNQ_REG); + BNAD_GET_REG(RAD1_DEFAULTQ_REG); + + BNAD_GET_REG(RAD1_ERR_STS); + BNAD_GET_REG(RAD1_SET_ERR_STS); + BNAD_GET_REG(RAD1_ERR_INT_EN); + + /* TxA0 Registers */ + BNAD_GET_REG(TXA0_CTRL_REG); + /* TxA0 TSO Sequence # Registers (RO) */ + for (i = 0; i < 8; i++) { + BNAD_GET_REG(TXA0_TSO_TCP_SEQ_REG(i)); + BNAD_GET_REG(TXA0_TSO_IP_INFO_REG(i)); + } + + /* TxA1 Registers */ + BNAD_GET_REG(TXA1_CTRL_REG); + /* TxA1 TSO Sequence # Registers (RO) */ + for (i = 0; i < 8; i++) { + BNAD_GET_REG(TXA1_TSO_TCP_SEQ_REG(i)); + BNAD_GET_REG(TXA1_TSO_IP_INFO_REG(i)); + } + + /* RxA Registers */ + BNAD_GET_REG(RXA0_CTL_REG); + BNAD_GET_REG(RXA1_CTL_REG); + + /* PLB0 Registers */ + BNAD_GET_REG(PLB0_ECM_TIMER_REG); + BNAD_GET_REG(PLB0_RL_CTL); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB0_RL_MAX_BC(i)); + BNAD_GET_REG(PLB0_RL_TU_PRIO); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB0_RL_BYTE_CNT(i)); + BNAD_GET_REG(PLB0_RL_MIN_REG); + BNAD_GET_REG(PLB0_RL_MAX_REG); + BNAD_GET_REG(PLB0_EMS_ADD_REG); + + /* PLB1 Registers */ + BNAD_GET_REG(PLB1_ECM_TIMER_REG); + BNAD_GET_REG(PLB1_RL_CTL); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB1_RL_MAX_BC(i)); + BNAD_GET_REG(PLB1_RL_TU_PRIO); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB1_RL_BYTE_CNT(i)); + BNAD_GET_REG(PLB1_RL_MIN_REG); + BNAD_GET_REG(PLB1_RL_MAX_REG); + BNAD_GET_REG(PLB1_EMS_ADD_REG); + + /* HQM Control Register */ + BNAD_GET_REG(HQM0_CTL_REG); + BNAD_GET_REG(HQM0_RXQ_STOP_SEM); + BNAD_GET_REG(HQM0_TXQ_STOP_SEM); + BNAD_GET_REG(HQM1_CTL_REG); + BNAD_GET_REG(HQM1_RXQ_STOP_SEM); + BNAD_GET_REG(HQM1_TXQ_STOP_SEM); + + /* LUT Registers */ + BNAD_GET_REG(LUT0_ERR_STS); + BNAD_GET_REG(LUT0_SET_ERR_STS); + BNAD_GET_REG(LUT1_ERR_STS); + BNAD_GET_REG(LUT1_SET_ERR_STS); + + /* TRC Registers */ + BNAD_GET_REG(TRC_CTL_REG); + BNAD_GET_REG(TRC_MODS_REG); + BNAD_GET_REG(TRC_TRGC_REG); + BNAD_GET_REG(TRC_CNT1_REG); + BNAD_GET_REG(TRC_CNT2_REG); + BNAD_GET_REG(TRC_NXTS_REG); + BNAD_GET_REG(TRC_DIRR_REG); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_TRGM_REG(i)); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_NXTM_REG(i)); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_STRM_REG(i)); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); +#undef BNAD_GET_REG + return num; +} +static int +bnad_get_regs_len(struct net_device *netdev) +{ + int ret = get_regs(netdev_priv(netdev), NULL) * sizeof(u32); + return ret; +} + +static void +bnad_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) +{ + memset(buf, 0, bnad_get_regs_len(netdev)); + get_regs(netdev_priv(netdev), buf); +} + +static void +bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo) +{ + wolinfo->supported = 0; + wolinfo->wolopts = 0; +} + +static int +bnad_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + /* Lock rqd. to access bnad->bna_lock */ + spin_lock_irqsave(&bnad->bna_lock, flags); + coalesce->use_adaptive_rx_coalesce = + (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) ? true : false; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + coalesce->rx_coalesce_usecs = bnad->rx_coalescing_timeo * + BFI_COALESCING_TIMER_UNIT; + coalesce->tx_coalesce_usecs = bnad->tx_coalescing_timeo * + BFI_COALESCING_TIMER_UNIT; + coalesce->tx_max_coalesced_frames = BFI_TX_INTERPKT_COUNT; + + return 0; +} + +static int +bnad_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + int dim_timer_del = 0; + + if (coalesce->rx_coalesce_usecs == 0 || + coalesce->rx_coalesce_usecs > + BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT) + return -EINVAL; + + if (coalesce->tx_coalesce_usecs == 0 || + coalesce->tx_coalesce_usecs > + BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + /* + * Do not need to store rx_coalesce_usecs here + * Every time DIM is disabled, we can get it from the + * stack. + */ + spin_lock_irqsave(&bnad->bna_lock, flags); + if (coalesce->use_adaptive_rx_coalesce) { + if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) { + bnad->cfg_flags |= BNAD_CF_DIM_ENABLED; + bnad_dim_timer_start(bnad); + } + } else { + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) { + bnad->cfg_flags &= ~BNAD_CF_DIM_ENABLED; + dim_timer_del = bnad_dim_timer_running(bnad); + if (dim_timer_del) { + clear_bit(BNAD_RF_DIM_TIMER_RUNNING, + &bnad->run_flags); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + del_timer_sync(&bnad->dim_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + } + bnad_rx_coalescing_timeo_set(bnad); + } + } + if (bnad->tx_coalescing_timeo != coalesce->tx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT) { + bnad->tx_coalescing_timeo = coalesce->tx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT; + bnad_tx_coalescing_timeo_set(bnad); + } + + if (bnad->rx_coalescing_timeo != coalesce->rx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT) { + bnad->rx_coalescing_timeo = coalesce->rx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT; + + if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) + bnad_rx_coalescing_timeo_set(bnad); + + } + + /* Add Tx Inter-pkt DMA count? */ + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static void +bnad_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + struct bnad *bnad = netdev_priv(netdev); + + ringparam->rx_max_pending = BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq; + ringparam->rx_mini_max_pending = 0; + ringparam->rx_jumbo_max_pending = 0; + ringparam->tx_max_pending = BNAD_MAX_Q_DEPTH; + + ringparam->rx_pending = bnad->rxq_depth; + ringparam->rx_mini_max_pending = 0; + ringparam->rx_jumbo_max_pending = 0; + ringparam->tx_pending = bnad->txq_depth; +} + +static int +bnad_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + int i, current_err, err = 0; + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (ringparam->rx_pending == bnad->rxq_depth && + ringparam->tx_pending == bnad->txq_depth) { + mutex_unlock(&bnad->conf_mutex); + return 0; + } + + if (ringparam->rx_pending < BNAD_MIN_Q_DEPTH || + ringparam->rx_pending > BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq || + !BNA_POWER_OF_2(ringparam->rx_pending)) { + mutex_unlock(&bnad->conf_mutex); + return -EINVAL; + } + if (ringparam->tx_pending < BNAD_MIN_Q_DEPTH || + ringparam->tx_pending > BNAD_MAX_Q_DEPTH || + !BNA_POWER_OF_2(ringparam->tx_pending)) { + mutex_unlock(&bnad->conf_mutex); + return -EINVAL; + } + + if (ringparam->rx_pending != bnad->rxq_depth) { + bnad->rxq_depth = ringparam->rx_pending; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + bnad_cleanup_rx(bnad, i); + current_err = bnad_setup_rx(bnad, i); + if (current_err && !err) + err = current_err; + } + } + if (ringparam->tx_pending != bnad->txq_depth) { + bnad->txq_depth = ringparam->tx_pending; + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + bnad_cleanup_tx(bnad, i); + current_err = bnad_setup_tx(bnad, i); + if (current_err && !err) + err = current_err; + } + } + + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static void +bnad_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pauseparam) +{ + struct bnad *bnad = netdev_priv(netdev); + + pauseparam->autoneg = 0; + pauseparam->rx_pause = bnad->bna.port.pause_config.rx_pause; + pauseparam->tx_pause = bnad->bna.port.pause_config.tx_pause; +} + +static int +bnad_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pauseparam) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bna_pause_config pause_config; + unsigned long flags; + + if (pauseparam->autoneg == AUTONEG_ENABLE) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + if (pauseparam->rx_pause != bnad->bna.port.pause_config.rx_pause || + pauseparam->tx_pause != bnad->bna.port.pause_config.tx_pause) { + pause_config.rx_pause = pauseparam->rx_pause; + pause_config.tx_pause = pauseparam->tx_pause; + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_pause_config(&bnad->bna.port, &pause_config, NULL); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static u32 +bnad_get_rx_csum(struct net_device *netdev) +{ + u32 rx_csum; + struct bnad *bnad = netdev_priv(netdev); + + rx_csum = bnad->rx_csum; + return rx_csum; +} + +static int +bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad->rx_csum = rx_csum; + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static int +bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (tx_csum) { + netdev->features |= NETIF_F_IP_CSUM; + netdev->features |= NETIF_F_IPV6_CSUM; + } else { + netdev->features &= ~NETIF_F_IP_CSUM; + netdev->features &= ~NETIF_F_IPV6_CSUM; + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static int +bnad_set_tso(struct net_device *netdev, u32 tso) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (tso) { + netdev->features |= NETIF_F_TSO; + netdev->features |= NETIF_F_TSO6; + } else { + netdev->features &= ~NETIF_F_TSO; + netdev->features &= ~NETIF_F_TSO6; + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static void +bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, q_num; + u64 bmap; + + mutex_lock(&bnad->conf_mutex); + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) { + BUG_ON(!(strlen(bnad_net_stats_strings[i]) < + ETH_GSTRING_LEN)); + memcpy(string, bnad_net_stats_strings[i], + ETH_GSTRING_LEN); + string += ETH_GSTRING_LEN; + } + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) { + sprintf(string, "txf%d_ucast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_ucast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_ucast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_errors", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_filter_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_filter_mac_sa", i); + string += ETH_GSTRING_LEN; + } + bmap >>= 1; + } + + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + sprintf(string, "rxf%d_ucast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_ucast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_ucast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_frame_drops", i); + string += ETH_GSTRING_LEN; + } + bmap >>= 1; + } + + q_num = 0; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + sprintf(string, "cq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "cq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "cq%d_hw_producer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + + q_num = 0; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + sprintf(string, "rxq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_packets_with_error", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_allocbuf_failed", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + q_num++; + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + sprintf(string, "rxq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, + "rxq%d_packets_with_error", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_allocbuf_failed", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_producer_index", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_consumer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + } + + q_num = 0; + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + for (j = 0; j < bnad->num_txq_per_tx; j++) { + sprintf(string, "txq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_hw_consumer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + + break; + + default: + break; + } + + mutex_unlock(&bnad->conf_mutex); +} + +static int +bnad_get_stats_count_locked(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, count, rxf_active_num = 0, txf_active_num = 0; + u64 bmap; + + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) + txf_active_num++; + bmap >>= 1; + } + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) + rxf_active_num++; + bmap >>= 1; + } + count = BNAD_ETHTOOL_STATS_NUM + + txf_active_num * BNAD_NUM_TXF_COUNTERS + + rxf_active_num * BNAD_NUM_RXF_COUNTERS; + + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + count += bnad->num_rxp_per_rx * BNAD_NUM_CQ_COUNTERS; + count += bnad->num_rxp_per_rx * BNAD_NUM_RXQ_COUNTERS; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1]->rxq) + count += BNAD_NUM_RXQ_COUNTERS; + } + + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + count += bnad->num_txq_per_tx * BNAD_NUM_TXQ_COUNTERS; + } + return count; +} + +static int +bnad_per_q_stats_fill(struct bnad *bnad, u64 *buf, int bi) +{ + int i, j; + struct bna_rcb *rcb = NULL; + struct bna_tcb *tcb = NULL; + + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0]->rxq) { + buf[bi++] = bnad->rx_info[i].rx_ctrl[j]. + ccb->producer_index; + buf[bi++] = 0; /* ccb->consumer_index */ + buf[bi++] = *(bnad->rx_info[i].rx_ctrl[j]. + ccb->hw_producer_index); + } + } + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb) { + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[0]->rxq) { + rcb = bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[0]; + buf[bi++] = rcb->rxq->rx_packets; + buf[bi++] = rcb->rxq->rx_bytes; + buf[bi++] = rcb->rxq-> + rx_packets_with_error; + buf[bi++] = rcb->rxq-> + rxbuf_alloc_failed; + buf[bi++] = rcb->producer_index; + buf[bi++] = rcb->consumer_index; + } + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + rcb = bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]; + buf[bi++] = rcb->rxq->rx_packets; + buf[bi++] = rcb->rxq->rx_bytes; + buf[bi++] = rcb->rxq-> + rx_packets_with_error; + buf[bi++] = rcb->rxq-> + rxbuf_alloc_failed; + buf[bi++] = rcb->producer_index; + buf[bi++] = rcb->consumer_index; + } + } + } + + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + for (j = 0; j < bnad->num_txq_per_tx; j++) + if (bnad->tx_info[i].tcb[j] && + bnad->tx_info[i].tcb[j]->txq) { + tcb = bnad->tx_info[i].tcb[j]; + buf[bi++] = tcb->txq->tx_packets; + buf[bi++] = tcb->txq->tx_bytes; + buf[bi++] = tcb->producer_index; + buf[bi++] = tcb->consumer_index; + buf[bi++] = *(tcb->hw_consumer_index); + } + } + + return bi; +} + +static void +bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, + u64 *buf) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, bi; + unsigned long *net_stats, flags; + u64 *stats64; + u64 bmap; + + mutex_lock(&bnad->conf_mutex); + if (bnad_get_stats_count_locked(netdev) != stats->n_stats) { + mutex_unlock(&bnad->conf_mutex); + return; + } + + /* + * Used bna_lock to sync reads from bna_stats, which is written + * under the same lock + */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bi = 0; + memset(buf, 0, stats->n_stats * sizeof(u64)); + memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); + + bnad_netdev_qstats_fill(bnad); + bnad_netdev_hwstats_fill(bnad); + + /* Fill net_stats into ethtool buffers */ + net_stats = (unsigned long *)&bnad->net_stats; + for (i = 0; i < sizeof(struct net_device_stats) / sizeof(unsigned long); + i++) + buf[bi++] = net_stats[i]; + + /* Fill driver stats into ethtool buffers */ + stats64 = (u64 *)&bnad->stats.drv_stats; + for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++) + buf[bi++] = stats64[i]; + + /* Fill hardware stats excluding the rxf/txf into ethtool bufs */ + stats64 = (u64 *) bnad->stats.bna_stats->hw_stats; + for (i = 0; + i < offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64); + i++) + buf[bi++] = stats64[i]; + + /* Fill txf stats into ethtool buffers */ + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) { + stats64 = (u64 *)&bnad->stats.bna_stats-> + hw_stats->txf_stats[i]; + for (j = 0; j < sizeof(struct bfi_ll_stats_txf) / + sizeof(u64); j++) + buf[bi++] = stats64[j]; + } + bmap >>= 1; + } + + /* Fill rxf stats into ethtool buffers */ + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + stats64 = (u64 *)&bnad->stats.bna_stats-> + hw_stats->rxf_stats[i]; + for (j = 0; j < sizeof(struct bfi_ll_stats_rxf) / + sizeof(u64); j++) + buf[bi++] = stats64[j]; + } + bmap >>= 1; + } + + /* Fill per Q stats into ethtool buffers */ + bi = bnad_per_q_stats_fill(bnad, buf, bi); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +static int +bnad_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return bnad_get_stats_count_locked(netdev); + default: + return -EOPNOTSUPP; + } +} + +static struct ethtool_ops bnad_ethtool_ops = { + .get_settings = bnad_get_settings, + .set_settings = bnad_set_settings, + .get_drvinfo = bnad_get_drvinfo, + .get_regs_len = bnad_get_regs_len, + .get_regs = bnad_get_regs, + .get_wol = bnad_get_wol, + .get_link = ethtool_op_get_link, + .get_coalesce = bnad_get_coalesce, + .set_coalesce = bnad_set_coalesce, + .get_ringparam = bnad_get_ringparam, + .set_ringparam = bnad_set_ringparam, + .get_pauseparam = bnad_get_pauseparam, + .set_pauseparam = bnad_set_pauseparam, + .get_rx_csum = bnad_get_rx_csum, + .set_rx_csum = bnad_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = bnad_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = bnad_set_tso, + .get_flags = ethtool_op_get_flags, + .set_flags = ethtool_op_set_flags, + .get_strings = bnad_get_strings, + .get_ethtool_stats = bnad_get_ethtool_stats, + .get_sset_count = bnad_get_sset_count +}; + +void +bnad_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops); +} diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h new file mode 100644 index 000000000000..bbd39dc65972 --- /dev/null +++ b/drivers/net/bna/cna.h @@ -0,0 +1,81 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2006-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __CNA_H__ +#define __CNA_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define bfa_sm_fault(__mod, __event) do { \ + pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \ + __event); \ +} while (0) + +extern char bfa_version[]; + +#define CNA_FW_FILE_CT "ctfw_cna.bin" +#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */ + +#pragma pack(1) + +#define MAC_ADDRLEN (6) +typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t; + +#pragma pack() + +#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next)) +#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next) +#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev) + +/* + * bfa_q_qe_init - to initialize a queue element + */ +#define bfa_q_qe_init(_qe) { \ + bfa_q_next(_qe) = (struct list_head *) NULL; \ + bfa_q_prev(_qe) = (struct list_head *) NULL; \ +} + +/* + * bfa_q_deq - dequeue an element from head of the queue + */ +#define bfa_q_deq(_q, _qe) { \ + if (!list_empty(_q)) { \ + (*((struct list_head **) (_qe))) = bfa_q_next(_q); \ + bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \ + (struct list_head *) (_q); \ + bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \ + bfa_q_qe_init(*((struct list_head **) _qe)); \ + } else { \ + *((struct list_head **) (_qe)) = (struct list_head *) NULL; \ + } \ +} + +#endif /* __CNA_H__ */ diff --git a/drivers/net/bna/cna_fwimg.c b/drivers/net/bna/cna_fwimg.c new file mode 100644 index 000000000000..0bd1d3790a27 --- /dev/null +++ b/drivers/net/bna/cna_fwimg.c @@ -0,0 +1,64 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include +#include "cna.h" + +const struct firmware *bfi_fw; +static u32 *bfi_image_ct_cna; +static u32 bfi_image_ct_cna_size; + +u32 * +cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, + u32 *bfi_image_size, char *fw_name) +{ + const struct firmware *fw; + + if (request_firmware(&fw, fw_name, &pdev->dev)) { + pr_alert("Can't locate firmware %s\n", fw_name); + goto error; + } + + *bfi_image = (u32 *)fw->data; + *bfi_image_size = fw->size/sizeof(u32); + bfi_fw = fw; + + return *bfi_image; +error: + return NULL; +} + +u32 * +cna_get_firmware_buf(struct pci_dev *pdev) +{ + if (bfi_image_ct_cna_size == 0) + cna_read_firmware(pdev, &bfi_image_ct_cna, + &bfi_image_ct_cna_size, CNA_FW_FILE_CT); + return bfi_image_ct_cna; +} + +u32 * +bfa_cb_image_get_chunk(int type, u32 off) +{ + return (u32 *)(bfi_image_ct_cna + off); +} + +u32 +bfa_cb_image_get_size(int type) +{ + return bfi_image_ct_cna_size; +} diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f6a3b2d36cad..1f730de0df06 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2189,6 +2189,9 @@ #define PCI_VENDOR_ID_ARIMA 0x161f #define PCI_VENDOR_ID_BROCADE 0x1657 +#define PCI_DEVICE_ID_BROCADE_CT 0x0014 +#define PCI_DEVICE_ID_BROCADE_FC_8G1P 0x0017 +#define PCI_DEVICE_ID_BROCADE_CT_FC 0x0021 #define PCI_VENDOR_ID_SIBYTE 0x166d #define PCI_DEVICE_ID_BCM1250_PCI 0x0001 -- cgit v1.2.3 From f04b4dd2b1f533cef0507e0410ffc6732d21a272 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 Aug 2010 20:34:51 -0700 Subject: bna: Delete get_flags and set_flags ethtool methods. This driver doesn't support LRO, NTUPLE, or the RXHASH features. So it should not set these ethtool operations. This also fixes the warning: drivers/net/bna/bnad_ethtool.c:1272: warning: initialization from incompatible pointer type Signed-off-by: David S. Miller --- drivers/net/bna/bnad_ethtool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index e982785b6b25..7e630f5e8e03 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -1268,8 +1268,6 @@ static struct ethtool_ops bnad_ethtool_ops = { .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, .set_tso = bnad_set_tso, - .get_flags = ethtool_op_get_flags, - .set_flags = ethtool_op_set_flags, .get_strings = bnad_get_strings, .get_ethtool_stats = bnad_get_ethtool_stats, .get_sset_count = bnad_get_sset_count -- cgit v1.2.3 From e46dab4d4be87769b09404135bc34f89e2e155d8 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 23 Aug 2010 17:20:58 +0000 Subject: cxgb4: handle Rx/Tx queue ranges not starting at 0 Currently the driver assumes that queue IDs start at 0 but that's true only for function 0. To support operation on other functions get the start of the queue ranges from FW and offset accordingly. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 2 ++ drivers/net/cxgb4/cxgb4_main.c | 24 +++++++++++++++++++----- drivers/net/cxgb4/sge.c | 15 +++++++++------ drivers/net/cxgb4/t4fw_api.h | 5 +++++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 6e562c0dad7d..3ece9f5069fa 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -463,6 +463,8 @@ struct sge { u8 counter_val[SGE_NCOUNTERS]; unsigned int starve_thres; u8 idma_state[2]; + unsigned int egr_start; + unsigned int ingr_start; void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */ struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */ DECLARE_BITMAP(starving_fl, MAX_EGRQ); diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index c327527fbbc8..6e08e2d8eb3e 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -423,10 +423,11 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, if (likely(opcode == CPL_SGE_EGR_UPDATE)) { const struct cpl_sge_egr_update *p = (void *)rsp; unsigned int qid = EGR_QID(ntohl(p->opcode_qid)); - struct sge_txq *txq = q->adap->sge.egr_map[qid]; + struct sge_txq *txq; + txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start]; txq->restarts++; - if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) { + if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) { struct sge_eth_txq *eq; eq = container_of(txq, struct sge_eth_txq, q); @@ -657,6 +658,15 @@ static int setup_rss(struct adapter *adap) return 0; } +/* + * Return the channel of the ingress queue with the given qid. + */ +static unsigned int rxq_to_chan(const struct sge *p, unsigned int qid) +{ + qid -= p->ingr_start; + return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan; +} + /* * Wait until all NAPI handlers are descheduled. */ @@ -2304,7 +2314,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid, req->peer_port = htons(0); req->local_ip = sip; req->peer_ip = htonl(0); - chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; + chan = rxq_to_chan(&adap->sge, queue); req->opt0 = cpu_to_be64(TX_CHAN(chan)); req->opt1 = cpu_to_be64(CONN_POLICY_ASK | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); @@ -2346,7 +2356,7 @@ int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8); req->peer_ip_hi = cpu_to_be64(0); req->peer_ip_lo = cpu_to_be64(0); - chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; + chan = rxq_to_chan(&adap->sge, queue); req->opt0 = cpu_to_be64(TX_CHAN(chan)); req->opt1 = cpu_to_be64(CONN_POLICY_ASK | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); @@ -3061,12 +3071,16 @@ static int adap_init0(struct adapter *adap) params[2] = FW_PARAM_PFVF(L2T_END); params[3] = FW_PARAM_PFVF(FILTER_START); params[4] = FW_PARAM_PFVF(FILTER_END); - ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val); + params[5] = FW_PARAM_PFVF(IQFLINT_START); + params[6] = FW_PARAM_PFVF(EQ_START); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val); if (ret < 0) goto bye; port_vec = val[0]; adap->tids.ftid_base = val[3]; adap->tids.nftids = val[4] - val[3] + 1; + adap->sge.ingr_start = val[5]; + adap->sge.egr_start = val[6]; if (c.ofldcaps) { /* query offload-related parameters */ diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index bf38cfc57565..44c2e6c9f073 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -557,7 +557,8 @@ out: cred = q->avail - cred; if (unlikely(fl_starving(q))) { smp_wmb(); - set_bit(q->cntxt_id, adap->sge.starving_fl); + set_bit(q->cntxt_id - adap->sge.egr_start, + adap->sge.starving_fl); } return cred; @@ -1213,7 +1214,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q) { q->mapping_err++; q->q.stops++; - set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr); + set_bit(q->q.cntxt_id - q->adap->sge.egr_start, + q->adap->sge.txq_maperr); } /** @@ -1835,6 +1837,7 @@ static unsigned int process_intrq(struct adapter *adap) if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { unsigned int qid = ntohl(rc->pldbuflen_qid); + qid -= adap->sge.ingr_start; napi_schedule(&adap->sge.ingr_map[qid]->napi); } @@ -2050,14 +2053,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, /* set offset to -1 to distinguish ingress queues without FL */ iq->offset = fl ? 0 : -1; - adap->sge.ingr_map[iq->cntxt_id] = iq; + adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq; if (fl) { fl->cntxt_id = ntohs(c.fl0id); fl->avail = fl->pend_cred = 0; fl->pidx = fl->cidx = 0; fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; - adap->sge.egr_map[fl->cntxt_id] = fl; + adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl; refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); } return 0; @@ -2087,7 +2090,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) q->stops = q->restarts = 0; q->stat = (void *)&q->desc[q->size]; q->cntxt_id = id; - adap->sge.egr_map[id] = q; + adap->sge.egr_map[id - adap->sge.egr_start] = q; } int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, @@ -2259,7 +2262,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, { unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; - adap->sge.ingr_map[rq->cntxt_id] = NULL; + adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL; t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id, 0xffff); dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h index 0969f2fbc1b0..940584a8a640 100644 --- a/drivers/net/cxgb4/t4fw_api.h +++ b/drivers/net/cxgb4/t4fw_api.h @@ -487,6 +487,11 @@ enum fw_params_param_pfvf { FW_PARAMS_PARAM_PFVF_CPMASK = 0x25, FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26, FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27, + FW_PARAMS_PARAM_PFVF_CONM_MAP = 0x28, + FW_PARAMS_PARAM_PFVF_IQFLINT_START = 0x29, + FW_PARAMS_PARAM_PFVF_IQFLINT_END = 0x2A, + FW_PARAMS_PARAM_PFVF_EQ_START = 0x2B, + FW_PARAMS_PARAM_PFVF_EQ_END = 0x2C, }; /* -- cgit v1.2.3 From 1478b3ee931e83c7a94f61376e962574b28d23d6 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 23 Aug 2010 17:20:59 +0000 Subject: cxgb4: support eeprom read/write on functions other than 0 Extend the address translation for eeprom read/write (code used by ethtool -[eE]) to functions other than 0. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 40 +++++++++++++++++++++++++++++++--------- drivers/net/cxgb4/t4_hw.h | 1 + 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 6e08e2d8eb3e..7552d8df55ed 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1681,27 +1681,41 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) return 0; } -/* - * Translate a physical EEPROM address to virtual. The first 1K is accessed - * through virtual addresses starting at 31K, the rest is accessed through - * virtual addresses starting at 0. This mapping is correct only for PF0. +/** + * eeprom_ptov - translate a physical EEPROM address to virtual + * @phys_addr: the physical EEPROM address + * @fn: the PCI function number + * @sz: size of function-specific area + * + * Translate a physical EEPROM address to virtual. The first 1K is + * accessed through virtual addresses starting at 31K, the rest is + * accessed through virtual addresses starting at 0. + * + * The mapping is as follows: + * [0..1K) -> [31K..32K) + * [1K..1K+A) -> [31K-A..31K) + * [1K+A..ES) -> [0..ES-A-1K) + * + * where A = @fn * @sz, and ES = EEPROM size. */ -static int eeprom_ptov(unsigned int phys_addr) +static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) { + fn *= sz; if (phys_addr < 1024) return phys_addr + (31 << 10); + if (phys_addr < 1024 + fn) + return 31744 - fn + phys_addr - 1024; if (phys_addr < EEPROMSIZE) - return phys_addr - 1024; + return phys_addr - 1024 - fn; return -EINVAL; } /* * The next two routines implement eeprom read/write from physical addresses. - * The physical->virtual translation is correct only for PF0. */ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) { - int vaddr = eeprom_ptov(phys_addr); + int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); if (vaddr >= 0) vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); @@ -1710,7 +1724,7 @@ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) { - int vaddr = eeprom_ptov(phys_addr); + int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); if (vaddr >= 0) vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); @@ -1753,6 +1767,14 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, aligned_offset = eeprom->offset & ~3; aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; + if (adapter->fn > 0) { + u32 start = 1024 + adapter->fn * EEPROMPFSIZE; + + if (aligned_offset < start || + aligned_offset + aligned_len > start + EEPROMPFSIZE) + return -EPERM; + } + if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { /* * RMW possibly needed for first or last words. diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h index 10a055565776..c26b455f37de 100644 --- a/drivers/net/cxgb4/t4_hw.h +++ b/drivers/net/cxgb4/t4_hw.h @@ -42,6 +42,7 @@ enum { MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ EEPROMSIZE = 17408, /* Serial EEPROM physical size */ EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */ + EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */ RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */ TCB_SIZE = 128, /* TCB size */ NMTUS = 16, /* size of MTU table */ -- cgit v1.2.3 From 1707aec9ac884de9e3358a8e564bbce91e4346f7 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 23 Aug 2010 17:21:00 +0000 Subject: cxgb4: fix setting of the function number in transmit descriptors Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/sge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 44c2e6c9f073..6ddb3bb0ce67 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -975,7 +975,7 @@ out_free: dev_kfree_skb(skb); } cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | - TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0)); + TXPKT_INTF(pi->tx_chan) | TXPKT_PF(adap->fn)); cpl->pack = htons(0); cpl->len = htons(skb->len); cpl->ctrl1 = cpu_to_be64(cntrl); -- cgit v1.2.3 From ccea790ef033cc890ca4b416a783e9f9dffe556e Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 23 Aug 2010 17:21:01 +0000 Subject: cxgb4: update PCI ids Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 7552d8df55ed..75b9401fd484 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -175,16 +175,26 @@ enum { static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { CH_DEVICE(0xa000, 0), /* PE10K */ - CH_DEVICE(0x4001, 0), - CH_DEVICE(0x4002, 0), - CH_DEVICE(0x4003, 0), - CH_DEVICE(0x4004, 0), - CH_DEVICE(0x4005, 0), - CH_DEVICE(0x4006, 0), - CH_DEVICE(0x4007, 0), - CH_DEVICE(0x4008, 0), - CH_DEVICE(0x4009, 0), - CH_DEVICE(0x400a, 0), + CH_DEVICE(0x4001, -1), + CH_DEVICE(0x4002, -1), + CH_DEVICE(0x4003, -1), + CH_DEVICE(0x4004, -1), + CH_DEVICE(0x4005, -1), + CH_DEVICE(0x4006, -1), + CH_DEVICE(0x4007, -1), + CH_DEVICE(0x4008, -1), + CH_DEVICE(0x4009, -1), + CH_DEVICE(0x400a, -1), + CH_DEVICE(0x4401, 4), + CH_DEVICE(0x4402, 4), + CH_DEVICE(0x4403, 4), + CH_DEVICE(0x4404, 4), + CH_DEVICE(0x4405, 4), + CH_DEVICE(0x4406, 4), + CH_DEVICE(0x4407, 4), + CH_DEVICE(0x4408, 4), + CH_DEVICE(0x4409, 4), + CH_DEVICE(0x440a, 4), { 0, } }; -- cgit v1.2.3 From 7abac686026ec1af38f6e766369dbfe4007949b6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 Aug 2010 20:42:11 -0700 Subject: pkt_sched: Make act_csum depend upon INET. It uses ip_send_check() and stuff like that. Reported-by: Randy Dunlap Signed-off-by: David S. Miller --- net/sched/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 522d5a9a2825..a36270a994d7 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -520,7 +520,7 @@ config NET_ACT_SKBEDIT config NET_ACT_CSUM tristate "Checksum Updating" - depends on NET_CLS_ACT + depends on NET_CLS_ACT && INET ---help--- Say Y here to update some common checksum after some direct packet alterations. -- cgit v1.2.3 From 0eec32ff350348e635b3b8d87b989117ce045d25 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Mon, 23 Aug 2010 03:27:58 +0000 Subject: net_sched: act_csum: coding style cleanup Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/sched/act_csum.c | 77 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index be41f1cc10ee..67dc7ce9b63a 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -42,9 +42,9 @@ static u32 csum_idx_gen; static DEFINE_RWLOCK(csum_lock); static struct tcf_hashinfo csum_hash_info = { - .htab = tcf_csum_ht, - .hmask = CSUM_TAB_MASK, - .lock = &csum_lock, + .htab = tcf_csum_ht, + .hmask = CSUM_TAB_MASK, + .lock = &csum_lock, }; static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { @@ -73,7 +73,8 @@ static int tcf_csum_init(struct nlattr *nla, struct nlattr *est, pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); if (!pc) { - pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, &csum_idx_gen, &csum_hash_info); + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, + &csum_idx_gen, &csum_hash_info); if (IS_ERR(pc)) return PTR_ERR(pc); p = to_tcf_csum(pc); @@ -230,8 +231,9 @@ static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, struct udphdr *udph; u16 ul; - /* Support both UDP and UDPLITE checksum algorithms, - * Don't use udph->len to get the real length without any protocol check, + /* + * Support both UDP and UDPLITE checksum algorithms, Don't use + * udph->len to get the real length without any protocol check, * UDPLITE uses udph->len for another thing, * Use iph->tot_len, or just ipl. */ @@ -249,10 +251,8 @@ static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, if (udplite) { if (ul == 0) skb->csum = csum_partial(udph, ipl - ihl, 0); - else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl)) skb->csum = csum_partial(udph, ul, 0); - else goto ignore_obscure_skb; } else { @@ -282,8 +282,9 @@ static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, struct udphdr *udph; u16 ul; - /* Support both UDP and UDPLITE checksum algorithms, - * Don't use udph->len to get the real length without any protocol check, + /* + * Support both UDP and UDPLITE checksum algorithms, Don't use + * udph->len to get the real length without any protocol check, * UDPLITE uses udph->len for another thing, * Use ip6h->payload_len + sizeof(*ip6h) ... , or just ipl. */ @@ -340,32 +341,32 @@ static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) { case IPPROTO_ICMP: if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) - if (!tcf_csum_ipv4_icmp(skb, - iph->ihl * 4, ntohs(iph->tot_len))) + if (!tcf_csum_ipv4_icmp(skb, iph->ihl * 4, + ntohs(iph->tot_len))) goto fail; break; case IPPROTO_IGMP: if (update_flags & TCA_CSUM_UPDATE_FLAG_IGMP) - if (!tcf_csum_ipv4_igmp(skb, - iph->ihl * 4, ntohs(iph->tot_len))) + if (!tcf_csum_ipv4_igmp(skb, iph->ihl * 4, + ntohs(iph->tot_len))) goto fail; break; case IPPROTO_TCP: if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) - if (!tcf_csum_ipv4_tcp(skb, iph, - iph->ihl * 4, ntohs(iph->tot_len))) + if (!tcf_csum_ipv4_tcp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len))) goto fail; break; case IPPROTO_UDP: if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) - if (!tcf_csum_ipv4_udp(skb, iph, - iph->ihl * 4, ntohs(iph->tot_len), 0)) + if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len), 0)) goto fail; break; case IPPROTO_UDPLITE: if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) - if (!tcf_csum_ipv4_udp(skb, iph, - iph->ihl * 4, ntohs(iph->tot_len), 1)) + if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len), 1)) goto fail; break; } @@ -386,7 +387,7 @@ fail: } static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh, - unsigned int ixhl, unsigned int *pl) + unsigned int ixhl, unsigned int *pl) { int off, len, optlen; unsigned char *xh = (void *)ip6xh; @@ -395,8 +396,7 @@ static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh, len = ixhl - off; while (len > 1) { - switch (xh[off]) - { + switch (xh[off]) { case IPV6_TLV_PAD0: optlen = 1; break; @@ -476,14 +476,14 @@ static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags) goto done; case IPPROTO_UDP: if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) - if (!tcf_csum_ipv6_udp(skb, ip6h, - hl, pl + sizeof(*ip6h), 0)) + if (!tcf_csum_ipv6_udp(skb, ip6h, hl, + pl + sizeof(*ip6h), 0)) goto fail; goto done; case IPPROTO_UDPLITE: if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) - if (!tcf_csum_ipv6_udp(skb, ip6h, - hl, pl + sizeof(*ip6h), 1)) + if (!tcf_csum_ipv6_udp(skb, ip6h, hl, + pl + sizeof(*ip6h), 1)) goto fail; goto done; default: @@ -544,7 +544,6 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tcf_csum *p = a->priv; struct tc_csum opt = { .update_flags = p->update_flags, - .index = p->tcf_index, .action = p->tcf_action, .refcnt = p->tcf_refcnt - ref, @@ -566,17 +565,17 @@ nla_put_failure: } static struct tc_action_ops act_csum_ops = { - .kind = "csum", - .hinfo = &csum_hash_info, - .type = TCA_ACT_CSUM, - .capab = TCA_CAP_NONE, - .owner = THIS_MODULE, - .act = tcf_csum, - .dump = tcf_csum_dump, - .cleanup = tcf_csum_cleanup, - .lookup = tcf_hash_search, - .init = tcf_csum_init, - .walk = tcf_generic_walker + .kind = "csum", + .hinfo = &csum_hash_info, + .type = TCA_ACT_CSUM, + .capab = TCA_CAP_NONE, + .owner = THIS_MODULE, + .act = tcf_csum, + .dump = tcf_csum_dump, + .cleanup = tcf_csum_cleanup, + .lookup = tcf_hash_search, + .init = tcf_csum_init, + .walk = tcf_generic_walker }; MODULE_DESCRIPTION("Checksum updating actions"); -- cgit v1.2.3 From afdcba371f9748ac91608bb6c57f170aab7085b4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 23 Aug 2010 07:14:36 +0000 Subject: net: copy_rtnl_link_stats64() simplification No need to use a temporary struct rtnl_link_stats64 variable, just copy the source to skb buffer. Signed-off-by: Eric Dumazet Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f78d821bd935..b2a718dfd720 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -612,36 +612,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) { - struct rtnl_link_stats64 a; - - a.rx_packets = b->rx_packets; - a.tx_packets = b->tx_packets; - a.rx_bytes = b->rx_bytes; - a.tx_bytes = b->tx_bytes; - a.rx_errors = b->rx_errors; - a.tx_errors = b->tx_errors; - a.rx_dropped = b->rx_dropped; - a.tx_dropped = b->tx_dropped; - - a.multicast = b->multicast; - a.collisions = b->collisions; - - a.rx_length_errors = b->rx_length_errors; - a.rx_over_errors = b->rx_over_errors; - a.rx_crc_errors = b->rx_crc_errors; - a.rx_frame_errors = b->rx_frame_errors; - a.rx_fifo_errors = b->rx_fifo_errors; - a.rx_missed_errors = b->rx_missed_errors; - - a.tx_aborted_errors = b->tx_aborted_errors; - a.tx_carrier_errors = b->tx_carrier_errors; - a.tx_fifo_errors = b->tx_fifo_errors; - a.tx_heartbeat_errors = b->tx_heartbeat_errors; - a.tx_window_errors = b->tx_window_errors; - - a.rx_compressed = b->rx_compressed; - a.tx_compressed = b->tx_compressed; - memcpy(v, &a, sizeof(a)); + memcpy(v, b, sizeof(*b)); } /* All VF info */ -- cgit v1.2.3 From 0fdc100bdc4b7ab61ed632962c76dfe539047296 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 23 Aug 2010 10:24:18 +0000 Subject: ethtool: allow non-netadmin to query settings The SNMP daemon uses ethtool to determine the speed of network interfaces. This fails on Debian (and probably elsewhere) because for security SNMP daemon runs as non-root user (snmp). Note: A similar patch was rejected previously because of a concern about the possibility that on some hardware querying the ethtool settings requires access to the PHY and could slow the machine down. But the security risk of requiring SNMP daemon (and related services) to run as root far out weighs the risk of denial-of-service. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d2c4da5a6a4f..970eb9817bbc 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1423,6 +1423,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) /* Allow some commands to be done by anyone */ switch (ethcmd) { + case ETHTOOL_GSET: case ETHTOOL_GDRVINFO: case ETHTOOL_GMSGLVL: case ETHTOOL_GCOALESCE: -- cgit v1.2.3 From 1726442e115a9e58f40747d009a5b4f303e0840a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 23 Aug 2010 16:26:41 +0000 Subject: net: increase the size of priv_flags and add IFF_OVS_DATAPATH IFF_OVS_DATAPATH is a place-holder for the Open vSwitch datapath which I am preparing to submit for merging. As all 16 bits of priv_flags are already assigned flags, also increase the size of priv_flags to 32 bits. Unfortunately, by my calculations this increases the size of struct net_device by 4 bytes on 32bit architectures and 8 bytes on 64 bit architectures. I couldn't see an obvious way to avoid that. Cc: Jesse Gross Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- include/linux/if.h | 2 ++ include/linux/netdevice.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/if.h b/include/linux/if.h index 53558ec59e1b..6ed43c1f07ab 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -75,6 +75,8 @@ #define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */ #define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */ #define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */ +#define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch + * dapath port */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ce2de8b64083..59962dbc2758 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -901,7 +901,7 @@ struct net_device { unsigned int flags; /* interface flags (a la BSD) */ unsigned short gflags; - unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */ + unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */ unsigned short padded; /* How much padding added by alloc_netdev() */ unsigned char operstate; /* RFC2863 operstate */ -- cgit v1.2.3 From b4ddf4b3331f0f2195bd0ab5e8b50080ba93af87 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Aug 2010 12:22:13 -0700 Subject: be2net: get rid of be_get_stats() drivers can avoid implementing ndo_get_stats method if using netdevice stats structure. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 74e146f470c6..b89bae029620 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -365,11 +365,6 @@ static void be_rx_eqd_update(struct be_adapter *adapter) rx_eq->cur_eqd = eqd; } -static struct net_device_stats *be_get_stats(struct net_device *dev) -{ - return &dev->stats; -} - static u32 be_calc_rate(u64 bytes, unsigned long ticks) { u64 rate = bytes; @@ -2399,7 +2394,6 @@ static struct net_device_ops be_netdev_ops = { .ndo_open = be_open, .ndo_stop = be_close, .ndo_start_xmit = be_xmit, - .ndo_get_stats = be_get_stats, .ndo_set_rx_mode = be_set_multicast_list, .ndo_set_mac_address = be_mac_addr_set, .ndo_change_mtu = be_change_mtu, -- cgit v1.2.3 From 6abc2376809497b04feee554240e158ac2072587 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Aug 2010 12:23:01 -0700 Subject: ethoc: get rid of ethoc_stats() drivers can avoid implementing ndo_get_stats method if using netdevice stats structure. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 6d653c459c1f..c5a2fe099a8d 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -806,11 +806,6 @@ static void ethoc_tx_timeout(struct net_device *dev) ethoc_interrupt(dev->irq, dev); } -static struct net_device_stats *ethoc_stats(struct net_device *dev) -{ - return &dev->stats; -} - static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ethoc *priv = netdev_priv(dev); @@ -863,7 +858,6 @@ static const struct net_device_ops ethoc_netdev_ops = { .ndo_set_multicast_list = ethoc_set_multicast_list, .ndo_change_mtu = ethoc_change_mtu, .ndo_tx_timeout = ethoc_tx_timeout, - .ndo_get_stats = ethoc_stats, .ndo_start_xmit = ethoc_start_xmit, }; -- cgit v1.2.3 From c32d83c0420950754cca01557bc5802793948d66 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Aug 2010 12:24:07 -0700 Subject: bcm63xx_enet: use netdev stats Use integrated net_device stats instead of a private one Get rid of bcm_enet_get_stats() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bcm63xx_enet.c | 60 +++++++++++++++++++++------------------------- drivers/net/bcm63xx_enet.h | 1 - 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index 0d2c5da08937..e2f70c3d7be4 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -293,22 +293,22 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) /* if the packet does not have start of packet _and_ * end of packet flag set, then just recycle it */ if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) { - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; continue; } /* recycle packet if it's marked as bad */ if (unlikely(len_stat & DMADESC_ERR_MASK)) { - priv->stats.rx_errors++; + dev->stats.rx_errors++; if (len_stat & DMADESC_OVSIZE_MASK) - priv->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (len_stat & DMADESC_CRC_MASK) - priv->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (len_stat & DMADESC_UNDER_MASK) - priv->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (len_stat & DMADESC_OV_MASK) - priv->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; continue; } @@ -324,7 +324,7 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) nskb = netdev_alloc_skb_ip_align(dev, len); if (!nskb) { /* forget packet, just rearm desc */ - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; continue; } @@ -342,8 +342,8 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); - priv->stats.rx_packets++; - priv->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; netif_receive_skb(skb); } while (--budget > 0); @@ -403,7 +403,7 @@ static int bcm_enet_tx_reclaim(struct net_device *dev, int force) spin_unlock(&priv->tx_lock); if (desc->len_stat & DMADESC_UNDER_MASK) - priv->stats.tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); released++; @@ -563,8 +563,8 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!priv->tx_desc_count) netif_stop_queue(dev); - priv->stats.tx_bytes += skb->len; - priv->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; ret = NETDEV_TX_OK; out_unlock: @@ -1140,17 +1140,6 @@ static int bcm_enet_stop(struct net_device *dev) return 0; } -/* - * core request to return device rx/tx stats - */ -static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev) -{ - struct bcm_enet_priv *priv; - - priv = netdev_priv(dev); - return &priv->stats; -} - /* * ethtool callbacks */ @@ -1163,16 +1152,18 @@ struct bcm_enet_stats { #define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \ offsetof(struct bcm_enet_priv, m) +#define DEV_STAT(m) sizeof(((struct net_device_stats *)0)->m), \ + offsetof(struct net_device_stats, m) static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = { - { "rx_packets", GEN_STAT(stats.rx_packets), -1 }, - { "tx_packets", GEN_STAT(stats.tx_packets), -1 }, - { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 }, - { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 }, - { "rx_errors", GEN_STAT(stats.rx_errors), -1 }, - { "tx_errors", GEN_STAT(stats.tx_errors), -1 }, - { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 }, - { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 }, + { "rx_packets", DEV_STAT(rx_packets), -1 }, + { "tx_packets", DEV_STAT(tx_packets), -1 }, + { "rx_bytes", DEV_STAT(rx_bytes), -1 }, + { "tx_bytes", DEV_STAT(tx_bytes), -1 }, + { "rx_errors", DEV_STAT(rx_errors), -1 }, + { "tx_errors", DEV_STAT(tx_errors), -1 }, + { "rx_dropped", DEV_STAT(rx_dropped), -1 }, + { "tx_dropped", DEV_STAT(tx_dropped), -1 }, { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS}, { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS }, @@ -1328,7 +1319,11 @@ static void bcm_enet_get_ethtool_stats(struct net_device *netdev, char *p; s = &bcm_enet_gstrings_stats[i]; - p = (char *)priv + s->stat_offset; + if (s->mib_reg == -1) + p = (char *)&netdev->stats; + else + p = (char *)priv; + p += s->stat_offset; data[i] = (s->sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } @@ -1605,7 +1600,6 @@ static const struct net_device_ops bcm_enet_ops = { .ndo_open = bcm_enet_open, .ndo_stop = bcm_enet_stop, .ndo_start_xmit = bcm_enet_start_xmit, - .ndo_get_stats = bcm_enet_get_stats, .ndo_set_mac_address = bcm_enet_set_mac_address, .ndo_set_multicast_list = bcm_enet_set_multicast_list, .ndo_do_ioctl = bcm_enet_ioctl, diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h index bd3684d42d74..0e3048b788c2 100644 --- a/drivers/net/bcm63xx_enet.h +++ b/drivers/net/bcm63xx_enet.h @@ -274,7 +274,6 @@ struct bcm_enet_priv { int pause_tx; /* stats */ - struct net_device_stats stats; struct bcm_enet_mib_counters mib; /* after mib interrupt, mib registers update is done in this -- cgit v1.2.3 From 633adf1ad1c92c02bd3f10bbd73737a969179378 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Aug 2010 14:49:58 +0200 Subject: cfg80211: mark ieee80211_hdrlen const This function analyses only its single, value-passed argument, and has no side effects. Thus it can be const, which makes mac80211 smaller, for example: text data bss dec hex filename 362518 16720 884 380122 5ccda mac80211.ko (before) 362358 16720 884 379962 5cc3a mac80211.ko (after) a 160 byte saving in text size, and an optimisation because the function won't be called as often. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 2 +- net/wireless/util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2fd06c60ffbb..2b403c7ee32e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1715,7 +1715,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); * ieee80211_hdrlen - get header length in bytes from frame control * @fc: frame control field in little-endian format */ -unsigned int ieee80211_hdrlen(__le16 fc); +unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); /** * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 diff --git a/net/wireless/util.c b/net/wireless/util.c index 0c8a1e8b7690..1eb24162be61 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -221,7 +221,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; EXPORT_SYMBOL(bridge_tunnel_header); -unsigned int ieee80211_hdrlen(__le16 fc) +unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) { unsigned int hdrlen = 24; -- cgit v1.2.3 From ac4c977d16d843f12901595c91773dddb65768a9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Aug 2010 15:37:29 +0200 Subject: mac80211: remove unused don't-encrypt flag When MFP is disabled, action frames will not be encrypted since they are management frames and the only management frames that can then be encrypted are authentication frames. Therefore, setting the don't-encrypt flag on action frames is unnecessary. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9a35d9e7efd7..f9a317766136 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1555,8 +1555,6 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, return -ENOLINK; break; case NL80211_IFTYPE_STATION: - if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) - flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; break; default: return -EOPNOTSUPP; -- cgit v1.2.3 From 2e161f78e5f63a7f9fd25a766bb7f816a01eb14a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Aug 2010 15:38:38 +0200 Subject: cfg80211/mac80211: extensible frame processing Allow userspace to register for more than just action frames by giving the frame subtype, and make it possible to use this in various modes as well. With some tweaks and some added functionality this will, in the future, also be usable in AP mode and be able to replace the cooked monitor interface currently used in that case. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 93 +++++++++++++++++++++++------ include/net/cfg80211.h | 56 +++++++++++------- net/mac80211/cfg.c | 12 ++-- net/mac80211/ieee80211_i.h | 1 + net/mac80211/iface.c | 6 +- net/mac80211/main.c | 37 ++++++++++++ net/mac80211/rx.c | 137 +++++++++++++++++++++++++++++------------- net/mac80211/status.c | 2 +- net/mac80211/util.c | 6 +- net/wireless/core.c | 8 +-- net/wireless/core.h | 21 +++---- net/wireless/mlme.c | 144 +++++++++++++++++++++++++++++---------------- net/wireless/nl80211.c | 108 +++++++++++++++++++++++++--------- net/wireless/nl80211.h | 14 ++--- net/wireless/util.c | 2 +- 15 files changed, 452 insertions(+), 195 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2c8701687336..8af1e66c3cf9 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -39,6 +39,43 @@ * TODO: need more info? */ +/** + * DOC: Frame transmission/registration support + * + * Frame transmission and registration support exists to allow userspace + * management entities such as wpa_supplicant react to management frames + * that are not being handled by the kernel. This includes, for example, + * certain classes of action frames that cannot be handled in the kernel + * for various reasons. + * + * Frame registration is done on a per-interface basis and registrations + * cannot be removed other than by closing the socket. It is possible to + * specify a registration filter to register, for example, only for a + * certain type of action frame. In particular with action frames, those + * that userspace registers for will not be returned as unhandled by the + * driver, so that the registered application has to take responsibility + * for doing that. + * + * The type of frame that can be registered for is also dependent on the + * driver and interface type. The frame types are advertised in wiphy + * attributes so applications know what to expect. + * + * NOTE: When an interface changes type while registrations are active, + * these registrations are ignored until the interface type is + * changed again. This means that changing the interface type can + * lead to a situation that couldn't otherwise be produced, but + * any such registrations will be dormant in the sense that they + * will not be serviced, i.e. they will not receive any frames. + * + * Frame transmission allows userspace to send for example the required + * responses to action frames. It is subject to some sanity checking, + * but many frames can be transmitted. When a frame was transmitted, its + * status is indicated to the sending socket. + * + * For more technical details, see the corresponding command descriptions + * below. + */ + /** * enum nl80211_commands - supported nl80211 commands * @@ -301,16 +338,18 @@ * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface * and @NL80211_ATTR_TX_RATES the set of allowed rates. * - * @NL80211_CMD_REGISTER_ACTION: Register for receiving certain action frames - * (via @NL80211_CMD_ACTION) for processing in userspace. This command - * requires an interface index and a match attribute containing the first - * few bytes of the frame that should match, e.g. a single byte for only - * a category match or four bytes for vendor frames including the OUI. - * The registration cannot be dropped, but is removed automatically - * when the netlink socket is closed. Multiple registrations can be made. - * @NL80211_CMD_ACTION: Action frame TX request and RX notification. This - * command is used both as a request to transmit an Action frame and as an - * event indicating reception of an Action frame that was not processed in + * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames + * (via @NL80211_CMD_FRAME) for processing in userspace. This command + * requires an interface index, a frame type attribute (optional for + * backward compatibility reasons, if not given assumes action frames) + * and a match attribute containing the first few bytes of the frame + * that should match, e.g. a single byte for only a category match or + * four bytes for vendor frames including the OUI. The registration + * cannot be dropped, but is removed automatically when the netlink + * socket is closed. Multiple registrations can be made. + * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This + * command is used both as a request to transmit a management frame and + * as an event indicating reception of a frame that was not processed in * kernel code, but is for us (i.e., which may need to be processed in a * user space application). %NL80211_ATTR_FRAME is used to specify the * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and @@ -320,8 +359,8 @@ * operational channel). When called, this operation returns a cookie * (%NL80211_ATTR_COOKIE) that will be included with the TX status event * pertaining to the TX request. - * @NL80211_CMD_ACTION_TX_STATUS: Report TX status of an Action frame - * transmitted with %NL80211_CMD_ACTION. %NL80211_ATTR_COOKIE identifies + * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame + * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies * the TX command and %NL80211_ATTR_FRAME includes the contents of the * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged * the frame. @@ -429,9 +468,12 @@ enum nl80211_commands { NL80211_CMD_SET_TX_BITRATE_MASK, - NL80211_CMD_REGISTER_ACTION, - NL80211_CMD_ACTION, - NL80211_CMD_ACTION_TX_STATUS, + NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_FRAME, + NL80211_CMD_ACTION = NL80211_CMD_FRAME, + NL80211_CMD_FRAME_TX_STATUS, + NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, NL80211_CMD_SET_POWER_SAVE, NL80211_CMD_GET_POWER_SAVE, @@ -708,7 +750,16 @@ enum nl80211_commands { * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. * * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain - * at least one byte, currently used with @NL80211_CMD_REGISTER_ACTION. + * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. + * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the + * @NL80211_CMD_REGISTER_FRAME command. + * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be transmitted with + * %NL80211_CMD_FRAME. + * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be registered for RX. * * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was * acknowledged by the recipient. @@ -891,6 +942,10 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_TX_POWER_SETTING, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, + NL80211_ATTR_TX_FRAME_TYPES, + NL80211_ATTR_RX_FRAME_TYPES, + NL80211_ATTR_FRAME_TYPE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -947,7 +1002,7 @@ enum nl80211_attrs { * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MESH_POINT: mesh point * @NL80211_IFTYPE_MAX: highest interface type number currently defined - * @__NL80211_IFTYPE_AFTER_LAST: internal use + * @NUM_NL80211_IFTYPES: number of defined interface types * * These values are used with the %NL80211_ATTR_IFTYPE * to set the type of an interface. @@ -964,8 +1019,8 @@ enum nl80211_iftype { NL80211_IFTYPE_MESH_POINT, /* keep last */ - __NL80211_IFTYPE_AFTER_LAST, - NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1 + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 }; /** diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2b403c7ee32e..6a98b1b3bfde 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1020,7 +1020,7 @@ struct cfg80211_pmksa { * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. * This allows the operation to be terminated prior to timeout based on * the duration value. - * @action: Transmit an action frame + * @mgmt_tx: Transmit a management frame * * @testmode_cmd: run a test mode command * @@ -1172,7 +1172,7 @@ struct cfg80211_ops { struct net_device *dev, u64 cookie); - int (*action)(struct wiphy *wiphy, struct net_device *dev, + int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, bool channel_type_valid, @@ -1236,6 +1236,10 @@ struct mac_address { u8 addr[ETH_ALEN]; }; +struct ieee80211_txrx_stypes { + u16 tx, rx; +}; + /** * struct wiphy - wireless hardware description * @reg_notifier: the driver's regulatory notification callback @@ -1286,6 +1290,10 @@ struct mac_address { * @privid: a pointer that drivers can use to identify if an arbitrary * wiphy is theirs, e.g. in global notifiers * @bands: information about bands/channels supported by this device + * + * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or + * transmitted through nl80211, points to an array indexed by interface + * type */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1294,9 +1302,12 @@ struct wiphy { u8 perm_addr[ETH_ALEN]; u8 addr_mask[ETH_ALEN]; - u16 n_addresses; struct mac_address *addresses; + const struct ieee80211_txrx_stypes *mgmt_stypes; + + u16 n_addresses; + /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ u16 interface_modes; @@ -1492,8 +1503,8 @@ struct cfg80211_cached_keys; * set by driver (if supported) on add_interface BEFORE registering the * netdev and may otherwise be used by driver read-only, will be update * by cfg80211 on change_interface - * @action_registrations: list of registrations for action frames - * @action_registrations_lock: lock for the list + * @mgmt_registrations: list of registrations for management frames + * @mgmt_registrations_lock: lock for the list * @mtx: mutex used to lock data in this struct * @cleanup_work: work struct used for cleanup that can't be done directly */ @@ -1505,8 +1516,8 @@ struct wireless_dev { struct list_head list; struct net_device *netdev; - struct list_head action_registrations; - spinlock_t action_registrations_lock; + struct list_head mgmt_registrations; + spinlock_t mgmt_registrations_lock; struct mutex mtx; @@ -2373,38 +2384,39 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); /** - * cfg80211_rx_action - notification of received, unprocessed Action frame + * cfg80211_rx_mgmt - notification of received, unprocessed management frame * @dev: network device * @freq: Frequency on which the frame was received in MHz - * @buf: Action frame (header + body) + * @buf: Management frame (header + body) * @len: length of the frame data * @gfp: context flags - * Returns %true if a user space application is responsible for rejecting the - * unrecognized Action frame; %false if no such application is registered - * (i.e., the driver is responsible for rejecting the unrecognized Action - * frame) + * + * Returns %true if a user space application has registered for this frame. + * For action frames, that makes it responsible for rejecting unrecognized + * action frames; %false otherwise, in which case for action frames the + * driver is responsible for rejecting the frame. * * This function is called whenever an Action frame is received for a station * mode interface, but is not processed in kernel. */ -bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp); +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, + size_t len, gfp_t gfp); /** - * cfg80211_action_tx_status - notification of TX status for Action frame + * cfg80211_mgmt_tx_status - notification of TX status for management frame * @dev: network device - * @cookie: Cookie returned by cfg80211_ops::action() - * @buf: Action frame (header + body) + * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() + * @buf: Management frame (header + body) * @len: length of the frame data * @ack: Whether frame was acknowledged * @gfp: context flags * - * This function is called whenever an Action frame was requested to be - * transmitted with cfg80211_ops::action() to report the TX status of the + * This function is called whenever a management frame was requested to be + * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the * transmission attempt. */ -void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, - const u8 *buf, size_t len, bool ack, gfp_t gfp); +void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, + const u8 *buf, size_t len, bool ack, gfp_t gfp); /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f9a317766136..94787d21282c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1521,11 +1521,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); } -static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie) +static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; @@ -1625,6 +1625,6 @@ struct cfg80211_ops mac80211_config_ops = { .set_bitrate_mask = ieee80211_set_bitrate_mask, .remain_on_channel = ieee80211_remain_on_channel, .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, - .action = ieee80211_action, + .mgmt_tx = ieee80211_mgmt_tx, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 1bf05bfd149d..e73ae51dc036 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -170,6 +170,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result; #define IEEE80211_RX_RA_MATCH BIT(1) #define IEEE80211_RX_AMSDU BIT(2) #define IEEE80211_RX_FRAGMENTED BIT(3) +#define IEEE80211_MALFORMED_ACTION_FRM BIT(4) /* only add flags here that do not change with subframes of an aMPDU */ struct ieee80211_rx_data { diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9459aeee0ddc..86f434f234ae 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -177,7 +177,7 @@ static int ieee80211_open(struct net_device *dev) /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: /* cannot happen */ WARN_ON(1); break; @@ -634,7 +634,7 @@ static void ieee80211_teardown_sdata(struct net_device *dev) case NL80211_IFTYPE_MONITOR: break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: BUG(); break; } @@ -886,7 +886,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP_VLAN: break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: BUG(); break; } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0afccda42a24..a53feac4618c 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -417,6 +417,41 @@ void ieee80211_napi_complete(struct ieee80211_hw *hw) } EXPORT_SYMBOL(ieee80211_napi_complete); +/* There isn't a lot of sense in it, but you can transmit anything you like */ +static const struct ieee80211_txrx_stypes +ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4), + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, +}; + struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -446,6 +481,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, if (!wiphy) return NULL; + wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; + wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | WIPHY_FLAG_4ADDR_STATION; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 4fdbed58ca2f..aa41e382bbb3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1939,14 +1939,37 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb(sdata, skb); } +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + + /* + * From here on, look only at management frames. + * Data and control frames are already handled, + * and unknown (reserved) frames are useless. + */ + if (rx->skb->len < 24) + return RX_DROP_MONITOR; + + if (!ieee80211_is_mgmt(mgmt->frame_control)) + return RX_DROP_MONITOR; + + if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + return RX_DROP_MONITOR; + + if (ieee80211_drop_unencrypted_mgmt(rx)) + return RX_DROP_UNUSABLE; + + return RX_CONTINUE; +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_action(struct ieee80211_rx_data *rx) { struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; - struct sk_buff *nskb; - struct ieee80211_rx_status *status; int len = rx->skb->len; if (!ieee80211_is_action(mgmt->frame_control)) @@ -1962,9 +1985,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (!(rx->flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_UNUSABLE; - if (ieee80211_drop_unencrypted_mgmt(rx)) - return RX_DROP_UNUSABLE; - switch (mgmt->u.action.category) { case WLAN_CATEGORY_BACK: /* @@ -2055,17 +2075,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) goto queue; } + return RX_CONTINUE; + invalid: - /* - * For AP mode, hostapd is responsible for handling any action - * frames that we didn't handle, including returning unknown - * ones. For all other modes we will return them to the sender, - * setting the 0x80 bit in the action category, as required by - * 802.11-2007 7.3.1.11. - */ - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - return RX_DROP_MONITOR; + rx->flags |= IEEE80211_MALFORMED_ACTION_FRM; + /* will return in the next handlers */ + return RX_CONTINUE; + + handled: + if (rx->sta) + rx->sta->rx_packets++; + dev_kfree_skb(rx->skb); + return RX_QUEUED; + + queue: + rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; + skb_queue_tail(&sdata->skb_queue, rx->skb); + ieee80211_queue_work(&local->hw, &sdata->work); + if (rx->sta) + rx->sta->rx_packets++; + return RX_QUEUED; +} + +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) +{ + struct ieee80211_rx_status *status; + + /* skip known-bad action frames and return them in the next handler */ + if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM) + return RX_CONTINUE; /* * Getting here means the kernel doesn't know how to handle @@ -2075,10 +2114,44 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) */ status = IEEE80211_SKB_RXCB(rx->skb); - if (cfg80211_rx_action(rx->sdata->dev, status->freq, - rx->skb->data, rx->skb->len, - GFP_ATOMIC)) - goto handled; + if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, + rx->skb->data, rx->skb->len, + GFP_ATOMIC)) { + if (rx->sta) + rx->sta->rx_packets++; + dev_kfree_skb(rx->skb); + return RX_QUEUED; + } + + + return RX_CONTINUE; +} + +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) +{ + struct ieee80211_local *local = rx->local; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + struct sk_buff *nskb; + struct ieee80211_sub_if_data *sdata = rx->sdata; + + if (!ieee80211_is_action(mgmt->frame_control)) + return RX_CONTINUE; + + /* + * For AP mode, hostapd is responsible for handling any action + * frames that we didn't handle, including returning unknown + * ones. For all other modes we will return them to the sender, + * setting the 0x80 bit in the action category, as required by + * 802.11-2007 7.3.1.11. + * Newer versions of hostapd shall also use the management frame + * registration mechanisms, but older ones still use cooked + * monitor interfaces so push all frames there. + */ + if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) && + (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) + return RX_DROP_MONITOR; /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) @@ -2097,20 +2170,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ieee80211_tx_skb(rx->sdata, nskb); } - - handled: - if (rx->sta) - rx->sta->rx_packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; - - queue: - rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; - skb_queue_tail(&sdata->skb_queue, rx->skb); - ieee80211_queue_work(&local->hw, &sdata->work); - if (rx->sta) - rx->sta->rx_packets++; - return RX_QUEUED; } static ieee80211_rx_result debug_noinline @@ -2121,15 +2182,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; __le16 stype; - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) - return RX_DROP_MONITOR; - - if (rx->skb->len < 24) - return RX_DROP_MONITOR; - - if (ieee80211_drop_unencrypted_mgmt(rx)) - return RX_DROP_UNUSABLE; - rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); if (rxs != RX_CONTINUE) return rxs; @@ -2374,7 +2426,10 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, if (res != RX_CONTINUE) goto rxh_next; + CALL_RXH(ieee80211_rx_h_mgmt_check) CALL_RXH(ieee80211_rx_h_action) + CALL_RXH(ieee80211_rx_h_userspace_mgmt) + CALL_RXH(ieee80211_rx_h_action_return) CALL_RXH(ieee80211_rx_h_mgmt) rxh_next: @@ -2527,7 +2582,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, break; case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: /* should never get here */ WARN_ON(1); break; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 10caec5ea8fa..67a35841bef0 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -296,7 +296,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) - cfg80211_action_tx_status( + cfg80211_mgmt_tx_status( skb->dev, (unsigned long) skb, skb->data, skb->len, !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 748387d45bc0..cd2b485fed4f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -471,7 +471,7 @@ void ieee80211_iterate_active_interfaces( list_for_each_entry(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -505,7 +505,7 @@ void ieee80211_iterate_active_interfaces_atomic( list_for_each_entry_rcu(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -1189,7 +1189,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* ignore virtual */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: WARN_ON(1); break; } diff --git a/net/wireless/core.c b/net/wireless/core.c index c70909c3eae4..d52630bbab04 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -433,7 +433,7 @@ int wiphy_register(struct wiphy *wiphy) /* sanity check ifmodes */ WARN_ON(!ifmodes); - ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; + ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1; if (WARN_ON(ifmodes != wiphy->interface_modes)) wiphy->interface_modes = ifmodes; @@ -685,8 +685,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work); INIT_LIST_HEAD(&wdev->event_list); spin_lock_init(&wdev->event_lock); - INIT_LIST_HEAD(&wdev->action_registrations); - spin_lock_init(&wdev->action_registrations_lock); + INIT_LIST_HEAD(&wdev->mgmt_registrations); + spin_lock_init(&wdev->mgmt_registrations_lock); mutex_lock(&rdev->devlist_mtx); list_add_rcu(&wdev->list, &rdev->netdev_list); @@ -806,7 +806,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, sysfs_remove_link(&dev->dev.kobj, "phy80211"); list_del_rcu(&wdev->list); rdev->devlist_generation++; - cfg80211_mlme_purge_actions(wdev); + cfg80211_mlme_purge_registrations(wdev); #ifdef CONFIG_CFG80211_WEXT kfree(wdev->wext.keys); #endif diff --git a/net/wireless/core.h b/net/wireless/core.h index 63d57ae399c3..58ab2c791d28 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -331,16 +331,17 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, const u8 *resp_ie, size_t resp_ie_len, u16 status, bool wextev, struct cfg80211_bss *bss); -int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, - const u8 *match_data, int match_len); -void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid); -void cfg80211_mlme_purge_actions(struct wireless_dev *wdev); -int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie); +int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, + u16 frame_type, const u8 *match_data, + int match_len); +void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); +void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); +int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie); /* SME */ int __cfg80211_connect(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index ee0af32ed59e..8515b1e5c578 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -748,31 +748,51 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, } EXPORT_SYMBOL(cfg80211_new_sta); -struct cfg80211_action_registration { +struct cfg80211_mgmt_registration { struct list_head list; u32 nlpid; int match_len; + __le16 frame_type; + u8 match[]; }; -int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, - const u8 *match_data, int match_len) +int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, + u16 frame_type, const u8 *match_data, + int match_len) { - struct cfg80211_action_registration *reg, *nreg; + struct cfg80211_mgmt_registration *reg, *nreg; int err = 0; + u16 mgmt_type; + + if (!wdev->wiphy->mgmt_stypes) + return -EOPNOTSUPP; + + if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) + return -EINVAL; + + if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) + return -EINVAL; + + mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; + if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) + return -EINVAL; nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL); if (!nreg) return -ENOMEM; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry(reg, &wdev->action_registrations, list) { + list_for_each_entry(reg, &wdev->mgmt_registrations, list) { int mlen = min(match_len, reg->match_len); + if (frame_type != le16_to_cpu(reg->frame_type)) + continue; + if (memcmp(reg->match, match_data, mlen) == 0) { err = -EALREADY; break; @@ -787,62 +807,75 @@ int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, memcpy(nreg->match, match_data, match_len); nreg->match_len = match_len; nreg->nlpid = snd_pid; - list_add(&nreg->list, &wdev->action_registrations); + nreg->frame_type = cpu_to_le16(frame_type); + list_add(&nreg->list, &wdev->mgmt_registrations); out: - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); return err; } -void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid) +void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) { - struct cfg80211_action_registration *reg, *tmp; + struct cfg80211_mgmt_registration *reg, *tmp; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) { + list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { if (reg->nlpid == nlpid) { list_del(®->list); kfree(reg); } } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); } -void cfg80211_mlme_purge_actions(struct wireless_dev *wdev) +void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) { - struct cfg80211_action_registration *reg, *tmp; + struct cfg80211_mgmt_registration *reg, *tmp; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) { + list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { list_del(®->list); kfree(reg); } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); } -int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie) +int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie) { struct wireless_dev *wdev = dev->ieee80211_ptr; const struct ieee80211_mgmt *mgmt; + u16 stype; + + if (!wdev->wiphy->mgmt_stypes) + return -EOPNOTSUPP; - if (rdev->ops->action == NULL) + if (!rdev->ops->mgmt_tx) return -EOPNOTSUPP; + if (len < 24 + 1) return -EINVAL; mgmt = (const struct ieee80211_mgmt *) buf; - if (!ieee80211_is_action(mgmt->frame_control)) + + if (!ieee80211_is_mgmt(mgmt->frame_control)) return -EINVAL; - if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { + + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; + if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4))) + return -EINVAL; + + if (ieee80211_is_action(mgmt->frame_control) && + mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { /* Verify that we are associated with the destination AP */ wdev_lock(wdev); @@ -863,64 +896,75 @@ int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, return -EINVAL; /* Transmit the Action frame as requested by user space */ - return rdev->ops->action(&rdev->wiphy, dev, chan, channel_type, - channel_type_valid, buf, len, cookie); + return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type, + channel_type_valid, buf, len, cookie); } -bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp) +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, + size_t len, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - struct cfg80211_action_registration *reg; - const u8 *action_data; - int action_data_len; + struct cfg80211_mgmt_registration *reg; + const struct ieee80211_txrx_stypes *stypes = + &wiphy->mgmt_stypes[wdev->iftype]; + struct ieee80211_mgmt *mgmt = (void *)buf; + const u8 *data; + int data_len; bool result = false; + __le16 ftype = mgmt->frame_control & + cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); + u16 stype; - /* frame length - min size excluding category */ - action_data_len = len - (IEEE80211_MIN_ACTION_SIZE - 1); + stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; - /* action data starts with category */ - action_data = buf + IEEE80211_MIN_ACTION_SIZE - 1; + if (!(stypes->rx & BIT(stype))) + return false; - spin_lock_bh(&wdev->action_registrations_lock); + data = buf + ieee80211_hdrlen(mgmt->frame_control); + data_len = len - ieee80211_hdrlen(mgmt->frame_control); + + spin_lock_bh(&wdev->mgmt_registrations_lock); + + list_for_each_entry(reg, &wdev->mgmt_registrations, list) { + if (reg->frame_type != ftype) + continue; - list_for_each_entry(reg, &wdev->action_registrations, list) { - if (reg->match_len > action_data_len) + if (reg->match_len > data_len) continue; - if (memcmp(reg->match, action_data, reg->match_len)) + if (memcmp(reg->match, data, reg->match_len)) continue; /* found match! */ /* Indicate the received Action frame to user space */ - if (nl80211_send_action(rdev, dev, reg->nlpid, freq, - buf, len, gfp)) + if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, + buf, len, gfp)) continue; result = true; break; } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); return result; } -EXPORT_SYMBOL(cfg80211_rx_action); +EXPORT_SYMBOL(cfg80211_rx_mgmt); -void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, - const u8 *buf, size_t len, bool ack, gfp_t gfp) +void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, + const u8 *buf, size_t len, bool ack, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); /* Indicate TX status of the Action frame to user space */ - nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp); + nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp); } -EXPORT_SYMBOL(cfg80211_action_tx_status); +EXPORT_SYMBOL(cfg80211_mgmt_tx_status); void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bb5b78eebeb2..927ffbd2aebc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -156,6 +156,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, + [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, }; /* policy for the attributes */ @@ -437,6 +438,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct ieee80211_rate *rate; int i; u16 ifmodes = dev->wiphy.interface_modes; + const struct ieee80211_txrx_stypes *mgmt_stypes = + dev->wiphy.mgmt_stypes; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); if (!hdr) @@ -587,7 +590,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(flush_pmksa, FLUSH_PMKSA); CMD(remain_on_channel, REMAIN_ON_CHANNEL); CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); - CMD(action, ACTION); + CMD(mgmt_tx, FRAME); if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { i++; NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); @@ -608,6 +611,53 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_cmds); + if (mgmt_stypes) { + u16 stypes; + struct nlattr *nl_ftypes, *nl_ifs; + enum nl80211_iftype ift; + + nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES); + if (!nl_ifs) + goto nla_put_failure; + + for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { + nl_ftypes = nla_nest_start(msg, ift); + if (!nl_ftypes) + goto nla_put_failure; + i = 0; + stypes = mgmt_stypes[ift].tx; + while (stypes) { + if (stypes & 1) + NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, + (i << 4) | IEEE80211_FTYPE_MGMT); + stypes >>= 1; + i++; + } + nla_nest_end(msg, nl_ftypes); + } + + nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); + if (!nl_ifs) + goto nla_put_failure; + + for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { + nl_ftypes = nla_nest_start(msg, ift); + if (!nl_ftypes) + goto nla_put_failure; + i = 0; + stypes = mgmt_stypes[ift].rx; + while (stypes) { + if (stypes & 1) + NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, + (i << 4) | IEEE80211_FTYPE_MGMT); + stypes >>= 1; + i++; + } + nla_nest_end(msg, nl_ftypes); + } + nla_nest_end(msg, nl_ifs); + } + return genlmsg_end(msg, hdr); nla_put_failure: @@ -4732,17 +4782,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, return err; } -static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info) +static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev; struct net_device *dev; + u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; int err; if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) return -EINVAL; - if (nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]) < 1) - return -EINVAL; + if (info->attrs[NL80211_ATTR_FRAME_TYPE]) + frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); rtnl_lock(); @@ -4757,12 +4808,13 @@ static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info) } /* not much point in registering if we can't reply */ - if (!rdev->ops->action) { + if (!rdev->ops->mgmt_tx) { err = -EOPNOTSUPP; goto out; } - err = cfg80211_mlme_register_action(dev->ieee80211_ptr, info->snd_pid, + err = cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, + frame_type, nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); out: @@ -4773,7 +4825,7 @@ static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info) return err; } -static int nl80211_action(struct sk_buff *skb, struct genl_info *info) +static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev; struct net_device *dev; @@ -4796,7 +4848,7 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (!rdev->ops->action) { + if (!rdev->ops->mgmt_tx) { err = -EOPNOTSUPP; goto out; } @@ -4839,17 +4891,17 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info) } hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, - NL80211_CMD_ACTION); + NL80211_CMD_FRAME); if (IS_ERR(hdr)) { err = PTR_ERR(hdr); goto free_msg; } - err = cfg80211_mlme_action(rdev, dev, chan, channel_type, - channel_type_valid, - nla_data(info->attrs[NL80211_ATTR_FRAME]), - nla_len(info->attrs[NL80211_ATTR_FRAME]), - &cookie); + err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type, + channel_type_valid, + nla_data(info->attrs[NL80211_ATTR_FRAME]), + nla_len(info->attrs[NL80211_ATTR_FRAME]), + &cookie); if (err) goto free_msg; @@ -5348,14 +5400,14 @@ static struct genl_ops nl80211_ops[] = { .flags = GENL_ADMIN_PERM, }, { - .cmd = NL80211_CMD_REGISTER_ACTION, - .doit = nl80211_register_action, + .cmd = NL80211_CMD_REGISTER_FRAME, + .doit = nl80211_register_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, }, { - .cmd = NL80211_CMD_ACTION, - .doit = nl80211_action, + .cmd = NL80211_CMD_FRAME, + .doit = nl80211_tx_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, }, @@ -6055,9 +6107,9 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, nl80211_mlme_mcgrp.id, gfp); } -int nl80211_send_action(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u32 nlpid, - int freq, const u8 *buf, size_t len, gfp_t gfp) +int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 nlpid, + int freq, const u8 *buf, size_t len, gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -6067,7 +6119,7 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev, if (!msg) return -ENOMEM; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION); + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); if (!hdr) { nlmsg_free(msg); return -ENOMEM; @@ -6095,10 +6147,10 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev, return -ENOBUFS; } -void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u64 cookie, - const u8 *buf, size_t len, bool ack, - gfp_t gfp) +void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u64 cookie, + const u8 *buf, size_t len, bool ack, + gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -6107,7 +6159,7 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, if (!msg) return; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION_TX_STATUS); + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS); if (!hdr) { nlmsg_free(msg); return; @@ -6194,7 +6246,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) - cfg80211_mlme_unregister_actions(wdev, notify->pid); + cfg80211_mlme_unregister_socket(wdev, notify->pid); rcu_read_unlock(); diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 2ad7fbc7d9f1..30d2f939150d 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -74,13 +74,13 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); -int nl80211_send_action(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u32 nlpid, int freq, - const u8 *buf, size_t len, gfp_t gfp); -void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u64 cookie, - const u8 *buf, size_t len, bool ack, - gfp_t gfp); +int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 nlpid, int freq, + const u8 *buf, size_t len, gfp_t gfp); +void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u64 cookie, + const u8 *buf, size_t len, bool ack, + gfp_t gfp); void nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/util.c b/net/wireless/util.c index 1eb24162be61..8d961cc4ae98 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -823,7 +823,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* monitor can't bridge anyway */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: /* not happening */ break; } -- cgit v1.2.3 From 418de6d955fa1da0cb4332661a31d21f57e954ab Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Sun, 15 Aug 2010 13:03:10 -0400 Subject: ath5k: rename ath5k_hw_set_associd to _set_bssid Although the named function also sets the aid, its main purpose is configuring the bssid and we use that everywhere else. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/attach.c | 2 +- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/pcu.c | 13 ++++++------- drivers/net/wireless/ath/ath5k/reset.c | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ea6362a8988d..9129e51b4f18 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1190,7 +1190,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); /* BSSID Functions */ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); -void ath5k_hw_set_associd(struct ath5k_hw *ah); +void ath5k_hw_set_bssid(struct ath5k_hw *ah); void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); /* Receive start/stop functions */ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index b32e28caeee2..e72a1e5421d7 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -329,7 +329,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); ath5k_hw_set_opmode(ah, sc->opmode); ath5k_hw_rfgain_opt_init(ah); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a729b8774670..0378bbcce494 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3476,7 +3476,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, /* Cache for later use during resets */ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); common->curaid = 0; - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); mmiowb(); } @@ -3494,7 +3494,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, "Bss Info ASSOC %d, bssid: %pM\n", bss_conf->aid, common->curbssid); common->curaid = bss_conf->aid; - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); /* Once ANI is available you would start it here */ } } diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index af273358c7cb..3fef5931ec3a 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -308,27 +308,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) } /** - * ath5k_hw_set_associd - Set BSSID for association + * ath5k_hw_set_bssid - Set current BSSID on hw * * @ah: The &struct ath5k_hw - * @bssid: BSSID - * @assoc_id: Assoc id * - * Sets the BSSID which trigers the "SME Join" operation + * Sets the current BSSID and BSSID mask we have from the + * common struct into the hardware */ -void ath5k_hw_set_associd(struct ath5k_hw *ah) +void ath5k_hw_set_bssid(struct ath5k_hw *ah) { struct ath_common *common = ath5k_hw_common(ah); u16 tim_offset = 0; /* - * Set simple BSSID mask on 5212 + * Set BSSID mask on 5212 */ if (ah->ah_version == AR5K_AR5212) ath_hw_setbssidmask(common); /* - * Set BSSID which triggers the "SME Join" operation + * Set BSSID */ ath5k_hw_reg_write(ah, get_unaligned_le32(common->curbssid), diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 498aa28ea9e6..f5434eb7f980 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1160,7 +1160,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, */ /* Restore bssid and bssid mask */ - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); /* Set PCU config */ ath5k_hw_set_opmode(ah, op_mode); -- cgit v1.2.3 From b61279809860690fe5c9fcb40441008d31fabab6 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Sun, 15 Aug 2010 13:03:11 -0400 Subject: ath5k: remove own (wrong) IEEE80211_MAX_LEN Use the version already supplied in include/linux/ieee80211.h. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 5 +---- drivers/net/wireless/ath/ath5k/base.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 9129e51b4f18..f399c4dd8e69 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -175,7 +175,7 @@ #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 #define AR5K_TUNE_RADAR_ALERT false #define AR5K_TUNE_MIN_TX_FIFO_THRES 1 -#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1) +#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1) #define AR5K_TUNE_REGISTER_TIMEOUT 20000 /* Register for RSSI threshold has a mask of 0xff, so 255 seems to * be the max value. */ @@ -343,9 +343,6 @@ struct ath5k_srev_name { #define AR5K_SREV_PHY_5413 0x61 #define AR5K_SREV_PHY_2425 0x70 -/* IEEE defs */ -#define IEEE80211_MAX_LEN 2500 - /* TODO add support to mac80211 for vendor-specific rates and modes */ /* diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0378bbcce494..91241b4525ad 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1709,7 +1709,7 @@ ath5k_rx_start(struct ath5k_softc *sc) struct ath5k_buf *bf; int ret; - common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); + common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", common->cachelsz, common->rx_bufsize); -- cgit v1.2.3 From a180a13081708b78d42232c6d922ce3de63f12e0 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 15 Aug 2010 13:03:12 -0400 Subject: ath5k: clean up some comments This fixes a few misspellings, word repetitions, and some grammar nits in ath5k comments. No code changes. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 6 ++-- drivers/net/wireless/ath/ath5k/attach.c | 6 ++-- drivers/net/wireless/ath/ath5k/base.c | 58 +++++++++++++++---------------- drivers/net/wireless/ath/ath5k/dma.c | 4 +-- drivers/net/wireless/ath/ath5k/eeprom.c | 4 +-- drivers/net/wireless/ath/ath5k/phy.c | 15 ++++---- drivers/net/wireless/ath/ath5k/reg.h | 2 +- drivers/net/wireless/ath/ath5k/reset.c | 22 ++++++------ drivers/net/wireless/ath/ath5k/rfbuffer.h | 4 +-- 9 files changed, 59 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 26dbe65fedb0..e4a5f046bba4 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -552,9 +552,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah) if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) return; - /* if one of the errors triggered, we can get a superfluous second - * interrupt, even though we have already reset the register. the - * function detects that so we can return early */ + /* If one of the errors triggered, we can get a superfluous second + * interrupt, even though we have already reset the register. The + * function detects that so we can return early. */ if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) return; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index e72a1e5421d7..aabad4f13e2a 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -139,12 +139,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc) else ah->ah_version = AR5K_AR5212; - /*Fill the ath5k_hw struct with the needed functions*/ + /* Fill the ath5k_hw struct with the needed functions */ ret = ath5k_hw_init_desc_functions(ah); if (ret) goto err_free; - /* Bring device out of sleep and reset it's units */ + /* Bring device out of sleep and reset its units */ ret = ath5k_hw_nic_wakeup(ah, 0, true); if (ret) goto err_free; @@ -158,7 +158,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) CHANNEL_5GHZ); ah->ah_phy = AR5K_PHY(0); - /* Try to identify radio chip based on it's srev */ + /* Try to identify radio chip based on its srev */ switch (ah->ah_radio_5ghz_revision & 0xf0) { case AR5K_SREV_RAD_5111: ah->ah_radio = AR5K_RF5111; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 91241b4525ad..c3b614d2ef34 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -612,7 +612,7 @@ ath5k_pci_probe(struct pci_dev *pdev, goto err_free; } - /*If we passed the test malloc a ath5k_hw struct*/ + /* If we passed the test, malloc an ath5k_hw struct */ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); if (!sc->ah) { ret = -ENOMEM; @@ -786,8 +786,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) /* * Check if the MAC has multi-rate retry support. * We do this by trying to setup a fake extended - * descriptor. MAC's that don't have support will - * return false w/o doing anything. MAC's that do + * descriptor. MACs that don't have support will + * return false w/o doing anything. MACs that do * support it will return true w/o doing anything. */ ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); @@ -827,7 +827,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) /* * Allocate hardware transmit queues: one queue for * beacon frames and one data queue for each QoS - * priority. Note that hw functions handle reseting + * priority. Note that hw functions handle resetting * these queues at the needed time. */ ret = ath5k_beaconq_setup(ah); @@ -909,7 +909,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) /* * NB: the order of these is important: * o call the 802.11 layer before detaching ath5k_hw to - * insure callbacks into the driver to delete global + * ensure callbacks into the driver to delete global * key cache entries can be handled * o reclaim the tx queue data structures after calling * the 802.11 layer as we'll get called back to reclaim @@ -1514,7 +1514,7 @@ ath5k_txq_setup(struct ath5k_softc *sc, /* * Enable interrupts only for EOL and DESC conditions. * We mark tx descriptors to receive a DESC interrupt - * when a tx queue gets deep; otherwise waiting for the + * when a tx queue gets deep; otherwise we wait for the * EOL to reap descriptors. Note that this is done to * reduce interrupt load and this only defers reaping * descriptors, never transmitting frames. Aside from @@ -1859,7 +1859,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) } /* - * Compute padding position. skb must contains an IEEE 802.11 frame + * Compute padding position. skb must contain an IEEE 802.11 frame */ static int ath5k_common_padpos(struct sk_buff *skb) { @@ -1878,10 +1878,9 @@ static int ath5k_common_padpos(struct sk_buff *skb) } /* - * This function expects a 802.11 frame and returns the number of - * bytes added, or -1 if we don't have enought header room. + * This function expects an 802.11 frame and returns the number of + * bytes added, or -1 if we don't have enough header room. */ - static int ath5k_add_padding(struct sk_buff *skb) { int padpos = ath5k_common_padpos(skb); @@ -1901,10 +1900,18 @@ static int ath5k_add_padding(struct sk_buff *skb) } /* - * This function expects a 802.11 frame and returns the number of - * bytes removed + * The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = 4 - (hdrlen & 3); however, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. We must not try to + * remove padding from short control frames that do not have a + * payload. + * + * This function expects an 802.11 frame and returns the number of + * bytes removed. */ - static int ath5k_remove_padding(struct sk_buff *skb) { int padpos = ath5k_common_padpos(skb); @@ -1925,14 +1932,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, { struct ieee80211_rx_status *rxs; - /* The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = (4 - hdrlen % 4) % 4; However, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. In addition, we must - * not try to remove padding from short control frames that do - * not have payload. */ ath5k_remove_padding(skb); rxs = IEEE80211_SKB_RXCB(skb); @@ -2281,10 +2280,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) * default antenna which is supposed to be an omni. * * Note2: On sectored scenarios it's possible to have - * multiple antennas (1omni -the default- and 14 sectors) - * so if we choose to actually support this mode we need - * to allow user to set how many antennas we have and tweak - * the code below to send beacons on all of them. + * multiple antennas (1 omni -- the default -- and 14 + * sectors), so if we choose to actually support this + * mode, we need to allow the user to set how many antennas + * we have and tweak the code below to send beacons + * on all of them. */ if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) antenna = sc->bsent & 4 ? 2 : 1; @@ -2333,7 +2333,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) } /* * Check if the previous beacon has gone out. If - * not don't don't try to post another, skip this + * not, don't don't try to post another: skip this * period and wait for the next. Missed beacons * indicate a problem and should not occur. If we * miss too many consecutive beacons reset the device. @@ -2905,8 +2905,8 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); /* - * the hardware expects the header padded to 4 byte boundaries - * if this is not the case we add the padding after the header + * The hardware expects the header padded to 4 byte boundaries. + * If this is not the case, we add the padding after the header. */ padsize = ath5k_add_padding(skb); if (padsize < 0) { @@ -3274,7 +3274,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, /* Set multicast bits */ ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); - /* Set the cached hw filter flags, this will alter actually + /* Set the cached hw filter flags, this will later actually * be set in HW */ sc->filter_flags = rfilt; diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 484f31870ba8..58bb6c5dda7b 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -377,11 +377,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) * * This function increases/decreases the tx trigger level for the tx fifo * buffer (aka FIFO threshold) that is used to indicate when PCU flushes - * the buffer and transmits it's data. Lowering this results sending small + * the buffer and transmits its data. Lowering this results sending small * frames more quickly but can lead to tx underruns, raising it a lot can * result other problems (i think bmiss is related). Right now we start with * the lowest possible (64Bytes) and if we get tx underrun we increase it using - * the increase flag. Returns -EIO if we have have reached maximum/minimum. + * the increase flag. Returns -EIO if we have reached maximum/minimum. * * XXX: Link this with tx DMA size ? * XXX: Use it to save interrupts ? diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index ae316fec4a6a..39722dd73e43 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -661,7 +661,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC * steps that match with the power values we read from eeprom. On * older eeprom versions (< 3.2) these steps are equaly spaced at - * 10% of the pcdac curve -until the curve reaches it's maximum- + * 10% of the pcdac curve -until the curve reaches its maximum- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) * these 11 steps are spaced in a different way. This function returns * the pcdac steps based on eeprom version and curve min/max so that we @@ -1113,7 +1113,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) */ /* For RF2413 power calibration data doesn't start on a fixed location and - * if a mode is not supported, it's section is missing -not zeroed-. + * if a mode is not supported, its section is missing -not zeroed-. * So we need to calculate the starting offset for each section by using * these two functions */ diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6284c389ba18..c7c446592374 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -115,7 +115,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, \**********************/ /* - * This code is used to optimize rf gain on different environments + * This code is used to optimize RF gain on different environments * (temperature mostly) based on feedback from a power detector. * * It's only used on RF5111 and RF5112, later RF chips seem to have @@ -302,7 +302,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) } /* Perform gain_F adjustment by choosing the right set - * of parameters from rf gain optimization ladder */ + * of parameters from RF gain optimization ladder */ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) { const struct ath5k_gain_opt *go; @@ -367,7 +367,7 @@ done: return ret; } -/* Main callback for thermal rf gain calibration engine +/* Main callback for thermal RF gain calibration engine * Check for a new gain reading and schedule an adjustment * if needed. * @@ -433,7 +433,7 @@ done: return ah->ah_gain.g_state; } -/* Write initial rf gain table to set the RF sensitivity +/* Write initial RF gain table to set the RF sensitivity * this one works on all RF chips and has nothing to do * with gain_F calibration */ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) @@ -496,7 +496,7 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) /* - * Setup RF registers by writing rf buffer on hw + * Setup RF registers by writing RF buffer on hw */ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode) @@ -571,7 +571,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - /* If it's the first time we set rf buffer, allocate + /* If it's the first time we set RF buffer, allocate * ah->ah_rf_banks based on ah->ah_rf_banks_size * we set above */ if (ah->ah_rf_banks == NULL) { @@ -3035,9 +3035,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); - /* FIXME: Tx power limit for this regdomain - * XXX: Mac80211/CRDA will do that anyway ? */ - /* FIXME: Antenna reduction stuff */ /* FIXME: Limit power on turbo modes */ diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 55b4ac6d236f..05ef587ad2b4 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -1911,7 +1911,7 @@ #define AR5K_PHY_TURBO 0x9804 /* Register Address */ #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ -#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ +#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */ /* * PHY agility command register diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index f5434eb7f980..4154959125b6 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -959,7 +959,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, AR5K_QUEUE_DCU_SEQNUM(0)); } - /* TSF accelerates on AR5211 durring reset + /* TSF accelerates on AR5211 during reset * As a workaround save it here and restore * it later so that it's back in time after * reset. This way it'll get re-synced on the @@ -1080,7 +1080,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, return ret; /* Spur info is available only from EEPROM versions - * bigger than 5.3 but but the EEPOM routines will use + * greater than 5.3, but the EEPROM routines will use * static values for older versions */ if (ah->ah_mac_srev >= AR5K_SREV_AR5424) ath5k_hw_set_spur_mitigation_filter(ah, @@ -1173,11 +1173,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* Set RSSI/BRSSI thresholds * * Note: If we decide to set this value - * dynamicaly, have in mind that when AR5K_RSSI_THR - * register is read it might return 0x40 if we haven't - * wrote anything to it plus BMISS RSSI threshold is zeroed. + * dynamically, keep in mind that when AR5K_RSSI_THR + * register is read, it might return 0x40 if we haven't + * written anything to it. Also, BMISS RSSI threshold is zeroed. * So doing a save/restore procedure here isn't the right - * choice. Instead store it on ath5k_hw */ + * choice. Instead, store it in ath5k_hw */ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S), @@ -1235,7 +1235,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* * Perform ADC test to see if baseband is ready - * Set tx hold and check adc test register + * Set TX hold and check ADC test register */ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); @@ -1254,15 +1254,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * * This method is used to calibrate some static offsets * used together with on-the fly I/Q calibration (the - * one performed via ath5k_hw_phy_calibrate), that doesn't + * one performed via ath5k_hw_phy_calibrate), which doesn't * interrupt rx path. * * While rx path is re-routed to the power detector we also - * start a noise floor calibration, to measure the + * start a noise floor calibration to measure the * card's noise floor (the noise we measure when we are not - * transmiting or receiving anything). + * transmitting or receiving anything). * - * If we are in a noisy environment AGC calibration may time + * If we are in a noisy environment, AGC calibration may time * out and/or noise floor calibration might timeout. */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index e50baff66175..3ac4cff4239d 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h @@ -25,10 +25,10 @@ * * We don't write on those registers directly but * we send a data packet on the chip, using a special register, - * that holds all the settings we need. After we 've sent the + * that holds all the settings we need. After we've sent the * data packet, we write on another special register to notify hw * to apply the settings. This is done so that control registers - * can be dynamicaly programmed during operation and the settings + * can be dynamically programmed during operation and the settings * are applied faster on the hw. * * We call each data packet an "RF Bank" and all the data we write -- cgit v1.2.3 From 23538c268c834d73a2f3e65a06ea6bf218ba1a0e Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 15 Aug 2010 13:03:13 -0400 Subject: ath5k: remove monitor check in receive_frame_ok filter Monitor interfaces are never seen by the driver, so tests based on that opmode don't make sense. Also, we already pass all mic failure packets. Consequently this code is actually accepting any frames with just crypto errors and rejecting those with CRC, FIFO, and PHY errors for all interface types. Adjust the code and comment accordingly. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c3b614d2ef34..166029913884 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2035,9 +2035,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) return true; } - /* let crypto-error packets fall through in MNTR */ - if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || - sc->opmode != NL80211_IFTYPE_MONITOR) + /* reject any frames with non-crypto errors */ + if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) return false; } -- cgit v1.2.3 From 4afd89d9cf17df46c3cfa1eb744232e345b3b0e6 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 15 Aug 2010 13:03:14 -0400 Subject: ath5k: remove all mention of monitor iftype Monitor interfaces are never seen by the driver so these cases are never reached. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 166029913884..99d56c6f06f1 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2325,8 +2325,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); - if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || - sc->opmode == NL80211_IFTYPE_MONITOR)) { + if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) { ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); return; } @@ -2900,9 +2899,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, ath5k_debug_dump_skb(sc, skb, "TX ", 1); - if (sc->opmode == NL80211_IFTYPE_MONITOR) - ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); - /* * The hardware expects the header padded to 4 byte boundaries. * If this is not the case, we add the padding after the header. @@ -3048,7 +3044,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_MONITOR: sc->opmode = vif->type; break; default: @@ -3250,7 +3245,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, switch (sc->opmode) { case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_MONITOR: rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ | -- cgit v1.2.3 From 30bf4169ad163047f87a2555cb33aa55f5d5e2bc Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 15 Aug 2010 13:03:15 -0400 Subject: ath5k: don't enable probe request rx for STAs AR5K_RX_FILTER_PROBEREQ enables reception of probe requests, but the filter flag FIF_BCN_PRBRESP_PROMISC is actually about receiving beacons and probe _responses_, so we shouldn't turn on the filter when scanning. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 99d56c6f06f1..f2fceb10c9fc 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3227,9 +3227,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, rfilt |= AR5K_RX_FILTER_PHYERR; /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons - * and probes for any BSSID, this needs testing */ + * and probes for any BSSID */ if (*new_flags & FIF_BCN_PRBRESP_PROMISC) - rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ; + rfilt |= AR5K_RX_FILTER_BEACON; /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not * set we should only pass on control frames for this -- cgit v1.2.3 From 9f19fa62edd2c397ed41c2dba29fb9f7144cb918 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Aug 2010 18:25:21 +0200 Subject: drivers/net/wireless/wl12xx: Use available error codes In each case, error codes are stored in ret, but the return value is always 0. Return ret instead. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ local idexpression x; constant C; @@ if (...) { ... x = -C ... when != x ( return <+...x...+>; | return NULL; | return; | * return ...; ) } // Signed-off-by: Julia Lawall Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_acx.c | 2 +- drivers/net/wireless/wl12xx/wl1251_cmd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c index 91891f928070..2f8a2ba744dc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl12xx/wl1251_acx.c @@ -380,7 +380,7 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl) out: kfree(pd); - return 0; + return ret; } int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time) diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c index ce3722f4c3e3..15fb68c6b542 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c @@ -200,7 +200,7 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, out: kfree(vbm); - return 0; + return ret; } int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) -- cgit v1.2.3 From 36d344131c154c0fb7dd6a3703fc1b29c56a75a1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 16 Aug 2010 18:27:30 +0200 Subject: drivers/net/wireless/wl12xx: Use available error codes Error codes are stored in ret, but the return value is always 0. Return ret instead. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ local idexpression x; constant C; @@ if (...) { ... x = -C ... when != x ( return <+...x...+>; | return NULL; | return; | * return ...; ) } // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_acx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index bb245f05af49..f03ad088db8b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -269,7 +269,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl) out: kfree(pd); - return 0; + return ret; } int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time) -- cgit v1.2.3 From 0975cc8fbf5b61b188734f2edd9e588c7edff2a1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 31 Jul 2010 08:34:07 -0700 Subject: iwlwifi: separate thermal throttling function "Thermal Throttling" is an advance feature which only available for newer _agn devices. Move from iwl-core to iwl-agn for better code organization. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-1000.c | 5 + drivers/net/wireless/iwlwifi/iwl-5000.c | 10 + drivers/net/wireless/iwlwifi/iwl-6000.c | 5 + drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 696 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-tt.h | 129 ++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 46 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 48 --- drivers/net/wireless/iwlwifi/iwl-core.h | 10 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-power.c | 640 +-------------------------- drivers/net/wireless/iwlwifi/iwl-power.h | 93 ---- drivers/net/wireless/iwlwifi/iwl-tx.c | 9 +- 13 files changed, 917 insertions(+), 776 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-tt.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-tt.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 728bb858ba97..493163925a45 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o +iwlagn-objs += iwl-agn-tt.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index fec026212326..f687a190f917 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -229,6 +229,11 @@ static struct iwl_lib_ops iwl1000_lib = { .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index aacf3770f075..54083a39c724 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -405,6 +405,11 @@ static struct iwl_lib_ops iwl5000_lib = { .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static struct iwl_lib_ops iwl5150_lib = { @@ -470,6 +475,11 @@ static struct iwl_lib_ops iwl5150_lib = { .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af4fd50f3405..7902de172a38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -330,6 +330,11 @@ static struct iwl_lib_ops iwl6000_lib = { .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static const struct iwl_ops iwl6000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c new file mode 100644 index 000000000000..30298ea56a24 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -0,0 +1,696 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-commands.h" +#include "iwl-debug.h" +#include "iwl-agn-tt.h" + +/* default Thermal Throttling transaction table + * Current state | Throttling Down | Throttling Up + *============================================================================= + * Condition Nxt State Condition Nxt State Condition Nxt State + *----------------------------------------------------------------------------- + * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A + * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 + * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 + * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 + *============================================================================= + */ +static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104}, + {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95}, + {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD}, + {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}, + {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX} +}; + +/* Advance Thermal Throttling default restriction table */ +static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = { + {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true }, + {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true }, + {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false }, + {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false } +}; + +bool iwl_tt_is_low_power_state(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (tt->state >= IWL_TI_1) + return true; + return false; +} + +u8 iwl_tt_current_power_mode(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + return tt->tt_power_mode; +} + +bool iwl_ht_enabled(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return true; + restriction = tt->restriction + tt->state; + return restriction->is_ht; +} + +static bool iwl_within_ct_kill_margin(struct iwl_priv *priv) +{ + s32 temp = priv->temperature; /* degrees CELSIUS except specified */ + bool within_margin = false; + + if (priv->cfg->temperature_kelvin) + temp = KELVIN_TO_CELSIUS(priv->temperature); + + if (!priv->thermal_throttle.advanced_tt) + within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= + CT_KILL_THRESHOLD_LEGACY) ? true : false; + else + within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= + CT_KILL_THRESHOLD) ? true : false; + return within_margin; +} + +bool iwl_check_for_ct_kill(struct iwl_priv *priv) +{ + bool is_ct_kill = false; + + if (iwl_within_ct_kill_margin(priv)) { + iwl_tt_enter_ct_kill(priv); + is_ct_kill = true; + } + return is_ct_kill; +} + +enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return IWL_ANT_OK_MULTI; + restriction = tt->restriction + tt->state; + return restriction->tx_stream; +} + +enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return IWL_ANT_OK_MULTI; + restriction = tt->restriction + tt->state; + return restriction->rx_stream; +} + +#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ +#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */ + +/* + * toggle the bit to wake up uCode and check the temperature + * if the temperature is below CT, uCode will stay awake and send card + * state notification with CT_KILL bit clear to inform Thermal Throttling + * Management to change state. Otherwise, uCode will go back to sleep + * without doing anything, driver should continue the 5 seconds timer + * to wake up uCode for temperature check until temperature drop below CT + */ +static void iwl_tt_check_exit_ct_kill(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + unsigned long flags; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (tt->state == IWL_TI_CT_KILL) { + if (priv->thermal_throttle.ct_kill_toggle) { + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + priv->thermal_throttle.ct_kill_toggle = false; + } else { + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + priv->thermal_throttle.ct_kill_toggle = true; + } + iwl_read32(priv, CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + + /* Reschedule the ct_kill timer to occur in + * CT_KILL_EXIT_DURATION seconds to ensure we get a + * thermal update */ + IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); + mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, + jiffies + CT_KILL_EXIT_DURATION * HZ); + } +} + +static void iwl_perform_ct_kill_task(struct iwl_priv *priv, + bool stop) +{ + if (stop) { + IWL_DEBUG_POWER(priv, "Stop all queues\n"); + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + IWL_DEBUG_POWER(priv, + "Schedule 5 seconds CT_KILL Timer\n"); + mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, + jiffies + CT_KILL_EXIT_DURATION * HZ); + } else { + IWL_DEBUG_POWER(priv, "Wake all queues\n"); + if (priv->mac80211_registered) + ieee80211_wake_queues(priv->hw); + } +} + +static void iwl_tt_ready_for_ct_kill(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* temperature timer expired, ready to go into CT_KILL state */ + if (tt->state != IWL_TI_CT_KILL) { + IWL_DEBUG_POWER(priv, "entering CT_KILL state when " + "temperature timer expired\n"); + tt->state = IWL_TI_CT_KILL; + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } +} + +static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) +{ + IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); + /* make request to retrieve statistics information */ + iwl_send_statistics_request(priv, CMD_SYNC, false); + /* Reschedule the ct_kill wait timer */ + mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, + jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); +} + +#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY) +#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100) +#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90) + +/* + * Legacy thermal throttling + * 1) Avoid NIC destruction due to high temperatures + * Chip will identify dangerously high temperatures that can + * harm the device and will power down + * 2) Avoid the NIC power down due to high temperature + * Throttle early enough to lower the power consumption before + * drastic steps are needed + */ +static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + enum iwl_tt_state old_state; + +#ifdef CONFIG_IWLWIFI_DEBUG + if ((tt->tt_previous_temp) && + (temp > tt->tt_previous_temp) && + ((temp - tt->tt_previous_temp) > + IWL_TT_INCREASE_MARGIN)) { + IWL_DEBUG_POWER(priv, + "Temperature increase %d degree Celsius\n", + (temp - tt->tt_previous_temp)); + } +#endif + old_state = tt->state; + /* in Celsius */ + if (temp >= IWL_MINIMAL_POWER_THRESHOLD) + tt->state = IWL_TI_CT_KILL; + else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2) + tt->state = IWL_TI_2; + else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1) + tt->state = IWL_TI_1; + else + tt->state = IWL_TI_0; + +#ifdef CONFIG_IWLWIFI_DEBUG + tt->tt_previous_temp = temp; +#endif + /* stop ct_kill_waiting_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + if (tt->state != old_state) { + switch (tt->state) { + case IWL_TI_0: + /* + * When the system is ready to go back to IWL_TI_0 + * we only have to call iwl_power_update_mode() to + * do so. + */ + break; + case IWL_TI_1: + tt->tt_power_mode = IWL_POWER_INDEX_3; + break; + case IWL_TI_2: + tt->tt_power_mode = IWL_POWER_INDEX_4; + break; + default: + tt->tt_power_mode = IWL_POWER_INDEX_5; + break; + } + mutex_lock(&priv->mutex); + if (old_state == IWL_TI_CT_KILL) + clear_bit(STATUS_CT_KILL, &priv->status); + if (tt->state != IWL_TI_CT_KILL && + iwl_power_update_mode(priv, true)) { + /* TT state not updated + * try again during next temperature read + */ + if (old_state == IWL_TI_CT_KILL) + set_bit(STATUS_CT_KILL, &priv->status); + tt->state = old_state; + IWL_ERR(priv, "Cannot update power mode, " + "TT state not updated\n"); + } else { + if (tt->state == IWL_TI_CT_KILL) { + if (force) { + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } else { + iwl_prepare_ct_kill_task(priv); + tt->state = old_state; + } + } else if (old_state == IWL_TI_CT_KILL && + tt->state != IWL_TI_CT_KILL) + iwl_perform_ct_kill_task(priv, false); + IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", + tt->state); + IWL_DEBUG_POWER(priv, "Power Index change to %u\n", + tt->tt_power_mode); + } + mutex_unlock(&priv->mutex); + } +} + +/* + * Advance thermal throttling + * 1) Avoid NIC destruction due to high temperatures + * Chip will identify dangerously high temperatures that can + * harm the device and will power down + * 2) Avoid the NIC power down due to high temperature + * Throttle early enough to lower the power consumption before + * drastic steps are needed + * Actions include relaxing the power down sleep thresholds and + * decreasing the number of TX streams + * 3) Avoid throughput performance impact as much as possible + * + *============================================================================= + * Condition Nxt State Condition Nxt State Condition Nxt State + *----------------------------------------------------------------------------- + * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A + * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 + * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 + * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 + *============================================================================= + */ +static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + int i; + bool changed = false; + enum iwl_tt_state old_state; + struct iwl_tt_trans *transaction; + + old_state = tt->state; + for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) { + /* based on the current TT state, + * find the curresponding transaction table + * each table has (IWL_TI_STATE_MAX - 1) entries + * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1)) + * will advance to the correct table. + * then based on the current temperature + * find the next state need to transaction to + * go through all the possible (IWL_TI_STATE_MAX - 1) entries + * in the current table to see if transaction is needed + */ + transaction = tt->transaction + + ((old_state * (IWL_TI_STATE_MAX - 1)) + i); + if (temp >= transaction->tt_low && + temp <= transaction->tt_high) { +#ifdef CONFIG_IWLWIFI_DEBUG + if ((tt->tt_previous_temp) && + (temp > tt->tt_previous_temp) && + ((temp - tt->tt_previous_temp) > + IWL_TT_INCREASE_MARGIN)) { + IWL_DEBUG_POWER(priv, + "Temperature increase %d " + "degree Celsius\n", + (temp - tt->tt_previous_temp)); + } + tt->tt_previous_temp = temp; +#endif + if (old_state != + transaction->next_state) { + changed = true; + tt->state = + transaction->next_state; + } + break; + } + } + /* stop ct_kill_waiting_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + if (changed) { + struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + + if (tt->state >= IWL_TI_1) { + /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ + tt->tt_power_mode = IWL_POWER_INDEX_5; + if (!iwl_ht_enabled(priv)) + /* disable HT */ + rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | + RXON_FLG_HT40_PROT_MSK | + RXON_FLG_HT_PROT_MSK); + else { + /* check HT capability and set + * according to the system HT capability + * in case get disabled before */ + iwl_set_rxon_ht(priv, &priv->current_ht_config); + } + + } else { + /* + * restore system power setting -- it will be + * recalculated automatically. + */ + + /* check HT capability and set + * according to the system HT capability + * in case get disabled before */ + iwl_set_rxon_ht(priv, &priv->current_ht_config); + } + mutex_lock(&priv->mutex); + if (old_state == IWL_TI_CT_KILL) + clear_bit(STATUS_CT_KILL, &priv->status); + if (tt->state != IWL_TI_CT_KILL && + iwl_power_update_mode(priv, true)) { + /* TT state not updated + * try again during next temperature read + */ + IWL_ERR(priv, "Cannot update power mode, " + "TT state not updated\n"); + if (old_state == IWL_TI_CT_KILL) + set_bit(STATUS_CT_KILL, &priv->status); + tt->state = old_state; + } else { + IWL_DEBUG_POWER(priv, + "Thermal Throttling to new state: %u\n", + tt->state); + if (old_state != IWL_TI_CT_KILL && + tt->state == IWL_TI_CT_KILL) { + if (force) { + IWL_DEBUG_POWER(priv, + "Enter IWL_TI_CT_KILL\n"); + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } else { + iwl_prepare_ct_kill_task(priv); + tt->state = old_state; + } + } else if (old_state == IWL_TI_CT_KILL && + tt->state != IWL_TI_CT_KILL) { + IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); + iwl_perform_ct_kill_task(priv, false); + } + } + mutex_unlock(&priv->mutex); + } +} + +/* Card State Notification indicated reach critical temperature + * if PSP not enable, no Thermal Throttling function will be performed + * just set the GP1 bit to acknowledge the event + * otherwise, go into IWL_TI_CT_KILL state + * since Card State Notification will not provide any temperature reading + * for Legacy mode + * so just pass the CT_KILL temperature to iwl_legacy_tt_handler() + * for advance mode + * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state + */ +static void iwl_bg_ct_enter(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_is_ready(priv)) + return; + + if (tt->state != IWL_TI_CT_KILL) { + IWL_ERR(priv, "Device reached critical temperature " + "- ucode going to sleep!\n"); + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, + IWL_MINIMAL_POWER_THRESHOLD, + true); + else + iwl_advance_tt_handler(priv, + CT_KILL_THRESHOLD + 1, true); + } +} + +/* Card State Notification indicated out of critical temperature + * since Card State Notification will not provide any temperature reading + * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature + * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state + */ +static void iwl_bg_ct_exit(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_is_ready(priv)) + return; + + /* stop ct_kill_exit_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); + + if (tt->state == IWL_TI_CT_KILL) { + IWL_ERR(priv, + "Device temperature below critical" + "- ucode awake!\n"); + /* + * exit from CT_KILL state + * reset the current temperature reading + */ + priv->temperature = 0; + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, + IWL_REDUCED_PERFORMANCE_THRESHOLD_2, + true); + else + iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD, + true); + } +} + +void iwl_tt_enter_ct_kill(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); + queue_work(priv->workqueue, &priv->ct_enter); +} +EXPORT_SYMBOL(iwl_tt_enter_ct_kill); + +void iwl_tt_exit_ct_kill(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); + queue_work(priv->workqueue, &priv->ct_exit); +} +EXPORT_SYMBOL(iwl_tt_exit_ct_kill); + +static void iwl_bg_tt_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); + s32 temp = priv->temperature; /* degrees CELSIUS except specified */ + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->cfg->temperature_kelvin) + temp = KELVIN_TO_CELSIUS(priv->temperature); + + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, temp, false); + else + iwl_advance_tt_handler(priv, temp, false); +} + +void iwl_tt_handler(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); + queue_work(priv->workqueue, &priv->tt_work); +} +EXPORT_SYMBOL(iwl_tt_handler); + +/* Thermal throttling initialization + * For advance thermal throttling: + * Initialize Thermal Index and temperature threshold table + * Initialize thermal throttling restriction table + */ +void iwl_tt_initialize(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); + struct iwl_tt_trans *transaction; + + IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); + + memset(tt, 0, sizeof(struct iwl_tt_mgmt)); + + tt->state = IWL_TI_0; + init_timer(&priv->thermal_throttle.ct_kill_exit_tm); + priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; + priv->thermal_throttle.ct_kill_exit_tm.function = + iwl_tt_check_exit_ct_kill; + init_timer(&priv->thermal_throttle.ct_kill_waiting_tm); + priv->thermal_throttle.ct_kill_waiting_tm.data = + (unsigned long)priv; + priv->thermal_throttle.ct_kill_waiting_tm.function = + iwl_tt_ready_for_ct_kill; + /* setup deferred ct kill work */ + INIT_WORK(&priv->tt_work, iwl_bg_tt_work); + INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); + INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); + + if (priv->cfg->adv_thermal_throttle) { + IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); + tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * + IWL_TI_STATE_MAX, GFP_KERNEL); + tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * + IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1), + GFP_KERNEL); + if (!tt->restriction || !tt->transaction) { + IWL_ERR(priv, "Fallback to Legacy Throttling\n"); + priv->thermal_throttle.advanced_tt = false; + kfree(tt->restriction); + tt->restriction = NULL; + kfree(tt->transaction); + tt->transaction = NULL; + } else { + transaction = tt->transaction + + (IWL_TI_0 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_0[0], size); + transaction = tt->transaction + + (IWL_TI_1 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_1[0], size); + transaction = tt->transaction + + (IWL_TI_2 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_2[0], size); + transaction = tt->transaction + + (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_3[0], size); + size = sizeof(struct iwl_tt_restriction) * + IWL_TI_STATE_MAX; + memcpy(tt->restriction, + &restriction_range[0], size); + priv->thermal_throttle.advanced_tt = true; + } + } else { + IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); + priv->thermal_throttle.advanced_tt = false; + } +} +EXPORT_SYMBOL(iwl_tt_initialize); + +/* cleanup thermal throttling management related memory and timer */ +void iwl_tt_exit(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + /* stop ct_kill_exit_tm timer if activated */ + del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); + /* stop ct_kill_waiting_tm timer if activated */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + cancel_work_sync(&priv->tt_work); + cancel_work_sync(&priv->ct_enter); + cancel_work_sync(&priv->ct_exit); + + if (priv->thermal_throttle.advanced_tt) { + /* free advance thermal throttling memory */ + kfree(tt->restriction); + tt->restriction = NULL; + kfree(tt->transaction); + tt->transaction = NULL; + } +} +EXPORT_SYMBOL(iwl_tt_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h new file mode 100644 index 000000000000..d55060427cac --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#ifndef __iwl_tt_setting_h__ +#define __iwl_tt_setting_h__ + +#include "iwl-commands.h" + +#define IWL_ABSOLUTE_ZERO 0 +#define IWL_ABSOLUTE_MAX 0xFFFFFFFF +#define IWL_TT_INCREASE_MARGIN 5 +#define IWL_TT_CT_KILL_MARGIN 3 + +enum iwl_antenna_ok { + IWL_ANT_OK_NONE, + IWL_ANT_OK_SINGLE, + IWL_ANT_OK_MULTI, +}; + +/* Thermal Throttling State Machine states */ +enum iwl_tt_state { + IWL_TI_0, /* normal temperature, system power state */ + IWL_TI_1, /* high temperature detect, low power state */ + IWL_TI_2, /* higher temperature detected, lower power state */ + IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */ + IWL_TI_STATE_MAX +}; + +/** + * struct iwl_tt_restriction - Thermal Throttling restriction table + * @tx_stream: number of tx stream allowed + * @is_ht: ht enable/disable + * @rx_stream: number of rx stream allowed + * + * This table is used by advance thermal throttling management + * based on the current thermal throttling state, and determines + * the number of tx/rx streams and the status of HT operation. + */ +struct iwl_tt_restriction { + enum iwl_antenna_ok tx_stream; + enum iwl_antenna_ok rx_stream; + bool is_ht; +}; + +/** + * struct iwl_tt_trans - Thermal Throttling transaction table + * @next_state: next thermal throttling mode + * @tt_low: low temperature threshold to change state + * @tt_high: high temperature threshold to change state + * + * This is used by the advanced thermal throttling algorithm + * to determine the next thermal state to go based on the + * current temperature. + */ +struct iwl_tt_trans { + enum iwl_tt_state next_state; + u32 tt_low; + u32 tt_high; +}; + +/** + * struct iwl_tt_mgnt - Thermal Throttling Management structure + * @advanced_tt: advanced thermal throttle required + * @state: current Thermal Throttling state + * @tt_power_mode: Thermal Throttling power mode index + * being used to set power level when + * when thermal throttling state != IWL_TI_0 + * the tt_power_mode should set to different + * power mode based on the current tt state + * @tt_previous_temperature: last measured temperature + * @iwl_tt_restriction: ptr to restriction tbl, used by advance + * thermal throttling to determine how many tx/rx streams + * should be used in tt state; and can HT be enabled or not + * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling + * state transaction + * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature + * @ct_kill_exit_tm: timer to exit thermal kill + */ +struct iwl_tt_mgmt { + enum iwl_tt_state state; + bool advanced_tt; + u8 tt_power_mode; + bool ct_kill_toggle; +#ifdef CONFIG_IWLWIFI_DEBUG + s32 tt_previous_temp; +#endif + struct iwl_tt_restriction *restriction; + struct iwl_tt_trans *transaction; + struct timer_list ct_kill_exit_tm; + struct timer_list ct_kill_waiting_tm; +}; + +u8 iwl_tt_current_power_mode(struct iwl_priv *priv); +bool iwl_tt_is_low_power_state(struct iwl_priv *priv); +bool iwl_ht_enabled(struct iwl_priv *priv); +bool iwl_check_for_ct_kill(struct iwl_priv *priv); +enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); +enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); +void iwl_tt_enter_ct_kill(struct iwl_priv *priv); +void iwl_tt_exit_ct_kill(struct iwl_priv *priv); +void iwl_tt_handler(struct iwl_priv *priv); +void iwl_tt_initialize(struct iwl_priv *priv); +void iwl_tt_exit(struct iwl_priv *priv); + +#endif /* __iwl_tt_setting_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 21a52ae05c0d..bce77eeb31c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2592,6 +2592,52 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } +static void iwl_rf_kill_ct_config(struct iwl_priv *priv) +{ + struct iwl_ct_kill_config cmd; + struct iwl_ct_kill_throttling_config adv_cmd; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + spin_unlock_irqrestore(&priv->lock, flags); + priv->thermal_throttle.ct_kill_toggle = false; + + if (priv->cfg->support_ct_kill_exit) { + adv_cmd.critical_temperature_enter = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + adv_cmd.critical_temperature_exit = + cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); + + ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(adv_cmd), &adv_cmd); + if (ret) + IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " + "succeeded, " + "critical temperature enter is %d," + "exit is %d\n", + priv->hw_params.ct_kill_threshold, + priv->hw_params.ct_kill_exit_threshold); + } else { + cmd.critical_temperature_R = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + + ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " + "succeeded, " + "critical temperature is %d\n", + priv->hw_params.ct_kill_threshold); + } +} + /** * iwl_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ccdf3c02bb3c..b5045c62de7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1514,54 +1514,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) } EXPORT_SYMBOL(iwl_send_statistics_request); -void iwl_rf_kill_ct_config(struct iwl_priv *priv) -{ - struct iwl_ct_kill_config cmd; - struct iwl_ct_kill_throttling_config adv_cmd; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - spin_unlock_irqrestore(&priv->lock, flags); - priv->thermal_throttle.ct_kill_toggle = false; - - if (priv->cfg->support_ct_kill_exit) { - adv_cmd.critical_temperature_enter = - cpu_to_le32(priv->hw_params.ct_kill_threshold); - adv_cmd.critical_temperature_exit = - cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); - - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(adv_cmd), &adv_cmd); - if (ret) - IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); - else - IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " - "succeeded, " - "critical temperature enter is %d," - "exit is %d\n", - priv->hw_params.ct_kill_threshold, - priv->hw_params.ct_kill_exit_threshold); - } else { - cmd.critical_temperature_R = - cpu_to_le32(priv->hw_params.ct_kill_threshold); - - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(cmd), &cmd); - if (ret) - IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); - else - IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " - "succeeded, " - "critical temperature is %d\n", - priv->hw_params.ct_kill_threshold); - } -} -EXPORT_SYMBOL(iwl_rf_kill_ct_config); - - /* * CARD_STATE_CMD * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7f1aaf206078..e6d127df01ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -136,6 +136,12 @@ struct iwl_temp_ops { void (*set_calib_version)(struct iwl_priv *priv); }; +struct iwl_tt_ops { + bool (*lower_power_detection)(struct iwl_priv *priv); + u8 (*tt_power_mode)(struct iwl_priv *priv); + bool (*ct_kill_check)(struct iwl_priv *priv); +}; + struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -212,6 +218,9 @@ struct iwl_lib_ops { void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); struct iwl_debugfs_ops debugfs_ops; + + /* thermal throttling */ + struct iwl_tt_ops tt_ops; }; struct iwl_led_ops { @@ -693,7 +702,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) return iwl_is_ready(priv); } -extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 149619fb1c07..a2927b3a606e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -47,6 +47,7 @@ #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" +#include "iwl-agn-tt.h" struct iwl_tx_queue; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index cda6a94d6cc9..da1f2ae24472 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -192,47 +192,6 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); } -/* default Thermal Throttling transaction table - * Current state | Throttling Down | Throttling Up - *============================================================================= - * Condition Nxt State Condition Nxt State Condition Nxt State - *----------------------------------------------------------------------------- - * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A - * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 - * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 - * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 - *============================================================================= - */ -static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104}, - {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95}, - {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD}, - {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}, - {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX} -}; - -/* Advance Thermal Throttling default restriction table */ -static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = { - {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true }, - {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true }, - {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false }, - {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false } -}; - - static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) { @@ -308,7 +267,6 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) int iwl_power_update_mode(struct iwl_priv *priv, bool force) { int ret = 0; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; bool update_chains; struct iwl_powertable_cmd cmd; @@ -325,9 +283,15 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) else if (priv->cfg->supports_idle && priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); - else if (tt->state >= IWL_TI_1) - iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper); - else if (!enabled) + else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && + priv->cfg->ops->lib->tt_ops.tt_power_mode) { + if (priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { + /* in thermal throttling low power state */ + iwl_static_sleep_cmd(priv, &cmd, + priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), + dtimper); + } + } else if (!enabled) iwl_power_sleep_cam_cmd(priv, &cmd); else if (priv->power_data.debug_sleep_level_override >= 0) iwl_static_sleep_cmd(priv, &cmd, @@ -367,592 +331,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) } EXPORT_SYMBOL(iwl_power_update_mode); -bool iwl_ht_enabled(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return true; - restriction = tt->restriction + tt->state; - return restriction->is_ht; -} -EXPORT_SYMBOL(iwl_ht_enabled); - -bool iwl_within_ct_kill_margin(struct iwl_priv *priv) -{ - s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - bool within_margin = false; - - if (priv->cfg->temperature_kelvin) - temp = KELVIN_TO_CELSIUS(priv->temperature); - - if (!priv->thermal_throttle.advanced_tt) - within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= - CT_KILL_THRESHOLD_LEGACY) ? true : false; - else - within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= - CT_KILL_THRESHOLD) ? true : false; - return within_margin; -} - -enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return IWL_ANT_OK_MULTI; - restriction = tt->restriction + tt->state; - return restriction->tx_stream; -} -EXPORT_SYMBOL(iwl_tx_ant_restriction); - -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return IWL_ANT_OK_MULTI; - restriction = tt->restriction + tt->state; - return restriction->rx_stream; -} - -#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ -#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */ - -/* - * toggle the bit to wake up uCode and check the temperature - * if the temperature is below CT, uCode will stay awake and send card - * state notification with CT_KILL bit clear to inform Thermal Throttling - * Management to change state. Otherwise, uCode will go back to sleep - * without doing anything, driver should continue the 5 seconds timer - * to wake up uCode for temperature check until temperature drop below CT - */ -static void iwl_tt_check_exit_ct_kill(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - unsigned long flags; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (tt->state == IWL_TI_CT_KILL) { - if (priv->thermal_throttle.ct_kill_toggle) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - priv->thermal_throttle.ct_kill_toggle = false; - } else { - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - priv->thermal_throttle.ct_kill_toggle = true; - } - iwl_read32(priv, CSR_UCODE_DRV_GP1); - spin_lock_irqsave(&priv->reg_lock, flags); - if (!iwl_grab_nic_access(priv)) - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, flags); - - /* Reschedule the ct_kill timer to occur in - * CT_KILL_EXIT_DURATION seconds to ensure we get a - * thermal update */ - IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); - mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + - CT_KILL_EXIT_DURATION * HZ); - } -} - -static void iwl_perform_ct_kill_task(struct iwl_priv *priv, - bool stop) -{ - if (stop) { - IWL_DEBUG_POWER(priv, "Stop all queues\n"); - if (priv->mac80211_registered) - ieee80211_stop_queues(priv->hw); - IWL_DEBUG_POWER(priv, - "Schedule 5 seconds CT_KILL Timer\n"); - mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + - CT_KILL_EXIT_DURATION * HZ); - } else { - IWL_DEBUG_POWER(priv, "Wake all queues\n"); - if (priv->mac80211_registered) - ieee80211_wake_queues(priv->hw); - } -} - -static void iwl_tt_ready_for_ct_kill(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* temperature timer expired, ready to go into CT_KILL state */ - if (tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "entering CT_KILL state when temperature timer expired\n"); - tt->state = IWL_TI_CT_KILL; - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } -} - -static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) -{ - IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); - /* make request to retrieve statistics information */ - iwl_send_statistics_request(priv, CMD_SYNC, false); - /* Reschedule the ct_kill wait timer */ - mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, - jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); -} - -#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY) -#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100) -#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90) - -/* - * Legacy thermal throttling - * 1) Avoid NIC destruction due to high temperatures - * Chip will identify dangerously high temperatures that can - * harm the device and will power down - * 2) Avoid the NIC power down due to high temperature - * Throttle early enough to lower the power consumption before - * drastic steps are needed - */ -static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - enum iwl_tt_state old_state; - -#ifdef CONFIG_IWLWIFI_DEBUG - if ((tt->tt_previous_temp) && - (temp > tt->tt_previous_temp) && - ((temp - tt->tt_previous_temp) > - IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, - "Temperature increase %d degree Celsius\n", - (temp - tt->tt_previous_temp)); - } -#endif - old_state = tt->state; - /* in Celsius */ - if (temp >= IWL_MINIMAL_POWER_THRESHOLD) - tt->state = IWL_TI_CT_KILL; - else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2) - tt->state = IWL_TI_2; - else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1) - tt->state = IWL_TI_1; - else - tt->state = IWL_TI_0; - -#ifdef CONFIG_IWLWIFI_DEBUG - tt->tt_previous_temp = temp; -#endif - /* stop ct_kill_waiting_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - if (tt->state != old_state) { - switch (tt->state) { - case IWL_TI_0: - /* - * When the system is ready to go back to IWL_TI_0 - * we only have to call iwl_power_update_mode() to - * do so. - */ - break; - case IWL_TI_1: - tt->tt_power_mode = IWL_POWER_INDEX_3; - break; - case IWL_TI_2: - tt->tt_power_mode = IWL_POWER_INDEX_4; - break; - default: - tt->tt_power_mode = IWL_POWER_INDEX_5; - break; - } - mutex_lock(&priv->mutex); - if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->status); - if (tt->state != IWL_TI_CT_KILL && - iwl_power_update_mode(priv, true)) { - /* TT state not updated - * try again during next temperature read - */ - if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->status); - tt->state = old_state; - IWL_ERR(priv, "Cannot update power mode, " - "TT state not updated\n"); - } else { - if (tt->state == IWL_TI_CT_KILL) { - if (force) { - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } else { - iwl_prepare_ct_kill_task(priv); - tt->state = old_state; - } - } else if (old_state == IWL_TI_CT_KILL && - tt->state != IWL_TI_CT_KILL) - iwl_perform_ct_kill_task(priv, false); - IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", - tt->state); - IWL_DEBUG_POWER(priv, "Power Index change to %u\n", - tt->tt_power_mode); - } - mutex_unlock(&priv->mutex); - } -} - -/* - * Advance thermal throttling - * 1) Avoid NIC destruction due to high temperatures - * Chip will identify dangerously high temperatures that can - * harm the device and will power down - * 2) Avoid the NIC power down due to high temperature - * Throttle early enough to lower the power consumption before - * drastic steps are needed - * Actions include relaxing the power down sleep thresholds and - * decreasing the number of TX streams - * 3) Avoid throughput performance impact as much as possible - * - *============================================================================= - * Condition Nxt State Condition Nxt State Condition Nxt State - *----------------------------------------------------------------------------- - * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A - * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 - * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 - * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 - *============================================================================= - */ -static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - int i; - bool changed = false; - enum iwl_tt_state old_state; - struct iwl_tt_trans *transaction; - - old_state = tt->state; - for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) { - /* based on the current TT state, - * find the curresponding transaction table - * each table has (IWL_TI_STATE_MAX - 1) entries - * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1)) - * will advance to the correct table. - * then based on the current temperature - * find the next state need to transaction to - * go through all the possible (IWL_TI_STATE_MAX - 1) entries - * in the current table to see if transaction is needed - */ - transaction = tt->transaction + - ((old_state * (IWL_TI_STATE_MAX - 1)) + i); - if (temp >= transaction->tt_low && - temp <= transaction->tt_high) { -#ifdef CONFIG_IWLWIFI_DEBUG - if ((tt->tt_previous_temp) && - (temp > tt->tt_previous_temp) && - ((temp - tt->tt_previous_temp) > - IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, - "Temperature increase %d " - "degree Celsius\n", - (temp - tt->tt_previous_temp)); - } - tt->tt_previous_temp = temp; -#endif - if (old_state != - transaction->next_state) { - changed = true; - tt->state = - transaction->next_state; - } - break; - } - } - /* stop ct_kill_waiting_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - if (changed) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; - - if (tt->state >= IWL_TI_1) { - /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ - tt->tt_power_mode = IWL_POWER_INDEX_5; - if (!iwl_ht_enabled(priv)) - /* disable HT */ - rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | - RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | - RXON_FLG_HT40_PROT_MSK | - RXON_FLG_HT_PROT_MSK); - else { - /* check HT capability and set - * according to the system HT capability - * in case get disabled before */ - iwl_set_rxon_ht(priv, &priv->current_ht_config); - } - - } else { - /* - * restore system power setting -- it will be - * recalculated automatically. - */ - - /* check HT capability and set - * according to the system HT capability - * in case get disabled before */ - iwl_set_rxon_ht(priv, &priv->current_ht_config); - } - mutex_lock(&priv->mutex); - if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->status); - if (tt->state != IWL_TI_CT_KILL && - iwl_power_update_mode(priv, true)) { - /* TT state not updated - * try again during next temperature read - */ - IWL_ERR(priv, "Cannot update power mode, " - "TT state not updated\n"); - if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->status); - tt->state = old_state; - } else { - IWL_DEBUG_POWER(priv, - "Thermal Throttling to new state: %u\n", - tt->state); - if (old_state != IWL_TI_CT_KILL && - tt->state == IWL_TI_CT_KILL) { - if (force) { - IWL_DEBUG_POWER(priv, - "Enter IWL_TI_CT_KILL\n"); - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } else { - iwl_prepare_ct_kill_task(priv); - tt->state = old_state; - } - } else if (old_state == IWL_TI_CT_KILL && - tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); - iwl_perform_ct_kill_task(priv, false); - } - } - mutex_unlock(&priv->mutex); - } -} - -/* Card State Notification indicated reach critical temperature - * if PSP not enable, no Thermal Throttling function will be performed - * just set the GP1 bit to acknowledge the event - * otherwise, go into IWL_TI_CT_KILL state - * since Card State Notification will not provide any temperature reading - * for Legacy mode - * so just pass the CT_KILL temperature to iwl_legacy_tt_handler() - * for advance mode - * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state - */ -static void iwl_bg_ct_enter(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!iwl_is_ready(priv)) - return; - - if (tt->state != IWL_TI_CT_KILL) { - IWL_ERR(priv, "Device reached critical temperature " - "- ucode going to sleep!\n"); - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, - IWL_MINIMAL_POWER_THRESHOLD, - true); - else - iwl_advance_tt_handler(priv, - CT_KILL_THRESHOLD + 1, true); - } -} - -/* Card State Notification indicated out of critical temperature - * since Card State Notification will not provide any temperature reading - * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature - * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state - */ -static void iwl_bg_ct_exit(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!iwl_is_ready(priv)) - return; - - /* stop ct_kill_exit_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); - - if (tt->state == IWL_TI_CT_KILL) { - IWL_ERR(priv, - "Device temperature below critical" - "- ucode awake!\n"); - /* - * exit from CT_KILL state - * reset the current temperature reading - */ - priv->temperature = 0; - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, - IWL_REDUCED_PERFORMANCE_THRESHOLD_2, - true); - else - iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD, - true); - } -} - -void iwl_tt_enter_ct_kill(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); - queue_work(priv->workqueue, &priv->ct_enter); -} -EXPORT_SYMBOL(iwl_tt_enter_ct_kill); - -void iwl_tt_exit_ct_kill(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); - queue_work(priv->workqueue, &priv->ct_exit); -} -EXPORT_SYMBOL(iwl_tt_exit_ct_kill); - -static void iwl_bg_tt_work(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); - s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (priv->cfg->temperature_kelvin) - temp = KELVIN_TO_CELSIUS(priv->temperature); - - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, temp, false); - else - iwl_advance_tt_handler(priv, temp, false); -} - -void iwl_tt_handler(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); - queue_work(priv->workqueue, &priv->tt_work); -} -EXPORT_SYMBOL(iwl_tt_handler); - -/* Thermal throttling initialization - * For advance thermal throttling: - * Initialize Thermal Index and temperature threshold table - * Initialize thermal throttling restriction table - */ -void iwl_tt_initialize(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); - struct iwl_tt_trans *transaction; - - IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); - - memset(tt, 0, sizeof(struct iwl_tt_mgmt)); - - tt->state = IWL_TI_0; - init_timer(&priv->thermal_throttle.ct_kill_exit_tm); - priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; - priv->thermal_throttle.ct_kill_exit_tm.function = - iwl_tt_check_exit_ct_kill; - init_timer(&priv->thermal_throttle.ct_kill_waiting_tm); - priv->thermal_throttle.ct_kill_waiting_tm.data = (unsigned long)priv; - priv->thermal_throttle.ct_kill_waiting_tm.function = - iwl_tt_ready_for_ct_kill; - /* setup deferred ct kill work */ - INIT_WORK(&priv->tt_work, iwl_bg_tt_work); - INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); - INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); - - if (priv->cfg->adv_thermal_throttle) { - IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); - tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * - IWL_TI_STATE_MAX, GFP_KERNEL); - tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * - IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1), - GFP_KERNEL); - if (!tt->restriction || !tt->transaction) { - IWL_ERR(priv, "Fallback to Legacy Throttling\n"); - priv->thermal_throttle.advanced_tt = false; - kfree(tt->restriction); - tt->restriction = NULL; - kfree(tt->transaction); - tt->transaction = NULL; - } else { - transaction = tt->transaction + - (IWL_TI_0 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_0[0], size); - transaction = tt->transaction + - (IWL_TI_1 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_1[0], size); - transaction = tt->transaction + - (IWL_TI_2 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_2[0], size); - transaction = tt->transaction + - (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_3[0], size); - size = sizeof(struct iwl_tt_restriction) * - IWL_TI_STATE_MAX; - memcpy(tt->restriction, - &restriction_range[0], size); - priv->thermal_throttle.advanced_tt = true; - } - } else { - IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); - priv->thermal_throttle.advanced_tt = false; - } -} -EXPORT_SYMBOL(iwl_tt_initialize); - -/* cleanup thermal throttling management related memory and timer */ -void iwl_tt_exit(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - /* stop ct_kill_exit_tm timer if activated */ - del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); - /* stop ct_kill_waiting_tm timer if activated */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - cancel_work_sync(&priv->tt_work); - cancel_work_sync(&priv->ct_enter); - cancel_work_sync(&priv->ct_exit); - - if (priv->thermal_throttle.advanced_tt) { - /* free advance thermal throttling memory */ - kfree(tt->restriction); - tt->restriction = NULL; - kfree(tt->transaction); - tt->transaction = NULL; - } -} -EXPORT_SYMBOL(iwl_tt_exit); - /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 5db91c10dcc8..df81565a7cc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -30,90 +30,6 @@ #include "iwl-commands.h" -#define IWL_ABSOLUTE_ZERO 0 -#define IWL_ABSOLUTE_MAX 0xFFFFFFFF -#define IWL_TT_INCREASE_MARGIN 5 -#define IWL_TT_CT_KILL_MARGIN 3 - -enum iwl_antenna_ok { - IWL_ANT_OK_NONE, - IWL_ANT_OK_SINGLE, - IWL_ANT_OK_MULTI, -}; - -/* Thermal Throttling State Machine states */ -enum iwl_tt_state { - IWL_TI_0, /* normal temperature, system power state */ - IWL_TI_1, /* high temperature detect, low power state */ - IWL_TI_2, /* higher temperature detected, lower power state */ - IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */ - IWL_TI_STATE_MAX -}; - -/** - * struct iwl_tt_restriction - Thermal Throttling restriction table - * @tx_stream: number of tx stream allowed - * @is_ht: ht enable/disable - * @rx_stream: number of rx stream allowed - * - * This table is used by advance thermal throttling management - * based on the current thermal throttling state, and determines - * the number of tx/rx streams and the status of HT operation. - */ -struct iwl_tt_restriction { - enum iwl_antenna_ok tx_stream; - enum iwl_antenna_ok rx_stream; - bool is_ht; -}; - -/** - * struct iwl_tt_trans - Thermal Throttling transaction table - * @next_state: next thermal throttling mode - * @tt_low: low temperature threshold to change state - * @tt_high: high temperature threshold to change state - * - * This is used by the advanced thermal throttling algorithm - * to determine the next thermal state to go based on the - * current temperature. - */ -struct iwl_tt_trans { - enum iwl_tt_state next_state; - u32 tt_low; - u32 tt_high; -}; - -/** - * struct iwl_tt_mgnt - Thermal Throttling Management structure - * @advanced_tt: advanced thermal throttle required - * @state: current Thermal Throttling state - * @tt_power_mode: Thermal Throttling power mode index - * being used to set power level when - * when thermal throttling state != IWL_TI_0 - * the tt_power_mode should set to different - * power mode based on the current tt state - * @tt_previous_temperature: last measured temperature - * @iwl_tt_restriction: ptr to restriction tbl, used by advance - * thermal throttling to determine how many tx/rx streams - * should be used in tt state; and can HT be enabled or not - * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling - * state transaction - * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature - * @ct_kill_exit_tm: timer to exit thermal kill - */ -struct iwl_tt_mgmt { - enum iwl_tt_state state; - bool advanced_tt; - u8 tt_power_mode; - bool ct_kill_toggle; -#ifdef CONFIG_IWLWIFI_DEBUG - s32 tt_previous_temp; -#endif - struct iwl_tt_restriction *restriction; - struct iwl_tt_trans *transaction; - struct timer_list ct_kill_exit_tm; - struct timer_list ct_kill_waiting_tm; -}; - enum iwl_power_level { IWL_POWER_INDEX_1, IWL_POWER_INDEX_2, @@ -130,15 +46,6 @@ struct iwl_power_mgr { }; int iwl_power_update_mode(struct iwl_priv *priv, bool force); -bool iwl_ht_enabled(struct iwl_priv *priv); -bool iwl_within_ct_kill_margin(struct iwl_priv *priv); -enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); -void iwl_tt_enter_ct_kill(struct iwl_priv *priv); -void iwl_tt_exit_ct_kill(struct iwl_priv *priv); -void iwl_tt_handler(struct iwl_priv *priv); -void iwl_tt_initialize(struct iwl_priv *priv); -void iwl_tt_exit(struct iwl_priv *priv); void iwl_power_initialize(struct iwl_priv *priv); extern bool no_sleep_autoadjust; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index a81989c06983..c308dab14673 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -422,6 +422,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int len; u32 idx; u16 fix_size; + bool is_ct_kill = false; cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); @@ -443,9 +444,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERR(priv, "No space in command queue\n"); - if (iwl_within_ct_kill_margin(priv)) - iwl_tt_enter_ct_kill(priv); - else { + if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { + is_ct_kill = + priv->cfg->ops->lib->tt_ops.ct_kill_check(priv); + } + if (!is_ct_kill) { IWL_ERR(priv, "Restarting adapter due to queue full\n"); queue_work(priv->workqueue, &priv->restart); } -- cgit v1.2.3 From e7f45d3ff8de9e936d870aba947b2e4ce88a1d1e Mon Sep 17 00:00:00 2001 From: Gábor Stefanik Date: Mon, 16 Aug 2010 22:39:14 +0200 Subject: b43: N-PHY: Implement Host Flags write during device init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gábor Stefanik Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 5a725703770c..cb815ccedfb3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1098,7 +1098,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) if (dev->phy.rev < 2) { if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) - ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ + b43_hf_write(dev, b43_hf_read(dev) | + B43_HF_MLADVW); } else if (dev->phy.rev == 2) { b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); -- cgit v1.2.3 From e723ef305c36785c08af9463b3a3ec369dfcedcb Mon Sep 17 00:00:00 2001 From: Gábor Stefanik Date: Mon, 16 Aug 2010 22:39:15 +0200 Subject: b43: N-PHY: Fix typo in function name (gain_crtl -> gain_ctrl) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gábor Stefanik Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index cb815ccedfb3..f1b57070ada9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -893,7 +893,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ -static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) +static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; u8 i, j; @@ -1094,7 +1094,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); - b43_nphy_gain_crtl_workarounds(dev); + b43_nphy_gain_ctrl_workarounds(dev); if (dev->phy.rev < 2) { if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) -- cgit v1.2.3 From d2730b2a6a019d14455556019d744ab051e6554b Mon Sep 17 00:00:00 2001 From: Gábor Stefanik Date: Mon, 16 Aug 2010 22:39:16 +0200 Subject: b43: N-PHY: Implement MAC PHY clock set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gábor Stefanik Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 13 ++++++++++++- include/linux/ssb/ssb_regs.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f1b57070ada9..d212726d509b 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3074,6 +3074,17 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev, return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ +static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on) +{ + u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); + if (on) + tmslow |= SSB_TMSLOW_PHYCLK; + else + tmslow &= ~SSB_TMSLOW_PHYCLK; + ssb_write32(dev->dev, SSB_TMSLOW, tmslow); +} + /* * Init N-PHY * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N @@ -3174,7 +3185,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); b43_nphy_bmac_clock_fgc(dev, 0); - /* TODO N PHY MAC PHY Clock Set with argument 1 */ + b43_nphy_mac_phy_clock_set(dev, true); b43_nphy_pa_override(dev, false); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index a6d5225b9275..11daf9c140e7 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -97,6 +97,7 @@ #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ +#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */ #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ #define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */ -- cgit v1.2.3 From 4e687b2226f47c656302b9c313bfe2ece85fe2ef Mon Sep 17 00:00:00 2001 From: Gábor Stefanik Date: Mon, 16 Aug 2010 22:39:17 +0200 Subject: b43: N-PHY: Implement RX core state setting for rev.2 and earlier PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rev.3+ support coming in a later patch. Signed-off-by: Gábor Stefanik Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d212726d509b..a0a6554a76d1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3085,6 +3085,44 @@ static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on) ssb_write32(dev->dev, SSB_TMSLOW, tmslow); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */ +static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = phy->n; + u16 buf[16]; + + if (0 /* FIXME clk */) + return; + + b43_mac_suspend(dev); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, + (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT); + + if (mask & 0x3 != 0x3) { + b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1); + if (dev->phy.rev >= 3) { + /* TODO */ + } + } else { + b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E); + if (dev->phy.rev >= 3) { + /* TODO */ + } + } + + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); + + b43_mac_enable(dev); +} + /* * Init N-PHY * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N @@ -3211,7 +3249,7 @@ int b43_phy_initn(struct b43_wldev *dev) } if (nphy->phyrxchain != 3) - ;/* TODO N PHY RX Core Set State with phyrxchain as argument */ + b43_nphy_set_rx_core_state(dev, nphy->phyrxchain); if (nphy->mphase_cal_phase_id > 0) ;/* TODO PHY Periodic Calibration Multi-Phase Restart */ -- cgit v1.2.3 From b9c066597fdf38b126d2e0434d0ce18d22bbf401 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 17 Aug 2010 01:16:05 +0200 Subject: p54spi: fix eeprom checksum This patch corrects the bogus descriptor checksum of our Nokia N8XX EEPROM blob. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi_eeprom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h index 1ea1050911d9..d592cbd34d78 100644 --- a/drivers/net/wireless/p54/p54spi_eeprom.h +++ b/drivers/net/wireless/p54/p54spi_eeprom.h @@ -671,7 +671,7 @@ static unsigned char p54spi_eeprom[] = { 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, /* PDR_END */ - 0xa8, 0xf5 /* bogus data */ + 0x67, 0x99, }; #endif /* P54SPI_EEPROM_H */ -- cgit v1.2.3 From d7eb50c0f7cb5d3ebb7bea8c681a6dfda3819a3b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 17 Aug 2010 01:16:58 +0200 Subject: p54: improve eeprom parser Like other vendors, p54* devices have a checksum for the EEPROM descriptor data. This patch enhances the parser code to generate and verify the data fields, before initializing the radio-chip on the card. Note: If you have to bootstrap an alternative EEPROM image for your device and you don't know how to generate a valid crc ccitt checksum, you should take a look at: http://git.kernel.org/?p=linux/kernel/git/chr/p54tools.git The "checksum" utility loads a binary p54 EEPROM blob (use the -f switch, to skip the check) and applies the correct crc automatically. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/Kconfig | 1 + drivers/net/wireless/p54/eeprom.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index b0342a520bf1..60a930e45a8b 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig @@ -2,6 +2,7 @@ config P54_COMMON tristate "Softmac Prism54 support" depends on MAC80211 && EXPERIMENTAL select FW_LOADER + select CRC_CCITT ---help--- This is common code for isl38xx/stlc45xx based modules. This module does nothing by itself - the USB/PCI/SPI front-ends diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index d687cb7f2a59..32d3f99b0844 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -23,6 +23,7 @@ #include #include +#include #include "p54.h" #include "eeprom.h" @@ -540,6 +541,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) int err; u8 *end = (u8 *)eeprom + len; u16 synth = 0; + u16 crc16 = ~0; wrap = (struct eeprom_pda_wrap *) eeprom; entry = (void *)wrap->data + le16_to_cpu(wrap->len); @@ -655,16 +657,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) } break; case PDR_END: - /* make it overrun */ - entry_len = len; + crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry)); + if (crc16 != le16_to_cpup((__le16 *)entry->data)) { + wiphy_err(dev->wiphy, "eeprom failed checksum " + "test!\n"); + err = -ENOMSG; + goto err; + } else { + goto good_eeprom; + } break; default: break; } - entry = (void *)entry + (entry_len + 1)*2; + crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2); + entry = (void *)entry + (entry_len + 1) * 2; } + wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n"); + err = -ENODATA; + goto err; + +good_eeprom: if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { wiphy_err(dev->wiphy, -- cgit v1.2.3 From 352de5573f60af0ab054859931cfb68eecb1832b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 17 Aug 2010 12:04:34 +0200 Subject: wireless: move documentation books This moves mac80211 documentation into a new 802.11 bookset and also adds a cfg80211 book to the set. All of this is rather incomplete, but it's easier to work with big code moving as a separate patch. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 371 ++++++++++++++++++++++++++++++++++++ Documentation/DocBook/Makefile | 2 +- Documentation/DocBook/mac80211.tmpl | 337 -------------------------------- 3 files changed, 372 insertions(+), 338 deletions(-) create mode 100644 Documentation/DocBook/80211.tmpl delete mode 100644 Documentation/DocBook/mac80211.tmpl diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl new file mode 100644 index 000000000000..6f88e184d2e7 --- /dev/null +++ b/Documentation/DocBook/80211.tmpl @@ -0,0 +1,371 @@ + + + + + The 802.11 subsystems – for kernel developers + + Explaining wireless 802.11 networking in the Linux kernel + + + + 2007-2009 + Johannes Berg + + + + + Johannes + Berg + +
johannes@sipsolutions.net
+
+
+
+ + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + + This documentation is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + You should have received a copy of the GNU General Public + License along with this documentation; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + For more details see the file COPYING in the source + distribution of Linux. + + + + + + These books attempt to give a description of the + various subsystems that play a role in 802.11 wireless + networking in Linux. Since these books are for kernel + developers they attempts to document the structures + and functions used in the kernel as well as giving a + higher-level overview. + + + The reader is expected to be familiar with the 802.11 + standard as published by the IEEE in 802.11-2007 (or + possibly later versions). References to this standard + will be given as "802.11-2007 8.1.5". + + +
+ + + The cfg80211 subsystem + + + +MISSING + + + + +!Finclude/net/cfg80211.h ieee80211_band + + + + + The mac80211 subsystem + +!Pinclude/net/mac80211.h Introduction +!Pinclude/net/mac80211.h Warning + + + + + + + + + The basic mac80211 driver interface + + + You should read and understand the information contained + within this part of the book while implementing a driver. + In some chapters, advanced usage is noted, that may be + skipped at first. + + + This part of the book only covers station and monitor mode + functionality, additional information required to implement + the other modes is covered in the second part of the book. + + + + + Basic hardware handling + TBD + + This chapter shall contain information on getting a hw + struct allocated and registered with mac80211. + + + Since it is required to allocate rates/modes before registering + a hw struct, this chapter shall also contain information on setting + up the rate/mode structs. + + + Additionally, some discussion about the callbacks and + the general programming model should be in here, including + the definition of ieee80211_ops which will be referred to + a lot. + + + Finally, a discussion of hardware capabilities should be done + with references to other parts of the book. + + +!Finclude/net/mac80211.h ieee80211_hw +!Finclude/net/mac80211.h ieee80211_hw_flags +!Finclude/net/mac80211.h SET_IEEE80211_DEV +!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR +!Finclude/net/mac80211.h ieee80211_ops +!Finclude/net/mac80211.h ieee80211_alloc_hw +!Finclude/net/mac80211.h ieee80211_register_hw +!Finclude/net/mac80211.h ieee80211_get_tx_led_name +!Finclude/net/mac80211.h ieee80211_get_rx_led_name +!Finclude/net/mac80211.h ieee80211_get_assoc_led_name +!Finclude/net/mac80211.h ieee80211_get_radio_led_name +!Finclude/net/mac80211.h ieee80211_unregister_hw +!Finclude/net/mac80211.h ieee80211_free_hw + + + + PHY configuration + TBD + + This chapter should describe PHY handling including + start/stop callbacks and the various structures used. + +!Finclude/net/mac80211.h ieee80211_conf +!Finclude/net/mac80211.h ieee80211_conf_flags + + + + Virtual interfaces + TBD + + This chapter should describe virtual interface basics + that are relevant to the driver (VLANs, MGMT etc are not.) + It should explain the use of the add_iface/remove_iface + callbacks as well as the interface configuration callbacks. + + Things related to AP mode should be discussed there. + + Things related to supporting multiple interfaces should be + in the appropriate chapter, a BIG FAT note should be here about + this though and the recommendation to allow only a single + interface in STA mode at first! + +!Finclude/net/mac80211.h ieee80211_vif + + + + Receive and transmit processing + + what should be here + TBD + + This should describe the receive and transmit + paths in mac80211/the drivers as well as + transmit status handling. + + + + Frame format +!Pinclude/net/mac80211.h Frame format + + + Packet alignment +!Pnet/mac80211/rx.c Packet alignment + + + Calling into mac80211 from interrupts +!Pinclude/net/mac80211.h Calling mac80211 from interrupts + + + functions/definitions +!Finclude/net/mac80211.h ieee80211_rx_status +!Finclude/net/mac80211.h mac80211_rx_flags +!Finclude/net/mac80211.h ieee80211_tx_info +!Finclude/net/mac80211.h ieee80211_rx +!Finclude/net/mac80211.h ieee80211_rx_irqsafe +!Finclude/net/mac80211.h ieee80211_tx_status +!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe +!Finclude/net/mac80211.h ieee80211_rts_get +!Finclude/net/mac80211.h ieee80211_rts_duration +!Finclude/net/mac80211.h ieee80211_ctstoself_get +!Finclude/net/mac80211.h ieee80211_ctstoself_duration +!Finclude/net/mac80211.h ieee80211_generic_frame_duration +!Finclude/net/mac80211.h ieee80211_wake_queue +!Finclude/net/mac80211.h ieee80211_stop_queue +!Finclude/net/mac80211.h ieee80211_wake_queues +!Finclude/net/mac80211.h ieee80211_stop_queues + + + + + Frame filtering +!Pinclude/net/mac80211.h Frame filtering +!Finclude/net/mac80211.h ieee80211_filter_flags + + + + + Advanced driver interface + + + Information contained within this part of the book is + of interest only for advanced interaction of mac80211 + with drivers to exploit more hardware capabilities and + improve performance. + + + + + Hardware crypto acceleration +!Pinclude/net/mac80211.h Hardware crypto acceleration + +!Finclude/net/mac80211.h set_key_cmd +!Finclude/net/mac80211.h ieee80211_key_conf +!Finclude/net/mac80211.h ieee80211_key_alg +!Finclude/net/mac80211.h ieee80211_key_flags + + + + Powersave support +!Pinclude/net/mac80211.h Powersave support + + + + Beacon filter support +!Pinclude/net/mac80211.h Beacon filter support +!Finclude/net/mac80211.h ieee80211_beacon_loss + + + + Multiple queues and QoS support + TBD +!Finclude/net/mac80211.h ieee80211_tx_queue_params + + + + Access point mode support + TBD + Some parts of the if_conf should be discussed here instead + + Insert notes about VLAN interfaces with hw crypto here or + in the hw crypto chapter. + +!Finclude/net/mac80211.h ieee80211_get_buffered_bc +!Finclude/net/mac80211.h ieee80211_beacon_get + + + + Supporting multiple virtual interfaces + TBD + + Note: WDS with identical MAC address should almost always be OK + + + Insert notes about having multiple virtual interfaces with + different MAC addresses here, note which configurations are + supported by mac80211, add notes about supporting hw crypto + with it. + + + + + Hardware scan offload + TBD +!Finclude/net/mac80211.h ieee80211_scan_completed + + + + + Rate control interface + + TBD + + This part of the book describes the rate control algorithm + interface and how it relates to mac80211 and drivers. + + + + dummy chapter + TBD + + + + + Internals + + TBD + + This part of the book describes mac80211 internals. + + + + + Key handling + + Key handling basics +!Pnet/mac80211/key.c Key handling basics + + + MORE TBD + TBD + + + + + Receive processing + TBD + + + + Transmit processing + TBD + + + + Station info handling + + Programming information +!Fnet/mac80211/sta_info.h sta_info +!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags + + + STA information lifetime rules +!Pnet/mac80211/sta_info.c STA information lifetime rules + + + + + Synchronisation + TBD + Locking, lots of RCU + + + +
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index c7e5dc7e8cb3..b6f2ba2f36b7 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ - mac80211.xml debugobjects.xml sh.xml regulator.xml \ + 80211.xml debugobjects.xml sh.xml regulator.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \ tracepoint.xml media.xml drm.xml diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl deleted file mode 100644 index affb15a344a1..000000000000 --- a/Documentation/DocBook/mac80211.tmpl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - The mac80211 subsystem for kernel developers - - - - Johannes - Berg - -
johannes@sipsolutions.net
-
-
-
- - - 2007-2009 - Johannes Berg - - - - - This documentation is free software; you can redistribute - it and/or modify it under the terms of the GNU General Public - License version 2 as published by the Free Software Foundation. - - - - This documentation is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - - - You should have received a copy of the GNU General Public - License along with this documentation; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, - MA 02111-1307 USA - - - - For more details see the file COPYING in the source - distribution of Linux. - - - - -!Pinclude/net/mac80211.h Introduction -!Pinclude/net/mac80211.h Warning - -
- - - - - - - The basic mac80211 driver interface - - - You should read and understand the information contained - within this part of the book while implementing a driver. - In some chapters, advanced usage is noted, that may be - skipped at first. - - - This part of the book only covers station and monitor mode - functionality, additional information required to implement - the other modes is covered in the second part of the book. - - - - - Basic hardware handling - TBD - - This chapter shall contain information on getting a hw - struct allocated and registered with mac80211. - - - Since it is required to allocate rates/modes before registering - a hw struct, this chapter shall also contain information on setting - up the rate/mode structs. - - - Additionally, some discussion about the callbacks and - the general programming model should be in here, including - the definition of ieee80211_ops which will be referred to - a lot. - - - Finally, a discussion of hardware capabilities should be done - with references to other parts of the book. - - -!Finclude/net/mac80211.h ieee80211_hw -!Finclude/net/mac80211.h ieee80211_hw_flags -!Finclude/net/mac80211.h SET_IEEE80211_DEV -!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR -!Finclude/net/mac80211.h ieee80211_ops -!Finclude/net/mac80211.h ieee80211_alloc_hw -!Finclude/net/mac80211.h ieee80211_register_hw -!Finclude/net/mac80211.h ieee80211_get_tx_led_name -!Finclude/net/mac80211.h ieee80211_get_rx_led_name -!Finclude/net/mac80211.h ieee80211_get_assoc_led_name -!Finclude/net/mac80211.h ieee80211_get_radio_led_name -!Finclude/net/mac80211.h ieee80211_unregister_hw -!Finclude/net/mac80211.h ieee80211_free_hw - - - - PHY configuration - TBD - - This chapter should describe PHY handling including - start/stop callbacks and the various structures used. - -!Finclude/net/mac80211.h ieee80211_conf -!Finclude/net/mac80211.h ieee80211_conf_flags - - - - Virtual interfaces - TBD - - This chapter should describe virtual interface basics - that are relevant to the driver (VLANs, MGMT etc are not.) - It should explain the use of the add_iface/remove_iface - callbacks as well as the interface configuration callbacks. - - Things related to AP mode should be discussed there. - - Things related to supporting multiple interfaces should be - in the appropriate chapter, a BIG FAT note should be here about - this though and the recommendation to allow only a single - interface in STA mode at first! - -!Finclude/net/mac80211.h ieee80211_vif - - - - Receive and transmit processing - - what should be here - TBD - - This should describe the receive and transmit - paths in mac80211/the drivers as well as - transmit status handling. - - - - Frame format -!Pinclude/net/mac80211.h Frame format - - - Packet alignment -!Pnet/mac80211/rx.c Packet alignment - - - Calling into mac80211 from interrupts -!Pinclude/net/mac80211.h Calling mac80211 from interrupts - - - functions/definitions -!Finclude/net/mac80211.h ieee80211_rx_status -!Finclude/net/mac80211.h mac80211_rx_flags -!Finclude/net/mac80211.h ieee80211_tx_info -!Finclude/net/mac80211.h ieee80211_rx -!Finclude/net/mac80211.h ieee80211_rx_irqsafe -!Finclude/net/mac80211.h ieee80211_tx_status -!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe -!Finclude/net/mac80211.h ieee80211_rts_get -!Finclude/net/mac80211.h ieee80211_rts_duration -!Finclude/net/mac80211.h ieee80211_ctstoself_get -!Finclude/net/mac80211.h ieee80211_ctstoself_duration -!Finclude/net/mac80211.h ieee80211_generic_frame_duration -!Finclude/net/mac80211.h ieee80211_wake_queue -!Finclude/net/mac80211.h ieee80211_stop_queue -!Finclude/net/mac80211.h ieee80211_wake_queues -!Finclude/net/mac80211.h ieee80211_stop_queues - - - - - Frame filtering -!Pinclude/net/mac80211.h Frame filtering -!Finclude/net/mac80211.h ieee80211_filter_flags - - - - - Advanced driver interface - - - Information contained within this part of the book is - of interest only for advanced interaction of mac80211 - with drivers to exploit more hardware capabilities and - improve performance. - - - - - Hardware crypto acceleration -!Pinclude/net/mac80211.h Hardware crypto acceleration - -!Finclude/net/mac80211.h set_key_cmd -!Finclude/net/mac80211.h ieee80211_key_conf -!Finclude/net/mac80211.h ieee80211_key_alg -!Finclude/net/mac80211.h ieee80211_key_flags - - - - Powersave support -!Pinclude/net/mac80211.h Powersave support - - - - Beacon filter support -!Pinclude/net/mac80211.h Beacon filter support -!Finclude/net/mac80211.h ieee80211_beacon_loss - - - - Multiple queues and QoS support - TBD -!Finclude/net/mac80211.h ieee80211_tx_queue_params - - - - Access point mode support - TBD - Some parts of the if_conf should be discussed here instead - - Insert notes about VLAN interfaces with hw crypto here or - in the hw crypto chapter. - -!Finclude/net/mac80211.h ieee80211_get_buffered_bc -!Finclude/net/mac80211.h ieee80211_beacon_get - - - - Supporting multiple virtual interfaces - TBD - - Note: WDS with identical MAC address should almost always be OK - - - Insert notes about having multiple virtual interfaces with - different MAC addresses here, note which configurations are - supported by mac80211, add notes about supporting hw crypto - with it. - - - - - Hardware scan offload - TBD -!Finclude/net/mac80211.h ieee80211_scan_completed - - - - - Rate control interface - - TBD - - This part of the book describes the rate control algorithm - interface and how it relates to mac80211 and drivers. - - - - dummy chapter - TBD - - - - - Internals - - TBD - - This part of the book describes mac80211 internals. - - - - - Key handling - - Key handling basics -!Pnet/mac80211/key.c Key handling basics - - - MORE TBD - TBD - - - - - Receive processing - TBD - - - - Transmit processing - TBD - - - - Station info handling - - Programming information -!Fnet/mac80211/sta_info.h sta_info -!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags - - - STA information lifetime rules -!Pnet/mac80211/sta_info.c STA information lifetime rules - - - - - Synchronisation - TBD - Locking, lots of RCU - - -
-- cgit v1.2.3 From 2b2d7795371df85bb106513d1b5fec077a29176e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 17 Aug 2010 12:08:07 +0200 Subject: mac80211-hwsim: allow configuring IBSS It will not look standard-compliant in a sniffer because because it doesn't * sync TSF * adjust the TSF in beacons * send beacons at TBTT * cancel beacons when another phy sends However, it does allow testing the configuration and parts of the mac80211 code for IBSS and as such is still useful. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 01ad7f77383a..d9dd9f9d3040 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -9,7 +9,8 @@ /* * TODO: - * - IBSS mode simulation (Beacon transmission with competition for "air time") + * - Add TSF sync and fix IBSS beacon transmission by adding + * competition for "air time" at TBTT * - RX filtering based on filter configuration (data->rx_filter) */ @@ -620,7 +621,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, hwsim_check_magic(vif); if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_MESH_POINT) + vif->type != NL80211_IFTYPE_MESH_POINT && + vif->type != NL80211_IFTYPE_ADHOC) return; skb = ieee80211_beacon_get(hw, vif); @@ -1295,6 +1297,7 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); hw->flags = IEEE80211_HW_MFP_CAPABLE | -- cgit v1.2.3 From 6ddbf8cd39dc1faee7ba60337b11eb02edfcbee6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Aug 2010 12:39:14 -0700 Subject: iwlwifi: fix thermal throttling related power management operation The current approach is very broken because it adds an often-used code path that will not initialise "cmd" at all. Signed-off-by: Johannes Berg Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-power.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index da1f2ae24472..63c0ab46261f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -284,13 +284,11 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && - priv->cfg->ops->lib->tt_ops.tt_power_mode) { - if (priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { - /* in thermal throttling low power state */ - iwl_static_sleep_cmd(priv, &cmd, - priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), - dtimper); - } + priv->cfg->ops->lib->tt_ops.tt_power_mode && + priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { + /* in thermal throttling low power state */ + iwl_static_sleep_cmd(priv, &cmd, + priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); } else if (!enabled) iwl_power_sleep_cam_cmd(priv, &cmd); else if (priv->power_data.debug_sleep_level_override >= 0) -- cgit v1.2.3 From 24e0f9f84707560d029fe17395f71e99866b438b Mon Sep 17 00:00:00 2001 From: Julian Calaby Date: Tue, 17 Aug 2010 14:52:41 -0400 Subject: Hostap: Fix "'ret' set but not used" warning message from GCC in hostap CC [M] drivers/net/wireless/hostap/hostap_ioctl.o drivers/net/wireless/hostap/hostap_ioctl.c: In function 'prism2_request_scan': drivers/net/wireless/hostap/hostap_ioctl.c:1666:6: warning: variable 'ret' set but not used Signed-off-by: Julian Calaby Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index a85e43a8d758..6038633ef361 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1696,7 +1696,7 @@ static int prism2_request_scan(struct net_device *dev) hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE, HFA384X_ROAMING_FIRMWARE); - return 0; + return ret; } #else /* !PRISM2_NO_STATION_MODES */ -- cgit v1.2.3 From 9c82d0a73f54adc2c8cc0ea10f91efc366b50992 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 23 Jul 2010 13:42:39 -0700 Subject: iwlwifi: remove unused define IWL_SIXTY_SECS is not been used, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a2927b3a606e..91d9c8b3efeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1052,7 +1052,6 @@ struct iwl_event_log { /* timer constants use to monitor and recover stuck tx queues in mSecs */ #define IWL_MONITORING_PERIOD (1000) #define IWL_ONE_HUNDRED_MSECS (100) -#define IWL_SIXTY_SECS (60000) enum iwl_reset { IWL_RF_RESET = 0, -- cgit v1.2.3 From 2cbc19f3d0cfe6cf7d9d2b3fac52976c3f2c6e89 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 23 Jul 2010 16:49:44 -0700 Subject: iwlwifi: additional comments in iwl_cfg No functional changes, just add additional comments to iwl_cfg structure Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e6d127df01ea..702d62bf4ee4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -278,6 +278,8 @@ struct iwl_mod_params { * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation * @scan_antennas: available antenna for scan operation + * @need_dc_calib: need to perform init dc calibration + * @bt_statistics: use BT version of statistics notification * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the -- cgit v1.2.3 From b15826a795969cbdd85a0b5100165e240e6508e4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 28 Jul 2010 09:18:53 -0700 Subject: iwlwifi: max/min aggregation time limit Set the minimum and maximum for aggregation time limit in uSec. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9435fd934d5e..c6a0470b2f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2092,8 +2092,8 @@ struct iwl_link_qual_general_params { } __packed; #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ -#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535) -#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0) +#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) +#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100) #define LINK_QUAL_AGG_DISABLE_START_DEF (3) #define LINK_QUAL_AGG_DISABLE_START_MAX (255) -- cgit v1.2.3 From 7469701e10adb6bcc3d66544bd9f6d553fc678c9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 28 Jul 2010 09:18:54 -0700 Subject: iwlwifi: make aggregation time limit configurable By default, aggregation time limit is 4000 uSec, add the parameter to .cfg to allow this parameter can be configure per device base if needed. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 23e5c42e7d7e..7c4deee4c527 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2694,8 +2694,18 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + lq_cmd->agg_params.agg_time_limit = cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + /* + * overwrite if needed, pass aggregation time limit + * to uCode in uSec + */ + if (priv && priv->cfg->agg_time_limit && + priv->cfg->agg_time_limit >= LINK_QUAL_AGG_TIME_LIMIT_MIN && + priv->cfg->agg_time_limit <= LINK_QUAL_AGG_TIME_LIMIT_MAX) + lq_cmd->agg_params.agg_time_limit = + cpu_to_le16(priv->cfg->agg_time_limit); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c6a0470b2f50..14a7a8c0711a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2110,8 +2110,10 @@ struct iwl_link_qual_general_params { */ struct iwl_link_qual_agg_params { - /* Maximum number of uSec in aggregation. - * Driver should set this to 4000 (4 milliseconds). */ + /* + *Maximum number of uSec in aggregation. + * default set to 4000 (4 milliseconds) if not configured in .cfg + */ __le16 agg_time_limit; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 702d62bf4ee4..f5586b5e0496 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -280,6 +280,7 @@ struct iwl_mod_params { * @scan_antennas: available antenna for scan operation * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification + * @agg_time_limit: maximum number of uSec in aggregation * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -350,6 +351,7 @@ struct iwl_cfg { u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; const bool need_dc_calib; const bool bt_statistics; + u16 agg_time_limit; }; /*************************** -- cgit v1.2.3 From 81e95430aaa898799421617c2db2882386bab69a Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Wed, 28 Jul 2010 13:40:27 -0700 Subject: iwlwifi: do not call ieee80211_frequency_to_channel A few cases in iwlwifi driver function ieee80211_frequency_to_channel() is called to get channel number from center frequency. This is not needed since the channel number is already saved in hw_value field of struct ieee80211_channel in function iwlcore_init_geos(). So replace those function calls with hw_value field of struct ieee80211_channel. Signed-off-by: Shanyu Zhao Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 ++---- 7 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d6da356608fa..9415b71fa12d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1470,7 +1470,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, cmd.band = band; cmd.expect_beacon = 0; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = priv->staging_rxon.flags; cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 54083a39c724..0c2ea136cfd5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -291,7 +291,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", priv->active_rxon.channel, ch); cmd.channel = cpu_to_le16(ch); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 7902de172a38..e0c6c3afba27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -214,7 +214,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", priv->active_rxon.channel, ch); cmd.channel = cpu_to_le16(ch); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9dd9e64c2b0b..eedd71f5506b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1098,7 +1098,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, if (chan->band != band) continue; - channel = ieee80211_frequency_to_channel(chan->center_freq); + channel = chan->hw_value; scan_ch->channel = cpu_to_le16(channel); ch_info = iwl_get_channel_info(priv, band, channel); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bce77eeb31c0..eecfec7c4063 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3655,8 +3655,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (priv->cfg->ops->lib->set_channel_switch) { - ch = ieee80211_frequency_to_channel( - ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; if (le16_to_cpu(priv->active_rxon.channel) != ch) { ch_info = iwl_get_channel_info(priv, conf->channel->band, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b5045c62de7e..dc29844cce1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -916,7 +916,7 @@ EXPORT_SYMBOL(iwl_get_single_channel_number); int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) { enum ieee80211_band band = ch->band; - u16 channel = ieee80211_frequency_to_channel(ch->center_freq); + u16 channel = ch->hw_value; if (!iwl_get_channel_info(priv, band, channel)) { IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n", @@ -2032,7 +2032,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (scan_active) goto set_ch_out; - ch = ieee80211_frequency_to_channel(conf->channel->center_freq); + ch = conf->channel->hw_value; ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); if (!is_channel_valid(ch_info)) { IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e96a1bb12783..d3acdae72381 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -467,8 +467,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, for (i = 0; i < supp_band->n_channels; i++) pos += scnprintf(buf + pos, bufsz - pos, "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), + channels[i].hw_value, channels[i].max_power, channels[i].flags & IEEE80211_CHAN_RADAR ? " (IEEE 802.11h required)" : "", @@ -491,8 +490,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, for (i = 0; i < supp_band->n_channels; i++) pos += scnprintf(buf + pos, bufsz - pos, "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), + channels[i].hw_value, channels[i].max_power, channels[i].flags & IEEE80211_CHAN_RADAR ? " (IEEE 802.11h required)" : "", -- cgit v1.2.3 From aa2dc6b529d781a375f7ad3185198f6315865b06 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Wed, 28 Jul 2010 13:40:39 -0700 Subject: iwlwifi: avoid race condition in channel change When iwl_mac_config() is called by mac80211, the channel pointer hw->conf->channel can potentially change, resulting in mismatch band and channel number when configuring RXON command. To avoid this situation, save the channel pointer in local variables and validate the channel before using it. Note that priv->mutex is locked during the whole function so the local variables are safe. Same change is applied to iwl_mac_channel_switch() since basically it copies code from iwl_mac_config(). Also removed an outdated comment in the flow. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ++++++-------- drivers/net/wireless/iwlwifi/iwl-core.c | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eecfec7c4063..61ecd180982e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3632,6 +3632,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, struct iwl_priv *priv = hw->priv; const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = ch_switch->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; u16 ch; unsigned long flags = 0; @@ -3655,10 +3656,10 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (priv->cfg->ops->lib->set_channel_switch) { - ch = ch_switch->channel->hw_value; + ch = channel->hw_value; if (le16_to_cpu(priv->active_rxon.channel) != ch) { ch_info = iwl_get_channel_info(priv, - conf->channel->band, + channel->band, ch); if (!is_channel_valid(ch_info)) { IWL_DEBUG_MAC80211(priv, "invalid channel\n"); @@ -3687,15 +3688,12 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, } else ht_conf->is_40mhz = false; - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) + if (le16_to_cpu(priv->staging_rxon.channel) != ch) priv->staging_rxon.flags = 0; - iwl_set_rxon_channel(priv, conf->channel); + iwl_set_rxon_channel(priv, channel); iwl_set_rxon_ht(priv, ht_conf); - iwl_set_flags_for_band(priv, conf->channel->band, + iwl_set_flags_for_band(priv, channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index dc29844cce1f..39aea7545603 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1992,6 +1992,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) struct iwl_priv *priv = hw->priv; const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; unsigned long flags = 0; int ret = 0; @@ -2001,7 +2002,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - conf->channel->hw_value, changed); + channel->hw_value, changed); if (unlikely(!priv->cfg->mod_params->disable_hw_scan && test_bit(STATUS_SCANNING, &priv->status))) { @@ -2032,8 +2033,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (scan_active) goto set_ch_out; - ch = conf->channel->hw_value; - ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); + ch = channel->hw_value; + ch_info = iwl_get_channel_info(priv, channel->band, ch); if (!is_channel_valid(ch_info)) { IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); ret = -EINVAL; @@ -2064,16 +2065,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) * from BSS config in iwl_ht_conf */ ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) priv->staging_rxon.flags = 0; - iwl_set_rxon_channel(priv, conf->channel); + iwl_set_rxon_channel(priv, channel); iwl_set_rxon_ht(priv, ht_conf); - iwl_set_flags_for_band(priv, conf->channel->band, priv->vif); + iwl_set_flags_for_band(priv, channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); if (priv->cfg->ops->lib->update_bcast_station) -- cgit v1.2.3 From 3edb5fd6ac898182a186d403695986f6ff51ac65 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 27 Jul 2010 20:45:15 -0700 Subject: iwlwifi: cleanup iwl_set_rxon_channel() Update outdated comments of iwl_set_rxon_channel() to reflect the current signature. Also remove the unnecessary validation of the channel. Those channel info are constructed in iwlwifi driver and mac80211 will never modify the content of the struct. Also everytime before this function is called the channel info has been validated already (as a paranoid check). Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 39aea7545603..602636c88fef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -904,26 +904,19 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_get_single_channel_number); /** - * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON - * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz - * @channel: Any channel valid for the requested phymode + * iwl_set_rxon_channel - Set the band and channel values in staging RXON + * @ch: requested channel as a pointer to struct ieee80211_channel - * In addition to setting the staging RXON, priv->phymode is also set. + * In addition to setting the staging RXON, priv->band is also set. * * NOTE: Does not commit to the hardware; it sets appropriate bit fields - * in the staging RXON flag structure based on the phymode + * in the staging RXON flag structure based on the ch->band */ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) { enum ieee80211_band band = ch->band; u16 channel = ch->hw_value; - if (!iwl_get_channel_info(priv, band, channel)) { - IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n", - channel, band); - return -EINVAL; - } - if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && (priv->band == band)) return 0; -- cgit v1.2.3 From 948f5a2f08cb782adf3c5bb92abc6dbec2b4275f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 29 Jul 2010 07:07:51 -0700 Subject: iwlwifi: refactor iwl_setup_rxon_timing All callers of iwl_setup_rxon_timing() also send the command right away, so rename the function to iwl_send_rxon_timing() and move the sending into it. Also, some callers clear the data, this can be done always and thus moved in as well. Finally, there's no reason for the function to acquire the spinlock, but it should be called with the mutex held, so assert that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-core.c | 14 +++++++++----- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 11 ++--------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 61ecd180982e..f832535c3a47 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3109,9 +3109,7 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - iwl_setup_rxon_timing(priv, vif); - ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + ret = iwl_send_rxon_timing(priv, vif); if (ret) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); @@ -3347,9 +3345,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) iwlcore_commit_rxon(priv); /* RXON Timing */ - iwl_setup_rxon_timing(priv, vif); - ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + ret = iwl_send_rxon_timing(priv, vif); if (ret) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 602636c88fef..7754be4463d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -491,17 +491,19 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) return new_val; } -void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) { u64 tsf; s32 interval_tm, rem; - unsigned long flags; struct ieee80211_conf *conf = NULL; u16 beacon_int; conf = ieee80211_get_hw_conf(priv->hw); - spin_lock_irqsave(&priv->lock, flags); + lockdep_assert_held(&priv->mutex); + + memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); + priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); @@ -524,14 +526,16 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) rem = do_div(tsf, interval_tm); priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); - spin_unlock_irqrestore(&priv->lock, flags); IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n", le16_to_cpu(priv->rxon_timing.beacon_interval), le32_to_cpu(priv->rxon_timing.beacon_init_val), le16_to_cpu(priv->rxon_timing.atim_window)); + + return iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + sizeof(priv->rxon_timing), &priv->rxon_timing); } -EXPORT_SYMBOL(iwl_setup_rxon_timing); +EXPORT_SYMBOL(iwl_send_rxon_timing); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f5586b5e0496..edadca510099 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -714,7 +714,7 @@ extern int iwl_send_lq_cmd(struct iwl_priv *priv, void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); -void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) { return priv->cfg->ops->hcmd->rxon_assoc(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index faa2e0037e10..84494b1f833e 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3094,10 +3094,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv, vif); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + rc = iwl_send_rxon_timing(priv, vif); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); @@ -3271,11 +3268,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) iwlcore_commit_rxon(priv); /* RXON Timing */ - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv, vif); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), - &priv->rxon_timing); + rc = iwl_send_rxon_timing(priv, vif); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); -- cgit v1.2.3 From b1a78858c4579d678444c007617292ccf6f7a315 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 31 Jul 2010 08:52:03 -0700 Subject: iwlagn: adjust starting action for rate scale During rate scale, reset starting action after making action adjustment to avoid the possibility of break out of loop too early. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 7c4deee4c527..4d5738dfc7eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1265,7 +1265,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, struct iwl_rate_scale_data *window = &(tbl->win[index]); u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret = 0; @@ -1277,6 +1277,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && tbl->action > IWL_LEGACY_SWITCH_SISO) tbl->action = IWL_LEGACY_SWITCH_SISO; + start_action = tbl->action; for (; ;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1403,7 +1404,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; @@ -1414,6 +1415,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, /* stay in SISO */ tbl->action = IWL_SISO_SWITCH_ANTENNA1; } + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1541,7 +1543,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; @@ -1553,6 +1555,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, /* switch in SISO */ tbl->action = IWL_MIMO2_SWITCH_SISO_A; } + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1682,7 +1685,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret; @@ -1694,6 +1697,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, /* switch in SISO */ tbl->action = IWL_MIMO3_SWITCH_SISO_A; } + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { -- cgit v1.2.3 From 80e9158c3fc1b55301b71cbeea2b31aa1d3c9b76 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 3 Aug 2010 08:23:32 -0700 Subject: iwlagn: continue perform rate scale when error detected If for some reason, the actual link command not matching neither active nor search table; instead of return and not performing rate scale, by-pass the data collection and continue the rate scale process. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 4d5738dfc7eb..a4563389bad0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -82,6 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, u32 rate_n_flags); +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta); #ifdef CONFIG_MAC80211_DEBUGFS @@ -502,6 +503,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); u8 mcs; + memset(tbl, 0, sizeof(struct iwl_scale_tbl_info)); *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); if (*rate_idx == IWL_RATE_INVALID) { @@ -848,7 +850,20 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); } else { IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); - return; + tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n", + tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI); + /* + * no matching table found, let's by-pass the data collection + * and continue to perform rate scale to find the rate table + */ + rs_stay_in_table(lq_sta); + goto done; } /* @@ -909,7 +924,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, } /* The last TX rate is cached in lq_sta; it's set in if/else above */ lq_sta->last_rate_n_flags = tx_rate; - +done: /* See if there's a better rate or modulation mode to try. */ if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); @@ -2598,7 +2613,6 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_dbgfs_set_mcs(lq_sta, &new_rate, index); /* Interpret new_rate (rate_n_flags) */ - memset(&tbl_type, 0, sizeof(tbl_type)); rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); -- cgit v1.2.3 From 30c1b0f7e96144e42e2be0bdec18d2475f5af31b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 4 Aug 2010 08:05:33 -0700 Subject: iwlwifi: additional parameter in REPLY_RX_PHY_CMD Adding additional parameter in REPLY_RX_PHY_CMD, frame_time indicate the frame's time on the air based on byte count and frame rate calculation Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 14a7a8c0711a..13893a0a6197 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1401,7 +1401,7 @@ struct iwl_rx_phy_res { u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */ __le32 rate_n_flags; /* RATE_MCS_* */ __le16 byte_count; /* frame's byte-count */ - __le16 reserved3; + __le16 frame_time; /* frame's time on the air */ } __packed; struct iwl_rx_mpdu_res_start { -- cgit v1.2.3 From 7ccc896f4c9d5f11e449368cf520565bf2073a9b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 4 Aug 2010 08:42:17 -0700 Subject: iwlwifi: more generic name for rssi calc in iwlagn Change the define to more generic naming to match _agn devices since the rssi calculation are common function for 5000 series and up Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 21 ++++++++++-------- drivers/net/wireless/iwlwifi/iwl-commands.h | 33 ++++++++++++++++------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 75b901b3eb1e..84939763d178 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -235,13 +235,13 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, /* data from PHY/DSP regarding signal strength, etc., * contents are always there, not configurable by host */ - struct iwl5000_non_cfg_phy *ncphy = - (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf; + struct iwlagn_non_cfg_phy *ncphy = + (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; u32 val, rssi_a, rssi_b, rssi_c, max_rssi; u8 agc; - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]); - agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); + agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; /* Find max rssi among 3 possible receivers. * These values are measured by the digital signal processor (DSP). @@ -249,11 +249,14 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, * if the radio's automatic gain control (AGC) is working right. * AGC value (see below) will provide the "interesting" info. */ - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]); - rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS; - rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS; - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]); - rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); + rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> + IWLAGN_OFDM_RSSI_A_BIT_POS; + rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> + IWLAGN_OFDM_RSSI_B_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); + rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> + IWLAGN_OFDM_RSSI_C_BIT_POS; max_rssi = max_t(u32, rssi_a, rssi_b); max_rssi = max_t(u32, max_rssi, rssi_c); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 13893a0a6197..4083e4430827 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1367,21 +1367,24 @@ struct iwl4965_rx_non_cfg_phy { } __packed; -#define IWL50_RX_RES_PHY_CNT 8 -#define IWL50_RX_RES_AGC_IDX 1 -#define IWL50_RX_RES_RSSI_AB_IDX 2 -#define IWL50_RX_RES_RSSI_C_IDX 3 -#define IWL50_OFDM_AGC_MSK 0xfe00 -#define IWL50_OFDM_AGC_BIT_POS 9 -#define IWL50_OFDM_RSSI_A_MSK 0x00ff -#define IWL50_OFDM_RSSI_A_BIT_POS 0 -#define IWL50_OFDM_RSSI_B_MSK 0xff0000 -#define IWL50_OFDM_RSSI_B_BIT_POS 16 -#define IWL50_OFDM_RSSI_C_MSK 0x00ff -#define IWL50_OFDM_RSSI_C_BIT_POS 0 - -struct iwl5000_non_cfg_phy { - __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* up to 8 phy entries */ +#define IWLAGN_RX_RES_PHY_CNT 8 +#define IWLAGN_RX_RES_AGC_IDX 1 +#define IWLAGN_RX_RES_RSSI_AB_IDX 2 +#define IWLAGN_RX_RES_RSSI_C_IDX 3 +#define IWLAGN_OFDM_AGC_MSK 0xfe00 +#define IWLAGN_OFDM_AGC_BIT_POS 9 +#define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff +#define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00 +#define IWLAGN_OFDM_RSSI_A_BIT_POS 0 +#define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000 +#define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000 +#define IWLAGN_OFDM_RSSI_B_BIT_POS 16 +#define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff +#define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00 +#define IWLAGN_OFDM_RSSI_C_BIT_POS 0 + +struct iwlagn_non_cfg_phy { + __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */ } __packed; -- cgit v1.2.3 From 172c1d112a38c8721fe1d7114e2ce1e8a91451c1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 4 Aug 2010 12:02:43 -0700 Subject: iwlwifi: configurable ampdu factor and density Add ampdu factor and density to .cfg, this allow both parameters can be configure per device based. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 13 ++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7754be4463d8..346e0ad7e351 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -239,7 +239,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; + if (priv->cfg->ampdu_factor) + ht_info->ampdu_factor = priv->cfg->ampdu_factor; ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; + if (priv->cfg->ampdu_density) + ht_info->ampdu_density = priv->cfg->ampdu_density; ht_info->mcs.rx_mask[0] = 0xFF; if (rx_chains_num >= 2) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index edadca510099..3efab0e29b06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -281,6 +281,8 @@ struct iwl_mod_params { * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -352,6 +354,8 @@ struct iwl_cfg { const bool need_dc_calib; const bool bt_statistics; u16 agg_time_limit; + u8 ampdu_factor; + u8 ampdu_density; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 91d9c8b3efeb..f72fbf4dc92b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -435,7 +435,13 @@ union iwl_ht_rate_supp { }; }; -#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) +#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) +#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) +#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) +#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) +#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K /* * Maximal MPDU density for TX aggregation @@ -444,8 +450,13 @@ union iwl_ht_rate_supp { * 6 - 8us density * 7 - 16us density */ +#define CFG_HT_MPDU_DENSITY_2USEC (0x4) #define CFG_HT_MPDU_DENSITY_4USEC (0x5) +#define CFG_HT_MPDU_DENSITY_8USEC (0x6) +#define CFG_HT_MPDU_DENSITY_16USEC (0x7) #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC +#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC +#define CFG_HT_MPDU_DENSITY_MIN (0x1) struct iwl_ht_config { /* self configuration data */ -- cgit v1.2.3 From 79e88e79a29abede50bf82064ad9d9b1a625e42a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 11 Aug 2010 07:30:20 -0700 Subject: iwlwifi: remove unused iwl_send_card_state function iwl_send_card_state() is not being call from anywhere, remove it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 22 ---------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 346e0ad7e351..ef713003682e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1515,28 +1515,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) } EXPORT_SYMBOL(iwl_send_statistics_request); -/* - * CARD_STATE_CMD - * - * Use: Sets the device's internal card state to enable, disable, or halt - * - * When in the 'enable' state the card operates as normal. - * When in the 'disable' state, the card enters into a low power mode. - * When in the 'halt' state, the card is shut down and must be fully - * restarted to come back on. - */ -int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_CARD_STATE_CMD, - .len = sizeof(u32), - .data = &flags, - .flags = meta_flag, - }; - - return iwl_send_cmd(priv, &cmd); -} - void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3efab0e29b06..870c62d438a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -595,8 +595,6 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); -int iwl_send_card_state(struct iwl_priv *priv, u32 flags, - u8 meta_flag); /***************************************************** * PCI * -- cgit v1.2.3 From 3939608591d1d0cbb79d7afd08beabcfb5eb115f Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Thu, 12 Aug 2010 10:24:07 -0700 Subject: iwlwifi: enable experimental ucode support ucode firmware may need to be released as experimental for testing or debugging. released ucode filenames have the API version as the last component. experimental ucode files will have that component be "exp" and the fw_version string reported by ethtool will also contain the string EXP to clearly identify this ucode from released ucode. EXP is short for EXPERIMENTAL since fw_version has a max lenght on 32. this capability is controlled by Kconfig and defaulted to not be used. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index a51e4da1bdfc..7ab5b51951ff 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -36,6 +36,12 @@ config IWLWIFI_DEBUGFS is a low-impact option that allows getting insight into the driver's state at runtime. +config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + bool "Experimental uCode support" + depends on IWLWIFI && IWLWIFI_DEBUG + ---help--- + Enable use of experimental ucode for testing and debugging. + config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" depends on IWLWIFI diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f832535c3a47..40b82d9f309e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1659,24 +1659,37 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); static int iwl_mac_setup_register(struct iwl_priv *priv, struct iwlagn_ucode_capabilities *capa); +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) { const char *name_pre = priv->cfg->fw_name_pre; + char tag[8]; - if (first) + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + priv->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif priv->fw_index = priv->cfg->ucode_api_max; - else + sprintf(tag, "%d", priv->fw_index); + } else { priv->fw_index--; + sprintf(tag, "%d", priv->fw_index); + } if (priv->fw_index < priv->cfg->ucode_api_min) { IWL_ERR(priv, "no suitable firmware found!\n"); return -ENOENT; } - sprintf(priv->firmware_name, "%s%d%s", - name_pre, priv->fw_index, ".ucode"); + sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", + IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, @@ -1971,8 +1984,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) memset(&pieces, 0, sizeof(pieces)); if (!ucode_raw) { - IWL_ERR(priv, "request for firmware file '%s' failed.\n", - priv->firmware_name); + if (priv->fw_index <= priv->cfg->ucode_api_max) + IWL_ERR(priv, + "request for firmware file '%s' failed.\n", + priv->firmware_name); goto try_again; } @@ -2019,7 +2034,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) api_max, api_ver); if (build) - sprintf(buildstr, " build %u", build); + sprintf(buildstr, " build %u%s", build, + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); else buildstr[0] = '\0'; -- cgit v1.2.3 From 110ff6db6f6fbb946c099f49f666b59258746048 Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Thu, 12 Aug 2010 12:15:55 -0700 Subject: iwlwifi: move debug options into submenu more debug options being added so it is useful to move them into a submenu for ease of readability when using config commands like make menuconfig and make xconfig Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 7ab5b51951ff..b82364258dc5 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -3,6 +3,9 @@ config IWLWIFI depends on PCI && MAC80211 select FW_LOADER +menu "Debugging Options" + depends on IWLWIFI + config IWLWIFI_DEBUG bool "Enable full debugging output in iwlagn and iwl3945 drivers" depends on IWLWIFI @@ -59,6 +62,7 @@ config IWLWIFI_DEVICE_TRACING If unsure, say Y so we can help you better when problems occur. +endmenu config IWLAGN tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)" -- cgit v1.2.3 From 8d5ad08525f1a8e0484d125ba155dbd3c3282ab8 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 17 Aug 2010 22:46:52 +0300 Subject: wl1251: add missing __packed modifier for some structs Several acx and cmd structures are missing __packed modifier, add it. This was noticed while comparing them with corresponding wl1271 code. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_acx.h | 6 +++--- drivers/net/wireless/wl12xx/wl1251_cmd.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index 842df310d92a..9864124d9e1b 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h @@ -37,7 +37,7 @@ struct acx_header { /* payload length (not including headers */ u16 len; -}; +} __packed; struct acx_error_counter { struct acx_header header; @@ -471,7 +471,7 @@ struct acx_conn_monit_params { u32 synch_fail_thold; /* number of beacons missed */ u32 bss_lose_timeout; /* number of TU's from synch fail */ -}; +} __packed; enum { SG_ENABLE = 0, @@ -1056,7 +1056,7 @@ struct acx_rate_class { u8 long_retry_limit; u8 aflags; u8 reserved; -}; +} __packed; struct acx_rate_policy { struct acx_header header; diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h index a9e4991369be..60d7e522486c 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h @@ -111,7 +111,7 @@ struct wl1251_cmd_header { struct wl1251_command { struct wl1251_cmd_header header; u8 parameters[MAX_CMD_PARAMS]; -}; +} __packed; enum { CMD_MAILBOX_IDLE = 0, @@ -164,7 +164,7 @@ struct cmd_read_write_memory { of this field is the Host in WRITE command or the Wilink in READ command. */ u8 value[MAX_READ_SIZE]; -}; +} __packed; #define CMDMBOX_HEADER_LEN 4 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 @@ -339,7 +339,7 @@ struct wl1251_cmd_trigger_scan_to { struct wl1251_cmd_header header; u32 timeout; -}; +} __packed; /* HW encryption keys */ #define NUM_ACCESS_CATEGORIES_COPY 4 -- cgit v1.2.3 From d41776fad4c6601c1711d4e454291efd6687addb Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 17 Aug 2010 22:46:53 +0300 Subject: wl1251: fix event handling mechanism In case both A and B events occured simultaneously, current code would only process A and clear both interrupts. Make it process both events instead. Based on wl1271 patches by Juuso Oikarinen: 1fd2794f36913992798184c464fe8f85753b13e0 13f2dc52c69bcca074cd12d4806953b2af45c386 Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 6d31c855fcfe..51474b697c1a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -293,14 +293,14 @@ static void wl1251_irq_work(struct work_struct *work) wl1251_tx_complete(wl); } - if (intr & (WL1251_ACX_INTR_EVENT_A | - WL1251_ACX_INTR_EVENT_B)) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", - intr); - if (intr & WL1251_ACX_INTR_EVENT_A) - wl1251_event_handle(wl, 0); - else - wl1251_event_handle(wl, 1); + if (intr & WL1251_ACX_INTR_EVENT_A) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A"); + wl1251_event_handle(wl, 0); + } + + if (intr & WL1251_ACX_INTR_EVENT_B) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B"); + wl1251_event_handle(wl, 1); } if (intr & WL1251_ACX_INTR_INIT_COMPLETE) -- cgit v1.2.3 From 5b44a1b5164c69cb274215fc79a9f4f5a1203c4d Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 17 Aug 2010 22:46:54 +0300 Subject: wl1251: fix beacon filter table structure The beacon filter table configuration ACX structure had certain elements reversed, fix it to match TI driver. Based on wl1271 patch 1937e742639c03a6fe77239c3003ce9602302117 by Juuso Oikarinen. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_acx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index 9864124d9e1b..a8845b8f2451 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h @@ -459,8 +459,8 @@ struct acx_beacon_filter_ie_table { struct acx_header header; u8 num_ie; - u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; u8 pad[3]; + u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; } __packed; #define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ -- cgit v1.2.3 From 7273b9700b74e8c26b612207aea47effb0e530bf Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 17 Aug 2010 22:46:55 +0300 Subject: wl1251: wait for join command complete event Poll for join command completion instead of waiting blindly for 10 msecs. There is a timeout of 100 msecs, if the command doesn't complete by then, we return an error code. Based on wl1271 patch 99d84c1de8fdf5f9b09f07fdbc628857a040bf8b by Luciano Coelho. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_boot.c | 2 +- drivers/net/wireless/wl12xx/wl1251_event.c | 29 +++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1251_event.h | 1 + drivers/net/wireless/wl12xx/wl1251_main.c | 8 +++----- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 65e0416be5b6..5e65f47fda8a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -302,7 +302,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | - BT_PTA_PREDICTION_EVENT_ID; + BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; ret = wl1251_event_unmask(wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c index 020d764f9c13..e093a1c5a205 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl12xx/wl1251_event.c @@ -97,6 +97,35 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) return 0; } +/* + * Poll the mailbox event field until any of the bits in the mask is set or a + * timeout occurs (WL1251_EVENT_TIMEOUT in msecs) + */ +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms) +{ + u32 events_vector, event; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + + /* read from both event fields */ + wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector, + sizeof(events_vector)); + event = events_vector & mask; + wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector, + sizeof(events_vector)); + event |= events_vector & mask; + } while (!event); + + return 0; +} + int wl1251_event_unmask(struct wl1251 *wl) { int ret; diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h index f48a2b66bc5a..ec456474a842 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.h +++ b/drivers/net/wireless/wl12xx/wl1251_event.h @@ -117,5 +117,6 @@ struct event_mailbox { int wl1251_event_unmask(struct wl1251 *wl); void wl1251_event_mbox_config(struct wl1251 *wl); int wl1251_event_handle(struct wl1251 *wl, u8 mbox); +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms); #endif diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 51474b697c1a..c81e95b45c14 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -339,11 +339,9 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, if (ret < 0) goto out; - /* - * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify - * locking we just sleep instead, for now - */ - msleep(10); + ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100); + if (ret < 0) + wl1251_warning("join timeout"); out: return ret; -- cgit v1.2.3 From 633dd1ea683d907af944bcd9814092efe9869b05 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 18 Aug 2010 15:01:23 +0200 Subject: mac80211: fix docbook Fix a small problem in the documentation for ieee80211_request_smps, and a now erroneous inclusion of enum ieee80211_key_alg, which no longer exists after the change to ciphers. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 1 - include/net/mac80211.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 6f88e184d2e7..52310ac892ea 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -248,7 +248,6 @@ MISSING !Finclude/net/mac80211.h set_key_cmd !Finclude/net/mac80211.h ieee80211_key_conf -!Finclude/net/mac80211.h ieee80211_key_alg !Finclude/net/mac80211.h ieee80211_key_flags diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 914c747ac3a0..2a1811366076 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2537,7 +2537,7 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); /** * ieee80211_request_smps - request SM PS transition * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * @mode: new SM PS mode + * @smps_mode: new SM PS mode * * This allows the driver to request an SM PS transition in managed * mode. This is useful when the driver has more information than -- cgit v1.2.3 From 2a5fb7b088f8418958775774dda9427d6c73c522 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 18 Aug 2010 17:44:36 +0200 Subject: nl80211: some documentation fixes The nl80211 documentation is currently never generated, so problems have accumulated. Fix most of the trivial ones. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 57 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 8af1e66c3cf9..ec1690da7845 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -347,6 +347,8 @@ * four bytes for vendor frames including the OUI. The registration * cannot be dropped, but is removed automatically when the netlink * socket is closed. Multiple registrations can be made. + * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for + * backward compatibility * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This * command is used both as a request to transmit a management frame and * as an event indicating reception of a frame that was not processed in @@ -359,11 +361,14 @@ * operational channel). When called, this operation returns a cookie * (%NL80211_ATTR_COOKIE) that will be included with the TX status event * pertaining to the TX request. + * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies * the TX command and %NL80211_ATTR_FRAME includes the contents of the * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged * the frame. + * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for + * backward compatibility. * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command * is used to configure connection quality monitoring notification trigger * levels. @@ -1029,11 +1034,14 @@ enum nl80211_iftype { * Station flags. When a station is added to an AP interface, it is * assumed to be already associated (and hence authenticated.) * + * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames * with short barker preamble * @NL80211_STA_FLAG_WME: station is WME/QoS capable * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_MAX: highest station flag number currently defined + * @__NL80211_STA_FLAG_AFTER_LAST: internal use */ enum nl80211_sta_flags { __NL80211_STA_FLAG_INVALID, @@ -1146,14 +1154,17 @@ enum nl80211_mpath_flags { * information about a mesh path. * * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved - * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination - * @NL80211_ATTR_MPATH_SN: destination sequence number - * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path - * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now - * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in + * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination + * @NL80211_MPATH_INFO_SN: destination sequence number + * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path + * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now + * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in * &enum nl80211_mpath_flags; - * @NL80211_ATTR_MPATH_DISCOVERY_TIMEOUT: total path discovery timeout, in msec - * @NL80211_ATTR_MPATH_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec + * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number + * currently defind + * @__NL80211_MPATH_INFO_AFTER_LAST: internal use */ enum nl80211_mpath_info { __NL80211_MPATH_INFO_INVALID, @@ -1182,6 +1193,8 @@ enum nl80211_mpath_info { * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n + * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined + * @__NL80211_BAND_ATTR_AFTER_LAST: internal use */ enum nl80211_band_attr { __NL80211_BAND_ATTR_INVALID, @@ -1202,6 +1215,7 @@ enum nl80211_band_attr { /** * enum nl80211_frequency_attr - frequency attributes + * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current * regulatory domain. @@ -1213,6 +1227,9 @@ enum nl80211_band_attr { * on this channel in current regulatory domain. * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm * (100 * dBm). + * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use */ enum nl80211_frequency_attr { __NL80211_FREQUENCY_ATTR_INVALID, @@ -1232,9 +1249,13 @@ enum nl80211_frequency_attr { /** * enum nl80211_bitrate_attr - bitrate attributes + * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported * in 2.4 GHz band. + * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number + * currently defined + * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use */ enum nl80211_bitrate_attr { __NL80211_BITRATE_ATTR_INVALID, @@ -1290,6 +1311,7 @@ enum nl80211_reg_type { /** * enum nl80211_reg_rule_attr - regulatory rule attributes + * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional * considerations for a given frequency range. These are the * &enum nl80211_reg_rule_flags. @@ -1306,6 +1328,9 @@ enum nl80211_reg_type { * If you don't have one then don't send this. * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for * a given frequency range. The value is in mBm (100 * dBm). + * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number + * currently defined + * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use */ enum nl80211_reg_rule_attr { __NL80211_REG_RULE_ATTR_INVALID, @@ -1357,6 +1382,9 @@ enum nl80211_reg_rule_flags { * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use */ enum nl80211_survey_info { __NL80211_SURVEY_INFO_INVALID, @@ -1521,6 +1549,7 @@ enum nl80211_channel_type { * enum nl80211_bss - netlink attributes for a BSS * * @__NL80211_BSS_INVALID: invalid + * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) @@ -1564,6 +1593,12 @@ enum nl80211_bss { /** * enum nl80211_bss_status - BSS "status" + * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. + * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. + * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. + * + * The BSS status is a BSS attribute in scan dumps, which + * indicates the status the interface has wrt. this BSS. */ enum nl80211_bss_status { NL80211_BSS_STATUS_AUTHENTICATED, @@ -1674,8 +1709,8 @@ enum nl80211_tx_rate_attributes { /** * enum nl80211_band - Frequency band - * @NL80211_BAND_2GHZ - 2.4 GHz ISM band - * @NL80211_BAND_5GHZ - around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) */ enum nl80211_band { NL80211_BAND_2GHZ, @@ -1713,9 +1748,9 @@ enum nl80211_attr_cqm { /** * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event - * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW - The RSSI level is lower than the + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the * configured threshold - * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH - The RSSI is higher than the + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the * configured threshold */ enum nl80211_cqm_rssi_threshold_event { -- cgit v1.2.3 From d99eeb87420a6da1f87064c7fa70bdf299699d90 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 18 Aug 2010 19:57:48 +0530 Subject: ath9k_common: Move bt_stomp to common for sharing with ath9k_htc. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 8 ------- drivers/net/wireless/ath/ath9k/common.c | 31 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/common.h | 10 +++++++++ drivers/net/wireless/ath/ath9k/gpio.c | 40 +++++---------------------------- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index def0cd308fdd..f0197a6046ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -437,14 +437,6 @@ void ath_ani_calibrate(unsigned long data); /* BTCOEX */ /**********/ -/* Defines the BT AR_BT_COEX_WGHT used */ -enum ath_stomp_type { - ATH_BTCOEX_NO_STOMP, - ATH_BTCOEX_STOMP_ALL, - ATH_BTCOEX_STOMP_LOW, - ATH_BTCOEX_STOMP_NONE -}; - struct ath_btcoex { bool hw_timer_enabled; spinlock_t btcoex_lock; diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 3100c87a4fcd..31cfe468e3fc 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -420,6 +420,37 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max) } EXPORT_SYMBOL(ath9k_cmn_count_streams); +/* + * Configures appropriate weight based on stomp type. + */ +void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, + enum ath_stomp_type stomp_type) +{ + struct ath_hw *ah = common->ah; + + switch (stomp_type) { + case ATH_BTCOEX_STOMP_ALL: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_ALL_WLAN_WGHT); + break; + case ATH_BTCOEX_STOMP_LOW: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + break; + case ATH_BTCOEX_STOMP_NONE: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_NONE_WLAN_WGHT); + break; + default: + ath_print(common, ATH_DBG_BTCOEX, + "Invalid Stomptype\n"); + break; + } + + ath9k_hw_btcoex_enable(ah); +} +EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); + static int __init ath9k_cmn_init(void) { return 0; diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 97809d39c73f..4aa4e7dbe4d2 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -52,6 +52,14 @@ #define ATH_EP_RND(x, mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) +/* Defines the BT AR_BT_COEX_WGHT used */ +enum ath_stomp_type { + ATH_BTCOEX_NO_STOMP, + ATH_BTCOEX_STOMP_ALL, + ATH_BTCOEX_STOMP_LOW, + ATH_BTCOEX_STOMP_NONE +}; + int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, @@ -65,3 +73,5 @@ int ath9k_cmn_key_config(struct ath_common *common, void ath9k_cmn_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); int ath9k_cmn_count_streams(unsigned int chainmask, int max); +void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, + enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 3a8ee999da5d..4a9a68bba324 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -251,36 +251,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc) } } -/* - * Configures appropriate weight based on stomp type. - */ -static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, - enum ath_stomp_type stomp_type) -{ - struct ath_hw *ah = sc->sc_ah; - - switch (stomp_type) { - case ATH_BTCOEX_STOMP_ALL: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_ALL_WLAN_WGHT); - break; - case ATH_BTCOEX_STOMP_LOW: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); - break; - case ATH_BTCOEX_STOMP_NONE: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_NONE_WLAN_WGHT); - break; - default: - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "Invalid Stomptype\n"); - break; - } - - ath9k_hw_btcoex_enable(ah); -} - static void ath9k_gen_timer_start(struct ath_hw *ah, struct ath_gen_timer *timer, u32 timer_next, @@ -319,6 +289,7 @@ static void ath_btcoex_period_timer(unsigned long data) struct ath_softc *sc = (struct ath_softc *) data; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_common *common = ath9k_hw_common(ah); u32 timer_period; bool is_btscan; @@ -328,7 +299,7 @@ static void ath_btcoex_period_timer(unsigned long data) spin_lock_bh(&btcoex->btcoex_lock); - ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL : + ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); spin_unlock_bh(&btcoex->btcoex_lock); @@ -359,17 +330,18 @@ static void ath_btcoex_no_stomp_timer(void *arg) struct ath_softc *sc = (struct ath_softc *)arg; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_common *common = ath9k_hw_common(ah); bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + ath_print(common, ATH_DBG_BTCOEX, "no stomp timer running\n"); spin_lock_bh(&btcoex->btcoex_lock); if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) - ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) - ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); spin_unlock_bh(&btcoex->btcoex_lock); } -- cgit v1.2.3 From 21cb987914cb5334af78378141efed77505ea987 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 18 Aug 2010 19:57:49 +0530 Subject: ath9k_htc: Add support for bluetooth coexistence. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/btcoex.c | 7 ++ drivers/net/wireless/ath/ath9k/hif_usb.c | 3 +- drivers/net/wireless/ath/ath9k/htc.h | 42 +++++--- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 134 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 42 +++++++- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 +++ drivers/net/wireless/ath/ath9k/htc_hst.c | 4 +- drivers/net/wireless/ath/ath9k/htc_hst.h | 2 +- drivers/net/wireless/ath/ath9k/wmi.c | 2 + drivers/net/wireless/ath/ath9k/wmi.h | 1 + 11 files changed, 230 insertions(+), 22 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/htc_drv_gpio.c diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 973ae4f49f35..4555e9983903 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -46,6 +46,7 @@ ath9k_htc-y += htc_hst.o \ htc_drv_txrx.o \ htc_drv_main.o \ htc_drv_beacon.o \ - htc_drv_init.o + htc_drv_init.o \ + htc_drv_gpio.o obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index fb4ac15f3b93..6a92e57fddf0 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -168,6 +168,7 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + u32 val; /* * Program coex mode and weight registers to @@ -177,6 +178,12 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); + if (AR_SREV_9271(ah)) { + val = REG_READ(ah, 0x50040); + val &= 0xFFFFFEFF; + REG_WRITE(ah, 0x50040, val); + } + REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 17e7a9a367e7..495f18950ac9 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -920,7 +920,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } ret = ath9k_htc_hw_init(hif_dev->htc_handle, - &hif_dev->udev->dev, hif_dev->device_id); + &hif_dev->udev->dev, hif_dev->device_id, + hif_dev->udev->product); if (ret) { ret = -EINVAL; goto err_htc_hw_init; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 43b9e21bc562..75ecf6a30d25 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -316,17 +316,32 @@ struct htc_beacon_config { u8 dtim_count; }; -#define OP_INVALID BIT(0) -#define OP_SCANNING BIT(1) -#define OP_FULL_RESET BIT(2) -#define OP_LED_ASSOCIATED BIT(3) -#define OP_LED_ON BIT(4) -#define OP_PREAMBLE_SHORT BIT(5) -#define OP_PROTECT_ENABLE BIT(6) -#define OP_ASSOCIATED BIT(7) -#define OP_ENABLE_BEACON BIT(8) -#define OP_LED_DEINIT BIT(9) -#define OP_UNPLUGGED BIT(10) +struct ath_btcoex { + u32 bt_priority_cnt; + unsigned long bt_priority_time; + int bt_stomp_type; /* Types of BT stomping */ + u32 btcoex_no_stomp; + u32 btcoex_period; + u32 btscan_no_stomp; +}; + +void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv); +void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv); +void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); + +#define OP_INVALID BIT(0) +#define OP_SCANNING BIT(1) +#define OP_FULL_RESET BIT(2) +#define OP_LED_ASSOCIATED BIT(3) +#define OP_LED_ON BIT(4) +#define OP_PREAMBLE_SHORT BIT(5) +#define OP_PROTECT_ENABLE BIT(6) +#define OP_ASSOCIATED BIT(7) +#define OP_ENABLE_BEACON BIT(8) +#define OP_LED_DEINIT BIT(9) +#define OP_UNPLUGGED BIT(10) +#define OP_BT_PRIORITY_DETECTED BIT(11) +#define OP_BT_SCAN BIT(12) struct ath9k_htc_priv { struct device *dev; @@ -391,6 +406,9 @@ struct ath9k_htc_priv { int cabq; int hwq_map[WME_NUM_AC]; + struct ath_btcoex btcoex; + struct delayed_work coex_period_work; + struct delayed_work duty_cycle_work; #ifdef CONFIG_ATH9K_HTC_DEBUGFS struct ath9k_debug debug; #endif @@ -443,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv); void ath9k_deinit_leds(struct ath9k_htc_priv *priv); int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid); + u16 devid, char *product); void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); #ifdef CONFIG_PM int ath9k_htc_resume(struct htc_target *htc_handle); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c new file mode 100644 index 000000000000..50eec9a3b88c --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -0,0 +1,134 @@ +#include "htc.h" + +/******************/ +/* BTCOEX */ +/******************/ + +/* + * Detects if there is any priority bt traffic + */ +static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_hw *ah = priv->ah; + + if (ath9k_hw_gpio_get(ah, ah->btcoex_hw.btpriority_gpio)) + btcoex->bt_priority_cnt++; + + if (time_after(jiffies, btcoex->bt_priority_time + + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + /* Detect if colocated bt started scanning */ + if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT scan detected"); + priv->op_flags |= (OP_BT_SCAN | + OP_BT_PRIORITY_DETECTED); + } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT priority traffic detected"); + priv->op_flags |= OP_BT_PRIORITY_DETECTED; + } + + btcoex->bt_priority_cnt = 0; + btcoex->bt_priority_time = jiffies; + } +} + +/* + * This is the master bt coex work which runs for every + * 45ms, bt traffic will be given priority during 55% of this + * period while wlan gets remaining 45% + */ +static void ath_btcoex_period_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + coex_period_work.work); + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_common *common = ath9k_hw_common(priv->ah); + u32 timer_period; + bool is_btscan; + int ret; + u8 cmd_rsp, aggr; + + ath_detect_bt_priority(priv); + + is_btscan = !!(priv->op_flags & OP_BT_SCAN); + + aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; + + WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); + + ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : + btcoex->bt_stomp_type); + + timer_period = is_btscan ? btcoex->btscan_no_stomp : + btcoex->btcoex_no_stomp; + ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, + msecs_to_jiffies(timer_period)); + ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, + msecs_to_jiffies(btcoex->btcoex_period)); +} + +/* + * Work to time slice between wlan and bt traffic and + * configure weight registers + */ +static void ath_btcoex_duty_cycle_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + duty_cycle_work.work); + struct ath_hw *ah = priv->ah; + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_common *common = ath9k_hw_common(ah); + bool is_btscan = priv->op_flags & OP_BT_SCAN; + + ath_print(common, ATH_DBG_BTCOEX, + "time slice work for bt and wlan\n"); + + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); + else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); +} + +void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * + btcoex->btcoex_period / 100; + btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * + btcoex->btcoex_period / 100; + INIT_DELAYED_WORK(&priv->coex_period_work, ath_btcoex_period_work); + INIT_DELAYED_WORK(&priv->duty_cycle_work, ath_btcoex_duty_cycle_work); +} + +/* + * (Re)start btcoex work + */ + +void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_hw *ah = priv->ah; + + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "Starting btcoex work"); + + btcoex->bt_priority_cnt = 0; + btcoex->bt_priority_time = jiffies; + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0); +} + + +/* + * Cancel btcoex and bt duty cycle work. + */ +void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) +{ + cancel_delayed_work_sync(&priv->coex_period_work); + cancel_delayed_work_sync(&priv->duty_cycle_work); +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 2d4279191d7a..695e2b088d10 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -41,6 +41,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); .max_power = 20, \ } +#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193" + static struct ieee80211_channel ath9k_2ghz_channels[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ @@ -605,7 +607,31 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) priv->ah->opmode = NL80211_IFTYPE_STATION; } -static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) +static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) +{ + int qnum; + + switch (priv->ah->btcoex_hw.scheme) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_3WIRE: + priv->ah->btcoex_hw.btactive_gpio = 7; + priv->ah->btcoex_hw.btpriority_gpio = 6; + priv->ah->btcoex_hw.wlanactive_gpio = 8; + priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + ath9k_hw_btcoex_init_3wire(priv->ah); + ath_htc_init_btcoex_work(priv); + qnum = priv->hwq_map[WME_AC_BE]; + ath9k_hw_init_btcoex_hw(priv->ah, qnum); + break; + default: + WARN_ON(1); + break; + } +} + +static int ath9k_init_priv(struct ath9k_htc_priv *priv, + u16 devid, char *product) { struct ath_hw *ah = NULL; struct ath_common *common; @@ -672,6 +698,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) ath9k_init_channels_rates(priv); ath9k_init_misc(priv); + if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { + ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; + ath9k_init_btcoex(priv); + } + return 0; err_queues: @@ -734,7 +765,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } -static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) +static int ath9k_init_device(struct ath9k_htc_priv *priv, + u16 devid, char *product) { struct ieee80211_hw *hw = priv->hw; struct ath_common *common; @@ -743,7 +775,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) struct ath_regulatory *reg; /* Bring up device */ - error = ath9k_init_priv(priv, devid); + error = ath9k_init_priv(priv, devid, product); if (error != 0) goto err_init; @@ -801,7 +833,7 @@ err_init: } int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid) + u16 devid, char *product) { struct ieee80211_hw *hw; struct ath9k_htc_priv *priv; @@ -835,7 +867,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, /* The device may have been unplugged earlier. */ priv->op_flags &= ~OP_UNPLUGGED; - ret = ath9k_init_device(priv, devid); + ret = ath9k_init_device(priv, devid, product); if (ret) goto err_init; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 4e345be62435..5e318cb662c6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1210,6 +1210,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); + ath_htc_resume_btcoex_work(priv); + } mutex_unlock(&priv->mutex); return ret; @@ -1254,6 +1260,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) "Monitor interface removed\n"); } + if (ah->btcoex_hw.enabled) { + ath9k_hw_btcoex_disable(ah); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) + ath_htc_cancel_btcoex_work(priv); + } + ath9k_hw_phy_disable(ah); ath9k_hw_disable(ah); ath9k_hw_configpcipowersave(ah, 1, 1); diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 705c0f342e1c..861ec9269309 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -462,9 +462,9 @@ void ath9k_htc_hw_free(struct htc_target *htc) } int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid) + struct device *dev, u16 devid, char *product) { - if (ath9k_htc_probe_device(target, dev, devid)) { + if (ath9k_htc_probe_device(target, dev, devid, product)) { printk(KERN_ERR "Failed to initialize the device\n"); return -ENODEV; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index faba6790328b..07b6509d5896 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -239,7 +239,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct device *dev); void ath9k_htc_hw_free(struct htc_target *htc); int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid); + struct device *dev, u16 devid, char *product); void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); #endif /* HTC_HST_H */ diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 6260faa658a2..45fe9cac7971 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -85,6 +85,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_TGT_DETACH_CMDID"; case WMI_TGT_TXQ_ENABLE_CMDID: return "WMI_TGT_TXQ_ENABLE_CMDID"; + case WMI_AGGR_LIMIT_CMD: + return "WMI_AGGR_LIMIT_CMD"; } return "Bogus"; diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 765db5faa2d3..a0bf857625df 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -71,6 +71,7 @@ enum wmi_cmd_id { WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, WMI_TGT_TXQ_ENABLE_CMDID, + WMI_AGGR_LIMIT_CMD = 0x0026, }; enum wmi_event_id { -- cgit v1.2.3 From 54c8067a4a0606f466faf0f30b16684b00060e70 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 18 Aug 2010 09:35:21 -0700 Subject: iwlagn: do not check for AP mode for WEP keys Even when we configure WEP keys in AP mode ones without a station pointer are default keys, so don't check for AP mode here. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 40b82d9f309e..5b967c014b41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3450,7 +3450,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, */ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) && - !sta && vif->type != NL80211_IFTYPE_AP) { + !sta) { if (cmd == SET_KEY) is_default_wep_key = !priv->key_mapping_key; else -- cgit v1.2.3 From 672ddeffeb2afad18fe1a2fc5aa14a07b4da1551 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 18 Aug 2010 09:35:22 -0700 Subject: iwlwifi: do not spuriously call ieee80211_scan_completed When a scan is aborted because the corresponding virtual interface is removed, we may still later attempt to tell mac80211 that the scan completed. This is obviously wrong, since we already told it that it was aborted, so don't do that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ac510840519c..8d7fa59364fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -508,6 +508,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); bool internal = false; + bool scan_completed = false; IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); @@ -518,7 +519,8 @@ static void iwl_bg_scan_completed(struct work_struct *work) priv->is_internal_short_scan = false; IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); internal = true; - } else { + } else if (priv->scan_request) { + scan_completed = true; priv->scan_request = NULL; priv->scan_vif = NULL; } @@ -549,7 +551,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) * into driver again into functions that will attempt to take * mutex. */ - if (!internal) + if (scan_completed) ieee80211_scan_completed(priv->hw, false); } -- cgit v1.2.3 From d70e96932de55fb2c05b1c0af1dff178651a9b77 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Aug 2010 16:11:27 +0200 Subject: cfg80211: add some documentation Add some documentation for cfg80211. I'm hoping some of the regulatory documentation will be filled by somebody more familiar with it, hint hint! :) Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 136 +++++++++++++++++++++++++++++++++++++-- include/net/cfg80211.h | 121 ++++++++++++++++++++++++++++++++-- 2 files changed, 246 insertions(+), 11 deletions(-) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 52310ac892ea..b84c9282828f 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -65,18 +65,144 @@ +!Ainclude/net/cfg80211.h The cfg80211 subsystem - -MISSING - +!Pinclude/net/cfg80211.h Introduction - + + Device registration +!Pinclude/net/cfg80211.h Device registration !Finclude/net/cfg80211.h ieee80211_band - +!Finclude/net/cfg80211.h ieee80211_channel_flags +!Finclude/net/cfg80211.h ieee80211_channel +!Finclude/net/cfg80211.h ieee80211_rate_flags +!Finclude/net/cfg80211.h ieee80211_rate +!Finclude/net/cfg80211.h ieee80211_sta_ht_cap +!Finclude/net/cfg80211.h ieee80211_supported_band +!Finclude/net/cfg80211.h cfg80211_signal_type +!Finclude/net/cfg80211.h wiphy_params_flags +!Finclude/net/cfg80211.h wiphy_flags +!Finclude/net/cfg80211.h wiphy +!Finclude/net/cfg80211.h wireless_dev +!Finclude/net/cfg80211.h wiphy_new +!Finclude/net/cfg80211.h wiphy_register +!Finclude/net/cfg80211.h wiphy_unregister +!Finclude/net/cfg80211.h wiphy_free + +!Finclude/net/cfg80211.h wiphy_name +!Finclude/net/cfg80211.h wiphy_dev +!Finclude/net/cfg80211.h wiphy_priv +!Finclude/net/cfg80211.h priv_to_wiphy +!Finclude/net/cfg80211.h set_wiphy_dev +!Finclude/net/cfg80211.h wdev_priv + + + Actions and configuration +!Pinclude/net/cfg80211.h Actions and configuration +!Finclude/net/cfg80211.h cfg80211_ops +!Finclude/net/cfg80211.h vif_params +!Finclude/net/cfg80211.h key_params +!Finclude/net/cfg80211.h survey_info_flags +!Finclude/net/cfg80211.h survey_info +!Finclude/net/cfg80211.h beacon_parameters +!Finclude/net/cfg80211.h plink_actions +!Finclude/net/cfg80211.h station_parameters +!Finclude/net/cfg80211.h station_info_flags +!Finclude/net/cfg80211.h rate_info_flags +!Finclude/net/cfg80211.h rate_info +!Finclude/net/cfg80211.h station_info +!Finclude/net/cfg80211.h monitor_flags +!Finclude/net/cfg80211.h mpath_info_flags +!Finclude/net/cfg80211.h mpath_info +!Finclude/net/cfg80211.h bss_parameters +!Finclude/net/cfg80211.h ieee80211_txq_params +!Finclude/net/cfg80211.h cfg80211_crypto_settings +!Finclude/net/cfg80211.h cfg80211_auth_request +!Finclude/net/cfg80211.h cfg80211_assoc_request +!Finclude/net/cfg80211.h cfg80211_deauth_request +!Finclude/net/cfg80211.h cfg80211_disassoc_request +!Finclude/net/cfg80211.h cfg80211_ibss_params +!Finclude/net/cfg80211.h cfg80211_connect_params +!Finclude/net/cfg80211.h cfg80211_pmksa +!Finclude/net/cfg80211.h cfg80211_send_rx_auth +!Finclude/net/cfg80211.h cfg80211_send_auth_timeout +!Finclude/net/cfg80211.h __cfg80211_auth_canceled +!Finclude/net/cfg80211.h cfg80211_send_rx_assoc +!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout +!Finclude/net/cfg80211.h cfg80211_send_deauth +!Finclude/net/cfg80211.h __cfg80211_send_deauth +!Finclude/net/cfg80211.h cfg80211_send_disassoc +!Finclude/net/cfg80211.h __cfg80211_send_disassoc +!Finclude/net/cfg80211.h cfg80211_ibss_joined +!Finclude/net/cfg80211.h cfg80211_connect_result +!Finclude/net/cfg80211.h cfg80211_roamed +!Finclude/net/cfg80211.h cfg80211_disconnected +!Finclude/net/cfg80211.h cfg80211_ready_on_channel +!Finclude/net/cfg80211.h cfg80211_remain_on_channel_expired +!Finclude/net/cfg80211.h cfg80211_new_sta +!Finclude/net/cfg80211.h cfg80211_rx_mgmt +!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status +!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify +!Finclude/net/cfg80211.h cfg80211_michael_mic_failure + + + Scanning and BSS list handling +!Pinclude/net/cfg80211.h Scanning and BSS list handling +!Finclude/net/cfg80211.h cfg80211_ssid +!Finclude/net/cfg80211.h cfg80211_scan_request +!Finclude/net/cfg80211.h cfg80211_scan_done +!Finclude/net/cfg80211.h cfg80211_bss +!Finclude/net/cfg80211.h cfg80211_inform_bss_frame +!Finclude/net/cfg80211.h cfg80211_inform_bss +!Finclude/net/cfg80211.h cfg80211_unlink_bss +!Finclude/net/cfg80211.h cfg80211_find_ie +!Finclude/net/cfg80211.h ieee80211_bss_get_ie + + + Utility functions +!Pinclude/net/cfg80211.h Utility functions +!Finclude/net/cfg80211.h ieee80211_channel_to_frequency +!Finclude/net/cfg80211.h ieee80211_frequency_to_channel +!Finclude/net/cfg80211.h ieee80211_get_channel +!Finclude/net/cfg80211.h ieee80211_get_response_rate +!Finclude/net/cfg80211.h ieee80211_hdrlen +!Finclude/net/cfg80211.h ieee80211_get_hdrlen_from_skb +!Finclude/net/cfg80211.h ieee80211_radiotap_iterator + + + Data path helpers +!Pinclude/net/cfg80211.h Data path helpers +!Finclude/net/cfg80211.h ieee80211_data_to_8023 +!Finclude/net/cfg80211.h ieee80211_data_from_8023 +!Finclude/net/cfg80211.h ieee80211_amsdu_to_8023s +!Finclude/net/cfg80211.h cfg80211_classify8021d + + + Regulatory enforcement infrastructure +!Pinclude/net/cfg80211.h Regulatory enforcement infrastructure +!Finclude/net/cfg80211.h regulatory_hint +!Finclude/net/cfg80211.h wiphy_apply_custom_regulatory +!Finclude/net/cfg80211.h freq_reg_info + + + RFkill integration +!Pinclude/net/cfg80211.h RFkill integration +!Finclude/net/cfg80211.h wiphy_rfkill_set_hw_state +!Finclude/net/cfg80211.h wiphy_rfkill_start_polling +!Finclude/net/cfg80211.h wiphy_rfkill_stop_polling + + + Test mode +!Pinclude/net/cfg80211.h Test mode +!Finclude/net/cfg80211.h cfg80211_testmode_alloc_reply_skb +!Finclude/net/cfg80211.h cfg80211_testmode_reply +!Finclude/net/cfg80211.h cfg80211_testmode_alloc_event_skb +!Finclude/net/cfg80211.h cfg80211_testmode_event + diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6a98b1b3bfde..f2740537b5d6 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -25,6 +25,43 @@ #include +/** + * DOC: Introduction + * + * cfg80211 is the configuration API for 802.11 devices in Linux. It bridges + * userspace and drivers, and offers some utility functionality associated + * with 802.11. cfg80211 must, directly or indirectly via mac80211, be used + * by all modern wireless drivers in Linux, so that they offer a consistent + * API through nl80211. For backward compatibility, cfg80211 also offers + * wireless extensions to userspace, but hides them from drivers completely. + * + * Additionally, cfg80211 contains code to help enforce regulatory spectrum + * use restrictions. + */ + + +/** + * DOC: Device registration + * + * In order for a driver to use cfg80211, it must register the hardware device + * with cfg80211. This happens through a number of hardware capability structs + * described below. + * + * The fundamental structure for each device is the 'wiphy', of which each + * instance describes a physical wireless device connected to the system. Each + * such wiphy can have zero, one, or many virtual interfaces associated with + * it, which need to be identified as such by pointing the network interface's + * @ieee80211_ptr pointer to a &struct wireless_dev which further describes + * the wireless part of the interface, normally this struct is embedded in the + * network interface's private data area. Drivers can optionally allow creating + * or destroying virtual interfaces on the fly, but without at least one or the + * ability to create some the wireless device isn't useful. + * + * Each wiphy structure contains device capability information, and also has + * a pointer to the various operations the driver offers. The definitions and + * structures here describe these capabilities in detail. + */ + /* * wireless hardware capability structures */ @@ -204,6 +241,21 @@ struct ieee80211_supported_band { * Wireless hardware/device configuration structures and methods */ +/** + * DOC: Actions and configuration + * + * Each wireless device and each virtual interface offer a set of configuration + * operations and other actions that are invoked by userspace. Each of these + * actions is described in the operations structure, and the parameters these + * operations use are described separately. + * + * Additionally, some operations are asynchronous and expect to get status + * information via some functions that drivers need to call. + * + * Scanning and BSS list handling with its associated functionality is described + * in a separate chapter. + */ + /** * struct vif_params - describes virtual interface parameters * @mesh_id: mesh ID to use @@ -570,8 +622,28 @@ struct ieee80211_txq_params { /* from net/wireless.h */ struct wiphy; -/* from net/ieee80211.h */ -struct ieee80211_channel; +/** + * DOC: Scanning and BSS list handling + * + * The scanning process itself is fairly simple, but cfg80211 offers quite + * a bit of helper functionality. To start a scan, the scan operation will + * be invoked with a scan definition. This scan definition contains the + * channels to scan, and the SSIDs to send probe requests for (including the + * wildcard, if desired). A passive scan is indicated by having no SSIDs to + * probe. Additionally, a scan request may contain extra information elements + * that should be added to the probe request. The IEs are guaranteed to be + * well-formed, and will not exceed the maximum length the driver advertised + * in the wiphy structure. + * + * When scanning finds a BSS, cfg80211 needs to be notified of that, because + * it is responsible for maintaining the BSS list; the driver should not + * maintain a list itself. For this notification, various functions exist. + * + * Since drivers do not maintain a BSS list, there are also a number of + * functions to search for a BSS and obtain information about it from the + * BSS structure cfg80211 maintains. The BSS list is also made available + * to userspace. + */ /** * struct cfg80211_ssid - SSID description @@ -1574,8 +1646,10 @@ static inline void *wdev_priv(struct wireless_dev *wdev) return wiphy_priv(wdev->wiphy); } -/* - * Utility functions +/** + * DOC: Utility functions + * + * cfg80211 offers a number of utility functions that can be useful. */ /** @@ -1728,6 +1802,14 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); +/** + * DOC: Data path helpers + * + * In addition to generic utilities, cfg80211 also offers + * functions that help implement the data path for devices + * that do not do the 802.11/802.3 conversion on the device. + */ + /** * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 * @skb: the 802.11 data frame @@ -1788,8 +1870,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb); */ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); -/* - * Regulatory helper functions for wiphys +/** + * DOC: Regulatory enforcement infrastructure + * + * TODO */ /** @@ -2191,6 +2275,20 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, */ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); +/** + * DOC: RFkill integration + * + * RFkill integration in cfg80211 is almost invisible to drivers, + * as cfg80211 automatically registers an rfkill instance for each + * wireless device it knows about. Soft kill is also translated + * into disconnecting and turning all interfaces off, drivers are + * expected to turn off the device when all interfaces are down. + * + * However, devices may have a hard RFkill line, in which case they + * also need to interact with the rfkill subsystem, via cfg80211. + * They can do this with a few helper functions documented here. + */ + /** * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state * @wiphy: the wiphy @@ -2211,6 +2309,17 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy); void wiphy_rfkill_stop_polling(struct wiphy *wiphy); #ifdef CONFIG_NL80211_TESTMODE +/** + * DOC: Test mode + * + * Test mode is a set of utility functions to allow drivers to + * interact with driver-specific tools to aid, for instance, + * factory programming. + * + * This chapter describes how drivers interact with it, for more + * information see the nl80211 book's chapter on it. + */ + /** * cfg80211_testmode_alloc_reply_skb - allocate testmode reply * @wiphy: the wiphy -- cgit v1.2.3 From ec550d246e38e1b4ea8604b5c71ccb72e38f3290 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Aug 2010 14:45:09 -0700 Subject: net: ip_append_data() optim Compiler is not smart enough to avoid a conditional branch. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 6d2753c7ffdd..e42762023c27 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -837,10 +837,9 @@ int ip_append_data(struct sock *sk, inet->cork.length = 0; sk->sk_sndmsg_page = NULL; sk->sk_sndmsg_off = 0; - if ((exthdrlen = rt->dst.header_len) != 0) { - length += exthdrlen; - transhdrlen += exthdrlen; - } + exthdrlen = rt->dst.header_len; + length += exthdrlen; + transhdrlen += exthdrlen; } else { rt = (struct rtable *)inet->cork.dst; if (inet->cork.flags & IPCORK_OPT) -- cgit v1.2.3 From 5a46790ca4c40fdb6ed5336d7d6b593c96326b31 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 24 Aug 2010 14:46:53 -0700 Subject: include/linux/if_ether.h: Remove unused #define MAC_FMT Last use was removed, so remove the #define. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/linux/if_ether.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index bed7a4682b90..f9c3df03db0f 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -137,8 +137,6 @@ extern struct ctl_table ether_table[]; extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" - #endif #endif /* _LINUX_IF_ETHER_H */ -- cgit v1.2.3 From c2e3143e3c46ede22336316b3ff4746727c0d93a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 24 Aug 2010 14:48:10 -0700 Subject: tc: add meta match on receive hash Trivial extension to existing meta data match rules to allow matching on skb receive hash value. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/tc_ematch/tc_em_meta.h | 1 + net/sched/em_meta.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index 0864206ec1a3..7138962664f8 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -79,6 +79,7 @@ enum { TCF_META_ID_SK_SENDMSG_OFF, TCF_META_ID_SK_WRITE_PENDING, TCF_META_ID_VLAN_TAG, + TCF_META_ID_RXHASH, __TCF_META_ID_MAX }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 3bcac8aa333c..34da5e29ea1a 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -223,6 +223,11 @@ META_COLLECTOR(int_maclen) dst->value = skb->mac_len; } +META_COLLECTOR(int_rxhash) +{ + dst->value = skb_get_rxhash(skb); +} + /************************************************************************** * Netfilter **************************************************************************/ @@ -541,6 +546,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag), + [META_ID(RXHASH)] = META_FUNC(int_rxhash), } }; -- cgit v1.2.3 From 69351a2933428515b31fe54100f90a669cbbd384 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:45:05 +0000 Subject: mlx4_en: Fixed incorrect unmapping on RX flow. When allocating new fragments to replace the ones that would be passed to the stack, The fragments that should be replaced, are the ones that were already used. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 2add04025fd0..4335c58160d7 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -459,7 +459,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv, goto fail; /* Unmap buffer */ - pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, + pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size, PCI_DMA_FROMDEVICE); } /* Adjust size of last fragment to match actual length */ -- cgit v1.2.3 From 00d7d7bc6e886ef48af6ed766eb12b8cec241d35 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:45:20 +0000 Subject: mlx4_en: Setting actual RX ring size When configuring HW resources, the RX ring size that is passed should be the actual size that depends on number of buffers that we succeeded to allocate. The mask for ring size should also be configured accordingly Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 4335c58160d7..7a5123c4a366 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -251,7 +251,6 @@ reduce_rings: ring->prod--; mlx4_en_free_rx_desc(priv, ring, ring->actual_size); } - ring->size_mask = ring->actual_size - 1; } return 0; @@ -389,6 +388,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; + ring->size_mask = ring->actual_size - 1; mlx4_en_update_rx_prod_db(ring); } @@ -816,7 +816,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn, qp->event = mlx4_en_sqp_event; memset(context, 0, sizeof *context); - mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0, + mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0, qpn, ring->cqn, context); context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma); -- cgit v1.2.3 From 8bf2e58f8b7a14244bf182ad0a3ba0457ad70c62 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:45:30 +0000 Subject: mlx4_en: Setting dev->perm_addr field Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index d00bfe250b05..4d6dac7617f7 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -1023,9 +1023,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, /* Set defualt MAC */ dev->addr_len = ETH_ALEN; - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[ETH_ALEN - 1 - i] = - (u8) (priv->mac >> (8 * i)); + for (i = 0; i < ETH_ALEN; i++) { + dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i)); + dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i)); + } /* * Set driver features -- cgit v1.2.3 From 7c2873809dd1a2d5e46be3f0ff2071fcdc3cf0fd Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:45:45 +0000 Subject: mlx4_en: performing CLOSE_PORT at the end of tear-down process All port's resources should be closed before we give the CLOSE_PORT command to the firmware. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 4d6dac7617f7..985e6f83b31a 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -704,9 +704,8 @@ void mlx4_en_stop_port(struct net_device *dev) netif_tx_stop_all_queues(dev); netif_tx_unlock_bh(dev); - /* close port*/ + /* Set port as not active */ priv->port_up = false; - mlx4_CLOSE_PORT(mdev->dev, priv->port); /* Unregister Mac address for the port */ mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); @@ -731,6 +730,9 @@ void mlx4_en_stop_port(struct net_device *dev) msleep(1); mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]); } + + /* close port*/ + mlx4_CLOSE_PORT(mdev->dev, priv->port); } static void mlx4_en_restart(struct work_struct *work) -- cgit v1.2.3 From a0b4e6e09c79df9efdb9872f30eb4cdb291c6c78 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:45:54 +0000 Subject: mlx4_en: Fixed MAX_TX_RINGS definition Defined as sum of default number of TX rings and number of rings used for priority flow control mode. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/mlx4_en.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 9d0932348b96..554014bd8af5 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -61,7 +61,6 @@ #define MLX4_EN_PAGE_SHIFT 12 #define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) -#define MAX_TX_RINGS 16 #define MAX_RX_RINGS 16 #define TXBB_SIZE 64 #define HEADROOM (2048 / TXBB_SIZE + 1) @@ -107,6 +106,7 @@ enum { #define MLX4_EN_SMALL_PKT_SIZE 64 #define MLX4_EN_NUM_TX_RINGS 8 #define MLX4_EN_NUM_PPP_RINGS 8 +#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS) #define MLX4_EN_DEF_TX_RING_SIZE 512 #define MLX4_EN_DEF_RX_RING_SIZE 1024 -- cgit v1.2.3 From e5cc44b2eb2b8192c9623eb877936063ba8556f3 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:01 +0000 Subject: mlx4_en: Reporting link state with KERN_INFO Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 4 ++-- drivers/net/mlx4/mlx4_en.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 985e6f83b31a..34cfa3cfbdae 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -528,10 +528,10 @@ static void mlx4_en_linkstate(struct work_struct *work) * report to system log */ if (priv->last_link_state != linkstate) { if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) { - en_dbg(LINK, priv, "Link Down\n"); + en_info(priv, "Link Down\n"); netif_carrier_off(priv->dev); } else { - en_dbg(LINK, priv, "Link Up\n"); + en_info(priv, "Link Up\n"); netif_carrier_on(priv->dev); } } diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 554014bd8af5..edf6523702c0 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -554,6 +554,8 @@ do { \ en_print(KERN_WARNING, priv, format, ##arg) #define en_err(priv, format, arg...) \ en_print(KERN_ERR, priv, format, ##arg) +#define en_info(priv, format, arg...) \ + en_print(KERN_INFO, priv, format, ## arg) #define mlx4_err(mdev, format, arg...) \ pr_err("%s %s: " format, DRV_NAME, \ -- cgit v1.2.3 From 3005ad40b95168aad530f1179cff47411b3ea8da Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:07 +0000 Subject: mlx4_en: Validate port up prior to transmitting We might try to use resources which were not activated. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 580968f304eb..3deabd1d0357 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -612,6 +612,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) int lso_header_size; void *fragptr; + if (!priv->port_up) + goto tx_drop; + real_size = get_real_size(skb, dev, &lso_header_size); if (unlikely(!real_size)) goto tx_drop; -- cgit v1.2.3 From e7c1c2c46201e46f8ce817196507d2ffd3dafd8e Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:18 +0000 Subject: mlx4_en: Added self diagnostics test implementation The selftest includes 5 features: 1. Interrupt test: Executing commands and receiving command completion on all our interrupt vectors. 2. Link test: Verifying we are connected to valid link partner. 3. Speed test: Check that we negotiated link speed correctly. 4. Registers test: Activate HW health check command. 5. Loopback test: Send a packet on loopback interface and catch it on RX side. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/Makefile | 2 +- drivers/net/mlx4/en_ethtool.c | 79 ++++++++++++------ drivers/net/mlx4/en_netdev.c | 2 +- drivers/net/mlx4/en_port.c | 32 ++++++++ drivers/net/mlx4/en_port.h | 14 ++++ drivers/net/mlx4/en_rx.c | 20 +++++ drivers/net/mlx4/en_selftest.c | 179 +++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx4/en_tx.c | 16 ++++ drivers/net/mlx4/eq.c | 44 ++++++++++ drivers/net/mlx4/fw.c | 3 + drivers/net/mlx4/fw.h | 1 + drivers/net/mlx4/main.c | 1 + drivers/net/mlx4/mlx4_en.h | 19 +++++ include/linux/mlx4/cmd.h | 1 + include/linux/mlx4/device.h | 2 + 15 files changed, 388 insertions(+), 27 deletions(-) create mode 100644 drivers/net/mlx4/en_selftest.c diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile index 1fd068e1d930..d1aa45a15854 100644 --- a/drivers/net/mlx4/Makefile +++ b/drivers/net/mlx4/Makefile @@ -6,4 +6,4 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \ obj-$(CONFIG_MLX4_EN) += mlx4_en.o mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \ - en_resources.o en_netdev.o + en_resources.o en_netdev.o en_selftest.o diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 398d54136967..f7d72d7a8704 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -125,6 +125,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = { #define NUM_MAIN_STATS 21 #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) +static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { + "Interupt Test", + "Link Test", + "Speed Test", + "Register Test", + "Loopback Test", +}; + static u32 mlx4_en_get_msglevel(struct net_device *dev) { return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable; @@ -146,10 +154,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset) { struct mlx4_en_priv *priv = netdev_priv(dev); - if (sset != ETH_SS_STATS) + switch (sset) { + case ETH_SS_STATS: + return NUM_ALL_STATS + + (priv->tx_ring_num + priv->rx_ring_num) * 2; + case ETH_SS_TEST: + return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2; + default: return -EOPNOTSUPP; - - return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2; + } } static void mlx4_en_get_ethtool_stats(struct net_device *dev, @@ -181,6 +194,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, } +static void mlx4_en_self_test(struct net_device *dev, + struct ethtool_test *etest, u64 *buf) +{ + mlx4_en_ex_selftest(dev, &etest->flags, buf); +} + static void mlx4_en_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { @@ -188,30 +207,39 @@ static void mlx4_en_get_strings(struct net_device *dev, int index = 0; int i; - if (stringset != ETH_SS_STATS) - return; - - /* Add main counters */ - for (i = 0; i < NUM_MAIN_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); - for (i = 0; i < NUM_PORT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, + switch (stringset) { + case ETH_SS_TEST: + for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++) + strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); + if (priv->mdev->dev->caps.loopback_support) + for (; i < MLX4_EN_NUM_SELF_TEST; i++) + strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); + break; + + case ETH_SS_STATS: + /* Add main counters */ + for (i = 0; i < NUM_MAIN_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); + for (i = 0; i< NUM_PORT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i + NUM_MAIN_STATS]); - for (i = 0; i < priv->tx_ring_num; i++) { - sprintf(data + (index++) * ETH_GSTRING_LEN, - "tx%d_packets", i); - sprintf(data + (index++) * ETH_GSTRING_LEN, - "tx%d_bytes", i); - } - for (i = 0; i < priv->rx_ring_num; i++) { - sprintf(data + (index++) * ETH_GSTRING_LEN, - "rx%d_packets", i); - sprintf(data + (index++) * ETH_GSTRING_LEN, - "rx%d_bytes", i); - } - for (i = 0; i < NUM_PKT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, + for (i = 0; i < priv->tx_ring_num; i++) { + sprintf(data + (index++) * ETH_GSTRING_LEN, + "tx%d_packets", i); + sprintf(data + (index++) * ETH_GSTRING_LEN, + "tx%d_bytes", i); + } + for (i = 0; i < priv->rx_ring_num; i++) { + sprintf(data + (index++) * ETH_GSTRING_LEN, + "rx%d_packets", i); + sprintf(data + (index++) * ETH_GSTRING_LEN, + "rx%d_bytes", i); + } + for (i = 0; i< NUM_PKT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); + break; + } } static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -439,6 +467,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_strings = mlx4_en_get_strings, .get_sset_count = mlx4_en_get_sset_count, .get_ethtool_stats = mlx4_en_get_ethtool_stats, + .self_test = mlx4_en_self_test, .get_wol = mlx4_en_get_wol, .get_msglevel = mlx4_en_get_msglevel, .set_msglevel = mlx4_en_set_msglevel, diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 34cfa3cfbdae..968e75b7acf4 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -109,7 +109,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) mutex_unlock(&mdev->state_lock); } -static u64 mlx4_en_mac_to_u64(u8 *addr) +u64 mlx4_en_mac_to_u64(u8 *addr) { u64 mac = 0; int i; diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index a29abe845d2e..aa3ef2aee5bf 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -142,6 +142,38 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, return err; } +int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) +{ + struct mlx4_en_query_port_context *qport_context; + struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); + struct mlx4_en_port_state *state = &priv->port_state; + struct mlx4_cmd_mailbox *mailbox; + int err; + + mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + memset(mailbox->buf, 0, sizeof(*qport_context)); + err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0, + MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B); + if (err) + goto out; + qport_context = mailbox->buf; + + /* This command is always accessed from Ethtool context + * already synchronized, no need in locking */ + state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); + if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) == + MLX4_EN_1G_SPEED) + state->link_speed = 1000; + else + state->link_speed = 10000; + state->transciver = qport_context->transceiver; + +out: + mlx4_free_cmd_mailbox(mdev->dev, mailbox); + return err; +} int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) { diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h index e6477f12beb5..f6511aa2b7df 100644 --- a/drivers/net/mlx4/en_port.h +++ b/drivers/net/mlx4/en_port.h @@ -84,6 +84,20 @@ enum { MLX4_MCAST_ENABLE = 2, }; +struct mlx4_en_query_port_context { + u8 link_up; +#define MLX4_EN_LINK_UP_MASK 0x80 + u8 reserved; + __be16 mtu; + u8 reserved2; + u8 link_speed; +#define MLX4_EN_SPEED_MASK 0x3 +#define MLX4_EN_1G_SPEED 0x2 + u16 reserved3[5]; + __be64 mac; + u8 transceiver; +}; + struct mlx4_en_stat_out_mbox { /* Received frames with a length of 64 octets */ diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 7a5123c4a366..f421a3d42723 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -541,6 +541,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, return skb; } +static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb) +{ + int i; + int offset = ETH_HLEN; + + for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) { + if (*(skb->data + offset) != (unsigned char) (i & 0xff)) + goto out_loopback; + } + /* Loopback found */ + priv->loopback_ok = 1; + +out_loopback: + dev_kfree_skb_any(skb); +} int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) { @@ -655,6 +670,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud goto next; } + if (unlikely(priv->validate_loopback)) { + validate_loopback(priv, skb); + goto next; + } + skb->ip_summed = ip_summed; skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c new file mode 100644 index 000000000000..43357d35616a --- /dev/null +++ b/drivers/net/mlx4/en_selftest.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2007 Mellanox Technologies. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include +#include +#include +#include + +#include "mlx4_en.h" + + +static int mlx4_en_test_registers(struct mlx4_en_priv *priv) +{ + return mlx4_cmd(priv->mdev->dev, 0, 0, 0, MLX4_CMD_HW_HEALTH_CHECK, + MLX4_CMD_TIME_CLASS_A); +} + +static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv) +{ + struct sk_buff *skb; + struct ethhdr *ethh; + unsigned char *packet; + unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD; + unsigned int i; + int err; + + + /* build the pkt before xmit */ + skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN); + if (!skb) { + en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n"); + return -ENOMEM; + } + skb_reserve(skb, NET_IP_ALIGN); + + ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr)); + packet = (unsigned char *)skb_put(skb, packet_size); + memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN); + memset(ethh->h_source, 0, ETH_ALEN); + ethh->h_proto = htons(ETH_P_ARP); + skb_set_mac_header(skb, 0); + for (i = 0; i < packet_size; ++i) /* fill our packet */ + packet[i] = (unsigned char)(i & 0xff); + + /* xmit the pkt */ + err = mlx4_en_xmit(skb, priv->dev); + return err; +} + +static int mlx4_en_test_loopback(struct mlx4_en_priv *priv) +{ + u32 loopback_ok = 0; + int i; + + + priv->loopback_ok = 0; + priv->validate_loopback = 1; + + /* xmit */ + if (mlx4_en_test_loopback_xmit(priv)) { + en_err(priv, "Transmitting loopback packet failed\n"); + goto mlx4_en_test_loopback_exit; + } + + /* polling for result */ + for (i = 0; i < MLX4_EN_LOOPBACK_RETRIES; ++i) { + msleep(MLX4_EN_LOOPBACK_TIMEOUT); + if (priv->loopback_ok) { + loopback_ok = 1; + break; + } + } + if (!loopback_ok) + en_err(priv, "Loopback packet didn't arrive\n"); + +mlx4_en_test_loopback_exit: + + priv->validate_loopback = 0; + return (!loopback_ok); +} + + +static int mlx4_en_test_link(struct mlx4_en_priv *priv) +{ + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + if (priv->port_state.link_state == 1) + return 0; + else + return 1; +} + +static int mlx4_en_test_speed(struct mlx4_en_priv *priv) +{ + + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + + /* The device currently only supports 10G speed */ + if (priv->port_state.link_speed != SPEED_10000) + return priv->port_state.link_speed; + return 0; +} + + +void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + struct mlx4_en_tx_ring *tx_ring; + int i, carrier_ok; + + memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST); + + if (*flags & ETH_TEST_FL_OFFLINE) { + /* disable the interface */ + carrier_ok = netif_carrier_ok(dev); + + netif_carrier_off(dev); +retry_tx: + /* Wait untill all tx queues are empty. + * there should not be any additional incoming traffic + * since we turned the carrier off */ + msleep(200); + for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) { + tx_ring = &priv->tx_ring[i]; + if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb)) + goto retry_tx; + } + + if (priv->mdev->dev->caps.loopback_support){ + buf[3] = mlx4_en_test_registers(priv); + buf[4] = mlx4_en_test_loopback(priv); + } + + if (carrier_ok) + netif_carrier_on(dev); + + } + buf[0] = mlx4_test_interrupts(mdev->dev); + buf[1] = mlx4_en_test_link(priv); + buf[2] = mlx4_en_test_speed(priv); + + for (i = 0; i < MLX4_EN_NUM_SELF_TEST; i++) { + if (buf[i]) + *flags |= ETH_TEST_FL_FAILED; + } +} diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 3deabd1d0357..b875f9c38848 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -600,6 +600,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) struct mlx4_wqe_data_seg *data; struct skb_frag_struct *frag; struct mlx4_en_tx_info *tx_info; + struct ethhdr *ethh; + u64 mac; + u32 mac_l, mac_h; int tx_ind = 0; int nr_txbb; int desc_size; @@ -679,6 +682,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) priv->port_stats.tx_chksum_offload++; } + if (unlikely(priv->validate_loopback)) { + /* Copy dst mac address to wqe */ + skb_reset_mac_header(skb); + ethh = eth_hdr(skb); + if (ethh && ethh->h_dest) { + mac = mlx4_en_mac_to_u64(ethh->h_dest); + mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16); + mac_l = (u32) (mac & 0xffffffff); + tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h); + tx_desc->ctrl.imm = cpu_to_be32(mac_l); + } + } + /* Handle LSO (TSO) packets */ if (lso_header_size) { /* Mark opcode as LSO */ diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 6d7b2bf210ce..552d0fce6f67 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) kfree(priv->eq_table.uar_map); } + +/* A test that verifies that we can accept interrupts on all + * the irq vectors of the device. + * Interrupts are checked using the NOP command. + */ +int mlx4_test_interrupts(struct mlx4_dev *dev) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + int i; + int err; + + err = mlx4_NOP(dev); + /* When not in MSI_X, there is only one irq to check */ + if (!(dev->flags & MLX4_FLAG_MSI_X)) + return err; + + /* A loop over all completion vectors, for each vector we will check + * whether it works by mapping command completions to that vector + * and performing a NOP command + */ + for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) { + /* Temporary use polling for command completions */ + mlx4_cmd_use_polling(dev); + + /* Map the new eq to handle all asyncronous events */ + err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, + priv->eq_table.eq[i].eqn); + if (err) { + mlx4_warn(dev, "Failed mapping eq for interrupt test\n"); + mlx4_cmd_use_events(dev); + break; + } + + /* Go back to using events */ + mlx4_cmd_use_events(dev); + err = mlx4_NOP(dev); + } + + /* Return to default */ + mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, + priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); + return err; +} +EXPORT_SYMBOL(mlx4_test_interrupts); diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 04f42ae1eda0..a87bf3c97055 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -178,6 +178,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f +#define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43 #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 #define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 @@ -268,6 +269,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->max_msg_sz = 1 << (field & 0x1f); MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); dev_cap->stat_rate_support = stat_rate; + MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET); + dev_cap->loopback_support = field & 0x1; MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); dev_cap->reserved_uars = field >> 4; diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 526d7f30c041..2cc1ba5452e3 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h @@ -74,6 +74,7 @@ struct mlx4_dev_cap { u64 def_mac[MLX4_MAX_PORTS + 1]; u16 eth_mtu[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; + int loopback_support; u32 flags; int reserved_uars; int uar_size; diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 5102ab1ac561..7390cdb19414 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -221,6 +221,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.bmme_flags = dev_cap->bmme_flags; dev->caps.reserved_lkey = dev_cap->reserved_lkey; dev->caps.stat_rate_support = dev_cap->stat_rate_support; + dev->caps.loopback_support = dev_cap->loopback_support; dev->caps.max_gso_sz = dev_cap->max_gso_sz; dev->caps.log_num_macs = log_num_mac; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index edf6523702c0..a09598b2b12e 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -45,6 +45,7 @@ #include #include #include +#include #include "en_port.h" @@ -139,10 +140,14 @@ enum { #define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) #define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) +#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN) #define MLX4_EN_MIN_MTU 46 #define ETH_BCAST 0xffffffffffffULL +#define MLX4_EN_LOOPBACK_RETRIES 5 +#define MLX4_EN_LOOPBACK_TIMEOUT 100 + #ifdef MLX4_EN_PERF_STAT /* Number of samples to 'average' */ #define AVG_SIZE 128 @@ -356,6 +361,12 @@ struct mlx4_en_rss_context { __be32 rss_key[10]; }; +struct mlx4_en_port_state { + int link_state; + int link_speed; + int transciver; +}; + struct mlx4_en_pkt_stats { unsigned long broadcast; unsigned long rx_prio[8]; @@ -404,6 +415,7 @@ struct mlx4_en_priv { struct vlan_group *vlgrp; struct net_device_stats stats; struct net_device_stats ret_stats; + struct mlx4_en_port_state port_state; spinlock_t stats_lock; unsigned long last_moder_packets; @@ -422,6 +434,8 @@ struct mlx4_en_priv { u16 sample_interval; u16 adaptive_rx_coal; u32 msg_enable; + u32 loopback_ok; + u32 validate_loopback; struct mlx4_hwq_resources res; int link_state; @@ -530,6 +544,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u8 promisc); int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset); +int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port); + +#define MLX4_EN_NUM_SELF_TEST 5 +void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); +u64 mlx4_en_mac_to_u64(u8 *addr); /* * Globals diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 0f82293a82ed..78a1b9671752 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -56,6 +56,7 @@ enum { MLX4_CMD_QUERY_HCA = 0xb, MLX4_CMD_QUERY_PORT = 0x43, MLX4_CMD_SENSE_PORT = 0x4d, + MLX4_CMD_HW_HEALTH_CHECK = 0x50, MLX4_CMD_SET_PORT = 0xc, MLX4_CMD_ACCESS_DDR = 0x2e, MLX4_CMD_MAP_ICM = 0xffa, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 7a7f9c1e679a..2cec58722738 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -229,6 +229,7 @@ struct mlx4_caps { u32 bmme_flags; u32 reserved_lkey; u16 stat_rate_support; + int loopback_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; int max_gso_sz; int reserved_qps_cnt[MLX4_NUM_QP_REGION]; @@ -480,5 +481,6 @@ void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u32 *lkey, u32 *rkey); int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr); int mlx4_SYNC_TPT(struct mlx4_dev *dev); +int mlx4_test_interrupts(struct mlx4_dev *dev); #endif /* MLX4_DEVICE_H */ -- cgit v1.2.3 From 7699517db435fd24143bd32dd644275e3eeb4c86 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:23 +0000 Subject: mlx4_en: Fixing report in Ethtool get_settings The report now based on query from FW, giving the correct tranciever type and link speed. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 27 +++++++++++++++++++++++++-- drivers/net/mlx4/fw.c | 9 +++++++++ drivers/net/mlx4/fw.h | 4 ++++ drivers/net/mlx4/main.c | 4 ++++ include/linux/mlx4/device.h | 4 ++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index f7d72d7a8704..fa2f2f43ab48 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -244,16 +244,39 @@ static void mlx4_en_get_strings(struct net_device *dev, static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { + struct mlx4_en_priv *priv = netdev_priv(dev); + int trans_type; + cmd->autoneg = AUTONEG_DISABLE; cmd->supported = SUPPORTED_10000baseT_Full; - cmd->advertising = ADVERTISED_1000baseT_Full; + cmd->advertising = ADVERTISED_10000baseT_Full; + + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + + trans_type = priv->port_state.transciver; if (netif_carrier_ok(dev)) { - cmd->speed = SPEED_10000; + cmd->speed = priv->port_state.link_speed; cmd->duplex = DUPLEX_FULL; } else { cmd->speed = -1; cmd->duplex = -1; } + + if (trans_type > 0 && trans_type <= 0xC) { + cmd->port = PORT_FIBRE; + cmd->transceiver = XCVR_EXTERNAL; + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + } else if (trans_type == 0x80 || trans_type == 0) { + cmd->port = PORT_TP; + cmd->transceiver = XCVR_INTERNAL; + cmd->supported |= SUPPORTED_TP; + cmd->advertising |= ADVERTISED_TP; + } else { + cmd->port = -1; + cmd->transceiver = -1; + } return 0; } diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index a87bf3c97055..515c6348f32b 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -141,6 +141,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) struct mlx4_cmd_mailbox *mailbox; u32 *outbox; u8 field; + u32 field32; u16 size; u16 stat_rate; int err; @@ -368,6 +369,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a #define QUERY_PORT_MAX_VL_OFFSET 0x0b #define QUERY_PORT_MAC_OFFSET 0x10 +#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18 +#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c +#define QUERY_PORT_TRANS_CODE_OFFSET 0x20 for (i = 1; i <= dev_cap->num_ports; ++i) { err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT, @@ -391,6 +395,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->log_max_vlans[i] = field >> 4; MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET); MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET); + MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET); + dev_cap->trans_type[i] = field32 >> 24; + dev_cap->vendor_oui[i] = field32 & 0xffffff; + MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET); + MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET); } } diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 2cc1ba5452e3..443e456c9dab 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h @@ -73,6 +73,10 @@ struct mlx4_dev_cap { int max_pkeys[MLX4_MAX_PORTS + 1]; u64 def_mac[MLX4_MAX_PORTS + 1]; u16 eth_mtu[MLX4_MAX_PORTS + 1]; + int trans_type[MLX4_MAX_PORTS + 1]; + int vendor_oui[MLX4_MAX_PORTS + 1]; + u16 wavelength[MLX4_MAX_PORTS + 1]; + u64 trans_code[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; int loopback_support; u32 flags; diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 7390cdb19414..f4791fa2472f 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -184,6 +184,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i]; dev->caps.def_mac[i] = dev_cap->def_mac[i]; dev->caps.supported_type[i] = dev_cap->supported_port_types[i]; + dev->caps.trans_type[i] = dev_cap->trans_type[i]; + dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i]; + dev->caps.wavelength[i] = dev_cap->wavelength[i]; + dev->caps.trans_code[i] = dev_cap->trans_code[i]; } dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 2cec58722738..2a36a344fb3d 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -186,6 +186,10 @@ struct mlx4_caps { int eth_mtu_cap[MLX4_MAX_PORTS + 1]; int gid_table_len[MLX4_MAX_PORTS + 1]; int pkey_table_len[MLX4_MAX_PORTS + 1]; + int trans_type[MLX4_MAX_PORTS + 1]; + int vendor_oui[MLX4_MAX_PORTS + 1]; + int wavelength[MLX4_MAX_PORTS + 1]; + u64 trans_code[MLX4_MAX_PORTS + 1]; int local_ca_ack_delay; int num_uars; int bf_reg_size; -- cgit v1.2.3 From bc081cecf3cb3da236061cf353d74c42ba7e37fb Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:34 +0000 Subject: mlx4_en: get/set ringsize uses actual ring size In case that the rings were not fully filled, the report in Ethtool should be according to the actual size that was filled. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index fa2f2f43ab48..c5551f2cf260 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -394,8 +394,9 @@ static int mlx4_en_set_ringparam(struct net_device *dev, tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE); tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE); - if (rx_size == priv->prof->rx_ring_size && - tx_size == priv->prof->tx_ring_size) + if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size : + priv->rx_ring[0].size) && + tx_size == priv->tx_ring[0].size) return 0; mutex_lock(&mdev->state_lock); @@ -429,13 +430,13 @@ static void mlx4_en_get_ringparam(struct net_device *dev, struct ethtool_ringparam *param) { struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; memset(param, 0, sizeof(*param)); param->rx_max_pending = MLX4_EN_MAX_RX_SIZE; param->tx_max_pending = MLX4_EN_MAX_TX_SIZE; - param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size; - param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size; + param->rx_pending = priv->port_up ? + priv->rx_ring[0].actual_size : priv->rx_ring[0].size; + param->tx_pending = priv->tx_ring[0].size; } static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data) -- cgit v1.2.3 From d7e1a487d31933deba742c1bd3ffe0f73220b729 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:38 +0000 Subject: mlx4_en: reconfiguring mac address. When Mac address is removed from one port of the CX2 device, the other device should reconfigure its Mac. This fixes an issue with failover, when both ports have the same Mac address, and one of the ports, is closed, the second one stops receiving traffic. (bugzilla #1965 at bugs.openfabrics.org) Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 6 ++++++ drivers/net/mlx4/mlx4_en.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 968e75b7acf4..242366ca0793 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -513,6 +513,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work) queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); } + if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { + queue_work(mdev->workqueue, &priv->mac_task); + mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0; + } mutex_unlock(&mdev->state_lock); } @@ -653,6 +657,7 @@ int mlx4_en_start_port(struct net_device *dev) en_err(priv, "Failed setting port mac\n"); goto tx_err; } + mdev->mac_removed[priv->port] = 0; /* Init port */ en_dbg(HW, priv, "Initializing port\n"); @@ -709,6 +714,7 @@ void mlx4_en_stop_port(struct net_device *dev) /* Unregister Mac address for the port */ mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); + mdev->mac_removed[priv->port] = 1; /* Free TX Rings */ for (i = 0; i < priv->tx_ring_num; i++) { diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index a09598b2b12e..5d8f097d7e06 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -341,6 +341,7 @@ struct mlx4_en_dev { struct mlx4_mr mr; u32 priv_pdn; spinlock_t uar_lock; + u8 mac_removed[MLX4_MAX_PORTS + 1]; }; -- cgit v1.2.3 From 0533943c5c45cce2e26432bf0a6b8e114757c897 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:42 +0000 Subject: mlx4_en: UDP RSS support Adding capability for RSS for UDP traffic, hashing is done based on IP addresses and UDP port number. The support depends on HW/FW capabilities. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_main.c | 19 ++++++++++++------- drivers/net/mlx4/en_rx.c | 8 ++++---- drivers/net/mlx4/fw.c | 3 +++ drivers/net/mlx4/fw.h | 1 + drivers/net/mlx4/main.c | 1 + drivers/net/mlx4/mlx4_en.h | 3 +++ include/linux/mlx4/device.h | 1 + 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index cacac4e966ee..143906417048 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -63,11 +63,12 @@ static const char mlx4_en_version[] = */ -/* Use a XOR rathern than Toeplitz hash function for RSS */ -MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); - -/* RSS hash type mask - default to */ -MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); +/* Enable RSS TCP traffic */ +MLX4_EN_PARM_INT(tcp_rss, 1, + "Enable RSS for incomming TCP traffic or disabled (0)"); +/* Enable RSS UDP traffic */ +MLX4_EN_PARM_INT(udp_rss, 1, + "Enable RSS for incomming UDP traffic or disabled (0)"); /* Priority pausing */ MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." @@ -103,8 +104,12 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) struct mlx4_en_profile *params = &mdev->profile; int i; - params->rss_xor = (rss_xor != 0); - params->rss_mask = rss_mask & 0x1f; + params->tcp_rss = tcp_rss; + params->udp_rss = udp_rss; + if (params->udp_rss && !mdev->dev->caps.udp_rss) { + mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); + params->udp_rss = 0; + } for (i = 1; i <= MLX4_MAX_PORTS; i++) { params->prof[i].rx_pause = 1; params->prof[i].rx_ppp = pfcrx; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index f421a3d42723..e2126c76d1dc 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -859,8 +859,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) struct mlx4_qp_context context; struct mlx4_en_rss_context *rss_context; void *ptr; - int rss_xor = mdev->profile.rss_xor; - u8 rss_mask = mdev->profile.rss_mask; + u8 rss_mask = 0x3f; int i, qpn; int err = 0; int good_qps = 0; @@ -906,9 +905,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | (rss_map->base_qpn)); rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); - rss_context->hash_fn = rss_xor & 0x3; - rss_context->flags = rss_mask << 2; + rss_context->flags = rss_mask; + if (priv->mdev->profile.udp_rss) + rss_context->base_qpn_udp = rss_context->default_qpn; err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); if (err) diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 515c6348f32b..b716e1a1b298 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -179,6 +179,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f +#define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42 #define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43 #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 @@ -270,6 +271,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->max_msg_sz = 1 << (field & 0x1f); MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); dev_cap->stat_rate_support = stat_rate; + MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET); + dev_cap->udp_rss = field & 0x1; MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET); dev_cap->loopback_support = field & 0x1; MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 443e456c9dab..65cc72eb899d 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h @@ -78,6 +78,7 @@ struct mlx4_dev_cap { u16 wavelength[MLX4_MAX_PORTS + 1]; u64 trans_code[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; + int udp_rss; int loopback_support; u32 flags; int reserved_uars; diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index f4791fa2472f..569fa3df381f 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -225,6 +225,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.bmme_flags = dev_cap->bmme_flags; dev->caps.reserved_lkey = dev_cap->reserved_lkey; dev->caps.stat_rate_support = dev_cap->stat_rate_support; + dev->caps.udp_rss = dev_cap->udp_rss; dev->caps.loopback_support = dev_cap->loopback_support; dev->caps.max_gso_sz = dev_cap->max_gso_sz; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 5d8f097d7e06..4036a053ee32 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -318,6 +318,8 @@ struct mlx4_en_port_profile { struct mlx4_en_profile { int rss_xor; + int tcp_rss; + int udp_rss; u8 rss_mask; u32 active_ports; u32 small_pkt_int; @@ -360,6 +362,7 @@ struct mlx4_en_rss_context { u8 hash_fn; u8 flags; __be32 rss_key[10]; + __be32 base_qpn_udp; }; struct mlx4_en_port_state { diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 2a36a344fb3d..7338654c02b4 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -233,6 +233,7 @@ struct mlx4_caps { u32 bmme_flags; u32 reserved_lkey; u16 stat_rate_support; + int udp_rss; int loopback_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; int max_gso_sz; -- cgit v1.2.3 From fa37a9586f92051de03a13e55e5ec3880bb6783e Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:46 +0000 Subject: mlx4_en: Moving to work with GRO Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 56 ++---------------------------------- drivers/net/mlx4/en_netdev.c | 2 +- drivers/net/mlx4/en_rx.c | 66 +++++++++---------------------------------- drivers/net/mlx4/en_tx.c | 1 + drivers/net/mlx4/mlx4_en.h | 5 ---- 5 files changed, 17 insertions(+), 113 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index c5551f2cf260..01634a3efe85 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -39,21 +39,6 @@ #include "en_port.h" -static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv) -{ - int i; - - priv->port_stats.lro_aggregated = 0; - priv->port_stats.lro_flushed = 0; - priv->port_stats.lro_no_desc = 0; - - for (i = 0; i < priv->rx_ring_num; i++) { - priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated; - priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed; - priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc; - } -} - static void mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { @@ -112,7 +97,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = { "tx_heartbeat_errors", "tx_window_errors", /* port statistics */ - "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets", + "tso_packets", "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed", "rx_csum_good", "rx_csum_none", "tx_chksum_offload", @@ -122,7 +107,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = { "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5", "tx_prio_6", "tx_prio_7", }; -#define NUM_MAIN_STATS 21 +#define NUM_MAIN_STATS 18 #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { @@ -174,8 +159,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, spin_lock_bh(&priv->stats_lock); - mlx4_en_update_lro_stats(priv); - for (i = 0; i < NUM_MAIN_STATS; i++) data[index++] = ((unsigned long *) &priv->stats)[i]; for (i = 0; i < NUM_PORT_STATS; i++) @@ -439,40 +422,6 @@ static void mlx4_en_get_ringparam(struct net_device *dev, param->tx_pending = priv->tx_ring[0].size; } -static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int rc = 0; - int changed = 0; - - if (data & ~ETH_FLAG_LRO) - return -EOPNOTSUPP; - - if (data & ETH_FLAG_LRO) { - if (!(dev->features & NETIF_F_LRO)) - changed = 1; - } else if (dev->features & NETIF_F_LRO) { - changed = 1; - } - - if (changed) { - if (netif_running(dev)) { - mutex_lock(&mdev->state_lock); - mlx4_en_stop_port(dev); - } - dev->features ^= NETIF_F_LRO; - if (netif_running(dev)) { - rc = mlx4_en_start_port(dev); - if (rc) - en_err(priv, "Failed to restart port\n"); - mutex_unlock(&mdev->state_lock); - } - } - - return rc; -} - const struct ethtool_ops mlx4_en_ethtool_ops = { .get_drvinfo = mlx4_en_get_drvinfo, .get_settings = mlx4_en_get_settings, @@ -502,7 +451,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_ringparam = mlx4_en_get_ringparam, .set_ringparam = mlx4_en_set_ringparam, .get_flags = ethtool_op_get_flags, - .set_flags = mlx4_ethtool_op_set_flags, }; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 242366ca0793..411bda581c04 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -1047,7 +1047,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_GRO; if (mdev->LSO_support) { dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index e2126c76d1dc..cb7ff00ce6de 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -42,18 +42,6 @@ #include "mlx4_en.h" -static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr, - void **ip_hdr, void **tcpudp_hdr, - u64 *hdr_flags, void *priv) -{ - *mac_hdr = page_address(frags->page) + frags->page_offset; - *ip_hdr = *mac_hdr + ETH_HLEN; - *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr)); - *hdr_flags = LRO_IPV4 | LRO_TCP; - - return 0; -} - static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv, struct mlx4_en_rx_desc *rx_desc, struct skb_frag_struct *skb_frags, @@ -312,24 +300,6 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, } ring->buf = ring->wqres.buf.direct.buf; - /* Configure lro mngr */ - memset(&ring->lro, 0, sizeof(struct net_lro_mgr)); - ring->lro.dev = priv->dev; - ring->lro.features = LRO_F_NAPI; - ring->lro.frag_align_pad = NET_IP_ALIGN; - ring->lro.ip_summed = CHECKSUM_UNNECESSARY; - ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY; - ring->lro.max_desc = MLX4_EN_MAX_LRO_DESCRIPTORS; - ring->lro.max_aggr = MAX_SKB_FRAGS; - ring->lro.lro_arr = kcalloc(MLX4_EN_MAX_LRO_DESCRIPTORS, - sizeof(struct net_lro_desc), - GFP_KERNEL); - if (!ring->lro.lro_arr) { - en_err(priv, "Failed to allocate lro array\n"); - goto err_map; - } - ring->lro.get_frag_header = mlx4_en_get_frag_header; - return 0; err_map: @@ -412,7 +382,6 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv, { struct mlx4_en_dev *mdev = priv->mdev; - kfree(ring->lro.lro_arr); mlx4_en_unmap_buffer(&ring->wqres.buf); mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE); vfree(ring->rx_info); @@ -563,7 +532,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud struct mlx4_cqe *cqe; struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring]; struct skb_frag_struct *skb_frags; - struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS]; struct mlx4_en_rx_desc *rx_desc; struct sk_buff *skb; int index; @@ -623,37 +591,33 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud * - TCP/IP (v4) * - without IP options * - not an IP fragment */ - if (mlx4_en_can_lro(cqe->status) && - dev->features & NETIF_F_LRO) { + if (dev->features & NETIF_F_GRO) { + struct sk_buff *gro_skb = napi_get_frags(&cq->napi); nr = mlx4_en_complete_rx_desc( priv, rx_desc, - skb_frags, lro_frags, + skb_frags, skb_shinfo(gro_skb)->frags, ring->page_alloc, length); if (!nr) goto next; + skb_shinfo(gro_skb)->nr_frags = nr; + gro_skb->len = length; + gro_skb->data_len = length; + gro_skb->truesize += length; + gro_skb->ip_summed = CHECKSUM_UNNECESSARY; + if (priv->vlgrp && (cqe->vlan_my_qpn & - cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) { - lro_vlan_hwaccel_receive_frags( - &ring->lro, lro_frags, - length, length, - priv->vlgrp, - be16_to_cpu(cqe->sl_vid), - NULL, 0); - } else - lro_receive_frags(&ring->lro, - lro_frags, - length, - length, - NULL, 0); + cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) + vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid)); + else + napi_gro_frags(&cq->napi); goto next; } /* LRO not possible, complete processing here */ ip_summed = CHECKSUM_UNNECESSARY; - INC_PERF_COUNTER(priv->pstats.lro_misses); } else { ip_summed = CHECKSUM_NONE; priv->port_stats.rx_chksum_none++; @@ -694,14 +658,10 @@ next: if (++polled == budget) { /* We are here because we reached the NAPI budget - * flush only pending LRO sessions */ - lro_flush_all(&ring->lro); goto out; } } - /* If CQ is empty flush all LRO sessions unconditionally */ - lro_flush_all(&ring->lro); - out: AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled); mlx4_cq_set_ci(&cq->mcq); diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index b875f9c38848..98dd620042a8 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "mlx4_en.h" diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 4036a053ee32..7d4ddb9a2bec 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -254,7 +253,6 @@ struct mlx4_en_rx_desc { struct mlx4_en_rx_ring { struct mlx4_hwq_resources wqres; struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS]; - struct net_lro_mgr lro; u32 size ; /* number of Rx descs*/ u32 actual_size; u32 size_mask; @@ -379,9 +377,6 @@ struct mlx4_en_pkt_stats { }; struct mlx4_en_port_stats { - unsigned long lro_aggregated; - unsigned long lro_flushed; - unsigned long lro_no_desc; unsigned long tso_packets; unsigned long queue_stopped; unsigned long wake_queue; -- cgit v1.2.3 From 04714a16db6fd8d175050a01459fd16660fba18c Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Tue, 24 Aug 2010 03:46:49 +0000 Subject: mlx4_en: updated driver version Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/mlx4_en.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 7d4ddb9a2bec..ce8e2338ee31 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -49,8 +49,8 @@ #include "en_port.h" #define DRV_NAME "mlx4_en" -#define DRV_VERSION "1.4.1.1" -#define DRV_RELDATE "June 2009" +#define DRV_VERSION "1.5.1.6" +#define DRV_RELDATE "August 2010" #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) -- cgit v1.2.3 From 4562487a00445eab96311365ba15c41dc4d043cd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 24 Aug 2010 15:06:27 -0700 Subject: mlx4_en: Fix build warning in mlx4_en_create_rx_ring. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/mlx4/en_rx.c: In function ‘mlx4_en_create_rx_ring’: drivers/net/mlx4/en_rx.c:305: warning: label ‘err_map’ defined but not used Signed-off-by: David S. Miller --- drivers/net/mlx4/en_rx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index cb7ff00ce6de..c4aad7f2beb9 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -302,8 +302,6 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, return 0; -err_map: - mlx4_en_unmap_buffer(&ring->wqres.buf); err_hwq: mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); err_ring: -- cgit v1.2.3 From b62177a0aa0521fd07cd7501534c0c3b256ebce6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 20 Aug 2010 15:23:47 +0200 Subject: iwlwifi: fix canceling monitor_recover timer To make del_timer_sync() works we have to assure that timer function does not rearm the timer. To achieve that we cancel timer with STATUS_EXIT_PENDING bit set in __iwl{3945,}_down function. Patch also fix priv->txq memory usage after free for iwl3945, because it move timer cancellation before iwl3945_hw_txq_ctx_free(priv) is called. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 7 +++++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3ced9ea9c5fe..26bc0482dd9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2764,6 +2764,11 @@ static void __iwl_down(struct iwl_priv *priv) if (!exit_pending) set_bit(STATUS_EXIT_PENDING, &priv->status); + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + if (priv->cfg->ops->lib->recover_from_tx_stall) + del_timer_sync(&priv->monitor_recover); + iwl_clear_ucode_stations(priv); iwl_dealloc_bcast_station(priv); iwl_clear_driver_stations(priv); @@ -3870,8 +3875,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->beacon_update); del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); } static void iwl_init_hw_rates(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 94d7e6e1323d..53e6cbb3aaaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2571,6 +2571,11 @@ static void __iwl3945_down(struct iwl_priv *priv) if (!exit_pending) set_bit(STATUS_EXIT_PENDING, &priv->status); + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + if (priv->cfg->ops->lib->recover_from_tx_stall) + del_timer_sync(&priv->monitor_recover); + /* Station information will now be cleared in device */ iwl_clear_ucode_stations(priv); iwl_dealloc_bcast_station(priv); @@ -3811,8 +3816,6 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) cancel_delayed_work(&priv->alive_start); cancel_work_sync(&priv->start_internal_scan); cancel_work_sync(&priv->beacon_update); - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); } static struct attribute *iwl3945_sysfs_entries[] = { -- cgit v1.2.3 From 0fb9a9ec27718fbf7fa3153bc94becefb716ceeb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 20 Aug 2010 16:25:38 -0700 Subject: net/mac80211: Use wiphy_ Standardize logging messages from printk(KERN_ "%s: " fmt , wiphy_name(foo), args); to wiphy_(foo, fmt, args); Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 6 +++--- net/mac80211/debugfs.c | 6 ++++-- net/mac80211/ibss.c | 4 ++-- net/mac80211/iface.c | 6 ++---- net/mac80211/key.c | 14 ++++++-------- net/mac80211/main.c | 15 +++++++-------- net/mac80211/mlme.c | 17 +++++++++-------- net/mac80211/rate.c | 9 ++++----- net/mac80211/rx.c | 13 +++++-------- net/mac80211/sta_info.c | 21 +++++++++------------ net/mac80211/status.c | 9 ++++----- net/mac80211/tx.c | 8 ++++---- 12 files changed, 59 insertions(+), 69 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 94787d21282c..7693ebc77596 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1123,9 +1123,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, p.uapsd = false; if (drv_conf_tx(local, params->queue, &p)) { - printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), params->queue); + wiphy_debug(local->hw.wiphy, + "failed to set TX queue parameters for queue %d\n", + params->queue); return -EINVAL; } diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index a694c593ff6a..e81ef4e8cb32 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -85,13 +85,15 @@ static ssize_t tsf_write(struct file *file, if (strncmp(buf, "reset", 5) == 0) { if (local->ops->reset_tsf) { drv_reset_tsf(local); - printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy)); + wiphy_info(local->hw.wiphy, "debugfs reset TSF\n"); } } else { tsf = simple_strtoul(buf, NULL, 0); if (local->ops->set_tsf) { drv_set_tsf(local, tsf); - printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf); + wiphy_info(local->hw.wiphy, + "debugfs set TSF to %#018llx\n", tsf); + } } diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 32af97108425..1a3aae54f0cf 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -427,8 +427,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, return NULL; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", - wiphy_name(local->hw.wiphy), addr, sdata->name); + wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n", + addr, sdata->name); #endif sta = sta_info_alloc(sdata, addr, gfp); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 86f434f234ae..9369710cc65b 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1175,8 +1175,7 @@ static u32 ieee80211_idle_off(struct ieee80211_local *local, return 0; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: device no longer idle - %s\n", - wiphy_name(local->hw.wiphy), reason); + wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); #endif local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; @@ -1189,8 +1188,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) return 0; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: device now idle\n", - wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, "device now idle\n"); #endif drv_flush(local, false); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 9c27c53cfae5..2ce2dbbf6309 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -87,10 +87,9 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) - printk(KERN_ERR "mac80211-%s: failed to set key " - "(%d, %pM) to hardware (%d)\n", - wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + wiphy_err(key->local->hw.wiphy, + "failed to set key (%d, %pM) to hardware (%d)\n", + key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); } static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) @@ -121,10 +120,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) sta, &key->conf); if (ret) - printk(KERN_ERR "mac80211-%s: failed to remove key " - "(%d, %pM) from hardware (%d)\n", - wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + wiphy_err(key->local->hw.wiphy, + "failed to remove key (%d, %pM) from hardware (%d)\n", + key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a53feac4618c..5756fba63d48 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -713,16 +713,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) result = ieee80211_wep_init(local); if (result < 0) - printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", - wiphy_name(local->hw.wiphy), result); + wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", + result); rtnl_lock(); result = ieee80211_init_rate_ctrl_alg(local, hw->rate_control_algorithm); if (result < 0) { - printk(KERN_DEBUG "%s: Failed to initialize rate control " - "algorithm\n", wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, + "Failed to initialize rate control algorithm\n"); goto fail_rate; } @@ -731,8 +731,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) result = ieee80211_if_add(local, "wlan%d", NULL, NL80211_IFTYPE_STATION, NULL); if (result) - printk(KERN_WARNING "%s: Failed to add default virtual iface\n", - wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, + "Failed to add default virtual iface\n"); } rtnl_unlock(); @@ -815,8 +815,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) if (skb_queue_len(&local->skb_queue) || skb_queue_len(&local->skb_queue_unreliable)) - printk(KERN_WARNING "%s: skb_queue not empty\n", - wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); skb_queue_purge(&local->skb_queue); skb_queue_purge(&local->skb_queue_unreliable); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 38996a44aa8e..5282ac18d2cf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -778,16 +778,17 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, params.uapsd = uapsd; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " - "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", - wiphy_name(local->hw.wiphy), queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, params.txop, - params.uapsd); + wiphy_debug(local->hw.wiphy, + "WMM queue=%d aci=%d acm=%d aifs=%d " + "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + queue, aci, acm, + params.aifs, params.cw_min, params.cw_max, + params.txop, params.uapsd); #endif if (drv_conf_tx(local, queue, ¶ms)) - printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), queue); + wiphy_debug(local->hw.wiphy, + "failed to set TX queue parameters for queue %d\n", + queue); } /* enable WMM or activate new settings */ diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 6d0bd198af19..f77a45625c0b 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -366,8 +366,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, ref = rate_control_alloc(name, local); if (!ref) { - printk(KERN_WARNING "%s: Failed to select rate control " - "algorithm\n", wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, + "Failed to select rate control algorithm\n"); return -ENOENT; } @@ -378,9 +378,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, sta_info_flush(local, NULL); } - printk(KERN_DEBUG "%s: Selected rate control " - "algorithm '%s'\n", wiphy_name(local->hw.wiphy), - ref->ops->name); + wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n", + ref->ops->name); return 0; } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index aa41e382bbb3..e1844f7085de 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -605,10 +605,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) - printk(KERN_DEBUG "%s: release an RX reorder " - "frame due to timeout on earlier " - "frames\n", - wiphy_name(hw->wiphy)); + wiphy_debug(hw->wiphy, + "release an RX reorder frame due to timeout on earlier frames\n"); #endif ieee80211_release_reorder_frame(hw, tid_agg_rx, j, frames); @@ -2698,10 +2696,9 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, skb_new = skb_copy(skb, GFP_ATOMIC); if (!skb_new) { if (net_ratelimit()) - printk(KERN_DEBUG "%s: failed to copy " - "multicast frame for %s\n", - wiphy_name(local->hw.wiphy), - prev->name); + wiphy_debug(local->hw.wiphy, + "failed to copy multicast frame for %s\n", + prev->name); goto next; } ieee80211_invoke_rx_handlers(prev, &rx, skb_new); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6d86f0c1ad04..687077e49dc6 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -174,8 +174,7 @@ static void __sta_info_free(struct ieee80211_local *local, } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Destroyed STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ kfree(sta); @@ -262,8 +261,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Allocated STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ #ifdef CONFIG_MAC80211_MESH @@ -300,8 +298,9 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) sta->uploaded = true; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (async) - printk(KERN_DEBUG "%s: Finished adding IBSS STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, + "Finished adding IBSS STA %pM\n", + sta->sta.addr); #endif } @@ -411,8 +410,8 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) spin_unlock_irqrestore(&local->sta_lock, flags); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Added IBSS STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n", + sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ ieee80211_queue_work(&local->hw, &local->sta_finish_work); @@ -459,8 +458,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Inserted STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ /* move reference to rcu-protected */ @@ -690,8 +688,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) #endif #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Removed STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ cancel_work_sync(&sta->drv_unblock_wk); diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 67a35841bef0..571b32bfc54c 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -114,11 +114,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (net_ratelimit()) - printk(KERN_DEBUG "%s: dropped TX filtered frame, " - "queue_len=%d PS=%d @%lu\n", - wiphy_name(local->hw.wiphy), - skb_queue_len(&sta->tx_filtered), - !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); + wiphy_debug(local->hw.wiphy, + "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", + skb_queue_len(&sta->tx_filtered), + !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); #endif dev_kfree_skb(skb); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index bc4fefc91663..d51ec74cfb62 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -351,8 +351,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) local->total_ps_buffered = total; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", - wiphy_name(local->hw.wiphy), purged); + wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", + purged); #endif } @@ -1513,8 +1513,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, I802_DEBUG_INC(local->tx_expand_skb_head); if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", - wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, + "failed to reallocate TX buffer\n"); return -ENOMEM; } -- cgit v1.2.3 From 9736ebfe39687f2edde9e97fc188f013a31048f6 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sat, 21 Aug 2010 12:08:15 +0100 Subject: orinoco: Fix walking past the end of the buffer Fix walking past the end of the bitrate_table array in the case when the loop counter == BITRATE_TABLE_SIZE. Reported by: Denis Kirjanov Signed-off-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/hw.c | 9 ++++++--- drivers/net/wireless/orinoco/wext.c | 11 +++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 077baa86756b..b4772c1c6135 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -762,14 +762,17 @@ int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate) case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */ case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */ for (i = 0; i < BITRATE_TABLE_SIZE; i++) - if (bitrate_table[i].intersil_txratectrl == val) + if (bitrate_table[i].intersil_txratectrl == val) { + *bitrate = bitrate_table[i].bitrate * 100000; break; + } - if (i >= BITRATE_TABLE_SIZE) + if (i >= BITRATE_TABLE_SIZE) { printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n", priv->ndev->name, val); + err = -EIO; + } - *bitrate = bitrate_table[i].bitrate * 100000; break; default: BUG(); diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index cf7be1eb6124..93505f93bf97 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -589,8 +589,15 @@ static int orinoco_ioctl_getrate(struct net_device *dev, /* If the interface is running we try to find more about the current mode */ - if (netif_running(dev)) - err = orinoco_hw_get_act_bitrate(priv, &bitrate); + if (netif_running(dev)) { + int act_bitrate; + int lerr; + + /* Ignore errors if we can't get the actual bitrate */ + lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate); + if (!lerr) + bitrate = act_bitrate; + } orinoco_unlock(priv, &flags); -- cgit v1.2.3 From 3a59babbee409fa5f1b2dd8a14c40803b5eb288b Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sat, 21 Aug 2010 12:13:45 +0100 Subject: orinoco: update status in MAINTAINERS Signed-off-by: David Kilroy Cc: Pavel Roskin Cc: David Gibson Signed-off-by: John W. Linville --- MAINTAINERS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 44620aebb369..a41e3a7b18f3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4265,13 +4265,12 @@ F: Documentation/filesystems/dlmfs.txt F: fs/ocfs2/ ORINOCO DRIVER -M: Pavel Roskin -M: David Gibson L: linux-wireless@vger.kernel.org L: orinoco-users@lists.sourceforge.net L: orinoco-devel@lists.sourceforge.net +W: http://linuxwireless.org/en/users/Drivers/orinoco W: http://www.nongnu.org/orinoco/ -S: Maintained +S: Orphan F: drivers/net/wireless/orinoco/ OSD LIBRARY and FILESYSTEM -- cgit v1.2.3 From ff67bb86d448c26cb9110e9681669dc4a8aa5e0a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 21 Aug 2010 07:23:29 -0700 Subject: mac80211: fix warning for un-used parameter mesh_hdr only used when CONFIG_MAC80211_MESH is defined Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d51ec74cfb62..a6ac9fd248f2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1701,7 +1701,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, u16 ethertype, hdrlen, meshhdrlen = 0; __le16 fc; struct ieee80211_hdr hdr; - struct ieee80211s_hdr mesh_hdr; + struct ieee80211s_hdr mesh_hdr __maybe_unused; const u8 *encaps_data; int encaps_len, skip_header_bytes; int nh_pos, h_pos; -- cgit v1.2.3 From 2738bd682df546f34654ed3d59dfc9ebe8d04979 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sat, 21 Aug 2010 16:39:01 -0400 Subject: mac80211: trivial spelling fixes Fix spelling and readability of a few lines of kernel doc: s/issueing/issuing/g s/approriate/appropriate/g s/supported by simply/supported simply by/ s/IEEE80211_HW_BEACON_FILTERING/IEEE80211_HW_BEACON_FILTER/g Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- include/net/mac80211.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2a1811366076..dcc8c2bf986e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1242,8 +1242,8 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * %IEEE80211_CONF_PS flag enabled means that the powersave mode defined in * IEEE 802.11-2007 section 11.2 is enabled. This is not to be confused * with hardware wakeup and sleep states. Driver is responsible for waking - * up the hardware before issueing commands to the hardware and putting it - * back to sleep at approriate times. + * up the hardware before issuing commands to the hardware and putting it + * back to sleep at appropriate times. * * When PS is enabled, hardware needs to wakeup for beacons and receive the * buffered multicast/broadcast frames after the beacon. Also it must be @@ -1264,7 +1264,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * there's data traffic and still saving significantly power in idle * periods. * - * Dynamic powersave is supported by simply mac80211 enabling and disabling + * Dynamic powersave is simply supported by mac80211 enabling and disabling * PS based on traffic. Driver needs to only set %IEEE80211_HW_SUPPORTS_PS * flag and mac80211 will handle everything automatically. Additionally, * hardware having support for the dynamic PS feature may set the @@ -2458,7 +2458,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING and + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the * hardware is not receiving beacons with this function. */ @@ -2469,7 +2469,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING, and + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver * needs to inform if the connection to the AP has been lost. * -- cgit v1.2.3 From 8801df86d79b1ffda94e3b937bc19bbe9a66557d Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sat, 21 Aug 2010 16:39:02 -0400 Subject: ath5k: trivial spelling fixes Fix some comments: s/transmition/transmission/ s/puting/putting/ Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/pcu.c | 4 ++-- drivers/net/wireless/ath/ath5k/phy.c | 2 +- drivers/net/wireless/ath/ath5k/reset.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 3fef5931ec3a..bb2e21553d1b 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -137,11 +137,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) * ath5k_hw_set_ack_bitrate - set bitrate for ACKs * * @ah: The &struct ath5k_hw - * @high: Flag to determine if we want to use high transmition rate + * @high: Flag to determine if we want to use high transmission rate * for ACKs or not * * If high flag is set, we tell hw to use a set of control rates based on - * the current transmition rate (check out control_rates array inside reset.c). + * the current transmission rate (check out control_rates array inside reset.c). * If not hw just uses the lowest rate available for the current modulation * scheme being used (1Mbit for CCK and 6Mbits for OFDM). */ diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index c7c446592374..8c27a3644d2f 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -2987,7 +2987,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, /* - * Set transmition power + * Set transmission power */ int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 4154959125b6..58912cd762d9 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -326,7 +326,7 @@ commit: * register). After this MAC and Baseband are * disabled and a full reset is needed to come * back. This way we save as much power as possible - * without puting the card on full sleep. + * without putting the card on full sleep. */ int ath5k_hw_on_hold(struct ath5k_hw *ah) { @@ -344,7 +344,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) /* * Put chipset on warm reset... * - * Note: puting PCI core on warm reset on PCI-E cards + * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. @@ -400,7 +400,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) /* * Put chipset on warm reset... * - * Note: puting PCI core on warm reset on PCI-E cards + * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. -- cgit v1.2.3 From b4c52612069c2756ad7506754765bfee57315efe Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sat, 21 Aug 2010 16:39:03 -0400 Subject: ath5k: log descriptor chains at a new debug level Descriptors are currently logged with ATH5K_DEBUG_RESET, which isn't really apt, and also means we can't see just the descriptor setup or just the resets. Add a new debug level just for that. Acked-by: Bruno Randolf Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 5 +++-- drivers/net/wireless/ath/ath5k/debug.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 4cccc29964f6..1b7c6d7fde93 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -312,6 +312,7 @@ static const struct { { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, + { ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, }; @@ -955,7 +956,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) struct ath5k_rx_status rs = {}; int status; - if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) + if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) return; printk(KERN_DEBUG "rxdp %x, rxlink %p\n", @@ -997,7 +998,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) struct ath5k_tx_status ts = {}; int done; - if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) + if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) return; done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 606ae94a9157..9b22722a95f0 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -95,6 +95,7 @@ struct ath5k_dbg_info { * @ATH5K_DEBUG_DUMP_TX: print transmit skb content * @ATH5K_DEBUG_DUMPBANDS: dump bands * @ATH5K_DEBUG_TRACE: trace function calls + * @ATH5K_DEBUG_DESC: descriptor setup * @ATH5K_DEBUG_ANY: show at any debug level * * The debug level is used to control the amount and type of debugging output @@ -117,6 +118,7 @@ enum ath5k_debug_level { ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_ANI = 0x00002000, + ATH5K_DEBUG_DESC = 0x00004000, ATH5K_DEBUG_ANY = 0xffffffff }; -- cgit v1.2.3 From d7065c305544d575c3697b46ddbc8601de03e46f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 22 Aug 2010 00:00:14 +0200 Subject: p54spi: Kconfig option for config blob This patch adds an Kconfig option, which allows the user to select, whenever he/she wants to include a 4k blob for generic calibration and interface values into the driver, or cut the module size by about 15 to 20%. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/Kconfig | 17 +++++++++++++++++ drivers/net/wireless/p54/p54spi.c | 7 ++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index 60a930e45a8b..e5f45cb2a7a2 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig @@ -49,6 +49,23 @@ config P54_SPI If you choose to build a module, it'll be called p54spi. +config P54_SPI_DEFAULT_EEPROM + bool "Include fallback EEPROM blob" + depends on P54_SPI + default n + ---help--- + Unlike the PCI or USB devices, the SPI variants don't have + a dedicated EEPROM chip to store all device specific values + for calibration, country and interface settings. + + The driver will try to load the image "3826.eeprom", if the + file is put at the right place. (usually /lib/firmware.) + + Only if this request fails, this option will provide a + backup set of generic values to get the device working. + + Enabling this option adds about 4k to p54spi. + config P54_LEDS bool depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 087bf0698a5a..156e57dbd2cf 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -32,11 +32,14 @@ #include #include "p54spi.h" -#include "p54spi_eeprom.h" #include "p54.h" #include "lmac.h" +#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM +#include "p54spi_eeprom.h" +#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */ + MODULE_FIRMWARE("3826.arm"); MODULE_ALIAS("stlc45xx"); @@ -195,9 +198,11 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev) ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); if (ret < 0) { +#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM dev_info(&priv->spi->dev, "loading default eeprom...\n"); ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom, sizeof(p54spi_eeprom)); +#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */ } else { dev_info(&priv->spi->dev, "loading user eeprom...\n"); ret = p54_parse_eeprom(dev, (void *) eeprom->data, -- cgit v1.2.3 From 31c726f0963cd022680dacd0c9f0036d7e12a8b2 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 22 Aug 2010 22:46:15 +0300 Subject: wl1251: update my email address I use now my adurom.com address. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- drivers/net/wireless/wl12xx/wl1251_main.c | 2 +- drivers/net/wireless/wl12xx/wl1251_sdio.c | 2 +- drivers/net/wireless/wl12xx/wl1251_spi.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a41e3a7b18f3..2fde65d66f51 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6302,7 +6302,7 @@ S: Maintained F: drivers/input/misc/wistron_btns.c WL1251 WIRELESS DRIVER -M: Kalle Valo +M: Kalle Valo L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index c81e95b45c14..c7cffbafdf66 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -1437,5 +1437,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw); MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); MODULE_FIRMWARE(WL1251_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index b901b6135654..c0b68b0a9aa8 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -339,4 +339,4 @@ module_init(wl1251_sdio_init); module_exit(wl1251_sdio_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 27fdfaaeb074..a6435fb66339 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -344,5 +344,5 @@ module_init(wl1251_spi_init); module_exit(wl1251_spi_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); MODULE_ALIAS("spi:wl1251"); -- cgit v1.2.3 From 4c5f7d7a1e6cf20ad515dad8a63c0813fac5bcea Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 22 Aug 2010 22:46:28 +0300 Subject: wl12xx: change contact person for the include file Luciano should be the contact person for the include/linux/spi/wl12xx.h file. Signed-off-by: Kalle Valo Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- include/linux/spi/wl12xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h index a223ecbc71ef..a20bccf0b5c2 100644 --- a/include/linux/spi/wl12xx.h +++ b/include/linux/spi/wl12xx.h @@ -3,7 +3,7 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo + * Contact: Luciano Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License -- cgit v1.2.3 From fe71559239b2227649198f032daa5a877204771b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 22 Aug 2010 13:02:03 -0700 Subject: MAINTAINERS: add info for include/linux/spi/wl12xx.h Signed-off-by: Joe Perches Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2fde65d66f51..4a6d93648b9c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6317,6 +6317,7 @@ W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/wl12xx/wl1271* +F: include/linux/spi/wl12xx.h WL3501 WIRELESS PCMCIA CARD DRIVER M: Arnaldo Carvalho de Melo -- cgit v1.2.3 From ba0492cf904629f7900fc213ee729f23a0084ad6 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 22 Aug 2010 22:46:43 +0300 Subject: wl1251: remove copyright contact person As my nokia address doesn't work anymore, it's better just to remove the copyright contact altogether. We have MODULE_AUTHOR() scripts for these anyway. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251.h | 2 -- drivers/net/wireless/wl12xx/wl1251_acx.h | 2 -- drivers/net/wireless/wl12xx/wl1251_boot.c | 2 -- drivers/net/wireless/wl12xx/wl1251_boot.h | 2 -- drivers/net/wireless/wl12xx/wl1251_cmd.h | 2 -- drivers/net/wireless/wl12xx/wl1251_debugfs.c | 2 -- drivers/net/wireless/wl12xx/wl1251_debugfs.h | 2 -- drivers/net/wireless/wl12xx/wl1251_event.c | 2 -- drivers/net/wireless/wl12xx/wl1251_event.h | 2 -- drivers/net/wireless/wl12xx/wl1251_init.c | 2 -- drivers/net/wireless/wl12xx/wl1251_init.h | 2 -- drivers/net/wireless/wl12xx/wl1251_io.c | 2 -- drivers/net/wireless/wl12xx/wl1251_main.c | 2 -- drivers/net/wireless/wl12xx/wl1251_ps.c | 2 -- drivers/net/wireless/wl12xx/wl1251_ps.h | 2 -- drivers/net/wireless/wl12xx/wl1251_reg.h | 2 -- drivers/net/wireless/wl12xx/wl1251_rx.c | 2 -- drivers/net/wireless/wl12xx/wl1251_rx.h | 2 -- drivers/net/wireless/wl12xx/wl1251_spi.c | 2 -- drivers/net/wireless/wl12xx/wl1251_spi.h | 2 -- drivers/net/wireless/wl12xx/wl1251_tx.c | 2 -- drivers/net/wireless/wl12xx/wl1251_tx.h | 2 -- 22 files changed, 44 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 6b942a28e6a5..9bc4fea3315a 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008-2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index a8845b8f2451..c7cc5c1e8a75 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 5e65f47fda8a..468b47b0328a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h index 90063697e8f2..7661bc5e4662 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.h +++ b/drivers/net/wireless/wl12xx/wl1251_boot.h @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h index 60d7e522486c..e5c74c631374 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index 5e4465ac08fa..6ffe4cd58561 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h index 6dc3d080853c..b3417c02a218 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.h @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c index e093a1c5a205..00c3e648d93f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl12xx/wl1251_event.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h index ec456474a842..30eb5d150bf7 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.h +++ b/drivers/net/wireless/wl12xx/wl1251_event.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c index b538bdd7b320..c5daec05d9ee 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ b/drivers/net/wireless/wl12xx/wl1251_init.c @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h index 269cefb3e7d4..543f17582ead 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.h +++ b/drivers/net/wireless/wl12xx/wl1251_init.h @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c index f1c232e0887f..ad6ca68b303f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_io.c +++ b/drivers/net/wireless/wl12xx/wl1251_io.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index c7cffbafdf66..edd4845c3707 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008-2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index b55cb2bd459a..0b997bdfec09 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h index c688ac57aee4..98ed6c237561 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ b/drivers/net/wireless/wl12xx/wl1251_ps.h @@ -7,8 +7,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h index d16edd9bf06c..a5809019c5c1 100644 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ b/drivers/net/wireless/wl12xx/wl1251_reg.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index 1b6294b3b996..25764592a596 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h index da4e53406a0e..4448f635a4d8 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.h +++ b/drivers/net/wireless/wl12xx/wl1251_rx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index a6435fb66339..334ded9881c0 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h index 2e273a97e7f3..7dcf3cf7ae40 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.h +++ b/drivers/net/wireless/wl12xx/wl1251_spi.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c index 6634b3e27cfc..6d618fb1fd95 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/drivers/net/wireless/wl12xx/wl1251_tx.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h index f40eeb37f5aa..96011e78cd5a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.h +++ b/drivers/net/wireless/wl12xx/wl1251_tx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. -- cgit v1.2.3 From 5effdf18aa10c3683094140cf893c399d581d39f Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 22 Aug 2010 22:47:02 +0300 Subject: wl1251: move include guard after the license Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_ps.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h index 98ed6c237561..e5db81fc1dfc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ b/drivers/net/wireless/wl12xx/wl1251_ps.h @@ -1,6 +1,3 @@ -#ifndef __WL1251_PS_H__ -#define __WL1251_PS_H__ - /* * This file is part of wl1251 * @@ -23,6 +20,9 @@ * */ +#ifndef __WL1251_PS_H__ +#define __WL1251_PS_H__ + #include "wl1251.h" #include "wl1251_acx.h" -- cgit v1.2.3 From 049fbfeeb5c7edb260848a89af4895e3dabfa77e Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Sun, 22 Aug 2010 21:47:32 +0200 Subject: b43: N-PHY: add missing phyrxchain setting and fix warning in RX core function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index a0a6554a76d1..5f0ce35bbe27 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3092,6 +3092,8 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) struct b43_phy_n *nphy = phy->n; u16 buf[16]; + nphy->phyrxchain = mask; + if (0 /* FIXME clk */) return; @@ -3103,7 +3105,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT); - if (mask & 0x3 != 0x3) { + if ((mask & 0x3) != 0x3) { b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1); if (dev->phy.rev >= 3) { /* TODO */ -- cgit v1.2.3 From 11791a6f7534906b4a01ffb54ba0b02ca39398ef Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 22 Aug 2010 22:41:33 +0200 Subject: p54usb: fix off-by-one on !CONFIG_PM The ISL3887 chip needs a USB reset, whenever the usb-frontend module "p54usb" is reloaded. This patch fixes an off-by-one bug, if the user is running a kernel without the CONFIG_PM option set and for some reason (e.g.: compat-wireless) wants to switch between different p54usb modules. Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index ad595958b7df..063248b35069 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -930,8 +930,8 @@ static int __devinit p54u_probe(struct usb_interface *intf, #ifdef CONFIG_PM /* ISL3887 needs a full reset on resume */ udev->reset_resume = 1; +#endif /* CONFIG_PM */ err = p54u_device_reset(dev); -#endif priv->hw_type = P54U_3887; dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); -- cgit v1.2.3 From 258086a48b766d12a500f98834654ffa927ca475 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 22 Aug 2010 23:48:25 +0200 Subject: mac80211: cancel restart_work in ieee80211_unregister_hw Unlike most other workqueue-tasks, the restart_work is not scheduled onto mac80211's private per-interface workqueue, but onto one of the system-wide workqueues. Therefore the mac80211-stack has to cancel any pending restarts, before destroying the shared device context and handing back the memory. Otherwise - under very unlucky circumstances - there could be a stale work- item left, because some other kernel component might have delayed the execution of ieee80211_restart_work for too long. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5756fba63d48..28415de5f476 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -807,6 +807,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) rtnl_unlock(); + cancel_work_sync(&local->restart_work); cancel_work_sync(&local->reconfig_filter); ieee80211_clear_tx_pending(local); -- cgit v1.2.3 From 5c673fbf193e272c8c786931b31f23090ab3cb9d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:56:52 -0700 Subject: iwlwifi: update out-of-date comments No functional changes, update comments to match current file structure Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-6000-hw.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 7c731a793632..a4a3194779d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. - * Please use iwl-3945-commands.h for uCode API definitions. + * Please use iwl-commands.h for uCode API definitions. * Please use iwl-3945.h for driver implementation definitions. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 146e6431ae95..3975e45e7500 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-5000-hw.h) only for hardware-related definitions. - * Use iwl-5000-commands.h for uCode API definitions. + * Use iwl-commands.h for uCode API definitions. */ #ifndef __iwl_5000_hw_h__ diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h index ddba39999997..47891e16a758 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-6000-hw.h) only for hardware-related definitions. - * Use iwl-5000-commands.h for uCode API definitions. + * Use iwl-commands.h for uCode API definitions. */ #ifndef __iwl_6000_hw_h__ -- cgit v1.2.3 From 767d055d6a85435bf1d5e63a5097402a5399cfdc Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:56:53 -0700 Subject: iwlwifi: comments cleanup No code or function changes, just some cleanup work for out-of-date comments Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 62 +++++++++++++++-------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 4083e4430827..e2f3616f5b8f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-commands.h) only for uCode API definitions. - * Please use iwl-4965-hw.h for hardware-related definitions. + * Please use iwl-xxxx-hw.h for hardware-related definitions. * Please use iwl-dev.h for driver implementation definitions. */ @@ -1056,7 +1056,8 @@ struct sta_id_modify { * * The device contains an internal table of per-station information, * with info on security keys, aggregation parameters, and Tx rates for - * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD, + * initial Tx attempt and any retries (agn devices uses + * REPLY_TX_LINK_QUALITY_CMD, * 3945 uses REPLY_RATE_SCALE to set up rate tables). * * REPLY_ADD_STA sets up the table entry for one station, either creating @@ -1427,12 +1428,12 @@ struct iwl_rx_mpdu_res_start { * uCode handles all timing and protocol related to control frames * (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler * handle reception of block-acks; uCode updates the host driver via - * REPLY_COMPRESSED_BA (4965). + * REPLY_COMPRESSED_BA. * * uCode handles retrying Tx when an ACK is expected but not received. * This includes trying lower data rates than the one requested in the Tx * command, as set up by the REPLY_RATE_SCALE (for 3945) or - * REPLY_TX_LINK_QUALITY_CMD (4965). + * REPLY_TX_LINK_QUALITY_CMD (agn). * * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. * This command must be executed after every RXON command, before Tx can occur. @@ -1468,7 +1469,7 @@ struct iwl_rx_mpdu_res_start { * Set this for unicast frames, but not broadcast/multicast. */ #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) -/* For 4965: +/* For agn devices: * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). * Tx command's initial_rate_index indicates first rate to try; * uCode walks through table for additional Tx attempts. @@ -1487,7 +1488,7 @@ struct iwl_rx_mpdu_res_start { */ #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) -/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. +/* Tx antenna selection field; used only for 3945, reserved (0) for agn devices. * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) @@ -1870,9 +1871,10 @@ enum { * frame in this new agg block failed in previous agg block(s). * * Note that, for aggregation, ACK (block-ack) status is not delivered here; - * block-ack has not been received by the time the 4965 records this status. + * block-ack has not been received by the time the agn device records + * this status. * This status relates to reasons the tx might have been blocked or aborted - * within the sending station (this 4965), rather than whether it was + * within the sending station (this agn device), rather than whether it was * received successfully by the destination station. */ struct agg_tx_status { @@ -2140,14 +2142,16 @@ struct iwl_link_qual_agg_params { /* * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) * - * For 4965 only; 3945 uses REPLY_RATE_SCALE. + * For agn devices only; 3945 uses REPLY_RATE_SCALE. * - * Each station in the 4965's internal station table has its own table of 16 + * Each station in the agn device's internal station table has its own table + * of 16 * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when * an ACK is not received. This command replaces the entire table for * one station. * - * NOTE: Station must already be in 4965's station table. Use REPLY_ADD_STA. + * NOTE: Station must already be in agn device's station table. + * Use REPLY_ADD_STA. * * The rate scaling procedures described below work well. Of course, other * procedures are possible, and may work better for particular environments. @@ -2184,12 +2188,12 @@ struct iwl_link_qual_agg_params { * * ACCUMULATING HISTORY * - * The rate scaling algorithm for 4965, as implemented in Linux driver, uses - * two sets of frame Tx success history: One for the current/active modulation - * mode, and one for a speculative/search mode that is being attempted. If the - * speculative mode turns out to be more effective (i.e. actual transfer - * rate is better), then the driver continues to use the speculative mode - * as the new current active mode. + * The rate scaling algorithm for agn devices, as implemented in Linux driver, + * uses two sets of frame Tx success history: One for the current/active + * modulation mode, and one for a speculative/search mode that is being + * attempted. If the speculative mode turns out to be more effective (i.e. + * actual transfer rate is better), then the driver continues to use the + * speculative mode as the new current active mode. * * Each history set contains, separately for each possible rate, data for a * sliding window of the 62 most recent tx attempts at that rate. The data @@ -2200,12 +2204,12 @@ struct iwl_link_qual_agg_params { * The driver uses the bit map to remove successes from the success sum, as * the oldest tx attempts fall out of the window. * - * When the 4965 makes multiple tx attempts for a given frame, each attempt - * might be at a different rate, and have different modulation characteristics - * (e.g. antenna, fat channel, short guard interval), as set up in the rate - * scaling table in the Link Quality command. The driver must determine - * which rate table entry was used for each tx attempt, to determine which - * rate-specific history to update, and record only those attempts that + * When the agn device makes multiple tx attempts for a given frame, each + * attempt might be at a different rate, and have different modulation + * characteristics (e.g. antenna, fat channel, short guard interval), as set + * up in the rate scaling table in the Link Quality command. The driver must + * determine which rate table entry was used for each tx attempt, to determine + * which rate-specific history to update, and record only those attempts that * match the modulation characteristics of the history set. * * When using block-ack (aggregation), all frames are transmitted at the same @@ -2335,7 +2339,7 @@ struct iwl_link_quality_cmd { /* * Rate info; when using rate-scaling, Tx command's initial_rate_index * specifies 1st Tx rate attempted, via index into this table. - * 4965 works its way through table when retrying Tx. + * agn devices works its way through table when retrying Tx. */ struct { __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ @@ -2371,7 +2375,7 @@ struct iwl_link_quality_cmd { /* * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) * - * 3945 and 4965 support hardware handshake with Bluetooth device on + * 3945 and agn devices support hardware handshake with Bluetooth device on * same platform. Bluetooth device alerts wireless device when it will Tx; * wireless device can delay or kill its own Tx to accommodate. */ @@ -2572,7 +2576,7 @@ struct iwl_powertable_cmd { /* * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) - * 3945 and 4965 identical. + * all devices identical. */ struct iwl_sleep_notification { u8 pm_sleep_mode; @@ -2583,7 +2587,7 @@ struct iwl_sleep_notification { __le32 bcon_timer; } __packed; -/* Sleep states. 3945 and 4965 identical. */ +/* Sleep states. all devices identical. */ enum { IWL_PM_NO_SLEEP = 0, IWL_PM_SLP_MAC = 1, @@ -3270,7 +3274,7 @@ struct statistics_general_bt { /* * REPLY_STATISTICS_CMD = 0x9c, - * 3945 and 4965 identical. + * all devices identical. * * This command triggers an immediate response containing uCode statistics. * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. @@ -3608,7 +3612,7 @@ struct iwl_enhance_sensitivity_cmd { /** * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) * - * This command sets the relative gains of 4965's 3 radio receiver chains. + * This command sets the relative gains of agn device's 3 radio receiver chains. * * After the first association, driver should accumulate signal and noise * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 -- cgit v1.2.3 From 0288d237fff4cbe54879e3c3433ae5782874f98c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:54 -0700 Subject: iwlwifi: add 6000g2b BT coexist API The new 6000g2b hardware requires a different bluetooth coexist implementation on the host, this adds the command/notification definitions for it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 76 ++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 3 ++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index e2f3616f5b8f..78086ad6b72e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -173,6 +173,12 @@ enum { REPLY_RX_MPDU_CMD = 0xc1, REPLY_RX = 0xc3, REPLY_COMPRESSED_BA = 0xc5, + + /* BT Coex */ + REPLY_BT_COEX_PRIO_TABLE = 0xcc, + REPLY_BT_COEX_PROT_ENV = 0xcd, + REPLY_BT_COEX_PROFILE_NOTIF = 0xce, + REPLY_MAX = 0xff }; @@ -2896,6 +2902,12 @@ struct iwl_scanstart_notification { #define SCAN_OWNER_STATUS 0x1; #define MEASURE_OWNER_STATUS 0x2; +#define IWL_PROBE_STATUS_OK 0 +#define IWL_PROBE_STATUS_TX_FAILED BIT(0) +/* error statuses combined with TX_FAILED */ +#define IWL_PROBE_STATUS_FAIL_TTL BIT(1) +#define IWL_PROBE_STATUS_FAIL_BT BIT(2) + #define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ /* * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) @@ -2903,7 +2915,8 @@ struct iwl_scanstart_notification { struct iwl_scanresults_notification { u8 channel; u8 band; - u8 reserved[2]; + u8 probe_status; + u8 num_probe_not_sent; /* not enough time to send */ __le32 tsf_low; __le32 tsf_high; __le32 statistics[NUMBER_OF_STATISTICS]; @@ -3968,6 +3981,66 @@ struct iwl_coex_event_resp { } __packed; +/****************************************************************************** + * Bluetooth Coexistence commands + * + *****************************************************************************/ + +/* + * BT Status notification + * REPLY_BT_COEX_PROFILE_NOTIF = 0xcb + */ +enum iwl_bt_coex_profile_traffic_load { + IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0, + IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1, + IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2, + IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3, +/* + * There are no more even though below is a u8, the + * indication from the BT device only has two bits. + */ +}; + +struct iwl_bt_coex_profile_notif { + u8 uart_msg[8]; + u8 bt_status; /* 0 - off, 1 - on */ + u8 bt_traffic_load; /* 0 .. 3? */ + u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ + u8 reserved; +} __attribute__((packed)); + +#define IWL_BT_COEX_PRIO_SHARED_ANTENNA 0x1 +#define IWL_BT_COEX_PRIO_PRIO_MASK 0xe +#define IWL_BT_COEX_PRIO_PRIO_SHIFT 1 + +/* + * BT Coexistence Priority table + * REPLY_BT_COEX_PRIO_TABLE = 0xcc + */ +struct iwl_bt_coex_prio_table_cmd { + u8 init_calib_protection_cfg1, + init_calib_protection_cfg2, + init_calib_protection_lowprio_cfg1, + init_calib_protection_lowprio_cfg2, + init_calib_protection_highprio_cfg1, + init_calib_protection_highprio_cfg2, + dtim_protection_prio_cfg, + scan_52_protection_cfg, + scan_24_protection_cfg, + bc_mc_protection_cfg; + u8 reserved[6]; +} __attribute__((packed)); + +/* + * BT Protection Envelope + * REPLY_BT_COEX_PROT_ENV = 0xcd + */ +struct iwl_bt_coex_prot_env_cmd { + u8 open; /* 0 = closed, 1 = open */ + u8 type; /* 0 .. 15 */ + u8 reserved[2]; +} __attribute__((packed)); + /****************************************************************************** * (13) * Union of all expected notifications/responses: @@ -4007,6 +4080,7 @@ struct iwl_rx_packet { struct iwl_missed_beacon_notif missed_beacon; struct iwl_coex_medium_notification coex_medium_notif; struct iwl_coex_event_resp coex_event; + struct iwl_bt_coex_profile_notif bt_coex_profile_notif; __le32 status; u8 raw[0]; } u; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 258d059ef41f..1f15b3aa8478 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -97,6 +97,9 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_TX_POWER_DBM_CMD); IWL_CMD(TEMPERATURE_NOTIFICATION); IWL_CMD(TX_ANT_CONFIGURATION_CMD); + IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); + IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); + IWL_CMD(REPLY_BT_COEX_PROT_ENV); default: return "UNKNOWN"; -- cgit v1.2.3 From 670245ed4515cbc5e39e39d44965cb7add2c8aa9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:55 -0700 Subject: iwlagn: implement advance BT config command 6000g2b hardware implements advance bluetooth coexist command, implement base on the new API command strucutre. Also increment the API 5 to support the advance BT/WIfi coex. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 140 ++++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 62 ++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 3 +- drivers/net/wireless/iwlwifi/iwl-core.h | 5 + 4 files changed, 203 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9e390f698641..fc2eeb00c78c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -52,7 +52,7 @@ /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 4 #define IWL6050_UCODE_API_MAX 4 -#define IWL6000G2_UCODE_API_MAX 4 +#define IWL6000G2_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 @@ -122,6 +122,120 @@ static void iwl6000_nic_config(struct iwl_priv *priv) priv->cfg->ops->lib->temp_ops.set_calib_version(priv); } +/* + * Macros to access the lookup table. + * + * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req, + * wifi_prio, wifi_txrx and wifi_sh_ant_req. + * + * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH + * + * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits + * one after another in 32-bit registers, and "registers" 0 through 7 contain + * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order). + * + * These macros encode that format. + */ +#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \ + wifi_txrx, wifi_sh_ant_req) \ + (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \ + (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6)) + +#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \ + lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f))) +#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx,\ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) +#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +#define LUT_WLAN_KILL_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e))) +#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) +#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +#define LUT_ANT_SWITCH_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1))) +#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) +#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +static const __le32 iwl6000g2b_def_3w_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00004000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0004000), +}; + +static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) +{ + struct iwl6000g2b_bt_cmd bt_cmd = { + .prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .max_kill = IWL6000G2B_BT_MAX_KILL_DEFAULT, + .bt3_timer_t7_value = IWL6000G2B_BT3_T7_DEFAULT, + .kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT, + .kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT, + .bt3_prio_sample_time = IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT, + .bt3_timer_t2_value = IWL6000G2B_BT3_T2_DEFAULT, + .valid = IWL6000G2B_BT_VALID_ENABLE_FLAGS, + }; + + BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) != + sizeof(bt_cmd.bt3_lookup_table)); + + if (!bt_coex_active) { + bt_cmd.flags = 0; + } else { + bt_cmd.flags = IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION | + IWL6000G2B_BT_FLAG_COEX_MODE_3W << + IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT; + bt_cmd.valid |= IWL6000G2B_BT_ALL_VALID_MSK; + } + + memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, + sizeof(iwl6000g2b_def_3w_lookup)); + + IWL_DEBUG_INFO(priv, "BT coex %s\n", + bt_cmd.flags ? "active" : "disabled"); + + if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) + IWL_ERR(priv, "failed to send BT Coex Config\n"); +} + static struct iwl_sensitivity_ranges iwl6000_sensitivity = { .min_nrg_cck = 97, .max_nrg_cck = 0, /* not used, set to 0 */ @@ -344,16 +458,12 @@ static const struct iwl_ops iwl6000_ops = { .led = &iwlagn_led_ops, }; -static void do_not_send_bt_config(struct iwl_priv *priv) -{ -} - static struct iwl_hcmd_ops iwl6000g2b_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, .set_rxon_chain = iwl_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, - .send_bt_config = do_not_send_bt_config, + .send_bt_config = iwl6000g2b_send_bt_config, }; static const struct iwl_ops iwl6000g2b_ops = { @@ -507,6 +617,9 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -543,6 +656,9 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -581,6 +697,9 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -617,6 +736,9 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -655,6 +777,9 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -691,6 +816,9 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .chain_noise_calib_by_driver = true, .need_dc_calib = true, .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, + .advanced_bt_coexist = true, }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 78086ad6b72e..69fc7745edaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2394,6 +2394,68 @@ struct iwl_bt_cmd { __le32 kill_cts_mask; } __packed; +#define IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION BIT(0) + +#define IWL6000G2B_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) +#define IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT 3 +#define IWL6000G2B_BT_FLAG_COEX_MODE_DISABLED 0 +#define IWL6000G2B_BT_FLAG_COEX_MODE_LEGACY_2W 1 +#define IWL6000G2B_BT_FLAG_COEX_MODE_3W 2 +#define IWL6000G2B_BT_FLAG_COEX_MODE_4W 3 + +#define IWL6000G2B_BT_FLAG_UCODE_DEFAULT BIT(6) +#define IWL6000G2B_BT_FLAG_NOCOEX_NOTIF BIT(7) + +#define IWL6000G2B_BT_PRIO_BOOST_MAX 0xFF +#define IWL6000G2B_BT_PRIO_BOOST_MIN 0x00 +#define IWL6000G2B_BT_PRIO_BOOST_DEFAULT 0x00 + +#define IWL6000G2B_BT_MAX_KILL_DEFAULT 5 + +#define IWL6000G2B_BT3_T7_DEFAULT 1 + +#define IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) + +#define IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT 2 + +#define IWL6000G2B_BT3_T2_DEFAULT 0xc + +#define IWL6000G2B_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) +#define IWL6000G2B_BT_VALID_BOOST cpu_to_le16(BIT(1)) +#define IWL6000G2B_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) +#define IWL6000G2B_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) +#define IWL6000G2B_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) +#define IWL6000G2B_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) +#define IWL6000G2B_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) +#define IWL6000G2B_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) + +#define IWL6000G2B_BT_ALL_VALID_MSK (IWL6000G2B_BT_VALID_ENABLE_FLAGS | \ + IWL6000G2B_BT_VALID_BOOST | \ + IWL6000G2B_BT_VALID_MAX_KILL | \ + IWL6000G2B_BT_VALID_3W_TIMERS | \ + IWL6000G2B_BT_VALID_KILL_ACK_MASK | \ + IWL6000G2B_BT_VALID_KILL_CTS_MASK | \ + IWL6000G2B_BT_VALID_BT4_TIMES | \ + IWL6000G2B_BT_VALID_3W_LUT) + +struct iwl6000g2b_bt_cmd { + u8 flags; + u8 ledtime; /* unused */ + u8 max_kill; + u8 bt3_timer_t7_value; + __le32 kill_ack_mask; + __le32 kill_cts_mask; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; /* unused */ + __le32 bt3_lookup_table[12]; + __le16 bt4_decision_time; /* unused */ + __le16 valid; + u8 prio_boost; + u8 reserved[3]; +}; + /****************************************************************************** * (6) * Spectrum Management (802.11h) Commands, Responses, Notifications: diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 3d9443b9bec1..4beddade7423 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -64,7 +64,8 @@ MODULE_LICENSE("GPL"); * * default: bt_coex_active = true (BT_COEX_ENABLE) */ -static bool bt_coex_active = true; +bool bt_coex_active = true; +EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7b1e832bae56..d77337987156 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -278,6 +278,7 @@ struct iwl_mod_params { * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation * @scan_antennas: available antenna for scan operation + * @advanced_bt_coexist: support advanced bt coexist * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation @@ -351,6 +352,7 @@ struct iwl_cfg { const bool chain_noise_calib_by_driver; u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + bool advanced_bt_coexist; const bool need_dc_calib; const bool bt_statistics; u16 agg_time_limit; @@ -732,4 +734,7 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( { return priv->hw->wiphy->bands[band]; } + +extern bool bt_coex_active; + #endif /* __iwl_core_h__ */ -- cgit v1.2.3 From d44ae69e80358ff88d39a14d92c27dba4e90c0c5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:56 -0700 Subject: iwlagn: set BT IGNORE for some frames The BT ignore bit should be set when transmitting auth, assoc response and eap frames. Also, scanning should set the BT ignore bit for the probe request transmission; Note that we only use the non-shared antenna. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index eedd71f5506b..e1b5250ea637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1290,6 +1290,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rate = IWL_RATE_1M_PLCP; rate_flags = RATE_MCS_CCK_MSK; } + /* + * Internal scans are passive, so we can indiscriminately set + * the BT ignore flag on 2.4 GHz since it applies to TX only. + */ + if (priv->cfg->advanced_bt_coexist) + scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; break; case IEEE80211_BAND_5GHZ: diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 3fc982e87921..8d2ffffe01b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -342,10 +342,11 @@ static inline int get_queue_from_ac(u16 ac) * handle build REPLY_TX command notification. */ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, - struct iwl_tx_cmd *tx_cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - u8 std_id) + struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + u8 std_id) { __le16 fc = hdr->frame_control; __le32 tx_flags = tx_cmd->tx_flags; @@ -365,6 +366,12 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, if (ieee80211_is_back_req(fc)) tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; + else if (info->band == IEEE80211_BAND_2GHZ && + priv->cfg->advanced_bt_coexist && + (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || + ieee80211_is_reassoc_req(fc) || + skb->protocol == cpu_to_be16(ETH_P_PAE))) + tx_flags |= TX_CMD_FLG_IGNORE_BT; tx_cmd->sta_id = std_id; @@ -655,7 +662,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); /* TODO need this for burst mode later on */ - iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); + iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); iwl_dbg_log_tx_data_frame(priv, len, hdr); iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc); -- cgit v1.2.3 From 9e4afc21895476114f131b70d1e8fdc3a9c75bb3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:57 -0700 Subject: iwlwifi: add BT notification support for bt coex When advanced bt coex enabled, uCode will send bt status notification to driver, here add support for it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 161 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-commands.h | 7 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 4 + 3 files changed, 171 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index fc2eeb00c78c..f049ebc4a6aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -377,6 +377,90 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return iwl_send_cmd_sync(priv, &hcmd); } +static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_traffic_change_work); + int smps_request = -1; + + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + smps_request = IEEE80211_SMPS_AUTOMATIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + smps_request = IEEE80211_SMPS_DYNAMIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + smps_request = IEEE80211_SMPS_STATIC; + break; + default: + IWL_ERR(priv, "Invalid BT traffic load: %d\n", + priv->bt_traffic_load); + break; + } + + mutex_lock(&priv->mutex); + + if (smps_request != -1 && + priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) + ieee80211_request_smps(priv->vif, smps_request); + + mutex_unlock(&priv->mutex); +} + +static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; + struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; + + IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); + IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); + IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); + IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); + IWL_DEBUG_NOTIF(priv, " UART msg: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x:" + "%.2x:%.2x\n", + coex->uart_msg[0], coex->uart_msg[1], coex->uart_msg[2], + coex->uart_msg[3], coex->uart_msg[4], coex->uart_msg[5], + coex->uart_msg[6], coex->uart_msg[7]); + + if (coex->bt_traffic_load != priv->bt_traffic_load) { + priv->bt_traffic_load = coex->bt_traffic_load; + + queue_work(priv->workqueue, &priv->bt_traffic_change_work); + } + + /* FIXME: add defines for this check */ + priv->bt_sco_active = coex->uart_msg[3] & 1; + if (priv->bt_sco_active) + sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; + iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd, NULL); +} + +void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv) +{ + iwlagn_rx_handler_setup(priv); + priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] = + iwl6000g2b_bt_coex_profile_notif; +} + +static void iwl6000g2b_bt_setup_deferred_work(struct iwl_priv *priv) +{ + iwlagn_setup_deferred_work(priv); + + INIT_WORK(&priv->bt_traffic_change_work, + iwl6000g2b_bt_traffic_change_work); + +} + +static void iwl6000g2b_bt_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->bt_traffic_change_work); +} + static struct iwl_lib_ops iwl6000_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, @@ -451,6 +535,81 @@ static struct iwl_lib_ops iwl6000_lib = { } }; +static struct iwl_lib_ops iwl6000g2b_lib = { + .set_hw_params = iwl6000_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, + .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, + .txq_set_sched = iwlagn_txq_set_sched, + .txq_agg_enable = iwlagn_txq_agg_enable, + .txq_agg_disable = iwlagn_txq_agg_disable, + .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl_hw_txq_free_tfd, + .txq_init = iwl_hw_tx_queue_init, + .rx_handler_setup = iwl6000g2b_rx_handler_setup, + .setup_deferred_work = iwl6000g2b_bt_setup_deferred_work, + .cancel_deferred_work = iwl6000g2b_bt_cancel_deferred_work, + .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, + .load_ucode = iwlagn_load_ucode, + .dump_nic_event_log = iwl_dump_nic_event_log, + .dump_nic_error_log = iwl_dump_nic_error_log, + .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, + .init_alive_start = iwlagn_init_alive_start, + .alive_notify = iwlagn_alive_notify, + .send_tx_power = iwlagn_send_tx_power, + .update_chain_flags = iwl_update_chain_flags, + .set_channel_switch = iwl6000_hw_channel_switch, + .apm_ops = { + .init = iwl_apm_init, + .stop = iwl_apm_stop, + .config = iwl6000_nic_config, + .set_pwr_src = iwl_set_pwr_src, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .verify_signature = iwlcore_eeprom_verify_signature, + .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, + .release_semaphore = iwlcore_eeprom_release_semaphore, + .calib_version = iwlagn_eeprom_calib_version, + .query_addr = iwlagn_eeprom_query_addr, + .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, + }, + .post_associate = iwl_post_associate, + .isr = iwl_isr_ict, + .config_ap = iwl_config_ap, + .temp_ops = { + .temperature = iwlagn_temperature, + .set_ct_kill = iwl6000_set_ct_threshold, + .set_calib_version = iwl6000_set_calib_version, + }, + .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, + .debugfs_ops = { + .rx_stats_read = iwl_ucode_rx_stats_read, + .tx_stats_read = iwl_ucode_tx_stats_read, + .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, + }, + .recover_from_tx_stall = iwl_bg_monitor_recover, + .check_plcp_health = iwl_good_plcp_health, + .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } +}; + static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, @@ -467,7 +626,7 @@ static struct iwl_hcmd_ops iwl6000g2b_hcmd = { }; static const struct iwl_ops iwl6000g2b_ops = { - .lib = &iwl6000_lib, + .lib = &iwl6000g2b_lib, .hcmd = &iwl6000g2b_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 69fc7745edaa..67eaeb6822cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -178,6 +178,7 @@ enum { REPLY_BT_COEX_PRIO_TABLE = 0xcc, REPLY_BT_COEX_PROT_ENV = 0xcd, REPLY_BT_COEX_PROFILE_NOTIF = 0xce, + REPLY_BT_COEX_SCO = 0xcf, REPLY_MAX = 0xff }; @@ -2456,6 +2457,12 @@ struct iwl6000g2b_bt_cmd { u8 reserved[3]; }; +#define IWL6000G2B_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) + +struct iwl6000g2b_bt_sco_cmd { + __le32 flags; +}; + /****************************************************************************** * (6) * Spectrum Management (802.11h) Commands, Responses, Notifications: diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1ad330342ffc..5d327b44533b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1362,6 +1362,10 @@ struct iwl_priv { #endif }; + u8 bt_traffic_load; + bool bt_sco_active; + struct work_struct bt_traffic_change_work; + struct iwl_hw_params hw_params; u32 inta_mask; -- cgit v1.2.3 From 290f599cc6ee8c769355486b7d98fd1dc5115d76 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:58 -0700 Subject: iwlagn: let bluetooth traffic load impact rate scale Depending on the amount of bluetooth traffic, using the shared antenna (antenna B) will have adverse impact on both bluetooth and wireless traffic. Add controls to improve the situation by making rate scaling depend on the BT load. When there's high bluetooth traffic load, there's little point in trying to aggregate as BT traffic would disrupt the aggregated frames all the time, so simply don't start sessions then. When BT traffic returns to lower levels, the rate scaling will come here again automatically when wifi traffic is high enough, and then it will be able to successfully enable aggregation. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 113 +++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 + 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a4563389bad0..f8eed92c1add 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -301,7 +301,19 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, struct ieee80211_sta *sta) { int ret = -EAGAIN; - u32 load = rs_tl_get_load(lq_data, tid); + u32 load; + + /* + * Don't create TX aggregation sessions when in high + * BT traffic, as they would just be disrupted by BT. + */ + if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) { + IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n", + priv->bt_traffic_load); + return ret; + } + + load = rs_tl_get_load(lq_data, tid); if (load > IWL_AGG_LOAD_THRESHOLD) { IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", @@ -1286,6 +1298,27 @@ static int rs_move_legacy_other(struct iwl_priv *priv, int ret = 0; u8 update_search_tbl_counter = 0; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && + tbl->action != IWL_LEGACY_SWITCH_SISO) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if (!iwl_ht_enabled(priv)) /* stay in Legacy */ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; @@ -1425,6 +1458,27 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, u8 update_search_tbl_counter = 0; int ret; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action >= IWL_SISO_SWITCH_ANTENNA2 && + tbl->action != IWL_SISO_SWITCH_GI) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && tbl->action > IWL_SISO_SWITCH_ANTENNA2) { /* stay in SISO */ @@ -1564,6 +1618,27 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, u8 update_search_tbl_counter = 0; int ret; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action == IWL_MIMO2_SWITCH_MIMO3_ABC) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_MIMO2_SWITCH_ANTENNA2) + tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; + else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && (tbl->action < IWL_MIMO2_SWITCH_SISO_A || tbl->action > IWL_MIMO2_SWITCH_SISO_C)) { @@ -1706,6 +1781,29 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, int ret; u8 update_search_tbl_counter = 0; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB || + tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC || + tbl->action == IWL_MIMO3_SWITCH_MIMO2_BC) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_MIMO3_SWITCH_SISO_B) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + else if (tbl->action == IWL_MIMO3_SWITCH_ANTENNA2) + tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && (tbl->action < IWL_MIMO3_SWITCH_SISO_A || tbl->action > IWL_MIMO3_SWITCH_SISO_C)) { @@ -2234,6 +2332,19 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI && (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) scale_action = -1; + + if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { + lq_sta->last_bt_traffic = priv->bt_traffic_load; + /* + * don't set scale_action, don't want to scale up if + * the rate scale doesn't otherwise think that is a + * good idea. + */ + } else if (lq_sta->last_bt_traffic < priv->bt_traffic_load) { + lq_sta->last_bt_traffic = priv->bt_traffic_load; + scale_action = -1; + } + switch (scale_action) { case -1: /* Decrease starting rate, update uCode's rate table */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 8292f6d48ec6..3970ab1deaf9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -432,6 +432,8 @@ struct iwl_lq_sta { u32 last_rate_n_flags; /* packets destined for this STA are aggregated */ u8 is_agg; + /* BT traffic this sta was last updated in */ + u8 last_bt_traffic; }; static inline u8 num_of_ant(u8 mask) -- cgit v1.2.3 From a11741383ba6eef707b8330f0d3c1da6a7478ee3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:56:59 -0700 Subject: iwlwifi: reset BT when going down When we turn off the device, reset BT data so that we don't have outdated information when we come up again. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 26bc0482dd9e..a8a5a5b79f39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2773,6 +2773,10 @@ static void __iwl_down(struct iwl_priv *priv) iwl_dealloc_bcast_station(priv); iwl_clear_driver_stations(priv); + /* reset BT coex data */ + priv->bt_traffic_load = 0; + priv->bt_sco_active = false; + /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -3078,8 +3082,9 @@ static void iwl_bg_restart(struct work_struct *data) mutex_lock(&priv->mutex); priv->vif = NULL; priv->is_open = 0; + __iwl_down(priv); mutex_unlock(&priv->mutex); - iwl_down(priv); + iwl_cancel_deferred_work(priv); ieee80211_restart_hw(priv->hw); } else { iwl_down(priv); -- cgit v1.2.3 From 59079949faed96cc2756d5a59c185b304f1bc840 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:57:00 -0700 Subject: iwlagn: disable gen2b BT coexistence in IBSS IBSS doesn't allow for coexistence, so it should be disabled. Additionally, disable reacting to the BT profile notification when in IBSS mode, it likely won't be sent by the device to start with though. Also, in IBSS mode, BT coexistence isn't as fully-featured and we must use a single antenna only. So instead of peppering the code with new checks, simply pretend we are in high BT traffic load, which has the needed effect of disabling antenna B use. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 34 ++++++++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-core.c | 21 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f049ebc4a6aa..51419444834f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -217,7 +217,14 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) != sizeof(bt_cmd.bt3_lookup_table)); - if (!bt_coex_active) { + /* + * Configure BT coex mode to "no coexistence" when the + * user disabled BT coexistence, we have no interface + * (might be in monitor mode), or the interface is in + * IBSS mode (no proper uCode support for coex then). + */ + if (!bt_coex_active || !priv->vif || + priv->iw_mode == NL80211_IFTYPE_ADHOC) { bt_cmd.flags = 0; } else { bt_cmd.flags = IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION | @@ -426,18 +433,23 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, coex->uart_msg[3], coex->uart_msg[4], coex->uart_msg[5], coex->uart_msg[6], coex->uart_msg[7]); - if (coex->bt_traffic_load != priv->bt_traffic_load) { - priv->bt_traffic_load = coex->bt_traffic_load; + priv->notif_bt_traffic_load = coex->bt_traffic_load; - queue_work(priv->workqueue, &priv->bt_traffic_change_work); - } + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { + if (coex->bt_traffic_load != priv->bt_traffic_load) { + priv->bt_traffic_load = coex->bt_traffic_load; - /* FIXME: add defines for this check */ - priv->bt_sco_active = coex->uart_msg[3] & 1; - if (priv->bt_sco_active) - sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; - iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, - sizeof(sco_cmd), &sco_cmd, NULL); + queue_work(priv->workqueue, + &priv->bt_traffic_change_work); + } + + /* FIXME: add defines for this check */ + priv->bt_sco_active = coex->uart_msg[3] & 1; + if (priv->bt_sco_active) + sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; + iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd, NULL); + } } void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4beddade7423..1921307a23b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1872,6 +1872,16 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) if (err) goto out_err; + if (priv->cfg->advanced_bt_coexist && + vif->type == NL80211_IFTYPE_ADHOC) { + /* + * pretend to have high BT traffic as long as we + * are operating in IBSS mode, as this will cause + * the rate scaling etc. to behave as intended. + */ + priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + } + goto out; out_err: @@ -1909,6 +1919,17 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } memset(priv->bssid, 0, ETH_ALEN); } + + /* + * When removing the IBSS interface, overwrite the + * BT traffic load with the stored one from the last + * notification, if any. If this is a device that + * doesn't implement this, this has no effect since + * both values are the same and zero. + */ + if (vif->type == NL80211_IFTYPE_ADHOC) + priv->bt_traffic_load = priv->notif_bt_traffic_load; + mutex_unlock(&priv->mutex); if (scan_completed) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5d327b44533b..815ba0af94ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1362,7 +1362,7 @@ struct iwl_priv { #endif }; - u8 bt_traffic_load; + u8 bt_traffic_load, notif_bt_traffic_load; bool bt_sco_active; struct work_struct bt_traffic_change_work; -- cgit v1.2.3 From 511b082d29bc68c722abd34c1f0219b5754c1163 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:57:01 -0700 Subject: iwlagn: keep BT settings across restart The BT SCO needs to be re-applied to the device, while the traffic load just needs to be correct in software. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 51419444834f..22676d960d6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -241,6 +241,22 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); + + /* + * When we are doing a restart, need to also reconfigure BT + * SCO to the device. If not doing a restart, bt_sco_active + * will always be false, so there's no need to have an extra + * variable to check for it. + */ + if (priv->bt_sco_active) { + struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; + + if (priv->bt_sco_active) + sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd)) + IWL_ERR(priv, "failed to send BT SCO command\n"); + } } static struct iwl_sensitivity_ranges iwl6000_sensitivity = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a8a5a5b79f39..ecf7cf012679 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3079,10 +3079,30 @@ static void iwl_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + bool bt_sco; + u8 bt_load; + mutex_lock(&priv->mutex); priv->vif = NULL; priv->is_open = 0; + + /* + * __iwl_down() will clear the BT status variables, + * which is correct, but when we restart we really + * want to keep them so restore them afterwards. + * + * The restart process will later pick them up and + * re-configure the hw when we reconfigure the BT + * command. + */ + bt_sco = priv->bt_sco_active; + bt_load = priv->bt_traffic_load; + __iwl_down(priv); + + priv->bt_sco_active = bt_sco; + priv->bt_traffic_load = bt_load; + mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); ieee80211_restart_hw(priv->hw); -- cgit v1.2.3 From 74e5c41bafb07f73d8445dcf5a6a968a717d3daa Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:02 -0700 Subject: iwlwifi: Relax uCode timeout/error checking for 6000g2b Disable plcp error checking for 6000g2b devices, with wifi/bt coex; this got trigger too often, disable for now until finding better trigger point. Also extend the firmware reload timer much longer for BT coex to make sure there are will be no mistake to reload firmware too fast and too often. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 10 +++++++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 22676d960d6e..9d430987cc62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -796,7 +796,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, @@ -835,7 +835,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, @@ -876,7 +876,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, @@ -915,7 +915,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, @@ -956,7 +956,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, @@ -995,7 +995,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, .chain_noise_scale = 1000, .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 1921307a23b8..72eda7e8a00d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2646,10 +2646,14 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) "queue %d, not read %d time\n", q->id, q->repeat_same_read_ptr); - mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS)); + if (!priv->cfg->advanced_bt_coexist) { + mod_timer(&priv->monitor_recover, + jiffies + msecs_to_jiffies( + IWL_ONE_HUNDRED_MSECS)); + return 1; + } } - return 1; + return 0; } else { q->last_read_ptr = q->read_ptr; q->repeat_same_read_ptr = 0; -- cgit v1.2.3 From bd6e2d579949aede258c673caf4b1eb39b95e172 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:57:03 -0700 Subject: iwlwifi: use antenna A only under high BT load When bluetooth indicated high load, we should use only antenna A in 2.4 GHz for management frames. Add this condition to iwl_toggle_tx_ant() to make sure it'll always be met. Note that scanning has a separate way of forcing the antenna, because we should scan on antenna A only regardless of BT traffic load. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 72eda7e8a00d..5e8fc720c570 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -147,6 +147,10 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) int i; u8 ind = ant; + if (priv->band == IEEE80211_BAND_2GHZ && + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) + return 0; + for (i = 0; i < RATE_ANT_NUM - 1; i++) { ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; if (valid & BIT(ind)) -- cgit v1.2.3 From bee008b78307ccc2e17c7ec152dd2098d5f2e1fa Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:04 -0700 Subject: iwlwifi: add bt full concurrency support Adding the bluetooth full concurrency support for WiFi/BT combo devices. Driver should configure uCode to operate in "full concurrency" mode (via LUT) if both conditions are met: - Antenna Coupling is more than 35dB - WiFi Channel Inhibition Request is hornored by BT Core Currently, there is no antenna coupling information provided by uCode; use module parameter to specified the antenna coupling in dB. When in "full concurrency" mode, driver need to download different LUT to uCode while sending bt configuration command; also, driver need to configure the device operate in 1x1 while in full concurrency mode. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 34 ++++++++++++-- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 6 ++- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 11 +++++ drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 70 ++++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 7 ++- drivers/net/wireless/iwlwifi/iwl-agn.c | 49 ++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-core.c | 11 ++++- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 7 +++ 9 files changed, 185 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9d430987cc62..a4601b58a5db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -201,6 +201,21 @@ static const __le32 iwl6000g2b_def_3w_lookup[12] = { cpu_to_le32(0xf0004000), }; +static const __le32 iwl6000g2b_concurrent_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) { struct iwl6000g2b_bt_cmd bt_cmd = { @@ -233,11 +248,17 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) bt_cmd.valid |= IWL6000G2B_BT_ALL_VALID_MSK; } - memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, - sizeof(iwl6000g2b_def_3w_lookup)); + if (priv->bt_full_concurrent) + memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_concurrent_lookup, + sizeof(iwl6000g2b_concurrent_lookup)); + else + memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, + sizeof(iwl6000g2b_def_3w_lookup)); - IWL_DEBUG_INFO(priv, "BT coex %s\n", - bt_cmd.flags ? "active" : "disabled"); + IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", + bt_cmd.flags ? "active" : "disabled", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); @@ -435,6 +456,7 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { + unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; @@ -466,6 +488,10 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, sizeof(sco_cmd), &sco_cmd, NULL); } + + spin_lock_irqsave(&priv->lock, flags); + priv->bt_ci_compliance = coex->bt_ci_compliance; + spin_unlock_irqrestore(&priv->lock, flags); } void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index c4c5691032a6..156b125dba71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -914,7 +914,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) * To be safe, simply mask out any chains that we know * are not on the device. */ - active_chains &= priv->hw_params.valid_rx_ant; + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + active_chains &= first_antenna(priv->hw_params.valid_rx_ant); + } else + active_chains &= priv->hw_params.valid_rx_ant; num_tx_chains = 0; for (i = 0; i < NUM_RX_CHAINS; i++) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e1b5250ea637..e0ec6c08b222 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1333,6 +1333,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->scan_tx_antennas[band]) scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + scan_tx_antennas = + first_antenna(priv->cfg->scan_tx_antennas[band]); + } + priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], scan_tx_antennas); rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); @@ -1351,6 +1357,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_ant = first_antenna(active_chains); } + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + rx_ant = first_antenna(rx_ant); + } + /* MIMO is not used here, but value is required */ rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index f8eed92c1add..687b534d83d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -758,6 +758,32 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, (a->is_SGI == b->is_SGI); } +static void rs_bt_update_lq(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta) +{ + struct iwl_scale_tbl_info *tbl; + bool full_concurrent; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) + full_concurrent = true; + else + full_concurrent = false; + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->bt_full_concurrent != full_concurrent) { + priv->bt_full_concurrent = full_concurrent; + + /* Update uCode's rate table. */ + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); + iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + + queue_work(priv->workqueue, &priv->bt_full_concurrency); + } +} + /* * mac80211 sends us Tx status */ @@ -940,6 +966,10 @@ done: /* See if there's a better rate or modulation mode to try. */ if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); + + /* Is there a need to switch between full concurrency and 3-wire? */ + if (priv->bt_ant_couple_ok) + rs_bt_update_lq(priv, lq_sta); } /* @@ -1325,6 +1355,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv, else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && tbl->action > IWL_LEGACY_SWITCH_SISO) tbl->action = IWL_LEGACY_SWITCH_SISO; + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent) { + if (!iwl_ht_enabled(priv)) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_LEGACY_SWITCH_SISO; + } + start_action = tbl->action; for (; ;) { lq_sta->action_counter++; @@ -1484,6 +1523,12 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, /* stay in SISO */ tbl->action = IWL_SISO_SWITCH_ANTENNA1; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent && + tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + start_action = tbl->action; for (;;) { lq_sta->action_counter++; @@ -1645,6 +1690,13 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, /* switch in SISO */ tbl->action = IWL_MIMO2_SWITCH_SISO_A; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent && + (tbl->action < IWL_MIMO2_SWITCH_SISO_A || + tbl->action > IWL_MIMO2_SWITCH_SISO_C)) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + start_action = tbl->action; for (;;) { lq_sta->action_counter++; @@ -1810,6 +1862,13 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, /* switch in SISO */ tbl->action = IWL_MIMO3_SWITCH_SISO_A; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent && + (tbl->action < IWL_MIMO3_SWITCH_SISO_A || + tbl->action > IWL_MIMO3_SWITCH_SISO_C)) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + start_action = tbl->action; for (;;) { lq_sta->action_counter++; @@ -2741,7 +2800,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, /* Fill 1st table entry (index 0) */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); - if (num_of_ant(tbl_type.ant_type) == 1) { + if (num_of_ant(tbl_type.ant_type) == 1 || + (priv && priv->bt_full_concurrent)) { lq_cmd->general_params.single_stream_ant_msk = tbl_type.ant_type; } else if (num_of_ant(tbl_type.ant_type) == 2) { @@ -2752,8 +2812,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, index++; repeat_rate--; - if (priv) - valid_tx_ant = priv->hw_params.valid_tx_ant; + if (priv) { + if (priv->bt_full_concurrent) + valid_tx_ant = ANT_A; + else + valid_tx_ant = priv->hw_params.valid_tx_ant; + } /* Fill rest of rate table */ while (index < LINK_QUAL_MAX_RETRY_NUM) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 8d2ffffe01b2..e2497e7ba926 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -461,7 +461,12 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ - priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + first_antenna(priv->hw_params.valid_tx_ant)); + } else + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ecf7cf012679..807d697f6239 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -87,6 +87,8 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); MODULE_ALIAS("iwl4965"); +static int iwlagn_ant_coupling; + /** * iwl_commit_rxon - commit staging_rxon to hardware * @@ -612,6 +614,33 @@ static void iwl_bg_beacon_update(struct work_struct *work) iwl_send_beacon_cmd(priv); } +static void iwl_bg_bt_full_concurrency(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_full_concurrency); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* dont send host command if rf-kill is on */ + if (!iwl_is_ready_rf(priv)) + return; + + IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); + + /* + * LQ & RXON updated cmds must be sent before BT Config cmd + * to avoid 3-wire collisions + */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + iwlcore_commit_rxon(priv); + + priv->cfg->ops->hcmd->send_bt_config(priv); +} + /** * iwl_bg_statistics_periodic - Timer callback to queue statistics * @@ -2776,6 +2805,8 @@ static void __iwl_down(struct iwl_priv *priv) /* reset BT coex data */ priv->bt_traffic_load = 0; priv->bt_sco_active = false; + priv->bt_full_concurrent = false; + priv->bt_ci_compliance = 0; /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -3079,7 +3110,8 @@ static void iwl_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { - bool bt_sco; + bool bt_sco, bt_full_concurrent; + u8 bt_ci_compliance; u8 bt_load; mutex_lock(&priv->mutex); @@ -3096,11 +3128,15 @@ static void iwl_bg_restart(struct work_struct *data) * command. */ bt_sco = priv->bt_sco_active; + bt_full_concurrent = priv->bt_full_concurrent; + bt_ci_compliance = priv->bt_ci_compliance; bt_load = priv->bt_traffic_load; __iwl_down(priv); priv->bt_sco_active = bt_sco; + priv->bt_full_concurrent = bt_full_concurrent; + priv->bt_ci_compliance = bt_ci_compliance; priv->bt_traffic_load = bt_load; mutex_unlock(&priv->mutex); @@ -3856,6 +3892,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); + INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); @@ -3898,6 +3935,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_delayed_work(&priv->alive_start); cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); + cancel_work_sync(&priv->bt_full_concurrency); del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); } @@ -4078,6 +4116,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; + /* is antenna coupling more than 35dB ? */ + priv->bt_ant_couple_ok = + (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? + true : false; + if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); @@ -4611,3 +4654,7 @@ module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, S_IRUGO); MODULE_PARM_DESC(ucode_alternative, "specify ucode alternative to use from ucode file"); + +module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO); +MODULE_PARM_DESC(antenna_coupling, + "specify antenna coupling in dB (defualt: 0 dB)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5e8fc720c570..13d2dcea85d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -780,6 +780,10 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); */ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + return IWL_NUM_RX_CHAINS_SINGLE; + } /* # of Rx chains to use when expecting MIMO. */ if (is_single_rx_stream(priv)) return IWL_NUM_RX_CHAINS_SINGLE; @@ -836,11 +840,16 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) * Before first association, we assume all antennas are connected. * Just after first association, iwl_chain_noise_calibration() * checks which antennas actually *are* connected. */ - if (priv->chain_noise_data.active_chains) + if (priv->chain_noise_data.active_chains) active_chains = priv->chain_noise_data.active_chains; else active_chains = priv->hw_params.valid_rx_ant; + if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + active_chains = first_antenna(active_chains); + } + rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; /* How many receivers should we use? */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d77337987156..146d0d5ec6b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -736,5 +736,6 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( } extern bool bt_coex_active; +extern bool bt_siso_mode; #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 815ba0af94ce..7a96d9dd1732 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1065,6 +1065,9 @@ struct iwl_event_log { #define IWL_LONG_MONITORING_PERIOD (5000) #define IWL_ONE_HUNDRED_MSECS (100) +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) + enum iwl_reset { IWL_RF_RESET = 0, IWL_FW_RESET, @@ -1364,6 +1367,9 @@ struct iwl_priv { u8 bt_traffic_load, notif_bt_traffic_load; bool bt_sco_active; + bool bt_full_concurrent; + bool bt_ant_couple_ok; + u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; struct iwl_hw_params hw_params; @@ -1384,6 +1390,7 @@ struct iwl_priv { struct work_struct ct_exit; struct work_struct start_internal_scan; struct work_struct tx_flush; + struct work_struct bt_full_concurrency; struct tasklet_struct irq_tasklet; -- cgit v1.2.3 From aeb4a2eec2b1d2ac6507e9cec2aecc46fdba8741 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:05 -0700 Subject: iwlagn: wifi/bt coex configuration sequence bt config command need to send before the init calibration command, driver need to let uCode know that calibrations are being performed now in order to assure antenna is not being taken to BT use during radio/dsp reads/writes Also, bt_coex_priorty_table command need to be send right after the bt_config_command during init sequence. Followed by bt coex envelope command to initialize and prepare uCode bt state machine Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 5 +-- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 59 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++- drivers/net/wireless/iwlwifi/iwl-commands.h | 59 +++++++++++++++++++++------- 4 files changed, 109 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a4601b58a5db..101630b80c40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -235,11 +235,10 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) /* * Configure BT coex mode to "no coexistence" when the * user disabled BT coexistence, we have no interface - * (might be in monitor mode), or the interface is in + * user disabled BT coexistence, or the interface is in * IBSS mode (no proper uCode support for coex then). */ - if (!bt_coex_active || !priv->vif || - priv->iw_mode == NL80211_IFTYPE_ADHOC) { + if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { bt_cmd.flags = 0; } else { bt_cmd.flags = IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION | diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 6f77441cb65a..2dc569bc7e8f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -329,6 +329,51 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) sizeof(coex_cmd), &coex_cmd); } +static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + 0, 0, 0, 0, 0, 0, 0 +}; + +static void iwlagn_send_prio_tbl(struct iwl_priv *priv) +{ + struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; + + memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl, + sizeof(iwlagn_bt_prio_tbl)); + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, + sizeof(prio_tbl_cmd), &prio_tbl_cmd)) + IWL_ERR(priv, "failed to send BT prio tbl command\n"); +} + +static void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) +{ + struct iwl_bt_coex_prot_env_cmd env_cmd; + + env_cmd.action = action; + env_cmd.type = type; + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, + sizeof(env_cmd), &env_cmd)) + IWL_ERR(priv, "failed to send BT env command\n"); +} + + int iwlagn_alive_notify(struct iwl_priv *priv) { u32 a; @@ -416,6 +461,20 @@ int iwlagn_alive_notify(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); + if (priv->cfg->advanced_bt_coexist) { + /* Configure Bluetooth device coexistence support */ + /* need to perform this before any calibration */ + priv->cfg->ops->hcmd->send_bt_config(priv); + if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) { + iwlagn_send_prio_tbl(priv); + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + } + + } + iwlagn_send_wimax_coex(priv); iwlagn_set_Xtal_calib(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 807d697f6239..c17ce823f84d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2754,8 +2754,10 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->set_rxon_chain(priv); } - /* Configure Bluetooth device coexistence support */ - priv->cfg->ops->hcmd->send_bt_config(priv); + if (!priv->cfg->advanced_bt_coexist) { + /* Configure Bluetooth device coexistence support */ + priv->cfg->ops->hcmd->send_bt_config(priv); + } iwl_reset_run_time_calib(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 67eaeb6822cb..b45882aa68fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -4078,34 +4078,63 @@ struct iwl_bt_coex_profile_notif { u8 reserved; } __attribute__((packed)); -#define IWL_BT_COEX_PRIO_SHARED_ANTENNA 0x1 -#define IWL_BT_COEX_PRIO_PRIO_MASK 0xe -#define IWL_BT_COEX_PRIO_PRIO_SHIFT 1 +#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 +#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 +#define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1 +#define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e +#define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4 +#define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0 +#define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1 /* * BT Coexistence Priority table * REPLY_BT_COEX_PRIO_TABLE = 0xcc */ +enum bt_coex_prio_table_events { + BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */ + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, + BT_COEX_PRIO_TBL_EVT_DTIM = 6, + BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, + BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, + BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9, + BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10, + BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11, + BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12, + BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13, + BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14, + BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15, + /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */ + BT_COEX_PRIO_TBL_EVT_MAX, +}; + +enum bt_coex_prio_table_priorities { + BT_COEX_PRIO_TBL_DISABLED = 0, + BT_COEX_PRIO_TBL_PRIO_LOW = 1, + BT_COEX_PRIO_TBL_PRIO_HIGH = 2, + BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, + BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, + BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6, + BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7, + BT_COEX_PRIO_TBL_MAX, +}; + struct iwl_bt_coex_prio_table_cmd { - u8 init_calib_protection_cfg1, - init_calib_protection_cfg2, - init_calib_protection_lowprio_cfg1, - init_calib_protection_lowprio_cfg2, - init_calib_protection_highprio_cfg1, - init_calib_protection_highprio_cfg2, - dtim_protection_prio_cfg, - scan_52_protection_cfg, - scan_24_protection_cfg, - bc_mc_protection_cfg; - u8 reserved[6]; + u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; } __attribute__((packed)); +#define IWL_BT_COEX_ENV_CLOSE 0 +#define IWL_BT_COEX_ENV_OPEN 1 /* * BT Protection Envelope * REPLY_BT_COEX_PROT_ENV = 0xcd */ struct iwl_bt_coex_prot_env_cmd { - u8 open; /* 0 = closed, 1 = open */ + u8 action; /* 0 = closed, 1 = open */ u8 type; /* 0 .. 15 */ u8 reserved[2]; } __attribute__((packed)); -- cgit v1.2.3 From c6c996b5de82b5de4b4b5a31941aab725961a6dd Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:06 -0700 Subject: iwlwifi: indicate bt_kill condition when receive tx reply Generate log when receive tx reply with bt_kill count > 0 and in advance bt coex mode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e0ec6c08b222..ea242401b5a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -247,7 +247,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg; agg = &priv->stations[sta_id].tid[tid].agg; - + /* + * If the BT kill count is non-zero, we'll get this + * notification again. + */ + if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && + priv->cfg->advanced_bt_coexist) { + IWL_WARN(priv, "receive reply tx with bt_kill\n"); + } iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); /* check if BAR is needed */ -- cgit v1.2.3 From 7bdc473c7a52497af9fe8c73e4745615a2825aaa Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:07 -0700 Subject: iwlwifi: add debugfs to control stuck queue timer In current implementation, stuck queue timer is fixed to 1 second. Add debugfs file to modify the timer to enhance the flexibility: Set the monitor_period as following: 0: disable stuck queue force reset function 1 - 60000: monitor period (1 - 60 second) Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 14 ++++++++------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 30 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 13d2dcea85d1..34cba38f1d0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2697,12 +2697,14 @@ void iwl_bg_monitor_recover(unsigned long data) return; } } - /* - * Reschedule the timer to occur in - * priv->cfg->monitor_recover_period - */ - mod_timer(&priv->monitor_recover, - jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period)); + if (priv->cfg->monitor_recover_period) { + /* + * Reschedule the timer to occur in + * priv->cfg->monitor_recover_period + */ + mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( + priv->cfg->monitor_recover_period)); + } } EXPORT_SYMBOL(iwl_bg_monitor_recover); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d3acdae72381..aae9eb552350 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1527,6 +1527,34 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, user_buf, count, ppos); } +static ssize_t iwl_dbgfs_monitor_period_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int period; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &period) != 1) + return -EINVAL; + if (period < 0 || period > IWL_MAX_MONITORING_PERIOD) + priv->cfg->monitor_recover_period = IWL_DEF_MONITORING_PERIOD; + else + priv->cfg->monitor_recover_period = period; + + if (priv->cfg->monitor_recover_period) + mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( + priv->cfg->monitor_recover_period)); + else + del_timer_sync(&priv->monitor_recover); + return count; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1550,6 +1578,7 @@ DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); DEBUGFS_WRITE_FILE_OPS(txfifo_flush); DEBUGFS_READ_FILE_OPS(ucode_bt_stats); +DEBUGFS_WRITE_FILE_OPS(monitor_period); /* * Create the debugfs files and directories @@ -1621,6 +1650,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); if (priv->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7a96d9dd1732..bb92a7f01988 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1064,6 +1064,7 @@ struct iwl_event_log { #define IWL_DEF_MONITORING_PERIOD (1000) #define IWL_LONG_MONITORING_PERIOD (5000) #define IWL_ONE_HUNDRED_MSECS (100) +#define IWL_MAX_MONITORING_PERIOD (60000) /* BT Antenna Coupling Threshold (dB) */ #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) -- cgit v1.2.3 From a4b96cc4e3fa99d5d6d8ad38c5b0aa4c3aa8a828 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:08 -0700 Subject: iwlwifi: add bt_init_traffic_load as configurable parameter Adding configurable parameter in .cfg for the initial Bluetooth traffic load; set it to IWL_BT_COEX_TRAFFIC_LOAD_NONE for now, but can be change for debugging or other reason. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 101630b80c40..396d80c0ef38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -832,6 +832,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -871,6 +872,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -912,6 +914,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -951,6 +954,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -992,6 +996,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -1031,6 +1036,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c17ce823f84d..06e89d474d04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2805,7 +2805,7 @@ static void __iwl_down(struct iwl_priv *priv) iwl_clear_driver_stations(priv); /* reset BT coex data */ - priv->bt_traffic_load = 0; + priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; priv->bt_sco_active = false; priv->bt_full_concurrent = false; priv->bt_ci_compliance = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 146d0d5ec6b9..d5dacaf0d09f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -279,6 +279,7 @@ struct iwl_mod_params { * chain noise calibration operation * @scan_antennas: available antenna for scan operation * @advanced_bt_coexist: support advanced bt coexist + * @bt_init_traffic_load: specify initial bt traffic load * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation @@ -353,6 +354,7 @@ struct iwl_cfg { u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; bool advanced_bt_coexist; + u8 bt_init_traffic_load; const bool need_dc_calib; const bool bt_statistics; u16 agg_time_limit; -- cgit v1.2.3 From 5d297d50653ba0c498e0b1e7b72b6611651357aa Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:09 -0700 Subject: iwlagn: add bt prio_boost to .cfg Use .cfg to configure the default bt priority boost value; the default bt priority boost is 0xf0 Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 11 ++++++++++- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 396d80c0ef38..54b59dadf2a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -219,7 +219,6 @@ static const __le32 iwl6000g2b_concurrent_lookup[12] = { static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) { struct iwl6000g2b_bt_cmd bt_cmd = { - .prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, .max_kill = IWL6000G2B_BT_MAX_KILL_DEFAULT, .bt3_timer_t7_value = IWL6000G2B_BT3_T7_DEFAULT, .kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT, @@ -232,6 +231,8 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) != sizeof(bt_cmd.bt3_lookup_table)); + bt_cmd.prio_boost = priv->cfg->bt_prio_boost; + /* * Configure BT coex mode to "no coexistence" when the * user disabled BT coexistence, we have no interface @@ -488,6 +489,8 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, sizeof(sco_cmd), &sco_cmd, NULL); } + /* FIXME: based on notification, adjust the prio_boost */ + spin_lock_irqsave(&priv->lock, flags); priv->bt_ci_compliance = coex->bt_ci_compliance; spin_unlock_irqrestore(&priv->lock, flags); @@ -833,6 +836,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -873,6 +877,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -915,6 +920,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -955,6 +961,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -997,6 +1004,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -1037,6 +1045,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index b45882aa68fe..e742f994ff82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2409,7 +2409,7 @@ struct iwl_bt_cmd { #define IWL6000G2B_BT_PRIO_BOOST_MAX 0xFF #define IWL6000G2B_BT_PRIO_BOOST_MIN 0x00 -#define IWL6000G2B_BT_PRIO_BOOST_DEFAULT 0x00 +#define IWL6000G2B_BT_PRIO_BOOST_DEFAULT 0xF0 #define IWL6000G2B_BT_MAX_KILL_DEFAULT 5 diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d5dacaf0d09f..de2e39f36c25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -280,6 +280,7 @@ struct iwl_mod_params { * @scan_antennas: available antenna for scan operation * @advanced_bt_coexist: support advanced bt coexist * @bt_init_traffic_load: specify initial bt traffic load + * @bt_prio_boost: default bt priority boost value * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation @@ -355,6 +356,7 @@ struct iwl_cfg { u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; bool advanced_bt_coexist; u8 bt_init_traffic_load; + u8 bt_prio_boost; const bool need_dc_calib; const bool bt_statistics; u16 agg_time_limit; -- cgit v1.2.3 From fbba94104fb44d2f984e767cd8ac1edd80cb03d5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:10 -0700 Subject: iwlagn: parsing uart message and take actions 1. Based on uart message from uCode, re-configure BT kill ack mask messages from uCode 2. send REPLY_BT_COEX_SCO command to uCode based on the uart frame received from uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 116 +++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 5 ++ drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 110 ++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 + 5 files changed, 235 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 54b59dadf2a8..e4873cc2a57a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -221,17 +221,17 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) struct iwl6000g2b_bt_cmd bt_cmd = { .max_kill = IWL6000G2B_BT_MAX_KILL_DEFAULT, .bt3_timer_t7_value = IWL6000G2B_BT3_T7_DEFAULT, - .kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT, - .kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT, .bt3_prio_sample_time = IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT, .bt3_timer_t2_value = IWL6000G2B_BT3_T2_DEFAULT, - .valid = IWL6000G2B_BT_VALID_ENABLE_FLAGS, }; BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) != sizeof(bt_cmd.bt3_lookup_table)); bt_cmd.prio_boost = priv->cfg->bt_prio_boost; + bt_cmd.kill_ack_mask = priv->kill_ack_mask; + bt_cmd.kill_cts_mask = priv->kill_cts_mask; + bt_cmd.valid = priv->bt_valid; /* * Configure BT coex mode to "no coexistence" when the @@ -245,7 +245,6 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) bt_cmd.flags = IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION | IWL6000G2B_BT_FLAG_COEX_MODE_3W << IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT; - bt_cmd.valid |= IWL6000G2B_BT_ALL_VALID_MSK; } if (priv->bt_full_concurrent) @@ -453,6 +452,93 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) mutex_unlock(&priv->mutex); } +static void iwlagn_print_uartmsg(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " + "Update Req = 0x%X", + (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1MSGTYPE_POS, + (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1SSN_POS, + (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1UPDATEREQ_POS); + + IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " + "Chl_SeqN = 0x%X, In band = 0x%X", + (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, + (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2TRAFFICLOAD_POS, + (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2CHLSEQN_POS, + (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2INBAND_POS); + + IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " + "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", + (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SCOESCO_POS, + (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SNIFF_POS, + (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3A2DP_POS, + (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3ACL_POS, + (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3MASTER_POS, + (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3OBEX_POS); + + IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", + (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> + BT_UART_MSG_FRAME4IDLEDURATION_POS); + + IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " + "eSCO Retransmissions = 0x%X", + (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5TXACTIVITY_POS, + (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5RXACTIVITY_POS, + (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", + (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, + (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6DISCOVERABLE_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = " + "0x%X, Connectable = 0x%X", + (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, + (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS, + (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7CONNECTABLE_POS); +} + +static void iwl6000g2b_set_kill_ack_msk(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + u8 kill_ack_msk; + __le32 bt_kill_ack_msg[2] = { + cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; + + kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | + BT_UART_MSG_FRAME3SNIFF_MSK | + BT_UART_MSG_FRAME3SCOESCO_MSK) & + uart_msg->frame3) == 0) ? 1 : 0; + if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) { + priv->bt_valid |= IWL6000G2B_BT_VALID_KILL_ACK_MASK; + priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk]; + /* schedule to send runtime bt_config */ + queue_work(priv->workqueue, &priv->bt_runtime_config); + } + +} + static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -460,16 +546,13 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; + struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); - IWL_DEBUG_NOTIF(priv, " UART msg: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x:" - "%.2x:%.2x\n", - coex->uart_msg[0], coex->uart_msg[1], coex->uart_msg[2], - coex->uart_msg[3], coex->uart_msg[4], coex->uart_msg[5], - coex->uart_msg[6], coex->uart_msg[7]); + iwlagn_print_uartmsg(priv, uart_msg); priv->notif_bt_traffic_load = coex->bt_traffic_load; @@ -481,14 +564,19 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, &priv->bt_traffic_change_work); } - /* FIXME: add defines for this check */ - priv->bt_sco_active = coex->uart_msg[3] & 1; - if (priv->bt_sco_active) - sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; - iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, + if (priv->bt_sco_active != + (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { + priv->bt_sco_active = uart_msg->frame3 & + BT_UART_MSG_FRAME3SCOESCO_MSK; + if (priv->bt_sco_active) + sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; + iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, sizeof(sco_cmd), &sco_cmd, NULL); + } } + iwl6000g2b_set_kill_ack_msk(priv, uart_msg); + /* FIXME: based on notification, adjust the prio_boost */ spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 2dc569bc7e8f..771ceffb8f8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -464,7 +464,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv) if (priv->cfg->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ /* need to perform this before any calibration */ + priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; + priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; priv->cfg->ops->hcmd->send_bt_config(priv); + priv->bt_valid = IWL6000G2B_BT_VALID_ENABLE_FLAGS; + if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) { iwlagn_send_prio_tbl(priv); iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 06e89d474d04..0c457be7bc01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -614,6 +614,20 @@ static void iwl_bg_beacon_update(struct work_struct *work) iwl_send_beacon_cmd(priv); } +static void iwl_bg_bt_runtime_config(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_runtime_config); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* dont send host command if rf-kill is on */ + if (!iwl_is_ready_rf(priv)) + return; + priv->cfg->ops->hcmd->send_bt_config(priv); +} + static void iwl_bg_bt_full_concurrency(struct work_struct *work) { struct iwl_priv *priv = @@ -3895,6 +3909,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); + INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); @@ -3938,6 +3953,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); cancel_work_sync(&priv->bt_full_concurrency); + cancel_work_sync(&priv->bt_runtime_config); del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index e742f994ff82..7369c52d42dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -4057,7 +4057,7 @@ struct iwl_coex_event_resp { /* * BT Status notification - * REPLY_BT_COEX_PROFILE_NOTIF = 0xcb + * REPLY_BT_COEX_PROFILE_NOTIF = 0xce */ enum iwl_bt_coex_profile_traffic_load { IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0, @@ -4070,8 +4070,114 @@ enum iwl_bt_coex_profile_traffic_load { */ }; +#define BT_UART_MSG_FRAME1MSGTYPE_POS (0) +#define BT_UART_MSG_FRAME1MSGTYPE_MSK \ + (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS) +#define BT_UART_MSG_FRAME1SSN_POS (3) +#define BT_UART_MSG_FRAME1SSN_MSK \ + (0x3 << BT_UART_MSG_FRAME1SSN_POS) +#define BT_UART_MSG_FRAME1UPDATEREQ_POS (5) +#define BT_UART_MSG_FRAME1UPDATEREQ_MSK \ + (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS) +#define BT_UART_MSG_FRAME1RESERVED_POS (6) +#define BT_UART_MSG_FRAME1RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME1RESERVED_POS) + +#define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0) +#define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \ + (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS) +#define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2) +#define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \ + (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS) +#define BT_UART_MSG_FRAME2CHLSEQN_POS (4) +#define BT_UART_MSG_FRAME2CHLSEQN_MSK \ + (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS) +#define BT_UART_MSG_FRAME2INBAND_POS (5) +#define BT_UART_MSG_FRAME2INBAND_MSK \ + (0x1 << BT_UART_MSG_FRAME2INBAND_POS) +#define BT_UART_MSG_FRAME2RESERVED_POS (6) +#define BT_UART_MSG_FRAME2RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME2RESERVED_POS) + +#define BT_UART_MSG_FRAME3SCOESCO_POS (0) +#define BT_UART_MSG_FRAME3SCOESCO_MSK \ + (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS) +#define BT_UART_MSG_FRAME3SNIFF_POS (1) +#define BT_UART_MSG_FRAME3SNIFF_MSK \ + (0x1 << BT_UART_MSG_FRAME3SNIFF_POS) +#define BT_UART_MSG_FRAME3A2DP_POS (2) +#define BT_UART_MSG_FRAME3A2DP_MSK \ + (0x1 << BT_UART_MSG_FRAME3A2DP_POS) +#define BT_UART_MSG_FRAME3ACL_POS (3) +#define BT_UART_MSG_FRAME3ACL_MSK \ + (0x1 << BT_UART_MSG_FRAME3ACL_POS) +#define BT_UART_MSG_FRAME3MASTER_POS (4) +#define BT_UART_MSG_FRAME3MASTER_MSK \ + (0x1 << BT_UART_MSG_FRAME3MASTER_POS) +#define BT_UART_MSG_FRAME3OBEX_POS (5) +#define BT_UART_MSG_FRAME3OBEX_MSK \ + (0x1 << BT_UART_MSG_FRAME3OBEX_POS) +#define BT_UART_MSG_FRAME3RESERVED_POS (6) +#define BT_UART_MSG_FRAME3RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME3RESERVED_POS) + +#define BT_UART_MSG_FRAME4IDLEDURATION_POS (0) +#define BT_UART_MSG_FRAME4IDLEDURATION_MSK \ + (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS) +#define BT_UART_MSG_FRAME4RESERVED_POS (6) +#define BT_UART_MSG_FRAME4RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME4RESERVED_POS) + +#define BT_UART_MSG_FRAME5TXACTIVITY_POS (0) +#define BT_UART_MSG_FRAME5TXACTIVITY_MSK \ + (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS) +#define BT_UART_MSG_FRAME5RXACTIVITY_POS (2) +#define BT_UART_MSG_FRAME5RXACTIVITY_MSK \ + (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS) +#define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4) +#define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \ + (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS) +#define BT_UART_MSG_FRAME5RESERVED_POS (6) +#define BT_UART_MSG_FRAME5RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME5RESERVED_POS) + +#define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0) +#define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \ + (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS) +#define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5) +#define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \ + (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS) +#define BT_UART_MSG_FRAME6RESERVED_POS (6) +#define BT_UART_MSG_FRAME6RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME6RESERVED_POS) + +#define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0) +#define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \ + (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS) +#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS (3) +#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK \ + (0x3 << BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS) +#define BT_UART_MSG_FRAME7CONNECTABLE_POS (5) +#define BT_UART_MSG_FRAME7CONNECTABLE_MSK \ + (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS) +#define BT_UART_MSG_FRAME7RESERVED_POS (6) +#define BT_UART_MSG_FRAME7RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME7RESERVED_POS) + + +struct iwl_bt_uart_msg { + u8 header; + u8 frame1; + u8 frame2; + u8 frame3; + u8 frame4; + u8 frame5; + u8 frame6; + u8 frame7; +} __attribute__((packed)); + struct iwl_bt_coex_profile_notif { - u8 uart_msg[8]; + struct iwl_bt_uart_msg last_bt_uart_msg; u8 bt_status; /* 0 - off, 1 - on */ u8 bt_traffic_load; /* 0 .. 3? */ u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index bb92a7f01988..e0d524d633bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1370,6 +1370,9 @@ struct iwl_priv { bool bt_sco_active; bool bt_full_concurrent; bool bt_ant_couple_ok; + __le32 kill_ack_mask; + __le32 kill_cts_mask; + __le16 bt_valid; u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; @@ -1392,6 +1395,7 @@ struct iwl_priv { struct work_struct start_internal_scan; struct work_struct tx_flush; struct work_struct bt_full_concurrency; + struct work_struct bt_runtime_config; struct tasklet_struct irq_tasklet; -- cgit v1.2.3 From 22bf59a03aacc221483e5aad1af903fc191ae958 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:11 -0700 Subject: iwlagn: add additional bt related parameters Add additional bt coex related parameters and initialize at init time. Thoese parameters will be used in later implementations. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0c457be7bc01..e8098a798240 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4014,6 +4014,17 @@ static int iwl_init_drv(struct iwl_priv *priv) iwl_init_scan_params(priv); + /* init bt coex */ + if (priv->cfg->advanced_bt_coexist) { + priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; + priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; + priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; + priv->bt_duration = BT_DURATION_LIMIT_DEF; + priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; + priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF; + } + /* Set the tx_power_user_lmt to the lowest power level * this value will get overwritten by channel max power avg * from eeprom */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 7369c52d42dd..5df22f1d57a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2379,6 +2379,22 @@ struct iwl_link_quality_cmd { #define BT_MAX_KILL_DEF (0x5) #define BT_MAX_KILL_MAX (0xFF) +#define BT_DURATION_LIMIT_DEF 625 +#define BT_DURATION_LIMIT_MAX 1250 +#define BT_DURATION_LIMIT_MIN 625 + +#define BT_ON_THRESHOLD_DEF 4 +#define BT_ON_THRESHOLD_MAX 1000 +#define BT_ON_THRESHOLD_MIN 1 + +#define BT_FRAG_THRESHOLD_DEF 0 +#define BT_FRAG_THRESHOLD_MAX 0 +#define BT_FRAG_THRESHOLD_MIN 0 + +#define BT_AGG_THRESHOLD_DEF 0 +#define BT_AGG_THRESHOLD_MAX 0 +#define BT_AGG_THRESHOLD_MIN 0 + /* * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) * diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e0d524d633bb..836fe2762464 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1366,6 +1366,7 @@ struct iwl_priv { #endif }; + /* bt coex */ u8 bt_traffic_load, notif_bt_traffic_load; bool bt_sco_active; bool bt_full_concurrent; @@ -1373,6 +1374,10 @@ struct iwl_priv { __le32 kill_ack_mask; __le32 kill_cts_mask; __le16 bt_valid; + u16 bt_on_thresh; + u16 bt_duration; + u16 dynamic_frag_thresh; + u16 dynamic_agg_thresh; u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; -- cgit v1.2.3 From f37837c962c309f1d90636626c779497b614be42 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:12 -0700 Subject: iwlagn: add bt_ch_announce module parameter Add bt_ch_announce module parameter to enable/disable BT channel announcement mode; default is "enable" Based on the bt channel announcement module parameter to configure the bt_config host command. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index e4873cc2a57a..ebf0c7ecef4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -242,9 +242,11 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { bt_cmd.flags = 0; } else { - bt_cmd.flags = IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION | - IWL6000G2B_BT_FLAG_COEX_MODE_3W << + bt_cmd.flags = IWL6000G2B_BT_FLAG_COEX_MODE_3W << IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT; + if (priv->bt_ch_announce) + bt_cmd.flags |= IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION; + IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); } if (priv->bt_full_concurrent) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e8098a798240..989e4a702602 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -88,6 +88,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("iwl4965"); static int iwlagn_ant_coupling; +static bool iwlagn_bt_ch_announce = 1; /** * iwl_commit_rxon - commit staging_rxon to hardware @@ -2606,6 +2607,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } + /* enable/disable bt channel announcement */ + priv->bt_ch_announce = iwlagn_bt_ch_announce; + #ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) @@ -4150,6 +4154,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? true : false; + /* enable/disable bt channel announcement */ + priv->bt_ch_announce = iwlagn_bt_ch_announce; + if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); @@ -4687,3 +4694,7 @@ MODULE_PARM_DESC(ucode_alternative, module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO); MODULE_PARM_DESC(antenna_coupling, "specify antenna coupling in dB (defualt: 0 dB)"); + +module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO); +MODULE_PARM_DESC(bt_ch_announce, + "Enable BT channel announcement mode (default: enable)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 836fe2762464..1adb68e92e8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1368,6 +1368,7 @@ struct iwl_priv { /* bt coex */ u8 bt_traffic_load, notif_bt_traffic_load; + bool bt_ch_announce; bool bt_sco_active; bool bt_full_concurrent; bool bt_ant_couple_ok; -- cgit v1.2.3 From da5dbb971573efda54c7c39e7e4ccd3fc7c86e49 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:13 -0700 Subject: iwlagn: set traffic load based on multiple factors Current BT traffic load should based on the following conditions: 1. BT On/Off status 2. Channel announcement enable/disable 3. Curren traffic load report from uCode Need to modify rate scale to down-grade from MIMO to SISO if detected high BT traffic load. Also need to make sure not using chain "B" with high BT traffic or if it is in "full concurrency" mode. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 29 ++++++-- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 113 +++++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 16 +++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 5 files changed, 112 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ebf0c7ecef4e..30dc1f334202 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -428,6 +428,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) container_of(work, struct iwl_priv, bt_traffic_change_work); int smps_request = -1; + IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", + priv->bt_traffic_load); + switch (priv->bt_traffic_load) { case IWL_BT_COEX_TRAFFIC_LOAD_NONE: smps_request = IEEE80211_SMPS_AUTOMATIC; @@ -447,6 +450,9 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) mutex_lock(&priv->mutex); + if (priv->cfg->ops->lib->update_chain_flags) + priv->cfg->ops->lib->update_chain_flags(priv); + if (smps_request != -1 && priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) ieee80211_request_smps(priv->vif, smps_request); @@ -549,6 +555,7 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; + u8 last_traffic_load; IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); @@ -556,16 +563,28 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); iwlagn_print_uartmsg(priv, uart_msg); + last_traffic_load = priv->notif_bt_traffic_load; priv->notif_bt_traffic_load = coex->bt_traffic_load; - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - if (coex->bt_traffic_load != priv->bt_traffic_load) { - priv->bt_traffic_load = coex->bt_traffic_load; - + if (priv->bt_status != coex->bt_status || + last_traffic_load != coex->bt_traffic_load) { + if (coex->bt_status) { + /* BT on */ + if (!priv->bt_ch_announce) + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + else + priv->bt_traffic_load = + coex->bt_traffic_load; + } else { + /* BT off */ + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_NONE; + } + priv->bt_status = coex->bt_status; queue_work(priv->workqueue, &priv->bt_traffic_change_work); } - if (priv->bt_sco_active != (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { priv->bt_sco_active = uart_msg->frame3 & diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 687b534d83d0..e78f3f0592d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -82,7 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, u32 rate_n_flags); -static void rs_stay_in_table(struct iwl_lq_sta *lq_sta); +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); #ifdef CONFIG_MAC80211_DEBUGFS @@ -900,7 +900,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, * no matching table found, let's by-pass the data collection * and continue to perform rate scale to find the rate table */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, true); goto done; } @@ -1334,15 +1334,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv, break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; break; case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && tbl->action != IWL_LEGACY_SWITCH_SISO) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + tbl->action = IWL_LEGACY_SWITCH_SISO; break; default: IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); @@ -1362,6 +1364,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) tbl->action = IWL_LEGACY_SWITCH_SISO; + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); } start_action = tbl->action; @@ -1379,7 +1382,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv, break; /* Don't change antenna if success has been great */ - if (window->success_ratio >= IWL_RS_GOOD_RATIO) + if (window->success_ratio >= IWL_RS_GOOD_RATIO && + !priv->bt_full_concurrent && + priv->bt_traffic_load == + IWL_BT_COEX_TRAFFIC_LOAD_NONE) break; /* Set up search table to try other antenna */ @@ -1503,14 +1509,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) tbl->action = IWL_SISO_SWITCH_ANTENNA1; break; case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action >= IWL_SISO_SWITCH_ANTENNA2 && - tbl->action != IWL_SISO_SWITCH_GI) + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) tbl->action = IWL_SISO_SWITCH_ANTENNA1; break; default: @@ -1525,9 +1532,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, } /* configure as 1x1 if bt full concurrency */ - if (priv->bt_full_concurrent && - tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + if (priv->bt_full_concurrent) { + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + } start_action = tbl->action; for (;;) { @@ -1536,14 +1545,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, case IWL_SISO_SWITCH_ANTENNA1: case IWL_SISO_SWITCH_ANTENNA2: IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); - if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && - tx_chains_num <= 1) || + tx_chains_num <= 1) || (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && - tx_chains_num <= 2)) + tx_chains_num <= 2)) break; - if (window->success_ratio >= IWL_RS_GOOD_RATIO) + if (window->success_ratio >= IWL_RS_GOOD_RATIO && + !priv->bt_full_concurrent && + priv->bt_traffic_load == + IWL_BT_COEX_TRAFFIC_LOAD_NONE) break; memcpy(search_tbl, tbl, sz); @@ -1670,13 +1681,13 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action == IWL_MIMO2_SWITCH_MIMO3_ABC) - tbl->action = IWL_SISO_SWITCH_ANTENNA1; + if (tbl->action != IWL_MIMO2_SWITCH_SISO_A) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ - if (tbl->action == IWL_MIMO2_SWITCH_ANTENNA2) - tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; - else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) + if (tbl->action == IWL_MIMO2_SWITCH_SISO_B || + tbl->action == IWL_MIMO2_SWITCH_SISO_C) tbl->action = IWL_MIMO2_SWITCH_SISO_A; break; default: @@ -1840,16 +1851,14 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: /* avoid antenna B and MIMO */ - if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB || - tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC || - tbl->action == IWL_MIMO3_SWITCH_MIMO2_BC) + if (tbl->action != IWL_MIMO3_SWITCH_SISO_A) tbl->action = IWL_MIMO3_SWITCH_SISO_A; + break; case IWL_BT_COEX_TRAFFIC_LOAD_LOW: /* avoid antenna B unless MIMO */ - if (tbl->action == IWL_MIMO3_SWITCH_SISO_B) + if (tbl->action == IWL_MIMO3_SWITCH_SISO_B || + tbl->action == IWL_MIMO3_SWITCH_SISO_C) tbl->action = IWL_MIMO3_SWITCH_SISO_A; - else if (tbl->action == IWL_MIMO3_SWITCH_ANTENNA2) - tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; break; default: IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); @@ -1996,7 +2005,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, * 2) # times calling this function * 3) elapsed time in this mode (not used, for now) */ -static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) { struct iwl_scale_tbl_info *tbl; int i; @@ -2027,7 +2036,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) * allow a new search. Also (below) reset all bitmaps and * stats in active history. */ - if ((lq_sta->total_failed > lq_sta->max_failure_limit) || + if (force_search || + (lq_sta->total_failed > lq_sta->max_failure_limit) || (lq_sta->total_success > lq_sta->max_success_limit) || ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) && (flush_interval_passed))) { @@ -2243,7 +2253,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* Should we stay with this modulation mode, * or search for a new one? */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, false); goto out; } @@ -2392,16 +2402,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) scale_action = -1; - if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { - lq_sta->last_bt_traffic = priv->bt_traffic_load; - /* - * don't set scale_action, don't want to scale up if - * the rate scale doesn't otherwise think that is a - * good idea. - */ - } else if (lq_sta->last_bt_traffic < priv->bt_traffic_load) { - lq_sta->last_bt_traffic = priv->bt_traffic_load; - scale_action = -1; + if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && + (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) { + if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { + /* + * don't set scale_action, don't want to scale up if + * the rate scale doesn't otherwise think that is a + * good idea. + */ + } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) { + scale_action = -1; + } + } + lq_sta->last_bt_traffic = priv->bt_traffic_load; + + if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && + (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) { + /* search for a new modulation */ + rs_stay_in_table(lq_sta, true); + goto lq_update; } switch (scale_action) { @@ -2440,7 +2459,7 @@ lq_update: if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { /* Should we stay with this modulation mode, * or search for a new one? */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, false); } /* * Search for new modulation mode if we're: @@ -2786,6 +2805,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); + if (priv && priv->bt_full_concurrent) { + /* 1x1 only */ + tbl_type.ant_type = + first_antenna(priv->hw_params.valid_tx_ant); + } + /* How many times should we repeat the initial rate? */ if (is_legacy(tbl_type.lq_type)) { ant_toggle_cnt = 1; @@ -2800,8 +2825,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, /* Fill 1st table entry (index 0) */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); - if (num_of_ant(tbl_type.ant_type) == 1 || - (priv && priv->bt_full_concurrent)) { + if (num_of_ant(tbl_type.ant_type) == 1) { lq_cmd->general_params.single_stream_ant_msk = tbl_type.ant_type; } else if (num_of_ant(tbl_type.ant_type) == 2) { @@ -2811,7 +2835,6 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, index++; repeat_rate--; - if (priv) { if (priv->bt_full_concurrent) valid_tx_ant = ANT_A; @@ -2832,7 +2855,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_toggle_antenna(valid_tx_ant, &new_rate, &tbl_type)) ant_toggle_cnt = 1; -} + } /* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs(lq_sta, &new_rate, index); @@ -2847,6 +2870,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); + if (priv && priv->bt_full_concurrent) { + /* 1x1 only */ + tbl_type.ant_type = + first_antenna(priv->hw_params.valid_tx_ant); + } + /* Indicate to uCode which entries might be MIMO. * If initial rate was MIMO, this will finally end up * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 989e4a702602..4410f820c2f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2823,6 +2823,7 @@ static void __iwl_down(struct iwl_priv *priv) iwl_clear_driver_stations(priv); /* reset BT coex data */ + priv->bt_status = 0; priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; priv->bt_sco_active = false; priv->bt_full_concurrent = false; @@ -3133,6 +3134,7 @@ static void iwl_bg_restart(struct work_struct *data) bool bt_sco, bt_full_concurrent; u8 bt_ci_compliance; u8 bt_load; + u8 bt_status; mutex_lock(&priv->mutex); priv->vif = NULL; @@ -3151,6 +3153,7 @@ static void iwl_bg_restart(struct work_struct *data) bt_full_concurrent = priv->bt_full_concurrent; bt_ci_compliance = priv->bt_ci_compliance; bt_load = priv->bt_traffic_load; + bt_status = priv->bt_status; __iwl_down(priv); @@ -3158,6 +3161,7 @@ static void iwl_bg_restart(struct work_struct *data) priv->bt_full_concurrent = bt_full_concurrent; priv->bt_ci_compliance = bt_ci_compliance; priv->bt_traffic_load = bt_load; + priv->bt_status = bt_status; mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 34cba38f1d0c..c43124c997cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -780,8 +780,12 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); */ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ + if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ return IWL_NUM_RX_CHAINS_SINGLE; } /* # of Rx chains to use when expecting MIMO. */ @@ -845,8 +849,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) else active_chains = priv->hw_params.valid_rx_ant; - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ + if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ active_chains = first_antenna(active_chains); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1adb68e92e8d..8d5201ac80f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1367,6 +1367,7 @@ struct iwl_priv { }; /* bt coex */ + u8 bt_status; u8 bt_traffic_load, notif_bt_traffic_load; bool bt_ch_announce; bool bt_sco_active; -- cgit v1.2.3 From b6e116e8bf7d749b0743c167bd47930c22c77a82 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:14 -0700 Subject: iwlagn: generic bt coex functions Move bt coex functions to iwl-agn-lib.c, so those functions can be shared by multiple wifi/bt combo devices Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 391 +-------------------------- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 8 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 370 +++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 9 + drivers/net/wireless/iwlwifi/iwl-commands.h | 74 ++--- 7 files changed, 441 insertions(+), 425 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 30dc1f334202..fc9344b873ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -122,165 +122,6 @@ static void iwl6000_nic_config(struct iwl_priv *priv) priv->cfg->ops->lib->temp_ops.set_calib_version(priv); } -/* - * Macros to access the lookup table. - * - * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req, - * wifi_prio, wifi_txrx and wifi_sh_ant_req. - * - * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH - * - * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits - * one after another in 32-bit registers, and "registers" 0 through 7 contain - * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order). - * - * These macros encode that format. - */ -#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \ - wifi_txrx, wifi_sh_ant_req) \ - (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \ - (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6)) - -#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \ - lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f))) -#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx,\ - bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) -#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \ - bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) -#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \ - bt_rf_act, wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) - -#define LUT_WLAN_KILL_OP(lut, op, val) \ - lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e))) -#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) -#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) -#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) - -#define LUT_ANT_SWITCH_OP(lut, op, val) \ - lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1))) -#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) -#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) -#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ - wifi_prio, wifi_txrx, wifi_sh_ant_req) \ - LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ - wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) - -static const __le32 iwl6000g2b_def_3w_lookup[12] = { - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaeaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xcc00ff28), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xcc00aaaa), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xc0004000), - cpu_to_le32(0x00004000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xf0004000), -}; - -static const __le32 iwl6000g2b_concurrent_lookup[12] = { - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0x00000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x00000000), -}; - -static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) -{ - struct iwl6000g2b_bt_cmd bt_cmd = { - .max_kill = IWL6000G2B_BT_MAX_KILL_DEFAULT, - .bt3_timer_t7_value = IWL6000G2B_BT3_T7_DEFAULT, - .bt3_prio_sample_time = IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT, - .bt3_timer_t2_value = IWL6000G2B_BT3_T2_DEFAULT, - }; - - BUILD_BUG_ON(sizeof(iwl6000g2b_def_3w_lookup) != - sizeof(bt_cmd.bt3_lookup_table)); - - bt_cmd.prio_boost = priv->cfg->bt_prio_boost; - bt_cmd.kill_ack_mask = priv->kill_ack_mask; - bt_cmd.kill_cts_mask = priv->kill_cts_mask; - bt_cmd.valid = priv->bt_valid; - - /* - * Configure BT coex mode to "no coexistence" when the - * user disabled BT coexistence, we have no interface - * user disabled BT coexistence, or the interface is in - * IBSS mode (no proper uCode support for coex then). - */ - if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { - bt_cmd.flags = 0; - } else { - bt_cmd.flags = IWL6000G2B_BT_FLAG_COEX_MODE_3W << - IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT; - if (priv->bt_ch_announce) - bt_cmd.flags |= IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION; - IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); - } - - if (priv->bt_full_concurrent) - memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_concurrent_lookup, - sizeof(iwl6000g2b_concurrent_lookup)); - else - memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, - sizeof(iwl6000g2b_def_3w_lookup)); - - IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", - bt_cmd.flags ? "active" : "disabled", - priv->bt_full_concurrent ? - "full concurrency" : "3-wire"); - - if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) - IWL_ERR(priv, "failed to send BT Coex Config\n"); - - /* - * When we are doing a restart, need to also reconfigure BT - * SCO to the device. If not doing a restart, bt_sco_active - * will always be false, so there's no need to have an extra - * variable to check for it. - */ - if (priv->bt_sco_active) { - struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; - - if (priv->bt_sco_active) - sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; - if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, - sizeof(sco_cmd), &sco_cmd)) - IWL_ERR(priv, "failed to send BT SCO command\n"); - } -} - static struct iwl_sensitivity_ranges iwl6000_sensitivity = { .min_nrg_cck = 97, .max_nrg_cck = 0, /* not used, set to 0 */ @@ -422,210 +263,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return iwl_send_cmd_sync(priv, &hcmd); } -static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) -{ - struct iwl_priv *priv = - container_of(work, struct iwl_priv, bt_traffic_change_work); - int smps_request = -1; - - IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", - priv->bt_traffic_load); - - switch (priv->bt_traffic_load) { - case IWL_BT_COEX_TRAFFIC_LOAD_NONE: - smps_request = IEEE80211_SMPS_AUTOMATIC; - break; - case IWL_BT_COEX_TRAFFIC_LOAD_LOW: - smps_request = IEEE80211_SMPS_DYNAMIC; - break; - case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: - case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: - smps_request = IEEE80211_SMPS_STATIC; - break; - default: - IWL_ERR(priv, "Invalid BT traffic load: %d\n", - priv->bt_traffic_load); - break; - } - - mutex_lock(&priv->mutex); - - if (priv->cfg->ops->lib->update_chain_flags) - priv->cfg->ops->lib->update_chain_flags(priv); - - if (smps_request != -1 && - priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) - ieee80211_request_smps(priv->vif, smps_request); - - mutex_unlock(&priv->mutex); -} - -static void iwlagn_print_uartmsg(struct iwl_priv *priv, - struct iwl_bt_uart_msg *uart_msg) -{ - IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " - "Update Req = 0x%X", - (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> - BT_UART_MSG_FRAME1MSGTYPE_POS, - (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >> - BT_UART_MSG_FRAME1SSN_POS, - (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> - BT_UART_MSG_FRAME1UPDATEREQ_POS); - - IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " - "Chl_SeqN = 0x%X, In band = 0x%X", - (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> - BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, - (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >> - BT_UART_MSG_FRAME2TRAFFICLOAD_POS, - (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >> - BT_UART_MSG_FRAME2CHLSEQN_POS, - (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> - BT_UART_MSG_FRAME2INBAND_POS); - - IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " - "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", - (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3SCOESCO_POS, - (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3SNIFF_POS, - (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3A2DP_POS, - (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3ACL_POS, - (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3MASTER_POS, - (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> - BT_UART_MSG_FRAME3OBEX_POS); - - IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", - (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> - BT_UART_MSG_FRAME4IDLEDURATION_POS); - - IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " - "eSCO Retransmissions = 0x%X", - (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> - BT_UART_MSG_FRAME5TXACTIVITY_POS, - (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >> - BT_UART_MSG_FRAME5RXACTIVITY_POS, - (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> - BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); - - IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", - (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> - BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, - (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> - BT_UART_MSG_FRAME6DISCOVERABLE_POS); - - IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = " - "0x%X, Connectable = 0x%X", - (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> - BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, - (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >> - BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS, - (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >> - BT_UART_MSG_FRAME7CONNECTABLE_POS); -} - -static void iwl6000g2b_set_kill_ack_msk(struct iwl_priv *priv, - struct iwl_bt_uart_msg *uart_msg) -{ - u8 kill_ack_msk; - __le32 bt_kill_ack_msg[2] = { - cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; - - kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | - BT_UART_MSG_FRAME3SNIFF_MSK | - BT_UART_MSG_FRAME3SCOESCO_MSK) & - uart_msg->frame3) == 0) ? 1 : 0; - if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) { - priv->bt_valid |= IWL6000G2B_BT_VALID_KILL_ACK_MASK; - priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk]; - /* schedule to send runtime bt_config */ - queue_work(priv->workqueue, &priv->bt_runtime_config); - } - -} - -static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - unsigned long flags; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; - struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; - struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; - u8 last_traffic_load; - - IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); - IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); - IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); - IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); - iwlagn_print_uartmsg(priv, uart_msg); - - last_traffic_load = priv->notif_bt_traffic_load; - priv->notif_bt_traffic_load = coex->bt_traffic_load; - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - if (priv->bt_status != coex->bt_status || - last_traffic_load != coex->bt_traffic_load) { - if (coex->bt_status) { - /* BT on */ - if (!priv->bt_ch_announce) - priv->bt_traffic_load = - IWL_BT_COEX_TRAFFIC_LOAD_HIGH; - else - priv->bt_traffic_load = - coex->bt_traffic_load; - } else { - /* BT off */ - priv->bt_traffic_load = - IWL_BT_COEX_TRAFFIC_LOAD_NONE; - } - priv->bt_status = coex->bt_status; - queue_work(priv->workqueue, - &priv->bt_traffic_change_work); - } - if (priv->bt_sco_active != - (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { - priv->bt_sco_active = uart_msg->frame3 & - BT_UART_MSG_FRAME3SCOESCO_MSK; - if (priv->bt_sco_active) - sco_cmd.flags |= IWL6000G2B_BT_SCO_ACTIVE; - iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, - sizeof(sco_cmd), &sco_cmd, NULL); - } - } - - iwl6000g2b_set_kill_ack_msk(priv, uart_msg); - - /* FIXME: based on notification, adjust the prio_boost */ - - spin_lock_irqsave(&priv->lock, flags); - priv->bt_ci_compliance = coex->bt_ci_compliance; - spin_unlock_irqrestore(&priv->lock, flags); -} - -void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv) -{ - iwlagn_rx_handler_setup(priv); - priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] = - iwl6000g2b_bt_coex_profile_notif; -} - -static void iwl6000g2b_bt_setup_deferred_work(struct iwl_priv *priv) -{ - iwlagn_setup_deferred_work(priv); - - INIT_WORK(&priv->bt_traffic_change_work, - iwl6000g2b_bt_traffic_change_work); - -} - -static void iwl6000g2b_bt_cancel_deferred_work(struct iwl_priv *priv) -{ - cancel_work_sync(&priv->bt_traffic_change_work); -} - static struct iwl_lib_ops iwl6000_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, @@ -710,9 +347,9 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, - .rx_handler_setup = iwl6000g2b_rx_handler_setup, - .setup_deferred_work = iwl6000g2b_bt_setup_deferred_work, - .cancel_deferred_work = iwl6000g2b_bt_cancel_deferred_work, + .rx_handler_setup = iwlagn_bt_rx_handler_setup, + .setup_deferred_work = iwlagn_bt_setup_deferred_work, + .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, @@ -782,17 +419,9 @@ static const struct iwl_ops iwl6000_ops = { .led = &iwlagn_led_ops, }; -static struct iwl_hcmd_ops iwl6000g2b_hcmd = { - .rxon_assoc = iwlagn_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, - .set_tx_ant = iwlagn_send_tx_ant_config, - .send_bt_config = iwl6000g2b_send_bt_config, -}; - static const struct iwl_ops iwl6000g2b_ops = { .lib = &iwl6000g2b_lib, - .hcmd = &iwl6000g2b_hcmd, + .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, }; @@ -945,7 +574,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -986,7 +615,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -1029,7 +658,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -1070,7 +699,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -1113,7 +742,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -1154,7 +783,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, .advanced_bt_coexist = true, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWL6000G2B_BT_PRIO_BOOST_DEFAULT, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 84939763d178..84fe06adcef4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -277,6 +277,14 @@ struct iwl_hcmd_ops iwlagn_hcmd = { .send_bt_config = iwl_send_bt_config, }; +struct iwl_hcmd_ops iwlagn_bt_hcmd = { + .rxon_assoc = iwlagn_send_rxon_assoc, + .commit_rxon = iwl_commit_rxon, + .set_rxon_chain = iwl_set_rxon_chain, + .set_tx_ant = iwlagn_send_tx_ant_config, + .send_bt_config = iwlagn_send_advance_bt_config, +}; + struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { .get_hcmd_size = iwlagn_get_hcmd_size, .build_addsta_hcmd = iwlagn_build_addsta_hcmd, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ea242401b5a3..a9e69a6213f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1542,3 +1542,373 @@ done: ieee80211_wake_queues(priv->hw); mutex_unlock(&priv->mutex); } + +/* + * BT coex + */ +/* + * Macros to access the lookup table. + * + * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req, +* wifi_prio, wifi_txrx and wifi_sh_ant_req. + * + * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH + * + * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits + * one after another in 32-bit registers, and "registers" 0 through 7 contain + * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order). + * + * These macros encode that format. + */ +#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \ + wifi_txrx, wifi_sh_ant_req) \ + (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \ + (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6)) + +#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \ + lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f))) +#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)))) +#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)) +#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)) + +#define LUT_WLAN_KILL_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e))) +#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) +#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +#define LUT_ANT_SWITCH_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1))) +#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)))) +#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +static const __le32 iwlagn_def_3w_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00004000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0004000), +}; + +static const __le32 iwlagn_concurrent_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + +void iwlagn_send_advance_bt_config(struct iwl_priv *priv) +{ + struct iwlagn_bt_cmd bt_cmd = { + .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT, + .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT, + .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, + .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, + }; + + BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != + sizeof(bt_cmd.bt3_lookup_table)); + + bt_cmd.prio_boost = priv->cfg->bt_prio_boost; + bt_cmd.kill_ack_mask = priv->kill_ack_mask; + bt_cmd.kill_cts_mask = priv->kill_cts_mask; + bt_cmd.valid = priv->bt_valid; + + /* + * Configure BT coex mode to "no coexistence" when the + * user disabled BT coexistence, we have no interface + * (might be in monitor mode), or the interface is in + * IBSS mode (no proper uCode support for coex then). + */ + if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { + bt_cmd.flags = 0; + } else { + bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << + IWLAGN_BT_FLAG_COEX_MODE_SHIFT; + if (priv->bt_ch_announce) + bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; + IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); + } + if (priv->bt_full_concurrent) + memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup, + sizeof(iwlagn_concurrent_lookup)); + else + memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup, + sizeof(iwlagn_def_3w_lookup)); + + IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", + bt_cmd.flags ? "active" : "disabled", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); + + if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) + IWL_ERR(priv, "failed to send BT Coex Config\n"); + + /* + * When we are doing a restart, need to also reconfigure BT + * SCO to the device. If not doing a restart, bt_sco_active + * will always be false, so there's no need to have an extra + * variable to check for it. + */ + if (priv->bt_sco_active) { + struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; + + if (priv->bt_sco_active) + sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd)) + IWL_ERR(priv, "failed to send BT SCO command\n"); + } +} + +static void iwlagn_bt_traffic_change_work(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_traffic_change_work); + int smps_request = -1; + + IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", + priv->bt_traffic_load); + + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + smps_request = IEEE80211_SMPS_AUTOMATIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + smps_request = IEEE80211_SMPS_DYNAMIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + smps_request = IEEE80211_SMPS_STATIC; + break; + default: + IWL_ERR(priv, "Invalid BT traffic load: %d\n", + priv->bt_traffic_load); + break; + } + + mutex_lock(&priv->mutex); + + if (priv->cfg->ops->lib->update_chain_flags) + priv->cfg->ops->lib->update_chain_flags(priv); + + if (smps_request != -1 && + priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) + ieee80211_request_smps(priv->vif, smps_request); + + mutex_unlock(&priv->mutex); +} + +static void iwlagn_print_uartmsg(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " + "Update Req = 0x%X", + (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1MSGTYPE_POS, + (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1SSN_POS, + (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1UPDATEREQ_POS); + + IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " + "Chl_SeqN = 0x%X, In band = 0x%X", + (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, + (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2TRAFFICLOAD_POS, + (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2CHLSEQN_POS, + (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2INBAND_POS); + + IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " + "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", + (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SCOESCO_POS, + (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SNIFF_POS, + (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3A2DP_POS, + (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3ACL_POS, + (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3MASTER_POS, + (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3OBEX_POS); + + IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", + (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> + BT_UART_MSG_FRAME4IDLEDURATION_POS); + + IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " + "eSCO Retransmissions = 0x%X", + (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5TXACTIVITY_POS, + (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5RXACTIVITY_POS, + (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", + (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, + (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6DISCOVERABLE_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = " + "0x%X, Connectable = 0x%X", + (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, + (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS, + (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7CONNECTABLE_POS); +} + +static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + u8 kill_ack_msk; + __le32 bt_kill_ack_msg[2] = { + cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; + + kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | + BT_UART_MSG_FRAME3SNIFF_MSK | + BT_UART_MSG_FRAME3SCOESCO_MSK) & + uart_msg->frame3) == 0) ? 1 : 0; + if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) { + priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK; + priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk]; + /* schedule to send runtime bt_config */ + queue_work(priv->workqueue, &priv->bt_runtime_config); + } + +} + +void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + unsigned long flags; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; + struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; + struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; + u8 last_traffic_load; + + IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); + IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); + IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); + IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", + coex->bt_ci_compliance); + iwlagn_print_uartmsg(priv, uart_msg); + + last_traffic_load = priv->notif_bt_traffic_load; + priv->notif_bt_traffic_load = coex->bt_traffic_load; + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { + if (priv->bt_status != coex->bt_status || + last_traffic_load != coex->bt_traffic_load) { + if (coex->bt_status) { + /* BT on */ + if (!priv->bt_ch_announce) + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + else + priv->bt_traffic_load = + coex->bt_traffic_load; + } else { + /* BT off */ + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_NONE; + } + priv->bt_status = coex->bt_status; + queue_work(priv->workqueue, + &priv->bt_traffic_change_work); + } + if (priv->bt_sco_active != + (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { + priv->bt_sco_active = uart_msg->frame3 & + BT_UART_MSG_FRAME3SCOESCO_MSK; + if (priv->bt_sco_active) + sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; + iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd, NULL); + } + } + + iwlagn_set_kill_ack_msk(priv, uart_msg); + + /* FIXME: based on notification, adjust the prio_boost */ + + spin_lock_irqsave(&priv->lock, flags); + priv->bt_ci_compliance = coex->bt_ci_compliance; + spin_unlock_irqrestore(&priv->lock, flags); +} + +void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv) +{ + iwlagn_rx_handler_setup(priv); + priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] = + iwlagn_bt_coex_profile_notif; +} + +void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv) +{ + iwlagn_setup_deferred_work(priv); + + INIT_WORK(&priv->bt_traffic_change_work, + iwlagn_bt_traffic_change_work); +} + +void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->bt_traffic_change_work); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 771ceffb8f8b..f2499e1f2047 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -464,11 +464,11 @@ int iwlagn_alive_notify(struct iwl_priv *priv) if (priv->cfg->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ /* need to perform this before any calibration */ - priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; - priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; - priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; + priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; priv->cfg->ops->hcmd->send_bt_config(priv); - priv->bt_valid = IWL6000G2B_BT_VALID_ENABLE_FLAGS; + priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) { iwlagn_send_prio_tbl(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4410f820c2f3..5e0d0d527bf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4024,9 +4024,9 @@ static int iwl_init_drv(struct iwl_priv *priv) /* init bt coex */ if (priv->cfg->advanced_bt_coexist) { - priv->kill_ack_mask = IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT; - priv->kill_cts_mask = IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT; - priv->bt_valid = IWL6000G2B_BT_ALL_VALID_MSK; + priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; priv->bt_duration = BT_DURATION_LIMIT_DEF; priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cc6464dc72e5..1a7f70f293a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -95,6 +95,7 @@ extern struct iwl_cfg iwl1000_bg_cfg; extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; +extern struct iwl_hcmd_ops iwlagn_bt_hcmd; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; int iwl_reset_ict(struct iwl_priv *priv); @@ -226,4 +227,12 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, int iwlagn_send_rxon_assoc(struct iwl_priv *priv); int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); +/* bt coex */ +void iwlagn_send_advance_bt_config(struct iwl_priv *priv); +void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); +void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); +void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 5df22f1d57a5..8ed2412862d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2411,52 +2411,52 @@ struct iwl_bt_cmd { __le32 kill_cts_mask; } __packed; -#define IWL6000G2B_BT_FLAG_CHANNEL_INHIBITION BIT(0) +#define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0) -#define IWL6000G2B_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) -#define IWL6000G2B_BT_FLAG_COEX_MODE_SHIFT 3 -#define IWL6000G2B_BT_FLAG_COEX_MODE_DISABLED 0 -#define IWL6000G2B_BT_FLAG_COEX_MODE_LEGACY_2W 1 -#define IWL6000G2B_BT_FLAG_COEX_MODE_3W 2 -#define IWL6000G2B_BT_FLAG_COEX_MODE_4W 3 +#define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) +#define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3 +#define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0 +#define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1 +#define IWLAGN_BT_FLAG_COEX_MODE_3W 2 +#define IWLAGN_BT_FLAG_COEX_MODE_4W 3 -#define IWL6000G2B_BT_FLAG_UCODE_DEFAULT BIT(6) -#define IWL6000G2B_BT_FLAG_NOCOEX_NOTIF BIT(7) +#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) +#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7) -#define IWL6000G2B_BT_PRIO_BOOST_MAX 0xFF -#define IWL6000G2B_BT_PRIO_BOOST_MIN 0x00 -#define IWL6000G2B_BT_PRIO_BOOST_DEFAULT 0xF0 +#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF +#define IWLAGN_BT_PRIO_BOOST_MIN 0x00 +#define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 -#define IWL6000G2B_BT_MAX_KILL_DEFAULT 5 +#define IWLAGN_BT_MAX_KILL_DEFAULT 5 -#define IWL6000G2B_BT3_T7_DEFAULT 1 +#define IWLAGN_BT3_T7_DEFAULT 1 -#define IWL6000G2B_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) -#define IWL6000G2B_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) -#define IWL6000G2B_BT3_PRIO_SAMPLE_DEFAULT 2 +#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 -#define IWL6000G2B_BT3_T2_DEFAULT 0xc +#define IWLAGN_BT3_T2_DEFAULT 0xc -#define IWL6000G2B_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) -#define IWL6000G2B_BT_VALID_BOOST cpu_to_le16(BIT(1)) -#define IWL6000G2B_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) -#define IWL6000G2B_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) -#define IWL6000G2B_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) -#define IWL6000G2B_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) -#define IWL6000G2B_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) -#define IWL6000G2B_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) +#define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) +#define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1)) +#define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) +#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) +#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) +#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) +#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) +#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) -#define IWL6000G2B_BT_ALL_VALID_MSK (IWL6000G2B_BT_VALID_ENABLE_FLAGS | \ - IWL6000G2B_BT_VALID_BOOST | \ - IWL6000G2B_BT_VALID_MAX_KILL | \ - IWL6000G2B_BT_VALID_3W_TIMERS | \ - IWL6000G2B_BT_VALID_KILL_ACK_MASK | \ - IWL6000G2B_BT_VALID_KILL_CTS_MASK | \ - IWL6000G2B_BT_VALID_BT4_TIMES | \ - IWL6000G2B_BT_VALID_3W_LUT) +#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \ + IWLAGN_BT_VALID_BOOST | \ + IWLAGN_BT_VALID_MAX_KILL | \ + IWLAGN_BT_VALID_3W_TIMERS | \ + IWLAGN_BT_VALID_KILL_ACK_MASK | \ + IWLAGN_BT_VALID_KILL_CTS_MASK | \ + IWLAGN_BT_VALID_BT4_TIMES | \ + IWLAGN_BT_VALID_3W_LUT) -struct iwl6000g2b_bt_cmd { +struct iwlagn_bt_cmd { u8 flags; u8 ledtime; /* unused */ u8 max_kill; @@ -2473,9 +2473,9 @@ struct iwl6000g2b_bt_cmd { u8 reserved[3]; }; -#define IWL6000G2B_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) +#define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) -struct iwl6000g2b_bt_sco_cmd { +struct iwlagn_bt_sco_cmd { __le32 flags; }; -- cgit v1.2.3 From f78e545449bb07a28b419d888c4c558b13d9e5e1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:15 -0700 Subject: iwlagn: update bt status upon scan complete Update bt status upon receive scan complete notification Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 8ed2412862d7..9b535832f117 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3013,7 +3013,7 @@ struct iwl_scanresults_notification { struct iwl_scancomplete_notification { u8 scanned_channels; u8 status; - u8 reserved; + u8 bt_status; /* BT On/Off status */ u8 last_channel; __le32 tsf_low; __le32 tsf_high; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8d7fa59364fe..33aa7a5eea8a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -236,6 +236,26 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, clear_bit(STATUS_SCANNING, &priv->status); + if (priv->iw_mode != NL80211_IFTYPE_ADHOC && + priv->cfg->advanced_bt_coexist && priv->bt_status != + scan_notif->bt_status) { + if (scan_notif->bt_status) { + /* BT on */ + if (!priv->bt_ch_announce) + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + /* + * otherwise, no traffic load information provided + * no changes made + */ + } else { + /* BT off */ + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_NONE; + } + priv->bt_status = scan_notif->bt_status; + queue_work(priv->workqueue, &priv->bt_traffic_change_work); + } queue_work(priv->workqueue, &priv->scan_completed); } -- cgit v1.2.3 From befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 07:57:16 -0700 Subject: iwlwifi: add bt traffic load debugfs file Add the debugfs file to show current bluetooth traffic load Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index aae9eb552350..ef787905f51c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1555,6 +1555,48 @@ static ssize_t iwl_dbgfs_monitor_period_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char buf[200]; + const size_t bufsz = sizeof(buf); + ssize_t ret; + + pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", + priv->bt_full_concurrent ? "full concurrency" : "3-wire"); + pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " + "last traffic notif: %d\n", + priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load); + pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " + "sco_active: %d, kill_ack_mask: %x, " + "kill_cts_mask: %x\n", + priv->bt_ch_announce, priv->bt_sco_active, + priv->kill_ack_mask, priv->kill_cts_mask); + + pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + pos += scnprintf(buf + pos, bufsz - pos, "High\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + pos += scnprintf(buf + pos, bufsz - pos, "Low\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + default: + pos += scnprintf(buf + pos, bufsz - pos, "None\n"); + break; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + return ret; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1579,6 +1621,7 @@ DEBUGFS_READ_FILE_OPS(rxon_filter_flags); DEBUGFS_WRITE_FILE_OPS(txfifo_flush); DEBUGFS_READ_FILE_OPS(ucode_bt_stats); DEBUGFS_WRITE_FILE_OPS(monitor_period); +DEBUGFS_READ_FILE_OPS(bt_traffic); /* * Create the debugfs files and directories @@ -1651,6 +1694,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); + if (priv->cfg->advanced_bt_coexist) + DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); if (priv->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); -- cgit v1.2.3 From 18c121d7558a550e8e48956fbd389759a850ab53 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 07:57:17 -0700 Subject: iwlwifi: disable aggregation queue if stopped early When aggregation is stopped again for some reason before the queue we selected has drained, we will currently leak the TX queue and keep it enabled for aggregation. Normally this doesn't happen, so the problem is rarely seen. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index e2497e7ba926..a51a7cfa5a14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1036,7 +1036,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { - int tx_fifo_id, txq_id, sta_id, ssn = -1; + int tx_fifo_id, txq_id, sta_id, ssn; struct iwl_tid_data *tid_data; int write_ptr, read_ptr; unsigned long flags; @@ -1054,21 +1054,26 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, spin_lock_irqsave(&priv->sta_lock, flags); - if (priv->stations[sta_id].tid[tid].agg.state == - IWL_EMPTYING_HW_QUEUE_ADDBA) { - IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } - - if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) - IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); - tid_data = &priv->stations[sta_id].tid[tid]; ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; txq_id = tid_data->agg.txq_id; + + switch (priv->stations[sta_id].tid[tid].agg.state) { + case IWL_EMPTYING_HW_QUEUE_ADDBA: + /* + * This can happen if the peer stops aggregation + * again before we've had a chance to drain the + * queue we selected previously, i.e. before the + * session was really started completely. + */ + IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); + goto turn_off; + case IWL_AGG_ON: + break; + default: + IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); + } + write_ptr = priv->txq[txq_id].q.write_ptr; read_ptr = priv->txq[txq_id].q.read_ptr; @@ -1082,6 +1087,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, } IWL_DEBUG_HT(priv, "HW queue is empty\n"); + turn_off: priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; /* do not restore/save irqs */ -- cgit v1.2.3 From 933314582ee5db00123683cf4c4d713ec9add306 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:53:39 +0200 Subject: rt2x00: Simplify arguments to rt2x00 driver callback functions write_tx_desc shouldn't pass a rt2x00dev and skb pointer, instead it should use the same format as other TX frame callback functions, which is passing the data_entry pointer which contains all the information which is needed to work on a TX frame. Most callers of the kick_tx_queue and kill_tx_queue already have the data_queue pointer, so rather then sending the QID with the given function, when the driver requests a new pointer to the data_queue, it is more efficient to just send the data_queue pointer directly. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 25 +++++++++---------- drivers/net/wireless/rt2x00/rt2500pci.c | 25 +++++++++---------- drivers/net/wireless/rt2x00/rt2500usb.c | 9 +++---- drivers/net/wireless/rt2x00/rt2800pci.c | 41 +++++++++++++------------------ drivers/net/wireless/rt2x00/rt2800usb.c | 9 +++---- drivers/net/wireless/rt2x00/rt2x00.h | 9 +++---- drivers/net/wireless/rt2x00/rt2x00queue.c | 11 ++++----- drivers/net/wireless/rt2x00/rt2x00usb.c | 14 ++++------- drivers/net/wireless/rt2x00/rt2x00usb.h | 12 +++------ drivers/net/wireless/rt2x00/rt61pci.c | 39 ++++++++++++++--------------- drivers/net/wireless/rt2x00/rt73usb.c | 11 ++++----- 11 files changed, 90 insertions(+), 115 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5063e01410e5..b86b6132a69c 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1007,12 +1007,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2400pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1096,7 +1095,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2400pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1112,24 +1111,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt2400pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } -static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2400pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, CSR14, 0); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c2a555d5376b..21f45810fd1e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1161,12 +1161,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2500pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1249,7 +1248,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2500pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1265,24 +1264,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt2500pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } -static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2500pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, CSR14, 0); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 97cf72f8bc12..8722464944f5 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1041,12 +1041,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2500usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txd = (__le32 *) entry->skb->data; u32 word; /* @@ -1129,7 +1128,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2500usb_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4390f2b74b2e..af1c6914d7b4 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -571,12 +571,11 @@ static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) return (__le32 *) entry->skb->data; } -static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2800pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -596,7 +595,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len); + rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W1_BURST, @@ -627,41 +626,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * TX data initialization */ -static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue_idx) +static void rt2800pci_kick_tx_queue(struct data_queue *queue) { - struct data_queue *queue; - unsigned int idx, qidx = 0; - - if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) - return; - - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); - idx = queue->index[Q_INDEX]; + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + unsigned int idx = queue->index[Q_INDEX]; + unsigned int qidx = 0; - if (queue_idx == QID_MGMT) + if (queue->qid == QID_MGMT) qidx = 5; else - qidx = queue_idx; + qidx = queue->qid; rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx); } -static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2800pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); return; } rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO)); rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); } diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9ad28be294eb..02f95892aa07 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -329,12 +329,11 @@ static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); } -static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2800usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txi = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txi = (__le32 *) entry->skb->data; u32 word; /* @@ -342,7 +341,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len - TXINFO_DESC_SIZE); + entry->skb->len - TXINFO_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8c65244a847a..69308a0df74f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -559,18 +559,15 @@ struct rt2x00lib_ops { /* * TX control handlers */ - void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, + void (*write_tx_desc) (struct queue_entry *entry, struct txentry_desc *txdesc); void (*write_tx_data) (struct queue_entry *entry, struct txentry_desc *txdesc); void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); int (*get_tx_data_len) (struct queue_entry *entry); - void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); - void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); + void (*kick_tx_queue) (struct data_queue *queue); + void (*kill_tx_queue) (struct data_queue *queue); /* * RX control handlers diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 18220953851e..189eaf72967e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -449,15 +449,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { struct data_queue *queue = entry->queue; - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); + queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc); /* * All processing on the frame has been completed, this means * it is now ready to be dumped to userspace through debugfs. */ - rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); + rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); } static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, @@ -477,7 +476,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, */ if (rt2x00queue_threshold(queue) || !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); + rt2x00dev->ops->lib->kick_tx_queue(queue); } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, @@ -591,7 +590,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, intf->beacon->skb = NULL; if (!enable_beacon) { - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); + rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); mutex_unlock(&intf->beacon_skb_mutex); return 0; } @@ -719,7 +718,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; txall_queue_for_each(rt2x00dev, queue) - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); + rt2x00dev->ops->lib->kill_tx_queue(queue); } void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index f76014f732ce..52ed3f44c843 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -249,10 +249,8 @@ static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) } } -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +void rt2x00usb_kick_tx_queue(struct data_queue *queue) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); unsigned long irqflags; unsigned int index; unsigned int index_done; @@ -286,10 +284,8 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); -void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +void rt2x00usb_kill_tx_queue(struct data_queue *queue) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; unsigned int i; @@ -300,8 +296,8 @@ void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, * the beacon guard byte. */ kill_guard = - (qid == QID_BEACON) && - (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); + (queue->qid == QID_BEACON) && + (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &queue->rt2x00dev->flags)); /* * Cancel all entries. @@ -447,7 +443,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) * The USB version of kill_tx_queue also works * on the RX queue. */ - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); + rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); } EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index d3d3ddc40875..c2d997f67b3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn { /** * rt2x00usb_kick_tx_queue - Kick data queue - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @qid: Data queue to kick + * @queue: Data queue to kick * * This will walk through all entries of the queue and push all pending * frames to the hardware as a single burst. */ -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid); +void rt2x00usb_kick_tx_queue(struct data_queue *queue); /** * rt2x00usb_kill_tx_queue - Kill data queue - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @qid: Data queue to kill + * @queue: Data queue to kill * * This will walk through all entries of the queue and kill all * previously kicked frames before they can be send. */ -void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid); +void rt2x00usb_kill_tx_queue(struct data_queue *queue); /** * rt2x00usb_watchdog - Watchdog for USB communication diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index cff503faac65..ae4698e18729 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1766,12 +1766,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt61pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1802,11 +1801,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, } rt2x00_desc_read(txd, 5, &word); - rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); + rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, skbdesc->entry->entry_idx); rt2x00_set_field32(&word, TXD_W5_TX_POWER, - TXPOWER_TO_DEV(rt2x00dev->tx_power)); + TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); @@ -1882,7 +1881,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt61pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1918,34 +1917,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry, entry->skb = NULL; } -static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt61pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); } -static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt61pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); return; } rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO)); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index c65529678fbd..ab9389439d75 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1426,12 +1426,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt73usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txd = (__le32 *) entry->skb->data; u32 word; /* @@ -1487,7 +1486,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_read(txd, 5, &word); rt2x00_set_field32(&word, TXD_W5_TX_POWER, - TXPOWER_TO_DEV(rt2x00dev->tx_power)); + TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); @@ -1526,7 +1525,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt73usb_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. -- cgit v1.2.3 From ee1e755f84dfd5d482076c642fac830aafdc482b Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:54:02 +0200 Subject: rt2x00: Reduce indenting Cosmetic change, reduce indenting. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 52ed3f44c843..1d2eb461329f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -232,21 +232,22 @@ static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) struct queue_entry_priv_usb *entry_priv = entry->priv_data; u32 length; - if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { - /* - * USB devices cannot blindly pass the skb->len as the - * length of the data to usb_fill_bulk_urb. Pass the skb - * to the driver to determine what the length should be. - */ - length = rt2x00dev->ops->lib->get_tx_data_len(entry); + if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) + return; + + /* + * USB devices cannot blindly pass the skb->len as the + * length of the data to usb_fill_bulk_urb. Pass the skb + * to the driver to determine what the length should be. + */ + length = rt2x00dev->ops->lib->get_tx_data_len(entry); - usb_fill_bulk_urb(entry_priv->urb, usb_dev, - usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), - entry->skb->data, length, - rt2x00usb_interrupt_txdone, entry); + usb_fill_bulk_urb(entry_priv->urb, usb_dev, + usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), + entry->skb->data, length, + rt2x00usb_interrupt_txdone, entry); - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); - } + usb_submit_urb(entry_priv->urb, GFP_ATOMIC); } void rt2x00usb_kick_tx_queue(struct data_queue *queue) -- cgit v1.2.3 From 5eb7efe8a4807d98a277280e1317e5094eedfb6b Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:54:21 +0200 Subject: rt2x00: Move direct access to queue->entries to rt2x00queue.c All access to queue->entries through the Q_INDEX/Q_INDEX_DONE variables must be done using spinlock protection. It is best to manage this completely from rt2x00queue.c. For safely looping through all entries in the queue, the function rt2x00queue_for_each_entry is added which will walk from from a index range in a safe manner. This also fixes rt2x00usb which walked the entries list from 0 to length to kill each entry (killing entries must be done from Q_INDEX_DONE to Q_INDEX to enforce TX status reporting to occur in the correct order. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 4 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 45 +++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00queue.h | 16 +++++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 75 +++++++++---------------------- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index af1c6914d7b4..a5e58705b49b 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -629,7 +629,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, static void rt2800pci_kick_tx_queue(struct data_queue *queue) { struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - unsigned int idx = queue->index[Q_INDEX]; + struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); unsigned int qidx = 0; if (queue->qid == QID_MGMT) @@ -637,7 +637,7 @@ static void rt2800pci_kick_tx_queue(struct data_queue *queue) else qidx = queue->qid; - rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx); + rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx); } static void rt2800pci_kill_tx_queue(struct data_queue *queue) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 189eaf72967e..7fb9b6179af1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -625,6 +625,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, return 0; } +void rt2x00queue_for_each_entry(struct data_queue *queue, + enum queue_index start, + enum queue_index end, + void (*fn)(struct queue_entry *entry)) +{ + unsigned long irqflags; + unsigned int index_start; + unsigned int index_end; + unsigned int i; + + if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { + ERROR(queue->rt2x00dev, + "Entry requested from invalid index range (%d - %d)\n", + start, end); + return; + } + + /* + * Only protect the range we are going to loop over, + * if during our loop a extra entry is set to pending + * it should not be kicked during this run, since it + * is part of another TX operation. + */ + spin_lock_irqsave(&queue->lock, irqflags); + index_start = queue->index[start]; + index_end = queue->index[end]; + spin_unlock_irqrestore(&queue->lock, irqflags); + + /* + * Start from the TX done pointer, this guarentees that we will + * send out all frames in the correct order. + */ + if (index_start < index_end) { + for (i = index_start; i < index_end; i++) + fn(&queue->entries[i]); + } else { + for (i = index_start; i < queue->limit; i++) + fn(&queue->entries[i]); + + for (i = 0; i < index_end; i++) + fn(&queue->entries[i]); + } +} +EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); + struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 2d3bf843735f..46a3be1d82b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -570,6 +570,22 @@ struct data_queue_desc { #define txall_queue_for_each(__dev, __entry) \ queue_loop(__entry, (__dev)->tx, queue_end(__dev)) +/** + * rt2x00queue_for_each_entry - Loop through all entries in the queue + * @queue: Pointer to @data_queue + * @start: &enum queue_index Pointer to start index + * @end: &enum queue_index Pointer to end index + * @fn: The function to call for each &struct queue_entry + * + * This will walk through all entries in the queue, in chronological + * order. This means it will start at the current @start pointer + * and will walk through the queue until it reaches the @end pointer. + */ +void rt2x00queue_for_each_entry(struct data_queue *queue, + enum queue_index start, + enum queue_index end, + void (*fn)(struct queue_entry *entry)); + /** * rt2x00queue_empty - Check if the queue is empty. * @queue: Queue to check if empty. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 1d2eb461329f..6cc7aa418d87 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -225,7 +225,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); } -static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) +static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); @@ -252,69 +252,34 @@ static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) void rt2x00usb_kick_tx_queue(struct data_queue *queue) { - unsigned long irqflags; - unsigned int index; - unsigned int index_done; - unsigned int i; - - /* - * Only protect the range we are going to loop over, - * if during our loop a extra entry is set to pending - * it should not be kicked during this run, since it - * is part of another TX operation. - */ - spin_lock_irqsave(&queue->lock, irqflags); - index = queue->index[Q_INDEX]; - index_done = queue->index[Q_INDEX_DONE]; - spin_unlock_irqrestore(&queue->lock, irqflags); - - /* - * Start from the TX done pointer, this guarentees that we will - * send out all frames in the correct order. - */ - if (index_done < index) { - for (i = index_done; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } else { - for (i = index_done; i < queue->limit; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - - for (i = 0; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kick_tx_entry); } EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); -void rt2x00usb_kill_tx_queue(struct data_queue *queue) +static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) { - struct queue_entry_priv_usb *entry_priv; - struct queue_entry_priv_usb_bcn *bcn_priv; - unsigned int i; - bool kill_guard; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct queue_entry_priv_usb *entry_priv = entry->priv_data; + struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; - /* - * When killing the beacon queue, we must also kill - * the beacon guard byte. - */ - kill_guard = - (queue->qid == QID_BEACON) && - (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &queue->rt2x00dev->flags)); + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; + + usb_kill_urb(entry_priv->urb); /* - * Cancel all entries. + * Kill guardian urb (if required by driver). */ - for (i = 0; i < queue->limit; i++) { - entry_priv = queue->entries[i].priv_data; - usb_kill_urb(entry_priv->urb); + if ((entry->queue->qid == QID_BEACON) && + (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) + usb_kill_urb(bcn_priv->guardian_urb); +} - /* - * Kill guardian urb (if required by driver). - */ - if (kill_guard) { - bcn_priv = queue->entries[i].priv_data; - usb_kill_urb(bcn_priv->guardian_urb); - } - } +void rt2x00usb_kill_tx_queue(struct data_queue *queue) +{ + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kill_tx_entry); } EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); -- cgit v1.2.3 From 54e34fbb6fae67b3dba4c2600d3c65aca81635ae Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:54:41 +0200 Subject: rt2x00: Remove Q_INDEX_CRYPTO and ENTRY_OWNER_DEVICE_CRYPTO Q_INDEX_CRYPTO and ENTRY_OWNER_DEVICE_CRYPTO where initially added with the plan to implement hardware encryption for rt2500pci. However there are no plans to do so anymore as the crypto mechanism in rt2500pci is very different then any other Ralink device. So we can now safely remove the definitions, and don't think about this feature anymore. :) Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00debug.c | 7 +++---- drivers/net/wireless/rt2x00/rt2x00queue.h | 7 ------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b0498e7e7aae..74f0d679883e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -338,16 +338,15 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, return -ENOMEM; temp = data + - sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); + sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { spin_lock_irqsave(&queue->lock, irqflags); - temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, + temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length, queue->index[Q_INDEX], - queue->index[Q_INDEX_DONE], - queue->index[Q_INDEX_CRYPTO]); + queue->index[Q_INDEX_DONE]); spin_unlock_irqrestore(&queue->lock, irqflags); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 46a3be1d82b9..c451a50f7a01 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -360,9 +360,6 @@ struct txentry_desc { * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data * transfer (either TX or RX depending on the queue). The entry should * only be touched after the device has signaled it is done with it. - * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data - * encryption or decryption. The entry should only be touched after - * the device has signaled it is done with it. * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting * for the signal to start sending. * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured @@ -372,7 +369,6 @@ struct txentry_desc { enum queue_entry_flags { ENTRY_BCN_ASSIGNED, ENTRY_OWNER_DEVICE_DATA, - ENTRY_OWNER_DEVICE_CRYPTO, ENTRY_DATA_PENDING, ENTRY_DATA_IO_FAILED }; @@ -408,15 +404,12 @@ struct queue_entry { * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by * the hardware and for which we need to run the txdone handler. If this * entry is not owned by the hardware the queue is considered to be empty. - * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription - * will be completed by the hardware next. * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size * of the index array. */ enum queue_index { Q_INDEX, Q_INDEX_DONE, - Q_INDEX_CRYPTO, Q_INDEX_MAX, }; -- cgit v1.2.3 From 21595bd50dd1ef16cf0dce33835caaf5ab458d4c Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:55:01 +0200 Subject: rt2x00: Fix rt2800 retry calculation The retry count for a frame is calculated by the realized MCS rate subtracting of the requested MCS rate. However during TX done reporting we accidently override the requested MCS rate with the realized MCS rate. This causes the retry count to be reset to 0 always, and feeding invalid rate information into minstrel_ht. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3a150d3a9d9f..8706702b69a2 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -650,7 +650,6 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) txdesc.flags = 0; rt2x00_desc_read(txwi, 0, &word); mcs = rt2x00_get_field32(word, TXWI_W0_MCS); - mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); /* -- cgit v1.2.3 From b9a07ae9d9e09662013992088fd58ffbcb2f9a30 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:55:22 +0200 Subject: rt2x00: Merge rt2800{pci/usb} radio enabling/disabling code to rt2800lib The functions rt2800pci_enable_radio and rt2800usb_disable_radio are almost equal and can be merged into rt2800lib. This reduces the number of functions which must be exported from rt2800lib to the drivers at the same time. Also rt2800pci_disable_radio and rt2800usb_disable_radio are almost equal and can be merged into rt2800lib in a similar fashion. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 103 ++++++++++++++++++++++++++++++-- drivers/net/wireless/rt2x00/rt2800lib.h | 8 +-- drivers/net/wireless/rt2x00/rt2800pci.c | 69 +-------------------- drivers/net/wireless/rt2x00/rt2800usb.c | 72 +--------------------- 4 files changed, 107 insertions(+), 145 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 8706702b69a2..b2f9b04134eb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1655,7 +1655,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); /* * Initialization functions. */ -int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; u16 eeprom; @@ -2025,7 +2025,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_registers); static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) { @@ -2068,7 +2067,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) return -EACCES; } -int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; u16 eeprom; @@ -2163,7 +2162,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_bbp); static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, bool bw40, u8 rfcsr24, u8 filter_target) @@ -2225,7 +2223,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, return rfcsr24; } -int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { u8 rfcsr; u8 bbp; @@ -2479,7 +2477,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); + +int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + u16 word; + + /* + * Initialize all registers. + */ + if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || + rt2800_init_registers(rt2x00dev) || + rt2800_init_bbp(rt2x00dev) || + rt2800_init_rfcsr(rt2x00dev))) + return -EIO; + + /* + * Send signal to firmware during boot time. + */ + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + + if (rt2x00_is_usb(rt2x00dev) && + (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3572))) { + udelay(200); + rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); + udelay(10); + } + + /* + * Enable RX. + */ + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + udelay(50); + + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); + rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + /* + * Initialize LED control + */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, + word & 0xff, (word >> 8) & 0xff); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, + word & 0xff, (word >> 8) & 0xff); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, + word & 0xff, (word >> 8) & 0xff); + + return 0; +} +EXPORT_SYMBOL_GPL(rt2800_enable_radio); + +void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + /* Wait for DMA, ignore error */ + rt2800_wait_wpdma_ready(rt2x00dev); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); +} +EXPORT_SYMBOL_GPL(rt2800_disable_radio); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) { diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 3b572c63382d..deb10b14157b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -140,6 +140,8 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1); +int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); + int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, @@ -176,10 +178,8 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); -int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); -int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); -int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); -int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); +int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); +void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index a5e58705b49b..4d93204b221f 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -399,78 +399,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { - u32 reg; - u16 word; - - /* - * Initialize all registers. - */ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800pci_init_queues(rt2x00dev) || - rt2800_init_registers(rt2x00dev) || - rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + rt2800pci_init_queues(rt2x00dev))) return -EIO; - /* - * Send signal to firmware during boot time. - */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - - /* - * Enable RX. - */ - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - /* - * Initialize LED control - */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, - word & 0xff, (word >> 8) & 0xff); - - return 0; + return rt2800_enable_radio(rt2x00dev); } static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); + rt2800_disable_radio(rt2x00dev); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); @@ -486,9 +426,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - - /* Wait for DMA, ignore error */ - rt2800_wait_wpdma_ready(rt2x00dev); } static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 02f95892aa07..82ae58e0c5d7 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -101,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, msleep(10); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); - /* - * Send signal to firmware during boot time. - */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - - if (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt(rt2x00dev, RT3071) || - rt2x00_rt(rt2x00dev, RT3572)) { - udelay(200); - rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); - udelay(10); - } - return 0; } @@ -173,30 +160,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; - u16 word; - /* - * Initialize all registers. - */ - if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800_init_registers(rt2x00dev) || - rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) return -EIO; - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - udelay(50); - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); @@ -211,45 +178,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - /* - * Initialize LED control - */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, - word & 0xff, (word >> 8) & 0xff); - - return 0; + return rt2800_enable_radio(rt2x00dev); } static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) { - u32 reg; - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); - - /* Wait for DMA, ignore error */ - rt2800_wait_wpdma_ready(rt2x00dev); - + rt2800_disable_radio(rt2x00dev); rt2x00usb_disable_radio(rt2x00dev); } -- cgit v1.2.3 From 46323e112ce2a0fdaf2dd5389f95b248576b8fda Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:55:43 +0200 Subject: rt2x00: Fix channel configuration for RF3052 We missed a check for RF3052 in the config_channel configuration function. As a result the channel is not properly configured for RF3052 devices. This also requires rt2800_config_channel_rf3xxx to support 5GHz channels, so we must apply the TXPOWER_A_TO_DEV and TXPOWER_G_TO_DEV conversions during rt2800_config_channel() Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b2f9b04134eb..cbab2e126167 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1244,8 +1244,7 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, if (info->tx_power1 < 0) info->tx_power1 += 7; - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, - TXPOWER_A_TO_DEV(info->tx_power1)); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->tx_power1); rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, (info->tx_power2 >= 0)); @@ -1253,13 +1252,10 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, if (info->tx_power2 < 0) info->tx_power2 += 7; - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, - TXPOWER_A_TO_DEV(info->tx_power2)); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->tx_power2); } else { - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, - TXPOWER_G_TO_DEV(info->tx_power1)); - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, - TXPOWER_G_TO_DEV(info->tx_power2)); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->tx_power1); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->tx_power2); } rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); @@ -1299,13 +1295,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, - TXPOWER_G_TO_DEV(info->tx_power1)); + rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->tx_power1); rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, - TXPOWER_G_TO_DEV(info->tx_power2)); + rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->tx_power2); rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); @@ -1329,10 +1323,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, unsigned int tx_pin; u8 bbp; + if (rf->channel <= 14) { + info->tx_power1 = TXPOWER_G_TO_DEV(info->tx_power1); + info->tx_power2 = TXPOWER_G_TO_DEV(info->tx_power2); + } else { + info->tx_power1 = TXPOWER_A_TO_DEV(info->tx_power1); + info->tx_power2 = TXPOWER_A_TO_DEV(info->tx_power2); + } + if (rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022)) + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3052)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); -- cgit v1.2.3 From 8d1331b37d5b656a7a8e561f8e9d7661dd00c910 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 23 Aug 2010 19:56:07 +0200 Subject: rt2x00: Fix max TX power settings During initialization each driver reads the default TX power for each individual channel. However mac80211 only accepts the maximum value (which is also handled as default value). As a result, the TX power of the device was being limited to the default value, which is often quite low compared to the real maximum acceptable value. This patch allows each driver to set the maximum value on a per-channel basis which is forwarded to mac80211. The default value will be preserved for now, in case we want to update mac80211 to differentiate between the maximum and default txpower. This fixes bug complaining about limited TX power values like: https://bugzilla.kernel.org/show_bug.cgi?id=16358 Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 6 ++- drivers/net/wireless/rt2x00/rt2500pci.c | 12 ++++-- drivers/net/wireless/rt2x00/rt2500usb.c | 12 ++++-- drivers/net/wireless/rt2x00/rt2800.h | 7 ++++ drivers/net/wireless/rt2x00/rt2800lib.c | 65 ++++++++++++++++++++------------- drivers/net/wireless/rt2x00/rt2x00.h | 5 ++- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- drivers/net/wireless/rt2x00/rt61pci.c | 12 ++++-- drivers/net/wireless/rt2x00/rt73usb.c | 12 ++++-- 9 files changed, 86 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index b86b6132a69c..e3005ff5ae98 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1487,8 +1487,10 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER); + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 21f45810fd1e..1e6a91b8d3df 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1801,12 +1801,16 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = DEFAULT_TXPOWER; + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = DEFAULT_TXPOWER; + } } return 0; diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 8722464944f5..71d8d821c4e1 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1706,12 +1706,16 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = DEFAULT_TXPOWER; + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = DEFAULT_TXPOWER; + } } return 0; diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index cf1f16bfcd5e..5c006a795346 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1858,6 +1858,13 @@ struct mac_iveiv_entry { #define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff) #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) +/* + * EEPROM Maximum TX power values + */ +#define EEPROM_MAX_TX_POWER 0x0027 +#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) +#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) + /* * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. * This is delta in 40MHZ. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cbab2e126167..ecbd07a78edb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1239,23 +1239,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, * double meaning, and we should set a 7DBm boost flag. */ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, - (info->tx_power1 >= 0)); + (info->default_power1 >= 0)); - if (info->tx_power1 < 0) - info->tx_power1 += 7; + if (info->default_power1 < 0) + info->default_power1 += 7; - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->tx_power1); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, - (info->tx_power2 >= 0)); + (info->default_power2 >= 0)); - if (info->tx_power2 < 0) - info->tx_power2 += 7; + if (info->default_power2 < 0) + info->default_power2 += 7; - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->tx_power2); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); } else { - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->tx_power1); - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->tx_power2); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); } rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); @@ -1295,11 +1295,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->tx_power1); + rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->tx_power2); + rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); @@ -1324,11 +1324,11 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, u8 bbp; if (rf->channel <= 14) { - info->tx_power1 = TXPOWER_G_TO_DEV(info->tx_power1); - info->tx_power2 = TXPOWER_G_TO_DEV(info->tx_power2); + info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); + info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); } else { - info->tx_power1 = TXPOWER_A_TO_DEV(info->tx_power1); - info->tx_power2 = TXPOWER_A_TO_DEV(info->tx_power2); + info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); + info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); } if (rt2x00_rf(rt2x00dev, RF2020) || @@ -2729,6 +2729,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) default_lna_gain); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); + if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) + rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); + if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) + rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); + rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); + return 0; } EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); @@ -2968,9 +2975,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; struct channel_info *info; - char *tx_power1; - char *tx_power2; + char *default_power1; + char *default_power2; unsigned int i; + unsigned short max_power; u16 eeprom; /* @@ -3084,21 +3092,26 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; - tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); - tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); + rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); + max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); + default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); + default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); for (i = 0; i < 14; i++) { - info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); - info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); + info[i].max_power = max_power; + info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); + info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); } if (spec->num_channels > 14) { - tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); - tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); + max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); + default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); + default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); for (i = 14; i < spec->num_channels; i++) { - info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); - info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); + info[i].max_power = max_power; + info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); + info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); } } diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 69308a0df74f..762f6b4e7afc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -213,8 +213,9 @@ struct channel_info { unsigned int flags; #define GEOGRAPHY_ALLOWED 0x00000001 - short tx_power1; - short tx_power2; + short max_power; + short default_power1; + short default_power2; }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e692608bee8b..580595ba5683 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -711,7 +711,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, for (i = 0; i < spec->num_channels; i++) { rt2x00lib_channel(&channels[i], spec->channels[i].channel, - spec->channels_info[i].tx_power1, i); + spec->channels_info[i].max_power, i); } /* diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index ae4698e18729..8f017ad8c3db 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2656,13 +2656,17 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } } return 0; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ab9389439d75..ee2c52fd0d73 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2090,13 +2090,17 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } } return 0; -- cgit v1.2.3 From f8d8b7a13d3d61f99bf3dc5c9650f87f9818d7a7 Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Mon, 23 Aug 2010 23:02:22 +0200 Subject: rt2x00: fix "buffer size not provably correct" build warning rt2x00 debugfs interface doesn't check the size of the data coming from userspace, leading to a build warning. Fix That. v2: return EINVAL if input is too long Signed-off-by: Arnaud Patard Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00debug.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 74f0d679883e..daf7f950a28f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -480,6 +480,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ if (index >= debug->__name.word_count) \ return -EINVAL; \ \ + if (length > sizeof(line)) \ + return -EINVAL; \ + \ if (copy_from_user(line, buf, length)) \ return -EFAULT; \ \ -- cgit v1.2.3 From 74b70a4e38d542843fccfb367dce1ac861cc3890 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 24 Aug 2010 12:15:53 +0200 Subject: nl80211: fix missing nesting commit 95a6ccbb46c70cff376684c752831c014c87029d Author: Johannes Berg Date: Thu Aug 12 15:38:38 2010 +0200 cfg80211/mac80211: extensible frame processing introduced a netlink bug that caused parsing errors in userspace because it forgot to close a nesting, which would advertise a nesting length of zero to userspace, which then completely threw off parsing and led to Illegal nla->nla_type == 0 being printed by libnl. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 927ffbd2aebc..49f5ca35e787 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -636,6 +636,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_ftypes); } + nla_nest_end(msg, nl_ifs); + nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); if (!nl_ifs) goto nla_put_failure; -- cgit v1.2.3 From 2c15a0cf27a74213a714cc7be31685b841f7c1ac Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 24 Aug 2010 19:22:42 +0200 Subject: mac80211: fix rcu-unsafe pointer dereference This patch fixes a potential crash (null-pointer de- reference) which was introduced in my previous patch: "mac80211: AMPDU rx reorder timeout timer" During a BA teardown, the pointer to the soon-to-be-gone tid_ampdu_rx element will be nullified. Therefore the release timer mechanism has to be careful not to accidentally access the item without any RCU protection. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e1844f7085de..e67deb48af5c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2479,6 +2479,11 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) { struct sk_buff_head frames; struct ieee80211_rx_data rx = { }; + struct tid_ampdu_rx *tid_agg_rx; + + tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); + if (!tid_agg_rx) + return; __skb_queue_head_init(&frames); @@ -2493,10 +2498,9 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning))) rx.flags |= IEEE80211_RX_IN_SCAN; - spin_lock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); - ieee80211_sta_reorder_release(&sta->local->hw, - sta->ampdu_mlme.tid_rx[tid], &frames); - spin_unlock(&sta->ampdu_mlme.tid_rx[tid]->reorder_lock); + spin_lock(&tid_agg_rx->reorder_lock); + ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); + spin_unlock(&tid_agg_rx->reorder_lock); ieee80211_rx_handlers(&rx, &frames); } -- cgit v1.2.3 From 45f7e3116fad77e6dd15cb0e2eaccb7de7b806c9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 24 Aug 2010 23:29:05 +0200 Subject: p54: better rssi->dbm conversion for longbow phys This patch should fix the dodgy signal and noise value reports for most longbow (p54spi) users: e.g.: (an older tcpdump extract) > 2.0 Mb/s 2437 MHz (0x00a0) -49dB signal -41dB noise > 1.0 Mb/s 2437 MHz (0x00a0) 4dB signal -41dB noise The formula is taken from stlc45xx: http://gitorious.org/stlc45xx/mainline/blobs/master/stlc45xx.c#line1199 Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/txrx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 34447d1ad80d..8f67db487f57 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -275,15 +275,15 @@ static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) { int band = priv->hw->conf.channel->band; - if (priv->rxhw != 5) + if (priv->rxhw != 5) { return ((rssi * priv->rssical_db[band].mul) / 64 + priv->rssical_db[band].add) / 4; - else + } else { /* * TODO: find the correct formula */ - return ((rssi * priv->rssical_db[band].mul) / 64 + - priv->rssical_db[band].add) / 4; + return rssi / 2 - 110; + } } /* -- cgit v1.2.3 From 5eb5a52da6ef04604cf8faca43ec670f69f417d3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 25 Aug 2010 14:34:01 +0200 Subject: mac80211: fix mesh advertisement When a mac80211-based driver advertises mesh mode support, this will be advertised to userspace. However, if mac80211 was compiled without mesh support, then that won't actually be true. Fix this by removing the bit for mesh if mesh isn't compiled in. Since this synchronizes what we advertise to cfg80211 and actually support, it means we can now rely on cfg80211's interface type checks and need not check again in mac80211. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 33 --------------------------------- net/mac80211/main.c | 5 +++++ 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7693ebc77596..581438255d7e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -19,33 +19,6 @@ #include "rate.h" #include "mesh.h" -static bool nl80211_type_check(enum nl80211_iftype type) -{ - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_MONITOR: -#ifdef CONFIG_MAC80211_MESH - case NL80211_IFTYPE_MESH_POINT: -#endif - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - return true; - default: - return false; - } -} - -static bool nl80211_params_check(enum nl80211_iftype type, - struct vif_params *params) -{ - if (!nl80211_type_check(type)) - return false; - - return true; -} - static int ieee80211_add_iface(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) @@ -55,9 +28,6 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, struct ieee80211_sub_if_data *sdata; int err; - if (!nl80211_params_check(type, params)) - return -EINVAL; - err = ieee80211_if_add(local, name, &dev, type, params); if (err || type != NL80211_IFTYPE_MONITOR || !flags) return err; @@ -85,9 +55,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, if (ieee80211_sdata_running(sdata)) return -EBUSY; - if (!nl80211_params_check(type, params)) - return -EINVAL; - ret = ieee80211_if_change_type(sdata, type); if (ret) return ret; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 28415de5f476..80db5ea02052 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -622,6 +622,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) /* mac80211 always supports monitor */ local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); +#ifndef CONFIG_MAC80211_MESH + /* mesh depends on Kconfig, but drivers should set it if they want */ + local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); +#endif + if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) -- cgit v1.2.3 From 903786a5626e7214d97b232bece88ee75e37d021 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 24 Aug 2010 07:27:56 -0700 Subject: iwlwifi: fix compile error without debugging support Encounter compiler error when iwlwifi debugging support is disabled, fix it. This compiler error was introduced by the previous WiFi/BT coexist patchset. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 33aa7a5eea8a..2939699a1200 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -206,7 +206,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; @@ -214,7 +213,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, scan_notif->scanned_channels, scan_notif->tsf_low, scan_notif->tsf_high, scan_notif->status); -#endif /* The HW is no longer scanning */ clear_bit(STATUS_SCAN_HW, &priv->status); -- cgit v1.2.3 From e9a47700cb35bc84d4954f762a193b150722612e Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Wed, 25 Aug 2010 04:03:02 +0000 Subject: qlcnic: eswitch config fixes o remove validation before deleting vlan id o Add missing 'break' while deleting vlan id. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ctx.c | 1 + drivers/net/qlcnic/qlcnic_main.c | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 315705b22be2..bd4b06b2d86d 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -1160,6 +1160,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, case QLCNIC_DEL_VLAN: arg1 |= (BIT_3 | BIT_5); arg1 &= ~(0x0ffff << 16); + break; default: return err; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 46b9137ca893..5d93b464681a 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -3301,8 +3301,6 @@ validate_esw_config(struct qlcnic_adapter *adapter, return QL_STATUS_INVALID_PARAM; break; case QLCNIC_DEL_VLAN: - if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) - return QL_STATUS_INVALID_PARAM; if (!esw_cfg[i].op_type) return QL_STATUS_INVALID_PARAM; break; @@ -3338,21 +3336,25 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, if (adapter->op_mode == QLCNIC_MGMT_FUNC) if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) return QL_STATUS_INVALID_PARAM; - if (adapter->ahw.pci_func == esw_cfg[i].pci_func) - op_mode = esw_cfg[i].op_mode; - qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]); - esw_cfg[i].op_mode = op_mode; - esw_cfg[i].pci_func = adapter->ahw.pci_func; - switch (esw_cfg[i].op_mode) { - case QLCNIC_PORT_DEFAULTS: - qlcnic_set_eswitch_port_features(adapter, - &esw_cfg[i]); - break; + + if (adapter->ahw.pci_func != esw_cfg[i].pci_func) + continue; + + op_mode = esw_cfg[i].op_mode; + qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]); + esw_cfg[i].op_mode = op_mode; + esw_cfg[i].pci_func = adapter->ahw.pci_func; + + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); + break; } } if (adapter->op_mode != QLCNIC_MGMT_FUNC) goto out; + for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; npar = &adapter->npars[pci_func]; -- cgit v1.2.3 From 8cf61f890ac4c2a15acb24658feba13c9c838b52 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 25 Aug 2010 04:03:03 +0000 Subject: qlcnic: support port vlan id On NIC Partition capable adapter, Administrator can configure to tag packet with particular vlan id. Packet will be tagged and strip with that vlan id. Also if 'Tagging' flag is disable, other packet will be drop. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 +- drivers/net/qlcnic/qlcnic_init.c | 39 ++++++++++++++++++ drivers/net/qlcnic/qlcnic_main.c | 89 +++++++++++++++++++++++++++++++--------- 3 files changed, 111 insertions(+), 21 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 508d531a55e5..d15de63ed0bb 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -175,7 +175,7 @@ ((_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0)) #define qlcnic_set_tx_flags_opcode(_desc, _flags, _opcode) \ - ((_desc)->flags_opcode = \ + ((_desc)->flags_opcode |= \ cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))) #define qlcnic_set_tx_frags_len(_desc, _frags, _len) \ @@ -902,6 +902,7 @@ struct qlcnic_mac_req { #define QLCNIC_BRIDGE_ENABLED 0X10 #define QLCNIC_DIAG_ENABLED 0x20 #define QLCNIC_ESWITCH_ENABLED 0x40 +#define QLCNIC_TAGGING_ENABLED 0x100 #define QLCNIC_MACSPOOF 0x200 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) @@ -967,6 +968,7 @@ struct qlcnic_adapter { u16 max_tx_ques; u16 max_rx_ques; u16 max_mtu; + u16 pvid; u32 fw_hal_version; u32 capabilities; diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index a174521daa63..df91b754bb70 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "qlcnic.h" struct crb_addr_pair { @@ -1302,6 +1303,27 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, return skb; } +static int +qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb) +{ + u16 vlan_tag; + struct ethhdr *eth_hdr; + + if (!__vlan_get_tag(skb, &vlan_tag)) { + if (vlan_tag == adapter->pvid) { + /* strip the tag from the packet and send it up */ + eth_hdr = (struct ethhdr *) skb->data; + memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); + skb_pull(skb, VLAN_HLEN); + return 0; + } + } + if (adapter->flags & QLCNIC_TAGGING_ENABLED) + return 0; + + return -EIO; +} + static struct qlcnic_rx_buffer * qlcnic_process_rcv(struct qlcnic_adapter *adapter, struct qlcnic_host_sds_ring *sds_ring, @@ -1342,6 +1364,15 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, skb_pull(skb, pkt_offset); skb->truesize = skb->len + sizeof(struct sk_buff); + + if (unlikely(adapter->pvid)) { + if (qlcnic_check_rx_tagging(adapter, skb)) { + adapter->stats.rxdropped++; + dev_kfree_skb_any(skb); + return buffer; + } + } + skb->protocol = eth_type_trans(skb, netdev); napi_gro_receive(&sds_ring->napi, skb); @@ -1406,6 +1437,14 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); skb_pull(skb, l2_hdr_offset); + + if (unlikely(adapter->pvid)) { + if (qlcnic_check_rx_tagging(adapter, skb)) { + adapter->stats.rxdropped++; + dev_kfree_skb_any(skb); + return buffer; + } + } skb->protocol = eth_type_trans(skb, netdev); iph = (struct iphdr *)skb->data; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 5d93b464681a..089212214ad4 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -758,6 +758,21 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->max_rds_rings = MAX_RDS_RINGS; } +static void +qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + if (esw_cfg->discard_tagged) + adapter->flags &= ~QLCNIC_TAGGING_ENABLED; + else + adapter->flags |= QLCNIC_TAGGING_ENABLED; + + if (esw_cfg->vlan_id) + adapter->pvid = esw_cfg->vlan_id; + else + adapter->pvid = 0; +} + static void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) @@ -781,6 +796,7 @@ qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) esw_cfg.pci_func = adapter->ahw.pci_func; if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) return -EIO; + qlcnic_set_vlan_config(adapter, &esw_cfg); qlcnic_set_eswitch_port_features(adapter, &esw_cfg); return 0; @@ -1728,26 +1744,13 @@ qlcnic_tso_check(struct net_device *netdev, { u8 opcode = TX_ETHER_PKT; __be16 protocol = skb->protocol; - u16 flags = 0, vid = 0; - int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; + u16 flags = 0; + int copied, offset, copy_len, hdr_len = 0, tso = 0; struct cmd_desc_type0 *hwdesc; struct vlan_ethhdr *vh; struct qlcnic_adapter *adapter = netdev_priv(netdev); u32 producer = tx_ring->producer; - - if (protocol == cpu_to_be16(ETH_P_8021Q)) { - - vh = (struct vlan_ethhdr *)skb->data; - protocol = vh->h_vlan_encapsulated_proto; - flags = FLAGS_VLAN_TAGGED; - - } else if (vlan_tx_tag_present(skb)) { - - flags = FLAGS_VLAN_OOB; - vid = vlan_tx_tag_get(skb); - qlcnic_set_tx_vlan_tci(first_desc, vid); - vlan_oob = 1; - } + int vlan_oob = first_desc->flags_opcode & cpu_to_le16(FLAGS_VLAN_OOB); if (*(skb->data) & BIT_0) { flags |= BIT_0; @@ -1818,7 +1821,7 @@ qlcnic_tso_check(struct net_device *netdev, vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); skb_copy_from_linear_data(skb, vh, 12); vh->h_vlan_proto = htons(ETH_P_8021Q); - vh->h_vlan_TCI = htons(vid); + vh->h_vlan_TCI = htons(first_desc->vlan_TCI); skb_copy_from_linear_data_offset(skb, 12, (char *)vh + 16, copy_len - 16); @@ -1898,11 +1901,47 @@ out_err: return -ENOMEM; } +static int +qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter, + struct sk_buff *skb, + struct cmd_desc_type0 *first_desc) +{ + u8 opcode = 0; + u16 flags = 0; + __be16 protocol = skb->protocol; + struct vlan_ethhdr *vh; + + if (protocol == cpu_to_be16(ETH_P_8021Q)) { + vh = (struct vlan_ethhdr *)skb->data; + protocol = vh->h_vlan_encapsulated_proto; + flags = FLAGS_VLAN_TAGGED; + qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI)); + } else if (vlan_tx_tag_present(skb)) { + flags = FLAGS_VLAN_OOB; + qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb)); + } + if (unlikely(adapter->pvid)) { + if (first_desc->vlan_TCI && + !(adapter->flags & QLCNIC_TAGGING_ENABLED)) + return -EIO; + if (first_desc->vlan_TCI && + (adapter->flags & QLCNIC_TAGGING_ENABLED)) + goto set_flags; + + flags = FLAGS_VLAN_OOB; + qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid); + } +set_flags: + qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); + return 0; +} + static inline void qlcnic_clear_cmddesc(u64 *desc) { desc[0] = 0ULL; desc[2] = 0ULL; + desc[7] = 0ULL; } netdev_tx_t @@ -1952,6 +1991,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pdev = adapter->pdev; + first_desc = hwdesc = &tx_ring->desc_head[producer]; + qlcnic_clear_cmddesc((u64 *)hwdesc); + + if (qlcnic_check_tx_tagging(adapter, skb, first_desc)) + goto drop_packet; + if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { adapter->stats.tx_dma_map_error++; goto drop_packet; @@ -1960,9 +2005,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->skb = skb; pbuf->frag_count = frag_count; - first_desc = hwdesc = &tx_ring->desc_head[producer]; - qlcnic_clear_cmddesc((u64 *)hwdesc); - qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); qlcnic_set_tx_port(first_desc, adapter->portnum); @@ -3349,6 +3391,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, case QLCNIC_PORT_DEFAULTS: qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); break; + case QLCNIC_ADD_VLAN: + qlcnic_set_vlan_config(adapter, &esw_cfg[i]); + break; + case QLCNIC_DEL_VLAN: + esw_cfg[i].vlan_id = 0; + qlcnic_set_vlan_config(adapter, &esw_cfg[i]); + break; } } -- cgit v1.2.3 From b18971d199cf35f68ffa22e4be1c477493fdb7e1 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 25 Aug 2010 04:03:04 +0000 Subject: qlcnic: fix fw recovery for PF Privilege function should wait for npar state to be operational before creating context. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 089212214ad4..26d9e10a36d5 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -997,11 +997,7 @@ check_fw_status: set_dev_ready: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); - err = qlcnic_check_npar_opertional(adapter); - if (err) { - qlcnic_release_firmware(adapter); - return err; - } + if (qlcnic_set_default_offload_settings(adapter)) goto err_out; if (qlcnic_reset_npar_config(adapter)) @@ -2602,6 +2598,7 @@ skip_ack_check: if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); + adapter->fw_wait_cnt = 0; return; } goto err_ret; @@ -2617,6 +2614,7 @@ wait_npar: case QLCNIC_DEV_READY: if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); + adapter->fw_wait_cnt = 0; return; } case QLCNIC_DEV_FAILED: @@ -2750,7 +2748,21 @@ qlcnic_attach_work(struct work_struct *work) struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter, fw_work.work); struct net_device *netdev = adapter->netdev; + u32 npar_state; + if (adapter->op_mode != QLCNIC_MGMT_FUNC) { + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) + qlcnic_clr_all_drv_state(adapter, 0); + else if (npar_state != QLCNIC_DEV_NPAR_OPER) + qlcnic_schedule_work(adapter, qlcnic_attach_work, + FW_POLL_DELAY); + else + goto attach; + QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); + return; + } +attach: if (netif_running(netdev)) { if (qlcnic_up(adapter, netdev)) goto done; -- cgit v1.2.3 From 31018e068edb9eed740bec5cf14802c3c676c9ee Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Wed, 25 Aug 2010 04:03:05 +0000 Subject: qlcnic: change reg name Change QLCNIC_CRB_DEV_REF_COUNT to QLCNIC_CRB_DRV_ACTIVE to match document. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 2 +- drivers/net/qlcnic/qlcnic_hdr.h | 2 +- drivers/net/qlcnic/qlcnic_main.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 2805f88aaf7c..e294b825bac5 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -99,7 +99,7 @@ static const u32 diag_registers[] = { CRB_XG_STATE_P3, CRB_FW_CAPABILITIES_1, ISR_INT_STATE_REG, - QLCNIC_CRB_DEV_REF_COUNT, + QLCNIC_CRB_DRV_ACTIVE, QLCNIC_CRB_DEV_STATE, QLCNIC_CRB_DRV_STATE, QLCNIC_CRB_DRV_SCRATCH, diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 794f6572e8fd..219de9f4496f 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -698,7 +698,7 @@ enum { #define QLCNIC_PEG_ALIVE_COUNTER (QLCNIC_CAM_RAM(0xb0)) #define QLCNIC_PEG_HALT_STATUS1 (QLCNIC_CAM_RAM(0xa8)) #define QLCNIC_PEG_HALT_STATUS2 (QLCNIC_CAM_RAM(0xac)) -#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138)) +#define QLCNIC_CRB_DRV_ACTIVE (QLCNIC_CAM_RAM(0x138)) #define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140)) #define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144)) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 26d9e10a36d5..630a077e4547 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -540,7 +540,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; /* If other drivers are not in use set their privilege level */ - ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); ret = qlcnic_api_lock(adapter); if (ret) goto err_lock; @@ -2404,9 +2404,9 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) if (qlcnic_api_lock(adapter)) goto err; - val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); QLC_DEV_CLR_REF_CNT(val, adapter->portnum); - QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); + QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); if (failed) { QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); @@ -2433,7 +2433,7 @@ qlcnic_check_drv_state(struct qlcnic_adapter *adapter) int act, state; state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); - act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); if (((state & 0x11111111) == (act & 0x11111111)) || ((act & 0x11111111) == ((state >> 1) & 0x11111111))) @@ -2468,10 +2468,10 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) if (qlcnic_api_lock(adapter)) return -1; - val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); if (!(val & (1 << (portnum * 4)))) { QLC_DEV_SET_REF_CNT(val, portnum); - QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); + QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); } prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); -- cgit v1.2.3 From c061b18df0f1fe3f50fe451dbbdc9ede3c19701a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 23 Aug 2010 18:20:03 +0000 Subject: drivers/net: Remove address use from assignments of function pointers "foo = &function" is more commonly written "foo = function" Done with coccinelle script: // @r@ identifier f; @@ f(...) { ... } @@ identifier r.f; @@ - &f + f // drivers/net/tehuti.c used a function and struct with the same name, the function was renamed. Compile tested x86 only. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/3c503.c | 8 +++---- drivers/net/3c515.c | 2 +- drivers/net/3c59x.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl1.c | 2 +- drivers/net/atlx/atl2.c | 4 ++-- drivers/net/atp.c | 2 +- drivers/net/bcm63xx_enet.c | 2 +- drivers/net/cpmac.c | 2 +- drivers/net/declance.c | 2 +- drivers/net/dl2k.c | 2 +- drivers/net/e1000/e1000_main.c | 6 ++--- drivers/net/e1000e/netdev.c | 4 ++-- drivers/net/ehea/ehea_main.c | 6 ++--- drivers/net/epic100.c | 2 +- drivers/net/fealnx.c | 4 ++-- drivers/net/forcedeth.c | 6 ++--- drivers/net/hamachi.c | 2 +- drivers/net/hp.c | 8 +++---- drivers/net/hydra.c | 8 +++---- drivers/net/igb/igb_main.c | 4 ++-- drivers/net/ioc3-eth.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 4 ++-- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/mac8390.c | 48 +++++++++++++++++++------------------- drivers/net/natsemi.c | 2 +- drivers/net/pci-skeleton.c | 2 +- drivers/net/pcmcia/3c574_cs.c | 2 +- drivers/net/pcmcia/3c589_cs.c | 2 +- drivers/net/pcmcia/axnet_cs.c | 10 ++++---- drivers/net/pcmcia/pcnet_cs.c | 16 ++++++------- drivers/net/pcmcia/smc91c92_cs.c | 4 ++-- drivers/net/rrunner.c | 2 +- drivers/net/sh_eth.c | 2 +- drivers/net/sis900.c | 2 +- drivers/net/sunbmac.c | 2 +- drivers/net/sundance.c | 2 +- drivers/net/sunhme.c | 2 +- drivers/net/sunlance.c | 2 +- drivers/net/tehuti.c | 8 +++---- drivers/net/tlan.c | 8 +++---- drivers/net/tulip/dmfe.c | 2 +- drivers/net/tulip/uli526x.c | 2 +- drivers/net/tulip/winbond-840.c | 2 +- drivers/net/wan/lmc/lmc_main.c | 2 +- drivers/net/wd.c | 8 +++---- drivers/net/wireless/ray_cs.c | 12 +++++----- drivers/net/yellowfin.c | 2 +- 49 files changed, 118 insertions(+), 118 deletions(-) diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index baac246561b9..4777a1cbcd8d 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -337,10 +337,10 @@ el2_probe1(struct net_device *dev, int ioaddr) /* Finish setting the board's parameters. */ ei_status.stop_page = EL2_MB1_STOP_PG; ei_status.word16 = wordlength; - ei_status.reset_8390 = &el2_reset_8390; - ei_status.get_8390_hdr = &el2_get_8390_hdr; - ei_status.block_input = &el2_block_input; - ei_status.block_output = &el2_block_output; + ei_status.reset_8390 = el2_reset_8390; + ei_status.get_8390_hdr = el2_get_8390_hdr; + ei_status.block_input = el2_block_input; + ei_status.block_output = el2_block_output; if (dev->irq == 2) dev->irq = 9; diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 3bba835f1a21..8a6eb0c44486 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -734,7 +734,7 @@ static int corkscrew_open(struct net_device *dev) init_timer(&vp->timer); vp->timer.expires = jiffies + media_tbl[dev->if_port].wait; vp->timer.data = (unsigned long) dev; - vp->timer.function = &corkscrew_timer; /* timer handler */ + vp->timer.function = corkscrew_timer; /* timer handler */ add_timer(&vp->timer); } else dev->if_port = vp->default_media; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index c754d88e5ec9..7a01588fb6fb 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1738,7 +1738,7 @@ vortex_open(struct net_device *dev) /* Use the now-standard shared IRQ implementation. */ if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? - &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) { + boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) { pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq); goto err; } diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1acea5774e89..1ae44bb26317 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -2316,7 +2316,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64); init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl1e_phy_config; + adapter->phy_config_timer.function = atl1e_phy_config; adapter->phy_config_timer.data = (unsigned long) adapter; /* get user settings */ diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 63b9ba0cc67e..5837b0184d4b 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -3036,7 +3036,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, netif_carrier_off(netdev); netif_stop_queue(netdev); - setup_timer(&adapter->phy_config_timer, &atl1_phy_config, + setup_timer(&adapter->phy_config_timer, atl1_phy_config, (unsigned long)adapter); adapter->phy_timer_pending = false; diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 8da87383fb39..07adc8446901 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1444,11 +1444,11 @@ static int __devinit atl2_probe(struct pci_dev *pdev, atl2_check_options(adapter); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &atl2_watchdog; + adapter->watchdog_timer.function = atl2_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl2_phy_config; + adapter->phy_config_timer.function = atl2_phy_config; adapter->phy_config_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->reset_task, atl2_reset_task); diff --git a/drivers/net/atp.c b/drivers/net/atp.c index bd2f9d331dac..dfd96b20547f 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -445,7 +445,7 @@ static int net_open(struct net_device *dev) init_timer(&lp->timer); lp->timer.expires = jiffies + TIMED_CHECKER; lp->timer.data = (unsigned long)dev; - lp->timer.function = &atp_timed_checker; /* timer handler */ + lp->timer.function = atp_timed_checker; /* timer handler */ add_timer(&lp->timer); netif_start_queue(dev); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index e2f70c3d7be4..ecfef240a303 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -798,7 +798,7 @@ static int bcm_enet_open(struct net_device *dev) snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->mac_id ? "1" : "0", priv->phy_id); - phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0, + phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev)) { diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 8e142aaa05d4..5a5af1ca7541 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1175,7 +1175,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); - priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, + priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(priv->phy)) { diff --git a/drivers/net/declance.c b/drivers/net/declance.c index d7de376d7178..219eb5ad5c12 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -1255,7 +1255,7 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type) */ init_timer(&lp->multicast_timer); lp->multicast_timer.data = (unsigned long) dev; - lp->multicast_timer.function = &lance_set_multicast_retry; + lp->multicast_timer.function = lance_set_multicast_retry; ret = register_netdev(dev); if (ret) { diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index a2f238d20caa..e1a8216ff692 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -465,7 +465,7 @@ rio_open (struct net_device *dev) init_timer (&np->timer); np->timer.expires = jiffies + 1*HZ; np->timer.data = (unsigned long) dev; - np->timer.function = &rio_timer; + np->timer.function = rio_timer; add_timer (&np->timer); /* Start Tx/Rx */ diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5cc39ed289c6..3e8ac4baae1b 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -962,15 +962,15 @@ static int __devinit e1000_probe(struct pci_dev *pdev, e1000_get_bus_info(hw); init_timer(&adapter->tx_fifo_stall_timer); - adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall; + adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall; adapter->tx_fifo_stall_timer.data = (unsigned long)adapter; init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &e1000_watchdog; + adapter->watchdog_timer.function = e1000_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_info_timer); - adapter->phy_info_timer.function = &e1000_update_phy_info; + adapter->phy_info_timer.function = e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, e1000_reset_task); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2b8ef44bd2b1..5f3eac6432cb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5745,11 +5745,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &e1000_watchdog; + adapter->watchdog_timer.function = e1000_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_info_timer); - adapter->phy_info_timer.function = &e1000_update_phy_info; + adapter->phy_info_timer.function = e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->reset_task, e1000_reset_task); diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 2b98ee80fa33..043d99013056 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3721,7 +3721,7 @@ int __init ehea_module_init(void) if (ret) ehea_info("failed registering memory remove notifier"); - ret = crash_shutdown_register(&ehea_crash_handler); + ret = crash_shutdown_register(ehea_crash_handler); if (ret) ehea_info("failed registering crash handler"); @@ -3746,7 +3746,7 @@ out3: out2: unregister_memory_notifier(&ehea_mem_nb); unregister_reboot_notifier(&ehea_reboot_nb); - crash_shutdown_unregister(&ehea_crash_handler); + crash_shutdown_unregister(ehea_crash_handler); out: return ret; } @@ -3759,7 +3759,7 @@ static void __exit ehea_module_exit(void) driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); unregister_reboot_notifier(&ehea_reboot_nb); - ret = crash_shutdown_unregister(&ehea_crash_handler); + ret = crash_shutdown_unregister(ehea_crash_handler); if (ret) ehea_info("failed unregistering crash handler"); unregister_memory_notifier(&ehea_mem_nb); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 57c8ac0ef3f1..32543a300b81 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -758,7 +758,7 @@ static int epic_open(struct net_device *dev) init_timer(&ep->timer); ep->timer.expires = jiffies + 3*HZ; ep->timer.data = (unsigned long)dev; - ep->timer.function = &epic_timer; /* timer handler */ + ep->timer.function = epic_timer; /* timer handler */ add_timer(&ep->timer); return 0; diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index d7e8f6b8f4cf..dd54abe2f710 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -915,14 +915,14 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = RUN_AT(3 * HZ); np->timer.data = (unsigned long) dev; - np->timer.function = &netdev_timer; + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); init_timer(&np->reset_timer); np->reset_timer.data = (unsigned long) dev; - np->reset_timer.function = &reset_timer; + np->reset_timer.function = reset_timer; np->reset_timer_armed = 0; return 0; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 4da05b1b445c..6a44fe411589 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5440,13 +5440,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i init_timer(&np->oom_kick); np->oom_kick.data = (unsigned long) dev; - np->oom_kick.function = &nv_do_rx_refill; /* timer handler */ + np->oom_kick.function = nv_do_rx_refill; /* timer handler */ init_timer(&np->nic_poll); np->nic_poll.data = (unsigned long) dev; - np->nic_poll.function = &nv_do_nic_poll; /* timer handler */ + np->nic_poll.function = nv_do_nic_poll; /* timer handler */ init_timer(&np->stats_poll); np->stats_poll.data = (unsigned long) dev; - np->stats_poll.function = &nv_do_stats_poll; /* timer handler */ + np->stats_poll.function = nv_do_stats_poll; /* timer handler */ err = pci_enable_device(pci_dev); if (err) diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 49aac7027fbb..9a6485892b3d 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1004,7 +1004,7 @@ static int hamachi_open(struct net_device *dev) init_timer(&hmp->timer); hmp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */ hmp->timer.data = (unsigned long)dev; - hmp->timer.function = &hamachi_timer; /* timer handler */ + hmp->timer.function = hamachi_timer; /* timer handler */ add_timer(&hmp->timer); return 0; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 86ececd3c658..d15d2f2ba78e 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -204,10 +204,10 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) ei_status.rx_start_page = HP_START_PG + TX_PAGES; ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG; - ei_status.reset_8390 = &hp_reset_8390; - ei_status.get_8390_hdr = &hp_get_8390_hdr; - ei_status.block_input = &hp_block_input; - ei_status.block_output = &hp_block_output; + ei_status.reset_8390 = hp_reset_8390; + ei_status.get_8390_hdr = hp_get_8390_hdr; + ei_status.block_input = hp_block_input; + ei_status.block_output = hp_block_output; hp_init_card(dev); retval = register_netdev(dev); diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 07d8e5b634f3..376e953c6ce6 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -155,10 +155,10 @@ static int __devinit hydra_init(struct zorro_dev *z) ei_status.rx_start_page = start_page + TX_PAGES; - ei_status.reset_8390 = &hydra_reset_8390; - ei_status.block_input = &hydra_block_input; - ei_status.block_output = &hydra_block_output; - ei_status.get_8390_hdr = &hydra_get_8390_hdr; + ei_status.reset_8390 = hydra_reset_8390; + ei_status.block_input = hydra_block_input; + ei_status.block_output = hydra_block_output; + ei_status.get_8390_hdr = hydra_get_8390_hdr; ei_status.reg_offset = hydra_offsets; dev->netdev_ops = &hydra_netdev_ops; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 985e37cf17b6..d35cc38bf8b2 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1888,9 +1888,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, goto err_eeprom; } - setup_timer(&adapter->watchdog_timer, &igb_watchdog, + setup_timer(&adapter->watchdog_timer, igb_watchdog, (unsigned long) adapter); - setup_timer(&adapter->phy_info_timer, &igb_update_phy_info, + setup_timer(&adapter->phy_info_timer, igb_update_phy_info, (unsigned long) adapter); INIT_WORK(&adapter->reset_task, igb_reset_task); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 0b3f6df5cff7..c8ee8d28767b 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -827,7 +827,7 @@ static void ioc3_mii_start(struct ioc3_private *ip) { ip->ioc3_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */ ip->ioc3_timer.data = (unsigned long) ip; - ip->ioc3_timer.function = &ioc3_timer; + ip->ioc3_timer.function = ioc3_timer; add_timer(&ip->ioc3_timer); } diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 45fc89b9ba64..33c4ffe6e103 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -470,7 +470,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgb_watchdog; + adapter->watchdog_timer.function = ixgb_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 18163e312a39..5e4dc1b0a1bd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6730,7 +6730,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, * which might start the timer */ init_timer(&adapter->sfp_timer); - adapter->sfp_timer.function = &ixgbe_sfp_timer; + adapter->sfp_timer.function = ixgbe_sfp_timer; adapter->sfp_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task); @@ -6862,7 +6862,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->mac.ops.disable_tx_laser(hw); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgbe_watchdog; + adapter->watchdog_timer.function = ixgbe_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, ixgbe_reset_task); diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 918c00359b0a..5d3c869283a5 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3426,7 +3426,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, } init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgbevf_watchdog; + adapter->watchdog_timer.function = ixgbevf_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, ixgbevf_reset_task); diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 3832fa4961dd..f84f5e6ededb 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -562,19 +562,19 @@ static int __init mac8390_initdev(struct net_device *dev, case ACCESS_16: /* 16 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; break; case ACCESS_32: /* 32 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &sane_block_input; - ei_status.block_output = &sane_block_output; - ei_status.get_8390_hdr = &sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = sane_block_input; + ei_status.block_output = sane_block_output; + ei_status.get_8390_hdr = sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; access_bitmode = 1; break; @@ -586,19 +586,19 @@ static int __init mac8390_initdev(struct net_device *dev, * but overwrite system memory when run at 32 bit. * so we run them all at 16 bit. */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; break; case MAC8390_CABLETRON: /* 16 bit card, register map is short forward */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd2_offsets; break; @@ -606,19 +606,19 @@ static int __init mac8390_initdev(struct net_device *dev, case MAC8390_KINETICS: /* 16 bit memory, register map is forward */ /* dayna and similar */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &dayna_block_input; - ei_status.block_output = &dayna_block_output; - ei_status.get_8390_hdr = &dayna_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = dayna_block_input; + ei_status.block_output = dayna_block_output; + ei_status.get_8390_hdr = dayna_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; break; case MAC8390_INTERLAN: /* 16 bit memory, register map is forward */ - ei_status.reset_8390 = &interlan_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = interlan_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; break; diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index a6033d48b5cc..2fd39630b1e5 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1570,7 +1570,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ); np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); return 0; diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 56f3fc45dbaa..8dd03439d994 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -1125,7 +1125,7 @@ static int netdrv_open(struct net_device *dev) init_timer(&tp->timer); tp->timer.expires = jiffies + 3 * HZ; tp->timer.data = (unsigned long) dev; - tp->timer.function = &netdrv_timer; + tp->timer.function = netdrv_timer; add_timer(&tp->timer); DPRINTK("EXIT, returning 0\n"); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 9b319be7f1d2..042f6777e6b9 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -707,7 +707,7 @@ static int el3_open(struct net_device *dev) netif_start_queue(dev); tc574_reset(dev); - lp->media.function = &media_check; + lp->media.function = media_check; lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 1c534f392474..7f2baf5eae26 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -538,7 +538,7 @@ static int el3_open(struct net_device *dev) tc589_reset(dev); init_timer(&lp->media); - lp->media.function = &media_check; + lp->media.function = media_check; lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index e97f1519a15f..3f61fde70d73 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -356,10 +356,10 @@ static int axnet_config(struct pcmcia_device *link) ei_status.tx_start_page = AXNET_START_PG; ei_status.rx_start_page = AXNET_START_PG + TX_PAGES; ei_status.stop_page = AXNET_STOP_PG; - ei_status.reset_8390 = &axnet_reset_8390; - ei_status.get_8390_hdr = &get_8390_hdr; - ei_status.block_input = &block_input; - ei_status.block_output = &block_output; + ei_status.reset_8390 = axnet_reset_8390; + ei_status.get_8390_hdr = get_8390_hdr; + ei_status.block_input = block_input; + ei_status.block_output = block_output; if (inb(dev->base_addr + AXNET_TEST) != 0) info->flags |= IS_AX88790; @@ -530,7 +530,7 @@ static int axnet_open(struct net_device *dev) info->link_status = 0x00; init_timer(&info->watchdog); - info->watchdog.function = &ei_watchdog; + info->watchdog.function = ei_watchdog; info->watchdog.data = (u_long)dev; info->watchdog.expires = jiffies + HZ; add_timer(&info->watchdog); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 1815b2644b96..5ad42e0aee25 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -624,7 +624,7 @@ static int pcnet_config(struct pcmcia_device *link) ei_status.name = "NE2000"; ei_status.word16 = 1; - ei_status.reset_8390 = &pcnet_reset_8390; + ei_status.reset_8390 = pcnet_reset_8390; if (info->flags & (IS_DL10019|IS_DL10022)) mii_phy_probe(dev); @@ -957,7 +957,7 @@ static int pcnet_open(struct net_device *dev) info->phy_id = info->eth_phy; info->link_status = 0x00; init_timer(&info->watchdog); - info->watchdog.function = &ei_watchdog; + info->watchdog.function = ei_watchdog; info->watchdog.data = (u_long)dev; info->watchdog.expires = jiffies + HZ; add_timer(&info->watchdog); @@ -1341,9 +1341,9 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg, ei_status.stop_page = stop_pg; /* set up block i/o functions */ - ei_status.get_8390_hdr = &dma_get_8390_hdr; - ei_status.block_input = &dma_block_input; - ei_status.block_output = &dma_block_output; + ei_status.get_8390_hdr = dma_get_8390_hdr; + ei_status.block_input = dma_block_input; + ei_status.block_output = dma_block_output; return 0; } @@ -1489,9 +1489,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, ei_status.stop_page = start_pg + ((req.Size - offset) >> 8); /* set up block i/o functions */ - ei_status.get_8390_hdr = &shmem_get_8390_hdr; - ei_status.block_input = &shmem_block_input; - ei_status.block_output = &shmem_block_output; + ei_status.get_8390_hdr = shmem_get_8390_hdr; + ei_status.block_input = shmem_block_input; + ei_status.block_output = shmem_block_output; info->flags |= USE_SHMEM; return 0; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index cc7a357feac9..3d1c549b7038 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -296,7 +296,7 @@ static const struct net_device_ops smc_netdev_ops = { .ndo_tx_timeout = smc_tx_timeout, .ndo_set_config = s9k_config, .ndo_set_multicast_list = set_rx_mode, - .ndo_do_ioctl = &smc_ioctl, + .ndo_do_ioctl = smc_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -1117,7 +1117,7 @@ static int smc_open(struct net_device *dev) smc_reset(dev); init_timer(&smc->media); - smc->media.function = &media_check; + smc->media.function = media_check; smc->media.data = (u_long) dev; smc->media.expires = jiffies + HZ; add_timer(&smc->media); diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index e26e107f93e0..e68c941926f1 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1245,7 +1245,7 @@ static int rr_open(struct net_device *dev) init_timer(&rrpriv->timer); rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */ rrpriv->timer.data = (unsigned long)dev; - rrpriv->timer.function = &rr_timer; /* timer handler */ + rrpriv->timer.function = rr_timer; /* timer handler */ add_timer(&rrpriv->timer); netif_start_queue(dev); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 79fd02bc69fd..a812efc3632e 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1031,7 +1031,7 @@ static int sh_eth_phy_init(struct net_device *ndev) mdp->duplex = -1; /* Try connect to PHY */ - phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link, + phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev)) { dev_err(&ndev->dev, "phy_connect failed\n"); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index bbbded76ff14..ffdd8591d4bc 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1042,7 +1042,7 @@ sis900_open(struct net_device *net_dev) init_timer(&sis_priv->timer); sis_priv->timer.expires = jiffies + HZ; sis_priv->timer.data = (unsigned long)net_dev; - sis_priv->timer.function = &sis900_timer; + sis_priv->timer.function = sis900_timer; add_timer(&sis_priv->timer); return 0; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 618643e3ca3e..0a6a5ced3c1c 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -617,7 +617,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) bp->timer_ticks = 0; bp->bigmac_timer.expires = jiffies + (12 * HZ) / 10; bp->bigmac_timer.data = (unsigned long) bp; - bp->bigmac_timer.function = &bigmac_timer; + bp->bigmac_timer.function = bigmac_timer; add_timer(&bp->bigmac_timer); } diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 2678588ea4b2..3fa949789b42 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -874,7 +874,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = jiffies + 3*HZ; np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); /* Enable interrupts by setting the interrupt mask. */ diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index d96431eb698b..45f315ed1868 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1409,7 +1409,7 @@ force_link: hp->timer_ticks = 0; hp->happy_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */ hp->happy_timer.data = (unsigned long) hp; - hp->happy_timer.function = &happy_meal_timer; + hp->happy_timer.function = happy_meal_timer; add_timer(&hp->happy_timer); } diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 8dcb858f2168..2cf84e5968b2 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1483,7 +1483,7 @@ no_link_test: */ init_timer(&lp->multicast_timer); lp->multicast_timer.data = (unsigned long) dev; - lp->multicast_timer.function = &lance_set_multicast_retry; + lp->multicast_timer.function = lance_set_multicast_retry; if (register_netdev(dev)) { printk(KERN_ERR "SunLance: Cannot register device.\n"); diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index d808f95a87ca..3128d6a8e9ce 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -92,7 +92,7 @@ static void bdx_rx_free(struct bdx_priv *priv); static void bdx_tx_free(struct bdx_priv *priv); /* Definitions needed by bdx_probe */ -static void bdx_ethtool_ops(struct net_device *netdev); +static void bdx_set_ethtool_ops(struct net_device *netdev); /************************************************************************* * Print Info * @@ -2005,7 +2005,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev->netdev_ops = &bdx_netdev_ops; ndev->tx_queue_len = BDX_NDEV_TXQ_LEN; - bdx_ethtool_ops(ndev); /* ethtool interface */ + bdx_set_ethtool_ops(ndev); /* ethtool interface */ /* these fields are used for info purposes only * so we can have them same for all ports of the board */ @@ -2410,10 +2410,10 @@ static void bdx_get_ethtool_stats(struct net_device *netdev, } /* - * bdx_ethtool_ops - ethtool interface implementation + * bdx_set_ethtool_ops - ethtool interface implementation * @netdev */ -static void bdx_ethtool_ops(struct net_device *netdev) +static void bdx_set_ethtool_ops(struct net_device *netdev) { static const struct ethtool_ops bdx_ethtool_ops = { .get_settings = bdx_get_settings, diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index ccee3eddc5f4..0564ca05963d 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -393,7 +393,7 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) spin_unlock_irqrestore(&priv->lock, flags); return; } - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; if (!in_irq()) spin_unlock_irqrestore(&priv->lock, flags); @@ -1453,7 +1453,7 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); if ( priv->timer.function == NULL ) { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; priv->timerSetAt = jiffies; @@ -1601,7 +1601,7 @@ drop_and_reuse: TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); if ( priv->timer.function == NULL ) { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; priv->timerSetAt = jiffies; @@ -1897,7 +1897,7 @@ static void TLan_Timer( unsigned long data ) TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK ); } else { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY; spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 0bc4f3030a80..a9f7d5d1a269 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -599,7 +599,7 @@ static int dmfe_open(struct DEVICE *dev) init_timer(&db->timer); db->timer.expires = DMFE_TIMER_WUT + HZ * 2; db->timer.data = (unsigned long)dev; - db->timer.function = &dmfe_timer; + db->timer.function = dmfe_timer; add_timer(&db->timer); return 0; diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 96de5829b940..1dc27a557275 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -480,7 +480,7 @@ static int uli526x_open(struct net_device *dev) init_timer(&db->timer); db->timer.expires = ULI526X_TIMER_WUT + HZ * 2; db->timer.data = (unsigned long)dev; - db->timer.function = &uli526x_timer; + db->timer.function = uli526x_timer; add_timer(&db->timer); return 0; diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 66d41cf8da29..f0b231035dee 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -662,7 +662,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = jiffies + 1*HZ; np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); return 0; out_err: diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index e2c6f7f4f51c..43af85b8e45e 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -1105,7 +1105,7 @@ static int lmc_open(struct net_device *dev) init_timer (&sc->timer); sc->timer.expires = jiffies + HZ; sc->timer.data = (unsigned long) dev; - sc->timer.function = &lmc_watchdog; + sc->timer.function = lmc_watchdog; add_timer (&sc->timer); lmc_trace(dev, "lmc_open out"); diff --git a/drivers/net/wd.c b/drivers/net/wd.c index eb72c67699ab..f1549fff0edc 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -342,10 +342,10 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr) printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n", model_name, dev->irq, dev->mem_start, dev->mem_end-1); - ei_status.reset_8390 = &wd_reset_8390; - ei_status.block_input = &wd_block_input; - ei_status.block_output = &wd_block_output; - ei_status.get_8390_hdr = &wd_get_8390_hdr; + ei_status.reset_8390 = wd_reset_8390; + ei_status.block_input = wd_block_input; + ei_status.block_output = wd_block_output; + ei_status.get_8390_hdr = wd_get_8390_hdr; dev->netdev_ops = &wd_netdev_ops; NS8390_init(dev, 0); diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 3bd9cf76517d..d91a831a7700 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -604,7 +604,7 @@ static int dl_startup_params(struct net_device *dev) /* Start kernel timer to wait for dl startup to complete. */ local->timer.expires = jiffies + HZ / 2; local->timer.data = (long)local; - local->timer.function = &verify_dl_startup; + local->timer.function = verify_dl_startup; add_timer(&local->timer); dev_dbg(&link->dev, "ray_cs dl_startup_params started timer for verify_dl_startup\n"); @@ -1981,12 +1981,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) dev_dbg(&link->dev, "ray_cs interrupt network \"%s\" start failed\n", local->sparm.b4.a_current_ess_id); - local->timer.function = &start_net; + local->timer.function = start_net; } else { dev_dbg(&link->dev, "ray_cs interrupt network \"%s\" join failed\n", local->sparm.b4.a_current_ess_id); - local->timer.function = &join_net; + local->timer.function = join_net; } add_timer(&local->timer); } @@ -2454,9 +2454,9 @@ static void authenticate(ray_dev_t *local) del_timer(&local->timer); if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) { - local->timer.function = &join_net; + local->timer.function = join_net; } else { - local->timer.function = &authenticate_timeout; + local->timer.function = authenticate_timeout; } local->timer.expires = jiffies + HZ * 2; local->timer.data = (long)local; @@ -2541,7 +2541,7 @@ static void associate(ray_dev_t *local) del_timer(&local->timer); local->timer.expires = jiffies + HZ * 2; local->timer.data = (long)local; - local->timer.function = &join_net; + local->timer.function = join_net; add_timer(&local->timer); local->card_status = CARD_ASSOC_FAILED; return; diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 4eb67aed68dd..cd1b3dcd61db 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -646,7 +646,7 @@ static int yellowfin_open(struct net_device *dev) init_timer(&yp->timer); yp->timer.expires = jiffies + 3*HZ; yp->timer.data = (unsigned long)dev; - yp->timer.function = &yellowfin_timer; /* timer handler */ + yp->timer.function = yellowfin_timer; /* timer handler */ add_timer(&yp->timer); return 0; -- cgit v1.2.3 From c6a056a349d10a6e879ca1be6067873b6feed259 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 23 Aug 2010 19:44:08 +0000 Subject: bnx2x: small fix in stats handling Use a private variable to fold rx_dropped value, instead of shared destination buffer, as it might break SNMP applications. Signed-off-by: Eric Dumazet CC: Eilon Greenstein CC: Dmitry Kravkov Acked-By: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_stats.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index c74724461020..efa1403ebf82 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -969,6 +969,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) { struct bnx2x_eth_stats *estats = &bp->eth_stats; struct net_device_stats *nstats = &bp->dev->stats; + unsigned long tmp; int i; nstats->rx_packets = @@ -985,10 +986,10 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); - nstats->rx_dropped = estats->mac_discard; + tmp = estats->mac_discard; for_each_queue(bp, i) - nstats->rx_dropped += - le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + nstats->rx_dropped = tmp; nstats->tx_dropped = 0; -- cgit v1.2.3 From 219dd1132a71875ef7097ac47f634d402478385c Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Mon, 23 Aug 2010 20:40:40 +0000 Subject: stmmac: fix_mac_speed is called during 10/100<->1000 speed changes This patch modifies the stmmac_adjust_link() function so the fix_mac_speed() is called not only when link speed is changing between 10 and 100 Mbps (as required in RMII mode) but also for 1000 Mbps. Signed-off-by: Pawel Moll Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index bbb7951b9c4c..86b6c69c068c 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -238,6 +238,9 @@ static void stmmac_adjust_link(struct net_device *dev) case 1000: if (likely(priv->is_gmac)) ctrl &= ~priv->hw->link.port; + if (likely(priv->fix_mac_speed)) + priv->fix_mac_speed(priv->bsp_priv, + phydev->speed); break; case 100: case 10: -- cgit v1.2.3 From ac75791aa943c7953521cb4fa7728bf51f9abd2d Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 23 Aug 2010 20:40:41 +0000 Subject: stmmac: remove dead option in the driver's Kconfig This patch removes the CPU_SUBTYPE_ST40 dependency in the driver's Kconfig. In fact, this option has been removed in the commit: f96691872439ab2071171d4531c4a95b5d493ae5 as reported by Christian Dietrich. Note that the driver remains tested on STM platforms, only. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig index eb63d44748a7..643968098afd 100644 --- a/drivers/net/stmmac/Kconfig +++ b/drivers/net/stmmac/Kconfig @@ -3,10 +3,10 @@ config STMMAC_ETH select MII select PHYLIB select CRC32 - depends on NETDEVICES && CPU_SUBTYPE_ST40 + depends on NETDEVICES help This is the driver for the Ethernet IPs are built around a - Synopsys IP Core and fully tested on the STMicroelectronics + Synopsys IP Core and only tested on the STMicroelectronics platforms. if STMMAC_ETH -- cgit v1.2.3 From ad01b7d480a4a135f974afd5c617c417e0b0542f Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 23 Aug 2010 20:40:42 +0000 Subject: stmmac: make ioaddr 'void __iomem *' rather than unsigned long This avoids unnecessary casting and adds the ioaddr in the private structure. This patch also removes many warning when compile the driver. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/common.h | 50 +++++++-------- drivers/net/stmmac/dwmac1000_core.c | 18 +++--- drivers/net/stmmac/dwmac1000_dma.c | 8 +-- drivers/net/stmmac/dwmac100_core.c | 20 +++--- drivers/net/stmmac/dwmac100_dma.c | 8 +-- drivers/net/stmmac/dwmac_dma.h | 16 ++--- drivers/net/stmmac/dwmac_lib.c | 22 +++---- drivers/net/stmmac/enh_desc.c | 2 +- drivers/net/stmmac/norm_desc.c | 2 +- drivers/net/stmmac/stmmac.h | 3 +- drivers/net/stmmac/stmmac_ethtool.c | 21 +++--- drivers/net/stmmac/stmmac_main.c | 124 +++++++++++++++++------------------- drivers/net/stmmac/stmmac_mdio.c | 21 +++--- include/linux/stmmac.h | 2 +- 14 files changed, 153 insertions(+), 164 deletions(-) diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index 66b9da0260fe..e8cbcb5c206e 100644 --- a/drivers/net/stmmac/common.h +++ b/drivers/net/stmmac/common.h @@ -167,7 +167,7 @@ struct stmmac_desc_ops { int (*get_tx_ls) (struct dma_desc *p); /* Return the transmit status looking at the TDES1 */ int (*tx_status) (void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr); + struct dma_desc *p, void __iomem *ioaddr); /* Get the buffer size from the descriptor */ int (*get_tx_len) (struct dma_desc *p); /* Handle extra events on specific interrupts hw dependent */ @@ -182,44 +182,44 @@ struct stmmac_desc_ops { struct stmmac_dma_ops { /* DMA core initialization */ - int (*init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx); + int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx); /* Dump DMA registers */ - void (*dump_regs) (unsigned long ioaddr); + void (*dump_regs) (void __iomem *ioaddr); /* Set tx/rx threshold in the csr6 register * An invalid value enables the store-and-forward mode */ - void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode); + void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode); /* To track extra statistic (if supported) */ void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, - unsigned long ioaddr); - void (*enable_dma_transmission) (unsigned long ioaddr); - void (*enable_dma_irq) (unsigned long ioaddr); - void (*disable_dma_irq) (unsigned long ioaddr); - void (*start_tx) (unsigned long ioaddr); - void (*stop_tx) (unsigned long ioaddr); - void (*start_rx) (unsigned long ioaddr); - void (*stop_rx) (unsigned long ioaddr); - int (*dma_interrupt) (unsigned long ioaddr, + void __iomem *ioaddr); + void (*enable_dma_transmission) (void __iomem *ioaddr); + void (*enable_dma_irq) (void __iomem *ioaddr); + void (*disable_dma_irq) (void __iomem *ioaddr); + void (*start_tx) (void __iomem *ioaddr); + void (*stop_tx) (void __iomem *ioaddr); + void (*start_rx) (void __iomem *ioaddr); + void (*stop_rx) (void __iomem *ioaddr); + int (*dma_interrupt) (void __iomem *ioaddr, struct stmmac_extra_stats *x); }; struct stmmac_ops { /* MAC core initialization */ - void (*core_init) (unsigned long ioaddr) ____cacheline_aligned; + void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned; /* Dump MAC registers */ - void (*dump_regs) (unsigned long ioaddr); + void (*dump_regs) (void __iomem *ioaddr); /* Handle extra events on specific interrupts hw dependent */ - void (*host_irq_status) (unsigned long ioaddr); + void (*host_irq_status) (void __iomem *ioaddr); /* Multicast filter setting */ void (*set_filter) (struct net_device *dev); /* Flow control setting */ - void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex, + void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time); /* Set power management mode (e.g. magic frame) */ - void (*pmt) (unsigned long ioaddr, unsigned long mode); + void (*pmt) (void __iomem *ioaddr, unsigned long mode); /* Set/Get Unicast MAC addresses */ - void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr, + void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n); - void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr, + void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n); }; @@ -243,11 +243,11 @@ struct mac_device_info { struct mac_link link; }; -struct mac_device_info *dwmac1000_setup(unsigned long addr); -struct mac_device_info *dwmac100_setup(unsigned long addr); +struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr); +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr); -extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], +extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); -extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, +extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low); -extern void dwmac_dma_flush_tx_fifo(unsigned long ioaddr); +extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 2b2f5c8caf1c..8bbfc0f48dea 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -30,7 +30,7 @@ #include #include "dwmac1000.h" -static void dwmac1000_core_init(unsigned long ioaddr) +static void dwmac1000_core_init(void __iomem *ioaddr) { u32 value = readl(ioaddr + GMAC_CONTROL); value |= GMAC_CORE_INIT; @@ -50,7 +50,7 @@ static void dwmac1000_core_init(unsigned long ioaddr) #endif } -static void dwmac1000_dump_regs(unsigned long ioaddr) +static void dwmac1000_dump_regs(void __iomem *ioaddr) { int i; pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr); @@ -62,14 +62,14 @@ static void dwmac1000_dump_regs(unsigned long ioaddr) } } -static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), GMAC_ADDR_LOW(reg_n)); } -static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), @@ -78,7 +78,7 @@ static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr, static void dwmac1000_set_filter(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; + void __iomem *ioaddr = (void __iomem *) dev->base_addr; unsigned int value = 0; CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", @@ -139,7 +139,7 @@ static void dwmac1000_set_filter(struct net_device *dev) readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW)); } -static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex, +static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time) { unsigned int flow = 0; @@ -162,7 +162,7 @@ static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex, writel(flow, ioaddr + GMAC_FLOW_CTRL); } -static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode) +static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode) { unsigned int pmt = 0; @@ -178,7 +178,7 @@ static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode) } -static void dwmac1000_irq_status(unsigned long ioaddr) +static void dwmac1000_irq_status(void __iomem *ioaddr) { u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); @@ -211,7 +211,7 @@ struct stmmac_ops dwmac1000_ops = { .get_umac_addr = dwmac1000_get_umac_addr, }; -struct mac_device_info *dwmac1000_setup(unsigned long ioaddr) +struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr) { struct mac_device_info *mac; u32 uid = readl(ioaddr + GMAC_VERSION); diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c index 415805057cb0..2ef5a56370e9 100644 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ b/drivers/net/stmmac/dwmac1000_dma.c @@ -29,7 +29,7 @@ #include "dwmac1000.h" #include "dwmac_dma.h" -static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, +static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); @@ -58,7 +58,7 @@ static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, return 0; } -static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode, +static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode, int rxmode) { u32 csr6 = readl(ioaddr + DMA_CONTROL); @@ -111,12 +111,12 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode, /* Not yet implemented --- no RMON module */ static void dwmac1000_dma_diagnostic_fr(void *data, - struct stmmac_extra_stats *x, unsigned long ioaddr) + struct stmmac_extra_stats *x, void __iomem *ioaddr) { return; } -static void dwmac1000_dump_dma_regs(unsigned long ioaddr) +static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) { int i; pr_info(" DMA registers\n"); diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index 2fb165fa2ba0..135a8082816e 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -31,7 +31,7 @@ #include #include "dwmac100.h" -static void dwmac100_core_init(unsigned long ioaddr) +static void dwmac100_core_init(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CONTROL); @@ -42,12 +42,12 @@ static void dwmac100_core_init(unsigned long ioaddr) #endif } -static void dwmac100_dump_mac_regs(unsigned long ioaddr) +static void dwmac100_dump_mac_regs(void __iomem *ioaddr) { pr_info("\t----------------------------------------------\n" "\t DWMAC 100 CSR (base addr = 0x%8x)\n" "\t----------------------------------------------\n", - (unsigned int)ioaddr); + (unsigned int) ioaddr); pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL, readl(ioaddr + MAC_CONTROL)); pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH, @@ -77,18 +77,18 @@ static void dwmac100_dump_mac_regs(unsigned long ioaddr) MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK)); } -static void dwmac100_irq_status(unsigned long ioaddr) +static void dwmac100_irq_status(void __iomem *ioaddr) { return; } -static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); @@ -96,7 +96,7 @@ static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr, static void dwmac100_set_filter(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; + void __iomem *ioaddr = (void __iomem *) dev->base_addr; u32 value = readl(ioaddr + MAC_CONTROL); if (dev->flags & IFF_PROMISC) { @@ -145,7 +145,7 @@ static void dwmac100_set_filter(struct net_device *dev) readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW)); } -static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex, +static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time) { unsigned int flow = MAC_FLOW_CTRL_ENABLE; @@ -158,7 +158,7 @@ static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex, /* No PMT module supported for this Ethernet Controller. * Tested on ST platforms only. */ -static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode) +static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode) { return; } @@ -174,7 +174,7 @@ struct stmmac_ops dwmac100_ops = { .get_umac_addr = dwmac100_get_umac_addr, }; -struct mac_device_info *dwmac100_setup(unsigned long ioaddr) +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) { struct mac_device_info *mac; diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c index 2fece7b72727..c7279d2b946b 100644 --- a/drivers/net/stmmac/dwmac100_dma.c +++ b/drivers/net/stmmac/dwmac100_dma.c @@ -31,7 +31,7 @@ #include "dwmac100.h" #include "dwmac_dma.h" -static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, +static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); @@ -58,7 +58,7 @@ static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, /* Store and Forward capability is not used at all.. * The transmit threshold can be programmed by * setting the TTC bits in the DMA control register.*/ -static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode, +static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode, int rxmode) { u32 csr6 = readl(ioaddr + DMA_CONTROL); @@ -73,7 +73,7 @@ static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode, writel(csr6, ioaddr + DMA_CONTROL); } -static void dwmac100_dump_dma_regs(unsigned long ioaddr) +static void dwmac100_dump_dma_regs(void __iomem *ioaddr) { int i; @@ -91,7 +91,7 @@ static void dwmac100_dump_dma_regs(unsigned long ioaddr) /* DMA controller has two counters to track the number of * the receive missed frames. */ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x, - unsigned long ioaddr) + void __iomem *ioaddr) { struct net_device_stats *stats = (struct net_device_stats *)data; u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR); diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h index 7b815a1b7b8c..da3f5ccf83d3 100644 --- a/drivers/net/stmmac/dwmac_dma.h +++ b/drivers/net/stmmac/dwmac_dma.h @@ -97,12 +97,12 @@ #define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ #define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ -extern void dwmac_enable_dma_transmission(unsigned long ioaddr); -extern void dwmac_enable_dma_irq(unsigned long ioaddr); -extern void dwmac_disable_dma_irq(unsigned long ioaddr); -extern void dwmac_dma_start_tx(unsigned long ioaddr); -extern void dwmac_dma_stop_tx(unsigned long ioaddr); -extern void dwmac_dma_start_rx(unsigned long ioaddr); -extern void dwmac_dma_stop_rx(unsigned long ioaddr); -extern int dwmac_dma_interrupt(unsigned long ioaddr, +extern void dwmac_enable_dma_transmission(void __iomem *ioaddr); +extern void dwmac_enable_dma_irq(void __iomem *ioaddr); +extern void dwmac_disable_dma_irq(void __iomem *ioaddr); +extern void dwmac_dma_start_tx(void __iomem *ioaddr); +extern void dwmac_dma_stop_tx(void __iomem *ioaddr); +extern void dwmac_dma_start_rx(void __iomem *ioaddr); +extern void dwmac_dma_stop_rx(void __iomem *ioaddr); +extern int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x); diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c index a85415216ef4..d65fab1ba790 100644 --- a/drivers/net/stmmac/dwmac_lib.c +++ b/drivers/net/stmmac/dwmac_lib.c @@ -32,43 +32,43 @@ #endif /* CSR1 enables the transmit DMA to check for new descriptor */ -void dwmac_enable_dma_transmission(unsigned long ioaddr) +void dwmac_enable_dma_transmission(void __iomem *ioaddr) { writel(1, ioaddr + DMA_XMT_POLL_DEMAND); } -void dwmac_enable_dma_irq(unsigned long ioaddr) +void dwmac_enable_dma_irq(void __iomem *ioaddr) { writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); } -void dwmac_disable_dma_irq(unsigned long ioaddr) +void dwmac_disable_dma_irq(void __iomem *ioaddr) { writel(0, ioaddr + DMA_INTR_ENA); } -void dwmac_dma_start_tx(unsigned long ioaddr) +void dwmac_dma_start_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value |= DMA_CONTROL_ST; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_stop_tx(unsigned long ioaddr) +void dwmac_dma_stop_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value &= ~DMA_CONTROL_ST; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_start_rx(unsigned long ioaddr) +void dwmac_dma_start_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value |= DMA_CONTROL_SR; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_stop_rx(unsigned long ioaddr) +void dwmac_dma_stop_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value &= ~DMA_CONTROL_SR; @@ -145,7 +145,7 @@ static void show_rx_process_state(unsigned int status) } #endif -int dwmac_dma_interrupt(unsigned long ioaddr, +int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x) { int ret = 0; @@ -219,7 +219,7 @@ int dwmac_dma_interrupt(unsigned long ioaddr, return ret; } -void dwmac_dma_flush_tx_fifo(unsigned long ioaddr) +void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr) { u32 csr6 = readl(ioaddr + DMA_CONTROL); writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL); @@ -227,7 +227,7 @@ void dwmac_dma_flush_tx_fifo(unsigned long ioaddr) do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF)); } -void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], +void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low) { unsigned long data; @@ -238,7 +238,7 @@ void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], writel(data, ioaddr + low); } -void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, +void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low) { unsigned int hi_addr, lo_addr; diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c index f612f986a7e1..77ff88c3958b 100644 --- a/drivers/net/stmmac/enh_desc.c +++ b/drivers/net/stmmac/enh_desc.c @@ -25,7 +25,7 @@ #include "common.h" static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr) + struct dma_desc *p, void __iomem *ioaddr) { int ret = 0; struct net_device_stats *stats = (struct net_device_stats *)data; diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c index 31ad53643792..51f4440ab98b 100644 --- a/drivers/net/stmmac/norm_desc.c +++ b/drivers/net/stmmac/norm_desc.c @@ -25,7 +25,7 @@ #include "common.h" static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr) + struct dma_desc *p, void __iomem *ioaddr) { int ret = 0; struct net_device_stats *stats = (struct net_device_stats *)data; diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index ebebc644b1b8..cca53dbac361 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -54,6 +54,7 @@ struct stmmac_priv { unsigned int dma_buf_sz; struct device *device; struct mac_device_info *hw; + void __iomem *ioaddr; struct stmmac_extra_stats xstats; struct napi_struct napi; @@ -65,7 +66,7 @@ struct stmmac_priv { int phy_mask; int (*phy_reset) (void *priv); void (*fix_mac_speed) (void *priv, unsigned int speed); - void (*bus_setup)(unsigned long ioaddr); + void (*bus_setup)(void __iomem *ioaddr); void *bsp_priv; int phy_irq; diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index f080509923f0..63b68e61afce 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -177,21 +177,21 @@ void stmmac_ethtool_gregs(struct net_device *dev, if (!priv->is_gmac) { /* MAC registers */ for (i = 0; i < 12; i++) - reg_space[i] = readl(dev->base_addr + (i * 4)); + reg_space[i] = readl(priv->ioaddr + (i * 4)); /* DMA registers */ for (i = 0; i < 9; i++) reg_space[i + 12] = - readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); - reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR); - reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR); + readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); + reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR); + reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR); } else { /* MAC registers */ for (i = 0; i < 55; i++) - reg_space[i] = readl(dev->base_addr + (i * 4)); + reg_space[i] = readl(priv->ioaddr + (i * 4)); /* DMA registers */ for (i = 0; i < 22; i++) reg_space[i + 55] = - readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); + readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); } } @@ -263,11 +263,9 @@ stmmac_set_pauseparam(struct net_device *netdev, cmd.phy_address = phy->addr; ret = phy_ethtool_sset(phy, &cmd); } - } else { - unsigned long ioaddr = netdev->base_addr; - priv->hw->mac->flow_ctrl(ioaddr, phy->duplex, + } else + priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex, priv->flow_ctrl, priv->pause); - } spin_unlock(&priv->lock); return ret; } @@ -276,12 +274,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 *data) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; int i; /* Update HW stats if supported */ priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats, - ioaddr); + priv->ioaddr); for (i = 0; i < STMMAC_STATS_LEN; i++) { char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 86b6c69c068c..c59c1061252a 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -202,7 +202,6 @@ static void stmmac_adjust_link(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phydev = priv->phydev; - unsigned long ioaddr = dev->base_addr; unsigned long flags; int new_state = 0; unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; @@ -215,7 +214,7 @@ static void stmmac_adjust_link(struct net_device *dev) spin_lock_irqsave(&priv->lock, flags); if (phydev->link) { - u32 ctrl = readl(ioaddr + MAC_CTRL_REG); + u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); /* Now we make sure that we can be in full duplex mode. * If not, we operate in half-duplex mode. */ @@ -229,7 +228,7 @@ static void stmmac_adjust_link(struct net_device *dev) } /* Flow Control operation */ if (phydev->pause) - priv->hw->mac->flow_ctrl(ioaddr, phydev->duplex, + priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, fc, pause_time); if (phydev->speed != priv->speed) { @@ -268,7 +267,7 @@ static void stmmac_adjust_link(struct net_device *dev) priv->speed = phydev->speed; } - writel(ctrl, ioaddr + MAC_CTRL_REG); + writel(ctrl, priv->ioaddr + MAC_CTRL_REG); if (!priv->oldlink) { new_state = 1; @@ -345,7 +344,7 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } -static inline void stmmac_mac_enable_rx(unsigned long ioaddr) +static inline void stmmac_mac_enable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value |= MAC_RNABLE_RX; @@ -353,7 +352,7 @@ static inline void stmmac_mac_enable_rx(unsigned long ioaddr) writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_enable_tx(unsigned long ioaddr) +static inline void stmmac_mac_enable_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value |= MAC_ENABLE_TX; @@ -361,14 +360,14 @@ static inline void stmmac_mac_enable_tx(unsigned long ioaddr) writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_disable_rx(unsigned long ioaddr) +static inline void stmmac_mac_disable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value &= ~MAC_RNABLE_RX; writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_disable_tx(unsigned long ioaddr) +static inline void stmmac_mac_disable_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value &= ~MAC_ENABLE_TX; @@ -577,17 +576,17 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { if (!priv->is_gmac) { /* MAC 10/100 */ - priv->hw->dma->dma_mode(priv->dev->base_addr, tc, 0); + priv->hw->dma->dma_mode(priv->ioaddr, tc, 0); priv->tx_coe = NO_HW_CSUM; } else { if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) { - priv->hw->dma->dma_mode(priv->dev->base_addr, + priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); tc = SF_DMA_MODE; priv->tx_coe = HW_CSUM; } else { /* Checksum computation is performed in software. */ - priv->hw->dma->dma_mode(priv->dev->base_addr, tc, + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); priv->tx_coe = NO_HW_CSUM; } @@ -603,7 +602,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) static void stmmac_tx(struct stmmac_priv *priv) { unsigned int txsize = priv->dma_tx_size; - unsigned long ioaddr = priv->dev->base_addr; while (priv->dirty_tx != priv->cur_tx) { int last; @@ -621,7 +619,7 @@ static void stmmac_tx(struct stmmac_priv *priv) int tx_error = priv->hw->desc->tx_status(&priv->dev->stats, &priv->xstats, p, - ioaddr); + priv->ioaddr); if (likely(tx_error == 0)) { priv->dev->stats.tx_packets++; priv->xstats.tx_pkt_n++; @@ -677,7 +675,7 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv) priv->tm->timer_start(tmrate); else #endif - priv->hw->dma->enable_dma_irq(priv->dev->base_addr); + priv->hw->dma->enable_dma_irq(priv->ioaddr); } static inline void stmmac_disable_irq(struct stmmac_priv *priv) @@ -687,7 +685,7 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv) priv->tm->timer_stop(); else #endif - priv->hw->dma->disable_dma_irq(priv->dev->base_addr); + priv->hw->dma->disable_dma_irq(priv->ioaddr); } static int stmmac_has_work(struct stmmac_priv *priv) @@ -742,14 +740,15 @@ static void stmmac_no_timer_stopped(void) */ static void stmmac_tx_err(struct stmmac_priv *priv) { + netif_stop_queue(priv->dev); - priv->hw->dma->stop_tx(priv->dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); dma_free_tx_skbufs(priv); priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); priv->dirty_tx = 0; priv->cur_tx = 0; - priv->hw->dma->start_tx(priv->dev->base_addr); + priv->hw->dma->start_tx(priv->ioaddr); priv->dev->stats.tx_errors++; netif_wake_queue(priv->dev); @@ -758,11 +757,9 @@ static void stmmac_tx_err(struct stmmac_priv *priv) static void stmmac_dma_interrupt(struct stmmac_priv *priv) { - unsigned long ioaddr = priv->dev->base_addr; int status; - status = priv->hw->dma->dma_interrupt(priv->dev->base_addr, - &priv->xstats); + status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); if (likely(status == handle_tx_rx)) _stmmac_schedule(priv); @@ -770,7 +767,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) /* Try to bump up the dma threshold on this failure */ if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { tc += 64; - priv->hw->dma->dma_mode(ioaddr, tc, SF_DMA_MODE); + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); priv->xstats.threshold = tc; } stmmac_tx_err(priv); @@ -790,7 +787,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) static int stmmac_open(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; int ret; /* Check that the MAC address is valid. If its not, refuse @@ -846,7 +842,8 @@ static int stmmac_open(struct net_device *dev) init_dma_desc_rings(dev); /* DMA initialization and SW reset */ - if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy, + if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl, + priv->dma_tx_phy, priv->dma_rx_phy) < 0)) { pr_err("%s: DMA initialization failed\n", __func__); @@ -854,22 +851,22 @@ static int stmmac_open(struct net_device *dev) } /* Copy the MAC addr into the HW */ - priv->hw->mac->set_umac_addr(ioaddr, dev->dev_addr, 0); + priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); /* If required, perform hw setup of the bus. */ if (priv->bus_setup) - priv->bus_setup(ioaddr); + priv->bus_setup(priv->ioaddr); /* Initialize the MAC Core */ - priv->hw->mac->core_init(ioaddr); + priv->hw->mac->core_init(priv->ioaddr); priv->shutdown = 0; /* Initialise the MMC (if present) to disable all interrupts. */ - writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK); - writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK); + writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); + writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); /* Enable the MAC Rx/Tx */ - stmmac_mac_enable_rx(ioaddr); - stmmac_mac_enable_tx(ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); /* Set the HW DMA mode and the COE */ stmmac_dma_operation_mode(priv); @@ -880,16 +877,16 @@ static int stmmac_open(struct net_device *dev) /* Start the ball rolling... */ DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); - priv->hw->dma->start_tx(ioaddr); - priv->hw->dma->start_rx(ioaddr); + priv->hw->dma->start_tx(priv->ioaddr); + priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_start(tmrate); #endif /* Dump DMA/MAC registers */ if (netif_msg_hw(priv)) { - priv->hw->mac->dump_regs(ioaddr); - priv->hw->dma->dump_regs(ioaddr); + priv->hw->mac->dump_regs(priv->ioaddr); + priv->hw->dma->dump_regs(priv->ioaddr); } if (priv->phydev) @@ -933,15 +930,15 @@ static int stmmac_release(struct net_device *dev) free_irq(dev->irq, dev); /* Stop TX/RX DMA and clear the descriptors */ - priv->hw->dma->stop_tx(dev->base_addr); - priv->hw->dma->stop_rx(dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); /* Release and free the Rx/Tx resources */ free_dma_desc_resources(priv); /* Disable the MAC core */ - stmmac_mac_disable_tx(dev->base_addr); - stmmac_mac_disable_rx(dev->base_addr); + stmmac_mac_disable_tx(priv->ioaddr); + stmmac_mac_disable_rx(priv->ioaddr); netif_carrier_off(dev); @@ -1143,7 +1140,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += skb->len; - priv->hw->dma->enable_dma_transmission(dev->base_addr); + priv->hw->dma->enable_dma_transmission(priv->ioaddr); return NETDEV_TX_OK; } @@ -1408,11 +1405,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_NONE; } - if (priv->is_gmac) { - unsigned long ioaddr = dev->base_addr; + if (priv->is_gmac) /* To handle GMAC own interrupts */ - priv->hw->mac->host_irq_status(ioaddr); - } + priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); stmmac_dma_interrupt(priv); @@ -1525,7 +1520,8 @@ static int stmmac_probe(struct net_device *dev) netif_napi_add(dev, &priv->napi, stmmac_poll, 64); /* Get the MAC address */ - priv->hw->mac->get_umac_addr(dev->base_addr, dev->dev_addr, 0); + priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr, + dev->dev_addr, 0); if (!is_valid_ether_addr(dev->dev_addr)) pr_warning("\tno valid MAC address;" @@ -1555,14 +1551,13 @@ static int stmmac_probe(struct net_device *dev) static int stmmac_mac_device_setup(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; struct mac_device_info *device; if (priv->is_gmac) - device = dwmac1000_setup(ioaddr); + device = dwmac1000_setup(priv->ioaddr); else - device = dwmac100_setup(ioaddr); + device = dwmac100_setup(priv->ioaddr); if (!device) return -ENOMEM; @@ -1656,7 +1651,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; - unsigned int *addr = NULL; + void __iomem *addr = NULL; struct net_device *ndev = NULL; struct stmmac_priv *priv; struct plat_stmmacenet_data *plat_dat; @@ -1711,6 +1706,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->pbl = plat_dat->pbl; /* TLI */ priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ priv->enh_desc = plat_dat->enh_desc; + priv->ioaddr = addr; platform_set_drvdata(pdev, ndev); @@ -1782,11 +1778,11 @@ static int stmmac_dvr_remove(struct platform_device *pdev) pr_info("%s:\n\tremoving driver", __func__); - priv->hw->dma->stop_rx(ndev->base_addr); - priv->hw->dma->stop_tx(ndev->base_addr); + priv->hw->dma->stop_rx(priv->ioaddr); + priv->hw->dma->stop_tx(priv->ioaddr); - stmmac_mac_disable_rx(ndev->base_addr); - stmmac_mac_disable_tx(ndev->base_addr); + stmmac_mac_disable_rx(priv->ioaddr); + stmmac_mac_disable_tx(priv->ioaddr); netif_carrier_off(ndev); @@ -1795,7 +1791,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - iounmap((void *)ndev->base_addr); + iounmap((void *)priv->ioaddr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); @@ -1830,22 +1826,21 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) napi_disable(&priv->napi); /* Stop TX/RX DMA */ - priv->hw->dma->stop_tx(dev->base_addr); - priv->hw->dma->stop_rx(dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); /* Clear the Rx/Tx descriptors */ priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, dis_ic); priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); - stmmac_mac_disable_tx(dev->base_addr); + stmmac_mac_disable_tx(priv->ioaddr); if (device_may_wakeup(&(pdev->dev))) { /* Enable Power down mode by programming the PMT regs */ if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(dev->base_addr, - priv->wolopts); + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); } else { - stmmac_mac_disable_rx(dev->base_addr); + stmmac_mac_disable_rx(priv->ioaddr); } } else { priv->shutdown = 1; @@ -1863,7 +1858,6 @@ static int stmmac_resume(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; if (!netif_running(dev)) return 0; @@ -1884,15 +1878,15 @@ static int stmmac_resume(struct platform_device *pdev) * from another devices (e.g. serial console). */ if (device_may_wakeup(&(pdev->dev))) if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(dev->base_addr, 0); + priv->hw->mac->pmt(priv->ioaddr, 0); netif_device_attach(dev); /* Enable the MAC and DMA */ - stmmac_mac_enable_rx(ioaddr); - stmmac_mac_enable_tx(ioaddr); - priv->hw->dma->start_tx(ioaddr); - priv->hw->dma->start_rx(ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); + priv->hw->dma->start_tx(priv->ioaddr); + priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_start(tmrate); diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 40b2c7929719..03dea1401571 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -47,7 +47,6 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; unsigned int mii_data = priv->hw->mii.data; @@ -56,12 +55,12 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) ((phyreg << 6) & (0x000007C0))); regValue |= MII_BUSY; /* in case of GMAC */ - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); - writel(regValue, ioaddr + mii_address); - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); + writel(regValue, priv->ioaddr + mii_address); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); /* Read the data from the MII data register */ - data = (int)readl(ioaddr + mii_data); + data = (int)readl(priv->ioaddr + mii_data); return data; } @@ -79,7 +78,6 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; unsigned int mii_data = priv->hw->mii.data; @@ -90,14 +88,14 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, value |= MII_BUSY; /* Wait until any existing MII operation is complete */ - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); /* Set the MII address register to write */ - writel(phydata, ioaddr + mii_data); - writel(value, ioaddr + mii_address); + writel(phydata, priv->ioaddr + mii_data); + writel(value, priv->ioaddr + mii_address); /* Wait until any existing MII operation is complete */ - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); return 0; } @@ -111,7 +109,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus) { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; if (priv->phy_reset) { @@ -123,7 +120,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus) * It doesn't complete its reset until at least one clock cycle * on MDC, so perform a dummy mdio read. */ - writel(0, ioaddr + mii_address); + writel(0, priv->ioaddr + mii_address); return 0; } diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 632ff7c03280..a4adf0de6ed6 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -35,7 +35,7 @@ struct plat_stmmacenet_data { int has_gmac; int enh_desc; void (*fix_mac_speed)(void *priv, unsigned int speed); - void (*bus_setup)(unsigned long ioaddr); + void (*bus_setup)(void __iomem *ioaddr); #ifdef CONFIG_STM_DRIVERS struct stm_pad_config *pad_config; #endif -- cgit v1.2.3 From 884c06f4777c598ea7bf4fbc7557ff2fca066f63 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Aug 2010 02:01:05 +0000 Subject: plip: remove superflous return This return isn't reachable and it obscures the goto on the line before. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/plip.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/plip.c b/drivers/net/plip.c index ec0349e84a8a..7e82a82422cf 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1279,7 +1279,6 @@ static void plip_attach (struct parport *port) if (!nl->pardev) { printk(KERN_ERR "%s: parport_register failed\n", name); goto err_free_dev; - return; } plip_init_netdev(dev); -- cgit v1.2.3 From 21ff2929edc89397cc4c621d3c3f842994640acd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Aug 2010 04:18:13 +0000 Subject: typhoon: fix a race in typhoon_do_get_stats Its important to store 'final' values in counters, not using them as temporary variables, or this might break some SNMP applications. Signed-off-by: Eric Dumazet Acked-by: David Dillow Signed-off-by: David S. Miller --- drivers/net/typhoon.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 2e50077ff450..3f4681f78262 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp) * The extra status reported would be a good candidate for * ethtool_ops->get_{strings,stats}() */ - stats->tx_packets = le32_to_cpu(s->txPackets); - stats->tx_bytes = le64_to_cpu(s->txBytes); - stats->tx_errors = le32_to_cpu(s->txCarrierLost); - stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost); - stats->collisions = le32_to_cpu(s->txMultipleCollisions); - stats->rx_packets = le32_to_cpu(s->rxPacketsGood); - stats->rx_bytes = le64_to_cpu(s->rxBytesGood); - stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns); + stats->tx_packets = le32_to_cpu(s->txPackets) + + saved->tx_packets; + stats->tx_bytes = le64_to_cpu(s->txBytes) + + saved->tx_bytes; + stats->tx_errors = le32_to_cpu(s->txCarrierLost) + + saved->tx_errors; + stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) + + saved->tx_carrier_errors; + stats->collisions = le32_to_cpu(s->txMultipleCollisions) + + saved->collisions; + stats->rx_packets = le32_to_cpu(s->rxPacketsGood) + + saved->rx_packets; + stats->rx_bytes = le64_to_cpu(s->rxBytesGood) + + saved->rx_bytes; + stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) + + saved->rx_fifo_errors; stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + - le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors); - stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors); - stats->rx_length_errors = le32_to_cpu(s->rxOversized); + le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) + + saved->rx_errors; + stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) + + saved->rx_crc_errors; + stats->rx_length_errors = le32_to_cpu(s->rxOversized) + + saved->rx_length_errors; tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? SPEED_100 : SPEED_10; tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF; - /* add in the saved statistics - */ - stats->tx_packets += saved->tx_packets; - stats->tx_bytes += saved->tx_bytes; - stats->tx_errors += saved->tx_errors; - stats->collisions += saved->collisions; - stats->rx_packets += saved->rx_packets; - stats->rx_bytes += saved->rx_bytes; - stats->rx_fifo_errors += saved->rx_fifo_errors; - stats->rx_errors += saved->rx_errors; - stats->rx_crc_errors += saved->rx_crc_errors; - stats->rx_length_errors += saved->rx_length_errors; - return 0; } -- cgit v1.2.3 From 8d34e7d6f38fce1c7e595404295494cd1eaba3eb Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 24 Aug 2010 04:38:33 +0000 Subject: drivers/net/irda: Eliminate memory leak dev_alloc_skb allocates some memory, so that memory should be freed before leaving the function in an error case. Corrected some typos in a nearby comment as well. A simplified version of the semantic match that finds this problem is: (http://coccinelle.lip6.fr/) // @r exists@ local idexpression x; expression E; identifier f1; iterator I; @@ x = dev_alloc_skb(...); <... when != x when != true (x == NULL || ...) when != if (...) { <+...x...+> } when != I (...) { <+...x...+> } ( x == NULL | x == E | x->f1 ) ...> * return ...; // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/irda/via-ircc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index b0a6cd815be1..67c0ad42d818 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -1182,12 +1182,13 @@ F01_E */ skb = dev_alloc_skb(len + 1 - 4); /* - * if frame size,data ptr,or skb ptr are wrong ,the get next + * if frame size, data ptr, or skb ptr are wrong, then get next * entry. */ if ((skb == NULL) || (skb->data == NULL) || (self->rx_buff.data == NULL) || (len < 6)) { self->netdev->stats.rx_dropped++; + kfree_skb(skb); return TRUE; } skb_reserve(skb, 1); -- cgit v1.2.3 From b2aff96327545aa5ceb25e3116be69c8b06de703 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 24 Aug 2010 04:39:49 +0000 Subject: net/netfilter/ipvs: Eliminate memory leak __ip_vs_service_get and __ip_vs_svc_fwm_get increment a reference count, so that reference count should be decremented before leaving the function in an error case. A simplified version of the semantic match that finds this problem is: (http://coccinelle.lip6.fr/) // @r exists@ local idexpression x; expression E; identifier f1; iterator I; @@ x = __ip_vs_service_get(...); <... when != x when != true (x == NULL || ...) when != if (...) { <+...x...+> } when != I (...) { <+...x...+> } ( x == NULL | x == E | x->f1 ) ...> * return ...; // Signed-off-by: Julia Lawall Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_ctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 0f0c079c422a..53a88af22503 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -2155,7 +2155,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) if (cmd != IP_VS_SO_SET_ADD && (svc == NULL || svc->protocol != usvc.protocol)) { ret = -ESRCH; - goto out_unlock; + goto out_drop_service; } switch (cmd) { @@ -2189,6 +2189,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ret = -EINVAL; } +out_drop_service: if (svc) ip_vs_service_put(svc); -- cgit v1.2.3 From 944c794d6437e5301c8769cb242c2b919a5acf59 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 24 Aug 2010 13:08:10 +0000 Subject: bridge: fix locking comment The carrier check is not called from work queue in current code. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index c03d2c3ff03e..170794546522 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -61,11 +61,7 @@ static int port_cost(struct net_device *dev) } -/* - * Check for port carrier transistions. - * Called from work queue to allow for calling functions that - * might sleep (such as speed check), and to debounce. - */ +/* Check for port carrier transistions. */ void br_port_carrier_check(struct net_bridge_port *p) { struct net_device *dev = p->dev; -- cgit v1.2.3 From c5dadddb8c9d310bc263f671f19fe3ba90b329fe Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 24 Aug 2010 12:50:40 +0000 Subject: qlge: Fix a deadlock when the interface is going down Currently qlge can deadlock when the interface is going down, and the mpi_port_cfg_work() is executing on another processor. It happens because unregister_netdev() holds the rtnl lock, and the mpi_port_cfg_work() also request this lock. Since unregiter_netdev() may wait mpi_port_cfg_work(), who also request the holding lock, it can cause an deadlock, displaying the following error: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. rmmod D 00000080c6c1d190 0 3993 2081 0x00008080 Call Trace: [c000000975f56ee0] [c0000000000152a0] .__switch_to+0x100/0x1d0 [c000000975f56f70] [c0000000005781b4] .schedule+0x3a4/0x8c0 [c000000975f570c0] [c000000000578e8c] .schedule_timeout+0x24c/0x350 [c000000975f571e0] [c000000000578a88] .wait_for_common+0x198/0x210 [c000000975f572c0] [c0000000000abbb4] .__cancel_work_timer+0x2c4/0x2e0 [c000000975f57400] [d0000000078e7a20] .ql_adapter_down+0x80/0x260 [qlge] [c000000975f574b0] [d0000000078e7d80] .qlge_close+0x70/0x130 [qlge] [c000000975f57540] [c000000000497ef8] .__dev_close+0x98/0xf0 [c000000975f575d0] [c000000000497f74] .dev_close+0x24/0x60 [c000000975f57650] [c000000000498080] .rollback_registered_many+0xd0/0x2b0 [c000000975f576f0] [c000000000498338] .rollback_registered+0x38/0x50 [c000000975f57780] [c0000000004983d8] .unregister_netdevice_queue+0x88/0xe0 [c000000975f57810] [c000000000498574] .unregister_netdev+0x24/0x40 [c000000975f57890] [d0000000078f6f38] .qlge_remove+0x3c/0x78 [qlge] [c000000975f57920] [c0000000002d9298] .pci_device_remove+0x48/0x90 [c000000975f579a0] [c000000000372850] .__device_release_driver+0xa0/0x130 [c000000975f57a30] [c000000000372a08] .driver_detach+0x128/0x150 [c000000975f57ad0] [c000000000371134] .bus_remove_driver+0xc4/0x1a0 [c000000975f57b70] [c00000000037357c] .driver_unregister+0x8c/0xd0 [c000000975f57c00] [c0000000002d968c] .pci_unregister_driver+0x5c/0x110 [c000000975f57ca0] [d0000000078f6ee4] .qlge_exit+0x1c/0x34 [qlge] Signed-off-by: Breno Leitao Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c9f9754f0784..5a245211fc53 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3889,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev) return status; } -static int ql_adapter_down(struct ql_adapter *qdev) +static void ql_cancel_all_work_sync(struct ql_adapter *qdev) { - int i, status = 0; - - ql_link_off(qdev); /* Don't kill the reset worker thread if we * are in the process of recovery. @@ -3905,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev) cancel_delayed_work_sync(&qdev->mpi_idc_work); cancel_delayed_work_sync(&qdev->mpi_core_to_log); cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); +} + +static int ql_adapter_down(struct ql_adapter *qdev) +{ + int i, status = 0; + + ql_link_off(qdev); + + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) napi_disable(&qdev->rx_ring[i].napi); @@ -4727,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev) struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); del_timer_sync(&qdev->timer); + ql_cancel_all_work_sync(qdev); unregister_netdev(ndev); ql_release_all(pdev); pci_disable_device(pdev); @@ -4746,13 +4753,7 @@ static void ql_eeh_close(struct net_device *ndev) /* Disabling the timer */ del_timer_sync(&qdev->timer); - if (test_bit(QL_ADAPTER_UP, &qdev->flags)) - cancel_delayed_work_sync(&qdev->asic_reset_work); - cancel_delayed_work_sync(&qdev->mpi_reset_work); - cancel_delayed_work_sync(&qdev->mpi_work); - cancel_delayed_work_sync(&qdev->mpi_idc_work); - cancel_delayed_work_sync(&qdev->mpi_core_to_log); - cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) netif_napi_del(&qdev->rx_ring[i].napi); -- cgit v1.2.3 From aa7c6e5fa08bb5014b6432a690d28748f11e93fc Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 24 Aug 2010 13:12:56 +0000 Subject: bridge: avoid ethtool on non running interface If bridge port is offline, don't call ethtool to query speed. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 170794546522..89ad25a76202 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -67,20 +67,21 @@ void br_port_carrier_check(struct net_bridge_port *p) struct net_device *dev = p->dev; struct net_bridge *br = p->br; - if (netif_carrier_ok(dev)) + if (netif_running(dev) && netif_carrier_ok(dev)) p->path_cost = port_cost(dev); - if (netif_running(br->dev)) { - spin_lock_bh(&br->lock); - if (netif_carrier_ok(dev)) { - if (p->state == BR_STATE_DISABLED) - br_stp_enable_port(p); - } else { - if (p->state != BR_STATE_DISABLED) - br_stp_disable_port(p); - } - spin_unlock_bh(&br->lock); + if (!netif_running(br->dev)) + return; + + spin_lock_bh(&br->lock); + if (netif_running(dev) && netif_carrier_ok(dev)) { + if (p->state == BR_STATE_DISABLED) + br_stp_enable_port(p); + } else { + if (p->state != BR_STATE_DISABLED) + br_stp_disable_port(p); } + spin_unlock_bh(&br->lock); } static void release_nbp(struct kobject *kobj) -- cgit v1.2.3 From 6d87f5c3ac5856bf1309700e2f15e2e7fcd3c578 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 25 Aug 2010 00:32:33 +0000 Subject: be2net: fix to dynamically generate MAC Address for VFs The BE ASIC/firmware doesnot reserve and assign MAC address for VFs. This results in the VF interfaces being created with MAC Address 0. The code change proposed takes the MAC address of PF to generate a seed. MAC Address for VFs are assigned incrementally starting from the seed. These addresses are programmed in the ASIC by the PF and the VF driver queries for the MAC address during its probe. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 14 ++++++++++++ drivers/net/benet/be_main.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 99197bd54da5..d1fb7928ffc5 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -413,6 +413,20 @@ static inline void be_check_sriov_fn_type(struct be_adapter *adapter) adapter->is_virtfn = (data != 0xAA); } +static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) +{ + u32 addr; + + addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0); + + mac[5] = (u8)(addr & 0xFF); + mac[4] = (u8)((addr >> 8) & 0xFF); + mac[3] = (u8)((addr >> 16) & 0xFF); + mac[2] = 0xC9; + mac[1] = 0x00; + mac[0] = 0x00; +} + extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index b89bae029620..9db10fec8235 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2088,6 +2088,47 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) return status; } +/* + * Generate a seed MAC address from the PF MAC Address using jhash. + * MAC Address for VFs are assigned incrementally starting from the seed. + * These addresses are programmed in the ASIC by the PF and the VF driver + * queries for the MAC address during its probe. + */ +static inline int be_vf_eth_addr_config(struct be_adapter *adapter) +{ + u32 vf = 0; + int status; + u8 mac[ETH_ALEN]; + + be_vf_eth_addr_generate(adapter, mac); + + for (vf = 0; vf < num_vfs; vf++) { + status = be_cmd_pmac_add(adapter, mac, + adapter->vf_cfg[vf].vf_if_handle, + &adapter->vf_cfg[vf].vf_pmac_id); + if (status) + dev_err(&adapter->pdev->dev, + "Mac address add failed for VF %d\n", vf); + else + memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); + + mac[5] += 1; + } + return status; +} + +static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) +{ + u32 vf; + + for (vf = 0; vf < num_vfs; vf++) { + if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) + be_cmd_pmac_del(adapter, + adapter->vf_cfg[vf].vf_if_handle, + adapter->vf_cfg[vf].vf_pmac_id); + } +} + static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -2147,10 +2188,20 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; + if (be_physfn(adapter)) { + status = be_vf_eth_addr_config(adapter); + if (status) + goto mcc_q_destroy; + } + adapter->link_speed = -1; return 0; +mcc_q_destroy: + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: @@ -2167,6 +2218,9 @@ do_none: static int be_clear(struct be_adapter *adapter) { + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); be_rx_queues_destroy(adapter); be_tx_queues_destroy(adapter); -- cgit v1.2.3 From def824c0d4902d27c52f17d267af8bc648d29e16 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 25 Aug 2010 00:32:56 +0000 Subject: be2net: stats for packets received due to internal switching in ASIC. Counters for packets received due to internal switching are already available. This change will start displaying them in ethtool -S Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index cd16243c7c36..9bedb9ff6e12 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -90,6 +90,9 @@ static const struct be_ethtool_stat et_stats[] = { {PORTSTAT_INFO(rx_non_rss_packets)}, {PORTSTAT_INFO(rx_ipv4_packets)}, {PORTSTAT_INFO(rx_ipv6_packets)}, + {PORTSTAT_INFO(rx_switched_unicast_packets)}, + {PORTSTAT_INFO(rx_switched_multicast_packets)}, + {PORTSTAT_INFO(rx_switched_broadcast_packets)}, {PORTSTAT_INFO(tx_unicastframes)}, {PORTSTAT_INFO(tx_multicastframes)}, {PORTSTAT_INFO(tx_broadcastframes)}, -- cgit v1.2.3 From f0c54ace9b74ec52e57d3ea2ef99fb277667abf8 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Wed, 25 Aug 2010 00:23:39 +0000 Subject: s2io: remove lro parameter Remove "lro" parameter of s2io driver. Signed-off-by: WANG Cong Cc: jon.mason@exar.com Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/s2io.c | 29 +++++++++-------------------- drivers/net/s2io.h | 1 - 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 5f062ddfd5c5..7061fc8e99c7 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -38,8 +38,6 @@ * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), * 2(MSI_X). Default value is '2(MSI_X)' - * lro: Specifies whether to enable Large Receive Offload (LRO) or not. - * Possible values '1' for enable '0' for disable. Default is '0' * lro_max_pkts: This parameter defines maximum number of packets can be * aggregated as a single large packet * napi: This parameter used to enable/disable NAPI (polling Rx) @@ -496,8 +494,6 @@ S2IO_PARM_INT(rxsync_frequency, 3); /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 2); /* Large receive offload feature */ -static unsigned int lro_enable = 1; -module_param_named(lro, lro_enable, uint, 0); /* Max pkts to be aggregated by LRO at one time. If not specified, * aggregation happens until we hit max IP pkt size(64K) @@ -6733,13 +6729,10 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) return -EINVAL; if (data & ETH_FLAG_LRO) { - if (lro_enable) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - changed = 1; - } - } else - rc = -EINVAL; + if (!(dev->features & NETIF_F_LRO)) { + dev->features |= NETIF_F_LRO; + changed = 1; + } } else if (dev->features & NETIF_F_LRO) { dev->features &= ~NETIF_F_LRO; changed = 1; @@ -6748,7 +6741,6 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) if (changed && netif_running(dev)) { s2io_stop_all_tx_queue(sp); s2io_card_down(sp); - sp->lro = !!(dev->features & NETIF_F_LRO); rc = s2io_card_up(sp); if (rc) s2io_reset(sp); @@ -7305,7 +7297,7 @@ static int s2io_card_up(struct s2io_nic *sp) struct ring_info *ring = &mac_control->rings[i]; ring->mtu = dev->mtu; - ring->lro = sp->lro; + ring->lro = !!(dev->features & NETIF_F_LRO); ret = fill_rx_buffers(sp, ring, 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", @@ -7339,7 +7331,7 @@ static int s2io_card_up(struct s2io_nic *sp) /* Setting its receive mode */ s2io_set_multicast(dev); - if (sp->lro) { + if (dev->features & NETIF_F_LRO) { /* Initialize max aggregatable pkts per session based on MTU */ sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; /* Check if we can use (if specified) user provided value */ @@ -7909,7 +7901,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) else sp->device_type = XFRAME_I_DEVICE; - sp->lro = lro_enable; /* Initialize some PCI/PCI-X fields of the NIC. */ s2io_init_pci(sp); @@ -8045,8 +8036,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->netdev_ops = &s2io_netdev_ops; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - if (lro_enable) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_LRO; dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == true) dev->features |= NETIF_F_HIGHDMA; @@ -8281,9 +8271,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->name); } - if (sp->lro) - DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", - dev->name); + DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", + dev->name); if (ufo) DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO) enabled\n", diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 924f618f2397..00b8614efe48 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -963,7 +963,6 @@ struct s2io_nic { unsigned long clubbed_frms_cnt; unsigned long sending_both; - u8 lro; u16 lro_max_aggr_per_sess; volatile unsigned long state; u64 general_int_mask; -- cgit v1.2.3 From ced1de4c9eeded664e5f1b21cfcb0fb70cc0cde3 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Tue, 24 Aug 2010 23:57:55 +0000 Subject: r6040: Free irq line on error path Free irq line on error path. Signed-off-by: Denis Kirjanov Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 0a00850da79d..63db065508f4 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -756,7 +756,7 @@ static int r6040_open(struct net_device *dev) ret = request_irq(dev->irq, r6040_interrupt, IRQF_SHARED, dev->name, dev); if (ret) - return ret; + goto out; /* Set MAC address */ r6040_mac_address(dev); @@ -764,30 +764,37 @@ static int r6040_open(struct net_device *dev) /* Allocate Descriptor memory */ lp->rx_ring = pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma); - if (!lp->rx_ring) - return -ENOMEM; + if (!lp->rx_ring) { + ret = -ENOMEM; + goto err_free_irq; + } lp->tx_ring = pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma); if (!lp->tx_ring) { - pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, - lp->rx_ring_dma); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_rx_ring; } ret = r6040_up(dev); - if (ret) { - pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring, - lp->tx_ring_dma); - pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, - lp->rx_ring_dma); - return ret; - } + if (ret) + goto err_free_tx_ring; napi_enable(&lp->napi); netif_start_queue(dev); return 0; + +err_free_tx_ring: + pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring, + lp->tx_ring_dma); +err_free_rx_ring: + pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, + lp->rx_ring_dma); +err_free_irq: + free_irq(dev->irq, dev); +out: + return ret; } static netdev_tx_t r6040_start_xmit(struct sk_buff *skb, -- cgit v1.2.3 From 8a891429d1879ae4f37f547ef5c2d68e19277e4a Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Wed, 25 Aug 2010 23:00:27 -0700 Subject: bna: Fixed build break for allyesconfig This is the patch to fix the build break caused by multiple definitions of symbols between Brocade's FC/FCOE driver(BFA) and 10G Networking Driver(BNA). Changes are: 1. locally used functions are made static 2. unused functions are removed 3. using unique namespaces for the function names that must be globally visible Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bfa_cee.c | 136 ++-------------------- drivers/net/bna/bfa_cee.h | 14 +-- drivers/net/bna/bfa_ioc.c | 249 ++++++++++++----------------------------- drivers/net/bna/bfa_ioc.h | 96 +++++----------- drivers/net/bna/bfa_ioc_ct.c | 49 ++++---- drivers/net/bna/bna_ctrl.c | 38 +++---- drivers/net/bna/bnad.c | 9 +- drivers/net/bna/bnad_ethtool.c | 2 +- 8 files changed, 162 insertions(+), 431 deletions(-) diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c index 1545fc9720f8..f7b789a3b217 100644 --- a/drivers/net/bna/bfa_cee.c +++ b/drivers/net/bna/bfa_cee.c @@ -152,7 +152,7 @@ bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status) cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); } /** - * bfa_cee_meminfo() + * bfa_nw_cee_meminfo() * * @brief Returns the size of the DMA memory needed by CEE module * @@ -161,13 +161,13 @@ bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status) * @return Size of DMA region */ u32 -bfa_cee_meminfo(void) +bfa_nw_cee_meminfo(void) { return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo(); } /** - * bfa_cee_mem_claim() + * bfa_nw_cee_mem_claim() * * @brief Initialized CEE DMA Memory * @@ -178,7 +178,7 @@ bfa_cee_meminfo(void) * @return void */ void -bfa_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) +bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) { cee->attr_dma.kva = dma_kva; cee->attr_dma.pa = dma_pa; @@ -189,108 +189,6 @@ bfa_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) (dma_kva + bfa_cee_attr_meminfo()); } -/** - * bfa_cee_get_attr() - * - * @brief - * Send the request to the f/w to fetch CEE attributes. - * - * @param[in] Pointer to the CEE module data structure. - * - * @return Status - */ - -enum bfa_status -bfa_cee_get_attr(struct bfa_cee *cee, struct bfa_cee_attr *attr, - bfa_cee_get_attr_cbfn_t cbfn, void *cbarg) -{ - struct bfi_cee_get_req *cmd; - - BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); - if (!bfa_ioc_is_operational(cee->ioc)) - return BFA_STATUS_IOC_FAILURE; - if (cee->get_attr_pending == true) - return BFA_STATUS_DEVBUSY; - cee->get_attr_pending = true; - cmd = (struct bfi_cee_get_req *) cee->get_cfg_mb.msg; - cee->attr = attr; - cee->cbfn.get_attr_cbfn = cbfn; - cee->cbfn.get_attr_cbarg = cbarg; - bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ, - bfa_ioc_portid(cee->ioc)); - bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa); - bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb); - - return BFA_STATUS_OK; -} - -/** - * bfa_cee_get_stats() - * - * @brief - * Send the request to the f/w to fetch CEE statistics. - * - * @param[in] Pointer to the CEE module data structure. - * - * @return Status - */ - -enum bfa_status -bfa_cee_get_stats(struct bfa_cee *cee, struct bfa_cee_stats *stats, - bfa_cee_get_stats_cbfn_t cbfn, void *cbarg) -{ - struct bfi_cee_get_req *cmd; - - BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); - - if (!bfa_ioc_is_operational(cee->ioc)) - return BFA_STATUS_IOC_FAILURE; - if (cee->get_stats_pending == true) - return BFA_STATUS_DEVBUSY; - cee->get_stats_pending = true; - cmd = (struct bfi_cee_get_req *) cee->get_stats_mb.msg; - cee->stats = stats; - cee->cbfn.get_stats_cbfn = cbfn; - cee->cbfn.get_stats_cbarg = cbarg; - bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ, - bfa_ioc_portid(cee->ioc)); - bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa); - bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb); - - return BFA_STATUS_OK; -} - -/** - * bfa_cee_reset_stats() - * - * @brief Clears CEE Stats in the f/w. - * - * @param[in] Pointer to the CEE module data structure. - * - * @return Status - */ - -enum bfa_status -bfa_cee_reset_stats(struct bfa_cee *cee, bfa_cee_reset_stats_cbfn_t cbfn, - void *cbarg) -{ - struct bfi_cee_reset_stats *cmd; - - BUG_ON(!((cee != NULL) && (cee->ioc != NULL))); - if (!bfa_ioc_is_operational(cee->ioc)) - return BFA_STATUS_IOC_FAILURE; - if (cee->reset_stats_pending == true) - return BFA_STATUS_DEVBUSY; - cee->reset_stats_pending = true; - cmd = (struct bfi_cee_reset_stats *) cee->reset_stats_mb.msg; - cee->cbfn.reset_stats_cbfn = cbfn; - cee->cbfn.reset_stats_cbarg = cbarg; - bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS, - bfa_ioc_portid(cee->ioc)); - bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb); - return BFA_STATUS_OK; -} - /** * bfa_cee_isrs() * @@ -301,7 +199,7 @@ bfa_cee_reset_stats(struct bfa_cee *cee, bfa_cee_reset_stats_cbfn_t cbfn, * @return void */ -void +static void bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) { union bfi_cee_i2h_msg_u *msg; @@ -334,7 +232,7 @@ bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) * @return void */ -void +static void bfa_cee_hbfail(void *arg) { struct bfa_cee *cee; @@ -367,7 +265,7 @@ bfa_cee_hbfail(void *arg) } /** - * bfa_cee_attach() + * bfa_nw_cee_attach() * * @brief CEE module-attach API * @@ -380,28 +278,14 @@ bfa_cee_hbfail(void *arg) * @return void */ void -bfa_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, +bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev) { BUG_ON(!(cee != NULL)); cee->dev = dev; cee->ioc = ioc; - bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); + bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee); - bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail); -} - -/** - * bfa_cee_detach() - * - * @brief CEE module-detach API - * - * @param[in] cee - Pointer to the CEE module data structure - * - * @return void - */ -void -bfa_cee_detach(struct bfa_cee *cee) -{ + bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail); } diff --git a/drivers/net/bna/bfa_cee.h b/drivers/net/bna/bfa_cee.h index 1208cadeceed..20543d15b64f 100644 --- a/drivers/net/bna/bfa_cee.h +++ b/drivers/net/bna/bfa_cee.h @@ -56,17 +56,9 @@ struct bfa_cee { struct bfa_mbox_cmd reset_stats_mb; }; -u32 bfa_cee_meminfo(void); -void bfa_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, +u32 bfa_nw_cee_meminfo(void); +void bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa); -void bfa_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev); -void bfa_cee_detach(struct bfa_cee *cee); -enum bfa_status bfa_cee_get_attr(struct bfa_cee *cee, - struct bfa_cee_attr *attr, bfa_cee_get_attr_cbfn_t cbfn, void *cbarg); -enum bfa_status bfa_cee_get_stats(struct bfa_cee *cee, - struct bfa_cee_stats *stats, bfa_cee_get_stats_cbfn_t cbfn, - void *cbarg); -enum bfa_status bfa_cee_reset_stats(struct bfa_cee *cee, - bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg); +void bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev); #endif /* __BFA_CEE_H__ */ diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index cdc2cb1597ec..caa45c2185e9 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -65,7 +65,7 @@ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ readl((__ioc)->ioc_regs.hfn_mbox_cmd)) -bool bfa_auto_recover = true; +bool bfa_nw_auto_recover = true; /* * forward declarations @@ -85,6 +85,23 @@ static void bfa_ioc_recover(struct bfa_ioc *ioc); static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc); static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); +static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, + u32 boot_param); +static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); +static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr); +static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, + char *serial_num); +static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, + char *fw_ver); +static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, + char *chip_rev); +static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, + char *optrom_ver); +static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, + char *manufacturer); +static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); +static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); +static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc); /** * IOC state machine events @@ -138,7 +155,7 @@ static void bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) { ioc->retry_count = 0; - ioc->auto_recover = bfa_auto_recover; + ioc->auto_recover = bfa_nw_auto_recover; } /** @@ -185,7 +202,7 @@ bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event) ioc->retry_count = 0; bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); } else { - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch); } break; @@ -314,12 +331,12 @@ bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event) break; } - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); break; case IOC_E_DISABLE: - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_ioc_timer_stop(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); break; @@ -346,7 +363,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) switch (event) { case IOC_E_FWRSP_ENABLE: bfa_ioc_timer_stop(ioc); - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); break; @@ -363,13 +380,13 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) break; } - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); break; case IOC_E_DISABLE: bfa_ioc_timer_stop(ioc); - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); break; @@ -662,7 +679,7 @@ bfa_ioc_disable_comp(struct bfa_ioc *ioc) } void -bfa_ioc_sem_timeout(void *ioc_arg) +bfa_nw_ioc_sem_timeout(void *ioc_arg) { struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; @@ -670,7 +687,7 @@ bfa_ioc_sem_timeout(void *ioc_arg) } bool -bfa_ioc_sem_get(void __iomem *sem_reg) +bfa_nw_ioc_sem_get(void __iomem *sem_reg) { u32 r32; int cnt = 0; @@ -692,7 +709,7 @@ bfa_ioc_sem_get(void __iomem *sem_reg) } void -bfa_ioc_sem_release(void __iomem *sem_reg) +bfa_nw_ioc_sem_release(void __iomem *sem_reg) { writel(1, sem_reg); } @@ -717,7 +734,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) } void -bfa_ioc_hw_sem_release(struct bfa_ioc *ioc) +bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc) { writel(1, ioc->ioc_regs.ioc_sem_reg); } @@ -800,7 +817,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc *ioc) * Get driver and firmware versions. */ void -bfa_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) { u32 pgnum, pgoff; u32 loff = 0; @@ -823,7 +840,7 @@ bfa_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) * Returns TRUE if same. */ bool -bfa_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) { struct bfi_ioc_image_hdr *drv_fwhdr; int i; @@ -854,7 +871,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc) if (bfa_ioc_is_optrom(ioc)) return true; - bfa_ioc_fwver_get(ioc, &fwhdr); + bfa_nw_ioc_fwver_get(ioc, &fwhdr); drv_fwhdr = (struct bfi_ioc_image_hdr *) bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); @@ -864,7 +881,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc) if (fwhdr.exec != drv_fwhdr->exec) return false; - return bfa_ioc_fwver_cmp(ioc, &fwhdr); + return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr); } /** @@ -941,14 +958,14 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) } void -bfa_ioc_timeout(void *ioc_arg) +bfa_nw_ioc_timeout(void *ioc_arg) { struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); } -void +static void bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len) { u32 *msgp = (u32 *) ioc_msg; @@ -1009,7 +1026,7 @@ bfa_ioc_send_getattr(struct bfa_ioc *ioc) } void -bfa_ioc_hb_check(void *cbarg) +bfa_nw_ioc_hb_check(void *cbarg) { struct bfa_ioc *ioc = cbarg; u32 hb_count; @@ -1195,13 +1212,13 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) /** * IOC public */ -enum bfa_status +static enum bfa_status bfa_ioc_pll_init(struct bfa_ioc *ioc) { /* * Hold semaphore so that nobody can access the chip during init. */ - bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); bfa_ioc_pll_init_asic(ioc); @@ -1209,7 +1226,7 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc) /* * release semaphore. */ - bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); return BFA_STATUS_OK; } @@ -1218,7 +1235,7 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc) * Interface used by diag module to do firmware boot with memory test * as the entry vector. */ -void +static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) { void __iomem *rb; @@ -1254,28 +1271,18 @@ bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) * Enable/disable IOC failure auto recovery. */ void -bfa_ioc_auto_recover(bool auto_recover) +bfa_nw_ioc_auto_recover(bool auto_recover) { - bfa_auto_recover = auto_recover; + bfa_nw_auto_recover = auto_recover; } bool -bfa_ioc_is_operational(struct bfa_ioc *ioc) +bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) { return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); } -bool -bfa_ioc_is_initialized(struct bfa_ioc *ioc) -{ - u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); - - return ((r32 != BFI_IOC_UNINIT) && - (r32 != BFI_IOC_INITING) && - (r32 != BFI_IOC_MEMTEST)); -} - -void +static void bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) { u32 *msgp = mbmsg; @@ -1299,7 +1306,7 @@ bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) readl(ioc->ioc_regs.lpu_mbox_cmd); } -void +static void bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) { union bfi_ioc_i2h_msg_u *msg; @@ -1340,7 +1347,7 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) * @param[in] bfa driver instance structure */ void -bfa_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) +bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) { ioc->bfa = bfa; ioc->cbfn = cbfn; @@ -1358,7 +1365,7 @@ bfa_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) * Driver detach time IOC cleanup. */ void -bfa_ioc_detach(struct bfa_ioc *ioc) +bfa_nw_ioc_detach(struct bfa_ioc *ioc) { bfa_fsm_send_event(ioc, IOC_E_DETACH); } @@ -1369,7 +1376,7 @@ bfa_ioc_detach(struct bfa_ioc *ioc) * @param[in] pcidev PCI device information for this IOC */ void -bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, +bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, enum bfi_mclass mc) { ioc->ioc_mc = mc; @@ -1377,7 +1384,7 @@ bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); ioc->cna = ioc->ctdev && !ioc->fcmode; - bfa_ioc_set_ct_hwif(ioc); + bfa_nw_ioc_set_ct_hwif(ioc); bfa_ioc_map_port(ioc); bfa_ioc_reg_init(ioc); @@ -1390,7 +1397,7 @@ bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, * @param[in] dm_pa physical address of IOC dma memory */ void -bfa_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) +bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) { /** * dma memory for firmware attribute @@ -1404,13 +1411,13 @@ bfa_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) * Return size of dma memory required. */ u32 -bfa_ioc_meminfo(void) +bfa_nw_ioc_meminfo(void) { return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ); } void -bfa_ioc_enable(struct bfa_ioc *ioc) +bfa_nw_ioc_enable(struct bfa_ioc *ioc) { bfa_ioc_stats(ioc, ioc_enables); ioc->dbg_fwsave_once = true; @@ -1419,45 +1426,29 @@ bfa_ioc_enable(struct bfa_ioc *ioc) } void -bfa_ioc_disable(struct bfa_ioc *ioc) +bfa_nw_ioc_disable(struct bfa_ioc *ioc) { bfa_ioc_stats(ioc, ioc_disables); bfa_fsm_send_event(ioc, IOC_E_DISABLE); } -u32 +static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr) { return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); } -u32 +static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr) { return PSS_SMEM_PGOFF(fmaddr); } -/** - * Register mailbox message handler functions - * - * @param[in] ioc IOC instance - * @param[in] mcfuncs message class handler functions - */ -void -bfa_ioc_mbox_register(struct bfa_ioc *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) -{ - struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; - int mc; - - for (mc = 0; mc < BFI_MC_MAX; mc++) - mod->mbhdlr[mc].cbfn = mcfuncs[mc]; -} - /** * Register mailbox message handler function, to be called by common modules */ void -bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, +bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) { struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; @@ -1474,7 +1465,7 @@ bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, * @param[i] cmd Mailbox command */ void -bfa_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) +bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) { struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; u32 stat; @@ -1506,7 +1497,7 @@ bfa_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) * Handle mailbox interrupts */ void -bfa_ioc_mbox_isr(struct bfa_ioc *ioc) +bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc) { struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; struct bfi_mbmsg m; @@ -1530,86 +1521,24 @@ bfa_ioc_mbox_isr(struct bfa_ioc *ioc) } void -bfa_ioc_error_isr(struct bfa_ioc *ioc) +bfa_nw_ioc_error_isr(struct bfa_ioc *ioc) { bfa_fsm_send_event(ioc, IOC_E_HWERROR); } -void -bfa_ioc_set_fcmode(struct bfa_ioc *ioc) -{ - ioc->fcmode = true; - ioc->port_id = bfa_ioc_pcifn(ioc); -} - -/** - * return true if IOC is disabled - */ -bool -bfa_ioc_is_disabled(struct bfa_ioc *ioc) -{ - return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || - bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); -} - -/** - * return true if IOC firmware is different. - */ -bool -bfa_ioc_fw_mismatch(struct bfa_ioc *ioc) -{ - return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) || - bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck) || - bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch); -} - -#define bfa_ioc_state_disabled(__sm) \ - (((__sm) == BFI_IOC_UNINIT) || \ - ((__sm) == BFI_IOC_INITING) || \ - ((__sm) == BFI_IOC_HWINIT) || \ - ((__sm) == BFI_IOC_DISABLED) || \ - ((__sm) == BFI_IOC_FAIL) || \ - ((__sm) == BFI_IOC_CFG_DISABLED)) - -/** - * Check if adapter is disabled -- both IOCs should be in a disabled - * state. - */ -bool -bfa_ioc_adapter_is_disabled(struct bfa_ioc *ioc) -{ - u32 ioc_state; - void __iomem *rb = ioc->pcidev.pci_bar_kva; - - if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) - return false; - - ioc_state = readl(rb + BFA_IOC0_STATE_REG); - if (!bfa_ioc_state_disabled(ioc_state)) - return false; - - if (ioc->pcidev.device_id != PCI_DEVICE_ID_BROCADE_FC_8G1P) { - ioc_state = readl(rb + BFA_IOC1_STATE_REG); - if (!bfa_ioc_state_disabled(ioc_state)) - return false; - } - - return true; -} - /** * Add to IOC heartbeat failure notification queue. To be used by common * modules such as cee, port, diag. */ void -bfa_ioc_hbfail_register(struct bfa_ioc *ioc, +bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, struct bfa_ioc_hbfail_notify *notify) { list_add_tail(¬ify->qe, &ioc->hb_notify_q); } #define BFA_MFG_NAME "Brocade" -void +static void bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, struct bfa_adapter_attr *ad_attr) { @@ -1640,7 +1569,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, ad_attr->prototype = 0; ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); - ad_attr->mac = bfa_ioc_get_mac(ioc); + ad_attr->mac = bfa_nw_ioc_get_mac(ioc); ad_attr->pcie_gen = ioc_attr->pcie_gen; ad_attr->pcie_lanes = ioc_attr->pcie_lanes; @@ -1653,7 +1582,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna; } -enum bfa_ioc_type +static enum bfa_ioc_type bfa_ioc_get_type(struct bfa_ioc *ioc) { if (!ioc->ctdev || ioc->fcmode) @@ -1668,7 +1597,7 @@ bfa_ioc_get_type(struct bfa_ioc *ioc) } } -void +static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) { memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); @@ -1677,14 +1606,14 @@ bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) BFA_ADAPTER_SERIAL_NUM_LEN); } -void +static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver) { memset(fw_ver, 0, BFA_VERSION_LEN); memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); } -void +static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) { BUG_ON(!(chip_rev)); @@ -1699,7 +1628,7 @@ bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) chip_rev[5] = '\0'; } -void +static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) { memset(optrom_ver, 0, BFA_VERSION_LEN); @@ -1707,14 +1636,14 @@ bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) BFA_VERSION_LEN); } -void +static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) { memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); } -void +static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) { struct bfi_ioc_attr *ioc_attr; @@ -1731,14 +1660,14 @@ bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) BFA_MFG_NAME, ioc_attr->card_type); } -enum bfa_ioc_state +static enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc *ioc) { return bfa_sm_to_state(ioc_sm_table, ioc->fsm); } void -bfa_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) +bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) { memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr)); @@ -1757,26 +1686,14 @@ bfa_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) /** * WWN public */ -u64 +static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc) { return ioc->attr->pwwn; } -u64 -bfa_ioc_get_nwwn(struct bfa_ioc *ioc) -{ - return ioc->attr->nwwn; -} - -u64 -bfa_ioc_get_adid(struct bfa_ioc *ioc) -{ - return ioc->attr->mfg_pwwn; -} - mac_t -bfa_ioc_get_mac(struct bfa_ioc *ioc) +bfa_nw_ioc_get_mac(struct bfa_ioc *ioc) { /* * Currently mfg mac is used as FCoE enode mac (not configured by PBC) @@ -1787,19 +1704,7 @@ bfa_ioc_get_mac(struct bfa_ioc *ioc) return ioc->attr->mac; } -u64 -bfa_ioc_get_mfg_pwwn(struct bfa_ioc *ioc) -{ - return ioc->attr->mfg_pwwn; -} - -u64 -bfa_ioc_get_mfg_nwwn(struct bfa_ioc *ioc) -{ - return ioc->attr->mfg_nwwn; -} - -mac_t +static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc) { mac_t m; @@ -1814,12 +1719,6 @@ bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc) return m; } -bool -bfa_ioc_get_fcmode(struct bfa_ioc *ioc) -{ - return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id); -} - /** * Firmware failure detected. Start recovery actions. */ diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h index 2e5c0adef899..7f0719e17efc 100644 --- a/drivers/net/bna/bfa_ioc.h +++ b/drivers/net/bna/bfa_ioc.h @@ -239,13 +239,9 @@ struct bfa_ioc_hwif { /** * IOC mailbox interface */ -void bfa_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd); -void bfa_ioc_mbox_register(struct bfa_ioc *ioc, - bfa_ioc_mbox_mcfunc_t *mcfuncs); -void bfa_ioc_mbox_isr(struct bfa_ioc *ioc); -void bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len); -void bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg); -void bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, +void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd); +void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc); +void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg); /** @@ -256,83 +252,45 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \ (__ioc)->fcmode)) -enum bfa_status bfa_ioc_pll_init(struct bfa_ioc *ioc); -enum bfa_status bfa_ioc_cb_pll_init(void __iomem *rb, bool fcmode); -enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); - #define bfa_ioc_isr_mode_set(__ioc, __msix) \ ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix)) #define bfa_ioc_ownership_reset(__ioc) \ ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc)) -void bfa_ioc_set_ct_hwif(struct bfa_ioc *ioc); +void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc); -void bfa_ioc_attach(struct bfa_ioc *ioc, void *bfa, +void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn); -void bfa_ioc_auto_recover(bool auto_recover); -void bfa_ioc_detach(struct bfa_ioc *ioc); -void bfa_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, +void bfa_nw_ioc_auto_recover(bool auto_recover); +void bfa_nw_ioc_detach(struct bfa_ioc *ioc); +void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, enum bfi_mclass mc); -u32 bfa_ioc_meminfo(void); -void bfa_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa); -void bfa_ioc_enable(struct bfa_ioc *ioc); -void bfa_ioc_disable(struct bfa_ioc *ioc); -bool bfa_ioc_intx_claim(struct bfa_ioc *ioc); - -void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, - u32 boot_param); -void bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *msg); -void bfa_ioc_error_isr(struct bfa_ioc *ioc); -bool bfa_ioc_is_operational(struct bfa_ioc *ioc); -bool bfa_ioc_is_initialized(struct bfa_ioc *ioc); -bool bfa_ioc_is_disabled(struct bfa_ioc *ioc); -bool bfa_ioc_fw_mismatch(struct bfa_ioc *ioc); -bool bfa_ioc_adapter_is_disabled(struct bfa_ioc *ioc); -void bfa_ioc_cfg_complete(struct bfa_ioc *ioc); -enum bfa_ioc_type bfa_ioc_get_type(struct bfa_ioc *ioc); -void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num); -void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver); -void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver); -void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); -void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, - char *manufacturer); -void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev); -enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc *ioc); - -void bfa_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); -void bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, - struct bfa_adapter_attr *ad_attr); -u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); -u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr); -void bfa_ioc_set_fcmode(struct bfa_ioc *ioc); -bool bfa_ioc_get_fcmode(struct bfa_ioc *ioc); -void bfa_ioc_hbfail_register(struct bfa_ioc *ioc, +u32 bfa_nw_ioc_meminfo(void); +void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa); +void bfa_nw_ioc_enable(struct bfa_ioc *ioc); +void bfa_nw_ioc_disable(struct bfa_ioc *ioc); + +void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc); +bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc); + +void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); +void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, struct bfa_ioc_hbfail_notify *notify); -bool bfa_ioc_sem_get(void __iomem *sem_reg); -void bfa_ioc_sem_release(void __iomem *sem_reg); -void bfa_ioc_hw_sem_release(struct bfa_ioc *ioc); -void bfa_ioc_fwver_get(struct bfa_ioc *ioc, +bool bfa_nw_ioc_sem_get(void __iomem *sem_reg); +void bfa_nw_ioc_sem_release(void __iomem *sem_reg); +void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc); +void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr); -bool bfa_ioc_fwver_cmp(struct bfa_ioc *ioc, +bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr); +mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc); /* * Timeout APIs */ -void bfa_ioc_timeout(void *ioc); -void bfa_ioc_hb_check(void *ioc); -void bfa_ioc_sem_timeout(void *ioc); - -/* - * bfa mfg wwn API functions - */ -u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); -u64 bfa_ioc_get_nwwn(struct bfa_ioc *ioc); -mac_t bfa_ioc_get_mac(struct bfa_ioc *ioc); -u64 bfa_ioc_get_mfg_pwwn(struct bfa_ioc *ioc); -u64 bfa_ioc_get_mfg_nwwn(struct bfa_ioc *ioc); -mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc); -u64 bfa_ioc_get_adid(struct bfa_ioc *ioc); +void bfa_nw_ioc_timeout(void *ioc); +void bfa_nw_ioc_hb_check(void *ioc); +void bfa_nw_ioc_sem_timeout(void *ioc); /* * F/W Image Size & Chunk diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c index 870046e32c8d..462857cbab9b 100644 --- a/drivers/net/bna/bfa_ioc_ct.c +++ b/drivers/net/bna/bfa_ioc_ct.c @@ -32,25 +32,26 @@ static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc); static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix); static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc); static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); +static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); -struct bfa_ioc_hwif hwif_ct; +struct bfa_ioc_hwif nw_hwif_ct; /** * Called from bfa_ioc_attach() to map asic specific calls. */ void -bfa_ioc_set_ct_hwif(struct bfa_ioc *ioc) +bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc) { - hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; - hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock; - hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; - hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; - hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; - hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; - hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail; - hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; - - ioc->ioc_hwif = &hwif_ct; + nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; + nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock; + nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; + nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; + nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; + nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; + nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail; + nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; + + ioc->ioc_hwif = &nw_hwif_ct; } /** @@ -76,7 +77,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) BFA_IOC_FWIMG_MINSZ) return true; - bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); usecnt = readl(ioc->ioc_regs.ioc_usage_reg); /** @@ -84,7 +85,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) */ if (usecnt == 0) { writel(1, ioc->ioc_regs.ioc_usage_reg); - bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); return true; } @@ -98,9 +99,9 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) /** * Check if another driver with a different firmware is active */ - bfa_ioc_fwver_get(ioc, &fwhdr); - if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { - bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_fwver_get(ioc, &fwhdr); + if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) { + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); return false; } @@ -109,7 +110,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) */ usecnt++; writel(usecnt, ioc->ioc_regs.ioc_usage_reg); - bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); return true; } @@ -134,14 +135,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc) /** * decrement usage count */ - bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); usecnt = readl(ioc->ioc_regs.ioc_usage_reg); BUG_ON(!(usecnt > 0)); usecnt--; writel(usecnt, ioc->ioc_regs.ioc_usage_reg); - bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); } /** @@ -302,9 +303,9 @@ static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) { if (ioc->cna) { - bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); writel(0, ioc->ioc_regs.ioc_usage_reg); - bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); } /* @@ -313,10 +314,10 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) * will lock it instead of clearing it. */ readl(ioc->ioc_regs.ioc_sem_reg); - bfa_ioc_hw_sem_release(ioc); + bfa_nw_ioc_hw_sem_release(ioc); } -enum bfa_status +static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode) { u32 pll_sclk, pll_fclk, r32; diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index 9d41ebf41cf4..f3034d6bda58 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -81,7 +81,7 @@ bna_ll_isr(void *llarg, struct bfi_mbmsg *msg) /* Post the next entry, if needed */ if (to_post) { mb_qe = bfa_q_first(&bna->mbox_mod.posted_q); - bfa_ioc_mbox_queue(&bna->device.ioc, + bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mb_qe->cmd); } } else { @@ -107,7 +107,7 @@ bna_err_handler(struct bna *bna, u32 intr_status) writel(init_halt, bna->device.ioc.ioc_regs.ll_halt); } - bfa_ioc_error_isr(&bna->device.ioc); + bfa_nw_ioc_error_isr(&bna->device.ioc); } void @@ -118,7 +118,7 @@ bna_mbox_handler(struct bna *bna, u32 intr_status) return; } if (BNA_IS_MBOX_INTR(intr_status)) - bfa_ioc_mbox_isr(&bna->device.ioc); + bfa_nw_ioc_mbox_isr(&bna->device.ioc); } void @@ -133,7 +133,7 @@ bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe) bna->mbox_mod.msg_pending++; if (bna->mbox_mod.state == BNA_MBOX_FREE) { list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); - bfa_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd); + bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd); bna->mbox_mod.state = BNA_MBOX_POSTED; } else { list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); @@ -180,7 +180,7 @@ bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod) void bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna) { - bfa_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna); + bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna); mbox_mod->state = BNA_MBOX_FREE; mbox_mod->msg_ctr = mbox_mod->msg_pending = 0; INIT_LIST_HEAD(&mbox_mod->posted_q); @@ -1289,7 +1289,7 @@ bna_port_mtu_set(struct bna_port *port, int mtu, void bna_port_mac_get(struct bna_port *port, mac_t *mac) { - *mac = bfa_ioc_get_mac(&port->bna->device.ioc); + *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc); } /** @@ -1427,7 +1427,7 @@ bna_device_sm_stopped(struct bna_device *device, case DEVICE_E_ENABLE: if (device->intr_type == BNA_INTR_T_MSIX) bna_mbox_msix_idx_set(device); - bfa_ioc_enable(&device->ioc); + bfa_nw_ioc_enable(&device->ioc); bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait); break; @@ -1547,7 +1547,7 @@ bna_device_sm_port_stop_wait(struct bna_device *device, static void bna_device_sm_ioc_disable_wait_entry(struct bna_device *device) { - bfa_ioc_disable(&device->ioc); + bfa_nw_ioc_disable(&device->ioc); } static void @@ -1655,12 +1655,12 @@ bna_device_init(struct bna_device *device, struct bna *bna, * 1. DMA memory for IOC attributes * 2. Kernel memory for FW trace */ - bfa_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn); - bfa_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL); + bfa_nw_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn); + bfa_nw_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL); BNA_GET_DMA_ADDR( &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma); - bfa_ioc_mem_claim(&device->ioc, + bfa_nw_ioc_mem_claim(&device->ioc, res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva, dma); @@ -1686,9 +1686,7 @@ bna_device_uninit(struct bna_device *device) { bna_mbox_mod_uninit(&device->bna->mbox_mod); - bfa_cee_detach(&device->bna->cee); - - bfa_ioc_detach(&device->ioc); + bfa_nw_ioc_detach(&device->ioc); device->bna = NULL; } @@ -1783,10 +1781,10 @@ bna_adv_device_init(struct bna_device *device, struct bna *bna, &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; - bfa_cee_attach(&bna->cee, &device->ioc, bna); - bfa_cee_mem_claim(&bna->cee, kva, dma); - kva += bfa_cee_meminfo(); - dma += bfa_cee_meminfo(); + bfa_nw_cee_attach(&bna->cee, &device->ioc, bna); + bfa_nw_cee_mem_claim(&bna->cee, kva, dma); + kva += bfa_nw_cee_meminfo(); + dma += bfa_nw_cee_meminfo(); } @@ -1800,7 +1798,7 @@ bna_adv_res_req(struct bna_res_info *res_info) res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA; res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( - bfa_cee_meminfo(), PAGE_SIZE); + bfa_nw_cee_meminfo(), PAGE_SIZE); /* Virtual memory for retreiving fw_trc */ res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM; @@ -3333,7 +3331,7 @@ bna_res_req(struct bna_res_info *res_info) res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA; res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1; res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len = - ALIGN(bfa_ioc_meminfo(), PAGE_SIZE); + ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE); /* DMA memory for index segment of an IB */ res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 491d148f88ae..cbc1d563a0c2 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -1365,7 +1365,7 @@ bnad_ioc_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); - bfa_ioc_timeout((void *) &bnad->bna.device.ioc); + bfa_nw_ioc_timeout((void *) &bnad->bna.device.ioc); spin_unlock_irqrestore(&bnad->bna_lock, flags); } @@ -1376,7 +1376,7 @@ bnad_ioc_hb_check(unsigned long data) unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); - bfa_ioc_hb_check((void *) &bnad->bna.device.ioc); + bfa_nw_ioc_hb_check((void *) &bnad->bna.device.ioc); spin_unlock_irqrestore(&bnad->bna_lock, flags); } @@ -1387,7 +1387,7 @@ bnad_ioc_sem_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); - bfa_ioc_sem_timeout((void *) &bnad->bna.device.ioc); + bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc); spin_unlock_irqrestore(&bnad->bna_lock, flags); } @@ -3067,7 +3067,6 @@ bnad_pci_probe(struct pci_dev *pdev, } bnad = netdev_priv(netdev); - /* * PCI initialization * Output : using_dac = 1 for 64 bit DMA @@ -3239,7 +3238,7 @@ bnad_module_init(void) pr_info("Brocade 10G Ethernet driver\n"); - bfa_ioc_auto_recover(bnad_ioc_auto_recover); + bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover); err = pci_register_driver(&bnad_pci_driver); if (err < 0) { diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index 7e630f5e8e03..b337bd9bed29 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -276,7 +276,7 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) if (ioc_attr) { memset(ioc_attr, 0, sizeof(*ioc_attr)); spin_lock_irqsave(&bnad->bna_lock, flags); - bfa_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); + bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); spin_unlock_irqrestore(&bnad->bna_lock, flags); strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, -- cgit v1.2.3 From 8870f8427b8fe30b2684b9e569e5ce038faf41ac Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 26 Aug 2010 13:21:26 -0700 Subject: IPVS: ICMPv6 checksum calculation Cc: Xiaoyu Du Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 4f8ddba48011..69661db420d7 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -637,10 +637,12 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, } /* And finally the ICMP checksum */ - icmph->icmp6_cksum = 0; - /* TODO IPv6: is this correct for ICMPv6? */ - ip_vs_checksum_complete(skb, icmp_offset); - skb->ip_summed = CHECKSUM_UNNECESSARY; + icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, + skb->len - icmp_offset, + IPPROTO_ICMPV6, 0); + skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset; + skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum); + skb->ip_summed = CHECKSUM_PARTIAL; if (inout) IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, -- cgit v1.2.3 From bd144550489270a32a531e84a2b4bb6882096236 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 26 Aug 2010 02:54:29 +0000 Subject: IPVS: convert __ip_vs_sched_lock to a spinlock Also rename __ip_vs_sched_lock to ip_vs_sched_lock. Acked-by: Eric Dumazet Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_sched.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index bbc1ac795952..727e45b66953 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -35,7 +35,7 @@ static LIST_HEAD(ip_vs_schedulers); /* lock for service table */ -static DEFINE_RWLOCK(__ip_vs_sched_lock); +static DEFINE_SPINLOCK(ip_vs_sched_lock); /* @@ -108,7 +108,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name) IP_VS_DBG(2, "%s(): sched_name \"%s\"\n", __func__, sched_name); - read_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); list_for_each_entry(sched, &ip_vs_schedulers, n_list) { /* @@ -122,14 +122,14 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name) } if (strcmp(sched_name, sched->name)==0) { /* HIT */ - read_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); return sched; } if (sched->module) module_put(sched->module); } - read_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); return NULL; } @@ -184,10 +184,10 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) /* increase the module use count */ ip_vs_use_count_inc(); - write_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); if (!list_empty(&scheduler->n_list)) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); ip_vs_use_count_dec(); pr_err("%s(): [%s] scheduler already linked\n", __func__, scheduler->name); @@ -200,7 +200,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) */ list_for_each_entry(sched, &ip_vs_schedulers, n_list) { if (strcmp(scheduler->name, sched->name) == 0) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); ip_vs_use_count_dec(); pr_err("%s(): [%s] scheduler already existed " "in the system\n", __func__, scheduler->name); @@ -211,7 +211,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) * Add it into the d-linked scheduler list */ list_add(&scheduler->n_list, &ip_vs_schedulers); - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); pr_info("[%s] scheduler registered.\n", scheduler->name); @@ -229,9 +229,9 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) return -EINVAL; } - write_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); if (list_empty(&scheduler->n_list)) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); pr_err("%s(): [%s] scheduler is not in the list. failed\n", __func__, scheduler->name); return -EINVAL; @@ -241,7 +241,7 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) * Remove it from the d-linked scheduler list */ list_del(&scheduler->n_list); - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); /* decrease the module use count */ ip_vs_use_count_dec(); -- cgit v1.2.3 From 4f72816ef07fdf49338ee0e6764a3961d552994a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 26 Aug 2010 02:54:30 +0000 Subject: IPVS: convert __ip_vs_securetcp_lock to a spinlock Also rename __ip_vs_securetcp_lock to ip_vs_securetcp_lock. Spinlock conversion was suggested by Eric Dumazet. Acked-by: Eric Dumazet Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_ctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 53a88af22503..8ca1a474eed6 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -61,7 +61,7 @@ static DEFINE_RWLOCK(__ip_vs_svc_lock); static DEFINE_RWLOCK(__ip_vs_rs_lock); /* lock for state and timeout tables */ -static DEFINE_RWLOCK(__ip_vs_securetcp_lock); +static DEFINE_SPINLOCK(ip_vs_securetcp_lock); /* lock for drop entry handling */ static DEFINE_SPINLOCK(__ip_vs_dropentry_lock); @@ -204,7 +204,7 @@ static void update_defense_level(void) spin_unlock(&__ip_vs_droppacket_lock); /* secure_tcp */ - write_lock(&__ip_vs_securetcp_lock); + spin_lock(&ip_vs_securetcp_lock); switch (sysctl_ip_vs_secure_tcp) { case 0: if (old_secure_tcp >= 2) @@ -238,7 +238,7 @@ static void update_defense_level(void) old_secure_tcp = sysctl_ip_vs_secure_tcp; if (to_change >= 0) ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1); - write_unlock(&__ip_vs_securetcp_lock); + spin_unlock(&ip_vs_securetcp_lock); local_bh_enable(); } -- cgit v1.2.3 From dee06e4702b5a64b9ca81e650d66223c5b3e7f14 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 26 Aug 2010 02:54:31 +0000 Subject: ipvs: switch to GFP_KERNEL allocations Switch from GFP_ATOMIC allocations to GFP_KERNEL ones in ip_vs_add_service() and ip_vs_new_dest(), as we hold a mutex and are allowed to sleep in this context. Signed-off-by: Eric Dumazet Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_ctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 8ca1a474eed6..ca8ec8c4f311 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -843,7 +843,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, return -EINVAL; } - dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); + dest = kzalloc(sizeof(struct ip_vs_dest), GFP_KERNEL); if (dest == NULL) { pr_err("%s(): no memory.\n", __func__); return -ENOMEM; @@ -1177,7 +1177,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, } #endif - svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); + svc = kzalloc(sizeof(struct ip_vs_service), GFP_KERNEL); if (svc == NULL) { IP_VS_DBG(1, "%s(): no memory\n", __func__); ret = -ENOMEM; -- cgit v1.2.3 From 145ce502e44b57c074c72cfdc855557e19026999 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 24 Aug 2010 13:21:08 +0000 Subject: net/sctp: Use pr_fmt and pr_ Change SCTP_DEBUG_PRINTK and SCTP_DEBUG_PRINTK_IPADDR to use do { print } while (0) guards. Add SCTP_DEBUG_PRINTK_CONT to fix errors in log when lines were continued. Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Add a missing newline in "Failed bind hash alloc" Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/sctp/sctp.h | 48 ++++++++++++++++++++++++++++++------------------ net/sctp/associola.c | 2 ++ net/sctp/chunk.c | 2 ++ net/sctp/inqueue.c | 2 ++ net/sctp/ipv6.c | 4 +++- net/sctp/objcnt.c | 5 +++-- net/sctp/output.c | 2 ++ net/sctp/outqueue.c | 34 ++++++++++++++++++---------------- net/sctp/probe.c | 4 +++- net/sctp/protocol.c | 17 ++++++++--------- net/sctp/sm_make_chunk.c | 2 ++ net/sctp/sm_sideeffect.c | 21 ++++++++++----------- net/sctp/sm_statefuns.c | 20 ++++++++++---------- net/sctp/sm_statetable.c | 42 +++++++++++++++++++++--------------------- net/sctp/socket.c | 39 +++++++++++++++------------------------ net/sctp/transport.c | 9 +++++---- 16 files changed, 136 insertions(+), 117 deletions(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 65946bc43d00..2cb3980b1616 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -275,24 +275,35 @@ struct sctp_mib { /* Print debugging messages. */ #if SCTP_DEBUG extern int sctp_debug_flag; -#define SCTP_DEBUG_PRINTK(whatever...) \ - ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever))) -#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \ - if (sctp_debug_flag) { \ - if (saddr->sa.sa_family == AF_INET6) { \ - printk(KERN_DEBUG \ - lead "%pI6" trail, \ - leadparm, \ - &saddr->v6.sin6_addr, \ - otherparms); \ - } else { \ - printk(KERN_DEBUG \ - lead "%pI4" trail, \ - leadparm, \ - &saddr->v4.sin_addr.s_addr, \ - otherparms); \ - } \ - } +#define SCTP_DEBUG_PRINTK(fmt, args...) \ +do { \ + if (sctp_debug_flag) \ + printk(KERN_DEBUG pr_fmt(fmt), ##args); \ +} while (0) +#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) \ +do { \ + if (sctp_debug_flag) \ + pr_cont(fmt, ##args); \ +} while (0) +#define SCTP_DEBUG_PRINTK_IPADDR(fmt_lead, fmt_trail, \ + args_lead, saddr, args_trail...) \ +do { \ + if (sctp_debug_flag) { \ + if (saddr->sa.sa_family == AF_INET6) { \ + printk(KERN_DEBUG \ + pr_fmt(fmt_lead "%pI6" fmt_trail), \ + args_lead, \ + &saddr->v6.sin6_addr, \ + args_trail); \ + } else { \ + printk(KERN_DEBUG \ + pr_fmt(fmt_lead "%pI4" fmt_trail), \ + args_lead, \ + &saddr->v4.sin_addr.s_addr, \ + args_trail); \ + } \ + } \ +} while (0) #define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; } #define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; } @@ -306,6 +317,7 @@ extern int sctp_debug_flag; #else /* SCTP_DEBUG */ #define SCTP_DEBUG_PRINTK(whatever...) +#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) #define SCTP_DEBUG_PRINTK_IPADDR(whatever...) #define SCTP_ENABLE_DEBUG #define SCTP_DISABLE_DEBUG diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 0b85e5256434..5f1fb8bd862d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -48,6 +48,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 476caaf100ed..6c8556459a75 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -37,6 +37,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index ccb6dc48d15b..397296fb156f 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c @@ -43,6 +43,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 732689140fb8..95e0c8eda1a0 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -47,6 +47,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -336,7 +338,7 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk, memcpy(saddr, baddr, sizeof(union sctp_addr)); SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); } else { - printk(KERN_ERR "%s: asoc:%p Could not find a valid source " + pr_err("%s: asoc:%p Could not find a valid source " "address for the dest:%pI6\n", __func__, asoc, &daddr->v6.sin6_addr); } diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index f73ec0ea93ba..8ef8e7d9eb61 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c @@ -38,6 +38,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -134,8 +136,7 @@ void sctp_dbg_objcnt_init(void) ent = proc_create("sctp_dbg_objcnt", 0, proc_net_sctp, &sctp_objcnt_ops); if (!ent) - printk(KERN_WARNING - "sctp_dbg_objcnt: Unable to create /proc entry.\n"); + pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); } /* Cleanup the objcount entry in the proc filesystem. */ diff --git a/net/sctp/output.c b/net/sctp/output.c index a646681f5acd..901764b17aee 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -41,6 +41,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c04b2eb59186..8c6d379b4bb6 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include /* For struct list_head */ #include @@ -1463,23 +1465,23 @@ static void sctp_check_transmitted(struct sctp_outq *q, /* Display the end of the * current range. */ - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_ack_tsn); } /* Start a new range. */ - SCTP_DEBUG_PRINTK(",%08x", tsn); + SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); dbg_ack_tsn = tsn; break; case 1: /* The last TSN was NOT ACKed. */ if (dbg_last_kept_tsn != dbg_kept_tsn) { /* Display the end of current range. */ - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_kept_tsn); } - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); /* FALL THROUGH... */ default: @@ -1526,18 +1528,18 @@ static void sctp_check_transmitted(struct sctp_outq *q, break; if (dbg_last_kept_tsn != dbg_kept_tsn) - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_kept_tsn); - SCTP_DEBUG_PRINTK(",%08x", tsn); + SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); dbg_kept_tsn = tsn; break; case 0: if (dbg_last_ack_tsn != dbg_ack_tsn) - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_ack_tsn); - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("\n"); /* FALL THROUGH... */ default: @@ -1556,17 +1558,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, switch (dbg_prt_state) { case 0: if (dbg_last_ack_tsn != dbg_ack_tsn) { - SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_ack_tsn); } else { - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); } break; case 1: if (dbg_last_kept_tsn != dbg_kept_tsn) { - SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_kept_tsn); } else { - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); } } #endif /* SCTP_DEBUG */ diff --git a/net/sctp/probe.c b/net/sctp/probe.c index db3a42b8b349..2e63e9dc010e 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c @@ -22,6 +22,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -192,7 +194,7 @@ static __init int sctpprobe_init(void) if (ret) goto remove_proc; - pr_info("SCTP probe registered (port=%d)\n", port); + pr_info("probe registered (port=%d)\n", port); return 0; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5027b83f1cc0..f774e657641a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -707,8 +709,7 @@ static int sctp_ctl_sock_init(void) &init_net); if (err < 0) { - printk(KERN_ERR - "SCTP: Failed to create the SCTP control socket.\n"); + pr_err("Failed to create the SCTP control socket\n"); return err; } return 0; @@ -1206,7 +1207,7 @@ SCTP_STATIC __init int sctp_init(void) __get_free_pages(GFP_ATOMIC, order); } while (!sctp_assoc_hashtable && --order > 0); if (!sctp_assoc_hashtable) { - printk(KERN_ERR "SCTP: Failed association hash alloc.\n"); + pr_err("Failed association hash alloc\n"); status = -ENOMEM; goto err_ahash_alloc; } @@ -1220,7 +1221,7 @@ SCTP_STATIC __init int sctp_init(void) sctp_ep_hashtable = (struct sctp_hashbucket *) kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); if (!sctp_ep_hashtable) { - printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n"); + pr_err("Failed endpoint_hash alloc\n"); status = -ENOMEM; goto err_ehash_alloc; } @@ -1239,7 +1240,7 @@ SCTP_STATIC __init int sctp_init(void) __get_free_pages(GFP_ATOMIC, order); } while (!sctp_port_hashtable && --order > 0); if (!sctp_port_hashtable) { - printk(KERN_ERR "SCTP: Failed bind hash alloc."); + pr_err("Failed bind hash alloc\n"); status = -ENOMEM; goto err_bhash_alloc; } @@ -1248,8 +1249,7 @@ SCTP_STATIC __init int sctp_init(void) INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); } - printk(KERN_INFO "SCTP: Hash tables configured " - "(established %d bind %d)\n", + pr_info("Hash tables configured (established %d bind %d)\n", sctp_assoc_hashsize, sctp_port_hashsize); /* Disable ADDIP by default. */ @@ -1290,8 +1290,7 @@ SCTP_STATIC __init int sctp_init(void) /* Initialize the control inode/socket for handling OOTB packets. */ if ((status = sctp_ctl_sock_init())) { - printk (KERN_ERR - "SCTP: Failed to initialize the SCTP control sock.\n"); + pr_err("Failed to initialize the SCTP control sock\n"); goto err_ctl_sock_init; } diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 246f92924658..2cc46f0962ca 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -50,6 +50,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index f5e5e27cac5e..b21b218d564f 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -47,6 +47,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1146,26 +1148,23 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, case SCTP_DISPOSITION_VIOLATION: if (net_ratelimit()) - printk(KERN_ERR "sctp protocol violation state %d " - "chunkid %d\n", state, subtype.chunk); + pr_err("protocol violation state %d chunkid %d\n", + state, subtype.chunk); break; case SCTP_DISPOSITION_NOT_IMPL: - printk(KERN_WARNING "sctp unimplemented feature in state %d, " - "event_type %d, event_id %d\n", - state, event_type, subtype.chunk); + pr_warn("unimplemented feature in state %d, event_type %d, event_id %d\n", + state, event_type, subtype.chunk); break; case SCTP_DISPOSITION_BUG: - printk(KERN_ERR "sctp bug in state %d, " - "event_type %d, event_id %d\n", + pr_err("bug in state %d, event_type %d, event_id %d\n", state, event_type, subtype.chunk); BUG(); break; default: - printk(KERN_ERR "sctp impossible disposition %d " - "in state %d, event_type %d, event_id %d\n", + pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n", status, state, event_type, subtype.chunk); BUG(); break; @@ -1679,8 +1678,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, sctp_cmd_send_asconf(asoc); break; default: - printk(KERN_WARNING "Impossible command: %u, %p\n", - cmd->verb, cmd->obj.ptr); + pr_warn("Impossible command: %u, %p\n", + cmd->verb, cmd->obj.ptr); break; } diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 24b2cd555637..8b284436be65 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -50,6 +50,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1138,18 +1140,16 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, if (unlikely(!link)) { if (from_addr.sa.sa_family == AF_INET6) { if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address %pI6\n", - __func__, - asoc, - &from_addr.v6.sin6_addr); + pr_warn("%s association %p could not find address %pI6\n", + __func__, + asoc, + &from_addr.v6.sin6_addr); } else { if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address %pI4\n", - __func__, - asoc, - &from_addr.v4.sin_addr.s_addr); + pr_warn("%s association %p could not find address %pI4\n", + __func__, + asoc, + &from_addr.v4.sin_addr.s_addr); } return SCTP_DISPOSITION_DISCARD; } diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 6d9b3aafcc5d..546d4387fb3c 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -66,15 +68,19 @@ static const sctp_sm_table_entry_t bug = { .name = "sctp_sf_bug" }; -#define DO_LOOKUP(_max, _type, _table) \ - if ((event_subtype._type > (_max))) { \ - printk(KERN_WARNING \ - "sctp table %p possible attack:" \ - " event %d exceeds max %d\n", \ - _table, event_subtype._type, _max); \ - return &bug; \ - } \ - return &_table[event_subtype._type][(int)state]; +#define DO_LOOKUP(_max, _type, _table) \ +({ \ + const sctp_sm_table_entry_t *rtn; \ + \ + if ((event_subtype._type > (_max))) { \ + pr_warn("table %p possible attack: event %d exceeds max %d\n", \ + _table, event_subtype._type, _max); \ + rtn = &bug; \ + } else \ + rtn = &_table[event_subtype._type][(int)state]; \ + \ + rtn; \ +}) const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, sctp_state_t state, @@ -83,21 +89,15 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, switch (event_type) { case SCTP_EVENT_T_CHUNK: return sctp_chunk_event_lookup(event_subtype.chunk, state); - break; case SCTP_EVENT_T_TIMEOUT: - DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, - timeout_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, + timeout_event_table); case SCTP_EVENT_T_OTHER: - DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, other_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, + other_event_table); case SCTP_EVENT_T_PRIMITIVE: - DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, - primitive_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, + primitive_event_table); default: /* Yikes! We got an illegal event type. */ return &bug; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca44917872d2..f4bec2772351 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -57,6 +57,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -2458,9 +2460,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, if (params.sack_delay == 0 && params.sack_freq == 0) return 0; } else if (optlen == sizeof(struct sctp_assoc_value)) { - printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " - "in delayed_ack socket option deprecated\n"); - printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); + pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); + pr_warn("Use struct sctp_sack_info instead\n"); if (copy_from_user(¶ms, optval, optlen)) return -EFAULT; @@ -2868,10 +2869,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int val; if (optlen == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in maxseg socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in maxseg socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); if (copy_from_user(&val, optval, optlen)) return -EFAULT; params.assoc_id = 0; @@ -3121,10 +3120,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, int assoc_id = 0; if (optlen == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in max_burst socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in max_burst socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); if (copy_from_user(&val, optval, optlen)) return -EFAULT; } else if (optlen == sizeof(struct sctp_assoc_value)) { @@ -4281,9 +4278,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, if (copy_from_user(¶ms, optval, len)) return -EFAULT; } else if (len == sizeof(struct sctp_assoc_value)) { - printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " - "in delayed_ack socket option deprecated\n"); - printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); + pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); + pr_warn("Use struct sctp_sack_info instead\n"); if (copy_from_user(¶ms, optval, len)) return -EFAULT; } else @@ -4929,10 +4925,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, struct sctp_association *asoc; if (len == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in maxseg socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in maxseg socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); params.assoc_id = 0; } else if (len >= sizeof(struct sctp_assoc_value)) { len = sizeof(struct sctp_assoc_value); @@ -5023,10 +5017,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, struct sctp_association *asoc; if (len == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in max_burst socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in max_burst socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); params.assoc_id = 0; } else if (len >= sizeof(struct sctp_assoc_value)) { len = sizeof(struct sctp_assoc_value); @@ -5586,8 +5578,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { if (net_ratelimit()) { - printk(KERN_INFO - "SCTP: failed to load transform for %s: %ld\n", + pr_info("failed to load transform for %s: %ld\n", sctp_hmac_alg, PTR_ERR(tfm)); } return -ENOSYS; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 132046cb82fc..d3ae493d234a 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -48,6 +48,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -244,10 +246,9 @@ void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) struct dst_entry *dst; if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { - printk(KERN_WARNING "%s: Reported pmtu %d too low, " - "using default minimum of %d\n", - __func__, pmtu, - SCTP_DEFAULT_MINSEGMENT); + pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", + __func__, pmtu, + SCTP_DEFAULT_MINSEGMENT); /* Use default minimum segment size and disable * pmtu discovery on this transport. */ -- cgit v1.2.3 From 53f91dc1f76922375ad7957ef29f48986722532d Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 24 Aug 2010 13:32:58 +0000 Subject: net: use scnprintf() to avoid potential buffer overflow strlcpy() returns the total length of the string they tried to create, so we should not use its return value without any check. scnprintf() returns the number of characters written into @buf not including the trailing '\0', so use it instead here. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/ethernet/eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 215c83986a9d..85e7b4551326 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -367,7 +367,7 @@ struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count) EXPORT_SYMBOL(alloc_etherdev_mq); static size_t _format_mac_addr(char *buf, int buflen, - const unsigned char *addr, int len) + const unsigned char *addr, int len) { int i; char *cp = buf; @@ -376,7 +376,7 @@ static size_t _format_mac_addr(char *buf, int buflen, cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]); if (i == len - 1) break; - cp += strlcpy(cp, ":", buflen - (cp - buf)); + cp += scnprintf(cp, buflen - (cp - buf), ":"); } return cp - buf; } @@ -386,7 +386,7 @@ ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len) size_t l; l = _format_mac_addr(buf, PAGE_SIZE, addr, len); - l += strlcpy(buf + l, "\n", PAGE_SIZE - l); + l += scnprintf(buf + l, PAGE_SIZE - l, "\n"); return ((ssize_t) l); } EXPORT_SYMBOL(sysfs_format_mac); -- cgit v1.2.3 From 8cfdce080722101a7fd2a1eff9763ca4008ec626 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 26 Aug 2010 14:02:41 +0000 Subject: qlcnic: Fix missing error codes In the original code, the error codes returned from some of the functions are not caught and sent up the caller chain. Fixed it here. Signed-off-by: Sony Chacko Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 630a077e4547..1b8f67dab9b8 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -967,7 +967,8 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) if (load_fw_file) qlcnic_request_firmware(adapter); else { - if (qlcnic_check_flash_fw_ver(adapter)) + err = qlcnic_check_flash_fw_ver(adapter); + if (err) goto err_out; adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; @@ -998,9 +999,11 @@ set_dev_ready: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); - if (qlcnic_set_default_offload_settings(adapter)) + err = qlcnic_set_default_offload_settings(adapter); + if (err) goto err_out; - if (qlcnic_reset_npar_config(adapter)) + err = qlcnic_reset_npar_config(adapter); + if (err) goto err_out; qlcnic_dev_set_npar_ready(adapter); qlcnic_check_options(adapter); @@ -1515,7 +1518,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (qlcnic_read_mac_addr(adapter)) dev_warn(&pdev->dev, "failed to read mac addr\n"); - if (qlcnic_setup_idc_param(adapter)) + err = qlcnic_setup_idc_param(adapter); + if (err) goto err_out_iounmap; err = adapter->nic_ops->start_firmware(adapter); -- cgit v1.2.3 From 0866d96da02cccc3ca837d0d71687aba962b3f2f Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Thu, 26 Aug 2010 14:02:52 +0000 Subject: qlcnic: Fix driver load issue in FW hang If there is a FW hang when the driver loads, it can not determine the FW operational mode. Fix it by checking the FW state first before issuing any FW commands to determine its capabilities and thereby detecting driver operational mode. Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_hdr.h | 2 +- drivers/net/qlcnic/qlcnic_init.c | 16 ++++-- drivers/net/qlcnic/qlcnic_main.c | 116 +++++++++++++++++++++------------------ 4 files changed, 75 insertions(+), 60 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index d15de63ed0bb..0a537044d7da 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -902,6 +902,7 @@ struct qlcnic_mac_req { #define QLCNIC_BRIDGE_ENABLED 0X10 #define QLCNIC_DIAG_ENABLED 0x20 #define QLCNIC_ESWITCH_ENABLED 0x40 +#define QLCNIC_ADAPTER_INITIALIZED 0x80 #define QLCNIC_TAGGING_ENABLED 0x100 #define QLCNIC_MACSPOOF 0x200 #define QLCNIC_IS_MSI_FAMILY(adapter) \ diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 219de9f4496f..bce1b1d541b7 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -748,7 +748,7 @@ enum { #define QLCNIC_RESET_TIMEOUT_SECS 10 #define QLCNIC_INIT_TIMEOUT_SECS 30 #define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 -#define QLCNIC_HEARTBEAT_RETRY_COUNT 30 +#define QLCNIC_HEARTBEAT_RETRY_COUNT 45 #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index df91b754bb70..eb8256bec516 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -547,7 +547,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) int qlcnic_check_fw_status(struct qlcnic_adapter *adapter) { - u32 heartbit, ret = -EIO; + u32 heartbit, cmdpeg_state, ret = -EIO; int retries = QLCNIC_HEARTBEAT_RETRY_COUNT; adapter->heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); @@ -555,10 +555,16 @@ qlcnic_check_fw_status(struct qlcnic_adapter *adapter) msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); if (heartbit != adapter->heartbit) { - /* Complete firmware handshake */ - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); - ret = QLCNIC_RCODE_SUCCESS; - break; + cmdpeg_state = QLCRD32(adapter, CRB_CMDPEG_STATE); + /* Ensure peg states are initialized */ + if (cmdpeg_state == PHAN_INITIALIZE_COMPLETE || + cmdpeg_state == PHAN_INITIALIZE_ACK) { + /* Complete firmware handshake */ + QLCWR32(adapter, CRB_CMDPEG_STATE, + PHAN_INITIALIZE_ACK); + ret = QLCNIC_RCODE_SUCCESS; + break; + } } } while (--retries); diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 1b8f67dab9b8..6999d5aaa157 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -566,12 +566,11 @@ err_lock: return ret; } -static u32 -qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) +static void +qlcnic_check_vf(struct qlcnic_adapter *adapter) { void __iomem *msix_base_addr; void __iomem *priv_op; - struct qlcnic_info nic_info; u32 func; u32 msix_base; u32 op_mode, priv_level; @@ -586,20 +585,6 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; adapter->ahw.pci_func = func; - if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { - adapter->capabilities = nic_info.capabilities; - - if (adapter->capabilities & BIT_6) - adapter->flags |= QLCNIC_ESWITCH_ENABLED; - else - adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; - } - - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { - adapter->nic_ops = &qlcnic_ops; - return adapter->fw_hal_version; - } - /* Determine function privilege level */ priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; op_mode = readl(priv_op); @@ -608,37 +593,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) else priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); - switch (priv_level) { - case QLCNIC_MGMT_FUNC: - adapter->op_mode = QLCNIC_MGMT_FUNC; - adapter->nic_ops = &qlcnic_ops; - qlcnic_init_pci_info(adapter); - /* Set privilege level for other functions */ - qlcnic_set_function_modes(adapter); - dev_info(&adapter->pdev->dev, - "HAL Version: %d, Management function\n", - adapter->fw_hal_version); - break; - case QLCNIC_PRIV_FUNC: - adapter->op_mode = QLCNIC_PRIV_FUNC; - dev_info(&adapter->pdev->dev, - "HAL Version: %d, Privileged function\n", - adapter->fw_hal_version); - adapter->nic_ops = &qlcnic_ops; - break; - case QLCNIC_NON_PRIV_FUNC: + if (priv_level == QLCNIC_NON_PRIV_FUNC) { adapter->op_mode = QLCNIC_NON_PRIV_FUNC; dev_info(&adapter->pdev->dev, "HAL Version: %d Non Privileged function\n", adapter->fw_hal_version); adapter->nic_ops = &qlcnic_vf_ops; - break; - default: - dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", - priv_level); - return 0; - } - return adapter->fw_hal_version; + } else + adapter->nic_ops = &qlcnic_ops; } static int @@ -671,10 +633,7 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) adapter->ahw.pci_base0 = mem_ptr0; adapter->ahw.pci_len0 = pci_len0; - if (!qlcnic_get_driver_mode(adapter)) { - iounmap(adapter->ahw.pci_base0); - return -EIO; - } + qlcnic_check_vf(adapter); adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); @@ -719,6 +678,9 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); + if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) + if (qlcnic_read_mac_addr(adapter)) + dev_warn(&pdev->dev, "failed to read mac addr\n"); if (adapter->portnum == 0) { get_brd_name(adapter, brd_name); @@ -836,6 +798,51 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, netdev->vlan_features = (features & vlan_features); } +static int +qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) +{ + void __iomem *priv_op; + u32 op_mode, priv_level; + int err = 0; + + if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) + return 0; + + priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; + op_mode = readl(priv_op); + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + + if (op_mode == QLC_DEV_DRV_DEFAULT) + priv_level = QLCNIC_MGMT_FUNC; + else + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + + if (adapter->capabilities & BIT_6) { + adapter->flags |= QLCNIC_ESWITCH_ENABLED; + if (priv_level == QLCNIC_MGMT_FUNC) { + adapter->op_mode = QLCNIC_MGMT_FUNC; + err = qlcnic_init_pci_info(adapter); + if (err) + return err; + /* Set privilege level for other functions */ + qlcnic_set_function_modes(adapter); + dev_info(&adapter->pdev->dev, + "HAL Version: %d, Management function\n", + adapter->fw_hal_version); + } else if (priv_level == QLCNIC_PRIV_FUNC) { + adapter->op_mode = QLCNIC_PRIV_FUNC; + dev_info(&adapter->pdev->dev, + "HAL Version: %d, Privileged function\n", + adapter->fw_hal_version); + } + } else + adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; + + adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; + + return err; +} + static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) { @@ -1005,8 +1012,14 @@ set_dev_ready: err = qlcnic_reset_npar_config(adapter); if (err) goto err_out; - qlcnic_dev_set_npar_ready(adapter); qlcnic_check_options(adapter); + err = qlcnic_check_eswitch_mode(adapter); + if (err) { + dev_err(&adapter->pdev->dev, + "Memory allocation failed for eswitch\n"); + goto err_out; + } + qlcnic_dev_set_npar_ready(adapter); adapter->need_fw_reset = 0; qlcnic_release_firmware(adapter); @@ -1015,6 +1028,7 @@ set_dev_ready: err_out: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); dev_err(&adapter->pdev->dev, "Device state set to failed\n"); + qlcnic_release_firmware(adapter); return err; } @@ -1419,9 +1433,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->features |= NETIF_F_LRO; netdev->irq = adapter->msix_entries[0].vector; - if (qlcnic_read_mac_addr(adapter)) - dev_warn(&pdev->dev, "failed to read mac addr\n"); - netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -1515,9 +1526,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iounmap; } - if (qlcnic_read_mac_addr(adapter)) - dev_warn(&pdev->dev, "failed to read mac addr\n"); - err = qlcnic_setup_idc_param(adapter); if (err) goto err_out_iounmap; -- cgit v1.2.3 From e132d8d3d2b4df0895fe73c9cfad53b3a5329edf Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 26 Aug 2010 14:03:05 +0000 Subject: qlcnic: PCI ID addition Added PCI ID to board info. Signed-off-by: Sritej Velaga Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 0a537044d7da..1f5c10bc9376 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1326,6 +1326,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x1077, 0x20f, "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, + {0x1077, 0x8020, 0x103c, 0x3733, + "NC523SFP 10Gb 2-port Flex-10 Server Adapter"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; -- cgit v1.2.3 From 250ad8f55c06eb866cfb57f8d3ea6ff961a7d1d7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 Aug 2010 20:32:02 -0700 Subject: stmmac: Make time functionality depend upon RTC_HCTOSYS_DEVICE Based upon a report by Stephen Rothwell. Signed-off-by: David S. Miller --- drivers/net/stmmac/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig index 643968098afd..3c2af7c6a39b 100644 --- a/drivers/net/stmmac/Kconfig +++ b/drivers/net/stmmac/Kconfig @@ -32,6 +32,7 @@ config STMMAC_DUAL_MAC config STMMAC_TIMER bool "STMMAC Timer optimisation" default n + depends on RTC_HCTOSYS_DEVICE help Use an external timer for mitigating the number of network interrupts. Currently, for SH architectures, it is possible -- cgit v1.2.3 From 40d0802b3eb47d57e2d57a5244a18cbbe9632e13 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 26 Aug 2010 22:03:08 -0700 Subject: gro: __napi_gro_receive() optimizations compare_ether_header() can have a special implementation on 64 bit arches if CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is defined. __napi_gro_receive() and vlan_gro_common() can avoid a conditional branch to perform device match. On x86_64, __napi_gro_receive() has now 38 instructions instead of 53 As gcc-4.4.3 still choose to not inline it, add inline keyword to this performance critical function. Signed-off-by: Eric Dumazet CC: Herbert Xu Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 18 +++++++++++++++++- net/8021q/vlan_core.c | 9 ++++++--- net/core/dev.c | 10 ++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 2308fbb4523a..fb6aa6070921 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -237,13 +237,29 @@ static inline bool is_etherdev_addr(const struct net_device *dev, * entry points. */ -static inline int compare_ether_header(const void *a, const void *b) +static inline unsigned long compare_ether_header(const void *a, const void *b) { +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 + unsigned long fold; + + /* + * We want to compare 14 bytes: + * [a0 ... a13] ^ [b0 ... b13] + * Use two long XOR, ORed together, with an overlap of two bytes. + * [a0 a1 a2 a3 a4 a5 a6 a7 ] ^ [b0 b1 b2 b3 b4 b5 b6 b7 ] | + * [a6 a7 a8 a9 a10 a11 a12 a13] ^ [b6 b7 b8 b9 b10 b11 b12 b13] + * This means the [a6 a7] ^ [b6 b7] part is done two times. + */ + fold = *(unsigned long *)a ^ *(unsigned long *)b; + fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6); + return fold; +#else u32 *a32 = (u32 *)((u8 *)a + 2); u32 *b32 = (u32 *)((u8 *)b + 2); return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) | (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]); +#endif } #endif /* _LINUX_ETHERDEVICE_H */ diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 07eeb5b99dce..3438c01bbacf 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -105,9 +105,12 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, goto drop; for (p = napi->gro_list; p; p = p->next) { - NAPI_GRO_CB(p)->same_flow = - p->dev == skb->dev && !compare_ether_header( - skb_mac_header(p), skb_gro_mac_header(skb)); + unsigned long diffs; + + diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; + diffs |= compare_ether_header(skb_mac_header(p), + skb_gro_mac_header(skb)); + NAPI_GRO_CB(p)->same_flow = !diffs; NAPI_GRO_CB(p)->flush = 0; } diff --git a/net/core/dev.c b/net/core/dev.c index 859e30ff044a..63bd20a75929 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3169,16 +3169,18 @@ normal: } EXPORT_SYMBOL(dev_gro_receive); -static gro_result_t +static inline gro_result_t __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { struct sk_buff *p; for (p = napi->gro_list; p; p = p->next) { - NAPI_GRO_CB(p)->same_flow = - (p->dev == skb->dev) && - !compare_ether_header(skb_mac_header(p), + unsigned long diffs; + + diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; + diffs |= compare_ether_header(skb_mac_header(p), skb_gro_mac_header(skb)); + NAPI_GRO_CB(p)->same_flow = !diffs; NAPI_GRO_CB(p)->flush = 0; } -- cgit v1.2.3 From 0fdf4d096102464e290d5ccaee8ad0cee7bd9e8a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 26 Aug 2010 22:03:53 -0700 Subject: bnx2x: fix wrong return from bnx2x_trylock_hw_lock bnx2x_trylock_hw_lock() returns a bool : true if succeeded to acquire the lock. false in case of error. -EINVAL is not an acceptable value, since its promoted to true. Signed-off-by: Eric Dumazet Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 05a08d1a09f3..7fb9a61a73c7 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -781,7 +781,7 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) DP(NETIF_MSG_HW, "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", resource, HW_LOCK_MAX_RESOURCE_VALUE); - return -EINVAL; + return false; } if (func <= 5) -- cgit v1.2.3 From 246ed355221076884d225f9d8a4c30a048be8162 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:32 +0200 Subject: iwlwifi: initial contextification In order to support multiple interfaces, we must move a lot of data into per-context structures so we can use the contexts the device offers. To start with, this makes a lot of code context-aware, more changes will move more things into the context structure. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 3 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 53 ++-- drivers/net/wireless/iwlwifi/iwl-4965.c | 46 ++-- drivers/net/wireless/iwlwifi/iwl-5000.c | 15 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 15 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 12 +- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 27 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 26 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 172 +++++++----- drivers/net/wireless/iwlwifi/iwl-agn.h | 3 +- drivers/net/wireless/iwlwifi/iwl-core.c | 391 ++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-core.h | 38 ++- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 62 ++++- drivers/net/wireless/iwlwifi/iwl-rx.c | 9 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 9 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 6 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 111 ++++---- 19 files changed, 611 insertions(+), 400 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 8e84a08ff951..08f53f869c18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -949,7 +949,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) switch (priv->band) { case IEEE80211_BAND_2GHZ: /* TODO: this always does G, not a regression */ - if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { + if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_TGG_PROTECT_MSK) { rs_sta->tgg = 1; rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; } else diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8ccfcd08218d..f4aa229986ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -245,7 +245,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) break; case IEEE80211_BAND_2GHZ: if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv)) { + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { if (rate == IWL_RATE_11M_INDEX) next_rate = IWL_RATE_5M_INDEX; } @@ -1439,17 +1439,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv) int rate_idx, i; const struct iwl_channel_info *ch_info = NULL; struct iwl3945_txpowertable_cmd txpower = { - .channel = priv->active_rxon.channel, + .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, }; + u16 chan; + + chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; - ch_info = iwl_get_channel_info(priv, - priv->band, - le16_to_cpu(priv->active_rxon.channel)); + ch_info = iwl_get_channel_info(priv, priv->band, chan); if (!ch_info) { IWL_ERR(priv, "Failed to get channel info for channel %d [%d]\n", - le16_to_cpu(priv->active_rxon.channel), priv->band); + chan, priv->band); return -EINVAL; } @@ -1710,7 +1711,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) return 0; } -static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) +static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int rc = 0; struct iwl_rx_packet *pkt; @@ -1721,8 +1723,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) .flags = CMD_WANT_SKB, .data = &rxon_assoc, }; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1732,10 +1734,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved = 0; rc = iwl_send_cmd_sync(priv, &cmd); @@ -1761,14 +1763,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -static int iwl3945_commit_rxon(struct iwl_priv *priv) +static int iwl3945_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; - struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; + struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; + struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; int rc = 0; - bool new_assoc = - !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); + bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -1; @@ -1781,7 +1783,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); staging_rxon->flags |= iwl3945_get_antenna_flags(priv); - rc = iwl_check_rxon_cmd(priv); + rc = iwl_check_rxon_cmd(priv, ctx); if (rc) { IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1790,8 +1792,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl3945_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv)) { - rc = iwl_send_rxon_assoc(priv); + if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) { + rc = iwl_send_rxon_assoc(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); if (rc) { IWL_ERR(priv, "Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1807,7 +1810,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (iwl_is_associated(priv) && new_assoc) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; @@ -1819,7 +1822,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) active_rxon->reserved5 = 0; rc = iwl_send_cmd_pdu(priv, REPLY_RXON, sizeof(struct iwl3945_rxon_cmd), - &priv->active_rxon); + &priv->contexts[IWL_RXON_CTX_BSS].active); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ @@ -1848,7 +1851,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) staging_rxon->reserved4 = 0; staging_rxon->reserved5 = 0; - iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto); + iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); /* Apply the new configuration */ rc = iwl_send_cmd_pdu(priv, REPLY_RXON, @@ -2366,7 +2369,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) * 1M CCK rates */ if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv)) { + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { index = IWL_FIRST_CCK_RATE; for (i = IWL_RATE_6M_INDEX_TABLE; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index f0a47f42d4b8..82f32305f50e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) struct iwl_chain_noise_data *data = &(priv->chain_noise_data); if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_associated(priv)) { + iwl_is_any_associated(priv)) { struct iwl_calib_diff_gain_cmd cmd; /* clear data for chain noise calibration algorithm */ @@ -1374,6 +1374,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) u8 band = 0; bool is_ht40 = false; u8 ctrl_chan_high = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (test_bit(STATUS_SCANNING, &priv->status)) { /* If this gets hit a lot, switch it to a BUG() and catch @@ -1385,17 +1386,16 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) band = priv->band == IEEE80211_BAND_2GHZ; - is_ht40 = is_ht40_channel(priv->active_rxon.flags); + is_ht40 = is_ht40_channel(ctx->active.flags); - if (is_ht40 && - (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; - cmd.channel = priv->active_rxon.channel; + cmd.channel = ctx->active.channel; ret = iwl4965_fill_txpower_tbl(priv, band, - le16_to_cpu(priv->active_rxon.channel), + le16_to_cpu(ctx->active.channel), is_ht40, ctrl_chan_high, &cmd.tx_power); if (ret) goto out; @@ -1406,12 +1406,13 @@ out: return ret; } -static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) +static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int ret = 0; struct iwl4965_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1426,16 +1427,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - priv->staging_rxon.ofdm_ht_single_stream_basic_rates; + ctx->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, sizeof(rxon_assoc), &rxon_assoc, NULL); @@ -1448,6 +1449,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) static int iwl4965_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int rc; u8 band = 0; bool is_ht40 = false; @@ -1458,22 +1460,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); struct ieee80211_vif *vif = priv->vif; band = priv->band == IEEE80211_BAND_2GHZ; - is_ht40 = is_ht40_channel(priv->staging_rxon.flags); + is_ht40 = is_ht40_channel(ctx->staging.flags); if (is_ht40 && - (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; cmd.expect_beacon = 0; ch = ch_switch->channel->hw_value; cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -1508,7 +1510,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 013f3dae69f1..8536f19d7dcc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -275,13 +275,18 @@ static void iwl5150_temperature(struct iwl_priv *priv) static int iwl5000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl5000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); struct ieee80211_vif *vif = priv->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, @@ -293,10 +298,10 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, cmd.band = priv->band == IEEE80211_BAND_2GHZ; ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -331,7 +336,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } priv->switch_rxon.channel = cmd.channel; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index fc9344b873ba..bf1fe25fae73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -198,13 +198,18 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl6000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); struct ieee80211_vif *vif = priv->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, @@ -216,10 +221,10 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, cmd.band = priv->band == IEEE80211_BAND_2GHZ; ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -254,7 +259,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } priv->switch_rxon.channel = cmd.channel; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 156b125dba71..84ad62958535 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -625,7 +625,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) data = &(priv->sensitivity_data); - if (!iwl_is_associated(priv)) { + if (!iwl_is_any_associated(priv)) { IWL_DEBUG_CALIB(priv, "<< - not associated\n"); return; } @@ -763,6 +763,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) unsigned long flags; struct statistics_rx_non_phy *rx_info; u8 first_chain; + /* + * MULTI-FIXME: + * When we support multiple interfaces on different channels, + * this must be modified/fixed. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (priv->disable_chain_noise_cal) return; @@ -793,8 +799,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) return; } - rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); - rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); + rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); + rxon_chnum = le16_to_cpu(ctx->staging.channel); if (priv->cfg->bt_statistics) { stat_band24 = !!(((struct iwl_bt_notif_statistics *) stat_resp)->flag & diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 84fe06adcef4..3e5069943dde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -37,12 +37,13 @@ #include "iwl-io.h" #include "iwl-agn.h" -int iwlagn_send_rxon_assoc(struct iwl_priv *priv) +int iwlagn_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int ret = 0; struct iwl5000_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -60,21 +61,21 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved1 = 0; rxon_assoc.reserved2 = 0; rxon_assoc.reserved3 = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - priv->staging_rxon.ofdm_ht_single_stream_basic_rates; + ctx->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; rxon_assoc.ofdm_ht_triple_stream_basic_rates = - priv->staging_rxon.ofdm_ht_triple_stream_basic_rates; - rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data; + ctx->staging.ofdm_ht_triple_stream_basic_rates; + rxon_assoc.acquisition_data = ctx->staging.acquisition_data; ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, sizeof(rxon_assoc), &rxon_assoc, NULL); @@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) int ret; if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_associated(priv)) { + iwl_is_any_associated(priv)) { struct iwl_calib_chain_noise_reset_cmd cmd; /* clear data for chain noise calibration algorithm */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a9e69a6213f4..531a7dc3dc72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1232,7 +1232,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -1289,7 +1289,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) switch (priv->scan_band) { case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK) + chan_mod = le32_to_cpu( + priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_CHANNEL_MODE_MSK) >> RXON_FLG_CHANNEL_MODE_POS; if (chan_mod == CHANNEL_MODE_PURE_40) { rate = IWL_RATE_6M_PLCP; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 30298ea56a24..07b2c6cadf51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -416,18 +416,26 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) /* stop ct_kill_waiting_tm timer */ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); if (changed) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; - if (tt->state >= IWL_TI_1) { /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ tt->tt_power_mode = IWL_POWER_INDEX_5; - if (!iwl_ht_enabled(priv)) - /* disable HT */ - rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | - RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | - RXON_FLG_HT40_PROT_MSK | - RXON_FLG_HT_PROT_MSK); - else { + + if (!iwl_ht_enabled(priv)) { + struct iwl_rxon_context *ctx; + + for_each_context(priv, ctx) { + struct iwl_rxon_cmd *rxon; + + rxon = &ctx->staging; + + /* disable HT */ + rxon->flags &= ~( + RXON_FLG_CHANNEL_MODE_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | + RXON_FLG_HT40_PROT_MSK | + RXON_FLG_HT_PROT_MSK); + } + } else { /* check HT capability and set * according to the system HT capability * in case get disabled before */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5e0d0d527bf0..e073069a44c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -98,21 +98,21 @@ static bool iwlagn_bt_ch_announce = 1; * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -int iwl_commit_rxon(struct iwl_priv *priv) +int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; int ret; bool new_assoc = - !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); + !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -EBUSY; /* always get timestamp with Rx frame */ - priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - ret = iwl_check_rxon_cmd(priv); + ret = iwl_check_rxon_cmd(priv, ctx); if (ret) { IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -123,7 +123,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) * abort any previous channel switch if still in process */ if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != priv->staging_rxon.channel)) { + (priv->switch_rxon.channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", le16_to_cpu(priv->switch_rxon.channel)); iwl_chswitch_done(priv, false); @@ -132,15 +132,15 @@ int iwl_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv)) { - ret = iwl_send_rxon_assoc(priv); + if (!iwl_full_rxon_required(priv, ctx)) { + ret = iwl_send_rxon_assoc(priv, ctx); if (ret) { IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); return ret; } - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); - iwl_print_rx_config_cmd(priv); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_print_rx_config_cmd(priv, ctx); return 0; } @@ -148,13 +148,13 @@ int iwl_commit_rxon(struct iwl_priv *priv) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (iwl_is_associated(priv) && new_assoc) { + if (iwl_is_associated_ctx(ctx) && new_assoc) { IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), - &priv->active_rxon); + sizeof(struct iwl_rxon_cmd), + active_rxon); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ @@ -177,10 +177,10 @@ int iwl_commit_rxon(struct iwl_priv *priv) "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), - le16_to_cpu(priv->staging_rxon.channel), - priv->staging_rxon.bssid_addr); + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); - iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); + iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of @@ -188,13 +188,13 @@ int iwl_commit_rxon(struct iwl_priv *priv) */ if (!new_assoc) { ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); return ret; } IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); iwl_clear_ucode_stations(priv); iwl_restore_stations(priv); ret = iwl_restore_default_wep_keys(priv); @@ -210,14 +210,14 @@ int iwl_commit_rxon(struct iwl_priv *priv) * RXON assoc doesn't clear the station table in uCode, */ ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); return ret; } - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); } - iwl_print_rx_config_cmd(priv); + iwl_print_rx_config_cmd(priv, ctx); iwl_init_sensitivity(priv); @@ -234,10 +234,14 @@ int iwl_commit_rxon(struct iwl_priv *priv) void iwl_update_chain_flags(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); - iwlcore_commit_rxon(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) { + for_each_context(priv, ctx) { + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlcore_commit_rxon(priv, ctx); + } + } } static void iwl_clear_free_frames(struct iwl_priv *priv) @@ -633,6 +637,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, bt_full_concurrency); + struct iwl_rxon_context *ctx; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -649,9 +654,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) * LQ & RXON updated cmds must be sent before BT Config cmd * to avoid 3-wire collisions */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); - iwlcore_commit_rxon(priv); + mutex_lock(&priv->mutex); + for_each_context(priv, ctx) { + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlcore_commit_rxon(priv, ctx); + } + mutex_unlock(&priv->mutex); priv->cfg->ops->hcmd->send_bt_config(priv); } @@ -2710,6 +2719,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) static void iwl_alive_start(struct iwl_priv *priv) { int ret = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); @@ -2758,18 +2768,18 @@ static void iwl_alive_start(struct iwl_priv *priv) if (priv->cfg->ops->hcmd->set_tx_ant) priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); - if (iwl_is_associated(priv)) { + if (iwl_is_associated_ctx(ctx)) { struct iwl_rxon_cmd *active_rxon = - (struct iwl_rxon_cmd *)&priv->active_rxon; + (struct iwl_rxon_cmd *)&ctx->active; /* apply any changes in staging */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ iwl_connection_init_rx_config(priv, NULL); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } if (!priv->cfg->advanced_bt_coexist) { @@ -2780,7 +2790,7 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_reset_run_time_calib(priv); /* Configure the adapter for unassociated operation */ - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); /* At this point, the NIC is initialized and operational */ iwl_rf_kill_ct_config(priv); @@ -3195,12 +3205,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data) void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx; struct ieee80211_conf *conf = NULL; int ret = 0; if (!vif || !priv->is_open) return; + ctx = iwl_rxon_ctx_from_vif(vif); + if (vif->type == NL80211_IFTYPE_AP) { IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); return; @@ -3213,42 +3226,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) conf = ieee80211_get_hw_conf(priv->hw); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); ret = iwl_send_rxon_timing(priv, vif); if (ret) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; iwl_set_rxon_ht(priv, &priv->current_ht_config); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, priv->active_rxon.bssid_addr); + vif->bss_conf.aid, ctx->active.bssid_addr); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3439,17 +3452,18 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret = 0; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ - if (!iwl_is_associated(priv)) { + if (!iwl_is_associated_ctx(ctx)) { /* RXON - unassoc (to set timing command) */ - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); /* RXON Timing */ ret = iwl_send_rxon_timing(priv, vif); @@ -3462,28 +3476,28 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->hw_params.valid_rx_ant; iwl_set_rxon_ht(priv, &priv->current_ht_config); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - priv->staging_rxon.assoc_id = 0; + ctx->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); } iwl_send_beacon_cmd(priv); @@ -3737,6 +3751,15 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; + /* + * MULTI-FIXME + * When we add support for multiple interfaces, we need to + * revisit this. The channel switch command in the device + * only affects the BSS context, but what does that really + * mean? And what if we get a CSA on the second interface? + * This needs a lot of work. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u16 ch; unsigned long flags = 0; @@ -3749,7 +3772,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, test_bit(STATUS_SCANNING, &priv->status)) goto out_exit; - if (!iwl_is_associated(priv)) + if (!iwl_is_associated_ctx(ctx)) goto out_exit; /* channel switch in progress */ @@ -3760,7 +3783,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, if (priv->cfg->ops->lib->set_channel_switch) { ch = channel->hw_value; - if (le16_to_cpu(priv->active_rxon.channel) != ch) { + if (le16_to_cpu(ctx->active.channel) != ch) { ch_info = iwl_get_channel_info(priv, channel->band, ch); @@ -3791,12 +3814,12 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, } else ht_conf->is_40mhz = false; - if (le16_to_cpu(priv->staging_rxon.channel) != ch) - priv->staging_rxon.flags = 0; + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; - iwl_set_rxon_channel(priv, channel); + iwl_set_rxon_channel(priv, channel, ctx); iwl_set_rxon_ht(priv, ht_conf); - iwl_set_flags_for_band(priv, channel->band, + iwl_set_flags_for_band(priv, ctx, channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); @@ -3825,6 +3848,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3844,10 +3868,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - priv->staging_rxon.filter_flags &= ~filter_nand; - priv->staging_rxon.filter_flags |= filter_or; - - iwlcore_commit_rxon(priv); + for_each_context(priv, ctx) { + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; + iwlcore_commit_rxon(priv, ctx); + } mutex_unlock(&priv->mutex); @@ -4018,7 +4043,8 @@ static int iwl_init_drv(struct iwl_priv *priv) /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); iwl_init_scan_params(priv); @@ -4118,7 +4144,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; + int err = 0, i; struct iwl_priv *priv; struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); @@ -4146,6 +4172,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv = hw->priv; /* At this point both hw and priv are allocated. */ + /* + * The default context is always valid, + * more may be discovered when firmware + * is loaded. + */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + SET_IEEE80211_DEV(hw, &pdev->dev); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 1a7f70f293a0..7c542a8c8f81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -224,7 +224,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); /* hcmd */ -int iwlagn_send_rxon_assoc(struct iwl_priv *priv); +int iwlagn_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); /* bt coex */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c43124c997cc..cc88401960e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -465,6 +465,9 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *sta_ht_inf) { struct iwl_ht_config *ht_conf = &priv->current_ht_config; +#if !TODO + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +#endif if (!ht_conf->is_ht || !ht_conf->is_40mhz) return 0; @@ -481,7 +484,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, return 0; #endif return iwl_is_channel_extension(priv, priv->band, - le16_to_cpu(priv->staging_rxon.channel), + le16_to_cpu(ctx->staging.channel), ht_conf->extension_chan_offset); } EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); @@ -506,49 +509,51 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) s32 interval_tm, rem; struct ieee80211_conf *conf = NULL; u16 beacon_int; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); conf = ieee80211_get_hw_conf(priv->hw); lockdep_assert_held(&priv->mutex); - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); + memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); - priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); - priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); + ctx->timing.timestamp = cpu_to_le64(priv->timestamp); + ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); beacon_int = vif->bss_conf.beacon_int; if (vif->type == NL80211_IFTYPE_ADHOC) { /* TODO: we need to get atim_window from upper stack * for now we set to 0 */ - priv->rxon_timing.atim_window = 0; + ctx->timing.atim_window = 0; } else { - priv->rxon_timing.atim_window = 0; + ctx->timing.atim_window = 0; } beacon_int = iwl_adjust_beacon_interval(beacon_int, priv->hw_params.max_beacon_itrvl * TIME_UNIT); - priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); + ctx->timing.beacon_interval = cpu_to_le16(beacon_int); tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ interval_tm = beacon_int * TIME_UNIT; rem = do_div(tsf, interval_tm); - priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n", - le16_to_cpu(priv->rxon_timing.beacon_interval), - le32_to_cpu(priv->rxon_timing.beacon_init_val), - le16_to_cpu(priv->rxon_timing.atim_window)); + le16_to_cpu(ctx->timing.beacon_interval), + le32_to_cpu(ctx->timing.beacon_init_val), + le16_to_cpu(ctx->timing.atim_window)); return iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + sizeof(ctx->timing), &ctx->timing); } EXPORT_SYMBOL(iwl_send_rxon_timing); -void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) +void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + int hw_decrypt) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -565,11 +570,11 @@ EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); * be #ifdef'd out once the driver is stable and folks aren't actively * making changes */ -int iwl_check_rxon_cmd(struct iwl_priv *priv) +int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { int error = 0; int counter = 1; - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; if (rxon->flags & RXON_FLG_BAND_24G_MSK) { error |= le32_to_cpu(rxon->flags & @@ -641,43 +646,57 @@ EXPORT_SYMBOL(iwl_check_rxon_cmd); * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ -int iwl_full_rxon_required(struct iwl_priv *priv) +int iwl_full_rxon_required(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { + const struct iwl_rxon_cmd *staging = &ctx->staging; + const struct iwl_rxon_cmd *active = &ctx->active; + +#define CHK(cond) \ + if ((cond)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \ + return 1; \ + } + +#define CHK_NEQ(c1, c2) \ + if ((c1) != (c2)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " \ + #c1 " != " #c2 " - %d != %d\n", \ + (c1), (c2)); \ + return 1; \ + } /* These items are only settable from the full RXON command */ - if (!(iwl_is_associated(priv)) || - compare_ether_addr(priv->staging_rxon.bssid_addr, - priv->active_rxon.bssid_addr) || - compare_ether_addr(priv->staging_rxon.node_addr, - priv->active_rxon.node_addr) || - compare_ether_addr(priv->staging_rxon.wlap_bssid_addr, - priv->active_rxon.wlap_bssid_addr) || - (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) || - (priv->staging_rxon.channel != priv->active_rxon.channel) || - (priv->staging_rxon.air_propagation != - priv->active_rxon.air_propagation) || - (priv->staging_rxon.ofdm_ht_single_stream_basic_rates != - priv->active_rxon.ofdm_ht_single_stream_basic_rates) || - (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != - priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || - (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates != - priv->active_rxon.ofdm_ht_triple_stream_basic_rates) || - (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) - return 1; + CHK(!iwl_is_associated_ctx(ctx)); + CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); + CHK(compare_ether_addr(staging->node_addr, active->node_addr)); + CHK(compare_ether_addr(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); + CHK_NEQ(staging->dev_type, active->dev_type); + CHK_NEQ(staging->channel, active->channel); + CHK_NEQ(staging->air_propagation, active->air_propagation); + CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates, + active->ofdm_ht_single_stream_basic_rates); + CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates, + active->ofdm_ht_dual_stream_basic_rates); + CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates, + active->ofdm_ht_triple_stream_basic_rates); + CHK_NEQ(staging->assoc_id, active->assoc_id); /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can * be updated with the RXON_ASSOC command -- however only some * flag transitions are allowed using RXON_ASSOC */ /* Check if we are not switching bands */ - if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) != - (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)) - return 1; + CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK, + active->flags & RXON_FLG_BAND_24G_MSK); /* Check if we are switching association toggle */ - if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) != - (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) - return 1; + CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK, + active->filter_flags & RXON_FILTER_ASSOC_MSK); + +#undef CHK +#undef CHK_NEQ return 0; } @@ -685,20 +704,25 @@ EXPORT_SYMBOL(iwl_full_rxon_required); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) { +#if !TODO + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +#endif /* * Assign the lowest rate -- should really get this from * the beacon skb from mac80211. */ - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) return IWL_RATE_1M_PLCP; else return IWL_RATE_6M_PLCP; } EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); -void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) +static void _iwl_set_rxon_ht(struct iwl_priv *priv, + struct iwl_ht_config *ht_conf, + struct iwl_rxon_context *ctx) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; if (!ht_conf->is_ht) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | @@ -754,13 +778,21 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) } if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), ht_conf->ht_protection, ht_conf->extension_chan_offset); } + +void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) +{ + struct iwl_rxon_context *ctx; + + for_each_context(priv, ctx) + _iwl_set_rxon_ht(priv, ht_conf, ctx); +} EXPORT_SYMBOL(iwl_set_rxon_ht); #define IWL_NUM_RX_CHAINS_MULTIPLE 3 @@ -832,7 +864,7 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap) * Selects how many and which Rx receivers/antennas/chains to use. * This should not be used for scan command ... it puts data in wrong place. */ -void iwl_set_rxon_chain(struct iwl_priv *priv) +void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { bool is_single = is_single_rx_stream(priv); bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); @@ -878,15 +910,15 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; - priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); + ctx->staging.rx_chain = cpu_to_le16(rx_chain); if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) - priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else - priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", - priv->staging_rxon.rx_chain, + ctx->staging.rx_chain, active_rx_cnt, idle_rx_cnt); WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || @@ -894,39 +926,41 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_set_rxon_chain); -/* Return valid channel */ +/* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, - enum ieee80211_band band) + enum ieee80211_band band) { const struct iwl_channel_info *ch_info; int i; u8 channel = 0; + u8 min, max; + struct iwl_rxon_context *ctx; - /* only scan single channel, good enough to reset the RF */ - /* pick the first valid not in-use channel */ if (band == IEEE80211_BAND_5GHZ) { - for (i = 14; i < priv->channel_count; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } - } + min = 14; + max = priv->channel_count; } else { - for (i = 0; i < 14; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = - priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } + min = 0; + max = 14; + } + + for (i = min; i < max; i++) { + bool busy = false; + + for_each_context(priv, ctx) { + busy = priv->channel_info[i].channel == + le16_to_cpu(ctx->staging.channel); + if (busy) + break; } + + if (busy) + continue; + + channel = priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, band, channel); + if (is_channel_valid(ch_info)) + break; } return channel; @@ -937,25 +971,24 @@ EXPORT_SYMBOL(iwl_get_single_channel_number); * iwl_set_rxon_channel - Set the band and channel values in staging RXON * @ch: requested channel as a pointer to struct ieee80211_channel - * In addition to setting the staging RXON, priv->band is also set. - * * NOTE: Does not commit to the hardware; it sets appropriate bit fields * in the staging RXON flag structure based on the ch->band */ -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) +int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx) { enum ieee80211_band band = ch->band; u16 channel = ch->hw_value; - if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && + if ((le16_to_cpu(ctx->staging.channel) == channel) && (priv->band == band)) return 0; - priv->staging_rxon.channel = cpu_to_le16(channel); + ctx->staging.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) - priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; + ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; else - priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; priv->band = band; @@ -966,24 +999,25 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) EXPORT_SYMBOL(iwl_set_rxon_channel); void iwl_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, enum ieee80211_band band, struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { - priv->staging_rxon.flags &= + ctx->staging.flags &= ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_CCK_MSK); - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { /* Copied from iwl_post_associate() */ if (vif && vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; - priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; - priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; + ctx->staging.flags &= ~RXON_FLG_CCK_MSK; } } EXPORT_SYMBOL(iwl_set_flags_for_band); @@ -996,26 +1030,29 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, { const struct iwl_channel_info *ch_info; enum nl80211_iftype type = NL80211_IFTYPE_STATION; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (vif) + if (vif) { type = vif->type; + ctx = iwl_rxon_ctx_from_vif(vif); + } - memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); + memset(&ctx->staging, 0, sizeof(ctx->staging)); switch (type) { case NL80211_IFTYPE_AP: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; + ctx->staging.dev_type = RXON_DEV_TYPE_AP; break; case NL80211_IFTYPE_STATION: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; - priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + ctx->staging.dev_type = RXON_DEV_TYPE_ESS; + ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; break; case NL80211_IFTYPE_ADHOC: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; - priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; - priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | + ctx->staging.dev_type = RXON_DEV_TYPE_IBSS; + ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; break; @@ -1028,37 +1065,36 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, /* TODO: Figure out when short_preamble would be set and cache from * that */ if (!hw_to_local(priv->hw)->short_preamble) - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif ch_info = iwl_get_channel_info(priv, priv->band, - le16_to_cpu(priv->active_rxon.channel)); + le16_to_cpu(ctx->active.channel)); if (!ch_info) ch_info = &priv->channel_info[0]; - priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); + ctx->staging.channel = cpu_to_le16(ch_info->channel); priv->band = ch_info->band; - iwl_set_flags_for_band(priv, priv->band, vif); + iwl_set_flags_for_band(priv, ctx, priv->band, vif); - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; - priv->staging_rxon.cck_basic_rates = + ctx->staging.cck_basic_rates = (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; /* clear both MIX and PURE40 mode flag */ - priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | + ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); - if (vif) - memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN); + memcpy(ctx->staging.node_addr, vif->addr, ETH_ALEN); - priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; - priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; } EXPORT_SYMBOL(iwl_connection_init_rx_config); @@ -1066,6 +1102,7 @@ void iwl_set_rate(struct iwl_priv *priv) { const struct ieee80211_supported_band *hw = NULL; struct ieee80211_rate *rate; + struct iwl_rxon_context *ctx; int i; hw = iwl_get_hw_mode(priv, priv->band); @@ -1084,11 +1121,13 @@ void iwl_set_rate(struct iwl_priv *priv) IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); - priv->staging_rxon.cck_basic_rates = - (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; + for_each_context(priv, ctx) { + ctx->staging.cck_basic_rates = + (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; - priv->staging_rxon.ofdm_basic_rates = - (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + ctx->staging.ofdm_basic_rates = + (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + } } EXPORT_SYMBOL(iwl_set_rate); @@ -1109,14 +1148,17 @@ EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; struct iwl_csa_notification *csa = &(pkt->u.csa_notif); +#if !TODO + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +#endif + struct iwl_rxon_cmd *rxon = (void *)&ctx->active; if (priv->switch_rxon.switch_in_progress) { if (!le32_to_cpu(csa->status) && (csa->channel == priv->switch_rxon.channel)) { rxon->channel = csa->channel; - priv->staging_rxon.channel = csa->channel; + ctx->staging.channel = csa->channel; IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); iwl_chswitch_done(priv, true); @@ -1130,9 +1172,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) EXPORT_SYMBOL(iwl_rx_csa); #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv) +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); @@ -1172,7 +1215,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv) priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) - iwl_print_rx_config_cmd(priv); + iwl_print_rx_config_cmd(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); #endif wake_up_interruptible(&priv->wait_command_queue); @@ -1640,18 +1684,20 @@ static void iwl_ht_conf(struct iwl_priv *priv, IWL_DEBUG_MAC80211(priv, "leave\n"); } -static inline void iwl_set_no_assoc(struct iwl_priv *priv) +static inline void iwl_set_no_assoc(struct iwl_priv *priv, + struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + iwl_led_disassociate(priv); /* * inform the ucode that there is no longer an * association and that no more packets should be * sent */ - priv->staging_rxon.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - priv->staging_rxon.assoc_id = 0; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ctx->staging.assoc_id = 0; + iwlcore_commit_rxon(priv, ctx); } static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -1691,6 +1737,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, u32 changes) { struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret; IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); @@ -1735,13 +1782,13 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, /* mac80211 only sets assoc when in STATION mode */ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(priv->staging_rxon.bssid_addr, + memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); /* currently needed in a few places */ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); } else { - priv->staging_rxon.filter_flags &= + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } @@ -1764,21 +1811,21 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; } if (changes & BSS_CHANGED_ERP_CTS_PROT) { IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; if (bss_conf->use_cts_prot) - priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; else - priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; } if (changes & BSS_CHANGED_BASIC_RATES) { @@ -1788,12 +1835,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, * like this here: * if (A-band) - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = bss_conf->basic_rates; else - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = bss_conf->basic_rates >> 4; - priv->staging_rxon.cck_basic_rates = + ctx->staging.cck_basic_rates = bss_conf->basic_rates & 0xF; */ } @@ -1802,7 +1849,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, iwl_ht_conf(priv, vif); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } if (changes & BSS_CHANGED_ASSOC) { @@ -1815,29 +1862,29 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, if (!iwl_is_rfkill(priv)) priv->cfg->ops->lib->post_associate(priv, vif); } else - iwl_set_no_assoc(priv); + iwl_set_no_assoc(priv, vif); } - if (changes && iwl_is_associated(priv) && bss_conf->aid) { + if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", changes); - ret = iwl_send_rxon_assoc(priv); + ret = iwl_send_rxon_assoc(priv, ctx); if (!ret) { /* Sync active_rxon with latest change. */ - memcpy((void *)&priv->active_rxon, - &priv->staging_rxon, + memcpy((void *)&ctx->active, + &ctx->staging, sizeof(struct iwl_rxon_cmd)); } } if (changes & BSS_CHANGED_BEACON_ENABLED) { if (vif->bss_conf.enable_beacon) { - memcpy(priv->staging_rxon.bssid_addr, + memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); iwlcore_config_ap(priv, vif); } else - iwl_set_no_assoc(priv); + iwl_set_no_assoc(priv, vif); } if (changes & BSS_CHANGED_IBSS) { @@ -1857,17 +1904,20 @@ EXPORT_SYMBOL(iwl_bss_info_changed); static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + iwl_connection_init_rx_config(priv, vif); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - return iwlcore_commit_rxon(priv); + return iwlcore_commit_rxon(priv, ctx); } int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; int err = 0; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", @@ -1875,6 +1925,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_lock(&priv->mutex); + vif_priv->ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + if (WARN_ON(!iwl_is_ready_rf(priv))) { err = -EINVAL; goto out; @@ -1920,6 +1972,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); bool scan_completed = false; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -1928,8 +1981,8 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, if (iwl_is_ready_rf(priv)) { iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); } if (priv->vif == vif) { priv->vif = NULL; @@ -1971,6 +2024,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct iwl_rxon_context *ctx; unsigned long flags = 0; int ret = 0; u16 ch; @@ -2000,7 +2054,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) * configured. */ if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } /* during scanning mac80211 will delay channel setting until @@ -2042,13 +2097,20 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) * from BSS config in iwl_ht_conf */ ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) - priv->staging_rxon.flags = 0; + for_each_context(priv, ctx) { + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; - iwl_set_rxon_channel(priv, channel); - iwl_set_rxon_ht(priv, ht_conf); + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, ht_conf); + + iwl_set_flags_for_band(priv, ctx, channel->band, + priv->vif); + } - iwl_set_flags_for_band(priv, channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); if (priv->cfg->ops->lib->update_bcast_station) @@ -2083,12 +2145,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (scan_active) goto out; - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); - else - IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n"); - + for_each_context(priv, ctx) { + if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); + else + IWL_DEBUG_INFO(priv, + "Not re-sending same RXON configuration.\n"); + } out: IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -2101,6 +2164,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; unsigned long flags; + /* IBSS can only be the IWL_RXON_CTX_BSS context */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2131,8 +2196,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) * clear RXON_FILTER_ASSOC_MSK bit */ iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); iwl_set_rate(priv); @@ -2541,7 +2606,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_associated(priv)) { + if (!iwl_is_any_associated(priv)) { IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); return; } @@ -2696,7 +2761,7 @@ void iwl_bg_monitor_recover(unsigned long data) return; /* monitor and check for other stuck queues */ - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { /* skip as we already checked the command queue */ if (cnt == IWL_CMD_QUEUE_NUM) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index de2e39f36c25..80c256246e4d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -88,9 +88,10 @@ struct iwl_cmd; #define IWL_CMD(x) case x: return #x struct iwl_hcmd_ops { - int (*rxon_assoc)(struct iwl_priv *priv); - int (*commit_rxon)(struct iwl_priv *priv); - void (*set_rxon_chain)(struct iwl_priv *priv); + int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + void (*set_rxon_chain)(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); void (*send_bt_config)(struct iwl_priv *priv); }; @@ -374,12 +375,15 @@ void iwl_activate_qos(struct iwl_priv *priv); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); -void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); -int iwl_check_rxon_cmd(struct iwl_priv *priv); -int iwl_full_rxon_required(struct iwl_priv *priv); -void iwl_set_rxon_chain(struct iwl_priv *priv); -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); +void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + int hw_decrypt); +int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx); void iwl_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, enum ieee80211_band band, struct ieee80211_vif *vif); u8 iwl_get_single_channel_number(struct iwl_priv *priv, @@ -400,7 +404,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -int iwl_commit_rxon(struct iwl_priv *priv); +int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void iwl_mac_remove_interface(struct ieee80211_hw *hw, @@ -632,9 +636,11 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, void iwl_dump_csr(struct iwl_priv *priv); int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv); +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); #else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { } #endif @@ -720,13 +726,15 @@ void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); -static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) +static inline int iwl_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - return priv->cfg->ops->hcmd->rxon_assoc(priv); + return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx); } -static inline int iwlcore_commit_rxon(struct iwl_priv *priv) +static inline int iwlcore_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - return priv->cfg->ops->hcmd->commit_rxon(priv); + return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); } static inline void iwlcore_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ef787905f51c..d36418c3a6b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -730,7 +730,7 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, return -EFAULT; if (sscanf(buf, "%d", &ht40) != 1) return -EFAULT; - if (!iwl_is_associated(priv)) + if (!iwl_is_any_associated(priv)) priv->disable_ht40 = ht40 ? true : false; else { IWL_ERR(priv, "Sta associated with AP - " @@ -1319,7 +1319,8 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, int len = 0; char buf[20]; - len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); + len = sprintf(buf, "0x%04X\n", + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1332,7 +1333,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, char buf[20]; len = sprintf(buf, "0x%04X\n", - le32_to_cpu(priv->active_rxon.filter_flags)); + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8d5201ac80f9..6b188926014b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -519,6 +519,7 @@ struct iwl_station_priv { * space for us to put data into. */ struct iwl_vif_priv { + struct iwl_rxon_context *ctx; u8 ibss_bssid_sta_id; }; @@ -1097,6 +1098,26 @@ struct iwl_force_reset { */ #define IWLAGN_EXT_BEACON_TIME_POS 22 +enum iwl_rxon_context_id { + IWL_RXON_CTX_BSS, + + NUM_IWL_RXON_CTX +}; + +struct iwl_rxon_context { + enum iwl_rxon_context_id ctxid; + /* + * We declare this const so it can only be + * changed via explicit cast within the + * routines that actually update the physical + * hardware. + */ + const struct iwl_rxon_cmd active; + struct iwl_rxon_cmd staging; + + struct iwl_rxon_time_cmd timing; +}; + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1173,6 +1194,9 @@ struct iwl_priv { u32 hw_wa_rev; u8 rev_id; + /* microcode/device supports multiple contexts */ + u8 valid_contexts; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; @@ -1190,15 +1214,7 @@ struct iwl_priv { u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; - - struct iwl_rxon_time_cmd rxon_timing; - - /* We declare this const so it can only be - * changed via explicit cast within the - * routines that actually update the physical - * hardware */ - const struct iwl_rxon_cmd active_rxon; - struct iwl_rxon_cmd staging_rxon; + struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; struct iwl_switch_rxon switch_rxon; @@ -1490,10 +1506,34 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, return NULL; } +static inline struct iwl_rxon_context * +iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + + return vif_priv->ctx; +} + +#define for_each_context(priv, ctx) \ + for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ + ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ + if (priv->valid_contexts & BIT(ctx->ctxid)) + +static inline int iwl_is_associated(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) +{ + return (priv->contexts[ctxid].active.filter_flags & + RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int iwl_is_any_associated(struct iwl_priv *priv) +{ + return iwl_is_associated(priv, IWL_RXON_CTX_BSS); +} -static inline int iwl_is_associated(struct iwl_priv *priv) +static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) { - return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; + return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; } static inline int is_channel_valid(const struct iwl_channel_info *ch_info) diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 79773e353baa..10be197b0f22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -228,7 +228,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { if (priv->cfg->ops->lib->check_ack_health) { if (!priv->cfg->ops->lib->check_ack_health( priv, pkt)) { @@ -266,7 +266,12 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, { u16 fc = le16_to_cpu(hdr->frame_control); - if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) + /* + * All contexts have the same setting here due to it being + * a module parameter, so OK to check any context. + */ + if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags & + RXON_FILTER_DIS_DECRYPT_MSK) return 0; if (!(fc & IEEE80211_FCTL_PROTECTED)) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 2939699a1200..fe4cb57c3a1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -290,7 +290,8 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { + /* TODO: should use minimum of all contexts */ /* If we're associated, we clamp the maximum passive * dwell time to be 98% of the beacon interval (minus * 2 * channel tune time) */ @@ -527,6 +528,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) container_of(work, struct iwl_priv, scan_completed); bool internal = false; bool scan_completed = false; + struct iwl_rxon_context *ctx; IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); @@ -557,9 +559,8 @@ static void iwl_bg_scan_completed(struct work_struct *work) * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); + for_each_context(priv, ctx) + iwlcore_commit_rxon(priv, ctx); out: mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index d5e8db37b86e..43afb8fb36c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1153,12 +1153,16 @@ static bool is_lq_table_valid(struct iwl_priv *priv, { int i; struct iwl_ht_config *ht_conf = &priv->current_ht_config; +#if !TODO + struct iwl_rxon_context *ctx = + &priv->contexts[IWL_RXON_CTX_BSS]; +#endif if (ht_conf->is_ht) return true; IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", - priv->active_rxon.channel); + ctx->active.channel); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { IWL_DEBUG_INFO(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 53e6cbb3aaaa..234d6b430fcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -317,7 +317,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon) + if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon) return 0; if (priv->ibss_beacon->len > left) @@ -683,11 +683,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, int rc; int spectrum_resp_status; int duration = le16_to_cpu(params->duration); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (iwl_is_associated(priv)) + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) add_time = iwl_usecs_to_beacons(priv, le64_to_cpu(params->start_time) - priv->_3945.last_tsf, - le16_to_cpu(priv->rxon_timing.beacon_interval)); + le16_to_cpu(ctx->timing.beacon_interval)); memset(&spectrum, 0, sizeof(spectrum)); @@ -698,18 +699,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, cmd.len = sizeof(spectrum); spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); - if (iwl_is_associated(priv)) + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) spectrum.start_time = iwl_add_beacon_time(priv, priv->_3945.last_beacon_time, add_time, - le16_to_cpu(priv->rxon_timing.beacon_interval)); + le16_to_cpu(ctx->timing.beacon_interval)); else spectrum.start_time = 0; spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); spectrum.channels[0].channel = params->channel; spectrum.channels[0].type = type; - if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) + if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; @@ -2468,6 +2469,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) { int thermal_spin = 0; u32 rfkill; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); @@ -2525,11 +2527,11 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl_power_update_mode(priv, true); - if (iwl_is_associated(priv)) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { struct iwl3945_rxon_cmd *active_rxon = - (struct iwl3945_rxon_cmd *)(&priv->active_rxon); + (struct iwl3945_rxon_cmd *)(&ctx->active); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ @@ -2540,7 +2542,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); iwl3945_reg_txpower_periodic(priv); @@ -2883,7 +2885,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -3077,6 +3079,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) { int rc = 0; struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (!vif || !priv->is_open) return; @@ -3087,7 +3090,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) } IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, priv->active_rxon.bssid_addr); + vif->bss_conf.aid, ctx->active.bssid_addr); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -3096,34 +3099,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) conf = ieee80211_get_hw_conf(priv->hw); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); rc = iwl_send_rxon_timing(priv, vif); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3260,17 +3263,18 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int rc = 0; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ - if (!(iwl_is_associated(priv))) { + if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) { /* RXON - unassoc (to set timing command) */ - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); /* RXON Timing */ rc = iwl_send_rxon_timing(priv, vif); @@ -3278,26 +3282,26 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - priv->staging_rxon.assoc_id = 0; + ctx->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); } iwl3945_send_beacon_cmd(priv); @@ -3323,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - static_key = !iwl_is_associated(priv); + static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); if (!static_key) { sta_id = iwl_sta_id_or_broadcast(priv, sta); @@ -3405,6 +3409,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3424,8 +3429,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - priv->staging_rxon.filter_flags &= ~filter_nand; - priv->staging_rxon.filter_flags |= filter_or; + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; /* * Committing directly here breaks for some reason, @@ -3539,8 +3544,9 @@ static ssize_t show_flags(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); + return sprintf(buf, "0x%04X\n", ctx->active.flags); } static ssize_t store_flags(struct device *d, @@ -3549,17 +3555,18 @@ static ssize_t store_flags(struct device *d, { struct iwl_priv *priv = dev_get_drvdata(d); u32 flags = simple_strtoul(buf, NULL, 0); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; mutex_lock(&priv->mutex); - if (le32_to_cpu(priv->staging_rxon.flags) != flags) { + if (le32_to_cpu(ctx->staging.flags) != flags) { /* Cancel any currently running scans... */ if (iwl_scan_cancel_timeout(priv, 100)) IWL_WARN(priv, "Could not cancel scan.\n"); else { IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", flags); - priv->staging_rxon.flags = cpu_to_le32(flags); - iwlcore_commit_rxon(priv); + ctx->staging.flags = cpu_to_le32(flags); + iwlcore_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); @@ -3573,9 +3580,10 @@ static ssize_t show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; return sprintf(buf, "0x%04X\n", - le32_to_cpu(priv->active_rxon.filter_flags)); + le32_to_cpu(ctx->active.filter_flags)); } static ssize_t store_filter_flags(struct device *d, @@ -3583,19 +3591,20 @@ static ssize_t store_filter_flags(struct device *d, const char *buf, size_t count) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); - if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { + if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ if (iwl_scan_cancel_timeout(priv, 100)) IWL_WARN(priv, "Could not cancel scan.\n"); else { IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " "0x%04X\n", filter_flags); - priv->staging_rxon.filter_flags = + ctx->staging.filter_flags = cpu_to_le32(filter_flags); - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); @@ -3643,8 +3652,9 @@ static ssize_t store_measurement(struct device *d, const char *buf, size_t count) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(priv->active_rxon.channel), + .channel = le16_to_cpu(ctx->active.channel), .start_time = cpu_to_le64(priv->_3945.last_tsf), .duration = cpu_to_le16(1), }; @@ -3969,7 +3979,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; + int err = 0, i; struct iwl_priv *priv; struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); @@ -3991,6 +4001,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv = hw->priv; SET_IEEE80211_DEV(hw, &pdev->dev); + /* 3945 has only one valid context */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + /* * Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. @@ -4126,7 +4142,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e } iwl_set_rxon_channel(priv, - &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); + &priv->bands[IEEE80211_BAND_2GHZ].channels[5], + &priv->contexts[IWL_RXON_CTX_BSS]); iwl3945_setup_deferred_work(priv); iwl3945_setup_rx_handlers(priv); iwl_power_initialize(priv); -- cgit v1.2.3 From 13bb9483e190b95b04b22280ec9efa6b48469fd6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:33 +0200 Subject: iwlwifi: prepare for PAN queue/fifo assignment PAN ucode will require a different queue assignment, in particular queue 9 instead of 4 should be used for commands. This is required because the ucode will stop/start queues 4 and 8 depending on the PAN state, since queue 8 will be used for PAN multicast (after DTIM). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 1 + drivers/net/wireless/iwlwifi/iwl-3945.c | 10 ++++---- drivers/net/wireless/iwlwifi/iwl-4965.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 +++++----- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 31 +++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 10 ++++---- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 9 ++++---- drivers/net/wireless/iwlwifi/iwl-tx.c | 34 ++++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 ++ 13 files changed, 77 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index a4a3194779d2..65b5834da28c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -226,6 +226,7 @@ struct iwl3945_eeprom { /* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ #define IWL39_NUM_QUEUES 5 +#define IWL39_CMD_QUEUE_NUM 4 #define IWL_DEFAULT_TX_RETRY 15 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index f4aa229986ca..f059b1dd4d41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -273,7 +273,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, struct iwl_queue *q = &txq->q; struct iwl_tx_info *tx_info; - BUG_ON(txq_id == IWL_CMD_QUEUE_NUM); + BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { @@ -285,7 +285,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, } if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && - (txq_id != IWL_CMD_QUEUE_NUM) && + (txq_id != IWL39_CMD_QUEUE_NUM) && priv->mac80211_registered) iwl_wake_queue(priv, txq_id); } @@ -760,7 +760,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, data_retry_limit = IWL_DEFAULT_TX_RETRY; tx_cmd->data_retry_limit = data_retry_limit; - if (tx_id >= IWL_CMD_QUEUE_NUM) + if (tx_id >= IWL39_CMD_QUEUE_NUM) rts_retry_limit = 3; else rts_retry_limit = 7; @@ -909,7 +909,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) /* Tx queue(s) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? + slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); @@ -1072,7 +1072,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) if (priv->txq) for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == IWL39_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else iwl_tx_queue_free(priv, txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 82f32305f50e..cda389c3b025 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -576,7 +576,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) /* Activate all Tx DMA/FIFO channels */ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6)); - iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); /* make sure all queue are not stopped */ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); @@ -587,6 +587,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) priv->txq_ctx_active_msk = 0; /* Map each Tx/cmd queue to its corresponding fifo */ BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); + for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { int ac = default_queue_to_tx_fifo[i]; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 531a7dc3dc72..f919977d5632 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1479,7 +1479,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { - if (cnt == IWL_CMD_QUEUE_NUM) + if (cnt == priv->cmd_queue) continue; txq = &priv->txq[cnt]; q = &txq->q; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a51a7cfa5a14..88b7bbfb1f91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -118,7 +118,7 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != IWL_CMD_QUEUE_NUM) { + if (txq_id != priv->cmd_queue) { sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; @@ -155,7 +155,7 @@ void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != IWL_CMD_QUEUE_NUM) + if (txq_id != priv->cmd_queue) sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); @@ -825,7 +825,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv) /* Tx queues */ if (priv->txq) { for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) iwl_cmd_queue_free(priv); else iwl_tx_queue_free(priv, txq_id); @@ -882,9 +882,9 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - /* Alloc and init all Tx queues, including the command queue (#4) */ + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? + slots_num = (txq_id == priv->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); @@ -922,7 +922,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv) /* Alloc and init all Tx queues, including the command queue (#4) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = txq_id == IWL_CMD_QUEUE_NUM ? + slots_num = txq_id == priv->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index f2499e1f2047..a9ea7a1fef02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -52,6 +52,19 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = { IWL_TX_FIFO_UNUSED, }; +static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL_TX_FIFO_UNUSED, /* FIXME */ + IWL_TX_FIFO_UNUSED, /* FIXME */ + IWL_TX_FIFO_UNUSED, /* FIXME */ + IWL_TX_FIFO_UNUSED, /* FIXME */ + IWL_TX_FIFO_UNUSED, /* FIXME */ + IWLAGN_CMD_FIFO_NUM, +}; + static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 0, COEX_UNASSOC_IDLE_FLAGS}, @@ -376,6 +389,7 @@ static void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { + const s8 *queues; u32 a; unsigned long flags; int i, chan; @@ -410,7 +424,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, - IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num)); + IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv)); iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0); /* initiate the queues */ @@ -436,7 +450,13 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* Activate all Tx DMA/FIFO channels */ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); - iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + /* map queues to FIFOs */ + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + queues = iwlagn_ipan_queue_to_tx_fifo; + else + queues = iwlagn_default_queue_to_tx_fifo; + + iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); /* make sure all queue are not stopped */ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); @@ -445,11 +465,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* reset to 0 to enable all the queue first */ priv->txq_ctx_active_msk = 0; - /* map qos queues to fifos one-to-one */ + BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); + BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); - for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) { - int ac = iwlagn_default_queue_to_tx_fifo[i]; + for (i = 0; i < 10; i++) { + int ac = queues[i]; iwl_txq_ctx_activate(priv, i); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e073069a44c2..cfc8e8de8798 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3011,6 +3011,9 @@ static int __iwl_up(struct iwl_priv *priv) iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + /* must be initialised before iwl_hw_nic_init */ + priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + ret = iwlagn_hw_nic_init(priv); if (ret) { IWL_ERR(priv, "Unable to init nic\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index cc88401960e4..f6aa5ce478b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2757,14 +2757,14 @@ void iwl_bg_monitor_recover(unsigned long data) return; /* monitor and check for stuck cmd queue */ - if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM)) + if (iwl_check_stuck_queue(priv, priv->cmd_queue)) return; /* monitor and check for other stuck queues */ if (iwl_is_any_associated(priv)) { for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { /* skip as we already checked the command queue */ - if (cnt == IWL_CMD_QUEUE_NUM) + if (cnt == priv->cmd_queue) continue; if (iwl_check_stuck_queue(priv, cnt)) return; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6b188926014b..7cafb26a5f52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -265,11 +265,10 @@ struct iwl_channel_info { #define IWL_MIN_NUM_QUEUES 10 /* - * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00, - * the driver maps it into the appropriate device FIFO for the - * uCode. + * Command queue depends on iPAN support. */ -#define IWL_CMD_QUEUE_NUM 4 +#define IWL_DEFAULT_CMD_QUEUE_NUM 4 +#define IWL_IPAN_CMD_QUEUE_NUM 9 /* Power management (not Tx power) structures */ @@ -1197,6 +1196,9 @@ struct iwl_priv { /* microcode/device supports multiple contexts */ u8 valid_contexts; + /* command queue number */ + u8 cmd_queue; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 1f15b3aa8478..9fb2035e4eca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -232,7 +232,7 @@ cancel: * in later, it will possibly set an invalid * address (cmd->meta.source). */ - priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &= + priv->txq[priv->cmd_queue].meta[cmd_idx].flags &= ~CMD_WANT_SKB; } fail: diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index b1f101caf19d..5469655646ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -306,7 +306,7 @@ * at a time, until receiving ACK from receiving station, or reaching * retry limit and giving up. * - * The command queue (#4) must use this mode! + * The command queue (#4/#9) must use this mode! * This mode does not require use of the Byte Count table in host DRAM. * * Driver controls scheduler operation via 3 means: @@ -322,7 +322,7 @@ * (1024 bytes for each queue). * * After receiving "Alive" response from uCode, driver must initialize - * the scheduler (especially for queue #4, the command queue, otherwise + * the scheduler (especially for queue #4/#9, the command queue, otherwise * the driver can't issue commands!): */ @@ -555,8 +555,9 @@ #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) -#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\ - (~(1<hw_params.max_txq_num) - 1) &\ + (~(1<<(priv)->cmd_queue))) #define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index c308dab14673..347d3dc6a015 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -134,7 +134,7 @@ EXPORT_SYMBOL(iwl_tx_queue_free); */ void iwl_cmd_queue_free(struct iwl_priv *priv) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; @@ -271,7 +271,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, /* Driver private data, only for Tx (not command) queues, * not shared with device. */ - if (id != IWL_CMD_QUEUE_NUM) { + if (id != priv->cmd_queue) { txq->txb = kzalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, GFP_KERNEL); if (!txq->txb) { @@ -314,13 +314,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, /* * Alloc buffer array for commands (Tx or other types of commands). - * For the command queue (#4), allocate command space + one big + * For the command queue (#4/#9), allocate command space + one big * command for scan, since scan command is very huge; the system will * not have two scans at the same time, so only one is needed. * For normal Tx queues (all other queues), no super-size command * space is needed. */ - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) actual_slots++; txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, @@ -355,7 +355,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, * need an swq_id so don't set one to catch errors, all others can * be set up to the identity mapping. */ - if (txq_id != IWL_CMD_QUEUE_NUM) + if (txq_id != priv->cmd_queue) txq->swq_id = txq_id; /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise @@ -385,7 +385,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, { int actual_slots = slots_num; - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) actual_slots++; memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); @@ -413,7 +413,7 @@ EXPORT_SYMBOL(iwl_tx_queue_reset); */ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; @@ -483,7 +483,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * information */ out_cmd->hdr.flags = 0; - out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | + out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | INDEX_TO_SEQ(q->write_ptr)); if (cmd->flags & CMD_SIZE_HUGE) out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; @@ -500,15 +500,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, IWL_CMD_QUEUE_NUM); - break; + q->write_ptr, idx, priv->cmd_queue); + break; default: IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " "%d bytes at %d[%d]:%d\n", get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, IWL_CMD_QUEUE_NUM); + q->write_ptr, idx, priv->cmd_queue); } #endif txq->need_update = 1; @@ -587,16 +587,16 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced * in the queue management code. */ - if (WARN(txq_id != IWL_CMD_QUEUE_NUM, - "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n", - txq_id, sequence, - priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr, - priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) { + if (WARN(txq_id != priv->cmd_queue, + "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", + txq_id, priv->cmd_queue, sequence, + priv->txq[priv->cmd_queue].q.read_ptr, + priv->txq[priv->cmd_queue].q.write_ptr)) { iwl_print_hex_error(priv, pkt, 32); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 234d6b430fcf..02e0a9bbad16 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4001,6 +4001,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv = hw->priv; SET_IEEE80211_DEV(hw, &pdev->dev); + priv->cmd_queue = IWL39_CMD_QUEUE_NUM; + /* 3945 has only one valid context */ priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); -- cgit v1.2.3 From 751ca305d0e37f0d44b6a261e7db31aa6b60fbf4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:34 +0200 Subject: iwlwifi: define PAN queues/FIFOs PAN capable microcode has a different queue assignment (not just more queues for PAN) due to the way multicast is handled for AP mode. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 10 +++++----- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-dev.h | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a9ea7a1fef02..a7961bf395fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -57,11 +57,11 @@ static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { IWL_TX_FIFO_VI, IWL_TX_FIFO_BE, IWL_TX_FIFO_BK, - IWL_TX_FIFO_UNUSED, /* FIXME */ - IWL_TX_FIFO_UNUSED, /* FIXME */ - IWL_TX_FIFO_UNUSED, /* FIXME */ - IWL_TX_FIFO_UNUSED, /* FIXME */ - IWL_TX_FIFO_UNUSED, /* FIXME */ + IWL_TX_FIFO_BK_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_BE_IPAN, IWLAGN_CMD_FIFO_NUM, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cfc8e8de8798..5f67955c76cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3012,7 +3012,10 @@ static int __iwl_up(struct iwl_priv *priv) iwl_write32(priv, CSR_INT, 0xFFFFFFFF); /* must be initialised before iwl_hw_nic_init */ - priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + else + priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; ret = iwlagn_hw_nic_init(priv); if (ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7cafb26a5f52..8ec377d514fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -253,10 +253,14 @@ struct iwl_channel_info { struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; }; -#define IWL_TX_FIFO_BK 0 +#define IWL_TX_FIFO_BK 0 /* shared */ #define IWL_TX_FIFO_BE 1 -#define IWL_TX_FIFO_VI 2 +#define IWL_TX_FIFO_VI 2 /* shared */ #define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK +#define IWL_TX_FIFO_BE_IPAN 4 +#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI +#define IWL_TX_FIFO_VO_IPAN 5 #define IWL_TX_FIFO_UNUSED -1 /* Minimum number of queues. MAX_NUM is defined in hw specific files. @@ -270,6 +274,13 @@ struct iwl_channel_info { #define IWL_DEFAULT_CMD_QUEUE_NUM 4 #define IWL_IPAN_CMD_QUEUE_NUM 9 +/* + * This queue number is required for proper operation + * because the ucode will stop/start the scheduler as + * required. + */ +#define IWL_IPAN_MCAST_QUEUE 8 + /* Power management (not Tx power) structures */ enum iwl_pwr_src { -- cgit v1.2.3 From a194e3249baf954dc34c67cdad5b8bed36f49e72 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 08:53:46 -0700 Subject: iwlwifi: contextify broadcast station The broadcast station ID is per context, so add a variable for the ID in the context and use it everywhere we previously hardcoded it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 11 ++-- drivers/net/wireless/iwlwifi/iwl-4965.c | 6 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 8 +-- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 9 ++- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 9 ++- drivers/net/wireless/iwlwifi/iwl-agn.c | 32 +++++++---- drivers/net/wireless/iwlwifi/iwl-core.c | 4 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 89 +++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-sta.h | 29 +++++----- drivers/net/wireless/iwlwifi/iwl3945-base.c | 20 ++++--- 15 files changed, 142 insertions(+), 93 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 3bf5a30828be..674fb93ae17f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -130,7 +130,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -217,7 +217,7 @@ static struct iwl_lib_ops iwl1000_lib = { .set_ct_kill = iwl1000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 08f53f869c18..0cfc7a605e3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -343,7 +343,7 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s int i; IWL_DEBUG_INFO(priv, "enter\n"); - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) goto out; psta = (struct iwl3945_sta_priv *) sta->drv_priv; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index f059b1dd4d41..905575c840cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2305,8 +2305,10 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv, int ret; if (add) { - ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false, - &vif_priv->ibss_bssid_sta_id); + ret = iwl_add_bssid_station( + priv, &priv->contexts[IWL_RXON_CTX_BSS], + vif->bss_conf.bssid, false, + &vif_priv->ibss_bssid_sta_id); if (ret) return ret; @@ -2424,7 +2426,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; priv->hw_params.max_stations = IWL3945_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; @@ -2442,7 +2444,8 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; + tx_beacon_cmd->tx.sta_id = + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; frame_size = iwl3945_fill_beacon_frame(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index cda389c3b025..c155816f811b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -657,7 +657,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) sizeof(struct iwl4965_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWL4965_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; @@ -2010,7 +2010,7 @@ static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) start = IWL_STA_ID; if (is_broadcast_ether_addr(addr)) - return priv->hw_params.bcast_sta_id; + return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; spin_lock_irqsave(&priv->sta_lock, flags); for (i = start; i < priv->hw_params.max_stations; i++) @@ -2283,7 +2283,7 @@ static struct iwl_lib_ops iwl4965_lib = { .set_ct_kill = iwl4965_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8536f19d7dcc..d67031f080c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -180,7 +180,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -227,7 +227,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -398,7 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = { .set_ct_kill = iwl5000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -469,7 +469,7 @@ static struct iwl_lib_ops iwl5150_lib = { .set_ct_kill = iwl5150_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index bf1fe25fae73..8c4a98b82e35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -161,7 +161,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; @@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = { .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -398,7 +398,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f919977d5632..cb3c173e7c86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1163,6 +1163,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) }; struct iwl_scan_cmd *scan; struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u32 rate_flags = 0; u16 cmd_len; u16 rx_chain = 0; @@ -1175,6 +1176,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u8 active_chains; u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; + if (vif) + ctx = iwl_rxon_ctx_from_vif(vif); + conf = ieee80211_get_hw_conf(priv->hw); cancel_delayed_work(&priv->scan_check); @@ -1283,7 +1287,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; + scan->tx_cmd.sta_id = ctx->bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; switch (priv->scan_band) { @@ -1446,7 +1450,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; if (add) - return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true, + return iwl_add_bssid_station(priv, vif_priv->ctx, + vif->bss_conf.bssid, true, &vif_priv->ibss_bssid_sta_id); return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 88b7bbfb1f91..a2e4ca0eb7c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -531,6 +531,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; struct iwl_tx_cmd *tx_cmd; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int swq_id, txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; @@ -545,6 +546,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) u8 *qc = NULL; unsigned long flags; + if (info->control.vif) + ctx = iwl_rxon_ctx_from_vif(info->control.vif); + spin_lock_irqsave(&priv->lock, flags); if (iwl_is_rfkill(priv)) { IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); @@ -565,7 +569,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); + sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -577,8 +581,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta) sta_priv = (void *)sta->drv_priv; - if (sta_priv && sta_id != priv->hw_params.bcast_sta_id && - sta_priv->asleep) { + if (sta_priv && sta_priv->asleep) { WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); /* * This sends an asynchronous command to the device, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5f67955c76cf..d2222782f46c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -357,7 +357,9 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); - tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; +#warning "Use proper STA ID" + tx_beacon_cmd->tx.sta_id = + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; @@ -2829,7 +2831,7 @@ static void __iwl_down(struct iwl_priv *priv) del_timer_sync(&priv->monitor_recover); iwl_clear_ucode_stations(priv); - iwl_dealloc_bcast_station(priv); + iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); /* reset BT coex data */ @@ -2971,6 +2973,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) static int __iwl_up(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; int i; int ret; @@ -2984,9 +2987,13 @@ static int __iwl_up(struct iwl_priv *priv) return -EIO; } - ret = iwl_alloc_bcast_station(priv, true); - if (ret) - return ret; + for_each_context(priv, ctx) { + ret = iwl_alloc_bcast_station(priv, ctx, true); + if (ret) { + iwl_dealloc_bcast_stations(priv); + return ret; + } + } iwl_prepare_card_hw(priv); @@ -3520,9 +3527,11 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + IWL_DEBUG_MAC80211(priv, "enter\n"); - iwl_update_tkip_key(priv, keyconf, sta, + iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta, iv32, phase1key); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -3534,6 +3543,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; int ret; u8 sta_id; bool is_default_wep_key = false; @@ -3545,7 +3555,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - sta_id = iwl_sta_id_or_broadcast(priv, sta); + sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); if (sta_id == IWL_INVALID_STATION) return -EINVAL; @@ -3573,7 +3583,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (is_default_wep_key) ret = iwl_set_default_wep_key(priv, key); else - ret = iwl_set_dynamic_key(priv, key, sta_id); + ret = iwl_set_dynamic_key(priv, vif_priv->ctx, + key, sta_id); IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); break; @@ -3713,6 +3724,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; int ret; u8 sta_id; @@ -3728,8 +3740,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP) sta_priv->client = true; - ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, - &sta_id); + ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, + is_ap, &sta->ht_cap, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f6aa5ce478b4..f7bfe59c0ca8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2113,8 +2113,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) spin_unlock_irqrestore(&priv->lock, flags); - if (priv->cfg->ops->lib->update_bcast_station) - ret = priv->cfg->ops->lib->update_bcast_station(priv); + if (priv->cfg->ops->lib->update_bcast_stations) + ret = priv->cfg->ops->lib->update_bcast_stations(priv); set_ch_out: /* The list of supported rates and rate mask can be different diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 80c256246e4d..7aa9c6c5c43e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -206,7 +206,7 @@ struct iwl_lib_ops { /* station management */ int (*manage_ibss_station)(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); - int (*update_bcast_station)(struct iwl_priv *priv); + int (*update_bcast_stations)(struct iwl_priv *priv); /* recover from tx queue stall */ void (*recover_from_tx_stall)(unsigned long data); /* check for plcp health */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8ec377d514fb..f51c07c078cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -681,7 +681,6 @@ struct iwl_sensitivity_ranges { * @rx_page_order: Rx buffer page order * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR * @max_stations: - * @bcast_sta_id: * @ht40_channel: is 40MHz width possible in band 2.4 * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ) * @sw_crypto: 0 for hw, 1 for sw @@ -705,7 +704,6 @@ struct iwl_hw_params { u32 rx_page_order; u32 rx_wrt_ptr_reg; u8 max_stations; - u8 bcast_sta_id; u8 ht40_channel; u8 max_beacon_itrvl; /* in 1024 ms */ u32 max_inst_size; @@ -1126,6 +1124,8 @@ struct iwl_rxon_context { struct iwl_rxon_cmd staging; struct iwl_rxon_time_cmd timing; + + u8 bcast_sta_id; }; struct iwl_priv { diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 43afb8fb36c3..b1275e34520d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -226,8 +226,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, * * should be called with sta_lock held */ -static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, - bool is_ap, +static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta_ht_cap *ht_info) { struct iwl_station_entry *station; @@ -238,7 +238,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, if (is_ap) sta_id = IWL_AP_ID; else if (is_broadcast_ether_addr(addr)) - sta_id = priv->hw_params.bcast_sta_id; + sta_id = ctx->bcast_sta_id; else for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { if (!compare_ether_addr(priv->stations[i].sta.sta.addr, @@ -313,10 +313,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, /** * iwl_add_station_common - */ -int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, - bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, - u8 *sta_id_r) +int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r) { unsigned long flags_spin; int ret = 0; @@ -325,7 +324,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, *sta_id_r = 0; spin_lock_irqsave(&priv->sta_lock, flags_spin); - sta_id = iwl_prep_station(priv, addr, is_ap, ht_info); + sta_id = iwl_prep_station(priv, ctx, addr, is_ap, ht_info); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare station %pM for addition\n", addr); @@ -431,8 +430,8 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv, * * Function sleeps. */ -int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, - u8 *sta_id_r) +int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool init_rs, u8 *sta_id_r) { int ret; u8 sta_id; @@ -442,7 +441,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, if (sta_id_r) *sta_id_r = IWL_INVALID_STATION; - ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id); + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM\n", addr); return ret; @@ -833,8 +832,9 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_set_default_wep_key); static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) { unsigned long flags; __le16 key_flags = 0; @@ -851,7 +851,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, if (keyconf->keylen == WEP_KEY_LEN_128) key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == ctx->bcast_sta_id) key_flags |= STA_KEY_MULTICAST_MSK; spin_lock_irqsave(&priv->sta_lock, flags); @@ -887,8 +887,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, } static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) { unsigned long flags; __le16 key_flags = 0; @@ -900,7 +901,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == ctx->bcast_sta_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -936,8 +937,9 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, } static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) { unsigned long flags; int ret = 0; @@ -947,7 +949,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == ctx->bcast_sta_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -982,8 +984,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, } void iwl_update_tkip_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) { u8 sta_id; unsigned long flags; @@ -995,7 +998,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, return; } - sta_id = iwl_sta_id_or_broadcast(priv, sta); + sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta); if (sta_id == IWL_INVALID_STATION) return; @@ -1080,8 +1083,8 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_remove_dynamic_key); -int iwl_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, u8 sta_id) +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, u8 sta_id) { int ret; @@ -1092,14 +1095,14 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_CCMP: - ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); + ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_TKIP: - ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id); + ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); + ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id); break; default: IWL_ERR(priv, @@ -1229,14 +1232,15 @@ EXPORT_SYMBOL(iwl_send_lq_cmd); * and marks it driver active, so that it will be restored to the * device at the next best time. */ -int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq) +int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + bool init_lq) { struct iwl_link_quality_cmd *link_cmd; unsigned long flags; u8 sta_id; spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -1271,11 +1275,12 @@ EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); * Only used by iwlagn. Placed here to have all bcast station management * code together. */ -int iwl_update_bcast_station(struct iwl_priv *priv) +static int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { unsigned long flags; struct iwl_link_quality_cmd *link_cmd; - u8 sta_id = priv->hw_params.bcast_sta_id; + u8 sta_id = ctx->bcast_sta_id; link_cmd = iwl_sta_alloc_lq(priv, sta_id); if (!link_cmd) { @@ -1293,9 +1298,23 @@ int iwl_update_bcast_station(struct iwl_priv *priv) return 0; } -EXPORT_SYMBOL_GPL(iwl_update_bcast_station); -void iwl_dealloc_bcast_station(struct iwl_priv *priv) +int iwl_update_bcast_stations(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + int ret = 0; + + for_each_context(priv, ctx) { + ret = iwl_update_bcast_station(priv, ctx); + if (ret) + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(iwl_update_bcast_stations); + +void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { unsigned long flags; int i; @@ -1313,7 +1332,7 @@ void iwl_dealloc_bcast_station(struct iwl_priv *priv) } spin_unlock_irqrestore(&priv->sta_lock, flags); } -EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); +EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); /** * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index d38a350ba0bd..8a978c6e105f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -48,28 +48,29 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, int iwl_set_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); int iwl_restore_default_wep_keys(struct iwl_priv *priv); -int iwl_set_dynamic_key(struct iwl_priv *priv, +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key, u8 sta_id); int iwl_remove_dynamic_key(struct iwl_priv *priv, struct ieee80211_key_conf *key, u8 sta_id); void iwl_update_tkip_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); void iwl_restore_stations(struct iwl_priv *priv); void iwl_clear_ucode_stations(struct iwl_priv *priv); -int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); -void iwl_dealloc_bcast_station(struct iwl_priv *priv); -int iwl_update_bcast_station(struct iwl_priv *priv); +int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + bool init_lq); +void iwl_dealloc_bcast_stations(struct iwl_priv *priv); +int iwl_update_bcast_stations(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags); -int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, - u8 *sta_id_r); -int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, - bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, - u8 *sta_id_r); +int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool init_rs, u8 *sta_id_r); +int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r); int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -123,6 +124,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) /** * iwl_sta_id_or_broadcast - return sta_id or broadcast sta * @priv: iwl priv + * @context: the current context * @sta: mac80211 station * * In certain circumstances mac80211 passes a station pointer @@ -131,12 +133,13 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) * inline wraps that pattern. */ static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, + struct iwl_rxon_context *context, struct ieee80211_sta *sta) { int sta_id; if (!sta) - return priv->hw_params.bcast_sta_id; + return context->bcast_sta_id; sta_id = iwl_sta_id(sta); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 02e0a9bbad16..8b0763264141 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -144,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -512,7 +512,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], + info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -2580,7 +2582,7 @@ static void __iwl3945_down(struct iwl_priv *priv) /* Station information will now be cleared in device */ iwl_clear_ucode_stations(priv); - iwl_dealloc_bcast_station(priv); + iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); /* Unblock any waiting calls */ @@ -2662,7 +2664,8 @@ static int __iwl3945_up(struct iwl_priv *priv) { int rc, i; - rc = iwl_alloc_bcast_station(priv, false); + rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS], + false); if (rc) return rc; @@ -2946,7 +2949,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* We don't build a direct scan probe request; the uCode will do * that based on the direct_mask added to each channel entry */ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; + scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; /* flags + rate selection */ @@ -3330,7 +3333,8 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); if (!static_key) { - sta_id = iwl_sta_id_or_broadcast(priv, sta); + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); if (sta_id == IWL_INVALID_STATION) return -EINVAL; } @@ -3381,8 +3385,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, sta_priv->common.sta_id = IWL_INVALID_STATION; - ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, - &sta_id); + ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], + sta->addr, is_ap, &sta->ht_cap, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); -- cgit v1.2.3 From dcef732c72fbe960de5069d3921bb6ce6847be58 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 08:55:52 -0700 Subject: iwlwifi: contextify-stations-completely The microcode tracks stations per context, so the driver needs to do that as well for adding, deleting and restoring them, especially in the implicit removal case when we send an RXON. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 10 ++++++---- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++----- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 11 +++++++++-- drivers/net/wireless/iwlwifi/iwl-sta.h | 5 +++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 905575c840cc..ba3a9f9d519e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1832,8 +1832,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv, "configuration (%d).\n", rc); return rc; } - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); } IWL_DEBUG_INFO(priv, "Sending RXON\n" @@ -1865,8 +1866,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv, memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); if (!new_assoc) { - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); } /* If we issue a new RXON command which required a tune then we must diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d2222782f46c..23db6c3e9aee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -163,8 +163,8 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); return ret; } - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); ret = iwl_restore_default_wep_keys(priv); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); @@ -195,8 +195,8 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); ret = iwl_restore_default_wep_keys(priv); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); @@ -2830,7 +2830,7 @@ static void __iwl_down(struct iwl_priv *priv) if (priv->cfg->ops->lib->recover_from_tx_stall) del_timer_sync(&priv->monitor_recover); - iwl_clear_ucode_stations(priv); + iwl_clear_ucode_stations(priv, NULL); iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f51c07c078cc..da54bd53c99d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -495,7 +495,7 @@ struct iwl_qos_info { struct iwl_station_entry { struct iwl_addsta_cmd sta; struct iwl_tid_data tid[MAX_TID_COUNT]; - u8 used; + u8 used, ctxid; struct iwl_hw_key keyinfo; struct iwl_link_quality_cmd *lq; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index b1275e34520d..29235626ac0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -290,6 +290,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, station->sta.mode = 0; station->sta.sta.sta_id = sta_id; station->sta.station_flags = 0; + station->ctxid = ctx->ctxid; /* * OK to call unconditionally, since local stations (IBSS BSSID @@ -615,7 +616,8 @@ EXPORT_SYMBOL_GPL(iwl_remove_station); * other than explicit station management would cause this in * the ucode, e.g. unassociated RXON. */ -void iwl_clear_ucode_stations(struct iwl_priv *priv) +void iwl_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int i; unsigned long flags_spin; @@ -625,6 +627,9 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv) spin_lock_irqsave(&priv->sta_lock, flags_spin); for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx && ctx->ctxid != priv->stations[i].ctxid) + continue; + if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i); priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; @@ -646,7 +651,7 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations); * * Function sleeps. */ -void iwl_restore_stations(struct iwl_priv *priv) +void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_addsta_cmd sta_cmd; struct iwl_link_quality_cmd lq; @@ -664,6 +669,8 @@ void iwl_restore_stations(struct iwl_priv *priv) IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); spin_lock_irqsave(&priv->sta_lock, flags_spin); for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx->ctxid != priv->stations[i].ctxid) + continue; if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) && !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) { IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 8a978c6e105f..269a3ed0f3fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -57,8 +57,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); -void iwl_restore_stations(struct iwl_priv *priv); -void iwl_clear_ucode_stations(struct iwl_priv *priv); +void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +void iwl_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, bool init_lq); void iwl_dealloc_bcast_stations(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8b0763264141..630b8d641720 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2581,7 +2581,7 @@ static void __iwl3945_down(struct iwl_priv *priv) del_timer_sync(&priv->monitor_recover); /* Station information will now be cleared in device */ - iwl_clear_ucode_stations(priv); + iwl_clear_ucode_stations(priv, NULL); iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); -- cgit v1.2.3 From 8f2d3d2ae17855e396483724f152f223e6f01bfe Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:37 +0200 Subject: iwlwifi: contextify command sending Some commands will have different command IDs for different contexts, so we need to store those IDs in the context structure and use them instead of hardcoding the commands. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 15 ++++++++++----- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 3e5069943dde..2d4cdb027aa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -77,7 +77,7 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ctx->staging.ofdm_ht_triple_stream_basic_rates; rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, + ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, sizeof(rxon_assoc), &rxon_assoc, NULL); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 23db6c3e9aee..d3714f076a0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -152,7 +152,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(struct iwl_rxon_cmd), active_rxon); @@ -187,7 +187,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * stations is needed after it (the RXON command) completes */ if (!new_assoc) { - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); @@ -209,7 +209,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* Apply the new configuration * RXON assoc doesn't clear the station table in uCode, */ - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); @@ -3244,7 +3244,7 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ret = iwl_send_rxon_timing(priv, vif); if (ret) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + IWL_WARN(priv, "RXON timing - " "Attempting to continue.\n"); ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; @@ -3481,7 +3481,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) /* RXON Timing */ ret = iwl_send_rxon_timing(priv, vif); if (ret) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + IWL_WARN(priv, "RXON timing failed - " "Attempting to continue.\n"); /* AP has all antennas */ @@ -4200,6 +4200,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) for (i = 0; i < NUM_IWL_RXON_CTX; i++) priv->contexts[i].ctxid = i; + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); + SET_IEEE80211_DEV(hw, &pdev->dev); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f7bfe59c0ca8..a145d17cd943 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -545,7 +545,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) le32_to_cpu(ctx->timing.beacon_init_val), le16_to_cpu(ctx->timing.atim_window)); - return iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, sizeof(ctx->timing), &ctx->timing); } EXPORT_SYMBOL(iwl_send_rxon_timing); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index da54bd53c99d..6a7e9ff4a88c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1126,6 +1126,8 @@ struct iwl_rxon_context { struct iwl_rxon_time_cmd timing; u8 bcast_sta_id; + + u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; }; struct iwl_priv { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 630b8d641720..4321d970d58d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4013,6 +4013,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e for (i = 0; i < NUM_IWL_RXON_CTX; i++) priv->contexts[i].ctxid = i; + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + /* * Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. -- cgit v1.2.3 From 8dfdb9d5757424f7018a643258065c4fc8e6a439 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:38 +0200 Subject: iwlwifi: move QoS into context Since mac80211 doesn't currently enable/disable QoS per interface, we can't yet do it properly, but we can already prepare for it and move the QoS data and command ID into the context struct. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 43 +++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 ++++++++++------ drivers/net/wireless/iwlwifi/iwl-dev.h | 5 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d3714f076a0c..007dede73698 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4203,6 +4203,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a145d17cd943..d5499db34eb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -191,27 +191,27 @@ EXPORT_SYMBOL(iwl_alloc_all); /* * QoS support */ -static void iwl_update_qos(struct iwl_priv *priv) +static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - priv->qos_data.def_qos_parm.qos_flags = 0; + ctx->qos_data.def_qos_parm.qos_flags = 0; - if (priv->qos_data.qos_active) - priv->qos_data.def_qos_parm.qos_flags |= + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; if (priv->current_ht_config.is_ht) - priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - priv->qos_data.qos_active, - priv->qos_data.def_qos_parm.qos_flags); + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); - iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, + iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, sizeof(struct iwl_qosparam_cmd), - &priv->qos_data.def_qos_parm, NULL); + &ctx->qos_data.def_qos_parm, NULL); } #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ @@ -1584,6 +1584,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx; unsigned long flags; int q; @@ -1603,13 +1604,21 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - priv->qos_data.def_qos_parm.ac[q].edca_txop = - cpu_to_le16((params->txop * 32)); + /* + * MULTI-FIXME + * This may need to be done per interface in nl80211/cfg80211/mac80211. + */ + for_each_context(priv, ctx) { + ctx->qos_data.def_qos_parm.ac[q].cw_min = + cpu_to_le16(params->cw_min); + ctx->qos_data.def_qos_parm.ac[q].cw_max = + cpu_to_le16(params->cw_max); + ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + ctx->qos_data.def_qos_parm.ac[q].edca_txop = + cpu_to_le16((params->txop * 32)); - priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; + ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; + } spin_unlock_irqrestore(&priv->lock, flags); @@ -1751,8 +1760,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv); + ctx->qos_data.qos_active = bss_conf->qos; + iwl_update_qos(priv, ctx); spin_unlock_irqrestore(&priv->lock, flags); } diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d36418c3a6b5..0ee8f516c4ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -643,19 +643,25 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; + struct iwl_rxon_context *ctx; int pos = 0, i; - char buf[256]; + char buf[256 * NUM_IWL_RXON_CTX]; const size_t bufsz = sizeof(buf); - for (i = 0; i < AC_NUM; i++) { - pos += scnprintf(buf + pos, bufsz - pos, - "\tcw_min\tcw_max\taifsn\ttxop\n"); - pos += scnprintf(buf + pos, bufsz - pos, + for_each_context(priv, ctx) { + pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", + ctx->ctxid); + for (i = 0; i < AC_NUM; i++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\tcw_min\tcw_max\taifsn\ttxop\n"); + pos += scnprintf(buf + pos, bufsz - pos, "AC[%d]\t%u\t%u\t%u\t%u\n", i, - priv->qos_data.def_qos_parm.ac[i].cw_min, - priv->qos_data.def_qos_parm.ac[i].cw_max, - priv->qos_data.def_qos_parm.ac[i].aifsn, - priv->qos_data.def_qos_parm.ac[i].edca_txop); + ctx->qos_data.def_qos_parm.ac[i].cw_min, + ctx->qos_data.def_qos_parm.ac[i].cw_max, + ctx->qos_data.def_qos_parm.ac[i].aifsn, + ctx->qos_data.def_qos_parm.ac[i].edca_txop); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6a7e9ff4a88c..01a654e6db26 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1125,9 +1125,12 @@ struct iwl_rxon_context { struct iwl_rxon_time_cmd timing; + struct iwl_qos_info qos_data; + u8 bcast_sta_id; u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; + u8 qos_cmd; }; struct iwl_priv { @@ -1418,8 +1421,6 @@ struct iwl_priv { u32 inta_mask; - struct iwl_qos_info qos_data; - struct workqueue_struct *workqueue; struct work_struct restart; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4321d970d58d..09bca17255b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4016,6 +4016,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; /* * Disabling hardware scan means that mac80211 will perform scans -- cgit v1.2.3 From c90cbbbd78e45abbefd5e9e1c3c179d6126e3ddf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:39 +0200 Subject: iwlwifi: add context into tx descriptor In status processing we'll need to find the context for a given frame, so add a context pointer to the TX info for each frame. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a2e4ca0eb7c6..bff593ab0944 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -640,6 +640,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = ctx; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 01a654e6db26..90bf6b317fc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -144,6 +144,7 @@ struct iwl_queue { /* One for each TFD */ struct iwl_tx_info { struct sk_buff *skb; + struct iwl_rxon_context *ctx; }; /** diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 09bca17255b4..aef5f812c7ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -544,6 +544,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; -- cgit v1.2.3 From 8bd413e611d4324f17e54a2a89b4d09216c22a37 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:40 +0200 Subject: iwlwifi: move virtual interface pointer into context iwlwifi occasionally needs to find the virtual interface pointer to give it to mac80211, but right now it only keeps one. Move it into the context so that we can keep one pointer each. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 10 ++++-- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 17 +++++----- drivers/net/wireless/iwlwifi/iwl-agn.c | 12 +++++--- drivers/net/wireless/iwlwifi/iwl-core.c | 48 +++++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +++-- 10 files changed, 66 insertions(+), 38 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 0cfc7a605e3e..d707f5bb1a8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -932,7 +932,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, + sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, priv->stations[sta_id].sta.sta.addr); if (!sta) { IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index c155816f811b..1d6a46d4db59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1462,7 +1462,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u32 tsf_low; u8 switch_count; u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + struct ieee80211_vif *vif = ctx->vif; band = priv->band == IEEE80211_BAND_2GHZ; is_ht40 = is_ht40_channel(ctx->staging.flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index d67031f080c8..1dbb1246c083 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -287,7 +287,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u32 tsf_low; u8 switch_count; u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8c4a98b82e35..2fdba088bd27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -210,7 +210,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u32 tsf_low; u8 switch_count; u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index cb3c173e7c86..7002d7d0fac4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1720,6 +1720,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, bt_traffic_change_work); + struct iwl_rxon_context *ctx; int smps_request = -1; IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", @@ -1747,9 +1748,12 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) if (priv->cfg->ops->lib->update_chain_flags) priv->cfg->ops->lib->update_chain_flags(priv); - if (smps_request != -1 && - priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) - ieee80211_request_smps(priv->vif, smps_request); + if (smps_request != -1) { + for_each_context(priv, ctx) { + if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) + ieee80211_request_smps(ctx->vif, smps_request); + } + } mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index bff593ab0944..64daddd92279 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1120,6 +1120,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, struct iwl_queue *q = &priv->txq[txq_id].q; u8 *addr = priv->stations[sta_id].sta.sta.addr; struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; + struct iwl_rxon_context *ctx; + + ctx = &priv->contexts[priv->stations[sta_id].ctxid]; lockdep_assert_held(&priv->sta_lock); @@ -1135,7 +1138,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, tx_fifo); tid_data->agg.state = IWL_AGG_OFF; - ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); + ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } break; case IWL_EMPTYING_HW_QUEUE_ADDBA: @@ -1143,7 +1146,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, if (tid_data->tfds_in_queue == 0) { IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); tid_data->agg.state = IWL_AGG_ON; - ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); + ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } break; } @@ -1151,14 +1154,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, return 0; } -static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) +static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data; struct ieee80211_sta *sta; struct iwl_station_priv *sta_priv; rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, hdr->addr1); + sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1); if (sta) { sta_priv = (void *)sta->drv_priv; /* avoid atomic ops if this isn't a client */ @@ -1168,7 +1171,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) } rcu_read_unlock(); - ieee80211_tx_status_irqsafe(priv->hw, skb); + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); } int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) @@ -1191,7 +1194,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - iwlagn_tx_status(priv, tx_info->skb); + iwlagn_tx_status(priv, tx_info); hdr = (struct ieee80211_hdr *)tx_info->skb->data; if (hdr && ieee80211_is_data_qos(hdr->frame_control)) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 007dede73698..5e1df24bdb5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -603,7 +603,9 @@ static void iwl_bg_beacon_update(struct work_struct *work) struct sk_buff *beacon; /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); +#warning "introduce and use beacon context" + beacon = ieee80211_beacon_get(priv->hw, + priv->contexts[IWL_RXON_CTX_BSS].vif); if (!beacon) { IWL_ERR(priv, "update beacon failed\n"); @@ -3154,13 +3156,15 @@ static void iwl_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; bool bt_sco, bt_full_concurrent; u8 bt_ci_compliance; u8 bt_load; u8 bt_status; mutex_lock(&priv->mutex); - priv->vif = NULL; + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; /* @@ -3838,7 +3842,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, iwl_set_rxon_channel(priv, channel, ctx); iwl_set_rxon_ht(priv, ht_conf); iwl_set_flags_for_band(priv, ctx, channel->band, - priv->vif); + ctx->vif); spin_unlock_irqrestore(&priv->lock, flags); iwl_set_rate(priv); @@ -3855,7 +3859,7 @@ out: mutex_unlock(&priv->mutex); out_exit: if (!priv->switch_rxon.switch_in_progress) - ieee80211_chswitch_done(priv->vif, false); + ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d5499db34eb2..f9abcd80271c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1133,11 +1133,17 @@ EXPORT_SYMBOL(iwl_set_rate); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (priv->switch_rxon.switch_in_progress) { - ieee80211_chswitch_done(priv->vif, is_success); + ieee80211_chswitch_done(ctx->vif, is_success); mutex_lock(&priv->mutex); priv->switch_rxon.switch_in_progress = false; mutex_unlock(&priv->mutex); @@ -1149,9 +1155,11 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_csa_notification *csa = &(pkt->u.csa_notif); -#if !TODO + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; -#endif struct iwl_rxon_cmd *rxon = (void *)&ctx->active; if (priv->switch_rxon.switch_in_progress) { @@ -1735,7 +1743,9 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) IWL_DEBUG_MAC80211(priv, "leave\n"); spin_unlock_irqrestore(&priv->lock, flags); - priv->cfg->ops->lib->post_associate(priv, priv->vif); +#warning "use beacon context?" + priv->cfg->ops->lib->post_associate( + priv, priv->contexts[IWL_RXON_CTX_BSS].vif); return 0; } @@ -1927,6 +1937,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx; int err = 0; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", @@ -1934,20 +1945,23 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_lock(&priv->mutex); - vif_priv->ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + /* For now always use this context. */ + ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + vif_priv->ctx = ctx; if (WARN_ON(!iwl_is_ready_rf(priv))) { err = -EINVAL; goto out; } - if (priv->vif) { + if (ctx->vif) { IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); err = -EOPNOTSUPP; goto out; } - priv->vif = vif; + ctx->vif = vif; priv->iw_mode = vif->type; err = iwl_set_mode(priv, vif); @@ -1967,7 +1981,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; out_err: - priv->vif = NULL; + ctx->vif = NULL; priv->iw_mode = NL80211_IFTYPE_STATION; out: mutex_unlock(&priv->mutex); @@ -1993,14 +2007,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv, ctx); } - if (priv->vif == vif) { - priv->vif = NULL; - if (priv->scan_vif == vif) { - scan_completed = true; - priv->scan_vif = NULL; - priv->scan_request = NULL; - } - memset(priv->bssid, 0, ETH_ALEN); + + if (priv->scan_vif == vif) { + scan_completed = true; + priv->scan_vif = NULL; + priv->scan_request = NULL; } /* @@ -2013,6 +2024,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_ADHOC) priv->bt_traffic_load = priv->notif_bt_traffic_load; + WARN_ON(ctx->vif != vif); + ctx->vif = NULL; + memset(priv->bssid, 0, ETH_ALEN); mutex_unlock(&priv->mutex); if (scan_completed) @@ -2117,7 +2131,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) iwl_set_rxon_ht(priv, ht_conf); iwl_set_flags_for_band(priv, ctx, channel->band, - priv->vif); + ctx->vif); } spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 90bf6b317fc7..a332ec55f149 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1114,6 +1114,7 @@ enum iwl_rxon_context_id { }; struct iwl_rxon_context { + struct ieee80211_vif *vif; enum iwl_rxon_context_id ctxid; /* * We declare this const so it can only be @@ -1321,7 +1322,6 @@ struct iwl_priv { /* Last Rx'd beacon timestamp */ u64 timestamp; - struct ieee80211_vif *vif; union { #if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index aef5f812c7ef..6b5629570582 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -802,7 +802,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) struct sk_buff *beacon; /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); + beacon = ieee80211_beacon_get(priv->hw, + priv->contexts[IWL_RXON_CTX_BSS].vif); if (!beacon) { IWL_ERR(priv, "update beacon failed\n"); @@ -3048,8 +3049,10 @@ static void iwl3945_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; mutex_lock(&priv->mutex); - priv->vif = NULL; + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; mutex_unlock(&priv->mutex); iwl3945_down(priv); -- cgit v1.2.3 From 95c38dd429712366739299579b0785625cba66d6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:41 +0200 Subject: iwlwifi: clamp scanning dwell time to all contexts The dwell time should at least fit into all context's beacon intervals. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-scan.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index fe4cb57c3a1c..556dcaaa0efe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -286,19 +286,28 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx; u16 passive = (band == IEEE80211_BAND_2GHZ) ? IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; if (iwl_is_any_associated(priv)) { - /* TODO: should use minimum of all contexts */ - /* If we're associated, we clamp the maximum passive - * dwell time to be 98% of the beacon interval (minus - * 2 * channel tune time) */ - passive = vif ? vif->bss_conf.beacon_int : 0; - if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) - passive = IWL_PASSIVE_DWELL_BASE; - passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + /* + * If we're associated, we clamp the maximum passive + * dwell time to be 98% of the smallest beacon interval + * (minus 2 * channel tune time) + */ + for_each_context(priv, ctx) { + u16 value; + + if (!iwl_is_associated_ctx(ctx)) + continue; + value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; + if ((value > IWL_PASSIVE_DWELL_BASE) || !value) + value = IWL_PASSIVE_DWELL_BASE; + value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + passive = min(value, passive); + } } return passive; -- cgit v1.2.3 From 2995bafafd4d9d2f840b51b0121997be09fb8b47 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:42 +0200 Subject: iwlwifi: move AP sta ID to context Each context needs to use a different AP sta ID, so we need to move that into the context struct instead of hardcoding it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-sta.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5e1df24bdb5f..a67b04b309e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3585,7 +3585,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: if (is_default_wep_key) - ret = iwl_set_default_wep_key(priv, key); + ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); else ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta_id); @@ -4208,6 +4208,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a332ec55f149..d1400a0926eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1129,7 +1129,7 @@ struct iwl_rxon_context { struct iwl_qos_info qos_data; - u8 bcast_sta_id; + u8 bcast_sta_id, ap_sta_id; u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; u8 qos_cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 29235626ac0b..f5500cc8a44e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -236,7 +236,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u16 rate; if (is_ap) - sta_id = IWL_AP_ID; + sta_id = ctx->ap_sta_id; else if (is_broadcast_ether_addr(addr)) sta_id = ctx->bcast_sta_id; else @@ -810,6 +810,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_remove_default_wep_key); int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct ieee80211_key_conf *keyconf) { int ret; @@ -824,7 +825,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->hw_key_idx = HW_KEY_DEFAULT; - priv->stations[IWL_AP_ID].keyinfo.cipher = keyconf->cipher; + priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 269a3ed0f3fb..b7f700638dae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -46,6 +46,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *key); int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key); int iwl_restore_default_wep_keys(struct iwl_priv *priv); int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6b5629570582..29d13765ff66 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4021,6 +4021,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; /* * Disabling hardware scan means that mac80211 will perform scans -- cgit v1.2.3 From c10afb6e844b7936092396f719b794c4d0038f27 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:43 +0200 Subject: iwlwifi: make hw crypto context aware HW crypto needs to be aware of the context, and there are different command IDs for the WEP keys per context, so move the key tracking variables and command IDs into the context structure. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-agn.c | 17 ++++++++---- drivers/net/wireless/iwlwifi/iwl-commands.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 9 +++++-- drivers/net/wireless/iwlwifi/iwl-sta.c | 41 ++++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-sta.h | 27 ++++++++++++------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 7 files changed, 63 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index ba3a9f9d519e..5d09686c3389 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2430,6 +2430,8 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_stations = IWL3945_STATION_COUNT; priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; + priv->sta_key_max_num = STA_KEY_MAX_NUM; + priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a67b04b309e0..837406e53b3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -165,7 +165,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } iwl_clear_ucode_stations(priv, ctx); iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv); + ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); return ret; @@ -197,7 +197,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); iwl_clear_ucode_stations(priv, ctx); iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv); + ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); return ret; @@ -2222,6 +2222,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; + if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS)) + priv->sta_key_max_num = STA_KEY_MAX_NUM; + else + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -3548,6 +3553,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, { struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx = vif_priv->ctx; int ret; u8 sta_id; bool is_default_wep_key = false; @@ -3576,7 +3582,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { if (cmd == SET_KEY) - is_default_wep_key = !priv->key_mapping_key; + is_default_wep_key = !ctx->key_mapping_keys; else is_default_wep_key = (key->hw_key_idx == HW_KEY_DEFAULT); @@ -3594,9 +3600,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; case DISABLE_KEY: if (is_default_wep_key) - ret = iwl_remove_default_wep_key(priv, key); + ret = iwl_remove_default_wep_key(priv, ctx, key); else - ret = iwl_remove_dynamic_key(priv, key, sta_id); + ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id); IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); break; @@ -4209,6 +4215,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9b535832f117..55779bf0627b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1001,6 +1001,7 @@ struct iwl_qosparam_cmd { #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) #define STA_KEY_MAX_NUM 8 +#define STA_KEY_MAX_NUM_PAN 16 /* Flags indicate whether to modify vs. don't change various station params */ #define STA_MODIFY_KEY_MASK 0x01 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index d1400a0926eb..ef7862b5e91c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1133,6 +1133,10 @@ struct iwl_rxon_context { u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; u8 qos_cmd; + u8 wep_key_cmd; + + struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; + u8 key_mapping_keys; }; struct iwl_priv { @@ -1217,6 +1221,9 @@ struct iwl_priv { /* command queue number */ u8 cmd_queue; + /* max number of station keys */ + u8 sta_key_max_num; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; @@ -1296,8 +1303,6 @@ struct iwl_priv { spinlock_t sta_lock; int num_stations; struct iwl_station_entry stations[IWL_STATION_COUNT]; - struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */ - u8 key_mapping_key; unsigned long ucode_key_table; /* queue refcounts */ diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index f5500cc8a44e..ac6e2be35284 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -724,7 +724,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { int i; - for (i = 0; i < STA_KEY_MAX_NUM; i++) + for (i = 0; i < priv->sta_key_max_num; i++) if (!test_and_set_bit(i, &priv->ucode_key_table)) return i; @@ -732,7 +732,9 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_get_free_ucode_key_index); -static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) +static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + bool send_if_empty) { int i, not_empty = 0; u8 buff[sizeof(struct iwl_wep_cmd) + @@ -740,7 +742,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; size_t cmd_size = sizeof(struct iwl_wep_cmd); struct iwl_host_cmd cmd = { - .id = REPLY_WEPKEY, + .id = ctx->wep_key_cmd, .data = wep_cmd, .flags = CMD_SYNC, }; @@ -752,16 +754,16 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) for (i = 0; i < WEP_KEYS_MAX ; i++) { wep_cmd->key[i].key_index = i; - if (priv->wep_keys[i].key_size) { + if (ctx->wep_keys[i].key_size) { wep_cmd->key[i].key_offset = i; not_empty = 1; } else { wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; } - wep_cmd->key[i].key_size = priv->wep_keys[i].key_size; - memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key, - priv->wep_keys[i].key_size); + wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; + memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, + ctx->wep_keys[i].key_size); } wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; @@ -777,15 +779,17 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) return 0; } -int iwl_restore_default_wep_keys(struct iwl_priv *priv) +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { lockdep_assert_held(&priv->mutex); - return iwl_send_static_wepkey_cmd(priv, 0); + return iwl_send_static_wepkey_cmd(priv, ctx, false); } EXPORT_SYMBOL(iwl_restore_default_wep_keys); int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct ieee80211_key_conf *keyconf) { int ret; @@ -795,13 +799,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", keyconf->keyidx); - memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); + memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); if (iwl_is_rfkill(priv)) { IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); /* but keys in device are clear anyway so return success */ return 0; } - ret = iwl_send_static_wepkey_cmd(priv, 1); + ret = iwl_send_static_wepkey_cmd(priv, ctx, 1); IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret); @@ -827,11 +831,11 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, keyconf->hw_key_idx = HW_KEY_DEFAULT; priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; - priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; - memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, + ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; + memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, keyconf->keylen); - ret = iwl_send_static_wepkey_cmd(priv, 0); + ret = iwl_send_static_wepkey_cmd(priv, ctx, false); IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen, keyconf->keyidx, ret); @@ -1029,8 +1033,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_update_tkip_key); int iwl_remove_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) { unsigned long flags; u16 key_flags; @@ -1039,7 +1044,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, lockdep_assert_held(&priv->mutex); - priv->key_mapping_key--; + ctx->key_mapping_keys--; spin_lock_irqsave(&priv->sta_lock, flags); key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); @@ -1098,7 +1103,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, lockdep_assert_held(&priv->mutex); - priv->key_mapping_key++; + ctx->key_mapping_keys++; keyconf->hw_key_idx = HW_KEY_DYNAMIC; switch (keyconf->cipher) { diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index b7f700638dae..6ab5587870dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -44,14 +44,16 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key); int iwl_set_default_wep_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key); -int iwl_restore_default_wep_keys(struct iwl_priv *priv); +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key, u8 sta_id); -int iwl_remove_dynamic_key(struct iwl_priv *priv, +int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_key_conf *key, u8 sta_id); void iwl_update_tkip_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -97,20 +99,25 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); static inline void iwl_clear_driver_stations(struct iwl_priv *priv) { unsigned long flags; + struct iwl_rxon_context *ctx; spin_lock_irqsave(&priv->sta_lock, flags); memset(priv->stations, 0, sizeof(priv->stations)); priv->num_stations = 0; - /* - * Remove all key information that is not stored as part of station - * information since mac80211 may not have had a - * chance to remove all the keys. When device is reconfigured by - * mac80211 after an error all keys will be reconfigured. - */ priv->ucode_key_table = 0; - priv->key_mapping_key = 0; - memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); + + for_each_context(priv, ctx) { + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); + ctx->key_mapping_keys = 0; + } spin_unlock_irqrestore(&priv->sta_lock, flags); } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 29d13765ff66..be48f7977278 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4022,6 +4022,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; /* * Disabling hardware scan means that mac80211 will perform scans -- cgit v1.2.3 From 770e13bdda27065e31b3ab4daa3a04b6429719a1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:44 +0200 Subject: iwlwifi: store default station flags in context Since the default context is initialised to zero, and the default flags are zero, no more code is needed to initialise them right now, but another context can have different default flags. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ef7862b5e91c..2f9d1daff554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1137,6 +1137,8 @@ struct iwl_rxon_context { struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; u8 key_mapping_keys; + + __le32 station_flags; }; struct iwl_priv { diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index ac6e2be35284..e6bb81b1514c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -289,7 +289,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = sta_id; - station->sta.station_flags = 0; + station->sta.station_flags = ctx->station_flags; station->ctxid = ctx->ctxid; /* -- cgit v1.2.3 From 238d781d33dcd7941e7ab799c59156e5f7ebda9d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:45 +0200 Subject: iwlwifi: add context pointer to station Sometimes we only pass around station pointers but need to find the context they belong to, so store it in there. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-sta.c | 22 +++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 837406e53b3f..de8db3a3848d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3751,7 +3751,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, sta_priv->client = true; ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, - is_ap, &sta->ht_cap, &sta_id); + is_ap, sta, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2f9d1daff554..93647688d720 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -502,6 +502,7 @@ struct iwl_station_entry { }; struct iwl_station_priv_common { + struct iwl_rxon_context *ctx; u8 sta_id; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index e6bb81b1514c..c18eb89a9aed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -172,12 +172,13 @@ int iwl_send_add_sta(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, - struct ieee80211_sta_ht_cap *sta_ht_inf) + struct ieee80211_sta *sta) { + struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; __le32 sta_flags; u8 mimo_ps_mode; - if (!sta_ht_inf || !sta_ht_inf->ht_supported) + if (!sta || !sta_ht_inf->ht_supported) goto done; mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; @@ -228,7 +229,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, */ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, - struct ieee80211_sta_ht_cap *ht_info) + struct ieee80211_sta *sta) { struct iwl_station_entry *station; int i; @@ -292,12 +293,19 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, station->sta.station_flags = ctx->station_flags; station->ctxid = ctx->ctxid; + if (sta) { + struct iwl_station_priv_common *sta_priv; + + sta_priv = (void *)sta->drv_priv; + sta_priv->ctx = ctx; + } + /* * OK to call unconditionally, since local stations (IBSS BSSID - * STA and broadcast STA) pass in a NULL ht_info, and mac80211 + * STA and broadcast STA) pass in a NULL sta, and mac80211 * doesn't allow HT IBSS. */ - iwl_set_ht_add_station(priv, sta_id, ht_info); + iwl_set_ht_add_station(priv, sta_id, sta); /* 3945 only */ rate = (priv->band == IEEE80211_BAND_5GHZ) ? @@ -316,7 +324,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, */ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r) + struct ieee80211_sta *sta, u8 *sta_id_r) { unsigned long flags_spin; int ret = 0; @@ -325,7 +333,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, *sta_id_r = 0; spin_lock_irqsave(&priv->sta_lock, flags_spin); - sta_id = iwl_prep_station(priv, ctx, addr, is_ap, ht_info); + sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare station %pM for addition\n", addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 6ab5587870dc..56bad3f60d81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -74,7 +74,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool init_rs, u8 *sta_id_r); int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r); + struct ieee80211_sta *sta, u8 *sta_id_r); int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index be48f7977278..c048c1db42fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3390,7 +3390,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], - sta->addr, is_ap, &sta->ht_cap, &sta_id); + sta->addr, is_ap, sta, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); -- cgit v1.2.3 From 7e6a588601eb85feb10c7e8898f1f69c3b229a20 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:46 +0200 Subject: iwlwifi: move HT configuration data into context A lot of HT configuration semantically belongs into the context, even if right now it will never be different between contexts. Move it so we're better prepared for future changes in mac80211. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 66 +++++++++++------ drivers/net/wireless/iwlwifi/iwl-agn.c | 26 +++---- drivers/net/wireless/iwlwifi/iwl-core.c | 113 +++++++++++++++--------------- drivers/net/wireless/iwlwifi/iwl-core.h | 7 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 14 ++-- drivers/net/wireless/iwlwifi/iwl-sta.c | 23 +++--- 6 files changed, 134 insertions(+), 115 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index e78f3f0592d6..57629fba3a7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -602,11 +602,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, * Green-field mode is valid if the station supports it and * there are no non-GF stations present in the BSS. */ -static inline u8 rs_use_green(struct ieee80211_sta *sta, - struct iwl_ht_config *ht_conf) +static bool rs_use_green(struct ieee80211_sta *sta) { + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && - !(ht_conf->non_GF_STA_present); + !(ctx->ht.non_gf_sta_present); } /** @@ -758,8 +760,8 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, (a->is_SGI == b->is_SGI); } -static void rs_bt_update_lq(struct iwl_priv *priv, - struct iwl_lq_sta *lq_sta) +static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct iwl_lq_sta *lq_sta) { struct iwl_scale_tbl_info *tbl; bool full_concurrent; @@ -778,7 +780,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, /* Update uCode's rate table. */ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); queue_work(priv->workqueue, &priv->bt_full_concurrency); } @@ -803,6 +805,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, u32 tx_rate; struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); @@ -869,7 +873,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, lq_sta->missed_rate_counter++; if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { lq_sta->missed_rate_counter = 0; - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); } /* Regardless, ignore this status info for outdated rate */ return; @@ -969,7 +973,7 @@ done: /* Is there a need to switch between full concurrency and 3-wire? */ if (priv->bt_ant_couple_ok) - rs_bt_update_lq(priv, lq_sta); + rs_bt_update_lq(priv, ctx, lq_sta); } /* @@ -1163,6 +1167,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1183,7 +1189,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1217,6 +1223,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1237,7 +1245,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; rate_mask = lq_sta->active_mimo3_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1272,6 +1280,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv, u16 rate_mask; u8 is_green = lq_sta->is_green; s32 rate; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1284,7 +1294,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -2086,6 +2096,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) * return rate_n_flags as used in the table */ static u32 rs_update_rate_tbl(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct iwl_lq_sta *lq_sta, struct iwl_scale_tbl_info *tbl, int index, u8 is_green) @@ -2095,7 +2106,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv, /* Update uCode's rate table. */ rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); rs_fill_link_cmd(priv, lq_sta, rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); return rate; } @@ -2134,6 +2145,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, s32 sr; u8 tid = MAX_TID_COUNT; struct iwl_tid_data *tid_data; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); @@ -2172,7 +2185,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (is_legacy(tbl->lq_type)) lq_sta->is_green = 0; else - lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); + lq_sta->is_green = rs_use_green(sta); is_green = lq_sta->is_green; /* current tx rate */ @@ -2211,7 +2224,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ index = iwl_hwrate_to_plcp_idx(tbl->current_rate); - rate = rs_update_rate_tbl(priv, lq_sta, + rate = rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); } return; @@ -2453,7 +2466,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - rate = rs_update_rate_tbl(priv, lq_sta, + rate = rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { @@ -2495,7 +2508,7 @@ lq_update: IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", tbl->current_rate, index); rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); } else done_search = 1; } @@ -2565,12 +2578,17 @@ static void rs_initialize_lq(struct iwl_priv *priv, int rate_idx; int i; u32 rate; - u8 use_green = rs_use_green(sta, &priv->current_ht_config); + u8 use_green = rs_use_green(sta); u8 active_tbl = 0; u8 valid_tx_ant; + struct iwl_station_priv *sta_priv; + struct iwl_rxon_context *ctx; if (!sta || !lq_sta) - goto out; + return; + + sta_priv = (void *)sta->drv_priv; + ctx = sta_priv->common.ctx; i = lq_sta->last_txrate_idx; @@ -2602,9 +2620,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, rs_set_expected_tpt_table(lq_sta, tbl); rs_fill_link_cmd(NULL, lq_sta, rate); priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true); - out: - return; + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true); } static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, @@ -2732,7 +2748,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->is_dup = 0; lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; - lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); + lq_sta->is_green = rs_use_green(sta); lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); lq_sta->band = priv->band; /* @@ -2992,6 +3008,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, char buf[64]; int buf_size; u32 parsed_rate; + struct iwl_station_priv *sta_priv = + container_of(lq_sta, struct iwl_station_priv, lq_sta); + struct iwl_rxon_context *ctx = sta_priv->common.ctx; priv = lq_sta->drv; memset(buf, 0, sizeof(buf)); @@ -3014,7 +3033,8 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, if (lq_sta->dbg_fixed_rate) { rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); - iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, + false); } return count; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index de8db3a3848d..4efca99b2a9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3671,8 +3671,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, sta_priv->lq_sta.lq.general_params.flags &= ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; - iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq, - CMD_ASYNC, false); + iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), + &sta_priv->lq_sta.lq, CMD_ASYNC, false); } break; case IEEE80211_AMPDU_TX_OPERATIONAL: @@ -3687,8 +3687,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, sta_priv->lq_sta.lq.general_params.flags |= LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; - iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq, - CMD_ASYNC, false); + iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), + &sta_priv->lq_sta.lq, CMD_ASYNC, false); } ret = 0; break; @@ -3824,23 +3824,23 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - ht_conf->is_ht = conf_is_ht(conf); - if (ht_conf->is_ht) { + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ht_conf->is_40mhz = true; + ctx->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ht_conf->is_40mhz = true; + ctx->ht.is_40mhz = true; } else { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ht_conf->is_40mhz = false; + ctx->ht.is_40mhz = false; } } else - ht_conf->is_40mhz = false; + ctx->ht.is_40mhz = false; if ((le16_to_cpu(ctx->staging.channel) != ch)) ctx->staging.flags = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f9abcd80271c..8ec042d4e375 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -202,7 +202,7 @@ static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; - if (priv->current_ht_config.is_ht) + if (ctx->ht.enabled) ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", @@ -441,15 +441,15 @@ static bool is_single_rx_stream(struct iwl_priv *priv) priv->current_ht_config.single_chain_sufficient; } -static u8 iwl_is_channel_extension(struct iwl_priv *priv, - enum ieee80211_band band, - u16 channel, u8 extension_chan_offset) +static bool iwl_is_channel_extension(struct iwl_priv *priv, + enum ieee80211_band band, + u16 channel, u8 extension_chan_offset) { const struct iwl_channel_info *ch_info; ch_info = iwl_get_channel_info(priv, band, channel); if (!is_channel_valid(ch_info)) - return 0; + return false; if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) return !(ch_info->ht40_extension_channel & @@ -458,34 +458,31 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, return !(ch_info->ht40_extension_channel & IEEE80211_CHAN_NO_HT40MINUS); - return 0; + return false; } -u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, - struct ieee80211_sta_ht_cap *sta_ht_inf) +bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap) { - struct iwl_ht_config *ht_conf = &priv->current_ht_config; -#if !TODO - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; -#endif + if (!ctx->ht.enabled || !ctx->ht.is_40mhz) + return false; - if (!ht_conf->is_ht || !ht_conf->is_40mhz) - return 0; - - /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 + /* + * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 * the bit will not set if it is pure 40MHz case */ - if (sta_ht_inf) { - if (!sta_ht_inf->ht_supported) - return 0; - } + if (ht_cap && !ht_cap->ht_supported) + return false; + #ifdef CONFIG_IWLWIFI_DEBUGFS if (priv->disable_ht40) - return 0; + return false; #endif + return iwl_is_channel_extension(priv, priv->band, le16_to_cpu(ctx->staging.channel), - ht_conf->extension_chan_offset); + ctx->ht.extension_chan_offset); } EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); @@ -724,7 +721,7 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv, { struct iwl_rxon_cmd *rxon = &ctx->staging; - if (!ht_conf->is_ht) { + if (!ctx->ht.enabled) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK | @@ -732,22 +729,22 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv, return; } - /* FIXME: if the definition of ht_protection changed, the "translation" + /* FIXME: if the definition of ht.protection changed, the "translation" * will be needed for rxon->flags */ - rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS); + rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); /* Set up channel bandwidth: * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ /* clear the HT channel mode before set the mode */ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); - if (iwl_is_ht40_tx_allowed(priv, NULL)) { + if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) { /* pure ht40 */ - if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { + if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; /* Note: control channel is opposite of extension channel */ - switch (ht_conf->extension_chan_offset) { + switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; break; @@ -757,7 +754,7 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv, } } else { /* Note: control channel is opposite of extension channel */ - switch (ht_conf->extension_chan_offset) { + switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; @@ -782,8 +779,8 @@ static void _iwl_set_rxon_ht(struct iwl_priv *priv, IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", - le32_to_cpu(rxon->flags), ht_conf->ht_protection, - ht_conf->extension_chan_offset); + le32_to_cpu(rxon->flags), ctx->ht.protection, + ctx->ht.extension_chan_offset); } void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) @@ -1649,15 +1646,16 @@ static void iwl_ht_conf(struct iwl_priv *priv, struct iwl_ht_config *ht_conf = &priv->current_ht_config; struct ieee80211_sta *sta; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); IWL_DEBUG_MAC80211(priv, "enter:\n"); - if (!ht_conf->is_ht) + if (!ctx->ht.enabled) return; - ht_conf->ht_protection = + ctx->ht.protection = bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ht_conf->non_GF_STA_present = + ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); ht_conf->single_chain_sufficient = false; @@ -2098,29 +2096,32 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) spin_lock_irqsave(&priv->lock, flags); - /* Configure HT40 channels */ - ht_conf->is_ht = conf_is_ht(conf); - if (ht_conf->is_ht) { - if (conf_is_ht40_minus(conf)) { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ht_conf->is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ht_conf->is_40mhz = true; - } else { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ht_conf->is_40mhz = false; - } - } else - ht_conf->is_40mhz = false; - /* Default to no protection. Protection mode will later be set - * from BSS config in iwl_ht_conf */ - ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - for_each_context(priv, ctx) { + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + /* if we are switching from ht to 2.4 clear flags * from any ht related info since 2.4 does not * support ht */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7aa9c6c5c43e..289fef8a881b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -389,8 +389,9 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, u8 iwl_get_single_channel_number(struct iwl_priv *priv, enum ieee80211_band band); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); -u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, - struct ieee80211_sta_ht_cap *sta_ht_inf); +bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap); void iwl_connection_init_rx_config(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwl_set_rate(struct iwl_priv *priv); @@ -720,7 +721,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); -extern int iwl_send_lq_cmd(struct iwl_priv *priv, +extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 93647688d720..c17c67f767e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -470,15 +470,8 @@ union iwl_ht_rate_supp { #define CFG_HT_MPDU_DENSITY_MIN (0x1) struct iwl_ht_config { - /* self configuration data */ - bool is_ht; - bool is_40mhz; bool single_chain_sufficient; enum ieee80211_smps_mode smps; /* current smps mode */ - /* BSS related data */ - u8 extension_chan_offset; - u8 ht_protection; - u8 non_GF_STA_present; }; /* QoS structures */ @@ -1140,6 +1133,13 @@ struct iwl_rxon_context { u8 key_mapping_keys; __le32 station_flags; + + struct { + bool non_gf_sta_present; + u8 protection; + bool enabled, is_40mhz; + u8 extension_chan_offset; + } ht; }; struct iwl_priv { diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c18eb89a9aed..ccd09027c7cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -172,7 +172,8 @@ int iwl_send_add_sta(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, - struct ieee80211_sta *sta) + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx) { struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; __le32 sta_flags; @@ -212,7 +213,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, sta_flags |= cpu_to_le32( (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (iwl_is_ht40_tx_allowed(priv, sta_ht_inf)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) sta_flags |= STA_FLG_HT40_EN_MSK; else sta_flags &= ~STA_FLG_HT40_EN_MSK; @@ -305,7 +306,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, * STA and broadcast STA) pass in a NULL sta, and mac80211 * doesn't allow HT IBSS. */ - iwl_set_ht_add_station(priv, sta_id, sta); + iwl_set_ht_add_station(priv, sta_id, sta, ctx); /* 3945 only */ rate = (priv->band == IEEE80211_BAND_5GHZ) ? @@ -472,7 +473,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -ENOMEM; } - ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true); + ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true); if (ret) IWL_ERR(priv, "Link quality command failed (%d)\n", ret); @@ -714,7 +715,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * current LQ command */ if (send_lq) - iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true); + iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); spin_lock_irqsave(&priv->sta_lock, flags_spin); priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; } @@ -1173,16 +1174,12 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv, * RXON flags are updated and when LQ command is updated. */ static bool is_lq_table_valid(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq) { int i; - struct iwl_ht_config *ht_conf = &priv->current_ht_config; -#if !TODO - struct iwl_rxon_context *ctx = - &priv->contexts[IWL_RXON_CTX_BSS]; -#endif - if (ht_conf->is_ht) + if (ctx->ht.enabled) return true; IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", @@ -1208,7 +1205,7 @@ static bool is_lq_table_valid(struct iwl_priv *priv, * this case to clear the state indicating that station creation is in * progress. */ -int iwl_send_lq_cmd(struct iwl_priv *priv, +int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init) { int ret = 0; @@ -1227,7 +1224,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, iwl_dump_lq_cmd(priv, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); - if (is_lq_table_valid(priv, lq)) + if (is_lq_table_valid(priv, ctx, lq)) ret = iwl_send_cmd(priv, &cmd); else ret = -EINVAL; -- cgit v1.2.3 From 76d048151cf935281998b591e070581fc438e27e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:47 +0200 Subject: iwlwifi: introduce beacon context Only one context can be beaconing at a time, but we need to track which one. Introduce a new variable priv->beacon_ctx to do that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 32 +++++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-core.c | 30 ++++++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-core.h | 3 ++- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 ++- 5 files changed, 50 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4efca99b2a9c..55d1cd4c1369 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -345,6 +345,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, * beacon contents. */ + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); + return -EINVAL; + } + /* Initialize memory */ tx_beacon_cmd = &frame->u.beacon; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); @@ -357,9 +364,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); -#warning "Use proper STA ID" - tx_beacon_cmd->tx.sta_id = - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; @@ -369,7 +374,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, frame_size); /* Set up packet rate and flags */ - rate = iwl_rate_get_lowest_plcp(priv); + rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); @@ -602,25 +607,28 @@ static void iwl_bg_beacon_update(struct work_struct *work) container_of(work, struct iwl_priv, beacon_update); struct sk_buff *beacon; - /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ -#warning "introduce and use beacon context" - beacon = ieee80211_beacon_get(priv->hw, - priv->contexts[IWL_RXON_CTX_BSS].vif); + mutex_lock(&priv->mutex); + if (!priv->beacon_ctx) { + IWL_ERR(priv, "updating beacon w/o beacon context!\n"); + goto out; + } + /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ + beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); if (!beacon) { IWL_ERR(priv, "update beacon failed\n"); - return; + goto out; } - mutex_lock(&priv->mutex); /* new beacon skb is allocated every time; dispose previous.*/ if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = beacon; - mutex_unlock(&priv->mutex); iwl_send_beacon_cmd(priv); + out: + mutex_unlock(&priv->mutex); } static void iwl_bg_bt_runtime_config(struct work_struct *work) @@ -3477,6 +3485,8 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret = 0; + lockdep_assert_held(&priv->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8ec042d4e375..fb9173b1e5aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -699,11 +699,9 @@ int iwl_full_rxon_required(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_full_rxon_required); -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) +u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { -#if !TODO - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; -#endif /* * Assign the lowest rate -- should really get this from * the beacon skb from mac80211. @@ -1723,6 +1721,14 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) IWL_DEBUG_MAC80211(priv, "enter\n"); + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "update beacon but no beacon context!\n"); + dev_kfree_skb(skb); + return -EINVAL; + } + if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); return -EIO; @@ -1741,9 +1747,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) IWL_DEBUG_MAC80211(priv, "leave\n"); spin_unlock_irqrestore(&priv->lock, flags); -#warning "use beacon context?" - priv->cfg->ops->lib->post_associate( - priv, priv->contexts[IWL_RXON_CTX_BSS].vif); + priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); return 0; } @@ -1773,6 +1777,18 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, spin_unlock_irqrestore(&priv->lock, flags); } + if (changes & BSS_CHANGED_BEACON_ENABLED) { + /* + * the add_interface code must make sure we only ever + * have a single interface that could be beaconing at + * any time. + */ + if (vif->bss_conf.enable_beacon) + priv->beacon_ctx = ctx; + else + priv->beacon_ctx = NULL; + } + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = ieee80211_beacon_get(hw, vif); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 289fef8a881b..d2ee55d6811d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -523,7 +523,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); +u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c17c67f767e6..e1565f734599 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1437,6 +1437,8 @@ struct iwl_priv { struct work_struct rx_replenish; struct work_struct abort_scan; struct work_struct beacon_update; + struct iwl_rxon_context *beacon_ctx; + struct work_struct tt_work; struct work_struct ct_enter; struct work_struct ct_exit; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c048c1db42fd..e81c438b3348 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -343,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) return -ENOMEM; } - rate = iwl_rate_get_lowest_plcp(priv); + rate = iwl_rate_get_lowest_plcp(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); -- cgit v1.2.3 From 946ba30d61d47ee634a39d27b4d067b6418eaa08 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:48 +0200 Subject: iwlwifi: add PAN API Define the new host commands and notifications REPLY_WIPAN_PARAMS REPLY_WIPAN_RXON REPLY_WIPAN_RXON_TIMING REPLY_WIPAN_RXON_ASSOC REPLY_WIPAN_QOS_PARAM REPLY_WIPAN_WEPKEY REPLY_WIPAN_P2P_CHANNEL_SWITCH REPLY_WIPAN_NOA_NOTIFICATION and their corresponding structures along with the PAN station flag, the PAN AP sta ID and new dev types for the second context. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 109 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 8 ++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 55779bf0627b..3e4ba31b5d59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -180,6 +180,16 @@ enum { REPLY_BT_COEX_PROFILE_NOTIF = 0xce, REPLY_BT_COEX_SCO = 0xcf, + /* PAN commands */ + REPLY_WIPAN_PARAMS = 0xb2, + REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */ + REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */ + REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */ + REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */ + REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ + REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, + REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, + REPLY_MAX = 0xff }; @@ -607,6 +617,9 @@ enum { RXON_DEV_TYPE_ESS = 3, RXON_DEV_TYPE_IBSS = 4, RXON_DEV_TYPE_SNIFFER = 6, + RXON_DEV_TYPE_CP = 7, + RXON_DEV_TYPE_2STA = 8, + RXON_DEV_TYPE_P2P = 9, }; @@ -823,7 +836,8 @@ struct iwl_rxon_time_cmd { __le16 atim_window; __le32 beacon_init_val; __le16 listen_interval; - __le16 reserved; + u8 dtim_period; + u8 delta_cp_bss_tbtts; } __packed; /* @@ -960,11 +974,13 @@ struct iwl_qosparam_cmd { /* Special, dedicated locations within device's station table */ #define IWL_AP_ID 0 +#define IWL_AP_ID_PAN 1 #define IWL_STA_ID 2 #define IWL3945_BROADCAST_ID 24 #define IWL3945_STATION_COUNT 25 #define IWL4965_BROADCAST_ID 31 #define IWL4965_STATION_COUNT 32 +#define IWLAGN_PAN_BCAST_ID 14 #define IWLAGN_BROADCAST_ID 15 #define IWLAGN_STATION_COUNT 16 @@ -973,6 +989,7 @@ struct iwl_qosparam_cmd { #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) +#define STA_FLG_PAN_STATION cpu_to_le32(1 << 13) #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) #define STA_FLG_MAX_AGG_SIZE_POS (19) @@ -4309,4 +4326,94 @@ struct iwl_rx_packet { int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); +/* + * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) + */ + +/** + * struct iwl_wipan_slot + * @width: Time in TU + * @type: + * 0 - BSS + * 1 - PAN + */ +struct iwl_wipan_slot { + __le16 width; + u8 type; + u8 reserved; +} __packed; + +#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4) +#define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5) + +/** + * struct iwl_wipan_params_cmd + * @flags: + * bit0: reserved + * bit1: CP leave channel with CTS + * bit2: CP leave channel qith Quiet + * bit3: slotted mode + * 1 - work in slotted mode + * 0 - work in non slotted mode + * bit4: filter beacon notification + * bit5: full tx slotted mode. if this flag is set, + * uCode will perform leaving channel methods in context switch + * also when working in same channel mode + * @num_slots: 1 - 10 + */ +struct iwl_wipan_params_cmd { + __le16 flags; + u8 reserved; + u8 num_slots; + struct iwl_wipan_slot slots[10]; +} __packed; + +/* + * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9 + * + * TODO: Figure out what this is used for, + * it can only switch between 2.4 GHz + * channels!! + */ + +struct iwl_wipan_p2p_channel_switch_cmd { + __le16 channel; + __le16 reserved; +}; + +/* + * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc + * + * This is used by the device to notify us of the + * NoA schedule it determined so we can forward it + * to userspace for inclusion in probe responses. + * + * In beacons, the NoA schedule is simply appended + * to the frame we give the device. + */ + +struct iwl_wipan_noa_descriptor { + u8 count; + __le32 duration; + __le32 interval; + __le32 starttime; +} __packed; + +struct iwl_wipan_noa_attribute { + u8 id; + __le16 length; + u8 index; + u8 ct_window; + struct iwl_wipan_noa_descriptor descr0, descr1; + u8 reserved; +} __packed; + +struct iwl_wipan_noa_notification { + u32 noa_active; + struct iwl_wipan_noa_attribute noa_attribute; +} __packed; + #endif /* __iwl_commands_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 9fb2035e4eca..c373b53babea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -100,6 +100,14 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); IWL_CMD(REPLY_BT_COEX_PROT_ENV); + IWL_CMD(REPLY_WIPAN_PARAMS); + IWL_CMD(REPLY_WIPAN_RXON); + IWL_CMD(REPLY_WIPAN_RXON_TIMING); + IWL_CMD(REPLY_WIPAN_RXON_ASSOC); + IWL_CMD(REPLY_WIPAN_QOS_PARAM); + IWL_CMD(REPLY_WIPAN_WEPKEY); + IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); + IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); default: return "UNKNOWN"; -- cgit v1.2.3 From ece9c4ee5e590f96d7221c746126eaafac15a60c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:49 +0200 Subject: iwlagn: detect PAN capability Detect whether or not the ucode is PAN capable and adjust the valid contexts accordingly. To be able to do this, add the PAN context to the array as well. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 25 +++++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 55d1cd4c1369..bad97f47eb9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1718,6 +1718,7 @@ static void iwl_nic_start(struct iwl_priv *priv) struct iwlagn_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; + bool pan; }; static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); @@ -1955,6 +1956,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, capa->max_probe_length = le32_to_cpup((__le32 *)tlv_data); break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->pan = true; + break; case IWL_UCODE_TLV_INIT_EVTLOG_PTR: if (tlv_len != sizeof(u32)) goto invalid_tlv_len; @@ -2230,10 +2236,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; - if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS)) - priv->sta_key_max_num = STA_KEY_MAX_NUM; - else + if (ucode_capa.pan) { + priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + } else + priv->sta_key_max_num = STA_KEY_MAX_NUM; /* Copy images into buffers for card's bus-master reads ... */ @@ -4226,7 +4233,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; - BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); + + priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; + priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; + priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; + priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; + priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e1565f734599..99b6b81be7e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -582,6 +582,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_INIT_DATA = 4, IWL_UCODE_TLV_BOOT = 5, IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, @@ -1103,6 +1104,7 @@ struct iwl_force_reset { enum iwl_rxon_context_id { IWL_RXON_CTX_BSS, + IWL_RXON_CTX_PAN, NUM_IWL_RXON_CTX }; -- cgit v1.2.3 From 60744f62971cfa80cab36ab8c12afeae371fbe8b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:50 +0200 Subject: iwlagn: remove iw_mode check for beacon Since we have the beacon context now, we no longer need to rely on iw_mode but can check the beacon context interface's type. However, that check must be in the work item instead due to locking constraints (mutex must be held when dereferencing beacon_ctx pointer). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bad97f47eb9f..b07d397ed5a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -613,6 +613,16 @@ static void iwl_bg_beacon_update(struct work_struct *work) goto out; } + if (priv->beacon_ctx->vif->type != NL80211_IFTYPE_AP) { + /* + * The ucode will send beacon notifications even in + * IBSS mode, but we don't want to process them. But + * we need to defer the type check to here due to + * requiring locking around the beacon_ctx access. + */ + goto out; + } + /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); if (!beacon) { @@ -846,8 +856,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - if ((priv->iw_mode == NL80211_IFTYPE_AP) && - (!test_bit(STATUS_EXIT_PENDING, &priv->status))) + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) queue_work(priv->workqueue, &priv->beacon_update); } -- cgit v1.2.3 From e72f368be61d9835c98cd00ee1f330d28e2488ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:51 +0200 Subject: iwlagn: queue frames according to context Frames for different contexts need to be put on different queues, and multicast after DTIM frames have a special queue yet which also depends on the context, so put all this into the context. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 42 ++++++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 27 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 5 ++++ 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 64daddd92279..5950184d9860 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = { 2, 3, 3, 2, 1, 1, 0, 0 }; -static const u8 ac_to_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, -}; - -static inline int get_fifo_from_ac(u8 ac) -{ - return ac_to_fifo[ac]; -} - static inline int get_ac_from_tid(u16 tid) { if (likely(tid < ARRAY_SIZE(tid_to_ac))) @@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid) return -EINVAL; } -static inline int get_fifo_from_tid(u16 tid) +static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid) { if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return get_fifo_from_ac(tid_to_ac[tid]); + return ctx->ac_to_fifo[tid_to_ac[tid]]; /* no support for TIDs 8-15 yet */ return -EINVAL; @@ -333,11 +321,6 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask) iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); } -static inline int get_queue_from_ac(u16 ac) -{ - return ac; -} - /* * handle build REPLY_TX command notification. */ @@ -595,7 +578,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); } - txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); + /* + * Send this frame after DTIM -- there's a special queue + * reserved for this for contexts that support AP mode. + */ + if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { + txq_id = ctx->mcast_queue; + /* + * The microcode will clear the more data + * bit in the last frame it transmits. + */ + hdr->frame_control |= + cpu_to_le16(IEEE80211_FCTL_MOREDATA); + } else + txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; /* irqs already disabled/saved above when locking priv->lock */ spin_lock(&priv->sta_lock); @@ -984,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, unsigned long flags; struct iwl_tid_data *tid_data; - tx_fifo = get_fifo_from_tid(tid); + tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid); if (unlikely(tx_fifo < 0)) return tx_fifo; @@ -1045,7 +1041,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, int write_ptr, read_ptr; unsigned long flags; - tx_fifo_id = get_fifo_from_tid(tid); + tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid); if (unlikely(tx_fifo_id < 0)) return tx_fifo_id; @@ -1133,7 +1129,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, if ((txq_id == tid_data->agg.txq_id) && (q->read_ptr == q->write_ptr)) { u16 ssn = SEQ_TO_SN(tid_data->seq_number); - int tx_fifo = get_fifo_from_tid(tid); + int tx_fifo = get_fifo_from_tid(ctx, tid); IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, tx_fifo); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b07d397ed5a7..143c12a29fd8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4196,6 +4196,28 @@ static int iwl_set_hw_params(struct iwl_priv *priv) return priv->cfg->ops->lib->set_hw_params(priv); } +static const u8 iwlagn_bss_ac_to_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, +}; + +static const u8 iwlagn_bss_ac_to_queue[] = { + 0, 1, 2, 3, +}; + +static const u8 iwlagn_pan_ac_to_fifo[] = { + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_BK_IPAN, +}; + +static const u8 iwlagn_pan_ac_to_queue[] = { + 7, 6, 5, 4, +}; + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0, i; @@ -4242,6 +4264,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; @@ -4251,6 +4275,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; + priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; + priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; + priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 99b6b81be7e2..422c71e122f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1111,6 +1111,11 @@ enum iwl_rxon_context_id { struct iwl_rxon_context { struct ieee80211_vif *vif; + + const u8 *ac_to_fifo; + const u8 *ac_to_queue; + u8 mcast_queue; + enum iwl_rxon_context_id ctxid; /* * We declare this const so it can only be -- cgit v1.2.3 From 2491fa42d9bdf26075765db5d091b5d7225ca636 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:52 +0200 Subject: iwlagn: send RXON timing before associating The PAN functionality requires us to send the timing including a valid DTIM period to the microcode before associating, so request this data from mac80211 and send it to the device. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 2 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 143c12a29fd8..79aff1fb85a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -182,6 +182,21 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); + if (new_assoc) { + if (WARN_ON(!ctx->vif)) + return -EINVAL; + /* + * First of all, before setting associated, we need to + * send RXON timing so the device knows about the DTIM + * period and other timing values + */ + ret = iwl_send_rxon_timing(priv, ctx->vif); + if (ret) { + IWL_ERR(priv, "Error setting RXON timing!\n"); + return ret; + } + } + /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of * stations is needed after it (the RXON command) completes @@ -3355,6 +3370,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT; if (!priv->cfg->broken_powersave) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index fb9173b1e5aa..04d7894e0004 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -536,6 +536,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) rem = do_div(tsf, interval_tm); ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + ctx->timing.dtim_period = vif->bss_conf.dtim_period; + IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n", le16_to_cpu(ctx->timing.beacon_interval), -- cgit v1.2.3 From 08abc53cf4f7547ab3bc3957bc6e60c364a882c3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:53 +0200 Subject: iwlagn: send beacon before committing associated RXON Newer AGN microcode requires know the beacon before starting the AP so that it can start beaconing right away. Implement that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 79aff1fb85a1..8e0722830413 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3559,6 +3559,8 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } + /* need to send beacon cmd before committing assoc RXON! */ + iwl_send_beacon_cmd(priv); /* restore RXON assoc */ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv, ctx); -- cgit v1.2.3 From 52a02d1500e4cbb347006e407d1c0bd941eee7fc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 09:44:50 -0700 Subject: iwlwifi: send PAN parameters In order for the microcode to be able to handle multiple interfaces, we need to give it the PAN parameters that state how to allocate the time between the two interfaces. Do this, and update it wherever necessary. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 75 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 ++ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++ drivers/net/wireless/iwlwifi/iwl-core.c | 6 +++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 3 ++ 6 files changed, 96 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 2d4cdb027aa6..6fb52abafc8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -270,12 +270,86 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, return max_rssi - agc - IWLAGN_RSSI_OFFSET; } +static int iwlagn_set_pan_params(struct iwl_priv *priv) +{ + struct iwl_wipan_params_cmd cmd; + struct iwl_rxon_context *ctx_bss, *ctx_pan; + int slot0 = 300, slot1 = 0; + int ret; + + if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS)) + return 0; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); + + lockdep_assert_held(&priv->mutex); + + ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; + ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; + + memset(&cmd, 0, sizeof(cmd)); + + /* only 2 slots are currently allowed */ + cmd.num_slots = 2; + + cmd.slots[0].type = 0; /* BSS */ + cmd.slots[1].type = 1; /* PAN */ + + if (ctx_bss->vif && ctx_pan->vif) { + int bcnint = ctx_pan->vif->bss_conf.beacon_int; + + /* should be set, but seems unused?? */ + cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE); + + if (ctx_pan->vif->type == NL80211_IFTYPE_AP && + bcnint && + bcnint != ctx_bss->vif->bss_conf.beacon_int) { + IWL_ERR(priv, + "beacon intervals don't match (%d, %d)\n", + ctx_bss->vif->bss_conf.beacon_int, + ctx_pan->vif->bss_conf.beacon_int); + } else + bcnint = max_t(int, bcnint, + ctx_bss->vif->bss_conf.beacon_int); + if (!bcnint) + bcnint = 100; + slot0 = bcnint / 2; + slot1 = bcnint - slot0; + + if (test_bit(STATUS_SCAN_HW, &priv->status) || + (!ctx_bss->vif->bss_conf.idle && + !ctx_bss->vif->bss_conf.assoc)) { + slot0 = bcnint * 3 - 20; + slot1 = 20; + } else if (!ctx_pan->vif->bss_conf.idle && + !ctx_pan->vif->bss_conf.assoc) { + slot1 = bcnint * 3 - 20; + slot0 = 20; + } + } else if (ctx_pan->vif) { + slot0 = 0; + slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) * + ctx_pan->vif->bss_conf.beacon_int; + slot1 = max_t(int, 100, slot1); + } + + cmd.slots[0].width = cpu_to_le16(slot0); + cmd.slots[1].width = cpu_to_le16(slot1); + + ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); + + return ret; +} + struct iwl_hcmd_ops iwlagn_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, .set_rxon_chain = iwl_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwl_send_bt_config, + .set_pan_params = iwlagn_set_pan_params, }; struct iwl_hcmd_ops iwlagn_bt_hcmd = { @@ -284,6 +358,7 @@ struct iwl_hcmd_ops iwlagn_bt_hcmd = { .set_rxon_chain = iwl_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwlagn_send_advance_bt_config, + .set_pan_params = iwlagn_set_pan_params, }; struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 7002d7d0fac4..a8f2adfd799e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1424,6 +1424,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->len = cpu_to_le16(cmd.len); set_bit(STATUS_SCAN_HW, &priv->status); + + if (priv->cfg->ops->hcmd->set_pan_params && + priv->cfg->ops->hcmd->set_pan_params(priv)) + goto done; + if (iwl_send_cmd_sync(priv, &cmd)) goto done; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8e0722830413..f2884b5ca5b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -197,6 +197,12 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } } + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } + /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of * stations is needed after it (the RXON command) completes diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 04d7894e0004..b61b838a24b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1931,6 +1931,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); } + if (changes & BSS_CHANGED_IDLE && + priv->cfg->ops->hcmd->set_pan_params) { + if (priv->cfg->ops->hcmd->set_pan_params(priv)) + IWL_ERR(priv, "failed to update PAN params\n"); + } + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d2ee55d6811d..ab465c5fd6f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -94,6 +94,7 @@ struct iwl_hcmd_ops { struct iwl_rxon_context *ctx); int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); void (*send_bt_config)(struct iwl_priv *priv); + int (*set_pan_params)(struct iwl_priv *priv); }; struct iwl_hcmd_utils_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 556dcaaa0efe..7727f0966d31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -572,6 +572,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) iwlcore_commit_rxon(priv, ctx); out: + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); + mutex_unlock(&priv->mutex); /* -- cgit v1.2.3 From 47313e340ee6faa43d8ad8a509a00ed1584fb34d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:55 +0200 Subject: iwlwifi: pass context to iwl_send_rxon_timing Sometimes we need to send RXON timing even when we don't have a virtual interface yet, so pass the context and allow passing one without a virtual interface pointer. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 +++----- drivers/net/wireless/iwlwifi/iwl-core.c | 20 +++++++++----------- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f2884b5ca5b4..85eea944498e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -183,14 +183,12 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); if (new_assoc) { - if (WARN_ON(!ctx->vif)) - return -EINVAL; /* * First of all, before setting associated, we need to * send RXON timing so the device knows about the DTIM * period and other timing values */ - ret = iwl_send_rxon_timing(priv, ctx->vif); + ret = iwl_send_rxon_timing(priv, ctx); if (ret) { IWL_ERR(priv, "Error setting RXON timing!\n"); return ret; @@ -3296,7 +3294,7 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv, ctx); - ret = iwl_send_rxon_timing(priv, vif); + ret = iwl_send_rxon_timing(priv, ctx); if (ret) IWL_WARN(priv, "RXON timing - " "Attempting to continue.\n"); @@ -3536,7 +3534,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) iwlcore_commit_rxon(priv, ctx); /* RXON Timing */ - ret = iwl_send_rxon_timing(priv, vif); + ret = iwl_send_rxon_timing(priv, ctx); if (ret) IWL_WARN(priv, "RXON timing failed - " "Attempting to continue.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b61b838a24b5..91ca5173e862 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -500,13 +500,13 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) return new_val; } -int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { u64 tsf; s32 interval_tm, rem; struct ieee80211_conf *conf = NULL; u16 beacon_int; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + struct ieee80211_vif *vif = ctx->vif; conf = ieee80211_get_hw_conf(priv->hw); @@ -517,15 +517,13 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->timing.timestamp = cpu_to_le64(priv->timestamp); ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); - beacon_int = vif->bss_conf.beacon_int; + beacon_int = vif ? vif->bss_conf.beacon_int : 0; - if (vif->type == NL80211_IFTYPE_ADHOC) { - /* TODO: we need to get atim_window from upper stack - * for now we set to 0 */ - ctx->timing.atim_window = 0; - } else { - ctx->timing.atim_window = 0; - } + /* + * TODO: For IBSS we need to get atim_window from mac80211, + * for now just always use 0 + */ + ctx->timing.atim_window = 0; beacon_int = iwl_adjust_beacon_interval(beacon_int, priv->hw_params.max_beacon_itrvl * TIME_UNIT); @@ -536,7 +534,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) rem = do_div(tsf, interval_tm); ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); - ctx->timing.dtim_period = vif->bss_conf.dtim_period; + ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1; IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ab465c5fd6f6..4d7910001b75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -728,7 +728,7 @@ extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); -int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); static inline int iwl_send_rxon_assoc(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index e81c438b3348..76a45b239664 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3110,7 +3110,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv, ctx); - rc = iwl_send_rxon_timing(priv, vif); + rc = iwl_send_rxon_timing(priv, ctx); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); @@ -3285,7 +3285,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) iwlcore_commit_rxon(priv, ctx); /* RXON Timing */ - rc = iwl_send_rxon_timing(priv, vif); + rc = iwl_send_rxon_timing(priv, ctx); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); -- cgit v1.2.3 From b01efe434bd6ea807eb72ba74fae11beab5c4c04 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:56 +0200 Subject: iwlagn: always send RXON timing The PAN context requires also getting RXON timing when we send an unassociated RXON in some cases. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 85eea944498e..1d58b1c7facd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -105,6 +105,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) int ret; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -EBUSY; @@ -182,7 +183,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - if (new_assoc) { + if (!old_assoc) { /* * First of all, before setting associated, we need to * send RXON timing so the device knows about the DTIM -- cgit v1.2.3 From bde4530e9d2fa013b5674e4c9b066ed6d87ab45c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:57 +0200 Subject: iwlwifi: follow main beacon interval It is necessary that the PAN context always use the same beacon interval as the BSS context unless it is in dual-station mode, ie. the PAN context is a station as well, so implement that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 91ca5173e862..a2b39fd4081e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -525,9 +525,16 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) */ ctx->timing.atim_window = 0; - beacon_int = iwl_adjust_beacon_interval(beacon_int, + if (ctx->ctxid == IWL_RXON_CTX_PAN && + (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION)) { + ctx->timing.beacon_interval = + priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval; + beacon_int = le16_to_cpu(ctx->timing.beacon_interval); + } else { + beacon_int = iwl_adjust_beacon_interval(beacon_int, priv->hw_params.max_beacon_itrvl * TIME_UNIT); - ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + } tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ interval_tm = beacon_int * TIME_UNIT; -- cgit v1.2.3 From d0fe478c9f42dbc4916aa8d1d7a05d7f669d2209 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 23 Aug 2010 10:46:58 +0200 Subject: iwlwifi: allow using multiple contexts We're now ready to start using multiple contexts. We do this by keeping track of the valid interface types per context (exclusive [ibss] and normal) and checking which context is "free" when a new interface is added. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 25 +++++++-- drivers/net/wireless/iwlwifi/iwl-core.c | 80 +++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 11 ++-- 5 files changed, 82 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1d58b1c7facd..ad0e67f5c0d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2828,8 +2828,10 @@ static void iwl_alive_start(struct iwl_priv *priv) ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { + struct iwl_rxon_context *tmp; /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, NULL); + for_each_context(priv, tmp) + iwl_connection_init_rx_config(priv, tmp); if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); @@ -3370,6 +3372,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, { int ret; struct ieee80211_hw *hw = priv->hw; + struct iwl_rxon_context *ctx; + hw->rate_control_algorithm = "iwl-agn-rs"; /* Tell mac80211 our characteristics */ @@ -3389,9 +3393,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->sta_data_size = sizeof(struct iwl_station_priv); hw->vif_data_size = sizeof(struct iwl_vif_priv); - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + for_each_context(priv, ctx) { + hw->wiphy->interface_modes |= ctx->interface_modes; + hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; + } hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -4289,6 +4294,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; + priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; @@ -4301,6 +4313,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; + priv->contexts[IWL_RXON_CTX_PAN].interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); + priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; + priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; + priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a2b39fd4081e..87a2e40972ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1028,38 +1028,34 @@ EXPORT_SYMBOL(iwl_set_flags_for_band); * initialize rxon structure with default values from eeprom */ void iwl_connection_init_rx_config(struct iwl_priv *priv, - struct ieee80211_vif *vif) + struct iwl_rxon_context *ctx) { const struct iwl_channel_info *ch_info; - enum nl80211_iftype type = NL80211_IFTYPE_STATION; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (vif) { - type = vif->type; - ctx = iwl_rxon_ctx_from_vif(vif); - } memset(&ctx->staging, 0, sizeof(ctx->staging)); - switch (type) { + if (!ctx->vif) { + ctx->staging.dev_type = ctx->unused_devtype; + } else switch (ctx->vif->type) { case NL80211_IFTYPE_AP: - ctx->staging.dev_type = RXON_DEV_TYPE_AP; + ctx->staging.dev_type = ctx->ap_devtype; break; case NL80211_IFTYPE_STATION: - ctx->staging.dev_type = RXON_DEV_TYPE_ESS; + ctx->staging.dev_type = ctx->station_devtype; ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; break; case NL80211_IFTYPE_ADHOC: - ctx->staging.dev_type = RXON_DEV_TYPE_IBSS; + ctx->staging.dev_type = ctx->ibss_devtype; ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; break; default: - IWL_ERR(priv, "Unsupported interface type %d\n", type); + IWL_ERR(priv, "Unsupported interface type %d\n", + ctx->vif->type); break; } @@ -1081,7 +1077,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ctx->staging.channel = cpu_to_le16(ch_info->channel); priv->band = ch_info->band; - iwl_set_flags_for_band(priv, ctx, priv->band, vif); + iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); ctx->staging.ofdm_basic_rates = (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; @@ -1091,8 +1087,8 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, /* clear both MIX and PURE40 mode flag */ ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); - if (vif) - memcpy(ctx->staging.node_addr, vif->addr, ETH_ALEN); + if (ctx->vif) + memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; @@ -1952,7 +1948,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - iwl_connection_init_rx_config(priv, vif); + iwl_connection_init_rx_config(priv, ctx); if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); @@ -1964,7 +1960,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - struct iwl_rxon_context *ctx; + struct iwl_rxon_context *tmp, *ctx = NULL; int err = 0; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", @@ -1972,23 +1968,45 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_lock(&priv->mutex); - /* For now always use this context. */ - ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - vif_priv->ctx = ctx; - if (WARN_ON(!iwl_is_ready_rf(priv))) { err = -EINVAL; goto out; } - if (ctx->vif) { - IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); + for_each_context(priv, tmp) { + u32 possible_modes = + tmp->interface_modes | tmp->exclusive_interface_modes; + + if (tmp->vif) { + /* check if this busy context is exclusive */ + if (tmp->exclusive_interface_modes & + BIT(tmp->vif->type)) { + err = -EINVAL; + goto out; + } + continue; + } + + if (!(possible_modes & BIT(vif->type))) + continue; + + /* have maybe usable context w/o interface */ + ctx = tmp; + break; + } + + if (!ctx) { err = -EOPNOTSUPP; goto out; } + vif_priv->ctx = ctx; ctx->vif = vif; + /* + * This variable will be correct only when there's just + * a single context, but all code using it is for hardware + * that supports only one context. + */ priv->iw_mode = vif->type; err = iwl_set_mode(priv, vif); @@ -2029,11 +2047,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (iwl_is_ready_rf(priv)) { - iwl_scan_cancel_timeout(priv, 100); - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - } + WARN_ON(ctx->vif != vif); + ctx->vif = NULL; + + iwl_scan_cancel_timeout(priv, 100); + iwl_set_mode(priv, vif); if (priv->scan_vif == vif) { scan_completed = true; @@ -2051,8 +2069,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_ADHOC) priv->bt_traffic_load = priv->notif_bt_traffic_load; - WARN_ON(ctx->vif != vif); - ctx->vif = NULL; memset(priv->bssid, 0, ETH_ALEN); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4d7910001b75..f7b57ed84f66 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -394,7 +394,7 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_sta_ht_cap *ht_cap); void iwl_connection_init_rx_config(struct iwl_priv *priv, - struct ieee80211_vif *vif); + struct iwl_rxon_context *ctx); void iwl_set_rate(struct iwl_priv *priv); int iwl_set_decrypted_flag(struct iwl_priv *priv, struct ieee80211_hdr *hdr, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 422c71e122f7..4dd38b7b8b74 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1117,6 +1117,10 @@ struct iwl_rxon_context { u8 mcast_queue; enum iwl_rxon_context_id ctxid; + + u32 interface_modes, exclusive_interface_modes; + u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; + /* * We declare this const so it can only be * changed via explicit cast within the diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 76a45b239664..68e624afb987 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2540,7 +2540,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, NULL); + iwl_connection_init_rx_config(priv, ctx); } /* Configure Bluetooth device coexistence support */ @@ -3955,8 +3955,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) IEEE80211_HW_SUPPORTS_DYNAMIC_PS; hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].interface_modes; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -4024,6 +4023,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; /* * Disabling hardware scan means that mac80211 will perform scans -- cgit v1.2.3 From df1c2986c4685776ed02802c170c7fb6f47d8218 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 21 Aug 2010 21:24:59 +0200 Subject: ath5k: re-order one of the frees on unwind There was a small misordering here. In the original code, if we were to go to err_free_ah then it wouldn't free the irq. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index f2fceb10c9fc..45789c8990d3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -700,10 +700,10 @@ ath5k_pci_probe(struct pci_dev *pdev, return 0; err_ah: ath5k_hw_detach(sc->ah); -err_irq: - free_irq(pdev->irq, sc); err_free_ah: kfree(sc->ah); +err_irq: + free_irq(pdev->irq, sc); err_free: ieee80211_free_hw(hw); err_map: -- cgit v1.2.3 From 53b1cf8a28c440fcb241f6fb84da71a7cb0f74f0 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Tue, 24 Aug 2010 21:37:14 -0400 Subject: ath5k: fix off-by-one in pilot magnitude mask If the symbol offset is 46, it will be counted in both the third and fourth bytes of the mask, and in this case the shift will be negative which can pollute high order bits in the mask. This may negatively impact OFDM symbol detection. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 8c27a3644d2f..984ba92c7df3 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1582,7 +1582,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, else if (curr_sym_off >= 31 && curr_sym_off <= 46) mag_mask[2] |= plt_mag_map << (curr_sym_off - 31) * 2; - else if (curr_sym_off >= 46 && curr_sym_off <= 53) + else if (curr_sym_off >= 47 && curr_sym_off <= 53) mag_mask[3] |= plt_mag_map << (curr_sym_off - 47) * 2; -- cgit v1.2.3 From 93dbbcc45c364d62d58737fb9fe6d31085d6a999 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 25 Aug 2010 19:34:52 +0530 Subject: ath9k: Change the default LED pattern. All major Atheros customers require the led to be in continuous ON state rather than the blinking pattern. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 243c1775f343..3dbff8d07766 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -33,7 +33,7 @@ int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); -int led_blink = 1; +int led_blink; module_param_named(blink, led_blink, int, 0444); MODULE_PARM_DESC(blink, "Enable LED blink on activity"); -- cgit v1.2.3 From 5f33c92d188add2a22ec524c03e0ab097e303d52 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 26 Aug 2010 13:30:25 +0200 Subject: mac80211: remove unused scan expire define Since cfg80211 manages the BSS list completely, this define hasn't been used for a long time and will never be used again. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e73ae51dc036..9e225f01497b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -50,12 +50,6 @@ struct ieee80211_local; * increased memory use (about 2 kB of RAM per entry). */ #define IEEE80211_FRAGMENT_MAX 4 -/* - * Time after which we ignore scan results and no longer report/use - * them in any way. - */ -#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) - #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) #define IEEE80211_DEFAULT_UAPSD_QUEUES \ -- cgit v1.2.3 From 8789d459bc5e837bf37d261453df96ef54018d7b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 26 Aug 2010 13:30:26 +0200 Subject: mac80211: allow scan to complete from any context The ieee80211_scan_completed() function was a frequent source of potential deadlocks, since it is called by drivers but may call back into drivers, so drivers had to make sure to call it without any locks held, which frequently lead to more complex code in drivers. Avoid that problem by allowing the function to be called in any context, and queueing the actual work it does. Also update the documentation for it to indicate this. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 3 ++- net/mac80211/ieee80211_i.h | 6 ++++++ net/mac80211/scan.c | 34 ++++++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dcc8c2bf986e..8f97548b6d80 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2268,7 +2268,8 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw); * * When hardware scan offload is used (i.e. the hw_scan() callback is * assigned) this function needs to be called by the driver to notify - * mac80211 that the scan finished. + * mac80211 that the scan finished. This function can be called from + * any context, including hardirq context. * * @hw: the hardware that finished the scan * @aborted: set to true if scan was aborted diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9e225f01497b..31713320258c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -596,11 +596,17 @@ enum queue_stop_reason { * determine if we are on the operating channel or not * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, * gets only set in conjunction with SCAN_SW_SCANNING + * @SCAN_COMPLETED: Set for our scan work function when the driver reported + * that the scan completed. + * @SCAN_ABORTED: Set for our scan work function when the driver reported + * a scan complete for an aborted scan. */ enum { SCAN_SW_SCANNING, SCAN_HW_SCANNING, SCAN_OFF_CHANNEL, + SCAN_COMPLETED, + SCAN_ABORTED, }; /** diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 31f233f7f51a..d60389ba9b95 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -248,13 +248,11 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) return true; } -void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) +static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) { struct ieee80211_local *local = hw_to_local(hw); bool was_hw_scan; - trace_api_scan_completed(local, aborted); - mutex_lock(&local->mtx); /* @@ -312,6 +310,18 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) ieee80211_mesh_notify_scan_completed(local); ieee80211_queue_work(&local->hw, &local->work_work); } + +void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_scan_completed(local, aborted); + + set_bit(SCAN_COMPLETED, &local->scanning); + if (aborted) + set_bit(SCAN_ABORTED, &local->scanning); + ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); +} EXPORT_SYMBOL(ieee80211_scan_completed); static int ieee80211_start_sw_scan(struct ieee80211_local *local) @@ -449,7 +459,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, /* if no more bands/channels left, complete scan and advance to the idle state */ if (local->scan_channel_idx >= local->scan_req->n_channels) { - ieee80211_scan_completed(&local->hw, false); + __ieee80211_scan_completed(&local->hw, false); return 1; } @@ -641,6 +651,14 @@ void ieee80211_scan_work(struct work_struct *work) struct ieee80211_sub_if_data *sdata = local->scan_sdata; unsigned long next_delay = 0; + if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { + bool aborted; + + aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); + __ieee80211_scan_completed(&local->hw, aborted); + return; + } + mutex_lock(&local->mtx); if (!sdata || !local->scan_req) { mutex_unlock(&local->mtx); @@ -651,7 +669,7 @@ void ieee80211_scan_work(struct work_struct *work) int rc = drv_hw_scan(local, sdata, local->hw_scan_req); mutex_unlock(&local->mtx); if (rc) - ieee80211_scan_completed(&local->hw, true); + __ieee80211_scan_completed(&local->hw, true); return; } @@ -666,7 +684,7 @@ void ieee80211_scan_work(struct work_struct *work) mutex_unlock(&local->mtx); if (rc) - ieee80211_scan_completed(&local->hw, true); + __ieee80211_scan_completed(&local->hw, true); return; } @@ -676,7 +694,7 @@ void ieee80211_scan_work(struct work_struct *work) * Avoid re-scheduling when the sdata is going away. */ if (!ieee80211_sdata_running(sdata)) { - ieee80211_scan_completed(&local->hw, true); + __ieee80211_scan_completed(&local->hw, true); return; } @@ -783,5 +801,5 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) mutex_unlock(&local->mtx); if (abortscan) - ieee80211_scan_completed(&local->hw, true); + __ieee80211_scan_completed(&local->hw, true); } -- cgit v1.2.3 From 0ec2f2724d7e457b91e5983d11db8adba9aad47e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 26 Aug 2010 13:30:27 +0200 Subject: wl12xx: remove unneeded locking With the scan callback now being callable from any context, these unlocks/locks can go away. This makes the code easier to understand, since callers of these functions must no longer be aware that the mutex may be dropped. As Stanislaw is working on iwlwifi scanning, I didn't change it to take advantage of the new mac80211 semantics. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251_event.c | 2 -- drivers/net/wireless/wl12xx/wl1251_main.c | 2 -- drivers/net/wireless/wl12xx/wl1271_main.c | 2 -- drivers/net/wireless/wl12xx/wl1271_scan.c | 2 -- 4 files changed, 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c index 00c3e648d93f..54223556b308 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl12xx/wl1251_event.c @@ -34,9 +34,7 @@ static int wl1251_event_scan_complete(struct wl1251 *wl, mbox->scheduled_scan_channels); if (wl->scanning) { - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); wl->scanning = false; } diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index edd4845c3707..f9d9ad620cc9 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -467,9 +467,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) WARN_ON(wl->state != WL1251_STATE_ON); if (wl->scanning) { - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, true); - mutex_lock(&wl->mutex); wl->scanning = false; } diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 30194c0f36a9..8e55cf8d509d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -948,9 +948,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, ieee80211_enable_dyn_ps(wl->vif); if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, true); - mutex_lock(&wl->mutex); wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index fec43eed8c55..9c80ba9b6be0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -215,9 +215,7 @@ void wl1271_scan_stm(struct wl1271 *wl) break; case WL1271_SCAN_STATE_DONE: - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; -- cgit v1.2.3 From fe67470ddd075cb7d538de1570950da3c0f67e65 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 27 Aug 2010 12:09:00 +0530 Subject: ath9k_htc: Enable ANI in associated state only While scanning, ANI is triggered unnecessarily where sta is in unassociated state. And cancelling ani work in ath9k_htc_stop is not required. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5e318cb662c6..f4672073ac0a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1239,7 +1239,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) /* Cancel all the running timers/work .. */ cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); ath9k_led_stop_brightness(priv); @@ -1787,7 +1786,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) priv->op_flags |= OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); + if (priv->op_flags & OP_ASSOCIATED) + cancel_delayed_work_sync(&priv->ath9k_ani_work); mutex_unlock(&priv->mutex); } @@ -1801,9 +1801,10 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); priv->op_flags |= OP_FULL_RESET; - if (priv->op_flags & OP_ASSOCIATED) + if (priv->op_flags & OP_ASSOCIATED) { ath9k_htc_beacon_config(priv, priv->vif); - ath_start_ani(priv); + ath_start_ani(priv); + } ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } -- cgit v1.2.3 From b49d09c5bf9a3261ae711ac3bb91e22c172db428 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 11:29:24 +0200 Subject: cfg80211 docbook: remove erronous !A My previous patch erroneously included an !A line (for some checking I am working on) that isn't yet supported by the docbook tools, so remove it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/DocBook/80211.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index b84c9282828f..19a1210c2530 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -65,7 +65,6 @@ -!Ainclude/net/cfg80211.h The cfg80211 subsystem -- cgit v1.2.3 From 7d64b7cc1fc33bab24567903a93f699d11649c0b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 14:26:51 +0300 Subject: cfg80211: allow vendor specific cipher suites cfg80211 currently rejects all cipher suites it doesn't know about for key length checking purposes. This can lead to inconsistencies when a driver advertises an algorithm that cfg80211 doesn't know about. Remove this rejection so drivers can specify any algorithm they like. Signed-off-by: Johannes Berg Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- net/wireless/util.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 8d961cc4ae98..bca32eb8f446 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -183,7 +183,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, return -EINVAL; break; default: - return -EINVAL; + /* + * We don't know anything about this algorithm, + * allow using it -- but the driver must check + * all parameters! We still check below whether + * or not the driver supports this algorithm, + * of course. + */ + break; } if (params->seq) { -- cgit v1.2.3 From 3ffc2a905b1faae4c0fe39d66f0752c3a4cbb3c7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 14:26:52 +0300 Subject: mac80211: allow vendor specific cipher suites Allow drivers to specify their own set of cipher suites to advertise vendor-specific ciphers. The driver is then required to implement hardware crypto offload for it. Signed-off-by: Johannes Berg Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 5 +++-- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/key.c | 38 ++++++++++++++++++++++++++++++-------- net/mac80211/key.h | 6 +++--- net/mac80211/main.c | 44 ++++++++++++++++++++++++++++++++++++++------ net/mac80211/rx.c | 6 ++++++ net/mac80211/tx.c | 12 ++++++++++-- 7 files changed, 92 insertions(+), 21 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 581438255d7e..f149b4eb28d9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -119,9 +119,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, } } - ieee80211_key_link(key, sdata, sta); + err = ieee80211_key_link(key, sdata, sta); + if (err) + ieee80211_key_free(sdata->local, key); - err = 0; out_unlock: mutex_unlock(&sdata->local->sta_mtx); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 31713320258c..7d2bb6fbc2e6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -662,6 +662,8 @@ struct ieee80211_local { int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; unsigned int filter_flags; /* FIF_* */ + bool wiphy_ciphers_allocated; + /* protects the aggregated multicast list and filter calls */ spinlock_t filter_lock; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 2ce2dbbf6309..3570f8c2bb40 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -60,7 +60,7 @@ static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) return NULL; } -static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) +static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) { struct ieee80211_sub_if_data *sdata; struct ieee80211_sta *sta; @@ -68,8 +68,10 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) might_sleep(); - if (!key->local->ops->set_key) - return; + if (!key->local->ops->set_key) { + ret = -EOPNOTSUPP; + goto out_unsupported; + } assert_key_lock(key->local); @@ -90,6 +92,24 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) wiphy_err(key->local->hw.wiphy, "failed to set key (%d, %pM) to hardware (%d)\n", key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + +out_unsupported: + if (ret) { + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_AES_CMAC: + /* all of these we can do in software */ + ret = 0; + break; + default: + ret = -EINVAL; + } + } + + return ret; } static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) @@ -329,12 +349,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) kfree(key); } -void ieee80211_key_link(struct ieee80211_key *key, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta) +int ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta) { struct ieee80211_key *old_key; - int idx; + int idx, ret; BUG_ON(!sdata); BUG_ON(!key); @@ -389,9 +409,11 @@ void ieee80211_key_link(struct ieee80211_key *key, ieee80211_debugfs_key_add(key); - ieee80211_key_enable_hw_accel(key); + ret = ieee80211_key_enable_hw_accel(key); mutex_unlock(&sdata->local->key_mtx); + + return ret; } static void __ieee80211_key_free(struct ieee80211_key *key) diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 53b5ce12536f..cb9a4a65cc68 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -130,9 +130,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, * Insert a key into data structures (sdata, sta if necessary) * to make it used, free old key. */ -void ieee80211_key_link(struct ieee80211_key *key, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta); +int __must_check ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta); void ieee80211_key_free(struct ieee80211_local *local, struct ieee80211_key *key); void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 80db5ea02052..15f0e960fde8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -662,13 +662,40 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->max_scan_ie_len) local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; - local->hw.wiphy->cipher_suites = cipher_suites; - local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) - local->hw.wiphy->n_cipher_suites--; + /* Set up cipher suites unless driver already did */ + if (!local->hw.wiphy->cipher_suites) { + local->hw.wiphy->cipher_suites = cipher_suites; + local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) + local->hw.wiphy->n_cipher_suites--; + } if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { - local->hw.wiphy->cipher_suites += 2; - local->hw.wiphy->n_cipher_suites -= 2; + if (local->hw.wiphy->cipher_suites == cipher_suites) { + local->hw.wiphy->cipher_suites += 2; + local->hw.wiphy->n_cipher_suites -= 2; + } else { + u32 *suites; + int r, w = 0; + + /* Filter out WEP */ + + suites = kmemdup( + local->hw.wiphy->cipher_suites, + sizeof(u32) * local->hw.wiphy->n_cipher_suites, + GFP_KERNEL); + if (!suites) + return -ENOMEM; + for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { + u32 suite = local->hw.wiphy->cipher_suites[r]; + if (suite == WLAN_CIPHER_SUITE_WEP40 || + suite == WLAN_CIPHER_SUITE_WEP104) + continue; + suites[w++] = suite; + } + local->hw.wiphy->cipher_suites = suites; + local->hw.wiphy->n_cipher_suites = w; + local->wiphy_ciphers_allocated = true; + } } result = wiphy_register(local->hw.wiphy); @@ -783,6 +810,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) fail_workqueue: wiphy_unregister(local->hw.wiphy); fail_wiphy_register: + if (local->wiphy_ciphers_allocated) + kfree(local->hw.wiphy->cipher_suites); kfree(local->int_scan_req); return result; } @@ -840,6 +869,9 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) mutex_destroy(&local->iflist_mtx); mutex_destroy(&local->mtx); + if (local->wiphy_ciphers_allocated) + kfree(local->hw.wiphy->cipher_suites); + wiphy_free(local->hw.wiphy); } EXPORT_SYMBOL(ieee80211_free_hw); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e67deb48af5c..6e5fb16af55c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1000,6 +1000,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) case WLAN_CIPHER_SUITE_AES_CMAC: result = ieee80211_crypto_aes_cmac_decrypt(rx); break; + default: + /* + * We can reach here only with HW-only algorithms + * but why didn't it decrypt the frame?! + */ + return RX_DROP_UNUSABLE; } /* either the frame has been decrypted or will be dropped */ diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a6ac9fd248f2..31a8903a45af 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -947,6 +947,8 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) static ieee80211_tx_result debug_noinline ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + if (!tx->key) return TX_CONTINUE; @@ -960,10 +962,16 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) return ieee80211_crypto_ccmp_encrypt(tx); case WLAN_CIPHER_SUITE_AES_CMAC: return ieee80211_crypto_aes_cmac_encrypt(tx); + default: + /* handle hw-only algorithm */ + if (info->control.hw_key) { + ieee80211_tx_set_protected(tx); + return TX_CONTINUE; + } + break; + } - /* not reached */ - WARN_ON(1); return TX_DROP; } -- cgit v1.2.3 From c0692b8fe29fb4d4dad33487aabf3ed7e1e880c0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 14:26:53 +0300 Subject: cfg80211: allow changing port control protocol Some vendor specified mechanisms for 802.1X-style functionality use a different protocol than EAP (even if EAP is vendor-extensible). Allow setting the ethertype for the protocol when a driver has support for this. The default if unspecified is EAP, of course. Note: This is suitable only for station mode, not for AP implementation. Signed-off-by: Johannes Berg Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 16 +++++++++++++++- include/net/cfg80211.h | 24 +++++++++++++++++------- net/wireless/nl80211.c | 25 ++++++++++++++++++++++--- net/wireless/wext-sme.c | 2 ++ 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index ec1690da7845..31603e8b5581 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -295,7 +295,9 @@ * auth and assoc steps. For this, you need to specify the SSID in a * %NL80211_ATTR_SSID attribute, and can optionally specify the association * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, - * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT. + * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be * determined by the STATUS_CODE attribute. @@ -686,6 +688,15 @@ enum nl80211_commands { * request, the driver will assume that the port is unauthorized until * authorized by user space. Otherwise, port is marked authorized by * default in station mode. + * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the + * ethertype that will be used for key negotiation. It can be + * specified with the associate and connect commands. If it is not + * specified, the value defaults to 0x888E (PAE, 802.1X). This + * attribute is also used as a flag in the wiphy information to + * indicate that protocols other than PAE are supported. + * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom + * ethertype frames used for key negotiation must not be encrypted. * * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. * We recommend using nested, driver-specific attributes within this. @@ -951,6 +962,9 @@ enum nl80211_attrs { NL80211_ATTR_RX_FRAME_TYPES, NL80211_ATTR_FRAME_TYPE, + NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f2740537b5d6..4c8c727d0cca 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -763,6 +763,10 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is * required to assume that the port is unauthorized until authorized by * user space. Otherwise, port is marked authorized by default. + * @control_port_ethertype: the control port protocol that should be + * allowed through even on unauthorized ports + * @control_port_no_encrypt: TRUE to prevent encryption of control port + * protocol frames. */ struct cfg80211_crypto_settings { u32 wpa_versions; @@ -772,6 +776,8 @@ struct cfg80211_crypto_settings { int n_akm_suites; u32 akm_suites[NL80211_MAX_NR_AKM_SUITES]; bool control_port; + __be16 control_port_ethertype; + bool control_port_no_encrypt; }; /** @@ -1293,15 +1299,19 @@ struct cfg80211_ops { * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station * on a VLAN interface) * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station + * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the + * control port protocol ethertype. The device also honours the + * control_port_no_encrypt flag. */ enum wiphy_flags { - WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), - WIPHY_FLAG_STRICT_REGULATORY = BIT(1), - WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), - WIPHY_FLAG_NETNS_OK = BIT(3), - WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), - WIPHY_FLAG_4ADDR_AP = BIT(5), - WIPHY_FLAG_4ADDR_STATION = BIT(6), + WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), + WIPHY_FLAG_STRICT_REGULATORY = BIT(1), + WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), + WIPHY_FLAG_NETNS_OK = BIT(3), + WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), + WIPHY_FLAG_4ADDR_AP = BIT(5), + WIPHY_FLAG_4ADDR_STATION = BIT(6), + WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), }; struct mac_address { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 49f5ca35e787..85a23de7bff3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -136,6 +136,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = sizeof(struct nl80211_sta_flag_update), }, [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, + [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, @@ -474,6 +476,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, dev->wiphy.max_num_pmkids); + if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) + NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); + nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); if (!nl_modes) goto nla_put_failure; @@ -3691,7 +3696,8 @@ unlock_rtnl: return err; } -static int nl80211_crypto_settings(struct genl_info *info, +static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, + struct genl_info *info, struct cfg80211_crypto_settings *settings, int cipher_limit) { @@ -3699,6 +3705,19 @@ static int nl80211_crypto_settings(struct genl_info *info, settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; + if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) { + u16 proto; + proto = nla_get_u16( + info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); + settings->control_port_ethertype = cpu_to_be16(proto); + if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && + proto != ETH_P_PAE) + return -EINVAL; + if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) + settings->control_port_no_encrypt = true; + } else + settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE); + if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { void *data; int len, i; @@ -3826,7 +3845,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_PREV_BSSID]) prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); - err = nl80211_crypto_settings(info, &crypto, 1); + err = nl80211_crypto_settings(rdev, info, &crypto, 1); if (!err) err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, ssid, ssid_len, ie, ie_len, use_mfp, @@ -4303,7 +4322,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) connect.privacy = info->attrs[NL80211_ATTR_PRIVACY]; - err = nl80211_crypto_settings(info, &connect.crypto, + err = nl80211_crypto_settings(rdev, info, &connect.crypto, NL80211_MAX_NR_CIPHER_SUITES); if (err) return err; diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 9818198add8a..6fffe62d7c25 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -197,6 +197,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, wdev->wext.connect.ssid_len = len; wdev->wext.connect.crypto.control_port = false; + wdev->wext.connect.crypto.control_port_ethertype = + cpu_to_be16(ETH_P_PAE); err = cfg80211_mgd_wext_connect(rdev, wdev); out: -- cgit v1.2.3 From a621fa4d6a7fdf9d34938d2e129a72624833eeeb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 14:26:54 +0300 Subject: mac80211: allow changing port control protocol Some vendor specified mechanisms for 802.1X-style functionality use a different protocol than EAP (even if EAP is vendor-extensible). Support this in mac80211 via the cfg80211 API for it. Signed-off-by: Johannes Berg Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 3 +++ net/mac80211/main.c | 3 +++ net/mac80211/mlme.c | 3 +++ net/mac80211/rx.c | 2 +- net/mac80211/tx.c | 20 +++++++++++++++++--- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 7d2bb6fbc2e6..f64837788681 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -509,6 +509,8 @@ struct ieee80211_sub_if_data { struct ieee80211_key *default_mgmt_key; u16 sequence_number; + __be16 control_port_protocol; + bool control_port_no_encrypt; struct work_struct work; struct sk_buff_head skb_queue; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9369710cc65b..810e6764d04f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -855,6 +855,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->dev->netdev_ops = &ieee80211_dataif_ops; sdata->wdev.iftype = type; + sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); + sdata->control_port_no_encrypt = false; + /* only monitor differs */ sdata->dev->type = ARPHRD_ETHER; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 15f0e960fde8..964c267163a0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -627,6 +627,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); #endif + /* mac80211 supports control port protocol changing */ + local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; + if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5282ac18d2cf..0cb429657474 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2262,6 +2262,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, else ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; + sdata->control_port_protocol = req->crypto.control_port_ethertype; + sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; + ieee80211_add_work(wk); return 0; } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6e5fb16af55c..ac205a33690f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1527,7 +1527,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) * Allow EAPOL frames to us/the PAE group address regardless * of whether the frame was encrypted or not. */ - if (ehdr->h_proto == htons(ETH_P_PAE) && + if (ehdr->h_proto == rx->sdata->control_port_protocol && (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) return true; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 31a8903a45af..92764bb8795c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -508,6 +508,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) return ieee80211_tx_h_multicast_ps_buf(tx); } +static ieee80211_tx_result debug_noinline +ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + + if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && + tx->sdata->control_port_no_encrypt)) + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + + return TX_CONTINUE; +} + static ieee80211_tx_result debug_noinline ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) { @@ -527,7 +539,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) else if ((key = rcu_dereference(tx->sdata->default_key))) tx->key = key; else if (tx->sdata->drop_unencrypted && - (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && + (tx->skb->protocol != tx->sdata->control_port_protocol) && !(info->flags & IEEE80211_TX_CTL_INJECTED) && (!ieee80211_is_robust_mgmt_frame(hdr) || (ieee80211_is_action(hdr->frame_control) && @@ -1349,6 +1361,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) CALL_TXH(ieee80211_tx_h_dynamic_ps); CALL_TXH(ieee80211_tx_h_check_assoc); CALL_TXH(ieee80211_tx_h_ps_buf); + CALL_TXH(ieee80211_tx_h_check_control_port_protocol); CALL_TXH(ieee80211_tx_h_select_key); if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) CALL_TXH(ieee80211_tx_h_rate_ctrl); @@ -1826,7 +1839,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, #endif case NL80211_IFTYPE_STATION: memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); - if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { + if (sdata->u.mgd.use_4addr && + cpu_to_be16(ethertype) != sdata->control_port_protocol) { fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); /* RA TA DA SA */ memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); @@ -1879,7 +1893,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (!ieee80211_vif_is_mesh(&sdata->vif) && unlikely(!is_multicast_ether_addr(hdr.addr1) && !(sta_flags & WLAN_STA_AUTHORIZED) && - !(ethertype == ETH_P_PAE && + !(cpu_to_be16(ethertype) == sdata->control_port_protocol && compare_ether_addr(sdata->vif.addr, skb->data + ETH_ALEN) == 0))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG -- cgit v1.2.3 From 2337db8db845ece2d4ab7673a343e285f1bfda85 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 13:36:49 +0200 Subject: mac80211: use subqueue helpers There are subqueue helpers so that we don't need to get the TX queue and then wake/stop it, use those helpers. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/tx.c | 3 +-- net/mac80211/util.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 92764bb8795c..ccf373788ce9 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2092,8 +2092,7 @@ void ieee80211_tx_pending(unsigned long data) if (skb_queue_empty(&local->pending[i])) list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_wake_queue( - netdev_get_tx_queue(sdata->dev, i)); + netif_wake_subqueue(sdata->dev, i); } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cd2b485fed4f..ef686d3b04e3 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -284,7 +284,7 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, if (skb_queue_empty(&local->pending[queue])) { rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); + netif_wake_subqueue(sdata->dev, queue); rcu_read_unlock(); } else tasklet_schedule(&local->tx_pending_tasklet); @@ -323,7 +323,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); + netif_stop_subqueue(sdata->dev, queue); rcu_read_unlock(); } -- cgit v1.2.3 From b9dcf712d1fb98bf279fcd453a42a763b104961d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:54 +0200 Subject: mac80211: clean up ifdown/cleanup paths There's a lot of redundant code in mac80211's interface cleanup/down, for example freeing AP beacons is done both when the interface is set DOWN as well as when it is torn down, of which only the former has any effect. Also, a bunch of things should be closer to where they matter, like the MLME timers that we should cancel when disassociating, rather than only when the interface is set DOWN. Clean up all this code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 89 ++++++++++++++-------------------------------------- net/mac80211/mlme.c | 5 +++ 2 files changed, 28 insertions(+), 66 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 810e6764d04f..cc1c68d7dda6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -370,12 +370,9 @@ static int ieee80211_stop(struct net_device *dev) * (because if we remove a STA after ops->remove_interface() * the driver will have removed the vif info already!) * - * We could relax this and only unlink the stations from the - * hash table and list but keep them on a per-sdata list that - * will be inserted back again when the interface is brought - * up again, but I don't currently see a use case for that, - * except with WDS which gets a STA entry created when it is - * brought up. + * This is relevant only in AP, WDS and mesh modes, since in + * all other modes we've already removed all stations when + * disconnecting etc. */ sta_info_flush(local, sdata); @@ -410,11 +407,21 @@ static int ieee80211_stop(struct net_device *dev) struct ieee80211_sub_if_data *vlan, *tmpsdata; struct beacon_data *old_beacon = sdata->u.ap.beacon; + /* sdata_running will return false, so this will disable */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BEACON_ENABLED); + /* remove beacon */ rcu_assign_pointer(sdata->u.ap.beacon, NULL); synchronize_rcu(); kfree(old_beacon); + /* free all potentially still buffered bcast frames */ + while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { + local->total_ps_buffered--; + dev_kfree_skb(skb); + } + /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, u.vlan.list) @@ -454,27 +461,6 @@ static int ieee80211_stop(struct net_device *dev) ieee80211_configure_filter(local); break; - case NL80211_IFTYPE_STATION: - del_timer_sync(&sdata->u.mgd.chswitch_timer); - del_timer_sync(&sdata->u.mgd.timer); - del_timer_sync(&sdata->u.mgd.conn_mon_timer); - del_timer_sync(&sdata->u.mgd.bcn_mon_timer); - /* - * If any of the timers fired while we waited for it, it will - * have queued its work. Now the work will be running again - * but will not rearm the timer again because it checks - * whether the interface is running, which, at this point, - * it no longer is. - */ - cancel_work_sync(&sdata->u.mgd.chswitch_work); - cancel_work_sync(&sdata->u.mgd.monitor_work); - cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); - - /* fall through */ - case NL80211_IFTYPE_ADHOC: - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - del_timer_sync(&sdata->u.ibss.timer); - /* fall through */ case NL80211_IFTYPE_MESH_POINT: if (ieee80211_vif_is_mesh(&sdata->vif)) { /* other_bss and allmulti are always set on mesh @@ -502,17 +488,19 @@ static int ieee80211_stop(struct net_device *dev) ieee80211_scan_cancel(local); /* - * Disable beaconing for AP and mesh, IBSS can't - * still be joined to a network at this point. + * Disable beaconing here for mesh only, AP and IBSS + * are already taken care of. */ - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { + if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - } - /* free all remaining keys, there shouldn't be any */ + /* + * Free all remaining keys, there shouldn't be any, + * except maybe group keys in AP more or WDS? + */ ieee80211_free_keys(sdata); + drv_remove_interface(local, &sdata->vif); } @@ -593,8 +581,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; - struct beacon_data *beacon; - struct sk_buff *skb; int flushed; int i; @@ -607,37 +593,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) __skb_queue_purge(&sdata->fragments[i].skb_list); sdata->fragment_next = 0; - switch (sdata->vif.type) { - case NL80211_IFTYPE_AP: - beacon = sdata->u.ap.beacon; - rcu_assign_pointer(sdata->u.ap.beacon, NULL); - synchronize_rcu(); - kfree(beacon); - - while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { - local->total_ps_buffered--; - dev_kfree_skb(skb); - } - - break; - case NL80211_IFTYPE_MESH_POINT: - if (ieee80211_vif_is_mesh(&sdata->vif)) - mesh_rmc_free(sdata); - break; - case NL80211_IFTYPE_ADHOC: - if (WARN_ON(sdata->u.ibss.presp)) - kfree_skb(sdata->u.ibss.presp); - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MONITOR: - break; - case NL80211_IFTYPE_UNSPECIFIED: - case NUM_NL80211_IFTYPES: - BUG(); - break; - } + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_rmc_free(sdata); flushed = sta_info_flush(local, sdata); WARN_ON(flushed); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0cb429657474..c8694478cde2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -991,6 +991,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (remove_sta) sta_info_destroy_addr(sdata, bssid); + + del_timer_sync(&sdata->u.mgd.conn_mon_timer); + del_timer_sync(&sdata->u.mgd.bcn_mon_timer); + del_timer_sync(&sdata->u.mgd.timer); + del_timer_sync(&sdata->u.mgd.chswitch_timer); } void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, -- cgit v1.2.3 From 26a58456be40d8181b884eb5b4e61e3f73ba94e0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:55 +0200 Subject: mac80211: switch to ieee80211_sdata_running Since the introduction of ieee80211_sdata_running(), some new code was introduced that uses netif_running() instead. Switch all these instances over. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 6 ++---- net/mac80211/main.c | 6 +++--- net/mac80211/util.c | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f149b4eb28d9..f82b18e996b2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -81,16 +81,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, const u8 *mac_addr, struct key_params *params) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct sta_info *sta = NULL; struct ieee80211_key *key; int err; - if (!netif_running(dev)) + if (!ieee80211_sdata_running(sdata)) return -ENETDOWN; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - /* reject WEP and TKIP keys if WEP failed to initialize */ switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 964c267163a0..93194f61adb0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -339,9 +339,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, struct ieee80211_if_managed *ifmgd; int c = 0; - if (!netif_running(ndev)) - return NOTIFY_DONE; - /* Make sure it's our interface that got changed */ if (!wdev) return NOTIFY_DONE; @@ -352,6 +349,9 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, sdata = IEEE80211_DEV_TO_SUB_IF(ndev); bss_conf = &sdata->vif.bss_conf; + if (!ieee80211_sdata_running(sdata)) + return NOTIFY_DONE; + /* ARP filtering is only supported in managed mode */ if (sdata->vif.type != NL80211_IFTYPE_STATION) return NOTIFY_DONE; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ef686d3b04e3..d38b3767e8cc 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1308,7 +1308,7 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, */ list_for_each_entry(sdata, &local->interfaces, list) { - if (!netif_running(sdata->dev)) + if (!ieee80211_sdata_running(sdata)) continue; if (sdata->vif.type != NL80211_IFTYPE_STATION) goto set; -- cgit v1.2.3 From bf533e0bfd77d9671adabdf134b1ac7f24bb0670 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:56 +0200 Subject: mac80211: simplify zero address checks The libertas_tf special code for zero addresses is a bit too complex, it compares against a stack value instead of using is_zero_ether_addr() and tries to update all interfaces even if just the one that's being brought up needs to be changed. Additionally, the repeated check for a valid MAC address need only be done if we actually changed it on the fly. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index cc1c68d7dda6..ea50732ec526 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -103,10 +103,9 @@ static int ieee80211_open(struct net_device *dev) u32 changed = 0; int res; u32 hw_reconf_flags = 0; - u8 null_addr[ETH_ALEN] = {0}; /* fail early if user set an invalid address */ - if (compare_ether_addr(dev->dev_addr, null_addr) && + if (!is_zero_ether_addr(dev->dev_addr) && !is_valid_ether_addr(dev->dev_addr)) return -EADDRNOTAVAIL; @@ -195,33 +194,22 @@ static int ieee80211_open(struct net_device *dev) } /* - * Check all interfaces and copy the hopefully now-present - * MAC address to those that have the special null one. + * Copy the hopefully now-present MAC address to + * this interface, if it has the special null one. */ - list_for_each_entry(nsdata, &local->interfaces, list) { - struct net_device *ndev = nsdata->dev; - - /* - * No need to check running since we do not allow - * it to start up with this invalid address. - */ - if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { - memcpy(ndev->dev_addr, - local->hw.wiphy->perm_addr, - ETH_ALEN); - memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); + if (is_zero_ether_addr(dev->dev_addr)) { + memcpy(dev->dev_addr, + local->hw.wiphy->perm_addr, + ETH_ALEN); + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); + + if (!is_valid_ether_addr(dev->dev_addr)) { + if (!local->open_count) + drv_stop(local); + return -EADDRNOTAVAIL; } } - /* - * Validate the MAC address for this device. - */ - if (!is_valid_ether_addr(dev->dev_addr)) { - if (!local->open_count) - drv_stop(local); - return -EADDRNOTAVAIL; - } - switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: /* no need to tell driver */ -- cgit v1.2.3 From 87490f6db38999fee7f6d3dbecc5b94730c7e010 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:57 +0200 Subject: mac80211: split out concurrent vif checks Split the concurrent virtual interface checks into a new function that can be used to check for any given new interface type. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ea50732ec526..cba3d806d722 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -94,20 +94,14 @@ static inline int identical_mac_addr_allowed(int type1, int type2) type2 == NL80211_IFTYPE_AP_VLAN)); } -static int ieee80211_open(struct net_device *dev) +static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype iftype) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_sub_if_data *nsdata; struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - u32 changed = 0; - int res; - u32 hw_reconf_flags = 0; + struct ieee80211_sub_if_data *nsdata; + struct net_device *dev = sdata->dev; - /* fail early if user set an invalid address */ - if (!is_zero_ether_addr(dev->dev_addr) && - !is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; + ASSERT_RTNL(); /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { @@ -124,7 +118,7 @@ static int ieee80211_open(struct net_device *dev) * belonging to the same hardware. Then, however, we're * faced with having to adopt two different TSF timers... */ - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && + if (iftype == NL80211_IFTYPE_ADHOC && nsdata->vif.type == NL80211_IFTYPE_ADHOC) return -EBUSY; @@ -138,19 +132,40 @@ static int ieee80211_open(struct net_device *dev) /* * check whether it may have the same address */ - if (!identical_mac_addr_allowed(sdata->vif.type, + if (!identical_mac_addr_allowed(iftype, nsdata->vif.type)) return -ENOTUNIQ; /* * can only add VLANs to enabled APs */ - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && + if (iftype == NL80211_IFTYPE_AP_VLAN && nsdata->vif.type == NL80211_IFTYPE_AP) sdata->bss = &nsdata->u.ap; } } + return 0; +} + +static int ieee80211_open(struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + u32 changed = 0; + int res; + u32 hw_reconf_flags = 0; + + /* fail early if user set an invalid address */ + if (!is_zero_ether_addr(dev->dev_addr) && + !is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; + + res = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); + if (res) + return res; + switch (sdata->vif.type) { case NL80211_IFTYPE_WDS: if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) -- cgit v1.2.3 From 34d4bc4d41d282a66dafe1b01a7d46bad468cefb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:58 +0200 Subject: mac80211: support runtime interface type changes Add support to mac80211 for changing the interface type even when the interface is UP, if the driver supports it. To achieve this * add a new driver callback for switching, * split some of the interface up/down code out into new functions (do_open/do_stop), and * maintain an own __SDATA_RUNNING bit that will not be set during interface type, so that any other code doesn't use the interface. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 9 +++ net/mac80211/cfg.c | 3 - net/mac80211/driver-ops.h | 14 ++++ net/mac80211/driver-trace.h | 25 +++++++ net/mac80211/ieee80211_i.h | 14 +++- net/mac80211/iface.c | 157 ++++++++++++++++++++++++++++++++++---------- 6 files changed, 185 insertions(+), 37 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8f97548b6d80..f91fc331369b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1537,6 +1537,12 @@ enum ieee80211_ampdu_mlme_action { * negative error code (which will be seen in userspace.) * Must be implemented and can sleep. * + * @change_interface: Called when a netdevice changes type. This callback + * is optional, but only if it is supported can interface types be + * switched while the interface is UP. The callback may sleep. + * Note that while an interface is being switched, it will not be + * found by the interface iteration callbacks. + * * @remove_interface: Notifies a driver that an interface is going down. * The @stop callback is called after this if it is the last interface * and no monitor interfaces are present. @@ -1693,6 +1699,9 @@ struct ieee80211_ops { void (*stop)(struct ieee80211_hw *hw); int (*add_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + int (*change_interface)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype new_type); void (*remove_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int (*config)(struct ieee80211_hw *hw, u32 changed); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f82b18e996b2..5de1ca3f17b9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -52,9 +52,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); int ret; - if (ieee80211_sdata_running(sdata)) - return -EBUSY; - ret = ieee80211_if_change_type(sdata, type); if (ret) return ret; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 14123dce544b..6064b7b09e01 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -54,6 +54,20 @@ static inline int drv_add_interface(struct ieee80211_local *local, return ret; } +static inline int drv_change_interface(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type) +{ + int ret; + + might_sleep(); + + trace_drv_change_interface(local, sdata, type); + ret = local->ops->change_interface(&local->hw, &sdata->vif, type); + trace_drv_return_int(local, ret); + return ret; +} + static inline void drv_remove_interface(struct ieee80211_local *local, struct ieee80211_vif *vif) { diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index b5a95582d816..f6f3d89e43fa 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -136,6 +136,31 @@ TRACE_EVENT(drv_add_interface, ) ); +TRACE_EVENT(drv_change_interface, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type), + + TP_ARGS(local, sdata, type), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __field(u32, new_type) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + __entry->new_type = type; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " new type:%d", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type + ) +); + TRACE_EVENT(drv_remove_interface, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f64837788681..d529bd5eab47 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -472,6 +472,16 @@ enum ieee80211_sub_if_data_flags { IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), }; +/** + * enum ieee80211_sdata_state_bits - virtual interface state bits + * @SDATA_STATE_RUNNING: virtual interface is up & running; this + * mirrors netif_running() but is separate for interface type + * change handling while the interface is up + */ +enum ieee80211_sdata_state_bits { + SDATA_STATE_RUNNING, +}; + struct ieee80211_sub_if_data { struct list_head list; @@ -485,6 +495,8 @@ struct ieee80211_sub_if_data { unsigned int flags; + unsigned long state; + int drop_unencrypted; char name[IFNAMSIZ]; @@ -1087,7 +1099,7 @@ void ieee80211_recalc_idle(struct ieee80211_local *local); static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) { - return netif_running(sdata->dev); + return test_bit(SDATA_STATE_RUNNING, &sdata->state); } /* tx handling */ diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index cba3d806d722..c1cc200ac81f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -148,7 +148,12 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, return 0; } -static int ieee80211_open(struct net_device *dev) +/* + * NOTE: Be very careful when changing this function, it must NOT return + * an error on interface type changes that have been pre-checked, so most + * checks should be in ieee80211_check_concurrent_iface. + */ +static int ieee80211_do_open(struct net_device *dev, bool coming_up) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; @@ -157,15 +162,6 @@ static int ieee80211_open(struct net_device *dev) int res; u32 hw_reconf_flags = 0; - /* fail early if user set an invalid address */ - if (!is_zero_ether_addr(dev->dev_addr) && - !is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; - - res = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); - if (res) - return res; - switch (sdata->vif.type) { case NL80211_IFTYPE_WDS: if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) @@ -258,9 +254,11 @@ static int ieee80211_open(struct net_device *dev) netif_carrier_on(dev); break; default: - res = drv_add_interface(local, &sdata->vif); - if (res) - goto err_stop; + if (coming_up) { + res = drv_add_interface(local, &sdata->vif); + if (res) + goto err_stop; + } if (ieee80211_vif_is_mesh(&sdata->vif)) { local->fif_other_bss++; @@ -316,7 +314,9 @@ static int ieee80211_open(struct net_device *dev) hw_reconf_flags |= __ieee80211_recalc_idle(local); mutex_unlock(&local->mtx); - local->open_count++; + if (coming_up) + local->open_count++; + if (hw_reconf_flags) { ieee80211_hw_config(local, hw_reconf_flags); /* @@ -331,6 +331,8 @@ static int ieee80211_open(struct net_device *dev) netif_tx_start_all_queues(dev); + set_bit(SDATA_STATE_RUNNING, &sdata->state); + return 0; err_del_interface: drv_remove_interface(local, &sdata->vif); @@ -344,19 +346,38 @@ static int ieee80211_open(struct net_device *dev) return res; } -static int ieee80211_stop(struct net_device *dev) +static int ieee80211_open(struct net_device *dev) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + int err; + + /* fail early if user set an invalid address */ + if (!is_zero_ether_addr(dev->dev_addr) && + !is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; + + err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); + if (err) + return err; + + return ieee80211_do_open(dev, true); +} + +static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, + bool going_down) +{ struct ieee80211_local *local = sdata->local; unsigned long flags; struct sk_buff *skb, *tmp; u32 hw_reconf_flags = 0; int i; + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + /* * Stop TX on this interface first. */ - netif_tx_stop_all_queues(dev); + netif_tx_stop_all_queues(sdata->dev); /* * Purge work for this interface. @@ -394,11 +415,12 @@ static int ieee80211_stop(struct net_device *dev) if (sdata->vif.type == NL80211_IFTYPE_AP) local->fif_pspoll--; - netif_addr_lock_bh(dev); + netif_addr_lock_bh(sdata->dev); spin_lock_bh(&local->filter_lock); - __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len); + __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, + sdata->dev->addr_len); spin_unlock_bh(&local->filter_lock); - netif_addr_unlock_bh(dev); + netif_addr_unlock_bh(sdata->dev); ieee80211_configure_filter(local); @@ -432,7 +454,8 @@ static int ieee80211_stop(struct net_device *dev) WARN_ON(!list_empty(&sdata->u.ap.vlans)); } - local->open_count--; + if (going_down) + local->open_count--; switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: @@ -504,7 +527,8 @@ static int ieee80211_stop(struct net_device *dev) */ ieee80211_free_keys(sdata); - drv_remove_interface(local, &sdata->vif); + if (going_down) + drv_remove_interface(local, &sdata->vif); } sdata->bss = NULL; @@ -540,6 +564,13 @@ static int ieee80211_stop(struct net_device *dev) } } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); +} + +static int ieee80211_stop(struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + ieee80211_do_stop(sdata, true); return 0; } @@ -857,9 +888,72 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, ieee80211_debugfs_add_netdev(sdata); } +static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type) +{ + struct ieee80211_local *local = sdata->local; + int ret, err; + + ASSERT_RTNL(); + + if (!local->ops->change_interface) + return -EBUSY; + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + /* + * Could maybe also all others here? + * Just not sure how that interacts + * with the RX/config path e.g. for + * mesh. + */ + break; + default: + return -EBUSY; + } + + switch (type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + /* + * Could probably support everything + * but WDS here (WDS do_open can fail + * under memory pressure, which this + * code isn't prepared to handle). + */ + break; + default: + return -EBUSY; + } + + ret = ieee80211_check_concurrent_iface(sdata, type); + if (ret) + return ret; + + ieee80211_do_stop(sdata, false); + + ieee80211_teardown_sdata(sdata->dev); + + ret = drv_change_interface(local, sdata, type); + if (ret) + type = sdata->vif.type; + + ieee80211_setup_sdata(sdata, type); + + err = ieee80211_do_open(sdata->dev, false); + WARN(err, "type change: do_open returned %d", err); + + return ret; +} + int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { + int ret; + ASSERT_RTNL(); if (type == sdata->vif.type) @@ -870,18 +964,15 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, type == NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; - /* - * We could, here, on changes between IBSS/STA/MESH modes, - * invoke an MLME function instead that disassociates etc. - * and goes into the requested mode. - */ - - if (ieee80211_sdata_running(sdata)) - return -EBUSY; - - /* Purge and reset type-dependent state. */ - ieee80211_teardown_sdata(sdata->dev); - ieee80211_setup_sdata(sdata, type); + if (ieee80211_sdata_running(sdata)) { + ret = ieee80211_runtime_change_iftype(sdata, type); + if (ret) + return ret; + } else { + /* Purge and reset type-dependent state. */ + ieee80211_teardown_sdata(sdata->dev); + ieee80211_setup_sdata(sdata, type); + } /* reset some values that shouldn't be kept across type changes */ sdata->vif.bss_conf.basic_rates = -- cgit v1.2.3 From c35d02705e9c2db90a89b29142046b4ffd5a76e5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 12:35:59 +0200 Subject: mac80211_hwsim: support runtime iftype changes Add the trivial support for runtime interface type changes to mac80211_hwsim for testing. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 298ba79fc51b..92b486d46eb9 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -601,6 +601,18 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, } +static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype newtype) +{ + wiphy_debug(hw->wiphy, + "%s (old type=%d, new type=%d, mac_addr=%pM)\n", + __func__, vif->type, newtype, vif->addr); + hwsim_check_magic(vif); + + return 0; +} + static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1027,6 +1039,7 @@ static struct ieee80211_ops mac80211_hwsim_ops = .start = mac80211_hwsim_start, .stop = mac80211_hwsim_stop, .add_interface = mac80211_hwsim_add_interface, + .change_interface = mac80211_hwsim_change_interface, .remove_interface = mac80211_hwsim_remove_interface, .config = mac80211_hwsim_config, .configure_filter = mac80211_hwsim_configure_filter, -- cgit v1.2.3 From 5b714c6a3753dad0798a70a049e15c7f6bc9446b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Aug 2010 13:45:28 +0200 Subject: mac80211: fix offchannel queue stop Somebody noticed this problem, and I outlined to them how to fix it, but haven't heard back from them. So while I was adding the state field I figured I could use it to fix it. The problem, as I understand it, is that when we go offchannel while the driver has a queue stopped, the driver will likely start draining the queue and then enable it while offchannel. This in turn will enable the interface queue, and that leads to transmitting data frames on the wrong channel. Fix this by keeping track of offchannel status per interface, and not enabling the interface queues on interfaces that are offchannel when the driver enables a queue. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/offchannel.c | 19 +++++++++++++++++-- net/mac80211/util.c | 5 ++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d529bd5eab47..9af50fbcd48b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -477,9 +477,12 @@ enum ieee80211_sub_if_data_flags { * @SDATA_STATE_RUNNING: virtual interface is up & running; this * mirrors netif_running() but is separate for interface type * change handling while the interface is up + * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel + * mode, so queues are stopped */ enum ieee80211_sdata_state_bits { SDATA_STATE_RUNNING, + SDATA_STATE_OFFCHANNEL, }; struct ieee80211_sub_if_data { diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c36b1911987a..eeacaa59380a 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -112,8 +112,10 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) * used from user space controlled off-channel operations. */ if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_MONITOR) + sdata->vif.type != NL80211_IFTYPE_MONITOR) { + set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); netif_tx_stop_all_queues(sdata->dev); + } } mutex_unlock(&local->iflist_mtx); } @@ -131,6 +133,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local) continue; if (sdata->vif.type == NL80211_IFTYPE_STATION) { + set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); netif_tx_stop_all_queues(sdata->dev); if (sdata->u.mgd.associated) ieee80211_offchannel_ps_enable(sdata); @@ -155,8 +158,20 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, ieee80211_offchannel_ps_disable(sdata); } - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) + if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { + clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); + /* + * This may wake up queues even though the driver + * currently has them stopped. This is not very + * likely, since the driver won't have gotten any + * (or hardly any) new packets while we weren't + * on the right channel, and even if it happens + * it will at most lead to queueing up one more + * packet per queue in mac80211 rather than on + * the interface qdisc. + */ netif_tx_wake_all_queues(sdata->dev); + } /* re-enable beaconing */ if (enable_beaconing && diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d38b3767e8cc..bd40b11d5ab9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, if (skb_queue_empty(&local->pending[queue])) { rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) + continue; netif_wake_subqueue(sdata->dev, queue); + } rcu_read_unlock(); } else tasklet_schedule(&local->tx_pending_tasklet); -- cgit v1.2.3 From 034de00b06fe2b2c451f7435414f15c1b625e6b0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 26 Aug 2010 22:12:08 +0000 Subject: slip: Use net_device_stats from struct net_device Use net_device->stats for stats instead of private variable copies in struct slip. Use ndo_get_stat64 so the additions can be performed on a private destination buffer. Cc: Eric Dumazet Signed-off-by: Tobias Klauser Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/slip.c | 61 +++++++++++++++++++++++++++--------------------------- drivers/net/slip.h | 9 -------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/drivers/net/slip.c b/drivers/net/slip.c index d5a36f5417cc..38547a8938fe 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -271,7 +271,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) memcpy(sl->xbuff, sl->xhead, sl->xleft); } else { sl->xleft = 0; - sl->tx_dropped++; + dev->stats.tx_dropped++; } } sl->xhead = sl->xbuff; @@ -281,7 +281,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) memcpy(sl->rbuff, rbuff, sl->rcount); } else { sl->rcount = 0; - sl->rx_over_errors++; + dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } @@ -319,6 +319,7 @@ static inline void sl_unlock(struct slip *sl) /* Send one completely decapsulated IP datagram to the IP layer. */ static void sl_bump(struct slip *sl) { + struct net_device *dev = sl->dev; struct sk_buff *skb; int count; @@ -329,13 +330,13 @@ static void sl_bump(struct slip *sl) if (c & SL_TYPE_COMPRESSED_TCP) { /* ignore compressed packets when CSLIP is off */ if (!(sl->mode & SL_MODE_CSLIP)) { - printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name); + printk(KERN_WARNING "%s: compressed packet ignored\n", dev->name); return; } /* make sure we've reserved enough space for uncompress to use */ if (count + 80 > sl->buffsize) { - sl->rx_over_errors++; + dev->stats.rx_over_errors++; return; } count = slhc_uncompress(sl->slcomp, sl->rbuff, count); @@ -346,7 +347,7 @@ static void sl_bump(struct slip *sl) /* turn on header compression */ sl->mode |= SL_MODE_CSLIP; sl->mode &= ~SL_MODE_ADAPTIVE; - printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name); + printk(KERN_INFO "%s: header compression turned on\n", dev->name); } sl->rbuff[0] &= 0x4f; if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) @@ -355,20 +356,20 @@ static void sl_bump(struct slip *sl) } #endif /* SL_INCLUDE_CSLIP */ - sl->rx_bytes += count; + dev->stats.rx_bytes += count; skb = dev_alloc_skb(count); if (skb == NULL) { - printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name); - sl->rx_dropped++; + printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); + dev->stats.rx_dropped++; return; } - skb->dev = sl->dev; + skb->dev = dev; memcpy(skb_put(skb, count), sl->rbuff, count); skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IP); netif_rx(skb); - sl->rx_packets++; + dev->stats.rx_packets++; } /* Encapsulate one IP datagram and stuff into a TTY queue. */ @@ -379,7 +380,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */ printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name); - sl->tx_dropped++; + sl->dev->stats.tx_dropped++; sl_unlock(sl); return; } @@ -433,7 +434,7 @@ static void slip_write_wakeup(struct tty_struct *tty) if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ - sl->tx_packets++; + sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); sl_unlock(sl); return; @@ -496,7 +497,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev) } sl_lock(sl); - sl->tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; sl_encaps(sl, skb->data, skb->len); spin_unlock(&sl->lock); @@ -558,16 +559,16 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu) /* Netdevice get statistics request */ -static struct net_device_stats * -sl_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 * +sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - struct net_device_stats *stats = &dev->stats; - struct slip *sl = netdev_priv(dev); + struct net_device_stats *devstats = &dev->stats; unsigned long c_rx_dropped = 0; #ifdef SL_INCLUDE_CSLIP unsigned long c_rx_fifo_errors = 0; unsigned long c_tx_fifo_errors = 0; unsigned long c_collisions = 0; + struct slip *sl = netdev_priv(dev); struct slcompress *comp = sl->slcomp; if (comp) { @@ -580,16 +581,16 @@ sl_get_stats(struct net_device *dev) stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors; stats->collisions = sl->tx_misses + c_collisions; #endif + stats->rx_packets = devstats->rx_packets; + stats->tx_packets = devstats->tx_packets; + stats->rx_bytes = devstats->rx_bytes; + stats->tx_bytes = devstats->tx_bytes; + stats->rx_dropped = devstats->rx_dropped + c_rx_dropped; + stats->tx_dropped = devstats->tx_dropped; + stats->tx_errors = devstats->tx_errors; + stats->rx_errors = devstats->rx_errors; + stats->rx_over_errors = devstats->rx_over_errors; - stats->rx_packets = sl->rx_packets; - stats->tx_packets = sl->tx_packets; - stats->rx_bytes = sl->rx_bytes; - stats->tx_bytes = sl->tx_bytes; - stats->rx_dropped = sl->rx_dropped + c_rx_dropped; - stats->tx_dropped = sl->tx_dropped; - stats->tx_errors = sl->tx_errors; - stats->rx_errors = sl->rx_errors; - stats->rx_over_errors = sl->rx_over_errors; return stats; } @@ -633,7 +634,7 @@ static const struct net_device_ops sl_netdev_ops = { .ndo_open = sl_open, .ndo_stop = sl_close, .ndo_start_xmit = sl_xmit, - .ndo_get_stats = sl_get_stats, + .ndo_get_stats64 = sl_get_stats64, .ndo_change_mtu = sl_change_mtu, .ndo_tx_timeout = sl_tx_timeout, #ifdef CONFIG_SLIP_SMART @@ -681,7 +682,7 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, while (count--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) - sl->rx_errors++; + sl->dev->stats.rx_errors++; cp++; continue; } @@ -981,7 +982,7 @@ static void slip_unesc(struct slip *sl, unsigned char s) sl->rbuff[sl->rcount++] = s; return; } - sl->rx_over_errors++; + sl->dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } @@ -1057,7 +1058,7 @@ static void slip_unesc6(struct slip *sl, unsigned char s) sl->rbuff[sl->rcount++] = c; return; } - sl->rx_over_errors++; + sl->dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } diff --git a/drivers/net/slip.h b/drivers/net/slip.h index 9ea5c11287d2..914e958abbfc 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -67,15 +67,6 @@ struct slip { int xleft; /* bytes left in XMIT queue */ /* SLIP interface statistics. */ - unsigned long rx_packets; /* inbound frames counter */ - unsigned long tx_packets; /* outbound frames counter */ - unsigned long rx_bytes; /* inbound byte counte */ - unsigned long tx_bytes; /* outbound byte counter */ - unsigned long rx_errors; /* Parity, etc. errors */ - unsigned long tx_errors; /* Planned stuff */ - unsigned long rx_dropped; /* No memory for skb */ - unsigned long tx_dropped; /* When MTU change */ - unsigned long rx_over_errors; /* Frame bigger than SLIP buf. */ #ifdef SL_INCLUDE_CSLIP unsigned long tx_compressed; unsigned long rx_compressed; -- cgit v1.2.3 From 762c29164e2850d8c5e4c258cef0077b2584d111 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Aug 2010 16:41:56 +0000 Subject: econet: kill unnecessary spin_lock_init() The spinlock aun_queue_lock is initialized statically. It is unnecessary to initialize by spin_lock_init() at module load time. This is detected by the semantic patch. // @def@ declarer name DEFINE_SPINLOCK; identifier spinlock; @@ DEFINE_SPINLOCK(spinlock); @@ identifier def.spinlock; @@ - spin_lock_init(&spinlock); // Signed-off-by: Akinobu Mita Cc: Julia Lawall Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- net/econet/af_econet.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index dc54bd0d083b..baa98fb83552 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -1009,7 +1009,6 @@ static int __init aun_udp_initialise(void) struct sockaddr_in sin; skb_queue_head_init(&aun_queue); - spin_lock_init(&aun_queue_lock); setup_timer(&ab_cleanup_timer, ab_cleanup, 0); ab_cleanup_timer.expires = jiffies + (HZ*2); add_timer(&ab_cleanup_timer); @@ -1167,7 +1166,6 @@ static int __init econet_proto_init(void) goto out; sock_register(&econet_family_ops); #ifdef CONFIG_ECONET_AUNUDP - spin_lock_init(&aun_queue_lock); aun_udp_initialise(); #endif #ifdef CONFIG_ECONET_NATIVE -- cgit v1.2.3 From e27cd4f8ca9dde7938f4f83ef75b6fae8d46dd5f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Aug 2010 19:08:13 +0000 Subject: mlx4: use bitmap library Replace loops calling set_bit() and clear_bit() with bitmap_set() and bitmap_clear(). Unlike loops calling set_bit() and clear_bit(), bitmap_set() and bitmap_clear() are not atomic. But this is ok. Because the bitmap operations are protected by bitmap->lock except for initialization of the bitmap in mlx4_bitmap_init(). Signed-off-by: Akinobu Mita Cc: Roland Dreier Cc: netdev@vger.kernel.org Cc: "David S. Miller" Signed-off-by: David S. Miller --- drivers/net/mlx4/alloc.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 537997f9443e..8f4bf1f07c11 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c @@ -74,7 +74,7 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj) u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) { - u32 obj, i; + u32 obj; if (likely(cnt == 1 && align == 1)) return mlx4_bitmap_alloc(bitmap); @@ -91,8 +91,7 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) } if (obj < bitmap->max) { - for (i = 0; i < cnt; i++) - set_bit(obj + i, bitmap->table); + bitmap_set(bitmap->table, obj, cnt); if (obj == bitmap->last) { bitmap->last = (obj + cnt); if (bitmap->last >= bitmap->max) @@ -109,13 +108,10 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) { - u32 i; - obj &= bitmap->max + bitmap->reserved_top - 1; spin_lock(&bitmap->lock); - for (i = 0; i < cnt; i++) - clear_bit(obj + i, bitmap->table); + bitmap_clear(bitmap->table, obj, cnt); bitmap->last = min(bitmap->last, obj); bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) & bitmap->mask; @@ -125,8 +121,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved_bot, u32 reserved_top) { - int i; - /* num must be a power of 2 */ if (num != roundup_pow_of_two(num)) return -EINVAL; @@ -142,8 +136,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, if (!bitmap->table) return -ENOMEM; - for (i = 0; i < reserved_bot; ++i) - set_bit(i, bitmap->table); + bitmap_set(bitmap->table, 0, reserved_bot); return 0; } -- cgit v1.2.3 From 6a499b242f7d1ebf13f5bc386e08e80603f79e2a Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Aug 2010 19:08:26 +0000 Subject: phonet: use for_each_set_bit Replace open-coded loop with for_each_set_bit(). Signed-off-by: Akinobu Mita Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- net/phonet/pn_dev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index b18e48fae975..d0a429459370 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -292,8 +292,7 @@ static void phonet_route_autodel(struct net_device *dev) if (bitmap_empty(deleted, 64)) return; /* short-circuit RCU */ synchronize_rcu(); - for (i = find_first_bit(deleted, 64); i < 64; - i = find_next_bit(deleted, 64, i + 1)) { + for_each_set_bit(i, deleted, 64) { rtm_phonet_notify(RTM_DELROUTE, dev, i); dev_put(dev); } -- cgit v1.2.3 From d08336e9998b1004b2baad62325d34349a593137 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Aug 2010 19:08:36 +0000 Subject: starfire: use PCI_VDEVICE Signed-off-by: Akinobu Mita Cc: Ion Badulescu Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/starfire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index a42b6873370b..26c363462856 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -302,7 +302,7 @@ enum chipset { }; static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = { - { 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 }, + { PCI_VDEVICE(ADAPTEC, 0x6915), CH_6915 }, { 0, } }; MODULE_DEVICE_TABLE(pci, starfire_pci_tbl); -- cgit v1.2.3 From 56543af9563d91c1c5596a7980b416389bdea071 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Aug 2010 19:08:45 +0000 Subject: starfire: use BUILD_BUG_ON for netdrv_addr_t Detect size mismatch for netdrv_addr_t at build time rather than checking at module load time. Signed-off-by: Akinobu Mita Cc: Ion Badulescu Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/starfire.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 26c363462856..c3bf288aaf25 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -2078,11 +2078,7 @@ static int __init starfire_init (void) printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n"); #endif - /* we can do this test only at run-time... sigh */ - if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) { - printk("This driver has dma_addr_t issues, please send email to maintainer\n"); - return -ENODEV; - } + BUILD_BUG_ON(sizeof(dma_addr_t) != sizeof(netdrv_addr_t)); return pci_register_driver(&starfire_driver); } -- cgit v1.2.3 From 2bc9e234658072145b63d1d364bac4c8e337c865 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Aug 2010 05:41:02 +0000 Subject: drivers/net/atl1c: Remove double test The nic_type field is compared to athr_l2c twice. The sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @expression@ expression E; @@ ( * E || ... || E | * E && ... && E ) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index d8501f060957..919080b2c3a5 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c @@ -480,7 +480,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw) atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D); } if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2 - || hw->nic_type == athr_l2c || hw->nic_type == athr_l2c) { + || hw->nic_type == athr_l2c) { atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD); } -- cgit v1.2.3 From 2c70b5196262f29b10eb1886293e0c2d75dc3dd9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Sun, 29 Aug 2010 17:04:53 +0000 Subject: IPVS: include net/ip6_checksum.h for csum_ipv6_magic Fixes this build error: net/netfilter/ipvs/ip_vs_core.c: In function 'ip_vs_nat_icmp_v6': net/netfilter/ipvs/ip_vs_core.c:640: error: implicit declaration of function 'csum_ipv6_magic' Signed-off-by: Stephen Rothwell Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 69661db420d7..edbfb96b935e 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -40,6 +40,7 @@ #include #include /* for icmp_send */ #include +#include #include #include -- cgit v1.2.3 From 409456b10f87b28303643fec37543103f9ada00c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 29 Aug 2010 21:57:55 -0700 Subject: net: fix datapath typo Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- include/linux/if.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/if.h b/include/linux/if.h index 6ed43c1f07ab..123959927745 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -76,7 +76,7 @@ #define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */ #define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */ #define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch - * dapath port */ + * datapath port */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 -- cgit v1.2.3 From dca43c75e7e545694a9dd6288553f55c53e2a3a3 Mon Sep 17 00:00:00 2001 From: Jerry Chu Date: Fri, 27 Aug 2010 19:13:28 +0000 Subject: tcp: Add TCP_USER_TIMEOUT socket option. This patch provides a "user timeout" support as described in RFC793. The socket option is also needed for the the local half of RFC5482 "TCP User Timeout Option". TCP_USER_TIMEOUT is a TCP level socket option that takes an unsigned int, when > 0, to specify the maximum amount of time in ms that transmitted data may remain unacknowledged before TCP will forcefully close the corresponding connection and return ETIMEDOUT to the application. If 0 is given, TCP will continue to use the system default. Increasing the user timeouts allows a TCP connection to survive extended periods without end-to-end connectivity. Decreasing the user timeouts allows applications to "fail fast" if so desired. Otherwise it may take upto 20 minutes with the current system defaults in a normal WAN environment. The socket option can be made during any state of a TCP connection, but is only effective during the synchronized states of a connection (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, or LAST-ACK). Moreover, when used with the TCP keepalive (SO_KEEPALIVE) option, TCP_USER_TIMEOUT will overtake keepalive to determine when to close a connection due to keepalive failure. The option does not change in anyway when TCP retransmits a packet, nor when a keepalive probe will be sent. This option, like many others, will be inherited by an acceptor from its listener. Signed-off-by: H.K. Jerry Chu Signed-off-by: David S. Miller --- include/linux/tcp.h | 1 + include/net/inet_connection_sock.h | 1 + net/ipv4/tcp.c | 11 ++++++++++- net/ipv4/tcp_timer.c | 40 ++++++++++++++++++++++++-------------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index a778ee024590..e64f4c67d0ef 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -105,6 +105,7 @@ enum { #define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ #define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ #define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ +#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ /* for TCP_INFO socket option */ #define TCPI_OPT_TIMESTAMPS 1 diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b6d3b55da19b..e4f494b42e06 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -125,6 +125,7 @@ struct inet_connection_sock { int probe_size; } icsk_mtup; u32 icsk_ca_priv[16]; + u32 icsk_user_timeout; #define ICSK_CA_PRIV_SIZE (16 * sizeof(u32)) }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 176e11aaea77..cf3254528753 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2391,7 +2391,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level, err = tp->af_specific->md5_parse(sk, optval, optlen); break; #endif - + case TCP_USER_TIMEOUT: + /* Cap the max timeout in ms TCP will retry/retrans + * before giving up and aborting (ETIMEDOUT) a connection. + */ + icsk->icsk_user_timeout = msecs_to_jiffies(val); + break; default: err = -ENOPROTOOPT; break; @@ -2610,6 +2615,10 @@ static int do_tcp_getsockopt(struct sock *sk, int level, case TCP_THIN_DUPACK: val = tp->thin_dupack; break; + + case TCP_USER_TIMEOUT: + val = jiffies_to_msecs(icsk->icsk_user_timeout); + break; default: return -ENOPROTOOPT; } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 808bb920c9f5..11569deccbea 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -138,10 +138,10 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) * retransmissions with an initial RTO of TCP_RTO_MIN. */ static bool retransmits_timed_out(struct sock *sk, - unsigned int boundary) + unsigned int boundary, + unsigned int timeout) { - unsigned int timeout, linear_backoff_thresh; - unsigned int start_ts; + unsigned int linear_backoff_thresh, start_ts; if (!inet_csk(sk)->icsk_retransmits) return false; @@ -151,14 +151,15 @@ static bool retransmits_timed_out(struct sock *sk, else start_ts = tcp_sk(sk)->retrans_stamp; - linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); - - if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; - else - timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + - (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + if (likely(timeout == 0)) { + linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); + if (boundary <= linear_backoff_thresh) + timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; + else + timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + } return (tcp_time_stamp - start_ts) >= timeout; } @@ -174,7 +175,7 @@ static int tcp_write_timeout(struct sock *sk) dst_negative_advice(sk); retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; } else { - if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { + if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { /* Black hole detection */ tcp_mtu_probing(icsk, sk); @@ -187,14 +188,16 @@ static int tcp_write_timeout(struct sock *sk) retry_until = tcp_orphan_retries(sk, alive); do_reset = alive || - !retransmits_timed_out(sk, retry_until); + !retransmits_timed_out(sk, retry_until, 0); if (tcp_out_of_resources(sk, do_reset)) return 1; } } - if (retransmits_timed_out(sk, retry_until)) { + if (retransmits_timed_out(sk, retry_until, + (1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) ? 0 : + icsk->icsk_user_timeout)) { /* Has it gone just too far? */ tcp_write_err(sk); return 1; @@ -436,7 +439,7 @@ out_reset_timer: icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); } inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); - if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) + if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) __sk_dst_reset(sk); out:; @@ -556,7 +559,14 @@ static void tcp_keepalive_timer (unsigned long data) elapsed = keepalive_time_elapsed(tp); if (elapsed >= keepalive_time_when(tp)) { - if (icsk->icsk_probes_out >= keepalive_probes(tp)) { + /* If the TCP_USER_TIMEOUT option is enabled, use that + * to determine when to timeout instead. + */ + if ((icsk->icsk_user_timeout != 0 && + elapsed >= icsk->icsk_user_timeout && + icsk->icsk_probes_out > 0) || + (icsk->icsk_user_timeout == 0 && + icsk->icsk_probes_out >= keepalive_probes(tp))) { tcp_send_active_reset(sk, GFP_ATOMIC); tcp_write_err(sk); goto out; -- cgit v1.2.3 From d82b6f85c1d73340ef4a26bd0b247ac14610cd83 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:23:10 +0000 Subject: dccp ccid-2: Use u32 timestamps uniformly Since CCID-2 is de facto a mini implementation of TCP, it makes sense to share as much code as possible. Hence this patch aligns CCID-2 timestamping with TCP timestamping. This also halves the space consumption (on 64-bit systems). The necessary include file is already included by way of net/dccp.h. Redundant includes have been removed. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 14 ++++++-------- net/dccp/ccids/ccid2.h | 15 ++++++++++----- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 7af3106c1f94..0cff637a4a51 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -25,8 +25,6 @@ */ #include #include "../feat.h" -#include "../ccid.h" -#include "../dccp.h" #include "ccid2.h" @@ -175,7 +173,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) hc->tx_seqh->ccid2s_seq = dp->dccps_gss; hc->tx_seqh->ccid2s_acked = 0; - hc->tx_seqh->ccid2s_sent = jiffies; + hc->tx_seqh->ccid2s_sent = ccid2_time_stamp; next = hc->tx_seqh->ccid2s_next; /* check if we need to alloc more space */ @@ -250,7 +248,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) struct ccid2_seq *seqp = hc->tx_seqt; while (seqp != hc->tx_seqh) { - ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", + ccid2_pr_debug("out seq=%llu acked=%d time=%u\n", (unsigned long long)seqp->ccid2s_seq, seqp->ccid2s_acked, seqp->ccid2s_sent); seqp = seqp->ccid2s_next; @@ -431,19 +429,19 @@ static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp, * The cleanest solution is to not use the ccid2s_sent field at all * and instead use DCCP timestamps: requires changes in other places. */ - ccid2_rtt_estimator(sk, jiffies - seqp->ccid2s_sent); + ccid2_rtt_estimator(sk, ccid2_time_stamp - seqp->ccid2s_sent); } static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - if (time_before(seqp->ccid2s_sent, hc->tx_last_cong)) { + if ((s32)(seqp->ccid2s_sent - hc->tx_last_cong) < 0) { ccid2_pr_debug("Multiple losses in an RTT---treating as one\n"); return; } - hc->tx_last_cong = jiffies; + hc->tx_last_cong = ccid2_time_stamp; hc->tx_cwnd = hc->tx_cwnd / 2 ? : 1U; hc->tx_ssthresh = max(hc->tx_cwnd, 2U); @@ -683,7 +681,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_rto = DCCP_TIMEOUT_INIT; hc->tx_rpdupack = -1; - hc->tx_last_cong = jiffies; + hc->tx_last_cong = ccid2_time_stamp; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk); return 0; diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index b017843ba44d..9731c2dc1487 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -18,18 +18,23 @@ #ifndef _DCCP_CCID2_H_ #define _DCCP_CCID2_H_ -#include #include #include #include "../ccid.h" +#include "../dccp.h" + +/* + * CCID-2 timestamping faces the same issues as TCP timestamping. + * Hence we reuse/share as much of the code as possible. + */ +#define ccid2_time_stamp tcp_time_stamp + /* NUMDUPACK parameter from RFC 4341, p. 6 */ #define NUMDUPACK 3 -struct sock; - struct ccid2_seq { u64 ccid2s_seq; - unsigned long ccid2s_sent; + u32 ccid2s_sent; int ccid2s_acked; struct ccid2_seq *ccid2s_prev; struct ccid2_seq *ccid2s_next; @@ -72,7 +77,7 @@ struct ccid2_hc_tx_sock { u64 tx_rpseq; int tx_rpdupack; - unsigned long tx_last_cong; + u32 tx_last_cong; u64 tx_high_ack; }; -- cgit v1.2.3 From d26eeb07fd02de31848b59d19687daff0e93532f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:23:11 +0000 Subject: dccp ccid-2: Remove wrappers around sk_{reset,stop}_timer() This removes the wrappers around the sk timer functions, since not much is gained from using them: the BUG_ON in start_rto_timer will never trigger since that function is called only if: * the RTO timer expires (rto_expire, and then timer_pending() is false); * in tx_packet_sent only if !timer_pending() (BUG_ON is redundant here); * previously in new_ack, after stopping the timer (timer_pending() false). Removing the wrappers also clears the way for eventually replacing the RTO timer with the icsk-retransmission-timer, as it is already part of the DCCP socket. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/dccp/ccids/ccid2.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 0cff637a4a51..8c95813bcc67 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -111,8 +111,6 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) dp->dccps_l_ack_ratio = val; } -static void ccid2_start_rto_timer(struct sock *sk); - static void ccid2_hc_tx_rto_expire(unsigned long data) { struct sock *sk = (struct sock *)data; @@ -131,7 +129,7 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) if (hc->tx_rto > DCCP_RTO_MAX) hc->tx_rto = DCCP_RTO_MAX; - ccid2_start_rto_timer(sk); + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); /* adjust pipe, cwnd etc */ hc->tx_ssthresh = hc->tx_cwnd / 2; @@ -153,16 +151,6 @@ out: sock_put(sk); } -static void ccid2_start_rto_timer(struct sock *sk) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - ccid2_pr_debug("setting RTO timeout=%u\n", hc->tx_rto); - - BUG_ON(timer_pending(&hc->tx_rtotimer)); - sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); -} - static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) { struct dccp_sock *dp = dccp_sk(sk); @@ -239,9 +227,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) } #endif - /* setup RTO timer */ - if (!timer_pending(&hc->tx_rtotimer)) - ccid2_start_rto_timer(sk); + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); #ifdef CONFIG_IP_DCCP_CCID2_DEBUG do { @@ -320,14 +306,6 @@ out_invalid_option: return -1; } -static void ccid2_hc_tx_kill_rto_timer(struct sock *sk) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - sk_stop_timer(sk, &hc->tx_rtotimer); - ccid2_pr_debug("deleted RTO timer\n"); -} - /** * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm * This code is almost identical with TCP's tcp_rtt_estimator(), since @@ -692,7 +670,7 @@ static void ccid2_hc_tx_exit(struct sock *sk) struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); int i; - ccid2_hc_tx_kill_rto_timer(sk); + sk_stop_timer(sk, &hc->tx_rtotimer); for (i = 0; i < hc->tx_seqbufc; i++) kfree(hc->tx_seqbuf[i]); -- cgit v1.2.3 From 22b71c8f4f3db8df92f5e7b081c265bc56c0bd2f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:23:12 +0000 Subject: tcp/dccp: Consolidate common code for RFC 3390 conversion This patch consolidates initial-window code common to TCP and CCID-2: * TCP uses RFC 3390 in a packet-oriented manner (tcp_input.c) and * CCID-2 uses RFC 3390 in packet-oriented manner (RFC 4341). Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- include/net/tcp.h | 15 +++++++++++++++ net/dccp/ccids/ccid2.c | 8 ++------ net/ipv4/tcp_input.c | 17 ++--------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index df6a2eb20193..a64022199b62 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -779,6 +779,21 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk) /* Use define here intentionally to get WARN_ON location shown at the caller */ #define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out) +/* + * Convert RFC 3390 larger initial window into an equivalent number of packets. + * + * John Heffner states: + * + * The RFC specifies a window of no more than 4380 bytes + * unless 2*MSS > 4380. Reading the pseudocode in the RFC + * is a bit misleading because they use a clamp at 4380 bytes + * rather than a multiplier in the relevant range. + */ +static inline u32 rfc3390_bytes_to_packets(const u32 smss) +{ + return smss <= 1095 ? 4 : (smss > 1460 ? 2 : 3); +} + extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh); extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst); diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 8c95813bcc67..b9c942a09c98 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -641,12 +641,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) /* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */ hc->tx_ssthresh = ~0U; - /* - * RFC 4341, 5: "The cwnd parameter is initialized to at most four - * packets for new connections, following the rules from [RFC3390]". - * We need to convert the bytes of RFC3390 into the packets of RFC 4341. - */ - hc->tx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U); + /* Use larger initial windows (RFC 4341, section 5). */ + hc->tx_cwnd = rfc3390_bytes_to_packets(dp->dccps_mss_cache); /* Make sure that Ack Ratio is enabled and within bounds. */ max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e663b78a2ef6..1bc87a05c734 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -805,25 +805,12 @@ void tcp_update_metrics(struct sock *sk) } } -/* Numbers are taken from RFC3390. - * - * John Heffner states: - * - * The RFC specifies a window of no more than 4380 bytes - * unless 2*MSS > 4380. Reading the pseudocode in the RFC - * is a bit misleading because they use a clamp at 4380 bytes - * rather than use a multiplier in the relevant range. - */ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) { __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); - if (!cwnd) { - if (tp->mss_cache > 1460) - cwnd = 2; - else - cwnd = (tp->mss_cache > 1095) ? 3 : 4; - } + if (!cwnd) + cwnd = rfc3390_bytes_to_packets(tp->mss_cache); return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } -- cgit v1.2.3 From 4886fcad6e12572afbd230dfab1b268eace20d6d Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:23:13 +0000 Subject: dccp ccid-2: Share TCP's minimum RTO code Using a fixed RTO_MIN of 0.2 seconds was found to cause problems for CCID-2 over 802.11g: at least once per session there was a spurious timeout. It helped to then increase the the value of RTO_MIN over this link. Since the problem is the same as in TCP, this patch makes the solution from commit "05bb1fad1cde025a864a90cfeb98dcbefe78a44a" "[TCP]: Allow minimum RTO to be configurable via routing metrics." available to DCCP. This avoids reinventing the wheel, so that e.g. the following works in the expected way now also for CCID-2: > ip route change 10.0.0.2 rto_min 800 dev ath0 Luckily this useful rto_min function was recently moved to net/tcp.h, which simplifies sharing code originating from TCP. Documentation also updated (plus minor whitespace fixes). Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- Documentation/networking/dccp.txt | 26 ++++++++++++++++++++------ net/dccp/ccids/ccid2.c | 5 +++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index a62fdf7a6bff..cdb64922ba10 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -1,18 +1,20 @@ DCCP protocol -============ +============= Contents ======== - - Introduction - Missing features - Socket options +- Sysctl variables +- IOCTLs +- Other tunables - Notes + Introduction ============ - Datagram Congestion Control Protocol (DCCP) is an unreliable, connection oriented protocol designed to solve issues present in UDP and TCP, particularly for real-time and multimedia (streaming) traffic. @@ -29,9 +31,9 @@ It has a base protocol and pluggable congestion control IDs (CCIDs). DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol is at http://www.ietf.org/html.charters/dccp-charter.html + Missing features ================ - The Linux DCCP implementation does not currently support all the features that are specified in RFCs 4340...42. @@ -45,7 +47,6 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree Socket options ============== - DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of service codes (RFC 4340, sec. 8.1.2); if this socket option is not set, the socket will fall back to 0 (which means that no meaningful service code @@ -112,6 +113,7 @@ DCCP_SOCKOPT_CCID_TX_INFO On unidirectional connections it is useful to close the unused half-connection via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs. + Sysctl variables ================ Several DCCP default parameters can be managed by the following sysctls @@ -155,15 +157,27 @@ sync_ratelimit = 125 ms sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit of this parameter is milliseconds; a value of 0 disables rate-limiting. + IOCTLS ====== FIONREAD Works as in udp(7): returns in the `int' argument pointer the size of the next pending datagram in bytes, or 0 when no datagram is pending. + +Other tunables +============== +Per-route rto_min support + CCID-2 supports the RTAX_RTO_MIN per-route setting for the minimum value + of the RTO timer. This setting can be modified via the 'rto_min' option + of iproute2; for example: + > ip route change 10.0.0.0/24 rto_min 250j dev wlan0 + > ip route add 10.0.0.254/32 rto_min 800j dev wlan0 + > ip route show dev wlan0 + + Notes ===== - DCCP does not travel through NAT successfully at present on many boxes. This is because the checksum covers the pseudo-header as per TCP and UDP. Linux NAT support for DCCP has been added. diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index b9c942a09c98..dc18172b1e59 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -325,8 +325,9 @@ static void ccid2_rtt_estimator(struct sock *sk, const long mrtt) hc->tx_srtt = m << 3; hc->tx_mdev = m << 1; - hc->tx_mdev_max = max(TCP_RTO_MIN, hc->tx_mdev); + hc->tx_mdev_max = max(hc->tx_mdev, tcp_rto_min(sk)); hc->tx_rttvar = hc->tx_mdev_max; + hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; } else { /* Update scaled SRTT as SRTT += 1/8 * (m - SRTT) */ @@ -367,7 +368,7 @@ static void ccid2_rtt_estimator(struct sock *sk, const long mrtt) hc->tx_rttvar -= (hc->tx_rttvar - hc->tx_mdev_max) >> 2; hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; - hc->tx_mdev_max = TCP_RTO_MIN; + hc->tx_mdev_max = tcp_rto_min(sk); } } -- cgit v1.2.3 From 89858ad14307a398961a0f1414b04053c1475e4f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:23:14 +0000 Subject: dccp ccid-3: use per-route RTO or TCP RTO as fallback This makes RTAX_RTO_MIN also available to CCID-3, replacing the compile-time RTO lower bound with a per-route tunable value. The original Kconfig option solved the problem that a very low RTT (in the order of HZ) can trigger too frequent and unnecessary reductions of the sending rate. This tunable does not affect the initial RTO value of 2 seconds specified in RFC 5348, section 4.2 and Appendix B. But like the hardcoded Kconfig value, it allows to adapt to network conditions. The same effect as the original Kconfig option of 100ms is now achieved by > ip route replace to unicast 192.168.0.0/24 rto_min 100j dev eth0 (assuming HZ=1000). Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- Documentation/networking/dccp.txt | 3 +++ net/dccp/ccids/Kconfig | 31 ------------------------------- net/dccp/ccids/ccid3.c | 11 +++++------ net/dccp/ccids/ccid3.h | 2 +- 4 files changed, 9 insertions(+), 38 deletions(-) diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index cdb64922ba10..271d524a4c8d 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -174,6 +174,9 @@ Per-route rto_min support > ip route change 10.0.0.0/24 rto_min 250j dev wlan0 > ip route add 10.0.0.254/32 rto_min 800j dev wlan0 > ip route show dev wlan0 + CCID-3 also supports the rto_min setting: it is used to define the lower + bound for the expiry of the nofeedback timer. This can be useful on LANs + with very low RTTs (e.g., loopback, Gbit ethernet). Notes diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig index 8408398cd44e..0581143cb800 100644 --- a/net/dccp/ccids/Kconfig +++ b/net/dccp/ccids/Kconfig @@ -47,37 +47,6 @@ config IP_DCCP_CCID3_DEBUG If in doubt, say N. -config IP_DCCP_CCID3_RTO - int "Use higher bound for nofeedback timer" - default 100 - depends on IP_DCCP_CCID3 && EXPERIMENTAL - ---help--- - Use higher lower bound for nofeedback timer expiration. - - The TFRC nofeedback timer normally expires after the maximum of 4 - RTTs and twice the current send interval (RFC 3448, 4.3). On LANs - with a small RTT this can mean a high processing load and reduced - performance, since then the nofeedback timer is triggered very - frequently. - - This option enables to set a higher lower bound for the nofeedback - value. Values in units of milliseconds can be set here. - - A value of 0 disables this feature by enforcing the value specified - in RFC 3448. The following values have been suggested as bounds for - experimental use: - * 16-20ms to match the typical multimedia inter-frame interval - * 100ms as a reasonable compromise [default] - * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4) - - The default of 100ms is a compromise between a large value for - efficient DCCP implementations, and a small value to avoid disrupting - the network in times of congestion. - - The purpose of the nofeedback timer is to slow DCCP down when there - is serious network congestion: experimenting with larger values should - therefore not be performed on WANs. - config IP_DCCP_TFRC_LIB def_bool y if IP_DCCP_CCID3 diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 4340672a817c..278e17069322 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -460,13 +460,12 @@ done_computing_x: sk->sk_write_space(sk); /* - * Update timeout interval for the nofeedback timer. - * We use a configuration option to increase the lower bound. - * This can help avoid triggering the nofeedback timer too - * often ('spinning') on LANs with small RTTs. + * Update timeout interval for the nofeedback timer. In order to control + * rate halving on networks with very low RTTs (<= 1 ms), use per-route + * tunable RTAX_RTO_MIN value as the lower bound. */ - hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, (CONFIG_IP_DCCP_CCID3_RTO * - (USEC_PER_SEC / 1000))); + hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, + USEC_PER_SEC/HZ * tcp_rto_min(sk)); /* * Schedule no feedback timer to expire in * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi) diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index b1864243be07..b7e569c22f36 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -42,7 +42,7 @@ #include "lib/tfrc.h" #include "../ccid.h" -/* Two seconds as per RFC 3448 4.2 */ +/* Two seconds as per RFC 5348, 4.2 */ #define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) /* In usecs - half the scheduling granularity as per RFC3448 4.6 */ -- cgit v1.2.3 From 3d5b99ae82f8742e3bb1f8634fd11ac36ea19ee1 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 29 Aug 2010 19:27:34 +0000 Subject: TCP: update initial windows according to RFC 5681 This updates the use of larger initial windows, as originally specified in RFC 3390, to use the newer IW values specified in RFC 5681, section 3.1. The changes made in RFC 5681 are: a) the setting now is more clearly specified in units of segments (as the comments by John Heffner emphasized, this was not very clear in RFC 3390); b) for connections with 1095 < SMSS <= 2190 there is now a change: - RFC 3390 says that IW <= 4380, - RFC 5681 says that IW = 3 * SMSS <= 6570. Since RFC 3390 is older and "only" proposed standard, whereas the newer RFC 5681 is already draft standard, it seems preferable to use the newer IW variant. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- include/net/tcp.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index a64022199b62..11dbacc886c0 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -781,17 +781,11 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk) /* * Convert RFC 3390 larger initial window into an equivalent number of packets. - * - * John Heffner states: - * - * The RFC specifies a window of no more than 4380 bytes - * unless 2*MSS > 4380. Reading the pseudocode in the RFC - * is a bit misleading because they use a clamp at 4380 bytes - * rather than a multiplier in the relevant range. + * This is based on the numbers specified in RFC 5681, 3.1. */ static inline u32 rfc3390_bytes_to_packets(const u32 smss) { - return smss <= 1095 ? 4 : (smss > 1460 ? 2 : 3); + return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3); } extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh); -- cgit v1.2.3 From c274f29120eff7852bb2370ae6f05f46de75edbc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 29 Aug 2010 21:43:46 +0000 Subject: net/m68k: Hydra Ethernet - print whole resource instead of start address resource_size_t changed from `unsigned long' to `phys_addr_t`, which is either `u32' or `u64'. Print the whole resource to remove the cast and to make it future-proof. Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/hydra.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 376e953c6ce6..c5ef62ceb840 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -173,9 +173,8 @@ static int __devinit hydra_init(struct zorro_dev *z) zorro_set_drvdata(z, dev); - printk(KERN_INFO "%s: Hydra at 0x%08llx, address " - "%pM (hydra.c " HYDRA_VERSION ")\n", - dev->name, (unsigned long long)z->resource.start, dev->dev_addr); + pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n", + dev->name, &z->resource, dev->dev_addr); return 0; } -- cgit v1.2.3 From 6dcd814bd08bc7989f7f3eac9bbe8b20aec0182a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 30 Aug 2010 07:04:14 +0000 Subject: net: struct xfrm_tunnel in read_mostly section tunnel4_handlers chain being scanned for each incoming packet, make sure it doesnt share an often dirtied cache line. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 2 +- net/ipv4/tunnel4.c | 4 ++-- net/ipv4/xfrm4_tunnel.c | 4 ++-- net/ipv6/sit.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index ec036731a70b..3c6f8f3968a6 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -744,7 +744,7 @@ static void __net_init ipip_fb_tunnel_init(struct net_device *dev) ipn->tunnels_wc[0] = tunnel; } -static struct xfrm_tunnel ipip_handler = { +static struct xfrm_tunnel ipip_handler __read_mostly = { .handler = ipip_rcv, .err_handler = ipip_err, .priority = 1, diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 59186ca7808a..942f02da07d8 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -14,8 +14,8 @@ #include #include -static struct xfrm_tunnel *tunnel4_handlers; -static struct xfrm_tunnel *tunnel64_handlers; +static struct xfrm_tunnel *tunnel4_handlers __read_mostly; +static struct xfrm_tunnel *tunnel64_handlers __read_mostly; static DEFINE_MUTEX(tunnel4_mutex); static inline struct xfrm_tunnel **fam_handlers(unsigned short family) diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 41f5982d2087..82806455e859 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -58,14 +58,14 @@ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) return -ENOENT; } -static struct xfrm_tunnel xfrm_tunnel_handler = { +static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = { .handler = xfrm_tunnel_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, }; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -static struct xfrm_tunnel xfrm64_tunnel_handler = { +static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = { .handler = xfrm_tunnel_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 4699cd3c3118..86618eb30335 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1132,7 +1132,7 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) sitn->tunnels_wc[0] = tunnel; } -static struct xfrm_tunnel sit_handler = { +static struct xfrm_tunnel sit_handler __read_mostly = { .handler = ipip6_rcv, .err_handler = ipip6_err, .priority = 1, -- cgit v1.2.3 From 3ff2cfa55fb35bb5ea4490fbc82bb3c6771c121b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 30 Aug 2010 10:27:10 +0000 Subject: ipv6: struct xfrm6_tunnel in read_mostly section tunnel6_handlers chain being scanned for each incoming packet, make sure it doesnt share an often dirtied cache line. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 4 ++-- net/ipv6/tunnel6.c | 4 ++-- net/ipv6/xfrm6_tunnel.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 0fd027f3f47e..29f99dd75bc6 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1372,13 +1372,13 @@ static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev) ip6n->tnls_wc[0] = t; } -static struct xfrm6_tunnel ip4ip6_handler = { +static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { .handler = ip4ip6_rcv, .err_handler = ip4ip6_err, .priority = 1, }; -static struct xfrm6_tunnel ip6ip6_handler = { +static struct xfrm6_tunnel ip6ip6_handler __read_mostly = { .handler = ip6ip6_rcv, .err_handler = ip6ip6_err, .priority = 1, diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index fc3c86a47452..d203e6df1f8b 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -30,8 +30,8 @@ #include #include -static struct xfrm6_tunnel *tunnel6_handlers; -static struct xfrm6_tunnel *tunnel46_handlers; +static struct xfrm6_tunnel *tunnel6_handlers __read_mostly; +static struct xfrm6_tunnel *tunnel46_handlers __read_mostly; static DEFINE_MUTEX(tunnel6_mutex); int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 2ce3a8278f26..ac7584b946a5 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -317,13 +317,13 @@ static const struct xfrm_type xfrm6_tunnel_type = { .output = xfrm6_tunnel_output, }; -static struct xfrm6_tunnel xfrm6_tunnel_handler = { +static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = { .handler = xfrm6_tunnel_rcv, .err_handler = xfrm6_tunnel_err, .priority = 2, }; -static struct xfrm6_tunnel xfrm46_tunnel_handler = { +static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = { .handler = xfrm6_tunnel_rcv, .err_handler = xfrm6_tunnel_err, .priority = 2, -- cgit v1.2.3 From 1f0f63885658889b3bcb8a08fbcb9532f8e536c9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 30 Aug 2010 21:55:17 -0700 Subject: stmmac: Fix build warnings. In file included from drivers/net/stmmac/stmmac_ethtool.c:30: drivers/net/stmmac/stmmac.h:111: warning: 'struct platform_device' declared inside parameter list drivers/net/stmmac/stmmac.h:111: warning: its scope is only this definition or declaration, which is probably not what you want drivers/net/stmmac/stmmac_main.c: In function 'stmmac_dvr_probe': drivers/net/stmmac/stmmac_main.c:1744: warning: cast from pointer to integer of different size In file included from drivers/net/stmmac/stmmac_mdio.c:31: drivers/net/stmmac/stmmac.h:111: warning: 'struct platform_device' declared inside parameter list drivers/net/stmmac/stmmac.h:111: warning: its scope is only this definition or declaration, which is probably not what you want drivers/net/stmmac/dwmac1000_core.c: In function 'dwmac1000_dump_regs': drivers/net/stmmac/dwmac1000_core.c:56: warning: cast from pointer to integer of different size Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/stmmac/dwmac1000_core.c | 2 +- drivers/net/stmmac/stmmac.h | 1 + drivers/net/stmmac/stmmac_main.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 8bbfc0f48dea..f1f426146f40 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -53,7 +53,7 @@ static void dwmac1000_core_init(void __iomem *ioaddr) static void dwmac1000_dump_regs(void __iomem *ioaddr) { int i; - pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr); + pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr); for (i = 0; i < 55; i++) { int offset = i * 4; diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index cca53dbac361..d0ddab0d21c2 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -21,6 +21,7 @@ *******************************************************************************/ #define DRV_MODULE_VERSION "Apr_2010" +#include #include #include "common.h" diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c59c1061252a..e3f002eba89a 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1742,8 +1742,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->bsp_priv = plat_dat->bsp_priv; pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" - "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name, - pdev->id, ndev->irq, (unsigned int)addr); + "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, + pdev->id, ndev->irq, addr); /* MDIO bus Registration */ pr_debug("\tMDIO bus (id: %d)...", priv->bus_id); -- cgit v1.2.3 From 3ba06c6fbd651ed3377e584026d1c112b492cc8b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Aug 2010 22:21:13 +0300 Subject: mac80211: Fix signal strength average initialization for CQM events The ave_beacon_signal value uses 1/16 dB unit and as such, must be initialized with the signal level of the first Beacon frame multiplied by 16. This fixes an issue where the initial CQM events are reported incorrectly with a burst of events while the running average approaches the correct value after the incorrect initialization. This could cause user space -based roaming decision process to get quite confused at the moment when we would like to go through authentication and DHCP. Cc: stable@kernel.org Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c8694478cde2..7915726d791e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1553,7 +1553,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ifmgd->last_beacon_signal = rx_status->signal; if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; - ifmgd->ave_beacon_signal = rx_status->signal; + ifmgd->ave_beacon_signal = rx_status->signal * 16; ifmgd->last_cqm_event_signal = 0; } else { ifmgd->ave_beacon_signal = -- cgit v1.2.3 From 391a200a89bf85bd38f117f34898c24299e3d53d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Aug 2010 22:22:00 +0300 Subject: mac80211: Do not generate CQM events based on first Beacon frames The signal strength value in a single RX frame is not that reliable, so it is better to delay start of CQM events until there is a real average signal strength from more than a single Beacon frame available. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 7 +++++++ net/mac80211/mlme.c | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9af50fbcd48b..16f7fb164c2d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -368,6 +368,13 @@ struct ieee80211_if_managed { */ int ave_beacon_signal; + /* + * Number of Beacon frames used in ave_beacon_signal. This can be used + * to avoid generating less reliable cqm events that would be based + * only on couple of received frames. + */ + unsigned int count_beacon_signal; + /* * Last Beacon frame signal strength average (ave_beacon_signal / 16) * that triggered a cqm event. 0 indicates that no event has been diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7915726d791e..0cb822cc12e9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -54,6 +54,12 @@ */ #define IEEE80211_SIGNAL_AVE_WEIGHT 3 +/* + * How many Beacon frames need to have been used in average signal strength + * before starting to indicate signal change events. + */ +#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 + #define TMR_RUNNING_TIMER 0 #define TMR_RUNNING_CHANSW 1 @@ -1555,13 +1561,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; ifmgd->ave_beacon_signal = rx_status->signal * 16; ifmgd->last_cqm_event_signal = 0; + ifmgd->count_beacon_signal = 1; } else { ifmgd->ave_beacon_signal = (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * ifmgd->ave_beacon_signal) / 16; + ifmgd->count_beacon_signal++; } if (bss_conf->cqm_rssi_thold && + ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { int sig = ifmgd->ave_beacon_signal / 16; int last_event = ifmgd->last_cqm_event_signal; -- cgit v1.2.3 From 9df86e2e702c6d5547aced7f241addd2d698bb11 Mon Sep 17 00:00:00 2001 From: Denis 'GNUtoo' Carikli Date: Fri, 27 Aug 2010 23:48:19 +0200 Subject: wl1251: Fix queue stopping/waking for TX path This patch was adapted from 06f7bc7db79fabe6b2ec16eff0f59e4acc21eb72 (from linus's linux-2.6 tree of kernel.org) here's the original message: The queue stopping/waking functionality was broken in a way that could cause huge latencies in TX transfers and even cause the TX to stall in the right circumstances. Correct these problems. Signed-off-by: Denis 'GNUtoo' Carikli Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1251.h | 5 ++++- drivers/net/wireless/wl12xx/wl1251_main.c | 12 +++++------- drivers/net/wireless/wl12xx/wl1251_tx.c | 20 +++++++++++++++----- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 9bc4fea3315a..e113d4c1fb35 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h @@ -272,6 +272,8 @@ struct wl1251 { int irq; bool use_eeprom; + spinlock_t wl_lock; + enum wl1251_state state; struct mutex mutex; @@ -399,7 +401,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl); #define WL1251_DEFAULT_POWER_LEVEL 20 -#define WL1251_TX_QUEUE_MAX_LENGTH 20 +#define WL1251_TX_QUEUE_LOW_WATERMARK 10 +#define WL1251_TX_QUEUE_HIGH_WATERMARK 25 #define WL1251_DEFAULT_BEACON_INT 100 #define WL1251_DEFAULT_DTIM_PERIOD 1 diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index f9d9ad620cc9..faf221ca3f41 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -375,6 +375,7 @@ out: static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; + unsigned long flags; skb_queue_tail(&wl->tx_queue, skb); @@ -389,16 +390,13 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) { + if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) { wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues"); - ieee80211_stop_queues(wl->hw); - /* - * FIXME: this is racy, the variable is not properly - * protected. Maybe fix this by removing the stupid - * variable altogether and checking the real queue state? - */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_stop_queues(wl->hw); wl->tx_queue_stopped = true; + spin_unlock_irqrestore(&wl->wl_lock, flags); } return NETDEV_TX_OK; diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c index 6d618fb1fd95..388492a7f41f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/drivers/net/wireless/wl12xx/wl1251_tx.c @@ -320,11 +320,6 @@ void wl1251_tx_work(struct work_struct *work) ret = wl1251_tx_frame(wl, skb); if (ret == -EBUSY) { - /* firmware buffer is full, stop queues */ - wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, " - "stop queues"); - ieee80211_stop_queues(wl->hw); - wl->tx_queue_stopped = true; skb_queue_head(&wl->tx_queue, skb); goto out; } else if (ret < 0) { @@ -447,6 +442,7 @@ void wl1251_tx_complete(struct wl1251 *wl) { int i, result_index, num_complete = 0; struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; + unsigned long flags; if (unlikely(wl->state != WL1251_STATE_ON)) return; @@ -475,6 +471,20 @@ void wl1251_tx_complete(struct wl1251 *wl) } } + if (wl->tx_queue_stopped + && + skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){ + + /* firmware buffer has space, restart queues */ + wl1251_debug(DEBUG_TX, "tx_complete: waking queues"); + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + wl->tx_queue_stopped = false; + spin_unlock_irqrestore(&wl->wl_lock, flags); + ieee80211_queue_work(wl->hw, &wl->tx_work); + + } + /* Every completed frame needs to be acknowledged */ if (num_complete) { /* -- cgit v1.2.3 From 3653910714a4a9b19aadb202c24f7b1ae61d3556 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Aug 2010 17:41:06 +0200 Subject: net/wireless: Remove double test The same expression is tested twice and the result is the same each time. The sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @expression@ expression E; @@ ( * E || ... || E | * E && ... && E ) // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- net/wireless/wext-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 0ef17bc42bac..40385936e286 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -611,7 +611,7 @@ struct iw_statistics *get_wireless_stats(struct net_device *dev) #endif #ifdef CONFIG_CFG80211_WEXT - if (dev->ieee80211_ptr && dev->ieee80211_ptr && + if (dev->ieee80211_ptr && dev->ieee80211_ptr->wiphy && dev->ieee80211_ptr->wiphy->wext && dev->ieee80211_ptr->wiphy->wext->get_wireless_stats) -- cgit v1.2.3 From 56363ddeeed3afc5277ca227209773bc1042cc7b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 28 Aug 2010 18:21:21 +0200 Subject: ath9k: fix spurious MIC failure reports According to the hardware documentation, the MIC failure bit is only valid if the frame was decrypted using a valid TKIP key and is not a fragment. In some setups I've seen hardware-reported MIC failures on an AP that was configured for CCMP only, so it's clear that additional checks are necessary. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/common.c | 11 +++++++++++ drivers/net/wireless/ath/ath9k/mac.c | 3 ++- drivers/net/wireless/ath/ath9k/recv.c | 19 +++++++++++-------- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index d32f2828b098..a706202fa67c 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -119,6 +119,7 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); + DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); u8 splitmic; struct ath_regulatory regulatory; diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 31cfe468e3fc..2dab64bb23a8 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -372,9 +372,13 @@ int ath9k_cmn_key_config(struct ath_common *common, set_bit(idx, common->keymap); if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); + set_bit(idx, common->tkip_keymap); + set_bit(idx + 64, common->tkip_keymap); if (common->splitmic) { set_bit(idx + 32, common->keymap); set_bit(idx + 64 + 32, common->keymap); + set_bit(idx + 32, common->tkip_keymap); + set_bit(idx + 64 + 32, common->tkip_keymap); } } @@ -399,10 +403,17 @@ void ath9k_cmn_key_delete(struct ath_common *common, return; clear_bit(key->hw_key_idx + 64, common->keymap); + + clear_bit(key->hw_key_idx, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + if (common->splitmic) { ath9k_hw_keyreset(ah, key->hw_key_idx + 32); clear_bit(key->hw_key_idx + 32, common->keymap); clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + + clear_bit(key->hw_key_idx + 32, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); } } EXPORT_SYMBOL(ath9k_cmn_key_delete); diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e955bb9d98cb..0b7d1253f0c0 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -711,7 +711,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (ads.ds_rxstatus8 & AR_MichaelErr) + else if ((ads.ds_rxstatus8 & AR_MichaelErr) && + rs->rs_keyix != ATH9K_RXKEYIX_INVALID) rs->rs_status |= ATH9K_RXERR_MIC; } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a3fc987ebab0..534a91bcc1d9 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -870,15 +870,18 @@ static bool ath9k_rx_accept(struct ath_common *common, if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { *decrypt_error = true; } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { - if (ieee80211_is_ctl(fc)) - /* - * Sometimes, we get invalid - * MIC failures on valid control frames. - * Remove these mic errors. - */ - rx_stats->rs_status &= ~ATH9K_RXERR_MIC; - else + /* + * The MIC error bit is only valid if the frame + * is not a control frame or fragment, and it was + * decrypted using a valid TKIP key. + */ + if (!ieee80211_is_ctl(fc) && + !ieee80211_has_morefrags(fc) && + !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && + test_bit(rx_stats->rs_keyix, common->tkip_keymap)) rxs->flag |= RX_FLAG_MMIC_ERROR; + else + rx_stats->rs_status &= ~ATH9K_RXERR_MIC; } /* * Reject error frames with the exception of -- cgit v1.2.3 From a908a743822d2eed2d8394bb607bb9db5934dcfc Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 30 Aug 2010 21:12:24 +0200 Subject: rt2x00: Rename txentry_desc.queue -> txentry_desc.qid Variables containing queue ids are called qid everywhere else, hence rename the queue field in txentry_desc to qid as well. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.h | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ecbd07a78edb..25c44cfd7452 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -469,7 +469,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); + rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); rt2x00_desc_write(txwi, 1, word); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7fb9b6179af1..ecf57635ae51 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -312,7 +312,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Initialize information from queue */ - txdesc->queue = entry->queue->qid; + txdesc->qid = entry->queue->qid; txdesc->cw_min = entry->queue->cw_min; txdesc->cw_max = entry->queue->cw_max; txdesc->aifs = entry->queue->aifs; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index c451a50f7a01..0e38a911195d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -296,7 +296,7 @@ enum txentry_desc_flags { * Summary of information for the frame descriptor before sending a TX frame. * * @flags: Descriptor flags (See &enum queue_entry_flags). - * @queue: Queue identification (See &enum data_queue_qid). + * @qid: Queue identification (See &enum data_queue_qid). * @length: Length of the entire frame. * @header_length: Length of 802.11 header. * @length_high: PLCP length high word. @@ -322,7 +322,7 @@ enum txentry_desc_flags { struct txentry_desc { unsigned long flags; - enum data_queue_qid queue; + enum data_queue_qid qid; u16 length; u16 header_length; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 8f017ad8c3db..18829b2eccc3 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1778,7 +1778,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, * Start writing the descriptor words. */ rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); @@ -1809,7 +1809,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); - if (txdesc->queue != QID_BEACON) { + if (txdesc->qid != QID_BEACON) { rt2x00_desc_read(txd, 6, &word); rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, skbdesc->skb_dma); @@ -1856,7 +1856,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, */ skbdesc->desc = txd; skbdesc->desc_len = - (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; + (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; } /* diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ee2c52fd0d73..ac8f6d0b8f49 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1463,7 +1463,7 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); -- cgit v1.2.3 From 2035c0cf8f637e88cdd338c15570a7ad42afc552 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 30 Aug 2010 21:12:47 +0200 Subject: rt2x00: Update rt2800 comments regarding AMPDU and PACKET_ID in TXWI Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 5c006a795346..70a5cb86405b 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1953,6 +1953,8 @@ struct mac_iveiv_entry { * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs * BW: Channel bandwidth 20MHz or 40 MHz * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED + * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will + * aggregate consecutive frames with the same RA and QoS TID. */ #define TXWI_W0_FRAG FIELD32(0x00000001) #define TXWI_W0_MIMO_PS FIELD32(0x00000002) @@ -1976,7 +1978,9 @@ struct mac_iveiv_entry { * WIRELESS_CLI_ID: Client ID for WCID table access * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame * PACKETID: Will be latched into the TX_STA_FIFO register once the according - * frame was processed. 0: Don't report tx status for this frame. + * frame was processed. If multiple frames are aggregated together + * (AMPDU==1) the reported tx status will always contain the packet + * id of the first frame. 0: Don't report tx status for this frame. */ #define TXWI_W1_ACK FIELD32(0x00000001) #define TXWI_W1_NSEQ FIELD32(0x00000002) -- cgit v1.2.3 From 5ffddc498c700bb45ea55efc37746cb28d601766 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:13:08 +0200 Subject: rt2x00: Add rt2800_wait_csr_ready Similar to rt2800_wait_wpdma_ready() we can add a function to waiting until the CSR is ready. This centralizes some additional code into rt2800lib. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 28 ++++++++++++++++++---------- drivers/net/wireless/rt2x00/rt2800lib.h | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 12 +----------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 25c44cfd7452..7c68bf35951f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -255,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2800_mcu_request); +int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) +{ + unsigned int i = 0; + u32 reg; + + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (reg && reg != ~0) + return 0; + msleep(1); + } + + ERROR(rt2x00dev, "Unstable hardware.\n"); + return -EBUSY; +} +EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); + int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) { unsigned int i; @@ -370,17 +387,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, /* * Wait for stable hardware. */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - } if (rt2x00_is_pci(rt2x00dev)) rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index deb10b14157b..986229c06c19 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -140,6 +140,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1); +int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev); int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 82ae58e0c5d7..b1a8e943750b 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -122,22 +122,12 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; - int i; /* * Wait until BBP and RF are ready. */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - } rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); -- cgit v1.2.3 From 3613884d96b186f58a77af05122f84167604aad9 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:13:30 +0200 Subject: rt2x00: Validate TX status results with current data entry Instead of printing a warning when the PID, ACK, or WCID of an entry don't match the TX status report, we should skip the entry to search for the entry which actually does match the TX status data. This reduces the number of watchdog errors on the TX queues for rt2800usb, and seems to improve the reliability of the TX flow a bit. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 73 ++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 7c68bf35951f..1a8170068b1c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -581,6 +581,49 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) +{ + __le32 *txwi; + u32 word; + int wcid, ack, pid; + int tx_wcid, tx_ack, tx_pid; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + + /* + * This frames has returned with an IO error, + * so the status report is not intended for this + * frame. + */ + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + return false; + } + + /* + * Validate if this TX status report is intended for + * this entry by comparing the WCID/ACK/PID fields. + */ + txwi = rt2800_drv_get_txwi(entry); + + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); + + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + WARNING(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); + return false; + } + + return true; +} + void rt2800_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; @@ -589,8 +632,8 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) struct txdone_entry_desc txdesc; u32 word; u32 reg; - int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; u16 mcs, real_mcs; + u8 pid; int i; /* @@ -607,18 +650,15 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) break; - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - /* * Skip this entry when it contains an invalid * queue identication number. */ - if (pid <= 0 || pid > QID_RX) + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; + if (pid >= QID_RX) continue; - queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); + queue = rt2x00queue_get_queue(rt2x00dev, pid); if (unlikely(!queue)) continue; @@ -627,35 +667,22 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) * order. We first check that the queue is not empty. */ entry = NULL; + txwi = NULL; while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (!test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + if (rt2800_txdone_entry_check(entry, reg)) break; - - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); } if (!entry || rt2x00queue_empty(queue)) break; - /* - * Check if we got a match by looking at WCID/ACK/PID - * fields - */ - txwi = rt2800_drv_get_txwi(entry); - - rt2x00_desc_read(txwi, 1, &word); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) - WARNING(rt2x00dev, "invalid TX_STA_FIFO content"); /* * Obtain the status about this packet. */ txdesc.flags = 0; + txwi = rt2800_drv_get_txwi(entry); rt2x00_desc_read(txwi, 0, &word); mcs = rt2x00_get_field32(word, TXWI_W0_MCS); real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); -- cgit v1.2.3 From b9eca24209a59ef0a8c3cbbbb94b8c76d4b3aae3 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:13:54 +0200 Subject: rt2x00: Wakeup hardware before loading firmware According to the legacy drivers the AUTOWAKEUP_CFG register must be reset to 0 before loading the firmware. Instead of during rt2800{pci,usb}_write_firmware it must actually be done in rt2800_load_firmware() before resetting the WPDMA_GLO_CFG and PWR_PIN_CFG registers. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++++ drivers/net/wireless/rt2x00/rt2800pci.c | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 1a8170068b1c..a5455f46cec1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -384,6 +384,12 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, unsigned int i; u32 reg; + /* + * If driver doesn't wake up firmware here, + * rt2800_load_firmware will hang forever when interface is up again. + */ + rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); + /* * Wait for stable hardware. */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4d93204b221f..2bcb1507e3ac 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); - /* * enable Host program ram write selection */ -- cgit v1.2.3 From c600c826a6f4e35512955a5e9a22b0baa741b455 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:14:15 +0200 Subject: rt2x00: Don't set unicast/BSSID masks when clearning MAC or BSSID When configuring the MAC_ADDR or MAC_BSSID with an empty address, the UNICAST_TO_ME_MASK and BSS_ID_MASK must also be reset to prevent invalid interpretation of the addresses. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a5455f46cec1..f90e932b3cb4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1135,19 +1135,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } if (flags & CONFIG_UPDATE_MAC) { - reg = le32_to_cpu(conf->mac[1]); - rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); - conf->mac[1] = cpu_to_le32(reg); + if (!is_zero_ether_addr((const u8 *)conf->mac)) { + reg = le32_to_cpu(conf->mac[1]); + rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); + conf->mac[1] = cpu_to_le32(reg); + } rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, conf->mac, sizeof(conf->mac)); } if (flags & CONFIG_UPDATE_BSSID) { - reg = le32_to_cpu(conf->bssid[1]); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); - conf->bssid[1] = cpu_to_le32(reg); + if (!is_zero_ether_addr((const u8 *)conf->bssid)) { + reg = le32_to_cpu(conf->bssid[1]); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); + conf->bssid[1] = cpu_to_le32(reg); + } rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, conf->bssid, sizeof(conf->bssid)); -- cgit v1.2.3 From e0540879db337b18ef7c580234038ff62c8cd381 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:14:38 +0200 Subject: rt2x00: Set PWR_PIN_CFG during initialization Add PWR_PIN_CFG initialization for rt2800usb at the same point as rt2800pci. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b1a8e943750b..d275549a1fb9 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -132,6 +132,8 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); -- cgit v1.2.3 From 0e3afe5b20c4ccdeff5178c62b557a917945a828 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:14:56 +0200 Subject: rt2x00: Correctly kill beacon queue USB devices upload their beacon and then automatically send it out every beacon interval. However when killing a TX queue we only kill the URB and not the actual transmission of the beacon. This will reset the Beacon register to prevent any beacons from being transmitted. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 10 +++++++++- drivers/net/wireless/rt2x00/rt2800usb.c | 10 +++++++++- drivers/net/wireless/rt2x00/rt73usb.c | 10 +++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 71d8d821c4e1..a161e9e33b73 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1196,6 +1196,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) return length; } +static void rt2500usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -1794,7 +1802,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt2500usb_kill_tx_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_shared_key = rt2500usb_config_key, .config_pairwise_key = rt2500usb_config_key, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index d275549a1fb9..3dff56ec195a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -335,6 +335,14 @@ static void rt2800usb_work_txdone(struct work_struct *work) } } +static void rt2800usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -533,7 +541,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt2800usb_kill_tx_queue, .fill_rxdone = rt2800usb_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ac8f6d0b8f49..df0ef3f70f1e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1573,6 +1573,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) return length; } +static void rt73usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -2262,7 +2270,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt73usb_kill_tx_queue, .fill_rxdone = rt73usb_fill_rxdone, .config_shared_key = rt73usb_config_shared_key, .config_pairwise_key = rt73usb_config_pairwise_key, -- cgit v1.2.3 From 652a9dd2a0c07251e328519cc23f1316ab13ed51 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:15:19 +0200 Subject: rt2x00: Split watchdog check into a DMA and STATUS timeout The watchdog for rt2800usb triggers frequently causing all URB's to be canceled often enough to interrupt the normal TX flow. More research indicated that not the URB upload to the USB host were hanging, but instead the TX status reports. To correctly detect what is going on, we introduce Q_INDEX_DMA_DONE which is an index counter between Q_INDEX_DONE and Q_INDEX and indicates if the frame has been transfered to the device. This also requires the rt2x00queue timeout functions to be updated to differentiate between a DMA timeout (time between Q_INDEX and Q_INDEX_DMA_DONE timeout) and a STATUS timeout (time between Q_INDEX_DMA_DONE and Q_INDEX_DONE timeout) All Q_INDEX_DMA_DONE code was taken from the RFC from Helmut Schaa for the implementation for watchdog for rt2800pci. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00debug.c | 5 +++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 6 ++++++ drivers/net/wireless/rt2x00/rt2x00queue.c | 13 ++++++++----- drivers/net/wireless/rt2x00/rt2x00queue.h | 21 +++++++++++++++++---- drivers/net/wireless/rt2x00/rt2x00usb.c | 27 ++++++++++++++++++++++++--- 6 files changed, 59 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 762f6b4e7afc..0ae942cb66df 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1070,6 +1070,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, */ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_dmadone(struct queue_entry *entry); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index daf7f950a28f..54dc44bb415c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -338,14 +338,15 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, return -ENOMEM; temp = data + - sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\n"); + sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { spin_lock_irqsave(&queue->lock, irqflags); - temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, + temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length, queue->index[Q_INDEX], + queue->index[Q_INDEX_DMA_DONE], queue->index[Q_INDEX_DONE]); spin_unlock_irqrestore(&queue->lock, irqflags); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 580595ba5683..053fdd3bd720 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -251,6 +251,12 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); +void rt2x00lib_dmadone(struct queue_entry *entry) +{ + rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); +} +EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); + void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index ecf57635ae51..6d41599a090c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -731,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) if (queue->index[index] >= queue->limit) queue->index[index] = 0; + queue->last_action[index] = jiffies; + if (index == Q_INDEX) { queue->length++; - queue->last_index = jiffies; } else if (index == Q_INDEX_DONE) { queue->length--; queue->count++; - queue->last_index_done = jiffies; } spin_unlock_irqrestore(&queue->lock, irqflags); @@ -746,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) static void rt2x00queue_reset(struct data_queue *queue) { unsigned long irqflags; + unsigned int i; spin_lock_irqsave(&queue->lock, irqflags); queue->count = 0; queue->length = 0; - queue->last_index = jiffies; - queue->last_index_done = jiffies; - memset(queue->index, 0, sizeof(queue->index)); + + for (i = 0; i < Q_INDEX_MAX; i++) { + queue->index[i] = 0; + queue->last_action[i] = jiffies; + } spin_unlock_irqrestore(&queue->lock, irqflags); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 0e38a911195d..d81d85f34866 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -401,6 +401,8 @@ struct queue_entry { * * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is * owned by the hardware then the queue is considered to be full. + * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been + * transfered to the hardware. * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by * the hardware and for which we need to run the txdone handler. If this * entry is not owned by the hardware the queue is considered to be empty. @@ -409,6 +411,7 @@ struct queue_entry { */ enum queue_index { Q_INDEX, + Q_INDEX_DMA_DONE, Q_INDEX_DONE, Q_INDEX_MAX, }; @@ -445,13 +448,12 @@ struct data_queue { enum data_queue_qid qid; spinlock_t lock; - unsigned long last_index; - unsigned long last_index_done; unsigned int count; unsigned short limit; unsigned short threshold; unsigned short length; unsigned short index[Q_INDEX_MAX]; + unsigned long last_action[Q_INDEX_MAX]; unsigned short txop; unsigned short aifs; @@ -616,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** - * rt2x00queue_timeout - Check if a timeout occured for this queue + * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts * @queue: Queue to check. */ static inline int rt2x00queue_timeout(struct data_queue *queue) { - return time_after(queue->last_index, queue->last_index_done + (HZ / 10)); + return time_after(queue->last_action[Q_INDEX_DMA_DONE], + queue->last_action[Q_INDEX_DONE] + (HZ / 10)); +} + +/** + * rt2x00queue_timeout - Check if a timeout occured for DMA transfers + * @queue: Queue to check. + */ +static inline int rt2x00queue_dma_timeout(struct data_queue *queue) +{ + return time_after(queue->last_action[Q_INDEX], + queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); } /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 6cc7aa418d87..aec6440d364a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -212,6 +212,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + /* + * Report the frame as DMA done + */ + rt2x00lib_dmadone(entry); + /* * Check if the frame was correctly uploaded */ @@ -283,13 +288,14 @@ void rt2x00usb_kill_tx_queue(struct data_queue *queue) } EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); -static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) +static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { struct queue_entry *entry; struct queue_entry_priv_usb *entry_priv; unsigned short threshold = queue->threshold; - WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); + WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," + " invoke forced forced reset", queue->qid); /* * Temporarily disable the TX queue, this will force mac80211 @@ -331,13 +337,23 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); } +static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) +{ + WARNING(queue->rt2x00dev, "TX queue %d status timed out," + " invoke forced tx handler", queue->qid); + + ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); +} + void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; tx_queue_for_each(rt2x00dev, queue) { + if (rt2x00queue_dma_timeout(queue)) + rt2x00usb_watchdog_tx_dma(queue); if (rt2x00queue_timeout(queue)) - rt2x00usb_watchdog_reset_tx(queue); + rt2x00usb_watchdog_tx_status(queue); } } EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); @@ -382,6 +398,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + /* + * Report the frame as DMA done + */ + rt2x00lib_dmadone(entry); + /* * Check if the received data is simply too small * to be actually valid, or if the urb is signaling -- cgit v1.2.3 From cd35a3912188d006f251fff1028d84e1d1649ca2 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 30 Aug 2010 21:15:51 +0200 Subject: rt2x00: Cleanup rt2x00usb_watchdog_reset_tx rt2x00usb_watchdog_reset_tx performs the same task as rt2x00usb_kill_tx_queue, with the only difference is that it waits for all entries to be returned to the driver and for all frames the status has been reported to mac80211. We can easily split this task by calling rt2x00usb_kill_tx_queue, sleep for a short period and invoke the TX status reporting function. By adding the sleep() to the kill_entry we make sure that even during shutdown we guarentee the entry has been killed when the function returns. To make this work correctly the interrupt handlers have to be updated to prevent checking for the RADIO_ENABLED flag too early which prevents the ownership of the entry to be reset. Additionally a check for the DEVICE_PRESENT flag is not required but is nice to prevent race conditions when the device was unplugged. Additionally rather then calling rt2x00usb_work_txdone() for status reporting we let the driver perform the TX status reporting first. If this is not sufficient then rt2x00usb_work_txdone() will still be used to cleanup the mess. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 66 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index aec6440d364a..4c5ae3d45625 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -208,8 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -227,7 +226,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Schedule the delayed work for reading the TX status * from the device. */ - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); } static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) @@ -279,6 +280,14 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) if ((entry->queue->qid == QID_BEACON) && (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) usb_kill_urb(bcn_priv->guardian_urb); + + /* + * We need a short delay here to wait for + * the URB to be canceled + */ + do { + udelay(100); + } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); } void rt2x00usb_kill_tx_queue(struct data_queue *queue) @@ -290,8 +299,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { - struct queue_entry *entry; - struct queue_entry_priv_usb *entry_priv; + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; unsigned short threshold = queue->threshold; WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," @@ -305,28 +313,33 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) * queue from being enabled during the txdone handler. */ queue->threshold = queue->limit; - ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); + ieee80211_stop_queue(rt2x00dev->hw, queue->qid); /* - * Reset all currently uploaded TX frames. + * Kill all entries in the queue, afterwards we need to + * wait a bit for all URBs to be cancelled. */ - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - entry_priv = entry->priv_data; - usb_kill_urb(entry_priv->urb); + rt2x00usb_kill_tx_queue(queue); - /* - * We need a short delay here to wait for - * the URB to be canceled - */ - do { - udelay(100); - } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); + /* + * In case that a driver has overriden the txdone_work + * function, we invoke the TX done through there. + */ + rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); - /* - * Invoke the TX done handler - */ - rt2x00usb_work_txdone_entry(entry); + /* + * Security measure: if the driver did override the + * txdone_work function, and the hardware did arrive + * in a state which causes it to malfunction, it is + * possible that the driver couldn't handle the txdone + * event correctly. So after giving the driver the + * chance to cleanup, we now force a cleanup of any + * leftovers. + */ + if (!rt2x00queue_empty(queue)) { + WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," + " status handling failed, invoke hard reset", queue->qid); + rt2x00usb_work_txdone(&rt2x00dev->txdone_work); } /* @@ -334,7 +347,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) * queue again. */ queue->threshold = threshold; - ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); + ieee80211_wake_queue(rt2x00dev->hw, queue->qid); } static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) @@ -394,8 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -415,7 +427,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Schedule the delayed work for reading the RX status * from the device. */ - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); } /* -- cgit v1.2.3 From 18145c69349f2ab60c470798f83b3a2639e2a8d9 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 30 Aug 2010 15:12:02 -0400 Subject: mac80211: cancel scan in ieee80211_restart_hw if software scan pending This function exists to clean-up after a hardware error or something similar. The restart is accomplished using the same infrastructure used to resume after a suspend. The suspend path cancels running scans, so it seems appropriate to do that here as well for software-based scans. If a hardware-based scan is pending, issue a warning message since this indicates that the drivers has failed to clean-up after itself. Signed-off-by: John W. Linville --- net/mac80211/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 93194f61adb0..a06b6ee63c07 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -305,7 +305,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) trace_api_restart_hw(local); - /* use this reason, __ieee80211_resume will unblock it */ + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + "%s called with hardware scan in progress\n", __func__); + + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) + ieee80211_scan_cancel(local); + + /* use this reason, ieee80211_reconfig will unblock it */ ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); -- cgit v1.2.3 From 1a98214feef2221cd7c24b17cd688a5a9d85b2ea Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Mon, 30 Aug 2010 12:57:03 +0000 Subject: Phonet: restore flow control credits when sending fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/pep.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b2a3ae6cad78..5034f0f62bdb 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -834,6 +834,7 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) { struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; + int err; if (pn_flow_safe(pn->tx_fc) && !atomic_add_unless(&pn->tx_credits, -1, 0)) { @@ -852,7 +853,10 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) ph->message_id = PNS_PIPE_DATA; ph->pipe_handle = pn->pipe_handle; - return pn_skb_send(sk, skb, &pipe_srv); + err = pn_skb_send(sk, skb, &pipe_srv); + if (err && pn_flow_safe(pn->tx_fc)) + atomic_inc(&pn->tx_credits); + return err; } static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, -- cgit v1.2.3 From 02ac3268a581639af241c254579160909373e12c Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Mon, 30 Aug 2010 12:57:04 +0000 Subject: Phonet: correct sendmsg() error code from sock_alloc_send_skb() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/pep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 5034f0f62bdb..04e34196c9de 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -876,7 +876,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, flags & MSG_DONTWAIT, &err); if (!skb) - return -ENOBUFS; + return err; skb_reserve(skb, MAX_PHONET_HEADER + 3); err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); -- cgit v1.2.3 From 01b38606bded44bf8b7ca42e8fe5f2cad5d28121 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Mon, 30 Aug 2010 12:57:05 +0000 Subject: Phonet: do not set POLLOUT in case of send buffer overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 6e9848bf0370..7c91f739f138 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -281,7 +281,9 @@ static unsigned int pn_socket_poll(struct file *file, struct socket *sock, if (!mask && sk->sk_state == TCP_CLOSE_WAIT) return POLLHUP; - if (sk->sk_state == TCP_ESTABLISHED && atomic_read(&pn->tx_credits)) + if (sk->sk_state == TCP_ESTABLISHED && + atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf && + atomic_read(&pn->tx_credits)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; return mask; -- cgit v1.2.3 From 72ed62f7c9f0abe11231d073195a722ee43d6ec1 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 31 Aug 2010 04:58:18 +0000 Subject: vlan: Use vlan_dev_real_dev in vlan_hwaccel_do_receive [patch net-next-2.6] vlan: Use vlan_dev_real_dev in vlan_hwaccel_do_receive Use helper as in other places. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/8021q/vlan_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 3438c01bbacf..889f4ac4459a 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -40,7 +40,7 @@ void vlan_hwaccel_do_receive(struct sk_buff *skb) struct net_device *dev = skb->dev; struct vlan_rx_stats *rx_stats; - skb->dev = vlan_dev_info(dev)->real_dev; + skb->dev = vlan_dev_real_dev(dev); netif_nit_deliver(skb); skb->dev = dev; -- cgit v1.2.3 From ba4fd9d8282f7f856f2287fe8be784d1dfdda28b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 31 Aug 2010 01:57:35 +0000 Subject: pktgen: remove non used variable remove non used variable "queue" in pg_cleanup Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/pktgen.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 10a1ea72010d..386c2283f14e 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3907,8 +3907,6 @@ static void __exit pg_cleanup(void) { struct pktgen_thread *t; struct list_head *q, *n; - wait_queue_head_t queue; - init_waitqueue_head(&queue); /* Stop all interfaces & threads */ -- cgit v1.2.3 From 4dc89133f49b8cfd77ba7e83f5960aed63aaa99e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 31 Aug 2010 07:40:16 +0000 Subject: net: add a comment on netdev->last_rx As some driver authors seem to reintroduce dev->last_rx use, add a comment to strongly discourage this. Since commit 6cf3f41e6c0 (bonding, net: Move last_rx update into bonding recv logic), network drivers dont need to update last_rx themselves, unless they use this field to implement a timeout. Not updating last_rx helps not dirtying a cache line, improving performance in SMP. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0cf9448a32c4..c82220a9f3d5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -953,7 +953,14 @@ struct net_device { /* * Cache line mostly used on receive path (including eth_type_trans()) */ - unsigned long last_rx; /* Time of last Rx */ + unsigned long last_rx; /* Time of last Rx + * This should not be set in + * drivers, unless really needed, + * because network stack (bonding) + * use it if/when necessary, to + * avoid dirtying this cache line. + */ + /* Interface address info used in eth_type_trans() */ unsigned char *dev_addr; /* hw address, (before bcast because most packets are -- cgit v1.2.3 From 1639ab6f7831f056286c64d98e8e5eb04e3bacac Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 31 Aug 2010 10:23:47 +0000 Subject: gro: unexport tcp4_gro_receive and tcp4_gro_complete tcp4_gro_receive() and tcp4_gro_complete() dont need to be exported. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 020766292bb0..a0232f3a358b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2571,7 +2571,6 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) return tcp_gro_receive(head, skb); } -EXPORT_SYMBOL(tcp4_gro_receive); int tcp4_gro_complete(struct sk_buff *skb) { @@ -2584,7 +2583,6 @@ int tcp4_gro_complete(struct sk_buff *skb) return tcp_gro_complete(skb); } -EXPORT_SYMBOL(tcp4_gro_complete); struct proto tcp_prot = { .name = "TCP", -- cgit v1.2.3 From 74af4c7df35e6811eb3c50e398abafa5b3cabb75 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 31 Aug 2010 20:56:48 -0700 Subject: stmmac: Fix another build warning. drivers/net/stmmac/dwmac100_core.c: In function 'dwmac100_dump_mac_regs': drivers/net/stmmac/dwmac100_core.c:47: warning: cast from pointer to integer of different size Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/stmmac/dwmac100_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index 135a8082816e..db06c04ce480 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -45,9 +45,9 @@ static void dwmac100_core_init(void __iomem *ioaddr) static void dwmac100_dump_mac_regs(void __iomem *ioaddr) { pr_info("\t----------------------------------------------\n" - "\t DWMAC 100 CSR (base addr = 0x%8x)\n" + "\t DWMAC 100 CSR (base addr = 0x%p)\n" "\t----------------------------------------------\n", - (unsigned int) ioaddr); + ioaddr); pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL, readl(ioaddr + MAC_CONTROL)); pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH, -- cgit v1.2.3 From 4e70812b3dc32c76fa2fa3aa2c8221eaac87cd6f Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Tue, 31 Aug 2010 17:17:44 +0000 Subject: qlcnic: backout firmware initialization update o Backing out "firmware initialization update" changes, commit-id "d4066833bb1b35fefb1dd45eb2b10659d46bf151". o fix heartbit spelling, it should be heartbeat Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 +- drivers/net/qlcnic/qlcnic_hdr.h | 6 ++- drivers/net/qlcnic/qlcnic_init.c | 109 ++++++++++++++++++++++++++++++++------- drivers/net/qlcnic/qlcnic_main.c | 11 ++-- 4 files changed, 100 insertions(+), 28 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 1f5c10bc9376..74eff18fc1ec 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -978,7 +978,7 @@ struct qlcnic_adapter { u32 temp; u32 int_vec_bit; - u32 heartbit; + u32 heartbeat; u8 max_mac_filters; u8 dev_state; diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index bce1b1d541b7..716203e41dc7 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -747,8 +747,12 @@ enum { #define QLCNIC_RESET_TIMEOUT_SECS 10 #define QLCNIC_INIT_TIMEOUT_SECS 30 +#define QLCNIC_RCVPEG_CHECK_RETRY_COUNT 2000 +#define QLCNIC_RCVPEG_CHECK_DELAY 10 +#define QLCNIC_CMDPEG_CHECK_RETRY_COUNT 60 +#define QLCNIC_CMDPEG_CHECK_DELAY 500 #define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 -#define QLCNIC_HEARTBEAT_RETRY_COUNT 45 +#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45 #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index eb8256bec516..8e0e7a3bbf9e 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -46,6 +46,9 @@ static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, struct qlcnic_host_rds_ring *rds_ring); +static int +qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter); + static void crb_addr_transform_setup(void) { crb_addr_transform(XDMA); @@ -544,31 +547,77 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) return 0; } -int -qlcnic_check_fw_status(struct qlcnic_adapter *adapter) +static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter) { - u32 heartbit, cmdpeg_state, ret = -EIO; - int retries = QLCNIC_HEARTBEAT_RETRY_COUNT; + u32 val; + int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT; - adapter->heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); do { - msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); - heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - if (heartbit != adapter->heartbit) { - cmdpeg_state = QLCRD32(adapter, CRB_CMDPEG_STATE); - /* Ensure peg states are initialized */ - if (cmdpeg_state == PHAN_INITIALIZE_COMPLETE || - cmdpeg_state == PHAN_INITIALIZE_ACK) { - /* Complete firmware handshake */ - QLCWR32(adapter, CRB_CMDPEG_STATE, - PHAN_INITIALIZE_ACK); - ret = QLCNIC_RCODE_SUCCESS; - break; - } + val = QLCRD32(adapter, CRB_CMDPEG_STATE); + + switch (val) { + case PHAN_INITIALIZE_COMPLETE: + case PHAN_INITIALIZE_ACK: + return 0; + case PHAN_INITIALIZE_FAILED: + goto out_err; + default: + break; } + + msleep(QLCNIC_CMDPEG_CHECK_DELAY); + } while (--retries); - return ret; + QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); + +out_err: + dev_err(&adapter->pdev->dev, "Command Peg initialization not " + "complete, state: 0x%x.\n", val); + return -EIO; +} + +static int +qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter) +{ + u32 val; + int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT; + + do { + val = QLCRD32(adapter, CRB_RCVPEG_STATE); + + if (val == PHAN_PEG_RCV_INITIALIZED) + return 0; + + msleep(QLCNIC_RCVPEG_CHECK_DELAY); + + } while (--retries); + + if (!retries) { + dev_err(&adapter->pdev->dev, "Receive Peg initialization not " + "complete, state: 0x%x.\n", val); + return -EIO; + } + + return 0; +} + +int +qlcnic_check_fw_status(struct qlcnic_adapter *adapter) +{ + int err; + + err = qlcnic_cmd_peg_ready(adapter); + if (err) + return err; + + err = qlcnic_receive_peg_ready(adapter); + if (err) + return err; + + QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + + return err; } int @@ -943,12 +992,32 @@ static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter) qlcnic_pcie_sem_unlock(adapter, 2); } +static int +qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter) +{ + u32 heartbeat, ret = -EIO; + int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT; + + adapter->heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + + do { + msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); + heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + if (heartbeat != adapter->heartbeat) { + ret = QLCNIC_RCODE_SUCCESS; + break; + } + } while (--retries); + + return ret; +} + int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) { u32 val, version, major, minor, build; - if (qlcnic_check_fw_status(adapter)) { + if (qlcnic_check_fw_hearbeat(adapter)) { qlcnic_rom_lock_recovery(adapter); return 1; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6999d5aaa157..771a160b88c1 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -983,7 +983,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) err = qlcnic_need_fw_reset(adapter); if (err == 0) - goto set_dev_ready; + goto check_fw_status; err = qlcnic_pinit_from_rom(adapter); if (err) @@ -1002,7 +1002,6 @@ check_fw_status: if (err) goto err_out; -set_dev_ready: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); @@ -2795,7 +2794,7 @@ done: static int qlcnic_check_health(struct qlcnic_adapter *adapter) { - u32 state = 0, heartbit; + u32 state = 0, heartbeat; struct net_device *netdev = adapter->netdev; if (qlcnic_check_temp(adapter)) @@ -2811,9 +2810,9 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) adapter->need_fw_reset = 1; } - heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - if (heartbit != adapter->heartbit) { - adapter->heartbit = heartbit; + heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + if (heartbeat != adapter->heartbeat) { + adapter->heartbeat = heartbeat; adapter->fw_fail_cnt = 0; if (adapter->need_fw_reset) goto detach; -- cgit v1.2.3 From 2cffcdbf7670980d4d74e2daea8a6cc0729902b8 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:45 +0000 Subject: qlcnic: add api version in reg dump o ethtool reg version bumped to 2 Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index e294b825bac5..cb9463bd6b1e 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -115,9 +115,13 @@ static const u32 diag_registers[] = { -1 }; +#define QLCNIC_MGMT_API_VERSION 2 +#define QLCNIC_DEV_INFO_SIZE 1 +#define QLCNIC_ETHTOOL_REGS_VER 2 static int qlcnic_get_regs_len(struct net_device *dev) { - return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN; + return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN + + QLCNIC_DEV_INFO_SIZE + 1; } static int qlcnic_get_eeprom_len(struct net_device *dev) @@ -342,10 +346,13 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) int ring, i = 0; memset(p, 0, qlcnic_get_regs_len(dev)); - regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | - (adapter->pdev)->device; + regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | + (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; - for (i = 0; diag_registers[i] != -1; i++) + regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); + regs_buff[1] = QLCNIC_MGMT_API_VERSION; + + for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[i] != -1; i++) regs_buff[i] = QLCRD32(adapter, diag_registers[i]); if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) -- cgit v1.2.3 From da48e6c362d24d324f36a780d8566109e5f5a1d7 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:46 +0000 Subject: qlcnic: fix mac addr read o Mac addr was read from flash for every fw reset for Non-priviledge function.It should be read only once. o Remove unnecessary get_mac_addr callback Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 -- drivers/net/qlcnic/qlcnic_hw.c | 13 ------------- drivers/net/qlcnic/qlcnic_main.c | 28 +++++++++++++--------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 74eff18fc1ec..220370fac726 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1259,7 +1259,6 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring); -int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac); void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter); int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); @@ -1346,7 +1345,6 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) extern const struct ethtool_ops qlcnic_ethtool_ops; struct qlcnic_nic_template { - int (*get_mac_addr) (struct qlcnic_adapter *, u8*); int (*config_bridged_mode) (struct qlcnic_adapter *, u32); int (*config_led) (struct qlcnic_adapter *, u32, u32); int (*start_firmware) (struct qlcnic_adapter *); diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 5e6f4864df94..670a54a84ba6 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -715,19 +715,6 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) return rc; } -int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac) -{ - u32 crbaddr; - int pci_func = adapter->ahw.pci_func; - - crbaddr = CRB_MAC_BLOCK_START + - (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); - - qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac); - - return 0; -} - /* * Changes the CRB window to the specified window. */ diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 771a160b88c1..3f2f93b1a9fe 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -322,7 +322,7 @@ qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0) + if (qlcnic_get_mac_address(adapter, mac_addr) != 0) return -EIO; memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); @@ -378,14 +378,12 @@ static const struct net_device_ops qlcnic_netdev_ops = { }; static struct qlcnic_nic_template qlcnic_ops = { - .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnic_config_bridged_mode, .config_led = qlcnic_config_led, .start_firmware = qlcnic_start_firmware }; static struct qlcnic_nic_template qlcnic_vf_ops = { - .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnicvf_config_bridged_mode, .config_led = qlcnicvf_config_led, .start_firmware = qlcnicvf_start_firmware @@ -668,7 +666,6 @@ static void qlcnic_check_options(struct qlcnic_adapter *adapter) { u32 fw_major, fw_minor, fw_build; - char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; struct pci_dev *pdev = adapter->pdev; struct qlcnic_info nic_info; @@ -678,17 +675,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); - if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) - if (qlcnic_read_mac_addr(adapter)) - dev_warn(&pdev->dev, "failed to read mac addr\n"); - if (adapter->portnum == 0) { - get_brd_name(adapter, brd_name); - - pr_info("%s: %s Board Chip rev 0x%x\n", - module_name(THIS_MODULE), - brd_name, adapter->ahw.revision_id); - } - dev_info(&pdev->dev, "firmware v%d.%d.%d\n", fw_major, fw_minor, fw_build); @@ -1468,6 +1454,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err; uint8_t revision_id; uint8_t pci_using_dac; + char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; err = pci_enable_device(pdev); if (err) @@ -1535,6 +1522,17 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_decr_ref; } + if (qlcnic_read_mac_addr(adapter)) + dev_warn(&pdev->dev, "failed to read mac addr\n"); + + if (adapter->portnum == 0) { + get_brd_name(adapter, brd_name); + + pr_info("%s: %s Board Chip rev 0x%x\n", + module_name(THIS_MODULE), + brd_name, adapter->ahw.revision_id); + } + qlcnic_clear_stats(adapter); qlcnic_setup_intr(adapter); -- cgit v1.2.3 From 174240a8efc441f01f2909ee167c0c15099c0212 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:47 +0000 Subject: qlcnic: fix for setting default eswitch config o Default eswitch config was set, even before eswitch capabilty get detected. As a result setting default config was getting fail. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 96 +++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 3f2f93b1a9fe..e0c6811610ab 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -667,7 +667,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) { u32 fw_major, fw_minor, fw_build; struct pci_dev *pdev = adapter->pdev; - struct qlcnic_info nic_info; fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); @@ -688,16 +687,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; } - if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { - adapter->physical_port = nic_info.phys_port; - adapter->switch_mode = nic_info.switch_mode; - adapter->max_tx_ques = nic_info.max_tx_ques; - adapter->max_rx_ques = nic_info.max_rx_ques; - adapter->capabilities = nic_info.capabilities; - adapter->max_mac_filters = nic_info.max_mac_filters; - adapter->max_mtu = nic_info.max_mtu; - } - adapter->msix_supported = !!use_msi_x; adapter->rss_supported = !!use_msi_x; @@ -706,6 +695,32 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->max_rds_rings = MAX_RDS_RINGS; } +static int +qlcnic_initialize_nic(struct qlcnic_adapter *adapter) +{ + int err; + struct qlcnic_info nic_info; + + err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func); + if (err) + return err; + + adapter->physical_port = nic_info.phys_port; + adapter->switch_mode = nic_info.switch_mode; + adapter->max_tx_ques = nic_info.max_tx_ques; + adapter->max_rx_ques = nic_info.max_rx_ques; + adapter->capabilities = nic_info.capabilities; + adapter->max_mac_filters = nic_info.max_mac_filters; + adapter->max_mtu = nic_info.max_mtu; + + if (adapter->capabilities & BIT_6) + adapter->flags |= QLCNIC_ESWITCH_ENABLED; + else + adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; + + return err; +} + static void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) @@ -791,6 +806,10 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) u32 op_mode, priv_level; int err = 0; + err = qlcnic_initialize_nic(adapter); + if (err) + return err; + if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) return 0; @@ -803,8 +822,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) else priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); - if (adapter->capabilities & BIT_6) { - adapter->flags |= QLCNIC_ESWITCH_ENABLED; + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { if (priv_level == QLCNIC_MGMT_FUNC) { adapter->op_mode = QLCNIC_MGMT_FUNC; err = qlcnic_init_pci_info(adapter); @@ -821,8 +839,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) "HAL Version: %d, Privileged function\n", adapter->fw_hal_version); } - } else - adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; + } adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; @@ -836,9 +853,7 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) struct qlcnic_npar_info *npar; u8 i; - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->need_fw_reset || - adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->need_fw_reset) return 0; for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { @@ -894,8 +909,7 @@ qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) struct qlcnic_npar_info *npar; struct qlcnic_info nic_info; - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - !adapter->need_fw_reset || adapter->op_mode != QLCNIC_MGMT_FUNC) + if (!adapter->need_fw_reset) return 0; /* Set the NPAR config data after FW reset */ @@ -946,6 +960,28 @@ static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) return 0; } +static int +qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) +{ + int err; + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || + adapter->op_mode != QLCNIC_MGMT_FUNC) + return 0; + + err = qlcnic_set_default_offload_settings(adapter); + if (err) + return err; + + err = qlcnic_reset_npar_config(adapter); + if (err) + return err; + + qlcnic_dev_set_npar_ready(adapter); + + return err; +} + static int qlcnic_start_firmware(struct qlcnic_adapter *adapter) { @@ -991,20 +1027,17 @@ check_fw_status: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); - err = qlcnic_set_default_offload_settings(adapter); - if (err) - goto err_out; - err = qlcnic_reset_npar_config(adapter); - if (err) - goto err_out; - qlcnic_check_options(adapter); err = qlcnic_check_eswitch_mode(adapter); if (err) { dev_err(&adapter->pdev->dev, "Memory allocation failed for eswitch\n"); goto err_out; } - qlcnic_dev_set_npar_ready(adapter); + err = qlcnic_set_mgmt_operations(adapter); + if (err) + goto err_out; + + qlcnic_check_options(adapter); adapter->need_fw_reset = 0; qlcnic_release_firmware(adapter); @@ -2719,9 +2752,6 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) { - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode != QLCNIC_MGMT_FUNC) - return; if (qlcnic_api_lock(adapter)) return; @@ -3004,6 +3034,10 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) if (err) return err; + err = qlcnic_initialize_nic(adapter); + if (err) + return err; + qlcnic_check_options(adapter); adapter->need_fw_reset = 0; -- cgit v1.2.3 From 7613c87b2d805acf7c882935d47aa84d1947656f Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:48 +0000 Subject: qlcnic: fix mac anti spoof policy o Allow enabling/disabling mac anti spoof policy only for Non privilege functions. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index e0c6811610ab..9a3ebb8a8203 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -741,9 +741,9 @@ qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { adapter->flags &= ~QLCNIC_MACSPOOF; - if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) - if (esw_cfg->mac_anti_spoof) - adapter->flags |= QLCNIC_MACSPOOF; + + if (esw_cfg->mac_anti_spoof) + adapter->flags |= QLCNIC_MACSPOOF; qlcnic_set_netdev_features(adapter, esw_cfg); } @@ -3377,8 +3377,12 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg, int count) { + u32 op_mode; u8 pci_func; int i; + + op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE); + for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; if (pci_func >= QLCNIC_MAX_PCI_FUNC) @@ -3390,6 +3394,9 @@ validate_esw_config(struct qlcnic_adapter *adapter, switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: + if (QLC_DEV_GET_DRV(op_mode, pci_func) != + QLCNIC_NON_PRIV_FUNC) + esw_cfg[i].mac_anti_spoof = 0; break; case QLCNIC_ADD_VLAN: if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) -- cgit v1.2.3 From dcb50afff747d15fc2ffff762c08c325e4c229e5 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:49 +0000 Subject: qlcnic: fix panic while using eth_hdr o skb->mac_header is not set, so machine panics while using function eth_hdr. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 9a3ebb8a8203..789fe817cfca 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1991,6 +1991,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct qlcnic_skb_frag *buffrag; struct cmd_desc_type0 *hwdesc, *first_desc; struct pci_dev *pdev; + struct ethhdr *phdr; int i, k; u32 producer; @@ -2003,7 +2004,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } if (adapter->flags & QLCNIC_MACSPOOF) { - if (compare_ether_addr(eth_hdr(skb)->h_source, + phdr = (struct ethhdr *)skb->data; + if (compare_ether_addr(phdr->h_source, adapter->mac_addr)) goto drop_packet; } -- cgit v1.2.3 From 7373373d100e5aebe751af0b2609a9a01dad5ac1 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Tue, 31 Aug 2010 17:17:50 +0000 Subject: qlcnic: fix mac override capability o Rename mac_learning to mac_override o Added check in set_mac to return error if mac override is disabled. o Disabling mac_override only supported for Non priviledged functions. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 5 +++-- drivers/net/qlcnic/qlcnic_ctx.c | 13 +++++++------ drivers/net/qlcnic/qlcnic_main.c | 23 ++++++++++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 220370fac726..cd1a2e6f59d2 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -905,6 +905,7 @@ struct qlcnic_mac_req { #define QLCNIC_ADAPTER_INITIALIZED 0x80 #define QLCNIC_TAGGING_ENABLED 0x100 #define QLCNIC_MACSPOOF 0x200 +#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) @@ -1060,7 +1061,7 @@ struct qlcnic_npar_info { u8 enable_pm; u8 dest_npar; u8 discard_tagged; - u8 mac_learning; + u8 mac_override; u8 mac_anti_spoof; u8 promisc_mode; u8 offload_flags; @@ -1134,7 +1135,7 @@ struct qlcnic_esw_func_cfg { u8 host_vlan_tag; u8 promisc_mode; u8 discard_tagged; - u8 mac_learning; + u8 mac_override; u8 mac_anti_spoof; u8 offload_flags; u8 reserved[5]; diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index bd4b06b2d86d..95a821e0b66f 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -1100,10 +1100,11 @@ __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); dev_info(&adapter->pdev->dev, - "eSwitch port config for pci func%d\n", pci_func); + "eSwitch port config for pci func %d\n", pci_func); } else { dev_err(&adapter->pdev->dev, - "Failed to get eswitch port config%d\n", pci_func); + "Failed to get eswitch port config for pci func %d\n", + pci_func); } return err; } @@ -1142,7 +1143,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, arg1 &= ~BIT_4; if (!(esw_cfg->promisc_mode)) arg1 &= ~BIT_6; - if (!(esw_cfg->mac_learning)) + if (!(esw_cfg->mac_override)) arg1 &= ~BIT_7; if (!(esw_cfg->mac_anti_spoof)) arg2 &= ~BIT_0; @@ -1175,10 +1176,10 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, - "Failed to configure eswitch port%d\n", pci_func); + "Failed to configure eswitch pci func %d\n", pci_func); } else { dev_info(&adapter->pdev->dev, - "Configured eSwitch for port %d\n", pci_func); + "Configured eSwitch for pci func %d\n", pci_func); } return err; @@ -1202,7 +1203,7 @@ qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, esw_cfg->discard_tagged = !!(arg1 & BIT_4); esw_cfg->host_vlan_tag = !!(arg1 & BIT_5); esw_cfg->promisc_mode = !!(arg1 & BIT_6); - esw_cfg->mac_learning = !!(arg1 & BIT_7); + esw_cfg->mac_override = !!(arg1 & BIT_7); esw_cfg->vlan_id = LSW(arg1 >> 16); esw_cfg->mac_anti_spoof = (arg2 & 0x1); esw_cfg->offload_flags = ((arg2 >> 1) & 0x7); diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 789fe817cfca..130f4dbe2f4b 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -343,6 +343,9 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) struct qlcnic_adapter *adapter = netdev_priv(netdev); struct sockaddr *addr = p; + if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED)) + return -EOPNOTSUPP; + if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -741,10 +744,14 @@ qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { adapter->flags &= ~QLCNIC_MACSPOOF; + adapter->flags &= ~QLCNIC_MAC_OVERRIDE_DISABLED; if (esw_cfg->mac_anti_spoof) adapter->flags |= QLCNIC_MACSPOOF; + if (!esw_cfg->mac_override) + adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; + qlcnic_set_netdev_features(adapter, esw_cfg); } @@ -862,14 +869,14 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); esw_cfg.pci_func = i; esw_cfg.offload_flags = BIT_0; - esw_cfg.mac_learning = BIT_0; + esw_cfg.mac_override = BIT_0; if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) esw_cfg.offload_flags |= (BIT_1 | BIT_2); if (qlcnic_config_switch_port(adapter, &esw_cfg)) return -EIO; npar = &adapter->npars[i]; npar->pvid = esw_cfg.vlan_id; - npar->mac_learning = esw_cfg.offload_flags; + npar->mac_override = esw_cfg.mac_override; npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; npar->discard_tagged = esw_cfg.discard_tagged; npar->promisc_mode = esw_cfg.promisc_mode; @@ -887,7 +894,7 @@ qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; esw_cfg.pci_func = pci_func; esw_cfg.vlan_id = npar->pvid; - esw_cfg.mac_learning = npar->mac_learning; + esw_cfg.mac_override = npar->mac_override; esw_cfg.discard_tagged = npar->discard_tagged; esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; esw_cfg.offload_flags = npar->offload_flags; @@ -3042,6 +3049,10 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) qlcnic_check_options(adapter); + err = qlcnic_set_eswitch_port_config(adapter); + if (err) + return err; + adapter->need_fw_reset = 0; return err; @@ -3397,8 +3408,10 @@ validate_esw_config(struct qlcnic_adapter *adapter, switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: if (QLC_DEV_GET_DRV(op_mode, pci_func) != - QLCNIC_NON_PRIV_FUNC) + QLCNIC_NON_PRIV_FUNC) { esw_cfg[i].mac_anti_spoof = 0; + esw_cfg[i].mac_override = 1; + } break; case QLCNIC_ADD_VLAN: if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) @@ -3474,7 +3487,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: npar->promisc_mode = esw_cfg[i].promisc_mode; - npar->mac_learning = esw_cfg[i].mac_learning; + npar->mac_override = esw_cfg[i].mac_override; npar->offload_flags = esw_cfg[i].offload_flags; npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof; npar->discard_tagged = esw_cfg[i].discard_tagged; -- cgit v1.2.3 From b5e5492c0d49e2fd6f51961d03b8533435e5e7f5 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 31 Aug 2010 17:17:51 +0000 Subject: qlcnic: support mac learning Device eswitch need to configure with VM's mac address. Hypervisor doesn't provide any utility/callbacks to get VM's mac address. Unicast mac address filter improves performance and also provide packet loopback capability i.e communication between VM. Above features is by default off, can be turned on with module parameter 'mac_learn'. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 20 +++++++ drivers/net/qlcnic/qlcnic_hw.c | 48 +++++++++++++++ drivers/net/qlcnic/qlcnic_main.c | 123 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index cd1a2e6f59d2..4727204a2450 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -926,6 +926,21 @@ struct qlcnic_mac_req { #define QLCNIC_INTERRUPT_TEST 1 #define QLCNIC_LOOPBACK_TEST 2 +#define QLCNIC_FILTER_AGE 80 +#define QLCNIC_LB_MAX_FILTERS 64 + +struct qlcnic_filter { + struct hlist_node fnode; + u8 faddr[ETH_ALEN]; + unsigned long ftime; +}; + +struct qlcnic_filter_hash { + struct hlist_head *fhead; + u8 fnum; + u8 fmax; +}; + struct qlcnic_adapter { struct qlcnic_hardware_context ahw; @@ -934,6 +949,7 @@ struct qlcnic_adapter { struct list_head mac_list; spinlock_t tx_clean_lock; + spinlock_t mac_learn_lock; u16 num_txd; u16 num_rxd; @@ -1013,6 +1029,8 @@ struct qlcnic_adapter { struct qlcnic_nic_intr_coalesce coal; + struct qlcnic_filter_hash fhash; + unsigned long state; __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; @@ -1211,6 +1229,8 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); int qlcnic_get_board_info(struct qlcnic_adapter *adapter); int qlcnic_wol_supported(struct qlcnic_adapter *adapter); int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate); +void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter); +void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter); /* Functions from qlcnic_init.c */ int qlcnic_load_firmware(struct qlcnic_adapter *adapter); diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 670a54a84ba6..5b2bce59498d 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -491,6 +491,54 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter) } } +void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) +{ + struct qlcnic_filter *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + int i; + + for (i = 0; i < adapter->fhash.fmax; i++) { + head = &(adapter->fhash.fhead[i]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) + { + if (jiffies > + (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) { + qlcnic_sre_macaddr_change(adapter, + tmp_fil->faddr, QLCNIC_MAC_DEL); + spin_lock_bh(&adapter->mac_learn_lock); + adapter->fhash.fnum--; + hlist_del(&tmp_fil->fnode); + spin_unlock_bh(&adapter->mac_learn_lock); + kfree(tmp_fil); + } + } + } +} + +void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) +{ + struct qlcnic_filter *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + int i; + + for (i = 0; i < adapter->fhash.fmax; i++) { + head = &(adapter->fhash.fhead[i]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { + qlcnic_sre_macaddr_change(adapter, + tmp_fil->faddr, QLCNIC_MAC_DEL); + spin_lock_bh(&adapter->mac_learn_lock); + adapter->fhash.fnum--; + hlist_del(&tmp_fil->fnode); + spin_unlock_bh(&adapter->mac_learn_lock); + kfree(tmp_fil); + } + } +} + #define QLCNIC_CONFIG_INTR_COALESCE 3 /* diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 130f4dbe2f4b..0fbfb53f2594 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -50,6 +50,10 @@ static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; /* Default to restricted 1G auto-neg mode */ static int wol_port_mode = 5; +static int qlcnic_mac_learn; +module_param(qlcnic_mac_learn, int, 0644); +MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); + static int use_msi = 1; module_param(use_msi, int, 0644); MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled"); @@ -106,6 +110,8 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); static int qlcnic_start_firmware(struct qlcnic_adapter *); +static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); +static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); @@ -1201,6 +1207,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_free_mac_list(adapter); + if (adapter->fhash.fnum) + qlcnic_delete_lb_filters(adapter); + qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); qlcnic_napi_disable(adapter); @@ -1596,6 +1605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + qlcnic_alloc_lb_filters_mem(adapter); qlcnic_create_diag_entries(adapter); return 0; @@ -1647,6 +1657,8 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) clear_bit(__QLCNIC_RESETTING, &adapter->state); + qlcnic_free_lb_filters_mem(adapter); + qlcnic_teardown_intr(adapter); qlcnic_remove_diag_entries(adapter); @@ -1781,6 +1793,111 @@ static int qlcnic_close(struct net_device *netdev) return 0; } +static void +qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) +{ + void *head; + int i; + + if (!qlcnic_mac_learn) + return; + + spin_lock_init(&adapter->mac_learn_lock); + + head = kcalloc(QLCNIC_LB_MAX_FILTERS, sizeof(struct hlist_head), + GFP_KERNEL); + if (!head) + return; + + adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS; + adapter->fhash.fhead = (struct hlist_head *)head; + + for (i = 0; i < adapter->fhash.fmax; i++) + INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); +} + +static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) +{ + if (adapter->fhash.fmax && adapter->fhash.fhead) + kfree(adapter->fhash.fhead); + + adapter->fhash.fhead = NULL; + adapter->fhash.fmax = 0; +} + +static void qlcnic_change_filter(struct qlcnic_adapter *adapter, + u64 uaddr, struct qlcnic_host_tx_ring *tx_ring) +{ + struct cmd_desc_type0 *hwdesc; + struct qlcnic_nic_req *req; + struct qlcnic_mac_req *mac_req; + u32 producer; + u64 word; + + producer = tx_ring->producer; + hwdesc = &tx_ring->desc_head[tx_ring->producer]; + + req = (struct qlcnic_nic_req *)hwdesc; + memset(req, 0, sizeof(struct qlcnic_nic_req)); + req->qhdr = cpu_to_le64(QLCNIC_REQUEST << 23); + + word = QLCNIC_MAC_EVENT | ((u64)(adapter->portnum) << 16); + req->req_hdr = cpu_to_le64(word); + + mac_req = (struct qlcnic_mac_req *)&(req->words[0]); + mac_req->op = QLCNIC_MAC_ADD; + memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); + + tx_ring->producer = get_next_index(producer, tx_ring->num_desc); +} + +#define QLCNIC_MAC_HASH(MAC)\ + ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25)) + +static void +qlcnic_send_filter(struct qlcnic_adapter *adapter, + struct qlcnic_host_tx_ring *tx_ring, + struct cmd_desc_type0 *first_desc, + struct sk_buff *skb) +{ + struct ethhdr *phdr = (struct ethhdr *)(skb->data); + struct qlcnic_filter *fil, *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + u64 src_addr = 0; + u8 hindex; + + if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) + return; + + if (adapter->fhash.fnum >= adapter->fhash.fmax) + return; + + memcpy(&src_addr, phdr->h_source, ETH_ALEN); + hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); + head = &(adapter->fhash.fhead[hindex]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { + if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN)) { + tmp_fil->ftime = jiffies; + return; + } + } + + fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); + if (!fil) + return; + + qlcnic_change_filter(adapter, src_addr, tx_ring); + + fil->ftime = jiffies; + memcpy(fil->faddr, &src_addr, ETH_ALEN); + spin_lock(&adapter->mac_learn_lock); + hlist_add_head(&(fil->fnode), head); + adapter->fhash.fnum++; + spin_unlock(&adapter->mac_learn_lock); +} + static void qlcnic_tso_check(struct net_device *netdev, struct qlcnic_host_tx_ring *tx_ring, @@ -2090,6 +2207,9 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) qlcnic_tso_check(netdev, tx_ring, first_desc, skb); + if (qlcnic_mac_learn) + qlcnic_send_filter(adapter, tx_ring, first_desc, skb); + qlcnic_update_cmd_producer(adapter, tx_ring); adapter->stats.txbytes += skb->len; @@ -2900,6 +3020,9 @@ qlcnic_fw_poll_work(struct work_struct *work) if (qlcnic_check_health(adapter)) return; + if (adapter->fhash.fnum) + qlcnic_prune_lb_filters(adapter); + reschedule: qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); } -- cgit v1.2.3 From 03c5d770c24cd673d105fbf1a9706ae838272091 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 31 Aug 2010 17:17:52 +0000 Subject: qlcnic: mac vlan learning support Hypervisor allows, two VM's interfaces to have same mac address. These VM's interfaces get differentiate with Vlan tag. This patch add support to learn and configure mac+vlan filter on device. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 3 +++ drivers/net/qlcnic/qlcnic_hw.c | 17 +++++++++++------ drivers/net/qlcnic/qlcnic_main.c | 16 ++++++++++++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 4727204a2450..9d211529fa16 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -722,6 +722,8 @@ struct qlcnic_cardrsp_tx_ctx { #define QLCNIC_MAC_NOOP 0 #define QLCNIC_MAC_ADD 1 #define QLCNIC_MAC_DEL 2 +#define QLCNIC_MAC_VLAN_ADD 3 +#define QLCNIC_MAC_VLAN_DEL 4 struct qlcnic_mac_list_s { struct list_head list; @@ -932,6 +934,7 @@ struct qlcnic_mac_req { struct qlcnic_filter { struct hlist_node fnode; u8 faddr[ETH_ALEN]; + u16 vlan_id; unsigned long ftime; }; diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 5b2bce59498d..c198df90ff3c 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -375,7 +375,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, static int qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, - unsigned op) + u16 vlan_id, unsigned op) { struct qlcnic_nic_req req; struct qlcnic_mac_req *mac_req; @@ -391,6 +391,8 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, mac_req->op = op; memcpy(mac_req->mac_addr, addr, 6); + req.words[1] = cpu_to_le64(vlan_id); + return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } @@ -415,7 +417,7 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) memcpy(cur->mac_addr, addr, ETH_ALEN); if (qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_ADD)) { + cur->mac_addr, 0, QLCNIC_MAC_ADD)) { kfree(cur); return -EIO; } @@ -485,7 +487,7 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter) while (!list_empty(head)) { cur = list_entry(head->next, struct qlcnic_mac_list_s, list); qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_DEL); + cur->mac_addr, 0, QLCNIC_MAC_DEL); list_del(&cur->list); kfree(cur); } @@ -506,7 +508,9 @@ void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) if (jiffies > (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) { qlcnic_sre_macaddr_change(adapter, - tmp_fil->faddr, QLCNIC_MAC_DEL); + tmp_fil->faddr, tmp_fil->vlan_id, + tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL : + QLCNIC_MAC_DEL); spin_lock_bh(&adapter->mac_learn_lock); adapter->fhash.fnum--; hlist_del(&tmp_fil->fnode); @@ -528,8 +532,9 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) head = &(adapter->fhash.fhead[i]); hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { - qlcnic_sre_macaddr_change(adapter, - tmp_fil->faddr, QLCNIC_MAC_DEL); + qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr, + tmp_fil->vlan_id, tmp_fil->vlan_id ? + QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL); spin_lock_bh(&adapter->mac_learn_lock); adapter->fhash.fnum--; hlist_del(&tmp_fil->fnode); diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 0fbfb53f2594..5a6445a691b3 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1826,7 +1826,7 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) } static void qlcnic_change_filter(struct qlcnic_adapter *adapter, - u64 uaddr, struct qlcnic_host_tx_ring *tx_ring) + u64 uaddr, u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) { struct cmd_desc_type0 *hwdesc; struct qlcnic_nic_req *req; @@ -1845,9 +1845,11 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter, req->req_hdr = cpu_to_le64(word); mac_req = (struct qlcnic_mac_req *)&(req->words[0]); - mac_req->op = QLCNIC_MAC_ADD; + mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); + req->words[1] = cpu_to_le64(vlan_id); + tx_ring->producer = get_next_index(producer, tx_ring->num_desc); } @@ -1865,6 +1867,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, struct hlist_node *tmp_hnode, *n; struct hlist_head *head; u64 src_addr = 0; + u16 vlan_id = 0; u8 hindex; if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) @@ -1873,12 +1876,16 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, if (adapter->fhash.fnum >= adapter->fhash.fmax) return; + /* Only NPAR capable devices support vlan based learning*/ + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + vlan_id = first_desc->vlan_TCI; memcpy(&src_addr, phdr->h_source, ETH_ALEN); hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); head = &(adapter->fhash.fhead[hindex]); hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { - if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN)) { + if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && + tmp_fil->vlan_id == vlan_id) { tmp_fil->ftime = jiffies; return; } @@ -1888,9 +1895,10 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, if (!fil) return; - qlcnic_change_filter(adapter, src_addr, tx_ring); + qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring); fil->ftime = jiffies; + fil->vlan_id = vlan_id; memcpy(fil->faddr, &src_addr, ETH_ALEN); spin_lock(&adapter->mac_learn_lock); hlist_add_head(&(fil->fnode), head); -- cgit v1.2.3 From d807b3f728518d218fb2fe54c1227bc6d6f93efd Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 31 Aug 2010 17:17:53 +0000 Subject: qlcnic: add cksum flag o New CKSUM flag added by fw to notify cksum is verified. o Update version to 5.0.9 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 7 ++++--- drivers/net/qlcnic/qlcnic_init.c | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9d211529fa16..cc8385a6727e 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 8 -#define QLCNIC_LINUX_VERSIONID "5.0.8" +#define _QLCNIC_LINUX_SUBVERSION 9 +#define QLCNIC_LINUX_VERSIONID "5.0.9" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -224,7 +224,8 @@ struct rcv_desc { #define QLCNIC_LRO_DESC 0x12 /* for status field in status_desc */ -#define STATUS_CKSUM_OK (2) +#define STATUS_CKSUM_LOOP 0 +#define STATUS_CKSUM_OK 2 /* owner bits of status_desc */ #define STATUS_OWNER_HOST (0x1ULL << 56) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 8e0e7a3bbf9e..8e47d7aea562 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1364,7 +1364,8 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, skb = buffer->skb; - if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) { + if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK || + cksum == STATUS_CKSUM_LOOP))) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else { -- cgit v1.2.3 From 8ca60a68a9fd61b4cf31b48d9c365b07e5588bbe Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:17 +0000 Subject: bnx2x: Fix potential link issue of BCM8073/BCM8727 Fix potential link issue caused by insufficient delay time during SPIROM load of BCM8073/BCM8727 Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 0fa09913051d..9b4e7b3261aa 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -2549,8 +2549,8 @@ static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* wait for 100ms for code download via SPI port */ - msleep(100); + /* wait for 120ms for code download via SPI port */ + msleep(120); /* Clear ser_boot_ctl bit */ bnx2x_cl45_write(bp, port, -- cgit v1.2.3 From eb80ce740a7e1deda5bedb9b5df876ce84ac5bc2 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:20 +0000 Subject: bnx2x: Fix potential link issue In BCM8727 based boards In BCM8727 based boards, setting default 10G link speed after link was set to 1G may lead to link down issue. The problem was setting the right value, but to the wrong registers Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 23 +++++++++++++---------- drivers/net/bnx2x/bnx2x_reg.h | 2 ++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 9b4e7b3261aa..cbacf8a7c65f 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -4239,8 +4239,10 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } else if ((params->req_line_speed == SPEED_AUTO_NEG) && ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { - + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && + ((params->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); bnx2x_cl45_write(bp, params->port, ext_phy_type, ext_phy_addr, MDIO_AN_DEVAD, @@ -4253,17 +4255,18 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) need to set the 10G registers although it is default */ bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x0020); + ext_phy_addr, MDIO_AN_DEVAD, + MDIO_AN_REG_8727_MISC_CTRL, + 0x0020); bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - 0x7, 0x0100); + ext_phy_addr, MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_AN, 0x0100); bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x2040); + ext_phy_addr, MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x2040); bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0x0008); + ext_phy_addr, MDIO_PMA_DEVAD, + MDIO_PMA_REG_10G_CTRL2, 0x0008); } /* Set 2-wire transfer rate of SFP+ module EEPROM diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index a1f3bf0cd630..c82e261020e2 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5211,6 +5211,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_8073_2_5G 0x8329 +#define MDIO_AN_REG_8727_MISC_CTRL 0x8309 + #define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0 #define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4 #define MDIO_AN_REG_8481_1000T_CTRL 0xffe9 -- cgit v1.2.3 From 54c2fb785965a666a3e79dda16896801dfcf34e9 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:23 +0000 Subject: bnx2x: Reset link before any new link settings Reset link before any new link settings to avoid potential link issue caused by previous link settings Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7fb9a61a73c7..b09fa04cbc1d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1292,6 +1292,7 @@ void bnx2x_link_set(struct bnx2x *bp) { if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); + bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1); bnx2x_phy_init(&bp->link_params, &bp->link_vars); bnx2x_release_phy_lock(bp); -- cgit v1.2.3 From ac4d944910d4d4e9cc520f304f2fa2eb54e9677c Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:25 +0000 Subject: bnx2x: Change BCM848xx configuration according to IEEE Change BCM848xx behavior to fit IEEE such that setting 10Mb/100Mb will use force speed, and setting 1Gb/10Gb will use auto-negotiation with the specific speed advertised Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 288 ++++++++++++++++++----------------------- drivers/net/bnx2x/bnx2x_reg.h | 3 +- 2 files changed, 127 insertions(+), 164 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index cbacf8a7c65f..7a8df7a2f4da 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -4354,197 +4354,159 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + { /* This phy uses the NIG latch mechanism since link indication arrives through its LED4 and not via its LASI signal, so we get steady signal instead of clear on read */ + u16 autoneg_val, an_1000_val, an_10_100_val; bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, - 1 << NIG_LATCH_BC_ENABLE_MI_INT); + 1 << NIG_LATCH_BC_ENABLE_MI_INT); bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x0000); + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x0000); bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr); - if (params->req_line_speed == SPEED_AUTO_NEG) { - u16 autoneg_val, an_1000_val, an_10_100_val; - /* set 1000 speed advertisement */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - &an_1000_val); - - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { - an_1000_val |= (1<<8); - if (params->req_duplex == DUPLEX_FULL) - an_1000_val |= (1<<9); - DP(NETIF_MSG_LINK, "Advertising 1G\n"); - } else - an_1000_val &= ~((1<<8) | (1<<9)); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - an_1000_val); - - /* set 100 speed advertisement */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - &an_10_100_val); - - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) { - an_10_100_val |= (1<<7); - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<8); - DP(NETIF_MSG_LINK, - "Advertising 100M\n"); - } else - an_10_100_val &= ~((1<<7) | (1<<8)); - - /* set 10 speed advertisement */ - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) { - an_10_100_val |= (1<<5); - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<6); - DP(NETIF_MSG_LINK, "Advertising 10M\n"); - } - else - an_10_100_val &= ~((1<<5) | (1<<6)); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - an_10_100_val); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_val); - - /* Disable forced speed */ - autoneg_val &= ~(1<<6|1<<13); + bnx2x_cl45_read(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_1000T_CTRL, + &an_1000_val); + bnx2x_ext_phy_set_pause(params, vars); + bnx2x_cl45_read(bp, params->port, ext_phy_type, + ext_phy_addr, MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_ADV, + &an_10_100_val); + bnx2x_cl45_read(bp, params->port, ext_phy_type, + ext_phy_addr, MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_CTRL, + &autoneg_val); + /* Disable forced speed */ + autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | + (1<<13)); + an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); + + if (((params->req_line_speed == SPEED_AUTO_NEG) && + (params->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (params->req_line_speed == SPEED_1000)) { + an_1000_val |= (1<<8); + autoneg_val |= (1<<9 | 1<<12); + if (params->req_duplex == DUPLEX_FULL) + an_1000_val |= (1<<9); + DP(NETIF_MSG_LINK, "Advertising 1G\n"); + } else + an_1000_val &= ~((1<<8) | (1<<9)); - /* Enable autoneg and restart autoneg - for legacy speeds */ - autoneg_val |= (1<<9|1<<12); + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_1000T_CTRL, + an_1000_val); + + /* set 10 speed advertisement */ + if (((params->req_line_speed == SPEED_AUTO_NEG) && + (params->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + an_10_100_val |= (1<<7); + /* + * Enable autoneg and restart autoneg for + * legacy speeds + */ + autoneg_val |= (1<<9 | 1<<12); if (params->req_duplex == DUPLEX_FULL) - autoneg_val |= (1<<8); - else - autoneg_val &= ~(1<<8); + an_10_100_val |= (1<<8); + DP(NETIF_MSG_LINK, "Advertising 100M\n"); + } + /* set 10 speed advertisement */ + if (((params->req_line_speed == SPEED_AUTO_NEG) && + (params->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + if (params->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<6); + DP(NETIF_MSG_LINK, "Advertising 10M\n"); + } + /* Only 10/100 are allowed to work in FORCE mode */ + if (params->req_line_speed == SPEED_100) { + autoneg_val |= (1<<13); + /* Enabled AUTO-MDIX when autoneg is disabled */ bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - autoneg_val); - - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { - DP(NETIF_MSG_LINK, "Advertising 10G\n"); - /* Restart autoneg for 10G*/ + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 100M force\n"); + } + if (params->req_line_speed == SPEED_10) { + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 10M force\n"); + } bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x3200); - } - } else { - /* Force speed */ - u16 autoneg_ctrl, pma_ctrl; - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_ctrl); + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_ADV, + an_10_100_val); - /* Disable autoneg */ - autoneg_ctrl &= ~(1<<12); + if (params->req_duplex == DUPLEX_FULL) + autoneg_val |= (1<<8); - /* Set 1000 force */ - switch (params->req_line_speed) { - case SPEED_10000: - DP(NETIF_MSG_LINK, - "Unable to set 10G force !\n"); - break; - case SPEED_1000: - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - &pma_ctrl); - autoneg_ctrl &= ~(1<<13); - autoneg_ctrl |= (1<<6); - pma_ctrl &= ~(1<<13); - pma_ctrl |= (1<<6); - DP(NETIF_MSG_LINK, - "Setting 1000M force\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - pma_ctrl); - break; - case SPEED_100: - autoneg_ctrl |= (1<<13); - autoneg_ctrl &= ~(1<<6); - DP(NETIF_MSG_LINK, - "Setting 100M force\n"); - break; - case SPEED_10: - autoneg_ctrl &= ~(1<<13); - autoneg_ctrl &= ~(1<<6); - DP(NETIF_MSG_LINK, - "Setting 10M force\n"); - break; - } + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_CTRL, + autoneg_val); - /* Duplex mode */ - if (params->req_duplex == DUPLEX_FULL) { - autoneg_ctrl |= (1<<8); - DP(NETIF_MSG_LINK, - "Setting full duplex\n"); - } else - autoneg_ctrl &= ~(1<<8); + if (((params->req_line_speed == SPEED_AUTO_NEG) && + (params->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || + (params->req_line_speed == SPEED_10000)) { + DP(NETIF_MSG_LINK, "Advertising 10G\n"); + /* Restart autoneg for 10G*/ - /* Update autoneg ctrl and pma ctrl */ bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - autoneg_ctrl); - } + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_CTRL, + 0x3200); + + } else if (params->req_line_speed != SPEED_10 && + params->req_line_speed != SPEED_100) + bnx2x_cl45_write(bp, params->port, + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, + 1); /* Save spirom version */ bnx2x_save_8481_spirom_version(bp, params->port, ext_phy_addr, params->shmem_base); break; + } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: DP(NETIF_MSG_LINK, "XGXS PHY Failure detected 0x%x\n", diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index c82e261020e2..398961772bb5 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5212,12 +5212,13 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_8073_2_5G 0x8329 #define MDIO_AN_REG_8727_MISC_CTRL 0x8309 - +#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0 #define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4 #define MDIO_AN_REG_8481_1000T_CTRL 0xffe9 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7 +#define MDIO_AN_REG_8481_AUX_CTRL 0xfff8 #define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc #define IGU_FUNC_BASE 0x0400 -- cgit v1.2.3 From 6f4ca066bc08877647aff2a7d68e36d14d06cb16 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:30 +0000 Subject: bnx2x: Remove unneeded setting of XAUI low power to BCM8727 Remove unneeded setting of XAUI low power to BCM8727. This was required only in older microcode which is not in the field. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7a8df7a2f4da..e2945b4695a8 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -4200,7 +4200,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) val); bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); - bnx2x_bcm8073_set_xaui_low_power_mode(params); bnx2x_cl45_read(bp, params->port, ext_phy_type, -- cgit v1.2.3 From a1e4be39dc5a8d83102b835a3ee049f2a6057be9 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:33 +0000 Subject: bnx2x: Change BCM848xx LED configuration Change 848xx LED configuration according to the new microcode (Boards were shipped with only with the new microcode) Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 171 ++++++++++++----------------------------- 1 file changed, 49 insertions(+), 122 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e2945b4695a8..8fce54cd6ba5 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -2203,6 +2203,10 @@ static void bnx2x_ext_phy_reset(struct link_params *params, 1<<15); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + params->port); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n"); @@ -3477,112 +3481,54 @@ static void bnx2x_set_preemphasis(struct link_params *params) } -static void bnx2x_8481_set_led4(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) -{ - struct bnx2x *bp = params->bp; - - /* PHYC_CTL_LED_CTL */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482); - - /* Unmask LED4 for 10G link */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6)); - /* 'Interrupt Mask' */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - 0xFFFB, 0xFFFD); -} -static void bnx2x_8481_set_legacy_led_mode(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) -{ - struct bnx2x *bp = params->bp; - - /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */ - /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_SHADOW, - (1<<15) | (0xd << 10) | (0xc<<4) | 0xe); -} - -static void bnx2x_8481_set_10G_led_mode(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) +static void bnx2x_8481_set_led(struct link_params *params, + u32 ext_phy_type, u8 ext_phy_addr) { struct bnx2x *bp = params->bp; - u16 val1; - - /* LED1 (10G Link) */ - /* Enable continuse based on source 7(10G-link) */ + u16 val; bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, - &val1); - /* Set bit 2 to 0, and bits [1:0] to 10 */ - val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/ - val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */ + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, &val); + val &= 0xFE00; + val |= 0x0092; bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, - val1); + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, val); - /* Unmask LED1 for 10G link */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - &val1); - /* Set bit 2 to 0, and bits [1:0] to 10 */ - val1 |= (1<<7); bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - val1); + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x80); - /* LED2 (1G/100/10G Link) */ - /* Mask LED2 for 10G link */ bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0); + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x18); - /* Unmask LED3 for 10G link */ bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x6); + ext_phy_type, + ext_phy_addr, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0040); + + /* 'Interrupt Mask' */ bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_BLINK, - 0); + ext_phy_type, + ext_phy_addr, + MDIO_AN_DEVAD, + 0xFFFB, 0xFFFD); } - static void bnx2x_init_internal_phy(struct link_params *params, struct link_vars *vars, u8 enable_cl73) @@ -4358,7 +4304,13 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) indication arrives through its LED4 and not via its LASI signal, so we get steady signal instead of clear on read */ - u16 autoneg_val, an_1000_val, an_10_100_val; + u16 autoneg_val, an_1000_val, an_10_100_val, temp; + temp = vars->line_speed; + vars->line_speed = SPEED_10000; + bnx2x_set_autoneg(params, vars, 0); + bnx2x_program_serdes(params, vars); + vars->line_speed = temp; + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -4368,7 +4320,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); - bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr); + bnx2x_8481_set_led(params, ext_phy_type, ext_phy_addr); bnx2x_cl45_read(bp, params->port, ext_phy_type, @@ -5184,9 +5136,6 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, if (val2 & (1<<11)) { vars->line_speed = SPEED_10000; ext_phy_link_up = 1; - bnx2x_8481_set_10G_led_mode(params, - ext_phy_type, - ext_phy_addr); } else { /* Check Legacy speed link */ u16 legacy_status, legacy_speed; @@ -5234,9 +5183,6 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, "= %d\n", vars->line_speed, (vars->duplex == DUPLEX_FULL)); - bnx2x_8481_set_legacy_led_mode(params, - ext_phy_type, - ext_phy_addr); } } break; @@ -6191,18 +6137,9 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + params->port); break; } default: @@ -6617,13 +6554,6 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - -static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base) -{ - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, 1); - return 0; -} u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) { u8 rc = 0; @@ -6654,9 +6584,6 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) it for single port alone */ rc = bnx2x_8726_common_init_phy(bp, shmem_base); break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - rc = bnx2x_84823_common_init_phy(bp, shmem_base); - break; default: DP(NETIF_MSG_LINK, "bnx2x_common_init_phy: ext_phy 0x%x not required\n", -- cgit v1.2.3 From 9a8a97e88ea893522779aecbc0ff3d7361f49c12 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:35 +0000 Subject: bnx2x: Add BCM84823 to the supported PHYs Add BCM84823 to the supported PHYs Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b09fa04cbc1d..993d7e83f1d3 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6226,7 +6226,8 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n", + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM848xx)\n", ext_phy_type); bp->port.supported |= (SUPPORTED_10baseT_Half | -- cgit v1.2.3 From 064270132602c6e11482439e0e257f208cae79c0 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 1 Sep 2010 09:51:37 +0000 Subject: bnx2x: Update version to 1.52.53-5 Update version to 1.52.53-5 Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 0c2d96ed561c..a019c67d2995 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-4" -#define DRV_MODULE_RELDATE "2010/16/08" +#define DRV_MODULE_VERSION "1.52.53-5" +#define DRV_MODULE_RELDATE "2010/01/09" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- cgit v1.2.3 From 875168a9330d3aa6481ce62ce8fa77c7be0c75fb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 30 Aug 2010 11:07:25 +0000 Subject: net: tunnels should use rcu_dereference tunnel4_handlers, tunnel64_handlers, tunnel6_handlers and tunnel46_handlers are protected by RCU, but we dont use appropriate rcu primitives to scan them. rcu_lock() is already held by caller. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tunnel4.c | 13 +++++++++---- net/ipv6/tunnel6.c | 11 ++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 942f02da07d8..df59d16337f2 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -73,6 +73,11 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) } EXPORT_SYMBOL(xfrm4_tunnel_deregister); +#define for_each_tunnel_rcu(head, handler) \ + for (handler = rcu_dereference(head); \ + handler != NULL; \ + handler = rcu_dereference(handler->next)) \ + static int tunnel4_rcv(struct sk_buff *skb) { struct xfrm_tunnel *handler; @@ -80,7 +85,7 @@ static int tunnel4_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto drop; - for (handler = tunnel4_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel4_handlers, handler) if (!handler->handler(skb)) return 0; @@ -99,7 +104,7 @@ static int tunnel64_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; - for (handler = tunnel64_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel64_handlers, handler) if (!handler->handler(skb)) return 0; @@ -115,7 +120,7 @@ static void tunnel4_err(struct sk_buff *skb, u32 info) { struct xfrm_tunnel *handler; - for (handler = tunnel4_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel4_handlers, handler) if (!handler->err_handler(skb, info)) break; } @@ -125,7 +130,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info) { struct xfrm_tunnel *handler; - for (handler = tunnel64_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel64_handlers, handler) if (!handler->err_handler(skb, info)) break; } diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index d203e6df1f8b..3177fe0459e0 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -88,6 +88,11 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) EXPORT_SYMBOL(xfrm6_tunnel_deregister); +#define for_each_tunnel_rcu(head, handler) \ + for (handler = rcu_dereference(head); \ + handler != NULL; \ + handler = rcu_dereference(handler->next)) \ + static int tunnel6_rcv(struct sk_buff *skb) { struct xfrm6_tunnel *handler; @@ -95,7 +100,7 @@ static int tunnel6_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; - for (handler = tunnel6_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel6_handlers, handler) if (!handler->handler(skb)) return 0; @@ -113,7 +118,7 @@ static int tunnel46_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto drop; - for (handler = tunnel46_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel46_handlers, handler) if (!handler->handler(skb)) return 0; @@ -129,7 +134,7 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, { struct xfrm6_tunnel *handler; - for (handler = tunnel6_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel6_handlers, handler) if (!handler->err_handler(skb, opt, type, code, offset, info)) break; } -- cgit v1.2.3 From 1a9f28c8f94659a70f34f0f2ab12371c0745518d Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 30 Aug 2010 21:19:15 +0000 Subject: ns83820: Use helper to disable chip interrupts Use helper routine to disable chip interrupts. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 5a3488f76b38..447c2c43769a 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1405,6 +1405,13 @@ static const struct ethtool_ops ops = { .get_link = ns83820_get_link }; +static inline void ns83820_disable_interrupts(struct ns83820 *dev) +{ + writel(0, dev->base + IMR); + writel(0, dev->base + IER); + readl(dev->base + IER); +} + /* this function is called in irq context from the ISR */ static void ns83820_mib_isr(struct ns83820 *dev) { @@ -1557,10 +1564,7 @@ static int ns83820_stop(struct net_device *ndev) /* FIXME: protect against interrupt handler? */ del_timer_sync(&dev->tx_watchdog); - /* disable interrupts */ - writel(0, dev->base + IMR); - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); dev->rx_info.up = 0; synchronize_irq(dev->pci_dev->irq); @@ -2023,10 +2027,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, dev->tx_descs, (long)dev->tx_phy_descs, dev->rx_info.descs, (long)dev->rx_info.phy_descs); - /* disable interrupts */ - writel(0, dev->base + IMR); - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); dev->IMR_cache = 0; @@ -2250,9 +2251,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, return 0; out_cleanup: - writel(0, dev->base + IMR); /* paranoia */ - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); /* paranoia */ out_free_irq: rtnl_unlock(); free_irq(pci_dev->irq, ndev); @@ -2277,9 +2276,7 @@ static void __devexit ns83820_remove_one(struct pci_dev *pci_dev) if (!ndev) /* paranoia */ return; - writel(0, dev->base + IMR); /* paranoia */ - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); /* paranoia */ unregister_netdev(ndev); free_irq(dev->pci_dev->irq, ndev); -- cgit v1.2.3 From aed5029ead26fe47527d9e9f2052cf56b72543f0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 31 Aug 2010 07:44:00 +0000 Subject: drivers/net/can/mscan/mpc5xxx_can.c: Add of_node_put to avoid memory leak Add a call to of_node_put in the error handling code following a call to of_find_matching_node. This patch also moves the existing call to of_node_put after the call to iounmap in the error handling code, to make it possible to jump to of_node_put without doing iounmap. These appear to be disjoint operations, so the ordering doesn't matter. This patch furthermore changes the -ENODEV result in the error handling code for of_find_matching_node to a return of 0, as found in the error handling code for of_iomap, because the return type of the function is unsigned. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ local idexpression x; expression E,E1,E2; statement S; @@ *x = (of_find_node_by_path |of_find_node_by_name |of_find_node_by_phandle |of_get_parent |of_get_next_parent |of_get_next_child |of_find_compatible_node |of_match_node |of_find_node_by_type |of_find_node_with_property |of_find_matching_node |of_parse_phandle )(...); ... if (x == NULL) S <... when != x = E *if (...) { ... when != of_node_put(x) when != if (...) { ... of_node_put(x); ... } ( return <+...x...+>; | * return ...; ) } ...> ( E2 = x; | of_node_put(x); ) // Signed-off-by: Julia Lawall Reviewed-by: Wolfram Sang Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/mscan/mpc5xxx_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index b1bdc909090f..312b9c8f4f3b 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -143,12 +143,12 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, np_clock = of_find_matching_node(NULL, mpc512x_clock_ids); if (!np_clock) { dev_err(&ofdev->dev, "couldn't find clock node\n"); - return -ENODEV; + return 0; } clockctl = of_iomap(np_clock, 0); if (!clockctl) { dev_err(&ofdev->dev, "couldn't map clock registers\n"); - return 0; + goto exit_put; } /* Determine the MSCAN device index from the physical address */ @@ -233,9 +233,9 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv); exit_unmap: - of_node_put(np_clock); iounmap(clockctl); - +exit_put: + of_node_put(np_clock); return freq; } #else /* !CONFIG_PPC_MPC512x */ -- cgit v1.2.3 From 86cac58b71227cc34a3d0e78f19585c0eff49ea3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 31 Aug 2010 18:25:32 +0000 Subject: skge: add GRO support - napi_gro_flush() is exported from net/core/dev.c, to avoid an irq_save/irq_restore in the packet receive path. - use napi_gro_receive() instead of netif_receive_skb() - use napi_gro_flush() before calling __napi_complete() - turn on NETIF_F_GRO by default - Tested on a Marvell 88E8001 Gigabit NIC Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/skge.c | 5 +++-- include/linux/netdevice.h | 1 + net/core/dev.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 40e5c46e7571..a8a63581d63d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3178,8 +3178,7 @@ static int skge_poll(struct napi_struct *napi, int to_do) skb = skge_rx_get(dev, e, control, rd->status, rd->csum2); if (likely(skb)) { - netif_receive_skb(skb); - + napi_gro_receive(napi, skb); ++work_done; } } @@ -3192,6 +3191,7 @@ static int skge_poll(struct napi_struct *napi, int to_do) if (work_done < to_do) { unsigned long flags; + napi_gro_flush(napi); spin_lock_irqsave(&hw->hw_lock, flags); __napi_complete(napi); hw->intr_mask |= napimask[skge->port]; @@ -3849,6 +3849,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; skge->rx_csum = 1; } + dev->features |= NETIF_F_GRO; /* read the mac address */ memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c82220a9f3d5..af05186d5b36 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1702,6 +1702,7 @@ extern gro_result_t dev_gro_receive(struct napi_struct *napi, extern gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb); extern gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); +extern void napi_gro_flush(struct napi_struct *napi); extern void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb); extern struct sk_buff * napi_get_frags(struct napi_struct *napi); diff --git a/net/core/dev.c b/net/core/dev.c index 63bd20a75929..d8c43e73f0b7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3063,7 +3063,7 @@ out: return netif_receive_skb(skb); } -static void napi_gro_flush(struct napi_struct *napi) +inline void napi_gro_flush(struct napi_struct *napi) { struct sk_buff *skb, *next; @@ -3076,6 +3076,7 @@ static void napi_gro_flush(struct napi_struct *napi) napi->gro_count = 0; napi->gro_list = NULL; } +EXPORT_SYMBOL(napi_gro_flush); enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { -- cgit v1.2.3 From 6602cebb5bcac1fccf2850541f8bf9fcc8c86dee Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 1 Sep 2010 05:25:10 +0000 Subject: net: skbuff.c cleanup (skb->data - skb->head) can be changed by skb_headroom(skb) Remove some uses of NET_SKBUFF_DATA_USES_OFFSET, using (skb_end_pointer(skb) - skb->head) or (skb_tail_pointer(skb) - skb->head) : compiler does the right thing, and this is more readable for us ;) (struct skb_shared_info *) casts in pskb_expand_head() to help memcpy() to use aligned moves. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/skbuff.c | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index e2535fb4985d..231dff0dde2e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -685,16 +685,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) { - int headerlen = skb->data - skb->head; - /* - * Allocate the copy buffer - */ - struct sk_buff *n; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - n = alloc_skb(skb->end + skb->data_len, gfp_mask); -#else - n = alloc_skb(skb->end - skb->head + skb->data_len, gfp_mask); -#endif + int headerlen = skb_headroom(skb); + unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len; + struct sk_buff *n = alloc_skb(size, gfp_mask); + if (!n) return NULL; @@ -726,20 +720,14 @@ EXPORT_SYMBOL(skb_copy); struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) { - /* - * Allocate the copy buffer - */ - struct sk_buff *n; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - n = alloc_skb(skb->end, gfp_mask); -#else - n = alloc_skb(skb->end - skb->head, gfp_mask); -#endif + unsigned int size = skb_end_pointer(skb) - skb->head; + struct sk_buff *n = alloc_skb(size, gfp_mask); + if (!n) goto out; /* Set the data pointer */ - skb_reserve(n, skb->data - skb->head); + skb_reserve(n, skb_headroom(skb)); /* Set the tail pointer and length */ skb_put(n, skb_headlen(skb)); /* Copy the bytes */ @@ -791,11 +779,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, { int i; u8 *data; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - int size = nhead + skb->end + ntail; -#else - int size = nhead + (skb->end - skb->head) + ntail; -#endif + int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail; long off; BUG_ON(nhead < 0); @@ -810,13 +794,12 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, goto nodata; /* Copy only real data... and, alas, header. This should be - * optimized for the cases when header is void. */ -#ifdef NET_SKBUFF_DATA_USES_OFFSET - memcpy(data + nhead, skb->head, skb->tail); -#else - memcpy(data + nhead, skb->head, skb->tail - skb->head); -#endif - memcpy(data + size, skb_end_pointer(skb), + * optimized for the cases when header is void. + */ + memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head); + + memcpy((struct skb_shared_info *)(data + size), + skb_shinfo(skb), offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -- cgit v1.2.3 From 85f72bc839705294b32b6c16b491c0422f0a71b3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 1 Sep 2010 16:12:28 -0400 Subject: mac80211: only cancel software-based scans on suspend Otherwise the hardware scan handler could access an invalid scan request structure. The driver should cancel any pending hardware scans during the suspend process anyway, so also add a warning if the hardware scan is still pending when the device resumes. Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 6 ++++++ net/mac80211/pm.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 16f7fb164c2d..4e635e2fabdb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1186,6 +1186,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw); static inline int __ieee80211_resume(struct ieee80211_hw *hw) { + struct ieee80211_local *local = hw_to_local(hw); + + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + "%s: resume with hardware scan still in progress\n", + wiphy_name(hw->wiphy)); + return ieee80211_reconfig(hw_to_local(hw)); } #else diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index d287fde0431d..ce671dfd238c 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -12,7 +12,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) struct ieee80211_sub_if_data *sdata; struct sta_info *sta; - ieee80211_scan_cancel(local); + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) + ieee80211_scan_cancel(local); ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); -- cgit v1.2.3 From 6267300e979e0fa912d871c7727c168bf3dbb37a Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Mon, 30 Aug 2010 13:06:20 +0000 Subject: pxa168_eth: remove duplicated #include Remove duplicated #include('s) in drivers/net/pxa168_eth.c Signed-off-by: Huang Weiyi Signed-off-by: David S. Miller --- drivers/net/pxa168_eth.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index ecc64d750cce..659915cf6872 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -42,8 +42,6 @@ #include #include #include -#include -#include #include #include -- cgit v1.2.3 From fa50d6457691d5c2d8a3430abf950435ef129cf1 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 31 Aug 2010 12:14:13 +0000 Subject: net: make rx_queue sysfs_ops const Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/net-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 7d748542d97e..76485a3f910b 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -515,7 +515,7 @@ static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr, return attribute->store(queue, attribute, buf, count); } -static struct sysfs_ops rx_queue_sysfs_ops = { +static const struct sysfs_ops rx_queue_sysfs_ops = { .show = rx_queue_attr_show, .store = rx_queue_attr_store, }; -- cgit v1.2.3 From 0705c6f0e2d39333645bf77cf1efb94526ff1f82 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 1 Sep 2010 00:28:35 +0000 Subject: tcp: update also tcp_output with regard to RFC 5681 Thanks to Ilpo Jarvinen, this updates also the initial window setting for tcp_output with regard to RFC 5681. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 01b94b8d9ec9..ea09d2fd50c7 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -224,16 +224,10 @@ void tcp_select_initial_window(int __space, __u32 mss, } } - /* Set initial window to value enough for senders, - * following RFC2414. Senders, not following this RFC, - * will be satisfied with 2. - */ + /* Set initial window to value enough for senders, following RFC5681. */ if (mss > (1 << *rcv_wscale)) { - int init_cwnd = 4; - if (mss > 1460 * 3) - init_cwnd = 2; - else if (mss > 1460) - init_cwnd = 3; + int init_cwnd = rfc3390_bytes_to_packets(mss); + /* when initializing use the value from init_rcv_wnd * rather than the default from above */ -- cgit v1.2.3 From 3e502e63586920f219ed2590f69c1f5a8888cfa4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Sep 2010 18:35:59 -0700 Subject: starfire: Temporary kludge to fix powerpc build. Add a dma_addr_t 64-bit case for powerpc with 64-bit phys addresses. Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/starfire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index c3bf288aaf25..4adf12422787 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, }; * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ #define netdrv_addr_t __le64 -- cgit v1.2.3 From 95f4b45bc688b03107f5452ccda29496fc1b4ecf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 09:19:32 -0700 Subject: net: another last_rx round Kill last_rx use in l2tp and two net drivers Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/sge.c | 1 - drivers/net/pxa168_eth.c | 1 - net/l2tp/l2tp_eth.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index eb5a1c9cb2d3..e00fd9c36e8b 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1520,7 +1520,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); - skb->dev->last_rx = jiffies; /* XXX removed 2.6.29 */ pi = netdev_priv(skb->dev); rxq->stats.pkts++; diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 659915cf6872..764aa9099468 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -848,7 +848,6 @@ static int rxq_process(struct net_device *dev, int budget) skb->protocol = eth_type_trans(skb, dev); netif_receive_skb(skb); } - dev->last_rx = jiffies; } /* Fill RX ring with skb's */ rxq_refill(dev); diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 58c6c4cda73b..f3468ba3f5cb 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -144,7 +144,6 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, nf_reset(skb); if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { - dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += data_len; } else -- cgit v1.2.3 From 8ed2163ff3b6abc5143d46dea73e523b22a6f987 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Wed, 1 Sep 2010 22:19:14 +0000 Subject: ipvs: use pkts for SCTP too Use correctly the in_pkts packet counter also for SCTP Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/netfilter/ipvs/ip_vs_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index edbfb96b935e..b7ce5b441b38 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -1383,8 +1383,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) && cp->protocol == IPPROTO_SCTP) { if ((cp->state == IP_VS_SCTP_S_ESTABLISHED && - (atomic_read(&cp->in_pkts) % - sysctl_ip_vs_sync_threshold[1] + (pkts % sysctl_ip_vs_sync_threshold[1] == sysctl_ip_vs_sync_threshold[0])) || (cp->old_state != cp->state && ((cp->state == IP_VS_SCTP_S_CLOSED) || @@ -1395,7 +1394,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, } } - if (af == AF_INET && + /* Keep this block last: TCP and others with pp->num_states <= 1 */ + else if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) && (((cp->protocol != IPPROTO_TCP || cp->state == IP_VS_TCP_S_ESTABLISHED) && -- cgit v1.2.3 From c68839963426d42bdb2c915b435f9860d060e645 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Thu, 2 Sep 2010 04:06:24 +0000 Subject: net: Improve comments in include/linux/phy.h Correct state range of PHY bus addresses (i.e. 0-31) in comment, make spelling of PHY consistent in comments. Signed-off-by: Peter Meerwald Signed-off-by: David S. Miller --- include/linux/phy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/phy.h b/include/linux/phy.h index 6b0a782c6224..a6e047a04f79 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -116,7 +116,7 @@ struct mii_bus { /* list of all PHYs on bus */ struct phy_device *phy_map[PHY_MAX_ADDR]; - /* Phy addresses to be ignored when probing */ + /* PHY addresses to be ignored when probing */ u32 phy_mask; /* @@ -283,7 +283,7 @@ struct phy_device { phy_interface_t interface; - /* Bus address of the PHY (0-32) */ + /* Bus address of the PHY (0-31) */ int addr; /* -- cgit v1.2.3 From c07b68e841bd737e2ebeb57268d251c89ccc5010 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 03:53:46 +0000 Subject: net: dev_add_pack() & __dev_remove_pack() changes Add a small helper ptype_head() to get the head to manipulate dev_add_pack() & __dev_remove_pack() can use a spinlock without blocking BH, since softirq use RCU, and these functions are run from process context only. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index d8c43e73f0b7..efd318db11ab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -371,6 +371,14 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) * --ANK (980803) */ +static inline struct list_head *ptype_head(const struct packet_type *pt) +{ + if (pt->type == htons(ETH_P_ALL)) + return &ptype_all; + else + return &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; +} + /** * dev_add_pack - add packet handler * @pt: packet type declaration @@ -386,16 +394,11 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) void dev_add_pack(struct packet_type *pt) { - int hash; + struct list_head *head = ptype_head(pt); - spin_lock_bh(&ptype_lock); - if (pt->type == htons(ETH_P_ALL)) - list_add_rcu(&pt->list, &ptype_all); - else { - hash = ntohs(pt->type) & PTYPE_HASH_MASK; - list_add_rcu(&pt->list, &ptype_base[hash]); - } - spin_unlock_bh(&ptype_lock); + spin_lock(&ptype_lock); + list_add_rcu(&pt->list, head); + spin_unlock(&ptype_lock); } EXPORT_SYMBOL(dev_add_pack); @@ -414,15 +417,10 @@ EXPORT_SYMBOL(dev_add_pack); */ void __dev_remove_pack(struct packet_type *pt) { - struct list_head *head; + struct list_head *head = ptype_head(pt); struct packet_type *pt1; - spin_lock_bh(&ptype_lock); - - if (pt->type == htons(ETH_P_ALL)) - head = &ptype_all; - else - head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; + spin_lock(&ptype_lock); list_for_each_entry(pt1, head, list) { if (pt == pt1) { @@ -433,7 +431,7 @@ void __dev_remove_pack(struct packet_type *pt) printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt); out: - spin_unlock_bh(&ptype_lock); + spin_unlock(&ptype_lock); } EXPORT_SYMBOL(__dev_remove_pack); -- cgit v1.2.3 From deffd77759e3ceb936f0760cc54a213881577a83 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 2 Sep 2010 03:56:51 +0000 Subject: net: arp: code cleanup Clean the code up according to Documentation/CodingStyle. Don't initialize the variable dont_send in arp_process(). Remove the temporary varialbe flags in arp_state_to_flags(). Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/ipv4/arp.c | 226 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 123 insertions(+), 103 deletions(-) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 96c1955b3e2f..dcfe7e961c10 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -55,7 +55,7 @@ * Stuart Cheshire : Metricom and grat arp fixes * *** FOR 2.1 clean this up *** * Lawrence V. Stefani: (08/12/96) Added FDDI support. - * Alan Cox : Took the AP1000 nasty FDDI hack and + * Alan Cox : Took the AP1000 nasty FDDI hack and * folded into the mainstream FDDI code. * Ack spit, Linus how did you allow that * one in... @@ -120,7 +120,7 @@ EXPORT_SYMBOL(clip_tbl_hook); #endif #include -#include +#include #include @@ -173,32 +173,32 @@ const struct neigh_ops arp_broken_ops = { EXPORT_SYMBOL(arp_broken_ops); struct neigh_table arp_tbl = { - .family = AF_INET, - .entry_size = sizeof(struct neighbour) + 4, - .key_len = 4, - .hash = arp_hash, - .constructor = arp_constructor, - .proxy_redo = parp_redo, - .id = "arp_cache", - .parms = { - .tbl = &arp_tbl, - .base_reachable_time = 30 * HZ, - .retrans_time = 1 * HZ, - .gc_staletime = 60 * HZ, - .reachable_time = 30 * HZ, - .delay_probe_time = 5 * HZ, - .queue_len = 3, - .ucast_probes = 3, - .mcast_probes = 3, - .anycast_delay = 1 * HZ, - .proxy_delay = (8 * HZ) / 10, - .proxy_qlen = 64, - .locktime = 1 * HZ, + .family = AF_INET, + .entry_size = sizeof(struct neighbour) + 4, + .key_len = 4, + .hash = arp_hash, + .constructor = arp_constructor, + .proxy_redo = parp_redo, + .id = "arp_cache", + .parms = { + .tbl = &arp_tbl, + .base_reachable_time = 30 * HZ, + .retrans_time = 1 * HZ, + .gc_staletime = 60 * HZ, + .reachable_time = 30 * HZ, + .delay_probe_time = 5 * HZ, + .queue_len = 3, + .ucast_probes = 3, + .mcast_probes = 3, + .anycast_delay = 1 * HZ, + .proxy_delay = (8 * HZ) / 10, + .proxy_qlen = 64, + .locktime = 1 * HZ, }, - .gc_interval = 30 * HZ, - .gc_thresh1 = 128, - .gc_thresh2 = 512, - .gc_thresh3 = 1024, + .gc_interval = 30 * HZ, + .gc_thresh1 = 128, + .gc_thresh2 = 512, + .gc_thresh3 = 1024, }; EXPORT_SYMBOL(arp_tbl); @@ -233,7 +233,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev) static int arp_constructor(struct neighbour *neigh) { - __be32 addr = *(__be32*)neigh->primary_key; + __be32 addr = *(__be32 *)neigh->primary_key; struct net_device *dev = neigh->dev; struct in_device *in_dev; struct neigh_parms *parms; @@ -296,16 +296,19 @@ static int arp_constructor(struct neighbour *neigh) neigh->ops = &arp_broken_ops; neigh->output = neigh->ops->output; return 0; +#else + break; #endif - ;} + } #endif if (neigh->type == RTN_MULTICAST) { neigh->nud_state = NUD_NOARP; arp_mc_map(addr, neigh->ha, dev, 1); - } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) { + } else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) { neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->dev_addr, dev->addr_len); - } else if (neigh->type == RTN_BROADCAST || dev->flags&IFF_POINTOPOINT) { + } else if (neigh->type == RTN_BROADCAST || + (dev->flags & IFF_POINTOPOINT)) { neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->broadcast, dev->addr_len); } @@ -315,7 +318,7 @@ static int arp_constructor(struct neighbour *neigh) else neigh->ops = &arp_generic_ops; - if (neigh->nud_state&NUD_VALID) + if (neigh->nud_state & NUD_VALID) neigh->output = neigh->ops->connected_output; else neigh->output = neigh->ops->output; @@ -334,7 +337,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) __be32 saddr = 0; u8 *dst_ha = NULL; struct net_device *dev = neigh->dev; - __be32 target = *(__be32*)neigh->primary_key; + __be32 target = *(__be32 *)neigh->primary_key; int probes = atomic_read(&neigh->probes); struct in_device *in_dev; @@ -347,7 +350,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { default: case 0: /* By default announce any local IP */ - if (skb && inet_addr_type(dev_net(dev), ip_hdr(skb)->saddr) == RTN_LOCAL) + if (skb && inet_addr_type(dev_net(dev), + ip_hdr(skb)->saddr) == RTN_LOCAL) saddr = ip_hdr(skb)->saddr; break; case 1: /* Restrict announcements of saddr in same subnet */ @@ -369,16 +373,21 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!saddr) saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); - if ((probes -= neigh->parms->ucast_probes) < 0) { - if (!(neigh->nud_state&NUD_VALID)) - printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); + probes -= neigh->parms->ucast_probes; + if (probes < 0) { + if (!(neigh->nud_state & NUD_VALID)) + printk(KERN_DEBUG + "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; read_lock_bh(&neigh->lock); - } else if ((probes -= neigh->parms->app_probes) < 0) { + } else { + probes -= neigh->parms->app_probes; + if (probes < 0) { #ifdef CONFIG_ARPD - neigh_app_ns(neigh); + neigh_app_ns(neigh); #endif - return; + return; + } } arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, @@ -451,7 +460,8 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) * is allowed to use this function, it is scheduled to be removed. --ANK */ -static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev) +static int arp_set_predefined(int addr_hint, unsigned char *haddr, + __be32 paddr, struct net_device *dev) { switch (addr_hint) { case RTN_LOCAL: @@ -483,7 +493,8 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) paddr = skb_rtable(skb)->rt_gateway; - if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) + if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, + paddr, dev)) return 0; n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); @@ -515,13 +526,14 @@ int arp_bind_neighbour(struct dst_entry *dst) return -EINVAL; if (n == NULL) { __be32 nexthop = ((struct rtable *)dst)->rt_gateway; - if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT)) + if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) nexthop = 0; n = __neigh_lookup_errno( #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - dev->type == ARPHRD_ATM ? clip_tbl_hook : + dev->type == ARPHRD_ATM ? + clip_tbl_hook : #endif - &arp_tbl, &nexthop, dev); + &arp_tbl, &nexthop, dev); if (IS_ERR(n)) return PTR_ERR(n); dst->neighbour = n; @@ -543,8 +555,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, if (!IN_DEV_PROXY_ARP(in_dev)) return 0; - - if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0) + imi = IN_DEV_MEDIUM_ID(in_dev); + if (imi == 0) return 1; if (imi == -1) return 0; @@ -685,7 +697,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, arp->ar_pln = 4; arp->ar_op = htons(type); - arp_ptr=(unsigned char *)(arp+1); + arp_ptr = (unsigned char *)(arp + 1); memcpy(arp_ptr, src_hw, dev->addr_len); arp_ptr += dev->addr_len; @@ -735,9 +747,8 @@ void arp_send(int type, int ptype, __be32 dest_ip, skb = arp_create(type, ptype, dest_ip, dev, src_ip, dest_hw, src_hw, target_hw); - if (skb == NULL) { + if (skb == NULL) return; - } arp_xmit(skb); } @@ -815,7 +826,7 @@ static int arp_process(struct sk_buff *skb) /* * Extract fields */ - arp_ptr= (unsigned char *)(arp+1); + arp_ptr = (unsigned char *)(arp + 1); sha = arp_ptr; arp_ptr += dev->addr_len; memcpy(&sip, arp_ptr, 4); @@ -869,16 +880,17 @@ static int arp_process(struct sk_buff *skb) addr_type = rt->rt_type; if (addr_type == RTN_LOCAL) { - int dont_send = 0; + int dont_send; - if (!dont_send) - dont_send |= arp_ignore(in_dev,sip,tip); + dont_send = arp_ignore(in_dev, sip, tip); if (!dont_send && IN_DEV_ARPFILTER(in_dev)) - dont_send |= arp_filter(sip,tip,dev); + dont_send |= arp_filter(sip, tip, dev); if (!dont_send) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, + dev, tip, sha, dev->dev_addr, + sha); neigh_release(n); } } @@ -887,8 +899,7 @@ static int arp_process(struct sk_buff *skb) if (addr_type == RTN_UNICAST && (arp_fwd_proxy(in_dev, dev, rt) || arp_fwd_pvlan(in_dev, dev, rt, sip, tip) || - pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) - { + pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) neigh_release(n); @@ -896,9 +907,12 @@ static int arp_process(struct sk_buff *skb) if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED || skb->pkt_type == PACKET_HOST || in_dev->arp_parms->proxy_delay == 0) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, + dev, tip, sha, dev->dev_addr, + sha); } else { - pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb); + pneigh_enqueue(&arp_tbl, + in_dev->arp_parms, skb); return 0; } goto out; @@ -939,7 +953,8 @@ static int arp_process(struct sk_buff *skb) if (arp->ar_op != htons(ARPOP_REPLY) || skb->pkt_type != PACKET_HOST) state = NUD_STALE; - neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0); + neigh_update(n, sha, state, + override ? NEIGH_UPDATE_F_OVERRIDE : 0); neigh_release(n); } @@ -975,7 +990,8 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev, arp->ar_pln != 4) goto freeskb; - if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + skb = skb_share_check(skb, GFP_ATOMIC); + if (skb == NULL) goto out_of_mem; memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); @@ -1019,7 +1035,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, return -EINVAL; if (!dev && (r->arp_flags & ATF_COM)) { dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, - r->arp_ha.sa_data); + r->arp_ha.sa_data); if (!dev) return -ENODEV; } @@ -1033,7 +1049,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, } static int arp_req_set(struct net *net, struct arpreq *r, - struct net_device * dev) + struct net_device *dev) { __be32 ip; struct neighbour *neigh; @@ -1046,10 +1062,11 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (r->arp_flags & ATF_PERM) r->arp_flags |= ATF_COM; if (dev == NULL) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } } }; - struct rtable * rt; - if ((err = ip_route_output_key(net, &rt, &fl)) != 0) + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; + struct rtable *rt; + err = ip_route_output_key(net, &rt, &fl); + if (err != 0) return err; dev = rt->dst.dev; ip_rt_put(rt); @@ -1083,9 +1100,9 @@ static int arp_req_set(struct net *net, struct arpreq *r, unsigned state = NUD_STALE; if (r->arp_flags & ATF_PERM) state = NUD_PERMANENT; - err = neigh_update(neigh, (r->arp_flags&ATF_COM) ? + err = neigh_update(neigh, (r->arp_flags & ATF_COM) ? r->arp_ha.sa_data : NULL, state, - NEIGH_UPDATE_F_OVERRIDE| + NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN); neigh_release(neigh); } @@ -1094,12 +1111,12 @@ static int arp_req_set(struct net *net, struct arpreq *r, static unsigned arp_state_to_flags(struct neighbour *neigh) { - unsigned flags = 0; if (neigh->nud_state&NUD_PERMANENT) - flags = ATF_PERM|ATF_COM; + return ATF_PERM | ATF_COM; else if (neigh->nud_state&NUD_VALID) - flags = ATF_COM; - return flags; + return ATF_COM; + else + return 0; } /* @@ -1142,7 +1159,7 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r, } static int arp_req_delete(struct net *net, struct arpreq *r, - struct net_device * dev) + struct net_device *dev) { int err; __be32 ip; @@ -1153,10 +1170,11 @@ static int arp_req_delete(struct net *net, struct arpreq *r, ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; if (dev == NULL) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } } }; - struct rtable * rt; - if ((err = ip_route_output_key(net, &rt, &fl)) != 0) + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; + struct rtable *rt; + err = ip_route_output_key(net, &rt, &fl); + if (err != 0) return err; dev = rt->dst.dev; ip_rt_put(rt); @@ -1166,7 +1184,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r, err = -ENXIO; neigh = neigh_lookup(&arp_tbl, &ip, dev); if (neigh) { - if (neigh->nud_state&~NUD_NOARP) + if (neigh->nud_state & ~NUD_NOARP) err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE| NEIGH_UPDATE_F_ADMIN); @@ -1186,24 +1204,24 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) struct net_device *dev = NULL; switch (cmd) { - case SIOCDARP: - case SIOCSARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - case SIOCGARP: - err = copy_from_user(&r, arg, sizeof(struct arpreq)); - if (err) - return -EFAULT; - break; - default: - return -EINVAL; + case SIOCDARP: + case SIOCSARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + case SIOCGARP: + err = copy_from_user(&r, arg, sizeof(struct arpreq)); + if (err) + return -EFAULT; + break; + default: + return -EINVAL; } if (r.arp_pa.sa_family != AF_INET) return -EPFNOSUPPORT; if (!(r.arp_flags & ATF_PUBL) && - (r.arp_flags & (ATF_NETMASK|ATF_DONTPUB))) + (r.arp_flags & (ATF_NETMASK | ATF_DONTPUB))) return -EINVAL; if (!(r.arp_flags & ATF_NETMASK)) ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = @@ -1211,7 +1229,8 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) rtnl_lock(); if (r.arp_dev[0]) { err = -ENODEV; - if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL) + dev = __dev_get_by_name(net, r.arp_dev); + if (dev == NULL) goto out; /* Mmmm... It is wrong... ARPHRD_NETROM==0 */ @@ -1243,7 +1262,8 @@ out: return err; } -static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) +static int arp_netdev_event(struct notifier_block *this, unsigned long event, + void *ptr) { struct net_device *dev = ptr; @@ -1311,12 +1331,13 @@ static char *ax2asc2(ax25_address *a, char *buf) for (n = 0, s = buf; n < 6; n++) { c = (a->ax25_call[n] >> 1) & 0x7F; - if (c != ' ') *s++ = c; + if (c != ' ') + *s++ = c; } *s++ = '-'; - - if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) { + n = (a->ax25_call[6] >> 1) & 0x0F; + if (n > 9) { *s++ = '1'; n -= 10; } @@ -1325,10 +1346,9 @@ static char *ax2asc2(ax25_address *a, char *buf) *s++ = '\0'; if (*buf == '\0' || *buf == '-') - return "*"; + return "*"; return buf; - } #endif /* CONFIG_AX25 */ @@ -1408,10 +1428,10 @@ static void *arp_seq_start(struct seq_file *seq, loff_t *pos) /* ------------------------------------------------------------------------ */ static const struct seq_operations arp_seq_ops = { - .start = arp_seq_start, - .next = neigh_seq_next, - .stop = neigh_seq_stop, - .show = arp_seq_show, + .start = arp_seq_start, + .next = neigh_seq_next, + .stop = neigh_seq_stop, + .show = arp_seq_show, }; static int arp_seq_open(struct inode *inode, struct file *file) -- cgit v1.2.3 From 250e061e1d3e26600236a3dd9172e7f5f5916c00 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 12:45:02 -0700 Subject: bna: fix stats handling get_stats() method incorrectly clears a global array before folding various stats. This can break SNMP applications. Switch to 64 bit flavor to work on a user supplied buffer, and provide 64bit counters even on 32bit arches. Fix a bug in bnad_netdev_hwstats_fill(), for rx_fifo_errors, missing a folding (only the last counter was taken into account) Signed-off-by: Eric Dumazet Acked-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 52 +++++++++++++++++++----------------------- drivers/net/bna/bnad.h | 5 ++-- drivers/net/bna/bnad_ethtool.c | 17 ++++++-------- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index cbc1d563a0c2..79c4c2441449 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -1964,25 +1964,24 @@ bnad_enable_default_bcast(struct bnad *bnad) /* Statistics utilities */ void -bnad_netdev_qstats_fill(struct bnad *bnad) +bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats) { - struct net_device_stats *net_stats = &bnad->net_stats; int i, j; for (i = 0; i < bnad->num_rx; i++) { for (j = 0; j < bnad->num_rxp_per_rx; j++) { if (bnad->rx_info[i].rx_ctrl[j].ccb) { - net_stats->rx_packets += bnad->rx_info[i]. + stats->rx_packets += bnad->rx_info[i]. rx_ctrl[j].ccb->rcb[0]->rxq->rx_packets; - net_stats->rx_bytes += bnad->rx_info[i]. + stats->rx_bytes += bnad->rx_info[i]. rx_ctrl[j].ccb->rcb[0]->rxq->rx_bytes; if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && bnad->rx_info[i].rx_ctrl[j].ccb-> rcb[1]->rxq) { - net_stats->rx_packets += + stats->rx_packets += bnad->rx_info[i].rx_ctrl[j]. ccb->rcb[1]->rxq->rx_packets; - net_stats->rx_bytes += + stats->rx_bytes += bnad->rx_info[i].rx_ctrl[j]. ccb->rcb[1]->rxq->rx_bytes; } @@ -1992,9 +1991,9 @@ bnad_netdev_qstats_fill(struct bnad *bnad) for (i = 0; i < bnad->num_tx; i++) { for (j = 0; j < bnad->num_txq_per_tx; j++) { if (bnad->tx_info[i].tcb[j]) { - net_stats->tx_packets += + stats->tx_packets += bnad->tx_info[i].tcb[j]->txq->tx_packets; - net_stats->tx_bytes += + stats->tx_bytes += bnad->tx_info[i].tcb[j]->txq->tx_bytes; } } @@ -2005,37 +2004,36 @@ bnad_netdev_qstats_fill(struct bnad *bnad) * Must be called with the bna_lock held. */ void -bnad_netdev_hwstats_fill(struct bnad *bnad) +bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats) { struct bfi_ll_stats_mac *mac_stats; - struct net_device_stats *net_stats = &bnad->net_stats; u64 bmap; int i; mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats; - net_stats->rx_errors = + stats->rx_errors = mac_stats->rx_fcs_error + mac_stats->rx_alignment_error + mac_stats->rx_frame_length_error + mac_stats->rx_code_error + mac_stats->rx_undersize; - net_stats->tx_errors = mac_stats->tx_fcs_error + + stats->tx_errors = mac_stats->tx_fcs_error + mac_stats->tx_undersize; - net_stats->rx_dropped = mac_stats->rx_drop; - net_stats->tx_dropped = mac_stats->tx_drop; - net_stats->multicast = mac_stats->rx_multicast; - net_stats->collisions = mac_stats->tx_total_collision; + stats->rx_dropped = mac_stats->rx_drop; + stats->tx_dropped = mac_stats->tx_drop; + stats->multicast = mac_stats->rx_multicast; + stats->collisions = mac_stats->tx_total_collision; - net_stats->rx_length_errors = mac_stats->rx_frame_length_error; + stats->rx_length_errors = mac_stats->rx_frame_length_error; /* receive ring buffer overflow ?? */ - net_stats->rx_crc_errors = mac_stats->rx_fcs_error; - net_stats->rx_frame_errors = mac_stats->rx_alignment_error; + stats->rx_crc_errors = mac_stats->rx_fcs_error; + stats->rx_frame_errors = mac_stats->rx_alignment_error; /* recv'r fifo overrun */ bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] | ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32); for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { if (bmap & 1) { - net_stats->rx_fifo_errors = + stats->rx_fifo_errors += bnad->stats.bna_stats-> hw_stats->rxf_stats[i].frame_drops; break; @@ -2638,22 +2636,20 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) * Used spin_lock to synchronize reading of stats structures, which * is written by BNA under the same lock. */ -static struct net_device_stats * -bnad_get_netdev_stats(struct net_device *netdev) +static struct rtnl_link_stats64 * +bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { struct bnad *bnad = netdev_priv(netdev); unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); - memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); - - bnad_netdev_qstats_fill(bnad); - bnad_netdev_hwstats_fill(bnad); + bnad_netdev_qstats_fill(bnad, stats); + bnad_netdev_hwstats_fill(bnad, stats); spin_unlock_irqrestore(&bnad->bna_lock, flags); - return &bnad->net_stats; + return stats; } static void @@ -2858,7 +2854,7 @@ static const struct net_device_ops bnad_netdev_ops = { .ndo_open = bnad_open, .ndo_stop = bnad_stop, .ndo_start_xmit = bnad_start_xmit, - .ndo_get_stats = bnad_get_netdev_stats, + .ndo_get_stats64 = bnad_get_stats64, .ndo_set_rx_mode = bnad_set_rx_mode, .ndo_set_multicast_list = bnad_set_rx_mode, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index 3261401e35cb..ee377888b905 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -273,7 +273,6 @@ struct bnad { /* Statistics */ struct bnad_stats stats; - struct net_device_stats net_stats; struct bnad_diag *diag; @@ -308,8 +307,8 @@ extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id); extern void bnad_dim_timer_start(struct bnad *bnad); /* Statistics */ -extern void bnad_netdev_qstats_fill(struct bnad *bnad); -extern void bnad_netdev_hwstats_fill(struct bnad *bnad); +extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); +extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); /** * MACROS diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index b337bd9bed29..11fa2ea842c1 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -34,7 +34,7 @@ #define BNAD_NUM_TXQ_COUNTERS 5 #define BNAD_ETHTOOL_STATS_NUM \ - (sizeof(struct net_device_stats) / sizeof(unsigned long) + \ + (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \ sizeof(struct bnad_drv_stats) / sizeof(u64) + \ offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) @@ -1159,7 +1159,8 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, { struct bnad *bnad = netdev_priv(netdev); int i, j, bi; - unsigned long *net_stats, flags; + unsigned long flags; + struct rtnl_link_stats64 *net_stats64; u64 *stats64; u64 bmap; @@ -1176,16 +1177,12 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, spin_lock_irqsave(&bnad->bna_lock, flags); bi = 0; memset(buf, 0, stats->n_stats * sizeof(u64)); - memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); - bnad_netdev_qstats_fill(bnad); - bnad_netdev_hwstats_fill(bnad); + net_stats64 = (struct rtnl_link_stats64 *)buf; + bnad_netdev_qstats_fill(bnad, net_stats64); + bnad_netdev_hwstats_fill(bnad, net_stats64); - /* Fill net_stats into ethtool buffers */ - net_stats = (unsigned long *)&bnad->net_stats; - for (i = 0; i < sizeof(struct net_device_stats) / sizeof(unsigned long); - i++) - buf[bi++] = net_stats[i]; + bi = sizeof(*net_stats64) / sizeof(u64); /* Fill driver stats into ethtool buffers */ stats64 = (u64 *)&bnad->stats.drv_stats; -- cgit v1.2.3 From bc8acf2c8c3e43fcc192762a9f964b3e9a17748b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 13:07:41 -0700 Subject: drivers/net: avoid some skb->ip_summed initializations fresh skbs have ip_summed set to CHECKSUM_NONE (0) We can avoid setting again skb->ip_summed to CHECKSUM_NONE in drivers. Introduce skb_checksum_none_assert() helper so that we keep this assertion documented in driver sources. Change most occurrences of : skb->ip_summed = CHECKSUM_NONE; by : skb_checksum_none_assert(skb); Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 2 +- drivers/net/acenic.c | 2 +- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl1.c | 2 +- drivers/net/b44.c | 2 +- drivers/net/benet/be_main.c | 2 +- drivers/net/bna/bnad.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/cassini.c | 2 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/cpmac.c | 2 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/cxgb4/sge.c | 2 +- drivers/net/cxgb4vf/sge.c | 2 +- drivers/net/dm9000.c | 2 +- drivers/net/e1000/e1000_main.c | 3 ++- drivers/net/e1000e/netdev.c | 3 ++- drivers/net/gianfar.c | 2 +- drivers/net/greth.c | 2 +- drivers/net/ibmlana.c | 2 +- drivers/net/igb/igb_main.c | 2 +- drivers/net/igbvf/netdev.c | 2 +- drivers/net/ipg.c | 6 +++--- drivers/net/iseries_veth.c | 2 +- drivers/net/ixgb/ixgb_main.c | 4 ++-- drivers/net/ixgbe/ixgbe_fcoe.c | 5 +++-- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/jme.c | 2 +- drivers/net/ll_temac_main.c | 2 +- drivers/net/macb.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/ns83820.c | 2 +- drivers/net/pasemi_mac.c | 2 +- drivers/net/ps3_gelic_net.c | 4 ++-- drivers/net/qla3xxx.c | 4 ++-- drivers/net/qlcnic/qlcnic_init.c | 2 +- drivers/net/qlge/qlge_main.c | 6 +++--- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 4 ++-- drivers/net/sb1250-mac.c | 2 +- drivers/net/sfc/rx.c | 2 +- drivers/net/sh_eth.c | 2 +- drivers/net/smsc911x.c | 2 +- drivers/net/spider_net.c | 4 ++-- drivers/net/stmmac/stmmac_main.c | 2 +- drivers/net/tehuti.c | 5 +++-- drivers/net/tg3.c | 2 +- drivers/net/typhoon.c | 2 +- drivers/net/via-velocity.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 4 ++-- drivers/net/vxge/vxge-main.c | 2 +- drivers/net/xilinx_emaclite.c | 2 +- include/linux/skbuff.h | 15 +++++++++++++++ 56 files changed, 86 insertions(+), 67 deletions(-) diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 4a4f6b81e32d..237d4ea5a416 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -561,7 +561,7 @@ rx_status_loop: if (cp_rx_csum_ok(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index b9a591604e5b..41d9911202d0 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -2033,7 +2033,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) skb->csum = htons(csum); skb->ip_summed = CHECKSUM_COMPLETE; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } /* send it up */ diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 61f1634ab3f8..553230eb365c 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1719,7 +1719,7 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, * cannot figure out if the packet is fragmented or not, * so we tell the KERNEL CHECKSUM_NONE */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1ae44bb26317..56ace3fbe40d 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1331,7 +1331,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter, u16 pkt_flags; u16 err_flags; - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); pkt_flags = prrs->pkt_flag; err_flags = prrs->err_flag; if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) && diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 5837b0184d4b..e1e0171d6e62 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1805,7 +1805,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, * the higher layers and let it be sorted out there. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 37617abc1647..7342308718a0 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -818,7 +818,7 @@ static int b44_rx(struct b44 *bp, int budget) copy_skb->data, len); skb = copy_skb; } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, bp->dev); netif_receive_skb(skb); received++; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9db10fec8235..dcee7a20c0b9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1016,7 +1016,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb_fill_rx_data(adapter, skb, rxcp, num_rcvd); if (do_pkt_csum(rxcp, adapter->rx_csum)) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); else skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 79c4c2441449..44adc7aefddc 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -510,7 +510,7 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) (flags & BNA_CQ_EF_L4_CKSUM_OK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); rcb->rxq->rx_packets++; rcb->rxq->rx_bytes += skb->len; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a0e02aa42214..4ff76e38e788 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3218,7 +3218,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (bp->rx_csum && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index da96d1a18c20..0e4caf411905 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -623,7 +623,7 @@ reuse_rx: /* Set Toeplitz hash for a none-LRO skb */ bnx2x_set_skb_rxhash(bp, cqe, skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (bp->rx_csum) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 28c88eeec757..32aaadc4734f 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -2149,7 +2149,7 @@ end_copy_pkt: skb->csum = csum_unfold(~csum); skb->ip_summed = CHECKSUM_COMPLETE; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return len; } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index f01cfdb995de..1950b9a20ecd 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1388,7 +1388,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) ++st->rx_cso_good; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(adapter->vlan_grp && p->vlan_valid)) { st->vlan_xtract++; diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 5a5af1ca7541..fec939f8f65f 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -391,7 +391,7 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, if (likely(skb)) { skb_put(desc->skb, desc->datalen); desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); - desc->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(desc->skb); priv->dev->stats.rx_packets++; priv->dev->stats.rx_bytes += desc->datalen; result = desc->skb; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 8ff96c6f6de5..c5a142bea5e9 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2022,7 +2022,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); if (unlikely(p->vlan_valid)) { diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 6ddb3bb0ce67..9967f3debce7 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -1605,7 +1605,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, rxq->stats.rx_cso++; } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index e00fd9c36e8b..f10864ddafbe 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1534,7 +1534,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } rxq->stats.rx_cso++; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 4fd6b2b4554b..9f6aeefa06bf 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1056,7 +1056,7 @@ dm9000_rx(struct net_device *dev) if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } netif_rx(skb); dev->stats.rx_packets++; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 3e8ac4baae1b..17f5867b5d9b 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3552,7 +3552,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, struct e1000_hw *hw = &adapter->hw; u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* 82543 or newer only */ if (unlikely(hw->mac_type < e1000_82543)) return; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5f3eac6432cb..c9b66f4727e4 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -475,7 +475,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index e6048d6ab0ea..f30adbf86bb2 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2654,7 +2654,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } diff --git a/drivers/net/greth.c b/drivers/net/greth.c index fbeaf70d1727..27d6960ce09e 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -893,7 +893,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit) if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 294ccfb427cf..0037a696cd0a 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -602,7 +602,7 @@ static void irqrx_handler(struct net_device *dev) /* set up skb fields */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* bookkeeping */ dev->stats.rx_packets++; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d35cc38bf8b2..c4d861b557ca 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5455,7 +5455,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector, static inline void igb_rx_checksum_adv(struct igb_ring *ring, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) || diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c539f7c9c3e0..c7fab80d2490 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -103,7 +103,7 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if ((status_err & E1000_RXD_STAT_IXSM) || diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 72e3d2da9e9f..dc0198092343 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1213,7 +1213,7 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev, skb_put(skb, framelen); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); sp->rx_buff[entry] = NULL; } @@ -1278,7 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, jumbo->skb->protocol = eth_type_trans(jumbo->skb, dev); - jumbo->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(jumbo->skb); netif_rx(jumbo->skb); } } @@ -1476,7 +1476,7 @@ static int ipg_nic_rx(struct net_device *dev) * IP/TCP/UDP frame was received. Let the * upper layer decide. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Hand off frame for higher layer processing. * The function netif_rx() releases the sk_buff diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index ba1de5973fb2..8df645e78f2e 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1524,7 +1524,7 @@ static void veth_receive(struct veth_lpar_connection *cnx, skb_put(skb, length); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); /* send it up */ dev->stats.rx_packets++; dev->stats.rx_bytes += length; diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 33c4ffe6e103..c2f6e71e1181 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1905,7 +1905,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, */ if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) || (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return; } @@ -1913,7 +1913,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, /* now look at the TCP checksum error bit */ if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) { /* let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); adapter->hw_csum_rx_error++; } else { /* TCP checksum is good */ diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 86fa07cb061d..2f1de8b90f9e 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -304,12 +304,13 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (!ixgbe_rx_is_fcoe(rx_desc)) goto ddp_out; - skb->ip_summed = CHECKSUM_UNNECESSARY; sterr = le32_to_cpu(rx_desc->wb.upper.status_error); fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)) fh = (struct fc_frame_header *)(skb->data + diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5e4dc1b0a1bd..3aafe94741ba 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -980,7 +980,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, { u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 5d3c869283a5..bdbd26c60ae6 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -356,7 +356,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 99f24f5cac53..1fcd533b1a61 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -936,7 +936,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { if (jme->vlgrp) { diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index bdf2149e5296..874ee01e8d9d 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -760,7 +760,7 @@ static void ll_temac_recv(struct net_device *ndev) skb_put(skb, length); skb->dev = ndev; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* if we're doing rx csum offload, set it up */ if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && diff --git a/drivers/net/macb.c b/drivers/net/macb.c index ff2f158ab0b9..4297f6e8c4bc 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, } skb_reserve(skb, RX_OFFSET); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); for (frag = first_frag; ; frag = NEXT_RX(frag)) { diff --git a/drivers/net/niu.c b/drivers/net/niu.c index b4cc61f1fc59..1f89f472cbfb 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -3484,7 +3484,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, RCR_ENTRY_ERROR))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else if (!(val & RCR_ENTRY_MULTI)) append_size = len - skb->len; diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 447c2c43769a..4475ca97f031 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -923,7 +923,7 @@ static void rx_irq(struct net_device *ndev) if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->protocol = eth_type_trans(skb, ndev); #ifdef NS83820_VLAN_ACCEL_SUPPORT diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 8ab6ae0a6107..828e97cacdbf 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -808,7 +808,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); packets++; tot_bytes += len; diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 87d6b8f36304..5526ab4895e6 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -956,9 +956,9 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* update netdevice statistics */ netdev->stats.rx_packets++; diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 6168a130f33f..7496ed2c34ab 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2029,7 +2029,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, dma_unmap_len(lrg_buf_cb2, maplen), PCI_DMA_FROMDEVICE); prefetch(skb->data); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, qdev->ndev); netif_receive_skb(skb); @@ -2076,7 +2076,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, PCI_DMA_FROMDEVICE); prefetch(skb2->data); - skb2->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb2); if (qdev->device_id == QL3022_DEVICE_ID) { /* * Copy the ethhdr from first buffer to second. This diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 8e47d7aea562..26a7d6bca5c7 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1369,7 +1369,7 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->dev = adapter->netdev; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5a245211fc53..e2d0e108b9aa 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (qdev->rx_csum && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { @@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. @@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, } skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 078bbf4e6f19..07b3fb5175e5 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4460,7 +4460,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) ((status == RxProtoIP) && !(opts1 & IPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 7061fc8e99c7..c70ad515383a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7603,10 +7603,10 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) * Packet with erroneous checksum, let the * upper layers deal with it. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); swstats->mem_freed += skb->truesize; send_up: diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 8e6bd45b9f31..d8249d7653c6 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -1170,7 +1170,7 @@ again: sb->ip_summed = CHECKSUM_UNNECESSARY; /* don't need to set sb->csum */ } else { - sb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(sb); } } prefetch(sb->data); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 799c461ce7b8..acb372e841b2 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel, EFX_BUG_ON_PARANOID(!skb); /* Set the SKB flags */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Pass the packet up */ netif_receive_skb(skb); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index a812efc3632e..50259dfec583 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -798,7 +798,7 @@ static int sh_eth_rx(struct net_device *ndev) skb->dev = ndev; sh_eth_set_receive_align(skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); } if (entry >= RX_RING_SIZE - 1) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 0909ae934ad0..13ddcd487200 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1048,7 +1048,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); /* Update counters */ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 1636a34d95dd..cb6bcca9d541 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1000,9 +1000,9 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (data_status & SPIDER_NET_VLAN_PACKET) { /* further enhancements: HW-accel VLAN diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index e3f002eba89a..1ccea76d89ae 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1256,7 +1256,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) if (unlikely(status == csum_none)) { /* always for the old mac 10/100 */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); } else { skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 3128d6a8e9ce..8b3dc1eb4015 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -1297,12 +1297,13 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) ndev->stats.rx_bytes += len; skb_put(skb, len); - skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = eth_type_trans(skb, ndev); /* Non-IP packets aren't checksum-offloaded */ if (GET_RXD_PKT_ID(rxd_val1) == 0) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc3af78a869f..9f6ffffc8376 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4719,7 +4719,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) >> RXD_TCPCSUM_SHIFT) == 0xffff)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, tp->dev); diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 3f4681f78262..5dfb39539b3e 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1760,7 +1760,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) { new_skb->ip_summed = CHECKSUM_UNNECESSARY; } else - new_skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(new_skb); spin_lock(&tp->state_lock); if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fd69095ef6e3..ed7f4f5c4062 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1954,7 +1954,7 @@ static int velocity_tx_srv(struct velocity_info *vptr) */ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rd->rdesc1.CSM & CSM_IPKT) { if (rd->rdesc1.CSM & CSM_IPOK) { diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index abe0ff53daf3..198ce92af0c3 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1042,11 +1042,11 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter, skb->csum = htons(gdesc->rcd.csum); skb->ip_summed = CHECKSUM_PARTIAL; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 01cdec712b64..5378b849f54f 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -501,7 +501,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); vxge_rx_complete(ring, skb, ext_info.vlan, pkt_length, &ext_info); diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 71122ee4e830..f3f8be5a35fa 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -641,7 +641,7 @@ static void xemaclite_rx_handler(struct net_device *dev) skb_put(skb, len); /* Tell the skb how much data we got */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f900ffcd847e..9e8085a89589 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2206,6 +2206,21 @@ static inline void skb_forward_csum(struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; } +/** + * skb_checksum_none_assert - make sure skb ip_summed is CHECKSUM_NONE + * @skb: skb to check + * + * fresh skbs have their ip_summed set to CHECKSUM_NONE. + * Instead of forcing ip_summed to CHECKSUM_NONE, we can + * use this helper, to document places where we make this assertion. + */ +static inline void skb_checksum_none_assert(struct sk_buff *skb) +{ +#ifdef DEBUG + BUG_ON(skb->ip_summed != CHECKSUM_NONE); +#endif +} + bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ -- cgit v1.2.3 From 65e9b62d4503849b10bedfc29bff0473760cc597 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 3 Sep 2010 02:59:14 +0000 Subject: ipv6: add special mode accept_ra=2 to accept RA while configured as router The current IPv6 behavior is to not accept router advertisements while forwarding, i.e. configured as router. This does make sense, a router is typically not supposed to be auto configured. However there are exceptions and we should allow the current behavior to be overwritten. Therefore this patch enables the user to overrule the "if forwarding enabled then don't listen to RAs" rule by setting accept_ra to the special value of 2. An alternative would be to ignore the forwarding switch alltogether and solely accept RAs based on the value of accept_ra. However, I found that if not intended, accepting RAs as a router can lead to strange unwanted behavior therefore we it seems wise to only do so if the user explicitely asks for this behavior. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 58841c4ae947..69a0051cea67 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1105,6 +1105,18 @@ errout: rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err); } +static inline int accept_ra(struct inet6_dev *in6_dev) +{ + /* + * If forwarding is enabled, RA are not accepted unless the special + * hybrid mode (accept_ra=2) is enabled. + */ + if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2) + return 0; + + return in6_dev->cnf.accept_ra; +} + static void ndisc_router_discovery(struct sk_buff *skb) { struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); @@ -1158,8 +1170,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } - /* skip route and link configuration on routers */ - if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) + if (!accept_ra(in6_dev)) goto skip_linkparms; #ifdef CONFIG_IPV6_NDISC_NODETYPE @@ -1309,8 +1320,7 @@ skip_linkparms: NEIGH_UPDATE_F_ISROUTER); } - /* skip route and link configuration on routers */ - if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) + if (!accept_ra(in6_dev)) goto out; #ifdef CONFIG_IPV6_ROUTE_INFO -- cgit v1.2.3 From c3bccac2fa76f1619dfe4fb7b9bee69de7f066d8 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 3 Sep 2010 03:04:20 +0000 Subject: ipv6: add special mode forwarding=2 to send RS while configured as router Similar to accepting router advertisement, the IPv6 stack does not send router solicitations if forwarding is enabled. This patch enables this behavior to be overruled by setting forwarding to the special value 2. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ab70a3fbcafa..5bc893e28008 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2964,7 +2964,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) start sending router solicitations. */ - if (ifp->idev->cnf.forwarding == 0 && + if ((ifp->idev->cnf.forwarding == 0 || + ifp->idev->cnf.forwarding == 2) && ifp->idev->cnf.rtr_solicits > 0 && (dev->flags&IFF_LOOPBACK) == 0 && (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { -- cgit v1.2.3 From ae8abfa00efb8ec550f772cbd1e1854977d06212 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 3 Sep 2010 05:47:30 +0000 Subject: ipv6: Update ip-sysctl.txt documentation for recent changes to accept_ra and forwarding Documentation for recent changes to the tunables accept_ra and forwarding. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f350c69b2bb4..c7165f4cb792 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1014,6 +1014,12 @@ conf/interface/*: accept_ra - BOOLEAN Accept Router Advertisements; autoconfigure using them. + Possible values are: + 0 Do not accept Router Advertisements. + 1 Accept Router Advertisements if forwarding is disabled. + 2 Overrule forwarding behaviour. Accept Router Advertisements + even if forwarding is enabled. + Functional default: enabled if local forwarding is disabled. disabled if local forwarding is enabled. @@ -1075,7 +1081,12 @@ forwarding - BOOLEAN Note: It is recommended to have the same setting on all interfaces; mixed router/host scenarios are rather uncommon. - FALSE: + Possible values are: + 0 Forwarding disabled + 1 Forwarding enabled + 2 Forwarding enabled (Hybrid Mode) + + FALSE (0): By default, Host behaviour is assumed. This means: @@ -1085,18 +1096,24 @@ forwarding - BOOLEAN Advertisements (and do autoconfiguration). 4. If accept_redirects is TRUE (default), accept Redirects. - TRUE: + TRUE (1): If local forwarding is enabled, Router behaviour is assumed. This means exactly the reverse from the above: 1. IsRouter flag is set in Neighbour Advertisements. 2. Router Solicitations are not sent. - 3. Router Advertisements are ignored. + 3. Router Advertisements are ignored unless accept_ra is 2. 4. Redirects are ignored. - Default: FALSE if global forwarding is disabled (default), - otherwise TRUE. + TRUE (2): + + Hybrid mode. Same behaviour as TRUE, except for: + + 2. Router Solicitations are being sent when necessary. + + Default: 0 (disabled) if global forwarding is disabled (default), + otherwise 1 (enabled). hop_limit - INTEGER Default Hop Limit to set. -- cgit v1.2.3 From 1a18abaa87c4c68a13c2ffcace39a078605b980a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 3 Sep 2010 03:52:43 +0000 Subject: tulip: use integrated netdev stats struct tulip_private is a bit large (order-1 allocation even on 32bit arch), try to shrink it, remove its net_device_stats field. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tulip/interrupt.c | 77 ++++++++++++++++++++++++------------------ drivers/net/tulip/tulip.h | 3 +- drivers/net/tulip/tulip_core.c | 10 +++--- 3 files changed, 50 insertions(+), 40 deletions(-) diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 1faf7a4d7202..0013642903ee 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -180,21 +180,24 @@ int tulip_poll(struct napi_struct *napi, int budget) dev_warn(&dev->dev, "Oversized Ethernet frame spanned multiple buffers, status %08x!\n", status); - tp->stats.rx_length_errors++; - } + dev->stats.rx_length_errors++; + } } else { /* There was a fatal error. */ if (tulip_debug > 2) printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n", dev->name, status); - tp->stats.rx_errors++; /* end of a packet.*/ - if (pkt_len > 1518 || - (status & RxDescRunt)) - tp->stats.rx_length_errors++; - - if (status & 0x0004) tp->stats.rx_frame_errors++; - if (status & 0x0002) tp->stats.rx_crc_errors++; - if (status & 0x0001) tp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; /* end of a packet.*/ + if (pkt_len > 1518 || + (status & RxDescRunt)) + dev->stats.rx_length_errors++; + + if (status & 0x0004) + dev->stats.rx_frame_errors++; + if (status & 0x0002) + dev->stats.rx_crc_errors++; + if (status & 0x0001) + dev->stats.rx_fifo_errors++; } } else { struct sk_buff *skb; @@ -244,8 +247,8 @@ int tulip_poll(struct napi_struct *napi, int budget) netif_receive_skb(skb); - tp->stats.rx_packets++; - tp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION received++; @@ -404,20 +407,23 @@ static int tulip_rx(struct net_device *dev) dev_warn(&dev->dev, "Oversized Ethernet frame spanned multiple buffers, status %08x!\n", status); - tp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } } else { /* There was a fatal error. */ if (tulip_debug > 2) printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n", dev->name, status); - tp->stats.rx_errors++; /* end of a packet.*/ + dev->stats.rx_errors++; /* end of a packet.*/ if (pkt_len > 1518 || (status & RxDescRunt)) - tp->stats.rx_length_errors++; - if (status & 0x0004) tp->stats.rx_frame_errors++; - if (status & 0x0002) tp->stats.rx_crc_errors++; - if (status & 0x0001) tp->stats.rx_fifo_errors++; + dev->stats.rx_length_errors++; + if (status & 0x0004) + dev->stats.rx_frame_errors++; + if (status & 0x0002) + dev->stats.rx_crc_errors++; + if (status & 0x0001) + dev->stats.rx_fifo_errors++; } } else { struct sk_buff *skb; @@ -467,8 +473,8 @@ static int tulip_rx(struct net_device *dev) netif_rx(skb); - tp->stats.rx_packets++; - tp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } received++; entry = (++tp->cur_rx) % RX_RING_SIZE; @@ -602,18 +608,22 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n", dev->name, status); #endif - tp->stats.tx_errors++; - if (status & 0x4104) tp->stats.tx_aborted_errors++; - if (status & 0x0C00) tp->stats.tx_carrier_errors++; - if (status & 0x0200) tp->stats.tx_window_errors++; - if (status & 0x0002) tp->stats.tx_fifo_errors++; + dev->stats.tx_errors++; + if (status & 0x4104) + dev->stats.tx_aborted_errors++; + if (status & 0x0C00) + dev->stats.tx_carrier_errors++; + if (status & 0x0200) + dev->stats.tx_window_errors++; + if (status & 0x0002) + dev->stats.tx_fifo_errors++; if ((status & 0x0080) && tp->full_duplex == 0) - tp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; } else { - tp->stats.tx_bytes += + dev->stats.tx_bytes += tp->tx_buffers[entry].skb->len; - tp->stats.collisions += (status >> 3) & 15; - tp->stats.tx_packets++; + dev->stats.collisions += (status >> 3) & 15; + dev->stats.tx_packets++; } pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping, @@ -655,7 +665,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ if (csr5 == 0xffffffff) break; - if (csr5 & TxJabber) tp->stats.tx_errors++; + if (csr5 & TxJabber) + dev->stats.tx_errors++; if (csr5 & TxFIFOUnderflow) { if ((tp->csr6 & 0xC000) != 0xC000) tp->csr6 += 0x4000; /* Bump up the Tx threshold */ @@ -672,8 +683,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) } } if (csr5 & RxDied) { /* Missed a Rx frame. */ - tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; - tp->stats.rx_errors++; + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + dev->stats.rx_errors++; tulip_start_rxtx(tp); } /* @@ -789,7 +800,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) #endif /* CONFIG_TULIP_NAPI */ if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) { - tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; + dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; } if (tulip_debug > 4) diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index e525875ed67d..ed66a16711dc 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -417,7 +417,6 @@ struct tulip_private { int revision; int flags; struct napi_struct napi; - struct net_device_stats stats; struct timer_list timer; /* Media selection timer. */ struct timer_list oom_timer; /* Out of memory timer. */ u32 mc_filter[2]; @@ -570,7 +569,7 @@ static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __io /* Trigger an immediate transmit demand. */ iowrite32(0, ioaddr + CSR1); - tp->stats.tx_errors++; + tp->dev->stats.tx_errors++; } #endif /* __NET_TULIP_H__ */ diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 3a8d7efa2acf..2c39f2591216 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -725,7 +725,7 @@ static void tulip_clean_tx_ring(struct tulip_private *tp) int status = le32_to_cpu(tp->tx_ring[entry].status); if (status < 0) { - tp->stats.tx_errors++; /* It wasn't Txed */ + tp->dev->stats.tx_errors++; /* It wasn't Txed */ tp->tx_ring[entry].status = 0; } @@ -781,8 +781,8 @@ static void tulip_down (struct net_device *dev) /* release any unconsumed transmit buffers */ tulip_clean_tx_ring(tp); - if (ioread32 (ioaddr + CSR6) != 0xffffffff) - tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff; + if (ioread32(ioaddr + CSR6) != 0xffffffff) + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; spin_unlock_irqrestore (&tp->lock, flags); @@ -864,12 +864,12 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev) spin_lock_irqsave (&tp->lock, flags); - tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; spin_unlock_irqrestore(&tp->lock, flags); } - return &tp->stats; + return &dev->stats; } -- cgit v1.2.3 From 52ee7a04a0f88815a71acdc604a854fb30dcbe45 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 3 Sep 2010 06:27:08 +0000 Subject: net: remove two kmemcheck annotations __alloc_skb() uses a memset() to clear all the beginning of skb, including bitfields contained in 'flags1' & 'flags2'. We dont need any more to use kmemcheck_annotate_bitfield() on these fields. However, we still need it for the clone part, which is not cleared. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/skbuff.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 231dff0dde2e..c030cf894f57 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -202,8 +202,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->tail + size; - kmemcheck_annotate_bitfield(skb, flags1); - kmemcheck_annotate_bitfield(skb, flags2); #ifdef NET_SKBUFF_DATA_USES_OFFSET skb->mac_header = ~0U; #endif -- cgit v1.2.3 From 96e4a387528cfe806fbdf7b022a6c3f103af4ae1 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 2 Sep 2010 13:07:29 +0000 Subject: cxgb3: Add register bit definition for Fatal Parity Error. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb3/regs.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index cb42353c9fdd..6990f6c65221 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -1997,6 +1997,10 @@ #define A_PL_RST 0x6f0 +#define S_FATALPERREN 4 +#define V_FATALPERREN(x) ((x) << S_FATALPERREN) +#define F_FATALPERREN V_FATALPERREN(1U) + #define S_CRSTWRM 1 #define V_CRSTWRM(x) ((x) << S_CRSTWRM) #define F_CRSTWRM V_CRSTWRM(1U) -- cgit v1.2.3 From e05e6a397c65ac9a31ce799cf85157f2d85f45b7 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 2 Sep 2010 13:07:30 +0000 Subject: cxgb3: Set FATALPERREN. Signed-off-by: Dimitris Michailidis Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb3/t3_hw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 427c451be1a7..14a56640dfa9 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -3569,6 +3569,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params) t3_write_reg(adapter, A_PM1_TX_MODE, 0); chan_init_hw(adapter, adapter->params.chan_map); t3_sge_init(adapter, &adapter->params.sge); + t3_set_reg_field(adapter, A_PL_RST, 0, F_FATALPERREN); t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter)); -- cgit v1.2.3 From aa476321022ac6c3cb8ebfd1736555ccf61da276 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 2 Sep 2010 13:07:31 +0000 Subject: cxgb3: Leave interrupts for fatal errors asserted in common code. Platform code needs to deal with them now. Signed-off-by: Dimitris Michailidis Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb3/t3_hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 14a56640dfa9..d307c9de59fb 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -1408,6 +1408,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, fatal++; CH_ALERT(adapter, "%s (0x%x)\n", acts->msg, status & acts->mask); + status &= ~acts->mask; } else if (acts->msg) CH_WARN(adapter, "%s (0x%x)\n", acts->msg, status & acts->mask); @@ -1843,11 +1844,10 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx) t3_os_link_fault_handler(adap, idx); } - t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); - if (cause & XGM_INTR_FATAL) t3_fatal_err(adap); + t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); return cause != 0; } -- cgit v1.2.3 From 55bc3228ccef255041d697fe55dcc7fe4b37feb6 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 2 Sep 2010 13:07:32 +0000 Subject: cxgb3: Avoid flush_workqueue() deadlock. Don't call flush_workqueue() on the cxgb3 Work Queue in cxgb_down() when we're being called from the fatal error task ... which is executing on the cxgb3 Work Queue. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index ad19585d960b..1ecf53dafe06 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1286,7 +1286,7 @@ irq_err: /* * Release resources when all the ports and offloading have been stopped. */ -static void cxgb_down(struct adapter *adapter) +static void cxgb_down(struct adapter *adapter, int on_wq) { t3_sge_stop(adapter); spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */ @@ -1296,7 +1296,8 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); t3_sge_stop(adapter); - flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ + if (!on_wq) + flush_workqueue(cxgb3_wq);/* wait for external IRQ handler */ } static void schedule_chk_task(struct adapter *adap) @@ -1374,7 +1375,7 @@ static int offload_close(struct t3cdev *tdev) clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, 0); cxgb3_offload_deactivate(adapter); return 0; @@ -1409,7 +1410,7 @@ static int cxgb_open(struct net_device *dev) return 0; } -static int cxgb_close(struct net_device *dev) +static int __cxgb_close(struct net_device *dev, int on_wq) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; @@ -1436,12 +1437,17 @@ static int cxgb_close(struct net_device *dev) cancel_delayed_work_sync(&adapter->adap_check_task); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, on_wq); cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_DOWN, pi->port_id); return 0; } +static int cxgb_close(struct net_device *dev) +{ + return __cxgb_close(dev, 0); +} + static struct net_device_stats *cxgb_get_stats(struct net_device *dev) { struct port_info *pi = netdev_priv(dev); @@ -2862,7 +2868,7 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id) spin_unlock(&adapter->work_lock); } -static int t3_adapter_error(struct adapter *adapter, int reset) +static int t3_adapter_error(struct adapter *adapter, int reset, int on_wq) { int i, ret = 0; @@ -2877,7 +2883,7 @@ static int t3_adapter_error(struct adapter *adapter, int reset) struct net_device *netdev = adapter->port[i]; if (netif_running(netdev)) - cxgb_close(netdev); + __cxgb_close(netdev, on_wq); } /* Stop SGE timers */ @@ -2948,7 +2954,7 @@ static void fatal_error_task(struct work_struct *work) int err = 0; rtnl_lock(); - err = t3_adapter_error(adapter, 1); + err = t3_adapter_error(adapter, 1, 1); if (!err) err = t3_reenable_adapter(adapter); if (!err) @@ -2998,7 +3004,7 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - ret = t3_adapter_error(adapter, 0); + ret = t3_adapter_error(adapter, 0, 0); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; -- cgit v1.2.3 From f7322f8f05f5755252e96d772fdcf9ca4304dc69 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 23 Aug 2010 15:24:49 -0700 Subject: iwlagn: open/close envlope to force move BT state machine In uCode, BT state machine need to receive open envlope command before perform calibration; followed by close envlope command to move to next stage. Since Linux has two separated uCode, one for init and the second one for runtime; we use open envlope commands for init uCode to indicate we are ready to perform calibration operation. But for runtime uCode, we are not doing any init calibration, so we issue open/close envlope commands to force uCode move to "BT COEX ON" state. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 34 +++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a7961bf395fc..8bfb0495a76b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -307,6 +307,17 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) goto restart; } + if (priv->cfg->advanced_bt_coexist) { + /* + * Tell uCode we are ready to perform calibration + * need to perform this before any calibration + * no need to close the envlope since we are going + * to load the runtime uCode later. + */ + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + + } iwlagn_send_calib_cfg(priv); return; @@ -364,7 +375,7 @@ static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; -static void iwlagn_send_prio_tbl(struct iwl_priv *priv) +void iwlagn_send_prio_tbl(struct iwl_priv *priv) { struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; @@ -375,7 +386,7 @@ static void iwlagn_send_prio_tbl(struct iwl_priv *priv) IWL_ERR(priv, "failed to send BT prio tbl command\n"); } -static void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) +void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) { struct iwl_bt_coex_prot_env_cmd env_cmd; @@ -482,25 +493,6 @@ int iwlagn_alive_notify(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - if (priv->cfg->advanced_bt_coexist) { - /* Configure Bluetooth device coexistence support */ - /* need to perform this before any calibration */ - priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; - priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; - priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; - priv->cfg->ops->hcmd->send_bt_config(priv); - priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; - - if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) { - iwlagn_send_prio_tbl(priv); - iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, - BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); - iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, - BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); - } - - } - iwlagn_send_wimax_coex(priv); iwlagn_set_Xtal_calib(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ad0e67f5c0d4..55ac079916d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2813,6 +2813,22 @@ static void iwl_alive_start(struct iwl_priv *priv) if (iwl_is_rfkill(priv)) return; + if (priv->cfg->advanced_bt_coexist) { + /* Configure Bluetooth device coexistence support */ + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; + priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; + priv->cfg->ops->hcmd->send_bt_config(priv); + priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; + if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) + iwlagn_send_prio_tbl(priv); + + /* FIXME: w/a to force change uCode BT state machine */ + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + } ieee80211_wake_queues(priv->hw); priv->active_rate = IWL_RATES_MASK; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 7c542a8c8f81..ab7c16f365f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -134,6 +134,8 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv, void iwlagn_init_alive_start(struct iwl_priv *priv); int iwlagn_alive_notify(struct iwl_priv *priv); int iwl_verify_ucode(struct iwl_priv *priv); +void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); +void iwlagn_send_prio_tbl(struct iwl_priv *priv); /* lib */ void iwl_check_abort_status(struct iwl_priv *priv, -- cgit v1.2.3 From adea1ac7effbddbe60a9de6d63462bfe79289e59 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 5 Sep 2010 20:04:05 -0700 Subject: r8169: fix rx checksum offload While porting GRO to r8169, I found this driver has a bug in its rx path. All skbs given to network stack had their ip_summed set to CHECKSUM_NONE, while hardware said they had correct TCP/UDP checksums. The reason is driver sets skb->ip_summed on the original skb before the copy eventually done by copybreak. The fresh skb gets the ip_summed = CHECKSUM_NONE value, forcing network stack to recompute checksum, and preventing my GRO patch to work. Fix is to make the ip_summed setting after skb copy. Note : rx_copybreak current value is 16383, so all frames are copied... Signed-off-by: Eric Dumazet Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/r8169.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 07b3fb5175e5..56a11e29af0b 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4450,9 +4450,8 @@ static inline int rtl8169_fragmented_frame(u32 status) return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); } -static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) +static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) { - u32 opts1 = le32_to_cpu(desc->opts1); u32 status = opts1 & RxProtoMask; if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || @@ -4546,8 +4545,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev, continue; } - rtl8169_rx_csum(skb, desc); - if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { pci_dma_sync_single_for_device(pdev, addr, pkt_size, PCI_DMA_FROMDEVICE); @@ -4558,6 +4555,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, tp->Rx_skbuff[entry] = NULL; } + rtl8169_rx_csum(skb, status); skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); -- cgit v1.2.3 From dcfc5d787a24b9a20be3e18e3dbbab5280d35e38 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 2 Sep 2010 14:29:35 +0000 Subject: wan: make read-only data const Change several wan drivers to make strings and other initialize only parameters const. Compile tested only (with no new warnings) Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/wan/cycx_drv.c | 14 +++++++------- drivers/net/wan/cycx_main.c | 6 +++--- drivers/net/wan/lapbether.c | 2 +- drivers/net/wan/pc300_drv.c | 2 +- drivers/net/wan/z85230.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index a5ddc6c8963e..164c3624ba89 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c @@ -73,7 +73,7 @@ static int reset_cyc2x(void __iomem *addr); static int detect_cyc2x(void __iomem *addr); /* Miscellaneous functions */ -static int get_option_index(long *optlist, long optval); +static int get_option_index(const long *optlist, long optval); static u16 checksum(u8 *buf, u32 len); #define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET) @@ -81,23 +81,23 @@ static u16 checksum(u8 *buf, u32 len); /* Global Data */ /* private data */ -static char modname[] = "cycx_drv"; -static char fullname[] = "Cyclom 2X Support Module"; -static char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " +static const char modname[] = "cycx_drv"; +static const char fullname[] = "Cyclom 2X Support Module"; +static const char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " ""; /* Hardware configuration options. * These are arrays of configuration options used by verification routines. * The first element of each array is its size (i.e. number of options). */ -static long cyc2x_dpmbase_options[] = { +static const long cyc2x_dpmbase_options[] = { 20, 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000 }; -static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; +static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; /* Kernel Loadable Module Entry Points */ /* Module 'insert' entry point. @@ -529,7 +529,7 @@ static int detect_cyc2x(void __iomem *addr) /* Miscellaneous */ /* Get option's index into the options list. * Return option's index (1 .. N) or zero if option is invalid. */ -static int get_option_index(long *optlist, long optval) +static int get_option_index(const long *optlist, long optval) { int i = 1; diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c index a0e8611ad8e8..859dba9b972e 100644 --- a/drivers/net/wan/cycx_main.c +++ b/drivers/net/wan/cycx_main.c @@ -81,9 +81,9 @@ static irqreturn_t cycx_isr(int irq, void *dev_id); */ /* private data */ -static char cycx_drvname[] = "cyclomx"; -static char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver"; -static char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " +static const char cycx_drvname[] = "cyclomx"; +static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver"; +static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " ""; static int cycx_ncards = CONFIG_CYCX_CARDS; static struct cycx_device *cycx_card_array; /* adapter data space */ diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 4d4dc38c7290..7f5bb913c8b9 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -46,7 +46,7 @@ #include -static char bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* If this number is made larger, check that the temporary string buffer * in lapbeth_new_device is large enough to store the probe device name.*/ diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index c6aa66e5b52f..fbf1175a07f1 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -1,5 +1,5 @@ #define USE_PCI_CLOCK -static char rcsid[] = +static const char rcsid[] = "Revision: 3.4.5 Date: 2002/03/07 "; /* diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index fbf5e843d48c..93956861ea21 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -766,7 +766,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id) EXPORT_SYMBOL(z8530_interrupt); -static char reg_init[16]= +static const u8 reg_init[16]= { 0,0,0,0, 0,0,0,0, @@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(z8530_sync_txdma_close); * it exists... */ -static char *z8530_type_name[]={ +static const char *z8530_type_name[]={ "Z8530", "Z85C30", "Z85230" -- cgit v1.2.3 From 5d9c54c1e9ececcf7e99c4f014f9bec7ee3a7def Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 3 Sep 2010 08:33:39 +0000 Subject: tipc: Minor optimizations to name table translation code Optimizes TIPC's name table translation code to avoid unnecessary manipulation of the node address field of the resulting port id when name translation fails. This change is possible because a valid port id cannot have a reference field of zero, so examining the reference only is sufficient to determine if the translation was successful. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/name_table.c | 4 +--- net/tipc/port.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index d504e490fd02..c13c2c7c4b57 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -613,8 +613,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, } /* - * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid. - * Very time-critical. + * tipc_nametbl_translate - translate name to port id * * Note: on entry 'destnode' is the search domain used during translation; * on exit it passes back the node address of the matching port (if any) @@ -685,7 +684,6 @@ found: } spin_unlock_bh(&seq->lock); not_found: - *destnode = 0; read_unlock_bh(&tipc_nametbl_lock); return 0; } diff --git a/net/tipc/port.c b/net/tipc/port.c index ebcbc21d8f98..d760336f2ca8 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -1464,7 +1464,7 @@ int tipc_forward2name(u32 ref, msg_set_destnode(msg, destnode); msg_set_destport(msg, destport); - if (likely(destport || destnode)) { + if (likely(destport)) { p_ptr->sent++; if (likely(destnode == tipc_own_addr)) return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); @@ -1542,7 +1542,7 @@ int tipc_forward_buf2name(u32 ref, skb_push(buf, LONG_H_SIZE); skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); msg_dbg(buf_msg(buf),"PREP:"); - if (likely(destport || destnode)) { + if (likely(destport)) { p_ptr->sent++; if (destnode == tipc_own_addr) return tipc_port_recv_msg(buf); -- cgit v1.2.3 From 9fbfca013176f9b90d186f3b446fd93e4d972b25 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 3 Sep 2010 08:33:40 +0000 Subject: tipc: Ensure outgoing messages on Ethernet have sufficient headroom Add code to expand the headroom of an outgoing TIPC message if the sk_buff has insufficient room to hold the header for the associated Ethernet device. This change is necessary to ensure that messages TIPC does not create itself (eg. incoming messages that are being routed to another node) do not cause problems, since TIPC has no control over the amount of headroom available in such messages. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/eth_media.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 6230d16020c4..81253d0b24b9 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -72,17 +72,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, { struct sk_buff *clone; struct net_device *dev; + int delta; clone = skb_clone(buf, GFP_ATOMIC); - if (clone) { - skb_reset_network_header(clone); - dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; - clone->dev = dev; - dev_hard_header(clone, dev, ETH_P_TIPC, - &dest->dev_addr.eth_addr, - dev->dev_addr, clone->len); - dev_queue_xmit(clone); + if (!clone) + return 0; + + dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; + delta = dev->hard_header_len - skb_headroom(buf); + + if ((delta > 0) && + pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { + kfree_skb(clone); + return 0; } + + skb_reset_network_header(clone); + clone->dev = dev; + dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr, + dev->dev_addr, clone->len); + dev_queue_xmit(clone); return 0; } -- cgit v1.2.3 From d1fb62796cdac6899ebd4319e4a610684db063e9 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Fri, 3 Sep 2010 08:33:42 +0000 Subject: tipc: Fix misleading error code when enabling Ethernet bearers Cause TIPC to return EAGAIN if it is unable to enable a new Ethernet bearer because one or more recently disabled Ethernet bearers are temporarily consuming resources during shut down. (The previous error code, EDQUOT, is now returned only if all available Ethernet bearer data structures are fully enabled at the time the request to enable an additional bearer is received.) Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/eth_media.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 81253d0b24b9..673fdf0b3222 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -142,6 +142,16 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) struct eth_bearer *eb_ptr = ð_bearers[0]; struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; + int pending_dev = 0; + + /* Find unused Ethernet bearer structure */ + + while (eb_ptr->dev) { + if (!eb_ptr->bearer) + pending_dev++; + if (++eb_ptr == stop) + return pending_dev ? -EAGAIN : -EDQUOT; + } /* Find device with specified name */ -- cgit v1.2.3 From 7457e911c72eb0041b007943b0a29aab5a1c4a39 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Fri, 3 Sep 2010 10:05:39 +0000 Subject: ns83820: Remove unused have_optical variable. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 4475ca97f031..b3cebb1204f1 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1246,7 +1246,6 @@ static int ns83820_get_settings(struct net_device *ndev, { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar, tbicr; - int have_optical = 0; int fullduplex = 0; /* @@ -1267,15 +1266,7 @@ static int ns83820_get_settings(struct net_device *ndev, tanar = readl(dev->base + TANAR); tbicr = readl(dev->base + TBICR); - if (dev->CFG_cache & CFG_TBI_EN) { - /* we have an optical interface */ - have_optical = 1; - fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; - - } else { - /* We have copper */ - fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; - } + fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; cmd->supported = SUPPORTED_Autoneg; -- cgit v1.2.3 From 3c083edc6d0d53a050672b15e3594d07d81b42e5 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Fri, 3 Sep 2010 10:05:40 +0000 Subject: ns83820: Add copper device settings Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index b3cebb1204f1..379af3e4edcc 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1270,13 +1270,21 @@ static int ns83820_get_settings(struct net_device *ndev, cmd->supported = SUPPORTED_Autoneg; - /* we have optical interface */ if (dev->CFG_cache & CFG_TBI_EN) { + /* we have optical interface */ cmd->supported |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; cmd->port = PORT_FIBRE; - } /* TODO: else copper related support */ + } else { + /* we have copper */ + cmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full | + SUPPORTED_MII; + cmd->port = PORT_MII; + } cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF; switch (cfg / CFG_SPDSTS0 & 3) { -- cgit v1.2.3 From a5d31e0faf025ca8f64b85fc6938b702105725b7 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Fri, 3 Sep 2010 10:05:41 +0000 Subject: ns83820: Use predefined autoneg constants Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 379af3e4edcc..3bbd0aab17e8 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1298,7 +1298,8 @@ static int ns83820_get_settings(struct net_device *ndev, cmd->speed = SPEED_10; break; } - cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0; + cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) + ? AUTONEG_ENABLE : AUTONEG_DISABLE; return 0; } -- cgit v1.2.3 From a613f581489aff23189c4945aec9567f6663b0c6 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:04 +0000 Subject: ibmveth: Remove integer divide caused by modulus Replace some modulus operators with an increment and compare to avoid an integer divide. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 4734c939ad03..d2cc6d3f401c 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -252,7 +252,9 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc } free_index = pool->consumer_index; - pool->consumer_index = (pool->consumer_index + 1) % pool->size; + pool->consumer_index++; + if (pool->consumer_index >= pool->size) + pool->consumer_index = 0; index = pool->free_map[free_index]; ibmveth_assert(index != IBM_VETH_INVALID_MAP); @@ -377,9 +379,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 DMA_FROM_DEVICE); free_index = adapter->rx_buff_pool[pool].producer_index; - adapter->rx_buff_pool[pool].producer_index - = (adapter->rx_buff_pool[pool].producer_index + 1) - % adapter->rx_buff_pool[pool].size; + adapter->rx_buff_pool[pool].producer_index++; + if (adapter->rx_buff_pool[pool].producer_index >= + adapter->rx_buff_pool[pool].size) + adapter->rx_buff_pool[pool].producer_index = 0; adapter->rx_buff_pool[pool].free_map[free_index] = index; mb(); -- cgit v1.2.3 From c033a6d1390bb6cc0c11c3b4137b856dfd8cb7c8 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:09 +0000 Subject: ibmveth: batch rx buffer replacement At the moment we try and replenish the receive ring on every rx interrupt. We even have a pool->threshold but aren't using it. To limit the maximum latency incurred when refilling, change the threshold from 1/2 to 7/8 and reduce the largest rx pool from 768 buffers to 512 which should be more than enough. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 13 ++++++++----- drivers/net/ibmveth.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index d2cc6d3f401c..3515ef318eb0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -178,7 +178,7 @@ static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_in pool->size = pool_size; pool->index = pool_index; pool->buff_size = buff_size; - pool->threshold = pool_size / 2; + pool->threshold = pool_size * 7 / 8; pool->active = pool_active; } @@ -315,10 +315,13 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) adapter->replenish_task_cycles++; - for (i = (IbmVethNumBufferPools - 1); i >= 0; i--) - if(adapter->rx_buff_pool[i].active) - ibmveth_replenish_buffer_pool(adapter, - &adapter->rx_buff_pool[i]); + for (i = (IbmVethNumBufferPools - 1); i >= 0; i--) { + struct ibmveth_buff_pool *pool = &adapter->rx_buff_pool[i]; + + if (pool->active && + (atomic_read(&pool->available) < pool->threshold)) + ibmveth_replenish_buffer_pool(adapter, pool); + } adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); } diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index ec76ace66c6b..f3ede8184b6d 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -102,7 +102,7 @@ static inline long h_illan_attributes(unsigned long unit_address, #define IBMVETH_MAX_BUF_SIZE (1024 * 128) static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 }; -static int pool_count[] = { 256, 768, 256, 256, 256 }; +static int pool_count[] = { 256, 512, 256, 256, 256 }; static int pool_active[] = { 1, 1, 0, 0, 0}; #define IBM_VETH_INVALID_MAP ((u16)0xffff) -- cgit v1.2.3 From e8cb7eb473ac47703282db6f90b4926f31cdf376 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:15 +0000 Subject: ibmveth: Remove LLTX The ibmveth adapter needs locking in the transmit routine to protect the bounce_buffer but it sets LLTX and forgets to add any of its own locking. Just remove the deprecated LLTX option. Remove the stats lock in the process. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 7 +------ drivers/net/ibmveth.h | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 3515ef318eb0..9d662dec21b0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -903,7 +903,6 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, union ibmveth_buf_desc desc; unsigned long lpar_rc; unsigned long correlator; - unsigned long flags; unsigned int retry_count; unsigned int tx_dropped = 0; unsigned int tx_bytes = 0; @@ -965,20 +964,18 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, } else { tx_packets++; tx_bytes += skb->len; - netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ } if (!used_bounce) dma_unmap_single(&adapter->vdev->dev, data_dma_addr, skb->len, DMA_TO_DEVICE); -out: spin_lock_irqsave(&adapter->stats_lock, flags); +out: netdev->stats.tx_dropped += tx_dropped; netdev->stats.tx_bytes += tx_bytes; netdev->stats.tx_packets += tx_packets; adapter->tx_send_failed += tx_send_failed; adapter->tx_map_failed += tx_map_failed; - spin_unlock_irqrestore(&adapter->stats_lock, flags); dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -1290,8 +1287,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->netdev_ops = &ibmveth_netdev_ops; netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); - netdev->features |= NETIF_F_LLTX; - spin_lock_init(&adapter->stats_lock); memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index f3ede8184b6d..d5651c79e199 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -158,7 +158,6 @@ struct ibmveth_adapter { u64 rx_no_buffer; u64 tx_map_failed; u64 tx_send_failed; - spinlock_t stats_lock; }; struct ibmveth_buf_desc_fields { -- cgit v1.2.3 From c08cc3ccebd46dce44d13a8ce81d249e687eeb8a Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:20 +0000 Subject: ibmveth: Add tx_copybreak Use the existing bounce buffer if we send a buffer under a certain size. This saves the overhead of a TCE map/unmap. I can't see any reason for the wmb() in the bounce buffer case, if we need a barrier it will be before we call h_send_logical_lan but we have nothing in the common case. Remove it. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 9d662dec21b0..fc6e2cf879c0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -117,6 +117,11 @@ MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(ibmveth_driver_version); +static unsigned int tx_copybreak __read_mostly = 128; +module_param(tx_copybreak, uint, 0644); +MODULE_PARM_DESC(tx_copybreak, + "Maximum size of packet that is copied to a new buffer on transmit"); + struct ibmveth_stat { char name[ETH_GSTRING_LEN]; int offset; @@ -931,17 +936,24 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, buf[1] = 0; } - data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { - if (!firmware_has_feature(FW_FEATURE_CMO)) - ibmveth_error_printk("tx: unable to map xmit buffer\n"); + if (skb->len < tx_copybreak) { + used_bounce = 1; + } else { + data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, + skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { + if (!firmware_has_feature(FW_FEATURE_CMO)) + ibmveth_error_printk("tx: unable to map " + "xmit buffer\n"); + tx_map_failed++; + used_bounce = 1; + } + } + + if (used_bounce) { skb_copy_from_linear_data(skb, adapter->bounce_buffer, skb->len); desc.fields.address = adapter->bounce_buffer_dma; - tx_map_failed++; - used_bounce = 1; - wmb(); } else desc.fields.address = data_dma_addr; -- cgit v1.2.3 From 8d86c61ae41d9068fd5e5cc01a4abd53c4fe3ab5 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:25 +0000 Subject: ibmveth: Add rx_copybreak For small packets, create a new skb and copy the packet into it so we avoid tearing down and creating a TCE entry. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index fc6e2cf879c0..c236c8af3367 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -122,6 +122,11 @@ module_param(tx_copybreak, uint, 0644); MODULE_PARM_DESC(tx_copybreak, "Maximum size of packet that is copied to a new buffer on transmit"); +static unsigned int rx_copybreak __read_mostly = 128; +module_param(rx_copybreak, uint, 0644); +MODULE_PARM_DESC(rx_copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + struct ibmveth_stat { char name[ETH_GSTRING_LEN]; int offset; @@ -1002,8 +1007,6 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) restart_poll: do { - struct sk_buff *skb; - if (!ibmveth_rxq_pending_buffer(adapter)) break; @@ -1014,20 +1017,34 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) ibmveth_debug_printk("recycling invalid buffer\n"); ibmveth_rxq_recycle_buffer(adapter); } else { + struct sk_buff *skb, *new_skb; int length = ibmveth_rxq_frame_length(adapter); int offset = ibmveth_rxq_frame_offset(adapter); int csum_good = ibmveth_rxq_csum_good(adapter); skb = ibmveth_rxq_get_buffer(adapter); - if (csum_good) - skb->ip_summed = CHECKSUM_UNNECESSARY; - ibmveth_rxq_harvest_buffer(adapter); + new_skb = NULL; + if (length < rx_copybreak) + new_skb = netdev_alloc_skb(netdev, length); + + if (new_skb) { + skb_copy_to_linear_data(new_skb, + skb->data + offset, + length); + skb = new_skb; + ibmveth_rxq_recycle_buffer(adapter); + } else { + ibmveth_rxq_harvest_buffer(adapter); + skb_reserve(skb, offset); + } - skb_reserve(skb, offset); skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); + if (csum_good) + skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_receive_skb(skb); /* send it up */ netdev->stats.rx_packets++; -- cgit v1.2.3 From f89e49e79f839dbe79364ec6cd7e2274ad11b120 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 6 Sep 2010 18:21:41 -0700 Subject: ibmveth: Use lighter weight read memory barrier in ibmveth_poll We want to order the read in ibmveth_rxq_pending_buffer and the read of ibmveth_rxq_buffer_valid which are both cacheable memory. smp_rmb() is good enough for this. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index c236c8af3367..aedcb1802182 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1010,7 +1010,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) if (!ibmveth_rxq_pending_buffer(adapter)) break; - rmb(); + smp_rmb(); if (!ibmveth_rxq_buffer_valid(adapter)) { wmb(); /* suggested by larson1 */ adapter->rx_invalid_buffer++; -- cgit v1.2.3 From 6e8ab30ec677925e8999a9f5bdb028736d22d48c Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:36 +0000 Subject: ibmveth: Add scatter-gather support ibmveth can scatter gather up to 6 segments. If we go over this then we have no option but to call skb_linearize, like other drivers with similar limitations do. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 184 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 60 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index aedcb1802182..d8a89846c6a8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -897,6 +897,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_strings = ibmveth_get_strings, .get_sset_count = ibmveth_get_sset_count, .get_ethtool_stats = ibmveth_get_ethtool_stats, + .set_sg = ethtool_op_set_sg, }; static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -906,96 +907,158 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1)) -static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, - struct net_device *netdev) +static int ibmveth_send(struct ibmveth_adapter *adapter, + union ibmveth_buf_desc *descs) { - struct ibmveth_adapter *adapter = netdev_priv(netdev); - union ibmveth_buf_desc desc; - unsigned long lpar_rc; unsigned long correlator; unsigned int retry_count; - unsigned int tx_dropped = 0; - unsigned int tx_bytes = 0; - unsigned int tx_packets = 0; - unsigned int tx_send_failed = 0; - unsigned int tx_map_failed = 0; - int used_bounce = 0; - unsigned long data_dma_addr; + unsigned long ret; + + /* + * The retry count sets a maximum for the number of broadcast and + * multicast destinations within the system. + */ + retry_count = 1024; + correlator = 0; + do { + ret = h_send_logical_lan(adapter->vdev->unit_address, + descs[0].desc, descs[1].desc, + descs[2].desc, descs[3].desc, + descs[4].desc, descs[5].desc, + correlator, &correlator); + } while ((ret == H_BUSY) && (retry_count--)); + + if (ret != H_SUCCESS && ret != H_DROPPED) { + ibmveth_error_printk("tx: h_send_logical_lan failed with " + "rc=%ld\n", ret); + return 1; + } + + return 0; +} - desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; +static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct ibmveth_adapter *adapter = netdev_priv(netdev); + unsigned int desc_flags; + union ibmveth_buf_desc descs[6]; + int last, i; + int force_bounce = 0; + + /* + * veth handles a maximum of 6 segments including the header, so + * we have to linearize the skb if there are more than this. + */ + if (skb_shinfo(skb)->nr_frags > 5 && __skb_linearize(skb)) { + netdev->stats.tx_dropped++; + goto out; + } + /* veth can't checksum offload UDP */ if (skb->ip_summed == CHECKSUM_PARTIAL && ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { ibmveth_error_printk("tx: failed to checksum packet\n"); - tx_dropped++; + netdev->stats.tx_dropped++; goto out; } + desc_flags = IBMVETH_BUF_VALID; + if (skb->ip_summed == CHECKSUM_PARTIAL) { - unsigned char *buf = skb_transport_header(skb) + skb->csum_offset; + unsigned char *buf = skb_transport_header(skb) + + skb->csum_offset; - desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); + desc_flags |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); /* Need to zero out the checksum */ buf[0] = 0; buf[1] = 0; } - if (skb->len < tx_copybreak) { - used_bounce = 1; - } else { - data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { - if (!firmware_has_feature(FW_FEATURE_CMO)) - ibmveth_error_printk("tx: unable to map " - "xmit buffer\n"); - tx_map_failed++; - used_bounce = 1; - } - } +retry_bounce: + memset(descs, 0, sizeof(descs)); - if (used_bounce) { + /* + * If a linear packet is below the rx threshold then + * copy it into the static bounce buffer. This avoids the + * cost of a TCE insert and remove. + */ + if (force_bounce || (!skb_is_nonlinear(skb) && + (skb->len < tx_copybreak))) { skb_copy_from_linear_data(skb, adapter->bounce_buffer, skb->len); - desc.fields.address = adapter->bounce_buffer_dma; - } else - desc.fields.address = data_dma_addr; - /* send the frame. Arbitrarily set retrycount to 1024 */ - correlator = 0; - retry_count = 1024; - do { - lpar_rc = h_send_logical_lan(adapter->vdev->unit_address, - desc.desc, 0, 0, 0, 0, 0, - correlator, &correlator); - } while ((lpar_rc == H_BUSY) && (retry_count--)); - - if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { - ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); - ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n", - (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0, - skb->len, desc.fields.address); - tx_send_failed++; - tx_dropped++; + descs[0].fields.flags_len = desc_flags | skb->len; + descs[0].fields.address = adapter->bounce_buffer_dma; + + if (ibmveth_send(adapter, descs)) { + adapter->tx_send_failed++; + netdev->stats.tx_dropped++; + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + } + + goto out; + } + + /* Map the header */ + descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, + skb_headlen(skb), + DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address)) + goto map_failed; + + descs[0].fields.flags_len = desc_flags | skb_headlen(skb); + + /* Map the frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + unsigned long dma_addr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, + frag->page_offset, frag->size, + DMA_TO_DEVICE); + + if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) + goto map_failed_frags; + + descs[i+1].fields.flags_len = desc_flags | frag->size; + descs[i+1].fields.address = dma_addr; + } + + if (ibmveth_send(adapter, descs)) { + adapter->tx_send_failed++; + netdev->stats.tx_dropped++; } else { - tx_packets++; - tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; } - if (!used_bounce) - dma_unmap_single(&adapter->vdev->dev, data_dma_addr, - skb->len, DMA_TO_DEVICE); + for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); out: - netdev->stats.tx_dropped += tx_dropped; - netdev->stats.tx_bytes += tx_bytes; - netdev->stats.tx_packets += tx_packets; - adapter->tx_send_failed += tx_send_failed; - adapter->tx_map_failed += tx_map_failed; - dev_kfree_skb(skb); return NETDEV_TX_OK; + +map_failed_frags: + last = i+1; + for (i = 0; i < last; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); + +map_failed: + if (!firmware_has_feature(FW_FEATURE_CMO)) + ibmveth_error_printk("tx: unable to map xmit buffer\n"); + adapter->tx_map_failed++; + skb_linearize(skb); + force_bounce = 1; + goto retry_bounce; } static int ibmveth_poll(struct napi_struct *napi, int budget) @@ -1316,6 +1379,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->netdev_ops = &ibmveth_netdev_ops; netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); + netdev->features |= NETIF_F_SG; memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); -- cgit v1.2.3 From 0c26b6775f36ce447722e8752bc3a006ec832df3 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:41 +0000 Subject: ibmveth: Add optional flush of rx buffer On some machines we can improve the bandwidth by ensuring rx buffers are not in the cache. Add a module option that is disabled by default that flushes rx buffers on insertion. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index d8a89846c6a8..1685e230a389 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -127,6 +127,10 @@ module_param(rx_copybreak, uint, 0644); MODULE_PARM_DESC(rx_copybreak, "Maximum size of packet that is copied to a new buffer on receive"); +static unsigned int rx_flush __read_mostly = 0; +module_param(rx_flush, uint, 0644); +MODULE_PARM_DESC(rx_flush, "Flush receive buffers before use"); + struct ibmveth_stat { char name[ETH_GSTRING_LEN]; int offset; @@ -234,6 +238,14 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) return 0; } +static inline void ibmveth_flush_buffer(void *addr, unsigned long length) +{ + unsigned long offset; + + for (offset = 0; offset < length; offset += SMP_CACHE_BYTES) + asm("dcbfl %0,%1" :: "b" (addr), "r" (offset)); +} + /* replenish the buffers for a pool. note that we don't need to * skb_reserve these since they are used for incoming... */ @@ -286,6 +298,12 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc desc.fields.flags_len = IBMVETH_BUF_VALID | pool->buff_size; desc.fields.address = dma_addr; + if (rx_flush) { + unsigned int len = min(pool->buff_size, + adapter->netdev->mtu + + IBMVETH_BUFF_OH); + ibmveth_flush_buffer(skb->data, len); + } lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); if (lpar_rc != H_SUCCESS) @@ -1095,6 +1113,9 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) skb_copy_to_linear_data(new_skb, skb->data + offset, length); + if (rx_flush) + ibmveth_flush_buffer(skb->data, + length + offset); skb = new_skb; ibmveth_rxq_recycle_buffer(adapter); } else { -- cgit v1.2.3 From bc4c6f54e4e9971717d84c630acef0c7c3c75a97 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:47 +0000 Subject: ibmveth: Remove duplicate checksum offload setup code Remove code in the device probe function where we set up the checksum offload feature and replace it with a call to an existing function that is doing the same. This is done to clean up the driver in preparation of adding IPv6 checksum offload support. Signed-off-by: Robert Jennings Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 1685e230a389..ab80d8fcccbf 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1338,10 +1338,8 @@ static const struct net_device_ops ibmveth_netdev_ops = { static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { int rc, i; - long ret; struct net_device *netdev; struct ibmveth_adapter *adapter; - unsigned long set_attr, ret_attr; unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; @@ -1425,21 +1423,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ ibmveth_debug_printk("registering netdev...\n"); - ret = h_illan_attributes(dev->unit_address, 0, 0, &ret_attr); - - if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) && - !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) && - (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) { - set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; - - ret = h_illan_attributes(dev->unit_address, 0, set_attr, &ret_attr); - - if (ret == H_SUCCESS) { - adapter->rx_csum = 1; - netdev->features |= NETIF_F_IP_CSUM; - } else - ret = h_illan_attributes(dev->unit_address, set_attr, 0, &ret_attr); - } + ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags); rc = register_netdev(netdev); -- cgit v1.2.3 From ab78df75cac4d90b5b5471af795a64141243c02a Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:52 +0000 Subject: ibmveth: Enable IPv6 checksum offload This patch enables TCP checksum offload support for IPv6 on ibmveth. This completely eliminates the generation and checking of the checksum for IPv6 packets that are completely virtual and never touch a physical network. A basic TCPIPV6_STREAM netperf run showed a ~30% throughput improvement when an MTU of 64000 was used. This featured is enabled by default, as is the case for IPv4 checksum offload. When checksum offload is enabled the driver will negotiate IPv4 and IPv6 offload with the firmware separately and enable what is available. As long as either IPv4 or IPv6 offload is supported and enabled the device will report that checksum offload is enabled. The device stats, available through ethtool, will display which checksum offload features are supported/enabled by firmware. Performance testing against a stock kernel shows no regression for IPv4 or IPv6 in terms of throughput or processor utilization with checksum disabled or enabled. Signed-off-by: Robert Jennings Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 59 +++++++++++++++++++++++++++++++++++++++++---------- drivers/net/ibmveth.h | 2 ++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ab80d8fcccbf..25cf7e0476d0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,8 @@ struct ibmveth_stat ibmveth_stats[] = { { "rx_no_buffer", IBMVETH_STAT_OFF(rx_no_buffer) }, { "tx_map_failed", IBMVETH_STAT_OFF(tx_map_failed) }, { "tx_send_failed", IBMVETH_STAT_OFF(tx_send_failed) }, + { "fw_enabled_ipv4_csum", IBMVETH_STAT_OFF(fw_ipv4_csum_support) }, + { "fw_enabled_ipv6_csum", IBMVETH_STAT_OFF(fw_ipv6_csum_support) }, }; /* simple methods of getting data from the current rxq entry */ @@ -773,6 +776,7 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data) */ adapter->rx_csum = 0; dev->features &= ~NETIF_F_IP_CSUM; + dev->features &= ~NETIF_F_IPV6_CSUM; } } @@ -781,10 +785,15 @@ static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data) struct ibmveth_adapter *adapter = netdev_priv(dev); if (data) { - dev->features |= NETIF_F_IP_CSUM; + if (adapter->fw_ipv4_csum_support) + dev->features |= NETIF_F_IP_CSUM; + if (adapter->fw_ipv6_csum_support) + dev->features |= NETIF_F_IPV6_CSUM; adapter->rx_csum = 1; - } else + } else { dev->features &= ~NETIF_F_IP_CSUM; + dev->features &= ~NETIF_F_IPV6_CSUM; + } } static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, @@ -792,7 +801,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, { struct ibmveth_adapter *adapter = netdev_priv(dev); unsigned long set_attr, clr_attr, ret_attr; - long ret; + unsigned long set_attr6, clr_attr6; + long ret, ret6; int rc1 = 0, rc2 = 0; int restart = 0; @@ -806,10 +816,13 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, set_attr = 0; clr_attr = 0; - if (data) + if (data) { set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; - else + set_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM; + } else { clr_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; + clr_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM; + } ret = h_illan_attributes(adapter->vdev->unit_address, 0, 0, &ret_attr); @@ -820,14 +833,33 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, set_attr, &ret_attr); if (ret != H_SUCCESS) { - rc1 = -EIO; - ibmveth_error_printk("unable to change checksum offload settings." - " %d rc=%ld\n", data, ret); + ibmveth_error_printk("unable to change IPv4 checksum " + "offload settings. %d rc=%ld\n", + data, ret); ret = h_illan_attributes(adapter->vdev->unit_address, set_attr, clr_attr, &ret_attr); } else + adapter->fw_ipv4_csum_support = data; + + ret6 = h_illan_attributes(adapter->vdev->unit_address, + clr_attr6, set_attr6, &ret_attr); + + if (ret6 != H_SUCCESS) { + ibmveth_error_printk("unable to change IPv6 checksum " + "offload settings. %d rc=%ld\n", + data, ret); + + ret = h_illan_attributes(adapter->vdev->unit_address, + set_attr6, clr_attr6, + &ret_attr); + } else + adapter->fw_ipv6_csum_support = data; + + if (ret == H_SUCCESS || ret6 == H_SUCCESS) done(dev, data); + else + rc1 = -EIO; } else { rc1 = -EIO; ibmveth_error_printk("unable to change checksum offload settings." @@ -855,9 +887,9 @@ static int ibmveth_set_tx_csum(struct net_device *dev, u32 data) struct ibmveth_adapter *adapter = netdev_priv(dev); int rc = 0; - if (data && (dev->features & NETIF_F_IP_CSUM)) + if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) return 0; - if (!data && !(dev->features & NETIF_F_IP_CSUM)) + if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) return 0; if (data && !adapter->rx_csum) @@ -975,7 +1007,12 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, /* veth can't checksum offload UDP */ if (skb->ip_summed == CHECKSUM_PARTIAL && - ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { + ((skb->protocol == htons(ETH_P_IP) && + ip_hdr(skb)->protocol != IPPROTO_TCP) || + (skb->protocol == htons(ETH_P_IPV6) && + ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)) && + skb_checksum_help(skb)) { + ibmveth_error_printk("tx: failed to checksum packet\n"); netdev->stats.tx_dropped++; goto out; diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index d5651c79e199..84e4ab224124 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -149,6 +149,8 @@ struct ibmveth_adapter { void *bounce_buffer; dma_addr_t bounce_buffer_dma; + u64 fw_ipv6_csum_support; + u64 fw_ipv4_csum_support; /* adapter specific stats */ u64 replenish_task_cycles; u64 replenish_no_mem; -- cgit v1.2.3 From d2684b516020c162b2852a2171ec588713c6cec0 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:28:58 +0000 Subject: ibmveth: remove procfs code We export all the driver specific statistics via ethtool, so there is no need to duplicate this in procfs. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 113 -------------------------------------------------- 1 file changed, 113 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 25cf7e0476d0..574f4d472551 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -26,11 +26,6 @@ /* ethernet NICs that are presented to the partition by the hypervisor. */ /* */ /**************************************************************************/ -/* - TODO: - - add support for sysfs - - possibly remove procfs support -*/ #include #include @@ -47,19 +42,16 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include #include #include #include -#include #include "ibmveth.h" @@ -94,21 +86,12 @@ static int ibmveth_poll(struct napi_struct *napi, int budget); static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev); static void ibmveth_set_multicast_list(struct net_device *dev); static int ibmveth_change_mtu(struct net_device *dev, int new_mtu); -static void ibmveth_proc_register_driver(void); -static void ibmveth_proc_unregister_driver(void); -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); static struct kobj_type ktype_veth_pool; -#ifdef CONFIG_PROC_FS -#define IBMVETH_PROC_DIR "ibmveth" -static struct proc_dir_entry *ibmveth_proc_dir; -#endif - static const char ibmveth_driver_name[] = "ibmveth"; static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; #define ibmveth_driver_version "1.03" @@ -1472,8 +1455,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ ibmveth_debug_printk("registered\n"); - ibmveth_proc_register_adapter(adapter); - return 0; } @@ -1488,103 +1469,12 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) unregister_netdev(netdev); - ibmveth_proc_unregister_adapter(adapter); - free_netdev(netdev); dev_set_drvdata(&dev->dev, NULL); return 0; } -#ifdef CONFIG_PROC_FS -static void ibmveth_proc_register_driver(void) -{ - ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net); - if (ibmveth_proc_dir) { - } -} - -static void ibmveth_proc_unregister_driver(void) -{ - remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net); -} - -static int ibmveth_show(struct seq_file *seq, void *v) -{ - struct ibmveth_adapter *adapter = seq->private; - char *current_mac = (char *) adapter->netdev->dev_addr; - char *firmware_mac = (char *) &adapter->mac_addr; - - seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); - - seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); - seq_printf(seq, "Current MAC: %pM\n", current_mac); - seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac); - - seq_printf(seq, "\nAdapter Statistics:\n"); - seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed); - seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed); - seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles); - seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem); - seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure); - seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer); - seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer); - - return 0; -} - -static int ibmveth_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ibmveth_show, PDE(inode)->data); -} - -static const struct file_operations ibmveth_proc_fops = { - .owner = THIS_MODULE, - .open = ibmveth_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) -{ - struct proc_dir_entry *entry; - if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - entry = proc_create_data(u_addr, S_IFREG, ibmveth_proc_dir, - &ibmveth_proc_fops, adapter); - if (!entry) - ibmveth_error_printk("Cannot create adapter proc entry"); - } -} - -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) -{ - if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - remove_proc_entry(u_addr, ibmveth_proc_dir); - } -} - -#else /* CONFIG_PROC_FS */ -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) -{ -} - -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) -{ -} -static void ibmveth_proc_register_driver(void) -{ -} - -static void ibmveth_proc_unregister_driver(void) -{ -} -#endif /* CONFIG_PROC_FS */ - static struct attribute veth_active_attr; static struct attribute veth_num_attr; static struct attribute veth_size_attr; @@ -1757,15 +1647,12 @@ static int __init ibmveth_module_init(void) { ibmveth_printk("%s: %s %s\n", ibmveth_driver_name, ibmveth_driver_string, ibmveth_driver_version); - ibmveth_proc_register_driver(); - return vio_register_driver(&ibmveth_driver); } static void __exit ibmveth_module_exit(void) { vio_unregister_driver(&ibmveth_driver); - ibmveth_proc_unregister_driver(); } module_init(ibmveth_module_init); -- cgit v1.2.3 From 003212cc599cdc006de486e28c1f6b327bcb9808 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:03 +0000 Subject: ibmveth: Convert to netdev_alloc_skb We were using alloc_skb which doesn't create any headroom. Change it to use netdev_alloc_skb to match most other drivers. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 574f4d472551..5c7eb06e5bc7 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -251,7 +251,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc for(i = 0; i < count; ++i) { union ibmveth_buf_desc desc; - skb = alloc_skb(pool->buff_size, GFP_ATOMIC); + skb = netdev_alloc_skb(adapter->netdev, pool->buff_size); if(!skb) { ibmveth_debug_printk("replenish: unable to allocate skb\n"); -- cgit v1.2.3 From e295fe83755213fb5991be577485525a7453213c Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:08 +0000 Subject: ibmveth: Remove redundant function prototypes These functions appear before their use, so we can remove the redundant prototypes. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 5c7eb06e5bc7..5a4fca162e00 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -79,16 +79,10 @@ #define ibmveth_assert(expr) #endif -static int ibmveth_open(struct net_device *dev); -static int ibmveth_close(struct net_device *dev); -static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -static int ibmveth_poll(struct napi_struct *napi, int budget); -static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void ibmveth_set_multicast_list(struct net_device *dev); -static int ibmveth_change_mtu(struct net_device *dev, int new_mtu); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); + static struct kobj_type ktype_veth_pool; -- cgit v1.2.3 From c43ced18a515bef29166f22c01a6d9062aa3008e Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:14 +0000 Subject: ibmveth: Convert driver specific debug to netdev_dbg Use netdev_dbg to standardise the debug output. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 5a4fca162e00..03eca309f326 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -64,18 +64,12 @@ printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) #ifdef DEBUG -#define ibmveth_debug_printk_no_adapter(fmt, args...) \ - printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args) -#define ibmveth_debug_printk(fmt, args...) \ - printk(KERN_DEBUG "(%s:%3.3d ua:%x): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) #define ibmveth_assert(expr) \ if(!(expr)) { \ printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \ BUG(); \ } #else -#define ibmveth_debug_printk_no_adapter(fmt, args...) -#define ibmveth_debug_printk(fmt, args...) #define ibmveth_assert(expr) #endif @@ -248,7 +242,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc skb = netdev_alloc_skb(adapter->netdev, pool->buff_size); if(!skb) { - ibmveth_debug_printk("replenish: unable to allocate skb\n"); + netdev_dbg(adapter->netdev, + "replenish: unable to allocate skb\n"); adapter->replenish_no_mem++; break; } @@ -440,7 +435,8 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); if(lpar_rc != H_SUCCESS) { - ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc); + netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " + "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); } @@ -551,7 +547,7 @@ static int ibmveth_open(struct net_device *netdev) int i; struct device *dev; - ibmveth_debug_printk("open starting\n"); + netdev_dbg(netdev, "open starting\n"); napi_enable(&adapter->napi); @@ -607,9 +603,9 @@ static int ibmveth_open(struct net_device *netdev) rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len; rxq_desc.fields.address = adapter->rx_queue.queue_dma; - ibmveth_debug_printk("buffer list @ 0x%p\n", adapter->buffer_list_addr); - ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); - ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); + netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr); + netdev_dbg(netdev, "filter list @ 0x%p\n", adapter->filter_list_addr); + netdev_dbg(netdev, "receive q @ 0x%p\n", adapter->rx_queue.queue_addr); h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); @@ -639,7 +635,7 @@ static int ibmveth_open(struct net_device *netdev) } } - ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq); + netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq); if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) { ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { @@ -669,12 +665,12 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - ibmveth_debug_printk("initial replenish cycle\n"); + netdev_dbg(netdev, "initial replenish cycle\n"); ibmveth_interrupt(netdev->irq, netdev); netif_start_queue(netdev); - ibmveth_debug_printk("open complete\n"); + netdev_dbg(netdev, "open complete\n"); return 0; } @@ -684,7 +680,7 @@ static int ibmveth_close(struct net_device *netdev) struct ibmveth_adapter *adapter = netdev_priv(netdev); long lpar_rc; - ibmveth_debug_printk("close starting\n"); + netdev_dbg(netdev, "close starting\n"); napi_disable(&adapter->napi); @@ -709,7 +705,7 @@ static int ibmveth_close(struct net_device *netdev) ibmveth_cleanup(adapter); - ibmveth_debug_printk("close complete\n"); + netdev_dbg(netdev, "close complete\n"); return 0; } @@ -1109,7 +1105,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) if (!ibmveth_rxq_buffer_valid(adapter)) { wmb(); /* suggested by larson1 */ adapter->rx_invalid_buffer++; - ibmveth_debug_printk("recycling invalid buffer\n"); + netdev_dbg(netdev, "recycling invalid buffer\n"); ibmveth_rxq_recycle_buffer(adapter); } else { struct sk_buff *skb, *new_skb; @@ -1359,8 +1355,8 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ unsigned int *mcastFilterSize_p; - ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n", - dev->unit_address); + dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n", + dev->unit_address); mac_addr_p = (unsigned char *) vio_get_attribute(dev, VETH_MAC_ADDR, NULL); @@ -1429,25 +1425,25 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ kobject_uevent(kobj, KOBJ_ADD); } - ibmveth_debug_printk("adapter @ 0x%p\n", adapter); + netdev_dbg(netdev, "adapter @ 0x%p\n", adapter); adapter->buffer_list_dma = DMA_ERROR_CODE; adapter->filter_list_dma = DMA_ERROR_CODE; adapter->rx_queue.queue_dma = DMA_ERROR_CODE; - ibmveth_debug_printk("registering netdev...\n"); + netdev_dbg(netdev, "registering netdev...\n"); ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags); rc = register_netdev(netdev); if(rc) { - ibmveth_debug_printk("failed to register netdev rc=%d\n", rc); + netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc); free_netdev(netdev); return rc; } - ibmveth_debug_printk("registered\n"); + netdev_dbg(netdev, "registered\n"); return 0; } -- cgit v1.2.3 From 21c2decea0f52980a34c79167fe69df3a84d2788 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:19 +0000 Subject: ibmveth: Convert driver specific error functions to netdev_err Use netdev_err to standardise the error output. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 88 +++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 03eca309f326..98873678e597 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -57,12 +57,6 @@ #undef DEBUG -#define ibmveth_printk(fmt, args...) \ - printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args) - -#define ibmveth_error_printk(fmt, args...) \ - printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) - #ifdef DEBUG #define ibmveth_assert(expr) \ if(!(expr)) { \ @@ -558,7 +552,8 @@ static int ibmveth_open(struct net_device *netdev) adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL); if(!adapter->buffer_list_addr || !adapter->filter_list_addr) { - ibmveth_error_printk("unable to allocate filter or buffer list pages\n"); + netdev_err(netdev, "unable to allocate filter or buffer list " + "pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; @@ -568,7 +563,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL); if(!adapter->rx_queue.queue_addr) { - ibmveth_error_printk("unable to allocate rx queue pages\n"); + netdev_err(netdev, "unable to allocate rx queue pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; @@ -587,7 +582,8 @@ static int ibmveth_open(struct net_device *netdev) if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || (dma_mapping_error(dev, adapter->filter_list_dma)) || (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { - ibmveth_error_printk("unable to map filter or buffer list pages\n"); + netdev_err(netdev, "unable to map filter or buffer list " + "pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; @@ -612,8 +608,10 @@ static int ibmveth_open(struct net_device *netdev) lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", + netdev_err(netdev, "h_register_logical_lan failed with %ld\n", + lpar_rc); + netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq " + "desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, @@ -627,7 +625,7 @@ static int ibmveth_open(struct net_device *netdev) if(!adapter->rx_buff_pool[i].active) continue; if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { - ibmveth_error_printk("unable to alloc pool\n"); + netdev_err(netdev, "unable to alloc pool\n"); adapter->rx_buff_pool[i].active = 0; ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -637,7 +635,8 @@ static int ibmveth_open(struct net_device *netdev) netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq); if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) { - ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); + netdev_err(netdev, "unable to request irq 0x%x, rc %d\n", + netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); @@ -650,7 +649,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->bounce_buffer = kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL); if (!adapter->bounce_buffer) { - ibmveth_error_printk("unable to allocate bounce buffer\n"); + netdev_err(netdev, "unable to allocate bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; @@ -659,7 +658,7 @@ static int ibmveth_open(struct net_device *netdev) dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { - ibmveth_error_printk("unable to map bounce buffer\n"); + netdev_err(netdev, "unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; @@ -695,8 +694,8 @@ static int ibmveth_close(struct net_device *netdev) if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n", - lpar_rc); + netdev_err(netdev, "h_free_logical_lan failed with %lx, " + "continuing with close\n", lpar_rc); } free_irq(netdev->irq, netdev); @@ -806,9 +805,9 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, set_attr, &ret_attr); if (ret != H_SUCCESS) { - ibmveth_error_printk("unable to change IPv4 checksum " - "offload settings. %d rc=%ld\n", - data, ret); + netdev_err(dev, "unable to change IPv4 checksum " + "offload settings. %d rc=%ld\n", + data, ret); ret = h_illan_attributes(adapter->vdev->unit_address, set_attr, clr_attr, &ret_attr); @@ -819,9 +818,9 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, clr_attr6, set_attr6, &ret_attr); if (ret6 != H_SUCCESS) { - ibmveth_error_printk("unable to change IPv6 checksum " - "offload settings. %d rc=%ld\n", - data, ret); + netdev_err(dev, "unable to change IPv6 checksum " + "offload settings. %d rc=%ld\n", + data, ret); ret = h_illan_attributes(adapter->vdev->unit_address, set_attr6, clr_attr6, @@ -835,8 +834,9 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, rc1 = -EIO; } else { rc1 = -EIO; - ibmveth_error_printk("unable to change checksum offload settings." - " %d rc=%ld ret_attr=%lx\n", data, ret, ret_attr); + netdev_err(dev, "unable to change checksum offload settings." + " %d rc=%ld ret_attr=%lx\n", data, ret, + ret_attr); } if (restart) @@ -952,8 +952,8 @@ static int ibmveth_send(struct ibmveth_adapter *adapter, } while ((ret == H_BUSY) && (retry_count--)); if (ret != H_SUCCESS && ret != H_DROPPED) { - ibmveth_error_printk("tx: h_send_logical_lan failed with " - "rc=%ld\n", ret); + netdev_err(adapter->netdev, "tx: h_send_logical_lan failed " + "with rc=%ld\n", ret); return 1; } @@ -986,7 +986,7 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)) && skb_checksum_help(skb)) { - ibmveth_error_printk("tx: failed to checksum packet\n"); + netdev_err(netdev, "tx: failed to checksum packet\n"); netdev->stats.tx_dropped++; goto out; } @@ -1082,7 +1082,7 @@ map_failed_frags: map_failed: if (!firmware_has_feature(FW_FEATURE_CMO)) - ibmveth_error_printk("tx: unable to map xmit buffer\n"); + netdev_err(netdev, "tx: unable to map xmit buffer\n"); adapter->tx_map_failed++; skb_linearize(skb); force_bounce = 1; @@ -1198,7 +1198,8 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastDisableFiltering, 0); if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc); + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "entering promisc mode\n", lpar_rc); } } else { struct netdev_hw_addr *ha; @@ -1209,7 +1210,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastClearFilterTable, 0); if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc); + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "attempting to clear filter table\n", + lpar_rc); } /* add the addresses to the filter table */ netdev_for_each_mc_addr(ha, netdev) { @@ -1220,7 +1223,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastAddFilter, mcast_addr); if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc); + netdev_err(netdev, "h_multicast_ctrl rc=%ld " + "when adding an entry to the filter " + "table\n", lpar_rc); } } @@ -1229,7 +1234,8 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastEnableFiltering, 0); if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc); + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "enabling filtering\n", lpar_rc); } } } @@ -1361,17 +1367,15 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ mac_addr_p = (unsigned char *) vio_get_attribute(dev, VETH_MAC_ADDR, NULL); if(!mac_addr_p) { - printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR " - "attribute\n", __FILE__, __LINE__); + dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n"); return 0; } mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev, VETH_MCAST_FILTER_SIZE, NULL); if(!mcastFilterSize_p) { - printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find " - "VETH_MCAST_FILTER_SIZE attribute\n", - __FILE__, __LINE__); + dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE " + "attribute\n"); return 0; } @@ -1501,7 +1505,8 @@ const char * buf, size_t count) if (value && !pool->active) { if (netif_running(netdev)) { if(ibmveth_alloc_buffer_pool(pool)) { - ibmveth_error_printk("unable to alloc pool\n"); + netdev_err(netdev, + "unable to alloc pool\n"); return -ENOMEM; } pool->active = 1; @@ -1527,7 +1532,7 @@ const char * buf, size_t count) } if (i == IbmVethNumBufferPools) { - ibmveth_error_printk("no active pool >= MTU\n"); + netdev_err(netdev, "no active pool >= MTU\n"); return -EPERM; } @@ -1635,7 +1640,8 @@ static struct vio_driver ibmveth_driver = { static int __init ibmveth_module_init(void) { - ibmveth_printk("%s: %s %s\n", ibmveth_driver_name, ibmveth_driver_string, ibmveth_driver_version); + printk(KERN_DEBUG "%s: %s %s\n", ibmveth_driver_name, + ibmveth_driver_string, ibmveth_driver_version); return vio_register_driver(&ibmveth_driver); } -- cgit v1.2.3 From 517e80e6786974651d460a11bb066eab2628ddf1 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:25 +0000 Subject: ibmveth: Some formatting fixes IbmVethNumBufferPools -> IBMVETH_NUM_BUFF_POOLS Also change IBMVETH_MAX_MTU -> IBMVETH_MIN_MTU, it refers to the minimum size not the maximum. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 32 ++++++++++++++++---------------- drivers/net/ibmveth.h | 6 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 98873678e597..e608ee8b5105 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -312,7 +312,7 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) adapter->replenish_task_cycles++; - for (i = (IbmVethNumBufferPools - 1); i >= 0; i--) { + for (i = (IBMVETH_NUM_BUFF_POOLS - 1); i >= 0; i--) { struct ibmveth_buff_pool *pool = &adapter->rx_buff_pool[i]; if (pool->active && @@ -364,7 +364,7 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 unsigned int free_index; struct sk_buff *skb; - ibmveth_assert(pool < IbmVethNumBufferPools); + ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); ibmveth_assert(index < adapter->rx_buff_pool[pool].size); skb = adapter->rx_buff_pool[pool].skbuff[index]; @@ -397,7 +397,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada unsigned int pool = correlator >> 32; unsigned int index = correlator & 0xffffffffUL; - ibmveth_assert(pool < IbmVethNumBufferPools); + ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); ibmveth_assert(index < adapter->rx_buff_pool[pool].size); return adapter->rx_buff_pool[pool].skbuff[index]; @@ -413,7 +413,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) union ibmveth_buf_desc desc; unsigned long lpar_rc; - ibmveth_assert(pool < IbmVethNumBufferPools); + ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); ibmveth_assert(index < adapter->rx_buff_pool[pool].size); if(!adapter->rx_buff_pool[pool].active) { @@ -487,7 +487,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->rx_queue.queue_addr = NULL; } - for(i = 0; irx_buff_pool[i].active) ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]); @@ -545,7 +545,7 @@ static int ibmveth_open(struct net_device *netdev) napi_enable(&adapter->napi); - for(i = 0; irx_buff_pool[i].size; adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL); @@ -621,7 +621,7 @@ static int ibmveth_open(struct net_device *netdev) return -ENONET; } - for(i = 0; irx_buff_pool[i].active) continue; if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { @@ -1248,14 +1248,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) int i, rc; int need_restart = 0; - if (new_mtu < IBMVETH_MAX_MTU) + if (new_mtu < IBMVETH_MIN_MTU) return -EINVAL; - for (i = 0; i < IbmVethNumBufferPools; i++) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) break; - if (i == IbmVethNumBufferPools) + if (i == IBMVETH_NUM_BUFF_POOLS) return -EINVAL; /* Deactivate all the buffer pools so that the next loop can activate @@ -1268,7 +1268,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) } /* Look for an active buffer pool that can hold the new MTU */ - for(i = 0; irx_buff_pool[i].active = 1; if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { @@ -1322,7 +1322,7 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev) ret = IBMVETH_BUFF_LIST_SIZE + IBMVETH_FILT_LIST_SIZE; ret += IOMMU_PAGE_ALIGN(netdev->mtu); - for (i = 0; i < IbmVethNumBufferPools; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { /* add the size of the active receive buffers */ if (adapter->rx_buff_pool[i].active) ret += @@ -1416,7 +1416,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); - for(i = 0; irx_buff_pool[i].kobj; int error; @@ -1458,7 +1458,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) struct ibmveth_adapter *adapter = netdev_priv(netdev); int i; - for(i = 0; irx_buff_pool[i].kobj); unregister_netdev(netdev); @@ -1522,7 +1522,7 @@ const char * buf, size_t count) int i; /* Make sure there is a buffer pool with buffers that can hold a packet of the size of the MTU */ - for (i = 0; i < IbmVethNumBufferPools; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { if (pool == &adapter->rx_buff_pool[i]) continue; if (!adapter->rx_buff_pool[i].active) @@ -1531,7 +1531,7 @@ const char * buf, size_t count) break; } - if (i == IbmVethNumBufferPools) { + if (i == IBMVETH_NUM_BUFF_POOLS) { netdev_err(netdev, "no active pool >= MTU\n"); return -EPERM; } diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index 84e4ab224124..e6d779471770 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -92,10 +92,10 @@ static inline long h_illan_attributes(unsigned long unit_address, #define h_change_logical_lan_mac(ua, mac) \ plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) -#define IbmVethNumBufferPools 5 +#define IBMVETH_NUM_BUFF_POOLS 5 #define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */ #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ -#define IBMVETH_MAX_MTU 68 +#define IBMVETH_MIN_MTU 68 #define IBMVETH_MAX_POOL_COUNT 4096 #define IBMVETH_BUFF_LIST_SIZE 4096 #define IBMVETH_FILT_LIST_SIZE 4096 @@ -142,7 +142,7 @@ struct ibmveth_adapter { void * filter_list_addr; dma_addr_t buffer_list_dma; dma_addr_t filter_list_dma; - struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools]; + struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS]; struct ibmveth_rx_q rx_queue; int pool_config; int rx_csum; -- cgit v1.2.3 From f148f61d89995660e8aa20a2784ecd9c7f25e2a6 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:30 +0000 Subject: ibmveth: Coding style fixes Fix most of the kernel coding style issues in ibmveth. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 317 +++++++++++++++++++++++++++----------------------- 1 file changed, 172 insertions(+), 145 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index e608ee8b5105..8adfff55792d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1,31 +1,29 @@ -/**************************************************************************/ -/* */ -/* IBM eServer i/pSeries Virtual Ethernet Device Driver */ -/* Copyright (C) 2003 IBM Corp. */ -/* Originally written by Dave Larson (larson1@us.ibm.com) */ -/* Maintained by Santiago Leon (santil@us.ibm.com) */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ -/* USA */ -/* */ -/* This module contains the implementation of a virtual ethernet device */ -/* for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN */ -/* option of the RS/6000 Platform Architechture to interface with virtual */ -/* ethernet NICs that are presented to the partition by the hypervisor. */ -/* */ -/**************************************************************************/ +/* + * IBM eServer i/pSeries Virtual Ethernet Device Driver + * Copyright (C) 2003 IBM Corp. + * Originally written by Dave Larson (larson1@us.ibm.com) + * Maintained by Santiago Leon (santil@us.ibm.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * This module contains the implementation of a virtual ethernet device + * for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN + * option of the RS/6000 Platform Architechture to interface with virtual + * ethernet NICs that are presented to the partition by the hypervisor. + */ #include #include @@ -59,7 +57,7 @@ #ifdef DEBUG #define ibmveth_assert(expr) \ - if(!(expr)) { \ + if (!(expr)) { \ printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \ BUG(); \ } @@ -75,7 +73,8 @@ static struct kobj_type ktype_veth_pool; static const char ibmveth_driver_name[] = "ibmveth"; -static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; +static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet " + "Driver"; #define ibmveth_driver_version "1.03" MODULE_AUTHOR("Santiago Leon "); @@ -108,8 +107,10 @@ struct ibmveth_stat { struct ibmveth_stat ibmveth_stats[] = { { "replenish_task_cycles", IBMVETH_STAT_OFF(replenish_task_cycles) }, { "replenish_no_mem", IBMVETH_STAT_OFF(replenish_no_mem) }, - { "replenish_add_buff_failure", IBMVETH_STAT_OFF(replenish_add_buff_failure) }, - { "replenish_add_buff_success", IBMVETH_STAT_OFF(replenish_add_buff_success) }, + { "replenish_add_buff_failure", + IBMVETH_STAT_OFF(replenish_add_buff_failure) }, + { "replenish_add_buff_success", + IBMVETH_STAT_OFF(replenish_add_buff_success) }, { "rx_invalid_buffer", IBMVETH_STAT_OFF(rx_invalid_buffer) }, { "rx_no_buffer", IBMVETH_STAT_OFF(rx_no_buffer) }, { "tx_map_failed", IBMVETH_STAT_OFF(tx_map_failed) }, @@ -126,36 +127,39 @@ static inline u32 ibmveth_rxq_flags(struct ibmveth_adapter *adapter) static inline int ibmveth_rxq_toggle(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> IBMVETH_RXQ_TOGGLE_SHIFT; + return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> + IBMVETH_RXQ_TOGGLE_SHIFT; } static inline int ibmveth_rxq_pending_buffer(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle); + return ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle; } static inline int ibmveth_rxq_buffer_valid(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID; } static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK; } static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter) { - return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].length); + return adapter->rx_queue.queue_addr[adapter->rx_queue.index].length; } static inline int ibmveth_rxq_csum_good(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD; } /* setup the initial settings for a buffer pool */ -static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_index, u32 pool_size, u32 buff_size, u32 pool_active) +static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, + u32 pool_index, u32 pool_size, + u32 buff_size, u32 pool_active) { pool->size = pool_size; pool->index = pool_index; @@ -171,12 +175,11 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) pool->free_map = kmalloc(sizeof(u16) * pool->size, GFP_KERNEL); - if(!pool->free_map) { + if (!pool->free_map) return -1; - } pool->dma_addr = kmalloc(sizeof(dma_addr_t) * pool->size, GFP_KERNEL); - if(!pool->dma_addr) { + if (!pool->dma_addr) { kfree(pool->free_map); pool->free_map = NULL; return -1; @@ -184,7 +187,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) pool->skbuff = kcalloc(pool->size, sizeof(void *), GFP_KERNEL); - if(!pool->skbuff) { + if (!pool->skbuff) { kfree(pool->dma_addr); pool->dma_addr = NULL; @@ -195,9 +198,8 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) memset(pool->dma_addr, 0, sizeof(dma_addr_t) * pool->size); - for(i = 0; i < pool->size; ++i) { + for (i = 0; i < pool->size; ++i) pool->free_map[i] = i; - } atomic_set(&pool->available, 0); pool->producer_index = 0; @@ -217,7 +219,8 @@ static inline void ibmveth_flush_buffer(void *addr, unsigned long length) /* replenish the buffers for a pool. note that we don't need to * skb_reserve these since they are used for incoming... */ -static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool) +static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, + struct ibmveth_buff_pool *pool) { u32 i; u32 count = pool->size - atomic_read(&pool->available); @@ -230,12 +233,12 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc mb(); - for(i = 0; i < count; ++i) { + for (i = 0; i < count; ++i) { union ibmveth_buf_desc desc; skb = netdev_alloc_skb(adapter->netdev, pool->buff_size); - if(!skb) { + if (!skb) { netdev_dbg(adapter->netdev, "replenish: unable to allocate skb\n"); adapter->replenish_no_mem++; @@ -262,7 +265,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc pool->skbuff[index] = skb; correlator = ((u64)pool->index << 32) | index; - *(u64*)skb->data = correlator; + *(u64 *)skb->data = correlator; desc.fields.flags_len = IBMVETH_BUF_VALID | pool->buff_size; desc.fields.address = dma_addr; @@ -273,11 +276,12 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc IBMVETH_BUFF_OH); ibmveth_flush_buffer(skb->data, len); } - lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); + lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, + desc.desc); - if (lpar_rc != H_SUCCESS) + if (lpar_rc != H_SUCCESS) { goto failure; - else { + } else { buffers_added++; adapter->replenish_add_buff_success++; } @@ -320,21 +324,23 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) ibmveth_replenish_buffer_pool(adapter, pool); } - adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); + adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) + + 4096 - 8); } /* empty and free ana buffer pool - also used to do cleanup in error paths */ -static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool) +static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, + struct ibmveth_buff_pool *pool) { int i; kfree(pool->free_map); pool->free_map = NULL; - if(pool->skbuff && pool->dma_addr) { - for(i = 0; i < pool->size; ++i) { + if (pool->skbuff && pool->dma_addr) { + for (i = 0; i < pool->size; ++i) { struct sk_buff *skb = pool->skbuff[i]; - if(skb) { + if (skb) { dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[i], pool->buff_size, @@ -345,19 +351,20 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm } } - if(pool->dma_addr) { + if (pool->dma_addr) { kfree(pool->dma_addr); pool->dma_addr = NULL; } - if(pool->skbuff) { + if (pool->skbuff) { kfree(pool->skbuff); pool->skbuff = NULL; } } /* remove a buffer from a pool */ -static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 correlator) +static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, + u64 correlator) { unsigned int pool = correlator >> 32; unsigned int index = correlator & 0xffffffffUL; @@ -416,7 +423,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); ibmveth_assert(index < adapter->rx_buff_pool[pool].size); - if(!adapter->rx_buff_pool[pool].active) { + if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); return; @@ -428,13 +435,13 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); } - if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) { + if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } @@ -444,7 +451,7 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) { ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); - if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) { + if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } @@ -455,7 +462,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) int i; struct device *dev = &adapter->vdev->dev; - if(adapter->buffer_list_addr != NULL) { + if (adapter->buffer_list_addr != NULL) { if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { dma_unmap_single(dev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); @@ -465,7 +472,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->buffer_list_addr = NULL; } - if(adapter->filter_list_addr != NULL) { + if (adapter->filter_list_addr != NULL) { if (!dma_mapping_error(dev, adapter->filter_list_dma)) { dma_unmap_single(dev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); @@ -475,7 +482,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->filter_list_addr = NULL; } - if(adapter->rx_queue.queue_addr != NULL) { + if (adapter->rx_queue.queue_addr != NULL) { if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { dma_unmap_single(dev, adapter->rx_queue.queue_dma, @@ -487,7 +494,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->rx_queue.queue_addr = NULL; } - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) if (adapter->rx_buff_pool[i].active) ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]); @@ -510,9 +517,11 @@ static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, { int rc, try_again = 1; - /* After a kexec the adapter will still be open, so our attempt to - * open it will fail. So if we get a failure we free the adapter and - * try again, but only once. */ + /* + * After a kexec the adapter will still be open, so our attempt to + * open it will fail. So if we get a failure we free the adapter and + * try again, but only once. + */ retry: rc = h_register_logical_lan(adapter->vdev->unit_address, adapter->buffer_list_dma, rxq_desc.desc, @@ -551,7 +560,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL); adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL); - if(!adapter->buffer_list_addr || !adapter->filter_list_addr) { + if (!adapter->buffer_list_addr || !adapter->filter_list_addr) { netdev_err(netdev, "unable to allocate filter or buffer list " "pages\n"); ibmveth_cleanup(adapter); @@ -559,10 +568,12 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries; - adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL); + adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * + rxq_entries; + adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, + GFP_KERNEL); - if(!adapter->rx_queue.queue_addr) { + if (!adapter->rx_queue.queue_addr) { netdev_err(netdev, "unable to allocate rx queue pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -596,7 +607,8 @@ static int ibmveth_open(struct net_device *netdev) memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); mac_address = mac_address >> 16; - rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len; + rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | + adapter->rx_queue.queue_len; rxq_desc.fields.address = adapter->rx_queue.queue_dma; netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr); @@ -607,7 +619,7 @@ static int ibmveth_open(struct net_device *netdev) lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_register_logical_lan failed with %ld\n", lpar_rc); netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq " @@ -621,8 +633,8 @@ static int ibmveth_open(struct net_device *netdev) return -ENONET; } - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { - if(!adapter->rx_buff_pool[i].active) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { + if (!adapter->rx_buff_pool[i].active) continue; if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { netdev_err(netdev, "unable to alloc pool\n"); @@ -634,7 +646,9 @@ static int ibmveth_open(struct net_device *netdev) } netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq); - if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) { + rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, + netdev); + if (rc != 0) { netdev_err(netdev, "unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { @@ -692,15 +706,15 @@ static int ibmveth_close(struct net_device *netdev) lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); - if(lpar_rc != H_SUCCESS) - { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_free_logical_lan failed with %lx, " "continuing with close\n", lpar_rc); } free_irq(netdev->irq, netdev); - adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); + adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) + + 4096 - 8); ibmveth_cleanup(adapter); @@ -709,9 +723,12 @@ static int ibmveth_close(struct net_device *netdev) return 0; } -static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE); - cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE); +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | + SUPPORTED_FIBRE); + cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | + ADVERTISED_FIBRE); cmd->speed = SPEED_1000; cmd->duplex = DUPLEX_FULL; cmd->port = PORT_FIBRE; @@ -723,12 +740,16 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; } -static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ strncpy(info->driver, ibmveth_driver_name, sizeof(info->driver) - 1); - strncpy(info->version, ibmveth_driver_version, sizeof(info->version) - 1); + strncpy(info->version, ibmveth_driver_version, + sizeof(info->version) - 1); } -static u32 netdev_get_link(struct net_device *dev) { +static u32 netdev_get_link(struct net_device *dev) +{ return 1; } @@ -736,15 +757,16 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data) { struct ibmveth_adapter *adapter = netdev_priv(dev); - if (data) + if (data) { adapter->rx_csum = 1; - else { + } else { /* - * Since the ibmveth firmware interface does not have the concept of - * separate tx/rx checksum offload enable, if rx checksum is disabled - * we also have to disable tx checksum offload. Once we disable rx - * checksum offload, we are no longer allowed to send tx buffers that - * are not properly checksummed. + * Since the ibmveth firmware interface does not have the + * concept of separate tx/rx checksum offload enable, if rx + * checksum is disabled we also have to disable tx checksum + * offload. Once we disable rx checksum offload, we are no + * longer allowed to send tx buffers that are not properly + * checksummed. */ adapter->rx_csum = 0; dev->features &= ~NETIF_F_IP_CSUM; @@ -811,8 +833,9 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, ret = h_illan_attributes(adapter->vdev->unit_address, set_attr, clr_attr, &ret_attr); - } else + } else { adapter->fw_ipv4_csum_support = data; + } ret6 = h_illan_attributes(adapter->vdev->unit_address, clr_attr6, set_attr6, &ret_attr); @@ -866,7 +889,8 @@ static int ibmveth_set_tx_csum(struct net_device *dev, u32 data) return 0; if (data && !adapter->rx_csum) - rc = ibmveth_set_csum_offload(dev, data, ibmveth_set_tx_csum_flags); + rc = ibmveth_set_csum_offload(dev, data, + ibmveth_set_tx_csum_flags); else ibmveth_set_tx_csum_flags(dev, data); @@ -1091,12 +1115,13 @@ map_failed: static int ibmveth_poll(struct napi_struct *napi, int budget) { - struct ibmveth_adapter *adapter = container_of(napi, struct ibmveth_adapter, napi); + struct ibmveth_adapter *adapter = + container_of(napi, struct ibmveth_adapter, napi); struct net_device *netdev = adapter->netdev; int frames_processed = 0; unsigned long lpar_rc; - restart_poll: +restart_poll: do { if (!ibmveth_rxq_pending_buffer(adapter)) break; @@ -1197,7 +1222,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastEnableRecv | IbmVethMcastDisableFiltering, 0); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_multicast_ctrl rc=%ld when " "entering promisc mode\n", lpar_rc); } @@ -1209,20 +1234,20 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastDisableFiltering | IbmVethMcastClearFilterTable, 0); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_multicast_ctrl rc=%ld when " "attempting to clear filter table\n", lpar_rc); } /* add the addresses to the filter table */ netdev_for_each_mc_addr(ha, netdev) { - // add the multicast address to the filter table + /* add the multicast address to the filter table */ unsigned long mcast_addr = 0; memcpy(((char *)&mcast_addr)+2, ha->addr, 6); lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_multicast_ctrl rc=%ld " "when adding an entry to the filter " "table\n", lpar_rc); @@ -1233,7 +1258,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastEnableFiltering, 0); - if(lpar_rc != H_SUCCESS) { + if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_multicast_ctrl rc=%ld when " "enabling filtering\n", lpar_rc); } @@ -1268,7 +1293,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) } /* Look for an active buffer pool that can hold the new MTU */ - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { adapter->rx_buff_pool[i].active = 1; if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { @@ -1351,29 +1376,28 @@ static const struct net_device_ops ibmveth_netdev_ops = { #endif }; -static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) +static int __devinit ibmveth_probe(struct vio_dev *dev, + const struct vio_device_id *id) { int rc, i; struct net_device *netdev; struct ibmveth_adapter *adapter; - unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; - dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n", dev->unit_address); - mac_addr_p = (unsigned char *) vio_get_attribute(dev, - VETH_MAC_ADDR, NULL); - if(!mac_addr_p) { + mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR, + NULL); + if (!mac_addr_p) { dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n"); return 0; } - mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev, + mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev, VETH_MCAST_FILTER_SIZE, NULL); - if(!mcastFilterSize_p) { + if (!mcastFilterSize_p) { dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE " "attribute\n"); return 0; @@ -1381,7 +1405,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev = alloc_etherdev(sizeof(struct ibmveth_adapter)); - if(!netdev) + if (!netdev) return -ENOMEM; adapter = netdev_priv(netdev); @@ -1389,19 +1413,19 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ adapter->vdev = dev; adapter->netdev = netdev; - adapter->mcastFilterSize= *mcastFilterSize_p; + adapter->mcastFilterSize = *mcastFilterSize_p; adapter->pool_config = 0; netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); - /* Some older boxes running PHYP non-natively have an OF that - returns a 8-byte local-mac-address field (and the first - 2 bytes have to be ignored) while newer boxes' OF return - a 6-byte field. Note that IEEE 1275 specifies that - local-mac-address must be a 6-byte field. - The RPA doc specifies that the first byte must be 10b, so - we'll just look for it to solve this 8 vs. 6 byte field issue */ - + /* + * Some older boxes running PHYP non-natively have an OF that returns + * a 8-byte local-mac-address field (and the first 2 bytes have to be + * ignored) while newer boxes' OF return a 6-byte field. Note that + * IEEE 1275 specifies that local-mac-address must be a 6-byte field. + * The RPA doc specifies that the first byte must be 10b, so we'll + * just look for it to solve this 8 vs. 6 byte field issue + */ if ((*mac_addr_p & 0x3) != 0x02) mac_addr_p += 2; @@ -1416,7 +1440,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; int error; @@ -1441,7 +1465,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ rc = register_netdev(netdev); - if(rc) { + if (rc) { netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc); free_netdev(netdev); return rc; @@ -1458,7 +1482,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) struct ibmveth_adapter *adapter = netdev_priv(netdev); int i; - for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) kobject_put(&adapter->rx_buff_pool[i].kobj); unregister_netdev(netdev); @@ -1473,8 +1497,8 @@ static struct attribute veth_active_attr; static struct attribute veth_num_attr; static struct attribute veth_size_attr; -static ssize_t veth_pool_show(struct kobject * kobj, - struct attribute * attr, char * buf) +static ssize_t veth_pool_show(struct kobject *kobj, + struct attribute *attr, char *buf) { struct ibmveth_buff_pool *pool = container_of(kobj, struct ibmveth_buff_pool, @@ -1489,8 +1513,8 @@ static ssize_t veth_pool_show(struct kobject * kobj, return 0; } -static ssize_t veth_pool_store(struct kobject * kobj, struct attribute * attr, -const char * buf, size_t count) +static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) { struct ibmveth_buff_pool *pool = container_of(kobj, struct ibmveth_buff_pool, @@ -1504,7 +1528,7 @@ const char * buf, size_t count) if (attr == &veth_active_attr) { if (value && !pool->active) { if (netif_running(netdev)) { - if(ibmveth_alloc_buffer_pool(pool)) { + if (ibmveth_alloc_buffer_pool(pool)) { netdev_err(netdev, "unable to alloc pool\n"); return -ENOMEM; @@ -1515,8 +1539,9 @@ const char * buf, size_t count) adapter->pool_config = 0; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->active = 1; + } } else if (!value && pool->active) { int mtu = netdev->mtu + IBMVETH_BUFF_OH; int i; @@ -1547,9 +1572,9 @@ const char * buf, size_t count) pool->active = 0; } } else if (attr == &veth_num_attr) { - if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) + if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) { return -EINVAL; - else { + } else { if (netif_running(netdev)) { adapter->pool_config = 1; ibmveth_close(netdev); @@ -1557,13 +1582,14 @@ const char * buf, size_t count) pool->size = value; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->size = value; + } } } else if (attr == &veth_size_attr) { - if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) + if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) { return -EINVAL; - else { + } else { if (netif_running(netdev)) { adapter->pool_config = 1; ibmveth_close(netdev); @@ -1571,8 +1597,9 @@ const char * buf, size_t count) pool->buff_size = value; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->buff_size = value; + } } } @@ -1582,16 +1609,16 @@ const char * buf, size_t count) } -#define ATTR(_name, _mode) \ - struct attribute veth_##_name##_attr = { \ - .name = __stringify(_name), .mode = _mode, \ - }; +#define ATTR(_name, _mode) \ + struct attribute veth_##_name##_attr = { \ + .name = __stringify(_name), .mode = _mode, \ + }; static ATTR(active, 0644); static ATTR(num, 0644); static ATTR(size, 0644); -static struct attribute * veth_pool_attrs[] = { +static struct attribute *veth_pool_attrs[] = { &veth_active_attr, &veth_num_attr, &veth_size_attr, @@ -1616,7 +1643,7 @@ static int ibmveth_resume(struct device *dev) return 0; } -static struct vio_device_id ibmveth_device_table[] __devinitdata= { +static struct vio_device_id ibmveth_device_table[] __devinitdata = { { "network", "IBM,l-lan"}, { "", "" } }; -- cgit v1.2.3 From be35ae9e08dbbc70f1cd50de8639627fa501692d Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:36 +0000 Subject: ibmveth: Return -EINVAL on all ->probe errors We had a few cases where we returned success on error. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 8adfff55792d..11086dbe76e8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1392,7 +1392,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, NULL); if (!mac_addr_p) { dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n"); - return 0; + return -EINVAL; } mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev, @@ -1400,7 +1400,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, if (!mcastFilterSize_p) { dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE " "attribute\n"); - return 0; + return -EINVAL; } netdev = alloc_etherdev(sizeof(struct ibmveth_adapter)); -- cgit v1.2.3 From 6485911a5c04c328939113528805f15b90ae28cf Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:41 +0000 Subject: ibmveth: Convert driver specific assert to BUG_ON We had a driver specific assert function which wasn't enabled most of the time. Convert them to BUG_ON and enable them all the time. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 11086dbe76e8..82cbf507f73e 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -53,18 +53,6 @@ #include "ibmveth.h" -#undef DEBUG - -#ifdef DEBUG -#define ibmveth_assert(expr) \ - if (!(expr)) { \ - printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \ - BUG(); \ - } -#else -#define ibmveth_assert(expr) -#endif - static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); @@ -251,8 +239,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, pool->consumer_index = 0; index = pool->free_map[free_index]; - ibmveth_assert(index != IBM_VETH_INVALID_MAP); - ibmveth_assert(pool->skbuff[index] == NULL); + BUG_ON(index == IBM_VETH_INVALID_MAP); + BUG_ON(pool->skbuff[index] != NULL); dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); @@ -371,12 +359,12 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, unsigned int free_index; struct sk_buff *skb; - ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); skb = adapter->rx_buff_pool[pool].skbuff[index]; - ibmveth_assert(skb != NULL); + BUG_ON(skb == NULL); adapter->rx_buff_pool[pool].skbuff[index] = NULL; @@ -404,8 +392,8 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada unsigned int pool = correlator >> 32; unsigned int index = correlator & 0xffffffffUL; - ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); return adapter->rx_buff_pool[pool].skbuff[index]; } @@ -420,8 +408,8 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) union ibmveth_buf_desc desc; unsigned long lpar_rc; - ibmveth_assert(pool < IBMVETH_NUM_BUFF_POOLS); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); @@ -1181,7 +1169,7 @@ restart_poll: lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_ENABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + BUG_ON(lpar_rc != H_SUCCESS); napi_complete(napi); @@ -1205,7 +1193,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance) if (napi_schedule_prep(&adapter->napi)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + BUG_ON(lpar_rc != H_SUCCESS); __napi_schedule(&adapter->napi); } return IRQ_HANDLED; -- cgit v1.2.3 From c22960977ad4b01dc608579e0865eac3b2bc9ce8 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:47 +0000 Subject: ibmveth: Remove some unnecessary include files These files probably came across from the skeleton driver. Remove them. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 82cbf507f73e..dfa2ee7a92c8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -29,14 +29,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -48,7 +46,6 @@ #include #include #include -#include #include #include "ibmveth.h" -- cgit v1.2.3 From 9d348af47656a65a697ff55a53daf294ea4d5662 Mon Sep 17 00:00:00 2001 From: Santiago Leon Date: Fri, 3 Sep 2010 18:29:53 +0000 Subject: ibmveth: Update module information and version Add an entry to the MAINTAINERS file for ibmveth, clean up the copyright and add all authors. Change the name of the module to reflect the product name over the last number of years. Considering all the changes we have made, bump the driver version. Signed-off-by: Anton Blanchard Signed-off-by: Santiago Leon Signed-off-by: David S. Miller --- MAINTAINERS | 6 ++++++ drivers/net/ibmveth.c | 48 +++++++++++++++++++++++------------------------- drivers/net/ibmveth.h | 48 +++++++++++++++++++++++++----------------------- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 7a49a7b5af1d..24fbd772e3b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2856,6 +2856,12 @@ M: Brian King S: Supported F: drivers/scsi/ipr.* +IBM Power Virtual Ethernet Device Driver +M: Santiago Leon +L: netdev@vger.kernel.org +S: Supported +F: drivers/net/ibmveth.* + IBM ServeRAID RAID DRIVER P: Jack Hammer M: Dave Jeffery diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index dfa2ee7a92c8..b3e157ed6776 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1,28 +1,27 @@ /* - * IBM eServer i/pSeries Virtual Ethernet Device Driver - * Copyright (C) 2003 IBM Corp. - * Originally written by Dave Larson (larson1@us.ibm.com) - * Maintained by Santiago Leon (santil@us.ibm.com) + * IBM Power Virtual Ethernet Device Driver * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * This module contains the implementation of a virtual ethernet device - * for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN - * option of the RS/6000 Platform Architechture to interface with virtual - * ethernet NICs that are presented to the partition by the hypervisor. + * Copyright (C) IBM Corporation, 2003, 2010 + * + * Authors: Dave Larson + * Santiago Leon + * Brian King + * Robert Jennings + * Anton Blanchard */ #include @@ -58,12 +57,11 @@ static struct kobj_type ktype_veth_pool; static const char ibmveth_driver_name[] = "ibmveth"; -static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet " - "Driver"; -#define ibmveth_driver_version "1.03" +static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver"; +#define ibmveth_driver_version "1.04" -MODULE_AUTHOR("Santiago Leon "); -MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); +MODULE_AUTHOR("Santiago Leon "); +MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(ibmveth_driver_version); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index e6d779471770..43a794fab9ff 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -1,26 +1,28 @@ -/**************************************************************************/ -/* */ -/* IBM eServer i/[Series Virtual Ethernet Device Driver */ -/* Copyright (C) 2003 IBM Corp. */ -/* Dave Larson (larson1@us.ibm.com) */ -/* Santiago Leon (santil@us.ibm.com) */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ -/* USA */ -/* */ -/**************************************************************************/ +/* + * IBM Power Virtual Ethernet Device Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2003, 2010 + * + * Authors: Dave Larson + * Santiago Leon + * Brian King + * Robert Jennings + * Anton Blanchard + */ #ifndef _IBMVETH_H #define _IBMVETH_H -- cgit v1.2.3 From 1fd63041c49c5c6ed1fe58b7bccc2de462d51e2b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 2 Sep 2010 23:09:32 +0000 Subject: net: pskb_expand_head() optimization pskb_expand_head() blindly takes references on fragments before calling skb_release_data(), potentially releasing these references. We can add a fast path, avoiding these atomic operations, if we own the last reference on skb->head. Based on a previous patch from David Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/skbuff.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c030cf894f57..2d1bc761fe4b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -779,6 +779,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, u8 *data; int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail; long off; + bool fastpath; BUG_ON(nhead < 0); @@ -800,14 +801,28 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, skb_shinfo(skb), offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - get_page(skb_shinfo(skb)->frags[i].page); + /* Check if we can avoid taking references on fragments if we own + * the last reference on skb->head. (see skb_release_data()) + */ + if (!skb->cloned) + fastpath = true; + else { + int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; - if (skb_has_frag_list(skb)) - skb_clone_fraglist(skb); + fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; + } - skb_release_data(skb); + if (fastpath) { + kfree(skb->head); + } else { + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + get_page(skb_shinfo(skb)->frags[i].page); + if (skb_has_frag_list(skb)) + skb_clone_fraglist(skb); + + skb_release_data(skb); + } off = (data + nhead) - skb->head; skb->head = data; -- cgit v1.2.3 From e8f7f43a4ad451ecfb2689985f99a9e276a08bba Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 4 Sep 2010 00:12:43 +0000 Subject: drivers/net/fs_enet/fs_enet-main.c: Add of_node_put to avoid memory leak In this case, a device_node structure is stored in another structure that is then freed without first decrementing the reference count of the device_node structure. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression x; identifier f; position p1,p2; @@ x@p1->f = \(of_find_node_by_path\|of_find_node_by_name\|of_find_node_by_phandle\|of_get_parent\|of_get_next_parent\|of_get_next_child\|of_find_compatible_node\|of_match_node\|of_find_node_by_type\|of_find_node_with_property\|of_find_matching_node\|of_parse_phandle\|of_node_get\)(...); ... when != of_node_put(x) kfree@p2(x) @script:python@ p1 << r.p1; p2 << r.p2; @@ cocci.print_main("call",p1) cocci.print_secs("free",p2) // Signed-off-by: Julia Lawall Acked-by: Wolfram Sang Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index d6e3111959ab..d684f187de57 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1036,7 +1036,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev, ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; - goto out_free_fpi; + goto out_put; } SET_NETDEV_DEV(ndev, &ofdev->dev); @@ -1099,6 +1099,7 @@ out_cleanup_data: out_free_dev: free_netdev(ndev); dev_set_drvdata(&ofdev->dev, NULL); +out_put: of_node_put(fpi->phy_node); out_free_fpi: kfree(fpi); -- cgit v1.2.3 From ca1cef3a3a8af961f504abfcf9e13dac088e1ad1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 4 Sep 2010 02:08:41 +0000 Subject: NET: bna, fix lock imbalance bnad_set_rx_mode omit to unlock bna_lock on one fail path. Fix that. Signed-off-by: Jiri Slaby Cc: Debashis Dutt Cc: Rasesh Mody Cc: David S. Miller Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 44adc7aefddc..8158fb93cb4c 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -2702,7 +2702,7 @@ bnad_set_rx_mode(struct net_device *netdev) kzalloc((mc_count + 1) * ETH_ALEN, GFP_ATOMIC); if (!mcaddr_list) - return; + goto unlock; memcpy(&mcaddr_list[0], &bnad_bcast_addr[0], ETH_ALEN); @@ -2715,6 +2715,7 @@ bnad_set_rx_mode(struct net_device *netdev) /* Should we enable BNAD_CF_ALLMULTI for err != 0 ? */ kfree(mcaddr_list); } +unlock: spin_unlock_irqrestore(&bnad->bna_lock, flags); } -- cgit v1.2.3 From 017d79ef0073fdb170dcf185dc4c2456a304d659 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 4 Sep 2010 08:38:59 +0000 Subject: isdn: potential buffer overflows cs->ics.parm.setup.phone is a 32 character array. In each of these cases we're copying from a 35 character array into a 32 character array so we should use strlcpy() instead of strcpy(). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/divert/isdn_divert.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 70cf6bac7a5a..48e6d220f62c 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c @@ -77,7 +77,7 @@ static void deflect_timer_expire(ulong arg) case DEFLECT_ALERT: cs->ics.command = ISDN_CMD_REDIR; /* protocol */ - strcpy(cs->ics.parm.setup.phone,cs->deflect_dest); + strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone)); strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); divert_if.ll_cmd(&cs->ics); spin_lock_irqsave(&divert_lock, flags); @@ -251,7 +251,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) case 2: /* redir */ del_timer(&cs->timer); - strcpy(cs->ics.parm.setup.phone, to_nr); + strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone)); strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); ic.command = ISDN_CMD_REDIR; if ((i = divert_if.ll_cmd(&ic))) @@ -480,7 +480,7 @@ static int isdn_divert_icall(isdn_ctrl *ic) if (!cs->timer.expires) { strcpy(ic->parm.setup.eazmsn,"Testtext direct"); ic->parm.setup.screen = dv->rule.screen; - strcpy(ic->parm.setup.phone,dv->rule.to_nr); + strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone)); cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); retval = 5; -- cgit v1.2.3 From f417f5e4ba79a08e992c79a4bb84c8a8c5062017 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 4 Sep 2010 08:33:03 +0000 Subject: isdn: cleanup: make buffer smaller This showed up in my audit because we use strcpy() to copy "ds" into a 32 character buffer inside the isdn_tty_dial() function. But it turns out that we only ever use the first 32 characters so it's OK. I have changed the declaration to make the static checkers happy. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 51dc60da333b..f013ee15327c 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -3515,7 +3515,7 @@ isdn_tty_parse_at(modem_info * info) { atemu *m = &info->emu; char *p; - char ds[40]; + char ds[ISDN_MSNLEN]; #ifdef ISDN_DEBUG_AT printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd); @@ -3594,7 +3594,7 @@ isdn_tty_parse_at(modem_info * info) break; case '3': p++; - sprintf(ds, "\r\n%d", info->emu.charge); + snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge); isdn_tty_at_cout(ds, info); break; default:; -- cgit v1.2.3 From 49d70c4856acfce943fab35fc199b3074961313f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 4 Sep 2010 22:21:05 +0000 Subject: drivers/net/jme: Use pr_ Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Convert jeprintk to pr_err Remove jeprintk macro define Remove periods from end of logging messages Coalesce format strings Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/jme.c | 98 +++++++++++++++++++++++++++---------------------------- drivers/net/jme.h | 3 -- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 1fcd533b1a61..c04c096bc6a9 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -21,6 +21,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -73,7 +75,7 @@ read_again: } if (i == 0) { - jeprintk(jme->pdev, "phy(%d) read timeout : %d\n", phy, reg); + pr_err("phy(%d) read timeout : %d\n", phy, reg); return 0; } @@ -102,7 +104,7 @@ jme_mdio_write(struct net_device *netdev, } if (i == 0) - jeprintk(jme->pdev, "phy(%d) write timeout : %d\n", phy, reg); + pr_err("phy(%d) write timeout : %d\n", phy, reg); } static inline void @@ -227,7 +229,7 @@ jme_reload_eeprom(struct jme_adapter *jme) } if (i == 0) { - jeprintk(jme->pdev, "eeprom reload timeout\n"); + pr_err("eeprom reload timeout\n"); return -EIO; } } @@ -397,8 +399,7 @@ jme_check_link(struct net_device *netdev, int testonly) phylink = jread32(jme, JME_PHY_LINK); } if (!cnt) - jeprintk(jme->pdev, - "Waiting speed resolve timeout.\n"); + pr_err("Waiting speed resolve timeout\n"); strcat(linkmsg, "ANed: "); } @@ -480,13 +481,13 @@ jme_check_link(struct net_device *netdev, int testonly) strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ? "MDI-X" : "MDI"); - netif_info(jme, link, jme->dev, "Link is up at %s.\n", linkmsg); + netif_info(jme, link, jme->dev, "Link is up at %s\n", linkmsg); netif_carrier_on(netdev); } else { if (testonly) goto out; - netif_info(jme, link, jme->dev, "Link is down.\n"); + netif_info(jme, link, jme->dev, "Link is down\n"); jme->phylink = 0; netif_carrier_off(netdev); } @@ -648,7 +649,7 @@ jme_disable_tx_engine(struct jme_adapter *jme) } if (!i) - jeprintk(jme->pdev, "Disable TX engine timeout.\n"); + pr_err("Disable TX engine timeout\n"); } static void @@ -867,7 +868,7 @@ jme_disable_rx_engine(struct jme_adapter *jme) } if (!i) - jeprintk(jme->pdev, "Disable RX engine timeout.\n"); + pr_err("Disable RX engine timeout\n"); } @@ -887,13 +888,13 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags) if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS)) == RXWBFLAG_UDPON)) { if (flags & RXWBFLAG_IPV4) - netif_err(jme, rx_err, jme->dev, "UDP Checksum error.\n"); + netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n"); return false; } if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS)) == RXWBFLAG_IPV4)) { - netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error.\n"); + netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error\n"); return false; } @@ -1185,9 +1186,9 @@ jme_link_change_tasklet(unsigned long arg) while (!atomic_dec_and_test(&jme->link_changing)) { atomic_inc(&jme->link_changing); - netif_info(jme, intr, jme->dev, "Get link change lock failed.\n"); + netif_info(jme, intr, jme->dev, "Get link change lock failed\n"); while (atomic_read(&jme->link_changing) != 1) - netif_info(jme, intr, jme->dev, "Waiting link change lock.\n"); + netif_info(jme, intr, jme->dev, "Waiting link change lock\n"); } if (jme_check_link(netdev, 1) && jme->old_mtu == netdev->mtu) @@ -1221,15 +1222,13 @@ jme_link_change_tasklet(unsigned long arg) if (netif_carrier_ok(netdev)) { rc = jme_setup_rx_resources(jme); if (rc) { - jeprintk(jme->pdev, "Allocating resources for RX error" - ", Device STOPPED!\n"); + pr_err("Allocating resources for RX error, Device STOPPED!\n"); goto out_enable_tasklet; } rc = jme_setup_tx_resources(jme); if (rc) { - jeprintk(jme->pdev, "Allocating resources for TX error" - ", Device STOPPED!\n"); + pr_err("Allocating resources for TX error, Device STOPPED!\n"); goto err_out_free_rx_resources; } @@ -1324,7 +1323,7 @@ jme_wake_queue_if_stopped(struct jme_adapter *jme) smp_wmb(); if (unlikely(netif_queue_stopped(jme->dev) && atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold))) { - netif_info(jme, tx_done, jme->dev, "TX Queue Waked.\n"); + netif_info(jme, tx_done, jme->dev, "TX Queue Waked\n"); netif_wake_queue(jme->dev); } @@ -1339,7 +1338,7 @@ jme_tx_clean_tasklet(unsigned long arg) struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi; int i, j, cnt = 0, max, err, mask; - tx_dbg(jme, "Into txclean.\n"); + tx_dbg(jme, "Into txclean\n"); if (unlikely(!atomic_dec_and_test(&jme->tx_cleaning))) goto out; @@ -1361,7 +1360,7 @@ jme_tx_clean_tasklet(unsigned long arg) !(txdesc[i].descwb.flags & TXWBFLAG_OWN))) { tx_dbg(jme, "txclean: %d+%d@%lu\n", - i, ctxbi->nr_desc, jiffies); + i, ctxbi->nr_desc, jiffies); err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR; @@ -1402,7 +1401,7 @@ jme_tx_clean_tasklet(unsigned long arg) ctxbi->nr_desc = 0; } - tx_dbg(jme, "txclean: done %d@%lu.\n", i, jiffies); + tx_dbg(jme, "txclean: done %d@%lu\n", i, jiffies); atomic_set(&txring->next_to_clean, i); atomic_add(cnt, &txring->nr_free); @@ -1548,10 +1547,10 @@ jme_request_irq(struct jme_adapter *jme) rc = request_irq(jme->pdev->irq, handler, irq_flags, netdev->name, netdev); if (rc) { - jeprintk(jme->pdev, - "Unable to request %s interrupt (return: %d)\n", - test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx", - rc); + netdev_err(netdev, + "Unable to request %s interrupt (return: %d)\n", + test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx", + rc); if (test_bit(JME_FLAG_MSI, &jme->flags)) { pci_disable_msi(jme->pdev); @@ -1834,7 +1833,7 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags) *flags |= TXFLAG_UDPCS; break; default: - netif_err(jme, tx_err, jme->dev, "Error upper layer protocol.\n"); + netif_err(jme, tx_err, jme->dev, "Error upper layer protocol\n"); break; } } @@ -1909,12 +1908,12 @@ jme_stop_queue_if_full(struct jme_adapter *jme) smp_wmb(); if (unlikely(atomic_read(&txring->nr_free) < (MAX_SKB_FRAGS+2))) { netif_stop_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Paused.\n"); + netif_info(jme, tx_queued, jme->dev, "TX Queue Paused\n"); smp_wmb(); if (atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold)) { netif_wake_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked.\n"); + netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked\n"); } } @@ -1922,7 +1921,8 @@ jme_stop_queue_if_full(struct jme_adapter *jme) (jiffies - txbi->start_xmit) >= TX_TIMEOUT && txbi->skb)) { netif_stop_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Stopped %d@%lu.\n", idx, jiffies); + netif_info(jme, tx_queued, jme->dev, + "TX Queue Stopped %d@%lu\n", idx, jiffies); } } @@ -1945,7 +1945,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (unlikely(idx < 0)) { netif_stop_queue(netdev); - netif_err(jme, tx_err, jme->dev, "BUG! Tx ring full when queue awake!\n"); + netif_err(jme, tx_err, jme->dev, + "BUG! Tx ring full when queue awake!\n"); return NETDEV_TX_BUSY; } @@ -1957,9 +1958,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) TXCS_QUEUE0S | TXCS_ENABLE); - tx_dbg(jme, "xmit: %d+%d@%lu\n", idx, - skb_shinfo(skb)->nr_frags + 2, - jiffies); + tx_dbg(jme, "xmit: %d+%d@%lu\n", + idx, skb_shinfo(skb)->nr_frags + 2, jiffies); jme_stop_queue_if_full(jme); return NETDEV_TX_OK; @@ -2501,7 +2501,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr) val = jread32(jme, JME_SMBCSR); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return 0xFF; } @@ -2517,7 +2517,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr) val = jread32(jme, JME_SMBINTF); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return 0xFF; } @@ -2537,7 +2537,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data) val = jread32(jme, JME_SMBCSR); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return; } @@ -2554,7 +2554,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data) val = jread32(jme, JME_SMBINTF); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return; } @@ -2699,26 +2699,26 @@ jme_init_one(struct pci_dev *pdev, */ rc = pci_enable_device(pdev); if (rc) { - jeprintk(pdev, "Cannot enable PCI device.\n"); + pr_err("Cannot enable PCI device\n"); goto err_out; } using_dac = jme_pci_dma64(pdev); if (using_dac < 0) { - jeprintk(pdev, "Cannot set PCI DMA Mask.\n"); + pr_err("Cannot set PCI DMA Mask\n"); rc = -EIO; goto err_out_disable_pdev; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - jeprintk(pdev, "No PCI resource region found.\n"); + pr_err("No PCI resource region found\n"); rc = -ENOMEM; goto err_out_disable_pdev; } rc = pci_request_regions(pdev, DRV_NAME); if (rc) { - jeprintk(pdev, "Cannot obtain PCI resource region.\n"); + pr_err("Cannot obtain PCI resource region\n"); goto err_out_disable_pdev; } @@ -2729,7 +2729,7 @@ jme_init_one(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(*jme)); if (!netdev) { - jeprintk(pdev, "Cannot allocate netdev structure.\n"); + pr_err("Cannot allocate netdev structure\n"); rc = -ENOMEM; goto err_out_release_regions; } @@ -2767,7 +2767,7 @@ jme_init_one(struct pci_dev *pdev, jme->regs = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!(jme->regs)) { - jeprintk(pdev, "Mapping PCI resource region error.\n"); + pr_err("Mapping PCI resource region error\n"); rc = -ENOMEM; goto err_out_free_netdev; } @@ -2855,8 +2855,8 @@ jme_init_one(struct pci_dev *pdev, if (!jme->mii_if.phy_id) { rc = -EIO; - jeprintk(pdev, "Can not find phy_id.\n"); - goto err_out_unmap; + pr_err("Can not find phy_id\n"); + goto err_out_unmap; } jme->reg_ghc |= GHC_LINK_POLL; @@ -2883,8 +2883,7 @@ jme_init_one(struct pci_dev *pdev, jme_reset_mac_processor(jme); rc = jme_reload_eeprom(jme); if (rc) { - jeprintk(pdev, - "Reload eeprom for reading MAC Address error.\n"); + pr_err("Reload eeprom for reading MAC Address error\n"); goto err_out_unmap; } jme_load_macaddr(netdev); @@ -2900,7 +2899,7 @@ jme_init_one(struct pci_dev *pdev, */ rc = register_netdev(netdev); if (rc) { - jeprintk(pdev, "Cannot register net device.\n"); + pr_err("Cannot register net device\n"); goto err_out_unmap; } @@ -3042,8 +3041,7 @@ static struct pci_driver jme_driver = { static int __init jme_init_module(void) { - printk(KERN_INFO PFX "JMicron JMC2XX ethernet " - "driver version %s\n", DRV_VERSION); + pr_info("JMicron JMC2XX ethernet driver version %s\n", DRV_VERSION); return pci_register_driver(&jme_driver); } diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 07ad3a457185..1360f68861b8 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -41,9 +41,6 @@ NETIF_MSG_TX_ERR | \ NETIF_MSG_HW) -#define jeprintk(pdev, fmt, args...) \ - printk(KERN_ERR PFX fmt, ## args) - #ifdef TX_DEBUG #define tx_dbg(priv, fmt, args...) \ printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args) -- cgit v1.2.3 From e04c4dc87c4af296982ff44123e064d483e826c4 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Mon, 6 Sep 2010 04:36:25 +0000 Subject: drivers/net: Removing undead ifdef CHELSIO_T1_1G The CHELSIO_T1_1G ifdef isn't necessary at this point, because it is checked in an outer ifdef level already and has no effect here. Signed-off-by: Christian Dietrich Signed-off-by: David S. Miller --- drivers/net/chelsio/subr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 599d178df62d..63ebf76d2390 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -314,14 +314,12 @@ static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr, return 0; } -#if defined(CONFIG_CHELSIO_T1_1G) static const struct mdio_ops mi1_mdio_ops = { .init = mi1_mdio_init, .read = mi1_mdio_read, .write = mi1_mdio_write, .mode_support = MDIO_SUPPORTS_C22 }; -#endif #endif -- cgit v1.2.3 From 29af9309dba25077f711f5f975977714bc43a0c3 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Sep 2010 09:00:21 +0000 Subject: net/9p/trans_fd.c: Fix unsigned return type The function has an unsigned return type, but returns a negative constant to indicate an error condition. The result of calling the function is always stored in a variable of type (signed) int, and thus unsigned can be dropped from the return type. A sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @exists@ identifier f; constant C; @@ unsigned f(...) { <+... * return -C; ...+> } // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- net/9p/trans_fd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index c85109d809ca..078eb162d9bf 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -222,7 +222,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) } } -static unsigned int +static int p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt) { int ret, n; -- cgit v1.2.3 From a0ece28539d49c9bdcc6da0bbb26771dceb57581 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Sep 2010 09:00:23 +0000 Subject: drivers/atm/firestream.c: Fix unsigned return type The function has an unsigned return type, but returns a negative constant to indicate an error condition. The result of calling the function is always stored in a variable of type (signed) int, and thus unsigned can be dropped from the return type. A sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @exists@ identifier f; constant C; @@ unsigned f(...) { <+... * return -C; ...+> } // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/atm/firestream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 8717809787fb..5d86bb803e94 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -444,8 +444,8 @@ static inline void fs_kfree_skb (struct sk_buff * skb) #define ROUND_NEAREST 3 /********** make rate (not quite as much fun as Horizon) **********/ -static unsigned int make_rate (unsigned int rate, int r, - u16 * bits, unsigned int * actual) +static int make_rate(unsigned int rate, int r, + u16 *bits, unsigned int *actual) { unsigned char exp = -1; /* hush gcc */ unsigned int man = -1; /* hush gcc */ -- cgit v1.2.3 From b31fa5bad576cd8180a5ad70c648333b44320d44 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 5 Sep 2010 21:31:11 +0000 Subject: net/caif: Use pr_fmt This patch standardizes caif message logging prefixes. Add #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ Add missing "\n"s to some logging messages Convert pr_warning to pr_warn This changes the logging message prefix from CAIF: to caif: for all uses but caif_socket.c and chnl_net.c. Those now use their filename without extension. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 22 +++++++++--------- net/caif/caif_socket.c | 19 ++++++++-------- net/caif/cfcnfg.c | 49 ++++++++++++++++++---------------------- net/caif/cfctrl.c | 59 +++++++++++++++++++++---------------------------- net/caif/cfdbgl.c | 4 +++- net/caif/cfdgml.c | 11 ++++----- net/caif/cffrml.c | 14 +++++++----- net/caif/cfmuxl.c | 14 +++++++----- net/caif/cfpkt_skbuff.c | 48 ++++++++++++++++++++-------------------- net/caif/cfrfml.c | 12 +++++----- net/caif/cfserl.c | 4 +++- net/caif/cfsrvl.c | 17 ++++++-------- net/caif/cfutill.c | 12 +++++----- net/caif/cfveil.c | 11 ++++----- net/caif/cfvidl.c | 6 +++-- net/caif/chnl_net.c | 46 ++++++++++++++++++-------------------- 16 files changed, 167 insertions(+), 181 deletions(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 0b586e9d1378..1fdfe70392dc 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -9,6 +9,8 @@ * and Sakari Ailus */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -214,7 +216,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, switch (what) { case NETDEV_REGISTER: - pr_info("CAIF: %s():register %s\n", __func__, dev->name); + pr_info("register %s\n", dev->name); caifd = caif_device_alloc(dev); if (caifd == NULL) break; @@ -225,14 +227,13 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, break; case NETDEV_UP: - pr_info("CAIF: %s(): up %s\n", __func__, dev->name); + pr_info("up %s\n", dev->name); caifd = caif_get(dev); if (caifd == NULL) break; caifdev = netdev_priv(dev); if (atomic_read(&caifd->state) == NETDEV_UP) { - pr_info("CAIF: %s():%s already up\n", - __func__, dev->name); + pr_info("%s already up\n", dev->name); break; } atomic_set(&caifd->state, what); @@ -273,7 +274,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("CAIF: %s():going down %s\n", __func__, dev->name); + pr_info("going down %s\n", dev->name); if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN || atomic_read(&caifd->state) == NETDEV_DOWN) @@ -295,11 +296,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("CAIF: %s(): down %s\n", __func__, dev->name); + pr_info("down %s\n", dev->name); if (atomic_read(&caifd->in_use)) - pr_warning("CAIF: %s(): " - "Unregistering an active CAIF device: %s\n", - __func__, dev->name); + pr_warn("Unregistering an active CAIF device: %s\n", + dev->name); cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); dev_put(dev); atomic_set(&caifd->state, what); @@ -307,7 +307,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, case NETDEV_UNREGISTER: caifd = caif_get(dev); - pr_info("CAIF: %s(): unregister %s\n", __func__, dev->name); + pr_info("unregister %s\n", dev->name); atomic_set(&caifd->state, what); caif_device_destroy(dev); break; @@ -391,7 +391,7 @@ static int __init caif_device_init(void) int result; cfg = cfcnfg_create(); if (!cfg) { - pr_warning("CAIF: %s(): can't create cfcnfg.\n", __func__); + pr_warn("can't create cfcnfg\n"); goto err_cfcnfg_create_failed; } result = register_pernet_device(&caif_net_ops); diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 8ce904786116..fd1f5df0827c 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -157,8 +159,8 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { - trace_printk("CAIF: %s():" - " sending flow OFF (queue len = %d %d)\n", + trace_printk("CAIF: %s(): " + "sending flow OFF (queue len = %d %d)\n", __func__, atomic_read(&cf_sk->sk.sk_rmem_alloc), sk_rcvbuf_lowwater(cf_sk)); @@ -172,8 +174,8 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { set_rx_flow_off(cf_sk); - trace_printk("CAIF: %s():" - " sending flow OFF due to rmem_schedule\n", + trace_printk("CAIF: %s(): " + "sending flow OFF due to rmem_schedule\n", __func__); dbfs_atomic_inc(&cnt.num_rx_flow_off); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); @@ -275,8 +277,7 @@ static void caif_ctrl_cb(struct cflayer *layr, break; default: - pr_debug("CAIF: %s(): Unexpected flow command %d\n", - __func__, flow); + pr_debug("Unexpected flow command %d\n", flow); } } @@ -536,8 +537,7 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk, /* Slight paranoia, probably not needed. */ if (unlikely(loopcnt++ > 1000)) { - pr_warning("CAIF: %s(): transmit retries failed," - " error = %d\n", __func__, ret); + pr_warn("transmit retries failed, error = %d\n", ret); break; } @@ -902,8 +902,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, cf_sk->maxframe = dev->mtu - (headroom + tailroom); dev_put(dev); if (cf_sk->maxframe < 1) { - pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n", - __func__, dev->mtu); + pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); err = -ENODEV; goto out; } diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 1c29189b344d..ef93a131310b 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -3,6 +3,9 @@ * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -78,7 +81,7 @@ struct cfcnfg *cfcnfg_create(void) /* Initiate this layer */ this = kzalloc(sizeof(struct cfcnfg), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } this->mux = cfmuxl_create(); @@ -106,7 +109,7 @@ struct cfcnfg *cfcnfg_create(void) layer_set_up(this->ctrl, this); return this; out_of_mem: - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); kfree(this->mux); kfree(this->ctrl); kfree(this); @@ -194,7 +197,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) caif_assert(adap_layer != NULL); channel_id = adap_layer->id; if (adap_layer->dn == NULL || channel_id == 0) { - pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); + pr_err("adap_layer->id is 0\n"); ret = -ENOTCONN; goto end; } @@ -204,9 +207,8 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) layer_set_up(servl, NULL); ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); if (servl == NULL) { - pr_err("CAIF: %s(): PROTOCOL ERROR " - "- Error removing service_layer Channel_Id(%d)", - __func__, channel_id); + pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)", + channel_id); ret = -EINVAL; goto end; } @@ -216,18 +218,14 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); if (phyinfo == NULL) { - pr_warning("CAIF: %s(): " - "No interface to send disconnect to\n", - __func__); + pr_warn("No interface to send disconnect to\n"); ret = -ENODEV; goto end; } if (phyinfo->id != phyid || phyinfo->phy_layer->id != phyid || phyinfo->frm_layer->id != phyid) { - pr_err("CAIF: %s(): " - "Inconsistency in phy registration\n", - __func__); + pr_err("Inconsistency in phy registration\n"); ret = -EINVAL; goto end; } @@ -276,21 +274,20 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, { struct cflayer *frml; if (adap_layer == NULL) { - pr_err("CAIF: %s(): adap_layer is zero", __func__); + pr_err("adap_layer is zero\n"); return -EINVAL; } if (adap_layer->receive == NULL) { - pr_err("CAIF: %s(): adap_layer->receive is NULL", __func__); + pr_err("adap_layer->receive is NULL\n"); return -EINVAL; } if (adap_layer->ctrlcmd == NULL) { - pr_err("CAIF: %s(): adap_layer->ctrlcmd == NULL", __func__); + pr_err("adap_layer->ctrlcmd == NULL\n"); return -EINVAL; } frml = cnfg->phy_layers[param->phyid].frm_layer; if (frml == NULL) { - pr_err("CAIF: %s(): Specified PHY type does not exist!", - __func__); + pr_err("Specified PHY type does not exist!\n"); return -ENODEV; } caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id); @@ -330,9 +327,7 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, struct net_device *netdev; if (adapt_layer == NULL) { - pr_debug("CAIF: %s(): link setup response " - "but no client exist, send linkdown back\n", - __func__); + pr_debug("link setup response but no client exist, send linkdown back\n"); cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL); return; } @@ -374,13 +369,11 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, servicel = cfdbgl_create(channel_id, &phyinfo->dev_info); break; default: - pr_err("CAIF: %s(): Protocol error. " - "Link setup response - unknown channel type\n", - __func__); + pr_err("Protocol error. Link setup response - unknown channel type\n"); return; } if (!servicel) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } layer_set_dn(servicel, cnfg->mux); @@ -418,7 +411,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, } } if (*phyid == 0) { - pr_err("CAIF: %s(): No Available PHY ID\n", __func__); + pr_err("No Available PHY ID\n"); return; } @@ -427,7 +420,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_driver = cfserl_create(CFPHYTYPE_FRAG, *phyid, stx); if (!phy_driver) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } @@ -436,7 +429,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_driver = NULL; break; default: - pr_err("CAIF: %s(): %d", __func__, phy_type); + pr_err("%d\n", phy_type); return; break; } @@ -455,7 +448,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_layer->type = phy_type; frml = cffrml_create(*phyid, fcs); if (!frml) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cnfg->phy_layers[*phyid].frm_layer = frml; diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 563145fdc4c3..08f267a109aa 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -36,7 +38,7 @@ struct cflayer *cfctrl_create(void) struct cfctrl *this = kmalloc(sizeof(struct cfctrl), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); @@ -132,9 +134,7 @@ struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (cfctrl_req_eq(req, p)) { if (p != first) - pr_warning("CAIF: %s(): Requests are not " - "received in order\n", - __func__); + pr_warn("Requests are not received in order\n"); atomic_set(&ctrl->rsp_seq_no, p->sequence_no); @@ -177,7 +177,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) int ret; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); @@ -189,8 +189,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit enum message\n", - __func__); + pr_err("Could not transmit enum message\n"); cfpkt_destroy(pkt); } } @@ -208,7 +207,7 @@ int cfctrl_linkup_request(struct cflayer *layer, char utility_name[16]; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); @@ -253,13 +252,13 @@ int cfctrl_linkup_request(struct cflayer *layer, param->u.utility.paramlen); break; default: - pr_warning("CAIF: %s():Request setup of bad link type = %d\n", - __func__, param->linktype); + pr_warn("Request setup of bad link type = %d\n", + param->linktype); return -EINVAL; } req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } req->client_layer = user_layer; @@ -276,8 +275,7 @@ int cfctrl_linkup_request(struct cflayer *layer, ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit linksetup request\n", - __func__); + pr_err("Could not transmit linksetup request\n"); cfpkt_destroy(pkt); return -ENODEV; } @@ -291,7 +289,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); @@ -300,8 +298,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit link-down request\n", - __func__); + pr_err("Could not transmit link-down request\n"); cfpkt_destroy(pkt); } return ret; @@ -313,7 +310,7 @@ void cfctrl_sleep_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP); @@ -330,7 +327,7 @@ void cfctrl_wake_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE); @@ -347,7 +344,7 @@ void cfctrl_getstartreason_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON); @@ -364,12 +361,11 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) struct cfctrl_request_info *p, *tmp; struct cfctrl *ctrl = container_obj(layr); spin_lock(&ctrl->info_list_lock); - pr_warning("CAIF: %s(): enter\n", __func__); + pr_warn("enter\n"); list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (p->client_layer == adap_layer) { - pr_warning("CAIF: %s(): cancel req :%d\n", __func__, - p->sequence_no); + pr_warn("cancel req :%d\n", p->sequence_no); list_del(&p->list); kfree(p); } @@ -520,9 +516,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfpkt_extr_head(pkt, ¶m, len); break; default: - pr_warning("CAIF: %s(): Request setup " - "- invalid link type (%d)", - __func__, serv); + pr_warn("Request setup - invalid link type (%d)\n", + serv); goto error; } @@ -532,9 +527,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || cfpkt_erroneous(pkt)) { - pr_err("CAIF: %s(): Invalid O/E bit or parse " - "error on CAIF control channel", - __func__); + pr_err("Invalid O/E bit or parse error on CAIF control channel\n"); cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, req ? req->client_layer @@ -556,8 +549,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); break; case CFCTRL_CMD_LINK_ERR: - pr_err("CAIF: %s(): Frame Error Indication received\n", - __func__); + pr_err("Frame Error Indication received\n"); cfctrl->res.linkerror_ind(); break; case CFCTRL_CMD_ENUM: @@ -576,7 +568,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfctrl->res.radioset_rsp(); break; default: - pr_err("CAIF: %s(): Unrecognized Control Frame\n", __func__); + pr_err("Unrecognized Control Frame\n"); goto error; break; } @@ -595,8 +587,7 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, case CAIF_CTRLCMD_FLOW_OFF_IND: spin_lock(&this->info_list_lock); if (!list_empty(&this->list)) { - pr_debug("CAIF: %s(): Received flow off in " - "control layer", __func__); + pr_debug("Received flow off in control layer\n"); } spin_unlock(&this->info_list_lock); break; @@ -620,7 +611,7 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) if (!ctrl->loop_linkused[linkid]) goto found; spin_unlock(&ctrl->loop_linkid_lock); - pr_err("CAIF: %s(): Out of link-ids\n", __func__); + pr_err("Out of link-ids\n"); return -EINVAL; found: if (!ctrl->loop_linkused[linkid]) diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 676648cac8dd..496fda9ac66f 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -17,7 +19,7 @@ struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *dbg = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!dbg) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index ed9d53aff280..d3ed264ad6c4 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -26,7 +28,7 @@ struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *dgm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!dgm) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -49,14 +51,14 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->ctrlcmd != NULL); if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } if ((cmd & DGM_CMD_BIT) == 0) { if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -75,8 +77,7 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) return 0; default: cfpkt_destroy(pkt); - pr_info("CAIF: %s(): Unknown datagram control %d (0x%x)\n", - __func__, cmd, cmd); + pr_info("Unknown datagram control %d (0x%x)\n", cmd, cmd); return -EPROTO; } } diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index e86a4ca3b217..a445043931ae 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -6,6 +6,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -32,7 +34,7 @@ struct cflayer *cffrml_create(u16 phyid, bool use_fcs) { struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cffrml, layer) == 0); @@ -83,7 +85,7 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) if (cfpkt_setlen(pkt, len) < 0) { ++cffrml_rcv_error; - pr_err("CAIF: %s():Framing length error (%d)\n", __func__, len); + pr_err("Framing length error (%d)\n", len); cfpkt_destroy(pkt); return -EPROTO; } @@ -99,14 +101,14 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_add_trail(pkt, &tmp, 2); ++cffrml_rcv_error; ++cffrml_rcv_checsum_error; - pr_info("CAIF: %s(): Frame checksum error " - "(0x%x != 0x%x)\n", __func__, hdrchks, pktchks); + pr_info("Frame checksum error (0x%x != 0x%x)\n", + hdrchks, pktchks); return -EILSEQ; } } if (cfpkt_erroneous(pkt)) { ++cffrml_rcv_error; - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -132,7 +134,7 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) cfpkt_add_head(pkt, &tmp, 2); cfpkt_info(pkt)->hdr_len += 2; if (cfpkt_erroneous(pkt)) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); return -EPROTO; } ret = layr->dn->transmit(layr->dn, pkt); diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 80c8d332b258..46f34b2e0478 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -3,6 +3,9 @@ * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -190,7 +193,7 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) u8 id; struct cflayer *up; if (cfpkt_extr_head(pkt, &id, 1) < 0) { - pr_err("CAIF: %s(): erroneous Caif Packet\n", __func__); + pr_err("erroneous Caif Packet\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -199,8 +202,8 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) up = get_up(muxl, id); spin_unlock(&muxl->receive_lock); if (up == NULL) { - pr_info("CAIF: %s():Received data on unknown link ID = %d " - "(0x%x) up == NULL", __func__, id, id); + pr_info("Received data on unknown link ID = %d (0x%x) up == NULL", + id, id); cfpkt_destroy(pkt); /* * Don't return ERROR, since modem misbehaves and sends out @@ -223,9 +226,8 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) struct caif_payload_info *info = cfpkt_info(pkt); dn = get_dn(muxl, cfpkt_info(pkt)->dev_info); if (dn == NULL) { - pr_warning("CAIF: %s(): Send data on unknown phy " - "ID = %d (0x%x)\n", - __func__, info->dev_info->id, info->dev_info->id); + pr_warn("Send data on unknown phy ID = %d (0x%x)\n", + info->dev_info->id, info->dev_info->id); return -ENOTCONN; } info->hdr_len += 1; diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index c49a6695793a..d7e865e2ff65 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -12,11 +14,12 @@ #define PKT_PREFIX 48 #define PKT_POSTFIX 2 #define PKT_LEN_WHEN_EXTENDING 128 -#define PKT_ERROR(pkt, errmsg) do { \ - cfpkt_priv(pkt)->erronous = true; \ - skb_reset_tail_pointer(&pkt->skb); \ - pr_warning("CAIF: " errmsg);\ - } while (0) +#define PKT_ERROR(pkt, errmsg) \ +do { \ + cfpkt_priv(pkt)->erronous = true; \ + skb_reset_tail_pointer(&pkt->skb); \ + pr_warn(errmsg); \ +} while (0) struct cfpktq { struct sk_buff_head head; @@ -130,13 +133,13 @@ int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len) return -EPROTO; if (unlikely(len > skb->len)) { - PKT_ERROR(pkt, "cfpkt_extr_head read beyond end of packet\n"); + PKT_ERROR(pkt, "read beyond end of packet\n"); return -EPROTO; } if (unlikely(len > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_extr_head linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } } @@ -156,11 +159,11 @@ int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len) return -EPROTO; if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_extr_trail linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } if (unlikely(skb->data + len > skb_tail_pointer(skb))) { - PKT_ERROR(pkt, "cfpkt_extr_trail read beyond end of packet\n"); + PKT_ERROR(pkt, "read beyond end of packet\n"); return -EPROTO; } from = skb_tail_pointer(skb) - len; @@ -202,7 +205,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) /* Make sure data is writable */ if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) { - PKT_ERROR(pkt, "cfpkt_add_body: cow failed\n"); + PKT_ERROR(pkt, "cow failed\n"); return -EPROTO; } /* @@ -211,8 +214,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) * lengths of the top SKB. */ if (lastskb != skb) { - pr_warning("CAIF: %s(): Packet is non-linear\n", - __func__); + pr_warn("Packet is non-linear\n"); skb->len += len; skb->data_len += len; } @@ -242,14 +244,14 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) if (unlikely(is_erronous(pkt))) return -EPROTO; if (unlikely(skb_headroom(skb) < len)) { - PKT_ERROR(pkt, "cfpkt_add_head: no headroom\n"); + PKT_ERROR(pkt, "no headroom\n"); return -EPROTO; } /* Make sure data is writable */ ret = skb_cow_data(skb, 0, &lastskb); if (unlikely(ret < 0)) { - PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n"); + PKT_ERROR(pkt, "cow failed\n"); return ret; } @@ -283,7 +285,7 @@ inline u16 cfpkt_iterate(struct cfpkt *pkt, if (unlikely(is_erronous(pkt))) return -EPROTO; if (unlikely(skb_linearize(&pkt->skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_iterate: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt)); @@ -309,7 +311,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len) /* Need to expand SKB */ if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len))) - PKT_ERROR(pkt, "cfpkt_setlen: skb_pad_trail failed\n"); + PKT_ERROR(pkt, "skb_pad_trail failed\n"); return cfpkt_getlen(pkt); } @@ -380,8 +382,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) return NULL; if (skb->data + pos > skb_tail_pointer(skb)) { - PKT_ERROR(pkt, - "cfpkt_split: trying to split beyond end of packet"); + PKT_ERROR(pkt, "trying to split beyond end of packet\n"); return NULL; } @@ -455,17 +456,17 @@ int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen) return -EPROTO; /* Make sure SKB is writable */ if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { - PKT_ERROR(pkt, "cfpkt_raw_append: skb_cow_data failed\n"); + PKT_ERROR(pkt, "skb_cow_data failed\n"); return -EPROTO; } if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_raw_append: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } if (unlikely(skb_tailroom(skb) < buflen)) { - PKT_ERROR(pkt, "cfpkt_raw_append: buffer too short - failed\n"); + PKT_ERROR(pkt, "buffer too short - failed\n"); return -EPROTO; } @@ -483,14 +484,13 @@ int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen) return -EPROTO; if (unlikely(buflen > skb->len)) { - PKT_ERROR(pkt, "cfpkt_raw_extract: buflen too large " - "- failed\n"); + PKT_ERROR(pkt, "buflen too large - failed\n"); return -EPROTO; } if (unlikely(buflen > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_raw_extract: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } } diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index eb1602022ac0..6acaeba20603 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -48,7 +50,7 @@ struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info, kzalloc(sizeof(struct cfrfml), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } @@ -178,9 +180,7 @@ out: cfpkt_destroy(rfml->incomplete_frm); rfml->incomplete_frm = NULL; - pr_info("CAIF: %s(): " - "Connection error %d triggered on RFM link\n", - __func__, err); + pr_info("Connection error %d triggered on RFM link\n", err); /* Trigger connection error upon failure.*/ layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, @@ -280,9 +280,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) out: if (err != 0) { - pr_info("CAIF: %s(): " - "Connection error %d triggered on RFM link\n", - __func__, err); + pr_info("Connection error %d triggered on RFM link\n", err); /* Trigger connection error upon failure.*/ layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index a11fbd68a13d..9297f7dea9d8 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -34,7 +36,7 @@ struct cflayer *cfserl_create(int type, int instance, bool use_stx) { struct cfserl *this = kmalloc(sizeof(struct cfserl), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfserl, layer) == 0); diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index f40939a91211..ab5e542526bf 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -79,8 +81,7 @@ static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, layr->up->ctrlcmd(layr->up, ctrl, phyid); break; default: - pr_warning("CAIF: %s(): " - "Unexpected ctrl in cfsrvl (%d)\n", __func__, ctrl); + pr_warn("Unexpected ctrl in cfsrvl (%d)\n", ctrl); /* We have both modem and phy flow on, send flow on */ layr->up->ctrlcmd(layr->up, ctrl, phyid); service->phy_flow_on = true; @@ -107,14 +108,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) u8 flow_on = SRVL_FLOW_ON; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", - __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } if (cfpkt_add_head(pkt, &flow_on, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", - __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -131,14 +130,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) u8 flow_off = SRVL_FLOW_OFF; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", - __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", - __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index 02795aff57a4..efad410e4c82 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -26,7 +28,7 @@ struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *util = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!util) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -47,7 +49,7 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->up->receive != NULL); caif_assert(layr->up->ctrlcmd != NULL); if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -64,16 +66,14 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); return 0; case UTIL_REMOTE_SHUTDOWN: /* Remote Shutdown Request */ - pr_err("CAIF: %s(): REMOTE SHUTDOWN REQUEST RECEIVED\n", - __func__); + pr_err("REMOTE SHUTDOWN REQUEST RECEIVED\n"); layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0); service->open = false; cfpkt_destroy(pkt); return 0; default: cfpkt_destroy(pkt); - pr_warning("CAIF: %s(): Unknown service control %d (0x%x)\n", - __func__, cmd, cmd); + pr_warn("Unknown service control %d (0x%x)\n", cmd, cmd); return -EPROTO; } } diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 77cc09faac9a..3b425b189a99 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -25,7 +27,7 @@ struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *vei = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vei) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -47,7 +49,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -67,8 +69,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); return 0; default: /* SET RS232 PIN */ - pr_warning("CAIF: %s():Unknown VEI control packet %d (0x%x)!\n", - __func__, cmd, cmd); + pr_warn("Unknown VEI control packet %d (0x%x)!\n", cmd, cmd); cfpkt_destroy(pkt); return -EPROTO; } @@ -86,7 +87,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->dn->transmit != NULL); if (cfpkt_add_head(pkt, &tmp, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); return -EPROTO; } diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c index ada6ee2d48f5..bf6fef2a0eff 100644 --- a/net/caif/cfvidl.c +++ b/net/caif/cfvidl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -21,7 +23,7 @@ struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *vid = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vid) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -38,7 +40,7 @@ static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt) { u32 videoheader; if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 4293e190ec53..86aac24b0225 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c @@ -5,6 +5,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -29,7 +31,7 @@ #define CAIF_NET_DEFAULT_QUEUE_LEN 500 #undef pr_debug -#define pr_debug pr_warning +#define pr_debug pr_warn /*This list is protected by the rtnl lock. */ static LIST_HEAD(chnl_net_list); @@ -142,8 +144,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, int phyid) { struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); - pr_debug("CAIF: %s(): NET flowctrl func called flow: %s\n", - __func__, + pr_debug("NET flowctrl func called flow: %s\n", flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" : flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" : @@ -196,12 +197,12 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) priv = netdev_priv(dev); if (skb->len > priv->netdev->mtu) { - pr_warning("CAIF: %s(): Size of skb exceeded MTU\n", __func__); + pr_warn("Size of skb exceeded MTU\n"); return -ENOSPC; } if (!priv->flowenabled) { - pr_debug("CAIF: %s(): dropping packets flow off\n", __func__); + pr_debug("dropping packets flow off\n"); return NETDEV_TX_BUSY; } @@ -237,7 +238,7 @@ static int chnl_net_open(struct net_device *dev) ASSERT_RTNL(); priv = netdev_priv(dev); if (!priv) { - pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__); + pr_debug("chnl_net_open: no priv\n"); return -ENODEV; } @@ -246,18 +247,17 @@ static int chnl_net_open(struct net_device *dev) result = caif_connect_client(&priv->conn_req, &priv->chnl, &llifindex, &headroom, &tailroom); if (result != 0) { - pr_debug("CAIF: %s(): err: " - "Unable to register and open device," - " Err:%d\n", - __func__, - result); + pr_debug("err: " + "Unable to register and open device," + " Err:%d\n", + result); goto error; } lldev = dev_get_by_index(dev_net(dev), llifindex); if (lldev == NULL) { - pr_debug("CAIF: %s(): no interface?\n", __func__); + pr_debug("no interface?\n"); result = -ENODEV; goto error; } @@ -279,9 +279,7 @@ static int chnl_net_open(struct net_device *dev) dev_put(lldev); if (mtu < 100) { - pr_warning("CAIF: %s(): " - "CAIF Interface MTU too small (%d)\n", - __func__, mtu); + pr_warn("CAIF Interface MTU too small (%d)\n", mtu); result = -ENODEV; goto error; } @@ -296,33 +294,32 @@ static int chnl_net_open(struct net_device *dev) rtnl_lock(); if (result == -ERESTARTSYS) { - pr_debug("CAIF: %s(): wait_event_interruptible" - " woken by a signal\n", __func__); + pr_debug("wait_event_interruptible woken by a signal\n"); result = -ERESTARTSYS; goto error; } if (result == 0) { - pr_debug("CAIF: %s(): connect timeout\n", __func__); + pr_debug("connect timeout\n"); caif_disconnect_client(&priv->chnl); priv->state = CAIF_DISCONNECTED; - pr_debug("CAIF: %s(): state disconnected\n", __func__); + pr_debug("state disconnected\n"); result = -ETIMEDOUT; goto error; } if (priv->state != CAIF_CONNECTED) { - pr_debug("CAIF: %s(): connect failed\n", __func__); + pr_debug("connect failed\n"); result = -ECONNREFUSED; goto error; } - pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__); + pr_debug("CAIF Netdevice connected\n"); return 0; error: caif_disconnect_client(&priv->chnl); priv->state = CAIF_DISCONNECTED; - pr_debug("CAIF: %s(): state disconnected\n", __func__); + pr_debug("state disconnected\n"); return result; } @@ -413,7 +410,7 @@ static void caif_netlink_parms(struct nlattr *data[], struct caif_connect_request *conn_req) { if (!data) { - pr_warning("CAIF: %s: no params data found\n", __func__); + pr_warn("no params data found\n"); return; } if (data[IFLA_CAIF_IPV4_CONNID]) @@ -442,8 +439,7 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, ret = register_netdevice(dev); if (ret) - pr_warning("CAIF: %s(): device rtml registration failed\n", - __func__); + pr_warn("device rtml registration failed\n"); return ret; } -- cgit v1.2.3 From f6c9322c3a0cd50a6996094327347c87cd2f4bd8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 5 Sep 2010 22:08:09 +0000 Subject: net/caifcaif_dev.c: Use netdev_ Convert pr_("%s" ..., (struct netdev *)->name ...) to netdev_((struct netdev *), ...) Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 1fdfe70392dc..0fd01dd17c48 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -216,7 +216,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, switch (what) { case NETDEV_REGISTER: - pr_info("register %s\n", dev->name); + netdev_info(dev, "register\n"); caifd = caif_device_alloc(dev); if (caifd == NULL) break; @@ -227,13 +227,13 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, break; case NETDEV_UP: - pr_info("up %s\n", dev->name); + netdev_info(dev, "up\n"); caifd = caif_get(dev); if (caifd == NULL) break; caifdev = netdev_priv(dev); if (atomic_read(&caifd->state) == NETDEV_UP) { - pr_info("%s already up\n", dev->name); + netdev_info(dev, "already up\n"); break; } atomic_set(&caifd->state, what); @@ -274,7 +274,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("going down %s\n", dev->name); + netdev_info(dev, "going down\n"); if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN || atomic_read(&caifd->state) == NETDEV_DOWN) @@ -296,10 +296,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("down %s\n", dev->name); + netdev_info(dev, "down\n"); if (atomic_read(&caifd->in_use)) - pr_warn("Unregistering an active CAIF device: %s\n", - dev->name); + netdev_warn(dev, + "Unregistering an active CAIF device\n"); cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); dev_put(dev); atomic_set(&caifd->state, what); @@ -307,7 +307,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, case NETDEV_UNREGISTER: caifd = caif_get(dev); - pr_info("unregister %s\n", dev->name); + netdev_info(dev, "unregister\n"); atomic_set(&caifd->state, what); caif_device_destroy(dev); break; -- cgit v1.2.3 From ebc872c7bd7155bcc7db2343155729d13bf4a2ee Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Sun, 5 Sep 2010 22:20:11 +0000 Subject: mlx4_en: Consider napi_get_frags() failure. If failed to get skb frags using napi_get_frags(), the packet is dropped. Reported-by: Eric Dumazet Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index c4aad7f2beb9..570f2508fb30 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -591,6 +591,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud * - not an IP fragment */ if (dev->features & NETIF_F_GRO) { struct sk_buff *gro_skb = napi_get_frags(&cq->napi); + if (!gro_skb) + goto next; nr = mlx4_en_complete_rx_desc( priv, rx_desc, -- cgit v1.2.3 From d61702f1273b71c2809365a7806d7fe84fd77f15 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Sun, 5 Sep 2010 22:20:24 +0000 Subject: mlx4_en: Fixed Ethtool statistics report The values didn't match the title after removing the LRO statistics in commit fa37a9586f92051de03a13e55e5ec3880bb6783e Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 2 +- drivers/net/mlx4/mlx4_en.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 01634a3efe85..056152b3ff58 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -107,7 +107,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = { "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5", "tx_prio_6", "tx_prio_7", }; -#define NUM_MAIN_STATS 18 +#define NUM_MAIN_STATS 21 #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index ce8e2338ee31..1fc16ab7ad2f 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -385,7 +385,7 @@ struct mlx4_en_port_stats { unsigned long rx_chksum_good; unsigned long rx_chksum_none; unsigned long tx_chksum_offload; -#define NUM_PORT_STATS 11 +#define NUM_PORT_STATS 8 }; struct mlx4_en_perf_stats { -- cgit v1.2.3 From db40980fcdb560d7992b0511df16cdd3f7e381f3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Sep 2010 11:13:50 +0000 Subject: net: poll() optimizations No need to test twice sk->sk_shutdown & RCV_SHUTDOWN Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/bluetooth/af_bluetooth.c | 5 ++--- net/core/datagram.c | 5 ++--- net/sctp/socket.c | 5 ++--- net/unix/af_unix.c | 5 ++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 421c45bd1b95..ed0f22f57668 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -297,13 +297,12 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; if (sk->sk_state == BT_CLOSED) diff --git a/net/core/datagram.c b/net/core/datagram.c index 251997a95483..4df1b7a6c1bf 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -746,13 +746,12 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f4bec2772351..cf6dcc908b88 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5707,13 +5707,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* Is it readable? Reconsider this code with TCP-style support. */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* The association is either gone or not ready. */ diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4414a18c63b4..9077b4ea00c5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2024,11 +2024,10 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ -- cgit v1.2.3 From b6f45c2c03c1d858233cb0c35471dcb6cb213cdf Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 1 Sep 2010 18:16:22 -0700 Subject: ray_cs: make data const Make the startup and other data parameters that are read/only const. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: John W. Linville --- drivers/net/wireless/ray_cs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 9c38fc331dca..390ccf6e08a3 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -198,7 +198,7 @@ module_param(bc, int, 0); module_param(phy_addr, charp, 0); module_param(ray_mem_speed, int, 0); -static UCHAR b5_default_startup_parms[] = { +static const UCHAR b5_default_startup_parms[] = { 0, 0, /* Adhoc station */ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -233,7 +233,7 @@ static UCHAR b5_default_startup_parms[] = { 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */ }; -static UCHAR b4_default_startup_parms[] = { +static const UCHAR b4_default_startup_parms[] = { 0, 0, /* Adhoc station */ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -265,9 +265,9 @@ static UCHAR b4_default_startup_parms[] = { }; /*===========================================================================*/ -static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 }; +static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 }; -static char hop_pattern_length[] = { 1, +static const char hop_pattern_length[] = { 1, USA_HOP_MOD, EUROPE_HOP_MOD, JAPAN_HOP_MOD, KOREA_HOP_MOD, SPAIN_HOP_MOD, FRANCE_HOP_MOD, @@ -275,7 +275,7 @@ static char hop_pattern_length[] = { 1, JAPAN_TEST_HOP_MOD }; -static char rcsid[] = +static const char rcsid[] = "Raylink/WebGear wireless LAN - Corey "; static const struct net_device_ops ray_netdev_ops = { @@ -2608,7 +2608,7 @@ static void clear_interrupt(ray_dev_t *local) #ifdef CONFIG_PROC_FS #define MAXDATA (PAGE_SIZE - 80) -static char *card_status[] = { +static const char *card_status[] = { "Card inserted - uninitialized", /* 0 */ "Card not downloaded", /* 1 */ "Waiting for download parameters", /* 2 */ @@ -2625,8 +2625,8 @@ static char *card_status[] = { "Association failed" /* 16 */ }; -static char *nettype[] = { "Adhoc", "Infra " }; -static char *framing[] = { "Encapsulation", "Translation" } +static const char *nettype[] = { "Adhoc", "Infra " }; +static const char *framing[] = { "Encapsulation", "Translation" } ; /*===========================================================================*/ -- cgit v1.2.3 From 7a374d8eeb1140c08d215de7a181e595ca606196 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 1 Sep 2010 18:17:21 -0700 Subject: airo: make strings const Make read/only data structures const. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1d05445d4ba3..c7528e5794d1 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -105,7 +105,7 @@ static struct pci_driver airo_driver = { of statistics in the /proc filesystem */ #define IGNLABEL(comment) NULL -static char *statsLabels[] = { +static const char *statsLabels[] = { "RxOverrun", IGNLABEL("RxPlcpCrcErr"), IGNLABEL("RxPlcpFormatErr"), @@ -932,7 +932,7 @@ typedef struct aironet_ioctl { unsigned char __user *data; // d-data } aironet_ioctl; -static char swversion[] = "2.1"; +static const char swversion[] = "2.1"; #endif /* CISCO_EXT */ #define NUM_MODULES 2 @@ -1374,7 +1374,7 @@ static int micsetup(struct airo_info *ai) { return SUCCESS; } -static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; +static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; /*=========================================================================== * Description: Mic a packet @@ -5024,7 +5024,7 @@ static void proc_config_on_close(struct inode *inode, struct file *file) airo_config_commit(dev, NULL, NULL, NULL); } -static char *get_rmode(__le16 mode) +static const char *get_rmode(__le16 mode) { switch(mode & RXMODE_MASK) { case RXMODE_RFMON: return "rfmon"; -- cgit v1.2.3 From 754dc53641e0038cd4fd3574b1f5b3c7239f73ce Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 2 Sep 2010 01:34:41 -0700 Subject: ath9k_hw: Add capability flag for Antenna diversity and combining feature This is enabled only for ar9285. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.h | 2 ++ drivers/net/wireless/ath/ath9k/eeprom_4k.c | 4 ++++ drivers/net/wireless/ath/ath9k/hw.c | 9 +++++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + 4 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 7f48df1e2903..090778da5d67 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -266,6 +266,8 @@ enum eeprom_param { EEP_INTERNAL_REGULATOR, EEP_SWREG, EEP_PAPRD, + EEP_MODAL_VER, + EEP_ANT_DIV_CTL1, }; enum ar5416_rates { diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 9cccd12e8f21..2e1397b68a87 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -213,6 +213,10 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, return 0; case EEP_PWR_TABLE_OFFSET: return AR5416_PWR_TABLE_OFFSET_DB; + case EEP_MODAL_VER: + return pModal->version; + case EEP_ANT_DIV_CTL1: + return pModal->antdiv_ctl1; default: return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 3384ca164562..68940a8864e0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2056,6 +2056,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; u16 capField = 0, eeval; + u8 ant_div_ctl1; eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); regulatory->current_rd = eeval; @@ -2280,6 +2281,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah)) pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; + if (AR_SREV_9285(ah)) + if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) { + ant_div_ctl1 = + ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); + if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) + pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; + } + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1601dd439890..1a0efbd03e4f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -204,6 +204,7 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_FASTCLOCK = BIT(20), ATH9K_HW_CAP_SGI_20 = BIT(21), ATH9K_HW_CAP_PAPRD = BIT(22), + ATH9K_HW_CAP_ANT_DIV_COMB = BIT(23), }; struct ath9k_hw_capabilities { -- cgit v1.2.3 From 21cc630f47d8589a42d563e89be4c631edbe8716 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 2 Sep 2010 01:34:42 -0700 Subject: ath9k_hw: Add functions to get/set antenna diversity configuration Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 35 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9002_phy.h | 2 ++ drivers/net/wireless/ath/ath9k/hw.h | 10 +++++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index adbf031fbc5a..cd56c8692705 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -530,3 +530,38 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) ar9002_hw_set_nf_limits(ah); } + +void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf) +{ + u32 regval; + + regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); + antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >> + AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S; + antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >> + AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; + antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> + AR_PHY_9285_FAST_DIV_BIAS_S; +} +EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get); + +void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf) +{ + u32 regval; + + regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); + regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF | + AR_PHY_9285_ANT_DIV_ALT_LNACONF | + AR_PHY_9285_FAST_DIV_BIAS); + regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S) + & AR_PHY_9285_ANT_DIV_MAIN_LNACONF); + regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S) + & AR_PHY_9285_ANT_DIV_ALT_LNACONF); + regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S) + & AR_PHY_9285_FAST_DIV_BIAS); + + REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); +} +EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index c5151a4dd10b..37663dbbcf57 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -302,6 +302,8 @@ #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 #define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac +#define AR_PHY_9285_FAST_DIV_BIAS 0x00007E00 +#define AR_PHY_9285_FAST_DIV_BIAS_S 9 #define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 #define AR_PHY_9285_ANT_DIV_CTL 0x01000000 #define AR_PHY_9285_ANT_DIV_CTL_S 24 diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1a0efbd03e4f..197c717286e7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -496,6 +496,12 @@ struct ath_gen_timer_table { } timer_mask; }; +struct ath_hw_antcomb_conf { + u8 main_lna_conf; + u8 alt_lna_conf; + u8 fast_div_bias; +}; + /** * struct ath_hw_private_ops - callbacks used internally by hardware code * @@ -889,6 +895,10 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); u32 ath9k_hw_getdefantenna(struct ath_hw *ah); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); +void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); +void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); /* General Operation */ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); -- cgit v1.2.3 From 102885a5d114abad8f9d4101f94ce5b28c232231 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 2 Sep 2010 01:34:43 -0700 Subject: ath9k: Implement an algorithm for Antenna diversity and combining This algorithm chooses the best main and alt lna out of LNA1, LNA2, LNA1+LNA2 and LNA1-LNA2 to improve rx for single chain chips(AR9285). This would greatly improve rx when there is only one antenna is connected with AR9285. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 56 ++++ drivers/net/wireless/ath/ath9k/init.c | 3 + drivers/net/wireless/ath/ath9k/recv.c | 545 +++++++++++++++++++++++++++++++++ 3 files changed, 604 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f0197a6046ab..5fe570bb5c4c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -481,6 +481,60 @@ struct ath_led { void ath_init_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc); +/* Antenna diversity/combining */ +#define ATH_ANT_RX_CURRENT_SHIFT 4 +#define ATH_ANT_RX_MAIN_SHIFT 2 +#define ATH_ANT_RX_MASK 0x3 + +#define ATH_ANT_DIV_COMB_SHORT_SCAN_INTR 50 +#define ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT 0x100 +#define ATH_ANT_DIV_COMB_MAX_PKTCOUNT 0x200 +#define ATH_ANT_DIV_COMB_INIT_COUNT 95 +#define ATH_ANT_DIV_COMB_MAX_COUNT 100 +#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 +#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 + +#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3 +#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2 + +enum ath9k_ant_div_comb_lna_conf { + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, + ATH_ANT_DIV_COMB_LNA2, + ATH_ANT_DIV_COMB_LNA1, + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2, +}; + +struct ath_ant_comb { + u16 count; + u16 total_pkt_count; + bool scan; + bool scan_not_start; + int main_total_rssi; + int alt_total_rssi; + int alt_recv_cnt; + int main_recv_cnt; + int rssi_lna1; + int rssi_lna2; + int rssi_add; + int rssi_sub; + int rssi_first; + int rssi_second; + int rssi_third; + bool alt_good; + int quick_scan_cnt; + int main_conf; + enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf; + enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf; + int first_bias; + int second_bias; + bool first_ratio; + bool second_ratio; + unsigned long scan_start_time; +}; + /********************/ /* Main driver core */ /********************/ @@ -597,6 +651,8 @@ struct ath_softc { struct ath_btcoex btcoex; struct ath_descdma txsdma; + + struct ath_ant_comb ant_comb; }; struct ath_wiphy { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 3dbff8d07766..e7c07b3370cc 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -531,6 +531,9 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->beacon.bslot[i] = NULL; sc->beacon.bslot_aphy[i] = NULL; } + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; } static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 534a91bcc1d9..b32c8f033d20 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -19,6 +19,15 @@ #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) +static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, + int mindelta, int main_rssi_avg, + int alt_rssi_avg, int pkt_count) +{ + return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + maxdelta)) || + (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); +} + static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) { return sc->ps_enabled && @@ -1076,6 +1085,539 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, rxs->flag &= ~RX_FLAG_DECRYPTED; } +static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf ant_conf, + int main_rssi_avg) +{ + antcomb->quick_scan_cnt = 0; + + if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + + switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { + case (0x10): /* LNA2 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case (0x20): /* LNA1 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + case (0x21): /* LNA1 LNA2 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case (0x12): /* LNA2 LNA1 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case (0x13): /* LNA2 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case (0x23): /* LNA1 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + default: + break; + } +} + +static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf *div_ant_conf, + int main_rssi_avg, int alt_rssi_avg, + int alt_ratio) +{ + /* alt_good */ + switch (antcomb->quick_scan_cnt) { + case 0: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; + break; + case 1: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_second = alt_rssi_avg; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + /* main is LNA1 */ + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } + break; + case 2: + antcomb->alt_good = false; + antcomb->scan_not_start = false; + antcomb->scan = false; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_third = alt_rssi_avg; + + if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + } + + if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + else + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } + + /* set alt to the conf with maximun ratio */ + if (antcomb->first_ratio && antcomb->second_ratio) { + if (antcomb->rssi_second > antcomb->rssi_third) { + /* first alt*/ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2*/ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } else { + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } + } else if (antcomb->first_ratio) { + /* first alt */ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if (antcomb->second_ratio) { + /* second alt */ + if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } else { + /* main is largest */ + if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || + (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = antcomb->main_conf; + } + break; + default: + break; + } +} + +void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) +{ + /* Adjust the fast_div_bias based on main and alt lna conf */ + switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { + case (0x01): /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case (0x02): /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + case (0x03): /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + break; + case (0x10): /* LNA2 A-B */ + ant_conf->fast_div_bias = 0x7; + break; + case (0x12): /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x2; + break; + case (0x13): /* LNA2 A+B */ + ant_conf->fast_div_bias = 0x7; + break; + case (0x20): /* LNA1 A-B */ + ant_conf->fast_div_bias = 0x6; + break; + case (0x21): /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x0; + break; + case (0x23): /* LNA1 A+B */ + ant_conf->fast_div_bias = 0x6; + break; + case (0x30): /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + break; + case (0x31): /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case (0x32): /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + default: + break; + } +} + +/* Antenna diversity and combining */ +static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) +{ + struct ath_hw_antcomb_conf div_ant_conf; + struct ath_ant_comb *antcomb = &sc->ant_comb; + int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; + int curr_main_set, curr_bias; + int main_rssi = rs->rs_rssi_ctl0; + int alt_rssi = rs->rs_rssi_ctl1; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + + rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; + main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* Record packet only when alt_rssi is positive */ + if (alt_rssi > 0) { + antcomb->total_pkt_count++; + antcomb->main_total_rssi += main_rssi; + antcomb->alt_total_rssi += alt_rssi; + if (main_ant_conf == rx_ant_conf) + antcomb->main_recv_cnt++; + else + antcomb->alt_recv_cnt++; + } + + /* Short scan check */ + if (antcomb->scan && antcomb->alt_good) { + if (time_after(jiffies, antcomb->scan_start_time + + msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) + short_scan = true; + else + if (antcomb->total_pkt_count == + ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) + short_scan = true; + } + } + + if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || + rs->rs_moreaggr) && !short_scan) + return; + + if (antcomb->total_pkt_count) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + main_rssi_avg = (antcomb->main_total_rssi / + antcomb->total_pkt_count); + alt_rssi_avg = (antcomb->alt_total_rssi / + antcomb->total_pkt_count); + } + + + ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); + curr_alt_set = div_ant_conf.alt_lna_conf; + curr_main_set = div_ant_conf.main_lna_conf; + curr_bias = div_ant_conf.fast_div_bias; + + antcomb->count++; + + if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { + ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, + main_rssi_avg); + antcomb->alt_good = true; + } else { + antcomb->alt_good = false; + } + + antcomb->count = 0; + antcomb->scan = true; + antcomb->scan_not_start = true; + } + + if (!antcomb->scan) { + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { + if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { + /* Switch main and alt LNA */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + + goto div_comb_done; + } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && + (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + + goto div_comb_done; + } + + if ((alt_rssi_avg < (main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA))) + goto div_comb_done; + } + + if (!antcomb->scan_not_start) { + switch (curr_alt_set) { + case ATH_ANT_DIV_COMB_LNA2: + antcomb->rssi_lna2 = alt_rssi_avg; + antcomb->rssi_lna1 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1: + antcomb->rssi_lna1 = alt_rssi_avg; + antcomb->rssi_lna2 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: + antcomb->rssi_add = alt_rssi_avg; + antcomb->scan = true; + /* set to A-B */ + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: + antcomb->rssi_sub = alt_rssi_avg; + antcomb->scan = false; + if (antcomb->rssi_lna2 > + (antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { + /* use LNA2 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna1) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA1 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } + } else { + /* use LNA1 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna2) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA2 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + } + break; + default: + break; + } + } else { + if (!antcomb->alt_good) { + antcomb->scan_not_start = false; + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + goto div_comb_done; + } + } + + ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, + main_rssi_avg, alt_rssi_avg, + alt_ratio); + + antcomb->quick_scan_cnt++; + +div_comb_done: + ath_ant_div_conf_fast_divbias(&div_ant_conf); + + ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); + + antcomb->scan_start_time = jiffies; + antcomb->total_pkt_count = 0; + antcomb->main_total_rssi = 0; + antcomb->alt_total_rssi = 0; + antcomb->main_recv_cnt = 0; + antcomb->alt_recv_cnt = 0; +} + int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { struct ath_buf *bf; @@ -1213,6 +1755,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) PS_WAIT_FOR_PSPOLL_DATA)))) ath_rx_ps(sc, skb); + if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + ath_ant_comb_scan(sc, &rs); + ath_rx_send_to_mac80211(hw, sc, skb, rxs); requeue: -- cgit v1.2.3 From 7cf1f2dd7de98e9a18536ab885d28ecb57e76cb1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Sep 2010 12:41:28 +0530 Subject: ath9k_htc: Enable fastcc for HTC devices. By enabling fastcc, the scan time reduced to half. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f4672073ac0a..bab894873bf5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -137,8 +137,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, if (priv->op_flags & OP_FULL_RESET) fastcc = false; - /* Fiddle around with fastcc later on, for now just use full reset */ - fastcc = false; ath9k_htc_ps_wakeup(priv); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -146,9 +144,10 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, WMI_CMD(WMI_STOP_RECV_CMDID); ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n", + "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", priv->ah->curchan->channel, - channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); + channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), + fastcc); caldata = &priv->caldata[channel->hw_value]; ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); -- cgit v1.2.3 From c2ba33424600e742f4d44ba2237024e6322a00fa Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Sep 2010 16:00:00 +0530 Subject: ath9k_hw: Restore ANI registers to default during partial reset for AR9271 For AR9271 chips, if partial reset is done while scanning, the cycpwrThr1 will be set to maximum. This causes the degrade in DL throughput. So restore the ANI registers to default during the partial reset. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 50 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.c | 2 ++ drivers/net/wireless/ath/ath9k/hw.h | 1 + 3 files changed, 53 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 303c63da5ea3..94392daebaa0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -580,3 +580,53 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) else ath9k_hw_attach_ani_ops_old(ah); } + +void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) +{ + u32 modesIndex; + int i; + + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return; + } + + ENABLE_REGWRITE_BUFFER(ah); + + for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) { + u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0); + u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex); + u32 val_orig; + + if (reg == AR_PHY_CCK_DETECT) { + val_orig = REG_READ(ah, reg); + val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; + val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; + + REG_WRITE(ah, reg, val|val_orig); + } else + REG_WRITE(ah, reg, val); + } + + REGWRITE_BUFFER_FLUSH(ah); + DISABLE_REGWRITE_BUFFER(ah); + +} diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 68940a8864e0..afadade2a67e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1263,6 +1263,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (ath9k_hw_channel_change(ah, chan)) { ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah, true); + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); return 0; } } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 197c717286e7..1724b17bfc73 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -996,6 +996,7 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah); void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); +void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); /* * ANI work can be shared between all families but a next * generation implementation of ANI will be used only for AR9003 only -- cgit v1.2.3 From f4bbf922f39696ed5517ac91a823e4120cb649d0 Mon Sep 17 00:00:00 2001 From: Michael Büsch Date: Sun, 5 Sep 2010 00:55:38 +0200 Subject: p54spi: Add error message for eeprom failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds an error message for the eeprom request failure case. This way it's easier for the user to figure out what went wrong. Signed-off-by: Michael Büsch Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 156e57dbd2cf..18d24b7b1e34 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -202,6 +202,8 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev) dev_info(&priv->spi->dev, "loading default eeprom...\n"); ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom, sizeof(p54spi_eeprom)); +#else + dev_err(&priv->spi->dev, "Failed to request user eeprom\n"); #endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */ } else { dev_info(&priv->spi->dev, "loading user eeprom...\n"); -- cgit v1.2.3 From 950094cb06f3cfd75338d8c197d1d3924724b1a8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 5 Sep 2010 21:00:26 +0200 Subject: drivers/net/wireless/iwlwifi/iwl-agn.c: Fix return value from an unsigned function The function has an unsigned return type, but returns a negative constant to indicate an error condition. Another error condition in the same function is indicated by returning 0, and indeed the only call to the function checks for 0 to detect errors, so the return of a negative value it converted to a return of 0. A sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @exists@ identifier f; constant C; @@ unsigned f(...) { <+... * return -C; ...+> } // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 55ac079916d7..c8a2ec802c8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -369,7 +369,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, if (!priv->beacon_ctx) { IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); - return -EINVAL; + return 0; } /* Initialize memory */ -- cgit v1.2.3 From e10bc84d0e96adff7569161e7d825074a119be36 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:40:50 +0000 Subject: bnx2x: Unify PHY attributes Start building the infrastructure for dual media by adding new component of PHY which will be used all along the function. Modify function to work with this component instead of the link_params. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 15 +- drivers/net/bnx2x/bnx2x_hsi.h | 17 + drivers/net/bnx2x/bnx2x_link.c | 2180 ++++++++++++++----------------------- drivers/net/bnx2x/bnx2x_link.h | 59 +- drivers/net/bnx2x/bnx2x_main.c | 21 +- drivers/net/bnx2x/bnx2x_reg.h | 10 +- 6 files changed, 916 insertions(+), 1386 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 8b75b05e34c5..2c7e0ab6ccf8 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -811,7 +811,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); int port = BP_PORT(bp); int rc = 0; - + u32 ext_phy_config; if (!netif_running(dev)) return -EAGAIN; @@ -827,6 +827,10 @@ static int bnx2x_set_eeprom(struct net_device *dev, !bp->port.pmf) return -EINVAL; + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + if (eeprom->magic == 0x50485950) { /* 'PHYP' (0x50485950): prepare phy for FW upgrade */ bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -834,7 +838,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, bnx2x_acquire_phy_lock(bp); rc |= bnx2x_link_reset(&bp->link_params, &bp->link_vars, 0); - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + if (XGXS_EXT_PHY_TYPE(ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_HIGH, port); @@ -855,10 +859,8 @@ static int bnx2x_set_eeprom(struct net_device *dev, } } else if (eeprom->magic == 0x53985943) { /* 'PHYC' (0x53985943): PHY FW upgrade completed */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + if (XGXS_EXT_PHY_TYPE(ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); /* DSP Remove Download Mode */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, @@ -866,7 +868,8 @@ static int bnx2x_set_eeprom(struct net_device *dev, bnx2x_acquire_phy_lock(bp); - bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); + bnx2x_sfx7101_sp_sw_reset(bp, + &bp->link_params.phy[EXT_PHY1]); /* wait 0.5 sec to allow it to run */ msleep(500); diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index fd1f29e0317d..f494bc333f52 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -120,6 +120,23 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_FAN_FAILURE_DISABLED 0x00080000 #define SHARED_HW_CFG_FAN_FAILURE_ENABLED 0x00100000 + /* Set the MDC/MDIO access for the first external phy */ +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK 0x1C000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT 26 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE 0x00000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0 0x04000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1 0x08000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH 0x0c000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED 0x10000000 + + /* Set the MDC/MDIO access for the second external phy */ +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK 0xE0000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT 29 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_PHY_TYPE 0x00000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC0 0x20000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC1 0x40000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_BOTH 0x60000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SWAPPED 0x80000000 u32 power_dissipated; /* 0x11c */ #define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000 #define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 8fce54cd6ba5..e6bc70ff8432 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -168,32 +168,33 @@ /**********************************************************/ /* INTERFACE */ /**********************************************************/ -#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ - bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \ + +#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ + bnx2x_cl45_write(_bp, _phy, \ DEFAULT_PHY_DEV_ADDR, \ (_bank + (_addr & 0xf)), \ _val) -#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ - bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \ +#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ + bnx2x_cl45_read(_bp, _phy, \ DEFAULT_PHY_DEV_ADDR, \ (_bank + (_addr & 0xf)), \ _val) -static void bnx2x_set_serdes_access(struct link_params *params) +static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) { - struct bnx2x *bp = params->bp; - u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; /* Set Clause 22 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1); + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1); REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); udelay(500); REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); udelay(500); /* Set Clause 45 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0); + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); } + static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) { struct bnx2x *bp = params->bp; @@ -204,7 +205,7 @@ static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, DEFAULT_PHY_DEV_ADDR); } else { - bnx2x_set_serdes_access(params); + bnx2x_set_serdes_access(bp, params->port); REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + params->port*0x10, @@ -825,37 +826,37 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) } -u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 val) +u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val) { u32 tmp, saved_mode; u8 i, rc = 0; - u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); /* set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ - saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); - REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); udelay(40); /* address */ - tmp = ((phy_addr << 21) | (devad << 16) | reg | + tmp = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, phy->mdio_ctrl + + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -866,15 +867,15 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, rc = -EFAULT; } else { /* data */ - tmp = ((phy_addr << 21) | (devad << 16) | val | + tmp = ((phy->addr << 21) | (devad << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, mdio_ctrl + + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); @@ -888,42 +889,41 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, } /* Restore the saved mode */ - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); return rc; } -u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 *ret_val) +u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val) { u32 val, saved_mode; u16 i; u8 rc = 0; - u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); /* set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ - saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL | + saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT)); val |= (EMAC_MDIO_MODE_CLAUSE_45 | (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); - REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); udelay(40); /* address */ - val = ((phy_addr << 21) | (devad << 16) | reg | + val = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -937,15 +937,15 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, } else { /* data */ - val = ((phy_addr << 21) | (devad << 16) | + val = ((phy->addr << 21) | (devad << 16) | EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, mdio_ctrl + + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); @@ -961,13 +961,49 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, } /* Restore the saved mode */ - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); return rc; } +u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val) +{ + u8 phy_index; + /** + * Probe for the phy according to the given phy_addr, and execute + * the read request on it + */ + for (phy_index = 0; phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].addr == phy_addr) { + return bnx2x_cl45_read(params->bp, + ¶ms->phy[phy_index], devad, + reg, ret_val); + } + } + return -EINVAL; +} + +u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val) +{ + u8 phy_index; + /** + * Probe for the phy according to the given phy_addr, and execute + * the write request on it + */ + for (phy_index = 0; phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].addr == phy_addr) { + return bnx2x_cl45_write(params->bp, + ¶ms->phy[phy_index], devad, + reg, val); + } + } + return -EINVAL; +} + static void bnx2x_set_aer_mmd(struct link_params *params, - struct link_vars *vars) + struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; u32 ser_lane; @@ -977,16 +1013,16 @@ static void bnx2x_set_aer_mmd(struct link_params *params, PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - offset = (vars->phy_flags & PHY_XGXS_FLAG) ? - (params->phy_addr + ser_lane) : 0; + offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? + (phy->addr + ser_lane) : 0; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); } -static void bnx2x_set_master_ln(struct link_params *params) +static void bnx2x_set_master_ln(struct link_params *params, + struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; u16 new_master_ln, ser_lane; @@ -995,47 +1031,44 @@ static void bnx2x_set_master_ln(struct link_params *params) PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); /* set the master_ln for AN */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, &new_master_ln); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2 , MDIO_XGXS_BLOCK2_TEST_MODE_LANE, (new_master_ln | ser_lane)); } -static u8 bnx2x_reset_unicore(struct link_params *params) +static u8 bnx2x_reset_unicore(struct link_params *params, + struct bnx2x_phy *phy, + u8 set_serdes) { struct bnx2x *bp = params->bp; u16 mii_control; u16 i; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); /* reset the unicore */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET)); - if (params->switch_cfg == SWITCH_CFG_1G) - bnx2x_set_serdes_access(params); + if (set_serdes) + bnx2x_set_serdes_access(bp, params->port); /* wait for the reset to self clear */ for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { udelay(5); /* the reset erased the previous bank value */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -1051,7 +1084,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params) } -static void bnx2x_set_swap_lanes(struct link_params *params) +static void bnx2x_set_swap_lanes(struct link_params *params, + struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; /* Each two bits represents a lane number: @@ -1069,43 +1103,37 @@ static void bnx2x_set_swap_lanes(struct link_params *params) PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); if (rx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, (rx_lane_swap | MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); } if (tx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, (tx_lane_swap | MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); } } -static void bnx2x_set_parallel_detection(struct link_params *params, - u8 phy_flags) +static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 control2; - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2); @@ -1115,25 +1143,22 @@ static void bnx2x_set_parallel_detection(struct link_params *params, control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n", params->speed_cap_mask, control2); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, control2); - if ((phy_flags & PHY_XGXS_FLAG) && + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "XGXS\n"); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, &control2); @@ -1142,15 +1167,13 @@ static void bnx2x_set_parallel_detection(struct link_params *params, control2 |= MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, control2); /* Disable parallel detection of HiG */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | @@ -1158,7 +1181,8 @@ static void bnx2x_set_parallel_detection(struct link_params *params, } } -static void bnx2x_set_autoneg(struct link_params *params, +static void bnx2x_set_autoneg(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars, u8 enable_cl73) { @@ -1166,9 +1190,7 @@ static void bnx2x_set_autoneg(struct link_params *params, u16 reg_val; /* CL37 Autoneg */ - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); @@ -1179,15 +1201,13 @@ static void bnx2x_set_autoneg(struct link_params *params, reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* Enable/Disable Autodetection */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | @@ -1198,14 +1218,12 @@ static void bnx2x_set_autoneg(struct link_params *params, else reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); /* Enable TetonII and BAM autoneg */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, ®_val); @@ -1218,23 +1236,20 @@ static void bnx2x_set_autoneg(struct link_params *params, reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); } - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, reg_val); if (enable_cl73) { /* Enable Cl73 FSM status bits */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_UCTRL, 0xe); /* Enable BAM Station Manager*/ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_BAM_CTRL1, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | @@ -1242,8 +1257,7 @@ static void bnx2x_set_autoneg(struct link_params *params, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); /* Advertise CL73 link speeds */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); @@ -1254,8 +1268,7 @@ static void bnx2x_set_autoneg(struct link_params *params, PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, reg_val); @@ -1266,22 +1279,21 @@ static void bnx2x_set_autoneg(struct link_params *params, } else /* CL73 Autoneg Disabled */ reg_val = 0; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); } /* program SerDes, forced speed */ -static void bnx2x_program_serdes(struct link_params *params, +static void bnx2x_program_serdes(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 reg_val; /* program duplex, disable autoneg and sgmii*/ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | @@ -1289,15 +1301,13 @@ static void bnx2x_program_serdes(struct link_params *params, MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); if (params->req_duplex == DUPLEX_FULL) reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* program speed - needed only if the speed is greater than 1G (2.5G or 10G) */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, ®_val); /* clearing the speed value before setting the right speed */ @@ -1320,14 +1330,14 @@ static void bnx2x_program_serdes(struct link_params *params, MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; } - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, reg_val); } -static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) +static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 val = 0; @@ -1339,18 +1349,17 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) val |= MDIO_OVER_1G_UP1_2_5G; if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= MDIO_OVER_1G_UP1_10G; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP1, val); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP3, 0x400); } -static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) +static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, + struct link_params *params, u16 *ieee_fc) { struct bnx2x *bp = params->bp; *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; @@ -1385,30 +1394,30 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); } -static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, +static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy, + struct link_params *params, u16 ieee_fc) { struct bnx2x *bp = params->bp; u16 val; /* for AN, we are always publishing full duplex */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &val); val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, val); } -static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) +static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, + struct link_params *params, + u8 enable_cl73) { struct bnx2x *bp = params->bp; u16 mii_control; @@ -1417,14 +1426,12 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) /* Enable and restart BAM/CL37 aneg */ if (enable_cl73) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, &mii_control); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, (mii_control | @@ -1432,16 +1439,14 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); } else { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg mii_control before = 0x%x\n", mii_control); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | @@ -1450,7 +1455,8 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) } } -static void bnx2x_initialize_sgmii_process(struct link_params *params, +static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; @@ -1458,8 +1464,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, /* in SGMII mode, the unicore is always slave */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &control1); @@ -1468,8 +1473,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, control1); @@ -1479,8 +1483,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, /* set speed, disable autoneg */ u16 mii_control; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -1511,15 +1514,14 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, if (params->req_duplex == DUPLEX_FULL) mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, mii_control); } else { /* AN mode */ /* enable and restart AN */ - bnx2x_restart_autoneg(params, 0); + bnx2x_restart_autoneg(phy, params, 0); } } @@ -1551,43 +1553,31 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) } } -static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 ext_phy_addr; u16 ld_pause; /* local */ u16 lp_pause; /* link partner */ u16 an_complete; /* AN complete */ u16 pause_result; u8 ret = 0; - u32 ext_phy_type; - u8 port = params->port; - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* read twice */ - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_STATUS, &an_complete); - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_STATUS, &an_complete); if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) { ret = 1; - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); pause_result = (ld_pause & @@ -1598,16 +1588,12 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, pause_result); bnx2x_pause_resolve(vars, pause_result); if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE && - ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &ld_pause); - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, &lp_pause); pause_result = (ld_pause & @@ -1623,17 +1609,16 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, return ret; } -static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) +static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 pd_10g, status2_1000x; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); @@ -1643,8 +1628,7 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) return 1; } - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, &pd_10g); @@ -1657,9 +1641,10 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) return 0; } -static void bnx2x_flow_ctrl_resolve(struct link_params *params, - struct link_vars *vars, - u32 gp_status) +static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u32 gp_status) { struct bnx2x *bp = params->bp; u16 ld_pause; /* local driver */ @@ -1672,9 +1657,8 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && (!(vars->phy_flags & PHY_SGMII_FLAG)) && - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { - if (bnx2x_direct_parallel_detect_used(params)) { + (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { + if (bnx2x_direct_parallel_detect_used(phy, params)) { vars->flow_ctrl = params->req_fc_auto_adv; return; } @@ -1684,13 +1668,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_LP_ADV1, &lp_pause); @@ -1703,14 +1685,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result); } else { - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, &lp_pause); @@ -1723,7 +1702,7 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, } bnx2x_pause_resolve(vars, pause_result); } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - (bnx2x_ext_phy_resolve_fc(params, vars))) { + (bnx2x_ext_phy_resolve_fc(phy, params, vars))) { return; } else { if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) @@ -1734,14 +1713,14 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); } -static void bnx2x_check_fallback_to_cl37(struct link_params *params) +static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 rx_status, ustat_val, cl37_fsm_recieved; DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); /* Step 1: Make sure signal is detected */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_RX0, MDIO_RX0_RX_STATUS, &rx_status); @@ -1749,16 +1728,14 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) (MDIO_RX0_RX_STATUS_SIGDET)) { DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." "rx_status(0x80b0) = 0x%x\n", rx_status); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); return; } /* Step 2: Check CL73 state machine */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_USTAT1, &ustat_val); @@ -1773,8 +1750,7 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) } /* Step 3: Check CL37 Message Pages received to indicate LP supports only CL37 */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_REMOTE_PHY, MDIO_REMOTE_PHY_MISC_RX_STATUS, &cl37_fsm_recieved); @@ -1792,13 +1768,12 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) connected to a device which does not support cl73, but does support cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ /* Disable CL73 */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 0); /* Restart CL37 autoneg */ - bnx2x_restart_autoneg(params, 0); + bnx2x_restart_autoneg(phy, params, 0); DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); } static u8 bnx2x_link_settings_status(struct link_params *params, @@ -1809,8 +1784,8 @@ static u8 bnx2x_link_settings_status(struct link_params *params, struct bnx2x *bp = params->bp; u16 new_line_speed; u8 rc = 0; + u32 ext_phy_type; vars->link_status = 0; - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", gp_status); @@ -1823,7 +1798,8 @@ static u8 bnx2x_link_settings_status(struct link_params *params, else vars->duplex = DUPLEX_HALF; - bnx2x_flow_ctrl_resolve(params, vars, gp_status); + bnx2x_flow_ctrl_resolve(¶ms->phy[INT_PHY], + params, vars, gp_status); switch (gp_status & GP_STATUS_SPEED_MASK) { case GP_STATUS_10M: @@ -1909,8 +1885,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, Comes to deals with possible FIFO glitch due to clk change when speed is decreased without link down indicator */ if (new_line_speed != vars->line_speed) { - if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT && + if (!SINGLE_MEDIA_DIRECT(params) && ext_phy_link_up) { DP(NETIF_MSG_LINK, "Internal link speed %d is" " different than the external" @@ -1925,15 +1900,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params, } vars->line_speed = new_line_speed; vars->link_status |= LINK_STATUS_SERDES_LINK; - + ext_phy_type = params->phy[EXT_PHY1].type; if ((params->req_line_speed == SPEED_AUTO_NEG) && - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == + ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == + (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == + (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == + (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { vars->autoneg = AUTO_NEG_ENABLED; @@ -1956,6 +1931,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, vars->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; + } else { /* link_down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -1967,10 +1943,10 @@ static u8 bnx2x_link_settings_status(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; if ((params->req_line_speed == SPEED_AUTO_NEG) && - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) { + (SINGLE_MEDIA_DIRECT(params))) { /* Check signal is detected */ - bnx2x_check_fallback_to_cl37(params); + bnx2x_check_fallback_to_cl37(¶ms->phy[INT_PHY], + params); } } @@ -1988,13 +1964,13 @@ static u8 bnx2x_link_settings_status(struct link_params *params, static void bnx2x_set_gmii_tx_driver(struct link_params *params) { struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; u16 lp_up2; u16 tx_driver; u16 bank; /* read precomp */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_LP_UP2, &lp_up2); @@ -2008,8 +1984,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, &tx_driver); @@ -2018,8 +1993,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; tx_driver |= lp_up2; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, tx_driver); } @@ -2072,6 +2046,7 @@ static u8 bnx2x_emac_program(struct link_params *params, return 0; } + /*****************************************************************************/ /* External Phy section */ /*****************************************************************************/ @@ -2084,21 +2059,16 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } -static void bnx2x_ext_phy_reset(struct link_params *params, - struct link_vars *vars) +static void bnx2x_ext_phy_reset(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* The PHY reset is controled by GPIO 1 * Give it 1ms of reset pulse */ - if (vars->phy_flags & PHY_XGXS_FLAG) { - - switch (ext_phy_type) { + switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); break; @@ -2115,9 +2085,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); break; @@ -2136,9 +2104,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -2153,9 +2119,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -2195,9 +2159,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -2211,31 +2173,11 @@ static void bnx2x_ext_phy_reset(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n"); break; - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); + DP(NETIF_MSG_LINK, "BAD phy type 0x%x\n", + phy->type); break; } - - } else { /* SerDes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - bnx2x_ext_phy_hw_reset(bp, params->port); - break; - - default: - DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); - break; - } - } } static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, @@ -2250,59 +2192,49 @@ static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, } static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, - u32 ext_phy_type, u8 ext_phy_addr, - u32 shmem_base) + struct bnx2x_phy *phy, + u32 shmem_base) { u16 fw_ver1, fw_ver2; - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &fw_ver2); bnx2x_save_spirom_version(bp, port, shmem_base, (u32)(fw_ver1<<16 | fw_ver2)); } - -static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, u32 shmem_base) +static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, + struct link_params *params, + u32 shmem_base) { u16 val, fw_ver1, fw_ver2, cnt; - /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/ + struct bnx2x *bp = params->bp; + + /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); @@ -2312,29 +2244,21 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port, } if (cnt == 100) { DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n"); - bnx2x_save_spirom_version(bp, port, + bnx2x_save_spirom_version(bp, params->port, shmem_base, 0); return; } /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); @@ -2344,58 +2268,53 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port, } if (cnt == 100) { DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n"); - bnx2x_save_spirom_version(bp, port, + bnx2x_save_spirom_version(bp, params->port, shmem_base, 0); return; } /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); - bnx2x_save_spirom_version(bp, port, + bnx2x_save_spirom_version(bp, params->port, shmem_base, (fw_ver2<<16) | fw_ver1); } -static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) +static void bnx2x_bcm8072_external_rom_boot(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* Need to wait 200ms after reset */ msleep(200); /* Boot port from external ROM * Set ser_boot_ctl bit in the MISC_CTRL1 register */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0001); /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); /* set micro reset = 0 */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); @@ -2403,30 +2322,24 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) msleep(100); /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0000); /* Wait 100ms */ msleep(100); bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, + phy, params->shmem_base); } -static u8 bnx2x_8073_is_snr_needed(struct link_params *params) +static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) { /* This is only required for 8073A1, version 102 only */ - - struct bnx2x *bp = params->bp; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u16 val; /* Read 8073 HW revision*/ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); @@ -2435,9 +2348,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params) return 0; } - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &val); @@ -2447,16 +2358,11 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params) return 1; } - -static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) +static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u16 val, cnt, cnt1 ; - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); @@ -2470,9 +2376,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) poll Dev1, Reg $C820: */ for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &val); @@ -2489,9 +2393,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) XAUI workaround has completed), then continue on with system initialization.*/ for (cnt1 = 0; cnt1 < 1000; cnt1++) { - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_XAUI_WA, &val); if (val & (1<<15)) { @@ -2509,46 +2411,35 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) return -EINVAL; } -static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 ext_phy_type, - u32 shmem_base) +static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port, u32 shmem_base) { /* Boot port from external ROM */ /* EDC grst */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001); /* ucode reboot and rst */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x008c); - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0001); /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); /* Release srst bit */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); @@ -2557,64 +2448,36 @@ static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, msleep(120); /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0000); - - bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, - shmem_base); + bnx2x_save_bcm_spirom_ver(bp, port, phy, shmem_base); } -static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 shmem_base) -{ - bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - shmem_base); -} - -static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 shmem_base) -{ - bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - shmem_base); - -} - -static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) +static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* Need to wait 100ms after reset */ msleep(100); /* Micro controller re-boot */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); /* Set soft reset */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0001); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); @@ -2623,29 +2486,25 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) msleep(150); /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0000); msleep(200); - bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_save_bcm_spirom_ver(bp, params->port, + phy, params->shmem_base); } -static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, - u32 ext_phy_type, u8 ext_phy_addr, - u8 tx_en) +static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 tx_en) { u16 val; - DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", - tx_en, port); + DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x\n", tx_en); /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val); @@ -2655,58 +2514,42 @@ static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, else val |= (1<<15); - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, val); } -static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, +static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val = 0; u16 i; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - if (byte_cnt > 16) { DP(NETIF_MSG_LINK, "Reading from eeprom is" " is limited to 0xf\n"); return -EINVAL; } /* Set the read command byte count */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, (byte_cnt | 0xa000)); /* Set the read command address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, addr); /* Activate read command */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 0x2c0f); /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2725,36 +2568,30 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; + return 0; msleep(1); } return -EINVAL; } -static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, +static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val, i; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); if (byte_cnt > 16) { DP(NETIF_MSG_LINK, "Reading from eeprom is" @@ -2763,40 +2600,30 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, } /* Need to read from 1.8000 to clear it */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); /* Set the read command byte count */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, ((byte_cnt < 2) ? 2 : byte_cnt)); /* Set the read command address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, addr); /* Set the destination address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0x8004, MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); /* Activate read command */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 0x8002); @@ -2806,9 +2633,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2827,18 +2652,14 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2850,21 +2671,21 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, return -EINVAL; } -u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - return bnx2x_8726_read_sfp_module_eeprom(params, addr, + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, byte_cnt, o_buf); - else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - return bnx2x_8727_read_sfp_module_eeprom(params, addr, + else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, byte_cnt, o_buf); return -EINVAL; } -static u8 bnx2x_get_edc_mode(struct link_params *params, +static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, + struct link_params *params, u16 *edc_mode) { struct bnx2x *bp = params->bp; @@ -2872,7 +2693,7 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, *edc_mode = EDC_MODE_LIMITING; /* First check for copper cable */ - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_CON_TYPE_ADDR, 1, &val) != 0) { @@ -2887,7 +2708,7 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, /* Check if its active cable( includes SFP+ module) of passive cable*/ - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_FC_TX_TECH_ADDR, 1, &copper_module_type) != @@ -2927,7 +2748,7 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, if (check_limiting_mode) { u8 options[SFP_EEPROM_OPTIONS_SIZE]; - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_OPTIONS_ADDR, SFP_EEPROM_OPTIONS_SIZE, options) != 0) { @@ -2943,10 +2764,10 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); return 0; } - /* This function read the relevant field from the module ( SFP+ ), and verify it is compliant with this board */ -static u8 bnx2x_verify_sfp_module(struct link_params *params) +static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u32 val; @@ -2978,14 +2799,14 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params) } /* format the warning message */ - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_VENDOR_NAME_ADDR, SFP_EEPROM_VENDOR_NAME_SIZE, (u8 *)vendor_name)) vendor_name[0] = '\0'; else vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_PART_NO_ADDR, SFP_EEPROM_PART_NO_SIZE, (u8 *)vendor_pn)) @@ -2993,22 +2814,19 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params) else vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; - netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n", + netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," + " Port %d from %s part number %s\n", params->port, vendor_name, vendor_pn); return -EINVAL; } -static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, +static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, u16 edc_mode) { - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u16 cur_limiting_mode; - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &cur_limiting_mode); @@ -3018,9 +2836,7 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, if (edc_mode == EDC_MODE_LIMITING) { DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n"); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, EDC_MODE_LIMITING); @@ -3034,27 +2850,19 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, if (cur_limiting_mode != EDC_MODE_LIMITING) return 0; - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LRM_MODE, 0); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, 0x128); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL0, 0x4008); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LRM_MODE, 0xaaaa); @@ -3062,46 +2870,33 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, return 0; } -static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params, +static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, u16 edc_mode) { - struct bnx2x *bp = params->bp; - u8 port = params->port; u16 phy_identifier; u16 rom_ver2_val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &phy_identifier); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, (phy_identifier & ~(1<<9))); - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &rom_ver2_val); /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, (phy_identifier | (1<<9))); @@ -3110,7 +2905,9 @@ static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params, } -static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) +static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, + struct link_params *params) + { u8 val; struct bnx2x *bp = params->bp; @@ -3118,7 +2915,7 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) /* Initialization time after hot-plug may take up to 300ms for some phys type ( e.g. JDSU ) */ for (timeout = 0; timeout < 60; timeout++) { - if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val) + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) == 0) { DP(NETIF_MSG_LINK, "SFP+ module initialization " "took %d ms\n", timeout * 5); @@ -3131,10 +2928,10 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) static void bnx2x_8727_power_module(struct bnx2x *bp, struct link_params *params, - u8 ext_phy_addr, u8 is_power_up) { + struct bnx2x_phy *phy, + u8 is_power_up) { /* Make sure GPIOs are not using for LED mode */ u16 val; - u8 port = params->port; /* * In the GPIO register, bit 4 is use to detemine if the GPIOs are * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for @@ -3160,21 +2957,19 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, */ val = ((!(is_power_up)) << 1); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, val); } -static u8 bnx2x_sfp_module_detection(struct link_params *params) +static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 edc_mode; u8 rc = 0; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); + u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].config)); @@ -3182,10 +2977,10 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", params->port); - if (bnx2x_get_edc_mode(params, &edc_mode) != 0) { + if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); return -EINVAL; - } else if (bnx2x_verify_sfp_module(params) != + } else if (bnx2x_verify_sfp_module(phy, params) != 0) { /* check SFP+ module compatibility */ DP(NETIF_MSG_LINK, "Module verification failed!!\n"); @@ -3194,13 +2989,12 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_HIGH, params->port); - if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { /* Shutdown SFP+ module */ DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); - bnx2x_8727_power_module(bp, params, - ext_phy_addr, 0); + bnx2x_8727_power_module(bp, params, phy, 0); return rc; } } else { @@ -3212,15 +3006,15 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) } /* power up the SFP module */ - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + bnx2x_8727_power_module(bp, params, phy, 1); /* Check and set limiting mode / LRM mode on 8726. On 8727 it is done automatically */ - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - bnx2x_bcm8726_set_limiting_mode(params, edc_mode); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); else - bnx2x_bcm8727_set_limiting_mode(params, edc_mode); + bnx2x_8727_set_limiting_mode(bp, phy, edc_mode); /* * Enable transmit for this module if the module is approved, or * if unapproved modules should also enable the Tx laser @@ -3228,11 +3022,9 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) if (rc == 0 || (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 1); + bnx2x_sfp_set_transmitter(bp, phy, 1); else - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, 0); return rc; } @@ -3240,6 +3032,7 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) void bnx2x_handle_module_detect_int(struct link_params *params) { struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; u32 gpio_val; u8 port = params->port; @@ -3249,25 +3042,20 @@ void bnx2x_handle_module_detect_int(struct link_params *params) params->port); /* Get current gpio val refelecting module plugged in / out*/ - gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); + gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); /* Call the handling function in case module is detected */ if (gpio_val == 0) { bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, - port); + MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, + port); - if (bnx2x_wait_for_sfp_module_initialized(params) == - 0) - bnx2x_sfp_module_detection(params); + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); else DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } else { - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(params->ext_phy_config); u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. @@ -3280,48 +3068,36 @@ void bnx2x_handle_module_detect_int(struct link_params *params) /* Disable transmit for this module */ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, 0); } } -static void bnx2x_bcm807x_force_10G(struct link_params *params) +static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* Force KR or KX */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); } -static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) +static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, + struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 port = params->port; u16 val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); @@ -3331,67 +3107,63 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) } /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); val &= ~(1<<13); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); /* PLL controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); /* Tx Controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); /* Rx Controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); /* Enable PLL sequencer (use read-modify-write to set bit 13) */ - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); val |= (1<<13); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); } static void bnx2x_8073_set_pause_cl37(struct link_params *params, - struct link_vars *vars) + struct bnx2x_phy *phy, + struct link_vars *vars) { - struct bnx2x *bp = params->bp; u16 cl37_val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + struct bnx2x *bp = params->bp; + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val); cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { @@ -3410,26 +3182,20 @@ static void bnx2x_8073_set_pause_cl37(struct link_params *params, DP(NETIF_MSG_LINK, "Ext phy AN advertize cl37 0x%x\n", cl37_val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val); msleep(500); } static void bnx2x_ext_phy_set_pause(struct link_params *params, - struct link_vars *vars) + struct bnx2x_phy *phy, + struct link_vars *vars) { - struct bnx2x *bp = params->bp; u16 val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - + struct bnx2x *bp = params->bp; /* read modify write pause advertizing */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); @@ -3450,21 +3216,21 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, } DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); } -static void bnx2x_set_preemphasis(struct link_params *params) + +static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, + struct link_params *params) { + u16 bank, i = 0; struct bnx2x *bp = params->bp; for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, bank, MDIO_RX0_RX_EQ_BOOST, params->xgxs_config_rx[i]); @@ -3472,141 +3238,120 @@ static void bnx2x_set_preemphasis(struct link_params *params) for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, params->xgxs_config_tx[i]); } } - -static void bnx2x_8481_set_led(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) +static void bnx2x_8481_set_led(struct bnx2x *bp, + struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; u16 val; - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + + /* PHYC_CTL_LED_CTL */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LINK_SIGNAL, &val); val &= 0xFE00; val |= 0x0092; - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LINK_SIGNAL, val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x80); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED2_MASK, 0x18); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED3_MASK, 0x0040); /* 'Interrupt Mask' */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, 0xFFFB, 0xFFFD); } -static void bnx2x_init_internal_phy(struct link_params *params, - struct link_vars *vars, - u8 enable_cl73) +static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - + u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || + (params->loopback_mode == LOOPBACK_XGXS_10)); if (!(vars->phy_flags & PHY_SGMII_FLAG)) { - if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + if (SINGLE_MEDIA_DIRECT(params) && (params->feature_config_flags & FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) - bnx2x_set_preemphasis(params); + bnx2x_set_preemphasis(phy, params); /* forced speed requested? */ if (vars->line_speed != SPEED_AUTO_NEG || - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (SINGLE_MEDIA_DIRECT(params) && params->loopback_mode == LOOPBACK_EXT)) { DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); /* disable autoneg */ - bnx2x_set_autoneg(params, vars, 0); + bnx2x_set_autoneg(phy, params, vars, 0); /* program speed and duplex */ - bnx2x_program_serdes(params, vars); + bnx2x_program_serdes(phy, params, vars); } else { /* AN_mode */ DP(NETIF_MSG_LINK, "not SGMII, AN\n"); /* AN enabled */ - bnx2x_set_brcm_cl37_advertisment(params); + bnx2x_set_brcm_cl37_advertisment(phy, params); /* program duplex & pause advertisement (for aneg) */ - bnx2x_set_ieee_aneg_advertisment(params, + bnx2x_set_ieee_aneg_advertisment(phy, params, vars->ieee_fc); /* enable autoneg */ - bnx2x_set_autoneg(params, vars, enable_cl73); + bnx2x_set_autoneg(phy, params, vars, enable_cl73); /* enable and restart AN */ - bnx2x_restart_autoneg(params, enable_cl73); + bnx2x_restart_autoneg(phy, params, enable_cl73); } } else { /* SGMII mode */ DP(NETIF_MSG_LINK, "SGMII\n"); - bnx2x_initialize_sgmii_process(params, vars); + bnx2x_initialize_sgmii_process(phy, params, vars); } } static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr; u16 cnt; u16 ctrl = 0; u16 val = 0; u8 rc = 0; - + struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; if (vars->phy_flags & PHY_XGXS_FLAG) { - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* Make sure that the soft reset is off (expect for the 8072: * due to the lock, it will be done inside the specific * handling) */ - if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) { + if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && + (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) && + (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) { /* Wait for soft reset to get cleared upto 1 sec */ for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); if (!(ctrl & (1<<15))) @@ -3617,34 +3362,26 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) ctrl, cnt); } - switch (ext_phy_type) { + switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); @@ -3656,8 +3393,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: /* Wait until fw is loaded */ for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); if (val) break; @@ -3673,9 +3409,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) reg = MDIO_XS_8706_REG_BANK_RX0 + i*(MDIO_XS_8706_REG_BANK_RX1 - MDIO_XS_8706_REG_BANK_RX0); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); /* Clear first 3 bits of the control */ @@ -3687,9 +3421,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Setting RX" "Equalizer to BCM8706 reg 0x%x" " <-- val 0x%x\n", reg, val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); } @@ -3698,14 +3430,11 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) if (params->req_line_speed == SPEED_10000) { DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, 0x400); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); } else { /* Force 1Gbps using autoneg with 1G @@ -3713,85 +3442,66 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) /* Allow CL37 through CL73 */ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); /* Enable Full-Duplex advertisment on CL37 */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); /* Enable CL37 AN */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); /* 1G support */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); /* Enable clause 73 AN */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, 0x0400); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); } bnx2x_save_bcm_spirom_ver(bp, params->port, - ext_phy_type, - ext_phy_addr, + phy, params->shmem_base); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); - bnx2x_bcm8726_external_rom_boot(params); + bnx2x_8726_external_rom_boot(phy, params); /* Need to call module detected on initialization since the module detection triggered by actual module insertion might occur before driver is loaded, and when driver is loaded, it reset all registers, including the transmitter */ - bnx2x_sfp_module_detection(params); + bnx2x_sfp_module_detection(phy, params); /* Set Flow control */ - bnx2x_ext_phy_set_pause(params, vars); + bnx2x_ext_phy_set_pause(params, phy, vars); if (params->req_line_speed == SPEED_1000) { DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, 0x400); } else if ((params->req_line_speed == @@ -3799,35 +3509,27 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) ((params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); /* Enable RX-ALARM control to receive interrupt for 1G speed change */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, 0x400); } else { /* Default 10G. Set only LASI control */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); } @@ -3838,16 +3540,12 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) "TX_CTRL2 0x%x\n", params->xgxs_config_tx[0], params->xgxs_config_tx[1]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TX_CTRL1, params->xgxs_config_tx[0]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TX_CTRL2, params->xgxs_config_tx[1]); @@ -3859,7 +3557,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) u16 tmp1; u16 rx_alarm_ctrl_val; u16 lasi_ctrl_val; - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { rx_alarm_ctrl_val = 0x400; lasi_ctrl_val = 0x0004; @@ -3869,40 +3567,32 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } /* enable LASI */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, rx_alarm_ctrl_val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); - bnx2x_8073_set_pause_cl37(params, vars); + bnx2x_8073_set_pause_cl37(params, phy, vars); - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) - bnx2x_bcm8072_external_rom_boot(params); + bnx2x_bcm8072_external_rom_boot(phy, params); else /* In case of 8073 with long xaui lines, don't set the 8073 xaui low power*/ - bnx2x_bcm8073_set_xaui_low_power_mode(params); + bnx2x_8073_set_xaui_low_power_mode(bp, phy); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); @@ -3913,13 +3603,12 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) * (all other are not supported) */ if (params->loopback_mode == LOOPBACK_EXT) { - bnx2x_bcm807x_force_10G(params); + bnx2x_807x_force_10G(bp, phy); DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); break; } else { - bnx2x_cl45_write(bp, params->port, - ext_phy_type, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); @@ -3951,16 +3640,11 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) "807x autoneg val = 0x%x\n", val); } - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); @@ -3972,9 +3656,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) SPEED_2500)) { u16 phy_ver; /* Allow 2.5G for A1 and above */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &phy_ver); DP(NETIF_MSG_LINK, "Add 2.5G\n"); @@ -3987,76 +3669,59 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) tmp1 &= 0xfffe; } - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); - } /* Add support for CL37 (passive mode) II */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, (tmp1 | ((params->req_duplex == DUPLEX_FULL) ? 0x20 : 0x40))); /* Add support for CL37 (passive mode) III */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { /* The SNR will improve about 2db by changing BW and FEE main tap. Rest commands are executed after link is up*/ /*Change FFE main cursor to 5 in EDC register*/ - if (bnx2x_8073_is_snr_needed(params)) - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + if (bnx2x_8073_is_snr_needed(bp, phy)) + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, 0xFB0C); /* Enable FEC (Forware Error Correction) Request in the AN */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); tmp1 |= (1<<15); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); } - bnx2x_ext_phy_set_pause(params, vars); + bnx2x_ext_phy_set_pause(params, phy, vars); /* Restart autoneg */ msleep(500); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); DP(NETIF_MSG_LINK, "807x Autoneg Restart: " @@ -4080,25 +3745,19 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); /* enable LASI */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, rx_alarm_ctrl_val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); /* Initially configure MOD_ABS to interrupt when module is presence( bit 8) */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); /* Set EDC off by setting OPTXLOS signal input to low @@ -4106,23 +3765,17 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) When the EDC is off it locks onto a reference clock and avoids becoming 'lost'.*/ mod_abs &= ~((1<<8) | (1<<9)); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Make MOD_ABS give interrupt on change */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, &val); val |= (1<<12); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); @@ -4131,32 +3784,24 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) 8727 GPIO0 status which reflect SFP+ module over-current */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, &val); val &= 0xff8f; /* Reset bits 4-6 */ - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); + bnx2x_8727_power_module(bp, params, phy, 1); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); @@ -4164,19 +3809,13 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) if (params->req_line_speed == SPEED_1000) { DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); @@ -4189,28 +3828,22 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_PMA_REG_8727_MISC_CTRL, 0); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_AN_REG_8727_MISC_CTRL, 0); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); } else { /* Since the 8727 has only single reset pin, need to set the 10G registers although it is default */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0x0020); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x0008); } @@ -4218,9 +3851,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) * to 100Khz since some DACs(direct attached cables) do * not work at 400Khz. */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, 0xa001); @@ -4232,16 +3863,12 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) "TX_CTRL2 0x%x\n", params->xgxs_config_tx[0], params->xgxs_config_tx[1]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, params->xgxs_config_tx[0]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, params->xgxs_config_tx[1]); @@ -4256,40 +3883,30 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - bnx2x_ext_phy_set_pause(params, vars); + bnx2x_ext_phy_set_pause(params, phy, vars); /* Restart autoneg */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); val |= 0x200; - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); /* Save spirom version */ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); bnx2x_save_spirom_version(params->bp, params->port, @@ -4307,34 +3924,28 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) u16 autoneg_val, an_1000_val, an_10_100_val, temp; temp = vars->line_speed; vars->line_speed = SPEED_10000; - bnx2x_set_autoneg(params, vars, 0); - bnx2x_program_serdes(params, vars); + bnx2x_set_autoneg(phy, params, vars, 0); + bnx2x_program_serdes(phy, params, vars); vars->line_speed = temp; bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); - bnx2x_8481_set_led(params, ext_phy_type, ext_phy_addr); + bnx2x_8481_set_led(bp, phy); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, &an_1000_val); - bnx2x_ext_phy_set_pause(params, vars); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, &an_10_100_val); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, &autoneg_val); /* Disable forced speed */ @@ -4354,9 +3965,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } else an_1000_val &= ~((1<<8) | (1<<9)); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, an_1000_val); @@ -4393,9 +4002,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) if (params->req_line_speed == SPEED_100) { autoneg_val |= (1<<13); /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, (1<<15 | 1<<9 | 7<<0)); @@ -4403,18 +4010,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } if (params->req_line_speed == SPEED_10) { /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, (1<<15 | 1<<9 | 7<<0)); DP(NETIF_MSG_LINK, "Setting 10M force\n"); } - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, an_10_100_val); @@ -4422,9 +4025,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) if (params->req_duplex == DUPLEX_FULL) autoneg_val |= (1<<8); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); @@ -4436,74 +4037,49 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Advertising 10G\n"); /* Restart autoneg for 10G*/ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x3200); } else if (params->req_line_speed != SPEED_10 && params->req_line_speed != SPEED_100) - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 1); /* Save spirom version */ - bnx2x_save_8481_spirom_version(bp, params->port, - ext_phy_addr, - params->shmem_base); + bnx2x_save_8481_spirom_version(phy, params, + params->shmem_base); break; } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: DP(NETIF_MSG_LINK, "XGXS PHY Failure detected 0x%x\n", - params->ext_phy_config); + phy->type); rc = -EINVAL; break; - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); - rc = -EINVAL; - break; - } - - } else { /* SerDes */ - - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - break; default: DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); + phy->type); break; } } return rc; } -static void bnx2x_8727_handle_mod_abs(struct link_params *params) +static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 mod_abs, rx_alarm_status; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. config)); - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); if (mod_abs & (1<<8)) { @@ -4519,17 +4095,13 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) When the EDC is off it locks onto a reference clock and avoids becoming 'lost'.*/ mod_abs &= ~((1<<8)|(1<<9)); - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Clear RX alarm since it stays up as long as the mod_abs wasn't changed */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -4547,9 +4119,7 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) this signal will then correctly indicate the presence or absence of the Rx signal. (bit 9) */ mod_abs |= ((1<<8)|(1<<9)); - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); @@ -4557,22 +4127,17 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) the mod_abs wasn't changed. This is need to be done before calling the module detection, otherwise it will clear the link update alarm */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, 0); - if (bnx2x_wait_for_sfp_module_initialized(params) - == 0) - bnx2x_sfp_module_detection(params); + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); else DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } @@ -4584,22 +4149,18 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) } -static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, +static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars, u8 is_mi_int) { struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr; u16 val1 = 0, val2; u16 rx_sd, pcs_status; u8 ext_phy_link_up = 0; - u8 port = params->port; if (vars->phy_flags & PHY_XGXS_FLAG) { - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { + switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); ext_phy_link_up = 1; @@ -4607,29 +4168,24 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, 1, 0xc809, &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, 1, 0xc809, &val1); @@ -4644,36 +4200,29 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); /* Clear RX Alarm*/ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); /* clear LASI indication*/ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->" "0x%x\n", val1, val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); @@ -4687,13 +4236,11 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); if (ext_phy_link_up) { - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { /* If transmitter is disabled, ignore false link up indication */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); @@ -4716,18 +4263,14 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, u16 link_status = 0; u16 rx_alarm_status; /* Check the LASI */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); @@ -4736,9 +4279,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, val1); /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); @@ -4751,9 +4292,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, FEATURE_CONFIG_BCM8727_NOC) && !(rx_alarm_status & (1<<5))) { /* Check over-current using 8727 GPIO0 input*/ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, &val1); @@ -4769,31 +4308,23 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, * Disable all RX_ALARMs except for * mod_abs */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); /* Wait for module_absent_event */ val1 |= (1<<8); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, val1); /* Clear RX alarm */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -4803,11 +4334,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, /* When module absent bit is set, check module */ if (rx_alarm_status & (1<<5)) { - bnx2x_8727_handle_mod_abs(params); + bnx2x_8727_handle_mod_abs(phy, params); /* Enable all mod_abs and link detection bits */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, ((1<<5) | (1<<2))); @@ -4815,9 +4344,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, /* If transmitter is disabled, ignore false link up indication */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); @@ -4827,9 +4354,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, break; } - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); @@ -4862,16 +4387,12 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, u16 link_status = 0; u16 an1000_status = 0; - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_LASI_STATUS, &val2); DP(NETIF_MSG_LINK, @@ -4881,101 +4402,77 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, /* In 8073, port1 is directed through emac0 and * port0 is directed through emac1 */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); - } + } /* clear the interrupt LASI status register */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); /* Check the LASI */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); /* Check the link status */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); ext_phy_link_up = ((val1 & 4) == 4); DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); - if (ext_phy_type == + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { if (ext_phy_link_up && ((params->req_line_speed != SPEED_10000))) { - if (bnx2x_bcm8073_xaui_wa(params) + if (bnx2x_8073_xaui_wa(bp, phy) != 0) { ext_phy_link_up = 0; break; } } - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); /* Check the link status on 1.1.2 */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," @@ -4985,7 +4482,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, ext_phy_link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); if (ext_phy_link_up && - bnx2x_8073_is_snr_needed(params)) { + bnx2x_8073_is_snr_needed(bp, phy)) { /* The SNR will improve about 2dbby changing the BW and FEE main tap.*/ @@ -4993,23 +4490,19 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, tap is set before restart AN */ /* Change PLL Bandwidth in EDC register */ - bnx2x_cl45_write(bp, port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, 0x26BC); /* Change CDR Bandwidth in EDC register */ - bnx2x_cl45_write(bp, port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, 0x0333); } - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); @@ -5045,15 +4538,11 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, } } else { /* See if 1G link is up for the 8072 */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); @@ -5072,27 +4561,22 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, } } - break; } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", val2, val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); DP(NETIF_MSG_LINK, @@ -5103,9 +4587,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, * print the AN outcome of the SFX7101 PHY */ if (ext_phy_link_up) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, &val2); @@ -5120,13 +4602,11 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: /* Check 10G-BaseT link status */ /* Check PMD signal ok */ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, 0xFFFA, &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, &val2); @@ -5141,17 +4621,13 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, /* Enable expansion register 0x42 (Operation mode status) */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); /* Get legacy speed operation status */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, &legacy_status); @@ -5187,48 +4663,27 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, } break; default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); + DP(NETIF_MSG_LINK, + "BAD SerDes ext_phy_config 0x%x\n", + phy->type); ext_phy_link_up = 0; break; } + } + /* Set SGMII mode for external phy */ - if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { + if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { if (vars->line_speed < SPEED_1000) vars->phy_flags |= PHY_SGMII_FLAG; else vars->phy_flags &= ~PHY_SGMII_FLAG; } - } else { /* SerDes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - ext_phy_link_up = 1; - break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - ext_phy_link_up = 1; - break; - - default: - DP(NETIF_MSG_LINK, - "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); - ext_phy_link_up = 0; - break; - } - } - return ext_phy_link_up; } - static void bnx2x_link_int_enable(struct link_params *params) { u8 port = params->port; - u32 ext_phy_type; u32 mask; struct bnx2x *bp = params->bp; @@ -5239,11 +4694,9 @@ static void bnx2x_link_int_enable(struct link_params *params) mask = (NIG_MASK_XGXS0_LINK10G | NIG_MASK_XGXS0_LINK_STATUS); DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (ext_phy_type != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) { + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) { mask |= NIG_MASK_MI_INT; DP(NETIF_MSG_LINK, "enabled external phy int\n"); } @@ -5251,11 +4704,9 @@ static void bnx2x_link_int_enable(struct link_params *params) } else { /* SerDes */ mask = NIG_MASK_SERDES0_LINK_STATUS; DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - if ((ext_phy_type != - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) { + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) { mask |= NIG_MASK_MI_INT; DP(NETIF_MSG_LINK, "enabled external phy int\n"); } @@ -5311,6 +4762,7 @@ static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, (latch_status & 0xfffe) | (latch_status & 1)); } } + /* * link management */ @@ -5327,9 +4779,9 @@ static void bnx2x_link_int_ack(struct link_params *params, (NIG_STATUS_XGXS0_LINK10G | NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); - if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) + if ((params->phy[EXT_PHY1].type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) + (params->phy[EXT_PHY1].type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); } @@ -5421,7 +4873,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, status = 0; /* reset the returned value to zero */ - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); + ext_phy_type = params->phy[EXT_PHY1].type; switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: @@ -5465,8 +4917,8 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, return status; } -static void bnx2x_set_xgxs_loopback(struct link_params *params, - struct link_vars *vars, +static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, + struct link_params *params, u8 is_10g) { u8 port = params->port; @@ -5483,59 +4935,49 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params, REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); - bnx2x_cl45_write(bp, port, 0, - params->phy_addr, + bnx2x_cl45_write(bp, phy, 5, (MDIO_REG_BANK_AER_BLOCK + (MDIO_AER_BLOCK_AER_REG & 0xf)), 0x2800); - bnx2x_cl45_write(bp, port, 0, - params->phy_addr, + bnx2x_cl45_write(bp, phy, 5, (MDIO_REG_BANK_CL73_IEEEB0 + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), 0x6041); msleep(200); /* set aer mmd back */ - bnx2x_set_aer_mmd(params, vars); + bnx2x_set_aer_mmd(params, phy); /* and md_devad */ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); } else { - u16 mii_control; - + u16 mii_ctrl; DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); - - CL45_RD_OVER_CL22(bp, port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); - - CL45_WR_OVER_CL22(bp, port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - (mii_control | - MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK)); + bnx2x_cl45_read(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + &mii_ctrl); + bnx2x_cl45_write(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + mii_ctrl | + MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK); } } - -static void bnx2x_ext_phy_loopback(struct link_params *params) +static void bnx2x_ext_phy_loopback(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - u8 ext_phy_addr; - u32 ext_phy_type; if (params->switch_cfg == SWITCH_CFG_10G) { - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); + /* CL37 Autoneg Enabled */ - switch (ext_phy_type) { + switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN: DP(NETIF_MSG_LINK, @@ -5549,16 +4991,14 @@ static void bnx2x_ext_phy_loopback(struct link_params *params) break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: /* SFX7101_XGXS_TEST1 */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); @@ -5569,21 +5009,13 @@ static void bnx2x_ext_phy_loopback(struct link_params *params) break; } /* switch external PHY type */ - } else { - /* serdes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - ext_phy_addr = (params->ext_phy_config & - PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) - >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT; } } - - /* *------------------------------------------------------------------------ * bnx2x_override_led_value - * - * Override the led value of the requsted led + * Override the led value of the requested led * *------------------------------------------------------------------------ */ @@ -5702,7 +5134,6 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) u8 rc = 0; u32 tmp; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", @@ -5718,7 +5149,7 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) break; case LED_MODE_OPER: - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { + if (SINGLE_MEDIA_DIRECT(params)) { REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); } else { @@ -5768,14 +5199,13 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) struct bnx2x *bp = params->bp; u16 gp_status = 0; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); /* link is up only if both local phy and external phy are up */ if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) && - bnx2x_ext_phy_is_link_up(params, vars, 1)) + bnx2x_ext_phy_is_link_up(¶ms->phy[EXT_PHY1], params, vars, 1)) return 0; return -ESRCH; @@ -5788,27 +5218,29 @@ static u8 bnx2x_link_initialize(struct link_params *params, u8 port = params->port; u8 rc = 0; u8 non_ext_phy; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - + struct bnx2x_phy *ext_phy = ¶ms->phy[EXT_PHY1]; + struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; /* Activate the external PHY */ - bnx2x_ext_phy_reset(params, vars); + bnx2x_ext_phy_reset(ext_phy, params, vars); - bnx2x_set_aer_mmd(params, vars); + bnx2x_set_aer_mmd(params, int_phy); if (vars->phy_flags & PHY_XGXS_FLAG) - bnx2x_set_master_ln(params); + bnx2x_set_master_ln(params, int_phy); - rc = bnx2x_reset_unicore(params); + rc = bnx2x_reset_unicore(params, int_phy, + int_phy->type == + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT); /* reset the SerDes and wait for reset bit return low */ if (rc != 0) return rc; - bnx2x_set_aer_mmd(params, vars); + bnx2x_set_aer_mmd(params, int_phy); /* setting the masterLn_def again after the reset */ if (vars->phy_flags & PHY_XGXS_FLAG) { - bnx2x_set_master_ln(params); - bnx2x_set_swap_lanes(params); + bnx2x_set_master_ln(params, int_phy); + bnx2x_set_swap_lanes(params, int_phy); } if (vars->phy_flags & PHY_XGXS_FLAG) { @@ -5832,20 +5264,21 @@ static u8 bnx2x_link_initialize(struct link_params *params, req_line_speed*/ vars->line_speed = params->req_line_speed; - bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc); + bnx2x_calc_ieee_aneg_adv(int_phy, params, &vars->ieee_fc); /* init ext phy and enable link state int */ - non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || + non_ext_phy = ((ext_phy->type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || (params->loopback_mode == LOOPBACK_XGXS_10)); if (non_ext_phy || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || + (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || + (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || + (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { - if (params->req_line_speed == SPEED_AUTO_NEG) - bnx2x_set_parallel_detection(params, vars->phy_flags); - bnx2x_init_internal_phy(params, vars, non_ext_phy); + if (vars->line_speed == SPEED_AUTO_NEG) + bnx2x_set_parallel_detection(int_phy, params); + bnx2x_init_internal_phy(int_phy, params, vars); } if (!non_ext_phy) @@ -5857,10 +5290,8 @@ static u8 bnx2x_link_initialize(struct link_params *params, NIG_STATUS_SERDES0_LINK_STATUS)); return rc; - } - u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; @@ -5877,10 +5308,28 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; - if (params->switch_cfg == SWITCH_CFG_1G) + if (params->switch_cfg == SWITCH_CFG_1G) { + params->phy[INT_PHY].type = + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT; vars->phy_flags = PHY_SERDES_FLAG; - else + } else { + params->phy[INT_PHY].type = + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT; vars->phy_flags = PHY_XGXS_FLAG; + } + params->phy[INT_PHY].mdio_ctrl = + bnx2x_get_emac_base(bp, + params->phy[INT_PHY].type, params->port); + if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { + params->phy[EXT_PHY1].type = + XGXS_EXT_PHY_TYPE(params->ext_phy_config); + params->phy[EXT_PHY1].addr = + XGXS_EXT_PHY_ADDR(params->ext_phy_config); + params->phy[EXT_PHY1].mdio_ctrl = + bnx2x_get_emac_base(bp, params->phy[EXT_PHY1].type, + params->port); + } /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, @@ -5951,6 +5400,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->phy_flags = PHY_XGXS_FLAG; bnx2x_phy_deassert(params, vars->phy_flags); + /* set bmac loopback */ bnx2x_bmac_enable(params, vars, 1); @@ -5989,7 +5439,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) NIG_REG_XGXS0_CTRL_PHY_ADDR+ params->port*0x18); params->phy_addr = (u8)val; - + params->phy[INT_PHY].addr = (u8)val; bnx2x_phy_deassert(params, vars->phy_flags); bnx2x_link_initialize(params, vars); @@ -5999,11 +5449,14 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) if (params->loopback_mode == LOOPBACK_XGXS_10) { /* set 10G XGXS loopback */ - bnx2x_set_xgxs_loopback(params, vars, 1); + bnx2x_set_xgxs_loopback(¶ms->phy[INT_PHY], + params, 1); } else { /* set external phy loopback */ - bnx2x_ext_phy_loopback(params); + bnx2x_ext_phy_loopback(¶ms->phy[INT_PHY], + params); } + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); @@ -6041,7 +5494,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) return -EINVAL; } DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr); - + params->phy[INT_PHY].addr = params->phy_addr; bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); @@ -6049,13 +5502,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) return 0; } -static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr) -{ - DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port); +static void bnx2x_8726_reset_phy(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy\n"); /* Set serial boot control for external load */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001); } @@ -6064,9 +5517,9 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u32 ext_phy_config = params->ext_phy_config; + u8 port = params->port; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. @@ -6101,7 +5554,8 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /* clear link led */ bnx2x_set_led(params, LED_MODE_OFF, 0); if (reset_ext_phy) { - switch (ext_phy_type) { + struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; + switch (phy->type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: break; @@ -6110,13 +5564,9 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, { /* Disable Transmitter */ - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, 0); break; } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: @@ -6129,10 +5579,8 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); /* Set soft reset */ - bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr); + bnx2x_8726_reset_phy(bp, phy); break; } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: @@ -6170,6 +5618,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, return 0; } + static u8 bnx2x_update_link_down(struct link_params *params, struct link_vars *vars) { @@ -6222,11 +5671,10 @@ static u8 bnx2x_update_link_up(struct link_params *params, bnx2x_emac_enable(params, vars, 0); /* AN complete? */ - if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { - if (!(vars->phy_flags & - PHY_SGMII_FLAG)) - bnx2x_set_gmii_tx_driver(params); - } + if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) + && (!(vars->phy_flags & PHY_SGMII_FLAG)) && + SINGLE_MEDIA_DIRECT(params)) + bnx2x_set_gmii_tx_driver(params); } /* PBF - link up */ @@ -6261,7 +5709,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) u16 gp_status; u8 link_10g; u8 ext_phy_link_up, rc = 0; - u32 ext_phy_type; + struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; u8 is_mi_int = 0; DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", @@ -6283,13 +5731,13 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) /* disable emac */ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* Check external link change only for non-direct */ - ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int); + ext_phy_link_up = bnx2x_ext_phy_is_link_up(¶ms->phy[EXT_PHY1], + params, vars, + is_mi_int); /* Read gp_status */ - CL45_RD_OVER_CL22(bp, port, params->phy_addr, + CL45_RD_OVER_CL22(bp, int_phy, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); @@ -6316,12 +5764,12 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) the xgxs link would probably become up again without the need to initialize it*/ - if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) && - (ext_phy_link_up && !vars->phy_link_up)) - bnx2x_init_internal_phy(params, vars, 0); + if ((int_phy->type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && + (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && + (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) && + (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) && + (int_phy->type && !vars->phy_link_up)) + bnx2x_init_internal_phy(int_phy, params, vars); /* link is up only if both local phy and external phy are up */ vars->link_up = (ext_phy_link_up && vars->phy_link_up); @@ -6334,19 +5782,65 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) return rc; } +static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, + u8 phy_index, u8 port) +{ + u32 ext_phy_config = 0; + switch (phy_index) { + case EXT_PHY1: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config)); + break; + default: + DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); + return -EINVAL; + } + + return ext_phy_config; +} + +static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, + u8 phy_index, + u32 shmem_base, + u8 port, + struct bnx2x_phy *phy) +{ + u32 ext_phy_config; + + ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, + phy_index, port); + phy->type = XGXS_EXT_PHY_TYPE(ext_phy_config); + phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); + phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port); + return 0; +} + +static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u8 port, struct bnx2x_phy *phy) +{ + u8 status = 0; + status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, + port, phy); + return status; +} + static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) { - u8 ext_phy_addr[PORT_MAX]; + struct bnx2x_phy phy[PORT_MAX]; + struct bnx2x_phy *phy_blk[PORT_MAX]; u16 val; s8 port; /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Extract the ext phy address for the port */ - u32 ext_phy_config = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].external_phy_config)); - + if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + port, &phy[port]) != + 0) { + DP(NETIF_MSG_LINK, "populate_phy failed\n"); + return -EINVAL; + } /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, (NIG_MASK_XGXS0_LINK_STATUS | @@ -6354,17 +5848,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config); - /* Need to take the phy out of low power mode in order to write to access its registers */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); /* Reset the phy */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, &phy[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -6373,15 +5863,22 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* Add delay of 150ms after reset */ msleep(150); + if (phy[PORT_0].addr & 0x1) { + phy_blk[PORT_0] = &(phy[PORT_1]); + phy_blk[PORT_1] = &(phy[PORT_0]); + } else { + phy_blk[PORT_0] = &(phy[PORT_0]); + phy_blk[PORT_1] = &(phy[PORT_1]); + } + /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; - bnx2x_bcm8073_external_rom_boot(bp, port, - ext_phy_addr[port], shmem_base); + bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], + port, shmem_base); - bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); if (fw_ver1 == 0 || fw_ver1 == 0x4321) { @@ -6393,16 +5890,12 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) } /* Only set bit 10 = 1 (Tx power down) */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, &val); /* Phase1 of TX_POWER_DOWN reset */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10)); @@ -6416,28 +5909,20 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Phase2 of POWER_DOWN_RESET */ /* Release bit 10 (Release Tx power down) */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, &val); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); msleep(15); /* Read modify write the SPI-ROM version select register */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, &val); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); @@ -6446,14 +5931,14 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } return 0; - } static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) { - u8 ext_phy_addr[PORT_MAX]; s8 port, first_port, i; u32 swap_val, swap_override; + struct bnx2x_phy phy[PORT_MAX]; + struct bnx2x_phy *phy_blk[PORT_MAX]; DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); @@ -6469,10 +5954,12 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* PART1 - Reset both phys */ for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { /* Extract the ext phy address for the port */ - u32 ext_phy_config = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].external_phy_config)); - + if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + port, &phy[port]) != + 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return -EINVAL; + } /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, (NIG_MASK_XGXS0_LINK_STATUS | @@ -6480,12 +5967,9 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config); /* Reset the phy */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr[port], + bnx2x_cl45_write(bp, &phy[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -6493,16 +5977,20 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* Add delay of 150ms after reset */ msleep(150); - + if (phy[PORT_0].addr & 0x1) { + phy_blk[PORT_0] = &(phy[PORT_1]); + phy_blk[PORT_1] = &(phy[PORT_0]); + } else { + phy_blk[PORT_0] = &(phy[PORT_0]); + phy_blk[PORT_1] = &(phy[PORT_1]); + } /* PART2 - Download firmware to both phys */ - for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { + for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; - bnx2x_bcm8727_external_rom_boot(bp, port, - ext_phy_addr[port], shmem_base); - - bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr[port], + bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], + port, shmem_base); + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); if (fw_ver1 == 0 || fw_ver1 == 0x4321) { @@ -6517,13 +6005,11 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) { - u8 ext_phy_addr; u32 val; s8 port; - + struct bnx2x_phy phy; /* Use port1 because of the static port-swap */ /* Enable the module detection interrupt */ val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); @@ -6535,15 +6021,17 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) msleep(5); for (port = 0; port < PORT_MAX; port++) { /* Extract the ext phy address for the port */ - u32 ext_phy_config = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].external_phy_config)); + if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + port, &phy) != + 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return -EINVAL; + } - ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config); - DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n", - ext_phy_addr); + /* Reset phy*/ + bnx2x_cl45_write(bp, &phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001); - bnx2x_8726_reset_phy(bp, port, ext_phy_addr); /* Set fault module detected LED on */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, @@ -6594,29 +6082,23 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) return rc; } -void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) +void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) { u16 val, cnt; - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, - phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_RESET, &val); for (cnt = 0; cnt < 10; cnt++) { msleep(50); /* Writes a self-clearing reset */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, - phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_RESET, (val | (1<<15))); /* Wait for clear */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, - phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_RESET, &val); diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 40c2981de8ed..9bfe7fa452bc 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2009 Broadcom Corporation +/* Copyright 2008-2010 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -46,9 +46,35 @@ #define SFP_EEPROM_PART_NO_ADDR 0x28 #define SFP_EEPROM_PART_NO_SIZE 16 #define PWR_FLT_ERR_MSG_LEN 250 +/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */ +#define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1) +/* Single Media board contains single external phy */ +#define SINGLE_MEDIA(params) (params->num_phys == 2) /***********************************************************/ /* Structs */ /***********************************************************/ +#define INT_PHY 0 +#define EXT_PHY1 1 + +#define MAX_PHYS 2 + +/***********************************************************/ +/* bnx2x_phy struct */ +/* Defines the required arguments and function per phy */ +/***********************************************************/ +struct link_vars; +struct link_params; +struct bnx2x_phy; + +struct bnx2x_phy { + u32 type; + + /* Loaded during init */ + u8 addr; + + u32 mdio_ctrl; +}; + /* Inputs parameters to the CLC */ struct link_params { @@ -106,6 +132,11 @@ struct link_params { #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BCM8727_NOC (1<<3) + /* Will be populated during common init */ + struct bnx2x_phy phy[MAX_PHYS]; + + /* Will be populated during common init */ + u8 num_phys; /* Device pointer passed to all callback functions */ struct bnx2x *bp; @@ -155,17 +186,20 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /* bnx2x_link_update should be called upon link interrupt */ u8 bnx2x_link_update(struct link_params *input, struct link_vars *output); -/* use the following cl45 functions to read/write from external_phy +/* use the following phy functions to read/write from external_phy In order to use it to read/write internal phy registers, use DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as - Use ext_phy_type of 0 in case of cl22 over cl45 the register */ -u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 *ret_val); +u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val); -u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 val); +u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val); +u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val); +u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val); /* Reads the link_status from the shmem, and update the link vars accordingly */ void bnx2x_link_status_update(struct link_params *input, @@ -198,9 +232,14 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); -void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr); +/* Reset the external of SFX7101 */ +void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy); -u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf); - +/* Returns the aggregative supported attributes of the phys on board */ +u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx); +/* Probe the phys on board, and populate them in "params" */ +u8 bnx2x_phy_probe(struct link_params *params); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 993d7e83f1d3..174ed8b4587e 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4351,7 +4351,6 @@ static int bnx2x_init_port(struct bnx2x *bp) default: break; } - bnx2x__link_reset(bp); return 0; @@ -6984,23 +6983,15 @@ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, struct bnx2x *bp = netdev_priv(netdev); u16 value; int rc; - u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n", prtad, devad, addr); - if (prtad != bp->mdio.prtad) { - DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n", - prtad, bp->mdio.prtad); - return -EINVAL; - } - /* The HW expects different devad if CL22 is used */ devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad; bnx2x_acquire_phy_lock(bp); - rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad, - devad, addr, &value); + rc = bnx2x_phy_read(&bp->link_params, prtad, devad, addr, &value); bnx2x_release_phy_lock(bp); DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc); @@ -7014,24 +7005,16 @@ static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad, u16 addr, u16 value) { struct bnx2x *bp = netdev_priv(netdev); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); int rc; DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x," " value 0x%x\n", prtad, devad, addr, value); - if (prtad != bp->mdio.prtad) { - DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n", - prtad, bp->mdio.prtad); - return -EINVAL; - } - /* The HW expects different devad if CL22 is used */ devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad; bnx2x_acquire_phy_lock(bp); - rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad, - devad, addr, value); + rc = bnx2x_phy_write(&bp->link_params, prtad, devad, addr, value); bnx2x_release_phy_lock(bp); return rc; } diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 398961772bb5..398cf55b8e10 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5135,18 +5135,22 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR 0x8005 #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF 0x8007 #define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff -#define MDIO_PMA_REG_8727_MISC_CTRL 0x8309 #define MDIO_PMA_REG_8727_TX_CTRL1 0xca02 #define MDIO_PMA_REG_8727_TX_CTRL2 0xca05 #define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808 #define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e +#define MDIO_PMA_REG_8727_PCS_GP 0xc842 + +#define MDIO_AN_REG_8727_MISC_CTRL 0x8309 #define MDIO_PMA_REG_8073_CHIP_REV 0xc801 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820 #define MDIO_PMA_REG_8073_XAUI_WA 0xc841 +#define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 0xcd08 #define MDIO_PMA_REG_7101_RESET 0xc000 #define MDIO_PMA_REG_7107_LED_CNTL 0xc007 +#define MDIO_PMA_REG_7107_LINK_LED_CNTL 0xc009 #define MDIO_PMA_REG_7101_VER1 0xc026 #define MDIO_PMA_REG_7101_VER2 0xc027 @@ -5210,11 +5214,13 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_CL37_FC_LP 0xffe5 #define MDIO_AN_REG_8073_2_5G 0x8329 +#define MDIO_AN_REG_8073_BAM 0x8350 -#define MDIO_AN_REG_8727_MISC_CTRL 0x8309 #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0 +#define MDIO_AN_REG_8481_LEGACY_MII_STATUS 0xffe1 #define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4 +#define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION 0xffe6 #define MDIO_AN_REG_8481_1000T_CTRL 0xffe9 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7 -- cgit v1.2.3 From b7737c9be9d3e894d1a4375c52f5f47789475f26 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:40:54 +0000 Subject: bnx2x: Split PHY functions Move the code into PHY oriented functions, and for that a new structure is defines for each PHY which contain PHY properties and its own functions. This also enables to encapsulate all PHY specific operations into the PHY functions. During initialization, the PHYs will be probed by the "bnx2x_phy_probe" function to detect which PHYs exist on-board, and configure them accordingly. Note that the ext_phy_reset implementation was incorporated in the ext_phy_init since it is actually part of the PHY initialization procedure. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 35 +- drivers/net/bnx2x/bnx2x_link.c | 1864 +++++++++++++++++++++++++------------ drivers/net/bnx2x/bnx2x_link.h | 109 ++- drivers/net/bnx2x/bnx2x_main.c | 270 +----- 4 files changed, 1425 insertions(+), 853 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 2c7e0ab6ccf8..becfd9eb8905 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -52,39 +52,14 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->duplex = -1; } - if (bp->link_params.switch_cfg == SWITCH_CFG_10G) { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + if (bp->link_params.num_phys > 0) { + if (bp->link_params.phy[bp->link_params.num_phys - 1]. + supported & SUPPORTED_FIBRE) cmd->port = PORT_FIBRE; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + else cmd->port = PORT_TP; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; - - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - break; - } } else - cmd->port = PORT_TP; - + DP(NETIF_MSG_LINK, "No media found\n"); cmd->phy_address = bp->mdio.prtad; cmd->transceiver = XCVR_INTERNAL; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e6bc70ff8432..c1540727cdbf 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1776,16 +1776,20 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, bnx2x_restart_autoneg(phy, params, 0); DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); } -static u8 bnx2x_link_settings_status(struct link_params *params, - struct link_vars *vars, - u32 gp_status, - u8 ext_phy_link_up) +static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 new_line_speed; + u16 new_line_speed , gp_status; u8 rc = 0; u32 ext_phy_type; - vars->link_status = 0; + /* Read gp_status */ + CL45_RD_OVER_CL22(bp, phy, + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", gp_status); @@ -1881,23 +1885,6 @@ static u8 bnx2x_link_settings_status(struct link_params *params, return -EINVAL; } - /* Upon link speed change set the NIG into drain mode. - Comes to deals with possible FIFO glitch due to clk change - when speed is decreased without link down indicator */ - if (new_line_speed != vars->line_speed) { - if (!SINGLE_MEDIA_DIRECT(params) && - ext_phy_link_up) { - DP(NETIF_MSG_LINK, "Internal link speed %d is" - " different than the external" - " link speed %d\n", new_line_speed, - vars->line_speed); - vars->phy_link_up = 0; - return 0; - } - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); - msleep(1); - } vars->line_speed = new_line_speed; vars->link_status |= LINK_STATUS_SERDES_LINK; ext_phy_type = params->phy[EXT_PHY1].type; @@ -2001,7 +1988,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) } static u8 bnx2x_emac_program(struct link_params *params, - u32 line_speed, u32 duplex) + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2013,7 +2000,7 @@ static u8 bnx2x_emac_program(struct link_params *params, (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_MII_10M | EMAC_MODE_HALF_DUPLEX)); - switch (line_speed) { + switch (vars->line_speed) { case SPEED_10: mode |= EMAC_MODE_PORT_MII_10M; break; @@ -2032,21 +2019,74 @@ static u8 bnx2x_emac_program(struct link_params *params, default: /* 10G not valid for EMAC */ - DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed); + DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", + vars->line_speed); return -EINVAL; } - if (duplex == DUPLEX_HALF) + if (vars->duplex == DUPLEX_HALF) mode |= EMAC_MODE_HALF_DUPLEX; bnx2x_bits_en(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, mode); - bnx2x_set_led(params, LED_MODE_OPER, line_speed); + bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); return 0; } +static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 rc; + vars->phy_flags |= PHY_SGMII_FLAG; + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + bnx2x_set_aer_mmd(params, phy); + rc = bnx2x_reset_unicore(params, phy, 1); + /* reset the SerDes and wait for reset bit return low */ + if (rc != 0) + return rc; + bnx2x_set_aer_mmd(params, phy); + + return rc; +} + +static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 rc; + vars->phy_flags = PHY_XGXS_FLAG; + if ((phy->req_line_speed && + ((phy->req_line_speed == SPEED_100) || + (phy->req_line_speed == SPEED_10))) || + (!phy->req_line_speed && + (phy->speed_cap_mask >= + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && + (phy->speed_cap_mask < + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + )) + vars->phy_flags |= PHY_SGMII_FLAG; + else + vars->phy_flags &= ~PHY_SGMII_FLAG; + + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + bnx2x_set_aer_mmd(params, phy); + bnx2x_set_master_ln(params, phy); + + rc = bnx2x_reset_unicore(params, phy, 0); + /* reset the SerDes and wait for reset bit return low */ + if (rc != 0) + return rc; + + bnx2x_set_aer_mmd(params, phy); + /* setting the masterLn_def again after the reset */ + bnx2x_set_master_ln(params, phy); + bnx2x_set_swap_lanes(params, phy); + + return rc; +} /*****************************************************************************/ /* External Phy section */ /*****************************************************************************/ @@ -2059,127 +2099,6 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } -static void bnx2x_ext_phy_reset(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port); - /* The PHY reset is controled by GPIO 1 - * Give it 1ms of reset pulse - */ - switch (phy->type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "XGXS Direct\n"); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "XGXS 8705/8706\n"); - - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0xa040); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - DP(NETIF_MSG_LINK, "XGXS 8072\n"); - - /* Unset Low Power Mode and SW reset */ - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - DP(NETIF_MSG_LINK, "XGXS 8073\n"); - - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - DP(NETIF_MSG_LINK, "XGXS SFX7101\n"); - - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - msleep(1); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n"); - break; - default: - DP(NETIF_MSG_LINK, "BAD phy type 0x%x\n", - phy->type); - break; - } -} - static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, u32 shmem_base, u32 spirom_ver) { @@ -2498,11 +2417,13 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 port, u8 tx_en) { u16 val; - DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x\n", tx_en); + DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", + tx_en, port); /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, @@ -2946,9 +2867,10 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, * In case of NOC feature is disabled and power is up, set GPIO control * as input to enable listening of over-current indication */ - - if (!(params->feature_config_flags & - FEATURE_CONFIG_BCM8727_NOC) && is_power_up) + if (phy->flags & FLAGS_NOC) + return; + if (!(phy->flags & + FLAGS_NOC) && is_power_up) val = (1<<4); else /* @@ -3022,9 +2944,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, if (rc == 0 || (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, 1); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); else - bnx2x_sfp_set_transmitter(bp, phy, 0); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); return rc; } @@ -3068,7 +2990,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) /* Disable transmit for this module */ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, 0); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); } } @@ -3233,7 +3155,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, CL45_WR_OVER_CL22(bp, phy, bank, MDIO_RX0_RX_EQ_BOOST, - params->xgxs_config_rx[i]); + phy->rx_preemphasis[i]); } for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; @@ -3241,7 +3163,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, CL45_WR_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, - params->xgxs_config_tx[i]); + phy->tx_preemphasis[i]); } } @@ -3331,24 +3253,10 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, } } -static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) +static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, + struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u16 cnt; - u16 ctrl = 0; - u16 val = 0; - u8 rc = 0; - struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; - if (vars->phy_flags & PHY_XGXS_FLAG) { - /* Make sure that the soft reset is off (expect for the 8072: - * due to the lock, it will be done inside the specific - * handling) - */ - if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && - (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) && - (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) { + u16 cnt, ctrl; /* Wait for soft reset to get cleared upto 1 sec */ for (cnt = 0; cnt < 1000; cnt++) { bnx2x_cl45_read(bp, phy, @@ -3360,13 +3268,22 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) } DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); - } - - switch (phy->type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - break; + return 0; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: +static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "init 8705\n"); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); + bnx2x_wait_reset_complete(bp, phy); DP(NETIF_MSG_LINK, "XGXS 8705\n"); bnx2x_cl45_write(bp, phy, @@ -3388,9 +3305,23 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) /* BCM8705 doesn't have microcode, hence the 0 */ bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + return 0; +} + +static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u16 cnt, val; + struct bnx2x *bp = params->bp; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); + + bnx2x_wait_reset_complete(bp, phy); /* Wait until fw is loaded */ for (cnt = 0; cnt < 100; cnt++) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, @@ -3416,7 +3347,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) val &= ~0x7; /* Set control bits according to configuation */ - val |= (params->xgxs_config_rx[i] & + val |= (phy->rx_preemphasis[i] & 0x7); DP(NETIF_MSG_LINK, "Setting RX" "Equalizer to BCM8706 reg 0x%x" @@ -3479,8 +3410,26 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_save_bcm_spirom_ver(bp, params->port, phy, params->shmem_base); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + return 0; +} + +static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + bnx2x_wait_reset_complete(bp, phy); + + bnx2x_wait_reset_complete(bp, phy); DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); bnx2x_8726_external_rom_boot(phy, params); @@ -3538,21 +3487,39 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," "TX_CTRL2 0x%x\n", - params->xgxs_config_tx[0], - params->xgxs_config_tx[1]); + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TX_CTRL1, - params->xgxs_config_tx[0]); + phy->tx_preemphasis[0]); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TX_CTRL2, - params->xgxs_config_tx[1]); + phy->tx_preemphasis[1]); } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + return 0; + +} + +static u8 bnx2x_8072_8073_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val = 0; + u8 gpio_port; + DP(NETIF_MSG_LINK, "Init 8073\n"); + + gpio_port = params->port; + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); + + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); + { u16 tmp1; u16 rx_alarm_ctrl_val; @@ -3606,7 +3573,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_807x_force_10G(bp, phy); DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); - break; + return 0; } else { bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, @@ -3728,21 +3695,25 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) "Advertise 1G=%x, 10G=%x\n", ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); - break; + return 0; } +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { - u16 tmp1; - u16 rx_alarm_ctrl_val; - u16 lasi_ctrl_val; +static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u16 tmp1, val, mod_abs; + u16 rx_alarm_ctrl_val; + u16 lasi_ctrl_val; + struct bnx2x *bp = params->bp; + /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ - u16 mod_abs; rx_alarm_ctrl_val = (1<<2) | (1<<5) ; lasi_ctrl_val = 0x0004; - + bnx2x_wait_reset_complete(bp, phy); DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); /* enable LASI */ bnx2x_cl45_write(bp, phy, @@ -3861,28 +3832,39 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," "TX_CTRL2 0x%x\n", - params->xgxs_config_tx[0], - params->xgxs_config_tx[1]); + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, - params->xgxs_config_tx[0]); + phy->tx_preemphasis[0]); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, - params->xgxs_config_tx[1]); + phy->tx_preemphasis[1]); } - break; - } + return 0; +} + +static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u16 fw_ver1, fw_ver2, val; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); + + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - { - u16 fw_ver1, fw_ver2; DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); - + bnx2x_wait_reset_complete(bp, phy); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); @@ -3912,10 +3894,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_save_spirom_version(params->bp, params->port, params->shmem_base, (u32)(fw_ver1<<16 | fw_ver2)); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + return 0; +} + +static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; { /* This phy uses the NIG latch mechanism since link indication arrives through its LED4 and not via @@ -3924,6 +3910,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) u16 autoneg_val, an_1000_val, an_10_100_val, temp; temp = vars->line_speed; vars->line_speed = SPEED_10000; + bnx2x_wait_reset_complete(bp, phy); bnx2x_set_autoneg(phy, params, vars, 0); bnx2x_program_serdes(phy, params, vars); vars->line_speed = temp; @@ -4052,24 +4039,49 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) /* Save spirom version */ bnx2x_save_8481_spirom_version(phy, params, params->shmem_base); - break; + return 0; } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, - "XGXS PHY Failure detected 0x%x\n", - phy->type); - rc = -EINVAL; - break; +} - default: - DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", - phy->type); - break; - } - } - return rc; +static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 temp; + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + params->port); + msleep(200); /* 100 is not enough */ + + /** + * BCM84823 requires that XGXS links up first @ 10G for normal + * behavior + */ + temp = vars->line_speed; + vars->line_speed = SPEED_10000; + bnx2x_set_autoneg(phy, params, vars, 0); + bnx2x_program_serdes(phy, params, vars); + vars->line_speed = temp; + return bnx2x_848xx_cmn_config_init(phy, params, vars); } +static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + return bnx2x_848xx_cmn_config_init(phy, params, vars); +} static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, struct link_params *params) { @@ -4134,7 +4146,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, 0); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) bnx2x_sfp_module_detection(phy, params); @@ -4148,25 +4160,13 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, module plugged in/out */ } - -static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, +static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, struct link_params *params, - struct link_vars *vars, - u8 is_mi_int) + struct link_vars *vars) { - struct bnx2x *bp = params->bp; - u16 val1 = 0, val2; - u16 rx_sd, pcs_status; u8 ext_phy_link_up = 0; - - if (vars->phy_flags & PHY_XGXS_FLAG) { - switch (phy->type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "XGXS Direct\n"); - ext_phy_link_up = 1; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + u16 val1, rx_sd; + struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "XGXS 8705\n"); bnx2x_cl45_read(bp, phy, MDIO_WIS_DEVAD, @@ -4194,10 +4194,16 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, ((val1 & (1<<8)) == 0)); if (ext_phy_link_up) vars->line_speed = SPEED_10000; - break; + return ext_phy_link_up; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: +static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 link_up = 0; + u16 val1, val2, rx_sd, pcs_status; + struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); /* Clear RX Alarm*/ bnx2x_cl45_read(bp, phy, @@ -4233,35 +4239,54 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, * bit 0 of pcs_status are set, or if the autoneg bit 1 is set */ - ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || - (val2 & (1<<1))); - if (ext_phy_link_up) { - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { - /* If transmitter is disabled, - ignore false link up indication */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is " - "disabled\n"); - ext_phy_link_up = 0; - break; - } - } + link_up = ((rx_sd & pcs_status & 0x1) || + (val2 & (1<<1))); + if (link_up) { if (val2 & (1<<1)) vars->line_speed = SPEED_1000; else vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); + return link_up; } - break; + return 0; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { +static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + return bnx2x_8706_8726_read_status(phy, params, vars); +} + +static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val1; + u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars); + if (link_up) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, + &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + link_up = 0; + vars->line_speed = 0; + } + } + return link_up; +} +static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) + +{ + struct bnx2x *bp = params->bp; + u8 ext_phy_link_up = 0; u16 link_status = 0; - u16 rx_alarm_status; + u16 rx_alarm_status, val1; /* Check the LASI */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, @@ -4288,8 +4313,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, * If a module is present and there is need to check * for over current */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BCM8727_NOC) && + if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { /* Check over-current using 8727 GPIO0 input*/ bnx2x_cl45_read(bp, phy, @@ -4328,7 +4352,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); - break; + return ext_phy_link_up; } } /* Over current check */ @@ -4351,7 +4375,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, if (val1 & (1<<15)) { DP(NETIF_MSG_LINK, "Tx is disabled\n"); ext_phy_link_up = 0; - break; + return ext_phy_link_up; } bnx2x_cl45_read(bp, phy, @@ -4378,12 +4402,16 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, "port %x: External link" " is down\n", params->port); } - break; - } + return ext_phy_link_up; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - { +} +static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 ext_phy_link_up = 0; + u16 val1, val2; u16 link_status = 0; u16 an1000_status = 0; @@ -4456,7 +4484,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, if (bnx2x_8073_xaui_wa(bp, phy) != 0) { ext_phy_link_up = 0; - break; + return ext_phy_link_up; } } bnx2x_cl45_read(bp, phy, @@ -4561,9 +4589,16 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, } } - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + return ext_phy_link_up; +} + +static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 ext_phy_link_up; + u16 val1, val2; bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); @@ -4597,9 +4632,17 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, val2, (val2 & (1<<14))); } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + return ext_phy_link_up; +} + +static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val1, val2; + u8 ext_phy_link_up = 0; + /* Check 10G-BaseT link status */ /* Check PMD signal ok */ bnx2x_cl45_read(bp, phy, @@ -4661,26 +4704,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct bnx2x_phy *phy, (vars->duplex == DUPLEX_FULL)); } } - break; - default: - DP(NETIF_MSG_LINK, - "BAD SerDes ext_phy_config 0x%x\n", - phy->type); - ext_phy_link_up = 0; - break; - } - } - - /* Set SGMII mode for external phy */ - if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { - if (vars->line_speed < SPEED_1000) - vars->phy_flags |= PHY_SGMII_FLAG; - else - vars->phy_flags &= ~PHY_SGMII_FLAG; - } - - return ext_phy_link_up; + return ext_phy_link_up; } + static void bnx2x_link_int_enable(struct link_params *params) { u8 port = params->port; @@ -4825,13 +4851,26 @@ static void bnx2x_link_int_ack(struct link_params *params, } } -static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) +static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) +{ + if (*len < 5) + return -EINVAL; + str[0] = (spirom_ver & 0xFF); + str[1] = (spirom_ver & 0xFF00) >> 8; + str[2] = (spirom_ver & 0xFF0000) >> 16; + str[3] = (spirom_ver & 0xFF000000) >> 24; + str[4] = '\0'; + *len -= 5; + return 0; +} + +static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) { u8 *str_ptr = str; u32 mask = 0xf0000000; u8 shift = 8*4; u8 digit; - if (len < 10) { + if (*len < 10) { /* Need more than 10chars for this format */ *str_ptr = '\0'; return -EINVAL; @@ -4855,65 +4894,41 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) return 0; } +static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) +{ + u8 status = 0; + u32 spirom_ver; + spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); + status = bnx2x_format_ver(spirom_ver, str, len); + return status; +} + +static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) +{ + str[0] = '\0'; + (*len)--; + return 0; +} + u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, u8 *version, u16 len) { struct bnx2x *bp; - u32 ext_phy_type = 0; u32 spirom_ver = 0; - u8 status; - + u8 status = 0; + u8 *ver_p = version; if (version == NULL || params == NULL) return -EINVAL; bp = params->bp; - spirom_ver = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[params->port].ext_phy_fw_version)); - - status = 0; - /* reset the returned value to zero */ - ext_phy_type = params->phy[EXT_PHY1].type; - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - - if (len < 5) - return -EINVAL; - - version[0] = (spirom_ver & 0xFF); - version[1] = (spirom_ver & 0xFF00) >> 8; - version[2] = (spirom_ver & 0xFF0000) >> 16; - version[3] = (spirom_ver & 0xFF000000) >> 24; - version[4] = '\0'; - - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - status = bnx2x_format_ver(spirom_ver, version, len); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 | - (spirom_ver & 0x7F); - status = bnx2x_format_ver(spirom_ver, version, len); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - version[0] = '\0'; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:" - " type is FAILURE!\n"); - status = -EINVAL; - break; + /* Extract first external phy*/ + version[0] = '\0'; + spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); - default: - break; - } + if (params->phy[EXT_PHY1].format_fw_ver) + status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, + ver_p, + &len); return status; } @@ -4969,47 +4984,21 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, } } -static void bnx2x_ext_phy_loopback(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); +} - if (params->switch_cfg == SWITCH_CFG_10G) { - - /* CL37 Autoneg Enabled */ - switch (phy->type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN: - DP(NETIF_MSG_LINK, - "ext_phy_loopback: We should not get here\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 0x0001); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* SFX7101_XGXS_TEST1 */ - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, - MDIO_XS_SFX7101_XGXS_TEST1, - 0x100); - DP(NETIF_MSG_LINK, - "ext_phy_loopback: set ext phy loopback\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - - break; - } /* switch external PHY type */ - } +static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* SFX7101_XGXS_TEST1 */ + bnx2x_cl45_write(bp, phy, + MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); } /* *------------------------------------------------------------------------ @@ -5204,9 +5193,17 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); /* link is up only if both local phy and external phy are up */ - if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) && - bnx2x_ext_phy_is_link_up(¶ms->phy[EXT_PHY1], params, vars, 1)) - return 0; + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { + u8 ext_phy_link_up = 1; + struct link_vars temp_vars; + if (params->phy[EXT_PHY1].read_status) + ext_phy_link_up &= + params->phy[EXT_PHY1].read_status( + ¶ms->phy[EXT_PHY1], + params, &temp_vars); + if (ext_phy_link_up) + return 0; + } return -ESRCH; } @@ -5217,11 +5214,10 @@ static u8 bnx2x_link_initialize(struct link_params *params, struct bnx2x *bp = params->bp; u8 port = params->port; u8 rc = 0; - u8 non_ext_phy; + u8 phy_index, non_ext_phy; struct bnx2x_phy *ext_phy = ¶ms->phy[EXT_PHY1]; struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; /* Activate the external PHY */ - bnx2x_ext_phy_reset(ext_phy, params, vars); bnx2x_set_aer_mmd(params, int_phy); @@ -5282,7 +5278,12 @@ static u8 bnx2x_link_initialize(struct link_params *params, } if (!non_ext_phy) - rc |= bnx2x_ext_phy_init(params, vars); + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + params->phy[phy_index].config_init( + ¶ms->phy[phy_index], + params, vars); + } bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, (NIG_STATUS_XGXS0_LINK10G | @@ -5292,6 +5293,35 @@ static u8 bnx2x_link_initialize(struct link_params *params, return rc; } +static void set_phy_vars(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 actual_phy_idx, phy_index; + + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + + actual_phy_idx = phy_index; + params->phy[actual_phy_idx].req_flow_ctrl = + params->req_flow_ctrl; + + params->phy[actual_phy_idx].req_line_speed = + params->req_line_speed; + + params->phy[actual_phy_idx].speed_cap_mask = + params->speed_cap_mask; + + params->phy[actual_phy_idx].req_duplex = + params->req_duplex; + + DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," + " speed_cap_mask %x\n", + params->phy[actual_phy_idx].req_flow_ctrl, + params->phy[actual_phy_idx].req_line_speed, + params->phy[actual_phy_idx].speed_cap_mask); + } +} + u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; @@ -5307,29 +5337,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; - - if (params->switch_cfg == SWITCH_CFG_1G) { - params->phy[INT_PHY].type = - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT; - vars->phy_flags = PHY_SERDES_FLAG; - } else { - params->phy[INT_PHY].type = - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT; - vars->phy_flags = PHY_XGXS_FLAG; - } - params->phy[INT_PHY].mdio_ctrl = - bnx2x_get_emac_base(bp, - params->phy[INT_PHY].type, params->port); - if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { - params->phy[EXT_PHY1].type = - XGXS_EXT_PHY_TYPE(params->ext_phy_config); - params->phy[EXT_PHY1].addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - params->phy[EXT_PHY1].mdio_ctrl = - bnx2x_get_emac_base(bp, params->phy[EXT_PHY1].type, - params->port); - } + vars->phy_flags = 0; /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, @@ -5340,6 +5348,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_emac_init(params, vars); + if (params->num_phys == 0) { + DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); + return -EINVAL; + } + set_phy_vars(params); + + DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); if (CHIP_REV_IS_FPGA(bp)) { vars->link_up = 1; @@ -5420,8 +5435,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_phy_deassert(params, vars->phy_flags); /* set bmac loopback */ bnx2x_emac_enable(params, vars, 1); - bnx2x_emac_program(params, vars->line_speed, - vars->duplex); + bnx2x_emac_program(params, vars); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); @@ -5438,8 +5452,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) val = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR+ params->port*0x18); - params->phy_addr = (u8)val; - params->phy[INT_PHY].addr = (u8)val; + bnx2x_phy_deassert(params, vars->phy_flags); bnx2x_link_initialize(params, vars); @@ -5449,12 +5462,20 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) if (params->loopback_mode == LOOPBACK_XGXS_10) { /* set 10G XGXS loopback */ - bnx2x_set_xgxs_loopback(¶ms->phy[INT_PHY], - params, 1); + params->phy[INT_PHY].config_loopback( + ¶ms->phy[INT_PHY], + params); + } else { /* set external phy loopback */ - bnx2x_ext_phy_loopback(¶ms->phy[INT_PHY], + u8 phy_index; + for (phy_index = EXT_PHY1; + phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].config_loopback) + params->phy[phy_index].config_loopback( + ¶ms->phy[phy_index], params); + } } REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + @@ -5464,37 +5485,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } else /* No loopback */ { + if (params->switch_cfg == SWITCH_CFG_10G) + vars->phy_flags = PHY_XGXS_FLAG; bnx2x_phy_deassert(params, vars->phy_flags); - switch (params->switch_cfg) { - case SWITCH_CFG_1G: - vars->phy_flags |= PHY_SERDES_FLAG; - if ((params->ext_phy_config & - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) == - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) { - vars->phy_flags |= PHY_SGMII_FLAG; - } - - val = REG_RD(bp, - NIG_REG_SERDES0_CTRL_PHY_ADDR+ - params->port*0x10); - - params->phy_addr = (u8)val; - - break; - case SWITCH_CFG_10G: - vars->phy_flags |= PHY_XGXS_FLAG; - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); - params->phy_addr = (u8)val; - - break; - default: - DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); - return -EINVAL; - } - DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr); - params->phy[INT_PHY].addr = params->phy_addr; bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); @@ -5503,14 +5496,78 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } -static void bnx2x_8726_reset_phy(struct bnx2x *bp, - struct bnx2x_phy *phy) +static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { - DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy\n"); + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); /* Set serial boot control for external load */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, 0x0001); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, 0x0001); +} + +static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* Disable Transmitter */ + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); +} +static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_port; + gpio_port = params->port; + DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); +} +static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + bnx2x_cl45_write(params->bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); + bnx2x_cl45_write(params->bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1); +} + +static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + port); +} + +static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_port; + /* HW reset */ + gpio_port = params->port; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + DP(NETIF_MSG_LINK, "reset external PHY\n"); +} + +static void bnx2x_int_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + /* reset the SerDes/XGXS */ + REG_WR(params->bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_3_CLEAR, + (0x1ff << (params->port*16))); } u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, @@ -5518,12 +5575,8 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, { struct bnx2x *bp = params->bp; - u8 port = params->port; + u8 phy_index, port = params->port; - u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port]. - config)); DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* disable attentions */ vars->link_status = 0; @@ -5554,57 +5607,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /* clear link led */ bnx2x_set_led(params, LED_MODE_OFF, 0); if (reset_ext_phy) { - struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; - switch (phy->type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { - - /* Disable Transmitter */ - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, 0); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - DP(NETIF_MSG_LINK, "Setting 8073 port %d into " - "low power mode\n", - port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - { - /* Set soft reset */ - bnx2x_8726_reset_phy(bp, phy); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - { - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - params->port); - break; - } - default: - /* HW reset */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - DP(NETIF_MSG_LINK, "reset external PHY\n"); + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].link_reset) + params->phy[phy_index].link_reset( + ¶ms->phy[phy_index], + params); } } - /* reset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, - (0x1ff << (port*16))); + if (params->phy[INT_PHY].link_reset) + params->phy[INT_PHY].link_reset( + ¶ms->phy[INT_PHY], params); /* reset BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -5654,7 +5668,7 @@ static u8 bnx2x_update_link_down(struct link_params *params, static u8 bnx2x_update_link_up(struct link_params *params, struct link_vars *vars, - u8 link_10g, u32 gp_status) + u8 link_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -5665,8 +5679,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, bnx2x_bmac_enable(params, vars, 0); bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); } else { - rc = bnx2x_emac_program(params, vars->line_speed, - vars->duplex); + rc = bnx2x_emac_program(params, vars); bnx2x_emac_enable(params, vars, 0); @@ -5689,28 +5702,39 @@ static u8 bnx2x_update_link_up(struct link_params *params, msleep(20); return rc; } -/* This function should called upon link interrupt */ -/* In case vars->link_up, driver needs to - 1. Update the pbf - 2. Disable drain - 3. Update the shared memory - 4. Indicate link up - 5. Set LEDs - Otherwise, - 1. Update shared memory - 2. Reset BigMac - 3. Report link down - 4. Unset LEDs +/** + * The bnx2x_link_update function should be called upon link + * interrupt. + * Link is considered up as follows: + * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs + * to be up + * - SINGLE_MEDIA - The link between the 577xx and the external + * phy (XGXS) need to up as well as the external link of the + * phy (PHY_EXT1) + * - DUAL_MEDIA - The link between the 577xx and the first + * external phy needs to be up, and at least one of the 2 + * external phy link must be up. */ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; + struct link_vars phy_vars[MAX_PHYS]; u8 port = params->port; - u16 gp_status; - u8 link_10g; - u8 ext_phy_link_up, rc = 0; - struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; + u8 link_10g, phy_index; + u8 ext_phy_link_up = 0, cur_link_up, rc = 0; u8 is_mi_int = 0; + u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; + u8 active_external_phy = INT_PHY; + vars->link_status = 0; + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + phy_vars[phy_index].flow_ctrl = 0; + phy_vars[phy_index].link_status = 0; + phy_vars[phy_index].line_speed = 0; + phy_vars[phy_index].duplex = DUPLEX_FULL; + phy_vars[phy_index].phy_link_up = 0; + phy_vars[phy_index].link_up = 0; + } DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", port, (vars->phy_flags & PHY_XGXS_FLAG), @@ -5731,21 +5755,94 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) /* disable emac */ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - /* Check external link change only for non-direct */ - ext_phy_link_up = bnx2x_ext_phy_is_link_up(¶ms->phy[EXT_PHY1], - params, vars, - is_mi_int); + /** + * Step 1: + * Check external link change only for external phys, and apply + * priority selection between them in case the link on both phys + * is up. Note that the instead of the common vars, a temporary + * vars argument is used since each phy may have different link/ + * speed/duplex result + */ + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + struct bnx2x_phy *phy = ¶ms->phy[phy_index]; + if (!phy->read_status) + continue; + /* Read link status and params of this ext phy */ + cur_link_up = phy->read_status(phy, params, + &phy_vars[phy_index]); + if (cur_link_up) { + DP(NETIF_MSG_LINK, "phy in index %d link is up\n", + phy_index); + } else { + DP(NETIF_MSG_LINK, "phy in index %d link is down\n", + phy_index); + continue; + } - /* Read gp_status */ - CL45_RD_OVER_CL22(bp, int_phy, - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); + if (!ext_phy_link_up) { + ext_phy_link_up = 1; + active_external_phy = phy_index; + } + } + prev_line_speed = vars->line_speed; + /** + * Step 2: + * Read the status of the internal phy. In case of + * DIRECT_SINGLE_MEDIA board, this link is the external link, + * otherwise this is the link between the 577xx and the first + * external phy + */ + if (params->phy[INT_PHY].read_status) + params->phy[INT_PHY].read_status( + ¶ms->phy[INT_PHY], + params, vars); + /** + * The INT_PHY flow control reside in the vars. This include the + * case where the speed or flow control are not set to AUTO. + * Otherwise, the active external phy flow control result is set + * to the vars. The ext_phy_line_speed is needed to check if the + * speed is different between the internal phy and external phy. + * This case may be result of intermediate link speed change. + */ + if (active_external_phy > INT_PHY) { + vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; + /** + * Link speed is taken from the XGXS. AN and FC result from + * the external phy. + */ + vars->link_status |= phy_vars[active_external_phy].link_status; + ext_phy_line_speed = phy_vars[active_external_phy].line_speed; + vars->duplex = phy_vars[active_external_phy].duplex; + if (params->phy[active_external_phy].supported & + SUPPORTED_FIBRE) + vars->link_status |= LINK_STATUS_SERDES_LINK; + DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", + active_external_phy); + } + DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," + " ext_phy_line_speed = %d\n", vars->flow_ctrl, + vars->link_status, ext_phy_line_speed); + /** + * Upon link speed change set the NIG into drain mode. Comes to + * deals with possible FIFO glitch due to clk change when speed + * is decreased without link down indicator + */ - rc = bnx2x_link_settings_status(params, vars, gp_status, - ext_phy_link_up); - if (rc != 0) - return rc; + if (vars->phy_link_up) { + if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up && + (ext_phy_line_speed != vars->line_speed)) { + DP(NETIF_MSG_LINK, "Internal link speed %d is" + " different than the external" + " link speed %d\n", vars->line_speed, + ext_phy_line_speed); + vars->phy_link_up = 0; + } else if (prev_line_speed != vars->line_speed) { + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + msleep(1); + } + } /* anything 10 and over uses the bmac */ link_10g = ((vars->line_speed == SPEED_10000) || @@ -5757,31 +5854,469 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); - /* In case external phy link is up, and internal link is down - ( not initialized yet probably after link initialization, it needs - to be initialized. - Note that after link down-up as result of cable plug, - the xgxs link would probably become up again without the need to - initialize it*/ - - if ((int_phy->type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && - (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && - (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) && - (int_phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) && - (int_phy->type && !vars->phy_link_up)) - bnx2x_init_internal_phy(int_phy, params, vars); - - /* link is up only if both local phy and external phy are up */ - vars->link_up = (ext_phy_link_up && vars->phy_link_up); + /** + * In case external phy link is up, and internal link is down + * (not initialized yet probably after link initialization, it + * needs to be initialized. + * Note that after link down-up as result of cable plug, the xgxs + * link would probably become up again without the need + * initialize it + */ + if (!(SINGLE_MEDIA_DIRECT(params))) { + DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," + " init_preceding = %d\n", ext_phy_link_up, + vars->phy_link_up, + params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST); + if (!(params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST) + && ext_phy_link_up && !vars->phy_link_up) { + vars->line_speed = ext_phy_line_speed; + if (vars->line_speed < SPEED_1000) + vars->phy_flags |= PHY_SGMII_FLAG; + else + vars->phy_flags &= ~PHY_SGMII_FLAG; + bnx2x_init_internal_phy(¶ms->phy[INT_PHY], + params, + vars); + } + } + /** + * Link is up only if both local phy and external phy (in case of + * non-direct board) are up + */ + vars->link_up = (vars->phy_link_up && + (ext_phy_link_up || + SINGLE_MEDIA_DIRECT(params))); if (vars->link_up) - rc = bnx2x_update_link_up(params, vars, link_10g, gp_status); + rc = bnx2x_update_link_up(params, vars, link_10g); else rc = bnx2x_update_link_down(params, vars); return rc; } +static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); +} + +static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + u32 swap_val, swap_override; + u8 port; + /** + * The PHY reset is controlled by GPIO 1. Fake the port number + * to cancel the swap done in set_gpio() + */ + struct bnx2x *bp = params->bp; + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + port = (swap_val && swap_override) ^ 1; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); +} + +static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + /* Low power mode is controlled by GPIO 2 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); + /* The PHY reset is controlled by GPIO 1 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); +} +/******************************************************************/ +/* STATIC PHY DECLARATION */ +/******************************************************************/ + +static struct bnx2x_phy phy_null = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, + .addr = 0, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = 0, + .media_type = ETH_PHY_NOT_PRESENT, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)NULL, + .read_status = (read_status_t)NULL, + .link_reset = (link_reset_t)NULL, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_serdes = { + .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .flags = 0, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_init_serdes, + .read_status = (read_status_t)bnx2x_link_settings_status, + .link_reset = (link_reset_t)bnx2x_int_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_xgxs = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .flags = 0, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_init_xgxs, + .read_status = (read_status_t)bnx2x_link_settings_status, + .link_reset = (link_reset_t)bnx2x_int_link_reset, + .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_7101 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_7101_config_init, + .read_status = (read_status_t)bnx2x_7101_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, + .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, + .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, + .set_link_led = (set_link_led_t)NULL +}; +static struct bnx2x_phy phy_8073 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, + .addr = 0xff, + .flags = FLAGS_HW_LOCK_REQUIRED, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8072_8073_config_init, + .read_status = (read_status_t)bnx2x_8073_read_status, + .link_reset = (link_reset_t)bnx2x_8073_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; +static struct bnx2x_phy phy_8705 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, + .addr = 0xff, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_XFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8705_config_init, + .read_status = (read_status_t)bnx2x_8705_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; +static struct bnx2x_phy phy_8706 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, + .addr = 0xff, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8706_config_init, + .read_status = (read_status_t)bnx2x_8706_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_8726 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, + .addr = 0xff, + .flags = (FLAGS_HW_LOCK_REQUIRED | + FLAGS_INIT_XGXS_FIRST), + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8726_config_init, + .read_status = (read_status_t)bnx2x_8726_read_status, + .link_reset = (link_reset_t)bnx2x_8726_link_reset, + .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_8727 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8727_config_init, + .read_status = (read_status_t)bnx2x_8727_read_status, + .link_reset = (link_reset_t)bnx2x_8727_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, + .set_link_led = (set_link_led_t)NULL +}; +static struct bnx2x_phy phy_8481 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8481_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_8481_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, + .set_link_led = (set_link_led_t)NULL +}; + +static struct bnx2x_phy phy_84823 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_848x3_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_848x3_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +/*****************************************************************/ +/* */ +/* Populate the phy according. Main function: bnx2x_populate_phy */ +/* */ +/*****************************************************************/ + +static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, + struct bnx2x_phy *phy, u8 port, + u8 phy_index) +{ + /* Get the 4 lanes xgxs config rx and tx */ + u32 rx = 0, tx = 0, i; + for (i = 0; i < 2; i++) { + /** + * INT_PHY and EXT_PHY1 share the same value location in the + * shmem. When num_phys is greater than 1, than this value + * applies only to EXT_PHY1 + */ + + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + + phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); + phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); + + phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff); + phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff); + } +} + static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, u8 phy_index, u8 port) { @@ -5799,6 +6334,45 @@ static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, return ext_phy_config; } +static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, + struct bnx2x_phy *phy) +{ + u32 phy_addr; + u32 chip_id; + u32 switch_cfg = (REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_feature_config[port].link_config)) & + PORT_FEATURE_CONNECTED_SWITCH_MASK); + chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; + switch (switch_cfg) { + case SWITCH_CFG_1G: + phy_addr = REG_RD(bp, + NIG_REG_SERDES0_CTRL_PHY_ADDR + + port * 0x10); + *phy = phy_serdes; + break; + case SWITCH_CFG_10G: + phy_addr = REG_RD(bp, + NIG_REG_XGXS0_CTRL_PHY_ADDR + + port * 0x18); + *phy = phy_xgxs; + break; + default: + DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); + return -EINVAL; + } + phy->addr = (u8)phy_addr; + phy->mdio_ctrl = bnx2x_get_emac_base(bp, + phy->type, + port); + phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; + + DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", + port, phy->addr, phy->mdio_ctrl); + + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY); + return 0; +} static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, u8 phy_index, @@ -5806,12 +6380,52 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, u8 port, struct bnx2x_phy *phy) { - u32 ext_phy_config; + u32 ext_phy_config, phy_type; ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, phy_index, port); - phy->type = XGXS_EXT_PHY_TYPE(ext_phy_config); + phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + /* Select the phy type */ + switch (phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + *phy = phy_8073; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + *phy = phy_8705; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + *phy = phy_8706; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + *phy = phy_8726; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: + /* BCM8727_NOC => BCM8727 no over current */ + *phy = phy_8727; + phy->flags |= FLAGS_NOC; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + *phy = phy_8727; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + *phy = phy_8481; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + *phy = phy_84823; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + *phy = phy_7101; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + *phy = phy_null; + return -EINVAL; + default: + *phy = phy_null; + return 0; + } + phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port); return 0; } @@ -5820,11 +6434,119 @@ static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, u8 port, struct bnx2x_phy *phy) { u8 status = 0; + phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; + if (phy_index == INT_PHY) + return bnx2x_populate_int_phy(bp, shmem_base, port, phy); status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, port, phy); return status; } +static void bnx2x_phy_def_cfg(struct link_params *params, + struct bnx2x_phy *phy, + u8 actual_phy_idx) +{ + struct bnx2x *bp = params->bp; + u32 link_config; + /* Populate the default phy configuration for MF mode */ + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask)); + + phy->req_duplex = DUPLEX_FULL; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_10M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_10M_FULL: + phy->req_line_speed = SPEED_10; + break; + case PORT_FEATURE_LINK_SPEED_100M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_100M_FULL: + phy->req_line_speed = SPEED_100; + break; + case PORT_FEATURE_LINK_SPEED_1G: + phy->req_line_speed = SPEED_1000; + break; + case PORT_FEATURE_LINK_SPEED_2_5G: + phy->req_line_speed = SPEED_2500; + break; + case PORT_FEATURE_LINK_SPEED_10G_CX4: + phy->req_line_speed = SPEED_10000; + break; + default: + phy->req_line_speed = SPEED_AUTO_NEG; + break; + } + + switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) { + case PORT_FEATURE_FLOW_CONTROL_AUTO: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + break; + case PORT_FEATURE_FLOW_CONTROL_TX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX; + break; + case PORT_FEATURE_FLOW_CONTROL_RX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX; + break; + case PORT_FEATURE_FLOW_CONTROL_BOTH: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + break; + default: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + break; + } +} + +u8 bnx2x_phy_probe(struct link_params *params) +{ + u8 phy_index, actual_phy_idx, link_cfg_idx; + + struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy; + params->num_phys = 0; + DP(NETIF_MSG_LINK, "Begin phy probe\n"); + + for (phy_index = INT_PHY; phy_index < MAX_PHYS; + phy_index++) { + link_cfg_idx = LINK_CONFIG_IDX(phy_index); + actual_phy_idx = phy_index; + + phy = ¶ms->phy[actual_phy_idx]; + if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, + params->port, + phy) != 0) { + params->num_phys = 0; + DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", + phy_index); + for (phy_index = INT_PHY; + phy_index < MAX_PHYS; + phy_index++) + *phy = phy_null; + return -EINVAL; + } + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) + break; + + bnx2x_phy_def_cfg(params, phy, actual_phy_idx); + params->num_phys++; + } + + DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys); + return 0; +} + +u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) +{ + if (phy_idx < params->num_phys) + return params->phy[phy_idx].supported; + return 0; +} + + static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) { struct bnx2x_phy phy[PORT_MAX]; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 9bfe7fa452bc..9717cb1fbad0 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -46,6 +46,15 @@ #define SFP_EEPROM_PART_NO_ADDR 0x28 #define SFP_EEPROM_PART_NO_SIZE 16 #define PWR_FLT_ERR_MSG_LEN 250 + +#define XGXS_EXT_PHY_TYPE(ext_phy_config) \ + ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK) +#define XGXS_EXT_PHY_ADDR(ext_phy_config) \ + (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \ + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT) +#define SERDES_EXT_PHY_TYPE(ext_phy_config) \ + ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) + /* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */ #define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1) /* Single Media board contains single external phy */ @@ -58,6 +67,10 @@ #define MAX_PHYS 2 +/* Same configuration is shared between the XGXS and the first external phy */ +#define LINK_CONFIG_SIZE (MAX_PHYS - 1) +#define LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == INT_PHY) ? \ + 0 : (_phy_idx - 1)) /***********************************************************/ /* bnx2x_phy struct */ /* Defines the required arguments and function per phy */ @@ -66,13 +79,88 @@ struct link_vars; struct link_params; struct bnx2x_phy; +typedef u8 (*config_init_t)(struct bnx2x_phy *phy, struct link_params *params, + struct link_vars *vars); +typedef u8 (*read_status_t)(struct bnx2x_phy *phy, struct link_params *params, + struct link_vars *vars); +typedef void (*link_reset_t)(struct bnx2x_phy *phy, + struct link_params *params); +typedef void (*config_loopback_t)(struct bnx2x_phy *phy, + struct link_params *params); +typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len); +typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params); +typedef void (*set_link_led_t)(struct bnx2x_phy *phy, + struct link_params *params, u8 mode); + struct bnx2x_phy { u32 type; /* Loaded during init */ u8 addr; + u8 flags; + /* Require HW lock */ +#define FLAGS_HW_LOCK_REQUIRED (1<<0) + /* No Over-Current detection */ +#define FLAGS_NOC (1<<1) + /* Fan failure detection required */ +#define FLAGS_FAN_FAILURE_DET_REQ (1<<2) + /* Initialize first the XGXS and only then the phy itself */ +#define FLAGS_INIT_XGXS_FIRST (1<<3) + + u8 def_md_devad; + u8 reserved; + /* preemphasis values for the rx side */ + u16 rx_preemphasis[4]; + + /* preemphasis values for the tx side */ + u16 tx_preemphasis[4]; + + /* EMAC address for access MDIO */ u32 mdio_ctrl; + + u32 supported; + + u32 media_type; +#define ETH_PHY_UNSPECIFIED 0x0 +#define ETH_PHY_SFP_FIBER 0x1 +#define ETH_PHY_XFP_FIBER 0x2 +#define ETH_PHY_DA_TWINAX 0x3 +#define ETH_PHY_BASE_T 0x4 +#define ETH_PHY_NOT_PRESENT 0xff + + /* The address in which version is located*/ + u32 ver_addr; + + u16 req_flow_ctrl; + + u16 req_line_speed; + + u32 speed_cap_mask; + + u16 req_duplex; + u16 rsrv; + /* Called per phy/port init, and it configures LASI, speed, autoneg, + duplex, flow control negotiation, etc. */ + config_init_t config_init; + + /* Called due to interrupt. It determines the link, speed */ + read_status_t read_status; + + /* Called when driver is unloading. Should reset the phy */ + link_reset_t link_reset; + + /* Set the loopback configuration for the phy */ + config_loopback_t config_loopback; + + /* Format the given raw number into str up to len */ + format_fw_ver_t format_fw_ver; + + /* Reset the phy (both ports) */ + hw_reset_t hw_reset; + + /* Set link led mode (on/off/oper)*/ + set_link_led_t set_link_led; }; /* Inputs parameters to the CLC */ @@ -106,38 +194,23 @@ struct link_params { #define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH #define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT - u16 hw_led_mode; /* part of the hw_config read from the shmem */ - - /* phy_addr populated by the phy_init function */ - u8 phy_addr; - /*u8 reserved1;*/ - u32 lane_config; - u32 ext_phy_config; -#define XGXS_EXT_PHY_TYPE(ext_phy_config) \ - ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK) -#define XGXS_EXT_PHY_ADDR(ext_phy_config) \ - (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \ - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT) -#define SERDES_EXT_PHY_TYPE(ext_phy_config) \ - ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) /* Phy register parameter */ u32 chip_id; - u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */ - u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */ - u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) -#define FEATURE_CONFIG_BCM8727_NOC (1<<3) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; /* Will be populated during common init */ u8 num_phys; + u8 rsrv; + u16 hw_led_mode; /* part of the hw_config read from the shmem */ + /* Device pointer passed to all callback functions */ struct bnx2x *bp; }; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 174ed8b4587e..1ecff37bab18 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1960,12 +1960,16 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) static inline void bnx2x_fan_failure(struct bnx2x *bp) { int port = BP_PORT(bp); - + u32 ext_phy_config; /* mark the failure */ - bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + + ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config, - bp->link_params.ext_phy_config); + ext_phy_config); /* log the failure */ netdev_err(bp->dev, "Fan Failure on Network Controller has caused" @@ -1991,7 +1995,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) BNX2X_ERR("SPIO5 hw attention\n"); /* Fan failure attention */ - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + switch (bp->link_params.phy[EXT_PHY1].type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: /* Low power mode is controlled by GPIO 2 */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, @@ -4140,7 +4144,7 @@ static int bnx2x_init_common(struct bnx2x *bp) return -EBUSY; } - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + switch (bp->link_params.phy[EXT_PHY1].type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: @@ -4299,7 +4303,7 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + switch (bp->link_params.phy[EXT_PHY1].type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: { u32 swap_val, swap_override, aeu_gpio_mask, offset; @@ -4480,7 +4484,7 @@ static int bnx2x_init_func(struct bnx2x *bp) /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); - + bnx2x_phy_probe(&bp->link_params); return 0; } @@ -6065,194 +6069,32 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) { int port = BP_PORT(bp); - u32 ext_phy_type; - - switch (switch_cfg) { - case SWITCH_CFG_1G: - BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg); - - ext_phy_type = - SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); + bp->port.supported = 0; + switch (bp->link_params.num_phys) { + case 1: + bp->port.supported = bp->link_params.phy[INT_PHY].supported; break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); + case 2: + bp->port.supported = bp->link_params.phy[EXT_PHY1].supported; break; + } - default: - BNX2X_ERR("NVRAM config error. " - "BAD SerDes ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); + if (!(bp->port.supported)) { + BNX2X_ERR("NVRAM config error. BAD phy config." + "PHY1 config 0x%x\n", + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config)); return; } + switch (switch_cfg) { + case SWITCH_CFG_1G: bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + port*0x10); BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); break; case SWITCH_CFG_10G: - BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg); - - ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM848xx)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; - - default: - BNX2X_ERR("NVRAM config error. " - "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - return; - } - bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + port*0x18); BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); @@ -6264,8 +6106,6 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, bp->port.link_config); return; } - bp->link_params.phy_addr = bp->port.phy_addr; - /* mask what we support according to speed_cap_mask */ if (!(bp->link_params.speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) @@ -6309,25 +6149,10 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->link_params.req_line_speed = SPEED_AUTO_NEG; bp->port.advertising = bp->port.supported; } else { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - - if ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { /* force 10G, no AN */ bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = - (ADVERTISED_10000baseT_Full | + bp->port.advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); - break; - } - BNX2X_ERR("NVRAM config error. " - "Invalid link_config 0x%x" - " Autoneg not supported\n", - bp->port.link_config); - return; } break; @@ -6475,27 +6300,13 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) int port = BP_PORT(bp); u32 val, val2; u32 config; - u16 i; - u32 ext_phy_type; + u32 ext_phy_type, ext_phy_config;; bp->link_params.bp = bp; bp->link_params.port = port; bp->link_params.lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); - bp->link_params.ext_phy_config = - SHMEM_RD(bp, - dev_info.port_hw_config[port].external_phy_config); - /* BCM8727_NOC => BCM8727 no over current */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) { - bp->link_params.ext_phy_config &= - ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727; - bp->link_params.feature_config_flags |= - FEATURE_CONFIG_BCM8727_NOC; - } bp->link_params.speed_cap_mask = SHMEM_RD(bp, @@ -6504,18 +6315,6 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->port.link_config = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - /* Get the 4 lanes xgxs config rx and tx */ - for (i = 0; i < 2; i++) { - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1]); - bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff); - - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1]); - bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff); - } /* If the device is capable of WoL, set the default state according * to the HW @@ -6524,14 +6323,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->wol = (!(bp->flags & NO_WOL_FLAG) && (config & PORT_FEATURE_WOL_ENABLED)); - BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x" + BNX2X_DEV_INFO("lane_config 0x%08x" " speed_cap_mask 0x%08x link_config 0x%08x\n", bp->link_params.lane_config, - bp->link_params.ext_phy_config, bp->link_params.speed_cap_mask, bp->port.link_config); bp->link_params.switch_cfg |= (bp->port.link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK); + bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); bnx2x_link_settings_requested(bp); @@ -6540,14 +6339,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) * If connected directly, work with the internal PHY, otherwise, work * with the external PHY */ - ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - bp->mdio.prtad = bp->link_params.phy_addr; + bp->mdio.prtad = bp->port.phy_addr; else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) bp->mdio.prtad = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); + XGXS_EXT_PHY_ADDR(ext_phy_config); val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); -- cgit v1.2.3 From 62b29a5dd0930e0c956b6740f32d5b3bbaf20136 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:40:58 +0000 Subject: bnx2x: Adjust alignment of split PHY functions In previous patch, common PHY functions were split in simple way to allow easy diff. This patch comes to align code in the new functions. In addition, the non-production BCM8072 PHY was removed. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 2164 +++++++++++++++++----------------------- drivers/net/bnx2x/bnx2x_main.c | 1 - 2 files changed, 894 insertions(+), 1271 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index c1540727cdbf..c2f1e3c24c0b 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -2096,7 +2096,7 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) MISC_REGISTERS_GPIO_OUTPUT_LOW, port); msleep(1); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, @@ -2133,30 +2133,14 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - 0xA819, 0x0014); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0xA81A, - 0xc200); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0xA81B, - 0x0000); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0xA81C, - 0x0300); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0xA817, - 0x0009); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - 0xA818, - &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); if (val & 1) break; udelay(5); @@ -2170,86 +2154,29 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - 0xA819, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - 0xA81A, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - 0xA817, 0x000A); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - 0xA818, - &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); if (val & 1) break; udelay(5); } if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n"); - bnx2x_save_spirom_version(bp, params->port, - shmem_base, 0); + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); return; } /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - 0xA81B, - &fw_ver1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - 0xA81C, - &fw_ver2); - - bnx2x_save_spirom_version(bp, params->port, - shmem_base, (fw_ver2<<16) | fw_ver1); -} - -static void bnx2x_bcm8072_external_rom_boot(struct bnx2x_phy *phy, - struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - - /* Need to wait 200ms after reset */ - msleep(200); - /* Boot port from external ROM - * Set ser_boot_ctl bit in the MISC_CTRL1 register - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* set micro reset = 0 */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* wait for 100ms for code download via SPI port */ - msleep(100); - - /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); - /* Wait 100ms */ - msleep(100); - - bnx2x_save_bcm_spirom_ver(bp, port, - phy, - params->shmem_base); + bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, + phy->ver_addr); } static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) @@ -2382,9 +2309,7 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, /* Micro controller re-boot */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x018B); + MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); /* Set soft reset */ bnx2x_cl45_write(bp, phy, @@ -2614,10 +2539,11 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, *edc_mode = EDC_MODE_LIMITING; /* First check for copper cable */ - if (bnx2x_read_sfp_module_eeprom(phy, params, - SFP_EEPROM_CON_TYPE_ADDR, - 1, - &val) != 0) { + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_CON_TYPE_ADDR, + 1, + &val) != 0) { DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); return -EINVAL; } @@ -2629,7 +2555,8 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, /* Check if its active cable( includes SFP+ module) of passive cable*/ - if (bnx2x_read_sfp_module_eeprom(phy, params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_FC_TX_TECH_ADDR, 1, &copper_module_type) != @@ -2669,10 +2596,11 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, if (check_limiting_mode) { u8 options[SFP_EEPROM_OPTIONS_SIZE]; - if (bnx2x_read_sfp_module_eeprom(phy, params, - SFP_EEPROM_OPTIONS_ADDR, - SFP_EEPROM_OPTIONS_SIZE, - options) != 0) { + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_OPTIONS_ADDR, + SFP_EEPROM_OPTIONS_SIZE, + options) != 0) { DP(NETIF_MSG_LINK, "Failed to read Option" " field from module EEPROM\n"); return -EINVAL; @@ -2720,14 +2648,16 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, } /* format the warning message */ - if (bnx2x_read_sfp_module_eeprom(phy, params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_VENDOR_NAME_ADDR, SFP_EEPROM_VENDOR_NAME_SIZE, (u8 *)vendor_name)) vendor_name[0] = '\0'; else vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; - if (bnx2x_read_sfp_module_eeprom(phy, params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_PART_NO_ADDR, SFP_EEPROM_PART_NO_SIZE, (u8 *)vendor_pn)) @@ -2743,7 +2673,7 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, struct bnx2x_phy *phy, - u16 edc_mode) + u16 edc_mode) { u16 cur_limiting_mode; @@ -2758,9 +2688,9 @@ static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n"); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - EDC_MODE_LIMITING); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + EDC_MODE_LIMITING); } else { /* LRM mode ( default )*/ DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); @@ -2848,7 +2778,6 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, } static void bnx2x_8727_power_module(struct bnx2x *bp, - struct link_params *params, struct bnx2x_phy *phy, u8 is_power_up) { /* Make sure GPIOs are not using for LED mode */ @@ -2880,9 +2809,9 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, val = ((!(is_power_up)) << 1); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_GPIO_CTRL, - val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + val); } static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, @@ -2916,7 +2845,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { /* Shutdown SFP+ module */ DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); - bnx2x_8727_power_module(bp, params, phy, 0); + bnx2x_8727_power_module(bp, phy, 0); return rc; } } else { @@ -2929,7 +2858,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, /* power up the SFP module */ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - bnx2x_8727_power_module(bp, params, phy, 1); + bnx2x_8727_power_module(bp, phy, 1); /* Check and set limiting mode / LRM mode on 8726. On 8727 it is done automatically */ @@ -2984,8 +2913,8 @@ void bnx2x_handle_module_detect_int(struct link_params *params) config)); bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_SET, - port); + MISC_REGISTERS_GPIO_INT_OUTPUT_SET, + port); /* Module was plugged out. */ /* Disable transmit for this module */ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == @@ -2998,21 +2927,13 @@ static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) { /* Force KR or KX */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 0x2040); + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, - 0x000b); + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_BCM_CTRL, - 0x0000); + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, - 0x0000); + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); } static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, @@ -3020,8 +2941,7 @@ static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, { u16 val; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); if (val == 0) { /* Mustn't set low power mode in 8073 A0 */ @@ -3030,47 +2950,32 @@ static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ bnx2x_cl45_read(bp, phy, - MDIO_XS_DEVAD, - MDIO_XS_PLL_SEQUENCER, &val); + MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); val &= ~(1<<13); bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); /* PLL controls */ - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x805E, 0x1077); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x805D, 0x0000); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x805C, 0x030B); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x805B, 0x1240); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x805A, 0x2490); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); /* Tx Controls */ - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80A7, 0x0C74); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80A6, 0x9041); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80A5, 0x4640); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); /* Rx Controls */ - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80FE, 0x01C4); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80FD, 0x9249); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, 0x80FC, 0x2015); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); /* Enable PLL sequencer (use read-modify-write to set bit 13) */ - bnx2x_cl45_read(bp, phy, - MDIO_XS_DEVAD, - MDIO_XS_PLL_SEQUENCER, &val); + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); val |= (1<<13); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); } static void bnx2x_8073_set_pause_cl37(struct link_params *params, @@ -3080,8 +2985,7 @@ static void bnx2x_8073_set_pause_cl37(struct link_params *params, u16 cl37_val; struct bnx2x *bp = params->bp; bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &cl37_val); + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val); cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ @@ -3105,8 +3009,7 @@ static void bnx2x_8073_set_pause_cl37(struct link_params *params, "Ext phy AN advertize cl37 0x%x\n", cl37_val); bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, cl37_val); + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val); msleep(500); } @@ -3117,9 +3020,7 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, u16 val; struct bnx2x *bp = params->bp; /* read modify write pause advertizing */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &val); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; @@ -3133,14 +3034,10 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { - val |= - MDIO_AN_REG_ADV_PAUSE_PAUSE; + val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; } - DP(NETIF_MSG_LINK, - "Ext phy AN advertize 0x%x\n", val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, val); + DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); } static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, @@ -3153,16 +3050,16 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { CL45_WR_OVER_CL22(bp, phy, - bank, - MDIO_RX0_RX_EQ_BOOST, + bank, + MDIO_RX0_RX_EQ_BOOST, phy->rx_preemphasis[i]); } for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { CL45_WR_OVER_CL22(bp, phy, - bank, - MDIO_TX0_TX_DRIVER, + bank, + MDIO_TX0_TX_DRIVER, phy->tx_preemphasis[i]); } } @@ -3257,18 +3154,16 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, struct bnx2x_phy *phy) { u16 cnt, ctrl; - /* Wait for soft reset to get cleared upto 1 sec */ - for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, &ctrl); - if (!(ctrl & (1<<15))) - break; - msleep(1); - } - DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", - ctrl, cnt); - return 0; + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); + return cnt; } static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, @@ -3284,29 +3179,18 @@ static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, "XGXS 8705\n"); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL, - 0x8288); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - 0x7fbf); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CMU_PLL_BYPASS, - 0x0100); - bnx2x_cl45_write(bp, phy, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_CNTL, 0x1); - /* BCM8705 doesn't have microcode, hence the 0 */ - bnx2x_save_spirom_version(bp, params->port, - params->shmem_base, 0); - - return 0; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); + /* BCM8705 doesn't have microcode, hence the 0 */ + bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); + return 0; } static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, @@ -3322,95 +3206,73 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); bnx2x_wait_reset_complete(bp, phy); - /* Wait until fw is loaded */ - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER1, &val); - if (val) - break; - msleep(10); - } - DP(NETIF_MSG_LINK, "XGXS 8706 is initialized " - "after %d ms\n", cnt); - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - u8 i; - u16 reg; - for (i = 0; i < 4; i++) { - reg = MDIO_XS_8706_REG_BANK_RX0 + - i*(MDIO_XS_8706_REG_BANK_RX1 - - MDIO_XS_8706_REG_BANK_RX0); - bnx2x_cl45_read(bp, phy, - MDIO_XS_DEVAD, - reg, &val); - /* Clear first 3 bits of the control */ - val &= ~0x7; - /* Set control bits according to - configuation */ - val |= (phy->rx_preemphasis[i] & - 0x7); - DP(NETIF_MSG_LINK, "Setting RX" - "Equalizer to BCM8706 reg 0x%x" - " <-- val 0x%x\n", reg, val); - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, - reg, val); - } - } - /* Force speed */ - if (params->req_line_speed == SPEED_10000) { - DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_DIGITAL_CTRL, - 0x400); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 1); - } else { - /* Force 1Gbps using autoneg with 1G - advertisment */ - - /* Allow CL37 through CL73 */ - DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_CL73, - 0x040c); - - /* Enable Full-Duplex advertisment on CL37 */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, - 0x0020); - /* Enable CL37 AN */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, - 0x1000); - /* 1G support */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, (1<<5)); - - /* Enable clause 73 AN */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, - 0x1200); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x0400); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x0004); - } - bnx2x_save_bcm_spirom_ver(bp, params->port, - phy, - params->shmem_base); - return 0; + /* Wait until fw is loaded */ + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); + if (val) + break; + msleep(10); + } + DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + u8 i; + u16 reg; + for (i = 0; i < 4; i++) { + reg = MDIO_XS_8706_REG_BANK_RX0 + + i*(MDIO_XS_8706_REG_BANK_RX1 - + MDIO_XS_8706_REG_BANK_RX0); + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); + /* Clear first 3 bits of the control */ + val &= ~0x7; + /* Set control bits according to configuration */ + val |= (phy->rx_preemphasis[i] & 0x7); + DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706" + " reg 0x%x <-- val 0x%x\n", reg, val); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); + } + } + /* Force speed */ + if (phy->req_line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_DIGITAL_CTRL, 0x400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + } else { + /* Force 1Gbps using autoneg with 1G advertisment */ + + /* Allow CL37 through CL73 */ + DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + + /* Enable Full-Duplex advertisment on CL37 */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); + /* Enable CL37 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + /* 1G support */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); + + /* Enable clause 73 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x0400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + 0x0004); + } + bnx2x_save_bcm_spirom_ver(bp, params->port, phy, params->shmem_base); + return 0; } static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, @@ -3429,86 +3291,85 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); bnx2x_wait_reset_complete(bp, phy); - bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); - bnx2x_8726_external_rom_boot(phy, params); - - /* Need to call module detected on initialization since - the module detection triggered by actual module - insertion might occur before driver is loaded, and when - driver is loaded, it reset all registers, including the - transmitter */ - bnx2x_sfp_module_detection(phy, params); + bnx2x_8726_external_rom_boot(phy, params); - /* Set Flow control */ - bnx2x_ext_phy_set_pause(params, phy, vars); - if (params->req_line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x5); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); - } else if ((params->req_line_speed == - SPEED_AUTO_NEG) && - ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, 0x20); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_CL73, 0x040c); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, 0x0020); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1000); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x1200); - - /* Enable RX-ALARM control to receive - interrupt for 1G speed change */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x4); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); - - } else { /* Default 10G. Set only LASI control */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 1); - } + /* Need to call module detected on initialization since + the module detection triggered by actual module + insertion might occur before driver is loaded, and when + driver is loaded, it reset all registers, including the + transmitter */ + bnx2x_sfp_module_detection(phy, params); + + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + /* Set Flow control */ + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + /* Enable RX-ALARM control to receive + interrupt for 1G speed change */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); + + } else { /* Default 10G. Set only LASI control */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + } - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," - "TX_CTRL2 0x%x\n", + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," + "TX_CTRL2 0x%x\n", phy->tx_preemphasis[0], phy->tx_preemphasis[1]); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL1, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL1, phy->tx_preemphasis[0]); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL2, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL2, phy->tx_preemphasis[1]); - } - return 0; + } + return 0; } -static u8 bnx2x_8072_8073_config_init(struct bnx2x_phy *phy, +static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val = 0; + u16 val = 0, tmp1; u8 gpio_port; DP(NETIF_MSG_LINK, "Init 8073\n"); @@ -3520,183 +3381,117 @@ static u8 bnx2x_8072_8073_config_init(struct bnx2x_phy *phy, bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - { - u16 tmp1; - u16 rx_alarm_ctrl_val; - u16 lasi_ctrl_val; - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { - rx_alarm_ctrl_val = 0x400; - lasi_ctrl_val = 0x0004; - } else { - rx_alarm_ctrl_val = (1<<2); - lasi_ctrl_val = 0x0004; - } - - /* enable LASI */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - rx_alarm_ctrl_val); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, - lasi_ctrl_val); - - bnx2x_8073_set_pause_cl37(params, phy, vars); + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) - bnx2x_bcm8072_external_rom_boot(phy, params); - else - /* In case of 8073 with long xaui lines, - don't set the 8073 xaui low power*/ - bnx2x_8073_set_xaui_low_power_mode(bp, phy); + bnx2x_8073_set_pause_cl37(params, phy, vars); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &tmp1); + bnx2x_8073_set_xaui_low_power_mode(bp, phy); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &tmp1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):" - "0x%x\n", tmp1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); - /* If this is forced speed, set to KR or KX - * (all other are not supported) - */ - if (params->loopback_mode == LOOPBACK_EXT) { - bnx2x_807x_force_10G(bp, phy); - DP(NETIF_MSG_LINK, - "Forced speed 10G on 807X\n"); - return 0; - } else { - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_BCM_CTRL, - 0x0002); - } - if (params->req_line_speed != SPEED_AUTO_NEG) { - if (params->req_line_speed == SPEED_10000) { - val = (1<<7); - } else if (params->req_line_speed == - SPEED_2500) { - val = (1<<5); - /* Note that 2.5G works only - when used with 1G advertisment */ - } else - val = (1<<5); - } else { + DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); - val = 0; - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) - val |= (1<<7); - - /* Note that 2.5G works only when - used with 1G advertisment */ - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - val |= (1<<5); - DP(NETIF_MSG_LINK, - "807x autoneg val = 0x%x\n", val); - } + /* Enable CL37 BAM */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, val | 1); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, val); + if (params->loopback_mode == LOOPBACK_EXT) { + bnx2x_807x_force_10G(bp, phy); + DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); + return 0; + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); + } + if (phy->req_line_speed != SPEED_AUTO_NEG) { + if (phy->req_line_speed == SPEED_10000) { + val = (1<<7); + } else if (phy->req_line_speed == SPEED_2500) { + val = (1<<5); + /* Note that 2.5G works only + when used with 1G advertisment */ + } else + val = (1<<5); + } else { + val = 0; + if (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + val |= (1<<7); + + /* Note that 2.5G works only when + used with 1G advertisment */ + if (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | + PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) + val |= (1<<5); + DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); + } - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_2_5G, &tmp1); - - if (((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && - (params->req_line_speed == - SPEED_AUTO_NEG)) || - (params->req_line_speed == - SPEED_2500)) { - u16 phy_ver; - /* Allow 2.5G for A1 and above */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &phy_ver); - DP(NETIF_MSG_LINK, "Add 2.5G\n"); - if (phy_ver > 0) - tmp1 |= 1; - else - tmp1 &= 0xfffe; - } else { - DP(NETIF_MSG_LINK, "Disable 2.5G\n"); - tmp1 &= 0xfffe; - } - - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_2_5G, tmp1); - - /* Add support for CL37 (passive mode) II */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, - &tmp1); + if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && + (phy->req_line_speed == SPEED_AUTO_NEG)) || + (phy->req_line_speed == SPEED_2500)) { + u16 phy_ver; + /* Allow 2.5G for A1 and above */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, + &phy_ver); + DP(NETIF_MSG_LINK, "Add 2.5G\n"); + if (phy_ver > 0) + tmp1 |= 1; + else + tmp1 &= 0xfffe; + } else { + DP(NETIF_MSG_LINK, "Disable 2.5G\n"); + tmp1 &= 0xfffe; + } - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, (tmp1 | - ((params->req_duplex == DUPLEX_FULL) ? - 0x20 : 0x40))); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); + /* Add support for CL37 (passive mode) II */ - /* Add support for CL37 (passive mode) III */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1000); - - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - /* The SNR will improve about 2db by changing - BW and FEE main tap. Rest commands are executed - after link is up*/ - /*Change FFE main cursor to 5 in EDC register*/ - if (bnx2x_8073_is_snr_needed(bp, phy)) - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_EDC_FFE_MAIN, - 0xFB0C); - - /* Enable FEC (Forware Error Correction) - Request in the AN */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV2, &tmp1); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, + (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ? + 0x20 : 0x40))); - tmp1 |= (1<<15); + /* Add support for CL37 (passive mode) III */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV2, tmp1); + /* The SNR will improve about 2db by changing + BW and FEE main tap. Rest commands are executed + after link is up*/ + if (bnx2x_8073_is_snr_needed(bp, phy)) + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, + 0xFB0C); - } + /* Enable FEC (Forware Error Correction) Request in the AN */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); + tmp1 |= (1<<15); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); - bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_ext_phy_set_pause(params, phy, vars); - /* Restart autoneg */ - msleep(500); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x1200); - DP(NETIF_MSG_LINK, "807x Autoneg Restart: " - "Advertise 1G=%x, 10G=%x\n", - ((val & (1<<5)) > 0), - ((val & (1<<7)) > 0)); - return 0; - } + /* Restart autoneg */ + msleep(500); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n", + ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); + return 0; } static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, @@ -3709,143 +3504,120 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ - /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ + bnx2x_wait_reset_complete(bp, phy); + rx_alarm_ctrl_val = (1<<2) | (1<<5) ; + lasi_ctrl_val = 0x0004; - rx_alarm_ctrl_val = (1<<2) | (1<<5) ; - lasi_ctrl_val = 0x0004; - bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); - /* enable LASI */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - rx_alarm_ctrl_val); + DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + rx_alarm_ctrl_val); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, - lasi_ctrl_val); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); - /* Initially configure MOD_ABS to interrupt when - module is presence( bit 8) */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); - /* Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8) | (1<<9)); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + /* Initially configure MOD_ABS to interrupt when + module is presence( bit 8) */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); + /* Set EDC off by setting OPTXLOS signal input to low + (bit 9). + When the EDC is off it locks onto a reference clock and + avoids becoming 'lost'.*/ + mod_abs &= ~((1<<8) | (1<<9)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - /* Make MOD_ABS give interrupt on change */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val |= (1<<12); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - val); - /* Set 8727 GPIOs to input to allow reading from the - 8727 GPIO0 status which reflect SFP+ module - over-current */ + /* Make MOD_ABS give interrupt on change */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val |= (1<<12); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); + /* Set 8727 GPIOs to input to allow reading from the + 8727 GPIO0 status which reflect SFP+ module + over-current */ + + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val &= 0xff8f; /* Reset bits 4-6 */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val &= 0xff8f; /* Reset bits 4-6 */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - val); + bnx2x_8727_power_module(bp, phy, 1); - bnx2x_8727_power_module(bp, params, phy, 1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &tmp1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &tmp1); - - /* Set option 1G speed */ - if (params->req_line_speed == SPEED_1000) { - - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, &tmp1); - DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); - - } else if ((params->req_line_speed == - SPEED_AUTO_NEG) && - ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && - ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8727_MISC_CTRL, 0); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1300); - } else { - /* Since the 8727 has only single reset pin, - need to set the 10G registers although it is - default */ - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8727_MISC_CTRL, - 0x0020); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x0100); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0x0008); - } + /* Set option 1G speed */ + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); + DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); + } else { + /** + * Since the 8727 has only single reset pin, need to set the 10G + * registers although it is default + */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, + 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, + 0x0008); + } - /* Set 2-wire transfer rate of SFP+ module EEPROM - * to 100Khz since some DACs(direct attached cables) do - * not work at 400Khz. - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, - 0xa001); - - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," - "TX_CTRL2 0x%x\n", - phy->tx_preemphasis[0], + + /* Set 2-wire transfer rate of SFP+ module EEPROM + * to 100Khz since some DACs(direct attached cables) do + * not work at 400Khz. + */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, + 0xa001); + + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", + phy->tx_preemphasis[0], phy->tx_preemphasis[1]); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TX_CTRL1, - phy->tx_preemphasis[0]); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TX_CTRL2, - phy->tx_preemphasis[1]); - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, + phy->tx_preemphasis[0]); - return 0; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, + phy->tx_preemphasis[1]); + } + + return 0; } static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, @@ -3861,40 +3633,31 @@ static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, - "Setting the SFX7101 LASI indication\n"); - bnx2x_wait_reset_complete(bp, phy); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x1); - DP(NETIF_MSG_LINK, - "Setting the SFX7101 LED to blink on traffic\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - - bnx2x_ext_phy_set_pause(params, phy, vars); - /* Restart autoneg */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, &val); - val |= 0x200; - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, val); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); + DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - /* Save spirom version */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_VER1, &fw_ver1); + bnx2x_ext_phy_set_pause(params, phy, vars); + /* Restart autoneg */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); + val |= 0x200; + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_VER2, &fw_ver2); + /* Save spirom version */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); - bnx2x_save_spirom_version(params->bp, params->port, - params->shmem_base, - (u32)(fw_ver1<<16 | fw_ver2)); - return 0; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); + bnx2x_save_spirom_version(bp, params->port, + (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); + return 0; } static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, @@ -3902,145 +3665,121 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - { - /* This phy uses the NIG latch mechanism since link - indication arrives through its LED4 and not via - its LASI signal, so we get steady signal - instead of clear on read */ - u16 autoneg_val, an_1000_val, an_10_100_val, temp; - temp = vars->line_speed; - vars->line_speed = SPEED_10000; - bnx2x_wait_reset_complete(bp, phy); - bnx2x_set_autoneg(phy, params, vars, 0); - bnx2x_program_serdes(phy, params, vars); - vars->line_speed = temp; + u16 autoneg_val, an_1000_val, an_10_100_val; + bnx2x_wait_reset_complete(bp, phy); + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, + 1 << NIG_LATCH_BC_ENABLE_MI_INT); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); + bnx2x_8481_set_led(bp, phy); + /* set 1000 speed advertisement */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + &an_1000_val); - bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, - 1 << NIG_LATCH_BC_ENABLE_MI_INT); + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_ADV, + &an_10_100_val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, + &autoneg_val); + /* Disable forced speed */ + autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); + an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); + + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (phy->req_line_speed == SPEED_1000)) { + an_1000_val |= (1<<8); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_1000_val |= (1<<9); + DP(NETIF_MSG_LINK, "Advertising 1G\n"); + } else + an_1000_val &= ~((1<<8) | (1<<9)); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x0000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + an_1000_val); + + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + an_10_100_val |= (1<<7); + /* Enable autoneg and restart autoneg for legacy speeds */ + autoneg_val |= (1<<9 | 1<<12); + + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<8); + DP(NETIF_MSG_LINK, "Advertising 100M\n"); + } + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<6); + DP(NETIF_MSG_LINK, "Advertising 10M\n"); + } - bnx2x_8481_set_led(bp, phy); + /* Only 10/100 are allowed to work in FORCE mode */ + if (phy->req_line_speed == SPEED_100) { + autoneg_val |= (1<<13); + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 100M force\n"); + } + if (phy->req_line_speed == SPEED_10) { + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 10M force\n"); + } - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - &an_1000_val); - bnx2x_ext_phy_set_pause(params, phy, vars); - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - &an_10_100_val); - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_val); - /* Disable forced speed */ - autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | - (1<<13)); - an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); - - if (((params->req_line_speed == SPEED_AUTO_NEG) && - (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || - (params->req_line_speed == SPEED_1000)) { - an_1000_val |= (1<<8); - autoneg_val |= (1<<9 | 1<<12); - if (params->req_duplex == DUPLEX_FULL) - an_1000_val |= (1<<9); - DP(NETIF_MSG_LINK, "Advertising 1G\n"); - } else - an_1000_val &= ~((1<<8) | (1<<9)); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, + an_10_100_val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - an_1000_val); - - /* set 10 speed advertisement */ - if (((params->req_line_speed == SPEED_AUTO_NEG) && - (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { - an_10_100_val |= (1<<7); - /* - * Enable autoneg and restart autoneg for - * legacy speeds - */ - autoneg_val |= (1<<9 | 1<<12); - - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<8); - DP(NETIF_MSG_LINK, "Advertising 100M\n"); - } - /* set 10 speed advertisement */ - if (((params->req_line_speed == SPEED_AUTO_NEG) && - (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { - an_10_100_val |= (1<<5); - autoneg_val |= (1<<9 | 1<<12); - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<6); - DP(NETIF_MSG_LINK, "Advertising 10M\n"); - } + if (phy->req_duplex == DUPLEX_FULL) + autoneg_val |= (1<<8); - /* Only 10/100 are allowed to work in FORCE mode */ - if (params->req_line_speed == SPEED_100) { - autoneg_val |= (1<<13); - /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_AUX_CTRL, - (1<<15 | 1<<9 | 7<<0)); - DP(NETIF_MSG_LINK, "Setting 100M force\n"); - } - if (params->req_line_speed == SPEED_10) { - /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_AUX_CTRL, - (1<<15 | 1<<9 | 7<<0)); - DP(NETIF_MSG_LINK, "Setting 10M force\n"); - } + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - an_10_100_val); + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || + (phy->req_line_speed == SPEED_10000)) { + DP(NETIF_MSG_LINK, "Advertising 10G\n"); + /* Restart autoneg for 10G*/ - if (params->req_duplex == DUPLEX_FULL) - autoneg_val |= (1<<8); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, + 0x3200); + } else if (phy->req_line_speed != SPEED_10 && + phy->req_line_speed != SPEED_100) { + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, + 1); + } + /* Save spirom version */ + bnx2x_save_8481_spirom_version(phy, params, params->shmem_base); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - autoneg_val); - - if (((params->req_line_speed == SPEED_AUTO_NEG) && - (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || - (params->req_line_speed == SPEED_10000)) { - DP(NETIF_MSG_LINK, "Advertising 10G\n"); - /* Restart autoneg for 10G*/ - - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, - 0x3200); - - } else if (params->req_line_speed != SPEED_10 && - params->req_line_speed != SPEED_100) - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, - 1); - - /* Save spirom version */ - bnx2x_save_8481_spirom_version(phy, params, - params->shmem_base); - return 0; - } + return 0; } static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, @@ -4132,16 +3871,16 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, absence of the Rx signal. (bit 9) */ mod_abs |= ((1<<8)|(1<<9)); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Clear RX alarm since it stays up as long as the mod_abs wasn't changed. This is need to be done before calling the module detection, otherwise it will clear the link update alarm */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == @@ -4164,37 +3903,33 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u8 ext_phy_link_up = 0; + u8 link_up = 0; u16 val1, rx_sd; struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_cl45_read(bp, phy, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + DP(NETIF_MSG_LINK, "read status 8705\n"); + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - bnx2x_cl45_read(bp, phy, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_SD, &rx_sd); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); - bnx2x_cl45_read(bp, phy, - 1, - 0xc809, &val1); - bnx2x_cl45_read(bp, phy, - 1, - 0xc809, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); - DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); - ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && - ((val1 & (1<<8)) == 0)); - if (ext_phy_link_up) - vars->line_speed = SPEED_10000; - return ext_phy_link_up; + DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); + link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0)); + if (link_up) { + vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; } static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, @@ -4204,52 +3939,41 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, u8 link_up = 0; u16 val1, val2, rx_sd, pcs_status; struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); - /* Clear RX Alarm*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, - &val2); - /* clear LASI indication*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, - &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, - &val2); - DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->" - "0x%x\n", val1, val2); + DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); + /* Clear RX Alarm*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + /* clear LASI indication*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, - &rx_sd); - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, - &pcs_status); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, - &val2); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, - &val2); - - DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x" - " pcs_status 0x%x 1Gbps link_status 0x%x\n", - rx_sd, pcs_status, val2); - /* link is up if both bit 0 of pmd_rx_sd and - * bit 0 of pcs_status are set, or if the autoneg bit - 1 is set - */ - link_up = ((rx_sd & pcs_status & 0x1) || - (val2 & (1<<1))); - if (link_up) { - if (val2 & (1<<1)) - vars->line_speed = SPEED_1000; - else - vars->line_speed = SPEED_10000; - bnx2x_ext_phy_resolve_fc(phy, params, vars); - return link_up; - } - return 0; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + + DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" + " link_status 0x%x\n", rx_sd, pcs_status, val2); + /* link is up if both bit 0 of pmd_rx_sd and + * bit 0 of pcs_status are set, or if the autoneg bit + * 1 is set + */ + link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); + if (link_up) { + if (val2 & (1<<1)) + vars->line_speed = SPEED_1000; + else + vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; } static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, @@ -4284,312 +4008,217 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; - u8 ext_phy_link_up = 0; - u16 link_status = 0; - u16 rx_alarm_status, val1; - /* Check the LASI */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + u8 link_up = 0; + u16 link_status = 0; + u16 rx_alarm_status, val1; + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, + &rx_alarm_status); + vars->line_speed = 0; + DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); - DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", - rx_alarm_status); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); - DP(NETIF_MSG_LINK, - "8727 LASI status 0x%x\n", - val1); + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &val1); + /** + * If a module is present and there is need to check + * for over current + */ + if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { + /* Check over-current using 8727 GPIO0 input*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, + &val1); + + if ((val1 & (1<<8)) == 0) { + DP(NETIF_MSG_LINK, "8727 Power fault has been detected" + " on port %d\n", params->port); + netdev_err(bp->dev, "Error: Power fault on Port %d has" + " been detected and the power to " + "that SFP+ module has been removed" + " to prevent failure of the card." + " Please remove the SFP+ module and" + " restart the system to clear this" + " error.\n", + params->port); /* - * If a module is present and there is need to check - * for over current + * Disable all RX_ALARMs except for + * mod_abs */ - if (!(phy->flags & FLAGS_NOC) && - !(rx_alarm_status & (1<<5))) { - /* Check over-current using 8727 GPIO0 input*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_GPIO_CTRL, - &val1); - - if ((val1 & (1<<8)) == 0) { - DP(NETIF_MSG_LINK, "8727 Power fault" - " has been detected on " - "port %d\n", - params->port); - netdev_err(bp->dev, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n", - params->port); - /* - * Disable all RX_ALARMs except for - * mod_abs - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - (1<<5)); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - /* Wait for module_absent_event */ - val1 |= (1<<8); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - val1); - /* Clear RX alarm */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, - &rx_alarm_status); - return ext_phy_link_up; - } - } /* Over current check */ - - /* When module absent bit is set, check module */ - if (rx_alarm_status & (1<<5)) { - bnx2x_8727_handle_mod_abs(phy, params); - /* Enable all mod_abs and link detection bits */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - ((1<<5) | (1<<2))); - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); - /* If transmitter is disabled, - ignore false link up indication */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is disabled\n"); - ext_phy_link_up = 0; - return ext_phy_link_up; - } - + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + /* Wait for module_absent_event */ + val1 |= (1<<8); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, val1); + /* Clear RX alarm */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &link_status); - - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ - if ((link_status & (1<<2)) && - (!(link_status & (1<<15)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - } else if ((link_status & (1<<0)) && - (!(link_status & (1<<13)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else { - ext_phy_link_up = 0; - DP(NETIF_MSG_LINK, - "port %x: External link" - " is down\n", params->port); - } - return ext_phy_link_up; + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + return 0; + } + } /* Over current check */ + /* When module absent bit is set, check module */ + if (rx_alarm_status & (1<<5)) { + bnx2x_8727_handle_mod_abs(phy, params); + /* Enable all mod_abs and link detection bits */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + ((1<<5) | (1<<2))); + } + + /* If transmitter is disabled, ignore false link up indication */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + return 0; + } + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); + + /* Bits 0..2 --> speed detected, + bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); + } + if (link_up) + bnx2x_ext_phy_resolve_fc(phy, params, vars); + return link_up; } + static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 ext_phy_link_up = 0; + u8 link_up = 0; u16 val1, val2; - u16 link_status = 0; - u16 an1000_status = 0; + u16 link_status = 0; + u16 an1000_status = 0; - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_LASI_STATUS, &val2); - DP(NETIF_MSG_LINK, - "870x LASI status 0x%x->0x%x\n", - val1, val2); - } else { - /* In 8073, port1 is directed through emac0 and - * port0 is directed through emac1 - */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, - "8703 LASI status 0x%x\n", - val1); + DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); - } - /* clear the interrupt LASI status register */ - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", - val2, val1); - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &val1); + /* clear the interrupt LASI status register */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); - /* Check the LASI */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &val2); + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); - DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); + DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); - /* Check the link status */ - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val2); - DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + /* Check the link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - ext_phy_link_up = ((val1 & 4) == 4); - DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); - if (phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - - if (ext_phy_link_up && - ((params->req_line_speed != - SPEED_10000))) { - if (bnx2x_8073_xaui_wa(bp, phy) - != 0) { - ext_phy_link_up = 0; - return ext_phy_link_up; - } - } - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + link_up = ((val1 & 4) == 4); + DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); - /* Check the link status on 1.1.2 */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," - "an_link_status=0x%x\n", - val2, val1, an1000_status); - - ext_phy_link_up = (((val1 & 4) == 4) || - (an1000_status & (1<<1))); - if (ext_phy_link_up && - bnx2x_8073_is_snr_needed(bp, phy)) { - /* The SNR will improve about 2dbby - changing the BW and FEE main tap.*/ - - /* The 1st write to change FFE main - tap is set before restart AN */ - /* Change PLL Bandwidth in EDC - register */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PLL_BANDWIDTH, - 0x26BC); - - /* Change CDR Bandwidth in EDC - register */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CDR_BANDWIDTH, - 0x0333); - } - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &link_status); - - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ - if ((link_status & (1<<2)) && - (!(link_status & (1<<15)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 10G\n", params->port); - } else if ((link_status & (1<<1)) && - (!(link_status & (1<<14)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_2500; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 2.5G\n", params->port); - } else if ((link_status & (1<<0)) && - (!(link_status & (1<<13)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else { - ext_phy_link_up = 0; - DP(NETIF_MSG_LINK, - "port %x: External link" - " is down\n", params->port); - } - } else { - /* See if 1G link is up for the 8072 */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - if (an1000_status & (1<<1)) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else if (ext_phy_link_up) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 10G\n", params->port); - } - } + if (link_up && + ((phy->req_line_speed != SPEED_10000))) { + if (bnx2x_8073_xaui_wa(bp, phy) != 0) + return 0; + } + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); + + /* Check the link status on 1.1.2 */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," + "an_link_status=0x%x\n", val2, val1, an1000_status); + + link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); + if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { + /* The SNR will improve about 2dbby + changing the BW and FEE main tap.*/ + /* The 1st write to change FFE main + tap is set before restart AN */ + /* Change PLL Bandwidth in EDC + register */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, + 0x26BC); + + /* Change CDR Bandwidth in EDC register */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, + 0x0333); + } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, + &link_status); + + /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", + params->port); + } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { + link_up = 1; + vars->line_speed = SPEED_2500; + DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", + params->port); + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); + } - return ext_phy_link_up; + return link_up; } static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, @@ -4597,42 +4226,33 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 ext_phy_link_up; + u8 link_up; u16 val1, val2; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, - "10G-base-T LASI status 0x%x->0x%x\n", - val2, val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, - "10G-base-T PMA status 0x%x->0x%x\n", - val2, val1); - ext_phy_link_up = ((val1 & 4) == 4); - /* if link is up - * print the AN outcome of the SFX7101 PHY - */ - if (ext_phy_link_up) { - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_MASTER_STATUS, - &val2); - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "SFX7101 AN status 0x%x->Master=%x\n", - val2, - (val2 & (1<<14))); - } - return ext_phy_link_up; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", + val2, val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", + val2, val1); + link_up = ((val1 & 4) == 4); + /* if link is up + * print the AN outcome of the SFX7101 PHY + */ + if (link_up) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, + &val2); + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", + val2, (val2 & (1<<14))); + } + return link_up; } static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, @@ -4640,73 +4260,78 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val1, val2; - u8 ext_phy_link_up = 0; + u16 val, val1, val2; + u8 link_up = 0; - /* Check 10G-BaseT link status */ - /* Check PMD signal ok */ + /* Check 10G-BaseT link status */ + /* Check PMD signal ok */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, 0xFFFA, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, + &val2); + DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); + + /* Check link 10G */ + if (val2 & (1<<11)) { + vars->line_speed = SPEED_10000; + link_up = 1; + } else { /* Check Legacy speed link */ + u16 legacy_status, legacy_speed; + + /* Enable expansion register 0x42 (Operation mode status) */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); + + /* Get legacy speed operation status */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, + &legacy_status); + + DP(NETIF_MSG_LINK, "Legacy speed status" + " = 0x%x\n", legacy_status); + link_up = ((legacy_status & (1<<11)) == (1<<11)); + if (link_up) { + legacy_speed = (legacy_status & (3<<9)); + if (legacy_speed == (0<<9)) + vars->line_speed = SPEED_10; + else if (legacy_speed == (1<<9)) + vars->line_speed = SPEED_100; + else if (legacy_speed == (2<<9)) + vars->line_speed = SPEED_1000; + else /* Should not happen */ + vars->line_speed = 0; + + if (legacy_status & (1<<8)) + vars->duplex = DUPLEX_FULL; + else + vars->duplex = DUPLEX_HALF; + + DP(NETIF_MSG_LINK, "Link is up in %dMbps," + " is_duplex_full= %d\n", vars->line_speed, + (vars->duplex == DUPLEX_FULL)); + + /* Check legacy speed AN resolution */ bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - 0xFFFA, - &val1); + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_STATUS, + &val); + if (val & (1<<5)) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_PMD_SIGNAL, - &val2); - DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2); - - /* Check link 10G */ - if (val2 & (1<<11)) { - vars->line_speed = SPEED_10000; - ext_phy_link_up = 1; - } else { /* Check Legacy speed link */ - u16 legacy_status, legacy_speed; - - /* Enable expansion register 0x42 - (Operation mode status) */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, - 0xf42); - - /* Get legacy speed operation status */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, - &legacy_status); - - DP(NETIF_MSG_LINK, "Legacy speed status" - " = 0x%x\n", legacy_status); - ext_phy_link_up = ((legacy_status & (1<<11)) - == (1<<11)); - if (ext_phy_link_up) { - legacy_speed = (legacy_status & (3<<9)); - if (legacy_speed == (0<<9)) - vars->line_speed = SPEED_10; - else if (legacy_speed == (1<<9)) - vars->line_speed = - SPEED_100; - else if (legacy_speed == (2<<9)) - vars->line_speed = - SPEED_1000; - else /* Should not happen */ - vars->line_speed = 0; - - if (legacy_status & (1<<8)) - vars->duplex = DUPLEX_FULL; - else - vars->duplex = DUPLEX_HALF; - - DP(NETIF_MSG_LINK, "Link is up " - "in %dMbps, is_duplex_full" - "= %d\n", - vars->line_speed, - (vars->duplex == DUPLEX_FULL)); - } - } - return ext_phy_link_up; + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_EXPANSION, + &val); + if ((val & (1<<0)) == 0) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; + } + } + return link_up; } - static void bnx2x_link_int_enable(struct link_params *params) { u8 port = params->port; @@ -4847,7 +4472,6 @@ static void bnx2x_link_int_ack(struct link_params *params, NIG_STATUS_SERDES0_LINK_STATUS); } - } else { /* link_down */ } } @@ -4933,13 +4557,12 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, } static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, - struct link_params *params, - u8 is_10g) + struct link_params *params) { u8 port = params->port; struct bnx2x *bp = params->bp; - if (is_10g) { + if (phy->req_line_speed != SPEED_1000) { u32 md_devad; DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); @@ -5474,7 +5097,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) if (params->phy[phy_index].config_loopback) params->phy[phy_index].config_loopback( ¶ms->phy[phy_index], - params); + params); } } @@ -5714,7 +5337,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, * - DUAL_MEDIA - The link between the 577xx and the first * external phy needs to be up, and at least one of the 2 * external phy link must be up. -*/ + */ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; @@ -6084,7 +5707,7 @@ static struct bnx2x_phy phy_8073 = { .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, - .config_init = (config_init_t)bnx2x_8072_8073_config_init, + .config_init = (config_init_t)bnx2x_8073_config_init, .read_status = (read_status_t)bnx2x_8073_read_status, .link_reset = (link_reset_t)bnx2x_8073_link_reset, .config_loopback = (config_loopback_t)NULL, @@ -6427,6 +6050,7 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port); + return 0; } diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 1ecff37bab18..1184677640e5 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4348,7 +4348,6 @@ static int bnx2x_init_port(struct bnx2x *bp) REG_WR(bp, reg_addr, val); } break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: bp->port.need_hw_lock = 1; break; -- cgit v1.2.3 From 7aa0711f32bf911add9e2ced165f8006864f973e Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:01 +0000 Subject: bnx2x: Adjust flow-control with the new scheme Flow control implementation is split to be done in each PHY function. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 211 ++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 74 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index c2f1e3c24c0b..bb42104b2377 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -171,13 +171,13 @@ #define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ bnx2x_cl45_write(_bp, _phy, \ - DEFAULT_PHY_DEV_ADDR, \ + (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ _val) #define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ bnx2x_cl45_read(_bp, _phy, \ - DEFAULT_PHY_DEV_ADDR, \ + (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ _val) @@ -634,24 +634,22 @@ void bnx2x_link_status_update(struct link_params *params, break; } + vars->flow_ctrl = 0; if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; - else - vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX; if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; - else - vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX; - if (vars->phy_flags & PHY_XGXS_FLAG) { - if (vars->line_speed && - ((vars->line_speed == SPEED_10) || - (vars->line_speed == SPEED_100))) { - vars->phy_flags |= PHY_SGMII_FLAG; - } else { - vars->phy_flags &= ~PHY_SGMII_FLAG; - } + if (!vars->flow_ctrl) + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (vars->line_speed && + ((vars->line_speed == SPEED_10) || + (vars->line_speed == SPEED_100))) { + vars->phy_flags |= PHY_SGMII_FLAG; + } else { + vars->phy_flags &= ~PHY_SGMII_FLAG; } /* anything 10 and over uses the bmac */ @@ -1137,12 +1135,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2); - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; else control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; - DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n", - params->speed_cap_mask, control2); + DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n", + phy->speed_cap_mask, control2); CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, @@ -1261,10 +1259,10 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); - if (params->speed_cap_mask & + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; - if (params->speed_cap_mask & + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; @@ -1299,7 +1297,7 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); - if (params->req_duplex == DUPLEX_FULL) + if (phy->req_duplex == DUPLEX_FULL) reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, @@ -1345,9 +1343,9 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, /* configure the 48 bits for BAM AN */ /* set extended capabilities */ - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) val |= MDIO_OVER_1G_UP1_2_5G; - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= MDIO_OVER_1G_UP1_10G; CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, @@ -1366,7 +1364,7 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, /* resolve pause mode and advertisement * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ - switch (params->req_flow_ctrl) { + switch (phy->req_flow_ctrl) { case BNX2X_FLOW_CTRL_AUTO: if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) { *ieee_fc |= @@ -1511,7 +1509,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, } /* setting the full duplex */ - if (params->req_duplex == DUPLEX_FULL) + if (phy->req_duplex == DUPLEX_FULL) mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; CL45_WR_OVER_CL22(bp, phy, @@ -1551,6 +1549,11 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) default: break; } + if (pause_result & (1<<0)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; + if (pause_result & (1<<1)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; + } static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, @@ -1560,19 +1563,17 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 ld_pause; /* local */ u16 lp_pause; /* link partner */ - u16 an_complete; /* AN complete */ u16 pause_result; u8 ret = 0; /* read twice */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &an_complete); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &an_complete); + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) { + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { ret = 1; bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, @@ -1587,24 +1588,6 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result); bnx2x_pause_resolve(vars, pause_result); - if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE && - phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &ld_pause); - - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, &lp_pause); - pause_result = (ld_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; - pause_result |= (lp_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; - - bnx2x_pause_resolve(vars, pause_result); - DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", - pause_result); - } } return ret; } @@ -1614,6 +1597,8 @@ static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 pd_10g, status2_1000x; + if (phy->req_line_speed != SPEED_AUTO_NEG) + return 0; CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, @@ -1654,10 +1639,12 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; /* resolve from gp_status in case of AN complete and not sgmii */ - if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && - (!(vars->phy_flags & PHY_SGMII_FLAG)) && - (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && + (!(vars->phy_flags & PHY_SGMII_FLAG))) { if (bnx2x_direct_parallel_detect_used(phy, params)) { vars->flow_ctrl = params->req_fc_auto_adv; return; @@ -1701,14 +1688,6 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, pause_result); } bnx2x_pause_resolve(vars, pause_result); - } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - (bnx2x_ext_phy_resolve_fc(phy, params, vars))) { - return; - } else { - if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - vars->flow_ctrl = params->req_fc_auto_adv; - else - vars->flow_ctrl = params->req_flow_ctrl; } DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); } @@ -1776,6 +1755,21 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, bnx2x_restart_autoneg(phy, params, 0); DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); } + +static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u32 gp_status) +{ + if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + + if (bnx2x_direct_parallel_detect_used(phy, params)) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; +} + static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -1789,7 +1783,8 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); - + if (phy->req_line_speed == SPEED_AUTO_NEG) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", gp_status); @@ -1802,8 +1797,12 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, else vars->duplex = DUPLEX_HALF; - bnx2x_flow_ctrl_resolve(¶ms->phy[INT_PHY], - params, vars, gp_status); + if (SINGLE_MEDIA_DIRECT(params)) { + bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); + if (phy->req_line_speed == SPEED_AUTO_NEG) + bnx2x_xgxs_an_resolve(phy, params, vars, + gp_status); + } switch (gp_status & GP_STATUS_SPEED_MASK) { case GP_STATUS_10M: @@ -1910,14 +1909,6 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, LINK_STATUS_PARALLEL_DETECTION_USED; } - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - vars->link_status |= - LINK_STATUS_TX_FLOW_CONTROL_ENABLED; - - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - vars->link_status |= - LINK_STATUS_RX_FLOW_CONTROL_ENABLED; - } else { /* link_down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -3025,7 +3016,7 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { @@ -3821,6 +3812,24 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); return bnx2x_848xx_cmn_config_init(phy, params, vars); } + + +static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 val; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + if (val & (1<<5)) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + if ((val & (1<<0)) == 0) + vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; +} static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, struct link_params *params) { @@ -4114,6 +4123,40 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, return link_up; } +static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + if (phy->req_line_speed == SPEED_10 || + phy->req_line_speed == SPEED_100) { + vars->flow_ctrl = phy->req_flow_ctrl; + return; + } + + if (bnx2x_ext_phy_resolve_fc(phy, params, vars) && + (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) { + u16 pause_result; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LD, &ld_pause); + + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LP, &lp_pause); + pause_result = (ld_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; + pause_result |= (lp_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; + + bnx2x_pause_resolve(vars, pause_result); + DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", + pause_result); + } +} + static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4218,6 +4261,10 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, params->port); } + if (link_up) { + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_8073_resolve_fc(phy, params, vars); + } return link_up; } @@ -4251,6 +4298,8 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, vars->line_speed = SPEED_10000; DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", val2, (val2 & (1<<14))); + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_ext_phy_resolve_fc(phy, params, vars); } return link_up; } @@ -4276,6 +4325,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, if (val2 & (1<<11)) { vars->line_speed = SPEED_10000; link_up = 1; + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); } else { /* Check Legacy speed link */ u16 legacy_status, legacy_speed; @@ -4330,6 +4380,12 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, LINK_STATUS_PARALLEL_DETECTION_USED; } } + if (link_up) { + DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", + vars->line_speed); + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; } static void bnx2x_link_int_enable(struct link_params *params) @@ -5298,6 +5354,13 @@ static u8 bnx2x_update_link_up(struct link_params *params, u8 rc = 0; vars->link_status |= LINK_STATUS_LINK_UP; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + vars->link_status |= + LINK_STATUS_TX_FLOW_CONTROL_ENABLED; + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + vars->link_status |= + LINK_STATUS_RX_FLOW_CONTROL_ENABLED; if (link_10g) { bnx2x_bmac_enable(params, vars, 0); bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); -- cgit v1.2.3 From d90d96baf0cc044bcdedc9ee9e925b5937865673 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:04 +0000 Subject: bnx2x: Move common function into aggregated function Move all PHY specific logic from bnx2x_main into bnx2x_link. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 95 ++++++++++++++++++++++++++++++++++--- drivers/net/bnx2x/bnx2x_link.h | 8 ++++ drivers/net/bnx2x/bnx2x_main.c | 103 +++++------------------------------------ 3 files changed, 108 insertions(+), 98 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index bb42104b2377..72ac8dcf6e20 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -2079,7 +2079,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, return rc; } /*****************************************************************************/ -/* External Phy section */ +/* External Phy section */ /*****************************************************************************/ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) { @@ -3271,6 +3271,8 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; + u32 val; + u32 swap_val, swap_override, aeu_gpio_mask, offset; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, @@ -3351,6 +3353,31 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, MDIO_PMA_REG_8726_TX_CTRL2, phy->tx_preemphasis[1]); } + + /* Set GPIO3 to trigger SFP+ module insertion/removal */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); + + /* The GPIO should be swapped if the swap register is set and active */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + + /* Select function upon port-swap configuration */ + if (params->port == 0) { + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; + } else { + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; + } + val = REG_RD(bp, offset); + /* add GPIO3 to group */ + val |= aeu_gpio_mask; + REG_WR(bp, offset, val); return 0; } @@ -4888,10 +4915,9 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) } static u8 bnx2x_link_initialize(struct link_params *params, - struct link_vars *vars) + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port = params->port; u8 rc = 0; u8 phy_index, non_ext_phy; struct bnx2x_phy *ext_phy = ¶ms->phy[EXT_PHY1]; @@ -4964,10 +4990,13 @@ static u8 bnx2x_link_initialize(struct link_params *params, params, vars); } - bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS)); + /* Reset the interrupt indication after phy was initialized */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + + params->port*4, + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); return rc; } @@ -6515,3 +6544,55 @@ void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) break; } } + +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) +{ + u8 phy_index; + struct bnx2x_phy phy; + for (phy_index = INT_PHY; phy_index < MAX_PHYS; + phy_index++) { + if (bnx2x_populate_phy(bp, phy_index, shmem_base, + 0, &phy) != 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return 0; + } + + if (phy.flags & FLAGS_HW_LOCK_REQUIRED) + return 1; + } + return 0; +} + +u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, + u32 shmem_base, + u8 port) +{ + u8 phy_index, fan_failure_det_req = 0; + struct bnx2x_phy phy; + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + if (bnx2x_populate_phy(bp, phy_index, shmem_base, + port, &phy) + != 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return 0; + } + fan_failure_det_req |= (phy.flags & + FLAGS_FAN_FAILURE_DET_REQ); + } + return fan_failure_det_req; +} + +void bnx2x_hw_reset_phy(struct link_params *params) +{ + u8 phy_index; + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + if (params->phy[phy_index].hw_reset) { + params->phy[phy_index].hw_reset( + ¶ms->phy[phy_index], + params); + params->phy[phy_index] = phy_null; + } + } +} diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 9717cb1fbad0..d663c4f3c265 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -311,8 +311,16 @@ void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy); u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf); + +void bnx2x_hw_reset_phy(struct link_params *params); + +/* Checks if HW lock is required for this phy/board type */ +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base); /* Returns the aggregative supported attributes of the phys on board */ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx); /* Probe the phys on board, and populate them in "params" */ u8 bnx2x_phy_probe(struct link_params *params); +/* Checks if fan failure detection is required on one of the phys on board */ +u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u8 port); + #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 1184677640e5..0210dde760d9 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1981,7 +1981,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) { int port = BP_PORT(bp); int reg_offset; - u32 val, swap_val, swap_override; + u32 val; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); @@ -1995,30 +1995,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) BNX2X_ERR("SPIO5 hw attention\n"); /* Fan failure attention */ - switch (bp->link_params.phy[EXT_PHY1].type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* Low power mode is controlled by GPIO 2 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - /* The PHY reset is controlled by GPIO 1 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* The PHY reset is controlled by GPIO 1 */ - /* fake the port number to cancel the swap done in - set_gpio() */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - port = (swap_val && swap_override) ^ 1; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; - - default: - break; - } + bnx2x_hw_reset_phy(&bp->link_params); bnx2x_fan_failure(bp); } @@ -3867,17 +3844,11 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) */ else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE) for (port = PORT_0; port < PORT_MAX; port++) { - u32 phy_type = - SHMEM_RD(bp, dev_info.port_hw_config[port]. - external_phy_config) & - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; is_required |= - ((phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)); + bnx2x_fan_failure_det_req( + bp, + bp->common.shmem_base, + port); } DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required); @@ -4144,17 +4115,8 @@ static int bnx2x_init_common(struct bnx2x *bp) return -EBUSY; } - switch (bp->link_params.phy[EXT_PHY1].type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - bp->port.need_hw_lock = 1; - break; - - default: - break; - } + bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, + bp->common.shmem_base); bnx2x_setup_fan_failure_detection(bp); @@ -4302,57 +4264,16 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); + bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, + bp->common.shmem_base); - switch (bp->link_params.phy[EXT_PHY1].type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - { - u32 swap_val, swap_override, aeu_gpio_mask, offset; - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, port); - - /* The GPIO should be swapped if the swap register is - set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - - /* Select function upon port-swap configuration */ - if (port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); - } - bp->port.need_hw_lock = 1; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - bp->port.need_hw_lock = 1; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* add SPIO 5 to group 0 */ - { + if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, + port)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, reg_addr); val |= AEU_INPUTS_ATTN_BITS_SPIO5; REG_WR(bp, reg_addr, val); - } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - bp->port.need_hw_lock = 1; - break; - default: - break; } bnx2x__link_reset(bp); -- cgit v1.2.3 From c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfd Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:07 +0000 Subject: bnx2x: Apply logic changes for the new scheme Make the needed changes for the new scheme especially around PHY initialization, and link detection. - The get_emac_base function was changed to enable setting different MAC access setting for each PHY based of external configuration. - As a part of the dual-media preparation, the save_spirom_version was modified to accept a PHY specific version address to be saved in the shmem. This will enable to save more than single spirom version in different locations. - The test_link function was changed also as a preparation for the dual-media upcoming changes - Duplicate initialization logic was removed from the link_setting_status and link_initialize functions Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 331 +++++++++++++++++++---------------------- drivers/net/bnx2x/bnx2x_link.h | 1 + 2 files changed, 155 insertions(+), 177 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 72ac8dcf6e20..fcf99bf62fa1 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -195,24 +195,6 @@ static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); } -static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) -{ - struct bnx2x *bp = params->bp; - - if (phy_flags & PHY_XGXS_FLAG) { - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + - params->port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, - DEFAULT_PHY_DEV_ADDR); - } else { - bnx2x_set_serdes_access(bp, params->port); - - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + - params->port*0x10, - DEFAULT_PHY_DEV_ADDR); - } -} - static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -528,31 +510,46 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, return 0; } -static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags) +static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) { - struct bnx2x *bp = params->bp; u32 val; - if (phy_flags & PHY_XGXS_FLAG) { - DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n"); - val = XGXS_RESET_BITS; + DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); - } else { /* SerDes */ - DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n"); - val = SERDES_RESET_BITS; - } - - val = val << (params->port*16); + val = SERDES_RESET_BITS << (port*16); /* reset and unreset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, - val); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, - val); - bnx2x_set_phy_mdio(params, phy_flags); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); + + bnx2x_set_serdes_access(bp, port); + + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + + port*0x10, + DEFAULT_PHY_DEV_ADDR); } +static void bnx2x_xgxs_deassert(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 port; + u32 val; + DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); + port = params->port; + + val = XGXS_RESET_BITS << (port*16); + + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + udelay(500); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); +} void bnx2x_link_status_update(struct link_params *params, struct link_vars *vars) { @@ -799,25 +796,32 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, return 0; } -static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) +static u32 bnx2x_get_emac_base(struct bnx2x *bp, + u32 mdc_mdio_access, u8 port) { - u32 emac_base; - - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* All MDC/MDIO is directed through single EMAC */ + u32 emac_base = 0; + switch (mdc_mdio_access) { + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE: + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0: + if (REG_RD(bp, NIG_REG_PORT_SWAP)) + emac_base = GRCBASE_EMAC1; + else + emac_base = GRCBASE_EMAC0; + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1: if (REG_RD(bp, NIG_REG_PORT_SWAP)) emac_base = GRCBASE_EMAC0; else emac_base = GRCBASE_EMAC1; break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH: + emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED: emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; break; default: - emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; break; } return emac_base; @@ -1147,7 +1151,7 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, control2); if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (params->speed_cap_mask & + (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "XGXS\n"); @@ -1777,7 +1781,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 new_line_speed , gp_status; u8 rc = 0; - u32 ext_phy_type; + /* Read gp_status */ CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_GP_STATUS, @@ -1885,30 +1889,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, } vars->line_speed = new_line_speed; - vars->link_status |= LINK_STATUS_SERDES_LINK; - ext_phy_type = params->phy[EXT_PHY1].type; - if ((params->req_line_speed == SPEED_AUTO_NEG) && - ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { - vars->autoneg = AUTO_NEG_ENABLED; - - if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { - vars->autoneg |= AUTO_NEG_COMPLETE; - vars->link_status |= - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; - } - vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED; - vars->link_status |= - LINK_STATUS_PARALLEL_DETECTION_USED; - - } } else { /* link_down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -1917,14 +1898,12 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->autoneg = AUTO_NEG_DISABLED; vars->mac_type = MAC_TYPE_NONE; - if ((params->req_line_speed == SPEED_AUTO_NEG) && - (SINGLE_MEDIA_DIRECT(params))) { + if ((phy->req_line_speed == SPEED_AUTO_NEG) && + SINGLE_MEDIA_DIRECT(params)) { /* Check signal is detected */ - bnx2x_check_fallback_to_cl37(¶ms->phy[INT_PHY], - params); + bnx2x_check_fallback_to_cl37(phy, params); } } @@ -2078,6 +2057,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, return rc; } + /*****************************************************************************/ /* External Phy section */ /*****************************************************************************/ @@ -2091,19 +2071,18 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) } static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, - u32 shmem_base, u32 spirom_ver) + u32 spirom_ver, u32 ver_addr) { DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", (u16)(spirom_ver>>16), (u16)spirom_ver, port); - REG_WR(bp, shmem_base + - offsetof(struct shmem_region, - port_mb[port].ext_phy_fw_version), - spirom_ver); + + if (ver_addr) + REG_WR(bp, ver_addr, spirom_ver); } -static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, +static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, struct bnx2x_phy *phy, - u32 shmem_base) + u8 port) { u16 fw_ver1, fw_ver2; @@ -2111,13 +2090,12 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, MDIO_PMA_REG_ROM_VER1, &fw_ver1); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &fw_ver2); - bnx2x_save_spirom_version(bp, port, shmem_base, - (u32)(fw_ver1<<16 | fw_ver2)); + bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), + phy->ver_addr); } -static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, - struct link_params *params, - u32 shmem_base) +static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, + struct link_params *params) { u16 val, fw_ver1, fw_ver2, cnt; struct bnx2x *bp = params->bp; @@ -2137,9 +2115,9 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, udelay(5); } if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n"); - bnx2x_save_spirom_version(bp, params->port, - shmem_base, 0); + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); return; } @@ -2169,7 +2147,6 @@ static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy, bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, phy->ver_addr); } - static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) { /* This is only required for 8073A1, version 102 only */ @@ -2250,7 +2227,7 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 port, u32 shmem_base) + u8 port) { /* Boot port from external ROM */ /* EDC grst */ @@ -2288,7 +2265,7 @@ static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL1, 0x0000); - bnx2x_save_bcm_spirom_ver(bp, port, phy, shmem_base); + bnx2x_save_bcm_spirom_ver(bp, phy, port); } static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, @@ -2326,9 +2303,7 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, MDIO_PMA_REG_MISC_CTRL1, 0x0000); msleep(200); - bnx2x_save_bcm_spirom_ver(bp, params->port, - phy, - params->shmem_base); + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); } static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, @@ -3055,7 +3030,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, } } -static void bnx2x_8481_set_led(struct bnx2x *bp, +static void bnx2x_848xx_set_led(struct bnx2x *bp, struct bnx2x_phy *phy) { u16 val; @@ -3195,7 +3170,6 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); - bnx2x_wait_reset_complete(bp, phy); /* Wait until fw is loaded */ @@ -3262,7 +3236,7 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); } - bnx2x_save_bcm_spirom_ver(bp, params->port, phy, params->shmem_base); + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); return 0; } @@ -3512,6 +3486,7 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, return 0; } + static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -3690,7 +3665,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); - bnx2x_8481_set_led(bp, phy); + bnx2x_848xx_set_led(bp, phy); /* set 1000 speed advertisement */ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, @@ -3795,7 +3770,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, 1); } /* Save spirom version */ - bnx2x_save_8481_spirom_version(phy, params, params->shmem_base); + bnx2x_save_848xx_spirom_version(phy, params); return 0; } @@ -3935,6 +3910,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, module plugged in/out */ } + static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4011,7 +3987,6 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, } return link_up; } - static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4038,6 +4013,7 @@ static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, } return link_up; } + static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4183,7 +4159,6 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, pause_result); } } - static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) @@ -4415,6 +4390,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, return link_up; } + static void bnx2x_link_int_enable(struct link_params *params) { u8 port = params->port; @@ -4616,7 +4592,6 @@ static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) (*len)--; return 0; } - u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, u8 *version, u16 len) { @@ -4706,6 +4681,7 @@ static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); } + /* *------------------------------------------------------------------------ * bnx2x_override_led_value - @@ -4892,7 +4868,7 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 gp_status = 0; + u16 gp_status = 0, phy_index = 0; CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], MDIO_REG_BANK_GP_STATUS, @@ -4902,86 +4878,59 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { u8 ext_phy_link_up = 1; struct link_vars temp_vars; - if (params->phy[EXT_PHY1].read_status) - ext_phy_link_up &= - params->phy[EXT_PHY1].read_status( - ¶ms->phy[EXT_PHY1], + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].read_status) + ext_phy_link_up &= + params->phy[phy_index].read_status( + ¶ms->phy[phy_index], params, &temp_vars); + } if (ext_phy_link_up) return 0; } - return -ESRCH; } static u8 bnx2x_link_initialize(struct link_params *params, struct link_vars *vars) { - struct bnx2x *bp = params->bp; u8 rc = 0; u8 phy_index, non_ext_phy; - struct bnx2x_phy *ext_phy = ¶ms->phy[EXT_PHY1]; - struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; - /* Activate the external PHY */ - - bnx2x_set_aer_mmd(params, int_phy); - - if (vars->phy_flags & PHY_XGXS_FLAG) - bnx2x_set_master_ln(params, int_phy); - - rc = bnx2x_reset_unicore(params, int_phy, - int_phy->type == - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT); - /* reset the SerDes and wait for reset bit return low */ - if (rc != 0) - return rc; - - bnx2x_set_aer_mmd(params, int_phy); - - /* setting the masterLn_def again after the reset */ - if (vars->phy_flags & PHY_XGXS_FLAG) { - bnx2x_set_master_ln(params, int_phy); - bnx2x_set_swap_lanes(params, int_phy); - } + struct bnx2x *bp = params->bp; + /** + * In case of external phy existence, the line speed would be the + * line speed linked up by the external phy. In case it is direct + * only, then the line_speed during initialization will be + * equal to the req_line_speed + */ + vars->line_speed = params->phy[INT_PHY].req_line_speed; - if (vars->phy_flags & PHY_XGXS_FLAG) { - if ((params->req_line_speed && - ((params->req_line_speed == SPEED_100) || - (params->req_line_speed == SPEED_10))) || - (!params->req_line_speed && - (params->speed_cap_mask >= - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && - (params->speed_cap_mask < - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) - )) { - vars->phy_flags |= PHY_SGMII_FLAG; - } else { - vars->phy_flags &= ~PHY_SGMII_FLAG; - } - } - /* In case of external phy existance, the line speed would be the - line speed linked up by the external phy. In case it is direct only, - then the line_speed during initialization will be equal to the - req_line_speed*/ - vars->line_speed = params->req_line_speed; + /** + * Initialize the internal phy in case this is a direct board + * (no external phys), or this board has external phy which requires + * to first. + */ - bnx2x_calc_ieee_aneg_adv(int_phy, params, &vars->ieee_fc); + if (params->phy[INT_PHY].config_init) + params->phy[INT_PHY].config_init( + ¶ms->phy[INT_PHY], + params, vars); /* init ext phy and enable link state int */ - non_ext_phy = ((ext_phy->type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || + non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || (params->loopback_mode == LOOPBACK_XGXS_10)); if (non_ext_phy || - (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || + (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; if (vars->line_speed == SPEED_AUTO_NEG) - bnx2x_set_parallel_detection(int_phy, params); - bnx2x_init_internal_phy(int_phy, params, vars); + bnx2x_set_parallel_detection(phy, params); + bnx2x_init_internal_phy(phy, params, vars); } + /* Init external phy*/ if (!non_ext_phy) for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { @@ -4997,7 +4946,6 @@ static u8 bnx2x_link_initialize(struct link_params *params, NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - return rc; } @@ -5122,7 +5070,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->phy_flags = PHY_XGXS_FLAG; - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); /* set bmac loopback */ bnx2x_bmac_enable(params, vars, 1); @@ -5140,7 +5088,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->phy_flags = PHY_XGXS_FLAG; - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); /* set bmac loopback */ bnx2x_emac_enable(params, vars, 1); bnx2x_emac_program(params, vars); @@ -5161,7 +5109,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) NIG_REG_XGXS0_CTRL_PHY_ADDR+ params->port*0x18); - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); bnx2x_link_initialize(params, vars); vars->mac_type = MAC_TYPE_BMAC; @@ -5194,8 +5142,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) /* No loopback */ { if (params->switch_cfg == SWITCH_CFG_10G) - vars->phy_flags = PHY_XGXS_FLAG; - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); + else + bnx2x_serdes_deassert(bp, params->port); bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); @@ -5282,9 +5231,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u8 phy_index, port = params->port; - DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* disable attentions */ vars->link_status = 0; @@ -5340,7 +5287,6 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, return 0; } - static u8 bnx2x_update_link_down(struct link_params *params, struct link_vars *vars) { @@ -6078,7 +6024,7 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, } phy->addr = (u8)phy_addr; phy->mdio_ctrl = bnx2x_get_emac_base(bp, - phy->type, + SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, port); phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; @@ -6095,14 +6041,15 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, u8 port, struct bnx2x_phy *phy) { - u32 ext_phy_config, phy_type; - + u32 ext_phy_config, phy_type, config2; + u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, phy_index, port); phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); /* Select the phy type */ switch (phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; *phy = phy_8073; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: @@ -6112,14 +6059,17 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, *phy = phy_8706; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; *phy = phy_8726; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: /* BCM8727_NOC => BCM8727 no over current */ + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; *phy = phy_8727; phy->flags |= FLAGS_NOC; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; *phy = phy_8727; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: @@ -6141,8 +6091,36 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); - phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port); + /** + * The shmem address of the phy version is located on different + * structures. In case this structure is too old, do not set + * the address + */ + config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, + dev_info.shared_hw_config.config2)); + + phy->ver_addr = shmem_base + offsetof(struct shmem_region, + port_mb[port].ext_phy_fw_version); + + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) + mdc_mdio_access = config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + + phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); + + /** + * In case mdc/mdio_access of the external phy is different than the + * mdc/mdio access of the XGXS, a HW lock must be taken in each access + * to prevent one port interfere with another port's CL45 operations. + */ + if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) + phy->flags |= FLAGS_HW_LOCK_REQUIRED; + DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", + phy_type, port, phy_index); + DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", + phy->addr, phy->mdio_ctrl); return 0; } @@ -6262,7 +6240,6 @@ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) return 0; } - static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) { struct bnx2x_phy phy[PORT_MAX]; @@ -6314,7 +6291,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) u16 fw_ver1; bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port, shmem_base); + port); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, @@ -6427,7 +6404,7 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) u16 fw_ver1; bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port, shmem_base); + port); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index d663c4f3c265..99e11576c6e4 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -268,6 +268,7 @@ u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, u8 devad, u16 reg, u16 val); + u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, u8 devad, u16 reg, u16 *ret_val); -- cgit v1.2.3 From de6eae1f42eae736548f293570fd867bd37c3bdd Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:13 +0000 Subject: bnx2x: Organize PHY functions Group all PHY specific functions together to have an organized code Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/bnx2x/bnx2x_link.c | 7369 +++++++++++++++++++------------------ drivers/net/bnx2x/bnx2x_link.h | 2 +- drivers/net/bnx2x/bnx2x_main.c | 2 +- 4 files changed, 3711 insertions(+), 3664 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index becfd9eb8905..dbcfa7a5618f 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1282,7 +1282,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* check the loopback mode */ switch (loopback_mode) { case BNX2X_PHY_LOOPBACK: - if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) + if (bp->link_params.loopback_mode != LOOPBACK_XGXS) return -EINVAL; break; case BNX2X_MAC_LOOPBACK: diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index fcf99bf62fa1..e2509aab9f0d 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -181,20 +181,6 @@ (_bank + (_addr & 0xf)), \ _val) -static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) -{ - u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - - /* Set Clause 22 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1); - REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); - udelay(500); - REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); - udelay(500); - /* Set Clause 45 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); -} - static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -510,175 +496,6 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, return 0; } -static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) -{ - u32 val; - - DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); - - val = SERDES_RESET_BITS << (port*16); - - /* reset and unreset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); - udelay(500); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - - bnx2x_set_serdes_access(bp, port); - - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + - port*0x10, - DEFAULT_PHY_DEV_ADDR); -} - -static void bnx2x_xgxs_deassert(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 port; - u32 val; - DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); - port = params->port; - - val = XGXS_RESET_BITS << (port*16); - - /* reset and unreset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); - udelay(500); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + - port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, - params->phy[INT_PHY].def_md_devad); -} -void bnx2x_link_status_update(struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u8 link_10g; - u8 port = params->port; - - if (params->switch_cfg == SWITCH_CFG_1G) - vars->phy_flags = PHY_SERDES_FLAG; - else - vars->phy_flags = PHY_XGXS_FLAG; - vars->link_status = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[port].link_status)); - - vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); - - if (vars->link_up) { - DP(NETIF_MSG_LINK, "phy link up\n"); - - vars->phy_link_up = 1; - vars->duplex = DUPLEX_FULL; - switch (vars->link_status & - LINK_STATUS_SPEED_AND_DUPLEX_MASK) { - case LINK_10THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_10TFD: - vars->line_speed = SPEED_10; - break; - - case LINK_100TXHD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_100T4: - case LINK_100TXFD: - vars->line_speed = SPEED_100; - break; - - case LINK_1000THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_1000TFD: - vars->line_speed = SPEED_1000; - break; - - case LINK_2500THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_2500TFD: - vars->line_speed = SPEED_2500; - break; - - case LINK_10GTFD: - vars->line_speed = SPEED_10000; - break; - - case LINK_12GTFD: - vars->line_speed = SPEED_12000; - break; - - case LINK_12_5GTFD: - vars->line_speed = SPEED_12500; - break; - - case LINK_13GTFD: - vars->line_speed = SPEED_13000; - break; - - case LINK_15GTFD: - vars->line_speed = SPEED_15000; - break; - - case LINK_16GTFD: - vars->line_speed = SPEED_16000; - break; - - default: - break; - } - - vars->flow_ctrl = 0; - if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) - vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; - - if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) - vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; - - if (!vars->flow_ctrl) - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - if (vars->line_speed && - ((vars->line_speed == SPEED_10) || - (vars->line_speed == SPEED_100))) { - vars->phy_flags |= PHY_SGMII_FLAG; - } else { - vars->phy_flags &= ~PHY_SGMII_FLAG; - } - - /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); - if (link_10g) - vars->mac_type = MAC_TYPE_BMAC; - else - vars->mac_type = MAC_TYPE_EMAC; - - } else { /* link down */ - DP(NETIF_MSG_LINK, "phy link down\n"); - - vars->phy_link_up = 0; - - vars->line_speed = 0; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - /* indicate no mac active */ - vars->mac_type = MAC_TYPE_NONE; - } - - DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", - vars->link_status, vars->phy_link_up); - DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", - vars->line_speed, vars->duplex, vars->flow_ctrl); -} static void bnx2x_update_mng(struct link_params *params, u32 link_status) { @@ -1023,63 +840,253 @@ static void bnx2x_set_aer_mmd(struct link_params *params, MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); } -static void bnx2x_set_master_ln(struct link_params *params, - struct bnx2x_phy *phy) -{ - struct bnx2x *bp = params->bp; - u16 new_master_ln, ser_lane; - ser_lane = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); +/******************************************************************/ +/* Internal phy section */ +/******************************************************************/ - /* set the master_ln for AN */ - CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_TEST_MODE_LANE, - &new_master_ln); +static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) +{ + u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2 , - MDIO_XGXS_BLOCK2_TEST_MODE_LANE, - (new_master_ln | ser_lane)); + /* Set Clause 22 */ + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1); + REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); + udelay(500); + REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); + udelay(500); + /* Set Clause 45 */ + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); } -static u8 bnx2x_reset_unicore(struct link_params *params, - struct bnx2x_phy *phy, - u8 set_serdes) +static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) { - struct bnx2x *bp = params->bp; - u16 mii_control; - u16 i; + u32 val; - CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); + DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); - /* reset the unicore */ - CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - (mii_control | - MDIO_COMBO_IEEO_MII_CONTROL_RESET)); - if (set_serdes) - bnx2x_set_serdes_access(bp, params->port); + val = SERDES_RESET_BITS << (port*16); - /* wait for the reset to self clear */ - for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { - udelay(5); + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + udelay(500); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - /* the reset erased the previous bank value */ - CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); + bnx2x_set_serdes_access(bp, port); - if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { - udelay(5); - return 0; - } - } + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + + port*0x10, + DEFAULT_PHY_DEV_ADDR); +} + +static void bnx2x_xgxs_deassert(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 port; + u32 val; + DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); + port = params->port; + + val = XGXS_RESET_BITS << (port*16); + + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + udelay(500); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); +} + +void bnx2x_link_status_update(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 link_10g; + u8 port = params->port; + + if (params->switch_cfg == SWITCH_CFG_1G) + vars->phy_flags = PHY_SERDES_FLAG; + else + vars->phy_flags = PHY_XGXS_FLAG; + vars->link_status = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + port_mb[port].link_status)); + + vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); + + if (vars->link_up) { + DP(NETIF_MSG_LINK, "phy link up\n"); + + vars->phy_link_up = 1; + vars->duplex = DUPLEX_FULL; + switch (vars->link_status & + LINK_STATUS_SPEED_AND_DUPLEX_MASK) { + case LINK_10THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_10TFD: + vars->line_speed = SPEED_10; + break; + + case LINK_100TXHD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_100T4: + case LINK_100TXFD: + vars->line_speed = SPEED_100; + break; + + case LINK_1000THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_1000TFD: + vars->line_speed = SPEED_1000; + break; + + case LINK_2500THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_2500TFD: + vars->line_speed = SPEED_2500; + break; + + case LINK_10GTFD: + vars->line_speed = SPEED_10000; + break; + + case LINK_12GTFD: + vars->line_speed = SPEED_12000; + break; + + case LINK_12_5GTFD: + vars->line_speed = SPEED_12500; + break; + + case LINK_13GTFD: + vars->line_speed = SPEED_13000; + break; + + case LINK_15GTFD: + vars->line_speed = SPEED_15000; + break; + + case LINK_16GTFD: + vars->line_speed = SPEED_16000; + break; + + default: + break; + } + + vars->flow_ctrl = 0; + if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) + vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; + + if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) + vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; + + if (!vars->flow_ctrl) + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (vars->line_speed && + ((vars->line_speed == SPEED_10) || + (vars->line_speed == SPEED_100))) { + vars->phy_flags |= PHY_SGMII_FLAG; + } else { + vars->phy_flags &= ~PHY_SGMII_FLAG; + } + + /* anything 10 and over uses the bmac */ + link_10g = ((vars->line_speed == SPEED_10000) || + (vars->line_speed == SPEED_12000) || + (vars->line_speed == SPEED_12500) || + (vars->line_speed == SPEED_13000) || + (vars->line_speed == SPEED_15000) || + (vars->line_speed == SPEED_16000)); + if (link_10g) + vars->mac_type = MAC_TYPE_BMAC; + else + vars->mac_type = MAC_TYPE_EMAC; + + } else { /* link down */ + DP(NETIF_MSG_LINK, "phy link down\n"); + + vars->phy_link_up = 0; + + vars->line_speed = 0; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + /* indicate no mac active */ + vars->mac_type = MAC_TYPE_NONE; + } + + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", + vars->link_status, vars->phy_link_up); + DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", + vars->line_speed, vars->duplex, vars->flow_ctrl); +} + + +static void bnx2x_set_master_ln(struct link_params *params, + struct bnx2x_phy *phy) +{ + struct bnx2x *bp = params->bp; + u16 new_master_ln, ser_lane; + ser_lane = ((params->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + + /* set the master_ln for AN */ + CL45_RD_OVER_CL22(bp, phy, + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + &new_master_ln); + + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_XGXS_BLOCK2 , + MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + (new_master_ln | ser_lane)); +} + +static u8 bnx2x_reset_unicore(struct link_params *params, + struct bnx2x_phy *phy, + u8 set_serdes) +{ + struct bnx2x *bp = params->bp; + u16 mii_control; + u16 i; + + CL45_RD_OVER_CL22(bp, phy, + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); + + /* reset the unicore */ + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | + MDIO_COMBO_IEEO_MII_CONTROL_RESET)); + if (set_serdes) + bnx2x_set_serdes_access(bp, params->port); + + /* wait for the reset to self clear */ + for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { + udelay(5); + + /* the reset erased the previous bank value */ + CL45_RD_OVER_CL22(bp, phy, + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); + + if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { + udelay(5); + return 0; + } + } DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n"); return -EINVAL; @@ -1271,9 +1278,9 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV2, - reg_val); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV2, + reg_val); /* CL73 Autoneg Enabled */ reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; @@ -1560,42 +1567,6 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) } -static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 ld_pause; /* local */ - u16 lp_pause; /* link partner */ - u16 pause_result; - u8 ret = 0; - /* read twice */ - - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) - vars->flow_ctrl = phy->req_flow_ctrl; - else if (phy->req_line_speed != SPEED_AUTO_NEG) - vars->flow_ctrl = params->req_fc_auto_adv; - else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { - ret = 1; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); - pause_result = (ld_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; - pause_result |= (lp_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; - DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", - pause_result); - bnx2x_pause_resolve(vars, pause_result); - } - return ret; -} - static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, struct link_params *params) { @@ -2004,12 +1975,85 @@ static u8 bnx2x_emac_program(struct link_params *params, return 0; } -static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, + struct link_params *params) { - u8 rc; - vars->phy_flags |= PHY_SGMII_FLAG; + + u16 bank, i = 0; + struct bnx2x *bp = params->bp; + + for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; + bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { + CL45_WR_OVER_CL22(bp, phy, + bank, + MDIO_RX0_RX_EQ_BOOST, + phy->rx_preemphasis[i]); + } + + for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; + bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { + CL45_WR_OVER_CL22(bp, phy, + bank, + MDIO_TX0_TX_DRIVER, + phy->tx_preemphasis[i]); + } +} + +static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || + (params->loopback_mode == LOOPBACK_XGXS)); + if (!(vars->phy_flags & PHY_SGMII_FLAG)) { + if (SINGLE_MEDIA_DIRECT(params) && + (params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) + bnx2x_set_preemphasis(phy, params); + + /* forced speed requested? */ + if (vars->line_speed != SPEED_AUTO_NEG || + (SINGLE_MEDIA_DIRECT(params) && + params->loopback_mode == LOOPBACK_EXT)) { + DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); + + /* disable autoneg */ + bnx2x_set_autoneg(phy, params, vars, 0); + + /* program speed and duplex */ + bnx2x_program_serdes(phy, params, vars); + + } else { /* AN_mode */ + DP(NETIF_MSG_LINK, "not SGMII, AN\n"); + + /* AN enabled */ + bnx2x_set_brcm_cl37_advertisment(phy, params); + + /* program duplex & pause advertisement (for aneg) */ + bnx2x_set_ieee_aneg_advertisment(phy, params, + vars->ieee_fc); + + /* enable autoneg */ + bnx2x_set_autoneg(phy, params, vars, enable_cl73); + + /* enable and restart AN */ + bnx2x_restart_autoneg(phy, params, enable_cl73); + } + + } else { /* SGMII mode */ + DP(NETIF_MSG_LINK, "SGMII\n"); + + bnx2x_initialize_sgmii_process(phy, params, vars); + } +} + +static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 rc; + vars->phy_flags |= PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); bnx2x_set_aer_mmd(params, phy); rc = bnx2x_reset_unicore(params, phy, 1); @@ -2058,864 +2102,1045 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, return rc; } -/*****************************************************************************/ -/* External Phy section */ -/*****************************************************************************/ -void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) +static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, + struct bnx2x_phy *phy) { - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - msleep(1); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); + u16 cnt, ctrl; + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); + return cnt; } -static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, - u32 spirom_ver, u32 ver_addr) +static void bnx2x_link_int_enable(struct link_params *params) { - DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", - (u16)(spirom_ver>>16), (u16)spirom_ver, port); + u8 port = params->port; + u32 mask; + struct bnx2x *bp = params->bp; - if (ver_addr) - REG_WR(bp, ver_addr, spirom_ver); + /* setting the status to report on link up + for either XGXS or SerDes */ + + if (params->switch_cfg == SWITCH_CFG_10G) { + mask = (NIG_MASK_XGXS0_LINK10G | + NIG_MASK_XGXS0_LINK_STATUS); + DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } + + } else { /* SerDes */ + mask = NIG_MASK_SERDES0_LINK_STATUS; + DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } + } + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + mask); + + DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, + (params->switch_cfg == SWITCH_CFG_10G), + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); + DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c)); + DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); } -static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 port) +static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, + u8 is_mi_int) { - u16 fw_ver1, fw_ver2; - - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER1, &fw_ver1); - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, &fw_ver2); - bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), - phy->ver_addr); + u32 latch_status = 0, is_mi_int_status; + /* Disable the MI INT ( external phy int ) + * by writing 1 to the status register. Link down indication + * is high-active-signal, so in this case we need to write the + * status to clear the XOR + */ + /* Read Latched signals */ + latch_status = REG_RD(bp, + NIG_REG_LATCH_STATUS_0 + port*8); + is_mi_int_status = REG_RD(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); + DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," + "latch_status = 0x%x\n", + is_mi_int, is_mi_int_status, latch_status); + /* Handle only those with latched-signal=up.*/ + if (latch_status & 1) { + /* For all latched-signal=up,Write original_signal to status */ + if (is_mi_int) + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + else + bnx2x_bits_dis(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + /* For all latched-signal=up : Re-Arm Latch signals */ + REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, + (latch_status & 0xfffe) | (latch_status & 1)); + } } -static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_link_int_ack(struct link_params *params, + struct link_vars *vars, u8 is_10g, + u8 is_mi_int) { - u16 val, fw_ver1, fw_ver2, cnt; struct bnx2x *bp = params->bp; + u8 port = params->port; - /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ - /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); - - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); - if (val & 1) - break; - udelay(5); - } - if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); - bnx2x_save_spirom_version(bp, params->port, 0, - phy->ver_addr); - return; + /* first reset all status + * we assume only one line will be change at a time */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); + if ((params->phy[EXT_PHY1].type + == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || + (params->phy[EXT_PHY1].type + == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { + bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); } + if (vars->phy_link_up) { + if (is_10g) { + /* Disable the 10G link interrupt + * by writing 1 to the status register + */ + DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + NIG_STATUS_XGXS0_LINK10G); + } else if (params->switch_cfg == SWITCH_CFG_10G) { + /* Disable the link interrupt + * by writing 1 to the relevant lane + * in the status register + */ + u32 ser_lane = ((params->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); - if (val & 1) - break; - udelay(5); - } - if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); - bnx2x_save_spirom_version(bp, params->port, 0, - phy->ver_addr); - return; - } - - /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); - /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); - - bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, - phy->ver_addr); -} -static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) -{ - /* This is only required for 8073A1, version 102 only */ - u16 val; + DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", + vars->line_speed); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + ((1 << ser_lane) << + NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); - /* Read 8073 HW revision*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); + } else { /* SerDes */ + DP(NETIF_MSG_LINK, "SerDes phy link up\n"); + /* Disable the link interrupt + * by writing 1 to the status register + */ + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + NIG_STATUS_SERDES0_LINK_STATUS); + } - if (val != 1) { - /* No need to workaround in 8073 A1 */ - return 0; } - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, &val); - - /* SNR should be applied only for version 0x102 */ - if (val != 0x102) - return 0; - - return 1; } -static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) -{ - u16 val, cnt, cnt1 ; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); - - if (val > 0) { - /* No need to workaround in 8073 A1 */ - return 0; +static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) +{ + u8 *str_ptr = str; + u32 mask = 0xf0000000; + u8 shift = 8*4; + u8 digit; + if (*len < 10) { + /* Need more than 10chars for this format */ + *str_ptr = '\0'; + return -EINVAL; } - /* XAUI workaround in 8073 A0: */ - - /* After loading the boot ROM and restarting Autoneg, - poll Dev1, Reg $C820: */ + while (shift > 0) { - for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &val); - /* If bit [14] = 0 or bit [13] = 0, continue on with - system initialization (XAUI work-around not required, - as these bits indicate 2.5G or 1G link up). */ - if (!(val & (1<<14)) || !(val & (1<<13))) { - DP(NETIF_MSG_LINK, "XAUI work-around not required\n"); - return 0; - } else if (!(val & (1<<15))) { - DP(NETIF_MSG_LINK, "clc bit 15 went off\n"); - /* If bit 15 is 0, then poll Dev1, Reg $C841 until - it's MSB (bit 15) goes to 1 (indicating that the - XAUI workaround has completed), - then continue on with system initialization.*/ - for (cnt1 = 0; cnt1 < 1000; cnt1++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_XAUI_WA, &val); - if (val & (1<<15)) { - DP(NETIF_MSG_LINK, - "XAUI workaround has completed\n"); - return 0; - } - msleep(3); - } - break; + shift -= 4; + digit = ((num & mask) >> shift); + if (digit < 0xa) + *str_ptr = digit + '0'; + else + *str_ptr = digit - 0xa + 'a'; + str_ptr++; + mask = mask >> 4; + if (shift == 4*4) { + *str_ptr = ':'; + str_ptr++; } - msleep(3); } - DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n"); - return -EINVAL; + *str_ptr = '\0'; + return 0; } -static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 port) +static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) { - /* Boot port from external ROM */ - /* EDC grst */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x0001); - - /* ucode reboot and rst */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x008c); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); - - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + str[0] = '\0'; + (*len)--; + return 0; +} - /* Release srst bit */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); +u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, + u8 *version, u16 len) +{ + struct bnx2x *bp; + u32 spirom_ver = 0; + u8 status = 0; + u8 *ver_p = version; + if (version == NULL || params == NULL) + return -EINVAL; + bp = params->bp; - /* wait for 120ms for code download via SPI port */ - msleep(120); + /* Extract first external phy*/ + version[0] = '\0'; + spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); - /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); - bnx2x_save_bcm_spirom_ver(bp, phy, port); + if (params->phy[EXT_PHY1].format_fw_ver) + status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, + ver_p, + &len); + return status; } -static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, + struct link_params *params) { + u8 port = params->port; struct bnx2x *bp = params->bp; - /* Need to wait 100ms after reset */ - msleep(100); - /* Micro controller re-boot */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); + if (phy->req_line_speed != SPEED_1000) { + u32 md_devad; - /* Set soft reset */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + /* change the uni_phy_addr in the nig */ + md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + + port*0x18)); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); - /* wait for 150ms for microcode load */ - msleep(150); + bnx2x_cl45_write(bp, phy, + 5, + (MDIO_REG_BANK_AER_BLOCK + + (MDIO_AER_BLOCK_AER_REG & 0xf)), + 0x2800); - /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); + bnx2x_cl45_write(bp, phy, + 5, + (MDIO_REG_BANK_CL73_IEEEB0 + + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), + 0x6041); + msleep(200); + /* set aer mmd back */ + bnx2x_set_aer_mmd(params, phy); - msleep(200); - bnx2x_save_bcm_spirom_ver(bp, phy, params->port); + /* and md_devad */ + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + md_devad); + + } else { + u16 mii_ctrl; + DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); + bnx2x_cl45_read(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + &mii_ctrl); + bnx2x_cl45_write(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + mii_ctrl | + MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK); + } } -static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 port, - u8 tx_en) +/* + *------------------------------------------------------------------------ + * bnx2x_override_led_value - + * + * Override the led value of the requested led + * + *------------------------------------------------------------------------ + */ +u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, + u32 led_idx, u32 value) { - u16 val; + u32 reg_val; - DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", - tx_en, port); - /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val); + /* If port 0 then use EMAC0, else use EMAC1*/ + u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - if (tx_en) - val &= ~(1<<15); - else - val |= (1<<15); + DP(NETIF_MSG_LINK, + "bnx2x_override_led_value() port %x led_idx %d value %d\n", + port, led_idx, value); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - val); + switch (led_idx) { + case 0: /* 10MB led */ + /* Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 10M_OVERRIDE bit, + otherwise reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : + (reg_val & ~EMAC_LED_10MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 1: /*100MB led */ + /*Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 100M_OVERRIDE bit, + otherwise reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : + (reg_val & ~EMAC_LED_100MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 2: /* 1000MB led */ + /* Read the current value of the LED register in the + EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 1000M_OVERRIDE bit, otherwise + reset it. */ + reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : + (reg_val & ~EMAC_LED_1000MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 3: /* 2500MB led */ + /* Read the current value of the LED register in the + EMAC block*/ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 2500M_OVERRIDE bit, otherwise + reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : + (reg_val & ~EMAC_LED_2500MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 4: /*10G led */ + if (port == 0) { + REG_WR(bp, NIG_REG_LED_10G_P0, + value); + } else { + REG_WR(bp, NIG_REG_LED_10G_P1, + value); + } + break; + case 5: /* TRAFFIC led */ + /* Find if the traffic control is via BMAC or EMAC */ + if (port == 0) + reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN); + else + reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN); + + /* Override the traffic led in the EMAC:*/ + if (reg_val == 1) { + /* Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + + EMAC_REG_EMAC_LED); + /* Set the TRAFFIC_OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the TRAFFIC bit, otherwise + reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) : + (reg_val & ~EMAC_LED_TRAFFIC); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + } else { /* Override the traffic led in the BMAC: */ + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 1); + REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, + value); + } + break; + default: + DP(NETIF_MSG_LINK, + "bnx2x_override_led_value() unknown led index %d " + "(should be 0-5)\n", led_idx); + return -EINVAL; + } + + return 0; } -static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) +u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) { + u8 port = params->port; + u16 hw_led_mode = params->hw_led_mode; + u8 rc = 0; + u32 tmp; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; struct bnx2x *bp = params->bp; - u16 val = 0; - u16 i; - if (byte_cnt > 16) { - DP(NETIF_MSG_LINK, "Reading from eeprom is" - " is limited to 0xf\n"); - return -EINVAL; - } - /* Set the read command byte count */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, - (byte_cnt | 0xa000)); + DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); + DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", + speed, hw_led_mode); + switch (mode) { + case LED_MODE_OFF: + REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, + SHARED_HW_CFG_LED_MAC1); - /* Set the read command address */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, - addr); + tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); + EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); + break; - /* Activate read command */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - 0x2c0f); + case LED_MODE_OPER: + if (SINGLE_MEDIA_DIRECT(params)) { + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); + REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); + } else { + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, + hw_led_mode); + } - /* Wait up to 500us for command complete status */ - for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) - break; - udelay(5); - } + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 0); + /* Set blinking rate to ~15.9Hz */ + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, + LED_BLINK_RATE_VAL); + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + + port*4, 1); + tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); + EMAC_WR(bp, EMAC_REG_EMAC_LED, + (tmp & (~EMAC_LED_OVERRIDE))); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { - DP(NETIF_MSG_LINK, - "Got bad status 0x%x when reading from SFP+ EEPROM\n", - (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); - return -EINVAL; - } + if (CHIP_IS_E1(bp) && + ((speed == SPEED_2500) || + (speed == SPEED_1000) || + (speed == SPEED_100) || + (speed == SPEED_10))) { + /* On Everest 1 Ax chip versions for speeds less than + 10G LED scheme is different */ + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 1); + REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + + port*4, 0); + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + + port*4, 1); + } + break; - /* Read the buffer */ - for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); - o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); + default: + rc = -EINVAL; + DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", + mode); + break; } + return rc; - for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0; - msleep(1); - } - return -EINVAL; } -static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) +u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val, i; + u16 gp_status = 0, phy_index = 0; - if (byte_cnt > 16) { - DP(NETIF_MSG_LINK, "Reading from eeprom is" - " is limited to 0xf\n"); - return -EINVAL; + CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + /* link is up only if both local phy and external phy are up */ + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { + u8 ext_phy_link_up = 1; + struct link_vars temp_vars; + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].read_status) + ext_phy_link_up &= + params->phy[phy_index].read_status( + ¶ms->phy[phy_index], + params, &temp_vars); + } + if (ext_phy_link_up) + return 0; } + return -ESRCH; +} - /* Need to read from 1.8000 to clear it */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - &val); - - /* Set the read command byte count */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, - ((byte_cnt < 2) ? 2 : byte_cnt)); +static u8 bnx2x_link_initialize(struct link_params *params, + struct link_vars *vars) +{ + u8 rc = 0; + u8 phy_index, non_ext_phy; + struct bnx2x *bp = params->bp; + /** + * In case of external phy existence, the line speed would be the + * line speed linked up by the external phy. In case it is direct + * only, then the line_speed during initialization will be + * equal to the req_line_speed + */ + vars->line_speed = params->phy[INT_PHY].req_line_speed; - /* Set the read command address */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, - addr); - /* Set the destination address */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0x8004, - MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); + /** + * Initialize the internal phy in case this is a direct board + * (no external phys), or this board has external phy which requires + * to first. + */ - /* Activate read command */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - 0x8002); - /* Wait appropriate time for two-wire command to finish before - polling the status register */ - msleep(1); + if (params->phy[INT_PHY].config_init) + params->phy[INT_PHY].config_init( + ¶ms->phy[INT_PHY], + params, vars); - /* Wait up to 500us for command complete status */ - for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) - break; - udelay(5); - } + /* init ext phy and enable link state int */ + non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || + (params->loopback_mode == LOOPBACK_XGXS)); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { - DP(NETIF_MSG_LINK, - "Got bad status 0x%x when reading from SFP+ EEPROM\n", - (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); - return -EINVAL; + if (non_ext_phy || + (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || + (params->loopback_mode == LOOPBACK_EXT_PHY)) { + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; + if (vars->line_speed == SPEED_AUTO_NEG) + bnx2x_set_parallel_detection(phy, params); + bnx2x_init_internal_phy(phy, params, vars); } - /* Read the buffer */ - for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); - o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); - } + /* Init external phy*/ + if (!non_ext_phy) + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + params->phy[phy_index].config_init( + ¶ms->phy[phy_index], + params, vars); + } - for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); - if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == - MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; - msleep(1); - } + /* Reset the interrupt indication after phy was initialized */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + + params->port*4, + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); + return rc; +} - return -EINVAL; +static void bnx2x_int_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + /* reset the SerDes/XGXS */ + REG_WR(params->bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_3_CLEAR, + (0x1ff << (params->port*16))); } -u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, u16 addr, - u8 byte_cnt, u8 *o_buf) +static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); - else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); - return -EINVAL; + struct bnx2x *bp = params->bp; + u8 gpio_port; + /* HW reset */ + gpio_port = params->port; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + DP(NETIF_MSG_LINK, "reset external PHY\n"); } -static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, - struct link_params *params, - u16 *edc_mode) +static u8 bnx2x_update_link_down(struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 val, check_limiting_mode = 0; - *edc_mode = EDC_MODE_LIMITING; + u8 port = params->port; - /* First check for copper cable */ - if (bnx2x_read_sfp_module_eeprom(phy, - params, - SFP_EEPROM_CON_TYPE_ADDR, - 1, - &val) != 0) { - DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); - return -EINVAL; - } + DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); + bnx2x_set_led(params, LED_MODE_OFF, 0); - switch (val) { - case SFP_EEPROM_CON_TYPE_VAL_COPPER: - { - u8 copper_module_type; + /* indicate no mac active */ + vars->mac_type = MAC_TYPE_NONE; - /* Check if its active cable( includes SFP+ module) - of passive cable*/ - if (bnx2x_read_sfp_module_eeprom(phy, - params, - SFP_EEPROM_FC_TX_TECH_ADDR, - 1, - &copper_module_type) != - 0) { - DP(NETIF_MSG_LINK, - "Failed to read copper-cable-type" - " from SFP+ EEPROM\n"); - return -EINVAL; - } + /* update shared memory */ + vars->link_status = 0; + vars->line_speed = 0; + bnx2x_update_mng(params, vars->link_status); - if (copper_module_type & - SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { - DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); - check_limiting_mode = 1; - } else if (copper_module_type & - SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { - DP(NETIF_MSG_LINK, "Passive Copper" - " cable detected\n"); - *edc_mode = - EDC_MODE_PASSIVE_DAC; - } else { - DP(NETIF_MSG_LINK, "Unknown copper-cable-" - "type 0x%x !!!\n", copper_module_type); - return -EINVAL; - } - break; - } - case SFP_EEPROM_CON_TYPE_VAL_LC: - DP(NETIF_MSG_LINK, "Optic module detected\n"); - check_limiting_mode = 1; - break; - default: - DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", - val); - return -EINVAL; - } + /* activate nig drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - if (check_limiting_mode) { - u8 options[SFP_EEPROM_OPTIONS_SIZE]; - if (bnx2x_read_sfp_module_eeprom(phy, - params, - SFP_EEPROM_OPTIONS_ADDR, - SFP_EEPROM_OPTIONS_SIZE, - options) != 0) { - DP(NETIF_MSG_LINK, "Failed to read Option" - " field from module EEPROM\n"); - return -EINVAL; - } - if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK)) - *edc_mode = EDC_MODE_LINEAR; - else - *edc_mode = EDC_MODE_LIMITING; - } - DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + + /* reset BigMac */ + bnx2x_bmac_rx_disable(bp, params->port); + REG_WR(bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); return 0; } -/* This function read the relevant field from the module ( SFP+ ), - and verify it is compliant with this board */ -static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, - struct link_params *params) + +static u8 bnx2x_update_link_up(struct link_params *params, + struct link_vars *vars, + u8 link_10g) { struct bnx2x *bp = params->bp; - u32 val; - u32 fw_resp; - char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; - char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; + u8 port = params->port; + u8 rc = 0; - val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port].config)); - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) { - DP(NETIF_MSG_LINK, "NOT enforcing module verification\n"); - return 0; - } - - /* Ask the FW to validate the module */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { - DP(NETIF_MSG_LINK, "FW does not support OPT MDL " - "verification\n"); - return -EINVAL; - } - - fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); - if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { - DP(NETIF_MSG_LINK, "Approved module\n"); - return 0; - } - - /* format the warning message */ - if (bnx2x_read_sfp_module_eeprom(phy, - params, - SFP_EEPROM_VENDOR_NAME_ADDR, - SFP_EEPROM_VENDOR_NAME_SIZE, - (u8 *)vendor_name)) - vendor_name[0] = '\0'; - else - vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; - if (bnx2x_read_sfp_module_eeprom(phy, - params, - SFP_EEPROM_PART_NO_ADDR, - SFP_EEPROM_PART_NO_SIZE, - (u8 *)vendor_pn)) - vendor_pn[0] = '\0'; - else - vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; - - netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," - " Port %d from %s part number %s\n", - params->port, vendor_name, vendor_pn); - return -EINVAL; -} + vars->link_status |= LINK_STATUS_LINK_UP; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + vars->link_status |= + LINK_STATUS_TX_FLOW_CONTROL_ENABLED; -static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, - struct bnx2x_phy *phy, - u16 edc_mode) -{ - u16 cur_limiting_mode; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + vars->link_status |= + LINK_STATUS_RX_FLOW_CONTROL_ENABLED; + if (link_10g) { + bnx2x_bmac_enable(params, vars, 0); + bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); + } else { + rc = bnx2x_emac_program(params, vars); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - &cur_limiting_mode); - DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", - cur_limiting_mode); + bnx2x_emac_enable(params, vars, 0); - if (edc_mode == EDC_MODE_LIMITING) { - DP(NETIF_MSG_LINK, - "Setting LIMITING MODE\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - EDC_MODE_LIMITING); - } else { /* LRM mode ( default )*/ + /* AN complete? */ + if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) + && (!(vars->phy_flags & PHY_SGMII_FLAG)) && + SINGLE_MEDIA_DIRECT(params)) + bnx2x_set_gmii_tx_driver(params); + } - DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); + /* PBF - link up */ + rc |= bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); - /* Changing to LRM mode takes quite few seconds. - So do it only if current mode is limiting - ( default is LRM )*/ - if (cur_limiting_mode != EDC_MODE_LIMITING) - return 0; + /* disable drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LRM_MODE, - 0); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - 0x128); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL0, - 0x4008); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LRM_MODE, - 0xaaaa); - } - return 0; + /* update shared memory */ + bnx2x_update_mng(params, vars->link_status); + msleep(20); + return rc; } - -static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, - struct bnx2x_phy *phy, - u16 edc_mode) +/** + * The bnx2x_link_update function should be called upon link + * interrupt. + * Link is considered up as follows: + * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs + * to be up + * - SINGLE_MEDIA - The link between the 577xx and the external + * phy (XGXS) need to up as well as the external link of the + * phy (PHY_EXT1) + * - DUAL_MEDIA - The link between the 577xx and the first + * external phy needs to be up, and at least one of the 2 + * external phy link must be up. + */ +u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) { - u16 phy_identifier; - u16 rom_ver2_val; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &phy_identifier); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - (phy_identifier & ~(1<<9))); + struct bnx2x *bp = params->bp; + struct link_vars phy_vars[MAX_PHYS]; + u8 port = params->port; + u8 link_10g, phy_index; + u8 ext_phy_link_up = 0, cur_link_up, rc = 0; + u8 is_mi_int = 0; + u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; + u8 active_external_phy = INT_PHY; + vars->link_status = 0; + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + phy_vars[phy_index].flow_ctrl = 0; + phy_vars[phy_index].link_status = 0; + phy_vars[phy_index].line_speed = 0; + phy_vars[phy_index].duplex = DUPLEX_FULL; + phy_vars[phy_index].phy_link_up = 0; + phy_vars[phy_index].link_up = 0; + } - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - &rom_ver2_val); - /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); + DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", + port, (vars->phy_flags & PHY_XGXS_FLAG), + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - (phy_identifier | (1<<9))); + is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + + port*0x18) > 0); + DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + is_mi_int, + REG_RD(bp, + NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); - return 0; -} + DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); -static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, - struct link_params *params) + /** + * Step 1: + * Check external link change only for external phys, and apply + * priority selection between them in case the link on both phys + * is up. Note that the instead of the common vars, a temporary + * vars argument is used since each phy may have different link/ + * speed/duplex result + */ + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + struct bnx2x_phy *phy = ¶ms->phy[phy_index]; + if (!phy->read_status) + continue; + /* Read link status and params of this ext phy */ + cur_link_up = phy->read_status(phy, params, + &phy_vars[phy_index]); + if (cur_link_up) { + DP(NETIF_MSG_LINK, "phy in index %d link is up\n", + phy_index); + } else { + DP(NETIF_MSG_LINK, "phy in index %d link is down\n", + phy_index); + continue; + } -{ - u8 val; - struct bnx2x *bp = params->bp; - u16 timeout; - /* Initialization time after hot-plug may take up to 300ms for some - phys type ( e.g. JDSU ) */ - for (timeout = 0; timeout < 60; timeout++) { - if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) - == 0) { - DP(NETIF_MSG_LINK, "SFP+ module initialization " - "took %d ms\n", timeout * 5); - return 0; + if (!ext_phy_link_up) { + ext_phy_link_up = 1; + active_external_phy = phy_index; } - msleep(5); } - return -EINVAL; -} - -static void bnx2x_8727_power_module(struct bnx2x *bp, - struct bnx2x_phy *phy, - u8 is_power_up) { - /* Make sure GPIOs are not using for LED mode */ - u16 val; - /* - * In the GPIO register, bit 4 is use to detemine if the GPIOs are - * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for - * output - * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 - * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 - * where the 1st bit is the over-current(only input), and 2nd bit is - * for power( only output ) + prev_line_speed = vars->line_speed; + /** + * Step 2: + * Read the status of the internal phy. In case of + * DIRECT_SINGLE_MEDIA board, this link is the external link, + * otherwise this is the link between the 577xx and the first + * external phy */ - - /* - * In case of NOC feature is disabled and power is up, set GPIO control - * as input to enable listening of over-current indication + if (params->phy[INT_PHY].read_status) + params->phy[INT_PHY].read_status( + ¶ms->phy[INT_PHY], + params, vars); + /** + * The INT_PHY flow control reside in the vars. This include the + * case where the speed or flow control are not set to AUTO. + * Otherwise, the active external phy flow control result is set + * to the vars. The ext_phy_line_speed is needed to check if the + * speed is different between the internal phy and external phy. + * This case may be result of intermediate link speed change. */ - if (phy->flags & FLAGS_NOC) - return; - if (!(phy->flags & - FLAGS_NOC) && is_power_up) - val = (1<<4); - else - /* - * Set GPIO control to OUTPUT, and set the power bit - * to according to the is_power_up + if (active_external_phy > INT_PHY) { + vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; + /** + * Link speed is taken from the XGXS. AN and FC result from + * the external phy. */ - val = ((!(is_power_up)) << 1); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_GPIO_CTRL, - val); -} + vars->link_status |= phy_vars[active_external_phy].link_status; + ext_phy_line_speed = phy_vars[active_external_phy].line_speed; + vars->duplex = phy_vars[active_external_phy].duplex; + if (params->phy[active_external_phy].supported & + SUPPORTED_FIBRE) + vars->link_status |= LINK_STATUS_SERDES_LINK; + DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", + active_external_phy); + } + DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," + " ext_phy_line_speed = %d\n", vars->flow_ctrl, + vars->link_status, ext_phy_line_speed); + /** + * Upon link speed change set the NIG into drain mode. Comes to + * deals with possible FIFO glitch due to clk change when speed + * is decreased without link down indicator + */ -static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, - struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u16 edc_mode; - u8 rc = 0; + if (vars->phy_link_up) { + if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up && + (ext_phy_line_speed != vars->line_speed)) { + DP(NETIF_MSG_LINK, "Internal link speed %d is" + " different than the external" + " link speed %d\n", vars->line_speed, + ext_phy_line_speed); + vars->phy_link_up = 0; + } else if (prev_line_speed != vars->line_speed) { + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + msleep(1); + } + } - u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port].config)); + /* anything 10 and over uses the bmac */ + link_10g = ((vars->line_speed == SPEED_10000) || + (vars->line_speed == SPEED_12000) || + (vars->line_speed == SPEED_12500) || + (vars->line_speed == SPEED_13000) || + (vars->line_speed == SPEED_15000) || + (vars->line_speed == SPEED_16000)); - DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", - params->port); + bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); - if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { - DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); - return -EINVAL; - } else if (bnx2x_verify_sfp_module(phy, params) != - 0) { - /* check SFP+ module compatibility */ - DP(NETIF_MSG_LINK, "Module verification failed!!\n"); - rc = -EINVAL; - /* Turn on fault module-detected led */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, - params->port); - if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && - ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { - /* Shutdown SFP+ module */ - DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); - bnx2x_8727_power_module(bp, phy, 0); - return rc; + /** + * In case external phy link is up, and internal link is down + * (not initialized yet probably after link initialization, it + * needs to be initialized. + * Note that after link down-up as result of cable plug, the xgxs + * link would probably become up again without the need + * initialize it + */ + if (!(SINGLE_MEDIA_DIRECT(params))) { + DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," + " init_preceding = %d\n", ext_phy_link_up, + vars->phy_link_up, + params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST); + if (!(params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST) + && ext_phy_link_up && !vars->phy_link_up) { + vars->line_speed = ext_phy_line_speed; + if (vars->line_speed < SPEED_1000) + vars->phy_flags |= PHY_SGMII_FLAG; + else + vars->phy_flags &= ~PHY_SGMII_FLAG; + bnx2x_init_internal_phy(¶ms->phy[INT_PHY], + params, + vars); } - } else { - /* Turn off fault module-detected led */ - DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_LOW, - params->port); } - - /* power up the SFP module */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - bnx2x_8727_power_module(bp, phy, 1); - - /* Check and set limiting mode / LRM mode on 8726. - On 8727 it is done automatically */ - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); - else - bnx2x_8727_set_limiting_mode(bp, phy, edc_mode); - /* - * Enable transmit for this module if the module is approved, or - * if unapproved modules should also enable the Tx laser + /** + * Link is up only if both local phy and external phy (in case of + * non-direct board) are up */ - if (rc == 0 || - (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + vars->link_up = (vars->phy_link_up && + (ext_phy_link_up || + SINGLE_MEDIA_DIRECT(params))); + + if (vars->link_up) + rc = bnx2x_update_link_up(params, vars, link_10g); else - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + rc = bnx2x_update_link_down(params, vars); return rc; } -void bnx2x_handle_module_detect_int(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; - u32 gpio_val; - u8 port = params->port; - - /* Set valid module led off */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, - params->port); - - /* Get current gpio val refelecting module plugged in / out*/ - gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); - - /* Call the handling function in case module is detected */ - if (gpio_val == 0) { - bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, - port); +/*****************************************************************************/ +/* External Phy section */ +/*****************************************************************************/ +void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) +{ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); +} - if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) - bnx2x_sfp_module_detection(phy, params); - else - DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); - } else { - u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port]. - config)); +static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, + u32 spirom_ver, u32 ver_addr) +{ + DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", + (u16)(spirom_ver>>16), (u16)spirom_ver, port); - bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_SET, - port); - /* Module was plugged out. */ - /* Disable transmit for this module */ - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); - } + if (ver_addr) + REG_WR(bp, ver_addr, spirom_ver); } -static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) +static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port) { - /* Force KR or KX */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); + u16 fw_ver1, fw_ver2; + + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER1, &fw_ver1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, &fw_ver2); + bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), + phy->ver_addr); } -static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, - struct bnx2x_phy *phy) +static void bnx2x_ext_phy_set_pause(struct link_params *params, + struct bnx2x_phy *phy, + struct link_vars *vars) { u16 val; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); + struct bnx2x *bp = params->bp; + /* read modify write pause advertizing */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); - if (val == 0) { - /* Mustn't set low power mode in 8073 A0 */ - return; - } + val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; - /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ - bnx2x_cl45_read(bp, phy, + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { + val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; + } + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { + val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; + } + DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); +} + +static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + u16 pause_result; + u8 ret = 0; + /* read twice */ + + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { + ret = 1; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_ADV_PAUSE, &ld_pause); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + pause_result = (ld_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; + pause_result |= (lp_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; + DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", + pause_result); + bnx2x_pause_resolve(vars, pause_result); + } + return ret; +} + +static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 val; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + if (val & (1<<5)) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + if ((val & (1<<0)) == 0) + vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; +} + +/******************************************************************/ +/* common BCM8073/BCM8727 PHY SECTION */ +/******************************************************************/ +static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + if (phy->req_line_speed == SPEED_10 || + phy->req_line_speed == SPEED_100) { + vars->flow_ctrl = phy->req_flow_ctrl; + return; + } + + if (bnx2x_ext_phy_resolve_fc(phy, params, vars) && + (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) { + u16 pause_result; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LD, &ld_pause); + + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LP, &lp_pause); + pause_result = (ld_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; + pause_result |= (lp_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; + + bnx2x_pause_resolve(vars, pause_result); + DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", + pause_result); + } +} + +static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port) +{ + /* Boot port from external ROM */ + /* EDC grst */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x0001); + + /* ucode reboot and rst */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x008c); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); + + /* Reset internal microprocessor */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + + /* Release srst bit */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + + /* wait for 120ms for code download via SPI port */ + msleep(120); + + /* Clear ser_boot_ctl bit */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); + bnx2x_save_bcm_spirom_ver(bp, phy, port); +} + +static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + u16 val; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); + + if (val == 0) { + /* Mustn't set low power mode in 8073 A0 */ + return; + } + + /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); val &= ~(1<<13); bnx2x_cl45_write(bp, phy, @@ -2944,6 +3169,101 @@ static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); } +/******************************************************************/ +/* BCM8073 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) +{ + /* This is only required for 8073A1, version 102 only */ + u16 val; + + /* Read 8073 HW revision*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_CHIP_REV, &val); + + if (val != 1) { + /* No need to workaround in 8073 A1 */ + return 0; + } + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, &val); + + /* SNR should be applied only for version 0x102 */ + if (val != 0x102) + return 0; + + return 1; +} + +static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) +{ + u16 val, cnt, cnt1 ; + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_CHIP_REV, &val); + + if (val > 0) { + /* No need to workaround in 8073 A1 */ + return 0; + } + /* XAUI workaround in 8073 A0: */ + + /* After loading the boot ROM and restarting Autoneg, + poll Dev1, Reg $C820: */ + + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_SPEED_LINK_STATUS, + &val); + /* If bit [14] = 0 or bit [13] = 0, continue on with + system initialization (XAUI work-around not required, + as these bits indicate 2.5G or 1G link up). */ + if (!(val & (1<<14)) || !(val & (1<<13))) { + DP(NETIF_MSG_LINK, "XAUI work-around not required\n"); + return 0; + } else if (!(val & (1<<15))) { + DP(NETIF_MSG_LINK, "clc bit 15 went off\n"); + /* If bit 15 is 0, then poll Dev1, Reg $C841 until + it's MSB (bit 15) goes to 1 (indicating that the + XAUI workaround has completed), + then continue on with system initialization.*/ + for (cnt1 = 0; cnt1 < 1000; cnt1++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_XAUI_WA, &val); + if (val & (1<<15)) { + DP(NETIF_MSG_LINK, + "XAUI workaround has completed\n"); + return 0; + } + msleep(3); + } + break; + } + msleep(3); + } + DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n"); + return -EINVAL; +} + +static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) +{ + /* Force KR or KX */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); +} + static void bnx2x_8073_set_pause_cl37(struct link_params *params, struct bnx2x_phy *phy, struct link_vars *vars) @@ -2979,2210 +3299,1950 @@ static void bnx2x_8073_set_pause_cl37(struct link_params *params, msleep(500); } -static void bnx2x_ext_phy_set_pause(struct link_params *params, - struct bnx2x_phy *phy, - struct link_vars *vars) +static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u16 val; struct bnx2x *bp = params->bp; - /* read modify write pause advertizing */ - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); - - val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; - - /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { - val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; - } - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { - val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; - } - DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); -} + u16 val = 0, tmp1; + u8 gpio_port; + DP(NETIF_MSG_LINK, "Init 8073\n"); -static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, - struct link_params *params) -{ + gpio_port = params->port; + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - u16 bank, i = 0; - struct bnx2x *bp = params->bp; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; - bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { - CL45_WR_OVER_CL22(bp, phy, - bank, - MDIO_RX0_RX_EQ_BOOST, - phy->rx_preemphasis[i]); - } + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); - for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; - bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { - CL45_WR_OVER_CL22(bp, phy, - bank, - MDIO_TX0_TX_DRIVER, - phy->tx_preemphasis[i]); - } -} + bnx2x_8073_set_pause_cl37(params, phy, vars); -static void bnx2x_848xx_set_led(struct bnx2x *bp, - struct bnx2x_phy *phy) -{ - u16 val; + bnx2x_8073_set_xaui_low_power_mode(bp, phy); - /* PHYC_CTL_LED_CTL */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, &val); - val &= 0xFE00; - val |= 0x0092; - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, val); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - 0x80); + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0x18); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x0040); + DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); - /* 'Interrupt Mask' */ + /* Enable CL37 BAM */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - 0xFFFB, 0xFFFD); -} - -static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || - (params->loopback_mode == LOOPBACK_XGXS_10)); - if (!(vars->phy_flags & PHY_SGMII_FLAG)) { - if (SINGLE_MEDIA_DIRECT(params) && - (params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) - bnx2x_set_preemphasis(phy, params); + MDIO_AN_REG_8073_BAM, val | 1); - /* forced speed requested? */ - if (vars->line_speed != SPEED_AUTO_NEG || - (SINGLE_MEDIA_DIRECT(params) && - params->loopback_mode == LOOPBACK_EXT)) { - DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); + if (params->loopback_mode == LOOPBACK_EXT) { + bnx2x_807x_force_10G(bp, phy); + DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); + return 0; + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); + } + if (phy->req_line_speed != SPEED_AUTO_NEG) { + if (phy->req_line_speed == SPEED_10000) { + val = (1<<7); + } else if (phy->req_line_speed == SPEED_2500) { + val = (1<<5); + /* Note that 2.5G works only + when used with 1G advertisment */ + } else + val = (1<<5); + } else { + val = 0; + if (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + val |= (1<<7); - /* disable autoneg */ - bnx2x_set_autoneg(phy, params, vars, 0); + /* Note that 2.5G works only when + used with 1G advertisment */ + if (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | + PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) + val |= (1<<5); + DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); + } - /* program speed and duplex */ - bnx2x_program_serdes(phy, params, vars); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); - } else { /* AN_mode */ - DP(NETIF_MSG_LINK, "not SGMII, AN\n"); + if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && + (phy->req_line_speed == SPEED_AUTO_NEG)) || + (phy->req_line_speed == SPEED_2500)) { + u16 phy_ver; + /* Allow 2.5G for A1 and above */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, + &phy_ver); + DP(NETIF_MSG_LINK, "Add 2.5G\n"); + if (phy_ver > 0) + tmp1 |= 1; + else + tmp1 &= 0xfffe; + } else { + DP(NETIF_MSG_LINK, "Disable 2.5G\n"); + tmp1 &= 0xfffe; + } - /* AN enabled */ - bnx2x_set_brcm_cl37_advertisment(phy, params); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); + /* Add support for CL37 (passive mode) II */ - /* program duplex & pause advertisement (for aneg) */ - bnx2x_set_ieee_aneg_advertisment(phy, params, - vars->ieee_fc); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, + (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ? + 0x20 : 0x40))); - /* enable autoneg */ - bnx2x_set_autoneg(phy, params, vars, enable_cl73); + /* Add support for CL37 (passive mode) III */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - /* enable and restart AN */ - bnx2x_restart_autoneg(phy, params, enable_cl73); - } + /* The SNR will improve about 2db by changing + BW and FEE main tap. Rest commands are executed + after link is up*/ + if (bnx2x_8073_is_snr_needed(bp, phy)) + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, + 0xFB0C); - } else { /* SGMII mode */ - DP(NETIF_MSG_LINK, "SGMII\n"); + /* Enable FEC (Forware Error Correction) Request in the AN */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); + tmp1 |= (1<<15); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); - bnx2x_initialize_sgmii_process(phy, params, vars); - } -} + bnx2x_ext_phy_set_pause(params, phy, vars); -static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, - struct bnx2x_phy *phy) -{ - u16 cnt, ctrl; - /* Wait for soft reset to get cleared upto 1 sec */ - for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); - if (!(ctrl & (1<<15))) - break; - msleep(1); - } - DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); - return cnt; + /* Restart autoneg */ + msleep(500); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n", + ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); + return 0; } -static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, +static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "init 8705\n"); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); - bnx2x_wait_reset_complete(bp, phy); + u8 link_up = 0; + u16 val1, val2; + u16 link_status = 0; + u16 an1000_status = 0; - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); - bnx2x_cl45_write(bp, phy, - MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); - /* BCM8705 doesn't have microcode, hence the 0 */ - bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); - return 0; -} + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); -static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - u16 cnt, val; - struct bnx2x *bp = params->bp; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); - bnx2x_wait_reset_complete(bp, phy); + DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); - /* Wait until fw is loaded */ - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); - if (val) - break; - msleep(10); - } - DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - u8 i; - u16 reg; - for (i = 0; i < 4; i++) { - reg = MDIO_XS_8706_REG_BANK_RX0 + - i*(MDIO_XS_8706_REG_BANK_RX1 - - MDIO_XS_8706_REG_BANK_RX0); - bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); - /* Clear first 3 bits of the control */ - val &= ~0x7; - /* Set control bits according to configuration */ - val |= (phy->rx_preemphasis[i] & 0x7); - DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706" - " reg 0x%x <-- val 0x%x\n", reg, val); - bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); - } + /* clear the interrupt LASI status register */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); + + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + + DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); + + /* Check the link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + link_up = ((val1 & 4) == 4); + DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); + + if (link_up && + ((phy->req_line_speed != SPEED_10000))) { + if (bnx2x_8073_xaui_wa(bp, phy) != 0) + return 0; } - /* Force speed */ - if (phy->req_line_speed == SPEED_10000) { - DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_DIGITAL_CTRL, 0x400); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); - } else { - /* Force 1Gbps using autoneg with 1G advertisment */ + /* Check the link status on 1.1.2 */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," + "an_link_status=0x%x\n", val2, val1, an1000_status); - /* Allow CL37 through CL73 */ - DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); + if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { + /* The SNR will improve about 2dbby + changing the BW and FEE main tap.*/ + /* The 1st write to change FFE main + tap is set before restart AN */ + /* Change PLL Bandwidth in EDC + register */ bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, + 0x26BC); - /* Enable Full-Duplex advertisment on CL37 */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); - /* Enable CL37 AN */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - /* 1G support */ + /* Change CDR Bandwidth in EDC register */ bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); + MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, + 0x0333); + } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, + &link_status); - /* Enable clause 73 AN */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, - 0x0400); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, - 0x0004); + /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", + params->port); + } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { + link_up = 1; + vars->line_speed = SPEED_2500; + DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", + params->port); + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); } - bnx2x_save_bcm_spirom_ver(bp, phy, params->port); - return 0; + + if (link_up) { + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_8073_resolve_fc(phy, params, vars); + } + return link_up; } -static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, +static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_port; + gpio_port = params->port; + DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); +} + +/******************************************************************/ +/* BCM8705 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - u32 swap_val, swap_override, aeu_gpio_mask, offset; - DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + DP(NETIF_MSG_LINK, "init 8705\n"); /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); bnx2x_wait_reset_complete(bp, phy); - bnx2x_8726_external_rom_boot(phy, params); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); + /* BCM8705 doesn't have microcode, hence the 0 */ + bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); + return 0; +} - /* Need to call module detected on initialization since - the module detection triggered by actual module - insertion might occur before driver is loaded, and when - driver is loaded, it reset all registers, including the - transmitter */ - bnx2x_sfp_module_detection(phy, params); +static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 link_up = 0; + u16 val1, rx_sd; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "read status 8705\n"); + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - if (phy->req_line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); - } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) && - ((phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - /* Set Flow control */ - bnx2x_ext_phy_set_pause(params, phy, vars); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - /* Enable RX-ALARM control to receive - interrupt for 1G speed change */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - } else { /* Default 10G. Set only LASI control */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); - } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," - "TX_CTRL2 0x%x\n", - phy->tx_preemphasis[0], - phy->tx_preemphasis[1]); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL1, - phy->tx_preemphasis[0]); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL2, - phy->tx_preemphasis[1]); + DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); + link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0)); + if (link_up) { + vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); } + return link_up; +} - /* Set GPIO3 to trigger SFP+ module insertion/removal */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); +/******************************************************************/ +/* SFP+ module Section */ +/******************************************************************/ +static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port, + u8 tx_en) +{ + u16 val; - /* The GPIO should be swapped if the swap register is set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", + tx_en, port); + /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + &val); - /* Select function upon port-swap configuration */ - if (params->port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); - return 0; + if (tx_en) + val &= ~(1<<15); + else + val |= (1<<15); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + val); } -static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, + u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; - u16 val = 0, tmp1; - u8 gpio_port; - DP(NETIF_MSG_LINK, "Init 8073\n"); - - gpio_port = params->port; - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - - /* enable LASI */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2)); + u16 val = 0; + u16 i; + if (byte_cnt > 16) { + DP(NETIF_MSG_LINK, "Reading from eeprom is" + " is limited to 0xf\n"); + return -EINVAL; + } + /* Set the read command byte count */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); - - bnx2x_8073_set_pause_cl37(params, phy, vars); - - bnx2x_8073_set_xaui_low_power_mode(bp, phy); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, + (byte_cnt | 0xa000)); - DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); + /* Set the read command address */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, + addr); - /* Enable CL37 BAM */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, &val); + /* Activate read command */ bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, val | 1); + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + 0x2c0f); - if (params->loopback_mode == LOOPBACK_EXT) { - bnx2x_807x_force_10G(bp, phy); - DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); - return 0; - } else { - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); + /* Wait up to 500us for command complete status */ + for (i = 0; i < 100; i++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) + break; + udelay(5); } - if (phy->req_line_speed != SPEED_AUTO_NEG) { - if (phy->req_line_speed == SPEED_10000) { - val = (1<<7); - } else if (phy->req_line_speed == SPEED_2500) { - val = (1<<5); - /* Note that 2.5G works only - when used with 1G advertisment */ - } else - val = (1<<5); - } else { - val = 0; - if (phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) - val |= (1<<7); - /* Note that 2.5G works only when - used with 1G advertisment */ - if (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - val |= (1<<5); - DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { + DP(NETIF_MSG_LINK, + "Got bad status 0x%x when reading from SFP+ EEPROM\n", + (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); + return -EINVAL; } - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); - - if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && - (phy->req_line_speed == SPEED_AUTO_NEG)) || - (phy->req_line_speed == SPEED_2500)) { - u16 phy_ver; - /* Allow 2.5G for A1 and above */ + /* Read the buffer */ + for (i = 0; i < byte_cnt; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, - &phy_ver); - DP(NETIF_MSG_LINK, "Add 2.5G\n"); - if (phy_ver > 0) - tmp1 |= 1; - else - tmp1 &= 0xfffe; - } else { - DP(NETIF_MSG_LINK, "Disable 2.5G\n"); - tmp1 &= 0xfffe; + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); + o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); } - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); - /* Add support for CL37 (passive mode) II */ - - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, - (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ? - 0x20 : 0x40))); - - /* Add support for CL37 (passive mode) III */ - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - - /* The SNR will improve about 2db by changing - BW and FEE main tap. Rest commands are executed - after link is up*/ - if (bnx2x_8073_is_snr_needed(bp, phy)) - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, - 0xFB0C); - - /* Enable FEC (Forware Error Correction) Request in the AN */ - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); - tmp1 |= (1<<15); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); - - bnx2x_ext_phy_set_pause(params, phy, vars); - - /* Restart autoneg */ - msleep(500); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n", - ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); - return 0; + for (i = 0; i < 100; i++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) + return 0;; + msleep(1); + } + return -EINVAL; } - -static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, + u16 addr, u8 byte_cnt, u8 *o_buf) { - u16 tmp1, val, mod_abs; - u16 rx_alarm_ctrl_val; - u16 lasi_ctrl_val; struct bnx2x *bp = params->bp; - /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ + u16 val, i; - bnx2x_wait_reset_complete(bp, phy); - rx_alarm_ctrl_val = (1<<2) | (1<<5) ; - lasi_ctrl_val = 0x0004; + if (byte_cnt > 16) { + DP(NETIF_MSG_LINK, "Reading from eeprom is" + " is limited to 0xf\n"); + return -EINVAL; + } - DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); - /* enable LASI */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, - rx_alarm_ctrl_val); + /* Need to read from 1.8000 to clear it */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + &val); + /* Set the read command byte count */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, + ((byte_cnt < 2) ? 2 : byte_cnt)); - /* Initially configure MOD_ABS to interrupt when - module is presence( bit 8) */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); - /* Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8) | (1<<9)); + /* Set the read command address */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - - - /* Make MOD_ABS give interrupt on change */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val |= (1<<12); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, + addr); + /* Set the destination address */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - /* Set 8727 GPIOs to input to allow reading from the - 8727 GPIO0 status which reflect SFP+ module - over-current */ + MDIO_PMA_DEVAD, + 0x8004, + MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val &= 0xff8f; /* Reset bits 4-6 */ + /* Activate read command */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - - bnx2x_8727_power_module(bp, phy, 1); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + 0x8002); + /* Wait appropriate time for two-wire command to finish before + polling the status register */ + msleep(1); - /* Set option 1G speed */ - if (phy->req_line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + /* Wait up to 500us for command complete status */ + for (i = 0; i < 100; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); - DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); - } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && - ((phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && - ((phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { - - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); - } else { - /** - * Since the 8727 has only single reset pin, need to set the 10G - * registers although it is default - */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, - 0x0020); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, - 0x0008); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) + break; + udelay(5); } + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { + DP(NETIF_MSG_LINK, + "Got bad status 0x%x when reading from SFP+ EEPROM\n", + (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); + return -EINVAL; + } - /* Set 2-wire transfer rate of SFP+ module EEPROM - * to 100Khz since some DACs(direct attached cables) do - * not work at 400Khz. - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, - 0xa001); - - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", - phy->tx_preemphasis[0], - phy->tx_preemphasis[1]); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, - phy->tx_preemphasis[0]); + /* Read the buffer */ + for (i = 0; i < byte_cnt; i++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); + o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); + } - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, - phy->tx_preemphasis[1]); + for (i = 0; i < 100; i++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == + MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) + return 0;; + msleep(1); } - return 0; + return -EINVAL; } -static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf) { - u16 fw_ver1, fw_ver2, val; - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); - - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_wait_reset_complete(bp, phy); - - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); - DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - - bnx2x_ext_phy_set_pause(params, phy, vars); - /* Restart autoneg */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); - val |= 0x200; - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); - - /* Save spirom version */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); - bnx2x_save_spirom_version(bp, params->port, - (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); - return 0; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, + byte_cnt, o_buf); + else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, + byte_cnt, o_buf); + return -EINVAL; } -static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, + struct link_params *params, + u16 *edc_mode) { struct bnx2x *bp = params->bp; - u16 autoneg_val, an_1000_val, an_10_100_val; - bnx2x_wait_reset_complete(bp, phy); - bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, - 1 << NIG_LATCH_BC_ENABLE_MI_INT); + u8 val, check_limiting_mode = 0; + *edc_mode = EDC_MODE_LIMITING; - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); - bnx2x_848xx_set_led(bp, phy); - /* set 1000 speed advertisement */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, - &an_1000_val); + /* First check for copper cable */ + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_CON_TYPE_ADDR, + 1, + &val) != 0) { + DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); + return -EINVAL; + } - bnx2x_ext_phy_set_pause(params, phy, vars); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - &an_10_100_val); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_val); - /* Disable forced speed */ - autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); - an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); + switch (val) { + case SFP_EEPROM_CON_TYPE_VAL_COPPER: + { + u8 copper_module_type; - if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || - (phy->req_line_speed == SPEED_1000)) { - an_1000_val |= (1<<8); - autoneg_val |= (1<<9 | 1<<12); - if (phy->req_duplex == DUPLEX_FULL) - an_1000_val |= (1<<9); - DP(NETIF_MSG_LINK, "Advertising 1G\n"); - } else - an_1000_val &= ~((1<<8) | (1<<9)); - - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, - an_1000_val); - - /* set 10 speed advertisement */ - if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { - an_10_100_val |= (1<<7); - /* Enable autoneg and restart autoneg for legacy speeds */ - autoneg_val |= (1<<9 | 1<<12); - - if (phy->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<8); - DP(NETIF_MSG_LINK, "Advertising 100M\n"); - } - /* set 10 speed advertisement */ - if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { - an_10_100_val |= (1<<5); - autoneg_val |= (1<<9 | 1<<12); - if (phy->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<6); - DP(NETIF_MSG_LINK, "Advertising 10M\n"); - } + /* Check if its active cable( includes SFP+ module) + of passive cable*/ + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_FC_TX_TECH_ADDR, + 1, + &copper_module_type) != + 0) { + DP(NETIF_MSG_LINK, + "Failed to read copper-cable-type" + " from SFP+ EEPROM\n"); + return -EINVAL; + } - /* Only 10/100 are allowed to work in FORCE mode */ - if (phy->req_line_speed == SPEED_100) { - autoneg_val |= (1<<13); - /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, - (1<<15 | 1<<9 | 7<<0)); - DP(NETIF_MSG_LINK, "Setting 100M force\n"); + if (copper_module_type & + SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { + DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); + check_limiting_mode = 1; + } else if (copper_module_type & + SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { + DP(NETIF_MSG_LINK, "Passive Copper" + " cable detected\n"); + *edc_mode = + EDC_MODE_PASSIVE_DAC; + } else { + DP(NETIF_MSG_LINK, "Unknown copper-cable-" + "type 0x%x !!!\n", copper_module_type); + return -EINVAL; + } + break; } - if (phy->req_line_speed == SPEED_10) { - /* Enabled AUTO-MDIX when autoneg is disabled */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, - (1<<15 | 1<<9 | 7<<0)); - DP(NETIF_MSG_LINK, "Setting 10M force\n"); + case SFP_EEPROM_CON_TYPE_VAL_LC: + DP(NETIF_MSG_LINK, "Optic module detected\n"); + check_limiting_mode = 1; + break; + default: + DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n", + val); + return -EINVAL; } - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, - an_10_100_val); - - if (phy->req_duplex == DUPLEX_FULL) - autoneg_val |= (1<<8); - - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); - - if (((phy->req_line_speed == SPEED_AUTO_NEG) && - (phy->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || - (phy->req_line_speed == SPEED_10000)) { - DP(NETIF_MSG_LINK, "Advertising 10G\n"); - /* Restart autoneg for 10G*/ - - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, - 0x3200); - } else if (phy->req_line_speed != SPEED_10 && - phy->req_line_speed != SPEED_100) { - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, - 1); + if (check_limiting_mode) { + u8 options[SFP_EEPROM_OPTIONS_SIZE]; + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_OPTIONS_ADDR, + SFP_EEPROM_OPTIONS_SIZE, + options) != 0) { + DP(NETIF_MSG_LINK, "Failed to read Option" + " field from module EEPROM\n"); + return -EINVAL; + } + if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK)) + *edc_mode = EDC_MODE_LINEAR; + else + *edc_mode = EDC_MODE_LIMITING; } - /* Save spirom version */ - bnx2x_save_848xx_spirom_version(phy, params); - + DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); return 0; } - -static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +/* This function read the relevant field from the module ( SFP+ ), + and verify it is compliant with this board */ +static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - u16 temp; - msleep(1); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - msleep(200); /* 100 is not enough */ + u32 val; + u32 fw_resp; + char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; + char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; - /** - * BCM84823 requires that XGXS links up first @ 10G for normal - * behavior - */ - temp = vars->line_speed; - vars->line_speed = SPEED_10000; - bnx2x_set_autoneg(phy, params, vars, 0); - bnx2x_program_serdes(phy, params, vars); - vars->line_speed = temp; - return bnx2x_848xx_cmn_config_init(phy, params, vars); -} + val = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].config)); + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) { + DP(NETIF_MSG_LINK, "NOT enforcing module verification\n"); + return 0; + } -static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* Ask the FW to validate the module */ + if (!(params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { + DP(NETIF_MSG_LINK, "FW does not support OPT MDL " + "verification\n"); + return -EINVAL; + } - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); + fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); + if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { + DP(NETIF_MSG_LINK, "Approved module\n"); + return 0; + } - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); - return bnx2x_848xx_cmn_config_init(phy, params, vars); + /* format the warning message */ + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_VENDOR_NAME_ADDR, + SFP_EEPROM_VENDOR_NAME_SIZE, + (u8 *)vendor_name)) + vendor_name[0] = '\0'; + else + vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_PART_NO_ADDR, + SFP_EEPROM_PART_NO_SIZE, + (u8 *)vendor_pn)) + vendor_pn[0] = '\0'; + else + vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; + + netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," + " Port %d from %s part number %s\n", + params->port, vendor_name, vendor_pn); + return -EINVAL; } +static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, + struct link_params *params) -static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, - struct bnx2x_phy *phy, - struct link_vars *vars) -{ - u16 val; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &val); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &val); - if (val & (1<<5)) - vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; - if ((val & (1<<0)) == 0) - vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; -} -static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, - struct link_params *params) { + u8 val; struct bnx2x *bp = params->bp; - u16 mod_abs, rx_alarm_status; - u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port]. - config)); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); - if (mod_abs & (1<<8)) { + u16 timeout; + /* Initialization time after hot-plug may take up to 300ms for some + phys type ( e.g. JDSU ) */ + for (timeout = 0; timeout < 60; timeout++) { + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) + == 0) { + DP(NETIF_MSG_LINK, "SFP+ module initialization " + "took %d ms\n", timeout * 5); + return 0; + } + msleep(5); + } + return -EINVAL; +} - /* Module is absent */ - DP(NETIF_MSG_LINK, "MOD_ABS indication " - "show module is absent\n"); +static void bnx2x_8727_power_module(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 is_power_up) { + /* Make sure GPIOs are not using for LED mode */ + u16 val; + /* + * In the GPIO register, bit 4 is use to detemine if the GPIOs are + * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for + * output + * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 + * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 + * where the 1st bit is the over-current(only input), and 2nd bit is + * for power( only output ) + */ - /* 1. Set mod_abs to detect next module - presence event - 2. Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8)|(1<<9)); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + /* + * In case of NOC feature is disabled and power is up, set GPIO control + * as input to enable listening of over-current indication + */ + if (phy->flags & FLAGS_NOC) + return; + if (!(phy->flags & + FLAGS_NOC) && is_power_up) + val = (1<<4); + else + /* + * Set GPIO control to OUTPUT, and set the power bit + * to according to the is_power_up + */ + val = ((!(is_power_up)) << 1); - /* Clear RX alarm since it stays up as long as - the mod_abs wasn't changed */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + val); +} - } else { - /* Module is present */ - DP(NETIF_MSG_LINK, "MOD_ABS indication " - "show module is present\n"); - /* First thing, disable transmitter, - and if the module is ok, the - module_detection will enable it*/ +static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 edc_mode) +{ + u16 cur_limiting_mode; - /* 1. Set mod_abs to detect next module - absent event ( bit 8) - 2. Restore the default polarity of the OPRXLOS signal and - this signal will then correctly indicate the presence or - absence of the Rx signal. (bit 9) */ - mod_abs |= ((1<<8)|(1<<9)); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + &cur_limiting_mode); + DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", + cur_limiting_mode); + + if (edc_mode == EDC_MODE_LIMITING) { + DP(NETIF_MSG_LINK, + "Setting LIMITING MODE\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - - /* Clear RX alarm since it stays up as long as - the mod_abs wasn't changed. This is need to be done - before calling the module detection, otherwise it will clear - the link update alarm */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_REG_ROM_VER2, + EDC_MODE_LIMITING); + } else { /* LRM mode ( default )*/ + DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + /* Changing to LRM mode takes quite few seconds. + So do it only if current mode is limiting + ( default is LRM )*/ + if (cur_limiting_mode != EDC_MODE_LIMITING) + return 0; - if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) - bnx2x_sfp_module_detection(phy, params); - else - DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_LRM_MODE, + 0); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + 0x128); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL0, + 0x4008); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_LRM_MODE, + 0xaaaa); } - - DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", - rx_alarm_status); - /* No need to check link status in case of - module plugged in/out */ + return 0; } - -static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 edc_mode) { - u8 link_up = 0; - u16 val1, rx_sd; - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "read status 8705\n"); + u16 phy_identifier; + u16 rom_ver2_val; bnx2x_cl45_read(bp, phy, - MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + &phy_identifier); - bnx2x_cl45_read(bp, phy, - MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + (phy_identifier & ~(1<<9))); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + &rom_ver2_val); + /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, 0xc809, &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, 0xc809, &val1); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + (phy_identifier | (1<<9))); - DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); - link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0)); - if (link_up) { - vars->line_speed = SPEED_10000; - bnx2x_ext_phy_resolve_fc(phy, params, vars); - } - return link_up; + return 0; } -static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params) { - u8 link_up = 0; - u16 val1, val2, rx_sd, pcs_status; struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); - /* Clear RX Alarm*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); - /* clear LASI indication*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); - DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); + u16 edc_mode; + u8 rc = 0; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + u32 val = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].config)); - DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" - " link_status 0x%x\n", rx_sd, pcs_status, val2); - /* link is up if both bit 0 of pmd_rx_sd and - * bit 0 of pcs_status are set, or if the autoneg bit - * 1 is set - */ - link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); - if (link_up) { - if (val2 & (1<<1)) - vars->line_speed = SPEED_1000; - else - vars->line_speed = SPEED_10000; - bnx2x_ext_phy_resolve_fc(phy, params, vars); + DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", + params->port); + + if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { + DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); + return -EINVAL; + } else if (bnx2x_verify_sfp_module(phy, params) != + 0) { + /* check SFP+ module compatibility */ + DP(NETIF_MSG_LINK, "Module verification failed!!\n"); + rc = -EINVAL; + /* Turn on fault module-detected led */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, + MISC_REGISTERS_GPIO_HIGH, + params->port); + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && + ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { + /* Shutdown SFP+ module */ + DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); + bnx2x_8727_power_module(bp, phy, 0); + return rc; + } + } else { + /* Turn off fault module-detected led */ + DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, + MISC_REGISTERS_GPIO_LOW, + params->port); } - return link_up; -} -static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - return bnx2x_8706_8726_read_status(phy, params, vars); -} -static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 val1; - u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars); - if (link_up) { - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is disabled\n"); - link_up = 0; - vars->line_speed = 0; - } - } - return link_up; -} + /* power up the SFP module */ + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + bnx2x_8727_power_module(bp, phy, 1); -static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) + /* Check and set limiting mode / LRM mode on 8726. + On 8727 it is done automatically */ + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); + else + bnx2x_8727_set_limiting_mode(bp, phy, edc_mode); + /* + * Enable transmit for this module if the module is approved, or + * if unapproved modules should also enable the Tx laser + */ + if (rc == 0 || + (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + else + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + return rc; +} + +void bnx2x_handle_module_detect_int(struct link_params *params) { struct bnx2x *bp = params->bp; - u8 link_up = 0; - u16 link_status = 0; - u16 rx_alarm_status, val1; - /* Check the LASI */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, - &rx_alarm_status); - vars->line_speed = 0; - DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - - DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); + struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; + u32 gpio_val; + u8 port = params->port; - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); + /* Set valid module led off */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, + MISC_REGISTERS_GPIO_HIGH, + params->port); - /** - * If a module is present and there is need to check - * for over current - */ - if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { - /* Check over-current using 8727 GPIO0 input*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, - &val1); + /* Get current gpio val refelecting module plugged in / out*/ + gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); - if ((val1 & (1<<8)) == 0) { - DP(NETIF_MSG_LINK, "8727 Power fault has been detected" - " on port %d\n", params->port); - netdev_err(bp->dev, "Error: Power fault on Port %d has" - " been detected and the power to " - "that SFP+ module has been removed" - " to prevent failure of the card." - " Please remove the SFP+ module and" - " restart the system to clear this" - " error.\n", - params->port); + /* Call the handling function in case module is detected */ + if (gpio_val == 0) { - /* - * Disable all RX_ALARMs except for - * mod_abs - */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); + bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, + port); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, &val1); - /* Wait for module_absent_event */ - val1 |= (1<<8); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, val1); - /* Clear RX alarm */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); - return 0; - } - } /* Over current check */ + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); + else + DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); + } else { + u32 val = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port]. + config)); - /* When module absent bit is set, check module */ - if (rx_alarm_status & (1<<5)) { - bnx2x_8727_handle_mod_abs(phy, params); - /* Enable all mod_abs and link detection bits */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, - ((1<<5) | (1<<2))); + bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INT_OUTPUT_SET, + port); + /* Module was plugged out. */ + /* Disable transmit for this module */ + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); } +} - /* If transmitter is disabled, ignore false link up indication */ +/******************************************************************/ +/* common BCM8706/BCM8726 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 link_up = 0; + u16 val1, val2, rx_sd, pcs_status; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); + /* Clear RX Alarm*/ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is disabled\n"); - return 0; - } + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + /* clear LASI indication*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ - if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { - link_up = 1; - vars->line_speed = SPEED_10000; - } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { - link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", - params->port); - } else { - link_up = 0; - DP(NETIF_MSG_LINK, "port %x: External link is down\n", - params->port); - } - if (link_up) + DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" + " link_status 0x%x\n", rx_sd, pcs_status, val2); + /* link is up if both bit 0 of pmd_rx_sd and + * bit 0 of pcs_status are set, or if the autoneg bit + * 1 is set + */ + link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); + if (link_up) { + if (val2 & (1<<1)) + vars->line_speed = SPEED_1000; + else + vars->line_speed = SPEED_10000; bnx2x_ext_phy_resolve_fc(phy, params, vars); + } return link_up; } -static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - if (phy->req_line_speed == SPEED_10 || - phy->req_line_speed == SPEED_100) { - vars->flow_ctrl = phy->req_flow_ctrl; - return; - } - - if (bnx2x_ext_phy_resolve_fc(phy, params, vars) && - (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) { - u16 pause_result; - u16 ld_pause; /* local */ - u16 lp_pause; /* link partner */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &ld_pause); - - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, &lp_pause); - pause_result = (ld_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; - pause_result |= (lp_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; - - bnx2x_pause_resolve(vars, pause_result); - DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", - pause_result); - } -} -static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, +/******************************************************************/ +/* BCM8706 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { + u16 cnt, val; struct bnx2x *bp = params->bp; - u8 link_up = 0; - u16 val1, val2; - u16 link_status = 0; - u16 an1000_status = 0; - - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); + bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); + /* Wait until fw is loaded */ + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); + if (val) + break; + msleep(10); + } + DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + u8 i; + u16 reg; + for (i = 0; i < 4; i++) { + reg = MDIO_XS_8706_REG_BANK_RX0 + + i*(MDIO_XS_8706_REG_BANK_RX1 - + MDIO_XS_8706_REG_BANK_RX0); + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); + /* Clear first 3 bits of the control */ + val &= ~0x7; + /* Set control bits according to configuration */ + val |= (phy->rx_preemphasis[i] & 0x7); + DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706" + " reg 0x%x <-- val 0x%x\n", reg, val); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); + } + } + /* Force speed */ + if (phy->req_line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); - /* clear the interrupt LASI status register */ - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_DIGITAL_CTRL, 0x400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + } else { + /* Force 1Gbps using autoneg with 1G advertisment */ - /* Check the LASI */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + /* Allow CL37 through CL73 */ + DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); - DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); + /* Enable Full-Duplex advertisment on CL37 */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); + /* Enable CL37 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + /* 1G support */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); - /* Check the link status */ - bnx2x_cl45_read(bp, phy, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); - DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + /* Enable clause 73 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x0400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + 0x0004); + } + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); + return 0; +} - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); - link_up = ((val1 & 4) == 4); - DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); +static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + return bnx2x_8706_8726_read_status(phy, params, vars); +} - if (link_up && - ((phy->req_line_speed != SPEED_10000))) { - if (bnx2x_8073_xaui_wa(bp, phy) != 0) - return 0; - } - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); +/******************************************************************/ +/* BCM8726 PHY SECTION */ +/******************************************************************/ +static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); +} - /* Check the link status on 1.1.2 */ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," - "an_link_status=0x%x\n", val2, val1, an1000_status); +static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* Need to wait 100ms after reset */ + msleep(100); - link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); - if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { - /* The SNR will improve about 2dbby - changing the BW and FEE main tap.*/ - /* The 1st write to change FFE main - tap is set before restart AN */ - /* Change PLL Bandwidth in EDC - register */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, - 0x26BC); + /* Micro controller re-boot */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); - /* Change CDR Bandwidth in EDC register */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, - 0x0333); - } - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &link_status); + /* Set soft reset */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); - /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ - if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { - link_up = 1; - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", - params->port); - } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { - link_up = 1; - vars->line_speed = SPEED_2500; - DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", - params->port); - } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { - link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", - params->port); - } else { - link_up = 0; - DP(NETIF_MSG_LINK, "port %x: External link is down\n", - params->port); - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); - if (link_up) { - bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); - bnx2x_8073_resolve_fc(phy, params, vars); - } - return link_up; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + + /* wait for 150ms for microcode load */ + msleep(150); + + /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); + + msleep(200); + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); } -static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, +static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 link_up; - u16 val1, val2; - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", - val2, val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", - val2, val1); - link_up = ((val1 & 4) == 4); - /* if link is up - * print the AN outcome of the SFX7101 PHY - */ + u16 val1; + u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars); if (link_up) { bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, - &val2); - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", - val2, (val2 & (1<<14))); - bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); - bnx2x_ext_phy_resolve_fc(phy, params, vars); + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, + &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + link_up = 0; + vars->line_speed = 0; + } } return link_up; } -static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) + +static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val, val1, val2; - u8 link_up = 0; + u32 val; + u32 swap_val, swap_override, aeu_gpio_mask, offset; + DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - /* Check 10G-BaseT link status */ - /* Check PMD signal ok */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, 0xFFFA, &val1); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, - &val2); - DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - /* Check link 10G */ - if (val2 & (1<<11)) { - vars->line_speed = SPEED_10000; - link_up = 1; - bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); - } else { /* Check Legacy speed link */ - u16 legacy_status, legacy_speed; - - /* Enable expansion register 0x42 (Operation mode status) */ - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); - - /* Get legacy speed operation status */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, - &legacy_status); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + bnx2x_wait_reset_complete(bp, phy); - DP(NETIF_MSG_LINK, "Legacy speed status" - " = 0x%x\n", legacy_status); - link_up = ((legacy_status & (1<<11)) == (1<<11)); - if (link_up) { - legacy_speed = (legacy_status & (3<<9)); - if (legacy_speed == (0<<9)) - vars->line_speed = SPEED_10; - else if (legacy_speed == (1<<9)) - vars->line_speed = SPEED_100; - else if (legacy_speed == (2<<9)) - vars->line_speed = SPEED_1000; - else /* Should not happen */ - vars->line_speed = 0; + bnx2x_8726_external_rom_boot(phy, params); - if (legacy_status & (1<<8)) - vars->duplex = DUPLEX_FULL; - else - vars->duplex = DUPLEX_HALF; + /* Need to call module detected on initialization since + the module detection triggered by actual module + insertion might occur before driver is loaded, and when + driver is loaded, it reset all registers, including the + transmitter */ + bnx2x_sfp_module_detection(phy, params); - DP(NETIF_MSG_LINK, "Link is up in %dMbps," - " is_duplex_full= %d\n", vars->line_speed, - (vars->duplex == DUPLEX_FULL)); + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + /* Set Flow control */ + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + /* Enable RX-ALARM control to receive + interrupt for 1G speed change */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); - /* Check legacy speed AN resolution */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_STATUS, - &val); - if (val & (1<<5)) - vars->link_status |= - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_EXPANSION, - &val); - if ((val & (1<<0)) == 0) - vars->link_status |= - LINK_STATUS_PARALLEL_DETECTION_USED; - } - } - if (link_up) { - DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", - vars->line_speed); - bnx2x_ext_phy_resolve_fc(phy, params, vars); + } else { /* Default 10G. Set only LASI control */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); } - return link_up; -} + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," + "TX_CTRL2 0x%x\n", + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL1, + phy->tx_preemphasis[0]); -static void bnx2x_link_int_enable(struct link_params *params) -{ - u8 port = params->port; - u32 mask; - struct bnx2x *bp = params->bp; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL2, + phy->tx_preemphasis[1]); + } - /* setting the status to report on link up - for either XGXS or SerDes */ + /* Set GPIO3 to trigger SFP+ module insertion/removal */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); - if (params->switch_cfg == SWITCH_CFG_10G) { - mask = (NIG_MASK_XGXS0_LINK10G | - NIG_MASK_XGXS0_LINK_STATUS); - DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); - if (!(SINGLE_MEDIA_DIRECT(params)) && - params->phy[INT_PHY].type != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) { - mask |= NIG_MASK_MI_INT; - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - } + /* The GPIO should be swapped if the swap register is set and active */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - } else { /* SerDes */ - mask = NIG_MASK_SERDES0_LINK_STATUS; - DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); - if (!(SINGLE_MEDIA_DIRECT(params)) && - params->phy[INT_PHY].type != - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) { - mask |= NIG_MASK_MI_INT; - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - } + /* Select function upon port-swap configuration */ + if (params->port == 0) { + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; + } else { + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; } - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - mask); + val = REG_RD(bp, offset); + /* add GPIO3 to group */ + val |= aeu_gpio_mask; + REG_WR(bp, offset, val); + return 0; - DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, - (params->switch_cfg == SWITCH_CFG_10G), - REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); - DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", - REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), - REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), - REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c)); - DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); } -static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, - u8 is_mi_int) +static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { - u32 latch_status = 0, is_mi_int_status; - /* Disable the MI INT ( external phy int ) - * by writing 1 to the status register. Link down indication - * is high-active-signal, so in this case we need to write the - * status to clear the XOR + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); + /* Set serial boot control for external load */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, 0x0001); +} + +/******************************************************************/ +/* BCM8727 PHY SECTION */ +/******************************************************************/ +static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + u32 swap_val, swap_override; + u8 port; + /** + * The PHY reset is controlled by GPIO 1. Fake the port number + * to cancel the swap done in set_gpio() */ - /* Read Latched signals */ - latch_status = REG_RD(bp, - NIG_REG_LATCH_STATUS_0 + port*8); - is_mi_int_status = REG_RD(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); - DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," - "latch_status = 0x%x\n", - is_mi_int, is_mi_int_status, latch_status); - /* Handle only those with latched-signal=up.*/ - if (latch_status & 1) { - /* For all latched-signal=up,Write original_signal to status */ - if (is_mi_int) - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - else - bnx2x_bits_dis(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - /* For all latched-signal=up : Re-Arm Latch signals */ - REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, - (latch_status & 0xfffe) | (latch_status & 1)); - } + struct bnx2x *bp = params->bp; + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + port = (swap_val && swap_override) ^ 1; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } -/* - * link management - */ -static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g, - u8 is_mi_int) +static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { + u16 tmp1, val, mod_abs; + u16 rx_alarm_ctrl_val; + u16 lasi_ctrl_val; struct bnx2x *bp = params->bp; - u8 port = params->port; + /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ - /* first reset all status - * we assume only one line will be change at a time */ - bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS)); - if ((params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { - bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); - } - if (vars->phy_link_up) { - if (is_10g) { - /* Disable the 10G link interrupt - * by writing 1 to the status register - */ - DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_XGXS0_LINK10G); + bnx2x_wait_reset_complete(bp, phy); + rx_alarm_ctrl_val = (1<<2) | (1<<5) ; + lasi_ctrl_val = 0x0004; - } else if (params->switch_cfg == SWITCH_CFG_10G) { - /* Disable the link interrupt - * by writing 1 to the relevant lane - * in the status register - */ - u32 ser_lane = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + rx_alarm_ctrl_val); - DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", - vars->line_speed); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - ((1 << ser_lane) << - NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); - } else { /* SerDes */ - DP(NETIF_MSG_LINK, "SerDes phy link up\n"); - /* Disable the link interrupt - * by writing 1 to the status register - */ - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_SERDES0_LINK_STATUS); - } + /* Initially configure MOD_ABS to interrupt when + module is presence( bit 8) */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); + /* Set EDC off by setting OPTXLOS signal input to low + (bit 9). + When the EDC is off it locks onto a reference clock and + avoids becoming 'lost'.*/ + mod_abs &= ~((1<<8) | (1<<9)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - } -} -static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) -{ - if (*len < 5) - return -EINVAL; - str[0] = (spirom_ver & 0xFF); - str[1] = (spirom_ver & 0xFF00) >> 8; - str[2] = (spirom_ver & 0xFF0000) >> 16; - str[3] = (spirom_ver & 0xFF000000) >> 24; - str[4] = '\0'; - *len -= 5; - return 0; -} + /* Make MOD_ABS give interrupt on change */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val |= (1<<12); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); + /* Set 8727 GPIOs to input to allow reading from the + 8727 GPIO0 status which reflect SFP+ module + over-current */ -static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) -{ - u8 *str_ptr = str; - u32 mask = 0xf0000000; - u8 shift = 8*4; - u8 digit; - if (*len < 10) { - /* Need more than 10chars for this format */ - *str_ptr = '\0'; - return -EINVAL; - } - while (shift > 0) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val &= 0xff8f; /* Reset bits 4-6 */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - shift -= 4; - digit = ((num & mask) >> shift); - if (digit < 0xa) - *str_ptr = digit + '0'; - else - *str_ptr = digit - 0xa + 'a'; - str_ptr++; - mask = mask >> 4; - if (shift == 4*4) { - *str_ptr = ':'; - str_ptr++; - } + bnx2x_8727_power_module(bp, phy, 1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + + /* Set option 1G speed */ + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); + DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); + } else { + /** + * Since the 8727 has only single reset pin, need to set the 10G + * registers although it is default + */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, + 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, + 0x0008); } - *str_ptr = '\0'; - return 0; -} -static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) -{ - u8 status = 0; - u32 spirom_ver; - spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); - status = bnx2x_format_ver(spirom_ver, str, len); - return status; -} + /* Set 2-wire transfer rate of SFP+ module EEPROM + * to 100Khz since some DACs(direct attached cables) do + * not work at 400Khz. + */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, + 0xa001); -static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) -{ - str[0] = '\0'; - (*len)--; - return 0; -} -u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, - u8 *version, u16 len) -{ - struct bnx2x *bp; - u32 spirom_ver = 0; - u8 status = 0; - u8 *ver_p = version; - if (version == NULL || params == NULL) - return -EINVAL; - bp = params->bp; + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, + phy->tx_preemphasis[0]); - /* Extract first external phy*/ - version[0] = '\0'; - spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, + phy->tx_preemphasis[1]); + } - if (params->phy[EXT_PHY1].format_fw_ver) - status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, - ver_p, - &len); - return status; + return 0; } -static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, + struct link_params *params) { - u8 port = params->port; struct bnx2x *bp = params->bp; + u16 mod_abs, rx_alarm_status; + u32 val = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port]. + config)); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); + if (mod_abs & (1<<8)) { - if (phy->req_line_speed != SPEED_1000) { - u32 md_devad; + /* Module is absent */ + DP(NETIF_MSG_LINK, "MOD_ABS indication " + "show module is absent\n"); - DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); + /* 1. Set mod_abs to detect next module + presence event + 2. Set EDC off by setting OPTXLOS signal input to low + (bit 9). + When the EDC is off it locks onto a reference clock and + avoids becoming 'lost'.*/ + mod_abs &= ~((1<<8)|(1<<9)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - /* change the uni_phy_addr in the nig */ - md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + - port*0x18)); + /* Clear RX alarm since it stays up as long as + the mod_abs wasn't changed */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); + } else { + /* Module is present */ + DP(NETIF_MSG_LINK, "MOD_ABS indication " + "show module is present\n"); + /* First thing, disable transmitter, + and if the module is ok, the + module_detection will enable it*/ + /* 1. Set mod_abs to detect next module + absent event ( bit 8) + 2. Restore the default polarity of the OPRXLOS signal and + this signal will then correctly indicate the presence or + absence of the Rx signal. (bit 9) */ + mod_abs |= ((1<<8)|(1<<9)); bnx2x_cl45_write(bp, phy, - 5, - (MDIO_REG_BANK_AER_BLOCK + - (MDIO_AER_BLOCK_AER_REG & 0xf)), - 0x2800); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - bnx2x_cl45_write(bp, phy, - 5, - (MDIO_REG_BANK_CL73_IEEEB0 + - (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), - 0x6041); - msleep(200); - /* set aer mmd back */ - bnx2x_set_aer_mmd(params, phy); + /* Clear RX alarm since it stays up as long as + the mod_abs wasn't changed. This is need to be done + before calling the module detection, otherwise it will clear + the link update alarm */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); - /* and md_devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, - md_devad); - } else { - u16 mii_ctrl; - DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); - bnx2x_cl45_read(bp, phy, 5, - (MDIO_REG_BANK_COMBO_IEEE0 + - (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), - &mii_ctrl); - bnx2x_cl45_write(bp, phy, 5, - (MDIO_REG_BANK_COMBO_IEEE0 + - (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), - mii_ctrl | - MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK); + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); + else + DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } + + DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", + rx_alarm_status); + /* No need to check link status in case of + module plugged in/out */ } -static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy, - struct link_params *params) +static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) + { struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); + u8 link_up = 0; + u16 link_status = 0; + u16 rx_alarm_status, val1; + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, + &rx_alarm_status); + vars->line_speed = 0; + DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + + DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); + + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); + + /** + * If a module is present and there is need to check + * for over current + */ + if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { + /* Check over-current using 8727 GPIO0 input*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, + &val1); + + if ((val1 & (1<<8)) == 0) { + DP(NETIF_MSG_LINK, "8727 Power fault has been detected" + " on port %d\n", params->port); + netdev_err(bp->dev, "Error: Power fault on Port %d has" + " been detected and the power to " + "that SFP+ module has been removed" + " to prevent failure of the card." + " Please remove the SFP+ module and" + " restart the system to clear this" + " error.\n", + params->port); + + /* + * Disable all RX_ALARMs except for + * mod_abs + */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + /* Wait for module_absent_event */ + val1 |= (1<<8); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, val1); + /* Clear RX alarm */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + return 0; + } + } /* Over current check */ + + /* When module absent bit is set, check module */ + if (rx_alarm_status & (1<<5)) { + bnx2x_8727_handle_mod_abs(phy, params); + /* Enable all mod_abs and link detection bits */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + ((1<<5) | (1<<2))); + } + + /* If transmitter is disabled, ignore false link up indication */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + return 0; + } + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); + + /* Bits 0..2 --> speed detected, + bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); + } + if (link_up) + bnx2x_ext_phy_resolve_fc(phy, params, vars); + return link_up; } -static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, - struct link_params *params) +static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - /* SFX7101_XGXS_TEST1 */ - bnx2x_cl45_write(bp, phy, - MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); + /* Disable Transmitter */ + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); } -/* - *------------------------------------------------------------------------ - * bnx2x_override_led_value - - * - * Override the led value of the requested led - * - *------------------------------------------------------------------------ - */ -u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, - u32 led_idx, u32 value) +/******************************************************************/ +/* BCM8481/BCM84823/BCM84833 PHY SECTION */ +/******************************************************************/ +static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, + struct link_params *params) { - u32 reg_val; + u16 val, fw_ver1, fw_ver2, cnt; + struct bnx2x *bp = params->bp; - /* If port 0 then use EMAC0, else use EMAC1*/ - u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ + /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() port %x led_idx %d value %d\n", - port, led_idx, value); + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + if (val & 1) + break; + udelay(5); + } + if (cnt == 100) { + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); + return; + } - switch (led_idx) { - case 0: /* 10MB led */ - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 10M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : - (reg_val & ~EMAC_LED_10MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 1: /*100MB led */ - /*Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 100M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : - (reg_val & ~EMAC_LED_100MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 2: /* 1000MB led */ - /* Read the current value of the LED register in the - EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 1000M_OVERRIDE bit, otherwise - reset it. */ - reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : - (reg_val & ~EMAC_LED_1000MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 3: /* 2500MB led */ - /* Read the current value of the LED register in the - EMAC block*/ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 2500M_OVERRIDE bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : - (reg_val & ~EMAC_LED_2500MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 4: /*10G led */ - if (port == 0) { - REG_WR(bp, NIG_REG_LED_10G_P0, - value); - } else { - REG_WR(bp, NIG_REG_LED_10G_P1, - value); - } - break; - case 5: /* TRAFFIC led */ - /* Find if the traffic control is via BMAC or EMAC */ - if (port == 0) - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN); - else - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN); - /* Override the traffic led in the EMAC:*/ - if (reg_val == 1) { - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + - EMAC_REG_EMAC_LED); - /* Set the TRAFFIC_OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the TRAFFIC bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) : - (reg_val & ~EMAC_LED_TRAFFIC); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - } else { /* Override the traffic led in the BMAC: */ - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); - REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, - value); - } - break; - default: - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() unknown led index %d " - "(should be 0-5)\n", led_idx); - return -EINVAL; + /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + if (val & 1) + break; + udelay(5); + } + if (cnt == 100) { + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); + return; } - return 0; -} + /* lower 16 bits of the register SPI_FW_STATUS */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); + /* upper 16 bits of register SPI_FW_STATUS */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); + bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, + phy->ver_addr); +} -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) +static void bnx2x_848xx_set_led(struct bnx2x *bp, + struct bnx2x_phy *phy) { - u8 port = params->port; - u16 hw_led_mode = params->hw_led_mode; - u8 rc = 0; - u32 tmp; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); - DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", - speed, hw_led_mode); - switch (mode) { - case LED_MODE_OFF: - REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - SHARED_HW_CFG_LED_MAC1); - - tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); - break; - - case LED_MODE_OPER: - if (SINGLE_MEDIA_DIRECT(params)) { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); - REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); - } else { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); - } + u16 val; - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + - port*4, 0); - /* Set blinking rate to ~15.9Hz */ - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, - LED_BLINK_RATE_VAL); - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + - port*4, 1); - tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, - (tmp & (~EMAC_LED_OVERRIDE))); + /* PHYC_CTL_LED_CTL */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, &val); + val &= 0xFE00; + val |= 0x0092; - if (CHIP_IS_E1(bp) && - ((speed == SPEED_2500) || - (speed == SPEED_1000) || - (speed == SPEED_100) || - (speed == SPEED_10))) { - /* On Everest 1 Ax chip versions for speeds less than - 10G LED scheme is different */ - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); - REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + - port*4, 0); - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + - port*4, 1); - } - break; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, val); - default: - rc = -EINVAL; - DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", - mode); - break; - } - return rc; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x80); -} + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x18); -u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 gp_status = 0, phy_index = 0; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0040); - CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); - /* link is up only if both local phy and external phy are up */ - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - u8 ext_phy_link_up = 1; - struct link_vars temp_vars; - for (phy_index = EXT_PHY1; phy_index < params->num_phys; - phy_index++) { - if (params->phy[phy_index].read_status) - ext_phy_link_up &= - params->phy[phy_index].read_status( - ¶ms->phy[phy_index], - params, &temp_vars); - } - if (ext_phy_link_up) - return 0; - } - return -ESRCH; + /* 'Interrupt Mask' */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + 0xFFFB, 0xFFFD); } -static u8 bnx2x_link_initialize(struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u8 rc = 0; - u8 phy_index, non_ext_phy; struct bnx2x *bp = params->bp; + u16 autoneg_val, an_1000_val, an_10_100_val; /** - * In case of external phy existence, the line speed would be the - * line speed linked up by the external phy. In case it is direct - * only, then the line_speed during initialization will be - * equal to the req_line_speed + * This phy uses the NIG latch mechanism since link indication + * arrives through its LED4 and not via its LASI signal, so we + * get steady signal instead of clear on read */ - vars->line_speed = params->phy[INT_PHY].req_line_speed; + bnx2x_wait_reset_complete(bp, phy); + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, + 1 << NIG_LATCH_BC_ENABLE_MI_INT); - /** - * Initialize the internal phy in case this is a direct board - * (no external phys), or this board has external phy which requires - * to first. - */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); - if (params->phy[INT_PHY].config_init) - params->phy[INT_PHY].config_init( - ¶ms->phy[INT_PHY], - params, vars); + bnx2x_848xx_set_led(bp, phy); - /* init ext phy and enable link state int */ - non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || - (params->loopback_mode == LOOPBACK_XGXS_10)); + /* set 1000 speed advertisement */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + &an_1000_val); - if (non_ext_phy || - (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || - (params->loopback_mode == LOOPBACK_EXT_PHY)) { - struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; - if (vars->line_speed == SPEED_AUTO_NEG) - bnx2x_set_parallel_detection(phy, params); - bnx2x_init_internal_phy(phy, params, vars); - } + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_ADV, + &an_10_100_val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, + &autoneg_val); + /* Disable forced speed */ + autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); + an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); - /* Init external phy*/ - if (!non_ext_phy) - for (phy_index = EXT_PHY1; phy_index < params->num_phys; - phy_index++) { - params->phy[phy_index].config_init( - ¶ms->phy[phy_index], - params, vars); - } + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (phy->req_line_speed == SPEED_1000)) { + an_1000_val |= (1<<8); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_1000_val |= (1<<9); + DP(NETIF_MSG_LINK, "Advertising 1G\n"); + } else + an_1000_val &= ~((1<<8) | (1<<9)); - /* Reset the interrupt indication after phy was initialized */ - bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + - params->port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); - return rc; -} + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + an_1000_val); -static void set_phy_vars(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 actual_phy_idx, phy_index; + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + an_10_100_val |= (1<<7); + /* Enable autoneg and restart autoneg for legacy speeds */ + autoneg_val |= (1<<9 | 1<<12); - for (phy_index = INT_PHY; phy_index < params->num_phys; - phy_index++) { + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<8); + DP(NETIF_MSG_LINK, "Advertising 100M\n"); + } + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<6); + DP(NETIF_MSG_LINK, "Advertising 10M\n"); + } - actual_phy_idx = phy_index; - params->phy[actual_phy_idx].req_flow_ctrl = - params->req_flow_ctrl; + /* Only 10/100 are allowed to work in FORCE mode */ + if (phy->req_line_speed == SPEED_100) { + autoneg_val |= (1<<13); + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 100M force\n"); + } + if (phy->req_line_speed == SPEED_10) { + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 10M force\n"); + } - params->phy[actual_phy_idx].req_line_speed = - params->req_line_speed; + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, + an_10_100_val); - params->phy[actual_phy_idx].speed_cap_mask = - params->speed_cap_mask; + if (phy->req_duplex == DUPLEX_FULL) + autoneg_val |= (1<<8); - params->phy[actual_phy_idx].req_duplex = - params->req_duplex; + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); - DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," - " speed_cap_mask %x\n", - params->phy[actual_phy_idx].req_flow_ctrl, - params->phy[actual_phy_idx].req_line_speed, - params->phy[actual_phy_idx].speed_cap_mask); + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || + (phy->req_line_speed == SPEED_10000)) { + DP(NETIF_MSG_LINK, "Advertising 10G\n"); + /* Restart autoneg for 10G*/ + + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, + 0x3200); + } else if (phy->req_line_speed != SPEED_10 && + phy->req_line_speed != SPEED_100) { + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, + 1); } + /* Save spirom version */ + bnx2x_save_848xx_spirom_version(phy, params); + + return 0; } -u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) +static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - - DP(NETIF_MSG_LINK, "Phy Initialization started\n"); - DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", - params->req_line_speed, params->req_flow_ctrl); - vars->link_status = 0; - vars->phy_link_up = 0; - vars->link_up = 0; - vars->line_speed = 0; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->mac_type = MAC_TYPE_NONE; - vars->phy_flags = 0; - - /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); - - bnx2x_emac_init(params, vars); - - if (params->num_phys == 0) { - DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); - return -EINVAL; - } - set_phy_vars(params); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); - if (CHIP_REV_IS_FPGA(bp)) { + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); - vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); - /* enable on E1.5 FPGA */ - if (CHIP_IS_E1H(bp)) { - vars->flow_ctrl |= - (BNX2X_FLOW_CTRL_TX | - BNX2X_FLOW_CTRL_RX); - vars->link_status |= - (LINK_STATUS_TX_FLOW_CONTROL_ENABLED | - LINK_STATUS_RX_FLOW_CONTROL_ENABLED); - } + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + return bnx2x_848xx_cmn_config_init(phy, params, vars); +} - bnx2x_emac_enable(params, vars, 0); - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); - /* disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); +static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 temp; + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + params->port); + msleep(200); /* 100 is not enough */ - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); + /** + * BCM84823 requires that XGXS links up first @ 10G for normal + * behavior + */ + temp = vars->line_speed; + vars->line_speed = SPEED_10000; + bnx2x_set_autoneg(phy, params, vars, 0); + bnx2x_program_serdes(phy, params, vars); + vars->line_speed = temp; + return bnx2x_848xx_cmn_config_init(phy, params, vars); +} - return 0; +static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val, val1, val2; + u8 link_up = 0; - } else - if (CHIP_REV_IS_EMUL(bp)) { + /* Check 10G-BaseT link status */ + /* Check PMD signal ok */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, 0xFFFA, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, + &val2); + DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); - vars->link_up = 1; + /* Check link 10G */ + if (val2 & (1<<11)) { vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); + link_up = 1; + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + } else { /* Check Legacy speed link */ + u16 legacy_status, legacy_speed; - bnx2x_bmac_enable(params, vars, 0); + /* Enable expansion register 0x42 (Operation mode status) */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); - /* Disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); + /* Get legacy speed operation status */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, + &legacy_status); - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); + DP(NETIF_MSG_LINK, "Legacy speed status" + " = 0x%x\n", legacy_status); + link_up = ((legacy_status & (1<<11)) == (1<<11)); + if (link_up) { + legacy_speed = (legacy_status & (3<<9)); + if (legacy_speed == (0<<9)) + vars->line_speed = SPEED_10; + else if (legacy_speed == (1<<9)) + vars->line_speed = SPEED_100; + else if (legacy_speed == (2<<9)) + vars->line_speed = SPEED_1000; + else /* Should not happen */ + vars->line_speed = 0; - return 0; + if (legacy_status & (1<<8)) + vars->duplex = DUPLEX_FULL; + else + vars->duplex = DUPLEX_HALF; - } else - if (params->loopback_mode == LOOPBACK_BMAC) { - - vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->mac_type = MAC_TYPE_BMAC; - - vars->phy_flags = PHY_XGXS_FLAG; - - bnx2x_xgxs_deassert(params); - - /* set bmac loopback */ - bnx2x_bmac_enable(params, vars, 1); - - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); - - } else if (params->loopback_mode == LOOPBACK_EMAC) { - - vars->link_up = 1; - vars->line_speed = SPEED_1000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->mac_type = MAC_TYPE_EMAC; - - vars->phy_flags = PHY_XGXS_FLAG; - - bnx2x_xgxs_deassert(params); - /* set bmac loopback */ - bnx2x_emac_enable(params, vars, 1); - bnx2x_emac_program(params, vars); - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); - - } else if ((params->loopback_mode == LOOPBACK_XGXS_10) || - (params->loopback_mode == LOOPBACK_EXT_PHY)) { - - vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - vars->phy_flags = PHY_XGXS_FLAG; - - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); - - bnx2x_xgxs_deassert(params); - bnx2x_link_initialize(params, vars); - - vars->mac_type = MAC_TYPE_BMAC; - - bnx2x_bmac_enable(params, vars, 0); - - if (params->loopback_mode == LOOPBACK_XGXS_10) { - /* set 10G XGXS loopback */ - params->phy[INT_PHY].config_loopback( - ¶ms->phy[INT_PHY], - params); - - } else { - /* set external phy loopback */ - u8 phy_index; - for (phy_index = EXT_PHY1; - phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].config_loopback) - params->phy[phy_index].config_loopback( - ¶ms->phy[phy_index], - params); - } + DP(NETIF_MSG_LINK, "Link is up in %dMbps," + " is_duplex_full= %d\n", vars->line_speed, + (vars->duplex == DUPLEX_FULL)); + /* Check legacy speed AN resolution */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_STATUS, + &val); + if (val & (1<<5)) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_EXPANSION, + &val); + if ((val & (1<<0)) == 0) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; } - - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); - - bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); - } else - /* No loopback */ - { - if (params->switch_cfg == SWITCH_CFG_10G) - bnx2x_xgxs_deassert(params); - else - bnx2x_serdes_deassert(bp, params->port); - bnx2x_link_initialize(params, vars); - msleep(30); - bnx2x_link_int_enable(params); } - return 0; -} - + if (link_up) { + DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", + vars->line_speed); + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } -static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, - struct link_params *params) -{ - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); - /* Set serial boot control for external load */ - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, 0x0001); + return link_up; } -static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, - struct link_params *params) +static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) { - struct bnx2x *bp = params->bp; - /* Disable Transmitter */ - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + u8 status = 0; + u32 spirom_ver; + spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); + status = bnx2x_format_ver(spirom_ver, str, len); + return status; } -static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, - struct link_params *params) + +static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { - struct bnx2x *bp = params->bp; - u8 gpio_port; - gpio_port = params->port; - DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", - gpio_port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); } + static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, struct link_params *params) { @@ -5202,460 +5262,207 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, port); } -static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, - struct link_params *params) +/******************************************************************/ +/* SFX7101 PHY SECTION */ +/******************************************************************/ +static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - u8 gpio_port; - /* HW reset */ - gpio_port = params->port; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); - DP(NETIF_MSG_LINK, "reset external PHY\n"); -} - -static void bnx2x_int_link_reset(struct bnx2x_phy *phy, - struct link_params *params) -{ - /* reset the SerDes/XGXS */ - REG_WR(params->bp, GRCBASE_MISC + - MISC_REGISTERS_RESET_REG_3_CLEAR, - (0x1ff << (params->port*16))); + /* SFX7101_XGXS_TEST1 */ + bnx2x_cl45_write(bp, phy, + MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); } -u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, - u8 reset_ext_phy) +static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { + u16 fw_ver1, fw_ver2, val; struct bnx2x *bp = params->bp; - u8 phy_index, port = params->port; - DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); - /* disable attentions */ - vars->link_status = 0; - bnx2x_update_mng(params, vars->link_status); - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); - - /* activate nig drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); - /* disable nig egress interface */ - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_wait_reset_complete(bp, phy); - /* Stop BigMac rx */ - bnx2x_bmac_rx_disable(bp, port); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); + DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + bnx2x_ext_phy_set_pause(params, phy, vars); + /* Restart autoneg */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); + val |= 0x200; + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); - msleep(10); - /* The PHY reset is controled by GPIO 1 - * Hold it as vars low - */ - /* clear link led */ - bnx2x_set_led(params, LED_MODE_OFF, 0); - if (reset_ext_phy) { - for (phy_index = EXT_PHY1; phy_index < params->num_phys; - phy_index++) { - if (params->phy[phy_index].link_reset) - params->phy[phy_index].link_reset( - ¶ms->phy[phy_index], - params); - } - } + /* Save spirom version */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); - if (params->phy[INT_PHY].link_reset) - params->phy[INT_PHY].link_reset( - ¶ms->phy[INT_PHY], params); - /* reset BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); + bnx2x_save_spirom_version(bp, params->port, + (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); + return 0; +} - /* disable nig ingress interface */ - REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - vars->link_up = 0; - return 0; -} - -static u8 bnx2x_update_link_down(struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port = params->port; - - DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); - bnx2x_set_led(params, LED_MODE_OFF, 0); - - /* indicate no mac active */ - vars->mac_type = MAC_TYPE_NONE; - - /* update shared memory */ - vars->link_status = 0; - vars->line_speed = 0; - bnx2x_update_mng(params, vars->link_status); - - /* activate nig drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - - /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + u8 link_up; + u16 val1, val2; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", + val2, val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", + val2, val1); + link_up = ((val1 & 4) == 4); + /* if link is up + * print the AN outcome of the SFX7101 PHY + */ + if (link_up) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, + &val2); + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", + val2, (val2 & (1<<14))); + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; +} - msleep(10); - /* reset BigMac */ - bnx2x_bmac_rx_disable(bp, params->port); - REG_WR(bp, GRCBASE_MISC + - MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); +static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) +{ + if (*len < 5) + return -EINVAL; + str[0] = (spirom_ver & 0xFF); + str[1] = (spirom_ver & 0xFF00) >> 8; + str[2] = (spirom_ver & 0xFF0000) >> 16; + str[3] = (spirom_ver & 0xFF000000) >> 24; + str[4] = '\0'; + *len -= 5; return 0; } -static u8 bnx2x_update_link_up(struct link_params *params, - struct link_vars *vars, - u8 link_10g) +void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 rc = 0; - - vars->link_status |= LINK_STATUS_LINK_UP; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - vars->link_status |= - LINK_STATUS_TX_FLOW_CONTROL_ENABLED; + u16 val, cnt; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - vars->link_status |= - LINK_STATUS_RX_FLOW_CONTROL_ENABLED; - if (link_10g) { - bnx2x_bmac_enable(params, vars, 0); - bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); - } else { - rc = bnx2x_emac_program(params, vars); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); - bnx2x_emac_enable(params, vars, 0); + for (cnt = 0; cnt < 10; cnt++) { + msleep(50); + /* Writes a self-clearing reset */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, + (val | (1<<15))); + /* Wait for clear */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); - /* AN complete? */ - if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) - && (!(vars->phy_flags & PHY_SGMII_FLAG)) && - SINGLE_MEDIA_DIRECT(params)) - bnx2x_set_gmii_tx_driver(params); + if ((val & (1<<15)) == 0) + break; } - - /* PBF - link up */ - rc |= bnx2x_pbf_update(params, vars->flow_ctrl, - vars->line_speed); - - /* disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); - - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); - msleep(20); - return rc; } -/** - * The bnx2x_link_update function should be called upon link - * interrupt. - * Link is considered up as follows: - * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs - * to be up - * - SINGLE_MEDIA - The link between the 577xx and the external - * phy (XGXS) need to up as well as the external link of the - * phy (PHY_EXT1) - * - DUAL_MEDIA - The link between the 577xx and the first - * external phy needs to be up, and at least one of the 2 - * external phy link must be up. - */ -u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - struct link_vars phy_vars[MAX_PHYS]; - u8 port = params->port; - u8 link_10g, phy_index; - u8 ext_phy_link_up = 0, cur_link_up, rc = 0; - u8 is_mi_int = 0; - u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; - u8 active_external_phy = INT_PHY; - vars->link_status = 0; - for (phy_index = INT_PHY; phy_index < params->num_phys; - phy_index++) { - phy_vars[phy_index].flow_ctrl = 0; - phy_vars[phy_index].link_status = 0; - phy_vars[phy_index].line_speed = 0; - phy_vars[phy_index].duplex = DUPLEX_FULL; - phy_vars[phy_index].phy_link_up = 0; - phy_vars[phy_index].link_up = 0; - } - DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", - port, (vars->phy_flags & PHY_XGXS_FLAG), - REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); +static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + /* Low power mode is controlled by GPIO 2 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); + /* The PHY reset is controlled by GPIO 1 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); +} - is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + - port*0x18) > 0); - DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", - REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), - is_mi_int, - REG_RD(bp, - NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); +/******************************************************************/ +/* STATIC PHY DECLARATION */ +/******************************************************************/ - DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); +static struct bnx2x_phy phy_null = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, + .addr = 0, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = 0, + .media_type = ETH_PHY_NOT_PRESENT, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)NULL, + .read_status = (read_status_t)NULL, + .link_reset = (link_reset_t)NULL, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; - /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - - /** - * Step 1: - * Check external link change only for external phys, and apply - * priority selection between them in case the link on both phys - * is up. Note that the instead of the common vars, a temporary - * vars argument is used since each phy may have different link/ - * speed/duplex result - */ - for (phy_index = EXT_PHY1; phy_index < params->num_phys; - phy_index++) { - struct bnx2x_phy *phy = ¶ms->phy[phy_index]; - if (!phy->read_status) - continue; - /* Read link status and params of this ext phy */ - cur_link_up = phy->read_status(phy, params, - &phy_vars[phy_index]); - if (cur_link_up) { - DP(NETIF_MSG_LINK, "phy in index %d link is up\n", - phy_index); - } else { - DP(NETIF_MSG_LINK, "phy in index %d link is down\n", - phy_index); - continue; - } - - if (!ext_phy_link_up) { - ext_phy_link_up = 1; - active_external_phy = phy_index; - } - } - prev_line_speed = vars->line_speed; - /** - * Step 2: - * Read the status of the internal phy. In case of - * DIRECT_SINGLE_MEDIA board, this link is the external link, - * otherwise this is the link between the 577xx and the first - * external phy - */ - if (params->phy[INT_PHY].read_status) - params->phy[INT_PHY].read_status( - ¶ms->phy[INT_PHY], - params, vars); - /** - * The INT_PHY flow control reside in the vars. This include the - * case where the speed or flow control are not set to AUTO. - * Otherwise, the active external phy flow control result is set - * to the vars. The ext_phy_line_speed is needed to check if the - * speed is different between the internal phy and external phy. - * This case may be result of intermediate link speed change. - */ - if (active_external_phy > INT_PHY) { - vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; - /** - * Link speed is taken from the XGXS. AN and FC result from - * the external phy. - */ - vars->link_status |= phy_vars[active_external_phy].link_status; - ext_phy_line_speed = phy_vars[active_external_phy].line_speed; - vars->duplex = phy_vars[active_external_phy].duplex; - if (params->phy[active_external_phy].supported & - SUPPORTED_FIBRE) - vars->link_status |= LINK_STATUS_SERDES_LINK; - DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", - active_external_phy); - } - DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," - " ext_phy_line_speed = %d\n", vars->flow_ctrl, - vars->link_status, ext_phy_line_speed); - /** - * Upon link speed change set the NIG into drain mode. Comes to - * deals with possible FIFO glitch due to clk change when speed - * is decreased without link down indicator - */ - - if (vars->phy_link_up) { - if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up && - (ext_phy_line_speed != vars->line_speed)) { - DP(NETIF_MSG_LINK, "Internal link speed %d is" - " different than the external" - " link speed %d\n", vars->line_speed, - ext_phy_line_speed); - vars->phy_link_up = 0; - } else if (prev_line_speed != vars->line_speed) { - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); - msleep(1); - } - } - - /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); - - bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); - - /** - * In case external phy link is up, and internal link is down - * (not initialized yet probably after link initialization, it - * needs to be initialized. - * Note that after link down-up as result of cable plug, the xgxs - * link would probably become up again without the need - * initialize it - */ - if (!(SINGLE_MEDIA_DIRECT(params))) { - DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," - " init_preceding = %d\n", ext_phy_link_up, - vars->phy_link_up, - params->phy[EXT_PHY1].flags & - FLAGS_INIT_XGXS_FIRST); - if (!(params->phy[EXT_PHY1].flags & - FLAGS_INIT_XGXS_FIRST) - && ext_phy_link_up && !vars->phy_link_up) { - vars->line_speed = ext_phy_line_speed; - if (vars->line_speed < SPEED_1000) - vars->phy_flags |= PHY_SGMII_FLAG; - else - vars->phy_flags &= ~PHY_SGMII_FLAG; - bnx2x_init_internal_phy(¶ms->phy[INT_PHY], - params, - vars); - } - } - /** - * Link is up only if both local phy and external phy (in case of - * non-direct board) are up - */ - vars->link_up = (vars->phy_link_up && - (ext_phy_link_up || - SINGLE_MEDIA_DIRECT(params))); - - if (vars->link_up) - rc = bnx2x_update_link_up(params, vars, link_10g); - else - rc = bnx2x_update_link_down(params, vars); - - return rc; -} - -static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, - struct link_params *params) -{ - bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); - bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); -} - -static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, - struct link_params *params) { - u32 swap_val, swap_override; - u8 port; - /** - * The PHY reset is controlled by GPIO 1. Fake the port number - * to cancel the swap done in set_gpio() - */ - struct bnx2x *bp = params->bp; - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - port = (swap_val && swap_override) ^ 1; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); -} - -static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, - struct link_params *params) { - /* Low power mode is controlled by GPIO 2 */ - bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); - /* The PHY reset is controlled by GPIO 1 */ - bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); -} -/******************************************************************/ -/* STATIC PHY DECLARATION */ -/******************************************************************/ - -static struct bnx2x_phy phy_null = { - .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, - .addr = 0, - .flags = FLAGS_INIT_XGXS_FIRST, - .def_md_devad = 0, - .reserved = 0, - .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .mdio_ctrl = 0, - .supported = 0, - .media_type = ETH_PHY_NOT_PRESENT, - .ver_addr = 0, - .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, - .req_duplex = 0, - .rsrv = 0, - .config_init = (config_init_t)NULL, - .read_status = (read_status_t)NULL, - .link_reset = (link_reset_t)NULL, - .config_loopback = (config_loopback_t)NULL, - .format_fw_ver = (format_fw_ver_t)NULL, - .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL -}; - -static struct bnx2x_phy phy_serdes = { - .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, - .addr = 0xff, - .flags = 0, - .def_md_devad = 0, - .reserved = 0, - .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .mdio_ctrl = 0, - .supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_UNSPECIFIED, - .ver_addr = 0, - .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, - .req_duplex = 0, - .rsrv = 0, - .config_init = (config_init_t)bnx2x_init_serdes, - .read_status = (read_status_t)bnx2x_link_settings_status, - .link_reset = (link_reset_t)bnx2x_int_link_reset, - .config_loopback = (config_loopback_t)NULL, - .format_fw_ver = (format_fw_ver_t)NULL, - .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL -}; +static struct bnx2x_phy phy_serdes = { + .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .flags = 0, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_init_serdes, + .read_status = (read_status_t)bnx2x_link_settings_status, + .link_reset = (link_reset_t)bnx2x_int_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; static struct bnx2x_phy phy_xgxs = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, @@ -5854,7 +5661,6 @@ static struct bnx2x_phy phy_8727 = { .mdio_ctrl = 0, .supported = (SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_Pause | SUPPORTED_Asym_Pause), @@ -5908,338 +5714,603 @@ static struct bnx2x_phy phy_8481 = { .set_link_led = (set_link_led_t)NULL }; -static struct bnx2x_phy phy_84823 = { - .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, - .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, - .def_md_devad = 0, - .reserved = 0, - .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, - .mdio_ctrl = 0, - .supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause), - .media_type = ETH_PHY_BASE_T, - .ver_addr = 0, - .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, - .req_duplex = 0, - .rsrv = 0, - .config_init = (config_init_t)bnx2x_848x3_config_init, - .read_status = (read_status_t)bnx2x_848xx_read_status, - .link_reset = (link_reset_t)bnx2x_848x3_link_reset, - .config_loopback = (config_loopback_t)NULL, - .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, - .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL -}; +static struct bnx2x_phy phy_84823 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_848x3_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_848x3_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL +}; + +/*****************************************************************/ +/* */ +/* Populate the phy according. Main function: bnx2x_populate_phy */ +/* */ +/*****************************************************************/ + +static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, + struct bnx2x_phy *phy, u8 port, + u8 phy_index) +{ + /* Get the 4 lanes xgxs config rx and tx */ + u32 rx = 0, tx = 0, i; + for (i = 0; i < 2; i++) { + /** + * INT_PHY and EXT_PHY1 share the same value location in the + * shmem. When num_phys is greater than 1, than this value + * applies only to EXT_PHY1 + */ + + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + + phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); + phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); + + phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff); + phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff); + } +} + +static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, + u8 phy_index, u8 port) +{ + u32 ext_phy_config = 0; + switch (phy_index) { + case EXT_PHY1: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config)); + break; + default: + DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); + return -EINVAL; + } + + return ext_phy_config; +} +static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, + struct bnx2x_phy *phy) +{ + u32 phy_addr; + u32 chip_id; + u32 switch_cfg = (REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_feature_config[port].link_config)) & + PORT_FEATURE_CONNECTED_SWITCH_MASK); + chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; + switch (switch_cfg) { + case SWITCH_CFG_1G: + phy_addr = REG_RD(bp, + NIG_REG_SERDES0_CTRL_PHY_ADDR + + port * 0x10); + *phy = phy_serdes; + break; + case SWITCH_CFG_10G: + phy_addr = REG_RD(bp, + NIG_REG_XGXS0_CTRL_PHY_ADDR + + port * 0x18); + *phy = phy_xgxs; + break; + default: + DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); + return -EINVAL; + } + phy->addr = (u8)phy_addr; + phy->mdio_ctrl = bnx2x_get_emac_base(bp, + SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, + port); + phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; + + DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", + port, phy->addr, phy->mdio_ctrl); + + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY); + return 0; +} + +static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, + u8 phy_index, + u32 shmem_base, + u8 port, + struct bnx2x_phy *phy) +{ + u32 ext_phy_config, phy_type, config2; + u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; + ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, + phy_index, port); + phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + /* Select the phy type */ + switch (phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; + *phy = phy_8073; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + *phy = phy_8705; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + *phy = phy_8706; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8726; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: + /* BCM8727_NOC => BCM8727 no over current */ + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8727; + phy->flags |= FLAGS_NOC; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8727; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + *phy = phy_8481; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + *phy = phy_84823; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + *phy = phy_7101; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + *phy = phy_null; + return -EINVAL; + default: + *phy = phy_null; + return 0; + } + + phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); + + /** + * The shmem address of the phy version is located on different + * structures. In case this structure is too old, do not set + * the address + */ + config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, + dev_info.shared_hw_config.config2)); + + phy->ver_addr = shmem_base + offsetof(struct shmem_region, + port_mb[port].ext_phy_fw_version); + + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) + mdc_mdio_access = config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + + phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); + + /** + * In case mdc/mdio_access of the external phy is different than the + * mdc/mdio access of the XGXS, a HW lock must be taken in each access + * to prevent one port interfere with another port's CL45 operations. + */ + if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) + phy->flags |= FLAGS_HW_LOCK_REQUIRED; + DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", + phy_type, port, phy_index); + DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", + phy->addr, phy->mdio_ctrl); + return 0; +} + +static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u8 port, struct bnx2x_phy *phy) +{ + u8 status = 0; + phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; + if (phy_index == INT_PHY) + return bnx2x_populate_int_phy(bp, shmem_base, port, phy); + status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, + port, phy); + return status; +} + +static void bnx2x_phy_def_cfg(struct link_params *params, + struct bnx2x_phy *phy, + u8 actual_phy_idx) +{ + struct bnx2x *bp = params->bp; + u32 link_config; + /* Populate the default phy configuration for MF mode */ + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask)); + + phy->req_duplex = DUPLEX_FULL; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_10M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_10M_FULL: + phy->req_line_speed = SPEED_10; + break; + case PORT_FEATURE_LINK_SPEED_100M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_100M_FULL: + phy->req_line_speed = SPEED_100; + break; + case PORT_FEATURE_LINK_SPEED_1G: + phy->req_line_speed = SPEED_1000; + break; + case PORT_FEATURE_LINK_SPEED_2_5G: + phy->req_line_speed = SPEED_2500; + break; + case PORT_FEATURE_LINK_SPEED_10G_CX4: + phy->req_line_speed = SPEED_10000; + break; + default: + phy->req_line_speed = SPEED_AUTO_NEG; + break; + } + + switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) { + case PORT_FEATURE_FLOW_CONTROL_AUTO: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + break; + case PORT_FEATURE_FLOW_CONTROL_TX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX; + break; + case PORT_FEATURE_FLOW_CONTROL_RX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX; + break; + case PORT_FEATURE_FLOW_CONTROL_BOTH: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + break; + default: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + break; + } +} + +u8 bnx2x_phy_probe(struct link_params *params) +{ + u8 phy_index, actual_phy_idx, link_cfg_idx; + + struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy; + params->num_phys = 0; + DP(NETIF_MSG_LINK, "Begin phy probe\n"); + + for (phy_index = INT_PHY; phy_index < MAX_PHYS; + phy_index++) { + link_cfg_idx = LINK_CONFIG_IDX(phy_index); + actual_phy_idx = phy_index; + + phy = ¶ms->phy[actual_phy_idx]; + if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, + params->port, + phy) != 0) { + params->num_phys = 0; + DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", + phy_index); + for (phy_index = INT_PHY; + phy_index < MAX_PHYS; + phy_index++) + *phy = phy_null; + return -EINVAL; + } + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) + break; + + bnx2x_phy_def_cfg(params, phy, actual_phy_idx); + params->num_phys++; + } + + DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys); + return 0; +} + +u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) +{ + if (phy_idx < params->num_phys) + return params->phy[phy_idx].supported; + return 0; +} + +static void set_phy_vars(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 actual_phy_idx, phy_index; + + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + + actual_phy_idx = phy_index; + params->phy[actual_phy_idx].req_flow_ctrl = + params->req_flow_ctrl; + + params->phy[actual_phy_idx].req_line_speed = + params->req_line_speed; + + params->phy[actual_phy_idx].speed_cap_mask = + params->speed_cap_mask; + + params->phy[actual_phy_idx].req_duplex = + params->req_duplex; + + DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," + " speed_cap_mask %x\n", + params->phy[actual_phy_idx].req_flow_ctrl, + params->phy[actual_phy_idx].req_line_speed, + params->phy[actual_phy_idx].speed_cap_mask); + } +} + +u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 val; + + DP(NETIF_MSG_LINK, "Phy Initialization started\n"); + DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", + params->req_line_speed, params->req_flow_ctrl); + vars->link_status = 0; + vars->phy_link_up = 0; + vars->link_up = 0; + vars->line_speed = 0; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_NONE; + vars->phy_flags = 0; + + /* disable attentions */ + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); + + bnx2x_emac_init(params, vars); + + if (params->num_phys == 0) { + DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); + return -EINVAL; + } + set_phy_vars(params); + + DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); + if (CHIP_REV_IS_FPGA(bp)) { + + vars->link_up = 1; + vars->line_speed = SPEED_10000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); + /* enable on E1.5 FPGA */ + if (CHIP_IS_E1H(bp)) { + vars->flow_ctrl |= + (BNX2X_FLOW_CTRL_TX | + BNX2X_FLOW_CTRL_RX); + vars->link_status |= + (LINK_STATUS_TX_FLOW_CONTROL_ENABLED | + LINK_STATUS_RX_FLOW_CONTROL_ENABLED); + } + + bnx2x_emac_enable(params, vars, 0); + bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); + /* disable drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); + + /* update shared memory */ + bnx2x_update_mng(params, vars->link_status); + + return 0; + + } else + if (CHIP_REV_IS_EMUL(bp)) { + + vars->link_up = 1; + vars->line_speed = SPEED_10000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); + + bnx2x_bmac_enable(params, vars, 0); + + bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); + /* Disable drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + + /* update shared memory */ + bnx2x_update_mng(params, vars->link_status); + + return 0; + + } else + if (params->loopback_mode == LOOPBACK_BMAC) { + + vars->link_up = 1; + vars->line_speed = SPEED_10000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_BMAC; -/*****************************************************************/ -/* */ -/* Populate the phy according. Main function: bnx2x_populate_phy */ -/* */ -/*****************************************************************/ + vars->phy_flags = PHY_XGXS_FLAG; -static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, - struct bnx2x_phy *phy, u8 port, - u8 phy_index) -{ - /* Get the 4 lanes xgxs config rx and tx */ - u32 rx = 0, tx = 0, i; - for (i = 0; i < 2; i++) { - /** - * INT_PHY and EXT_PHY1 share the same value location in the - * shmem. When num_phys is greater than 1, than this value - * applies only to EXT_PHY1 - */ + bnx2x_xgxs_deassert(params); - rx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + /* set bmac loopback */ + bnx2x_bmac_enable(params, vars, 1); - tx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); - phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); - phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); + } else if (params->loopback_mode == LOOPBACK_EMAC) { - phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff); - phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff); - } -} + vars->link_up = 1; + vars->line_speed = SPEED_1000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + vars->mac_type = MAC_TYPE_EMAC; -static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, - u8 phy_index, u8 port) -{ - u32 ext_phy_config = 0; - switch (phy_index) { - case EXT_PHY1: - ext_phy_config = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].external_phy_config)); - break; - default: - DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); - return -EINVAL; - } + vars->phy_flags = PHY_XGXS_FLAG; - return ext_phy_config; -} -static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, - struct bnx2x_phy *phy) -{ - u32 phy_addr; - u32 chip_id; - u32 switch_cfg = (REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_feature_config[port].link_config)) & - PORT_FEATURE_CONNECTED_SWITCH_MASK); - chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; - switch (switch_cfg) { - case SWITCH_CFG_1G: - phy_addr = REG_RD(bp, - NIG_REG_SERDES0_CTRL_PHY_ADDR + - port * 0x10); - *phy = phy_serdes; - break; - case SWITCH_CFG_10G: - phy_addr = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR + - port * 0x18); - *phy = phy_xgxs; - break; - default: - DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); - return -EINVAL; - } - phy->addr = (u8)phy_addr; - phy->mdio_ctrl = bnx2x_get_emac_base(bp, - SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, - port); - phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; + bnx2x_xgxs_deassert(params); + /* set bmac loopback */ + bnx2x_emac_enable(params, vars, 1); + bnx2x_emac_program(params, vars); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); - DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", - port, phy->addr, phy->mdio_ctrl); + } else if ((params->loopback_mode == LOOPBACK_XGXS) || + (params->loopback_mode == LOOPBACK_EXT_PHY)) { - bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY); - return 0; -} + vars->link_up = 1; + vars->line_speed = SPEED_10000; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; -static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, - u8 phy_index, - u32 shmem_base, - u8 port, - struct bnx2x_phy *phy) -{ - u32 ext_phy_config, phy_type, config2; - u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; - ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, - phy_index, port); - phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); - /* Select the phy type */ - switch (phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; - *phy = phy_8073; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - *phy = phy_8705; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - *phy = phy_8706; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; - *phy = phy_8726; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: - /* BCM8727_NOC => BCM8727 no over current */ - mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; - *phy = phy_8727; - phy->flags |= FLAGS_NOC; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; - *phy = phy_8727; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - *phy = phy_8481; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - *phy = phy_84823; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - *phy = phy_7101; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - *phy = phy_null; - return -EINVAL; - default: - *phy = phy_null; - return 0; - } + vars->phy_flags = PHY_XGXS_FLAG; - phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); - bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); + val = REG_RD(bp, + NIG_REG_XGXS0_CTRL_PHY_ADDR+ + params->port*0x18); - /** - * The shmem address of the phy version is located on different - * structures. In case this structure is too old, do not set - * the address - */ - config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, - dev_info.shared_hw_config.config2)); + bnx2x_xgxs_deassert(params); + bnx2x_link_initialize(params, vars); - phy->ver_addr = shmem_base + offsetof(struct shmem_region, - port_mb[port].ext_phy_fw_version); + vars->mac_type = MAC_TYPE_BMAC; - /* Check specific mdc mdio settings */ - if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) - mdc_mdio_access = config2 & - SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + bnx2x_bmac_enable(params, vars, 0); - phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); + if (params->loopback_mode == LOOPBACK_XGXS) { + /* set 10G XGXS loopback */ + params->phy[INT_PHY].config_loopback( + ¶ms->phy[INT_PHY], + params); - /** - * In case mdc/mdio_access of the external phy is different than the - * mdc/mdio access of the XGXS, a HW lock must be taken in each access - * to prevent one port interfere with another port's CL45 operations. - */ - if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) - phy->flags |= FLAGS_HW_LOCK_REQUIRED; - DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", - phy_type, port, phy_index); - DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", - phy->addr, phy->mdio_ctrl); + } else { + /* set external phy loopback */ + u8 phy_index; + for (phy_index = EXT_PHY1; + phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].config_loopback) + params->phy[phy_index].config_loopback( + ¶ms->phy[phy_index], + params); + } + } + + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + + bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); + } else + /* No loopback */ + { + if (params->switch_cfg == SWITCH_CFG_10G) + bnx2x_xgxs_deassert(params); + else + bnx2x_serdes_deassert(bp, params->port); + bnx2x_link_initialize(params, vars); + msleep(30); + bnx2x_link_int_enable(params); + } return 0; } - -static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, - u8 port, struct bnx2x_phy *phy) -{ - u8 status = 0; - phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; - if (phy_index == INT_PHY) - return bnx2x_populate_int_phy(bp, shmem_base, port, phy); - status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, - port, phy); - return status; -} - -static void bnx2x_phy_def_cfg(struct link_params *params, - struct bnx2x_phy *phy, - u8 actual_phy_idx) +u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, + u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u32 link_config; - /* Populate the default phy configuration for MF mode */ - link_config = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port].link_config)); - phy->speed_cap_mask = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_hw_config[params->port].speed_capability_mask)); - - phy->req_duplex = DUPLEX_FULL; - switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { - case PORT_FEATURE_LINK_SPEED_10M_HALF: - phy->req_duplex = DUPLEX_HALF; - case PORT_FEATURE_LINK_SPEED_10M_FULL: - phy->req_line_speed = SPEED_10; - break; - case PORT_FEATURE_LINK_SPEED_100M_HALF: - phy->req_duplex = DUPLEX_HALF; - case PORT_FEATURE_LINK_SPEED_100M_FULL: - phy->req_line_speed = SPEED_100; - break; - case PORT_FEATURE_LINK_SPEED_1G: - phy->req_line_speed = SPEED_1000; - break; - case PORT_FEATURE_LINK_SPEED_2_5G: - phy->req_line_speed = SPEED_2500; - break; - case PORT_FEATURE_LINK_SPEED_10G_CX4: - phy->req_line_speed = SPEED_10000; - break; - default: - phy->req_line_speed = SPEED_AUTO_NEG; - break; - } + u8 phy_index, port = params->port; + DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); + /* disable attentions */ + vars->link_status = 0; + bnx2x_update_mng(params, vars->link_status); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); - switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) { - case PORT_FEATURE_FLOW_CONTROL_AUTO: - phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; - break; - case PORT_FEATURE_FLOW_CONTROL_TX: - phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX; - break; - case PORT_FEATURE_FLOW_CONTROL_RX: - phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX; - break; - case PORT_FEATURE_FLOW_CONTROL_BOTH: - phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH; - break; - default: - phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; - break; - } -} + /* activate nig drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); -u8 bnx2x_phy_probe(struct link_params *params) -{ - u8 phy_index, actual_phy_idx, link_cfg_idx; + /* disable nig egress interface */ + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - struct bnx2x *bp = params->bp; - struct bnx2x_phy *phy; - params->num_phys = 0; - DP(NETIF_MSG_LINK, "Begin phy probe\n"); + /* Stop BigMac rx */ + bnx2x_bmac_rx_disable(bp, port); - for (phy_index = INT_PHY; phy_index < MAX_PHYS; - phy_index++) { - link_cfg_idx = LINK_CONFIG_IDX(phy_index); - actual_phy_idx = phy_index; + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - phy = ¶ms->phy[actual_phy_idx]; - if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, - params->port, - phy) != 0) { - params->num_phys = 0; - DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", - phy_index); - for (phy_index = INT_PHY; - phy_index < MAX_PHYS; - phy_index++) - *phy = phy_null; - return -EINVAL; + msleep(10); + /* The PHY reset is controled by GPIO 1 + * Hold it as vars low + */ + /* clear link led */ + bnx2x_set_led(params, LED_MODE_OFF, 0); + if (reset_ext_phy) { + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].link_reset) + params->phy[phy_index].link_reset( + ¶ms->phy[phy_index], + params); } - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) - break; - - bnx2x_phy_def_cfg(params, phy, actual_phy_idx); - params->num_phys++; } - DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys); - return 0; -} + if (params->phy[INT_PHY].link_reset) + params->phy[INT_PHY].link_reset( + ¶ms->phy[INT_PHY], params); + /* reset BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); -u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) -{ - if (phy_idx < params->num_phys) - return params->phy[phy_idx].supported; + /* disable nig ingress interface */ + REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); + REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + vars->link_up = 0; return 0; } +/****************************************************************************/ +/* Common function */ +/****************************************************************************/ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) { struct bnx2x_phy phy[PORT_MAX]; @@ -6348,6 +6419,43 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) +{ + u32 val; + s8 port; + struct bnx2x_phy phy; + /* Use port1 because of the static port-swap */ + /* Enable the module detection interrupt */ + val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); + val |= ((1<link_params.loopback_mode = LOOPBACK_XGXS_10; + bp->link_params.loopback_mode = LOOPBACK_XGXS; rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); -- cgit v1.2.3 From a22f078867ef362e35c54055878168e6613ff743 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:20 +0000 Subject: bnx2x: Add dual-media changes Add required changes in order to support dual-media boards. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 10 +- drivers/net/bnx2x/bnx2x_cmn.c | 14 +- drivers/net/bnx2x/bnx2x_cmn.h | 3 +- drivers/net/bnx2x/bnx2x_ethtool.c | 176 +++++++--- drivers/net/bnx2x/bnx2x_hsi.h | 111 +++++- drivers/net/bnx2x/bnx2x_link.c | 695 +++++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_link.h | 62 ++-- drivers/net/bnx2x/bnx2x_main.c | 354 ++++++++++++------- drivers/net/bnx2x/bnx2x_reg.h | 25 ++ 9 files changed, 1074 insertions(+), 376 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index a019c67d2995..137187684f27 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -566,13 +566,13 @@ struct bnx2x_common { struct bnx2x_port { u32 pmf; - u32 link_config; + u32 link_config[LINK_CONFIG_SIZE]; - u32 supported; + u32 supported[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define SUPPORTED_2500baseX_Full (1 << 15) - u32 advertising; + u32 advertising[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define ADVERTISED_2500baseX_Full (1 << 15) @@ -931,7 +931,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command); +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, u32 addr, u32 len); @@ -939,7 +939,7 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); void bnx2x_update_coalesce(struct bnx2x *bp); - +int bnx2x_get_link_cfg_idx(struct bnx2x *bp); static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) { diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 0e4caf411905..7f1d291eaaa5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1283,7 +1283,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) common blocks should be initialized, otherwise - not */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; @@ -1322,9 +1322,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_init_hw(bp, load_code); if (rc) { BNX2X_ERR("HW init failed, aborting\n"); - bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); goto load_error2; } @@ -1339,7 +1339,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Send LOAD_DONE command to MCP */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; @@ -1455,8 +1455,8 @@ load_error4: load_error3: bnx2x_int_disable_sync(bp, 1); if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } bp->port.pmf = 0; /* Free SKBs, SGEs, TPA pool and driver internals */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 32543c32805c..d1e6a8c977d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -49,10 +49,11 @@ void bnx2x_link_set(struct bnx2x *bp); * Query link status * * @param bp + * @param is_serdes * * @return 0 - link is UP */ -u8 bnx2x_link_test(struct bnx2x *bp); +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); /** * Handles link status change diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index dbcfa7a5618f..d058f9716785 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -29,9 +29,12 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - - cmd->supported = bp->port.supported; - cmd->advertising = bp->port.advertising; + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Dual Media boards present all available port types */ + cmd->supported = bp->port.supported[cfg_idx] | + (bp->port.supported[cfg_idx ^ 1] & + (SUPPORTED_TP | SUPPORTED_FIBRE)); + cmd->advertising = bp->port.advertising[cfg_idx]; if ((bp->state == BNX2X_STATE_OPEN) && !(bp->flags & MF_FUNC_DIS) && @@ -48,22 +51,21 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->speed = vn_max_rate; } } else { - cmd->speed = -1; - cmd->duplex = -1; + cmd->speed = bp->link_params.req_line_speed[cfg_idx]; + cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } - if (bp->link_params.num_phys > 0) { - if (bp->link_params.phy[bp->link_params.num_phys - 1]. - supported & SUPPORTED_FIBRE) - cmd->port = PORT_FIBRE; - else - cmd->port = PORT_TP; - } else - DP(NETIF_MSG_LINK, "No media found\n"); + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) + cmd->port = PORT_TP; + else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + cmd->port = PORT_FIBRE; + else + BNX2X_ERR("XGXS PHY Failure detected\n"); + cmd->phy_address = bp->mdio.prtad; cmd->transceiver = XCVR_INTERNAL; - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) cmd->autoneg = AUTONEG_ENABLE; else cmd->autoneg = AUTONEG_DISABLE; @@ -85,7 +87,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - u32 advertising; + u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; if (IS_E1HMF(bp)) return 0; @@ -98,26 +100,81 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + cfg_idx = bnx2x_get_link_cfg_idx(bp); + old_multi_phy_config = bp->link_params.multi_phy_config; + switch (cmd->port) { + case PORT_TP: + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_TP || + bp->port.supported[1] & SUPPORTED_TP)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_FIBRE: + if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_FIBRE || + bp->port.supported[1] & SUPPORTED_FIBRE)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + default: + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + /* Save new config in case command complete successuly */ + new_multi_phy_config = bp->link_params.multi_phy_config; + /* Get the new cfg_idx */ + cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Restore old config in case command failed */ + bp->link_params.multi_phy_config = old_multi_phy_config; + DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx); + if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "Autoneg not supported\n"); return -EINVAL; } /* advertise the requested speed and duplex if supported */ - cmd->advertising &= bp->port.supported; + cmd->advertising &= bp->port.supported[cfg_idx]; - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->link_params.req_duplex = DUPLEX_FULL; - bp->port.advertising |= (ADVERTISED_Autoneg | + bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG; + bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL; + bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg | cmd->advertising); } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ - switch (cmd->speed) { + u32 speed = cmd->speed; + speed |= (cmd->speed_hi << 16); + switch (speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Full)) { DP(NETIF_MSG_LINK, "10M full not supported\n"); @@ -127,7 +184,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Half)) { DP(NETIF_MSG_LINK, "10M half not supported\n"); @@ -141,7 +198,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) case SPEED_100: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Full)) { DP(NETIF_MSG_LINK, "100M full not supported\n"); @@ -151,7 +208,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Half)) { DP(NETIF_MSG_LINK, "100M half not supported\n"); @@ -169,7 +226,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] & + SUPPORTED_1000baseT_Full)) { DP(NETIF_MSG_LINK, "1G full not supported\n"); return -EINVAL; } @@ -185,7 +243,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_2500baseX_Full)) { DP(NETIF_MSG_LINK, "2.5G full not supported\n"); return -EINVAL; @@ -201,7 +260,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_10000baseT_Full)) { DP(NETIF_MSG_LINK, "10G full not supported\n"); return -EINVAL; } @@ -211,20 +271,23 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: - DP(NETIF_MSG_LINK, "Unsupported speed\n"); + DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed); return -EINVAL; } - bp->link_params.req_line_speed = cmd->speed; - bp->link_params.req_duplex = cmd->duplex; - bp->port.advertising = advertising; + bp->link_params.req_line_speed[cfg_idx] = speed; + bp->link_params.req_duplex[cfg_idx] = cmd->duplex; + bp->port.advertising[cfg_idx] = advertising; } DP(NETIF_MSG_LINK, "req_line_speed %d\n" DP_LEVEL " req_duplex %d advertising 0x%x\n", - bp->link_params.req_line_speed, bp->link_params.req_duplex, - bp->port.advertising); + bp->link_params.req_line_speed[cfg_idx], + bp->link_params.req_duplex[cfg_idx], + bp->port.advertising[cfg_idx]); + /* Set new config */ + bp->link_params.multi_phy_config = new_multi_phy_config; if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); bnx2x_link_set(bp); @@ -937,10 +1000,9 @@ static void bnx2x_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - - epause->autoneg = (bp->link_params.req_flow_ctrl == - BNX2X_FLOW_CTRL_AUTO) && - (bp->link_params.req_line_speed == SPEED_AUTO_NEG); + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] == + BNX2X_FLOW_CTRL_AUTO); epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) == BNX2X_FLOW_CTRL_RX); @@ -956,7 +1018,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - + u32 cfg_idx = bnx2x_get_link_cfg_idx(bp); if (IS_E1HMF(bp)) return 0; @@ -964,29 +1026,31 @@ static int bnx2x_set_pauseparam(struct net_device *dev, DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO; if (epause->rx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX; if (epause->tx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX; - if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO) + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE; if (epause->autoneg) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "autoneg not supported\n"); return -EINVAL; } - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) { + bp->link_params.req_flow_ctrl[cfg_idx] = + BNX2X_FLOW_CTRL_AUTO; + } } DP(NETIF_MSG_LINK, - "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); + "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]); if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1250,12 +1314,12 @@ test_mem_exit: return rc; } -static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up) +static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { int cnt = 1000; if (link_up) - while (bnx2x_link_test(bp) && cnt--) + while (bnx2x_link_test(bp, is_serdes) && cnt--) msleep(10); } @@ -1527,7 +1591,7 @@ static void bnx2x_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { struct bnx2x *bp = netdev_priv(dev); - + u8 is_serdes; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); etest->flags |= ETH_TEST_FL_FAILED; @@ -1542,6 +1606,7 @@ static void bnx2x_self_test(struct net_device *dev, /* offline tests are not supported in MF mode */ if (IS_E1HMF(bp)) etest->flags &= ~ETH_TEST_FL_OFFLINE; + is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; if (etest->flags & ETH_TEST_FL_OFFLINE) { int port = BP_PORT(bp); @@ -1553,11 +1618,12 @@ static void bnx2x_self_test(struct net_device *dev, /* disable input for TX port IF */ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0); - link_up = (bnx2x_link_test(bp) == 0); + link_up = bp->link_vars.link_up; + bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_load(bp, LOAD_DIAG); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); if (bnx2x_test_registers(bp) != 0) { buf[0] = 1; @@ -1578,7 +1644,7 @@ static void bnx2x_self_test(struct net_device *dev, bnx2x_nic_load(bp, LOAD_NORMAL); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); } if (bnx2x_test_nvram(bp) != 0) { buf[3] = 1; @@ -1589,7 +1655,7 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; } if (bp->port.pmf) - if (bnx2x_link_test(bp) != 0) { + if (bnx2x_link_test(bp, is_serdes) != 0) { buf[5] = 1; etest->flags |= ETH_TEST_FL_FAILED; } diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index f494bc333f52..bab3b2d8cc7a 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -238,7 +238,88 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u16 xgxs_config_tx[4]; /* 0x1A0 */ - u32 Reserved1[64]; /* 0x1A8 */ + u32 Reserved1[57]; /* 0x1A8 */ + u32 speed_capability_mask2; /* 0x28C */ +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10M_FULL 0x00000001 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3__ 0x00000002 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3___ 0x00000004 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_100M_FULL 0x00000008 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_1G 0x00000010 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_2_DOT_5G 0x00000020 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10G 0x00000040 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12G 0x00000080 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12_DOT_5G 0x00000100 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_13G 0x00000200 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_15G 0x00000400 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_16G 0x00000800 + +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_MASK 0xFFFF0000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_SHIFT 16 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10M_FULL 0x00010000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0__ 0x00020000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0___ 0x00040000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_100M_FULL 0x00080000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_1G 0x00100000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_2_DOT_5G 0x00200000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10G 0x00400000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12G 0x00800000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12_DOT_5G 0x01000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_13G 0x02000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_15G 0x04000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_16G 0x08000000 + + /* In the case where two media types (e.g. copper and fiber) are + present and electrically active at the same time, PHY Selection + will determine which of the two PHYs will be designated as the + Active PHY and used for a connection to the network. */ + u32 multi_phy_config; /* 0x290 */ +#define PORT_HW_CFG_PHY_SELECTION_MASK 0x00000007 +#define PORT_HW_CFG_PHY_SELECTION_SHIFT 0 +#define PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT 0x00000000 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY 0x00000001 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY 0x00000002 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY 0x00000003 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY 0x00000004 + + /* When enabled, all second phy nvram parameters will be swapped + with the first phy parameters */ +#define PORT_HW_CFG_PHY_SWAPPED_MASK 0x00000008 +#define PORT_HW_CFG_PHY_SWAPPED_SHIFT 3 +#define PORT_HW_CFG_PHY_SWAPPED_DISABLED 0x00000000 +#define PORT_HW_CFG_PHY_SWAPPED_ENABLED 0x00000008 + + + /* Address of the second external phy */ + u32 external_phy_config2; /* 0x294 */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_MASK 0x000000FF +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_SHIFT 0 + + /* The second XGXS external PHY type */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_MASK 0x0000FF00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SHIFT 8 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_DIRECT 0x00000000 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8071 0x00000100 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8072 0x00000200 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8073 0x00000300 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8705 0x00000400 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8706 0x00000500 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8726 0x00000600 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SFX7101 0x00000800 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727 0x00000900 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727_NOC 0x00000a00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00 + + /* 4 times 16 bits for all 4 lanes. For some external PHYs (such as + 8706, 8726 and 8727) not all 4 values are needed. */ + u16 xgxs_config2_rx[4]; /* 0x296 */ + u16 xgxs_config2_tx[4]; /* 0x2A0 */ u32 lane_config; #define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff @@ -532,10 +613,17 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ #define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 /* The default for MCP link configuration, - uses the same defines as link_config */ + uses the same defines as link_config */ u32 mfw_wol_link_cfg; + /* The default for the driver of the second external phy, + uses the same defines as link_config */ + u32 link_config2; /* 0x47C */ - u32 reserved[19]; + /* The default for MCP of the second external phy, + uses the same defines as link_config */ + u32 mfw_wol_link_cfg2; /* 0x480 */ + + u32 Reserved2[17]; /* 0x484 */ }; @@ -703,8 +791,14 @@ struct drv_func_mb { * The optic module verification commands require bootcode * v5.0.6 or later */ -#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000 -#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006 +#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000 +#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 + /* + * The specific optic module verification command requires bootcode + * v5.2.12 or later + */ +#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 +#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 @@ -939,7 +1033,12 @@ struct shmem2_region { #define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040 #define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080 #define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE - + u32 ext_phy_fw_version2[PORT_MAX]; + /* + * For backwards compatibility, if the mf_cfg_addr does not exist + * (the size filed is smaller than 0xc) the mf_cfg resides at the + * end of struct shmem_region + */ }; diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e2509aab9f0d..571785898970 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -899,6 +899,7 @@ static void bnx2x_xgxs_deassert(struct link_params *params) params->phy[INT_PHY].def_md_devad); } + void bnx2x_link_status_update(struct link_params *params, struct link_vars *vars) { @@ -906,10 +907,6 @@ void bnx2x_link_status_update(struct link_params *params, u8 link_10g; u8 port = params->port; - if (params->switch_cfg == SWITCH_CFG_1G) - vars->phy_flags = PHY_SERDES_FLAG; - else - vars->phy_flags = PHY_XGXS_FLAG; vars->link_status = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, port_mb[port].link_status)); @@ -1880,12 +1877,8 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", gp_status, vars->phy_link_up, vars->line_speed); - DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x" - " autoneg 0x%x\n", - vars->duplex, - vars->flow_ctrl, vars->autoneg); - DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status); - + DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", + vars->duplex, vars->flow_ctrl, vars->link_status); return rc; } @@ -2164,45 +2157,43 @@ static void bnx2x_link_int_enable(struct link_params *params) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); } -static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, - u8 is_mi_int) +static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, + u8 exp_mi_int) { - u32 latch_status = 0, is_mi_int_status; - /* Disable the MI INT ( external phy int ) - * by writing 1 to the status register. Link down indication - * is high-active-signal, so in this case we need to write the - * status to clear the XOR + u32 latch_status = 0; + + /** + * Disable the MI INT ( external phy int ) by writing 1 to the + * status register. Link down indication is high-active-signal, + * so in this case we need to write the status to clear the XOR */ /* Read Latched signals */ latch_status = REG_RD(bp, - NIG_REG_LATCH_STATUS_0 + port*8); - is_mi_int_status = REG_RD(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); - DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," - "latch_status = 0x%x\n", - is_mi_int, is_mi_int_status, latch_status); + NIG_REG_LATCH_STATUS_0 + port*8); + DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status); /* Handle only those with latched-signal=up.*/ + if (exp_mi_int) + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + else + bnx2x_bits_dis(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + if (latch_status & 1) { - /* For all latched-signal=up,Write original_signal to status */ - if (is_mi_int) - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - else - bnx2x_bits_dis(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); + /* For all latched-signal=up : Re-Arm Latch signals */ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, (latch_status & 0xfffe) | (latch_status & 1)); } + /* For all latched-signal=up,Write original_signal to status */ } static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g, - u8 is_mi_int) + struct link_vars *vars, u8 is_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2213,12 +2204,6 @@ static void bnx2x_link_int_ack(struct link_params *params, (NIG_STATUS_XGXS0_LINK10G | NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); - if ((params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (params->phy[EXT_PHY1].type - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { - bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); - } if (vars->phy_link_up) { if (is_10g) { /* Disable the 10G link interrupt @@ -2264,30 +2249,39 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) u32 mask = 0xf0000000; u8 shift = 8*4; u8 digit; + u8 remove_leading_zeros = 1; if (*len < 10) { /* Need more than 10chars for this format */ *str_ptr = '\0'; + (*len)--; return -EINVAL; } while (shift > 0) { shift -= 4; digit = ((num & mask) >> shift); - if (digit < 0xa) + if (digit == 0 && remove_leading_zeros) { + mask = mask >> 4; + continue; + } else if (digit < 0xa) *str_ptr = digit + '0'; else *str_ptr = digit - 0xa + 'a'; + remove_leading_zeros = 0; str_ptr++; + (*len)--; mask = mask >> 4; if (shift == 4*4) { - *str_ptr = ':'; + *str_ptr = '.'; str_ptr++; + (*len)--; + remove_leading_zeros = 1; } } - *str_ptr = '\0'; return 0; } + static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) { str[0] = '\0'; @@ -2302,6 +2296,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, u32 spirom_ver = 0; u8 status = 0; u8 *ver_p = version; + u16 remain_len = len; if (version == NULL || params == NULL) return -EINVAL; bp = params->bp; @@ -2310,10 +2305,28 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, version[0] = '\0'; spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); - if (params->phy[EXT_PHY1].format_fw_ver) + if (params->phy[EXT_PHY1].format_fw_ver) { status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, ver_p, - &len); + &remain_len); + ver_p += (len - remain_len); + } + if ((params->num_phys == MAX_PHYS) && + (params->phy[EXT_PHY2].ver_addr != 0)) { + spirom_ver = REG_RD(bp, + params->phy[EXT_PHY2].ver_addr); + if (params->phy[EXT_PHY2].format_fw_ver) { + *ver_p = '/'; + ver_p++; + remain_len--; + status |= params->phy[EXT_PHY2].format_fw_ver( + spirom_ver, + ver_p, + &remain_len); + ver_p = version + (len - remain_len); + } + } + *ver_p = '\0'; return status; } @@ -2550,30 +2563,56 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) } -u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) +/** + * This function comes to reflect the actual link state read DIRECTLY from the + * HW + */ +u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, + u8 is_serdes) { struct bnx2x *bp = params->bp; u16 gp_status = 0, phy_index = 0; + u8 ext_phy_link_up = 0, serdes_phy_type; + struct link_vars temp_vars; CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); /* link is up only if both local phy and external phy are up */ - if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - u8 ext_phy_link_up = 1; - struct link_vars temp_vars; + if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) + return -ESRCH; + + switch (params->num_phys) { + case 1: + /* No external PHY */ + return 0; + case 2: + ext_phy_link_up = params->phy[EXT_PHY1].read_status( + ¶ms->phy[EXT_PHY1], + params, &temp_vars); + break; + case 3: /* Dual Media */ for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].read_status) - ext_phy_link_up &= + serdes_phy_type = ((params->phy[phy_index].media_type == + ETH_PHY_SFP_FIBER) || + (params->phy[phy_index].media_type == + ETH_PHY_XFP_FIBER)); + + if (is_serdes != serdes_phy_type) + continue; + if (params->phy[phy_index].read_status) { + ext_phy_link_up |= params->phy[phy_index].read_status( ¶ms->phy[phy_index], params, &temp_vars); + } } - if (ext_phy_link_up) - return 0; + break; } + if (ext_phy_link_up) + return 0; return -ESRCH; } @@ -2619,6 +2658,19 @@ static u8 bnx2x_link_initialize(struct link_params *params, if (!non_ext_phy) for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { + /** + * No need to initialize second phy in case of first + * phy only selection. In case of second phy, we do + * need to initialize the first phy, since they are + * connected. + **/ + if (phy_index == EXT_PHY2 && + (bnx2x_phy_selection(params) == + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { + DP(NETIF_MSG_LINK, "Not initializing" + "second phy\n"); + continue; + } params->phy[phy_index].config_init( ¶ms->phy[phy_index], params, vars); @@ -2816,6 +2868,40 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) if (!ext_phy_link_up) { ext_phy_link_up = 1; active_external_phy = phy_index; + } else { + switch (bnx2x_phy_selection(params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through itself only. + * Its not clear how to reset the link on the second phy + **/ + active_external_phy = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through the second PHY. + **/ + active_external_phy = EXT_PHY2; + break; + default: + /** + * Link indication on both PHYs with the following cases + * is invalid: + * - FIRST_PHY means that second phy wasn't initialized, + * hence its link is expected to be down + * - SECOND_PHY means that first phy should not be able + * to link up by itself (using configuration) + * - DEFAULT should be overriden during initialiazation + **/ + DP(NETIF_MSG_LINK, "Invalid link indication" + "mpc=0x%x. DISABLING LINK !!!\n", + params->multi_phy_config); + ext_phy_link_up = 0; + break; + } } } prev_line_speed = vars->line_speed; @@ -2845,6 +2931,21 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) * the external phy. */ vars->link_status |= phy_vars[active_external_phy].link_status; + + /** + * if active_external_phy is first PHY and link is up - disable + * disable TX on second external PHY + */ + if (active_external_phy == EXT_PHY1) { + if (params->phy[EXT_PHY2].phy_specific_func) { + DP(NETIF_MSG_LINK, "Disabling TX on" + " EXT_PHY2\n"); + params->phy[EXT_PHY2].phy_specific_func( + ¶ms->phy[EXT_PHY2], + params, DISABLE_TX); + } + } + ext_phy_line_speed = phy_vars[active_external_phy].line_speed; vars->duplex = phy_vars[active_external_phy].duplex; if (params->phy[active_external_phy].supported & @@ -2853,6 +2954,17 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", active_external_phy); } + + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].flags & + FLAGS_REARM_LATCH_SIGNAL) { + bnx2x_rearm_latch_signal(bp, port, + phy_index == + active_external_phy); + break; + } + } DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," " ext_phy_line_speed = %d\n", vars->flow_ctrl, vars->link_status, ext_phy_line_speed); @@ -2885,7 +2997,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) (vars->line_speed == SPEED_15000) || (vars->line_speed == SPEED_16000)); - bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); + bnx2x_link_int_ack(params, vars, link_10g); /** * In case external phy link is up, and internal link is down @@ -3898,11 +4010,11 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u32 val; - u32 fw_resp; + u32 val, cmd; + u32 fw_resp, fw_cmd_param; char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; - + phy->flags &= ~FLAGS_SFP_NOT_APPROVED; val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].config)); @@ -3912,15 +4024,27 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, return 0; } - /* Ask the FW to validate the module */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { + if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) { + /* Use specific phy request */ + cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL; + } else if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) { + /* Use first phy request only in case of non-dual media*/ + if (DUAL_MEDIA(params)) { + DP(NETIF_MSG_LINK, "FW does not support OPT MDL " + "verification\n"); + return -EINVAL; + } + cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL; + } else { + /* No support in OPT MDL detection */ DP(NETIF_MSG_LINK, "FW does not support OPT MDL " - "verification\n"); + "verification\n"); return -EINVAL; } - - fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); + fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); + fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { DP(NETIF_MSG_LINK, "Approved module\n"); return 0; @@ -3947,6 +4071,7 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," " Port %d from %s part number %s\n", params->port, vendor_name, vendor_pn); + phy->flags |= FLAGS_SFP_NOT_APPROVED; return -EINVAL; } @@ -4092,6 +4217,27 @@ static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, return 0; } +static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, + struct link_params *params, + u32 action) +{ + struct bnx2x *bp = params->bp; + + switch (action) { + case DISABLE_TX: + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + break; + case ENABLE_TX: + if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + break; + default: + DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", + action); + return; + } +} + static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, struct link_params *params) { @@ -4625,6 +4771,19 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + /** + * Power down the XAUI until link is up in case of dual-media + * and 1G + */ + if (DUAL_MEDIA(params)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val); + val |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val); + } } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && ((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && @@ -4766,7 +4925,15 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u8 link_up = 0; u16 link_status = 0; - u16 rx_alarm_status, val1; + u16 rx_alarm_status, lasi_ctrl, val1; + + /* If PHY is not initialized, do not check link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + &lasi_ctrl); + if (!lasi_ctrl) + return 0; + /* Check the LASI */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, @@ -4837,7 +5004,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, ((1<<5) | (1<<2))); } - + DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); + bnx2x_8727_specific_func(phy, params, ENABLE_TX); /* If transmitter is disabled, ignore false link up indication */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); @@ -4867,6 +5035,24 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, } if (link_up) bnx2x_ext_phy_resolve_fc(phy, params, vars); + + if ((DUAL_MEDIA(params)) && + (phy->req_line_speed == SPEED_1000)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val1); + /** + * In case of dual-media board and 1G, power up the XAUI side, + * otherwise power it down. For 10G it is done automatically + */ + if (link_up) + val1 &= ~(3<<10); + else + val1 |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val1); + } return link_up; } @@ -4876,6 +5062,9 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Disable Transmitter */ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + /* Clear LASI */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); + } /******************************************************************/ @@ -4973,16 +5162,11 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp, } static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - /** - * This phy uses the NIG latch mechanism since link indication - * arrives through its LED4 and not via its LASI signal, so we - * get steady signal instead of clear on read - */ bnx2x_wait_reset_complete(bp, phy); bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -5122,7 +5306,11 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; + u8 initialize = 1; + u16 val; u16 temp; + u32 actual_phy_selection; + u8 rc = 0; msleep(1); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, @@ -5135,10 +5323,55 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, */ temp = vars->line_speed; vars->line_speed = SPEED_10000; - bnx2x_set_autoneg(phy, params, vars, 0); - bnx2x_program_serdes(phy, params, vars); + bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); + bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars); vars->line_speed = temp; - return bnx2x_848xx_cmn_config_init(phy, params, vars); + + /* Set dual-media configuration according to configuration */ + + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, &val); + val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | + MDIO_CTL_REG_84823_MEDIA_LINE_MASK | + MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | + MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK | + MDIO_CTL_REG_84823_MEDIA_FIBER_1G); + val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI | + MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L; + + actual_phy_selection = bnx2x_phy_selection(params); + + switch (actual_phy_selection) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + /* Do nothing. Essentialy this is like the priority copper */ + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + /* Do nothing here. The first PHY won't be initialized at all */ + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN; + initialize = 0; + break; + } + if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000) + val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; + + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, val); + DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", + params->multi_phy_config, val); + + if (initialize) + rc = bnx2x_848xx_cmn_config_init(phy, params, vars); + else + bnx2x_save_848xx_spirom_version(phy, params); + return rc; } static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, @@ -5426,7 +5659,8 @@ static struct bnx2x_phy phy_null = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_serdes = { @@ -5461,7 +5695,8 @@ static struct bnx2x_phy phy_serdes = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_xgxs = { @@ -5497,7 +5732,8 @@ static struct bnx2x_phy phy_xgxs = { .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_7101 = { @@ -5527,7 +5763,8 @@ static struct bnx2x_phy phy_7101 = { .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8073 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, @@ -5558,7 +5795,8 @@ static struct bnx2x_phy phy_8073 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8705 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, @@ -5586,7 +5824,8 @@ static struct bnx2x_phy phy_8705 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8706 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, @@ -5615,7 +5854,8 @@ static struct bnx2x_phy phy_8706 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8726 = { @@ -5647,7 +5887,8 @@ static struct bnx2x_phy phy_8726 = { .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8727 = { @@ -5677,12 +5918,14 @@ static struct bnx2x_phy phy_8727 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func }; static struct bnx2x_phy phy_8481 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, .def_md_devad = 0, .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, @@ -5711,13 +5954,15 @@ static struct bnx2x_phy phy_8481 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_84823 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, .addr = 0xff, - .flags = FLAGS_FAN_FAILURE_DET_REQ, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, .def_md_devad = 0, .reserved = 0, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, @@ -5746,7 +5991,8 @@ static struct bnx2x_phy phy_84823 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL }; /*****************************************************************/ @@ -5767,14 +6013,23 @@ static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, * shmem. When num_phys is greater than 1, than this value * applies only to EXT_PHY1 */ + if (phy_index == INT_PHY || phy_index == EXT_PHY1) { + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + } else { + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); - rx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); - - tx = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); + } phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); @@ -5794,6 +6049,11 @@ static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, offsetof(struct shmem_region, dev_info.port_hw_config[port].external_phy_config)); break; + case EXT_PHY2: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config2)); + break; default: DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); return -EINVAL; @@ -5844,6 +6104,7 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { @@ -5905,15 +6166,30 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, */ config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, dev_info.shared_hw_config.config2)); - - phy->ver_addr = shmem_base + offsetof(struct shmem_region, - port_mb[port].ext_phy_fw_version); + if (phy_index == EXT_PHY1) { + phy->ver_addr = shmem_base + offsetof(struct shmem_region, + port_mb[port].ext_phy_fw_version); /* Check specific mdc mdio settings */ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) mdc_mdio_access = config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + } else { + u32 size = REG_RD(bp, shmem2_base); + if (size > + offsetof(struct shmem2_region, ext_phy_fw_version2)) { + phy->ver_addr = shmem2_base + + offsetof(struct shmem2_region, + ext_phy_fw_version2[port]); + } + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) + mdc_mdio_access = (config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >> + (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT - + SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT); + } phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); /** @@ -5931,30 +6207,41 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, } static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, - u8 port, struct bnx2x_phy *phy) + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { u8 status = 0; phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; if (phy_index == INT_PHY) return bnx2x_populate_int_phy(bp, shmem_base, port, phy); - status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, + status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base, port, phy); return status; } static void bnx2x_phy_def_cfg(struct link_params *params, struct bnx2x_phy *phy, - u8 actual_phy_idx) + u8 phy_index) { struct bnx2x *bp = params->bp; u32 link_config; /* Populate the default phy configuration for MF mode */ - link_config = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port].link_config)); - phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + if (phy_index == EXT_PHY2) { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config2)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask2)); + } else { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. - port_hw_config[params->port].speed_capability_mask)); + port_hw_config[params->port].speed_capability_mask)); + } + DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask" + " 0x%x\n", phy_index, link_config, phy->speed_cap_mask); phy->req_duplex = DUPLEX_FULL; switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { @@ -6001,23 +6288,66 @@ static void bnx2x_phy_def_cfg(struct link_params *params, } } +u32 bnx2x_phy_selection(struct link_params *params) +{ + u32 phy_config_swapped, prio_cfg; + u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT; + + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + + prio_cfg = params->multi_phy_config & + PORT_HW_CFG_PHY_SELECTION_MASK; + + if (phy_config_swapped) { + switch (prio_cfg) { + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + } + } else + return_cfg = prio_cfg; + + return return_cfg; +} + + u8 bnx2x_phy_probe(struct link_params *params) { u8 phy_index, actual_phy_idx, link_cfg_idx; - + u32 phy_config_swapped; struct bnx2x *bp = params->bp; struct bnx2x_phy *phy; params->num_phys = 0; DP(NETIF_MSG_LINK, "Begin phy probe\n"); + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; for (phy_index = INT_PHY; phy_index < MAX_PHYS; phy_index++) { link_cfg_idx = LINK_CONFIG_IDX(phy_index); actual_phy_idx = phy_index; - + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } + DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x," + " actual_phy_idx %x\n", phy_config_swapped, + phy_index, actual_phy_idx); phy = ¶ms->phy[actual_phy_idx]; if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, - params->port, + params->shmem2_base, params->port, phy) != 0) { params->num_phys = 0; DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", @@ -6031,7 +6361,7 @@ u8 bnx2x_phy_probe(struct link_params *params) if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) break; - bnx2x_phy_def_cfg(params, phy, actual_phy_idx); + bnx2x_phy_def_cfg(params, phy, phy_index); params->num_phys++; } @@ -6049,23 +6379,30 @@ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) static void set_phy_vars(struct link_params *params) { struct bnx2x *bp = params->bp; - u8 actual_phy_idx, phy_index; - + u8 actual_phy_idx, phy_index, link_cfg_idx; + u8 phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { - + link_cfg_idx = LINK_CONFIG_IDX(phy_index); actual_phy_idx = phy_index; + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } params->phy[actual_phy_idx].req_flow_ctrl = - params->req_flow_ctrl; + params->req_flow_ctrl[link_cfg_idx]; params->phy[actual_phy_idx].req_line_speed = - params->req_line_speed; + params->req_line_speed[link_cfg_idx]; params->phy[actual_phy_idx].speed_cap_mask = - params->speed_cap_mask; + params->speed_cap_mask[link_cfg_idx]; params->phy[actual_phy_idx].req_duplex = - params->req_duplex; + params->req_duplex[link_cfg_idx]; DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," " speed_cap_mask %x\n", @@ -6078,11 +6415,11 @@ static void set_phy_vars(struct link_params *params) u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - DP(NETIF_MSG_LINK, "Phy Initialization started\n"); - DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", - params->req_line_speed, params->req_flow_ctrl); + DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[0], params->req_flow_ctrl[0]); + DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[1], params->req_flow_ctrl[1]); vars->link_status = 0; vars->phy_link_up = 0; vars->link_up = 0; @@ -6196,21 +6533,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) (params->loopback_mode == LOOPBACK_EXT_PHY)) { vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - vars->phy_flags = PHY_XGXS_FLAG; - - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); + vars->duplex = DUPLEX_FULL; + if (params->req_line_speed[0] == SPEED_1000) { + vars->line_speed = SPEED_1000; + vars->mac_type = MAC_TYPE_EMAC; + } else { + vars->line_speed = SPEED_10000; + vars->mac_type = MAC_TYPE_BMAC; + } bnx2x_xgxs_deassert(params); bnx2x_link_initialize(params, vars); - vars->mac_type = MAC_TYPE_BMAC; - + if (params->req_line_speed[0] == SPEED_1000) { + bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + } else bnx2x_bmac_enable(params, vars, 0); if (params->loopback_mode == LOOPBACK_XGXS) { @@ -6311,7 +6650,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /****************************************************************************/ /* Common function */ /****************************************************************************/ -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) { struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -6321,7 +6660,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate_phy failed\n"); @@ -6419,7 +6758,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index) { u32 val; s8 port; @@ -6435,7 +6775,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) msleep(5); for (port = 0; port < PORT_MAX; port++) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); @@ -6455,10 +6795,10 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - -static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index) { - s8 port, first_port, i; + s8 port; u32 swap_val, swap_override; struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -6466,18 +6806,19 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override)); - msleep(5); + port = 1; - if (swap_val && swap_override) - first_port = PORT_0; - else - first_port = PORT_1; + bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override)); + + /* Calculate the port based on port swap */ + port ^= (swap_val && swap_override); + + msleep(5); /* PART1 - Reset both phys */ - for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { + for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Extract the ext phy address for the port */ - if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); @@ -6528,35 +6869,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) +static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 phy_index, + u32 ext_phy_type) { u8 rc = 0; - u32 ext_phy_type; - - DP(NETIF_MSG_LINK, "Begin common phy init\n"); - - /* Read the ext_phy_type for arbitrary port(0) */ - ext_phy_type = XGXS_EXT_PHY_TYPE( - REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[0].external_phy_config))); switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - { - rc = bnx2x_8073_common_init_phy(bp, shmem_base); + rc = bnx2x_8073_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); break; - } case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: - rc = bnx2x_8727_common_init_phy(bp, shmem_base); + rc = bnx2x_8727_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: /* GPIO1 affects both ports, so there's need to pull it for single port alone */ - rc = bnx2x_8726_common_init_phy(bp, shmem_base); + rc = bnx2x_8726_common_init_phy(bp, shmem_base, + shmem2_base, phy_index); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + rc = -EINVAL; break; default: DP(NETIF_MSG_LINK, @@ -6568,14 +6906,38 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) return rc; } +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base) +{ + u8 rc = 0; + u8 phy_index; + u32 ext_phy_type, ext_phy_config; + DP(NETIF_MSG_LINK, "Begin common phy init\n"); + + if (CHIP_REV_IS_EMUL(bp)) + return 0; + + /* Read the ext_phy_type for arbitrary port(0) */ + for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; + phy_index++) { + ext_phy_config = bnx2x_get_ext_phy_config(bp, + shmem_base, + phy_index, 0); + ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + rc |= bnx2x_ext_phy_common_init(bp, shmem_base, + shmem2_base, + phy_index, ext_phy_type); + } + return rc; +} -u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base) { u8 phy_index; struct bnx2x_phy phy; for (phy_index = INT_PHY; phy_index < MAX_PHYS; phy_index++) { - if (bnx2x_populate_phy(bp, phy_index, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 0, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); return 0; @@ -6589,13 +6951,14 @@ u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base) u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 port) { u8 phy_index, fan_failure_det_req = 0; struct bnx2x_phy phy; for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; phy_index++) { - if (bnx2x_populate_phy(bp, phy_index, shmem_base, + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 35f665f97be6..9115c125aeaf 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -59,13 +59,18 @@ #define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1) /* Single Media board contains single external phy */ #define SINGLE_MEDIA(params) (params->num_phys == 2) +/* Dual Media board contains two external phy with different media */ +#define DUAL_MEDIA(params) (params->num_phys == 3) +#define FW_PARAM_MDIO_CTRL_OFFSET 16 +#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ + (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) /***********************************************************/ /* Structs */ /***********************************************************/ #define INT_PHY 0 #define EXT_PHY1 1 - -#define MAX_PHYS 2 +#define EXT_PHY2 2 +#define MAX_PHYS 3 /* Same configuration is shared between the XGXS and the first external phy */ #define LINK_CONFIG_SIZE (MAX_PHYS - 1) @@ -91,6 +96,8 @@ typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len); typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params); typedef void (*set_link_led_t)(struct bnx2x_phy *phy, struct link_params *params, u8 mode); +typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy, + struct link_params *params, u32 action); struct bnx2x_phy { u32 type; @@ -106,7 +113,9 @@ struct bnx2x_phy { /* Fan failure detection required */ #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) /* Initialize first the XGXS and only then the phy itself */ -#define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_REARM_LATCH_SIGNAL (1<<6) +#define FLAGS_SFP_NOT_APPROVED (1<<7) u8 def_md_devad; u8 reserved; @@ -161,6 +170,11 @@ struct bnx2x_phy { /* Set link led mode (on/off/oper)*/ set_link_led_t set_link_led; + + /* PHY Specific tasks */ + phy_specific_func_t phy_specific_func; +#define DISABLE_TX 1 +#define ENABLE_TX 2 }; /* Inputs parameters to the CLC */ @@ -177,18 +191,18 @@ struct link_params { #define LOOPBACK_EXT_PHY 4 #define LOOPBACK_EXT 5 - u16 req_duplex; - u16 req_flow_ctrl; - u16 req_fc_auto_adv; /* Should be set to TX / BOTH when - req_flow_ctrl is set to AUTO */ - u16 req_line_speed; /* Also determine AutoNeg */ - /* Device parameters */ u8 mac_addr[6]; + u16 req_duplex[LINK_CONFIG_SIZE]; + u16 req_flow_ctrl[LINK_CONFIG_SIZE]; + + u16 req_line_speed[LINK_CONFIG_SIZE]; /* Also determine AutoNeg */ + /* shmem parameters */ u32 shmem_base; - u32 speed_cap_mask; + u32 shmem2_base; + u32 speed_cap_mask[LINK_CONFIG_SIZE]; u32 switch_cfg; #define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH #define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH @@ -202,6 +216,7 @@ struct link_params { u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) +#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; @@ -210,9 +225,12 @@ struct link_params { u8 rsrv; u16 hw_led_mode; /* part of the hw_config read from the shmem */ + u32 multi_phy_config; /* Device pointer passed to all callback functions */ struct bnx2x *bp; + u16 req_fc_auto_adv; /* Should be set to TX / BOTH when + req_flow_ctrl is set to AUTO */ }; /* Output parameters */ @@ -233,12 +251,6 @@ struct link_vars { u16 flow_ctrl; u16 ieee_fc; - u32 autoneg; -#define AUTO_NEG_DISABLED 0x0 -#define AUTO_NEG_ENABLED 0x1 -#define AUTO_NEG_COMPLETE 0x2 -#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3 - /* The same definitions as the shmem parameter */ u32 link_status; }; @@ -246,8 +258,6 @@ struct link_vars { /***********************************************************/ /* Functions */ /***********************************************************/ - -/* Initialize the phy */ u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); /* Reset the link. Should be called when driver or interface goes down @@ -298,10 +308,11 @@ void bnx2x_handle_module_detect_int(struct link_params *params); /* Get the actual link status. In case it returns 0, link is up, otherwise link is down*/ -u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); +u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, + u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base); +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); @@ -316,12 +327,19 @@ u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, void bnx2x_hw_reset_phy(struct link_params *params); /* Checks if HW lock is required for this phy/board type */ -u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base); +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base); + /* Returns the aggregative supported attributes of the phys on board */ u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx); + +/* Check swap bit and adjust PHY order */ +u32 bnx2x_phy_selection(struct link_params *params); + /* Probe the phys on board, and populate them in "params" */ u8 bnx2x_phy_probe(struct link_params *params); /* Checks if fan failure detection is required on one of the phys on board */ -u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u8 port); +u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 port); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 30618c7ed4ed..f0a788467fb1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1227,26 +1227,66 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) return 0; } +int bnx2x_get_link_cfg_idx(struct bnx2x *bp) +{ + u32 sel_phy_idx = 0; + if (bp->link_vars.link_up) { + sel_phy_idx = EXT_PHY1; + /* In case link is SERDES, check if the EXT_PHY2 is the one */ + if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) && + (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE)) + sel_phy_idx = EXT_PHY2; + } else { + + switch (bnx2x_phy_selection(&bp->link_params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + sel_phy_idx = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + sel_phy_idx = EXT_PHY2; + break; + } + } + /* + * The selected actived PHY is always after swapping (in case PHY + * swapping is enabled). So when swapping is enabled, we need to reverse + * the configuration + */ + + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + if (sel_phy_idx == EXT_PHY1) + sel_phy_idx = EXT_PHY2; + else if (sel_phy_idx == EXT_PHY2) + sel_phy_idx = EXT_PHY1; + } + return LINK_CONFIG_IDX(sel_phy_idx); +} + void bnx2x_calc_fc_adv(struct bnx2x *bp) { + u8 cfg_idx = bnx2x_get_link_cfg_idx(bp); switch (bp->link_vars.ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: - bp->port.advertising |= (ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: - bp->port.advertising |= ADVERTISED_Asym_Pause; + bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause; break; default: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); break; } @@ -1257,7 +1297,8 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { if (!BP_NOMCP(bp)) { u8 rc; - + int cfx_idx = bnx2x_get_link_cfg_idx(bp); + u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx]; /* Initialize link parameters structure variables */ /* It is recommended to turn off RX FC for jumbo frames for better performance */ @@ -1268,8 +1309,10 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) bnx2x_acquire_phy_lock(bp); - if (load_mode == LOAD_DIAG) + if (load_mode == LOAD_DIAG) { bp->link_params.loopback_mode = LOOPBACK_XGXS; + bp->link_params.req_line_speed[cfx_idx] = SPEED_10000; + } rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); @@ -1281,7 +1324,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_link_report(bp); } - + bp->link_params.req_line_speed[cfx_idx] = req_line_speed; return rc; } BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -1311,13 +1354,14 @@ static void bnx2x__link_reset(struct bnx2x *bp) BNX2X_ERR("Bootcode is missing - can not reset link\n"); } -u8 bnx2x_link_test(struct bnx2x *bp) +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes) { u8 rc = 0; if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); - rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); + rc = bnx2x_test_link(&bp->link_params, &bp->link_vars, + is_serdes); bnx2x_release_phy_lock(bp); } else BNX2X_ERR("Bootcode is missing - can not test link\n"); @@ -1586,7 +1630,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp) */ /* send the MCP a request, block until there is a reply */ -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) { int func = BP_FUNC(bp); u32 seq = ++bp->fw_seq; @@ -1595,6 +1639,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; mutex_lock(&bp->fw_mb_mutex); + SHMEM_WR(bp, func_mb[func].drv_mb_param, param); SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); @@ -1716,9 +1761,9 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) /* Report results to MCP */ if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); } /* must be called under the spq lock */ @@ -3848,6 +3893,7 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) bnx2x_fan_failure_det_req( bp, bp->common.shmem_base, + bp->common.shmem2_base, port); } @@ -4116,7 +4162,8 @@ static int bnx2x_init_common(struct bnx2x *bp) } bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base); + bp->common.shmem_base, + bp->common.shmem2_base); bnx2x_setup_fan_failure_detection(bp); @@ -4129,7 +4176,8 @@ static int bnx2x_init_common(struct bnx2x *bp) if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base); + bnx2x_common_init_phy(bp, bp->common.shmem_base, + bp->common.shmem2_base); bnx2x_release_phy_lock(bp); } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -4265,10 +4313,10 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, - bp->common.shmem_base); - + bp->common.shmem_base, + bp->common.shmem2_base); if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, - port)) { + bp->common.shmem2_base, port)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, reg_addr); @@ -5226,7 +5274,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) unload_error: if (!BP_NOMCP(bp)) - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); else { DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", load_count[0], load_count[1], load_count[2]); @@ -5251,7 +5299,7 @@ unload_error: /* Report UNLOAD_DONE to MCP */ if (!BP_NOMCP(bp)) - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } @@ -5816,13 +5864,14 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); /* if UNDI is loaded on the other port */ if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { /* send "DONE" for previous unload */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, + DRV_MSG_CODE_UNLOAD_DONE, 0); /* unload UNDI on port 1 */ bp->func = 1; @@ -5831,7 +5880,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) DRV_MSG_SEQ_NUMBER_MASK); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - bnx2x_fw_command(bp, reset_code); + bnx2x_fw_command(bp, reset_code, 0); } /* now it's safe to release the lock */ @@ -5873,7 +5922,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); /* send unload done to the MCP */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); /* restore our func and fw_seq */ bp->func = func; @@ -5921,6 +5970,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); bp->link_params.shmem_base = bp->common.shmem_base; + bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", bp->common.shmem_base, bp->common.shmem2_base); @@ -5963,8 +6013,11 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) "please upgrade BC\n", BNX2X_BC_VER, val); } bp->link_params.feature_config_flags |= - (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? + (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + bp->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; if (BP_E1HVN(bp) == 0) { pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); @@ -5988,22 +6041,44 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) { - int port = BP_PORT(bp); - bp->port.supported = 0; + int cfg_size = 0, idx, port = BP_PORT(bp); + + /* Aggregation of supported attributes of all external phys */ + bp->port.supported[0] = 0; + bp->port.supported[1] = 0; switch (bp->link_params.num_phys) { case 1: - bp->port.supported = bp->link_params.phy[INT_PHY].supported; - break; + bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported; + cfg_size = 1; + break; case 2: - bp->port.supported = bp->link_params.phy[EXT_PHY1].supported; - break; + bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported; + cfg_size = 1; + break; + case 3: + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY2].supported; + } else { + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY2].supported; + } + cfg_size = 2; + break; } - if (!(bp->port.supported)) { + if (!(bp->port.supported[0] || bp->port.supported[1])) { BNX2X_ERR("NVRAM config error. BAD phy config." - "PHY1 config 0x%x\n", + "PHY1 config 0x%x, PHY2 config 0x%x\n", SHMEM_RD(bp, - dev_info.port_hw_config[port].external_phy_config)); + dev_info.port_hw_config[port].external_phy_config), + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config2)); return; } @@ -6023,147 +6098,183 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, default: BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", - bp->port.link_config); + bp->port.link_config[0]); return; } - /* mask what we support according to speed_cap_mask */ - if (!(bp->link_params.speed_cap_mask & + /* mask what we support according to speed_cap_mask per configuration */ + for (idx = 0; idx < cfg_size; idx++) { + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) - bp->port.supported &= ~SUPPORTED_10baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) - bp->port.supported &= ~SUPPORTED_10baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) - bp->port.supported &= ~SUPPORTED_100baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) - bp->port.supported &= ~SUPPORTED_100baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) - bp->port.supported &= ~(SUPPORTED_1000baseT_Half | + bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->port.supported &= ~SUPPORTED_2500baseX_Full; + bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) - bp->port.supported &= ~SUPPORTED_10000baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full; + + } - BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); + BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0], + bp->port.supported[1]); } static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) { - bp->link_params.req_duplex = DUPLEX_FULL; - - switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { + u32 link_config, idx, cfg_size = 0; + bp->port.advertising[0] = 0; + bp->port.advertising[1] = 0; + switch (bp->link_params.num_phys) { + case 1: + case 2: + cfg_size = 1; + break; + case 3: + cfg_size = 2; + break; + } + for (idx = 0; idx < cfg_size; idx++) { + bp->link_params.req_duplex[idx] = DUPLEX_FULL; + link_config = bp->port.link_config[idx]; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { case PORT_FEATURE_LINK_SPEED_AUTO: - if (bp->port.supported & SUPPORTED_Autoneg) { - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; + if (bp->port.supported[idx] & SUPPORTED_Autoneg) { + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] |= + bp->port.supported[idx]; } else { - /* force 10G, no AN */ - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | + /* force 10G, no AN */ + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); + continue; } break; case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->port.supported & SUPPORTED_10baseT_Full) { - bp->link_params.req_line_speed = SPEED_10; - bp->port.advertising = (ADVERTISED_10baseT_Full | + if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->port.supported & SUPPORTED_10baseT_Half) { - bp->link_params.req_line_speed = SPEED_10; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_10baseT_Half | + if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Half | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported & SUPPORTED_100baseT_Full) { - bp->link_params.req_line_speed = SPEED_100; - bp->port.advertising = (ADVERTISED_100baseT_Full | + if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed = SPEED_100; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_100baseT_Half | + if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed[idx] = SPEED_100; + bp->link_params.req_duplex[idx] = DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Half | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_1G: - if (bp->port.supported & SUPPORTED_1000baseT_Full) { - bp->link_params.req_line_speed = SPEED_1000; - bp->port.advertising = (ADVERTISED_1000baseT_Full | + if (bp->port.supported[idx] & + SUPPORTED_1000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_1000; + bp->port.advertising[idx] |= + (ADVERTISED_1000baseT_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->port.supported & SUPPORTED_2500baseX_Full) { - bp->link_params.req_line_speed = SPEED_2500; - bp->port.advertising = (ADVERTISED_2500baseX_Full | + if (bp->port.supported[idx] & + SUPPORTED_2500baseX_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_2500; + bp->port.advertising[idx] |= + (ADVERTISED_2500baseX_Full | ADVERTISED_TP); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; @@ -6171,16 +6282,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) case PORT_FEATURE_LINK_SPEED_10G_CX4: case PORT_FEATURE_LINK_SPEED_10G_KX4: case PORT_FEATURE_LINK_SPEED_10G_KR: - if (bp->port.supported & SUPPORTED_10000baseT_Full) { - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | + if (bp->port.supported[idx] & + SUPPORTED_10000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); } else { BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); + link_config, + bp->link_params.speed_cap_mask[idx]); return; } break; @@ -6188,23 +6302,28 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) default: BNX2X_ERROR("NVRAM config error. " "BAD link speed link_config 0x%x\n", - bp->port.link_config); - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; + link_config); + bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; + bp->port.advertising[idx] = bp->port.supported[idx]; break; } - bp->link_params.req_flow_ctrl = (bp->port.link_config & + bp->link_params.req_flow_ctrl[idx] = (link_config & PORT_FEATURE_FLOW_CONTROL_MASK); - if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - !(bp->port.supported & SUPPORTED_Autoneg)) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + if ((bp->link_params.req_flow_ctrl[idx] == + BNX2X_FLOW_CTRL_AUTO) && + !(bp->port.supported[idx] & SUPPORTED_Autoneg)) { + bp->link_params.req_flow_ctrl[idx] = + BNX2X_FLOW_CTRL_NONE; + } - BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" - " advertising 0x%x\n", - bp->link_params.req_line_speed, - bp->link_params.req_duplex, - bp->link_params.req_flow_ctrl, bp->port.advertising); + BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl" + " 0x%x advertising 0x%x\n", + bp->link_params.req_line_speed[idx], + bp->link_params.req_duplex[idx], + bp->link_params.req_flow_ctrl[idx], + bp->port.advertising[idx]); + } } static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) @@ -6228,14 +6347,20 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->link_params.lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); - bp->link_params.speed_cap_mask = + bp->link_params.speed_cap_mask[0] = SHMEM_RD(bp, dev_info.port_hw_config[port].speed_capability_mask); - - bp->port.link_config = + bp->link_params.speed_cap_mask[1] = + SHMEM_RD(bp, + dev_info.port_hw_config[port].speed_capability_mask2); + bp->port.link_config[0] = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); + bp->port.link_config[1] = + SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2); + bp->link_params.multi_phy_config = + SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config); /* If the device is capable of WoL, set the default state according * to the HW */ @@ -6244,11 +6369,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) (config & PORT_FEATURE_WOL_ENABLED)); BNX2X_DEV_INFO("lane_config 0x%08x" - " speed_cap_mask 0x%08x link_config 0x%08x\n", + "speed_cap_mask0 0x%08x link_config0 0x%08x\n", bp->link_params.lane_config, - bp->link_params.speed_cap_mask, bp->port.link_config); + bp->link_params.speed_cap_mask[0], + bp->port.link_config[0]); - bp->link_params.switch_cfg |= (bp->port.link_config & + bp->link_params.switch_cfg = (bp->port.link_config[0] & PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 398cf55b8e10..f0a69563b66a 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -4964,6 +4964,8 @@ #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001 #define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII 0x0001 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK 0x0002 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3 @@ -5192,6 +5194,8 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_XS_8706_REG_BANK_RX3 0x80ec #define MDIO_XS_8706_REG_BANK_RXA 0x80fc +#define MDIO_XS_REG_8073_RX_CTRL_PCIE 0x80FA + #define MDIO_AN_DEVAD 0x7 /*ieee*/ #define MDIO_AN_REG_CTRL 0x0000 @@ -5227,6 +5231,27 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_8481_AUX_CTRL 0xfff8 #define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc +/* BCM84823 only */ +#define MDIO_CTL_DEVAD 0x1e +#define MDIO_CTL_REG_84823_MEDIA 0x401a +#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK 0x0018 + /* These pins configure the BCM84823 interface to MAC after reset. */ +#define MDIO_CTL_REG_84823_CTRL_MAC_XFI 0x0008 +#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M 0x0010 + /* These pins configure the BCM84823 interface to Line after reset. */ +#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK 0x0060 +#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L 0x0020 +#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI 0x0040 + /* When this pin is active high during reset, 10GBASE-T core is power + * down, When it is active low the 10GBASE-T is power up + */ +#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN 0x0080 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK 0x0100 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000 +#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100 +#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000 + + #define IGU_FUNC_BASE 0x0400 #define IGU_ADDR_MSIX 0x0000 -- cgit v1.2.3 From 7f02c4ad2182ee7820edecbaf6c510728ee8bbb3 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:23 +0000 Subject: bnx2x: Change LED scheme for dual-media Change LED scheme for dual-media Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 9 +- drivers/net/bnx2x/bnx2x_hsi.h | 2 + drivers/net/bnx2x/bnx2x_link.c | 345 ++++++++++++++++++++++++++++++++++---- drivers/net/bnx2x/bnx2x_link.h | 9 +- drivers/net/bnx2x/bnx2x_reg.h | 17 +- 5 files changed, 336 insertions(+), 46 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index d058f9716785..6f939c5a0089 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1954,10 +1954,11 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) for (i = 0; i < (data * 2); i++) { if ((i % 2) == 0) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - SPEED_1000); + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OPER, SPEED_1000); else - bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0); + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OFF, 0); msleep_interruptible(500); if (signal_pending(current)) @@ -1965,7 +1966,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) } if (bp->link_vars.link_up) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, + bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER, bp->link_vars.line_speed); return 0; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index bab3b2d8cc7a..60d141cd9950 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -78,6 +78,8 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_LED_PHY11 0x000b0000 #define SHARED_HW_CFG_LED_MAC4 0x000c0000 #define SHARED_HW_CFG_LED_PHY8 0x000d0000 +#define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000 + #define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000 #define SHARED_HW_CFG_AN_ENABLE_SHIFT 24 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 571785898970..a07a3a6abd40 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -976,7 +976,6 @@ void bnx2x_link_status_update(struct link_params *params, default: break; } - vars->flow_ctrl = 0; if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; @@ -1561,7 +1560,6 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; if (pause_result & (1<<1)) vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; - } static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, @@ -1755,6 +1753,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); + if (phy->req_line_speed == SPEED_AUTO_NEG) vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { @@ -1858,7 +1857,6 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, vars->line_speed = new_line_speed; - } else { /* link_down */ DP(NETIF_MSG_LINK, "phy link down\n"); @@ -1964,7 +1962,7 @@ static u8 bnx2x_emac_program(struct link_params *params, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, mode); - bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); + bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); return 0; } @@ -2187,7 +2185,7 @@ static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, /* For all latched-signal=up : Re-Arm Latch signals */ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, - (latch_status & 0xfffe) | (latch_status & 1)); + (latch_status & 0xfffe) | (latch_status & 1)); } /* For all latched-signal=up,Write original_signal to status */ } @@ -2496,18 +2494,29 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, return 0; } -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) + +u8 bnx2x_set_led(struct link_params *params, + struct link_vars *vars, u8 mode, u32 speed) { u8 port = params->port; u16 hw_led_mode = params->hw_led_mode; - u8 rc = 0; + u8 rc = 0, phy_idx; u32 tmp; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", speed, hw_led_mode); + /* In case */ + for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) { + if (params->phy[phy_idx].set_link_led) { + params->phy[phy_idx].set_link_led( + ¶ms->phy[phy_idx], params, mode); + } + } + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: case LED_MODE_OFF: REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, @@ -2518,7 +2527,18 @@ u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) break; case LED_MODE_OPER: + /** + * For all other phys, OPER mode is same as ON, so in case + * link is down, do nothing + **/ + if (!vars->link_up) + break; + case LED_MODE_ON: if (SINGLE_MEDIA_DIRECT(params)) { + /** + * This is a work-around for HW issue found when link + * is up in CL73 + */ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); } else { @@ -2718,7 +2738,7 @@ static u8 bnx2x_update_link_down(struct link_params *params, u8 port = params->port; DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); - bnx2x_set_led(params, LED_MODE_OFF, 0); + bnx2x_set_led(params, vars, LED_MODE_OFF, 0); /* indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; @@ -2753,6 +2773,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, u8 rc = 0; vars->link_status |= LINK_STATUS_LINK_UP; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) vars->link_status |= LINK_STATUS_TX_FLOW_CONTROL_ENABLED; @@ -2760,9 +2781,11 @@ static u8 bnx2x_update_link_up(struct link_params *params, if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) vars->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; + if (link_10g) { bnx2x_bmac_enable(params, vars, 0); - bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); + bnx2x_set_led(params, vars, + LED_MODE_OPER, SPEED_10000); } else { rc = bnx2x_emac_program(params, vars); @@ -4685,6 +4708,53 @@ static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, /******************************************************************/ /* BCM8727 PHY SECTION */ /******************************************************************/ + +static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + struct bnx2x *bp = params->bp; + u16 led_mode_bitmask = 0; + u16 gpio_pins_bitmask = 0; + u16 val; + /* Only NOC flavor requires to set the LED specifically */ + if (!(phy->flags & FLAGS_NOC)) + return; + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + led_mode_bitmask = 0; + gpio_pins_bitmask = 0x03; + break; + case LED_MODE_ON: + led_mode_bitmask = 0; + gpio_pins_bitmask = 0x02; + break; + case LED_MODE_OPER: + led_mode_bitmask = 0x60; + gpio_pins_bitmask = 0x11; + break; + } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val &= 0xff8f; + val |= led_mode_bitmask; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_OPT_CTRL, + val); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + &val); + val &= 0xffe0; + val |= gpio_pins_bitmask; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + val); +} static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { u32 swap_val, swap_override; @@ -4732,7 +4802,9 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, (bit 9). When the EDC is off it locks onto a reference clock and avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8) | (1<<9)); + mod_abs &= ~(1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs &= ~(1<<9); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); @@ -4741,15 +4813,15 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, &val); val |= (1<<12); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); - /* Set 8727 GPIOs to input to allow reading from the - 8727 GPIO0 status which reflect SFP+ module - over-current */ + if (phy->flags & FLAGS_NOC) + val |= (3<<5); - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val &= 0xff8f; /* Reset bits 4-6 */ + /** + * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0 + * status which reflect SFP+ module over-current + */ + if (!(phy->flags & FLAGS_NOC)) + val &= 0xff8f; /* Reset bits 4-6 */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); @@ -4863,7 +4935,9 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, (bit 9). When the EDC is off it locks onto a reference clock and avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8)|(1<<9)); + mod_abs &= ~(1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs &= ~(1<<9); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); @@ -4887,7 +4961,9 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, 2. Restore the default polarity of the OPRXLOS signal and this signal will then correctly indicate the presence or absence of the Rx signal. (bit 9) */ - mod_abs |= ((1<<8)|(1<<9)); + mod_abs |= (1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs |= (1<<9); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); @@ -5306,21 +5382,22 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 initialize = 1; + u8 port = params->port, initialize = 1; u16 val; u16 temp; u32 actual_phy_selection; u8 rc = 0; + + /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ + msleep(1); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + port); msleep(200); /* 100 is not enough */ - /** - * BCM84823 requires that XGXS links up first @ 10G for normal - * behavior - */ + /* BCM84823 requires that XGXS links up first @ 10G for normal + behavior */ temp = vars->line_speed; vars->line_speed = SPEED_10000; bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); @@ -5495,6 +5572,184 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, port); } +static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + struct bnx2x *bp = params->bp; + u16 val; + + switch (mode) { + case LED_MODE_OFF: + + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port); + + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x0); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + } + break; + case LED_MODE_FRONT_PANEL_OFF: + + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n", + params->port); + + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x20); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + } + break; + case LED_MODE_ON: + + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port); + + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + /* Set control reg */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val); + val &= 0x8000; + val |= 0x2492; + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + val); + + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x20); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x20); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x0); + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x20); + } + break; + + case LED_MODE_OPER: + + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port); + + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + + /* Set control reg */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val); + + if (!((val & + MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) + >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){ + DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + 0xa492); + } + + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x10); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x80); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x98); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x40); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x80); + } + break; + } +} /******************************************************************/ /* SFX7101 PHY SECTION */ /******************************************************************/ @@ -5632,6 +5887,29 @@ static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); } +static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + u16 val = 0; + struct bnx2x *bp = params->bp; + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + val = 2; + break; + case LED_MODE_ON: + val = 1; + break; + case LED_MODE_OPER: + val = 0; + break; + } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7107_LINK_LED_CNTL, + val); +} + /******************************************************************/ /* STATIC PHY DECLARATION */ /******************************************************************/ @@ -5763,7 +6041,7 @@ static struct bnx2x_phy phy_7101 = { .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, - .set_link_led = (set_link_led_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led, .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_8073 = { @@ -5918,7 +6196,7 @@ static struct bnx2x_phy phy_8727 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, - .set_link_led = (set_link_led_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led, .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func }; static struct bnx2x_phy phy_8481 = { @@ -5954,7 +6232,7 @@ static struct bnx2x_phy phy_8481 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, - .set_link_led = (set_link_led_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, .phy_specific_func = (phy_specific_func_t)NULL }; @@ -5991,7 +6269,7 @@ static struct bnx2x_phy phy_84823 = { .config_loopback = (config_loopback_t)NULL, .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, .hw_reset = (hw_reset_t)NULL, - .set_link_led = (set_link_led_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, .phy_specific_func = (phy_specific_func_t)NULL }; @@ -6573,7 +6851,8 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); + bnx2x_set_led(params, vars, + LED_MODE_OPER, vars->line_speed); } else /* No loopback */ { @@ -6581,6 +6860,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_xgxs_deassert(params); else bnx2x_serdes_deassert(bp, params->port); + bnx2x_link_initialize(params, vars); msleep(30); bnx2x_link_int_enable(params); @@ -6620,7 +6900,8 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, * Hold it as vars low */ /* clear link led */ - bnx2x_set_led(params, LED_MODE_OFF, 0); + bnx2x_set_led(params, vars, LED_MODE_OFF, 0); + if (reset_ext_phy) { for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 9115c125aeaf..e98ea3d19471 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -296,9 +296,12 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, Basically, the CLC takes care of the led for the link, but in case one needs to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to blink the led, and LED_MODE_OFF to set the led off.*/ -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed); -#define LED_MODE_OFF 0 -#define LED_MODE_OPER 2 +u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars, + u8 mode, u32 speed); +#define LED_MODE_OFF 0 +#define LED_MODE_ON 1 +#define LED_MODE_OPER 2 +#define LED_MODE_FRONT_PANEL_OFF 3 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index f0a69563b66a..6be0d09ad3fd 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -5156,13 +5156,16 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_7101_VER1 0xc026 #define MDIO_PMA_REG_7101_VER2 0xc027 -#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811 -#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c -#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f -#define MDIO_PMA_REG_8481_LED3_MASK 0xa832 -#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834 -#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835 -#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b +#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811 +#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c +#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f +#define MDIO_PMA_REG_8481_LED3_MASK 0xa832 +#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834 +#define MDIO_PMA_REG_8481_LED5_MASK 0xa838 +#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835 +#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b +#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK 0x800 +#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT 11 #define MDIO_WIS_DEVAD 0x2 -- cgit v1.2.3 From c936335e7ac24d1751543e2007a89e3eb649cc2a Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Tue, 7 Sep 2010 11:41:26 +0000 Subject: bnx2x: Update bnx2x version to 1.52.53-6 Note that the date format was fixed. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 137187684f27..b6aaf22a1b84 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-5" -#define DRV_MODULE_RELDATE "2010/01/09" +#define DRV_MODULE_VERSION "1.52.53-6" +#define DRV_MODULE_RELDATE "2010/09/07" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- cgit v1.2.3 From 2edae08e5b75269855fef3c74fe4292c066e7c33 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Sep 2010 18:46:39 +0000 Subject: r8169: add gro support - Use napi_gro_receive() and vlan_gro_receive() - Enable GRO by default Tested on a RTL8111/8168 adapter Signed-off-by: Eric Dumazet Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/r8169.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 56a11e29af0b..54900332f12d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1076,7 +1076,12 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, int ret; if (vlgrp && (opts2 & RxVlanTag)) { - __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling); + u16 vtag = swab16(opts2 & 0xffff); + + if (likely(polling)) + vlan_gro_receive(&tp->napi, vlgrp, vtag, skb); + else + __vlan_hwaccel_rx(skb, vlgrp, vtag, polling); ret = 0; } else ret = -1; @@ -3186,6 +3191,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_R8169_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; #endif + dev->features |= NETIF_F_GRO; tp->intr_mask = 0xffff; tp->align = cfg->align; @@ -4561,7 +4567,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) { if (likely(polling)) - netif_receive_skb(skb); + napi_gro_receive(&tp->napi, skb); else netif_rx(skb); } -- cgit v1.2.3 From 65040c33ee8d0199ab7686402bffdbf9e1e26cbe Mon Sep 17 00:00:00 2001 From: Diego Elio 'Flameeyes' Pettenò Date: Fri, 3 Sep 2010 03:47:03 +0000 Subject: sctp: implement SIOCINQ ioctl() (take 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This simple patch copies the current approach for SIOCINQ ioctl() from DCCP into SCTP so that the userland code working with SCTP can use a similar interface across different protocols to know how much space to allocate for a buffer. Signed-off-by: Diego Elio Pettenò Signed-off-by: David S. Miller --- net/sctp/socket.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index cf6dcc908b88..6a691d84aef4 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3592,7 +3592,40 @@ out: /* The SCTP ioctl handler. */ SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) { - return -ENOIOCTLCMD; + int rc = -ENOTCONN; + + sctp_lock_sock(sk); + + /* + * SEQPACKET-style sockets in LISTENING state are valid, for + * SCTP, so only discard TCP-style sockets in LISTENING state. + */ + if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) + goto out; + + switch (cmd) { + case SIOCINQ: { + struct sk_buff *skb; + unsigned int amount = 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb != NULL) { + /* + * We will only return the amount of this packet since + * that is all that will be read. + */ + amount = skb->len; + } + rc = put_user(amount, (int __user *)arg); + } + break; + default: + rc = -ENOIOCTLCMD; + break; + } +out: + sctp_release_sock(sk); + return rc; } /* This is the function which gets called during socket creation to -- cgit v1.2.3 From 6febfca98f25c7ee5c3ff7fc85e048bf82230ad5 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 3 Sep 2010 23:12:37 +0000 Subject: net: rps: add the shortcut for one rps_cpus When there is only one rps_cpus, skb_get_rxhash() can be eliminated. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/core/dev.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index efd318db11ab..cdbbea39c549 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2343,7 +2343,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, struct rps_dev_flow **rflowp) { struct netdev_rx_queue *rxqueue; - struct rps_map *map; + struct rps_map *map = NULL; struct rps_dev_flow_table *flow_table; struct rps_sock_flow_table *sock_flow_table; int cpu = -1; @@ -2361,8 +2361,17 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, } else rxqueue = dev->_rx; - if (!rxqueue->rps_map && !rxqueue->rps_flow_table) + if (rxqueue->rps_map) { + map = rcu_dereference(rxqueue->rps_map); + if (map && map->len == 1) { + tcpu = map->cpus[0]; + if (cpu_online(tcpu)) + cpu = tcpu; + goto done; + } + } else if (!rxqueue->rps_flow_table) { goto done; + } skb_reset_network_header(skb); if (!skb_get_rxhash(skb)) @@ -2407,7 +2416,6 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, } } - map = rcu_dereference(rxqueue->rps_map); if (map) { tcpu = map->cpus[((u64) skb->rxhash * map->len) >> 32]; -- cgit v1.2.3 From cc28a20e77b261eb4e80c84abd621e810302f435 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 4 Sep 2010 02:39:34 +0000 Subject: introduce cx82310_eth: Conexant CX82310-based ADSL router USB ethernet driver This patch introduces cx82310_eth driver - driver for USB ethernet port of ADSL routers based on Conexant CX82310 chips. Such routers usually have ethernet port(s) too which are bridged together with the USB ethernet port, allowing the USB-connected machine to communicate to the network (and also internet through the ADSL, of course). This is my first driver, so please check thoroughly. As there's no protocol documentation, it was done with usbsnoop dumps from Windows driver, some parts (the commands) inspired by cxacru driver and also other usbnet drivers. The driver passed my testing - some real work and also pings sized from 0 to 65507 B. The only problem I found is the ifconfig error counter. When I return 0 (or 1 but empty skb) from rx_fixup(), usbnet increases the error counter although it's not an error condition (because packets can cross URB boundaries). Maybe the usbnet should be fixed to allow rx_fixup() to return empty skbs (or some other value, e.g. 2)? The USB ID of my device is 0x0572:0xcb01 which conflicts with some ADSL modems using cxacru driver (they probably use the same chipset but simpler firmware). The modems seem to use bDeviceClass 0 and iProduct "ADSL USB MODEM", my router uses bDeviceClass 255 and iProduct "USB NET CARD". The driver matches only devices with class 255 and checks for the iProduct string during init. I already posted a patch for the cxacru driver to ignore these devices. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 8 + drivers/net/usb/Makefile | 1 + drivers/net/usb/cx82310_eth.c | 354 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 drivers/net/usb/cx82310_eth.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index d7b7018a1de1..52ffabe6db0e 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -358,6 +358,14 @@ config USB_NET_ZAURUS really need this non-conformant variant of CDC Ethernet (or in some cases CDC MDLM) protocol, not "g_ether". +config USB_NET_CX82310_ETH + tristate "Conexant CX82310 USB ethernet port" + depends on USB_USBNET + help + Choose this option if you're using a Conexant CX82310-based ADSL + router with USB ethernet port. This driver is for routers only, + it will not work with ADSL modems (use cxacru driver instead). + config USB_HSO tristate "Option USB High Speed Mobile Devices" depends on USB && RFKILL diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b13a279663ba..a19b0259ae16 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -25,4 +25,5 @@ obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o +obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c new file mode 100644 index 000000000000..6fbe03276b27 --- /dev/null +++ b/drivers/net/usb/cx82310_eth.c @@ -0,0 +1,354 @@ +/* + * Driver for USB ethernet port of Conexant CX82310-based ADSL routers + * Copyright (C) 2010 by Ondrej Zary + * some parts inspired by the cxacru driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum cx82310_cmd { + CMD_START = 0x84, /* no effect? */ + CMD_STOP = 0x85, /* no effect? */ + CMD_GET_STATUS = 0x90, /* returns nothing? */ + CMD_GET_MAC_ADDR = 0x91, /* read MAC address */ + CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */ + CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */ +}; + +enum cx82310_status { + STATUS_UNDEFINED, + STATUS_SUCCESS, + STATUS_ERROR, + STATUS_UNSUPPORTED, + STATUS_UNIMPLEMENTED, + STATUS_PARAMETER_ERROR, + STATUS_DBG_LOOPBACK, +}; + +#define CMD_PACKET_SIZE 64 +/* first command after power on can take around 8 seconds */ +#define CMD_TIMEOUT 15000 +#define CMD_REPLY_RETRY 5 + +#define CX82310_MTU 1514 +#define CMD_EP 0x01 + +/* + * execute control command + * - optionally send some data (command parameters) + * - optionally wait for the reply + * - optionally read some data from the reply + */ +static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply, + u8 *wdata, int wlen, u8 *rdata, int rlen) +{ + int actual_len, retries, ret; + struct usb_device *udev = dev->udev; + u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + /* create command packet */ + buf[0] = cmd; + if (wdata) + memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4)); + + /* send command packet */ + ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf, + CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT); + if (ret < 0) { + dev_err(&dev->udev->dev, "send command %#x: error %d\n", + cmd, ret); + goto end; + } + + if (reply) { + /* wait for reply, retry if it's empty */ + for (retries = 0; retries < CMD_REPLY_RETRY; retries++) { + ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP), + buf, CMD_PACKET_SIZE, &actual_len, + CMD_TIMEOUT); + if (ret < 0) { + dev_err(&dev->udev->dev, + "reply receive error %d\n", ret); + goto end; + } + if (actual_len > 0) + break; + } + if (actual_len == 0) { + dev_err(&dev->udev->dev, "no reply to command %#x\n", + cmd); + ret = -EIO; + goto end; + } + if (buf[0] != cmd) { + dev_err(&dev->udev->dev, + "got reply to command %#x, expected: %#x\n", + buf[0], cmd); + ret = -EIO; + goto end; + } + if (buf[1] != STATUS_SUCCESS) { + dev_err(&dev->udev->dev, "command %#x failed: %#x\n", + cmd, buf[1]); + ret = -EIO; + goto end; + } + if (rdata) + memcpy(rdata, buf + 4, + min_t(int, rlen, CMD_PACKET_SIZE - 4)); + } +end: + kfree(buf); + return ret; +} + +#define partial_len data[0] /* length of partial packet data */ +#define partial_rem data[1] /* remaining (missing) data length */ +#define partial_data data[2] /* partial packet data */ + +static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + char buf[15]; + struct usb_device *udev = dev->udev; + + /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ + if (udev->descriptor.iProduct && + usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) && + strcmp(buf, "USB NET CARD")) { + dev_err(&udev->dev, + "probably an ADSL modem, use cxacru driver instead\n"); + return -ENODEV; + } + + ret = usbnet_get_endpoints(dev, intf); + if (ret) + return ret; + + /* + * this must not include ethernet header as the device can send partial + * packets with no header (URB is at least 2 bytes long, so 2 is OK) + */ + dev->net->hard_header_len = 2; + /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */ + dev->hard_mtu = CX82310_MTU + dev->net->hard_header_len; + /* we can receive URBs up to 4KB from the device */ + dev->rx_urb_size = 4096; + + dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL); + if (!dev->partial_data) + return -ENOMEM; + + /* enable ethernet mode (?) */ + ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0); + if (ret) { + dev_err(&udev->dev, "unable to enable ethernet mode: %d\n", + ret); + goto err; + } + + /* get the MAC address */ + ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0, + dev->net->dev_addr, ETH_ALEN); + if (ret) { + dev_err(&udev->dev, "unable to read MAC address: %d\n", ret); + goto err; + } + + /* start (does not seem to have any effect?) */ + ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0); + if (ret) + goto err; + + return 0; +err: + kfree((void *)dev->partial_data); + return ret; +} + +static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + kfree((void *)dev->partial_data); +} + +/* + * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte + * packet length at the beginning. + * The last packet might be incomplete (when it crosses the 4KB URB size), + * continuing in the next skb (without any headers). + * If a packet has odd length, there is one extra byte at the end (before next + * packet or at the end of the URB). + */ +static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + int len; + struct sk_buff *skb2; + + /* + * If the last skb ended with an incomplete packet, this skb contains + * end of that packet at the beginning. + */ + if (dev->partial_rem) { + len = dev->partial_len + dev->partial_rem; + skb2 = alloc_skb(len, GFP_ATOMIC); + if (!skb2) + return 0; + skb_put(skb2, len); + memcpy(skb2->data, (void *)dev->partial_data, + dev->partial_len); + memcpy(skb2->data + dev->partial_len, skb->data, + dev->partial_rem); + usbnet_skb_return(dev, skb2); + skb_pull(skb, (dev->partial_rem + 1) & ~1); + dev->partial_rem = 0; + if (skb->len < 2) + return 1; + } + + if (skb->len < 2) { + dev_err(&dev->udev->dev, "RX frame too short: %d B\n", + skb->len); + return 0; + } + + /* a skb can contain multiple packets */ + while (skb->len > 1) { + /* first two bytes are packet length */ + len = skb->data[0] | (skb->data[1] << 8); + skb_pull(skb, 2); + + /* if last packet in the skb, let usbnet to process it */ + if (len == skb->len || len + 1 == skb->len) { + skb_trim(skb, len); + break; + } + + if (len > CX82310_MTU) { + dev_err(&dev->udev->dev, "RX packet too long: %d B\n", + len); + return 0; + } + + /* incomplete packet, save it for the next skb */ + if (len > skb->len) { + dev->partial_len = skb->len; + dev->partial_rem = len - skb->len; + memcpy((void *)dev->partial_data, skb->data, + dev->partial_len); + skb_pull(skb, skb->len); + break; + } + + skb2 = alloc_skb(len, GFP_ATOMIC); + if (!skb2) + return 0; + skb_put(skb2, len); + memcpy(skb2->data, skb->data, len); + /* process the packet */ + usbnet_skb_return(dev, skb2); + + skb_pull(skb, (len + 1) & ~1); + } + + /* let usbnet process the last packet */ + return 1; +} + +/* TX is easy, just add 2 bytes of length at the beginning */ +static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) +{ + int len = skb->len; + + if (skb_headroom(skb) < 2) { + struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + skb_push(skb, 2); + + skb->data[0] = len; + skb->data[1] = len >> 8; + + return skb; +} + + +static const struct driver_info cx82310_info = { + .description = "Conexant CX82310 USB ethernet", + .flags = FLAG_ETHER, + .bind = cx82310_bind, + .unbind = cx82310_unbind, + .rx_fixup = cx82310_rx_fixup, + .tx_fixup = cx82310_tx_fixup, +}; + +#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_DEV_INFO, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bDeviceClass = (cl), \ + .bDeviceSubClass = (sc), \ + .bDeviceProtocol = (pr) + +static const struct usb_device_id products[] = { + { + USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0), + .driver_info = (unsigned long) &cx82310_info + }, + { }, +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver cx82310_driver = { + .name = "cx82310_eth", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, +}; + +static int __init cx82310_init(void) +{ + return usb_register(&cx82310_driver); +} +module_init(cx82310_init); + +static void __exit cx82310_exit(void) +{ + usb_deregister(&cx82310_driver); +} +module_exit(cx82310_exit); + +MODULE_AUTHOR("Ondrej Zary"); +MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e3634169bcc0cce33c815865d62ab378739f7389 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Sep 2010 05:55:38 +0000 Subject: include/net/raw.h: Convert raw_seq_private macro to inline Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/raw.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/net/raw.h b/include/net/raw.h index 43c57502659b..42ce6fe7a2d5 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -45,7 +45,10 @@ struct raw_iter_state { struct raw_hashinfo *h; }; -#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private) +static inline struct raw_iter_state *raw_seq_private(struct seq_file *seq) +{ + return seq->private; +} void *raw_seq_start(struct seq_file *seq, loff_t *pos); void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos); void raw_seq_stop(struct seq_file *seq, void *v); -- cgit v1.2.3 From fb8621bb6c040a25ac2fc246653859f841a1f53d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 7 Sep 2010 03:55:00 +0000 Subject: net: remove address space warnings in net/socket.c Casts __kernel to __user pointer require __force markup, so add it. Also sock_get/setsockopt() takes @optval and/or @optlen arguments as user pointers but were taking kernel pointers, use new variables 'uoptval' and/or 'uoptlen' to fix it. These remove following warnings from sparse: net/socket.c:1922:46: warning: cast adds address space to expression () net/socket.c:3061:61: warning: incorrect type in argument 4 (different address spaces) net/socket.c:3061:61: expected char [noderef] *optval net/socket.c:3061:61: got char *optval net/socket.c:3061:69: warning: incorrect type in argument 5 (different address spaces) net/socket.c:3061:69: expected int [noderef] *optlen net/socket.c:3061:69: got int *optlen net/socket.c:3063:67: warning: incorrect type in argument 4 (different address spaces) net/socket.c:3063:67: expected char [noderef] *optval net/socket.c:3063:67: got char *optval net/socket.c:3064:45: warning: incorrect type in argument 5 (different address spaces) net/socket.c:3064:45: expected int [noderef] *optlen net/socket.c:3064:45: got int *optlen net/socket.c:3078:61: warning: incorrect type in argument 4 (different address spaces) net/socket.c:3078:61: expected char [noderef] *optval net/socket.c:3078:61: got char *optval net/socket.c:3080:67: warning: incorrect type in argument 4 (different address spaces) net/socket.c:3080:67: expected char [noderef] *optval net/socket.c:3080:67: got char *optval Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- net/socket.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/net/socket.c b/net/socket.c index 7848d12f5e4d..717a5f1c8792 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1918,7 +1918,8 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) * Afterwards, it will be a kernel pointer. Thus the compiler-assisted * checking falls down on this. */ - if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control, + if (copy_from_user(ctl_buf, + (void __user __force *)msg_sys.msg_control, ctl_len)) goto out_freectl; msg_sys.msg_control = ctl_buf; @@ -3053,14 +3054,19 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { mm_segment_t oldfs = get_fs(); + char __user *uoptval; + int __user *uoptlen; int err; + uoptval = (char __user __force *) optval; + uoptlen = (int __user __force *) optlen; + set_fs(KERNEL_DS); if (level == SOL_SOCKET) - err = sock_getsockopt(sock, level, optname, optval, optlen); + err = sock_getsockopt(sock, level, optname, uoptval, uoptlen); else - err = sock->ops->getsockopt(sock, level, optname, optval, - optlen); + err = sock->ops->getsockopt(sock, level, optname, uoptval, + uoptlen); set_fs(oldfs); return err; } @@ -3070,13 +3076,16 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval, unsigned int optlen) { mm_segment_t oldfs = get_fs(); + char __user *uoptval; int err; + uoptval = (char __user __force *) optval; + set_fs(KERNEL_DS); if (level == SOL_SOCKET) - err = sock_setsockopt(sock, level, optname, optval, optlen); + err = sock_setsockopt(sock, level, optname, uoptval, optlen); else - err = sock->ops->setsockopt(sock, level, optname, optval, + err = sock->ops->setsockopt(sock, level, optname, uoptval, optlen); set_fs(oldfs); return err; -- cgit v1.2.3 From a7a4f1c1a52912eb8b3bd4d8f628d83a8b5d69dd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Sep 2010 05:14:30 +0000 Subject: drivers: isdn: capi: use simple_strtol to convert numbers Signed-off-by: Andy Shevchenko Cc: Karsten Keil Cc: Tilman Schmidt Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/capi/capidrv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 2978bdaa6b88..e54e79d4e2c1 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -1515,8 +1515,13 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) while (*s) { int digit1 = 0; int digit2 = 0; - if (!isdigit(*s)) return -3; - while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; } + char *endp; + + digit1 = simple_strtoul(s, &endp, 10); + if (s == endp) + return -3; + s = endp; + if (digit1 <= 0 || digit1 > 30) return -4; if (*s == 0 || *s == ',' || *s == ' ') { bmask |= (1 << digit1); @@ -1526,8 +1531,12 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) } if (*s != '-') return -5; s++; - if (!isdigit(*s)) return -3; - while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; } + + digit2 = simple_strtoul(s, &endp, 10); + if (s == endp) + return -3; + s = endp; + if (digit2 <= 0 || digit2 > 30) return -4; if (*s == 0 || *s == ',' || *s == ' ') { if (digit1 > digit2) -- cgit v1.2.3 From a6e0fc8514d41dfdd98b1d15cacc432cf040f8af Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 8 Sep 2010 14:15:32 -0700 Subject: net: introduce rcu_dereference_rtnl We use rcu_dereference_check(p, rcu_read_lock_held() || lockdep_rtnl_is_held()) several times in network stack. More usages to come too, so its time to create a helper. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 58d44491880f..263690d991a8 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -749,6 +749,17 @@ extern int rtnl_is_locked(void); extern int lockdep_rtnl_is_held(void); #endif /* #ifdef CONFIG_PROVE_LOCKING */ +/** + * rcu_dereference_rtnl - rcu_dereference with debug checking + * @p: The pointer to read, prior to dereferencing + * + * Do an rcu_dereference(p), but check caller either holds rcu_read_lock() + * or RTNL + */ +#define rcu_dereference_rtnl(p) \ + rcu_dereference_check(p, rcu_read_lock_held() || \ + lockdep_rtnl_is_held()) + extern void rtnetlink_init(void); extern void __rtnl_unlock(void); -- cgit v1.2.3 From e508be174ad36b0cf9b324cd04978c2b13c21502 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 7 Sep 2010 21:01:12 +0000 Subject: e1000: fix Tx hangs by disabling 64-bit DMA Several users report issues with 32-bit adapters when plugged into PCI slots in machines with >= 4GB ram. In particular AMD systems with HyperTransport to PCI bridges seem to trigger the issue, but it isn't limited to only them. This issue is not easily reproducible here, yet still continues to occur in the field. For e1000 on PCI devices, just disable DMA addresses over the 4GB boundary when in PCI (not PCI-X) mode, to prevent the issue from continuing to pop up. The performance impact for this is negligible. The code was refactored to move the init of the hw struct to its own function. This allows the init to be called very early in probe, which then allows using hw-> members for this fix. A slight refactor to the DMA mask code was done for minor correctness based on the instructions in DMA-API-HOWTO. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 162 +++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 70 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 17f5867b5d9b..8d9269d12a67 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -789,6 +789,70 @@ static const struct net_device_ops e1000_netdev_ops = { #endif }; +/** + * e1000_init_hw_struct - initialize members of hw struct + * @adapter: board private struct + * @hw: structure used by e1000_hw.c + * + * Factors out initialization of the e1000_hw struct to its own function + * that can be called very early at init (just after struct allocation). + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + * Returns negative error codes if MAC type setup fails. + */ +static int e1000_init_hw_struct(struct e1000_adapter *adapter, + struct e1000_hw *hw) +{ + struct pci_dev *pdev = adapter->pdev; + + /* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_id = pdev->subsystem_device; + hw->revision_id = pdev->revision; + + pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); + + hw->max_frame_size = adapter->netdev->mtu + + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; + hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; + + /* identify the MAC */ + if (e1000_set_mac_type(hw)) { + e_err(probe, "Unknown MAC Type\n"); + return -EIO; + } + + switch (hw->mac_type) { + default: + break; + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->phy_init_script = 1; + break; + } + + e1000_set_media_type(hw); + e1000_get_bus_info(hw); + + hw->wait_autoneg_complete = false; + hw->tbi_compatibility_en = true; + hw->adaptive_ifs = true; + + /* Copper options */ + + if (hw->media_type == e1000_media_type_copper) { + hw->mdix = AUTO_ALL_MODES; + hw->disable_polarity_correction = false; + hw->master_slave = E1000_MASTER_SLAVE; + } + + return 0; +} + /** * e1000_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -826,22 +890,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) return err; - if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && - !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { - pci_using_dac = 1; - } else { - err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (err) { - err = dma_set_coherent_mask(&pdev->dev, - DMA_BIT_MASK(32)); - if (err) { - pr_err("No usable DMA config, aborting\n"); - goto err_dma; - } - } - pci_using_dac = 0; - } - err = pci_request_selected_regions(pdev, bars, e1000_driver_name); if (err) goto err_pci_reg; @@ -885,6 +933,32 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } } + /* make ready for any if (hw->...) below */ + err = e1000_init_hw_struct(adapter, hw); + if (err) + goto err_sw_init; + + /* + * there is a workaround being applied below that limits + * 64-bit DMA addresses to 64-bit hardware. There are some + * 32-bit adapters that Tx hang when given 64-bit DMA addresses + */ + pci_using_dac = 0; + if ((hw->bus_type == e1000_bus_type_pcix) && + !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { + /* + * according to DMA-API-HOWTO, coherent calls will always + * succeed if the set call did + */ + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); + pci_using_dac = 1; + } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + } else { + pr_err("No usable DMA config, aborting\n"); + goto err_dma; + } + netdev->netdev_ops = &e1000_netdev_ops; e1000_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; @@ -959,8 +1033,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!is_valid_ether_addr(netdev->perm_addr)) e_err(probe, "Invalid MAC Address\n"); - e1000_get_bus_info(hw); - init_timer(&adapter->tx_fifo_stall_timer); adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall; adapter->tx_fifo_stall_timer.data = (unsigned long)adapter; @@ -1072,6 +1144,7 @@ err_eeprom: iounmap(hw->flash_address); kfree(adapter->tx_ring); kfree(adapter->rx_ring); +err_dma: err_sw_init: iounmap(hw->hw_addr); err_ioremap: @@ -1079,7 +1152,6 @@ err_ioremap: err_alloc_etherdev: pci_release_selected_regions(pdev, bars); err_pci_reg: -err_dma: pci_disable_device(pdev); return err; } @@ -1131,62 +1203,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev) * @adapter: board private structure to initialize * * e1000_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). + * e1000_init_hw_struct MUST be called before this function **/ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) { - struct e1000_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* PCI config space info */ - - hw->vendor_id = pdev->vendor; - hw->device_id = pdev->device; - hw->subsystem_vendor_id = pdev->subsystem_vendor; - hw->subsystem_id = pdev->subsystem_device; - hw->revision_id = pdev->revision; - - pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; - hw->max_frame_size = netdev->mtu + - ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; - - /* identify the MAC */ - - if (e1000_set_mac_type(hw)) { - e_err(probe, "Unknown MAC Type\n"); - return -EIO; - } - - switch (hw->mac_type) { - default: - break; - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->phy_init_script = 1; - break; - } - - e1000_set_media_type(hw); - - hw->wait_autoneg_complete = false; - hw->tbi_compatibility_en = true; - hw->adaptive_ifs = true; - - /* Copper options */ - - if (hw->media_type == e1000_media_type_copper) { - hw->mdix = AUTO_ALL_MODES; - hw->disable_polarity_correction = false; - hw->master_slave = E1000_MASTER_SLAVE; - } adapter->num_tx_queues = 1; adapter->num_rx_queues = 1; -- cgit v1.2.3 From d36deae75011a7890f0e730dd0f867c64081cb50 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Tue, 7 Sep 2010 21:14:39 +0000 Subject: qdio: extend API to allow polling Extend the qdio API to allow polling in the upper-layer driver. This is needed by qeth to use NAPI. To use the new interface the upper-layer driver must specify the queue_start_poll(). This callback is used to signal the upper-layer driver that is has initiative and must process the inbound queue by calling qdio_get_next_buffers(). If the upper-layer driver wants to stop polling it calls qdio_start_irq(). Since adapter interrupts are not completely stoppable qdio implements a software bit QDIO_QUEUE_IRQS_DISABLED to safely disable interrupts for an input queue. The old interface is preserved and will be used as is by zfcp. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- arch/s390/include/asm/qdio.h | 13 ++-- drivers/s390/cio/qdio.h | 29 +++++++++ drivers/s390/cio/qdio_debug.c | 33 ++++------ drivers/s390/cio/qdio_main.c | 138 +++++++++++++++++++++++++++++++++++++++- drivers/s390/cio/qdio_setup.c | 1 + drivers/s390/cio/qdio_thinint.c | 66 +++++++++++-------- drivers/s390/scsi/zfcp_qdio.c | 6 +- 7 files changed, 225 insertions(+), 61 deletions(-) diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 2ba630276295..46e96bc1f5a1 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -360,6 +360,7 @@ struct qdio_initialize { unsigned int no_output_qs; qdio_handler_t *input_handler; qdio_handler_t *output_handler; + void (*queue_start_poll) (struct ccw_device *, int, unsigned long); unsigned long int_parm; void **input_sbal_addr_array; void **output_sbal_addr_array; @@ -377,11 +378,13 @@ struct qdio_initialize { extern int qdio_allocate(struct qdio_initialize *); extern int qdio_establish(struct qdio_initialize *); extern int qdio_activate(struct ccw_device *); - -extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, - int q_nr, unsigned int bufnr, unsigned int count); -extern int qdio_shutdown(struct ccw_device*, int); +extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int, + unsigned int); +extern int qdio_start_irq(struct ccw_device *, int); +extern int qdio_stop_irq(struct ccw_device *, int); +extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *); +extern int qdio_shutdown(struct ccw_device *, int); extern int qdio_free(struct ccw_device *); -extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*); +extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); #endif /* __QDIO_H__ */ diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index f0037eefd44e..0f4ef8769a3d 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -208,6 +208,7 @@ struct qdio_dev_perf_stat { unsigned int eqbs_partial; unsigned int sqbs; unsigned int sqbs_partial; + unsigned int int_discarded; } ____cacheline_aligned; struct qdio_queue_perf_stat { @@ -222,6 +223,10 @@ struct qdio_queue_perf_stat { unsigned int nr_sbal_total; }; +enum qdio_queue_irq_states { + QDIO_QUEUE_IRQS_DISABLED, +}; + struct qdio_input_q { /* input buffer acknowledgement flag */ int polling; @@ -231,6 +236,10 @@ struct qdio_input_q { int ack_count; /* last time of noticing incoming data */ u64 timestamp; + /* upper-layer polling flag */ + unsigned long queue_irq_state; + /* callback to start upper-layer polling */ + void (*queue_start_poll) (struct ccw_device *, int, unsigned long); }; struct qdio_output_q { @@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q) #define sub_buf(bufnr, dec) \ ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK) +#define queue_irqs_enabled(q) \ + (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0) +#define queue_irqs_disabled(q) \ + (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) + +#define TIQDIO_SHARED_IND 63 + +/* device state change indicators */ +struct indicator_t { + u32 ind; /* u32 because of compare-and-swap performance */ + atomic_t count; /* use count, 0 or 1 for non-shared indicators */ +}; + +extern struct indicator_t *q_indicators; + +static inline int shared_ind(struct qdio_irq *irq_ptr) +{ + return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; +} + /* prototypes for thin interrupt */ void qdio_setup_thinint(struct qdio_irq *irq_ptr); int qdio_establish_thinint(struct qdio_irq *irq_ptr); diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 6ce83f56d537..28868e7471a5 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -56,9 +56,16 @@ static int qstat_show(struct seq_file *m, void *v) seq_printf(m, "DSCI: %d nr_used: %d\n", *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); - seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); - seq_printf(m, "polling: %d ack start: %d ack count: %d\n", - q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); + seq_printf(m, "ftc: %d last_move: %d\n", + q->first_to_check, q->last_move); + if (q->is_input_q) { + seq_printf(m, "polling: %d ack start: %d ack count: %d\n", + q->u.in.polling, q->u.in.ack_start, + q->u.in.ack_count); + seq_printf(m, "IRQs disabled: %u\n", + test_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)); + } seq_printf(m, "SBAL states:\n"); seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); @@ -113,22 +120,6 @@ static int qstat_show(struct seq_file *m, void *v) return 0; } -static ssize_t qstat_seq_write(struct file *file, const char __user *buf, - size_t count, loff_t *off) -{ - struct seq_file *seq = file->private_data; - struct qdio_q *q = seq->private; - - if (!q) - return 0; - if (q->is_input_q) - xchg(q->irq_ptr->dsci, 1); - local_bh_disable(); - tasklet_schedule(&q->tasklet); - local_bh_enable(); - return count; -} - static int qstat_seq_open(struct inode *inode, struct file *filp) { return single_open(filp, qstat_show, @@ -139,7 +130,6 @@ static const struct file_operations debugfs_fops = { .owner = THIS_MODULE, .open = qstat_seq_open, .read = seq_read, - .write = qstat_seq_write, .llseek = seq_lseek, .release = single_release, }; @@ -166,7 +156,8 @@ static char *qperf_names[] = { "QEBSM eqbs", "QEBSM eqbs partial", "QEBSM sqbs", - "QEBSM sqbs partial" + "QEBSM sqbs partial", + "Discarded interrupts" }; static int qperf_show(struct seq_file *m, void *v) diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 00520f9a7a8e..5fcfa7f9e9ef 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -884,8 +884,19 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) return; - for_each_input_queue(irq_ptr, q, i) - tasklet_schedule(&q->tasklet); + for_each_input_queue(irq_ptr, q, i) { + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) { + qperf_inc(q, int_discarded); + continue; + } + q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, + q->irq_ptr->int_parm); + } else + tasklet_schedule(&q->tasklet); + } if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) return; @@ -1519,6 +1530,129 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags, } EXPORT_SYMBOL_GPL(do_QDIO); +/** + * qdio_start_irq - process input buffers + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * + * Return codes + * 0 - success + * 1 - irqs not started since new data is available + */ +int qdio_start_irq(struct ccw_device *cdev, int nr) +{ + struct qdio_q *q; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + + WARN_ON(queue_irqs_enabled(q)); + + if (!shared_ind(q->irq_ptr)) + xchg(q->irq_ptr->dsci, 0); + + qdio_stop_polling(q); + clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state); + + /* + * We need to check again to not lose initiative after + * resetting the ACK state. + */ + if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci) + goto rescan; + if (!qdio_inbound_q_done(q)) + goto rescan; + return 0; + +rescan: + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) + return 0; + else + return 1; + +} +EXPORT_SYMBOL(qdio_start_irq); + +/** + * qdio_get_next_buffers - process input buffers + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * @bufnr: first filled buffer number + * @error: buffers are in error state + * + * Return codes + * < 0 - error + * = 0 - no new buffers found + * > 0 - number of processed buffers + */ +int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, + int *error) +{ + struct qdio_q *q; + int start, end; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + WARN_ON(queue_irqs_enabled(q)); + + qdio_sync_after_thinint(q); + + /* + * The interrupt could be caused by a PCI request. Check the + * PCI capable outbound queues. + */ + qdio_check_outbound_after_thinint(q); + + if (!qdio_inbound_q_moved(q)) + return 0; + + /* Note: upper-layer MUST stop processing immediately here ... */ + if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) + return -EIO; + + start = q->first_to_kick; + end = q->first_to_check; + *bufnr = start; + *error = q->qdio_error; + + /* for the next time */ + q->first_to_kick = end; + q->qdio_error = 0; + return sub_buf(end, start); +} +EXPORT_SYMBOL(qdio_get_next_buffers); + +/** + * qdio_stop_irq - disable interrupt processing for the device + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * + * Return codes + * 0 - interrupts were already disabled + * 1 - interrupts successfully disabled + */ +int qdio_stop_irq(struct ccw_device *cdev, int nr) +{ + struct qdio_q *q; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) + return 0; + else + return 1; +} +EXPORT_SYMBOL(qdio_stop_irq); + static int __init init_QDIO(void) { int rc; diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 34c7e4046df4..a13cf7ec64b2 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -161,6 +161,7 @@ static void setup_queues(struct qdio_irq *irq_ptr, setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); q->is_input_q = 1; + q->u.in.queue_start_poll = qdio_init->queue_start_poll; setup_storage_lists(q, irq_ptr, input_sbal_array, i); input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 8daf1b99f153..752dbee06af5 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -25,24 +25,20 @@ */ #define TIQDIO_NR_NONSHARED_IND 63 #define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) -#define TIQDIO_SHARED_IND 63 /* list of thin interrupt input queues */ static LIST_HEAD(tiq_list); DEFINE_MUTEX(tiq_list_lock); /* adapter local summary indicator */ -static unsigned char *tiqdio_alsi; +static u8 *tiqdio_alsi; -/* device state change indicators */ -struct indicator_t { - u32 ind; /* u32 because of compare-and-swap performance */ - atomic_t count; /* use count, 0 or 1 for non-shared indicators */ -}; -static struct indicator_t *q_indicators; +struct indicator_t *q_indicators; static int css_qdio_omit_svs; +static u64 last_ai_time; + static inline unsigned long do_clear_global_summary(void) { register unsigned long __fn asm("1") = 3; @@ -116,59 +112,73 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) } } -static inline int shared_ind(struct qdio_irq *irq_ptr) +static inline int shared_ind_used(void) { - return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; + return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count); } /** * tiqdio_thinint_handler - thin interrupt handler for qdio - * @ind: pointer to adapter local summary indicator - * @drv_data: NULL + * @alsi: pointer to adapter local summary indicator + * @data: NULL */ -static void tiqdio_thinint_handler(void *ind, void *drv_data) +static void tiqdio_thinint_handler(void *alsi, void *data) { struct qdio_q *q; + last_ai_time = S390_lowcore.int_clock; + /* * SVS only when needed: issue SVS to benefit from iqdio interrupt - * avoidance (SVS clears adapter interrupt suppression overwrite) + * avoidance (SVS clears adapter interrupt suppression overwrite). */ if (!css_qdio_omit_svs) do_clear_global_summary(); - /* - * reset local summary indicator (tiqdio_alsi) to stop adapter - * interrupts for now - */ - xchg((u8 *)ind, 0); + /* reset local summary indicator */ + if (shared_ind_used()) + xchg(tiqdio_alsi, 0); /* protect tiq_list entries, only changed in activate or shutdown */ rcu_read_lock(); /* check for work on all inbound thinint queues */ - list_for_each_entry_rcu(q, &tiq_list, entry) + list_for_each_entry_rcu(q, &tiq_list, entry) { + /* only process queues from changed sets */ - if (*q->irq_ptr->dsci) { - qperf_inc(q, adapter_int); + if (!*q->irq_ptr->dsci) + continue; + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) { + qperf_inc(q, int_discarded); + continue; + } + + /* avoid dsci clear here, done after processing */ + q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, + q->irq_ptr->int_parm); + } else { /* only clear it if the indicator is non-shared */ if (!shared_ind(q->irq_ptr)) xchg(q->irq_ptr->dsci, 0); /* - * don't call inbound processing directly since - * that could starve other thinint queues + * Call inbound processing but not directly + * since that could starve other thinint queues. */ tasklet_schedule(&q->tasklet); } - + qperf_inc(q, adapter_int); + } rcu_read_unlock(); /* - * if we used the shared indicator clear it now after all queues - * were processed + * If the shared indicator was used clear it now after all queues + * were processed. */ - if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) { + if (shared_ind_used()) { xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); /* prevent racing */ diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index b2635759721c..da54a28a1b87 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -277,16 +277,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, struct zfcp_qdio *qdio) { - + memset(id, 0, sizeof(*id)); id->cdev = qdio->adapter->ccw_device; id->q_format = QDIO_ZFCP_QFMT; memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); ASCEBC(id->adapter_name, 8); id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; - id->qib_param_field_format = 0; - id->qib_param_field = NULL; - id->input_slib_elements = NULL; - id->output_slib_elements = NULL; id->no_input_qs = 1; id->no_output_qs = 1; id->input_handler = zfcp_qdio_int_resp; -- cgit v1.2.3 From 963a9fd22d7e5b50806f619ef8d047fd9398f105 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Sep 2010 21:14:40 +0000 Subject: qeth: Use %pI6 Format an ipv6 address using vsprintf extensions. Signed-off-by: Joe Perches Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e22ae248f613..561bdc881e92 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) { - sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" - ":%02x%02x:%02x%02x:%02x%02x:%02x%02x", - addr[0], addr[1], addr[2], addr[3], - addr[4], addr[5], addr[6], addr[7], - addr[8], addr[9], addr[10], addr[11], - addr[12], addr[13], addr[14], addr[15]); + sprintf(buf, "%pI6", addr); } int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) -- cgit v1.2.3 From 81d53749416995538f830c8e4d3fbaf1769b9375 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 7 Sep 2010 21:14:41 +0000 Subject: Kconfig: have CCWGROUP depend on CLAW Since the claw code calls ccwgroup_remove_ccwdev(), we need to make sure CCWGROUP is enabled when CLAW is enabled. Otherwise we hit fun undefined references at build time: ERROR: "ccwgroup_remove_ccwdev" [drivers/s390/net/claw.ko] undefined! ERROR: "ccwgroup_probe_ccwdev" [drivers/s390/net/claw.ko] undefined! ERROR: "ccwgroup_driver_register" [drivers/s390/net/claw.ko] undefined! ERROR: "ccwgroup_driver_unregister" [drivers/s390/net/claw.ko] undefined! ERROR: "ccwgroup_create_from_string" [drivers/s390/net/claw.ko] undefined! Signed-off-by: Mike Frysinger Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 977bb4d4ed15..456b18743397 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -100,6 +100,6 @@ config QETH_IPV6 config CCWGROUP tristate - default (LCS || CTCM || QETH) + default (LCS || CTCM || QETH || CLAW) endmenu -- cgit v1.2.3 From a1c3ed4c9ca01dded8d511a1d1daf271fbae8d89 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Tue, 7 Sep 2010 21:14:42 +0000 Subject: qeth: NAPI support for l2 and l3 discipline This patch adds NAPI support to the qeth layer 2 and layer 3 discipline. It is important to understand that we can not enable/disable IRQs as usual, we have to use the corresponding new QDIO interface. Also to not overdraw the budget we have to stop and restart buffer processing at any point during processing a bulk of QDIO buffers. Having the driver NAPI enabled it is possible to turn on GRO for the layer 3 discipline. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 17 ++++ drivers/s390/net/qeth_core_main.c | 26 +++++- drivers/s390/net/qeth_l2_main.c | 173 ++++++++++++++++++++++-------------- drivers/s390/net/qeth_l3_main.c | 182 +++++++++++++++++++++++--------------- 4 files changed, 260 insertions(+), 138 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d1257768be90..6be43eb126b4 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -676,6 +676,7 @@ enum qeth_discipline_id { }; struct qeth_discipline { + void (*start_poll)(struct ccw_device *, int, unsigned long); qdio_handler_t *input_handler; qdio_handler_t *output_handler; int (*recover)(void *ptr); @@ -702,6 +703,16 @@ struct qeth_skb_data { #define QETH_SKB_MAGIC 0x71657468 #define QETH_SIGA_CC2_RETRIES 3 +struct qeth_rx { + int b_count; + int b_index; + struct qdio_buffer_element *b_element; + int e_offset; + int qdio_err; +}; + +#define QETH_NAPI_WEIGHT 128 + struct qeth_card { struct list_head list; enum qeth_card_states state; @@ -749,6 +760,8 @@ struct qeth_card { debug_info_t *debug; struct mutex conf_mutex; struct mutex discipline_mutex; + struct napi_struct napi; + struct qeth_rx rx; }; struct qeth_card_list_struct { @@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qdio_buffer *, struct qdio_buffer_element **, int *, struct qeth_hdr **); void qeth_schedule_recovery(struct qeth_card *); +void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long); +void qeth_qdio_input_handler(struct ccw_device *, + unsigned int, unsigned int, int, + int, unsigned long); void qeth_qdio_output_handler(struct ccw_device *, unsigned int, int, int, int, unsigned long); void qeth_clear_ipacmd_list(struct qeth_card *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3a5a18a0fc28..764267062601 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) } } +void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue, + unsigned long card_ptr) +{ + struct qeth_card *card = (struct qeth_card *)card_ptr; + + if (card->dev) + napi_schedule(&card->napi); +} +EXPORT_SYMBOL_GPL(qeth_qdio_start_poll); + +void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err, + unsigned int queue, int first_element, int count, + unsigned long card_ptr) +{ + struct qeth_card *card = (struct qeth_card *)card_ptr; + + if (qdio_err) + qeth_schedule_recovery(card); +} +EXPORT_SYMBOL_GPL(qeth_qdio_input_handler); + void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int qdio_error, int __queue, int first_element, int count, unsigned long card_ptr) @@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card) init_data.no_output_qs = card->qdio.no_out_queues; init_data.input_handler = card->discipline.input_handler; init_data.output_handler = card->discipline.output_handler; + init_data.queue_start_poll = card->discipline.start_poll; init_data.int_parm = (unsigned long) card; init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; @@ -4513,8 +4535,8 @@ static struct { /* 20 */{"queue 1 buffer usage"}, {"queue 2 buffer usage"}, {"queue 3 buffer usage"}, - {"rx handler time"}, - {"rx handler count"}, + {"rx poll time"}, + {"rx poll count"}, {"rx do_QDIO time"}, {"rx do_QDIO count"}, {"tx handler time"}, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 830d63524d61..01c3c1f77879 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -407,29 +407,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) return rc; } -static void qeth_l2_process_inbound_buffer(struct qeth_card *card, - struct qeth_qdio_buffer *buf, int index) +static int qeth_l2_process_inbound_buffer(struct qeth_card *card, + int budget, int *done) { - struct qdio_buffer_element *element; + int work_done = 0; struct sk_buff *skb; struct qeth_hdr *hdr; - int offset; unsigned int len; - /* get first element of current buffer */ - element = (struct qdio_buffer_element *)&buf->buffer->element[0]; - offset = 0; - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, - &offset, &hdr))) { - skb->dev = card->dev; - /* is device UP ? */ - if (!(card->dev->flags & IFF_UP)) { - dev_kfree_skb_any(skb); - continue; + *done = 0; + BUG_ON(!budget); + while (budget) { + skb = qeth_core_get_next_skb(card, + card->qdio.in_q->bufs[card->rx.b_index].buffer, + &card->rx.b_element, &card->rx.e_offset, &hdr); + if (!skb) { + *done = 1; + break; } - + skb->dev = card->dev; switch (hdr->hdr.l2.id) { case QETH_HEADER_TYPE_LAYER2: skb->pkt_type = PACKET_HOST; @@ -441,7 +437,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card, if (skb->protocol == htons(ETH_P_802_2)) *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; len = skb->len; - netif_rx(skb); + netif_receive_skb(skb); break; case QETH_HEADER_TYPE_OSN: if (card->info.type == QETH_CARD_TYPE_OSN) { @@ -459,9 +455,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card, QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); continue; } + work_done++; + budget--; card->stats.rx_packets++; card->stats.rx_bytes += len; } + return work_done; +} + +static int qeth_l2_poll(struct napi_struct *napi, int budget) +{ + struct qeth_card *card = container_of(napi, struct qeth_card, napi); + int work_done = 0; + struct qeth_qdio_buffer *buffer; + int done; + int new_budget = budget; + + if (card->options.performance_stats) { + card->perf_stats.inbound_cnt++; + card->perf_stats.inbound_start_time = qeth_get_micros(); + } + + while (1) { + if (!card->rx.b_count) { + card->rx.qdio_err = 0; + card->rx.b_count = qdio_get_next_buffers( + card->data.ccwdev, 0, &card->rx.b_index, + &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; + } + card->rx.b_element = + &card->qdio.in_q->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + + while (card->rx.b_count) { + buffer = &card->qdio.in_q->bufs[card->rx.b_index]; + if (!(card->rx.qdio_err && + qeth_check_qdio_errors(card, buffer->buffer, + card->rx.qdio_err, "qinerr"))) + work_done += qeth_l2_process_inbound_buffer( + card, new_budget, &done); + else + done = 1; + + if (done) { + if (card->options.performance_stats) + card->perf_stats.bufs_rec++; + qeth_put_buffer_pool_entry(card, + buffer->pool_entry); + qeth_queue_input_buffer(card, card->rx.b_index); + card->rx.b_count--; + if (card->rx.b_count) { + card->rx.b_index = + (card->rx.b_index + 1) % + QDIO_MAX_BUFFERS_PER_Q; + card->rx.b_element = + &card->qdio.in_q + ->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + } + + if (work_done >= budget) + goto out; + else + new_budget = budget - work_done; + } + } + + napi_complete(napi); + if (qdio_start_irq(card->data.ccwdev, 0)) + napi_schedule(&card->napi); +out: + if (card->options.performance_stats) + card->perf_stats.inbound_time += qeth_get_micros() - + card->perf_stats.inbound_start_time; + return work_done; } static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, @@ -755,49 +829,10 @@ tx_drop: return NETDEV_TX_OK; } -static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int qdio_err, unsigned int queue, - int first_element, int count, unsigned long card_ptr) -{ - struct net_device *net_dev; - struct qeth_card *card; - struct qeth_qdio_buffer *buffer; - int index; - int i; - - card = (struct qeth_card *) card_ptr; - net_dev = card->dev; - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { - QETH_CARD_TEXT(card, 1, "qdinchk"); - QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element, - count); - QETH_CARD_TEXT_(card, 1, "%04X", queue); - qeth_schedule_recovery(card); - return; - } - for (i = first_element; i < (first_element + count); ++i) { - index = i % QDIO_MAX_BUFFERS_PER_Q; - buffer = &card->qdio.in_q->bufs[index]; - if (!(qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, qdio_err, - "qinerr"))) - qeth_l2_process_inbound_buffer(card, buffer, index); - /* clear buffer and give back to hardware */ - qeth_put_buffer_pool_entry(card, buffer->pool_entry); - qeth_queue_input_buffer(card, index); - } - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; -} - static int qeth_l2_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; + int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -814,18 +849,24 @@ static int qeth_l2_open(struct net_device *dev) if (!card->lan_online && netif_carrier_ok(dev)) netif_carrier_off(dev); - return 0; + if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { + napi_enable(&card->napi); + napi_schedule(&card->napi); + } else + rc = -EIO; + return rc; } - static int qeth_l2_stop(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; QETH_CARD_TEXT(card, 4, "qethstop"); netif_tx_disable(dev); - if (card->state == CARD_STATE_UP) + if (card->state == CARD_STATE_UP) { card->state = CARD_STATE_SOFTSETUP; + napi_disable(&card->napi); + } return 0; } @@ -836,8 +877,9 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev) INIT_LIST_HEAD(&card->vid_list); INIT_LIST_HEAD(&card->mc_list); card->options.layer2 = 1; + card->discipline.start_poll = qeth_qdio_start_poll; card->discipline.input_handler = (qdio_handler_t *) - qeth_l2_qdio_input_handler; + qeth_qdio_input_handler; card->discipline.output_handler = (qdio_handler_t *) qeth_qdio_output_handler; card->discipline.recover = qeth_l2_recover; @@ -923,6 +965,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) card->info.broadcast_capable = 1; qeth_l2_request_initial_mac(card); SET_NETDEV_DEV(card->dev, &card->gdev->dev); + netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); return register_netdev(card->dev); } @@ -955,6 +998,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); card->state = CARD_STATE_HARDSETUP; + memset(&card->rx, 0, sizeof(struct qeth_rx)); qeth_print_status_message(card); /* softsetup */ @@ -1086,9 +1130,6 @@ static int qeth_l2_recover(void *ptr) card->use_hard_stop = 1; __qeth_l2_set_offline(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1); - /* don't run another scheduled recovery */ - qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); - qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -1099,6 +1140,8 @@ static int qeth_l2_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } + qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); + qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 561bdc881e92..5b79f573bd93 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2107,51 +2107,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, return vlan_id; } -static void qeth_l3_process_inbound_buffer(struct qeth_card *card, - struct qeth_qdio_buffer *buf, int index) +static int qeth_l3_process_inbound_buffer(struct qeth_card *card, + int budget, int *done) { - struct qdio_buffer_element *element; + int work_done = 0; struct sk_buff *skb; struct qeth_hdr *hdr; - int offset; __u16 vlan_tag = 0; unsigned int len; - /* get first element of current buffer */ - element = (struct qdio_buffer_element *)&buf->buffer->element[0]; - offset = 0; - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, - &offset, &hdr))) { - skb->dev = card->dev; - /* is device UP ? */ - if (!(card->dev->flags & IFF_UP)) { - dev_kfree_skb_any(skb); - continue; - } + *done = 0; + BUG_ON(!budget); + while (budget) { + skb = qeth_core_get_next_skb(card, + card->qdio.in_q->bufs[card->rx.b_index].buffer, + &card->rx.b_element, &card->rx.e_offset, &hdr); + if (!skb) { + *done = 1; + break; + } + skb->dev = card->dev; switch (hdr->hdr.l3.id) { case QETH_HEADER_TYPE_LAYER3: vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); len = skb->len; if (vlan_tag && !card->options.sniffer) if (card->vlangrp) - vlan_hwaccel_rx(skb, card->vlangrp, - vlan_tag); + vlan_gro_receive(&card->napi, + card->vlangrp, vlan_tag, skb); else { dev_kfree_skb_any(skb); continue; } else - netif_rx(skb); + napi_gro_receive(&card->napi, skb); break; case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, skb->dev); - if (card->options.checksum_type == NO_CHECKSUMMING) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; len = skb->len; netif_receive_skb(skb); break; @@ -2161,10 +2154,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card, QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); continue; } - + work_done++; + budget--; card->stats.rx_packets++; card->stats.rx_bytes += len; } + return work_done; +} + +static int qeth_l3_poll(struct napi_struct *napi, int budget) +{ + struct qeth_card *card = container_of(napi, struct qeth_card, napi); + int work_done = 0; + struct qeth_qdio_buffer *buffer; + int done; + int new_budget = budget; + + if (card->options.performance_stats) { + card->perf_stats.inbound_cnt++; + card->perf_stats.inbound_start_time = qeth_get_micros(); + } + + while (1) { + if (!card->rx.b_count) { + card->rx.qdio_err = 0; + card->rx.b_count = qdio_get_next_buffers( + card->data.ccwdev, 0, &card->rx.b_index, + &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; + } + card->rx.b_element = + &card->qdio.in_q->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + + while (card->rx.b_count) { + buffer = &card->qdio.in_q->bufs[card->rx.b_index]; + if (!(card->rx.qdio_err && + qeth_check_qdio_errors(card, buffer->buffer, + card->rx.qdio_err, "qinerr"))) + work_done += qeth_l3_process_inbound_buffer( + card, new_budget, &done); + else + done = 1; + + if (done) { + if (card->options.performance_stats) + card->perf_stats.bufs_rec++; + qeth_put_buffer_pool_entry(card, + buffer->pool_entry); + qeth_queue_input_buffer(card, card->rx.b_index); + card->rx.b_count--; + if (card->rx.b_count) { + card->rx.b_index = + (card->rx.b_index + 1) % + QDIO_MAX_BUFFERS_PER_Q; + card->rx.b_element = + &card->qdio.in_q + ->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + } + + if (work_done >= budget) + goto out; + else + new_budget = budget - work_done; + } + } + + napi_complete(napi); + if (qdio_start_irq(card->data.ccwdev, 0)) + napi_schedule(&card->napi); +out: + if (card->options.performance_stats) + card->perf_stats.inbound_time += qeth_get_micros() - + card->perf_stats.inbound_start_time; + return work_done; } static int qeth_l3_verify_vlan_dev(struct net_device *dev, @@ -3098,6 +3168,7 @@ tx_drop: static int qeth_l3_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; + int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -3108,7 +3179,12 @@ static int qeth_l3_open(struct net_device *dev) if (!card->lan_online && netif_carrier_ok(dev)) netif_carrier_off(dev); - return 0; + if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { + napi_enable(&card->napi); + napi_schedule(&card->napi); + } else + rc = -EIO; + return rc; } static int qeth_l3_stop(struct net_device *dev) @@ -3117,8 +3193,10 @@ static int qeth_l3_stop(struct net_device *dev) QETH_CARD_TEXT(card, 4, "qethstop"); netif_tx_disable(dev); - if (card->state == CARD_STATE_UP) + if (card->state == CARD_STATE_UP) { card->state = CARD_STATE_SOFTSETUP; + napi_disable(&card->napi); + } return 0; } @@ -3288,57 +3366,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) card->dev->gso_max_size = 15 * PAGE_SIZE; SET_NETDEV_DEV(card->dev, &card->gdev->dev); + netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT); return register_netdev(card->dev); } -static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int qdio_err, unsigned int queue, int first_element, - int count, unsigned long card_ptr) -{ - struct net_device *net_dev; - struct qeth_card *card; - struct qeth_qdio_buffer *buffer; - int index; - int i; - - card = (struct qeth_card *) card_ptr; - net_dev = card->dev; - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { - QETH_CARD_TEXT(card, 1, "qdinchk"); - QETH_CARD_TEXT_(card, 1, "%04X%04X", - first_element, count); - QETH_CARD_TEXT_(card, 1, "%04X", queue); - qeth_schedule_recovery(card); - return; - } - for (i = first_element; i < (first_element + count); ++i) { - index = i % QDIO_MAX_BUFFERS_PER_Q; - buffer = &card->qdio.in_q->bufs[index]; - if (!(qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, - qdio_err, "qinerr"))) - qeth_l3_process_inbound_buffer(card, buffer, index); - /* clear buffer and give back to hardware */ - qeth_put_buffer_pool_entry(card, buffer->pool_entry); - qeth_queue_input_buffer(card, index); - } - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; -} - static int qeth_l3_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); qeth_l3_create_device_attributes(&gdev->dev); card->options.layer2 = 0; + card->discipline.start_poll = qeth_qdio_start_poll; card->discipline.input_handler = (qdio_handler_t *) - qeth_l3_qdio_input_handler; + qeth_qdio_input_handler; card->discipline.output_handler = (qdio_handler_t *) qeth_qdio_output_handler; card->discipline.recover = qeth_l3_recover; @@ -3397,6 +3437,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) } card->state = CARD_STATE_HARDSETUP; + memset(&card->rx, 0, sizeof(struct qeth_rx)); qeth_print_status_message(card); /* softsetup */ @@ -3533,9 +3574,6 @@ static int qeth_l3_recover(void *ptr) card->use_hard_stop = 1; __qeth_l3_set_offline(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1); - /* don't run another scheduled recovery */ - qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); - qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -3546,6 +3584,8 @@ static int qeth_l3_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } + qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); + qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; } -- cgit v1.2.3 From 933d41f1f2b6d5e7bcc0782ad0eeaac983a79592 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 7 Sep 2010 21:34:29 +0000 Subject: ixgbe: fix TX ring enable issues seen when VMDQ is enabled The ordering of operations was messed up in the init and as a result when VMDQ was enabled we were trying to enable TX rings before setting the VFTE bits. This resulted in a ring that appeared to fail to enable when in fact it was blocked because the VFTE bits were cleared after the reset. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3aafe94741ba..0027d7561516 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3004,7 +3004,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) /* Program registers for the distribution of queues */ ixgbe_setup_mrqc(adapter); - ixgbe_configure_virtualization(adapter); ixgbe_set_uta(adapter); @@ -3391,6 +3390,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc); } + ixgbe_configure_virtualization(adapter); ixgbe_configure_tx(adapter); ixgbe_configure_rx(adapter); -- cgit v1.2.3 From e8e9f6966ab1977df05c894a50d7eca7d013c2a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Sep 2010 21:34:53 +0000 Subject: drivers/net/ixgbe/ixgbe_main.c: Checkpatch cleanups Whitespace cleanups. Move inline keyword after function type declarations. Signed-off-by: Joe Perches Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 467 +++++++++++++++++++++-------------------- 1 file changed, 236 insertions(+), 231 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0027d7561516..7b6dcd8cf1a6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -50,7 +50,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = - "Intel(R) 10 Gigabit PCI Express Network Driver"; + "Intel(R) 10 Gigabit PCI Express Network Driver"; #define DRV_VERSION "2.0.84-k2" const char ixgbe_driver_version[] = DRV_VERSION; @@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); #ifdef CONFIG_IXGBE_DCA static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, - void *p); + void *p); static struct notifier_block dca_notifier = { .notifier_call = ixgbe_notify_dca, .next = NULL, @@ -131,8 +131,8 @@ static struct notifier_block dca_notifier = { #ifdef CONFIG_PCI_IOV static unsigned int max_vfs; module_param(max_vfs, uint, 0); -MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate " - "per physical function"); +MODULE_PARM_DESC(max_vfs, + "Maximum number of virtual functions to allocate per physical function"); #endif /* CONFIG_PCI_IOV */ MODULE_AUTHOR("Intel Corporation, "); @@ -169,8 +169,8 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) /* take a breather then clean up driver data */ msleep(100); - if (adapter->vfinfo) - kfree(adapter->vfinfo); + + kfree(adapter->vfinfo); adapter->vfinfo = NULL; adapter->num_vfs = 0; @@ -523,7 +523,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter) /* Let firmware take over control of h/w */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); } static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) @@ -533,7 +533,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) /* Let firmware know the driver has taken over */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); } /* @@ -545,7 +545,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) * */ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, - u8 queue, u8 msix_vector) + u8 queue, u8 msix_vector) { u32 ivar, index; struct ixgbe_hw *hw = &adapter->hw; @@ -586,7 +586,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, } static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, - u64 qmask) + u64 qmask) { u32 mask; @@ -602,8 +602,8 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, } void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, - struct ixgbe_tx_buffer - *tx_buffer_info) + struct ixgbe_tx_buffer + *tx_buffer_info) { if (tx_buffer_info->dma) { if (tx_buffer_info->mapped_as_page) @@ -637,7 +637,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, * Returns : true if in xon state (currently not paused) */ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { u32 txoff = IXGBE_TFCS_TXOFF; @@ -682,8 +682,8 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, } static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - unsigned int eop) + struct ixgbe_ring *tx_ring, + unsigned int eop) { struct ixgbe_hw *hw = &adapter->hw; @@ -732,7 +732,7 @@ static void ixgbe_tx_timeout(struct net_device *netdev); * @tx_ring: tx ring to clean **/ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct ixgbe_adapter *adapter = q_vector->adapter; struct net_device *netdev = adapter->netdev; @@ -781,7 +781,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } ixgbe_unmap_and_free_tx_resource(adapter, - tx_buffer_info); + tx_buffer_info); tx_desc->wb.status = 0; @@ -798,7 +798,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) if (unlikely(count && netif_carrier_ok(netdev) && - (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { + (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ @@ -832,7 +832,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, #ifdef CONFIG_IXGBE_DCA static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { u32 rxctrl; int cpu = get_cpu(); @@ -846,13 +846,13 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); + IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); } rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); rx_ring->cpu = cpu; } @@ -860,7 +860,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, } static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { u32 txctrl; int cpu = get_cpu(); @@ -878,7 +878,7 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q)); txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl); } @@ -946,9 +946,9 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) * @rx_desc: rx descriptor **/ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb, u8 status, - struct ixgbe_ring *ring, - union ixgbe_adv_rx_desc *rx_desc) + struct sk_buff *skb, u8 status, + struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc) { struct ixgbe_adapter *adapter = q_vector->adapter; struct napi_struct *napi = &q_vector->napi; @@ -1016,7 +1016,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, } static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, - struct ixgbe_ring *rx_ring, u32 val) + struct ixgbe_ring *rx_ring, u32 val) { /* * Force memory writes to complete before letting h/w @@ -1033,8 +1033,8 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, * @adapter: address of board private structure **/ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - int cleaned_count) + struct ixgbe_ring *rx_ring, + int cleaned_count) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -1064,8 +1064,8 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, } bi->page_dma = dma_map_page(&pdev->dev, bi->page, - bi->page_offset, - (PAGE_SIZE / 2), + bi->page_offset, + (PAGE_SIZE / 2), DMA_FROM_DEVICE); } @@ -1085,7 +1085,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->dma) { bi->dma = dma_map_single(&pdev->dev, bi->skb->data, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); } /* Refresh the desc even if buffer_addrs didn't change because @@ -1127,8 +1127,8 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) { return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & - IXGBE_RXDADV_RSCCNT_MASK) >> - IXGBE_RXDADV_RSCCNT_SHIFT; + IXGBE_RXDADV_RSCCNT_MASK) >> + IXGBE_RXDADV_RSCCNT_SHIFT; } /** @@ -1141,7 +1141,7 @@ static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) * turns it into the frag list owner. **/ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, - u64 *count) + u64 *count) { unsigned int frag_list_size = 0; @@ -1169,8 +1169,8 @@ struct ixgbe_rsc_cb { #define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, - struct ixgbe_ring *rx_ring, - int *work_done, int work_to_do) + struct ixgbe_ring *rx_ring, + int *work_done, int work_to_do) { struct ixgbe_adapter *adapter = q_vector->adapter; struct net_device *netdev = adapter->netdev; @@ -1232,9 +1232,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; } else { dma_unmap_single(&pdev->dev, - rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); + rx_buffer_info->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); } rx_buffer_info->dma = 0; skb_put(skb, len); @@ -1245,9 +1245,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, PAGE_SIZE / 2, DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, - rx_buffer_info->page, - rx_buffer_info->page_offset, - upper_len); + rx_buffer_info->page, + rx_buffer_info->page_offset, + upper_len); if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || (page_count(rx_buffer_info->page) != 1)) @@ -1281,18 +1281,20 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (staterr & IXGBE_RXD_STAT_EOP) { if (skb->prev) - skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); + skb = ixgbe_transform_rsc_queue(skb, + &(rx_ring->rsc_count)); if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { if (IXGBE_RSC_CB(skb)->delay_unmap) { dma_unmap_single(&pdev->dev, IXGBE_RSC_CB(skb)->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); IXGBE_RSC_CB(skb)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; } if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) - rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; + rx_ring->rsc_count += + skb_shinfo(skb)->nr_frags; else rx_ring->rsc_count++; rx_ring->rsc_flush++; @@ -1404,24 +1406,24 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector = adapter->q_vector[v_idx]; /* XXX for_each_set_bit(...) */ r_idx = find_first_bit(q_vector->rxr_idx, - adapter->num_rx_queues); + adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { j = adapter->rx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 0, j, v_idx); r_idx = find_next_bit(q_vector->rxr_idx, - adapter->num_rx_queues, - r_idx + 1); + adapter->num_rx_queues, + r_idx + 1); } r_idx = find_first_bit(q_vector->txr_idx, - adapter->num_tx_queues); + adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { j = adapter->tx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 1, j, v_idx); r_idx = find_next_bit(q_vector->txr_idx, - adapter->num_tx_queues, - r_idx + 1); + adapter->num_tx_queues, + r_idx + 1); } if (q_vector->txr_count && !q_vector->rxr_count) @@ -1436,7 +1438,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) if (adapter->hw.mac.type == ixgbe_mac_82598EB) ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX, - v_idx); + v_idx); else if (adapter->hw.mac.type == ixgbe_mac_82599EB) ixgbe_set_ivar(adapter, -1, 1, v_idx); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); @@ -1478,8 +1480,8 @@ enum latency_range { * parameter (see ixgbe_param.c) **/ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, - u32 eitr, u8 itr_setting, - int packets, int bytes) + u32 eitr, u8 itr_setting, + int packets, int bytes) { unsigned int retval = itr_setting; u32 timepassed_us; @@ -1568,30 +1570,30 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) for (i = 0; i < q_vector->txr_count; i++) { tx_ring = adapter->tx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? - q_vector->tx_itr - 1 : ret_itr); + q_vector->tx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = adapter->rx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? - q_vector->rx_itr - 1 : ret_itr); + q_vector->rx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } current_itr = max(q_vector->rx_itr, q_vector->tx_itr); @@ -1628,8 +1630,8 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) static void ixgbe_check_overtemp_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - check_overtemp_task); + struct ixgbe_adapter, + check_overtemp_task); struct ixgbe_hw *hw = &adapter->hw; u32 eicr = adapter->interrupt_event; @@ -1747,9 +1749,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) netif_tx_stop_all_queues(netdev); for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = - adapter->tx_ring[i]; + adapter->tx_ring[i]; if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) + &tx_ring->reinit_state)) schedule_work(&adapter->fdir_reinit_task); } } @@ -1778,7 +1780,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, } static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, - u64 qmask) + u64 qmask) { u32 mask; @@ -1810,7 +1812,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) tx_ring->total_bytes = 0; tx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } /* EIAM disabled interrupts (on this vector) for us */ @@ -1838,7 +1840,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) rx_ring->total_bytes = 0; rx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } if (!q_vector->rxr_count) @@ -1868,7 +1870,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) ring->total_bytes = 0; ring->total_packets = 0; r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); @@ -1877,7 +1879,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) ring->total_bytes = 0; ring->total_packets = 0; r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } /* EIAM disabled interrupts (on this vector) for us */ @@ -1897,7 +1899,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *rx_ring = NULL; int work_done = 0; @@ -1919,7 +1921,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ((u64)1 << q_vector->v_idx)); } return work_done; @@ -1936,7 +1938,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *ring = NULL; int work_done = 0, i; @@ -1952,7 +1954,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) #endif tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } /* attempt to distribute budget to each queue fairly, but don't allow @@ -1968,7 +1970,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) #endif ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); @@ -1980,7 +1982,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ((u64)1 << q_vector->v_idx)); return 0; } @@ -1998,7 +2000,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *tx_ring = NULL; int work_done = 0; @@ -2020,14 +2022,15 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) if (adapter->tx_itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); + ixgbe_irq_enable_queues(adapter, + ((u64)1 << q_vector->v_idx)); } return work_done; } static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, - int r_idx) + int r_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; @@ -2036,7 +2039,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, - int t_idx) + int t_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; @@ -2056,7 +2059,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, * mapping configurations in here. **/ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int v_start = 0; int rxr_idx = 0, txr_idx = 0; @@ -2123,7 +2126,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) struct net_device *netdev = adapter->netdev; irqreturn_t (*handler)(int, void *); int i, vector, q_vectors, err; - int ri=0, ti=0; + int ri = 0, ti = 0; /* Decrement for Other and TCP Timer vectors */ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; @@ -2134,26 +2137,24 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) goto out; #define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \ - (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ - &ixgbe_msix_clean_many) + (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ + &ixgbe_msix_clean_many) for (vector = 0; vector < q_vectors; vector++) { handler = SET_HANDLER(adapter->q_vector[vector]); - if(handler == &ixgbe_msix_clean_rx) { + if (handler == &ixgbe_msix_clean_rx) { sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "rx", ri++); - } - else if(handler == &ixgbe_msix_clean_tx) { + } else if (handler == &ixgbe_msix_clean_tx) { sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "tx", ti++); - } - else + } else sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "TxRx", vector); err = request_irq(adapter->msix_entries[vector].vector, - handler, 0, adapter->name[vector], - adapter->q_vector[vector]); + handler, 0, adapter->name[vector], + adapter->q_vector[vector]); if (err) { e_err(probe, "request_irq failed for MSIX interrupt " "Error: %d\n", err); @@ -2163,7 +2164,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) sprintf(adapter->name[vector], "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - ixgbe_msix_lsc, 0, adapter->name[vector], netdev); + ixgbe_msix_lsc, 0, adapter->name[vector], netdev); if (err) { e_err(probe, "request_irq for msix_lsc failed: %d\n", err); goto free_queue_irqs; @@ -2174,7 +2175,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) free_queue_irqs: for (i = vector - 1; i >= 0; i--) free_irq(adapter->msix_entries[--vector].vector, - adapter->q_vector[i]); + adapter->q_vector[i]); adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); @@ -2192,13 +2193,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); current_itr = max(q_vector->rx_itr, q_vector->tx_itr); @@ -2344,10 +2345,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter) err = ixgbe_request_msix_irqs(adapter); } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { err = request_irq(adapter->pdev->irq, ixgbe_intr, 0, - netdev->name, netdev); + netdev->name, netdev); } else { err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED, - netdev->name, netdev); + netdev->name, netdev); } if (err) @@ -2371,7 +2372,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { free_irq(adapter->msix_entries[i].vector, - adapter->q_vector[i]); + adapter->q_vector[i]); } ixgbe_reset_q_vectors(adapter); @@ -2414,7 +2415,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; IXGBE_WRITE_REG(hw, IXGBE_EITR(0), - EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param)); + EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param)); ixgbe_set_ivar(adapter, 0, 0, 0); ixgbe_set_ivar(adapter, 1, 0, 0); @@ -2448,7 +2449,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx), - (tdba & DMA_BIT_MASK(32))); + (tdba & DMA_BIT_MASK(32))); IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32)); IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx), ring->count * sizeof(union ixgbe_adv_tx_desc)); @@ -2559,7 +2560,7 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { u32 srrctl; int index; @@ -2601,8 +2602,8 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, - 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, - 0x6A3E67EA, 0x14364D17, 0x3BED200D}; + 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, + 0x6A3E67EA, 0x14364D17, 0x3BED200D}; u32 mrqc = 0, reta = 0; u32 rxcsum; int i, j; @@ -2813,10 +2814,10 @@ static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) /* PSRTYPE must be initialized in non 82598 adapters */ u32 psrtype = IXGBE_PSRTYPE_TCPHDR | - IXGBE_PSRTYPE_UDPHDR | - IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_L2HDR | - IXGBE_PSRTYPE_IPV6HDR; + IXGBE_PSRTYPE_IPV6HDR; if (hw->mac.type == ixgbe_mac_82598EB) return; @@ -2931,15 +2932,14 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; #ifdef IXGBE_FCOE - if (netdev->features & NETIF_F_FCOE_MTU) - { + if (netdev->features & NETIF_F_FCOE_MTU) { struct ixgbe_ring_feature *f; f = &adapter->ring_feature[RING_F_FCOE]; if ((i >= f->mask) && (i < f->mask + f->indices)) { rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) rx_ring->rx_buf_len = - IXGBE_FCOE_JUMBO_FRAME_SIZE; + IXGBE_FCOE_JUMBO_FRAME_SIZE; } } #endif /* IXGBE_FCOE */ @@ -3127,7 +3127,7 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) } static void ixgbe_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) + struct vlan_group *grp) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -3385,7 +3385,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { for (i = 0; i < adapter->num_tx_queues; i++) adapter->tx_ring[i]->atr_sample_rate = - adapter->atr_sample_rate; + adapter->atr_sample_rate; ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc); } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc); @@ -3464,7 +3464,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) goto link_cfg_out; if (hw->mac.ops.get_link_capabilities) - ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); + ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, + &negotiation); if (ret) goto link_cfg_out; @@ -3666,7 +3667,7 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) * @rx_ring: ring to free buffers from **/ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; unsigned long size; @@ -3683,7 +3684,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_buffer_info = &rx_ring->rx_buffer_info[i]; if (rx_buffer_info->dma) { dma_unmap_single(&pdev->dev, rx_buffer_info->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); rx_buffer_info->dma = 0; } @@ -3695,7 +3696,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, if (IXGBE_RSC_CB(this)->delay_unmap) { dma_unmap_single(&pdev->dev, IXGBE_RSC_CB(this)->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); IXGBE_RSC_CB(this)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; @@ -3737,7 +3738,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, * @tx_ring: ring to be cleaned **/ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned long size; @@ -3849,13 +3850,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter) j = adapter->tx_ring[i]->reg_idx; txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), - (txdctl & ~IXGBE_TXDCTL_ENABLE)); + (txdctl & ~IXGBE_TXDCTL_ENABLE)); } /* Disable the Tx DMA engine on 82599 */ if (hw->mac.type == ixgbe_mac_82599EB) IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, - (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & - ~IXGBE_DMATXCTL_TE)); + (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & + ~IXGBE_DMATXCTL_TE)); /* power down the optics */ if (hw->phy.multispeed_fiber) @@ -3885,7 +3886,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) static int ixgbe_poll(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; int tx_clean_complete, work_done = 0; @@ -3995,7 +3996,7 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) * Rx load across CPUs using RSS. * **/ -static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) +static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) { bool ret = false; struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR]; @@ -4124,7 +4125,7 @@ done: } static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int err, vector_threshold; @@ -4143,7 +4144,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, */ while (vectors >= vector_threshold) { err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - vectors); + vectors); if (!err) /* Success in acquiring all requested vectors. */ break; else if (err < 0) @@ -4170,7 +4171,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, * vectors we were allocated. */ adapter->num_msix_vectors = min(vectors, - adapter->max_msix_q_vectors + NON_Q_VECTORS); + adapter->max_msix_q_vectors + NON_Q_VECTORS); } } @@ -4241,12 +4242,12 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) } for ( ; i < 5; i++) { adapter->tx_ring[i]->reg_idx = - ((i + 2) << 4); + ((i + 2) << 4); adapter->rx_ring[i]->reg_idx = i << 4; } for ( ; i < dcb_i; i++) { adapter->tx_ring[i]->reg_idx = - ((i + 8) << 3); + ((i + 8) << 3); adapter->rx_ring[i]->reg_idx = i << 4; } @@ -4289,7 +4290,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) * Cache the descriptor ring offsets for Flow Director to the assigned rings. * **/ -static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) +static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) { int i; bool ret = false; @@ -4446,7 +4447,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) adapter->node = cur_node; } ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + adapter->node); if (!ring) ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) @@ -4470,7 +4471,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) adapter->node = cur_node; } ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + adapter->node); if (!ring) ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) @@ -4516,7 +4517,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) * (roughly) the same number of vectors as there are CPU's. */ v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues, - (int)num_online_cpus()) + NON_Q_VECTORS; + (int)num_online_cpus()) + NON_Q_VECTORS; /* * At the same time, hardware can only support a maximum of @@ -4530,7 +4531,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) /* A failure in MSI-X entry allocation isn't fatal, but it does * mean we disable MSI-X capabilities of the adapter. */ adapter->msix_entries = kcalloc(v_budget, - sizeof(struct msix_entry), GFP_KERNEL); + sizeof(struct msix_entry), GFP_KERNEL); if (adapter->msix_entries) { for (vector = 0; vector < v_budget; vector++) adapter->msix_entries[vector].entry = vector; @@ -4592,10 +4593,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { q_vector = kzalloc_node(sizeof(struct ixgbe_q_vector), - GFP_KERNEL, adapter->node); + GFP_KERNEL, adapter->node); if (!q_vector) q_vector = kzalloc(sizeof(struct ixgbe_q_vector), - GFP_KERNEL); + GFP_KERNEL); if (!q_vector) goto err_out; q_vector->adapter = adapter; @@ -4756,8 +4757,8 @@ static void ixgbe_sfp_timer(unsigned long data) static void ixgbe_sfp_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - sfp_task); + struct ixgbe_adapter, + sfp_task); struct ixgbe_hw *hw = &adapter->hw; if ((hw->phy.type == ixgbe_phy_nl) && @@ -4782,7 +4783,7 @@ static void ixgbe_sfp_task(struct work_struct *work) reschedule: if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state)) mod_timer(&adapter->sfp_timer, - round_jiffies(jiffies + (2 * HZ))); + round_jiffies(jiffies + (2 * HZ))); } /** @@ -4838,7 +4839,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->atr_sample_rate = 20; } adapter->ring_feature[RING_F_FDIR].indices = - IXGBE_MAX_FDIR_INDICES; + IXGBE_MAX_FDIR_INDICES; adapter->fdir_pballoc = 0; #ifdef IXGBE_FCOE adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; @@ -4869,7 +4870,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->dcb_cfg.round_robin_enable = false; adapter->dcb_set_bitmap = 0x00; ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, - adapter->ring_feature[RING_F_DCB].indices); + adapter->ring_feature[RING_F_DCB].indices); #endif @@ -4924,7 +4925,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) * Return 0 on success, negative on failure **/ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct pci_dev *pdev = adapter->pdev; int size; @@ -4991,7 +4992,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) * Returns 0 on success, negative on failure **/ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; int size; @@ -5064,7 +5065,7 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) * Free all transmit software resources **/ void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -5102,7 +5103,7 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) * Free all receive software resources **/ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -5406,7 +5407,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u64 rsc_flush = 0; for (i = 0; i < 16; i++) adapter->hw_rx_no_dma_resources += - IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); for (i = 0; i < adapter->num_rx_queues; i++) { rsc_count += adapter->rx_ring[i]->rsc_count; rsc_flush += adapter->rx_ring[i]->rsc_flush; @@ -5439,20 +5440,20 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); if (hw->mac.type == ixgbe_mac_82599EB) { adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXCNT(i)); + IXGBE_PXONRXCNT(i)); adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXCNT(i)); + IXGBE_PXOFFRXCNT(i)); adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXC(i)); + IXGBE_PXONRXC(i)); adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXC(i)); + IXGBE_PXOFFRXC(i)); } adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONTXC(i)); + IXGBE_PXONTXC(i)); adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFTXC(i)); + IXGBE_PXOFFTXC(i)); } adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); /* work around hardware counting issue */ @@ -5462,13 +5463,15 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82599EB) { u64 tmp; adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */ + tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; + /* 4 high bits of GORC */ adapter->stats.gorc += (tmp << 32); adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */ + tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; + /* 4 high bits of GOTC */ adapter->stats.gotc += (tmp << 32); adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL); - IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ + IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); @@ -5533,7 +5536,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) /* Rx Errors */ netdev->stats.rx_errors = adapter->stats.crcerrs + - adapter->stats.rlec; + adapter->stats.rlec; netdev->stats.rx_dropped = 0; netdev->stats.rx_length_errors = adapter->stats.rlec; netdev->stats.rx_crc_errors = adapter->stats.crcerrs; @@ -5595,8 +5598,8 @@ watchdog_short_circuit: static void ixgbe_multispeed_fiber_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - multispeed_fiber_task); + struct ixgbe_adapter, + multispeed_fiber_task); struct ixgbe_hw *hw = &adapter->hw; u32 autoneg; bool negotiation; @@ -5619,8 +5622,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) static void ixgbe_sfp_config_module_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - sfp_config_module_task); + struct ixgbe_adapter, + sfp_config_module_task); struct ixgbe_hw *hw = &adapter->hw; u32 err; @@ -5653,15 +5656,15 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) static void ixgbe_fdir_reinit_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - fdir_reinit_task); + struct ixgbe_adapter, + fdir_reinit_task); struct ixgbe_hw *hw = &adapter->hw; int i; if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { for (i = 0; i < adapter->num_tx_queues; i++) set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->reinit_state)); + &(adapter->tx_ring[i]->reinit_state)); } else { e_err(probe, "failed to finish FDIR re-initialization, " "ignored adding FDIR ATR filters\n"); @@ -5679,8 +5682,8 @@ static DEFINE_MUTEX(ixgbe_watchdog_lock); static void ixgbe_watchdog_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - watchdog_task); + struct ixgbe_adapter, + watchdog_task); struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; u32 link_speed; @@ -5711,7 +5714,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) if (link_up || time_after(jiffies, (adapter->link_check_timeout + - IXGBE_TRY_LINK_TIMEOUT))) { + IXGBE_TRY_LINK_TIMEOUT))) { adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); } @@ -5782,8 +5785,8 @@ static void ixgbe_watchdog_task(struct work_struct *work) } static int ixgbe_tso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len) + struct ixgbe_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, u8 *hdr_len) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5806,15 +5809,15 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, iph->tot_len = 0; iph->check = 0; tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); + iph->daddr, 0, + IPPROTO_TCP, + 0); } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); } i = tx_ring->next_to_use; @@ -5827,7 +5830,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= ((skb_network_offset(skb)) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); *hdr_len += skb_network_offset(skb); vlan_macip_lens |= (skb_transport_header(skb) - skb_network_header(skb)); @@ -5838,7 +5841,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + IXGBE_ADVTXD_DTYP_CTXT); if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; @@ -5867,8 +5870,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, } static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5885,16 +5888,16 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= (skb_network_offset(skb) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); if (skb->ip_summed == CHECKSUM_PARTIAL) vlan_macip_lens |= (skb_transport_header(skb) - - skb_network_header(skb)); + skb_network_header(skb)); context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); context_desc->seqnum_seed = 0; type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { __be16 protocol; @@ -5913,19 +5916,19 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; if (ip_hdr(skb)->protocol == IPPROTO_TCP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; + IXGBE_ADVTXD_TUCMD_L4T_TCP; else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; + IXGBE_ADVTXD_TUCMD_L4T_SCTP; break; case cpu_to_be16(ETH_P_IPV6): /* XXX what about other V6 headers?? */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; + IXGBE_ADVTXD_TUCMD_L4T_TCP; else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; + IXGBE_ADVTXD_TUCMD_L4T_SCTP; break; default: if (unlikely(net_ratelimit())) { @@ -5956,9 +5959,9 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, } static int ixgbe_tx_map(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - unsigned int first) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags, + unsigned int first) { struct pci_dev *pdev = adapter->pdev; struct ixgbe_tx_buffer *tx_buffer_info; @@ -6053,7 +6056,7 @@ dma_error: /* clear timestamp and dma mappings for remaining portion of packet */ while (count--) { - if (i==0) + if (i == 0) i += tx_ring->count; i--; tx_buffer_info = &tx_ring->tx_buffer_info[i]; @@ -6064,8 +6067,8 @@ dma_error: } static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - int tx_flags, int count, u32 paylen, u8 hdr_len) + struct ixgbe_ring *tx_ring, + int tx_flags, int count, u32 paylen, u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; struct ixgbe_tx_buffer *tx_buffer_info; @@ -6084,17 +6087,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; /* use index 1 context for tso */ olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT); if (tx_flags & IXGBE_TX_FLAGS_IPV4) olinfo_status |= IXGBE_TXD_POPTS_IXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; } else if (tx_flags & IXGBE_TX_FLAGS_CSUM) olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; if (tx_flags & IXGBE_TX_FLAGS_FCOE) { olinfo_status |= IXGBE_ADVTXD_CC; @@ -6111,7 +6114,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma); tx_desc->read.cmd_type_len = - cpu_to_le32(cmd_type_len | tx_buffer_info->length); + cpu_to_le32(cmd_type_len | tx_buffer_info->length); tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); i++; if (i == tx_ring->count) @@ -6133,7 +6136,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - int queue, u32 tx_flags) + int queue, u32 tx_flags) { struct ixgbe_atr_input atr_input; struct tcphdr *th; @@ -6161,7 +6164,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> - IXGBE_TX_FLAGS_VLAN_SHIFT; + IXGBE_TX_FLAGS_VLAN_SHIFT; src_ipv4_addr = iph->saddr; dst_ipv4_addr = iph->daddr; flex_bytes = eth->h_proto; @@ -6180,7 +6183,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, } static int __ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { netif_stop_subqueue(netdev, tx_ring->queue_index); /* Herbert's original patch had: @@ -6200,7 +6203,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, } static int ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) return 0; @@ -6343,10 +6346,10 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev if (tx_ring->atr_sample_rate) { ++tx_ring->atr_count; if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) && - test_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) { + test_bit(__IXGBE_FDIR_INIT_DONE, + &tx_ring->reinit_state)) { ixgbe_atr(adapter, skb, tx_ring->queue_index, - tx_flags); + tx_flags); tx_ring->atr_count = 0; } } @@ -6354,7 +6357,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev txq->tx_bytes += skb->len; txq->tx_packets++; ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, - hdr_len); + hdr_len); ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); } else { @@ -6506,7 +6509,7 @@ static void ixgbe_netpoll(struct net_device *netdev) #endif static const struct net_device_ops ixgbe_netdev_ops = { - .ndo_open = ixgbe_open, + .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, .ndo_start_xmit = ixgbe_xmit_frame, .ndo_select_queue = ixgbe_select_queue, @@ -6601,7 +6604,7 @@ err_novfs: * and a hardware reset occur. **/ static int __devinit ixgbe_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct net_device *netdev; struct ixgbe_adapter *adapter = NULL; @@ -6646,7 +6649,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } err = pci_request_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM), ixgbe_driver_name); + IORESOURCE_MEM), ixgbe_driver_name); if (err) { dev_err(&pdev->dev, "pci_request_selected_regions failed 0x%x\n", err); @@ -6686,7 +6689,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; hw->hw_addr = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + pci_resource_len(pdev, 0)); if (!hw->hw_addr) { err = -EIO; goto err_ioremap; @@ -6740,7 +6743,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* a new SFP+ module arrival, called from GPI SDP2 context */ INIT_WORK(&adapter->sfp_config_module_task, - ixgbe_sfp_config_module_task); + ixgbe_sfp_config_module_task); ii->get_invariants(hw); @@ -6792,10 +6795,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ixgbe_probe_vf(adapter, ii); netdev->features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + NETIF_F_IP_CSUM | + NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_IPV6_CSUM; netdev->features |= NETIF_F_TSO; @@ -6875,7 +6878,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, switch (pdev->device) { case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + IXGBE_WUFC_MC | IXGBE_WUFC_BC); break; default: adapter->wol = 0; @@ -6888,13 +6891,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* print bus type/speed/width info */ e_dev_info("(PCI Express:%s:%s) %pM\n", - ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s": - (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"), - ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" : - (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" : - (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" : - "Unknown"), - netdev->dev_addr); + (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" : + hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" : + "Unknown"), + (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" : + hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" : + hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" : + "Unknown"), + netdev->dev_addr); ixgbe_read_pba_num_generic(hw, &part_num); if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) e_dev_info("MAC: %d, PHY: %d, SFP+: %d, " @@ -6941,7 +6945,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task); if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) - INIT_WORK(&adapter->check_overtemp_task, ixgbe_check_overtemp_task); + INIT_WORK(&adapter->check_overtemp_task, + ixgbe_check_overtemp_task); #ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; @@ -6977,8 +6982,8 @@ err_eeprom: err_ioremap: free_netdev(netdev); err_alloc_etherdev: - pci_release_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM)); + pci_release_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_MEM)); err_pci_reg: err_dma: pci_disable_device(pdev); @@ -7045,7 +7050,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) iounmap(adapter->hw.hw_addr); pci_release_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM)); + IORESOURCE_MEM)); e_dev_info("complete\n"); @@ -7065,7 +7070,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) * this device has been detected. */ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) + pci_channel_state_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -7201,12 +7206,12 @@ static void __exit ixgbe_exit_module(void) #ifdef CONFIG_IXGBE_DCA static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, - void *p) + void *p) { int ret_val; ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event, - __ixgbe_notify_dca); + __ixgbe_notify_dca); return ret_val ? NOTIFY_BAD : NOTIFY_DONE; } -- cgit v1.2.3 From c7689578f52bbe258693996f2251b276445f87ce Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Sep 2010 21:35:17 +0000 Subject: drivers/net/ixgbe/ixgbe_main.c: Use pr_ Did not add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt because no printk in this module used message prefixing. Signed-off-by: Joe Perches Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 74 ++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7b6dcd8cf1a6..edb71e1bc43a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -282,17 +282,17 @@ static void ixgbe_regdump(struct ixgbe_hw *hw, struct ixgbe_reg_info *reginfo) regs[i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); break; default: - printk(KERN_INFO "%-15s %08x\n", reginfo->name, + pr_info("%-15s %08x\n", reginfo->name, IXGBE_READ_REG(hw, reginfo->ofs)); return; } for (i = 0; i < 8; i++) { snprintf(rname, 16, "%s[%d-%d]", reginfo->name, i*8, i*8+7); - printk(KERN_ERR "%-15s ", rname); + pr_err("%-15s", rname); for (j = 0; j < 8; j++) - printk(KERN_CONT "%08x ", regs[i*8+j]); - printk(KERN_CONT "\n"); + pr_cont(" %08x", regs[i*8+j]); + pr_cont("\n"); } } @@ -322,18 +322,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) /* Print netdevice Info */ if (netdev) { dev_info(&adapter->pdev->dev, "Net device Info\n"); - printk(KERN_INFO "Device Name state " + pr_info("Device Name state " "trans_start last_rx\n"); - printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", - netdev->name, - netdev->state, - netdev->trans_start, - netdev->last_rx); + pr_info("%-15s %016lX %016lX %016lX\n", + netdev->name, + netdev->state, + netdev->trans_start, + netdev->last_rx); } /* Print Registers */ dev_info(&adapter->pdev->dev, "Register Dump\n"); - printk(KERN_INFO " Register Name Value\n"); + pr_info(" Register Name Value\n"); for (reginfo = (struct ixgbe_reg_info *)ixgbe_reg_info_tbl; reginfo->name; reginfo++) { ixgbe_regdump(hw, reginfo); @@ -344,13 +344,12 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) goto exit; dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); - printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ] " - "leng ntw timestamp\n"); + pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); for (n = 0; n < adapter->num_tx_queues; n++) { tx_ring = adapter->tx_ring[n]; tx_buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; - printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", + pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n", n, tx_ring->next_to_use, tx_ring->next_to_clean, (u64)tx_buffer_info->dma, tx_buffer_info->length, @@ -377,10 +376,10 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) for (n = 0; n < adapter->num_tx_queues; n++) { tx_ring = adapter->tx_ring[n]; - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index); - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "T [desc] [address 63:0 ] " + pr_info("------------------------------------\n"); + pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("T [desc] [address 63:0 ] " "[PlPOIdStDDt Ln] [bi->dma ] " "leng ntw timestamp bi->skb\n"); @@ -388,7 +387,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; u0 = (struct my_u0 *)tx_desc; - printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX" + pr_info("T [0x%03X] %016llX %016llX %016llX" " %04X %3X %016llX %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), @@ -399,13 +398,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) tx_buffer_info->skb); if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) - printk(KERN_CONT " NTC/U\n"); + pr_cont(" NTC/U\n"); else if (i == tx_ring->next_to_use) - printk(KERN_CONT " NTU\n"); + pr_cont(" NTU\n"); else if (i == tx_ring->next_to_clean) - printk(KERN_CONT " NTC\n"); + pr_cont(" NTC\n"); else - printk(KERN_CONT "\n"); + pr_cont("\n"); if (netif_msg_pktdata(adapter) && tx_buffer_info->dma != 0) @@ -419,11 +418,11 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) /* Print RX Rings Summary */ rx_ring_summary: dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); - printk(KERN_INFO "Queue [NTU] [NTC]\n"); + pr_info("Queue [NTU] [NTC]\n"); for (n = 0; n < adapter->num_rx_queues; n++) { rx_ring = adapter->rx_ring[n]; - printk(KERN_INFO "%5d %5X %5X\n", n, - rx_ring->next_to_use, rx_ring->next_to_clean); + pr_info("%5d %5X %5X\n", + n, rx_ring->next_to_use, rx_ring->next_to_clean); } /* Print RX Rings */ @@ -454,13 +453,13 @@ rx_ring_summary: */ for (n = 0; n < adapter->num_rx_queues; n++) { rx_ring = adapter->rx_ring[n]; - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index); - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "R [desc] [ PktBuf A0] " + pr_info("------------------------------------\n"); + pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("R [desc] [ PktBuf A0] " "[ HeadBuf DD] [bi->dma ] [bi->skb] " "<-- Adv Rx Read format\n"); - printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] " + pr_info("RWB[desc] [PcsmIpSHl PtRs] " "[vl er S cks ln] ---------------- [bi->skb] " "<-- Adv Rx Write-Back format\n"); @@ -471,13 +470,13 @@ rx_ring_summary: staterr = le32_to_cpu(rx_desc->wb.upper.status_error); if (staterr & IXGBE_RXD_STAT_DD) { /* Descriptor Done */ - printk(KERN_INFO "RWB[0x%03X] %016llX " + pr_info("RWB[0x%03X] %016llX " "%016llX ---------------- %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), rx_buffer_info->skb); } else { - printk(KERN_INFO "R [0x%03X] %016llX " + pr_info("R [0x%03X] %016llX " "%016llX %016llX %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), @@ -503,11 +502,11 @@ rx_ring_summary: } if (i == rx_ring->next_to_use) - printk(KERN_CONT " NTU\n"); + pr_cont(" NTU\n"); else if (i == rx_ring->next_to_clean) - printk(KERN_CONT " NTC\n"); + pr_cont(" NTC\n"); else - printk(KERN_CONT "\n"); + pr_cont("\n"); } } @@ -7176,8 +7175,7 @@ static struct pci_driver ixgbe_driver = { static int __init ixgbe_init_module(void) { int ret; - pr_info("%s - version %s\n", ixgbe_driver_string, - ixgbe_driver_version); + pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version); pr_info("%s\n", ixgbe_copyright); #ifdef CONFIG_IXGBE_DCA -- cgit v1.2.3 From 7ca647bdad0110a47edc44c48f8e646fdac87922 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Sep 2010 21:35:40 +0000 Subject: drivers/net/ixgbe/ixgbe_main.c: Add ixgbe_psum Reduce indentation in a couple of places Add static function ixgbe_psum Add temporary for adapter->stats Signed-off-by: Joe Perches Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 297 +++++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 146 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index edb71e1bc43a..d03eef96c0ba 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1634,34 +1634,35 @@ static void ixgbe_check_overtemp_task(struct work_struct *work) struct ixgbe_hw *hw = &adapter->hw; u32 eicr = adapter->interrupt_event; - if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { - switch (hw->device_id) { - case IXGBE_DEV_ID_82599_T3_LOM: { - u32 autoneg; - bool link_up = false; - - if (hw->mac.ops.check_link) - hw->mac.ops.check_link(hw, &autoneg, &link_up, false); - - if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || - (eicr & IXGBE_EICR_LSC)) - /* Check if this is due to overtemp */ - if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) - break; - } + if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)) + return; + + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: { + u32 autoneg; + bool link_up = false; + + if (hw->mac.ops.check_link) + hw->mac.ops.check_link(hw, &autoneg, &link_up, false); + + if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || + (eicr & IXGBE_EICR_LSC)) + /* Check if this is due to overtemp */ + if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) + break; + return; + } + default: + if (!(eicr & IXGBE_EICR_GPI_SDP0)) return; - default: - if (!(eicr & IXGBE_EICR_GPI_SDP0)) - return; - break; - } - e_crit(drv, "Network adapter has been stopped because it has " - "over heated. Restart the computer. If the problem " - "persists, power off the system and replace the " - "adapter\n"); - /* write to clear the interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); + break; } + e_crit(drv, + "Network adapter has been stopped because it has over heated. " + "Restart the computer. If the problem persists, " + "power off the system and replace the adapter\n"); + /* write to clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); } static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) @@ -5396,6 +5397,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u64 total_mpc = 0; u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; u64 non_eop_descs = 0, restart_queue = 0; + struct ixgbe_hw_stats *hwstats = &adapter->stats; if (test_bit(__IXGBE_DOWN, &adapter->state) || test_bit(__IXGBE_RESETTING, &adapter->state)) @@ -5406,7 +5408,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u64 rsc_flush = 0; for (i = 0; i < 16; i++) adapter->hw_rx_no_dma_resources += - IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); for (i = 0; i < adapter->num_rx_queues; i++) { rsc_count += adapter->rx_ring[i]->rsc_count; rsc_flush += adapter->rx_ring[i]->rsc_flush; @@ -5424,121 +5426,118 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) non_eop_descs += adapter->rx_ring[i]->non_eop_descs; adapter->non_eop_descs = non_eop_descs; - adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); + hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (i = 0; i < 8; i++) { /* for packet buffers not used, the register should read 0 */ mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i)); missed_rx += mpc; - adapter->stats.mpc[i] += mpc; - total_mpc += adapter->stats.mpc[i]; + hwstats->mpc[i] += mpc; + total_mpc += hwstats->mpc[i]; if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); - adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); - adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); - adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); + hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); + hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); + hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); if (hw->mac.type == ixgbe_mac_82599EB) { - adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXCNT(i)); - adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXCNT(i)); - adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { - adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXC(i)); - adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXC(i)); + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); } - adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONTXC(i)); - adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFTXC(i)); + hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); + hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); } - adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); + hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); /* work around hardware counting issue */ - adapter->stats.gprc -= missed_rx; + hwstats->gprc -= missed_rx; /* 82598 hardware only has a 32 bit counter in the high register */ if (hw->mac.type == ixgbe_mac_82599EB) { u64 tmp; - adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */ - adapter->stats.gorc += (tmp << 32); - adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); + hwstats->gorc += (tmp << 32); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */ - adapter->stats.gotc += (tmp << 32); - adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL); + hwstats->gotc += (tmp << 32); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ - adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); - adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); - adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); + hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); #ifdef IXGBE_FCOE - adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); - adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); - adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); - adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); - adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); - adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); + hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); + hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); + hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); + hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); + hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); #endif /* IXGBE_FCOE */ } else { - adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH); + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); } bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); - adapter->stats.bprc += bprc; - adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); + hwstats->bprc += bprc; + hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.mprc -= bprc; - adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC); - adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); - adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); - adapter->stats.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); - adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); - adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); - adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); - adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); + hwstats->mprc -= bprc; + hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC); + hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); + hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); + hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); + hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); + hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); + hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); + hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); - adapter->stats.lxontxc += lxon; + hwstats->lxontxc += lxon; lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - adapter->stats.lxofftxc += lxoff; - adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC); - adapter->stats.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); - adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); + hwstats->lxofftxc += lxoff; + hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); + hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); /* * 82598 errata - tx of flow control packets is included in tx counters */ xon_off_tot = lxon + lxoff; - adapter->stats.gptc -= xon_off_tot; - adapter->stats.mptc -= xon_off_tot; - adapter->stats.gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN)); - adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC); - adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC); - adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC); - adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR); - adapter->stats.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); - adapter->stats.ptc64 -= xon_off_tot; - adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); - adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); - adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); - adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); - adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); - adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); + hwstats->gptc -= xon_off_tot; + hwstats->mptc -= xon_off_tot; + hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN)); + hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC); + hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC); + hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR); + hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); + hwstats->ptc64 -= xon_off_tot; + hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); + hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); + hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); + hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); + hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); + hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); /* Fill out the OS statistics structure */ - netdev->stats.multicast = adapter->stats.mprc; + netdev->stats.multicast = hwstats->mprc; /* Rx Errors */ - netdev->stats.rx_errors = adapter->stats.crcerrs + - adapter->stats.rlec; + netdev->stats.rx_errors = hwstats->crcerrs + hwstats->rlec; netdev->stats.rx_dropped = 0; - netdev->stats.rx_length_errors = adapter->stats.rlec; - netdev->stats.rx_crc_errors = adapter->stats.crcerrs; + netdev->stats.rx_length_errors = hwstats->rlec; + netdev->stats.rx_crc_errors = hwstats->crcerrs; netdev->stats.rx_missed_errors = total_mpc; } @@ -5868,6 +5867,50 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, return false; } +static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb) +{ + u32 rtn = 0; + __be16 protocol; + + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) + protocol = ((const struct vlan_ethhdr *)skb->data)-> + h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + switch (protocol) { + case cpu_to_be16(ETH_P_IP): + rtn |= IXGBE_ADVTXD_TUCMD_IPV4; + switch (ip_hdr(skb)->protocol) { + case IPPROTO_TCP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; + case IPPROTO_SCTP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; + } + break; + case cpu_to_be16(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + switch (ipv6_hdr(skb)->nexthdr) { + case IPPROTO_TCP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; + case IPPROTO_SCTP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; + } + break; + default: + if (unlikely(net_ratelimit())) + e_warn(probe, "partial checksum but proto=%x!\n", + skb->protocol); + break; + } + + return rtn; +} + static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags) @@ -5898,46 +5941,8 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT); - if (skb->ip_summed == CHECKSUM_PARTIAL) { - __be16 protocol; - - if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { - const struct vlan_ethhdr *vhdr = - (const struct vlan_ethhdr *)skb->data; - - protocol = vhdr->h_vlan_encapsulated_proto; - } else { - protocol = skb->protocol; - } - - switch (protocol) { - case cpu_to_be16(ETH_P_IP): - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; - break; - case cpu_to_be16(ETH_P_IPV6): - /* XXX what about other V6 headers?? */ - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; - break; - default: - if (unlikely(net_ratelimit())) { - e_warn(probe, "partial checksum " - "but proto=%x!\n", - skb->protocol); - } - break; - } - } + if (skb->ip_summed == CHECKSUM_PARTIAL) + type_tucmd_mlhl |= ixgbe_psum(adapter, skb); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); /* use index zero for tx checksum offload */ -- cgit v1.2.3 From 2b1b8edfe229b1832134827c6948d0b70029e965 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 7 Sep 2010 21:36:04 +0000 Subject: ixgbevf: Removed unneeded HW struct members The VF has no flash and can only do memory mapped I/O. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbevf/vf.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 94b750b8874f..61f9dc831424 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h @@ -124,8 +124,6 @@ struct ixgbe_hw { void *back; u8 __iomem *hw_addr; - u8 *flash_address; - unsigned long io_base; struct ixgbe_mac_info mac; struct ixgbe_mbx_info mbx; -- cgit v1.2.3 From 9e2effba2c16fc3bd47da605116485afe01e0be0 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 12 Mar 2010 16:22:32 -0800 Subject: RDS: Fix BUG_ONs to not fire when in a tasklet in_interrupt() is true in softirqs. The BUG_ONs are supposed to check for if irqs are disabled, so we should use BUG_ON(irqs_disabled()) instead, duh. Signed-off-by: Andy Grover --- net/rds/ib_rdma.c | 2 +- net/rds/rdma.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index a54cd63f9e35..a92aebcb7fcf 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -441,7 +441,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr) /* FIXME we need a way to tell a r/w MR * from a r/o MR */ - BUG_ON(in_interrupt()); + BUG_ON(irqs_disabled()); set_page_dirty(page); put_page(page); } diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 75fd13bb631b..3b442d4d64cf 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -440,7 +440,7 @@ void rds_rdma_free_op(struct rds_rdma_op *ro) * is the case for a RDMA_READ which copies from remote * to local memory */ if (!ro->r_write) { - BUG_ON(in_interrupt()); + BUG_ON(irqs_disabled()); set_page_dirty(page); } put_page(page); -- cgit v1.2.3 From 35b52c70534cb7193b218ec12efe6bc595312097 Mon Sep 17 00:00:00 2001 From: Tina Yang Date: Thu, 1 Apr 2010 14:09:00 -0700 Subject: RDS: Fix corrupted rds_mrs On second look at this bug (OFED #2002), it seems that the collision is not with the retransmission queue (packet acked by the peer), but with the local send completion. A theoretical sequence of events (from time t0 to t3) is thought to be as follows, Thread #1 t0: sock_release rds_release rds_send_drop_to /* wait on send completion */ t2: rds_rdma_drop_keys() /* destroy & free all mrs */ Thread #2 t1: rds_ib_send_cq_comp_handler rds_ib_send_unmap_rm rds_message_unmapped /* wake up #1 @ t0 */ t3: rds_message_put rds_message_purge rds_mr_put /* memory corruption detected */ The problem with the rds_rdma_drop_keys() is it could remove a mr's refcount more than its due (i.e. repeatedly as long as it still remains in the tree (mr->r_refcount > 0)). Theoretically it should remove only one reference - reference by the tree. /* Release any MRs associated with this socket */ while ((node = rb_first(&rs->rs_rdma_keys))) { mr = container_of(node, struct rds_mr, r_rb_node); if (mr->r_trans == rs->rs_transport) mr->r_invalidate = 0; rds_mr_put(mr); } I think the correct way of doing it is to remove the mr from the tree and rds_destroy_mr it first, then a rds_mr_put() to decrement its reference count by one. Whichever thread holds the last reference will free the mr via rds_mr_put(). Signed-off-by: Tina Yang Signed-off-by: Andy Grover --- net/rds/rdma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 3b442d4d64cf..463b458ff27e 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -130,14 +130,22 @@ void rds_rdma_drop_keys(struct rds_sock *rs) { struct rds_mr *mr; struct rb_node *node; + unsigned long flags; /* Release any MRs associated with this socket */ + spin_lock_irqsave(&rs->rs_rdma_lock, flags); while ((node = rb_first(&rs->rs_rdma_keys))) { mr = container_of(node, struct rds_mr, r_rb_node); if (mr->r_trans == rs->rs_transport) mr->r_invalidate = 0; + rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys); + RB_CLEAR_NODE(&mr->r_rb_node); + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); + rds_destroy_mr(mr); rds_mr_put(mr); + spin_lock_irqsave(&rs->rs_rdma_lock, flags); } + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); if (rs->rs_transport && rs->rs_transport->flush_mrs) rs->rs_transport->flush_mrs(); -- cgit v1.2.3 From 7c82eaf00ec7d460932be9314b29997006b799b6 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 19 Feb 2010 18:01:41 -0800 Subject: RDS: Rewrite rds_send_drop_to() for clarity This function has been the source of numerous bugs; it's just too complicated. Simplified to nest spinlocks cleanly within the second loop body, and kick out early if there are no rms to drop. This will be a little slower because conn lock is grabbed for each entry instead of "caching" the lock across rms, but this should be entirely irrelevant to fastpath performance. Signed-off-by: Andy Grover --- net/rds/send.c | 64 ++++++++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index 9c1c6bcaa6c9..aee58f931b69 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -619,9 +619,8 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) { struct rds_message *rm, *tmp; struct rds_connection *conn; - unsigned long flags, flags2; + unsigned long flags; LIST_HEAD(list); - int wake = 0; /* get all the messages we're dropping under the rs lock */ spin_lock_irqsave(&rs->rs_lock, flags); @@ -631,59 +630,54 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) dest->sin_port != rm->m_inc.i_hdr.h_dport)) continue; - wake = 1; list_move(&rm->m_sock_item, &list); rds_send_sndbuf_remove(rs, rm); clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); } /* order flag updates with the rs lock */ - if (wake) - smp_mb__after_clear_bit(); + smp_mb__after_clear_bit(); spin_unlock_irqrestore(&rs->rs_lock, flags); - conn = NULL; + if (list_empty(&list)) + return; - /* now remove the messages from the conn list as needed */ + /* Remove the messages from the conn */ list_for_each_entry(rm, &list, m_sock_item) { - /* We do this here rather than in the loop above, so that - * we don't have to nest m_rs_lock under rs->rs_lock */ - spin_lock_irqsave(&rm->m_rs_lock, flags2); - /* If this is a RDMA operation, notify the app. */ - spin_lock(&rs->rs_lock); - __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); - spin_unlock(&rs->rs_lock); - rm->m_rs = NULL; - spin_unlock_irqrestore(&rm->m_rs_lock, flags2); + + conn = rm->m_inc.i_conn; + spin_lock_irqsave(&conn->c_lock, flags); /* - * If we see this flag cleared then we're *sure* that someone - * else beat us to removing it from the conn. If we race - * with their flag update we'll get the lock and then really - * see that the flag has been cleared. + * Maybe someone else beat us to removing rm from the conn. + * If we race with their flag update we'll get the lock and + * then really see that the flag has been cleared. */ - if (!test_bit(RDS_MSG_ON_CONN, &rm->m_flags)) + if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { + spin_unlock_irqrestore(&conn->c_lock, flags); continue; - - if (conn != rm->m_inc.i_conn) { - if (conn) - spin_unlock_irqrestore(&conn->c_lock, flags); - conn = rm->m_inc.i_conn; - spin_lock_irqsave(&conn->c_lock, flags); } - if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { - list_del_init(&rm->m_conn_item); - rds_message_put(rm); - } - } + /* + * Couldn't grab m_rs_lock in top loop (lock ordering), + * but we can now. + */ + spin_lock(&rm->m_rs_lock); - if (conn) + spin_lock(&rs->rs_lock); + __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); + spin_unlock(&rs->rs_lock); + + rm->m_rs = NULL; + spin_unlock(&rm->m_rs_lock); + + list_del_init(&rm->m_conn_item); + rds_message_put(rm); spin_unlock_irqrestore(&conn->c_lock, flags); + } - if (wake) - rds_wake_sk_sleep(rs); + rds_wake_sk_sleep(rs); while (!list_empty(&list)) { rm = list_entry(list.next, struct rds_message, m_sock_item); -- cgit v1.2.3 From 9de0864cf55927a7383b5ba6e48834ff3ef053de Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:50:54 -0700 Subject: RDS: Fix locking in send on m_rs_lock Do not nest m_rs_lock under c_lock Disable interrupts in {rdma,atomic}_send_complete Signed-off-by: Andy Grover --- net/rds/send.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index aee58f931b69..725fb0419797 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -415,8 +415,9 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) struct rds_sock *rs = NULL; struct rds_rdma_op *ro; struct rds_notifier *notifier; + unsigned long flags; - spin_lock(&rm->m_rs_lock); + spin_lock_irqsave(&rm->m_rs_lock, flags); ro = rm->m_rdma_op; if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && @@ -433,7 +434,7 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) ro->r_notifier = NULL; } - spin_unlock(&rm->m_rs_lock); + spin_unlock_irqrestore(&rm->m_rs_lock, flags); if (rs) { rds_wake_sk_sleep(rs); @@ -647,8 +648,8 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) list_for_each_entry(rm, &list, m_sock_item) { conn = rm->m_inc.i_conn; - spin_lock_irqsave(&conn->c_lock, flags); + spin_lock_irqsave(&conn->c_lock, flags); /* * Maybe someone else beat us to removing rm from the conn. * If we race with their flag update we'll get the lock and @@ -658,23 +659,23 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) spin_unlock_irqrestore(&conn->c_lock, flags); continue; } + list_del_init(&rm->m_conn_item); + spin_unlock_irqrestore(&conn->c_lock, flags); /* * Couldn't grab m_rs_lock in top loop (lock ordering), * but we can now. */ - spin_lock(&rm->m_rs_lock); + spin_lock_irqsave(&rm->m_rs_lock, flags); spin_lock(&rs->rs_lock); __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); spin_unlock(&rs->rs_lock); rm->m_rs = NULL; - spin_unlock(&rm->m_rs_lock); + spin_unlock_irqrestore(&rm->m_rs_lock, flags); - list_del_init(&rm->m_conn_item); rds_message_put(rm); - spin_unlock_irqrestore(&conn->c_lock, flags); } rds_wake_sk_sleep(rs); -- cgit v1.2.3 From 2dc393573430f853e56e25bf4b41c34ba2aa8fd6 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 11 Jun 2010 13:49:13 -0700 Subject: RDS: move rds_shutdown_worker impl. to rds_conn_shutdown This fits better in connection.c, rather than threads.c. Signed-off-by: Andy Grover --- net/rds/connection.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ net/rds/rds.h | 2 ++ net/rds/threads.c | 61 +++++++--------------------------------------------- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 7619b671ca28..895e39cdc6a6 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -263,6 +263,59 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, } EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); +void rds_conn_shutdown(struct rds_connection *conn) +{ + /* shut it down unless it's down already */ + if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) { + /* + * Quiesce the connection mgmt handlers before we start tearing + * things down. We don't hold the mutex for the entire + * duration of the shutdown operation, else we may be + * deadlocking with the CM handler. Instead, the CM event + * handler is supposed to check for state DISCONNECTING + */ + mutex_lock(&conn->c_cm_lock); + if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) + && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { + rds_conn_error(conn, "shutdown called in state %d\n", + atomic_read(&conn->c_state)); + mutex_unlock(&conn->c_cm_lock); + return; + } + mutex_unlock(&conn->c_cm_lock); + + mutex_lock(&conn->c_send_lock); + conn->c_trans->conn_shutdown(conn); + rds_conn_reset(conn); + mutex_unlock(&conn->c_send_lock); + + if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { + /* This can happen - eg when we're in the middle of tearing + * down the connection, and someone unloads the rds module. + * Quite reproduceable with loopback connections. + * Mostly harmless. + */ + rds_conn_error(conn, + "%s: failed to transition to state DOWN, " + "current state is %d\n", + __func__, + atomic_read(&conn->c_state)); + return; + } + } + + /* Then reconnect if it's still live. + * The passive side of an IB loopback connection is never added + * to the conn hash, so we never trigger a reconnect on this + * conn - the reconnect is always triggered by the active peer. */ + cancel_delayed_work_sync(&conn->c_conn_w); + if (!hlist_unhashed(&conn->c_hash_node)) + rds_queue_reconnect(conn); +} + +/* + * Stop and free a connection. + */ void rds_conn_destroy(struct rds_connection *conn) { struct rds_message *rm, *rtmp; diff --git a/net/rds/rds.h b/net/rds/rds.h index c224b5bb3ba9..1d3eef67137f 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -527,6 +527,7 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); +void rds_conn_shutdown(struct rds_connection *conn); void rds_conn_destroy(struct rds_connection *conn); void rds_conn_reset(struct rds_connection *conn); void rds_conn_drop(struct rds_connection *conn); @@ -681,6 +682,7 @@ extern unsigned int rds_sysctl_trace_level; int __init rds_threads_init(void); void rds_threads_exit(void); extern struct workqueue_struct *rds_wq; +void rds_queue_reconnect(struct rds_connection *conn); void rds_connect_worker(struct work_struct *); void rds_shutdown_worker(struct work_struct *); void rds_send_worker(struct work_struct *); diff --git a/net/rds/threads.c b/net/rds/threads.c index 786c20eaaf5e..6e2e43d5f576 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete); * We should *always* start with a random backoff; otherwise a broken connection * will always take several iterations to be re-established. */ -static void rds_queue_reconnect(struct rds_connection *conn) +void rds_queue_reconnect(struct rds_connection *conn) { unsigned long rand; @@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work) } } -void rds_shutdown_worker(struct work_struct *work) -{ - struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w); - - /* shut it down unless it's down already */ - if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) { - /* - * Quiesce the connection mgmt handlers before we start tearing - * things down. We don't hold the mutex for the entire - * duration of the shutdown operation, else we may be - * deadlocking with the CM handler. Instead, the CM event - * handler is supposed to check for state DISCONNECTING - */ - mutex_lock(&conn->c_cm_lock); - if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) && - !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { - rds_conn_error(conn, "shutdown called in state %d\n", - atomic_read(&conn->c_state)); - mutex_unlock(&conn->c_cm_lock); - return; - } - mutex_unlock(&conn->c_cm_lock); - - mutex_lock(&conn->c_send_lock); - conn->c_trans->conn_shutdown(conn); - rds_conn_reset(conn); - mutex_unlock(&conn->c_send_lock); - - if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { - /* This can happen - eg when we're in the middle of tearing - * down the connection, and someone unloads the rds module. - * Quite reproduceable with loopback connections. - * Mostly harmless. - */ - rds_conn_error(conn, - "%s: failed to transition to state DOWN, " - "current state is %d\n", - __func__, - atomic_read(&conn->c_state)); - return; - } - } - - /* Then reconnect if it's still live. - * The passive side of an IB loopback connection is never added - * to the conn hash, so we never trigger a reconnect on this - * conn - the reconnect is always triggered by the active peer. */ - cancel_delayed_work(&conn->c_conn_w); - if (!hlist_unhashed(&conn->c_hash_node)) - rds_queue_reconnect(conn); -} - void rds_send_worker(struct work_struct *work) { struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work); @@ -252,6 +200,13 @@ void rds_recv_worker(struct work_struct *work) } } +void rds_shutdown_worker(struct work_struct *work) +{ + struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w); + + rds_conn_shutdown(conn); +} + void rds_threads_exit(void) { destroy_workqueue(rds_wq); -- cgit v1.2.3 From 8690bfa17aea4c42da1bcf90a7af93d161eca624 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 11:56:44 -0800 Subject: RDS: cleanup: remove "== NULL"s and "!= NULL"s in ptr comparisons Favor "if (foo)" style over "if (foo != NULL)". Signed-off-by: Andy Grover --- net/rds/af_rds.c | 2 +- net/rds/bind.c | 4 ++-- net/rds/cong.c | 6 +++--- net/rds/connection.c | 4 ++-- net/rds/ib_cm.c | 14 +++++++------- net/rds/ib_recv.c | 20 ++++++++++---------- net/rds/ib_send.c | 4 ++-- net/rds/ib_sysctl.c | 2 +- net/rds/info.c | 12 ++++++------ net/rds/iw_cm.c | 14 +++++++------- net/rds/iw_recv.c | 20 ++++++++++---------- net/rds/iw_send.c | 4 ++-- net/rds/iw_sysctl.c | 2 +- net/rds/loop.c | 2 +- net/rds/message.c | 4 ++-- net/rds/page.c | 4 ++-- net/rds/rdma.c | 18 +++++++++--------- net/rds/recv.c | 4 ++-- net/rds/send.c | 14 +++++++------- net/rds/sysctl.c | 2 +- net/rds/tcp.c | 4 ++-- net/rds/tcp_connect.c | 2 +- net/rds/tcp_listen.c | 4 ++-- net/rds/tcp_recv.c | 10 +++++----- net/rds/tcp_send.c | 2 +- net/rds/threads.c | 2 +- 26 files changed, 90 insertions(+), 90 deletions(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index aebfecbdb841..63474e1f4dd8 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -62,7 +62,7 @@ static int rds_release(struct socket *sock) struct rds_sock *rs; unsigned long flags; - if (sk == NULL) + if (!sk) goto out; rs = rds_sk_to_rs(sk); diff --git a/net/rds/bind.c b/net/rds/bind.c index 5d95fc007f1a..65de5cbdb576 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -121,7 +121,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) do { if (rover == 0) rover++; - if (rds_bind_tree_walk(addr, cpu_to_be16(rover), rs) == NULL) { + if (!rds_bind_tree_walk(addr, cpu_to_be16(rover), rs)) { *port = cpu_to_be16(rover); ret = 0; break; @@ -184,7 +184,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; trans = rds_trans_get_preferred(sin->sin_addr.s_addr); - if (trans == NULL) { + if (!trans) { ret = -EADDRNOTAVAIL; rds_remove_bound(rs); if (printk_ratelimit()) diff --git a/net/rds/cong.c b/net/rds/cong.c index 0871a29f0780..c741e906d49f 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -141,7 +141,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr) unsigned long flags; map = kzalloc(sizeof(struct rds_cong_map), GFP_KERNEL); - if (map == NULL) + if (!map) return NULL; map->m_addr = addr; @@ -159,7 +159,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr) ret = rds_cong_tree_walk(addr, map); spin_unlock_irqrestore(&rds_cong_lock, flags); - if (ret == NULL) { + if (!ret) { ret = map; map = NULL; } @@ -205,7 +205,7 @@ int rds_cong_get_maps(struct rds_connection *conn) conn->c_lcong = rds_cong_from_addr(conn->c_laddr); conn->c_fcong = rds_cong_from_addr(conn->c_faddr); - if (conn->c_lcong == NULL || conn->c_fcong == NULL) + if (!(conn->c_lcong && conn->c_fcong)) return -ENOMEM; return 0; diff --git a/net/rds/connection.c b/net/rds/connection.c index 895e39cdc6a6..9c9afb58a143 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -148,7 +148,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, goto out; conn = kmem_cache_zalloc(rds_conn_slab, gfp); - if (conn == NULL) { + if (!conn) { conn = ERR_PTR(-ENOMEM); goto out; } @@ -502,7 +502,7 @@ int __init rds_conn_init(void) rds_conn_slab = kmem_cache_create("rds_connection", sizeof(struct rds_connection), 0, 0, NULL); - if (rds_conn_slab == NULL) + if (!rds_conn_slab) return -ENOMEM; rds_info_register_func(RDS_INFO_CONNECTIONS, rds_conn_info); diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index f68832798db2..b46bc2f22ab6 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -230,7 +230,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) * the rds_ibdev at all. */ rds_ibdev = ib_get_client_data(dev, &rds_ib_client); - if (rds_ibdev == NULL) { + if (!rds_ibdev) { if (printk_ratelimit()) printk(KERN_NOTICE "RDS/IB: No client_data for device %s\n", dev->name); @@ -306,7 +306,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_send_ring.w_nr * sizeof(struct rds_header), &ic->i_send_hdrs_dma, GFP_KERNEL); - if (ic->i_send_hdrs == NULL) { + if (!ic->i_send_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent send failed\n"); goto out; @@ -316,7 +316,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_recv_ring.w_nr * sizeof(struct rds_header), &ic->i_recv_hdrs_dma, GFP_KERNEL); - if (ic->i_recv_hdrs == NULL) { + if (!ic->i_recv_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent recv failed\n"); goto out; @@ -324,14 +324,14 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), &ic->i_ack_dma, GFP_KERNEL); - if (ic->i_ack == NULL) { + if (!ic->i_ack) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent ack failed\n"); goto out; } ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); - if (ic->i_sends == NULL) { + if (!ic->i_sends) { ret = -ENOMEM; rdsdebug("send allocation failed\n"); goto out; @@ -339,7 +339,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work)); - if (ic->i_recvs == NULL) { + if (!ic->i_recvs) { ret = -ENOMEM; rdsdebug("recv allocation failed\n"); goto out; @@ -693,7 +693,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) /* XXX too lazy? */ ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL); - if (ic == NULL) + if (!ic) return -ENOMEM; INIT_LIST_HEAD(&ic->ib_node); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index c74e9904a6b2..d0ee9c114c6c 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -53,7 +53,7 @@ static void rds_ib_frag_drop_page(struct rds_page_frag *frag) static void rds_ib_frag_free(struct rds_page_frag *frag) { rdsdebug("frag %p page %p\n", frag, frag->f_page); - BUG_ON(frag->f_page != NULL); + BUG_ON(frag->f_page); kmem_cache_free(rds_ib_frag_slab, frag); } @@ -143,14 +143,14 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, struct ib_sge *sge; int ret = -ENOMEM; - if (recv->r_ibinc == NULL) { + if (!recv->r_ibinc) { if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { rds_ib_stats_inc(s_ib_rx_alloc_limit); goto out; } recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, kptr_gfp); - if (recv->r_ibinc == NULL) { + if (!recv->r_ibinc) { atomic_dec(&rds_ib_allocation); goto out; } @@ -158,17 +158,17 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); } - if (recv->r_frag == NULL) { + if (!recv->r_frag) { recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, kptr_gfp); - if (recv->r_frag == NULL) + if (!recv->r_frag) goto out; INIT_LIST_HEAD(&recv->r_frag->f_item); recv->r_frag->f_page = NULL; } - if (ic->i_frag.f_page == NULL) { + if (!ic->i_frag.f_page) { ic->i_frag.f_page = alloc_page(page_gfp); - if (ic->i_frag.f_page == NULL) + if (!ic->i_frag.f_page) goto out; ic->i_frag.f_offset = 0; } @@ -757,7 +757,7 @@ static void rds_ib_process_recv(struct rds_connection *conn, * into the inc and save the inc so we can hang upcoming fragments * off its list. */ - if (ibinc == NULL) { + if (!ibinc) { ibinc = recv->r_ibinc; recv->r_ibinc = NULL; ic->i_ibinc = ibinc; @@ -940,13 +940,13 @@ int __init rds_ib_recv_init(void) rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming", sizeof(struct rds_ib_incoming), 0, 0, NULL); - if (rds_ib_incoming_slab == NULL) + if (!rds_ib_incoming_slab) goto out; rds_ib_frag_slab = kmem_cache_create("rds_ib_frag", sizeof(struct rds_page_frag), 0, 0, NULL); - if (rds_ib_frag_slab == NULL) + if (!rds_ib_frag_slab) kmem_cache_destroy(rds_ib_incoming_slab); else ret = 0; diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 17fa80803ab0..0b0090d2ee01 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -86,7 +86,7 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - if (rm->m_rdma_op != NULL) { + if (rm->m_rdma_op) { rds_ib_send_unmap_rdma(ic, rm->m_rdma_op); /* If the user asked for a completion notification on this @@ -525,7 +525,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } /* map the message the first time we see it */ - if (ic->i_rm == NULL) { + if (!ic->i_rm) { /* printk(KERN_NOTICE "rds_ib_xmit prep msg dport=%u flags=0x%x len=%d\n", be16_to_cpu(rm->m_inc.i_hdr.h_dport), diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c index 03f01cb4e0fe..c070524c4d95 100644 --- a/net/rds/ib_sysctl.c +++ b/net/rds/ib_sysctl.c @@ -135,7 +135,7 @@ void rds_ib_sysctl_exit(void) int __init rds_ib_sysctl_init(void) { rds_ib_sysctl_hdr = register_sysctl_paths(rds_ib_sysctl_path, rds_ib_sysctl_table); - if (rds_ib_sysctl_hdr == NULL) + if (!rds_ib_sysctl_hdr) return -ENOMEM; return 0; } diff --git a/net/rds/info.c b/net/rds/info.c index c45c4173a44d..4fdf1b6e84ff 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -76,7 +76,7 @@ void rds_info_register_func(int optname, rds_info_func func) BUG_ON(optname < RDS_INFO_FIRST || optname > RDS_INFO_LAST); spin_lock(&rds_info_lock); - BUG_ON(rds_info_funcs[offset] != NULL); + BUG_ON(rds_info_funcs[offset]); rds_info_funcs[offset] = func; spin_unlock(&rds_info_lock); } @@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(rds_info_deregister_func); */ void rds_info_iter_unmap(struct rds_info_iterator *iter) { - if (iter->addr != NULL) { + if (iter->addr) { kunmap_atomic(iter->addr, KM_USER0); iter->addr = NULL; } @@ -117,7 +117,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data, unsigned long this; while (bytes) { - if (iter->addr == NULL) + if (!iter->addr) iter->addr = kmap_atomic(*iter->pages, KM_USER0); this = min(bytes, PAGE_SIZE - iter->offset); @@ -188,7 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, >> PAGE_SHIFT; pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { + if (!pages) { ret = -ENOMEM; goto out; } @@ -206,7 +206,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, call_func: func = rds_info_funcs[optname - RDS_INFO_FIRST]; - if (func == NULL) { + if (!func) { ret = -ENOPROTOOPT; goto out; } @@ -234,7 +234,7 @@ call_func: ret = -EFAULT; out: - for (i = 0; pages != NULL && i < nr_pages; i++) + for (i = 0; pages && i < nr_pages; i++) put_page(pages[i]); kfree(pages); diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c index b5dd6ac39be8..712cf2d1f28e 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c @@ -257,7 +257,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) * the rds_iwdev at all. */ rds_iwdev = ib_get_client_data(dev, &rds_iw_client); - if (rds_iwdev == NULL) { + if (!rds_iwdev) { if (printk_ratelimit()) printk(KERN_NOTICE "RDS/IW: No client_data for device %s\n", dev->name); @@ -292,7 +292,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_send_ring.w_nr * sizeof(struct rds_header), &ic->i_send_hdrs_dma, GFP_KERNEL); - if (ic->i_send_hdrs == NULL) { + if (!ic->i_send_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent send failed\n"); goto out; @@ -302,7 +302,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_recv_ring.w_nr * sizeof(struct rds_header), &ic->i_recv_hdrs_dma, GFP_KERNEL); - if (ic->i_recv_hdrs == NULL) { + if (!ic->i_recv_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent recv failed\n"); goto out; @@ -310,14 +310,14 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), &ic->i_ack_dma, GFP_KERNEL); - if (ic->i_ack == NULL) { + if (!ic->i_ack) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent ack failed\n"); goto out; } ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_iw_send_work)); - if (ic->i_sends == NULL) { + if (!ic->i_sends) { ret = -ENOMEM; rdsdebug("send allocation failed\n"); goto out; @@ -325,7 +325,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) rds_iw_send_init_ring(ic); ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_iw_recv_work)); - if (ic->i_recvs == NULL) { + if (!ic->i_recvs) { ret = -ENOMEM; rdsdebug("recv allocation failed\n"); goto out; @@ -696,7 +696,7 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp) /* XXX too lazy? */ ic = kzalloc(sizeof(struct rds_iw_connection), GFP_KERNEL); - if (ic == NULL) + if (!ic) return -ENOMEM; INIT_LIST_HEAD(&ic->iw_node); diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index 3d479067d54d..48bcf4f2bf3c 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -53,7 +53,7 @@ static void rds_iw_frag_drop_page(struct rds_page_frag *frag) static void rds_iw_frag_free(struct rds_page_frag *frag) { rdsdebug("frag %p page %p\n", frag, frag->f_page); - BUG_ON(frag->f_page != NULL); + BUG_ON(frag->f_page); kmem_cache_free(rds_iw_frag_slab, frag); } @@ -143,14 +143,14 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn, struct ib_sge *sge; int ret = -ENOMEM; - if (recv->r_iwinc == NULL) { + if (!recv->r_iwinc) { if (!atomic_add_unless(&rds_iw_allocation, 1, rds_iw_sysctl_max_recv_allocation)) { rds_iw_stats_inc(s_iw_rx_alloc_limit); goto out; } recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab, kptr_gfp); - if (recv->r_iwinc == NULL) { + if (!recv->r_iwinc) { atomic_dec(&rds_iw_allocation); goto out; } @@ -158,17 +158,17 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn, rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr); } - if (recv->r_frag == NULL) { + if (!recv->r_frag) { recv->r_frag = kmem_cache_alloc(rds_iw_frag_slab, kptr_gfp); - if (recv->r_frag == NULL) + if (!recv->r_frag) goto out; INIT_LIST_HEAD(&recv->r_frag->f_item); recv->r_frag->f_page = NULL; } - if (ic->i_frag.f_page == NULL) { + if (!ic->i_frag.f_page) { ic->i_frag.f_page = alloc_page(page_gfp); - if (ic->i_frag.f_page == NULL) + if (!ic->i_frag.f_page) goto out; ic->i_frag.f_offset = 0; } @@ -716,7 +716,7 @@ static void rds_iw_process_recv(struct rds_connection *conn, * into the inc and save the inc so we can hang upcoming fragments * off its list. */ - if (iwinc == NULL) { + if (!iwinc) { iwinc = recv->r_iwinc; recv->r_iwinc = NULL; ic->i_iwinc = iwinc; @@ -899,13 +899,13 @@ int __init rds_iw_recv_init(void) rds_iw_incoming_slab = kmem_cache_create("rds_iw_incoming", sizeof(struct rds_iw_incoming), 0, 0, NULL); - if (rds_iw_incoming_slab == NULL) + if (!rds_iw_incoming_slab) goto out; rds_iw_frag_slab = kmem_cache_create("rds_iw_frag", sizeof(struct rds_page_frag), 0, 0, NULL); - if (rds_iw_frag_slab == NULL) + if (!rds_iw_frag_slab) kmem_cache_destroy(rds_iw_incoming_slab); else ret = 0; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 52182ff7519e..dced532f9cfb 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -86,7 +86,7 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - if (rm->m_rdma_op != NULL) { + if (rm->m_rdma_op) { rds_iw_send_unmap_rdma(ic, rm->m_rdma_op); /* If the user asked for a completion notification on this @@ -556,7 +556,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, } /* map the message the first time we see it */ - if (ic->i_rm == NULL) { + if (!ic->i_rm) { /* printk(KERN_NOTICE "rds_iw_xmit prep msg dport=%u flags=0x%x len=%d\n", be16_to_cpu(rm->m_inc.i_hdr.h_dport), diff --git a/net/rds/iw_sysctl.c b/net/rds/iw_sysctl.c index 1c4428a61a02..3cb0587d6f50 100644 --- a/net/rds/iw_sysctl.c +++ b/net/rds/iw_sysctl.c @@ -125,7 +125,7 @@ void rds_iw_sysctl_exit(void) int __init rds_iw_sysctl_init(void) { rds_iw_sysctl_hdr = register_sysctl_paths(rds_iw_sysctl_path, rds_iw_sysctl_table); - if (rds_iw_sysctl_hdr == NULL) + if (!rds_iw_sysctl_hdr) return -ENOMEM; return 0; } diff --git a/net/rds/loop.c b/net/rds/loop.c index dd9879379457..a74b469a844a 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -112,7 +112,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) unsigned long flags; lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL); - if (lc == NULL) + if (!lc) return -ENOMEM; INIT_LIST_HEAD(&lc->loop_node); diff --git a/net/rds/message.c b/net/rds/message.c index 9a1d67e001ba..809656c2b25c 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -240,7 +240,7 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in unsigned int i; rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL); - if (rm == NULL) + if (!rm) return ERR_PTR(-ENOMEM); set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); @@ -284,7 +284,7 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ while (total_len) { - if (sg_page(sg) == NULL) { + if (!sg_page(sg)) { ret = rds_page_remainder_alloc(sg, total_len, GFP_HIGHUSER); if (ret) diff --git a/net/rds/page.c b/net/rds/page.c index 595a952d4b17..e5b2527ae257 100644 --- a/net/rds/page.c +++ b/net/rds/page.c @@ -116,7 +116,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, /* jump straight to allocation if we're trying for a huge page */ if (bytes >= PAGE_SIZE) { page = alloc_page(gfp); - if (page == NULL) { + if (!page) { ret = -ENOMEM; } else { sg_set_page(scat, page, PAGE_SIZE, 0); @@ -162,7 +162,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, rem = &per_cpu(rds_page_remainders, get_cpu()); local_irq_save(flags); - if (page == NULL) { + if (!page) { ret = -ENOMEM; break; } diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 463b458ff27e..dee698b979af 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -189,7 +189,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, goto out; } - if (rs->rs_transport->get_mr == NULL) { + if (!rs->rs_transport->get_mr) { ret = -EOPNOTSUPP; goto out; } @@ -205,13 +205,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, /* XXX clamp nr_pages to limit the size of this alloc? */ pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { + if (!pages) { ret = -ENOMEM; goto out; } mr = kzalloc(sizeof(struct rds_mr), GFP_KERNEL); - if (mr == NULL) { + if (!mr) { ret = -ENOMEM; goto out; } @@ -244,7 +244,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, nents = ret; sg = kcalloc(nents, sizeof(*sg), GFP_KERNEL); - if (sg == NULL) { + if (!sg) { ret = -ENOMEM; goto out; } @@ -425,7 +425,7 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force) /* May have to issue a dma_sync on this memory region. * Note we could avoid this if the operation was a RDMA READ, * but at this point we can't tell. */ - if (mr != NULL) { + if (mr) { if (mr->r_trans->sync_mr) mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE); @@ -511,13 +511,13 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, } pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { + if (!pages) { ret = -ENOMEM; goto out; } op = kzalloc(offsetof(struct rds_rdma_op, r_sg[nr_pages]), GFP_KERNEL); - if (op == NULL) { + if (!op) { ret = -ENOMEM; goto out; } @@ -643,7 +643,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, struct rds_rdma_op *op; if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || - rm->m_rdma_op != NULL) + rm->m_rdma_op) return -EINVAL; op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); @@ -681,7 +681,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); - if (mr == NULL) + if (!mr) err = -EINVAL; /* invalid r_key */ else atomic_inc(&mr->r_refcount); diff --git a/net/rds/recv.c b/net/rds/recv.c index c93588c2d553..88f1f5aecfa6 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -210,7 +210,7 @@ void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr, } rs = rds_find_bound(daddr, inc->i_hdr.h_dport); - if (rs == NULL) { + if (!rs) { rds_stats_inc(s_recv_drop_no_sock); goto out; } @@ -251,7 +251,7 @@ static int rds_next_incoming(struct rds_sock *rs, struct rds_incoming **inc) { unsigned long flags; - if (*inc == NULL) { + if (!*inc) { read_lock_irqsave(&rs->rs_recv_lock, flags); if (!list_empty(&rs->rs_recv_queue)) { *inc = list_entry(rs->rs_recv_queue.next, diff --git a/net/rds/send.c b/net/rds/send.c index 725fb0419797..817997daf785 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -164,7 +164,7 @@ int rds_send_xmit(struct rds_connection *conn) * offset and S/G temporaries. */ rm = conn->c_xmit_rm; - if (rm != NULL && + if (rm && conn->c_xmit_hdr_off == sizeof(struct rds_header) && conn->c_xmit_sg == rm->m_nents) { conn->c_xmit_rm = NULL; @@ -180,8 +180,8 @@ int rds_send_xmit(struct rds_connection *conn) /* If we're asked to send a cong map update, do so. */ - if (rm == NULL && test_and_clear_bit(0, &conn->c_map_queued)) { - if (conn->c_trans->xmit_cong_map != NULL) { + if (!rm && test_and_clear_bit(0, &conn->c_map_queued)) { + if (conn->c_trans->xmit_cong_map) { conn->c_map_offset = 0; conn->c_map_bytes = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; @@ -204,7 +204,7 @@ int rds_send_xmit(struct rds_connection *conn) * the connction. We can use this ref while holding the * send_sem.. rds_send_reset() is serialized with it. */ - if (rm == NULL) { + if (!rm) { unsigned int len; spin_lock_irqsave(&conn->c_lock, flags); @@ -224,7 +224,7 @@ int rds_send_xmit(struct rds_connection *conn) spin_unlock_irqrestore(&conn->c_lock, flags); - if (rm == NULL) { + if (!rm) { was_empty = 1; break; } @@ -875,7 +875,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; if ((rm->m_rdma_cookie || rm->m_rdma_op) && - conn->c_trans->xmit_rdma == NULL) { + !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", rm->m_rdma_op, conn->c_trans->xmit_rdma); @@ -961,7 +961,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) int ret = 0; rm = rds_message_alloc(0, GFP_ATOMIC); - if (rm == NULL) { + if (!rm) { ret = -ENOMEM; goto out; } diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c index 7829a20325d3..5a6dd81de188 100644 --- a/net/rds/sysctl.c +++ b/net/rds/sysctl.c @@ -111,7 +111,7 @@ int __init rds_sysctl_init(void) rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min; rds_sysctl_reg_table = register_sysctl_paths(rds_sysctl_path, rds_sysctl_rds_table); - if (rds_sysctl_reg_table == NULL) + if (!rds_sysctl_reg_table) return -ENOMEM; return 0; } diff --git a/net/rds/tcp.c b/net/rds/tcp.c index babf4577ff7d..aebe10314fdb 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -200,7 +200,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) struct rds_tcp_connection *tc; tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp); - if (tc == NULL) + if (!tc) return -ENOMEM; tc->t_sock = NULL; @@ -283,7 +283,7 @@ int __init rds_tcp_init(void) rds_tcp_conn_slab = kmem_cache_create("rds_tcp_connection", sizeof(struct rds_tcp_connection), 0, 0, NULL); - if (rds_tcp_conn_slab == NULL) { + if (!rds_tcp_conn_slab) { ret = -ENOMEM; goto out; } diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index c397524c039c..a65ee78db0c5 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c @@ -45,7 +45,7 @@ void rds_tcp_state_change(struct sock *sk) read_lock(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { + if (!conn) { state_change = sk->sk_state_change; goto out; } diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 975183fe6950..50b649eb6933 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -116,7 +116,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) read_lock(&sk->sk_callback_lock); ready = sk->sk_user_data; - if (ready == NULL) { /* check for teardown race */ + if (!ready) { /* check for teardown race */ ready = sk->sk_data_ready; goto out; } @@ -178,7 +178,7 @@ void rds_tcp_listen_stop(void) struct socket *sock = rds_tcp_listen_sock; struct sock *sk; - if (sock == NULL) + if (!sock) return; sk = sock->sk; diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 1aba6878fa5d..ea7382908aa5 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -190,10 +190,10 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb, * processing. */ while (left) { - if (tinc == NULL) { + if (!tinc) { tinc = kmem_cache_alloc(rds_tcp_incoming_slab, arg->gfp); - if (tinc == NULL) { + if (!tinc) { desc->error = -ENOMEM; goto out; } @@ -229,7 +229,7 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb, if (left && tc->t_tinc_data_rem) { clone = skb_clone(skb, arg->gfp); - if (clone == NULL) { + if (!clone) { desc->error = -ENOMEM; goto out; } @@ -326,7 +326,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) read_lock(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { /* check for teardown race */ + if (!conn) { /* check for teardown race */ ready = sk->sk_data_ready; goto out; } @@ -347,7 +347,7 @@ int __init rds_tcp_recv_init(void) rds_tcp_incoming_slab = kmem_cache_create("rds_tcp_incoming", sizeof(struct rds_tcp_incoming), 0, 0, NULL); - if (rds_tcp_incoming_slab == NULL) + if (!rds_tcp_incoming_slab) return -ENOMEM; return 0; } diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index a28b895ff0d1..e5f6ccef79ef 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -226,7 +226,7 @@ void rds_tcp_write_space(struct sock *sk) read_lock(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { + if (!conn) { write_space = sk->sk_write_space; goto out; } diff --git a/net/rds/threads.c b/net/rds/threads.c index 6e2e43d5f576..7a8ca7a1d983 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -215,7 +215,7 @@ void rds_threads_exit(void) int __init rds_threads_init(void) { rds_wq = create_workqueue("krdsd"); - if (rds_wq == NULL) + if (!rds_wq) return -ENOMEM; return 0; -- cgit v1.2.3 From e779137aa76d38d5c33a98ed887092ae4e4f016f Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 12:15:02 -0800 Subject: RDS: break out rdma and data ops into nested structs in rds_message Clearly separate rdma-related variables in rm from data-related ones. This is in anticipation of adding atomic support. Signed-off-by: Andy Grover --- net/rds/ib_send.c | 44 +++++++++++++++++++++++--------------------- net/rds/iw_send.c | 38 ++++++++++++++++++++------------------ net/rds/message.c | 30 +++++++++++++++--------------- net/rds/rdma.c | 9 +++++---- net/rds/rds.h | 16 +++++++++++----- net/rds/send.c | 30 +++++++++++++++--------------- net/rds/tcp_send.c | 14 +++++++------- 7 files changed, 96 insertions(+), 85 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 0b0090d2ee01..53750203c9e5 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -83,11 +83,11 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rdsdebug("ic %p send %p rm %p\n", ic, send, rm); ib_dma_unmap_sg(ic->i_cm_id->device, - rm->m_sg, rm->m_nents, - DMA_TO_DEVICE); + rm->data.m_sg, rm->data.m_nents, + DMA_TO_DEVICE); - if (rm->m_rdma_op) { - rds_ib_send_unmap_rdma(ic, rm->m_rdma_op); + if (rm->rdma.m_rdma_op) { + rds_ib_send_unmap_rdma(ic, rm->rdma.m_rdma_op); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -111,10 +111,10 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, */ rds_ib_send_rdma_complete(rm, wc_status); - if (rm->m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes); + if (rm->rdma.m_rdma_op->r_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -244,8 +244,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rm = rds_send_get_message(conn, send->s_op); if (rm) { - if (rm->m_rdma_op) - rds_ib_send_unmap_rdma(ic, rm->m_rdma_op); + if (rm->rdma.m_rdma_op) + rds_ib_send_unmap_rdma(ic, rm->rdma.m_rdma_op); rds_ib_send_rdma_complete(rm, wc.status); rds_message_put(rm); } @@ -532,18 +532,20 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, rm->m_inc.i_hdr.h_flags, be32_to_cpu(rm->m_inc.i_hdr.h_len)); */ - if (rm->m_nents) { - rm->m_count = ib_dma_map_sg(dev, - rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count); - if (rm->m_count == 0) { + if (rm->data.m_nents) { + rm->data.m_count = ib_dma_map_sg(dev, + rm->data.m_sg, + rm->data.m_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.m_count); + if (rm->data.m_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->m_count = 0; + rm->data.m_count = 0; } ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; @@ -559,10 +561,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->m_rdma_op) { + if (rm->rdma.m_rdma_op) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op->r_key); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -590,7 +592,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->m_sg[sg]; + scat = &rm->data.m_sg[sg]; sent = 0; i = 0; @@ -600,7 +602,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->m_rdma_op && rm->m_rdma_op->r_fence) + if (rm->rdma.m_rdma_op && rm->rdma.m_rdma_op->r_fence) send_flags = IB_SEND_FENCE; /* @@ -619,7 +621,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) { + for (; i < work_alloc && scat != &rm->data.m_sg[rm->data.m_count]; i++) { unsigned int len; send = &ic->i_sends[pos]; @@ -697,7 +699,7 @@ add_header: sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->m_sg[rm->m_count]) { + if (scat == &rm->data.m_sg[rm->data.m_count]) { prev->s_rm = ic->i_rm; prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; ic->i_rm = NULL; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index dced532f9cfb..c187e8fdeab1 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -83,11 +83,11 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rdsdebug("ic %p send %p rm %p\n", ic, send, rm); ib_dma_unmap_sg(ic->i_cm_id->device, - rm->m_sg, rm->m_nents, + rm->data.m_sg, rm->data.m_nents, DMA_TO_DEVICE); - if (rm->m_rdma_op) { - rds_iw_send_unmap_rdma(ic, rm->m_rdma_op); + if (rm->rdma.m_rdma_op) { + rds_iw_send_unmap_rdma(ic, rm->rdma.m_rdma_op); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -111,10 +111,10 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, */ rds_iw_send_rdma_complete(rm, wc_status); - if (rm->m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes); + if (rm->rdma.m_rdma_op->r_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -563,18 +563,20 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, rm->m_inc.i_hdr.h_flags, be32_to_cpu(rm->m_inc.i_hdr.h_len)); */ - if (rm->m_nents) { - rm->m_count = ib_dma_map_sg(dev, - rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count); - if (rm->m_count == 0) { + if (rm->data.m_nents) { + rm->data.m_count = ib_dma_map_sg(dev, + rm->data.m_sg, + rm->data.m_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.m_count); + if (rm->data.m_count == 0) { rds_iw_stats_inc(s_iw_tx_sg_mapping_failure); rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->m_count = 0; + rm->data.m_count = 0; } ic->i_unsignaled_wrs = rds_iw_sysctl_max_unsig_wrs; @@ -590,10 +592,10 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->m_rdma_op) { + if (rm->rdma.m_rdma_op) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op->r_key); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -621,7 +623,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->m_sg[sg]; + scat = &rm->data.m_sg[sg]; sent = 0; i = 0; @@ -631,7 +633,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->m_rdma_op && rm->m_rdma_op->r_fence) + if (rm->rdma.m_rdma_op && rm->rdma.m_rdma_op->r_fence) send_flags = IB_SEND_FENCE; /* @@ -650,7 +652,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, } /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) { + for (; i < work_alloc && scat != &rm->data.m_sg[rm->data.m_count]; i++) { unsigned int len; send = &ic->i_sends[pos]; @@ -728,7 +730,7 @@ add_header: sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->m_sg[rm->m_count]) { + if (scat == &rm->data.m_sg[rm->data.m_count]) { prev->s_rm = ic->i_rm; prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; ic->i_rm = NULL; diff --git a/net/rds/message.c b/net/rds/message.c index 809656c2b25c..4421d160b1a4 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -63,17 +63,17 @@ static void rds_message_purge(struct rds_message *rm) if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags))) return; - for (i = 0; i < rm->m_nents; i++) { - rdsdebug("putting data page %p\n", (void *)sg_page(&rm->m_sg[i])); + for (i = 0; i < rm->data.m_nents; i++) { + rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.m_sg[i])); /* XXX will have to put_page for page refs */ - __free_page(sg_page(&rm->m_sg[i])); + __free_page(sg_page(&rm->data.m_sg[i])); } - rm->m_nents = 0; + rm->data.m_nents = 0; - if (rm->m_rdma_op) - rds_rdma_free_op(rm->m_rdma_op); - if (rm->m_rdma_mr) - rds_mr_put(rm->m_rdma_mr); + if (rm->rdma.m_rdma_op) + rds_rdma_free_op(rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_mr) + rds_mr_put(rm->rdma.m_rdma_mr); } void rds_message_inc_purge(struct rds_incoming *inc) @@ -224,7 +224,7 @@ struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp) goto out; if (nents) - sg_init_table(rm->m_sg, nents); + sg_init_table(rm->data.m_sg, nents); atomic_set(&rm->m_refcount, 1); INIT_LIST_HEAD(&rm->m_sock_item); INIT_LIST_HEAD(&rm->m_conn_item); @@ -245,10 +245,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); - rm->m_nents = ceil(total_len, PAGE_SIZE); + rm->data.m_nents = ceil(total_len, PAGE_SIZE); - for (i = 0; i < rm->m_nents; ++i) { - sg_set_page(&rm->m_sg[i], + for (i = 0; i < rm->data.m_nents; ++i) { + sg_set_page(&rm->data.m_sg[i], virt_to_page(page_addrs[i]), PAGE_SIZE, 0); } @@ -278,7 +278,7 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, /* * now allocate and copy in the data payload. */ - sg = rm->m_sg; + sg = rm->data.m_sg; iov = first_iov; iov_off = 0; sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ @@ -289,7 +289,7 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, GFP_HIGHUSER); if (ret) goto out; - rm->m_nents++; + rm->data.m_nents++; sg_off = 0; } @@ -348,7 +348,7 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, iov = first_iov; iov_off = 0; - sg = rm->m_sg; + sg = rm->data.m_sg; vec_off = 0; copied = 0; diff --git a/net/rds/rdma.c b/net/rds/rdma.c index dee698b979af..24274bb9e329 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -643,14 +643,14 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, struct rds_rdma_op *op; if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || - rm->m_rdma_op) + rm->rdma.m_rdma_op) return -EINVAL; op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); if (IS_ERR(op)) return PTR_ERR(op); rds_stats_inc(s_send_rdma); - rm->m_rdma_op = op; + rm->rdma.m_rdma_op = op; return 0; } @@ -679,6 +679,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, */ r_key = rds_rdma_cookie_key(rm->m_rdma_cookie); + spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); if (!mr) @@ -689,7 +690,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, if (mr) { mr->r_trans->sync_mr(mr->r_trans_private, DMA_TO_DEVICE); - rm->m_rdma_mr = mr; + rm->rdma.m_rdma_mr = mr; } return err; } @@ -707,5 +708,5 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, rm->m_rdma_cookie != 0) return -EINVAL; - return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); + return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.m_rdma_mr); } diff --git a/net/rds/rds.h b/net/rds/rds.h index 1d3eef67137f..07a750b3fb31 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -259,12 +259,18 @@ struct rds_message { */ spinlock_t m_rs_lock; struct rds_sock *m_rs; - struct rds_rdma_op *m_rdma_op; rds_rdma_cookie_t m_rdma_cookie; - struct rds_mr *m_rdma_mr; - unsigned int m_nents; - unsigned int m_count; - struct scatterlist m_sg[0]; + struct { + struct { + struct rds_rdma_op *m_rdma_op; + struct rds_mr *m_rdma_mr; + } rdma; + struct { + unsigned int m_nents; + unsigned int m_count; + struct scatterlist m_sg[0]; + } data; + }; }; /* diff --git a/net/rds/send.c b/net/rds/send.c index 817997daf785..19dfd025498e 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -166,7 +166,7 @@ int rds_send_xmit(struct rds_connection *conn) rm = conn->c_xmit_rm; if (rm && conn->c_xmit_hdr_off == sizeof(struct rds_header) && - conn->c_xmit_sg == rm->m_nents) { + conn->c_xmit_sg == rm->data.m_nents) { conn->c_xmit_rm = NULL; conn->c_xmit_sg = 0; conn->c_xmit_hdr_off = 0; @@ -236,7 +236,7 @@ int rds_send_xmit(struct rds_connection *conn) * connection. * Therefore, we never retransmit messages with RDMA ops. */ - if (rm->m_rdma_op && + if (rm->rdma.m_rdma_op && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { spin_lock_irqsave(&conn->c_lock, flags); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) @@ -268,8 +268,8 @@ int rds_send_xmit(struct rds_connection *conn) * keep this simple and require that the transport either * send the whole rdma or none of it. */ - if (rm->m_rdma_op && !conn->c_xmit_rdma_sent) { - ret = conn->c_trans->xmit_rdma(conn, rm->m_rdma_op); + if (rm->rdma.m_rdma_op && !conn->c_xmit_rdma_sent) { + ret = conn->c_trans->xmit_rdma(conn, rm->rdma.m_rdma_op); if (ret) break; conn->c_xmit_rdma_sent = 1; @@ -279,7 +279,7 @@ int rds_send_xmit(struct rds_connection *conn) } if (conn->c_xmit_hdr_off < sizeof(struct rds_header) || - conn->c_xmit_sg < rm->m_nents) { + conn->c_xmit_sg < rm->data.m_nents) { ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, @@ -295,7 +295,7 @@ int rds_send_xmit(struct rds_connection *conn) ret -= tmp; } - sg = &rm->m_sg[conn->c_xmit_sg]; + sg = &rm->data.m_sg[conn->c_xmit_sg]; while (ret) { tmp = min_t(int, ret, sg->length - conn->c_xmit_data_off); @@ -306,7 +306,7 @@ int rds_send_xmit(struct rds_connection *conn) sg++; conn->c_xmit_sg++; BUG_ON(ret != 0 && - conn->c_xmit_sg == rm->m_nents); + conn->c_xmit_sg == rm->data.m_nents); } } } @@ -419,7 +419,7 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) spin_lock_irqsave(&rm->m_rs_lock, flags); - ro = rm->m_rdma_op; + ro = rm->rdma.m_rdma_op; if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && ro && ro->r_notify && ro->r_notifier) { notifier = ro->r_notifier; @@ -453,7 +453,7 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status { struct rds_rdma_op *ro; - ro = rm->m_rdma_op; + ro = rm->rdma.m_rdma_op; if (ro && ro->r_notify && ro->r_notifier) { ro->r_notifier->n_status = status; list_add_tail(&ro->r_notifier->n_list, &rs->rs_notify_queue); @@ -477,7 +477,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, spin_lock_irqsave(&conn->c_lock, flags); list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (rm->m_rdma_op == op) { + if (rm->rdma.m_rdma_op == op) { atomic_inc(&rm->m_refcount); found = rm; goto out; @@ -485,7 +485,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, } list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (rm->m_rdma_op == op) { + if (rm->rdma.m_rdma_op == op) { atomic_inc(&rm->m_refcount); found = rm; break; @@ -545,7 +545,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) spin_lock(&rs->rs_lock); if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { - struct rds_rdma_op *ro = rm->m_rdma_op; + struct rds_rdma_op *ro = rm->rdma.m_rdma_op; struct rds_notifier *notifier; list_del_init(&rm->m_sock_item); @@ -557,7 +557,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) &rs->rs_notify_queue); if (!notifier->n_status) notifier->n_status = status; - rm->m_rdma_op->r_notifier = NULL; + rm->rdma.m_rdma_op->r_notifier = NULL; } was_on_sock = 1; rm->m_rs = NULL; @@ -874,11 +874,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (ret) goto out; - if ((rm->m_rdma_cookie || rm->m_rdma_op) && + if ((rm->m_rdma_cookie || rm->rdma.m_rdma_op) && !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", - rm->m_rdma_op, conn->c_trans->xmit_rdma); + rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); ret = -EOPNOTSUPP; goto out; } diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index e5f6ccef79ef..d63aa35ac673 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -166,21 +166,21 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, goto out; } - while (sg < rm->m_nents) { + while (sg < rm->data.m_nents) { ret = tc->t_sock->ops->sendpage(tc->t_sock, - sg_page(&rm->m_sg[sg]), - rm->m_sg[sg].offset + off, - rm->m_sg[sg].length - off, + sg_page(&rm->data.m_sg[sg]), + rm->data.m_sg[sg].offset + off, + rm->data.m_sg[sg].length - off, MSG_DONTWAIT|MSG_NOSIGNAL); - rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->m_sg[sg]), - rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off, + rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.m_sg[sg]), + rm->data.m_sg[sg].offset + off, rm->data.m_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; - if (off == rm->m_sg[sg].length) { + if (off == rm->data.m_sg[sg].length) { off = 0; sg++; } -- cgit v1.2.3 From 3ef13f3c22aaea28aff383cb0883481d24885456 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 12:37:17 -0800 Subject: RDS: cleanup/fix rds_rdma_unuse First, it looks to me like the atomic_inc is wrong. We should be decrementing refcount only once here, no? It's already being done by the mr_put() at the end. Second, simplify the logic a bit by bailing early (with a warning) if !mr. Signed-off-by: Andy Grover --- net/rds/rdma.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 24274bb9e329..5011efa62a92 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -414,27 +414,30 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force) spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); - if (mr && (mr->r_use_once || force)) { + if (!mr) { + printk(KERN_ERR "rds: trying to unuse MR with unknown r_key %u!\n", r_key); + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); + return; + } + + if (mr->r_use_once || force) { rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys); RB_CLEAR_NODE(&mr->r_rb_node); zot_me = 1; - } else if (mr) - atomic_inc(&mr->r_refcount); + } spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); /* May have to issue a dma_sync on this memory region. * Note we could avoid this if the operation was a RDMA READ, * but at this point we can't tell. */ - if (mr) { - if (mr->r_trans->sync_mr) - mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE); + if (mr->r_trans->sync_mr) + mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE); - /* If the MR was marked as invalidate, this will - * trigger an async flush. */ - if (zot_me) - rds_destroy_mr(mr); - rds_mr_put(mr); - } + /* If the MR was marked as invalidate, this will + * trigger an async flush. */ + if (zot_me) + rds_destroy_mr(mr); + rds_mr_put(mr); } void rds_rdma_free_op(struct rds_rdma_op *ro) -- cgit v1.2.3 From fc445084f185cdd877bec323bfe724a361e2292a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 12:56:06 -0800 Subject: RDS: Explicitly allocate rm in sendmsg() r_m_copy_from_user used to allocate the rm as well as kernel buffers for the data, and then copy the data in. Now, sendmsg() allocates the rm, although the data buffer alloc still happens in r_m_copy_from_user. SGs are still allocated with rm, but now r_m_alloc_sgs() is used to reserve them. This allows multiple SG lists to be allocated from the one rm -- this is important once we also want to alloc our rdma sgl from this pool. Signed-off-by: Andy Grover --- net/rds/message.c | 51 ++++++++++++++++++++++++++++++--------------------- net/rds/rds.h | 7 +++++-- net/rds/send.c | 31 +++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 4421d160b1a4..3498cbcc7542 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -214,17 +214,22 @@ int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 o } EXPORT_SYMBOL_GPL(rds_message_add_rdma_dest_extension); -struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp) +/* + * Each rds_message is allocated with extra space for the scatterlist entries + * rds ops will need. This is to minimize memory allocation count. Then, each rds op + * can grab SGs when initializing its part of the rds_message. + */ +struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) { struct rds_message *rm; - rm = kzalloc(sizeof(struct rds_message) + - (nents * sizeof(struct scatterlist)), gfp); + rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp); if (!rm) goto out; - if (nents) - sg_init_table(rm->data.m_sg, nents); + rm->m_used_sgs = 0; + rm->m_total_sgs = extra_len / sizeof(struct scatterlist); + atomic_set(&rm->m_refcount, 1); INIT_LIST_HEAD(&rm->m_sock_item); INIT_LIST_HEAD(&rm->m_conn_item); @@ -234,6 +239,23 @@ out: return rm; } +/* + * RDS ops use this to grab SG entries from the rm's sg pool. + */ +struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) +{ + struct scatterlist *sg_first = (struct scatterlist *) &rm[1]; + struct scatterlist *sg_ret; + + WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs); + + sg_ret = &sg_first[rm->m_used_sgs]; + + rm->m_used_sgs += nents; + + return sg_ret; +} + struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len) { struct rds_message *rm; @@ -256,22 +278,15 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in return rm; } -struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, +int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, size_t total_len) { unsigned long to_copy; unsigned long iov_off; unsigned long sg_off; - struct rds_message *rm; struct iovec *iov; struct scatterlist *sg; - int ret; - - rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL); - if (rm == NULL) { - ret = -ENOMEM; - goto out; - } + int ret = 0; rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); @@ -320,14 +335,8 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, sg++; } - ret = 0; out: - if (ret) { - if (rm) - rds_message_put(rm); - rm = ERR_PTR(ret); - } - return rm; + return ret; } int rds_message_inc_copy_to_user(struct rds_incoming *inc, diff --git a/net/rds/rds.h b/net/rds/rds.h index 07a750b3fb31..d29c71aabbd4 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -268,9 +268,11 @@ struct rds_message { struct { unsigned int m_nents; unsigned int m_count; - struct scatterlist m_sg[0]; + struct scatterlist *m_sg; } data; }; + unsigned int m_used_sgs; + unsigned int m_total_sgs; }; /* @@ -573,7 +575,8 @@ rds_conn_connecting(struct rds_connection *conn) /* message.c */ struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); -struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, +struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); +int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, size_t total_len); struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); void rds_message_populate_header(struct rds_header *hdr, __be16 sport, diff --git a/net/rds/send.c b/net/rds/send.c index 19dfd025498e..28d09447207b 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -758,6 +758,19 @@ out: return *queued; } +/* + * rds_message is getting to be quite complicated, and we'd like to allocate + * it all in one go. This figures out how big it needs to be up front. + */ +static int rds_rm_size(struct msghdr *msg, int data_len) +{ + int size = 0; + + size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); + + return size; +} + static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, struct msghdr *msg, int *allocated_mr) { @@ -845,13 +858,23 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; } - rm = rds_message_copy_from_user(msg->msg_iov, payload_len); - if (IS_ERR(rm)) { - ret = PTR_ERR(rm); - rm = NULL; + /* size of rm including all sgs */ + ret = rds_rm_size(msg, payload_len); + if (ret < 0) + goto out; + + rm = rds_message_alloc(ret, GFP_KERNEL); + if (!rm) { + ret = -ENOMEM; goto out; } + rm->data.m_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); + /* XXX fix this to not allocate memory */ + ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); + if (ret) + goto out; + rm->m_daddr = daddr; /* rds_conn_create has a spinlock that runs with IRQ off. -- cgit v1.2.3 From 21f79afa5fda2820671a8f64c3d0e43bb118053b Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 12:57:27 -0800 Subject: RDS: fold rdma.h into rds.h RDMA is now an intrinsic part of RDS, so it's easier to just have a single header. Signed-off-by: Andy Grover --- net/rds/af_rds.c | 1 - net/rds/connection.c | 1 - net/rds/ib_rdma.c | 1 - net/rds/ib_send.c | 1 - net/rds/iw_rdma.c | 1 - net/rds/iw_send.c | 1 - net/rds/message.c | 1 - net/rds/rdma.c | 2 +- net/rds/rdma.h | 85 ---------------------------------------------------- net/rds/rds.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++ net/rds/recv.c | 1 - net/rds/send.c | 1 - 12 files changed, 77 insertions(+), 95 deletions(-) delete mode 100644 net/rds/rdma.h diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 63474e1f4dd8..ef09340cf7a9 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -39,7 +39,6 @@ #include #include "rds.h" -#include "rdma.h" /* this is just used for stats gathering :/ */ static DEFINE_SPINLOCK(rds_sock_lock); diff --git a/net/rds/connection.c b/net/rds/connection.c index 9c9afb58a143..88bcaf3f3e16 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -37,7 +37,6 @@ #include "rds.h" #include "loop.h" -#include "rdma.h" #define RDS_CONNECTION_HASH_BITS 12 #define RDS_CONNECTION_HASH_ENTRIES (1 << RDS_CONNECTION_HASH_BITS) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index a92aebcb7fcf..0f3b5a2f3fe0 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -34,7 +34,6 @@ #include #include "rds.h" -#include "rdma.h" #include "ib.h" diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 53750203c9e5..575fce463c65 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -36,7 +36,6 @@ #include #include "rds.h" -#include "rdma.h" #include "ib.h" static void rds_ib_send_rdma_complete(struct rds_message *rm, diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index 13dc1862d862..4e152e2daa3d 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c @@ -34,7 +34,6 @@ #include #include "rds.h" -#include "rdma.h" #include "iw.h" diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index c187e8fdeab1..62234b804d93 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -36,7 +36,6 @@ #include #include "rds.h" -#include "rdma.h" #include "iw.h" static void rds_iw_send_rdma_complete(struct rds_message *rm, diff --git a/net/rds/message.c b/net/rds/message.c index 3498cbcc7542..fb382fbb5b6f 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -34,7 +34,6 @@ #include #include "rds.h" -#include "rdma.h" static DECLARE_WAIT_QUEUE_HEAD(rds_message_flush_waitq); diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 5011efa62a92..a21edad33950 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -35,7 +35,7 @@ #include #include /* for DMA_*_DEVICE */ -#include "rdma.h" +#include "rds.h" /* * XXX diff --git a/net/rds/rdma.h b/net/rds/rdma.h deleted file mode 100644 index 909c39835a5d..000000000000 --- a/net/rds/rdma.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _RDS_RDMA_H -#define _RDS_RDMA_H - -#include -#include -#include - -#include "rds.h" - -struct rds_mr { - struct rb_node r_rb_node; - atomic_t r_refcount; - u32 r_key; - - /* A copy of the creation flags */ - unsigned int r_use_once:1; - unsigned int r_invalidate:1; - unsigned int r_write:1; - - /* This is for RDS_MR_DEAD. - * It would be nice & consistent to make this part of the above - * bit field here, but we need to use test_and_set_bit. - */ - unsigned long r_state; - struct rds_sock *r_sock; /* back pointer to the socket that owns us */ - struct rds_transport *r_trans; - void *r_trans_private; -}; - -/* Flags for mr->r_state */ -#define RDS_MR_DEAD 0 - -struct rds_rdma_op { - u32 r_key; - u64 r_remote_addr; - unsigned int r_write:1; - unsigned int r_fence:1; - unsigned int r_notify:1; - unsigned int r_recverr:1; - unsigned int r_mapped:1; - struct rds_notifier *r_notifier; - unsigned int r_bytes; - unsigned int r_nents; - unsigned int r_count; - struct scatterlist r_sg[0]; -}; - -static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset) -{ - return r_key | (((u64) offset) << 32); -} - -static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie) -{ - return cookie; -} - -static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) -{ - return cookie >> 32; -} - -int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); -int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen); -int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); -void rds_rdma_drop_keys(struct rds_sock *rs); -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -void rds_rdma_free_op(struct rds_rdma_op *ro); -void rds_rdma_send_complete(struct rds_message *rm, int); - -extern void __rds_put_mr_final(struct rds_mr *mr); -static inline void rds_mr_put(struct rds_mr *mr) -{ - if (atomic_dec_and_test(&mr->r_refcount)) - __rds_put_mr_final(mr); -} - -#endif diff --git a/net/rds/rds.h b/net/rds/rds.h index d29c71aabbd4..7c4adbe8c284 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -206,6 +206,60 @@ struct rds_incoming { rds_rdma_cookie_t i_rdma_cookie; }; +struct rds_mr { + struct rb_node r_rb_node; + atomic_t r_refcount; + u32 r_key; + + /* A copy of the creation flags */ + unsigned int r_use_once:1; + unsigned int r_invalidate:1; + unsigned int r_write:1; + + /* This is for RDS_MR_DEAD. + * It would be nice & consistent to make this part of the above + * bit field here, but we need to use test_and_set_bit. + */ + unsigned long r_state; + struct rds_sock *r_sock; /* back pointer to the socket that owns us */ + struct rds_transport *r_trans; + void *r_trans_private; +}; + +/* Flags for mr->r_state */ +#define RDS_MR_DEAD 0 + +struct rds_rdma_op { + u32 r_key; + u64 r_remote_addr; + unsigned int r_write:1; + unsigned int r_fence:1; + unsigned int r_notify:1; + unsigned int r_recverr:1; + unsigned int r_mapped:1; + unsigned int r_active:1; + struct rds_notifier *r_notifier; + unsigned int r_bytes; + unsigned int r_nents; + unsigned int r_count; + struct scatterlist *r_sg; +}; + +static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset) +{ + return r_key | (((u64) offset) << 32); +} + +static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie) +{ + return cookie; +} + +static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) +{ + return cookie >> 32; +} + /* * m_sock_item and m_conn_item are on lists that are serialized under * conn->c_lock. m_sock_item has additional meaning in that once it is empty @@ -654,6 +708,28 @@ struct rds_message *rds_send_get_message(struct rds_connection *, /* rdma.c */ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force); +int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); +int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen); +int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); +void rds_rdma_drop_keys(struct rds_sock *rs); +int rds_rdma_extra_size(struct rds_rdma_args *args); +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +void rds_rdma_free_op(struct rds_rdma_op *ro); +void rds_rdma_send_complete(struct rds_message *rm, int); + +extern void __rds_put_mr_final(struct rds_mr *mr); +static inline void rds_mr_put(struct rds_mr *mr) +{ + if (atomic_dec_and_test(&mr->r_refcount)) + __rds_put_mr_final(mr); +} /* stats.c */ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats); diff --git a/net/rds/recv.c b/net/rds/recv.c index 88f1f5aecfa6..5188763b609b 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -36,7 +36,6 @@ #include #include "rds.h" -#include "rdma.h" void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, __be32 saddr) diff --git a/net/rds/send.c b/net/rds/send.c index 28d09447207b..89e26ffdc812 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -37,7 +37,6 @@ #include #include "rds.h" -#include "rdma.h" /* When transmitting messages in rds_send_xmit, we need to emerge from * time to time and briefly release the CPU. Otherwise the softlock watchdog -- cgit v1.2.3 From ff87e97a9d70c9ae133d3d3d7792b26ab85f4297 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:13:15 -0800 Subject: RDS: make m_rdma_op a member of rds_message This eliminates a separate memory alloc, although it is now necessary to add an "r_active" flag, since it is no longer to use the m_rdma_op pointer as an indicator of if an rdma op is present. rdma SGs allocated from rm sg pool. rds_rm_size also gets bigger. It's a little inefficient to run through CMSGs twice, but it makes later steps a lot smoother. Signed-off-by: Andy Grover --- net/rds/ib_send.c | 20 +++++----- net/rds/iw_send.c | 16 ++++---- net/rds/message.c | 9 +++-- net/rds/rdma.c | 113 +++++++++++++++++++++++++++++------------------------- net/rds/rds.h | 2 +- net/rds/send.c | 59 ++++++++++++++++++++-------- 6 files changed, 129 insertions(+), 90 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 575fce463c65..f0edfdb2866c 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -85,8 +85,8 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rm->data.m_sg, rm->data.m_nents, DMA_TO_DEVICE); - if (rm->rdma.m_rdma_op) { - rds_ib_send_unmap_rdma(ic, rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_op.r_active) { + rds_ib_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -110,10 +110,10 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, */ rds_ib_send_rdma_complete(rm, wc_status); - if (rm->rdma.m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); + if (rm->rdma.m_rdma_op.r_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -243,8 +243,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rm = rds_send_get_message(conn, send->s_op); if (rm) { - if (rm->rdma.m_rdma_op) - rds_ib_send_unmap_rdma(ic, rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_op.r_active) + rds_ib_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); rds_ib_send_rdma_complete(rm, wc.status); rds_message_put(rm); } @@ -560,10 +560,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->rdma.m_rdma_op) { + if (rm->rdma.m_rdma_op.r_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op.r_key); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -601,7 +601,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->rdma.m_rdma_op && rm->rdma.m_rdma_op->r_fence) + if (rm->rdma.m_rdma_op.r_active && rm->rdma.m_rdma_op.r_fence) send_flags = IB_SEND_FENCE; /* diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 62234b804d93..9b79a1b10445 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -85,8 +85,8 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rm->data.m_sg, rm->data.m_nents, DMA_TO_DEVICE); - if (rm->rdma.m_rdma_op) { - rds_iw_send_unmap_rdma(ic, rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_op.r_active) { + rds_iw_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -110,10 +110,10 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, */ rds_iw_send_rdma_complete(rm, wc_status); - if (rm->rdma.m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); + if (rm->rdma.m_rdma_op.r_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op->r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -591,10 +591,10 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->rdma.m_rdma_op) { + if (rm->rdma.m_rdma_op.r_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op.r_key); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -632,7 +632,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->rdma.m_rdma_op && rm->rdma.m_rdma_op->r_fence) + if (rm->rdma.m_rdma_op.r_active && rm->rdma.m_rdma_op.r_fence) send_flags = IB_SEND_FENCE; /* diff --git a/net/rds/message.c b/net/rds/message.c index fb382fbb5b6f..4352ce79b376 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -69,8 +69,8 @@ static void rds_message_purge(struct rds_message *rm) } rm->data.m_nents = 0; - if (rm->rdma.m_rdma_op) - rds_rdma_free_op(rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_op.r_active) + rds_rdma_free_op(&rm->rdma.m_rdma_op); if (rm->rdma.m_rdma_mr) rds_mr_put(rm->rdma.m_rdma_mr); } @@ -259,14 +259,17 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in { struct rds_message *rm; unsigned int i; + int num_sgs = ceil(total_len, PAGE_SIZE); + int extra_bytes = num_sgs * sizeof(struct scatterlist); - rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL); + rm = rds_message_alloc(extra_bytes, GFP_KERNEL); if (!rm) return ERR_PTR(-ENOMEM); set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); rm->data.m_nents = ceil(total_len, PAGE_SIZE); + rm->data.m_sg = rds_message_alloc_sgs(rm, num_sgs); for (i = 0; i < rm->data.m_nents; ++i) { sg_set_page(&rm->data.m_sg[i], diff --git a/net/rds/rdma.c b/net/rds/rdma.c index a21edad33950..7ff3379bab14 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -458,26 +458,60 @@ void rds_rdma_free_op(struct rds_rdma_op *ro) } kfree(ro->r_notifier); - kfree(ro); + ro->r_notifier = NULL; + ro->r_active = 0; +} + +/* + * Count the number of pages needed to describe an incoming iovec. + */ +static int rds_rdma_pages(struct rds_rdma_args *args) +{ + struct rds_iovec vec; + struct rds_iovec __user *local_vec; + unsigned int tot_pages = 0; + unsigned int nr_pages; + unsigned int i; + + local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; + + /* figure out the number of pages in the vector */ + for (i = 0; i < args->nr_local; i++) { + if (copy_from_user(&vec, &local_vec[i], + sizeof(struct rds_iovec))) + return -EFAULT; + + nr_pages = rds_pages_in_vec(&vec); + if (nr_pages == 0) + return -EINVAL; + + tot_pages += nr_pages; + } + + return tot_pages; +} + +int rds_rdma_extra_size(struct rds_rdma_args *args) +{ + return rds_rdma_pages(args) * sizeof(struct scatterlist); } /* * args is a pointer to an in-kernel copy in the sendmsg cmsg. */ -static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, - struct rds_rdma_args *args) +static int rds_rdma_prepare(struct rds_message *rm, + struct rds_sock *rs, + struct rds_rdma_args *args) { struct rds_iovec vec; - struct rds_rdma_op *op = NULL; + struct rds_rdma_op *op = &rm->rdma.m_rdma_op; unsigned int nr_pages; - unsigned int max_pages; unsigned int nr_bytes; struct page **pages = NULL; struct rds_iovec __user *local_vec; - struct scatterlist *sg; unsigned int nr; unsigned int i, j; - int ret; + int ret = 0; if (rs->rs_bound_addr == 0) { @@ -490,44 +524,21 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, goto out; } - nr_pages = 0; - max_pages = 0; - - local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; - - /* figure out the number of pages in the vector */ - for (i = 0; i < args->nr_local; i++) { - if (copy_from_user(&vec, &local_vec[i], - sizeof(struct rds_iovec))) { - ret = -EFAULT; - goto out; - } - - nr = rds_pages_in_vec(&vec); - if (nr == 0) { - ret = -EINVAL; - goto out; - } - - max_pages = max(nr, max_pages); - nr_pages += nr; - } - - pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL); - if (!pages) { - ret = -ENOMEM; + nr_pages = rds_rdma_pages(args); + if (nr_pages < 0) goto out; - } - op = kzalloc(offsetof(struct rds_rdma_op, r_sg[nr_pages]), GFP_KERNEL); - if (!op) { + pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + if (!pages) { ret = -ENOMEM; goto out; } + op->r_sg = rds_message_alloc_sgs(rm, nr_pages); op->r_write = !!(args->flags & RDS_RDMA_READWRITE); op->r_fence = !!(args->flags & RDS_RDMA_FENCE); op->r_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + op->r_active = 1; op->r_recverr = rs->rs_recverr; WARN_ON(!nr_pages); sg_init_table(op->r_sg, nr_pages); @@ -564,6 +575,8 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, (unsigned long long)args->remote_vec.addr, op->r_key); + local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; + for (i = 0; i < args->nr_local; i++) { if (copy_from_user(&vec, &local_vec[i], sizeof(struct rds_iovec))) { @@ -580,11 +593,6 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, rs->rs_user_addr = vec.addr; rs->rs_user_bytes = vec.bytes; - /* did the user change the vec under us? */ - if (nr > max_pages || op->r_nents + nr > nr_pages) { - ret = -EINVAL; - goto out; - } /* If it's a WRITE operation, we want to pin the pages for reading. * If it's a READ operation, we need to pin the pages for writing. */ @@ -599,6 +607,7 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, for (j = 0; j < nr; j++) { unsigned int offset = vec.addr & ~PAGE_MASK; + struct scatterlist *sg; sg = &op->r_sg[op->r_nents + j]; sg_set_page(sg, pages[j], @@ -628,12 +637,10 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, ret = 0; out: kfree(pages); - if (ret) { - if (op) - rds_rdma_free_op(op); - op = ERR_PTR(ret); - } - return op; + if (ret) + rds_rdma_free_op(op); + + return ret; } /* @@ -643,17 +650,17 @@ out: int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, struct cmsghdr *cmsg) { - struct rds_rdma_op *op; + int ret; if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || - rm->rdma.m_rdma_op) + rm->rdma.m_rdma_op.r_active) return -EINVAL; - op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); - if (IS_ERR(op)) - return PTR_ERR(op); + ret = rds_rdma_prepare(rm, rs, CMSG_DATA(cmsg)); + if (ret) + return ret; + rds_stats_inc(s_send_rdma); - rm->rdma.m_rdma_op = op; return 0; } diff --git a/net/rds/rds.h b/net/rds/rds.h index 7c4adbe8c284..0bb4957e0cfc 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -316,7 +316,7 @@ struct rds_message { rds_rdma_cookie_t m_rdma_cookie; struct { struct { - struct rds_rdma_op *m_rdma_op; + struct rds_rdma_op m_rdma_op; struct rds_mr *m_rdma_mr; } rdma; struct { diff --git a/net/rds/send.c b/net/rds/send.c index 89e26ffdc812..72dbe7fc4f54 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -235,7 +235,7 @@ int rds_send_xmit(struct rds_connection *conn) * connection. * Therefore, we never retransmit messages with RDMA ops. */ - if (rm->rdma.m_rdma_op && + if (rm->rdma.m_rdma_op.r_active && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { spin_lock_irqsave(&conn->c_lock, flags); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) @@ -267,8 +267,8 @@ int rds_send_xmit(struct rds_connection *conn) * keep this simple and require that the transport either * send the whole rdma or none of it. */ - if (rm->rdma.m_rdma_op && !conn->c_xmit_rdma_sent) { - ret = conn->c_trans->xmit_rdma(conn, rm->rdma.m_rdma_op); + if (rm->rdma.m_rdma_op.r_active && !conn->c_xmit_rdma_sent) { + ret = conn->c_trans->xmit_rdma(conn, &rm->rdma.m_rdma_op); if (ret) break; conn->c_xmit_rdma_sent = 1; @@ -418,9 +418,9 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) spin_lock_irqsave(&rm->m_rs_lock, flags); - ro = rm->rdma.m_rdma_op; + ro = &rm->rdma.m_rdma_op; if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && - ro && ro->r_notify && ro->r_notifier) { + ro->r_active && ro->r_notify && ro->r_notifier) { notifier = ro->r_notifier; rs = rm->m_rs; sock_hold(rds_rs_to_sk(rs)); @@ -452,8 +452,8 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status { struct rds_rdma_op *ro; - ro = rm->rdma.m_rdma_op; - if (ro && ro->r_notify && ro->r_notifier) { + ro = &rm->rdma.m_rdma_op; + if (ro->r_active && ro->r_notify && ro->r_notifier) { ro->r_notifier->n_status = status; list_add_tail(&ro->r_notifier->n_list, &rs->rs_notify_queue); ro->r_notifier = NULL; @@ -476,7 +476,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, spin_lock_irqsave(&conn->c_lock, flags); list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (rm->rdma.m_rdma_op == op) { + if (&rm->rdma.m_rdma_op == op) { atomic_inc(&rm->m_refcount); found = rm; goto out; @@ -484,7 +484,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, } list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (rm->rdma.m_rdma_op == op) { + if (&rm->rdma.m_rdma_op == op) { atomic_inc(&rm->m_refcount); found = rm; break; @@ -544,19 +544,20 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) spin_lock(&rs->rs_lock); if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { - struct rds_rdma_op *ro = rm->rdma.m_rdma_op; + struct rds_rdma_op *ro = &rm->rdma.m_rdma_op; struct rds_notifier *notifier; list_del_init(&rm->m_sock_item); rds_send_sndbuf_remove(rs, rm); - if (ro && ro->r_notifier && (status || ro->r_notify)) { + if (ro->r_active && ro->r_notifier && + (status || ro->r_notify)) { notifier = ro->r_notifier; list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); if (!notifier->n_status) notifier->n_status = status; - rm->rdma.m_rdma_op->r_notifier = NULL; + rm->rdma.m_rdma_op.r_notifier = NULL; } was_on_sock = 1; rm->m_rs = NULL; @@ -763,9 +764,37 @@ out: */ static int rds_rm_size(struct msghdr *msg, int data_len) { + struct cmsghdr *cmsg; int size = 0; + int retval; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + + if (cmsg->cmsg_level != SOL_RDS) + continue; + + switch (cmsg->cmsg_type) { + case RDS_CMSG_RDMA_ARGS: + retval = rds_rdma_extra_size(CMSG_DATA(cmsg)); + if (retval < 0) + return retval; + size += retval; + break; + + case RDS_CMSG_RDMA_DEST: + case RDS_CMSG_RDMA_MAP: + /* these are valid but do no add any size */ + break; + + default: + return -EINVAL; + } + + } - size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); + size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); return size; } @@ -896,11 +925,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (ret) goto out; - if ((rm->m_rdma_cookie || rm->rdma.m_rdma_op) && + if ((rm->m_rdma_cookie || rm->rdma.m_rdma_op.r_active) && !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", - rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); + &rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); ret = -EOPNOTSUPP; goto out; } -- cgit v1.2.3 From f4dd96f7b27743e568cec519eff0f951c56833c6 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:17:31 -0800 Subject: RDS: make sure all sgs alloced are initialized rds_message_alloc_sgs() now returns correctly-initialized sg lists, so calleds need not do this themselves. Signed-off-by: Andy Grover --- net/rds/message.c | 2 +- net/rds/rdma.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 4352ce79b376..7d678e217820 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -249,7 +249,7 @@ struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs); sg_ret = &sg_first[rm->m_used_sgs]; - + sg_init_table(sg_ret, nents); rm->m_used_sgs += nents; return sg_ret; diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 7ff3379bab14..4fda33045598 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -534,14 +534,13 @@ static int rds_rdma_prepare(struct rds_message *rm, goto out; } - op->r_sg = rds_message_alloc_sgs(rm, nr_pages); op->r_write = !!(args->flags & RDS_RDMA_READWRITE); op->r_fence = !!(args->flags & RDS_RDMA_FENCE); op->r_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); op->r_active = 1; op->r_recverr = rs->rs_recverr; WARN_ON(!nr_pages); - sg_init_table(op->r_sg, nr_pages); + op->r_sg = rds_message_alloc_sgs(rm, nr_pages); if (op->r_notify || op->r_recverr) { /* We allocate an uninitialized notifier here, because -- cgit v1.2.3 From a63273d4992603979ddb181b6a8f07082839b39f Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:19:32 -0800 Subject: RDS: Clear up some confusing code in send_remove_from_sock The previous code was correct, but made the assumption that if r_notifier was non-NULL then either r_recverr or r_notify was true. Valid, but fragile. Changed to explicitly check r_recverr (shows up in greps for recverr now, too.) Signed-off-by: Andy Grover --- net/rds/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/send.c b/net/rds/send.c index 72dbe7fc4f54..b751a8e77c41 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -551,7 +551,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) rds_send_sndbuf_remove(rs, rm); if (ro->r_active && ro->r_notifier && - (status || ro->r_notify)) { + (ro->r_notify || (ro->r_recverr && status))) { notifier = ro->r_notifier; list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); -- cgit v1.2.3 From 15133f6e67d8d646d0744336b4daa3135452cb0d Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:33:38 -0800 Subject: RDS: Implement atomic operations Implement a CMSG-based interface to do FADD and CSWP ops. Alter send routines to handle atomic ops. Add atomic counters to stats. Add xmit_atomic() to struct rds_transport Inline rds_ib_send_unmap_rdma into unmap_rm Signed-off-by: Andy Grover --- include/linux/rds.h | 19 +++++++ net/rds/ib.c | 1 + net/rds/ib.h | 1 + net/rds/ib_rdma.c | 4 +- net/rds/ib_send.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++------ net/rds/rdma.c | 73 +++++++++++++++++++++++++++ net/rds/rds.h | 33 +++++++++++-- net/rds/send.c | 71 ++++++++++++++++++++++++-- net/rds/stats.c | 2 + 9 files changed, 321 insertions(+), 23 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index 7f3971d9fc5c..9239152abf7a 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -73,6 +73,8 @@ #define RDS_CMSG_RDMA_MAP 3 #define RDS_CMSG_RDMA_STATUS 4 #define RDS_CMSG_CONG_UPDATE 5 +#define RDS_CMSG_ATOMIC_FADD 6 +#define RDS_CMSG_ATOMIC_CSWP 7 #define RDS_INFO_FIRST 10000 #define RDS_INFO_COUNTERS 10000 @@ -237,6 +239,23 @@ struct rds_rdma_args { u_int64_t user_token; }; +struct rds_atomic_args { + rds_rdma_cookie_t cookie; + uint64_t local_addr; + uint64_t remote_addr; + union { + struct { + uint64_t compare; + uint64_t swap; + } cswp; + struct { + uint64_t add; + } fadd; + }; + uint64_t flags; + uint64_t user_token; +}; + struct rds_rdma_notify { u_int64_t user_token; int32_t status; diff --git a/net/rds/ib.c b/net/rds/ib.c index 8f2d6dd7700a..f0d29656baff 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -264,6 +264,7 @@ struct rds_transport rds_ib_transport = { .xmit = rds_ib_xmit, .xmit_cong_map = NULL, .xmit_rdma = rds_ib_xmit_rdma, + .xmit_atomic = rds_ib_xmit_atomic, .recv = rds_ib_recv, .conn_alloc = rds_ib_conn_alloc, .conn_free = rds_ib_conn_free, diff --git a/net/rds/ib.h b/net/rds/ib.h index 64df4e79b29f..d2fd0aa4fde7 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -336,6 +336,7 @@ void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, u32 *adv_credits, int need_posted, int max_posted); +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 0f3b5a2f3fe0..242231f09464 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -298,7 +298,9 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) ibmr->fmr = ib_alloc_fmr(rds_ibdev->pd, (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | - IB_ACCESS_REMOTE_WRITE), + IB_ACCESS_REMOTE_WRITE| + IB_ACCESS_REMOTE_ATOMIC), + &pool->fmr_attr); if (IS_ERR(ibmr->fmr)) { err = PTR_ERR(ibmr->fmr); diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index f0edfdb2866c..b2bd164434ad 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -62,15 +62,17 @@ static void rds_ib_send_rdma_complete(struct rds_message *rm, rds_rdma_send_complete(rm, notify_status); } -static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic, - struct rds_rdma_op *op) +static void rds_ib_send_atomic_complete(struct rds_message *rm, + int wc_status) { - if (op->r_mapped) { - ib_dma_unmap_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, - op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->r_mapped = 0; - } + int notify_status; + + if (wc_status != IB_WC_SUCCESS) + notify_status = RDS_RDMA_OTHER_ERROR; + else + notify_status = RDS_RDMA_SUCCESS; + + rds_atomic_send_complete(rm, notify_status); } static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, @@ -86,7 +88,14 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, DMA_TO_DEVICE); if (rm->rdma.m_rdma_op.r_active) { - rds_ib_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); + struct rds_rdma_op *op = &rm->rdma.m_rdma_op; + + if (op->r_mapped) { + ib_dma_unmap_sg(ic->i_cm_id->device, + op->r_sg, op->r_nents, + op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->r_mapped = 0; + } /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -116,6 +125,24 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); } + if (rm->atomic.op_active) { + struct rm_atomic_op *op = &rm->atomic; + + /* unmap atomic recvbuf */ + if (op->op_mapped) { + ib_dma_unmap_sg(ic->i_cm_id->device, op->op_sg, 1, + DMA_FROM_DEVICE); + op->op_mapped = 0; + } + + rds_ib_send_atomic_complete(rm, wc_status); + + if (rm->atomic.op_type == RDS_ATOMIC_TYPE_CSWP) + rds_stats_inc(s_atomic_cswp); + else + rds_stats_inc(s_atomic_fadd); + } + /* If anyone waited for this message to get flushed out, wake * them up now */ rds_message_unmapped(rm); @@ -158,12 +185,9 @@ void rds_ib_send_clear_ring(struct rds_ib_connection *ic) u32 i; for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) { - if (send->s_wr.opcode == 0xdead) + if (!send->s_rm || send->s_wr.opcode == 0xdead) continue; - if (send->s_rm) - rds_ib_send_unmap_rm(ic, send, IB_WC_WR_FLUSH_ERR); - if (send->s_op) - rds_ib_send_unmap_rdma(ic, send->s_op); + rds_ib_send_unmap_rm(ic, send, IB_WC_WR_FLUSH_ERR); } } @@ -218,6 +242,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) break; case IB_WR_RDMA_WRITE: case IB_WR_RDMA_READ: + case IB_WR_ATOMIC_FETCH_AND_ADD: + case IB_WR_ATOMIC_CMP_AND_SWP: /* Nothing to be done - the SG list will be unmapped * when the SEND completes. */ break; @@ -243,8 +269,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rm = rds_send_get_message(conn, send->s_op); if (rm) { - if (rm->rdma.m_rdma_op.r_active) - rds_ib_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); + rds_ib_send_unmap_rm(ic, send, wc.status); rds_ib_send_rdma_complete(rm, wc.status); rds_message_put(rm); } @@ -736,6 +761,89 @@ out: return ret; } +/* + * Issue atomic operation. + * A simplified version of the rdma case, we always map 1 SG, and + * only 8 bytes, for the return value from the atomic operation. + */ +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) +{ + struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_ib_send_work *send = NULL; + struct ib_send_wr *failed_wr; + struct rds_ib_device *rds_ibdev; + u32 pos; + u32 work_alloc; + int ret; + + rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); + + work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, 1, &pos); + if (work_alloc != 1) { + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_stats_inc(s_ib_tx_ring_full); + ret = -ENOMEM; + goto out; + } + + /* address of send request in ring */ + send = &ic->i_sends[pos]; + send->s_queued = jiffies; + + if (op->op_type == RDS_ATOMIC_TYPE_CSWP) { + send->s_wr.opcode = IB_WR_ATOMIC_CMP_AND_SWP; + send->s_wr.wr.atomic.compare_add = op->op_compare; + send->s_wr.wr.atomic.swap = op->op_swap_add; + } else { /* FADD */ + send->s_wr.opcode = IB_WR_ATOMIC_FETCH_AND_ADD; + send->s_wr.wr.atomic.compare_add = op->op_swap_add; + send->s_wr.wr.atomic.swap = 0; + } + send->s_wr.send_flags = IB_SEND_SIGNALED; + send->s_wr.num_sge = 1; + send->s_wr.next = NULL; + send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; + send->s_wr.wr.atomic.rkey = op->op_rkey; + + /* map 8 byte retval buffer to the device */ + ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE); + rdsdebug("ic %p mapping atomic op %p. mapped %d pg\n", ic, op, ret); + if (ret != 1) { + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); + ret = -ENOMEM; /* XXX ? */ + goto out; + } + + /* Convert our struct scatterlist to struct ib_sge */ + send->s_sge[0].addr = ib_sg_dma_address(ic->i_cm_id->device, op->op_sg); + send->s_sge[0].length = ib_sg_dma_len(ic->i_cm_id->device, op->op_sg); + send->s_sge[0].lkey = ic->i_mr->lkey; + + rdsdebug("rva %Lx rpa %Lx len %u\n", op->op_remote_addr, + send->s_sge[0].addr, send->s_sge[0].length); + + failed_wr = &send->s_wr; + ret = ib_post_send(ic->i_cm_id->qp, &send->s_wr, &failed_wr); + rdsdebug("ic %p send %p (wr %p) ret %d wr %p\n", ic, + send, &send->s_wr, ret, failed_wr); + BUG_ON(failed_wr != &send->s_wr); + if (ret) { + printk(KERN_WARNING "RDS/IB: atomic ib_post_send to %pI4 " + "returned %d\n", &conn->c_faddr, ret); + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + goto out; + } + + if (unlikely(failed_wr != &send->s_wr)) { + printk(KERN_WARNING "RDS/IB: atomic ib_post_send() rc=%d, but failed_wqe updated!\n", ret); + BUG_ON(failed_wr != &send->s_wr); + } + +out: + return ret; +} + int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) { struct rds_ib_connection *ic = conn->c_transport_data; diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 4fda33045598..a7019df38c70 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -719,3 +719,76 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.m_rdma_mr); } + +/* + * Fill in rds_message for an atomic request. + */ +int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg) +{ + struct page *page = NULL; + struct rds_atomic_args *args; + int ret = 0; + + if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_atomic_args)) + || rm->atomic.op_active) + return -EINVAL; + + args = CMSG_DATA(cmsg); + + if (cmsg->cmsg_type == RDS_CMSG_ATOMIC_CSWP) { + rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; + rm->atomic.op_swap_add = args->cswp.swap; + rm->atomic.op_compare = args->cswp.compare; + } else { + rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD; + rm->atomic.op_swap_add = args->fadd.add; + } + + rm->m_rdma_cookie = args->cookie; + rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + rm->atomic.op_recverr = rs->rs_recverr; + rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); + + /* verify 8 byte-aligned */ + if (args->local_addr & 0x7) { + ret = -EFAULT; + goto err; + } + + ret = rds_pin_pages(args->local_addr, 1, &page, 1); + if (ret != 1) + goto err; + ret = 0; + + sg_set_page(rm->atomic.op_sg, page, 8, offset_in_page(args->local_addr)); + + if (rm->atomic.op_notify || rm->atomic.op_recverr) { + /* We allocate an uninitialized notifier here, because + * we don't want to do that in the completion handler. We + * would have to use GFP_ATOMIC there, and don't want to deal + * with failed allocations. + */ + rm->atomic.op_notifier = kmalloc(sizeof(*rm->atomic.op_notifier), GFP_KERNEL); + if (!rm->atomic.op_notifier) { + ret = -ENOMEM; + goto err; + } + + rm->atomic.op_notifier->n_user_token = args->user_token; + rm->atomic.op_notifier->n_status = RDS_RDMA_SUCCESS; + } + + rm->atomic.op_rkey = rds_rdma_cookie_key(rm->m_rdma_cookie); + rm->atomic.op_remote_addr = args->remote_addr + rds_rdma_cookie_offset(args->cookie); + + rm->atomic.op_active = 1; + + return ret; +err: + if (page) + put_page(page); + kfree(rm->atomic.op_notifier); + + return ret; +} diff --git a/net/rds/rds.h b/net/rds/rds.h index 0bb4957e0cfc..830e2bbb3332 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -97,6 +97,7 @@ struct rds_connection { unsigned int c_xmit_hdr_off; unsigned int c_xmit_data_off; unsigned int c_xmit_rdma_sent; + unsigned int c_xmit_atomic_sent; spinlock_t c_lock; /* protect msg queues */ u64 c_next_tx_seq; @@ -260,6 +261,10 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) return cookie >> 32; } +/* atomic operation types */ +#define RDS_ATOMIC_TYPE_CSWP 0 +#define RDS_ATOMIC_TYPE_FADD 1 + /* * m_sock_item and m_conn_item are on lists that are serialized under * conn->c_lock. m_sock_item has additional meaning in that once it is empty @@ -315,11 +320,27 @@ struct rds_message { struct rds_sock *m_rs; rds_rdma_cookie_t m_rdma_cookie; struct { - struct { + struct rm_atomic_op { + int op_type; + uint64_t op_swap_add; + uint64_t op_compare; + + u32 op_rkey; + u64 op_remote_addr; + unsigned int op_notify:1; + unsigned int op_recverr:1; + unsigned int op_mapped:1; + unsigned int op_active:1; + struct rds_notifier *op_notifier; + struct scatterlist *op_sg; + + struct rds_mr *op_rdma_mr; + } atomic; + struct rm_rdma_op { struct rds_rdma_op m_rdma_op; struct rds_mr *m_rdma_mr; } rdma; - struct { + struct rm_data_op { unsigned int m_nents; unsigned int m_count; struct scatterlist *m_sg; @@ -397,6 +418,7 @@ struct rds_transport { int (*xmit_cong_map)(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset); int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op); + int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, size_t size); @@ -546,6 +568,8 @@ struct rds_statistics { uint64_t s_cong_update_received; uint64_t s_cong_send_error; uint64_t s_cong_send_blocked; + uint64_t s_atomic_cswp; + uint64_t s_atomic_fadd; }; /* af_rds.c */ @@ -722,7 +746,10 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, struct cmsghdr *cmsg); void rds_rdma_free_op(struct rds_rdma_op *ro); -void rds_rdma_send_complete(struct rds_message *rm, int); +void rds_rdma_send_complete(struct rds_message *rm, int wc_status); +void rds_atomic_send_complete(struct rds_message *rm, int wc_status); +int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); extern void __rds_put_mr_final(struct rds_mr *mr); static inline void rds_mr_put(struct rds_mr *mr) diff --git a/net/rds/send.c b/net/rds/send.c index b751a8e77c41..f3f4e79274bf 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -73,6 +73,7 @@ void rds_send_reset(struct rds_connection *conn) conn->c_xmit_hdr_off = 0; conn->c_xmit_data_off = 0; conn->c_xmit_rdma_sent = 0; + conn->c_xmit_atomic_sent = 0; conn->c_map_queued = 0; @@ -171,6 +172,7 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_hdr_off = 0; conn->c_xmit_data_off = 0; conn->c_xmit_rdma_sent = 0; + conn->c_xmit_atomic_sent = 0; /* Release the reference to the previous message. */ rds_message_put(rm); @@ -262,6 +264,17 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_rm = rm; } + + if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { + ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); + if (ret) + break; + conn->c_xmit_atomic_sent = 1; + /* The transport owns the mapped memory for now. + * You can't unmap it while it's on the send queue */ + set_bit(RDS_MSG_MAPPED, &rm->m_flags); + } + /* * Try and send an rdma message. Let's see if we can * keep this simple and require that the transport either @@ -442,6 +455,41 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) } EXPORT_SYMBOL_GPL(rds_rdma_send_complete); +/* + * Just like above, except looks at atomic op + */ +void rds_atomic_send_complete(struct rds_message *rm, int status) +{ + struct rds_sock *rs = NULL; + struct rm_atomic_op *ao; + struct rds_notifier *notifier; + + spin_lock(&rm->m_rs_lock); + + ao = &rm->atomic; + if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) + && ao->op_active && ao->op_notify && ao->op_notifier) { + notifier = ao->op_notifier; + rs = rm->m_rs; + sock_hold(rds_rs_to_sk(rs)); + + notifier->n_status = status; + spin_lock(&rs->rs_lock); + list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); + spin_unlock(&rs->rs_lock); + + ao->op_notifier = NULL; + } + + spin_unlock(&rm->m_rs_lock); + + if (rs) { + rds_wake_sk_sleep(rs); + sock_put(rds_rs_to_sk(rs)); + } +} +EXPORT_SYMBOL_GPL(rds_atomic_send_complete); + /* * This is the same as rds_rdma_send_complete except we * don't do any locking - we have all the ingredients (message, @@ -788,6 +836,11 @@ static int rds_rm_size(struct msghdr *msg, int data_len) /* these are valid but do no add any size */ break; + case RDS_CMSG_ATOMIC_CSWP: + case RDS_CMSG_ATOMIC_FADD: + size += sizeof(struct scatterlist); + break; + default: return -EINVAL; } @@ -813,7 +866,7 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, continue; /* As a side effect, RDMA_DEST and RDMA_MAP will set - * rm->m_rdma_cookie and rm->m_rdma_mr. + * rm->rdma.m_rdma_cookie and rm->rdma.m_rdma_mr. */ switch (cmsg->cmsg_type) { case RDS_CMSG_RDMA_ARGS: @@ -829,6 +882,10 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, if (!ret) *allocated_mr = 1; break; + case RDS_CMSG_ATOMIC_CSWP: + case RDS_CMSG_ATOMIC_FADD: + ret = rds_cmsg_atomic(rs, rm, cmsg); + break; default: return -EINVAL; @@ -926,10 +983,18 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; if ((rm->m_rdma_cookie || rm->rdma.m_rdma_op.r_active) && - !conn->c_trans->xmit_rdma) { + !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", - &rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); + &rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); + ret = -EOPNOTSUPP; + goto out; + } + + if (rm->atomic.op_active && !conn->c_trans->xmit_atomic) { + if (printk_ratelimit()) + printk(KERN_NOTICE "atomic_op %p conn xmit_atomic %p\n", + &rm->atomic, conn->c_trans->xmit_atomic); ret = -EOPNOTSUPP; goto out; } diff --git a/net/rds/stats.c b/net/rds/stats.c index 7598eb07cfb1..c66d95d9c262 100644 --- a/net/rds/stats.c +++ b/net/rds/stats.c @@ -75,6 +75,8 @@ static const char *const rds_stat_names[] = { "cong_update_received", "cong_send_error", "cong_send_blocked", + "s_atomic_cswp", + "s_atomic_fadd", }; void rds_stats_info_copy(struct rds_info_iterator *iter, -- cgit v1.2.3 From 40589e74f7ba855f3a887c9d4abe9d100c5b039c Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 10:50:48 -0800 Subject: RDS: Base init_depth and responder_resources on hw values Instead of using a constant for initiator_depth and responder_resources, read the per-QP values when the device is enumerated, and then use these values when creating the connection. Signed-off-by: Andy Grover --- net/rds/ib.c | 3 +++ net/rds/ib.h | 2 ++ net/rds/ib_cm.c | 27 ++++++++++++++++++--------- net/rds/rdma.c | 3 +-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index f0d29656baff..72a5116c11de 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -91,6 +91,9 @@ void rds_ib_add_one(struct ib_device *device) min_t(unsigned int, dev_attr->max_fmr, fmr_pool_size) : fmr_pool_size; + rds_ibdev->max_initiator_depth = dev_attr->max_qp_init_rd_atom; + rds_ibdev->max_responder_resources = dev_attr->max_qp_rd_atom; + rds_ibdev->dev = device; rds_ibdev->pd = ib_alloc_pd(device); if (IS_ERR(rds_ibdev->pd)) diff --git a/net/rds/ib.h b/net/rds/ib.h index d2fd0aa4fde7..a303f13111c2 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -164,6 +164,8 @@ struct rds_ib_device { unsigned int max_fmrs; int max_sge; unsigned int max_wrs; + unsigned int max_initiator_depth; + unsigned int max_responder_resources; spinlock_t spinlock; /* protect the above */ }; diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index b46bc2f22ab6..3134336ca17d 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -153,18 +153,25 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, struct rdma_conn_param *conn_param, struct rds_ib_connect_private *dp, - u32 protocol_version) + u32 protocol_version, + u32 max_responder_resources, + u32 max_initiator_depth) { + struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_ib_device *rds_ibdev; + memset(conn_param, 0, sizeof(struct rdma_conn_param)); - /* XXX tune these? */ - conn_param->responder_resources = 1; - conn_param->initiator_depth = 1; + + rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); + + conn_param->responder_resources = + min_t(u32, rds_ibdev->max_responder_resources, max_responder_resources); + conn_param->initiator_depth = + min_t(u32, rds_ibdev->max_initiator_depth, max_initiator_depth); conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7); conn_param->rnr_retry_count = 7; if (dp) { - struct rds_ib_connection *ic = conn->c_transport_data; - memset(dp, 0, sizeof(*dp)); dp->dp_saddr = conn->c_laddr; dp->dp_daddr = conn->c_faddr; @@ -479,7 +486,9 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, goto out; } - rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version); + rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version, + event->param.conn.responder_resources, + event->param.conn.initiator_depth); /* rdma_accept() calls rdma_reject() internally if it fails */ err = rdma_accept(cm_id, &conn_param); @@ -516,8 +525,8 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id) goto out; } - rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION); - + rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION, + UINT_MAX, UINT_MAX); ret = rdma_connect(cm_id, &conn_param); if (ret) rds_ib_conn_error(conn, "rdma_connect failed (%d)\n", ret); diff --git a/net/rds/rdma.c b/net/rds/rdma.c index a7019df38c70..abbc2979e7e5 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -745,7 +745,6 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, rm->atomic.op_swap_add = args->fadd.add; } - rm->m_rdma_cookie = args->cookie; rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); rm->atomic.op_recverr = rs->rs_recverr; rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); @@ -779,7 +778,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, rm->atomic.op_notifier->n_status = RDS_RDMA_SUCCESS; } - rm->atomic.op_rkey = rds_rdma_cookie_key(rm->m_rdma_cookie); + rm->atomic.op_rkey = rds_rdma_cookie_key(args->cookie); rm->atomic.op_remote_addr = args->remote_addr + rds_rdma_cookie_offset(args->cookie); rm->atomic.op_active = 1; -- cgit v1.2.3 From d22faec22c2ab2364fd8fc3c8159b0b5b28b0fd1 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 10:52:28 -0800 Subject: RDS: Do not mask address when pinning pages This does not appear to be necessary. Signed-off-by: Andy Grover --- net/rds/rdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index abbc2979e7e5..1929cb8f17d7 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -238,7 +238,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, * r/o or r/w. We need to assume r/w, or we'll do a lot of RDMA to * the zero page. */ - ret = rds_pin_pages(args->vec.addr & PAGE_MASK, nr_pages, pages, 1); + ret = rds_pin_pages(args->vec.addr, nr_pages, pages, 1); if (ret < 0) goto out; @@ -595,7 +595,7 @@ static int rds_rdma_prepare(struct rds_message *rm, /* If it's a WRITE operation, we want to pin the pages for reading. * If it's a READ operation, we need to pin the pages for writing. */ - ret = rds_pin_pages(vec.addr & PAGE_MASK, nr, pages, !op->r_write); + ret = rds_pin_pages(vec.addr, nr, pages, !op->r_write); if (ret < 0) goto out; -- cgit v1.2.3 From 6200ed7799d9225f363f157ab61f1566cfd80e19 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 10:53:05 -0800 Subject: RDS: Whitespace Tidy up some whitespace issues. Signed-off-by: Andy Grover --- net/rds/rdma.c | 1 - net/rds/recv.c | 4 ++-- net/rds/send.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 1929cb8f17d7..4df545a6eab8 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -688,7 +688,6 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, */ r_key = rds_rdma_cookie_key(rm->m_rdma_cookie); - spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); if (!mr) diff --git a/net/rds/recv.c b/net/rds/recv.c index 5188763b609b..68800f02aa30 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -333,10 +333,10 @@ int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) if (msghdr) { cmsg.user_token = notifier->n_user_token; - cmsg.status = notifier->n_status; + cmsg.status = notifier->n_status; err = put_cmsg(msghdr, SOL_RDS, RDS_CMSG_RDMA_STATUS, - sizeof(cmsg), &cmsg); + sizeof(cmsg), &cmsg); if (err) break; } diff --git a/net/rds/send.c b/net/rds/send.c index f3f4e79274bf..5bc35d2f40ea 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -150,7 +150,7 @@ int rds_send_xmit(struct rds_connection *conn) */ if (conn->c_map_bytes) { ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong, - conn->c_map_offset); + conn->c_map_offset); if (ret <= 0) break; -- cgit v1.2.3 From 809fa148a29467954280fe8b7f97c92403f6293c Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:41:46 -0800 Subject: RDS: inc_purge() transport function unused - remove it Signed-off-by: Andy Grover --- net/rds/ib.c | 1 - net/rds/ib.h | 1 - net/rds/ib_recv.c | 2 +- net/rds/iw.c | 1 - net/rds/iw.h | 1 - net/rds/iw_recv.c | 2 +- net/rds/loop.c | 1 - net/rds/message.c | 6 ------ net/rds/rds.h | 2 -- net/rds/tcp.c | 1 - net/rds/tcp.h | 1 - net/rds/tcp_recv.c | 2 +- 12 files changed, 3 insertions(+), 18 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 72a5116c11de..932dacbdbea1 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -274,7 +274,6 @@ struct rds_transport rds_ib_transport = { .conn_connect = rds_ib_conn_connect, .conn_shutdown = rds_ib_conn_shutdown, .inc_copy_to_user = rds_ib_inc_copy_to_user, - .inc_purge = rds_ib_inc_purge, .inc_free = rds_ib_inc_free, .cm_initiate_connect = rds_ib_cm_initiate_connect, .cm_handle_connect = rds_ib_cm_handle_connect, diff --git a/net/rds/ib.h b/net/rds/ib.h index a303f13111c2..426035ac54a1 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -301,7 +301,6 @@ void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, gfp_t page_gfp, int prefill); -void rds_ib_inc_purge(struct rds_incoming *inc); void rds_ib_inc_free(struct rds_incoming *inc); int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index d0ee9c114c6c..e294d00abc80 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -273,7 +273,7 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, return ret; } -void rds_ib_inc_purge(struct rds_incoming *inc) +static void rds_ib_inc_purge(struct rds_incoming *inc) { struct rds_ib_incoming *ibinc; struct rds_page_frag *frag; diff --git a/net/rds/iw.c b/net/rds/iw.c index c8f3d3525cb9..e766aecd46c9 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -272,7 +272,6 @@ struct rds_transport rds_iw_transport = { .conn_connect = rds_iw_conn_connect, .conn_shutdown = rds_iw_conn_shutdown, .inc_copy_to_user = rds_iw_inc_copy_to_user, - .inc_purge = rds_iw_inc_purge, .inc_free = rds_iw_inc_free, .cm_initiate_connect = rds_iw_cm_initiate_connect, .cm_handle_connect = rds_iw_cm_handle_connect, diff --git a/net/rds/iw.h b/net/rds/iw.h index eef2f0c28476..6f08300851ad 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -326,7 +326,6 @@ void rds_iw_recv_exit(void); int rds_iw_recv(struct rds_connection *conn); int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, gfp_t page_gfp, int prefill); -void rds_iw_inc_purge(struct rds_incoming *inc); void rds_iw_inc_free(struct rds_incoming *inc); int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index 48bcf4f2bf3c..7e929f701a0c 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -273,7 +273,7 @@ int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, return ret; } -void rds_iw_inc_purge(struct rds_incoming *inc) +static void rds_iw_inc_purge(struct rds_incoming *inc) { struct rds_iw_incoming *iwinc; struct rds_page_frag *frag; diff --git a/net/rds/loop.c b/net/rds/loop.c index a74b469a844a..9364de6dcd8b 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -176,7 +176,6 @@ struct rds_transport rds_loop_transport = { .conn_connect = rds_loop_conn_connect, .conn_shutdown = rds_loop_conn_shutdown, .inc_copy_to_user = rds_message_inc_copy_to_user, - .inc_purge = rds_message_inc_purge, .inc_free = rds_message_inc_free, .t_name = "loopback", }; diff --git a/net/rds/message.c b/net/rds/message.c index 7d678e217820..f681690b2bdc 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -75,12 +75,6 @@ static void rds_message_purge(struct rds_message *rm) rds_mr_put(rm->rdma.m_rdma_mr); } -void rds_message_inc_purge(struct rds_incoming *inc) -{ - struct rds_message *rm = container_of(inc, struct rds_message, m_inc); - rds_message_purge(rm); -} - void rds_message_put(struct rds_message *rm) { rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount)); diff --git a/net/rds/rds.h b/net/rds/rds.h index 830e2bbb3332..0c610a102c20 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -422,7 +422,6 @@ struct rds_transport { int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, size_t size); - void (*inc_purge)(struct rds_incoming *inc); void (*inc_free)(struct rds_incoming *inc); int (*cm_handle_connect)(struct rdma_cm_id *cm_id, @@ -668,7 +667,6 @@ int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *vers int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, size_t size); -void rds_message_inc_purge(struct rds_incoming *inc); void rds_message_inc_free(struct rds_incoming *inc); void rds_message_addref(struct rds_message *rm); void rds_message_put(struct rds_message *rm); diff --git a/net/rds/tcp.c b/net/rds/tcp.c index aebe10314fdb..831881640e56 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -266,7 +266,6 @@ struct rds_transport rds_tcp_transport = { .conn_connect = rds_tcp_conn_connect, .conn_shutdown = rds_tcp_conn_shutdown, .inc_copy_to_user = rds_tcp_inc_copy_to_user, - .inc_purge = rds_tcp_inc_purge, .inc_free = rds_tcp_inc_free, .stats_info_copy = rds_tcp_stats_info_copy, .exit = rds_tcp_exit, diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 844fa6b9cf5a..c639872bf701 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -70,7 +70,6 @@ int __init rds_tcp_recv_init(void); void rds_tcp_recv_exit(void); void rds_tcp_data_ready(struct sock *sk, int bytes); int rds_tcp_recv(struct rds_connection *conn); -void rds_tcp_inc_purge(struct rds_incoming *inc); void rds_tcp_inc_free(struct rds_incoming *inc); int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index ea7382908aa5..49c966010788 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -39,7 +39,7 @@ static struct kmem_cache *rds_tcp_incoming_slab; -void rds_tcp_inc_purge(struct rds_incoming *inc) +static void rds_tcp_inc_purge(struct rds_incoming *inc) { struct rds_tcp_incoming *tinc; tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); -- cgit v1.2.3 From 9c030391e8741695ff6114703e4edccccb634479 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 12 Jan 2010 14:43:06 -0800 Subject: RDS/IB: eliminate duplicate code both atomics and rdmas need to convert ib-specific completion codes into RDS status codes. Rename rds_ib_rdma_send_complete to rds_ib_send_complete, and have it take a pointer to the function to call with the new error code. Signed-off-by: Andy Grover --- net/rds/ib_send.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index b2bd164434ad..d2516d3f87e2 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -38,8 +38,13 @@ #include "rds.h" #include "ib.h" -static void rds_ib_send_rdma_complete(struct rds_message *rm, - int wc_status) +/* + * Convert IB-specific error message to RDS error message and call core + * completion handler. + */ +static void rds_ib_send_complete(struct rds_message *rm, + int wc_status, + void (*complete)(struct rds_message *rm, int status)) { int notify_status; @@ -59,20 +64,7 @@ static void rds_ib_send_rdma_complete(struct rds_message *rm, notify_status = RDS_RDMA_OTHER_ERROR; break; } - rds_rdma_send_complete(rm, notify_status); -} - -static void rds_ib_send_atomic_complete(struct rds_message *rm, - int wc_status) -{ - int notify_status; - - if (wc_status != IB_WC_SUCCESS) - notify_status = RDS_RDMA_OTHER_ERROR; - else - notify_status = RDS_RDMA_SUCCESS; - - rds_atomic_send_complete(rm, notify_status); + complete(rm, notify_status); } static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, @@ -117,7 +109,7 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, * operation itself unmapped the RDMA buffers, which takes care * of synching. */ - rds_ib_send_rdma_complete(rm, wc_status); + rds_ib_send_complete(rm, wc_status, rds_rdma_send_complete); if (rm->rdma.m_rdma_op.r_write) rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); @@ -135,7 +127,7 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, op->op_mapped = 0; } - rds_ib_send_atomic_complete(rm, wc_status); + rds_ib_send_complete(rm, wc_status, rds_atomic_send_complete); if (rm->atomic.op_type == RDS_ATOMIC_TYPE_CSWP) rds_stats_inc(s_atomic_cswp); @@ -270,7 +262,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rm = rds_send_get_message(conn, send->s_op); if (rm) { rds_ib_send_unmap_rm(ic, send, wc.status); - rds_ib_send_rdma_complete(rm, wc.status); + rds_ib_send_complete(rm, wc.status, rds_rdma_send_complete); rds_message_put(rm); } } -- cgit v1.2.3 From f147dd9ecabf23fd63d2562ffe64252a0453ecde Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 13 Jan 2010 15:50:09 -0800 Subject: RDS/IB: Disallow connections less than RDS 3.1 RDS 3.0 connections (in OFED 1.3 and earlier) put the header at the end. 3.1 connections put it at the head. The code has significant added complexity in order to handle both configurations. In OFED 1.6 we can drop this and simplify the code by only supporting "header-first" configuration. This patch checks the protocol version, and if prior to 3.1, does not complete the connection. Signed-off-by: Andy Grover --- net/rds/ib_cm.c | 20 +++++++++++++++----- net/rds/ib_recv.c | 43 +------------------------------------------ 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 3134336ca17d..8b0c743c0900 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -111,11 +111,21 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even } } - printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n", - &conn->c_faddr, - RDS_PROTOCOL_MAJOR(conn->c_version), - RDS_PROTOCOL_MINOR(conn->c_version), - ic->i_flowctl ? ", flow control" : ""); + if (conn->c_version < RDS_PROTOCOL(3,1)) { + printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u failed," + " no longer supported\n", + &conn->c_faddr, + RDS_PROTOCOL_MAJOR(conn->c_version), + RDS_PROTOCOL_MINOR(conn->c_version)); + rds_conn_destroy(conn); + return; + } else { + printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n", + &conn->c_faddr, + RDS_PROTOCOL_MAJOR(conn->c_version), + RDS_PROTOCOL_MINOR(conn->c_version), + ic->i_flowctl ? ", flow control" : ""); + } /* * Init rings and fill recv. this needs to wait until protocol negotiation diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index e294d00abc80..a68a3a721c6c 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -557,47 +557,6 @@ u64 rds_ib_piggyb_ack(struct rds_ib_connection *ic) return rds_ib_get_ack(ic); } -static struct rds_header *rds_ib_get_header(struct rds_connection *conn, - struct rds_ib_recv_work *recv, - u32 data_len) -{ - struct rds_ib_connection *ic = conn->c_transport_data; - void *hdr_buff = &ic->i_recv_hdrs[recv - ic->i_recvs]; - void *addr; - u32 misplaced_hdr_bytes; - - /* - * Support header at the front (RDS 3.1+) as well as header-at-end. - * - * Cases: - * 1) header all in header buff (great!) - * 2) header all in data page (copy all to header buff) - * 3) header split across hdr buf + data page - * (move bit in hdr buff to end before copying other bit from data page) - */ - if (conn->c_version > RDS_PROTOCOL_3_0 || data_len == RDS_FRAG_SIZE) - return hdr_buff; - - if (data_len <= (RDS_FRAG_SIZE - sizeof(struct rds_header))) { - addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0); - memcpy(hdr_buff, - addr + recv->r_frag->f_offset + data_len, - sizeof(struct rds_header)); - kunmap_atomic(addr, KM_SOFTIRQ0); - return hdr_buff; - } - - misplaced_hdr_bytes = (sizeof(struct rds_header) - (RDS_FRAG_SIZE - data_len)); - - memmove(hdr_buff + misplaced_hdr_bytes, hdr_buff, misplaced_hdr_bytes); - - addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0); - memcpy(hdr_buff, addr + recv->r_frag->f_offset + data_len, - sizeof(struct rds_header) - misplaced_hdr_bytes); - kunmap_atomic(addr, KM_SOFTIRQ0); - return hdr_buff; -} - /* * It's kind of lame that we're copying from the posted receive pages into * long-lived bitmaps. We could have posted the bitmaps and rdma written into @@ -710,7 +669,7 @@ static void rds_ib_process_recv(struct rds_connection *conn, } data_len -= sizeof(struct rds_header); - ihdr = rds_ib_get_header(conn, recv, data_len); + ihdr = &ic->i_recv_hdrs[recv - ic->i_recvs]; /* Validate the checksum. */ if (!rds_message_verify_checksum(ihdr)) { -- cgit v1.2.3 From 6f3d05db0da0b874afd2dd229bed715133532f8d Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 13 Jan 2010 16:29:37 -0800 Subject: RDS/IB: Remove dead code Signed-off-by: Andy Grover --- net/rds/ib_send.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index d2516d3f87e2..e86908497fcf 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -542,12 +542,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* map the message the first time we see it */ if (!ic->i_rm) { - /* - printk(KERN_NOTICE "rds_ib_xmit prep msg dport=%u flags=0x%x len=%d\n", - be16_to_cpu(rm->m_inc.i_hdr.h_dport), - rm->m_inc.i_hdr.h_flags, - be32_to_cpu(rm->m_inc.i_hdr.h_len)); - */ if (rm->data.m_nents) { rm->data.m_count = ib_dma_map_sg(dev, rm->data.m_sg, @@ -684,14 +678,6 @@ add_header: * have been set up to point to the right header buffer. */ memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header)); - if (0) { - struct rds_header *hdr = &ic->i_send_hdrs[pos]; - - printk(KERN_NOTICE "send WR dport=%u flags=0x%x len=%d\n", - be16_to_cpu(hdr->h_dport), - hdr->h_flags, - be32_to_cpu(hdr->h_len)); - } if (adv_credits) { struct rds_header *hdr = &ic->i_send_hdrs[pos]; -- cgit v1.2.3 From 919ced4ce7d6ac62dd5be62d8993fe22a527d53a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 13 Jan 2010 16:32:24 -0800 Subject: RDS/IB: Remove ib_[header/data]_sge() functions These functions were to cope with differently ordered sg entries depending on RDS 3.0 or 3.1+. Now that we've dropped 3.0 compatibility we no longer need them. Also, modify usage sites for these to refer to sge[0] or [1] directly. Reorder code to initialize header sgs first. Signed-off-by: Andy Grover --- net/rds/ib.h | 24 ------------------------ net/rds/ib_recv.c | 22 +++++++++++----------- net/rds/ib_send.c | 32 ++++++++++++-------------------- 3 files changed, 23 insertions(+), 55 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 426035ac54a1..dbf8d6e31493 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -356,28 +356,4 @@ extern unsigned long rds_ib_sysctl_max_recv_allocation; extern unsigned int rds_ib_sysctl_flow_control; extern ctl_table rds_ib_sysctl_table[]; -/* - * Helper functions for getting/setting the header and data SGEs in - * RDS packets (not RDMA) - * - * From version 3.1 onwards, header is in front of data in the sge. - */ -static inline struct ib_sge * -rds_ib_header_sge(struct rds_ib_connection *ic, struct ib_sge *sge) -{ - if (ic->conn->c_version > RDS_PROTOCOL_3_0) - return &sge[0]; - else - return &sge[1]; -} - -static inline struct ib_sge * -rds_ib_data_sge(struct rds_ib_connection *ic, struct ib_sge *sge) -{ - if (ic->conn->c_version > RDS_PROTOCOL_3_0) - return &sge[1]; - else - return &sge[0]; -} - #endif diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index a68a3a721c6c..e9fe08a86c40 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -95,15 +95,15 @@ void rds_ib_recv_init_ring(struct rds_ib_connection *ic) recv->r_wr.sg_list = recv->r_sge; recv->r_wr.num_sge = RDS_IB_RECV_SGE; - sge = rds_ib_data_sge(ic, recv->r_sge); - sge->addr = 0; - sge->length = RDS_FRAG_SIZE; - sge->lkey = ic->i_mr->lkey; - - sge = rds_ib_header_sge(ic, recv->r_sge); + sge = &recv->r_sge[0]; sge->addr = ic->i_recv_hdrs_dma + (i * sizeof(struct rds_header)); sge->length = sizeof(struct rds_header); sge->lkey = ic->i_mr->lkey; + + sge = &recv->r_sge[1]; + sge->addr = 0; + sge->length = RDS_FRAG_SIZE; + sge->lkey = ic->i_mr->lkey; } } @@ -190,14 +190,14 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, recv->r_frag->f_offset = ic->i_frag.f_offset; recv->r_frag->f_mapped = dma_addr; - sge = rds_ib_data_sge(ic, recv->r_sge); - sge->addr = dma_addr; - sge->length = RDS_FRAG_SIZE; - - sge = rds_ib_header_sge(ic, recv->r_sge); + sge = &recv->r_sge[0]; sge->addr = ic->i_recv_hdrs_dma + (recv - ic->i_recvs) * sizeof(struct rds_header); sge->length = sizeof(struct rds_header); + sge = &recv->r_sge[1]; + sge->addr = dma_addr; + sge->length = RDS_FRAG_SIZE; + get_page(recv->r_frag->f_page); if (ic->i_frag.f_offset < RDS_PAGE_LAST_OFF) { diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e86908497fcf..46026d9091f1 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -156,18 +156,14 @@ void rds_ib_send_init_ring(struct rds_ib_connection *ic) send->s_wr.wr_id = i; send->s_wr.sg_list = send->s_sge; - send->s_wr.num_sge = 1; - send->s_wr.opcode = IB_WR_SEND; - send->s_wr.send_flags = 0; send->s_wr.ex.imm_data = 0; - sge = rds_ib_data_sge(ic, send->s_sge); - sge->lkey = ic->i_mr->lkey; - - sge = rds_ib_header_sge(ic, send->s_sge); + sge = &send->s_sge[0]; sge->addr = ic->i_send_hdrs_dma + (i * sizeof(struct rds_header)); sge->length = sizeof(struct rds_header); sge->lkey = ic->i_mr->lkey; + + send->s_sge[1].lkey = ic->i_mr->lkey; } } @@ -441,28 +437,24 @@ rds_ib_xmit_populate_wr(struct rds_ib_connection *ic, send->s_wr.send_flags = send_flags; send->s_wr.opcode = IB_WR_SEND; - send->s_wr.num_sge = 2; + send->s_wr.num_sge = 1; send->s_wr.next = NULL; send->s_queued = jiffies; send->s_op = NULL; + sge = &send->s_sge[0]; + sge->addr = ic->i_send_hdrs_dma + (pos * sizeof(struct rds_header)); + sge->length = sizeof(struct rds_header); + sge->lkey = ic->i_mr->lkey; + if (length != 0) { - sge = rds_ib_data_sge(ic, send->s_sge); + send->s_wr.num_sge = 2; + + sge = &send->s_sge[1]; sge->addr = buffer; sge->length = length; sge->lkey = ic->i_mr->lkey; - - sge = rds_ib_header_sge(ic, send->s_sge); - } else { - /* We're sending a packet with no payload. There is only - * one SGE */ - send->s_wr.num_sge = 1; - sge = &send->s_sge[0]; } - - sge->addr = ic->i_send_hdrs_dma + (pos * sizeof(struct rds_header)); - sge->length = sizeof(struct rds_header); - sge->lkey = ic->i_mr->lkey; } /* -- cgit v1.2.3 From da5a06cef5724737af4315715632f0a07dd5e116 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 14 Jan 2010 12:18:11 -0800 Subject: RDS: rewrite rds_ib_xmit Now that the header always goes first, it is possible to simplify rds_ib_xmit. Instead of having a path to handle 0-byte dgrams and another path to handle >0, these can both be handled in one path. This lets us eliminate xmit_populate_wr(). Rename sent to bytes_sent, to differentiate better from other variable named "send". Signed-off-by: Andy Grover --- net/rds/ib_send.c | 123 ++++++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 78 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 46026d9091f1..06c1d7e032d2 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -425,38 +425,6 @@ void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted) set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); } -static inline void -rds_ib_xmit_populate_wr(struct rds_ib_connection *ic, - struct rds_ib_send_work *send, unsigned int pos, - unsigned long buffer, unsigned int length, - int send_flags) -{ - struct ib_sge *sge; - - WARN_ON(pos != send - ic->i_sends); - - send->s_wr.send_flags = send_flags; - send->s_wr.opcode = IB_WR_SEND; - send->s_wr.num_sge = 1; - send->s_wr.next = NULL; - send->s_queued = jiffies; - send->s_op = NULL; - - sge = &send->s_sge[0]; - sge->addr = ic->i_send_hdrs_dma + (pos * sizeof(struct rds_header)); - sge->length = sizeof(struct rds_header); - sge->lkey = ic->i_mr->lkey; - - if (length != 0) { - send->s_wr.num_sge = 2; - - sge = &send->s_sge[1]; - sge->addr = buffer; - sge->length = length; - sge->lkey = ic->i_mr->lkey; - } -} - /* * This can be called multiple times for a given message. The first time * we see a message we map its scatterlist into the IB device so that @@ -483,11 +451,11 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, u32 pos; u32 i; u32 work_alloc; - u32 credit_alloc; + u32 credit_alloc = 0; u32 posted; u32 adv_credits = 0; int send_flags = 0; - int sent; + int bytes_sent = 0; int ret; int flow_controlled = 0; @@ -515,7 +483,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, goto out; } - credit_alloc = work_alloc; if (ic->i_flowctl) { credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT); adv_credits += posted; @@ -591,13 +558,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, BUG_ON(adv_credits > 255); } - send = &ic->i_sends[pos]; - first = send; - prev = NULL; - scat = &rm->data.m_sg[sg]; - sent = 0; - i = 0; - /* Sometimes you want to put a fence between an RDMA * READ and the following SEND. * We could either do this all the time @@ -607,31 +567,45 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, if (rm->rdma.m_rdma_op.r_active && rm->rdma.m_rdma_op.r_fence) send_flags = IB_SEND_FENCE; - /* - * We could be copying the header into the unused tail of the page. - * That would need to be changed in the future when those pages might - * be mapped userspace pages or page cache pages. So instead we always - * use a second sge and our long-lived ring of mapped headers. We send - * the header after the data so that the data payload can be aligned on - * the receiver. - */ + /* Each frag gets a header. Msgs may be 0 bytes */ + send = &ic->i_sends[pos]; + first = send; + prev = NULL; + scat = &rm->data.m_sg[sg]; + i = 0; + do { + unsigned int len = 0; - /* handle a 0-len message */ - if (be32_to_cpu(rm->m_inc.i_hdr.h_len) == 0) { - rds_ib_xmit_populate_wr(ic, send, pos, 0, 0, send_flags); - goto add_header; - } + /* Set up the header */ + send->s_wr.send_flags = send_flags; + send->s_wr.opcode = IB_WR_SEND; + send->s_wr.num_sge = 1; + send->s_wr.next = NULL; + send->s_queued = jiffies; + send->s_op = NULL; - /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->data.m_sg[rm->data.m_count]; i++) { - unsigned int len; + send->s_sge[0].addr = ic->i_send_hdrs_dma + + (pos * sizeof(struct rds_header)); + send->s_sge[0].length = sizeof(struct rds_header); - send = &ic->i_sends[pos]; + memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header)); + + /* Set up the data, if present */ + if (i < work_alloc + && scat != &rm->data.m_sg[rm->data.m_count]) { + len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off); + send->s_wr.num_sge = 2; - len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off); - rds_ib_xmit_populate_wr(ic, send, pos, - ib_sg_dma_address(dev, scat) + off, len, - send_flags); + send->s_sge[1].addr = ib_sg_dma_address(dev, scat) + off; + send->s_sge[1].length = len; + + bytes_sent += len; + off += len; + if (off == ib_sg_dma_len(dev, scat)) { + scat++; + off = 0; + } + } /* * We want to delay signaling completions just enough to get @@ -658,18 +632,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, rdsdebug("send %p wr %p num_sge %u next %p\n", send, &send->s_wr, send->s_wr.num_sge, send->s_wr.next); - sent += len; - off += len; - if (off == ib_sg_dma_len(dev, scat)) { - scat++; - off = 0; - } - -add_header: - /* Tack on the header after the data. The header SGE should already - * have been set up to point to the right header buffer. */ - memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header)); - if (adv_credits) { struct rds_header *hdr = &ic->i_send_hdrs[pos]; @@ -685,12 +647,16 @@ add_header: prev = send; pos = (pos + 1) % ic->i_send_ring.w_nr; - } + send = &ic->i_sends[pos]; + i++; + + } while (i < work_alloc + && scat != &rm->data.m_sg[rm->data.m_count]); /* Account the RDS header in the number of bytes we sent, but just once. * The caller has no concept of fragmentation. */ if (hdr_off == 0) - sent += sizeof(struct rds_header); + bytes_sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ if (scat == &rm->data.m_sg[rm->data.m_count]) { @@ -699,6 +665,7 @@ add_header: ic->i_rm = NULL; } + /* Put back wrs & credits we didn't use */ if (i < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i); work_alloc = i; @@ -725,7 +692,7 @@ add_header: goto out; } - ret = sent; + ret = bytes_sent; out: BUG_ON(adv_credits); return ret; -- cgit v1.2.3 From 1d34f175712b59ad292ecbbaa8fc05402a1fd8ed Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 14 Jan 2010 15:08:33 -0800 Subject: RDS: Remove unsignaled_bytes sysctl Removed unsignaled_bytes sysctl and code to signal based on it. I believe unsignaled_wrs is more than sufficient for our purposes. Signed-off-by: Andy Grover --- net/rds/ib.h | 1 - net/rds/ib_send.c | 7 ------- net/rds/ib_sysctl.c | 13 ------------- 3 files changed, 21 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index dbf8d6e31493..148818174a04 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -138,7 +138,6 @@ struct rds_ib_connection { /* Batched completions */ unsigned int i_unsignaled_wrs; - long i_unsignaled_bytes; }; /* This assumes that atomic_t is at least 32 bits */ diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 06c1d7e032d2..48724b71f26c 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -518,7 +518,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes; rds_message_addref(rm); ic->i_rm = rm; @@ -617,12 +616,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; } - ic->i_unsignaled_bytes -= len; - if (ic->i_unsignaled_bytes <= 0) { - ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes; - send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; - } - /* * Always signal the last one if we're stopping due to flow control. */ diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c index c070524c4d95..b556c5c2a902 100644 --- a/net/rds/ib_sysctl.c +++ b/net/rds/ib_sysctl.c @@ -49,10 +49,6 @@ unsigned long rds_ib_sysctl_max_unsig_wrs = 16; static unsigned long rds_ib_sysctl_max_unsig_wr_min = 1; static unsigned long rds_ib_sysctl_max_unsig_wr_max = 64; -unsigned long rds_ib_sysctl_max_unsig_bytes = (16 << 20); -static unsigned long rds_ib_sysctl_max_unsig_bytes_min = 1; -static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL; - /* * This sysctl does nothing. * @@ -93,15 +89,6 @@ ctl_table rds_ib_sysctl_table[] = { .extra1 = &rds_ib_sysctl_max_unsig_wr_min, .extra2 = &rds_ib_sysctl_max_unsig_wr_max, }, - { - .procname = "max_unsignaled_bytes", - .data = &rds_ib_sysctl_max_unsig_bytes, - .maxlen = sizeof(unsigned long), - .mode = 0644, - .proc_handler = proc_doulongvec_minmax, - .extra1 = &rds_ib_sysctl_max_unsig_bytes_min, - .extra2 = &rds_ib_sysctl_max_unsig_bytes_max, - }, { .procname = "max_recv_allocation", .data = &rds_ib_sysctl_max_recv_allocation, -- cgit v1.2.3 From c8de3f1005e8359ea07083e37f3f993646e1adba Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 15 Jan 2010 15:55:26 -0800 Subject: RDS/IB: Make all flow control code conditional on i_flowctl Maybe things worked fine with the flow control code running even in the non-flow-control case, but making it explicitly conditional helps the non-fc case be easier to read. Signed-off-by: Andy Grover --- net/rds/ib_send.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 48724b71f26c..d839b403d46b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -489,7 +489,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, if (credit_alloc < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); work_alloc = credit_alloc; - flow_controlled++; + flow_controlled = 1; } if (work_alloc == 0) { set_bit(RDS_LL_SEND_FULL, &conn->c_flags); @@ -552,9 +552,11 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* * Update adv_credits since we reset the ACK_REQUIRED bit. */ - rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); - adv_credits += posted; - BUG_ON(adv_credits > 255); + if (ic->i_flowctl) { + rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); + adv_credits += posted; + BUG_ON(adv_credits > 255); + } } /* Sometimes you want to put a fence between an RDMA @@ -619,13 +621,13 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* * Always signal the last one if we're stopping due to flow control. */ - if (flow_controlled && i == (work_alloc-1)) + if (ic->i_flowctl && flow_controlled && i == (work_alloc-1)) send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; rdsdebug("send %p wr %p num_sge %u next %p\n", send, &send->s_wr, send->s_wr.num_sge, send->s_wr.next); - if (adv_credits) { + if (ic->i_flowctl && adv_credits) { struct rds_header *hdr = &ic->i_send_hdrs[pos]; /* add credit and redo the header checksum */ -- cgit v1.2.3 From d37c9359056f4f07b37e59810f0ece1031e280b2 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 19 Jan 2010 18:14:56 -0800 Subject: RDS: Move loop-only function to loop.c Also, try to better-document the locking around the rm and its m_inc in loop.c. Signed-off-by: Andy Grover --- net/rds/loop.c | 15 +++++++++++++-- net/rds/message.c | 6 ------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/net/rds/loop.c b/net/rds/loop.c index 9364de6dcd8b..4a3dd49315b4 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -64,7 +64,8 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, BUG_ON(hdr_off || sg || off); rds_inc_init(&rm->m_inc, conn, conn->c_laddr); - rds_message_addref(rm); /* for the inc */ + /* For the embedded inc. Matching put is in loop_inc_free() */ + rds_message_addref(rm); rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc, GFP_KERNEL, KM_USER0); @@ -77,6 +78,16 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len); } +/* + * See rds_loop_xmit(). Since our inc is embedded in the rm, we + * make sure the rm lives at least until the inc is done. + */ +static void rds_loop_inc_free(struct rds_incoming *inc) +{ + struct rds_message *rm = container_of(inc, struct rds_message, m_inc); + rds_message_put(rm); +} + static int rds_loop_xmit_cong_map(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset) @@ -176,6 +187,6 @@ struct rds_transport rds_loop_transport = { .conn_connect = rds_loop_conn_connect, .conn_shutdown = rds_loop_conn_shutdown, .inc_copy_to_user = rds_message_inc_copy_to_user, - .inc_free = rds_message_inc_free, + .inc_free = rds_loop_inc_free, .t_name = "loopback", }; diff --git a/net/rds/message.c b/net/rds/message.c index f681690b2bdc..3ea05c864cd4 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -89,12 +89,6 @@ void rds_message_put(struct rds_message *rm) } EXPORT_SYMBOL_GPL(rds_message_put); -void rds_message_inc_free(struct rds_incoming *inc) -{ - struct rds_message *rm = container_of(inc, struct rds_message, m_inc); - rds_message_put(rm); -} - void rds_message_populate_header(struct rds_header *hdr, __be16 sport, __be16 dport, u64 seq) { -- cgit v1.2.3 From 241eef3e2f51fe4ad50abacd7f79c4e2d468197e Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 19 Jan 2010 21:25:26 -0800 Subject: RDS: Implement silent atomics Signed-off-by: Andy Grover --- net/rds/ib.h | 2 +- net/rds/ib_send.c | 62 ++++++++++++++++++++++++++++--------------------------- net/rds/message.c | 2 ++ net/rds/rds.h | 3 ++- net/rds/send.c | 11 +++++++--- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 148818174a04..96769b86a536 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -336,7 +336,7 @@ void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, u32 *adv_credits, int need_posted, int max_posted); -int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op); +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index d839b403d46b..e6745d827c3a 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -225,15 +225,12 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) /* In the error case, wc.opcode sometimes contains garbage */ switch (send->s_wr.opcode) { case IB_WR_SEND: - if (send->s_rm) - rds_ib_send_unmap_rm(ic, send, wc.status); - break; case IB_WR_RDMA_WRITE: case IB_WR_RDMA_READ: case IB_WR_ATOMIC_FETCH_AND_ADD: case IB_WR_ATOMIC_CMP_AND_SWP: - /* Nothing to be done - the SG list will be unmapped - * when the SEND completes. */ + if (send->s_rm) + rds_ib_send_unmap_rm(ic, send, wc.status); break; default: if (printk_ratelimit()) @@ -425,6 +422,21 @@ void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted) set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); } +static inline void rds_ib_set_wr_signal_state(struct rds_ib_connection *ic, + struct rds_ib_send_work *send, + bool notify) +{ + /* + * We want to delay signaling completions just enough to get + * the batching benefits but not so much that we create dead time + * on the wire. + */ + if (ic->i_unsignaled_wrs-- == 0 || notify) { + ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; + send->s_wr.send_flags |= IB_SEND_SIGNALED; + } +} + /* * This can be called multiple times for a given message. The first time * we see a message we map its scatterlist into the IB device so that @@ -517,7 +529,6 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, rm->data.m_count = 0; } - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; rds_message_addref(rm); ic->i_rm = rm; @@ -608,15 +619,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } } - /* - * We want to delay signaling completions just enough to get - * the batching benefits but not so much that we create dead time - * on the wire. - */ - if (ic->i_unsignaled_wrs-- == 0) { - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; - } + rds_ib_set_wr_signal_state(ic, send, 0); /* * Always signal the last one if we're stopping due to flow control. @@ -656,7 +659,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* if we finished the message then send completion owns it */ if (scat == &rm->data.m_sg[rm->data.m_count]) { prev->s_rm = ic->i_rm; - prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; + prev->s_wr.send_flags |= IB_SEND_SOLICITED; ic->i_rm = NULL; } @@ -698,9 +701,10 @@ out: * A simplified version of the rdma case, we always map 1 SG, and * only 8 bytes, for the return value from the atomic operation. */ -int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm) { struct rds_ib_connection *ic = conn->c_transport_data; + struct rm_atomic_op *op = &rm->atomic; struct rds_ib_send_work *send = NULL; struct ib_send_wr *failed_wr; struct rds_ib_device *rds_ibdev; @@ -731,12 +735,20 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) send->s_wr.wr.atomic.compare_add = op->op_swap_add; send->s_wr.wr.atomic.swap = 0; } - send->s_wr.send_flags = IB_SEND_SIGNALED; + rds_ib_set_wr_signal_state(ic, send, op->op_notify); send->s_wr.num_sge = 1; send->s_wr.next = NULL; send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; send->s_wr.wr.atomic.rkey = op->op_rkey; + /* + * If there is no data or rdma ops in the message, then + * we must fill in s_rm ourselves, so we properly clean up + * on completion. + */ + if (!rm->rdma.m_rdma_op.r_active && !rm->data.op_active) + send->s_rm = rm; + /* map 8 byte retval buffer to the device */ ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE); rdsdebug("ic %p mapping atomic op %p. mapped %d pg\n", ic, op, ret); @@ -836,14 +848,8 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; - /* - * We want to delay signaling completions just enough to get - * the batching benefits but not so much that we create dead time on the wire. - */ - if (ic->i_unsignaled_wrs-- == 0) { - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - send->s_wr.send_flags = IB_SEND_SIGNALED; - } + + rds_ib_set_wr_signal_state(ic, send, op->r_notify); send->s_wr.opcode = op->r_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; send->s_wr.wr.rdma.remote_addr = remote_addr; @@ -884,10 +890,6 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) send = ic->i_sends; } - /* if we finished the message then send completion owns it */ - if (scat == &op->r_sg[op->r_count]) - prev->s_wr.send_flags = IB_SEND_SIGNALED; - if (i < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i); work_alloc = i; diff --git a/net/rds/message.c b/net/rds/message.c index 3ea05c864cd4..a27e493a63a2 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -325,6 +325,8 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, sg++; } + rm->data.op_active = 1; + out: return ret; } diff --git a/net/rds/rds.h b/net/rds/rds.h index 0c610a102c20..bf2349da4db7 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -341,6 +341,7 @@ struct rds_message { struct rds_mr *m_rdma_mr; } rdma; struct rm_data_op { + unsigned int op_active:1; unsigned int m_nents; unsigned int m_count; struct scatterlist *m_sg; @@ -418,7 +419,7 @@ struct rds_transport { int (*xmit_cong_map)(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset); int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op); - int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); + int (*xmit_atomic)(struct rds_connection *conn, struct rds_message *rm); int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/send.c b/net/rds/send.c index 5bc35d2f40ea..42fb934293be 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -266,7 +266,7 @@ int rds_send_xmit(struct rds_connection *conn) if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { - ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); + ret = conn->c_trans->xmit_atomic(conn, rm); if (ret) break; conn->c_xmit_atomic_sent = 1; @@ -285,13 +285,18 @@ int rds_send_xmit(struct rds_connection *conn) if (ret) break; conn->c_xmit_rdma_sent = 1; + + /* rdmas need data sent, even if just the header */ + rm->data.op_active = 1; + /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); } - if (conn->c_xmit_hdr_off < sizeof(struct rds_header) || - conn->c_xmit_sg < rm->data.m_nents) { + if (rm->data.op_active + && (conn->c_xmit_hdr_off < sizeof(struct rds_header) || + conn->c_xmit_sg < rm->data.m_nents)) { ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, -- cgit v1.2.3 From 4324879df06ba4db01a0b455af2d003f117e6aa3 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 27 Jan 2010 16:07:30 -0800 Subject: RDS: Inline rdma_prepare into cmsg_rdma_args cmsg_rdma_args just calls rdma_prepare and does a little arg checking -- not quite enough to justify its existence. Plus, it is the only caller of rdma_prepare(). Signed-off-by: Andy Grover --- net/rds/rdma.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 4df545a6eab8..91967c8bc572 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -497,12 +497,13 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) } /* - * args is a pointer to an in-kernel copy in the sendmsg cmsg. + * The application asks for a RDMA transfer. + * Extract all arguments and set up the rdma_op */ -static int rds_rdma_prepare(struct rds_message *rm, - struct rds_sock *rs, - struct rds_rdma_args *args) +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg) { + struct rds_rdma_args *args; struct rds_iovec vec; struct rds_rdma_op *op = &rm->rdma.m_rdma_op; unsigned int nr_pages; @@ -513,6 +514,11 @@ static int rds_rdma_prepare(struct rds_message *rm, unsigned int i, j; int ret = 0; + if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) + || rm->rdma.m_rdma_op.r_active) + return -EINVAL; + + args = CMSG_DATA(cmsg); if (rs->rs_bound_addr == 0) { ret = -ENOTCONN; /* XXX not a great errno */ @@ -623,7 +629,6 @@ static int rds_rdma_prepare(struct rds_message *rm, op->r_nents += nr; } - if (nr_bytes > args->remote_vec.bytes) { rdsdebug("RDS nr_bytes %u remote_bytes %u do not match\n", nr_bytes, @@ -639,28 +644,9 @@ out: if (ret) rds_rdma_free_op(op); - return ret; -} - -/* - * The application asks for a RDMA transfer. - * Extract all arguments and set up the rdma_op - */ -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg) -{ - int ret; - - if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || - rm->rdma.m_rdma_op.r_active) - return -EINVAL; - - ret = rds_rdma_prepare(rm, rs, CMSG_DATA(cmsg)); - if (ret) - return ret; - rds_stats_inc(s_send_rdma); - return 0; + + return ret; } /* -- cgit v1.2.3 From d0ab25a83c4a08cd98b73a37d3f4c069f7b4f50b Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 27 Jan 2010 16:15:48 -0800 Subject: RDS: purge atomic resources too in rds_message_purge() Add atomic_free_op function, analogous to rdma_free_op, and call it in rds_message_purge(). Signed-off-by: Andy Grover --- net/rds/message.c | 5 +++++ net/rds/rdma.c | 16 ++++++++++++++++ net/rds/rds.h | 1 + 3 files changed, 22 insertions(+) diff --git a/net/rds/message.c b/net/rds/message.c index a27e493a63a2..b53306c3e656 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -73,6 +73,11 @@ static void rds_message_purge(struct rds_message *rm) rds_rdma_free_op(&rm->rdma.m_rdma_op); if (rm->rdma.m_rdma_mr) rds_mr_put(rm->rdma.m_rdma_mr); + + if (rm->atomic.op_active) + rds_atomic_free_op(&rm->atomic); + if (rm->atomic.op_rdma_mr) + rds_mr_put(rm->atomic.op_rdma_mr); } void rds_message_put(struct rds_message *rm) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 91967c8bc572..0df86a382e2e 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -462,6 +462,22 @@ void rds_rdma_free_op(struct rds_rdma_op *ro) ro->r_active = 0; } +void rds_atomic_free_op(struct rm_atomic_op *ao) +{ + struct page *page = sg_page(ao->op_sg); + + /* Mark page dirty if it was possibly modified, which + * is the case for a RDMA_READ which copies from remote + * to local memory */ + set_page_dirty(page); + put_page(page); + + kfree(ao->op_notifier); + ao->op_notifier = NULL; + ao->op_active = 0; +} + + /* * Count the number of pages needed to describe an incoming iovec. */ diff --git a/net/rds/rds.h b/net/rds/rds.h index bf2349da4db7..32b3d46aea36 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -745,6 +745,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, struct cmsghdr *cmsg); void rds_rdma_free_op(struct rds_rdma_op *ro); +void rds_atomic_free_op(struct rm_atomic_op *ao); void rds_rdma_send_complete(struct rds_message *rm, int wc_status); void rds_atomic_send_complete(struct rds_message *rm, int wc_status); int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, -- cgit v1.2.3 From f8b3aaf2ba8ca9e27b47f8bfdff07c8b968f2c05 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 1 Mar 2010 14:11:53 -0800 Subject: RDS: Remove struct rds_rdma_op A big changeset, but it's all pretty dumb. struct rds_rdma_op was already embedded in struct rm_rdma_op. Remove rds_rdma_op and put its members in rm_rdma_op. Rename members with "op_" prefix instead of "r_", for consistency. Of course this breaks a lot, so fixup the code accordingly. Signed-off-by: Andy Grover --- net/rds/ib.h | 4 ++-- net/rds/ib_send.c | 60 ++++++++++++++++++++++++------------------------ net/rds/iw.h | 4 ++-- net/rds/iw_send.c | 68 +++++++++++++++++++++++++++---------------------------- net/rds/message.c | 8 +++---- net/rds/rdma.c | 58 +++++++++++++++++++++++------------------------ net/rds/rds.h | 41 ++++++++++++++++----------------- net/rds/send.c | 50 ++++++++++++++++++++-------------------- 8 files changed, 145 insertions(+), 148 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 96769b86a536..d64b5087eefe 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -54,7 +54,7 @@ struct rds_ib_connect_private { struct rds_ib_send_work { struct rds_message *s_rm; - struct rds_rdma_op *s_op; + struct rm_rdma_op *s_op; struct ib_send_wr s_wr; struct ib_sge s_sge[RDS_IB_MAX_SGE]; unsigned long s_queued; @@ -331,7 +331,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context); void rds_ib_send_init_ring(struct rds_ib_connection *ic); void rds_ib_send_clear_ring(struct rds_ib_connection *ic); -int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); +int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op); void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e6745d827c3a..63981cd1827a 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -79,14 +79,14 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rm->data.m_sg, rm->data.m_nents, DMA_TO_DEVICE); - if (rm->rdma.m_rdma_op.r_active) { - struct rds_rdma_op *op = &rm->rdma.m_rdma_op; + if (rm->rdma.op_active) { + struct rm_rdma_op *op = &rm->rdma; - if (op->r_mapped) { + if (op->op_mapped) { ib_dma_unmap_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, - op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->r_mapped = 0; + op->op_sg, op->op_nents, + op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->op_mapped = 0; } /* If the user asked for a completion notification on this @@ -111,10 +111,10 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, */ rds_ib_send_complete(rm, wc_status, rds_rdma_send_complete); - if (rm->rdma.m_rdma_op.r_write) - rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); + if (rm->rdma.op_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.op_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.op_bytes); } if (rm->atomic.op_active) { @@ -540,10 +540,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->rdma.m_rdma_op.r_active) { + if (rm->rdma.op_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op.r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -576,7 +576,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->rdma.m_rdma_op.r_active && rm->rdma.m_rdma_op.r_fence) + if (rm->rdma.op_active && rm->rdma.op_fence) send_flags = IB_SEND_FENCE; /* Each frag gets a header. Msgs may be 0 bytes */ @@ -746,7 +746,7 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm) * we must fill in s_rm ourselves, so we properly clean up * on completion. */ - if (!rm->rdma.m_rdma_op.r_active && !rm->data.op_active) + if (!rm->rdma.op_active && !rm->data.op_active) send->s_rm = rm; /* map 8 byte retval buffer to the device */ @@ -788,7 +788,7 @@ out: return ret; } -int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) +int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) { struct rds_ib_connection *ic = conn->c_transport_data; struct rds_ib_send_work *send = NULL; @@ -798,7 +798,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) struct rds_ib_device *rds_ibdev; struct scatterlist *scat; unsigned long len; - u64 remote_addr = op->r_remote_addr; + u64 remote_addr = op->op_remote_addr; u32 pos; u32 work_alloc; u32 i; @@ -810,25 +810,25 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); /* map the message the first time we see it */ - if (!op->r_mapped) { - op->r_count = ib_dma_map_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, (op->r_write) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count); - if (op->r_count == 0) { + if (!op->op_mapped) { + op->op_count = ib_dma_map_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, (op->op_write) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count); + if (op->op_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); ret = -ENOMEM; /* XXX ? */ goto out; } - op->r_mapped = 1; + op->op_mapped = 1; } /* * Instead of knowing how to return a partial rdma read/write we insist that there * be enough work requests to send the entire message. */ - i = ceil(op->r_count, rds_ibdev->max_sge); + i = ceil(op->op_count, rds_ibdev->max_sge); work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos); if (work_alloc != i) { @@ -841,19 +841,19 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &op->r_sg[0]; + scat = &op->op_sg[0]; sent = 0; - num_sge = op->r_count; + num_sge = op->op_count; - for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) { + for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; - rds_ib_set_wr_signal_state(ic, send, op->r_notify); + rds_ib_set_wr_signal_state(ic, send, op->op_notify); - send->s_wr.opcode = op->r_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; + send->s_wr.opcode = op->op_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; send->s_wr.wr.rdma.remote_addr = remote_addr; - send->s_wr.wr.rdma.rkey = op->r_key; + send->s_wr.wr.rdma.rkey = op->op_rkey; send->s_op = op; if (num_sge > rds_ibdev->max_sge) { @@ -868,7 +868,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) if (prev) prev->s_wr.next = &send->s_wr; - for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) { + for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) { len = ib_sg_dma_len(ic->i_cm_id->device, scat); send->s_sge[j].addr = ib_sg_dma_address(ic->i_cm_id->device, scat); diff --git a/net/rds/iw.h b/net/rds/iw.h index 6f08300851ad..f112105faced 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -70,7 +70,7 @@ struct rds_iw_send_work { struct rds_message *s_rm; /* We should really put these into a union: */ - struct rds_rdma_op *s_op; + struct rm_rdma_op *s_op; struct rds_iw_mapping *s_mapping; struct ib_mr *s_mr; struct ib_fast_reg_page_list *s_page_list; @@ -357,7 +357,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context); void rds_iw_send_init_ring(struct rds_iw_connection *ic); void rds_iw_send_clear_ring(struct rds_iw_connection *ic); -int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); +int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op); void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted, diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 9b79a1b10445..05ebf16ecad7 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -63,13 +63,13 @@ static void rds_iw_send_rdma_complete(struct rds_message *rm, } static void rds_iw_send_unmap_rdma(struct rds_iw_connection *ic, - struct rds_rdma_op *op) + struct rm_rdma_op *op) { - if (op->r_mapped) { + if (op->op_mapped) { ib_dma_unmap_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, - op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->r_mapped = 0; + op->op_sg, op->op_nents, + op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->op_mapped = 0; } } @@ -85,8 +85,8 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rm->data.m_sg, rm->data.m_nents, DMA_TO_DEVICE); - if (rm->rdma.m_rdma_op.r_active) { - rds_iw_send_unmap_rdma(ic, &rm->rdma.m_rdma_op); + if (rm->rdma.op_active) { + rds_iw_send_unmap_rdma(ic, &rm->rdma); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -110,10 +110,10 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, */ rds_iw_send_rdma_complete(rm, wc_status); - if (rm->rdma.m_rdma_op.r_write) - rds_stats_add(s_send_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); + if (rm->rdma.op_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.op_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->rdma.m_rdma_op.r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.op_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -591,10 +591,10 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->rdma.m_rdma_op.r_active) { + if (rm->rdma.op_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.m_rdma_op.r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -632,7 +632,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->rdma.m_rdma_op.r_active && rm->rdma.m_rdma_op.r_fence) + if (rm->rdma.op_active && rm->rdma.op_fence) send_flags = IB_SEND_FENCE; /* @@ -785,7 +785,7 @@ static void rds_iw_build_send_fastreg(struct rds_iw_device *rds_iwdev, struct rd ib_update_fast_reg_key(send->s_mr, send->s_remap_count++); } -int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) +int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) { struct rds_iw_connection *ic = conn->c_transport_data; struct rds_iw_send_work *send = NULL; @@ -795,7 +795,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) struct rds_iw_device *rds_iwdev; struct scatterlist *scat; unsigned long len; - u64 remote_addr = op->r_remote_addr; + u64 remote_addr = op->op_remote_addr; u32 pos, fr_pos; u32 work_alloc; u32 i; @@ -807,21 +807,21 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) rds_iwdev = ib_get_client_data(ic->i_cm_id->device, &rds_iw_client); /* map the message the first time we see it */ - if (!op->r_mapped) { - op->r_count = ib_dma_map_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, (op->r_write) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count); - if (op->r_count == 0) { + if (!op->op_mapped) { + op->op_count = ib_dma_map_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, (op->op_write) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count); + if (op->op_count == 0) { rds_iw_stats_inc(s_iw_tx_sg_mapping_failure); ret = -ENOMEM; /* XXX ? */ goto out; } - op->r_mapped = 1; + op->op_mapped = 1; } - if (!op->r_write) { + if (!op->op_write) { /* Alloc space on the send queue for the fastreg */ work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, 1, &fr_pos); if (work_alloc != 1) { @@ -836,7 +836,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * Instead of knowing how to return a partial rdma read/write we insist that there * be enough work requests to send the entire message. */ - i = ceil(op->r_count, rds_iwdev->max_sge); + i = ceil(op->op_count, rds_iwdev->max_sge); work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, i, &pos); if (work_alloc != i) { @@ -847,17 +847,17 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) } send = &ic->i_sends[pos]; - if (!op->r_write) { + if (!op->op_write) { first = prev = &ic->i_sends[fr_pos]; } else { first = send; prev = NULL; } - scat = &op->r_sg[0]; + scat = &op->op_sg[0]; sent = 0; - num_sge = op->r_count; + num_sge = op->op_count; - for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) { + for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; @@ -874,13 +874,13 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * for local access after RDS is finished with it, using * IB_WR_RDMA_READ_WITH_INV will invalidate it after the read has completed. */ - if (op->r_write) + if (op->op_write) send->s_wr.opcode = IB_WR_RDMA_WRITE; else send->s_wr.opcode = IB_WR_RDMA_READ_WITH_INV; send->s_wr.wr.rdma.remote_addr = remote_addr; - send->s_wr.wr.rdma.rkey = op->r_key; + send->s_wr.wr.rdma.rkey = op->op_rkey; send->s_op = op; if (num_sge > rds_iwdev->max_sge) { @@ -894,7 +894,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) if (prev) prev->s_wr.next = &send->s_wr; - for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) { + for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) { len = ib_sg_dma_len(ic->i_cm_id->device, scat); if (send->s_wr.opcode == IB_WR_RDMA_READ_WITH_INV) @@ -928,7 +928,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) } /* if we finished the message then send completion owns it */ - if (scat == &op->r_sg[op->r_count]) + if (scat == &op->op_sg[op->op_count]) first->s_wr.send_flags = IB_SEND_SIGNALED; if (i < work_alloc) { @@ -942,9 +942,9 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * adapters do not allow using the lkey for this at all. To bypass this use a * fastreg_mr (or possibly a dma_mr) */ - if (!op->r_write) { + if (!op->op_write) { rds_iw_build_send_fastreg(rds_iwdev, ic, &ic->i_sends[fr_pos], - op->r_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr); + op->op_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr); work_alloc++; } diff --git a/net/rds/message.c b/net/rds/message.c index b53306c3e656..bca7eda6dde9 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -69,10 +69,10 @@ static void rds_message_purge(struct rds_message *rm) } rm->data.m_nents = 0; - if (rm->rdma.m_rdma_op.r_active) - rds_rdma_free_op(&rm->rdma.m_rdma_op); - if (rm->rdma.m_rdma_mr) - rds_mr_put(rm->rdma.m_rdma_mr); + if (rm->rdma.op_active) + rds_rdma_free_op(&rm->rdma); + if (rm->rdma.op_rdma_mr) + rds_mr_put(rm->rdma.op_rdma_mr); if (rm->atomic.op_active) rds_atomic_free_op(&rm->atomic); diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 0df86a382e2e..8d22999b0471 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -440,26 +440,26 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force) rds_mr_put(mr); } -void rds_rdma_free_op(struct rds_rdma_op *ro) +void rds_rdma_free_op(struct rm_rdma_op *ro) { unsigned int i; - for (i = 0; i < ro->r_nents; i++) { - struct page *page = sg_page(&ro->r_sg[i]); + for (i = 0; i < ro->op_nents; i++) { + struct page *page = sg_page(&ro->op_sg[i]); /* Mark page dirty if it was possibly modified, which * is the case for a RDMA_READ which copies from remote * to local memory */ - if (!ro->r_write) { + if (!ro->op_write) { BUG_ON(irqs_disabled()); set_page_dirty(page); } put_page(page); } - kfree(ro->r_notifier); - ro->r_notifier = NULL; - ro->r_active = 0; + kfree(ro->op_notifier); + ro->op_notifier = NULL; + ro->op_active = 0; } void rds_atomic_free_op(struct rm_atomic_op *ao) @@ -521,7 +521,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, { struct rds_rdma_args *args; struct rds_iovec vec; - struct rds_rdma_op *op = &rm->rdma.m_rdma_op; + struct rm_rdma_op *op = &rm->rdma; unsigned int nr_pages; unsigned int nr_bytes; struct page **pages = NULL; @@ -531,7 +531,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, int ret = 0; if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) - || rm->rdma.m_rdma_op.r_active) + || rm->rdma.op_active) return -EINVAL; args = CMSG_DATA(cmsg); @@ -556,27 +556,27 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, goto out; } - op->r_write = !!(args->flags & RDS_RDMA_READWRITE); - op->r_fence = !!(args->flags & RDS_RDMA_FENCE); - op->r_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); - op->r_active = 1; - op->r_recverr = rs->rs_recverr; + op->op_write = !!(args->flags & RDS_RDMA_READWRITE); + op->op_fence = !!(args->flags & RDS_RDMA_FENCE); + op->op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + op->op_active = 1; + op->op_recverr = rs->rs_recverr; WARN_ON(!nr_pages); - op->r_sg = rds_message_alloc_sgs(rm, nr_pages); + op->op_sg = rds_message_alloc_sgs(rm, nr_pages); - if (op->r_notify || op->r_recverr) { + if (op->op_notify || op->op_recverr) { /* We allocate an uninitialized notifier here, because * we don't want to do that in the completion handler. We * would have to use GFP_ATOMIC there, and don't want to deal * with failed allocations. */ - op->r_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); - if (!op->r_notifier) { + op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); + if (!op->op_notifier) { ret = -ENOMEM; goto out; } - op->r_notifier->n_user_token = args->user_token; - op->r_notifier->n_status = RDS_RDMA_SUCCESS; + op->op_notifier->n_user_token = args->user_token; + op->op_notifier->n_status = RDS_RDMA_SUCCESS; } /* The cookie contains the R_Key of the remote memory region, and @@ -586,15 +586,15 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, * destination address (which is really an offset into the MR) * FIXME: We may want to move this into ib_rdma.c */ - op->r_key = rds_rdma_cookie_key(args->cookie); - op->r_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie); + op->op_rkey = rds_rdma_cookie_key(args->cookie); + op->op_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie); nr_bytes = 0; rdsdebug("RDS: rdma prepare nr_local %llu rva %llx rkey %x\n", (unsigned long long)args->nr_local, (unsigned long long)args->remote_vec.addr, - op->r_key); + op->op_rkey); local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; @@ -617,7 +617,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, /* If it's a WRITE operation, we want to pin the pages for reading. * If it's a READ operation, we need to pin the pages for writing. */ - ret = rds_pin_pages(vec.addr, nr, pages, !op->r_write); + ret = rds_pin_pages(vec.addr, nr, pages, !op->op_write); if (ret < 0) goto out; @@ -630,7 +630,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, unsigned int offset = vec.addr & ~PAGE_MASK; struct scatterlist *sg; - sg = &op->r_sg[op->r_nents + j]; + sg = &op->op_sg[op->op_nents + j]; sg_set_page(sg, pages[j], min_t(unsigned int, vec.bytes, PAGE_SIZE - offset), offset); @@ -642,7 +642,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, vec.bytes -= sg->length; } - op->r_nents += nr; + op->op_nents += nr; } if (nr_bytes > args->remote_vec.bytes) { @@ -652,7 +652,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, ret = -EINVAL; goto out; } - op->r_bytes = nr_bytes; + op->op_bytes = nr_bytes; ret = 0; out: @@ -700,7 +700,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, if (mr) { mr->r_trans->sync_mr(mr->r_trans_private, DMA_TO_DEVICE); - rm->rdma.m_rdma_mr = mr; + rm->rdma.op_rdma_mr = mr; } return err; } @@ -718,7 +718,7 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, rm->m_rdma_cookie != 0) return -EINVAL; - return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.m_rdma_mr); + return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.op_rdma_mr); } /* diff --git a/net/rds/rds.h b/net/rds/rds.h index 32b3d46aea36..76eeb5988b5f 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -230,22 +230,6 @@ struct rds_mr { /* Flags for mr->r_state */ #define RDS_MR_DEAD 0 -struct rds_rdma_op { - u32 r_key; - u64 r_remote_addr; - unsigned int r_write:1; - unsigned int r_fence:1; - unsigned int r_notify:1; - unsigned int r_recverr:1; - unsigned int r_mapped:1; - unsigned int r_active:1; - struct rds_notifier *r_notifier; - unsigned int r_bytes; - unsigned int r_nents; - unsigned int r_count; - struct scatterlist *r_sg; -}; - static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset) { return r_key | (((u64) offset) << 32); @@ -331,14 +315,27 @@ struct rds_message { unsigned int op_recverr:1; unsigned int op_mapped:1; unsigned int op_active:1; - struct rds_notifier *op_notifier; struct scatterlist *op_sg; + struct rds_notifier *op_notifier; struct rds_mr *op_rdma_mr; } atomic; struct rm_rdma_op { - struct rds_rdma_op m_rdma_op; - struct rds_mr *m_rdma_mr; + u32 op_rkey; + u64 op_remote_addr; + unsigned int op_write:1; + unsigned int op_fence:1; + unsigned int op_notify:1; + unsigned int op_recverr:1; + unsigned int op_mapped:1; + unsigned int op_active:1; + unsigned int op_bytes; + unsigned int op_nents; + unsigned int op_count; + struct scatterlist *op_sg; + struct rds_notifier *op_notifier; + + struct rds_mr *op_rdma_mr; } rdma; struct rm_data_op { unsigned int op_active:1; @@ -418,7 +415,7 @@ struct rds_transport { unsigned int hdr_off, unsigned int sg, unsigned int off); int (*xmit_cong_map)(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset); - int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op); + int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); int (*xmit_atomic)(struct rds_connection *conn, struct rds_message *rm); int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, @@ -727,7 +724,7 @@ int rds_send_acked_before(struct rds_connection *conn, u64 seq); void rds_send_remove_from_sock(struct list_head *messages, int status); int rds_send_pong(struct rds_connection *conn, __be16 dport); struct rds_message *rds_send_get_message(struct rds_connection *, - struct rds_rdma_op *); + struct rm_rdma_op *); /* rdma.c */ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force); @@ -744,7 +741,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, struct cmsghdr *cmsg); int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, struct cmsghdr *cmsg); -void rds_rdma_free_op(struct rds_rdma_op *ro); +void rds_rdma_free_op(struct rm_rdma_op *ro); void rds_atomic_free_op(struct rm_atomic_op *ao); void rds_rdma_send_complete(struct rds_message *rm, int wc_status); void rds_atomic_send_complete(struct rds_message *rm, int wc_status); diff --git a/net/rds/send.c b/net/rds/send.c index 42fb934293be..08df279ced2a 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -237,7 +237,7 @@ int rds_send_xmit(struct rds_connection *conn) * connection. * Therefore, we never retransmit messages with RDMA ops. */ - if (rm->rdma.m_rdma_op.r_active && + if (rm->rdma.op_active && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { spin_lock_irqsave(&conn->c_lock, flags); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) @@ -280,8 +280,8 @@ int rds_send_xmit(struct rds_connection *conn) * keep this simple and require that the transport either * send the whole rdma or none of it. */ - if (rm->rdma.m_rdma_op.r_active && !conn->c_xmit_rdma_sent) { - ret = conn->c_trans->xmit_rdma(conn, &rm->rdma.m_rdma_op); + if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { + ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); if (ret) break; conn->c_xmit_rdma_sent = 1; @@ -430,16 +430,16 @@ int rds_send_acked_before(struct rds_connection *conn, u64 seq) void rds_rdma_send_complete(struct rds_message *rm, int status) { struct rds_sock *rs = NULL; - struct rds_rdma_op *ro; + struct rm_rdma_op *ro; struct rds_notifier *notifier; unsigned long flags; spin_lock_irqsave(&rm->m_rs_lock, flags); - ro = &rm->rdma.m_rdma_op; + ro = &rm->rdma; if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && - ro->r_active && ro->r_notify && ro->r_notifier) { - notifier = ro->r_notifier; + ro->op_active && ro->op_notify && ro->op_notifier) { + notifier = ro->op_notifier; rs = rm->m_rs; sock_hold(rds_rs_to_sk(rs)); @@ -448,7 +448,7 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); spin_unlock(&rs->rs_lock); - ro->r_notifier = NULL; + ro->op_notifier = NULL; } spin_unlock_irqrestore(&rm->m_rs_lock, flags); @@ -503,13 +503,13 @@ EXPORT_SYMBOL_GPL(rds_atomic_send_complete); static inline void __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status) { - struct rds_rdma_op *ro; + struct rm_rdma_op *ro; - ro = &rm->rdma.m_rdma_op; - if (ro->r_active && ro->r_notify && ro->r_notifier) { - ro->r_notifier->n_status = status; - list_add_tail(&ro->r_notifier->n_list, &rs->rs_notify_queue); - ro->r_notifier = NULL; + ro = &rm->rdma; + if (ro->op_active && ro->op_notify && ro->op_notifier) { + ro->op_notifier->n_status = status; + list_add_tail(&ro->op_notifier->n_list, &rs->rs_notify_queue); + ro->op_notifier = NULL; } /* No need to wake the app - caller does this */ @@ -521,7 +521,7 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status * So speed is not an issue here. */ struct rds_message *rds_send_get_message(struct rds_connection *conn, - struct rds_rdma_op *op) + struct rm_rdma_op *op) { struct rds_message *rm, *tmp, *found = NULL; unsigned long flags; @@ -529,7 +529,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, spin_lock_irqsave(&conn->c_lock, flags); list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (&rm->rdma.m_rdma_op == op) { + if (&rm->rdma == op) { atomic_inc(&rm->m_refcount); found = rm; goto out; @@ -537,7 +537,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, } list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (&rm->rdma.m_rdma_op == op) { + if (&rm->rdma == op) { atomic_inc(&rm->m_refcount); found = rm; break; @@ -597,20 +597,20 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) spin_lock(&rs->rs_lock); if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { - struct rds_rdma_op *ro = &rm->rdma.m_rdma_op; + struct rm_rdma_op *ro = &rm->rdma; struct rds_notifier *notifier; list_del_init(&rm->m_sock_item); rds_send_sndbuf_remove(rs, rm); - if (ro->r_active && ro->r_notifier && - (ro->r_notify || (ro->r_recverr && status))) { - notifier = ro->r_notifier; + if (ro->op_active && ro->op_notifier && + (ro->op_notify || (ro->op_recverr && status))) { + notifier = ro->op_notifier; list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); if (!notifier->n_status) notifier->n_status = status; - rm->rdma.m_rdma_op.r_notifier = NULL; + rm->rdma.op_notifier = NULL; } was_on_sock = 1; rm->m_rs = NULL; @@ -987,11 +987,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (ret) goto out; - if ((rm->m_rdma_cookie || rm->rdma.m_rdma_op.r_active) && - !conn->c_trans->xmit_rdma) { + if ((rm->m_rdma_cookie || rm->rdma.op_active) && + !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", - &rm->rdma.m_rdma_op, conn->c_trans->xmit_rdma); + &rm->rdma, conn->c_trans->xmit_rdma); ret = -EOPNOTSUPP; goto out; } -- cgit v1.2.3 From 6c7cc6e4694dc464ae884332f2a322973497e3cf Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 27 Jan 2010 18:04:18 -0800 Subject: RDS: Rename data op members prefix from m_ to op_ For consistency. Signed-off-by: Andy Grover --- net/rds/ib_send.c | 26 +++++++++++++------------- net/rds/iw_send.c | 24 ++++++++++++------------ net/rds/message.c | 22 +++++++++++----------- net/rds/rds.h | 6 +++--- net/rds/send.c | 10 +++++----- net/rds/tcp_send.c | 14 +++++++------- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 63981cd1827a..95f15247acd7 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -76,7 +76,7 @@ static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, rdsdebug("ic %p send %p rm %p\n", ic, send, rm); ib_dma_unmap_sg(ic->i_cm_id->device, - rm->data.m_sg, rm->data.m_nents, + rm->data.op_sg, rm->data.op_nents, DMA_TO_DEVICE); if (rm->rdma.op_active) { @@ -513,20 +513,20 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* map the message the first time we see it */ if (!ic->i_rm) { - if (rm->data.m_nents) { - rm->data.m_count = ib_dma_map_sg(dev, - rm->data.m_sg, - rm->data.m_nents, - DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.m_count); - if (rm->data.m_count == 0) { + if (rm->data.op_nents) { + rm->data.op_count = ib_dma_map_sg(dev, + rm->data.op_sg, + rm->data.op_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count); + if (rm->data.op_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->data.m_count = 0; + rm->data.op_count = 0; } rds_message_addref(rm); @@ -583,7 +583,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->data.m_sg[sg]; + scat = &rm->data.op_sg[sg]; i = 0; do { unsigned int len = 0; @@ -604,7 +604,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* Set up the data, if present */ if (i < work_alloc - && scat != &rm->data.m_sg[rm->data.m_count]) { + && scat != &rm->data.op_sg[rm->data.op_count]) { len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off); send->s_wr.num_sge = 2; @@ -649,7 +649,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, i++; } while (i < work_alloc - && scat != &rm->data.m_sg[rm->data.m_count]); + && scat != &rm->data.op_sg[rm->data.op_count]); /* Account the RDS header in the number of bytes we sent, but just once. * The caller has no concept of fragmentation. */ @@ -657,7 +657,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, bytes_sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->data.m_sg[rm->data.m_count]) { + if (scat == &rm->data.op_sg[rm->data.op_count]) { prev->s_rm = ic->i_rm; prev->s_wr.send_flags |= IB_SEND_SOLICITED; ic->i_rm = NULL; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 05ebf16ecad7..6280ea020d4e 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -82,7 +82,7 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rdsdebug("ic %p send %p rm %p\n", ic, send, rm); ib_dma_unmap_sg(ic->i_cm_id->device, - rm->data.m_sg, rm->data.m_nents, + rm->data.op_sg, rm->data.op_nents, DMA_TO_DEVICE); if (rm->rdma.op_active) { @@ -562,20 +562,20 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, rm->m_inc.i_hdr.h_flags, be32_to_cpu(rm->m_inc.i_hdr.h_len)); */ - if (rm->data.m_nents) { - rm->data.m_count = ib_dma_map_sg(dev, - rm->data.m_sg, - rm->data.m_nents, - DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.m_count); - if (rm->data.m_count == 0) { + if (rm->data.op_nents) { + rm->data.op_count = ib_dma_map_sg(dev, + rm->data.op_sg, + rm->data.op_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count); + if (rm->data.op_count == 0) { rds_iw_stats_inc(s_iw_tx_sg_mapping_failure); rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->data.m_count = 0; + rm->data.op_count = 0; } ic->i_unsignaled_wrs = rds_iw_sysctl_max_unsig_wrs; @@ -622,7 +622,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->data.m_sg[sg]; + scat = &rm->data.op_sg[sg]; sent = 0; i = 0; @@ -651,7 +651,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, } /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->data.m_sg[rm->data.m_count]; i++) { + for (; i < work_alloc && scat != &rm->data.op_sg[rm->data.op_count]; i++) { unsigned int len; send = &ic->i_sends[pos]; @@ -729,7 +729,7 @@ add_header: sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->data.m_sg[rm->data.m_count]) { + if (scat == &rm->data.op_sg[rm->data.op_count]) { prev->s_rm = ic->i_rm; prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; ic->i_rm = NULL; diff --git a/net/rds/message.c b/net/rds/message.c index bca7eda6dde9..4bd9504ca048 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -62,12 +62,12 @@ static void rds_message_purge(struct rds_message *rm) if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags))) return; - for (i = 0; i < rm->data.m_nents; i++) { - rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.m_sg[i])); + for (i = 0; i < rm->data.op_nents; i++) { + rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.op_sg[i])); /* XXX will have to put_page for page refs */ - __free_page(sg_page(&rm->data.m_sg[i])); + __free_page(sg_page(&rm->data.op_sg[i])); } - rm->data.m_nents = 0; + rm->data.op_nents = 0; if (rm->rdma.op_active) rds_rdma_free_op(&rm->rdma); @@ -261,11 +261,11 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); - rm->data.m_nents = ceil(total_len, PAGE_SIZE); - rm->data.m_sg = rds_message_alloc_sgs(rm, num_sgs); + rm->data.op_nents = ceil(total_len, PAGE_SIZE); + rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); - for (i = 0; i < rm->data.m_nents; ++i) { - sg_set_page(&rm->data.m_sg[i], + for (i = 0; i < rm->data.op_nents; ++i) { + sg_set_page(&rm->data.op_sg[i], virt_to_page(page_addrs[i]), PAGE_SIZE, 0); } @@ -288,7 +288,7 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, /* * now allocate and copy in the data payload. */ - sg = rm->data.m_sg; + sg = rm->data.op_sg; iov = first_iov; iov_off = 0; sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ @@ -299,7 +299,7 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, GFP_HIGHUSER); if (ret) goto out; - rm->data.m_nents++; + rm->data.op_nents++; sg_off = 0; } @@ -354,7 +354,7 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, iov = first_iov; iov_off = 0; - sg = rm->data.m_sg; + sg = rm->data.op_sg; vec_off = 0; copied = 0; diff --git a/net/rds/rds.h b/net/rds/rds.h index 76eeb5988b5f..d70284989124 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -339,9 +339,9 @@ struct rds_message { } rdma; struct rm_data_op { unsigned int op_active:1; - unsigned int m_nents; - unsigned int m_count; - struct scatterlist *m_sg; + unsigned int op_nents; + unsigned int op_count; + struct scatterlist *op_sg; } data; }; unsigned int m_used_sgs; diff --git a/net/rds/send.c b/net/rds/send.c index 08df279ced2a..d60d31309032 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -166,7 +166,7 @@ int rds_send_xmit(struct rds_connection *conn) rm = conn->c_xmit_rm; if (rm && conn->c_xmit_hdr_off == sizeof(struct rds_header) && - conn->c_xmit_sg == rm->data.m_nents) { + conn->c_xmit_sg == rm->data.op_nents) { conn->c_xmit_rm = NULL; conn->c_xmit_sg = 0; conn->c_xmit_hdr_off = 0; @@ -296,7 +296,7 @@ int rds_send_xmit(struct rds_connection *conn) if (rm->data.op_active && (conn->c_xmit_hdr_off < sizeof(struct rds_header) || - conn->c_xmit_sg < rm->data.m_nents)) { + conn->c_xmit_sg < rm->data.op_nents)) { ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, @@ -312,7 +312,7 @@ int rds_send_xmit(struct rds_connection *conn) ret -= tmp; } - sg = &rm->data.m_sg[conn->c_xmit_sg]; + sg = &rm->data.op_sg[conn->c_xmit_sg]; while (ret) { tmp = min_t(int, ret, sg->length - conn->c_xmit_data_off); @@ -323,7 +323,7 @@ int rds_send_xmit(struct rds_connection *conn) sg++; conn->c_xmit_sg++; BUG_ON(ret != 0 && - conn->c_xmit_sg == rm->data.m_nents); + conn->c_xmit_sg == rm->data.op_nents); } } } @@ -959,7 +959,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; } - rm->data.m_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); + rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); /* XXX fix this to not allocate memory */ ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); if (ret) diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index d63aa35ac673..53c1de55f471 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -166,21 +166,21 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, goto out; } - while (sg < rm->data.m_nents) { + while (sg < rm->data.op_nents) { ret = tc->t_sock->ops->sendpage(tc->t_sock, - sg_page(&rm->data.m_sg[sg]), - rm->data.m_sg[sg].offset + off, - rm->data.m_sg[sg].length - off, + sg_page(&rm->data.op_sg[sg]), + rm->data.op_sg[sg].offset + off, + rm->data.op_sg[sg].length - off, MSG_DONTWAIT|MSG_NOSIGNAL); - rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.m_sg[sg]), - rm->data.m_sg[sg].offset + off, rm->data.m_sg[sg].length - off, + rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.op_sg[sg]), + rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; - if (off == rm->data.m_sg[sg].length) { + if (off == rm->data.op_sg[sg].length) { off = 0; sg++; } -- cgit v1.2.3 From 5b2366bd2835919e2e6a836e837eab4a9274bd46 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 3 Feb 2010 19:36:44 -0800 Subject: RDS: Rewrite rds_send_xmit Simplify rds_send_xmit(). Send a congestion map (via xmit_cong_map) without decrementing send_quota. Move resetting of conn xmit variables to end of loop. Update comments. Implement a special case to turn off sending an rds header when there is an atomic op and no other data. Signed-off-by: Andy Grover --- net/rds/rds.h | 5 +-- net/rds/send.c | 131 +++++++++++++++++++++++++++++++-------------------------- 2 files changed, 73 insertions(+), 63 deletions(-) diff --git a/net/rds/rds.h b/net/rds/rds.h index d70284989124..13ed30ac424d 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -96,8 +96,9 @@ struct rds_connection { unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; unsigned int c_xmit_data_off; - unsigned int c_xmit_rdma_sent; unsigned int c_xmit_atomic_sent; + unsigned int c_xmit_rdma_sent; + unsigned int c_xmit_data_sent; spinlock_t c_lock; /* protect msg queues */ u64 c_next_tx_seq; @@ -120,8 +121,6 @@ struct rds_connection { struct list_head c_map_item; unsigned long c_map_queued; - unsigned long c_map_offset; - unsigned long c_map_bytes; unsigned int c_unacked_packets; unsigned int c_unacked_bytes; diff --git a/net/rds/send.c b/net/rds/send.c index d60d31309032..66dc6b045261 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -72,8 +72,9 @@ void rds_send_reset(struct rds_connection *conn) conn->c_xmit_sg = 0; conn->c_xmit_hdr_off = 0; conn->c_xmit_data_off = 0; - conn->c_xmit_rdma_sent = 0; conn->c_xmit_atomic_sent = 0; + conn->c_xmit_rdma_sent = 0; + conn->c_xmit_data_sent = 0; conn->c_map_queued = 0; @@ -137,69 +138,54 @@ int rds_send_xmit(struct rds_connection *conn) /* * spin trying to push headers and data down the connection until - * the connection doens't make forward progress. + * the connection doesn't make forward progress. */ while (--send_quota) { - /* - * See if need to send a congestion map update if we're - * between sending messages. The send_sem protects our sole - * use of c_map_offset and _bytes. - * Note this is used only by transports that define a special - * xmit_cong_map function. For all others, we create allocate - * a cong_map message and treat it just like any other send. - */ - if (conn->c_map_bytes) { - ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong, - conn->c_map_offset); - if (ret <= 0) - break; - conn->c_map_offset += ret; - conn->c_map_bytes -= ret; - if (conn->c_map_bytes) - continue; - } - - /* If we're done sending the current message, clear the - * offset and S/G temporaries. - */ rm = conn->c_xmit_rm; - if (rm && - conn->c_xmit_hdr_off == sizeof(struct rds_header) && - conn->c_xmit_sg == rm->data.op_nents) { - conn->c_xmit_rm = NULL; - conn->c_xmit_sg = 0; - conn->c_xmit_hdr_off = 0; - conn->c_xmit_data_off = 0; - conn->c_xmit_rdma_sent = 0; - conn->c_xmit_atomic_sent = 0; - - /* Release the reference to the previous message. */ - rds_message_put(rm); - rm = NULL; - } - /* If we're asked to send a cong map update, do so. + /* + * If between sending messages, we can send a pending congestion + * map update. + * + * Transports either define a special xmit_cong_map function, + * or we allocate a cong_map message and treat it just like any + * other send. */ if (!rm && test_and_clear_bit(0, &conn->c_map_queued)) { if (conn->c_trans->xmit_cong_map) { - conn->c_map_offset = 0; - conn->c_map_bytes = sizeof(struct rds_header) + + unsigned long map_offset = 0; + unsigned long map_bytes = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; - continue; - } - rm = rds_cong_update_alloc(conn); - if (IS_ERR(rm)) { - ret = PTR_ERR(rm); - break; - } + while (map_bytes) { + ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong, + map_offset); + if (ret <= 0) { + /* too far down the rabbithole! */ + mutex_unlock(&conn->c_send_lock); + rds_conn_error(conn, "Cong map xmit failed\n"); + goto out; + } + + map_offset += ret; + map_bytes -= ret; + } + } else { + /* send cong update like a normal rm */ + rm = rds_cong_update_alloc(conn); + if (IS_ERR(rm)) { + ret = PTR_ERR(rm); + break; + } + rm->data.op_active = 1; - conn->c_xmit_rm = rm; + conn->c_xmit_rm = rm; + } } /* - * Grab the next message from the send queue, if there is one. + * If not already working on one, grab the next message. * * c_xmit_rm holds a ref while we're sending this message down * the connction. We can use this ref while holding the @@ -264,7 +250,6 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_rm = rm; } - if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { ret = conn->c_trans->xmit_atomic(conn, rm); if (ret) @@ -273,13 +258,20 @@ int rds_send_xmit(struct rds_connection *conn) /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); + + /* + * This is evil, muahaha. + * We permit 0-byte sends. (rds-ping depends on this.) + * BUT if there is an atomic op and no sent data, + * we turn off sending the header, to achieve + * "silent" atomics. + * But see below; RDMA op might toggle this back on! + */ + if (rm->data.op_nents == 0) + rm->data.op_active = 0; } - /* - * Try and send an rdma message. Let's see if we can - * keep this simple and require that the transport either - * send the whole rdma or none of it. - */ + /* The transport either sends the whole rdma or none of it */ if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); if (ret) @@ -294,9 +286,7 @@ int rds_send_xmit(struct rds_connection *conn) set_bit(RDS_MSG_MAPPED, &rm->m_flags); } - if (rm->data.op_active - && (conn->c_xmit_hdr_off < sizeof(struct rds_header) || - conn->c_xmit_sg < rm->data.op_nents)) { + if (rm->data.op_active && !conn->c_xmit_data_sent) { ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, @@ -326,6 +316,27 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_sg == rm->data.op_nents); } } + + if (conn->c_xmit_hdr_off == sizeof(struct rds_header) && + (conn->c_xmit_sg == rm->data.op_nents)) + conn->c_xmit_data_sent = 1; + } + + /* + * A rm will only take multiple times through this loop + * if there is a data op. Thus, if the data is sent (or there was + * none), then we're done with the rm. + */ + if (!rm->data.op_active || conn->c_xmit_data_sent) { + conn->c_xmit_rm = NULL; + conn->c_xmit_sg = 0; + conn->c_xmit_hdr_off = 0; + conn->c_xmit_data_off = 0; + conn->c_xmit_rdma_sent = 0; + conn->c_xmit_atomic_sent = 0; + conn->c_xmit_data_sent = 0; + + rds_message_put(rm); } } @@ -350,7 +361,7 @@ int rds_send_xmit(struct rds_connection *conn) */ mutex_unlock(&conn->c_send_lock); - if (conn->c_map_bytes || (send_quota == 0 && !was_empty)) { + if (send_quota == 0 && !was_empty) { /* We exhausted the send quota, but there's work left to * do. Return and (re-)schedule the send worker. */ -- cgit v1.2.3 From 372cd7dedfd1ea93a9ae8d9c282e910dc1b76773 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 3 Feb 2010 19:40:32 -0800 Subject: RDS: Do not set op_active in r_m_copy_from_user(). Do not allocate sgs for data for 0-length datagrams Set data.op_active in rds_sendmsg() instead of rds_message_copy_from_user(). Signed-off-by: Andy Grover --- net/rds/message.c | 2 -- net/rds/send.c | 13 ++++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 4bd9504ca048..f4c3be0878e9 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -330,8 +330,6 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, sg++; } - rm->data.op_active = 1; - out: return ret; } diff --git a/net/rds/send.c b/net/rds/send.c index 66dc6b045261..ad89a63c4304 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -970,11 +970,14 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; } - rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); - /* XXX fix this to not allocate memory */ - ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); - if (ret) - goto out; + /* Attach data to the rm */ + if (payload_len) { + rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); + ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); + if (ret) + goto out; + } + rm->data.op_active = 1; rm->m_daddr = daddr; -- cgit v1.2.3 From ee4c7b47e46a9dea789aadb8279c8505f755b3ee Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 3 Feb 2010 19:41:52 -0800 Subject: RDS: Add a warning if trying to allocate 0 sgs rds_message_alloc_sgs() only works when nents is nonzero. Signed-off-by: Andy Grover --- net/rds/message.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/rds/message.c b/net/rds/message.c index f4c3be0878e9..1f73a7358a8e 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -240,6 +240,7 @@ struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) struct scatterlist *sg_ret; WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs); + WARN_ON(!nents); sg_ret = &sg_first[rm->m_used_sgs]; sg_init_table(sg_ret, nents); -- cgit v1.2.3 From 940786eb0a0faf3f30898a1cc7c1540d54c1aff6 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 19 Feb 2010 18:04:58 -0800 Subject: RDS: queue failure notifications for dropped atomic ops When dropping ops in the send queue, we notify the client of failed rdma ops they asked for notifications on, but not atomic ops. It should be for both. Signed-off-by: Andy Grover --- net/rds/send.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index ad89a63c4304..cdca9747fcbc 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -512,9 +512,10 @@ EXPORT_SYMBOL_GPL(rds_atomic_send_complete); * socket, socket lock) and can just move the notifier. */ static inline void -__rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status) +__rds_send_complete(struct rds_sock *rs, struct rds_message *rm, int status) { struct rm_rdma_op *ro; + struct rm_atomic_op *ao; ro = &rm->rdma; if (ro->op_active && ro->op_notify && ro->op_notifier) { @@ -523,6 +524,13 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status ro->op_notifier = NULL; } + ao = &rm->atomic; + if (ao->op_active && ao->op_notify && ao->op_notifier) { + ao->op_notifier->n_status = status; + list_add_tail(&ao->op_notifier->n_list, &rs->rs_notify_queue); + ao->op_notifier = NULL; + } + /* No need to wake the app - caller does this */ } @@ -733,7 +741,7 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) spin_lock_irqsave(&rm->m_rs_lock, flags); spin_lock(&rs->rs_lock); - __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); + __rds_send_complete(rs, rm, RDS_RDMA_CANCELED); spin_unlock(&rs->rs_lock); rm->m_rs = NULL; -- cgit v1.2.3 From 7e3bd65ebfd5d6cd76b8b979920c632d6e6b4b2a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 1 Mar 2010 16:04:59 -0800 Subject: RDS: Move some variables around for consistency Also, add a comment. Signed-off-by: Andy Grover --- net/rds/rdma.c | 3 +-- net/rds/rds.h | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 8d22999b0471..5ba514684431 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -747,6 +747,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, } rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + rm->atomic.op_active = 1; rm->atomic.op_recverr = rs->rs_recverr; rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); @@ -782,8 +783,6 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, rm->atomic.op_rkey = rds_rdma_cookie_key(args->cookie); rm->atomic.op_remote_addr = args->remote_addr + rds_rdma_cookie_offset(args->cookie); - rm->atomic.op_active = 1; - return ret; err: if (page) diff --git a/net/rds/rds.h b/net/rds/rds.h index 13ed30ac424d..46d190d08549 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -301,7 +301,13 @@ struct rds_message { */ spinlock_t m_rs_lock; struct rds_sock *m_rs; + + /* cookie to send to remote, in rds header */ rds_rdma_cookie_t m_rdma_cookie; + + unsigned int m_used_sgs; + unsigned int m_total_sgs; + struct { struct rm_atomic_op { int op_type; @@ -343,8 +349,6 @@ struct rds_message { struct scatterlist *op_sg; } data; }; - unsigned int m_used_sgs; - unsigned int m_total_sgs; }; /* -- cgit v1.2.3 From 2c3a5f9abb1dc5efdab8ba9a568b1661c65fd1e3 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 1 Mar 2010 16:10:40 -0800 Subject: RDS: Add flag for silent ops. Do atomic op before RDMA Add a flag to the API so users can indicate they want silent operations. This is needed because silent ops cannot be used with USE_ONCE MRs, so we can't just assume silent. Also, change send_xmit to do atomic op before rdma op if both are present, and centralize the hairy logic to determine if we want to attempt silent, or not. Signed-off-by: Andy Grover --- include/linux/rds.h | 1 + net/rds/rdma.c | 2 ++ net/rds/rds.h | 2 ++ net/rds/send.c | 55 ++++++++++++++++++++++++++++++----------------------- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index 9239152abf7a..109f1d343318 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -276,5 +276,6 @@ struct rds_rdma_notify { #define RDS_RDMA_USE_ONCE 0x0008 /* free MR after use */ #define RDS_RDMA_DONTWAIT 0x0010 /* Don't wait in SET_BARRIER */ #define RDS_RDMA_NOTIFY_ME 0x0020 /* Notify when operation completes */ +#define RDS_RDMA_SILENT 0x0040 /* Do not interrupt remote */ #endif /* IB_RDS_H */ diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 5ba514684431..48781fe4431c 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -559,6 +559,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, op->op_write = !!(args->flags & RDS_RDMA_READWRITE); op->op_fence = !!(args->flags & RDS_RDMA_FENCE); op->op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + op->op_silent = !!(args->flags & RDS_RDMA_SILENT); op->op_active = 1; op->op_recverr = rs->rs_recverr; WARN_ON(!nr_pages); @@ -747,6 +748,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, } rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT); rm->atomic.op_active = 1; rm->atomic.op_recverr = rs->rs_recverr; rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); diff --git a/net/rds/rds.h b/net/rds/rds.h index 46d190d08549..23b921000e74 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -319,6 +319,7 @@ struct rds_message { unsigned int op_notify:1; unsigned int op_recverr:1; unsigned int op_mapped:1; + unsigned int op_silent:1; unsigned int op_active:1; struct scatterlist *op_sg; struct rds_notifier *op_notifier; @@ -333,6 +334,7 @@ struct rds_message { unsigned int op_notify:1; unsigned int op_recverr:1; unsigned int op_mapped:1; + unsigned int op_silent:1; unsigned int op_active:1; unsigned int op_bytes; unsigned int op_nents; diff --git a/net/rds/send.c b/net/rds/send.c index cdca9747fcbc..38567f3ee7e8 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -250,42 +250,50 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_rm = rm; } - if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { - ret = conn->c_trans->xmit_atomic(conn, rm); + /* The transport either sends the whole rdma or none of it */ + if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { + ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); if (ret) break; - conn->c_xmit_atomic_sent = 1; + conn->c_xmit_rdma_sent = 1; + /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); - - /* - * This is evil, muahaha. - * We permit 0-byte sends. (rds-ping depends on this.) - * BUT if there is an atomic op and no sent data, - * we turn off sending the header, to achieve - * "silent" atomics. - * But see below; RDMA op might toggle this back on! - */ - if (rm->data.op_nents == 0) - rm->data.op_active = 0; } - /* The transport either sends the whole rdma or none of it */ - if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { - ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); + if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { + ret = conn->c_trans->xmit_atomic(conn, rm); if (ret) break; - conn->c_xmit_rdma_sent = 1; - - /* rdmas need data sent, even if just the header */ - rm->data.op_active = 1; - + conn->c_xmit_atomic_sent = 1; /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); } + /* + * A number of cases require an RDS header to be sent + * even if there is no data. + * We permit 0-byte sends; rds-ping depends on this. + * However, if there are exclusively attached silent ops, + * we skip the hdr/data send, to enable silent operation. + */ + if (rm->data.op_nents == 0) { + int ops_present; + int all_ops_are_silent = 1; + + ops_present = (rm->atomic.op_active || rm->rdma.op_active); + if (rm->atomic.op_active && !rm->atomic.op_silent) + all_ops_are_silent = 0; + if (rm->rdma.op_active && !rm->rdma.op_silent) + all_ops_are_silent = 0; + + if (ops_present && all_ops_are_silent + && !rm->m_rdma_cookie) + rm->data.op_active = 0; + } + if (rm->data.op_active && !conn->c_xmit_data_sent) { ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, @@ -1009,8 +1017,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (ret) goto out; - if ((rm->m_rdma_cookie || rm->rdma.op_active) && - !conn->c_trans->xmit_rdma) { + if (rm->rdma.op_active && !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", &rm->rdma, conn->c_trans->xmit_rdma); -- cgit v1.2.3 From aa0a4ef4ac3a3c5ffa35e32520bfbc0922ef3630 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 13 Apr 2010 12:00:35 -0700 Subject: RDS: Make sure cmsgs aren't used in improper ways It hasn't cropped up in the field, but this code ensures it is impossible to issue operations that pass an rdma cookie (DEST, MAP) in the same sendmsg call that's actually initiating rdma or atomic ops. Disallowing this perverse-but-technically-allowed usage makes silent RDMA heuristics slightly easier. Signed-off-by: Andy Grover --- net/rds/send.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/rds/send.c b/net/rds/send.c index 38567f3ee7e8..69ab1040d02d 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -846,6 +846,7 @@ static int rds_rm_size(struct msghdr *msg, int data_len) { struct cmsghdr *cmsg; int size = 0; + int cmsg_groups = 0; int retval; for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { @@ -857,19 +858,23 @@ static int rds_rm_size(struct msghdr *msg, int data_len) switch (cmsg->cmsg_type) { case RDS_CMSG_RDMA_ARGS: + cmsg_groups |= 1; retval = rds_rdma_extra_size(CMSG_DATA(cmsg)); if (retval < 0) return retval; size += retval; + break; case RDS_CMSG_RDMA_DEST: case RDS_CMSG_RDMA_MAP: + cmsg_groups |= 2; /* these are valid but do no add any size */ break; case RDS_CMSG_ATOMIC_CSWP: case RDS_CMSG_ATOMIC_FADD: + cmsg_groups |= 1; size += sizeof(struct scatterlist); break; @@ -881,6 +886,10 @@ static int rds_rm_size(struct msghdr *msg, int data_len) size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); + /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */ + if (cmsg_groups == 3) + return -EINVAL; + return size; } -- cgit v1.2.3 From ff3d7d36134ef7138803734fdbf91cc986ea7976 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 1 Mar 2010 14:03:09 -0800 Subject: RDS: Perform unmapping ops in stages Previously, RDS would wait until the final send WR had completed and then handle cleanup. With silent ops, we do not know if an atomic, rdma, or data op will be last. This patch handles any of these cases by keeping a pointer to the last op in the message in m_last_op. When the TX completion event fires, rds dispatches to per-op-type cleanup functions, and then does whole-message cleanup, if the last op equalled m_last_op. This patch also moves towards having op-specific functions take the op struct, instead of the overall rm struct. rds_ib_connection has a pointer to keep track of a a partially- completed data send operation. This patch changes it from an rds_message pointer to the narrower rm_data_op pointer, and modifies places that use this pointer as needed. Signed-off-by: Andy Grover --- net/rds/ib.h | 7 +- net/rds/ib_cm.c | 9 +- net/rds/ib_send.c | 242 ++++++++++++++++++++++++++++-------------------------- net/rds/rds.h | 4 +- net/rds/send.c | 6 +- 5 files changed, 142 insertions(+), 126 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index d64b5087eefe..202140a84f0c 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -53,8 +53,7 @@ struct rds_ib_connect_private { }; struct rds_ib_send_work { - struct rds_message *s_rm; - struct rm_rdma_op *s_op; + void *s_op; struct ib_send_wr s_wr; struct ib_sge s_sge[RDS_IB_MAX_SGE]; unsigned long s_queued; @@ -92,7 +91,7 @@ struct rds_ib_connection { /* tx */ struct rds_ib_work_ring i_send_ring; - struct rds_message *i_rm; + struct rm_data_op *i_data_op; struct rds_header *i_send_hdrs; u64 i_send_hdrs_dma; struct rds_ib_send_work *i_sends; @@ -336,7 +335,7 @@ void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, u32 *adv_credits, int need_posted, int max_posted); -int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm); +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 8b0c743c0900..b5b5ebbc0bb6 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -673,9 +673,12 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) BUG_ON(ic->rds_ibdev); /* Clear pending transmit */ - if (ic->i_rm) { - rds_message_put(ic->i_rm); - ic->i_rm = NULL; + if (ic->i_data_op) { + struct rds_message *rm; + + rm = container_of(ic->i_data_op, struct rds_message, data); + rds_message_put(rm); + ic->i_data_op = NULL; } /* Clear the ACK state */ diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 95f15247acd7..6461a152bd5b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -67,80 +67,122 @@ static void rds_ib_send_complete(struct rds_message *rm, complete(rm, notify_status); } -static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, - struct rds_ib_send_work *send, - int wc_status) +static void rds_ib_send_unmap_data(struct rds_ib_connection *ic, + struct rm_data_op *op, + int wc_status) { - struct rds_message *rm = send->s_rm; - - rdsdebug("ic %p send %p rm %p\n", ic, send, rm); - - ib_dma_unmap_sg(ic->i_cm_id->device, - rm->data.op_sg, rm->data.op_nents, - DMA_TO_DEVICE); + if (op->op_nents) + ib_dma_unmap_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, + DMA_TO_DEVICE); +} - if (rm->rdma.op_active) { - struct rm_rdma_op *op = &rm->rdma; +static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic, + struct rm_rdma_op *op, + int wc_status) +{ + if (op->op_mapped) { + ib_dma_unmap_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, + op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->op_mapped = 0; + } - if (op->op_mapped) { - ib_dma_unmap_sg(ic->i_cm_id->device, - op->op_sg, op->op_nents, - op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->op_mapped = 0; - } + /* If the user asked for a completion notification on this + * message, we can implement three different semantics: + * 1. Notify when we received the ACK on the RDS message + * that was queued with the RDMA. This provides reliable + * notification of RDMA status at the expense of a one-way + * packet delay. + * 2. Notify when the IB stack gives us the completion event for + * the RDMA operation. + * 3. Notify when the IB stack gives us the completion event for + * the accompanying RDS messages. + * Here, we implement approach #3. To implement approach #2, + * we would need to take an event for the rdma WR. To implement #1, + * don't call rds_rdma_send_complete at all, and fall back to the notify + * handling in the ACK processing code. + * + * Note: There's no need to explicitly sync any RDMA buffers using + * ib_dma_sync_sg_for_cpu - the completion for the RDMA + * operation itself unmapped the RDMA buffers, which takes care + * of synching. + */ + rds_ib_send_complete(container_of(op, struct rds_message, rdma), + wc_status, rds_rdma_send_complete); - /* If the user asked for a completion notification on this - * message, we can implement three different semantics: - * 1. Notify when we received the ACK on the RDS message - * that was queued with the RDMA. This provides reliable - * notification of RDMA status at the expense of a one-way - * packet delay. - * 2. Notify when the IB stack gives us the completion event for - * the RDMA operation. - * 3. Notify when the IB stack gives us the completion event for - * the accompanying RDS messages. - * Here, we implement approach #3. To implement approach #2, - * call rds_rdma_send_complete from the cq_handler. To implement #1, - * don't call rds_rdma_send_complete at all, and fall back to the notify - * handling in the ACK processing code. - * - * Note: There's no need to explicitly sync any RDMA buffers using - * ib_dma_sync_sg_for_cpu - the completion for the RDMA - * operation itself unmapped the RDMA buffers, which takes care - * of synching. - */ - rds_ib_send_complete(rm, wc_status, rds_rdma_send_complete); + if (op->op_write) + rds_stats_add(s_send_rdma_bytes, op->op_bytes); + else + rds_stats_add(s_recv_rdma_bytes, op->op_bytes); +} - if (rm->rdma.op_write) - rds_stats_add(s_send_rdma_bytes, rm->rdma.op_bytes); - else - rds_stats_add(s_recv_rdma_bytes, rm->rdma.op_bytes); +static void rds_ib_send_unmap_atomic(struct rds_ib_connection *ic, + struct rm_atomic_op *op, + int wc_status) +{ + /* unmap atomic recvbuf */ + if (op->op_mapped) { + ib_dma_unmap_sg(ic->i_cm_id->device, op->op_sg, 1, + DMA_FROM_DEVICE); + op->op_mapped = 0; } - if (rm->atomic.op_active) { - struct rm_atomic_op *op = &rm->atomic; - - /* unmap atomic recvbuf */ - if (op->op_mapped) { - ib_dma_unmap_sg(ic->i_cm_id->device, op->op_sg, 1, - DMA_FROM_DEVICE); - op->op_mapped = 0; - } + rds_ib_send_complete(container_of(op, struct rds_message, atomic), + wc_status, rds_atomic_send_complete); - rds_ib_send_complete(rm, wc_status, rds_atomic_send_complete); + if (op->op_type == RDS_ATOMIC_TYPE_CSWP) + rds_stats_inc(s_atomic_cswp); + else + rds_stats_inc(s_atomic_fadd); +} - if (rm->atomic.op_type == RDS_ATOMIC_TYPE_CSWP) - rds_stats_inc(s_atomic_cswp); - else - rds_stats_inc(s_atomic_fadd); +/* + * Unmap the resources associated with a struct send_work. + * + * Returns the rm for no good reason other than it is unobtainable + * other than by switching on wr.opcode, currently, and the caller, + * the event handler, needs it. + */ +static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic, + struct rds_ib_send_work *send, + int wc_status) +{ + struct rds_message *rm = NULL; + + /* In the error case, wc.opcode sometimes contains garbage */ + switch (send->s_wr.opcode) { + case IB_WR_SEND: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, data); + rds_ib_send_unmap_data(ic, send->s_op, wc_status); + } + break; + case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_READ: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, rdma); + rds_ib_send_unmap_rdma(ic, send->s_op, wc_status); + } + break; + case IB_WR_ATOMIC_FETCH_AND_ADD: + case IB_WR_ATOMIC_CMP_AND_SWP: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, atomic); + rds_ib_send_unmap_atomic(ic, send->s_op, wc_status); + } + break; + default: + if (printk_ratelimit()) + printk(KERN_NOTICE + "RDS/IB: %s: unexpected opcode 0x%x in WR!\n", + __func__, send->s_wr.opcode); + break; } - /* If anyone waited for this message to get flushed out, wake - * them up now */ - rds_message_unmapped(rm); + send->s_wr.opcode = 0xdead; - rds_message_put(rm); - send->s_rm = NULL; + return rm; } void rds_ib_send_init_ring(struct rds_ib_connection *ic) @@ -151,7 +193,6 @@ void rds_ib_send_init_ring(struct rds_ib_connection *ic) for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) { struct ib_sge *sge; - send->s_rm = NULL; send->s_op = NULL; send->s_wr.wr_id = i; @@ -173,9 +214,8 @@ void rds_ib_send_clear_ring(struct rds_ib_connection *ic) u32 i; for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) { - if (!send->s_rm || send->s_wr.opcode == 0xdead) - continue; - rds_ib_send_unmap_rm(ic, send, IB_WC_WR_FLUSH_ERR); + if (send->s_op && send->s_wr.opcode != 0xdead) + rds_ib_send_unmap_op(ic, send, IB_WC_WR_FLUSH_ERR); } } @@ -189,6 +229,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) { struct rds_connection *conn = context; struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_message *rm = NULL; struct ib_wc wc; struct rds_ib_send_work *send; u32 completed; @@ -222,42 +263,18 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) for (i = 0; i < completed; i++) { send = &ic->i_sends[oldest]; - /* In the error case, wc.opcode sometimes contains garbage */ - switch (send->s_wr.opcode) { - case IB_WR_SEND: - case IB_WR_RDMA_WRITE: - case IB_WR_RDMA_READ: - case IB_WR_ATOMIC_FETCH_AND_ADD: - case IB_WR_ATOMIC_CMP_AND_SWP: - if (send->s_rm) - rds_ib_send_unmap_rm(ic, send, wc.status); - break; - default: - if (printk_ratelimit()) - printk(KERN_NOTICE - "RDS/IB: %s: unexpected opcode 0x%x in WR!\n", - __func__, send->s_wr.opcode); - break; - } + rm = rds_ib_send_unmap_op(ic, send, wc.status); - send->s_wr.opcode = 0xdead; - send->s_wr.num_sge = 1; if (send->s_queued + HZ/2 < jiffies) rds_ib_stats_inc(s_ib_tx_stalled); - /* If a RDMA operation produced an error, signal this right - * away. If we don't, the subsequent SEND that goes with this - * RDMA will be canceled with ERR_WFLUSH, and the application - * never learn that the RDMA failed. */ - if (unlikely(wc.status == IB_WC_REM_ACCESS_ERR && send->s_op)) { - struct rds_message *rm; - - rm = rds_send_get_message(conn, send->s_op); - if (rm) { - rds_ib_send_unmap_rm(ic, send, wc.status); - rds_ib_send_complete(rm, wc.status, rds_rdma_send_complete); - rds_message_put(rm); - } + if (&send->s_op == &rm->m_final_op) { + /* If anyone waited for this message to get flushed out, wake + * them up now */ + rds_message_unmapped(rm); + + rds_message_put(rm); + send->s_op = NULL; } oldest = (oldest + 1) % ic->i_send_ring.w_nr; @@ -512,7 +529,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } /* map the message the first time we see it */ - if (!ic->i_rm) { + if (!ic->i_data_op) { if (rm->data.op_nents) { rm->data.op_count = ib_dma_map_sg(dev, rm->data.op_sg, @@ -530,7 +547,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } rds_message_addref(rm); - ic->i_rm = rm; + ic->i_data_op = &rm->data; /* Finalize the header */ if (test_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags)) @@ -583,7 +600,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->data.op_sg[sg]; + scat = &ic->i_data_op->op_sg[sg]; i = 0; do { unsigned int len = 0; @@ -658,9 +675,9 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* if we finished the message then send completion owns it */ if (scat == &rm->data.op_sg[rm->data.op_count]) { - prev->s_rm = ic->i_rm; + prev->s_op = ic->i_data_op; prev->s_wr.send_flags |= IB_SEND_SOLICITED; - ic->i_rm = NULL; + ic->i_data_op = NULL; } /* Put back wrs & credits we didn't use */ @@ -681,9 +698,9 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, printk(KERN_WARNING "RDS/IB: ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); - if (prev->s_rm) { - ic->i_rm = prev->s_rm; - prev->s_rm = NULL; + if (prev->s_op) { + ic->i_data_op = prev->s_op; + prev->s_op = NULL; } rds_ib_conn_error(ic->conn, "ib_post_send failed\n"); @@ -701,10 +718,9 @@ out: * A simplified version of the rdma case, we always map 1 SG, and * only 8 bytes, for the return value from the atomic operation. */ -int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm) +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) { struct rds_ib_connection *ic = conn->c_transport_data; - struct rm_atomic_op *op = &rm->atomic; struct rds_ib_send_work *send = NULL; struct ib_send_wr *failed_wr; struct rds_ib_device *rds_ibdev; @@ -741,14 +757,6 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rds_message *rm) send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; send->s_wr.wr.atomic.rkey = op->op_rkey; - /* - * If there is no data or rdma ops in the message, then - * we must fill in s_rm ourselves, so we properly clean up - * on completion. - */ - if (!rm->rdma.op_active && !rm->data.op_active) - send->s_rm = rm; - /* map 8 byte retval buffer to the device */ ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE); rdsdebug("ic %p mapping atomic op %p. mapped %d pg\n", ic, op, ret); @@ -809,7 +817,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - /* map the message the first time we see it */ + /* map the op the first time we see it */ if (!op->op_mapped) { op->op_count = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, op->op_nents, (op->op_write) ? diff --git a/net/rds/rds.h b/net/rds/rds.h index 23b921000e74..7291f006f364 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -308,6 +308,8 @@ struct rds_message { unsigned int m_used_sgs; unsigned int m_total_sgs; + void *m_final_op; + struct { struct rm_atomic_op { int op_type; @@ -421,7 +423,7 @@ struct rds_transport { int (*xmit_cong_map)(struct rds_connection *conn, struct rds_cong_map *map, unsigned long offset); int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); - int (*xmit_atomic)(struct rds_connection *conn, struct rds_message *rm); + int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/send.c b/net/rds/send.c index 69ab1040d02d..d1f364e44e36 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -252,6 +252,7 @@ int rds_send_xmit(struct rds_connection *conn) /* The transport either sends the whole rdma or none of it */ if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { + rm->m_final_op = &rm->rdma; ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); if (ret) break; @@ -263,10 +264,12 @@ int rds_send_xmit(struct rds_connection *conn) } if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { - ret = conn->c_trans->xmit_atomic(conn, rm); + rm->m_final_op = &rm->atomic; + ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); if (ret) break; conn->c_xmit_atomic_sent = 1; + /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); @@ -295,6 +298,7 @@ int rds_send_xmit(struct rds_connection *conn) } if (rm->data.op_active && !conn->c_xmit_data_sent) { + rm->m_final_op = &rm->data; ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, -- cgit v1.2.3 From e32b4a70495aac6a612e13f4c21db09dd756ff2c Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 3 Mar 2010 19:25:21 -0800 Subject: RDS/IB: Do not wait for send ring to be empty on conn shutdown Now that we are signaling send completions much less, we are likely to have dirty entries in the send queue when the connection is shut down (on rmmod, for example.) These are cleaned up a little further down in conn_shutdown, but if we wait on the ring_empty_wait for them, it'll never happen, and we hand on unload. Signed-off-by: Andy Grover --- net/rds/ib_cm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index b5b5ebbc0bb6..1a91af75f4c7 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -620,8 +620,11 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) ic->i_cm_id, err); } + /* + * Don't wait for the send ring to be empty -- there may be completed + * non-signaled entries sitting on there. We unmap these below. + */ wait_event(rds_ib_ring_empty_wait, - rds_ib_ring_empty(&ic->i_send_ring) && rds_ib_ring_empty(&ic->i_recv_ring)); if (ic->i_send_hdrs) -- cgit v1.2.3 From 77dd550e5547846604ff6f90c4dc6bba4414e485 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 22 Mar 2010 15:22:04 -0700 Subject: RDS: Stop supporting old cong map sending method We now ask the transport to give us a rm for the congestion map, and then we handle it normally. Previously, the transport defined a function that we would call to send a congestion map. Convert TCP and loop transports to new cong map method. Signed-off-by: Andy Grover --- net/rds/ib.c | 1 - net/rds/iw.c | 1 - net/rds/loop.c | 19 ++++++------------- net/rds/rds.h | 6 ------ net/rds/send.c | 39 +++++++-------------------------------- net/rds/tcp.c | 1 - net/rds/tcp.h | 2 -- net/rds/tcp_send.c | 50 -------------------------------------------------- 8 files changed, 13 insertions(+), 106 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 932dacbdbea1..927c481b5245 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -265,7 +265,6 @@ struct rds_transport rds_ib_transport = { .laddr_check = rds_ib_laddr_check, .xmit_complete = rds_ib_xmit_complete, .xmit = rds_ib_xmit, - .xmit_cong_map = NULL, .xmit_rdma = rds_ib_xmit_rdma, .xmit_atomic = rds_ib_xmit_atomic, .recv = rds_ib_recv, diff --git a/net/rds/iw.c b/net/rds/iw.c index e766aecd46c9..467790da1316 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -264,7 +264,6 @@ struct rds_transport rds_iw_transport = { .laddr_check = rds_iw_laddr_check, .xmit_complete = rds_iw_xmit_complete, .xmit = rds_iw_xmit, - .xmit_cong_map = NULL, .xmit_rdma = rds_iw_xmit_rdma, .recv = rds_iw_recv, .conn_alloc = rds_iw_conn_alloc, diff --git a/net/rds/loop.c b/net/rds/loop.c index 4a3dd49315b4..c390156b426f 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -61,6 +61,12 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) { + /* Do not send cong updates to loopback */ + if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { + rds_cong_map_updated(conn->c_fcong, ~(u64) 0); + return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; + } + BUG_ON(hdr_off || sg || off); rds_inc_init(&rm->m_inc, conn, conn->c_laddr); @@ -88,18 +94,6 @@ static void rds_loop_inc_free(struct rds_incoming *inc) rds_message_put(rm); } -static int rds_loop_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, - unsigned long offset) -{ - BUG_ON(offset); - BUG_ON(map != conn->c_lcong); - - rds_cong_map_updated(conn->c_fcong, ~(u64) 0); - - return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; -} - /* we need to at least give the thread something to succeed */ static int rds_loop_recv(struct rds_connection *conn) { @@ -180,7 +174,6 @@ void rds_loop_exit(void) */ struct rds_transport rds_loop_transport = { .xmit = rds_loop_xmit, - .xmit_cong_map = rds_loop_xmit_cong_map, .recv = rds_loop_recv, .conn_alloc = rds_loop_conn_alloc, .conn_free = rds_loop_conn_free, diff --git a/net/rds/rds.h b/net/rds/rds.h index 7291f006f364..e81d7e478474 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -393,10 +393,6 @@ struct rds_notifier { * transport is responsible for other serialization, including * rds_recv_incoming(). This is called in process context but * should try hard not to block. - * - * @xmit_cong_map: This asks the transport to send the local bitmap down the - * given connection. XXX get a better story about the bitmap - * flag and header. */ #define RDS_TRANS_IB 0 @@ -420,8 +416,6 @@ struct rds_transport { void (*xmit_complete)(struct rds_connection *conn); int (*xmit)(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); - int (*xmit_cong_map)(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset); int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); int (*recv)(struct rds_connection *conn); diff --git a/net/rds/send.c b/net/rds/send.c index d1f364e44e36..8a0647af5d95 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -147,41 +147,16 @@ int rds_send_xmit(struct rds_connection *conn) /* * If between sending messages, we can send a pending congestion * map update. - * - * Transports either define a special xmit_cong_map function, - * or we allocate a cong_map message and treat it just like any - * other send. */ if (!rm && test_and_clear_bit(0, &conn->c_map_queued)) { - if (conn->c_trans->xmit_cong_map) { - unsigned long map_offset = 0; - unsigned long map_bytes = sizeof(struct rds_header) + - RDS_CONG_MAP_BYTES; - - while (map_bytes) { - ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong, - map_offset); - if (ret <= 0) { - /* too far down the rabbithole! */ - mutex_unlock(&conn->c_send_lock); - rds_conn_error(conn, "Cong map xmit failed\n"); - goto out; - } - - map_offset += ret; - map_bytes -= ret; - } - } else { - /* send cong update like a normal rm */ - rm = rds_cong_update_alloc(conn); - if (IS_ERR(rm)) { - ret = PTR_ERR(rm); - break; - } - rm->data.op_active = 1; - - conn->c_xmit_rm = rm; + rm = rds_cong_update_alloc(conn); + if (IS_ERR(rm)) { + ret = PTR_ERR(rm); + break; } + rm->data.op_active = 1; + + conn->c_xmit_rm = rm; } /* diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 831881640e56..3262992f5f2b 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -258,7 +258,6 @@ struct rds_transport rds_tcp_transport = { .laddr_check = rds_tcp_laddr_check, .xmit_prepare = rds_tcp_xmit_prepare, .xmit_complete = rds_tcp_xmit_complete, - .xmit_cong_map = rds_tcp_xmit_cong_map, .xmit = rds_tcp_xmit, .recv = rds_tcp_recv, .conn_alloc = rds_tcp_conn_alloc, diff --git a/net/rds/tcp.h b/net/rds/tcp.h index c639872bf701..16b166379ea9 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -80,8 +80,6 @@ void rds_tcp_xmit_complete(struct rds_connection *conn); int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); void rds_tcp_write_space(struct sock *sk); -int rds_tcp_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset); /* tcp_stats.c */ DECLARE_PER_CPU(struct rds_tcp_statistics, rds_tcp_stats); diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index 53c1de55f471..2979fb4a4b9a 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -76,56 +76,6 @@ int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len); } -/* the core send_sem serializes this with other xmit and shutdown */ -int rds_tcp_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset) -{ - static struct rds_header rds_tcp_map_header = { - .h_flags = RDS_FLAG_CONG_BITMAP, - }; - struct rds_tcp_connection *tc = conn->c_transport_data; - unsigned long i; - int ret; - int copied = 0; - - /* Some problem claims cpu_to_be32(constant) isn't a constant. */ - rds_tcp_map_header.h_len = cpu_to_be32(RDS_CONG_MAP_BYTES); - - if (offset < sizeof(struct rds_header)) { - ret = rds_tcp_sendmsg(tc->t_sock, - (void *)&rds_tcp_map_header + offset, - sizeof(struct rds_header) - offset); - if (ret <= 0) - return ret; - offset += ret; - copied = ret; - if (offset < sizeof(struct rds_header)) - return ret; - } - - offset -= sizeof(struct rds_header); - i = offset / PAGE_SIZE; - offset = offset % PAGE_SIZE; - BUG_ON(i >= RDS_CONG_MAP_PAGES); - - do { - ret = tc->t_sock->ops->sendpage(tc->t_sock, - virt_to_page(map->m_page_addrs[i]), - offset, PAGE_SIZE - offset, - MSG_DONTWAIT); - if (ret <= 0) - break; - copied += ret; - offset += ret; - if (offset == PAGE_SIZE) { - offset = 0; - i++; - } - } while (i < RDS_CONG_MAP_PAGES); - - return copied ? copied : ret; -} - /* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) -- cgit v1.2.3 From f17a1a55fb672d7f64be7f2e940ef5669e5efa0a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 18 Mar 2010 17:19:52 -0700 Subject: RDS: Refill recv ring directly from tasklet Performance is better if we use allocations that don't block to refill the receive ring. Since the whole reason we were kicking out to the worker thread was so we could do blocking allocs, we no longer need to do this. Remove gfp params from rds_ib_recv_refill(); we always use GFP_NOWAIT. Signed-off-by: Andy Grover --- net/rds/ib.h | 3 +-- net/rds/ib_cm.c | 2 +- net/rds/ib_recv.c | 22 ++++++++-------------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 202140a84f0c..4c2ee2401979 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -297,8 +297,7 @@ void rds_ib_flush_mrs(void); int __init rds_ib_recv_init(void); void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); -int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, - gfp_t page_gfp, int prefill); +int rds_ib_recv_refill(struct rds_connection *conn, int prefill); void rds_ib_inc_free(struct rds_incoming *inc); int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 1a91af75f4c7..75eda9c82135 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -135,7 +135,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even rds_ib_recv_init_ring(ic); /* Post receive buffers - as a side effect, this will update * the posted credit count. */ - rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1); + rds_ib_recv_refill(conn, 1); /* Tune RNR behavior */ rds_ib_tune_rnr(ic, &qp_attr); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index e9fe08a86c40..8f041f7954a2 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -135,8 +135,7 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic) } static int rds_ib_recv_refill_one(struct rds_connection *conn, - struct rds_ib_recv_work *recv, - gfp_t kptr_gfp, gfp_t page_gfp) + struct rds_ib_recv_work *recv) { struct rds_ib_connection *ic = conn->c_transport_data; dma_addr_t dma_addr; @@ -148,8 +147,7 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, rds_ib_stats_inc(s_ib_rx_alloc_limit); goto out; } - recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, - kptr_gfp); + recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, GFP_NOWAIT); if (!recv->r_ibinc) { atomic_dec(&rds_ib_allocation); goto out; @@ -159,7 +157,7 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, } if (!recv->r_frag) { - recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, kptr_gfp); + recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); if (!recv->r_frag) goto out; INIT_LIST_HEAD(&recv->r_frag->f_item); @@ -167,7 +165,7 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, } if (!ic->i_frag.f_page) { - ic->i_frag.f_page = alloc_page(page_gfp); + ic->i_frag.f_page = alloc_page(GFP_NOWAIT); if (!ic->i_frag.f_page) goto out; ic->i_frag.f_offset = 0; @@ -221,8 +219,7 @@ out: * * -1 is returned if posting fails due to temporary resource exhaustion. */ -int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, - gfp_t page_gfp, int prefill) +int rds_ib_recv_refill(struct rds_connection *conn, int prefill) { struct rds_ib_connection *ic = conn->c_transport_data; struct rds_ib_recv_work *recv; @@ -241,7 +238,7 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, } recv = &ic->i_recvs[pos]; - ret = rds_ib_recv_refill_one(conn, recv, kptr_gfp, page_gfp); + ret = rds_ib_recv_refill_one(conn, recv); if (ret) { ret = -1; break; @@ -856,11 +853,8 @@ void rds_ib_recv_tasklet_fn(unsigned long data) if (rds_ib_ring_empty(&ic->i_recv_ring)) rds_ib_stats_inc(s_ib_rx_ring_empty); - /* - * If the ring is running low, then schedule the thread to refill. - */ if (rds_ib_ring_low(&ic->i_recv_ring)) - queue_delayed_work(rds_wq, &conn->c_recv_w, 0); + rds_ib_recv_refill(conn, 0); } int rds_ib_recv(struct rds_connection *conn) @@ -875,7 +869,7 @@ int rds_ib_recv(struct rds_connection *conn) * we're really low and we want the caller to back off for a bit. */ mutex_lock(&ic->i_recv_mutex); - if (rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 0)) + if (rds_ib_recv_refill(conn, 0)) ret = -ENOMEM; else rds_ib_stats_inc(s_ib_rx_refill_from_thread); -- cgit v1.2.3 From 049ee3f500954176a87f22e6ee3e98aecb1b8958 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 23 Mar 2010 17:39:07 -0700 Subject: RDS: Change send lock from a mutex to a spinlock This change allows us to call rds_send_xmit() from a tasklet, which is crucial to our new operating model. * Change c_send_lock to a spinlock * Update stats fields "sem_" to "_lock" * Remove unneeded rds_conn_is_sending() About locking between shutdown and send -- send checks if the connection is up. Shutdown puts the connection into DISCONNECTING. After this, all threads entering send will exit immediately. However, a thread could be *in* send_xmit(), so shutdown acquires the c_send_lock to ensure everyone is out before proceeding with connection shutdown. Signed-off-by: Andy Grover --- net/rds/connection.c | 22 ++++++---------------- net/rds/rds.h | 6 +++--- net/rds/send.c | 15 +++++++-------- net/rds/stats.c | 4 ++-- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 88bcaf3f3e16..56aebe444ad3 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -62,18 +62,6 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) var |= RDS_INFO_CONNECTION_FLAG_##suffix; \ } while (0) -static inline int rds_conn_is_sending(struct rds_connection *conn) -{ - int ret = 0; - - if (!mutex_trylock(&conn->c_send_lock)) - ret = 1; - else - mutex_unlock(&conn->c_send_lock); - - return ret; -} - static struct rds_connection *rds_conn_lookup(struct hlist_head *head, __be32 laddr, __be32 faddr, struct rds_transport *trans) @@ -158,7 +146,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, spin_lock_init(&conn->c_lock); conn->c_next_tx_seq = 1; - mutex_init(&conn->c_send_lock); + spin_lock_init(&conn->c_send_lock); INIT_LIST_HEAD(&conn->c_send_queue); INIT_LIST_HEAD(&conn->c_retrans); @@ -283,10 +271,12 @@ void rds_conn_shutdown(struct rds_connection *conn) } mutex_unlock(&conn->c_cm_lock); - mutex_lock(&conn->c_send_lock); + /* verify everybody's out of rds_send_xmit() */ + spin_lock_irq(&conn->c_send_lock); + spin_unlock_irq(&conn->c_send_lock); + conn->c_trans->conn_shutdown(conn); rds_conn_reset(conn); - mutex_unlock(&conn->c_send_lock); if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { /* This can happen - eg when we're in the middle of tearing @@ -476,7 +466,7 @@ static int rds_conn_info_visitor(struct rds_connection *conn, cinfo->flags = 0; rds_conn_info_set(cinfo->flags, - rds_conn_is_sending(conn), SENDING); + spin_is_locked(&conn->c_send_lock), SENDING); /* XXX Future: return the state rather than these funky bits */ rds_conn_info_set(cinfo->flags, atomic_read(&conn->c_state) == RDS_CONN_CONNECTING, diff --git a/net/rds/rds.h b/net/rds/rds.h index e81d7e478474..c3a668b9cc14 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -91,7 +91,7 @@ struct rds_connection { struct rds_cong_map *c_lcong; struct rds_cong_map *c_fcong; - struct mutex c_send_lock; /* protect send ring */ + spinlock_t c_send_lock; /* protect send ring */ struct rds_message *c_xmit_rm; unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; @@ -548,8 +548,8 @@ struct rds_statistics { uint64_t s_recv_ping; uint64_t s_send_queue_empty; uint64_t s_send_queue_full; - uint64_t s_send_sem_contention; - uint64_t s_send_sem_queue_raced; + uint64_t s_send_lock_contention; + uint64_t s_send_lock_queue_raced; uint64_t s_send_immediate_retry; uint64_t s_send_delayed_retry; uint64_t s_send_drop_acked; diff --git a/net/rds/send.c b/net/rds/send.c index 8a0647af5d95..d4feec6ad09c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -116,19 +116,18 @@ int rds_send_xmit(struct rds_connection *conn) int was_empty = 0; LIST_HEAD(to_be_dropped); + if (!rds_conn_up(conn)) + goto out; + /* * sendmsg calls here after having queued its message on the send * queue. We only have one task feeding the connection at a time. If * another thread is already feeding the queue then we back off. This * avoids blocking the caller and trading per-connection data between * caches per message. - * - * The sem holder will issue a retry if they notice that someone queued - * a message after they stopped walking the send queue but before they - * dropped the sem. */ - if (!mutex_trylock(&conn->c_send_lock)) { - rds_stats_inc(s_send_sem_contention); + if (!spin_trylock_irqsave(&conn->c_send_lock, flags)) { + rds_stats_inc(s_send_lock_contention); ret = -ENOMEM; goto out; } @@ -346,7 +345,7 @@ int rds_send_xmit(struct rds_connection *conn) * stop processing the loop when the transport hasn't taken * responsibility for forward progress. */ - mutex_unlock(&conn->c_send_lock); + spin_unlock_irqrestore(&conn->c_send_lock, flags); if (send_quota == 0 && !was_empty) { /* We exhausted the send quota, but there's work left to @@ -360,7 +359,7 @@ int rds_send_xmit(struct rds_connection *conn) * spin lock */ spin_lock_irqsave(&conn->c_lock, flags); if (!list_empty(&conn->c_send_queue)) { - rds_stats_inc(s_send_sem_queue_raced); + rds_stats_inc(s_send_lock_queue_raced); ret = -EAGAIN; } spin_unlock_irqrestore(&conn->c_lock, flags); diff --git a/net/rds/stats.c b/net/rds/stats.c index c66d95d9c262..b77be8be33ba 100644 --- a/net/rds/stats.c +++ b/net/rds/stats.c @@ -57,8 +57,8 @@ static const char *const rds_stat_names[] = { "recv_ping", "send_queue_empty", "send_queue_full", - "send_sem_contention", - "send_sem_queue_raced", + "send_lock_contention", + "send_lock_queue_raced", "send_immediate_retry", "send_delayed_retry", "send_drop_acked", -- cgit v1.2.3 From 2ad8099b58f274dc23bc866ca259d7e5db87fa1a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 23 Mar 2010 17:48:04 -0700 Subject: RDS: rds_send_xmit() locking/irq fixes rds_message_put() cannot be called with irqs off, so move it after irqs are re-enabled. Spinlocks throughout the function do not to use _irqsave because the lock of c_send_lock at top already disabled irqs. Signed-off-by: Andy Grover --- net/rds/send.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index d4feec6ad09c..624a3dc7f060 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -168,7 +168,7 @@ int rds_send_xmit(struct rds_connection *conn) if (!rm) { unsigned int len; - spin_lock_irqsave(&conn->c_lock, flags); + spin_lock(&conn->c_lock); if (!list_empty(&conn->c_send_queue)) { rm = list_entry(conn->c_send_queue.next, @@ -183,7 +183,7 @@ int rds_send_xmit(struct rds_connection *conn) list_move_tail(&rm->m_conn_item, &conn->c_retrans); } - spin_unlock_irqrestore(&conn->c_lock, flags); + spin_unlock(&conn->c_lock); if (!rm) { was_empty = 1; @@ -199,11 +199,10 @@ int rds_send_xmit(struct rds_connection *conn) */ if (rm->rdma.op_active && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { - spin_lock_irqsave(&conn->c_lock, flags); + spin_lock(&conn->c_lock); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) list_move(&rm->m_conn_item, &to_be_dropped); - spin_unlock_irqrestore(&conn->c_lock, flags); - rds_message_put(rm); + spin_unlock(&conn->c_lock); continue; } @@ -326,10 +325,6 @@ int rds_send_xmit(struct rds_connection *conn) } } - /* Nuke any messages we decided not to retransmit. */ - if (!list_empty(&to_be_dropped)) - rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); - if (conn->c_trans->xmit_complete) conn->c_trans->xmit_complete(conn); @@ -347,6 +342,14 @@ int rds_send_xmit(struct rds_connection *conn) */ spin_unlock_irqrestore(&conn->c_send_lock, flags); + /* Nuke any messages we decided not to retransmit. */ + if (!list_empty(&to_be_dropped)) { + /* irqs on here, so we can put(), unlike above */ + list_for_each_entry(rm, &to_be_dropped, m_conn_item) + rds_message_put(rm); + rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); + } + if (send_quota == 0 && !was_empty) { /* We exhausted the send quota, but there's work left to * do. Return and (re-)schedule the send worker. -- cgit v1.2.3 From a7d3a281483684f77e350b045af7f80a149fc4c7 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:20:18 -0700 Subject: RDS: Call rds_send_xmit() directly from sendmsg() rds_sendmsg() is calling the send worker function to send the just-queued datagrams, presumably because it wants the behavior where anything not sent will re-call the send worker. We now ensure all queued datagrams are sent by retrying from the send completion handler, so this isn't needed any more. Signed-off-by: Andy Grover --- net/rds/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/send.c b/net/rds/send.c index 624a3dc7f060..15b715a85fd5 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -1073,7 +1073,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, rds_stats_inc(s_send_queued); if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) - rds_send_worker(&conn->c_send_w.work); + rds_send_xmit(conn); rds_message_put(rm); return payload_len; -- cgit v1.2.3 From 2fa57129df61bf3fb7d90c5486fe15df94091f61 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:45:40 -0700 Subject: RDS: Bypass workqueue when queueing cong updates Now that rds_send_xmit() does not block, we can call it directly instead of going through the helper thread. Signed-off-by: Andy Grover --- net/rds/cong.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/cong.c b/net/rds/cong.c index c741e906d49f..75ea686f27d5 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -221,7 +221,7 @@ void rds_cong_queue_updates(struct rds_cong_map *map) list_for_each_entry(conn, &map->m_conn_list, c_map_item) { if (!test_and_set_bit(0, &conn->c_map_queued)) { rds_stats_inc(s_cong_update_queued); - queue_delayed_work(rds_wq, &conn->c_send_w, 0); + rds_send_xmit(conn); } } -- cgit v1.2.3 From f2ec76f288118fb18449402d75383212cbcb6762 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:46:46 -0700 Subject: RDS: Use NOWAIT in message_map_pages() Can no longer block, so use NOWAIT. Signed-off-by: Andy Grover --- net/rds/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/message.c b/net/rds/message.c index 1f73a7358a8e..dd915e3e492d 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -256,7 +256,7 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in int num_sgs = ceil(total_len, PAGE_SIZE); int extra_bytes = num_sgs * sizeof(struct scatterlist); - rm = rds_message_alloc(extra_bytes, GFP_KERNEL); + rm = rds_message_alloc(extra_bytes, GFP_NOWAIT); if (!rm) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From cf4b7389ee812817deeb11da1422004e01b50646 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:50:54 -0700 Subject: RDS: Fix locking in send on m_rs_lock Do not nest m_rs_lock under c_lock Disable interrupts in {rdma,atomic}_send_complete Signed-off-by: Andy Grover --- net/rds/send.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index 15b715a85fd5..ecda3e6c432c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -468,8 +468,9 @@ void rds_atomic_send_complete(struct rds_message *rm, int status) struct rds_sock *rs = NULL; struct rm_atomic_op *ao; struct rds_notifier *notifier; + unsigned long flags; - spin_lock(&rm->m_rs_lock); + spin_lock_irqsave(&rm->m_rs_lock, flags); ao = &rm->atomic; if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) @@ -486,7 +487,7 @@ void rds_atomic_send_complete(struct rds_message *rm, int status) ao->op_notifier = NULL; } - spin_unlock(&rm->m_rs_lock); + spin_unlock_irqrestore(&rm->m_rs_lock, flags); if (rs) { rds_wake_sk_sleep(rs); -- cgit v1.2.3 From ab1a6926f589c51e7a57ce7544d85272c4acc854 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 16:52:12 -0700 Subject: RDS: rds_message_unmapped() doesn't need to check if queue active If the queue has nobody on it, then wake_up does nothing. Signed-off-by: Andy Grover --- net/rds/message.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index dd915e3e492d..9122b5392111 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -406,8 +406,7 @@ void rds_message_wait(struct rds_message *rm) void rds_message_unmapped(struct rds_message *rm) { clear_bit(RDS_MSG_MAPPED, &rm->m_flags); - if (waitqueue_active(&rds_message_flush_waitq)) - wake_up(&rds_message_flush_waitq); + wake_up(&rds_message_flush_waitq); } EXPORT_SYMBOL_GPL(rds_message_unmapped); -- cgit v1.2.3 From 51e2cba8b5936c13b40f0fa11aa4e84683dbc751 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 17:47:30 -0700 Subject: RDS: Move atomic stats from general to ib-specific area Signed-off-by: Andy Grover --- net/rds/ib.h | 2 ++ net/rds/ib_send.c | 4 ++-- net/rds/ib_stats.c | 2 ++ net/rds/rds.h | 2 -- net/rds/stats.c | 2 -- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 4c2ee2401979..c506604325d5 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -202,6 +202,8 @@ struct rds_ib_statistics { uint64_t s_ib_rdma_mr_pool_flush; uint64_t s_ib_rdma_mr_pool_wait; uint64_t s_ib_rdma_mr_pool_depleted; + uint64_t s_ib_atomic_cswp; + uint64_t s_ib_atomic_fadd; }; extern struct workqueue_struct *rds_ib_wq; diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 6461a152bd5b..657037d96cbf 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -132,9 +132,9 @@ static void rds_ib_send_unmap_atomic(struct rds_ib_connection *ic, wc_status, rds_atomic_send_complete); if (op->op_type == RDS_ATOMIC_TYPE_CSWP) - rds_stats_inc(s_atomic_cswp); + rds_ib_stats_inc(s_ib_atomic_cswp); else - rds_stats_inc(s_atomic_fadd); + rds_ib_stats_inc(s_ib_atomic_fadd); } /* diff --git a/net/rds/ib_stats.c b/net/rds/ib_stats.c index d2c904dd6fbc..2d5965d6e97c 100644 --- a/net/rds/ib_stats.c +++ b/net/rds/ib_stats.c @@ -67,6 +67,8 @@ static const char *const rds_ib_stat_names[] = { "ib_rdma_mr_pool_flush", "ib_rdma_mr_pool_wait", "ib_rdma_mr_pool_depleted", + "ib_atomic_cswp", + "ib_atomic_fadd", }; unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter, diff --git a/net/rds/rds.h b/net/rds/rds.h index c3a668b9cc14..2f19d49fac9c 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -566,8 +566,6 @@ struct rds_statistics { uint64_t s_cong_update_received; uint64_t s_cong_send_error; uint64_t s_cong_send_blocked; - uint64_t s_atomic_cswp; - uint64_t s_atomic_fadd; }; /* af_rds.c */ diff --git a/net/rds/stats.c b/net/rds/stats.c index b77be8be33ba..344929a663e5 100644 --- a/net/rds/stats.c +++ b/net/rds/stats.c @@ -75,8 +75,6 @@ static const char *const rds_stat_names[] = { "cong_update_received", "cong_send_error", "cong_send_blocked", - "s_atomic_cswp", - "s_atomic_fadd", }; void rds_stats_info_copy(struct rds_info_iterator *iter, -- cgit v1.2.3 From fcc5450c6386526034edc437e4cb2c67a6fdd7e9 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 17:08:49 -0700 Subject: RDS: Remove send_quota from send_xmit() The purpose of the send quota was really to give fairness when different connections were all using the same workq thread to send backlogged msgs -- they could only send so many before another connection could make progress. Now that each connection is pushing the backlog from its completion handler, they are all guaranteed to make progress and the quota isn't needed any longer. A thread *will* have to send all previously queued data, as well as any further msgs placed on the queue while while c_send_lock was held. In a pathological case a single process can get roped into doing this for long periods while other threads get off free. But, since it can only do this until the transport reports full, this is a bounded scenario. Signed-off-by: Andy Grover --- net/rds/send.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index ecda3e6c432c..656c5c1b32bc 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -110,12 +110,11 @@ int rds_send_xmit(struct rds_connection *conn) struct rds_message *rm; unsigned long flags; unsigned int tmp; - unsigned int send_quota = send_batch_count; struct scatterlist *sg; int ret = 0; - int was_empty = 0; LIST_HEAD(to_be_dropped); +restart: if (!rds_conn_up(conn)) goto out; @@ -139,7 +138,7 @@ int rds_send_xmit(struct rds_connection *conn) * spin trying to push headers and data down the connection until * the connection doesn't make forward progress. */ - while (--send_quota) { + while (1) { rm = conn->c_xmit_rm; @@ -185,10 +184,8 @@ int rds_send_xmit(struct rds_connection *conn) spin_unlock(&conn->c_lock); - if (!rm) { - was_empty = 1; + if (!rm) break; - } /* Unfortunately, the way Infiniband deals with * RDMA to a bad MR key is by moving the entire @@ -350,20 +347,23 @@ int rds_send_xmit(struct rds_connection *conn) rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); } - if (send_quota == 0 && !was_empty) { - /* We exhausted the send quota, but there's work left to - * do. Return and (re-)schedule the send worker. - */ - ret = -EAGAIN; - } - - if (ret == 0 && was_empty) { + /* + * Other senders will see we have c_send_lock and exit. We + * need to recheck the send queue and race again for c_send_lock + * to make sure messages don't just sit on the send queue. + * + * If the transport cannot continue (i.e ret != 0), then it must + * call us when more room is available, such as from the tx + * completion handler. + */ + if (ret == 0) { /* A simple bit test would be way faster than taking the * spin lock */ spin_lock_irqsave(&conn->c_lock, flags); if (!list_empty(&conn->c_send_queue)) { rds_stats_inc(s_send_lock_queue_raced); - ret = -EAGAIN; + spin_unlock_irqrestore(&conn->c_lock, flags); + goto restart; } spin_unlock_irqrestore(&conn->c_lock, flags); } -- cgit v1.2.3 From a40aa9233aa22d69212d02f92e5b607bd4d658f4 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 29 Mar 2010 17:10:01 -0700 Subject: RDS: Do wait_event_interruptible instead of wait_event Can't see a reason not to allow signals to interrupt the wait. Signed-off-by: Andy Grover --- net/rds/message.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 9122b5392111..4cb1ed704153 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -399,14 +399,14 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, */ void rds_message_wait(struct rds_message *rm) { - wait_event(rds_message_flush_waitq, + wait_event_interruptible(rds_message_flush_waitq, !test_bit(RDS_MSG_MAPPED, &rm->m_flags)); } void rds_message_unmapped(struct rds_message *rm) { clear_bit(RDS_MSG_MAPPED, &rm->m_flags); - wake_up(&rds_message_flush_waitq); + wake_up_interruptible(&rds_message_flush_waitq); } EXPORT_SYMBOL_GPL(rds_message_unmapped); -- cgit v1.2.3 From acfcd4d4ec4ed8cb504f96d4fabb7a94029b362b Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 31 Mar 2010 18:56:25 -0700 Subject: RDS: Get pong working again Call send_xmit() directly from pong() Set pongs as op_active Signed-off-by: Andy Grover --- net/rds/send.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/rds/send.c b/net/rds/send.c index 656c5c1b32bc..de5693cdcefb 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -1108,6 +1108,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) } rm->m_daddr = conn->c_faddr; + rm->data.op_active = 1; /* If the connection is down, trigger a connect. We may * have scheduled a delayed reconnect however - in this case @@ -1135,7 +1136,9 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) rds_stats_inc(s_send_queued); rds_stats_inc(s_send_pong); - queue_delayed_work(rds_wq, &conn->c_send_w, 0); + if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) + rds_send_xmit(conn); + rds_message_put(rm); return 0; -- cgit v1.2.3 From 9e29db0e3645cafa980e68a9c717a761448389e1 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 15 Apr 2010 16:38:14 -0400 Subject: RDS: Use a generation counter to avoid rds_send_xmit loop rds_send_xmit is required to loop around after it releases the lock because someone else could done a trylock, found someone working on the list and backed off. But, once we drop our lock, it is possible that someone else does come in and make progress on the list. We should detect this and not loop around if another process is actually working on the list. This patch adds a generation counter that is bumped every time we get the lock and do some send work. If the retry notices someone else has bumped the generation counter, it does not need to loop around and continue working. Signed-off-by: Chris Mason Signed-off-by: Andy Grover --- net/rds/connection.c | 1 + net/rds/rds.h | 1 + net/rds/send.c | 11 +++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 56aebe444ad3..7e4e9dfdbc0b 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -147,6 +147,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, conn->c_next_tx_seq = 1; spin_lock_init(&conn->c_send_lock); + atomic_set(&conn->c_send_generation, 1); INIT_LIST_HEAD(&conn->c_send_queue); INIT_LIST_HEAD(&conn->c_retrans); diff --git a/net/rds/rds.h b/net/rds/rds.h index 2f19d49fac9c..b57cb50c1f22 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -92,6 +92,7 @@ struct rds_connection { struct rds_cong_map *c_fcong; spinlock_t c_send_lock; /* protect send ring */ + atomic_t c_send_generation; struct rds_message *c_xmit_rm; unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; diff --git a/net/rds/send.c b/net/rds/send.c index de5693cdcefb..663fd60b40cf 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -112,6 +112,7 @@ int rds_send_xmit(struct rds_connection *conn) unsigned int tmp; struct scatterlist *sg; int ret = 0; + int gen = 0; LIST_HEAD(to_be_dropped); restart: @@ -134,6 +135,8 @@ restart: if (conn->c_trans->xmit_prepare) conn->c_trans->xmit_prepare(conn); + gen = atomic_inc_return(&conn->c_send_generation); + /* * spin trying to push headers and data down the connection until * the connection doesn't make forward progress. @@ -359,13 +362,13 @@ restart: if (ret == 0) { /* A simple bit test would be way faster than taking the * spin lock */ - spin_lock_irqsave(&conn->c_lock, flags); + smp_mb(); if (!list_empty(&conn->c_send_queue)) { rds_stats_inc(s_send_lock_queue_raced); - spin_unlock_irqrestore(&conn->c_lock, flags); - goto restart; + if (gen == atomic_read(&conn->c_send_generation)) { + goto restart; + } } - spin_unlock_irqrestore(&conn->c_lock, flags); } out: return ret; -- cgit v1.2.3 From ce47f52f42e69d48d1b63fa618fce9cd7ffa9417 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 15 Apr 2010 17:19:29 -0700 Subject: RDS: Update comments in rds_send_xmit() Update comments to reflect changes in previous commit. Keeping as separate commits due to different authorship. Signed-off-by: Andy Grover --- net/rds/send.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index 663fd60b40cf..8e3fd9981c2e 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -353,15 +353,14 @@ restart: /* * Other senders will see we have c_send_lock and exit. We * need to recheck the send queue and race again for c_send_lock - * to make sure messages don't just sit on the send queue. + * to make sure messages don't just sit on the send queue, if + * somebody hasn't already beat us into the loop. * * If the transport cannot continue (i.e ret != 0), then it must * call us when more room is available, such as from the tx * completion handler. */ if (ret == 0) { - /* A simple bit test would be way faster than taking the - * spin lock */ smp_mb(); if (!list_empty(&conn->c_send_queue)) { rds_stats_inc(s_send_lock_queue_raced); -- cgit v1.2.3 From 976673ee1b92d939168c8c1fbad3e16c45caa545 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 21 Apr 2010 13:04:43 -0700 Subject: rds: switch to rwlock on bind_lock The bind_lock is almost entirely readonly, but it gets hammered during normal operations and is a major bottleneck. This commit changes it to an rwlock, which takes it from 80% of the system time on a big numa machine down to much lower numbers. A better fix would involve RCU, which is done in a later commit Signed-off-by: Chris Mason --- net/rds/bind.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/rds/bind.c b/net/rds/bind.c index 65de5cbdb576..a65afff6f4b5 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -43,7 +43,7 @@ * This is now called for every incoming frame so we arguably care much more * about it than we used to. */ -static DEFINE_SPINLOCK(rds_bind_lock); +static DEFINE_RWLOCK(rds_bind_lock); static struct rb_root rds_bind_tree = RB_ROOT; static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port, @@ -88,13 +88,13 @@ struct rds_sock *rds_find_bound(__be32 addr, __be16 port) struct rds_sock *rs; unsigned long flags; - spin_lock_irqsave(&rds_bind_lock, flags); + read_lock_irqsave(&rds_bind_lock, flags); rs = rds_bind_tree_walk(addr, port, NULL); if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) rds_sock_addref(rs); else rs = NULL; - spin_unlock_irqrestore(&rds_bind_lock, flags); + read_unlock_irqrestore(&rds_bind_lock, flags); rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr, ntohs(port)); @@ -116,7 +116,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) last = rover - 1; } - spin_lock_irqsave(&rds_bind_lock, flags); + write_lock_irqsave(&rds_bind_lock, flags); do { if (rover == 0) @@ -137,7 +137,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) rs, &addr, (int)ntohs(*port)); } - spin_unlock_irqrestore(&rds_bind_lock, flags); + write_unlock_irqrestore(&rds_bind_lock, flags); return ret; } @@ -146,7 +146,7 @@ void rds_remove_bound(struct rds_sock *rs) { unsigned long flags; - spin_lock_irqsave(&rds_bind_lock, flags); + write_lock_irqsave(&rds_bind_lock, flags); if (rs->rs_bound_addr) { rdsdebug("rs %p unbinding from %pI4:%d\n", @@ -158,7 +158,7 @@ void rds_remove_bound(struct rds_sock *rs) rs->rs_bound_addr = 0; } - spin_unlock_irqrestore(&rds_bind_lock, flags); + write_unlock_irqrestore(&rds_bind_lock, flags); } int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -- cgit v1.2.3 From c83188dcd76b1f0c17c31b4bbd8de57c634b19f8 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 21 Apr 2010 13:09:28 -0700 Subject: rds: per-rm flush_wait waitq This removes a global waitqueue used to wait for rds messages and replaces it with a waitqueue inside the rds_message struct. The global waitqueue turns into a global lock and significantly bottlenecks operations on large machines. Signed-off-by: Chris Mason --- net/rds/message.c | 7 +++---- net/rds/rds.h | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 4cb1ed704153..96e2bf7dc77e 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -35,8 +35,6 @@ #include "rds.h" -static DECLARE_WAIT_QUEUE_HEAD(rds_message_flush_waitq); - static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = { [RDS_EXTHDR_NONE] = 0, [RDS_EXTHDR_VERSION] = sizeof(struct rds_ext_header_version), @@ -226,6 +224,7 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) INIT_LIST_HEAD(&rm->m_sock_item); INIT_LIST_HEAD(&rm->m_conn_item); spin_lock_init(&rm->m_rs_lock); + init_waitqueue_head(&rm->m_flush_wait); out: return rm; @@ -399,14 +398,14 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, */ void rds_message_wait(struct rds_message *rm) { - wait_event_interruptible(rds_message_flush_waitq, + wait_event_interruptible(rm->m_flush_wait, !test_bit(RDS_MSG_MAPPED, &rm->m_flags)); } void rds_message_unmapped(struct rds_message *rm) { clear_bit(RDS_MSG_MAPPED, &rm->m_flags); - wake_up_interruptible(&rds_message_flush_waitq); + wake_up_interruptible(&rm->m_flush_wait); } EXPORT_SYMBOL_GPL(rds_message_unmapped); diff --git a/net/rds/rds.h b/net/rds/rds.h index b57cb50c1f22..c22bd7b49460 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -301,6 +301,8 @@ struct rds_message { * -> rs->rs_lock */ spinlock_t m_rs_lock; + wait_queue_head_t m_flush_wait; + struct rds_sock *m_rs; /* cookie to send to remote, in rds header */ -- cgit v1.2.3 From 764f2dd92f5cd308d1c4372b33fea2b265c093f5 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 22 Apr 2010 21:59:15 -0400 Subject: rds: rcu-ize rds_ib_get_device() rds_ib_get_device is called very often as we turn an ip address into a corresponding device structure. It currently take a global spinlock as it walks different lists to find active devices. This commit changes the lists over to RCU, which isn't very complex because they are not updated very often at all. Signed-off-by: Chris Mason --- net/rds/ib.c | 1 + net/rds/ib_rdma.c | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 927c481b5245..7a2131d37dfb 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -137,6 +137,7 @@ void rds_ib_remove_one(struct ib_device *device) if (!rds_ibdev) return; + synchronize_rcu(); list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) { list_del(&i_ipaddr->list); kfree(i_ipaddr); diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 242231f09464..7240e583ee58 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -32,6 +32,7 @@ */ #include #include +#include #include "rds.h" #include "ib.h" @@ -83,14 +84,14 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr) struct rds_ib_ipaddr *i_ipaddr; list_for_each_entry(rds_ibdev, &rds_ib_devices, list) { - spin_lock_irq(&rds_ibdev->spinlock); - list_for_each_entry(i_ipaddr, &rds_ibdev->ipaddr_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { - spin_unlock_irq(&rds_ibdev->spinlock); + rcu_read_unlock(); return rds_ibdev; } } - spin_unlock_irq(&rds_ibdev->spinlock); + rcu_read_unlock(); } return NULL; @@ -107,7 +108,7 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) i_ipaddr->ipaddr = ipaddr; spin_lock_irq(&rds_ibdev->spinlock); - list_add_tail(&i_ipaddr->list, &rds_ibdev->ipaddr_list); + list_add_tail_rcu(&i_ipaddr->list, &rds_ibdev->ipaddr_list); spin_unlock_irq(&rds_ibdev->spinlock); return 0; @@ -116,16 +117,23 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) static void rds_ib_remove_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) { struct rds_ib_ipaddr *i_ipaddr, *next; + struct rds_ib_ipaddr *to_free = NULL; + spin_lock_irq(&rds_ibdev->spinlock); - list_for_each_entry_safe(i_ipaddr, next, &rds_ibdev->ipaddr_list, list) { + list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { - list_del(&i_ipaddr->list); - kfree(i_ipaddr); + list_del_rcu(&i_ipaddr->list); + to_free = i_ipaddr; break; } } spin_unlock_irq(&rds_ibdev->spinlock); + + if (to_free) { + synchronize_rcu(); + kfree(to_free); + } } int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) -- cgit v1.2.3 From 4a81802b5e5e0b059627d7173c917711cf35e668 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 23 Apr 2010 11:04:21 -0700 Subject: RDS/IB: Remove unused variable in ib_remove_addr() Signed-off-by: Andy Grover --- net/rds/ib_rdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 7240e583ee58..7315fffd3bc8 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -116,7 +116,7 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) static void rds_ib_remove_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) { - struct rds_ib_ipaddr *i_ipaddr, *next; + struct rds_ib_ipaddr *i_ipaddr; struct rds_ib_ipaddr *to_free = NULL; -- cgit v1.2.3 From e4c52c98e04937ea87b0979a81354d0040d284f9 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 23 Apr 2010 10:49:53 -0700 Subject: RDS/IB: add _to_node() macros for numa and use {k,v}malloc_node() Allocate send/recv rings in memory that is node-local to the HCA. This significantly helps performance. Signed-off-by: Andy Grover --- net/rds/ib.c | 2 +- net/rds/ib.h | 6 ++++++ net/rds/ib_cm.c | 6 ++++-- net/rds/ib_rdma.c | 5 +++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 7a2131d37dfb..7d289d7985fe 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -77,7 +77,7 @@ void rds_ib_add_one(struct ib_device *device) goto free_attr; } - rds_ibdev = kmalloc(sizeof *rds_ibdev, GFP_KERNEL); + rds_ibdev = kmalloc_node(sizeof *rds_ibdev, GFP_KERNEL, ibdev_to_node(device)); if (!rds_ibdev) goto free_attr; diff --git a/net/rds/ib.h b/net/rds/ib.h index c506604325d5..4bc3e2fba25a 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include "rds.h" #include "rdma_transport.h" @@ -167,6 +169,10 @@ struct rds_ib_device { spinlock_t spinlock; /* protect the above */ }; +#define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus) +#define ibdev_to_node(ibdev) pcidev_to_node(to_pci_dev(ibdev->dma_device)) +#define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) + /* bits for i_ack_flags */ #define IB_ACK_IN_FLIGHT 0 #define IB_ACK_REQUESTED 1 diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 75eda9c82135..b5d0b60a26bc 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -347,7 +347,8 @@ static int rds_ib_setup_qp(struct rds_connection *conn) goto out; } - ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); + ic->i_sends = vmalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), + ibdev_to_node(dev)); if (!ic->i_sends) { ret = -ENOMEM; rdsdebug("send allocation failed\n"); @@ -355,7 +356,8 @@ static int rds_ib_setup_qp(struct rds_connection *conn) } memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); - ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work)); + ic->i_recvs = vmalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), + ibdev_to_node(dev)); if (!ic->i_recvs) { ret = -ENOMEM; rdsdebug("recv allocation failed\n"); diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 7315fffd3bc8..cc341cd70c87 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -297,7 +297,7 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) rds_ib_flush_mr_pool(pool, 0); } - ibmr = kzalloc(sizeof(*ibmr), GFP_KERNEL); + ibmr = kzalloc_node(sizeof(*ibmr), GFP_KERNEL, rdsibdev_to_node(rds_ibdev)); if (!ibmr) { err = -ENOMEM; goto out_no_cigar; @@ -376,7 +376,8 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm if (page_cnt > fmr_message_size) return -EINVAL; - dma_pages = kmalloc(sizeof(u64) * page_cnt, GFP_ATOMIC); + dma_pages = kmalloc_node(sizeof(u64) * page_cnt, GFP_ATOMIC, + rdsibdev_to_node(rds_ibdev)); if (!dma_pages) return -ENOMEM; -- cgit v1.2.3 From 38a4e5e61344490f18241333d7b1b368a3a38748 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 15:09:45 -0700 Subject: rds: Use RCU for the bind lookup searches The RDS bind lookups are somewhat expensive in terms of CPU time and locking overhead. This commit changes them into a faster RCU based hash tree instead of the rbtrees they were using before. On large NUMA systems it is a significant improvement. Signed-off-by: Chris Mason --- net/rds/af_rds.c | 8 +++++ net/rds/bind.c | 90 ++++++++++++++++++++++++++++--------------------------- net/rds/ib_rdma.c | 2 ++ net/rds/rds.h | 2 +- 4 files changed, 57 insertions(+), 45 deletions(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index ef09340cf7a9..f16d2a92cb89 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -72,7 +72,15 @@ static int rds_release(struct socket *sock) * with the socket. */ rds_clear_recv_queue(rs); rds_cong_remove_socket(rs); + + /* + * the binding lookup hash uses rcu, we need to + * make sure we sychronize_rcu before we free our + * entry + */ rds_remove_bound(rs); + synchronize_rcu(); + rds_send_drop_to(rs, NULL); rds_rdma_drop_keys(rs); rds_notify_queue_get(rs, NULL); diff --git a/net/rds/bind.c b/net/rds/bind.c index a65afff6f4b5..2f6b3fcc79f8 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -34,45 +34,52 @@ #include #include #include +#include #include "rds.h" -/* - * XXX this probably still needs more work.. no INADDR_ANY, and rbtrees aren't - * particularly zippy. - * - * This is now called for every incoming frame so we arguably care much more - * about it than we used to. - */ -static DEFINE_RWLOCK(rds_bind_lock); -static struct rb_root rds_bind_tree = RB_ROOT; +#define BIND_HASH_SIZE 1024 +static struct hlist_head bind_hash_table[BIND_HASH_SIZE]; +static DEFINE_SPINLOCK(rds_bind_lock); + +static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port) +{ + return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) & + (BIND_HASH_SIZE - 1)); +} -static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port, - struct rds_sock *insert) +static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, + struct rds_sock *insert) { - struct rb_node **p = &rds_bind_tree.rb_node; - struct rb_node *parent = NULL; struct rds_sock *rs; + struct hlist_node *node; + struct hlist_head *head = hash_to_bucket(addr, port); u64 cmp; u64 needle = ((u64)be32_to_cpu(addr) << 32) | be16_to_cpu(port); - while (*p) { - parent = *p; - rs = rb_entry(parent, struct rds_sock, rs_bound_node); - + rcu_read_lock(); + hlist_for_each_entry_rcu(rs, node, head, rs_bound_node) { cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) | be16_to_cpu(rs->rs_bound_port); - if (needle < cmp) - p = &(*p)->rb_left; - else if (needle > cmp) - p = &(*p)->rb_right; - else + if (cmp == needle) { + rcu_read_unlock(); return rs; + } } + rcu_read_unlock(); if (insert) { - rb_link_node(&insert->rs_bound_node, parent, p); - rb_insert_color(&insert->rs_bound_node, &rds_bind_tree); + /* + * make sure our addr and port are set before + * we are added to the list, other people + * in rcu will find us as soon as the + * hlist_add_head_rcu is done + */ + insert->rs_bound_addr = addr; + insert->rs_bound_port = port; + rds_sock_addref(insert); + + hlist_add_head_rcu(&insert->rs_bound_node, head); } return NULL; } @@ -86,15 +93,13 @@ static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port, struct rds_sock *rds_find_bound(__be32 addr, __be16 port) { struct rds_sock *rs; - unsigned long flags; - read_lock_irqsave(&rds_bind_lock, flags); - rs = rds_bind_tree_walk(addr, port, NULL); + rs = rds_bind_lookup(addr, port, NULL); + if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) rds_sock_addref(rs); else rs = NULL; - read_unlock_irqrestore(&rds_bind_lock, flags); rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr, ntohs(port)); @@ -116,28 +121,21 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) last = rover - 1; } - write_lock_irqsave(&rds_bind_lock, flags); + spin_lock_irqsave(&rds_bind_lock, flags); do { if (rover == 0) rover++; - if (!rds_bind_tree_walk(addr, cpu_to_be16(rover), rs)) { - *port = cpu_to_be16(rover); + if (!rds_bind_lookup(addr, cpu_to_be16(rover), rs)) { + *port = rs->rs_bound_port; ret = 0; + rdsdebug("rs %p binding to %pI4:%d\n", + rs, &addr, (int)ntohs(*port)); break; } } while (rover++ != last); - if (ret == 0) { - rs->rs_bound_addr = addr; - rs->rs_bound_port = *port; - rds_sock_addref(rs); - - rdsdebug("rs %p binding to %pI4:%d\n", - rs, &addr, (int)ntohs(*port)); - } - - write_unlock_irqrestore(&rds_bind_lock, flags); + spin_unlock_irqrestore(&rds_bind_lock, flags); return ret; } @@ -146,19 +144,19 @@ void rds_remove_bound(struct rds_sock *rs) { unsigned long flags; - write_lock_irqsave(&rds_bind_lock, flags); + spin_lock_irqsave(&rds_bind_lock, flags); if (rs->rs_bound_addr) { rdsdebug("rs %p unbinding from %pI4:%d\n", rs, &rs->rs_bound_addr, ntohs(rs->rs_bound_port)); - rb_erase(&rs->rs_bound_node, &rds_bind_tree); + hlist_del_init_rcu(&rs->rs_bound_node); rds_sock_put(rs); rs->rs_bound_addr = 0; } - write_unlock_irqrestore(&rds_bind_lock, flags); + spin_unlock_irqrestore(&rds_bind_lock, flags); } int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) @@ -198,5 +196,9 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out: release_sock(sk); + + /* we might have called rds_remove_bound on error */ + if (ret) + synchronize_rcu(); return ret; } diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index cc341cd70c87..4ba01b9ffd44 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -303,6 +303,8 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) goto out_no_cigar; } + memset(ibmr, 0, sizeof(*ibmr)); + ibmr->fmr = ib_alloc_fmr(rds_ibdev->pd, (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | diff --git a/net/rds/rds.h b/net/rds/rds.h index c22bd7b49460..241a0859d16e 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -452,7 +452,7 @@ struct rds_sock { * bound_addr used for both incoming and outgoing, no INADDR_ANY * support. */ - struct rb_node rs_bound_node; + struct hlist_node rs_bound_node; __be32 rs_bound_addr; __be32 rs_conn_addr; __be16 rs_bound_port; -- cgit v1.2.3 From 7e3f2952eeb1a0fe2aa9882fd1705a88f9d89b35 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 15:11:11 -0700 Subject: rds: don't let RDS shutdown a connection while senders are present This is the first in a long line of patches that tries to fix races between RDS connection shutdown and RDS traffic. Here we are maintaining a count of active senders to make sure the connection doesn't go away while they are using it. Signed-off-by: Chris Mason --- net/rds/connection.c | 7 +++++++ net/rds/ib_recv.c | 12 ------------ net/rds/message.c | 5 ++++- net/rds/rds.h | 1 + net/rds/send.c | 17 ++++++++++++++--- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 7e4e9dfdbc0b..9c249f394f29 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -148,6 +148,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, spin_lock_init(&conn->c_send_lock); atomic_set(&conn->c_send_generation, 1); + atomic_set(&conn->c_senders, 0); INIT_LIST_HEAD(&conn->c_send_queue); INIT_LIST_HEAD(&conn->c_retrans); @@ -276,6 +277,12 @@ void rds_conn_shutdown(struct rds_connection *conn) spin_lock_irq(&conn->c_send_lock); spin_unlock_irq(&conn->c_send_lock); + while(atomic_read(&conn->c_senders)) { + schedule_timeout(1); + spin_lock_irq(&conn->c_send_lock); + spin_unlock_irq(&conn->c_send_lock); + } + conn->c_trans->conn_shutdown(conn); rds_conn_reset(conn); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 8f041f7954a2..24d14615f41a 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -863,18 +863,6 @@ int rds_ib_recv(struct rds_connection *conn) int ret = 0; rdsdebug("conn %p\n", conn); - - /* - * If we get a temporary posting failure in this context then - * we're really low and we want the caller to back off for a bit. - */ - mutex_lock(&ic->i_recv_mutex); - if (rds_ib_recv_refill(conn, 0)) - ret = -ENOMEM; - else - rds_ib_stats_inc(s_ib_rx_refill_from_thread); - mutex_unlock(&ic->i_recv_mutex); - if (rds_conn_up(conn)) rds_ib_attempt_ack(ic); diff --git a/net/rds/message.c b/net/rds/message.c index 96e2bf7dc77e..84f937f11d47 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -81,7 +81,10 @@ static void rds_message_purge(struct rds_message *rm) void rds_message_put(struct rds_message *rm) { rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount)); - + if (atomic_read(&rm->m_refcount) == 0) { +printk(KERN_CRIT "danger refcount zero on %p\n", rm); +WARN_ON(1); + } if (atomic_dec_and_test(&rm->m_refcount)) { BUG_ON(!list_empty(&rm->m_sock_item)); BUG_ON(!list_empty(&rm->m_conn_item)); diff --git a/net/rds/rds.h b/net/rds/rds.h index 241a0859d16e..4ab3d1aa0237 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -93,6 +93,7 @@ struct rds_connection { spinlock_t c_send_lock; /* protect send ring */ atomic_t c_send_generation; + atomic_t c_senders; struct rds_message *c_xmit_rm; unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; diff --git a/net/rds/send.c b/net/rds/send.c index 8e3fd9981c2e..d35c43ff792e 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -60,15 +60,23 @@ void rds_send_reset(struct rds_connection *conn) struct rds_message *rm, *tmp; unsigned long flags; + spin_lock_irqsave(&conn->c_send_lock, flags); if (conn->c_xmit_rm) { + rm = conn->c_xmit_rm; + conn->c_xmit_rm = NULL; /* Tell the user the RDMA op is no longer mapped by the * transport. This isn't entirely true (it's flushed out * independently) but as the connection is down, there's * no ongoing RDMA to/from that memory */ - rds_message_unmapped(conn->c_xmit_rm); - rds_message_put(conn->c_xmit_rm); - conn->c_xmit_rm = NULL; +printk(KERN_CRIT "send reset unmapping %p\n", rm); + rds_message_unmapped(rm); + spin_unlock_irqrestore(&conn->c_send_lock, flags); + + rds_message_put(rm); + } else { + spin_unlock_irqrestore(&conn->c_send_lock, flags); } + conn->c_xmit_sg = 0; conn->c_xmit_hdr_off = 0; conn->c_xmit_data_off = 0; @@ -131,6 +139,7 @@ restart: ret = -ENOMEM; goto out; } + atomic_inc(&conn->c_senders); if (conn->c_trans->xmit_prepare) conn->c_trans->xmit_prepare(conn); @@ -350,6 +359,8 @@ restart: rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); } + atomic_dec(&conn->c_senders); + /* * Other senders will see we have c_send_lock and exit. We * need to recheck the send queue and race again for c_send_lock -- cgit v1.2.3 From c9e65383a20d9a656db70efbf67e57f8115ad776 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 15:14:16 -0700 Subject: rds: Fix RDMA message reference counting The RDS send_xmit code was trying to get fancy with message counting and was dropping the final reference on the RDMA messages too early. This resulted in memory corruption and oopsen. The fix here is to always add a ref as the parts of the message passes through rds_send_xmit, and always drop a ref as the parts of the message go through completion handling. Signed-off-by: Chris Mason --- net/rds/ib_send.c | 11 ++++++----- net/rds/send.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 657037d96cbf..82459e52c771 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -268,11 +268,12 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) if (send->s_queued + HZ/2 < jiffies) rds_ib_stats_inc(s_ib_tx_stalled); - if (&send->s_op == &rm->m_final_op) { - /* If anyone waited for this message to get flushed out, wake - * them up now */ - rds_message_unmapped(rm); - + if (send->s_op) { + if (send->s_op == rm->m_final_op) { + /* If anyone waited for this message to get flushed out, wake + * them up now */ + rds_message_unmapped(rm); + } rds_message_put(rm); send->s_op = NULL; } diff --git a/net/rds/send.c b/net/rds/send.c index d35c43ff792e..5c6d4a0be0d7 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -68,7 +68,6 @@ void rds_send_reset(struct rds_connection *conn) * transport. This isn't entirely true (it's flushed out * independently) but as the connection is down, there's * no ongoing RDMA to/from that memory */ -printk(KERN_CRIT "send reset unmapping %p\n", rm); rds_message_unmapped(rm); spin_unlock_irqrestore(&conn->c_send_lock, flags); @@ -234,10 +233,13 @@ restart: /* The transport either sends the whole rdma or none of it */ if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { + rds_message_addref(rm); rm->m_final_op = &rm->rdma; ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); - if (ret) + if (ret) { + rds_message_put(rm); break; + } conn->c_xmit_rdma_sent = 1; /* The transport owns the mapped memory for now. @@ -246,10 +248,13 @@ restart: } if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { + rds_message_addref(rm); rm->m_final_op = &rm->atomic; ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); - if (ret) + if (ret) { + rds_message_put(rm); break; + } conn->c_xmit_atomic_sent = 1; /* The transport owns the mapped memory for now. -- cgit v1.2.3 From abf454398c2ebafc629ebb8b149f5a752c79e919 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 15:14:52 -0700 Subject: RDS: use locking on the connection hash list rds_conn_destroy really needs locking while it changes the connection hash. Signed-off-by: Chris Mason --- net/rds/connection.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/rds/connection.c b/net/rds/connection.c index 9c249f394f29..87df15b9f8e4 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -321,7 +321,10 @@ void rds_conn_destroy(struct rds_connection *conn) "%pI4\n", conn, &conn->c_laddr, &conn->c_faddr); + /* Ensure conn will not be scheduled for reconnect */ + spin_lock_irq(&rds_conn_lock); hlist_del_init(&conn->c_hash_node); + spin_unlock_irq(&rds_conn_lock); /* wait for the rds thread to shut it down */ atomic_set(&conn->c_state, RDS_CONN_ERROR); -- cgit v1.2.3 From bcf50ef2ce3c5d8f2fe995259da16677898cb300 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 15:15:15 -0700 Subject: rds: use RCU to protect the connection hash The connection hash was almost entirely RCU ready, this just makes the final couple of changes to use RCU instead of spinlocks for everything. Signed-off-by: Chris Mason --- net/rds/connection.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 87df15b9f8e4..180b83ab2607 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -62,6 +62,7 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) var |= RDS_INFO_CONNECTION_FLAG_##suffix; \ } while (0) +/* rcu read lock must be held or the connection spinlock */ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, __be32 laddr, __be32 faddr, struct rds_transport *trans) @@ -69,7 +70,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, struct rds_connection *conn, *ret = NULL; struct hlist_node *pos; - hlist_for_each_entry(conn, pos, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { if (conn->c_faddr == faddr && conn->c_laddr == laddr && conn->c_trans == trans) { ret = conn; @@ -119,7 +120,8 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, unsigned long flags; int ret; - spin_lock_irqsave(&rds_conn_lock, flags); + + rcu_read_lock(); conn = rds_conn_lookup(head, laddr, faddr, trans); if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && !is_outgoing) { @@ -130,7 +132,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, parent = conn; conn = parent->c_passive; } - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); if (conn) goto out; @@ -227,7 +229,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, kmem_cache_free(rds_conn_slab, conn); conn = found; } else { - hlist_add_head(&conn->c_hash_node, head); + hlist_add_head_rcu(&conn->c_hash_node, head); rds_cong_add_conn(conn); rds_conn_count++; } @@ -306,8 +308,13 @@ void rds_conn_shutdown(struct rds_connection *conn) * to the conn hash, so we never trigger a reconnect on this * conn - the reconnect is always triggered by the active peer. */ cancel_delayed_work_sync(&conn->c_conn_w); - if (!hlist_unhashed(&conn->c_hash_node)) + rcu_read_lock(); + if (!hlist_unhashed(&conn->c_hash_node)) { + rcu_read_unlock(); rds_queue_reconnect(conn); + } else { + rcu_read_unlock(); + } } /* @@ -323,14 +330,12 @@ void rds_conn_destroy(struct rds_connection *conn) /* Ensure conn will not be scheduled for reconnect */ spin_lock_irq(&rds_conn_lock); - hlist_del_init(&conn->c_hash_node); + hlist_del_init_rcu(&conn->c_hash_node); spin_unlock_irq(&rds_conn_lock); - /* wait for the rds thread to shut it down */ - atomic_set(&conn->c_state, RDS_CONN_ERROR); - cancel_delayed_work(&conn->c_conn_w); - queue_work(rds_wq, &conn->c_down_w); - flush_workqueue(rds_wq); + synchronize_rcu(); + + rds_conn_shutdown(conn); /* tear down queued messages */ list_for_each_entry_safe(rm, rtmp, @@ -369,17 +374,16 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, struct list_head *list; struct rds_connection *conn; struct rds_message *rm; - unsigned long flags; unsigned int total = 0; size_t i; len /= sizeof(struct rds_info_message); - spin_lock_irqsave(&rds_conn_lock, flags); + rcu_read_lock(); for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash); i++, head++) { - hlist_for_each_entry(conn, pos, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { if (want_send) list = &conn->c_send_queue; else @@ -399,8 +403,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, spin_unlock(&conn->c_lock); } } - - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); lens->nr = total; lens->each = sizeof(struct rds_info_message); @@ -430,19 +433,17 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len, uint64_t buffer[(item_len + 7) / 8]; struct hlist_head *head; struct hlist_node *pos; - struct hlist_node *tmp; struct rds_connection *conn; - unsigned long flags; size_t i; - spin_lock_irqsave(&rds_conn_lock, flags); + rcu_read_lock(); lens->nr = 0; lens->each = item_len; for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash); i++, head++) { - hlist_for_each_entry_safe(conn, pos, tmp, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { /* XXX no c_lock usage.. */ if (!visitor(conn, buffer)) @@ -458,8 +459,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len, lens->nr++; } } - - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(rds_for_each_conn_info); -- cgit v1.2.3 From 1cc2228c599f173d77000a250bf0541294e1a7be Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 11 May 2010 16:15:35 -0700 Subject: rds: Fix reference counting on the for xmit_atomic and xmit_rdma This makes sure we have the proper number of references in rds_ib_xmit_atomic and rds_ib_xmit_rdma. We also consistently drop references the same way for all message types as the IOs end. Signed-off-by: Chris Mason --- net/rds/ib_send.c | 10 +++++++++- net/rds/send.c | 10 ++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 82459e52c771..209dbc6d159d 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -757,6 +757,8 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) send->s_wr.next = NULL; send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; send->s_wr.wr.atomic.rkey = op->op_rkey; + send->s_op = op; + rds_message_addref(container_of(send->s_op, struct rds_message, atomic)); /* map 8 byte retval buffer to the device */ ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE); @@ -857,13 +859,13 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; + send->s_op = NULL; rds_ib_set_wr_signal_state(ic, send, op->op_notify); send->s_wr.opcode = op->op_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; send->s_wr.wr.rdma.remote_addr = remote_addr; send->s_wr.wr.rdma.rkey = op->op_rkey; - send->s_op = op; if (num_sge > rds_ibdev->max_sge) { send->s_wr.num_sge = rds_ibdev->max_sge; @@ -899,6 +901,12 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) send = ic->i_sends; } + /* give a reference to the last op */ + if (scat == &op->op_sg[op->op_count]) { + prev->s_op = op; + rds_message_addref(container_of(op, struct rds_message, rdma)); + } + if (i < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i); work_alloc = i; diff --git a/net/rds/send.c b/net/rds/send.c index 5c6d4a0be0d7..437f1e72609c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -233,13 +233,10 @@ restart: /* The transport either sends the whole rdma or none of it */ if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { - rds_message_addref(rm); rm->m_final_op = &rm->rdma; ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); - if (ret) { - rds_message_put(rm); + if (ret) break; - } conn->c_xmit_rdma_sent = 1; /* The transport owns the mapped memory for now. @@ -248,13 +245,10 @@ restart: } if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { - rds_message_addref(rm); rm->m_final_op = &rm->atomic; ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); - if (ret) { - rds_message_put(rm); + if (ret) break; - } conn->c_xmit_atomic_sent = 1; /* The transport owns the mapped memory for now. -- cgit v1.2.3 From a46ca94e7fb2c93a59e08b42fd77d8c478fda5fc Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 24 May 2010 13:14:59 -0700 Subject: RDS/IB: rds_ib_cm_handle_connect() forgot to unlock c_cm_lock rds_ib_cm_handle_connect() could return without unlocking the c_conn_lock if rds_setup_qp() failed. Rather than adding another imbalanced mutex_unlock() to this error path we only unlock the mutex once as we exit the function, reducing the likelyhood of making this same mistake in the future. We remove the previous mulitple return sites, leaving one unambigious return path. Signed-off-by: Zach Brown --- net/rds/ib_cm.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index b5d0b60a26bc..73253f7c1fa3 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -428,7 +428,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, struct rds_ib_connection *ic = NULL; struct rdma_conn_param conn_param; u32 version; - int err, destroy = 1; + int err = 1, destroy = 1; /* Check whether the remote protocol version matches ours. */ version = rds_ib_protocol_compatible(event); @@ -467,7 +467,6 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, /* Wait and see - our connect may still be succeeding */ rds_ib_stats_inc(s_ib_connect_raced); } - mutex_unlock(&conn->c_cm_lock); goto out; } @@ -504,16 +503,14 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, /* rdma_accept() calls rdma_reject() internally if it fails */ err = rdma_accept(cm_id, &conn_param); - mutex_unlock(&conn->c_cm_lock); - if (err) { + if (err) rds_ib_conn_error(conn, "rdma_accept failed (%d)\n", err); - goto out; - } - - return 0; out: - rdma_reject(cm_id, NULL, 0); + if (conn) + mutex_unlock(&conn->c_cm_lock); + if (err) + rdma_reject(cm_id, NULL, 0); return destroy; } -- cgit v1.2.3 From 89bf9d4158b5a1b6bd00960eb2e47601ec8cc138 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 18 May 2010 15:44:50 -0700 Subject: RDS/IB: get the xmit max_sge from the RDS IB device on the connection rds_ib_xmit_rdma() was calling ib_get_client_data() to get at the rds_ibdevice just to get the max_sge for the transmit. This patch instead has it get it directly off the rds_ibdev which is stored on the connection. The current code won't free the rds_ibdev until all the IB connections that use it are freed. So it's safe to reference the rds_ibdev this way. In the future it also makes it easier to support proper reference counting of the rds_ibdev struct. As an additional bonus, this gets rid of the performance hit of calling in to the IB stack to look up the rds_ibdev. The current implementation in the IB stack acquires an interrupt blocking spinlock to protect the registration of client callback data. Signed-off-by: Zach Brown --- net/rds/ib_send.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 209dbc6d159d..3f91e794eae9 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -806,10 +806,10 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) struct rds_ib_send_work *first; struct rds_ib_send_work *prev; struct ib_send_wr *failed_wr; - struct rds_ib_device *rds_ibdev; struct scatterlist *scat; unsigned long len; u64 remote_addr = op->op_remote_addr; + u32 max_sge = ic->rds_ibdev->max_sge; u32 pos; u32 work_alloc; u32 i; @@ -818,8 +818,6 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) int ret; int num_sge; - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - /* map the op the first time we see it */ if (!op->op_mapped) { op->op_count = ib_dma_map_sg(ic->i_cm_id->device, @@ -839,7 +837,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) * Instead of knowing how to return a partial rdma read/write we insist that there * be enough work requests to send the entire message. */ - i = ceil(op->op_count, rds_ibdev->max_sge); + i = ceil(op->op_count, max_sge); work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos); if (work_alloc != i) { @@ -867,9 +865,9 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) send->s_wr.wr.rdma.remote_addr = remote_addr; send->s_wr.wr.rdma.rkey = op->op_rkey; - if (num_sge > rds_ibdev->max_sge) { - send->s_wr.num_sge = rds_ibdev->max_sge; - num_sge -= rds_ibdev->max_sge; + if (num_sge > max_sge) { + send->s_wr.num_sge = max_sge; + num_sge -= max_sge; } else { send->s_wr.num_sge = num_sge; } -- cgit v1.2.3 From 3e0249f9c05cb77b66f7f09644ca9ca208d991a9 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 18 May 2010 15:48:51 -0700 Subject: RDS/IB: add refcount tracking to struct rds_ib_device The RDS IB client .remove callback used to free the rds_ibdev for the given device unconditionally. This could race other users of the struct. This patch adds refcounting so that we only free the rds_ibdev once all of its users are done. Many rds_ibdev users are tied to connections. We give the connection a reference and change these users to reference the device in the connection instead of looking it up in the IB client data. The only user of the IB client data remaining is the first lookup of the device as connections are built up. Incrementing the reference count of a device found in the IB client data could race with final freeing so we use an RCU grace period to make sure that freeing won't happen until those lookups are done. MRs need the rds_ibdev to get at the pool that they're freed in to. They exist outside a connection and many MRs can reference different devices from one socket, so it was natural to have each MR hold a reference. MR refs can be dropped from interrupt handlers and final device teardown can block so we push it off to a work struct. Pool teardown had to be fixed to cancel its pending work instead of deadlocking waiting for all queued work, including itself, to finish. MRs get their reference from the global device list, which gets a reference. It is left unprotected by locks and remains racy. A simple global lock would be a significant bottleneck. More scalable (complicated) locking should be done carefully in a later patch. Signed-off-by: Zach Brown --- net/rds/ib.c | 129 ++++++++++++++++++++++++++++++++++++++++-------------- net/rds/ib.h | 4 ++ net/rds/ib_cm.c | 33 ++++++-------- net/rds/ib_rdma.c | 14 +++++- 4 files changed, 125 insertions(+), 55 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 7d289d7985fe..1732f8effb59 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -59,6 +59,38 @@ struct list_head rds_ib_devices; DEFINE_SPINLOCK(ib_nodev_conns_lock); LIST_HEAD(ib_nodev_conns); +/* + * rds_ib_destroy_mr_pool() blocks on a few things and mrs drop references + * from interrupt context so we push freing off into a work struct in krdsd. + */ +static void rds_ib_dev_free(struct work_struct *work) +{ + struct rds_ib_ipaddr *i_ipaddr, *i_next; + struct rds_ib_device *rds_ibdev = container_of(work, + struct rds_ib_device, free_work); + + if (rds_ibdev->mr_pool) + rds_ib_destroy_mr_pool(rds_ibdev->mr_pool); + if (rds_ibdev->mr) + ib_dereg_mr(rds_ibdev->mr); + if (rds_ibdev->pd) + ib_dealloc_pd(rds_ibdev->pd); + + list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) { + list_del(&i_ipaddr->list); + kfree(i_ipaddr); + } + + kfree(rds_ibdev); +} + +void rds_ib_dev_put(struct rds_ib_device *rds_ibdev) +{ + BUG_ON(atomic_read(&rds_ibdev->refcount) <= 0); + if (atomic_dec_and_test(&rds_ibdev->refcount)) + queue_work(rds_wq, &rds_ibdev->free_work); +} + void rds_ib_add_one(struct ib_device *device) { struct rds_ib_device *rds_ibdev; @@ -77,11 +109,14 @@ void rds_ib_add_one(struct ib_device *device) goto free_attr; } - rds_ibdev = kmalloc_node(sizeof *rds_ibdev, GFP_KERNEL, ibdev_to_node(device)); + rds_ibdev = kzalloc_node(sizeof(struct rds_ib_device), GFP_KERNEL, + ibdev_to_node(device)); if (!rds_ibdev) goto free_attr; spin_lock_init(&rds_ibdev->spinlock); + atomic_set(&rds_ibdev->refcount, 1); + INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free); rds_ibdev->max_wrs = dev_attr->max_qp_wr; rds_ibdev->max_sge = min(dev_attr->max_sge, RDS_IB_MAX_SGE); @@ -96,67 +131,93 @@ void rds_ib_add_one(struct ib_device *device) rds_ibdev->dev = device; rds_ibdev->pd = ib_alloc_pd(device); - if (IS_ERR(rds_ibdev->pd)) - goto free_dev; + if (IS_ERR(rds_ibdev->pd)) { + rds_ibdev->pd = NULL; + goto put_dev; + } - rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, - IB_ACCESS_LOCAL_WRITE); - if (IS_ERR(rds_ibdev->mr)) - goto err_pd; + rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(rds_ibdev->mr)) { + rds_ibdev->mr = NULL; + goto put_dev; + } rds_ibdev->mr_pool = rds_ib_create_mr_pool(rds_ibdev); if (IS_ERR(rds_ibdev->mr_pool)) { rds_ibdev->mr_pool = NULL; - goto err_mr; + goto put_dev; } INIT_LIST_HEAD(&rds_ibdev->ipaddr_list); INIT_LIST_HEAD(&rds_ibdev->conn_list); list_add_tail(&rds_ibdev->list, &rds_ib_devices); + atomic_inc(&rds_ibdev->refcount); ib_set_client_data(device, &rds_ib_client, rds_ibdev); + atomic_inc(&rds_ibdev->refcount); - goto free_attr; - -err_mr: - ib_dereg_mr(rds_ibdev->mr); -err_pd: - ib_dealloc_pd(rds_ibdev->pd); -free_dev: - kfree(rds_ibdev); +put_dev: + rds_ib_dev_put(rds_ibdev); free_attr: kfree(dev_attr); } +/* + * New connections use this to find the device to associate with the + * connection. It's not in the fast path so we're not concerned about the + * performance of the IB call. (As of this writing, it uses an interrupt + * blocking spinlock to serialize walking a per-device list of all registered + * clients.) + * + * RCU is used to handle incoming connections racing with device teardown. + * Rather than use a lock to serialize removal from the client_data and + * getting a new reference, we use an RCU grace period. The destruction + * path removes the device from client_data and then waits for all RCU + * readers to finish. + * + * A new connection can get NULL from this if its arriving on a + * device that is in the process of being removed. + */ +struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device) +{ + struct rds_ib_device *rds_ibdev; + + rcu_read_lock(); + rds_ibdev = ib_get_client_data(device, &rds_ib_client); + if (rds_ibdev) + atomic_inc(&rds_ibdev->refcount); + rcu_read_unlock(); + return rds_ibdev; +} + +/* + * The IB stack is letting us know that a device is going away. This can + * happen if the underlying HCA driver is removed or if PCI hotplug is removing + * the pci function, for example. + * + * This can be called at any time and can be racing with any other RDS path. + */ void rds_ib_remove_one(struct ib_device *device) { struct rds_ib_device *rds_ibdev; - struct rds_ib_ipaddr *i_ipaddr, *i_next; rds_ibdev = ib_get_client_data(device, &rds_ib_client); if (!rds_ibdev) return; - synchronize_rcu(); - list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) { - list_del(&i_ipaddr->list); - kfree(i_ipaddr); - } - rds_ib_destroy_conns(rds_ibdev); - if (rds_ibdev->mr_pool) - rds_ib_destroy_mr_pool(rds_ibdev->mr_pool); - - ib_dereg_mr(rds_ibdev->mr); - - while (ib_dealloc_pd(rds_ibdev->pd)) { - rdsdebug("Failed to dealloc pd %p\n", rds_ibdev->pd); - msleep(1); - } + /* + * prevent future connection attempts from getting a reference to this + * device and wait for currently racing connection attempts to finish + * getting their reference + */ + ib_set_client_data(device, &rds_ib_client, NULL); + synchronize_rcu(); + rds_ib_dev_put(rds_ibdev); list_del(&rds_ibdev->list); - kfree(rds_ibdev); + rds_ib_dev_put(rds_ibdev); } struct ib_client rds_ib_client = { @@ -190,7 +251,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn, rdma_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); rdma_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); + rds_ibdev = ic->rds_ibdev; iinfo->max_send_wr = ic->i_send_ring.w_nr; iinfo->max_recv_wr = ic->i_recv_ring.w_nr; iinfo->max_send_sge = rds_ibdev->max_sge; diff --git a/net/rds/ib.h b/net/rds/ib.h index 4bc3e2fba25a..282ec69fe282 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -167,6 +167,8 @@ struct rds_ib_device { unsigned int max_initiator_depth; unsigned int max_responder_resources; spinlock_t spinlock; /* protect the above */ + atomic_t refcount; + struct work_struct free_work; }; #define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus) @@ -251,6 +253,8 @@ static inline void rds_ib_dma_sync_sg_for_device(struct ib_device *dev, extern struct rds_transport rds_ib_transport; extern void rds_ib_add_one(struct ib_device *device); extern void rds_ib_remove_one(struct ib_device *device); +struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device); +void rds_ib_dev_put(struct rds_ib_device *rds_ibdev); extern struct ib_client rds_ib_client; extern unsigned int fmr_pool_size; diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 73253f7c1fa3..a9fb917c00bb 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -95,7 +95,6 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even { const struct rds_ib_connect_private *dp = NULL; struct rds_ib_connection *ic = conn->c_transport_data; - struct rds_ib_device *rds_ibdev; struct ib_qp_attr qp_attr; int err; @@ -145,12 +144,11 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even if (err) printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err); - /* update ib_device with this local ipaddr & conn */ - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - err = rds_ib_update_ipaddr(rds_ibdev, conn->c_laddr); + /* update ib_device with this local ipaddr */ + err = rds_ib_update_ipaddr(ic->rds_ibdev, conn->c_laddr); if (err) - printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", err); - rds_ib_add_conn(rds_ibdev, conn); + printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", + err); /* If the peer gave us the last packet it saw, process this as if * we had received a regular ACK. */ @@ -168,12 +166,10 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, u32 max_initiator_depth) { struct rds_ib_connection *ic = conn->c_transport_data; - struct rds_ib_device *rds_ibdev; + struct rds_ib_device *rds_ibdev = ic->rds_ibdev; memset(conn_param, 0, sizeof(struct rdma_conn_param)); - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - conn_param->responder_resources = min_t(u32, rds_ibdev->max_responder_resources, max_responder_resources); conn_param->initiator_depth = @@ -241,18 +237,16 @@ static int rds_ib_setup_qp(struct rds_connection *conn) struct rds_ib_device *rds_ibdev; int ret; - /* rds_ib_add_one creates a rds_ib_device object per IB device, - * and allocates a protection domain, memory range and FMR pool - * for each. If that fails for any reason, it will not register - * the rds_ibdev at all. + /* + * It's normal to see a null device if an incoming connection races + * with device removal, so we don't print a warning. */ - rds_ibdev = ib_get_client_data(dev, &rds_ib_client); - if (!rds_ibdev) { - if (printk_ratelimit()) - printk(KERN_NOTICE "RDS/IB: No client_data for device %s\n", - dev->name); + rds_ibdev = rds_ib_get_client_data(dev); + if (!rds_ibdev) return -EOPNOTSUPP; - } + + /* add the conn now so that connection establishment has the dev */ + rds_ib_add_conn(rds_ibdev, conn); if (rds_ibdev->max_wrs < ic->i_send_ring.w_nr + 1) rds_ib_ring_resize(&ic->i_send_ring, rds_ibdev->max_wrs - 1); @@ -371,6 +365,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_send_cq, ic->i_recv_cq); out: + rds_ib_dev_put(rds_ibdev); return ret; } diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 4ba01b9ffd44..64b5ede037c8 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -87,6 +87,7 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr) rcu_read_lock(); list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { + atomic_inc(&rds_ibdev->refcount); rcu_read_unlock(); return rds_ibdev; } @@ -141,8 +142,10 @@ int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) struct rds_ib_device *rds_ibdev_old; rds_ibdev_old = rds_ib_get_device(ipaddr); - if (rds_ibdev_old) + if (rds_ibdev_old) { rds_ib_remove_ipaddr(rds_ibdev_old, ipaddr); + rds_ib_dev_put(rds_ibdev_old); + } return rds_ib_add_ipaddr(rds_ibdev, ipaddr); } @@ -163,6 +166,7 @@ void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *con spin_unlock_irq(&ib_nodev_conns_lock); ic->rds_ibdev = rds_ibdev; + atomic_inc(&rds_ibdev->refcount); } void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn) @@ -182,6 +186,7 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection * spin_unlock(&ib_nodev_conns_lock); ic->rds_ibdev = NULL; + rds_ib_dev_put(rds_ibdev); } void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) @@ -240,7 +245,7 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) { - flush_workqueue(rds_wq); + cancel_work_sync(&pool->flush_worker); rds_ib_flush_mr_pool(pool, 1); WARN_ON(atomic_read(&pool->item_count)); WARN_ON(atomic_read(&pool->free_pinned)); @@ -597,6 +602,8 @@ void rds_ib_free_mr(void *trans_private, int invalidate) queue_work(rds_wq, &pool->flush_worker); } } + + rds_ib_dev_put(rds_ibdev); } void rds_ib_flush_mrs(void) @@ -640,6 +647,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, printk(KERN_WARNING "RDS/IB: map_fmr failed (errno=%d)\n", ret); ibmr->device = rds_ibdev; + rds_ibdev = NULL; out: if (ret) { @@ -647,5 +655,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, rds_ib_free_mr(ibmr, 0); ibmr = ERR_PTR(ret); } + if (rds_ibdev) + rds_ib_dev_put(rds_ibdev); return ibmr; } -- cgit v1.2.3 From f3c6808d3d8513db2b0543538fc35c25a60fe7a7 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 24 May 2010 13:14:36 -0700 Subject: RDS: introduce rds_conn_connect_if_down() A few paths had the same block of code to queue a connection's connect work if it was in the right state. Let's move this in to a helper function. Signed-off-by: Zach Brown --- net/rds/connection.c | 12 ++++++++++++ net/rds/rds.h | 1 + net/rds/send.c | 16 ++-------------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 180b83ab2607..5bd96d538fb9 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -539,6 +539,18 @@ void rds_conn_drop(struct rds_connection *conn) } EXPORT_SYMBOL_GPL(rds_conn_drop); +/* + * If the connection is down, trigger a connect. We may have scheduled a + * delayed reconnect however - in this case we should not interfere. + */ +void rds_conn_connect_if_down(struct rds_connection *conn) +{ + if (rds_conn_state(conn) == RDS_CONN_DOWN && + !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) + queue_delayed_work(rds_wq, &conn->c_conn_w, 0); +} +EXPORT_SYMBOL_GPL(rds_conn_connect_if_down); + /* * An error occurred on the connection */ diff --git a/net/rds/rds.h b/net/rds/rds.h index 4ab3d1aa0237..cba5f8bb4780 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -617,6 +617,7 @@ void rds_conn_shutdown(struct rds_connection *conn); void rds_conn_destroy(struct rds_connection *conn); void rds_conn_reset(struct rds_connection *conn); void rds_conn_drop(struct rds_connection *conn); +void rds_conn_connect_if_down(struct rds_connection *conn); void rds_for_each_conn_info(struct socket *sock, unsigned int len, struct rds_info_iterator *iter, struct rds_info_lengths *lens, diff --git a/net/rds/send.c b/net/rds/send.c index 437f1e72609c..a6295993e3e1 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -1036,13 +1036,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; } - /* If the connection is down, trigger a connect. We may - * have scheduled a delayed reconnect however - in this case - * we should not interfere. - */ - if (rds_conn_state(conn) == RDS_CONN_DOWN && - !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) - queue_delayed_work(rds_wq, &conn->c_conn_w, 0); + rds_conn_connect_if_down(conn); ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); if (ret) { @@ -1122,13 +1116,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) rm->m_daddr = conn->c_faddr; rm->data.op_active = 1; - /* If the connection is down, trigger a connect. We may - * have scheduled a delayed reconnect however - in this case - * we should not interfere. - */ - if (rds_conn_state(conn) == RDS_CONN_DOWN && - !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) - queue_delayed_work(rds_wq, &conn->c_conn_w, 0); + rds_conn_connect_if_down(conn); ret = rds_cong_wait(conn->c_fcong, dport, 1, NULL); if (ret) -- cgit v1.2.3 From fc19de38be924728fea76026c0d1a6c4b6156084 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 24 May 2010 13:16:57 -0700 Subject: RDS/IB: disconnect when IB devices are removed Currently IB device removal destroys connections which are associated with the device. This prevents connections from being re-established when replacement devices are added. Instead we'll queue shutdown work on the connections as their devices are removed. When we see that devices are added we triger connection attempts on all connections that don't currently have a device. The result is that RDS sockets can resume device-independent work (bcopy, not RDMA) across IB device removal and restoration. Signed-off-by: Zach Brown --- net/rds/ib.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 1732f8effb59..b21e24fd060c 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -59,6 +59,27 @@ struct list_head rds_ib_devices; DEFINE_SPINLOCK(ib_nodev_conns_lock); LIST_HEAD(ib_nodev_conns); +void rds_ib_nodev_connect(void) +{ + struct rds_ib_connection *ic; + + spin_lock(&ib_nodev_conns_lock); + list_for_each_entry(ic, &ib_nodev_conns, ib_node) + rds_conn_connect_if_down(ic->conn); + spin_unlock(&ib_nodev_conns_lock); +} + +void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev) +{ + struct rds_ib_connection *ic; + unsigned long flags; + + spin_lock_irqsave(&rds_ibdev->spinlock, flags); + list_for_each_entry(ic, &rds_ibdev->conn_list, ib_node) + rds_conn_drop(ic->conn); + spin_unlock_irqrestore(&rds_ibdev->spinlock, flags); +} + /* * rds_ib_destroy_mr_pool() blocks on a few things and mrs drop references * from interrupt context so we push freing off into a work struct in krdsd. @@ -156,6 +177,8 @@ void rds_ib_add_one(struct ib_device *device) ib_set_client_data(device, &rds_ib_client, rds_ibdev); atomic_inc(&rds_ibdev->refcount); + rds_ib_nodev_connect(); + put_dev: rds_ib_dev_put(rds_ibdev); free_attr: @@ -205,7 +228,7 @@ void rds_ib_remove_one(struct ib_device *device) if (!rds_ibdev) return; - rds_ib_destroy_conns(rds_ibdev); + rds_ib_dev_shutdown(rds_ibdev); /* * prevent future connection attempts from getting a reference to this -- cgit v1.2.3 From 0b088e003ccf316a76c51be5dec2d70b93be3be8 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 24 May 2010 20:12:41 -0700 Subject: RDS: Use page_remainder_alloc() for recv bufs Instead of splitting up a page into RDS_FRAG_SIZE chunks ourselves, ask rds_page_remainder_alloc() to do it. While it is possible PAGE_SIZE > FRAG_SIZE, on x86en it isn't, so having duplicate "carve up a page into buffers" code seems excessive. The other modification this spawns is the use of a single struct scatterlist in rds_page_frag instead of a bare page ptr. This causes verbosity to increase in some places, and decrease in others. Finally, I decided to unify the lifetimes and alloc/free of rds_page_frag and its page. This is a nice simplification in itself, but will be extra-nice once we come to adding cmason's recycling patch. Signed-off-by: Andy Grover --- net/rds/ib.h | 7 +---- net/rds/ib_recv.c | 94 ++++++++++++++++--------------------------------------- net/rds/page.c | 1 + 3 files changed, 29 insertions(+), 73 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 282ec69fe282..9bb7a7412a44 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -28,13 +28,9 @@ extern struct list_head rds_ib_devices; * try and minimize the amount of memory tied up both the device and * socket receive queues. */ -/* page offset of the final full frag that fits in the page */ -#define RDS_PAGE_LAST_OFF (((PAGE_SIZE / RDS_FRAG_SIZE) - 1) * RDS_FRAG_SIZE) struct rds_page_frag { struct list_head f_item; - struct page *f_page; - unsigned long f_offset; - dma_addr_t f_mapped; + struct scatterlist f_sg; }; struct rds_ib_incoming { @@ -107,7 +103,6 @@ struct rds_ib_connection { struct rds_header *i_recv_hdrs; u64 i_recv_hdrs_dma; struct rds_ib_recv_work *i_recvs; - struct rds_page_frag i_frag; u64 i_ack_recv; /* last ACK received */ /* sending acks */ diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 24d14615f41a..f6dbf16e0741 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -43,17 +43,11 @@ static struct kmem_cache *rds_ib_incoming_slab; static struct kmem_cache *rds_ib_frag_slab; static atomic_t rds_ib_allocation = ATOMIC_INIT(0); -static void rds_ib_frag_drop_page(struct rds_page_frag *frag) -{ - rdsdebug("frag %p page %p\n", frag, frag->f_page); - __free_page(frag->f_page); - frag->f_page = NULL; -} - +/* Free frag and attached recv buffer f_sg */ static void rds_ib_frag_free(struct rds_page_frag *frag) { - rdsdebug("frag %p page %p\n", frag, frag->f_page); - BUG_ON(frag->f_page); + rdsdebug("frag %p page %p\n", frag, sg_page(&frag->f_sg)); + __free_page(sg_page(&frag->f_sg)); kmem_cache_free(rds_ib_frag_slab, frag); } @@ -71,12 +65,8 @@ static void rds_ib_recv_unmap_page(struct rds_ib_connection *ic, { struct rds_page_frag *frag = recv->r_frag; - rdsdebug("recv %p frag %p page %p\n", recv, frag, frag->f_page); - if (frag->f_mapped) - ib_dma_unmap_page(ic->i_cm_id->device, - frag->f_mapped, - RDS_FRAG_SIZE, DMA_FROM_DEVICE); - frag->f_mapped = 0; + rdsdebug("recv %p frag %p page %p\n", recv, frag, sg_page(&frag->f_sg)); + ib_dma_unmap_sg(ic->i_cm_id->device, &frag->f_sg, 1, DMA_FROM_DEVICE); } void rds_ib_recv_init_ring(struct rds_ib_connection *ic) @@ -116,8 +106,6 @@ static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, } if (recv->r_frag) { rds_ib_recv_unmap_page(ic, recv); - if (recv->r_frag->f_page) - rds_ib_frag_drop_page(recv->r_frag); rds_ib_frag_free(recv->r_frag); recv->r_frag = NULL; } @@ -129,16 +117,12 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic) for (i = 0; i < ic->i_recv_ring.w_nr; i++) rds_ib_recv_clear_one(ic, &ic->i_recvs[i]); - - if (ic->i_frag.f_page) - rds_ib_frag_drop_page(&ic->i_frag); } static int rds_ib_recv_refill_one(struct rds_connection *conn, struct rds_ib_recv_work *recv) { struct rds_ib_connection *ic = conn->c_transport_data; - dma_addr_t dma_addr; struct ib_sge *sge; int ret = -ENOMEM; @@ -161,50 +145,27 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, if (!recv->r_frag) goto out; INIT_LIST_HEAD(&recv->r_frag->f_item); - recv->r_frag->f_page = NULL; - } - - if (!ic->i_frag.f_page) { - ic->i_frag.f_page = alloc_page(GFP_NOWAIT); - if (!ic->i_frag.f_page) + sg_init_table(&recv->r_frag->f_sg, 1); + ret = rds_page_remainder_alloc(&recv->r_frag->f_sg, + RDS_FRAG_SIZE, GFP_NOWAIT); + if (ret) { + kmem_cache_free(rds_ib_frag_slab, recv->r_frag); + recv->r_frag = NULL; goto out; - ic->i_frag.f_offset = 0; + } } - dma_addr = ib_dma_map_page(ic->i_cm_id->device, - ic->i_frag.f_page, - ic->i_frag.f_offset, - RDS_FRAG_SIZE, - DMA_FROM_DEVICE); - if (ib_dma_mapping_error(ic->i_cm_id->device, dma_addr)) - goto out; - - /* - * Once we get the RDS_PAGE_LAST_OFF frag then rds_ib_frag_unmap() - * must be called on this recv. This happens as completions hit - * in order or on connection shutdown. - */ - recv->r_frag->f_page = ic->i_frag.f_page; - recv->r_frag->f_offset = ic->i_frag.f_offset; - recv->r_frag->f_mapped = dma_addr; + ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, + 1, DMA_FROM_DEVICE); + WARN_ON(ret != 1); sge = &recv->r_sge[0]; sge->addr = ic->i_recv_hdrs_dma + (recv - ic->i_recvs) * sizeof(struct rds_header); sge->length = sizeof(struct rds_header); sge = &recv->r_sge[1]; - sge->addr = dma_addr; - sge->length = RDS_FRAG_SIZE; - - get_page(recv->r_frag->f_page); - - if (ic->i_frag.f_offset < RDS_PAGE_LAST_OFF) { - ic->i_frag.f_offset += RDS_FRAG_SIZE; - } else { - put_page(ic->i_frag.f_page); - ic->i_frag.f_page = NULL; - ic->i_frag.f_offset = 0; - } + sge->addr = sg_dma_address(&recv->r_frag->f_sg); + sge->length = sg_dma_len(&recv->r_frag->f_sg); ret = 0; out: @@ -247,8 +208,8 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) /* XXX when can this fail? */ ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr); rdsdebug("recv %p ibinc %p page %p addr %lu ret %d\n", recv, - recv->r_ibinc, recv->r_frag->f_page, - (long) recv->r_frag->f_mapped, ret); + recv->r_ibinc, sg_page(&recv->r_frag->f_sg), + (long) sg_dma_address(&recv->r_frag->f_sg), ret); if (ret) { rds_ib_conn_error(conn, "recv post on " "%pI4 returned %d, disconnecting and " @@ -281,7 +242,6 @@ static void rds_ib_inc_purge(struct rds_incoming *inc) list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) { list_del_init(&frag->f_item); - rds_ib_frag_drop_page(frag); rds_ib_frag_free(frag); } } @@ -333,13 +293,13 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, to_copy = min_t(unsigned long, to_copy, len - copied); rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " - "[%p, %lu] + %lu\n", + "[%p, %u] + %lu\n", to_copy, iov->iov_base, iov->iov_len, iov_off, - frag->f_page, frag->f_offset, frag_off); + sg_page(&frag->f_sg), frag->f_sg.offset, frag_off); /* XXX needs + offset for multiple recvs per page */ - ret = rds_page_copy_to_user(frag->f_page, - frag->f_offset + frag_off, + ret = rds_page_copy_to_user(sg_page(&frag->f_sg), + frag->f_sg.offset + frag_off, iov->iov_base + iov_off, to_copy); if (ret) { @@ -595,7 +555,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off); BUG_ON(to_copy & 7); /* Must be 64bit aligned. */ - addr = kmap_atomic(frag->f_page, KM_SOFTIRQ0); + addr = kmap_atomic(sg_page(&frag->f_sg), KM_SOFTIRQ0); src = addr + frag_off; dst = (void *)map->m_page_addrs[map_page] + map_off; @@ -698,12 +658,12 @@ static void rds_ib_process_recv(struct rds_connection *conn, * the inc is freed. We don't go that route, so we have to drop the * page ref ourselves. We can't just leave the page on the recv * because that confuses the dma mapping of pages and each recv's use - * of a partial page. We can leave the frag, though, it will be - * reused. + * of a partial page. * * FIXME: Fold this into the code path below. */ - rds_ib_frag_drop_page(recv->r_frag); + rds_ib_frag_free(recv->r_frag); + recv->r_frag = NULL; return; } diff --git a/net/rds/page.c b/net/rds/page.c index e5b2527ae257..5e44f5ae7898 100644 --- a/net/rds/page.c +++ b/net/rds/page.c @@ -186,6 +186,7 @@ out: ret ? 0 : scat->length); return ret; } +EXPORT_SYMBOL_GPL(rds_page_remainder_alloc); static int rds_page_remainder_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) -- cgit v1.2.3 From 3427e854e1a0e76be8b3d75fc0fa878f59b43693 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 24 May 2010 20:28:49 -0700 Subject: RDS: Assume recv->r_frag is always NULL in refill_one() refill_one() should never be called on a recv struct that doesn't need a new r_frag allocated. Add a WARN and remove conditional around r_frag alloc code. Also, add a comment to explain why r_ibinc may or may not need refilling. Signed-off-by: Andy Grover --- net/rds/ib_recv.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index f6dbf16e0741..5c7e6acf7c60 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -126,6 +126,10 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, struct ib_sge *sge; int ret = -ENOMEM; + /* + * ibinc was taken from recv if recv contained the start of a message. + * recvs that were continuations will still have this allocated. + */ if (!recv->r_ibinc) { if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { rds_ib_stats_inc(s_ib_rx_alloc_limit); @@ -140,19 +144,18 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); } - if (!recv->r_frag) { - recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); - if (!recv->r_frag) - goto out; - INIT_LIST_HEAD(&recv->r_frag->f_item); - sg_init_table(&recv->r_frag->f_sg, 1); - ret = rds_page_remainder_alloc(&recv->r_frag->f_sg, - RDS_FRAG_SIZE, GFP_NOWAIT); - if (ret) { - kmem_cache_free(rds_ib_frag_slab, recv->r_frag); - recv->r_frag = NULL; - goto out; - } + WARN_ON(recv->r_frag); /* leak! */ + recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); + if (!recv->r_frag) + goto out; + INIT_LIST_HEAD(&recv->r_frag->f_item); + sg_init_table(&recv->r_frag->f_sg, 1); + ret = rds_page_remainder_alloc(&recv->r_frag->f_sg, + RDS_FRAG_SIZE, GFP_NOWAIT); + if (ret) { + kmem_cache_free(rds_ib_frag_slab, recv->r_frag); + recv->r_frag = NULL; + goto out; } ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, -- cgit v1.2.3 From fc24f78085e8771670af42f2b8929b16a0c98a22 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Tue, 25 May 2010 11:20:09 -0700 Subject: RDS/IB: Remove ib_recv_unmap_page() All it does is call unmap_sg(), so just call that directly. The comment above unmap_page also may be incorrect, so we shouldn't hold on to it, either. Signed-off-by: Andy Grover --- net/rds/ib_recv.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 5c7e6acf7c60..48add108ddee 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -51,24 +51,6 @@ static void rds_ib_frag_free(struct rds_page_frag *frag) kmem_cache_free(rds_ib_frag_slab, frag); } -/* - * We map a page at a time. Its fragments are posted in order. This - * is called in fragment order as the fragments get send completion events. - * Only the last frag in the page performs the unmapping. - * - * It's OK for ring cleanup to call this in whatever order it likes because - * DMA is not in flight and so we can unmap while other ring entries still - * hold page references in their frags. - */ -static void rds_ib_recv_unmap_page(struct rds_ib_connection *ic, - struct rds_ib_recv_work *recv) -{ - struct rds_page_frag *frag = recv->r_frag; - - rdsdebug("recv %p frag %p page %p\n", recv, frag, sg_page(&frag->f_sg)); - ib_dma_unmap_sg(ic->i_cm_id->device, &frag->f_sg, 1, DMA_FROM_DEVICE); -} - void rds_ib_recv_init_ring(struct rds_ib_connection *ic) { struct rds_ib_recv_work *recv; @@ -105,7 +87,7 @@ static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, recv->r_ibinc = NULL; } if (recv->r_frag) { - rds_ib_recv_unmap_page(ic, recv); + ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); rds_ib_frag_free(recv->r_frag); recv->r_frag = NULL; } @@ -768,7 +750,7 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic, recv = &ic->i_recvs[rds_ib_ring_oldest(&ic->i_recv_ring)]; - rds_ib_recv_unmap_page(ic, recv); + ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); /* * Also process recvs in connecting state because it is possible -- cgit v1.2.3 From 33244125871734ebc0d8d147680a0d7e99385e0b Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 26 May 2010 22:05:37 -0700 Subject: RDS/IB: Add caching of frags and incs This patch is based heavily on an initial patch by Chris Mason. Instead of freeing slab memory and pages, it keeps them, and funnels them back to be reused. The lock minimization strategy uses xchg and cmpxchg atomic ops for manipulation of pointers to list heads. We anchor the lists with a pointer to a list_head struct instead of a static list_head struct. We just have to carefully use the existing primitives with the difference between a pointer and a static head struct. For example, 'list_empty()' means that our anchor pointer points to a list with a single item instead of meaning that our static head element doesn't point to any list items. Original patch by Chris, with significant mods and fixes by Andy and Zach. Signed-off-by: Chris Mason Signed-off-by: Andy Grover Signed-off-by: Zach Brown --- net/rds/ib.h | 19 ++++ net/rds/ib_cm.c | 9 ++ net/rds/ib_recv.c | 321 +++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 297 insertions(+), 52 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 9bb7a7412a44..2efd9d11e7d4 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -21,6 +21,8 @@ #define RDS_IB_SUPPORTED_PROTOCOLS 0x00000003 /* minor versions supported */ +#define RDS_IB_RECYCLE_BATCH_COUNT 32 + extern struct list_head rds_ib_devices; /* @@ -30,14 +32,27 @@ extern struct list_head rds_ib_devices; */ struct rds_page_frag { struct list_head f_item; + struct list_head f_cache_entry; struct scatterlist f_sg; }; struct rds_ib_incoming { struct list_head ii_frags; + struct list_head ii_cache_entry; struct rds_incoming ii_inc; }; +struct rds_ib_cache_head { + struct list_head *first; + unsigned long count; +}; + +struct rds_ib_refill_cache { + struct rds_ib_cache_head *percpu; + struct list_head *xfer; + struct list_head *ready; +}; + struct rds_ib_connect_private { /* Add new fields at the end, and don't permute existing fields. */ __be32 dp_saddr; @@ -104,6 +119,8 @@ struct rds_ib_connection { u64 i_recv_hdrs_dma; struct rds_ib_recv_work *i_recvs; u64 i_ack_recv; /* last ACK received */ + struct rds_ib_refill_cache i_cache_incs; + struct rds_ib_refill_cache i_cache_frags; /* sending acks */ unsigned long i_ack_flags; @@ -304,6 +321,8 @@ void rds_ib_flush_mrs(void); int __init rds_ib_recv_init(void); void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); +int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); +void rds_ib_recv_free_caches(struct rds_ib_connection *ic); int rds_ib_recv_refill(struct rds_connection *conn, int prefill); void rds_ib_inc_free(struct rds_incoming *inc); int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index a9fb917c00bb..10f6a8815cd0 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -709,12 +709,19 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) { struct rds_ib_connection *ic; unsigned long flags; + int ret; /* XXX too lazy? */ ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL); if (!ic) return -ENOMEM; + ret = rds_ib_recv_alloc_caches(ic); + if (ret) { + kfree(ic); + return ret; + } + INIT_LIST_HEAD(&ic->ib_node); tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn, (unsigned long) ic); @@ -763,6 +770,8 @@ void rds_ib_conn_free(void *arg) list_del(&ic->ib_node); spin_unlock_irq(lock_ptr); + rds_ib_recv_free_caches(ic); + kfree(ic); } diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 48add108ddee..5b429b7fd81c 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -43,14 +43,6 @@ static struct kmem_cache *rds_ib_incoming_slab; static struct kmem_cache *rds_ib_frag_slab; static atomic_t rds_ib_allocation = ATOMIC_INIT(0); -/* Free frag and attached recv buffer f_sg */ -static void rds_ib_frag_free(struct rds_page_frag *frag) -{ - rdsdebug("frag %p page %p\n", frag, sg_page(&frag->f_sg)); - __free_page(sg_page(&frag->f_sg)); - kmem_cache_free(rds_ib_frag_slab, frag); -} - void rds_ib_recv_init_ring(struct rds_ib_connection *ic) { struct rds_ib_recv_work *recv; @@ -79,6 +71,151 @@ void rds_ib_recv_init_ring(struct rds_ib_connection *ic) } } +/* + * The entire 'from' list, including the from element itself, is put on + * to the tail of the 'to' list. + */ +static void list_splice_entire_tail(struct list_head *from, + struct list_head *to) +{ + struct list_head *from_last = from->prev; + + list_splice_tail(from_last, to); + list_add_tail(from_last, to); +} + +static void rds_ib_cache_xfer_to_ready(struct rds_ib_refill_cache *cache) +{ + struct list_head *tmp; + + tmp = xchg(&cache->xfer, NULL); + if (tmp) { + if (cache->ready) + list_splice_entire_tail(tmp, cache->ready); + else + cache->ready = tmp; + } +} + +static int rds_ib_recv_alloc_cache(struct rds_ib_refill_cache *cache) +{ + struct rds_ib_cache_head *head; + int cpu; + + cache->percpu = alloc_percpu(struct rds_ib_cache_head); + if (!cache->percpu) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + head = per_cpu_ptr(cache->percpu, cpu); + head->first = NULL; + head->count = 0; + } + cache->xfer = NULL; + cache->ready = NULL; + + return 0; +} + +int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic) +{ + int ret; + + ret = rds_ib_recv_alloc_cache(&ic->i_cache_incs); + if (!ret) { + ret = rds_ib_recv_alloc_cache(&ic->i_cache_frags); + if (ret) + free_percpu(ic->i_cache_incs.percpu); + } + + return ret; +} + +static void rds_ib_cache_splice_all_lists(struct rds_ib_refill_cache *cache, + struct list_head *caller_list) +{ + struct rds_ib_cache_head *head; + int cpu; + + for_each_possible_cpu(cpu) { + head = per_cpu_ptr(cache->percpu, cpu); + if (head->first) { + list_splice_entire_tail(head->first, caller_list); + head->first = NULL; + } + } + + if (cache->ready) { + list_splice_entire_tail(cache->ready, caller_list); + cache->ready = NULL; + } +} + +void rds_ib_recv_free_caches(struct rds_ib_connection *ic) +{ + struct rds_ib_incoming *inc; + struct rds_ib_incoming *inc_tmp; + struct rds_page_frag *frag; + struct rds_page_frag *frag_tmp; + LIST_HEAD(list); + + rds_ib_cache_xfer_to_ready(&ic->i_cache_incs); + rds_ib_cache_splice_all_lists(&ic->i_cache_incs, &list); + free_percpu(ic->i_cache_incs.percpu); + + list_for_each_entry_safe(inc, inc_tmp, &list, ii_cache_entry) { + list_del(&inc->ii_cache_entry); + WARN_ON(!list_empty(&inc->ii_frags)); + kmem_cache_free(rds_ib_incoming_slab, inc); + } + + rds_ib_cache_xfer_to_ready(&ic->i_cache_frags); + rds_ib_cache_splice_all_lists(&ic->i_cache_frags, &list); + free_percpu(ic->i_cache_frags.percpu); + + list_for_each_entry_safe(frag, frag_tmp, &list, f_cache_entry) { + list_del(&frag->f_cache_entry); + WARN_ON(!list_empty(&frag->f_item)); + kmem_cache_free(rds_ib_frag_slab, frag); + } +} + +/* fwd decl */ +static void rds_ib_recv_cache_put(struct list_head *new_item, + struct rds_ib_refill_cache *cache); +static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache); + + +/* Recycle frag and attached recv buffer f_sg */ +static void rds_ib_frag_free(struct rds_ib_connection *ic, + struct rds_page_frag *frag) +{ + rdsdebug("frag %p page %p\n", frag, sg_page(&frag->f_sg)); + + rds_ib_recv_cache_put(&frag->f_cache_entry, &ic->i_cache_frags); +} + +/* Recycle inc after freeing attached frags */ +void rds_ib_inc_free(struct rds_incoming *inc) +{ + struct rds_ib_incoming *ibinc; + struct rds_page_frag *frag; + struct rds_page_frag *pos; + struct rds_ib_connection *ic = inc->i_conn->c_transport_data; + + ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); + + /* Free attached frags */ + list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) { + list_del_init(&frag->f_item); + rds_ib_frag_free(ic, frag); + } + BUG_ON(!list_empty(&ibinc->ii_frags)); + + rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc); + rds_ib_recv_cache_put(&ibinc->ii_cache_entry, &ic->i_cache_incs); +} + static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, struct rds_ib_recv_work *recv) { @@ -88,7 +225,7 @@ static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, } if (recv->r_frag) { ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); - rds_ib_frag_free(recv->r_frag); + rds_ib_frag_free(ic, recv->r_frag); recv->r_frag = NULL; } } @@ -101,6 +238,61 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic) rds_ib_recv_clear_one(ic, &ic->i_recvs[i]); } +static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *ic) +{ + struct rds_ib_incoming *ibinc; + struct list_head *cache_item; + int avail_allocs; + + cache_item = rds_ib_recv_cache_get(&ic->i_cache_incs); + if (cache_item) { + ibinc = container_of(cache_item, struct rds_ib_incoming, ii_cache_entry); + } else { + avail_allocs = atomic_add_unless(&rds_ib_allocation, + 1, rds_ib_sysctl_max_recv_allocation); + if (!avail_allocs) { + rds_ib_stats_inc(s_ib_rx_alloc_limit); + return NULL; + } + ibinc = kmem_cache_alloc(rds_ib_incoming_slab, GFP_NOWAIT); + if (!ibinc) { + atomic_dec(&rds_ib_allocation); + return NULL; + } + } + INIT_LIST_HEAD(&ibinc->ii_frags); + rds_inc_init(&ibinc->ii_inc, ic->conn, ic->conn->c_faddr); + + return ibinc; +} + +static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic) +{ + struct rds_page_frag *frag; + struct list_head *cache_item; + int ret; + + cache_item = rds_ib_recv_cache_get(&ic->i_cache_frags); + if (cache_item) { + frag = container_of(cache_item, struct rds_page_frag, f_cache_entry); + } else { + frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); + if (!frag) + return NULL; + + ret = rds_page_remainder_alloc(&frag->f_sg, + RDS_FRAG_SIZE, GFP_NOWAIT); + if (ret) { + kmem_cache_free(rds_ib_frag_slab, frag); + return NULL; + } + } + + INIT_LIST_HEAD(&frag->f_item); + + return frag; +} + static int rds_ib_recv_refill_one(struct rds_connection *conn, struct rds_ib_recv_work *recv) { @@ -108,37 +300,25 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, struct ib_sge *sge; int ret = -ENOMEM; + if (!ic->i_cache_incs.ready) + rds_ib_cache_xfer_to_ready(&ic->i_cache_incs); + if (!ic->i_cache_frags.ready) + rds_ib_cache_xfer_to_ready(&ic->i_cache_frags); + /* * ibinc was taken from recv if recv contained the start of a message. * recvs that were continuations will still have this allocated. */ if (!recv->r_ibinc) { - if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { - rds_ib_stats_inc(s_ib_rx_alloc_limit); - goto out; - } - recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, GFP_NOWAIT); - if (!recv->r_ibinc) { - atomic_dec(&rds_ib_allocation); + recv->r_ibinc = rds_ib_refill_one_inc(ic); + if (!recv->r_ibinc) goto out; - } - INIT_LIST_HEAD(&recv->r_ibinc->ii_frags); - rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); } WARN_ON(recv->r_frag); /* leak! */ - recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); + recv->r_frag = rds_ib_refill_one_frag(ic); if (!recv->r_frag) goto out; - INIT_LIST_HEAD(&recv->r_frag->f_item); - sg_init_table(&recv->r_frag->f_sg, 1); - ret = rds_page_remainder_alloc(&recv->r_frag->f_sg, - RDS_FRAG_SIZE, GFP_NOWAIT); - if (ret) { - kmem_cache_free(rds_ib_frag_slab, recv->r_frag); - recv->r_frag = NULL; - goto out; - } ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); @@ -160,8 +340,7 @@ out: /* * This tries to allocate and post unused work requests after making sure that * they have all the allocations they need to queue received fragments into - * sockets. The i_recv_mutex is held here so that ring_alloc and _unalloc - * pairs don't go unmatched. + * sockets. * * -1 is returned if posting fails due to temporary resource exhaustion. */ @@ -216,33 +395,71 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) return ret; } -static void rds_ib_inc_purge(struct rds_incoming *inc) +/* + * We want to recycle several types of recv allocations, like incs and frags. + * To use this, the *_free() function passes in the ptr to a list_head within + * the recyclee, as well as the cache to put it on. + * + * First, we put the memory on a percpu list. When this reaches a certain size, + * We move it to an intermediate non-percpu list in a lockless manner, with some + * xchg/compxchg wizardry. + * + * N.B. Instead of a list_head as the anchor, we use a single pointer, which can + * be NULL and xchg'd. The list is actually empty when the pointer is NULL, and + * list_empty() will return true with one element is actually present. + */ +static void rds_ib_recv_cache_put(struct list_head *new_item, + struct rds_ib_refill_cache *cache) { - struct rds_ib_incoming *ibinc; - struct rds_page_frag *frag; - struct rds_page_frag *pos; + unsigned long flags; + struct rds_ib_cache_head *chp; + struct list_head *old; - ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); - rdsdebug("purging ibinc %p inc %p\n", ibinc, inc); + local_irq_save(flags); - list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) { - list_del_init(&frag->f_item); - rds_ib_frag_free(frag); - } + chp = per_cpu_ptr(cache->percpu, smp_processor_id()); + if (!chp->first) + INIT_LIST_HEAD(new_item); + else /* put on front */ + list_add_tail(new_item, chp->first); + chp->first = new_item; + chp->count++; + + if (chp->count < RDS_IB_RECYCLE_BATCH_COUNT) + goto end; + + /* + * Return our per-cpu first list to the cache's xfer by atomically + * grabbing the current xfer list, appending it to our per-cpu list, + * and then atomically returning that entire list back to the + * cache's xfer list as long as it's still empty. + */ + do { + old = xchg(&cache->xfer, NULL); + if (old) + list_splice_entire_tail(old, chp->first); + old = cmpxchg(&cache->xfer, NULL, chp->first); + } while (old); + + chp->first = NULL; + chp->count = 0; +end: + local_irq_restore(flags); } -void rds_ib_inc_free(struct rds_incoming *inc) +static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache) { - struct rds_ib_incoming *ibinc; - - ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); + struct list_head *head = cache->ready; + + if (head) { + if (!list_empty(head)) { + cache->ready = head->next; + list_del_init(head); + } else + cache->ready = NULL; + } - rds_ib_inc_purge(inc); - rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc); - BUG_ON(!list_empty(&ibinc->ii_frags)); - kmem_cache_free(rds_ib_incoming_slab, ibinc); - atomic_dec(&rds_ib_allocation); - BUG_ON(atomic_read(&rds_ib_allocation) < 0); + return head; } int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, @@ -647,7 +864,7 @@ static void rds_ib_process_recv(struct rds_connection *conn, * * FIXME: Fold this into the code path below. */ - rds_ib_frag_free(recv->r_frag); + rds_ib_frag_free(ic, recv->r_frag); recv->r_frag = NULL; return; } -- cgit v1.2.3 From 037f18a3074753991656189a091a5fa371999107 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 26 May 2010 21:45:06 -0700 Subject: RDS: use friendly gfp masks for prefill When prefilling the rds frags, we end up doing a lot of allocations. We're not in atomic context here, and so there's no reason to dip into atomic reserves. This changes the prefills to use masks that allow waiting. Signed-off-by: Chris Mason --- net/rds/ib_recv.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 5b429b7fd81c..1add097fe198 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -238,7 +238,8 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic) rds_ib_recv_clear_one(ic, &ic->i_recvs[i]); } -static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *ic) +static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *ic, + gfp_t slab_mask) { struct rds_ib_incoming *ibinc; struct list_head *cache_item; @@ -254,7 +255,7 @@ static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *i rds_ib_stats_inc(s_ib_rx_alloc_limit); return NULL; } - ibinc = kmem_cache_alloc(rds_ib_incoming_slab, GFP_NOWAIT); + ibinc = kmem_cache_alloc(rds_ib_incoming_slab, slab_mask); if (!ibinc) { atomic_dec(&rds_ib_allocation); return NULL; @@ -266,7 +267,8 @@ static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *i return ibinc; } -static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic) +static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic, + gfp_t slab_mask, gfp_t page_mask) { struct rds_page_frag *frag; struct list_head *cache_item; @@ -276,12 +278,12 @@ static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic if (cache_item) { frag = container_of(cache_item, struct rds_page_frag, f_cache_entry); } else { - frag = kmem_cache_alloc(rds_ib_frag_slab, GFP_NOWAIT); + frag = kmem_cache_alloc(rds_ib_frag_slab, slab_mask); if (!frag) return NULL; ret = rds_page_remainder_alloc(&frag->f_sg, - RDS_FRAG_SIZE, GFP_NOWAIT); + RDS_FRAG_SIZE, page_mask); if (ret) { kmem_cache_free(rds_ib_frag_slab, frag); return NULL; @@ -294,11 +296,18 @@ static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic } static int rds_ib_recv_refill_one(struct rds_connection *conn, - struct rds_ib_recv_work *recv) + struct rds_ib_recv_work *recv, int prefill) { struct rds_ib_connection *ic = conn->c_transport_data; struct ib_sge *sge; int ret = -ENOMEM; + gfp_t slab_mask = GFP_NOWAIT; + gfp_t page_mask = GFP_NOWAIT; + + if (prefill) { + slab_mask = GFP_KERNEL; + page_mask = GFP_HIGHUSER; + } if (!ic->i_cache_incs.ready) rds_ib_cache_xfer_to_ready(&ic->i_cache_incs); @@ -310,13 +319,13 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, * recvs that were continuations will still have this allocated. */ if (!recv->r_ibinc) { - recv->r_ibinc = rds_ib_refill_one_inc(ic); + recv->r_ibinc = rds_ib_refill_one_inc(ic, slab_mask); if (!recv->r_ibinc) goto out; } WARN_ON(recv->r_frag); /* leak! */ - recv->r_frag = rds_ib_refill_one_frag(ic); + recv->r_frag = rds_ib_refill_one_frag(ic, slab_mask, page_mask); if (!recv->r_frag) goto out; @@ -363,7 +372,7 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) } recv = &ic->i_recvs[pos]; - ret = rds_ib_recv_refill_one(conn, recv); + ret = rds_ib_recv_refill_one(conn, recv, prefill); if (ret) { ret = -1; break; -- cgit v1.2.3 From 671202f3491cccdb267f88ad59ba0635aeb2a22e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 4 Jun 2010 14:26:32 -0700 Subject: rds: remove unused rds_send_acked_before() rds_send_acked_before() wasn't blocking interrupts when acquiring c_lock from user context but nothing calls it. Rather than fix its use of c_lock we just remove the function. Signed-off-by: Zach Brown --- net/rds/rds.h | 1 - net/rds/send.c | 29 ----------------------------- 2 files changed, 30 deletions(-) diff --git a/net/rds/rds.h b/net/rds/rds.h index cba5f8bb4780..270ded76fd53 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -724,7 +724,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest); typedef int (*is_acked_func)(struct rds_message *rm, uint64_t ack); void rds_send_drop_acked(struct rds_connection *conn, u64 ack, is_acked_func is_acked); -int rds_send_acked_before(struct rds_connection *conn, u64 seq); void rds_send_remove_from_sock(struct list_head *messages, int status); int rds_send_pong(struct rds_connection *conn, __be16 dport); struct rds_message *rds_send_get_message(struct rds_connection *, diff --git a/net/rds/send.c b/net/rds/send.c index a6295993e3e1..b9e41afef323 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -404,35 +404,6 @@ static inline int rds_send_is_acked(struct rds_message *rm, u64 ack, return be64_to_cpu(rm->m_inc.i_hdr.h_sequence) <= ack; } -/* - * Returns true if there are no messages on the send and retransmit queues - * which have a sequence number greater than or equal to the given sequence - * number. - */ -int rds_send_acked_before(struct rds_connection *conn, u64 seq) -{ - struct rds_message *rm, *tmp; - int ret = 1; - - spin_lock(&conn->c_lock); - - list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq) - ret = 0; - break; - } - - list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq) - ret = 0; - break; - } - - spin_unlock(&conn->c_lock); - - return ret; -} - /* * This is pretty similar to what happens below in the ACK * handling code - except that we call here as soon as we get -- cgit v1.2.3 From 501dcccdb7a2335cde07d4acb56e636182d62944 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 4 Jun 2010 14:25:27 -0700 Subject: rds: block ints when acquiring c_lock in rds_conn_message_info() conn->c_lock is acquired in interrupt context. rds_conn_message_info() is called from user context and was acquiring c_lock without blocking interrupts, leading to possible deadlocks. Signed-off-by: Zach Brown --- net/rds/connection.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 5bd96d538fb9..5bb0eec5ada3 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -375,6 +375,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, struct rds_connection *conn; struct rds_message *rm; unsigned int total = 0; + unsigned long flags; size_t i; len /= sizeof(struct rds_info_message); @@ -389,7 +390,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, else list = &conn->c_retrans; - spin_lock(&conn->c_lock); + spin_lock_irqsave(&conn->c_lock, flags); /* XXX too lazy to maintain counts.. */ list_for_each_entry(rm, list, m_conn_item) { @@ -400,7 +401,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, conn->c_faddr, 0); } - spin_unlock(&conn->c_lock); + spin_unlock_irqrestore(&conn->c_lock, flags); } } rcu_read_unlock(); -- cgit v1.2.3 From 0f4b1c7e89e699f588807a914ec6e6396c851a72 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 4 Jun 2010 14:41:41 -0700 Subject: rds: fix rds_send_xmit() serialization rds_send_xmit() was changed to hold an interrupt masking spinlock instead of a mutex so that it could be called from the IB receive tasklet path. This broke the TCP transport because its xmit method can block and masks and unmasks interrupts. This patch serializes callers to rds_send_xmit() with a simple bit instead of the current spinlock or previous mutex. This enables rds_send_xmit() to be called from any context and to call functions which block. Getting rid of the c_send_lock exposes the bare c_lock acquisitions which are changed to block interrupts. A waitqueue is added so that rds_conn_shutdown() can wait for callers to leave rds_send_xmit() before tearing down partial send state. This lets us get rid of c_senders. rds_send_xmit() is changed to check the conn state after acquiring the RDS_IN_XMIT bit to resolve races with the shutdown path. Previously both worked with the conn state and then the lock in the same order, allowing them to race and execute the paths concurrently. rds_send_reset() isn't racing with rds_send_xmit() now that rds_conn_shutdown() properly ensures that rds_send_xmit() can't start once the conn state has been changed. We can remove its previous use of the spinlock. Finally, c_send_generation is redundant. Callers can race to test the c_flags bit by simply retrying instead of racing to test the c_send_generation atomic. Signed-off-by: Zach Brown --- net/rds/connection.c | 19 ++++-------- net/rds/ib_send.c | 2 +- net/rds/rds.h | 5 ++-- net/rds/send.c | 82 +++++++++++++++++++++++++++------------------------- net/rds/threads.c | 2 +- 5 files changed, 52 insertions(+), 58 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 5bb0eec5ada3..89871db77f8f 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -148,9 +148,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, spin_lock_init(&conn->c_lock); conn->c_next_tx_seq = 1; - spin_lock_init(&conn->c_send_lock); - atomic_set(&conn->c_send_generation, 1); - atomic_set(&conn->c_senders, 0); + init_waitqueue_head(&conn->c_waitq); INIT_LIST_HEAD(&conn->c_send_queue); INIT_LIST_HEAD(&conn->c_retrans); @@ -275,15 +273,8 @@ void rds_conn_shutdown(struct rds_connection *conn) } mutex_unlock(&conn->c_cm_lock); - /* verify everybody's out of rds_send_xmit() */ - spin_lock_irq(&conn->c_send_lock); - spin_unlock_irq(&conn->c_send_lock); - - while(atomic_read(&conn->c_senders)) { - schedule_timeout(1); - spin_lock_irq(&conn->c_send_lock); - spin_unlock_irq(&conn->c_send_lock); - } + wait_event(conn->c_waitq, + !test_bit(RDS_IN_XMIT, &conn->c_flags)); conn->c_trans->conn_shutdown(conn); rds_conn_reset(conn); @@ -477,8 +468,8 @@ static int rds_conn_info_visitor(struct rds_connection *conn, sizeof(cinfo->transport)); cinfo->flags = 0; - rds_conn_info_set(cinfo->flags, - spin_is_locked(&conn->c_send_lock), SENDING); + rds_conn_info_set(cinfo->flags, test_bit(RDS_IN_XMIT, &conn->c_flags), + SENDING); /* XXX Future: return the state rather than these funky bits */ rds_conn_info_set(cinfo->flags, atomic_read(&conn->c_state) == RDS_CONN_CONNECTING, diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 3f91e794eae9..e88cb4af009b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -321,7 +321,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) * credits (see rds_ib_send_add_credits below). * * The RDS send code is essentially single-threaded; rds_send_xmit - * grabs c_send_lock to ensure exclusive access to the send ring. + * sets RDS_IN_XMIT to ensure exclusive access to the send ring. * However, the ACK sending code is independent and can race with * message SENDs. * diff --git a/net/rds/rds.h b/net/rds/rds.h index 270ded76fd53..4510344ce8ca 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -80,6 +80,7 @@ enum { /* Bits for c_flags */ #define RDS_LL_SEND_FULL 0 #define RDS_RECONNECT_PENDING 1 +#define RDS_IN_XMIT 2 struct rds_connection { struct hlist_node c_hash_node; @@ -91,9 +92,6 @@ struct rds_connection { struct rds_cong_map *c_lcong; struct rds_cong_map *c_fcong; - spinlock_t c_send_lock; /* protect send ring */ - atomic_t c_send_generation; - atomic_t c_senders; struct rds_message *c_xmit_rm; unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; @@ -120,6 +118,7 @@ struct rds_connection { struct delayed_work c_conn_w; struct work_struct c_down_w; struct mutex c_cm_lock; /* protect conn state & cm */ + wait_queue_head_t c_waitq; struct list_head c_map_item; unsigned long c_map_queued; diff --git a/net/rds/send.c b/net/rds/send.c index b9e41afef323..81471b25373b 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -53,14 +53,14 @@ module_param(send_batch_count, int, 0444); MODULE_PARM_DESC(send_batch_count, " batch factor when working the send queue"); /* - * Reset the send state. Caller must hold c_send_lock when calling here. + * Reset the send state. Callers must ensure that this doesn't race with + * rds_send_xmit(). */ void rds_send_reset(struct rds_connection *conn) { struct rds_message *rm, *tmp; unsigned long flags; - spin_lock_irqsave(&conn->c_send_lock, flags); if (conn->c_xmit_rm) { rm = conn->c_xmit_rm; conn->c_xmit_rm = NULL; @@ -69,11 +69,7 @@ void rds_send_reset(struct rds_connection *conn) * independently) but as the connection is down, there's * no ongoing RDMA to/from that memory */ rds_message_unmapped(rm); - spin_unlock_irqrestore(&conn->c_send_lock, flags); - rds_message_put(rm); - } else { - spin_unlock_irqrestore(&conn->c_send_lock, flags); } conn->c_xmit_sg = 0; @@ -98,6 +94,25 @@ void rds_send_reset(struct rds_connection *conn) spin_unlock_irqrestore(&conn->c_lock, flags); } +static int acquire_in_xmit(struct rds_connection *conn) +{ + return test_and_set_bit(RDS_IN_XMIT, &conn->c_flags) == 0; +} + +static void release_in_xmit(struct rds_connection *conn) +{ + clear_bit(RDS_IN_XMIT, &conn->c_flags); + smp_mb__after_clear_bit(); + /* + * We don't use wait_on_bit()/wake_up_bit() because our waking is in a + * hot path and finding waiters is very rare. We don't want to walk + * the system-wide hashed waitqueue buckets in the fast path only to + * almost never find waiters. + */ + if (waitqueue_active(&conn->c_waitq)) + wake_up_all(&conn->c_waitq); +} + /* * We're making the concious trade-off here to only send one message * down the connection at a time. @@ -119,12 +134,9 @@ int rds_send_xmit(struct rds_connection *conn) unsigned int tmp; struct scatterlist *sg; int ret = 0; - int gen = 0; LIST_HEAD(to_be_dropped); restart: - if (!rds_conn_up(conn)) - goto out; /* * sendmsg calls here after having queued its message on the send @@ -133,18 +145,25 @@ restart: * avoids blocking the caller and trading per-connection data between * caches per message. */ - if (!spin_trylock_irqsave(&conn->c_send_lock, flags)) { + if (!acquire_in_xmit(conn)) { rds_stats_inc(s_send_lock_contention); ret = -ENOMEM; goto out; } - atomic_inc(&conn->c_senders); + + /* + * rds_conn_shutdown() sets the conn state and then tests RDS_IN_XMIT, + * we do the opposite to avoid races. + */ + if (!rds_conn_up(conn)) { + release_in_xmit(conn); + ret = 0; + goto out; + } if (conn->c_trans->xmit_prepare) conn->c_trans->xmit_prepare(conn); - gen = atomic_inc_return(&conn->c_send_generation); - /* * spin trying to push headers and data down the connection until * the connection doesn't make forward progress. @@ -178,7 +197,7 @@ restart: if (!rm) { unsigned int len; - spin_lock(&conn->c_lock); + spin_lock_irqsave(&conn->c_lock, flags); if (!list_empty(&conn->c_send_queue)) { rm = list_entry(conn->c_send_queue.next, @@ -193,7 +212,7 @@ restart: list_move_tail(&rm->m_conn_item, &conn->c_retrans); } - spin_unlock(&conn->c_lock); + spin_unlock_irqrestore(&conn->c_lock, flags); if (!rm) break; @@ -207,10 +226,10 @@ restart: */ if (rm->rdma.op_active && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { - spin_lock(&conn->c_lock); + spin_lock_irqsave(&conn->c_lock, flags); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) list_move(&rm->m_conn_item, &to_be_dropped); - spin_unlock(&conn->c_lock); + spin_unlock_irqrestore(&conn->c_lock, flags); continue; } @@ -336,19 +355,7 @@ restart: if (conn->c_trans->xmit_complete) conn->c_trans->xmit_complete(conn); - /* - * We might be racing with another sender who queued a message but - * backed off on noticing that we held the c_send_lock. If we check - * for queued messages after dropping the sem then either we'll - * see the queued message or the queuer will get the sem. If we - * notice the queued message then we trigger an immediate retry. - * - * We need to be careful only to do this when we stopped processing - * the send queue because it was empty. It's the only way we - * stop processing the loop when the transport hasn't taken - * responsibility for forward progress. - */ - spin_unlock_irqrestore(&conn->c_send_lock, flags); + release_in_xmit(conn); /* Nuke any messages we decided not to retransmit. */ if (!list_empty(&to_be_dropped)) { @@ -358,13 +365,12 @@ restart: rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); } - atomic_dec(&conn->c_senders); - /* - * Other senders will see we have c_send_lock and exit. We - * need to recheck the send queue and race again for c_send_lock - * to make sure messages don't just sit on the send queue, if - * somebody hasn't already beat us into the loop. + * Other senders can queue a message after we last test the send queue + * but before we clear RDS_IN_XMIT. In that case they'd back off and + * not try and send their newly queued message. We need to check the + * send queue after having cleared RDS_IN_XMIT so that their message + * doesn't get stuck on the send queue. * * If the transport cannot continue (i.e ret != 0), then it must * call us when more room is available, such as from the tx @@ -374,9 +380,7 @@ restart: smp_mb(); if (!list_empty(&conn->c_send_queue)) { rds_stats_inc(s_send_lock_queue_raced); - if (gen == atomic_read(&conn->c_send_generation)) { - goto restart; - } + goto restart; } } out: diff --git a/net/rds/threads.c b/net/rds/threads.c index 7a8ca7a1d983..2bab9bf07b91 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -61,7 +61,7 @@ * * Transition to state DISCONNECTING/DOWN: * - Inside the shutdown worker; synchronizes with xmit path - * through c_send_lock, and with connection management callbacks + * through RDS_IN_XMIT, and with connection management callbacks * via c_cm_lock. * * For receive callbacks, we rely on the underlying transport -- cgit v1.2.3 From 6fa70da6081bbcf948801fd5ee0be4d222298a43 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 11 Jun 2010 11:17:59 -0700 Subject: rds: recycle FMRs through lockless lists FRM allocation and recycling is performance critical and fairly lock intensive. The current code has a per connection lock that all processes bang on and it becomes a major bottleneck on large systems. This changes things to use a number of cmpxchg based lists instead, allowing us to go through the whole FMR lifecycle without locking inside RDS. Zach Brown pointed out that our usage of cmpxchg for xlist removal is racey if someone manages to remove and add back an FMR struct into the list while another CPU can see the FMR's address at the head of the list. The second CPU might assume the list hasn't changed when in fact any number of operations might have happened in between the deletion and reinsertion. This commit maintains a per cpu count of CPUs that are currently in xlist removal, and establishes a grace period to make sure that nobody can see an entry we have just removed from the list. Signed-off-by: Chris Mason --- net/rds/ib_rdma.c | 214 +++++++++++++++++++++++++++++++++++++++++++----------- net/rds/xlist.h | 110 ++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 42 deletions(-) create mode 100644 net/rds/xlist.h diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 64b5ede037c8..8c40391de5a2 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -36,7 +36,10 @@ #include "rds.h" #include "ib.h" +#include "xlist.h" +static DEFINE_PER_CPU(unsigned long, clean_list_grace); +#define CLEAN_LIST_BUSY_BIT 0 /* * This is stored as mr->r_trans_private. @@ -45,7 +48,11 @@ struct rds_ib_mr { struct rds_ib_device *device; struct rds_ib_mr_pool *pool; struct ib_fmr *fmr; - struct list_head list; + + struct xlist_head xlist; + + /* unmap_list is for freeing */ + struct list_head unmap_list; unsigned int remap_count; struct scatterlist *sg; @@ -61,12 +68,14 @@ struct rds_ib_mr_pool { struct mutex flush_lock; /* serialize fmr invalidate */ struct work_struct flush_worker; /* flush worker */ - spinlock_t list_lock; /* protect variables below */ atomic_t item_count; /* total # of MRs */ atomic_t dirty_count; /* # dirty of MRs */ - struct list_head drop_list; /* MRs that have reached their max_maps limit */ - struct list_head free_list; /* unused MRs */ - struct list_head clean_list; /* unused & unamapped MRs */ + + struct xlist_head drop_list; /* MRs that have reached their max_maps limit */ + struct xlist_head free_list; /* unused MRs */ + struct xlist_head clean_list; /* global unused & unamapped MRs */ + wait_queue_head_t flush_wait; + atomic_t free_pinned; /* memory pinned by free MRs */ unsigned long max_items; unsigned long max_items_soft; @@ -74,7 +83,7 @@ struct rds_ib_mr_pool { struct ib_fmr_attr fmr_attr; }; -static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all); +static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all, struct rds_ib_mr **); static void rds_ib_teardown_mr(struct rds_ib_mr *ibmr); static void rds_ib_mr_pool_flush_worker(struct work_struct *work); @@ -212,11 +221,11 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev) if (!pool) return ERR_PTR(-ENOMEM); - INIT_LIST_HEAD(&pool->free_list); - INIT_LIST_HEAD(&pool->drop_list); - INIT_LIST_HEAD(&pool->clean_list); + INIT_XLIST_HEAD(&pool->free_list); + INIT_XLIST_HEAD(&pool->drop_list); + INIT_XLIST_HEAD(&pool->clean_list); mutex_init(&pool->flush_lock); - spin_lock_init(&pool->list_lock); + init_waitqueue_head(&pool->flush_wait); INIT_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker); pool->fmr_attr.max_pages = fmr_message_size; @@ -246,27 +255,50 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) { cancel_work_sync(&pool->flush_worker); - rds_ib_flush_mr_pool(pool, 1); + rds_ib_flush_mr_pool(pool, 1, NULL); WARN_ON(atomic_read(&pool->item_count)); WARN_ON(atomic_read(&pool->free_pinned)); kfree(pool); } +static void refill_local(struct rds_ib_mr_pool *pool, struct xlist_head *xl, + struct rds_ib_mr **ibmr_ret) +{ + struct xlist_head *ibmr_xl; + ibmr_xl = xlist_del_head_fast(xl); + *ibmr_ret = list_entry(ibmr_xl, struct rds_ib_mr, xlist); +} + static inline struct rds_ib_mr *rds_ib_reuse_fmr(struct rds_ib_mr_pool *pool) { struct rds_ib_mr *ibmr = NULL; - unsigned long flags; + struct xlist_head *ret; + unsigned long *flag; - spin_lock_irqsave(&pool->list_lock, flags); - if (!list_empty(&pool->clean_list)) { - ibmr = list_entry(pool->clean_list.next, struct rds_ib_mr, list); - list_del_init(&ibmr->list); - } - spin_unlock_irqrestore(&pool->list_lock, flags); + preempt_disable(); + flag = &__get_cpu_var(clean_list_grace); + set_bit(CLEAN_LIST_BUSY_BIT, flag); + ret = xlist_del_head(&pool->clean_list); + if (ret) + ibmr = list_entry(ret, struct rds_ib_mr, xlist); + clear_bit(CLEAN_LIST_BUSY_BIT, flag); + preempt_enable(); return ibmr; } +static inline void wait_clean_list_grace(void) +{ + int cpu; + unsigned long *flag; + + for_each_online_cpu(cpu) { + flag = &per_cpu(clean_list_grace, cpu); + while (test_bit(CLEAN_LIST_BUSY_BIT, flag)) + cpu_relax(); + } +} + static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) { struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; @@ -299,7 +331,9 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) /* We do have some empty MRs. Flush them out. */ rds_ib_stats_inc(s_ib_rdma_mr_pool_wait); - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, &ibmr); + if (ibmr) + return ibmr; } ibmr = kzalloc_node(sizeof(*ibmr), GFP_KERNEL, rdsibdev_to_node(rds_ibdev)); @@ -493,34 +527,110 @@ static inline unsigned int rds_ib_flush_goal(struct rds_ib_mr_pool *pool, int fr return 0; } +/* + * given an xlist of mrs, put them all into the list_head for more processing + */ +static void xlist_append_to_list(struct xlist_head *xlist, struct list_head *list) +{ + struct rds_ib_mr *ibmr; + struct xlist_head splice; + struct xlist_head *cur; + struct xlist_head *next; + + splice.next = NULL; + xlist_splice(xlist, &splice); + cur = splice.next; + while (cur) { + next = cur->next; + ibmr = list_entry(cur, struct rds_ib_mr, xlist); + list_add_tail(&ibmr->unmap_list, list); + cur = next; + } +} + +/* + * this takes a list head of mrs and turns it into an xlist of clusters. + * each cluster has an xlist of MR_CLUSTER_SIZE mrs that are ready for + * reuse. + */ +static void list_append_to_xlist(struct rds_ib_mr_pool *pool, + struct list_head *list, struct xlist_head *xlist, + struct xlist_head **tail_ret) +{ + struct rds_ib_mr *ibmr; + struct xlist_head *cur_mr = xlist; + struct xlist_head *tail_mr = NULL; + + list_for_each_entry(ibmr, list, unmap_list) { + tail_mr = &ibmr->xlist; + tail_mr->next = NULL; + cur_mr->next = tail_mr; + cur_mr = tail_mr; + } + *tail_ret = tail_mr; +} + /* * Flush our pool of MRs. * At a minimum, all currently unused MRs are unmapped. * If the number of MRs allocated exceeds the limit, we also try * to free as many MRs as needed to get back to this limit. */ -static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) +static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, + int free_all, struct rds_ib_mr **ibmr_ret) { struct rds_ib_mr *ibmr, *next; + struct xlist_head clean_xlist; + struct xlist_head *clean_tail; LIST_HEAD(unmap_list); LIST_HEAD(fmr_list); unsigned long unpinned = 0; - unsigned long flags; unsigned int nfreed = 0, ncleaned = 0, free_goal; int ret = 0; rds_ib_stats_inc(s_ib_rdma_mr_pool_flush); - mutex_lock(&pool->flush_lock); + if (ibmr_ret) { + DEFINE_WAIT(wait); + while(!mutex_trylock(&pool->flush_lock)) { + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + finish_wait(&pool->flush_wait, &wait); + goto out_nolock; + } + + prepare_to_wait(&pool->flush_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (xlist_empty(&pool->clean_list)) + schedule(); + + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + finish_wait(&pool->flush_wait, &wait); + goto out_nolock; + } + } + finish_wait(&pool->flush_wait, &wait); + } else + mutex_lock(&pool->flush_lock); + + if (ibmr_ret) { + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + goto out; + } + } - spin_lock_irqsave(&pool->list_lock, flags); /* Get the list of all MRs to be dropped. Ordering matters - - * we want to put drop_list ahead of free_list. */ - list_splice_init(&pool->free_list, &unmap_list); - list_splice_init(&pool->drop_list, &unmap_list); + * we want to put drop_list ahead of free_list. + */ + xlist_append_to_list(&pool->drop_list, &unmap_list); + xlist_append_to_list(&pool->free_list, &unmap_list); if (free_all) - list_splice_init(&pool->clean_list, &unmap_list); - spin_unlock_irqrestore(&pool->list_lock, flags); + xlist_append_to_list(&pool->clean_list, &unmap_list); free_goal = rds_ib_flush_goal(pool, free_all); @@ -528,19 +638,20 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) goto out; /* String all ib_mr's onto one list and hand them to ib_unmap_fmr */ - list_for_each_entry(ibmr, &unmap_list, list) + list_for_each_entry(ibmr, &unmap_list, unmap_list) list_add(&ibmr->fmr->list, &fmr_list); + ret = ib_unmap_fmr(&fmr_list); if (ret) printk(KERN_WARNING "RDS/IB: ib_unmap_fmr failed (err=%d)\n", ret); /* Now we can destroy the DMA mapping and unpin any pages */ - list_for_each_entry_safe(ibmr, next, &unmap_list, list) { + list_for_each_entry_safe(ibmr, next, &unmap_list, unmap_list) { unpinned += ibmr->sg_len; __rds_ib_teardown_mr(ibmr); if (nfreed < free_goal || ibmr->remap_count >= pool->fmr_attr.max_maps) { rds_ib_stats_inc(s_ib_rdma_mr_free); - list_del(&ibmr->list); + list_del(&ibmr->unmap_list); ib_dealloc_fmr(ibmr->fmr); kfree(ibmr); nfreed++; @@ -548,9 +659,27 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) ncleaned++; } - spin_lock_irqsave(&pool->list_lock, flags); - list_splice(&unmap_list, &pool->clean_list); - spin_unlock_irqrestore(&pool->list_lock, flags); + if (!list_empty(&unmap_list)) { + /* we have to make sure that none of the things we're about + * to put on the clean list would race with other cpus trying + * to pull items off. The xlist would explode if we managed to + * remove something from the clean list and then add it back again + * while another CPU was spinning on that same item in xlist_del_head. + * + * This is pretty unlikely, but just in case wait for an xlist grace period + * here before adding anything back into the clean list. + */ + wait_clean_list_grace(); + + list_append_to_xlist(pool, &unmap_list, &clean_xlist, &clean_tail); + if (ibmr_ret) + refill_local(pool, &clean_xlist, ibmr_ret); + + /* refill_local may have emptied our list */ + if (!xlist_empty(&clean_xlist)) + xlist_add(clean_xlist.next, clean_tail, &pool->clean_list); + + } atomic_sub(unpinned, &pool->free_pinned); atomic_sub(ncleaned, &pool->dirty_count); @@ -558,6 +687,9 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) out: mutex_unlock(&pool->flush_lock); + if (waitqueue_active(&pool->flush_wait)) + wake_up(&pool->flush_wait); +out_nolock: return ret; } @@ -565,7 +697,7 @@ static void rds_ib_mr_pool_flush_worker(struct work_struct *work) { struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker); - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } void rds_ib_free_mr(void *trans_private, int invalidate) @@ -573,20 +705,17 @@ void rds_ib_free_mr(void *trans_private, int invalidate) struct rds_ib_mr *ibmr = trans_private; struct rds_ib_device *rds_ibdev = ibmr->device; struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; - unsigned long flags; rdsdebug("RDS/IB: free_mr nents %u\n", ibmr->sg_len); /* Return it to the pool's free list */ - spin_lock_irqsave(&pool->list_lock, flags); if (ibmr->remap_count >= pool->fmr_attr.max_maps) - list_add(&ibmr->list, &pool->drop_list); + xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->drop_list); else - list_add(&ibmr->list, &pool->free_list); + xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->free_list); atomic_add(ibmr->sg_len, &pool->free_pinned); atomic_inc(&pool->dirty_count); - spin_unlock_irqrestore(&pool->list_lock, flags); /* If we've pinned too many pages, request a flush */ if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || @@ -595,7 +724,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate) if (invalidate) { if (likely(!in_interrupt())) { - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } else { /* We get here if the user created a MR marked * as use_once and invalidate at the same time. */ @@ -614,7 +743,7 @@ void rds_ib_flush_mrs(void) struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; if (pool) - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } } @@ -659,3 +788,4 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, rds_ib_dev_put(rds_ibdev); return ibmr; } + diff --git a/net/rds/xlist.h b/net/rds/xlist.h new file mode 100644 index 000000000000..8c21aca49d50 --- /dev/null +++ b/net/rds/xlist.h @@ -0,0 +1,110 @@ +#ifndef _LINUX_XLIST_H +#define _LINUX_XLIST_H + +#include +#include +#include +#include + +struct xlist_head { + struct xlist_head *next; +}; + +/* + * XLIST_PTR_TAIL can be used to prevent double insertion. See + * xlist_protect() + */ +#define XLIST_PTR_TAIL ((struct xlist_head *)0x1) + +static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, struct xlist_head *head) +{ + struct xlist_head *cur; + struct xlist_head *check; + + while (1) { + cur = head->next; + tail->next = cur; + check = cmpxchg(&head->next, cur, new); + if (check == cur) + break; + } +} + +/* + * To avoid duplicate insertion by two CPUs of the same xlist item + * you can call xlist_protect. It will stuff XLIST_PTR_TAIL + * into the entry->next pointer with xchg, and only return 1 + * if there was a NULL there before. + * + * if xlist_protect returns zero, someone else is busy working + * on this entry. Getting a NULL into the entry in a race + * free manner is the caller's job. + */ +static inline int xlist_protect(struct xlist_head *entry) +{ + struct xlist_head *val; + + val = xchg(&entry->next, XLIST_PTR_TAIL); + if (val == NULL) + return 1; + return 0; +} + +static inline struct xlist_head *xlist_del_head(struct xlist_head *head) +{ + struct xlist_head *cur; + struct xlist_head *check; + struct xlist_head *next; + + while (1) { + cur = head->next; + if (!cur) + goto out; + + if (cur == XLIST_PTR_TAIL) { + cur = NULL; + goto out; + } + + next = cur->next; + check = cmpxchg(&head->next, cur, next); + if (check == cur) + goto out; + } +out: + return cur; +} + +static inline struct xlist_head *xlist_del_head_fast(struct xlist_head *head) +{ + struct xlist_head *cur; + + cur = head->next; + if (!cur || cur == XLIST_PTR_TAIL) + return NULL; + + head->next = cur->next; + return cur; +} + +static inline void xlist_splice(struct xlist_head *list, + struct xlist_head *head) +{ + struct xlist_head *cur; + + WARN_ON(head->next); + cur = xchg(&list->next, NULL); + head->next = cur; +} + +static inline void INIT_XLIST_HEAD(struct xlist_head *list) +{ + list->next = NULL; +} + +static inline int xlist_empty(struct xlist_head *head) +{ + return head->next == NULL || head->next == XLIST_PTR_TAIL; +} + +#endif -- cgit v1.2.3 From eabb732279f1a41ac9d066aeb56973ae505c4cbc Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 11 Jun 2010 11:18:57 -0700 Subject: rds: more FMRs are faster When we add more FMRs, we flush them less often and so we go faster. Signed-off-by: Chris Mason --- net/rds/ib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 2efd9d11e7d4..d2dd23d5c1a0 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -9,7 +9,7 @@ #include "rdma_transport.h" #define RDS_FMR_SIZE 256 -#define RDS_FMR_POOL_SIZE 4096 +#define RDS_FMR_POOL_SIZE 8192 #define RDS_IB_MAX_SGE 8 #define RDS_IB_RECV_SGE 2 -- cgit v1.2.3 From 7a0ff5dbdd0b4cb7ea8764da9d78f4bb2eebaf31 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 11 Jun 2010 11:26:02 -0700 Subject: RDS: use delayed work for the FMR flushes Using a delayed work queue helps us make sure a healthy number of FMRs have queued up over the limit. It makes for a large improvement in RDMA iops. Signed-off-by: Chris Mason --- net/rds/ib_rdma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 8c40391de5a2..3a275af9d52f 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -66,7 +66,7 @@ struct rds_ib_mr { */ struct rds_ib_mr_pool { struct mutex flush_lock; /* serialize fmr invalidate */ - struct work_struct flush_worker; /* flush worker */ + struct delayed_work flush_worker; /* flush worker */ atomic_t item_count; /* total # of MRs */ atomic_t dirty_count; /* # dirty of MRs */ @@ -226,7 +226,7 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev) INIT_XLIST_HEAD(&pool->clean_list); mutex_init(&pool->flush_lock); init_waitqueue_head(&pool->flush_wait); - INIT_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker); + INIT_DELAYED_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker); pool->fmr_attr.max_pages = fmr_message_size; pool->fmr_attr.max_maps = rds_ibdev->fmr_max_remaps; @@ -254,7 +254,7 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) { - cancel_work_sync(&pool->flush_worker); + cancel_delayed_work_sync(&pool->flush_worker); rds_ib_flush_mr_pool(pool, 1, NULL); WARN_ON(atomic_read(&pool->item_count)); WARN_ON(atomic_read(&pool->free_pinned)); @@ -695,7 +695,7 @@ out_nolock: static void rds_ib_mr_pool_flush_worker(struct work_struct *work) { - struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker); + struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work); rds_ib_flush_mr_pool(pool, 0, NULL); } @@ -720,7 +720,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate) /* If we've pinned too many pages, request a flush */ if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || atomic_read(&pool->dirty_count) >= pool->max_items / 10) - queue_work(rds_wq, &pool->flush_worker); + queue_delayed_work(rds_wq, &pool->flush_worker, 10); if (invalidate) { if (likely(!in_interrupt())) { @@ -728,7 +728,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate) } else { /* We get here if the user created a MR marked * as use_once and invalidate at the same time. */ - queue_work(rds_wq, &pool->flush_worker); + queue_delayed_work(rds_wq, &pool->flush_worker, 10); } } -- cgit v1.2.3 From c9455d9996ba84af1f534c7e3944ea6f35d2fc54 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 11 Jun 2010 15:18:51 -0700 Subject: RDS: whitespace --- net/rds/connection.c | 1 - net/rds/ib_rdma.c | 1 - 2 files changed, 2 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 89871db77f8f..7670b45680e1 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -120,7 +120,6 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, unsigned long flags; int ret; - rcu_read_lock(); conn = rds_conn_lookup(head, laddr, faddr, trans); if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 3a275af9d52f..2a4ec1182ba6 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -349,7 +349,6 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE| IB_ACCESS_REMOTE_ATOMIC), - &pool->fmr_attr); if (IS_ERR(ibmr->fmr)) { err = PTR_ERR(ibmr->fmr); -- cgit v1.2.3 From fbf4d7e3d03587a983ee4e536251ea6c1c848ec2 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 11 Jun 2010 16:24:42 -0700 Subject: RDS: Remove unused XLIST_PTR_TAIL and xlist_protect() Not used. Signed-off-by: Andy Grover --- net/rds/xlist.h | 54 ++++++++++++------------------------------------------ 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/net/rds/xlist.h b/net/rds/xlist.h index 8c21aca49d50..e6b5190daddd 100644 --- a/net/rds/xlist.h +++ b/net/rds/xlist.h @@ -10,13 +10,18 @@ struct xlist_head { struct xlist_head *next; }; -/* - * XLIST_PTR_TAIL can be used to prevent double insertion. See - * xlist_protect() - */ -#define XLIST_PTR_TAIL ((struct xlist_head *)0x1) +static inline void INIT_XLIST_HEAD(struct xlist_head *list) +{ + list->next = NULL; +} + +static inline int xlist_empty(struct xlist_head *head) +{ + return head->next == NULL; +} -static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, struct xlist_head *head) +static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, + struct xlist_head *head) { struct xlist_head *cur; struct xlist_head *check; @@ -30,26 +35,6 @@ static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, st } } -/* - * To avoid duplicate insertion by two CPUs of the same xlist item - * you can call xlist_protect. It will stuff XLIST_PTR_TAIL - * into the entry->next pointer with xchg, and only return 1 - * if there was a NULL there before. - * - * if xlist_protect returns zero, someone else is busy working - * on this entry. Getting a NULL into the entry in a race - * free manner is the caller's job. - */ -static inline int xlist_protect(struct xlist_head *entry) -{ - struct xlist_head *val; - - val = xchg(&entry->next, XLIST_PTR_TAIL); - if (val == NULL) - return 1; - return 0; -} - static inline struct xlist_head *xlist_del_head(struct xlist_head *head) { struct xlist_head *cur; @@ -61,11 +46,6 @@ static inline struct xlist_head *xlist_del_head(struct xlist_head *head) if (!cur) goto out; - if (cur == XLIST_PTR_TAIL) { - cur = NULL; - goto out; - } - next = cur->next; check = cmpxchg(&head->next, cur, next); if (check == cur) @@ -80,7 +60,7 @@ static inline struct xlist_head *xlist_del_head_fast(struct xlist_head *head) struct xlist_head *cur; cur = head->next; - if (!cur || cur == XLIST_PTR_TAIL) + if (!cur) return NULL; head->next = cur->next; @@ -97,14 +77,4 @@ static inline void xlist_splice(struct xlist_head *list, head->next = cur; } -static inline void INIT_XLIST_HEAD(struct xlist_head *list) -{ - list->next = NULL; -} - -static inline int xlist_empty(struct xlist_head *head) -{ - return head->next == NULL || head->next == XLIST_PTR_TAIL; -} - #endif -- cgit v1.2.3 From b6fb0df12db6c8b6bbcc7b5c9459b3bbf5f0cee6 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 23 Jun 2010 18:06:30 -0700 Subject: RDS/IB: Make ib_recv_refill return void Signed-off-by: Andy Grover --- net/rds/ib.h | 2 +- net/rds/ib_recv.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index d2dd23d5c1a0..6265ada08959 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -323,7 +323,7 @@ void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); void rds_ib_recv_free_caches(struct rds_ib_connection *ic); -int rds_ib_recv_refill(struct rds_connection *conn, int prefill); +void rds_ib_recv_refill(struct rds_connection *conn, int prefill); void rds_ib_inc_free(struct rds_incoming *inc); int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 1add097fe198..c8c60981cf2e 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -353,7 +353,7 @@ out: * * -1 is returned if posting fails due to temporary resource exhaustion. */ -int rds_ib_recv_refill(struct rds_connection *conn, int prefill) +void rds_ib_recv_refill(struct rds_connection *conn, int prefill) { struct rds_ib_connection *ic = conn->c_transport_data; struct rds_ib_recv_work *recv; @@ -367,14 +367,12 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) if (pos >= ic->i_recv_ring.w_nr) { printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", pos); - ret = -EINVAL; break; } recv = &ic->i_recvs[pos]; ret = rds_ib_recv_refill_one(conn, recv, prefill); if (ret) { - ret = -1; break; } @@ -388,7 +386,6 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) "%pI4 returned %d, disconnecting and " "reconnecting\n", &conn->c_faddr, ret); - ret = -1; break; } @@ -401,7 +398,6 @@ int rds_ib_recv_refill(struct rds_connection *conn, int prefill) if (ret) rds_ib_ring_unalloc(&ic->i_recv_ring, 1); - return ret; } /* -- cgit v1.2.3 From 24fa163a4bae74b3378d30e1bc776568cfca8121 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 25 Jun 2010 14:59:49 -0700 Subject: RDS/IB: wait for IB dev freeing work to finish during rmmod The RDS IB client removal callback can queue work to drop the final reference to an IB device. We have to make sure that this function has returned before we complete rmmod or the work threads can try to execute freed code. Signed-off-by: Zach Brown --- net/rds/ib.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index b21e24fd060c..fc14f637d645 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -336,11 +336,18 @@ static int rds_ib_laddr_check(__be32 addr) return ret; } +static void rds_ib_unregister_client(void) +{ + ib_unregister_client(&rds_ib_client); + /* wait for rds_ib_dev_free() to complete */ + flush_workqueue(rds_wq); +} + void rds_ib_exit(void) { rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); rds_ib_destroy_nodev_conns(); - ib_unregister_client(&rds_ib_client); + rds_ib_unregister_client(); rds_ib_sysctl_exit(); rds_ib_recv_exit(); rds_trans_unregister(&rds_ib_transport); @@ -404,7 +411,7 @@ out_recv: out_sysctl: rds_ib_sysctl_exit(); out_ibreg: - ib_unregister_client(&rds_ib_client); + rds_ib_unregister_client(); out: return ret; } -- cgit v1.2.3 From 8aeb1ba6630ffd44001ae9833842794df0107676 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 25 Jun 2010 14:58:16 -0700 Subject: RDS/IB: destroy connections on rmmod IB connections were not being destroyed during rmmod. First, recently IB device removal callback was changed to disconnect connections that used the removing device rather than destroying them. So connections with devices during rmmod were not being destroyed. Second, rds_ib_destroy_nodev_conns() was being called before connections are disassociated with devices. It would almost never find connections in the nodev list. We first get rid of rds_ib_destroy_conns(), which is no longer called, and refactor the existing caller into the main body of the function and get rid of the list and lock wrappers. Then we call rds_ib_destroy_nodev_conns() *after* ib_unregister_client() has removed the IB device from all the conns and put the conns on the nodev list. The result is that IB connections are destroyed by rmmod. Signed-off-by: Zach Brown --- net/rds/ib.c | 2 +- net/rds/ib.h | 10 +--------- net/rds/ib_rdma.c | 9 ++++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index fc14f637d645..af1ef18b6ff0 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -346,8 +346,8 @@ static void rds_ib_unregister_client(void) void rds_ib_exit(void) { rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); - rds_ib_destroy_nodev_conns(); rds_ib_unregister_client(); + rds_ib_destroy_nodev_conns(); rds_ib_sysctl_exit(); rds_ib_recv_exit(); rds_trans_unregister(&rds_ib_transport); diff --git a/net/rds/ib.h b/net/rds/ib.h index 6265ada08959..e9f9ddf440ca 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -299,15 +299,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr); void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); -void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock); -static inline void rds_ib_destroy_nodev_conns(void) -{ - __rds_ib_destroy_conns(&ib_nodev_conns, &ib_nodev_conns_lock); -} -static inline void rds_ib_destroy_conns(struct rds_ib_device *rds_ibdev) -{ - __rds_ib_destroy_conns(&rds_ibdev->conn_list, &rds_ibdev->spinlock); -} +void rds_ib_destroy_nodev_conns(void); struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *); void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo); void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 2a4ec1182ba6..00f3995351c8 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -198,16 +198,15 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection * rds_ib_dev_put(rds_ibdev); } -void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) +void rds_ib_destroy_nodev_conns(void) { struct rds_ib_connection *ic, *_ic; LIST_HEAD(tmp_list); /* avoid calling conn_destroy with irqs off */ - spin_lock_irq(list_lock); - list_splice(list, &tmp_list); - INIT_LIST_HEAD(list); - spin_unlock_irq(list_lock); + spin_lock_irq(&ib_nodev_conns_lock); + list_splice(&ib_nodev_conns, &tmp_list); + spin_unlock_irq(&ib_nodev_conns_lock); list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) rds_conn_destroy(ic->conn); -- cgit v1.2.3 From 515e079dab19cf774d1eec6e5f4ed65509e31ef1 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 6 Jul 2010 15:09:56 -0700 Subject: RDS/IB: create a work queue for FMR flushing This patch moves the FMR flushing work in to its own mult-threaded work queue. This is to maintain performance in preparation for returning the main krdsd work queue back to a single threaded work queue to avoid deep-rooted concurrency bugs. This is also good because it further separates FMRs, which might be removed some day, from the rest of the code base. Signed-off-by: Zach Brown --- net/rds/ib.c | 9 ++++++++- net/rds/ib.h | 2 ++ net/rds/ib_rdma.c | 25 +++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index af1ef18b6ff0..d2007b931616 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -351,6 +351,7 @@ void rds_ib_exit(void) rds_ib_sysctl_exit(); rds_ib_recv_exit(); rds_trans_unregister(&rds_ib_transport); + rds_ib_fmr_exit(); } struct rds_transport rds_ib_transport = { @@ -386,10 +387,14 @@ int __init rds_ib_init(void) INIT_LIST_HEAD(&rds_ib_devices); - ret = ib_register_client(&rds_ib_client); + ret = rds_ib_fmr_init(); if (ret) goto out; + ret = ib_register_client(&rds_ib_client); + if (ret) + goto out_fmr_exit; + ret = rds_ib_sysctl_init(); if (ret) goto out_ibreg; @@ -412,6 +417,8 @@ out_sysctl: rds_ib_sysctl_exit(); out_ibreg: rds_ib_unregister_client(); +out_fmr_exit: + rds_ib_fmr_exit(); out: return ret; } diff --git a/net/rds/ib.h b/net/rds/ib.h index e9f9ddf440ca..fd4ea69d2443 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -308,6 +308,8 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, void rds_ib_sync_mr(void *trans_private, int dir); void rds_ib_free_mr(void *trans_private, int invalidate); void rds_ib_flush_mrs(void); +int __init rds_ib_fmr_init(void); +void __exit rds_ib_fmr_exit(void); /* ib_recv.c */ int __init rds_ib_recv_init(void); diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 00f3995351c8..0eb597670c5b 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -691,6 +691,26 @@ out_nolock: return ret; } +struct workqueue_struct *rds_ib_fmr_wq; + +int __init rds_ib_fmr_init(void) +{ + rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd"); + if (!rds_ib_fmr_wq) + return -ENOMEM; + return 0; +} + +/* + * By the time this is called all the IB devices should have been torn down and + * had their pools freed. As each pool is freed its work struct is waited on, + * so the pool flushing work queue should be idle by the time we get here. + */ +void __exit rds_ib_fmr_exit(void) +{ + destroy_workqueue(rds_ib_fmr_wq); +} + static void rds_ib_mr_pool_flush_worker(struct work_struct *work) { struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work); @@ -718,7 +738,7 @@ void rds_ib_free_mr(void *trans_private, int invalidate) /* If we've pinned too many pages, request a flush */ if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || atomic_read(&pool->dirty_count) >= pool->max_items / 10) - queue_delayed_work(rds_wq, &pool->flush_worker, 10); + queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); if (invalidate) { if (likely(!in_interrupt())) { @@ -726,7 +746,8 @@ void rds_ib_free_mr(void *trans_private, int invalidate) } else { /* We get here if the user created a MR marked * as use_once and invalidate at the same time. */ - queue_delayed_work(rds_wq, &pool->flush_worker, 10); + queue_delayed_work(rds_ib_fmr_wq, + &pool->flush_worker, 10); } } -- cgit v1.2.3 From 80c51be56ffa257d3177f0d750d90be65d30c22f Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 6 Jul 2010 15:08:48 -0700 Subject: RDS: return to a single-threaded krdsd We were seeing very nasty bugs due to fundamental assumption the current code makes about concurrent work struct processing. The code simpy isn't able to handle concurrent connection shutdown work function execution today, for example, which is very much possible once a multi-threaded krdsd was introduced. The problem compounds as additional work structs are added to the mix. krdsd is no longer perforance critical now that send and receive posting and FMR flushing are done elsewhere, so the safest fix is to move back to the single threaded krdsd that the current code was built around. Signed-off-by: Zach Brown --- net/rds/threads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/threads.c b/net/rds/threads.c index 2bab9bf07b91..c08c220efac5 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -214,7 +214,7 @@ void rds_threads_exit(void) int __init rds_threads_init(void) { - rds_wq = create_workqueue("krdsd"); + rds_wq = create_singlethread_workqueue("krdsd"); if (!rds_wq) return -ENOMEM; -- cgit v1.2.3 From d455ab64096b9a86849c7315c53e595330842db6 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 6 Jul 2010 15:04:34 -0700 Subject: RDS/IB: always process recv completions The recv refill path was leaking fragments because the recv event handler had marked a ring element as free without freeing its frag. This was happening because it wasn't processing receives when the conn wasn't marked up or connecting, as can be the case if it races with rmmod. Two observations support always processing receives in the callback. First, buildup should only post receives, thus triggering recv event handler calls, once it has built up all the state to handle them. Teardown should destroy the CQ and drain the ring before tearing down the state needed to process recvs. Both appear to be true today. Second, this test was fundamentally racy. There is nothing to stop rmmod and connection destruction from swooping in the moment after the conn state was sampled but before real receive procesing starts. Signed-off-by: Zach Brown --- net/rds/ib_recv.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index c8c60981cf2e..9c4208f6b451 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -979,18 +979,22 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic, * to get a recv completion _before_ the rdmacm ESTABLISHED * event is processed. */ - if (rds_conn_up(conn) || rds_conn_connecting(conn)) { + if (wc.status == IB_WC_SUCCESS) { + rds_ib_process_recv(conn, recv, wc.byte_len, state); + } else { /* We expect errors as the qp is drained during shutdown */ - if (wc.status == IB_WC_SUCCESS) { - rds_ib_process_recv(conn, recv, wc.byte_len, state); - } else { + if (rds_conn_up(conn) || rds_conn_connecting(conn)) rds_ib_conn_error(conn, "recv completion on " - "%pI4 had status %u, disconnecting and " - "reconnecting\n", &conn->c_faddr, - wc.status); - } + "%pI4 had status %u, disconnecting and " + "reconnecting\n", &conn->c_faddr, + wc.status); } + /* + * It's very important that we only free this ring entry if we've truly + * freed the resources allocated to the entry. The refilling path can + * leak if we don't. + */ rds_ib_ring_free(&ic->i_recv_ring, 1); } } -- cgit v1.2.3 From c20f5b9633bb0953bd2422f0f1430a2028cdbd0a Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 7 Jul 2010 16:46:26 -0700 Subject: RDS/IB: Use SLAB_HWCACHE_ALIGN flag for kmem_cache_create() We are *definitely* counting cycles as closely as DaveM, so ensure hwcache alignment for our recv ring control structs. Signed-off-by: Andy Grover --- net/rds/ib_recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 9c4208f6b451..37dab2898ad0 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -1051,13 +1051,13 @@ int __init rds_ib_recv_init(void) rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming", sizeof(struct rds_ib_incoming), - 0, 0, NULL); + 0, SLAB_HWCACHE_ALIGN, NULL); if (!rds_ib_incoming_slab) goto out; rds_ib_frag_slab = kmem_cache_create("rds_ib_frag", sizeof(struct rds_page_frag), - 0, 0, NULL); + 0, SLAB_HWCACHE_ALIGN, NULL); if (!rds_ib_frag_slab) kmem_cache_destroy(rds_ib_incoming_slab); else -- cgit v1.2.3 From ef87b7ea39a91906218a262686bcb8bad8b6b46e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 9 Jul 2010 12:26:20 -0700 Subject: RDS: remove __init and __exit annotation The trivial amount of memory saved isn't worth the cost of dealing with section mismatches. Signed-off-by: Zach Brown --- net/rds/af_rds.c | 4 ++-- net/rds/connection.c | 2 +- net/rds/ib.c | 2 +- net/rds/ib.h | 10 +++++----- net/rds/ib_rdma.c | 4 ++-- net/rds/ib_recv.c | 2 +- net/rds/ib_sysctl.c | 2 +- net/rds/iw.c | 2 +- net/rds/iw.h | 6 +++--- net/rds/iw_recv.c | 2 +- net/rds/iw_sysctl.c | 2 +- net/rds/rdma_transport.c | 4 ++-- net/rds/rds.h | 10 +++++----- net/rds/stats.c | 2 +- net/rds/sysctl.c | 2 +- net/rds/tcp.c | 2 +- net/rds/tcp.h | 6 +++--- net/rds/tcp_listen.c | 2 +- net/rds/tcp_recv.c | 2 +- net/rds/threads.c | 2 +- 20 files changed, 35 insertions(+), 35 deletions(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index f16d2a92cb89..57ef0ec4f03d 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -521,7 +521,7 @@ out: spin_unlock_irqrestore(&rds_sock_lock, flags); } -static void __exit rds_exit(void) +static void rds_exit(void) { sock_unregister(rds_family_ops.family); proto_unregister(&rds_proto); @@ -536,7 +536,7 @@ static void __exit rds_exit(void) } module_exit(rds_exit); -static int __init rds_init(void) +static int rds_init(void) { int ret; diff --git a/net/rds/connection.c b/net/rds/connection.c index 7670b45680e1..0de40d9563ca 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -488,7 +488,7 @@ static void rds_conn_info(struct socket *sock, unsigned int len, sizeof(struct rds_info_connection)); } -int __init rds_conn_init(void) +int rds_conn_init(void) { rds_conn_slab = kmem_cache_create("rds_connection", sizeof(struct rds_connection), diff --git a/net/rds/ib.c b/net/rds/ib.c index d2007b931616..3eb5617649c6 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -381,7 +381,7 @@ struct rds_transport rds_ib_transport = { .t_type = RDS_TRANS_IB }; -int __init rds_ib_init(void) +int rds_ib_init(void) { int ret; diff --git a/net/rds/ib.h b/net/rds/ib.h index fd4ea69d2443..acda2dbc6576 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -282,7 +282,7 @@ void rds_ib_conn_free(void *arg); int rds_ib_conn_connect(struct rds_connection *conn); void rds_ib_conn_shutdown(struct rds_connection *conn); void rds_ib_state_change(struct sock *sk); -int __init rds_ib_listen_init(void); +int rds_ib_listen_init(void); void rds_ib_listen_stop(void); void __rds_ib_conn_error(struct rds_connection *conn, const char *, ...); int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, @@ -308,11 +308,11 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, void rds_ib_sync_mr(void *trans_private, int dir); void rds_ib_free_mr(void *trans_private, int invalidate); void rds_ib_flush_mrs(void); -int __init rds_ib_fmr_init(void); -void __exit rds_ib_fmr_exit(void); +int rds_ib_fmr_init(void); +void rds_ib_fmr_exit(void); /* ib_recv.c */ -int __init rds_ib_recv_init(void); +int rds_ib_recv_init(void); void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); @@ -363,7 +363,7 @@ unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); /* ib_sysctl.c */ -int __init rds_ib_sysctl_init(void); +int rds_ib_sysctl_init(void); void rds_ib_sysctl_exit(void); extern unsigned long rds_ib_sysctl_max_send_wr; extern unsigned long rds_ib_sysctl_max_recv_wr; diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 0eb597670c5b..3efdddc39d49 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -693,7 +693,7 @@ out_nolock: struct workqueue_struct *rds_ib_fmr_wq; -int __init rds_ib_fmr_init(void) +int rds_ib_fmr_init(void) { rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd"); if (!rds_ib_fmr_wq) @@ -706,7 +706,7 @@ int __init rds_ib_fmr_init(void) * had their pools freed. As each pool is freed its work struct is waited on, * so the pool flushing work queue should be idle by the time we get here. */ -void __exit rds_ib_fmr_exit(void) +void rds_ib_fmr_exit(void) { destroy_workqueue(rds_ib_fmr_wq); } diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 37dab2898ad0..f25c4837d2f6 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -1040,7 +1040,7 @@ int rds_ib_recv(struct rds_connection *conn) return ret; } -int __init rds_ib_recv_init(void) +int rds_ib_recv_init(void) { struct sysinfo si; int ret = -ENOMEM; diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c index b556c5c2a902..fc3da37220fd 100644 --- a/net/rds/ib_sysctl.c +++ b/net/rds/ib_sysctl.c @@ -119,7 +119,7 @@ void rds_ib_sysctl_exit(void) unregister_sysctl_table(rds_ib_sysctl_hdr); } -int __init rds_ib_sysctl_init(void) +int rds_ib_sysctl_init(void) { rds_ib_sysctl_hdr = register_sysctl_paths(rds_ib_sysctl_path, rds_ib_sysctl_table); if (!rds_ib_sysctl_hdr) diff --git a/net/rds/iw.c b/net/rds/iw.c index 467790da1316..56808cac0fc7 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -287,7 +287,7 @@ struct rds_transport rds_iw_transport = { .t_prefer_loopback = 1, }; -int __init rds_iw_init(void) +int rds_iw_init(void) { int ret; diff --git a/net/rds/iw.h b/net/rds/iw.h index f112105faced..543e665fafe3 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -284,7 +284,7 @@ void rds_iw_conn_free(void *arg); int rds_iw_conn_connect(struct rds_connection *conn); void rds_iw_conn_shutdown(struct rds_connection *conn); void rds_iw_state_change(struct sock *sk); -int __init rds_iw_listen_init(void); +int rds_iw_listen_init(void); void rds_iw_listen_stop(void); void __rds_iw_conn_error(struct rds_connection *conn, const char *, ...); int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id, @@ -321,7 +321,7 @@ void rds_iw_flush_mrs(void); void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id); /* ib_recv.c */ -int __init rds_iw_recv_init(void); +int rds_iw_recv_init(void); void rds_iw_recv_exit(void); int rds_iw_recv(struct rds_connection *conn); int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, @@ -370,7 +370,7 @@ unsigned int rds_iw_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); /* ib_sysctl.c */ -int __init rds_iw_sysctl_init(void); +int rds_iw_sysctl_init(void); void rds_iw_sysctl_exit(void); extern unsigned long rds_iw_sysctl_max_send_wr; extern unsigned long rds_iw_sysctl_max_recv_wr; diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index 7e929f701a0c..5e57347f49ff 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -887,7 +887,7 @@ int rds_iw_recv(struct rds_connection *conn) return ret; } -int __init rds_iw_recv_init(void) +int rds_iw_recv_init(void) { struct sysinfo si; int ret = -ENOMEM; diff --git a/net/rds/iw_sysctl.c b/net/rds/iw_sysctl.c index 3cb0587d6f50..23e3a9a26aaf 100644 --- a/net/rds/iw_sysctl.c +++ b/net/rds/iw_sysctl.c @@ -122,7 +122,7 @@ void rds_iw_sysctl_exit(void) unregister_sysctl_table(rds_iw_sysctl_hdr); } -int __init rds_iw_sysctl_init(void) +int rds_iw_sysctl_init(void) { rds_iw_sysctl_hdr = register_sysctl_paths(rds_iw_sysctl_path, rds_iw_sysctl_table); if (!rds_iw_sysctl_hdr) diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index e599ba2f950d..550d34837fe7 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -122,7 +122,7 @@ out: return ret; } -static int __init rds_rdma_listen_init(void) +static int rds_rdma_listen_init(void) { struct sockaddr_in sin; struct rdma_cm_id *cm_id; @@ -177,7 +177,7 @@ static void rds_rdma_listen_stop(void) } } -int __init rds_rdma_init(void) +int rds_rdma_init(void) { int ret; diff --git a/net/rds/rds.h b/net/rds/rds.h index 4510344ce8ca..8a8a4822d02a 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -606,7 +606,7 @@ void rds_cong_exit(void); struct rds_message *rds_cong_update_alloc(struct rds_connection *conn); /* conn.c */ -int __init rds_conn_init(void); +int rds_conn_init(void); void rds_conn_exit(void); struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); @@ -769,14 +769,14 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats); put_cpu(); \ } while (0) #define rds_stats_add(member, count) rds_stats_add_which(rds_stats, member, count) -int __init rds_stats_init(void); +int rds_stats_init(void); void rds_stats_exit(void); void rds_stats_info_copy(struct rds_info_iterator *iter, uint64_t *values, const char *const *names, size_t nr); /* sysctl.c */ -int __init rds_sysctl_init(void); +int rds_sysctl_init(void); void rds_sysctl_exit(void); extern unsigned long rds_sysctl_sndbuf_min; extern unsigned long rds_sysctl_sndbuf_default; @@ -790,7 +790,7 @@ extern unsigned long rds_sysctl_trace_flags; extern unsigned int rds_sysctl_trace_level; /* threads.c */ -int __init rds_threads_init(void); +int rds_threads_init(void); void rds_threads_exit(void); extern struct workqueue_struct *rds_wq; void rds_queue_reconnect(struct rds_connection *conn); @@ -806,7 +806,7 @@ void rds_trans_unregister(struct rds_transport *trans); struct rds_transport *rds_trans_get_preferred(__be32 addr); unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); -int __init rds_trans_init(void); +int rds_trans_init(void); void rds_trans_exit(void); #endif diff --git a/net/rds/stats.c b/net/rds/stats.c index 344929a663e5..10c759ccac0c 100644 --- a/net/rds/stats.c +++ b/net/rds/stats.c @@ -143,7 +143,7 @@ void rds_stats_exit(void) rds_info_deregister_func(RDS_INFO_COUNTERS, rds_stats_info); } -int __init rds_stats_init(void) +int rds_stats_init(void) { rds_info_register_func(RDS_INFO_COUNTERS, rds_stats_info); return 0; diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c index 5a6dd81de188..25ad0c77a26c 100644 --- a/net/rds/sysctl.c +++ b/net/rds/sysctl.c @@ -105,7 +105,7 @@ void rds_sysctl_exit(void) unregister_sysctl_table(rds_sysctl_reg_table); } -int __init rds_sysctl_init(void) +int rds_sysctl_init(void) { rds_sysctl_reconnect_min = msecs_to_jiffies(1); rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min; diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 3262992f5f2b..eeb08e6ab96b 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -274,7 +274,7 @@ struct rds_transport rds_tcp_transport = { .t_prefer_loopback = 1, }; -int __init rds_tcp_init(void) +int rds_tcp_init(void) { int ret; diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 16b166379ea9..f5e6f7bebb50 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -43,7 +43,7 @@ struct rds_tcp_statistics { }; /* tcp.c */ -int __init rds_tcp_init(void); +int rds_tcp_init(void); void rds_tcp_exit(void); void rds_tcp_tune(struct socket *sock); void rds_tcp_nonagle(struct socket *sock); @@ -61,12 +61,12 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn); void rds_tcp_state_change(struct sock *sk); /* tcp_listen.c */ -int __init rds_tcp_listen_init(void); +int rds_tcp_listen_init(void); void rds_tcp_listen_stop(void); void rds_tcp_listen_data_ready(struct sock *sk, int bytes); /* tcp_recv.c */ -int __init rds_tcp_recv_init(void); +int rds_tcp_recv_init(void); void rds_tcp_recv_exit(void); void rds_tcp_data_ready(struct sock *sk, int bytes); int rds_tcp_recv(struct rds_connection *conn); diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 50b649eb6933..ae27869dfc21 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -135,7 +135,7 @@ out: ready(sk, bytes); } -int __init rds_tcp_listen_init(void) +int rds_tcp_listen_init(void) { struct sockaddr_in sin; struct socket *sock = NULL; diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 49c966010788..7017f3af80b6 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -342,7 +342,7 @@ out: ready(sk, bytes); } -int __init rds_tcp_recv_init(void) +int rds_tcp_recv_init(void) { rds_tcp_incoming_slab = kmem_cache_create("rds_tcp_incoming", sizeof(struct rds_tcp_incoming), diff --git a/net/rds/threads.c b/net/rds/threads.c index c08c220efac5..0fd90f8c5f59 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -212,7 +212,7 @@ void rds_threads_exit(void) destroy_workqueue(rds_wq); } -int __init rds_threads_init(void) +int rds_threads_init(void) { rds_wq = create_singlethread_workqueue("krdsd"); if (!rds_wq) -- cgit v1.2.3 From f046011cd73c372267befd10242988eb744649fe Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 14 Jul 2010 13:55:35 -0700 Subject: RDS/IB: track signaled sends We're seeing bugs today where IB connection shutdown clears the send ring while the tasklet is processing completed sends. Implementation details cause this to dereference a null pointer. Shutdown needs to wait for send completion to stop before tearing down the connection. We can't simply wait for the ring to empty because it may contain unsignaled sends that will never be processed. This patch tracks the number of signaled sends that we've posted and waits for them to complete. It also makes sure that the tasklet has finished executing. Signed-off-by: Zach Brown --- net/rds/ib.h | 1 + net/rds/ib_cm.c | 14 +++++++++++--- net/rds/ib_send.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index acda2dbc6576..a13ced504145 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -108,6 +108,7 @@ struct rds_ib_connection { struct rds_header *i_send_hdrs; u64 i_send_hdrs_dma; struct rds_ib_send_work *i_sends; + atomic_t i_signaled_sends; /* rx */ struct tasklet_struct i_recv_tasklet; diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 10f6a8815cd0..123c7d33b54e 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -615,11 +615,18 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) } /* - * Don't wait for the send ring to be empty -- there may be completed - * non-signaled entries sitting on there. We unmap these below. + * We want to wait for tx and rx completion to finish + * before we tear down the connection, but we have to be + * careful not to get stuck waiting on a send ring that + * only has unsignaled sends in it. We've shutdown new + * sends before getting here so by waiting for signaled + * sends to complete we're ensured that there will be no + * more tx processing. */ wait_event(rds_ib_ring_empty_wait, - rds_ib_ring_empty(&ic->i_recv_ring)); + rds_ib_ring_empty(&ic->i_recv_ring) && + (atomic_read(&ic->i_signaled_sends) == 0)); + tasklet_kill(&ic->i_recv_tasklet); if (ic->i_send_hdrs) ib_dma_free_coherent(dev, @@ -729,6 +736,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) #ifndef KERNEL_HAS_ATOMIC64 spin_lock_init(&ic->i_ack_lock); #endif + atomic_set(&ic->i_signaled_sends, 0); /* * rds_ib_conn_shutdown() waits for these to be emptied so they diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e88cb4af009b..15f75692574c 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -219,6 +219,18 @@ void rds_ib_send_clear_ring(struct rds_ib_connection *ic) } } +/* + * The only fast path caller always has a non-zero nr, so we don't + * bother testing nr before performing the atomic sub. + */ +static void rds_ib_sub_signaled(struct rds_ib_connection *ic, int nr) +{ + if ((atomic_sub_return(nr, &ic->i_signaled_sends) == 0) && + waitqueue_active(&rds_ib_ring_empty_wait)) + wake_up(&rds_ib_ring_empty_wait); + BUG_ON(atomic_read(&ic->i_signaled_sends) < 0); +} + /* * The _oldest/_free ring operations here race cleanly with the alloc/unalloc * operations performed in the send path. As the sender allocs and potentially @@ -236,6 +248,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) u32 oldest; u32 i = 0; int ret; + int nr_sig = 0; rdsdebug("cq %p conn %p\n", cq, conn); rds_ib_stats_inc(s_ib_tx_cq_call); @@ -262,6 +275,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) for (i = 0; i < completed; i++) { send = &ic->i_sends[oldest]; + if (send->s_wr.send_flags & IB_SEND_SIGNALED) + nr_sig++; rm = rds_ib_send_unmap_op(ic, send, wc.status); @@ -282,6 +297,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) } rds_ib_ring_free(&ic->i_send_ring, completed); + rds_ib_sub_signaled(ic, nr_sig); + nr_sig = 0; if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) || test_bit(0, &conn->c_map_queued)) @@ -440,9 +457,9 @@ void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted) set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); } -static inline void rds_ib_set_wr_signal_state(struct rds_ib_connection *ic, - struct rds_ib_send_work *send, - bool notify) +static inline int rds_ib_set_wr_signal_state(struct rds_ib_connection *ic, + struct rds_ib_send_work *send, + bool notify) { /* * We want to delay signaling completions just enough to get @@ -452,7 +469,9 @@ static inline void rds_ib_set_wr_signal_state(struct rds_ib_connection *ic, if (ic->i_unsignaled_wrs-- == 0 || notify) { ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; send->s_wr.send_flags |= IB_SEND_SIGNALED; + return 1; } + return 0; } /* @@ -488,6 +507,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, int bytes_sent = 0; int ret; int flow_controlled = 0; + int nr_sig = 0; BUG_ON(off % RDS_FRAG_SIZE); BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header)); @@ -645,6 +665,9 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, if (ic->i_flowctl && flow_controlled && i == (work_alloc-1)) send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; + if (send->s_wr.send_flags & IB_SEND_SIGNALED) + nr_sig++; + rdsdebug("send %p wr %p num_sge %u next %p\n", send, &send->s_wr, send->s_wr.num_sge, send->s_wr.next); @@ -689,6 +712,9 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, if (ic->i_flowctl && i < credit_alloc) rds_ib_send_add_credits(conn, credit_alloc - i); + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + /* XXX need to worry about failed_wr and partial sends. */ failed_wr = &first->s_wr; ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr); @@ -699,6 +725,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, printk(KERN_WARNING "RDS/IB: ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_sub_signaled(ic, nr_sig); if (prev->s_op) { ic->i_data_op = prev->s_op; prev->s_op = NULL; @@ -728,6 +755,7 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) u32 pos; u32 work_alloc; int ret; + int nr_sig = 0; rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); @@ -752,7 +780,7 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) send->s_wr.wr.atomic.compare_add = op->op_swap_add; send->s_wr.wr.atomic.swap = 0; } - rds_ib_set_wr_signal_state(ic, send, op->op_notify); + nr_sig = rds_ib_set_wr_signal_state(ic, send, op->op_notify); send->s_wr.num_sge = 1; send->s_wr.next = NULL; send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; @@ -778,6 +806,9 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) rdsdebug("rva %Lx rpa %Lx len %u\n", op->op_remote_addr, send->s_sge[0].addr, send->s_sge[0].length); + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + failed_wr = &send->s_wr; ret = ib_post_send(ic->i_cm_id->qp, &send->s_wr, &failed_wr); rdsdebug("ic %p send %p (wr %p) ret %d wr %p\n", ic, @@ -787,6 +818,7 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) printk(KERN_WARNING "RDS/IB: atomic ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_sub_signaled(ic, nr_sig); goto out; } @@ -817,6 +849,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) int sent; int ret; int num_sge; + int nr_sig = 0; /* map the op the first time we see it */ if (!op->op_mapped) { @@ -859,7 +892,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) send->s_queued = jiffies; send->s_op = NULL; - rds_ib_set_wr_signal_state(ic, send, op->op_notify); + nr_sig += rds_ib_set_wr_signal_state(ic, send, op->op_notify); send->s_wr.opcode = op->op_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; send->s_wr.wr.rdma.remote_addr = remote_addr; @@ -910,6 +943,9 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) work_alloc = i; } + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + failed_wr = &first->s_wr; ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr); rdsdebug("ic %p first %p (wr %p) ret %d wr %p\n", ic, @@ -919,6 +955,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) printk(KERN_WARNING "RDS/IB: rdma ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_sub_signaled(ic, nr_sig); goto out; } -- cgit v1.2.3 From b4e1da3c9a0ac9b01f45a8578b7347e3a31f9fb8 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 19 Jul 2010 17:02:41 -0700 Subject: RDS: properly use sg_init_table This is only needed to keep debugging code from bugging. Signed-off-by: Chris Mason --- net/rds/ib_recv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index f25c4837d2f6..a2f5f6faf35c 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -282,6 +282,7 @@ static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic if (!frag) return NULL; + sg_init_table(&frag->f_sg, 1); ret = rds_page_remainder_alloc(&frag->f_sg, RDS_FRAG_SIZE, page_mask); if (ret) { -- cgit v1.2.3 From 8576f374ac9537674e3cccb0a9d43fa2b7ebbf5b Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 19 Jul 2010 17:06:46 -0700 Subject: RDS: flush fmrs before allocating new ones Flushing FMRs is somewhat expensive, and is currently kicked off when the interrupt handler notices that we are getting low. The result of this is that FMR flushing only happens from the interrupt cpus. This spreads the load more effectively by triggering flushes just before we allocate a new FMR. Signed-off-by: Chris Mason --- net/rds/ib_rdma.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 3efdddc39d49..0017964f2fcf 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -38,6 +38,8 @@ #include "ib.h" #include "xlist.h" +struct workqueue_struct *rds_ib_fmr_wq; + static DEFINE_PER_CPU(unsigned long, clean_list_grace); #define CLEAN_LIST_BUSY_BIT 0 @@ -304,6 +306,9 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) struct rds_ib_mr *ibmr = NULL; int err = 0, iter = 0; + if (atomic_read(&pool->dirty_count) >= pool->max_items / 10) + queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); + while (1) { ibmr = rds_ib_reuse_fmr(pool); if (ibmr) @@ -691,8 +696,6 @@ out_nolock: return ret; } -struct workqueue_struct *rds_ib_fmr_wq; - int rds_ib_fmr_init(void) { rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd"); -- cgit v1.2.3 From 1bde04a63d532c2540d6fdee0a661530a62b1686 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 14 Jul 2010 14:01:21 -0700 Subject: RDS/IB: print IB event strings as well as their number It's nice to not have to go digging in the code to see which event occurred. It's easy to throw together a quick array that maps the ib event enums to their strings. I didn't see anything in the stack that does this translation for us, but I also didn't look very hard. Signed-off-by: Zach Brown --- net/rds/ib_cm.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 123c7d33b54e..0e2fea893a76 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -38,6 +38,38 @@ #include "rds.h" #include "ib.h" +static char *rds_ib_event_type_strings[] = { +#define RDS_IB_EVENT_STRING(foo) [IB_EVENT_##foo] = __stringify(foo) + RDS_IB_EVENT_STRING(CQ_ERR), + RDS_IB_EVENT_STRING(QP_FATAL), + RDS_IB_EVENT_STRING(QP_REQ_ERR), + RDS_IB_EVENT_STRING(QP_ACCESS_ERR), + RDS_IB_EVENT_STRING(COMM_EST), + RDS_IB_EVENT_STRING(SQ_DRAINED), + RDS_IB_EVENT_STRING(PATH_MIG), + RDS_IB_EVENT_STRING(PATH_MIG_ERR), + RDS_IB_EVENT_STRING(DEVICE_FATAL), + RDS_IB_EVENT_STRING(PORT_ACTIVE), + RDS_IB_EVENT_STRING(PORT_ERR), + RDS_IB_EVENT_STRING(LID_CHANGE), + RDS_IB_EVENT_STRING(PKEY_CHANGE), + RDS_IB_EVENT_STRING(SM_CHANGE), + RDS_IB_EVENT_STRING(SRQ_ERR), + RDS_IB_EVENT_STRING(SRQ_LIMIT_REACHED), + RDS_IB_EVENT_STRING(QP_LAST_WQE_REACHED), + RDS_IB_EVENT_STRING(CLIENT_REREGISTER), +#undef RDS_IB_EVENT_STRING +}; + +static char *rds_ib_event_str(enum ib_event_type type) +{ + if (type < ARRAY_SIZE(rds_ib_event_type_strings) && + rds_ib_event_type_strings[type]) + return rds_ib_event_type_strings[type]; + else + return "unknown"; +}; + /* * Set the selected protocol version */ @@ -202,7 +234,8 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, static void rds_ib_cq_event_handler(struct ib_event *event, void *data) { - rdsdebug("event %u data %p\n", event->event, data); + rdsdebug("event %u (%s) data %p\n", + event->event, rds_ib_event_str(event->event), data); } static void rds_ib_qp_event_handler(struct ib_event *event, void *data) @@ -210,16 +243,18 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data) struct rds_connection *conn = data; struct rds_ib_connection *ic = conn->c_transport_data; - rdsdebug("conn %p ic %p event %u\n", conn, ic, event->event); + rdsdebug("conn %p ic %p event %u (%s)\n", conn, ic, event->event, + rds_ib_event_str(event->event)); switch (event->event) { case IB_EVENT_COMM_EST: rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); break; default: - rdsdebug("Fatal QP Event %u " + rdsdebug("Fatal QP Event %u (%s) " "- connection %pI4->%pI4, reconnecting\n", - event->event, &conn->c_laddr, &conn->c_faddr); + event->event, rds_ib_event_str(event->event), + &conn->c_laddr, &conn->c_faddr); rds_conn_drop(conn); break; } -- cgit v1.2.3 From ea819867b788728aca60717e4fdacb3df771f670 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 15 Jul 2010 12:34:33 -0700 Subject: RDS/IB: protect the list of IB devices The RDS IB device list wasn't protected by any locking. Traversal in both the get_mr and FMR flushing paths could race with additon and removal. List manipulation is done with RCU primatives and is protected by the write side of a rwsem. The list traversal in the get_mr fast path is protected by a rcu read critical section. The FMR list traversal is more problematic because it can block while traversing the list. We protect this with the read side of the rwsem. Signed-off-by: Zach Brown --- net/rds/ib.c | 27 ++++++++++++++++++++------- net/rds/ib.h | 1 + net/rds/ib_rdma.c | 8 +++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 3eb5617649c6..b12a3951167d 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -53,6 +53,12 @@ MODULE_PARM_DESC(fmr_message_size, " Max size of a RDMA transfer"); module_param(rds_ib_retry_count, int, 0444); MODULE_PARM_DESC(rds_ib_retry_count, " Number of hw retries before reporting an error"); +/* + * we have a clumsy combination of RCU and a rwsem protecting this list + * because it is used both in the get_mr fast path and while blocking in + * the FMR flushing path. + */ +DECLARE_RWSEM(rds_ib_devices_lock); struct list_head rds_ib_devices; /* NOTE: if also grabbing ibdev lock, grab this first */ @@ -171,7 +177,10 @@ void rds_ib_add_one(struct ib_device *device) INIT_LIST_HEAD(&rds_ibdev->ipaddr_list); INIT_LIST_HEAD(&rds_ibdev->conn_list); - list_add_tail(&rds_ibdev->list, &rds_ib_devices); + + down_write(&rds_ib_devices_lock); + list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices); + up_write(&rds_ib_devices_lock); atomic_inc(&rds_ibdev->refcount); ib_set_client_data(device, &rds_ib_client, rds_ibdev); @@ -230,16 +239,20 @@ void rds_ib_remove_one(struct ib_device *device) rds_ib_dev_shutdown(rds_ibdev); + /* stop connection attempts from getting a reference to this device. */ + ib_set_client_data(device, &rds_ib_client, NULL); + + down_write(&rds_ib_devices_lock); + list_del_rcu(&rds_ibdev->list); + up_write(&rds_ib_devices_lock); + /* - * prevent future connection attempts from getting a reference to this - * device and wait for currently racing connection attempts to finish - * getting their reference + * This synchronize rcu is waiting for readers of both the ib + * client data and the devices list to finish before we drop + * both of those references. */ - ib_set_client_data(device, &rds_ib_client, NULL); synchronize_rcu(); rds_ib_dev_put(rds_ibdev); - - list_del(&rds_ibdev->list); rds_ib_dev_put(rds_ibdev); } diff --git a/net/rds/ib.h b/net/rds/ib.h index a13ced504145..2189fd47a738 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -23,6 +23,7 @@ #define RDS_IB_RECYCLE_BATCH_COUNT 32 +extern struct rw_semaphore rds_ib_devices_lock; extern struct list_head rds_ib_devices; /* diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 0017964f2fcf..8f6e221c9f78 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -94,8 +94,8 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr) struct rds_ib_device *rds_ibdev; struct rds_ib_ipaddr *i_ipaddr; - list_for_each_entry(rds_ibdev, &rds_ib_devices, list) { - rcu_read_lock(); + rcu_read_lock(); + list_for_each_entry_rcu(rds_ibdev, &rds_ib_devices, list) { list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { atomic_inc(&rds_ibdev->refcount); @@ -103,8 +103,8 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr) return rds_ibdev; } } - rcu_read_unlock(); } + rcu_read_unlock(); return NULL; } @@ -761,12 +761,14 @@ void rds_ib_flush_mrs(void) { struct rds_ib_device *rds_ibdev; + down_read(&rds_ib_devices_lock); list_for_each_entry(rds_ibdev, &rds_ib_devices, list) { struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; if (pool) rds_ib_flush_mr_pool(pool, 0, NULL); } + up_read(&rds_ib_devices_lock); } void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, -- cgit v1.2.3 From fe8ff6b58f040dd52d2db45972db8e0301847f1c Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:30:45 -0700 Subject: RDS: lock rds_conn_count decrement in rds_conn_destroy() rds_conn_destroy() can race with all other modifications of the rds_conn_count but it was modifying the count without locking. Signed-off-by: Zach Brown --- net/rds/connection.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/rds/connection.c b/net/rds/connection.c index 0de40d9563ca..75a1a37d64d3 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -313,6 +313,7 @@ void rds_conn_shutdown(struct rds_connection *conn) void rds_conn_destroy(struct rds_connection *conn) { struct rds_message *rm, *rtmp; + unsigned long flags; rdsdebug("freeing conn %p for %pI4 -> " "%pI4\n", conn, &conn->c_laddr, @@ -350,7 +351,9 @@ void rds_conn_destroy(struct rds_connection *conn) BUG_ON(!list_empty(&conn->c_retrans)); kmem_cache_free(rds_conn_slab, conn); + spin_lock_irqsave(&rds_conn_lock, flags); rds_conn_count--; + spin_unlock_irqrestore(&rds_conn_lock, flags); } EXPORT_SYMBOL_GPL(rds_conn_destroy); -- cgit v1.2.3 From 77510481c0c3980c8979ed236d63e59221fb8ce5 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 21 Jul 2010 15:13:25 -0700 Subject: RDS: remove old rs_transport comment rs_transport is now also used by the rdma paths once the socket is bound. We don't need this stale comment to tell us what cscope can. Signed-off-by: Zach Brown --- net/rds/rds.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/rds/rds.h b/net/rds/rds.h index 8a8a4822d02a..2ff7fc9f0539 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -457,12 +457,6 @@ struct rds_sock { __be32 rs_conn_addr; __be16 rs_bound_port; __be16 rs_conn_port; - - /* - * This is only used to communicate the transport between bind and - * initiating connections. All other trans use is referenced through - * the connection. - */ struct rds_transport *rs_transport; /* -- cgit v1.2.3 From 5adb5bc65f93e52341c3fc9d03d4030dd375e256 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:32:31 -0700 Subject: RDS: have sockets get transport module references Right now there's nothing to stop the various paths that use rs->rs_transport from racing with rmmod and executing freed transport code. The simple fix is to have binding to a transport also hold a reference to the transport's module, removing this class of races. We already had an unused t_owner field which was set for the modular transports and which wasn't set for the built-in loop transport. Signed-off-by: Zach Brown --- net/rds/af_rds.c | 2 ++ net/rds/connection.c | 5 ++++- net/rds/rds.h | 1 + net/rds/transport.c | 19 ++++++++++++++----- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 57ef0ec4f03d..8e3886d353b5 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -90,6 +90,8 @@ static int rds_release(struct socket *sock) rds_sock_count--; spin_unlock_irqrestore(&rds_sock_lock, flags); + rds_trans_put(rs->rs_transport); + sock->sk = NULL; sock_put(sk); out: diff --git a/net/rds/connection.c b/net/rds/connection.c index 75a1a37d64d3..968b7a798398 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -117,6 +117,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, { struct rds_connection *conn, *parent = NULL; struct hlist_head *head = rds_conn_bucket(laddr, faddr); + struct rds_transport *loop_trans; unsigned long flags; int ret; @@ -163,7 +164,9 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, * can bind to the destination address then we'd rather the messages * flow through loopback rather than either transport. */ - if (rds_trans_get_preferred(faddr)) { + loop_trans = rds_trans_get_preferred(faddr); + if (loop_trans) { + rds_trans_put(loop_trans); conn->c_loopback = 1; if (is_outgoing && trans->t_prefer_loopback) { /* "outgoing" connection - and the transport diff --git a/net/rds/rds.h b/net/rds/rds.h index 2ff7fc9f0539..aab5e949fa93 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -798,6 +798,7 @@ void rds_connect_complete(struct rds_connection *conn); int rds_trans_register(struct rds_transport *trans); void rds_trans_unregister(struct rds_transport *trans); struct rds_transport *rds_trans_get_preferred(__be32 addr); +void rds_trans_put(struct rds_transport *trans); unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); int rds_trans_init(void); diff --git a/net/rds/transport.c b/net/rds/transport.c index 7e1067901353..7f2ac4fec367 100644 --- a/net/rds/transport.c +++ b/net/rds/transport.c @@ -71,19 +71,28 @@ void rds_trans_unregister(struct rds_transport *trans) } EXPORT_SYMBOL_GPL(rds_trans_unregister); +void rds_trans_put(struct rds_transport *trans) +{ + if (trans && trans->t_owner) + module_put(trans->t_owner); +} + struct rds_transport *rds_trans_get_preferred(__be32 addr) { struct rds_transport *ret = NULL; - int i; + struct rds_transport *trans; + unsigned int i; if (IN_LOOPBACK(ntohl(addr))) return &rds_loop_transport; down_read(&rds_trans_sem); - for (i = 0; i < RDS_TRANS_COUNT; i++) - { - if (transports[i] && (transports[i]->laddr_check(addr) == 0)) { - ret = transports[i]; + for (i = 0; i < RDS_TRANS_COUNT; i++) { + trans = transports[i]; + + if (trans && (trans->laddr_check(addr) == 0) && + (!trans->t_owner || try_module_get(trans->t_owner))) { + ret = trans; break; } } -- cgit v1.2.3 From ffcec0e110c198717eb0f6ac000c1e5397db9451 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:36:58 -0700 Subject: RDS: don't call rds_conn_shutdown() from rds_conn_destroy() rds_conn_shutdown() can return before the connection is shut down when it encounters an existing state that it doesn't understand. This lets rds_conn_destroy() then start tearing down the conn from under paths that are still using it. It's more reliable the shutdown work and wait for krdsd to complete the shutdown callback. This stopped some hangs I was seeing where krdsd was trying to shut down a freed conn. Signed-off-by: Zach Brown --- net/rds/connection.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 968b7a798398..519b4fe962b6 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -312,6 +312,10 @@ void rds_conn_shutdown(struct rds_connection *conn) /* * Stop and free a connection. + * + * This can only be used in very limited circumstances. It assumes that once + * the conn has been shutdown that no one else is referencing the connection. + * We can only ensure this in the rmmod path in the current code. */ void rds_conn_destroy(struct rds_connection *conn) { @@ -326,10 +330,11 @@ void rds_conn_destroy(struct rds_connection *conn) spin_lock_irq(&rds_conn_lock); hlist_del_init_rcu(&conn->c_hash_node); spin_unlock_irq(&rds_conn_lock); - synchronize_rcu(); - rds_conn_shutdown(conn); + /* shut the connection down */ + rds_conn_drop(conn); + flush_work(&conn->c_down_w); /* tear down queued messages */ list_for_each_entry_safe(rm, rtmp, -- cgit v1.2.3 From 4518071ac1bcb76c64a55a3fddb39fb3d39add41 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:37:33 -0700 Subject: RDS: cancel connection work structs as we shut down Nothing was canceling the send and receive work that might have been queued as a conn was being destroyed. Signed-off-by: Zach Brown --- net/rds/connection.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/rds/connection.c b/net/rds/connection.c index 519b4fe962b6..870992e08cae 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -336,6 +336,10 @@ void rds_conn_destroy(struct rds_connection *conn) rds_conn_drop(conn); flush_work(&conn->c_down_w); + /* make sure lingering queued work won't try to ref the conn */ + cancel_delayed_work_sync(&conn->c_send_w); + cancel_delayed_work_sync(&conn->c_recv_w); + /* tear down queued messages */ list_for_each_entry_safe(rm, rtmp, &conn->c_send_queue, -- cgit v1.2.3 From 59f740a6aeb2cde2f79fe0df38262d4c1ef35cd8 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 3 Aug 2010 13:52:47 -0700 Subject: RDS/IB: print string constants in more places This prints the constant identifier for work completion status and rdma cm event types, like we already do for IB event types. A core string array helper is added that each string type uses. Signed-off-by: Zach Brown --- net/rds/af_rds.c | 9 +++++++++ net/rds/ib.h | 1 + net/rds/ib_cm.c | 10 ++++------ net/rds/ib_recv.c | 12 +++++++----- net/rds/ib_send.c | 47 +++++++++++++++++++++++++++++++++++++++++------ net/rds/rdma_transport.c | 38 ++++++++++++++++++++++++++++++++++---- net/rds/rds.h | 1 + 7 files changed, 97 insertions(+), 21 deletions(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 8e3886d353b5..bb6ad81b671d 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -40,6 +40,15 @@ #include "rds.h" +char *rds_str_array(char **array, size_t elements, size_t index) +{ + if ((index < elements) && array[index]) + return array[index]; + else + return "unknown"; +} +EXPORT_SYMBOL(rds_str_array); + /* this is just used for stats gathering :/ */ static DEFINE_SPINLOCK(rds_sock_lock); static unsigned long rds_sock_count; diff --git a/net/rds/ib.h b/net/rds/ib.h index 2189fd47a738..7ad3d57e06a5 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -345,6 +345,7 @@ u32 rds_ib_ring_completed(struct rds_ib_work_ring *ring, u32 wr_id, u32 oldest); extern wait_queue_head_t rds_ib_ring_empty_wait; /* ib_send.c */ +char *rds_ib_wc_status_str(enum ib_wc_status status); void rds_ib_xmit_complete(struct rds_connection *conn); int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 0e2fea893a76..bc3dbc1ba61f 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -39,7 +39,8 @@ #include "ib.h" static char *rds_ib_event_type_strings[] = { -#define RDS_IB_EVENT_STRING(foo) [IB_EVENT_##foo] = __stringify(foo) +#define RDS_IB_EVENT_STRING(foo) \ + [IB_EVENT_##foo] = __stringify(IB_EVENT_##foo) RDS_IB_EVENT_STRING(CQ_ERR), RDS_IB_EVENT_STRING(QP_FATAL), RDS_IB_EVENT_STRING(QP_REQ_ERR), @@ -63,11 +64,8 @@ static char *rds_ib_event_type_strings[] = { static char *rds_ib_event_str(enum ib_event_type type) { - if (type < ARRAY_SIZE(rds_ib_event_type_strings) && - rds_ib_event_type_strings[type]) - return rds_ib_event_type_strings[type]; - else - return "unknown"; + return rds_str_array(rds_ib_event_type_strings, + ARRAY_SIZE(rds_ib_event_type_strings), type); }; /* diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index a2f5f6faf35c..e29e0ca32f74 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -966,8 +966,9 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic, struct rds_ib_recv_work *recv; while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) { - rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", - (unsigned long long)wc.wr_id, wc.status, wc.byte_len, + rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n", + (unsigned long long)wc.wr_id, wc.status, + rds_ib_wc_status_str(wc.status), wc.byte_len, be32_to_cpu(wc.ex.imm_data)); rds_ib_stats_inc(s_ib_rx_cq_event); @@ -985,10 +986,11 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic, } else { /* We expect errors as the qp is drained during shutdown */ if (rds_conn_up(conn) || rds_conn_connecting(conn)) - rds_ib_conn_error(conn, "recv completion on " - "%pI4 had status %u, disconnecting and " + rds_ib_conn_error(conn, "recv completion on %pI4 had " + "status %u (%s), disconnecting and " "reconnecting\n", &conn->c_faddr, - wc.status); + wc.status, + rds_ib_wc_status_str(wc.status)); } /* diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 15f75692574c..808544aebb70 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -38,6 +38,40 @@ #include "rds.h" #include "ib.h" +static char *rds_ib_wc_status_strings[] = { +#define RDS_IB_WC_STATUS_STR(foo) \ + [IB_WC_##foo] = __stringify(IB_WC_##foo) + RDS_IB_WC_STATUS_STR(SUCCESS), + RDS_IB_WC_STATUS_STR(LOC_LEN_ERR), + RDS_IB_WC_STATUS_STR(LOC_QP_OP_ERR), + RDS_IB_WC_STATUS_STR(LOC_EEC_OP_ERR), + RDS_IB_WC_STATUS_STR(LOC_PROT_ERR), + RDS_IB_WC_STATUS_STR(WR_FLUSH_ERR), + RDS_IB_WC_STATUS_STR(MW_BIND_ERR), + RDS_IB_WC_STATUS_STR(BAD_RESP_ERR), + RDS_IB_WC_STATUS_STR(LOC_ACCESS_ERR), + RDS_IB_WC_STATUS_STR(REM_INV_REQ_ERR), + RDS_IB_WC_STATUS_STR(REM_ACCESS_ERR), + RDS_IB_WC_STATUS_STR(REM_OP_ERR), + RDS_IB_WC_STATUS_STR(RETRY_EXC_ERR), + RDS_IB_WC_STATUS_STR(RNR_RETRY_EXC_ERR), + RDS_IB_WC_STATUS_STR(LOC_RDD_VIOL_ERR), + RDS_IB_WC_STATUS_STR(REM_INV_RD_REQ_ERR), + RDS_IB_WC_STATUS_STR(REM_ABORT_ERR), + RDS_IB_WC_STATUS_STR(INV_EECN_ERR), + RDS_IB_WC_STATUS_STR(INV_EEC_STATE_ERR), + RDS_IB_WC_STATUS_STR(FATAL_ERR), + RDS_IB_WC_STATUS_STR(RESP_TIMEOUT_ERR), + RDS_IB_WC_STATUS_STR(GENERAL_ERR), +#undef RDS_IB_WC_STATUS_STR +}; + +char *rds_ib_wc_status_str(enum ib_wc_status status) +{ + return rds_str_array(rds_ib_wc_status_strings, + ARRAY_SIZE(rds_ib_wc_status_strings), status); +} + /* * Convert IB-specific error message to RDS error message and call core * completion handler. @@ -257,8 +291,9 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rdsdebug("ib_req_notify_cq send failed: %d\n", ret); while (ib_poll_cq(cq, 1, &wc) > 0) { - rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", - (unsigned long long)wc.wr_id, wc.status, wc.byte_len, + rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n", + (unsigned long long)wc.wr_id, wc.status, + rds_ib_wc_status_str(wc.status), wc.byte_len, be32_to_cpu(wc.ex.imm_data)); rds_ib_stats_inc(s_ib_tx_cq_event); @@ -306,10 +341,10 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) /* We expect errors as the qp is drained during shutdown */ if (wc.status != IB_WC_SUCCESS && rds_conn_up(conn)) { - rds_ib_conn_error(conn, - "send completion on %pI4 " - "had status %u, disconnecting and reconnecting\n", - &conn->c_faddr, wc.status); + rds_ib_conn_error(conn, "send completion on %pI4 had status " + "%u (%s), disconnecting and reconnecting\n", + &conn->c_faddr, wc.status, + rds_ib_wc_status_str(wc.status)); } } } diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 550d34837fe7..e6ed10aee190 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -36,6 +36,34 @@ static struct rdma_cm_id *rds_rdma_listen_id; +static char *rds_cm_event_strings[] = { +#define RDS_CM_EVENT_STRING(foo) \ + [RDMA_CM_EVENT_##foo] = __stringify(RDMA_CM_EVENT_##foo) + RDS_CM_EVENT_STRING(ADDR_RESOLVED), + RDS_CM_EVENT_STRING(ADDR_ERROR), + RDS_CM_EVENT_STRING(ROUTE_RESOLVED), + RDS_CM_EVENT_STRING(ROUTE_ERROR), + RDS_CM_EVENT_STRING(CONNECT_REQUEST), + RDS_CM_EVENT_STRING(CONNECT_RESPONSE), + RDS_CM_EVENT_STRING(CONNECT_ERROR), + RDS_CM_EVENT_STRING(UNREACHABLE), + RDS_CM_EVENT_STRING(REJECTED), + RDS_CM_EVENT_STRING(ESTABLISHED), + RDS_CM_EVENT_STRING(DISCONNECTED), + RDS_CM_EVENT_STRING(DEVICE_REMOVAL), + RDS_CM_EVENT_STRING(MULTICAST_JOIN), + RDS_CM_EVENT_STRING(MULTICAST_ERROR), + RDS_CM_EVENT_STRING(ADDR_CHANGE), + RDS_CM_EVENT_STRING(TIMEWAIT_EXIT), +#undef RDS_CM_EVENT_STRING +}; + +static char *rds_cm_event_str(enum rdma_cm_event_type type) +{ + return rds_str_array(rds_cm_event_strings, + ARRAY_SIZE(rds_cm_event_strings), type); +}; + int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) { @@ -44,8 +72,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rds_transport *trans; int ret = 0; - rdsdebug("conn %p id %p handling event %u\n", conn, cm_id, - event->event); + rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id, + event->event, rds_cm_event_str(event->event)); if (cm_id->device->node_type == RDMA_NODE_RNIC) trans = &rds_iw_transport; @@ -109,7 +137,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, default: /* things like device disconnect? */ - printk(KERN_ERR "RDS: unknown event %u!\n", event->event); + printk(KERN_ERR "RDS: unknown event %u (%s)!\n", + event->event, rds_cm_event_str(event->event)); break; } @@ -117,7 +146,8 @@ out: if (conn) mutex_unlock(&conn->c_cm_lock); - rdsdebug("id %p event %u handling ret %d\n", cm_id, event->event, ret); + rdsdebug("id %p event %u (%s) handling ret %d\n", cm_id, event->event, + rds_cm_event_str(event->event), ret); return ret; } diff --git a/net/rds/rds.h b/net/rds/rds.h index aab5e949fa93..aadaddba88a7 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -566,6 +566,7 @@ struct rds_statistics { }; /* af_rds.c */ +char *rds_str_array(char **array, size_t elements, size_t index); void rds_sock_addref(struct rds_sock *rs); void rds_sock_put(struct rds_sock *rs); void rds_wake_sk_sleep(struct rds_sock *rs); -- cgit v1.2.3 From 20c72bd5f5f902e5a8745d51573699605bf8d21c Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 25 Aug 2010 05:51:28 -0700 Subject: RDS: Implement masked atomic operations Add two CMSGs for masked versions of cswp and fadd. args struct modified to use a union for different atomic op type's arguments. Change IB to do masked atomic ops. Atomic op type in rds_message similarly unionized. Signed-off-by: Andy Grover --- include/linux/rds.h | 12 ++++++++++++ net/rds/ib_send.c | 14 +++++++++----- net/rds/rdma.c | 33 +++++++++++++++++++++++++++------ net/rds/rds.h | 14 ++++++++++++-- net/rds/send.c | 4 ++++ 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index 109f1d343318..a2a5edb4a276 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -75,6 +75,8 @@ #define RDS_CMSG_CONG_UPDATE 5 #define RDS_CMSG_ATOMIC_FADD 6 #define RDS_CMSG_ATOMIC_CSWP 7 +#define RDS_CMSG_MASKED_ATOMIC_FADD 8 +#define RDS_CMSG_MASKED_ATOMIC_CSWP 9 #define RDS_INFO_FIRST 10000 #define RDS_INFO_COUNTERS 10000 @@ -251,6 +253,16 @@ struct rds_atomic_args { struct { uint64_t add; } fadd; + struct { + uint64_t compare; + uint64_t swap; + uint64_t compare_mask; + uint64_t swap_mask; + } m_cswp; + struct { + uint64_t add; + uint64_t nocarry_mask; + } m_fadd; }; uint64_t flags; uint64_t user_token; diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 808544aebb70..71f373c421bc 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -807,13 +807,17 @@ int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) send->s_queued = jiffies; if (op->op_type == RDS_ATOMIC_TYPE_CSWP) { - send->s_wr.opcode = IB_WR_ATOMIC_CMP_AND_SWP; - send->s_wr.wr.atomic.compare_add = op->op_compare; - send->s_wr.wr.atomic.swap = op->op_swap_add; + send->s_wr.opcode = IB_WR_MASKED_ATOMIC_CMP_AND_SWP; + send->s_wr.wr.atomic.compare_add = op->op_m_cswp.compare; + send->s_wr.wr.atomic.swap = op->op_m_cswp.swap; + send->s_wr.wr.atomic.compare_add_mask = op->op_m_cswp.compare_mask; + send->s_wr.wr.atomic.swap_mask = op->op_m_cswp.swap_mask; } else { /* FADD */ - send->s_wr.opcode = IB_WR_ATOMIC_FETCH_AND_ADD; - send->s_wr.wr.atomic.compare_add = op->op_swap_add; + send->s_wr.opcode = IB_WR_MASKED_ATOMIC_FETCH_AND_ADD; + send->s_wr.wr.atomic.compare_add = op->op_m_fadd.add; send->s_wr.wr.atomic.swap = 0; + send->s_wr.wr.atomic.compare_add_mask = op->op_m_fadd.nocarry_mask; + send->s_wr.wr.atomic.swap_mask = 0; } nr_sig = rds_ib_set_wr_signal_state(ic, send, op->op_notify); send->s_wr.num_sge = 1; diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 48781fe4431c..48064673fc76 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -738,13 +738,34 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, args = CMSG_DATA(cmsg); - if (cmsg->cmsg_type == RDS_CMSG_ATOMIC_CSWP) { - rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; - rm->atomic.op_swap_add = args->cswp.swap; - rm->atomic.op_compare = args->cswp.compare; - } else { + /* Nonmasked & masked cmsg ops converted to masked hw ops */ + switch (cmsg->cmsg_type) { + case RDS_CMSG_ATOMIC_FADD: + rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD; + rm->atomic.op_m_fadd.add = args->fadd.add; + rm->atomic.op_m_fadd.nocarry_mask = 0; + break; + case RDS_CMSG_MASKED_ATOMIC_FADD: rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD; - rm->atomic.op_swap_add = args->fadd.add; + rm->atomic.op_m_fadd.add = args->m_fadd.add; + rm->atomic.op_m_fadd.nocarry_mask = args->m_fadd.nocarry_mask; + break; + case RDS_CMSG_ATOMIC_CSWP: + rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; + rm->atomic.op_m_cswp.compare = args->cswp.compare; + rm->atomic.op_m_cswp.swap = args->cswp.swap; + rm->atomic.op_m_cswp.compare_mask = ~0; + rm->atomic.op_m_cswp.swap_mask = ~0; + break; + case RDS_CMSG_MASKED_ATOMIC_CSWP: + rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; + rm->atomic.op_m_cswp.compare = args->m_cswp.compare; + rm->atomic.op_m_cswp.swap = args->m_cswp.swap; + rm->atomic.op_m_cswp.compare_mask = args->m_cswp.compare_mask; + rm->atomic.op_m_cswp.swap_mask = args->m_cswp.swap_mask; + break; + default: + BUG(); /* should never happen */ } rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); diff --git a/net/rds/rds.h b/net/rds/rds.h index aadaddba88a7..8103dcf8b976 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -316,8 +316,18 @@ struct rds_message { struct { struct rm_atomic_op { int op_type; - uint64_t op_swap_add; - uint64_t op_compare; + union { + struct { + uint64_t compare; + uint64_t swap; + uint64_t compare_mask; + uint64_t swap_mask; + } op_m_cswp; + struct { + uint64_t add; + uint64_t nocarry_mask; + } op_m_fadd; + }; u32 op_rkey; u64 op_remote_addr; diff --git a/net/rds/send.c b/net/rds/send.c index 81471b25373b..9b951a0ab6b7 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -843,6 +843,8 @@ static int rds_rm_size(struct msghdr *msg, int data_len) case RDS_CMSG_ATOMIC_CSWP: case RDS_CMSG_ATOMIC_FADD: + case RDS_CMSG_MASKED_ATOMIC_CSWP: + case RDS_CMSG_MASKED_ATOMIC_FADD: cmsg_groups |= 1; size += sizeof(struct scatterlist); break; @@ -894,6 +896,8 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, break; case RDS_CMSG_ATOMIC_CSWP: case RDS_CMSG_ATOMIC_FADD: + case RDS_CMSG_MASKED_ATOMIC_CSWP: + case RDS_CMSG_MASKED_ATOMIC_FADD: ret = rds_cmsg_atomic(rs, rm, cmsg); break; -- cgit v1.2.3 From fd128dfa50cfc4f2959dc4aa5d7468d33b988332 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 25 Aug 2010 09:32:17 -0700 Subject: RDS: Add rds.h to exported headers list Also, a number of changes were made based on the assumption that rds.h wasn't exported, so roll these back. Signed-off-by: Andy Grover --- include/linux/Kbuild | 1 + include/linux/rds.h | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 626b629429ff..c7fbf298ad68 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -302,6 +302,7 @@ header-y += quota.h header-y += radeonfb.h header-y += random.h header-y += raw.h +header-y += rds.h header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h diff --git a/include/linux/rds.h b/include/linux/rds.h index a2a5edb4a276..f371f885a352 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -95,7 +95,7 @@ struct rds_info_counter { u_int8_t name[32]; u_int64_t value; -} __packed; +} __attribute__((packed)); #define RDS_INFO_CONNECTION_FLAG_SENDING 0x01 #define RDS_INFO_CONNECTION_FLAG_CONNECTING 0x02 @@ -110,7 +110,7 @@ struct rds_info_connection { __be32 faddr; u_int8_t transport[TRANSNAMSIZ]; /* null term ascii */ u_int8_t flags; -} __packed; +} __attribute__((packed)); struct rds_info_flow { __be32 laddr; @@ -118,7 +118,7 @@ struct rds_info_flow { u_int32_t bytes; __be16 lport; __be16 fport; -} __packed; +} __attribute__((packed)); #define RDS_INFO_MESSAGE_FLAG_ACK 0x01 #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 @@ -131,7 +131,7 @@ struct rds_info_message { __be16 lport; __be16 fport; u_int8_t flags; -} __packed; +} __attribute__((packed)); struct rds_info_socket { u_int32_t sndbuf; @@ -141,7 +141,7 @@ struct rds_info_socket { __be16 connected_port; u_int32_t rcvbuf; u_int64_t inum; -} __packed; +} __attribute__((packed)); struct rds_info_tcp_socket { __be32 local_addr; @@ -153,7 +153,7 @@ struct rds_info_tcp_socket { u_int32_t last_sent_nxt; u_int32_t last_expected_una; u_int32_t last_seen_una; -} __packed; +} __attribute__((packed)); #define RDS_IB_GID_LEN 16 struct rds_info_rdma_connection { -- cgit v1.2.3 From a46f561b774d90d8616473d56696e7d44fa1c9f1 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 25 Aug 2010 09:34:10 -0700 Subject: RDS: rds.h: Replace u_int[size]_t with uint[size]_t Replace e.g. u_int32_t types with the more common uint32_t. Reported-by: Matthew Wilcox Signed-off-by: Andy Grover --- include/linux/rds.h | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index f371f885a352..3576b31b6b7b 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -93,8 +93,8 @@ #define RDS_INFO_LAST 10010 struct rds_info_counter { - u_int8_t name[32]; - u_int64_t value; + uint8_t name[32]; + uint64_t value; } __attribute__((packed)); #define RDS_INFO_CONNECTION_FLAG_SENDING 0x01 @@ -104,18 +104,18 @@ struct rds_info_counter { #define TRANSNAMSIZ 16 struct rds_info_connection { - u_int64_t next_tx_seq; - u_int64_t next_rx_seq; + uint64_t next_tx_seq; + uint64_t next_rx_seq; __be32 laddr; __be32 faddr; - u_int8_t transport[TRANSNAMSIZ]; /* null term ascii */ - u_int8_t flags; + uint8_t transport[TRANSNAMSIZ]; /* null term ascii */ + uint8_t flags; } __attribute__((packed)); struct rds_info_flow { __be32 laddr; __be32 faddr; - u_int32_t bytes; + uint32_t bytes; __be16 lport; __be16 fport; } __attribute__((packed)); @@ -124,23 +124,23 @@ struct rds_info_flow { #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 struct rds_info_message { - u_int64_t seq; - u_int32_t len; + uint64_t seq; + uint32_t len; __be32 laddr; __be32 faddr; __be16 lport; __be16 fport; - u_int8_t flags; + uint8_t flags; } __attribute__((packed)); struct rds_info_socket { - u_int32_t sndbuf; + uint32_t sndbuf; __be32 bound_addr; __be32 connected_addr; __be16 bound_port; __be16 connected_port; - u_int32_t rcvbuf; - u_int64_t inum; + uint32_t rcvbuf; + uint64_t inum; } __attribute__((packed)); struct rds_info_tcp_socket { @@ -148,11 +148,11 @@ struct rds_info_tcp_socket { __be16 local_port; __be32 peer_addr; __be16 peer_port; - u_int64_t hdr_rem; - u_int64_t data_rem; - u_int32_t last_sent_nxt; - u_int32_t last_expected_una; - u_int32_t last_seen_una; + uint64_t hdr_rem; + uint64_t data_rem; + uint32_t last_sent_nxt; + uint32_t last_expected_una; + uint32_t last_seen_una; } __attribute__((packed)); #define RDS_IB_GID_LEN 16 @@ -207,38 +207,38 @@ struct rds_info_rdma_connection { * (so that the application does not have to worry about * alignment). */ -typedef u_int64_t rds_rdma_cookie_t; +typedef uint64_t rds_rdma_cookie_t; struct rds_iovec { - u_int64_t addr; - u_int64_t bytes; + uint64_t addr; + uint64_t bytes; }; struct rds_get_mr_args { struct rds_iovec vec; - u_int64_t cookie_addr; + uint64_t cookie_addr; uint64_t flags; }; struct rds_get_mr_for_dest_args { struct sockaddr_storage dest_addr; struct rds_iovec vec; - u_int64_t cookie_addr; + uint64_t cookie_addr; uint64_t flags; }; struct rds_free_mr_args { rds_rdma_cookie_t cookie; - u_int64_t flags; + uint64_t flags; }; struct rds_rdma_args { rds_rdma_cookie_t cookie; struct rds_iovec remote_vec; - u_int64_t local_vec_addr; - u_int64_t nr_local; - u_int64_t flags; - u_int64_t user_token; + uint64_t local_vec_addr; + uint64_t nr_local; + uint64_t flags; + uint64_t user_token; }; struct rds_atomic_args { @@ -269,7 +269,7 @@ struct rds_atomic_args { }; struct rds_rdma_notify { - u_int64_t user_token; + uint64_t user_token; int32_t status; }; -- cgit v1.2.3 From 905d64c89e2a9d71d0606904b7c3908633db6072 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Wed, 8 Sep 2010 18:03:54 -0700 Subject: RDS: Remove dead struct from rds.h flows are an obsolete date type. Signed-off-by: Andy Grover --- include/linux/rds.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/linux/rds.h b/include/linux/rds.h index 3576b31b6b7b..91950950aa59 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -112,14 +112,6 @@ struct rds_info_connection { uint8_t flags; } __attribute__((packed)); -struct rds_info_flow { - __be32 laddr; - __be32 faddr; - uint32_t bytes; - __be16 lport; - __be16 fport; -} __attribute__((packed)); - #define RDS_INFO_MESSAGE_FLAG_ACK 0x01 #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 -- cgit v1.2.3 From 92e32eaee288ee2e838fe76680cbaeaea25643c6 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 8 Sep 2010 21:29:20 -0700 Subject: cxacru: ignore cx82310_eth devices Ignore ADSL routers, which can have the same vendor and product IDs as ADSL modems but should be handled by the cx82310_eth driver. This intentionally ignores device IDs that aren't currently handled by cx82310_eth. There may be other device IDs that perhaps shouldn't be claimed by cxacru. Signed-off-by: Ondrej Zary Signed-off-by: Simon Arlott Signed-off-by: David S. Miller --- drivers/usb/atm/cxacru.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 593fc5e2d2e6..1c320bfa6fb7 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -1324,8 +1324,24 @@ static struct usbatm_driver cxacru_driver = { .tx_padding = 11, }; -static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int cxacru_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usb_dev = interface_to_usbdev(intf); + char buf[15]; + + /* Avoid ADSL routers (cx82310_eth). + * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD". + */ + if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC + && usb_string(usb_dev, usb_dev->descriptor.iProduct, + buf, sizeof(buf)) > 0) { + if (!strcmp(buf, "USB NET CARD")) { + dev_info(&intf->dev, "ignoring cx82310_eth device\n"); + return -ENODEV; + } + } + return usbatm_usb_probe(intf, id, &cxacru_driver); } -- cgit v1.2.3 From e0386005ff2a729998735e10769d99e1acbc2dd1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 8 Sep 2010 21:31:35 -0700 Subject: net: inet_add_protocol() can use cmpxchg() Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and friends. inet_protos[] & inet6_protos[] are moved to read_mostly section Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/protocol.c | 31 +++++-------------------------- net/ipv6/protocol.c | 32 ++++---------------------------- 2 files changed, 9 insertions(+), 54 deletions(-) diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index f2d297351405..65699c24411c 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -28,8 +28,7 @@ #include #include -const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp; -static DEFINE_SPINLOCK(inet_proto_lock); +const struct net_protocol *inet_protos[MAX_INET_PROTOS] __read_mostly; /* * Add a protocol handler to the hash tables @@ -37,20 +36,9 @@ static DEFINE_SPINLOCK(inet_proto_lock); int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) { - int hash, ret; + int hash = protocol & (MAX_INET_PROTOS - 1); - hash = protocol & (MAX_INET_PROTOS - 1); - - spin_lock_bh(&inet_proto_lock); - if (inet_protos[hash]) { - ret = -1; - } else { - inet_protos[hash] = prot; - ret = 0; - } - spin_unlock_bh(&inet_proto_lock); - - return ret; + return !cmpxchg(&inet_protos[hash], NULL, prot) ? 0 : -1; } EXPORT_SYMBOL(inet_add_protocol); @@ -60,18 +48,9 @@ EXPORT_SYMBOL(inet_add_protocol); int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) { - int hash, ret; - - hash = protocol & (MAX_INET_PROTOS - 1); + int ret, hash = protocol & (MAX_INET_PROTOS - 1); - spin_lock_bh(&inet_proto_lock); - if (inet_protos[hash] == prot) { - inet_protos[hash] = NULL; - ret = 0; - } else { - ret = -1; - } - spin_unlock_bh(&inet_proto_lock); + ret = (cmpxchg(&inet_protos[hash], prot, NULL) == prot) ? 0 : -1; synchronize_net(); diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 1fa3468f0f32..9bb936ae2452 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c @@ -25,28 +25,14 @@ #include #include -const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; -static DEFINE_SPINLOCK(inet6_proto_lock); - +const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS] __read_mostly; int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) { - int ret, hash = protocol & (MAX_INET_PROTOS - 1); - - spin_lock_bh(&inet6_proto_lock); - - if (inet6_protos[hash]) { - ret = -1; - } else { - inet6_protos[hash] = prot; - ret = 0; - } - - spin_unlock_bh(&inet6_proto_lock); + int hash = protocol & (MAX_INET_PROTOS - 1); - return ret; + return !cmpxchg(&inet6_protos[hash], NULL, prot) ? 0 : -1; } - EXPORT_SYMBOL(inet6_add_protocol); /* @@ -57,20 +43,10 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol { int ret, hash = protocol & (MAX_INET_PROTOS - 1); - spin_lock_bh(&inet6_proto_lock); - - if (inet6_protos[hash] != prot) { - ret = -1; - } else { - inet6_protos[hash] = NULL; - ret = 0; - } - - spin_unlock_bh(&inet6_proto_lock); + ret = (cmpxchg(&inet6_protos[hash], prot, NULL) == prot) ? 0 : -1; synchronize_net(); return ret; } - EXPORT_SYMBOL(inet6_del_protocol); -- cgit v1.2.3 From f27e21a813e2c4ca74b30a5443602e75b146db9b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 8 Sep 2010 21:32:12 -0700 Subject: atlx: make strings const Signed-off-by: Stephen Hemminger Acked-by: Chris Snook Signed-off-by: David S. Miller --- drivers/net/atlx/atl2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 07adc8446901..29c0265ccc5d 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -51,10 +51,10 @@ #define ATL2_DRV_VERSION "2.2.3" -static char atl2_driver_name[] = "atl2"; +static const char atl2_driver_name[] = "atl2"; static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; -static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; -static char atl2_driver_version[] = ATL2_DRV_VERSION; +static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; +static const char atl2_driver_version[] = ATL2_DRV_VERSION; MODULE_AUTHOR("Atheros Corporation , Chris Snook "); MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); -- cgit v1.2.3 From a700d8be733bd593ea4797dfde17aed4f35213c0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 8 Sep 2010 03:48:47 +0000 Subject: net/core: remove address space warnings on verify_iovec() move_addr_to_kernel() and copy_from_user() requires their argument as __user pointer but were missing proper markups. Add it. This removes following warnings from sparse. net/core/iovec.c:44:52: warning: incorrect type in argument 1 (different address spaces) net/core/iovec.c:44:52: expected void [noderef] *uaddr net/core/iovec.c:44:52: got void *msg_name net/core/iovec.c:55:34: warning: incorrect type in argument 2 (different address spaces) net/core/iovec.c:55:34: expected void const [noderef] *from net/core/iovec.c:55:34: got struct iovec *msg_iov Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- net/core/iovec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/core/iovec.c b/net/core/iovec.c index 1cd98df412df..f4657c2127b4 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -41,7 +41,9 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, if (m->msg_namelen) { if (mode == VERIFY_READ) { - err = move_addr_to_kernel(m->msg_name, m->msg_namelen, + void __user *namep; + namep = (void __user __force *) m->msg_name; + err = move_addr_to_kernel(namep, m->msg_namelen, address); if (err < 0) return err; @@ -52,7 +54,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, } size = m->msg_iovlen * sizeof(struct iovec); - if (copy_from_user(iov, m->msg_iov, size)) + if (copy_from_user(iov, (void __user __force *) m->msg_iov, size)) return -EFAULT; m->msg_iov = iov; -- cgit v1.2.3 From f39234d60617d37818b30991e6794643ce220296 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 8 Sep 2010 03:48:48 +0000 Subject: net/core: add lock context change annotations in net/core/sock.c __lock_sock() and __release_sock() releases and regrabs lock but were missing proper annotations. Add it. This removes following warning from sparse. (Currently __lock_sock() does not emit any warning about it but I think it is better to add also.) net/core/sock.c:1580:17: warning: context imbalance in '__release_sock' - unexpected unlock Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- net/core/sock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/core/sock.c b/net/core/sock.c index b05b9b6ddb87..f3a06c40d5e0 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1557,6 +1557,8 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, EXPORT_SYMBOL(sock_alloc_send_skb); static void __lock_sock(struct sock *sk) + __releases(&sk->sk_lock.slock) + __acquires(&sk->sk_lock.slock) { DEFINE_WAIT(wait); @@ -1573,6 +1575,8 @@ static void __lock_sock(struct sock *sk) } static void __release_sock(struct sock *sk) + __releases(&sk->sk_lock.slock) + __acquires(&sk->sk_lock.slock) { struct sk_buff *skb = sk->sk_backlog.head; -- cgit v1.2.3 From 49d61e2390c92bd226fc395a6165eb5a65ae4de6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 9 Sep 2010 05:33:43 +0000 Subject: tunnels: missing rcu_assign_pointer() xfrm4_tunnel_register() & xfrm6_tunnel_register() should use rcu_assign_pointer() to make sure previous writes (to handler->next) are committed to memory before chain insertion. deregister functions dont need a particular barrier. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tunnel4.c | 2 +- net/ipv6/tunnel6.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index df59d16337f2..9a17bd2a0a37 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -39,7 +39,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) } handler->next = *pprev; - *pprev = handler; + rcu_assign_pointer(*pprev, handler); ret = 0; diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index 3177fe0459e0..d9864725d0c6 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -51,7 +51,7 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) } handler->next = *pprev; - *pprev = handler; + rcu_assign_pointer(*pprev, handler); ret = 0; -- cgit v1.2.3 From fb621bac21fc315af9f66a754b7abe26ded3f260 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 8 Sep 2010 22:48:31 +0000 Subject: ixgbevf: remove private net_device_stats Use the net_device provided net_device_stats structure. Remove ixgbevf_get_stats() now its not needed. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ixgbevf/ixgbevf.h | 1 - drivers/net/ixgbevf/ixgbevf_main.c | 26 +++++--------------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index f7015efbff05..da4033c6efa2 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -243,7 +243,6 @@ struct ixgbevf_adapter { /* OS defined structs */ struct net_device *netdev; struct pci_dev *pdev; - struct net_device_stats net_stats; /* structs defined in ixgbe_vf.h */ struct ixgbe_hw hw; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index bdbd26c60ae6..3eda1bdbbb7a 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -308,8 +308,8 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; - adapter->net_stats.tx_bytes += total_bytes; - adapter->net_stats.tx_packets += total_packets; + netdev->stats.tx_bytes += total_bytes; + netdev->stats.tx_packets += total_packets; return (count < tx_ring->work_limit); } @@ -639,8 +639,8 @@ next_desc: rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - adapter->net_stats.rx_bytes += total_rx_bytes; - adapter->net_stats.rx_packets += total_rx_packets; + adapter->netdev->stats.rx_bytes += total_rx_bytes; + adapter->netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -2297,7 +2297,7 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter) adapter->stats.vfmprc); /* Fill out the OS statistics structure */ - adapter->net_stats.multicast = adapter->stats.vfmprc - + adapter->netdev->stats.multicast = adapter->stats.vfmprc - adapter->stats.base_vfmprc; } @@ -3180,21 +3180,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -/** - * ixgbevf_get_stats - Get System Network Statistics - * @netdev: network interface device structure - * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. - **/ -static struct net_device_stats *ixgbevf_get_stats(struct net_device *netdev) -{ - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - - /* only return the current stats */ - return &adapter->net_stats; -} - /** * ixgbevf_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -3272,7 +3257,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = &ixgbevf_open, .ndo_stop = &ixgbevf_close, .ndo_start_xmit = &ixgbevf_xmit_frame, - .ndo_get_stats = &ixgbevf_get_stats, .ndo_set_rx_mode = &ixgbevf_set_rx_mode, .ndo_set_multicast_list = &ixgbevf_set_rx_mode, .ndo_validate_addr = eth_validate_addr, -- cgit v1.2.3 From b2abd4c033c3965ce670841dfb401f5f166222d5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 8 Sep 2010 13:31:24 +0000 Subject: tipc: Optimize handling excess content on incoming messages Remove code that trimmed excess trailing info from incoming messages arriving over an Ethernet interface. TIPC now ignores the extra info while the message is being processed by the node, and only trims it off if the message is retransmitted to another node. (This latter step is done to ensure the extra info doesn't cause the sk_buff to exceed the outgoing interface's MTU limit.) The outgoing buffer is guaranteed to be linear. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- net/tipc/eth_media.c | 13 +++---------- net/tipc/net.c | 1 + 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 673fdf0b3222..6e988ba485fd 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -101,15 +101,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, * Accept only packets explicitly sent to this node, or broadcast packets; * ignores packets sent using Ethernet multicast, and traffic sent to other * nodes (which can happen if interface is running in promiscuous mode). - * Routine truncates any Ethernet padding/CRC appended to the message, - * and ensures message size matches actual length */ static int recv_msg(struct sk_buff *buf, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; - u32 size; if (!net_eq(dev_net(dev), &init_net)) { kfree_skb(buf); @@ -118,13 +115,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, if (likely(eb_ptr->bearer)) { if (likely(buf->pkt_type <= PACKET_BROADCAST)) { - size = msg_size((struct tipc_msg *)buf->data); - skb_trim(buf, size); - if (likely(buf->len == size)) { - buf->next = NULL; - tipc_recv_msg(buf, eb_ptr->bearer); - return 0; - } + buf->next = NULL; + tipc_recv_msg(buf, eb_ptr->bearer); + return 0; } } kfree_skb(buf); diff --git a/net/tipc/net.c b/net/tipc/net.c index f61b7694138b..7e05af47a196 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -248,6 +248,7 @@ void tipc_net_route_msg(struct sk_buff *buf) /* Handle message for another node */ msg_dbg(msg, "NET>SEND>: "); + skb_trim(buf, msg_size(msg)); tipc_link_send(buf, dnode, msg_link_selector(msg)); } -- cgit v1.2.3 From 3441592b34121a38047ed6680f0ed9b9017de9cf Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:25 +0000 Subject: au1000-eth: typedefs removal Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 26 +++++++++++++------------- drivers/net/au1000_eth.h | 30 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 15ae6df2ff00..b8ae85c6da03 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -452,9 +452,9 @@ static int au1000_mii_probe (struct net_device *dev) * has the virtual and dma address of a buffer suitable for * both, receive and transmit operations. */ -static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup) +static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup) { - db_dest_t *pDB; + struct db_dest *pDB; pDB = aup->pDBfree; if (pDB) { @@ -463,9 +463,9 @@ static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup) return pDB; } -void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB) +void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB) { - db_dest_t *pDBfree = aup->pDBfree; + struct db_dest *pDBfree = aup->pDBfree; if (pDBfree) pDBfree->pnext = pDB; aup->pDBfree = pDB; @@ -524,11 +524,11 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) for (i = 0; i < NUM_RX_DMA; i++) { aup->rx_dma_ring[i] = - (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i); + (volatile struct rx_dma *) (rx_base + sizeof(struct rx_dma)*i); } for (i = 0; i < NUM_TX_DMA; i++) { aup->tx_dma_ring[i] = - (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i); + (volatile struct tx_dma *) (tx_base + sizeof(struct tx_dma)*i); } } @@ -681,9 +681,9 @@ static int au1000_rx(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct sk_buff *skb; - volatile rx_dma_t *prxd; + volatile struct rx_dma *prxd; u32 buff_stat, status; - db_dest_t *pDB; + struct db_dest *pDB; u32 frmlen; netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head); @@ -774,7 +774,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status) static void au1000_tx_ack(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); - volatile tx_dma_t *ptxd; + volatile struct tx_dma *ptxd; ptxd = aup->tx_dma_ring[aup->tx_tail]; @@ -873,9 +873,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct net_device_stats *ps = &dev->stats; - volatile tx_dma_t *ptxd; + volatile struct tx_dma *ptxd; u32 buff_stat; - db_dest_t *pDB; + struct db_dest *pDB; int i; netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n", @@ -991,7 +991,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) struct au1000_private *aup = NULL; struct au1000_eth_platform_data *pd; struct net_device *dev = NULL; - db_dest_t *pDB, *pDBfree; + struct db_dest *pDB, *pDBfree; int irq, i, err = 0; struct resource *base, *macen; @@ -1054,7 +1054,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base)); + aup->mac = (volatile struct mac_reg *)ioremap_nocache(base->start, resource_size(base)); if (!aup->mac) { dev_err(&pdev->dev, "failed to ioremap MAC registers\n"); err = -ENXIO; diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index d06ec008fbf1..44003e4843b8 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -44,34 +44,34 @@ * Data Buffer Descriptor. Data buffers must be aligned on 32 byte * boundary for both, receive and transmit. */ -typedef struct db_dest { +struct db_dest { struct db_dest *pnext; volatile u32 *vaddr; dma_addr_t dma_addr; -} db_dest_t; +}; /* * The transmit and receive descriptors are memory * mapped registers. */ -typedef struct tx_dma { +struct tx_dma { u32 status; u32 buff_stat; u32 len; u32 pad; -} tx_dma_t; +}; -typedef struct rx_dma { +struct rx_dma { u32 status; u32 buff_stat; u32 pad[2]; -} rx_dma_t; +}; /* * MAC control registers, memory mapped. */ -typedef struct mac_reg { +struct mac_reg { u32 control; u32 mac_addr_high; u32 mac_addr_low; @@ -82,16 +82,16 @@ typedef struct mac_reg { u32 flow_control; u32 vlan1_tag; u32 vlan2_tag; -} mac_reg_t; +}; struct au1000_private { - db_dest_t *pDBfree; - db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS]; - volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA]; - volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA]; - db_dest_t *rx_db_inuse[NUM_RX_DMA]; - db_dest_t *tx_db_inuse[NUM_TX_DMA]; + struct db_dest *pDBfree; + struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS]; + volatile struct rx_dma *rx_dma_ring[NUM_RX_DMA]; + volatile struct tx_dma *tx_dma_ring[NUM_TX_DMA]; + struct db_dest *rx_db_inuse[NUM_RX_DMA]; + struct db_dest *tx_db_inuse[NUM_TX_DMA]; u32 rx_head; u32 tx_head; u32 tx_tail; @@ -118,7 +118,7 @@ struct au1000_private { int phy_irq; /* These variables are just for quick access to certain regs addresses. */ - volatile mac_reg_t *mac; /* mac registers */ + volatile struct mac_reg *mac; /* mac registers */ volatile u32 *enable; /* address of MAC Enable Register */ u32 vaddr; /* virtual address of rx/tx buffers */ -- cgit v1.2.3 From ec7eabdde2cc3e71fa71f979bd3448c45122a4a8 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:31 +0000 Subject: au1000-eth: stylistic fixes This patch fixes the following checkpatch.pl warnings: - spaces after tabs - space between function and arguments - one-line statement braces - tabs instead of spaces Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index b8ae85c6da03..df3eee11cd95 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -13,7 +13,7 @@ * converted to use linux-2.6.x's PHY framework * * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * ppopov@mvista.com or source@mvista.com * * ######################################################################## * @@ -152,7 +152,7 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) spin_lock_irqsave(&aup->lock, flags); - if(force_reset || (!aup->mac_enabled)) { + if (force_reset || (!aup->mac_enabled)) { *aup->enable = MAC_EN_CLOCK_ENABLE; au_sync_delay(2); *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 @@ -353,7 +353,7 @@ au1000_adjust_link(struct net_device *dev) } } -static int au1000_mii_probe (struct net_device *dev) +static int au1000_mii_probe(struct net_device *dev) { struct au1000_private *const aup = netdev_priv(dev); struct phy_device *phydev = NULL; @@ -457,9 +457,9 @@ static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup) struct db_dest *pDB; pDB = aup->pDBfree; - if (pDB) { + if (pDB) aup->pDBfree = pDB->pnext; - } + return pDB; } @@ -507,7 +507,7 @@ static void au1000_reset_mac(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - au1000_reset_mac_unlocked (dev); + au1000_reset_mac_unlocked(dev); spin_unlock_irqrestore(&aup->lock, flags); } @@ -625,9 +625,9 @@ static int au1000_init(struct net_device *dev) aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | dev->dev_addr[1]<<8 | dev->dev_addr[0]; - for (i = 0; i < NUM_RX_DMA; i++) { + for (i = 0; i < NUM_RX_DMA; i++) aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; - } + au_sync(); control = MAC_RX_ENABLE | MAC_TX_ENABLE; @@ -854,7 +854,7 @@ static int au1000_close(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - au1000_reset_mac_unlocked (dev); + au1000_reset_mac_unlocked(dev); /* stop the device */ netif_stop_queue(dev); @@ -902,9 +902,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) pDB = aup->tx_db_inuse[aup->tx_head]; skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len); if (skb->len < ETH_ZLEN) { - for (i = skb->len; i < ETH_ZLEN; i++) { + for (i = skb->len; i < ETH_ZLEN; i++) ((char *)pDB->vaddr)[i] = 0; - } + ptxd->len = ETH_ZLEN; } else ptxd->len = skb->len; @@ -1061,7 +1061,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) goto err_remap1; } - /* Setup some variables for quick register address access */ + /* Setup some variables for quick register address access */ aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen)); if (!aup->enable) { dev_err(&pdev->dev, "failed to ioremap MAC enable register\n"); @@ -1151,17 +1151,17 @@ static int __devinit au1000_probe(struct platform_device *pdev) for (i = 0; i < NUM_RX_DMA; i++) { pDB = au1000_GetFreeDB(aup); - if (!pDB) { + if (!pDB) goto err_out; - } + aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->rx_db_inuse[i] = pDB; } for (i = 0; i < NUM_TX_DMA; i++) { pDB = au1000_GetFreeDB(aup); - if (!pDB) { + if (!pDB) goto err_out; - } + aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->tx_dma_ring[i]->len = 0; aup->tx_db_inuse[i] = pDB; -- cgit v1.2.3 From 18b8e15b0433ac682138ce5d03157ddc28bdf350 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:40 +0000 Subject: au1000-eth: fix all but one "line over 80 characters warnings" One line has not been changed because it would not improve readability. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 103 ++++++++++++++++++++++++++--------------------- drivers/net/au1000_eth.h | 6 ++- 2 files changed, 61 insertions(+), 48 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index df3eee11cd95..a2d86cf62760 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -357,6 +357,7 @@ static int au1000_mii_probe(struct net_device *dev) { struct au1000_private *const aup = netdev_priv(dev); struct phy_device *phydev = NULL; + int phy_addr; if (aup->phy_static_config) { BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); @@ -366,42 +367,45 @@ static int au1000_mii_probe(struct net_device *dev) else netdev_info(dev, "using PHY-less setup\n"); return 0; - } else { - int phy_addr; - - /* find the first (lowest address) PHY on the current MAC's MII bus */ - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) - if (aup->mii_bus->phy_map[phy_addr]) { - phydev = aup->mii_bus->phy_map[phy_addr]; - if (!aup->phy_search_highest_addr) - break; /* break out with first one found */ - } - - if (aup->phy1_search_mac0) { - /* try harder to find a PHY */ - if (!phydev && (aup->mac_id == 1)) { - /* no PHY found, maybe we have a dual PHY? */ - dev_info(&dev->dev, ": no PHY found on MAC1, " - "let's see if it's attached to MAC0...\n"); - - /* find the first (lowest address) non-attached PHY on - * the MAC0 MII bus */ - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { - struct phy_device *const tmp_phydev = - aup->mii_bus->phy_map[phy_addr]; - - if (aup->mac_id == 1) - break; - - if (!tmp_phydev) - continue; /* no PHY here... */ + } - if (tmp_phydev->attached_dev) - continue; /* already claimed by MAC0 */ + /* find the first (lowest address) PHY + * on the current MAC's MII bus */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) + if (aup->mii_bus->phy_map[phy_addr]) { + phydev = aup->mii_bus->phy_map[phy_addr]; + if (!aup->phy_search_highest_addr) + /* break out with first one found */ + break; + } - phydev = tmp_phydev; - break; /* found it */ - } + if (aup->phy1_search_mac0) { + /* try harder to find a PHY */ + if (!phydev && (aup->mac_id == 1)) { + /* no PHY found, maybe we have a dual PHY? */ + dev_info(&dev->dev, ": no PHY found on MAC1, " + "let's see if it's attached to MAC0...\n"); + + /* find the first (lowest address) non-attached + * PHY on the MAC0 MII bus + */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { + struct phy_device *const tmp_phydev = + aup->mii_bus->phy_map[phy_addr]; + + if (aup->mac_id == 1) + break; + + /* no PHY here... */ + if (!tmp_phydev) + continue; + + /* already claimed by MAC0 */ + if (tmp_phydev->attached_dev) + continue; + + phydev = tmp_phydev; + break; /* found it */ } } } @@ -524,11 +528,13 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) for (i = 0; i < NUM_RX_DMA; i++) { aup->rx_dma_ring[i] = - (volatile struct rx_dma *) (rx_base + sizeof(struct rx_dma)*i); + (volatile struct rx_dma *) + (rx_base + sizeof(struct rx_dma)*i); } for (i = 0; i < NUM_TX_DMA; i++) { aup->tx_dma_ring[i] = - (volatile struct tx_dma *) (tx_base + sizeof(struct tx_dma)*i); + (volatile struct tx_dma *) + (tx_base + sizeof(struct tx_dma)*i); } } @@ -625,6 +631,7 @@ static int au1000_init(struct net_device *dev) aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | dev->dev_addr[1]<<8 | dev->dev_addr[0]; + for (i = 0; i < NUM_RX_DMA; i++) aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; @@ -936,8 +943,7 @@ static void au1000_multicast_list(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); - netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags); - + netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ aup->mac->control |= MAC_PROMISCUOUS; } else if ((dev->flags & IFF_ALLMULTI) || @@ -1016,13 +1022,15 @@ static int __devinit au1000_probe(struct platform_device *pdev) goto out; } - if (!request_mem_region(base->start, resource_size(base), pdev->name)) { + if (!request_mem_region(base->start, resource_size(base), + pdev->name)) { dev_err(&pdev->dev, "failed to request memory region for base registers\n"); err = -ENXIO; goto out; } - if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) { + if (!request_mem_region(macen->start, resource_size(macen), + pdev->name)) { dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n"); err = -ENXIO; goto err_request; @@ -1040,7 +1048,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) aup = netdev_priv(dev); spin_lock_init(&aup->lock); - aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug); + aup->msg_enable = (au1000_debug < 4 ? + AU1000_DEF_MSG_ENABLE : au1000_debug); /* Allocate the data buffers */ /* Snooping works fine with eth on all au1xxx */ @@ -1054,7 +1063,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile struct mac_reg *)ioremap_nocache(base->start, resource_size(base)); + aup->mac = (volatile struct mac_reg *) + ioremap_nocache(base->start, resource_size(base)); if (!aup->mac) { dev_err(&pdev->dev, "failed to ioremap MAC registers\n"); err = -ENXIO; @@ -1062,7 +1072,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* Setup some variables for quick register address access */ - aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen)); + aup->enable = (volatile u32 *)ioremap_nocache(macen->start, + resource_size(macen)); if (!aup->enable) { dev_err(&pdev->dev, "failed to ioremap MAC enable register\n"); err = -ENXIO; @@ -1083,7 +1094,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) pd = pdev->dev.platform_data; if (!pd) { - dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n"); + dev_info(&pdev->dev, "no platform_data passed," + " PHY search on MAC0\n"); aup->phy1_search_mac0 = 1; } else { if (is_valid_ether_addr(pd->mac)) @@ -1098,8 +1110,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) } if (aup->phy_busid && aup->phy_busid > 0) { - dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII" - "bus not supported yet\n"); + dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII bus not supported yet\n"); err = -ENODEV; goto err_mdiobus_alloc; } diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index 44003e4843b8..38c1d8845ac6 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -99,7 +99,8 @@ struct au1000_private { int mac_id; - int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */ + int mac_enabled; /* whether MAC is currently enabled and running + (req. for mdio) */ int old_link; /* used by au1000_adjust_link */ int old_speed; @@ -117,7 +118,8 @@ struct au1000_private { int phy_busid; int phy_irq; - /* These variables are just for quick access to certain regs addresses. */ + /* These variables are just for quick access + * to certain regs addresses. */ volatile struct mac_reg *mac; /* mac registers */ volatile u32 *enable; /* address of MAC Enable Register */ -- cgit v1.2.3 From 215e17be9f390e787cf9b9e5c9020d298b41d513 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:45 +0000 Subject: au1000-eth: fix bad printk usages Use pr_(info|err) and pr_cont where required instead of calls to printk. Add missing pr_fmt to the driver. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index a2d86cf62760..f758b60eea22 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -34,6 +34,8 @@ * * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -720,24 +722,26 @@ static int au1000_rx(struct net_device *dev) netif_rx(skb); /* pass the packet to upper layers */ } else { if (au1000_debug > 4) { + pr_err("rx_error(s):"); if (status & RX_MISSED_FRAME) - printk("rx miss\n"); + pr_cont(" miss"); if (status & RX_WDOG_TIMER) - printk("rx wdog\n"); + pr_cont(" wdog"); if (status & RX_RUNT) - printk("rx runt\n"); + pr_cont(" runt"); if (status & RX_OVERLEN) - printk("rx overlen\n"); + pr_cont(" overlen"); if (status & RX_COLL) - printk("rx coll\n"); + pr_cont(" coll"); if (status & RX_MII_ERROR) - printk("rx mii error\n"); + pr_cont(" mii error"); if (status & RX_CRC_ERROR) - printk("rx crc error\n"); + pr_cont(" crc error"); if (status & RX_LEN_ERROR) - printk("rx len error\n"); + pr_cont(" len error"); if (status & RX_U_CNTRL_FRAME) - printk("rx u control frame\n"); + pr_cont(" u control frame"); + pr_cont("\n"); } } prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); @@ -1199,7 +1203,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n", (unsigned long)base->start, irq); if (version_printed++ == 0) - printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); + pr_info("%s version %s %s\n", + DRV_NAME, DRV_VERSION, DRV_AUTHOR); return 0; -- cgit v1.2.3 From 49a42c080fbba9e99b4339763dd7771569ee38c3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:49 +0000 Subject: au1000-eth: fix asm -> linux headers inclusion Replace asm/io.h and asm/cpu.h wih linux/io.h and linux/cpu.h Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index f758b60eea22..4bbc537a7870 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -58,11 +58,11 @@ #include #include #include +#include +#include -#include #include #include -#include #include #include -- cgit v1.2.3 From d0e7cb5d401695809ba8c980124ab1d8c66efc8b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:15:13 +0000 Subject: au1000-eth: remove volatiles, switch to I/O accessors Remove all the volatile keywords where they were used, switch to using the proper readl/writel accessors. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 107 ++++++++++++++++++++++++++--------------------- drivers/net/au1000_eth.h | 10 ++--- 2 files changed, 65 insertions(+), 52 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 4bbc537a7870..f4c394fa2d93 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) spin_lock_irqsave(&aup->lock, flags); if (force_reset || (!aup->mac_enabled)) { - *aup->enable = MAC_EN_CLOCK_ENABLE; + writel(MAC_EN_CLOCK_ENABLE, &aup->enable); au_sync_delay(2); - *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 - | MAC_EN_CLOCK_ENABLE); + writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 + | MAC_EN_CLOCK_ENABLE), &aup->enable); au_sync_delay(2); aup->mac_enabled = 1; @@ -173,12 +173,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) { struct au1000_private *aup = netdev_priv(dev); - volatile u32 *const mii_control_reg = &aup->mac->mii_control; - volatile u32 *const mii_data_reg = &aup->mac->mii_data; + u32 *const mii_control_reg = &aup->mac->mii_control; + u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "read_MII busy timeout!!\n"); @@ -189,29 +189,29 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ; - *mii_control_reg = mii_control; + writel(mii_control, mii_control_reg); timedout = 20; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_read busy timeout!!\n"); return -1; } } - return (int)*mii_data_reg; + return readl(mii_data_reg); } static void au1000_mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value) { struct au1000_private *aup = netdev_priv(dev); - volatile u32 *const mii_control_reg = &aup->mac->mii_control; - volatile u32 *const mii_data_reg = &aup->mac->mii_data; + u32 *const mii_control_reg = &aup->mac->mii_control; + u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_write busy timeout!!\n"); @@ -222,8 +222,8 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE; - *mii_data_reg = value; - *mii_control_reg = mii_control; + writel(value, mii_data_reg); + writel(mii_control, mii_control_reg); } static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) @@ -260,20 +260,26 @@ static int au1000_mdiobus_reset(struct mii_bus *bus) static void au1000_hard_stop(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; netif_dbg(aup, drv, dev, "hard stop\n"); - aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); + reg = readl(&aup->mac->control); + reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); + writel(reg, &aup->mac->control); au_sync_delay(10); } static void au1000_enable_rx_tx(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; netif_dbg(aup, hw, dev, "enable_rx_tx\n"); - aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE); + reg = readl(&aup->mac->control); + reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); + writel(reg, &aup->mac->control); au_sync_delay(10); } @@ -283,6 +289,7 @@ au1000_adjust_link(struct net_device *dev) struct au1000_private *aup = netdev_priv(dev); struct phy_device *phydev = aup->phy_dev; unsigned long flags; + u32 reg; int status_change = 0; @@ -314,14 +321,15 @@ au1000_adjust_link(struct net_device *dev) /* switching duplex mode requires to disable rx and tx! */ au1000_hard_stop(dev); - if (DUPLEX_FULL == phydev->duplex) - aup->mac->control = ((aup->mac->control - | MAC_FULL_DUPLEX) - & ~MAC_DISABLE_RX_OWN); - else - aup->mac->control = ((aup->mac->control - & ~MAC_FULL_DUPLEX) - | MAC_DISABLE_RX_OWN); + reg = readl(&aup->mac->control); + if (DUPLEX_FULL == phydev->duplex) { + reg |= MAC_FULL_DUPLEX; + reg &= ~MAC_DISABLE_RX_OWN; + } else { + reg &= ~MAC_FULL_DUPLEX; + reg |= MAC_DISABLE_RX_OWN; + } + writel(reg, &aup->mac->control); au_sync_delay(1); au1000_enable_rx_tx(dev); @@ -484,9 +492,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) au1000_hard_stop(dev); - *aup->enable = MAC_EN_CLOCK_ENABLE; + writel(MAC_EN_CLOCK_ENABLE, &aup->enable); au_sync_delay(2); - *aup->enable = 0; + writel(0, &aup->enable); au_sync_delay(2); aup->tx_full = 0; @@ -530,12 +538,12 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) for (i = 0; i < NUM_RX_DMA; i++) { aup->rx_dma_ring[i] = - (volatile struct rx_dma *) + (struct rx_dma *) (rx_base + sizeof(struct rx_dma)*i); } for (i = 0; i < NUM_TX_DMA; i++) { aup->tx_dma_ring[i] = - (volatile struct tx_dma *) + (struct tx_dma *) (tx_base + sizeof(struct tx_dma)*i); } } @@ -624,14 +632,16 @@ static int au1000_init(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - aup->mac->control = 0; + writel(0, &aup->mac->control); aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2; aup->tx_tail = aup->tx_head; aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2; - aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4]; - aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | - dev->dev_addr[1]<<8 | dev->dev_addr[0]; + writel(dev->dev_addr[5]<<8 | dev->dev_addr[4], + &aup->mac->mac_addr_high); + writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | + dev->dev_addr[1]<<8 | dev->dev_addr[0], + &aup->mac->mac_addr_low); for (i = 0; i < NUM_RX_DMA; i++) @@ -652,8 +662,8 @@ static int au1000_init(struct net_device *dev) control |= MAC_FULL_DUPLEX; } - aup->mac->control = control; - aup->mac->vlan1_tag = 0x8100; /* activate vlan support */ + writel(control, &aup->mac->control); + writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ au_sync(); spin_unlock_irqrestore(&aup->lock, flags); @@ -690,7 +700,7 @@ static int au1000_rx(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct sk_buff *skb; - volatile struct rx_dma *prxd; + struct rx_dma *prxd; u32 buff_stat, status; struct db_dest *pDB; u32 frmlen; @@ -785,7 +795,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status) static void au1000_tx_ack(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); - volatile struct tx_dma *ptxd; + struct tx_dma *ptxd; ptxd = aup->tx_dma_ring[aup->tx_tail]; @@ -884,7 +894,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct net_device_stats *ps = &dev->stats; - volatile struct tx_dma *ptxd; + struct tx_dma *ptxd; u32 buff_stat; struct db_dest *pDB; int i; @@ -946,14 +956,16 @@ static void au1000_tx_timeout(struct net_device *dev) static void au1000_multicast_list(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags); + reg = readl(&aup->mac->control); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - aup->mac->control |= MAC_PROMISCUOUS; + reg |= MAC_PROMISCUOUS; } else if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) { - aup->mac->control |= MAC_PASS_ALL_MULTI; - aup->mac->control &= ~MAC_PROMISCUOUS; + reg |= MAC_PASS_ALL_MULTI; + reg &= ~MAC_PROMISCUOUS; netdev_info(dev, "Pass all multicast\n"); } else { struct netdev_hw_addr *ha; @@ -963,11 +975,12 @@ static void au1000_multicast_list(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) set_bit(ether_crc(ETH_ALEN, ha->addr)>>26, (long *)mc_filter); - aup->mac->multi_hash_high = mc_filter[1]; - aup->mac->multi_hash_low = mc_filter[0]; - aup->mac->control &= ~MAC_PROMISCUOUS; - aup->mac->control |= MAC_HASH_MODE; + writel(mc_filter[1], &aup->mac->multi_hash_high); + writel(mc_filter[0], &aup->mac->multi_hash_low); + reg &= ~MAC_PROMISCUOUS; + reg |= MAC_HASH_MODE; } + writel(reg, &aup->mac->control); } static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -1067,7 +1080,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile struct mac_reg *) + aup->mac = (struct mac_reg *) ioremap_nocache(base->start, resource_size(base)); if (!aup->mac) { dev_err(&pdev->dev, "failed to ioremap MAC registers\n"); @@ -1076,7 +1089,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* Setup some variables for quick register address access */ - aup->enable = (volatile u32 *)ioremap_nocache(macen->start, + aup->enable = (u32 *)ioremap_nocache(macen->start, resource_size(macen)); if (!aup->enable) { dev_err(&pdev->dev, "failed to ioremap MAC enable register\n"); @@ -1093,7 +1106,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) /* set a random MAC now in case platform_data doesn't provide one */ random_ether_addr(dev->dev_addr); - *aup->enable = 0; + writel(0, &aup->enable); aup->mac_enabled = 0; pd = pdev->dev.platform_data; diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index 38c1d8845ac6..4b638df22240 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -46,7 +46,7 @@ */ struct db_dest { struct db_dest *pnext; - volatile u32 *vaddr; + u32 *vaddr; dma_addr_t dma_addr; }; @@ -88,8 +88,8 @@ struct mac_reg { struct au1000_private { struct db_dest *pDBfree; struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS]; - volatile struct rx_dma *rx_dma_ring[NUM_RX_DMA]; - volatile struct tx_dma *tx_dma_ring[NUM_TX_DMA]; + struct rx_dma *rx_dma_ring[NUM_RX_DMA]; + struct tx_dma *tx_dma_ring[NUM_TX_DMA]; struct db_dest *rx_db_inuse[NUM_RX_DMA]; struct db_dest *tx_db_inuse[NUM_TX_DMA]; u32 rx_head; @@ -120,8 +120,8 @@ struct au1000_private { /* These variables are just for quick access * to certain regs addresses. */ - volatile struct mac_reg *mac; /* mac registers */ - volatile u32 *enable; /* address of MAC Enable Register */ + struct mac_reg *mac; /* mac registers */ + u32 *enable; /* address of MAC Enable Register */ u32 vaddr; /* virtual address of rx/tx buffers */ dma_addr_t dma_addr; /* dma address of rx/tx buffers */ -- cgit v1.2.3 From dc99839cf600518ed1f20e47522fe7f629387078 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 8 Sep 2010 11:11:59 +0000 Subject: au1000-eth: change multi-line comments style Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/au1000_eth.c | 38 ++++++++++++++++++++++++++------------ drivers/net/au1000_eth.h | 6 ++++-- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index f4c394fa2d93..43489f89c142 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -229,11 +229,15 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) { /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does - * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */ + * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) + */ struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + return au1000_mdio_read(dev, phy_addr, regnum); } @@ -242,8 +246,11 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, { struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + au1000_mdio_write(dev, phy_addr, regnum, value); return 0; } @@ -252,8 +259,11 @@ static int au1000_mdiobus_reset(struct mii_bus *bus) { struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + return 0; } @@ -380,7 +390,8 @@ static int au1000_mii_probe(struct net_device *dev) } /* find the first (lowest address) PHY - * on the current MAC's MII bus */ + * on the current MAC's MII bus + */ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) if (aup->mii_bus->phy_map[phy_addr]) { phydev = aup->mii_bus->phy_map[phy_addr]; @@ -774,7 +785,8 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status) if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { /* any other tx errors are only valid - * in half duplex mode */ + * in half duplex mode + */ ps->tx_errors++; ps->tx_aborted_errors++; } @@ -1068,8 +1080,9 @@ static int __devinit au1000_probe(struct platform_device *pdev) aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug); - /* Allocate the data buffers */ - /* Snooping works fine with eth on all au1xxx */ + /* Allocate the data buffers + * Snooping works fine with eth on all au1xxx + */ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), &aup->dma_addr, 0); @@ -1226,7 +1239,8 @@ err_out: mdiobus_unregister(aup->mii_bus); /* here we should have a valid dev plus aup-> register addresses - * so we can reset the mac properly.*/ + * so we can reset the mac properly. + */ au1000_reset_mac(dev); for (i = 0; i < NUM_RX_DMA; i++) { diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index 4b638df22240..6229c774552c 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -100,7 +100,8 @@ struct au1000_private { int mac_id; int mac_enabled; /* whether MAC is currently enabled and running - (req. for mdio) */ + * (req. for mdio) + */ int old_link; /* used by au1000_adjust_link */ int old_speed; @@ -119,7 +120,8 @@ struct au1000_private { int phy_irq; /* These variables are just for quick access - * to certain regs addresses. */ + * to certain regs addresses. + */ struct mac_reg *mac; /* mac registers */ u32 *enable; /* address of MAC Enable Register */ -- cgit v1.2.3 From cbd9da7be869f676afc204e1a664163778c770bd Mon Sep 17 00:00:00 2001 From: Nikitas Angelinas Date: Wed, 8 Sep 2010 11:20:37 +0000 Subject: drivers/net/bnx2x: use ARRAY_SIZE macro in bnx2x_main.c Replace sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0]) with ARRAY_SIZE(bnx2x_parity_mask) in drivers/net/bnx2x/bnx2x_main.c Signed-off-by: Nikitas Angelinas Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f0a788467fb1..7ba3a6d96fd5 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3830,10 +3830,9 @@ static const struct { static void enable_blocks_parity(struct bnx2x *bp) { - int i, mask_arr_len = - sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0])); + int i; - for (i = 0; i < mask_arr_len; i++) + for (i = 0; i < ARRAY_SIZE(bnx2x_parity_mask); i++) REG_WR(bp, bnx2x_parity_mask[i].addr, bnx2x_parity_mask[i].mask); } -- cgit v1.2.3 From 1cdc2cfc8af6d1045c844b9e24a7910b57232065 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:00 +0000 Subject: sfc: Use MCDI RX_BAD_FCS_PKTS count as MAC rx_bad count Calculating rx_bad as rx_packets - rx_good is unnecessary and incorrect, since rx_good does not include control frames (e.g. pause frames) and rx_packets does. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/siena.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 3fab030f8ab5..9f5368049694 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -450,7 +450,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) mac_stats->rx_bad_bytes); MAC_STAT(rx_packets, RX_PKTS); MAC_STAT(rx_good, RX_GOOD_PKTS); - mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good; + MAC_STAT(rx_bad, RX_BAD_FCS_PKTS); MAC_STAT(rx_pause, RX_PAUSE_PKTS); MAC_STAT(rx_control, RX_CONTROL_PKTS); MAC_STAT(rx_unicast, RX_UNICAST_PKTS); -- cgit v1.2.3 From 80485d3441fc26aff5ddb2bf44baf7a61e1909b4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:06 +0000 Subject: sfc: Accumulate RX_NODESC_DROP count in rx_dropped, not rx_over_errors rx_over_errors appears to be intended as a count of packets that overflow a packet buffer in the NIC. Given that we implement a cut-through receive path, this should always be 0. rx_dropped appears to be the correct counter for packets dropped due to lack of host buffers. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index ba674c5ca29e..b385f895bf23 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1546,11 +1546,11 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc stats->tx_packets = mac_stats->tx_packets; stats->rx_bytes = mac_stats->rx_bytes; stats->tx_bytes = mac_stats->tx_bytes; + stats->rx_dropped = efx->n_rx_nodesc_drop_cnt; stats->multicast = mac_stats->rx_multicast; stats->collisions = mac_stats->tx_collision; stats->rx_length_errors = (mac_stats->rx_gtjumbo + mac_stats->rx_length_error); - stats->rx_over_errors = efx->n_rx_nodesc_drop_cnt; stats->rx_crc_errors = mac_stats->rx_bad; stats->rx_frame_errors = mac_stats->rx_align_error; stats->rx_fifo_errors = mac_stats->rx_overflow; -- cgit v1.2.3 From 7db8e8ec3995a1dc2bfadd8ac97e9024013db9c3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:12 +0000 Subject: sfc: Remove declarations of functions that no longer exist Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 060dc952a0fd..d6b172b1a8ef 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -81,8 +81,6 @@ extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok); extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, bool rx_adaptive); -extern int efx_request_power(struct efx_nic *efx, int mw, const char *name); -extern void efx_hex_dump(const u8 *, unsigned int, const char *); /* Dummy PHY ops for PHY drivers */ extern int efx_port_dummy_op_int(struct efx_nic *efx); -- cgit v1.2.3 From e42de26249c88a00715ea686993192546d07133e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:19 +0000 Subject: sfc: Fix failure paths in efx_probe_port() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index b385f895bf23..a57604527a42 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -761,7 +761,7 @@ static int efx_probe_port(struct efx_nic *efx) /* Connect up MAC/PHY operations table */ rc = efx->type->probe_port(efx); if (rc) - goto err; + return rc; /* Sanity check MAC address */ if (is_valid_ether_addr(efx->mac_address)) { @@ -782,7 +782,7 @@ static int efx_probe_port(struct efx_nic *efx) return 0; err: - efx_remove_port(efx); + efx->type->remove_port(efx); return rc; } -- cgit v1.2.3 From 58758aa505edc5b8f8393cee45b54c7485d76de5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:26 +0000 Subject: sfc: Allocate DMA and event rings using GFP_KERNEL Currently we allocate DMA descriptor rings and event rings using pci_alloc_consistent() which selects non-blocking behaviour from the page allocator (GFP_ATOMIC). This is unnecessary, and since we currently allocate a single contiguous block for each ring (up to 32 pages!) these allocations are likely to fail if there is any significant memory pressure. Use dma_alloc_coherent() and GFP_KERNEL instead. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/nic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index f595d920c7c4..8efe1ca83c1d 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -263,8 +263,8 @@ static int efx_alloc_special_buffer(struct efx_nic *efx, { len = ALIGN(len, EFX_BUF_SIZE); - buffer->addr = pci_alloc_consistent(efx->pci_dev, len, - &buffer->dma_addr); + buffer->addr = dma_alloc_coherent(&efx->pci_dev->dev, len, + &buffer->dma_addr, GFP_KERNEL); if (!buffer->addr) return -ENOMEM; buffer->len = len; @@ -301,8 +301,8 @@ efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) (u64)buffer->dma_addr, buffer->len, buffer->addr, (u64)virt_to_phys(buffer->addr)); - pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr, - buffer->dma_addr); + dma_free_coherent(&efx->pci_dev->dev, buffer->len, buffer->addr, + buffer->dma_addr); buffer->addr = NULL; buffer->entries = 0; } -- cgit v1.2.3 From ba1e8a35b77f3bc7d109696dbd2a7fd5af208b62 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:36 +0000 Subject: sfc: Abstract channel and index lookup for RX queues Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 11 +++++++++++ drivers/net/sfc/nic.c | 31 +++++++++++++++++-------------- drivers/net/sfc/rx.c | 38 +++++++++++++++++++------------------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 64e7caa4bbb5..89c6e02c57dd 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -943,6 +943,17 @@ struct efx_nic_type { continue; \ else +static inline struct efx_channel * +efx_rx_queue_channel(struct efx_rx_queue *rx_queue) +{ + return rx_queue->channel; +} + +static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue) +{ + return rx_queue->queue; +} + /* Returns a pointer to the specified receive buffer in the RX * descriptor queue. */ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 8efe1ca83c1d..be4d5524054f 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -539,8 +539,8 @@ void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue) wmb(); write_ptr = rx_queue->added_count & EFX_RXQ_MASK; EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); - efx_writed_page(rx_queue->efx, ®, - FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); + efx_writed_page(rx_queue->efx, ®, FR_AZ_RX_DESC_UPD_DWORD_P0, + efx_rx_queue_index(rx_queue)); } int efx_nic_probe_rx(struct efx_rx_queue *rx_queue) @@ -561,7 +561,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) netif_dbg(efx, hw, efx->net_dev, "RX queue %d ring in special buffers %d-%d\n", - rx_queue->queue, rx_queue->rxd.index, + efx_rx_queue_index(rx_queue), rx_queue->rxd.index, rx_queue->rxd.index + rx_queue->rxd.entries - 1); rx_queue->flushed = FLUSH_NONE; @@ -575,9 +575,10 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en, FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index, FRF_AZ_RX_DESCQ_EVQ_ID, - rx_queue->channel->channel, + efx_rx_queue_channel(rx_queue)->channel, FRF_AZ_RX_DESCQ_OWNER_ID, 0, - FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue, + FRF_AZ_RX_DESCQ_LABEL, + efx_rx_queue_index(rx_queue), FRF_AZ_RX_DESCQ_SIZE, __ffs(rx_queue->rxd.entries), FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , @@ -585,7 +586,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) FRF_AZ_RX_DESCQ_JUMBO, !is_b0, FRF_AZ_RX_DESCQ_EN, 1); efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_rx_queue_index(rx_queue)); } static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) @@ -598,7 +599,8 @@ static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) /* Post a flush command */ EFX_POPULATE_OWORD_2(rx_flush_descq, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, - FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue); + FRF_AZ_RX_FLUSH_DESCQ, + efx_rx_queue_index(rx_queue)); efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); } @@ -613,7 +615,7 @@ void efx_nic_fini_rx(struct efx_rx_queue *rx_queue) /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_rx_queue_index(rx_queue)); /* Unpin RX descriptor ring */ efx_fini_special_buffer(efx, &rx_queue->rxd); @@ -714,6 +716,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, bool *rx_ev_pkt_ok, bool *discard) { + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; @@ -746,14 +749,14 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, /* Count errors that are not in MAC stats. Ignore expected * checksum errors during self-test. */ if (rx_ev_frm_trunc) - ++rx_queue->channel->n_rx_frm_trunc; + ++channel->n_rx_frm_trunc; else if (rx_ev_tobe_disc) - ++rx_queue->channel->n_rx_tobe_disc; + ++channel->n_rx_tobe_disc; else if (!efx->loopback_selftest) { if (rx_ev_ip_hdr_chksum_err) - ++rx_queue->channel->n_rx_ip_hdr_chksum_err; + ++channel->n_rx_ip_hdr_chksum_err; else if (rx_ev_tcp_udp_chksum_err) - ++rx_queue->channel->n_rx_tcp_udp_chksum_err; + ++channel->n_rx_tcp_udp_chksum_err; } /* The frame must be discarded if any of these are true. */ @@ -769,7 +772,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, netif_dbg(efx, rx_err, efx->net_dev, " RX queue %d unexpected RX event " EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n", - rx_queue->queue, EFX_QWORD_VAL(*event), + efx_rx_queue_index(rx_queue), EFX_QWORD_VAL(*event), rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "", rx_ev_ip_hdr_chksum_err ? " [IP_HDR_CHKSUM_ERR]" : "", @@ -1269,7 +1272,7 @@ int efx_nic_flush_queues(struct efx_nic *efx) if (rx_queue->flushed != FLUSH_DONE) netif_err(efx, hw, efx->net_dev, "rx queue %d flush command timed out\n", - rx_queue->queue); + efx_rx_queue_index(rx_queue)); rx_queue->flushed = FLUSH_DONE; } diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index acb372e841b2..1e6c8cfa6c0c 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -341,7 +341,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, */ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) { - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); unsigned fill_level; int space, rc = 0; @@ -364,7 +364,8 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" " level %d to level %d using %s allocation\n", - rx_queue->queue, fill_level, rx_queue->fast_fill_limit, + efx_rx_queue_index(rx_queue), fill_level, + rx_queue->fast_fill_limit, channel->rx_alloc_push_pages ? "page" : "skb"); do { @@ -382,7 +383,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filled descriptor ring " - "to level %d\n", rx_queue->queue, + "to level %d\n", efx_rx_queue_index(rx_queue), rx_queue->added_count - rx_queue->removed_count); out: @@ -393,7 +394,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) void efx_rx_slow_fill(unsigned long context) { struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); /* Post an event to cause NAPI to run and refill the queue */ efx_nic_generate_fill_event(channel); @@ -421,7 +422,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d seriously overlength " "RX event (0x%x > 0x%x+0x%x). Leaking\n", - rx_queue->queue, len, max_len, + efx_rx_queue_index(rx_queue), len, max_len, efx->type->rx_buffer_padding); /* If this buffer was skb-allocated, then the meta * data at the end of the skb will be trashed. So @@ -434,10 +435,10 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d overlength RX event " "(0x%x > 0x%x)\n", - rx_queue->queue, len, max_len); + efx_rx_queue_index(rx_queue), len, max_len); } - rx_queue->channel->n_rx_overlength++; + efx_rx_queue_channel(rx_queue)->n_rx_overlength++; } /* Pass a received packet up through the generic LRO stack @@ -507,7 +508,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, bool checksummed, bool discard) { struct efx_nic *efx = rx_queue->efx; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_rx_buffer *rx_buf; bool leak_packet = false; @@ -528,7 +529,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", - rx_queue->queue, index, + efx_rx_queue_index(rx_queue), index, (unsigned long long)rx_buf->dma_addr, len, (checksummed ? " [SUMMED]" : ""), (discard ? " [DISCARD]" : "")); @@ -560,12 +561,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ rx_buf->len = len; out: - if (rx_queue->channel->rx_pkt) - __efx_rx_packet(rx_queue->channel, - rx_queue->channel->rx_pkt, - rx_queue->channel->rx_pkt_csummed); - rx_queue->channel->rx_pkt = rx_buf; - rx_queue->channel->rx_pkt_csummed = checksummed; + if (channel->rx_pkt) + __efx_rx_packet(channel, + channel->rx_pkt, channel->rx_pkt_csummed); + channel->rx_pkt = rx_buf; + channel->rx_pkt_csummed = checksummed; } /* Handle a received packet. Second half: Touches packet payload. */ @@ -654,7 +654,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) int rc; netif_dbg(efx, probe, efx->net_dev, - "creating RX queue %d\n", rx_queue->queue); + "creating RX queue %d\n", efx_rx_queue_index(rx_queue)); /* Allocate RX buffers */ rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer); @@ -675,7 +675,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) unsigned int max_fill, trigger, limit; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "initialising RX queue %d\n", rx_queue->queue); + "initialising RX queue %d\n", efx_rx_queue_index(rx_queue)); /* Initialise ptr fields */ rx_queue->added_count = 0; @@ -703,7 +703,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) struct efx_rx_buffer *rx_buf; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "shutting down RX queue %d\n", rx_queue->queue); + "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); del_timer_sync(&rx_queue->slow_fill); efx_nic_fini_rx(rx_queue); @@ -720,7 +720,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) { netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "destroying RX queue %d\n", rx_queue->queue); + "destroying RX queue %d\n", efx_rx_queue_index(rx_queue)); efx_nic_remove_rx(rx_queue); -- cgit v1.2.3 From f7d12cdcbb28207b3bdcf4affbf3935e4c015d03 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:47 +0000 Subject: sfc: Refactor channel and queue lookup and iteration In preparation for changes to the way channels and queue structures are allocated, revise the macros and functions used to look up and iterator over them. - Replace efx_for_each_tx_queue() with iteration over channels then TX queues - Replace efx_for_each_rx_queue() with iteration over channels then RX queues (with one exception, shortly to be removed) - Introduce efx_get_{channel,rx_queue,tx_queue}() functions to look up channels and queues by index - Introduce efx_channel_get_{rx,tx}_queue() functions to look up a channel's queues Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 28 ++++++++------- drivers/net/sfc/ethtool.c | 15 ++++---- drivers/net/sfc/net_driver.h | 43 ++++++++++++++++++---- drivers/net/sfc/nic.c | 85 +++++++++++++++++++++++++------------------- drivers/net/sfc/rx.c | 2 +- drivers/net/sfc/selftest.c | 5 +-- drivers/net/sfc/tx.c | 22 ++++++------ 7 files changed, 125 insertions(+), 75 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index a57604527a42..3dd71aa310cd 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -248,7 +248,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) efx_rx_strategy(channel); - efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); + efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel)); return spent; } @@ -1050,7 +1050,8 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_rx_channels = efx->n_channels; } for (i = 0; i < n_channels; i++) - efx->channel[i].irq = xentries[i].vector; + efx_get_channel(efx, i)->irq = + xentries[i].vector; } else { /* Fall back to single channel MSI */ efx->interrupt_mode = EFX_INT_MODE_MSI; @@ -1066,7 +1067,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_tx_channels = 1; rc = pci_enable_msi(efx->pci_dev); if (rc == 0) { - efx->channel[0].irq = efx->pci_dev->irq; + efx_get_channel(efx, 0)->irq = efx->pci_dev->irq; } else { netif_err(efx, drv, efx->net_dev, "could not enable MSI\n"); @@ -1355,20 +1356,20 @@ static unsigned irq_mod_ticks(int usecs, int resolution) void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, bool rx_adaptive) { - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; + struct efx_channel *channel; unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); EFX_ASSERT_RESET_SERIALISED(efx); - efx_for_each_tx_queue(tx_queue, efx) - tx_queue->channel->irq_moderation = tx_ticks; - efx->irq_rx_adaptive = rx_adaptive; efx->irq_rx_moderation = rx_ticks; - efx_for_each_rx_queue(rx_queue, efx) - rx_queue->channel->irq_moderation = rx_ticks; + efx_for_each_channel(channel, efx) { + if (efx_channel_get_rx_queue(channel)) + channel->irq_moderation = rx_ticks; + else if (efx_channel_get_tx_queue(channel, 0)) + channel->irq_moderation = tx_ticks; + } } /************************************************************************** @@ -1767,6 +1768,7 @@ fail_registered: static void efx_unregister_netdev(struct efx_nic *efx) { + struct efx_channel *channel; struct efx_tx_queue *tx_queue; if (!efx->net_dev) @@ -1777,8 +1779,10 @@ static void efx_unregister_netdev(struct efx_nic *efx) /* Free up any skbs still remaining. This has to happen before * we try to unregister the netdev as running their destructors * may be needed to get the device ref. count to 0. */ - efx_for_each_tx_queue(tx_queue, efx) - efx_release_tx_buffers(tx_queue); + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_release_tx_buffers(tx_queue); + } if (efx_dev_registered(efx)) { strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index fd19d6ab97a2..b9291db023bb 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -328,9 +328,10 @@ static int efx_fill_loopback_test(struct efx_nic *efx, unsigned int test_index, struct ethtool_string *strings, u64 *data) { + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; - efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { + efx_for_each_channel_tx_queue(tx_queue, channel) { efx_fill_test(test_index++, strings, data, &lb_tests->tx_sent[tx_queue->queue], EFX_TX_QUEUE_NAME(tx_queue), @@ -673,15 +674,15 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, struct ethtool_coalesce *coalesce) { struct efx_nic *efx = netdev_priv(net_dev); - struct efx_tx_queue *tx_queue; struct efx_channel *channel; memset(coalesce, 0, sizeof(*coalesce)); /* Find lowest IRQ moderation across all used TX queues */ coalesce->tx_coalesce_usecs_irq = ~((u32) 0); - efx_for_each_tx_queue(tx_queue, efx) { - channel = tx_queue->channel; + efx_for_each_channel(channel, efx) { + if (!efx_channel_get_tx_queue(channel, 0)) + continue; if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { if (channel->channel < efx->n_rx_channels) coalesce->tx_coalesce_usecs_irq = @@ -708,7 +709,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_channel *channel; - struct efx_tx_queue *tx_queue; unsigned tx_usecs, rx_usecs, adaptive; if (coalesce->use_adaptive_tx_coalesce) @@ -725,8 +725,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, adaptive = coalesce->use_adaptive_rx_coalesce; /* If the channel is shared only allow RX parameters to be set */ - efx_for_each_tx_queue(tx_queue, efx) { - if ((tx_queue->channel->channel < efx->n_rx_channels) && + efx_for_each_channel(channel, efx) { + if (efx_channel_get_rx_queue(channel) && + efx_channel_get_tx_queue(channel, 0) && tx_usecs) { netif_err(efx, drv, efx->net_dev, "Channel is shared. " "Only RX coalescing may be set\n"); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 89c6e02c57dd..eb3537529c9c 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -909,18 +909,34 @@ struct efx_nic_type { * *************************************************************************/ +static inline struct efx_channel * +efx_get_channel(struct efx_nic *efx, unsigned index) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_channels); + return &efx->channel[index]; +} + /* Iterate over all used channels */ #define efx_for_each_channel(_channel, _efx) \ for (_channel = &((_efx)->channel[0]); \ _channel < &((_efx)->channel[(efx)->n_channels]); \ _channel++) -/* Iterate over all used TX queues */ -#define efx_for_each_tx_queue(_tx_queue, _efx) \ - for (_tx_queue = &((_efx)->tx_queue[0]); \ - _tx_queue < &((_efx)->tx_queue[EFX_TXQ_TYPES * \ - (_efx)->n_tx_channels]); \ - _tx_queue++) +static inline struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || + type >= EFX_TXQ_TYPES); + return &efx->tx_queue[index * EFX_TXQ_TYPES + type]; +} + +static inline struct efx_tx_queue * +efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) +{ + struct efx_tx_queue *tx_queue = channel->tx_queue; + EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES); + return tx_queue ? tx_queue + type : NULL; +} /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ @@ -928,12 +944,27 @@ struct efx_nic_type { _tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ _tx_queue++) +static inline struct efx_rx_queue * +efx_get_rx_queue(struct efx_nic *efx, unsigned index) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels); + return &efx->rx_queue[index]; +} + /* Iterate over all used RX queues */ #define efx_for_each_rx_queue(_rx_queue, _efx) \ for (_rx_queue = &((_efx)->rx_queue[0]); \ _rx_queue < &((_efx)->rx_queue[(_efx)->n_rx_channels]); \ _rx_queue++) +static inline struct efx_rx_queue * +efx_channel_get_rx_queue(struct efx_channel *channel) +{ + struct efx_rx_queue *rx_queue = + &channel->efx->rx_queue[channel->channel]; + return rx_queue->channel == channel ? rx_queue : NULL; +} + /* Iterate over all RX queues belonging to a channel */ #define efx_for_each_channel_rx_queue(_rx_queue, _channel) \ for (_rx_queue = &((_channel)->efx->rx_queue[(_channel)->channel]); \ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index be4d5524054f..9e3563348eb7 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -682,7 +682,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) /* Transmit completion */ tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; + tx_queue = efx_channel_get_tx_queue( + channel, tx_ev_q_label % EFX_TXQ_TYPES); tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) & EFX_TXQ_MASK); channel->irq_mod_score += tx_packets; @@ -690,7 +691,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { /* Rewrite the FIFO write pointer */ tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; + tx_queue = efx_channel_get_tx_queue( + channel, tx_ev_q_label % EFX_TXQ_TYPES); if (efx_dev_registered(efx)) netif_tx_lock(efx->net_dev); @@ -830,7 +832,7 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) != channel->channel); - rx_queue = &efx->rx_queue[channel->channel]; + rx_queue = efx_channel_get_rx_queue(channel); rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; @@ -882,7 +884,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event) /* The queue must be empty, so we won't receive any rx * events, so efx_process_channel() won't refill the * queue. Refill it here */ - efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); + efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel)); else netif_dbg(efx, hw, efx->net_dev, "channel %d received " "generated event "EFX_QWORD_FMT"\n", @@ -1166,7 +1168,7 @@ void efx_nic_generate_fill_event(struct efx_channel *channel) static void efx_poll_flush_events(struct efx_nic *efx) { - struct efx_channel *channel = &efx->channel[0]; + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; unsigned int read_ptr = channel->eventq_read_ptr; @@ -1188,7 +1190,9 @@ static void efx_poll_flush_events(struct efx_nic *efx) ev_queue = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) { - tx_queue = efx->tx_queue + ev_queue; + tx_queue = efx_get_tx_queue( + efx, ev_queue / EFX_TXQ_TYPES, + ev_queue % EFX_TXQ_TYPES); tx_queue->flushed = FLUSH_DONE; } } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && @@ -1198,7 +1202,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) ev_failed = EFX_QWORD_FIELD( *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); if (ev_queue < efx->n_rx_channels) { - rx_queue = efx->rx_queue + ev_queue; + rx_queue = efx_get_rx_queue(efx, ev_queue); rx_queue->flushed = ev_failed ? FLUSH_FAILED : FLUSH_DONE; } @@ -1219,6 +1223,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) * serialise them */ int efx_nic_flush_queues(struct efx_nic *efx) { + struct efx_channel *channel; struct efx_rx_queue *rx_queue; struct efx_tx_queue *tx_queue; int i, tx_pending, rx_pending; @@ -1227,29 +1232,35 @@ int efx_nic_flush_queues(struct efx_nic *efx) efx->type->prepare_flush(efx); /* Flush all tx queues in parallel */ - efx_for_each_tx_queue(tx_queue, efx) - efx_flush_tx_queue(tx_queue); + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_flush_tx_queue(tx_queue); + } /* The hardware supports four concurrent rx flushes, each of which may * need to be retried if there is an outstanding descriptor fetch */ for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) { rx_pending = tx_pending = 0; - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed == FLUSH_PENDING) - ++rx_pending; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_pending == EFX_RX_FLUSH_COUNT) - break; - if (rx_queue->flushed == FLUSH_FAILED || - rx_queue->flushed == FLUSH_NONE) { - efx_flush_rx_queue(rx_queue); - ++rx_pending; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_queue->flushed == FLUSH_PENDING) + ++rx_pending; } } - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - ++tx_pending; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_pending == EFX_RX_FLUSH_COUNT) + break; + if (rx_queue->flushed == FLUSH_FAILED || + rx_queue->flushed == FLUSH_NONE) { + efx_flush_rx_queue(rx_queue); + ++rx_pending; + } + } + efx_for_each_channel_tx_queue(tx_queue, channel) { + if (tx_queue->flushed != FLUSH_DONE) + ++tx_pending; + } } if (rx_pending == 0 && tx_pending == 0) @@ -1261,19 +1272,21 @@ int efx_nic_flush_queues(struct efx_nic *efx) /* Mark the queues as all flushed. We're going to return failure * leading to a reset, or fake up success anyway */ - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - netif_err(efx, hw, efx->net_dev, - "tx queue %d flush command timed out\n", - tx_queue->queue); - tx_queue->flushed = FLUSH_DONE; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed != FLUSH_DONE) - netif_err(efx, hw, efx->net_dev, - "rx queue %d flush command timed out\n", - efx_rx_queue_index(rx_queue)); - rx_queue->flushed = FLUSH_DONE; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) { + if (tx_queue->flushed != FLUSH_DONE) + netif_err(efx, hw, efx->net_dev, + "tx queue %d flush command timed out\n", + tx_queue->queue); + tx_queue->flushed = FLUSH_DONE; + } + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_queue->flushed != FLUSH_DONE) + netif_err(efx, hw, efx->net_dev, + "rx queue %d flush command timed out\n", + efx_rx_queue_index(rx_queue)); + rx_queue->flushed = FLUSH_DONE; + } } return -ETIMEDOUT; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 1e6c8cfa6c0c..6651d9364e8f 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -311,7 +311,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; - struct efx_rx_queue *rx_queue = &efx->rx_queue[channel->channel]; + struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); struct efx_rx_buffer *new_buf; unsigned index; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 85f015f005d5..11153d99bc2b 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -567,7 +567,7 @@ static int efx_wait_for_link(struct efx_nic *efx) efx->type->monitor(efx); mutex_unlock(&efx->mac_lock); } else { - struct efx_channel *channel = &efx->channel[0]; + struct efx_channel *channel = efx_get_channel(efx, 0); if (channel->work_pending) efx_process_channel_now(channel); } @@ -594,6 +594,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, { enum efx_loopback_mode mode; struct efx_loopback_state *state; + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; int rc = 0; @@ -634,7 +635,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, } /* Test both types of TX queue */ - efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { + efx_for_each_channel_tx_queue(tx_queue, channel) { state->offload_csum = (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD); rc = efx_test_loopback(tx_queue, diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index c6942da2c99a..6a6acc47285c 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -37,8 +37,9 @@ void efx_stop_queue(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - if (!channel->tx_queue) + if (!tx_queue) return; spin_lock_bh(&channel->tx_stop_lock); @@ -46,9 +47,8 @@ void efx_stop_queue(struct efx_channel *channel) atomic_inc(&channel->tx_stop_count); netif_tx_stop_queue( - netdev_get_tx_queue( - efx->net_dev, - channel->tx_queue->queue / EFX_TXQ_TYPES)); + netdev_get_tx_queue(efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES)); spin_unlock_bh(&channel->tx_stop_lock); } @@ -57,8 +57,9 @@ void efx_stop_queue(struct efx_channel *channel) void efx_wake_queue(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - if (!channel->tx_queue) + if (!tx_queue) return; local_bh_disable(); @@ -66,9 +67,8 @@ void efx_wake_queue(struct efx_channel *channel) &channel->tx_stop_lock)) { netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n"); netif_tx_wake_queue( - netdev_get_tx_queue( - efx->net_dev, - channel->tx_queue->queue / EFX_TXQ_TYPES)); + netdev_get_tx_queue(efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES)); spin_unlock(&channel->tx_stop_lock); } local_bh_enable(); @@ -390,9 +390,9 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, if (unlikely(efx->port_inhibited)) return NETDEV_TX_BUSY; - tx_queue = &efx->tx_queue[EFX_TXQ_TYPES * skb_get_queue_mapping(skb)]; - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) - tx_queue += EFX_TXQ_TYPE_OFFLOAD; + tx_queue = efx_get_tx_queue(efx, skb_get_queue_mapping(skb), + skb->ip_summed == CHECKSUM_PARTIAL ? + EFX_TXQ_TYPE_OFFLOAD : 0); return efx_enqueue_skb(tx_queue, skb); } -- cgit v1.2.3 From 8313aca38b3937947fffebca6e34bac8e24300c8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:57 +0000 Subject: sfc: Allocate each channel separately, along with its RX and TX queues This will allow for reallocation of channel structures and rings. Change module parameter separate_tx_channels to be read-only, since we now require its value to be constant. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 61 ++++++++++++++++++++++++------------------- drivers/net/sfc/falcon.c | 14 +++------- drivers/net/sfc/net_driver.h | 62 ++++++++++++++++---------------------------- 3 files changed, 61 insertions(+), 76 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 3dd71aa310cd..4b42e61e3c7d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -114,7 +114,7 @@ static struct workqueue_struct *reset_workqueue; * This is only used in MSI-X interrupt mode */ static unsigned int separate_tx_channels; -module_param(separate_tx_channels, uint, 0644); +module_param(separate_tx_channels, uint, 0444); MODULE_PARM_DESC(separate_tx_channels, "Use separate channels for TX and RX"); @@ -334,6 +334,7 @@ void efx_process_channel_now(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + BUG_ON(channel->channel >= efx->n_channels); BUG_ON(!channel->enabled); /* Disable interrupts and wait for ISRs to complete */ @@ -1098,26 +1099,32 @@ static void efx_remove_interrupts(struct efx_nic *efx) efx->legacy_irq = 0; } +struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) +{ + unsigned tx_channel_offset = + separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; + EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || + type >= EFX_TXQ_TYPES); + return &efx->channel[tx_channel_offset + index]->tx_queue[type]; +} + static void efx_set_channels(struct efx_nic *efx) { struct efx_channel *channel; struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; unsigned tx_channel_offset = separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; + /* Channel pointers were set in efx_init_struct() but we now + * need to clear them for TX queues in any RX-only channels. */ efx_for_each_channel(channel, efx) { - if (channel->channel - tx_channel_offset < efx->n_tx_channels) { - channel->tx_queue = &efx->tx_queue[ - (channel->channel - tx_channel_offset) * - EFX_TXQ_TYPES]; + if (channel->channel - tx_channel_offset >= + efx->n_tx_channels) { efx_for_each_channel_tx_queue(tx_queue, channel) - tx_queue->channel = channel; + tx_queue->channel = NULL; } } - - efx_for_each_rx_queue(rx_queue, efx) - rx_queue->channel = &efx->channel[rx_queue->queue]; } static int efx_probe_nic(struct efx_nic *efx) @@ -2044,7 +2051,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; - int i; + int i, j; /* Initialise common structures */ memset(efx, 0, sizeof(*efx)); @@ -2072,27 +2079,22 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, INIT_WORK(&efx->mac_work, efx_mac_work); for (i = 0; i < EFX_MAX_CHANNELS; i++) { - channel = &efx->channel[i]; + efx->channel[i] = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = efx->channel[i]; channel->efx = efx; channel->channel = i; - channel->work_pending = false; spin_lock_init(&channel->tx_stop_lock); atomic_set(&channel->tx_stop_count, 1); - } - for (i = 0; i < EFX_MAX_TX_QUEUES; i++) { - tx_queue = &efx->tx_queue[i]; - tx_queue->efx = efx; - tx_queue->queue = i; - tx_queue->buffer = NULL; - tx_queue->channel = &efx->channel[0]; /* for safety */ - tx_queue->tso_headers_free = NULL; - } - for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { - rx_queue = &efx->rx_queue[i]; + + for (j = 0; j < EFX_TXQ_TYPES; j++) { + tx_queue = &channel->tx_queue[j]; + tx_queue->efx = efx; + tx_queue->queue = i * EFX_TXQ_TYPES + j; + tx_queue->channel = channel; + } + + rx_queue = &channel->rx_queue; rx_queue->efx = efx; - rx_queue->queue = i; - rx_queue->channel = &efx->channel[0]; /* for safety */ - rx_queue->buffer = NULL; setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, (unsigned long)rx_queue); } @@ -2120,6 +2122,11 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, static void efx_fini_struct(struct efx_nic *efx) { + int i; + + for (i = 0; i < EFX_MAX_CHANNELS; i++) + kfree(efx->channel[i]); + if (efx->workqueue) { destroy_workqueue(efx->workqueue); efx->workqueue = NULL; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 4f9d33f3cca1..b4d8efe67772 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -159,7 +159,6 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) { struct efx_nic *efx = dev_id; efx_oword_t *int_ker = efx->irq_status.addr; - struct efx_channel *channel; int syserr; int queues; @@ -194,15 +193,10 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) wmb(); /* Ensure the vector is cleared before interrupt ack */ falcon_irq_ack_a1(efx); - /* Schedule processing of any interrupting queues */ - channel = &efx->channel[0]; - while (queues) { - if (queues & 0x01) - efx_schedule_channel(channel); - channel++; - queues >>= 1; - } - + if (queues & 1) + efx_schedule_channel(efx_get_channel(efx, 0)); + if (queues & 2) + efx_schedule_channel(efx_get_channel(efx, 1)); return IRQ_HANDLED; } /************************************************************************** diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index eb3537529c9c..cfc65f5a3c09 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -225,8 +225,6 @@ struct efx_rx_page_state { /** * struct efx_rx_queue - An Efx RX queue * @efx: The associated Efx NIC - * @queue: DMA queue number - * @channel: The associated channel * @buffer: The software buffer ring * @rxd: The hardware descriptor ring * @added_count: Number of buffers added to the receive queue. @@ -250,8 +248,6 @@ struct efx_rx_page_state { */ struct efx_rx_queue { struct efx_nic *efx; - int queue; - struct efx_channel *channel; struct efx_rx_buffer *buffer; struct efx_special_buffer rxd; @@ -327,9 +323,10 @@ enum efx_rx_alloc_method { * @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun - * @tx_queue: Pointer to first TX queue, or %NULL if not used for TX + * @rx_queue: RX queue for this channel * @tx_stop_count: Core TX queue stop count * @tx_stop_lock: Core TX queue stop lock + * @tx_queue: TX queues for this channel */ struct efx_channel { struct efx_nic *efx; @@ -366,9 +363,12 @@ struct efx_channel { struct efx_rx_buffer *rx_pkt; bool rx_pkt_csummed; - struct efx_tx_queue *tx_queue; + struct efx_rx_queue rx_queue; + atomic_t tx_stop_count; spinlock_t tx_stop_lock; + + struct efx_tx_queue tx_queue[2]; }; enum efx_led_mode { @@ -724,9 +724,7 @@ struct efx_nic { enum nic_state state; enum reset_type reset_pending; - struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES]; - struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES]; - struct efx_channel channel[EFX_MAX_CHANNELS]; + struct efx_channel *channel[EFX_MAX_CHANNELS]; unsigned next_buffer_table; unsigned n_channels; @@ -913,34 +911,30 @@ static inline struct efx_channel * efx_get_channel(struct efx_nic *efx, unsigned index) { EFX_BUG_ON_PARANOID(index >= efx->n_channels); - return &efx->channel[index]; + return efx->channel[index]; } /* Iterate over all used channels */ #define efx_for_each_channel(_channel, _efx) \ - for (_channel = &((_efx)->channel[0]); \ - _channel < &((_efx)->channel[(efx)->n_channels]); \ - _channel++) + for (_channel = (_efx)->channel[0]; \ + _channel; \ + _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ + (_efx)->channel[_channel->channel + 1] : NULL) -static inline struct efx_tx_queue * -efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) -{ - EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || - type >= EFX_TXQ_TYPES); - return &efx->tx_queue[index * EFX_TXQ_TYPES + type]; -} +extern struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type); static inline struct efx_tx_queue * efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) { struct efx_tx_queue *tx_queue = channel->tx_queue; EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES); - return tx_queue ? tx_queue + type : NULL; + return tx_queue->channel ? tx_queue + type : NULL; } /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ - for (_tx_queue = (_channel)->tx_queue; \ + for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \ _tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ _tx_queue++) @@ -948,41 +942,31 @@ static inline struct efx_rx_queue * efx_get_rx_queue(struct efx_nic *efx, unsigned index) { EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels); - return &efx->rx_queue[index]; + return &efx->channel[index]->rx_queue; } -/* Iterate over all used RX queues */ -#define efx_for_each_rx_queue(_rx_queue, _efx) \ - for (_rx_queue = &((_efx)->rx_queue[0]); \ - _rx_queue < &((_efx)->rx_queue[(_efx)->n_rx_channels]); \ - _rx_queue++) - static inline struct efx_rx_queue * efx_channel_get_rx_queue(struct efx_channel *channel) { - struct efx_rx_queue *rx_queue = - &channel->efx->rx_queue[channel->channel]; - return rx_queue->channel == channel ? rx_queue : NULL; + return channel->channel < channel->efx->n_rx_channels ? + &channel->rx_queue : NULL; } /* Iterate over all RX queues belonging to a channel */ #define efx_for_each_channel_rx_queue(_rx_queue, _channel) \ - for (_rx_queue = &((_channel)->efx->rx_queue[(_channel)->channel]); \ + for (_rx_queue = efx_channel_get_rx_queue(channel); \ _rx_queue; \ - _rx_queue = NULL) \ - if (_rx_queue->channel != (_channel)) \ - continue; \ - else + _rx_queue = NULL) static inline struct efx_channel * efx_rx_queue_channel(struct efx_rx_queue *rx_queue) { - return rx_queue->channel; + return container_of(rx_queue, struct efx_channel, rx_queue); } static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue) { - return rx_queue->queue; + return efx_rx_queue_channel(rx_queue)->channel; } /* Returns a pointer to the specified receive buffer in the RX -- cgit v1.2.3 From ecc910f520ba8f22848982ee816ad75c449b805d Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Fri, 10 Sep 2010 06:42:22 +0000 Subject: sfc: Make the dmaq size a run-time setting (rather than compile-time) - Allow the ring size to be specified in non power-of-two sizes (for instance to limit the amount of receive buffers). - Automatically size the event queue. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 15 ++++++++---- drivers/net/sfc/efx.h | 13 +++++----- drivers/net/sfc/net_driver.h | 13 +++++++--- drivers/net/sfc/nic.c | 53 ++++++++++++++++++++++------------------- drivers/net/sfc/rx.c | 33 ++++++++++++++++---------- drivers/net/sfc/selftest.c | 2 +- drivers/net/sfc/tx.c | 56 ++++++++++++++++++++++++-------------------- 7 files changed, 109 insertions(+), 76 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 4b42e61e3c7d..6166e2207160 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -348,7 +348,7 @@ void efx_process_channel_now(struct efx_channel *channel) napi_disable(&channel->napi_str); /* Poll the channel */ - efx_process_channel(channel, EFX_EVQ_SIZE); + efx_process_channel(channel, channel->eventq_mask + 1); /* Ack the eventq. This may cause an interrupt to be generated * when they are reenabled */ @@ -365,9 +365,18 @@ void efx_process_channel_now(struct efx_channel *channel) */ static int efx_probe_eventq(struct efx_channel *channel) { + struct efx_nic *efx = channel->efx; + unsigned long entries; + netif_dbg(channel->efx, probe, channel->efx->net_dev, "chan %d create event queue\n", channel->channel); + /* Build an event queue with room for one event per tx and rx buffer, + * plus some extra for link state events and MCDI completions. */ + entries = roundup_pow_of_two(efx->rxq_entries + efx->txq_entries + 128); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_EVQ_SIZE); + channel->eventq_mask = max(entries, EFX_MIN_EVQ_SIZE) - 1; + return efx_nic_probe_eventq(channel); } @@ -1191,6 +1200,7 @@ static int efx_probe_all(struct efx_nic *efx) } /* Create channels */ + efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; efx_for_each_channel(channel, efx) { rc = efx_probe_channel(channel); if (rc) { @@ -2101,9 +2111,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->type = type; - /* As close as we can get to guaranteeing that we don't overflow */ - BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE); - EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS); /* Higher numbered interrupt modes are less capable! */ diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index d6b172b1a8ef..c15a2d3c2c23 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -37,8 +37,6 @@ efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); extern void efx_stop_queue(struct efx_channel *channel); extern void efx_wake_queue(struct efx_channel *channel); -#define EFX_TXQ_SIZE 1024 -#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1) /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); @@ -53,13 +51,16 @@ extern void __efx_rx_packet(struct efx_channel *channel, extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, bool checksummed, bool discard); extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); -#define EFX_RXQ_SIZE 1024 -#define EFX_RXQ_MASK (EFX_RXQ_SIZE - 1) + +#define EFX_MAX_DMAQ_SIZE 4096UL +#define EFX_DEFAULT_DMAQ_SIZE 1024UL +#define EFX_MIN_DMAQ_SIZE 512UL + +#define EFX_MAX_EVQ_SIZE 16384UL +#define EFX_MIN_EVQ_SIZE 512UL /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); -#define EFX_EVQ_SIZE 4096 -#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1) /* Ports */ extern int efx_reconfigure_port(struct efx_nic *efx); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index cfc65f5a3c09..ac622ab72e11 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -137,6 +137,7 @@ struct efx_tx_buffer { * @channel: The associated channel * @buffer: The software buffer ring * @txd: The hardware descriptor ring + * @ptr_mask: The size of the ring minus 1. * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. @@ -170,6 +171,7 @@ struct efx_tx_queue { struct efx_nic *nic; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; + unsigned int ptr_mask; enum efx_flush_state flushed; /* Members used mainly on the completion path */ @@ -227,6 +229,7 @@ struct efx_rx_page_state { * @efx: The associated Efx NIC * @buffer: The software buffer ring * @rxd: The hardware descriptor ring + * @ptr_mask: The size of the ring minus 1. * @added_count: Number of buffers added to the receive queue. * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. @@ -238,9 +241,6 @@ struct efx_rx_page_state { * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. - * @min_overfill: RX descriptor minimum overflow fill level. - * This records the minimum fill level at which RX queue - * overflow was observed. It should never be set. * @alloc_page_count: RX allocation strategy counter. * @alloc_skb_count: RX allocation strategy counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). @@ -250,6 +250,7 @@ struct efx_rx_queue { struct efx_nic *efx; struct efx_rx_buffer *buffer; struct efx_special_buffer rxd; + unsigned int ptr_mask; int added_count; int notified_count; @@ -307,6 +308,7 @@ enum efx_rx_alloc_method { * @reset_work: Scheduled reset work thread * @work_pending: Is work pending via NAPI? * @eventq: Event queue buffer + * @eventq_mask: Event queue pointer mask * @eventq_read_ptr: Event queue read pointer * @last_eventq_read_ptr: Last event queue read pointer value. * @magic_count: Event queue test event count @@ -339,6 +341,7 @@ struct efx_channel { struct napi_struct napi_str; bool work_pending; struct efx_special_buffer eventq; + unsigned int eventq_mask; unsigned int eventq_read_ptr; unsigned int last_eventq_read_ptr; unsigned int magic_count; @@ -641,6 +644,8 @@ union efx_multicast_hash { * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues * @channel: Channels + * @rxq_entries: Size of receive queues requested by user. + * @txq_entries: Size of transmit queues requested by user. * @next_buffer_table: First available buffer table id * @n_channels: Number of channels in use * @n_rx_channels: Number of channels used for RX (= number of RX queues) @@ -726,6 +731,8 @@ struct efx_nic { struct efx_channel *channel[EFX_MAX_CHANNELS]; + unsigned rxq_entries; + unsigned txq_entries; unsigned next_buffer_table; unsigned n_channels; unsigned n_rx_channels; diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 9e3563348eb7..0deb5c38efff 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -356,7 +356,7 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue) unsigned write_ptr; efx_dword_t reg; - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; + write_ptr = tx_queue->write_count & tx_queue->ptr_mask; EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); efx_writed_page(tx_queue->efx, ®, FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); @@ -377,7 +377,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) BUG_ON(tx_queue->write_count == tx_queue->insert_count); do { - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; + write_ptr = tx_queue->write_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[write_ptr]; txd = efx_tx_desc(tx_queue, write_ptr); ++tx_queue->write_count; @@ -398,10 +398,11 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; - BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 || - EFX_TXQ_SIZE & EFX_TXQ_MASK); + unsigned entries; + + entries = tx_queue->ptr_mask + 1; return efx_alloc_special_buffer(efx, &tx_queue->txd, - EFX_TXQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_tx(struct efx_tx_queue *tx_queue) @@ -526,30 +527,32 @@ efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index) */ void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue) { + struct efx_nic *efx = rx_queue->efx; efx_dword_t reg; unsigned write_ptr; while (rx_queue->notified_count != rx_queue->added_count) { - efx_build_rx_desc(rx_queue, - rx_queue->notified_count & - EFX_RXQ_MASK); + efx_build_rx_desc( + rx_queue, + rx_queue->notified_count & rx_queue->ptr_mask); ++rx_queue->notified_count; } wmb(); - write_ptr = rx_queue->added_count & EFX_RXQ_MASK; + write_ptr = rx_queue->added_count & rx_queue->ptr_mask; EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); - efx_writed_page(rx_queue->efx, ®, FR_AZ_RX_DESC_UPD_DWORD_P0, + efx_writed_page(efx, ®, FR_AZ_RX_DESC_UPD_DWORD_P0, efx_rx_queue_index(rx_queue)); } int efx_nic_probe_rx(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 || - EFX_RXQ_SIZE & EFX_RXQ_MASK); + unsigned entries; + + entries = rx_queue->ptr_mask + 1; return efx_alloc_special_buffer(efx, &rx_queue->rxd, - EFX_RXQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_rx(struct efx_rx_queue *rx_queue) @@ -685,7 +688,7 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) tx_queue = efx_channel_get_tx_queue( channel, tx_ev_q_label % EFX_TXQ_TYPES); tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) & - EFX_TXQ_MASK); + tx_queue->ptr_mask); channel->irq_mod_score += tx_packets; efx_xmit_done(tx_queue, tx_ev_desc_ptr); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { @@ -796,8 +799,8 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) struct efx_nic *efx = rx_queue->efx; unsigned expected, dropped; - expected = rx_queue->removed_count & EFX_RXQ_MASK; - dropped = (index - expected) & EFX_RXQ_MASK; + expected = rx_queue->removed_count & rx_queue->ptr_mask; + dropped = (index - expected) & rx_queue->ptr_mask; netif_info(efx, rx_err, efx->net_dev, "dropped %d events (index=%d expected=%d)\n", dropped, index, expected); @@ -835,7 +838,7 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) rx_queue = efx_channel_get_rx_queue(channel); rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); - expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; + expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask; if (unlikely(rx_ev_desc_ptr != expected_ptr)) efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); @@ -1002,6 +1005,7 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event) int efx_nic_process_eventq(struct efx_channel *channel, int budget) { + struct efx_nic *efx = channel->efx; unsigned int read_ptr; efx_qword_t event, *p_event; int ev_code; @@ -1026,7 +1030,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) EFX_SET_QWORD(*p_event); /* Increment read pointer */ - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; + read_ptr = (read_ptr + 1) & channel->eventq_mask; ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); @@ -1038,7 +1042,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) break; case FSE_AZ_EV_CODE_TX_EV: tx_packets += efx_handle_tx_event(channel, &event); - if (tx_packets >= EFX_TXQ_SIZE) { + if (tx_packets > efx->txq_entries) { spent = budget; goto out; } @@ -1073,10 +1077,11 @@ out: int efx_nic_probe_eventq(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; - BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 || - EFX_EVQ_SIZE & EFX_EVQ_MASK); + unsigned entries; + + entries = channel->eventq_mask + 1; return efx_alloc_special_buffer(efx, &channel->eventq, - EFX_EVQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_eventq(struct efx_channel *channel) @@ -1172,7 +1177,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; unsigned int read_ptr = channel->eventq_read_ptr; - unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK; + unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask; do { efx_qword_t *event = efx_event(channel, read_ptr); @@ -1212,7 +1217,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) * it's ok to throw away every non-flush event */ EFX_SET_QWORD(*event); - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; + read_ptr = (read_ptr + 1) & channel->eventq_mask; } while (read_ptr != end_ptr); channel->eventq_read_ptr = read_ptr; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 6651d9364e8f..6d0959b5158e 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -133,7 +133,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) unsigned index, count; for (count = 0; count < EFX_RX_BATCH; ++count) { - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->skb = netdev_alloc_skb(net_dev, skb_len); @@ -208,7 +208,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) dma_addr += sizeof(struct efx_rx_page_state); split: - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->skb = NULL; @@ -285,7 +285,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, * we'd like to insert an additional descriptor whilst leaving * EFX_RXD_HEAD_ROOM for the non-recycle path */ fill_level = (rx_queue->added_count - rx_queue->removed_count + 2); - if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) { + if (unlikely(fill_level > rx_queue->max_fill)) { /* We could place "state" on a list, and drain the list in * efx_fast_push_rx_descriptors(). For now, this will do. */ return; @@ -294,7 +294,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, ++state->refcnt; get_page(rx_buf->page); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->skb = NULL; @@ -319,7 +319,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, page_count(rx_buf->page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); memcpy(new_buf, rx_buf, sizeof(*new_buf)); @@ -347,7 +347,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) /* Calculate current fill level, and exit if we don't need to fill */ fill_level = (rx_queue->added_count - rx_queue->removed_count); - EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE); + EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); if (fill_level >= rx_queue->fast_fill_trigger) goto out; @@ -650,15 +650,22 @@ void efx_rx_strategy(struct efx_channel *channel) int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - unsigned int rxq_size; + unsigned int entries; int rc; + /* Create the smallest power-of-two aligned ring */ + entries = max(roundup_pow_of_two(efx->rxq_entries), EFX_MIN_DMAQ_SIZE); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE); + rx_queue->ptr_mask = entries - 1; + netif_dbg(efx, probe, efx->net_dev, - "creating RX queue %d\n", efx_rx_queue_index(rx_queue)); + "creating RX queue %d size %#x mask %#x\n", + efx_rx_queue_index(rx_queue), efx->rxq_entries, + rx_queue->ptr_mask); /* Allocate RX buffers */ - rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer); - rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL); + rx_queue->buffer = kzalloc(entries * sizeof(*rx_queue->buffer), + GFP_KERNEL); if (!rx_queue->buffer) return -ENOMEM; @@ -672,6 +679,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { + struct efx_nic *efx = rx_queue->efx; unsigned int max_fill, trigger, limit; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, @@ -682,10 +690,9 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) rx_queue->notified_count = 0; rx_queue->removed_count = 0; rx_queue->min_fill = -1U; - rx_queue->min_overfill = -1U; /* Initialise limit fields */ - max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM; + max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; limit = max_fill * min(rx_refill_limit, 100U) / 100U; @@ -710,7 +717,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) /* Release RX buffers NB start at index 0 not current HW ptr */ if (rx_queue->buffer) { - for (i = 0; i <= EFX_RXQ_MASK; i++) { + for (i = 0; i <= rx_queue->ptr_mask; i++) { rx_buf = efx_rx_buffer(rx_queue, i); efx_fini_rx_buffer(rx_queue, rx_buf); } diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 11153d99bc2b..da4473b71058 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -506,7 +506,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, for (i = 0; i < 3; i++) { /* Determine how many packets to send */ - state->packet_count = EFX_TXQ_SIZE / 3; + state->packet_count = efx->txq_entries / 3; state->packet_count = min(1 << (i << 2), state->packet_count); state->skbs = kzalloc(sizeof(state->skbs[0]) * state->packet_count, GFP_KERNEL); diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 6a6acc47285c..11726989fe2d 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -28,7 +28,7 @@ * The tx_queue descriptor ring fill-level must fall below this value * before we restart the netif queue */ -#define EFX_TXQ_THRESHOLD (EFX_TXQ_MASK / 2u) +#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u) /* We need to be able to nest calls to netif_tx_stop_queue(), partly * because of the 2 hardware queues associated with each core queue, @@ -207,7 +207,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) } fill_level = tx_queue->insert_count - tx_queue->old_read_count; - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; /* Map for DMA. Use pci_map_single rather than pci_map_page * since this is more efficient on machines with sparse @@ -244,14 +244,14 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) &tx_queue->read_count; fill_level = (tx_queue->insert_count - tx_queue->old_read_count); - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; if (unlikely(q_space-- <= 0)) goto stop; smp_mb(); --tx_queue->stopped; } - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->tsoh); @@ -320,7 +320,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; efx_dequeue_buffer(tx_queue, buffer); buffer->len = 0; @@ -350,8 +350,8 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, struct efx_nic *efx = tx_queue->efx; unsigned int stop_index, read_ptr; - stop_index = (index + 1) & EFX_TXQ_MASK; - read_ptr = tx_queue->read_count & EFX_TXQ_MASK; + stop_index = (index + 1) & tx_queue->ptr_mask; + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; while (read_ptr != stop_index) { struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr]; @@ -368,7 +368,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, buffer->len = 0; ++tx_queue->read_count; - read_ptr = tx_queue->read_count & EFX_TXQ_MASK; + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; } } @@ -402,7 +402,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) unsigned fill_level; struct efx_nic *efx = tx_queue->efx; - EFX_BUG_ON_PARANOID(index > EFX_TXQ_MASK); + EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); efx_dequeue_buffers(tx_queue, index); @@ -412,7 +412,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) smp_mb(); if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) { fill_level = tx_queue->insert_count - tx_queue->read_count; - if (fill_level < EFX_TXQ_THRESHOLD) { + if (fill_level < EFX_TXQ_THRESHOLD(efx)) { EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); /* Do this under netif_tx_lock(), to avoid racing @@ -430,18 +430,24 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; - unsigned int txq_size; + unsigned int entries; int i, rc; - netif_dbg(efx, probe, efx->net_dev, "creating TX queue %d\n", - tx_queue->queue); + /* Create the smallest power-of-two aligned ring */ + entries = max(roundup_pow_of_two(efx->txq_entries), EFX_MIN_DMAQ_SIZE); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE); + tx_queue->ptr_mask = entries - 1; + + netif_dbg(efx, probe, efx->net_dev, + "creating TX queue %d size %#x mask %#x\n", + tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask); /* Allocate software ring */ - txq_size = EFX_TXQ_SIZE * sizeof(*tx_queue->buffer); - tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL); + tx_queue->buffer = kzalloc(entries * sizeof(*tx_queue->buffer), + GFP_KERNEL); if (!tx_queue->buffer) return -ENOMEM; - for (i = 0; i <= EFX_TXQ_MASK; ++i) + for (i = 0; i <= tx_queue->ptr_mask; ++i) tx_queue->buffer[i].continuation = true; /* Allocate hardware ring */ @@ -481,7 +487,7 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue) /* Free any buffers left in the ring */ while (tx_queue->read_count != tx_queue->write_count) { - buffer = &tx_queue->buffer[tx_queue->read_count & EFX_TXQ_MASK]; + buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask]; efx_dequeue_buffer(tx_queue, buffer); buffer->continuation = true; buffer->len = 0; @@ -741,7 +747,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, fill_level = tx_queue->insert_count - tx_queue->old_read_count; /* -1 as there is no way to represent all descriptors used */ - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; while (1) { if (unlikely(q_space-- <= 0)) { @@ -757,7 +763,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, *(volatile unsigned *)&tx_queue->read_count; fill_level = (tx_queue->insert_count - tx_queue->old_read_count); - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; if (unlikely(q_space-- <= 0)) { *final_buffer = NULL; return 1; @@ -766,13 +772,13 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, --tx_queue->stopped; } - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; ++tx_queue->insert_count; EFX_BUG_ON_PARANOID(tx_queue->insert_count - - tx_queue->read_count > - EFX_TXQ_MASK); + tx_queue->read_count >= + efx->txq_entries); efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->len); @@ -813,7 +819,7 @@ static void efx_tso_put_header(struct efx_tx_queue *tx_queue, { struct efx_tx_buffer *buffer; - buffer = &tx_queue->buffer[tx_queue->insert_count & EFX_TXQ_MASK]; + buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->len); EFX_BUG_ON_PARANOID(buffer->unmap_len); @@ -838,7 +844,7 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; buffer = &tx_queue->buffer[tx_queue->insert_count & - EFX_TXQ_MASK]; + tx_queue->ptr_mask]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->skb); if (buffer->unmap_len) { @@ -1168,7 +1174,7 @@ static void efx_fini_tso(struct efx_tx_queue *tx_queue) unsigned i; if (tx_queue->buffer) { - for (i = 0; i <= EFX_TXQ_MASK; ++i) + for (i = 0; i <= tx_queue->ptr_mask; ++i) efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); } -- cgit v1.2.3 From 4642610c77b345130d6b5a08c75d23ad98601fd5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:42:33 +0000 Subject: sfc: Allow changing the DMA ring sizes dynamically via ethtool This requires some reorganisation of channel setup and teardown to ensure that we can always roll-back a failed change. Based on work by Steve Hodgson Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 218 ++++++++++++++++++++++++++++++++++--------- drivers/net/sfc/efx.h | 7 ++ drivers/net/sfc/ethtool.c | 38 ++++++++ drivers/net/sfc/net_driver.h | 4 +- drivers/net/sfc/nic.c | 9 +- 5 files changed, 224 insertions(+), 52 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 6166e2207160..f702f1fb63b6 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -201,10 +201,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); * Utility functions and prototypes * *************************************************************************/ -static void efx_remove_channel(struct efx_channel *channel); + +static void efx_remove_channels(struct efx_nic *efx); static void efx_remove_port(struct efx_nic *efx); static void efx_fini_napi(struct efx_nic *efx); -static void efx_fini_channels(struct efx_nic *efx); +static void efx_fini_struct(struct efx_nic *efx); +static void efx_start_all(struct efx_nic *efx); +static void efx_stop_all(struct efx_nic *efx); #define EFX_ASSERT_RESET_SERIALISED(efx) \ do { \ @@ -413,6 +416,63 @@ static void efx_remove_eventq(struct efx_channel *channel) * *************************************************************************/ +/* Allocate and initialise a channel structure, optionally copying + * parameters (but not resources) from an old channel structure. */ +static struct efx_channel * +efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) +{ + struct efx_channel *channel; + struct efx_rx_queue *rx_queue; + struct efx_tx_queue *tx_queue; + int j; + + if (old_channel) { + channel = kmalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) + return NULL; + + *channel = *old_channel; + + memset(&channel->eventq, 0, sizeof(channel->eventq)); + + rx_queue = &channel->rx_queue; + rx_queue->buffer = NULL; + memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd)); + + for (j = 0; j < EFX_TXQ_TYPES; j++) { + tx_queue = &channel->tx_queue[j]; + if (tx_queue->channel) + tx_queue->channel = channel; + tx_queue->buffer = NULL; + memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); + } + } else { + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) + return NULL; + + channel->efx = efx; + channel->channel = i; + + for (j = 0; j < EFX_TXQ_TYPES; j++) { + tx_queue = &channel->tx_queue[j]; + tx_queue->efx = efx; + tx_queue->queue = i * EFX_TXQ_TYPES + j; + tx_queue->channel = channel; + } + } + + spin_lock_init(&channel->tx_stop_lock); + atomic_set(&channel->tx_stop_count, 1); + + rx_queue = &channel->rx_queue; + rx_queue->efx = efx; + setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, + (unsigned long)rx_queue); + + return channel; +} + static int efx_probe_channel(struct efx_channel *channel) { struct efx_tx_queue *tx_queue; @@ -469,11 +529,38 @@ static void efx_set_channel_names(struct efx_nic *efx) number -= efx->n_rx_channels; } } - snprintf(channel->name, sizeof(channel->name), + snprintf(efx->channel_name[channel->channel], + sizeof(efx->channel_name[0]), "%s%s-%d", efx->name, type, number); } } +static int efx_probe_channels(struct efx_nic *efx) +{ + struct efx_channel *channel; + int rc; + + /* Restart special buffer allocation */ + efx->next_buffer_table = 0; + + efx_for_each_channel(channel, efx) { + rc = efx_probe_channel(channel); + if (rc) { + netif_err(efx, probe, efx->net_dev, + "failed to create channel %d\n", + channel->channel); + goto fail; + } + } + efx_set_channel_names(efx); + + return 0; + +fail: + efx_remove_channels(efx); + return rc; +} + /* Channels are shutdown and reinitialised whilst the NIC is running * to propagate configuration changes (mtu, checksum offload), or * to clear hardware error conditions @@ -611,6 +698,75 @@ static void efx_remove_channel(struct efx_channel *channel) efx_remove_eventq(channel); } +static void efx_remove_channels(struct efx_nic *efx) +{ + struct efx_channel *channel; + + efx_for_each_channel(channel, efx) + efx_remove_channel(channel); +} + +int +efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) +{ + struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel; + u32 old_rxq_entries, old_txq_entries; + unsigned i; + int rc; + + efx_stop_all(efx); + efx_fini_channels(efx); + + /* Clone channels */ + memset(other_channel, 0, sizeof(other_channel)); + for (i = 0; i < efx->n_channels; i++) { + channel = efx_alloc_channel(efx, i, efx->channel[i]); + if (!channel) { + rc = -ENOMEM; + goto out; + } + other_channel[i] = channel; + } + + /* Swap entry counts and channel pointers */ + old_rxq_entries = efx->rxq_entries; + old_txq_entries = efx->txq_entries; + efx->rxq_entries = rxq_entries; + efx->txq_entries = txq_entries; + for (i = 0; i < efx->n_channels; i++) { + channel = efx->channel[i]; + efx->channel[i] = other_channel[i]; + other_channel[i] = channel; + } + + rc = efx_probe_channels(efx); + if (rc) + goto rollback; + + /* Destroy old channels */ + for (i = 0; i < efx->n_channels; i++) + efx_remove_channel(other_channel[i]); +out: + /* Free unused channel structures */ + for (i = 0; i < efx->n_channels; i++) + kfree(other_channel[i]); + + efx_init_channels(efx); + efx_start_all(efx); + return rc; + +rollback: + /* Swap back */ + efx->rxq_entries = old_rxq_entries; + efx->txq_entries = old_txq_entries; + for (i = 0; i < efx->n_channels; i++) { + channel = efx->channel[i]; + efx->channel[i] = other_channel[i]; + other_channel[i] = channel; + } + goto out; +} + void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue) { mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100)); @@ -1182,41 +1338,28 @@ static void efx_remove_nic(struct efx_nic *efx) static int efx_probe_all(struct efx_nic *efx) { - struct efx_channel *channel; int rc; - /* Create NIC */ rc = efx_probe_nic(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to create NIC\n"); goto fail1; } - /* Create port */ rc = efx_probe_port(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to create port\n"); goto fail2; } - /* Create channels */ efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; - efx_for_each_channel(channel, efx) { - rc = efx_probe_channel(channel); - if (rc) { - netif_err(efx, probe, efx->net_dev, - "failed to create channel %d\n", - channel->channel); - goto fail3; - } - } - efx_set_channel_names(efx); + rc = efx_probe_channels(efx); + if (rc) + goto fail3; return 0; fail3: - efx_for_each_channel(channel, efx) - efx_remove_channel(channel); efx_remove_port(efx); fail2: efx_remove_nic(efx); @@ -1346,10 +1489,7 @@ static void efx_stop_all(struct efx_nic *efx) static void efx_remove_all(struct efx_nic *efx) { - struct efx_channel *channel; - - efx_for_each_channel(channel, efx) - efx_remove_channel(channel); + efx_remove_channels(efx); efx_remove_port(efx); efx_remove_nic(efx); } @@ -2058,10 +2198,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = { static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, struct pci_dev *pci_dev, struct net_device *net_dev) { - struct efx_channel *channel; - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; - int i, j; + int i; /* Initialise common structures */ memset(efx, 0, sizeof(*efx)); @@ -2089,24 +2226,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, INIT_WORK(&efx->mac_work, efx_mac_work); for (i = 0; i < EFX_MAX_CHANNELS; i++) { - efx->channel[i] = kzalloc(sizeof(*channel), GFP_KERNEL); - channel = efx->channel[i]; - channel->efx = efx; - channel->channel = i; - spin_lock_init(&channel->tx_stop_lock); - atomic_set(&channel->tx_stop_count, 1); - - for (j = 0; j < EFX_TXQ_TYPES; j++) { - tx_queue = &channel->tx_queue[j]; - tx_queue->efx = efx; - tx_queue->queue = i * EFX_TXQ_TYPES + j; - tx_queue->channel = channel; - } - - rx_queue = &channel->rx_queue; - rx_queue->efx = efx; - setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, - (unsigned long)rx_queue); + efx->channel[i] = efx_alloc_channel(efx, i, NULL); + if (!efx->channel[i]) + goto fail; } efx->type = type; @@ -2122,9 +2244,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, pci_name(pci_dev)); efx->workqueue = create_singlethread_workqueue(efx->workqueue_name); if (!efx->workqueue) - return -ENOMEM; + goto fail; return 0; + +fail: + efx_fini_struct(efx); + return -ENOMEM; } static void efx_fini_struct(struct efx_nic *efx) diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index c15a2d3c2c23..e783c0fedfd8 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -59,8 +59,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_EVQ_SIZE 16384UL #define EFX_MIN_EVQ_SIZE 512UL +/* The smallest [rt]xq_entries that the driver supports. Callers of + * efx_wake_queue() assume that they can subsequently send at least one + * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ +#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) + /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); +extern int +efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); /* Ports */ extern int efx_reconfigure_port(struct efx_nic *efx); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index b9291db023bb..7f735d804801 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -742,6 +742,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, return 0; } +static void efx_ethtool_get_ringparam(struct net_device *net_dev, + struct ethtool_ringparam *ring) +{ + struct efx_nic *efx = netdev_priv(net_dev); + + ring->rx_max_pending = EFX_MAX_DMAQ_SIZE; + ring->tx_max_pending = EFX_MAX_DMAQ_SIZE; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = efx->rxq_entries; + ring->tx_pending = efx->txq_entries; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; +} + +static int efx_ethtool_set_ringparam(struct net_device *net_dev, + struct ethtool_ringparam *ring) +{ + struct efx_nic *efx = netdev_priv(net_dev); + + if (ring->rx_mini_pending || ring->rx_jumbo_pending || + ring->rx_pending > EFX_MAX_DMAQ_SIZE || + ring->tx_pending > EFX_MAX_DMAQ_SIZE) + return -EINVAL; + + if (ring->rx_pending < EFX_MIN_RING_SIZE || + ring->tx_pending < EFX_MIN_RING_SIZE) { + netif_err(efx, drv, efx->net_dev, + "TX and RX queues cannot be smaller than %ld\n", + EFX_MIN_RING_SIZE); + return -EINVAL; + } + + return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); +} + static int efx_ethtool_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause) { @@ -972,6 +1008,8 @@ const struct ethtool_ops efx_ethtool_ops = { .set_eeprom = efx_ethtool_set_eeprom, .get_coalesce = efx_ethtool_get_coalesce, .set_coalesce = efx_ethtool_set_coalesce, + .get_ringparam = efx_ethtool_get_ringparam, + .set_ringparam = efx_ethtool_set_ringparam, .get_pauseparam = efx_ethtool_get_pauseparam, .set_pauseparam = efx_ethtool_set_pauseparam, .get_rx_csum = efx_ethtool_get_rx_csum, diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index ac622ab72e11..4b3f680ba69e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -299,7 +299,6 @@ enum efx_rx_alloc_method { * * @efx: Associated Efx NIC * @channel: Channel instance number - * @name: Name for channel and IRQ * @enabled: Channel enabled indicator * @irq: IRQ number (MSI and MSI-X only) * @irq_moderation: IRQ moderation value (in hardware ticks) @@ -333,7 +332,6 @@ enum efx_rx_alloc_method { struct efx_channel { struct efx_nic *efx; int channel; - char name[IFNAMSIZ + 6]; bool enabled; int irq; unsigned int irq_moderation; @@ -644,6 +642,7 @@ union efx_multicast_hash { * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues * @channel: Channels + * @channel_name: Names for channels and their IRQs * @rxq_entries: Size of receive queues requested by user. * @txq_entries: Size of transmit queues requested by user. * @next_buffer_table: First available buffer table id @@ -730,6 +729,7 @@ struct efx_nic { enum reset_type reset_pending; struct efx_channel *channel[EFX_MAX_CHANNELS]; + char channel_name[IFNAMSIZ + 6][EFX_MAX_CHANNELS]; unsigned rxq_entries; unsigned txq_entries; diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 0deb5c38efff..6c5c0cefa9d8 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1478,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) */ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) { - struct efx_channel *channel = dev_id; + struct efx_channel *channel = *(struct efx_channel **)dev_id; struct efx_nic *efx = channel->efx; efx_oword_t *int_ker = efx->irq_status.addr; int syserr; @@ -1553,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx) efx_for_each_channel(channel, efx) { rc = request_irq(channel->irq, efx_msi_interrupt, IRQF_PROBE_SHARED, /* Not shared */ - channel->name, channel); + efx->channel_name[channel->channel], + &efx->channel[channel->channel]); if (rc) { netif_err(efx, drv, efx->net_dev, "failed to hook IRQ %d\n", channel->irq); @@ -1565,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx) fail2: efx_for_each_channel(channel, efx) - free_irq(channel->irq, channel); + free_irq(channel->irq, &efx->channel[channel->channel]); fail1: return rc; } @@ -1578,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx) /* Disable MSI/MSI-X interrupts */ efx_for_each_channel(channel, efx) { if (channel->irq) - free_irq(channel->irq, channel); + free_irq(channel->irq, &efx->channel[channel->channel]); } /* ACK legacy interrupt */ -- cgit v1.2.3 From a034ee3cca5726b14107f281f4bed1c0fd44472a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 9 Sep 2010 23:32:28 +0000 Subject: fib: cleanups Use rcu_dereference_rtnl() helper Change hard coded constants in fib_flag_trans() 7 -> RTN_UNREACHABLE 8 -> RTN_PROHIBIT Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 55 ++++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4a8e370862bc..a96e5ec211a0 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -186,9 +186,7 @@ static inline struct tnode *node_parent_rcu(struct node *node) { struct tnode *ret = node_parent(node); - return rcu_dereference_check(ret, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(ret); } /* Same as rcu_assign_pointer @@ -211,9 +209,7 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) { struct node *ret = tnode_get_child(tn, i); - return rcu_dereference_check(ret, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(ret); } static inline int tnode_child_length(const struct tnode *tn) @@ -459,8 +455,8 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) tn->empty_children = 1<trie, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + n = rcu_dereference_rtnl(t->trie); while (n != NULL && NODE_TYPE(n) == T_TNODE) { tn = (struct tnode *) n; @@ -1748,16 +1741,14 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) /* Node empty, walk back up to parent */ c = (struct node *) p; - } while ( (p = node_parent_rcu(c)) != NULL); + } while ((p = node_parent_rcu(c)) != NULL); return NULL; /* Root of trie */ } static struct leaf *trie_firstleaf(struct trie *t) { - struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie); if (!n) return NULL; @@ -2043,14 +2034,14 @@ struct fib_trie_iter { struct seq_net_private p; struct fib_table *tb; struct tnode *tnode; - unsigned index; - unsigned depth; + unsigned int index; + unsigned int depth; }; static struct node *fib_trie_get_next(struct fib_trie_iter *iter) { struct tnode *tn = iter->tnode; - unsigned cindex = iter->index; + unsigned int cindex = iter->index; struct tnode *p; /* A single entry routing table */ @@ -2159,7 +2150,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s) */ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) { - unsigned i, max, pointers, bytes, avdepth; + unsigned int i, max, pointers, bytes, avdepth; if (stat->leaves) avdepth = stat->totdepth*100 / stat->leaves; @@ -2356,7 +2347,8 @@ static void fib_trie_seq_stop(struct seq_file *seq, void *v) static void seq_indent(struct seq_file *seq, int n) { - while (n-- > 0) seq_puts(seq, " "); + while (n-- > 0) + seq_puts(seq, " "); } static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s) @@ -2388,7 +2380,7 @@ static const char *const rtn_type_names[__RTN_MAX] = { [RTN_XRESOLVE] = "XRESOLVE", }; -static inline const char *rtn_type(char *buf, size_t len, unsigned t) +static inline const char *rtn_type(char *buf, size_t len, unsigned int t) { if (t < __RTN_MAX && rtn_type_names[t]) return rtn_type_names[t]; @@ -2544,13 +2536,12 @@ static void fib_route_seq_stop(struct seq_file *seq, void *v) rcu_read_unlock(); } -static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) +static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) { - static unsigned type2flags[RTN_MAX + 1] = { - [7] = RTF_REJECT, [8] = RTF_REJECT, - }; - unsigned flags = type2flags[type]; + unsigned int flags = 0; + if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT) + flags = RTF_REJECT; if (fi && fi->fib_nh->nh_gw) flags |= RTF_GATEWAY; if (mask == htonl(0xFFFFFFFF)) @@ -2562,7 +2553,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) /* * This outputs /proc/net/route. * The format of the file is not supposed to be changed - * and needs to be same as fib_hash output to avoid breaking + * and needs to be same as fib_hash output to avoid breaking * legacy utilities */ static int fib_route_seq_show(struct seq_file *seq, void *v) @@ -2587,7 +2578,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) list_for_each_entry_rcu(fa, &li->falh, fa_list) { const struct fib_info *fi = fa->fa_info; - unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); + unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi); int len; if (fa->fa_type == RTN_BROADCAST -- cgit v1.2.3 From 9ca7f8762299bb391c11a81c844224216e925b5c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 8 Sep 2010 09:16:28 +0000 Subject: pkt_sched: remov unnecessary bh_disable Now that est_tree_lock is acquired with BH protection, the other call is unnecessary. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/gen_estimator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 6743146e4d6b..7c2373321b74 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -274,9 +274,9 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, while ((e = gen_find_node(bstats, rate_est))) { rb_erase(&e->node, &est_root); - write_lock_bh(&est_lock); + write_lock(&est_lock); e->bstats = NULL; - write_unlock_bh(&est_lock); + write_unlock(&est_lock); list_del_rcu(&e->list); call_rcu(&e->e_rcu, __gen_kill_estimator); -- cgit v1.2.3 From cf6da94acb1e158c8efe0d184ac757829fbf9632 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 23 Aug 2010 14:00:54 -0700 Subject: iwlwifi: fix default LQ table in 5.2 band The default LQ is filled decreasingly using iwl_get_prev_ieee_rate from a starting rate. Since the starting rate is already the lowest one for a specific band it should be actually filled evenly with the starting rate: 1M and 6M for 5.2GHZ and 2.4GH respectively. The bug is that for for A or G-only it decreases to CCK rates which are not supported. iwl_get_prev_ieee_rate function is just not band aware. This affects broadcast station which lq table is not updated by rs algorithm G-only scenario is not treated by this patch iwl_get_prev_ieee_rate is removed completely as it is not used in other contexts Signed-off-by: Tomas Winkler Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 9 --------- drivers/net/wireless/iwlwifi/iwl-sta.c | 19 ++++++++----------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 3970ab1deaf9..357cdb26f16d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -453,15 +453,6 @@ static inline u8 first_antenna(u8 mask) } -static inline u8 iwl_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) { u8 rate = iwl3945_rates[rate_index].prev_ieee; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index ccd09027c7cd..6edd0341dfe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -386,7 +386,8 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv, { int i, r; struct iwl_link_quality_cmd *link_cmd; - u32 rate_flags; + u32 rate_flags = 0; + __le32 rate_n_flags; link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); if (!link_cmd) { @@ -400,18 +401,14 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv, else r = IWL_RATE_1M_INDEX; - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { - rate_flags = 0; - if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) - rate_flags |= RATE_MCS_CCK_MSK; + if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) + rate_flags |= RATE_MCS_CCK_MSK; - rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << + rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << RATE_MCS_ANT_POS; - - link_cmd->rs_table[i].rate_n_flags = - iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); - r = iwl_get_prev_ieee_rate(r); - } + rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) + link_cmd->rs_table[i].rate_n_flags = rate_n_flags; link_cmd->general_params.single_stream_ant_msk = first_antenna(priv->hw_params.valid_tx_ant); -- cgit v1.2.3 From 6e6ebf4befa75ebdf28130d0135f3ad3aadc02f8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 27 Aug 2010 10:41:37 -0700 Subject: iwlwifi: remember the last uCode sysassert error code When sysassert happen, uCode will report the error code, driver dump the information to dmesg. Here also remember the last error code for future reference. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c8a2ec802c8c..df2edccdf9bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1278,7 +1278,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -1459,7 +1458,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -2467,6 +2465,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) } desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); + priv->isr_stats.err_code = desc; pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32)); blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 0ee8f516c4ab..86017eda1f06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -575,10 +575,10 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file, priv->isr_stats.hw); pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", priv->isr_stats.sw); - if (priv->isr_stats.sw > 0) { + if (priv->isr_stats.sw || priv->isr_stats.hw) { pos += scnprintf(buf + pos, bufsz - pos, "\tLast Restarting Code: 0x%X\n", - priv->isr_stats.sw_err); + priv->isr_stats.err_code); } #ifdef CONFIG_IWLWIFI_DEBUG pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4dd38b7b8b74..504ff0f922d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -945,7 +945,7 @@ enum iwl_pa_type { struct isr_statistics { u32 hw; u32 sw; - u32 sw_err; + u32 err_code; u32 sch; u32 alive; u32 rfkill; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 68e624afb987..9c90be1ea0df 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1730,7 +1730,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " "Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } -- cgit v1.2.3 From 27eafdda7714d5b189c175e71ab22c72c90ba93e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 30 Aug 2010 06:12:00 -0700 Subject: iwlwifi: fix PAN parameters while scanning When only the PAN side was active, we gave no time to the WLAN context, which is OK unless we are scanning, which always happens on the WLAN context. Fix this. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 6fb52abafc8d..d03ba6a8e64a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -331,6 +331,11 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) * ctx_pan->vif->bss_conf.beacon_int; slot1 = max_t(int, 100, slot1); + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + slot0 = slot1 * 3 - 20; + slot1 = 20; + } } cmd.slots[0].width = cpu_to_le16(slot0); -- cgit v1.2.3 From 2a3aeb44f555b2b51bbe58792e8ab172a69172c5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 30 Aug 2010 06:13:42 -0700 Subject: iwlwifi: implement beacon interval change When the beacon interval needs to be changed, all we need to do is send updated timing to the device. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 87a2e40972ba..a76310311aab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1797,9 +1797,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, priv->ibss_beacon = ieee80211_beacon_get(hw, vif); } - if (changes & BSS_CHANGED_BEACON_INT) { - /* TODO: in AP mode, do something to make this take effect */ - } + if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) + iwl_send_rxon_timing(priv, ctx); if (changes & BSS_CHANGED_BSSID) { IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); -- cgit v1.2.3 From c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 1 Sep 2010 17:10:51 -0700 Subject: iwlwifi: allow configure protection mode Even driver use rts/cts protection mode for aggregation packets by default. Allow the protection mode to be configure through debugfs Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 86017eda1f06..e0b31a2a1dac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1604,6 +1604,44 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, return ret; } +static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + + int pos = 0; + char buf[40]; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", + (priv->cfg->use_rts_for_aggregation) ? "rts/cts" : + "cts-to-self"); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int rts; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &rts) != 1) + return -EINVAL; + if (rts) + priv->cfg->use_rts_for_aggregation = true; + else + priv->cfg->use_rts_for_aggregation = false; + return count; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1629,6 +1667,7 @@ DEBUGFS_WRITE_FILE_OPS(txfifo_flush); DEBUGFS_READ_FILE_OPS(ucode_bt_stats); DEBUGFS_WRITE_FILE_OPS(monitor_period); DEBUGFS_READ_FILE_OPS(bt_traffic); +DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); /* * Create the debugfs files and directories @@ -1689,6 +1728,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); if (priv->cfg->ops->lib->dev_txfifo_flush) DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); if (priv->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); -- cgit v1.2.3 From 763cc3bf5c2ae189a929fce54759c5bd94b8ba16 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Sep 2010 06:32:21 -0700 Subject: iwlwifi: avoid sending too many commands When the PAN context is unused, there's no need to continually update it in the device. So track which contexts are active (with the special case that the WLAN context is always active ...) and only send their commands to the device when needed. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +++++ drivers/net/wireless/iwlwifi/iwl-core.c | 13 ++++++++++++- drivers/net/wireless/iwlwifi/iwl-dev.h | 7 +++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index d03ba6a8e64a..a63582f060f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -287,6 +287,15 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; + /* + * If the PAN context is inactive, then we don't need + * to update the PAN parameters, the last thing we'll + * have done before it goes inactive is making the PAN + * parameters be WLAN-only. + */ + if (!ctx_pan->is_active) + return 0; + memset(&cmd, 0, sizeof(cmd)); /* only 2 slots are currently allowed */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index df2edccdf9bd..a19671d99248 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -110,6 +110,9 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (!iwl_is_alive(priv)) return -EBUSY; + if (!ctx->is_active) + return 0; + /* always get timestamp with Rx frame */ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; @@ -4301,6 +4304,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) for (i = 0; i < NUM_IWL_RXON_CTX; i++) priv->contexts[i].ctxid = i; + priv->contexts[IWL_RXON_CTX_BSS].always_active = true; + priv->contexts[IWL_RXON_CTX_BSS].is_active = true; priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a76310311aab..f67cab5bc6f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -196,6 +196,9 @@ static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; + if (!ctx->is_active) + return; + ctx->qos_data.def_qos_parm.qos_flags = 0; if (ctx->qos_data.qos_active) @@ -2008,9 +2011,14 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) */ priv->iw_mode = vif->type; + ctx->is_active = true; + err = iwl_set_mode(priv, vif); - if (err) + if (err) { + if (!ctx->always_active) + ctx->is_active = false; goto out_err; + } if (priv->cfg->advanced_bt_coexist && vif->type == NL80211_IFTYPE_ADHOC) { @@ -2052,6 +2060,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, iwl_scan_cancel_timeout(priv, 100); iwl_set_mode(priv, vif); + if (!ctx->always_active) + ctx->is_active = false; + if (priv->scan_vif == vif) { scan_completed = true; priv->scan_vif = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 504ff0f922d9..4e3a69271e34 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1116,6 +1116,13 @@ struct iwl_rxon_context { const u8 *ac_to_queue; u8 mcast_queue; + /* + * We could use the vif to indicate active, but we + * also need it to be active during disabling when + * we already removed the vif for type setting. + */ + bool always_active, is_active; + enum iwl_rxon_context_id ctxid; u32 interface_modes, exclusive_interface_modes; -- cgit v1.2.3 From f1f270b25c6ece9ff65f7ad970850338a198d52f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Sep 2010 06:31:26 -0700 Subject: iwlwifi: improve timing handling with dual-mode In dual-mode, a number of scenarios need to be considered, and the firmware can be very picky about them. Adjust the timing (most importantly the beacon interval) according to the different modes. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f67cab5bc6f2..c393b20ae1c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -529,10 +529,22 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ctx->timing.atim_window = 0; if (ctx->ctxid == IWL_RXON_CTX_PAN && - (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION)) { + (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) && + iwl_is_associated(priv, IWL_RXON_CTX_BSS) && + priv->contexts[IWL_RXON_CTX_BSS].vif && + priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) { ctx->timing.beacon_interval = priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval; beacon_int = le16_to_cpu(ctx->timing.beacon_interval); + } else if (ctx->ctxid == IWL_RXON_CTX_BSS && + iwl_is_associated(priv, IWL_RXON_CTX_PAN) && + priv->contexts[IWL_RXON_CTX_PAN].vif && + priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int && + (!iwl_is_associated_ctx(ctx) || !ctx->vif || + !ctx->vif->bss_conf.beacon_int)) { + ctx->timing.beacon_interval = + priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval; + beacon_int = le16_to_cpu(ctx->timing.beacon_interval); } else { beacon_int = iwl_adjust_beacon_interval(beacon_int, priv->hw_params.max_beacon_itrvl * TIME_UNIT); -- cgit v1.2.3 From ea196fdbb982150c19854f90773cb8b9bf331049 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 3 Sep 2010 06:30:55 -0700 Subject: iwlwifi: fix and describe iwl_adjust_beacon_interval The iwl_adjust_beacon_interval function is a bit of black magic, so add comments to it describing what it does. Also, in the case when there's no beacon interval set, program the default into the device (instead of adjusting, which results in the max) since using the max in that case interacts badly with dual-mode/PAN parameters. Also update the PAN parameters accordingly and use the same constant as here. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index a63582f060f1..d86902b83630 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -321,7 +321,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) bcnint = max_t(int, bcnint, ctx_bss->vif->bss_conf.beacon_int); if (!bcnint) - bcnint = 100; + bcnint = DEFAULT_BEACON_INTERVAL; slot0 = bcnint / 2; slot1 = bcnint - slot0; @@ -339,7 +339,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) slot0 = 0; slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) * ctx_pan->vif->bss_conf.beacon_int; - slot1 = max_t(int, 100, slot1); + slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); if (test_bit(STATUS_SCAN_HW, &priv->status)) { slot0 = slot1 * 3 - 20; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c393b20ae1c1..c9c523b2883f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -491,8 +491,29 @@ EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) { - u16 new_val = 0; - u16 beacon_factor = 0; + u16 new_val; + u16 beacon_factor; + + /* + * If mac80211 hasn't given us a beacon interval, program + * the default into the device (not checking this here + * would cause the adjustment below to return the maximum + * value, which may break PAN.) + */ + if (!beacon_val) + return DEFAULT_BEACON_INTERVAL; + + /* + * If the beacon interval we obtained from the peer + * is too large, we'll have to wake up more often + * (and in IBSS case, we'll beacon too much) + * + * For example, if max_beacon_val is 4096, and the + * requested beacon interval is 7000, we'll have to + * use 3500 to be able to wake up on the beacons. + * + * This could badly influence beacon detection stats. + */ beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val; new_val = beacon_val / beacon_factor; -- cgit v1.2.3 From 8f1d968721f9b3d4ff364bef0f33eb9697a6a7ee Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 3 Sep 2010 11:42:04 -0700 Subject: iwlwifi: make sure runtime calibration is enabled after association Clear the "start calib" flag only for new association, The flag will be set in post_associate function to trigger the runtime calibration. Set this flag to "0" will stop the runtime sensitivity calibration Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a19671d99248..36df9a7fcbcb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -226,9 +226,8 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return ret; } } - - priv->start_calib = 0; if (new_assoc) { + priv->start_calib = 0; /* Apply the new configuration * RXON assoc doesn't clear the station table in uCode, */ -- cgit v1.2.3 From 743e015dcbb428bf8454cf7d78272b4a76dd3c4b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 4 Sep 2010 09:00:14 -0700 Subject: iwlwifi: remove code repetition Move the duplicated code into single static function. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 60 ++++++++++++++---------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a8f2adfd799e..ec99a72edb76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -46,6 +46,28 @@ static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) tx_resp->frame_count) & MAX_SN; } +static void iwlagn_set_tx_status(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + struct iwl5000_tx_resp *tx_resp, + int txq_id, bool is_agg) +{ + u16 status = le16_to_cpu(tx_resp->status.status); + + info->status.rates[0].count = tx_resp->failure_frame + 1; + if (is_agg) + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= iwl_tx_status_to_mac80211(status); + iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), + info); + + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " + "0x%x retries %d\n", + txq_id, + iwl_get_tx_fail_reason(status), status, + le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); +} + static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, struct iwl5000_tx_resp *tx_resp, @@ -53,9 +75,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, { u16 status; struct agg_tx_status *frame_status = &tx_resp->status; - struct ieee80211_tx_info *info = NULL; struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); int i, sh, idx; u16 seq; @@ -64,31 +84,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, agg->frame_count = tx_resp->frame_count; agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); agg->bitmap = 0; /* # frames attempted by Tx command */ if (agg->frame_count == 1) { /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); idx = start_idx; - /* FIXME: code repetition */ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); - - /* FIXME: code repetition end */ - - IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", - status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); - + iwlagn_set_tx_status(priv, + IEEE80211_SKB_CB( + priv->txq[txq_id].txb[idx].skb), + tx_resp, txq_id, true); agg->wait_for_ba = 0; } else { /* Two or more frames were attempted; expect block-ack */ @@ -281,20 +290,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, } } else { BUG_ON(txq_id != txq->swq_id); - - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " - "0x%x retries %d\n", - txq_id, - iwl_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - + iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); -- cgit v1.2.3 From 0ea05ce7fd0c1286759933933764aacd12f6ac3a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Sep 2010 12:06:00 -0700 Subject: bna: Check for NULL before deref in bnad_cb_tx_cleanup Reported-by: Jiri Slaby Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 8158fb93cb4c..e380c0e88f4f 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -867,11 +867,12 @@ bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb) static void bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) { - struct bnad_unmap_q *unmap_q = tcb->unmap_q; + struct bnad_unmap_q *unmap_q; if (!tcb || (!tcb->unmap_q)) return; + unmap_q = tcb->unmap_q; if (!unmap_q->unmap_array) return; -- cgit v1.2.3 From efbc2d7cfa67a9753cd45eb7eee8c9ad10c8b74c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 13 Sep 2010 04:14:49 +0000 Subject: sfc: Fix order of channel_name array dimensions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 4b3f680ba69e..152342dbff29 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -729,7 +729,7 @@ struct efx_nic { enum reset_type reset_pending; struct efx_channel *channel[EFX_MAX_CHANNELS]; - char channel_name[IFNAMSIZ + 6][EFX_MAX_CHANNELS]; + char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; unsigned rxq_entries; unsigned txq_entries; -- cgit v1.2.3 From 83b6b1f5d13414d0cb5c4f0a567a6aec0af073bd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 10 Sep 2010 07:00:25 +0000 Subject: flow: better memory management Allocate hash tables for every online cpus, not every possible ones. NUMA aware allocations. Dont use a full page on arches where PAGE_SIZE > 1024*sizeof(void *) misc: __percpu , __read_mostly, __cpuinit annotations flow_compare_t is just an "unsigned long" Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/flow.c | 78 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/net/core/flow.c b/net/core/flow.c index f67dcbfe54ef..b143b86b1f2a 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -53,8 +53,7 @@ struct flow_flush_info { struct flow_cache { u32 hash_shift; - unsigned long order; - struct flow_cache_percpu *percpu; + struct flow_cache_percpu __percpu *percpu; struct notifier_block hotcpu_notifier; int low_watermark; int high_watermark; @@ -64,7 +63,7 @@ struct flow_cache { atomic_t flow_cache_genid = ATOMIC_INIT(0); EXPORT_SYMBOL(flow_cache_genid); static struct flow_cache flow_cache_global; -static struct kmem_cache *flow_cachep; +static struct kmem_cache *flow_cachep __read_mostly; static DEFINE_SPINLOCK(flow_cache_gc_lock); static LIST_HEAD(flow_cache_gc_list); @@ -181,11 +180,7 @@ static u32 flow_hash_code(struct flow_cache *fc, & (flow_cache_hash_size(fc) - 1)); } -#if (BITS_PER_LONG == 64) -typedef u64 flow_compare_t; -#else -typedef u32 flow_compare_t; -#endif +typedef unsigned long flow_compare_t; /* I hear what you're saying, use memcmp. But memcmp cannot make * important assumptions that we can here, such as alignment and @@ -357,62 +352,73 @@ void flow_cache_flush(void) put_online_cpus(); } -static void __init flow_cache_cpu_prepare(struct flow_cache *fc, - struct flow_cache_percpu *fcp) +static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu) { - fcp->hash_table = (struct hlist_head *) - __get_free_pages(GFP_KERNEL|__GFP_ZERO, fc->order); - if (!fcp->hash_table) - panic("NET: failed to allocate flow cache order %lu\n", fc->order); + struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); + size_t sz = sizeof(struct hlist_head) * flow_cache_hash_size(fc); - fcp->hash_rnd_recalc = 1; - fcp->hash_count = 0; - tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0); + if (!fcp->hash_table) { + fcp->hash_table = kzalloc_node(sz, GFP_KERNEL, cpu_to_node(cpu)); + if (!fcp->hash_table) { + pr_err("NET: failed to allocate flow cache sz %zu\n", sz); + return -ENOMEM; + } + fcp->hash_rnd_recalc = 1; + fcp->hash_count = 0; + tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0); + } + return 0; } -static int flow_cache_cpu(struct notifier_block *nfb, +static int __cpuinit flow_cache_cpu(struct notifier_block *nfb, unsigned long action, void *hcpu) { struct flow_cache *fc = container_of(nfb, struct flow_cache, hotcpu_notifier); - int cpu = (unsigned long) hcpu; + int res, cpu = (unsigned long) hcpu; struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); - if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + res = flow_cache_cpu_prepare(fc, cpu); + if (res) + return notifier_from_errno(res); + break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: __flow_cache_shrink(fc, fcp, 0); + break; + } return NOTIFY_OK; } -static int flow_cache_init(struct flow_cache *fc) +static int __init flow_cache_init(struct flow_cache *fc) { - unsigned long order; int i; fc->hash_shift = 10; fc->low_watermark = 2 * flow_cache_hash_size(fc); fc->high_watermark = 4 * flow_cache_hash_size(fc); - for (order = 0; - (PAGE_SIZE << order) < - (sizeof(struct hlist_head)*flow_cache_hash_size(fc)); - order++) - /* NOTHING */; - fc->order = order; fc->percpu = alloc_percpu(struct flow_cache_percpu); + if (!fc->percpu) + return -ENOMEM; - setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd, - (unsigned long) fc); - fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; - add_timer(&fc->rnd_timer); - - for_each_possible_cpu(i) - flow_cache_cpu_prepare(fc, per_cpu_ptr(fc->percpu, i)); - + for_each_online_cpu(i) { + if (flow_cache_cpu_prepare(fc, i)) + return -ENOMEM; + } fc->hotcpu_notifier = (struct notifier_block){ .notifier_call = flow_cache_cpu, }; register_hotcpu_notifier(&fc->hotcpu_notifier); + setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd, + (unsigned long) fc); + fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; + add_timer(&fc->rnd_timer); + return 0; } -- cgit v1.2.3 From 61a21455ee27dccdd286f61aea611da5e70b47bf Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Fri, 10 Sep 2010 23:23:13 +0000 Subject: sundance: Add power management hooks This patch to adds support for PM hooks into sundance driver Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 3fa949789b42..7dfdbee878e8 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1757,11 +1757,59 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev) } } +#ifdef CONFIG_PM + +static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + + if (!netif_running(dev)) + return 0; + + netdev_close(dev); + netif_device_detach(dev); + + pci_save_state(pci_dev); + pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); + + return 0; +} + +static int sundance_resume(struct pci_dev *pci_dev) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + int err = 0; + + if (!netif_running(dev)) + return 0; + + pci_set_power_state(pci_dev, PCI_D0); + pci_restore_state(pci_dev); + + err = netdev_open(dev); + if (err) { + printk(KERN_ERR "%s: Can't resume interface!\n", + dev->name); + goto out; + } + + netif_device_attach(dev); + +out: + return err; +} + +#endif /* CONFIG_PM */ + static struct pci_driver sundance_driver = { .name = DRV_NAME, .id_table = sundance_pci_tbl, .probe = sundance_probe1, .remove = __devexit_p(sundance_remove1), +#ifdef CONFIG_PM + .suspend = sundance_suspend, + .resume = sundance_resume, +#endif /* CONFIG_PM */ }; static int __init sundance_init(void) -- cgit v1.2.3 From 1570475a477b46cb16b2a0dd73c06974c8d2b550 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 11 Sep 2010 01:08:58 +0000 Subject: net/de4x5: remove undefined operations Modifying an object twice without an intervening sequence point is undefined. Signed-off-by: Andreas Schwab Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 75a64c88cf7a..4f7503063446 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1448,7 +1448,7 @@ de4x5_sw_reset(struct net_device *dev) status = -EIO; } - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; lp->tx_old = lp->tx_new; return status; @@ -1506,7 +1506,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) lp->stats.tx_bytes += skb->len; outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */ - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; if (TX_BUFFS_AVAIL) { netif_start_queue(dev); /* Another pkt may be queued */ @@ -1657,7 +1657,7 @@ de4x5_rx(struct net_device *dev) } /* Change buffer ownership for this frame, back to the adapter */ - for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) { + for (;lp->rx_old!=entry;lp->rx_old=(lp->rx_old + 1)%lp->rxRingSize) { lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN); barrier(); } @@ -1668,7 +1668,7 @@ de4x5_rx(struct net_device *dev) /* ** Update entry information */ - lp->rx_new = (++lp->rx_new) % lp->rxRingSize; + lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize; } return 0; @@ -1726,7 +1726,7 @@ de4x5_tx(struct net_device *dev) } /* Update all the pointers */ - lp->tx_old = (++lp->tx_old) % lp->txRingSize; + lp->tx_old = (lp->tx_old + 1) % lp->txRingSize; } /* Any resources available? */ @@ -1801,7 +1801,7 @@ de4x5_rx_ovfc(struct net_device *dev) for (; (s32)le32_to_cpu(lp->rx_ring[lp->rx_new].status)>=0;) { lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN); - lp->rx_new = (++lp->rx_new % lp->rxRingSize); + lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize; } outl(omr, DE4X5_OMR); @@ -1932,7 +1932,7 @@ set_multicast_list(struct net_device *dev) load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | SETUP_FRAME_LEN, (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ dev->trans_start = jiffies; /* prevent tx timeout */ } @@ -3568,7 +3568,7 @@ ping_media(struct net_device *dev, int msec) lp->tmp = lp->tx_new; /* Remember the ring position */ load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); } @@ -5417,7 +5417,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Set up the descriptor and give ownership to the card */ load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | SETUP_FRAME_LEN, (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ netif_wake_queue(dev); /* Unlock the TX ring */ break; -- cgit v1.2.3 From 70ce679be6f7fd8ff24d4b7007e2c0e430587945 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 11 Sep 2010 01:12:34 +0000 Subject: net/cxgb3: remove undefined operations Modifying an object twice without an intervening sequence point is undefined. Signed-off-by: Andreas Schwab Signed-off-by: David S. Miller --- drivers/net/cxgb3/t3_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index d307c9de59fb..421d5589cecd 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -3683,7 +3683,7 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7, mc7->name = name; mc7->offset = base_addr - MC7_PMRX_BASE_ADDR; cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); - mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg); + mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg); mc7->width = G_WIDTH(cfg); } -- cgit v1.2.3 From d81e27cf4e2a5050245f9962539292ea2c9e2206 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 11 Sep 2010 19:10:56 +0000 Subject: drivers/net/skfp: Remove pr_ uses of KERN_ Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/skfp/skfddi.c | 84 +++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 31b2dabf094c..8a12bd9d28ba 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -209,7 +209,7 @@ static int skfp_init_one(struct pci_dev *pdev, void __iomem *mem; int err; - pr_debug(KERN_INFO "entering skfp_init_one\n"); + pr_debug("entering skfp_init_one\n"); if (num_boards == 0) printk("%s\n", boot_msg); @@ -385,7 +385,7 @@ static int skfp_driver_init(struct net_device *dev) skfddi_priv *bp = &smc->os; int err = -EIO; - pr_debug(KERN_INFO "entering skfp_driver_init\n"); + pr_debug("entering skfp_driver_init\n"); // set the io address in private structures bp->base_addr = dev->base_addr; @@ -405,7 +405,7 @@ static int skfp_driver_init(struct net_device *dev) // Determine the required size of the 'shared' memory area. bp->SharedMemSize = mac_drv_check_space(); - pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize); + pr_debug("Memory for HWM: %ld\n", bp->SharedMemSize); if (bp->SharedMemSize > 0) { bp->SharedMemSize += 16; // for descriptor alignment @@ -429,13 +429,13 @@ static int skfp_driver_init(struct net_device *dev) card_stop(smc); // Reset adapter. - pr_debug(KERN_INFO "mac_drv_init()..\n"); + pr_debug("mac_drv_init()..\n"); if (mac_drv_init(smc) != 0) { - pr_debug(KERN_INFO "mac_drv_init() failed.\n"); + pr_debug("mac_drv_init() failed\n"); goto fail; } read_address(smc, NULL); - pr_debug(KERN_INFO "HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a); + pr_debug("HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a); memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6); smt_reset_defaults(smc, 0); @@ -485,7 +485,7 @@ static int skfp_open(struct net_device *dev) struct s_smc *smc = netdev_priv(dev); int err; - pr_debug(KERN_INFO "entering skfp_open\n"); + pr_debug("entering skfp_open\n"); /* Register IRQ - support shared interrupts by passing device ptr */ err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED, dev->name, dev); @@ -856,12 +856,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) /* Enable promiscuous mode, if necessary */ if (dev->flags & IFF_PROMISC) { mac_drv_rx_mode(smc, RX_ENABLE_PROMISC); - pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n"); + pr_debug("PROMISCUOUS MODE ENABLED\n"); } /* Else, update multicast address table */ else { mac_drv_rx_mode(smc, RX_DISABLE_PROMISC); - pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n"); + pr_debug("PROMISCUOUS MODE DISABLED\n"); // Reset all MC addresses mac_clear_multicast(smc); @@ -869,7 +869,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) { mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI); - pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n"); + pr_debug("ENABLE ALL MC ADDRESSES\n"); } else if (!netdev_mc_empty(dev)) { if (netdev_mc_count(dev) <= FPMAX_MULTICAST) { /* use exact filtering */ @@ -880,18 +880,18 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) (struct fddi_addr *)ha->addr, 1); - pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n", - ha->addr); + pr_debug("ENABLE MC ADDRESS: %pMF\n", + ha->addr); } } else { // more MC addresses than HW supports mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI); - pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n"); + pr_debug("ENABLE ALL MC ADDRESSES\n"); } } else { // no MC addresses - pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n"); + pr_debug("DISABLE ALL MC ADDRESSES\n"); } /* Update adapter filters */ @@ -1045,7 +1045,7 @@ static netdev_tx_t skfp_send_pkt(struct sk_buff *skb, struct s_smc *smc = netdev_priv(dev); skfddi_priv *bp = &smc->os; - pr_debug(KERN_INFO "skfp_send_pkt\n"); + pr_debug("skfp_send_pkt\n"); /* * Verify that incoming transmit request is OK @@ -1114,13 +1114,13 @@ static void send_queued_packets(struct s_smc *smc) int frame_status; // HWM tx frame status. - pr_debug(KERN_INFO "send queued packets\n"); + pr_debug("send queued packets\n"); for (;;) { // send first buffer from queue skb = skb_dequeue(&bp->SendSkbQueue); if (!skb) { - pr_debug(KERN_INFO "queue empty\n"); + pr_debug("queue empty\n"); return; } // queue empty ! @@ -1232,7 +1232,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr) static void ResetAdapter(struct s_smc *smc) { - pr_debug(KERN_INFO "[fddi: ResetAdapter]\n"); + pr_debug("[fddi: ResetAdapter]\n"); // Stop the adapter. @@ -1278,7 +1278,7 @@ void llc_restart_tx(struct s_smc *smc) { skfddi_priv *bp = &smc->os; - pr_debug(KERN_INFO "[llc_restart_tx]\n"); + pr_debug("[llc_restart_tx]\n"); // Try to send queued packets spin_unlock(&bp->DriverLock); @@ -1308,7 +1308,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) { void *virt; - pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size); + pr_debug("mac_drv_get_space (%d bytes), ", size); virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap); if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) { @@ -1317,9 +1317,9 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) } smc->os.SharedMemHeap += size; // Move heap pointer. - pr_debug(KERN_INFO "mac_drv_get_space end\n"); - pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt); - pr_debug(KERN_INFO "bus addr: %lx\n", (ulong) + pr_debug("mac_drv_get_space end\n"); + pr_debug("virt addr: %lx\n", (ulong) virt); + pr_debug("bus addr: %lx\n", (ulong) (smc->os.SharedMemDMA + ((char *) virt - (char *)smc->os.SharedMemAddr))); return (virt); @@ -1349,7 +1349,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) char *virt; - pr_debug(KERN_INFO "mac_drv_get_desc_mem\n"); + pr_debug("mac_drv_get_desc_mem\n"); // Descriptor memory must be aligned on 16-byte boundary. @@ -1493,7 +1493,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) { struct sk_buff *skb; - pr_debug(KERN_INFO "entering mac_drv_tx_complete\n"); + pr_debug("entering mac_drv_tx_complete\n"); // Check if this TxD points to a skb if (!(skb = txd->txd_os.skb)) { @@ -1513,7 +1513,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) // free the skb dev_kfree_skb_irq(skb); - pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n"); + pr_debug("leaving mac_drv_tx_complete\n"); } // mac_drv_tx_complete @@ -1580,7 +1580,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, unsigned short ri; u_int RifLength; - pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len); + pr_debug("entering mac_drv_rx_complete (len=%d)\n", len); if (frag_count != 1) { // This is not allowed to happen. printk("fddi: Multi-fragment receive!\n"); @@ -1589,7 +1589,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, } skb = rxd->rxd_os.skb; if (!skb) { - pr_debug(KERN_INFO "No skb in rxd\n"); + pr_debug("No skb in rxd\n"); smc->os.MacStat.gen.rx_errors++; goto RequeueRxd; } @@ -1619,7 +1619,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, else { int n; // goos: RIF removal has still to be tested - pr_debug(KERN_INFO "RIF found\n"); + pr_debug("RIF found\n"); // Get RIF length from Routing Control (RC) field. cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header. @@ -1664,7 +1664,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, return; RequeueRxd: - pr_debug(KERN_INFO "Rx: re-queue RXD.\n"); + pr_debug("Rx: re-queue RXD.\n"); mac_drv_requeue_rxd(smc, rxd, frag_count); smc->os.MacStat.gen.rx_errors++; // Count receive packets // not indicated. @@ -1775,7 +1775,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) struct sk_buff *skb; volatile struct s_smt_fp_rxd *rxd; - pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n"); + pr_debug("entering mac_drv_fill_rxd\n"); // Walk through the list of free receive buffers, passing receive // buffers to the HWM as long as RXDs are available. @@ -1783,7 +1783,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) MaxFrameSize = smc->os.MaxFrameSize; // Check if there is any RXD left. while (HWM_GET_RX_FREE(smc) > 0) { - pr_debug(KERN_INFO ".\n"); + pr_debug(".\n"); rxd = HWM_GET_CURR_RXD(smc); skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC); @@ -1814,7 +1814,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize, FIRST_FRAG | LAST_FRAG); } - pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n"); + pr_debug("leaving mac_drv_fill_rxd\n"); } // mac_drv_fill_rxd @@ -2034,17 +2034,17 @@ void smt_stat_counter(struct s_smc *smc, int stat) { // BOOLEAN RingIsUp ; - pr_debug(KERN_INFO "smt_stat_counter\n"); + pr_debug("smt_stat_counter\n"); switch (stat) { case 0: - pr_debug(KERN_INFO "Ring operational change.\n"); + pr_debug("Ring operational change.\n"); break; case 1: - pr_debug(KERN_INFO "Receive fifo overflow.\n"); + pr_debug("Receive fifo overflow.\n"); smc->os.MacStat.gen.rx_errors++; break; default: - pr_debug(KERN_INFO "Unknown status (%d).\n", stat); + pr_debug("Unknown status (%d).\n", stat); break; } } // smt_stat_counter @@ -2100,10 +2100,10 @@ void cfm_state_change(struct s_smc *smc, int c_state) s = "SC11_C_WRAP_S"; break; default: - pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state); + pr_debug("cfm_state_change: unknown %d\n", c_state); return; } - pr_debug(KERN_INFO "cfm_state_change: %s\n", s); + pr_debug("cfm_state_change: %s\n", s); #endif // DRIVERDEBUG } // cfm_state_change @@ -2158,7 +2158,7 @@ void ecm_state_change(struct s_smc *smc, int e_state) s = "unknown"; break; } - pr_debug(KERN_INFO "ecm_state_change: %s\n", s); + pr_debug("ecm_state_change: %s\n", s); #endif //DRIVERDEBUG } // ecm_state_change @@ -2213,7 +2213,7 @@ void rmt_state_change(struct s_smc *smc, int r_state) s = "unknown"; break; } - pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s); + pr_debug("[rmt_state_change: %s]\n", s); #endif // DRIVERDEBUG } // rmt_state_change @@ -2233,7 +2233,7 @@ void rmt_state_change(struct s_smc *smc, int r_state) ************************/ void drv_reset_indication(struct s_smc *smc) { - pr_debug(KERN_INFO "entering drv_reset_indication\n"); + pr_debug("entering drv_reset_indication\n"); smc->os.ResetRequested = TRUE; // Set flag. -- cgit v1.2.3 From 7dbfdc2390afc4e244817ab26d5a1b987b0c0669 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 11 Sep 2010 05:39:57 +0000 Subject: cx82310_eth: check usb_string() return value for error Fix that usb_string() return value is not checked for error (negative value). Also change the ignore message a bit and lower its level to info. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/usb/cx82310_eth.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c index 6fbe03276b27..4d451789ea7c 100644 --- a/drivers/net/usb/cx82310_eth.c +++ b/drivers/net/usb/cx82310_eth.c @@ -138,11 +138,9 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) struct usb_device *udev = dev->udev; /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ - if (udev->descriptor.iProduct && - usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) && - strcmp(buf, "USB NET CARD")) { - dev_err(&udev->dev, - "probably an ADSL modem, use cxacru driver instead\n"); + if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0 + && strcmp(buf, "USB NET CARD")) { + dev_info(&udev->dev, "ignoring: probably an ADSL modem\n"); return -ENODEV; } -- cgit v1.2.3 From 441993da47777d961300c070fe1210600af48ad8 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 11 Sep 2010 05:40:16 +0000 Subject: cx82310_eth: allow empty URBs Empty received URBs are currently counted as errors but the device sends them sometimes as part of regular traffic - so remove this check. Signed-off-by: Ondrej Zary Signed-off-by: David S. Miller --- drivers/net/usb/cx82310_eth.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c index 4d451789ea7c..8969f124c18c 100644 --- a/drivers/net/usb/cx82310_eth.c +++ b/drivers/net/usb/cx82310_eth.c @@ -150,11 +150,11 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) /* * this must not include ethernet header as the device can send partial - * packets with no header (URB is at least 2 bytes long, so 2 is OK) + * packets with no header (and sometimes even empty URBs) */ - dev->net->hard_header_len = 2; + dev->net->hard_header_len = 0; /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */ - dev->hard_mtu = CX82310_MTU + dev->net->hard_header_len; + dev->hard_mtu = CX82310_MTU + 2; /* we can receive URBs up to 4KB from the device */ dev->rx_urb_size = 4096; @@ -228,12 +228,6 @@ static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 1; } - if (skb->len < 2) { - dev_err(&dev->udev->dev, "RX frame too short: %d B\n", - skb->len); - return 0; - } - /* a skb can contain multiple packets */ while (skb->len > 1) { /* first two bytes are packet length */ -- cgit v1.2.3 From 251415808306a19be93ec93268e2985f10d3db8b Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 12 Sep 2010 05:48:28 +0000 Subject: bnx2x: Spread rx buffers between allocated queues Default number of rx buffers will be divided equally between allocated queues. This will decrease amount of pre-allocated buffers on systems with multiple CPUs. User can override this behavior with ethtool -G. Minimum amount of rx buffers per queue set to 128. Reported-by: Eric Dumazet Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 5 +++-- drivers/net/bnx2x/bnx2x_cmn.c | 6 +++++- drivers/net/bnx2x/bnx2x_ethtool.c | 10 +++++++++- drivers/net/bnx2x/bnx2x_main.c | 1 - 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index b6aaf22a1b84..64329c5fbdea 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-6" -#define DRV_MODULE_RELDATE "2010/09/07" +#define DRV_MODULE_VERSION "1.52.53-7" +#define DRV_MODULE_RELDATE "2010/09/12" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -369,6 +369,7 @@ struct bnx2x_fastpath { #define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) +#define MIN_RX_AVAIL 128 #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 7f1d291eaaa5..efc7be4aefb5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -781,6 +781,10 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) ETH_MAX_AGGREGATION_QUEUES_E1H; u16 ring_prod, cqe_ring_prod; int i, j; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; DP(NETIF_MSG_IFUP, @@ -883,7 +887,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) /* Allocate BDs and initialize BD ring */ fp->rx_comp_cons = 0; cqe_ring_prod = ring_prod = 0; - for (i = 0; i < bp->rx_ring_size; i++) { + for (i = 0; i < rx_ring_size; i++) { if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { BNX2X_ERR("was only able to allocate " "%d rx skbs on queue[%d]\n", i, j); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 6f939c5a0089..d9748e97fad3 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -961,7 +961,14 @@ static void bnx2x_get_ringparam(struct net_device *dev, ering->rx_mini_max_pending = 0; ering->rx_jumbo_max_pending = 0; - ering->rx_pending = bp->rx_ring_size; + if (bp->rx_ring_size) + ering->rx_pending = bp->rx_ring_size; + else + if (bp->state == BNX2X_STATE_OPEN && bp->num_queues) + ering->rx_pending = MAX_RX_AVAIL/bp->num_queues; + else + ering->rx_pending = MAX_RX_AVAIL; + ering->rx_mini_pending = 0; ering->rx_jumbo_pending = 0; @@ -981,6 +988,7 @@ static int bnx2x_set_ringparam(struct net_device *dev, } if ((ering->rx_pending > MAX_RX_AVAIL) || + (ering->rx_pending < MIN_RX_AVAIL) || (ering->tx_pending > MAX_TX_AVAIL) || (ering->tx_pending <= MAX_SKB_FRAGS + 4)) return -EINVAL; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7ba3a6d96fd5..67587fe9e358 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6619,7 +6619,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->mrrs = mrrs; bp->tx_ring_size = MAX_TX_AVAIL; - bp->rx_ring_size = MAX_RX_AVAIL; bp->rx_csum = 1; -- cgit v1.2.3 From bc0ed0be10a4925efa7b81a84af53f12fbdbcb4e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sun, 12 Sep 2010 08:16:26 +0000 Subject: uwb: use '%pM' format to print MAC address Signed-off-by: Andy Shevchenko Signed-off-by: David S. Miller --- drivers/uwb/address.c | 5 +---- drivers/uwb/wlp/wss-lc.c | 7 ++----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c index 973321327c44..8739c4f4d015 100644 --- a/drivers/uwb/address.c +++ b/drivers/uwb/address.c @@ -363,10 +363,7 @@ size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr, { size_t result; if (type) - result = scnprintf(buf, buf_size, - "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); + result = scnprintf(buf, buf_size, "%pM", addr); else result = scnprintf(buf, buf_size, "%02x:%02x", addr[1], addr[0]); diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c index a005d2a03b5d..67872c83b679 100644 --- a/drivers/uwb/wlp/wss-lc.c +++ b/drivers/uwb/wlp/wss-lc.c @@ -791,11 +791,8 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry, } else { if (printk_ratelimit()) dev_err(dev, "WLP: Destination neighbor (Ethernet: " - "%02x:%02x:%02x:%02x:%02x:%02x, Dev: " - "%02x:%02x) is not connected. \n", eth_addr[0], - eth_addr[1], eth_addr[2], eth_addr[3], - eth_addr[4], eth_addr[5], dev_addr->data[1], - dev_addr->data[0]); + "%pM, Dev: %02x:%02x) is not connected.\n", + eth_addr, dev_addr->data[1], dev_addr->data[0]); result = -EINVAL; } return result; -- cgit v1.2.3 From fe8ee9ad80b28382111f0aab01690b09982e5691 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 00:48:55 +0200 Subject: carl9170: mac80211 glue and command interface Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 626 +++++++++ drivers/net/wireless/ath/carl9170/cmd.c | 188 +++ drivers/net/wireless/ath/carl9170/cmd.h | 158 +++ drivers/net/wireless/ath/carl9170/led.c | 190 +++ drivers/net/wireless/ath/carl9170/main.c | 1855 ++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/version.h | 7 + 6 files changed, 3024 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/carl9170.h create mode 100644 drivers/net/wireless/ath/carl9170/cmd.c create mode 100644 drivers/net/wireless/ath/carl9170/cmd.h create mode 100644 drivers/net/wireless/ath/carl9170/led.c create mode 100644 drivers/net/wireless/ath/carl9170/main.c create mode 100644 drivers/net/wireless/ath/carl9170/version.h diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h new file mode 100644 index 000000000000..9f1d60359061 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -0,0 +1,626 @@ +/* + * Atheros CARL9170 driver + * + * Driver specific definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CARL9170_H +#define __CARL9170_H + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CARL9170_LEDS +#include +#endif /* CONFIG_CARL170_LEDS */ +#ifdef CONFIG_CARL9170_WPC +#include +#endif /* CONFIG_CARL9170_WPC */ +#include "eeprom.h" +#include "wlan.h" +#include "hw.h" +#include "fwdesc.h" +#include "fwcmd.h" +#include "../regd.h" + +#ifdef CONFIG_CARL9170_DEBUGFS +#include "debug.h" +#endif /* CONFIG_CARL9170_DEBUGFS */ + +#define CARL9170FW_NAME "carl9170-1.fw" + +#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) + +enum carl9170_rf_init_mode { + CARL9170_RFI_NONE, + CARL9170_RFI_WARM, + CARL9170_RFI_COLD, +}; + +#define CARL9170_MAX_RX_BUFFER_SIZE 8192 + +enum carl9170_device_state { + CARL9170_UNKNOWN_STATE, + CARL9170_STOPPED, + CARL9170_IDLE, + CARL9170_STARTED, +}; + +#define CARL9170_NUM_TID 16 +#define WME_BA_BMP_SIZE 64 +#define CARL9170_TX_USER_RATE_TRIES 3 + +#define WME_AC_BE 2 +#define WME_AC_BK 3 +#define WME_AC_VI 1 +#define WME_AC_VO 0 + +#define TID_TO_WME_AC(_tid) \ + ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ + (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ + (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ + WME_AC_VO) + +#define SEQ_DIFF(_start, _seq) \ + (((_start) - (_seq)) & 0x0fff) +#define SEQ_PREV(_seq) \ + (((_seq) - 1) & 0x0fff) +#define SEQ_NEXT(_seq) \ + (((_seq) + 1) & 0x0fff) +#define BAW_WITHIN(_start, _bawsz, _seqno) \ + ((((_seqno) - (_start)) & 0xfff) < (_bawsz)) + +enum carl9170_tid_state { + CARL9170_TID_STATE_INVALID, + CARL9170_TID_STATE_KILLED, + CARL9170_TID_STATE_SHUTDOWN, + CARL9170_TID_STATE_SUSPEND, + CARL9170_TID_STATE_PROGRESS, + CARL9170_TID_STATE_IDLE, + CARL9170_TID_STATE_XMIT, +}; + +#define CARL9170_BAW_BITS (2 * WME_BA_BMP_SIZE) +#define CARL9170_BAW_SIZE (BITS_TO_LONGS(CARL9170_BAW_BITS)) +#define CARL9170_BAW_LEN (DIV_ROUND_UP(CARL9170_BAW_BITS, BITS_PER_BYTE)) + +struct carl9170_sta_tid { + /* must be the first entry! */ + struct list_head list; + + /* temporary list for RCU unlink procedure */ + struct list_head tmp_list; + + /* lock for the following data structures */ + spinlock_t lock; + + unsigned int counter; + enum carl9170_tid_state state; + u8 tid; /* TID number ( 0 - 15 ) */ + u16 max; /* max. AMPDU size */ + + u16 snx; /* awaiting _next_ frame */ + u16 hsn; /* highest _queued_ sequence */ + u16 bsn; /* base of the tx/agg bitmap */ + unsigned long bitmap[CARL9170_BAW_SIZE]; + + /* Preaggregation reorder queue */ + struct sk_buff_head queue; +}; + +#define CARL9170_QUEUE_TIMEOUT 256 +#define CARL9170_BUMP_QUEUE 1000 +#define CARL9170_TX_TIMEOUT 2500 +#define CARL9170_JANITOR_DELAY 128 +#define CARL9170_QUEUE_STUCK_TIMEOUT 5500 + +#define CARL9170_NUM_TX_AGG_MAX 30 + +/* + * Tradeoff between stability/latency and speed. + * + * AR9170_TXQ_DEPTH is devised by dividing the amount of available + * tx buffers with the size of a full ethernet frame + overhead. + * + * Naturally: The higher the limit, the faster the device CAN send. + * However, even a slight over-commitment at the wrong time and the + * hardware is doomed to send all already-queued frames at suboptimal + * rates. This in turn leads to an enourmous amount of unsuccessful + * retries => Latency goes up, whereas the throughput goes down. CRASH! + */ +#define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2) +#define CARL9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH) + +struct carl9170_tx_queue_stats { + unsigned int count; + unsigned int limit; + unsigned int len; +}; + +struct carl9170_vif { + unsigned int id; + struct ieee80211_vif *vif; +}; + +struct carl9170_vif_info { + struct list_head list; + bool active; + unsigned int id; + struct sk_buff *beacon; + bool enable_beacon; +}; + +#define AR9170_NUM_RX_URBS 16 +#define AR9170_NUM_RX_URBS_MUL 2 +#define AR9170_NUM_TX_URBS 8 +#define AR9170_NUM_RX_URBS_POOL (AR9170_NUM_RX_URBS_MUL * AR9170_NUM_RX_URBS) + +enum carl9170_device_features { + CARL9170_WPS_BUTTON = BIT(0), + CARL9170_ONE_LED = BIT(1), +}; + +#ifdef CONFIG_CARL9170_LEDS +struct ar9170; + +struct carl9170_led { + struct ar9170 *ar; + struct led_classdev l; + char name[32]; + unsigned int toggled; + bool last_state; + bool registered; +}; +#endif /* CONFIG_CARL9170_LEDS */ + +enum carl9170_restart_reasons { + CARL9170_RR_NO_REASON = 0, + CARL9170_RR_FATAL_FIRMWARE_ERROR, + CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, + CARL9170_RR_WATCHDOG, + CARL9170_RR_STUCK_TX, + CARL9170_RR_SLOW_SYSTEM, + CARL9170_RR_COMMAND_TIMEOUT, + CARL9170_RR_TOO_MANY_PHY_ERRORS, + CARL9170_RR_LOST_RSP, + CARL9170_RR_INVALID_RSP, + CARL9170_RR_USER_REQUEST, + + __CARL9170_RR_LAST, +}; + +enum carl9170_erp_modes { + CARL9170_ERP_INVALID, + CARL9170_ERP_AUTO, + CARL9170_ERP_MAC80211, + CARL9170_ERP_OFF, + CARL9170_ERP_CTS, + CARL9170_ERP_RTS, + __CARL9170_ERP_NUM, +}; + +struct ar9170 { + struct ath_common common; + struct ieee80211_hw *hw; + struct mutex mutex; + enum carl9170_device_state state; + spinlock_t state_lock; + enum carl9170_restart_reasons last_reason; + bool registered; + + /* USB */ + struct usb_device *udev; + struct usb_interface *intf; + struct usb_anchor rx_anch; + struct usb_anchor rx_work; + struct usb_anchor rx_pool; + struct usb_anchor tx_wait; + struct usb_anchor tx_anch; + struct usb_anchor tx_cmd; + struct usb_anchor tx_err; + struct tasklet_struct usb_tasklet; + atomic_t tx_cmd_urbs; + atomic_t tx_anch_urbs; + atomic_t rx_anch_urbs; + atomic_t rx_work_urbs; + atomic_t rx_pool_urbs; + kernel_ulong_t features; + + /* firmware settings */ + struct completion fw_load_wait; + struct completion fw_boot_wait; + struct { + const struct carl9170fw_desc_head *desc; + const struct firmware *fw; + unsigned int offset; + unsigned int address; + unsigned int cmd_bufs; + unsigned int api_version; + unsigned int vif_num; + unsigned int err_counter; + unsigned int bug_counter; + u32 beacon_addr; + unsigned int beacon_max_len; + bool rx_stream; + bool tx_stream; + unsigned int mem_blocks; + unsigned int mem_block_size; + unsigned int rx_size; + } fw; + + /* reset / stuck frames/queue detection */ + struct work_struct restart_work; + unsigned int restart_counter; + unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; + unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; + bool needs_full_reset; + atomic_t pending_restarts; + + /* interface mode settings */ + struct list_head vif_list; + unsigned long vif_bitmap; + unsigned int vifs; + struct carl9170_vif vif_priv[AR9170_MAX_VIRTUAL_MAC]; + + /* beaconing */ + spinlock_t beacon_lock; + unsigned int global_pretbtt; + unsigned int global_beacon_int; + struct carl9170_vif_info *beacon_iter; + unsigned int beacon_enabled; + + /* cryptographic engine */ + u64 usedkeys; + bool rx_software_decryption; + bool disable_offload; + + /* filter settings */ + u64 cur_mc_hash; + u32 cur_filter; + unsigned int filter_state; + bool sniffer_enabled; + + /* MAC */ + enum carl9170_erp_modes erp_mode; + + /* PHY */ + struct ieee80211_channel *channel; + int noise[6]; + unsigned int chan_fail; + unsigned int total_chan_fail; + u8 heavy_clip; + + /* power calibration data */ + u8 power_5G_leg[4]; + u8 power_2G_cck[4]; + u8 power_2G_ofdm[4]; + u8 power_5G_ht20[8]; + u8 power_5G_ht40[8]; + u8 power_2G_ht20[8]; + u8 power_2G_ht40[8]; + +#ifdef CONFIG_CARL9170_LEDS + /* LED */ + struct delayed_work led_work; + struct carl9170_led leds[AR9170_NUM_LEDS]; +#endif /* CONFIG_CARL9170_LEDS */ + + /* qos queue settings */ + spinlock_t tx_stats_lock; + struct carl9170_tx_queue_stats tx_stats[__AR9170_NUM_TXQ]; + struct ieee80211_tx_queue_params edcf[5]; + struct completion tx_flush; + + /* CMD */ + int cmd_seq; + int readlen; + u8 *readbuf; + spinlock_t cmd_lock; + struct completion cmd_wait; + union { + __le32 cmd_buf[PAYLOAD_MAX + 1]; + struct carl9170_cmd cmd; + struct carl9170_rsp rsp; + }; + + /* statistics */ + unsigned int tx_dropped; + unsigned int tx_ack_failures; + unsigned int tx_fcs_errors; + unsigned int tx_ampdu_timeout; + unsigned int rx_dropped; + + /* EEPROM */ + struct ar9170_eeprom eeprom; + + /* tx queuing */ + struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; + struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; + struct delayed_work tx_janitor; + unsigned long tx_janitor_last_run; + bool tx_schedule; + + /* tx ampdu */ + struct work_struct ampdu_work; + spinlock_t tx_ampdu_list_lock; + struct carl9170_sta_tid *tx_ampdu_iter; + struct list_head tx_ampdu_list; + atomic_t tx_ampdu_upload; + atomic_t tx_ampdu_scheduler; + atomic_t tx_total_pending; + atomic_t tx_total_queued; + unsigned int tx_ampdu_list_len; + int current_density; + int current_factor; + bool tx_ampdu_schedule; + + /* internal memory management */ + spinlock_t mem_lock; + unsigned long *mem_bitmap; + atomic_t mem_free_blocks; + atomic_t mem_allocs; + + /* rxstream mpdu merge */ + struct ar9170_rx_head rx_plcp; + bool rx_has_plcp; + struct sk_buff *rx_failover; + int rx_failover_missing; + +#ifdef CONFIG_CARL9170_WPC + struct { + bool pbc_state; + struct input_dev *pbc; + char name[32]; + char phys[32]; + } wps; +#endif /* CONFIG_CARL9170_WPC */ + +#ifdef CONFIG_CARL9170_DEBUGFS + struct carl9170_debug debug; + struct dentry *debug_dir; +#endif /* CONFIG_CARL9170_DEBUGFS */ + + /* PSM */ + struct work_struct ps_work; + struct { + unsigned int dtim_counter; + unsigned long last_beacon; + unsigned long last_action; + unsigned long last_slept; + unsigned int sleep_ms; + unsigned int off_override; + bool state; + } ps; +}; + +enum carl9170_ps_off_override_reasons { + PS_OFF_VIF = BIT(0), + PS_OFF_BCN = BIT(1), + PS_OFF_5GHZ = BIT(2), +}; + +struct carl9170_ba_stats { + u8 ampdu_len; + u8 ampdu_ack_len; + bool clear; +}; + +struct carl9170_sta_info { + bool ht_sta; + unsigned int ampdu_max_len; + struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; + struct carl9170_ba_stats stats[CARL9170_NUM_TID]; +}; + +struct carl9170_tx_info { + unsigned long timeout; + struct ar9170 *ar; + struct kref ref; +}; + +#define CHK_DEV_STATE(a, s) (((struct ar9170 *)a)->state >= (s)) +#define IS_INITIALIZED(a) (CHK_DEV_STATE(a, CARL9170_STOPPED)) +#define IS_ACCEPTING_CMD(a) (CHK_DEV_STATE(a, CARL9170_IDLE)) +#define IS_STARTED(a) (CHK_DEV_STATE(a, CARL9170_STARTED)) + +static inline void __carl9170_set_state(struct ar9170 *ar, + enum carl9170_device_state newstate) +{ + ar->state = newstate; +} + +static inline void carl9170_set_state(struct ar9170 *ar, + enum carl9170_device_state newstate) +{ + unsigned long flags; + + spin_lock_irqsave(&ar->state_lock, flags); + __carl9170_set_state(ar, newstate); + spin_unlock_irqrestore(&ar->state_lock, flags); +} + +static inline void carl9170_set_state_when(struct ar9170 *ar, + enum carl9170_device_state min, enum carl9170_device_state newstate) +{ + unsigned long flags; + + spin_lock_irqsave(&ar->state_lock, flags); + if (CHK_DEV_STATE(ar, min)) + __carl9170_set_state(ar, newstate); + spin_unlock_irqrestore(&ar->state_lock, flags); +} + +/* exported interface */ +void *carl9170_alloc(size_t priv_size); +int carl9170_register(struct ar9170 *ar); +void carl9170_unregister(struct ar9170 *ar); +void carl9170_free(struct ar9170 *ar); +void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r); +void carl9170_ps_check(struct ar9170 *ar); + +/* USB back-end */ +int carl9170_usb_open(struct ar9170 *ar); +void carl9170_usb_stop(struct ar9170 *ar); +void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_usb_handle_tx_err(struct ar9170 *ar); +int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids, + u32 plen, void *payload, u32 rlen, void *resp); +int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, + const bool free_buf); +int carl9170_usb_restart(struct ar9170 *ar); +void carl9170_usb_reset(struct ar9170 *ar); + +/* MAC */ +int carl9170_init_mac(struct ar9170 *ar); +int carl9170_set_qos(struct ar9170 *ar); +int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); +int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, + const u8 *mac); +int carl9170_set_operating_mode(struct ar9170 *ar); +int carl9170_set_beacon_timers(struct ar9170 *ar); +int carl9170_set_dyn_sifs_ack(struct ar9170 *ar); +int carl9170_set_rts_cts_rate(struct ar9170 *ar); +int carl9170_set_ampdu_settings(struct ar9170 *ar); +int carl9170_set_slot_time(struct ar9170 *ar); +int carl9170_set_mac_rates(struct ar9170 *ar); +int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); +int carl9170_update_beacon(struct ar9170 *ar, const bool submit); +int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, + const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); +int carl9170_disable_key(struct ar9170 *ar, const u8 id); + +/* RX */ +void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); +void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); + +/* TX */ +int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void carl9170_tx_janitor(struct work_struct *work); +void carl9170_tx_process_status(struct ar9170 *ar, + const struct carl9170_rsp *cmd); +void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, + const bool success); +void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_tx_scheduler(struct ar9170 *ar); +void carl9170_tx_get_skb(struct sk_buff *skb); +int carl9170_tx_put_skb(struct sk_buff *skb); + +/* LEDs */ +#ifdef CONFIG_CARL9170_LEDS +int carl9170_led_register(struct ar9170 *ar); +void carl9170_led_unregister(struct ar9170 *ar); +#endif /* CONFIG_CARL9170_LEDS */ +int carl9170_led_init(struct ar9170 *ar); +int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state); + +/* PHY / RF */ +int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, + enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi); +int carl9170_get_noisefloor(struct ar9170 *ar); + +/* FW */ +int carl9170_parse_firmware(struct ar9170 *ar); +int carl9170_fw_fix_eeprom(struct ar9170 *ar); + +extern struct ieee80211_rate __carl9170_ratetable[]; +extern int modparam_noht; + +static inline struct ar9170 *carl9170_get_priv(struct carl9170_vif *carl_vif) +{ + return container_of(carl_vif, struct ar9170, + vif_priv[carl_vif->id]); +} + +static inline struct ieee80211_hdr *carl9170_get_hdr(struct sk_buff *skb) +{ + return (void *)((struct _carl9170_tx_superframe *) + skb->data)->frame_data; +} + +static inline u16 get_seq_h(struct ieee80211_hdr *hdr) +{ + return le16_to_cpu(hdr->seq_ctrl) >> 4; +} + +static inline u16 carl9170_get_seq(struct sk_buff *skb) +{ + return get_seq_h(carl9170_get_hdr(skb)); +} + +static inline u16 get_tid_h(struct ieee80211_hdr *hdr) +{ + return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; +} + +static inline u16 carl9170_get_tid(struct sk_buff *skb) +{ + return get_tid_h(carl9170_get_hdr(skb)); +} + +static inline struct ieee80211_vif * +carl9170_get_vif(struct carl9170_vif_info *priv) +{ + return container_of((void *)priv, struct ieee80211_vif, drv_priv); +} + +/* Protected by ar->mutex or RCU */ +static inline struct ieee80211_vif *carl9170_get_main_vif(struct ar9170 *ar) +{ + struct carl9170_vif_info *cvif; + + list_for_each_entry_rcu(cvif, &ar->vif_list, list) { + if (cvif->active) + return carl9170_get_vif(cvif); + } + + return NULL; +} + +static inline bool is_main_vif(struct ar9170 *ar, struct ieee80211_vif *vif) +{ + bool ret; + + rcu_read_lock(); + ret = (carl9170_get_main_vif(ar) == vif); + rcu_read_unlock(); + return ret; +} + +#endif /* __CARL9170_H */ diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c new file mode 100644 index 000000000000..c21f3364bfec --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -0,0 +1,188 @@ +/* + * Atheros CARL9170 driver + * + * Basic HW register/memory/command access functions + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) +{ + __le32 buf[2] = { + cpu_to_le32(reg), + cpu_to_le32(val), + }; + int err; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf), + (u8 *) buf, 0, NULL); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "writing reg %#x " + "(val %#x) failed (%d)\n", reg, val, err); + } + } + return err; +} + +int carl9170_read_mreg(struct ar9170 *ar, const int nregs, + const u32 *regs, u32 *out) +{ + int i, err; + __le32 *offs, *res; + + /* abuse "out" for the register offsets, must be same length */ + offs = (__le32 *)out; + for (i = 0; i < nregs; i++) + offs[i] = cpu_to_le32(regs[i]); + + /* also use the same buffer for the input */ + res = (__le32 *)out; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, + 4 * nregs, (u8 *)offs, + 4 * nregs, (u8 *)res); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n", + err); + } + return err; + } + + /* convert result to cpu endian */ + for (i = 0; i < nregs; i++) + out[i] = le32_to_cpu(res[i]); + + return 0; +} + +int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) +{ + return carl9170_read_mreg(ar, 1, ®, val); +} + +int carl9170_echo_test(struct ar9170 *ar, const u32 v) +{ + u32 echores; + int err; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO, + 4, (u8 *)&v, + 4, (u8 *)&echores); + if (err) + return err; + + if (v != echores) { + wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores); + return -EINVAL; + } + + return 0; +} + +struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, + const enum carl9170_cmd_oids cmd, const unsigned int len) +{ + struct carl9170_cmd *tmp; + + tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC); + if (tmp) { + tmp->hdr.cmd = cmd; + tmp->hdr.len = len; + } + + return tmp; +} + +int carl9170_reboot(struct ar9170 *ar) +{ + struct carl9170_cmd *cmd; + int err; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0); + if (!cmd) + return -ENOMEM; + + err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true); + return err; +} + +int carl9170_mac_reset(struct ar9170 *ar) +{ + return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST, + 0, NULL, 0, NULL); +} + +int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, + const u32 mode, const u32 addr, const u32 len) +{ + struct carl9170_cmd *cmd; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC, + sizeof(struct carl9170_bcn_ctrl_cmd)); + if (!cmd) + return -ENOMEM; + + cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id); + cmd->bcn_ctrl.mode = cpu_to_le32(mode); + cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr); + cmd->bcn_ctrl.bcn_len = cpu_to_le32(len); + + return __carl9170_exec_cmd(ar, cmd, true); +} + +int carl9170_powersave(struct ar9170 *ar, const bool ps) +{ + struct carl9170_cmd *cmd; + u32 state; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC, + sizeof(struct carl9170_psm)); + if (!cmd) + return -ENOMEM; + + if (ps) { + /* Sleep until next TBTT */ + state = CARL9170_PSM_SLEEP | 1; + } else { + /* wake up immediately */ + state = 1; + } + + cmd->psm.state = cpu_to_le32(state); + return __carl9170_exec_cmd(ar, cmd, true); +} diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h new file mode 100644 index 000000000000..0fc83d2336fd --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/cmd.h @@ -0,0 +1,158 @@ +/* + * Atheros CARL9170 driver + * + * Basic HW register/memory/command access functions + * + * Copyright 2008, Johannes Berg + * Copyright 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CMD_H +#define __CMD_H + +#include "carl9170.h" + +/* basic HW access */ +int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); +int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val); +int carl9170_read_mreg(struct ar9170 *ar, const int nregs, + const u32 *regs, u32 *out); +int carl9170_echo_test(struct ar9170 *ar, u32 v); +int carl9170_reboot(struct ar9170 *ar); +int carl9170_mac_reset(struct ar9170 *ar); +int carl9170_powersave(struct ar9170 *ar, const bool power_on); +int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, + const u32 mode, const u32 addr, const u32 len); + +static inline int carl9170_flush_cab(struct ar9170 *ar, + const unsigned int vif_id) +{ + return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); +} + +struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, + const enum carl9170_cmd_oids cmd, const unsigned int len); + +/* + * Macros to facilitate writing multiple registers in a single + * write-combining USB command. Note that when the first group + * fails the whole thing will fail without any others attempted, + * but you won't know which write in the group failed. + */ +#define carl9170_regwrite_begin(ar) \ +do { \ + int __nreg = 0, __err = 0; \ + struct ar9170 *__ar = ar; + +#define carl9170_regwrite(r, v) do { \ + __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \ + __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \ + __nreg++; \ + if ((__nreg >= PAYLOAD_MAX/2)) { \ + if (IS_ACCEPTING_CMD(__ar)) \ + __err = carl9170_exec_cmd(__ar, \ + CARL9170_CMD_WREG, 8 * __nreg, \ + (u8 *) &__ar->cmd_buf[1], 0, NULL); \ + else \ + goto __regwrite_out; \ + \ + __nreg = 0; \ + if (__err) \ + goto __regwrite_out; \ + } \ +} while (0) + +#define carl9170_regwrite_finish() \ +__regwrite_out : \ + if (__err == 0 && __nreg) { \ + if (IS_ACCEPTING_CMD(__ar)) \ + __err = carl9170_exec_cmd(__ar, \ + CARL9170_CMD_WREG, 8 * __nreg, \ + (u8 *) &__ar->cmd_buf[1], 0, NULL); \ + __nreg = 0; \ + } + +#define carl9170_regwrite_result() \ + __err; \ +} while (0); + + +#define carl9170_async_get_buf() \ +do { \ + __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ + CARL9170_MAX_CMD_PAYLOAD_LEN); \ + if (__cmd == NULL) { \ + __err = -ENOMEM; \ + goto __async_regwrite_out; \ + } \ +} while (0); + +#define carl9170_async_regwrite_begin(carl) \ +do { \ + int __nreg = 0, __err = 0; \ + struct ar9170 *__carl = carl; \ + struct carl9170_cmd *__cmd; \ + carl9170_async_get_buf(); \ + +#define carl9170_async_regwrite(r, v) do { \ + __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ + __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ + __nreg++; \ + if ((__nreg >= PAYLOAD_MAX/2)) { \ + if (IS_ACCEPTING_CMD(__carl)) { \ + __cmd->hdr.len = 8 * __nreg; \ + __err = __carl9170_exec_cmd(__carl, __cmd, true);\ + __cmd = NULL; \ + carl9170_async_get_buf(); \ + } else { \ + goto __async_regwrite_out; \ + } \ + __nreg = 0; \ + if (__err) \ + goto __async_regwrite_out; \ + } \ +} while (0) + +#define carl9170_async_regwrite_finish() \ +__async_regwrite_out : \ + if (__err == 0 && __nreg) { \ + __cmd->hdr.len = 8 * __nreg; \ + if (IS_ACCEPTING_CMD(__carl)) \ + __err = __carl9170_exec_cmd(__carl, __cmd, true);\ + __nreg = 0; \ + } + +#define carl9170_async_regwrite_result() \ + __err; \ +} while (0); + +#endif /* __CMD_H */ diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c new file mode 100644 index 000000000000..4bb2cbd8bd9b --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/led.c @@ -0,0 +1,190 @@ +/* + * Atheros CARL9170 driver + * + * LED handling + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state) +{ + return carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_DATA, led_state); +} + +int carl9170_led_init(struct ar9170 *ar) +{ + int err; + + /* disable LEDs */ + /* GPIO [0/1 mode: output, 2/3: input] */ + err = carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3); + if (err) + goto out; + + /* GPIO 0/1 value: off */ + err = carl9170_led_set_state(ar, 0); + +out: + return err; +} + +#ifdef CONFIG_CARL9170_LEDS +static void carl9170_led_update(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, led_work.work); + int i, tmp = 300, blink_delay = 1000; + u32 led_val = 0; + bool rerun = false; + + if (!IS_ACCEPTING_CMD(ar)) + return; + + mutex_lock(&ar->mutex); + for (i = 0; i < AR9170_NUM_LEDS; i++) { + if (ar->leds[i].registered) { + if (ar->leds[i].last_state || + ar->leds[i].toggled) { + + if (ar->leds[i].toggled) + tmp = 70 + 200 / (ar->leds[i].toggled); + + if (tmp < blink_delay) + blink_delay = tmp; + + led_val |= 1 << i; + ar->leds[i].toggled = 0; + rerun = true; + } + } + } + + carl9170_led_set_state(ar, led_val); + mutex_unlock(&ar->mutex); + + if (!rerun) + return; + + ieee80211_queue_delayed_work(ar->hw, + &ar->led_work, + msecs_to_jiffies(blink_delay)); +} + +static void carl9170_led_set_brightness(struct led_classdev *led, + enum led_brightness brightness) +{ + struct carl9170_led *arl = container_of(led, struct carl9170_led, l); + struct ar9170 *ar = arl->ar; + + if (!arl->registered) + return; + + if (arl->last_state != !!brightness) { + arl->toggled++; + arl->last_state = !!brightness; + } + + if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) + ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); +} + +static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, + char *trigger) +{ + int err; + + snprintf(ar->leds[i].name, sizeof(ar->leds[i].name), + "carl9170-%s::%s", wiphy_name(ar->hw->wiphy), name); + + ar->leds[i].ar = ar; + ar->leds[i].l.name = ar->leds[i].name; + ar->leds[i].l.brightness_set = carl9170_led_set_brightness; + ar->leds[i].l.brightness = 0; + ar->leds[i].l.default_trigger = trigger; + + err = led_classdev_register(wiphy_dev(ar->hw->wiphy), + &ar->leds[i].l); + if (err) { + wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", + ar->leds[i].name, err); + } else { + ar->leds[i].registered = true; + } + + return err; +} + +void carl9170_led_unregister(struct ar9170 *ar) +{ + int i; + + for (i = 0; i < AR9170_NUM_LEDS; i++) + if (ar->leds[i].registered) { + led_classdev_unregister(&ar->leds[i].l); + ar->leds[i].registered = false; + ar->leds[i].toggled = 0; + } + + cancel_delayed_work_sync(&ar->led_work); +} + +int carl9170_led_register(struct ar9170 *ar) +{ + int err; + + INIT_DELAYED_WORK(&ar->led_work, carl9170_led_update); + + err = carl9170_led_register_led(ar, 0, "tx", + ieee80211_get_tx_led_name(ar->hw)); + if (err) + goto fail; + + if (ar->features & CARL9170_ONE_LED) + return 0; + + err = carl9170_led_register_led(ar, 1, "assoc", + ieee80211_get_assoc_led_name(ar->hw)); + if (err) + goto fail; + + return 0; + +fail: + carl9170_led_unregister(ar); + return err; +} + +#endif /* CONFIG_CARL9170_LEDS */ diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c new file mode 100644 index 000000000000..ea49d54ce03b --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -0,0 +1,1855 @@ +/* + * Atheros CARL9170 driver + * + * mac80211 interaction code + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hw.h" +#include "carl9170.h" +#include "cmd.h" + +static int modparam_nohwcrypt; +module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); +MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); + +int modparam_noht; +module_param_named(noht, modparam_noht, int, S_IRUGO); +MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); + +#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ + .bitrate = (_bitrate), \ + .flags = (_flags), \ + .hw_value = (_hw_rate) | (_txpidx) << 4, \ +} + +struct ieee80211_rate __carl9170_ratetable[] = { + RATE(10, 0, 0, 0), + RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0xb, 0, 0), + RATE(90, 0xf, 0, 0), + RATE(120, 0xa, 0, 0), + RATE(180, 0xe, 0, 0), + RATE(240, 0x9, 0, 0), + RATE(360, 0xd, 1, 0), + RATE(480, 0x8, 2, 0), + RATE(540, 0xc, 3, 0), +}; +#undef RATE + +#define carl9170_g_ratetable (__carl9170_ratetable + 0) +#define carl9170_g_ratetable_size 12 +#define carl9170_a_ratetable (__carl9170_ratetable + 4) +#define carl9170_a_ratetable_size 8 + +/* + * NB: The hw_value is used as an index into the carl9170_phy_freq_params + * array in phy.c so that we don't have to do frequency lookups! + */ +#define CHAN(_freq, _idx) { \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 18, /* XXX */ \ +} + +static struct ieee80211_channel carl9170_2ghz_chantable[] = { + CHAN(2412, 0), + CHAN(2417, 1), + CHAN(2422, 2), + CHAN(2427, 3), + CHAN(2432, 4), + CHAN(2437, 5), + CHAN(2442, 6), + CHAN(2447, 7), + CHAN(2452, 8), + CHAN(2457, 9), + CHAN(2462, 10), + CHAN(2467, 11), + CHAN(2472, 12), + CHAN(2484, 13), +}; + +static struct ieee80211_channel carl9170_5ghz_chantable[] = { + CHAN(4920, 14), + CHAN(4940, 15), + CHAN(4960, 16), + CHAN(4980, 17), + CHAN(5040, 18), + CHAN(5060, 19), + CHAN(5080, 20), + CHAN(5180, 21), + CHAN(5200, 22), + CHAN(5220, 23), + CHAN(5240, 24), + CHAN(5260, 25), + CHAN(5280, 26), + CHAN(5300, 27), + CHAN(5320, 28), + CHAN(5500, 29), + CHAN(5520, 30), + CHAN(5540, 31), + CHAN(5560, 32), + CHAN(5580, 33), + CHAN(5600, 34), + CHAN(5620, 35), + CHAN(5640, 36), + CHAN(5660, 37), + CHAN(5680, 38), + CHAN(5700, 39), + CHAN(5745, 40), + CHAN(5765, 41), + CHAN(5785, 42), + CHAN(5805, 43), + CHAN(5825, 44), + CHAN(5170, 45), + CHAN(5190, 46), + CHAN(5210, 47), + CHAN(5230, 48), +}; +#undef CHAN + +#define CARL9170_HT_CAP \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ + IEEE80211_HT_CAP_SGI_40 | \ + IEEE80211_HT_CAP_DSSSCCK40 | \ + IEEE80211_HT_CAP_SM_PS, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ + .mcs = { \ + .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \ + .rx_highest = cpu_to_le16(300), \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ + }, \ +} + +static struct ieee80211_supported_band carl9170_band_2GHz = { + .channels = carl9170_2ghz_chantable, + .n_channels = ARRAY_SIZE(carl9170_2ghz_chantable), + .bitrates = carl9170_g_ratetable, + .n_bitrates = carl9170_g_ratetable_size, + .ht_cap = CARL9170_HT_CAP, +}; + +static struct ieee80211_supported_band carl9170_band_5GHz = { + .channels = carl9170_5ghz_chantable, + .n_channels = ARRAY_SIZE(carl9170_5ghz_chantable), + .bitrates = carl9170_a_ratetable, + .n_bitrates = carl9170_a_ratetable_size, + .ht_cap = CARL9170_HT_CAP, +}; + +static void carl9170_ampdu_gc(struct ar9170 *ar) +{ + struct carl9170_sta_tid *tid_info; + LIST_HEAD(tid_gc); + + rcu_read_lock(); + list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state == CARL9170_TID_STATE_SHUTDOWN) { + tid_info->state = CARL9170_TID_STATE_KILLED; + list_del_rcu(&tid_info->list); + ar->tx_ampdu_list_len--; + list_add_tail(&tid_info->tmp_list, &tid_gc); + } + spin_unlock_bh(&ar->tx_ampdu_list_lock); + + } + rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); + rcu_read_unlock(); + + synchronize_rcu(); + + while (!list_empty(&tid_gc)) { + struct sk_buff *skb; + tid_info = list_first_entry(&tid_gc, struct carl9170_sta_tid, + tmp_list); + + while ((skb = __skb_dequeue(&tid_info->queue))) + carl9170_tx_status(ar, skb, false); + + list_del_init(&tid_info->tmp_list); + kfree(tid_info); + } +} + +static void carl9170_flush(struct ar9170 *ar, bool drop_queued) +{ + if (drop_queued) { + int i; + + /* + * We can only drop frames which have not been uploaded + * to the device yet. + */ + + for (i = 0; i < ar->hw->queues; i++) { + struct sk_buff *skb; + + while ((skb = skb_dequeue(&ar->tx_pending[i]))) + carl9170_tx_status(ar, skb, false); + } + } + + /* Wait for all other outstanding frames to timeout. */ + if (atomic_read(&ar->tx_total_queued)) + WARN_ON(wait_for_completion_timeout(&ar->tx_flush, HZ) == 0); +} + +static void carl9170_flush_ba(struct ar9170 *ar) +{ + struct sk_buff_head free; + struct carl9170_sta_tid *tid_info; + struct sk_buff *skb; + + __skb_queue_head_init(&free); + + rcu_read_lock(); + spin_lock_bh(&ar->tx_ampdu_list_lock); + list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { + if (tid_info->state > CARL9170_TID_STATE_SUSPEND) { + tid_info->state = CARL9170_TID_STATE_SUSPEND; + + spin_lock(&tid_info->lock); + while ((skb = __skb_dequeue(&tid_info->queue))) + __skb_queue_tail(&free, skb); + spin_unlock(&tid_info->lock); + } + } + spin_unlock_bh(&ar->tx_ampdu_list_lock); + rcu_read_unlock(); + + while ((skb = __skb_dequeue(&free))) + carl9170_tx_status(ar, skb, false); +} + +static void carl9170_zap_queues(struct ar9170 *ar) +{ + struct carl9170_vif_info *cvif; + unsigned int i; + + carl9170_ampdu_gc(ar); + + carl9170_flush_ba(ar); + carl9170_flush(ar, true); + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_status[i].lock); + while (!skb_queue_empty(&ar->tx_status[i])) { + struct sk_buff *skb; + + skb = skb_peek(&ar->tx_status[i]); + carl9170_tx_get_skb(skb); + spin_unlock_bh(&ar->tx_status[i].lock); + carl9170_tx_drop(ar, skb); + spin_lock_bh(&ar->tx_status[i].lock); + carl9170_tx_put_skb(skb); + } + spin_unlock_bh(&ar->tx_status[i].lock); + } + + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_SOFT < 1); + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD < CARL9170_NUM_TX_LIMIT_SOFT); + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD >= CARL9170_BAW_BITS); + + /* reinitialize queues statistics */ + memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); + for (i = 0; i < ar->hw->queues; i++) + ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD; + + for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++) + ar->mem_bitmap[i] = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(cvif, &ar->vif_list, list) { + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(cvif->beacon); + cvif->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + } + rcu_read_unlock(); + + atomic_set(&ar->tx_ampdu_upload, 0); + atomic_set(&ar->tx_ampdu_scheduler, 0); + atomic_set(&ar->tx_total_pending, 0); + atomic_set(&ar->tx_total_queued, 0); + atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); +} + +#define CARL9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ +do { \ + queue.aifs = ai_fs; \ + queue.cw_min = cwmin; \ + queue.cw_max = cwmax; \ + queue.txop = _txop; \ +} while (0) + +static int carl9170_op_start(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + int err, i; + + mutex_lock(&ar->mutex); + + carl9170_zap_queues(ar); + + /* reset QoS defaults */ + CARL9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT */ + CARL9170_FILL_QUEUE(ar->edcf[1], 2, 7, 15, 94); /* VIDEO */ + CARL9170_FILL_QUEUE(ar->edcf[2], 2, 3, 7, 47); /* VOICE */ + CARL9170_FILL_QUEUE(ar->edcf[3], 7, 15, 1023, 0); /* BACKGROUND */ + CARL9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ + + ar->current_factor = ar->current_density = -1; + /* "The first key is unique." */ + ar->usedkeys = 1; + ar->filter_state = 0; + ar->ps.last_action = jiffies; + ar->ps.last_slept = jiffies; + ar->erp_mode = CARL9170_ERP_AUTO; + ar->rx_software_decryption = false; + ar->disable_offload = false; + + for (i = 0; i < ar->hw->queues; i++) { + ar->queue_stop_timeout[i] = jiffies; + ar->max_queue_stop_timeout[i] = 0; + } + + atomic_set(&ar->mem_allocs, 0); + + err = carl9170_usb_open(ar); + if (err) + goto out; + + err = carl9170_init_mac(ar); + if (err) + goto out; + + err = carl9170_set_qos(ar); + if (err) + goto out; + + err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, + AR9170_DMA_TRIGGER_RXQ); + if (err) + goto out; + + /* Clear key-cache */ + for (i = 0; i < AR9170_CAM_MAX_USER + 4; i++) { + err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, + 0, NULL, 0); + if (err) + goto out; + + err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, + 1, NULL, 0); + if (err) + goto out; + + if (i < AR9170_CAM_MAX_USER) { + err = carl9170_disable_key(ar, i); + if (err) + goto out; + } + } + + carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED); + + ieee80211_wake_queues(ar->hw); + err = 0; + +out: + mutex_unlock(&ar->mutex); + return err; +} + +static void carl9170_cancel_worker(struct ar9170 *ar) +{ + cancel_delayed_work_sync(&ar->tx_janitor); +#ifdef CONFIG_CARL9170_LEDS + cancel_delayed_work_sync(&ar->led_work); +#endif /* CONFIG_CARL9170_LEDS */ + cancel_work_sync(&ar->ps_work); + cancel_work_sync(&ar->ampdu_work); +} + +static void carl9170_op_stop(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + + carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); + + ieee80211_stop_queues(ar->hw); + + mutex_lock(&ar->mutex); + if (IS_ACCEPTING_CMD(ar)) { + rcu_assign_pointer(ar->beacon_iter, NULL); + + carl9170_led_set_state(ar, 0); + + /* stop DMA */ + carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 0); + carl9170_usb_stop(ar); + } + + carl9170_zap_queues(ar); + mutex_unlock(&ar->mutex); + + carl9170_cancel_worker(ar); +} + +static void carl9170_restart_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + restart_work); + int err; + + ar->usedkeys = 0; + ar->filter_state = 0; + carl9170_cancel_worker(ar); + + mutex_lock(&ar->mutex); + err = carl9170_usb_restart(ar); + if (net_ratelimit()) { + if (err) { + dev_err(&ar->udev->dev, "Failed to restart device " + " (%d).\n", err); + } else { + dev_info(&ar->udev->dev, "device restarted " + "successfully.\n"); + } + } + + carl9170_zap_queues(ar); + mutex_unlock(&ar->mutex); + if (!err) { + ar->restart_counter++; + atomic_set(&ar->pending_restarts, 0); + + ieee80211_restart_hw(ar->hw); + } else { + /* + * The reset was unsuccessful and the device seems to + * be dead. But there's still one option: a low-level + * usb subsystem reset... + */ + + carl9170_usb_reset(ar); + } +} + +void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r) +{ + carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); + + /* + * Sometimes, an error can trigger several different reset events. + * By ignoring these *surplus* reset events, the device won't be + * killed again, right after it has recovered. + */ + if (atomic_inc_return(&ar->pending_restarts) > 1) { + dev_dbg(&ar->udev->dev, "ignoring restart (%d)\n", r); + return; + } + + ieee80211_stop_queues(ar->hw); + + dev_err(&ar->udev->dev, "restart device (%d)\n", r); + + if (!WARN_ON(r == CARL9170_RR_NO_REASON) || + !WARN_ON(r >= __CARL9170_RR_LAST)) + ar->last_reason = r; + + if (!ar->registered) + return; + + if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset) + ieee80211_queue_work(ar->hw, &ar->restart_work); + else + carl9170_usb_reset(ar); + + /* + * At this point, the device instance might have vanished/disabled. + * So, don't put any code which access the ar9170 struct + * without proper protection. + */ +} + +static int carl9170_init_interface(struct ar9170 *ar, + struct ieee80211_vif *vif) +{ + struct ath_common *common = &ar->common; + int err; + + if (!vif) { + WARN_ON_ONCE(IS_STARTED(ar)); + return 0; + } + + memcpy(common->macaddr, vif->addr, ETH_ALEN); + + if (modparam_nohwcrypt || + ((vif->type != NL80211_IFTYPE_STATION) && + (vif->type != NL80211_IFTYPE_AP))) { + ar->rx_software_decryption = true; + ar->disable_offload = true; + } + + err = carl9170_set_operating_mode(ar); + return err; +} + +static int carl9170_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; + struct ieee80211_vif *main_vif; + struct ar9170 *ar = hw->priv; + int vif_id = -1, err = 0; + + mutex_lock(&ar->mutex); + rcu_read_lock(); + if (vif_priv->active) { + /* + * Skip the interface structure initialization, + * if the vif survived the _restart call. + */ + vif_id = vif_priv->id; + vif_priv->enable_beacon = false; + + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(vif_priv->beacon); + vif_priv->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + + goto init; + } + + main_vif = carl9170_get_main_vif(ar); + + if (main_vif) { + switch (main_vif->type) { + case NL80211_IFTYPE_STATION: + if (vif->type == NL80211_IFTYPE_STATION) + break; + + err = -EBUSY; + rcu_read_unlock(); + + goto unlock; + + case NL80211_IFTYPE_AP: + if ((vif->type == NL80211_IFTYPE_STATION) || + (vif->type == NL80211_IFTYPE_WDS) || + (vif->type == NL80211_IFTYPE_AP)) + break; + + err = -EBUSY; + rcu_read_unlock(); + goto unlock; + + default: + rcu_read_unlock(); + goto unlock; + } + } + + vif_id = bitmap_find_free_region(&ar->vif_bitmap, ar->fw.vif_num, 0); + + if (vif_id < 0) { + rcu_read_unlock(); + + err = -ENOSPC; + goto unlock; + } + + BUG_ON(ar->vif_priv[vif_id].id != vif_id); + + vif_priv->active = true; + vif_priv->id = vif_id; + vif_priv->enable_beacon = false; + ar->vifs++; + list_add_tail_rcu(&vif_priv->list, &ar->vif_list); + rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); + +init: + if (carl9170_get_main_vif(ar) == vif) { + rcu_assign_pointer(ar->beacon_iter, vif_priv); + rcu_read_unlock(); + + err = carl9170_init_interface(ar, vif); + if (err) + goto unlock; + } else { + err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr); + rcu_read_unlock(); + + if (err) + goto unlock; + } + +unlock: + if (err && (vif_id != -1)) { + vif_priv->active = false; + bitmap_release_region(&ar->vif_bitmap, vif_id, 0); + ar->vifs--; + rcu_assign_pointer(ar->vif_priv[vif_id].vif, NULL); + list_del_rcu(&vif_priv->list); + mutex_unlock(&ar->mutex); + synchronize_rcu(); + } else { + if (ar->vifs > 1) + ar->ps.off_override |= PS_OFF_VIF; + + mutex_unlock(&ar->mutex); + } + + return err; +} + +static void carl9170_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; + struct ieee80211_vif *main_vif; + struct ar9170 *ar = hw->priv; + unsigned int id; + + mutex_lock(&ar->mutex); + + if (WARN_ON_ONCE(!vif_priv->active)) + goto unlock; + + ar->vifs--; + + rcu_read_lock(); + main_vif = carl9170_get_main_vif(ar); + + id = vif_priv->id; + + vif_priv->active = false; + WARN_ON(vif_priv->enable_beacon); + vif_priv->enable_beacon = false; + list_del_rcu(&vif_priv->list); + rcu_assign_pointer(ar->vif_priv[id].vif, NULL); + + if (vif == main_vif) { + rcu_read_unlock(); + + if (ar->vifs) { + WARN_ON(carl9170_init_interface(ar, + carl9170_get_main_vif(ar))); + } else { + carl9170_set_operating_mode(ar); + } + } else { + rcu_read_unlock(); + + WARN_ON(carl9170_mod_virtual_mac(ar, id, NULL)); + } + + carl9170_update_beacon(ar, false); + carl9170_flush_cab(ar, id); + + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(vif_priv->beacon); + vif_priv->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + + bitmap_release_region(&ar->vif_bitmap, id, 0); + + carl9170_set_beacon_timers(ar); + + if (ar->vifs == 1) + ar->ps.off_override &= ~PS_OFF_VIF; + +unlock: + mutex_unlock(&ar->mutex); + + synchronize_rcu(); +} + +void carl9170_ps_check(struct ar9170 *ar) +{ + ieee80211_queue_work(ar->hw, &ar->ps_work); +} + +/* caller must hold ar->mutex */ +static int carl9170_ps_update(struct ar9170 *ar) +{ + bool ps = false; + int err = 0; + + if (!ar->ps.off_override) + ps = (ar->hw->conf.flags & IEEE80211_CONF_PS); + + if (ps != ar->ps.state) { + err = carl9170_powersave(ar, ps); + if (err) + return err; + + if (ar->ps.state && !ps) { + ar->ps.sleep_ms = jiffies_to_msecs(jiffies - + ar->ps.last_action); + } + + if (ps) + ar->ps.last_slept = jiffies; + + ar->ps.last_action = jiffies; + ar->ps.state = ps; + } + + return 0; +} + +static void carl9170_ps_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + ps_work); + mutex_lock(&ar->mutex); + if (IS_STARTED(ar)) + WARN_ON_ONCE(carl9170_ps_update(ar) != 0); + mutex_unlock(&ar->mutex); +} + + +static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ar9170 *ar = hw->priv; + int err = 0; + + mutex_lock(&ar->mutex); + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_PS) { + err = carl9170_ps_update(ar); + if (err) + goto out; + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_SMPS) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + /* adjust slot time for 5 GHz */ + err = carl9170_set_slot_time(ar); + if (err) + goto out; + + err = carl9170_set_channel(ar, hw->conf.channel, + hw->conf.channel_type, CARL9170_RFI_NONE); + if (err) + goto out; + + err = carl9170_set_dyn_sifs_ack(ar); + if (err) + goto out; + + err = carl9170_set_rts_cts_rate(ar); + if (err) + goto out; + } + +out: + mutex_unlock(&ar->mutex); + return err; +} + +static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + struct netdev_hw_addr *ha; + u64 mchash; + + /* always get broadcast frames */ + mchash = 1ULL << (0xff >> 2); + + netdev_hw_addr_list_for_each(ha, mc_list) + mchash |= 1ULL << (ha->addr[5] >> 2); + + return mchash; +} + +static void carl9170_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct ar9170 *ar = hw->priv; + + /* mask supported flags */ + *new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL | + FIF_OTHER_BSS | FIF_PROMISC_IN_BSS; + + if (!IS_ACCEPTING_CMD(ar)) + return; + + mutex_lock(&ar->mutex); + + ar->filter_state = *new_flags; + /* + * We can support more by setting the sniffer bit and + * then checking the error flags, later. + */ + + if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) + multicast = ~0ULL; + + if (multicast != ar->cur_mc_hash) + WARN_ON(carl9170_update_multicast(ar, multicast)); + + if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { + ar->sniffer_enabled = !!(*new_flags & + (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)); + + WARN_ON(carl9170_set_operating_mode(ar)); + } + + mutex_unlock(&ar->mutex); +} + + +static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + struct ar9170 *ar = hw->priv; + struct ath_common *common = &ar->common; + int err = 0; + struct carl9170_vif_info *vif_priv; + struct ieee80211_vif *main_vif; + + mutex_lock(&ar->mutex); + vif_priv = (void *) vif->drv_priv; + main_vif = carl9170_get_main_vif(ar); + if (WARN_ON(!main_vif)) + goto out; + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + struct carl9170_vif_info *iter; + int i = 0; + + vif_priv->enable_beacon = bss_conf->enable_beacon; + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->vif_list, list) { + if (iter->active && iter->enable_beacon) + i++; + + } + rcu_read_unlock(); + + ar->beacon_enabled = i; + } + + if (changed & BSS_CHANGED_BEACON) { + err = carl9170_update_beacon(ar, false); + if (err) + goto out; + } + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_INT)) { + + if (main_vif != vif) { + bss_conf->beacon_int = main_vif->bss_conf.beacon_int; + bss_conf->dtim_period = main_vif->bss_conf.dtim_period; + } + + /* + * Therefore a hard limit for the broadcast traffic should + * prevent false alarms. + */ + if (vif->type != NL80211_IFTYPE_STATION && + (bss_conf->beacon_int * bss_conf->dtim_period >= + (CARL9170_QUEUE_STUCK_TIMEOUT / 2))) { + err = -EINVAL; + goto out; + } + + err = carl9170_set_beacon_timers(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_HT) { + /* TODO */ + err = 0; + if (err) + goto out; + } + + if (main_vif != vif) + goto out; + + /* + * The following settings can only be changed by the + * master interface. + */ + + if (changed & BSS_CHANGED_BSSID) { + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + err = carl9170_set_operating_mode(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_ASSOC) { + ar->common.curaid = bss_conf->aid; + err = carl9170_set_beacon_timers(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + err = carl9170_set_slot_time(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_BASIC_RATES) { + err = carl9170_set_mac_rates(ar); + if (err) + goto out; + } + +out: + WARN_ON_ONCE(err && IS_STARTED(ar)); + mutex_unlock(&ar->mutex); +} + +static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_tsf_rsp tsf; + int err; + + mutex_lock(&ar->mutex); + err = carl9170_exec_cmd(ar, CARL9170_CMD_READ_TSF, + 0, NULL, sizeof(tsf), &tsf); + mutex_unlock(&ar->mutex); + if (WARN_ON(err)) + return 0; + + return le64_to_cpu(tsf.tsf_64); +} + +static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ar9170 *ar = hw->priv; + int err = 0, i; + u8 ktype; + + if (ar->disable_offload || !vif) + return -EOPNOTSUPP; + + /* + * We have to fall back to software encryption, whenever + * the user choose to participates in an IBSS or is connected + * to more than one network. + * + * This is very unfortunate, because some machines cannot handle + * the high througput speed in 802.11n networks. + */ + + if (!is_main_vif(ar, vif)) + goto err_softw; + + /* + * While the hardware supports *catch-all* key, for offloading + * group-key en-/de-cryption. The way of how the hardware + * decides which keyId maps to which key, remains a mystery... + */ + if ((vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_ADHOC) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + ktype = AR9170_ENC_ALG_WEP64; + break; + case WLAN_CIPHER_SUITE_WEP104: + ktype = AR9170_ENC_ALG_WEP128; + break; + case WLAN_CIPHER_SUITE_TKIP: + ktype = AR9170_ENC_ALG_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + ktype = AR9170_ENC_ALG_AESCCMP; + break; + default: + return -EOPNOTSUPP; + } + + mutex_lock(&ar->mutex); + if (cmd == SET_KEY) { + if (!IS_STARTED(ar)) { + err = -EOPNOTSUPP; + goto out; + } + + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + sta = NULL; + + i = 64 + key->keyidx; + } else { + for (i = 0; i < 64; i++) + if (!(ar->usedkeys & BIT(i))) + break; + if (i == 64) + goto err_softw; + } + + key->hw_key_idx = i; + + err = carl9170_upload_key(ar, i, sta ? sta->addr : NULL, + ktype, 0, key->key, + min_t(u8, 16, key->keylen)); + if (err) + goto out; + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + err = carl9170_upload_key(ar, i, sta ? sta->addr : + NULL, ktype, 1, + key->key + 16, 16); + if (err) + goto out; + + /* + * hardware is not capable generating MMIC + * of fragmented frames! + */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + } + + if (i < 64) + ar->usedkeys |= BIT(i); + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + } else { + if (!IS_STARTED(ar)) { + /* The device is gone... together with the key ;-) */ + err = 0; + goto out; + } + + if (key->hw_key_idx < 64) { + ar->usedkeys &= ~BIT(key->hw_key_idx); + } else { + err = carl9170_upload_key(ar, key->hw_key_idx, NULL, + AR9170_ENC_ALG_NONE, 0, + NULL, 0); + if (err) + goto out; + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + err = carl9170_upload_key(ar, key->hw_key_idx, + NULL, + AR9170_ENC_ALG_NONE, + 1, NULL, 0); + if (err) + goto out; + } + + } + + err = carl9170_disable_key(ar, key->hw_key_idx); + if (err) + goto out; + } + +out: + mutex_unlock(&ar->mutex); + return err; + +err_softw: + if (!ar->rx_software_decryption) { + ar->rx_software_decryption = true; + carl9170_set_operating_mode(ar); + } + mutex_unlock(&ar->mutex); + return -ENOSPC; +} + +static int carl9170_op_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + unsigned int i; + + if (sta->ht_cap.ht_supported) { + if (sta->ht_cap.ampdu_density > 6) { + /* + * HW does support 16us AMPDU density. + * No HT-Xmit for station. + */ + + return 0; + } + + for (i = 0; i < CARL9170_NUM_TID; i++) + rcu_assign_pointer(sta_info->agg[i], NULL); + + sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); + sta_info->ht_sta = true; + } + + return 0; +} + +static int carl9170_op_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + unsigned int i; + bool cleanup = false; + + if (sta->ht_cap.ht_supported) { + + sta_info->ht_sta = false; + + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + rcu_assign_pointer(sta_info->agg[i], NULL); + + if (!tid_info) + continue; + + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) + tid_info->state = CARL9170_TID_STATE_SHUTDOWN; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + cleanup = true; + } + rcu_read_unlock(); + + if (cleanup) + carl9170_ampdu_gc(ar); + } + + return 0; +} + +static int carl9170_op_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *param) +{ + struct ar9170 *ar = hw->priv; + int ret; + + mutex_lock(&ar->mutex); + if (queue < ar->hw->queues) { + memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param)); + ret = carl9170_set_qos(ar); + } else { + ret = -EINVAL; + } + + mutex_unlock(&ar->mutex); + return ret; +} + +static void carl9170_ampdu_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + ampdu_work); + + if (!IS_STARTED(ar)) + return; + + mutex_lock(&ar->mutex); + carl9170_ampdu_gc(ar); + mutex_unlock(&ar->mutex); +} + +static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, + u16 tid, u16 *ssn) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + struct carl9170_sta_tid *tid_info; + + if (modparam_noht) + return -EOPNOTSUPP; + + switch (action) { + case IEEE80211_AMPDU_TX_START: + if (WARN_ON_ONCE(!sta_info->ht_sta)) + return -EOPNOTSUPP; + + rcu_read_lock(); + if (rcu_dereference(sta_info->agg[tid])) { + rcu_read_unlock(); + return -EBUSY; + } + + tid_info = kzalloc(sizeof(struct carl9170_sta_tid), + GFP_ATOMIC); + if (!tid_info) { + rcu_read_unlock(); + return -ENOMEM; + } + + tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); + tid_info->state = CARL9170_TID_STATE_PROGRESS; + tid_info->tid = tid; + tid_info->max = sta_info->ampdu_max_len; + + INIT_LIST_HEAD(&tid_info->list); + INIT_LIST_HEAD(&tid_info->tmp_list); + skb_queue_head_init(&tid_info->queue); + spin_lock_init(&tid_info->lock); + + spin_lock_bh(&ar->tx_ampdu_list_lock); + ar->tx_ampdu_list_len++; + list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); + rcu_assign_pointer(sta_info->agg[tid], tid_info); + spin_unlock_bh(&ar->tx_ampdu_list_lock); + rcu_read_unlock(); + + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + + case IEEE80211_AMPDU_TX_STOP: + rcu_read_lock(); + tid_info = rcu_dereference(sta_info->agg[tid]); + if (tid_info) { + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) + tid_info->state = CARL9170_TID_STATE_SHUTDOWN; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + } + + rcu_assign_pointer(sta_info->agg[tid], NULL); + rcu_read_unlock(); + + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ieee80211_queue_work(ar->hw, &ar->ampdu_work); + break; + + case IEEE80211_AMPDU_TX_OPERATIONAL: + rcu_read_lock(); + tid_info = rcu_dereference(sta_info->agg[tid]); + + sta_info->stats[tid].clear = true; + + if (tid_info) { + bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); + tid_info->state = CARL9170_TID_STATE_IDLE; + } + rcu_read_unlock(); + + if (WARN_ON_ONCE(!tid_info)) + return -EFAULT; + + break; + + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + /* Handled by hardware */ + break; + + default: + return -EOPNOTSUPP; + } + + return 0; +} + +#ifdef CONFIG_CARL9170_WPC +static int carl9170_register_wps_button(struct ar9170 *ar) +{ + struct input_dev *input; + int err; + + if (!(ar->features & CARL9170_WPS_BUTTON)) + return 0; + + input = input_allocate_device(); + if (!input) + return -ENOMEM; + + snprintf(ar->wps.name, sizeof(ar->wps.name), "%s WPS Button", + wiphy_name(ar->hw->wiphy)); + + snprintf(ar->wps.phys, sizeof(ar->wps.phys), + "ieee80211/%s/input0", wiphy_name(ar->hw->wiphy)); + + input->name = ar->wps.name; + input->phys = ar->wps.phys; + input->id.bustype = BUS_USB; + input->dev.parent = &ar->hw->wiphy->dev; + + input_set_capability(input, EV_KEY, KEY_WPS_BUTTON); + + err = input_register_device(input); + if (err) { + input_free_device(input); + return err; + } + + ar->wps.pbc = input; + return 0; +} +#endif /* CONFIG_CARL9170_WPC */ + +static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ar9170 *ar = hw->priv; + int err; + + if (idx != 0) + return -ENOENT; + + mutex_lock(&ar->mutex); + err = carl9170_get_noisefloor(ar); + mutex_unlock(&ar->mutex); + if (err) + return err; + + survey->channel = ar->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = ar->noise[0]; + return 0; +} + +static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) +{ + struct ar9170 *ar = hw->priv; + unsigned int vid; + + mutex_lock(&ar->mutex); + for_each_set_bit(vid, &ar->vif_bitmap, ar->fw.vif_num) + carl9170_flush_cab(ar, vid); + + carl9170_flush(ar, drop); + mutex_unlock(&ar->mutex); +} + +static int carl9170_op_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct ar9170 *ar = hw->priv; + + memset(stats, 0, sizeof(*stats)); + stats->dot11ACKFailureCount = ar->tx_ack_failures; + stats->dot11FCSErrorCount = ar->tx_fcs_errors; + return 0; +} + +static void carl9170_op_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + struct sk_buff *skb; + struct sk_buff_head free; + int i; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + /* + * Since the peer is no longer listening, we have to return + * as many SKBs as possible back to the mac80211 stack. + * It will deal with the retry procedure, once the peer + * has become available again. + * + * NB: Ideally, the driver should return the all frames in + * the correct, ascending order. However, I think that this + * functionality should be implemented in the stack and not + * here... + */ + + __skb_queue_head_init(&free); + + if (sta->ht_cap.ht_supported) { + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + + if (!tid_info) + continue; + + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > + CARL9170_TID_STATE_SUSPEND) + tid_info->state = + CARL9170_TID_STATE_SUSPEND; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + + spin_lock_bh(&tid_info->lock); + while ((skb = __skb_dequeue(&tid_info->queue))) + __skb_queue_tail(&free, skb); + spin_unlock_bh(&tid_info->lock); + + ieee80211_stop_tx_ba_session(sta, + tid_info->tid); + } + rcu_read_unlock(); + } + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_pending[i].lock); + skb_queue_walk(&ar->tx_pending[i], skb) { + struct _carl9170_tx_superframe *super; + struct ieee80211_hdr *hdr; + + super = (void *) skb->data; + hdr = (void *) super->frame_data; + + if (compare_ether_addr(hdr->addr1, sta->addr)) + continue; + + __skb_unlink(skb, &ar->tx_pending[i]); + carl9170_tx_status(ar, skb, false); + } + spin_unlock_bh(&ar->tx_pending[i].lock); + } + + while ((skb = __skb_dequeue(&free))) + carl9170_tx_status(ar, skb, false); + + break; + + case STA_NOTIFY_AWAKE: + if (!sta->ht_cap.ht_supported) + return; + + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + + if (!tid_info) + continue; + + if ((tid_info->state == CARL9170_TID_STATE_SUSPEND)) + tid_info->state = CARL9170_TID_STATE_IDLE; + } + rcu_read_unlock(); + break; + } +} + +static const struct ieee80211_ops carl9170_ops = { + .start = carl9170_op_start, + .stop = carl9170_op_stop, + .tx = carl9170_op_tx, + .flush = carl9170_op_flush, + .add_interface = carl9170_op_add_interface, + .remove_interface = carl9170_op_remove_interface, + .config = carl9170_op_config, + .prepare_multicast = carl9170_op_prepare_multicast, + .configure_filter = carl9170_op_configure_filter, + .conf_tx = carl9170_op_conf_tx, + .bss_info_changed = carl9170_op_bss_info_changed, + .get_tsf = carl9170_op_get_tsf, + .set_key = carl9170_op_set_key, + .sta_add = carl9170_op_sta_add, + .sta_remove = carl9170_op_sta_remove, + .sta_notify = carl9170_op_sta_notify, + .get_survey = carl9170_op_get_survey, + .get_stats = carl9170_op_get_stats, + .ampdu_action = carl9170_op_ampdu_action, +}; + +void *carl9170_alloc(size_t priv_size) +{ + struct ieee80211_hw *hw; + struct ar9170 *ar; + struct sk_buff *skb; + int i; + + /* + * this buffer is used for rx stream reconstruction. + * Under heavy load this device (or the transport layer?) + * tends to split the streams into separate rx descriptors. + */ + + skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); + if (!skb) + goto err_nomem; + + hw = ieee80211_alloc_hw(priv_size, &carl9170_ops); + if (!hw) + goto err_nomem; + + ar = hw->priv; + ar->hw = hw; + ar->rx_failover = skb; + + memset(&ar->rx_plcp, 0, sizeof(struct ar9170_rx_head)); + ar->rx_has_plcp = false; + + /* + * Here's a hidden pitfall! + * + * All 4 AC queues work perfectly well under _legacy_ operation. + * However as soon as aggregation is enabled, the traffic flow + * gets very bumpy. Therefore we have to _switch_ to a + * software AC with a single HW queue. + */ + hw->queues = __AR9170_NUM_TXQ; + + mutex_init(&ar->mutex); + spin_lock_init(&ar->beacon_lock); + spin_lock_init(&ar->cmd_lock); + spin_lock_init(&ar->tx_stats_lock); + spin_lock_init(&ar->tx_ampdu_list_lock); + spin_lock_init(&ar->mem_lock); + spin_lock_init(&ar->state_lock); + atomic_set(&ar->pending_restarts, 0); + ar->vifs = 0; + for (i = 0; i < ar->hw->queues; i++) { + skb_queue_head_init(&ar->tx_status[i]); + skb_queue_head_init(&ar->tx_pending[i]); + } + INIT_WORK(&ar->ps_work, carl9170_ps_work); + INIT_WORK(&ar->restart_work, carl9170_restart_work); + INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); + INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); + INIT_LIST_HEAD(&ar->tx_ampdu_list); + rcu_assign_pointer(ar->tx_ampdu_iter, + (struct carl9170_sta_tid *) &ar->tx_ampdu_list); + + bitmap_zero(&ar->vif_bitmap, ar->fw.vif_num); + INIT_LIST_HEAD(&ar->vif_list); + init_completion(&ar->tx_flush); + + /* + * Note: + * IBSS/ADHOC and AP mode are only enabled, if the firmware + * supports these modes. The code which will add the + * additional interface_modes is in fw.c. + */ + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_SIGNAL_DBM; + + if (!modparam_noht) { + /* + * see the comment above, why we allow the user + * to disable HT by a module parameter. + */ + hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; + } + + hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe); + hw->sta_data_size = sizeof(struct carl9170_sta_info); + hw->vif_data_size = sizeof(struct carl9170_vif_info); + + hw->max_rates = CARL9170_TX_MAX_RATES; + hw->max_rate_tries = CARL9170_TX_USER_RATE_TRIES; + + for (i = 0; i < ARRAY_SIZE(ar->noise); i++) + ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ + + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + return ar; + +err_nomem: + kfree_skb(skb); + return ERR_PTR(-ENOMEM); +} + +static int carl9170_read_eeprom(struct ar9170 *ar) +{ +#define RW 8 /* number of words to read at once */ +#define RB (sizeof(u32) * RW) + u8 *eeprom = (void *)&ar->eeprom; + __le32 offsets[RW]; + int i, j, err; + + BUILD_BUG_ON(sizeof(ar->eeprom) & 3); + + BUILD_BUG_ON(RB > CARL9170_MAX_CMD_LEN - 4); +#ifndef __CHECKER__ + /* don't want to handle trailing remains */ + BUILD_BUG_ON(sizeof(ar->eeprom) % RB); +#endif + + for (i = 0; i < sizeof(ar->eeprom)/RB; i++) { + for (j = 0; j < RW; j++) + offsets[j] = cpu_to_le32(AR9170_EEPROM_START + + RB * i + 4 * j); + + err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, + RB, (u8 *) &offsets, + RB, eeprom + RB * i); + if (err) + return err; + } + +#undef RW +#undef RB + return 0; +} + +static int carl9170_parse_eeprom(struct ar9170 *ar) +{ + struct ath_regulatory *regulatory = &ar->common.regulatory; + unsigned int rx_streams, tx_streams, tx_params = 0; + int bands = 0; + + if (ar->eeprom.length == cpu_to_le16(0xffff)) + return -ENODATA; + + rx_streams = hweight8(ar->eeprom.rx_mask); + tx_streams = hweight8(ar->eeprom.tx_mask); + + if (rx_streams != tx_streams) { + tx_params = IEEE80211_HT_MCS_TX_RX_DIFF; + + WARN_ON(!(tx_streams >= 1 && tx_streams <= + IEEE80211_HT_MCS_TX_MAX_STREAMS)); + + tx_params = (tx_streams - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + + carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; + carl9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params; + } + + if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { + ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &carl9170_band_2GHz; + bands++; + } + if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { + ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &carl9170_band_5GHz; + bands++; + } + + /* + * I measured this, a bandswitch takes roughly + * 135 ms and a frequency switch about 80. + * + * FIXME: measure these values again once EEPROM settings + * are used, that will influence them! + */ + if (bands == 2) + ar->hw->channel_change_time = 135 * 1000; + else + ar->hw->channel_change_time = 80 * 1000; + + regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); + regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); + + /* second part of wiphy init */ + SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); + + return bands ? 0 : -EINVAL; +} + +static int carl9170_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ar9170 *ar = hw->priv; + + return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); +} + +int carl9170_register(struct ar9170 *ar) +{ + struct ath_regulatory *regulatory = &ar->common.regulatory; + int err = 0, i; + + if (WARN_ON(ar->mem_bitmap)) + return -EINVAL; + + ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) * + sizeof(unsigned long), GFP_KERNEL); + + if (!ar->mem_bitmap) + return -ENOMEM; + + /* try to read EEPROM, init MAC addr */ + err = carl9170_read_eeprom(ar); + if (err) + return err; + + err = carl9170_fw_fix_eeprom(ar); + if (err) + return err; + + err = carl9170_parse_eeprom(ar); + if (err) + return err; + + err = ath_regd_init(regulatory, ar->hw->wiphy, + carl9170_reg_notifier); + if (err) + return err; + + if (modparam_noht) { + carl9170_band_2GHz.ht_cap.ht_supported = false; + carl9170_band_5GHz.ht_cap.ht_supported = false; + } + + for (i = 0; i < ar->fw.vif_num; i++) { + ar->vif_priv[i].id = i; + ar->vif_priv[i].vif = NULL; + } + + err = ieee80211_register_hw(ar->hw); + if (err) + return err; + + /* mac80211 interface is now registered */ + ar->registered = true; + + if (!ath_is_world_regd(regulatory)) + regulatory_hint(ar->hw->wiphy, regulatory->alpha2); + +#ifdef CONFIG_CARL9170_DEBUGFS + carl9170_debugfs_register(ar); +#endif /* CONFIG_CARL9170_DEBUGFS */ + + err = carl9170_led_init(ar); + if (err) + goto err_unreg; + +#ifdef CONFIG_CARL9170_LEDS + err = carl9170_led_register(ar); + if (err) + goto err_unreg; +#endif /* CONFIG_CAR9L170_LEDS */ + +#ifdef CONFIG_CARL9170_WPC + err = carl9170_register_wps_button(ar); + if (err) + goto err_unreg; +#endif /* CONFIG_CARL9170_WPC */ + + dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n", + wiphy_name(ar->hw->wiphy)); + + return 0; + +err_unreg: + carl9170_unregister(ar); + return err; +} + +void carl9170_unregister(struct ar9170 *ar) +{ + if (!ar->registered) + return; + + ar->registered = false; + +#ifdef CONFIG_CARL9170_LEDS + carl9170_led_unregister(ar); +#endif /* CONFIG_CARL9170_LEDS */ + +#ifdef CONFIG_CARL9170_DEBUGFS + carl9170_debugfs_unregister(ar); +#endif /* CONFIG_CARL9170_DEBUGFS */ + +#ifdef CONFIG_CARL9170_WPC + if (ar->wps.pbc) { + input_unregister_device(ar->wps.pbc); + ar->wps.pbc = NULL; + } +#endif /* CONFIG_CARL9170_WPC */ + + carl9170_cancel_worker(ar); + cancel_work_sync(&ar->restart_work); + + ieee80211_unregister_hw(ar->hw); +} + +void carl9170_free(struct ar9170 *ar) +{ + WARN_ON(ar->registered); + WARN_ON(IS_INITIALIZED(ar)); + + kfree_skb(ar->rx_failover); + ar->rx_failover = NULL; + + kfree(ar->mem_bitmap); + ar->mem_bitmap = NULL; + + mutex_destroy(&ar->mutex); + + ieee80211_free_hw(ar->hw); +} diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h new file mode 100644 index 000000000000..0e917f80eab4 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -0,0 +1,7 @@ +#ifndef __CARL9170_SHARED_VERSION_H +#define __CARL9170_SHARED_VERSION_H +#define CARL9170FW_VERSION_YEAR 10 +#define CARL9170FW_VERSION_MONTH 8 +#define CARL9170FW_VERSION_DAY 30 +#define CARL9170FW_VERSION_GIT "1.8.8.1" +#endif /* __CARL9170_SHARED_VERSION_H */ -- cgit v1.2.3 From aae9af605a41cb3e9bbad15df72076423a22f903 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 01:06:57 +0200 Subject: carl9170: Register maps, tx/rx descriptor formats and eeprom layout Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/eeprom.h | 216 +++++++++ drivers/net/wireless/ath/carl9170/fwcmd.h | 268 +++++++++++ drivers/net/wireless/ath/carl9170/fwdesc.h | 237 ++++++++++ drivers/net/wireless/ath/carl9170/hw.h | 736 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/phy.h | 567 ++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/wlan.h | 412 ++++++++++++++++ 6 files changed, 2436 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/eeprom.h create mode 100644 drivers/net/wireless/ath/carl9170/fwcmd.h create mode 100644 drivers/net/wireless/ath/carl9170/fwdesc.h create mode 100644 drivers/net/wireless/ath/carl9170/hw.h create mode 100644 drivers/net/wireless/ath/carl9170/phy.h create mode 100644 drivers/net/wireless/ath/carl9170/wlan.h diff --git a/drivers/net/wireless/ath/carl9170/eeprom.h b/drivers/net/wireless/ath/carl9170/eeprom.h new file mode 100644 index 000000000000..7cff40ac7759 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/eeprom.h @@ -0,0 +1,216 @@ +/* + * Shared Atheros AR9170 Header + * + * EEPROM layout + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CARL9170_SHARED_EEPROM_H +#define __CARL9170_SHARED_EEPROM_H + +#define AR9170_EEPROM_START 0x1600 + +#define AR5416_MAX_CHAINS 2 +#define AR5416_MODAL_SPURS 5 + +struct ar9170_eeprom_modal { + __le32 antCtrlChain[AR5416_MAX_CHAINS]; + __le32 antCtrlCommon; + s8 antennaGainCh[AR5416_MAX_CHAINS]; + u8 switchSettling; + u8 txRxAttenCh[AR5416_MAX_CHAINS]; + u8 rxTxMarginCh[AR5416_MAX_CHAINS]; + s8 adcDesiredSize; + s8 pgaDesiredSize; + u8 xlnaGainCh[AR5416_MAX_CHAINS]; + u8 txEndToXpaOff; + u8 txEndToRxOn; + u8 txFrameToXpaOn; + u8 thresh62; + s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; + u8 xpdGain; + u8 xpd; + s8 iqCalICh[AR5416_MAX_CHAINS]; + s8 iqCalQCh[AR5416_MAX_CHAINS]; + u8 pdGainOverlap; + u8 ob; + u8 db; + u8 xpaBiasLvl; + u8 pwrDecreaseFor2Chain; + u8 pwrDecreaseFor3Chain; + u8 txFrameToDataStart; + u8 txFrameToPaOn; + u8 ht40PowerIncForPdadc; + u8 bswAtten[AR5416_MAX_CHAINS]; + u8 bswMargin[AR5416_MAX_CHAINS]; + u8 swSettleHt40; + u8 reserved[22]; + struct spur_channel { + __le16 spurChan; + u8 spurRangeLow; + u8 spurRangeHigh; + } __packed spur_channels[AR5416_MODAL_SPURS]; +} __packed; + +#define AR5416_NUM_PD_GAINS 4 +#define AR5416_PD_GAIN_ICEPTS 5 + +struct ar9170_calibration_data_per_freq { + u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; +} __packed; + +#define AR5416_NUM_5G_CAL_PIERS 8 +#define AR5416_NUM_2G_CAL_PIERS 4 + +#define AR5416_NUM_5G_TARGET_PWRS 8 +#define AR5416_NUM_2G_CCK_TARGET_PWRS 3 +#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 +#define AR5416_MAX_NUM_TGT_PWRS 8 + +struct ar9170_calibration_target_power_legacy { + u8 freq; + u8 power[4]; +} __packed; + +struct ar9170_calibration_target_power_ht { + u8 freq; + u8 power[8]; +} __packed; + +#define AR5416_NUM_CTLS 24 + +struct ar9170_calctl_edges { + u8 channel; +#define AR9170_CALCTL_EDGE_FLAGS 0xC0 + u8 power_flags; +} __packed; + +#define AR5416_NUM_BAND_EDGES 8 + +struct ar9170_calctl_data { + struct ar9170_calctl_edges + control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; +} __packed; + +struct ar9170_eeprom { + __le16 length; + __le16 checksum; + __le16 version; + u8 operating_flags; +#define AR9170_OPFLAG_5GHZ 1 +#define AR9170_OPFLAG_2GHZ 2 + u8 misc; + __le16 reg_domain[2]; + u8 mac_address[6]; + u8 rx_mask; + u8 tx_mask; + __le16 rf_silent; + __le16 bluetooth_options; + __le16 device_capabilities; + __le32 build_number; + u8 deviceType; + u8 reserved[33]; + + u8 customer_data[64]; + + struct ar9170_eeprom_modal + modal_header[2]; + + u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; + u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; + + struct ar9170_calibration_data_per_freq + cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], + cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; + + /* power calibration data */ + struct ar9170_calibration_target_power_legacy + cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; + struct ar9170_calibration_target_power_ht + cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], + cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; + + struct ar9170_calibration_target_power_legacy + cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], + cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; + struct ar9170_calibration_target_power_ht + cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], + cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; + + /* conformance testing limits */ + u8 ctl_index[AR5416_NUM_CTLS]; + struct ar9170_calctl_data + ctl_data[AR5416_NUM_CTLS]; + + u8 pad; + __le16 subsystem_id; +} __packed; + +#define AR9170_LED_MODE_POWER_ON 0x0001 +#define AR9170_LED_MODE_RESERVED 0x0002 +#define AR9170_LED_MODE_DISABLE_STATE 0x0004 +#define AR9170_LED_MODE_OFF_IN_PSM 0x0008 + +/* AR9170_LED_MODE BIT is set */ +#define AR9170_LED_MODE_FREQUENCY_S 4 +#define AR9170_LED_MODE_FREQUENCY 0x0030 +#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000 +#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010 +#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020 +#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030 + +/* AR9170_LED_MODE BIT is not set */ +#define AR9170_LED_MODE_CONN_STATE_S 4 +#define AR9170_LED_MODE_CONN_STATE 0x0030 +#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000 +#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010 +/* Idle off / Active on */ +#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020 +/* Idle on / Active off */ +#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010 + +#define AR9170_LED_MODE_MODE 0x0040 +#define AR9170_LED_MODE_RESERVED2 0x0080 + +#define AR9170_LED_MODE_TON_SCAN_S 8 +#define AR9170_LED_MODE_TON_SCAN 0x0f00 + +#define AR9170_LED_MODE_TOFF_SCAN_S 12 +#define AR9170_LED_MODE_TOFF_SCAN 0xf000 + +struct ar9170_led_mode { + __le16 led; +}; + +#endif /* __CARL9170_SHARED_EEPROM_H */ diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h new file mode 100644 index 000000000000..d4a4e1dbef06 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -0,0 +1,268 @@ +/* + * Shared Atheros AR9170 Header + * + * Firmware command interface definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_FWCMD_H +#define __CARL9170_SHARED_FWCMD_H + +#define CARL9170_MAX_CMD_LEN 64 +#define CARL9170_MAX_CMD_PAYLOAD_LEN 60 + +#define CARL9170FW_API_MIN_VER 1 +#define CARL9170FW_API_MAX_VER 1 + +enum carl9170_cmd_oids { + CARL9170_CMD_RREG = 0x00, + CARL9170_CMD_WREG = 0x01, + CARL9170_CMD_ECHO = 0x02, + CARL9170_CMD_SWRST = 0x03, + CARL9170_CMD_REBOOT = 0x04, + CARL9170_CMD_BCN_CTRL = 0x05, + CARL9170_CMD_READ_TSF = 0x06, + + /* CAM */ + CARL9170_CMD_EKEY = 0x10, + CARL9170_CMD_DKEY = 0x11, + + /* RF / PHY */ + CARL9170_CMD_FREQUENCY = 0x20, + CARL9170_CMD_RF_INIT = 0x21, + CARL9170_CMD_SYNTH = 0x22, + CARL9170_CMD_FREQ_START = 0x23, + CARL9170_CMD_PSM = 0x24, + + /* Asychronous command flag */ + CARL9170_CMD_ASYNC_FLAG = 0x40, + CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM | + CARL9170_CMD_ASYNC_FLAG), + + /* responses and traps */ + CARL9170_RSP_FLAG = 0xc0, + CARL9170_RSP_PRETBTT = 0xc0, + CARL9170_RSP_TXCOMP = 0xc1, + CARL9170_RSP_BEACON_CONFIG = 0xc2, + CARL9170_RSP_ATIM = 0xc3, + CARL9170_RSP_WATCHDOG = 0xc6, + CARL9170_RSP_TEXT = 0xca, + CARL9170_RSP_HEXDUMP = 0xcc, + CARL9170_RSP_RADAR = 0xcd, + CARL9170_RSP_GPIO = 0xce, + CARL9170_RSP_BOOT = 0xcf, +}; + +struct carl9170_set_key_cmd { + __le16 user; + __le16 keyId; + __le16 type; + u8 macAddr[6]; + u32 key[4]; +} __packed; +#define CARL9170_SET_KEY_CMD_SIZE 28 + +struct carl9170_disable_key_cmd { + __le16 user; + __le16 padding; +} __packed; +#define CARL9170_DISABLE_KEY_CMD_SIZE 4 + +struct carl9170_u32_list { + u32 vals[0]; +} __packed; + +struct carl9170_reg_list { + __le32 regs[0]; +} __packed; + +struct carl9170_write_reg { + struct { + __le32 addr; + __le32 val; + } regs[0] __packed; +} __packed; + +#define CARL9170FW_PHY_HT_ENABLE 0x4 +#define CARL9170FW_PHY_HT_DYN2040 0x8 +#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3 +#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2 + +struct carl9170_rf_init { + __le32 freq; + u8 ht_settings; + u8 padding2[3]; + __le32 delta_slope_coeff_exp; + __le32 delta_slope_coeff_man; + __le32 delta_slope_coeff_exp_shgi; + __le32 delta_slope_coeff_man_shgi; + __le32 finiteLoopCount; +} __packed; +#define CARL9170_RF_INIT_SIZE 28 + +struct carl9170_rf_init_result { + __le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */ +} __packed; +#define CARL9170_RF_INIT_RESULT_SIZE 4 + +#define CARL9170_PSM_SLEEP 0x1000 +#define CARL9170_PSM_SOFTWARE 0 +#define CARL9170_PSM_WAKE 0 /* internally used. */ +#define CARL9170_PSM_COUNTER 0xfff +#define CARL9170_PSM_COUNTER_S 0 + +struct carl9170_psm { + __le32 state; +} __packed; +#define CARL9170_PSM_SIZE 4 + +struct carl9170_bcn_ctrl_cmd { + __le32 vif_id; + __le32 mode; + __le32 bcn_addr; + __le32 bcn_len; +} __packed; +#define CARL9170_BCN_CTRL_CMD_SIZE 16 + +#define CARL9170_BCN_CTRL_DRAIN 0 +#define CARL9170_BCN_CTRL_CAB_TRIGGER 1 + +struct carl9170_cmd_head { + union { + struct { + u8 len; + u8 cmd; + u8 seq; + u8 ext; + } __packed; + + u32 hdr_data; + } __packed; +} __packed; + +struct carl9170_cmd { + struct carl9170_cmd_head hdr; + union { + struct carl9170_set_key_cmd setkey; + struct carl9170_disable_key_cmd disablekey; + struct carl9170_u32_list echo; + struct carl9170_reg_list rreg; + struct carl9170_write_reg wreg; + struct carl9170_rf_init rf_init; + struct carl9170_psm psm; + struct carl9170_bcn_ctrl_cmd bcn_ctrl; + u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; + } __packed; +} __packed; + +#define CARL9170_TX_STATUS_QUEUE 3 +#define CARL9170_TX_STATUS_QUEUE_S 0 +#define CARL9170_TX_STATUS_RIX_S 2 +#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S) +#define CARL9170_TX_STATUS_TRIES_S 4 +#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) +#define CARL9170_TX_STATUS_SUCCESS 0x80 + +/* + * NOTE: + * Both structs [carl9170_tx_status and _carl9170_tx_status] + * need to be "bit for bit" in sync. + */ +struct carl9170_tx_status { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 cookie; + u8 queue:2; + u8 rix:2; + u8 tries:3; + u8 success:1; +} __packed; +struct _carl9170_tx_status { + /* + * This version should be immune to all alignment bugs. + */ + + u8 cookie; + u8 info; +} __packed; +#define CARL9170_TX_STATUS_SIZE 2 + +#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \ + sizeof(struct _carl9170_tx_status)) + +#define CARL9170_TX_MAX_RATE_TRIES 7 + +#define CARL9170_TX_MAX_RATES 4 +#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1) +#define CARL9170_ERR_MAGIC "ERR:" +#define CARL9170_BUG_MAGIC "BUG:" + +struct carl9170_gpio { + __le32 gpio; +} __packed; +#define CARL9170_GPIO_SIZE 4 + +struct carl9170_tsf_rsp { + union { + __le32 tsf[2]; + __le64 tsf_64; + } __packed; +} __packed; +#define CARL9170_TSF_RSP_SIZE 8 + +struct carl9170_rsp { + struct carl9170_cmd_head hdr; + + union { + struct carl9170_rf_init_result rf_init_res; + struct carl9170_u32_list rreg_res; + struct carl9170_u32_list echo; + struct carl9170_tx_status tx_status[0]; + struct _carl9170_tx_status _tx_status[0]; + struct carl9170_gpio gpio; + struct carl9170_tsf_rsp tsf; + struct carl9170_psm psm; + u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; + } __packed; +} __packed; + +#endif /* __CARL9170_SHARED_FWCMD_H */ diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h new file mode 100644 index 000000000000..7cd811708fe5 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -0,0 +1,237 @@ +/* + * Shared CARL9170 Header + * + * Firmware descriptor format + * + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + */ + +#ifndef __CARL9170_SHARED_FWDESC_H +#define __CARL9170_SHARED_FWDESC_H + +/* NOTE: Don't mess with the order of the flags! */ +enum carl9170fw_feature_list { + /* Always set */ + CARL9170FW_DUMMY_FEATURE, + + /* + * Indicates that this image has special boot block which prevents + * legacy drivers to drive the firmware. + */ + CARL9170FW_MINIBOOT, + + /* usb registers are initialized by the firmware */ + CARL9170FW_USB_INIT_FIRMWARE, + + /* command traps & notifications are send through EP2 */ + CARL9170FW_USB_RESP_EP2, + + /* usb download (app -> fw) stream */ + CARL9170FW_USB_DOWN_STREAM, + + /* usb upload (fw -> app) stream */ + CARL9170FW_USB_UP_STREAM, + + /* unusable - reserved to flag non-functional debug firmwares */ + CARL9170FW_UNUSABLE, + + /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */ + CARL9170FW_COMMAND_PHY, + + /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */ + CARL9170FW_COMMAND_CAM, + + /* Firmware has a software Content After Beacon Queueing mechanism */ + CARL9170FW_WLANTX_CAB, + + /* The firmware is capable of responding to incoming BAR frames */ + CARL9170FW_HANDLE_BACK_REQ, + + /* GPIO Interrupt | CARL9170_RSP_GPIO */ + CARL9170FW_GPIO_INTERRUPT, + + /* Firmware PSM support | CARL9170_CMD_PSM */ + CARL9170FW_PSM, + + /* KEEP LAST */ + __CARL9170FW_FEATURE_NUM +}; + +#define OTUS_MAGIC "OTAR" +#define MOTD_MAGIC "MOTD" +#define FIX_MAGIC "FIX\0" +#define DBG_MAGIC "DBG\0" +#define CHK_MAGIC "CHK\0" +#define LAST_MAGIC "LAST" + +#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) +#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31) +#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372) + +#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1) +#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) +#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) + +struct carl9170fw_desc_head { + u8 magic[4]; + __le16 length; + u8 min_ver; + u8 cur_ver; +} __packed; +#define CARL9170FW_DESC_HEAD_SIZE \ + (sizeof(struct carl9170fw_desc_head)) + +#define CARL9170FW_OTUS_DESC_MIN_VER 6 +#define CARL9170FW_OTUS_DESC_CUR_VER 6 +struct carl9170fw_otus_desc { + struct carl9170fw_desc_head head; + __le32 feature_set; + __le32 fw_address; + __le32 bcn_addr; + __le16 bcn_len; + __le16 miniboot_size; + __le16 tx_frag_len; + __le16 rx_max_frame_len; + u8 tx_descs; + u8 cmd_bufs; + u8 api_ver; + u8 vif_num; +} __packed; +#define CARL9170FW_OTUS_DESC_SIZE \ + (sizeof(struct carl9170fw_otus_desc)) + +#define CARL9170FW_MOTD_STRING_LEN 24 +#define CARL9170FW_MOTD_RELEASE_LEN 20 +#define CARL9170FW_MOTD_DESC_MIN_VER 1 +#define CARL9170FW_MOTD_DESC_CUR_VER 2 +struct carl9170fw_motd_desc { + struct carl9170fw_desc_head head; + __le32 fw_year_month_day; + char desc[CARL9170FW_MOTD_STRING_LEN]; + char release[CARL9170FW_MOTD_RELEASE_LEN]; +} __packed; +#define CARL9170FW_MOTD_DESC_SIZE \ + (sizeof(struct carl9170fw_motd_desc)) + +#define CARL9170FW_FIX_DESC_MIN_VER 1 +#define CARL9170FW_FIX_DESC_CUR_VER 2 +struct carl9170fw_fix_entry { + __le32 address; + __le32 mask; + __le32 value; +} __packed; + +struct carl9170fw_fix_desc { + struct carl9170fw_desc_head head; + struct carl9170fw_fix_entry data[0]; +} __packed; +#define CARL9170FW_FIX_DESC_SIZE \ + (sizeof(struct carl9170fw_fix_desc)) + +#define CARL9170FW_DBG_DESC_MIN_VER 1 +#define CARL9170FW_DBG_DESC_CUR_VER 2 +struct carl9170fw_dbg_desc { + struct carl9170fw_desc_head head; + + __le32 bogoclock_addr; + __le32 counter_addr; + __le32 rx_total_addr; + __le32 rx_overrun_addr; + + /* Put your debugging definitions here */ +} __packed; +#define CARL9170FW_DBG_DESC_SIZE \ + (sizeof(struct carl9170fw_dbg_desc)) + +#define CARL9170FW_CHK_DESC_MIN_VER 1 +#define CARL9170FW_CHK_DESC_CUR_VER 2 +struct carl9170fw_chk_desc { + struct carl9170fw_desc_head head; + __le32 fw_crc32; + __le32 hdr_crc32; +} __packed; +#define CARL9170FW_CHK_DESC_SIZE \ + (sizeof(struct carl9170fw_chk_desc)) + +#define CARL9170FW_LAST_DESC_MIN_VER 1 +#define CARL9170FW_LAST_DESC_CUR_VER 2 +struct carl9170fw_last_desc { + struct carl9170fw_desc_head head; +} __packed; +#define CARL9170FW_LAST_DESC_SIZE \ + (sizeof(struct carl9170fw_fix_desc)) + +#define CARL9170FW_DESC_MAX_LENGTH 8192 + +#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \ + .head = { \ + .magic = _magic, \ + .length = cpu_to_le16(_length), \ + .min_ver = _min_ver, \ + .cur_ver = _cur_ver, \ + } + +static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, + u8 magic[4], __le16 length, + u8 min_ver, u8 cur_ver) +{ + head->magic[0] = magic[0]; + head->magic[1] = magic[1]; + head->magic[2] = magic[2]; + head->magic[3] = magic[3]; + + head->length = length; + head->min_ver = min_ver; + head->cur_ver = cur_ver; +} + +#define carl9170fw_for_each_hdr(desc, fw_desc) \ + for (desc = fw_desc; \ + memcmp(desc->magic, LAST_MAGIC, 4) && \ + le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ + le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ + desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) + +#define CHECK_HDR_VERSION(head, _min_ver) \ + (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ + +static inline bool carl9170fw_supports(__le32 list, u8 feature) +{ + return le32_to_cpu(list) & BIT(feature); +} + +static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, + const u8 descid[4], u16 min_len, + u8 compatible_revision) +{ + if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && + descid[2] == head->magic[2] && descid[3] == head->magic[3] && + !CHECK_HDR_VERSION(head, compatible_revision) && + (le16_to_cpu(head->length) >= min_len)) + return true; + + return false; +} + +#define CARL9170FW_MIN_SIZE 32 +#define CARL9170FW_MAX_SIZE 16384 + +static inline bool carl9170fw_size_check(unsigned int len) +{ + return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE); +} + +#endif /* __CARL9170_SHARED_FWDESC_H */ diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h new file mode 100644 index 000000000000..b1292ac5b703 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -0,0 +1,736 @@ +/* + * Shared Atheros AR9170 Header + * + * Register map, hardware-specific definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_HW_H +#define __CARL9170_SHARED_HW_H + +/* High Speed UART */ +#define AR9170_UART_REG_BASE 0x1c0000 + +/* Definitions of interrupt registers */ +#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000) +#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004) +#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010) +#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02 +#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04 + +#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014) +#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018) +#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01 +#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02 +#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10 +#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20 +#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40 + +#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c) +#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01 +#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02 +#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10 +#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20 +#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40 + +#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020) +#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01 +#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02 +#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08 +#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10 +#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20 +#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80 + +#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024) +#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028) +#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c) +#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034) +#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038) +#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c) +#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c) + +/* Timer */ +#define AR9170_TIMER_REG_BASE 0x1c1000 + +#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000) +#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010) +#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014) +#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018) +#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c) +#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020) +#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024) +#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100 + +#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028) +#define AR9170_TIMER_INT_TIMER0 0x001 +#define AR9170_TIMER_INT_TIMER1 0x002 +#define AR9170_TIMER_INT_TIMER2 0x004 +#define AR9170_TIMER_INT_TIMER3 0x008 +#define AR9170_TIMER_INT_TIMER4 0x010 +#define AR9170_TIMER_INT_TICK_TIMER 0x100 + +#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030) +#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040) +#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044) + +#define AR9170_MAC_REG_BASE 0x1c3000 + +#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500) +#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20 + +#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c) + +#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510) +#define AR9170_MAC_INT_TXC BIT(0) +#define AR9170_MAC_INT_RXC BIT(1) +#define AR9170_MAC_INT_RETRY_FAIL BIT(2) +#define AR9170_MAC_INT_WAKEUP BIT(3) +#define AR9170_MAC_INT_ATIM BIT(4) +#define AR9170_MAC_INT_DTIM BIT(5) +#define AR9170_MAC_INT_CFG_BCN BIT(6) +#define AR9170_MAC_INT_ABORT BIT(7) +#define AR9170_MAC_INT_QOS BIT(8) +#define AR9170_MAC_INT_MIMO_PS BIT(9) +#define AR9170_MAC_INT_KEY_GEN BIT(10) +#define AR9170_MAC_INT_DECRY_NOUSER BIT(11) +#define AR9170_MAC_INT_RADAR BIT(12) +#define AR9170_MAC_INT_QUIET_FRAME BIT(13) +#define AR9170_MAC_INT_PRETBTT BIT(14) + +#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) +#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) + +#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51c) +#define AR9170_MAC_ATIM_PERIOD_S 0 +#define AR9170_MAC_ATIM_PERIOD 0x0000ffff + +#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) +#define AR9170_MAC_BCN_PERIOD_S 0 +#define AR9170_MAC_BCN_PERIOD 0x0000ffff +#define AR9170_MAC_BCN_DTIM_S 16 +#define AR9170_MAC_BCN_DTIM 0x00ff0000 +#define AR9170_MAC_BCN_AP_MODE BIT(24) +#define AR9170_MAC_BCN_IBSS_MODE BIT(25) +#define AR9170_MAC_BCN_PWR_MGT BIT(26) +#define AR9170_MAC_BCN_STA_PS BIT(27) + +#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) +#define AR9170_MAC_PRETBTT_S 0 +#define AR9170_MAC_PRETBTT 0x0000ffff +#define AR9170_MAC_PRETBTT2_S 16 +#define AR9170_MAC_PRETBTT2 0xffff0000 + +#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) +#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) +#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) +#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) + +#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) +#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) + +#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62c) + +#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) +#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) +#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) +#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) +#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) +#define AR9170_MAC_REG_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648) +#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64c) + +#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) +#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) +#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0) +#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000 +#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) +#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3) +#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70 + +#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) +#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684) +#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) + +#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) +#define AR9170_MAC_FTF_ASSOC_REQ BIT(0) +#define AR9170_MAC_FTF_ASSOC_RESP BIT(1) +#define AR9170_MAC_FTF_REASSOC_REQ BIT(2) +#define AR9170_MAC_FTF_REASSOC_RESP BIT(3) +#define AR9170_MAC_FTF_PRB_REQ BIT(4) +#define AR9170_MAC_FTF_PRB_RESP BIT(5) +#define AR9170_MAC_FTF_BIT6 BIT(6) +#define AR9170_MAC_FTF_BIT7 BIT(7) +#define AR9170_MAC_FTF_BEACON BIT(8) +#define AR9170_MAC_FTF_ATIM BIT(9) +#define AR9170_MAC_FTF_DEASSOC BIT(10) +#define AR9170_MAC_FTF_AUTH BIT(11) +#define AR9170_MAC_FTF_DEAUTH BIT(12) +#define AR9170_MAC_FTF_BIT13 BIT(13) +#define AR9170_MAC_FTF_BIT14 BIT(14) +#define AR9170_MAC_FTF_BIT15 BIT(15) +#define AR9170_MAC_FTF_BAR BIT(24) +#define AR9170_MAC_FTF_BA BIT(25) +#define AR9170_MAC_FTF_PSPOLL BIT(26) +#define AR9170_MAC_FTF_RTS BIT(27) +#define AR9170_MAC_FTF_CTS BIT(28) +#define AR9170_MAC_FTF_ACK BIT(29) +#define AR9170_MAC_FTF_CFE BIT(30) +#define AR9170_MAC_FTF_CFE_ACK BIT(31) +#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff +#define AR9170_MAC_FTF_MONITOR 0xff00ffff + +#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) +#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694) +#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) +#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c) +#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6a0) +#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6a4) +#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6a8) +#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6ac) +#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6b0) +#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6bc) +#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0) +#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4) +#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8) +#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc) + +#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4) + +#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8) +#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec) + +#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0) +#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4) +#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8) + +#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700) +#define AR9170_MAC_CAM_IBSS 0xe0 +#define AR9170_MAC_CAM_AP 0xa1 +#define AR9170_MAC_CAM_STA 0x2 +#define AR9170_MAC_CAM_AP_WDS 0x3 +#define AR9170_MAC_CAM_DEFAULTS (0xf << 24) +#define AR9170_MAC_CAM_HOST_PENDING 0x80000000 + +#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) +#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) + +#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c) +#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000 +#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720) +#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724) +#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728) +#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c) + +#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730) +#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734) +#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738) +#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c) +#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000 +#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000 + +#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740) +#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750) + +#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760) +#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770) +#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780) +#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790) + +#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xb00) +#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xb04) +#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xb08) +#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xb0c) +#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xb10) +#define AR9170_MAC_REG_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14) +#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18) +#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c) +#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20) +#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24) +#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28) +#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c) +#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30) +#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34) +#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38) +#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c) +#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40) +#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15) +#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16) +#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17) +#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18) +#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19) +#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000) + +#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xb44) +#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xb48) + +#define AR9170_MAC_REG_AMPDU_COUNT (AR9170_MAC_REG_BASE + 0xb88) +#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c) + +#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c) +#define AR9170_MAC_AMPDU_FACTOR 0x7f0000 +#define AR9170_MAC_AMPDU_FACTOR_S 16 +#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0) +#define AR9170_MAC_AMPDU_DENSITY 0x7 +#define AR9170_MAC_AMPDU_DENSITY_S 0 + +#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xbb0) +#define AR9170_MAC_FCS_SWFCS 0x1 +#define AR9170_MAC_FCS_FIFO_PROT 0x4 + +#define AR9170_MAC_REG_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4) +#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8) + +#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00) +#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40) +#define AR9170_MAC_RX_CTRL_DEAGG 0x1 +#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2 +#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20 +#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28) +#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30) + +#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44) + +#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50) + +#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0) +#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4) +#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8) +#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac) +#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0) +#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4) +#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8) +#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc) +#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0) + +#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00) +#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) +#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00) +#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) +#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08) +#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c) +#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10) +#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14) +#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18) +#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c) +#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20) +#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24) +#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28) +#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c) + +#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30) +#define AR9170_DMA_TRIGGER_TXQ0 BIT(0) +#define AR9170_DMA_TRIGGER_TXQ1 BIT(1) +#define AR9170_DMA_TRIGGER_TXQ2 BIT(2) +#define AR9170_DMA_TRIGGER_TXQ3 BIT(3) +#define AR9170_DMA_TRIGGER_TXQ4 BIT(4) +#define AR9170_DMA_TRIGGER_RXQ BIT(8) + +#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38) +#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c) + +#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c) +#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f +#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 +#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 +#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 + +#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) +#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) +#define AR9170_MAC_BCN_LENGTH_MAX 256 + +#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) + +#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90) +#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94) +#define AR9170_BCN_CTRL_READY 0x01 +#define AR9170_BCN_CTRL_LOCK 0x02 + +#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98) +#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c) + + +#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0) +#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4) + +#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0) + +/* Random number generator */ +#define AR9170_RAND_REG_BASE 0x1d0000 + +#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000) +#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004) +#define AR9170_RAND_MODE_MANUAL 0x000 +#define AR9170_RAND_MODE_FREE 0x001 + +/* GPIO */ +#define AR9170_GPIO_REG_BASE 0x1d0100 +#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000) +#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004) +#define AR9170_GPIO_PORT_LED_0 1 +#define AR9170_GPIO_PORT_LED_1 2 +/* WPS Button GPIO for TP-Link TL-WN821N */ +#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4 + +/* Memory Controller */ +#define AR9170_MC_REG_BASE 0x1d1000 + +#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) +#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) +#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) +#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) + +/* Interrupt Controller */ +#define AR9170_MAX_INT_SRC 9 +#define AR9170_INT_REG_BASE 0x1d2000 + +#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000) +#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004) +#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008) +/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */ +#define AR9170_INT_FLAG_WLAN 0x001 +#define AR9170_INT_FLAG_PTAB_BIT 0x002 +#define AR9170_INT_FLAG_SE_BIT 0x004 +#define AR9170_INT_FLAG_UART_BIT 0x008 +#define AR9170_INT_FLAG_TIMER_BIT 0x010 +#define AR9170_INT_FLAG_EXT_BIT 0x020 +#define AR9170_INT_FLAG_SW_BIT 0x040 +#define AR9170_INT_FLAG_USB_BIT 0x080 +#define AR9170_INT_FLAG_ETHERNET_BIT 0x100 + +#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c) +#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010) +#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014) +#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018) +#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c) +#define AR9170_INT_SW_INT_ENABLE 0x1 + +#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020) +#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024) + +/* Power Management */ +#define AR9170_PWR_REG_BASE 0x1d4000 + +#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000) + +#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004) +#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0) +#define AR9170_PWR_RESET_WLAN_MASK BIT(1) +#define AR9170_PWR_RESET_DMA_MASK BIT(2) +#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3) +#define AR9170_PWR_RESET_AHB_MASK BIT(9) +#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10) +#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11) +#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12) +#define AR9170_PWR_RESET_PLL BIT(13) +#define AR9170_PWR_RESET_USB_PLL BIT(14) + +#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) +#define AR9170_PWR_CLK_AHB_40MHZ 0 +#define AR9170_PWR_CLK_AHB_20_22MHZ 1 +#define AR9170_PWR_CLK_AHB_40_44MHZ 2 +#define AR9170_PWR_CLK_AHB_80_88MHZ 3 +#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 + +#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010) +#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014) +#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020) + +/* Faraday USB Controller */ +#define AR9170_USB_REG_BASE 0x1e1000 + +#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000) +#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0) +#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2) +#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6) + +#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001) +#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7) + +#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002) +#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008) +#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b) +#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c) +#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c) +#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d) + +#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011) +#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012) +#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013) +#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014) +#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015) +#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6)) + +#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016) +#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017) +#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6) + +#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018) + +#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020) + +#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021) +#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022) +#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023) +#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024) +#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025) +#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026) +#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027) +#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028) + +#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030) +#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030) +#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031) +#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032) +#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033) +#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034) +#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035) +#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036) +#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037) +#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038) +#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) + +#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) +#define AR9170_USB_EP_IN_TOGGLE 0x10 + +#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) + +#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) +#define AR9170_USB_EP_OUT_TOGGLE 0x10 + +#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) + +#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae) +#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be) +#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af) +#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf) + +#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080) +#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080) +#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081) +#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082) +#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083) +#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084) +#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085) +#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086) +#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087) +#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088) +#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089) + +#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090) +#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090) +#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091) +#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092) +#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093) +#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094) +#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095) +#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096) +#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097) +#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098) +#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099) + +#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8) +#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc) + +#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100) +#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) +#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0) +#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1) +#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2) +#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3) +#define AR9170_USB_DMA_CTL_UP_STREAM_S 4 +#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5)) +#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0) +#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4) +#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5) +#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5)) +#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6) + +#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c) +#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8) +#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16) + +#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) +#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) +#define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0) +#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1)) + +/* PCI/USB to AHB Bridge */ +#define AR9170_PTA_REG_BASE 0x1e2000 + +#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000) +#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004) +#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008) +#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c) +#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010) +#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014) +#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018) +#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c) +#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020) +#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024) +#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028) +#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030) +#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034) +#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038) +#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c) + +#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) + +/* + * PCI to AHB Bridge + */ + +#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100) +#define AR9170_PTA_INT_FLAG_DN 0x01 +#define AR9170_PTA_INT_FLAG_UP 0x02 +#define AR9170_PTA_INT_FLAG_CMD 0x04 + +#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104) +#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108) +#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c) +#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110) +#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114) +#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118) +#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c) +#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120) +#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00 +#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01 +#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02 +#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10 + +#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) +#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128) +#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c) +#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130) +#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134) +#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138) +#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c) +#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140) +#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144) +#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148) +#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0) +#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1) + +/* Protocol Controller Module */ +#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00) + + +#define AR9170_NUM_LEDS 2 + +/* CAM */ +#define AR9170_CAM_MAX_USER 64 +#define AR9170_CAM_MAX_KEY_LENGTH 16 + +#define AR9170_SRAM_OFFSET 0x100000 +#define AR9170_SRAM_SIZE 0x18000 + +#define AR9170_PRAM_OFFSET 0x200000 +#define AR9170_PRAM_SIZE 0x8000 + +enum cpu_clock { + AHB_STATIC_40MHZ = 0, + AHB_GMODE_22MHZ = 1, + AHB_AMODE_20MHZ = 1, + AHB_GMODE_44MHZ = 2, + AHB_AMODE_40MHZ = 2, + AHB_GMODE_88MHZ = 3, + AHB_AMODE_80MHZ = 3 +}; + +/* USB endpoints */ +enum ar9170_usb_ep { + /* + * Control EP is always EP 0 (USB SPEC) + * + * The weird thing is: the original firmware has a few + * comments that suggest that the actual EP numbers + * are in the 1 to 10 range?! + */ + AR9170_USB_EP_CTRL = 0, + + AR9170_USB_EP_TX, + AR9170_USB_EP_RX, + AR9170_USB_EP_IRQ, + AR9170_USB_EP_CMD, + AR9170_USB_NUM_EXTRA_EP = 4, + + __AR9170_USB_NUM_EP, + + __AR9170_USB_NUM_MAX_EP = 10 +}; + +enum ar9170_usb_fifo { + __AR9170_USB_NUM_MAX_FIFO = 10 +}; + +enum ar9170_tx_queues { + AR9170_TXQ0 = 0, + AR9170_TXQ1, + AR9170_TXQ2, + AR9170_TXQ3, + AR9170_TXQ_SPECIAL, + + /* keep last */ + __AR9170_NUM_TX_QUEUES = 5 +}; + +#define AR9170_TX_STREAM_TAG 0x697e +#define AR9170_RX_STREAM_TAG 0x4e00 +#define AR9170_RX_STREAM_MAX_SIZE 0xffff + +struct ar9170_stream { + __le16 length; + __le16 tag; + + u8 payload[0]; +}; + +#define AR9170_MAX_ACKTABLE_ENTRIES 8 +#define AR9170_MAX_VIRTUAL_MAC 7 + +#define AR9170_USB_EP_CTRL_MAX 64 +#define AR9170_USB_EP_TX_MAX 512 +#define AR9170_USB_EP_RX_MAX 512 +#define AR9170_USB_EP_IRQ_MAX 64 +#define AR9170_USB_EP_CMD_MAX 64 + +/* Trigger PRETBTT interrupt 6 Kus earlier */ +#define CARL9170_PRETBTT_KUS 6 + +#define AR5416_MAX_RATE_POWER 63 + +#define SET_VAL(reg, value, newvalue) \ + (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) + +#define MOD_VAL(reg, value, newvalue) \ + (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) +#endif /* __CARL9170_SHARED_HW_H */ diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h new file mode 100644 index 000000000000..53c18d34ffcc --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/phy.h @@ -0,0 +1,567 @@ +/* + * Shared Atheros AR9170 Header + * + * PHY register map + * + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_PHY_H +#define __CARL9170_SHARED_PHY_H + +#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800) +#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \ + ((_n) << 2)) + +#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000) +#define AR9170_PHY_TEST_AGC_CLR 0x10000000 +#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000 + +#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004) +#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001 +#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002 +#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004 +#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008 +#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010 +/* For 25 MHz channel spacing -- not used but supported by hw */ +#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020 +#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040 +#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080 +#define AR9170_PHY_TURBO_FC_WALSH 0x00000100 +#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200 +#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800 + +#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008) + +#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010) +#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000 +#define AR9170_PHY_TIMING2_FORCE 0x00000fff +#define AR9170_PHY_TIMING2_FORCE_S 0 + +#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014) +#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000 +#define AR9170_PHY_TIMING3_DSC_EXP_S 13 +#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000 +#define AR9170_PHY_TIMING3_DSC_MAN_S 17 + +#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018) +#define AR9170_PHY_CHIP_ID_REV_0 0x80 +#define AR9170_PHY_CHIP_ID_REV_1 0x81 +#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0 + +#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c) +#define AR9170_PHY_ACTIVE_EN 0x00000001 +#define AR9170_PHY_ACTIVE_DIS 0x00000000 + +#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024) +#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff +#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0 +#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00 +#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8 + +#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028) +#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000 +#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16 + +#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c) +#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 +#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 +#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 +#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 +#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000 +#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 +#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16 + +#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030) +#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000 +#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001 + +#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034) +#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000 +#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 +#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000 +#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 +#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00 +#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 +#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff +#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 + +#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c) + +#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044) +#define AR9170_PHY_SETTLING_SWITCH 0x00003f80 +#define AR9170_PHY_SETTLING_SWITCH_S 7 + +#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048) +#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048) +#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000 +#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12 +#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000 +#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18 + +#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050) +#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff +#define AR9170_PHY_DESIRED_SZ_ADC_S 0 +#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00 +#define AR9170_PHY_DESIRED_SZ_PGA_S 8 +#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000 +#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20 + +#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058) +#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000 +#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12 +#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000 +#define AR9170_PHY_FIND_SIG_FIRPWR_S 18 + +#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c) +#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80 +#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7 +#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000 +#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15 + +#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060) +#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001 +#define AR9170_PHY_AGC_CONTROL_NF 0x00000002 +#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 +#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 +#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 + +#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) +#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CCA_MINCCA_PWR_S 19 +#define AR9170_PHY_CCA_THRESH62 0x0007f000 +#define AR9170_PHY_CCA_THRESH62_S 12 + +#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068) +#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f +#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0 +#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000 +#define AR9170_PHY_SFCORR_M1_THRESH_S 17 +#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000 +#define AR9170_PHY_SFCORR_M2_THRESH_S 24 + +#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c) +#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 +#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00 +#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 +#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000 +#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 +#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000 +#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 + +#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070) +#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074) +#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078) + +#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c) +#define AR9170_PHY_PLL_CTL_40 0xaa +#define AR9170_PHY_PLL_CTL_40_5413 0x04 +#define AR9170_PHY_PLL_CTL_44 0xab +#define AR9170_PHY_PLL_CTL_44_2133 0xeb +#define AR9170_PHY_PLL_CTL_40_2133 0xea + +#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100) +#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104) +#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108) +#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c) + +/* analogue power on time (100ns) */ +#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114) +#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118) +#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff + +#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \ + (0x0120 + ((_i) << 12))) +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 +#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000 +#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 +#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 + +#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124) +#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe +#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1 + +#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134) +#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138) +#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c) +#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 + +#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144) +#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038 +#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3 + +#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c) +#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18) +#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 +#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 +#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9) +#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 +#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 +#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f +#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 + +#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140) +#define AR9170_PHY_RADAR_EXT_ENA 0x00004000 + +#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154) +#define AR9170_PHY_RADAR_0_ENA 0x00000001 +#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000 +/* inband pulse threshold */ +#define AR9170_PHY_RADAR_0_INBAND 0x0000003e +#define AR9170_PHY_RADAR_0_INBAND_S 1 +/* pulse RSSI threshold */ +#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0 +#define AR9170_PHY_RADAR_0_PRSSI_S 6 +/* pulse height threshold */ +#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000 +#define AR9170_PHY_RADAR_0_HEIGHT_S 12 +/* radar RSSI threshold */ +#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000 +#define AR9170_PHY_RADAR_0_RRSSI_S 18 +/* radar firepower threshold */ +#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000 +#define AR9170_PHY_RADAR_0_FIRPWR_S 24 + +#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158) +#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000 +#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000 +#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000 +#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16 +#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000 +#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000 +#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 +#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00 +#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8 +#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff +#define AR9170_PHY_RADAR_1_MAXLEN_S 0 + +#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160) +#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160) + +#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164) + +#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168) + +#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c) +#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 +#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0 +#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8 +#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3 +#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00 +#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8 +#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 +#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13 + +#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170) +#define AR9170_PHY_RESTART_DIV_GC 0x001c0000 +#define AR9170_PHY_RESTART_DIV_GC_S 18 + +#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c) +#define AR9170_PHY_RFBUS_REQ_EN 0x00000001 + +#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180) +#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184) +#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff +#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0 + +#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188) +#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c) +#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190) +#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194) +#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff +#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0 + +#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198) +#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c) +#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff +#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0 + +#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0) +#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff +#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 +#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000 +#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20 +#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 +#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 + +#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4) +#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \ + 0x01b4 + ((_i) << 12)) +#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 +#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 + +#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac) +#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 +#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000 +#define AR9170_PHY_9285_ANT_DIV_CTL_S 24 +#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 +#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 +#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 +#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 +#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 +#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 +#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 +#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 +#define AR9170_PHY_9285_ANT_DIV_LNA1 2 +#define AR9170_PHY_9285_ANT_DIV_LNA2 1 +#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 +#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 +#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0 +#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1 + +#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8) +#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff +#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0 + +#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc) +#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00 +#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 +#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 +#define AR9170_PHY_EXT_CCA_THRESH62_S 16 +#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_EXT_MINCCA_PWR_S 23 + +#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) +#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7 +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000 +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 +#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 + +#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0) +#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0 +#define AR9170_PHY_HALFGI_DSC_MAN_S 4 +#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f +#define AR9170_PHY_HALFGI_DSC_EXP_S 0 + +#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4) +#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8) + +#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc) +#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 + +#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0) +#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec) +#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000 + +#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0) +#define AR9170_PHY_CALMODE_IQ 0x00000000 +#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001 +#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002 +#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003 + +#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4) +#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8) + + +#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \ + 0x0410 + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \ + 0x0414 \ + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \ + 0x0418 + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \ + 0x041c + ((_i) << 12)) + +#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c) + +#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420) +#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001 + +#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4) +#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 + +#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc) + +#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00) +#define AR9170_PHY_MODE_ASYNCFIFO 0x80 +#define AR9170_PHY_MODE_AR2133 0x08 +#define AR9170_PHY_MODE_AR5111 0x00 +#define AR9170_PHY_MODE_AR5112 0x08 +#define AR9170_PHY_MODE_DYNAMIC 0x04 +#define AR9170_PHY_MODE_RF2GHZ 0x02 +#define AR9170_PHY_MODE_RF5GHZ 0x00 +#define AR9170_PHY_MODE_CCK 0x01 +#define AR9170_PHY_MODE_OFDM 0x00 +#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100 + +#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04) +#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010 +#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c +#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 + +#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08) +#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f +#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 +/* [12:6] settling time for antenna switch */ +#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0 +#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 +#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 +#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 + +#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) +#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) +#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 +#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 +#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 +#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 +#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f +#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 + +#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c) +#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000 +#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 + +#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28) +#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 +#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00 +#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10 + +#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c) +#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 + +#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34) +#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38) + +#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c) +#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40) +#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44) +#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54) + +#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58) +#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 +#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14 +#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000 +#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16 +#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000 +#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18 +#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000 +#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20 +#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 +#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22 + +#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64) +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 + +#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68) +#define AR9170_PHY_ANALOG_SWAP_AB 0x0001 +#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040 + +#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c) +#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f +#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 + +#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70) +#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70) +#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 +#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 + +#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74) +#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000 +#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 + +#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c) +#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00 +#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10 +#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 +#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 + +#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00) +#define AR9170_PHY_TX_GAIN 0x0007f000 +#define AR9170_PHY_TX_GAIN_S 12 + +/* Carrier leak calibration control, do it after AGC calibration */ +#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58) +#define AR9170_PHY_CL_CAL_ENABLE 0x00000002 +#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001 + +#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c) +#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90) + +#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98) +#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98) +#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00 +#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10 + +#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c) +#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0) +#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4) +#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8) +#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac) +#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0) +#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4) +#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8) +#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc) +#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0) +#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4) +#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8) +#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc) +#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0) +#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4) +#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8) +#define AR9170_PHY_FORCE_XPA_CFG 0x000000001 +#define AR9170_PHY_FORCE_XPA_CFG_S 0 + +#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) +#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CH1_MINCCA_PWR_S 19 + +#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) +#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CH2_MINCCA_PWR_S 19 + +#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) +#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23 + +#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) +#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 + +#define REDUCE_CHAIN_0 0x00000050 +#define REDUCE_CHAIN_1 0x00000051 + +#endif /* __CARL9170_SHARED_PHY_H */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h new file mode 100644 index 000000000000..48ead2268f50 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -0,0 +1,412 @@ +/* + * Shared Atheros AR9170 Header + * + * RX/TX meta descriptor format + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_WLAN_H +#define __CARL9170_SHARED_WLAN_H + +#include "fwcmd.h" + +#define AR9170_RX_PHY_RATE_CCK_1M 0x0a +#define AR9170_RX_PHY_RATE_CCK_2M 0x14 +#define AR9170_RX_PHY_RATE_CCK_5M 0x37 +#define AR9170_RX_PHY_RATE_CCK_11M 0x6e + +#define AR9170_ENC_ALG_NONE 0x0 +#define AR9170_ENC_ALG_WEP64 0x1 +#define AR9170_ENC_ALG_TKIP 0x2 +#define AR9170_ENC_ALG_AESCCMP 0x4 +#define AR9170_ENC_ALG_WEP128 0x5 +#define AR9170_ENC_ALG_WEP256 0x6 +#define AR9170_ENC_ALG_CENC 0x7 + +#define AR9170_RX_ENC_SOFTWARE 0x8 + +#define AR9170_RX_STATUS_MODULATION 0x03 +#define AR9170_RX_STATUS_MODULATION_S 0 +#define AR9170_RX_STATUS_MODULATION_CCK 0x00 +#define AR9170_RX_STATUS_MODULATION_OFDM 0x01 +#define AR9170_RX_STATUS_MODULATION_HT 0x02 +#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 + +/* depends on modulation */ +#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 +#define AR9170_RX_STATUS_GREENFIELD 0x08 + +#define AR9170_RX_STATUS_MPDU 0x30 +#define AR9170_RX_STATUS_MPDU_S 4 +#define AR9170_RX_STATUS_MPDU_SINGLE 0x00 +#define AR9170_RX_STATUS_MPDU_FIRST 0x20 +#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 +#define AR9170_RX_STATUS_MPDU_LAST 0x10 + +#define AR9170_RX_ERROR_RXTO 0x01 +#define AR9170_RX_ERROR_OVERRUN 0x02 +#define AR9170_RX_ERROR_DECRYPT 0x04 +#define AR9170_RX_ERROR_FCS 0x08 +#define AR9170_RX_ERROR_WRONG_RA 0x10 +#define AR9170_RX_ERROR_PLCP 0x20 +#define AR9170_RX_ERROR_MMIC 0x40 +#define AR9170_RX_ERROR_FATAL 0x80 + +/* these are either-or */ +#define AR9170_TX_MAC_PROT_RTS 0x0001 +#define AR9170_TX_MAC_PROT_CTS 0x0002 +#define AR9170_TX_MAC_PROT 0x0003 + +#define AR9170_TX_MAC_NO_ACK 0x0004 +/* if unset, MAC will only do SIFS space before frame */ +#define AR9170_TX_MAC_BACKOFF 0x0008 +#define AR9170_TX_MAC_BURST 0x0010 +#define AR9170_TX_MAC_AGGR 0x0020 + +/* encryption is a two-bit field */ +#define AR9170_TX_MAC_ENCR_NONE 0x0000 +#define AR9170_TX_MAC_ENCR_RC4 0x0040 +#define AR9170_TX_MAC_ENCR_CENC 0x0080 +#define AR9170_TX_MAC_ENCR_AES 0x00c0 + +#define AR9170_TX_MAC_MMIC 0x0100 +#define AR9170_TX_MAC_HW_DURATION 0x0200 +#define AR9170_TX_MAC_QOS_S 10 +#define AR9170_TX_MAC_QOS 0x0c00 +#define AR9170_TX_MAC_DISABLE_TXOP 0x1000 +#define AR9170_TX_MAC_TXOP_RIFS 0x2000 +#define AR9170_TX_MAC_IMM_BA 0x4000 + +/* either-or */ +#define AR9170_TX_PHY_MOD_CCK 0x00000000 +#define AR9170_TX_PHY_MOD_OFDM 0x00000001 +#define AR9170_TX_PHY_MOD_HT 0x00000002 + +/* depends on modulation */ +#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 +#define AR9170_TX_PHY_GREENFIELD 0x00000004 + +#define AR9170_TX_PHY_BW_S 3 +#define AR9170_TX_PHY_BW (3 << AR9170_TX_PHY_BW_SHIFT) +#define AR9170_TX_PHY_BW_20MHZ 0 +#define AR9170_TX_PHY_BW_40MHZ 2 +#define AR9170_TX_PHY_BW_40MHZ_DUP 3 + +#define AR9170_TX_PHY_TX_HEAVY_CLIP_S 6 +#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \ + AR9170_TX_PHY_TX_HEAVY_CLIP_S) + +#define AR9170_TX_PHY_TX_PWR_S 9 +#define AR9170_TX_PHY_TX_PWR (0x3f << \ + AR9170_TX_PHY_TX_PWR_S) + +#define AR9170_TX_PHY_TXCHAIN_S 15 +#define AR9170_TX_PHY_TXCHAIN (7 << \ + AR9170_TX_PHY_TXCHAIN_S) +#define AR9170_TX_PHY_TXCHAIN_1 1 +/* use for cck, ofdm 6/9/12/18/24 and HT if capable */ +#define AR9170_TX_PHY_TXCHAIN_2 5 + +#define AR9170_TX_PHY_MCS_S 18 +#define AR9170_TX_PHY_MCS (0x7f << \ + AR9170_TX_PHY_MCS_S) + +#define AR9170_TX_PHY_RATE_CCK_1M 0x0 +#define AR9170_TX_PHY_RATE_CCK_2M 0x1 +#define AR9170_TX_PHY_RATE_CCK_5M 0x2 +#define AR9170_TX_PHY_RATE_CCK_11M 0x3 + +/* same as AR9170_RX_PHY_RATE */ +#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb +#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf +#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa +#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe +#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9 +#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd +#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8 +#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc + +#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0 +#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1 +#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2 +#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3 +#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4 +#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5 +#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6 +#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7 +#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8 +#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9 +#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa +#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb +#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc +#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd +#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe +#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf + +#define AR9170_TX_PHY_SHORT_GI 0x80000000 + +#ifdef __CARL9170FW__ +struct ar9170_tx_hw_mac_control { + union { + struct { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 erp_prot:2; + u8 no_ack:1; + u8 backoff:1; + u8 burst:1; + u8 ampdu:1; + + u8 enc_mode:2; + + u8 hw_mmic:1; + u8 hw_duration:1; + + u8 qos_queue:2; + + u8 disable_txop:1; + u8 txop_rifs:1; + + u8 ba_end:1; + u8 probe:1; + } __packed; + + __le16 set; + } __packed; +} __packed; + +struct ar9170_tx_hw_phy_control { + union { + struct { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 modulation:2; + u8 preamble:1; + u8 bandwidth:2; + u8:1; + u8 heavy_clip:3; + u8 tx_power:6; + u8 chains:3; + u8 mcs:7; + u8:6; + u8 short_gi:1; + } __packed; + + __le32 set; + } __packed; +} __packed; + +struct ar9170_tx_rate_info { + u8 tries:3; + u8 erp_prot:2; + u8 ampdu:1; + u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */ +} __packed; + +struct carl9170_tx_superdesc { + __le16 len; + u8 rix; + u8 cnt; + u8 cookie; + u8 ampdu_density:3; + u8 ampdu_factor:2; + u8 ampdu_commit_density:1; + u8 ampdu_commit_factor:1; + u8 ampdu_unused_bit:1; + u8 queue:2; + u8 reserved:1; + u8 vif_id:3; + u8 fill_in_tsf:1; + u8 cab:1; + u8 padding2; + struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES]; + struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES]; +} __packed; + +struct ar9170_tx_hwdesc { + __le16 length; + struct ar9170_tx_hw_mac_control mac; + struct ar9170_tx_hw_phy_control phy; +} __packed; + +struct ar9170_tx_frame { + struct ar9170_tx_hwdesc hdr; + + union { + struct ieee80211_hdr i3e; + u8 payload[0]; + } data; +} __packed; + +struct carl9170_tx_superframe { + struct carl9170_tx_superdesc s; + struct ar9170_tx_frame f; +} __packed; + +#endif /* __CARL9170FW__ */ + +struct _ar9170_tx_hwdesc { + __le16 length; + __le16 mac_control; + __le32 phy_control; +} __packed; + +#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0 +#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7 +#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18 +#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6 + +#define CARL9170_TX_SUPER_MISC_QUEUE 0x3 +#define CARL9170_TX_SUPER_MISC_QUEUE_S 0 +#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38 +#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3 +#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40 +#define CARL9170_TX_SUPER_MISC_CAB 0x80 + +#define CARL9170_TX_SUPER_RI_TRIES 0x7 +#define CARL9170_TX_SUPER_RI_TRIES_S 0 +#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18 +#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3 +#define CARL9170_TX_SUPER_RI_AMPDU 0x20 +#define CARL9170_TX_SUPER_RI_AMPDU_S 5 + +struct _carl9170_tx_superdesc { + __le16 len; + u8 rix; + u8 cnt; + u8 cookie; + u8 ampdu_settings; + u8 misc; + u8 padding; + u8 ri[CARL9170_TX_MAX_RATES]; + __le32 rr[CARL9170_TX_MAX_RETRY_RATES]; +} __packed; + +struct _carl9170_tx_superframe { + struct _carl9170_tx_superdesc s; + struct _ar9170_tx_hwdesc f; + u8 frame_data[0]; +} __packed; + +#define CARL9170_TX_SUPERDESC_LEN 24 +#define AR9170_TX_HWDESC_LEN 8 +#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \ + AR9170_TX_SUPERDESC_LEN) + +struct ar9170_rx_head { + u8 plcp[12]; +} __packed; + +struct ar9170_rx_phystatus { + union { + struct { + u8 rssi_ant0, rssi_ant1, rssi_ant2, + rssi_ant0x, rssi_ant1x, rssi_ant2x, + rssi_combined; + } __packed; + u8 rssi[7]; + } __packed; + + u8 evm_stream0[6], evm_stream1[6]; + u8 phy_err; +} __packed; + +struct ar9170_rx_macstatus { + u8 SAidx, DAidx; + u8 error; + u8 status; +} __packed; + +struct ar9170_rx_frame_single { + struct ar9170_rx_head phy_head; + struct ieee80211_hdr i3e; + struct ar9170_rx_phystatus phy_tail; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_head { + struct ar9170_rx_head phy_head; + struct ieee80211_hdr i3e; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_middle { + struct ieee80211_hdr i3e; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_tail { + struct ieee80211_hdr i3e; + struct ar9170_rx_phystatus phy_tail; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame { + union { + struct ar9170_rx_frame_single single; + struct ar9170_rx_frame_head head; + struct ar9170_rx_frame_middle middle; + struct ar9170_rx_frame_tail tail; + } __packed; +} __packed; + +static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) +{ + return (t->SAidx & 0xc0) >> 4 | + (t->DAidx & 0xc0) >> 6; +} + +enum ar9170_txq { + AR9170_TXQ_BE, + + AR9170_TXQ_VI, + AR9170_TXQ_VO, + AR9170_TXQ_BK, + + __AR9170_NUM_TXQ, +}; + +static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 }; + +#define AR9170_TXQ_DEPTH 32 + +#endif /* __CARL9170_SHARED_WLAN_H */ -- cgit v1.2.3 From 319da621d5c4e9bd8c34feeb200e864e87d91fe7 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 01:08:38 +0200 Subject: carl9170: PHY/RF and MAC routines Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/mac.c | 604 +++++++++++ drivers/net/wireless/ath/carl9170/phy.c | 1805 +++++++++++++++++++++++++++++++ 2 files changed, 2409 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/mac.c create mode 100644 drivers/net/wireless/ath/carl9170/phy.c diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c new file mode 100644 index 000000000000..2305bc27151c --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -0,0 +1,604 @@ +/* + * Atheros CARL9170 driver + * + * MAC programming + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) +{ + u32 val; + + if (conf_is_ht40(&ar->hw->conf)) + val = 0x010a; + else { + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) + val = 0x105; + else + val = 0x104; + } + + return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); +} + +int carl9170_set_rts_cts_rate(struct ar9170 *ar) +{ + u32 rts_rate, cts_rate; + + if (conf_is_ht(&ar->hw->conf)) { + /* 12 mbit OFDM */ + rts_rate = 0x1da; + cts_rate = 0x10a; + } else { + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + /* 11 mbit CCK */ + rts_rate = 033; + cts_rate = 003; + } else { + /* 6 mbit OFDM */ + rts_rate = 0x1bb; + cts_rate = 0x10b; + } + } + + return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE, + rts_rate | (cts_rate) << 16); +} + +int carl9170_set_slot_time(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 slottime = 20; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + if (!vif) { + rcu_read_unlock(); + return 0; + } + + if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || + vif->bss_conf.use_short_slot) + slottime = 9; + + rcu_read_unlock(); + + return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, + slottime << 10); +} + +int carl9170_set_mac_rates(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 basic, mandatory; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (!vif) { + rcu_read_unlock(); + return 0; + } + + basic = (vif->bss_conf.basic_rates & 0xf); + basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; + rcu_read_unlock(); + + if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) + mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ + else + mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic); + carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory); + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_set_qos(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | + (ar->edcf[0].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | + (ar->edcf[1].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | + (ar->edcf[2].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | + (ar->edcf[3].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | + (ar->edcf[4].cw_max << 16)); + + carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS, + ((ar->edcf[0].aifs * 9 + 10)) | + ((ar->edcf[1].aifs * 9 + 10) << 12) | + ((ar->edcf[2].aifs * 9 + 10) << 24)); + carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS, + ((ar->edcf[2].aifs * 9 + 10) >> 8) | + ((ar->edcf[3].aifs * 9 + 10) << 4) | + ((ar->edcf[4].aifs * 9 + 10) << 16)); + + carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, + ar->edcf[0].txop | ar->edcf[1].txop << 16); + carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, + ar->edcf[2].txop | ar->edcf[3].txop << 16 | + ar->edcf[4].txop << 24); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_init_mac(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + /* switch MAC to OTUS interface */ + carl9170_regwrite(0x1c3600, 0x3); + + carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); + + carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0); + + carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, + AR9170_MAC_FTF_MONITOR); + + /* enable MMIC */ + carl9170_regwrite(AR9170_MAC_REG_SNIFFER, + AR9170_MAC_SNIFFER_DEFAULTS); + + carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); + + carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); + carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); + carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); + + /* CF-END & CF-ACK rate => 24M OFDM */ + carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000); + + /* NAV protects ACK only (in TXOP) */ + carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201); + + /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ + /* OTUS set AM to 0x1 */ + carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); + + carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); + + /* Aggregation MAX number and timeout */ + carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa); + carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00); + + carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, + AR9170_MAC_FTF_DEFAULTS); + + carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, + AR9170_MAC_RX_CTRL_DEAGG | + AR9170_MAC_RX_CTRL_SHORT_FILTER); + + /* rate sets */ + carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); + carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033); + + /* MIMO response control */ + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e); + + carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); + + /* set PHY register read timeout (??) */ + carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); + + /* Disable Rx TimeOut, workaround for BB. */ + carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); + + /* Set WLAN DMA interrupt mode: generate int per packet */ + carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); + + carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT, + AR9170_MAC_FCS_FIFO_PROT); + + /* Disables the CF_END frame, undocumented register */ + carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, + 0x141e0f48); + + /* reset group hash table */ + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff); + + /* disable PRETBTT interrupt */ + carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0); + carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +static int carl9170_set_mac_reg(struct ar9170 *ar, + const u32 reg, const u8 *mac) +{ + static const u8 zero[ETH_ALEN] = { 0 }; + + if (!mac) + mac = zero; + + carl9170_regwrite_begin(ar); + + carl9170_regwrite(reg, get_unaligned_le32(mac)); + carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, + const u8 *mac) +{ + if (WARN_ON(id >= ar->fw.vif_num)) + return -EINVAL; + + return carl9170_set_mac_reg(ar, + AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac); +} + +int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) +{ + int err; + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + ar->cur_mc_hash = mc_hash; + return 0; +} + +int carl9170_set_operating_mode(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + struct ath_common *common = &ar->common; + u8 *mac_addr, *bssid; + u32 cam_mode = AR9170_MAC_CAM_DEFAULTS; + u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS; + u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | + AR9170_MAC_RX_CTRL_SHORT_FILTER; + u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; + int err = 0; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (vif) { + mac_addr = common->macaddr; + bssid = common->curbssid; + + switch (vif->type) { + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_ADHOC: + cam_mode |= AR9170_MAC_CAM_IBSS; + break; + case NL80211_IFTYPE_AP: + cam_mode |= AR9170_MAC_CAM_AP; + + /* iwlagn 802.11n STA Workaround */ + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + case NL80211_IFTYPE_WDS: + cam_mode |= AR9170_MAC_CAM_AP_WDS; + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + case NL80211_IFTYPE_STATION: + cam_mode |= AR9170_MAC_CAM_STA; + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + default: + WARN(1, "Unsupported operation mode %x\n", vif->type); + err = -EOPNOTSUPP; + break; + } + } else { + mac_addr = NULL; + bssid = NULL; + } + rcu_read_unlock(); + + if (err) + return err; + + if (ar->rx_software_decryption) + enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; + + if (ar->sniffer_enabled) { + rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; + sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; + enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; + } + + err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); + if (err) + return err; + + err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); + if (err) + return err; + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); + carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); + carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); + carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) +{ + u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); + + return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); +} + +int carl9170_set_beacon_timers(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 v = 0; + u32 pretbtt = 0; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (vif) { + struct carl9170_vif_info *mvif; + mvif = (void *) vif->drv_priv; + + if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { + ar->global_beacon_int = vif->bss_conf.beacon_int / + ar->beacon_enabled; + + SET_VAL(AR9170_MAC_BCN_DTIM, v, + vif->bss_conf.dtim_period); + + switch (vif->type) { + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_ADHOC: + v |= AR9170_MAC_BCN_IBSS_MODE; + break; + case NL80211_IFTYPE_AP: + v |= AR9170_MAC_BCN_AP_MODE; + break; + default: + WARN_ON_ONCE(1); + break; + } + } else if (vif->type == NL80211_IFTYPE_STATION) { + ar->global_beacon_int = vif->bss_conf.beacon_int; + + SET_VAL(AR9170_MAC_BCN_DTIM, v, + ar->hw->conf.ps_dtim_period); + + v |= AR9170_MAC_BCN_STA_PS | + AR9170_MAC_BCN_PWR_MGT; + } + + if (ar->global_beacon_int) { + if (ar->global_beacon_int < 15) { + rcu_read_unlock(); + return -ERANGE; + } + + ar->global_pretbtt = ar->global_beacon_int - + CARL9170_PRETBTT_KUS; + } else { + ar->global_pretbtt = 0; + } + } else { + ar->global_beacon_int = 0; + ar->global_pretbtt = 0; + } + + rcu_read_unlock(); + + SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); + SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); + SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); + carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +int carl9170_update_beacon(struct ar9170 *ar, const bool submit) +{ + struct sk_buff *skb; + struct carl9170_vif_info *cvif; + __le32 *data, *old = NULL; + u32 word, off, addr, len; + int i = 0, err = 0; + + rcu_read_lock(); + cvif = rcu_dereference(ar->beacon_iter); +retry: + if (ar->vifs == 0 || !cvif) + goto out_unlock; + + list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) { + if (cvif->active && cvif->enable_beacon) + goto found; + } + + if (!ar->beacon_enabled || i++) + goto out_unlock; + + goto retry; + +found: + rcu_assign_pointer(ar->beacon_iter, cvif); + + skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), + NULL, NULL); + + if (!skb) { + err = -ENOMEM; + goto out_unlock; + } + + spin_lock_bh(&ar->beacon_lock); + data = (__le32 *)skb->data; + if (cvif->beacon) + old = (__le32 *)cvif->beacon->data; + + off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX; + addr = ar->fw.beacon_addr + off; + len = roundup(skb->len + FCS_LEN, 4); + + if ((off + len) > ar->fw.beacon_max_len) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "beacon does not " + "fit into device memory!\n"); + } + + spin_unlock_bh(&ar->beacon_lock); + dev_kfree_skb_any(skb); + err = -EINVAL; + goto out_unlock; + } + + if (len > AR9170_MAC_BCN_LENGTH_MAX) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "no support for beacons " + "bigger than %d (yours:%d).\n", + AR9170_MAC_BCN_LENGTH_MAX, len); + } + + spin_unlock_bh(&ar->beacon_lock); + dev_kfree_skb_any(skb); + err = -EMSGSIZE; + goto out_unlock; + } + + carl9170_async_regwrite_begin(ar); + + /* XXX: use skb->cb info */ + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, + ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); + } else { + carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, + ((skb->len + FCS_LEN) << 16) + 0x001b); + } + + for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { + /* + * XXX: This accesses beyond skb data for up + * to the last 3 bytes!! + */ + + if (old && (data[i] == old[i])) + continue; + + word = le32_to_cpu(data[i]); + carl9170_async_regwrite(addr + 4 * i, word); + } + carl9170_async_regwrite_finish(); + + dev_kfree_skb_any(cvif->beacon); + cvif->beacon = NULL; + + err = carl9170_async_regwrite_result(); + if (!err) + cvif->beacon = skb; + spin_unlock_bh(&ar->beacon_lock); + if (err) + goto out_unlock; + + if (submit) { + err = carl9170_bcn_ctrl(ar, cvif->id, + CARL9170_BCN_CTRL_CAB_TRIGGER, + addr, skb->len + FCS_LEN); + + if (err) + goto out_unlock; + } +out_unlock: + rcu_read_unlock(); + return err; +} + +int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, + const u8 ktype, const u8 keyidx, const u8 *keydata, + const int keylen) +{ + struct carl9170_set_key_cmd key = { }; + static const u8 bcast[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + mac = mac ? : bcast; + + key.user = cpu_to_le16(id); + key.keyId = cpu_to_le16(keyidx); + key.type = cpu_to_le16(ktype); + memcpy(&key.macAddr, mac, ETH_ALEN); + if (keydata) + memcpy(&key.key, keydata, keylen); + + return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, + sizeof(key), (u8 *)&key, 0, NULL); +} + +int carl9170_disable_key(struct ar9170 *ar, const u8 id) +{ + struct carl9170_disable_key_cmd key = { }; + + key.user = cpu_to_le16(id); + + return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, + sizeof(key), (u8 *)&key, 0, NULL); +} diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c new file mode 100644 index 000000000000..47709c13d964 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -0,0 +1,1805 @@ +/* + * Atheros CARL9170 driver + * + * PHY and RF code + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "carl9170.h" +#include "cmd.h" +#include "phy.h" + +static int carl9170_init_power_cal(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f); + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +struct carl9170_phy_init { + u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20; +}; + +static struct carl9170_phy_init ar5416_phy_init[] = { + { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, }, + { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, }, + { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, }, + { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, }, + { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, }, + { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, }, + { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, + { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, }, + { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, + { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, + { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, }, + { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, }, + { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, + { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, + { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, + { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, }, + { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, + { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, + { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, }, + { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, + { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, + { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, + { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, }, + { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, }, + { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, }, + { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, }, + { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, }, + { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, + { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, }, + { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, }, + { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, }, + { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, }, + { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, }, + { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, }, + { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, }, + { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, }, + { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, }, + { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, + { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, + { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, + { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, + { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, + { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, }, + { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, + { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, + { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, }, + { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, }, + { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, }, + { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, }, + { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, }, + { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, }, + { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, }, + { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, }, + { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, }, + { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, }, + { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, }, + { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, }, + { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, }, + { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, }, + { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, + { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, }, + { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, }, + { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, }, + { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, }, + { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, }, + { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, }, + { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, }, + { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, }, + { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, }, + { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, }, + { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, }, + { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, }, + { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, }, + { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, }, + { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, }, + { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, }, + { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, }, + { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, }, + { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, }, + { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, }, + { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, }, + { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, }, + { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, }, + { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, }, + { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, }, + { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, }, + { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, }, + { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, }, + { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, }, + { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, }, + { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, }, + { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, + { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, }, + { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, }, + { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, }, + { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, }, + { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, }, + { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, }, + { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, }, + { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, + { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, }, + { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, }, + { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, }, + { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, }, + { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, }, + { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, }, + { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, }, + { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, + { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, }, + { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, }, + { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, }, + { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, }, + { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, }, + { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, }, + { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, }, + { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, }, + { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, }, + { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, + { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, }, + { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, }, + { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, }, + { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, }, + { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, }, + { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, }, + { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, }, + { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, }, + { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, }, + { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, }, + { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, + { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, + { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, }, + { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, }, + { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, }, + { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, }, + { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, }, + { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, }, + { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, }, + { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, }, + { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, }, + { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, }, + { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, }, + { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, }, + { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, }, + { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, }, + { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, }, + { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, + { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, }, + { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, }, + { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, }, + { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, }, + { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, + { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, }, + { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, }, + { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, }, + { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, }, + { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, }, + { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, }, + { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, }, + { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, }, + { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, }, + { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, }, + { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, }, + { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, }, + { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, }, + { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, }, + { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, }, + { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, }, + { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, }, + { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, }, + { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, + { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, + { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, + { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, + { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, + { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, +/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */ + { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, + { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, }, + { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, }, + { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, + { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, }, + { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, }, + { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, }, + { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, }, + { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, }, + { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, }, + { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, }, + { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, }, + { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, }, + { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, }, + { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, }, + { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } +}; + +/* + * look up a certain register in ar5416_phy_init[] and return the init. value + * for the band and bandwidth given. Return 0 if register address not found. + */ +static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { + if (ar5416_phy_init[i].reg != reg) + continue; + + if (is_2ghz) { + if (is_40mhz) + return ar5416_phy_init[i]._2ghz_40; + else + return ar5416_phy_init[i]._2ghz_20; + } else { + if (is_40mhz) + return ar5416_phy_init[i]._5ghz_40; + else + return ar5416_phy_init[i]._5ghz_20; + } + } + return 0; +} + +/* + * initialize some phy regs from eeprom values in modal_header[] + * acc. to band and bandwith + */ +static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, + bool is_2ghz, bool is_40mhz) +{ + static const u8 xpd2pd[16] = { + 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, + 0x2, 0x3, 0x7, 0x2, 0xb, 0x2, 0x2, 0x2 + }; + /* pointer to the modal_header acc. to band */ + struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz]; + u32 val; + + carl9170_regwrite_begin(ar); + + /* ant common control (index 0) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM, + le32_to_cpu(m->antCtrlCommon)); + + /* ant control chain 0 (index 1) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0, + le32_to_cpu(m->antCtrlChain[0])); + + /* ant control chain 2 (index 2) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2, + le32_to_cpu(m->antCtrlChain[1])); + + /* SwSettle (index 3) */ + if (!is_40mhz) { + val = carl9170_def_val(AR9170_PHY_REG_SETTLING, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling); + carl9170_regwrite(AR9170_PHY_REG_SETTLING, val); + } + + /* adcDesired, pdaDesired (index 4) */ + val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize); + SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize); + carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val); + + /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */ + val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff); + SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff); + SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn); + SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn); + carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val); + + /* TxEndToRxOn (index 6) */ + val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn); + carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val); + + /* thresh62 (index 7) */ + val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz); + val = (val & ~0x7f000) | (m->thresh62 << 12); + carl9170_regwrite(0x1c8864, val); + + /* tx/rx attenuation chain 0 (index 8) */ + val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]); + carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val); + + /* tx/rx attenuation chain 2 (index 9) */ + val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]); + carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val); + + /* tx/rx margin chain 0 (index 10) */ + val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]); + /* bsw margin chain 0 for 5GHz only */ + if (!is_2ghz) + SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]); + carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val); + + /* tx/rx margin chain 2 (index 11) */ + val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]); + carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val); + + /* iqCall, iqCallq chain 0 (index 12) */ + val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0), + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]); + carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val); + + /* iqCall, iqCallq chain 2 (index 13) */ + val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2), + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]); + carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val); + + /* xpd gain mask (index 14) */ + val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val, + xpd2pd[m->xpdGain & 0xf] & 3); + SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val, + xpd2pd[m->xpdGain & 0xf] >> 2); + carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val); + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) +{ + int i, err; + u32 val; + bool is_2ghz = band == IEEE80211_BAND_2GHZ; + bool is_40mhz = conf_is_ht40(&ar->hw->conf); + + carl9170_regwrite_begin(ar); + + for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { + if (is_40mhz) { + if (is_2ghz) + val = ar5416_phy_init[i]._2ghz_40; + else + val = ar5416_phy_init[i]._5ghz_40; + } else { + if (is_2ghz) + val = ar5416_phy_init[i]._2ghz_20; + else + val = ar5416_phy_init[i]._5ghz_20; + } + + carl9170_regwrite(ar5416_phy_init[i].reg, val); + } + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz); + if (err) + return err; + + err = carl9170_init_power_cal(ar); + if (err) + return err; + + /* XXX: remove magic! */ + if (is_2ghz) + err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5163); + else + err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5143); + + return err; +} + +struct carl9170_rf_initvals { + u32 reg, _5ghz, _2ghz; +}; + +static struct carl9170_rf_initvals carl9170_rf_initval[] = { + /* bank 0 */ + { 0x1c58b0, 0x1e5795e5, 0x1e5795e5}, + { 0x1c58e0, 0x02008020, 0x02008020}, + /* bank 1 */ + { 0x1c58b0, 0x02108421, 0x02108421}, + { 0x1c58ec, 0x00000008, 0x00000008}, + /* bank 2 */ + { 0x1c58b0, 0x0e73ff17, 0x0e73ff17}, + { 0x1c58e0, 0x00000420, 0x00000420}, + /* bank 3 */ + { 0x1c58f0, 0x01400018, 0x01c00018}, + /* bank 4 */ + { 0x1c58b0, 0x000001a1, 0x000001a1}, + { 0x1c58e8, 0x00000001, 0x00000001}, + /* bank 5 */ + { 0x1c58b0, 0x00000013, 0x00000013}, + { 0x1c58e4, 0x00000002, 0x00000002}, + /* bank 6 */ + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00002c00, 0x00002c00}, + { 0x1c58b0, 0x00004800, 0x00004800}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00006000, 0x00006000}, + { 0x1c58b0, 0x00001000, 0x00001000}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00087c00, 0x00087c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00005400, 0x00005400}, + { 0x1c58b0, 0x00000c00, 0x00000c00}, + { 0x1c58b0, 0x00001800, 0x00001800}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00002c00, 0x00002c00}, + { 0x1c58b0, 0x00003c00, 0x00003c00}, + { 0x1c58b0, 0x00003800, 0x00003800}, + { 0x1c58b0, 0x00001c00, 0x00001c00}, + { 0x1c58b0, 0x00000800, 0x00000800}, + { 0x1c58b0, 0x00000408, 0x00000408}, + { 0x1c58b0, 0x00004c15, 0x00004c15}, + { 0x1c58b0, 0x00004188, 0x00004188}, + { 0x1c58b0, 0x0000201e, 0x0000201e}, + { 0x1c58b0, 0x00010408, 0x00010408}, + { 0x1c58b0, 0x00000801, 0x00000801}, + { 0x1c58b0, 0x00000c08, 0x00000c08}, + { 0x1c58b0, 0x0000181e, 0x0000181e}, + { 0x1c58b0, 0x00001016, 0x00001016}, + { 0x1c58b0, 0x00002800, 0x00002800}, + { 0x1c58b0, 0x00004010, 0x00004010}, + { 0x1c58b0, 0x0000081c, 0x0000081c}, + { 0x1c58b0, 0x00000115, 0x00000115}, + { 0x1c58b0, 0x00000015, 0x00000015}, + { 0x1c58b0, 0x00000066, 0x00000066}, + { 0x1c58b0, 0x0000001c, 0x0000001c}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000004, 0x00000004}, + { 0x1c58b0, 0x00000015, 0x00000015}, + { 0x1c58b0, 0x0000001f, 0x0000001f}, + { 0x1c58e0, 0x00000000, 0x00000400}, + /* bank 7 */ + { 0x1c58b0, 0x000000a0, 0x000000a0}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000040, 0x00000040}, + { 0x1c58f0, 0x0000001c, 0x0000001c}, +}; + +static int carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) +{ + int err, i; + + carl9170_regwrite_begin(ar); + + for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++) + carl9170_regwrite(carl9170_rf_initval[i].reg, + band5ghz ? carl9170_rf_initval[i]._5ghz + : carl9170_rf_initval[i]._2ghz); + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + wiphy_err(ar->hw->wiphy, "rf init failed\n"); + + return err; +} + +struct carl9170_phy_freq_params { + u8 coeff_exp; + u16 coeff_man; + u8 coeff_exp_shgi; + u16 coeff_man_shgi; +}; + +enum carl9170_bw { + CARL9170_BW_20, + CARL9170_BW_40_BELOW, + CARL9170_BW_40_ABOVE, + + __CARL9170_NUM_BW, +}; + +struct carl9170_phy_freq_entry { + u16 freq; + struct carl9170_phy_freq_params params[__CARL9170_NUM_BW]; +}; + +/* NB: must be in sync with channel tables in main! */ +static const struct carl9170_phy_freq_entry carl9170_phy_freq_params[] = { +/* + * freq, + * 20MHz, + * 40MHz (below), + * 40Mhz (above), + */ + { 2412, { + { 3, 21737, 3, 19563, }, + { 3, 21827, 3, 19644, }, + { 3, 21647, 3, 19482, }, + } }, + { 2417, { + { 3, 21692, 3, 19523, }, + { 3, 21782, 3, 19604, }, + { 3, 21602, 3, 19442, }, + } }, + { 2422, { + { 3, 21647, 3, 19482, }, + { 3, 21737, 3, 19563, }, + { 3, 21558, 3, 19402, }, + } }, + { 2427, { + { 3, 21602, 3, 19442, }, + { 3, 21692, 3, 19523, }, + { 3, 21514, 3, 19362, }, + } }, + { 2432, { + { 3, 21558, 3, 19402, }, + { 3, 21647, 3, 19482, }, + { 3, 21470, 3, 19323, }, + } }, + { 2437, { + { 3, 21514, 3, 19362, }, + { 3, 21602, 3, 19442, }, + { 3, 21426, 3, 19283, }, + } }, + { 2442, { + { 3, 21470, 3, 19323, }, + { 3, 21558, 3, 19402, }, + { 3, 21382, 3, 19244, }, + } }, + { 2447, { + { 3, 21426, 3, 19283, }, + { 3, 21514, 3, 19362, }, + { 3, 21339, 3, 19205, }, + } }, + { 2452, { + { 3, 21382, 3, 19244, }, + { 3, 21470, 3, 19323, }, + { 3, 21295, 3, 19166, }, + } }, + { 2457, { + { 3, 21339, 3, 19205, }, + { 3, 21426, 3, 19283, }, + { 3, 21252, 3, 19127, }, + } }, + { 2462, { + { 3, 21295, 3, 19166, }, + { 3, 21382, 3, 19244, }, + { 3, 21209, 3, 19088, }, + } }, + { 2467, { + { 3, 21252, 3, 19127, }, + { 3, 21339, 3, 19205, }, + { 3, 21166, 3, 19050, }, + } }, + { 2472, { + { 3, 21209, 3, 19088, }, + { 3, 21295, 3, 19166, }, + { 3, 21124, 3, 19011, }, + } }, + { 2484, { + { 3, 21107, 3, 18996, }, + { 3, 21192, 3, 19073, }, + { 3, 21022, 3, 18920, }, + } }, + { 4920, { + { 4, 21313, 4, 19181, }, + { 4, 21356, 4, 19220, }, + { 4, 21269, 4, 19142, }, + } }, + { 4940, { + { 4, 21226, 4, 19104, }, + { 4, 21269, 4, 19142, }, + { 4, 21183, 4, 19065, }, + } }, + { 4960, { + { 4, 21141, 4, 19027, }, + { 4, 21183, 4, 19065, }, + { 4, 21098, 4, 18988, }, + } }, + { 4980, { + { 4, 21056, 4, 18950, }, + { 4, 21098, 4, 18988, }, + { 4, 21014, 4, 18912, }, + } }, + { 5040, { + { 4, 20805, 4, 18725, }, + { 4, 20846, 4, 18762, }, + { 4, 20764, 4, 18687, }, + } }, + { 5060, { + { 4, 20723, 4, 18651, }, + { 4, 20764, 4, 18687, }, + { 4, 20682, 4, 18614, }, + } }, + { 5080, { + { 4, 20641, 4, 18577, }, + { 4, 20682, 4, 18614, }, + { 4, 20601, 4, 18541, }, + } }, + { 5180, { + { 4, 20243, 4, 18219, }, + { 4, 20282, 4, 18254, }, + { 4, 20204, 4, 18183, }, + } }, + { 5200, { + { 4, 20165, 4, 18148, }, + { 4, 20204, 4, 18183, }, + { 4, 20126, 4, 18114, }, + } }, + { 5220, { + { 4, 20088, 4, 18079, }, + { 4, 20126, 4, 18114, }, + { 4, 20049, 4, 18044, }, + } }, + { 5240, { + { 4, 20011, 4, 18010, }, + { 4, 20049, 4, 18044, }, + { 4, 19973, 4, 17976, }, + } }, + { 5260, { + { 4, 19935, 4, 17941, }, + { 4, 19973, 4, 17976, }, + { 4, 19897, 4, 17907, }, + } }, + { 5280, { + { 4, 19859, 4, 17873, }, + { 4, 19897, 4, 17907, }, + { 4, 19822, 4, 17840, }, + } }, + { 5300, { + { 4, 19784, 4, 17806, }, + { 4, 19822, 4, 17840, }, + { 4, 19747, 4, 17772, }, + } }, + { 5320, { + { 4, 19710, 4, 17739, }, + { 4, 19747, 4, 17772, }, + { 4, 19673, 4, 17706, }, + } }, + { 5500, { + { 4, 19065, 4, 17159, }, + { 4, 19100, 4, 17190, }, + { 4, 19030, 4, 17127, }, + } }, + { 5520, { + { 4, 18996, 4, 17096, }, + { 4, 19030, 4, 17127, }, + { 4, 18962, 4, 17065, }, + } }, + { 5540, { + { 4, 18927, 4, 17035, }, + { 4, 18962, 4, 17065, }, + { 4, 18893, 4, 17004, }, + } }, + { 5560, { + { 4, 18859, 4, 16973, }, + { 4, 18893, 4, 17004, }, + { 4, 18825, 4, 16943, }, + } }, + { 5580, { + { 4, 18792, 4, 16913, }, + { 4, 18825, 4, 16943, }, + { 4, 18758, 4, 16882, }, + } }, + { 5600, { + { 4, 18725, 4, 16852, }, + { 4, 18758, 4, 16882, }, + { 4, 18691, 4, 16822, }, + } }, + { 5620, { + { 4, 18658, 4, 16792, }, + { 4, 18691, 4, 16822, }, + { 4, 18625, 4, 16762, }, + } }, + { 5640, { + { 4, 18592, 4, 16733, }, + { 4, 18625, 4, 16762, }, + { 4, 18559, 4, 16703, }, + } }, + { 5660, { + { 4, 18526, 4, 16673, }, + { 4, 18559, 4, 16703, }, + { 4, 18493, 4, 16644, }, + } }, + { 5680, { + { 4, 18461, 4, 16615, }, + { 4, 18493, 4, 16644, }, + { 4, 18428, 4, 16586, }, + } }, + { 5700, { + { 4, 18396, 4, 16556, }, + { 4, 18428, 4, 16586, }, + { 4, 18364, 4, 16527, }, + } }, + { 5745, { + { 4, 18252, 4, 16427, }, + { 4, 18284, 4, 16455, }, + { 4, 18220, 4, 16398, }, + } }, + { 5765, { + { 4, 18189, 5, 32740, }, + { 4, 18220, 4, 16398, }, + { 4, 18157, 5, 32683, }, + } }, + { 5785, { + { 4, 18126, 5, 32626, }, + { 4, 18157, 5, 32683, }, + { 4, 18094, 5, 32570, }, + } }, + { 5805, { + { 4, 18063, 5, 32514, }, + { 4, 18094, 5, 32570, }, + { 4, 18032, 5, 32458, }, + } }, + { 5825, { + { 4, 18001, 5, 32402, }, + { 4, 18032, 5, 32458, }, + { 4, 17970, 5, 32347, }, + } }, + { 5170, { + { 4, 20282, 4, 18254, }, + { 4, 20321, 4, 18289, }, + { 4, 20243, 4, 18219, }, + } }, + { 5190, { + { 4, 20204, 4, 18183, }, + { 4, 20243, 4, 18219, }, + { 4, 20165, 4, 18148, }, + } }, + { 5210, { + { 4, 20126, 4, 18114, }, + { 4, 20165, 4, 18148, }, + { 4, 20088, 4, 18079, }, + } }, + { 5230, { + { 4, 20049, 4, 18044, }, + { 4, 20088, 4, 18079, }, + { 4, 20011, 4, 18010, }, + } }, +}; + +static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, + u32 freq, enum carl9170_bw bw) +{ + int err; + u32 d0, d1, td0, td1, fd0, fd1; + u8 chansel; + u8 refsel0 = 1, refsel1 = 0; + u8 lf_synth = 0; + + switch (bw) { + case CARL9170_BW_40_ABOVE: + freq += 10; + break; + case CARL9170_BW_40_BELOW: + freq -= 10; + break; + case CARL9170_BW_20: + break; + default: + BUG(); + return -ENOSYS; + } + + if (band5ghz) { + if (freq % 10) { + chansel = (freq - 4800) / 5; + } else { + chansel = ((freq - 4800) / 10) * 2; + refsel0 = 0; + refsel1 = 1; + } + chansel = byte_rev_table[chansel]; + } else { + if (freq == 2484) { + chansel = 10 + (freq - 2274) / 5; + lf_synth = 1; + } else + chansel = 16 + (freq - 2272) / 5; + chansel *= 4; + chansel = byte_rev_table[chansel]; + } + + d1 = chansel; + d0 = 0x21 | + refsel0 << 3 | + refsel1 << 2 | + lf_synth << 1; + td0 = d0 & 0x1f; + td1 = d1 & 0x1f; + fd0 = td1 << 5 | td0; + + td0 = (d0 >> 5) & 0x7; + td1 = (d1 >> 5) & 0x7; + fd1 = td1 << 5 | td0; + + carl9170_regwrite_begin(ar); + + carl9170_regwrite(0x1c58b0, fd0); + carl9170_regwrite(0x1c58e8, fd1); + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + msleep(20); + + return 0; +} + +static const struct carl9170_phy_freq_params * +carl9170_get_hw_dyn_params(struct ieee80211_channel *channel, + enum carl9170_bw bw) +{ + unsigned int chanidx = 0; + u16 freq = 2412; + + if (channel) { + chanidx = channel->hw_value; + freq = channel->center_freq; + } + + BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params)); + + BUILD_BUG_ON(__CARL9170_NUM_BW != 3); + + WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq); + + return &carl9170_phy_freq_params[chanidx].params[bw]; +} + +static int carl9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f) +{ + int idx = nfreqs - 2; + + while (idx >= 0) { + if (f >= freqs[idx]) + return idx; + idx--; + } + + return 0; +} + +static s32 carl9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) +{ + /* nothing to interpolate, it's horizontal */ + if (y2 == y1) + return y1; + + /* check if we hit one of the edges */ + if (x == x1) + return y1; + if (x == x2) + return y2; + + /* x1 == x2 is bad, hopefully == x */ + if (x2 == x1) + return y1; + + return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1)); +} + +static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2) +{ +#define SHIFT 8 + s32 y; + + y = carl9170_interpolate_s32(x << SHIFT, x1 << SHIFT, + y1 << SHIFT, x2 << SHIFT, y2 << SHIFT); + + /* + * XXX: unwrap this expression + * Isn't it just DIV_ROUND_UP(y, 1<> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1)); +#undef SHIFT +} + +static u8 carl9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array) +{ + int i; + + for (i = 0; i < 3; i++) { + if (x <= x_array[i + 1]) + break; + } + + return carl9170_interpolate_u8(x, x_array[i], y_array[i], + x_array[i + 1], y_array[i + 1]); +} + +static int carl9170_set_freq_cal_data(struct ar9170 *ar, + struct ieee80211_channel *channel) +{ + u8 *cal_freq_pier; + u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; + u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; + int chain, idx, i; + u32 phy_data = 0; + u8 f, tmp; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + f = channel->center_freq - 2300; + cal_freq_pier = ar->eeprom.cal_freq_pier_2G; + i = AR5416_NUM_2G_CAL_PIERS - 1; + break; + + case IEEE80211_BAND_5GHZ: + f = (channel->center_freq - 4800) / 5; + cal_freq_pier = ar->eeprom.cal_freq_pier_5G; + i = AR5416_NUM_5G_CAL_PIERS - 1; + break; + + default: + return -EINVAL; + break; + } + + for (; i >= 0; i--) { + if (cal_freq_pier[i] != 0xff) + break; + } + if (i < 0) + return -EINVAL; + + idx = carl9170_find_freq_idx(i, cal_freq_pier, f); + + carl9170_regwrite_begin(ar); + + for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) { + for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) { + struct ar9170_calibration_data_per_freq *cal_pier_data; + int j; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + cal_pier_data = &ar->eeprom. + cal_pier_data_2G[chain][idx]; + break; + + case IEEE80211_BAND_5GHZ: + cal_pier_data = &ar->eeprom. + cal_pier_data_5G[chain][idx]; + break; + + default: + return -EINVAL; + } + + for (j = 0; j < 2; j++) { + vpds[j][i] = carl9170_interpolate_u8(f, + cal_freq_pier[idx], + cal_pier_data->vpd_pdg[j][i], + cal_freq_pier[idx + 1], + cal_pier_data[1].vpd_pdg[j][i]); + + pwrs[j][i] = carl9170_interpolate_u8(f, + cal_freq_pier[idx], + cal_pier_data->pwr_pdg[j][i], + cal_freq_pier[idx + 1], + cal_pier_data[1].pwr_pdg[j][i]) / 2; + } + } + + for (i = 0; i < 76; i++) { + if (i < 25) { + tmp = carl9170_interpolate_val(i, &pwrs[0][0], + &vpds[0][0]); + } else { + tmp = carl9170_interpolate_val(i - 12, + &pwrs[1][0], + &vpds[1][0]); + } + + phy_data |= tmp << ((i & 3) << 3); + if ((i & 3) == 3) { + carl9170_regwrite(0x1c6280 + chain * 0x1000 + + (i & ~3), phy_data); + phy_data = 0; + } + } + + for (i = 19; i < 32; i++) + carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2), + 0x0); + } + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +static u8 carl9170_get_max_edge_power(struct ar9170 *ar, + u32 freq, struct ar9170_calctl_edges edges[]) +{ + int i; + u8 rc = AR5416_MAX_RATE_POWER; + u8 f; + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800) / 5; + + for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { + if (edges[i].channel == 0xff) + break; + if (f == edges[i].channel) { + /* exact freq match */ + rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS; + break; + } + if (i > 0 && f < edges[i].channel) { + if (f > edges[i - 1].channel && + edges[i - 1].power_flags & + AR9170_CALCTL_EDGE_FLAGS) { + /* lower channel has the inband flag set */ + rc = edges[i - 1].power_flags & + ~AR9170_CALCTL_EDGE_FLAGS; + } + break; + } + } + + if (i == AR5416_NUM_BAND_EDGES) { + if (f > edges[i - 1].channel && + edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { + /* lower channel has the inband flag set */ + rc = edges[i - 1].power_flags & + ~AR9170_CALCTL_EDGE_FLAGS; + } + } + return rc; +} + +static u8 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw, struct ar9170_calctl_edges edges[]) +{ + u8 f; + int i; + u8 rc = 0; + + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800) / 5; + + if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_BW_40_ABOVE) + rc |= 0xf0; + + for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { + if (edges[i].channel == 0xff) + break; + if (f == edges[i].channel) { + if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) + rc |= 0x0f; + break; + } + } + + return rc; +} + +/* + * calculate the conformance test limits and the heavy clip parameter + * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) + */ +static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) +{ + u8 ctl_grp; /* CTL group */ + u8 ctl_idx; /* CTL index */ + int i, j; + struct ctl_modes { + u8 ctl_mode; + u8 max_power; + u8 *pwr_cal_data; + int pwr_cal_len; + } *modes; + + /* + * order is relevant in the mode_list_*: we fall back to the + * lower indices if any mode is missed in the EEPROM. + */ + struct ctl_modes mode_list_2ghz[] = { + { CTL_11B, 0, ar->power_2G_cck, 4 }, + { CTL_11G, 0, ar->power_2G_ofdm, 4 }, + { CTL_2GHT20, 0, ar->power_2G_ht20, 8 }, + { CTL_2GHT40, 0, ar->power_2G_ht40, 8 }, + }; + struct ctl_modes mode_list_5ghz[] = { + { CTL_11A, 0, ar->power_5G_leg, 4 }, + { CTL_5GHT20, 0, ar->power_5G_ht20, 8 }, + { CTL_5GHT40, 0, ar->power_5G_ht40, 8 }, + }; + int nr_modes; + +#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) + + ar->heavy_clip = 0; + + /* + * TODO: investigate the differences between OTUS' + * hpreg.c::zfHpGetRegulatoryDomain() and + * ath/regd.c::ath_regd_get_band_ctl() - + * e.g. for FCC3_WORLD the OTUS procedure + * always returns CTL_FCC, while the one in ath/ delivers + * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. + */ + ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, + ar->hw->conf.channel->band); + + /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ + if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) + ctl_grp = CTL_FCC; + + if (ctl_grp != CTL_FCC) + /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ + return; + + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + modes = mode_list_2ghz; + nr_modes = ARRAY_SIZE(mode_list_2ghz); + } else { + modes = mode_list_5ghz; + nr_modes = ARRAY_SIZE(mode_list_5ghz); + } + + for (i = 0; i < nr_modes; i++) { + u8 c = ctl_grp | modes[i].ctl_mode; + for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++) + if (c == ar->eeprom.ctl_index[ctl_idx]) + break; + if (ctl_idx < AR5416_NUM_CTLS) { + int f_off = 0; + + /* + * determine heavy clip parameter + * from the 11G edges array + */ + if (modes[i].ctl_mode == CTL_11G) { + ar->heavy_clip = + carl9170_get_heavy_clip(ar, + freq, bw, EDGES(ctl_idx, 1)); + } + + /* adjust freq for 40MHz */ + if (modes[i].ctl_mode == CTL_2GHT40 || + modes[i].ctl_mode == CTL_5GHT40) { + if (bw == CARL9170_BW_40_BELOW) + f_off = -10; + else + f_off = 10; + } + + modes[i].max_power = + carl9170_get_max_edge_power(ar, + freq+f_off, EDGES(ctl_idx, 1)); + + /* + * TODO: check if the regulatory max. power is + * controlled by cfg80211 for DFS. + * (hpmain applies it to max_power itself for DFS freq) + */ + + } else { + /* + * Workaround in otus driver, hpmain.c, line 3906: + * if no data for 5GHT20 are found, take the + * legacy 5G value. We extend this here to fallback + * from any other HT* or 11G, too. + */ + int k = i; + + modes[i].max_power = AR5416_MAX_RATE_POWER; + while (k-- > 0) { + if (modes[k].max_power != + AR5416_MAX_RATE_POWER) { + modes[i].max_power = modes[k].max_power; + break; + } + } + } + + /* apply max power to pwr_cal_data (ar->power_*) */ + for (j = 0; j < modes[i].pwr_cal_len; j++) { + modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j], + modes[i].max_power); + } + } + + if (ar->heavy_clip & 0xf0) { + ar->power_2G_ht40[0]--; + ar->power_2G_ht40[1]--; + ar->power_2G_ht40[2]--; + } + if (ar->heavy_clip & 0xf) { + ar->power_2G_ht20[0]++; + ar->power_2G_ht20[1]++; + ar->power_2G_ht20[2]++; + } + +#undef EDGES +} + +static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw) +{ + struct ar9170_calibration_target_power_legacy *ctpl; + struct ar9170_calibration_target_power_ht *ctph; + u8 *ctpres; + int ntargets; + int idx, i, n; + u8 ackpower, ackchains, f; + u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; + + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800)/5; + + /* + * cycle through the various modes + * + * legacy modes first: 5G, 2G CCK, 2G OFDM + */ + for (i = 0; i < 3; i++) { + switch (i) { + case 0: /* 5 GHz legacy */ + ctpl = &ar->eeprom.cal_tgt_pwr_5G[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_leg; + break; + case 1: /* 2.4 GHz CCK */ + ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0]; + ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS; + ctpres = ar->power_2G_cck; + break; + case 2: /* 2.4 GHz OFDM */ + ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ofdm; + break; + default: + BUG(); + } + + for (n = 0; n < ntargets; n++) { + if (ctpl[n].freq == 0xff) + break; + pwr_freqs[n] = ctpl[n].freq; + } + ntargets = n; + idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); + for (n = 0; n < 4; n++) + ctpres[n] = carl9170_interpolate_u8(f, + ctpl[idx + 0].freq, ctpl[idx + 0].power[n], + ctpl[idx + 1].freq, ctpl[idx + 1].power[n]); + } + + /* HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 */ + for (i = 0; i < 4; i++) { + switch (i) { + case 0: /* 5 GHz HT 20 */ + ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_ht20; + break; + case 1: /* 5 GHz HT 40 */ + ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_ht40; + break; + case 2: /* 2.4 GHz HT 20 */ + ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ht20; + break; + case 3: /* 2.4 GHz HT 40 */ + ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ht40; + break; + default: + BUG(); + } + + for (n = 0; n < ntargets; n++) { + if (ctph[n].freq == 0xff) + break; + pwr_freqs[n] = ctph[n].freq; + } + ntargets = n; + idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); + for (n = 0; n < 8; n++) + ctpres[n] = carl9170_interpolate_u8(f, + ctph[idx + 0].freq, ctph[idx + 0].power[n], + ctph[idx + 1].freq, ctph[idx + 1].power[n]); + } + + /* calc. conformance test limits and apply to ar->power*[] */ + carl9170_calc_ctl(ar, freq, bw); + + /* set ACK/CTS TX power */ + carl9170_regwrite_begin(ar); + + if (ar->eeprom.tx_mask != 1) + ackchains = AR9170_TX_PHY_TXCHAIN_2; + else + ackchains = AR9170_TX_PHY_TXCHAIN_1; + + if (freq < 3000) + ackpower = ar->power_2G_ofdm[0] & 0x3f; + else + ackpower = ar->power_5G_leg[0] & 0x3f; + + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, + 0x3c1e | ackpower << 20 | ackchains << 26); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, + ackpower << 5 | ackchains << 11 | + ackpower << 21 | ackchains << 27); + + carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, + ackpower << 5 | ackchains << 11 | + ackpower << 21 | ackchains << 27); + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +/* TODO: replace this with sign_extend32(noise, 8) */ +static int carl9170_calc_noise_dbm(u32 raw_noise) +{ + if (raw_noise & 0x100) + return ~((raw_noise & 0x0ff) >> 1); + else + return (raw_noise & 0xff) >> 1; +} + +int carl9170_get_noisefloor(struct ar9170 *ar) +{ + static const u32 phy_regs[] = { + AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH1_CCA, + AR9170_PHY_REG_CH2_CCA, AR9170_PHY_REG_EXT_CCA, + AR9170_PHY_REG_CH1_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA }; + u32 phy_res[ARRAY_SIZE(phy_regs)]; + int err, i; + + BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise)); + + err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res); + if (err) + return err; + + for (i = 0; i < 3; i++) { + ar->noise[i] = carl9170_calc_noise_dbm( + (phy_res[i] >> 19) & 0x1ff); + + ar->noise[i + 3] = carl9170_calc_noise_dbm( + (phy_res[i + 3] >> 23) & 0x1ff); + } + + return 0; +} + +static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type) +{ + switch (type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + return CARL9170_BW_20; + case NL80211_CHAN_HT40MINUS: + return CARL9170_BW_40_BELOW; + case NL80211_CHAN_HT40PLUS: + return CARL9170_BW_40_ABOVE; + default: + BUG(); + } +} + +int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, + enum nl80211_channel_type _bw, + enum carl9170_rf_init_mode rfi) +{ + const struct carl9170_phy_freq_params *freqpar; + struct carl9170_rf_init_result rf_res; + struct carl9170_rf_init rf; + u32 cmd, tmp, offs = 0; + int err; + enum carl9170_bw bw; + bool warm_reset; + struct ieee80211_channel *old_channel = NULL; + + bw = nl80211_to_carl(_bw); + + /* may be NULL at first setup */ + if (ar->channel) { + old_channel = ar->channel; + warm_reset = (old_channel->band != channel->band) || + (old_channel->center_freq == + channel->center_freq); + + ar->channel = NULL; + } else { + warm_reset = true; + } + + /* HW workaround */ + if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && + channel->center_freq <= 2417) + warm_reset = true; + + if (rfi != CARL9170_RFI_NONE || warm_reset) { + u32 val; + + if (rfi == CARL9170_RFI_COLD) + val = AR9170_PWR_RESET_BB_COLD_RESET; + else + val = AR9170_PWR_RESET_BB_WARM_RESET; + + /* warm/cold reset BB/ADDA */ + err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val); + if (err) + return err; + + err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0); + if (err) + return err; + + err = carl9170_init_phy(ar, channel->band); + if (err) + return err; + + err = carl9170_init_rf_banks_0_7(ar, + channel->band == IEEE80211_BAND_5GHZ); + if (err) + return err; + + cmd = CARL9170_CMD_RF_INIT; + + msleep(100); + + err = carl9170_echo_test(ar, 0xaabbccdd); + if (err) + return err; + } else { + cmd = CARL9170_CMD_FREQUENCY; + } + + err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL); + if (err) + return err; + + err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, + 0x200); + + err = carl9170_init_rf_bank4_pwr(ar, + channel->band == IEEE80211_BAND_5GHZ, + channel->center_freq, bw); + if (err) + return err; + + tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 | + AR9170_PHY_TURBO_FC_HT_EN; + + switch (bw) { + case CARL9170_BW_20: + break; + case CARL9170_BW_40_BELOW: + tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | + AR9170_PHY_TURBO_FC_SHORT_GI_40; + offs = 3; + break; + case CARL9170_BW_40_ABOVE: + tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | + AR9170_PHY_TURBO_FC_SHORT_GI_40 | + AR9170_PHY_TURBO_FC_DYN2040_PRI_CH; + offs = 1; + break; + default: + BUG(); + return -ENOSYS; + } + + if (ar->eeprom.tx_mask != 1) + tmp |= AR9170_PHY_TURBO_FC_WALSH; + + err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp); + if (err) + return err; + + err = carl9170_set_freq_cal_data(ar, channel); + if (err) + return err; + + err = carl9170_set_power_cal(ar, channel->center_freq, bw); + if (err) + return err; + + freqpar = carl9170_get_hw_dyn_params(channel, bw); + + rf.ht_settings = 0; + if (conf_is_ht(&ar->hw->conf)) { + rf.ht_settings |= CARL9170FW_PHY_HT_ENABLE; + + if (conf_is_ht40(&ar->hw->conf)) { + rf.ht_settings |= CARL9170FW_PHY_HT_DYN2040; + SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, + rf.ht_settings, offs); + } + } + + rf.freq = cpu_to_le32(channel->center_freq * 1000); + rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp); + rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man); + rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi); + rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi); + + if (rfi != CARL9170_RFI_NONE) + rf.finiteLoopCount = cpu_to_le32(2000); + else + rf.finiteLoopCount = cpu_to_le32(1000); + + err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf, + sizeof(rf_res), &rf_res); + if (err) + return err; + + err = le32_to_cpu(rf_res.ret); + if (err != 0) { + ar->chan_fail++; + ar->total_chan_fail++; + + wiphy_err(ar->hw->wiphy, "channel change: %d -> %d " + "failed (%d).\n", old_channel ? + old_channel->center_freq : -1, channel->center_freq, + err); + + if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) { + /* + * We have tried very hard to change to _another_ + * channel and we've failed to do so! + * Chances are that the PHY/RF is no longer + * operable (due to corruptions/fatal events/bugs?) + * and we need to reset at a higher level. + */ + carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS); + return 0; + } + + err = carl9170_set_channel(ar, channel, _bw, + CARL9170_RFI_COLD); + if (err) + return err; + } else { + ar->chan_fail = 0; + } + + err = carl9170_get_noisefloor(ar); + if (err) + return err; + + if (ar->heavy_clip) { + err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, + 0x200 | ar->heavy_clip); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "failed to set " + "heavy clip\n"); + } + + return err; + } + } + + /* FIXME: PSM does not work in 5GHz Band */ + if (channel->band == IEEE80211_BAND_5GHZ) + ar->ps.off_override |= PS_OFF_5GHZ; + else + ar->ps.off_override &= ~PS_OFF_5GHZ; + + ar->channel = channel; + return 0; +} -- cgit v1.2.3 From a84fab3cbfdc427e7d366f1cc844f27b2084c26c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 01:09:20 +0200 Subject: carl9170: 802.11 rx/tx processing and usb backend Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/rx.c | 909 ++++++++++++++++++++ drivers/net/wireless/ath/carl9170/tx.c | 1373 +++++++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/usb.c | 1137 +++++++++++++++++++++++++ 3 files changed, 3419 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/rx.c create mode 100644 drivers/net/wireless/ath/carl9170/tx.c create mode 100644 drivers/net/wireless/ath/carl9170/usb.c diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c new file mode 100644 index 000000000000..671dbc429547 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -0,0 +1,909 @@ +/* + * Atheros CARL9170 driver + * + * 802.11 & command trap routines + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "hw.h" +#include "cmd.h" + +static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len) +{ + bool restart = false; + enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON; + + if (len > 3) { + if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) { + ar->fw.err_counter++; + if (ar->fw.err_counter > 3) { + restart = true; + reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS; + } + } + + if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) { + ar->fw.bug_counter++; + restart = true; + reason = CARL9170_RR_FATAL_FIRMWARE_ERROR; + } + } + + wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf); + + if (restart) + carl9170_restart(ar, reason); +} + +static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp) +{ + u32 ps; + bool new_ps; + + ps = le32_to_cpu(rsp->psm.state); + + new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE; + if (ar->ps.state != new_ps) { + if (!new_ps) { + ar->ps.sleep_ms = jiffies_to_msecs(jiffies - + ar->ps.last_action); + } + + ar->ps.last_action = jiffies; + + ar->ps.state = new_ps; + } +} + +static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq) +{ + if (ar->cmd_seq < -1) + return 0; + + /* + * Initialize Counter + */ + if (ar->cmd_seq < 0) + ar->cmd_seq = seq; + + /* + * The sequence is strictly monotonic increasing and it never skips! + * + * Therefore we can safely assume that whenever we received an + * unexpected sequence we have lost some valuable data. + */ + if (seq != ar->cmd_seq) { + int count; + + count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs; + + wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! " + "w:%d g:%d\n", count, ar->cmd_seq, seq); + + carl9170_restart(ar, CARL9170_RR_LOST_RSP); + return -EIO; + } + + ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs; + return 0; +} + +static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) +{ + /* + * Some commands may have a variable response length + * and we cannot predict the correct length in advance. + * So we only check if we provided enough space for the data. + */ + if (unlikely(ar->readlen != (len - 4))) { + dev_warn(&ar->udev->dev, "received invalid command response:" + "got %d, instead of %d\n", len - 4, ar->readlen); + print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET, + ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f); + print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET, + buffer, len); + /* + * Do not complete. The command times out, + * and we get a stack trace from there. + */ + carl9170_restart(ar, CARL9170_RR_INVALID_RSP); + } + + spin_lock(&ar->cmd_lock); + if (ar->readbuf) { + if (len >= 4) + memcpy(ar->readbuf, buffer + 4, len - 4); + + ar->readbuf = NULL; + } + complete(&ar->cmd_wait); + spin_unlock(&ar->cmd_lock); +} + +void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) +{ + struct carl9170_rsp *cmd = (void *) buf; + struct ieee80211_vif *vif; + + if (carl9170_check_sequence(ar, cmd->hdr.seq)) + return; + + if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { + if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) + carl9170_cmd_callback(ar, len, buf); + + return; + } + + if (unlikely(cmd->hdr.len != (len - 4))) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "FW: received over-/under" + "sized event %x (%d, but should be %d).\n", + cmd->hdr.cmd, cmd->hdr.len, len - 4); + + print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, + buf, len); + } + + return; + } + + /* hardware event handlers */ + switch (cmd->hdr.cmd) { + case CARL9170_RSP_PRETBTT: + /* pre-TBTT event */ + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (!vif) { + rcu_read_unlock(); + break; + } + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + carl9170_handle_ps(ar, cmd); + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + carl9170_update_beacon(ar, true); + break; + + default: + break; + } + rcu_read_unlock(); + + break; + + + case CARL9170_RSP_TXCOMP: + /* TX status notification */ + carl9170_tx_process_status(ar, cmd); + break; + + case CARL9170_RSP_BEACON_CONFIG: + /* + * (IBSS) beacon send notification + * bytes: 04 c2 XX YY B4 B3 B2 B1 + * + * XX always 80 + * YY always 00 + * B1-B4 "should" be the number of send out beacons. + */ + break; + + case CARL9170_RSP_ATIM: + /* End of Atim Window */ + break; + + case CARL9170_RSP_WATCHDOG: + /* Watchdog Interrupt */ + carl9170_restart(ar, CARL9170_RR_WATCHDOG); + break; + + case CARL9170_RSP_TEXT: + /* firmware debug */ + carl9170_dbg_message(ar, (char *)buf + 4, len - 4); + break; + + case CARL9170_RSP_HEXDUMP: + wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4); + print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE, + (char *)buf + 4, len - 4); + break; + + case CARL9170_RSP_RADAR: + if (!net_ratelimit()) + break; + + wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this " + "incident to linux-wireless@vger.kernel.org !\n"); + break; + + case CARL9170_RSP_GPIO: +#ifdef CONFIG_CARL9170_WPC + if (ar->wps.pbc) { + bool state = !!(cmd->gpio.gpio & cpu_to_le32( + AR9170_GPIO_PORT_WPS_BUTTON_PRESSED)); + + if (state != ar->wps.pbc_state) { + ar->wps.pbc_state = state; + input_report_key(ar->wps.pbc, KEY_WPS_BUTTON, + state); + input_sync(ar->wps.pbc); + } + } +#endif /* CONFIG_CARL9170_WPC */ + break; + + case CARL9170_RSP_BOOT: + complete(&ar->fw_boot_wait); + break; + + default: + wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n", + cmd->hdr.cmd); + print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); + break; + } +} + +static int carl9170_rx_mac_status(struct ar9170 *ar, + struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac, + struct ieee80211_rx_status *status) +{ + struct ieee80211_channel *chan; + u8 error, decrypt; + + BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); + BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); + + error = mac->error; + + if (error & AR9170_RX_ERROR_WRONG_RA) { + if (!ar->sniffer_enabled) + return -EINVAL; + } + + if (error & AR9170_RX_ERROR_PLCP) { + if (!(ar->filter_state & FIF_PLCPFAIL)) + return -EINVAL; + + status->flag |= RX_FLAG_FAILED_PLCP_CRC; + } + + if (error & AR9170_RX_ERROR_FCS) { + ar->tx_fcs_errors++; + + if (!(ar->filter_state & FIF_FCSFAIL)) + return -EINVAL; + + status->flag |= RX_FLAG_FAILED_FCS_CRC; + } + + decrypt = ar9170_get_decrypt_type(mac); + if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && + decrypt != AR9170_ENC_ALG_NONE) { + if ((decrypt == AR9170_ENC_ALG_TKIP) && + (error & AR9170_RX_ERROR_MMIC)) + status->flag |= RX_FLAG_MMIC_ERROR; + + status->flag |= RX_FLAG_DECRYPTED; + } + + if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled) + return -ENODATA; + + error &= ~(AR9170_RX_ERROR_MMIC | + AR9170_RX_ERROR_FCS | + AR9170_RX_ERROR_WRONG_RA | + AR9170_RX_ERROR_DECRYPT | + AR9170_RX_ERROR_PLCP); + + /* drop any other error frames */ + if (unlikely(error)) { + /* TODO: update netdevice's RX dropped/errors statistics */ + + if (net_ratelimit()) + wiphy_dbg(ar->hw->wiphy, "received frame with " + "suspicious error code (%#x).\n", error); + + return -EINVAL; + } + + chan = ar->channel; + if (chan) { + status->band = chan->band; + status->freq = chan->center_freq; + } + + switch (mac->status & AR9170_RX_STATUS_MODULATION) { + case AR9170_RX_STATUS_MODULATION_CCK: + if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) + status->flag |= RX_FLAG_SHORTPRE; + switch (head->plcp[0]) { + case AR9170_RX_PHY_RATE_CCK_1M: + status->rate_idx = 0; + break; + case AR9170_RX_PHY_RATE_CCK_2M: + status->rate_idx = 1; + break; + case AR9170_RX_PHY_RATE_CCK_5M: + status->rate_idx = 2; + break; + case AR9170_RX_PHY_RATE_CCK_11M: + status->rate_idx = 3; + break; + default: + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "invalid plcp cck " + "rate (%x).\n", head->plcp[0]); + } + + return -EINVAL; + } + break; + + case AR9170_RX_STATUS_MODULATION_DUPOFDM: + case AR9170_RX_STATUS_MODULATION_OFDM: + switch (head->plcp[0] & 0xf) { + case AR9170_TXRX_PHY_RATE_OFDM_6M: + status->rate_idx = 0; + break; + case AR9170_TXRX_PHY_RATE_OFDM_9M: + status->rate_idx = 1; + break; + case AR9170_TXRX_PHY_RATE_OFDM_12M: + status->rate_idx = 2; + break; + case AR9170_TXRX_PHY_RATE_OFDM_18M: + status->rate_idx = 3; + break; + case AR9170_TXRX_PHY_RATE_OFDM_24M: + status->rate_idx = 4; + break; + case AR9170_TXRX_PHY_RATE_OFDM_36M: + status->rate_idx = 5; + break; + case AR9170_TXRX_PHY_RATE_OFDM_48M: + status->rate_idx = 6; + break; + case AR9170_TXRX_PHY_RATE_OFDM_54M: + status->rate_idx = 7; + break; + default: + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "invalid plcp ofdm " + "rate (%x).\n", head->plcp[0]); + } + + return -EINVAL; + } + if (status->band == IEEE80211_BAND_2GHZ) + status->rate_idx += 4; + break; + + case AR9170_RX_STATUS_MODULATION_HT: + if (head->plcp[3] & 0x80) + status->flag |= RX_FLAG_40MHZ; + if (head->plcp[6] & 0x80) + status->flag |= RX_FLAG_SHORT_GI; + + status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f); + status->flag |= RX_FLAG_HT; + break; + + default: + BUG(); + return -ENOSYS; + } + + return 0; +} + +static void carl9170_rx_phy_status(struct ar9170 *ar, + struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status) +{ + int i; + + BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); + + for (i = 0; i < 3; i++) + if (phy->rssi[i] != 0x80) + status->antenna |= BIT(i); + + /* post-process RSSI */ + for (i = 0; i < 7; i++) + if (phy->rssi[i] & 0x80) + phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; + + /* TODO: we could do something with phy_errors */ + status->signal = ar->noise[0] + phy->rssi_combined; +} + +static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len) +{ + struct sk_buff *skb; + int reserved = 0; + struct ieee80211_hdr *hdr = (void *) buf; + + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + reserved += NET_IP_ALIGN; + + if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) + reserved += NET_IP_ALIGN; + } + + if (ieee80211_has_a4(hdr->frame_control)) + reserved += NET_IP_ALIGN; + + reserved = 32 + (reserved & NET_IP_ALIGN); + + skb = dev_alloc_skb(len + reserved); + if (likely(skb)) { + skb_reserve(skb, reserved); + memcpy(skb_put(skb, len), buf, len); + } + + return skb; +} + +static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie) +{ + struct ieee80211_mgmt *mgmt = (void *)data; + u8 *pos, *end; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + while (pos < end) { + if (pos + 2 + pos[1] > end) + return NULL; + + if (pos[0] == ie) + return pos; + + pos += 2 + pos[1]; + } + return NULL; +} + +/* + * NOTE: + * + * The firmware is in charge of waking up the device just before + * the AP is expected to transmit the next beacon. + * + * This leaves the driver with the important task of deciding when + * to set the PHY back to bed again. + */ +static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) +{ + struct ieee80211_hdr *hdr = (void *) data; + struct ieee80211_tim_ie *tim_ie; + u8 *tim; + u8 tim_len; + bool cam; + + if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || + !ar->common.curaid) + return; + + ar->ps.last_beacon = jiffies; + + tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); + if (!tim) + return; + + if (tim[1] < sizeof(*tim_ie)) + return; + + tim_len = tim[1]; + tim_ie = (struct ieee80211_tim_ie *) &tim[2]; + + if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period)) + ar->ps.dtim_counter = (tim_ie->dtim_count - 1) % + ar->hw->conf.ps_dtim_period; + + /* Check whenever the PHY can be turned off again. */ + + /* 1. What about buffered unicast traffic for our AID? */ + cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); + + /* 2. Maybe the AP wants to send multicast/broadcast data? */ + cam = !!(tim_ie->bitmap_ctrl & 0x01); + + if (!cam) { + /* back to low-power land. */ + ar->ps.off_override &= ~PS_OFF_BCN; + carl9170_ps_check(ar); + } else { + /* force CAM */ + ar->ps.off_override |= PS_OFF_BCN; + } +} + +/* + * If the frame alignment is right (or the kernel has + * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there + * is only a single MPDU in the USB frame, then we could + * submit to mac80211 the SKB directly. However, since + * there may be multiple packets in one SKB in stream + * mode, and we need to observe the proper ordering, + * this is non-trivial. + */ + +static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) +{ + struct ar9170_rx_head *head; + struct ar9170_rx_macstatus *mac; + struct ar9170_rx_phystatus *phy = NULL; + struct ieee80211_rx_status status; + struct sk_buff *skb; + int mpdu_len; + + if (!IS_STARTED(ar)) + return; + + if (unlikely(len < sizeof(*mac))) { + ar->rx_dropped++; + return; + } + + mpdu_len = len - sizeof(*mac); + + mac = (void *)(buf + mpdu_len); + if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { + ar->rx_dropped++; + return; + } + + switch (mac->status & AR9170_RX_STATUS_MPDU) { + case AR9170_RX_STATUS_MPDU_FIRST: + /* Aggregated MPDUs start with an PLCP header */ + if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { + head = (void *) buf; + + /* + * The PLCP header needs to be cached for the + * following MIDDLE + LAST A-MPDU packets. + * + * So, if you are wondering why all frames seem + * to share a common RX status information, + * then you have the answer right here... + */ + memcpy(&ar->rx_plcp, (void *) buf, + sizeof(struct ar9170_rx_head)); + + mpdu_len -= sizeof(struct ar9170_rx_head); + buf += sizeof(struct ar9170_rx_head); + + ar->rx_has_plcp = true; + } else { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "plcp info " + "is clipped.\n"); + } + + ar->rx_dropped++; + return; + } + break; + + case AR9170_RX_STATUS_MPDU_LAST: + /* + * The last frame of an A-MPDU has an extra tail + * which does contain the phy status of the whole + * aggregate. + */ + + if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + phy = (void *)(buf + mpdu_len); + } else { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "frame tail " + "is clipped.\n"); + } + + ar->rx_dropped++; + return; + } + + case AR9170_RX_STATUS_MPDU_MIDDLE: + /* These are just data + mac status */ + if (unlikely(!ar->rx_has_plcp)) { + if (!net_ratelimit()) + return; + + wiphy_err(ar->hw->wiphy, "rx stream does not start " + "with a first_mpdu frame tag.\n"); + + ar->rx_dropped++; + return; + } + + head = &ar->rx_plcp; + break; + + case AR9170_RX_STATUS_MPDU_SINGLE: + /* single mpdu has both: plcp (head) and phy status (tail) */ + head = (void *) buf; + + mpdu_len -= sizeof(struct ar9170_rx_head); + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + + buf += sizeof(struct ar9170_rx_head); + phy = (void *)(buf + mpdu_len); + break; + + default: + BUG_ON(1); + break; + } + + /* FC + DU + RA + FCS */ + if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) { + ar->rx_dropped++; + return; + } + + memset(&status, 0, sizeof(status)); + if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) { + ar->rx_dropped++; + return; + } + + if (phy) + carl9170_rx_phy_status(ar, phy, &status); + + carl9170_ps_beacon(ar, buf, mpdu_len); + + skb = carl9170_rx_copy_data(buf, mpdu_len); + if (likely(skb)) { + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx(ar->hw, skb); + } else { + ar->rx_dropped++; + } +} + +static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, + const unsigned int resplen) +{ + struct carl9170_rsp *cmd; + int i = 0; + + while (i < resplen) { + cmd = (void *) &respbuf[i]; + + i += cmd->hdr.len + 4; + if (unlikely(i > resplen)) + break; + + carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); + } + + if (unlikely(i != resplen)) { + if (!net_ratelimit()) + return; + + wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n"); + print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET, + respbuf, resplen); + } +} + +static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len) +{ + unsigned int i = 0; + + /* weird thing, but this is the same in the original driver */ + while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) { + i += 2; + len -= 2; + buf += 2; + } + + if (unlikely(len < 4)) + return; + + /* found the 6 * 0xffff marker? */ + if (i == 12) + carl9170_rx_untie_cmds(ar, buf, len); + else + carl9170_handle_mpdu(ar, buf, len); +} + +static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) +{ + unsigned int tlen, wlen = 0, clen = 0; + struct ar9170_stream *rx_stream; + u8 *tbuf; + + tbuf = buf; + tlen = len; + + while (tlen >= 4) { + rx_stream = (void *) tbuf; + clen = le16_to_cpu(rx_stream->length); + wlen = ALIGN(clen, 4); + + /* check if this is stream has a valid tag.*/ + if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) { + /* + * TODO: handle the highly unlikely event that the + * corrupted stream has the TAG at the right position. + */ + + /* check if the frame can be repaired. */ + if (!ar->rx_failover_missing) { + + /* this is not "short read". */ + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, + "missing tag!\n"); + } + + __carl9170_rx(ar, tbuf, tlen); + return; + } + + if (ar->rx_failover_missing > tlen) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, + "possible multi " + "stream corruption!\n"); + goto err_telluser; + } else { + goto err_silent; + } + } + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing -= tlen; + + if (ar->rx_failover_missing <= 0) { + /* + * nested carl9170_rx_stream call! + * + * termination is guranteed, even when the + * combined frame also have an element with + * a bad tag. + */ + + ar->rx_failover_missing = 0; + carl9170_rx_stream(ar, ar->rx_failover->data, + ar->rx_failover->len); + + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + } + + return; + } + + /* check if stream is clipped */ + if (wlen > tlen - 4) { + if (ar->rx_failover_missing) { + /* TODO: handle double stream corruption. */ + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "double rx " + "stream corruption!\n"); + goto err_telluser; + } else { + goto err_silent; + } + } + + /* + * save incomplete data set. + * the firmware will resend the missing bits when + * the rx - descriptor comes round again. + */ + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing = clen - tlen; + return; + } + __carl9170_rx(ar, rx_stream->payload, clen); + + tbuf += wlen + 4; + tlen -= wlen + 4; + } + + if (tlen) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed " + "data left in rx stream!\n", tlen); + } + + goto err_telluser; + } + + return; + +err_telluser: + wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, " + "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen, + ar->rx_failover_missing); + + if (ar->rx_failover_missing) + print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, + ar->rx_failover->data, + ar->rx_failover->len); + + print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, + buf, len); + + wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if " + "you see this message frequently.\n"); + +err_silent: + if (ar->rx_failover_missing) { + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + ar->rx_failover_missing = 0; + } +} + +void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len) +{ + if (ar->fw.rx_stream) + carl9170_rx_stream(ar, buf, len); + else + __carl9170_rx(ar, buf, len); +} diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c new file mode 100644 index 000000000000..e0d2374e0c77 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -0,0 +1,1373 @@ +/* + * Atheros CARL9170 driver + * + * 802.11 xmit & status routines + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "hw.h" +#include "cmd.h" + +static inline unsigned int __carl9170_get_queue(struct ar9170 *ar, + unsigned int queue) +{ + if (unlikely(modparam_noht)) { + return queue; + } else { + /* + * This is just another workaround, until + * someone figures out how to get QoS and + * AMPDU to play nicely together. + */ + + return 2; /* AC_BE */ + } +} + +static inline unsigned int carl9170_get_queue(struct ar9170 *ar, + struct sk_buff *skb) +{ + return __carl9170_get_queue(ar, skb_get_queue_mapping(skb)); +} + +static bool is_mem_full(struct ar9170 *ar) +{ + return (DIV_ROUND_UP(IEEE80211_MAX_FRAME_LEN, ar->fw.mem_block_size) > + atomic_read(&ar->mem_free_blocks)); +} + +static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) +{ + int queue, i; + bool mem_full; + + atomic_inc(&ar->tx_total_queued); + + queue = skb_get_queue_mapping(skb); + spin_lock_bh(&ar->tx_stats_lock); + + /* + * The driver has to accept the frame, regardless if the queue is + * full to the brim, or not. We have to do the queuing internally, + * since mac80211 assumes that a driver which can operate with + * aggregated frames does not reject frames for this reason. + */ + ar->tx_stats[queue].len++; + ar->tx_stats[queue].count++; + + mem_full = is_mem_full(ar); + for (i = 0; i < ar->hw->queues; i++) { + if (mem_full || ar->tx_stats[i].len >= ar->tx_stats[i].limit) { + ieee80211_stop_queue(ar->hw, i); + ar->queue_stop_timeout[i] = jiffies; + } + } + + spin_unlock_bh(&ar->tx_stats_lock); +} + +static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_tx_info *txinfo; + int queue; + + txinfo = IEEE80211_SKB_CB(skb); + queue = skb_get_queue_mapping(skb); + + spin_lock_bh(&ar->tx_stats_lock); + + ar->tx_stats[queue].len--; + + if (!is_mem_full(ar)) { + unsigned int i; + for (i = 0; i < ar->hw->queues; i++) { + if (ar->tx_stats[i].len >= CARL9170_NUM_TX_LIMIT_SOFT) + continue; + + if (ieee80211_queue_stopped(ar->hw, i)) { + unsigned long tmp; + + tmp = jiffies - ar->queue_stop_timeout[i]; + if (tmp > ar->max_queue_stop_timeout[i]) + ar->max_queue_stop_timeout[i] = tmp; + } + + ieee80211_wake_queue(ar->hw, i); + } + } + + spin_unlock_bh(&ar->tx_stats_lock); + if (atomic_dec_and_test(&ar->tx_total_queued)) + complete(&ar->tx_flush); +} + +static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + unsigned int chunks; + int cookie = -1; + + atomic_inc(&ar->mem_allocs); + + chunks = DIV_ROUND_UP(skb->len, ar->fw.mem_block_size); + if (unlikely(atomic_sub_return(chunks, &ar->mem_free_blocks) < 0)) { + atomic_add(chunks, &ar->mem_free_blocks); + return -ENOSPC; + } + + spin_lock_bh(&ar->mem_lock); + cookie = bitmap_find_free_region(ar->mem_bitmap, ar->fw.mem_blocks, 0); + spin_unlock_bh(&ar->mem_lock); + + if (unlikely(cookie < 0)) { + atomic_add(chunks, &ar->mem_free_blocks); + return -ENOSPC; + } + + super = (void *) skb->data; + + /* + * Cookie #0 serves two special purposes: + * 1. The firmware might use it generate BlockACK frames + * in responds of an incoming BlockAckReqs. + * + * 2. Prevent double-free bugs. + */ + super->s.cookie = (u8) cookie + 1; + return 0; +} + +static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + int cookie; + + /* make a local copy of the cookie */ + cookie = super->s.cookie; + /* invalidate cookie */ + super->s.cookie = 0; + + /* + * Do a out-of-bounds check on the cookie: + * + * * cookie "0" is reserved and won't be assigned to any + * out-going frame. Internally however, it is used to + * mark no longer/un-accounted frames and serves as a + * cheap way of preventing frames from being freed + * twice by _accident_. NB: There is a tiny race... + * + * * obviously, cookie number is limited by the amount + * of available memory blocks, so the number can + * never execeed the mem_blocks count. + */ + if (unlikely(WARN_ON_ONCE(cookie == 0) || + WARN_ON_ONCE(cookie > ar->fw.mem_blocks))) + return; + + atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size), + &ar->mem_free_blocks); + + spin_lock_bh(&ar->mem_lock); + bitmap_release_region(ar->mem_bitmap, cookie - 1, 0); + spin_unlock_bh(&ar->mem_lock); +} + +/* Called from any context */ +static void carl9170_tx_release(struct kref *ref) +{ + struct ar9170 *ar; + struct carl9170_tx_info *arinfo; + struct ieee80211_tx_info *txinfo; + struct sk_buff *skb; + + arinfo = container_of(ref, struct carl9170_tx_info, ref); + txinfo = container_of((void *) arinfo, struct ieee80211_tx_info, + rate_driver_data); + skb = container_of((void *) txinfo, struct sk_buff, cb); + + ar = arinfo->ar; + if (WARN_ON_ONCE(!ar)) + return; + + BUILD_BUG_ON( + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); + + memset(&txinfo->status.ampdu_ack_len, 0, + sizeof(struct ieee80211_tx_info) - + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); + + if (atomic_read(&ar->tx_total_queued)) + ar->tx_schedule = true; + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) { + if (!atomic_read(&ar->tx_ampdu_upload)) + ar->tx_ampdu_schedule = true; + + if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { + txinfo->status.ampdu_len = txinfo->pad[0]; + txinfo->status.ampdu_ack_len = txinfo->pad[1]; + txinfo->pad[0] = txinfo->pad[1] = 0; + } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { + /* + * drop redundant tx_status reports: + * + * 1. ampdu_ack_len of the final tx_status does + * include the feedback of this particular frame. + * + * 2. tx_status_irqsafe only queues up to 128 + * tx feedback reports and discards the rest. + * + * 3. minstrel_ht is picky, it only accepts + * reports of frames with the TX_STATUS_AMPDU flag. + */ + + dev_kfree_skb_any(skb); + return; + } else { + /* + * Frame has failed, but we want to keep it in + * case it was lost due to a power-state + * transition. + */ + } + } + + skb_pull(skb, sizeof(struct _carl9170_tx_superframe)); + ieee80211_tx_status_irqsafe(ar->hw, skb); +} + +void carl9170_tx_get_skb(struct sk_buff *skb) +{ + struct carl9170_tx_info *arinfo = (void *) + (IEEE80211_SKB_CB(skb))->rate_driver_data; + kref_get(&arinfo->ref); +} + +int carl9170_tx_put_skb(struct sk_buff *skb) +{ + struct carl9170_tx_info *arinfo = (void *) + (IEEE80211_SKB_CB(skb))->rate_driver_data; + + return kref_put(&arinfo->ref, carl9170_tx_release); +} + +/* Caller must hold the tid_info->lock & rcu_read_lock */ +static void carl9170_tx_shift_bm(struct ar9170 *ar, + struct carl9170_sta_tid *tid_info, u16 seq) +{ + u16 off; + + off = SEQ_DIFF(seq, tid_info->bsn); + + if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) + return; + + /* + * Sanity check. For each MPDU we set the bit in bitmap and + * clear it once we received the tx_status. + * But if the bit is already cleared then we've been bitten + * by a bug. + */ + WARN_ON_ONCE(!test_and_clear_bit(off, tid_info->bitmap)); + + off = SEQ_DIFF(tid_info->snx, tid_info->bsn); + if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) + return; + + if (!bitmap_empty(tid_info->bitmap, off)) + off = find_first_bit(tid_info->bitmap, off); + + tid_info->bsn += off; + tid_info->bsn &= 0x0fff; + + bitmap_shift_right(tid_info->bitmap, tid_info->bitmap, + off, CARL9170_BAW_BITS); +} + +static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, + struct sk_buff *skb, struct ieee80211_tx_info *txinfo) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *) super->frame_data; + struct ieee80211_tx_info *tx_info; + struct carl9170_tx_info *ar_info; + struct carl9170_sta_info *sta_info; + struct ieee80211_sta *sta; + struct carl9170_sta_tid *tid_info; + struct ieee80211_vif *vif; + unsigned int vif_id; + u8 tid; + + if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || + txinfo->flags & IEEE80211_TX_CTL_INJECTED) + return; + + tx_info = IEEE80211_SKB_CB(skb); + ar_info = (void *) tx_info->rate_driver_data; + + vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> + CARL9170_TX_SUPER_MISC_VIF_ID_S; + + if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) + return; + + rcu_read_lock(); + vif = rcu_dereference(ar->vif_priv[vif_id].vif); + if (unlikely(!vif)) + goto out_rcu; + + /* + * Normally we should use wrappers like ieee80211_get_DA to get + * the correct peer ieee80211_sta. + * + * But there is a problem with indirect traffic (broadcasts, or + * data which is designated for other stations) in station mode. + * The frame will be directed to the AP for distribution and not + * to the actual destination. + */ + sta = ieee80211_find_sta(vif, hdr->addr1); + if (unlikely(!sta)) + goto out_rcu; + + tid = get_tid_h(hdr); + + sta_info = (void *) sta->drv_priv; + tid_info = rcu_dereference(sta_info->agg[tid]); + if (!tid_info) + goto out_rcu; + + spin_lock_bh(&tid_info->lock); + if (likely(tid_info->state >= CARL9170_TID_STATE_IDLE)) + carl9170_tx_shift_bm(ar, tid_info, get_seq_h(hdr)); + + if (sta_info->stats[tid].clear) { + sta_info->stats[tid].clear = false; + sta_info->stats[tid].ampdu_len = 0; + sta_info->stats[tid].ampdu_ack_len = 0; + } + + sta_info->stats[tid].ampdu_len++; + if (txinfo->status.rates[0].count == 1) + sta_info->stats[tid].ampdu_ack_len++; + + if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { + txinfo->pad[0] = sta_info->stats[tid].ampdu_len; + txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len; + txinfo->flags |= IEEE80211_TX_STAT_AMPDU; + sta_info->stats[tid].clear = true; + } + spin_unlock_bh(&tid_info->lock); + +out_rcu: + rcu_read_unlock(); +} + +void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, + const bool success) +{ + struct ieee80211_tx_info *txinfo; + + carl9170_tx_accounting_free(ar, skb); + + txinfo = IEEE80211_SKB_CB(skb); + + if (success) + txinfo->flags |= IEEE80211_TX_STAT_ACK; + else + ar->tx_ack_failures++; + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) + carl9170_tx_status_process_ampdu(ar, skb, txinfo); + + carl9170_tx_put_skb(skb); +} + +/* This function may be called form any context */ +void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); + + atomic_dec(&ar->tx_total_pending); + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + + if (carl9170_tx_put_skb(skb)) + tasklet_hi_schedule(&ar->usb_tasklet); +} + +static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + + spin_lock_bh(&queue->lock); + skb_queue_walk(queue, skb) { + struct _carl9170_tx_superframe *txc = (void *) skb->data; + + if (txc->s.cookie != cookie) + continue; + + __skb_unlink(skb, queue); + spin_unlock_bh(&queue->lock); + + carl9170_release_dev_space(ar, skb); + return skb; + } + spin_unlock_bh(&queue->lock); + + return NULL; +} + +static void carl9170_tx_fill_rateinfo(struct ar9170 *ar, unsigned int rix, + unsigned int tries, struct ieee80211_tx_info *txinfo) +{ + unsigned int i; + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + if (txinfo->status.rates[i].idx < 0) + break; + + if (i == rix) { + txinfo->status.rates[i].count = tries; + i++; + break; + } + } + + for (; i < IEEE80211_TX_MAX_RATES; i++) { + txinfo->status.rates[i].idx = -1; + txinfo->status.rates[i].count = 0; + } +} + +static void carl9170_check_queue_stop_timeout(struct ar9170 *ar) +{ + int i; + struct sk_buff *skb; + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + bool restart = false; + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_status[i].lock); + + skb = skb_peek(&ar->tx_status[i]); + + if (!skb) + goto next; + + txinfo = IEEE80211_SKB_CB(skb); + arinfo = (void *) txinfo->rate_driver_data; + + if (time_is_before_jiffies(arinfo->timeout + + msecs_to_jiffies(CARL9170_QUEUE_STUCK_TIMEOUT)) == true) + restart = true; + +next: + spin_unlock_bh(&ar->tx_status[i].lock); + } + + if (restart) { + /* + * At least one queue has been stuck for long enough. + * Give the device a kick and hope it gets back to + * work. + * + * possible reasons may include: + * - frames got lost/corrupted (bad connection to the device) + * - stalled rx processing/usb controller hiccups + * - firmware errors/bugs + * - every bug you can think of. + * - all bugs you can't... + * - ... + */ + carl9170_restart(ar, CARL9170_RR_STUCK_TX); + } +} + +void carl9170_tx_janitor(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + tx_janitor.work); + if (!IS_STARTED(ar)) + return; + + ar->tx_janitor_last_run = jiffies; + + carl9170_check_queue_stop_timeout(ar); + + if (!atomic_read(&ar->tx_total_queued)) + return; + + ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, + msecs_to_jiffies(CARL9170_TX_TIMEOUT)); +} + +static void __carl9170_tx_process_status(struct ar9170 *ar, + const uint8_t cookie, const uint8_t info) +{ + struct sk_buff *skb; + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + unsigned int r, t, q; + bool success = true; + + q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE]; + + skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]); + if (!skb) { + /* + * We have lost the race to another thread. + */ + + return ; + } + + txinfo = IEEE80211_SKB_CB(skb); + arinfo = (void *) txinfo->rate_driver_data; + + if (!(info & CARL9170_TX_STATUS_SUCCESS)) + success = false; + + r = (info & CARL9170_TX_STATUS_RIX) >> CARL9170_TX_STATUS_RIX_S; + t = (info & CARL9170_TX_STATUS_TRIES) >> CARL9170_TX_STATUS_TRIES_S; + + carl9170_tx_fill_rateinfo(ar, r, t, txinfo); + carl9170_tx_status(ar, skb, success); +} + +void carl9170_tx_process_status(struct ar9170 *ar, + const struct carl9170_rsp *cmd) +{ + unsigned int i; + + for (i = 0; i < cmd->hdr.ext; i++) { + if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) { + print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE, + (void *) cmd, cmd->hdr.len + 4); + break; + } + + __carl9170_tx_process_status(ar, cmd->_tx_status[i].cookie, + cmd->_tx_status[i].info); + } +} + +static __le32 carl9170_tx_physet(struct ar9170 *ar, + struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate) +{ + struct ieee80211_rate *rate = NULL; + u32 power, chains; + __le32 tmp; + + tmp = cpu_to_le32(0); + + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ << + AR9170_TX_PHY_BW_S); + /* this works because 40 MHz is 2 and dup is 3 */ + if (txrate->flags & IEEE80211_TX_RC_DUP_DATA) + tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP << + AR9170_TX_PHY_BW_S); + + if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) + tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); + + if (txrate->flags & IEEE80211_TX_RC_MCS) { + u32 r = txrate->idx; + u8 *txpower; + + /* heavy clip control */ + tmp |= cpu_to_le32((r & 0x7) << + AR9170_TX_PHY_TX_HEAVY_CLIP_S); + + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { + if (info->band == IEEE80211_BAND_5GHZ) + txpower = ar->power_5G_ht40; + else + txpower = ar->power_2G_ht40; + } else { + if (info->band == IEEE80211_BAND_5GHZ) + txpower = ar->power_5G_ht20; + else + txpower = ar->power_2G_ht20; + } + + power = txpower[r & 7]; + + /* +1 dBm for HT40 */ + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + power += 2; + + r <<= AR9170_TX_PHY_MCS_S; + BUG_ON(r & ~AR9170_TX_PHY_MCS); + + tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS); + tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); + + /* + * green field preamble does not work. + * + * if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) + * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); + */ + } else { + u8 *txpower; + u32 mod; + u32 phyrate; + u8 idx = txrate->idx; + + if (info->band != IEEE80211_BAND_2GHZ) { + idx += 4; + txpower = ar->power_5G_leg; + mod = AR9170_TX_PHY_MOD_OFDM; + } else { + if (idx < 4) { + txpower = ar->power_2G_cck; + mod = AR9170_TX_PHY_MOD_CCK; + } else { + mod = AR9170_TX_PHY_MOD_OFDM; + txpower = ar->power_2G_ofdm; + } + } + + rate = &__carl9170_ratetable[idx]; + + phyrate = rate->hw_value & 0xF; + power = txpower[(rate->hw_value & 0x30) >> 4]; + phyrate <<= AR9170_TX_PHY_MCS_S; + + tmp |= cpu_to_le32(mod); + tmp |= cpu_to_le32(phyrate); + + /* + * short preamble seems to be broken too. + * + * if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); + */ + } + power <<= AR9170_TX_PHY_TX_PWR_S; + power &= AR9170_TX_PHY_TX_PWR; + tmp |= cpu_to_le32(power); + + /* set TX chains */ + if (ar->eeprom.tx_mask == 1) { + chains = AR9170_TX_PHY_TXCHAIN_1; + } else { + chains = AR9170_TX_PHY_TXCHAIN_2; + + /* >= 36M legacy OFDM - use only one chain */ + if (rate && rate->bitrate >= 360 && + !(txrate->flags & IEEE80211_TX_RC_MCS)) + chains = AR9170_TX_PHY_TXCHAIN_1; + } + tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S); + + return tmp; +} + +static bool carl9170_tx_rts_check(struct ar9170 *ar, + struct ieee80211_tx_rate *rate, + bool ampdu, bool multi) +{ + switch (ar->erp_mode) { + case CARL9170_ERP_AUTO: + if (ampdu) + break; + + case CARL9170_ERP_MAC80211: + if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)) + break; + + case CARL9170_ERP_RTS: + if (likely(!multi)) + return true; + + default: + break; + } + + return false; +} + +static bool carl9170_tx_cts_check(struct ar9170 *ar, + struct ieee80211_tx_rate *rate) +{ + switch (ar->erp_mode) { + case CARL9170_ERP_AUTO: + case CARL9170_ERP_MAC80211: + if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) + break; + + case CARL9170_ERP_CTS: + return true; + + default: + break; + } + + return false; +} + +static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + struct _carl9170_tx_superframe *txc; + struct carl9170_vif_info *cvif; + struct ieee80211_tx_info *info; + struct ieee80211_tx_rate *txrate; + struct ieee80211_sta *sta; + struct carl9170_tx_info *arinfo; + unsigned int hw_queue; + int i; + u16 keytype = 0; + u16 len, icv = 0; + bool ampdu, no_ack; + + BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) != + CARL9170_TX_SUPERDESC_LEN); + + BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) != + AR9170_TX_HWDESC_LEN); + + BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES); + + hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)]; + + hdr = (void *)skb->data; + info = IEEE80211_SKB_CB(skb); + len = skb->len; + + /* + * Note: If the frame was sent through a monitor interface, + * the ieee80211_vif pointer can be NULL. + */ + if (likely(info->control.vif)) + cvif = (void *) info->control.vif->drv_priv; + else + cvif = NULL; + + sta = info->control.sta; + + txc = (void *)skb_push(skb, sizeof(*txc)); + memset(txc, 0, sizeof(*txc)); + + ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU); + no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); + + if (info->control.hw_key) { + icv = info->control.hw_key->icv_len; + + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + keytype = AR9170_TX_MAC_ENCR_RC4; + break; + case WLAN_CIPHER_SUITE_CCMP: + keytype = AR9170_TX_MAC_ENCR_AES; + break; + default: + WARN_ON(1); + goto err_out; + } + } + + BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC > + ((CARL9170_TX_SUPER_MISC_VIF_ID >> + CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); + + txc->s.len = cpu_to_le16(len + sizeof(*txc)); + txc->f.length = cpu_to_le16(len + icv + 4); + SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, + cvif ? cvif->id : 0); + + txc->f.mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | + AR9170_TX_MAC_BACKOFF); + + SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); + + txc->f.mac_control |= cpu_to_le16(hw_queue << AR9170_TX_MAC_QOS_S); + txc->f.mac_control |= cpu_to_le16(keytype); + txc->f.phy_control = cpu_to_le32(0); + + if (no_ack) + txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); + + if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) + txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; + + txrate = &info->control.rates[0]; + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); + else if (carl9170_tx_cts_check(ar, txrate)) + txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); + + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); + txc->f.phy_control |= carl9170_tx_physet(ar, info, txrate); + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + txrate = &info->control.rates[i]; + if (txrate->idx >= 0) + continue; + + txrate->idx = 0; + txrate->count = ar->hw->max_rate_tries; + } + } + + /* + * NOTE: For the first rate, the ERP & AMPDU flags are directly + * taken from mac_control. For all fallback rate, the firmware + * updates the mac_control flags from the rate info field. + */ + for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + txrate = &info->control.rates[i]; + if (txrate->idx < 0) + break; + + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], + txrate->count); + + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS << + CARL9170_TX_SUPER_RI_ERP_PROT_S); + else if (carl9170_tx_cts_check(ar, txrate)) + txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << + CARL9170_TX_SUPER_RI_ERP_PROT_S); + + /* + * unaggregated fallback, in case aggregation + * proves to be unsuccessful and unreliable. + */ + if (ampdu && i < 3) + txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU; + + txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); + } + + if (ieee80211_is_probe_resp(hdr->frame_control)) + txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; + + if (ampdu) { + unsigned int density, factor; + + if (unlikely(!sta || !cvif)) + goto err_out; + + density = info->control.sta->ht_cap.ampdu_density; + factor = info->control.sta->ht_cap.ampdu_factor; + + if (density) { + /* + * Watch out! + * + * Otus uses slightly different density values than + * those from the 802.11n spec. + */ + + density = max_t(unsigned int, density + 1, 7u); + } + + factor = min_t(unsigned int, 1u, factor); + + SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY, + txc->s.ampdu_settings, density); + + SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, + txc->s.ampdu_settings, factor); + + if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) { + txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); + } else { + /* + * Not sure if it's even possible to aggregate + * non-ht rates with this HW. + */ + WARN_ON_ONCE(1); + } + } + + arinfo = (void *)info->rate_driver_data; + arinfo->timeout = jiffies; + arinfo->ar = ar; + kref_init(&arinfo->ref); + return 0; + +err_out: + skb_pull(skb, sizeof(*txc)); + return -EINVAL; +} + +static void carl9170_set_immba(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + + super = (void *) skb->data; + super->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_BA); +} + +static void carl9170_set_ampdu_params(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + int tmp; + + super = (void *) skb->data; + + tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_DENSITY) << + CARL9170_TX_SUPER_AMPDU_DENSITY_S; + + /* + * If you haven't noticed carl9170_tx_prepare has already filled + * in all ampdu spacing & factor parameters. + * Now it's the time to check whenever the settings have to be + * updated by the firmware, or if everything is still the same. + * + * There's no sane way to handle different density values with + * this hardware, so we may as well just do the compare in the + * driver. + */ + + if (tmp != ar->current_density) { + ar->current_density = tmp; + super->s.ampdu_settings |= + CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY; + } + + tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_FACTOR) << + CARL9170_TX_SUPER_AMPDU_FACTOR_S; + + if (tmp != ar->current_factor) { + ar->current_factor = tmp; + super->s.ampdu_settings |= + CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR; + } +} + +static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest, + struct sk_buff *_src) +{ + struct _carl9170_tx_superframe *dest, *src; + + dest = (void *) _dest->data; + src = (void *) _src->data; + + /* + * The mac80211 rate control algorithm expects that all MPDUs in + * an AMPDU share the same tx vectors. + * This is not really obvious right now, because the hardware + * does the AMPDU setup according to its own rulebook. + * Our nicely assembled, strictly monotonic increasing mpdu + * chains will be broken up, mashed back together... + */ + + return (dest->f.phy_control == src->f.phy_control); +} + +static void carl9170_tx_ampdu(struct ar9170 *ar) +{ + struct sk_buff_head agg; + struct carl9170_sta_tid *tid_info; + struct sk_buff *skb, *first; + unsigned int i = 0, done_ampdus = 0; + u16 seq, queue, tmpssn; + + atomic_inc(&ar->tx_ampdu_scheduler); + ar->tx_ampdu_schedule = false; + + if (atomic_read(&ar->tx_ampdu_upload)) + return; + + if (!ar->tx_ampdu_list_len) + return; + + __skb_queue_head_init(&agg); + + rcu_read_lock(); + tid_info = rcu_dereference(ar->tx_ampdu_iter); + if (WARN_ON_ONCE(!tid_info)) { + rcu_read_unlock(); + return; + } + +retry: + list_for_each_entry_continue_rcu(tid_info, &ar->tx_ampdu_list, list) { + i++; + + if (tid_info->state < CARL9170_TID_STATE_PROGRESS) + continue; + + queue = TID_TO_WME_AC(tid_info->tid); + + spin_lock_bh(&tid_info->lock); + if (tid_info->state != CARL9170_TID_STATE_XMIT) { + first = skb_peek(&tid_info->queue); + if (first) { + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + + txinfo = IEEE80211_SKB_CB(first); + arinfo = (void *) txinfo->rate_driver_data; + + if (time_is_after_jiffies(arinfo->timeout + + msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)) + == true) + goto processed; + + /* + * We've been waiting for the frame which + * matches "snx" (start sequence of the + * next aggregate) for some time now. + * + * But it never arrived. Therefore + * jump to the next available frame + * and kick-start the transmission. + * + * Note: This might induce odd latency + * spikes because the receiver will be + * waiting for the lost frame too. + */ + ar->tx_ampdu_timeout++; + + tid_info->snx = carl9170_get_seq(first); + tid_info->state = CARL9170_TID_STATE_XMIT; + } else { + goto processed; + } + } + + tid_info->counter++; + first = skb_peek(&tid_info->queue); + tmpssn = carl9170_get_seq(first); + seq = tid_info->snx; + + if (unlikely(tmpssn != seq)) { + tid_info->state = CARL9170_TID_STATE_IDLE; + + goto processed; + } + + while ((skb = skb_peek(&tid_info->queue))) { + /* strict 0, 1, ..., n - 1, n frame sequence order */ + if (unlikely(carl9170_get_seq(skb) != seq)) + break; + + /* don't upload more than AMPDU FACTOR allows. */ + if (unlikely(SEQ_DIFF(tid_info->snx, tid_info->bsn) >= + (tid_info->max - 1))) + break; + + if (!carl9170_tx_rate_check(ar, skb, first)) + break; + + atomic_inc(&ar->tx_ampdu_upload); + tid_info->snx = seq = SEQ_NEXT(seq); + __skb_unlink(skb, &tid_info->queue); + + __skb_queue_tail(&agg, skb); + + if (skb_queue_len(&agg) >= CARL9170_NUM_TX_AGG_MAX) + break; + } + + if (skb_queue_empty(&tid_info->queue) || + carl9170_get_seq(skb_peek(&tid_info->queue)) != + tid_info->snx) { + /* + * stop TID, if A-MPDU frames are still missing, + * or whenever the queue is empty. + */ + + tid_info->state = CARL9170_TID_STATE_IDLE; + } + done_ampdus++; + +processed: + spin_unlock_bh(&tid_info->lock); + + if (skb_queue_empty(&agg)) + continue; + + /* apply ampdu spacing & factor settings */ + carl9170_set_ampdu_params(ar, skb_peek(&agg)); + + /* set aggregation push bit */ + carl9170_set_immba(ar, skb_peek_tail(&agg)); + + spin_lock_bh(&ar->tx_pending[queue].lock); + skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]); + spin_unlock_bh(&ar->tx_pending[queue].lock); + ar->tx_schedule = true; + } + if ((done_ampdus++ == 0) && (i++ == 0)) + goto retry; + + rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); + rcu_read_unlock(); +} + +static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + struct ieee80211_tx_info *info; + struct carl9170_tx_info *arinfo; + + BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + + spin_lock_bh(&queue->lock); + skb = skb_peek(queue); + if (unlikely(!skb)) + goto err_unlock; + + if (carl9170_alloc_dev_space(ar, skb)) + goto err_unlock; + + __skb_unlink(skb, queue); + spin_unlock_bh(&queue->lock); + + info = IEEE80211_SKB_CB(skb); + arinfo = (void *) info->rate_driver_data; + + arinfo->timeout = jiffies; + + /* + * increase ref count to "2". + * Ref counting is the easiest way to solve the race between + * the the urb's completion routine: carl9170_tx_callback and + * wlan tx status functions: carl9170_tx_status/janitor. + */ + carl9170_tx_get_skb(skb); + + return skb; + +err_unlock: + spin_unlock_bh(&queue->lock); + return NULL; +} + +void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + uint8_t q = 0; + + ar->tx_dropped++; + + super = (void *)skb->data; + SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q, + ar9170_qmap[carl9170_get_queue(ar, skb)]); + __carl9170_tx_process_status(ar, super->s.cookie, q); +} + +static void carl9170_tx(struct ar9170 *ar) +{ + struct sk_buff *skb; + unsigned int i, q; + bool schedule_garbagecollector = false; + + ar->tx_schedule = false; + + if (unlikely(!IS_STARTED(ar))) + return; + + carl9170_usb_handle_tx_err(ar); + + for (i = 0; i < ar->hw->queues; i++) { + while (!skb_queue_empty(&ar->tx_pending[i])) { + skb = carl9170_tx_pick_skb(ar, &ar->tx_pending[i]); + if (unlikely(!skb)) + break; + + atomic_inc(&ar->tx_total_pending); + + q = __carl9170_get_queue(ar, i); + /* + * NB: tx_status[i] vs. tx_status[q], + * TODO: Move into pick_skb or alloc_dev_space. + */ + skb_queue_tail(&ar->tx_status[q], skb); + + carl9170_usb_tx(ar, skb); + schedule_garbagecollector = true; + } + } + + if (!schedule_garbagecollector) + return; + + ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, + msecs_to_jiffies(CARL9170_TX_TIMEOUT)); +} + +static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, + struct ieee80211_sta *sta, struct sk_buff *skb) +{ + struct carl9170_sta_info *sta_info; + struct carl9170_sta_tid *agg; + struct sk_buff *iter; + unsigned int max; + u16 tid, seq, qseq, off; + bool run = false; + + tid = carl9170_get_tid(skb); + seq = carl9170_get_seq(skb); + sta_info = (void *) sta->drv_priv; + + rcu_read_lock(); + agg = rcu_dereference(sta_info->agg[tid]); + max = sta_info->ampdu_max_len; + + if (!agg) + goto err_unlock_rcu; + + spin_lock_bh(&agg->lock); + if (unlikely(agg->state < CARL9170_TID_STATE_IDLE)) + goto err_unlock; + + /* check if sequence is within the BA window */ + if (unlikely(!BAW_WITHIN(agg->bsn, CARL9170_BAW_BITS, seq))) + goto err_unlock; + + if (WARN_ON_ONCE(!BAW_WITHIN(agg->snx, CARL9170_BAW_BITS, seq))) + goto err_unlock; + + off = SEQ_DIFF(seq, agg->bsn); + if (WARN_ON_ONCE(test_and_set_bit(off, agg->bitmap))) + goto err_unlock; + + if (likely(BAW_WITHIN(agg->hsn, CARL9170_BAW_BITS, seq))) { + __skb_queue_tail(&agg->queue, skb); + agg->hsn = seq; + goto queued; + } + + skb_queue_reverse_walk(&agg->queue, iter) { + qseq = carl9170_get_seq(iter); + + if (BAW_WITHIN(qseq, CARL9170_BAW_BITS, seq)) { + __skb_queue_after(&agg->queue, iter, skb); + goto queued; + } + } + + __skb_queue_head(&agg->queue, skb); +queued: + + if (unlikely(agg->state != CARL9170_TID_STATE_XMIT)) { + if (agg->snx == carl9170_get_seq(skb_peek(&agg->queue))) { + agg->state = CARL9170_TID_STATE_XMIT; + run = true; + } + } + + spin_unlock_bh(&agg->lock); + rcu_read_unlock(); + + return run; + +err_unlock: + spin_unlock_bh(&agg->lock); + +err_unlock_rcu: + rcu_read_unlock(); + carl9170_tx_status(ar, skb, false); + ar->tx_dropped++; + return false; +} + +int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ar9170 *ar = hw->priv; + struct ieee80211_tx_info *info; + struct ieee80211_sta *sta; + bool run; + + if (unlikely(!IS_STARTED(ar))) + goto err_free; + + info = IEEE80211_SKB_CB(skb); + sta = info->control.sta; + + if (unlikely(carl9170_tx_prepare(ar, skb))) + goto err_free; + + carl9170_tx_accounting(ar, skb); + /* + * from now on, one has to use carl9170_tx_status to free + * all ressouces which are associated with the frame. + */ + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + if (WARN_ON_ONCE(!sta)) + goto err_free; + + run = carl9170_tx_ampdu_queue(ar, sta, skb); + if (run) + carl9170_tx_ampdu(ar); + + } else { + unsigned int queue = skb_get_queue_mapping(skb); + + skb_queue_tail(&ar->tx_pending[queue], skb); + } + + carl9170_tx(ar); + return NETDEV_TX_OK; + +err_free: + ar->tx_dropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +void carl9170_tx_scheduler(struct ar9170 *ar) +{ + + if (ar->tx_ampdu_schedule) + carl9170_tx_ampdu(ar); + + if (ar->tx_schedule) + carl9170_tx(ar); +} diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c new file mode 100644 index 000000000000..fde918d0120b --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -0,0 +1,1137 @@ +/* + * Atheros CARL9170 driver + * + * USB - frontend + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "cmd.h" +#include "hw.h" +#include "fwcmd.h" + +MODULE_AUTHOR("Johannes Berg "); +MODULE_AUTHOR("Christian Lamparter "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); +MODULE_FIRMWARE(CARL9170FW_NAME); +MODULE_ALIAS("ar9170usb"); +MODULE_ALIAS("arusb_lnx"); + +/* + * Note: + * + * Always update our wiki's device list (located at: + * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), + * whenever you add a new device. + */ +static struct usb_device_id carl9170_usb_ids[] = { + /* Atheros 9170 */ + { USB_DEVICE(0x0cf3, 0x9170) }, + /* Atheros TG121N */ + { USB_DEVICE(0x0cf3, 0x1001) }, + /* TP-Link TL-WN821N v2 */ + { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON | + CARL9170_ONE_LED }, + /* 3Com Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1010) }, + /* H3C Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1011) }, + /* Cace Airpcap NX */ + { USB_DEVICE(0xcace, 0x0300) }, + /* D-Link DWA 160 A1 */ + { USB_DEVICE(0x07d1, 0x3c10) }, + /* D-Link DWA 160 A2 */ + { USB_DEVICE(0x07d1, 0x3a09) }, + /* Netgear WNA1000 */ + { USB_DEVICE(0x0846, 0x9040) }, + /* Netgear WNDA3100 */ + { USB_DEVICE(0x0846, 0x9010) }, + /* Netgear WN111 v2 */ + { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, + /* Zydas ZD1221 */ + { USB_DEVICE(0x0ace, 0x1221) }, + /* Proxim ORiNOCO 802.11n USB */ + { USB_DEVICE(0x1435, 0x0804) }, + /* WNC Generic 11n USB Dongle */ + { USB_DEVICE(0x1435, 0x0326) }, + /* ZyXEL NWD271N */ + { USB_DEVICE(0x0586, 0x3417) }, + /* Z-Com UB81 BG */ + { USB_DEVICE(0x0cde, 0x0023) }, + /* Z-Com UB82 ABG */ + { USB_DEVICE(0x0cde, 0x0026) }, + /* Sphairon Homelink 1202 */ + { USB_DEVICE(0x0cde, 0x0027) }, + /* Arcadyan WN7512 */ + { USB_DEVICE(0x083a, 0xf522) }, + /* Planex GWUS300 */ + { USB_DEVICE(0x2019, 0x5304) }, + /* IO-Data WNGDNUS2 */ + { USB_DEVICE(0x04bb, 0x093f) }, + /* NEC WL300NU-G */ + { USB_DEVICE(0x0409, 0x0249) }, + /* AVM FRITZ!WLAN USB Stick N */ + { USB_DEVICE(0x057c, 0x8401) }, + /* AVM FRITZ!WLAN USB Stick N 2.4 */ + { USB_DEVICE(0x057c, 0x8402) }, + /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ + { USB_DEVICE(0x1668, 0x1200) }, + + /* terminate */ + {} +}; +MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); + +static void carl9170_usb_submit_data_urb(struct ar9170 *ar) +{ + struct urb *urb; + int err; + + if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS) + goto err_acc; + + urb = usb_get_from_anchor(&ar->tx_wait); + if (!urb) + goto err_acc; + + usb_anchor_urb(urb, &ar->tx_anch); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + if (net_ratelimit()) { + dev_err(&ar->udev->dev, "tx submit failed (%d)\n", + urb->status); + } + + usb_unanchor_urb(urb); + usb_anchor_urb(urb, &ar->tx_err); + } + + usb_free_urb(urb); + + if (likely(err == 0)) + return; + +err_acc: + atomic_dec(&ar->tx_anch_urbs); +} + +static void carl9170_usb_tx_data_complete(struct urb *urb) +{ + struct ar9170 *ar = (struct ar9170 *) + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + + if (WARN_ON_ONCE(!ar)) { + dev_kfree_skb_irq(urb->context); + return; + } + + atomic_dec(&ar->tx_anch_urbs); + + switch (urb->status) { + /* everything is fine */ + case 0: + carl9170_tx_callback(ar, (void *)urb->context); + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + /* + * Defer the frame clean-up to the tasklet worker. + * This is necessary, because carl9170_tx_drop + * does not work in an irqsave context. + */ + usb_anchor_urb(urb, &ar->tx_err); + return; + + /* a random transmission error has occurred? */ + default: + if (net_ratelimit()) { + dev_err(&ar->udev->dev, "tx failed (%d)\n", + urb->status); + } + + usb_anchor_urb(urb, &ar->tx_err); + break; + } + + if (likely(IS_STARTED(ar))) + carl9170_usb_submit_data_urb(ar); +} + +static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar) +{ + struct urb *urb; + int err; + + if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) { + atomic_dec(&ar->tx_cmd_urbs); + return 0; + } + + urb = usb_get_from_anchor(&ar->tx_cmd); + if (!urb) { + atomic_dec(&ar->tx_cmd_urbs); + return 0; + } + + usb_anchor_urb(urb, &ar->tx_anch); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + usb_unanchor_urb(urb); + atomic_dec(&ar->tx_cmd_urbs); + } + usb_free_urb(urb); + + return err; +} + +static void carl9170_usb_cmd_complete(struct urb *urb) +{ + struct ar9170 *ar = urb->context; + int err = 0; + + if (WARN_ON_ONCE(!ar)) + return; + + atomic_dec(&ar->tx_cmd_urbs); + + switch (urb->status) { + /* everything is fine */ + case 0: + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + return; + + default: + err = urb->status; + break; + } + + if (!IS_INITIALIZED(ar)) + return; + + if (err) + dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err); + + err = carl9170_usb_submit_cmd_urb(ar); + if (err) + dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err); +} + +static void carl9170_usb_rx_irq_complete(struct urb *urb) +{ + struct ar9170 *ar = urb->context; + + if (WARN_ON_ONCE(!ar)) + return; + + switch (urb->status) { + /* everything is fine */ + case 0: + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + return; + + default: + goto resubmit; + } + + carl9170_handle_command_response(ar, urb->transfer_buffer, + urb->actual_length); + +resubmit: + usb_anchor_urb(urb, &ar->rx_anch); + if (unlikely(usb_submit_urb(urb, GFP_ATOMIC))) + usb_unanchor_urb(urb); +} + +static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp) +{ + struct urb *urb; + int err = 0, runs = 0; + + while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) && + (runs++ < AR9170_NUM_RX_URBS)) { + err = -ENOSPC; + urb = usb_get_from_anchor(&ar->rx_pool); + if (urb) { + usb_anchor_urb(urb, &ar->rx_anch); + err = usb_submit_urb(urb, gfp); + if (unlikely(err)) { + usb_unanchor_urb(urb); + usb_anchor_urb(urb, &ar->rx_pool); + } else { + atomic_dec(&ar->rx_pool_urbs); + atomic_inc(&ar->rx_anch_urbs); + } + usb_free_urb(urb); + } + } + + return err; +} + +static void carl9170_usb_rx_work(struct ar9170 *ar) +{ + struct urb *urb; + int i; + + for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { + urb = usb_get_from_anchor(&ar->rx_work); + if (!urb) + break; + + atomic_dec(&ar->rx_work_urbs); + if (IS_INITIALIZED(ar)) { + carl9170_rx(ar, urb->transfer_buffer, + urb->actual_length); + } + + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + + usb_free_urb(urb); + + carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); + } +} + +void carl9170_usb_handle_tx_err(struct ar9170 *ar) +{ + struct urb *urb; + + while ((urb = usb_get_from_anchor(&ar->tx_err))) { + struct sk_buff *skb = (void *)urb->context; + + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); + usb_free_urb(urb); + } +} + +static void carl9170_usb_tasklet(unsigned long data) +{ + struct ar9170 *ar = (struct ar9170 *) data; + + carl9170_usb_rx_work(ar); + + /* + * Strictly speaking: The tx scheduler is not part of the USB system. + * But the rx worker returns frames back to the mac80211-stack and + * this is the _perfect_ place to generate the next transmissions. + */ + if (IS_STARTED(ar)) + carl9170_tx_scheduler(ar); +} + +static void carl9170_usb_rx_complete(struct urb *urb) +{ + struct ar9170 *ar = (struct ar9170 *)urb->context; + int err; + + if (WARN_ON_ONCE(!ar)) + return; + + atomic_dec(&ar->rx_anch_urbs); + + switch (urb->status) { + case 0: + /* rx path */ + usb_anchor_urb(urb, &ar->rx_work); + atomic_inc(&ar->rx_work_urbs); + break; + + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + /* handle disconnect events*/ + return; + + default: + /* handle all other errors */ + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + break; + } + + err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); + if (unlikely(err)) { + /* + * usb_submit_rx_urb reported a problem. + * In case this is due to a rx buffer shortage, + * elevate the tasklet worker priority to + * the highest available level. + */ + tasklet_hi_schedule(&ar->usb_tasklet); + + if (atomic_read(&ar->rx_anch_urbs) == 0) { + /* + * The system is too slow to cope with + * the enormous workload. We have simply + * run out of active rx urbs and this + * unfortunatly leads to an unpredictable + * device. + */ + + carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM); + } + } else { + /* + * Using anything less than _high_ priority absolutely + * kills the rx performance my UP-System... + */ + tasklet_hi_schedule(&ar->usb_tasklet); + } +} + +static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp) +{ + struct urb *urb; + void *buf; + + buf = kmalloc(ar->fw.rx_size, gfp); + if (!buf) + return NULL; + + urb = usb_alloc_urb(0, gfp); + if (!urb) { + kfree(buf); + return NULL; + } + + usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev, + AR9170_USB_EP_RX), buf, ar->fw.rx_size, + carl9170_usb_rx_complete, ar); + + urb->transfer_flags |= URB_FREE_BUFFER; + + return urb; +} + +static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar) +{ + struct urb *urb = NULL; + void *ibuf; + int err = -ENOMEM; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + goto out; + + ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL); + if (!ibuf) + goto out; + + usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev, + AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX, + carl9170_usb_rx_irq_complete, ar, 1); + + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_anchor_urb(urb, &ar->rx_anch); + err = usb_submit_urb(urb, GFP_KERNEL); + if (err) + usb_unanchor_urb(urb); + +out: + usb_free_urb(urb); + return err; +} + +static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar) +{ + struct urb *urb; + int i, err = -EINVAL; + + /* + * The driver actively maintains a second shadow + * pool for inactive, but fully-prepared rx urbs. + * + * The pool should help the driver to master huge + * workload spikes without running the risk of + * undersupplying the hardware or wasting time by + * processing rx data (streams) inside the urb + * completion (hardirq context). + */ + for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { + urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL); + if (!urb) { + err = -ENOMEM; + goto err_out; + } + + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + usb_free_urb(urb); + } + + err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL); + if (err) + goto err_out; + + /* the device now waiting for the firmware. */ + carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); + return 0; + +err_out: + + usb_scuttle_anchored_urbs(&ar->rx_pool); + usb_scuttle_anchored_urbs(&ar->rx_work); + usb_kill_anchored_urbs(&ar->rx_anch); + return err; +} + +static int carl9170_usb_flush(struct ar9170 *ar) +{ + struct urb *urb; + int ret, err = 0; + + while ((urb = usb_get_from_anchor(&ar->tx_wait))) { + struct sk_buff *skb = (void *)urb->context; + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); + usb_free_urb(urb); + } + + ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ); + if (ret == 0) + err = -ETIMEDOUT; + + /* lets wait a while until the tx - queues are dried out */ + ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ); + if (ret == 0) + err = -ETIMEDOUT; + + usb_kill_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + + return err; +} + +static void carl9170_usb_cancel_urbs(struct ar9170 *ar) +{ + int err; + + carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); + + err = carl9170_usb_flush(ar); + if (err) + dev_err(&ar->udev->dev, "stuck tx urbs!\n"); + + usb_poison_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + usb_poison_anchored_urbs(&ar->rx_anch); + + tasklet_kill(&ar->usb_tasklet); + + usb_scuttle_anchored_urbs(&ar->rx_work); + usb_scuttle_anchored_urbs(&ar->rx_pool); + usb_scuttle_anchored_urbs(&ar->tx_cmd); +} + +int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, + const bool free_buf) +{ + struct urb *urb; + + if (!IS_INITIALIZED(ar)) + return -EPERM; + + if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) + return -EINVAL; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, + AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, + carl9170_usb_cmd_complete, ar, 1); + + urb->transfer_flags |= URB_ZERO_PACKET; + + if (free_buf) + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_anchor_urb(urb, &ar->tx_cmd); + usb_free_urb(urb); + + return carl9170_usb_submit_cmd_urb(ar); +} + +int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, + unsigned int plen, void *payload, unsigned int outlen, void *out) +{ + int err = -ENOMEM; + + if (!IS_ACCEPTING_CMD(ar)) + return -EIO; + + if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) + might_sleep(); + + ar->cmd.hdr.len = plen; + ar->cmd.hdr.cmd = cmd; + /* writing multiple regs fills this buffer already */ + if (plen && payload != (u8 *)(ar->cmd.data)) + memcpy(ar->cmd.data, payload, plen); + + spin_lock_bh(&ar->cmd_lock); + ar->readbuf = (u8 *)out; + ar->readlen = outlen; + spin_unlock_bh(&ar->cmd_lock); + + err = __carl9170_exec_cmd(ar, &ar->cmd, false); + + if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { + err = wait_for_completion_timeout(&ar->cmd_wait, HZ); + if (err == 0) { + err = -ETIMEDOUT; + goto err_unbuf; + } + + if (ar->readlen != outlen) { + err = -EMSGSIZE; + goto err_unbuf; + } + } + + return 0; + +err_unbuf: + /* Maybe the device was removed in the moment we were waiting? */ + if (IS_STARTED(ar)) { + dev_err(&ar->udev->dev, "no command feedback " + "received (%d).\n", err); + + /* provide some maybe useful debug information */ + print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE, + &ar->cmd, plen + 4); + + carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT); + } + + /* invalidate to avoid completing the next command prematurely */ + spin_lock_bh(&ar->cmd_lock); + ar->readbuf = NULL; + ar->readlen = 0; + spin_unlock_bh(&ar->cmd_lock); + + return err; +} + +void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) +{ + struct urb *urb; + struct ar9170_stream *tx_stream; + void *data; + unsigned int len; + + if (!IS_STARTED(ar)) + goto err_drop; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + goto err_drop; + + if (ar->fw.tx_stream) { + tx_stream = (void *) (skb->data - sizeof(*tx_stream)); + + len = skb->len + sizeof(*tx_stream); + tx_stream->length = cpu_to_le16(len); + tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG); + data = tx_stream; + } else { + data = skb->data; + len = skb->len; + } + + usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, + AR9170_USB_EP_TX), data, len, + carl9170_usb_tx_data_complete, skb); + + urb->transfer_flags |= URB_ZERO_PACKET; + + usb_anchor_urb(urb, &ar->tx_wait); + + usb_free_urb(urb); + + carl9170_usb_submit_data_urb(ar); + return; + +err_drop: + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); +} + +static void carl9170_release_firmware(struct ar9170 *ar) +{ + if (ar->fw.fw) { + release_firmware(ar->fw.fw); + memset(&ar->fw, 0, sizeof(ar->fw)); + } +} + +void carl9170_usb_stop(struct ar9170 *ar) +{ + int ret; + + carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED); + + ret = carl9170_usb_flush(ar); + if (ret) + dev_err(&ar->udev->dev, "kill pending tx urbs.\n"); + + usb_poison_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + + /* kill any pending command */ + spin_lock_bh(&ar->cmd_lock); + ar->readlen = 0; + spin_unlock_bh(&ar->cmd_lock); + complete_all(&ar->cmd_wait); + + /* This is required to prevent an early completion on _start */ + INIT_COMPLETION(ar->cmd_wait); + + /* + * Note: + * So far we freed all tx urbs, but we won't dare to touch any rx urbs. + * Else we would end up with a unresponsive device... + */ +} + +int carl9170_usb_open(struct ar9170 *ar) +{ + usb_unpoison_anchored_urbs(&ar->tx_anch); + + carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); + return 0; +} + +static int carl9170_usb_load_firmware(struct ar9170 *ar) +{ + const u8 *data; + u8 *buf; + unsigned int transfer; + size_t len; + u32 addr; + int err = 0; + + buf = kmalloc(4096, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto err_out; + } + + data = ar->fw.fw->data; + len = ar->fw.fw->size; + addr = ar->fw.address; + + /* this removes the miniboot image */ + data += ar->fw.offset; + len -= ar->fw.offset; + + while (len) { + transfer = min_t(unsigned int, len, 4096u); + memcpy(buf, data, transfer); + + err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), + 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, + addr >> 8, 0, buf, transfer, 100); + + if (err < 0) { + kfree(buf); + goto err_out; + } + + len -= transfer; + data += transfer; + addr += transfer; + } + kfree(buf); + + err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), + 0x31 /* FW DL COMPLETE */, + 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200); + + if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) { + err = -ETIMEDOUT; + goto err_out; + } + + err = carl9170_echo_test(ar, 0x4a110123); + if (err) + goto err_out; + + /* firmware restarts cmd counter */ + ar->cmd_seq = -1; + + return 0; + +err_out: + dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err); + return err; +} + +int carl9170_usb_restart(struct ar9170 *ar) +{ + int err = 0; + + if (ar->intf->condition != USB_INTERFACE_BOUND) + return 0; + + /* Disable command response sequence counter. */ + ar->cmd_seq = -2; + + err = carl9170_reboot(ar); + + carl9170_usb_stop(ar); + + carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); + + if (err) + goto err_out; + + tasklet_schedule(&ar->usb_tasklet); + + /* The reboot procedure can take quite a while to complete. */ + msleep(1100); + + err = carl9170_usb_open(ar); + if (err) + goto err_out; + + err = carl9170_usb_load_firmware(ar); + if (err) + goto err_out; + + return 0; + +err_out: + carl9170_usb_cancel_urbs(ar); + return err; +} + +void carl9170_usb_reset(struct ar9170 *ar) +{ + /* + * This is the last resort to get the device going again + * without any *user replugging action*. + * + * But there is a catch: usb_reset really is like a physical + * *reconnect*. The mac80211 state will be lost in the process. + * Therefore a userspace application, which is monitoring + * the link must step in. + */ + carl9170_usb_cancel_urbs(ar); + + carl9170_usb_stop(ar); + + usb_queue_reset_device(ar->intf); +} + +static int carl9170_usb_init_device(struct ar9170 *ar) +{ + int err; + + err = carl9170_usb_send_rx_irq_urb(ar); + if (err) + goto err_out; + + err = carl9170_usb_init_rx_bulk_urbs(ar); + if (err) + goto err_unrx; + + mutex_lock(&ar->mutex); + err = carl9170_usb_load_firmware(ar); + mutex_unlock(&ar->mutex); + if (err) + goto err_unrx; + + return 0; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + +err_out: + return err; +} + +static void carl9170_usb_firmware_failed(struct ar9170 *ar) +{ + struct device *parent = ar->udev->dev.parent; + struct usb_device *udev; + + /* + * Store a copy of the usb_device pointer locally. + * This is because device_release_driver initiates + * carl9170_usb_disconnect, which in turn frees our + * driver context (ar). + */ + udev = ar->udev; + + complete(&ar->fw_load_wait); + + /* unbind anything failed */ + if (parent) + device_lock(parent); + + device_release_driver(&udev->dev); + if (parent) + device_unlock(parent); + + usb_put_dev(udev); +} + +static void carl9170_usb_firmware_finish(struct ar9170 *ar) +{ + int err; + + err = carl9170_parse_firmware(ar); + if (err) + goto err_freefw; + + err = carl9170_usb_init_device(ar); + if (err) + goto err_freefw; + + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + + err = carl9170_register(ar); + + carl9170_usb_stop(ar); + if (err) + goto err_unrx; + + complete(&ar->fw_load_wait); + usb_put_dev(ar->udev); + return; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + +err_freefw: + carl9170_release_firmware(ar); + carl9170_usb_firmware_failed(ar); +} + +static void carl9170_usb_firmware_step2(const struct firmware *fw, + void *context) +{ + struct ar9170 *ar = context; + + if (fw) { + ar->fw.fw = fw; + carl9170_usb_firmware_finish(ar); + return; + } + + dev_err(&ar->udev->dev, "firmware not found.\n"); + carl9170_usb_firmware_failed(ar); +} + +static int carl9170_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct ar9170 *ar; + struct usb_device *udev; + int err; + + err = usb_reset_device(interface_to_usbdev(intf)); + if (err) + return err; + + ar = carl9170_alloc(sizeof(*ar)); + if (IS_ERR(ar)) + return PTR_ERR(ar); + + udev = interface_to_usbdev(intf); + usb_get_dev(udev); + ar->udev = udev; + ar->intf = intf; + ar->features = id->driver_info; + + usb_set_intfdata(intf, ar); + SET_IEEE80211_DEV(ar->hw, &intf->dev); + + init_usb_anchor(&ar->rx_anch); + init_usb_anchor(&ar->rx_pool); + init_usb_anchor(&ar->rx_work); + init_usb_anchor(&ar->tx_wait); + init_usb_anchor(&ar->tx_anch); + init_usb_anchor(&ar->tx_cmd); + init_usb_anchor(&ar->tx_err); + init_completion(&ar->cmd_wait); + init_completion(&ar->fw_boot_wait); + init_completion(&ar->fw_load_wait); + tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, + (unsigned long)ar); + + atomic_set(&ar->tx_cmd_urbs, 0); + atomic_set(&ar->tx_anch_urbs, 0); + atomic_set(&ar->rx_work_urbs, 0); + atomic_set(&ar->rx_anch_urbs, 0); + atomic_set(&ar->rx_pool_urbs, 0); + ar->cmd_seq = -2; + + usb_get_dev(ar->udev); + + carl9170_set_state(ar, CARL9170_STOPPED); + + return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); +} + +static void carl9170_usb_disconnect(struct usb_interface *intf) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + struct usb_device *udev; + + if (WARN_ON(!ar)) + return; + + udev = ar->udev; + wait_for_completion(&ar->fw_load_wait); + + if (IS_INITIALIZED(ar)) { + carl9170_reboot(ar); + carl9170_usb_stop(ar); + } + + carl9170_usb_cancel_urbs(ar); + carl9170_unregister(ar); + + usb_set_intfdata(intf, NULL); + + carl9170_release_firmware(ar); + carl9170_free(ar); + usb_put_dev(udev); +} + +#ifdef CONFIG_PM +static int carl9170_usb_suspend(struct usb_interface *intf, + pm_message_t message) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + + if (!ar) + return -ENODEV; + + carl9170_usb_cancel_urbs(ar); + + /* + * firmware automatically reboots for usb suspend. + */ + + return 0; +} + +static int carl9170_usb_resume(struct usb_interface *intf) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + int err; + + if (!ar) + return -ENODEV; + + usb_unpoison_anchored_urbs(&ar->rx_anch); + + err = carl9170_usb_init_device(ar); + if (err) + goto err_unrx; + + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + + return 0; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + + return err; +} +#endif /* CONFIG_PM */ + +static struct usb_driver carl9170_driver = { + .name = KBUILD_MODNAME, + .probe = carl9170_usb_probe, + .disconnect = carl9170_usb_disconnect, + .id_table = carl9170_usb_ids, + .soft_unbind = 1, +#ifdef CONFIG_PM + .suspend = carl9170_usb_suspend, + .resume = carl9170_usb_resume, +#endif /* CONFIG_PM */ +}; + +static int __init carl9170_usb_init(void) +{ + return usb_register(&carl9170_driver); +} + +static void __exit carl9170_usb_exit(void) +{ + usb_deregister(&carl9170_driver); +} + +module_init(carl9170_usb_init); +module_exit(carl9170_usb_exit); -- cgit v1.2.3 From 00c4da27a4219385cfe6a3054ddf3195c9e3c30e Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 01:09:49 +0200 Subject: carl9170: firmware parser and debugfs code Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/debug.c | 908 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/debug.h | 134 +++++ drivers/net/wireless/ath/carl9170/fw.c | 395 +++++++++++++ 3 files changed, 1437 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/debug.c create mode 100644 drivers/net/wireless/ath/carl9170/debug.h create mode 100644 drivers/net/wireless/ath/carl9170/fw.c diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c new file mode 100644 index 000000000000..3e9b0e8b2b8c --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/debug.c @@ -0,0 +1,908 @@ +/* + * Atheros CARL9170 driver + * + * debug(fs) probing + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2008-2009 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "cmd.h" + +#define ADD(buf, off, max, fmt, args...) \ + off += snprintf(&buf[off], max - off, fmt, ##args); + +static int carl9170_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +struct carl9170_debugfs_fops { + unsigned int read_bufsize; + mode_t attr; + char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize, + ssize_t *len); + ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size); + const struct file_operations fops; + + enum carl9170_device_state req_dev_state; +}; + +static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct carl9170_debugfs_fops *dfops; + struct ar9170 *ar; + char *buf = NULL, *res_buf = NULL; + ssize_t ret = 0; + int err = 0; + + if (!count) + return 0; + + ar = file->private_data; + + if (!ar) + return -ENODEV; + dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + + if (!dfops->read) + return -ENOSYS; + + if (dfops->read_bufsize) { + buf = vmalloc(dfops->read_bufsize); + if (!buf) + return -ENOMEM; + } + + mutex_lock(&ar->mutex); + if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { + err = -ENODEV; + res_buf = buf; + goto out_free; + } + + res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret); + + if (ret > 0) + err = simple_read_from_buffer(userbuf, count, ppos, + res_buf, ret); + else + err = ret; + + WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf)); + +out_free: + vfree(res_buf); + mutex_unlock(&ar->mutex); + return err; +} + +static ssize_t carl9170_debugfs_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct carl9170_debugfs_fops *dfops; + struct ar9170 *ar; + char *buf = NULL; + int err = 0; + + if (!count) + return 0; + + if (count > PAGE_SIZE) + return -E2BIG; + + ar = file->private_data; + + if (!ar) + return -ENODEV; + dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + + if (!dfops->write) + return -ENOSYS; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, userbuf, count)) { + err = -EFAULT; + goto out_free; + } + + if (mutex_trylock(&ar->mutex) == 0) { + err = -EAGAIN; + goto out_free; + } + + if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { + err = -ENODEV; + goto out_unlock; + } + + err = dfops->write(ar, buf, count); + if (err) + goto out_unlock; + +out_unlock: + mutex_unlock(&ar->mutex); + +out_free: + vfree(buf); + return err; +} + +#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ + _attr, _dstate) \ +static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ + .read_bufsize = _read_bufsize, \ + .read = _read, \ + .write = _write, \ + .attr = _attr, \ + .req_dev_state = _dstate, \ + .fops = { \ + .open = carl9170_debugfs_open, \ + .read = carl9170_debugfs_read, \ + .write = carl9170_debugfs_write, \ + .owner = THIS_MODULE \ + }, \ +} + +#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \ + __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ + _attr, CARL9170_STARTED) \ + +#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ + DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + NULL, _read_bufsize, S_IRUSR) + +#define DEBUGFS_DECLARE_WO_FILE(name) \ + DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ + 0, S_IWUSR) + +#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ + DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + carl9170_debugfs_##name ##_write, \ + _read_bufsize, S_IRUSR | S_IWUSR) + +#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ + __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + carl9170_debugfs_##name ##_write, \ + _read_bufsize, S_IRUSR | S_IWUSR, _dstate) + +#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ +static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ + char *buf, size_t buf_size,\ + ssize_t *len) \ +{ \ + ADD(buf, *len, buf_size, fmt "\n", ##value); \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) + +static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "jar: ["); + + spin_lock_bh(&ar->mem_lock); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + ar->mem_bitmap, ar->fw.mem_blocks); + + ADD(buf, *len, bufsize, "]\n"); + + ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n", + bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks), + ar->fw.mem_blocks, atomic_read(&ar->mem_allocs)); + + ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n", + atomic_read(&ar->mem_free_blocks), + (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024, + (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024); + + spin_unlock_bh(&ar->mem_lock); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(mem_usage, 512); + +static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" : + "Software"); + + ADD(buf, *len, bufsize, "[ VO VI " + " BE BK ]\n"); + + spin_lock_bh(&ar->tx_stats_lock); + ADD(buf, *len, bufsize, "[length/limit length/limit " + "length/limit length/limit ]\n" + "[ %3d/%3d %3d/%3d " + " %3d/%3d %3d/%3d ]\n\n", + ar->tx_stats[0].len, ar->tx_stats[0].limit, + ar->tx_stats[1].len, ar->tx_stats[1].limit, + ar->tx_stats[2].len, ar->tx_stats[2].limit, + ar->tx_stats[3].len, ar->tx_stats[3].limit); + + ADD(buf, *len, bufsize, "[ total total " + " total total ]\n" + "[%10d %10d %10d %10d ]\n\n", + ar->tx_stats[0].count, ar->tx_stats[1].count, + ar->tx_stats[2].count, ar->tx_stats[3].count); + + spin_unlock_bh(&ar->tx_stats_lock); + + ADD(buf, *len, bufsize, "[ pend/waittx pend/waittx " + " pend/waittx pend/waittx]\n" + "[ %3d/%3d %3d/%3d " + " %3d/%3d %3d/%3d ]\n\n", + skb_queue_len(&ar->tx_pending[0]), + skb_queue_len(&ar->tx_status[0]), + skb_queue_len(&ar->tx_pending[1]), + skb_queue_len(&ar->tx_status[1]), + skb_queue_len(&ar->tx_pending[2]), + skb_queue_len(&ar->tx_status[2]), + skb_queue_len(&ar->tx_pending[3]), + skb_queue_len(&ar->tx_status[3])); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(qos_stat, 512); + +static void carl9170_debugfs_format_frame(struct ar9170 *ar, + struct sk_buff *skb, const char *prefix, char *buf, + ssize_t *off, ssize_t bufsize) +{ + struct _carl9170_tx_superframe *txc = (void *) skb->data; + struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); + struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; + struct ieee80211_hdr *hdr = (void *) txc->frame_data; + + ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, " + "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie, + ieee80211_get_DA(hdr), get_seq_h(hdr), + le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control), + jiffies_to_msecs(jiffies - arinfo->timeout)); +} + + +static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + struct carl9170_sta_tid *iter; + struct sk_buff *skb; + int cnt = 0, fc; + int offset; + + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { + + spin_lock_bh(&iter->lock); + ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, " + "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n", + cnt, iter->tid, iter->bsn, iter->snx, iter->hsn, + iter->max, iter->state, iter->counter); + + ADD(buf, *len, bufsize, "\tWindow: ["); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + iter->bitmap, CARL9170_BAW_BITS); + +#define BM_STR_OFF(offset) \ + ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \ + (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1) + + ADD(buf, *len, bufsize, ",W]\n"); + + offset = BM_STR_OFF(0); + ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T"); + + offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn)); + ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W"); + + offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) % + CARL9170_BAW_BITS); + ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N"); + + ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: " + " currently queued:%d\n", skb_queue_len(&iter->queue)); + + fc = 0; + skb_queue_walk(&iter->queue, skb) { + char prefix[32]; + + snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc); + carl9170_debugfs_format_frame(ar, skb, prefix, buf, + len, bufsize); + + fc++; + } + spin_unlock_bh(&iter->lock); + cnt++; + } + rcu_read_unlock(); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000); + +static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf, + ssize_t *len, size_t bufsize, struct sk_buff_head *queue) +{ + struct sk_buff *skb; + char prefix[16]; + int fc = 0; + + spin_lock_bh(&queue->lock); + skb_queue_walk(queue, skb) { + snprintf(prefix, sizeof(prefix), "%3d :", fc); + carl9170_debugfs_format_frame(ar, skb, prefix, buf, + len, bufsize); + fc++; + } + spin_unlock_bh(&queue->lock); +} + +#define DEBUGFS_QUEUE_DUMP(q, qi) \ +static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar, \ + char *buf, size_t bufsize, ssize_t *len) \ +{ \ + carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000); + +static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ? + "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM"))); + + ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms); + ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n", + jiffies_to_msecs(jiffies - ar->ps.last_action)); + ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n", + jiffies_to_msecs(jiffies - ar->ps.last_slept)); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(sta_psm, 160); + +static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + int i; + + for (i = 0; i < ar->hw->queues; i++) { + ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n", + i, ieee80211_queue_stopped(ar->hw, i) ? + jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0, + jiffies_to_msecs(ar->max_queue_stop_timeout[i])); + + ar->max_queue_stop_timeout[i] = 0; + } + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180); + +static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + int err; + + err = carl9170_get_noisefloor(ar); + if (err) { + *len = err; + return buf; + } + + ADD(buf, *len, bufsize, "Chain 1: %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[1], ar->noise[4]); + ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[2], ar->noise[5]); + ADD(buf, *len, bufsize, "Combined %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[0], ar->noise[3]); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(phy_noise, 180); + +static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + struct carl9170_vif_info *iter; + int i = 0; + + ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n", + ar->vifs, ar->fw.vif_num); + + ADD(buf, *len, bufsize, "VIF bitmap: ["); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + &ar->vif_bitmap, ar->fw.vif_num); + + ADD(buf, *len, bufsize, "]\n"); + + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->vif_list, list) { + struct ieee80211_vif *vif = carl9170_get_vif(iter); + ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x " + " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ? + "Master" : " Slave"), iter->id, vif->type, vif->addr, + iter->enable_beacon ? "beaconing " : ""); + i++; + } + rcu_read_unlock(); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000); + +#define UPDATE_COUNTER(ar, name) ({ \ + u32 __tmp[ARRAY_SIZE(name##_regs)]; \ + unsigned int __i, __err = -ENODEV; \ + \ + for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ + __tmp[__i] = name##_regs[__i].reg; \ + ar->debug.stats.name##_counter[__i] = 0; \ + } \ + \ + if (IS_STARTED(ar)) \ + __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \ + __tmp, ar->debug.stats.name##_counter); \ + (__err); }) + +#define TALLY_SUM_UP(ar, name) do { \ + unsigned int __i; \ + \ + for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ + ar->debug.stats.name##_sum[__i] += \ + ar->debug.stats.name##_counter[__i]; \ + } \ +} while (0) + +#define DEBUGFS_HW_TALLY_FILE(name, f) \ +static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ + char *dum, size_t bufsize, ssize_t *ret) \ +{ \ + char *buf; \ + int i, max_len, err; \ + \ + max_len = ARRAY_SIZE(name##_regs) * 80; \ + buf = vmalloc(max_len); \ + if (!buf) \ + return NULL; \ + \ + err = UPDATE_COUNTER(ar, name); \ + if (err) { \ + *ret = err; \ + return buf; \ + } \ + \ + TALLY_SUM_UP(ar, name); \ + \ + for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ + ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \ + name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\ + ar->debug.stats.name ##_counter[i]); \ + } \ + \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, 0); + +#define DEBUGFS_HW_REG_FILE(name, f) \ +static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ + char *dum, size_t bufsize, ssize_t *ret) \ +{ \ + char *buf; \ + int i, max_len, err; \ + \ + max_len = ARRAY_SIZE(name##_regs) * 80; \ + buf = vmalloc(max_len); \ + if (!buf) \ + return NULL; \ + \ + err = UPDATE_COUNTER(ar, name); \ + if (err) { \ + *ret = err; \ + return buf; \ + } \ + \ + for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ + ADD(buf, *ret, max_len, "%22s = %" f "\n", \ + name##_regs[i].nreg, \ + ar->debug.stats.name##_counter[i]); \ + } \ + \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, 0); + +static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar, + const char *buf, size_t count) +{ + int err = 0, i, n = 0, max_len = 32, res; + unsigned int reg, tmp; + + if (!count) + return 0; + + if (count > max_len) + return -E2BIG; + + res = sscanf(buf, "0x%X %d", ®, &n); + if (res < 1) { + err = -EINVAL; + goto out; + } + + if (res == 1) + n = 1; + + if (n > 15) { + err = -EMSGSIZE; + goto out; + } + + if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) { + err = -EADDRNOTAVAIL; + goto out; + } + + if (reg & 3) { + err = -EINVAL; + goto out; + } + + for (i = 0; i < n; i++) { + err = carl9170_read_reg(ar, reg + (i << 2), &tmp); + if (err) + goto out; + + ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2); + ar->debug.ring[ar->debug.ring_tail].value = tmp; + ar->debug.ring_tail++; + ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE; + } + +out: + return err ? err : count; +} + +static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + int i = 0; + + while (ar->debug.ring_head != ar->debug.ring_tail) { + ADD(buf, *ret, bufsize, "%.8x = %.8x\n", + ar->debug.ring[ar->debug.ring_head].reg, + ar->debug.ring[ar->debug.ring_head].value); + + ar->debug.ring_head++; + ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE; + + if (i++ == 64) + break; + } + ar->debug.ring_head = ar->debug.ring_tail; + return buf; +} +DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40); + +static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf, + size_t count) +{ + int err; + + if (count < 1) + return -EINVAL; + + switch (buf[0]) { + case 'F': + ar->needs_full_reset = true; + break; + + case 'R': + if (!IS_STARTED(ar)) { + err = -EAGAIN; + goto out; + } + + ar->needs_full_reset = false; + break; + + case 'M': + err = carl9170_mac_reset(ar); + if (err < 0) + count = err; + + goto out; + + case 'P': + err = carl9170_set_channel(ar, ar->hw->conf.channel, + ar->hw->conf.channel_type, CARL9170_RFI_COLD); + if (err < 0) + count = err; + + goto out; + + default: + return -EINVAL; + } + + carl9170_restart(ar, CARL9170_RR_USER_REQUEST); + +out: + return count; +} + +static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, " + "[M]ac reset\n"); + ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n", + ar->restart_counter, ar->last_reason); + ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n", + ar->total_chan_fail, ar->chan_fail); + ADD(buf, *ret, bufsize, "reported firmware errors:%d\n", + ar->fw.err_counter); + ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n", + ar->fw.bug_counter); + ADD(buf, *ret, bufsize, "pending restart requests:%d\n", + atomic_read(&ar->pending_restarts)); + return buf; +} +__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED); + +static const char *erp_modes[] = { + [CARL9170_ERP_INVALID] = "INVALID", + [CARL9170_ERP_AUTO] = "Automatic", + [CARL9170_ERP_MAC80211] = "Set by MAC80211", + [CARL9170_ERP_OFF] = "Force Off", + [CARL9170_ERP_RTS] = "Force RTS", + [CARL9170_ERP_CTS] = "Force CTS" +}; + +static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode, + erp_modes[ar->erp_mode]); + return buf; +} + +static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf, + size_t count) +{ + int res, val; + + if (count < 1) + return -EINVAL; + + res = sscanf(buf, "%d", &val); + if (res != 1) + return -EINVAL; + + if (!((val > CARL9170_ERP_INVALID) && + (val < __CARL9170_ERP_NUM))) + return -EINVAL; + + ar->erp_mode = val; + return count; +} + +DEBUGFS_DECLARE_RW_FILE(erp, 80); + +static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar, + const char *buf, size_t count) +{ + int err = 0, max_len = 22, res; + u32 reg, val; + + if (!count) + return 0; + + if (count > max_len) + return -E2BIG; + + res = sscanf(buf, "0x%X 0x%X", ®, &val); + if (res != 2) { + err = -EINVAL; + goto out; + } + + if (reg <= 0x100000 || reg >= 0x280000) { + err = -EADDRNOTAVAIL; + goto out; + } + + if (reg & 3) { + err = -EINVAL; + goto out; + } + + err = carl9170_write_reg(ar, reg, val); + if (err) + goto out; + +out: + return err ? err : count; +} +DEBUGFS_DECLARE_WO_FILE(hw_iowrite32); + +DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u"); +DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u"); +DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u"); +DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x"); +DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x"); +DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x"); +DEBUGFS_QUEUE_DUMP(tx_status, 0); +DEBUGFS_QUEUE_DUMP(tx_status, 1); +DEBUGFS_QUEUE_DUMP(tx_status, 2); +DEBUGFS_QUEUE_DUMP(tx_status, 3); +DEBUGFS_QUEUE_DUMP(tx_pending, 0); +DEBUGFS_QUEUE_DUMP(tx_pending, 1); +DEBUGFS_QUEUE_DUMP(tx_pending, 2); +DEBUGFS_QUEUE_DUMP(tx_pending, 3); +DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d", + atomic_read(&ar->tx_anch_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d", + atomic_read(&ar->rx_anch_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d", + atomic_read(&ar->rx_work_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d", + atomic_read(&ar->rx_pool_urbs)); + +DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d", + atomic_read(&ar->tx_total_queued)); +DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d", + atomic_read(&ar->tx_ampdu_scheduler)); +DEBUGFS_READONLY_FILE(tx_ampdu_timeout, 20, "%d", + ar->tx_ampdu_timeout); + +DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d", + atomic_read(&ar->tx_total_pending)); + +DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d", + ar->tx_ampdu_list_len); + +DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d", + atomic_read(&ar->tx_ampdu_upload)); + +DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago", + jiffies_to_msecs(jiffies - ar->tx_janitor_last_run)); + +DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped); + +DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped); + +DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled); +DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d", + ar->rx_software_decryption); +DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d", + ar->current_factor); +DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d", + ar->current_density); + +DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int); +DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt); + +void carl9170_debugfs_register(struct ar9170 *ar) +{ + ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME, + ar->hw->wiphy->debugfsdir); + +#define DEBUGFS_ADD(name) \ + debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \ + ar->debug_dir, ar, \ + &carl_debugfs_##name ## _ops.fops); + + DEBUGFS_ADD(usb_tx_anch_urbs); + DEBUGFS_ADD(usb_rx_pool_urbs); + DEBUGFS_ADD(usb_rx_anch_urbs); + DEBUGFS_ADD(usb_rx_work_urbs); + + DEBUGFS_ADD(tx_total_queued); + DEBUGFS_ADD(tx_total_pending); + DEBUGFS_ADD(tx_dropped); + DEBUGFS_ADD(tx_stuck); + DEBUGFS_ADD(tx_ampdu_upload); + DEBUGFS_ADD(tx_ampdu_scheduler); + DEBUGFS_ADD(tx_ampdu_list_len); + + DEBUGFS_ADD(rx_dropped); + DEBUGFS_ADD(sniffer_enabled); + DEBUGFS_ADD(rx_software_decryption); + + DEBUGFS_ADD(mem_usage); + DEBUGFS_ADD(qos_stat); + DEBUGFS_ADD(sta_psm); + DEBUGFS_ADD(ampdu_state); + + DEBUGFS_ADD(hw_tx_tally); + DEBUGFS_ADD(hw_rx_tally); + DEBUGFS_ADD(hw_phy_errors); + DEBUGFS_ADD(phy_noise); + + DEBUGFS_ADD(hw_wlan_queue); + DEBUGFS_ADD(hw_pta_queue); + DEBUGFS_ADD(hw_ampdu_info); + + DEBUGFS_ADD(ampdu_density); + DEBUGFS_ADD(ampdu_factor); + + DEBUGFS_ADD(tx_ampdu_timeout); + + DEBUGFS_ADD(tx_janitor_last_run); + + DEBUGFS_ADD(tx_status_0); + DEBUGFS_ADD(tx_status_1); + DEBUGFS_ADD(tx_status_2); + DEBUGFS_ADD(tx_status_3); + + DEBUGFS_ADD(tx_pending_0); + DEBUGFS_ADD(tx_pending_1); + DEBUGFS_ADD(tx_pending_2); + DEBUGFS_ADD(tx_pending_3); + + DEBUGFS_ADD(hw_ioread32); + DEBUGFS_ADD(hw_iowrite32); + DEBUGFS_ADD(bug); + + DEBUGFS_ADD(erp); + + DEBUGFS_ADD(vif_dump); + + DEBUGFS_ADD(beacon_int); + DEBUGFS_ADD(pretbtt); + +#undef DEBUGFS_ADD +} + +void carl9170_debugfs_unregister(struct ar9170 *ar) +{ + debugfs_remove_recursive(ar->debug_dir); +} diff --git a/drivers/net/wireless/ath/carl9170/debug.h b/drivers/net/wireless/ath/carl9170/debug.h new file mode 100644 index 000000000000..ea4b97524122 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/debug.h @@ -0,0 +1,134 @@ +/* + * Atheros CARL9170 driver + * + * debug header + * + * Copyright 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __DEBUG_H +#define __DEBUG_H + +#include "eeprom.h" +#include "wlan.h" +#include "hw.h" +#include "fwdesc.h" +#include "fwcmd.h" +#include "../regd.h" + +struct hw_stat_reg_entry { + u32 reg; + char nreg[32]; +}; + +#define STAT_MAC_REG(reg) \ + { (AR9170_MAC_REG_##reg), #reg } + +#define STAT_PTA_REG(reg) \ + { (AR9170_PTA_REG_##reg), #reg } + +#define STAT_USB_REG(reg) \ + { (AR9170_USB_REG_##reg), #reg } + +static const struct hw_stat_reg_entry hw_rx_tally_regs[] = { + STAT_MAC_REG(RX_CRC32), STAT_MAC_REG(RX_CRC16), + STAT_MAC_REG(RX_TIMEOUT_COUNT), STAT_MAC_REG(RX_ERR_DECRYPTION_UNI), + STAT_MAC_REG(RX_ERR_DECRYPTION_MUL), STAT_MAC_REG(RX_MPDU), + STAT_MAC_REG(RX_DROPPED_MPDU), STAT_MAC_REG(RX_DEL_MPDU), +}; + +static const struct hw_stat_reg_entry hw_phy_errors_regs[] = { + STAT_MAC_REG(RX_PHY_MISC_ERROR), STAT_MAC_REG(RX_PHY_XR_ERROR), + STAT_MAC_REG(RX_PHY_OFDM_ERROR), STAT_MAC_REG(RX_PHY_CCK_ERROR), + STAT_MAC_REG(RX_PHY_HT_ERROR), STAT_MAC_REG(RX_PHY_TOTAL), +}; + +static const struct hw_stat_reg_entry hw_tx_tally_regs[] = { + STAT_MAC_REG(TX_TOTAL), STAT_MAC_REG(TX_UNDERRUN), + STAT_MAC_REG(TX_RETRY), +}; + +static const struct hw_stat_reg_entry hw_wlan_queue_regs[] = { + STAT_MAC_REG(DMA_STATUS), STAT_MAC_REG(DMA_TRIGGER), + STAT_MAC_REG(DMA_TXQ0_ADDR), STAT_MAC_REG(DMA_TXQ0_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ1_ADDR), STAT_MAC_REG(DMA_TXQ1_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ2_ADDR), STAT_MAC_REG(DMA_TXQ2_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ3_ADDR), STAT_MAC_REG(DMA_TXQ3_CURR_ADDR), + STAT_MAC_REG(DMA_RXQ_ADDR), STAT_MAC_REG(DMA_RXQ_CURR_ADDR), +}; + +static const struct hw_stat_reg_entry hw_ampdu_info_regs[] = { + STAT_MAC_REG(AMPDU_DENSITY), STAT_MAC_REG(AMPDU_FACTOR), +}; + +static const struct hw_stat_reg_entry hw_pta_queue_regs[] = { + STAT_PTA_REG(DN_CURR_ADDRH), STAT_PTA_REG(DN_CURR_ADDRL), + STAT_PTA_REG(UP_CURR_ADDRH), STAT_PTA_REG(UP_CURR_ADDRL), + STAT_PTA_REG(DMA_STATUS), STAT_PTA_REG(DMA_MODE_CTRL), +}; + +#define DEFINE_TALLY(name) \ + u32 name##_sum[ARRAY_SIZE(name##_regs)], \ + name##_counter[ARRAY_SIZE(name##_regs)] \ + +#define DEFINE_STAT(name) \ + u32 name##_counter[ARRAY_SIZE(name##_regs)] \ + +struct ath_stats { + DEFINE_TALLY(hw_tx_tally); + DEFINE_TALLY(hw_rx_tally); + DEFINE_TALLY(hw_phy_errors); + DEFINE_STAT(hw_wlan_queue); + DEFINE_STAT(hw_pta_queue); + DEFINE_STAT(hw_ampdu_info); +}; + +struct carl9170_debug_mem_rbe { + u32 reg; + u32 value; +}; + +#define CARL9170_DEBUG_RING_SIZE 64 + +struct carl9170_debug { + struct ath_stats stats; + struct carl9170_debug_mem_rbe ring[CARL9170_DEBUG_RING_SIZE]; + struct mutex ring_lock; + unsigned int ring_head, ring_tail; + struct delayed_work update_tally; +}; + +struct ar9170; + +void carl9170_debugfs_register(struct ar9170 *ar); +void carl9170_debugfs_unregister(struct ar9170 *ar); +#endif /* __DEBUG_H */ diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c new file mode 100644 index 000000000000..36615462b87a --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -0,0 +1,395 @@ +/* + * Atheros CARL9170 driver + * + * firmware parser + * + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + */ + +#include +#include +#include +#include "carl9170.h" +#include "fwcmd.h" +#include "version.h" + +#define MAKE_STR(symbol) #symbol +#define TO_STR(symbol) MAKE_STR(symbol) +#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) +MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); + +static const u8 otus_magic[4] = { OTUS_MAGIC }; + +static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], + const unsigned int len, const u8 compatible_revision) +{ + const struct carl9170fw_desc_head *iter; + + carl9170fw_for_each_hdr(iter, ar->fw.desc) { + if (carl9170fw_desc_cmp(iter, descid, len, + compatible_revision)) + return (void *)iter; + } + + /* needed to find the LAST desc */ + if (carl9170fw_desc_cmp(iter, descid, len, + compatible_revision)) + return (void *)iter; + + return NULL; +} + +static int carl9170_fw_verify_descs(struct ar9170 *ar, + const struct carl9170fw_desc_head *head, unsigned int max_len) +{ + const struct carl9170fw_desc_head *pos; + unsigned long pos_addr, end_addr; + unsigned int pos_length; + + if (max_len < sizeof(*pos)) + return -ENODATA; + + max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len); + + pos = head; + pos_addr = (unsigned long) pos; + end_addr = pos_addr + max_len; + + while (pos_addr < end_addr) { + if (pos_addr + sizeof(*head) > end_addr) + return -E2BIG; + + pos_length = le16_to_cpu(pos->length); + + if (pos_length < sizeof(*head)) + return -EBADMSG; + + if (pos_length > max_len) + return -EOVERFLOW; + + if (pos_addr + pos_length > end_addr) + return -EMSGSIZE; + + if (carl9170fw_desc_cmp(pos, LAST_MAGIC, + CARL9170FW_LAST_DESC_SIZE, + CARL9170FW_LAST_DESC_CUR_VER)) + return 0; + + pos_addr += pos_length; + pos = (void *)pos_addr; + max_len -= pos_length; + } + return -EINVAL; +} + +static void carl9170_fw_info(struct ar9170 *ar) +{ + const struct carl9170fw_motd_desc *motd_desc; + unsigned int str_ver_len; + u32 fw_date; + + dev_info(&ar->udev->dev, "driver API: %s 2%03d-%02d-%02d [%d-%d]\n", + CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR, + CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY, + CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER); + + motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC, + sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER); + + if (motd_desc) { + str_ver_len = strnlen(motd_desc->release, + CARL9170FW_MOTD_RELEASE_LEN); + + fw_date = le32_to_cpu(motd_desc->fw_year_month_day); + + dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n", + str_ver_len, motd_desc->release, + CARL9170FW_GET_YEAR(fw_date), + CARL9170FW_GET_MONTH(fw_date), + CARL9170FW_GET_DAY(fw_date)); + + strlcpy(ar->hw->wiphy->fw_version, motd_desc->release, + sizeof(ar->hw->wiphy->fw_version)); + } +} + +static bool valid_dma_addr(const u32 address) +{ + if (address >= AR9170_SRAM_OFFSET && + address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE)) + return true; + + return false; +} + +static bool valid_cpu_addr(const u32 address) +{ + if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET && + address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE))) + return true; + + return false; +} + +static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) +{ + const struct carl9170fw_otus_desc *otus_desc; + const struct carl9170fw_chk_desc *chk_desc; + const struct carl9170fw_last_desc *last_desc; + + last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, + sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); + if (!last_desc) + return -EINVAL; + + otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC, + sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER); + if (!otus_desc) { + dev_err(&ar->udev->dev, "failed to find compatible firmware " + "descriptor.\n"); + return -ENODATA; + } + + chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC, + sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER); + + if (chk_desc) { + unsigned long fin, diff; + unsigned int dsc_len; + u32 crc32; + + dsc_len = min_t(unsigned int, len, + (unsigned long)chk_desc - (unsigned long)otus_desc); + + fin = (unsigned long) last_desc + sizeof(*last_desc); + diff = fin - (unsigned long) otus_desc; + + if (diff < len) + len -= diff; + + if (len < 256) + return -EIO; + + crc32 = crc32_le(~0, data, len); + if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { + dev_err(&ar->udev->dev, "fw checksum test failed.\n"); + return -ENOEXEC; + } + + crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); + if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { + dev_err(&ar->udev->dev, "descriptor check failed.\n"); + return -EINVAL; + } + } else { + dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); + } + +#define SUPP(feat) \ + (carl9170fw_supports(otus_desc->feature_set, feat)) + + if (!SUPP(CARL9170FW_DUMMY_FEATURE)) { + dev_err(&ar->udev->dev, "invalid firmware descriptor " + "format detected.\n"); + return -EINVAL; + } + + ar->fw.api_version = otus_desc->api_ver; + + if (ar->fw.api_version < CARL9170FW_API_MIN_VER || + ar->fw.api_version > CARL9170FW_API_MAX_VER) { + dev_err(&ar->udev->dev, "unsupported firmware api version.\n"); + return -EINVAL; + } + + if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) || + !SUPP(CARL9170FW_HANDLE_BACK_REQ)) { + dev_err(&ar->udev->dev, "firmware does support " + "mandatory features.\n"); + return -ECANCELED; + } + + if (ilog2(le32_to_cpu(otus_desc->feature_set)) >= + __CARL9170FW_FEATURE_NUM) { + dev_warn(&ar->udev->dev, "driver does not support all " + "firmware features.\n"); + } + + if (!SUPP(CARL9170FW_COMMAND_CAM)) { + dev_info(&ar->udev->dev, "crypto offloading is disabled " + "by firmware.\n"); + ar->disable_offload = true; + } + + if (SUPP(CARL9170FW_PSM)) + ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS; + + if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) { + dev_err(&ar->udev->dev, "firmware does not provide " + "mandatory interfaces.\n"); + return -EINVAL; + } + + if (SUPP(CARL9170FW_MINIBOOT)) + ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size); + else + ar->fw.offset = 0; + + if (SUPP(CARL9170FW_USB_DOWN_STREAM)) { + ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream); + ar->fw.tx_stream = true; + } + + if (SUPP(CARL9170FW_USB_UP_STREAM)) + ar->fw.rx_stream = true; + + ar->fw.vif_num = otus_desc->vif_num; + ar->fw.cmd_bufs = otus_desc->cmd_bufs; + ar->fw.address = le32_to_cpu(otus_desc->fw_address); + ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len); + ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe); + atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); + ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len); + + if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num || + ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs || + ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 || + ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 || + !valid_cpu_addr(ar->fw.address)) { + dev_err(&ar->udev->dev, "firmware shows obvious signs of " + "malicious tampering.\n"); + return -EINVAL; + } + + ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr); + ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len); + + if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >= + AR9170_MAC_BCN_LENGTH_MAX) { + ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + + if (SUPP(CARL9170FW_WLANTX_CAB)) { + ar->hw->wiphy->interface_modes |= + BIT(NL80211_IFTYPE_AP); + } + } + +#undef SUPPORTED + return 0; +} + +static struct carl9170fw_desc_head * +carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) + +{ + int scan = 0, found = 0; + + if (!carl9170fw_size_check(len)) { + dev_err(&ar->udev->dev, "firmware size is out of bound.\n"); + return NULL; + } + + while (scan < len - sizeof(struct carl9170fw_desc_head)) { + if (fw_data[scan++] == otus_magic[found]) + found++; + else + found = 0; + + if (scan >= len) + break; + + if (found == sizeof(otus_magic)) + break; + } + + if (found != sizeof(otus_magic)) + return NULL; + + return (void *)&fw_data[scan - found]; +} + +int carl9170_fw_fix_eeprom(struct ar9170 *ar) +{ + const struct carl9170fw_fix_desc *fix_desc = NULL; + unsigned int i, n, off; + u32 *data = (void *)&ar->eeprom; + + fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC, + sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER); + + if (!fix_desc) + return 0; + + n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) / + sizeof(struct carl9170fw_fix_entry); + + for (i = 0; i < n; i++) { + off = le32_to_cpu(fix_desc->data[i].address) - + AR9170_EEPROM_START; + + if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) { + dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i); + continue; + } + + data[off / sizeof(*data)] &= + le32_to_cpu(fix_desc->data[i].mask); + data[off / sizeof(*data)] |= + le32_to_cpu(fix_desc->data[i].value); + } + + return 0; +} + +int carl9170_parse_firmware(struct ar9170 *ar) +{ + const struct carl9170fw_desc_head *fw_desc = NULL; + const struct firmware *fw = ar->fw.fw; + unsigned long header_offset = 0; + int err; + + if (WARN_ON(!fw)) + return -EINVAL; + + fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size); + + if (!fw_desc) { + dev_err(&ar->udev->dev, "unsupported firmware.\n"); + return -ENODATA; + } + + header_offset = (unsigned long)fw_desc - (unsigned long)fw->data; + + err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset); + if (err) { + dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err); + return err; + } + + ar->fw.desc = fw_desc; + + carl9170_fw_info(ar); + + err = carl9170_fw(ar, fw->data, fw->size); + if (err) { + dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n", + err); + return err; + } + + return 0; +} -- cgit v1.2.3 From 1d7e1e6b1b8ed456e7678130ad17086a5f5b3286 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 6 Sep 2010 01:10:25 +0200 Subject: carl9170: Makefile, Kconfig files and MAINTAINERS Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- MAINTAINERS | 7 +++++ drivers/net/wireless/ath/Kconfig | 1 + drivers/net/wireless/ath/Makefile | 1 + drivers/net/wireless/ath/carl9170/Kconfig | 41 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/Makefile | 4 +++ 5 files changed, 54 insertions(+) create mode 100644 drivers/net/wireless/ath/carl9170/Kconfig create mode 100644 drivers/net/wireless/ath/carl9170/Makefile diff --git a/MAINTAINERS b/MAINTAINERS index 4a6d93648b9c..80cea03a737e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1102,6 +1102,13 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170 S: Maintained F: drivers/net/wireless/ath/ar9170/ +CARL9170 LINUX COMMUNITY WIRELESS DRIVER +M: Christian Lamparter +L: linux-wireless@vger.kernel.org +W: http://wireless.kernel.org/en/users/Drivers/carl9170 +S: Maintained +F: drivers/net/wireless/ath/carl9170/ + ATK0110 HWMON DRIVER M: Luca Tettamanti L: lm-sensors@lm-sensors.org diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 0a75be027afa..92c216263ee9 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -25,5 +25,6 @@ config ATH_DEBUG source "drivers/net/wireless/ath/ath5k/Kconfig" source "drivers/net/wireless/ath/ath9k/Kconfig" source "drivers/net/wireless/ath/ar9170/Kconfig" +source "drivers/net/wireless/ath/carl9170/Kconfig" endif diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 8113a5042afa..40fa1794d489 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K_HW) += ath9k/ obj-$(CONFIG_AR9170_USB) += ar9170/ +obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH_COMMON) += ath.o diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig new file mode 100644 index 000000000000..c5d3a3f2e55b --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -0,0 +1,41 @@ +config CARL9170 + tristate "Linux Community AR9170 802.11n USB support" + depends on USB && MAC80211 && EXPERIMENTAL + select FW_LOADER + select CRC32 + help + This is another driver for the Atheros "otus" 802.11n USB devices. + + This driver provides more features than the original, + but it needs a special firmware (carl9170-1.fw) to do that. + + The firmware can be downloaded from our wiki here: + http://wireless.kernel.org/en/users/Drivers/carl9170 + + If you choose to build a module, it'll be called carl9170. + +config CARL9170_LEDS + bool "SoftLED Support" + depends on CARL9170 + select MAC80211_LEDS + select LEDS_CLASS + select NEW_LEDS + default y + help + This option is necessary, if you want your device' LEDs to blink + + Say Y, unless you need the LEDs for firmware debugging. + +config CARL9170_DEBUGFS + bool "DebugFS Support" + depends on CARL9170 && DEBUG_FS && MAC80211_DEBUGFS + default n + help + Export several driver and device internals to user space. + + Say N. + +config CARL9170_WPC + bool + depends on CARL9170 && (INPUT = y || INPUT = CARL9170) + default y diff --git a/drivers/net/wireless/ath/carl9170/Makefile b/drivers/net/wireless/ath/carl9170/Makefile new file mode 100644 index 000000000000..f64ed76af8ad --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/Makefile @@ -0,0 +1,4 @@ +carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o +carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o + +obj-$(CONFIG_CARL9170) += carl9170.o -- cgit v1.2.3 From 49063a0d0b65e40ece846a744cb10cbdf295515d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 7 Sep 2010 04:24:21 +0300 Subject: wl1271: sdio: claim host only when doing IO Do not maintain a persistent sdio_claim_host state. Instead, claim host before doing IO and release host soon after. This fixes several mmc deadlock scenarios, e.g. during suspend/resume. Signed-off-by: Ohad Ben-Cohen Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 43 +++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 7059b5cccf0f..b3c3158551c8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -107,6 +107,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", @@ -122,9 +124,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); } + sdio_release_host(func); + if (ret) wl1271_error("sdio read failed (%d)", ret); - } static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, @@ -133,6 +136,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", @@ -147,9 +152,33 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, else ret = sdio_memcpy_toio(func, addr, buf, len); } + + sdio_release_host(func); + if (ret) wl1271_error("sdio write failed (%d)", ret); +} + +static int wl1271_sdio_power_on(struct wl1271 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + return 0; +} + +static int wl1271_sdio_power_off(struct wl1271 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + return 0; } static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) @@ -160,13 +189,11 @@ static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) * keep host claimed while wlan is in use to keep wl1271 * alive. */ - if (enable) { - sdio_claim_host(func); - sdio_enable_func(func); - } else { - sdio_disable_func(func); - sdio_release_host(func); - } + if (enable) + return wl1271_sdio_power_on(wl); + else + return wl1271_sdio_power_off(wl); + } static struct wl1271_if_operations sdio_ops = { -- cgit v1.2.3 From 58d7e0f37cfc5b4f473d437024a03d874e5969a3 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 8 Sep 2010 15:57:12 +0530 Subject: ath9k_hw: Support fastcc for AR7010 To reduce scan time, enable fastcc for AR7010 (fastcc == fast channel change -- JWL) Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index afadade2a67e..0a61f426d7d7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1258,7 +1258,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, (chan->channel != ah->curchan->channel) && ((chan->channelFlags & CHANNEL_ALL) == (ah->curchan->channelFlags & CHANNEL_ALL)) && - !AR_SREV_9280(ah)) { + (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) { if (ath9k_hw_channel_change(ah, chan)) { ath9k_hw_loadnf(ah, ah->curchan); -- cgit v1.2.3 From 85f4d6488cba35d3bb58833edbcb28faaffdd37c Mon Sep 17 00:00:00 2001 From: Lars Ericsson Date: Wed, 8 Sep 2010 20:55:36 +0200 Subject: rt2x00: Antenna diversity does not work in 2.6.35 The test if antenna diversity is at all enabled uses a local variable 'flags' to prepare the test condition, but uses 'ant->flags' when the test is evaluated. The effect is that the diversity evaluation will never start. I can see two solutions, use the 'flag' in the test condition or revert the local flag change. My attached patch took alternative two. Then the evaluation start but it will still not switch antenna. The problem is a code section in rt2x00lib_config_antenna (). The effect of that code section is that any change the diversity function perform will be effectively shorten and no antenna selection command issued. The attached patch will filter out any ANTENNA_SW_DIVERSITY setting but forward all other Signed-off-by: Lars Ericsson Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00config.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00link.c | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 34f34fa7f53a..db09a641a948 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -129,12 +129,12 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); - else + else if(config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); - else + else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 666cef3f8472..4d534e9dc628 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -188,7 +188,6 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) { struct link_ant *ant = &rt2x00dev->link.ant; - unsigned int flags = ant->flags; /* * Determine if software diversity is enabled for @@ -196,13 +195,13 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) * Always perform this check since within the link * tuner interval the configuration might have changed. */ - flags &= ~ANTENNA_RX_DIVERSITY; - flags &= ~ANTENNA_TX_DIVERSITY; + ant->flags &= ~ANTENNA_RX_DIVERSITY; + ant->flags &= ~ANTENNA_TX_DIVERSITY; if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) - flags |= ANTENNA_RX_DIVERSITY; + ant->flags |= ANTENNA_RX_DIVERSITY; if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) - flags |= ANTENNA_TX_DIVERSITY; + ant->flags |= ANTENNA_TX_DIVERSITY; if (!(ant->flags & ANTENNA_RX_DIVERSITY) && !(ant->flags & ANTENNA_TX_DIVERSITY)) { @@ -210,9 +209,6 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) return true; } - /* Update flags */ - ant->flags = flags; - /* * If we have only sampled the data over the last period * we should now harvest the data. Otherwise just evaluate -- cgit v1.2.3 From 47ee3eb1359a5444efd9f529e3d28c02e8e405e7 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 8 Sep 2010 20:56:04 +0200 Subject: rt2x00: Initialize AMPDU_BA_WINSIZE register Since we're not using the AMPDU_BA_WINSIZE register to force the BlockAck window size (we specify it in every TXWI) we should initialize it to 0. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 12 ++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 70a5cb86405b..2edc7742a7e9 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -638,6 +638,18 @@ #define LED_CFG_Y_LED_MODE FIELD32(0x30000000) #define LED_CFG_LED_POLAR FIELD32(0x40000000) +/* + * AMPDU_BA_WINSIZE: Force BlockAck window size + * FORCE_WINSIZE_ENABLE: + * 0: Disable forcing of BlockAck window size + * 1: Enable forcing of BlockAck window size, overwrites values BlockAck + * window size values in the TXWI + * FORCE_WINSIZE: BlockAck window size + */ +#define AMPDU_BA_WINSIZE 0x1040 +#define AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE FIELD32(0x00000020) +#define AMPDU_BA_WINSIZE_FORCE_WINSIZE FIELD32(0x0000001f) + /* * XIFS_TIME_CFG: MAC timing * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index f90e932b3cb4..78e5830c86c2 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2052,6 +2052,14 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS3FBK, 2); rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); + /* + * Do not force the BA window size, we use the TXWI to set it + */ + rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, ®); + rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0); + rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0); + rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg); + /* * We must clear the error counters. * These registers are cleared on read, -- cgit v1.2.3 From 0204464329c17ba6d293e1899f71223599a0e582 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 8 Sep 2010 20:56:32 +0200 Subject: rt2x00: Check for specific changed flags when updating the erp config Previously rt2x00 was always updating all erp related config variables even though mac80211 might only have changed one. Hence, pass the changed flags to the config_erp driver callback so that the driver can limit the changes to the correct values. This fixes an issue in AP mode where the beacon interval is not initialized (and thus zero) but still sent to the hardware causing an interrupt storm on rt2800pci hanging the system. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 114 +++++++++++++++------------- drivers/net/wireless/rt2x00/rt2500pci.c | 115 ++++++++++++++++------------- drivers/net/wireless/rt2x00/rt2500usb.c | 34 ++++++--- drivers/net/wireless/rt2x00/rt2800lib.c | 60 +++++++++------ drivers/net/wireless/rt2x00/rt2800lib.h | 3 +- drivers/net/wireless/rt2x00/rt2x00.h | 3 +- drivers/net/wireless/rt2x00/rt2x00config.c | 5 +- drivers/net/wireless/rt2x00/rt2x00lib.h | 3 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 +- drivers/net/wireless/rt2x00/rt61pci.c | 47 +++++++----- drivers/net/wireless/rt2x00/rt73usb.c | 47 +++++++----- 11 files changed, 256 insertions(+), 181 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index e3005ff5ae98..4b88909275a1 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -321,7 +321,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { int preamble_mask; u32 reg; @@ -329,59 +330,72 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, /* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = erp->short_preamble << 3; - - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); - rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); - rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); - rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); - rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); - rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); - rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); - rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); - rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); - rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); - rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); - rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); - - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + preamble_mask = erp->short_preamble << 3; + + rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); + rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); + rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); + rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); + rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 10)); + rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); + rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 20)); + rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); + rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 55)); + rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); + rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 110)); + rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR11, ®); - rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); - rt2x00pci_register_read(rt2x00dev, CSR12, ®); - rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); - rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); - rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); - rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); + rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); + rt2x00pci_register_write(rt2x00dev, CSR18, reg); - rt2x00pci_register_read(rt2x00dev, CSR19, ®); - rt2x00_set_field32(®, CSR19_DIFS, erp->difs); - rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); + rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00_set_field32(®, CSR19_DIFS, erp->difs); + rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, CSR19, reg); + } + + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, CSR12, reg); + } } static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 1e6a91b8d3df..46ef692e404d 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -327,7 +327,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { int preamble_mask; u32 reg; @@ -335,59 +336,73 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, /* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = erp->short_preamble << 3; - - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); - rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); - rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); - rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); - rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); - rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); - rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); - rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); - rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); - rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); - rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); - rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); - - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + preamble_mask = erp->short_preamble << 3; + + rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); + rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); + rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); + rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); + rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 10)); + rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); + rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 20)); + rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); + rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 55)); + rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); + rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 110)); + rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR11, ®); - rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR12, ®); - rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); - rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); + rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); + rt2x00pci_register_write(rt2x00dev, CSR18, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); - rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); - rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00_set_field32(®, CSR19_DIFS, erp->difs); + rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, CSR19, reg); + } + + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, CSR12, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR19, ®); - rt2x00_set_field32(®, CSR19_DIFS, erp->difs); - rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); } static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index a161e9e33b73..5843a6d8b627 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -494,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u16 reg; - rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); - rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); + rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); + } - rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2500usb_register_write(rt2x00dev, TXRX_CSR11, + erp->basic_rates); - rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); - rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, erp->beacon_int * 4); - rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); + rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, + erp->beacon_int * 4); + rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); + } - rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); - rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); - rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); + rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); + rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); + } } static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 78e5830c86c2..c7076deaecea 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1159,38 +1159,50 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } EXPORT_SYMBOL_GPL(rt2800_config_intf); -void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp) +void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, + u32 changed) { u32 reg; - rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); - rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, - !!erp->short_preamble); - rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, - !!erp->short_preamble); - rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); + rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, + !!erp->short_preamble); + rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, + !!erp->short_preamble); + rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); + } - rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); - rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, - erp->cts_protection ? 2 : 0); - rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); + rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, + erp->cts_protection ? 2 : 0); + rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); + } - rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, - erp->basic_rates); - rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); + if (changed & BSS_CHANGED_BASIC_RATES) { + rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, + erp->basic_rates); + rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); + } - rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); - rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); - rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); + rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, + erp->slot_time); + rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); - rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); - rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); - rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); + rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); + rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); + rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); + } - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } } EXPORT_SYMBOL_GPL(rt2800_config_erp); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 986229c06c19..600c5eb25c41 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -169,7 +169,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, const unsigned int filter_flags); void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags); -void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp); +void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, + u32 changed); void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); void rt2800_config(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0ae942cb66df..7832a5996a8c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -596,7 +596,8 @@ struct rt2x00lib_ops { #define CONFIG_UPDATE_BSSID ( 1 << 3 ) void (*config_erp) (struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp); + struct rt2x00lib_erp *erp, + u32 changed); void (*config_ant) (struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); void (*config) (struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index db09a641a948..4c7ff765a8bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -81,7 +81,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, - struct ieee80211_bss_conf *bss_conf) + struct ieee80211_bss_conf *bss_conf, + u32 changed) { struct rt2x00lib_erp erp; @@ -102,7 +103,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; - rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); + rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); } static inline diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index dc5c6574aaf4..70c85ac2e53e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -86,7 +86,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, const u8 *mac, const u8 *bssid); void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, - struct ieee80211_bss_conf *conf); + struct ieee80211_bss_conf *conf, + u32 changed); void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup ant); void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 235e037e6509..7862a840984a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, * When the erp information has changed, we should perform * additional configuration steps. For all other changes we are done. */ - if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) - rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); + if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | + BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | + BSS_CHANGED_BEACON_INT)) + rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); } EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 18829b2eccc3..7a35f121e678 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u32 reg; @@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + } - rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, + erp->basic_rates); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + } - rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); - rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); - rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); - rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); - rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); + rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); + rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); + rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); + rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); + } } static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index df0ef3f70f1e..cc6a72b09f46 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u32 reg; @@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); - rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); + } - rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, + erp->basic_rates); - rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + } - rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); - rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); - rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); + rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); - rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); - rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); - rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); - rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); + rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); + rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); + rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); + rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); + rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); + } } static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, -- cgit v1.2.3 From 93149cf87bdd511db86d709a6db7ed09f1b8ba99 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 8 Sep 2010 20:56:52 +0200 Subject: rt2x00: Mask out unused interrupts in rt2800pci We don't use all available interrupts in rt2800pci. Mask out all unused interrupts to avoid waking up without having anything to do. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 2bcb1507e3ac..005ee153e0cc 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -342,24 +342,24 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, } rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); - rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, mask); - rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, mask); - rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); - rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, mask); - rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, mask); - rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); } -- cgit v1.2.3 From 6646505de03b2ae85de09fd3b8d383ab816a19f9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 8 Sep 2010 20:57:10 +0200 Subject: rt2x00: Enable missing interrupts in rt61pci We're handling both, the CSR_BEACON_DONE and the CSR_TWAKEUP interrupts in rt61pci. However, these interrupts are masked out by default. Fix this. Found via pure code inspection. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 7a35f121e678..286a5eb11339 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1654,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); + rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); @@ -1667,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); + rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); } -- cgit v1.2.3 From 65b7fc97473656eb35b6b58a22c7cef4a99d9e35 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 8 Sep 2010 20:57:40 +0200 Subject: rt2x00: fix oops in rt2x00lib_txdone with rt61pci Fix a typo introduced in "rt2x00: Add helper function for reporting tx status" that results in an oops in rt2x00lib_txdone. Reported-by: Pavel Roskin Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 286a5eb11339..8940070fe2a2 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2117,7 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) "TX status report missed for entry %d\n", entry_done->entry_idx); - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); + rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); } -- cgit v1.2.3 From 516c6e1f52a09fb2e7024101db3f0375f65670df Mon Sep 17 00:00:00 2001 From: Fabio Rossi Date: Wed, 8 Sep 2010 22:37:41 +0200 Subject: ath5k: avoid unneeded calibration error messages Don't generate calibration errors messages when not needed. Signed-off-by: Fabio Rossi Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 984ba92c7df3..4932bf2f35eb 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1377,7 +1377,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah) /* protect against divide by 0 and loss of sign bits */ if (i_coffd == 0 || q_coffd < 2) - return -1; + return 0; i_coff = (-iq_corr) / i_coffd; i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ -- cgit v1.2.3 From bbce80e1101526f7a616e75a0d77b57f4062c62d Mon Sep 17 00:00:00 2001 From: Nikitas Angelinas Date: Wed, 8 Sep 2010 22:25:42 +0100 Subject: drivers/net/wireless/ath/ath9k: use ARRAY_SIZE macro in ani.c Replace (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0]) with ARRAY_SIZE(ofdm_level_table), and (sizeof(cck_level_table)/ sizeof(cck_level_table[0]) with ARRAY_SIZE(cck_level_table) in drivers/net/wireless/ath/ath9k/ani.c Signed-off-by: Nikitas Angelinas Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index cc648b6ae31c..0496f965314f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "hw.h" #include "hw-ops.h" @@ -48,7 +49,7 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = { { 7, 8, 0 } /* lvl 9 */ }; #define ATH9K_ANI_OFDM_NUM_LEVEL \ - (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0])) + ARRAY_SIZE(ofdm_level_table) #define ATH9K_ANI_OFDM_MAX_LEVEL \ (ATH9K_ANI_OFDM_NUM_LEVEL-1) #define ATH9K_ANI_OFDM_DEF_LEVEL \ @@ -94,7 +95,7 @@ static const struct ani_cck_level_entry cck_level_table[] = { }; #define ATH9K_ANI_CCK_NUM_LEVEL \ - (sizeof(cck_level_table)/sizeof(cck_level_table[0])) + ARRAY_SIZE(cck_level_table) #define ATH9K_ANI_CCK_MAX_LEVEL \ (ATH9K_ANI_CCK_NUM_LEVEL-1) #define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \ -- cgit v1.2.3 From 942623166df3256821e8451273bc07737745e3cb Mon Sep 17 00:00:00 2001 From: Nikitas Angelinas Date: Wed, 8 Sep 2010 22:29:53 +0100 Subject: net/wireless: use ARRAY_SIZE macro in radiotap.c Replace sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]) with ARRAY_SIZE(rtap_namespace_sizes) in net/wireless/radiotap.c Signed-off-by: Nikitas Angelinas Signed-off-by: John W. Linville --- net/wireless/radiotap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 1332c445d1c7..c774bc0f155e 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -14,6 +14,7 @@ * See COPYING for more details. */ +#include #include #include #include @@ -45,7 +46,7 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = { }; static const struct ieee80211_radiotap_namespace radiotap_ns = { - .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]), + .n_bits = ARRAY_SIZE(rtap_namespace_sizes), .align_size = rtap_namespace_sizes, }; -- cgit v1.2.3 From a1e567c83f541432e687142570215b75bebb1338 Mon Sep 17 00:00:00 2001 From: Bill Jordan Date: Fri, 10 Sep 2010 11:22:32 -0400 Subject: nl80211: Uninitialized variable There is a path in nl80211_set_wiphy where result is tested but uninitialized. I am hitting this path when I attempt: sh# iw dev wlan0 set channel 10 command failed: Unknown error 1069727332 (-1069727332) Signed-off-by: William Jordan Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 85a23de7bff3..1d6ef24254fe 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -833,7 +833,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev; struct net_device *netdev = NULL; struct wireless_dev *wdev; - int result, rem_txq_params = 0; + int result = 0, rem_txq_params = 0; struct nlattr *nl_txq_params; u32 changed; u8 retry_short = 0, retry_long = 0; -- cgit v1.2.3 From 740c1aa3b01251c3c324743f395621749b099065 Mon Sep 17 00:00:00 2001 From: Steve deRosier Date: Sat, 11 Sep 2010 20:01:31 -0700 Subject: mac80211: Fix dangling pointer in ieee80211_xmit hdr pointer is left dangling after call to ieee80211_skb_resize. This can cause guards around mesh path selection to fail. Signed-off-by: Steve deRosier Signed-off-by: John W. Linville --- net/mac80211/tx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ccf373788ce9..e1733dcb58a7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1609,6 +1609,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, return; } + hdr = (struct ieee80211_hdr *) skb->data; info->control.vif = &sdata->vif; if (ieee80211_vif_is_mesh(&sdata->vif) && -- cgit v1.2.3 From b5be3efc34294cc34e305903df6a388950e8d1f3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Sep 2010 14:46:32 +0200 Subject: iwlwifi: remove unused conf variables There are a number of conf variables that are unused, remove them. Signed-off-by: Johannes Berg Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 ------ 2 files changed, 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ec99a72edb76..35470d280c14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1158,7 +1158,6 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct iwl_scan_cmd *scan; - struct ieee80211_conf *conf = NULL; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u32 rate_flags = 0; u16 cmd_len; @@ -1175,8 +1174,6 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (vif) ctx = iwl_rxon_ctx_from_vif(vif); - conf = ieee80211_get_hw_conf(priv->hw); - cancel_delayed_work(&priv->scan_check); if (!iwl_is_ready(priv)) { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 9c90be1ea0df..be1e75e3be55 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2568,12 +2568,9 @@ static void __iwl3945_down(struct iwl_priv *priv) { unsigned long flags; int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); - struct ieee80211_conf *conf = NULL; IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - conf = ieee80211_get_hw_conf(priv->hw); - if (!exit_pending) set_bit(STATUS_EXIT_PENDING, &priv->status); @@ -2827,13 +2824,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct iwl3945_scan_cmd *scan; - struct ieee80211_conf *conf = NULL; u8 n_probes = 0; enum ieee80211_band band; bool is_active = false; - conf = ieee80211_get_hw_conf(priv->hw); - cancel_delayed_work(&priv->scan_check); if (!iwl_is_ready(priv)) { -- cgit v1.2.3 From 3eecce527c7434dfd16517ce08b49632c8a26717 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Sep 2010 14:46:33 +0200 Subject: iwlwifi: unify scan start checks Rather than duplicating all the checks and even in case of errors accepting the scan request from mac80211, we can push the checks to the caller and in all error cases reject the scan request right away (rather than accepting and then saying it was aborted). Signed-off-by: Johannes Berg Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 88 +++++-------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 127 ++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl3945-base.c | 74 +++------------- 6 files changed, 108 insertions(+), 187 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index bb2aeebf3652..98509c5e708d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -295,7 +295,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info( extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); /* scanning */ -void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); /* Requires full declaration of iwl_priv before including */ #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 35470d280c14..12170cfcff4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1150,7 +1150,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, return added; } -void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, @@ -1170,57 +1170,20 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) int chan_mod; u8 active_chains; u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; + int ret; + + lockdep_assert_held(&priv->mutex); if (vif) ctx = iwl_rxon_ctx_from_vif(vif); - cancel_delayed_work(&priv->scan_check); - - if (!iwl_is_ready(priv)) { - IWL_WARN(priv, "request scan called when driver not ready.\n"); - goto done; - } - - /* Make sure the scan wasn't canceled before this queued work - * was given the chance to run... */ - if (!test_bit(STATUS_SCANNING, &priv->status)) - goto done; - - /* This should never be called or scheduled if there is currently - * a scan active in the hardware. */ - if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " - "Ignoring second request.\n"); - goto done; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); - goto done; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n"); - goto done; - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); - goto done; - } - - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n"); - goto done; - } - if (!priv->scan_cmd) { priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan_cmd) { IWL_DEBUG_SCAN(priv, "fail to allocate memory for scan\n"); - goto done; + return -ENOMEM; } } scan = priv->scan_cmd; @@ -1327,8 +1290,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_GOOD_CRC_TH_NEVER; break; default: - IWL_WARN(priv, "Invalid scan band count\n"); - goto done; + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; } band = priv->scan_band; @@ -1408,7 +1371,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) } if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - goto done; + return -EIO; } cmd.len += le16_to_cpu(scan->tx_cmd.len) + @@ -1416,30 +1379,21 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) cmd.data = scan; scan->len = cpu_to_le16(cmd.len); - set_bit(STATUS_SCAN_HW, &priv->status); - - if (priv->cfg->ops->hcmd->set_pan_params && - priv->cfg->ops->hcmd->set_pan_params(priv)) - goto done; + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } - if (iwl_send_cmd_sync(priv, &cmd)) - goto done; + set_bit(STATUS_SCAN_HW, &priv->status); + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) { + clear_bit(STATUS_SCAN_HW, &priv->status); + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); + } - queue_delayed_work(priv->workqueue, &priv->scan_check, - IWL_SCAN_CHECK_WATCHDOG); - - return; - - done: - /* Cannot perform scan. Make sure we clear scanning - * bits from status so next scan request can be performed. - * If we don't clear scanning status bit here all next scan - * will fail - */ - clear_bit(STATUS_SCAN_HW, &priv->status); - clear_bit(STATUS_SCANNING, &priv->status); - /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->scan_completed); + return ret; } int iwlagn_manage_ibss_station(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index ab7c16f365f0..e1f85ae9da59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -219,7 +219,7 @@ void iwl_reply_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* scan */ -void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); /* station mgmt */ int iwlagn_manage_ibss_station(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f7b57ed84f66..8dab074e491f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -111,7 +111,7 @@ struct iwl_hcmd_utils_ops { __le16 fc, __le32 *tx_flags); int (*calc_rssi)(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp); - void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); + int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); }; struct iwl_apm_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 7727f0966d31..6bd14bc33478 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -324,19 +324,68 @@ void iwl_init_scan_params(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_init_scan_params); -static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif) +static int __must_check iwl_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool internal, + enum nl80211_band band) { + int ret; + lockdep_assert_held(&priv->mutex); - IWL_DEBUG_INFO(priv, "Starting scan...\n"); + if (WARN_ON(!priv->cfg->ops->utils->request_scan)) + return -EOPNOTSUPP; + + cancel_delayed_work(&priv->scan_check); + + if (!iwl_is_ready(priv)) { + IWL_WARN(priv, "request scan called when driver not ready.\n"); + return -EIO; + } + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + IWL_DEBUG_INFO(priv, + "Multiple concurrent scan requests in parallel.\n"); + return -EBUSY; + } + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); + return -EIO; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_HC(priv, "Scan request while abort pending.\n"); + return -EBUSY; + } + + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); + return -EIO; + } + + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n"); + return -EBUSY; + } + + IWL_DEBUG_INFO(priv, "Starting %sscan...\n", + internal ? "internal short " : ""); + set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = false; + priv->is_internal_short_scan = internal; priv->scan_start = jiffies; + priv->scan_band = band; - if (WARN_ON(!priv->cfg->ops->utils->request_scan)) - return -EOPNOTSUPP; + ret = priv->cfg->ops->utils->request_scan(priv, vif); + if (ret) { + clear_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = false; + return ret; + } - priv->cfg->ops->utils->request_scan(priv, vif); + queue_delayed_work(priv->workqueue, &priv->scan_check, + IWL_SCAN_CHECK_WATCHDOG); return 0; } @@ -355,12 +404,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (!iwl_is_ready_rf(priv)) { - ret = -EIO; - IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n"); - goto out_unlock; - } - if (test_bit(STATUS_SCANNING, &priv->status) && !priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); @@ -368,14 +411,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); - ret = -EAGAIN; - goto out_unlock; - } - /* mac80211 will only ask for one band at a time */ - priv->scan_band = req->channels[0]->band; priv->scan_request = req; priv->scan_vif = vif; @@ -386,7 +422,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, if (priv->is_internal_short_scan) ret = 0; else - ret = iwl_scan_initiate(priv, vif); + ret = iwl_scan_initiate(priv, vif, false, + req->channels[0]->band); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -418,31 +455,13 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) goto unlock; } - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); - goto unlock; - } - if (test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); goto unlock; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); - goto unlock; - } - - priv->scan_band = priv->band; - - IWL_DEBUG_SCAN(priv, "Start internal short scan...\n"); - set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = true; - - if (WARN_ON(!priv->cfg->ops->utils->request_scan)) - goto unlock; - - priv->cfg->ops->utils->request_scan(priv, NULL); + if (iwl_scan_initiate(priv, NULL, true, priv->band)) + IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); unlock: mutex_unlock(&priv->mutex); } @@ -536,7 +555,6 @@ static void iwl_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); bool internal = false; - bool scan_completed = false; struct iwl_rxon_context *ctx; IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); @@ -549,16 +567,27 @@ static void iwl_bg_scan_completed(struct work_struct *work) IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); internal = true; } else if (priv->scan_request) { - scan_completed = true; priv->scan_request = NULL; priv->scan_vif = NULL; + ieee80211_scan_completed(priv->hw, false); } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) goto out; - if (internal && priv->scan_request) - iwl_scan_initiate(priv, priv->scan_vif); + if (internal && priv->scan_request) { + int err = iwl_scan_initiate(priv, priv->scan_vif, false, + priv->scan_request->channels[0]->band); + + if (err) { + IWL_DEBUG_SCAN(priv, + "failed to initiate pending scan: %d\n", err); + priv->scan_request = NULL; + priv->scan_vif = NULL; + ieee80211_scan_completed(priv->hw, true); + } else + goto out; + } /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ @@ -571,19 +600,11 @@ static void iwl_bg_scan_completed(struct work_struct *work) for_each_context(priv, ctx) iwlcore_commit_rxon(priv, ctx); - out: if (priv->cfg->ops->hcmd->set_pan_params) priv->cfg->ops->hcmd->set_pan_params(priv); + out: mutex_unlock(&priv->mutex); - - /* - * Do not hold mutex here since this will cause mac80211 to call - * into driver again into functions that will attempt to take - * mutex. - */ - if (scan_completed) - ieee80211_scan_completed(priv->hw, false); } void iwl_setup_scan_deferred_work(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index be1e75e3be55..fc553bacef17 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2816,7 +2816,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data) } -void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, @@ -2827,55 +2827,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u8 n_probes = 0; enum ieee80211_band band; bool is_active = false; + int ret; - cancel_delayed_work(&priv->scan_check); - - if (!iwl_is_ready(priv)) { - IWL_WARN(priv, "request scan called when driver not ready.\n"); - goto done; - } - - /* Make sure the scan wasn't canceled before this queued work - * was given the chance to run... */ - if (!test_bit(STATUS_SCANNING, &priv->status)) - goto done; - - /* This should never be called or scheduled if there is currently - * a scan active in the hardware. */ - if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " - "Ignoring second request.\n"); - goto done; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); - goto done; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC(priv, - "Scan request while abort pending. Queuing.\n"); - goto done; - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); - goto done; - } - - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC(priv, - "Scan request while uninitialized. Queuing.\n"); - goto done; - } + lockdep_assert_held(&priv->mutex); if (!priv->scan_cmd) { priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan_cmd) { IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); - goto done; + return -ENOMEM; } } scan = priv->scan_cmd; @@ -2970,7 +2931,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) break; default: IWL_WARN(priv, "Invalid scan band\n"); - goto done; + return -EIO; } if (!priv->is_internal_short_scan) { @@ -3005,7 +2966,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - goto done; + return -EIO; } cmd.len += le16_to_cpu(scan->tx_cmd.len) + @@ -3014,25 +2975,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->len = cpu_to_le16(cmd.len); set_bit(STATUS_SCAN_HW, &priv->status); - if (iwl_send_cmd_sync(priv, &cmd)) - goto done; - - queue_delayed_work(priv->workqueue, &priv->scan_check, - IWL_SCAN_CHECK_WATCHDOG); - - return; - - done: - /* can not perform scan make sure we clear scanning - * bits from status so next scan request can be performed. - * if we dont clear scanning status bit here all next scan - * will fail - */ - clear_bit(STATUS_SCAN_HW, &priv->status); - clear_bit(STATUS_SCANNING, &priv->status); - - /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->scan_completed); + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + clear_bit(STATUS_SCAN_HW, &priv->status); + return ret; } static void iwl3945_bg_restart(struct work_struct *data) -- cgit v1.2.3 From d5926d9d6a183d109060f68c0b96ea2b33c15377 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Sep 2010 14:46:34 +0200 Subject: iwlwifi: move scan completed flags handling Move the scan completed flags handling so that we can notify mac80211 about aborted scans with the correct status. Also queue the scan_completed work before the BT status update so that it won't see the bits still set (unless a new scan was started in which case that's fine.) Signed-off-by: Johannes Berg Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 6bd14bc33478..22bdc986c03e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -222,21 +222,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, jiffies_to_msecs(elapsed_jiffies (priv->scan_start, jiffies))); - /* - * If a request to abort was given, or the scan did not succeed - * then we reset the scan state machine and terminate, - * re-queuing another scan if one has been requested - */ - if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status)) - IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); - - IWL_DEBUG_INFO(priv, "Setting scan to off\n"); - - clear_bit(STATUS_SCANNING, &priv->status); + queue_work(priv->workqueue, &priv->scan_completed); if (priv->iw_mode != NL80211_IFTYPE_ADHOC && - priv->cfg->advanced_bt_coexist && priv->bt_status != - scan_notif->bt_status) { + priv->cfg->advanced_bt_coexist && + priv->bt_status != scan_notif->bt_status) { if (scan_notif->bt_status) { /* BT on */ if (!priv->bt_ch_announce) @@ -254,7 +244,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, priv->bt_status = scan_notif->bt_status; queue_work(priv->workqueue, &priv->bt_traffic_change_work); } - queue_work(priv->workqueue, &priv->scan_completed); } void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) @@ -554,7 +543,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - bool internal = false; + bool internal = false, aborted; struct iwl_rxon_context *ctx; IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); @@ -562,6 +551,15 @@ static void iwl_bg_scan_completed(struct work_struct *work) cancel_delayed_work(&priv->scan_check); mutex_lock(&priv->mutex); + + aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); + if (aborted) + IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); + + IWL_DEBUG_INFO(priv, "Setting scan to off\n"); + + clear_bit(STATUS_SCANNING, &priv->status); + if (priv->is_internal_short_scan) { priv->is_internal_short_scan = false; IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); @@ -569,7 +567,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) } else if (priv->scan_request) { priv->scan_request = NULL; priv->scan_vif = NULL; - ieee80211_scan_completed(priv->hw, false); + ieee80211_scan_completed(priv->hw, aborted); } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) -- cgit v1.2.3 From d745d472afcbc6354ebfee008123894a7f37e97e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:35 +0200 Subject: iwlwifi: cancel scan when down the device Always cancel scan when stooping device and scan is currently pending, we should newer have scan running after down device. To assure we start scan cancel from restart work we have to schedule abort_scan to different workqueue than priv->workqueue. Patch fix not cancel scanning when restarting firmware, what is one of the causes of wdev_cleanup_work warning (together with permanent network connection lost) reported at https://bugzilla.redhat.com/show_bug.cgi?id=593566 Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 +++----------- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 16 ++++------------ 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36df9a7fcbcb..d2315debd1b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2892,8 +2892,9 @@ static void __iwl_down(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - if (!exit_pending) - set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_scan_cancel_timeout(priv, 200); + + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ @@ -3503,15 +3504,6 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; - if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) { - /* stop mac, cancel any scan request and clear - * RXON_FILTER_ASSOC_MSK BIT - */ - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - mutex_unlock(&priv->mutex); - } - iwl_down(priv); flush_workqueue(priv->workqueue); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 22bdc986c03e..ea338498ee1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -71,7 +71,7 @@ int iwl_scan_cancel(struct iwl_priv *priv) if (test_bit(STATUS_SCANNING, &priv->status)) { if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n"); - queue_work(priv->workqueue, &priv->abort_scan); + schedule_work(&priv->abort_scan); } else IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index fc553bacef17..6cc5ba2a2e39 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2567,12 +2567,13 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); static void __iwl3945_down(struct iwl_priv *priv) { unsigned long flags; - int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); + int exit_pending; IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - if (!exit_pending) - set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_scan_cancel_timeout(priv, 200); + + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ @@ -3172,15 +3173,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; - if (iwl_is_ready_rf(priv)) { - /* stop mac, cancel any scan request and clear - * RXON_FILTER_ASSOC_MSK BIT - */ - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - mutex_unlock(&priv->mutex); - } - iwl3945_down(priv); flush_workqueue(priv->workqueue); -- cgit v1.2.3 From cd44600fdd89832c0bc898189270a81be0db01cd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:36 +0200 Subject: iwlwifi: report scan completion when abort fail When we are not able to send abort command to firmware, notify mac80211 that we complete scan, as we will newer do it lately. Check for all possible errors that low level sending command procedure does not check, to assure we catch all failures cases. Patch fix one of the causes of wdev_cleanup_work warning reported at https://bugzilla.redhat.com/show_bug.cgi?id=593566 Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 131 ++++++++++++++++---------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ea338498ee1c..dbb07e8dfcd7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -54,34 +54,83 @@ #define IWL_PASSIVE_DWELL_BASE (100) #define IWL_CHANNEL_TUNE_TIME 5 +static int iwl_send_scan_abort(struct iwl_priv *priv) +{ + int ret; + struct iwl_rx_packet *pkt; + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_ABORT_CMD, + .flags = CMD_WANT_SKB, + }; + /* Exit instantly with error when device is not ready + * to receive scan abort command or it does not perform + * hardware scan currently */ + if (!test_bit(STATUS_READY, &priv->status) || + !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || + !test_bit(STATUS_SCAN_HW, &priv->status) || + test_bit(STATUS_FW_ERROR, &priv->status) || + test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EIO; -/** - * iwl_scan_cancel - Cancel any currently executing HW scan - * - * NOTE: priv->mutex is not required before calling this function - */ -int iwl_scan_cancel(struct iwl_priv *priv) -{ - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCANNING, &priv->status); - return 0; + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + return ret; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->u.status != CAN_ABORT_STATUS) { + /* The scan abort will return 1 for success or + * 2 for "failure". A failure condition can be + * due to simply not being in an active scan which + * can occur if we send the scan abort before we + * the microcode has notified us that a scan is + * completed. */ + IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + ret = -EIO; } - if (test_bit(STATUS_SCANNING, &priv->status)) { - if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n"); - schedule_work(&priv->abort_scan); + iwl_free_pages(priv, cmd.reply_page); + return ret; +} - } else - IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n"); +static void iwl_do_scan_abort(struct iwl_priv *priv) +{ + int ret; - return test_bit(STATUS_SCANNING, &priv->status); + lockdep_assert_held(&priv->mutex); + + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); + return; } + if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); + return; + } + + ret = iwl_send_scan_abort(priv); + if (ret) { + IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + ieee80211_scan_completed(priv->hw, true); + } else + IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); +} + +/** + * iwl_scan_cancel - Cancel any currently executing HW scan + */ +int iwl_scan_cancel(struct iwl_priv *priv) +{ + IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); + schedule_work(&priv->abort_scan); return 0; } EXPORT_SYMBOL(iwl_scan_cancel); + /** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan * @ms: amount of time to wait (in milliseconds) for scan to abort @@ -108,47 +157,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) } EXPORT_SYMBOL(iwl_scan_cancel_timeout); -static int iwl_send_scan_abort(struct iwl_priv *priv) -{ - int ret = 0; - struct iwl_rx_packet *pkt; - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_ABORT_CMD, - .flags = CMD_WANT_SKB, - }; - - /* If there isn't a scan actively going on in the hardware - * then we are in between scan bands and not actually - * actively scanning, so don't send the abort command */ - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return 0; - } - - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return ret; - } - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->u.status != CAN_ABORT_STATUS) { - /* The scan abort will return 1 for success or - * 2 for "failure". A failure condition can be - * due to simply not being in an active scan which - * can occur if we send the scan abort before we - * the microcode has notified us that a scan is - * completed. */ - IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status); - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - clear_bit(STATUS_SCAN_HW, &priv->status); - } - - iwl_free_pages(priv, cmd.reply_page); - - return ret; -} - /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl_rx_reply_scan(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -527,15 +535,10 @@ static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); - if (!test_bit(STATUS_READY, &priv->status) || - !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) - return; - cancel_delayed_work(&priv->scan_check); mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) - iwl_send_scan_abort(priv); + iwl_do_scan_abort(priv); mutex_unlock(&priv->mutex); } -- cgit v1.2.3 From e693a802f06f538b711333a32a83e2732dc4773d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:37 +0200 Subject: iwlwifi: rework iwl_scan_cancel_timeout Since on timeout version of iwl_scan_cancel procedure we can sleep, do not have to schedule abort_scan work to begin and perform scanning, can do this directly. Also now, as we do not queue abort_scan from restart work anymore, we can queue abort_scan to priv->workqueue. Don't drop mutex when waiting for scan complete. Use STATUS_HW_SCAN bit to check if scanning is currently pending, because STATUS_SCANNING will be cleared only with priv->mutex taken. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dbb07e8dfcd7..6d02f41e8caa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -126,7 +126,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) int iwl_scan_cancel(struct iwl_priv *priv) { IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); - schedule_work(&priv->abort_scan); + queue_work(priv->workqueue, &priv->abort_scan); return 0; } EXPORT_SYMBOL(iwl_scan_cancel); @@ -135,25 +135,24 @@ EXPORT_SYMBOL(iwl_scan_cancel); * iwl_scan_cancel_timeout - Cancel any currently executing HW scan * @ms: amount of time to wait (in milliseconds) for scan to abort * - * NOTE: priv->mutex must be held before calling this function */ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { - unsigned long now = jiffies; - int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(ms); + + lockdep_assert_held(&priv->mutex); - ret = iwl_scan_cancel(priv); - if (ret && ms) { - mutex_unlock(&priv->mutex); - while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && - test_bit(STATUS_SCANNING, &priv->status)) - msleep(1); - mutex_lock(&priv->mutex); + IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); - return test_bit(STATUS_SCANNING, &priv->status); + iwl_do_scan_abort(priv); + + while (time_before_eq(jiffies, timeout)) { + if (!test_bit(STATUS_SCAN_HW, &priv->status)) + break; + msleep(20); } - return ret; + return test_bit(STATUS_SCAN_HW, &priv->status); } EXPORT_SYMBOL(iwl_scan_cancel_timeout); -- cgit v1.2.3 From 02d8c14b590f583fd6e8c16fe779f845845effd9 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:38 +0200 Subject: iwlwifi: rewrite scan completion Assure (partially) we call ieee80211_scan_completed() only once when scan was requested from mac80211. Code path that first clear STATUS_SCANNING bit is responsible to call ieee80211_scan_completed(). Before the call, we check if mac80211 really request the scan. Still persist some cases when we behave wrong, that will be addressed in the next patches. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 65 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 6d02f41e8caa..e65a98d5d07f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -93,6 +93,19 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) return ret; } +static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) +{ + /* check if scan was requested from mac80211 */ + if (priv->scan_request) { + IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n"); + ieee80211_scan_completed(priv->hw, aborted); + } + + priv->is_internal_short_scan = false; + priv->scan_vif = NULL; + priv->scan_request = NULL; +} + static void iwl_do_scan_abort(struct iwl_priv *priv) { int ret; @@ -115,7 +128,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) clear_bit(STATUS_SCANNING, &priv->status); clear_bit(STATUS_SCAN_HW, &priv->status); clear_bit(STATUS_SCAN_ABORTING, &priv->status); - ieee80211_scan_completed(priv->hw, true); + iwl_complete_scan(priv, true); } else IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); } @@ -545,10 +558,11 @@ static void iwl_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - bool internal = false, aborted; + bool aborted; struct iwl_rxon_context *ctx; - IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); + IWL_DEBUG_INFO(priv, "Completed %sscan.\n", + priv->is_internal_short_scan ? "internal short " : ""); cancel_delayed_work(&priv->scan_check); @@ -558,37 +572,38 @@ static void iwl_bg_scan_completed(struct work_struct *work) if (aborted) IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); - IWL_DEBUG_INFO(priv, "Setting scan to off\n"); - - clear_bit(STATUS_SCANNING, &priv->status); - - if (priv->is_internal_short_scan) { - priv->is_internal_short_scan = false; - IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); - internal = true; - } else if (priv->scan_request) { - priv->scan_request = NULL; - priv->scan_vif = NULL; - ieee80211_scan_completed(priv->hw, aborted); + if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_INFO(priv, "Scan already completed.\n"); + goto out; } - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - goto out; + if (priv->is_internal_short_scan && !aborted) { + int err; - if (internal && priv->scan_request) { - int err = iwl_scan_initiate(priv, priv->scan_vif, false, - priv->scan_request->channels[0]->band); + /* Check if mac80211 requested scan during our internal scan */ + if (priv->scan_request == NULL) + goto out_complete; + /* If so request a new scan */ + err = iwl_scan_initiate(priv, priv->scan_vif, false, + priv->scan_request->channels[0]->band); if (err) { IWL_DEBUG_SCAN(priv, "failed to initiate pending scan: %d\n", err); - priv->scan_request = NULL; - priv->scan_vif = NULL; - ieee80211_scan_completed(priv->hw, true); - } else - goto out; + aborted = true; + goto out_complete; + } + + goto out; } +out_complete: + iwl_complete_scan(priv, aborted); + + /* Can we still talk to firmware ? */ + if (!iwl_is_ready_rf(priv)) + goto out; + /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); -- cgit v1.2.3 From f5354c17dc29681c241f2774f3ef9478fb586673 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:39 +0200 Subject: iwlwifi: force scan complete after timeout If we do not get notification from hardware about scan complete, after timeout do mac80211 scan completion anyway. This assure we end scan in case of firmware hung. Patch fix one of the causes of wdev_cleanup_work warning reported at https://bugzilla.redhat.com/show_bug.cgi?id=593566 Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 15 +++------------ drivers/net/wireless/iwlwifi/iwl-scan.c | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c9c523b2883f..b04a4f81ee97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2081,7 +2081,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - bool scan_completed = false; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2090,18 +2089,13 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, WARN_ON(ctx->vif != vif); ctx->vif = NULL; - iwl_scan_cancel_timeout(priv, 100); + if (priv->scan_vif == vif) + iwl_scan_cancel_timeout(priv, 100); iwl_set_mode(priv, vif); if (!ctx->always_active) ctx->is_active = false; - if (priv->scan_vif == vif) { - scan_completed = true; - priv->scan_vif = NULL; - priv->scan_request = NULL; - } - /* * When removing the IBSS interface, overwrite the * BT traffic load with the stored one from the last @@ -2115,9 +2109,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, memset(priv->bssid, 0, ETH_ALEN); mutex_unlock(&priv->mutex); - if (scan_completed) - ieee80211_scan_completed(priv->hw, true); - IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -2298,6 +2289,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->lock, flags); + iwl_scan_cancel_timeout(priv, 100); if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); @@ -2307,7 +2299,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) /* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */ - iwl_scan_cancel_timeout(priv, 100); ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv, ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index e65a98d5d07f..ce605e0aadfe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -106,6 +106,15 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) priv->scan_request = NULL; } +static void iwl_force_scan_end(struct iwl_priv *priv) +{ + IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + iwl_complete_scan(priv, true); +} + static void iwl_do_scan_abort(struct iwl_priv *priv) { int ret; @@ -125,10 +134,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) ret = iwl_send_scan_abort(priv); if (ret) { IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); - clear_bit(STATUS_SCANNING, &priv->status); - clear_bit(STATUS_SCAN_HW, &priv->status); - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_complete_scan(priv, true); + iwl_force_scan_end(priv); } else IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); } @@ -151,6 +157,7 @@ EXPORT_SYMBOL(iwl_scan_cancel); */ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { + int ret; unsigned long timeout = jiffies + msecs_to_jiffies(ms); lockdep_assert_held(&priv->mutex); @@ -165,7 +172,10 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) msleep(20); } - return test_bit(STATUS_SCAN_HW, &priv->status); + ret = test_bit(STATUS_SCAN_HW, &priv->status); + if (ret) + iwl_force_scan_end(priv); + return ret; } EXPORT_SYMBOL(iwl_scan_cancel_timeout); -- cgit v1.2.3 From 6bd1758d978f917dc0804f44e3528ef1a80d9d43 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:40 +0200 Subject: iwlwifi: assure we complete scan in scan_abort and scan_check works Assure we complete scan in mac80211 when we abort scanning (scan_abort work) or scan timeout occurs (scan_check work). Currently iwl_scan_cancel_timeout() procedure force scan finish in mac80211 at the end of timeout loop, so we can use it in proper work functions. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ce605e0aadfe..da037b2f08b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -490,18 +490,8 @@ static void iwl_bg_scan_check(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, scan_check.work); - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) && - !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - iwl_send_scan_abort(priv); - } + iwl_scan_cancel_timeout(priv, 200); mutex_unlock(&priv->mutex); } @@ -560,7 +550,7 @@ static void iwl_bg_abort_scan(struct work_struct *work) cancel_delayed_work(&priv->scan_check); mutex_lock(&priv->mutex); - iwl_do_scan_abort(priv); + iwl_scan_cancel_timeout(priv, 200); mutex_unlock(&priv->mutex); } -- cgit v1.2.3 From e7e16b90b477a07d17af37dceb2e8af1ddbd9712 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:41 +0200 Subject: iwlwifi: do not force complete scan too early Currently we force scan complete at the end of iwl_scan_cancel_timeout function. This cause race condition when we can get a new scan request from mac80211 and complete it by iwl_bg_complete from older scan. Change code to force scan complete only when really needed: device goes down, interface is removed or scan timeout occurs. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++-- drivers/net/wireless/iwlwifi/iwl-core.c | 6 +++-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-scan.c | 38 ++++++++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 +-- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d2315debd1b8..646864a26eaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4071,13 +4071,15 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) priv->cfg->ops->lib->cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->scan_check); - cancel_work_sync(&priv->start_internal_scan); cancel_delayed_work(&priv->alive_start); cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); + + iwl_cancel_scan_deferred_work(priv); + cancel_work_sync(&priv->bt_full_concurrency); cancel_work_sync(&priv->bt_runtime_config); + del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b04a4f81ee97..393f02d94c4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2089,8 +2089,10 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, WARN_ON(ctx->vif != vif); ctx->vif = NULL; - if (priv->scan_vif == vif) - iwl_scan_cancel_timeout(priv, 100); + if (priv->scan_vif == vif) { + iwl_scan_cancel_timeout(priv, 200); + iwl_force_scan_end(priv); + } iwl_set_mode(priv, vif); if (!ctx->always_active) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8dab074e491f..f1d40c6173c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -553,6 +553,7 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) void iwl_init_scan_params(struct iwl_priv *priv); int iwl_scan_cancel(struct iwl_priv *priv); int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); +void iwl_force_scan_end(struct iwl_priv *priv); int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); @@ -568,6 +569,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, struct ieee80211_vif *vif); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); +void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); /* For faster active scanning, scan will move to the next channel if fewer than * PLCP_QUIET_THRESH packets are heard on this channel within diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index da037b2f08b4..af9a83669f5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -106,14 +106,22 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) priv->scan_request = NULL; } -static void iwl_force_scan_end(struct iwl_priv *priv) +void iwl_force_scan_end(struct iwl_priv *priv) { + lockdep_assert_held(&priv->mutex); + + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); + return; + } + IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); clear_bit(STATUS_SCANNING, &priv->status); clear_bit(STATUS_SCAN_HW, &priv->status); clear_bit(STATUS_SCAN_ABORTING, &priv->status); iwl_complete_scan(priv, true); } +EXPORT_SYMBOL(iwl_force_scan_end); static void iwl_do_scan_abort(struct iwl_priv *priv) { @@ -157,7 +165,6 @@ EXPORT_SYMBOL(iwl_scan_cancel); */ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { - int ret; unsigned long timeout = jiffies + msecs_to_jiffies(ms); lockdep_assert_held(&priv->mutex); @@ -172,10 +179,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) msleep(20); } - ret = test_bit(STATUS_SCAN_HW, &priv->status); - if (ret) - iwl_force_scan_end(priv); - return ret; + return test_bit(STATUS_SCAN_HW, &priv->status); } EXPORT_SYMBOL(iwl_scan_cancel_timeout); @@ -490,8 +494,11 @@ static void iwl_bg_scan_check(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, scan_check.work); + /* Since we are here firmware does not finish scan and + * most likely is in bad shape, so we don't bother to + * send abort command, just force scan complete to mac80211 */ mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 200); + iwl_force_scan_end(priv); mutex_unlock(&priv->mutex); } @@ -547,8 +554,8 @@ static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); - cancel_delayed_work(&priv->scan_check); - + /* We keep scan_check work queued in case when firmware will not + * report back scan completed notification */ mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 200); mutex_unlock(&priv->mutex); @@ -631,3 +638,16 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_setup_scan_deferred_work); +void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->start_internal_scan); + cancel_work_sync(&priv->abort_scan); + cancel_work_sync(&priv->scan_completed); + + if (cancel_delayed_work_sync(&priv->scan_check)) { + mutex_lock(&priv->mutex); + iwl_force_scan_end(priv); + mutex_unlock(&priv->mutex); + } +} +EXPORT_SYMBOL(iwl_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6cc5ba2a2e39..116777122a79 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3762,10 +3762,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) iwl3945_hw_cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->scan_check); cancel_delayed_work(&priv->alive_start); - cancel_work_sync(&priv->start_internal_scan); cancel_work_sync(&priv->beacon_update); + + iwl_cancel_scan_deferred_work(priv); } static struct attribute *iwl3945_sysfs_entries[] = { -- cgit v1.2.3 From edeb78a7fa838b7fb9c2043680bd8da7cb5cb0e5 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:42 +0200 Subject: mac80211: wait for scan work complete before restarting hw This is needed to avoid warning in ieee80211_restart_hw about hardware scan in progress. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- net/mac80211/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a06b6ee63c07..7fb114856977 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -305,6 +305,9 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) trace_api_restart_hw(local); + /* wait for scan work complete */ + flush_workqueue(local->workqueue); + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), "%s called with hardware scan in progress\n", __func__); -- cgit v1.2.3 From 74d81b259d6c8493f066e34c939cb6fb7d3129e5 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:43 +0200 Subject: iwlwifi: cleanup scan initiate check Remove redundant checks and use iwl_is_ready_rf(). Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index af9a83669f5e..26dd8f3228c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -361,7 +361,7 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv, cancel_delayed_work(&priv->scan_check); - if (!iwl_is_ready(priv)) { + if (!iwl_is_ready_rf(priv)) { IWL_WARN(priv, "request scan called when driver not ready.\n"); return -EIO; } @@ -372,26 +372,11 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv, return -EBUSY; } - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); - return -EIO; - } - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_HC(priv, "Scan request while abort pending.\n"); return -EBUSY; } - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); - return -EIO; - } - - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n"); - return -EBUSY; - } - IWL_DEBUG_INFO(priv, "Starting %sscan...\n", internal ? "internal short " : ""); -- cgit v1.2.3 From 7cf24421292d92556d53630e6973b34324c94103 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:44 +0200 Subject: iwlwifi: use IWL_DEBUG_SCAN for debug scanning Replace IWL_DEBUG_{INFO,HC,RC} to IWL_DEBUG_SCAN in iwl-scan.c file. Add some more IWL_DEBUG_SCAN messages. This will allow to fully debug scanning using only IWL_DL_SCAN flag. Also start one message sentence with capital letter, since that convention in iwl-scan.c file. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 26dd8f3228c0..65b7cb4290cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -85,7 +85,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) * can occur if we send the scan abort before we * the microcode has notified us that a scan is * completed. */ - IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); ret = -EIO; } @@ -192,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, struct iwl_scanreq_notification *notif = (struct iwl_scanreq_notification *)pkt->u.raw; - IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status); + IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); #endif } @@ -251,7 +251,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, /* The HW is no longer scanning */ clear_bit(STATUS_SCAN_HW, &priv->status); - IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n", + IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n", (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2", jiffies_to_msecs(elapsed_jiffies (priv->scan_start, jiffies))); @@ -362,22 +362,22 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv, cancel_delayed_work(&priv->scan_check); if (!iwl_is_ready_rf(priv)) { - IWL_WARN(priv, "request scan called when driver not ready.\n"); + IWL_WARN(priv, "Request scan called when driver not ready.\n"); return -EIO; } if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO(priv, + IWL_DEBUG_SCAN(priv, "Multiple concurrent scan requests in parallel.\n"); return -EBUSY; } if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while abort pending.\n"); + IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); return -EBUSY; } - IWL_DEBUG_INFO(priv, "Starting %sscan...\n", + IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", internal ? "internal short " : ""); set_bit(STATUS_SCANNING, &priv->status); @@ -427,9 +427,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, * If an internal scan is in progress, just set * up the scan_request as per above. */ - if (priv->is_internal_short_scan) + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); ret = 0; - else + } else ret = iwl_scan_initiate(priv, vif, false, req->channels[0]->band); @@ -456,6 +457,8 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, start_internal_scan); + IWL_DEBUG_SCAN(priv, "Start internal scan\n"); + mutex_lock(&priv->mutex); if (priv->is_internal_short_scan == true) { @@ -479,6 +482,8 @@ static void iwl_bg_scan_check(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, scan_check.work); + IWL_DEBUG_SCAN(priv, "Scan check work\n"); + /* Since we are here firmware does not finish scan and * most likely is in bad shape, so we don't bother to * send abort command, just force scan complete to mac80211 */ @@ -539,6 +544,8 @@ static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); + IWL_DEBUG_SCAN(priv, "Abort scan work\n"); + /* We keep scan_check work queued in case when firmware will not * report back scan completed notification */ mutex_lock(&priv->mutex); @@ -553,7 +560,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) bool aborted; struct iwl_rxon_context *ctx; - IWL_DEBUG_INFO(priv, "Completed %sscan.\n", + IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", priv->is_internal_short_scan ? "internal short " : ""); cancel_delayed_work(&priv->scan_check); @@ -562,10 +569,10 @@ static void iwl_bg_scan_completed(struct work_struct *work) aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); if (aborted) - IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); + IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_INFO(priv, "Scan already completed.\n"); + IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); goto out; } -- cgit v1.2.3 From 3a160a5b5fc7d45fa2f869b23f8fcd27a4c05f8f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 13 Sep 2010 14:46:45 +0200 Subject: iwlwifi: apply settings when finishing scan Even is someone else complete scanning in mac80211, apply rxon and tx power settings if gets scan complete notification from hardware. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi W Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 65b7cb4290cb..599573f2b01f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -573,7 +573,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); - goto out; + goto out_settings; } if (priv->is_internal_short_scan && !aborted) { @@ -599,6 +599,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) out_complete: iwl_complete_scan(priv, aborted); +out_settings: /* Can we still talk to firmware ? */ if (!iwl_is_ready_rf(priv)) goto out; -- cgit v1.2.3 From cc0de6536e8b70d61948128a9cbf86920066c53d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 14 Sep 2010 13:07:28 +0530 Subject: ath9k_htc: Fix memory leak on WMI event handler ath9k_wmi_ctrl_rx is racy with ath9k_wmi_tasklet on event notification due to which the wmi_skb may be overwritten which leads to memory leak. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.c | 72 +++++++++++------------------------- drivers/net/wireless/ath/ath9k/wmi.h | 6 +-- 2 files changed, 23 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 45fe9cac7971..93a8bda09c25 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -124,55 +124,11 @@ void ath9k_wmi_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath_common *common = ath9k_hw_common(priv->ah); - struct wmi_cmd_hdr *hdr; - struct wmi_swba *swba_hdr; - enum wmi_event_id event; - struct sk_buff *skb; - void *wmi_event; - unsigned long flags; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - skb = priv->wmi->wmi_skb; - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + ath_print(common, ATH_DBG_WMI, "SWBA Event received\n"); - hdr = (struct wmi_cmd_hdr *) skb->data; - event = be16_to_cpu(hdr->command_id); - wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + ath9k_htc_swba(priv, priv->wmi->beacon_pending); - ath_print(common, ATH_DBG_WMI, - "WMI Event: 0x%x\n", event); - - switch (event) { - case WMI_TGT_RDY_EVENTID: - break; - case WMI_SWBA_EVENTID: - swba_hdr = (struct wmi_swba *) wmi_event; - ath9k_htc_swba(priv, swba_hdr->beacon_pending); - break; - case WMI_FATAL_EVENTID: - break; - case WMI_TXTO_EVENTID: - break; - case WMI_BMISS_EVENTID: - break; - case WMI_WLAN_TXCOMP_EVENTID: - break; - case WMI_DELBA_EVENTID: - break; - case WMI_TXRATE_EVENTID: -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; - default: - break; - } - - kfree_skb(skb); } static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb) @@ -191,6 +147,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi *wmi = (struct wmi *) priv; struct wmi_cmd_hdr *hdr; u16 cmd_id; + void *wmi_event; +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + __be32 txrate; +#endif if (unlikely(wmi->stopped)) goto free_skb; @@ -199,10 +159,22 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, cmd_id = be16_to_cpu(hdr->command_id); if (cmd_id & 0x1000) { - spin_lock(&wmi->wmi_lock); - wmi->wmi_skb = skb; - spin_unlock(&wmi->wmi_lock); - tasklet_schedule(&wmi->drv_priv->wmi_tasklet); + wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + switch (cmd_id) { + case WMI_SWBA_EVENTID: + wmi->beacon_pending = *(u8 *)wmi_event; + tasklet_schedule(&wmi->drv_priv->wmi_tasklet); + break; + case WMI_TXRATE_EVENTID: +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; + wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); +#endif + break; + default: + break; + } + kfree_skb(skb); return; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index a0bf857625df..ac61074af8ac 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -31,10 +31,6 @@ struct wmi_cmd_hdr { __be16 seq_no; } __packed; -struct wmi_swba { - u8 beacon_pending; -} __packed; - enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -104,7 +100,7 @@ struct wmi { u32 cmd_rsp_len; bool stopped; - struct sk_buff *wmi_skb; + u8 beacon_pending; spinlock_t wmi_lock; atomic_t mwrite_cnt; -- cgit v1.2.3 From 4a0e8ecca4eeed38d4b3b7a317a3aaab4dd3cacd Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 14 Sep 2010 14:35:55 +0530 Subject: ath9k_htc: Fix CPU usage issue during scan period The CPU consumption during the scan period is high, since the register write go over Interrupt endpoint. On downloading the firmware to the target, the USB descriptors are 'patched' to change the type of the endpoints from Interrupt to Bulk. With this fix, the CPU usage during a scan run comes down to acceptable levels. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 495f18950ac9..27f88a0a155b 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -92,10 +92,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, cmd->skb = skb; cmd->hif_dev = hif_dev; - usb_fill_int_urb(urb, hif_dev->udev, - usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE), + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE), skb->data, skb->len, - hif_usb_regout_cb, cmd, 1); + hif_usb_regout_cb, cmd); usb_anchor_urb(urb, &hif_dev->regout_submitted); ret = usb_submit_urb(urb, GFP_KERNEL); @@ -822,7 +822,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - int ret; + int ret, idx; + struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; + struct usb_endpoint_descriptor *endp; /* Request firmware */ ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, @@ -850,6 +852,22 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) goto err_fw_download; } + /* On downloading the firmware to the target, the USB descriptor of EP4 + * is 'patched' to change the type of the endpoint to Bulk. This will + * bring down CPU usage during the scan period. + */ + for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) { + endp = &alt->endpoint[idx].desc; + if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) + == 0x04) && + ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT)) { + endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK; + endp->bmAttributes |= USB_ENDPOINT_XFER_BULK; + endp->bInterval = 0; + } + } + return 0; err_fw_download: -- cgit v1.2.3 From 31a01645c0c7b46d7f74777cd2a66ddb2a22bbd9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Sep 2010 18:37:19 +0200 Subject: ath9k: fix BSSID mask calculation At the time the .add_interface driver op is called, the interface has not been marked as running yet, so ieee80211_iterate_active_interfaces will not pass it to the iterator function. Because of this, the calculated BSSID mask is wrong, which breaks multi-BSS operation. Additionally, the current way of comparing all addresses against each other is pointless, as the hardware only uses the hardware MAC address and the BSSID mask for matching the destination address, so all the address array reallocation is completely unnecessary. This patch simplifies the logic by setting the initial mask bytes to 0xff and removing all bits in the iterator call that don't match the hardware MAC address. It also calls the iterator for the vif that was passed to add_interface() Signed-off-by: Felix Fietkau Tested-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 2 +- drivers/net/wireless/ath/ath9k/virtual.c | 63 ++++++++------------------------ 3 files changed, 17 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 5fe570bb5c4c..c8ff417f6c10 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -719,7 +719,7 @@ static inline void ath_ahb_exit(void) {}; void ath9k_ps_wakeup(struct ath_softc *sc); void ath9k_ps_restore(struct ath_softc *sc); -void ath9k_set_bssid_mask(struct ieee80211_hw *hw); +void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int ath9k_wiphy_add(struct ath_softc *sc); int ath9k_wiphy_del(struct ath_wiphy *aphy); void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1165f909ef04..d3f96e4520f1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1415,7 +1415,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, sc->nvifs++; if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath9k_set_bssid_mask(hw); + ath9k_set_bssid_mask(hw, vif); if (sc->nvifs > 1) goto out; /* skip global settings for secondary vif */ diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index fd20241f57d8..ec7cf5ee56bc 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -19,45 +19,36 @@ #include "ath9k.h" struct ath9k_vif_iter_data { - int count; - u8 *addr; + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; }; static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { struct ath9k_vif_iter_data *iter_data = data; - u8 *nbuf; - - nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN, - GFP_ATOMIC); - if (nbuf == NULL) - return; + int i; - memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN); - iter_data->addr = nbuf; - iter_data->count++; + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); } -void ath9k_set_bssid_mask(struct ieee80211_hw *hw) +void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_vif_iter_data iter_data; - int i, j; - u8 mask[ETH_ALEN]; + int i; /* - * Add primary MAC address even if it is not in active use since it - * will be configured to the hardware as the starting point and the - * BSSID mask will need to be changed if another address is active. + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. */ - iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC); - if (iter_data.addr) { - memcpy(iter_data.addr, common->macaddr, ETH_ALEN); - iter_data.count = 1; - } else - iter_data.count = 0; + iter_data.hw_macaddr = common->macaddr; + memset(&iter_data.mask, 0xff, ETH_ALEN); + + if (vif) + ath9k_vif_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ spin_lock_bh(&sc->wiphy_lock); @@ -71,31 +62,7 @@ void ath9k_set_bssid_mask(struct ieee80211_hw *hw) } spin_unlock_bh(&sc->wiphy_lock); - /* Generate an address mask to cover all active addresses */ - memset(mask, 0, ETH_ALEN); - for (i = 0; i < iter_data.count; i++) { - u8 *a1 = iter_data.addr + i * ETH_ALEN; - for (j = i + 1; j < iter_data.count; j++) { - u8 *a2 = iter_data.addr + j * ETH_ALEN; - mask[0] |= a1[0] ^ a2[0]; - mask[1] |= a1[1] ^ a2[1]; - mask[2] |= a1[2] ^ a2[2]; - mask[3] |= a1[3] ^ a2[3]; - mask[4] |= a1[4] ^ a2[4]; - mask[5] |= a1[5] ^ a2[5]; - } - } - - kfree(iter_data.addr); - - /* Invert the mask and configure hardware */ - common->bssidmask[0] = ~mask[0]; - common->bssidmask[1] = ~mask[1]; - common->bssidmask[2] = ~mask[2]; - common->bssidmask[3] = ~mask[3]; - common->bssidmask[4] = ~mask[4]; - common->bssidmask[5] = ~mask[5]; - + memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ath_hw_setbssidmask(common); } -- cgit v1.2.3 From 2944f45d9db851e186774df7c9cbf075f4a585c6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Sep 2010 18:37:20 +0200 Subject: mac80211: add a note about iterating interfaces during add_interface() Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/mac80211.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f91fc331369b..19a5cb4a6582 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2293,6 +2293,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted); * This function allows the iterator function to sleep, when the iterator * function is atomic @ieee80211_iterate_active_interfaces_atomic can * be used. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call @@ -2310,6 +2311,7 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, * hardware that are currently active and calls the callback for them. * This function requires the iterator callback function to be atomic, * if that is not desired, use @ieee80211_iterate_active_interfaces instead. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call, cannot sleep -- cgit v1.2.3 From 3ae74c33c4f799f6bf6d67240a94a0814a8f1944 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Sep 2010 18:38:26 +0200 Subject: ath9k_hw: handle rx key miss If AR_KeyMiss is set in the rx descriptor and AR_RxFrameOK is unset, the hardware could not locate a valid key during a decryption attempt. In this case, the frame must not be reported as decrypted, otherwise mac80211 sees only random garbage. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 ++- drivers/net/wireless/ath/ath9k/mac.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index a462da23e87e..3b424ca1ba84 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_DECRYPT; } else if (rxsp->status11 & AR_MichaelErr) { rxs->rs_status |= ATH9K_RXERR_MIC; - } + } else if (rxsp->status11 & AR_KeyMiss) + rxs->rs_status |= ATH9K_RXERR_DECRYPT; } return 0; diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 0b7d1253f0c0..3efda8a8a3c1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -714,6 +714,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, else if ((ads.ds_rxstatus8 & AR_MichaelErr) && rs->rs_keyix != ATH9K_RXKEYIX_INVALID) rs->rs_status |= ATH9K_RXERR_MIC; + else if (ads.ds_rxstatus8 & AR_KeyMiss) + rs->rs_status |= ATH9K_RXERR_DECRYPT; } return 0; -- cgit v1.2.3 From 364734fafbba0c3133e482db78149b9a823ae7a5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Sep 2010 20:22:44 +0200 Subject: ath9k_hw: remove useless hw capability flags Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 3 +-- drivers/net/wireless/ath/ath9k/hw.c | 21 --------------- drivers/net/wireless/ath/ath9k/hw.h | 37 ++++++++++----------------- drivers/net/wireless/ath/ath9k/init.c | 3 +-- drivers/net/wireless/ath/ath9k/main.c | 12 ++------- drivers/net/wireless/ath/ath9k/recv.c | 3 +-- 7 files changed, 19 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 695e2b088d10..717f2b821f0d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -601,8 +601,7 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) common->tx_chainmask = priv->ah->caps.tx_chainmask; common->rx_chainmask = priv->ah->caps.rx_chainmask; - if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); + memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); priv->ah->opmode = NL80211_IFTYPE_STATION; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2a6e45a293a9..c99600aff76d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -415,8 +415,7 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) ath9k_hw_setrxfilter(ah, rfilt); /* configure bssid mask */ - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath_hw_setbssidmask(common); + ath_hw_setbssidmask(common); /* configure operational mode */ ath9k_hw_setopmode(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0a61f426d7d7..40c6451602d3 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1574,12 +1574,6 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, keyType = AR_KEYTABLE_TYPE_AES; break; case ATH9K_CIPHER_AES_CCM: - if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { - ath_print(common, ATH_DBG_ANY, - "AES-CCM not supported by mac rev 0x%x\n", - ah->hw_version.macRev); - return false; - } keyType = AR_KEYTABLE_TYPE_CCM; break; case ATH9K_CIPHER_TKIP: @@ -2143,24 +2137,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->low_5ghz_chan = 4920; pCap->high_5ghz_chan = 6100; - pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP; - pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP; - pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM; - - pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP; - pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP; - pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM; - if (ah->config.ht_enable) pCap->hw_caps |= ATH9K_HW_CAP_HT; else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; - pCap->hw_caps |= ATH9K_HW_CAP_GTT; - pCap->hw_caps |= ATH9K_HW_CAP_VEOL; - pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK; - pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH; - if (capField & AR_EEPROM_EEPCAP_MAXQCU) pCap->total_queues = MS(capField, AR_EEPROM_EEPCAP_MAXQCU); @@ -2173,8 +2154,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->keycache_size = AR_KEYTABLE_SIZE; - pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; else diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1724b17bfc73..a3c2ce235123 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -181,30 +181,19 @@ enum wireless_mode { }; enum ath9k_hw_caps { - ATH9K_HW_CAP_MIC_AESCCM = BIT(0), - ATH9K_HW_CAP_MIC_CKIP = BIT(1), - ATH9K_HW_CAP_MIC_TKIP = BIT(2), - ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3), - ATH9K_HW_CAP_CIPHER_CKIP = BIT(4), - ATH9K_HW_CAP_CIPHER_TKIP = BIT(5), - ATH9K_HW_CAP_VEOL = BIT(6), - ATH9K_HW_CAP_BSSIDMASK = BIT(7), - ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8), - ATH9K_HW_CAP_HT = BIT(9), - ATH9K_HW_CAP_GTT = BIT(10), - ATH9K_HW_CAP_FASTCC = BIT(11), - ATH9K_HW_CAP_RFSILENT = BIT(12), - ATH9K_HW_CAP_CST = BIT(13), - ATH9K_HW_CAP_ENHANCEDPM = BIT(14), - ATH9K_HW_CAP_AUTOSLEEP = BIT(15), - ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), - ATH9K_HW_CAP_EDMA = BIT(17), - ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), - ATH9K_HW_CAP_LDPC = BIT(19), - ATH9K_HW_CAP_FASTCLOCK = BIT(20), - ATH9K_HW_CAP_SGI_20 = BIT(21), - ATH9K_HW_CAP_PAPRD = BIT(22), - ATH9K_HW_CAP_ANT_DIV_COMB = BIT(23), + ATH9K_HW_CAP_HT = BIT(0), + ATH9K_HW_CAP_RFSILENT = BIT(1), + ATH9K_HW_CAP_CST = BIT(2), + ATH9K_HW_CAP_ENHANCEDPM = BIT(3), + ATH9K_HW_CAP_AUTOSLEEP = BIT(4), + ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), + ATH9K_HW_CAP_EDMA = BIT(6), + ATH9K_HW_CAP_RAC_SUPPORTED = BIT(7), + ATH9K_HW_CAP_LDPC = BIT(8), + ATH9K_HW_CAP_FASTCLOCK = BIT(9), + ATH9K_HW_CAP_SGI_20 = BIT(10), + ATH9K_HW_CAP_PAPRD = BIT(11), + ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), }; struct ath9k_hw_capabilities { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e7c07b3370cc..5c77a9913e03 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -522,8 +522,7 @@ static void ath9k_init_misc(struct ath_softc *sc) ath9k_hw_set_diversity(sc->sc_ah, true); sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); + memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); sc->beacon.slottime = ATH9K_SLOT_TIME_9; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d3f96e4520f1..a2f7eb2a552b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1156,8 +1156,7 @@ static int ath9k_start(struct ieee80211_hw *hw) else ah->imask |= ATH9K_INT_RX; - if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) - ah->imask |= ATH9K_INT_GTT; + ah->imask |= ATH9K_INT_GTT; if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) ah->imask |= ATH9K_INT_CST; @@ -1379,12 +1378,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && - sc->nvifs > 0) { - ret = -ENOBUFS; - goto out; - } - switch (vif->type) { case NL80211_IFTYPE_STATION: ic_opmode = NL80211_IFTYPE_STATION; @@ -1414,8 +1407,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, sc->nvifs++; - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath9k_set_bssid_mask(hw, vif); + ath9k_set_bssid_mask(hw, vif); if (sc->nvifs > 1) goto out; /* skip global settings for secondary vif */ diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b32c8f033d20..6fb3b4536045 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -119,8 +119,7 @@ static void ath_opmode_init(struct ath_softc *sc) ath9k_hw_setrxfilter(ah, rfilt); /* configure bssid mask */ - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath_hw_setbssidmask(common); + ath_hw_setbssidmask(common); /* configure operational mode */ ath9k_hw_setopmode(ah); -- cgit v1.2.3 From a2c1e3dad516618cb0fbfb1a62c36d0b0744573a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Sep 2010 21:34:14 +0200 Subject: mac80211: match only assigned bss in sta_info_get_bss sta_info_get_bss() is used to match STA pointers for VLAN/AP interfaces, but if the same station is also added to multiple other interfaces it will erroneously match because both pointers are NULL, fix this by ignoring NULL pointers here. Reported-by: Ben Greear Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 687077e49dc6..e356ff80671a 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -125,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, lockdep_is_held(&local->sta_mtx)); while (sta) { if ((sta->sdata == sdata || - sta->sdata->bss == sdata->bss) && + (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) break; sta = rcu_dereference_check(sta->hnext, -- cgit v1.2.3 From 78381c41776572cb642a485219c5d7651f198fbd Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 14 Sep 2010 16:26:44 -0400 Subject: wl1271: remove warnings in wl1271_sdio_set_power MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were introduced in "wl1271: sdio: claim host only when doing IO" drivers/net/wireless/wl12xx/wl1271_sdio.c: In function ‘wl1271_sdio_set_power’: drivers/net/wireless/wl12xx/wl1271_sdio.c:193: warning: ‘return’ with a value, in function returning void drivers/net/wireless/wl12xx/wl1271_sdio.c:195: warning: ‘return’ with a value, in function returning void drivers/net/wireless/wl12xx/wl1271_sdio.c:186: warning: unused variable ‘func’ Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index b3c3158551c8..b5d9565f659f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -159,40 +159,34 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, wl1271_error("sdio write failed (%d)", ret); } -static int wl1271_sdio_power_on(struct wl1271 *wl) +static void wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); - - return 0; } -static int wl1271_sdio_power_off(struct wl1271 *wl) +static void wl1271_sdio_power_off(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); - - return 0; } static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) { - struct sdio_func *func = wl_to_func(wl); - /* Let the SDIO stack handle wlan_enable control, so we * keep host claimed while wlan is in use to keep wl1271 * alive. */ if (enable) - return wl1271_sdio_power_on(wl); + wl1271_sdio_power_on(wl); else - return wl1271_sdio_power_off(wl); + wl1271_sdio_power_off(wl); } -- cgit v1.2.3 From 068e8a30320e33b1f8d15df9eaef84f04258f96d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 12 Sep 2010 22:45:39 +0000 Subject: e1000e: Simplify MSI interrupt testing The code is quite convoluted, simplify it. This also avoids calling e1000_request_irq() without testing the value it returned, which was bad. Signed-off-by: Jean Delvare Cc: Bruce Allan Cc: Jeff Kirsher Acked-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c9b66f4727e4..e2c7e0d767b1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3412,22 +3412,16 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) if (adapter->flags & FLAG_MSI_TEST_FAILED) { adapter->int_mode = E1000E_INT_MODE_LEGACY; - err = -EIO; - e_info("MSI interrupt test failed!\n"); - } + e_info("MSI interrupt test failed, using legacy interrupt.\n"); + } else + e_dbg("MSI interrupt test succeeded!\n"); free_irq(adapter->pdev->irq, netdev); pci_disable_msi(adapter->pdev); - if (err == -EIO) - goto msi_test_failed; - - /* okay so the test worked, restore settings */ - e_dbg("MSI interrupt test succeeded!\n"); msi_test_failed: e1000e_set_interrupt_capability(adapter); - e1000_request_irq(adapter); - return err; + return e1000_request_irq(adapter); } /** @@ -3459,21 +3453,6 @@ static int e1000_test_msi(struct e1000_adapter *adapter) pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); } - /* success ! */ - if (!err) - return 0; - - /* EIO means MSI test failed */ - if (err != -EIO) - return err; - - /* back to INTx mode */ - e_warn("MSI interrupt test failed, using legacy interrupt.\n"); - - e1000_free_irq(adapter); - - err = e1000_request_irq(adapter); - return err; } -- cgit v1.2.3 From 6f68ad7fbb421df0aa3c267768245b2e86a91f74 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 18:23:52 +0000 Subject: drivers/isdn: Use static const char * const where possible Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/isdn/pcbit/edss1.c | 2 +- drivers/isdn/pcbit/edss1.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index d5920ae22d73..80c9c16fd5ef 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c @@ -33,7 +33,7 @@ #include "callbacks.h" -char * isdn_state_table[] = { +const char * const isdn_state_table[] = { "Closed", "Call initiated", "Overlap sending", diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h index 0b64f97015d8..39f8346e28c5 100644 --- a/drivers/isdn/pcbit/edss1.h +++ b/drivers/isdn/pcbit/edss1.h @@ -90,7 +90,7 @@ struct fsm_timer_entry { unsigned long timeout; /* in seconds */ }; -extern char * isdn_state_table[]; +extern const char * const isdn_state_table[]; void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, unsigned short event, struct callb_data *); -- cgit v1.2.3 From 6fa59c9da82adcc7d63a2776969548e2b45448e0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 18:23:53 +0000 Subject: drivers/net: Use static const char * const where possible Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/3c515.c | 4 +++- drivers/net/eth16i.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 8a6eb0c44486..cdf7226a7c43 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -662,7 +662,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n"); { - char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" }; + static const char * const ram_split[] = { + "5:3", "3:1", "1:1", "3:5" + }; __u32 config; EL3WINDOW(3); vp->available_media = inw(ioaddr + Wn3_Options); diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 10e39f2b31c3..ce22e15a3776 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -637,7 +637,9 @@ static void eth16i_initialize(struct net_device *dev, int boot) /* Set interface port type */ if(boot) { - char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" }; + static const char * const porttype[] = { + "BNC", "DIX", "TP", "AUTO", "FROM_EPROM" + }; switch(dev->if_port) { -- cgit v1.2.3 From 99101d3d8900dd3fc3cac44859ab8a380e1e553f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 18:23:54 +0000 Subject: drivers/net/pcmcia: Use static const char * const where possible Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/pcmcia/3c589_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 7f2baf5eae26..35562a395770 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -266,7 +266,7 @@ static int tc589_config(struct pcmcia_device *link) __be16 *phys_addr; int ret, i, j, multi = 0, fifo; unsigned int ioaddr; - char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; u8 *buf; size_t len; -- cgit v1.2.3 From 030bda0d416babd0cf34e584086f815b1c9d417c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 18:23:55 +0000 Subject: drivers/net/wireless: Use static const char * const where possible Signed-off-by: Joe Perches Acked-by: Ivo van Doorn Signed-off-by: David S. Miller --- drivers/net/wireless/rt2x00/rt2x00debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b8cf45c4e9f5..c1710b27ba70 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -380,7 +380,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file, loff_t *offset) { struct rt2x00debug_intf *intf = file->private_data; - char *name[] = { "WEP64", "WEP128", "TKIP", "AES" }; + static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" }; char *data; char *temp; size_t size; -- cgit v1.2.3 From 55b1804c678e679e1018671bd40b583eab124689 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 18:24:01 +0000 Subject: net/irda: Use static const char * const where possible Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/irda/irlan_event.h | 2 +- net/irda/irlan/irlan_event.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/irda/irlan_event.h b/include/net/irda/irlan_event.h index 6d9539f05806..018b5a77e610 100644 --- a/include/net/irda/irlan_event.h +++ b/include/net/irda/irlan_event.h @@ -67,7 +67,7 @@ typedef enum { IRLAN_WATCHDOG_TIMEOUT, } IRLAN_EVENT; -extern char *irlan_state[]; +extern const char * const irlan_state[]; void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event, struct sk_buff *skb); diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c index cbcb4eb54037..43f16040a6fe 100644 --- a/net/irda/irlan/irlan_event.c +++ b/net/irda/irlan/irlan_event.c @@ -24,7 +24,7 @@ #include -char *irlan_state[] = { +const char * const irlan_state[] = { "IRLAN_IDLE", "IRLAN_QUERY", "IRLAN_CONN", -- cgit v1.2.3 From 25aa4efe4feb4150fe613169795df505c5018f2b Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Tue, 14 Sep 2010 13:31:16 +0000 Subject: X.25 remove bkl in listen Listen updates socket values and needs lock_sock. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 5e86d4e97dce..f6a8f175b4f5 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -507,14 +507,14 @@ static int x25_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk; int rc = -EOPNOTSUPP; - lock_kernel(); + lock_sock(sk); if (sk->sk_state != TCP_LISTEN) { memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; rc = 0; } - unlock_kernel(); + release_sock(sk); return rc; } -- cgit v1.2.3 From 90c27297a9bfb8ea11c0e3f73ad90c4c66e8501e Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Tue, 14 Sep 2010 13:31:38 +0000 Subject: X.25 remove bkl in bind Accept updates socket values in 3 lines so wrapped with lock_sock. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index f6a8f175b4f5..bd6fce31a738 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -688,7 +688,6 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; int len, i, rc = 0; - lock_kernel(); if (!sock_flag(sk, SOCK_ZAPPED) || addr_len != sizeof(struct sockaddr_x25) || addr->sx25_family != AF_X25) { @@ -704,12 +703,13 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } } + lock_sock(sk); x25_sk(sk)->source_addr = addr->sx25_addr; x25_insert_socket(sk); sock_reset_flag(sk, SOCK_ZAPPED); + release_sock(sk); SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); out: - unlock_kernel(); return rc; } -- cgit v1.2.3 From 141646ce56735cedb2336b3cd21364287f0aa4c7 Mon Sep 17 00:00:00 2001 From: Andrew Hendry Date: Tue, 14 Sep 2010 20:38:54 -0700 Subject: X.25 remove bkl in accept Accept already has socket locking. [ Extend socket locking over TCP_LISTEN state test. -DaveM ] Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index bd6fce31a738..04321eec65e1 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -869,8 +869,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) struct sk_buff *skb; int rc = -EINVAL; - lock_kernel(); - if (!sk || sk->sk_state != TCP_LISTEN) + if (!sk) goto out; rc = -EOPNOTSUPP; @@ -878,6 +877,10 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) goto out; lock_sock(sk); + rc = -EINVAL; + if (sk->sk_state != TCP_LISTEN) + goto out2; + rc = x25_wait_for_data(sk, sk->sk_rcvtimeo); if (rc) goto out2; @@ -897,7 +900,6 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) out2: release_sock(sk); out: - unlock_kernel(); return rc; } -- cgit v1.2.3 From 21a4591794c82c1a73f9d45d6400f878648261e3 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Tue, 14 Sep 2010 13:32:03 +0000 Subject: X.25 remove bkl in connect Connect already has socket locking. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 04321eec65e1..c1bbf9ec71f4 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -751,7 +751,6 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, struct x25_route *rt; int rc = 0; - lock_kernel(); lock_sock(sk); if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { sock->state = SS_CONNECTED; @@ -829,7 +828,6 @@ out_put_route: x25_route_put(rt); out: release_sock(sk); - unlock_kernel(); return rc; } -- cgit v1.2.3 From 20cbd3e120a0c20bebe420e1fed0e816730bb988 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 14 Sep 2010 20:16:59 +0200 Subject: dccp ccid-3: A lower bound for the inter-packet scheduling algorithm This fixes a subtle bug in the calculation of the inter-packet gap and shows that t_delta, as it is currently used, is not needed. The algorithm from RFC 5348, 8.3 below continually computes a send time t_nom, which is initialised with the current time t_now; t_gran = 1E6 / HZ specifies the scheduling granularity, s the packet size, and X the sending rate: t_distance = t_nom - t_now; // in microseconds t_delta = min(t_ipi, t_gran) / 2; // `delta' parameter in microseconds if (t_distance >= t_delta) { reschedule after (t_distance / 1000) milliseconds; } else { t_ipi = s / X; // inter-packet interval in usec t_nom += t_ipi; // compute the next send time send packet now; } Problem: -------- Rescheduling requires a conversion into milliseconds (sk_reset_timer()). The highest jiffy resolution with HZ=1000 is 1 millisecond, so using a higher granularity does not make much sense here. As a consequence, values of t_distance < 1000 are truncated to 0. This issue has so far been resolved by using instead if (t_distance >= t_delta + 1000) reschedule after (t_distance / 1000) milliseconds; This is unnecessarily large, a lower bound is t_delta' = max(t_delta, 1000). And it implies a further simplification: a) when HZ >= 500, then t_delta <= t_gran/2 = 10^6/(2*HZ) <= 1000, so that t_delta' = MAX(1000, t_delta) = 1000 (constant value); b) when HZ < 500, then t_delta = 1/2*MIN(rtt, t_ipi, t_gran) <= t_gran/2, so that 1000 <= t_delta' <= t_gran/2. The maximum error of using a constant t_delta in (b) is less than half a jiffy. Fix: ---- The patch replaces t_delta with a constant, whose value depends on CONFIG_HZ, changing the above algorithm to: if (t_distance >= t_delta') reschedule after (t_distance / 1000) milliseconds; where t_delta' = 10^6/(2*HZ) if HZ < 500, and t_delta' = 1000 otherwise. Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 19 ++++++++----------- net/dccp/ccids/ccid3.h | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 278e17069322..e9ca0983ac58 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -91,19 +91,16 @@ static inline u64 rfc3390_initial_rate(struct sock *sk) return scaled_div(w_init << 6, hc->tx_rtt); } -/* - * Recalculate t_ipi and delta (should be called whenever X changes) +/** + * ccid3_update_send_interval - Calculate new t_ipi = s / X_inst + * This respects the granularity of X_inst (64 * bytes/second). */ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc) { - /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */ hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x); - /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ - hc->tx_delta = min_t(u32, hc->tx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN); - - ccid3_pr_debug("t_ipi=%u, delta=%u, s=%u, X=%u\n", hc->tx_t_ipi, - hc->tx_delta, hc->tx_s, (unsigned)(hc->tx_x >> 6)); + ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi, + hc->tx_s, (unsigned)(hc->tx_x >> 6)); } static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hc, ktime_t now) @@ -332,15 +329,15 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) delay = ktime_us_delta(hc->tx_t_nom, now); ccid3_pr_debug("delay=%ld\n", (long)delay); /* - * Scheduling of packet transmissions [RFC 3448, 4.6] + * Scheduling of packet transmissions (RFC 5348, 8.3) * * if (t_now > t_nom - delta) * // send the packet now * else * // send the packet in (t_nom - t_now) milliseconds. */ - if (delay - (s64)hc->tx_delta >= 1000) - return (u32)delay / 1000L; + if (delay >= TFRC_T_DELTA) + return (u32)delay / USEC_PER_MSEC; ccid3_hc_tx_update_win_count(hc, now); break; diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index b7e569c22f36..4a00174a97dd 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -45,12 +45,22 @@ /* Two seconds as per RFC 5348, 4.2 */ #define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) -/* In usecs - half the scheduling granularity as per RFC3448 4.6 */ -#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) - /* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */ #define TFRC_T_MBI 64 +/* + * The t_delta parameter (RFC 5348, 8.3): delays of less than %USEC_PER_MSEC are + * rounded down to 0, since sk_reset_timer() here uses millisecond granularity. + * Hence we can use a constant t_delta = %USEC_PER_MSEC when HZ >= 500. A coarse + * resolution of HZ < 500 means that the error is below one timer tick (t_gran) + * when using the constant t_delta = t_gran / 2 = %USEC_PER_SEC / (2 * HZ). + */ +#if (HZ >= 500) +# define TFRC_T_DELTA USEC_PER_MSEC +#else +# define TFRC_T_DELTA (USEC_PER_SEC / (2 * HZ)) +#endif + enum ccid3_options { TFRC_OPT_LOSS_EVENT_RATE = 192, TFRC_OPT_LOSS_INTERVALS = 193, @@ -90,7 +100,6 @@ enum ccid3_hc_tx_states { * @tx_no_feedback_timer: Handle to no feedback timer * @tx_t_ld: Time last doubled during slow start * @tx_t_nom: Nominal send time of next packet - * @tx_delta: Send timer delta (RFC 3448, 4.6) in usecs * @tx_hist: Packet history * @tx_options_received: Parsed set of retrieved options */ @@ -109,7 +118,6 @@ struct ccid3_hc_tx_sock { struct timer_list tx_no_feedback_timer; ktime_t tx_t_ld; ktime_t tx_t_nom; - u32 tx_delta; struct tfrc_tx_hist_entry *tx_hist; struct ccid3_options_received tx_options_received; }; -- cgit v1.2.3 From d2c726309d88df3c5568486e4b5b9e4c3150903f Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 14 Sep 2010 20:18:00 +0200 Subject: dccp ccid-3: remove buggy RTT-sampling history lookup This removes the RTT-sampling function tfrc_tx_hist_rtt(), since 1. it suffered from complex passing of return values (the return value both indicated successful lookup while the value doubled as RTT sample); 2. when for some odd reason the sample value equalled 0, this triggered a bug warning about "bogus Ack", due to the ambiguity of the return value; 3. on a passive host which has not sent anything the TX history is empty and thus will lead to unwanted "bogus Ack" warnings such as ccid3_hc_tx_packet_recv: server(e7b7d518): DATAACK with bogus ACK-28197148 ccid3_hc_tx_packet_recv: server(e7b7d518): DATAACK with bogus ACK-26641606. The fix is to replace the implicit encoding by performing the steps manually. Furthermore, the "bogus Ack" warning has been removed, since it can actually be triggered due to several reasons (network reordering, old packet, (3) above), hence it is not very useful. Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 34 ++++++++++++++++++-------------- net/dccp/ccids/lib/packet_history.c | 39 ------------------------------------- net/dccp/ccids/lib/packet_history.h | 22 ++++++++++++++++++--- 3 files changed, 38 insertions(+), 57 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index e9ca0983ac58..b2ddd205d438 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -370,6 +370,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); struct ccid3_options_received *opt_recv = &hc->tx_options_received; + struct tfrc_tx_hist_entry *acked; ktime_t now; unsigned long t_nfb; u32 pinv, r_sample; @@ -383,17 +384,24 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_state != TFRC_SSTATE_NO_FBACK) return; - now = ktime_get_real(); - - /* Estimate RTT from history if ACK number is valid */ - r_sample = tfrc_tx_hist_rtt(hc->tx_hist, - DCCP_SKB_CB(skb)->dccpd_ack_seq, now); - if (r_sample == 0) { - DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, - dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), - (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); + /* + * Locate the acknowledged packet in the TX history. + * + * Returning "entry not found" here can for instance happen when + * - the host has not sent out anything (e.g. a passive server), + * - the Ack is outdated (packet with higher Ack number was received), + * - it is a bogus Ack (for a packet not sent on this connection). + */ + acked = tfrc_tx_hist_find_entry(hc->tx_hist, dccp_hdr_ack_seq(skb)); + if (acked == NULL) return; - } + /* For the sake of RTT sampling, ignore/remove all older entries */ + tfrc_tx_hist_purge(&acked->next); + + /* Update the moving average for the RTT estimate (RFC 3448, 4.3) */ + now = ktime_get_real(); + r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp)); + hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9); /* Update receive rate in units of 64 * bytes/second */ hc->tx_x_recv = opt_recv->ccid3or_receive_rate; @@ -405,11 +413,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_p = 0; else /* can not exceed 100% */ hc->tx_p = scaled_div(1, pinv); - /* - * Validate new RTT sample and update moving average - */ - r_sample = dccp_sample_rtt(sk, r_sample); - hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9); + /* * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 */ diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index 3a4f414e94a0..de8fe294bf0b 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c @@ -38,18 +38,6 @@ #include "packet_history.h" #include "../../dccp.h" -/** - * tfrc_tx_hist_entry - Simple singly-linked TX history list - * @next: next oldest entry (LIFO order) - * @seqno: sequence number of this entry - * @stamp: send time of packet with sequence number @seqno - */ -struct tfrc_tx_hist_entry { - struct tfrc_tx_hist_entry *next; - u64 seqno; - ktime_t stamp; -}; - /* * Transmitter History Routines */ @@ -71,15 +59,6 @@ void tfrc_tx_packet_history_exit(void) } } -static struct tfrc_tx_hist_entry * - tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) -{ - while (head != NULL && head->seqno != seqno) - head = head->next; - - return head; -} - int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) { struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any()); @@ -107,24 +86,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp) *headp = NULL; } -u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno, - const ktime_t now) -{ - u32 rtt = 0; - struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno); - - if (packet != NULL) { - rtt = ktime_us_delta(now, packet->stamp); - /* - * Garbage-collect older (irrelevant) entries: - */ - tfrc_tx_hist_purge(&packet->next); - } - - return rtt; -} - - /* * Receiver History Routines */ diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h index 7df6c5299999..7ee4a9d9d335 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h @@ -40,12 +40,28 @@ #include #include "tfrc.h" -struct tfrc_tx_hist_entry; +/** + * tfrc_tx_hist_entry - Simple singly-linked TX history list + * @next: next oldest entry (LIFO order) + * @seqno: sequence number of this entry + * @stamp: send time of packet with sequence number @seqno + */ +struct tfrc_tx_hist_entry { + struct tfrc_tx_hist_entry *next; + u64 seqno; + ktime_t stamp; +}; + +static inline struct tfrc_tx_hist_entry * + tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) +{ + while (head != NULL && head->seqno != seqno) + head = head->next; + return head; +} extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); -extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, - const u64 seqno, const ktime_t now); /* Subtraction a-b modulo-16, respects circular wrap-around */ #define SUB16(a, b) (((a) + 16 - (b)) & 0xF) -- cgit v1.2.3 From 37efb03fbd0935f5f85a0538c46b53be5cf40504 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 14 Sep 2010 20:21:29 +0200 Subject: dccp ccid-3: Simplify and consolidate tx_parse_options This simplifies and consolidates the TX option-parsing code: 1. The Loss Intervals option is not currently used, so dead code related to this option is removed. I am aware of no plans to support the option, but if someone wants to implement it (e.g. for inter-op tests), it is better to start afresh than having to also update currently unused code. 2. The Loss Event and Receive Rate options have a lot of code in common (both are 32 bit, both have same length etc.), so this is consolidated. 3. The test against GSR is not necessary, because - on first loading CCID3, ccid_new() zeroes out all fields in the socket; - ccid3_hc_tx_packet_recv() treats 0 and ~0U equivalently, due to pinv = opt_recv->ccid3or_loss_event_rate; if (pinv == ~0U || pinv == 0) hctx->p = 0; - as a result, the sequence number field is removed from opt_recv. Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 57 +++++++++++++------------------------------------- net/dccp/ccids/ccid3.h | 3 --- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index b2ddd205d438..ce8059130070 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -485,60 +485,31 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, unsigned char len, u16 idx, unsigned char *value) { - int rc = 0; - const struct dccp_sock *dp = dccp_sk(sk); struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); struct ccid3_options_received *opt_recv = &hc->tx_options_received; __be32 opt_val; - if (opt_recv->ccid3or_seqno != dp->dccps_gsr) { - opt_recv->ccid3or_seqno = dp->dccps_gsr; - opt_recv->ccid3or_loss_event_rate = ~0; - opt_recv->ccid3or_loss_intervals_idx = 0; - opt_recv->ccid3or_loss_intervals_len = 0; - opt_recv->ccid3or_receive_rate = 0; - } - switch (option) { + case TFRC_OPT_RECEIVE_RATE: case TFRC_OPT_LOSS_EVENT_RATE: if (unlikely(len != 4)) { - DCCP_WARN("%s(%p), invalid len %d " - "for TFRC_OPT_LOSS_EVENT_RATE\n", - dccp_role(sk), sk, len); - rc = -EINVAL; - } else { - opt_val = get_unaligned((__be32 *)value); - opt_recv->ccid3or_loss_event_rate = ntohl(opt_val); - ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", - dccp_role(sk), sk, - opt_recv->ccid3or_loss_event_rate); + DCCP_WARN("%s(%p), invalid len %d for %u\n", + dccp_role(sk), sk, len, option); + return -EINVAL; } - break; - case TFRC_OPT_LOSS_INTERVALS: - opt_recv->ccid3or_loss_intervals_idx = idx; - opt_recv->ccid3or_loss_intervals_len = len; - ccid3_pr_debug("%s(%p), LOSS_INTERVALS=(%u, %u)\n", - dccp_role(sk), sk, - opt_recv->ccid3or_loss_intervals_idx, - opt_recv->ccid3or_loss_intervals_len); - break; - case TFRC_OPT_RECEIVE_RATE: - if (unlikely(len != 4)) { - DCCP_WARN("%s(%p), invalid len %d " - "for TFRC_OPT_RECEIVE_RATE\n", - dccp_role(sk), sk, len); - rc = -EINVAL; - } else { - opt_val = get_unaligned((__be32 *)value); - opt_recv->ccid3or_receive_rate = ntohl(opt_val); + opt_val = ntohl(get_unaligned((__be32 *)value)); + + if (option == TFRC_OPT_RECEIVE_RATE) { + opt_recv->ccid3or_receive_rate = opt_val; ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", - dccp_role(sk), sk, - opt_recv->ccid3or_receive_rate); + dccp_role(sk), sk, opt_val); + } else { + opt_recv->ccid3or_loss_event_rate = opt_val; + ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", + dccp_role(sk), sk, opt_val); } - break; } - - return rc; + return 0; } static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 4a00174a97dd..9eb90b863abd 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -68,9 +68,6 @@ enum ccid3_options { }; struct ccid3_options_received { - u64 ccid3or_seqno:48, - ccid3or_loss_intervals_idx:16; - u16 ccid3or_loss_intervals_len; u32 ccid3or_loss_event_rate; u32 ccid3or_receive_rate; }; -- cgit v1.2.3 From 0abee5260babe0a12d468b485a28336551697925 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 15 Sep 2010 19:24:50 +0200 Subject: netfilter: nf_nat: add nf_nat_csum() Add a static function nf_nat_csum() to replace the duplicate code in nf_nat_mangle_udp_packet() and __nf_nat_mangle_tcp_packet(). Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/nf_nat_helper.c | 76 ++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 4a0c6b548eee..31427fb57aa8 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c @@ -153,6 +153,35 @@ void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo, } EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust); +static void nf_nat_csum(struct sk_buff *skb, struct iphdr *iph, void *data, + int datalen, __sum16 *check, int oldlen) +{ + struct rtable *rt = skb_rtable(skb); + + if (skb->ip_summed != CHECKSUM_PARTIAL) { + if (!(rt->rt_flags & RTCF_LOCAL) && + skb->dev->features & NETIF_F_V4_CSUM) { + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = skb_headroom(skb) + + skb_network_offset(skb) + + iph->ihl * 4; + skb->csum_offset = (void *)check - data; + *check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + datalen, iph->protocol, 0); + } else { + *check = 0; + *check = csum_tcpudp_magic(iph->saddr, iph->daddr, + datalen, iph->protocol, + csum_partial(data, datalen, + 0)); + if (iph->protocol == IPPROTO_UDP && !*check) + *check = CSUM_MANGLED_0; + } + } else + inet_proto_csum_replace2(check, skb, + htons(oldlen), htons(datalen), 1); +} + /* Generic function for mangling variable-length address changes inside * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX * command in FTP). @@ -169,7 +198,6 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len, bool adjust) { - struct rtable *rt = skb_rtable(skb); struct iphdr *iph; struct tcphdr *tcph; int oldlen, datalen; @@ -192,26 +220,7 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, match_offset, match_len, rep_buffer, rep_len); datalen = skb->len - iph->ihl*4; - if (skb->ip_summed != CHECKSUM_PARTIAL) { - if (!(rt->rt_flags & RTCF_LOCAL) && - skb->dev->features & NETIF_F_V4_CSUM) { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_headroom(skb) + - skb_network_offset(skb) + - iph->ihl * 4; - skb->csum_offset = offsetof(struct tcphdr, check); - tcph->check = ~tcp_v4_check(datalen, - iph->saddr, iph->daddr, 0); - } else { - tcph->check = 0; - tcph->check = tcp_v4_check(datalen, - iph->saddr, iph->daddr, - csum_partial(tcph, - datalen, 0)); - } - } else - inet_proto_csum_replace2(&tcph->check, skb, - htons(oldlen), htons(datalen), 1); + nf_nat_csum(skb, iph, tcph, datalen, &tcph->check, oldlen); if (adjust && rep_len != match_len) nf_nat_set_seq_adjust(ct, ctinfo, tcph->seq, @@ -240,7 +249,6 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len) { - struct rtable *rt = skb_rtable(skb); struct iphdr *iph; struct udphdr *udph; int datalen, oldlen; @@ -274,29 +282,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL) return 1; - if (skb->ip_summed != CHECKSUM_PARTIAL) { - if (!(rt->rt_flags & RTCF_LOCAL) && - skb->dev->features & NETIF_F_V4_CSUM) { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_headroom(skb) + - skb_network_offset(skb) + - iph->ihl * 4; - skb->csum_offset = offsetof(struct udphdr, check); - udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, - datalen, IPPROTO_UDP, - 0); - } else { - udph->check = 0; - udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, - datalen, IPPROTO_UDP, - csum_partial(udph, - datalen, 0)); - if (!udph->check) - udph->check = CSUM_MANGLED_0; - } - } else - inet_proto_csum_replace2(&udph->check, skb, - htons(oldlen), htons(datalen), 1); + nf_nat_csum(skb, iph, udph, datalen, &udph->check, oldlen); return 1; } -- cgit v1.2.3 From 41a8a7ee4a78216962f3afcea5968c04d0ab3b08 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:53 +0000 Subject: tg3: Fix read DMA FIFO overruns on recent devices Earlier versions of tg3 devices had a problem where the read DMA FIFO could be overrun in certain edge conditions. The fix was to limit the number of rx BDs the hardware would fetch at a time. For later devices (5761, 5784 and later ASIC revs), there is a hardware fix that must be enabled to fix the same problem. This patch adds that hardware fix. There is a gap in the ASIC revision lineage where neither fix is applied. This is intentional as these ASIC revisions are not afflicted by the bug. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 10 ++++++++++ drivers/net/tg3.h | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9f6ffffc8376..c3a430cfbe00 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8015,6 +8015,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || + (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + val = tr32(TG3_RDMA_RSRVCTRL_REG); + tw32(TG3_RDMA_RSRVCTRL_REG, + val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); + } + /* Receive/send statistics. */ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { val = tr32(RCVLPC_STATS_ENABLE); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4937bd190964..783cd77b6165 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1302,7 +1302,11 @@ #define RDMAC_STATUS_FIFOURUN 0x00000080 #define RDMAC_STATUS_FIFOOREAD 0x00000100 #define RDMAC_STATUS_LNGREAD 0x00000200 -/* 0x4808 --> 0x4c00 unused */ +/* 0x4808 --> 0x4900 unused */ + +#define TG3_RDMA_RSRVCTRL_REG 0x00004900 +#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 +/* 0x4904 --> 0x4c00 unused */ /* Write DMA control registers */ #define WDMAC_MODE 0x00004c00 -- cgit v1.2.3 From f0392d24485e4c144d2741a5424f069b8b5f30e7 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:54 +0000 Subject: tg3: Disable TSS It was recently discovered that enabling TSS can lockup the device. This patch disables the feature until a suitable workaround can be found. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c3a430cfbe00..38f1b19b776b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8827,16 +8827,9 @@ static bool tg3_enable_msix(struct tg3 *tp) tp->napi[i].irq_vec = msix_ent[i].vector; tp->dev->real_num_tx_queues = 1; - if (tp->irq_cnt > 1) { + if (tp->irq_cnt > 1) tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; - tp->dev->real_num_tx_queues = tp->irq_cnt - 1; - } - } - return true; } -- cgit v1.2.3 From dc6d074457f1551f9357f773a4eda09a3d5ef150 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:55 +0000 Subject: tg3: Don't send APE events for NCSI firmware NCSI firmware does not accept APE events. It relies on a "driver state" location in shared memory to tell it what the driver's current state is. This patch pivots the code to use the new driver state scheme. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 22 ++++++++++++++++++++-- drivers/net/tg3.h | 9 ++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 38f1b19b776b..fc9706c8e3c6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6596,6 +6596,10 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event) int i; u32 apedata; + /* NCSI does not support APE events */ + if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI) + return; + apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) return; @@ -6647,6 +6651,8 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM)); tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR, APE_HOST_BEHAV_NO_PHYLOCK); + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, + TG3_APE_HOST_DRVR_STATE_START); event = APE_EVENT_STATUS_STATE_START; break; @@ -6658,6 +6664,16 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) */ tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); + if (device_may_wakeup(&tp->pdev->dev) && + (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { + tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, + TG3_APE_HOST_WOL_SPEED_AUTO); + apedata = TG3_APE_HOST_DRVR_STATE_WOL; + } else + apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD; + + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata); + event = APE_EVENT_STATUS_STATE_UNLOAD; break; case RESET_KIND_SUSPEND: @@ -12739,10 +12755,12 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); - if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) + if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) { + tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI; fwtype = "NCSI"; - else + } else { fwtype = "DASH"; + } vlen = strlen(tp->fw_ver); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 783cd77b6165..5cd0653d6caf 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2180,7 +2180,7 @@ #define TG3_APE_HOST_SEG_SIG 0x4200 #define APE_HOST_SEG_SIG_MAGIC 0x484f5354 #define TG3_APE_HOST_SEG_LEN 0x4204 -#define APE_HOST_SEG_LEN_MAGIC 0x0000001c +#define APE_HOST_SEG_LEN_MAGIC 0x00000020 #define TG3_APE_HOST_INIT_COUNT 0x4208 #define TG3_APE_HOST_DRIVER_ID 0x420c #define APE_HOST_DRIVER_ID_LINUX 0xf0000000 @@ -2192,6 +2192,12 @@ #define APE_HOST_HEARTBEAT_INT_DISABLE 0 #define APE_HOST_HEARTBEAT_INT_5SEC 5000 #define TG3_APE_HOST_HEARTBEAT_COUNT 0x4218 +#define TG3_APE_HOST_DRVR_STATE 0x421c +#define TG3_APE_HOST_DRVR_STATE_START 0x00000001 +#define TG3_APE_HOST_DRVR_STATE_UNLOAD 0x00000002 +#define TG3_APE_HOST_DRVR_STATE_WOL 0x00000003 +#define TG3_APE_HOST_WOL_SPEED 0x4224 +#define TG3_APE_HOST_WOL_SPEED_AUTO 0x00008000 #define TG3_APE_EVENT_STATUS 0x4300 @@ -2854,6 +2860,7 @@ struct tg3 { #define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000 #define TG3_FLG3_L1PLLPD_EN 0x00800000 #define TG3_FLG3_5717_PLUS 0x01000000 +#define TG3_FLG3_APE_HAS_NCSI 0x02000000 struct timer_list timer; u16 timer_counter; -- cgit v1.2.3 From 2e9f7a7408d264f01d4477c564ef5c6b610cd10f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:56 +0000 Subject: tg3: Unlock 5717 B0+ support This patch adjusts the driver to use the tg3_start_xmit_dma_bug() transmit routine for all revisions of 5717 asic rev devices and then allows the driver to attach to B0 and later devices. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index fc9706c8e3c6..4e92b81bccfa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13431,10 +13431,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (err) return err; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && - tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) - return -ENOTSUPP; - /* Initialize data/descriptor byte/word swapping. */ val = tr32(GRC_MODE); val &= GRC_MODE_HOST_STACKUP; @@ -14463,7 +14459,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) && - tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) dev->netdev_ops = &tg3_netdev_ops; else -- cgit v1.2.3 From 6fd45cb814709767a1704b541aa91647b7f275cf Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:57 +0000 Subject: tg3: Clarify semantics of TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS should be seen as the maximum number of vectors that any device could be expected to use. tp->irq_max represents the maximum number of vectors the current device can use. This patch clarifies the semantics of the code to match the above description. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 +++--- drivers/net/tg3.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4e92b81bccfa..7468479902ae 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7564,7 +7564,7 @@ static void tg3_rings_reset(struct tg3 *tp) /* Zero mailbox registers. */ if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) { - for (i = 1; i < TG3_IRQ_MAX_VECS; i++) { + for (i = 1; i < tp->irq_max; i++) { tp->napi[i].tx_prod = 0; tp->napi[i].tx_cons = 0; if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) @@ -9886,7 +9886,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e tp->rx_pending = 63; tp->rx_jumbo_pending = ering->rx_jumbo_pending; - for (i = 0; i < TG3_IRQ_MAX_VECS; i++) + for (i = 0; i < tp->irq_max; i++) tp->napi[i].tx_pending = ering->tx_pending; if (netif_running(dev)) { @@ -14598,7 +14598,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; - for (i = 0; i < TG3_IRQ_MAX_VECS; i++) { + for (i = 0; i < tp->irq_max; i++) { struct tg3_napi *tnapi = &tp->napi[i]; tnapi->tp = tp; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 5cd0653d6caf..d39426fc8a6e 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2659,7 +2659,8 @@ struct tg3_rx_prodring_set { dma_addr_t rx_jmb_mapping; }; -#define TG3_IRQ_MAX_VECS 5 +#define TG3_IRQ_MAX_VECS_RSS 5 +#define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS struct tg3_napi { struct napi_struct napi ____cacheline_aligned; -- cgit v1.2.3 From 8fea32b9555726d35b91492d17fc21c7874d36f9 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:58 +0000 Subject: tg3: Move producer ring struct to tg3_napi Now that each NAPI instance has its own producer ring, it no longer makes sense to keep the producer ring structure external. This patch migrates the producer ring struct to tg3_napi and pivots the code to the new implementation. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 39 +++++++++++++++++---------------------- drivers/net/tg3.h | 4 +--- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7468479902ae..179eb6539bd0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4549,7 +4549,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, struct tg3 *tp = tnapi->tp; struct tg3_rx_buffer_desc *src_desc, *dest_desc; struct ring_info *src_map, *dest_map; - struct tg3_rx_prodring_set *spr = &tp->prodring[0]; + struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring; int dest_idx; switch (opaque_key) { @@ -4619,7 +4619,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) u32 sw_idx = tnapi->rx_rcb_ptr; u16 hw_idx; int received; - struct tg3_rx_prodring_set *tpr = tnapi->prodring; + struct tg3_rx_prodring_set *tpr = &tnapi->prodring; hw_idx = *(tnapi->rx_rcb_prod_idx); /* @@ -4644,13 +4644,13 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; if (opaque_key == RXD_OPAQUE_RING_STD) { - ri = &tp->prodring[0].rx_std_buffers[desc_idx]; + ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx]; dma_addr = dma_unmap_addr(ri, mapping); skb = ri->skb; post_ptr = &std_prod_idx; rx_std_posted++; } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { - ri = &tp->prodring[0].rx_jmb_buffers[desc_idx]; + ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx]; dma_addr = dma_unmap_addr(ri, mapping); skb = ri->skb; post_ptr = &jmb_prod_idx; @@ -4981,14 +4981,14 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) work_done += tg3_rx(tnapi, budget - work_done); if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) { - struct tg3_rx_prodring_set *dpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring; int i, err = 0; u32 std_prod_idx = dpr->rx_std_prod_idx; u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; for (i = 1; i < tp->irq_cnt; i++) err |= tg3_rx_prodring_xfer(tp, dpr, - tp->napi[i].prodring); + &tp->napi[i].prodring); wmb(); @@ -6057,7 +6057,7 @@ static void tg3_rx_prodring_free(struct tg3 *tp, { int i; - if (tpr != &tp->prodring[0]) { + if (tpr != &tp->napi[0].prodring) { for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; i = (i + 1) % TG3_RX_RING_SIZE) tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], @@ -6103,7 +6103,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, tpr->rx_jmb_cons_idx = 0; tpr->rx_jmb_prod_idx = 0; - if (tpr != &tp->prodring[0]) { + if (tpr != &tp->napi[0].prodring) { memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE); if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) memset(&tpr->rx_jmb_buffers[0], 0, @@ -6253,7 +6253,7 @@ static void tg3_free_rings(struct tg3 *tp) for (j = 0; j < tp->irq_cnt; j++) { struct tg3_napi *tnapi = &tp->napi[j]; - tg3_rx_prodring_free(tp, &tp->prodring[j]); + tg3_rx_prodring_free(tp, &tnapi->prodring); if (!tnapi->tx_buffers) continue; @@ -6325,7 +6325,7 @@ static int tg3_init_rings(struct tg3 *tp) if (tnapi->rx_rcb) memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); - if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) { + if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) { tg3_free_rings(tp); return -ENOMEM; } @@ -6361,6 +6361,8 @@ static void tg3_free_consistent(struct tg3 *tp) tnapi->rx_rcb = NULL; } + tg3_rx_prodring_fini(tp, &tnapi->prodring); + if (tnapi->hw_status) { pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE, tnapi->hw_status, @@ -6374,9 +6376,6 @@ static void tg3_free_consistent(struct tg3 *tp) tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } - - for (i = 0; i < tp->irq_cnt; i++) - tg3_rx_prodring_fini(tp, &tp->prodring[i]); } /* @@ -6387,11 +6386,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) { int i; - for (i = 0; i < tp->irq_cnt; i++) { - if (tg3_rx_prodring_init(tp, &tp->prodring[i])) - goto err_out; - } - tp->hw_stats = pci_alloc_consistent(tp->pdev, sizeof(struct tg3_hw_stats), &tp->stats_mapping); @@ -6413,6 +6407,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); sblk = tnapi->hw_status; + if (tg3_rx_prodring_init(tp, &tnapi->prodring)) + goto err_out; + /* If multivector TSS is enabled, vector 0 does not handle * tx interrupts. Don't allocate any resources for it. */ @@ -6452,8 +6449,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) break; } - tnapi->prodring = &tp->prodring[i]; - /* * If multivector RSS is enabled, vector 0 does not handle * rx or tx interrupts. Don't allocate any resources for it. @@ -7647,7 +7642,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) { u32 val, rdmac_mode; int i, err, limit; - struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; tg3_disable_ints(tp); @@ -10627,7 +10622,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) int num_pkts, tx_len, rx_len, i, err; struct tg3_rx_buffer_desc *desc; struct tg3_napi *tnapi, *rnapi; - struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; tnapi = &tp->napi[0]; rnapi = &tp->napi[0]; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index d39426fc8a6e..44733e4a68a2 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2679,7 +2679,7 @@ struct tg3_napi { u32 consmbox; u32 rx_rcb_ptr; u16 *rx_rcb_prod_idx; - struct tg3_rx_prodring_set *prodring; + struct tg3_rx_prodring_set prodring; struct tg3_rx_buffer_desc *rx_rcb; struct tg3_tx_buffer_desc *tx_ring; @@ -2766,8 +2766,6 @@ struct tg3 { struct vlan_group *vlgrp; #endif - struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS]; - /* begin "everything else" cacheline(s) section */ struct rtnl_link_stats64 net_stats; -- cgit v1.2.3 From 02e96080af2b70313f2ffc8c1b03ae2f9d8c65ac Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 08:59:59 +0000 Subject: tg3: Use skb_is_gso_v6() This patch converts the driver to prefer the skb_is_gso_v6() helper over the explicit inlined version. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 179eb6539bd0..a4fbe4f85ffe 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5574,9 +5574,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, goto out_unlock; } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso_v6(skb)) { hdrlen = skb_headlen(skb) - ETH_HLEN; - else { + } else { struct iphdr *iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); @@ -5798,7 +5798,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { + if (skb_is_gso_v6(skb)) { hdr_len = skb_headlen(skb) - ETH_HLEN; } else { u32 ip_tcp_len; -- cgit v1.2.3 From a4a8bb15aed20ff74aa3ca14a4f2c0d62efd8391 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 09:00:00 +0000 Subject: tg3: Dynamically allocate VPD data memory This patch eases stack pressure by dynamically allocating the memory used to temporarily store VPD data. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a4fbe4f85ffe..0d0deaae5f4c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12415,14 +12415,18 @@ skip_phy_reset: static void __devinit tg3_read_vpd(struct tg3 *tp) { - u8 vpd_data[TG3_NVM_VPD_LEN]; + u8 *vpd_data; unsigned int block_end, rosize, len; int j, i = 0; u32 magic; if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || tg3_nvram_read(tp, 0x0, &magic)) - goto out_not_found; + goto out_no_vpd; + + vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL); + if (!vpd_data) + goto out_no_vpd; if (magic == TG3_EEPROM_MAGIC) { for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) { @@ -12506,9 +12510,12 @@ partno: memcpy(tp->board_part_number, &vpd_data[i], len); - return; - out_not_found: + kfree(vpd_data); + if (!tp->board_part_number[0]) + return; + +out_no_vpd: if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) strcpy(tp->board_part_number, "BCM95906"); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && -- cgit v1.2.3 From f833c4c181e4e948758b7b252322f50273100d30 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 15 Sep 2010 09:00:01 +0000 Subject: tg3: phy tmp variable roundup The tg3's phy routines define temporary variables in many locations within the same routine. This patch unifies all temporary variables into one location. Reviewed-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0d0deaae5f4c..e7a2ba8b20a2 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1917,19 +1917,16 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) */ static int tg3_phy_reset(struct tg3 *tp) { - u32 cpmuctrl; - u32 phy_status; + u32 val, cpmuctrl; int err; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - u32 val; - val = tr32(GRC_MISC_CFG); tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); udelay(40); } - err = tg3_readphy(tp, MII_BMSR, &phy_status); - err |= tg3_readphy(tp, MII_BMSR, &phy_status); + err = tg3_readphy(tp, MII_BMSR, &val); + err |= tg3_readphy(tp, MII_BMSR, &val); if (err != 0) return -EBUSY; @@ -1961,18 +1958,14 @@ static int tg3_phy_reset(struct tg3 *tp) return err; if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) { - u32 phy; - - phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz; - tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy); + val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz; + tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val); tw32(TG3_CPMU_CTRL, cpmuctrl); } if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX || GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) { - u32 val; - val = tr32(TG3_CPMU_LSPD_1000MB_CLK); if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) == CPMU_LSPD_1000MB_MACCLK_12_5) { @@ -2028,23 +2021,19 @@ out: /* Cannot do read-modify-write on 5401 */ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); } else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - u32 phy_reg; - /* Set bit 14 with read-modify-write to preserve other bits */ if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) && - !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg)) - tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); + !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val)) + tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000); } /* Set phy register 0x10 bit 0 to high fifo elasticity to support * jumbo frames transmission. */ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - u32 phy_reg; - - if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg)) + if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val)) tg3_writephy(tp, MII_TG3_EXT_CTRL, - phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC); + val | MII_TG3_EXT_CTRL_FIFO_ELASTIC); } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { @@ -3060,7 +3049,7 @@ static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv) static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) { int current_link_up; - u32 bmsr, dummy; + u32 bmsr, val; u32 lcl_adv, rmt_adv; u16 current_speed; u8 current_duplex; @@ -3140,8 +3129,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) } /* Clear pending interrupts... */ - tg3_readphy(tp, MII_TG3_ISTAT, &dummy); - tg3_readphy(tp, MII_TG3_ISTAT, &dummy); + tg3_readphy(tp, MII_TG3_ISTAT, &val); + tg3_readphy(tp, MII_TG3_ISTAT, &val); if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); @@ -3162,8 +3151,6 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) current_duplex = DUPLEX_INVALID; if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { - u32 val; - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007); tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); if (!(val & (1 << 10))) { @@ -3238,13 +3225,11 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) relink: if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { - u32 tmp; - tg3_phy_copper_begin(tp); - tg3_readphy(tp, MII_BMSR, &tmp); - if (!tg3_readphy(tp, MII_BMSR, &tmp) && - (tmp & BMSR_LSTATUS)) + tg3_readphy(tp, MII_BMSR, &bmsr); + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + (bmsr & BMSR_LSTATUS)) current_link_up = 1; } -- cgit v1.2.3 From e035587305011432ee07f69f9738b3c7ef7f3684 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 14 Sep 2010 09:10:03 +0000 Subject: ethtool: Complete kernel-doc comments for RX flow filter and hash control There are now several interfaces within the ethtool API for getting and setting RX flow filtering and hashing behaviour, most of which are poorly documented. This adds kernel-doc comments for all these interfaces, based on the existing incomplete comments and on the initial implementations. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 129 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 16 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 991269e5b152..4b3ba05b11a8 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -314,9 +314,20 @@ enum ethtool_flags { }; /* The following structures are for supporting RX network flow - * classification configuration. Note, all multibyte fields, e.g., - * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network - * byte order. + * classification and RX n-tuple configuration. Note, all multibyte + * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to + * be in network byte order. + */ + +/** + * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc. + * @ip4src: Source host + * @ip4dst: Destination host + * @psrc: Source port + * @pdst: Destination port + * @tos: Type-of-service + * + * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow. */ struct ethtool_tcpip4_spec { __be32 ip4src; @@ -326,6 +337,15 @@ struct ethtool_tcpip4_spec { __u8 tos; }; +/** + * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @spi: Security parameters index + * @tos: Type-of-service + * + * This can be used to specify an IPsec transport or tunnel over IPv4. + */ struct ethtool_ah_espip4_spec { __be32 ip4src; __be32 ip4dst; @@ -348,6 +368,15 @@ struct ethtool_ether_spec { #define ETH_RX_NFC_IP4 1 #define ETH_RX_NFC_IP6 2 +/** + * struct ethtool_usrip4_spec - general flow specification for IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @l4_4_bytes: First 4 bytes of transport (layer 4) header + * @tos: Type-of-service + * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0 + * @proto: Transport protocol number; mask must be 0 + */ struct ethtool_usrip4_spec { __be32 ip4src; __be32 ip4dst; @@ -357,6 +386,15 @@ struct ethtool_usrip4_spec { __u8 proto; }; +/** + * struct ethtool_rx_flow_spec - specification for RX flow filter + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow fields to match (dependent on @flow_type) + * @m_u: Masks for flow field bits to be ignored + * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC + * if packets should be discarded + * @location: Index of filter in hardware table + */ struct ethtool_rx_flow_spec { __u32 flow_type; union { @@ -369,32 +407,87 @@ struct ethtool_rx_flow_spec { struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; __u8 hdata[64]; - } h_u, m_u; /* entry, mask */ + } h_u, m_u; __u64 ring_cookie; __u32 location; }; +/** + * struct ethtool_rxnfc - command to get or set RX flow classification rules + * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH, + * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE, + * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS + * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW + * @data: Command-dependent value + * @fs: Flow filter specification + * @rule_cnt: Number of rules to be affected + * @rule_locs: Array of valid rule indices + * + * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating + * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following + * structure fields must not be used. + * + * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues + * on return. + * + * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined + * rules on return. + * + * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the index of an + * existing filter rule on entry and @fs contains the rule on return. + * + * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the + * user buffer for @rule_locs on entry. On return, @data is the size + * of the filter table and @rule_locs contains the indices of the + * defined rules. + * + * For %ETHTOOL_SRXCLSRLINS, @fs specifies the filter rule to add or + * update. @fs.@location specifies the index to use and must not be + * ignored. + * + * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the index of an + * existing filter rule on entry. + * + * Implementation of indexed classification rules generally requires a + * TCAM. + */ struct ethtool_rxnfc { __u32 cmd; __u32 flow_type; - /* The rx flow hash value or the rule DB size */ __u64 data; - /* The following fields are not valid and must not be used for - * the ETHTOOL_{G,X}RXFH commands. */ struct ethtool_rx_flow_spec fs; __u32 rule_cnt; __u32 rule_locs[0]; }; +/** + * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection + * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR + * @size: On entry, the array size of the user buffer. On return from + * %ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table. + * @ring_index: RX ring/queue index for each hash value + */ struct ethtool_rxfh_indir { __u32 cmd; - /* On entry, this is the array size of the user buffer. On - * return from ETHTOOL_GRXFHINDIR, this is the array size of - * the hardware indirection table. */ __u32 size; - __u32 ring_index[0]; /* ring/queue index for each hash value */ + __u32 ring_index[0]; }; +/** + * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow field values to match (dependent on @flow_type) + * @m_u: Masks for flow field value bits to be ignored + * @vlan_tag: VLAN tag to match + * @vlan_tag_mask: Mask for VLAN tag bits to be ignored + * @data: Driver-dependent data to match + * @data_mask: Mask for driver-dependent data bits to be ignored + * @action: RX ring/queue index to deliver to (non-negative) or other action + * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP) + * + * Zero values in @h_u may be ignored, as if all the corresponding + * mask bits were set. + */ struct ethtool_rx_ntuple_flow_spec { __u32 flow_type; union { @@ -407,18 +500,22 @@ struct ethtool_rx_ntuple_flow_spec { struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; __u8 hdata[64]; - } h_u, m_u; /* entry, mask */ + } h_u, m_u; __u16 vlan_tag; __u16 vlan_tag_mask; - __u64 data; /* user-defined flow spec data */ - __u64 data_mask; /* user-defined flow spec mask */ + __u64 data; + __u64 data_mask; - /* signed to distinguish between queue and actions (DROP) */ __s32 action; -#define ETHTOOL_RXNTUPLE_ACTION_DROP -1 +#define ETHTOOL_RXNTUPLE_ACTION_DROP -1 /* drop packet */ }; +/** + * struct ethtool_rx_ntuple - command to set RX flow filter + * @cmd: Command number - %ETHTOOL_SRXNTUPLE + * @fs: Flow filter specification + */ struct ethtool_rx_ntuple { __u32 cmd; struct ethtool_rx_ntuple_flow_spec fs; -- cgit v1.2.3 From e0de7c93b950b9e784894efc4b529c6958cb747a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 14 Sep 2010 09:13:08 +0000 Subject: ethtool: Remove unimplemented flow specification types struct ethtool_rawip4_spec and struct ethtool_ether_spec are neither commented nor used by any driver, so remove them. Adjust padding in the user-visible unions that included these structures. Fix references to struct ethtool_rawip4_spec in ethtool_get_rx_ntuple(), which should use struct ethtool_usrip4_spec. struct ethtool_usrip4_spec cannot hold IPv6 host addresses and there is no separate structure that can, so remove ETH_RX_NFC_IP6 and the reference to it in niu. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/niu.c | 19 +++++-------------- include/linux/ethtool.h | 21 ++------------------- net/core/ethtool.c | 8 ++++---- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 8e1859c801a4..e36a83845a1c 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7462,10 +7462,12 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, if (fsp->flow_type == IP_USER_FLOW) { int i; int add_usr_cls = 0; - int ipv6 = 0; struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec; struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec; + if (uspec->ip_ver != ETH_RX_NFC_IP4) + return -EINVAL; + niu_lock_parent(np, flags); for (i = 0; i < NIU_L3_PROG_CLS; i++) { @@ -7494,9 +7496,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, default: break; } - if (uspec->ip_ver == ETH_RX_NFC_IP6) - ipv6 = 1; - ret = tcam_user_ip_class_set(np, class, ipv6, + ret = tcam_user_ip_class_set(np, class, 0, uspec->proto, uspec->tos, umask->tos); @@ -7553,16 +7553,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, ret = -EINVAL; goto out; case IP_USER_FLOW: - if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) { - niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, - class); - } else { - /* Not yet implemented */ - netdev_info(np->dev, "niu%d: In %s(): usr flow for IPv6 not implemented\n", - parent->index, __func__); - ret = -EINVAL; - goto out; - } + niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class); break; default: netdev_info(np->dev, "niu%d: In %s(): Unknown flow type %d\n", diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 4b3ba05b11a8..d64e246a39e7 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -353,20 +353,7 @@ struct ethtool_ah_espip4_spec { __u8 tos; }; -struct ethtool_rawip4_spec { - __be32 ip4src; - __be32 ip4dst; - __u8 hdata[64]; -}; - -struct ethtool_ether_spec { - __be16 ether_type; - __u8 frame_size; - __u8 eframe[16]; -}; - #define ETH_RX_NFC_IP4 1 -#define ETH_RX_NFC_IP6 2 /** * struct ethtool_usrip4_spec - general flow specification for IPv4 @@ -403,10 +390,8 @@ struct ethtool_rx_flow_spec { struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_rawip4_spec raw_ip4_spec; - struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; - __u8 hdata[64]; + __u8 hdata[72]; } h_u, m_u; __u64 ring_cookie; __u32 location; @@ -496,10 +481,8 @@ struct ethtool_rx_ntuple_flow_spec { struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_rawip4_spec raw_ip4_spec; - struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; - __u8 hdata[64]; + __u8 hdata[72]; } h_u, m_u; __u16 vlan_tag; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 970eb9817bbc..fcd62757704d 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -673,19 +673,19 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) break; case IP_USER_FLOW: sprintf(p, "\tSrc IP addr: 0x%x\n", - fsc->fs.h_u.raw_ip4_spec.ip4src); + fsc->fs.h_u.usr_ip4_spec.ip4src); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tSrc IP mask: 0x%x\n", - fsc->fs.m_u.raw_ip4_spec.ip4src); + fsc->fs.m_u.usr_ip4_spec.ip4src); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tDest IP addr: 0x%x\n", - fsc->fs.h_u.raw_ip4_spec.ip4dst); + fsc->fs.h_u.usr_ip4_spec.ip4dst); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tDest IP mask: 0x%x\n", - fsc->fs.m_u.raw_ip4_spec.ip4dst); + fsc->fs.m_u.usr_ip4_spec.ip4dst); p += ETH_GSTRING_LEN; num_strings++; break; -- cgit v1.2.3 From 7dff59efbb0e8b0f81c95fd40379c0d0c757c808 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 11:07:15 +0000 Subject: net: add rtnl_dereference() We sometime want to dereference an rcu protected pointer while holding RTNL. Use a macro to hide all lockdep details. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 263690d991a8..68c436bddc88 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -760,6 +760,15 @@ extern int lockdep_rtnl_is_held(void); rcu_dereference_check(p, rcu_read_lock_held() || \ lockdep_rtnl_is_held()) +/** + * rtnl_dereference - rcu_dereference with debug checking + * @p: The pointer to read, prior to dereferencing + * + * Do an rcu_dereference(p), but check caller holds RTNL + */ +#define rtnl_dereference(p) \ + rcu_dereference_check(p, lockdep_rtnl_is_held()) + extern void rtnetlink_init(void); extern void __rtnl_unlock(void); -- cgit v1.2.3 From b7285b7912776a4492744949c747c88d539006fa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 11:07:24 +0000 Subject: ipip: get rid of ipip_lock As RTNL is held while doing tunnels inserts and deletes, we can remove ipip_lock spinlock. My initial RCU conversion was conservative and converted the rwlock to spinlock, with no RTNL requirement. Use appropriate rcu annotations and modern lockdep checks as well. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 67 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 3c6f8f3968a6..8de8888dc95a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -122,11 +122,11 @@ static int ipip_net_id __read_mostly; struct ipip_net { - struct ip_tunnel *tunnels_r_l[HASH_SIZE]; - struct ip_tunnel *tunnels_r[HASH_SIZE]; - struct ip_tunnel *tunnels_l[HASH_SIZE]; - struct ip_tunnel *tunnels_wc[1]; - struct ip_tunnel **tunnels[4]; + struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_r[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_wc[1]; + struct ip_tunnel __rcu **tunnels[4]; struct net_device *fb_tunnel_dev; }; @@ -135,9 +135,8 @@ static void ipip_tunnel_init(struct net_device *dev); static void ipip_tunnel_setup(struct net_device *dev); /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipip_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) @@ -145,8 +144,8 @@ static DEFINE_SPINLOCK(ipip_lock); static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, __be32 remote, __be32 local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip_tunnel *t; struct ipip_net *ipn = net_generic(net, ipip_net_id); @@ -169,12 +168,12 @@ static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, return NULL; } -static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn, +static struct ip_tunnel __rcu **__ipip_bucket(struct ipip_net *ipn, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - unsigned h = 0; + unsigned int h = 0; int prio = 0; if (remote) { @@ -188,7 +187,7 @@ static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn, return &ipn->tunnels[prio][h]; } -static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn, +static inline struct ip_tunnel __rcu **ipip_bucket(struct ipip_net *ipn, struct ip_tunnel *t) { return __ipip_bucket(ipn, &t->parms); @@ -196,13 +195,14 @@ static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn, static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipip_bucket(ipn, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipip_lock); - *tp = t->next; - spin_unlock_bh(&ipip_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipip_bucket(ipn, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -210,12 +210,10 @@ static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t) static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipip_bucket(ipn, t); + struct ip_tunnel __rcu **tp = ipip_bucket(ipn, t); - spin_lock_bh(&ipip_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipip_lock); } static struct ip_tunnel * ipip_tunnel_locate(struct net *net, @@ -223,12 +221,15 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - struct ip_tunnel *t, **tp, *nt; + struct ip_tunnel *t, *nt; + struct ip_tunnel __rcu **tp; struct net_device *dev; char name[IFNAMSIZ]; struct ipip_net *ipn = net_generic(net, ipip_net_id); - for (tp = __ipip_bucket(ipn, parms); (t = *tp) != NULL; tp = &t->next) { + for (tp = __ipip_bucket(ipn, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) return t; } @@ -268,16 +269,15 @@ failed_free: return NULL; } +/* called with RTNL */ static void ipip_tunnel_uninit(struct net_device *dev) { struct net *net = dev_net(dev); struct ipip_net *ipn = net_generic(net, ipip_net_id); - if (dev == ipn->fb_tunnel_dev) { - spin_lock_bh(&ipip_lock); - ipn->tunnels_wc[0] = NULL; - spin_unlock_bh(&ipip_lock); - } else + if (dev == ipn->fb_tunnel_dev) + rcu_assign_pointer(ipn->tunnels_wc[0], NULL); + else ipip_tunnel_unlink(ipn, netdev_priv(dev)); dev_put(dev); } @@ -741,7 +741,7 @@ static void __net_init ipip_fb_tunnel_init(struct net_device *dev) iph->ihl = 5; dev_hold(dev); - ipn->tunnels_wc[0] = tunnel; + rcu_assign_pointer(ipn->tunnels_wc[0], tunnel); } static struct xfrm_tunnel ipip_handler __read_mostly = { @@ -760,11 +760,12 @@ static void ipip_destroy_tunnels(struct ipip_net *ipn, struct list_head *head) for (prio = 1; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { - struct ip_tunnel *t = ipn->tunnels[prio][h]; + struct ip_tunnel *t; + t = rtnl_dereference(ipn->tunnels[prio][h]); while (t != NULL) { unregister_netdevice_queue(t->dev, head); - t = t->next; + t = rtnl_dereference(t->next); } } } -- cgit v1.2.3 From 1507850b400492fdedc3064d3b8db5e9a1c871e3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 11:07:53 +0000 Subject: gre: get rid of ipgre_lock As RTNL is held while doing tunnels inserts and deletes, we can remove ipgre_lock spinlock. My initial RCU conversion was conservative and converted the rwlock to spinlock, with no RTNL requirement. Use appropriate rcu annotations and modern lockdep checks as well. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 61 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 85176895495a..fc20e687e933 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -129,7 +129,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev); static int ipgre_net_id __read_mostly; struct ipgre_net { - struct ip_tunnel *tunnels[4][HASH_SIZE]; + struct ip_tunnel __rcu *tunnels[4][HASH_SIZE]; struct net_device *fb_tunnel_dev; }; @@ -159,9 +159,8 @@ struct ipgre_net { #define tunnels_l tunnels[1] #define tunnels_wc tunnels[0] /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipgre_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) @@ -174,8 +173,8 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, { struct net *net = dev_net(dev); int link = dev->ifindex; - unsigned h0 = HASH(remote); - unsigned h1 = HASH(key); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(key); struct ip_tunnel *t, *cand = NULL; struct ipgre_net *ign = net_generic(net, ipgre_net_id); int dev_type = (gre_proto == htons(ETH_P_TEB)) ? @@ -290,13 +289,13 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, return NULL; } -static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign, +static struct ip_tunnel __rcu **__ipgre_bucket(struct ipgre_net *ign, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; __be32 key = parms->i_key; - unsigned h = HASH(key); + unsigned int h = HASH(key); int prio = 0; if (local) @@ -309,7 +308,7 @@ static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign, return &ign->tunnels[prio][h]; } -static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign, +static inline struct ip_tunnel __rcu **ipgre_bucket(struct ipgre_net *ign, struct ip_tunnel *t) { return __ipgre_bucket(ign, &t->parms); @@ -317,23 +316,22 @@ static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign, static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipgre_bucket(ign, t); + struct ip_tunnel __rcu **tp = ipgre_bucket(ign, t); - spin_lock_bh(&ipgre_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipgre_lock); } static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipgre_lock); - *tp = t->next; - spin_unlock_bh(&ipgre_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipgre_bucket(ign, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -347,10 +345,13 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net, __be32 local = parms->iph.saddr; __be32 key = parms->i_key; int link = parms->link; - struct ip_tunnel *t, **tp; + struct ip_tunnel *t; + struct ip_tunnel __rcu **tp; struct ipgre_net *ign = net_generic(net, ipgre_net_id); - for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) + for (tp = __ipgre_bucket(ign, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && key == t->parms.i_key && @@ -361,7 +362,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net, return t; } -static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, +static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { struct ip_tunnel *t, *nt; @@ -669,7 +670,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev u8 tos; __be16 df; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int gre_hlen; @@ -1013,7 +1014,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) break; } } else { - unsigned nflags = 0; + unsigned int nflags = 0; t = netdev_priv(dev); @@ -1126,7 +1127,7 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - const void *daddr, const void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned int len) { struct ip_tunnel *t = netdev_priv(dev); struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); @@ -1275,7 +1276,7 @@ static void ipgre_fb_tunnel_init(struct net_device *dev) tunnel->hlen = sizeof(struct iphdr) + 4; dev_hold(dev); - ign->tunnels_wc[0] = tunnel; + rcu_assign_pointer(ign->tunnels_wc[0], tunnel); } @@ -1291,11 +1292,13 @@ static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) for (prio = 0; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { - struct ip_tunnel *t = ign->tunnels[prio][h]; + struct ip_tunnel *t; + + t = rtnl_dereference(ign->tunnels[prio][h]); while (t != NULL) { unregister_netdevice_queue(t->dev, head); - t = t->next; + t = rtnl_dereference(t->next); } } } @@ -1522,7 +1525,7 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], t = nt; if (dev->type != ARPHRD_ETHER) { - unsigned nflags = 0; + unsigned int nflags = 0; if (ipv4_is_multicast(p.iph.daddr)) nflags = IFF_BROADCAST; -- cgit v1.2.3 From 3a43be3c328ff42327da0b141de360dc4587aab7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 11:35:10 +0000 Subject: sit: get rid of ipip6_lock As RTNL is held while doing tunnels inserts and deletes, we can remove ipip6_lock spinlock. My initial RCU conversion was conservative and converted the rwlock to spinlock, with no RTNL requirement. Use appropriate rcu annotations and modern lockdep checks as well. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/sit.c | 64 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 86618eb30335..6822481ff766 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -68,19 +68,18 @@ static void ipip6_tunnel_setup(struct net_device *dev); static int sit_net_id __read_mostly; struct sit_net { - struct ip_tunnel *tunnels_r_l[HASH_SIZE]; - struct ip_tunnel *tunnels_r[HASH_SIZE]; - struct ip_tunnel *tunnels_l[HASH_SIZE]; - struct ip_tunnel *tunnels_wc[1]; - struct ip_tunnel **tunnels[4]; + struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_r[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_wc[1]; + struct ip_tunnel __rcu **tunnels[4]; struct net_device *fb_tunnel_dev; }; /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipip6_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) @@ -91,8 +90,8 @@ static DEFINE_SPINLOCK(ipip6_lock); static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, struct net_device *dev, __be32 remote, __be32 local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip_tunnel *t; struct sit_net *sitn = net_generic(net, sit_net_id); @@ -121,12 +120,12 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, return NULL; } -static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, +static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - unsigned h = 0; + unsigned int h = 0; int prio = 0; if (remote) { @@ -140,7 +139,7 @@ static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, return &sitn->tunnels[prio][h]; } -static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn, +static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn, struct ip_tunnel *t) { return __ipip6_bucket(sitn, &t->parms); @@ -148,13 +147,14 @@ static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn, static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipip6_lock); - *tp = t->next; - spin_unlock_bh(&ipip6_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipip6_bucket(sitn, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -162,12 +162,10 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipip6_bucket(sitn, t); + struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); - spin_lock_bh(&ipip6_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipip6_lock); } static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) @@ -187,17 +185,20 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) #endif } -static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, +static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - struct ip_tunnel *t, **tp, *nt; + struct ip_tunnel *t, *nt; + struct ip_tunnel __rcu **tp; struct net_device *dev; char name[IFNAMSIZ]; struct sit_net *sitn = net_generic(net, sit_net_id); - for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { + for (tp = __ipip6_bucket(sitn, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && parms->link == t->parms.link) { @@ -340,7 +341,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) ASSERT_RTNL(); - for (p = t->prl; p; p = p->next) { + for (p = rtnl_dereference(t->prl); p; p = rtnl_dereference(p->next)) { if (p->addr == a->addr) { if (chg) { p->flags = a->flags; @@ -451,15 +452,12 @@ static void ipip6_tunnel_uninit(struct net_device *dev) struct sit_net *sitn = net_generic(net, sit_net_id); if (dev == sitn->fb_tunnel_dev) { - spin_lock_bh(&ipip6_lock); - sitn->tunnels_wc[0] = NULL; - spin_unlock_bh(&ipip6_lock); - dev_put(dev); + rcu_assign_pointer(sitn->tunnels_wc[0], NULL); } else { ipip6_tunnel_unlink(sitn, netdev_priv(dev)); ipip6_tunnel_del_prl(netdev_priv(dev), NULL); - dev_put(dev); } + dev_put(dev); } @@ -590,7 +588,7 @@ __be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel) #ifdef CONFIG_IPV6_SIT_6RD if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix, tunnel->ip6rd.prefixlen)) { - unsigned pbw0, pbi0; + unsigned int pbw0, pbi0; int pbi1; u32 d; -- cgit v1.2.3 From 0a5f1d476aef43916abb2b8634ebff23ef2c05f6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 14 Sep 2010 10:22:36 +0000 Subject: irda/irnet: use noop_llseek There may be applications trying to seek on the irnet character device, so we should use noop_llseek to avoid returning an error when the default llseek changes to no_llseek. Signed-off-by: Arnd Bergmann Cc: Samuel Ortiz Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- net/irda/irnet/irnet_ppp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h index b5df2418f90c..940225866da0 100644 --- a/net/irda/irnet/irnet_ppp.h +++ b/net/irda/irnet/irnet_ppp.h @@ -103,7 +103,8 @@ static const struct file_operations irnet_device_fops = .poll = dev_irnet_poll, .unlocked_ioctl = dev_irnet_ioctl, .open = dev_irnet_open, - .release = dev_irnet_close + .release = dev_irnet_close, + .llseek = noop_llseek, /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */ }; -- cgit v1.2.3 From 72250d44bc76d3d7fa9253aeeb063a467e2458fa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 14 Sep 2010 09:35:04 +0000 Subject: i4l: kill big kernel lock The isdn4linux driver uses the big kernel lock only to serialize access to a few fields in its own modem_info structure. The easiest replacement is a driver-wide mutex. More fine-grained locking would be more appropriate here, but likely harder to implement. Signed-off-by: Arnd Bergmann Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_tty.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index f013ee15327c..c463162843ba 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "isdn_common.h" #include "isdn_tty.h" #ifdef CONFIG_ISDN_AUDIO @@ -28,6 +28,7 @@ /* Prototypes */ +static DEFINE_MUTEX(modem_info_mutex); static int isdn_tty_edit_at(const char *, int, modem_info *); static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *); static void isdn_tty_modem_reset_regs(modem_info *, int); @@ -1354,14 +1355,14 @@ isdn_tty_tiocmget(struct tty_struct *tty, struct file *file) if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; - lock_kernel(); + mutex_lock(&modem_info_mutex); #ifdef ISDN_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line); #endif control = info->mcr; status = info->msr; - unlock_kernel(); + mutex_unlock(&modem_info_mutex); return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) @@ -1385,7 +1386,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear); #endif - lock_kernel(); + mutex_lock(&modem_info_mutex); if (set & TIOCM_RTS) info->mcr |= UART_MCR_RTS; if (set & TIOCM_DTR) { @@ -1407,7 +1408,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, isdn_tty_modem_hup(info, 1); } } - unlock_kernel(); + mutex_unlock(&modem_info_mutex); return 0; } -- cgit v1.2.3 From 1a19eb753a591f8b39946b7fda91b25f07454835 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 14 Sep 2010 09:35:05 +0000 Subject: misdn: kill big kernel lock The use of the big kernel lock in misdn is completely bogus, so let's just remove it. Signed-off-by: Arnd Bergmann Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/mISDN/stack.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index b159bd59e64e..a5b632e67552 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "core.h" static u_int *debug; @@ -205,13 +204,7 @@ mISDNStackd(void *data) struct mISDNstack *st = data; int err = 0; -#ifdef CONFIG_SMP - lock_kernel(); -#endif sigfillset(¤t->blocked); -#ifdef CONFIG_SMP - unlock_kernel(); -#endif if (*debug & DEBUG_MSG_THREAD) printk(KERN_DEBUG "mISDNStackd %s started\n", dev_name(&st->dev->dev)); -- cgit v1.2.3 From 6482f554e2b9cbe733d63124765104f29cf0c9ad Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:19:53 +0000 Subject: Phonet: remove dangling pipe if an endpoint is closed early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closing a pipe endpoint is not normally allowed by the Phonet pipe, other than as a side after-effect of removing the pipe between two endpoints. But there is no way to prevent Linux userspace processes from being killed or suffering from bugs, so this can still happen. We might as well forcefully close Phonet pipe endpoints then. The cellular modem supports only a few existing pipes at a time. So we really should not leak them. This change instructs the modem to destroy the pipe if either of the pipe's endpoint (Linux socket) is closed too early. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/net/phonet/pep.h | 5 +++++ net/phonet/pep.c | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h index 35672b1cf44a..37f23dc05de8 100644 --- a/include/net/phonet/pep.h +++ b/include/net/phonet/pep.h @@ -77,6 +77,11 @@ static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb) #define MAX_PNPIPE_HEADER (MAX_PHONET_HEADER + 4) enum { + PNS_PIPE_CREATE_REQ = 0x00, + PNS_PIPE_CREATE_RESP, + PNS_PIPE_REMOVE_REQ, + PNS_PIPE_REMOVE_RESP, + PNS_PIPE_DATA = 0x20, PNS_PIPE_ALIGNED_DATA, diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 04e34196c9de..d0e7eb24c8b9 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -620,6 +620,28 @@ drop: return err; } +static int pipe_do_remove(struct sock *sk) +{ + struct pep_sock *pn = pep_sk(sk); + struct pnpipehdr *ph; + struct sk_buff *skb; + + skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = 0; + ph->message_id = PNS_PIPE_REMOVE_REQ; + ph->pipe_handle = pn->pipe_handle; + ph->data[0] = PAD; + + return pn_skb_send(sk, skb, &pipe_srv); +} + /* associated socket ceases to exist */ static void pep_sock_close(struct sock *sk, long timeout) { @@ -638,7 +660,10 @@ static void pep_sock_close(struct sock *sk, long timeout) sk_for_each_safe(sknode, p, n, &pn->ackq) sk_del_node_init(sknode); sk->sk_state = TCP_CLOSE; - } + } else if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED)) + /* Forcefully remove dangling Phonet pipe */ + pipe_do_remove(sk); + ifindex = pn->ifindex; pn->ifindex = 0; release_sock(sk); -- cgit v1.2.3 From 4e3d16ce5e82648d7f4dfd28b6cf8fe2e9a9efc3 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:30:11 +0000 Subject: Phonet: resource routing backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When both destination device and object are nul, Phonet routes the packet according to the resource field. In fact, this is the most common pattern when sending Phonet "request" packets. In this case, the packet is delivered to whichever endpoint (socket) has registered the resource. This adds a new table so that Linux processes can register their Phonet sockets to Phonet resources, if they have adequate privileges. (Namespace support is not implemented at the moment.) Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/net/phonet/phonet.h | 5 +++ net/phonet/socket.c | 88 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index 7b114079a51b..d5df797f9540 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -54,6 +54,11 @@ void pn_sock_hash(struct sock *sk); void pn_sock_unhash(struct sock *sk); int pn_sock_get_port(struct sock *sk, unsigned short sport); +struct sock *pn_find_sock_by_res(struct net *net, u8 res); +int pn_sock_bind_res(struct sock *sock, u8 res); +int pn_sock_unbind_res(struct sock *sk, u8 res); +void pn_sock_unbind_all_res(struct sock *sk); + int pn_skb_send(struct sock *sk, struct sk_buff *skb, const struct sockaddr_pn *target); diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 7c91f739f138..4c29a23e9007 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -565,3 +565,91 @@ const struct file_operations pn_sock_seq_fops = { .release = seq_release_net, }; #endif + +static struct { + struct sock *sk[256]; +} pnres; + +/* + * Find and hold socket based on resource. + */ +struct sock *pn_find_sock_by_res(struct net *net, u8 res) +{ + struct sock *sk; + + if (!net_eq(net, &init_net)) + return NULL; + + rcu_read_lock(); + sk = rcu_dereference(pnres.sk[res]); + if (sk) + sock_hold(sk); + rcu_read_unlock(); + return sk; +} + +static DEFINE_MUTEX(resource_mutex); + +int pn_sock_bind_res(struct sock *sk, u8 res) +{ + int ret = -EADDRINUSE; + + if (!net_eq(sock_net(sk), &init_net)) + return -ENOIOCTLCMD; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (pn_socket_autobind(sk->sk_socket)) + return -EAGAIN; + + mutex_lock(&resource_mutex); + if (pnres.sk[res] == NULL) { + sock_hold(sk); + rcu_assign_pointer(pnres.sk[res], sk); + ret = 0; + } + mutex_unlock(&resource_mutex); + return ret; +} + +int pn_sock_unbind_res(struct sock *sk, u8 res) +{ + int ret = -ENOENT; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + mutex_lock(&resource_mutex); + if (pnres.sk[res] == sk) { + rcu_assign_pointer(pnres.sk[res], NULL); + ret = 0; + } + mutex_unlock(&resource_mutex); + + if (ret == 0) { + synchronize_rcu(); + sock_put(sk); + } + return ret; +} + +void pn_sock_unbind_all_res(struct sock *sk) +{ + unsigned res, match = 0; + + mutex_lock(&resource_mutex); + for (res = 0; res < 256; res++) { + if (pnres.sk[res] == sk) { + rcu_assign_pointer(pnres.sk[res], NULL); + match++; + } + } + mutex_unlock(&resource_mutex); + + if (match == 0) + return; + synchronize_rcu(); + while (match > 0) { + sock_put(sk); + match--; + } +} -- cgit v1.2.3 From 7417fa83c1a8b75a03bd9b9b358999f38e771eab Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:30:12 +0000 Subject: Phonet: hook resource routing to userspace via ioctl()'s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I wish we could use something cleaner, such as bind(). But that would not work since resource subscription is orthogonal/in addition to the normal object ID allocated via bind(). This is similar to multicasting which also uses ioctl()'s. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 2 ++ net/phonet/datagram.c | 13 +++++++++++++ net/phonet/socket.c | 1 + 3 files changed, 16 insertions(+) diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 76edadf046d3..85e14a83283b 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -47,6 +47,8 @@ /* ioctls */ #define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) +#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14) +#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15) /* Phonet protocol header */ struct phonethdr { diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index 1bd38db4fe1e..2f032381bd45 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c @@ -52,6 +52,19 @@ static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg) answ = skb ? skb->len : 0; release_sock(sk); return put_user(answ, (int __user *)arg); + + case SIOCPNADDRESOURCE: + case SIOCPNDELRESOURCE: { + u32 res; + if (get_user(res, (u32 __user *)arg)) + return -EFAULT; + if (res >= 256) + return -EINVAL; + if (cmd == SIOCPNADDRESOURCE) + return pn_sock_bind_res(sk, res); + else + return pn_sock_unbind_res(sk, res); + } } return -ENOIOCTLCMD; diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 4c29a23e9007..d4f41afc0583 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -158,6 +158,7 @@ void pn_sock_unhash(struct sock *sk) spin_lock_bh(&pnsocks.lock); sk_del_node_init(sk); spin_unlock_bh(&pnsocks.lock); + pn_sock_unbind_all_res(sk); } EXPORT_SYMBOL(pn_sock_unhash); -- cgit v1.2.3 From b6a563b2af4ec5b0363cf89869ba234c0e2cd3da Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:30:13 +0000 Subject: Phonet: look up the resource routing table when forwarding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/af_phonet.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 73aee7f2fcdc..fd95beb72f5d 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -251,6 +251,16 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb, else if (phonet_address_lookup(net, daddr) == 0) { dev = phonet_device_get(net); skb->pkt_type = PACKET_LOOPBACK; + } else if (pn_sockaddr_get_object(target) == 0) { + /* Resource routing (small race until phonet_rcv()) */ + struct sock *sk = pn_find_sock_by_res(net, + target->spn_resource); + if (sk) { + sock_put(sk); + dev = phonet_device_get(net); + skb->pkt_type = PACKET_LOOPBACK; + } else + dev = phonet_route_output(net, daddr); } else dev = phonet_route_output(net, daddr); @@ -383,6 +393,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev, goto out; } + /* resource routing */ + if (pn_sockaddr_get_object(&sa) == 0) { + struct sock *sk = pn_find_sock_by_res(net, sa.spn_resource); + if (sk) + return sk_receive_skb(sk, skb, 0); + } + /* check if we are the destination */ if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) { /* Phonet packet input */ -- cgit v1.2.3 From 507215f8d04f9e61f38c975e61d93bcafd30815f Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:30:14 +0000 Subject: Phonet: list subscribed resources via proc_fs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/net/phonet/pn_dev.h | 1 + net/phonet/pn_dev.c | 2 + net/phonet/socket.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 2d16783d5e20..13649eb57413 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -57,5 +57,6 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr); #define PN_NO_ADDR 0xff extern const struct file_operations pn_sock_seq_fops; +extern const struct file_operations pn_res_seq_fops; #endif diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index d0a429459370..947038ddd04c 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -373,6 +373,7 @@ int __init phonet_device_init(void) if (err) return err; + proc_net_fops_create(&init_net, "pnresource", 0, &pn_res_seq_fops); register_netdevice_notifier(&phonet_device_notifier); err = phonet_netlink_register(); if (err) @@ -385,6 +386,7 @@ void phonet_device_exit(void) rtnl_unregister_all(PF_PHONET); unregister_netdevice_notifier(&phonet_device_notifier); unregister_pernet_device(&phonet_net_ops); + proc_net_remove(&init_net, "pnresource"); } int phonet_route_add(struct net_device *dev, u8 daddr) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index d4f41afc0583..6bf6e3c97d5c 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -654,3 +654,99 @@ void pn_sock_unbind_all_res(struct sock *sk) match--; } } + +#ifdef CONFIG_PROC_FS +static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos) +{ + struct net *net = seq_file_net(seq); + unsigned i; + + if (!net_eq(net, &init_net)) + return NULL; + + for (i = 0; i < 256; i++) { + if (pnres.sk[i] == NULL) + continue; + if (!pos) + return pnres.sk + i; + pos--; + } + return NULL; +} + +static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk) +{ + struct net *net = seq_file_net(seq); + unsigned i; + + BUG_ON(!net_eq(net, &init_net)); + + for (i = (sk - pnres.sk) + 1; i < 256; i++) + if (pnres.sk[i]) + return pnres.sk + i; + return NULL; +} + +static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(resource_mutex) +{ + mutex_lock(&resource_mutex); + return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; +} + +static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct sock **sk; + + if (v == SEQ_START_TOKEN) + sk = pn_res_get_idx(seq, 0); + else + sk = pn_res_get_next(seq, v); + (*pos)++; + return sk; +} + +static void pn_res_seq_stop(struct seq_file *seq, void *v) + __releases(resource_mutex) +{ + mutex_unlock(&resource_mutex); +} + +static int pn_res_seq_show(struct seq_file *seq, void *v) +{ + int len; + + if (v == SEQ_START_TOKEN) + seq_printf(seq, "%s%n", "rs uid inode", &len); + else { + struct sock **psk = v; + struct sock *sk = *psk; + + seq_printf(seq, "%02X %5d %lu%n", + psk - pnres.sk, sock_i_uid(sk), sock_i_ino(sk), &len); + } + seq_printf(seq, "%*s\n", 63 - len, ""); + return 0; +} + +static const struct seq_operations pn_res_seq_ops = { + .start = pn_res_seq_start, + .next = pn_res_seq_next, + .stop = pn_res_seq_stop, + .show = pn_res_seq_show, +}; + +static int pn_res_open(struct inode *inode, struct file *file) +{ + return seq_open_net(inode, file, &pn_res_seq_ops, + sizeof(struct seq_net_private)); +} + +const struct file_operations pn_res_seq_fops = { + .owner = THIS_MODULE, + .open = pn_res_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_net, +}; +#endif -- cgit v1.2.3 From 274a517ec13b3b47047b97a2e7c912138c9806e0 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 15 Sep 2010 12:30:15 +0000 Subject: Phonet: resource routing documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- Documentation/networking/phonet.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt index 6e8ce09f9c73..cf76608a2d35 100644 --- a/Documentation/networking/phonet.txt +++ b/Documentation/networking/phonet.txt @@ -112,6 +112,22 @@ However, connect() and getpeername() are not supported, as they did not seem useful with Phonet usages (could be added easily). +Resource subscription +--------------------- + +A Phonet datagram socket can be subscribed to any number of 8-bits +Phonet resources, as follow: + + uint32_t res = 0xXX; + ioctl(fd, SIOCPNADDRESOURCE, &res); + +Subscription is similarly cancelled using the SIOCPNDELRESOURCE I/O +control request, or when the socket is closed. + +Note that no more than one socket can be subcribed to any given +resource at a time. If not, ioctl() will return EBUSY. + + Phonet Pipe protocol -------------------- -- cgit v1.2.3 From 9e0064a5456fd75fd7c70f6f3692c7f732f91a65 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 15 Sep 2010 21:34:41 -0700 Subject: phonet: Fix build warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/phonet/socket.c: In function ‘pn_res_seq_show’: net/phonet/socket.c:726: warning: format ‘%02X’ expects type ‘unsigned int’, but argument 3 has type ‘long int’ Signed-off-by: David S. Miller --- net/phonet/socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 6bf6e3c97d5c..aca8fba099e9 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -723,7 +723,8 @@ static int pn_res_seq_show(struct seq_file *seq, void *v) struct sock *sk = *psk; seq_printf(seq, "%02X %5d %lu%n", - psk - pnres.sk, sock_i_uid(sk), sock_i_ino(sk), &len); + (int) (psk - pnres.sk), sock_i_uid(sk), + sock_i_ino(sk), &len); } seq_printf(seq, "%*s\n", 63 - len, ""); return 0; -- cgit v1.2.3 From 95ae6b228f814fc0528d0506ee9f18ac333d6851 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 04:04:31 +0000 Subject: ipv4: ip_ptr cleanups dev->ip_ptr is protected by rtnl and rcu. Yet some places dont use appropriate primitives and/or locking rules. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/plip.c | 8 ++++++-- drivers/net/via-velocity.h | 11 +++++++---- drivers/net/wan/hdlc_cisco.c | 4 +++- include/linux/inetdevice.h | 14 +++++--------- include/linux/netdevice.h | 2 +- net/core/dev.c | 2 +- net/ipv4/devinet.c | 4 ++-- net/ipv4/ipmr.c | 2 +- net/mac80211/main.c | 2 +- 9 files changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 7e82a82422cf..ca4df7f4cf21 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -995,8 +995,10 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev) static void plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) { - const struct in_device *in_dev = dev->ip_ptr; + const struct in_device *in_dev; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev); if (in_dev) { /* Any address will do - we take the first */ const struct in_ifaddr *ifa = in_dev->ifa_list; @@ -1006,6 +1008,7 @@ plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) memcpy(eth->h_dest+2, &ifa->ifa_address, 4); } } + rcu_read_unlock(); } static int @@ -1088,7 +1091,8 @@ plip_open(struct net_device *dev) when the device address isn't identical to the address of a received frame, the kernel incorrectly drops it). */ - if ((in_dev=dev->ip_ptr) != NULL) { + in_dev=__in_dev_get_rtnl(dev); + if (in_dev) { /* Any address will do - we take the first. We already have the first two bytes filled with 0xfc, from plip_init_dev(). */ diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index f7b33ae7a703..b5e120b0074b 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -1504,22 +1504,25 @@ struct velocity_info { * addresses on this chain then we use the first - multi-IP WOL is not * supported. * - * CHECK ME: locking */ static inline int velocity_get_ip(struct velocity_info *vptr) { - struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr; + struct in_device *in_dev; struct in_ifaddr *ifa; + int res = -ENOENT; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(vptr->dev); if (in_dev != NULL) { ifa = (struct in_ifaddr *) in_dev->ifa_list; if (ifa != NULL) { memcpy(vptr->ip_addr, &ifa->ifa_address, 4); - return 0; + res = 0; } } - return -ENOENT; + rcu_read_unlock(); + return res; } /** diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index b38ffa149aba..b1e5e5b69c2a 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -191,7 +191,8 @@ static int cisco_rx(struct sk_buff *skb) switch (ntohl (cisco_data->type)) { case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ - in_dev = dev->ip_ptr; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev); addr = 0; mask = ~cpu_to_be32(0); /* is the mask correct? */ @@ -211,6 +212,7 @@ static int cisco_rx(struct sk_buff *skb) cisco_keepalive_send(dev, CISCO_ADDR_REPLY, addr, mask); } + rcu_read_unlock(); dev_kfree_skb_any(skb); return NET_RX_SUCCESS; diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 2be1a1a2beb9..1ec09bb4a3ab 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -9,6 +9,7 @@ #include #include #include +#include enum { @@ -198,14 +199,10 @@ static __inline__ int bad_mask(__be32 mask, __be32 addr) static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) { - struct in_device *in_dev = dev->ip_ptr; - if (in_dev) - in_dev = rcu_dereference(in_dev); - return in_dev; + return rcu_dereference(dev->ip_ptr); } -static __inline__ struct in_device * -in_dev_get(const struct net_device *dev) +static inline struct in_device *in_dev_get(const struct net_device *dev) { struct in_device *in_dev; @@ -217,10 +214,9 @@ in_dev_get(const struct net_device *dev) return in_dev; } -static __inline__ struct in_device * -__in_dev_get_rtnl(const struct net_device *dev) +static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev) { - return (struct in_device*)dev->ip_ptr; + return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held()); } extern void in_dev_finish_destroy(struct in_device *idev); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index af05186d5b36..8992fffb8104 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -942,7 +942,7 @@ struct net_device { void *dsa_ptr; /* dsa specific data */ #endif void *atalk_ptr; /* AppleTalk link */ - void *ip_ptr; /* IPv4 specific data */ + struct in_device __rcu *ip_ptr; /* IPv4 specific data */ void *dn_ptr; /* DECnet specific data */ void *ip6_ptr; /* IPv6 specific data */ void *ec_ptr; /* Econet specific data */ diff --git a/net/core/dev.c b/net/core/dev.c index fc2dc933bee5..5bdce97b8175 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5286,7 +5286,7 @@ void netdev_run_todo(void) /* paranoia */ BUG_ON(atomic_read(&dev->refcnt)); - WARN_ON(dev->ip_ptr); + WARN_ON(rcu_dereference_raw(dev->ip_ptr)); WARN_ON(dev->ip6_ptr); WARN_ON(dev->dn_ptr); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index da14c49284f4..c2ff48fa18c7 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -209,7 +209,7 @@ static void inetdev_destroy(struct in_device *in_dev) inet_free_ifa(ifa); } - dev->ip_ptr = NULL; + rcu_assign_pointer(dev->ip_ptr, NULL); devinet_sysctl_unregister(in_dev); neigh_parms_release(&arp_tbl, in_dev->arp_parms); @@ -1059,7 +1059,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_REGISTER: printk(KERN_DEBUG "inetdev_event: bug\n"); - dev->ip_ptr = NULL; + rcu_assign_pointer(dev->ip_ptr, NULL); break; case NETDEV_UP: if (!inetdev_valid_mtu(dev->mtu)) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 179fcab866fc..10b24c02deb0 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -724,7 +724,7 @@ static int vif_add(struct net *net, struct mr_table *mrt, case 0: if (vifc->vifc_flags == VIFF_USE_IFINDEX) { dev = dev_get_by_index(net, vifc->vifc_lcl_ifindex); - if (dev && dev->ip_ptr == NULL) { + if (dev && __in_dev_get_rtnl(dev) == NULL) { dev_put(dev); return -EADDRNOTAVAIL; } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4935b843bcca..b8cf2821f00d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -362,7 +362,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, if (sdata->vif.type != NL80211_IFTYPE_STATION) return NOTIFY_DONE; - idev = sdata->dev->ip_ptr; + idev = __in_dev_get_rtnl(sdata->dev); if (!idev) return NOTIFY_DONE; -- cgit v1.2.3 From 1953925ea61cd1a77828deddc61d000303dbbb97 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 15 Sep 2010 17:22:17 +0000 Subject: sky2: enable GRO by default The driver has supported GRO for a while, but it was not enabled by default. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 194e5cf8c763..3ef9b67ac6e6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4581,7 +4581,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->port = port; - dev->features |= NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_SG; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG + | NETIF_F_TSO | NETIF_F_GRO; if (highmem) dev->features |= NETIF_F_HIGHDMA; -- cgit v1.2.3 From b1cbd5f980863eb97f687baba95850c334c83a47 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 15 Sep 2010 17:54:22 +0000 Subject: ehea: Remove a silly return This patch removes the unconditional return in the end of the function check_sqs() Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 043d99013056..190fb691d20b 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -818,8 +818,6 @@ static void check_sqs(struct ehea_port *port) } } } - - return; } -- cgit v1.2.3 From 16c3ea785fe4a383c6675dfe7316f3c815755bdd Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 15 Sep 2010 09:24:24 +0000 Subject: net: enable GRO by default for vlan devices Currently vlan devices don't have GRO by default as none of the Ethernet drivers add NETIF_F_GRO to their vlan_features. As GRO is a software feature add GRO to dev->vlan_features in register_netdevice() and let vlan_dev_init() take care that it gets enabled only when dev->features has NETIF_F_GRO too. Signed-off-by: Brandon Philips Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index 5bdce97b8175..09b3742c4c89 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5057,6 +5057,11 @@ int register_netdevice(struct net_device *dev) if (dev->features & NETIF_F_SG) dev->features |= NETIF_F_GSO; + /* Enable GRO for vlans by default if dev->features has GRO also. + * vlan_dev_init() will do the dev->features check. + */ + dev->vlan_features |= NETIF_F_GRO; + ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); ret = notifier_to_errno(ret); if (ret) -- cgit v1.2.3 From 70a851667dbd7aa3f7be9609d6580ca9861230b3 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 16 Sep 2010 19:37:30 +0200 Subject: netfilter: use NFPROTO_IPV4 instead of AF_INET The field family of xt_target should be NFPROTO_IPV4, though NFPROTO_IPV4 and AF_INET are the same. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/netfilter/xt_TPROXY.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index c61294d85fda..21bb2aff6b8f 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -76,7 +76,7 @@ static int tproxy_tg_check(const struct xt_tgchk_param *par) static struct xt_target tproxy_tg_reg __read_mostly = { .name = "TPROXY", - .family = AF_INET, + .family = NFPROTO_IPV4, .table = "mangle", .target = tproxy_tg, .targetsize = sizeof(struct xt_tproxy_target_info), -- cgit v1.2.3 From 99ad3c53b36a056a472927de9c79eda231ecc6fe Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 16 Sep 2010 19:45:19 +0200 Subject: netfilter: nf_nat_core: don't check if the tuple is used if there is no other choice Eliminate nf_nat_used_tuple() to save some CPU cycles when there is no other choice. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/nf_nat_core.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 8c8632d9b93c..2c084b3a8f0c 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -262,11 +262,17 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, proto = __nf_nat_proto_find(orig_tuple->dst.protonum); /* Only bother mapping if it's not already in range and unique */ - if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM) && - (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || - proto->in_range(tuple, maniptype, &range->min, &range->max)) && - !nf_nat_used_tuple(tuple, ct)) - goto out; + if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { + if (range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) { + if (proto->in_range(tuple, maniptype, &range->min, + &range->max) && + (range->min.all == range->max.all || + !nf_nat_used_tuple(tuple, ct))) + goto out; + } else if (!nf_nat_used_tuple(tuple, ct)) { + goto out; + } + } /* Last change: get protocol to try to obtain unique tuple. */ proto->unique_tuple(tuple, range, maniptype, ct); -- cgit v1.2.3 From ed0b6d7581b54455062f09ccac123814e70cd02f Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 16 Sep 2010 19:47:51 +0200 Subject: netfilter: nf_nat: no IP_NAT_RANGE_MAP_IPS flags when alloc_null_binding() When alloc_null_binding(), no IP_NAT_RNAGE_MAP_IPS in flags means no IP address translation is needed. It isn't necessary to specify the address explicitly. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/nf_nat_rule.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index ebbd319f62f5..21c30426480b 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c @@ -106,16 +106,15 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) { /* Force range to this IP; let proto decide mapping for per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). - Use reply in case it's already been mangled (eg local packet). */ - __be32 ip - = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC - ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip - : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip); - struct nf_nat_range range - = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } }; - - pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, &ip); + struct nf_nat_range range; + + range.flags = 0; + pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, + HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC ? + &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip : + &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip); + return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); } -- cgit v1.2.3 From b23909695c33f53df5f1d16696b1aa5b874c1904 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 16 Sep 2010 19:55:03 +0200 Subject: netfilter: nf_conntrack: fix the hash random initializing race nf_conntrack_alloc() isn't called with nf_conntrack_lock locked, so hash random initializing code maybe executed more than once on different CPUs. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/netfilter/nf_conntrack_core.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index df3eedb142ff..4c0ad9b4dba0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -65,8 +65,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max); DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked); EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked); -static int nf_conntrack_hash_rnd_initted; -static unsigned int nf_conntrack_hash_rnd; +static unsigned int nf_conntrack_hash_rnd __read_mostly; static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, u16 zone, unsigned int size, unsigned int rnd) @@ -574,10 +573,18 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, { struct nf_conn *ct; - if (unlikely(!nf_conntrack_hash_rnd_initted)) { - get_random_bytes(&nf_conntrack_hash_rnd, - sizeof(nf_conntrack_hash_rnd)); - nf_conntrack_hash_rnd_initted = 1; + if (unlikely(!nf_conntrack_hash_rnd)) { + unsigned int rand; + + /* + * Why not initialize nf_conntrack_rnd in a "init()" function ? + * Because there isn't enough entropy when system initializing, + * and we initialize it as late as possible. + */ + do { + get_random_bytes(&rand, sizeof(rand)); + } while (!rand); + cmpxchg(&nf_conntrack_hash_rnd, 0, rand); } /* We don't want any race condition at early drop stage */ -- cgit v1.2.3 From 9c376639297d3dd82d40e54c9cdca8da9dfc22f1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 20 Aug 2010 15:13:59 -0700 Subject: include/net/cfg80211.h: wiphy_ messages use dev_printk The output becomes: [ 41.261941] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- include/net/cfg80211.h | 37 ++++++++++++------------------------- net/wireless/core.c | 49 ------------------------------------------------- 2 files changed, 12 insertions(+), 74 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4c8c727d0cca..a0613ff62c97 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2558,49 +2558,36 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, /* wiphy_printk helpers, similar to dev_printk */ #define wiphy_printk(level, wiphy, format, args...) \ - printk(level "%s: " format, wiphy_name(wiphy), ##args) + dev_printk(level, &(wiphy)->dev, format, ##args) #define wiphy_emerg(wiphy, format, args...) \ - wiphy_printk(KERN_EMERG, wiphy, format, ##args) + dev_emerg(&(wiphy)->dev, format, ##args) #define wiphy_alert(wiphy, format, args...) \ - wiphy_printk(KERN_ALERT, wiphy, format, ##args) + dev_alert(&(wiphy)->dev, format, ##args) #define wiphy_crit(wiphy, format, args...) \ - wiphy_printk(KERN_CRIT, wiphy, format, ##args) + dev_crit(&(wiphy)->dev, format, ##args) #define wiphy_err(wiphy, format, args...) \ - wiphy_printk(KERN_ERR, wiphy, format, ##args) + dev_err(&(wiphy)->dev, format, ##args) #define wiphy_warn(wiphy, format, args...) \ - wiphy_printk(KERN_WARNING, wiphy, format, ##args) + dev_warn(&(wiphy)->dev, format, ##args) #define wiphy_notice(wiphy, format, args...) \ - wiphy_printk(KERN_NOTICE, wiphy, format, ##args) + dev_notice(&(wiphy)->dev, format, ##args) #define wiphy_info(wiphy, format, args...) \ - wiphy_printk(KERN_INFO, wiphy, format, ##args) + dev_info(&(wiphy)->dev, format, ##args) -int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - -#if defined(DEBUG) -#define wiphy_dbg(wiphy, format, args...) \ +#define wiphy_debug(wiphy, format, args...) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args) -#elif defined(CONFIG_DYNAMIC_DEBUG) + #define wiphy_dbg(wiphy, format, args...) \ - dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args) -#else -#define wiphy_dbg(wiphy, format, args...) \ -({ \ - if (0) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ -}) -#endif + dev_dbg(&(wiphy)->dev, format, ##args) #if defined(VERBOSE_DEBUG) #define wiphy_vdbg wiphy_dbg #else - #define wiphy_vdbg(wiphy, format, args...) \ ({ \ if (0) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ + 0; \ }) #endif diff --git a/net/wireless/core.c b/net/wireless/core.c index d52630bbab04..b8191cf86226 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -912,52 +912,3 @@ static void __exit cfg80211_exit(void) destroy_workqueue(cfg80211_wq); } module_exit(cfg80211_exit); - -static int ___wiphy_printk(const char *level, const struct wiphy *wiphy, - struct va_format *vaf) -{ - if (!wiphy) - return printk("%s(NULL wiphy *): %pV", level, vaf); - - return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf); -} - -int __wiphy_printk(const char *level, const struct wiphy *wiphy, - const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - int r; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - r = ___wiphy_printk(level, wiphy, &vaf); - va_end(args); - - return r; -} -EXPORT_SYMBOL(__wiphy_printk); - -#define define_wiphy_printk_level(func, kern_level) \ -int func(const struct wiphy *wiphy, const char *fmt, ...) \ -{ \ - struct va_format vaf; \ - va_list args; \ - int r; \ - \ - va_start(args, fmt); \ - \ - vaf.fmt = fmt; \ - vaf.va = &args; \ - \ - r = ___wiphy_printk(kern_level, wiphy, &vaf); \ - va_end(args); \ - \ - return r; \ -} \ -EXPORT_SYMBOL(func); - -define_wiphy_printk_level(wiphy_debug, KERN_DEBUG); -- cgit v1.2.3 From 34a1305137f484ee1806df5a00b9d8ee8d4ef758 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:33 +0900 Subject: ath: Copy cryptographic capability flags into ath This will be used later in this patch series. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index a706202fa67c..057fdd7ddaf4 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -71,6 +71,15 @@ struct ath_regulatory { struct reg_dmn_pair_mapping *regpair; }; +enum ath_crypt_caps { + ATH_CRYPT_CAP_MIC_AESCCM = BIT(0), + ATH_CRYPT_CAP_MIC_CKIP = BIT(1), + ATH_CRYPT_CAP_MIC_TKIP = BIT(2), + ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(3), + ATH_CRYPT_CAP_CIPHER_CKIP = BIT(4), + ATH_CRYPT_CAP_CIPHER_TKIP = BIT(5), +}; + /** * struct ath_ops - Register read/write operations * @@ -121,6 +130,7 @@ struct ath_common { DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); u8 splitmic; + enum ath_crypt_caps crypt_caps; struct ath_regulatory regulatory; const struct ath_ops *ops; -- cgit v1.2.3 From 1bba5b7329e15555dab90071b24ca84d0afcc635 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:38 +0900 Subject: ath: Copy key cache management functions from ath9k to ath Copied the key cache management functions from ath9k (common.c and hw.c) to ath/key.c so we can use them from ath5k, later. Minor changes have been made: - renamed ath9k_* to ath_* - replaced ah->caps.keycache_size with common->keymax - removed ATH9K_IS_MIC_ENABLED since it is always true. - the AR_PCU_MIC_NEW_LOC_ENA flag is replaced with (splitmic == 0). Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/Makefile | 3 +- drivers/net/wireless/ath/ath.h | 27 ++ drivers/net/wireless/ath/key.c | 568 ++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/reg.h | 23 ++ 4 files changed, 620 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ath/key.c diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 40fa1794d489..6d711ec97ec2 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := main.o \ regd.o \ - hw.o + hw.o \ + key.o ath-$(CONFIG_ATH_DEBUG) += debug.o diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 057fdd7ddaf4..fb24f66373fd 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -80,6 +80,27 @@ enum ath_crypt_caps { ATH_CRYPT_CAP_CIPHER_TKIP = BIT(5), }; +struct ath_keyval { + u8 kv_type; + u8 kv_pad; + u16 kv_len; + u8 kv_val[16]; /* TK */ + u8 kv_mic[8]; /* Michael MIC key */ + u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware + * supports both MIC keys in the same key cache entry; + * in that case, kv_mic is the RX key) */ +}; + +enum ath_cipher { + ATH_CIPHER_WEP = 0, + ATH_CIPHER_AES_OCB = 1, + ATH_CIPHER_AES_CCM = 2, + ATH_CIPHER_CKIP = 3, + ATH_CIPHER_TKIP = 4, + ATH_CIPHER_CLR = 5, + ATH_CIPHER_MIC = 127 +}; + /** * struct ath_ops - Register read/write operations * @@ -142,5 +163,11 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, gfp_t gfp_mask); void ath_hw_setbssidmask(struct ath_common *common); +void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +int ath_key_config(struct ath_common *common, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +bool ath_hw_keyreset(struct ath_common *common, u16 entry); #endif /* ATH_H */ diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c new file mode 100644 index 000000000000..e45b8546810a --- /dev/null +++ b/drivers/net/wireless/ath/key.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2010 Bruno Randolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "ath.h" +#include "reg.h" +#include "debug.h" + +#define REG_READ (common->ops->read) +#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) + +#define IEEE80211_WEP_NKID 4 /* number of key ids */ + +/************************/ +/* Key Cache Management */ +/************************/ + +bool ath_hw_keyreset(struct ath_common *common, u16 entry) +{ + u32 keyType; + void *ah = common->ah; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); + return false; + } + + keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); + + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); + REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); + + if (keyType == AR_KEYTABLE_TYPE_TKIP) { + u16 micentry = entry + 64; + + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); + + } + + return true; +} +EXPORT_SYMBOL(ath_hw_keyreset); + +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) +{ + u32 macHi, macLo; + u32 unicast_flag = AR_KEYTABLE_VALID; + void *ah = common->ah; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); + return false; + } + + if (mac != NULL) { + /* + * AR_KEYTABLE_VALID indicates that the address is a unicast + * address, which must match the transmitter address for + * decrypting frames. + * Not setting this bit allows the hardware to use the key + * for multicast frame decryption. + */ + if (mac[0] & 0x01) + unicast_flag = 0; + + macHi = (mac[5] << 8) | mac[4]; + macLo = (mac[3] << 24) | + (mac[2] << 16) | + (mac[1] << 8) | + mac[0]; + macLo >>= 1; + macLo |= (macHi & 1) << 31; + macHi >>= 1; + } else { + macLo = macHi = 0; + } + REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); + REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); + + return true; +} + +bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, + const struct ath_keyval *k, + const u8 *mac) +{ + void *ah = common->ah; + u32 key0, key1, key2, key3, key4; + u32 keyType; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keycache entry %u out of range\n", entry); + return false; + } + + switch (k->kv_type) { + case ATH_CIPHER_AES_OCB: + keyType = AR_KEYTABLE_TYPE_AES; + break; + case ATH_CIPHER_AES_CCM: + if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) { + ath_print(common, ATH_DBG_ANY, + "AES-CCM not supported by this mac rev\n"); + return false; + } + keyType = AR_KEYTABLE_TYPE_CCM; + break; + case ATH_CIPHER_TKIP: + keyType = AR_KEYTABLE_TYPE_TKIP; + if (entry + 64 >= common->keymax) { + ath_print(common, ATH_DBG_ANY, + "entry %u inappropriate for TKIP\n", entry); + return false; + } + break; + case ATH_CIPHER_WEP: + if (k->kv_len < WLAN_KEY_LEN_WEP40) { + ath_print(common, ATH_DBG_ANY, + "WEP key length %u too small\n", k->kv_len); + return false; + } + if (k->kv_len <= WLAN_KEY_LEN_WEP40) + keyType = AR_KEYTABLE_TYPE_40; + else if (k->kv_len <= WLAN_KEY_LEN_WEP104) + keyType = AR_KEYTABLE_TYPE_104; + else + keyType = AR_KEYTABLE_TYPE_128; + break; + case ATH_CIPHER_CLR: + keyType = AR_KEYTABLE_TYPE_CLR; + break; + default: + ath_print(common, ATH_DBG_FATAL, + "cipher %u not supported\n", k->kv_type); + return false; + } + + key0 = get_unaligned_le32(k->kv_val + 0); + key1 = get_unaligned_le16(k->kv_val + 4); + key2 = get_unaligned_le32(k->kv_val + 6); + key3 = get_unaligned_le16(k->kv_val + 10); + key4 = get_unaligned_le32(k->kv_val + 12); + if (k->kv_len <= WLAN_KEY_LEN_WEP104) + key4 &= 0xff; + + /* + * Note: Key cache registers access special memory area that requires + * two 32-bit writes to actually update the values in the internal + * memory. Consequently, the exact order and pairs used here must be + * maintained. + */ + + if (keyType == AR_KEYTABLE_TYPE_TKIP) { + u16 micentry = entry + 64; + + /* + * Write inverted key[47:0] first to avoid Michael MIC errors + * on frames that could be sent or received at the same time. + * The correct key will be written in the end once everything + * else is ready. + */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); + + /* Write key[95:48] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); + + /* Write key[127:96] and key type */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); + + /* Write MAC address for the entry */ + (void) ath_hw_keysetmac(common, entry, mac); + + if (common->splitmic == 0) { + /* + * TKIP uses two key cache entries: + * Michael MIC TX/RX keys in the same key cache entry + * (idx = main index + 64): + * key0 [31:0] = RX key [31:0] + * key1 [15:0] = TX key [31:16] + * key1 [31:16] = reserved + * key2 [31:0] = RX key [63:32] + * key3 [15:0] = TX key [15:0] + * key3 [31:16] = reserved + * key4 [31:0] = TX key [63:32] + */ + u32 mic0, mic1, mic2, mic3, mic4; + + mic0 = get_unaligned_le32(k->kv_mic + 0); + mic2 = get_unaligned_le32(k->kv_mic + 4); + mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; + mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; + mic4 = get_unaligned_le32(k->kv_txmic + 4); + + /* Write RX[31:0] and TX[31:16] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); + + /* Write RX[63:32] and TX[15:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); + + /* Write TX[63:32] and keyType(reserved) */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + + } else { + /* + * TKIP uses four key cache entries (two for group + * keys): + * Michael MIC TX/RX keys are in different key cache + * entries (idx = main index + 64 for TX and + * main index + 32 + 96 for RX): + * key0 [31:0] = TX/RX MIC key [31:0] + * key1 [31:0] = reserved + * key2 [31:0] = TX/RX MIC key [63:32] + * key3 [31:0] = reserved + * key4 [31:0] = reserved + * + * Upper layer code will call this function separately + * for TX and RX keys when these registers offsets are + * used. + */ + u32 mic0, mic2; + + mic0 = get_unaligned_le32(k->kv_mic + 0); + mic2 = get_unaligned_le32(k->kv_mic + 4); + + /* Write MIC key[31:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); + + /* Write MIC key[63:32] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); + + /* Write TX[63:32] and keyType(reserved) */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + } + + /* MAC address registers are reserved for the MIC entry */ + REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); + + /* + * Write the correct (un-inverted) key[47:0] last to enable + * TKIP now that all other registers are set with correct + * values. + */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); + } else { + /* Write key[47:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); + + /* Write key[95:48] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); + + /* Write key[127:96] and key type */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); + + /* Write MAC address for the entry */ + (void) ath_hw_keysetmac(common, entry, mac); + } + + return true; +} + +static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, + struct ath_keyval *hk, const u8 *addr, + bool authenticator) +{ + const u8 *key_rxmic; + const u8 *key_txmic; + + key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; + key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; + + if (addr == NULL) { + /* + * Group key installation - only two key cache entries are used + * regardless of splitmic capability since group key is only + * used either for TX or RX. + */ + if (authenticator) { + memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); + } else { + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); + } + return ath_hw_set_keycache_entry(common, keyix, hk, addr); + } + if (!common->splitmic) { + /* TX and RX keys share the same key cache entry. */ + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); + return ath_hw_set_keycache_entry(common, keyix, hk, addr); + } + + /* Separate key cache entries for TX and RX */ + + /* TX key goes at first index, RX key at +32. */ + memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); + if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) { + /* TX MIC entry failed. No need to proceed further */ + ath_print(common, ATH_DBG_FATAL, + "Setting TX MIC Key Failed\n"); + return 0; + } + + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + /* XXX delete tx key on failure? */ + return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr); +} + +static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) +{ + int i; + + for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { + if (test_bit(i, common->keymap) || + test_bit(i + 64, common->keymap)) + continue; /* At least one part of TKIP key allocated */ + if (common->splitmic && + (test_bit(i + 32, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + continue; /* At least one part of TKIP key allocated */ + + /* Found a free slot for a TKIP key */ + return i; + } + return -1; +} + +static int ath_reserve_key_cache_slot(struct ath_common *common, + u32 cipher) +{ + int i; + + if (cipher == WLAN_CIPHER_SUITE_TKIP) + return ath_reserve_key_cache_slot_tkip(common); + + /* First, try to find slots that would not be available for TKIP. */ + if (common->splitmic) { + for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { + if (!test_bit(i, common->keymap) && + (test_bit(i + 32, common->keymap) || + test_bit(i + 64, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i; + if (!test_bit(i + 32, common->keymap) && + (test_bit(i, common->keymap) || + test_bit(i + 64, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i + 32; + if (!test_bit(i + 64, common->keymap) && + (test_bit(i , common->keymap) || + test_bit(i + 32, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i + 64; + if (!test_bit(i + 64 + 32, common->keymap) && + (test_bit(i, common->keymap) || + test_bit(i + 32, common->keymap) || + test_bit(i + 64, common->keymap))) + return i + 64 + 32; + } + } else { + for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { + if (!test_bit(i, common->keymap) && + test_bit(i + 64, common->keymap)) + return i; + if (test_bit(i, common->keymap) && + !test_bit(i + 64, common->keymap)) + return i + 64; + } + } + + /* No partially used TKIP slots, pick any available slot */ + for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { + /* Do not allow slots that could be needed for TKIP group keys + * to be used. This limitation could be removed if we know that + * TKIP will not be used. */ + if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) + continue; + if (common->splitmic) { + if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) + continue; + if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) + continue; + } + + if (!test_bit(i, common->keymap)) + return i; /* Found a free slot for a key */ + } + + /* No free slot found */ + return -1; +} + +/* + * Configure encryption in the HW. + */ +int ath_key_config(struct ath_common *common, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ath_keyval hk; + const u8 *mac = NULL; + u8 gmac[ETH_ALEN]; + int ret = 0; + int idx; + + memset(&hk, 0, sizeof(hk)); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + hk.kv_type = ATH_CIPHER_WEP; + break; + case WLAN_CIPHER_SUITE_TKIP: + hk.kv_type = ATH_CIPHER_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + hk.kv_type = ATH_CIPHER_AES_CCM; + break; + default: + return -EOPNOTSUPP; + } + + hk.kv_len = key->keylen; + memcpy(hk.kv_val, key->key, key->keylen); + + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + switch (vif->type) { + case NL80211_IFTYPE_AP: + memcpy(gmac, vif->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->cipher); + break; + case NL80211_IFTYPE_ADHOC: + if (!sta) { + idx = key->keyidx; + break; + } + memcpy(gmac, sta->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->cipher); + break; + default: + idx = key->keyidx; + break; + } + } else if (key->keyidx) { + if (WARN_ON(!sta)) + return -EOPNOTSUPP; + mac = sta->addr; + + if (vif->type != NL80211_IFTYPE_AP) { + /* Only keyidx 0 should be used with unicast key, but + * allow this for client mode for now. */ + idx = key->keyidx; + } else + return -EIO; + } else { + if (WARN_ON(!sta)) + return -EOPNOTSUPP; + mac = sta->addr; + + idx = ath_reserve_key_cache_slot(common, key->cipher); + } + + if (idx < 0) + return -ENOSPC; /* no free key cache entries */ + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, + vif->type == NL80211_IFTYPE_AP); + else + ret = ath_hw_set_keycache_entry(common, idx, &hk, mac); + + if (!ret) + return -EIO; + + set_bit(idx, common->keymap); + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + set_bit(idx + 64, common->keymap); + set_bit(idx, common->tkip_keymap); + set_bit(idx + 64, common->tkip_keymap); + if (common->splitmic) { + set_bit(idx + 32, common->keymap); + set_bit(idx + 64 + 32, common->keymap); + set_bit(idx + 32, common->tkip_keymap); + set_bit(idx + 64 + 32, common->tkip_keymap); + } + } + + return idx; +} +EXPORT_SYMBOL(ath_key_config); + +/* + * Delete Key. + */ +void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) +{ + ath_hw_keyreset(common, key->hw_key_idx); + if (key->hw_key_idx < IEEE80211_WEP_NKID) + return; + + clear_bit(key->hw_key_idx, common->keymap); + if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + return; + + clear_bit(key->hw_key_idx + 64, common->keymap); + + clear_bit(key->hw_key_idx, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + + if (common->splitmic) { + ath_hw_keyreset(common, key->hw_key_idx + 32); + clear_bit(key->hw_key_idx + 32, common->keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + + clear_bit(key->hw_key_idx + 32, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + } +} +EXPORT_SYMBOL(ath_key_delete); diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h index dfe1fbec24f5..e798ef476581 100644 --- a/drivers/net/wireless/ath/reg.h +++ b/drivers/net/wireless/ath/reg.h @@ -24,4 +24,27 @@ #define AR_BSSMSKL 0x80e0 #define AR_BSSMSKU 0x80e4 +#define AR_KEYTABLE_0 0x8800 +#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) +#define AR_KEY_CACHE_SIZE 128 +#define AR_RSVD_KEYTABLE_ENTRIES 4 +#define AR_KEY_TYPE 0x00000007 +#define AR_KEYTABLE_TYPE_40 0x00000000 +#define AR_KEYTABLE_TYPE_104 0x00000001 +#define AR_KEYTABLE_TYPE_128 0x00000003 +#define AR_KEYTABLE_TYPE_TKIP 0x00000004 +#define AR_KEYTABLE_TYPE_AES 0x00000005 +#define AR_KEYTABLE_TYPE_CCM 0x00000006 +#define AR_KEYTABLE_TYPE_CLR 0x00000007 +#define AR_KEYTABLE_ANT 0x00000008 +#define AR_KEYTABLE_VALID 0x00008000 +#define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0) +#define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4) +#define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8) +#define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12) +#define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16) +#define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20) +#define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24) +#define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28) + #endif /* ATH_REGISTERS_H */ -- cgit v1.2.3 From e0f8c2a9b879e1e65d588a40a3c88db69a7d6956 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:43 +0900 Subject: ath5k: Use common ath key management functions Use common ath key management functions in ath5k. This fixes problems with HW encryption in AP mode, which was broken in the ath5k implementation. Before (with the ath5k implementation) only one client could connect to the AP using HW encryption and WPA. When a second client connected, the first client was not able to send/receive any more packets. Because of the problems with HW encryption, software encryption was always used in AP mode, which resulted in a high CPU load (and/or low thruput) on embedded devices. Instead of trying to fix the implementation in ath5k it makes more sense to share the code with ath9k. This also enables HW encryption for AP mode again. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 3 +++ drivers/net/wireless/ath/ath5k/base.c | 33 ++++++++++++++------------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index aabad4f13e2a..eb125d69fb78 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -314,6 +314,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc) } /* Crypto settings */ + common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? + AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); + ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 45789c8990d3..7933646583a9 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2570,6 +2570,7 @@ static int ath5k_init(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); int ret, i; mutex_lock(&sc->lock); @@ -2605,8 +2606,8 @@ ath5k_init(struct ath5k_softc *sc) * Reset the key cache since some parts do not reset the * contents on initial power up or resume from suspend. */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); + for (i = 0; i < common->keymax; i++) + ath_hw_keyreset(common, (u16)i); ath5k_hw_set_ack_bitrate_high(ah, true); ret = 0; @@ -3287,9 +3288,6 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (modparam_nohwcrypt) return -EOPNOTSUPP; - if (sc->opmode == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; - switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: @@ -3298,7 +3296,6 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case WLAN_CIPHER_SUITE_CCMP: if (sc->ah->ah_aes_support) break; - return -EOPNOTSUPP; default: WARN_ON(1); @@ -3309,27 +3306,25 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: - ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, - sta ? sta->addr : NULL); - if (ret) { - ATH5K_ERR(sc, "can't set the key\n"); - goto unlock; + ret = ath_key_config(common, vif, sta, key); + if (ret >= 0) { + key->hw_key_idx = ret; + /* push IV and Michael MIC generation to stack */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + ret = 0; } - __set_bit(key->keyidx, common->keymap); - key->hw_key_idx = key->keyidx; - key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | - IEEE80211_KEY_FLAG_GENERATE_MMIC); break; case DISABLE_KEY: - ath5k_hw_reset_key(sc->ah, key->keyidx); - __clear_bit(key->keyidx, common->keymap); + ath_key_delete(common, key); break; default: ret = -EINVAL; - goto unlock; } -unlock: mmiowb(); mutex_unlock(&sc->lock); return ret; -- cgit v1.2.3 From d8878f83cf1cc0061e8b3bcf7dbd589410a51039 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:49 +0900 Subject: ath5k: Remove old ath5k key handling functions Remove the old ath5k key handling functions, since we now use the key management in ath common. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 5 - drivers/net/wireless/ath/ath5k/pcu.c | 191 --------------------------------- drivers/net/wireless/ath/ath5k/reg.h | 42 -------- 3 files changed, 238 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index f399c4dd8e69..932ed5613355 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1207,11 +1207,6 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); -/* Key table (WEP) functions */ -int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); -int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, - const struct ieee80211_key_conf *key, const u8 *mac); -int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); /* Queue Control Unit, DFS Control Unit Functions */ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index bb2e21553d1b..6a891c4484a0 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -640,197 +640,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) } - -/*********************\ -* Key table functions * -\*********************/ - -/* - * Reset a key entry on the table - */ -int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) -{ - unsigned int i, type; - u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; - - AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); - - type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); - - for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); - - /* Reset associated MIC entry if TKIP - * is enabled located at offset (entry + 64) */ - if (type == AR5K_KEYTABLE_TYPE_TKIP) { - AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE); - for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) - ath5k_hw_reg_write(ah, 0, - AR5K_KEYTABLE_OFF(micentry, i)); - } - - /* - * Set NULL encryption on AR5212+ - * - * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) - * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 - * - * Note2: Windows driver (ndiswrapper) sets this to - * 0x00000714 instead of 0x00000007 - */ - if (ah->ah_version >= AR5K_AR5211) { - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(entry)); - - if (type == AR5K_KEYTABLE_TYPE_TKIP) { - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(micentry)); - } - } - - return 0; -} - -static -int ath5k_keycache_type(const struct ieee80211_key_conf *key) -{ - switch (key->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - return AR5K_KEYTABLE_TYPE_TKIP; - case WLAN_CIPHER_SUITE_CCMP: - return AR5K_KEYTABLE_TYPE_CCM; - case WLAN_CIPHER_SUITE_WEP40: - return AR5K_KEYTABLE_TYPE_40; - case WLAN_CIPHER_SUITE_WEP104: - return AR5K_KEYTABLE_TYPE_104; - default: - return -EINVAL; - } -} - -/* - * Set a key entry on the table - */ -int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, - const struct ieee80211_key_conf *key, const u8 *mac) -{ - unsigned int i; - int keylen; - __le32 key_v[5] = {}; - __le32 key0 = 0, key1 = 0; - __le32 *rxmic, *txmic; - int keytype; - u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; - bool is_tkip; - const u8 *key_ptr; - - is_tkip = (key->cipher == WLAN_CIPHER_SUITE_TKIP); - - /* - * key->keylen comes in from mac80211 in bytes. - * TKIP is 128 bit + 128 bit mic - */ - keylen = (is_tkip) ? (128 / 8) : key->keylen; - - if (entry > AR5K_KEYTABLE_SIZE || - (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) - return -EOPNOTSUPP; - - if (unlikely(keylen > 16)) - return -EOPNOTSUPP; - - keytype = ath5k_keycache_type(key); - if (keytype < 0) - return keytype; - - /* - * each key block is 6 bytes wide, written as pairs of - * alternating 32 and 16 bit le values. - */ - key_ptr = key->key; - for (i = 0; keylen >= 6; keylen -= 6) { - memcpy(&key_v[i], key_ptr, 6); - i += 2; - key_ptr += 6; - } - if (keylen) - memcpy(&key_v[i], key_ptr, keylen); - - /* intentionally corrupt key until mic is installed */ - if (is_tkip) { - key0 = key_v[0] = ~key_v[0]; - key1 = key_v[1] = ~key_v[1]; - } - - for (i = 0; i < ARRAY_SIZE(key_v); i++) - ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), - AR5K_KEYTABLE_OFF(entry, i)); - - ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); - - if (is_tkip) { - /* Install rx/tx MIC */ - rxmic = (__le32 *) &key->key[16]; - txmic = (__le32 *) &key->key[24]; - - if (ah->ah_combined_mic) { - key_v[0] = rxmic[0]; - key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16); - key_v[2] = rxmic[1]; - key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff); - key_v[4] = txmic[1]; - } else { - key_v[0] = rxmic[0]; - key_v[1] = 0; - key_v[2] = rxmic[1]; - key_v[3] = 0; - key_v[4] = 0; - } - for (i = 0; i < ARRAY_SIZE(key_v); i++) - ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), - AR5K_KEYTABLE_OFF(micentry, i)); - - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(micentry)); - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry)); - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry)); - - /* restore first 2 words of key */ - ath5k_hw_reg_write(ah, le32_to_cpu(~key0), - AR5K_KEYTABLE_OFF(entry, 0)); - ath5k_hw_reg_write(ah, le32_to_cpu(~key1), - AR5K_KEYTABLE_OFF(entry, 1)); - } - - return ath5k_hw_set_key_lladdr(ah, entry, mac); -} - -int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) -{ - u32 low_id, high_id; - - /* Invalid entry (key table overflow) */ - AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); - - /* - * MAC may be NULL if it's a broadcast key. In this case no need to - * to compute get_unaligned_le32 and get_unaligned_le16 as we - * already know it. - */ - if (!mac) { - low_id = 0xffffffff; - high_id = 0xffff | AR5K_KEYTABLE_VALID; - } else { - low_id = get_unaligned_le32(mac); - high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID; - } - - ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); - ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); - - return 0; -} - /** * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class * diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 05ef587ad2b4..67d63081705a 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -1822,50 +1822,8 @@ /*===5212 end===*/ -/* - * Key table (WEP) register - */ -#define AR5K_KEYTABLE_0_5210 0x9000 -#define AR5K_KEYTABLE_0_5211 0x8800 -#define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5)) -#define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5)) -#define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \ - AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n)) -#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2)) -#define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5) -#define AR5K_KEYTABLE_TYPE_40 0x00000000 -#define AR5K_KEYTABLE_TYPE_104 0x00000001 -#define AR5K_KEYTABLE_TYPE_128 0x00000003 -#define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */ -#define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */ -#define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */ -#define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */ -#define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */ -#define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6) -#define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) -#define AR5K_KEYTABLE_VALID 0x00008000 - -/* If key type is TKIP and MIC is enabled - * MIC key goes in offset entry + 64 */ -#define AR5K_KEYTABLE_MIC_OFFSET 64 - -/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit - * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit - * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit - * - * Some vendors have introduced bigger WEP keys to address - * security vulnerabilities in WEP. This includes: - * - * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit - * - * We can expand this if we find ar5k Atheros cards with a larger - * key table size. - */ #define AR5K_KEYTABLE_SIZE_5210 64 #define AR5K_KEYTABLE_SIZE_5211 128 -#define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \ - AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211) - /*===PHY REGISTERS===*/ -- cgit v1.2.3 From 117675d06ad2dd16fcf466669ba9700a8d589ea3 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:54 +0900 Subject: ath/ath9k: Replace common->splitmic with a flag Replace common->splitmic with ATH_CRYPT_CAP_MIC_COMBINED flag. splitmic has to be used when the ATH_CRYPT_CAP_MIC_COMBINED capability flag is not set. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 +- drivers/net/wireless/ath/ath9k/common.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/init.c | 4 ++-- drivers/net/wireless/ath/key.c | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index fb24f66373fd..c5584077d1de 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -78,6 +78,7 @@ enum ath_crypt_caps { ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(3), ATH_CRYPT_CAP_CIPHER_CKIP = BIT(4), ATH_CRYPT_CAP_CIPHER_TKIP = BIT(5), + ATH_CRYPT_CAP_MIC_COMBINED = BIT(6), }; struct ath_keyval { @@ -150,7 +151,6 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); - u8 splitmic; enum ath_crypt_caps crypt_caps; struct ath_regulatory regulatory; diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 2dab64bb23a8..2db24eb5f0ee 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -174,7 +174,7 @@ static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, } return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); } - if (!common->splitmic) { + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { /* TX and RX keys share the same key cache entry. */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); @@ -205,7 +205,7 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) if (test_bit(i, common->keymap) || test_bit(i + 64, common->keymap)) continue; /* At least one part of TKIP key allocated */ - if (common->splitmic && + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) && (test_bit(i + 32, common->keymap) || test_bit(i + 64 + 32, common->keymap))) continue; /* At least one part of TKIP key allocated */ @@ -225,7 +225,7 @@ static int ath_reserve_key_cache_slot(struct ath_common *common, return ath_reserve_key_cache_slot_tkip(common); /* First, try to find slots that would not be available for TKIP. */ - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { if (!test_bit(i, common->keymap) && (test_bit(i + 32, common->keymap) || @@ -266,7 +266,7 @@ static int ath_reserve_key_cache_slot(struct ath_common *common, * TKIP will not be used. */ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) continue; - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) continue; if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) @@ -374,7 +374,7 @@ int ath9k_cmn_key_config(struct ath_common *common, set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); set_bit(idx + 64, common->tkip_keymap); - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { set_bit(idx + 32, common->keymap); set_bit(idx + 64 + 32, common->keymap); set_bit(idx + 32, common->tkip_keymap); @@ -407,7 +407,7 @@ void ath9k_cmn_key_delete(struct ath_common *common, clear_bit(key->hw_key_idx, common->tkip_keymap); clear_bit(key->hw_key_idx + 64, common->tkip_keymap); - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { ath9k_hw_keyreset(ah, key->hw_key_idx + 32); clear_bit(key->hw_key_idx + 32, common->keymap); clear_bit(key->hw_key_idx + 64 + 32, common->keymap); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5c77a9913e03..fd651d8ef816 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -389,8 +389,8 @@ static void ath9k_init_crypto(struct ath_softc *sc) * With split mic keys the number of stations is limited * to 27 otherwise 59. */ - if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)) - common->splitmic = 1; + if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; } static int ath9k_init_btcoex(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index e45b8546810a..bd21a4d82085 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -201,7 +201,7 @@ bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, /* Write MAC address for the entry */ (void) ath_hw_keysetmac(common, entry, mac); - if (common->splitmic == 0) { + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { /* * TKIP uses two key cache entries: * Michael MIC TX/RX keys in the same key cache entry @@ -327,7 +327,7 @@ static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, } return ath_hw_set_keycache_entry(common, keyix, hk, addr); } - if (!common->splitmic) { + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { /* TX and RX keys share the same key cache entry. */ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); @@ -358,7 +358,7 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) if (test_bit(i, common->keymap) || test_bit(i + 64, common->keymap)) continue; /* At least one part of TKIP key allocated */ - if (common->splitmic && + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) && (test_bit(i + 32, common->keymap) || test_bit(i + 64 + 32, common->keymap))) continue; /* At least one part of TKIP key allocated */ @@ -378,7 +378,7 @@ static int ath_reserve_key_cache_slot(struct ath_common *common, return ath_reserve_key_cache_slot_tkip(common); /* First, try to find slots that would not be available for TKIP. */ - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { if (!test_bit(i, common->keymap) && (test_bit(i + 32, common->keymap) || @@ -419,7 +419,7 @@ static int ath_reserve_key_cache_slot(struct ath_common *common, * TKIP will not be used. */ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) continue; - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) continue; if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) @@ -526,7 +526,7 @@ int ath_key_config(struct ath_common *common, set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); set_bit(idx + 64, common->tkip_keymap); - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { set_bit(idx + 32, common->keymap); set_bit(idx + 64 + 32, common->keymap); set_bit(idx + 32, common->tkip_keymap); @@ -556,7 +556,7 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) clear_bit(key->hw_key_idx, common->tkip_keymap); clear_bit(key->hw_key_idx + 64, common->tkip_keymap); - if (common->splitmic) { + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { ath_hw_keyreset(common, key->hw_key_idx + 32); clear_bit(key->hw_key_idx + 32, common->keymap); clear_bit(key->hw_key_idx + 64 + 32, common->keymap); -- cgit v1.2.3 From 781f3136ff4cdd2b33149f2295fefa21f77b1c56 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:04:59 +0900 Subject: ath5k: Use common crypt capabilities flags Replace ah_aes_support and ah_combined_mic with common ath_crypt_caps ATH_CRYPT_CAP_CIPHER_AESCCM and ATH_CRYPT_CAP_MIC_COMBINED. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 -- drivers/net/wireless/ath/ath5k/attach.c | 10 ++++++---- drivers/net/wireless/ath/ath5k/base.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 932ed5613355..50209aed0ed2 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1028,8 +1028,6 @@ struct ath5k_hw { bool ah_turbo; bool ah_calibration; bool ah_single_chip; - bool ah_aes_support; - bool ah_combined_mic; enum ath5k_version ah_version; enum ath5k_radio ah_radio; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index eb125d69fb78..a0e08201c939 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -317,12 +317,14 @@ int ath5k_hw_attach(struct ath5k_softc *sc) common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); - ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && - (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && - !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); + if (srev >= AR5K_SREV_AR5212_V4 && + (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && + !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) + common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM | + ATH_CRYPT_CAP_MIC_AESCCM; if (srev >= AR5K_SREV_AR2414) { - ah->ah_combined_mic = true; + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, AR5K_MISC_MODE_COMBINED_MIC); } diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 7933646583a9..0709bb091b2f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3294,7 +3294,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case WLAN_CIPHER_SUITE_TKIP: break; case WLAN_CIPHER_SUITE_CCMP: - if (sc->ah->ah_aes_support) + if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) break; return -EOPNOTSUPP; default: -- cgit v1.2.3 From 040e539e8e8d5585e1c3d7d15fa7215d3a691258 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 8 Sep 2010 16:05:04 +0900 Subject: ath9k: Use common ath key management functions Use key management functions which have been moved to ath/key.c and remove ath9k copies of these functions and other now unused definitions. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common.c | 270 ------------------------- drivers/net/wireless/ath/ath9k/common.h | 6 - drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 +- drivers/net/wireless/ath/ath9k/hw.c | 271 -------------------------- drivers/net/wireless/ath/ath9k/hw.h | 6 - drivers/net/wireless/ath/ath9k/init.c | 2 +- drivers/net/wireless/ath/ath9k/mac.h | 21 -- drivers/net/wireless/ath/ath9k/main.c | 4 +- drivers/net/wireless/ath/ath9k/phy.h | 3 - 10 files changed, 6 insertions(+), 583 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 2db24eb5f0ee..f43a2d98421c 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -148,276 +148,6 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ath9k_cmn_get_curchannel); -static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, - struct ath9k_keyval *hk, const u8 *addr, - bool authenticator) -{ - struct ath_hw *ah = common->ah; - const u8 *key_rxmic; - const u8 *key_txmic; - - key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; - key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; - - if (addr == NULL) { - /* - * Group key installation - only two key cache entries are used - * regardless of splitmic capability since group key is only - * used either for TX or RX. - */ - if (authenticator) { - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); - } else { - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); - } - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { - /* TX and RX keys share the same key cache entry. */ - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - - /* Separate key cache entries for TX and RX */ - - /* TX key goes at first index, RX key at +32. */ - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { - /* TX MIC entry failed. No need to proceed further */ - ath_print(common, ATH_DBG_FATAL, - "Setting TX MIC Key Failed\n"); - return 0; - } - - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - /* XXX delete tx key on failure? */ - return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); -} - -static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) -{ - int i; - - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap)) - continue; /* At least one part of TKIP key allocated */ - if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - continue; /* At least one part of TKIP key allocated */ - - /* Found a free slot for a TKIP key */ - return i; - } - return -1; -} - -static int ath_reserve_key_cache_slot(struct ath_common *common, - u32 cipher) -{ - int i; - - if (cipher == WLAN_CIPHER_SUITE_TKIP) - return ath_reserve_key_cache_slot_tkip(common); - - /* First, try to find slots that would not be available for TKIP. */ - if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { - if (!test_bit(i, common->keymap) && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i; - if (!test_bit(i + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 32; - if (!test_bit(i + 64, common->keymap) && - (test_bit(i , common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 64; - if (!test_bit(i + 64 + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap))) - return i + 64 + 32; - } - } else { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (!test_bit(i, common->keymap) && - test_bit(i + 64, common->keymap)) - return i; - if (test_bit(i, common->keymap) && - !test_bit(i + 64, common->keymap)) - return i + 64; - } - } - - /* No partially used TKIP slots, pick any available slot */ - for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { - /* Do not allow slots that could be needed for TKIP group keys - * to be used. This limitation could be removed if we know that - * TKIP will not be used. */ - if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) - continue; - if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) - continue; - if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) - continue; - } - - if (!test_bit(i, common->keymap)) - return i; /* Found a free slot for a key */ - } - - /* No free slot found */ - return -1; -} - -/* - * Configure encryption in the HW. - */ -int ath9k_cmn_key_config(struct ath_common *common, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct ath_hw *ah = common->ah; - struct ath9k_keyval hk; - const u8 *mac = NULL; - u8 gmac[ETH_ALEN]; - int ret = 0; - int idx; - - memset(&hk, 0, sizeof(hk)); - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - hk.kv_type = ATH9K_CIPHER_WEP; - break; - case WLAN_CIPHER_SUITE_TKIP: - hk.kv_type = ATH9K_CIPHER_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - hk.kv_type = ATH9K_CIPHER_AES_CCM; - break; - default: - return -EOPNOTSUPP; - } - - hk.kv_len = key->keylen; - memcpy(hk.kv_val, key->key, key->keylen); - - if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - switch (vif->type) { - case NL80211_IFTYPE_AP: - memcpy(gmac, vif->addr, ETH_ALEN); - gmac[0] |= 0x01; - mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->cipher); - break; - case NL80211_IFTYPE_ADHOC: - if (!sta) { - idx = key->keyidx; - break; - } - memcpy(gmac, sta->addr, ETH_ALEN); - gmac[0] |= 0x01; - mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->cipher); - break; - default: - idx = key->keyidx; - break; - } - } else if (key->keyidx) { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - if (vif->type != NL80211_IFTYPE_AP) { - /* Only keyidx 0 should be used with unicast key, but - * allow this for client mode for now. */ - idx = key->keyidx; - } else - return -EIO; - } else { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - idx = ath_reserve_key_cache_slot(common, key->cipher); - } - - if (idx < 0) - return -ENOSPC; /* no free key cache entries */ - - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) - ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, - vif->type == NL80211_IFTYPE_AP); - else - ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); - - if (!ret) - return -EIO; - - set_bit(idx, common->keymap); - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - set_bit(idx + 64, common->keymap); - set_bit(idx, common->tkip_keymap); - set_bit(idx + 64, common->tkip_keymap); - if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - set_bit(idx + 32, common->keymap); - set_bit(idx + 64 + 32, common->keymap); - set_bit(idx + 32, common->tkip_keymap); - set_bit(idx + 64 + 32, common->tkip_keymap); - } - } - - return idx; -} -EXPORT_SYMBOL(ath9k_cmn_key_config); - -/* - * Delete Key. - */ -void ath9k_cmn_key_delete(struct ath_common *common, - struct ieee80211_key_conf *key) -{ - struct ath_hw *ah = common->ah; - - ath9k_hw_keyreset(ah, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) - return; - - clear_bit(key->hw_key_idx, common->keymap); - if (key->cipher != WLAN_CIPHER_SUITE_TKIP) - return; - - clear_bit(key->hw_key_idx + 64, common->keymap); - - clear_bit(key->hw_key_idx, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64, common->tkip_keymap); - - if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - ath9k_hw_keyreset(ah, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); - - clear_bit(key->hw_key_idx + 32, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); - } -} -EXPORT_SYMBOL(ath9k_cmn_key_delete); - int ath9k_cmn_count_streams(unsigned int chainmask, int max) { int streams = 0; diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 4aa4e7dbe4d2..fea3b3315391 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -66,12 +66,6 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, struct ath9k_channel *ichan); struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, struct ath_hw *ah); -int ath9k_cmn_key_config(struct ath_common *common, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); -void ath9k_cmn_key_delete(struct ath_common *common, - struct ieee80211_key_conf *key); int ath9k_cmn_count_streams(unsigned int chainmask, int max); void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 717f2b821f0d..33850c952314 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) * reset the contents on initial power up. */ for (i = 0; i < common->keymax; i++) - ath9k_hw_keyreset(priv->ah, (u16) i); + ath_hw_keyreset(common, (u16) i); } static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index bab894873bf5..5124d04b240b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1590,7 +1590,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - ret = ath9k_cmn_key_config(common, vif, sta, key); + ret = ath_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ @@ -1604,7 +1604,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath9k_cmn_key_delete(common, key); + ath_key_delete(common, key); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 40c6451602d3..f3c9d7549571 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1476,277 +1476,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } EXPORT_SYMBOL(ath9k_hw_reset); -/************************/ -/* Key Cache Management */ -/************************/ - -bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) -{ - u32 keyType; - - if (entry >= ah->caps.keycache_size) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); - return false; - } - - keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); - - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); - REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); - - if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { - u16 micentry = entry + 64; - - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); - - } - - return true; -} -EXPORT_SYMBOL(ath9k_hw_keyreset); - -static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) -{ - u32 macHi, macLo; - u32 unicast_flag = AR_KEYTABLE_VALID; - - if (entry >= ah->caps.keycache_size) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); - return false; - } - - if (mac != NULL) { - /* - * AR_KEYTABLE_VALID indicates that the address is a unicast - * address, which must match the transmitter address for - * decrypting frames. - * Not setting this bit allows the hardware to use the key - * for multicast frame decryption. - */ - if (mac[0] & 0x01) - unicast_flag = 0; - - macHi = (mac[5] << 8) | mac[4]; - macLo = (mac[3] << 24) | - (mac[2] << 16) | - (mac[1] << 8) | - mac[0]; - macLo >>= 1; - macLo |= (macHi & 1) << 31; - macHi >>= 1; - } else { - macLo = macHi = 0; - } - REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); - REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); - - return true; -} - -bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, - const struct ath9k_keyval *k, - const u8 *mac) -{ - const struct ath9k_hw_capabilities *pCap = &ah->caps; - struct ath_common *common = ath9k_hw_common(ah); - u32 key0, key1, key2, key3, key4; - u32 keyType; - - if (entry >= pCap->keycache_size) { - ath_print(common, ATH_DBG_FATAL, - "keycache entry %u out of range\n", entry); - return false; - } - - switch (k->kv_type) { - case ATH9K_CIPHER_AES_OCB: - keyType = AR_KEYTABLE_TYPE_AES; - break; - case ATH9K_CIPHER_AES_CCM: - keyType = AR_KEYTABLE_TYPE_CCM; - break; - case ATH9K_CIPHER_TKIP: - keyType = AR_KEYTABLE_TYPE_TKIP; - if (ATH9K_IS_MIC_ENABLED(ah) - && entry + 64 >= pCap->keycache_size) { - ath_print(common, ATH_DBG_ANY, - "entry %u inappropriate for TKIP\n", entry); - return false; - } - break; - case ATH9K_CIPHER_WEP: - if (k->kv_len < WLAN_KEY_LEN_WEP40) { - ath_print(common, ATH_DBG_ANY, - "WEP key length %u too small\n", k->kv_len); - return false; - } - if (k->kv_len <= WLAN_KEY_LEN_WEP40) - keyType = AR_KEYTABLE_TYPE_40; - else if (k->kv_len <= WLAN_KEY_LEN_WEP104) - keyType = AR_KEYTABLE_TYPE_104; - else - keyType = AR_KEYTABLE_TYPE_128; - break; - case ATH9K_CIPHER_CLR: - keyType = AR_KEYTABLE_TYPE_CLR; - break; - default: - ath_print(common, ATH_DBG_FATAL, - "cipher %u not supported\n", k->kv_type); - return false; - } - - key0 = get_unaligned_le32(k->kv_val + 0); - key1 = get_unaligned_le16(k->kv_val + 4); - key2 = get_unaligned_le32(k->kv_val + 6); - key3 = get_unaligned_le16(k->kv_val + 10); - key4 = get_unaligned_le32(k->kv_val + 12); - if (k->kv_len <= WLAN_KEY_LEN_WEP104) - key4 &= 0xff; - - /* - * Note: Key cache registers access special memory area that requires - * two 32-bit writes to actually update the values in the internal - * memory. Consequently, the exact order and pairs used here must be - * maintained. - */ - - if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { - u16 micentry = entry + 64; - - /* - * Write inverted key[47:0] first to avoid Michael MIC errors - * on frames that could be sent or received at the same time. - * The correct key will be written in the end once everything - * else is ready. - */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); - - /* Write key[95:48] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); - - /* Write key[127:96] and key type */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); - - /* Write MAC address for the entry */ - (void) ath9k_hw_keysetmac(ah, entry, mac); - - if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { - /* - * TKIP uses two key cache entries: - * Michael MIC TX/RX keys in the same key cache entry - * (idx = main index + 64): - * key0 [31:0] = RX key [31:0] - * key1 [15:0] = TX key [31:16] - * key1 [31:16] = reserved - * key2 [31:0] = RX key [63:32] - * key3 [15:0] = TX key [15:0] - * key3 [31:16] = reserved - * key4 [31:0] = TX key [63:32] - */ - u32 mic0, mic1, mic2, mic3, mic4; - - mic0 = get_unaligned_le32(k->kv_mic + 0); - mic2 = get_unaligned_le32(k->kv_mic + 4); - mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; - mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; - mic4 = get_unaligned_le32(k->kv_txmic + 4); - - /* Write RX[31:0] and TX[31:16] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); - - /* Write RX[63:32] and TX[15:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); - - /* Write TX[63:32] and keyType(reserved) */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), - AR_KEYTABLE_TYPE_CLR); - - } else { - /* - * TKIP uses four key cache entries (two for group - * keys): - * Michael MIC TX/RX keys are in different key cache - * entries (idx = main index + 64 for TX and - * main index + 32 + 96 for RX): - * key0 [31:0] = TX/RX MIC key [31:0] - * key1 [31:0] = reserved - * key2 [31:0] = TX/RX MIC key [63:32] - * key3 [31:0] = reserved - * key4 [31:0] = reserved - * - * Upper layer code will call this function separately - * for TX and RX keys when these registers offsets are - * used. - */ - u32 mic0, mic2; - - mic0 = get_unaligned_le32(k->kv_mic + 0); - mic2 = get_unaligned_le32(k->kv_mic + 4); - - /* Write MIC key[31:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); - - /* Write MIC key[63:32] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); - - /* Write TX[63:32] and keyType(reserved) */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), - AR_KEYTABLE_TYPE_CLR); - } - - /* MAC address registers are reserved for the MIC entry */ - REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); - - /* - * Write the correct (un-inverted) key[47:0] last to enable - * TKIP now that all other registers are set with correct - * values. - */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); - } else { - /* Write key[47:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); - - /* Write key[95:48] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); - - /* Write key[127:96] and key type */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); - - /* Write MAC address for the entry */ - (void) ath9k_hw_keysetmac(ah, entry, mac); - } - - return true; -} -EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); - /******************************/ /* Power Management (Chipset) */ /******************************/ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a3c2ce235123..df47f792cf4e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -870,12 +870,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, int ath9k_hw_fill_cap_info(struct ath_hw *ah); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); -/* Key Cache Management */ -bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); -bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, - const struct ath9k_keyval *k, - const u8 *mac); - /* GPIO / RFKILL / Antennae */ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index fd651d8ef816..224df6d8fe2c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -381,7 +381,7 @@ static void ath9k_init_crypto(struct ath_softc *sc) * reset the contents on initial power up. */ for (i = 0; i < common->keymax; i++) - ath9k_hw_keyreset(sc->sc_ah, (u16) i); + ath_hw_keyreset(common, (u16) i); /* * Check whether the separate key cache entries diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 2633896d3998..7c1a34d64f6d 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -660,17 +660,6 @@ struct ath9k_11n_rate_series { u32 RateFlags; }; -struct ath9k_keyval { - u8 kv_type; - u8 kv_pad; - u16 kv_len; - u8 kv_val[16]; /* TK */ - u8 kv_mic[8]; /* Michael MIC key */ - u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware - * supports both MIC keys in the same key cache entry; - * in that case, kv_mic is the RX key) */ -}; - enum ath9k_key_type { ATH9K_KEY_TYPE_CLEAR, ATH9K_KEY_TYPE_WEP, @@ -678,16 +667,6 @@ enum ath9k_key_type { ATH9K_KEY_TYPE_TKIP, }; -enum ath9k_cipher { - ATH9K_CIPHER_WEP = 0, - ATH9K_CIPHER_AES_OCB = 1, - ATH9K_CIPHER_AES_CCM = 2, - ATH9K_CIPHER_CKIP = 3, - ATH9K_CIPHER_TKIP = 4, - ATH9K_CIPHER_CLR = 5, - ATH9K_CIPHER_MIC = 127 -}; - struct ath_hw; struct ath9k_channel; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a2f7eb2a552b..fa875d1c7e91 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1769,7 +1769,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - ret = ath9k_cmn_key_config(common, vif, sta, key); + ret = ath_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ @@ -1783,7 +1783,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath9k_cmn_key_delete(common, key); + ath_key_delete(common, key); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index e724c2c1ae2a..17969af842f6 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -45,9 +45,6 @@ } \ } while (0) -#define ATH9K_IS_MIC_ENABLED(ah) \ - ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE) - #define ANTSWAP_AB 0x0001 #define REDUCE_CHAIN_0 0x00000050 #define REDUCE_CHAIN_1 0x00000051 -- cgit v1.2.3 From cfda669519241fccd5aa66c5a12bdae3dd04d5cd Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 14 Sep 2010 12:00:22 -0700 Subject: ath9k: calcrxfilter should take multiple VIFs into account. When there is more than one VIF, listen for all beacons and ensure ATH9K_RX_FILTER_MCAST_BCAST_ALL is set. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6fb3b4536045..9eceeae28e7e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -448,6 +448,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt |= ATH9K_RX_FILTER_CONTROL; if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && + (sc->nvifs <= 1) && !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) rfilt |= ATH9K_RX_FILTER_MYBEACON; else @@ -462,9 +463,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (conf_is_ht(&sc->hw->conf)) rfilt |= ATH9K_RX_FILTER_COMP_BAR; - if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) { - /* TODO: only needed if more than one BSSID is in use in - * station/adhoc mode */ + if (sc->sec_wiphy || (sc->nvifs > 1) || + (sc->rx.rxfilter & FIF_OTHER_BSS)) { /* The following may also be needed for other older chips */ if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) rfilt |= ATH9K_RX_FILTER_PROM; -- cgit v1.2.3 From 3905751243fd84340e027672d2f603e9009d490e Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 14 Sep 2010 12:46:04 -0700 Subject: ath9k: Print rxfilter in debugfs. Print raw and decoded rxfilter in debufs 'wiphy' file. Also, move variable-length printouts to bottom of file to make bounds checking easier. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 53 +++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 54aae931424e..d65a896a421d 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -492,12 +492,55 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, unsigned int len = 0; int i; u8 addr[ETH_ALEN]; + u32 tmp; len += snprintf(buf + len, sizeof(buf) - len, "primary: %s (%s chan=%d ht=%d)\n", wiphy_name(sc->pri_wiphy->hw->wiphy), ath_wiphy_state_str(sc->pri_wiphy->state), sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht); + + put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); + put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); + len += snprintf(buf + len, sizeof(buf) - len, + "addr: %pM\n", addr); + put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr); + put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); + len += snprintf(buf + len, sizeof(buf) - len, + "addrmask: %pM\n", addr); + tmp = ath9k_hw_getrxfilter(sc->sc_ah); + len += snprintf(buf + len, sizeof(buf) - len, + "rfilt: 0x%x", tmp); + if (tmp & ATH9K_RX_FILTER_UCAST) + len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); + if (tmp & ATH9K_RX_FILTER_MCAST) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); + if (tmp & ATH9K_RX_FILTER_BCAST) + len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); + if (tmp & ATH9K_RX_FILTER_CONTROL) + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); + if (tmp & ATH9K_RX_FILTER_BEACON) + len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); + if (tmp & ATH9K_RX_FILTER_PROM) + len += snprintf(buf + len, sizeof(buf) - len, " PROM"); + if (tmp & ATH9K_RX_FILTER_PROBEREQ) + len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); + if (tmp & ATH9K_RX_FILTER_PHYERR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); + if (tmp & ATH9K_RX_FILTER_MYBEACON) + len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); + if (tmp & ATH9K_RX_FILTER_COMP_BAR) + len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); + if (tmp & ATH9K_RX_FILTER_PSPOLL) + len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); + if (tmp & ATH9K_RX_FILTER_PHYRADAR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); + if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n"); + else + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + + /* Put variable-length stuff down here, and check for overflows. */ for (i = 0; i < sc->num_sec_wiphy; i++) { struct ath_wiphy *aphy = sc->sec_wiphy[i]; if (aphy == NULL) @@ -508,16 +551,6 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, ath_wiphy_state_str(aphy->state), aphy->chan_idx, aphy->chan_is_ht); } - - put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); - put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); - len += snprintf(buf + len, sizeof(buf) - len, - "addr: %pM\n", addr); - put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr); - put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); - len += snprintf(buf + len, sizeof(buf) - len, - "addrmask: %pM\n", addr); - if (len > sizeof(buf)) len = sizeof(buf); -- cgit v1.2.3 From f5521b13880f4f4f612e1d20dd4f565122d16e04 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Sep 2010 22:06:53 +0200 Subject: mac80211: use correct station flags lock This code is modifying the station flags, and as such should hold the flags lock so it can do so atomically vs. other flags modifications and readers. This issue was introduced when this code was added in eccb8e8f, as it used the wrong lock (thus not fixing the race that was previously documented in a comment.) Cc: stable@kernel.org [2.6.31+] Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5de1ca3f17b9..171e8ff8e028 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -577,6 +577,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, struct sta_info *sta, struct station_parameters *params) { + unsigned long flags; u32 rates; int i, j; struct ieee80211_supported_band *sband; @@ -585,7 +586,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, sband = local->hw.wiphy->bands[local->oper_channel->band]; - spin_lock_bh(&sta->lock); + spin_lock_irqsave(&sta->flaglock, flags); mask = params->sta_flags_mask; set = params->sta_flags_set; @@ -612,7 +613,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_MFP)) sta->flags |= WLAN_STA_MFP; } - spin_unlock_bh(&sta->lock); + spin_unlock_irqrestore(&sta->flaglock, flags); /* * cfg80211 validates this (1-2007) and allows setting the AID -- cgit v1.2.3 From 46a5ebaf02d69e26ee0f47a0b8d2d9bc619240d4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Sep 2010 13:28:15 +0200 Subject: cfg80211/mac80211: use lockdep_assert_held Instead of using a WARN_ON(!mutex_is_locked()) use lockdep_assert_held() which compiles away completely when lockdep isn't enabled, and also is a more accurate assertion since it checks that the current thread is holding the mutex. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/chan.c | 2 +- net/mac80211/key.c | 2 +- net/mac80211/mlme.c | 2 +- net/mac80211/sta_info.c | 2 +- net/mac80211/util.c | 4 ++-- net/wireless/core.h | 9 ++++++--- net/wireless/reg.c | 6 +++++- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 32be11e4c4d9..5b24740fc0b0 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -11,7 +11,7 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, { struct ieee80211_sub_if_data *sdata; - WARN_ON(!mutex_is_locked(&local->iflist_mtx)); + lockdep_assert_held(&local->iflist_mtx); list_for_each_entry(sdata, &local->interfaces, list) { if (sdata == ignore) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 3570f8c2bb40..6a63d1abd14d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -49,7 +49,7 @@ static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static void assert_key_lock(struct ieee80211_local *local) { - WARN_ON(!mutex_is_locked(&local->key_mtx)); + lockdep_assert_held(&local->key_mtx); } static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0cb822cc12e9..bfb0eab5c26d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -92,7 +92,7 @@ enum rx_mgmt_action { /* utils */ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) { - WARN_ON(!mutex_is_locked(&ifmgd->mtx)); + lockdep_assert_held(&ifmgd->mtx); } /* diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e356ff80671a..44e10a9de0a7 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -280,7 +280,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) unsigned long flags; int err = 0; - WARN_ON(!mutex_is_locked(&local->sta_mtx)); + lockdep_assert_held(&local->sta_mtx); /* notify driver */ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bd40b11d5ab9..9f21a69f0917 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1296,9 +1296,9 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, int count = 0; if (forsdata) - WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); + lockdep_assert_held(&forsdata->u.mgd.mtx); - WARN_ON(!mutex_is_locked(&local->iflist_mtx)); + lockdep_assert_held(&local->iflist_mtx); /* * This function could be improved to handle multiple diff --git a/net/wireless/core.h b/net/wireless/core.h index 58ab2c791d28..37580e090a3d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -95,7 +95,10 @@ extern struct mutex cfg80211_mutex; extern struct list_head cfg80211_rdev_list; extern int cfg80211_rdev_list_generation; -#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex)) +static inline void assert_cfg80211_lock(void) +{ + lockdep_assert_held(&cfg80211_mutex); +} /* * You can use this to mark a wiphy_idx as not having an associated wiphy. @@ -202,8 +205,8 @@ static inline void wdev_unlock(struct wireless_dev *wdev) mutex_unlock(&wdev->mtx); } -#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx)); -#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx)); +#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) +#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) enum cfg80211_event_type { EVENT_CONNECT_RESULT, diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b0d9a08447c9..d14bbf960c18 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -74,7 +74,11 @@ const struct ieee80211_regdomain *cfg80211_regdomain; * - last_request */ static DEFINE_MUTEX(reg_mutex); -#define assert_reg_lock() WARN_ON(!mutex_is_locked(®_mutex)) + +static inline void assert_reg_lock(void) +{ + lockdep_assert_held(®_mutex); +} /* Used to queue up regulatory hints */ static LIST_HEAD(reg_requests_list); -- cgit v1.2.3 From 2d2080c3c1d52e186166afc3efe5067291e618bf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Sep 2010 15:13:13 +0200 Subject: mac80211: set running state earlier When an interface is brought up, the recent changes to allow changing type-while-up only set the running bit after everything was done. This broke a number of things, including idle calculation for monitor interfaces, and it also broke WDS station insertion (although nobody noticed yet). Thus, change the code to set the running bit earlier, but keep it after the driver's add_interface was called because otherwise drivers may iterate over interfaces they haven't fully set up yet. Reported-by: Rajkumar Manoharan Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index c1cc200ac81f..95908aaa8a68 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -280,6 +280,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) netif_carrier_on(dev); } + set_bit(SDATA_STATE_RUNNING, &sdata->state); + if (sdata->vif.type == NL80211_IFTYPE_WDS) { /* Create STA entry for the WDS peer */ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, @@ -331,8 +333,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) netif_tx_start_all_queues(dev); - set_bit(SDATA_STATE_RUNNING, &sdata->state); - return 0; err_del_interface: drv_remove_interface(local, &sdata->vif); @@ -343,6 +343,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) sdata->bss = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) list_del(&sdata->u.vlan.list); + clear_bit(SDATA_STATE_RUNNING, &sdata->state); return res; } -- cgit v1.2.3 From 20c956dfbeec823082054954b2443e736455418b Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 15 Sep 2010 15:16:22 -0400 Subject: iwlwifi: fix sparse warning about wrong enum for band parameter drivers/net/wireless/iwlwifi/iwl-scan.c:386:27: warning: mixing different enum types drivers/net/wireless/iwlwifi/iwl-scan.c:386:27: int enum nl80211_band versus drivers/net/wireless/iwlwifi/iwl-scan.c:386:27: int enum ieee80211_band drivers/net/wireless/iwlwifi/iwl-scan.c:435:57: warning: mixing different enum types drivers/net/wireless/iwlwifi/iwl-scan.c:435:57: int enum ieee80211_band versus drivers/net/wireless/iwlwifi/iwl-scan.c:435:57: int enum nl80211_band drivers/net/wireless/iwlwifi/iwl-scan.c:474:53: warning: mixing different enum types drivers/net/wireless/iwlwifi/iwl-scan.c:474:53: int enum ieee80211_band versus drivers/net/wireless/iwlwifi/iwl-scan.c:474:53: int enum nl80211_band drivers/net/wireless/iwlwifi/iwl-scan.c:588:72: warning: mixing different enum types drivers/net/wireless/iwlwifi/iwl-scan.c:588:72: int enum ieee80211_band versus drivers/net/wireless/iwlwifi/iwl-scan.c:588:72: int enum nl80211_band Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 599573f2b01f..c54c20023e7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -350,7 +350,7 @@ EXPORT_SYMBOL(iwl_init_scan_params); static int __must_check iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif, bool internal, - enum nl80211_band band) + enum ieee80211_band band) { int ret; -- cgit v1.2.3 From 9bad82b8ae0e96483507e09463d8520bcfa78cc3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 15 Sep 2010 15:26:13 -0400 Subject: ath9k: make ath_ant_div_conf_fast_divbias static CHECK drivers/net/wireless/ath/ath9k/recv.c drivers/net/wireless/ath/ath9k/recv.c:1341:6: warning: symbol 'ath_ant_div_conf_fast_divbias' was not declared. Should it be static? Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 9eceeae28e7e..f921aa20b301 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1338,7 +1338,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, } } -void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) +static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) { /* Adjust the fast_div_bias based on main and alt lna conf */ switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { -- cgit v1.2.3 From 65a602dd536ce45814a118322a393b956ea797fb Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 15 Sep 2010 15:40:12 -0400 Subject: libertas: correct sparse warnings CHECK drivers/net/wireless/libertas/cfg.c drivers/net/wireless/libertas/cfg.c:493:19: warning: cast to restricted __le16 CHECK drivers/net/wireless/libertas/mesh.c drivers/net/wireless/libertas/mesh.c:577:16: warning: incorrect type in assignment (different base types) drivers/net/wireless/libertas/mesh.c:577:16: expected restricted __le32 [addressable] [assigned] [usertype] id drivers/net/wireless/libertas/mesh.c:577:16: got bool Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cfg.c | 6 ++---- drivers/net/wireless/libertas/mesh.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 03b7108505e7..cb3b855d949c 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -479,7 +479,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; int bsssize; const u8 *pos; - u16 nr_sets; const u8 *tsfdesc; int tsfsize; int i; @@ -488,12 +487,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, lbs_deb_enter(LBS_DEB_CFG80211); bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); - nr_sets = le16_to_cpu(scanresp->nr_sets); lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n", - nr_sets, bsssize, le16_to_cpu(resp->size)); + scanresp->nr_sets, bsssize, le16_to_cpu(resp->size)); - if (nr_sets == 0) { + if (scanresp->nr_sets == 0) { ret = 0; goto done; } diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 194762ab0142..acf3bf63ee33 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -574,7 +574,7 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) memset(&cmd, 0, sizeof(cmd)); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); - cmd.id = !!inverted; + cmd.id = cpu_to_le32(!!inverted); ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); -- cgit v1.2.3 From f799a301abf77b87133d624164d28dc2b521e99d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 16 Sep 2010 11:40:06 +0530 Subject: ath9k_hw: remove warning in ath9k_hw_def_get_num_ant_config This patch fixes following warning drivers/net/wireless/ath/ath9k/eeprom_def.c: In function 'ath9k_hw_def_get_num_ant_config' drivers/net/wireless/ath/ath9k/eeprom_def.c:1425:47: warning: comparison between 'enum ath9k_hal_freq_band' and 'enum ieee80211_band' Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom.h | 3 ++- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_def.c | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b883b174385b..e2ae98feb0be 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -968,7 +968,7 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) } static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 090778da5d67..e583421fcaa6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -672,7 +672,8 @@ struct eeprom_ops { bool (*fill_eeprom)(struct ath_hw *hw); int (*get_eeprom_ver)(struct ath_hw *hw); int (*get_eeprom_rev)(struct ath_hw *hw); - u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band); + u8 (*get_num_ant_config)(struct ath_hw *hw, + enum ath9k_hal_freq_band band); u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 2e1397b68a87..ead8b0dd3b53 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -1161,7 +1161,7 @@ static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, } static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index dff2da777312..e6186515d05b 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -1126,7 +1126,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, } static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index afa2b73ddbdd..23f480d4c770 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -1418,11 +1418,11 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, } static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { struct ar5416_eeprom_def *eep = &ah->eeprom.def; struct modal_eep_header *pModal = - &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); + &(eep->modalHeader[freq_band]); struct base_eep_header *pBase = &eep->baseEepHeader; u8 num_ant_config; -- cgit v1.2.3 From 074ac8df9f93f2a35a356d92fd7f16cd846f0a03 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Sep 2010 14:58:22 +0200 Subject: cfg80211/nl80211: introduce p2p device types This adds P2P-STA and P2P-GO as device types so we can distinguish between those and normal STA or AP (respectively) type interfaces. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ net/wireless/core.c | 2 ++ net/wireless/mlme.c | 3 ++- net/wireless/nl80211.c | 56 ++++++++++++++++++++++++++++++++++--------------- net/wireless/sme.c | 9 +++++--- net/wireless/util.c | 15 ++++++++++--- 6 files changed, 65 insertions(+), 24 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 31603e8b5581..f0518b0278a9 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1020,6 +1020,8 @@ enum nl80211_attrs { * @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -1036,6 +1038,8 @@ enum nl80211_iftype { NL80211_IFTYPE_WDS, NL80211_IFTYPE_MONITOR, NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, /* keep last */ NUM_NL80211_IFTYPES, diff --git a/net/wireless/core.c b/net/wireless/core.c index b8191cf86226..ff9615a7ee7a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -726,6 +726,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, dev->ethtool_ops = &cfg80211_ethtool_ops; if ((wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) dev->priv_flags |= IFF_DONT_BRIDGE; break; @@ -734,6 +735,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, true); break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: wdev_lock(wdev); #ifdef CONFIG_CFG80211_WEXT diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 8515b1e5c578..46f371160896 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -882,7 +882,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, if (!wdev->current_bss || memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, ETH_ALEN) != 0 || - (wdev->iftype == NL80211_IFTYPE_STATION && + ((wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && memcmp(wdev->current_bss->pub.bssid, mgmt->da, ETH_ALEN) != 0)) { wdev_unlock(wdev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1d6ef24254fe..f15b1af2c768 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -410,12 +410,14 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: break; case NL80211_IFTYPE_ADHOC: if (!wdev->current_bss) return -ENOLINK; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: if (wdev->sme_state != CFG80211_SME_CONNECTED) return -ENOLINK; break; @@ -766,7 +768,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_WDS || wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_MONITOR; + wdev->iftype == NL80211_IFTYPE_MONITOR || + wdev->iftype == NL80211_IFTYPE_P2P_GO; } static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, @@ -1693,7 +1696,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -1785,7 +1789,8 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -2128,10 +2133,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) switch (dev->ieee80211_ptr->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: /* disallow mesh-specific things */ if (params.plink_action) err = -EINVAL; break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: /* disallow everything but AUTHORIZED flag */ if (params.plink_action) @@ -2233,7 +2240,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) goto out_rtnl; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EINVAL; goto out; } @@ -2286,7 +2294,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EINVAL; goto out; } @@ -2660,7 +2669,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -3363,6 +3373,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, } switch (wdev->iftype) { + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: if (intbss == wdev->current_bss) NLA_PUT_U32(msg, NL80211_BSS_STATUS, @@ -3649,7 +3660,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3804,7 +3816,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3888,7 +3901,8 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -3954,7 +3968,8 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4332,7 +4347,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4408,7 +4424,8 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4496,7 +4513,8 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4541,7 +4559,8 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) if (err) goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4823,7 +4842,8 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) goto unlock_rtnl; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -4875,7 +4895,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) } if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto out; } @@ -5093,7 +5114,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, goto unlock_rdev; } - if (wdev->iftype != NL80211_IFTYPE_STATION) { + if (wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { err = -EOPNOTSUPP; goto unlock_rdev; } diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a8c2d6b877ae..f161b9844542 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTING) @@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) @@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) diff --git a/net/wireless/util.c b/net/wireless/util.c index bca32eb8f446..fb5448f7d55a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -326,7 +326,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { case cpu_to_le16(IEEE80211_FCTL_TODS): if (unlikely(iftype != NL80211_IFTYPE_AP && - iftype != NL80211_IFTYPE_AP_VLAN)) + iftype != NL80211_IFTYPE_AP_VLAN && + iftype != NL80211_IFTYPE_P2P_GO)) return -1; break; case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): @@ -354,7 +355,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, break; case cpu_to_le16(IEEE80211_FCTL_FROMDS): if ((iftype != NL80211_IFTYPE_STATION && - iftype != NL80211_IFTYPE_MESH_POINT) || + iftype != NL80211_IFTYPE_P2P_CLIENT && + iftype != NL80211_IFTYPE_MESH_POINT) || (is_multicast_ether_addr(dst) && !compare_ether_addr(src, addr))) return -1; @@ -431,6 +433,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); /* DA BSSID SA */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -439,6 +442,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, hdrlen = 24; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: fc |= cpu_to_le16(IEEE80211_FCTL_TODS); /* BSSID SA DA */ memcpy(hdr.addr1, bssid, ETH_ALEN); @@ -778,7 +782,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* if it's part of a bridge, reject changing type to station/ibss */ if ((dev->priv_flags & IFF_BRIDGE_PORT) && - (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) + (ntype == NL80211_IFTYPE_ADHOC || + ntype == NL80211_IFTYPE_STATION || + ntype == NL80211_IFTYPE_P2P_CLIENT)) return -EBUSY; if (ntype != otype) { @@ -789,6 +795,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, cfg80211_leave_ibss(rdev, dev, false); break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: cfg80211_disconnect(rdev, dev, WLAN_REASON_DEAUTH_LEAVING, true); break; @@ -817,9 +824,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->use_4addr) break; /* fall through */ + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_ADHOC: dev->priv_flags |= IFF_DONT_BRIDGE; break; + case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: -- cgit v1.2.3 From 2ca27bcff7127da1aa7dd39cd2a6f7cb187e327f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Sep 2010 14:58:23 +0200 Subject: mac80211: add p2p device type support When a driver advertises p2p device support, mac80211 will handle it, but internally it will rewrite the interface type to STA/AP rather than P2P-STA/GO since otherwise a lot of paths need to be touched that are otherwise identical. A p2p boolean tells drivers whether or not a given interface will be used for p2p or not. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 15 +++++++++++---- include/net/mac80211.h | 27 ++++++++++++++++++++++++++- net/mac80211/cfg.c | 25 ++++++++++++++++++------- net/mac80211/driver-ops.h | 6 +++--- net/mac80211/driver-trace.h | 21 +++++++++++++-------- net/mac80211/iface.c | 29 ++++++++++++++++++++++++++--- net/mac80211/main.c | 15 +++++++++++++++ net/mac80211/rx.c | 4 +--- net/mac80211/util.c | 18 ++++-------------- 9 files changed, 117 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 92b486d46eb9..7eaaa3bab547 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -595,7 +595,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_set_magic(vif); return 0; } @@ -603,11 +604,14 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum nl80211_iftype newtype) + enum nl80211_iftype newtype, + bool newp2p) { + newtype = ieee80211_iftype_p2p(newtype, newp2p); wiphy_debug(hw->wiphy, "%s (old type=%d, new type=%d, mac_addr=%pM)\n", - __func__, vif->type, newtype, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + newtype, vif->addr); hwsim_check_magic(vif); return 0; @@ -617,7 +621,8 @@ static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_check_magic(vif); hwsim_clear_magic(vif); } @@ -1310,6 +1315,8 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 19a5cb4a6582..12a49f0ba32c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -769,6 +769,8 @@ struct ieee80211_channel_switch { * @bss_conf: BSS configuration for this interface, either our own * or the BSS we're associated to * @addr: address of this interface + * @p2p: indicates whether this AP or STA interface is a p2p + * interface, i.e. a GO or p2p-sta respectively * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -776,6 +778,7 @@ struct ieee80211_vif { enum nl80211_iftype type; struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN]; + bool p2p; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -1701,7 +1704,7 @@ struct ieee80211_ops { struct ieee80211_vif *vif); int (*change_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum nl80211_iftype new_type); + enum nl80211_iftype new_type, bool p2p); void (*remove_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int (*config)(struct ieee80211_hw *hw, u32 changed); @@ -2721,4 +2724,26 @@ conf_is_ht(struct ieee80211_conf *conf) return conf->channel_type != NL80211_CHAN_NO_HT; } +static inline enum nl80211_iftype +ieee80211_iftype_p2p(enum nl80211_iftype type, bool p2p) +{ + if (p2p) { + switch (type) { + case NL80211_IFTYPE_STATION: + return NL80211_IFTYPE_P2P_CLIENT; + case NL80211_IFTYPE_AP: + return NL80211_IFTYPE_P2P_GO; + default: + break; + } + } + return type; +} + +static inline enum nl80211_iftype +ieee80211_vif_type_p2p(struct ieee80211_vif *vif) +{ + return ieee80211_iftype_p2p(vif->type, vif->p2p); +} + #endif /* MAC80211_H */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 171e8ff8e028..c981604b71e6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1151,15 +1151,26 @@ static int ieee80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *req) { - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) + switch (ieee80211_vif_type_p2p(&sdata->vif)) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_P2P_CLIENT: + break; + case NL80211_IFTYPE_P2P_GO: + if (sdata->local->ops->hw_scan) + break; + /* FIXME: implement NoA while scanning in software */ + return -EOPNOTSUPP; + case NL80211_IFTYPE_AP: + if (sdata->u.ap.beacon) + return -EOPNOTSUPP; + break; + default: return -EOPNOTSUPP; + } return ieee80211_request_scan(sdata, req); } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 6064b7b09e01..16983825f8e8 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -56,14 +56,14 @@ static inline int drv_add_interface(struct ieee80211_local *local, static inline int drv_change_interface(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - enum nl80211_iftype type) + enum nl80211_iftype type, bool p2p) { int ret; might_sleep(); - trace_drv_change_interface(local, sdata, type); - ret = local->ops->change_interface(&local->hw, &sdata->vif, type); + trace_drv_change_interface(local, sdata, type, p2p); + ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); trace_drv_return_int(local, ret); return ret; } diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index f6f3d89e43fa..6831fb1641c8 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -25,12 +25,14 @@ static inline void trace_ ## name(proto) {} #define STA_PR_FMT " sta:%pM" #define STA_PR_ARG __entry->sta_addr -#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ +#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ + __field(bool, p2p) \ __string(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ +#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ + __entry->p2p = sdata->vif.p2p; \ __assign_str(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_PR_FMT " vif:%s(%d)" -#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type +#define VIF_PR_FMT " vif:%s(%d%s)" +#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" /* * Tracing for driver callbacks. @@ -139,25 +141,28 @@ TRACE_EVENT(drv_add_interface, TRACE_EVENT(drv_change_interface, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - enum nl80211_iftype type), + enum nl80211_iftype type, bool p2p), - TP_ARGS(local, sdata, type), + TP_ARGS(local, sdata, type, p2p), TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY __field(u32, new_type) + __field(bool, new_p2p) ), TP_fast_assign( LOCAL_ASSIGN; VIF_ASSIGN; __entry->new_type = type; + __entry->new_p2p = p2p; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " new type:%d", - LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type + LOCAL_PR_FMT VIF_PR_FMT " new type:%d%s", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type, + __entry->new_p2p ? "/p2p" : "" ) ); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 95908aaa8a68..66785739dad3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -188,6 +188,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: /* cannot happen */ WARN_ON(1); break; @@ -844,6 +846,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, /* and set some type-dependent values */ sdata->vif.type = type; + sdata->vif.p2p = false; sdata->dev->netdev_ops = &ieee80211_dataif_ops; sdata->wdev.iftype = type; @@ -857,10 +860,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, INIT_WORK(&sdata->work, ieee80211_iface_work); switch (type) { + case NL80211_IFTYPE_P2P_GO: + type = NL80211_IFTYPE_AP; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_AP: skb_queue_head_init(&sdata->u.ap.ps_bc_buf); INIT_LIST_HEAD(&sdata->u.ap.vlans); break; + case NL80211_IFTYPE_P2P_CLIENT: + type = NL80211_IFTYPE_STATION; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_STATION: ieee80211_sta_setup_sdata(sdata); break; @@ -894,6 +907,8 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; int ret, err; + enum nl80211_iftype internal_type = type; + bool p2p = false; ASSERT_RTNL(); @@ -926,11 +941,19 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, * code isn't prepared to handle). */ break; + case NL80211_IFTYPE_P2P_CLIENT: + p2p = true; + internal_type = NL80211_IFTYPE_STATION; + break; + case NL80211_IFTYPE_P2P_GO: + p2p = true; + internal_type = NL80211_IFTYPE_AP; + break; default: return -EBUSY; } - ret = ieee80211_check_concurrent_iface(sdata, type); + ret = ieee80211_check_concurrent_iface(sdata, internal_type); if (ret) return ret; @@ -938,7 +961,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ieee80211_teardown_sdata(sdata->dev); - ret = drv_change_interface(local, sdata, type); + ret = drv_change_interface(local, sdata, internal_type, p2p); if (ret) type = sdata->vif.type; @@ -957,7 +980,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, ASSERT_RTNL(); - if (type == sdata->vif.type) + if (type == ieee80211_vif_type_p2p(&sdata->vif)) return 0; /* Setting ad-hoc mode on non-IBSS channel is not supported. */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7fb114856977..18fdeca43d98 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -459,6 +459,21 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4), }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, }; struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ac205a33690f..c0368152b721 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2588,9 +2588,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_UNSPECIFIED: - case NUM_NL80211_IFTYPES: + default: /* should never get here */ WARN_ON(1); break; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9f21a69f0917..737f4267c335 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -474,16 +474,10 @@ void ieee80211_iterate_active_interfaces( list_for_each_entry(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -508,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic( list_for_each_entry_rcu(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case NUM_NL80211_IFTYPES: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -1193,6 +1181,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: WARN_ON(1); break; } -- cgit v1.2.3 From 0f529e98498ff1a8bb264958b5fe7c0aa308d5dc Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 16 Sep 2010 19:56:55 +0530 Subject: ath9k_htc: Fix register read through bulk pipe To optimize register read/write operations, the HTC firmwares were patched to change EP3 and EP4 pipe types from Interrupt to Bulk. So register writes are submitted as bulk urbs, but register reads are not. Also changing the register read endpoint pipe as bulk type when URBs are filled improves the register reads considerably which results in reduced scan time and CPU utilization. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 27f88a0a155b..728d904c74d7 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -541,7 +541,8 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) } usb_fill_int_urb(urb, hif_dev->udev, - usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, nskb, 1); @@ -720,7 +721,8 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) goto err; usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev, - usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, skb, 1); -- cgit v1.2.3 From 8ab2cd09fecc8819bbaee2d0fd8f3a092d866ce3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:26 -0400 Subject: ath9k: fix power save race conditions ath9k has a race on putting the chip into network sleep and having registers read from hardware. The race occurs because although ath9k_ps_restore() locks its own callers it makes use of some variables which get altered in the driver at different code paths. The variables are the ps_enabled and ps_flags. This is easily reprodicible in large network environments when roaming with the wpa_supplicant simple bgscan. You'd get some 0xdeadbeef read out on certain registers such as: ath: timeout (100000 us) on reg 0x806c: 0xdeadbeef & 0x01f00000 != 0x00000000 ath: RX failed to go idle in 10 ms RXSM=0xdeadbeef ath: timeout (100000 us) on reg 0x7000: 0xdeadbeef & 0x00000003 != 0x00000000 ath: Chip reset failed The fix is to protect the ath9k_config(hw, IEEE80211_CONF_CHANGE_PS) calls with a spin_lock_irqsave() which will disable contendors for these variables from interrupt context, timers, re-entry from mac80211 on the same callback, and most importantly from ath9k_ps_restore() which is the only call which will put the device into network sleep. There are quite a few threads and bug reports on these a few of them are: https://bugs.launchpad.net/ubuntu/karmic/+source/linux/+bug/407040 http://code.google.com/p/chromium-os/issues/detail?id=5709 http://code.google.com/p/chromium-os/issues/detail?id=5943 Stable fixes apply to [2.6.32+] Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 5 ++++- drivers/net/wireless/ath/ath9k/recv.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index fa875d1c7e91..1dd8768c63dc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1554,6 +1554,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. */ if (changed & IEEE80211_CONF_CHANGE_PS) { + unsigned long flags; + spin_lock_irqsave(&sc->sc_pm_lock, flags); if (conf->flags & IEEE80211_CONF_PS) { sc->ps_flags |= PS_ENABLED; /* @@ -1568,7 +1570,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) sc->ps_enabled = false; sc->ps_flags &= ~(PS_ENABLED | PS_NULLFUNC_COMPLETED); - ath9k_setpower(sc, ATH9K_PM_AWAKE); + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { ath9k_hw_setrxabort(sc->sc_ah, 0); @@ -1583,6 +1585,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } } } + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) { diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index f921aa20b301..3e7b8fe36044 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1640,6 +1640,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) u8 rx_status_len = ah->caps.rx_status_len; u64 tsf = 0; u32 tsf_lower = 0; + unsigned long flags; if (edma) dma_type = DMA_BIDIRECTIONAL; @@ -1748,11 +1749,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) sc->rx.rxotherant = 0; } + spin_lock_irqsave(&sc->sc_pm_lock, flags); if (unlikely(ath9k_check_auto_sleep(sc) || (sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA)))) ath_rx_ps(sc, skb); + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) ath_ant_comb_scan(sc, &rs); -- cgit v1.2.3 From 52b8ac92496e03d6b5619204d7f3bae6ce6eae45 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:27 -0400 Subject: ath9k: fix regression on beacon loss after bgscan When we return to the home channel we were never reseting our beacon timers, this was casued by the fact that the scanning flag was still on even after we returned to our home channel. There are also other reasons why we would get a reset and if we are not off channel we always need to resynch our beacon timers, because a reset will clear them. This bug is a regression introduced on 2.6.36. The order of the changes are as follows: 5ee08656 - Sat Jul 31 - ath9k: prevent calibration during off-channel activity a0daa0e7 - Tue Jul 27 - Revert "mac80211: fix sw scan bracketing" 543708be - Fri Jun 18 - mac80211: fix sw scan bracketing mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ --contains 5ee0865615f65f84e6ee9174771a6716c29e08e1 v2.6.36-rc1~43^2~34^2~22 mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ --contains a0daa0e7592ada797d6835f11529097aabc27ad2 v2.6.36-rc1~571^2~64^2~13 mcgrof@tux ~/linux-2.6-allstable (git::master)$ git describe \ --contains 543708be320d7df692d24b349ca01a947b340764 v2.6.36-rc1~571^2~107^2~187 So 5ee08656 would have worked if a0daa0e7 was not committed but it was so this means 5ee08656 was broken since it assumed that when we were in the channel change routine the scan flag would be lifted. As it turns out the scan flag will be set when we are already on the home channel. For more details refer to: http://code.google.com/p/chromium-os/issues/detail?id=5715 These issues will need to be considered for our solution on reshifting the scan complete callback location on mac80211 on current development kernel work. This patch has stable fixes which apply down to [2.6.36+] Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1dd8768c63dc..3295c638f7e3 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -258,9 +258,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { ath_start_ani(common); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); - ath_beacon_config(sc, NULL); } + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) + ath_beacon_config(sc, NULL); + ps_restore: ath9k_ps_restore(sc); return r; @@ -957,7 +959,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) ath_update_txpow(sc); - if (sc->sc_flags & SC_OP_BEACONS) + if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) ath_beacon_config(sc, NULL); /* restart beacons */ ath9k_hw_set_interrupts(ah, ah->imask); -- cgit v1.2.3 From 48a6a468198aadb54bc5d3fdd065364d43ff5197 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:28 -0400 Subject: ath9k: fix enabling ANI / tx monitor after bg scan ath9k's entire logic with SC_OP_SCANNING is incorrect due to the way mac80211 currently implements the scan complete callback and we handle it in ath9k. This patch removes the flag completely in preference for the SC_OP_OFFCHANNEL which is really what we wanted. The scanning flag was used to ensure we reset ANI to the old values when we go back to the home channel, but if we are offchannel we use some defaults. The flag was also used to re-enable the TX monitor. Without this patch we simply never re-enabled ANI and the TX monitor after going offchannel. This means that after one background scan we are prone to noise issues and if we had a TX hang we would not recover. To get this to work properly we must enable ANI after we have configured the beacon timers, otherwise hardware acts really oddly. This patch has stable fixes which apply down to [2.6.36+], there *may* be a to fix this on older kernels but requires a bit of work since this patch relies on the new mac80211 flag IEEE80211_CONF_OFFCHANNEL which was introduced as of 2.6.36. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 10 +++------- drivers/net/wireless/ath/ath9k/recv.c | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c8ff417f6c10..98b57e6c614e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -563,7 +563,6 @@ struct ath_ant_comb { #define SC_OP_RXFLUSH BIT(7) #define SC_OP_LED_ASSOCIATED BIT(8) #define SC_OP_LED_ON BIT(9) -#define SC_OP_SCANNING BIT(10) #define SC_OP_TSF_RESET BIT(11) #define SC_OP_BT_PRIORITY_DETECTED BIT(12) #define SC_OP_BT_SCAN BIT(13) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3295c638f7e3..5056733e6f66 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -255,14 +255,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { - ath_start_ani(common); + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { + ath_beacon_config(sc, NULL); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + ath_start_ani(common); } - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) - ath_beacon_config(sc, NULL); - ps_restore: ath9k_ps_restore(sc); return r; @@ -2036,7 +2034,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) aphy->state = ATH_WIPHY_SCAN; ath9k_wiphy_pause_all_forced(sc, aphy); - sc->sc_flags |= SC_OP_SCANNING; mutex_unlock(&sc->mutex); } @@ -2051,7 +2048,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); aphy->state = ATH_WIPHY_ACTIVE; - sc->sc_flags &= ~SC_OP_SCANNING; mutex_unlock(&sc->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3e7b8fe36044..007df33ab05e 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -300,7 +300,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) ath_opmode_init(sc); - ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING)); + ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); } static void ath_edma_stop_recv(struct ath_softc *sc) @@ -506,7 +506,7 @@ int ath_startrecv(struct ath_softc *sc) start_recv: spin_unlock_bh(&sc->rx.rxbuflock); ath_opmode_init(sc); - ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING)); + ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); return 0; } -- cgit v1.2.3 From be099e82e9cf6d5d65d044e9ef6fc8bee3c7a113 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:29 -0400 Subject: mac80211: add helper for reseting the connection monitor This will be used in another place later. The connection monitor was added as of 2.6.35 so these fixes will be applicable to >= 2.6.35. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4e635e2fabdb..737fd0f07524 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1041,6 +1041,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index bfb0eab5c26d..2d86a4d5e912 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -124,6 +124,15 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); } +void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) +{ + if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) + return; + + mod_timer(&sdata->u.mgd.conn_mon_timer, + round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); +} + static int ecw2cw(int ecw) { return (1 << ecw) - 1; @@ -1018,11 +1027,7 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, if (is_multicast_ether_addr(hdr->addr1)) return; - if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) - return; - - mod_timer(&sdata->u.mgd.conn_mon_timer, - round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); + ieee80211_sta_reset_conn_monitor(sdata); } static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) -- cgit v1.2.3 From 0c699c3a75d4e8d0d2c317f83048d8fd3ffe692a Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:30 -0400 Subject: mac80211: reset probe send counter upon connection timer reset Upon beacon loss we send probe requests after 30 seconds of idle time and we wait for each probe response 1/2 second. We send a total of 3 probe requests before giving up on the AP. In the case that we reset the connection idle monitor we should reset the probe requests count to 0. Right now this won't help in any way but the next patch will. This patch has fixes for stable kernel [2.6.35+]. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2d86a4d5e912..d7915ab15a43 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -126,11 +126,15 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) return; mod_timer(&sdata->u.mgd.conn_mon_timer, round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); + + ifmgd->probe_send_count = 0; } static int ecw2cw(int ecw) -- cgit v1.2.3 From 4730d5977f3e12b828d354f7752cffd94bdf39e5 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:31 -0400 Subject: mac80211: reset connection idle when going offchannel When we go offchannel mac80211 currently leaves alive the connection idle monitor. This should be instead postponed until we come back to our home channel, otherwise by the time we get back to the home channel we could be triggering unecesary probe requests. For APs that do not respond to unicast probe requests (Nexus One is a simple example) this means we essentially get disconnected after the probes fails. This patch has stable fixes for kernels [2.6.35+] Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/offchannel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index eeacaa59380a..627a33ef84c4 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -22,12 +22,15 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; local->offchannel_ps_enabled = false; /* FIXME: what to do when local->pspolling is true? */ del_timer_sync(&local->dynamic_ps_timer); + del_timer_sync(&ifmgd->conn_mon_timer); + cancel_work_sync(&local->dynamic_ps_enable_work); if (local->hw.conf.flags & IEEE80211_CONF_PS) { @@ -85,6 +88,8 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) mod_timer(&local->dynamic_ps_timer, jiffies + msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); } + + ieee80211_sta_reset_conn_monitor(sdata); } void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) -- cgit v1.2.3 From d3a910a8e4e846b9a767d35483f4dc7c6de7af82 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:32 -0400 Subject: mac80211: make the beacon monitor available externally This will be used by other components next. The beacon monitor was added as of 2.6.34 so these fixes are applicable only to kernels >= 2.6.34. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 737fd0f07524..9346a6b0f400 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1041,6 +1041,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); /* IBSS code */ diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7915ab15a43..07d03e791bc0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -115,7 +115,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, mod_timer(&ifmgd->timer, timeout); } -static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) +void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) { if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) return; @@ -1390,7 +1390,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, * Also start the timer that will detect beacon loss. */ ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); return true; } @@ -1493,7 +1493,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, * we have or will be receiving any beacons or data, so let's * schedule the timers again, just in case. */ - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(jiffies + @@ -1619,7 +1619,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, * Push the beacon loss detection into the future since * we are processing a beacon from the AP just now. */ - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, -- cgit v1.2.3 From 3bc3c0d748402e8c1f31b8569f5924d25d7b8e30 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:33 -0400 Subject: mac80211: disable beacon monitor while going offchannel The beacon monitor should be disabled when going off channel to prevent spurious warnings and triggering connection deterioration work such as sending probe requests. Re-enable the beacon monitor once we come back to the home channel. This patch has fixes for stable kernels [2.6.34+]. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/offchannel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 627a33ef84c4..4b564091e51d 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -29,6 +29,7 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) /* FIXME: what to do when local->pspolling is true? */ del_timer_sync(&local->dynamic_ps_timer); + del_timer_sync(&ifmgd->bcn_mon_timer); del_timer_sync(&ifmgd->conn_mon_timer); cancel_work_sync(&local->dynamic_ps_enable_work); @@ -89,6 +90,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); } + ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata); } -- cgit v1.2.3 From f01a067d9e4598c71e3c9ee3a84859d2e8af4f8e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:34 -0400 Subject: mac80211: send last 3/5 probe requests as unicast Some buggy APs do not respond to unicast probe requests or send unicast probe requests very delayed so in the worst case we should try to send broadcast probe requests, otherwise we can get disconnected from these APs. Even if drivers do not have filters to disregard probe responses from foreign APs mac80211 will only process probe responses from our associated AP for re-arming connection monitoring. We need to do this since the beacon monitor does not push back the connection monitor by design so even if we are getting beacons from these type of APs our connection monitor currently relies heavily on the way the probe requests are received on the AP. An example of an AP affected by this is the Nexus One, but this has also been observed with random APs. We can probably optimize this later by using null funcs instead of probe requests. For more details refer to: http://code.google.com/p/chromium-os/issues/detail?id=5715 This patch has fixes for stable kernels [2.6.35+]. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 07d03e791bc0..8b733cf6f3ea 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1038,10 +1038,19 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; const u8 *ssid; + u8 *dst = ifmgd->associated->bssid; + u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); + + /* + * Try sending broadcast probe requests for the last three + * probe requests after the first ones failed since some + * buggy APs only support broadcast probe requests. + */ + if (ifmgd->probe_send_count >= unicast_limit) + dst = NULL; ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); - ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, - ssid + 2, ssid[1], NULL, 0); + ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); ifmgd->probe_send_count++; ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; -- cgit v1.2.3 From 3fac6dfdcd2b893c22b20a03dd1bf1af8b627c4b Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Thu, 16 Sep 2010 15:12:35 -0400 Subject: ath9k: fix regression which prevents chip sleep after CAB data The patch: commit 293dc5dfdbcc16cde06e40a688394cc8ab083e48 Author: Gabor Juhos Date: Fri Jun 19 12:17:48 2009 +0200 ath9k: remove ath_rx_ps_back_to_sleep helper This helper only clears the SC_OP_WAIT_FOR_{BEACON,CAB} flags. Remove it and clear these flags directly in the approptiate places instead. Changes-licensed-under: ISC Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville introduced a regression which forgot to lift the beacon flag after we received all broadcast and multicast data. This meant we never went to sleep consuming about ~650mW on idle. This pretty much broke power save completely. This patch has fixes for stable kernels [2.6.32+]. Cc: stable@kernel.org Cc: Paul Stewart Cc: Sameer Nanda Cc: Gabor Juhos Cc: Amod Bodas Signed-off-by: Senthil Balasubramanian Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 007df33ab05e..c5e7af4f51ab 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -639,7 +639,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) * No more broadcast/multicast frames to be received at this * point. */ - sc->ps_flags &= ~PS_WAIT_FOR_CAB; + sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); ath_print(common, ATH_DBG_PS, "All PS CAB frames received, back to sleep\n"); } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && -- cgit v1.2.3 From 008443def34db1dcc8016763587a288254ea5735 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 16 Sep 2010 15:12:36 -0400 Subject: ath9k: fix regression which disabled ps on ath9k The patch titled "ath9k: Add new file init.c" shuffled some code around but in dong so for some reason also removed the revision check for disablign power save. Add this revision check again so we can get power save re-enabled again by default on cards newer than AR5416 and AR5418. $ git describe --contains 556242049cc3992d0ee625e9f15c4b00ea4baac8 v2.6.34-rc1~233^2~49^2~343 This patch has fixes for stable kernels [2.6.34+]. Cc: stable@kernel.org Cc: Paul Stewart Cc: Amod Bodas Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 224df6d8fe2c..0364167cbfaf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -643,7 +643,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + if (AR_SREV_5416(sc->sc_ah)) + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->queues = 4; hw->max_rates = 4; -- cgit v1.2.3 From caeda9b926c608702c99f3432aae2c24298c3c1d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 16 Sep 2010 21:39:16 -0700 Subject: net: include inetdevice.h for rcu_dereference_raw api change rcu_dereference_raw() now needs to know the type of its argument. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index 09b3742c4c89..c09ff096525a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -129,6 +129,7 @@ #include #include #include +#include #include "net-sysfs.h" -- cgit v1.2.3 From 94767632623c7bf5b16a0cf963ec93a8ad9acca4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 15 Sep 2010 20:25:34 +0000 Subject: ip6tnl: get rid of ip6_tnl_lock As RTNL is held while doing tunnels inserts and deletes, we can remove ip6_tnl_lock spinlock. My initial RCU conversion was conservative and converted the rwlock to spinlock, with no RTNL requirement. Use appropriate rcu annotations and modern lockdep checks as well. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 29f99dd75bc6..9289cecac4de 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -83,15 +83,14 @@ struct ip6_tnl_net { /* the IPv6 tunnel fallback device */ struct net_device *fb_tnl_dev; /* lists for storing tunnels in use */ - struct ip6_tnl *tnls_r_l[HASH_SIZE]; - struct ip6_tnl *tnls_wc[1]; - struct ip6_tnl **tnls[2]; + struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE]; + struct ip6_tnl __rcu *tnls_wc[1]; + struct ip6_tnl __rcu **tnls[2]; }; /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ip6_tnl_lock); static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) { @@ -138,8 +137,8 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst) static struct ip6_tnl * ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip6_tnl *t; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); @@ -167,7 +166,7 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) * Return: head of IPv6 tunnel list **/ -static struct ip6_tnl ** +static struct ip6_tnl __rcu ** ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p) { struct in6_addr *remote = &p->raddr; @@ -190,12 +189,10 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p) static void ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) { - struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms); + struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms); - spin_lock_bh(&ip6_tnl_lock); - t->next = *tp; + rcu_assign_pointer(t->next , rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ip6_tnl_lock); } /** @@ -206,13 +203,14 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) static void ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) { - struct ip6_tnl **tp; - - for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ip6_tnl_lock); - *tp = t->next; - spin_unlock_bh(&ip6_tnl_lock); + struct ip6_tnl __rcu **tp; + struct ip6_tnl *iter; + + for (tp = ip6_tnl_bucket(ip6n, &t->parms); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -290,10 +288,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net, { struct in6_addr *remote = &p->raddr; struct in6_addr *local = &p->laddr; + struct ip6_tnl __rcu **tp; struct ip6_tnl *t; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) { + for (tp = ip6_tnl_bucket(ip6n, p); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr)) return t; @@ -318,13 +319,10 @@ ip6_tnl_dev_uninit(struct net_device *dev) struct net *net = dev_net(dev); struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - if (dev == ip6n->fb_tnl_dev) { - spin_lock_bh(&ip6_tnl_lock); - ip6n->tnls_wc[0] = NULL; - spin_unlock_bh(&ip6_tnl_lock); - } else { + if (dev == ip6n->fb_tnl_dev) + rcu_assign_pointer(ip6n->tnls_wc[0], NULL); + else ip6_tnl_unlink(ip6n, t); - } ip6_tnl_dst_reset(t); dev_put(dev); } @@ -1369,7 +1367,7 @@ static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev) ip6_tnl_dev_init_gen(dev); t->parms.proto = IPPROTO_IPV6; dev_hold(dev); - ip6n->tnls_wc[0] = t; + rcu_assign_pointer(ip6n->tnls_wc[0], t); } static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { @@ -1391,14 +1389,14 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) LIST_HEAD(list); for (h = 0; h < HASH_SIZE; h++) { - t = ip6n->tnls_r_l[h]; + t = rtnl_dereference(ip6n->tnls_r_l[h]); while (t != NULL) { unregister_netdevice_queue(t->dev, &list); - t = t->next; + t = rtnl_dereference(t->next); } } - t = ip6n->tnls_wc[0]; + t = rtnl_dereference(ip6n->tnls_wc[0]); unregister_netdevice_queue(t->dev, &list); unregister_netdevice_many(&list); } -- cgit v1.2.3 From cd13539b8bc9ae884e6d8d9374c594adff4304e4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 16 Sep 2010 02:58:13 +0000 Subject: net: shrinks struct net_device commit ab95bfe01 (net: replace hooks in __netif_receive_skb) added rx_handler at wrong place, between two cache line aligned objects, creating a big hole (a full cache line) Move rx_handler and rx_handler_data before rx_queue, filling existing hole. Move master field in the cache line(s) used in receive path. This saves 64 bytes (or L1_CACHE_BYTES), and avoids two possible cache misses in receive path. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8992fffb8104..ec17887a5bca 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -918,10 +918,6 @@ struct net_device { unsigned short needed_headroom; unsigned short needed_tailroom; - struct net_device *master; /* Pointer to master device of a group, - * which this device is member of. - */ - /* Interface address info. */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ unsigned char addr_assign_type; /* hw address assignment type */ @@ -951,7 +947,7 @@ struct net_device { assign before registering */ /* - * Cache line mostly used on receive path (including eth_type_trans()) + * Cache lines mostly used on receive path (including eth_type_trans()) */ unsigned long last_rx; /* Time of last Rx * This should not be set in @@ -961,6 +957,10 @@ struct net_device { * avoid dirtying this cache line. */ + struct net_device *master; /* Pointer to master device of a group, + * which this device is member of. + */ + /* Interface address info used in eth_type_trans() */ unsigned char *dev_addr; /* hw address, (before bcast because most packets are @@ -980,10 +980,14 @@ struct net_device { unsigned int num_rx_queues; #endif - struct netdev_queue rx_queue; rx_handler_func_t *rx_handler; void *rx_handler_data; + struct netdev_queue rx_queue; /* use two cache lines */ + +/* + * Cache lines mostly used on transmit path + */ struct netdev_queue *_tx ____cacheline_aligned_in_smp; /* Number of TX queues allocated at alloc_netdev_mq() time */ @@ -997,9 +1001,7 @@ struct net_device { unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; -/* - * One part is mostly used on xmit path (device) - */ + /* These may be needed for future network-power-down code. */ /* -- cgit v1.2.3 From 0c796f91a518480fd6696ba2affed1167e840823 Mon Sep 17 00:00:00 2001 From: Dan Rosenberg Date: Thu, 16 Sep 2010 22:34:26 -0700 Subject: drivers/net/tulip/de4x5.c: fix union member name in DE4X5_GET_REG ioctl This was previously reported as a security issue due to leakage of uninitialized stack memory. Jeff Mahoney pointed out that this is incorrect since the copied data is from a union (rather than a struct). Therefore, this patch is only under consideration for the sake of correctness, and is not security relevant. Signed-off-by: Dan Rosenberg Acked-by: Grant Grundler Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 4f7503063446..1d9fef74b39b 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -5474,7 +5474,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) tmp.lval[6] = inl(DE4X5_STRR); j+=4; tmp.lval[7] = inl(DE4X5_SIGR); j+=4; ioc->len = j; - if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT; + if (copy_to_user(ioc->data, tmp.lval, ioc->len)) return -EFAULT; break; #define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */ -- cgit v1.2.3 From 3575792e005dc9994f15ae72c1c6f401d134177d Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Fri, 17 Sep 2010 14:18:16 +0200 Subject: ipvs: extend connection flags to 32 bits - the sync protocol supports 16 bits only, so bits 0..15 should be used only for flags that should go to backup server, bits 16 and above should be allocated for flags not sent to backup. - use IP_VS_CONN_F_DEST_MASK as mask of connection flags in destination that can be changed by user space - allow IP_VS_CONN_F_ONE_PACKET to be set in destination Signed-off-by: Julian Anastasov Signed-off-by: Patrick McHardy --- include/linux/ip_vs.h | 8 ++++++++ include/net/ip_vs.h | 2 +- net/netfilter/ipvs/ip_vs_conn.c | 16 ++++++++++------ net/netfilter/ipvs/ip_vs_core.c | 11 ++++++----- net/netfilter/ipvs/ip_vs_ctl.c | 5 +++-- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index 9708de265bb1..003d75f6ffe1 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -70,6 +70,7 @@ /* * IPVS Connection Flags + * Only flags 0..15 are sent to backup server */ #define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */ #define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */ @@ -88,6 +89,13 @@ #define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ #define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ +/* Flags that are not sent to backup server start from bit 16 */ + +/* Connection flags from destination that can be changed by user space */ +#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \ + IP_VS_CONN_F_ONE_PACKET | \ + 0) + #define IP_VS_SCHEDNAME_MAXLEN 16 #define IP_VS_IFNAME_MAXLEN 16 diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index f976885f686f..62698a9c1631 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -366,6 +366,7 @@ struct ip_vs_conn { union nf_inet_addr caddr; /* client address */ union nf_inet_addr vaddr; /* virtual address */ union nf_inet_addr daddr; /* destination address */ + volatile __u32 flags; /* status flags */ __be16 cport; __be16 vport; __be16 dport; @@ -378,7 +379,6 @@ struct ip_vs_conn { /* Flags and state transition */ spinlock_t lock; /* lock for state transition */ - volatile __u16 flags; /* status flags */ volatile __u16 state; /* state info */ volatile __u16 old_state; /* old state, to be used for * state transition triggerd diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index b71c69a2db13..9fe1da7bcf16 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -505,6 +505,8 @@ static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest) static inline void ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) { + unsigned int conn_flags; + /* if dest is NULL, then return directly */ if (!dest) return; @@ -512,16 +514,18 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) /* Increase the refcnt counter of the dest */ atomic_inc(&dest->refcnt); + conn_flags = atomic_read(&dest->conn_flags); + if (cp->protocol != IPPROTO_UDP) + conn_flags &= ~IP_VS_CONN_F_ONE_PACKET; /* Bind with the destination and its corresponding transmitter */ - if ((cp->flags & IP_VS_CONN_F_SYNC) && - (!(cp->flags & IP_VS_CONN_F_TEMPLATE))) + if (cp->flags & IP_VS_CONN_F_SYNC) { /* if the connection is not template and is created * by sync, preserve the activity flag. */ - cp->flags |= atomic_read(&dest->conn_flags) & - (~IP_VS_CONN_F_INACTIVE); - else - cp->flags |= atomic_read(&dest->conn_flags); + if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) + conn_flags &= ~IP_VS_CONN_F_INACTIVE; + } + cp->flags |= conn_flags; cp->dest = dest; IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d " diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 0c043b6ce65e..319991d4d251 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -194,7 +194,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, struct ip_vs_dest *dest; struct ip_vs_conn *ct; __be16 dport; /* destination port to forward */ - __be16 flags; + unsigned int flags; union nf_inet_addr snet; /* source network of the client, after masking */ @@ -382,7 +382,8 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) struct ip_vs_conn *cp = NULL; struct ip_vs_iphdr iph; struct ip_vs_dest *dest; - __be16 _ports[2], *pptr, flags; + __be16 _ports[2], *pptr; + unsigned int flags; ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); @@ -473,9 +474,9 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) { int ret, cs; struct ip_vs_conn *cp; - __u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && - iph.protocol == IPPROTO_UDP)? - IP_VS_CONN_F_ONE_PACKET : 0; + unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && + iph.protocol == IPPROTO_UDP)? + IP_VS_CONN_F_ONE_PACKET : 0; union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } }; ip_vs_service_put(svc); diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index ca8ec8c4f311..7bd41d28080c 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -765,7 +765,8 @@ __ip_vs_update_dest(struct ip_vs_service *svc, /* set the weight and the flags */ atomic_set(&dest->weight, udest->weight); - conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; + conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK; + conn_flags |= IP_VS_CONN_F_INACTIVE; /* check if local node and update the flags */ #ifdef CONFIG_IP_VS_IPV6 @@ -782,7 +783,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, } /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */ - if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) { + if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) { conn_flags |= IP_VS_CONN_F_NOOUTPUT; } else { /* -- cgit v1.2.3 From d57906633efd58ccd93f056ed436ffde5cb31aa8 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 16 Sep 2010 19:14:39 +0000 Subject: qlcnic: support vlan rx accleration Implemented vlan rx accleration in driver. This helps in increasing significant performance and reduces cpu utilization with GRO and LRO. Eric Dumazet: "Its a bit strange you use dev_kfree_skb_any(skb) here." "We run in NAPI mode, so you can use dev_kfree_skb()." Amit: Done. Using dev_kfree_skb(); Signed-off-by: Amit Kumar Salecha Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_init.c | 59 +++++++++++++++++++++++----------------- drivers/net/qlcnic/qlcnic_main.c | 10 ++++++- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index cc8385a6727e..c8caec90b31b 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1013,6 +1013,7 @@ struct qlcnic_adapter { u64 dev_rst_time; + struct vlan_group *vlgrp; struct qlcnic_npar_info *npars; struct qlcnic_eswitch *eswitch; struct qlcnic_nic_template *nic_ops; diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 26a7d6bca5c7..10cebb15ccd4 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1380,24 +1380,28 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, } static int -qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb) +qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb, + u16 *vlan_tag) { - u16 vlan_tag; struct ethhdr *eth_hdr; - if (!__vlan_get_tag(skb, &vlan_tag)) { - if (vlan_tag == adapter->pvid) { - /* strip the tag from the packet and send it up */ - eth_hdr = (struct ethhdr *) skb->data; - memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); - skb_pull(skb, VLAN_HLEN); - return 0; - } + if (!__vlan_get_tag(skb, vlan_tag)) { + eth_hdr = (struct ethhdr *) skb->data; + memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); + skb_pull(skb, VLAN_HLEN); + } + if (!adapter->pvid) + return 0; + + if (*vlan_tag == adapter->pvid) { + /* Outer vlan tag. Packet should follow non-vlan path */ + *vlan_tag = 0xffff; + return 0; } if (adapter->flags & QLCNIC_TAGGING_ENABLED) return 0; - return -EIO; + return -EINVAL; } static struct qlcnic_rx_buffer * @@ -1411,6 +1415,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, struct sk_buff *skb; struct qlcnic_host_rds_ring *rds_ring; int index, length, cksum, pkt_offset; + u16 vid = 0xffff; if (unlikely(ring >= adapter->max_rds_rings)) return NULL; @@ -1441,17 +1446,18 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, skb->truesize = skb->len + sizeof(struct sk_buff); - if (unlikely(adapter->pvid)) { - if (qlcnic_check_rx_tagging(adapter, skb)) { - adapter->stats.rxdropped++; - dev_kfree_skb_any(skb); - return buffer; - } + if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + adapter->stats.rxdropped++; + dev_kfree_skb(skb); + return buffer; } skb->protocol = eth_type_trans(skb, netdev); - napi_gro_receive(&sds_ring->napi, skb); + if ((vid != 0xffff) && adapter->vlgrp) + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid); + else + napi_gro_receive(&sds_ring->napi, skb); adapter->stats.rx_pkts++; adapter->stats.rxbytes += length; @@ -1480,6 +1486,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, int index; u16 lro_length, length, data_offset; u32 seq_number; + u16 vid = 0xffff; if (unlikely(ring > adapter->max_rds_rings)) return NULL; @@ -1514,13 +1521,12 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, skb_pull(skb, l2_hdr_offset); - if (unlikely(adapter->pvid)) { - if (qlcnic_check_rx_tagging(adapter, skb)) { - adapter->stats.rxdropped++; - dev_kfree_skb_any(skb); - return buffer; - } + if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + adapter->stats.rxdropped++; + dev_kfree_skb(skb); + return buffer; } + skb->protocol = eth_type_trans(skb, netdev); iph = (struct iphdr *)skb->data; @@ -1535,7 +1541,10 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, length = skb->len; - netif_receive_skb(skb); + if ((vid != 0xffff) && adapter->vlgrp) + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid); + else + netif_receive_skb(skb); adapter->stats.lro_pkts++; adapter->stats.lrobytes += length; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 5fd2abd1eb67..9eb0ced1ffab 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -371,6 +371,13 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) return 0; } +static void qlcnic_vlan_rx_register(struct net_device *netdev, + struct vlan_group *grp) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + adapter->vlgrp = grp; +} + static const struct net_device_ops qlcnic_netdev_ops = { .ndo_open = qlcnic_open, .ndo_stop = qlcnic_close, @@ -381,6 +388,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { .ndo_set_mac_address = qlcnic_set_mac, .ndo_change_mtu = qlcnic_change_mtu, .ndo_tx_timeout = qlcnic_tx_timeout, + .ndo_vlan_rx_register = qlcnic_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, #endif @@ -1446,7 +1454,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_GRO); + NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX); netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); -- cgit v1.2.3 From 5718d3b432757ac83f65c50dd61df9c1e0d88e61 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 16 Sep 2010 19:14:40 +0000 Subject: qlcnic: vlan gro support GRO support + vlan rx accleration, boost around 9% performance and reduces 25% of cpu utilization on vlan interface. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 10cebb15ccd4..9f994b968f4a 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1455,7 +1455,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, skb->protocol = eth_type_trans(skb, netdev); if ((vid != 0xffff) && adapter->vlgrp) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid); + vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb); else napi_gro_receive(&sds_ring->napi, skb); -- cgit v1.2.3 From aec1e8452dc364cffd0333e5632ec482f6322593 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 16 Sep 2010 19:14:41 +0000 Subject: qlcnic: vlan lro support LRO + GRO + vlan rx accleration support, performance increases around 20% and cpu utilization reduces around 70% on vlan interface. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 9eb0ced1ffab..17124f6e0a93 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -107,7 +107,7 @@ static irqreturn_t qlcnic_msi_intr(int irq, void *data); static irqreturn_t qlcnic_msix_intr(int irq, void *data); static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); -static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); +static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); static int qlcnic_start_firmware(struct qlcnic_adapter *); static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); @@ -1759,7 +1759,7 @@ qlcnic_resume(struct pci_dev *pdev) if (err) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: netif_device_attach(netdev); @@ -2958,7 +2958,7 @@ attach: if (qlcnic_up(adapter, netdev)) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: @@ -3120,7 +3120,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (err) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: netif_device_attach(netdev); @@ -4035,10 +4035,10 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) static void -qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) +qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, + struct net_device *dev, unsigned long event) { struct in_device *indev; - struct qlcnic_adapter *adapter = netdev_priv(dev); indev = in_dev_get(dev); if (!indev) @@ -4062,6 +4062,27 @@ qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) in_dev_put(indev); } +static void +qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct net_device *dev; + u16 vid; + + qlcnic_config_indev_addr(adapter, netdev, event); + + if (!adapter->vlgrp) + return; + + for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + dev = vlan_group_get_device(adapter->vlgrp, vid); + if (!dev) + continue; + + qlcnic_config_indev_addr(adapter, dev, event); + } +} + static int qlcnic_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -4088,7 +4109,7 @@ recheck: if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) goto done; - qlcnic_config_indev_addr(dev, event); + qlcnic_config_indev_addr(adapter, dev, event); done: return NOTIFY_DONE; } @@ -4105,7 +4126,7 @@ qlcnic_inetaddr_event(struct notifier_block *this, dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; recheck: - if (dev == NULL || !netif_running(dev)) + if (dev == NULL) goto done; if (dev->priv_flags & IFF_802_1Q_VLAN) { @@ -4148,7 +4169,7 @@ static struct notifier_block qlcnic_inetaddr_cb = { }; #else static void -qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) +qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) { } #endif static struct pci_error_handlers qlcnic_err_handler = { -- cgit v1.2.3 From 97f29d8236aa3612986e7e7179282ff460eba686 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 16 Sep 2010 19:14:42 +0000 Subject: qlcnic: remove fw version check Don't compare flash and file fw version. Allow to load old fw from file than flashed fw. If file fw is present, don't skip fw re-intialization. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 9f994b968f4a..e26fa9593311 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1015,8 +1015,6 @@ qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter) int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) { - u32 val, version, major, minor, build; - if (qlcnic_check_fw_hearbeat(adapter)) { qlcnic_rom_lock_recovery(adapter); return 1; @@ -1025,20 +1023,8 @@ qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) if (adapter->need_fw_reset) return 1; - /* check if we have got newer or different file firmware */ - if (adapter->fw) { - - val = qlcnic_get_fw_version(adapter); - - version = QLCNIC_DECODE_VERSION(val); - - major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); - minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); - build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); - - if (version > QLCNIC_VERSION_CODE(major, minor, build)) - return 1; - } + if (adapter->fw) + return 1; return 0; } @@ -1174,18 +1160,6 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) return -EINVAL; } - /* check if flashed firmware is newer */ - if (qlcnic_rom_fast_read(adapter, - QLCNIC_FW_VERSION_OFFSET, (int *)&val)) - return -EIO; - - val = QLCNIC_DECODE_VERSION(val); - if (val > ver) { - dev_info(&pdev->dev, "%s: firmware is older than flash\n", - fw_name[fw_type]); - return -EINVAL; - } - QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC); return 0; } -- cgit v1.2.3 From 457e9d2233bdde5bb5577df3e2d4d48f84c67b66 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 16 Sep 2010 19:14:43 +0000 Subject: qlcnic: update version 5.0.10 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index c8caec90b31b..714ddf461d73 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 9 -#define QLCNIC_LINUX_VERSIONID "5.0.9" +#define _QLCNIC_LINUX_SUBVERSION 10 +#define QLCNIC_LINUX_VERSIONID "5.0.10" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3 From 67c9660831f6b6b76866a0838466c83765ffbbd3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 17 Sep 2010 11:56:18 -0700 Subject: ethtool: change ethtool_set_gro() to use ethtool_op_get_rx_csum To be able to switch on GRO on a device, ethtool_set_gro() checks this device provides a get_rx_csum() method. Some devices dont provide this method, while they do support RX checksumming. This patch allows bonding to support GRO : ethtool -K bond0 gro on Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/ethtool.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index fcd62757704d..248c25c3e820 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1181,8 +1181,11 @@ static int ethtool_set_gro(struct net_device *dev, char __user *useraddr) return -EFAULT; if (edata.data) { - if (!dev->ethtool_ops->get_rx_csum || - !dev->ethtool_ops->get_rx_csum(dev)) + u32 rxcsum = dev->ethtool_ops->get_rx_csum ? + dev->ethtool_ops->get_rx_csum(dev) : + ethtool_op_get_rx_csum(dev); + + if (!rxcsum) return -EINVAL; dev->features |= NETIF_F_GRO; } else -- cgit v1.2.3 From a437fbb96fe4eab241f06bbd7c7c1070ccdb2544 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:38 -0700 Subject: iwlagn: add bt_status_read for 5150 Include bt_status_read function pointer for 5150 device Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1dbb1246c083..b9399fbcee97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -474,6 +474,7 @@ static struct iwl_lib_ops iwl5150_lib = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, -- cgit v1.2.3 From 91835ba401189a81e5ad1f932f880d8eed8c9db2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:41 -0700 Subject: iwlagn: keep track fail tx reason counter If uCode fail to transmit frame, it will send reply tx back to driver with failure status; keep the counters of each failure cases for debugging. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 79 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 29 +++++++++++ 2 files changed, 108 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 12170cfcff4e..68a2ab399e3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -46,6 +46,83 @@ static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) tx_resp->frame_count) & MAX_SN; } +static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) +{ + status &= TX_STATUS_MSK; + + switch (status) { + case TX_STATUS_POSTPONE_DELAY: + priv->_agn.reply_tx_stats.pp_delay++; + break; + case TX_STATUS_POSTPONE_FEW_BYTES: + priv->_agn.reply_tx_stats.pp_few_bytes++; + break; + case TX_STATUS_POSTPONE_BT_PRIO: + priv->_agn.reply_tx_stats.pp_bt_prio++; + break; + case TX_STATUS_POSTPONE_QUIET_PERIOD: + priv->_agn.reply_tx_stats.pp_quiet_period++; + break; + case TX_STATUS_POSTPONE_CALC_TTAK: + priv->_agn.reply_tx_stats.pp_calc_ttak++; + break; + case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY: + priv->_agn.reply_tx_stats.int_crossed_retry++; + break; + case TX_STATUS_FAIL_SHORT_LIMIT: + priv->_agn.reply_tx_stats.short_limit++; + break; + case TX_STATUS_FAIL_LONG_LIMIT: + priv->_agn.reply_tx_stats.long_limit++; + break; + case TX_STATUS_FAIL_FIFO_UNDERRUN: + priv->_agn.reply_tx_stats.fifo_underrun++; + break; + case TX_STATUS_FAIL_DRAIN_FLOW: + priv->_agn.reply_tx_stats.drain_flow++; + break; + case TX_STATUS_FAIL_RFKILL_FLUSH: + priv->_agn.reply_tx_stats.rfkill_flush++; + break; + case TX_STATUS_FAIL_LIFE_EXPIRE: + priv->_agn.reply_tx_stats.life_expire++; + break; + case TX_STATUS_FAIL_DEST_PS: + priv->_agn.reply_tx_stats.dest_ps++; + break; + case TX_STATUS_FAIL_HOST_ABORTED: + priv->_agn.reply_tx_stats.host_abort++; + break; + case TX_STATUS_FAIL_BT_RETRY: + priv->_agn.reply_tx_stats.bt_retry++; + break; + case TX_STATUS_FAIL_STA_INVALID: + priv->_agn.reply_tx_stats.sta_invalid++; + break; + case TX_STATUS_FAIL_FRAG_DROPPED: + priv->_agn.reply_tx_stats.frag_drop++; + break; + case TX_STATUS_FAIL_TID_DISABLE: + priv->_agn.reply_tx_stats.tid_disable++; + break; + case TX_STATUS_FAIL_FIFO_FLUSHED: + priv->_agn.reply_tx_stats.fifo_flush++; + break; + case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL: + priv->_agn.reply_tx_stats.insuff_cf_poll++; + break; + case TX_STATUS_FAIL_FW_DROP: + priv->_agn.reply_tx_stats.fail_hw_drop++; + break; + case TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP: + priv->_agn.reply_tx_stats.sta_color_mismatch++; + break; + default: + priv->_agn.reply_tx_stats.unknown++; + break; + } +} + static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, struct iwl5000_tx_resp *tx_resp, @@ -59,6 +136,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, info->flags |= iwl_tx_status_to_mac80211(status); iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), info); + if (!iwl_is_tx_success(status)) + iwlagn_count_tx_err_status(priv, status); IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " "0x%x retries %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4e3a69271e34..bfa4864ec6d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -957,6 +957,33 @@ struct isr_statistics { u32 unhandled; }; +/* reply_tx_statistics (for _agn devices) */ +struct reply_tx_error_statistics { + u32 pp_delay; + u32 pp_few_bytes; + u32 pp_bt_prio; + u32 pp_quiet_period; + u32 pp_calc_ttak; + u32 int_crossed_retry; + u32 short_limit; + u32 long_limit; + u32 fifo_underrun; + u32 drain_flow; + u32 rfkill_flush; + u32 life_expire; + u32 dest_ps; + u32 host_abort; + u32 bt_retry; + u32 sta_invalid; + u32 frag_drop; + u32 tid_disable; + u32 fifo_flush; + u32 insuff_cf_poll; + u32 fail_hw_drop; + u32 sta_color_mismatch; + u32 unknown; +}; + #ifdef CONFIG_IWLWIFI_DEBUGFS /* management statistics */ enum iwl_mgmt_stats { @@ -1415,6 +1442,8 @@ struct iwl_priv { struct iwl_notif_statistics statistics; struct iwl_bt_notif_statistics statistics_bt; + /* counts reply_tx error */ + struct reply_tx_error_statistics reply_tx_stats; #ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_notif_statistics accum_statistics; struct iwl_notif_statistics delta_statistics; -- cgit v1.2.3 From 54a9aa65f749673f851ef86481940394185c1b0e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:42 -0700 Subject: iwlagn: keep track of failure tx status Tx command response sent to host by uCode after completed the transmission attempt. The status parameter indicates whether the transmission was successful, or else why if failed. Here we keep the counters to help understand the different failure cases. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 2 + drivers/net/wireless/iwlwifi/iwl-6000.c | 2 + drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 97 ++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h | 7 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 14 ++++ 8 files changed, 126 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 674fb93ae17f..56ef4ed0db47 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -223,6 +223,7 @@ static struct iwl_lib_ops iwl1000_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 1d6a46d4db59..943a9c7bfa7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2289,6 +2289,7 @@ static struct iwl_lib_ops iwl4965_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b9399fbcee97..21b4b23368e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -404,6 +404,7 @@ static struct iwl_lib_ops iwl5000_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, @@ -475,6 +476,7 @@ static struct iwl_lib_ops iwl5150_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 2fdba088bd27..9f43f2770c96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -329,6 +329,7 @@ static struct iwl_lib_ops iwl6000_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, @@ -404,6 +405,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index d706b8afbe5a..de68dde4feee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -1011,3 +1011,100 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, kfree(buf); return ret; } + +ssize_t iwl_reply_tx_error_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + 200; + ssize_t ret; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), + priv->_agn.reply_tx_stats.pp_delay); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), + priv->_agn.reply_tx_stats.pp_few_bytes); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), + priv->_agn.reply_tx_stats.pp_bt_prio); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), + priv->_agn.reply_tx_stats.pp_quiet_period); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), + priv->_agn.reply_tx_stats.pp_calc_ttak); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), + priv->_agn.reply_tx_stats.int_crossed_retry); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), + priv->_agn.reply_tx_stats.short_limit); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), + priv->_agn.reply_tx_stats.long_limit); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), + priv->_agn.reply_tx_stats.fifo_underrun); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), + priv->_agn.reply_tx_stats.drain_flow); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), + priv->_agn.reply_tx_stats.rfkill_flush); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), + priv->_agn.reply_tx_stats.life_expire); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), + priv->_agn.reply_tx_stats.dest_ps); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), + priv->_agn.reply_tx_stats.host_abort); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), + priv->_agn.reply_tx_stats.pp_delay); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), + priv->_agn.reply_tx_stats.sta_invalid); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), + priv->_agn.reply_tx_stats.frag_drop); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), + priv->_agn.reply_tx_stats.tid_disable); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), + priv->_agn.reply_tx_stats.fifo_flush); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), + priv->_agn.reply_tx_stats.insuff_cf_poll); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FW_DROP), + priv->_agn.reply_tx_stats.fail_hw_drop); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP), + priv->_agn.reply_tx_stats.sta_color_mismatch); + pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", + priv->_agn.reply_tx_stats.unknown); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h index bbdce5913ac7..f2573b5486cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h @@ -39,6 +39,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); +ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); #else static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -60,4 +62,9 @@ static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, { return 0; } +static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f1d40c6173c1..f0302bfe85f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -130,6 +130,8 @@ struct iwl_debugfs_ops { size_t count, loff_t *ppos); ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); + ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); }; struct iwl_temp_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e0b31a2a1dac..265ad01a443f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1642,6 +1642,18 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + + if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error) + return priv->cfg->ops->lib->debugfs_ops.reply_tx_error( + file, user_buf, count, ppos); + else + return -ENODATA; +} DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1668,6 +1680,7 @@ DEBUGFS_READ_FILE_OPS(ucode_bt_stats); DEBUGFS_WRITE_FILE_OPS(monitor_period); DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); +DEBUGFS_READ_FILE_OPS(reply_tx_error); /* * Create the debugfs files and directories @@ -1738,6 +1751,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); if (priv->cfg->bt_statistics) DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); -- cgit v1.2.3 From e1b3fa0c22625d985cc7f82b7f3aa90a6fc75c2f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:43 -0700 Subject: iwlagn: log aggregation tx command status For aggregated frames with block ack, different status flag will be used as part of tx command response. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 32 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 3 +++ 2 files changed, 35 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 68a2ab399e3e..a8494d0e285a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -147,6 +147,33 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, tx_resp->failure_frame); } +#ifdef CONFIG_IWLWIFI_DEBUG +#define AGG_TX_STATE_FAIL(x) case AGG_TX_STATE_ ## x: return #x + +const char *iwl_get_agg_tx_fail_reason(u16 status) +{ + status &= AGG_TX_STATUS_MSK; + switch (status) { + case AGG_TX_STATE_TRANSMITTED: + return "SUCCESS"; + AGG_TX_STATE_FAIL(UNDERRUN_MSK); + AGG_TX_STATE_FAIL(BT_PRIO_MSK); + AGG_TX_STATE_FAIL(FEW_BYTES_MSK); + AGG_TX_STATE_FAIL(ABORT_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_TTL_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_TRY_CNT_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_BT_KILL_MSK); + AGG_TX_STATE_FAIL(SCD_QUERY_MSK); + AGG_TX_STATE_FAIL(TEST_BAD_CRC32_MSK); + AGG_TX_STATE_FAIL(RESPONSE_MSK); + AGG_TX_STATE_FAIL(DUMP_TX_MSK); + AGG_TX_STATE_FAIL(DELAY_TX_MSK); + } + + return "UNKNOWN"; +} +#endif /* CONFIG_IWLWIFI_DEBUG */ + static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, struct iwl5000_tx_resp *tx_resp, @@ -203,6 +230,11 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", agg->frame_count, txq_id, idx); + IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " + "try-count (0x%08x)\n", + iwl_get_agg_tx_fail_reason(status), + status & AGG_TX_STATUS_MSK, + status & AGG_TX_TRY_MSK); hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); if (!hdr) { diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 3e4ba31b5d59..dd47acafa25b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1868,6 +1868,9 @@ enum { AGG_TX_STATE_DELAY_TX_MSK = 0x400 }; +#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ +#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ + #define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) -- cgit v1.2.3 From 814665fef7562b31d32e515c4d91b06c8b956560 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:44 -0700 Subject: iwlagn: keep track of aggregated tx frames failure counter When uCode completed the aggregated frames transmission attempt, it will send tx command response with aggregated frame status. Keep track of the failure counter which help indicate any transmission error condition. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 50 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 18 +++++++++++ 2 files changed, 68 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a8494d0e285a..c42cb18de833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -123,6 +123,53 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) } } +static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) +{ + status &= AGG_TX_STATUS_MSK; + + switch (status) { + case AGG_TX_STATE_UNDERRUN_MSK: + priv->_agn.reply_agg_tx_stats.underrun++; + break; + case AGG_TX_STATE_BT_PRIO_MSK: + priv->_agn.reply_agg_tx_stats.bt_prio++; + break; + case AGG_TX_STATE_FEW_BYTES_MSK: + priv->_agn.reply_agg_tx_stats.few_bytes++; + break; + case AGG_TX_STATE_ABORT_MSK: + priv->_agn.reply_agg_tx_stats.abort++; + break; + case AGG_TX_STATE_LAST_SENT_TTL_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_ttl++; + break; + case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_try++; + break; + case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_bt_kill++; + break; + case AGG_TX_STATE_SCD_QUERY_MSK: + priv->_agn.reply_agg_tx_stats.scd_query++; + break; + case AGG_TX_STATE_TEST_BAD_CRC32_MSK: + priv->_agn.reply_agg_tx_stats.bad_crc32++; + break; + case AGG_TX_STATE_RESPONSE_MSK: + priv->_agn.reply_agg_tx_stats.response++; + break; + case AGG_TX_STATE_DUMP_TX_MSK: + priv->_agn.reply_agg_tx_stats.dump_tx++; + break; + case AGG_TX_STATE_DELAY_TX_MSK: + priv->_agn.reply_agg_tx_stats.delay_tx++; + break; + default: + priv->_agn.reply_agg_tx_stats.unknown++; + break; + } +} + static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, struct iwl5000_tx_resp *tx_resp, @@ -224,6 +271,9 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, idx = SEQ_TO_INDEX(seq); txq_id = SEQ_TO_QUEUE(seq); + if (status & AGG_TX_STATUS_MSK) + iwlagn_count_agg_tx_err_status(priv, status); + if (status & (AGG_TX_STATE_FEW_BYTES_MSK | AGG_TX_STATE_ABORT_MSK)) continue; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index bfa4864ec6d3..74d25bcbfcb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -984,6 +984,23 @@ struct reply_tx_error_statistics { u32 unknown; }; +/* reply_agg_tx_statistics (for _agn devices) */ +struct reply_agg_tx_error_statistics { + u32 underrun; + u32 bt_prio; + u32 few_bytes; + u32 abort; + u32 last_sent_ttl; + u32 last_sent_try; + u32 last_sent_bt_kill; + u32 scd_query; + u32 bad_crc32; + u32 response; + u32 dump_tx; + u32 delay_tx; + u32 unknown; +}; + #ifdef CONFIG_IWLWIFI_DEBUGFS /* management statistics */ enum iwl_mgmt_stats { @@ -1444,6 +1461,7 @@ struct iwl_priv { struct iwl_bt_notif_statistics statistics_bt; /* counts reply_tx error */ struct reply_tx_error_statistics reply_tx_stats; + struct reply_agg_tx_error_statistics reply_agg_tx_stats; #ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_notif_statistics accum_statistics; struct iwl_notif_statistics delta_statistics; -- cgit v1.2.3 From 95b49ed013c9a8856ce768d8d4a62acfc410f73d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 5 Sep 2010 10:49:45 -0700 Subject: iwlagn: adding aggregated frame failure status to debugfs Addition to standard tx frame failure report, adding aggregated frame failure report to debugfs Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 51 +++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn.h | 5 +++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index de68dde4feee..52e98691ddfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -25,7 +25,7 @@ * Intel Linux Wireless * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ - +#include "iwl-agn.h" #include "iwl-agn-debugfs.h" static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) @@ -1019,7 +1019,8 @@ ssize_t iwl_reply_tx_error_read(struct file *file, struct iwl_priv *priv = (struct iwl_priv *)file->private_data; int pos = 0; char *buf; - int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + 200; + int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + + (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; ssize_t ret; if (!iwl_is_alive(priv)) @@ -1104,6 +1105,52 @@ ssize_t iwl_reply_tx_error_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", priv->_agn.reply_tx_stats.unknown); + pos += scnprintf(buf + pos, bufsz - pos, + "\nStatistics_Agg_TX_Error:\n"); + + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), + priv->_agn.reply_agg_tx_stats.underrun); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), + priv->_agn.reply_agg_tx_stats.bt_prio); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), + priv->_agn.reply_agg_tx_stats.few_bytes); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), + priv->_agn.reply_agg_tx_stats.abort); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_TTL_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_ttl); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_try); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_bt_kill); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), + priv->_agn.reply_agg_tx_stats.scd_query); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_TEST_BAD_CRC32_MSK), + priv->_agn.reply_agg_tx_stats.bad_crc32); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), + priv->_agn.reply_agg_tx_stats.response); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), + priv->_agn.reply_agg_tx_stats.dump_tx); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), + priv->_agn.reply_agg_tx_stats.delay_tx); + pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", + priv->_agn.reply_agg_tx_stats.unknown); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index e1f85ae9da59..a372184ac210 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -238,4 +238,9 @@ void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); +#ifdef CONFIG_IWLWIFI_DEBUG +const char *iwl_get_agg_tx_fail_reason(u16 status); +#else +static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } +#endif #endif /* __iwl_agn_h__ */ -- cgit v1.2.3 From 0b7e5e85b0317f06d92704a5be42cc101a552ab5 Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Wed, 8 Sep 2010 09:42:35 -0700 Subject: iwlwifi: corrections to debug output of ucode statistics remove duplicate header and clean up format so it is defined once making changes consolicated ensuring consistancy of output. no function change to date displayed. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 357 ++++++++++--------------- 1 file changed, 135 insertions(+), 222 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index 52e98691ddfd..33862ff56d0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -28,6 +28,12 @@ #include "iwl-agn.h" #include "iwl-agn-debugfs.h" +static const char *fmt_value = " %-30s %10u\n"; +static const char *fmt_hex = " %-30s 0x%02X\n"; +static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; +static const char *fmt_header = + "%-32s current cumulative delta max\n"; + static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) { int p = 0; @@ -121,436 +127,380 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), + fmt_header, "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", + le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt, delta_ofdm->ina_cnt, max_ofdm->ina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", + fmt_table, "fina_cnt:", le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, delta_ofdm->fina_cnt, max_ofdm->fina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_table, "plcp_err:", le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, delta_ofdm->plcp_err, max_ofdm->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, delta_ofdm->crc32_err, max_ofdm->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(ofdm->overrun_err), accum_ofdm->overrun_err, delta_ofdm->overrun_err, max_ofdm->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(ofdm->early_overrun_err), accum_ofdm->early_overrun_err, delta_ofdm->early_overrun_err, max_ofdm->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", le32_to_cpu(ofdm->crc32_good), + fmt_table, "crc32_good:", + le32_to_cpu(ofdm->crc32_good), accum_ofdm->crc32_good, delta_ofdm->crc32_good, max_ofdm->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", + fmt_table, "false_alarm_cnt:", le32_to_cpu(ofdm->false_alarm_cnt), accum_ofdm->false_alarm_cnt, delta_ofdm->false_alarm_cnt, max_ofdm->false_alarm_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", + fmt_table, "fina_sync_err_cnt:", le32_to_cpu(ofdm->fina_sync_err_cnt), accum_ofdm->fina_sync_err_cnt, delta_ofdm->fina_sync_err_cnt, max_ofdm->fina_sync_err_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sfd_timeout:", + fmt_table, "sfd_timeout:", le32_to_cpu(ofdm->sfd_timeout), accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, max_ofdm->sfd_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "fina_timeout:", + fmt_table, "fina_timeout:", le32_to_cpu(ofdm->fina_timeout), accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, max_ofdm->fina_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", + fmt_table, "unresponded_rts:", le32_to_cpu(ofdm->unresponded_rts), accum_ofdm->unresponded_rts, delta_ofdm->unresponded_rts, max_ofdm->unresponded_rts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", + fmt_table, "rxe_frame_lmt_ovrun:", le32_to_cpu(ofdm->rxe_frame_limit_overrun), accum_ofdm->rxe_frame_limit_overrun, delta_ofdm->rxe_frame_limit_overrun, max_ofdm->rxe_frame_limit_overrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:", + fmt_table, "sent_ack_cnt:", le32_to_cpu(ofdm->sent_ack_cnt), accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, max_ofdm->sent_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:", + fmt_table, "sent_cts_cnt:", le32_to_cpu(ofdm->sent_cts_cnt), accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ba_rsp_cnt:", + fmt_table, "sent_ba_rsp_cnt:", le32_to_cpu(ofdm->sent_ba_rsp_cnt), accum_ofdm->sent_ba_rsp_cnt, delta_ofdm->sent_ba_rsp_cnt, max_ofdm->sent_ba_rsp_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:", + fmt_table, "dsp_self_kill:", le32_to_cpu(ofdm->dsp_self_kill), accum_ofdm->dsp_self_kill, delta_ofdm->dsp_self_kill, max_ofdm->dsp_self_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(ofdm->mh_format_err), accum_ofdm->mh_format_err, delta_ofdm->mh_format_err, max_ofdm->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "re_acq_main_rssi_sum:", + fmt_table, "re_acq_main_rssi_sum:", le32_to_cpu(ofdm->re_acq_main_rssi_sum), accum_ofdm->re_acq_main_rssi_sum, delta_ofdm->re_acq_main_rssi_sum, max_ofdm->re_acq_main_rssi_sum); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - CCK:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", + fmt_header, "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, delta_cck->ina_cnt, max_cck->ina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", + fmt_table, "fina_cnt:", le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, delta_cck->fina_cnt, max_cck->fina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_table, "plcp_err:", le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, delta_cck->plcp_err, max_cck->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, delta_cck->crc32_err, max_cck->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(cck->overrun_err), accum_cck->overrun_err, delta_cck->overrun_err, max_cck->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(cck->early_overrun_err), accum_cck->early_overrun_err, delta_cck->early_overrun_err, max_cck->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", + fmt_table, "crc32_good:", le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, delta_cck->crc32_good, max_cck->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "false_alarm_cnt:", + fmt_table, "false_alarm_cnt:", le32_to_cpu(cck->false_alarm_cnt), accum_cck->false_alarm_cnt, delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", + fmt_table, "fina_sync_err_cnt:", le32_to_cpu(cck->fina_sync_err_cnt), accum_cck->fina_sync_err_cnt, delta_cck->fina_sync_err_cnt, max_cck->fina_sync_err_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", + fmt_table, "sfd_timeout:", le32_to_cpu(cck->sfd_timeout), accum_cck->sfd_timeout, delta_cck->sfd_timeout, max_cck->sfd_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "fina_timeout:", + fmt_table, "fina_timeout:", le32_to_cpu(cck->fina_timeout), accum_cck->fina_timeout, delta_cck->fina_timeout, max_cck->fina_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", + fmt_table, "unresponded_rts:", le32_to_cpu(cck->unresponded_rts), accum_cck->unresponded_rts, delta_cck->unresponded_rts, max_cck->unresponded_rts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", + fmt_table, "rxe_frame_lmt_ovrun:", le32_to_cpu(cck->rxe_frame_limit_overrun), accum_cck->rxe_frame_limit_overrun, delta_cck->rxe_frame_limit_overrun, max_cck->rxe_frame_limit_overrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:", + fmt_table, "sent_ack_cnt:", le32_to_cpu(cck->sent_ack_cnt), accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, max_cck->sent_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:", + fmt_table, "sent_cts_cnt:", le32_to_cpu(cck->sent_cts_cnt), accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, max_cck->sent_cts_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:", + fmt_table, "sent_ba_rsp_cnt:", le32_to_cpu(cck->sent_ba_rsp_cnt), accum_cck->sent_ba_rsp_cnt, delta_cck->sent_ba_rsp_cnt, max_cck->sent_ba_rsp_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:", + fmt_table, "dsp_self_kill:", le32_to_cpu(cck->dsp_self_kill), accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, max_cck->dsp_self_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(cck->mh_format_err), accum_cck->mh_format_err, delta_cck->mh_format_err, max_cck->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "re_acq_main_rssi_sum:", + fmt_table, "re_acq_main_rssi_sum:", le32_to_cpu(cck->re_acq_main_rssi_sum), accum_cck->re_acq_main_rssi_sum, delta_cck->re_acq_main_rssi_sum, max_cck->re_acq_main_rssi_sum); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - GENERAL:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "bogus_cts:", + fmt_header, "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bogus_cts:", le32_to_cpu(general->bogus_cts), accum_general->bogus_cts, delta_general->bogus_cts, max_general->bogus_cts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "bogus_ack:", + fmt_table, "bogus_ack:", le32_to_cpu(general->bogus_ack), accum_general->bogus_ack, delta_general->bogus_ack, max_general->bogus_ack); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_bssid_frames:", + fmt_table, "non_bssid_frames:", le32_to_cpu(general->non_bssid_frames), accum_general->non_bssid_frames, delta_general->non_bssid_frames, max_general->non_bssid_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "filtered_frames:", + fmt_table, "filtered_frames:", le32_to_cpu(general->filtered_frames), accum_general->filtered_frames, delta_general->filtered_frames, max_general->filtered_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_channel_beacons:", + fmt_table, "non_channel_beacons:", le32_to_cpu(general->non_channel_beacons), accum_general->non_channel_beacons, delta_general->non_channel_beacons, max_general->non_channel_beacons); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "channel_beacons:", + fmt_table, "channel_beacons:", le32_to_cpu(general->channel_beacons), accum_general->channel_beacons, delta_general->channel_beacons, max_general->channel_beacons); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "num_missed_bcon:", + fmt_table, "num_missed_bcon:", le32_to_cpu(general->num_missed_bcon), accum_general->num_missed_bcon, delta_general->num_missed_bcon, max_general->num_missed_bcon); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "adc_rx_saturation_time:", + fmt_table, "adc_rx_saturation_time:", le32_to_cpu(general->adc_rx_saturation_time), accum_general->adc_rx_saturation_time, delta_general->adc_rx_saturation_time, max_general->adc_rx_saturation_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_detect_search_tm:", + fmt_table, "ina_detect_search_tm:", le32_to_cpu(general->ina_detection_search_time), accum_general->ina_detection_search_time, delta_general->ina_detection_search_time, max_general->ina_detection_search_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_a:", + fmt_table, "beacon_silence_rssi_a:", le32_to_cpu(general->beacon_silence_rssi_a), accum_general->beacon_silence_rssi_a, delta_general->beacon_silence_rssi_a, max_general->beacon_silence_rssi_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_b:", + fmt_table, "beacon_silence_rssi_b:", le32_to_cpu(general->beacon_silence_rssi_b), accum_general->beacon_silence_rssi_b, delta_general->beacon_silence_rssi_b, max_general->beacon_silence_rssi_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_c:", + fmt_table, "beacon_silence_rssi_c:", le32_to_cpu(general->beacon_silence_rssi_c), accum_general->beacon_silence_rssi_c, delta_general->beacon_silence_rssi_c, max_general->beacon_silence_rssi_c); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "interference_data_flag:", + fmt_table, "interference_data_flag:", le32_to_cpu(general->interference_data_flag), accum_general->interference_data_flag, delta_general->interference_data_flag, max_general->interference_data_flag); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "channel_load:", + fmt_table, "channel_load:", le32_to_cpu(general->channel_load), accum_general->channel_load, delta_general->channel_load, max_general->channel_load); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "dsp_false_alarms:", + fmt_table, "dsp_false_alarms:", le32_to_cpu(general->dsp_false_alarms), accum_general->dsp_false_alarms, delta_general->dsp_false_alarms, max_general->dsp_false_alarms); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_a:", + fmt_table, "beacon_rssi_a:", le32_to_cpu(general->beacon_rssi_a), accum_general->beacon_rssi_a, delta_general->beacon_rssi_a, max_general->beacon_rssi_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_b:", + fmt_table, "beacon_rssi_b:", le32_to_cpu(general->beacon_rssi_b), accum_general->beacon_rssi_b, delta_general->beacon_rssi_b, max_general->beacon_rssi_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_c:", + fmt_table, "beacon_rssi_c:", le32_to_cpu(general->beacon_rssi_c), accum_general->beacon_rssi_c, delta_general->beacon_rssi_c, max_general->beacon_rssi_c); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_a:", + fmt_table, "beacon_energy_a:", le32_to_cpu(general->beacon_energy_a), accum_general->beacon_energy_a, delta_general->beacon_energy_a, max_general->beacon_energy_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_b:", + fmt_table, "beacon_energy_b:", le32_to_cpu(general->beacon_energy_b), accum_general->beacon_energy_b, delta_general->beacon_energy_b, max_general->beacon_energy_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_c:", + fmt_table, "beacon_energy_c:", le32_to_cpu(general->beacon_energy_c), accum_general->beacon_energy_c, delta_general->beacon_energy_c, max_general->beacon_energy_c); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM_HT:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_header, "Statistics_Rx - OFDM_HT:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "plcp_err:", le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, delta_ht->plcp_err, max_ht->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, delta_ht->overrun_err, max_ht->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(ht->early_overrun_err), accum_ht->early_overrun_err, delta_ht->early_overrun_err, max_ht->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", + fmt_table, "crc32_good:", le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, delta_ht->crc32_good, max_ht->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, delta_ht->crc32_err, max_ht->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(ht->mh_format_err), accum_ht->mh_format_err, delta_ht->mh_format_err, max_ht->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_crc32_good:", + fmt_table, "agg_crc32_good:", le32_to_cpu(ht->agg_crc32_good), accum_ht->agg_crc32_good, delta_ht->agg_crc32_good, max_ht->agg_crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_mpdu_cnt:", + fmt_table, "agg_mpdu_cnt:", le32_to_cpu(ht->agg_mpdu_cnt), accum_ht->agg_mpdu_cnt, delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_cnt:", + fmt_table, "agg_cnt:", le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, delta_ht->agg_cnt, max_ht->agg_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unsupport_mcs:", + fmt_table, "unsupport_mcs:", le32_to_cpu(ht->unsupport_mcs), accum_ht->unsupport_mcs, delta_ht->unsupport_mcs, max_ht->unsupport_mcs); @@ -597,166 +547,141 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Tx:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "preamble:", + fmt_header, "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "preamble:", le32_to_cpu(tx->preamble_cnt), accum_tx->preamble_cnt, delta_tx->preamble_cnt, max_tx->preamble_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_detected_cnt:", + fmt_table, "rx_detected_cnt:", le32_to_cpu(tx->rx_detected_cnt), accum_tx->rx_detected_cnt, delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_defer_cnt:", + fmt_table, "bt_prio_defer_cnt:", le32_to_cpu(tx->bt_prio_defer_cnt), accum_tx->bt_prio_defer_cnt, delta_tx->bt_prio_defer_cnt, max_tx->bt_prio_defer_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_kill_cnt:", + fmt_table, "bt_prio_kill_cnt:", le32_to_cpu(tx->bt_prio_kill_cnt), accum_tx->bt_prio_kill_cnt, delta_tx->bt_prio_kill_cnt, max_tx->bt_prio_kill_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "few_bytes_cnt:", + fmt_table, "few_bytes_cnt:", le32_to_cpu(tx->few_bytes_cnt), accum_tx->few_bytes_cnt, delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout:", + fmt_table, "cts_timeout:", le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, delta_tx->cts_timeout, max_tx->cts_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_timeout:", + fmt_table, "ack_timeout:", le32_to_cpu(tx->ack_timeout), accum_tx->ack_timeout, delta_tx->ack_timeout, max_tx->ack_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "expected_ack_cnt:", + fmt_table, "expected_ack_cnt:", le32_to_cpu(tx->expected_ack_cnt), accum_tx->expected_ack_cnt, delta_tx->expected_ack_cnt, max_tx->expected_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "actual_ack_cnt:", + fmt_table, "actual_ack_cnt:", le32_to_cpu(tx->actual_ack_cnt), accum_tx->actual_ack_cnt, delta_tx->actual_ack_cnt, max_tx->actual_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "dump_msdu_cnt:", + fmt_table, "dump_msdu_cnt:", le32_to_cpu(tx->dump_msdu_cnt), accum_tx->dump_msdu_cnt, delta_tx->dump_msdu_cnt, max_tx->dump_msdu_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "abort_nxt_frame_mismatch:", + fmt_table, "abort_nxt_frame_mismatch:", le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), accum_tx->burst_abort_next_frame_mismatch_cnt, delta_tx->burst_abort_next_frame_mismatch_cnt, max_tx->burst_abort_next_frame_mismatch_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "abort_missing_nxt_frame:", + fmt_table, "abort_missing_nxt_frame:", le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), accum_tx->burst_abort_missing_next_frame_cnt, delta_tx->burst_abort_missing_next_frame_cnt, max_tx->burst_abort_missing_next_frame_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout_collision:", + fmt_table, "cts_timeout_collision:", le32_to_cpu(tx->cts_timeout_collision), accum_tx->cts_timeout_collision, delta_tx->cts_timeout_collision, max_tx->cts_timeout_collision); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_ba_timeout_collision:", + fmt_table, "ack_ba_timeout_collision:", le32_to_cpu(tx->ack_or_ba_timeout_collision), accum_tx->ack_or_ba_timeout_collision, delta_tx->ack_or_ba_timeout_collision, max_tx->ack_or_ba_timeout_collision); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg ba_timeout:", + fmt_table, "agg ba_timeout:", le32_to_cpu(tx->agg.ba_timeout), accum_tx->agg.ba_timeout, delta_tx->agg.ba_timeout, max_tx->agg.ba_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg ba_resched_frames:", + fmt_table, "agg ba_resched_frames:", le32_to_cpu(tx->agg.ba_reschedule_frames), accum_tx->agg.ba_reschedule_frames, delta_tx->agg.ba_reschedule_frames, max_tx->agg.ba_reschedule_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_agg_frame:", + fmt_table, "agg scd_query_agg_frame:", le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), accum_tx->agg.scd_query_agg_frame_cnt, delta_tx->agg.scd_query_agg_frame_cnt, max_tx->agg.scd_query_agg_frame_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_no_agg:", + fmt_table, "agg scd_query_no_agg:", le32_to_cpu(tx->agg.scd_query_no_agg), accum_tx->agg.scd_query_no_agg, delta_tx->agg.scd_query_no_agg, max_tx->agg.scd_query_no_agg); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_agg:", + fmt_table, "agg scd_query_agg:", le32_to_cpu(tx->agg.scd_query_agg), accum_tx->agg.scd_query_agg, delta_tx->agg.scd_query_agg, max_tx->agg.scd_query_agg); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_mismatch:", + fmt_table, "agg scd_query_mismatch:", le32_to_cpu(tx->agg.scd_query_mismatch), accum_tx->agg.scd_query_mismatch, delta_tx->agg.scd_query_mismatch, max_tx->agg.scd_query_mismatch); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg frame_not_ready:", + fmt_table, "agg frame_not_ready:", le32_to_cpu(tx->agg.frame_not_ready), accum_tx->agg.frame_not_ready, delta_tx->agg.frame_not_ready, max_tx->agg.frame_not_ready); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg underrun:", + fmt_table, "agg underrun:", le32_to_cpu(tx->agg.underrun), accum_tx->agg.underrun, delta_tx->agg.underrun, max_tx->agg.underrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg bt_prio_kill:", + fmt_table, "agg bt_prio_kill:", le32_to_cpu(tx->agg.bt_prio_kill), accum_tx->agg.bt_prio_kill, delta_tx->agg.bt_prio_kill, max_tx->agg.bt_prio_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg rx_ba_rsp_cnt:", + fmt_table, "agg rx_ba_rsp_cnt:", le32_to_cpu(tx->agg.rx_ba_rsp_cnt), accum_tx->agg.rx_ba_rsp_cnt, delta_tx->agg.rx_ba_rsp_cnt, @@ -767,15 +692,15 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, "tx power: (1/2 dB step)\n"); if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna A: 0x%X\n", + fmt_hex, "antenna A:", tx->tx_power.ant_a); if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna B: 0x%X\n", + fmt_hex, "antenna B:", tx->tx_power.ant_b); if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna C: 0x%X\n", + fmt_hex, "antenna C:", tx->tx_power.ant_c); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -838,84 +763,72 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_General:"); - pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n", - "temperature:", + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "temperature:", le32_to_cpu(general->temperature)); - pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n", - "temperature_m:", + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "temperature_m:", le32_to_cpu(general->temperature_m)); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_check:", + fmt_value, "ttl_timestamp:", + le32_to_cpu(general->ttl_timestamp)); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "burst_check:", le32_to_cpu(dbg->burst_check), accum_dbg->burst_check, delta_dbg->burst_check, max_dbg->burst_check); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_count:", + fmt_table, "burst_count:", le32_to_cpu(dbg->burst_count), accum_dbg->burst_count, delta_dbg->burst_count, max_dbg->burst_count); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "wait_for_silence_timeout_count:", + fmt_table, "wait_for_silence_timeout_count:", le32_to_cpu(dbg->wait_for_silence_timeout_cnt), accum_dbg->wait_for_silence_timeout_cnt, delta_dbg->wait_for_silence_timeout_cnt, max_dbg->wait_for_silence_timeout_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sleep_time:", + fmt_table, "sleep_time:", le32_to_cpu(general->sleep_time), accum_general->sleep_time, delta_general->sleep_time, max_general->sleep_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_out:", + fmt_table, "slots_out:", le32_to_cpu(general->slots_out), accum_general->slots_out, delta_general->slots_out, max_general->slots_out); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_idle:", + fmt_table, "slots_idle:", le32_to_cpu(general->slots_idle), accum_general->slots_idle, delta_general->slots_idle, max_general->slots_idle); - pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", - le32_to_cpu(general->ttl_timestamp)); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_a:", + fmt_table, "tx_on_a:", le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, delta_div->tx_on_a, max_div->tx_on_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_b:", + fmt_table, "tx_on_b:", le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, delta_div->tx_on_b, max_div->tx_on_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "exec_time:", + fmt_table, "exec_time:", le32_to_cpu(div->exec_time), accum_div->exec_time, delta_div->exec_time, max_div->exec_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "probe_time:", + fmt_table, "probe_time:", le32_to_cpu(div->probe_time), accum_div->probe_time, delta_div->probe_time, max_div->probe_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_enable_counter:", + fmt_table, "rx_enable_counter:", le32_to_cpu(general->rx_enable_counter), accum_general->rx_enable_counter, delta_general->rx_enable_counter, max_general->rx_enable_counter); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "num_of_sos_states:", + fmt_table, "num_of_sos_states:", le32_to_cpu(general->num_of_sos_states), accum_general->num_of_sos_states, delta_general->num_of_sos_states, -- cgit v1.2.3 From 1d270075be62fb8212bd5afebd0bab693759a1a0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 7 Sep 2010 12:42:20 -0700 Subject: iwlagn: correct naming for failure reply tx status For failure tx status 0x90 and 0x91, give the correct name to reflect the errors. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 9 ++------- drivers/net/wireless/iwlwifi/iwl-tx.c | 4 ++-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index 33862ff56d0d..5391b4627397 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -1009,11 +1009,11 @@ ssize_t iwl_reply_tx_error_read(struct file *file, TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), priv->_agn.reply_tx_stats.insuff_cf_poll); pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", - iwl_get_tx_fail_reason(TX_STATUS_FAIL_FW_DROP), + iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), priv->_agn.reply_tx_stats.fail_hw_drop); - pos += scnprintf(buf + pos, bufsz - pos, "%s:\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", iwl_get_tx_fail_reason( - TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP), + TX_STATUS_FAIL_NO_BEACON_ON_RADAR), priv->_agn.reply_tx_stats.sta_color_mismatch); pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", priv->_agn.reply_tx_stats.unknown); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c42cb18de833..616115ab009d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -111,10 +111,10 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL: priv->_agn.reply_tx_stats.insuff_cf_poll++; break; - case TX_STATUS_FAIL_FW_DROP: + case TX_STATUS_FAIL_PASSIVE_NO_RX: priv->_agn.reply_tx_stats.fail_hw_drop++; break; - case TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP: + case TX_STATUS_FAIL_NO_BEACON_ON_RADAR: priv->_agn.reply_tx_stats.sta_color_mismatch++; break; default: diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index dd47acafa25b..294a1d559e3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1820,13 +1820,8 @@ enum { TX_STATUS_FAIL_TID_DISABLE = 0x8d, TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, - /* uCode drop due to FW drop request */ - TX_STATUS_FAIL_FW_DROP = 0x90, - /* - * uCode drop due to station color mismatch - * between tx command and station table - */ - TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP = 0x91, + TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90, + TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, }; #define TX_PACKET_MODE_REGULAR 0x0000 diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 347d3dc6a015..3290b1552f5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -666,8 +666,8 @@ const char *iwl_get_tx_fail_reason(u32 status) TX_STATUS_FAIL(TID_DISABLE); TX_STATUS_FAIL(FIFO_FLUSHED); TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); - TX_STATUS_FAIL(FW_DROP); - TX_STATUS_FAIL(STA_COLOR_MISMATCH_DROP); + TX_STATUS_FAIL(PASSIVE_NO_RX); + TX_STATUS_FAIL(NO_BEACON_ON_RADAR); } return "UNKNOWN"; -- cgit v1.2.3 From b345f4da42da69f7136ea1b83ef38b3412e51b72 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 13 Sep 2010 07:51:03 -0700 Subject: iwlagn: minor coex API changes Adding two new parameters in config bt API. these two parameters use the 3 reserved bytes, so there is no structure size changes. Make sure set both parameters to "zero" in order to preserve previous behavior. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 294a1d559e3c..27e250c8d4b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2486,7 +2486,12 @@ struct iwlagn_bt_cmd { __le16 bt4_decision_time; /* unused */ __le16 valid; u8 prio_boost; - u8 reserved[3]; + /* + * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask + * if configure the following patterns + */ + u8 tx_prio_boost; /* SW boost of WiFi tx priority */ + __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ }; #define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) -- cgit v1.2.3 From 09f250ac8faefa9deb14854e4715a139ed99617b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 13 Sep 2010 08:08:18 -0700 Subject: iwlagn: initialize both tx/rx prio boost parameters For config bt command, initialize both tx_prio_boost and rx_prio_boost to "0". Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 616115ab009d..299fd9d59604 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1781,6 +1781,8 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) bt_cmd.kill_ack_mask = priv->kill_ack_mask; bt_cmd.kill_cts_mask = priv->kill_cts_mask; bt_cmd.valid = priv->bt_valid; + bt_cmd.tx_prio_boost = 0; + bt_cmd.rx_prio_boost = 0; /* * Configure BT coex mode to "no coexistence" when the -- cgit v1.2.3 From dfb8fb96ae2b5126cd0c08c0ccd7c42e1f46568a Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 17 Sep 2010 03:23:39 +0000 Subject: stmmac: add CSR Clock range selection This patch adds the CSR Clock range selection. Original patch from Johannes Stezenbach fixed the CSR in the stmmac_mdio. We agreed to provide this through the platform instead of. Also thanks to Johannes for having tested it on ARM. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Johannes Stezenbach Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 1 + drivers/net/stmmac/stmmac_main.c | 1 + drivers/net/stmmac/stmmac_mdio.c | 5 +++-- include/linux/stmmac.h | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index d0ddab0d21c2..12d1cb00c0d7 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -78,6 +78,7 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; + int mii_clk_csr; u32 msg_enable; spinlock_t lock; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 03c160c6d75c..a169b1441d50 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1704,6 +1704,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) plat_dat = pdev->dev.platform_data; priv->bus_id = plat_dat->bus_id; priv->pbl = plat_dat->pbl; /* TLI */ + priv->mii_clk_csr = plat_dat->clk_csr; priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ priv->enh_desc = plat_dat->enh_desc; priv->ioaddr = addr; diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 03dea1401571..d7441616357d 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -53,7 +53,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) int data; u16 regValue = (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))); - regValue |= MII_BUSY; /* in case of GMAC */ + regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); writel(regValue, priv->ioaddr + mii_address); @@ -85,7 +85,8 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) | MII_WRITE; - value |= MII_BUSY; + value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); + /* Wait until any existing MII operation is complete */ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index a4adf0de6ed6..c87c88ccffc0 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -32,6 +32,7 @@ struct plat_stmmacenet_data { int bus_id; int pbl; + int clk_csr; int has_gmac; int enh_desc; void (*fix_mac_speed)(void *priv, unsigned int speed); -- cgit v1.2.3 From ebbb293f8b3021ae2009fcb7cb3b8a52fb5fd06a Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 17 Sep 2010 03:23:40 +0000 Subject: stmmac: consolidate and tidy-up the COE support The first version of the driver had hard-coded the logic for handling the checksum offloading. This was designed according to the chips included in the STM platforms where: o MAC10/100 supports no COE at all. o GMAC fully supports RX/TX COE. This is not good for other chip configurations where, for example, the mac10/100 supports the tx csum in HW or when the GMAC has no IPC. Thanks to Johannes Stezenbach; he provided me a first draft of this patch that only reviewed the IPC for the GMAC devices. This patch also helps on SPEAr platforms where the MAC10/100 can perform the TX csum in HW. Thanks to Deepak SIKRI for his support on this. In the end, GMAC devices for STM platforms have a bugged Jumbo frame support that needs to have the Tx COE disabled for oversized frames (due to limited buffer sizes). This information is also passed through the driver's platform structure. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Johannes Stezenbach Signed-off-by: Deepak SIKRI Signed-off-by: David S. Miller --- drivers/net/stmmac/common.h | 4 +-- drivers/net/stmmac/dwmac1000.h | 2 +- drivers/net/stmmac/dwmac1000_core.c | 13 ++++++++ drivers/net/stmmac/dwmac100_core.c | 6 ++++ drivers/net/stmmac/stmmac.h | 4 ++- drivers/net/stmmac/stmmac_ethtool.c | 2 +- drivers/net/stmmac/stmmac_main.c | 66 ++++++++++++++++++------------------- include/linux/stmmac.h | 2 ++ 8 files changed, 60 insertions(+), 39 deletions(-) diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index e8cbcb5c206e..673ef86a063f 100644 --- a/drivers/net/stmmac/common.h +++ b/drivers/net/stmmac/common.h @@ -102,8 +102,6 @@ struct stmmac_extra_stats { #define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */ -#define HW_CSUM 1 -#define NO_HW_CSUM 0 enum rx_frame_status { /* IPC status */ good_frame = 0, discard_frame = 1, @@ -205,6 +203,8 @@ struct stmmac_dma_ops { struct stmmac_ops { /* MAC core initialization */ void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned; + /* Support checksum offload engine */ + int (*rx_coe) (void __iomem *ioaddr); /* Dump MAC registers */ void (*dump_regs) (void __iomem *ioaddr); /* Handle extra events on specific interrupts hw dependent */ diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h index 8b20b19971cb..81ee4fd04386 100644 --- a/drivers/net/stmmac/dwmac1000.h +++ b/drivers/net/stmmac/dwmac1000.h @@ -99,7 +99,7 @@ enum inter_frame_gap { #define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ #define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ - GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE) + GMAC_CONTROL_JE | GMAC_CONTROL_BE) /* GMAC Frame Filter defines */ #define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index f1f426146f40..c18c85993179 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -50,6 +50,18 @@ static void dwmac1000_core_init(void __iomem *ioaddr) #endif } +static int dwmac1000_rx_coe_supported(void __iomem *ioaddr) +{ + u32 value = readl(ioaddr + GMAC_CONTROL); + + value |= GMAC_CONTROL_IPC; + writel(value, ioaddr + GMAC_CONTROL); + + value = readl(ioaddr + GMAC_CONTROL); + + return !!(value & GMAC_CONTROL_IPC); +} + static void dwmac1000_dump_regs(void __iomem *ioaddr) { int i; @@ -202,6 +214,7 @@ static void dwmac1000_irq_status(void __iomem *ioaddr) struct stmmac_ops dwmac1000_ops = { .core_init = dwmac1000_core_init, + .rx_coe = dwmac1000_rx_coe_supported, .dump_regs = dwmac1000_dump_regs, .host_irq_status = dwmac1000_irq_status, .set_filter = dwmac1000_set_filter, diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index db06c04ce480..58a914b27003 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -42,6 +42,11 @@ static void dwmac100_core_init(void __iomem *ioaddr) #endif } +static int dwmac100_rx_coe_supported(void __iomem *ioaddr) +{ + return 0; +} + static void dwmac100_dump_mac_regs(void __iomem *ioaddr) { pr_info("\t----------------------------------------------\n" @@ -165,6 +170,7 @@ static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode) struct stmmac_ops dwmac100_ops = { .core_init = dwmac100_core_init, + .rx_coe = dwmac100_rx_coe_supported, .dump_regs = dwmac100_dump_mac_regs, .host_irq_status = dwmac100_irq_status, .set_filter = dwmac100_set_filter, diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 12d1cb00c0d7..92154ff7d702 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -51,7 +51,6 @@ struct stmmac_priv { int is_gmac; dma_addr_t dma_rx_phy; unsigned int dma_rx_size; - int rx_csum; unsigned int dma_buf_sz; struct device *device; struct mac_device_info *hw; @@ -92,6 +91,9 @@ struct stmmac_priv { struct vlan_group *vlgrp; #endif int enh_desc; + int rx_coe; + int bugged_jumbo; + int no_csum_insertion; }; #ifdef CONFIG_STM_DRIVERS diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 63b68e61afce..b32c16ae55c6 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -209,7 +209,7 @@ u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - return priv->rx_csum; + return priv->rx_coe; } static void diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index a169b1441d50..a908f7201aae 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -134,13 +134,6 @@ static int buf_sz = DMA_BUFFER_SIZE; module_param(buf_sz, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(buf_sz, "DMA buffer size"); -/* In case of Giga ETH, we can enable/disable the COE for the - * transmit HW checksum computation. - * Note that, if tx csum is off in HW, SG will be still supported. */ -static int tx_coe = HW_CSUM; -module_param(tx_coe, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]"); - static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); @@ -569,29 +562,22 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) * stmmac_dma_operation_mode - HW DMA operation mode * @priv : pointer to the private device structure. * Description: it sets the DMA operation mode: tx/rx DMA thresholds - * or Store-And-Forward capability. It also verifies the COE for the - * transmission in case of Giga ETH. + * or Store-And-Forward capability. */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { - if (!priv->is_gmac) { - /* MAC 10/100 */ - priv->hw->dma->dma_mode(priv->ioaddr, tc, 0); - priv->tx_coe = NO_HW_CSUM; - } else { - if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) { - priv->hw->dma->dma_mode(priv->ioaddr, - SF_DMA_MODE, SF_DMA_MODE); - tc = SF_DMA_MODE; - priv->tx_coe = HW_CSUM; - } else { - /* Checksum computation is performed in software. */ - priv->hw->dma->dma_mode(priv->ioaddr, tc, - SF_DMA_MODE); - priv->tx_coe = NO_HW_CSUM; - } - } - tx_coe = priv->tx_coe; + if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) { + /* In case of GMAC, SF mode has to be enabled + * to perform the TX COE. This depends on: + * 1) TX COE if actually supported + * 2) There is no bugged Jumbo frame support + * that needs to not insert csum in the TDES. + */ + priv->hw->dma->dma_mode(priv->ioaddr, + SF_DMA_MODE, SF_DMA_MODE); + tc = SF_DMA_MODE; + } else + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); } /** @@ -858,6 +844,12 @@ static int stmmac_open(struct net_device *dev) /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); + priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); + if (priv->rx_coe) + pr_info("stmmac: Rx Checksum Offload Engine supported\n"); + if (priv->tx_coe) + pr_info("\tTX Checksum insertion supported\n"); + priv->shutdown = 0; /* Initialise the MMC (if present) to disable all interrupts. */ @@ -1066,7 +1058,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return stmmac_sw_tso(priv, skb); if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { - if (likely(priv->tx_coe == NO_HW_CSUM)) + if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion))) skb_checksum_help(skb); else csum_insertion = 1; @@ -1390,6 +1382,15 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } + /* Some GMAC devices have a bugged Jumbo frame support that + * needs to have the Tx COE disabled for oversized frames + * (due to limited buffer sizes). In this case we disable + * the TX csum insertionin the TDES and not use SF. */ + if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) + priv->no_csum_insertion = 1; + else + priv->no_csum_insertion = 0; + dev->mtu = new_mtu; return 0; @@ -1510,9 +1511,6 @@ static int stmmac_probe(struct net_device *dev) #endif priv->msg_enable = netif_msg_init(debug, default_msg_level); - if (priv->is_gmac) - priv->rx_csum = 1; - if (flow_ctrl) priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ @@ -1662,7 +1660,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) ret = -ENODEV; goto out; } - pr_info("done!\n"); + pr_info("\tdone!\n"); if (!request_mem_region(res->start, resource_size(res), pdev->name)) { @@ -1705,6 +1703,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->bus_id = plat_dat->bus_id; priv->pbl = plat_dat->pbl; /* TLI */ priv->mii_clk_csr = plat_dat->clk_csr; + priv->tx_coe = plat_dat->tx_coe; + priv->bugged_jumbo = plat_dat->bugged_jumbo; priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ priv->enh_desc = plat_dat->enh_desc; priv->ioaddr = addr; @@ -1966,8 +1966,6 @@ static int __init stmmac_cmdline_opt(char *str) strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); else if (!strncmp(opt, "tc:", 3)) strict_strtoul(opt + 3, 0, (unsigned long *)&tc); - else if (!strncmp(opt, "tx_coe:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe); else if (!strncmp(opt, "watchdog:", 9)) strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); else if (!strncmp(opt, "flow_ctrl:", 10)) diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index c87c88ccffc0..1d8baf719211 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -35,6 +35,8 @@ struct plat_stmmacenet_data { int clk_csr; int has_gmac; int enh_desc; + int tx_coe; + int bugged_jumbo; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); #ifdef CONFIG_STM_DRIVERS -- cgit v1.2.3 From c629882ac73cab2cd41d9948caeed633fc570fc0 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 17 Sep 2010 03:23:41 +0000 Subject: stmmac: prevent dma init stuck in case of failures. Add a limit when perform the DMA reset procedure so, in case of problems (i.e. PHY reset failed) the Kernel won't hang on the stmmac DMA initialisation blocking the Kernels execution. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/dwmac1000_dma.c | 10 +++++++++- drivers/net/stmmac/dwmac100_dma.c | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c index 2ef5a56370e9..ce6163e39cd5 100644 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ b/drivers/net/stmmac/dwmac1000_dma.c @@ -33,10 +33,18 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); + int limit; + /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)); + limit = 15000; + while (limit--) { + if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) + break; + } + if (limit < 0) + return -EBUSY; value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) | diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c index c7279d2b946b..96aac93b789b 100644 --- a/drivers/net/stmmac/dwmac100_dma.c +++ b/drivers/net/stmmac/dwmac100_dma.c @@ -35,10 +35,18 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); + int limit; + /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)); + limit = 15000; + while (limit--) { + if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) + break; + } + if (limit < 0) + return -EBUSY; /* Enable Application Access by writing to DMA CSR0 */ writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT), -- cgit v1.2.3 From b71c7aaa1e2a9858f0c469026098fbd6e046d7bb Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Fri, 17 Sep 2010 03:23:42 +0000 Subject: stmmac: use one memset() to reset TDES01 Use one memset() to reset all TDES01 fields instead of one by one to reduce number of instructions. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/enh_desc.c | 2 +- drivers/net/stmmac/norm_desc.c | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c index 77ff88c3958b..5d1471d8f8f6 100644 --- a/drivers/net/stmmac/enh_desc.c +++ b/drivers/net/stmmac/enh_desc.c @@ -284,7 +284,7 @@ static void enh_desc_release_tx_desc(struct dma_desc *p) { int ter = p->des01.etx.end_ring; - memset(p, 0, sizeof(struct dma_desc)); + memset(p, 0, offsetof(struct dma_desc, des2)); p->des01.etx.end_ring = ter; } diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c index 51f4440ab98b..0dce90cb8124 100644 --- a/drivers/net/stmmac/norm_desc.c +++ b/drivers/net/stmmac/norm_desc.c @@ -174,22 +174,7 @@ static void ndesc_release_tx_desc(struct dma_desc *p) { int ter = p->des01.tx.end_ring; - /* clean field used within the xmit */ - p->des01.tx.first_segment = 0; - p->des01.tx.last_segment = 0; - p->des01.tx.buffer1_size = 0; - - /* clean status reported */ - p->des01.tx.error_summary = 0; - p->des01.tx.underflow_error = 0; - p->des01.tx.no_carrier = 0; - p->des01.tx.loss_carrier = 0; - p->des01.tx.excessive_deferral = 0; - p->des01.tx.excessive_collisions = 0; - p->des01.tx.late_collision = 0; - p->des01.tx.heartbeat_fail = 0; - p->des01.tx.deferred = 0; - + memset(p, 0, offsetof(struct dma_desc, des2)); /* set termination field */ p->des01.tx.end_ring = ter; } -- cgit v1.2.3 From 3b27e105550f7c4a79ecb6d6a9c49c651c59ae9b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 17 Sep 2010 03:22:19 +0000 Subject: netns: keep vlan slaves on master netns move previously, if a vlan master device was moved from one network namespace to another, all 802.1q and macvlan slaves were deleted. we can use dev->reg_state to figure out whether dev_change_net_namespace is happening, since that won't set dev->reg_state NETREG_UNREGISTERING. so, this changes 8021q and macvlan to ignore NETDEV_UNREGISTER when reg_state is not NETREG_UNREGISTERING. Signed-off-by: David Lamparter Reviewed-by: "Eric W. Biederman" Acked-by: Daniel Lezcano Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 4 ++++ net/8021q/vlan.c | 4 ++++ net/core/dev.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 0ef0eb0db945..0fc9dc7f20db 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -788,6 +788,10 @@ static int macvlan_device_event(struct notifier_block *unused, } break; case NETDEV_UNREGISTER: + /* twiddle thumbs on netns device moves */ + if (dev->reg_state != NETREG_UNREGISTERING) + break; + list_for_each_entry_safe(vlan, next, &port->vlans, list) vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL); break; diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index a2ad15250575..2c6c2bd6e4a9 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -525,6 +525,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, break; case NETDEV_UNREGISTER: + /* twiddle thumbs on netns device moves */ + if (dev->reg_state != NETREG_UNREGISTERING) + break; + /* Delete all VLANs for this dev. */ grp->killall = 1; diff --git a/net/core/dev.c b/net/core/dev.c index c09ff096525a..2c7934f8cf3e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5686,6 +5686,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Notify protocols, that we are about to destroy this device. They should clean all the things. + + Note that dev->reg_state stays at NETREG_REGISTERED. + This is wanted because this way 8021q and macvlan know + the device is just moving and can keep their slaves up. */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); -- cgit v1.2.3 From be2902daee80b655cebd482b5ee91ffc29408121 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 16 Sep 2010 11:28:07 +0000 Subject: ethtool, ixgbe: Move RX n-tuple mask fixup to ethtool The ethtool utility does not set masks for flow parameters that are not specified, so if both value and mask are 0 then this must be treated as equivalent to a mask with all bits set. Currently that is done in the only driver that implements RX n-tuple filtering, ixgbe. Move it to the ethtool core. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 57 ++++++++++------------------------------- include/linux/ethtool.h | 5 ++-- net/core/ethtool.c | 34 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 3e06a61da921..e80657c75506 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1910,56 +1910,27 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); /* - * Program the relevant mask registers. If src/dst_port or src/dst_addr - * are zero, then assume a full mask for that field. Also assume that - * a VLAN of 0 is unspecified, so mask that out as well. L4type - * cannot be masked out in this implementation. + * Program the relevant mask registers. L4type cannot be + * masked out in this implementation. * * This also assumes IPv4 only. IPv6 masking isn't supported at this * point in time. */ - if (src_ipv4 == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); - - if (dst_ipv4 == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); switch (l4type & IXGBE_ATR_L4TYPE_MASK) { case IXGBE_ATR_L4TYPE_TCP: - if (src_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - input_masks->src_port_mask); - - if (dst_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | - (0xffff << 16))); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | - (input_masks->dst_port_mask << 16))); + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, input_masks->src_port_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + (input_masks->dst_port_mask << 16))); break; case IXGBE_ATR_L4TYPE_UDP: - if (src_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - input_masks->src_port_mask); - - if (dst_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | - (0xffff << 16))); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | - (input_masks->src_port_mask << 16))); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, input_masks->src_port_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + (input_masks->src_port_mask << 16))); break; default: /* this already would have failed above */ @@ -1967,11 +1938,11 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, } /* Program the last mask register, FDIRM */ - if (input_masks->vlan_id_mask || !vlan_id) + if (input_masks->vlan_id_mask) /* Mask both VLAN and VLANP - bits 0 and 1 */ fdirm |= 0x3; - if (input_masks->data_mask || !flex_bytes) + if (input_masks->data_mask) /* Flex bytes need masking, so mask the whole thing - bit 4 */ fdirm |= 0x10; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index d64e246a39e7..00334eebbe26 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -470,8 +470,9 @@ struct ethtool_rxfh_indir { * @action: RX ring/queue index to deliver to (non-negative) or other action * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP) * - * Zero values in @h_u may be ignored, as if all the corresponding - * mask bits were set. + * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where + * a field value and mask are both zero this is treated as if all mask + * bits are set i.e. the field is ignored. */ struct ethtool_rx_ntuple_flow_spec { __u32 flow_type; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 248c25c3e820..91ffce20c36b 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -485,6 +485,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, list->count++; } +/* + * ethtool does not (or did not) set masks for flow parameters that are + * not specified, so if both value and mask are 0 then this must be + * treated as equivalent to a mask with all bits set. Implement that + * here rather than in drivers. + */ +static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs) +{ + struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec; + + if (fs->flow_type != TCP_V4_FLOW && + fs->flow_type != UDP_V4_FLOW && + fs->flow_type != SCTP_V4_FLOW) + return; + + if (!(entry->ip4src | mask->ip4src)) + mask->ip4src = htonl(0xffffffff); + if (!(entry->ip4dst | mask->ip4dst)) + mask->ip4dst = htonl(0xffffffff); + if (!(entry->psrc | mask->psrc)) + mask->psrc = htons(0xffff); + if (!(entry->pdst | mask->pdst)) + mask->pdst = htons(0xffff); + if (!(entry->tos | mask->tos)) + mask->tos = 0xff; + if (!(fs->vlan_tag | fs->vlan_tag_mask)) + fs->vlan_tag_mask = 0xffff; + if (!(fs->data | fs->data_mask)) + fs->data_mask = 0xffffffffffffffffULL; +} + static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) { @@ -499,6 +531,8 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, if (copy_from_user(&cmd, useraddr, sizeof(cmd))) return -EFAULT; + rx_ntuple_fix_masks(&cmd.fs); + /* * Cache filter in dev struct for GET operation only if * the underlying driver doesn't have its own GET operation, and -- cgit v1.2.3 From 07af7a2bfa853db3957a22f9a41f437bf0f10e63 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 16 Sep 2010 11:34:26 +0000 Subject: ethtool: Add comments for valid use of flow types Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 00334eebbe26..b67af60a8890 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -841,21 +841,21 @@ struct ethtool_ops { #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ /* L3-L4 network traffic flow types */ -#define TCP_V4_FLOW 0x01 -#define UDP_V4_FLOW 0x02 -#define SCTP_V4_FLOW 0x03 -#define AH_ESP_V4_FLOW 0x04 -#define TCP_V6_FLOW 0x05 -#define UDP_V6_FLOW 0x06 -#define SCTP_V6_FLOW 0x07 -#define AH_ESP_V6_FLOW 0x08 -#define AH_V4_FLOW 0x09 -#define ESP_V4_FLOW 0x0a -#define AH_V6_FLOW 0x0b -#define ESP_V6_FLOW 0x0c -#define IP_USER_FLOW 0x0d -#define IPV4_FLOW 0x10 -#define IPV6_FLOW 0x11 +#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ +#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ +#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ +#define AH_ESP_V4_FLOW 0x04 /* hash only */ +#define TCP_V6_FLOW 0x05 /* hash only */ +#define UDP_V6_FLOW 0x06 /* hash only */ +#define SCTP_V6_FLOW 0x07 /* hash only */ +#define AH_ESP_V6_FLOW 0x08 /* hash only */ +#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */ +#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */ +#define AH_V6_FLOW 0x0b /* hash only */ +#define ESP_V6_FLOW 0x0c /* hash only */ +#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ +#define IPV4_FLOW 0x10 /* hash only */ +#define IPV6_FLOW 0x11 /* hash only */ /* L3-L4 network traffic flow hash options */ #define RXH_L2DA (1 << 1) -- cgit v1.2.3 From e6599c2ecf18002339fe81cde1fa83b37bf26290 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 17 Sep 2010 09:25:07 +0000 Subject: bonding: enable gro by default gro can be enabled by default on bonding devices. Actual support depends on the lower devices. One can still use ethtool to switch off GRO if needed. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3b16f62d5606..fb70c3e12927 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4678,6 +4678,10 @@ static void bond_setup(struct net_device *bond_dev) NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER); + /* By default, we enable GRO on bonding devices. + * Actual support requires lowlevel drivers are GRO ready. + */ + bond_dev->features |= NETIF_F_GRO; } static void bond_work_cancel_all(struct bonding *bond) -- cgit v1.2.3 From 8f8f103d8466e627ecef7894248eb79407d9047c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 19 Sep 2010 11:24:02 -0700 Subject: net: reorder struct netdev_hw_addr Move 'synced' and 'global_use' fields before 'refcount', to shrinks struct netdev_hw_addr by 8 bytes (on 64bit arches). Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ec17887a5bca..f7f1302138af 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -228,9 +228,9 @@ struct netdev_hw_addr { #define NETDEV_HW_ADDR_T_SLAVE 3 #define NETDEV_HW_ADDR_T_UNICAST 4 #define NETDEV_HW_ADDR_T_MULTICAST 5 - int refcount; bool synced; bool global_use; + int refcount; struct rcu_head rcu_head; }; -- cgit v1.2.3 From 0746556beab1a57f1afb5c9d6f393d98528ce682 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 19 Sep 2010 11:25:54 -0700 Subject: bna: off by one The mod->mbhdlr[] array has BFI_MC_MAX elements. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/bna/bfa_ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index caa45c2185e9..73493de98de5 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -1514,7 +1514,7 @@ bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc) return; } - if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) + if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) return; mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); -- cgit v1.2.3 From 9b9d2e00bfa592aceda7b43da76c670df61faa97 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 18 Sep 2010 13:42:25 +0000 Subject: rds: signedness bug In the original code if the copy_from_user() fails in rds_rdma_pages() then the error handling fails and we get a stack trace from kmalloc(). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/rds/rdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 48064673fc76..1a41debca1ce 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -522,7 +522,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, struct rds_rdma_args *args; struct rds_iovec vec; struct rm_rdma_op *op = &rm->rdma; - unsigned int nr_pages; + int nr_pages; unsigned int nr_bytes; struct page **pages = NULL; struct rds_iovec __user *local_vec; -- cgit v1.2.3 From f4fa7f3807d41b78056c6648b04bfadd737df21e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 18 Sep 2010 13:42:59 +0000 Subject: rds: double unlock in rds_ib_cm_handle_connect() We unlock after we goto out. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/rds/ib_cm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index bc3dbc1ba61f..ee369d201a65 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -521,7 +521,6 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, err = rds_ib_setup_qp(conn); if (err) { rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err); - mutex_unlock(&conn->c_cm_lock); goto out; } -- cgit v1.2.3 From aef3ea33e85035f7c827c1db9155f97f4b7ee725 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 18 Sep 2010 13:44:14 +0000 Subject: rds: spin_lock_irq() is not nestable This is basically just a cleanup. IRQs were disabled on the previous line so we don't need to do it again here. In the current code IRQs would get turned on one line earlier than intended. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/rds/ib_rdma.c | 4 ++-- net/rds/iw_rdma.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 8f6e221c9f78..b5a88415a18e 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -171,9 +171,9 @@ void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *con BUG_ON(list_empty(&ic->ib_node)); list_del(&ic->ib_node); - spin_lock_irq(&rds_ibdev->spinlock); + spin_lock(&rds_ibdev->spinlock); list_add_tail(&ic->ib_node, &rds_ibdev->conn_list); - spin_unlock_irq(&rds_ibdev->spinlock); + spin_unlock(&rds_ibdev->spinlock); spin_unlock_irq(&ib_nodev_conns_lock); ic->rds_ibdev = rds_ibdev; diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index 4e152e2daa3d..0e7accc23ee2 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c @@ -206,9 +206,9 @@ void rds_iw_add_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *con BUG_ON(list_empty(&ic->iw_node)); list_del(&ic->iw_node); - spin_lock_irq(&rds_iwdev->spinlock); + spin_lock(&rds_iwdev->spinlock); list_add_tail(&ic->iw_node, &rds_iwdev->conn_list); - spin_unlock_irq(&rds_iwdev->spinlock); + spin_unlock(&rds_iwdev->spinlock); spin_unlock_irq(&iw_nodev_conns_lock); ic->rds_iwdev = rds_iwdev; -- cgit v1.2.3 From 462fb2af9788a82a534f8184abfde31574e1cfa0 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Sun, 19 Sep 2010 09:34:33 +0000 Subject: bridge : Sanitize skb before it enters the IP stack Related dicussion here : http://lkml.org/lkml/2010/9/3/16 Introduce a function br_parse_ip_options that will audit the skb and possibly refill IP options before a packet enters the IP stack. If no options are present, the function will zero out the skb cb area so that it is not misinterpreted as options by some unsuspecting IP layer routine. If packet consistency fails, drop it. Signed-off-by: Bandan Das Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 107 +++++++++++++++++++++++++++++++++------------- net/ipv4/ip_options.c | 3 +- 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 137f23259a93..77f7b5fda45a 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -209,6 +209,72 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb) skb->protocol = htons(ETH_P_PPP_SES); } +/* When handing a packet over to the IP layer + * check whether we have a skb that is in the + * expected format + */ + +int br_parse_ip_options(struct sk_buff *skb) +{ + struct ip_options *opt; + struct iphdr *iph; + struct net_device *dev = skb->dev; + u32 len; + + iph = ip_hdr(skb); + opt = &(IPCB(skb)->opt); + + /* Basic sanity checks */ + if (iph->ihl < 5 || iph->version != 4) + goto inhdr_error; + + if (!pskb_may_pull(skb, iph->ihl*4)) + goto inhdr_error; + + iph = ip_hdr(skb); + if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) + goto inhdr_error; + + len = ntohs(iph->tot_len); + if (skb->len < len) { + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS); + goto drop; + } else if (len < (iph->ihl*4)) + goto inhdr_error; + + if (pskb_trim_rcsum(skb, len)) { + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); + goto drop; + } + + /* Zero out the CB buffer if no options present */ + if (iph->ihl == 5) { + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + return 0; + } + + opt->optlen = iph->ihl*4 - sizeof(struct iphdr); + if (ip_options_compile(dev_net(dev), opt, skb)) + goto inhdr_error; + + /* Check correct handling of SRR option */ + if (unlikely(opt->srr)) { + struct in_device *in_dev = __in_dev_get_rcu(dev); + if (in_dev && !IN_DEV_SOURCE_ROUTE(in_dev)) + goto drop; + + if (ip_options_rcv_srr(skb)) + goto drop; + } + + return 0; + +inhdr_error: + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS); +drop: + return -1; +} + /* Fill in the header for fragmented IP packets handled by * the IPv4 connection tracking code. */ @@ -549,7 +615,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, { struct net_bridge_port *p; struct net_bridge *br; - struct iphdr *iph; __u32 len = nf_bridge_encap_header_len(skb); if (unlikely(!pskb_may_pull(skb, len))) @@ -578,28 +643,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, nf_bridge_pull_encap_header_rcsum(skb); - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - goto inhdr_error; - - iph = ip_hdr(skb); - if (iph->ihl < 5 || iph->version != 4) - goto inhdr_error; - - if (!pskb_may_pull(skb, 4 * iph->ihl)) - goto inhdr_error; - - iph = ip_hdr(skb); - if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0) - goto inhdr_error; - - len = ntohs(iph->tot_len); - if (skb->len < len || len < 4 * iph->ihl) - goto inhdr_error; - - pskb_trim_rcsum(skb, len); - - /* BUG: Should really parse the IP options here. */ - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + if (br_parse_ip_options(skb)) + /* Drop invalid packet */ + goto out; nf_bridge_put(skb->nf_bridge); if (!nf_bridge_alloc(skb)) @@ -614,8 +660,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, return NF_STOLEN; -inhdr_error: -// IP_INC_STATS_BH(IpInHdrErrors); out: return NF_DROP; } @@ -759,14 +803,19 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) static int br_nf_dev_queue_xmit(struct sk_buff *skb) { + int ret; + if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && !skb_is_gso(skb)) { - /* BUG: Should really parse the IP options here. */ - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); - return ip_fragment(skb, br_dev_queue_push_xmit); + if (br_parse_ip_options(skb)) + /* Drop invalid packet */ + return NF_DROP; + ret = ip_fragment(skb, br_dev_queue_push_xmit); } else - return br_dev_queue_push_xmit(skb); + ret = br_dev_queue_push_xmit(skb); + + return ret; } #else static int br_nf_dev_queue_xmit(struct sk_buff *skb) diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index ba9836c488ed..1906fa35860c 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -466,7 +466,7 @@ error: } return -EINVAL; } - +EXPORT_SYMBOL(ip_options_compile); /* * Undo all the changes done by ip_options_compile(). @@ -646,3 +646,4 @@ int ip_options_rcv_srr(struct sk_buff *skb) } return 0; } +EXPORT_SYMBOL(ip_options_rcv_srr); -- cgit v1.2.3 From 8990f468ae9010ab0af4be8f51bf7ab833a67202 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Sep 2010 00:12:11 +0000 Subject: net: rx_dropped accounting Under load, netif_rx() can drop incoming packets but administrators dont have a chance to spot which device needs some tuning (RPS activation for example) This patch adds rx_dropped accounting in vlans and tunnels. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/8021q/vlan.h | 2 ++ net/8021q/vlan_dev.c | 9 +++++++-- net/ipv4/ip_gre.c | 6 ++++-- net/ipv4/ipip.c | 5 ++++- net/ipv6/ip6_tunnel.c | 5 ++++- net/ipv6/ip6mr.c | 4 +++- net/ipv6/sit.c | 5 ++++- 7 files changed, 28 insertions(+), 8 deletions(-) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 8d9503ad01da..b26ce343072c 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -25,6 +25,7 @@ struct vlan_priority_tci_mapping { * @rx_multicast: number of received multicast packets * @syncp: synchronization point for 64bit counters * @rx_errors: number of errors + * @rx_dropped: number of dropped packets */ struct vlan_rx_stats { u64 rx_packets; @@ -32,6 +33,7 @@ struct vlan_rx_stats { u64 rx_multicast; struct u64_stats_sync syncp; unsigned long rx_errors; + unsigned long rx_dropped; }; /** diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 3bccdd12a264..94a1feddeb49 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -225,7 +225,10 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } } - netif_rx(skb); + if (unlikely(netif_rx(skb) == NET_RX_DROP)) { + if (rx_stats) + rx_stats->rx_dropped++; + } rcu_read_unlock(); return NET_RX_SUCCESS; @@ -843,13 +846,15 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st accum.rx_packets += rxpackets; accum.rx_bytes += rxbytes; accum.rx_multicast += rxmulticast; - /* rx_errors is an ulong, not protected by syncp */ + /* rx_errors, rx_dropped are ulong, not protected by syncp */ accum.rx_errors += p->rx_errors; + accum.rx_dropped += p->rx_dropped; } stats->rx_packets = accum.rx_packets; stats->rx_bytes = accum.rx_bytes; stats->rx_errors = accum.rx_errors; stats->multicast = accum.rx_multicast; + stats->rx_dropped = accum.rx_dropped; } return stats; } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fc20e687e933..714b6a80361d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -647,9 +647,11 @@ static int ipgre_rcv(struct sk_buff *skb) skb_reset_network_header(skb); ipgre_ecn_decapsulate(iph, skb); - netif_rx(skb); + if (netif_rx(skb) == NET_RX_DROP) + stats->rx_dropped++; + rcu_read_unlock(); - return(0); + return 0; } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 8de8888dc95a..babd25278106 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -377,7 +377,10 @@ static int ipip_rcv(struct sk_buff *skb) skb_tunnel_rx(skb, tunnel->dev); ipip_ecn_decapsulate(iph, skb); - netif_rx(skb); + + if (netif_rx(skb) == NET_RX_DROP) + tunnel->dev->stats.rx_dropped++; + rcu_read_unlock(); return 0; } diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9289cecac4de..f6d9f683543e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -725,7 +725,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, skb_tunnel_rx(skb, t->dev); dscp_ecn_decapsulate(t, ipv6h, skb); - netif_rx(skb); + + if (netif_rx(skb) == NET_RX_DROP) + t->dev->stats.rx_dropped++; + rcu_read_unlock(); return 0; } diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 66078dad7fe8..2640c9be589d 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -666,7 +666,9 @@ static int pim6_rcv(struct sk_buff *skb) skb_tunnel_rx(skb, reg_dev); - netif_rx(skb); + if (netif_rx(skb) == NET_RX_DROP) + reg_dev->stats.rx_dropped++; + dev_put(reg_dev); return 0; drop: diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 6822481ff766..8a0399822230 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -564,7 +564,10 @@ static int ipip6_rcv(struct sk_buff *skb) skb_tunnel_rx(skb, tunnel->dev); ipip6_ecn_decapsulate(iph, skb); - netif_rx(skb); + + if (netif_rx(skb) == NET_RX_DROP) + tunnel->dev->stats.rx_dropped++; + rcu_read_unlock(); return 0; } -- cgit v1.2.3 From daebbca3ab41031666ee27f991b223d2bc0415e9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Sep 2010 02:28:59 +0000 Subject: qlcnic: dont set skb->truesize skb->truesize is set in core network. Dont change it unless dealing with fragments. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_init.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index e26fa9593311..16dd9ebd36c9 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1418,8 +1418,6 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, if (pkt_offset) skb_pull(skb, pkt_offset); - skb->truesize = skb->len + sizeof(struct sk_buff); - if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { adapter->stats.rxdropped++; dev_kfree_skb(skb); @@ -1491,8 +1489,6 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, skb_put(skb, lro_length + data_offset); - skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); - skb_pull(skb, l2_hdr_offset); if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { @@ -1732,8 +1728,6 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, if (pkt_offset) skb_pull(skb, pkt_offset); - skb->truesize = skb->len + sizeof(struct sk_buff); - if (!qlcnic_check_loopback_buff(skb->data)) adapter->diag_cnt++; -- cgit v1.2.3 From 4874c131d79695e3d372042781a408a1a8a762d8 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Sep 2010 20:06:50 +0200 Subject: dccp: Add packet type information to CCID-specific option parsing This 1. adds packet type information to ccid_hc_{rx,tx}_parse_options(). This is necessary, since table 3 in RFC 4340, 5.8 leaves it to the CCIDs to state which options may (not) appear on what packet type. 2. adds such a check for CCID-3's {Loss Event, Receive} Rate as specified in RFC 4340 8.3 ("Receive Rate options MUST NOT be sent on DCCP-Data packets") and 8.5 ("Loss Event Rate options MUST NOT be sent on DCCP-Data packets"). 3. removes an unused argument `idx' from ccid_hc_{rx,tx}_parse_options(). This is also no longer necessary, since the CCID-specific option-parsing routines are passed every single parameter of the type-length-value option encoding. Signed-off-by: Gerrit Renker --- net/dccp/ccid.h | 46 +++++++++++++++++++++++----------------------- net/dccp/ccids/ccid3.c | 14 ++++++++------ net/dccp/options.c | 16 ++++------------ 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 6df6f8ac9636..6d16a9070ff0 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h @@ -62,18 +62,14 @@ struct ccid_operations { void (*ccid_hc_tx_exit)(struct sock *sk); void (*ccid_hc_rx_packet_recv)(struct sock *sk, struct sk_buff *skb); - int (*ccid_hc_rx_parse_options)(struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value); + int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt, + u8 opt, u8 *val, u8 len); int (*ccid_hc_rx_insert_options)(struct sock *sk, struct sk_buff *skb); void (*ccid_hc_tx_packet_recv)(struct sock *sk, struct sk_buff *skb); - int (*ccid_hc_tx_parse_options)(struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value); + int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt, + u8 opt, u8 *val, u8 len); int (*ccid_hc_tx_send_packet)(struct sock *sk, struct sk_buff *skb); void (*ccid_hc_tx_packet_sent)(struct sock *sk, @@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk, ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); } +/** + * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver + * @pkt: type of packet that @opt appears on (RFC 4340, 5.1) + * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3) + * @val: value of @opt + * @len: length of @val in bytes + */ static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value) + u8 pkt, u8 opt, u8 *val, u8 len) { - int rc = 0; - if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL) - rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx, - value); - return rc; + if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL) + return 0; + return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len); } +/** + * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender + * Arguments are analogous to ccid_hc_tx_parse_options() + */ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value) + u8 pkt, u8 opt, u8 *val, u8 len) { - int rc = 0; - if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL) - rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value); - return rc; + if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL) + return 0; + return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len); } static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index ce8059130070..be1b8baaf298 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -481,9 +481,8 @@ done_computing_x: jiffies + usecs_to_jiffies(t_nfb)); } -static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, - unsigned char len, u16 idx, - unsigned char *value) +static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, + u8 option, u8 *optval, u8 optlen) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); struct ccid3_options_received *opt_recv = &hc->tx_options_received; @@ -492,12 +491,15 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, switch (option) { case TFRC_OPT_RECEIVE_RATE: case TFRC_OPT_LOSS_EVENT_RATE: - if (unlikely(len != 4)) { + /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */ + if (packet_type == DCCP_PKT_DATA) + break; + if (unlikely(optlen != 4)) { DCCP_WARN("%s(%p), invalid len %d for %u\n", - dccp_role(sk), sk, len, option); + dccp_role(sk), sk, optlen, option); return -EINVAL; } - opt_val = ntohl(get_unaligned((__be32 *)value)); + opt_val = ntohl(get_unaligned((__be32 *)optval)); if (option == TFRC_OPT_RECEIVE_RATE) { opt_recv->ccid3or_receive_rate = opt_val; diff --git a/net/dccp/options.c b/net/dccp/options.c index bfda087bd90d..e4983e3d2616 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -226,23 +226,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", dccp_role(sk), elapsed_time); break; - case 128 ... 191: { - const u16 idx = value - options; - + case 128 ... 191: if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, - opt, len, idx, - value) != 0) + pkt_type, opt, value, len)) goto out_invalid_option; - } break; - case 192 ... 255: { - const u16 idx = value - options; - + case 192 ... 255: if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, - opt, len, idx, - value) != 0) + pkt_type, opt, value, len)) goto out_invalid_option; - } break; default: DCCP_CRIT("DCCP(%p): option %d(len=%d) not " -- cgit v1.2.3 From a18213d1d2a469956845b437f5d1d0401ab22e8b Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Sep 2010 20:08:00 +0200 Subject: dccp: Replace magic CCID-specific numbers by symbolic constants The constants DCCPO_{MIN,MAX}_CCID_SPECIFIC are nowhere used in the code, but instead for the CCID-specific options numbers are used. This patch unifies the use of CCID-specific option numbers, by adding symbolic names reflecting the definitions in RFC 4340, 10.3. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 6 ++++-- net/dccp/options.c | 13 +++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 7434a8353e23..7187bd8a75f6 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -165,8 +165,10 @@ enum { DCCPO_TIMESTAMP_ECHO = 42, DCCPO_ELAPSED_TIME = 43, DCCPO_MAX = 45, - DCCPO_MIN_CCID_SPECIFIC = 128, - DCCPO_MAX_CCID_SPECIFIC = 255, + DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */ + DCCPO_MAX_RX_CCID_SPECIFIC = 191, + DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */ + DCCPO_MAX_TX_CCID_SPECIFIC = 255, }; /* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ #define DCCP_SINGLE_OPT_MAXLEN 253 diff --git a/net/dccp/options.c b/net/dccp/options.c index e4983e3d2616..92718511eac5 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, } /* - * CCID-Specific Options (from RFC 4340, sec. 10.3): - * - * Option numbers 128 through 191 are for options sent from the - * HC-Sender to the HC-Receiver; option numbers 192 through 255 - * are for options sent from the HC-Receiver to the HC-Sender. - * * CCID-specific options are ignored during connection setup, as * negotiation may still be in progress (see RFC 4340, 10.3). * The same applies to Ack Vectors, as these depend on the CCID. - * */ - if (dreq != NULL && (opt >= 128 || + if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC || opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1)) goto ignore_option; @@ -226,12 +219,12 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", dccp_role(sk), elapsed_time); break; - case 128 ... 191: + case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC: if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, pkt_type, opt, value, len)) goto out_invalid_option; break; - case 192 ... 255: + case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC: if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, pkt_type, opt, value, len)) goto out_invalid_option; -- cgit v1.2.3 From 80763dfbac4ed1e6dfe6ec08ef748e0e9aec3260 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Sep 2010 20:08:24 +0200 Subject: dccp ccid-3: remove dead states This patch is thanks to an investigation by Leandro Sales de Melo and his colleagues. They worked out two state diagrams which highlight the fact that the xxx_TERM states in CCID-3/4 are in fact not necessary. And this can be confirmed by in turn looking at the code: the xxx_TERM states are only ever set in ccid3_hc_{rx,tx}_exit(): when CCID-3 sets the state to xxx_TERM, it is at a time where no more processing should be going on, hence it is not necessary to introduce a dedicated exit state - this is already implied by unloading the CCID. Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 37 +++++++++---------------------------- net/dccp/ccids/ccid3.h | 2 -- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index be1b8baaf298..90bc0a7da8e4 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) [TFRC_SSTATE_NO_SENT] = "NO_SENT", [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", [TFRC_SSTATE_FBACK] = "FBACK", - [TFRC_SSTATE_TERM] = "TERM", }; return ccid3_state_names[state]; @@ -208,10 +207,13 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk, ccid3_tx_state_name(hc->tx_state)); + /* Ignore and do not restart after leaving the established state */ + if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN)) + goto out; + + /* Reset feedback state to "no feedback received" */ if (hc->tx_state == TFRC_SSTATE_FBACK) ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); - else if (hc->tx_state != TFRC_SSTATE_NO_FBACK) - goto out; /* * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 @@ -287,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) if (unlikely(skb->len == 0)) return -EBADMSG; - switch (hc->tx_state) { - case TFRC_SSTATE_NO_SENT: + if (hc->tx_state == TFRC_SSTATE_NO_SENT) { sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); hc->tx_last_win_count = 0; @@ -323,9 +324,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) ccid3_update_send_interval(hc); ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); - break; - case TFRC_SSTATE_NO_FBACK: - case TFRC_SSTATE_FBACK: + + } else { delay = ktime_us_delta(hc->tx_t_nom, now); ccid3_pr_debug("delay=%ld\n", (long)delay); /* @@ -340,10 +340,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) return (u32)delay / USEC_PER_MSEC; ccid3_hc_tx_update_win_count(hc, now); - break; - case TFRC_SSTATE_TERM: - DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk); - return -EINVAL; } /* prepare to send now (add options etc.) */ @@ -379,11 +375,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) return; - /* ... and only in the established state */ - if (hc->tx_state != TFRC_SSTATE_FBACK && - hc->tx_state != TFRC_SSTATE_NO_FBACK) - return; - /* * Locate the acknowledged packet in the TX history. * @@ -529,9 +520,7 @@ static void ccid3_hc_tx_exit(struct sock *sk) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); sk_stop_timer(sk, &hc->tx_no_feedback_timer); - tfrc_tx_hist_purge(&hc->tx_hist); } @@ -590,7 +579,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) static const char *const ccid3_rx_state_names[] = { [TFRC_RSTATE_NO_DATA] = "NO_DATA", [TFRC_RSTATE_DATA] = "DATA", - [TFRC_RSTATE_TERM] = "TERM", }; return ccid3_rx_state_names[state]; @@ -616,14 +604,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, { struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); struct dccp_sock *dp = dccp_sk(sk); - ktime_t now; + ktime_t now = ktime_get_real(); s64 delta = 0; - if (unlikely(hc->rx_state == TFRC_RSTATE_TERM)) - return; - - now = ktime_get_real(); - switch (fbtype) { case CCID3_FBACK_INITIAL: hc->rx_x_recv = 0; @@ -827,8 +810,6 @@ static void ccid3_hc_rx_exit(struct sock *sk) { struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); - ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); - tfrc_rx_hist_purge(&hc->rx_hist); tfrc_lh_cleanup(&hc->rx_li_hist); } diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 9eb90b863abd..89b047b0c79b 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -77,7 +77,6 @@ enum ccid3_hc_tx_states { TFRC_SSTATE_NO_SENT = 1, TFRC_SSTATE_NO_FBACK, TFRC_SSTATE_FBACK, - TFRC_SSTATE_TERM, }; /** @@ -130,7 +129,6 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) enum ccid3_hc_rx_states { TFRC_RSTATE_NO_DATA = 1, TFRC_RSTATE_DATA, - TFRC_RSTATE_TERM = 127, }; /** -- cgit v1.2.3 From 792e6d3389061ad449429b9ba228eb758c247ea0 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Sep 2010 20:10:52 +0200 Subject: dccp tfrc/ccid-3: computing the loss rate from the Loss Event Rate This adds a function to take care of the following, separate cases occurring in the computation of the Loss Rate p: * 1/(2^32-1) is mapped into 0% as per RFC 4342, 8.5; * 1/0 is mapped into 100%, the maximum; * to avoid that p = 1/x is rounded down to 0 when x is very large, since this means accidentally re-entering slow-start indicated by p == 0, the minimum resolution value of p is now returned instead; * a bug in ccid3_hc_rx_getsockopt is fixed: 1/0 was mapped into ~0U. Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 9 ++++----- net/dccp/ccids/lib/tfrc.h | 1 + net/dccp/ccids/lib/tfrc_equation.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 90bc0a7da8e4..9715eebf1551 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -400,10 +400,10 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) /* Update loss event rate (which is scaled by 1e6) */ pinv = opt_recv->ccid3or_loss_event_rate; - if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ + if (pinv == 0) hc->tx_p = 0; - else /* can not exceed 100% */ - hc->tx_p = scaled_div(1, pinv); + else + hc->tx_p = tfrc_invert_loss_event_rate(pinv); /* * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 @@ -834,8 +834,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, return -EINVAL; rx_info.tfrcrx_x_recv = hc->rx_x_recv; rx_info.tfrcrx_rtt = hc->rx_rtt; - rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U : - scaled_div(1, hc->rx_pinv); + rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hc->rx_pinv); len = sizeof(rx_info); val = &rx_info; break; diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h index 01bb48e96c2e..f8ee3f549770 100644 --- a/net/dccp/ccids/lib/tfrc.h +++ b/net/dccp/ccids/lib/tfrc.h @@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight) extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); +extern u32 tfrc_invert_loss_event_rate(u32 loss_event_rate); extern int tfrc_tx_packet_history_init(void); extern void tfrc_tx_packet_history_exit(void); diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c index 22ca1cf0eb55..a052a4377e26 100644 --- a/net/dccp/ccids/lib/tfrc_equation.c +++ b/net/dccp/ccids/lib/tfrc_equation.c @@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue) index = tfrc_binsearch(fvalue, 0); return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE; } + +/** + * tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100% + * When @loss_event_rate is large, there is a chance that p is truncated to 0. + * To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0. + */ +u32 tfrc_invert_loss_event_rate(u32 loss_event_rate) +{ + if (loss_event_rate == UINT_MAX) /* see RFC 4342, 8.5 */ + return 0; + if (unlikely(loss_event_rate == 0)) /* map 1/0 into 100% */ + return 1000000; + return max_t(u32, scaled_div(1, loss_event_rate), TFRC_SMALLEST_P); +} -- cgit v1.2.3 From 536bb20b45dee3f9b77b0d250f8ed0733a5cb025 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Sep 2010 20:14:23 +0200 Subject: dccp ccid-3: Remove redundant 'options_received' struct The `options_received' struct is redundant, since it re-duplicates the existing `p' and `x_recv' fields. This patch removes the sub-struct and migrates the format conversion operations to ccid3_hc_tx_parse_options(). Signed-off-by: Gerrit Renker --- net/dccp/ccids/ccid3.c | 24 ++++++++---------------- net/dccp/ccids/ccid3.h | 7 ------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 9715eebf1551..c3f3a25bbd7a 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -365,11 +365,10 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv = &hc->tx_options_received; struct tfrc_tx_hist_entry *acked; ktime_t now; unsigned long t_nfb; - u32 pinv, r_sample; + u32 r_sample; /* we are only interested in ACKs */ if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || @@ -394,17 +393,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp)); hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9); - /* Update receive rate in units of 64 * bytes/second */ - hc->tx_x_recv = opt_recv->ccid3or_receive_rate; - hc->tx_x_recv <<= 6; - - /* Update loss event rate (which is scaled by 1e6) */ - pinv = opt_recv->ccid3or_loss_event_rate; - if (pinv == 0) - hc->tx_p = 0; - else - hc->tx_p = tfrc_invert_loss_event_rate(pinv); - /* * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 */ @@ -476,7 +464,6 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, u8 option, u8 *optval, u8 optlen) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv = &hc->tx_options_received; __be32 opt_val; switch (option) { @@ -493,11 +480,16 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, opt_val = ntohl(get_unaligned((__be32 *)optval)); if (option == TFRC_OPT_RECEIVE_RATE) { - opt_recv->ccid3or_receive_rate = opt_val; + /* Receive Rate is kept in units of 64 bytes/second */ + hc->tx_x_recv = opt_val; + hc->tx_x_recv <<= 6; + ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", dccp_role(sk), sk, opt_val); } else { - opt_recv->ccid3or_loss_event_rate = opt_val; + /* Update the fixpoint Loss Event Rate fraction */ + hc->tx_p = tfrc_invert_loss_event_rate(opt_val); + ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", dccp_role(sk), sk, opt_val); } diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 89b047b0c79b..1a9933c29672 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -67,11 +67,6 @@ enum ccid3_options { TFRC_OPT_RECEIVE_RATE = 194, }; -struct ccid3_options_received { - u32 ccid3or_loss_event_rate; - u32 ccid3or_receive_rate; -}; - /* TFRC sender states */ enum ccid3_hc_tx_states { TFRC_SSTATE_NO_SENT = 1, @@ -97,7 +92,6 @@ enum ccid3_hc_tx_states { * @tx_t_ld: Time last doubled during slow start * @tx_t_nom: Nominal send time of next packet * @tx_hist: Packet history - * @tx_options_received: Parsed set of retrieved options */ struct ccid3_hc_tx_sock { u64 tx_x; @@ -115,7 +109,6 @@ struct ccid3_hc_tx_sock { ktime_t tx_t_ld; ktime_t tx_t_nom; struct tfrc_tx_hist_entry *tx_hist; - struct ccid3_options_received tx_options_received; }; static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) -- cgit v1.2.3 From c1f9a095600e07fefe64eb94eb711f410100824a Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 13:16:02 +0200 Subject: wl12xx: make wl12xx.h common to both spi and sdio Move wl12xx.h outside of the spi-specific location, so it can be shared with both spi and sdio solutions. Update all users of spi/wl12xx.h accordingly Signed-off-by: Ohad Ben-Cohen Acked-by: Luciano Coelho Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- arch/arm/mach-omap2/board-omap3pandora.c | 1 + arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- drivers/net/wireless/wl12xx/wl1251_sdio.c | 2 +- drivers/net/wireless/wl12xx/wl1251_spi.c | 2 +- drivers/net/wireless/wl12xx/wl1271_spi.c | 2 +- include/linux/spi/wl12xx.h | 34 ---------------------------- include/linux/wl12xx.h | 34 ++++++++++++++++++++++++++++ 8 files changed, 40 insertions(+), 39 deletions(-) delete mode 100644 include/linux/spi/wl12xx.h create mode 100644 include/linux/wl12xx.h diff --git a/MAINTAINERS b/MAINTAINERS index 80cea03a737e..e9aec08e575a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6324,7 +6324,7 @@ W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained F: drivers/net/wireless/wl12xx/wl1271* -F: include/linux/spi/wl12xx.h +F: include/linux/wl12xx.h WL3501 WIRELESS PCMCIA CARD DRIVER M: Arnaldo Carvalho de Melo diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index c0f4f12eba54..9b62b6283c6e 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 03483920ed6e..1cf994299cbe 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index c0b68b0a9aa8..74ba9ced5393 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "wl1251.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 334ded9881c0..320de79667a6 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "wl1251.h" #include "wl1251_reg.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 4cb99c541e2a..c3fdab75ad2a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "wl1271.h" diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h deleted file mode 100644 index a20bccf0b5c2..000000000000 --- a/include/linux/spi/wl12xx.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef _LINUX_SPI_WL12XX_H -#define _LINUX_SPI_WL12XX_H - -struct wl12xx_platform_data { - void (*set_power)(bool enable); - /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ - int irq; - bool use_eeprom; -}; - -#endif diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h new file mode 100644 index 000000000000..015687a1776d --- /dev/null +++ b/include/linux/wl12xx.h @@ -0,0 +1,34 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Luciano Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef _LINUX_WL12XX_H +#define _LINUX_WL12XX_H + +struct wl12xx_platform_data { + void (*set_power)(bool enable); + /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ + int irq; + bool use_eeprom; +}; + +#endif -- cgit v1.2.3 From 2cc78ff78c0af502b040d4527212e29e02d3231d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:22:04 +0200 Subject: wl1271: propagate set_power's return value Make it possible for the set power method to indicate a success/failure return value. This is needed to support more complex power on/off operations such as SDIO power manipulations. Signed-off-by: Ohad Ben-Cohen Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271.h | 2 +- drivers/net/wireless/wl12xx/wl1271_io.h | 9 ++++++--- drivers/net/wireless/wl12xx/wl1271_main.c | 4 +++- drivers/net/wireless/wl12xx/wl1271_sdio.c | 15 +++++++++------ drivers/net/wireless/wl12xx/wl1271_spi.c | 4 +++- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index dd3cee6ea5bb..faa5925efe30 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -313,7 +313,7 @@ struct wl1271_if_operations { bool fixed); void (*reset)(struct wl1271 *wl); void (*init)(struct wl1271 *wl); - void (*power)(struct wl1271 *wl, bool enable); + int (*power)(struct wl1271 *wl, bool enable); struct device* (*dev)(struct wl1271 *wl); void (*enable_irq)(struct wl1271 *wl); void (*disable_irq)(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h index bc806c74c63a..c1f92e65ded0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ b/drivers/net/wireless/wl12xx/wl1271_io.h @@ -144,10 +144,13 @@ static inline void wl1271_power_off(struct wl1271 *wl) clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); } -static inline void wl1271_power_on(struct wl1271 *wl) +static inline int wl1271_power_on(struct wl1271 *wl) { - wl->if_ops->power(wl, true); - set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + int ret = wl->if_ops->power(wl, true); + if (ret == 0) + set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + + return ret; } diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 8e55cf8d509d..af26150109e3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -621,7 +621,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) int ret = 0; msleep(WL1271_PRE_POWER_ON_SLEEP); - wl1271_power_on(wl); + ret = wl1271_power_on(wl); + if (ret < 0) + goto out; msleep(WL1271_POWER_ON_SLEEP); wl1271_io_reset(wl); wl1271_io_init(wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index b5d9565f659f..1d5dc727167d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -159,35 +159,38 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, wl1271_error("sdio write failed (%d)", ret); } -static void wl1271_sdio_power_on(struct wl1271 *wl) +static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); + + return 0; } -static void wl1271_sdio_power_off(struct wl1271 *wl) +static int wl1271_sdio_power_off(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); + + return 0; } -static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) { /* Let the SDIO stack handle wlan_enable control, so we * keep host claimed while wlan is in use to keep wl1271 * alive. */ if (enable) - wl1271_sdio_power_on(wl); + return wl1271_sdio_power_on(wl); else - wl1271_sdio_power_off(wl); - + return wl1271_sdio_power_off(wl); } static struct wl1271_if_operations sdio_ops = { diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index c3fdab75ad2a..de56d8d9ee66 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -312,10 +312,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) return IRQ_HANDLED; } -static void wl1271_spi_set_power(struct wl1271 *wl, bool enable) +static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) { if (wl->set_power) wl->set_power(enable); + + return 0; } static struct wl1271_if_operations spi_ops = { -- cgit v1.2.3 From 61ee7007a5d61aa066076da578e8e8084e122d7d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:31:12 +0200 Subject: wl12xx: add platform data passing support Add a simple mechanism to pass platform data to the SDIO instances of wl12xx. This way there is no confusion over who owns the 'embedded data', typechecking is preserved, and no possibility for the wrong driver to pick up the data. Originally proposed by Russell King. Signed-off-by: Ohad Ben-Cohen Signed-off-by: John W. Linville --- drivers/net/wireless/Makefile | 2 ++ drivers/net/wireless/wl12xx/Kconfig | 5 +++- drivers/net/wireless/wl12xx/wl12xx_platform_data.c | 28 ++++++++++++++++++++++ include/linux/wl12xx.h | 3 +++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/wl12xx/wl12xx_platform_data.c diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 5d4ce4d2b32b..85af697574a6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -50,5 +50,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o obj-$(CONFIG_WL12XX) += wl12xx/ +# small builtin driver bit +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/wl12xx_platform_data.o obj-$(CONFIG_IWM) += iwmc3200wifi/ diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 2f98058be451..4a8bb25c1739 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -74,4 +74,7 @@ config WL1271_SDIO If you choose to build a module, it'll be called wl1271_sdio. Say N if unsure. - +config WL12XX_PLATFORM_DATA + bool + depends on WL1271_SDIO != n + default y diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c new file mode 100644 index 000000000000..973b11060a8f --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c @@ -0,0 +1,28 @@ +#include +#include +#include + +static const struct wl12xx_platform_data *platform_data; + +int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + if (platform_data) + return -EBUSY; + if (!data) + return -EINVAL; + + platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!platform_data) + return -ENOMEM; + + return 0; +} + +const struct wl12xx_platform_data *wl12xx_get_platform_data(void) +{ + if (!platform_data) + return ERR_PTR(-ENODEV); + + return platform_data; +} +EXPORT_SYMBOL(wl12xx_get_platform_data); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 015687a1776d..bd70563107fa 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -31,4 +31,7 @@ struct wl12xx_platform_data { bool use_eeprom; }; +int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); +const struct wl12xx_platform_data *wl12xx_get_platform_data(void); + #endif -- cgit v1.2.3 From 09cecc340b3b4d9960b039c0f576548bbf857f5a Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:31:35 +0200 Subject: wl1271: take irq info from private board data Remove the hard coded irq information, and instead take the irq information from the board's platform data. Signed-off-by: Ohad Ben-Cohen Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 1d5dc727167d..987ecdc9406d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -29,14 +29,12 @@ #include #include #include +#include #include "wl1271.h" #include "wl12xx_80211.h" #include "wl1271_io.h" - -#define RX71_WL1271_IRQ_GPIO 42 - #ifndef SDIO_VENDOR_ID_TI #define SDIO_VENDOR_ID_TI 0x0097 #endif @@ -208,6 +206,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct ieee80211_hw *hw; + const struct wl12xx_platform_data *wlan_data; struct wl1271 *wl; int ret; @@ -227,13 +226,15 @@ static int __devinit wl1271_probe(struct sdio_func *func, /* Grab access to FN0 for ELP reg. */ func->card->quirks |= MMC_QUIRK_LENIENT_FN0; - wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO); - if (wl->irq < 0) { - ret = wl->irq; - wl1271_error("could not get irq!"); + wlan_data = wl12xx_get_platform_data(); + if (IS_ERR(wlan_data)) { + ret = PTR_ERR(wlan_data); + wl1271_error("missing wlan platform data: %d", ret); goto out_free; } + wl->irq = wlan_data->irq; + ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); -- cgit v1.2.3 From 15cea99306ae14ce5f7c3d3989bcc17202e2b0be Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:31:51 +0200 Subject: wl1271: make ref_clock configurable by board The wl1271 device is using a reference clock that may change between board to board. Make the ref_clock parameter configurable by board settings instead of having a hard coded value in the sources. Signed-off-by: Ohad Ben-Cohen Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_boot.c | 11 +++++++---- drivers/net/wireless/wl12xx/wl1271_boot.h | 1 - drivers/net/wireless/wl12xx/wl1271_sdio.c | 1 + drivers/net/wireless/wl12xx/wl1271_spi.c | 2 ++ include/linux/wl12xx.h | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index faa5925efe30..4134f4495b95 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -330,6 +330,7 @@ struct wl1271 { void (*set_power)(bool enable); int irq; + int ref_clock; spinlock_t wl_lock; diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index f36430b0336d..fc21db810812 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -457,17 +457,20 @@ int wl1271_boot(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; + int ref_clock = wl->ref_clock; wl1271_boot_hw_version(wl); - if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4) + if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; - else if (REF_CLOCK == 1 || REF_CLOCK == 3) + else if (ref_clock == 1 || ref_clock == 3) /* ref clk: 26/52 */ clk = 0x5; + else + return -EINVAL; - if (REF_CLOCK != 0) { + if (ref_clock != 0) { u16 val; /* Set clock type (open drain) */ val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); @@ -516,7 +519,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); /* 2 */ - clk |= (REF_CLOCK << 1) << 4; + clk |= (ref_clock << 1) << 4; wl1271_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, &part_table[PART_WORK]); diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h index f829699d597e..f73b0b15a280 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.h +++ b/drivers/net/wireless/wl12xx/wl1271_boot.h @@ -46,7 +46,6 @@ struct wl1271_static_data { /* delay between retries */ #define INIT_LOOP_DELAY 50 -#define REF_CLOCK 2 #define WU_COUNTER_PAUSE_VAL 0x3FF #define WELP_ARM_COMMAND_VAL 0x4 diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 987ecdc9406d..f2f04663627c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -234,6 +234,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, } wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index de56d8d9ee66..ced0a9e2c7e1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -372,6 +372,8 @@ static int __devinit wl1271_probe(struct spi_device *spi) goto out_free; } + wl->ref_clock = pdata->board_ref_clock; + wl->irq = spi->irq; if (wl->irq < 0) { wl1271_error("irq missing in platform data"); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index bd70563107fa..95deae3968f4 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -29,6 +29,7 @@ struct wl12xx_platform_data { /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; + int board_ref_clock; }; int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); -- cgit v1.2.3 From b642fde7f137566c993991fd2e7bf6b8274bf625 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:32:09 +0200 Subject: omap: zoom: add fixed regulator device for wlan Add a fixed regulator vmmc device to enable power control of the wl1271 wlan device. Signed-off-by: Ohad Ben-Cohen Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- arch/arm/mach-omap2/board-zoom-peripherals.c | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 6b3984964cc5..f5df9a2b1465 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,8 @@ #include "mux.h" #include "hsmmc.h" +#define OMAP_ZOOM_WLAN_PMENA_GPIO (101) + /* Zoom2 has Qwerty keyboard*/ static int board_keymap[] = { KEY(0, 0, KEY_E), @@ -106,6 +109,11 @@ static struct regulator_consumer_supply zoom_vmmc2_supply = { .supply = "vmmc", }; +static struct regulator_consumer_supply zoom_vmmc3_supply = { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.2", +}; + /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ static struct regulator_init_data zoom_vmmc1 = { .constraints = { @@ -151,6 +159,32 @@ static struct regulator_init_data zoom_vsim = { .consumer_supplies = &zoom_vsim_supply, }; +static struct regulator_init_data zoom_vmmc3 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &zoom_vmmc3_supply, +}; + +static struct fixed_voltage_config zoom_vwlan = { + .supply_name = "vwl1271", + .microvolts = 1800000, /* 1.8V */ + .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO, + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &zoom_vmmc3, +}; + +static struct platform_device omap_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &zoom_vwlan, + }, +}; + static struct omap2_hsmmc_info mmc[] __initdata = { { .name = "external", @@ -280,6 +314,7 @@ static void enable_board_wakeup_source(void) void __init zoom_peripherals_init(void) { omap_i2c_init(); + platform_device_register(&omap_vwlan_device); usb_musb_init(&musb_board_data); enable_board_wakeup_source(); } -- cgit v1.2.3 From 80b517f362605f2b6a6cfe086604534290aab2de Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 16 Sep 2010 01:32:30 +0200 Subject: omap: zoom: add mmc3/wl1271 device support Add MMC3 support on ZOOM, which has the wl1271 device hardwired to. The wl1271 is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ line, and power-controlled by a GPIO-based fixed regulator. Signed-off-by: Ohad Ben-Cohen Acked-by: Tony Lindgren Signed-off-by: John W. Linville --- arch/arm/mach-omap2/board-zoom-peripherals.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index f5df9a2b1465..6aa0728fa15d 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include "hsmmc.h" #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) +#define OMAP_ZOOM_WLAN_IRQ_GPIO (162) /* Zoom2 has Qwerty keyboard*/ static int board_keymap[] = { @@ -185,6 +187,12 @@ static struct platform_device omap_vwlan_device = { }, }; +struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { + .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO), + /* ZOOM ref clock is 26 MHz */ + .board_ref_clock = 1, +}; + static struct omap2_hsmmc_info mmc[] __initdata = { { .name = "external", @@ -202,6 +210,14 @@ static struct omap2_hsmmc_info mmc[] __initdata = { .nonremovable = true, .power_saving = true, }, + { + .name = "wl1271", + .mmc = 3, + .wires = 4, + .gpio_wp = -EINVAL, + .gpio_cd = -EINVAL, + .nonremovable = true, + }, {} /* Terminator */ }; @@ -313,6 +329,9 @@ static void enable_board_wakeup_source(void) void __init zoom_peripherals_init(void) { + if (wl12xx_set_platform_data(&omap_zoom_wlan_data)) + pr_err("error setting wl12xx data\n"); + omap_i2c_init(); platform_device_register(&omap_vwlan_device); usb_musb_init(&musb_board_data); -- cgit v1.2.3 From c807666a08800ab387298817db5a6f6e11606adb Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 16 Sep 2010 22:55:20 +0200 Subject: carl9170: update AR9170 phy initvals This patch is loosely based on an ath9k patch called: "ath9k_hw: sync initvals for ar9001 and ar9002 with Atheros" It includes the following changes/fixes: - AGC setting improvements - timing changes for improved performance Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 47709c13d964..71dea9707e21 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -85,11 +85,12 @@ static struct carl9170_phy_init ar5416_phy_init[] = { { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, - { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, }, + { 0x1c5850, 0x6c48b4e4, 0x6d48b4e4, 0x6d48b0e4, 0x6c48b0e4, }, { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, - { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, }, + { 0x1c585c, 0x31395c5e, 0x3139605e, 0x3139605e, 0x31395c5e, }, { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, + { 0x1c5864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, @@ -131,9 +132,10 @@ static struct carl9170_phy_init ar5416_phy_init[] = { { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, + { 0x1c59bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, - { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, }, + { 0x1c59c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, }, { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, -- cgit v1.2.3 From ce2220d1da0bad9583af38a03ad508968d554c0f Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:25 +0900 Subject: ath/ath5k/ath9k: Fix crypto capabilities merge issue Fixing up a merge issue / concurrent development: Remove unneeded ath_crypt_caps flags, as per "ath9k_hw: remove useless hw capability flags" (364734fafbba0c3133e482db78149b9a823ae7a5), but set the AESCCM flag for ath9k. common ath code still needs a flag for this because there is ath5k hardware which can't do AES in hardware. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 9 ++------- drivers/net/wireless/ath/ath5k/attach.c | 3 +-- drivers/net/wireless/ath/ath9k/hw.c | 2 ++ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c5584077d1de..dd236c3b52f6 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -72,13 +72,8 @@ struct ath_regulatory { }; enum ath_crypt_caps { - ATH_CRYPT_CAP_MIC_AESCCM = BIT(0), - ATH_CRYPT_CAP_MIC_CKIP = BIT(1), - ATH_CRYPT_CAP_MIC_TKIP = BIT(2), - ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(3), - ATH_CRYPT_CAP_CIPHER_CKIP = BIT(4), - ATH_CRYPT_CAP_CIPHER_TKIP = BIT(5), - ATH_CRYPT_CAP_MIC_COMBINED = BIT(6), + ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(0), + ATH_CRYPT_CAP_MIC_COMBINED = BIT(1), }; struct ath_keyval { diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index a0e08201c939..20d178eabc9c 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -320,8 +320,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) if (srev >= AR5K_SREV_AR5212_V4 && (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) - common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM | - ATH_CRYPT_CAP_MIC_AESCCM; + common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; if (srev >= AR5K_SREV_AR2414) { common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f3c9d7549571..0b2ff98b6f33 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1866,6 +1866,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->low_5ghz_chan = 4920; pCap->high_5ghz_chan = 6100; + common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; + if (ah->config.ht_enable) pCap->hw_caps |= ATH9K_HW_CAP_HT; else -- cgit v1.2.3 From 8a63facc376a7b8bb2b64c0ffbdb0949d1d6c71c Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 17 Sep 2010 12:45:07 +0900 Subject: ath5k: reorder base.c to remove fwd decls This change reorganizes the main ath5k file in order to re-group related functions and remove most of the forward declarations (from 61 down to 3). This is, unfortunately, a lot of churn, but there should be no functional changes. Signed-off-by: Bob Copeland Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4024 ++++++++++++++++----------------- 1 file changed, 1945 insertions(+), 2079 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0709bb091b2f..4a07fb89021e 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -70,11 +70,6 @@ static int modparam_all_channels; module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); - -/******************\ -* Internal defines * -\******************/ - /* Module info */ MODULE_AUTHOR("Jiri Slaby"); MODULE_AUTHOR("Nick Kossifidis"); @@ -83,6 +78,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); +static int ath5k_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known PCI ids */ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { @@ -190,129 +189,6 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; -/* - * Prototypes - PCI stack related functions - */ -static int __devinit ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); -static void __devexit ath5k_pci_remove(struct pci_dev *pdev); -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev); -static int ath5k_pci_resume(struct device *dev); - -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); -#define ATH5K_PM_OPS (&ath5k_pm_ops) -#else -#define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ - -static struct pci_driver ath5k_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ath5k_pci_id_table, - .probe = ath5k_pci_probe, - .remove = __devexit_p(ath5k_pci_remove), - .driver.pm = ATH5K_PM_OPS, -}; - - - -/* - * Prototypes - MAC 802.11 stack related functions - */ -static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq); -static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); -static int ath5k_start(struct ieee80211_hw *hw); -static void ath5k_stop(struct ieee80211_hw *hw); -static int ath5k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static int ath5k_config(struct ieee80211_hw *hw, u32 changed); -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list); -static void ath5k_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast); -static int ath5k_set_key(struct ieee80211_hw *hw, - enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); -static int ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -static int ath5k_get_survey(struct ieee80211_hw *hw, - int idx, struct survey_info *survey); -static u64 ath5k_get_tsf(struct ieee80211_hw *hw); -static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); -static void ath5k_reset_tsf(struct ieee80211_hw *hw); -static int ath5k_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void ath5k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes); -static void ath5k_sw_scan_start(struct ieee80211_hw *hw); -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); -static void ath5k_set_coverage_class(struct ieee80211_hw *hw, - u8 coverage_class); - -static const struct ieee80211_ops ath5k_hw_ops = { - .tx = ath5k_tx, - .start = ath5k_start, - .stop = ath5k_stop, - .add_interface = ath5k_add_interface, - .remove_interface = ath5k_remove_interface, - .config = ath5k_config, - .prepare_multicast = ath5k_prepare_multicast, - .configure_filter = ath5k_configure_filter, - .set_key = ath5k_set_key, - .get_stats = ath5k_get_stats, - .get_survey = ath5k_get_survey, - .conf_tx = NULL, - .get_tsf = ath5k_get_tsf, - .set_tsf = ath5k_set_tsf, - .reset_tsf = ath5k_reset_tsf, - .bss_info_changed = ath5k_bss_info_changed, - .sw_scan_start = ath5k_sw_scan_start, - .sw_scan_complete = ath5k_sw_scan_complete, - .set_coverage_class = ath5k_set_coverage_class, -}; - -/* - * Prototypes - Internal functions - */ -/* Attach detach */ -static int ath5k_attach(struct pci_dev *pdev, - struct ieee80211_hw *hw); -static void ath5k_detach(struct pci_dev *pdev, - struct ieee80211_hw *hw); -/* Channel/mode setup */ -static inline short ath5k_ieee2mhz(short chan); -static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, - struct ieee80211_channel *channels, - unsigned int mode, - unsigned int max); -static int ath5k_setup_bands(struct ieee80211_hw *hw); -static int ath5k_chan_set(struct ath5k_softc *sc, - struct ieee80211_channel *chan); -static void ath5k_setcurmode(struct ath5k_softc *sc, - unsigned int mode); -static void ath5k_mode_setup(struct ath5k_softc *sc); - -/* Descriptor setup */ -static int ath5k_desc_alloc(struct ath5k_softc *sc, - struct pci_dev *pdev); -static void ath5k_desc_free(struct ath5k_softc *sc, - struct pci_dev *pdev); -/* Buffers setup */ -static int ath5k_rxbuf_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf); -static int ath5k_txbuf_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf, - struct ath5k_txq *txq, int padsize); - static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { @@ -345,35 +221,6 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, } -/* Queues setup */ -static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc, - int qtype, int subtype); -static int ath5k_beaconq_setup(struct ath5k_hw *ah); -static int ath5k_beaconq_config(struct ath5k_softc *sc); -static void ath5k_txq_drainq(struct ath5k_softc *sc, - struct ath5k_txq *txq); -static void ath5k_txq_cleanup(struct ath5k_softc *sc); -static void ath5k_txq_release(struct ath5k_softc *sc); -/* Rx handling */ -static int ath5k_rx_start(struct ath5k_softc *sc); -static void ath5k_rx_stop(struct ath5k_softc *sc); -static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, - struct sk_buff *skb, - struct ath5k_rx_status *rs); -static void ath5k_tasklet_rx(unsigned long data); -/* Tx handling */ -static void ath5k_tx_processq(struct ath5k_softc *sc, - struct ath5k_txq *txq); -static void ath5k_tasklet_tx(unsigned long data); -/* Beacon handling */ -static int ath5k_beacon_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf); -static void ath5k_beacon_send(struct ath5k_softc *sc); -static void ath5k_beacon_config(struct ath5k_softc *sc); -static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); -static void ath5k_tasklet_beacon(unsigned long data); -static void ath5k_tasklet_ani(unsigned long data); - static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) { u64 tsf = ath5k_hw_get_tsf64(ah); @@ -384,50 +231,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) return (tsf & ~0x7fff) | rstamp; } -/* Interrupt handling */ -static int ath5k_init(struct ath5k_softc *sc); -static int ath5k_stop_locked(struct ath5k_softc *sc); -static int ath5k_stop_hw(struct ath5k_softc *sc); -static irqreturn_t ath5k_intr(int irq, void *dev_id); -static void ath5k_reset_work(struct work_struct *work); - -static void ath5k_tasklet_calibrate(unsigned long data); - -/* - * Module init/exit functions - */ -static int __init -init_ath5k_pci(void) -{ - int ret; - - ath5k_debug_init(); - - ret = pci_register_driver(&ath5k_pci_driver); - if (ret) { - printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); - return ret; - } - - return 0; -} - -static void __exit -exit_ath5k_pci(void) -{ - pci_unregister_driver(&ath5k_pci_driver); - - ath5k_debug_finish(); -} - -module_init(init_ath5k_pci); -module_exit(exit_ath5k_pci); - - -/********************\ -* PCI Initialization * -\********************/ - static const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) { @@ -466,1695 +269,1286 @@ static const struct ath_ops ath5k_common_ops = { .write = ath5k_iowrite32, }; -static int __devinit -ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +/***********************\ +* Driver Initialization * +\***********************/ + +static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { - void __iomem *mem; - struct ath5k_softc *sc; - struct ath_common *common; - struct ieee80211_hw *hw; - int ret; - u8 csz; + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath5k_softc *sc = hw->priv; + struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah); - /* - * L0s needs to be disabled on all ath5k cards. - * - * For distributions shipping with CONFIG_PCIEASPM (this will be enabled - * by default in the future in 2.6.36) this will also mean both L1 and - * L0s will be disabled when a pre 1.1 PCIe device is detected. We do - * know L1 works correctly even for all ath5k pre 1.1 PCIe devices - * though but cannot currently undue the effect of a blacklist, for - * details you can read pcie_aspm_sanity_check() and see how it adjusts - * the device link capability. - * - * It may be possible in the future to implement some PCI API to allow - * drivers to override blacklists for pre 1.1 PCIe but for now it is - * best to accept that both L0s and L1 will be disabled completely for - * distributions shipping with CONFIG_PCIEASPM rather than having this - * issue present. Motivation for adding this new API will be to help - * with power consumption for some of these devices. - */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + return ath_reg_notifier_apply(wiphy, request, regulatory); +} - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "can't enable device\n"); - goto err; - } +/********************\ +* Channel/mode setup * +\********************/ - /* XXX 32-bit addressing only */ - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "32-bit DMA not available\n"); - goto err_dis; - } +/* + * Convert IEEE channel number to MHz frequency. + */ +static inline short +ath5k_ieee2mhz(short chan) +{ + if (chan <= 14 || chan >= 27) + return ieee80211chan2mhz(chan); + else + return 2212 + chan * 20; +} - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); - if (csz == 0) { - /* - * Linux 2.4.18 (at least) writes the cache line size - * register as a 16-bit wide register which is wrong. - * We must have this setup properly for rx buffer - * DMA to work so force a reasonable value here if it - * comes up zero. - */ - csz = L1_CACHE_BYTES >> 2; - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); - } - /* - * The default setting of latency timer yields poor results, - * set it to the value used by other systems. It may be worth - * tweaking this setting more. - */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); +/* + * Returns true for the channel numbers used without all_channels modparam. + */ +static bool ath5k_is_standard_channel(short chan) +{ + return ((chan <= 14) || + /* UNII 1,2 */ + ((chan & 3) == 0 && chan >= 36 && chan <= 64) || + /* midband */ + ((chan & 3) == 0 && chan >= 100 && chan <= 140) || + /* UNII-3 */ + ((chan & 3) == 1 && chan >= 149 && chan <= 165)); +} - /* Enable bus mastering */ - pci_set_master(pdev); +static unsigned int +ath5k_copy_channels(struct ath5k_hw *ah, + struct ieee80211_channel *channels, + unsigned int mode, + unsigned int max) +{ + unsigned int i, count, size, chfreq, freq, ch; - /* - * Disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, 0x41, 0); + if (!test_bit(mode, ah->ah_modes)) + return 0; - ret = pci_request_region(pdev, 0, "ath5k"); - if (ret) { - dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); - goto err_dis; + switch (mode) { + case AR5K_MODE_11A: + case AR5K_MODE_11A_TURBO: + /* 1..220, but 2GHz frequencies are filtered by check_channel */ + size = 220 ; + chfreq = CHANNEL_5GHZ; + break; + case AR5K_MODE_11B: + case AR5K_MODE_11G: + case AR5K_MODE_11G_TURBO: + size = 26; + chfreq = CHANNEL_2GHZ; + break; + default: + ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); + return 0; } - mem = pci_iomap(pdev, 0, 0); - if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; - ret = -EIO; - goto err_reg; - } + for (i = 0, count = 0; i < size && max > 0; i++) { + ch = i + 1 ; + freq = ath5k_ieee2mhz(ch); - /* - * Allocate hw (mac80211 main struct) - * and hw->priv (driver private data) - */ - hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); - ret = -ENOMEM; - goto err_map; - } - - dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - - /* Initialize driver private data */ - SET_IEEE80211_DEV(hw, &pdev->dev); - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; + /* Check if channel is supported by the chipset */ + if (!ath5k_channel_ok(ah, freq, chfreq)) + continue; - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT); + if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) + continue; - hw->extra_tx_headroom = 2; - hw->channel_change_time = 5000; - sc = hw->priv; - sc->hw = hw; - sc->pdev = pdev; + /* Write channel info and increment counter */ + channels[count].center_freq = freq; + channels[count].band = (chfreq == CHANNEL_2GHZ) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + switch (mode) { + case AR5K_MODE_11A: + case AR5K_MODE_11G: + channels[count].hw_value = chfreq | CHANNEL_OFDM; + break; + case AR5K_MODE_11A_TURBO: + case AR5K_MODE_11G_TURBO: + channels[count].hw_value = chfreq | + CHANNEL_OFDM | CHANNEL_TURBO; + break; + case AR5K_MODE_11B: + channels[count].hw_value = CHANNEL_B; + } - ath5k_debug_init_device(sc); + count++; + max--; + } - /* - * Mark the device as detached to avoid processing - * interrupts until setup is complete. - */ - __set_bit(ATH_STAT_INVALID, sc->status); + return count; +} - sc->iobase = mem; /* So we can unmap it on detach */ - sc->opmode = NL80211_IFTYPE_STATION; - sc->bintval = 1000; - mutex_init(&sc->lock); - spin_lock_init(&sc->rxbuflock); - spin_lock_init(&sc->txbuflock); - spin_lock_init(&sc->block); +static void +ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) +{ + u8 i; - /* Set private data */ - pci_set_drvdata(pdev, sc); + for (i = 0; i < AR5K_MAX_RATES; i++) + sc->rate_idx[b->band][i] = -1; - /* Setup interrupt handler */ - ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); - if (ret) { - ATH5K_ERR(sc, "request_irq failed\n"); - goto err_free; + for (i = 0; i < b->n_bitrates; i++) { + sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; + if (b->bitrates[i].hw_value_short) + sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; } +} - /* If we passed the test, malloc an ath5k_hw struct */ - sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); - if (!sc->ah) { - ret = -ENOMEM; - ATH5K_ERR(sc, "out of memory\n"); - goto err_irq; - } +static int +ath5k_setup_bands(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ieee80211_supported_band *sband; + int max_c, count_c = 0; + int i; - sc->ah->ah_sc = sc; - sc->ah->ah_iobase = sc->iobase; - common = ath5k_hw_common(sc->ah); - common->ops = &ath5k_common_ops; - common->ah = sc->ah; - common->hw = hw; - common->cachelsz = csz << 2; /* convert to bytes */ + BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); + max_c = ARRAY_SIZE(sc->channels); - /* Initialize device */ - ret = ath5k_hw_attach(sc); - if (ret) { - goto err_free_ah; - } + /* 2GHz band */ + sband = &sc->sbands[IEEE80211_BAND_2GHZ]; + sband->band = IEEE80211_BAND_2GHZ; + sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; - /* set up multi-rate retry capabilities */ - if (sc->ah->ah_version == AR5K_AR5212) { - hw->max_rates = 4; - hw->max_rate_tries = 11; - } + if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { + /* G mode */ + memcpy(sband->bitrates, &ath5k_rates[0], + sizeof(struct ieee80211_rate) * 12); + sband->n_bitrates = 12; - /* Finish private driver data initialization */ - ret = ath5k_attach(pdev, hw); - if (ret) - goto err_ah; + sband->channels = sc->channels; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11G, max_c); - ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", - ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), - sc->ah->ah_mac_srev, - sc->ah->ah_phy_revision); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + count_c = sband->n_channels; + max_c -= count_c; + } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { + /* B mode */ + memcpy(sband->bitrates, &ath5k_rates[0], + sizeof(struct ieee80211_rate) * 4); + sband->n_bitrates = 4; - if (!sc->ah->ah_single_chip) { - /* Single chip radio (!RF5111) */ - if (sc->ah->ah_radio_5ghz_revision && - !sc->ah->ah_radio_2ghz_revision) { - /* No 5GHz support -> report 2GHz radio */ - if (!test_bit(AR5K_MODE_11A, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* No 2GHz support (5110 and some - * 5Ghz only cards) -> report 5Ghz radio */ - } else if (!test_bit(AR5K_MODE_11B, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* Multiband radio */ - } else { - ATH5K_INFO(sc, "RF%s multiband radio found" - " (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); + /* 5211 only supports B rates and uses 4bit rate codes + * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) + * fix them up here: + */ + if (ah->ah_version == AR5K_AR5211) { + for (i = 0; i < 4; i++) { + sband->bitrates[i].hw_value = + sband->bitrates[i].hw_value & 0xF; + sband->bitrates[i].hw_value_short = + sband->bitrates[i].hw_value_short & 0xF; } } - /* Multi chip radio (RF5111 - RF2111) -> - * report both 2GHz/5GHz radios */ - else if (sc->ah->ah_radio_5ghz_revision && - sc->ah->ah_radio_2ghz_revision){ - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_2ghz_revision), - sc->ah->ah_radio_2ghz_revision); - } - } + sband->channels = sc->channels; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11B, max_c); - /* ready to process interrupts */ - __clear_bit(ATH_STAT_INVALID, sc->status); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + count_c = sband->n_channels; + max_c -= count_c; + } + ath5k_setup_rate_idx(sc, sband); - return 0; -err_ah: - ath5k_hw_detach(sc->ah); -err_free_ah: - kfree(sc->ah); -err_irq: - free_irq(pdev->irq, sc); -err_free: - ieee80211_free_hw(hw); -err_map: - pci_iounmap(pdev, mem); -err_reg: - pci_release_region(pdev, 0); -err_dis: - pci_disable_device(pdev); -err: - return ret; -} + /* 5GHz band, A mode */ + if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { + sband = &sc->sbands[IEEE80211_BAND_5GHZ]; + sband->band = IEEE80211_BAND_5GHZ; + sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; -static void __devexit -ath5k_pci_remove(struct pci_dev *pdev) -{ - struct ath5k_softc *sc = pci_get_drvdata(pdev); + memcpy(sband->bitrates, &ath5k_rates[4], + sizeof(struct ieee80211_rate) * 8); + sband->n_bitrates = 8; - ath5k_debug_finish_device(sc); - ath5k_detach(pdev, sc->hw); - ath5k_hw_detach(sc->ah); - kfree(sc->ah); - free_irq(pdev->irq, sc); - pci_iounmap(pdev, sc->iobase); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - ieee80211_free_hw(sc->hw); -} + sband->channels = &sc->channels[count_c]; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11A, max_c); -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev) -{ - struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; + } + ath5k_setup_rate_idx(sc, sband); + + ath5k_debug_dump_bands(sc); - ath5k_led_off(sc); return 0; } -static int ath5k_pci_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ath5k_softc *sc = pci_get_drvdata(pdev); - +/* + * Set/change channels. We always reset the chip. + * To accomplish this we must first cleanup any pending DMA, + * then restart stuff after a la ath5k_init. + * + * Called with sc->lock. + */ +static int +ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) +{ + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "channel set, resetting (%u -> %u MHz)\n", + sc->curchan->center_freq, chan->center_freq); + /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state + * To switch channels clear any pending DMA operations; + * wait long enough for the RX fifo to drain, reset the + * hardware at the new frequency, and then re-enable + * the relevant bits of the h/w. */ - pci_write_config_byte(pdev, 0x41, 0); - - ath5k_led_enable(sc); - return 0; + return ath5k_reset(sc, chan); } -#endif /* CONFIG_PM_SLEEP */ - - -/***********************\ -* Driver Initialization * -\***********************/ -static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +static void +ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath5k_softc *sc = hw->priv; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah); + sc->curmode = mode; - return ath_reg_notifier_apply(wiphy, request, regulatory); + if (mode == AR5K_MODE_11A) { + sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; + } else { + sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; + } } -static int -ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) +static void +ath5k_mode_setup(struct ath5k_softc *sc) { - struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); - u8 mac[ETH_ALEN] = {}; - int ret; + u32 rfilt; - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); + /* configure rx filter */ + rfilt = sc->filter_flags; + ath5k_hw_set_rx_filter(ah, rfilt); - /* - * Check if the MAC has multi-rate retry support. - * We do this by trying to setup a fake extended - * descriptor. MACs that don't have support will - * return false w/o doing anything. MACs that do - * support it will return true w/o doing anything. - */ - ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + if (ath5k_hw_hasbssidmask(ah)) + ath5k_hw_set_bssid_mask(ah, sc->bssidmask); - if (ret < 0) - goto err; - if (ret > 0) - __set_bit(ATH_STAT_MRRETRY, sc->status); + /* configure operational mode */ + ath5k_hw_set_opmode(ah, sc->opmode); - /* - * Collect the channel list. The 802.11 layer - * is resposible for filtering this list based - * on settings like the phy mode and regulatory - * domain restrictions. - */ - ret = ath5k_setup_bands(hw); - if (ret) { - ATH5K_ERR(sc, "can't get channels\n"); - goto err; - } + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); +} - /* NB: setup here so ath5k_rate_update is happy */ - if (test_bit(AR5K_MODE_11A, ah->ah_modes)) - ath5k_setcurmode(sc, AR5K_MODE_11A); - else - ath5k_setcurmode(sc, AR5K_MODE_11B); +static inline int +ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) +{ + int rix; - /* - * Allocate tx+rx descriptors and populate the lists. - */ - ret = ath5k_desc_alloc(sc, pdev); - if (ret) { - ATH5K_ERR(sc, "can't allocate descriptors\n"); - goto err; - } + /* return base rate on errors */ + if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, + "hw_rix out of bounds: %x\n", hw_rix)) + return 0; + + rix = sc->rate_idx[sc->curband->band][hw_rix]; + if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) + rix = 0; + + return rix; +} + +/***************\ +* Buffers setup * +\***************/ + +static +struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) +{ + struct ath_common *common = ath5k_hw_common(sc->ah); + struct sk_buff *skb; /* - * Allocate hardware transmit queues: one queue for - * beacon frames and one data queue for each QoS - * priority. Note that hw functions handle resetting - * these queues at the needed time. + * Allocate buffer with headroom_needed space for the + * fake physical layer header at the start. */ - ret = ath5k_beaconq_setup(ah); - if (ret < 0) { - ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); - goto err_desc; - } - sc->bhalq = ret; - sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); - if (IS_ERR(sc->cabq)) { - ATH5K_ERR(sc, "can't setup cab queue\n"); - ret = PTR_ERR(sc->cabq); - goto err_bhal; - } + skb = ath_rxbuf_alloc(common, + common->rx_bufsize, + GFP_ATOMIC); - sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); - if (IS_ERR(sc->txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(sc->txq); - goto err_queues; + if (!skb) { + ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", + common->rx_bufsize); + return NULL; } - tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); - tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); - tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); - tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); - tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); - - INIT_WORK(&sc->reset_work, ath5k_reset_work); - - ret = ath5k_eeprom_read_mac(ah, mac); - if (ret) { - ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", - sc->pdev->device); - goto err_queues; + *skb_addr = pci_map_single(sc->pdev, + skb->data, common->rx_bufsize, + PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { + ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); + dev_kfree_skb(skb); + return NULL; } + return skb; +} - SET_IEEE80211_PERM_ADDR(hw, mac); - /* All MAC address bits matter for ACKs */ - memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); +static int +ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) +{ + struct ath5k_hw *ah = sc->ah; + struct sk_buff *skb = bf->skb; + struct ath5k_desc *ds; + int ret; - regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; - ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); - if (ret) { - ATH5K_ERR(sc, "can't initialize regulatory system\n"); - goto err_queues; + if (!skb) { + skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr); + if (!skb) + return -ENOMEM; + bf->skb = skb; } - ret = ieee80211_register_hw(hw); + /* + * Setup descriptors. For receive we always terminate + * the descriptor list with a self-linked entry so we'll + * not get overrun under high load (as can happen with a + * 5212 when ANI processing enables PHY error frames). + * + * To ensure the last descriptor is self-linked we create + * each descriptor as self-linked and add it to the end. As + * each additional descriptor is added the previous self-linked + * entry is "fixed" naturally. This should be safe even + * if DMA is happening. When processing RX interrupts we + * never remove/process the last, self-linked, entry on the + * descriptor list. This ensures the hardware always has + * someplace to write a new frame. + */ + ds = bf->desc; + ds->ds_link = bf->daddr; /* link to self */ + ds->ds_data = bf->skbaddr; + ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); if (ret) { - ATH5K_ERR(sc, "can't register ieee80211 hw\n"); - goto err_queues; + ATH5K_ERR(sc, "%s: could not setup RX desc\n", __func__); + return ret; } - if (!ath_is_world_regd(regulatory)) - regulatory_hint(hw->wiphy, regulatory->alpha2); - - ath5k_init_leds(sc); - - ath5k_sysfs_register(sc); - + if (sc->rxlink != NULL) + *sc->rxlink = bf->daddr; + sc->rxlink = &ds->ds_link; return 0; -err_queues: - ath5k_txq_release(sc); -err_bhal: - ath5k_hw_release_tx_queue(ah, sc->bhalq); -err_desc: - ath5k_desc_free(sc, pdev); -err: - return ret; } -static void -ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) +static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) { - struct ath5k_softc *sc = hw->priv; + struct ieee80211_hdr *hdr; + enum ath5k_pkt_type htype; + __le16 fc; - /* - * NB: the order of these is important: - * o call the 802.11 layer before detaching ath5k_hw to - * ensure callbacks into the driver to delete global - * key cache entries can be handled - * o reclaim the tx queue data structures after calling - * the 802.11 layer as we'll get called back to reclaim - * node state and potentially want to use them - * o to cleanup the tx queues the hal is called, so detach - * it last - * XXX: ??? detach ath5k_hw ??? - * Other than that, it's straightforward... - */ - ieee80211_unregister_hw(hw); - ath5k_desc_free(sc, pdev); - ath5k_txq_release(sc); - ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); - ath5k_unregister_leds(sc); - - ath5k_sysfs_unregister(sc); - /* - * NB: can't reclaim these until after ieee80211_ifdetach - * returns because we'll get called back to reclaim node - * state and potentially want to use them. - */ -} - - - - -/********************\ -* Channel/mode setup * -\********************/ + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; -/* - * Convert IEEE channel number to MHz frequency. - */ -static inline short -ath5k_ieee2mhz(short chan) -{ - if (chan <= 14 || chan >= 27) - return ieee80211chan2mhz(chan); + if (ieee80211_is_beacon(fc)) + htype = AR5K_PKT_TYPE_BEACON; + else if (ieee80211_is_probe_resp(fc)) + htype = AR5K_PKT_TYPE_PROBE_RESP; + else if (ieee80211_is_atim(fc)) + htype = AR5K_PKT_TYPE_ATIM; + else if (ieee80211_is_pspoll(fc)) + htype = AR5K_PKT_TYPE_PSPOLL; else - return 2212 + chan * 20; -} + htype = AR5K_PKT_TYPE_NORMAL; -/* - * Returns true for the channel numbers used without all_channels modparam. - */ -static bool ath5k_is_standard_channel(short chan) -{ - return ((chan <= 14) || - /* UNII 1,2 */ - ((chan & 3) == 0 && chan >= 36 && chan <= 64) || - /* midband */ - ((chan & 3) == 0 && chan >= 100 && chan <= 140) || - /* UNII-3 */ - ((chan & 3) == 1 && chan >= 149 && chan <= 165)); + return htype; } -static unsigned int -ath5k_copy_channels(struct ath5k_hw *ah, - struct ieee80211_channel *channels, - unsigned int mode, - unsigned int max) +static int +ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, + struct ath5k_txq *txq, int padsize) { - unsigned int i, count, size, chfreq, freq, ch; + struct ath5k_hw *ah = sc->ah; + struct ath5k_desc *ds = bf->desc; + struct sk_buff *skb = bf->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; + struct ieee80211_rate *rate; + unsigned int mrr_rate[3], mrr_tries[3]; + int i, ret; + u16 hw_rate; + u16 cts_rate = 0; + u16 duration = 0; + u8 rc_flags; - if (!test_bit(mode, ah->ah_modes)) - return 0; + flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; - switch (mode) { - case AR5K_MODE_11A: - case AR5K_MODE_11A_TURBO: - /* 1..220, but 2GHz frequencies are filtered by check_channel */ - size = 220 ; - chfreq = CHANNEL_5GHZ; - break; - case AR5K_MODE_11B: - case AR5K_MODE_11G: - case AR5K_MODE_11G_TURBO: - size = 26; - chfreq = CHANNEL_2GHZ; - break; - default: - ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); - return 0; - } + /* XXX endianness */ + bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); - for (i = 0, count = 0; i < size && max > 0; i++) { - ch = i + 1 ; - freq = ath5k_ieee2mhz(ch); + rate = ieee80211_get_tx_rate(sc->hw, info); - /* Check if channel is supported by the chipset */ - if (!ath5k_channel_ok(ah, freq, chfreq)) - continue; + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + flags |= AR5K_TXDESC_NOACK; - if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) - continue; + rc_flags = info->control.rates[0].flags; + hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? + rate->hw_value_short : rate->hw_value; - /* Write channel info and increment counter */ - channels[count].center_freq = freq; - channels[count].band = (chfreq == CHANNEL_2GHZ) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - switch (mode) { - case AR5K_MODE_11A: - case AR5K_MODE_11G: - channels[count].hw_value = chfreq | CHANNEL_OFDM; - break; - case AR5K_MODE_11A_TURBO: - case AR5K_MODE_11G_TURBO: - channels[count].hw_value = chfreq | - CHANNEL_OFDM | CHANNEL_TURBO; + pktlen = skb->len; + + /* FIXME: If we are in g mode and rate is a CCK rate + * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta + * from tx power (value is in dB units already) */ + if (info->control.hw_key) { + keyidx = info->control.hw_key->hw_key_idx; + pktlen += info->control.hw_key->icv_len; + } + if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { + flags |= AR5K_TXDESC_RTSENA; + cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; + duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, + sc->vif, pktlen, info)); + } + if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + flags |= AR5K_TXDESC_CTSENA; + cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; + duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, + sc->vif, pktlen, info)); + } + ret = ah->ah_setup_tx_desc(ah, ds, pktlen, + ieee80211_get_hdrlen_from_skb(skb), padsize, + get_hw_packet_type(skb), + (sc->power_level * 2), + hw_rate, + info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, + cts_rate, duration); + if (ret) + goto err_unmap; + + memset(mrr_rate, 0, sizeof(mrr_rate)); + memset(mrr_tries, 0, sizeof(mrr_tries)); + for (i = 0; i < 3; i++) { + rate = ieee80211_get_alt_retry_rate(sc->hw, info, i); + if (!rate) break; - case AR5K_MODE_11B: - channels[count].hw_value = CHANNEL_B; - } - count++; - max--; + mrr_rate[i] = rate->hw_value; + mrr_tries[i] = info->control.rates[i + 1].count; } - return count; -} + ath5k_hw_setup_mrr_tx_desc(ah, ds, + mrr_rate[0], mrr_tries[0], + mrr_rate[1], mrr_tries[1], + mrr_rate[2], mrr_tries[2]); -static void -ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) -{ - u8 i; + ds->ds_link = 0; + ds->ds_data = bf->skbaddr; - for (i = 0; i < AR5K_MAX_RATES; i++) - sc->rate_idx[b->band][i] = -1; + spin_lock_bh(&txq->lock); + list_add_tail(&bf->list, &txq->q); + if (txq->link == NULL) /* is this first packet? */ + ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); + else /* no, so only link it */ + *txq->link = bf->daddr; - for (i = 0; i < b->n_bitrates; i++) { - sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; - if (b->bitrates[i].hw_value_short) - sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; - } + txq->link = &ds->ds_link; + ath5k_hw_start_tx_dma(ah, txq->qnum); + mmiowb(); + spin_unlock_bh(&txq->lock); + + return 0; +err_unmap: + pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); + return ret; } +/*******************\ +* Descriptors setup * +\*******************/ + static int -ath5k_setup_bands(struct ieee80211_hw *hw) +ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) { - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ieee80211_supported_band *sband; - int max_c, count_c = 0; - int i; - - BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); - max_c = ARRAY_SIZE(sc->channels); + struct ath5k_desc *ds; + struct ath5k_buf *bf; + dma_addr_t da; + unsigned int i; + int ret; - /* 2GHz band */ - sband = &sc->sbands[IEEE80211_BAND_2GHZ]; - sband->band = IEEE80211_BAND_2GHZ; - sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; + /* allocate descriptors */ + sc->desc_len = sizeof(struct ath5k_desc) * + (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); + sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); + if (sc->desc == NULL) { + ATH5K_ERR(sc, "can't allocate descriptors\n"); + ret = -ENOMEM; + goto err; + } + ds = sc->desc; + da = sc->desc_daddr; + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n", + ds, sc->desc_len, (unsigned long long)sc->desc_daddr); - if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { - /* G mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 12); - sband->n_bitrates = 12; + bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF, + sizeof(struct ath5k_buf), GFP_KERNEL); + if (bf == NULL) { + ATH5K_ERR(sc, "can't allocate bufptr\n"); + ret = -ENOMEM; + goto err_free; + } + sc->bufptr = bf; - sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11G, max_c); - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; - } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { - /* B mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 4); - sband->n_bitrates = 4; - - /* 5211 only supports B rates and uses 4bit rate codes - * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) - * fix them up here: - */ - if (ah->ah_version == AR5K_AR5211) { - for (i = 0; i < 4; i++) { - sband->bitrates[i].hw_value = - sband->bitrates[i].hw_value & 0xF; - sband->bitrates[i].hw_value_short = - sband->bitrates[i].hw_value_short & 0xF; - } - } - - sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11B, max_c); + INIT_LIST_HEAD(&sc->rxbuf); + for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->rxbuf); + } - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; + INIT_LIST_HEAD(&sc->txbuf); + sc->txbuf_len = ATH_TXBUF; + for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, + da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->txbuf); } - ath5k_setup_rate_idx(sc, sband); - /* 5GHz band, A mode */ - if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { - sband = &sc->sbands[IEEE80211_BAND_5GHZ]; - sband->band = IEEE80211_BAND_5GHZ; - sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; + /* beacon buffer */ + bf->desc = ds; + bf->daddr = da; + sc->bbuf = bf; - memcpy(sband->bitrates, &ath5k_rates[4], - sizeof(struct ieee80211_rate) * 8); - sband->n_bitrates = 8; + return 0; +err_free: + pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); +err: + sc->desc = NULL; + return ret; +} - sband->channels = &sc->channels[count_c]; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11A, max_c); +static void +ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) +{ + struct ath5k_buf *bf; - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; - } - ath5k_setup_rate_idx(sc, sband); + ath5k_txbuf_free_skb(sc, sc->bbuf); + list_for_each_entry(bf, &sc->txbuf, list) + ath5k_txbuf_free_skb(sc, bf); + list_for_each_entry(bf, &sc->rxbuf, list) + ath5k_rxbuf_free_skb(sc, bf); - ath5k_debug_dump_bands(sc); + /* Free memory associated with all descriptors */ + pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); + sc->desc = NULL; + sc->desc_daddr = 0; - return 0; + kfree(sc->bufptr); + sc->bufptr = NULL; + sc->bbuf = NULL; } -/* - * Set/change channels. We always reset the chip. - * To accomplish this we must first cleanup any pending DMA, - * then restart stuff after a la ath5k_init. - * - * Called with sc->lock. - */ -static int -ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) + +/**************\ +* Queues setup * +\**************/ + +static struct ath5k_txq * +ath5k_txq_setup(struct ath5k_softc *sc, + int qtype, int subtype) { - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, - "channel set, resetting (%u -> %u MHz)\n", - sc->curchan->center_freq, chan->center_freq); + struct ath5k_hw *ah = sc->ah; + struct ath5k_txq *txq; + struct ath5k_txq_info qi = { + .tqi_subtype = subtype, + .tqi_aifs = AR5K_TXQ_USEDEFAULT, + .tqi_cw_min = AR5K_TXQ_USEDEFAULT, + .tqi_cw_max = AR5K_TXQ_USEDEFAULT + }; + int qnum; /* - * To switch channels clear any pending DMA operations; - * wait long enough for the RX fifo to drain, reset the - * hardware at the new frequency, and then re-enable - * the relevant bits of the h/w. + * Enable interrupts only for EOL and DESC conditions. + * We mark tx descriptors to receive a DESC interrupt + * when a tx queue gets deep; otherwise we wait for the + * EOL to reap descriptors. Note that this is done to + * reduce interrupt load and this only defers reaping + * descriptors, never transmitting frames. Aside from + * reducing interrupts this also permits more concurrency. + * The only potential downside is if the tx queue backs + * up in which case the top half of the kernel may backup + * due to a lack of tx descriptors. */ - return ath5k_reset(sc, chan); + qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE | + AR5K_TXQ_FLAG_TXDESCINT_ENABLE; + qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi); + if (qnum < 0) { + /* + * NB: don't print a message, this happens + * normally on parts with too few tx queues + */ + return ERR_PTR(qnum); + } + if (qnum >= ARRAY_SIZE(sc->txqs)) { + ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n", + qnum, ARRAY_SIZE(sc->txqs)); + ath5k_hw_release_tx_queue(ah, qnum); + return ERR_PTR(-EINVAL); + } + txq = &sc->txqs[qnum]; + if (!txq->setup) { + txq->qnum = qnum; + txq->link = NULL; + INIT_LIST_HEAD(&txq->q); + spin_lock_init(&txq->lock); + txq->setup = true; + } + return &sc->txqs[qnum]; } -static void -ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) +static int +ath5k_beaconq_setup(struct ath5k_hw *ah) { - sc->curmode = mode; + struct ath5k_txq_info qi = { + .tqi_aifs = AR5K_TXQ_USEDEFAULT, + .tqi_cw_min = AR5K_TXQ_USEDEFAULT, + .tqi_cw_max = AR5K_TXQ_USEDEFAULT, + /* NB: for dynamic turbo, don't enable any other interrupts */ + .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE + }; - if (mode == AR5K_MODE_11A) { - sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; - } else { - sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; - } + return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi); } -static void -ath5k_mode_setup(struct ath5k_softc *sc) +static int +ath5k_beaconq_config(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; - u32 rfilt; - - /* configure rx filter */ - rfilt = sc->filter_flags; - ath5k_hw_set_rx_filter(ah, rfilt); + struct ath5k_txq_info qi; + int ret; - if (ath5k_hw_hasbssidmask(ah)) - ath5k_hw_set_bssid_mask(ah, sc->bssidmask); + ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); + if (ret) + goto err; - /* configure operational mode */ - ath5k_hw_set_opmode(ah, sc->opmode); + if (sc->opmode == NL80211_IFTYPE_AP || + sc->opmode == NL80211_IFTYPE_MESH_POINT) { + /* + * Always burst out beacon and CAB traffic + * (aifs = cwmin = cwmax = 0) + */ + qi.tqi_aifs = 0; + qi.tqi_cw_min = 0; + qi.tqi_cw_max = 0; + } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { + /* + * Adhoc mode; backoff between 0 and (2 * cw_min). + */ + qi.tqi_aifs = 0; + qi.tqi_cw_min = 0; + qi.tqi_cw_max = 2 * ah->ah_cw_min; + } - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); -} + ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, + "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", + qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); -static inline int -ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) -{ - int rix; + ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi); + if (ret) { + ATH5K_ERR(sc, "%s: unable to update parameters for beacon " + "hardware queue!\n", __func__); + goto err; + } + ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ + if (ret) + goto err; - /* return base rate on errors */ - if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, - "hw_rix out of bounds: %x\n", hw_rix)) - return 0; + /* reconfigure cabq with ready time to 80% of beacon_interval */ + ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; - rix = sc->rate_idx[sc->curband->band][hw_rix]; - if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) - rix = 0; + qi.tqi_ready_time = (sc->bintval * 80) / 100; + ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; - return rix; + ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); +err: + return ret; } -/***************\ -* Buffers setup * -\***************/ - -static -struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) -{ - struct ath_common *common = ath5k_hw_common(sc->ah); - struct sk_buff *skb; +static void +ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) +{ + struct ath5k_buf *bf, *bf0; /* - * Allocate buffer with headroom_needed space for the - * fake physical layer header at the start. + * NB: this assumes output has been stopped and + * we do not need to block ath5k_tx_tasklet */ - skb = ath_rxbuf_alloc(common, - common->rx_bufsize, - GFP_ATOMIC); + spin_lock_bh(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { + ath5k_debug_printtxbuf(sc, bf); - if (!skb) { - ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", - common->rx_bufsize); - return NULL; - } + ath5k_txbuf_free_skb(sc, bf); - *skb_addr = pci_map_single(sc->pdev, - skb->data, common->rx_bufsize, - PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { - ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); - dev_kfree_skb(skb); - return NULL; + spin_lock_bh(&sc->txbuflock); + list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + spin_unlock_bh(&sc->txbuflock); } - return skb; + txq->link = NULL; + spin_unlock_bh(&txq->lock); } -static int -ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) +/* + * Drain the transmit queues and reclaim resources. + */ +static void +ath5k_txq_cleanup(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; - struct sk_buff *skb = bf->skb; - struct ath5k_desc *ds; - int ret; - - if (!skb) { - skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr); - if (!skb) - return -ENOMEM; - bf->skb = skb; - } + unsigned int i; - /* - * Setup descriptors. For receive we always terminate - * the descriptor list with a self-linked entry so we'll - * not get overrun under high load (as can happen with a - * 5212 when ANI processing enables PHY error frames). - * - * To ensure the last descriptor is self-linked we create - * each descriptor as self-linked and add it to the end. As - * each additional descriptor is added the previous self-linked - * entry is "fixed" naturally. This should be safe even - * if DMA is happening. When processing RX interrupts we - * never remove/process the last, self-linked, entry on the - * descriptor list. This ensures the hardware always has - * someplace to write a new frame. - */ - ds = bf->desc; - ds->ds_link = bf->daddr; /* link to self */ - ds->ds_data = bf->skbaddr; - ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); - if (ret) { - ATH5K_ERR(sc, "%s: could not setup RX desc\n", __func__); - return ret; + /* XXX return value */ + if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) { + /* don't touch the hardware if marked invalid */ + ath5k_hw_stop_tx_dma(ah, sc->bhalq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", + ath5k_hw_get_txdp(ah, sc->bhalq)); + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) + if (sc->txqs[i].setup) { + ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " + "link %p\n", + sc->txqs[i].qnum, + ath5k_hw_get_txdp(ah, + sc->txqs[i].qnum), + sc->txqs[i].link); + } } - if (sc->rxlink != NULL) - *sc->rxlink = bf->daddr; - sc->rxlink = &ds->ds_link; - return 0; + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) + if (sc->txqs[i].setup) + ath5k_txq_drainq(sc, &sc->txqs[i]); } -static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) +static void +ath5k_txq_release(struct ath5k_softc *sc) { - struct ieee80211_hdr *hdr; - enum ath5k_pkt_type htype; - __le16 fc; + struct ath5k_txq *txq = sc->txqs; + unsigned int i; - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++) + if (txq->setup) { + ath5k_hw_release_tx_queue(sc->ah, txq->qnum); + txq->setup = false; + } +} - if (ieee80211_is_beacon(fc)) - htype = AR5K_PKT_TYPE_BEACON; - else if (ieee80211_is_probe_resp(fc)) - htype = AR5K_PKT_TYPE_PROBE_RESP; - else if (ieee80211_is_atim(fc)) - htype = AR5K_PKT_TYPE_ATIM; - else if (ieee80211_is_pspoll(fc)) - htype = AR5K_PKT_TYPE_PSPOLL; - else - htype = AR5K_PKT_TYPE_NORMAL; - return htype; -} +/*************\ +* RX Handling * +\*************/ +/* + * Enable the receive h/w following a reset. + */ static int -ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, - struct ath5k_txq *txq, int padsize) +ath5k_rx_start(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; - struct ath5k_desc *ds = bf->desc; - struct sk_buff *skb = bf->skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; - struct ieee80211_rate *rate; - unsigned int mrr_rate[3], mrr_tries[3]; - int i, ret; - u16 hw_rate; - u16 cts_rate = 0; - u16 duration = 0; - u8 rc_flags; - - flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; - - /* XXX endianness */ - bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); - - rate = ieee80211_get_tx_rate(sc->hw, info); - - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - flags |= AR5K_TXDESC_NOACK; - - rc_flags = info->control.rates[0].flags; - hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? - rate->hw_value_short : rate->hw_value; - - pktlen = skb->len; + struct ath_common *common = ath5k_hw_common(ah); + struct ath5k_buf *bf; + int ret; - /* FIXME: If we are in g mode and rate is a CCK rate - * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta - * from tx power (value is in dB units already) */ - if (info->control.hw_key) { - keyidx = info->control.hw_key->hw_key_idx; - pktlen += info->control.hw_key->icv_len; - } - if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { - flags |= AR5K_TXDESC_RTSENA; - cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; - duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, - sc->vif, pktlen, info)); - } - if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - flags |= AR5K_TXDESC_CTSENA; - cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; - duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, - sc->vif, pktlen, info)); - } - ret = ah->ah_setup_tx_desc(ah, ds, pktlen, - ieee80211_get_hdrlen_from_skb(skb), padsize, - get_hw_packet_type(skb), - (sc->power_level * 2), - hw_rate, - info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, - cts_rate, duration); - if (ret) - goto err_unmap; + common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); - memset(mrr_rate, 0, sizeof(mrr_rate)); - memset(mrr_tries, 0, sizeof(mrr_tries)); - for (i = 0; i < 3; i++) { - rate = ieee80211_get_alt_retry_rate(sc->hw, info, i); - if (!rate) - break; + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", + common->cachelsz, common->rx_bufsize); - mrr_rate[i] = rate->hw_value; - mrr_tries[i] = info->control.rates[i + 1].count; + spin_lock_bh(&sc->rxbuflock); + sc->rxlink = NULL; + list_for_each_entry(bf, &sc->rxbuf, list) { + ret = ath5k_rxbuf_setup(sc, bf); + if (ret != 0) { + spin_unlock_bh(&sc->rxbuflock); + goto err; + } } + bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); + ath5k_hw_set_rxdp(ah, bf->daddr); + spin_unlock_bh(&sc->rxbuflock); - ath5k_hw_setup_mrr_tx_desc(ah, ds, - mrr_rate[0], mrr_tries[0], - mrr_rate[1], mrr_tries[1], - mrr_rate[2], mrr_tries[2]); - - ds->ds_link = 0; - ds->ds_data = bf->skbaddr; - - spin_lock_bh(&txq->lock); - list_add_tail(&bf->list, &txq->q); - if (txq->link == NULL) /* is this first packet? */ - ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); - else /* no, so only link it */ - *txq->link = bf->daddr; - - txq->link = &ds->ds_link; - ath5k_hw_start_tx_dma(ah, txq->qnum); - mmiowb(); - spin_unlock_bh(&txq->lock); + ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ + ath5k_mode_setup(sc); /* set filters, etc. */ + ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; -err_unmap: - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); +err: return ret; } -/*******************\ -* Descriptors setup * -\*******************/ - -static int -ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) +/* + * Disable the receive h/w in preparation for a reset. + */ +static void +ath5k_rx_stop(struct ath5k_softc *sc) { - struct ath5k_desc *ds; - struct ath5k_buf *bf; - dma_addr_t da; - unsigned int i; - int ret; + struct ath5k_hw *ah = sc->ah; - /* allocate descriptors */ - sc->desc_len = sizeof(struct ath5k_desc) * - (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); - sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); - if (sc->desc == NULL) { - ATH5K_ERR(sc, "can't allocate descriptors\n"); - ret = -ENOMEM; - goto err; - } - ds = sc->desc; - da = sc->desc_daddr; - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n", - ds, sc->desc_len, (unsigned long long)sc->desc_daddr); + ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ + ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ + ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ - bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF, - sizeof(struct ath5k_buf), GFP_KERNEL); - if (bf == NULL) { - ATH5K_ERR(sc, "can't allocate bufptr\n"); - ret = -ENOMEM; - goto err_free; - } - sc->bufptr = bf; + ath5k_debug_printrxbuffs(sc, ah); +} - INIT_LIST_HEAD(&sc->rxbuf); - for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) { - bf->desc = ds; - bf->daddr = da; - list_add_tail(&bf->list, &sc->rxbuf); - } +static unsigned int +ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_rx_status *rs) +{ + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + struct ieee80211_hdr *hdr = (void *)skb->data; + unsigned int keyix, hlen; - INIT_LIST_HEAD(&sc->txbuf); - sc->txbuf_len = ATH_TXBUF; - for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, - da += sizeof(*ds)) { - bf->desc = ds; - bf->daddr = da; - list_add_tail(&bf->list, &sc->txbuf); - } + if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && + rs->rs_keyix != AR5K_RXKEYIX_INVALID) + return RX_FLAG_DECRYPTED; - /* beacon buffer */ - bf->desc = ds; - bf->daddr = da; - sc->bbuf = bf; + /* Apparently when a default key is used to decrypt the packet + the hw does not set the index used to decrypt. In such cases + get the index from the packet. */ + hlen = ieee80211_hdrlen(hdr->frame_control); + if (ieee80211_has_protected(hdr->frame_control) && + !(rs->rs_status & AR5K_RXERR_DECRYPT) && + skb->len >= hlen + 4) { + keyix = skb->data[hlen + 3] >> 6; + + if (test_bit(keyix, common->keymap)) + return RX_FLAG_DECRYPTED; + } return 0; -err_free: - pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); -err: - sc->desc = NULL; - return ret; } + static void -ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) +ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, + struct ieee80211_rx_status *rxs) { - struct ath5k_buf *bf; + struct ath_common *common = ath5k_hw_common(sc->ah); + u64 tsf, bc_tstamp; + u32 hw_tu; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - ath5k_txbuf_free_skb(sc, sc->bbuf); - list_for_each_entry(bf, &sc->txbuf, list) - ath5k_txbuf_free_skb(sc, bf); - list_for_each_entry(bf, &sc->rxbuf, list) - ath5k_rxbuf_free_skb(sc, bf); + if (ieee80211_is_beacon(mgmt->frame_control) && + le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && + memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { + /* + * Received an IBSS beacon with the same BSSID. Hardware *must* + * have updated the local TSF. We have to work around various + * hardware bugs, though... + */ + tsf = ath5k_hw_get_tsf64(sc->ah); + bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp); + hw_tu = TSF_TO_TU(tsf); - /* Free memory associated with all descriptors */ - pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); - sc->desc = NULL; - sc->desc_daddr = 0; + ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, + "beacon %llx mactime %llx (diff %lld) tsf now %llx\n", + (unsigned long long)bc_tstamp, + (unsigned long long)rxs->mactime, + (unsigned long long)(rxs->mactime - bc_tstamp), + (unsigned long long)tsf); - kfree(sc->bufptr); - sc->bufptr = NULL; - sc->bbuf = NULL; -} + /* + * Sometimes the HW will give us a wrong tstamp in the rx + * status, causing the timestamp extension to go wrong. + * (This seems to happen especially with beacon frames bigger + * than 78 byte (incl. FCS)) + * But we know that the receive timestamp must be later than the + * timestamp of the beacon since HW must have synced to that. + * + * NOTE: here we assume mactime to be after the frame was + * received, not like mac80211 which defines it at the start. + */ + if (bc_tstamp > rxs->mactime) { + ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, + "fixing mactime from %llx to %llx\n", + (unsigned long long)rxs->mactime, + (unsigned long long)tsf); + rxs->mactime = tsf; + } + /* + * Local TSF might have moved higher than our beacon timers, + * in that case we have to update them to continue sending + * beacons. This also takes care of synchronizing beacon sending + * times with other stations. + */ + if (hw_tu >= sc->nexttbtt) + ath5k_beacon_update_timers(sc, bc_tstamp); + } +} +static void +ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + /* only beacons from our BSSID */ + if (!ieee80211_is_beacon(mgmt->frame_control) || + memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) + return; + ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, + rssi); -/**************\ -* Queues setup * -\**************/ + /* in IBSS mode we should keep RSSI statistics per neighbour */ + /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ +} -static struct ath5k_txq * -ath5k_txq_setup(struct ath5k_softc *sc, - int qtype, int subtype) +/* + * Compute padding position. skb must contain an IEEE 802.11 frame + */ +static int ath5k_common_padpos(struct sk_buff *skb) { - struct ath5k_hw *ah = sc->ah; - struct ath5k_txq *txq; - struct ath5k_txq_info qi = { - .tqi_subtype = subtype, - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT - }; - int qnum; + struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; + __le16 frame_control = hdr->frame_control; + int padpos = 24; - /* - * Enable interrupts only for EOL and DESC conditions. - * We mark tx descriptors to receive a DESC interrupt - * when a tx queue gets deep; otherwise we wait for the - * EOL to reap descriptors. Note that this is done to - * reduce interrupt load and this only defers reaping - * descriptors, never transmitting frames. Aside from - * reducing interrupts this also permits more concurrency. - * The only potential downside is if the tx queue backs - * up in which case the top half of the kernel may backup - * due to a lack of tx descriptors. - */ - qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE | - AR5K_TXQ_FLAG_TXDESCINT_ENABLE; - qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi); - if (qnum < 0) { - /* - * NB: don't print a message, this happens - * normally on parts with too few tx queues - */ - return ERR_PTR(qnum); - } - if (qnum >= ARRAY_SIZE(sc->txqs)) { - ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n", - qnum, ARRAY_SIZE(sc->txqs)); - ath5k_hw_release_tx_queue(ah, qnum); - return ERR_PTR(-EINVAL); + if (ieee80211_has_a4(frame_control)) { + padpos += ETH_ALEN; } - txq = &sc->txqs[qnum]; - if (!txq->setup) { - txq->qnum = qnum; - txq->link = NULL; - INIT_LIST_HEAD(&txq->q); - spin_lock_init(&txq->lock); - txq->setup = true; + if (ieee80211_is_data_qos(frame_control)) { + padpos += IEEE80211_QOS_CTL_LEN; } - return &sc->txqs[qnum]; + + return padpos; } -static int -ath5k_beaconq_setup(struct ath5k_hw *ah) +/* + * This function expects an 802.11 frame and returns the number of + * bytes added, or -1 if we don't have enough header room. + */ +static int ath5k_add_padding(struct sk_buff *skb) { - struct ath5k_txq_info qi = { - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT, - /* NB: for dynamic turbo, don't enable any other interrupts */ - .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE - }; + int padpos = ath5k_common_padpos(skb); + int padsize = padpos & 3; - return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi); -} + if (padsize && skb->len>padpos) { -static int -ath5k_beaconq_config(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - struct ath5k_txq_info qi; - int ret; + if (skb_headroom(skb) < padsize) + return -1; - ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); - if (ret) - goto err; + skb_push(skb, padsize); + memmove(skb->data, skb->data+padsize, padpos); + return padsize; + } - if (sc->opmode == NL80211_IFTYPE_AP || - sc->opmode == NL80211_IFTYPE_MESH_POINT) { - /* - * Always burst out beacon and CAB traffic - * (aifs = cwmin = cwmax = 0) - */ - qi.tqi_aifs = 0; - qi.tqi_cw_min = 0; - qi.tqi_cw_max = 0; - } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { - /* - * Adhoc mode; backoff between 0 and (2 * cw_min). - */ - qi.tqi_aifs = 0; - qi.tqi_cw_min = 0; - qi.tqi_cw_max = 2 * ah->ah_cw_min; - } + return 0; +} - ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, - "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", - qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); +/* + * The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = 4 - (hdrlen & 3); however, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. We must not try to + * remove padding from short control frames that do not have a + * payload. + * + * This function expects an 802.11 frame and returns the number of + * bytes removed. + */ +static int ath5k_remove_padding(struct sk_buff *skb) +{ + int padpos = ath5k_common_padpos(skb); + int padsize = padpos & 3; - ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi); - if (ret) { - ATH5K_ERR(sc, "%s: unable to update parameters for beacon " - "hardware queue!\n", __func__); - goto err; + if (padsize && skb->len>=padpos+padsize) { + memmove(skb->data + padsize, skb->data, padpos); + skb_pull(skb, padsize); + return padsize; } - ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ - if (ret) - goto err; - - /* reconfigure cabq with ready time to 80% of beacon_interval */ - ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); - if (ret) - goto err; - - qi.tqi_ready_time = (sc->bintval * 80) / 100; - ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); - if (ret) - goto err; - ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); -err: - return ret; + return 0; } static void -ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) +ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_rx_status *rs) { - struct ath5k_buf *bf, *bf0; + struct ieee80211_rx_status *rxs; + + ath5k_remove_padding(skb); + + rxs = IEEE80211_SKB_RXCB(skb); + + rxs->flag = 0; + if (unlikely(rs->rs_status & AR5K_RXERR_MIC)) + rxs->flag |= RX_FLAG_MMIC_ERROR; /* - * NB: this assumes output has been stopped and - * we do not need to block ath5k_tx_tasklet + * always extend the mac timestamp, since this information is + * also needed for proper IBSS merging. + * + * XXX: it might be too late to do it here, since rs_tstamp is + * 15bit only. that means TSF extension has to be done within + * 32768usec (about 32ms). it might be necessary to move this to + * the interrupt handler, like it is done in madwifi. + * + * Unfortunately we don't know when the hardware takes the rx + * timestamp (beginning of phy frame, data frame, end of rx?). + * The only thing we know is that it is hardware specific... + * On AR5213 it seems the rx timestamp is at the end of the + * frame, but i'm not sure. + * + * NOTE: mac80211 defines mactime at the beginning of the first + * data symbol. Since we don't have any time references it's + * impossible to comply to that. This affects IBSS merge only + * right now, so it's not too bad... */ - spin_lock_bh(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ath5k_debug_printtxbuf(sc, bf); - - ath5k_txbuf_free_skb(sc, bf); + rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); + rxs->flag |= RX_FLAG_TSFT; - spin_lock_bh(&sc->txbuflock); - list_move_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - spin_unlock_bh(&sc->txbuflock); - } - txq->link = NULL; - spin_unlock_bh(&txq->lock); -} + rxs->freq = sc->curchan->center_freq; + rxs->band = sc->curband->band; -/* - * Drain the transmit queues and reclaim resources. - */ -static void -ath5k_txq_cleanup(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - unsigned int i; + rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; - /* XXX return value */ - if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) { - /* don't touch the hardware if marked invalid */ - ath5k_hw_stop_tx_dma(ah, sc->bhalq); - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", - ath5k_hw_get_txdp(ah, sc->bhalq)); - for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) - if (sc->txqs[i].setup) { - ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " - "link %p\n", - sc->txqs[i].qnum, - ath5k_hw_get_txdp(ah, - sc->txqs[i].qnum), - sc->txqs[i].link); - } - } + rxs->antenna = rs->rs_antenna; - for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) - if (sc->txqs[i].setup) - ath5k_txq_drainq(sc, &sc->txqs[i]); -} + if (rs->rs_antenna > 0 && rs->rs_antenna < 5) + sc->stats.antenna_rx[rs->rs_antenna]++; + else + sc->stats.antenna_rx[0]++; /* invalid */ -static void -ath5k_txq_release(struct ath5k_softc *sc) -{ - struct ath5k_txq *txq = sc->txqs; - unsigned int i; + rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs->rs_rate); + rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); - for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++) - if (txq->setup) { - ath5k_hw_release_tx_queue(sc->ah, txq->qnum); - txq->setup = false; - } -} + if (rxs->rate_idx >= 0 && rs->rs_rate == + sc->curband->bitrates[rxs->rate_idx].hw_value_short) + rxs->flag |= RX_FLAG_SHORTPRE; + ath5k_debug_dump_skb(sc, skb, "RX ", 0); + ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); + /* check beacons in IBSS mode */ + if (sc->opmode == NL80211_IFTYPE_ADHOC) + ath5k_check_ibss_tsf(sc, skb, rxs); -/*************\ -* RX Handling * -\*************/ + ieee80211_rx(sc->hw, skb); +} -/* - * Enable the receive h/w following a reset. +/** ath5k_frame_receive_ok() - Do we want to receive this frame or not? + * + * Check if we want to further process this frame or not. Also update + * statistics. Return true if we want this frame, false if not. */ -static int -ath5k_rx_start(struct ath5k_softc *sc) +static bool +ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) { - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - struct ath5k_buf *bf; - int ret; - - common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", - common->cachelsz, common->rx_bufsize); + sc->stats.rx_all_count++; - spin_lock_bh(&sc->rxbuflock); - sc->rxlink = NULL; - list_for_each_entry(bf, &sc->rxbuf, list) { - ret = ath5k_rxbuf_setup(sc, bf); - if (ret != 0) { - spin_unlock_bh(&sc->rxbuflock); - goto err; + if (unlikely(rs->rs_status)) { + if (rs->rs_status & AR5K_RXERR_CRC) + sc->stats.rxerr_crc++; + if (rs->rs_status & AR5K_RXERR_FIFO) + sc->stats.rxerr_fifo++; + if (rs->rs_status & AR5K_RXERR_PHY) { + sc->stats.rxerr_phy++; + if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32) + sc->stats.rxerr_phy_code[rs->rs_phyerr]++; + return false; + } + if (rs->rs_status & AR5K_RXERR_DECRYPT) { + /* + * Decrypt error. If the error occurred + * because there was no hardware key, then + * let the frame through so the upper layers + * can process it. This is necessary for 5210 + * parts which have no way to setup a ``clear'' + * key cache entry. + * + * XXX do key cache faulting + */ + sc->stats.rxerr_decrypt++; + if (rs->rs_keyix == AR5K_RXKEYIX_INVALID && + !(rs->rs_status & AR5K_RXERR_CRC)) + return true; + } + if (rs->rs_status & AR5K_RXERR_MIC) { + sc->stats.rxerr_mic++; + return true; } - } - bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); - ath5k_hw_set_rxdp(ah, bf->daddr); - spin_unlock_bh(&sc->rxbuflock); - ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_mode_setup(sc); /* set filters, etc. */ - ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ + /* reject any frames with non-crypto errors */ + if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) + return false; + } - return 0; -err: - return ret; + if (unlikely(rs->rs_more)) { + sc->stats.rxerr_jumbo++; + return false; + } + return true; } -/* - * Disable the receive h/w in preparation for a reset. - */ static void -ath5k_rx_stop(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - - ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ - ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ - ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ - - ath5k_debug_printrxbuffs(sc, ah); -} - -static unsigned int -ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb, - struct ath5k_rx_status *rs) +ath5k_tasklet_rx(unsigned long data) { + struct ath5k_rx_status rs = {}; + struct sk_buff *skb, *next_skb; + dma_addr_t next_skb_addr; + struct ath5k_softc *sc = (void *)data; struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); - struct ieee80211_hdr *hdr = (void *)skb->data; - unsigned int keyix, hlen; + struct ath5k_buf *bf; + struct ath5k_desc *ds; + int ret; - if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && - rs->rs_keyix != AR5K_RXKEYIX_INVALID) - return RX_FLAG_DECRYPTED; + spin_lock(&sc->rxbuflock); + if (list_empty(&sc->rxbuf)) { + ATH5K_WARN(sc, "empty rx buf pool\n"); + goto unlock; + } + do { + bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); + BUG_ON(bf->skb == NULL); + skb = bf->skb; + ds = bf->desc; - /* Apparently when a default key is used to decrypt the packet - the hw does not set the index used to decrypt. In such cases - get the index from the packet. */ - hlen = ieee80211_hdrlen(hdr->frame_control); - if (ieee80211_has_protected(hdr->frame_control) && - !(rs->rs_status & AR5K_RXERR_DECRYPT) && - skb->len >= hlen + 4) { - keyix = skb->data[hlen + 3] >> 6; + /* bail if HW is still using self-linked descriptor */ + if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr) + break; - if (test_bit(keyix, common->keymap)) - return RX_FLAG_DECRYPTED; - } + ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); + if (unlikely(ret == -EINPROGRESS)) + break; + else if (unlikely(ret)) { + ATH5K_ERR(sc, "error in processing rx descriptor\n"); + sc->stats.rxerr_proc++; + break; + } - return 0; -} + if (ath5k_receive_frame_ok(sc, &rs)) { + next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); + /* + * If we can't replace bf->skb with a new skb under + * memory pressure, just skip this packet + */ + if (!next_skb) + goto next; -static void -ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, - struct ieee80211_rx_status *rxs) -{ - struct ath_common *common = ath5k_hw_common(sc->ah); - u64 tsf, bc_tstamp; - u32 hw_tu; - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + pci_unmap_single(sc->pdev, bf->skbaddr, + common->rx_bufsize, + PCI_DMA_FROMDEVICE); - if (ieee80211_is_beacon(mgmt->frame_control) && - le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && - memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { - /* - * Received an IBSS beacon with the same BSSID. Hardware *must* - * have updated the local TSF. We have to work around various - * hardware bugs, though... - */ - tsf = ath5k_hw_get_tsf64(sc->ah); - bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp); - hw_tu = TSF_TO_TU(tsf); + skb_put(skb, rs.rs_datalen); - ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, - "beacon %llx mactime %llx (diff %lld) tsf now %llx\n", - (unsigned long long)bc_tstamp, - (unsigned long long)rxs->mactime, - (unsigned long long)(rxs->mactime - bc_tstamp), - (unsigned long long)tsf); + ath5k_receive_frame(sc, skb, &rs); - /* - * Sometimes the HW will give us a wrong tstamp in the rx - * status, causing the timestamp extension to go wrong. - * (This seems to happen especially with beacon frames bigger - * than 78 byte (incl. FCS)) - * But we know that the receive timestamp must be later than the - * timestamp of the beacon since HW must have synced to that. - * - * NOTE: here we assume mactime to be after the frame was - * received, not like mac80211 which defines it at the start. - */ - if (bc_tstamp > rxs->mactime) { - ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, - "fixing mactime from %llx to %llx\n", - (unsigned long long)rxs->mactime, - (unsigned long long)tsf); - rxs->mactime = tsf; + bf->skb = next_skb; + bf->skbaddr = next_skb_addr; } - - /* - * Local TSF might have moved higher than our beacon timers, - * in that case we have to update them to continue sending - * beacons. This also takes care of synchronizing beacon sending - * times with other stations. - */ - if (hw_tu >= sc->nexttbtt) - ath5k_beacon_update_timers(sc, bc_tstamp); - } +next: + list_move_tail(&bf->list, &sc->rxbuf); + } while (ath5k_rxbuf_setup(sc, bf) == 0); +unlock: + spin_unlock(&sc->rxbuflock); } -static void -ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - /* only beacons from our BSSID */ - if (!ieee80211_is_beacon(mgmt->frame_control) || - memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) - return; +/*************\ +* TX Handling * +\*************/ - ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, - rssi); +static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_buf *bf; + unsigned long flags; + int padsize; - /* in IBSS mode we should keep RSSI statistics per neighbour */ - /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ -} + ath5k_debug_dump_skb(sc, skb, "TX ", 1); -/* - * Compute padding position. skb must contain an IEEE 802.11 frame - */ -static int ath5k_common_padpos(struct sk_buff *skb) -{ - struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; - __le16 frame_control = hdr->frame_control; - int padpos = 24; + /* + * The hardware expects the header padded to 4 byte boundaries. + * If this is not the case, we add the padding after the header. + */ + padsize = ath5k_add_padding(skb); + if (padsize < 0) { + ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" + " headroom to pad"); + goto drop_packet; + } - if (ieee80211_has_a4(frame_control)) { - padpos += ETH_ALEN; + spin_lock_irqsave(&sc->txbuflock, flags); + if (list_empty(&sc->txbuf)) { + ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); + spin_unlock_irqrestore(&sc->txbuflock, flags); + ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); + goto drop_packet; } - if (ieee80211_is_data_qos(frame_control)) { - padpos += IEEE80211_QOS_CTL_LEN; + bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); + list_del(&bf->list); + sc->txbuf_len--; + if (list_empty(&sc->txbuf)) + ieee80211_stop_queues(hw); + spin_unlock_irqrestore(&sc->txbuflock, flags); + + bf->skb = skb; + + if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { + bf->skb = NULL; + spin_lock_irqsave(&sc->txbuflock, flags); + list_add_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + spin_unlock_irqrestore(&sc->txbuflock, flags); + goto drop_packet; } + return NETDEV_TX_OK; - return padpos; +drop_packet: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } -/* - * This function expects an 802.11 frame and returns the number of - * bytes added, or -1 if we don't have enough header room. - */ -static int ath5k_add_padding(struct sk_buff *skb) + +static void +ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) { - int padpos = ath5k_common_padpos(skb); - int padsize = padpos & 3; + struct ath5k_tx_status ts = {}; + struct ath5k_buf *bf, *bf0; + struct ath5k_desc *ds; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + int i, ret; - if (padsize && skb->len>padpos) { + spin_lock(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { + ds = bf->desc; - if (skb_headroom(skb) < padsize) - return -1; + /* + * It's possible that the hardware can say the buffer is + * completed when it hasn't yet loaded the ds_link from + * host memory and moved on. If there are more TX + * descriptors in the queue, wait for TXDP to change + * before processing this one. + */ + if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && + !list_is_last(&bf->list, &txq->q)) + break; - skb_push(skb, padsize); - memmove(skb->data, skb->data+padsize, padpos); - return padsize; - } + ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); + if (unlikely(ret == -EINPROGRESS)) + break; + else if (unlikely(ret)) { + ATH5K_ERR(sc, "error %d while processing queue %u\n", + ret, txq->qnum); + break; + } - return 0; -} - -/* - * The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = 4 - (hdrlen & 3); however, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. We must not try to - * remove padding from short control frames that do not have a - * payload. - * - * This function expects an 802.11 frame and returns the number of - * bytes removed. - */ -static int ath5k_remove_padding(struct sk_buff *skb) -{ - int padpos = ath5k_common_padpos(skb); - int padsize = padpos & 3; - - if (padsize && skb->len>=padpos+padsize) { - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); - return padsize; - } - - return 0; -} - -static void -ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, - struct ath5k_rx_status *rs) -{ - struct ieee80211_rx_status *rxs; - - ath5k_remove_padding(skb); - - rxs = IEEE80211_SKB_RXCB(skb); - - rxs->flag = 0; - if (unlikely(rs->rs_status & AR5K_RXERR_MIC)) - rxs->flag |= RX_FLAG_MMIC_ERROR; - - /* - * always extend the mac timestamp, since this information is - * also needed for proper IBSS merging. - * - * XXX: it might be too late to do it here, since rs_tstamp is - * 15bit only. that means TSF extension has to be done within - * 32768usec (about 32ms). it might be necessary to move this to - * the interrupt handler, like it is done in madwifi. - * - * Unfortunately we don't know when the hardware takes the rx - * timestamp (beginning of phy frame, data frame, end of rx?). - * The only thing we know is that it is hardware specific... - * On AR5213 it seems the rx timestamp is at the end of the - * frame, but i'm not sure. - * - * NOTE: mac80211 defines mactime at the beginning of the first - * data symbol. Since we don't have any time references it's - * impossible to comply to that. This affects IBSS merge only - * right now, so it's not too bad... - */ - rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); - rxs->flag |= RX_FLAG_TSFT; - - rxs->freq = sc->curchan->center_freq; - rxs->band = sc->curband->band; - - rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; - - rxs->antenna = rs->rs_antenna; - - if (rs->rs_antenna > 0 && rs->rs_antenna < 5) - sc->stats.antenna_rx[rs->rs_antenna]++; - else - sc->stats.antenna_rx[0]++; /* invalid */ - - rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs->rs_rate); - rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); - - if (rxs->rate_idx >= 0 && rs->rs_rate == - sc->curband->bitrates[rxs->rate_idx].hw_value_short) - rxs->flag |= RX_FLAG_SHORTPRE; - - ath5k_debug_dump_skb(sc, skb, "RX ", 0); - - ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); - - /* check beacons in IBSS mode */ - if (sc->opmode == NL80211_IFTYPE_ADHOC) - ath5k_check_ibss_tsf(sc, skb, rxs); - - ieee80211_rx(sc->hw, skb); -} - -/** ath5k_frame_receive_ok() - Do we want to receive this frame or not? - * - * Check if we want to further process this frame or not. Also update - * statistics. Return true if we want this frame, false if not. - */ -static bool -ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) -{ - sc->stats.rx_all_count++; - - if (unlikely(rs->rs_status)) { - if (rs->rs_status & AR5K_RXERR_CRC) - sc->stats.rxerr_crc++; - if (rs->rs_status & AR5K_RXERR_FIFO) - sc->stats.rxerr_fifo++; - if (rs->rs_status & AR5K_RXERR_PHY) { - sc->stats.rxerr_phy++; - if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32) - sc->stats.rxerr_phy_code[rs->rs_phyerr]++; - return false; - } - if (rs->rs_status & AR5K_RXERR_DECRYPT) { - /* - * Decrypt error. If the error occurred - * because there was no hardware key, then - * let the frame through so the upper layers - * can process it. This is necessary for 5210 - * parts which have no way to setup a ``clear'' - * key cache entry. - * - * XXX do key cache faulting - */ - sc->stats.rxerr_decrypt++; - if (rs->rs_keyix == AR5K_RXKEYIX_INVALID && - !(rs->rs_status & AR5K_RXERR_CRC)) - return true; - } - if (rs->rs_status & AR5K_RXERR_MIC) { - sc->stats.rxerr_mic++; - return true; - } - - /* reject any frames with non-crypto errors */ - if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) - return false; - } - - if (unlikely(rs->rs_more)) { - sc->stats.rxerr_jumbo++; - return false; - } - return true; -} - -static void -ath5k_tasklet_rx(unsigned long data) -{ - struct ath5k_rx_status rs = {}; - struct sk_buff *skb, *next_skb; - dma_addr_t next_skb_addr; - struct ath5k_softc *sc = (void *)data; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - struct ath5k_buf *bf; - struct ath5k_desc *ds; - int ret; - - spin_lock(&sc->rxbuflock); - if (list_empty(&sc->rxbuf)) { - ATH5K_WARN(sc, "empty rx buf pool\n"); - goto unlock; - } - do { - bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); - BUG_ON(bf->skb == NULL); - skb = bf->skb; - ds = bf->desc; - - /* bail if HW is still using self-linked descriptor */ - if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr) - break; - - ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(sc, "error in processing rx descriptor\n"); - sc->stats.rxerr_proc++; - break; - } - - if (ath5k_receive_frame_ok(sc, &rs)) { - next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); - - /* - * If we can't replace bf->skb with a new skb under - * memory pressure, just skip this packet - */ - if (!next_skb) - goto next; - - pci_unmap_single(sc->pdev, bf->skbaddr, - common->rx_bufsize, - PCI_DMA_FROMDEVICE); - - skb_put(skb, rs.rs_datalen); - - ath5k_receive_frame(sc, skb, &rs); - - bf->skb = next_skb; - bf->skbaddr = next_skb_addr; - } -next: - list_move_tail(&bf->list, &sc->rxbuf); - } while (ath5k_rxbuf_setup(sc, bf) == 0); -unlock: - spin_unlock(&sc->rxbuflock); -} - - -/*************\ -* TX Handling * -\*************/ - -static void -ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) -{ - struct ath5k_tx_status ts = {}; - struct ath5k_buf *bf, *bf0; - struct ath5k_desc *ds; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - int i, ret; - - spin_lock(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ds = bf->desc; - - /* - * It's possible that the hardware can say the buffer is - * completed when it hasn't yet loaded the ds_link from - * host memory and moved on. If there are more TX - * descriptors in the queue, wait for TXDP to change - * before processing this one. - */ - if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && - !list_is_last(&bf->list, &txq->q)) - break; - - ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(sc, "error %d while processing queue %u\n", - ret, txq->qnum); - break; - } - - sc->stats.tx_all_count++; - skb = bf->skb; - info = IEEE80211_SKB_CB(skb); - bf->skb = NULL; + sc->stats.tx_all_count++; + skb = bf->skb; + info = IEEE80211_SKB_CB(skb); + bf->skb = NULL; pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); @@ -2308,6 +1702,43 @@ err_unmap: return ret; } +/* + * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, + * this is called only once at config_bss time, for AP we do it every + * SWBA interrupt so that the TIM will reflect buffered frames. + * + * Called with the beacon lock. + */ +static int +ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + int ret; + struct ath5k_softc *sc = hw->priv; + struct sk_buff *skb; + + if (WARN_ON(!vif)) { + ret = -EINVAL; + goto out; + } + + skb = ieee80211_beacon_get(hw, vif); + + if (!skb) { + ret = -ENOMEM; + goto out; + } + + ath5k_debug_dump_skb(sc, skb, "BC ", 1); + + ath5k_txbuf_free_skb(sc, sc->bbuf); + sc->bbuf->skb = skb; + ret = ath5k_beacon_setup(sc, sc->bbuf); + if (ret) + sc->bbuf->skb = NULL; +out: + return ret; +} + /* * Transmit a beacon frame at SWBA. Dynamic updates to the * frame contents are done as needed and the slot time is @@ -2385,7 +1816,6 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->bsent++; } - /** * ath5k_beacon_update_timers - update beacon timers * @@ -2487,7 +1917,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); } - /** * ath5k_beacon_config - Configure the beacon queues and interrupts * @@ -2566,156 +1995,6 @@ static void ath5k_tasklet_beacon(unsigned long data) * Interrupt handling * \********************/ -static int -ath5k_init(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - int ret, i; - - mutex_lock(&sc->lock); - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); - - /* - * Stop anything previously setup. This is safe - * no matter this is the first time through or not. - */ - ath5k_stop_locked(sc); - - /* - * The basic interface to setting the hardware in a good - * state is ``reset''. On return the hardware is known to - * be powered up and with interrupts disabled. This must - * be followed by initialization of the appropriate bits - * and then setup of the interrupt mask. - */ - sc->curchan = sc->hw->conf.channel; - sc->curband = &sc->sbands[sc->curchan->band]; - sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | - AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | - AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; - - ret = ath5k_reset(sc, NULL); - if (ret) - goto done; - - ath5k_rfkill_hw_start(ah); - - /* - * Reset the key cache since some parts do not reset the - * contents on initial power up or resume from suspend. - */ - for (i = 0; i < common->keymax; i++) - ath_hw_keyreset(common, (u16)i); - - ath5k_hw_set_ack_bitrate_high(ah, true); - ret = 0; -done: - mmiowb(); - mutex_unlock(&sc->lock); - return ret; -} - -static int -ath5k_stop_locked(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", - test_bit(ATH_STAT_INVALID, sc->status)); - - /* - * Shutdown the hardware and driver: - * stop output from above - * disable interrupts - * turn off timers - * turn off the radio - * clear transmit machinery - * clear receive machinery - * drain and release tx queues - * reclaim beacon resources - * power down hardware - * - * Note that some of this work is not possible if the - * hardware is gone (invalid). - */ - ieee80211_stop_queues(sc->hw); - - if (!test_bit(ATH_STAT_INVALID, sc->status)) { - ath5k_led_off(sc); - ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); - } - ath5k_txq_cleanup(sc); - if (!test_bit(ATH_STAT_INVALID, sc->status)) { - ath5k_rx_stop(sc); - ath5k_hw_phy_disable(ah); - } - - return 0; -} - -static void stop_tasklets(struct ath5k_softc *sc) -{ - tasklet_kill(&sc->rxtq); - tasklet_kill(&sc->txtq); - tasklet_kill(&sc->calib); - tasklet_kill(&sc->beacontq); - tasklet_kill(&sc->ani_tasklet); -} - -/* - * Stop the device, grabbing the top-level lock to protect - * against concurrent entry through ath5k_init (which can happen - * if another thread does a system call and the thread doing the - * stop is preempted). - */ -static int -ath5k_stop_hw(struct ath5k_softc *sc) -{ - int ret; - - mutex_lock(&sc->lock); - ret = ath5k_stop_locked(sc); - if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { - /* - * Don't set the card in full sleep mode! - * - * a) When the device is in this state it must be carefully - * woken up or references to registers in the PCI clock - * domain may freeze the bus (and system). This varies - * by chip and is mostly an issue with newer parts - * (madwifi sources mentioned srev >= 0x78) that go to - * sleep more quickly. - * - * b) On older chips full sleep results a weird behaviour - * during wakeup. I tested various cards with srev < 0x78 - * and they don't wake up after module reload, a second - * module reload is needed to bring the card up again. - * - * Until we figure out what's going on don't enable - * full chip reset on any chip (this is what Legacy HAL - * and Sam's HAL do anyway). Instead Perform a full reset - * on the device (same as initial state after attach) and - * leave it idle (keep MAC/BB on warm reset) */ - ret = ath5k_hw_on_hold(sc->ah); - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, - "putting device to sleep\n"); - } - ath5k_txbuf_free_skb(sc, sc->bbuf); - - mmiowb(); - mutex_unlock(&sc->lock); - - stop_tasklets(sc); - - ath5k_rfkill_hw_stop(sc->ah); - - return ret; -} - static void ath5k_intr_calibration_poll(struct ath5k_hw *ah) { @@ -2878,68 +2157,158 @@ ath5k_tasklet_ani(unsigned long data) } -/********************\ -* Mac80211 functions * -\********************/ +/*************************\ +* Initialization routines * +\*************************/ static int -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +ath5k_stop_locked(struct ath5k_softc *sc) { - struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; - return ath5k_tx_queue(hw, skb, sc->txq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", + test_bit(ATH_STAT_INVALID, sc->status)); + + /* + * Shutdown the hardware and driver: + * stop output from above + * disable interrupts + * turn off timers + * turn off the radio + * clear transmit machinery + * clear receive machinery + * drain and release tx queues + * reclaim beacon resources + * power down hardware + * + * Note that some of this work is not possible if the + * hardware is gone (invalid). + */ + ieee80211_stop_queues(sc->hw); + + if (!test_bit(ATH_STAT_INVALID, sc->status)) { + ath5k_led_off(sc); + ath5k_hw_set_imr(ah, 0); + synchronize_irq(sc->pdev->irq); + } + ath5k_txq_cleanup(sc); + if (!test_bit(ATH_STAT_INVALID, sc->status)) { + ath5k_rx_stop(sc); + ath5k_hw_phy_disable(ah); + } + + return 0; } -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq) +static int +ath5k_init(struct ath5k_softc *sc) { - struct ath5k_softc *sc = hw->priv; - struct ath5k_buf *bf; - unsigned long flags; - int padsize; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + int ret, i; - ath5k_debug_dump_skb(sc, skb, "TX ", 1); + mutex_lock(&sc->lock); + + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); /* - * The hardware expects the header padded to 4 byte boundaries. - * If this is not the case, we add the padding after the header. + * Stop anything previously setup. This is safe + * no matter this is the first time through or not. */ - padsize = ath5k_add_padding(skb); - if (padsize < 0) { - ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" - " headroom to pad"); - goto drop_packet; - } + ath5k_stop_locked(sc); - spin_lock_irqsave(&sc->txbuflock, flags); - if (list_empty(&sc->txbuf)) { - ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); - spin_unlock_irqrestore(&sc->txbuflock, flags); - ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); - goto drop_packet; - } - bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); - list_del(&bf->list); - sc->txbuf_len--; - if (list_empty(&sc->txbuf)) - ieee80211_stop_queues(hw); - spin_unlock_irqrestore(&sc->txbuflock, flags); + /* + * The basic interface to setting the hardware in a good + * state is ``reset''. On return the hardware is known to + * be powered up and with interrupts disabled. This must + * be followed by initialization of the appropriate bits + * and then setup of the interrupt mask. + */ + sc->curchan = sc->hw->conf.channel; + sc->curband = &sc->sbands[sc->curchan->band]; + sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | + AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | + AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; - bf->skb = skb; + ret = ath5k_reset(sc, NULL); + if (ret) + goto done; - if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { - bf->skb = NULL; - spin_lock_irqsave(&sc->txbuflock, flags); - list_add_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - spin_unlock_irqrestore(&sc->txbuflock, flags); - goto drop_packet; + ath5k_rfkill_hw_start(ah); + + /* + * Reset the key cache since some parts do not reset the + * contents on initial power up or resume from suspend. + */ + for (i = 0; i < common->keymax; i++) + ath_hw_keyreset(common, (u16) i); + + ath5k_hw_set_ack_bitrate_high(ah, true); + ret = 0; +done: + mmiowb(); + mutex_unlock(&sc->lock); + return ret; +} + +static void stop_tasklets(struct ath5k_softc *sc) +{ + tasklet_kill(&sc->rxtq); + tasklet_kill(&sc->txtq); + tasklet_kill(&sc->calib); + tasklet_kill(&sc->beacontq); + tasklet_kill(&sc->ani_tasklet); +} + +/* + * Stop the device, grabbing the top-level lock to protect + * against concurrent entry through ath5k_init (which can happen + * if another thread does a system call and the thread doing the + * stop is preempted). + */ +static int +ath5k_stop_hw(struct ath5k_softc *sc) +{ + int ret; + + mutex_lock(&sc->lock); + ret = ath5k_stop_locked(sc); + if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { + /* + * Don't set the card in full sleep mode! + * + * a) When the device is in this state it must be carefully + * woken up or references to registers in the PCI clock + * domain may freeze the bus (and system). This varies + * by chip and is mostly an issue with newer parts + * (madwifi sources mentioned srev >= 0x78) that go to + * sleep more quickly. + * + * b) On older chips full sleep results a weird behaviour + * during wakeup. I tested various cards with srev < 0x78 + * and they don't wake up after module reload, a second + * module reload is needed to bring the card up again. + * + * Until we figure out what's going on don't enable + * full chip reset on any chip (this is what Legacy HAL + * and Sam's HAL do anyway). Instead Perform a full reset + * on the device (same as initial state after attach) and + * leave it idle (keep MAC/BB on warm reset) */ + ret = ath5k_hw_on_hold(sc->ah); + + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "putting device to sleep\n"); } - return NETDEV_TX_OK; + ath5k_txbuf_free_skb(sc, sc->bbuf); -drop_packet: - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; + mmiowb(); + mutex_unlock(&sc->lock); + + stop_tasklets(sc); + + ath5k_rfkill_hw_stop(sc->ah); + + return ret; } /* @@ -3016,91 +2385,264 @@ static void ath5k_reset_work(struct work_struct *work) mutex_unlock(&sc->lock); } -static int ath5k_start(struct ieee80211_hw *hw) -{ - return ath5k_init(hw->priv); -} - -static void ath5k_stop(struct ieee80211_hw *hw) -{ - ath5k_stop_hw(hw->priv); -} - -static int ath5k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static int +ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) { struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); + u8 mac[ETH_ALEN] = {}; int ret; - mutex_lock(&sc->lock); - if (sc->vif) { - ret = 0; - goto end; - } - - sc->vif = vif; + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); - switch (vif->type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - sc->opmode = vif->type; - break; - default: - ret = -EOPNOTSUPP; - goto end; - } + /* + * Check if the MAC has multi-rate retry support. + * We do this by trying to setup a fake extended + * descriptor. MACs that don't have support will + * return false w/o doing anything. MACs that do + * support it will return true w/o doing anything. + */ + ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); + if (ret < 0) + goto err; + if (ret > 0) + __set_bit(ATH_STAT_MRRETRY, sc->status); - ath5k_hw_set_lladdr(sc->ah, vif->addr); - ath5k_mode_setup(sc); + /* + * Collect the channel list. The 802.11 layer + * is resposible for filtering this list based + * on settings like the phy mode and regulatory + * domain restrictions. + */ + ret = ath5k_setup_bands(hw); + if (ret) { + ATH5K_ERR(sc, "can't get channels\n"); + goto err; + } - ret = 0; -end: - mutex_unlock(&sc->lock); - return ret; -} + /* NB: setup here so ath5k_rate_update is happy */ + if (test_bit(AR5K_MODE_11A, ah->ah_modes)) + ath5k_setcurmode(sc, AR5K_MODE_11A); + else + ath5k_setcurmode(sc, AR5K_MODE_11B); -static void -ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ath5k_softc *sc = hw->priv; - u8 mac[ETH_ALEN] = {}; + /* + * Allocate tx+rx descriptors and populate the lists. + */ + ret = ath5k_desc_alloc(sc, pdev); + if (ret) { + ATH5K_ERR(sc, "can't allocate descriptors\n"); + goto err; + } - mutex_lock(&sc->lock); - if (sc->vif != vif) - goto end; + /* + * Allocate hardware transmit queues: one queue for + * beacon frames and one data queue for each QoS + * priority. Note that hw functions handle resetting + * these queues at the needed time. + */ + ret = ath5k_beaconq_setup(ah); + if (ret < 0) { + ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); + goto err_desc; + } + sc->bhalq = ret; + sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); + if (IS_ERR(sc->cabq)) { + ATH5K_ERR(sc, "can't setup cab queue\n"); + ret = PTR_ERR(sc->cabq); + goto err_bhal; + } - ath5k_hw_set_lladdr(sc->ah, mac); - sc->vif = NULL; -end: - mutex_unlock(&sc->lock); -} + sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); + if (IS_ERR(sc->txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(sc->txq); + goto err_queues; + } -/* - * TODO: Phy disable/diversity etc - */ -static int -ath5k_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ieee80211_conf *conf = &hw->conf; - int ret = 0; + tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); + tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); + tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); + tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); + tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); - mutex_lock(&sc->lock); + INIT_WORK(&sc->reset_work, ath5k_reset_work); - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(sc, conf->channel); - if (ret < 0) - goto unlock; + ret = ath5k_eeprom_read_mac(ah, mac); + if (ret) { + ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", + sc->pdev->device); + goto err_queues; } - if ((changed & IEEE80211_CONF_CHANGE_POWER) && - (sc->power_level != conf->power_level)) { + SET_IEEE80211_PERM_ADDR(hw, mac); + /* All MAC address bits matter for ACKs */ + memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); + ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); + + regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; + ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); + if (ret) { + ATH5K_ERR(sc, "can't initialize regulatory system\n"); + goto err_queues; + } + + ret = ieee80211_register_hw(hw); + if (ret) { + ATH5K_ERR(sc, "can't register ieee80211 hw\n"); + goto err_queues; + } + + if (!ath_is_world_regd(regulatory)) + regulatory_hint(hw->wiphy, regulatory->alpha2); + + ath5k_init_leds(sc); + + ath5k_sysfs_register(sc); + + return 0; +err_queues: + ath5k_txq_release(sc); +err_bhal: + ath5k_hw_release_tx_queue(ah, sc->bhalq); +err_desc: + ath5k_desc_free(sc, pdev); +err: + return ret; +} + +static void +ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + /* + * NB: the order of these is important: + * o call the 802.11 layer before detaching ath5k_hw to + * ensure callbacks into the driver to delete global + * key cache entries can be handled + * o reclaim the tx queue data structures after calling + * the 802.11 layer as we'll get called back to reclaim + * node state and potentially want to use them + * o to cleanup the tx queues the hal is called, so detach + * it last + * XXX: ??? detach ath5k_hw ??? + * Other than that, it's straightforward... + */ + ieee80211_unregister_hw(hw); + ath5k_desc_free(sc, pdev); + ath5k_txq_release(sc); + ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); + ath5k_unregister_leds(sc); + + ath5k_sysfs_unregister(sc); + /* + * NB: can't reclaim these until after ieee80211_ifdetach + * returns because we'll get called back to reclaim node + * state and potentially want to use them. + */ +} + +/********************\ +* Mac80211 functions * +\********************/ + +static int +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ath5k_softc *sc = hw->priv; + + return ath5k_tx_queue(hw, skb, sc->txq); +} + +static int ath5k_start(struct ieee80211_hw *hw) +{ + return ath5k_init(hw->priv); +} + +static void ath5k_stop(struct ieee80211_hw *hw) +{ + ath5k_stop_hw(hw->priv); +} + +static int ath5k_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath5k_softc *sc = hw->priv; + int ret; + + mutex_lock(&sc->lock); + if (sc->vif) { + ret = 0; + goto end; + } + + sc->vif = vif; + + switch (vif->type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + sc->opmode = vif->type; + break; + default: + ret = -EOPNOTSUPP; + goto end; + } + + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); + + ath5k_hw_set_lladdr(sc->ah, vif->addr); + ath5k_mode_setup(sc); + + ret = 0; +end: + mutex_unlock(&sc->lock); + return ret; +} + +static void +ath5k_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath5k_softc *sc = hw->priv; + u8 mac[ETH_ALEN] = {}; + + mutex_lock(&sc->lock); + if (sc->vif != vif) + goto end; + + ath5k_hw_set_lladdr(sc->ah, mac); + sc->vif = NULL; +end: + mutex_unlock(&sc->lock); +} + +/* + * TODO: Phy disable/diversity etc + */ +static int +ath5k_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ieee80211_conf *conf = &hw->conf; + int ret = 0; + + mutex_lock(&sc->lock); + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + ret = ath5k_chan_set(sc, conf->channel); + if (ret < 0) + goto unlock; + } + + if ((changed & IEEE80211_CONF_CHANGE_POWER) && + (sc->power_level != conf->power_level)) { sc->power_level = conf->power_level; /* Half dB steps */ @@ -3325,214 +2867,538 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = -EINVAL; } - mmiowb(); - mutex_unlock(&sc->lock); - return ret; -} - -static int -ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct ath5k_softc *sc = hw->priv; - - /* Force update */ - ath5k_hw_update_mib_counters(sc->ah); - - stats->dot11ACKFailureCount = sc->stats.ack_fail; - stats->dot11RTSFailureCount = sc->stats.rts_fail; - stats->dot11RTSSuccessCount = sc->stats.rts_ok; - stats->dot11FCSErrorCount = sc->stats.fcs_error; - - return 0; -} - -static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct ath5k_softc *sc = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; + mmiowb(); + mutex_unlock(&sc->lock); + return ret; +} + +static int +ath5k_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct ath5k_softc *sc = hw->priv; + + /* Force update */ + ath5k_hw_update_mib_counters(sc->ah); + + stats->dot11ACKFailureCount = sc->stats.ack_fail; + stats->dot11RTSFailureCount = sc->stats.rts_fail; + stats->dot11RTSSuccessCount = sc->stats.rts_ok; + stats->dot11FCSErrorCount = sc->stats.fcs_error; + + return 0; +} + +static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ath5k_softc *sc = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = sc->ah->ah_noise_floor; + + return 0; +} + +static u64 +ath5k_get_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + return ath5k_hw_get_tsf64(sc->ah); +} + +static void +ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + struct ath5k_softc *sc = hw->priv; + + ath5k_hw_set_tsf64(sc->ah, tsf); +} + +static void +ath5k_reset_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + /* + * in IBSS mode we need to update the beacon timers too. + * this will also reset the TSF if we call it with 0 + */ + if (sc->opmode == NL80211_IFTYPE_ADHOC) + ath5k_beacon_update_timers(sc, 0); + else + ath5k_hw_reset_tsf(sc->ah); +} + +static void +set_beacon_filter(struct ieee80211_hw *hw, bool enable) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + u32 rfilt; + rfilt = ath5k_hw_get_rx_filter(ah); + if (enable) + rfilt |= AR5K_RX_FILTER_BEACON; + else + rfilt &= ~AR5K_RX_FILTER_BEACON; + ath5k_hw_set_rx_filter(ah, rfilt); + sc->filter_flags = rfilt; +} + +static void ath5k_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + unsigned long flags; + + mutex_lock(&sc->lock); + if (WARN_ON(sc->vif != vif)) + goto unlock; + + if (changes & BSS_CHANGED_BSSID) { + /* Cache for later use during resets */ + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = 0; + ath5k_hw_set_bssid(ah); + mmiowb(); + } + + if (changes & BSS_CHANGED_BEACON_INT) + sc->bintval = bss_conf->beacon_int; + + if (changes & BSS_CHANGED_ASSOC) { + sc->assoc = bss_conf->assoc; + if (sc->opmode == NL80211_IFTYPE_STATION) + set_beacon_filter(hw, sc->assoc); + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); + if (bss_conf->assoc) { + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Bss Info ASSOC %d, bssid: %pM\n", + bss_conf->aid, common->curbssid); + common->curaid = bss_conf->aid; + ath5k_hw_set_bssid(ah); + /* Once ANI is available you would start it here */ + } + } + + if (changes & BSS_CHANGED_BEACON) { + spin_lock_irqsave(&sc->block, flags); + ath5k_beacon_update(hw, vif); + spin_unlock_irqrestore(&sc->block, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) + sc->enable_beacon = bss_conf->enable_beacon; + + if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | + BSS_CHANGED_BEACON_INT)) + ath5k_beacon_config(sc); + + unlock: + mutex_unlock(&sc->lock); +} + +static void ath5k_sw_scan_start(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + if (!sc->assoc) + ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); +} + +static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); +} + +/** + * ath5k_set_coverage_class - Set IEEE 802.11 coverage class + * + * @hw: struct ieee80211_hw pointer + * @coverage_class: IEEE 802.11 coverage class number + * + * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given + * coverage class. The values are persistent, they are restored after device + * reset. + */ +static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) +{ + struct ath5k_softc *sc = hw->priv; + + mutex_lock(&sc->lock); + ath5k_hw_set_coverage_class(sc->ah, coverage_class); + mutex_unlock(&sc->lock); +} + +static const struct ieee80211_ops ath5k_hw_ops = { + .tx = ath5k_tx, + .start = ath5k_start, + .stop = ath5k_stop, + .add_interface = ath5k_add_interface, + .remove_interface = ath5k_remove_interface, + .config = ath5k_config, + .prepare_multicast = ath5k_prepare_multicast, + .configure_filter = ath5k_configure_filter, + .set_key = ath5k_set_key, + .get_stats = ath5k_get_stats, + .get_survey = ath5k_get_survey, + .conf_tx = NULL, + .get_tsf = ath5k_get_tsf, + .set_tsf = ath5k_set_tsf, + .reset_tsf = ath5k_reset_tsf, + .bss_info_changed = ath5k_bss_info_changed, + .sw_scan_start = ath5k_sw_scan_start, + .sw_scan_complete = ath5k_sw_scan_complete, + .set_coverage_class = ath5k_set_coverage_class, +}; + +/********************\ +* PCI Initialization * +\********************/ + +static int __devinit +ath5k_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + void __iomem *mem; + struct ath5k_softc *sc; + struct ath_common *common; + struct ieee80211_hw *hw; + int ret; + u8 csz; + + /* + * L0s needs to be disabled on all ath5k cards. + * + * For distributions shipping with CONFIG_PCIEASPM (this will be enabled + * by default in the future in 2.6.36) this will also mean both L1 and + * L0s will be disabled when a pre 1.1 PCIe device is detected. We do + * know L1 works correctly even for all ath5k pre 1.1 PCIe devices + * though but cannot currently undue the effect of a blacklist, for + * details you can read pcie_aspm_sanity_check() and see how it adjusts + * the device link capability. + * + * It may be possible in the future to implement some PCI API to allow + * drivers to override blacklists for pre 1.1 PCIe but for now it is + * best to accept that both L0s and L1 will be disabled completely for + * distributions shipping with CONFIG_PCIEASPM rather than having this + * issue present. Motivation for adding this new API will be to help + * with power consumption for some of these devices. + */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "can't enable device\n"); + goto err; + } + + /* XXX 32-bit addressing only */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "32-bit DMA not available\n"); + goto err_dis; + } + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); + if (csz == 0) { + /* + * Linux 2.4.18 (at least) writes the cache line size + * register as a 16-bit wide register which is wrong. + * We must have this setup properly for rx buffer + * DMA to work so force a reasonable value here if it + * comes up zero. + */ + csz = L1_CACHE_BYTES >> 2; + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); + } + /* + * The default setting of latency timer yields poor results, + * set it to the value used by other systems. It may be worth + * tweaking this setting more. + */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); + + /* Enable bus mastering */ + pci_set_master(pdev); + + /* + * Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, 0x41, 0); + + ret = pci_request_region(pdev, 0, "ath5k"); + if (ret) { + dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); + goto err_dis; + } + + mem = pci_iomap(pdev, 0, 0); + if (!mem) { + dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; + ret = -EIO; + goto err_reg; + } + + /* + * Allocate hw (mac80211 main struct) + * and hw->priv (driver private data) + */ + hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); + ret = -ENOMEM; + goto err_map; + } + + dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); + + /* Initialize driver private data */ + SET_IEEE80211_DEV(hw, &pdev->dev); + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; + + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + + hw->extra_tx_headroom = 2; + hw->channel_change_time = 5000; + sc = hw->priv; + sc->hw = hw; + sc->pdev = pdev; + + ath5k_debug_init_device(sc); + + /* + * Mark the device as detached to avoid processing + * interrupts until setup is complete. + */ + __set_bit(ATH_STAT_INVALID, sc->status); + + sc->iobase = mem; /* So we can unmap it on detach */ + sc->opmode = NL80211_IFTYPE_STATION; + sc->bintval = 1000; + mutex_init(&sc->lock); + spin_lock_init(&sc->rxbuflock); + spin_lock_init(&sc->txbuflock); + spin_lock_init(&sc->block); + + /* Set private data */ + pci_set_drvdata(pdev, sc); + + /* Setup interrupt handler */ + ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); + if (ret) { + ATH5K_ERR(sc, "request_irq failed\n"); + goto err_free; + } + + /* If we passed the test, malloc an ath5k_hw struct */ + sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); + if (!sc->ah) { + ret = -ENOMEM; + ATH5K_ERR(sc, "out of memory\n"); + goto err_irq; + } + + sc->ah->ah_sc = sc; + sc->ah->ah_iobase = sc->iobase; + common = ath5k_hw_common(sc->ah); + common->ops = &ath5k_common_ops; + common->ah = sc->ah; + common->hw = hw; + common->cachelsz = csz << 2; /* convert to bytes */ + + /* Initialize device */ + ret = ath5k_hw_attach(sc); + if (ret) { + goto err_free_ah; + } + + /* set up multi-rate retry capabilities */ + if (sc->ah->ah_version == AR5K_AR5212) { + hw->max_rates = 4; + hw->max_rate_tries = 11; + } + + /* Finish private driver data initialization */ + ret = ath5k_attach(pdev, hw); + if (ret) + goto err_ah; + + ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", + ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), + sc->ah->ah_mac_srev, + sc->ah->ah_phy_revision); + + if (!sc->ah->ah_single_chip) { + /* Single chip radio (!RF5111) */ + if (sc->ah->ah_radio_5ghz_revision && + !sc->ah->ah_radio_2ghz_revision) { + /* No 5GHz support -> report 2GHz radio */ + if (!test_bit(AR5K_MODE_11A, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* No 2GHz support (5110 and some + * 5Ghz only cards) -> report 5Ghz radio */ + } else if (!test_bit(AR5K_MODE_11B, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* Multiband radio */ + } else { + ATH5K_INFO(sc, "RF%s multiband radio found" + " (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + } + } + /* Multi chip radio (RF5111 - RF2111) -> + * report both 2GHz/5GHz radios */ + else if (sc->ah->ah_radio_5ghz_revision && + sc->ah->ah_radio_2ghz_revision){ + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_2ghz_revision), + sc->ah->ah_radio_2ghz_revision); + } + } + - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = sc->ah->ah_noise_floor; + /* ready to process interrupts */ + __clear_bit(ATH_STAT_INVALID, sc->status); return 0; +err_ah: + ath5k_hw_detach(sc->ah); +err_free_ah: + kfree(sc->ah); +err_irq: + free_irq(pdev->irq, sc); +err_free: + ieee80211_free_hw(hw); +err_map: + pci_iounmap(pdev, mem); +err_reg: + pci_release_region(pdev, 0); +err_dis: + pci_disable_device(pdev); +err: + return ret; } -static u64 -ath5k_get_tsf(struct ieee80211_hw *hw) +static void __devexit +ath5k_pci_remove(struct pci_dev *pdev) { - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = pci_get_drvdata(pdev); - return ath5k_hw_get_tsf64(sc->ah); + ath5k_debug_finish_device(sc); + ath5k_detach(pdev, sc->hw); + ath5k_hw_detach(sc->ah); + kfree(sc->ah); + free_irq(pdev->irq, sc); + pci_iounmap(pdev, sc->iobase); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + ieee80211_free_hw(sc->hw); } -static void -ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) +#ifdef CONFIG_PM_SLEEP +static int ath5k_pci_suspend(struct device *dev) { - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); - ath5k_hw_set_tsf64(sc->ah, tsf); + ath5k_led_off(sc); + return 0; } -static void -ath5k_reset_tsf(struct ieee80211_hw *hw) +static int ath5k_pci_resume(struct device *dev) { - struct ath5k_softc *sc = hw->priv; + struct pci_dev *pdev = to_pci_dev(dev); + struct ath5k_softc *sc = pci_get_drvdata(pdev); /* - * in IBSS mode we need to update the beacon timers too. - * this will also reset the TSF if we call it with 0 + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ - if (sc->opmode == NL80211_IFTYPE_ADHOC) - ath5k_beacon_update_timers(sc, 0); - else - ath5k_hw_reset_tsf(sc->ah); + pci_write_config_byte(pdev, 0x41, 0); + + ath5k_led_enable(sc); + return 0; } +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); +#define ATH5K_PM_OPS (&ath5k_pm_ops) +#else +#define ATH5K_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver ath5k_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = ath5k_pci_id_table, + .probe = ath5k_pci_probe, + .remove = __devexit_p(ath5k_pci_remove), + .driver.pm = ATH5K_PM_OPS, +}; + /* - * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, - * this is called only once at config_bss time, for AP we do it every - * SWBA interrupt so that the TIM will reflect buffered frames. - * - * Called with the beacon lock. + * Module init/exit functions */ -static int -ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +static int __init +init_ath5k_pci(void) { int ret; - struct ath5k_softc *sc = hw->priv; - struct sk_buff *skb; - - if (WARN_ON(!vif)) { - ret = -EINVAL; - goto out; - } - - skb = ieee80211_beacon_get(hw, vif); - - if (!skb) { - ret = -ENOMEM; - goto out; - } - - ath5k_debug_dump_skb(sc, skb, "BC ", 1); - - ath5k_txbuf_free_skb(sc, sc->bbuf); - sc->bbuf->skb = skb; - ret = ath5k_beacon_setup(sc, sc->bbuf); - if (ret) - sc->bbuf->skb = NULL; -out: - return ret; -} - -static void -set_beacon_filter(struct ieee80211_hw *hw, bool enable) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - u32 rfilt; - rfilt = ath5k_hw_get_rx_filter(ah); - if (enable) - rfilt |= AR5K_RX_FILTER_BEACON; - else - rfilt &= ~AR5K_RX_FILTER_BEACON; - ath5k_hw_set_rx_filter(ah, rfilt); - sc->filter_flags = rfilt; -} - -static void ath5k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; - - mutex_lock(&sc->lock); - if (WARN_ON(sc->vif != vif)) - goto unlock; - - if (changes & BSS_CHANGED_BSSID) { - /* Cache for later use during resets */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = 0; - ath5k_hw_set_bssid(ah); - mmiowb(); - } - - if (changes & BSS_CHANGED_BEACON_INT) - sc->bintval = bss_conf->beacon_int; - if (changes & BSS_CHANGED_ASSOC) { - sc->assoc = bss_conf->assoc; - if (sc->opmode == NL80211_IFTYPE_STATION) - set_beacon_filter(hw, sc->assoc); - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); - if (bss_conf->assoc) { - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); - common->curaid = bss_conf->aid; - ath5k_hw_set_bssid(ah); - /* Once ANI is available you would start it here */ - } - } + ath5k_debug_init(); - if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&sc->block, flags); - ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&sc->block, flags); + ret = pci_register_driver(&ath5k_pci_driver); + if (ret) { + printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); + return ret; } - if (changes & BSS_CHANGED_BEACON_ENABLED) - sc->enable_beacon = bss_conf->enable_beacon; - - if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON_INT)) - ath5k_beacon_config(sc); - - unlock: - mutex_unlock(&sc->lock); + return 0; } -static void ath5k_sw_scan_start(struct ieee80211_hw *hw) +static void __exit +exit_ath5k_pci(void) { - struct ath5k_softc *sc = hw->priv; - if (!sc->assoc) - ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); -} + pci_unregister_driver(&ath5k_pci_driver); -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); + ath5k_debug_finish(); } -/** - * ath5k_set_coverage_class - Set IEEE 802.11 coverage class - * - * @hw: struct ieee80211_hw pointer - * @coverage_class: IEEE 802.11 coverage class number - * - * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given - * coverage class. The values are persistent, they are restored after device - * reset. - */ -static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) -{ - struct ath5k_softc *sc = hw->priv; - - mutex_lock(&sc->lock); - ath5k_hw_set_coverage_class(sc->ah, coverage_class); - mutex_unlock(&sc->lock); -} +module_init(init_ath5k_pci); +module_exit(exit_ath5k_pci); -- cgit v1.2.3 From 925e0b061300c94912be36eac16f0b44249a1add Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:35 +0900 Subject: ath5k: Use four hardware queues Prepare ath5k for WME by using four hardware queues. The way we set up our queues matches the mac80211 queue priority 1:1, so we don't have to do any mapping for queue numbers. Every queue uses 50 of the total 200 available transmit buffers, so the DMA memory usage does not increase with this patch, but it might be good to fine-tune the number of buffers per queue later (depending on the CPU speed and load, and the speed of the medium access, it might not be big enough). Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 47 ++++++++++++++++++++++++++++++----- drivers/net/wireless/ath/ath5k/base.h | 5 +++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4a07fb89021e..776f415e8567 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -733,6 +733,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, spin_lock_bh(&txq->lock); list_add_tail(&bf->list, &txq->q); + txq->txq_len++; if (txq->link == NULL) /* is this first packet? */ ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); else /* no, so only link it */ @@ -889,6 +890,7 @@ ath5k_txq_setup(struct ath5k_softc *sc, INIT_LIST_HEAD(&txq->q); spin_lock_init(&txq->lock); txq->setup = true; + txq->txq_len = 0; } return &sc->txqs[qnum]; } @@ -983,6 +985,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) spin_lock_bh(&sc->txbuflock); list_move_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; + txq->txq_len--; spin_unlock_bh(&sc->txbuflock); } txq->link = NULL; @@ -1479,6 +1482,9 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, goto drop_packet; } + if (txq->txq_len >= ATH5K_TXQ_LEN_MAX) + ieee80211_stop_queue(hw, txq->qnum); + spin_lock_irqsave(&sc->txbuflock, flags); if (list_empty(&sc->txbuf)) { ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); @@ -1601,13 +1607,14 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) spin_lock(&sc->txbuflock); list_move_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; + txq->txq_len--; spin_unlock(&sc->txbuflock); } if (likely(list_empty(&txq->q))) txq->link = NULL; spin_unlock(&txq->lock); - if (sc->txbuf_len > ATH_TXBUF / 5) - ieee80211_wake_queues(sc->hw); + if (txq->txq_len < ATH5K_TXQ_LEN_LOW) + ieee80211_wake_queue(sc->hw, txq->qnum); } static void @@ -2391,6 +2398,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); + struct ath5k_txq *txq; u8 mac[ETH_ALEN] = {}; int ret; @@ -2456,12 +2464,33 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) goto err_bhal; } - sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); - if (IS_ERR(sc->txq)) { + /* This order matches mac80211's queue priority, so we can + * directly use the mac80211 queue number without any mapping */ + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); + if (IS_ERR(txq)) { ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(sc->txq); + ret = PTR_ERR(txq); goto err_queues; } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + hw->queues = 4; tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); @@ -2554,8 +2583,14 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath5k_softc *sc = hw->priv; + u16 qnum = skb_get_queue_mapping(skb); + + if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { + dev_kfree_skb_any(skb); + return 0; + } - return ath5k_tx_queue(hw, skb, sc->txq); + return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); } static int ath5k_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index dc1241f9c4e8..5e2366d3db09 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -60,6 +60,9 @@ #define ATH_TXBUF 200 /* number of TX buffers */ #define ATH_BCBUF 1 /* number of beacon buffers */ +#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ +#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ + struct ath5k_buf { struct list_head list; struct ath5k_desc *desc; /* virtual addr of desc */ @@ -83,6 +86,7 @@ struct ath5k_txq { struct list_head q; /* transmit queue */ spinlock_t lock; /* lock on q and link */ bool setup; + int txq_len; /* number of queued buffers */ }; #define ATH5K_LED_MAX_NAME_LEN 31 @@ -204,7 +208,6 @@ struct ath5k_softc { spinlock_t txbuflock; unsigned int txbuf_len; /* buf count in txbuf list */ struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ - struct ath5k_txq *txq; /* main tx queue */ struct tasklet_struct txtq; /* tx intr tasklet */ struct ath5k_led tx_led; /* tx led */ -- cgit v1.2.3 From cfddc11c429a655e418ffc111372cc69dee6a1a5 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:40 +0900 Subject: ath5k: Fix queue debug file Take txq lock in debug file and fix reporting of used buffers. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 1b7c6d7fde93..b2c610ba8b7e 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -763,7 +763,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, struct ath5k_txq *txq; struct ath5k_buf *bf, *bf0; - int i, n = 0; + int i, n; len += snprintf(buf+len, sizeof(buf)-len, "available txbuffers: %d\n", sc->txbuf_len); @@ -777,9 +777,14 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, if (!txq->setup) continue; + n = 0; + spin_lock_bh(&txq->lock); list_for_each_entry_safe(bf, bf0, &txq->q, list) n++; - len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); + spin_unlock_bh(&txq->lock); + + len += snprintf(buf+len, sizeof(buf)-len, + " len: %d bufs: %d\n", txq->txq_len, n); } if (len > sizeof(buf)) -- cgit v1.2.3 From 651d9375dca9997ef2b05639191756da73b0cf8d Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:46 +0900 Subject: ath5k: Fix TX queues stopping It does not make sense to stop queues for NF calibration. This will not stop transmissions from the card, if there are queued packets. If we run out of TX buffers we need to stop all queues, not only one. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 776f415e8567..92d139bbcc31 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1489,7 +1489,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, if (list_empty(&sc->txbuf)) { ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); spin_unlock_irqrestore(&sc->txbuflock, flags); - ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); + ieee80211_stop_queues(hw); goto drop_packet; } bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); @@ -2138,14 +2138,13 @@ ath5k_tasklet_calibrate(unsigned long data) sc->curchan->center_freq)); /* Noise floor calibration interrupts rx/tx path while I/Q calibration - * doesn't. We stop the queues so that calibration doesn't interfere - * with TX and don't run it as often */ + * doesn't. + * TODO: We should stop TX here, so that it doesn't interfere. + * Note that stopping the queues is not enough to stop TX! */ if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { ah->ah_cal_next_nf = jiffies + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); - ieee80211_stop_queues(sc->hw); ath5k_hw_update_noise_floor(ah); - ieee80211_wake_queues(sc->hw); } ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; -- cgit v1.2.3 From 1440401e7051d4cf66084a7c36125834901bb90d Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:51 +0900 Subject: ath5k: Move tx frame completion into separate function Clearer separation between queue handling and what we do with completed frames. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 107 ++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 92d139bbcc31..81f4b567c6f2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1516,6 +1516,61 @@ drop_packet: return NETDEV_TX_OK; } +static void +ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_tx_status *ts) +{ + struct ieee80211_tx_info *info; + int i; + + sc->stats.tx_all_count++; + info = IEEE80211_SKB_CB(skb); + + ieee80211_tx_info_clear_status(info); + for (i = 0; i < 4; i++) { + struct ieee80211_tx_rate *r = + &info->status.rates[i]; + + if (ts->ts_rate[i]) { + r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); + r->count = ts->ts_retry[i]; + } else { + r->idx = -1; + r->count = 0; + } + } + + /* count the successful attempt as well */ + info->status.rates[ts->ts_final_idx].count++; + + if (unlikely(ts->ts_status)) { + sc->stats.ack_fail++; + if (ts->ts_status & AR5K_TXERR_FILT) { + info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + sc->stats.txerr_filt++; + } + if (ts->ts_status & AR5K_TXERR_XRETRY) + sc->stats.txerr_retry++; + if (ts->ts_status & AR5K_TXERR_FIFO) + sc->stats.txerr_fifo++; + } else { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ts_rssi; + } + + /* + * Remove MAC header padding before giving the frame + * back to mac80211. + */ + ath5k_remove_padding(skb); + + if (ts->ts_antenna > 0 && ts->ts_antenna < 5) + sc->stats.antenna_tx[ts->ts_antenna]++; + else + sc->stats.antenna_tx[0]++; /* invalid */ + + ieee80211_tx_status(sc->hw, skb); +} static void ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) @@ -1524,8 +1579,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) struct ath5k_buf *bf, *bf0; struct ath5k_desc *ds; struct sk_buff *skb; - struct ieee80211_tx_info *info; - int i, ret; + int ret; spin_lock(&txq->lock); list_for_each_entry_safe(bf, bf0, &txq->q, list) { @@ -1541,7 +1595,6 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && !list_is_last(&bf->list, &txq->q)) break; - ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); if (unlikely(ret == -EINPROGRESS)) break; @@ -1551,58 +1604,12 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) break; } - sc->stats.tx_all_count++; skb = bf->skb; - info = IEEE80211_SKB_CB(skb); bf->skb = NULL; - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); - ieee80211_tx_info_clear_status(info); - for (i = 0; i < 4; i++) { - struct ieee80211_tx_rate *r = - &info->status.rates[i]; - - if (ts.ts_rate[i]) { - r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); - r->count = ts.ts_retry[i]; - } else { - r->idx = -1; - r->count = 0; - } - } - - /* count the successful attempt as well */ - info->status.rates[ts.ts_final_idx].count++; - - if (unlikely(ts.ts_status)) { - sc->stats.ack_fail++; - if (ts.ts_status & AR5K_TXERR_FILT) { - info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - sc->stats.txerr_filt++; - } - if (ts.ts_status & AR5K_TXERR_XRETRY) - sc->stats.txerr_retry++; - if (ts.ts_status & AR5K_TXERR_FIFO) - sc->stats.txerr_fifo++; - } else { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts.ts_rssi; - } - - /* - * Remove MAC header padding before giving the frame - * back to mac80211. - */ - ath5k_remove_padding(skb); - - if (ts.ts_antenna > 0 && ts.ts_antenna < 5) - sc->stats.antenna_tx[ts.ts_antenna]++; - else - sc->stats.antenna_tx[0]++; /* invalid */ - - ieee80211_tx_status(sc->hw, skb); + ath5k_tx_frame_completed(sc, skb, &ts); spin_lock(&sc->txbuflock); list_move_tail(&bf->list, &sc->txbuf); -- cgit v1.2.3 From 4edd761f4075b03be5932682a2f7b9368dc9e536 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:36:56 +0900 Subject: ath5k: Add watchdog for stuck TX queues Since we do not know any better solution to the problem that TX queues can get stuck, this adds a timer-based watchdog, which will check for stuck queues and reset the hardware if necessary. Ported from ath9k commit 164ace38536849966ffa377b1b1132993a5a375d. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++ drivers/net/wireless/ath/ath5k/base.c | 51 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath5k/base.h | 3 ++ 3 files changed, 56 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 50209aed0ed2..9475b2157f2d 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -206,6 +206,8 @@ #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ #define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ +#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */ + #define AR5K_INIT_CARR_SENSE_EN 1 /*Swap RX/TX Descriptor for big endian archs*/ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 81f4b567c6f2..afedfeba13dd 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -891,6 +891,7 @@ ath5k_txq_setup(struct ath5k_softc *sc, spin_lock_init(&txq->lock); txq->setup = true; txq->txq_len = 0; + txq->txq_poll_mark = false; } return &sc->txqs[qnum]; } @@ -989,6 +990,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) spin_unlock_bh(&sc->txbuflock); } txq->link = NULL; + txq->txq_poll_mark = false; spin_unlock_bh(&txq->lock); } @@ -1616,6 +1618,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) sc->txbuf_len++; txq->txq_len--; spin_unlock(&sc->txbuflock); + + txq->txq_poll_mark = false; } if (likely(list_empty(&txq->q))) txq->link = NULL; @@ -2170,6 +2174,46 @@ ath5k_tasklet_ani(unsigned long data) } +static void +ath5k_tx_complete_poll_work(struct work_struct *work) +{ + struct ath5k_softc *sc = container_of(work, struct ath5k_softc, + tx_complete_work.work); + struct ath5k_txq *txq; + int i; + bool needreset = false; + + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { + if (sc->txqs[i].setup) { + txq = &sc->txqs[i]; + spin_lock_bh(&txq->lock); + if (txq->txq_len > 0) { + if (txq->txq_poll_mark) { + ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, + "TX queue stuck %d\n", + txq->qnum); + needreset = true; + spin_unlock_bh(&txq->lock); + break; + } else { + txq->txq_poll_mark = true; + } + } + spin_unlock_bh(&txq->lock); + } + } + + if (needreset) { + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "TX queues stuck, resetting\n"); + ath5k_reset(sc, sc->curchan); + } + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, + msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); +} + + /*************************\ * Initialization routines * \*************************/ @@ -2261,6 +2305,10 @@ ath5k_init(struct ath5k_softc *sc) done: mmiowb(); mutex_unlock(&sc->lock); + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, + msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); + return ret; } @@ -2319,6 +2367,8 @@ ath5k_stop_hw(struct ath5k_softc *sc) stop_tasklets(sc); + cancel_delayed_work_sync(&sc->tx_complete_work); + ath5k_rfkill_hw_stop(sc->ah); return ret; @@ -2505,6 +2555,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); INIT_WORK(&sc->reset_work, ath5k_reset_work); + INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 5e2366d3db09..d8e2674aec71 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -87,6 +87,7 @@ struct ath5k_txq { spinlock_t lock; /* lock on q and link */ bool setup; int txq_len; /* number of queued buffers */ + bool txq_poll_mark; }; #define ATH5K_LED_MAX_NAME_LEN 31 @@ -233,6 +234,8 @@ struct ath5k_softc { struct ath5k_ani_state ani_state; struct tasklet_struct ani_tasklet; /* ANI calibration */ + + struct delayed_work tx_complete_work; }; #define ath5k_hw_hasbssidmask(_ah) \ -- cgit v1.2.3 From 923e5b3d3d773b9956b943ac64f782d5a127bdea Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:37:02 +0900 Subject: ath5k: Count how many times a queue got stuck Add a counter to show how many times a queue got stuck in the debugfs queue file. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 ++ drivers/net/wireless/ath/ath5k/base.h | 1 + drivers/net/wireless/ath/ath5k/debug.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index afedfeba13dd..cae9fe4676e7 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -892,6 +892,7 @@ ath5k_txq_setup(struct ath5k_softc *sc, txq->setup = true; txq->txq_len = 0; txq->txq_poll_mark = false; + txq->txq_stuck = 0; } return &sc->txqs[qnum]; } @@ -2193,6 +2194,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work) "TX queue stuck %d\n", txq->qnum); needreset = true; + txq->txq_stuck++; spin_unlock_bh(&txq->lock); break; } else { diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index d8e2674aec71..7f9d0d3018e8 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -88,6 +88,7 @@ struct ath5k_txq { bool setup; int txq_len; /* number of queued buffers */ bool txq_poll_mark; + unsigned int txq_stuck; /* informational counter */ }; #define ATH5K_LED_MAX_NAME_LEN 31 diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index b2c610ba8b7e..6583a82a0783 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -785,6 +785,8 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, " len: %d bufs: %d\n", txq->txq_len, n); + len += snprintf(buf+len, sizeof(buf)-len, + " stuck: %d\n", txq->txq_stuck); } if (len > sizeof(buf)) -- cgit v1.2.3 From 234132960dcf8ebd9d424d92a4dfb0e57fa63a17 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:37:07 +0900 Subject: ath5k: Keep last descriptor in queue If we return a TX descriptor to the pool of available descriptors, while a queues TXDP still points to it we could potentially run into all sorts of troube. It has been suggested that there is hardware which can set the descriptors done bit before it reads ds_link and moves on to the next descriptor. While the documentation says this is not true for newer chipsets (the descriptor contents are copied to some internal memory), we don't know about older hardware. To be safe, we always keep the last descriptor in the queue, and avoid dangling TXDP pointers. Unfortunately this does not fully resolve the problem - queues still get stuck! This is similar to what ath9k does. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 64 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cae9fe4676e7..3e5ed6c0c808 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1586,44 +1586,44 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) spin_lock(&txq->lock); list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ds = bf->desc; + + txq->txq_poll_mark = false; + + /* skb might already have been processed last time. */ + if (bf->skb != NULL) { + ds = bf->desc; + + ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); + if (unlikely(ret == -EINPROGRESS)) + break; + else if (unlikely(ret)) { + ATH5K_ERR(sc, + "error %d while processing " + "queue %u\n", ret, txq->qnum); + break; + } + + skb = bf->skb; + bf->skb = NULL; + pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, + PCI_DMA_TODEVICE); + ath5k_tx_frame_completed(sc, skb, &ts); + } /* * It's possible that the hardware can say the buffer is * completed when it hasn't yet loaded the ds_link from - * host memory and moved on. If there are more TX - * descriptors in the queue, wait for TXDP to change - * before processing this one. + * host memory and moved on. + * Always keep the last descriptor to avoid HW races... */ - if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && - !list_is_last(&bf->list, &txq->q)) - break; - ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(sc, "error %d while processing queue %u\n", - ret, txq->qnum); - break; + if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) { + spin_lock(&sc->txbuflock); + list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + txq->txq_len--; + spin_unlock(&sc->txbuflock); } - - skb = bf->skb; - bf->skb = NULL; - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, - PCI_DMA_TODEVICE); - - ath5k_tx_frame_completed(sc, skb, &ts); - - spin_lock(&sc->txbuflock); - list_move_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - txq->txq_len--; - spin_unlock(&sc->txbuflock); - - txq->txq_poll_mark = false; } - if (likely(list_empty(&txq->q))) - txq->link = NULL; spin_unlock(&txq->lock); if (txq->txq_len < ATH5K_TXQ_LEN_LOW) ieee80211_wake_queue(sc->hw, txq->qnum); @@ -2188,7 +2188,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work) if (sc->txqs[i].setup) { txq = &sc->txqs[i]; spin_lock_bh(&txq->lock); - if (txq->txq_len > 0) { + if (txq->txq_len > 1) { if (txq->txq_poll_mark) { ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "TX queue stuck %d\n", -- cgit v1.2.3 From de8af45520f47d14397b603beefae3d2983ce787 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:37:12 +0900 Subject: ath5k: Simplify cw_min/max and AIFS configuration Get rid of overly complicated cw_min/max and AIFS configuration: * Validate values in ath5k_hw_set_tx_queueprops(), so we can use them directly without further checks or computation in ath5k_hw_reset_tx_queue(). * Simplifiy by using AR5K_TUNE_AIFS|CWMIN|CWMAX variables directly since we don't support XR or B channels. That way we can also remove AR5K_TXQ_USEDEFAULT and the confusing logic around it. * Update data types: AIFS is u8, CW's are u16. * Remove now unneeded variables in ath5k_hw. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 11 +--- drivers/net/wireless/ath/ath5k/attach.c | 2 - drivers/net/wireless/ath/ath5k/base.c | 18 +++--- drivers/net/wireless/ath/ath5k/qcu.c | 99 +++++++++++++++++---------------- 4 files changed, 65 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 9475b2157f2d..b96bb985b56d 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -258,8 +258,6 @@ (AR5K_INIT_PROG_IFS_TURBO) \ ) -/* token to use for aifs, cwmin, cwmax in MadWiFi */ -#define AR5K_TXQ_USEDEFAULT ((u32) -1) /* GENERIC CHIPSET DEFINITIONS */ @@ -530,9 +528,9 @@ struct ath5k_txq_info { enum ath5k_tx_queue tqi_type; enum ath5k_tx_queue_subtype tqi_subtype; u16 tqi_flags; /* Tx queue flags (see above) */ - u32 tqi_aifs; /* Arbitrated Interframe Space */ - s32 tqi_cw_min; /* Minimum Contention Window */ - s32 tqi_cw_max; /* Maximum Contention Window */ + u8 tqi_aifs; /* Arbitrated Interframe Space */ + u16 tqi_cw_min; /* Minimum Contention Window */ + u16 tqi_cw_max; /* Maximum Contention Window */ u32 tqi_cbr_period; /* Constant bit rate period */ u32 tqi_cbr_overflow_limit; u32 tqi_burst_time; @@ -1044,9 +1042,6 @@ struct ath5k_hw { #define ah_ee_version ah_capabilities.cap_eeprom.ee_version u32 ah_atim_window; - u32 ah_aifs; - u32 ah_cw_min; - u32 ah_cw_max; u32 ah_limit_tx_retries; u8 ah_coverage_class; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 20d178eabc9c..6e02de311cdd 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -119,8 +119,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_imr = 0; ah->ah_atim_window = 0; - ah->ah_aifs = AR5K_TUNE_AIFS; - ah->ah_cw_min = AR5K_TUNE_CWMIN; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; ah->ah_software_retry = false; ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3e5ed6c0c808..6bd8dd6f327b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -849,9 +849,11 @@ ath5k_txq_setup(struct ath5k_softc *sc, struct ath5k_txq *txq; struct ath5k_txq_info qi = { .tqi_subtype = subtype, - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT + /* XXX: default values not correct for B and XR channels, + * but who cares? */ + .tqi_aifs = AR5K_TUNE_AIFS, + .tqi_cw_min = AR5K_TUNE_CWMIN, + .tqi_cw_max = AR5K_TUNE_CWMAX }; int qnum; @@ -901,9 +903,11 @@ static int ath5k_beaconq_setup(struct ath5k_hw *ah) { struct ath5k_txq_info qi = { - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT, + /* XXX: default values not correct for B and XR channels, + * but who cares? */ + .tqi_aifs = AR5K_TUNE_AIFS, + .tqi_cw_min = AR5K_TUNE_CWMIN, + .tqi_cw_max = AR5K_TUNE_CWMAX, /* NB: for dynamic turbo, don't enable any other interrupts */ .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE }; @@ -937,7 +941,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) */ qi.tqi_aifs = 0; qi.tqi_cw_min = 0; - qi.tqi_cw_max = 2 * ah->ah_cw_min; + qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN; } ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 4186ff4c6e9c..84c717ded1c5 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -35,25 +35,59 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, return 0; } +/* + * Make sure cw is a power of 2 minus 1 and smaller than 1024 + */ +static u16 ath5k_cw_validate(u16 cw_req) +{ + u32 cw = 1; + cw_req = min(cw_req, (u16)1023); + + while (cw < cw_req) + cw = (cw << 1) | 1; + + return cw; +} + /* * Set properties for a transmit queue */ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, - const struct ath5k_txq_info *queue_info) + const struct ath5k_txq_info *qinfo) { + struct ath5k_txq_info *qi; + AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) + qi = &ah->ah_txq[queue]; + + if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE) return -EIO; - memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); + /* copy and validate values */ + qi->tqi_type = qinfo->tqi_type; + qi->tqi_subtype = qinfo->tqi_subtype; + qi->tqi_flags = qinfo->tqi_flags; + /* + * According to the docs: Although the AIFS field is 8 bit wide, + * the maximum supported value is 0xFC. Setting it higher than that + * will cause the DCU to hang. + */ + qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC); + qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min); + qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max); + qi->tqi_cbr_period = qinfo->tqi_cbr_period; + qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit; + qi->tqi_burst_time = qinfo->tqi_burst_time; + qi->tqi_ready_time = qinfo->tqi_ready_time; /*XXX: Is this supported on 5210 ?*/ - if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && - ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || - (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || - queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) - ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; + /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/ + if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA && + ((qinfo->tqi_subtype == AR5K_WME_AC_VI) || + (qinfo->tqi_subtype == AR5K_WME_AC_VO))) || + qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD) + qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; return 0; } @@ -186,7 +220,7 @@ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) */ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) { - u32 cw_min, cw_max, retry_lg, retry_sh; + u32 retry_lg, retry_sh; struct ath5k_txq_info *tq = &ah->ah_txq[queue]; AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); @@ -217,14 +251,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* Set IFS0 */ if (ah->ah_turbo) { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + - (ah->ah_aifs + tq->tqi_aifs) * - AR5K_INIT_SLOT_TIME_TURBO) << + tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) << AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, AR5K_IFS0); } else { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + - (ah->ah_aifs + tq->tqi_aifs) * - AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | + tq->tqi_aifs * AR5K_INIT_SLOT_TIME) << + AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS, AR5K_IFS0); } @@ -247,35 +280,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) AR5K_PHY_FRAME_CTL_5210); } - /* - * Calculate cwmin/max by channel mode - */ - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; - ah->ah_aifs = AR5K_TUNE_AIFS; - /*XR is only supported on 5212*/ - if (IS_CHAN_XR(ah->ah_current_channel) && - ah->ah_version == AR5K_AR5212) { - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; - ah->ah_aifs = AR5K_TUNE_AIFS_XR; - /*B mode is not supported on 5210*/ - } else if (IS_CHAN_B(ah->ah_current_channel) && - ah->ah_version != AR5K_AR5210) { - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; - ah->ah_aifs = AR5K_TUNE_AIFS_11B; - } - - cw_min = 1; - while (cw_min < ah->ah_cw_min) - cw_min = (cw_min << 1) | 1; - - cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : - ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); - cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : - ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); - /* * Calculate and set retry limits */ @@ -292,7 +296,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /*No QCU/DCU [5210]*/ if (ah->ah_version == AR5K_AR5210) { ath5k_hw_reg_write(ah, - (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) + (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_NODCU_RETRY_LMT_SLG_RETRY) | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, @@ -314,14 +318,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /*===Rest is also for QCU/DCU only [5211+]===*/ /* - * Set initial content window (cw_min/cw_max) + * Set contention window (cw_min/cw_max) * and arbitrated interframe space (aifs)... */ ath5k_hw_reg_write(ah, - AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | - AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | - AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, - AR5K_DCU_LCL_IFS_AIFS), + AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | + AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | + AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), AR5K_QUEUE_DFS_LOCAL_IFS(queue)); /* -- cgit v1.2.3 From e0b1cc52e5da3e2fa79666b8df81a953c95c91e4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 17 Sep 2010 11:37:18 +0900 Subject: ath5k: Add tx queue configuration function Add the mac80211 callback function to configure the tx queue properties like cw_min, cw_max and aifs. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 6bd8dd6f327b..504c6d648ecf 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3140,6 +3140,44 @@ static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_unlock(&sc->lock); } +static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath5k_txq_info qi; + int ret = 0; + + if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) + return 0; + + mutex_lock(&sc->lock); + + ath5k_hw_get_tx_queueprops(ah, queue, &qi); + + qi.tqi_aifs = params->aifs; + qi.tqi_cw_min = params->cw_min; + qi.tqi_cw_max = params->cw_max; + qi.tqi_burst_time = params->txop; + + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Configure tx [queue %d], " + "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + queue, params->aifs, params->cw_min, + params->cw_max, params->txop); + + if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { + ATH5K_ERR(sc, + "Unable to update hardware queue %u!\n", queue); + ret = -EIO; + } else + ath5k_hw_reset_tx_queue(ah, queue); + + mutex_unlock(&sc->lock); + + return ret; +} + static const struct ieee80211_ops ath5k_hw_ops = { .tx = ath5k_tx, .start = ath5k_start, @@ -3152,7 +3190,7 @@ static const struct ieee80211_ops ath5k_hw_ops = { .set_key = ath5k_set_key, .get_stats = ath5k_get_stats, .get_survey = ath5k_get_survey, - .conf_tx = NULL, + .conf_tx = ath5k_conf_tx, .get_tsf = ath5k_get_tsf, .set_tsf = ath5k_set_tsf, .reset_tsf = ath5k_reset_tsf, -- cgit v1.2.3 From 9dec6f9c48242eec742c9475f32eeef29448701c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 22:07:59 +0200 Subject: carl9170: use rx chainmask from eeprom The eeprom provides a mask for all present rx chains. Why not use it instead of the generic initval default? Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 71dea9707e21..fe265e3e6ac4 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -532,8 +532,11 @@ static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val, xpd2pd[m->xpdGain & 0xf] >> 2); carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val); - carl9170_regwrite_finish(); + carl9170_regwrite(AR9170_PHY_REG_RX_CHAINMASK, ar->eeprom.rx_mask); + carl9170_regwrite(AR9170_PHY_REG_CAL_CHAINMASK, ar->eeprom.rx_mask); + + carl9170_regwrite_finish(); return carl9170_regwrite_result(); } -- cgit v1.2.3 From e278c5a90368408bd191743e7c6f978f068f4b8d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 22:22:50 +0200 Subject: carl9170: fix noise dBm conversion Ever since carl9170 gained support to read the noisefloor, the reported noisefloor level was pretty poor. Initially I assumed that something was wrong in the PHY setup and it would be impossible to fix without any guidances. But this was not the case. In fact the nf readings were correct and the thing that was broken was the "simple" sign extension code! Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index fe265e3e6ac4..7df8f711f5d8 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1558,9 +1558,9 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, static int carl9170_calc_noise_dbm(u32 raw_noise) { if (raw_noise & 0x100) - return ~((raw_noise & 0x0ff) >> 1); + return ~0x1ff | raw_noise; else - return (raw_noise & 0xff) >> 1; + return raw_noise; } int carl9170_get_noisefloor(struct ar9170 *ar) -- cgit v1.2.3 From 9adc9e0ff397fb2d4f383cc2d399b18adc32e6eb Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 22:42:37 +0200 Subject: carl9170: don't load bogus nf of chain 1 According to Atheros, chain 1 is not connected. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 2 +- drivers/net/wireless/ath/carl9170/debug.c | 8 +++----- drivers/net/wireless/ath/carl9170/phy.c | 11 +++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 9f1d60359061..d43675aca0bb 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -321,7 +321,7 @@ struct ar9170 { /* PHY */ struct ieee80211_channel *channel; - int noise[6]; + int noise[4]; unsigned int chan_fail; unsigned int total_chan_fail; u8 heavy_clip; diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 3e9b0e8b2b8c..19b48369ffed 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c @@ -436,12 +436,10 @@ static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf, return buf; } - ADD(buf, *len, bufsize, "Chain 1: %10d dBm, ext. chan.:%10d dBm\n", - ar->noise[1], ar->noise[4]); + ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[0], ar->noise[2]); ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n", - ar->noise[2], ar->noise[5]); - ADD(buf, *len, bufsize, "Combined %10d dBm, ext. chan.:%10d dBm\n", - ar->noise[0], ar->noise[3]); + ar->noise[1], ar->noise[3]); return buf; } diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 7df8f711f5d8..fa349b86ea62 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1566,9 +1566,8 @@ static int carl9170_calc_noise_dbm(u32 raw_noise) int carl9170_get_noisefloor(struct ar9170 *ar) { static const u32 phy_regs[] = { - AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH1_CCA, - AR9170_PHY_REG_CH2_CCA, AR9170_PHY_REG_EXT_CCA, - AR9170_PHY_REG_CH1_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA }; + AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH2_CCA, + AR9170_PHY_REG_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA }; u32 phy_res[ARRAY_SIZE(phy_regs)]; int err, i; @@ -1578,12 +1577,12 @@ int carl9170_get_noisefloor(struct ar9170 *ar) if (err) return err; - for (i = 0; i < 3; i++) { + for (i = 0; i < 2; i++) { ar->noise[i] = carl9170_calc_noise_dbm( (phy_res[i] >> 19) & 0x1ff); - ar->noise[i + 3] = carl9170_calc_noise_dbm( - (phy_res[i + 3] >> 23) & 0x1ff); + ar->noise[i + 2] = carl9170_calc_noise_dbm( + (phy_res[i + 2] >> 23) & 0x1ff); } return 0; -- cgit v1.2.3 From cf6487d0d656994cc43851b8c2384741e220f7ac Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 22:47:28 +0200 Subject: carl9170: abort tasklet during usb reset This patch prevents the tasklet code from interfering while the firmware is down for an unscheduled maintenance. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index fde918d0120b..1e7c2748d85a 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -367,6 +367,9 @@ static void carl9170_usb_tasklet(unsigned long data) { struct ar9170 *ar = (struct ar9170 *) data; + if (!IS_INITIALIZED(ar)) + return; + carl9170_usb_rx_work(ar); /* -- cgit v1.2.3 From 78ec789bd397249a9bb412ca91bd360079e7b446 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 22:58:40 +0200 Subject: carl9170: fix state downgrade during reset Don't mark the device as completely dead just yet. If all goes to plan and carl9170_reboot succeeds then we can skip the expensive userspace-driven reinitialization anyway. And if it doesn't and carl9170_reboot fails, then carl9170_usb_cancel_urbs will do the necessary steps. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 1e7c2748d85a..eb789a9e4f15 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -846,8 +846,6 @@ int carl9170_usb_restart(struct ar9170 *ar) carl9170_usb_stop(ar); - carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); - if (err) goto err_out; -- cgit v1.2.3 From 735761108f435a30bbabb5254fc5a8e17b99f2a1 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Sep 2010 23:09:19 +0200 Subject: carl9170: reinit phy after HT settings have changed The driver has a set of different initvals for 20 MHz vs dynamic HT2040 operation. Because we can't change some of the registers "in-flight", the driver needs to perform a warm reset. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 + drivers/net/wireless/ath/carl9170/phy.c | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index d43675aca0bb..d7c5482d74ce 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -325,6 +325,7 @@ struct ar9170 { unsigned int chan_fail; unsigned int total_chan_fail; u8 heavy_clip; + u8 ht_settings; /* power calibration data */ u8 power_5G_leg[4]; diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index fa349b86ea62..89deca37a988 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1610,7 +1610,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, const struct carl9170_phy_freq_params *freqpar; struct carl9170_rf_init_result rf_res; struct carl9170_rf_init rf; - u32 cmd, tmp, offs = 0; + u32 cmd, tmp, offs = 0, new_ht = 0; int err; enum carl9170_bw bw; bool warm_reset; @@ -1618,12 +1618,19 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, bw = nl80211_to_carl(_bw); + if (conf_is_ht(&ar->hw->conf)) + new_ht |= CARL9170FW_PHY_HT_ENABLE; + + if (conf_is_ht40(&ar->hw->conf)) + new_ht |= CARL9170FW_PHY_HT_DYN2040; + /* may be NULL at first setup */ if (ar->channel) { old_channel = ar->channel; warm_reset = (old_channel->band != channel->band) || (old_channel->center_freq == - channel->center_freq); + channel->center_freq) || + (ar->ht_settings != new_ht); ar->channel = NULL; } else { @@ -1724,16 +1731,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, freqpar = carl9170_get_hw_dyn_params(channel, bw); - rf.ht_settings = 0; - if (conf_is_ht(&ar->hw->conf)) { - rf.ht_settings |= CARL9170FW_PHY_HT_ENABLE; - - if (conf_is_ht40(&ar->hw->conf)) { - rf.ht_settings |= CARL9170FW_PHY_HT_DYN2040; - SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, - rf.ht_settings, offs); - } - } + rf.ht_settings = new_ht; + if (conf_is_ht40(&ar->hw->conf)) + SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, rf.ht_settings, offs); rf.freq = cpu_to_le32(channel->center_freq * 1000); rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp); @@ -1805,5 +1805,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, ar->ps.off_override &= ~PS_OFF_5GHZ; ar->channel = channel; + ar->ht_settings = new_ht; return 0; } -- cgit v1.2.3 From 2c7808d9345b91bb19f6bfaebf7b9e0916b0859a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 18 Sep 2010 00:15:13 +0200 Subject: carl9170: fix hang in AP mode when HT STA does PSM This is a obvious bug, skb_queue_walk does not work if the iterator gets removed from the queue. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ea49d54ce03b..43de9dfa5820 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1412,7 +1412,7 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, { struct ar9170 *ar = hw->priv; struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; - struct sk_buff *skb; + struct sk_buff *skb, *tmp; struct sk_buff_head free; int i; @@ -1462,7 +1462,7 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, for (i = 0; i < ar->hw->queues; i++) { spin_lock_bh(&ar->tx_pending[i].lock); - skb_queue_walk(&ar->tx_pending[i], skb) { + skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { struct _carl9170_tx_superframe *super; struct ieee80211_hdr *hdr; -- cgit v1.2.3 From 58be4607d25f86962dee6cc6b30573f95303517e Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 19 Sep 2010 18:55:08 +0200 Subject: wl1271: avoid redundant memcpy of rx_status copy the rx_status directly to skb->cb (control buffer) instead of copying it to a local struct and then copying it again (for each rx packet) Signed-off-by: Eliad Peller Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_rx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 019aa79cd9df..94da5dd7723c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -76,7 +76,6 @@ static void wl1271_rx_status(struct wl1271 *wl, static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) { - struct ieee80211_rx_status rx_status; struct wl1271_rx_descriptor *desc; struct sk_buff *skb; u16 *fc; @@ -109,14 +108,13 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) beacon = 1; - wl1271_rx_status(wl, desc, &rx_status, beacon); + wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, beacon ? "beacon" : ""); skb_trim(skb, skb->len - desc->pad_len); - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); ieee80211_rx_ni(wl->hw, skb); } -- cgit v1.2.3 From 9ee82d541095cb64bf16a1f5d7573a8cddc125aa Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 19 Sep 2010 18:55:09 +0200 Subject: wl1271: bugfix: use bitwise-AND instead of logical-AND typo - while looking for specific bits we should do a bitwise-AND instead of logical-AND. Signed-off-by: Eliad Peller Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index af26150109e3..776cd7c41148 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1634,7 +1634,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (ret < 0) goto out; - if ((changed && BSS_CHANGED_BEACON_INT) && + if ((changed & BSS_CHANGED_BEACON_INT) && (wl->bss_type == BSS_TYPE_IBSS)) { wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", bss_conf->beacon_int); @@ -1643,7 +1643,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, do_join = true; } - if ((changed && BSS_CHANGED_BEACON) && + if ((changed & BSS_CHANGED_BEACON) && (wl->bss_type == BSS_TYPE_IBSS)) { struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); -- cgit v1.2.3 From 81ee13ba7ef8c9eaebe91ed06edb844ab6403d4e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Sep 2010 13:45:36 +0200 Subject: ath9k: clean up block ack window handling There's no reason to keep pointers to pending tx buffers around, if they're only used to keep track of which frames are still pending. Use a bitfield instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 98b57e6c614e..79217c3c92e5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -254,7 +254,7 @@ struct ath_atx_tid { struct list_head buf_q; struct ath_node *an; struct ath_atx_ac *ac; - struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; + unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)]; u16 seq_start; u16 seq_next; u16 baw_size; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 457f07692ac7..5323a4d9ebb8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -168,9 +168,9 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, index = ATH_BA_INDEX(tid->seq_start, seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - tid->tx_buf[cindex] = NULL; + __clear_bit(cindex, tid->tx_buf); - while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) { + while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) { INCR(tid->seq_start, IEEE80211_SEQ_MAX); INCR(tid->baw_head, ATH_TID_MAX_BUFS); } @@ -186,9 +186,7 @@ static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - - BUG_ON(tid->tx_buf[cindex] != NULL); - tid->tx_buf[cindex] = bf; + __set_bit(cindex, tid->tx_buf); if (index >= ((tid->baw_tail - tid->baw_head) & (ATH_TID_MAX_BUFS - 1))) { -- cgit v1.2.3 From 231c3a1f0630c07a584905507a1cb7b705a56ab7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Sep 2010 19:35:28 +0200 Subject: ath9k: fix an aggregation start related race condition A new aggregation session start can be issued by mac80211, even when the cleanup of the previous session has not completed yet. Since the data structure for the session is not recreated, this could corrupt the block ack window and lock up the aggregation session. Fix this by delaying the new session until the old one has been cleaned up. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- drivers/net/wireless/ath/ath9k/xmit.c | 10 ++++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 79217c3c92e5..004533d2ca5f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -346,8 +346,8 @@ void ath_tx_tasklet(struct ath_softc *sc); void ath_tx_edma_tasklet(struct ath_softc *sc); void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); -void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn); +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath9k_enable_ps(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5056733e6f66..8b327bcad695 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1970,8 +1970,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_START: ath9k_ps_wakeup(sc); - ath_tx_aggr_start(sc, sta, tid, ssn); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = ath_tx_aggr_start(sc, sta, tid, ssn); + if (!ret) + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_STOP: diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5323a4d9ebb8..d629bfbdfab4 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -783,17 +783,23 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, status != ATH_AGGR_BAW_CLOSED); } -void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn) +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn) { struct ath_atx_tid *txtid; struct ath_node *an; an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); + + if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) + return -EAGAIN; + txtid->state |= AGGR_ADDBA_PROGRESS; txtid->paused = true; *ssn = txtid->seq_start; + + return 0; } void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) -- cgit v1.2.3 From 90fa539ca3f07323da5a90f5c8f4e5cd952875e7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Sep 2010 13:45:38 +0200 Subject: ath9k: clean up / fix aggregation session flush The tid aggregation cleanup is a bit fragile, as it discards failed subframes in some places, and retransmits them in others. This could block the cleanup of an existing aggregation session, if a retransmission for a tid is issued, yet the tid is never scheduled again because of the cleanup state. Fix this by getting rid of as many subframes as possible, as early as possible, and immediately transmitting pending subframes as regular HT frames instead of waiting for the cleanup to complete. Drop all pending subframes while keeping track of the Block ACK window during aggregate tx completion to prevent sending out stale subframes, which could confuse the receiver side. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 63 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d629bfbdfab4..e53433e3e4cc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -61,6 +61,8 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok); static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, int nbad, int txok, bool update_rc); +static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, + int seqno); enum { MCS_HT20, @@ -143,18 +145,23 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; struct ath_buf *bf; struct list_head bf_head; - INIT_LIST_HEAD(&bf_head); + struct ath_tx_status ts; - WARN_ON(!tid->paused); + INIT_LIST_HEAD(&bf_head); + memset(&ts, 0, sizeof(ts)); spin_lock_bh(&txq->axq_lock); - tid->paused = false; while (!list_empty(&tid->buf_q)) { bf = list_first_entry(&tid->buf_q, struct ath_buf, list); - BUG_ON(bf_isretried(bf)); list_move_tail(&bf->list, &bf_head); - ath_tx_send_ht_normal(sc, txq, tid, &bf_head); + + if (bf_isretried(bf)) { + ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); + } else { + ath_tx_send_ht_normal(sc, txq, tid, &bf_head); + } } spin_unlock_bh(&txq->axq_lock); @@ -429,7 +436,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, list_move_tail(&bf->list, &bf_head); } - if (!txpending) { + if (!txpending || (tid->state & AGGR_CLEANUP)) { /* * complete the acked-ones/xretried ones; update * block-ack window @@ -508,15 +515,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, } if (tid->state & AGGR_CLEANUP) { + ath_tx_flush_tid(sc, tid); + if (tid->baw_head == tid->baw_tail) { tid->state &= ~AGGR_ADDBA_COMPLETE; tid->state &= ~AGGR_CLEANUP; - - /* send buffered frames as singles */ - ath_tx_flush_tid(sc, tid); } - rcu_read_unlock(); - return; } rcu_read_unlock(); @@ -807,12 +811,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; - struct ath_tx_status ts; - struct ath_buf *bf; - struct list_head bf_head; - - memset(&ts, 0, sizeof(ts)); - INIT_LIST_HEAD(&bf_head); if (txtid->state & AGGR_CLEANUP) return; @@ -822,31 +820,22 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) return; } - /* drop all software retried frames and mark this TID */ spin_lock_bh(&txq->axq_lock); txtid->paused = true; - while (!list_empty(&txtid->buf_q)) { - bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); - if (!bf_isretried(bf)) { - /* - * NB: it's based on the assumption that - * software retried frame will always stay - * at the head of software queue. - */ - break; - } - list_move_tail(&bf->list, &bf_head); - ath_tx_update_baw(sc, txtid, bf->bf_seqno); - ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); - } - spin_unlock_bh(&txq->axq_lock); - if (txtid->baw_head != txtid->baw_tail) { + /* + * If frames are still being transmitted for this TID, they will be + * cleaned up during tx completion. To prevent race conditions, this + * TID can only be reused after all in-progress subframes have been + * completed. + */ + if (txtid->baw_head != txtid->baw_tail) txtid->state |= AGGR_CLEANUP; - } else { + else txtid->state &= ~AGGR_ADDBA_COMPLETE; - ath_tx_flush_tid(sc, txtid); - } + spin_unlock_bh(&txq->axq_lock); + + ath_tx_flush_tid(sc, txtid); } void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) -- cgit v1.2.3 From 334b06029ed3f5e31d773527d54fb40e3ee571f9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Sep 2010 13:45:39 +0200 Subject: ath9k: move ath_tx_aggr_check() to the rate control module It is not used anywhere else and can be made static Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/rc.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath9k/xmit.c | 14 -------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 004533d2ca5f..9f8e542ef47e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -345,7 +345,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, void ath_tx_tasklet(struct ath_softc *sc); void ath_tx_edma_tasklet(struct ath_softc *sc); void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); -bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index e49be733d546..ce1cd6d85847 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1320,6 +1320,22 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, return caps; } +static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, + u8 tidno) +{ + struct ath_atx_tid *txtid; + + if (!(sc->sc_flags & SC_OP_TXAGGR)) + return false; + + txtid = ATH_AN_2_TID(an, tidno); + + if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) + return true; + return false; +} + + /***********************************/ /* mac80211 Rate Control callbacks */ /***********************************/ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e53433e3e4cc..85a7323a04ef 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -855,20 +855,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid } } -bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) -{ - struct ath_atx_tid *txtid; - - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return false; - - txtid = ATH_AN_2_TID(an, tidno); - - if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) - return true; - return false; -} - /********************/ /* Queue Management */ /********************/ -- cgit v1.2.3 From 6e5c2b4e8addfaab8ef54dedaf7b607e1585c35b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 20 Sep 2010 13:45:40 +0200 Subject: ath9k: make the driver specific rate control module optional ath9k can use minstrel_ht instead, so it makes sense to save some space here. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 8 ++++++++ drivers/net/wireless/ath/ath9k/Makefile | 2 +- drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/ath9k/rc.h | 11 +++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 35f23bdc442f..ad57a6d23110 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -32,6 +32,14 @@ config ATH9K_DEBUGFS Also required for changing debug message flags at run time. +config ATH9K_RATE_CONTROL + bool "Atheros ath9k rate control" + depends on ATH9K + default y + ---help--- + Say Y, if you want to use the ath9k specific rate control + module instead of minstrel_ht. + config ATH9K_HTC tristate "Atheros HTC based wireless cards support" depends on USB && MAC80211 diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4555e9983903..aca01621c205 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -5,8 +5,8 @@ ath9k-y += beacon.o \ recv.o \ xmit.o \ virtual.o \ - rc.o +ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_PCI) += pci.o ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 0364167cbfaf..573899e27b3d 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -654,7 +654,9 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); +#ifdef CONFIG_ATH9K_RATE_CONTROL hw->rate_control_algorithm = "ath9k_rate_control"; +#endif if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index dc1082654501..268072fd3c1c 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -224,7 +224,18 @@ enum ath9k_internal_frame_type { ATH9K_IFT_UNPAUSE }; +#ifdef CONFIG_ATH9K_RATE_CONTROL int ath_rate_control_register(void); void ath_rate_control_unregister(void); +#else +static inline int ath_rate_control_register(void) +{ + return 0; +} + +static inline void ath_rate_control_unregister(void) +{ +} +#endif #endif /* RC_H */ -- cgit v1.2.3 From f4bc17cdd205ebaa3807c2aa973719bb5ce6a5b2 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Tue, 21 Sep 2010 17:35:41 +0200 Subject: ipvs: netfilter connection tracking changes Add more code to IPVS to work with Netfilter connection tracking and fix some problems. - Allow IPVS to be compiled without connection tracking as in 2.6.35 and before. This can avoid keeping conntracks for all IPVS connections because this costs memory. ip_vs_ftp still depends on connection tracking and NAT as implemented for 2.6.36. - Add sysctl var "conntrack" to enable connection tracking for all IPVS connections. For loaded IPVS directors it needs tuning of nf_conntrack_max limit. - Add IP_VS_CONN_F_NFCT connection flag to request the connection to use connection tracking. This allows user space to provide this flag, for example, in dest->conn_flags. This can be useful to request connection tracking per real server instead of forcing it for all connections with the "conntrack" sysctl. This flag is set currently only by ip_vs_ftp and of course by "conntrack" sysctl. - Add ip_vs_nfct.c file to hold all connection tracking code, by this way main code should not depend of netfilter conntrack support. - Return back the ip_vs_post_routing handler as in 2.6.35 and use skb->ipvs_property=1 to allow IPVS to work without connection tracking Connection tracking: - most of the code is already in 2.6.36-rc - alter conntrack reply tuple for LVS-NAT connections when first packet from client is forwarded and conntrack state is NEW or RELATED. Additionally, alter reply for RELATED connections from real server, again for packet in original direction. - add IP_VS_XMIT_TUNNEL to confirm conntrack (without altering reply) for LVS-TUN early because we want to call nf_reset. It is needed because we add IPIP header and the original conntrack should be preserved, not destroyed. The transmitted IPIP packets can reuse same conntrack, so we do not set skb->ipvs_property. - try to destroy conntrack when the IPVS connection is destroyed. It is not fatal if conntrack disappears before that, it depends on the used timers. Fix problems from long time: - add skb->ip_summed = CHECKSUM_NONE for the LVS-TUN transmitters Signed-off-by: Julian Anastasov Signed-off-by: Patrick McHardy --- include/linux/ip_vs.h | 2 + include/net/ip_vs.h | 44 +++++- net/netfilter/ipvs/Kconfig | 13 +- net/netfilter/ipvs/Makefile | 5 +- net/netfilter/ipvs/ip_vs_conn.c | 13 ++ net/netfilter/ipvs/ip_vs_core.c | 46 ++++++- net/netfilter/ipvs/ip_vs_ctl.c | 12 ++ net/netfilter/ipvs/ip_vs_ftp.c | 146 +------------------- net/netfilter/ipvs/ip_vs_nfct.c | 292 ++++++++++++++++++++++++++++++++++++++++ net/netfilter/ipvs/ip_vs_xmit.c | 98 +++++++------- 10 files changed, 475 insertions(+), 196 deletions(-) create mode 100644 net/netfilter/ipvs/ip_vs_nfct.c diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index 003d75f6ffe1..df7728613720 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -90,10 +90,12 @@ #define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ /* Flags that are not sent to backup server start from bit 16 */ +#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */ /* Connection flags from destination that can be changed by user space */ #define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \ IP_VS_CONN_F_ONE_PACKET | \ + IP_VS_CONN_F_NFCT | \ 0) #define IP_VS_SCHEDNAME_MAXLEN 16 diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 62698a9c1631..e8ec5231eae9 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -25,7 +25,9 @@ #include #include /* for struct ipv6hdr */ #include /* for ipv6_addr_copy */ - +#ifdef CONFIG_IP_VS_NFCT +#include +#endif /* Connections' size value needed by ip_vs_ctl.c */ extern int ip_vs_conn_tab_size; @@ -798,6 +800,7 @@ extern int sysctl_ip_vs_expire_nodest_conn; extern int sysctl_ip_vs_expire_quiescent_template; extern int sysctl_ip_vs_sync_threshold[2]; extern int sysctl_ip_vs_nat_icmp_send; +extern int sysctl_ip_vs_conntrack; extern struct ip_vs_stats ip_vs_stats; extern const struct ctl_path net_vs_ctl_path[]; @@ -955,8 +958,47 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) return csum_partial(diff, sizeof(diff), oldsum); } +#ifdef CONFIG_IP_VS_NFCT +/* + * Netfilter connection tracking + * (from ip_vs_nfct.c) + */ +static inline int ip_vs_conntrack_enabled(void) +{ + return sysctl_ip_vs_conntrack; +} + extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin); +extern int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp); +extern void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, + struct ip_vs_conn *cp, u_int8_t proto, + const __be16 port, int from_rs); +extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp); + +#else + +static inline int ip_vs_conntrack_enabled(void) +{ + return 0; +} + +static inline void ip_vs_update_conntrack(struct sk_buff *skb, + struct ip_vs_conn *cp, int outin) +{ +} + +static inline int ip_vs_confirm_conntrack(struct sk_buff *skb, + struct ip_vs_conn *cp) +{ + return NF_ACCEPT; +} + +static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) +{ +} +/* CONFIG_IP_VS_NFCT */ +#endif #endif /* __KERNEL__ */ diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index 46a77d5c3887..af3c9f48f2d7 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -3,7 +3,7 @@ # menuconfig IP_VS tristate "IP virtual server support" - depends on NET && INET && NETFILTER && NF_CONNTRACK + depends on NET && INET && NETFILTER ---help--- IP Virtual Server support will let you build a high-performance virtual server based on cluster of two or more real servers. This @@ -235,7 +235,8 @@ comment 'IPVS application helper' config IP_VS_FTP tristate "FTP protocol helper" - depends on IP_VS_PROTO_TCP && NF_NAT + depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT + select IP_VS_NFCT ---help--- FTP is a protocol that transfers IP address and/or port number in the payload. In the virtual server via Network Address Translation, @@ -247,4 +248,12 @@ config IP_VS_FTP If you want to compile it in kernel, say Y. To compile it as a module, choose M here. If unsure, say N. +config IP_VS_NFCT + bool "Netfilter connection tracking" + depends on NF_CONNTRACK + ---help--- + The Netfilter connection tracking support allows the IPVS + connection state to be exported to the Netfilter framework + for filtering purposes. + endif # IP_VS diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile index e3baefd7066e..349fe8819b89 100644 --- a/net/netfilter/ipvs/Makefile +++ b/net/netfilter/ipvs/Makefile @@ -9,10 +9,13 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH_ESP) += ip_vs_proto_ah_esp.o ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_SCTP) += ip_vs_proto_sctp.o +ip_vs-extra_objs-y := +ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o + ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ ip_vs_est.o ip_vs_proto.o \ - $(ip_vs_proto-objs-y) + $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y) # IPVS core diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 9fe1da7bcf16..a970d9691496 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -721,6 +721,9 @@ static void ip_vs_conn_expire(unsigned long data) if (cp->control) ip_vs_control_del(cp); + if (cp->flags & IP_VS_CONN_F_NFCT) + ip_vs_conn_drop_conntrack(cp); + if (unlikely(cp->app != NULL)) ip_vs_unbind_app(cp); ip_vs_unbind_dest(cp); @@ -816,6 +819,16 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, if (unlikely(pp && atomic_read(&pp->appcnt))) ip_vs_bind_app(cp, pp); + /* + * Allow conntrack to be preserved. By default, conntrack + * is created and destroyed for every packet. + * Sometimes keeping conntrack can be useful for + * IP_VS_CONN_F_ONE_PACKET too. + */ + + if (ip_vs_conntrack_enabled()) + cp->flags |= IP_VS_CONN_F_NFCT; + /* Hash it in the ip_vs_conn_tab finally */ ip_vs_conn_hash(cp); diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 319991d4d251..7fbc80d81fe8 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -537,6 +537,23 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, return NF_DROP; } +/* + * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING + * chain and is used to avoid double NAT and confirmation when we do + * not want to keep the conntrack structure + */ +static unsigned int ip_vs_post_routing(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + if (!skb->ipvs_property) + return NF_ACCEPT; + /* The packet was sent from IPVS, exit this chain */ + return NF_STOP; +} + __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) { return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); @@ -695,7 +712,10 @@ static int handle_response_icmp(int af, struct sk_buff *skb, /* do the statistics and put it back */ ip_vs_out_stats(cp, skb); - skb->ipvs_property = 1; + if (!(cp->flags & IP_VS_CONN_F_NFCT)) + skb->ipvs_property = 1; + else + ip_vs_update_conntrack(skb, cp, 0); verdict = NF_ACCEPT; out: @@ -928,17 +948,19 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ip_vs_out_stats(cp, skb); ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); - ip_vs_update_conntrack(skb, cp, 0); + if (!(cp->flags & IP_VS_CONN_F_NFCT)) + skb->ipvs_property = 1; + else + ip_vs_update_conntrack(skb, cp, 0); ip_vs_conn_put(cp); - skb->ipvs_property = 1; - LeaveFunction(11); return NF_ACCEPT; drop: ip_vs_conn_put(cp); kfree_skb(skb); + LeaveFunction(11); return NF_STOLEN; } @@ -1483,6 +1505,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* Before the netfilter connection tracking, exit from POST_ROUTING */ + { + .hook = ip_vs_post_routing, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_NAT_SRC-1, + }, #ifdef CONFIG_IP_VS_IPV6 /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be @@ -1511,6 +1541,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* Before the netfilter connection tracking, exit from POST_ROUTING */ + { + .hook = ip_vs_post_routing, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_NAT_SRC-1, + }, #endif }; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 7bd41d28080c..d2d842f292c6 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -88,6 +88,9 @@ int sysctl_ip_vs_expire_nodest_conn = 0; int sysctl_ip_vs_expire_quiescent_template = 0; int sysctl_ip_vs_sync_threshold[2] = { 3, 50 }; int sysctl_ip_vs_nat_icmp_send = 0; +#ifdef CONFIG_IP_VS_NFCT +int sysctl_ip_vs_conntrack; +#endif #ifdef CONFIG_IP_VS_DEBUG @@ -1580,6 +1583,15 @@ static struct ctl_table vs_vars[] = { .mode = 0644, .proc_handler = proc_do_defense_mode, }, +#ifdef CONFIG_IP_VS_NFCT + { + .procname = "conntrack", + .data = &sysctl_ip_vs_conntrack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif { .procname = "secure_tcp", .data = &sysctl_ip_vs_secure_tcp, diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 7e9af5b76d9e..9cd375f94d61 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -20,17 +20,6 @@ * * Author: Wouter Gadeyne * - * - * Code for ip_vs_expect_related and ip_vs_expect_callback is taken from - * http://www.ssi.bg/~ja/nfct/: - * - * ip_vs_nfct.c: Netfilter connection tracking support for IPVS - * - * Portions Copyright (C) 2001-2002 - * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland. - * - * Portions Copyright (C) 2003-2008 - * Julian Anastasov */ #define KMSG_COMPONENT "IPVS" @@ -58,16 +47,6 @@ #define SERVER_STRING "227 Entering Passive Mode (" #define CLIENT_STRING "PORT " -#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u" -#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \ - &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \ - (T)->dst.protonum - -#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u" -#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \ - &((C)->vaddr.ip), ntohs((C)->vport), \ - &((C)->daddr.ip), ntohs((C)->dport), \ - (C)->protocol, (C)->state /* * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper @@ -85,6 +64,8 @@ static int ip_vs_ftp_pasv; static int ip_vs_ftp_init_conn(struct ip_vs_app *app, struct ip_vs_conn *cp) { + /* We use connection tracking for the command connection */ + cp->flags |= IP_VS_CONN_F_NFCT; return 0; } @@ -148,120 +129,6 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, return 1; } -/* - * Called from init_conntrack() as expectfn handler. - */ -static void -ip_vs_expect_callback(struct nf_conn *ct, - struct nf_conntrack_expect *exp) -{ - struct nf_conntrack_tuple *orig, new_reply; - struct ip_vs_conn *cp; - - if (exp->tuple.src.l3num != PF_INET) - return; - - /* - * We assume that no NF locks are held before this callback. - * ip_vs_conn_out_get and ip_vs_conn_in_get should match their - * expectations even if they use wildcard values, now we provide the - * actual values from the newly created original conntrack direction. - * The conntrack is confirmed when packet reaches IPVS hooks. - */ - - /* RS->CLIENT */ - orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply CLIENT->RS to CLIENT->VS */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found inout cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.dst.u3 = cp->vaddr; - new_reply.dst.u.tcp.port = cp->vport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE - ", inout cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - /* CLIENT->VS */ - cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply VS->CLIENT to RS->CLIENT */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found outin cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.src.u3 = cp->daddr; - new_reply.src.u.tcp.port = cp->dport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " - FMT_TUPLE ", outin cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuple=" FMT_TUPLE - " - unknown expect\n", - __func__, ct, ct->status, ARG_TUPLE(orig)); - return; - -alter: - /* Never alter conntrack for non-NAT conns */ - if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) - nf_conntrack_alter_reply(ct, &new_reply); - ip_vs_conn_put(cp); - return; -} - -/* - * Create NF conntrack expectation with wildcard (optional) source port. - * Then the default callback function will alter the reply and will confirm - * the conntrack entry when the first packet comes. - */ -static void -ip_vs_expect_related(struct sk_buff *skb, struct nf_conn *ct, - struct ip_vs_conn *cp, u_int8_t proto, - const __be16 *port, int from_rs) -{ - struct nf_conntrack_expect *exp; - - BUG_ON(!ct || ct == &nf_conntrack_untracked); - - exp = nf_ct_expect_alloc(ct); - if (!exp) - return; - - if (from_rs) - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->daddr, &cp->caddr, - proto, port, &cp->cport); - else - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->caddr, &cp->vaddr, - proto, port, &cp->vport); - - exp->expectfn = ip_vs_expect_callback; - - IP_VS_DBG(7, "%s(): ct=%p, expect tuple=" FMT_TUPLE "\n", - __func__, ct, ARG_TUPLE(&exp->tuple)); - nf_ct_expect_related(exp); - nf_ct_expect_put(exp); -} - /* * Look at outgoing ftp packets to catch the response to a PASV command * from the server (inside-to-outside). @@ -335,7 +202,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, &cp->caddr, 0, &cp->vaddr, port, &from, port, - IP_VS_CONN_F_NO_CPORT, + IP_VS_CONN_F_NO_CPORT | + IP_VS_CONN_F_NFCT, cp->dest); if (!n_cp) return 0; @@ -371,8 +239,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, start-data, end-start, buf, buf_len); if (ret) - ip_vs_expect_related(skb, ct, n_cp, - IPPROTO_TCP, NULL, 0); + ip_vs_nfct_expect_related(skb, ct, n_cp, + IPPROTO_TCP, 0, 0); } /* @@ -487,7 +355,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, &to, port, &cp->vaddr, htons(ntohs(cp->vport)-1), &cp->daddr, htons(ntohs(cp->dport)-1), - 0, + IP_VS_CONN_F_NFCT, cp->dest); if (!n_cp) return 0; diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c new file mode 100644 index 000000000000..c038458d0290 --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_nfct.c @@ -0,0 +1,292 @@ +/* + * ip_vs_nfct.c: Netfilter connection tracking support for IPVS + * + * Portions Copyright (C) 2001-2002 + * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland. + * + * Portions Copyright (C) 2003-2010 + * Julian Anastasov + * + * + * This code is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Authors: + * Ben North + * Julian Anastasov Reorganize and sync with latest kernels + * Hannes Eder Extend NFCT support for FTP, ipvs match + * + * + * Current status: + * + * - provide conntrack confirmation for new and related connections, by + * this way we can see their proper conntrack state in all hooks + * - support for all forwarding methods, not only NAT + * - FTP support (NAT), ability to support other NAT apps with expectations + * - to correctly create expectations for related NAT connections the proper + * NF conntrack support must be already installed, eg. ip_vs_ftp requires + * nf_conntrack_ftp ... iptables_nat for the same ports (but no iptables + * NAT rules are needed) + * - alter reply for NAT when forwarding packet in original direction: + * conntrack from client in NEW or RELATED (Passive FTP DATA) state or + * when RELATED conntrack is created from real server (Active FTP DATA) + * - if iptables_nat is not loaded the Passive FTP will not work (the + * PASV response can not be NAT-ed) but Active FTP should work + * + */ + +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u" +#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \ + &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \ + (T)->dst.protonum + +#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u" +#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \ + &((C)->vaddr.ip), ntohs((C)->vport), \ + &((C)->daddr.ip), ntohs((C)->dport), \ + (C)->protocol, (C)->state + +void +ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + struct nf_conntrack_tuple new_tuple; + + if (ct == NULL || nf_ct_is_confirmed(ct) || nf_ct_is_untracked(ct) || + nf_ct_is_dying(ct)) + return; + + /* Never alter conntrack for non-NAT conns */ + if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) + return; + + /* Alter reply only in original direction */ + if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) + return; + + /* + * The connection is not yet in the hashtable, so we update it. + * CIP->VIP will remain the same, so leave the tuple in + * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the + * real-server we will see RIP->DIP. + */ + new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + /* + * This will also take care of UDP and other protocols. + */ + if (outin) { + new_tuple.src.u3 = cp->daddr; + if (new_tuple.dst.protonum != IPPROTO_ICMP && + new_tuple.dst.protonum != IPPROTO_ICMPV6) + new_tuple.src.u.tcp.port = cp->dport; + } else { + new_tuple.dst.u3 = cp->vaddr; + if (new_tuple.dst.protonum != IPPROTO_ICMP && + new_tuple.dst.protonum != IPPROTO_ICMPV6) + new_tuple.dst.u.tcp.port = cp->vport; + } + IP_VS_DBG(7, "%s: Updating conntrack ct=%p, status=0x%lX, " + "ctinfo=%d, old reply=" FMT_TUPLE + ", new reply=" FMT_TUPLE ", cp=" FMT_CONN "\n", + __func__, ct, ct->status, ctinfo, + ARG_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple), + ARG_TUPLE(&new_tuple), ARG_CONN(cp)); + nf_conntrack_alter_reply(ct, &new_tuple); +} + +int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) +{ + return nf_conntrack_confirm(skb); +} + +/* + * Called from init_conntrack() as expectfn handler. + */ +static void ip_vs_nfct_expect_callback(struct nf_conn *ct, + struct nf_conntrack_expect *exp) +{ + struct nf_conntrack_tuple *orig, new_reply; + struct ip_vs_conn *cp; + + if (exp->tuple.src.l3num != PF_INET) + return; + + /* + * We assume that no NF locks are held before this callback. + * ip_vs_conn_out_get and ip_vs_conn_in_get should match their + * expectations even if they use wildcard values, now we provide the + * actual values from the newly created original conntrack direction. + * The conntrack is confirmed when packet reaches IPVS hooks. + */ + + /* RS->CLIENT */ + orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, + &orig->src.u3, orig->src.u.tcp.port, + &orig->dst.u3, orig->dst.u.tcp.port); + if (cp) { + /* Change reply CLIENT->RS to CLIENT->VS */ + new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " + FMT_TUPLE ", found inout cp=" FMT_CONN "\n", + __func__, ct, ct->status, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + new_reply.dst.u3 = cp->vaddr; + new_reply.dst.u.tcp.port = cp->vport; + IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE + ", inout cp=" FMT_CONN "\n", + __func__, ct, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + goto alter; + } + + /* CLIENT->VS */ + cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, + &orig->src.u3, orig->src.u.tcp.port, + &orig->dst.u3, orig->dst.u.tcp.port); + if (cp) { + /* Change reply VS->CLIENT to RS->CLIENT */ + new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " + FMT_TUPLE ", found outin cp=" FMT_CONN "\n", + __func__, ct, ct->status, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + new_reply.src.u3 = cp->daddr; + new_reply.src.u.tcp.port = cp->dport; + IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " + FMT_TUPLE ", outin cp=" FMT_CONN "\n", + __func__, ct, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + goto alter; + } + + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuple=" FMT_TUPLE + " - unknown expect\n", + __func__, ct, ct->status, ARG_TUPLE(orig)); + return; + +alter: + /* Never alter conntrack for non-NAT conns */ + if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) + nf_conntrack_alter_reply(ct, &new_reply); + ip_vs_conn_put(cp); + return; +} + +/* + * Create NF conntrack expectation with wildcard (optional) source port. + * Then the default callback function will alter the reply and will confirm + * the conntrack entry when the first packet comes. + * Use port 0 to expect connection from any port. + */ +void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, + struct ip_vs_conn *cp, u_int8_t proto, + const __be16 port, int from_rs) +{ + struct nf_conntrack_expect *exp; + + if (ct == NULL || nf_ct_is_untracked(ct)) + return; + + exp = nf_ct_expect_alloc(ct); + if (!exp) + return; + + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), + from_rs ? &cp->daddr : &cp->caddr, + from_rs ? &cp->caddr : &cp->vaddr, + proto, port ? &port : NULL, + from_rs ? &cp->cport : &cp->vport); + + exp->expectfn = ip_vs_nfct_expect_callback; + + IP_VS_DBG(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&exp->tuple)); + nf_ct_expect_related(exp); + nf_ct_expect_put(exp); +} +EXPORT_SYMBOL(ip_vs_nfct_expect_related); + +/* + * Our connection was terminated, try to drop the conntrack immediately + */ +void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) +{ + struct nf_conntrack_tuple_hash *h; + struct nf_conn *ct; + struct nf_conntrack_tuple tuple; + + if (!cp->cport) + return; + + tuple = (struct nf_conntrack_tuple) { + .dst = { .protonum = cp->protocol, .dir = IP_CT_DIR_ORIGINAL } }; + tuple.src.u3 = cp->caddr; + tuple.src.u.all = cp->cport; + tuple.src.l3num = cp->af; + tuple.dst.u3 = cp->vaddr; + tuple.dst.u.all = cp->vport; + + IP_VS_DBG(7, "%s: dropping conntrack with tuple=" FMT_TUPLE + " for conn " FMT_CONN "\n", + __func__, ARG_TUPLE(&tuple), ARG_CONN(cp)); + + h = nf_conntrack_find_get(&init_net, NF_CT_DEFAULT_ZONE, &tuple); + if (h) { + ct = nf_ct_tuplehash_to_ctrack(h); + /* Show what happens instead of calling nf_ct_kill() */ + if (del_timer(&ct->timeout)) { + IP_VS_DBG(7, "%s: ct=%p, deleted conntrack timer for tuple=" + FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&tuple)); + if (ct->timeout.function) + ct->timeout.function(ct->timeout.data); + } else { + IP_VS_DBG(7, "%s: ct=%p, no conntrack timer for tuple=" + FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&tuple)); + } + nf_ct_put(ct); + } else { + IP_VS_DBG(7, "%s: no conntrack for tuple=" FMT_TUPLE "\n", + __func__, ARG_TUPLE(&tuple)); + } +} + diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 49df6bea6a2d..8817afa34e6a 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -194,12 +193,37 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) dst_release(old_dst); } -#define IP_VS_XMIT(pf, skb, rt) \ +#define IP_VS_XMIT_TUNNEL(skb, cp) \ +({ \ + int __ret = NF_ACCEPT; \ + \ + if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \ + __ret = ip_vs_confirm_conntrack(skb, cp); \ + if (__ret == NF_ACCEPT) { \ + nf_reset(skb); \ + (skb)->ip_summed = CHECKSUM_NONE; \ + } \ + __ret; \ +}) + +#define IP_VS_XMIT_NAT(pf, skb, cp) \ do { \ - (skb)->ipvs_property = 1; \ + if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ + (skb)->ipvs_property = 1; \ + else \ + ip_vs_update_conntrack(skb, cp, 1); \ skb_forward_csum(skb); \ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ - (rt)->dst.dev, dst_output); \ + skb_dst(skb)->dev, dst_output); \ +} while (0) + +#define IP_VS_XMIT(pf, skb, cp) \ +do { \ + if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ + (skb)->ipvs_property = 1; \ + skb_forward_csum(skb); \ + NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ + skb_dst(skb)->dev, dst_output); \ } while (0) @@ -271,7 +295,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -335,7 +359,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -349,36 +373,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, } #endif -void -ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) -{ - struct nf_conn *ct = (struct nf_conn *)skb->nfct; - struct nf_conntrack_tuple new_tuple; - - if (ct == NULL || nf_ct_is_untracked(ct) || nf_ct_is_confirmed(ct)) - return; - - /* - * The connection is not yet in the hashtable, so we update it. - * CIP->VIP will remain the same, so leave the tuple in - * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the - * real-server we will see RIP->DIP. - */ - new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - if (outin) - new_tuple.src.u3 = cp->daddr; - else - new_tuple.dst.u3 = cp->vaddr; - /* - * This will also take care of UDP and other protocols. - */ - if (outin) - new_tuple.src.u.tcp.port = cp->dport; - else - new_tuple.dst.u.tcp.port = cp->vport; - nf_conntrack_alter_reply(ct, &new_tuple); -} - /* * NAT transmitter (only for outside-to-inside nat forwarding) * Not used for related ICMP @@ -434,8 +428,6 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); - ip_vs_update_conntrack(skb, cp, 1); - /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still MTU problem. */ @@ -443,7 +435,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -451,8 +443,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, tx_error_icmp: dst_link_failure(skb); tx_error: - LeaveFunction(10); kfree_skb(skb); + LeaveFunction(10); return NF_STOLEN; tx_error_put: ip_rt_put(rt); @@ -512,8 +504,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); - ip_vs_update_conntrack(skb, cp, 1); - /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still MTU problem. */ @@ -521,7 +511,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -571,6 +561,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; + int ret; EnterFunction(10); @@ -655,7 +646,11 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - ip_local_out(skb); + ret = IP_VS_XMIT_TUNNEL(skb, cp); + if (ret == NF_ACCEPT) + ip_local_out(skb); + else if (ret == NF_DROP) + kfree_skb(skb); LeaveFunction(10); @@ -681,6 +676,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ipv6hdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; + int ret; EnterFunction(10); @@ -761,7 +757,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - ip6_local_out(skb); + ret = IP_VS_XMIT_TUNNEL(skb, cp); + if (ret == NF_ACCEPT) + ip6_local_out(skb); + else if (ret == NF_DROP) + kfree_skb(skb); LeaveFunction(10); @@ -820,7 +820,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -873,7 +873,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp); LeaveFunction(10); return NF_STOLEN; @@ -947,7 +947,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp); rc = NF_STOLEN; goto out; @@ -1022,7 +1022,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp); rc = NF_STOLEN; goto out; -- cgit v1.2.3 From 8a8030407f55a6aaedb51167c1a2383311fcd707 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Tue, 21 Sep 2010 17:38:57 +0200 Subject: ipvs: make rerouting optional with snat_reroute Add new sysctl flag "snat_reroute". Recent kernels use ip_route_me_harder() to route LVS-NAT responses properly by VIP when there are multiple paths to client. But setups that do not have alternative default routes can skip this routing lookup by using snat_reroute=0. Signed-off-by: Julian Anastasov Signed-off-by: Patrick McHardy --- include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_core.c | 37 +++++++++++++++++++++++++++++-------- net/netfilter/ipvs/ip_vs_ctl.c | 8 ++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index e8ec5231eae9..3915a4f4cd30 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -801,6 +801,7 @@ extern int sysctl_ip_vs_expire_quiescent_template; extern int sysctl_ip_vs_sync_threshold[2]; extern int sysctl_ip_vs_nat_icmp_send; extern int sysctl_ip_vs_conntrack; +extern int sysctl_ip_vs_snat_reroute; extern struct ip_vs_stats ip_vs_stats; extern const struct ctl_path net_vs_ctl_path[]; diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 7fbc80d81fe8..06c388bf4e33 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -929,20 +929,31 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ip_send_check(ip_hdr(skb)); } + /* + * nf_iterate does not expect change in the skb->dst->dev. + * It looks like it is not fatal to enable this code for hooks + * where our handlers are at the end of the chain list and + * when all next handlers use skb->dst->dev and not outdev. + * It will definitely route properly the inout NAT traffic + * when multiple paths are used. + */ + /* For policy routing, packets originating from this * machine itself may be routed differently to packets * passing through. We want this packet to be routed as * if it came from this machine itself. So re-compute * the routing information. */ + if (sysctl_ip_vs_snat_reroute) { #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) { - if (ip6_route_me_harder(skb) != 0) - goto drop; - } else + if (af == AF_INET6) { + if (ip6_route_me_harder(skb) != 0) + goto drop; + } else #endif - if (ip_route_me_harder(skb, RTN_LOCAL) != 0) - goto drop; + if (ip_route_me_harder(skb, RTN_LOCAL) != 0) + goto drop; + } IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT"); @@ -991,8 +1002,13 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { int related, verdict = ip_vs_out_icmp_v6(skb, &related); - if (related) + if (related) { + if (sysctl_ip_vs_snat_reroute && + NF_ACCEPT == verdict && + ip6_route_me_harder(skb)) + verdict = NF_DROP; return verdict; + } ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } } else @@ -1000,8 +1016,13 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, if (unlikely(iph.protocol == IPPROTO_ICMP)) { int related, verdict = ip_vs_out_icmp(skb, &related); - if (related) + if (related) { + if (sysctl_ip_vs_snat_reroute && + NF_ACCEPT == verdict && + ip_route_me_harder(skb, RTN_LOCAL)) + verdict = NF_DROP; return verdict; + } ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index d2d842f292c6..e637cd0384b1 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -91,6 +91,7 @@ int sysctl_ip_vs_nat_icmp_send = 0; #ifdef CONFIG_IP_VS_NFCT int sysctl_ip_vs_conntrack; #endif +int sysctl_ip_vs_snat_reroute = 1; #ifdef CONFIG_IP_VS_DEBUG @@ -1599,6 +1600,13 @@ static struct ctl_table vs_vars[] = { .mode = 0644, .proc_handler = proc_do_defense_mode, }, + { + .procname = "snat_reroute", + .data = &sysctl_ip_vs_snat_reroute, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #if 0 { .procname = "timeout_established", -- cgit v1.2.3 From 99f07e91bef34db0fc8b1a224096e97f02dc0d56 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 21 Sep 2010 17:49:20 +0200 Subject: netfilter: save the hash of the tuple in the original direction for latter use Since we don't change the tuple in the original direction, we can save it in ct->tuplehash[IP_CT_DIR_REPLY].hnode.pprev for __nf_conntrack_confirm() use. __hash_conntrack() is split into two steps: hash_conntrack_raw() is used to get the raw hash, and __hash_bucket() is used to get the bucket id. In SYN-flood case, early_drop() doesn't need to recompute the hash again. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/netfilter/nf_conntrack_core.c | 112 ++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 34 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 4c0ad9b4dba0..1eacf8d9966a 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -67,29 +67,40 @@ EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked); static unsigned int nf_conntrack_hash_rnd __read_mostly; -static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, - u16 zone, unsigned int size, unsigned int rnd) +static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone) { unsigned int n; - u_int32_t h; /* The direction must be ignored, so we hash everything up to the * destination ports (which is a multiple of 4) and treat the last * three bytes manually. */ n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32); - h = jhash2((u32 *)tuple, n, - zone ^ rnd ^ (((__force __u16)tuple->dst.u.all << 16) | - tuple->dst.protonum)); + return jhash2((u32 *)tuple, n, zone ^ nf_conntrack_hash_rnd ^ + (((__force __u16)tuple->dst.u.all << 16) | + tuple->dst.protonum)); +} + +static u32 __hash_bucket(u32 hash, unsigned int size) +{ + return ((u64)hash * size) >> 32; +} + +static u32 hash_bucket(u32 hash, const struct net *net) +{ + return __hash_bucket(hash, net->ct.htable_size); +} - return ((u64)h * size) >> 32; +static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, + u16 zone, unsigned int size) +{ + return __hash_bucket(hash_conntrack_raw(tuple, zone), size); } static inline u_int32_t hash_conntrack(const struct net *net, u16 zone, const struct nf_conntrack_tuple *tuple) { - return __hash_conntrack(tuple, zone, net->ct.htable_size, - nf_conntrack_hash_rnd); + return __hash_conntrack(tuple, zone, net->ct.htable_size); } bool @@ -291,20 +302,20 @@ static void death_by_timeout(unsigned long ul_conntrack) * OR * - Caller must lock nf_conntrack_lock before calling this function */ -struct nf_conntrack_tuple_hash * -__nf_conntrack_find(struct net *net, u16 zone, - const struct nf_conntrack_tuple *tuple) +static struct nf_conntrack_tuple_hash * +____nf_conntrack_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple, u32 hash) { struct nf_conntrack_tuple_hash *h; struct hlist_nulls_node *n; - unsigned int hash = hash_conntrack(net, zone, tuple); + unsigned int bucket = hash_bucket(hash, net); /* Disable BHs the entire time since we normally need to disable them * at least once for the stats anyway. */ local_bh_disable(); begin: - hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) { + hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) { if (nf_ct_tuple_equal(tuple, &h->tuple) && nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) { NF_CT_STAT_INC(net, found); @@ -318,7 +329,7 @@ begin: * not the expected one, we must restart lookup. * We probably met an item that was moved to another chain. */ - if (get_nulls_value(n) != hash) { + if (get_nulls_value(n) != bucket) { NF_CT_STAT_INC(net, search_restart); goto begin; } @@ -326,19 +337,27 @@ begin: return NULL; } + +struct nf_conntrack_tuple_hash * +__nf_conntrack_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple) +{ + return ____nf_conntrack_find(net, zone, tuple, + hash_conntrack_raw(tuple, zone)); +} EXPORT_SYMBOL_GPL(__nf_conntrack_find); /* Find a connection corresponding to a tuple. */ -struct nf_conntrack_tuple_hash * -nf_conntrack_find_get(struct net *net, u16 zone, - const struct nf_conntrack_tuple *tuple) +static struct nf_conntrack_tuple_hash * +__nf_conntrack_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple, u32 hash) { struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; rcu_read_lock(); begin: - h = __nf_conntrack_find(net, zone, tuple); + h = ____nf_conntrack_find(net, zone, tuple, hash); if (h) { ct = nf_ct_tuplehash_to_ctrack(h); if (unlikely(nf_ct_is_dying(ct) || @@ -356,6 +375,14 @@ begin: return h; } + +struct nf_conntrack_tuple_hash * +nf_conntrack_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple) +{ + return __nf_conntrack_find_get(net, zone, tuple, + hash_conntrack_raw(tuple, zone)); +} EXPORT_SYMBOL_GPL(nf_conntrack_find_get); static void __nf_conntrack_hash_insert(struct nf_conn *ct, @@ -408,8 +435,11 @@ __nf_conntrack_confirm(struct sk_buff *skb) return NF_ACCEPT; zone = nf_ct_zone(ct); - hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); - repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple); + /* reuse the hash saved before */ + hash = *(unsigned long *)&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev; + hash = hash_bucket(hash, net); + repl_hash = hash_conntrack(net, zone, + &ct->tuplehash[IP_CT_DIR_REPLY].tuple); /* We're not in hash table, and we refuse to set up related connections for unconfirmed conns. But packet copies and @@ -566,10 +596,11 @@ static noinline int early_drop(struct net *net, unsigned int hash) return dropped; } -struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, - const struct nf_conntrack_tuple *orig, - const struct nf_conntrack_tuple *repl, - gfp_t gfp) +static struct nf_conn * +__nf_conntrack_alloc(struct net *net, u16 zone, + const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_tuple *repl, + gfp_t gfp, u32 hash) { struct nf_conn *ct; @@ -585,6 +616,9 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, get_random_bytes(&rand, sizeof(rand)); } while (!rand); cmpxchg(&nf_conntrack_hash_rnd, 0, rand); + + /* recompute the hash as nf_conntrack_hash_rnd is initialized */ + hash = hash_conntrack_raw(orig, zone); } /* We don't want any race condition at early drop stage */ @@ -592,8 +626,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, if (nf_conntrack_max && unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) { - unsigned int hash = hash_conntrack(net, zone, orig); - if (!early_drop(net, hash)) { + if (!early_drop(net, hash_bucket(hash, net))) { atomic_dec(&net->ct.count); if (net_ratelimit()) printk(KERN_WARNING @@ -623,7 +656,8 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL; ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; - ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL; + /* save hash for reusing when confirming */ + *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; /* Don't set timer yet: wait for confirmation */ setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); write_pnet(&ct->ct_net, net); @@ -650,6 +684,14 @@ out_free: return ERR_PTR(-ENOMEM); #endif } + +struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, + const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_tuple *repl, + gfp_t gfp) +{ + return __nf_conntrack_alloc(net, zone, orig, repl, gfp, 0); +} EXPORT_SYMBOL_GPL(nf_conntrack_alloc); void nf_conntrack_free(struct nf_conn *ct) @@ -671,7 +713,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, struct nf_conntrack_l3proto *l3proto, struct nf_conntrack_l4proto *l4proto, struct sk_buff *skb, - unsigned int dataoff) + unsigned int dataoff, u32 hash) { struct nf_conn *ct; struct nf_conn_help *help; @@ -685,7 +727,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, return NULL; } - ct = nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC); + ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC, + hash); if (IS_ERR(ct)) { pr_debug("Can't allocate conntrack.\n"); return (struct nf_conntrack_tuple_hash *)ct; @@ -762,6 +805,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE; + u32 hash; if (!nf_ct_get_tuple(skb, skb_network_offset(skb), dataoff, l3num, protonum, &tuple, l3proto, @@ -771,10 +815,11 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, } /* look for tuple match */ - h = nf_conntrack_find_get(net, zone, &tuple); + hash = hash_conntrack_raw(&tuple, zone); + h = __nf_conntrack_find_get(net, zone, &tuple, hash); if (!h) { h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, - skb, dataoff); + skb, dataoff, hash); if (!h) return NULL; if (IS_ERR(h)) @@ -1314,8 +1359,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) ct = nf_ct_tuplehash_to_ctrack(h); hlist_nulls_del_rcu(&h->hnnode); bucket = __hash_conntrack(&h->tuple, nf_ct_zone(ct), - hashsize, - nf_conntrack_hash_rnd); + hashsize); hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]); } } -- cgit v1.2.3 From 26c15cfd291f8b4ee40b4bbdf5e3772adfd704f5 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Tue, 21 Sep 2010 18:12:30 +0200 Subject: ipvs: changes related to service usecnt Change the usage of svc usecnt during command execution: - we check if svc is registered but we do not need to hold usecnt reference while under __ip_vs_mutex, only the packet handling needs it during scheduling - change __ip_vs_service_get to __ip_vs_service_find and __ip_vs_svc_fwm_get to __ip_vs_svc_fwm_find because now caller will increase svc->usecnt - put common code that calls update_service in __ip_vs_update_dest - put common code in ip_vs_unlink_service() and use it to unregister the service - add comment that svc should not be accessed after ip_vs_del_service anymore - all IP_VS_WAIT_WHILE calls are now unified: usecnt > 0 - Properly log the app ports As result, some problems are fixed: - possible use-after-free of svc in ip_vs_genl_set_cmd after ip_vs_del_service because our usecnt reference does not guarantee that svc is not freed on refcnt==0, eg. when no dests are moved to trash - possible usecnt leak in do_ip_vs_set_ctl after ip_vs_del_service when the service is not freed now, for example, when some destionations are moved into trash and svc->refcnt remains above 0. It is harmless because svc is not in hash anymore. Signed-off-by: Julian Anastasov Acked-by: Simon Horman Signed-off-by: Patrick McHardy --- net/netfilter/ipvs/ip_vs_app.c | 6 +- net/netfilter/ipvs/ip_vs_ctl.c | 250 ++++++++++++++++------------------------- 2 files changed, 102 insertions(+), 154 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index e76f87f4aca8..a475edee0912 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c @@ -103,8 +103,8 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) goto out; list_add(&inc->a_list, &app->incs_list); - IP_VS_DBG(9, "%s application %s:%u registered\n", - pp->name, inc->name, inc->port); + IP_VS_DBG(9, "%s App %s:%u registered\n", + pp->name, inc->name, ntohs(inc->port)); return 0; @@ -130,7 +130,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc) pp->unregister_app(inc); IP_VS_DBG(9, "%s App %s:%u unregistered\n", - pp->name, inc->name, inc->port); + pp->name, inc->name, ntohs(inc->port)); list_del(&inc->a_list); diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e637cd0384b1..e4ec8f364f8b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -405,7 +405,7 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc) * Get service by {proto,addr,port} in the service table. */ static inline struct ip_vs_service * -__ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, +__ip_vs_service_find(int af, __u16 protocol, const union nf_inet_addr *vaddr, __be16 vport) { unsigned hash; @@ -420,7 +420,6 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, && (svc->port == vport) && (svc->protocol == protocol)) { /* HIT */ - atomic_inc(&svc->usecnt); return svc; } } @@ -433,7 +432,7 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, * Get service by {fwmark} in the service table. */ static inline struct ip_vs_service * -__ip_vs_svc_fwm_get(int af, __u32 fwmark) +__ip_vs_svc_fwm_find(int af, __u32 fwmark) { unsigned hash; struct ip_vs_service *svc; @@ -444,7 +443,6 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark) list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) { if (svc->fwmark == fwmark && svc->af == af) { /* HIT */ - atomic_inc(&svc->usecnt); return svc; } } @@ -463,14 +461,14 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, /* * Check the table hashed by fwmark first */ - if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark))) + if (fwmark && (svc = __ip_vs_svc_fwm_find(af, fwmark))) goto out; /* * Check the table hashed by * for "full" addressed entries */ - svc = __ip_vs_service_get(af, protocol, vaddr, vport); + svc = __ip_vs_service_find(af, protocol, vaddr, vport); if (svc == NULL && protocol == IPPROTO_TCP @@ -480,7 +478,7 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, * Check if ftp service entry exists, the packet * might belong to FTP data connections. */ - svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT); + svc = __ip_vs_service_find(af, protocol, vaddr, FTPPORT); } if (svc == NULL @@ -488,10 +486,12 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, /* * Check if the catch-all port (port zero) exists */ - svc = __ip_vs_service_get(af, protocol, vaddr, 0); + svc = __ip_vs_service_find(af, protocol, vaddr, 0); } out: + if (svc) + atomic_inc(&svc->usecnt); read_unlock(&__ip_vs_svc_lock); IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n", @@ -510,14 +510,19 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc) dest->svc = svc; } -static inline void +static void __ip_vs_unbind_svc(struct ip_vs_dest *dest) { struct ip_vs_service *svc = dest->svc; dest->svc = NULL; - if (atomic_dec_and_test(&svc->refcnt)) + if (atomic_dec_and_test(&svc->refcnt)) { + IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n", + svc->fwmark, + IP_VS_DBG_ADDR(svc->af, &svc->addr), + ntohs(svc->port), atomic_read(&svc->usecnt)); kfree(svc); + } } @@ -762,8 +767,8 @@ ip_vs_zero_stats(struct ip_vs_stats *stats) * Update a destination in the given service */ static void -__ip_vs_update_dest(struct ip_vs_service *svc, - struct ip_vs_dest *dest, struct ip_vs_dest_user_kern *udest) +__ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, + struct ip_vs_dest_user_kern *udest, int add) { int conn_flags; @@ -818,6 +823,25 @@ __ip_vs_update_dest(struct ip_vs_service *svc, dest->flags &= ~IP_VS_DEST_F_OVERLOAD; dest->u_threshold = udest->u_threshold; dest->l_threshold = udest->l_threshold; + + if (add) + ip_vs_new_estimator(&dest->stats); + + write_lock_bh(&__ip_vs_svc_lock); + + /* Wait until all other svc users go away */ + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); + + if (add) { + list_add(&dest->n_list, &svc->destinations); + svc->num_dests++; + } + + /* call the update_service, because server weight may be changed */ + if (svc->scheduler->update_service) + svc->scheduler->update_service(svc); + + write_unlock_bh(&__ip_vs_svc_lock); } @@ -865,13 +889,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, atomic_set(&dest->activeconns, 0); atomic_set(&dest->inactconns, 0); atomic_set(&dest->persistconns, 0); - atomic_set(&dest->refcnt, 0); + atomic_set(&dest->refcnt, 1); INIT_LIST_HEAD(&dest->d_list); spin_lock_init(&dest->dst_lock); spin_lock_init(&dest->stats.lock); - __ip_vs_update_dest(svc, dest, udest); - ip_vs_new_estimator(&dest->stats); + __ip_vs_update_dest(svc, dest, udest, 1); *dest_p = dest; @@ -931,65 +954,22 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) IP_VS_DBG_ADDR(svc->af, &dest->vaddr), ntohs(dest->vport)); - __ip_vs_update_dest(svc, dest, udest); - /* * Get the destination from the trash */ list_del(&dest->n_list); - ip_vs_new_estimator(&dest->stats); - - write_lock_bh(&__ip_vs_svc_lock); - + __ip_vs_update_dest(svc, dest, udest, 1); + ret = 0; + } else { /* - * Wait until all other svc users go away. + * Allocate and initialize the dest structure */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - list_add(&dest->n_list, &svc->destinations); - svc->num_dests++; - - /* call the update_service function of its scheduler */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - return 0; - } - - /* - * Allocate and initialize the dest structure - */ - ret = ip_vs_new_dest(svc, udest, &dest); - if (ret) { - return ret; + ret = ip_vs_new_dest(svc, udest, &dest); } - - /* - * Add the dest entry into the list - */ - atomic_inc(&dest->refcnt); - - write_lock_bh(&__ip_vs_svc_lock); - - /* - * Wait until all other svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - list_add(&dest->n_list, &svc->destinations); - svc->num_dests++; - - /* call the update_service function of its scheduler */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - LeaveFunction(2); - return 0; + return ret; } @@ -1028,19 +1008,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) return -ENOENT; } - __ip_vs_update_dest(svc, dest, udest); - - write_lock_bh(&__ip_vs_svc_lock); - - /* Wait until all other svc users go away */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - /* call the update_service, because server weight may be changed */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - + __ip_vs_update_dest(svc, dest, udest, 0); LeaveFunction(2); return 0; @@ -1067,6 +1035,10 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest) * the destination into the trash. */ if (atomic_dec_and_test(&dest->refcnt)) { + IP_VS_DBG_BUF(3, "Removing destination %u/%s:%u\n", + dest->vfwmark, + IP_VS_DBG_ADDR(dest->af, &dest->addr), + ntohs(dest->port)); ip_vs_dst_reset(dest); /* simply decrease svc->refcnt here, let the caller check and release the service if nobody refers to it. @@ -1133,7 +1105,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) /* * Wait until all other svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); /* * Unlink dest from the service @@ -1190,7 +1162,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, } /* I'm the first user of the service */ - atomic_set(&svc->usecnt, 1); + atomic_set(&svc->usecnt, 0); atomic_set(&svc->refcnt, 0); svc->af = u->af; @@ -1284,7 +1256,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) /* * Wait until all other svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); /* * Set the flags and timeout value @@ -1383,21 +1355,23 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) /* * Free the service if nobody refers to it */ - if (atomic_read(&svc->refcnt) == 0) + if (atomic_read(&svc->refcnt) == 0) { + IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n", + svc->fwmark, + IP_VS_DBG_ADDR(svc->af, &svc->addr), + ntohs(svc->port), atomic_read(&svc->usecnt)); kfree(svc); + } /* decrease the module use count */ ip_vs_use_count_dec(); } /* - * Delete a service from the service list + * Unlink a service from list and try to delete it if its refcnt reached 0 */ -static int ip_vs_del_service(struct ip_vs_service *svc) +static void ip_vs_unlink_service(struct ip_vs_service *svc) { - if (svc == NULL) - return -EEXIST; - /* * Unhash it from the service table */ @@ -1408,11 +1382,21 @@ static int ip_vs_del_service(struct ip_vs_service *svc) /* * Wait until all the svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); __ip_vs_del_service(svc); write_unlock_bh(&__ip_vs_svc_lock); +} + +/* + * Delete a service from the service list + */ +static int ip_vs_del_service(struct ip_vs_service *svc) +{ + if (svc == NULL) + return -EEXIST; + ip_vs_unlink_service(svc); return 0; } @@ -1431,14 +1415,7 @@ static int ip_vs_flush(void) */ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) { - write_lock_bh(&__ip_vs_svc_lock); - ip_vs_svc_unhash(svc); - /* - * Wait until all the svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); - __ip_vs_del_service(svc); - write_unlock_bh(&__ip_vs_svc_lock); + ip_vs_unlink_service(svc); } } @@ -1448,14 +1425,7 @@ static int ip_vs_flush(void) for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { list_for_each_entry_safe(svc, nxt, &ip_vs_svc_fwm_table[idx], f_list) { - write_lock_bh(&__ip_vs_svc_lock); - ip_vs_svc_unhash(svc); - /* - * Wait until all the svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); - __ip_vs_del_service(svc); - write_unlock_bh(&__ip_vs_svc_lock); + ip_vs_unlink_service(svc); } } @@ -2168,15 +2138,15 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) /* Lookup the exact service by or fwmark */ if (usvc.fwmark == 0) - svc = __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); + svc = __ip_vs_service_find(usvc.af, usvc.protocol, + &usvc.addr, usvc.port); else - svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); + svc = __ip_vs_svc_fwm_find(usvc.af, usvc.fwmark); if (cmd != IP_VS_SO_SET_ADD && (svc == NULL || svc->protocol != usvc.protocol)) { ret = -ESRCH; - goto out_drop_service; + goto out_unlock; } switch (cmd) { @@ -2210,10 +2180,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ret = -EINVAL; } -out_drop_service: - if (svc) - ip_vs_service_put(svc); - out_unlock: mutex_unlock(&__ip_vs_mutex); out_dec: @@ -2306,10 +2272,10 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get, int ret = 0; if (get->fwmark) - svc = __ip_vs_svc_fwm_get(AF_INET, get->fwmark); + svc = __ip_vs_svc_fwm_find(AF_INET, get->fwmark); else - svc = __ip_vs_service_get(AF_INET, get->protocol, &addr, - get->port); + svc = __ip_vs_service_find(AF_INET, get->protocol, &addr, + get->port); if (svc) { int count = 0; @@ -2337,7 +2303,6 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get, } count++; } - ip_vs_service_put(svc); } else ret = -ESRCH; return ret; @@ -2458,15 +2423,14 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) entry = (struct ip_vs_service_entry *)arg; addr.ip = entry->addr; if (entry->fwmark) - svc = __ip_vs_svc_fwm_get(AF_INET, entry->fwmark); + svc = __ip_vs_svc_fwm_find(AF_INET, entry->fwmark); else - svc = __ip_vs_service_get(AF_INET, entry->protocol, - &addr, entry->port); + svc = __ip_vs_service_find(AF_INET, entry->protocol, + &addr, entry->port); if (svc) { ip_vs_copy_service(entry, svc); if (copy_to_user(user, entry, sizeof(*entry)) != 0) ret = -EFAULT; - ip_vs_service_put(svc); } else ret = -ESRCH; } @@ -2733,10 +2697,12 @@ nla_put_failure: } static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, - struct nlattr *nla, int full_entry) + struct nlattr *nla, int full_entry, + struct ip_vs_service **ret_svc) { struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1]; struct nlattr *nla_af, *nla_port, *nla_fwmark, *nla_protocol, *nla_addr; + struct ip_vs_service *svc; /* Parse mandatory identifying service fields first */ if (nla == NULL || @@ -2772,12 +2738,18 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, usvc->fwmark = 0; } + if (usvc->fwmark) + svc = __ip_vs_svc_fwm_find(usvc->af, usvc->fwmark); + else + svc = __ip_vs_service_find(usvc->af, usvc->protocol, + &usvc->addr, usvc->port); + *ret_svc = svc; + /* If a full entry was requested, check for the additional fields */ if (full_entry) { struct nlattr *nla_sched, *nla_flags, *nla_timeout, *nla_netmask; struct ip_vs_flags flags; - struct ip_vs_service *svc; nla_sched = attrs[IPVS_SVC_ATTR_SCHED_NAME]; nla_flags = attrs[IPVS_SVC_ATTR_FLAGS]; @@ -2790,16 +2762,8 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, nla_memcpy(&flags, nla_flags, sizeof(flags)); /* prefill flags from service if it already exists */ - if (usvc->fwmark) - svc = __ip_vs_svc_fwm_get(usvc->af, usvc->fwmark); - else - svc = __ip_vs_service_get(usvc->af, usvc->protocol, - &usvc->addr, usvc->port); - if (svc) { + if (svc) usvc->flags = svc->flags; - ip_vs_service_put(svc); - } else - usvc->flags = 0; /* set new flags from userland */ usvc->flags = (usvc->flags & ~flags.mask) | @@ -2815,17 +2779,11 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) { struct ip_vs_service_user_kern usvc; + struct ip_vs_service *svc; int ret; - ret = ip_vs_genl_parse_service(&usvc, nla, 0); - if (ret) - return ERR_PTR(ret); - - if (usvc.fwmark) - return __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); - else - return __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); + ret = ip_vs_genl_parse_service(&usvc, nla, 0, &svc); + return ret ? ERR_PTR(ret) : svc; } static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) @@ -2916,7 +2874,6 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb, nla_put_failure: cb->args[0] = idx; - ip_vs_service_put(svc); out_err: mutex_unlock(&__ip_vs_mutex); @@ -3129,17 +3086,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) ret = ip_vs_genl_parse_service(&usvc, info->attrs[IPVS_CMD_ATTR_SERVICE], - need_full_svc); + need_full_svc, &svc); if (ret) goto out; - /* Lookup the exact service by or fwmark */ - if (usvc.fwmark == 0) - svc = __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); - else - svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); - /* Unless we're adding a new service, the service must already exist */ if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) { ret = -ESRCH; @@ -3173,6 +3123,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) break; case IPVS_CMD_DEL_SERVICE: ret = ip_vs_del_service(svc); + /* do not use svc, it can be freed */ break; case IPVS_CMD_NEW_DEST: ret = ip_vs_add_dest(svc, &udest); @@ -3191,8 +3142,6 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) } out: - if (svc) - ip_vs_service_put(svc); mutex_unlock(&__ip_vs_mutex); return ret; @@ -3238,7 +3187,6 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info) goto out_err; } else if (svc) { ret = ip_vs_genl_fill_service(msg, svc); - ip_vs_service_put(svc); if (ret) goto nla_put_failure; } else { -- cgit v1.2.3 From c22ab7816fd81efceefa96b00c4ad62cf657964b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:41:47 +0000 Subject: ethtool: Define RX n-tuple action to clear a rule Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index b67af60a8890..3350870001fe 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -492,11 +492,12 @@ struct ethtool_rx_ntuple_flow_spec { __u64 data_mask; __s32 action; -#define ETHTOOL_RXNTUPLE_ACTION_DROP -1 /* drop packet */ +#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */ +#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */ }; /** - * struct ethtool_rx_ntuple - command to set RX flow filter + * struct ethtool_rx_ntuple - command to set or clear RX flow filter * @cmd: Command number - %ETHTOOL_SRXNTUPLE * @fs: Flow filter specification */ -- cgit v1.2.3 From 6099e3dea9aaa6127cea0610533221c9e956f009 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:42:08 +0000 Subject: ethtool: Add Ethernet MAC-level filtering/steering Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 3350870001fe..8a3338ceb438 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -14,6 +14,7 @@ #define _LINUX_ETHTOOL_H #include +#include /* This should work for both 32 and 64 bit userland. */ struct ethtool_cmd { @@ -391,6 +392,7 @@ struct ethtool_rx_flow_spec { struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; struct ethtool_usrip4_spec usr_ip4_spec; + struct ethhdr ether_spec; __u8 hdata[72]; } h_u, m_u; __u64 ring_cookie; @@ -483,6 +485,7 @@ struct ethtool_rx_ntuple_flow_spec { struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; struct ethtool_usrip4_spec usr_ip4_spec; + struct ethhdr ether_spec; __u8 hdata[72]; } h_u, m_u; @@ -841,7 +844,7 @@ struct ethtool_ops { #define WAKE_MAGIC (1 << 5) #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ -/* L3-L4 network traffic flow types */ +/* L2-L4 network traffic flow types */ #define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ #define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ #define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ @@ -857,6 +860,7 @@ struct ethtool_ops { #define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ #define IPV4_FLOW 0x10 /* hash only */ #define IPV6_FLOW 0x11 /* hash only */ +#define ETHER_FLOW 0x12 /* spec only (ether_spec) */ /* L3-L4 network traffic flow hash options */ #define RXH_L2DA (1 << 1) -- cgit v1.2.3 From a77f5db361ed9953b5b749353ea2c7fed2bf8d93 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:42:17 +0000 Subject: ethtool: Allocate register dump buffer with vmalloc() Some NICs have huge register files which exceed the maximum heap allocation size. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 91ffce20c36b..dae2fd053c2b 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -815,7 +815,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) if (regs.len > reglen) regs.len = reglen; - regbuf = kmalloc(reglen, GFP_USER); + regbuf = vmalloc(reglen); if (!regbuf) return -ENOMEM; @@ -830,7 +830,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) ret = 0; out: - kfree(regbuf); + vfree(regbuf); return ret; } -- cgit v1.2.3 From 64eebcfd899a5d2ebe211a593ec13ec24630f1a3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:43:07 +0000 Subject: sfc: Add filter table management Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/Makefile | 2 +- drivers/net/sfc/efx.c | 11 ++ drivers/net/sfc/efx.h | 14 ++ drivers/net/sfc/filter.c | 445 +++++++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/filter.h | 189 ++++++++++++++++++ drivers/net/sfc/net_driver.h | 4 + drivers/net/sfc/regs.h | 14 ++ 7 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 drivers/net/sfc/filter.c create mode 100644 drivers/net/sfc/filter.h diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index 1047b19c60a5..fd9272b5873a 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile @@ -1,4 +1,4 @@ -sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o \ +sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ falcon_gmac.o falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f702f1fb63b6..4a1c93f165e6 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1357,8 +1357,17 @@ static int efx_probe_all(struct efx_nic *efx) if (rc) goto fail3; + rc = efx_probe_filters(efx); + if (rc) { + netif_err(efx, probe, efx->net_dev, + "failed to create filter tables\n"); + goto fail4; + } + return 0; + fail4: + efx_remove_channels(efx); fail3: efx_remove_port(efx); fail2: @@ -1489,6 +1498,7 @@ static void efx_stop_all(struct efx_nic *efx) static void efx_remove_all(struct efx_nic *efx) { + efx_remove_filters(efx); efx_remove_channels(efx); efx_remove_port(efx); efx_remove_nic(efx); @@ -2002,6 +2012,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) efx->mac_op->reconfigure(efx); efx_init_channels(efx); + efx_restore_filters(efx); mutex_unlock(&efx->spi_lock); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index e783c0fedfd8..f502b14eb22c 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -12,6 +12,7 @@ #define EFX_EFX_H #include "net_driver.h" +#include "filter.h" /* PCI IDs */ #define EFX_VENDID_SFC 0x1924 @@ -64,6 +65,19 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ #define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) +/* Filters */ +extern int efx_probe_filters(struct efx_nic *efx); +extern void efx_restore_filters(struct efx_nic *efx); +extern void efx_remove_filters(struct efx_nic *efx); +extern int efx_filter_insert_filter(struct efx_nic *efx, + struct efx_filter_spec *spec, + bool replace); +extern int efx_filter_remove_filter(struct efx_nic *efx, + struct efx_filter_spec *spec); +extern void efx_filter_table_clear(struct efx_nic *efx, + enum efx_filter_table_id table_id, + enum efx_filter_priority priority); + /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); extern int diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c new file mode 100644 index 000000000000..abc884d09d57 --- /dev/null +++ b/drivers/net/sfc/filter.c @@ -0,0 +1,445 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include "efx.h" +#include "filter.h" +#include "io.h" +#include "nic.h" +#include "regs.h" + +/* "Fudge factors" - difference between programmed value and actual depth. + * Due to pipelined implementation we need to program H/W with a value that + * is larger than the hop limit we want. + */ +#define FILTER_CTL_SRCH_FUDGE_WILD 3 +#define FILTER_CTL_SRCH_FUDGE_FULL 1 + +struct efx_filter_table { + u32 offset; /* address of table relative to BAR */ + unsigned size; /* number of entries */ + unsigned step; /* step between entries */ + unsigned used; /* number currently used */ + unsigned long *used_bitmap; + struct efx_filter_spec *spec; +}; + +struct efx_filter_state { + spinlock_t lock; + struct efx_filter_table table[EFX_FILTER_TABLE_COUNT]; + unsigned search_depth[EFX_FILTER_TYPE_COUNT]; +}; + +/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit + * key derived from the n-tuple. The initial LFSR state is 0xffff. */ +static u16 efx_filter_hash(u32 key) +{ + u16 tmp; + + /* First 16 rounds */ + tmp = 0x1fff ^ key >> 16; + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + tmp = tmp ^ tmp >> 9; + /* Last 16 rounds */ + tmp = tmp ^ tmp << 13 ^ key; + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + return tmp ^ tmp >> 9; +} + +/* To allow for hash collisions, filter search continues at these + * increments from the first possible entry selected by the hash. */ +static u16 efx_filter_increment(u32 key) +{ + return key * 2 - 1; +} + +static enum efx_filter_table_id +efx_filter_type_table_id(enum efx_filter_type type) +{ + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2)); + return type >> 2; +} + +static void +efx_filter_table_reset_search_depth(struct efx_filter_state *state, + enum efx_filter_table_id table_id) +{ + memset(state->search_depth + (table_id << 2), 0, + sizeof(state->search_depth[0]) << 2); +} + +static void efx_filter_push_rx_limits(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + efx_oword_t filter_ctl; + + efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); + + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_TCP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_TCP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_UDP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_UDP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + + if (state->table[EFX_FILTER_TABLE_RX_MAC].size) { + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT, + state->search_depth[EFX_FILTER_RX_MAC_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT, + state->search_depth[EFX_FILTER_RX_MAC_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + } + + efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); +} + +/* Build a filter entry and return its n-tuple key. */ +static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) +{ + u32 data3; + + switch (efx_filter_type_table_id(spec->type)) { + case EFX_FILTER_TABLE_RX_IP: { + bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL || + spec->type == EFX_FILTER_RX_UDP_WILD); + EFX_POPULATE_OWORD_7( + *filter, + FRF_BZ_RSS_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_RSS), + FRF_BZ_SCATTER_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), + FRF_BZ_TCP_UDP, is_udp, + FRF_BZ_RXQ_ID, spec->dmaq_id, + EFX_DWORD_2, spec->data[2], + EFX_DWORD_1, spec->data[1], + EFX_DWORD_0, spec->data[0]); + data3 = is_udp; + break; + } + + case EFX_FILTER_TABLE_RX_MAC: { + bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD; + EFX_POPULATE_OWORD_8( + *filter, + FRF_CZ_RMFT_RSS_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_RSS), + FRF_CZ_RMFT_SCATTER_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), + FRF_CZ_RMFT_IP_OVERRIDE, + !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP), + FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id, + FRF_CZ_RMFT_WILDCARD_MATCH, is_wild, + FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2], + FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1], + FRF_CZ_RMFT_VLAN_ID, spec->data[0]); + data3 = is_wild; + break; + } + + default: + BUG(); + } + + return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3; +} + +static bool efx_filter_equal(const struct efx_filter_spec *left, + const struct efx_filter_spec *right) +{ + if (left->type != right->type || + memcmp(left->data, right->data, sizeof(left->data))) + return false; + + return true; +} + +static int efx_filter_search(struct efx_filter_table *table, + struct efx_filter_spec *spec, u32 key, + bool for_insert, int *depth_required) +{ + unsigned hash, incr, filter_idx, depth; + struct efx_filter_spec *cmp; + + hash = efx_filter_hash(key); + incr = efx_filter_increment(key); + + for (depth = 1, filter_idx = hash & (table->size - 1); + test_bit(filter_idx, table->used_bitmap); + ++depth) { + cmp = &table->spec[filter_idx]; + if (efx_filter_equal(spec, cmp)) + goto found; + filter_idx = (filter_idx + incr) & (table->size - 1); + } + if (!for_insert) + return -ENOENT; +found: + *depth_required = depth; + return filter_idx; +} + +/** + * efx_filter_insert_filter - add or replace a filter + * @efx: NIC in which to insert the filter + * @spec: Specification for the filter + * @replace: Flag for whether the specified filter may replace a filter + * with an identical match expression and equal or lower priority + * + * On success, return the filter index within its table. + * On failure, return a negative error code. + */ +int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, + bool replace) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id = + efx_filter_type_table_id(spec->type); + struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_spec *saved_spec; + efx_oword_t filter; + int filter_idx, depth; + u32 key; + int rc; + + if (table->size == 0) + return -EINVAL; + + key = efx_filter_build(&filter, spec); + + netif_vdbg(efx, hw, efx->net_dev, + "%s: type %d search_depth=%d", __func__, spec->type, + state->search_depth[spec->type]); + + spin_lock_bh(&state->lock); + + rc = efx_filter_search(table, spec, key, true, &depth); + if (rc < 0) + goto out; + filter_idx = rc; + BUG_ON(filter_idx >= table->size); + saved_spec = &table->spec[filter_idx]; + + if (test_bit(filter_idx, table->used_bitmap)) { + /* Should we replace the existing filter? */ + if (!replace) { + rc = -EEXIST; + goto out; + } + if (spec->priority < saved_spec->priority) { + rc = -EPERM; + goto out; + } + } else { + __set_bit(filter_idx, table->used_bitmap); + ++table->used; + } + *saved_spec = *spec; + + if (state->search_depth[spec->type] < depth) { + state->search_depth[spec->type] = depth; + efx_filter_push_rx_limits(efx); + } + + efx_writeo(efx, &filter, table->offset + table->step * filter_idx); + + netif_vdbg(efx, hw, efx->net_dev, + "%s: filter type %d index %d rxq %u set", + __func__, spec->type, filter_idx, spec->dmaq_id); + +out: + spin_unlock_bh(&state->lock); + return rc; +} + +static void efx_filter_table_clear_entry(struct efx_nic *efx, + struct efx_filter_table *table, + int filter_idx) +{ + static efx_oword_t filter; + + if (test_bit(filter_idx, table->used_bitmap)) { + __clear_bit(filter_idx, table->used_bitmap); + --table->used; + memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); + + efx_writeo(efx, &filter, + table->offset + table->step * filter_idx); + } +} + +/** + * efx_filter_remove_filter - remove a filter by specification + * @efx: NIC from which to remove the filter + * @spec: Specification for the filter + * + * On success, return zero. + * On failure, return a negative error code. + */ +int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id = + efx_filter_type_table_id(spec->type); + struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_spec *saved_spec; + efx_oword_t filter; + int filter_idx, depth; + u32 key; + int rc; + + key = efx_filter_build(&filter, spec); + + spin_lock_bh(&state->lock); + + rc = efx_filter_search(table, spec, key, false, &depth); + if (rc < 0) + goto out; + filter_idx = rc; + saved_spec = &table->spec[filter_idx]; + + if (spec->priority < saved_spec->priority) { + rc = -EPERM; + goto out; + } + + efx_filter_table_clear_entry(efx, table, filter_idx); + if (table->used == 0) + efx_filter_table_reset_search_depth(state, table_id); + rc = 0; + +out: + spin_unlock_bh(&state->lock); + return rc; +} + +/** + * efx_filter_table_clear - remove filters from a table by priority + * @efx: NIC from which to remove the filters + * @table_id: Table from which to remove the filters + * @priority: Maximum priority to remove + */ +void efx_filter_table_clear(struct efx_nic *efx, + enum efx_filter_table_id table_id, + enum efx_filter_priority priority) +{ + struct efx_filter_state *state = efx->filter_state; + struct efx_filter_table *table = &state->table[table_id]; + int filter_idx; + + spin_lock_bh(&state->lock); + + for (filter_idx = 0; filter_idx < table->size; ++filter_idx) + if (table->spec[filter_idx].priority <= priority) + efx_filter_table_clear_entry(efx, table, filter_idx); + if (table->used == 0) + efx_filter_table_reset_search_depth(state, table_id); + + spin_unlock_bh(&state->lock); +} + +/* Restore filter stater after reset */ +void efx_restore_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id; + struct efx_filter_table *table; + efx_oword_t filter; + int filter_idx; + + spin_lock_bh(&state->lock); + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + table = &state->table[table_id]; + for (filter_idx = 0; filter_idx < table->size; filter_idx++) { + if (!test_bit(filter_idx, table->used_bitmap)) + continue; + efx_filter_build(&filter, &table->spec[filter_idx]); + efx_writeo(efx, &filter, + table->offset + table->step * filter_idx); + } + } + + efx_filter_push_rx_limits(efx); + + spin_unlock_bh(&state->lock); +} + +int efx_probe_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state; + struct efx_filter_table *table; + unsigned table_id; + + state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL); + if (!state) + return -ENOMEM; + efx->filter_state = state; + + spin_lock_init(&state->lock); + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + table = &state->table[EFX_FILTER_TABLE_RX_IP]; + table->offset = FR_BZ_RX_FILTER_TBL0; + table->size = FR_BZ_RX_FILTER_TBL0_ROWS; + table->step = FR_BZ_RX_FILTER_TBL0_STEP; + } + + if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) { + table = &state->table[EFX_FILTER_TABLE_RX_MAC]; + table->offset = FR_CZ_RX_MAC_FILTER_TBL0; + table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS; + table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP; + } + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + table = &state->table[table_id]; + if (table->size == 0) + continue; + table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size), + sizeof(unsigned long), + GFP_KERNEL); + if (!table->used_bitmap) + goto fail; + table->spec = vmalloc(table->size * sizeof(*table->spec)); + if (!table->spec) + goto fail; + memset(table->spec, 0, table->size * sizeof(*table->spec)); + } + + return 0; + +fail: + efx_remove_filters(efx); + return -ENOMEM; +} + +void efx_remove_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id; + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + kfree(state->table[table_id].used_bitmap); + vfree(state->table[table_id].spec); + } + kfree(state); +} diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h new file mode 100644 index 000000000000..a53319ded79c --- /dev/null +++ b/drivers/net/sfc/filter.h @@ -0,0 +1,189 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#ifndef EFX_FILTER_H +#define EFX_FILTER_H + +#include + +enum efx_filter_table_id { + EFX_FILTER_TABLE_RX_IP = 0, + EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_TABLE_COUNT, +}; + +/** + * enum efx_filter_type - type of hardware filter + * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple + * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port) + * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple + * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port) + * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID + * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address + * + * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types. + */ +enum efx_filter_type { + EFX_FILTER_RX_TCP_FULL = 0, + EFX_FILTER_RX_TCP_WILD, + EFX_FILTER_RX_UDP_FULL, + EFX_FILTER_RX_UDP_WILD, + EFX_FILTER_RX_MAC_FULL = 4, + EFX_FILTER_RX_MAC_WILD, + EFX_FILTER_TYPE_COUNT, +}; + +/** + * enum efx_filter_priority - priority of a hardware filter specification + * @EFX_FILTER_PRI_HINT: Performance hint + * @EFX_FILTER_PRI_MANUAL: Manually configured filter + * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour + */ +enum efx_filter_priority { + EFX_FILTER_PRI_HINT = 0, + EFX_FILTER_PRI_MANUAL, + EFX_FILTER_PRI_REQUIRED, +}; + +/** + * enum efx_filter_flags - flags for hardware filter specifications + * @EFX_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues. + * By default, matching packets will be delivered only to the + * specified queue. If this flag is set, they will be delivered + * to a range of queues offset from the specified queue number + * according to the indirection table. + * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving + * queue. + * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override + * any IP filter that matches the same packet. By default, IP + * filters take precedence. + * + * Currently, no flags are defined for TX filters. + */ +enum efx_filter_flags { + EFX_FILTER_FLAG_RX_RSS = 0x01, + EFX_FILTER_FLAG_RX_SCATTER = 0x02, + EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, +}; + +/** + * struct efx_filter_spec - specification for a hardware filter + * @type: Type of match to be performed, from &enum efx_filter_type + * @priority: Priority of the filter, from &enum efx_filter_priority + * @flags: Miscellaneous flags, from &enum efx_filter_flags + * @dmaq_id: Source/target queue index + * @data: Match data (type-dependent) + * + * Use the efx_filter_set_*() functions to initialise the @type and + * @data fields. + */ +struct efx_filter_spec { + u8 type:4; + u8 priority:4; + u8 flags; + u16 dmaq_id; + u32 data[3]; +}; + +/** + * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match + * @spec: Specification to initialise + * @shost: Source host address (host byte order) + * @sport: Source port (host byte order) + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec, + u32 shost, u16 sport, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_TCP_FULL; + spec->data[0] = sport | shost << 16; + spec->data[1] = dport << 16 | shost >> 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match + * @spec: Specification to initialise + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_TCP_WILD; + spec->data[0] = 0; + spec->data[1] = dport << 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match + * @spec: Specification to initialise + * @shost: Source host address (host byte order) + * @sport: Source port (host byte order) + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_udp_full(struct efx_filter_spec *spec, + u32 shost, u16 sport, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_UDP_FULL; + spec->data[0] = sport | shost << 16; + spec->data[1] = dport << 16 | shost >> 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match + * @spec: Specification to initialise + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_UDP_WILD; + spec->data[0] = dport; + spec->data[1] = 0; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_mac_full - specify RX filter with MAC full match + * @spec: Specification to initialise + * @vid: VLAN ID + * @addr: Destination MAC address + */ +static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec, + u16 vid, const u8 *addr) +{ + spec->type = EFX_FILTER_RX_MAC_FULL; + spec->data[0] = vid; + spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; + spec->data[2] = addr[0] << 8 | addr[1]; +} + +/** + * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match + * @spec: Specification to initialise + * @addr: Destination MAC address + */ +static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec, + const u8 *addr) +{ + spec->type = EFX_FILTER_RX_MAC_WILD; + spec->data[0] = 0; + spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; + spec->data[2] = addr[0] << 8 | addr[1]; +} + +#endif /* EFX_FILTER_H */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 152342dbff29..ea6691c83fba 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -619,6 +619,8 @@ union efx_multicast_hash { efx_oword_t oword[EFX_MCAST_HASH_ENTRIES / sizeof(efx_oword_t) / 8]; }; +struct efx_filter_state; + /** * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) @@ -799,6 +801,8 @@ struct efx_nic { u64 loopback_modes; void *loopback_selftest; + + struct efx_filter_state *filter_state; }; static inline int efx_dev_registered(struct efx_nic *efx) diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 18a3be428348..96430ed81c36 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h @@ -2893,6 +2893,20 @@ #define FRF_AB_XX_FORCE_SIG_WIDTH 8 #define FFE_AB_XX_FORCE_SIG_ALL_LANES 0xff +/* RX_MAC_FILTER_TBL0 */ +/* RMFT_DEST_MAC is wider than 32 bits */ +#define FRF_CZ_RMFT_DEST_MAC_LO_LBN 12 +#define FRF_CZ_RMFT_DEST_MAC_LO_WIDTH 32 +#define FRF_CZ_RMFT_DEST_MAC_HI_LBN 44 +#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH 16 + +/* TX_MAC_FILTER_TBL0 */ +/* TMFT_SRC_MAC is wider than 32 bits */ +#define FRF_CZ_TMFT_SRC_MAC_LO_LBN 12 +#define FRF_CZ_TMFT_SRC_MAC_LO_WIDTH 32 +#define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44 +#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16 + /* DRIVER_EV */ /* Sub-fields of an RX flush completion event */ #define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12 -- cgit v1.2.3 From b4187e4277b13d7bc4acc3c953b3cab0137b14b2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:43:42 +0000 Subject: sfc: Implement the ethtool RX n-tuple control functions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 118 +++++++++++++++++++++++++++++++++++++++++++++- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/siena.c | 2 +- 3 files changed, 118 insertions(+), 4 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 7f735d804801..c95328fa3ee8 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -15,6 +15,7 @@ #include "workarounds.h" #include "selftest.h" #include "efx.h" +#include "filter.h" #include "nic.h" #include "spi.h" #include "mdio_10g.h" @@ -551,9 +552,22 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) { struct efx_nic *efx = netdev_priv(net_dev); - u32 supported = efx->type->offload_features & ETH_FLAG_RXHASH; + u32 supported = (efx->type->offload_features & + (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE)); + int rc; + + rc = ethtool_op_set_flags(net_dev, data, supported); + if (rc) + return rc; + + if (!(data & ETH_FLAG_NTUPLE)) { + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, + EFX_FILTER_PRI_MANUAL); + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_PRI_MANUAL); + } - return ethtool_op_set_flags(net_dev, data, supported); + return 0; } static void efx_ethtool_self_test(struct net_device *net_dev, @@ -955,6 +969,105 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev, } } +static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, + struct ethtool_rx_ntuple *ntuple) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec; + struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec; + struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec; + struct efx_filter_spec filter; + + /* Range-check action */ + if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR || + ntuple->fs.action >= (s32)efx->n_rx_channels) + return -EINVAL; + + if (~ntuple->fs.data_mask) + return -EINVAL; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + /* Must match all of destination, */ + if (ip_mask->ip4dst | ip_mask->pdst) + return -EINVAL; + /* all or none of source, */ + if ((ip_mask->ip4src | ip_mask->psrc) && + ((__force u32)~ip_mask->ip4src | + (__force u16)~ip_mask->psrc)) + return -EINVAL; + /* and nothing else */ + if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask) + return -EINVAL; + break; + case ETHER_FLOW: + /* Must match all of destination, */ + if (!is_zero_ether_addr(mac_mask->h_dest)) + return -EINVAL; + /* all or none of VID, */ + if (ntuple->fs.vlan_tag_mask != 0xf000 && + ntuple->fs.vlan_tag_mask != 0xffff) + return -EINVAL; + /* and nothing else */ + if (!is_broadcast_ether_addr(mac_mask->h_source) || + mac_mask->h_proto != htons(0xffff)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + filter.priority = EFX_FILTER_PRI_MANUAL; + filter.flags = 0; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_tcp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_tcp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case UDP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_udp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_udp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case ETHER_FLOW: + if (ntuple->fs.vlan_tag_mask == 0xf000) + efx_filter_set_rx_mac_full(&filter, + ntuple->fs.vlan_tag & 0xfff, + mac_entry->h_dest); + else + efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest); + break; + } + + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) { + return efx_filter_remove_filter(efx, &filter); + } else { + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) + filter.dmaq_id = 0xfff; + else + filter.dmaq_id = ntuple->fs.action; + return efx_filter_insert_filter(efx, &filter, true); + } +} + static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, struct ethtool_rxfh_indir *indir) { @@ -1033,6 +1146,7 @@ const struct ethtool_ops efx_ethtool_ops = { .set_wol = efx_ethtool_set_wol, .reset = efx_ethtool_reset, .get_rxnfc = efx_ethtool_get_rxnfc, + .set_rx_ntuple = efx_ethtool_set_rx_ntuple, .get_rxfh_indir = efx_ethtool_get_rxfh_indir, .set_rxfh_indir = efx_ethtool_set_rxfh_indir, }; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b4d8efe67772..b398a4198042 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1874,7 +1874,7 @@ struct efx_nic_type falcon_b0_nic_type = { * channels */ .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, - .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH, + .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, .reset_world_flags = ETH_RESET_IRQ, }; diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 9f5368049694..2115f95ddc88 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -651,6 +651,6 @@ struct efx_nic_type siena_a0_nic_type = { .tx_dc_base = 0x88000, .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXHASH), + NETIF_F_RXHASH | NETIF_F_NTUPLE), .reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT, }; -- cgit v1.2.3 From 75abc51c29d1d1f6cde0abd003003ac61b9a9fba Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:43:53 +0000 Subject: sfc: Include RX IP filter table in register dump For backward compatibility, add it at the end. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/nic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 6c5c0cefa9d8..c4de0014441c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1849,8 +1849,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL), REGISTER_TABLE_AA(EVQ_PTR_TBL_KER), REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL), - /* The register buffer is allocated with slab, so we can't - * reasonably read all of the buffer table (up to 8MB!). + /* We can't reasonably read all of the buffer table (up to 8MB!). * However this driver will only use a few entries. Reading * 1K entries allows for some expansion of queue count and * size before we need to change the version. */ @@ -1858,7 +1857,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { A, A, 8, 1024), REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL, B, Z, 8, 1024), - /* RX_FILTER_TBL{0,1} is huge and not used by this driver */ REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0), REGISTER_TABLE_BB_CZ(TIMER_TBL), REGISTER_TABLE_BB_CZ(TX_PACE_TBL), @@ -1868,6 +1866,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { REGISTER_TABLE_CZ(MC_TREG_SMEM), /* MSIX_PBA_TABLE is not mapped */ /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */ + REGISTER_TABLE_BZ(RX_FILTER_TBL0), }; size_t efx_nic_get_regs_len(struct efx_nic *efx) -- cgit v1.2.3 From e254c274ae19888e5693ba6d32576ab03a8ae8a4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:44:10 +0000 Subject: sfc: Clean up and correct comments on efx_monitor() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 4a1c93f165e6..5be71f49a205 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -124,8 +124,9 @@ MODULE_PARM_DESC(separate_tx_channels, static int napi_weight = 64; /* This is the time (in jiffies) between invocations of the hardware - * monitor, which checks for known hardware bugs and resets the - * hardware and driver as necessary. + * monitor. On Falcon-based NICs, this will: + * - Check the on-board hardware monitor; + * - Poll the link state and reconfigure the hardware as necessary. */ unsigned int efx_monitor_interval = 1 * HZ; @@ -1545,8 +1546,7 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, * **************************************************************************/ -/* Run periodically off the general workqueue. Serialised against - * efx_reconfigure_port via the mac_lock */ +/* Run periodically off the general workqueue */ static void efx_monitor(struct work_struct *data) { struct efx_nic *efx = container_of(data, struct efx_nic, @@ -1559,16 +1559,13 @@ static void efx_monitor(struct work_struct *data) /* If the mac_lock is already held then it is likely a port * reconfiguration is already in place, which will likely do - * most of the work of check_hw() anyway. */ - if (!mutex_trylock(&efx->mac_lock)) - goto out_requeue; - if (!efx->port_enabled) - goto out_unlock; - efx->type->monitor(efx); + * most of the work of monitor() anyway. */ + if (mutex_trylock(&efx->mac_lock)) { + if (efx->port_enabled) + efx->type->monitor(efx); + mutex_unlock(&efx->mac_lock); + } -out_unlock: - mutex_unlock(&efx->mac_lock); -out_requeue: queue_delayed_work(efx->workqueue, &efx->monitor_work, efx_monitor_interval); } -- cgit v1.2.3 From 10ed61c432c013705ef6a2bebad139fc5d72e274 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Sep 2010 16:11:06 -0700 Subject: sfc: Fix build due to lack of vmalloc.h include. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/sfc/filter.c: In function ‘efx_probe_filters’: drivers/net/sfc/filter.c:422: error: implicit declaration of function ‘vmalloc’ drivers/net/sfc/filter.c:422: warning: assignment makes pointer from integer without a cast drivers/net/sfc/filter.c: In function ‘efx_remove_filters’: drivers/net/sfc/filter.c:442: error: implicit declaration of function ‘vfree’ Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index ea6691c83fba..b3f2bf436735 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "enum.h" -- cgit v1.2.3 From 73da16c28ed0724755afdb95c7dd6b166381be10 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Sep 2010 16:12:11 -0700 Subject: ethtool: Fix build due to lack of ethtool.h include. net/core/ethtool.c: In function 'ethtool_get_regs': net/core/ethtool.c:818:2: error: implicit declaration of function 'vmalloc' net/core/ethtool.c:818:9: warning: assignment makes pointer from integer without a cast net/core/ethtool.c:833:2: error: implicit declaration of function 'vfree' Signed-off-by: David S. Miller --- net/core/ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index dae2fd053c2b..7d7e572cedc7 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -19,6 +19,7 @@ #include #include #include +#include #include /* -- cgit v1.2.3 From d9fd1b2857154f1ac32ca041641ba947525ff7fa Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Mon, 20 Sep 2010 21:19:03 +0000 Subject: tmspci: fix tr%d in printk tmspci driver uses dev->name before register_netdev() and so prints tr%d in initialization messages. Fix it by using dev_info. Found and tested on real hardware. Signed-off-by: Meelis Roos Signed-off-by: David S. Miller --- drivers/net/tokenring/tmspci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index d4c7c0c0a3d6..d3e788a9cd1c 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c @@ -125,18 +125,16 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic dev->irq = pci_irq_line; dev->dma = 0; - printk("%s: %s\n", dev->name, cardinfo->name); - printk("%s: IO: %#4lx IRQ: %d\n", - dev->name, dev->base_addr, dev->irq); + dev_info(&pdev->dev, "%s\n", cardinfo->name); + dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq); tms_pci_read_eeprom(dev); - printk("%s: Ring Station Address: %pM\n", - dev->name, dev->dev_addr); + dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr); ret = tmsdev_init(dev, &pdev->dev); if (ret) { - printk("%s: unable to get memory for dev->priv.\n", dev->name); + dev_info(&pdev->dev, "unable to get memory for dev->priv.\n"); goto err_out_region; } -- cgit v1.2.3 From 66bb16de6b9a05936d1eeb20155bab008b476191 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 20 Sep 2010 20:40:24 +0000 Subject: drivers: atm: use native kernel's hex_to_bin() func Signed-off-by: Andy Shevchenko Cc: Chas Williams Cc: linux-atm-general@lists.sourceforge.net Signed-off-by: David S. Miller --- drivers/atm/horizon.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 54720baa7363..a95790452a68 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1645,10 +1645,8 @@ static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) { unsigned short d = 0; char * s = skb->data; if (*s++ == 'D') { - for (i = 0; i < 4; ++i) { - d = (d<<4) | ((*s <= '9') ? (*s - '0') : (*s - 'a' + 10)); - ++s; - } + for (i = 0; i < 4; ++i) + d = (d << 4) | hex_to_bin(*s++); PRINTK (KERN_INFO, "debug bitmap is now %hx", debug = d); } } -- cgit v1.2.3 From 82fd5b5d1ec370a50b3060418cde6a4ac8401117 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 20 Sep 2010 20:40:26 +0000 Subject: net: core: use kernel's converter from hex to bin Signed-off-by: Andy Shevchenko Signed-off-by: David S. Miller --- net/core/pktgen.c | 10 ++++------ net/core/utils.c | 13 +++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 386c2283f14e..2c0df0f95b3d 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -729,16 +729,14 @@ static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, *num = 0; for (; i < maxlen; i++) { + int value; char c; *num <<= 4; if (get_user(c, &user_buffer[i])) return -EFAULT; - if ((c >= '0') && (c <= '9')) - *num |= c - '0'; - else if ((c >= 'a') && (c <= 'f')) - *num |= c - 'a' + 10; - else if ((c >= 'A') && (c <= 'F')) - *num |= c - 'A' + 10; + value = hex_to_bin(c); + if (value >= 0) + *num |= value; else break; } diff --git a/net/core/utils.c b/net/core/utils.c index f41854470539..ec6bb322f372 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -92,18 +92,19 @@ EXPORT_SYMBOL(in_aton); static inline int xdigit2bin(char c, int delim) { + int val; + if (c == delim || c == '\0') return IN6PTON_DELIM; if (c == ':') return IN6PTON_COLON_MASK; if (c == '.') return IN6PTON_DOT; - if (c >= '0' && c <= '9') - return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0')); - if (c >= 'a' && c <= 'f') - return (IN6PTON_XDIGIT | (c - 'a' + 10)); - if (c >= 'A' && c <= 'F') - return (IN6PTON_XDIGIT | (c - 'A' + 10)); + + val = hex_to_bin(c); + if (val >= 0) + return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0); + if (delim == -1) return IN6PTON_DELIM; return IN6PTON_UNKNOWN; -- cgit v1.2.3 From 0c8a745f06f7f007ec492dc0606f5b1ea62f3da9 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 20 Sep 2010 22:56:07 +0000 Subject: sundance: Convert to DMA API Convert to DMA API Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 87 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 7dfdbee878e8..5b786ce2b5f1 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -96,6 +96,7 @@ static char *media[MAX_UNITS]; #include #include #include +#include #ifndef _COMPAT_WITH_OLD_KERNEL #include #include @@ -523,13 +524,15 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev); tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long)dev); - ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, + &ring_dma, GFP_KERNEL); if (!ring_space) goto err_out_cleardev; np->tx_ring = (struct netdev_desc *)ring_space; np->tx_ring_dma = ring_dma; - ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, + &ring_dma, GFP_KERNEL); if (!ring_space) goto err_out_unmap_tx; np->rx_ring = (struct netdev_desc *)ring_space; @@ -663,9 +666,11 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, err_out_unregister: unregister_netdev(dev); err_out_unmap_rx: - pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, + np->rx_ring, np->rx_ring_dma); err_out_unmap_tx: - pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, + np->tx_ring, np->tx_ring_dma); err_out_cleardev: pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ioaddr); @@ -1011,8 +1016,8 @@ static void init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ np->rx_ring[i].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, - PCI_DMA_FROMDEVICE)); + dma_map_single(&np->pci_dev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); } np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1063,9 +1068,8 @@ start_tx (struct sk_buff *skb, struct net_device *dev) txdesc->next_desc = 0; txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign); - txdesc->frag[0].addr = cpu_to_le32 (pci_map_single (np->pci_dev, skb->data, - skb->len, - PCI_DMA_TODEVICE)); + txdesc->frag[0].addr = cpu_to_le32(dma_map_single(&np->pci_dev->dev, + skb->data, skb->len, DMA_TO_DEVICE)); txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag); /* Increment cur_tx before tasklet_schedule() */ @@ -1109,9 +1113,9 @@ reset_tx (struct net_device *dev) skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[i].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); if (irq) dev_kfree_skb_irq (skb); else @@ -1233,9 +1237,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[entry].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq (np->tx_skbuff[entry]); np->tx_skbuff[entry] = NULL; np->tx_ring[entry].frag[0].addr = 0; @@ -1252,9 +1256,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[entry].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq (np->tx_skbuff[entry]); np->tx_skbuff[entry] = NULL; np->tx_ring[entry].frag[0].addr = 0; @@ -1334,22 +1338,18 @@ static void rx_poll(unsigned long data) if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single_for_cpu(np->pci_dev, - le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); - + dma_sync_single_for_cpu(&np->pci_dev->dev, + le32_to_cpu(desc->frag[0].addr), + np->rx_buf_sz, DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len); - pci_dma_sync_single_for_device(np->pci_dev, - le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(&np->pci_dev->dev, + le32_to_cpu(desc->frag[0].addr), + np->rx_buf_sz, DMA_FROM_DEVICE); skb_put(skb, pkt_len); } else { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + np->rx_buf_sz, DMA_FROM_DEVICE); skb_put(skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } @@ -1396,8 +1396,8 @@ static void refill_rx (struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ np->rx_ring[entry].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->data, - np->rx_buf_sz, PCI_DMA_FROMDEVICE)); + dma_map_single(&np->pci_dev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); } /* Perhaps we need not reset this field. */ np->rx_ring[entry].frag[0].length = @@ -1715,9 +1715,9 @@ static int netdev_close(struct net_device *dev) np->rx_ring[i].status = 0; skb = np->rx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->rx_ring[i].frag[0].addr), - np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->rx_buf_sz, DMA_FROM_DEVICE); dev_kfree_skb(skb); np->rx_skbuff[i] = NULL; } @@ -1727,9 +1727,9 @@ static int netdev_close(struct net_device *dev) np->tx_ring[i].next_desc = 0; skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[i].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); np->tx_skbuff[i] = NULL; } @@ -1743,17 +1743,16 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); if (dev) { - struct netdev_private *np = netdev_priv(dev); - - unregister_netdev(dev); - pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, - np->rx_ring_dma); - pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, - np->tx_ring_dma); - pci_iounmap(pdev, np->base); - pci_release_regions(pdev); - free_netdev(dev); - pci_set_drvdata(pdev, NULL); + struct netdev_private *np = netdev_priv(dev); + unregister_netdev(dev); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, + np->rx_ring, np->rx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, + np->tx_ring, np->tx_ring_dma); + pci_iounmap(pdev, np->base); + pci_release_regions(pdev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); } } -- cgit v1.2.3 From d91dc27993a366565b3ed37fc62d35cf3e10ff5d Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 20 Sep 2010 22:56:57 +0000 Subject: sundance: Handle DMA mapping errors Check for DMA mapping errors. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 5b786ce2b5f1..0df8a2c23592 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1018,6 +1018,12 @@ static void init_ring(struct net_device *dev) np->rx_ring[i].frag[0].addr = cpu_to_le32( dma_map_single(&np->pci_dev->dev, skb->data, np->rx_buf_sz, DMA_FROM_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + np->rx_ring[i].frag[0].addr)) { + dev_kfree_skb(skb); + np->rx_skbuff[i] = NULL; + break; + } np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); } np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1070,6 +1076,9 @@ start_tx (struct sk_buff *skb, struct net_device *dev) txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign); txdesc->frag[0].addr = cpu_to_le32(dma_map_single(&np->pci_dev->dev, skb->data, skb->len, DMA_TO_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + txdesc->frag[0].addr)) + goto drop_frame; txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag); /* Increment cur_tx before tasklet_schedule() */ @@ -1091,6 +1100,12 @@ start_tx (struct sk_buff *skb, struct net_device *dev) dev->name, np->cur_tx, entry); } return NETDEV_TX_OK; + +drop_frame: + dev_kfree_skb(skb); + np->tx_skbuff[entry] = NULL; + dev->stats.tx_dropped++; + return NETDEV_TX_OK; } /* Reset hardware tx and free all of tx buffers */ @@ -1398,6 +1413,12 @@ static void refill_rx (struct net_device *dev) np->rx_ring[entry].frag[0].addr = cpu_to_le32( dma_map_single(&np->pci_dev->dev, skb->data, np->rx_buf_sz, DMA_FROM_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + np->rx_ring[entry].frag[0].addr)) { + dev_kfree_skb_irq(skb); + np->rx_skbuff[entry] = NULL; + break; + } } /* Perhaps we need not reset this field. */ np->rx_ring[entry].frag[0].length = -- cgit v1.2.3 From a9478e386165477504916094ae5efb073a44fd9f Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 20 Sep 2010 22:57:49 +0000 Subject: sundance: Use dev_kfree_skb_any() helper Use dev_kfree_skb_any() helper to free the skb Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 0df8a2c23592..8b5aeca24d5d 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1116,7 +1116,6 @@ reset_tx (struct net_device *dev) void __iomem *ioaddr = np->base; struct sk_buff *skb; int i; - int irq = in_interrupt(); /* Reset tx logic, TxListPtr will be cleaned */ iowrite16 (TxDisable, ioaddr + MACCtrl1); @@ -1131,10 +1130,7 @@ reset_tx (struct net_device *dev) dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[i].frag[0].addr), skb->len, DMA_TO_DEVICE); - if (irq) - dev_kfree_skb_irq (skb); - else - dev_kfree_skb (skb); + dev_kfree_skb_any(skb); np->tx_skbuff[i] = NULL; dev->stats.tx_dropped++; } -- cgit v1.2.3 From 756e64a0b106f1a2ca96889c39ea0d48131105c0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 21 Sep 2010 06:43:54 +0000 Subject: net: constify some ppp/pptp structs Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 2 +- drivers/net/pppox.c | 4 ++-- drivers/net/pptp.c | 8 ++++---- include/linux/if_pppox.h | 2 +- net/l2tp/l2tp_ppp.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index c07de359dc07..d72fb0519a2a 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -1124,7 +1124,7 @@ static const struct proto_ops pppoe_ops = { .ioctl = pppox_ioctl, }; -static struct pppox_proto pppoe_proto = { +static const struct pppox_proto pppoe_proto = { .create = pppoe_create, .ioctl = pppoe_ioctl, .owner = THIS_MODULE, diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index d4191ef9cad1..8c0d170dabcd 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -36,9 +36,9 @@ #include -static struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1]; +static const struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1]; -int register_pppox_proto(int proto_num, struct pppox_proto *pp) +int register_pppox_proto(int proto_num, const struct pppox_proto *pp) { if (proto_num < 0 || proto_num > PX_MAX_PROTO) return -EINVAL; diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 761f0eced724..ccbc91326bfa 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -53,7 +53,7 @@ static struct pppox_sock **callid_sock; static DEFINE_SPINLOCK(chan_lock); static struct proto pptp_sk_proto __read_mostly; -static struct ppp_channel_ops pptp_chan_ops; +static const struct ppp_channel_ops pptp_chan_ops; static const struct proto_ops pptp_ops; #define PPP_LCP_ECHOREQ 0x09 @@ -628,7 +628,7 @@ static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd, return err; } -static struct ppp_channel_ops pptp_chan_ops = { +static const struct ppp_channel_ops pptp_chan_ops = { .start_xmit = pptp_xmit, .ioctl = pptp_ppp_ioctl, }; @@ -659,12 +659,12 @@ static const struct proto_ops pptp_ops = { .ioctl = pppox_ioctl, }; -static struct pppox_proto pppox_pptp_proto = { +static const struct pppox_proto pppox_pptp_proto = { .create = pptp_create, .owner = THIS_MODULE, }; -static struct gre_protocol gre_pptp_protocol = { +static const struct gre_protocol gre_pptp_protocol = { .handler = pptp_rcv, }; diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 29bcd55851eb..397921b09ef9 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -204,7 +204,7 @@ struct pppox_proto { struct module *owner; }; -extern int register_pppox_proto(int proto_num, struct pppox_proto *pp); +extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp); extern void unregister_pppox_proto(int proto_num); extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index ff954b3e94b6..39a21d0c61c4 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -1768,7 +1768,7 @@ static const struct proto_ops pppol2tp_ops = { .ioctl = pppox_ioctl, }; -static struct pppox_proto pppol2tp_proto = { +static const struct pppox_proto pppol2tp_proto = { .create = pppol2tp_create, .ioctl = pppol2tp_ioctl }; -- cgit v1.2.3 From 48daa3bb84d547828871534caa51427a3fe90748 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 21 Sep 2010 06:57:39 +0000 Subject: ipv6: addrconf.h cleanups - Use rcu_dereference_rtnl() in __in6_dev_get - kerneldoc for __in6_dev_get() and in6_dev_get() - Use inline functions instead of macros Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/addrconf.h | 63 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 45375b41a2a0..7d178a758acf 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -174,20 +174,32 @@ extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, extern int register_inet6addr_notifier(struct notifier_block *nb); extern int unregister_inet6addr_notifier(struct notifier_block *nb); -static inline struct inet6_dev * -__in6_dev_get(struct net_device *dev) +/** + * __in6_dev_get - get inet6_dev pointer from netdevice + * @dev: network device + * + * Caller must hold rcu_read_lock or RTNL, because this function + * does not take a reference on the inet6_dev. + */ +static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev) { - return rcu_dereference_check(dev->ip6_ptr, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(dev->ip6_ptr); } -static inline struct inet6_dev * -in6_dev_get(struct net_device *dev) +/** + * in6_dev_get - get inet6_dev pointer from netdevice + * @dev: network device + * + * This version can be used in any context, and takes a reference + * on the inet6_dev. Callers must use in6_dev_put() later to + * release this reference. + */ +static inline struct inet6_dev *in6_dev_get(const struct net_device *dev) { - struct inet6_dev *idev = NULL; + struct inet6_dev *idev; + rcu_read_lock(); - idev = __in6_dev_get(dev); + idev = rcu_dereference(dev->ip6_ptr); if (idev) atomic_inc(&idev->refcnt); rcu_read_unlock(); @@ -196,16 +208,21 @@ in6_dev_get(struct net_device *dev) extern void in6_dev_finish_destroy(struct inet6_dev *idev); -static inline void -in6_dev_put(struct inet6_dev *idev) +static inline void in6_dev_put(struct inet6_dev *idev) { if (atomic_dec_and_test(&idev->refcnt)) in6_dev_finish_destroy(idev); } -#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) -#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) +static inline void __in6_dev_put(struct inet6_dev *idev) +{ + atomic_dec(&idev->refcnt); +} +static inline void in6_dev_hold(struct inet6_dev *idev) +{ + atomic_inc(&idev->refcnt); +} extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp); @@ -215,9 +232,15 @@ static inline void in6_ifa_put(struct inet6_ifaddr *ifp) inet6_ifa_finish_destroy(ifp); } -#define __in6_ifa_put(ifp) atomic_dec(&(ifp)->refcnt) -#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt) +static inline void __in6_ifa_put(struct inet6_ifaddr *ifp) +{ + atomic_dec(&ifp->refcnt); +} +static inline void in6_ifa_hold(struct inet6_ifaddr *ifp) +{ + atomic_inc(&ifp->refcnt); +} /* @@ -240,23 +263,23 @@ static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) { - return (((addr->s6_addr32[0] ^ htonl(0xff020000)) | + return ((addr->s6_addr32[0] ^ htonl(0xff020000)) | addr->s6_addr32[1] | addr->s6_addr32[2] | - (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0); + (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0; } static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) { - return (((addr->s6_addr32[0] ^ htonl(0xff020000)) | + return ((addr->s6_addr32[0] ^ htonl(0xff020000)) | addr->s6_addr32[1] | addr->s6_addr32[2] | - (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0); + (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0; } extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr); static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) { - return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE)); + return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); } #ifdef CONFIG_PROC_FS -- cgit v1.2.3 From 9c44c9fa78c5a449699491f0355189e2a09c242a Mon Sep 17 00:00:00 2001 From: Sjur Braendeland Date: Tue, 21 Sep 2010 10:40:06 +0000 Subject: caif: Remove buggy re-definition of pr_debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove debugging quirk redefining pr_debug to pr_warning. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/chnl_net.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 86aac24b0225..84a422c98941 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c @@ -30,9 +30,6 @@ #define CONNECT_TIMEOUT (5 * HZ) #define CAIF_NET_DEFAULT_QUEUE_LEN 500 -#undef pr_debug -#define pr_debug pr_warn - /*This list is protected by the rtnl lock. */ static LIST_HEAD(chnl_net_list); -- cgit v1.2.3 From b04367df66eb63444d38c43d15f5e39499d85ae6 Mon Sep 17 00:00:00 2001 From: Sjur Braendeland Date: Tue, 21 Sep 2010 11:44:44 +0000 Subject: caif: Minor fixes in log prints. Use pr_debug for flow control printouts, and refine an error printout. Signed-off-by: Sjur Braendeland Signed-off-by: David S. Miller --- net/caif/caif_socket.c | 8 ++------ net/caif/cfcnfg.c | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index fd1f5df0827c..3943398f70cd 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -159,9 +159,7 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { - trace_printk("CAIF: %s(): " - "sending flow OFF (queue len = %d %d)\n", - __func__, + pr_debug("sending flow OFF (queue len = %d %d)\n", atomic_read(&cf_sk->sk.sk_rmem_alloc), sk_rcvbuf_lowwater(cf_sk)); set_rx_flow_off(cf_sk); @@ -174,9 +172,7 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { set_rx_flow_off(cf_sk); - trace_printk("CAIF: %s(): " - "sending flow OFF due to rmem_schedule\n", - __func__); + pr_debug("sending flow OFF due to rmem_schedule\n"); dbfs_atomic_inc(&cnt.num_rx_flow_off); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index ef93a131310b..41adafd18914 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -197,7 +197,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) caif_assert(adap_layer != NULL); channel_id = adap_layer->id; if (adap_layer->dn == NULL || channel_id == 0) { - pr_err("adap_layer->id is 0\n"); + pr_err("adap_layer->dn == NULL or adap_layer->id is 0\n"); ret = -ENOTCONN; goto end; } -- cgit v1.2.3 From e5e03ce1e5c6c015cabf274b24976dff408dc07f Mon Sep 17 00:00:00 2001 From: Sjur Braendeland Date: Tue, 21 Sep 2010 11:44:45 +0000 Subject: caif: Fix function NULL pointer check. Check that receive function pointer is not null before calling it. Signed-off-by: Sjur Braendeland Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 0fd01dd17c48..b99369a055d1 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -173,7 +173,7 @@ static int receive(struct sk_buff *skb, struct net_device *dev, net = dev_net(dev); pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); caifd = caif_get(dev); - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) + if (!caifd || !caifd->layer.up || !caifd->layer.up->receive) return NET_RX_DROP; if (caifd->layer.up->receive(caifd->layer.up, pkt)) -- cgit v1.2.3 From 9e2e8f14d48dbb6c31aeb739ae4fc8997b9dfe84 Mon Sep 17 00:00:00 2001 From: Sjur Braendeland Date: Tue, 21 Sep 2010 11:44:46 +0000 Subject: caif: Use default send and receive buffer size in caif_socket. CAIF sockets should use socket's default send and receive buffers sizes. Signed-off-by: Sjur Braendeland Signed-off-by: David S. Miller --- net/caif/caif_socket.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 3943398f70cd..4d918f8f4e67 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -30,9 +30,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS_NETPROTO(AF_CAIF); -#define CAIF_DEF_SNDBUF (4096*10) -#define CAIF_DEF_RCVBUF (4096*100) - /* * CAIF state is re-using the TCP socket states. * caif_states stored in sk_state reflect the state as reported by @@ -1118,10 +1115,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, /* Store the protocol */ sk->sk_protocol = (unsigned char) protocol; - /* Sendbuf dictates the amount of outbound packets not yet sent */ - sk->sk_sndbuf = CAIF_DEF_SNDBUF; - sk->sk_rcvbuf = CAIF_DEF_RCVBUF; - /* * Lock in order to try to stop someone from opening the socket * too early. -- cgit v1.2.3 From 5b92b61f3891517d18d0573ad2c939c81b59ecfe Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 22 Sep 2010 08:34:12 +0200 Subject: netfilter: nf_nat: better error handling of nf_ct_expect_related() in helpers This patch improves the situation in which the expectation table is full for conntrack NAT helpers. Basically, we give up if we don't find a place in the table instead of looping over nf_ct_expect_related() with a different port (we should only do this if it returns -EBUSY, for -EMFILE or -ESHUTDOWN I think that it's better to skip this). Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/nf_nat_amanda.c | 9 ++++++- net/ipv4/netfilter/nf_nat_ftp.c | 9 ++++++- net/ipv4/netfilter/nf_nat_h323.c | 53 +++++++++++++++++++++++++++++++++----- net/ipv4/netfilter/nf_nat_irc.c | 9 ++++++- net/ipv4/netfilter/nf_nat_sip.c | 27 ++++++++++++++++--- 5 files changed, 93 insertions(+), 14 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c index c31b87668250..0f23b3f06df0 100644 --- a/net/ipv4/netfilter/nf_nat_amanda.c +++ b/net/ipv4/netfilter/nf_nat_amanda.c @@ -44,9 +44,16 @@ static unsigned int help(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c index 86e0e84ff0a0..dc73abb3fe27 100644 --- a/net/ipv4/netfilter/nf_nat_ftp.c +++ b/net/ipv4/netfilter/nf_nat_ftp.c @@ -79,9 +79,16 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 5045196d853c..790f3160e012 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -222,13 +222,24 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Try to get a pair of ports. */ for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port); nated_port != 0; nated_port += 2) { + int ret; + rtp_exp->tuple.dst.u.udp.port = htons(nated_port); - if (nf_ct_expect_related(rtp_exp) == 0) { + ret = nf_ct_expect_related(rtp_exp); + if (ret == 0) { rtcp_exp->tuple.dst.u.udp.port = htons(nated_port + 1); - if (nf_ct_expect_related(rtcp_exp) == 0) + ret = nf_ct_expect_related(rtcp_exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nf_ct_unexpect_related(rtp_exp); + nated_port = 0; break; - nf_ct_unexpect_related(rtp_exp); + } + } else if (ret != -EBUSY) { + nated_port = 0; + break; } } @@ -284,9 +295,16 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nated_port = 0; break; + } } if (nated_port == 0) { /* No port available */ @@ -334,9 +352,16 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) break; + else if (ret != -EBUSY) { + nated_port = 0; + break; + } } if (nated_port == 0) { /* No port available */ @@ -418,9 +443,16 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nated_port = 0; break; + } } if (nated_port == 0) { /* No port available */ @@ -500,9 +532,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (nated_port = ntohs(port); nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) break; + else if (ret != -EBUSY) { + nated_port = 0; + break; + } } if (nated_port == 0) { /* No port available */ diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c index ea83a886b03e..535e1a802356 100644 --- a/net/ipv4/netfilter/nf_nat_irc.c +++ b/net/ipv4/netfilter/nf_nat_irc.c @@ -45,9 +45,16 @@ static unsigned int help(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 11b538deaaec..e40cf7816fdb 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -307,9 +307,16 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff, exp->expectfn = ip_nat_sip_expected; for (; port != 0; port++) { + int ret; + exp->tuple.dst.u.udp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) @@ -480,13 +487,25 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff, /* Try to get same pair of ports: if not, try to change them. */ for (port = ntohs(rtp_exp->tuple.dst.u.udp.port); port != 0; port += 2) { + int ret; + rtp_exp->tuple.dst.u.udp.port = htons(port); - if (nf_ct_expect_related(rtp_exp) != 0) + ret = nf_ct_expect_related(rtp_exp); + if (ret == -EBUSY) continue; + else if (ret < 0) { + port = 0; + break; + } rtcp_exp->tuple.dst.u.udp.port = htons(port + 1); - if (nf_ct_expect_related(rtcp_exp) == 0) + ret = nf_ct_expect_related(rtcp_exp); + if (ret == 0) break; - nf_ct_unexpect_related(rtp_exp); + else if (ret != -EBUSY) { + nf_ct_unexpect_related(rtp_exp); + port = 0; + break; + } } if (port == 0) -- cgit v1.2.3 From bcac0dfab191cb53b3f9b43c8014a34070ed58ff Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 22 Sep 2010 08:35:36 +0200 Subject: netfilter: ctnetlink: missing validation of CTA_EXPECT_ZONE attribute This patch adds the missing validation of the CTA_EXPECT_ZONE attribute in the ctnetlink code. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy --- net/netfilter/nf_conntrack_netlink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5bae1cd15eea..37533a30413b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1733,6 +1733,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, [CTA_EXPECT_ID] = { .type = NLA_U32 }, [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING }, + [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, }; static int -- cgit v1.2.3 From 8b008faf92ac8f7eeb65e8cd36077601af7c46db Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 22 Sep 2010 08:36:59 +0200 Subject: netfilter: ctnetlink: allow to specify the expectation flags With this patch, you can specify the expectation flags for user-space created expectations. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_conntrack_common.h | 4 ++++ include/linux/netfilter/nfnetlink_conntrack.h | 1 + include/net/netfilter/nf_conntrack_expect.h | 3 --- net/netfilter/nf_conntrack_netlink.c | 8 +++++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index 1afd18c855ec..fdc50cae861f 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -100,6 +100,10 @@ enum ip_conntrack_expect_events { IPEXP_NEW, /* new expectation */ }; +/* expectation flags */ +#define NF_CT_EXPECT_PERMANENT 0x1 +#define NF_CT_EXPECT_INACTIVE 0x2 + #ifdef __KERNEL__ struct ip_conntrack_stat { unsigned int searched; diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index 9ed534c991b9..455f0ce4f430 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -161,6 +161,7 @@ enum ctattr_expect { CTA_EXPECT_ID, CTA_EXPECT_HELP_NAME, CTA_EXPECT_ZONE, + CTA_EXPECT_FLAGS, __CTA_EXPECT_MAX }; #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1) diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 11e815084fcf..96bb42af5fae 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -67,9 +67,6 @@ struct nf_conntrack_expect_policy { #define NF_CT_EXPECT_CLASS_DEFAULT 0 -#define NF_CT_EXPECT_PERMANENT 0x1 -#define NF_CT_EXPECT_INACTIVE 0x2 - int nf_conntrack_expect_init(struct net *net); void nf_conntrack_expect_fini(struct net *net); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 37533a30413b..0804e0ef6500 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1577,6 +1577,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)); NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)); + NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)); helper = rcu_dereference(nfct_help(master)->helper); if (helper) NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name); @@ -1734,6 +1735,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { [CTA_EXPECT_ID] = { .type = NLA_U32 }, [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING }, [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, + [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, }; static int @@ -1933,9 +1935,13 @@ ctnetlink_create_expect(struct net *net, u16 zone, goto out; } + if (cda[CTA_EXPECT_FLAGS]) + exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); + else + exp->flags = 0; + exp->class = 0; exp->expectfn = NULL; - exp->flags = 0; exp->master = ct; exp->helper = NULL; memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); -- cgit v1.2.3 From 8fbca791309b5a57bec53e5fd7da912c16416ed3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 22 Sep 2010 10:00:11 +0000 Subject: sfc: Remove support for SFN4111T, SFT9001 and Falcon GMAC SFN4111T never reached production and is not being used for internal or customer testing. Since we have no production Falcon boards using the SFT9001 or the GMAC, remove support for them as well. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/Makefile | 2 +- drivers/net/sfc/falcon.c | 117 ++--------- drivers/net/sfc/falcon_boards.c | 127 +----------- drivers/net/sfc/falcon_gmac.c | 230 ---------------------- drivers/net/sfc/mac.h | 1 - drivers/net/sfc/mdio_10g.c | 30 +-- drivers/net/sfc/net_driver.h | 2 - drivers/net/sfc/phy.h | 7 +- drivers/net/sfc/tenxpress.c | 424 +++------------------------------------- drivers/net/sfc/workarounds.h | 9 +- 10 files changed, 56 insertions(+), 893 deletions(-) delete mode 100644 drivers/net/sfc/falcon_gmac.c diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index fd9272b5873a..39f7c1bc2405 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile @@ -1,5 +1,5 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ - falcon_gmac.o falcon_xmac.o mcdi_mac.o \ + falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o sfc-$(CONFIG_SFC_MTD) += mtd.o diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b398a4198042..254a599935c1 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -446,30 +446,19 @@ static void falcon_reset_macs(struct efx_nic *efx) /* It's not safe to use GLB_CTL_REG to reset the * macs, so instead use the internal MAC resets */ - if (!EFX_IS10G(efx)) { - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(1000); - - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(1000); - return; - } else { - EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); - efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); - - for (count = 0; count < 10000; count++) { - efx_reado(efx, ®, FR_AB_XM_GLB_CFG); - if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == - 0) - return; - udelay(10); - } - - netif_err(efx, hw, efx->net_dev, - "timed out waiting for XMAC core reset\n"); + EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); + efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); + + for (count = 0; count < 10000; count++) { + efx_reado(efx, ®, FR_AB_XM_GLB_CFG); + if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == + 0) + return; + udelay(10); } + + netif_err(efx, hw, efx->net_dev, + "timed out waiting for XMAC core reset\n"); } /* Mac stats will fail whist the TX fifo is draining */ @@ -508,7 +497,6 @@ static void falcon_reset_macs(struct efx_nic *efx) * are re-enabled by the caller */ efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); - /* This can run even when the GMAC is selected */ falcon_setup_xaui(efx); } @@ -646,8 +634,6 @@ static void falcon_stats_timer_func(unsigned long context) spin_unlock(&efx->stats_lock); } -static void falcon_switch_mac(struct efx_nic *efx); - static bool falcon_loopback_link_poll(struct efx_nic *efx) { struct efx_link_state old_state = efx->link_state; @@ -658,11 +644,7 @@ static bool falcon_loopback_link_poll(struct efx_nic *efx) efx->link_state.fd = true; efx->link_state.fc = efx->wanted_fc; efx->link_state.up = true; - - if (efx->loopback_mode == LOOPBACK_GMAC) - efx->link_state.speed = 1000; - else - efx->link_state.speed = 10000; + efx->link_state.speed = 10000; return !efx_link_state_equal(&efx->link_state, &old_state); } @@ -685,7 +667,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx) falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); - falcon_switch_mac(efx); + falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); rc = efx->mac_op->reconfigure(efx); @@ -835,69 +817,16 @@ out: return rc; } -static void falcon_clock_mac(struct efx_nic *efx) -{ - unsigned strap_val; - efx_oword_t nic_stat; - - /* Configure the NIC generated MAC clock correctly */ - efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); - strap_val = EFX_IS10G(efx) ? 5 : 3; - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); - efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); - } else { - /* Falcon A1 does not support 1G/10G speed switching - * and must not be used with a PHY that does. */ - BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) != - strap_val); - } -} - -static void falcon_switch_mac(struct efx_nic *efx) -{ - struct efx_mac_operations *old_mac_op = efx->mac_op; - struct falcon_nic_data *nic_data = efx->nic_data; - unsigned int stats_done_offset; - - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - WARN_ON(nic_data->stats_disable_count == 0); - - efx->mac_op = (EFX_IS10G(efx) ? - &falcon_xmac_operations : &falcon_gmac_operations); - - if (EFX_IS10G(efx)) - stats_done_offset = XgDmaDone_offset; - else - stats_done_offset = GDmaDone_offset; - nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; - - if (old_mac_op == efx->mac_op) - return; - - falcon_clock_mac(efx); - - netif_dbg(efx, hw, efx->net_dev, "selected %cMAC\n", - EFX_IS10G(efx) ? 'X' : 'G'); - /* Not all macs support a mac-level link state */ - efx->xmac_poll_required = false; - falcon_reset_macs(efx); -} - /* This call is responsible for hooking in the MAC and PHY operations */ static int falcon_probe_port(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; int rc; switch (efx->phy_type) { case PHY_TYPE_SFX7101: efx->phy_op = &falcon_sfx7101_phy_ops; break; - case PHY_TYPE_SFT9001A: - case PHY_TYPE_SFT9001B: - efx->phy_op = &falcon_sft9001_phy_ops; - break; case PHY_TYPE_QT2022C2: case PHY_TYPE_QT2025C: efx->phy_op = &falcon_qt202x_phy_ops; @@ -937,6 +866,7 @@ static int falcon_probe_port(struct efx_nic *efx) (u64)efx->stats_buffer.dma_addr, efx->stats_buffer.addr, (u64)virt_to_phys(efx->stats_buffer.addr)); + nic_data->stats_dma_done = efx->stats_buffer.addr + XgDmaDone_offset; return 0; } @@ -1201,7 +1131,7 @@ static void falcon_monitor(struct efx_nic *efx) falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); - falcon_switch_mac(efx); + falcon_reset_macs(efx); rc = efx->mac_op->reconfigure(efx); BUG_ON(rc); @@ -1210,8 +1140,7 @@ static void falcon_monitor(struct efx_nic *efx) efx_link_status_changed(efx); } - if (EFX_IS10G(efx)) - falcon_poll_xmac(efx); + falcon_poll_xmac(efx); } /* Zeroes out the SRAM contents. This routine must be called in @@ -1604,16 +1533,6 @@ static int falcon_init_nic(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); efx_writeo(efx, &temp, FR_AB_NIC_STAT); - /* Set the source of the GMAC clock */ - if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { - efx_reado(efx, &temp, FR_AB_GPIO_CTL); - EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); - efx_writeo(efx, &temp, FR_AB_GPIO_CTL); - } - - /* Select the correct MAC */ - falcon_clock_mac(efx); - rc = falcon_reset_sram(efx); if (rc) return rc; diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 3d950c2cf205..bf029b3d3b0a 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -26,7 +26,6 @@ /* Board types */ #define FALCON_BOARD_SFE4001 0x01 #define FALCON_BOARD_SFE4002 0x02 -#define FALCON_BOARD_SFN4111T 0x51 #define FALCON_BOARD_SFN4112F 0x52 /* Board temperature is about 15°C above ambient when air flow is @@ -142,17 +141,17 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask) #endif /* CONFIG_SENSORS_LM87 */ /***************************************************************************** - * Support for the SFE4001 and SFN4111T NICs. + * Support for the SFE4001 NIC. * * The SFE4001 does not power-up fully at reset due to its high power * consumption. We control its power via a PCA9539 I/O expander. - * Both boards have a MAX6647 temperature monitor which we expose to + * It also has a MAX6647 temperature monitor which we expose to * the lm90 driver. * * This also provides minimal support for reflashing the PHY, which is * initiated by resetting it with the FLASH_CFG_1 pin pulled down. * On SFE4001 rev A2 and later this is connected to the 3V3X output of - * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3. + * the IO-expander. * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually * exclusive with the network device being open. */ @@ -304,34 +303,6 @@ fail_on: return rc; } -static int sfn4111t_reset(struct efx_nic *efx) -{ - struct falcon_board *board = falcon_board(efx); - efx_oword_t reg; - - /* GPIO 3 and the GPIO register are shared with I2C, so block that */ - i2c_lock_adapter(&board->i2c_adap); - - /* Pull RST_N (GPIO 2) low then let it up again, setting the - * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the - * output enables; the output levels should always be 0 (low) - * and we rely on external pull-ups. */ - efx_reado(efx, ®, FR_AB_GPIO_CTL); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true); - efx_writeo(efx, ®, FR_AB_GPIO_CTL); - msleep(1000); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, - !!(efx->phy_mode & PHY_MODE_SPECIAL)); - efx_writeo(efx, ®, FR_AB_GPIO_CTL); - msleep(1); - - i2c_unlock_adapter(&board->i2c_adap); - - ssleep(1); - return 0; -} - static ssize_t show_phy_flash_cfg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -363,10 +334,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev, efx->phy_mode = new_mode; if (new_mode & PHY_MODE_SPECIAL) falcon_stop_nic_stats(efx); - if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) - err = sfe4001_poweron(efx); - else - err = sfn4111t_reset(efx); + err = sfe4001_poweron(efx); if (!err) err = efx_reconfigure_port(efx); if (!(new_mode & PHY_MODE_SPECIAL)) @@ -479,83 +447,6 @@ fail_hwmon: return rc; } -static int sfn4111t_check_hw(struct efx_nic *efx) -{ - s32 status; - - /* If XAUI link is up then do not monitor */ - if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) - return 0; - - /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */ - status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client, - MAX664X_REG_RSL); - if (status < 0) - return -EIO; - if (status & 0x57) - return -ERANGE; - return 0; -} - -static void sfn4111t_fini(struct efx_nic *efx) -{ - netif_info(efx, drv, efx->net_dev, "%s\n", __func__); - - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); - i2c_unregister_device(falcon_board(efx)->hwmon_client); -} - -static struct i2c_board_info sfn4111t_a0_hwmon_info = { - I2C_BOARD_INFO("max6647", 0x4e), -}; - -static struct i2c_board_info sfn4111t_r5_hwmon_info = { - I2C_BOARD_INFO("max6646", 0x4d), -}; - -static void sfn4111t_init_phy(struct efx_nic *efx) -{ - if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { - if (sft9001_wait_boot(efx) != -EINVAL) - return; - - efx->phy_mode = PHY_MODE_SPECIAL; - falcon_stop_nic_stats(efx); - } - - sfn4111t_reset(efx); - sft9001_wait_boot(efx); -} - -static int sfn4111t_init(struct efx_nic *efx) -{ - struct falcon_board *board = falcon_board(efx); - int rc; - - board->hwmon_client = - i2c_new_device(&board->i2c_adap, - (board->minor < 5) ? - &sfn4111t_a0_hwmon_info : - &sfn4111t_r5_hwmon_info); - if (!board->hwmon_client) - return -EIO; - - rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); - if (rc) - goto fail_hwmon; - - if (efx->phy_mode & PHY_MODE_SPECIAL) - /* PHY may not generate a 156.25 MHz clock and MAC - * stats fetch will fail. */ - falcon_stop_nic_stats(efx); - - return 0; - -fail_hwmon: - i2c_unregister_device(board->hwmon_client); - return rc; -} - /***************************************************************************** * Support for the SFE4002 * @@ -712,16 +603,6 @@ static const struct falcon_board_type board_types[] = { .set_id_led = sfe4002_set_id_led, .monitor = sfe4002_check_hw, }, - { - .id = FALCON_BOARD_SFN4111T, - .ref_model = "SFN4111T", - .gen_type = "100/1000/10GBASE-T adapter", - .init = sfn4111t_init, - .init_phy = sfn4111t_init_phy, - .fini = sfn4111t_fini, - .set_id_led = tenxpress_set_id_led, - .monitor = sfn4111t_check_hw, - }, { .id = FALCON_BOARD_SFN4112F, .ref_model = "SFN4112F", diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c deleted file mode 100644 index 7dadfcbd6ce7..000000000000 --- a/drivers/net/sfc/falcon_gmac.c +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#include -#include "net_driver.h" -#include "efx.h" -#include "nic.h" -#include "mac.h" -#include "regs.h" -#include "io.h" - -/************************************************************************** - * - * MAC operations - * - *************************************************************************/ - -static int falcon_reconfigure_gmac(struct efx_nic *efx) -{ - struct efx_link_state *link_state = &efx->link_state; - bool loopback, tx_fc, rx_fc, bytemode; - int if_mode; - unsigned int max_frame_len; - efx_oword_t reg; - - /* Configuration register 1 */ - tx_fc = (link_state->fc & EFX_FC_TX) || !link_state->fd; - rx_fc = !!(link_state->fc & EFX_FC_RX); - loopback = (efx->loopback_mode == LOOPBACK_GMAC); - bytemode = (link_state->speed == 1000); - - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GM_LOOP, loopback, - FRF_AB_GM_TX_EN, 1, - FRF_AB_GM_TX_FC_EN, tx_fc, - FRF_AB_GM_RX_EN, 1, - FRF_AB_GM_RX_FC_EN, rx_fc); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(10); - - /* Configuration register 2 */ - if_mode = (bytemode) ? 2 : 1; - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GM_IF_MODE, if_mode, - FRF_AB_GM_PAD_CRC_EN, 1, - FRF_AB_GM_LEN_CHK, 1, - FRF_AB_GM_FD, link_state->fd, - FRF_AB_GM_PAMBL_LEN, 0x7/*datasheet recommended */); - - efx_writeo(efx, ®, FR_AB_GM_CFG2); - udelay(10); - - /* Max frame len register */ - max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_MAX_FLEN, max_frame_len); - efx_writeo(efx, ®, FR_AB_GM_MAX_FLEN); - udelay(10); - - /* FIFO configuration register 0 */ - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GMF_FTFENREQ, 1, - FRF_AB_GMF_STFENREQ, 1, - FRF_AB_GMF_FRFENREQ, 1, - FRF_AB_GMF_SRFENREQ, 1, - FRF_AB_GMF_WTMENREQ, 1); - efx_writeo(efx, ®, FR_AB_GMF_CFG0); - udelay(10); - - /* FIFO configuration register 1 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGFRTH, 0x12, - FRF_AB_GMF_CFGXOFFRTX, 0xffff); - efx_writeo(efx, ®, FR_AB_GMF_CFG1); - udelay(10); - - /* FIFO configuration register 2 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGHWM, 0x3f, - FRF_AB_GMF_CFGLWM, 0xa); - efx_writeo(efx, ®, FR_AB_GMF_CFG2); - udelay(10); - - /* FIFO configuration register 3 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGHWMFT, 0x1c, - FRF_AB_GMF_CFGFTTH, 0x08); - efx_writeo(efx, ®, FR_AB_GMF_CFG3); - udelay(10); - - /* FIFO configuration register 4 */ - EFX_POPULATE_OWORD_1(reg, FRF_AB_GMF_HSTFLTRFRM_PAUSE, 1); - efx_writeo(efx, ®, FR_AB_GMF_CFG4); - udelay(10); - - /* FIFO configuration register 5 */ - efx_reado(efx, ®, FR_AB_GMF_CFG5); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGBYTMODE, bytemode); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !link_state->fd); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !link_state->fd); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE, 0); - efx_writeo(efx, ®, FR_AB_GMF_CFG5); - udelay(10); - - /* MAC address */ - EFX_POPULATE_OWORD_4(reg, - FRF_AB_GM_ADR_B0, efx->net_dev->dev_addr[5], - FRF_AB_GM_ADR_B1, efx->net_dev->dev_addr[4], - FRF_AB_GM_ADR_B2, efx->net_dev->dev_addr[3], - FRF_AB_GM_ADR_B3, efx->net_dev->dev_addr[2]); - efx_writeo(efx, ®, FR_AB_GM_ADR1); - udelay(10); - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GM_ADR_B4, efx->net_dev->dev_addr[1], - FRF_AB_GM_ADR_B5, efx->net_dev->dev_addr[0]); - efx_writeo(efx, ®, FR_AB_GM_ADR2); - udelay(10); - - falcon_reconfigure_mac_wrapper(efx); - - return 0; -} - -static void falcon_update_stats_gmac(struct efx_nic *efx) -{ - struct efx_mac_stats *mac_stats = &efx->mac_stats; - unsigned long old_rx_pause, old_tx_pause; - unsigned long new_rx_pause, new_tx_pause; - - /* Pause frames are erroneously counted as errors (SFC bug 3269) */ - old_rx_pause = mac_stats->rx_pause; - old_tx_pause = mac_stats->tx_pause; - - /* Update MAC stats from DMAed values */ - FALCON_STAT(efx, GRxGoodOct, rx_good_bytes); - FALCON_STAT(efx, GRxBadOct, rx_bad_bytes); - FALCON_STAT(efx, GRxMissPkt, rx_missed); - FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier); - FALCON_STAT(efx, GRxPausePkt, rx_pause); - FALCON_STAT(efx, GRxBadPkt, rx_bad); - FALCON_STAT(efx, GRxUcastPkt, rx_unicast); - FALCON_STAT(efx, GRxMcastPkt, rx_multicast); - FALCON_STAT(efx, GRxBcastPkt, rx_broadcast); - FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64); - FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64); - FALCON_STAT(efx, GRx64Pkt, rx_64); - FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127); - FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255); - FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511); - FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023); - FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx); - FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo); - FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo); - FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx); - FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo); - FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo); - FALCON_STAT(efx, GTxGoodBadOct, tx_bytes); - FALCON_STAT(efx, GTxGoodOct, tx_good_bytes); - FALCON_STAT(efx, GTxSglColPkt, tx_single_collision); - FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision); - FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision); - FALCON_STAT(efx, GTxDefPkt, tx_deferred); - FALCON_STAT(efx, GTxLateCol, tx_late_collision); - FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred); - FALCON_STAT(efx, GTxPausePkt, tx_pause); - FALCON_STAT(efx, GTxBadPkt, tx_bad); - FALCON_STAT(efx, GTxUcastPkt, tx_unicast); - FALCON_STAT(efx, GTxMcastPkt, tx_multicast); - FALCON_STAT(efx, GTxBcastPkt, tx_broadcast); - FALCON_STAT(efx, GTxLt64Pkt, tx_lt64); - FALCON_STAT(efx, GTx64Pkt, tx_64); - FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127); - FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255); - FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511); - FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023); - FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx); - FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo); - FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo); - FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp); - FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error); - FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error); - - /* Pause frames are erroneously counted as errors (SFC bug 3269) */ - new_rx_pause = mac_stats->rx_pause; - new_tx_pause = mac_stats->tx_pause; - mac_stats->rx_bad -= (new_rx_pause - old_rx_pause); - mac_stats->tx_bad -= (new_tx_pause - old_tx_pause); - - /* Derive stats that the MAC doesn't provide directly */ - mac_stats->tx_bad_bytes = - mac_stats->tx_bytes - mac_stats->tx_good_bytes; - mac_stats->tx_packets = - mac_stats->tx_lt64 + mac_stats->tx_64 + - mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 + - mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 + - mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo + - mac_stats->tx_gtjumbo; - mac_stats->tx_collision = - mac_stats->tx_single_collision + - mac_stats->tx_multiple_collision + - mac_stats->tx_excessive_collision + - mac_stats->tx_late_collision; - mac_stats->rx_bytes = - mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes; - mac_stats->rx_packets = - mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 + - mac_stats->rx_64 + mac_stats->rx_65_to_127 + - mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 + - mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx + - mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo; - mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad; - mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; -} - -static bool falcon_gmac_check_fault(struct efx_nic *efx) -{ - return false; -} - -struct efx_mac_operations falcon_gmac_operations = { - .reconfigure = falcon_reconfigure_gmac, - .update_stats = falcon_update_stats_gmac, - .check_fault = falcon_gmac_check_fault, -}; diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index f1aa5f374890..7a6e5ca0290e 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h @@ -13,7 +13,6 @@ #include "net_driver.h" -extern struct efx_mac_operations falcon_gmac_operations; extern struct efx_mac_operations falcon_xmac_operations; extern struct efx_mac_operations efx_mcdi_mac_operations; extern void falcon_reconfigure_xmac_core(struct efx_nic *efx); diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index eeaf0bd64bd3..98d946020429 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -286,46 +286,24 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) */ void efx_mdio_an_reconfigure(struct efx_nic *efx) { - bool xnp = (efx->link_advertising & ADVERTISED_10000baseT_Full - || EFX_WORKAROUND_13204(efx)); int reg; WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN)); /* Set up the base page */ - reg = ADVERTISE_CSMA; - if (efx->link_advertising & ADVERTISED_10baseT_Half) - reg |= ADVERTISE_10HALF; - if (efx->link_advertising & ADVERTISED_10baseT_Full) - reg |= ADVERTISE_10FULL; - if (efx->link_advertising & ADVERTISED_100baseT_Half) - reg |= ADVERTISE_100HALF; - if (efx->link_advertising & ADVERTISED_100baseT_Full) - reg |= ADVERTISE_100FULL; - if (xnp) - reg |= ADVERTISE_RESV; - else if (efx->link_advertising & (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full)) - reg |= ADVERTISE_NPAGE; + reg = ADVERTISE_CSMA | ADVERTISE_RESV; if (efx->link_advertising & ADVERTISED_Pause) reg |= ADVERTISE_PAUSE_CAP; if (efx->link_advertising & ADVERTISED_Asym_Pause) reg |= ADVERTISE_PAUSE_ASYM; efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); - /* Set up the (extended) next page if necessary */ - if (efx->phy_op->set_npage_adv) - efx->phy_op->set_npage_adv(efx, efx->link_advertising); + /* Set up the (extended) next page */ + efx->phy_op->set_npage_adv(efx, efx->link_advertising); /* Enable and restart AN */ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); - reg |= MDIO_AN_CTRL1_ENABLE; - if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_EXTERNAL(efx))) - reg |= MDIO_AN_CTRL1_RESTART; - if (xnp) - reg |= MDIO_AN_CTRL1_XNP; - else - reg &= ~MDIO_AN_CTRL1_XNP; + reg |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART | MDIO_AN_CTRL1_XNP; efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); } diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index b3f2bf436735..845be71bef63 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -406,8 +406,6 @@ enum efx_int_mode { }; #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI) -#define EFX_IS10G(efx) ((efx)->link_state.speed == 10000) - enum nic_state { STATE_INIT = 0, STATE_RUNNING = 1, diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 5bc26137257b..7ab07575c6d3 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -11,17 +11,12 @@ #define EFX_PHY_H /**************************************************************************** - * 10Xpress (SFX7101 and SFT9001) PHYs + * 10Xpress (SFX7101) PHY */ extern struct efx_phy_operations falcon_sfx7101_phy_ops; -extern struct efx_phy_operations falcon_sft9001_phy_ops; extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed - * to boot due to corrupt flash, or some other negative error code. */ -extern int sft9001_wait_boot(struct efx_nic *efx); - /**************************************************************************** * AMCC/Quake QT202x PHYs */ diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 6791be90c2fe..1bc6c48c96ee 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -19,10 +19,7 @@ #include "workarounds.h" #include "selftest.h" -/* We expect these MMDs to be in the package. SFT9001 also has a - * clause 22 extension MMD, but since it doesn't have all the generic - * MMD registers it is pointless to include it here. - */ +/* We expect these MMDs to be in the package. */ #define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ MDIO_DEVS_PCS | \ MDIO_DEVS_PHYXS | \ @@ -33,12 +30,6 @@ (1 << LOOPBACK_PMAPMD) | \ (1 << LOOPBACK_PHYXS_WS)) -#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \ - (1 << LOOPBACK_PHYXS) | \ - (1 << LOOPBACK_PCS) | \ - (1 << LOOPBACK_PMAPMD) | \ - (1 << LOOPBACK_PHYXS_WS)) - /* We complain if we fail to see the link partner as 10G capable this many * times in a row (must be > 1 as sampling the autoneg. registers is racy) */ @@ -50,9 +41,8 @@ #define PMA_PMD_EXT_GMII_EN_WIDTH 1 #define PMA_PMD_EXT_CLK_OUT_LBN 2 #define PMA_PMD_EXT_CLK_OUT_WIDTH 1 -#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */ +#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 -#define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */ #define PMA_PMD_EXT_CLK312_WIDTH 1 #define PMA_PMD_EXT_LPOWER_LBN 12 #define PMA_PMD_EXT_LPOWER_WIDTH 1 @@ -84,7 +74,6 @@ #define PMA_PMD_LED_FLASH (3) #define PMA_PMD_LED_MASK 3 /* All LEDs under hardware control */ -#define SFT9001_PMA_PMD_LED_DEFAULT 0 /* Green and Amber under hardware control, Red off */ #define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) @@ -98,31 +87,7 @@ #define PMA_PMD_SPEED_LBN 4 #define PMA_PMD_SPEED_WIDTH 4 -/* Cable diagnostics - SFT9001 only */ -#define PMA_PMD_CDIAG_CTRL_REG 49213 -#define CDIAG_CTRL_IMMED_LBN 15 -#define CDIAG_CTRL_BRK_LINK_LBN 12 -#define CDIAG_CTRL_IN_PROG_LBN 11 -#define CDIAG_CTRL_LEN_UNIT_LBN 10 -#define CDIAG_CTRL_LEN_METRES 1 -#define PMA_PMD_CDIAG_RES_REG 49174 -#define CDIAG_RES_A_LBN 12 -#define CDIAG_RES_B_LBN 8 -#define CDIAG_RES_C_LBN 4 -#define CDIAG_RES_D_LBN 0 -#define CDIAG_RES_WIDTH 4 -#define CDIAG_RES_OPEN 2 -#define CDIAG_RES_OK 1 -#define CDIAG_RES_INVALID 0 -/* Set of 4 registers for pairs A-D */ -#define PMA_PMD_CDIAG_LEN_REG 49175 - -/* Serdes control registers - SFT9001 only */ -#define PMA_PMD_CSERDES_CTRL_REG 64258 -/* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */ -#define PMA_PMD_CSERDES_DEFAULT 0x000f - -/* Misc register defines - SFX7101 only */ +/* Misc register defines */ #define PCS_CLOCK_CTRL_REG 55297 #define PLL312_RST_N_LBN 2 @@ -185,121 +150,17 @@ struct tenxpress_phy_data { int bad_lp_tries; }; -static ssize_t show_phy_short_reach(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - int reg; - - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR); - return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT)); -} - -static ssize_t set_phy_short_reach(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - int rc; - - rtnl_lock(); - if (efx->state != STATE_RUNNING) { - rc = -EBUSY; - } else { - efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, - MDIO_PMA_10GBT_TXPWR_SHORT, - count != 0 && *buf != '0'); - rc = efx_reconfigure_port(efx); - } - rtnl_unlock(); - - return rc < 0 ? rc : (ssize_t)count; -} - -static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, - set_phy_short_reach); - -int sft9001_wait_boot(struct efx_nic *efx) -{ - unsigned long timeout = jiffies + HZ + 1; - int boot_stat; - - for (;;) { - boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS, - PCS_BOOT_STATUS_REG); - if (boot_stat >= 0) { - netif_dbg(efx, hw, efx->net_dev, - "PHY boot status = %#x\n", boot_stat); - switch (boot_stat & - ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (3 << PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN))) { - case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (PCS_BOOT_PROGRESS_CHECKSUM << - PCS_BOOT_PROGRESS_LBN)): - case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (PCS_BOOT_PROGRESS_INIT << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): - return -EINVAL; - case ((PCS_BOOT_PROGRESS_WAIT_MDIO << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): - return (efx->phy_mode & PHY_MODE_SPECIAL) ? - 0 : -EIO; - case ((PCS_BOOT_PROGRESS_JUMP << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN)): - case ((PCS_BOOT_PROGRESS_JUMP << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN)): - return (efx->phy_mode & PHY_MODE_SPECIAL) ? - -EIO : 0; - default: - if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN)) - return -EIO; - break; - } - } - - if (time_after_eq(jiffies, timeout)) - return -ETIMEDOUT; - - msleep(50); - } -} - static int tenxpress_init(struct efx_nic *efx) { - int reg; - - if (efx->phy_type == PHY_TYPE_SFX7101) { - /* Enable 312.5 MHz clock */ - efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, - 1 << CLK312_EN_LBN); - } else { - /* Enable 312.5 MHz clock and GMII */ - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); - reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | - (1 << PMA_PMD_EXT_CLK_OUT_LBN) | - (1 << PMA_PMD_EXT_CLK312_LBN) | - (1 << PMA_PMD_EXT_ROBUST_LBN)); - - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN, - false); - } + /* Enable 312.5 MHz clock */ + efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, + 1 << CLK312_EN_LBN); /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, - 1 << PMA_PMA_LED_ACTIVITY_LBN, true); - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, - SFX7101_PMA_PMD_LED_DEFAULT); - } + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, + 1 << PMA_PMA_LED_ACTIVITY_LBN, true); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, + SFX7101_PMA_PMD_LED_DEFAULT); return 0; } @@ -307,7 +168,6 @@ static int tenxpress_init(struct efx_nic *efx) static int tenxpress_phy_probe(struct efx_nic *efx) { struct tenxpress_phy_data *phy_data; - int rc; /* Allocate phy private storage */ phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); @@ -316,42 +176,15 @@ static int tenxpress_phy_probe(struct efx_nic *efx) efx->phy_data = phy_data; phy_data->phy_mode = efx->phy_mode; - /* Create any special files */ - if (efx->phy_type == PHY_TYPE_SFT9001B) { - rc = device_create_file(&efx->pci_dev->dev, - &dev_attr_phy_short_reach); - if (rc) - goto fail; - } - - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45; - - efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45; - efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full); - } else { - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; - efx->loopback_modes = (SFT9001_LOOPBACKS | - FALCON_XMAC_LOOPBACKS | - FALCON_GMAC_LOOPBACKS); - - efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_100baseT_Full); - } + efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | + ADVERTISED_10000baseT_Full); return 0; - -fail: - kfree(efx->phy_data); - efx->phy_data = NULL; - return rc; } static int tenxpress_phy_init(struct efx_nic *efx) @@ -361,16 +194,6 @@ static int tenxpress_phy_init(struct efx_nic *efx) falcon_board(efx)->type->init_phy(efx); if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { - if (efx->phy_type == PHY_TYPE_SFT9001A) { - int reg; - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG); - reg |= (1 << PMA_PMD_EXT_SSR_LBN); - efx_mdio_write(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); - mdelay(200); - } - rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; @@ -403,7 +226,7 @@ static int tenxpress_special_reset(struct efx_nic *efx) { int rc, reg; - /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so + /* The XGMAC clock is driven from the SFX7101 312MHz clock, so * a special software reset can glitch the XGMAC sufficiently for stats * requests to fail. */ falcon_stop_nic_stats(efx); @@ -484,53 +307,18 @@ static bool sfx7101_link_ok(struct efx_nic *efx) MDIO_DEVS_PHYXS); } -static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) -{ - u32 reg; - - if (efx_phy_mode_disabled(efx->phy_mode)) - return false; - else if (efx->loopback_mode == LOOPBACK_GPHY) - return true; - else if (efx->loopback_mode) - return efx_mdio_links_ok(efx, - MDIO_DEVS_PMAPMD | - MDIO_DEVS_PHYXS); - - /* We must use the same definition of link state as LASI, - * otherwise we can miss a link state transition - */ - if (ecmd->speed == 10000) { - reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1); - return reg & MDIO_PCS_10GBRT_STAT1_BLKLK; - } else { - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG); - return reg & (1 << C22EXT_STATUS_LINK_LBN); - } -} - static void tenxpress_ext_loopback(struct efx_nic *efx) { efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1, 1 << LOOPBACK_NEAR_LBN, efx->loopback_mode == LOOPBACK_PHYXS); - if (efx->phy_type != PHY_TYPE_SFX7101) - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG, - 1 << GPHY_LOOPBACK_NEAR_LBN, - efx->loopback_mode == LOOPBACK_GPHY); } static void tenxpress_low_power(struct efx_nic *efx) { - if (efx->phy_type == PHY_TYPE_SFX7101) - efx_mdio_set_mmds_lpower( - efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), - TENXPRESS_REQUIRED_DEVS); - else - efx_mdio_set_flag( - efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, - 1 << PMA_PMD_EXT_LPOWER_LBN, - !!(efx->phy_mode & PHY_MODE_LOW_POWER)); + efx_mdio_set_mmds_lpower( + efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), + TENXPRESS_REQUIRED_DEVS); } static int tenxpress_phy_reconfigure(struct efx_nic *efx) @@ -550,12 +338,7 @@ static int tenxpress_phy_reconfigure(struct efx_nic *efx) if (loop_reset || phy_mode_change) { tenxpress_special_reset(efx); - - /* Reset XAUI if we were in 10G, and are staying - * in 10G. If we're moving into and out of 10G - * then xaui will be reset anyway */ - if (EFX_IS10G(efx)) - falcon_reset_xaui(efx); + falcon_reset_xaui(efx); } tenxpress_low_power(efx); @@ -578,29 +361,12 @@ static bool tenxpress_phy_poll(struct efx_nic *efx) { struct efx_link_state old_state = efx->link_state; - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx->link_state.up = sfx7101_link_ok(efx); - efx->link_state.speed = 10000; - efx->link_state.fd = true; - efx->link_state.fc = efx_mdio_get_pause(efx); - - sfx7101_check_bad_lp(efx, efx->link_state.up); - } else { - struct ethtool_cmd ecmd; - - /* Check the LASI alarm first */ - if (efx->loopback_mode == LOOPBACK_NONE && - !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) & - MDIO_PMA_LASI_LSALARM)) - return false; + efx->link_state.up = sfx7101_link_ok(efx); + efx->link_state.speed = 10000; + efx->link_state.fd = true; + efx->link_state.fc = efx_mdio_get_pause(efx); - tenxpress_get_settings(efx, &ecmd); - - efx->link_state.up = sft9001_link_ok(efx, &ecmd); - efx->link_state.speed = ecmd.speed; - efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL); - efx->link_state.fc = efx_mdio_get_pause(efx); - } + sfx7101_check_bad_lp(efx, efx->link_state.up); return !efx_link_state_equal(&efx->link_state, &old_state); } @@ -621,10 +387,6 @@ static void sfx7101_phy_fini(struct efx_nic *efx) static void tenxpress_phy_remove(struct efx_nic *efx) { - if (efx->phy_type == PHY_TYPE_SFT9001B) - device_remove_file(&efx->pci_dev->dev, - &dev_attr_phy_short_reach); - kfree(efx->phy_data); efx->phy_data = NULL; } @@ -647,10 +409,7 @@ void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN); break; default: - if (efx->phy_type == PHY_TYPE_SFX7101) - reg = SFX7101_PMA_PMD_LED_DEFAULT; - else - reg = SFT9001_PMA_PMD_LED_DEFAULT; + reg = SFX7101_PMA_PMD_LED_DEFAULT; break; } @@ -685,102 +444,12 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) return rc; } -static const char *const sft9001_test_names[] = { - "bist", - "cable.pairA.status", - "cable.pairB.status", - "cable.pairC.status", - "cable.pairD.status", - "cable.pairA.length", - "cable.pairB.length", - "cable.pairC.length", - "cable.pairD.length", -}; - -static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index) -{ - if (index < ARRAY_SIZE(sft9001_test_names)) - return sft9001_test_names[index]; - return NULL; -} - -static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) -{ - int rc = 0, rc2, i, ctrl_reg, res_reg; - - /* Initialise cable diagnostic results to unknown failure */ - for (i = 1; i < 9; ++i) - results[i] = -1; - - /* Run cable diagnostics; wait up to 5 seconds for them to complete. - * A cable fault is not a self-test failure, but a timeout is. */ - ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) | - (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN)); - if (flags & ETH_TEST_FL_OFFLINE) { - /* Break the link in order to run full diagnostics. We - * must reset the PHY to resume normal service. */ - ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN); - } - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG, - ctrl_reg); - i = 0; - while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) & - (1 << CDIAG_CTRL_IN_PROG_LBN)) { - if (++i == 50) { - rc = -ETIMEDOUT; - goto out; - } - msleep(100); - } - res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG); - for (i = 0; i < 4; i++) { - int pair_res = - (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH)) - & ((1 << CDIAG_RES_WIDTH) - 1); - int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_LEN_REG + i); - if (pair_res == CDIAG_RES_OK) - results[1 + i] = 1; - else if (pair_res == CDIAG_RES_INVALID) - results[1 + i] = -1; - else - results[1 + i] = -pair_res; - if (pair_res != CDIAG_RES_INVALID && - pair_res != CDIAG_RES_OPEN && - len_reg != 0xffff) - results[5 + i] = len_reg; - } - -out: - if (flags & ETH_TEST_FL_OFFLINE) { - /* Reset, running the BIST and then resuming normal service. */ - rc2 = tenxpress_special_reset(efx); - results[0] = rc2 ? -1 : 1; - if (!rc) - rc = rc2; - - efx_mdio_an_reconfigure(efx); - } - - return rc; -} - static void tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { u32 adv = 0, lpa = 0; int reg; - if (efx->phy_type != PHY_TYPE_SFX7101) { - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL); - if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) - adv |= ADVERTISED_1000baseT_Full; - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS); - if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) - lpa |= ADVERTISED_1000baseT_Half; - if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) - lpa |= ADVERTISED_1000baseT_Full; - } reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); if (reg & MDIO_AN_10GBT_CTRL_ADV10G) adv |= ADVERTISED_10000baseT_Full; @@ -790,23 +459,9 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); - if (efx->phy_type != PHY_TYPE_SFX7101) { - ecmd->supported |= (SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); - if (ecmd->speed != SPEED_10000) { - ecmd->eth_tp_mdix = - (efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XSTATUS_REG) & - (1 << PMA_PMD_XSTAT_MDIX_LBN)) - ? ETH_TP_MDI_X : ETH_TP_MDI; - } - } - /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ - if (efx->loopback_mode == LOOPBACK_GPHY) - ecmd->speed = SPEED_1000; - else if (LOOPBACK_EXTERNAL(efx)) + if (LOOPBACK_EXTERNAL(efx)) ecmd->speed = SPEED_10000; } @@ -825,16 +480,6 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) advertising & ADVERTISED_10000baseT_Full); } -static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) -{ - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL, - 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, - advertising & ADVERTISED_1000baseT_Full); - efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV10G, - advertising & ADVERTISED_10000baseT_Full); -} - struct efx_phy_operations falcon_sfx7101_phy_ops = { .probe = tenxpress_phy_probe, .init = tenxpress_phy_init, @@ -849,18 +494,3 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { .test_name = sfx7101_test_name, .run_tests = sfx7101_run_tests, }; - -struct efx_phy_operations falcon_sft9001_phy_ops = { - .probe = tenxpress_phy_probe, - .init = tenxpress_phy_init, - .reconfigure = tenxpress_phy_reconfigure, - .poll = tenxpress_phy_poll, - .fini = efx_port_dummy_op_void, - .remove = tenxpress_phy_remove, - .get_settings = tenxpress_get_settings, - .set_settings = tenxpress_set_settings, - .set_npage_adv = sft9001_set_npage_adv, - .test_alive = efx_mdio_test_alive, - .test_name = sft9001_test_name, - .run_tests = sft9001_run_tests, -}; diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 782e45a613d6..e0d63083c3a8 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -19,9 +19,7 @@ #define EFX_WORKAROUND_FALCON_A(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) #define EFX_WORKAROUND_FALCON_AB(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_B0) #define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0) -#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) -#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ - (efx)->phy_type == PHY_TYPE_SFT9001B) +#define EFX_WORKAROUND_10G(efx) 1 /* XAUI resets if link not detected */ #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS @@ -58,9 +56,4 @@ /* Leak overlength packets rather than free */ #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A -/* Need to send XNP pages for 100BaseT */ -#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 -/* Don't restart AN in near-side loopback */ -#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 - #endif /* EFX_WORKAROUNDS_H */ -- cgit v1.2.3 From 7e51b439f147670c4ddd2bf6ca4567592b5312de Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 22 Sep 2010 10:00:47 +0000 Subject: sfc: Add support for SFE4003 board and TXC43128 PHY This board never went into production, but some engineering samples are in use. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/Makefile | 3 +- drivers/net/sfc/falcon.c | 3 + drivers/net/sfc/falcon_boards.c | 80 ++++++ drivers/net/sfc/phy.h | 11 + drivers/net/sfc/txc43128_phy.c | 560 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 656 insertions(+), 1 deletion(-) create mode 100644 drivers/net/sfc/txc43128_phy.c diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index 39f7c1bc2405..ab31c7124db1 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile @@ -1,7 +1,8 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ - tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o + tenxpress.o txc43128_phy.o falcon_boards.o \ + mcdi.o mcdi_phy.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 254a599935c1..267019bb2b15 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -831,6 +831,9 @@ static int falcon_probe_port(struct efx_nic *efx) case PHY_TYPE_QT2025C: efx->phy_op = &falcon_qt202x_phy_ops; break; + case PHY_TYPE_TXC43128: + efx->phy_op = &falcon_txc_phy_ops; + break; default: netif_err(efx, probe, efx->net_dev, "Unknown PHY type %d\n", efx->phy_type); diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index bf029b3d3b0a..cfc6a5b5a477 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -26,6 +26,7 @@ /* Board types */ #define FALCON_BOARD_SFE4001 0x01 #define FALCON_BOARD_SFE4002 0x02 +#define FALCON_BOARD_SFE4003 0x03 #define FALCON_BOARD_SFN4112F 0x52 /* Board temperature is about 15°C above ambient when air flow is @@ -582,6 +583,75 @@ static int sfn4112f_init(struct efx_nic *efx) return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); } +/***************************************************************************** + * Support for the SFE4003 + * + */ +static u8 sfe4003_lm87_channel = 0x03; /* use AIN not FAN inputs */ + +static const u8 sfe4003_lm87_regs[] = { + LM87_IN_LIMITS(0, 0x67, 0x7f), /* 2.5V: 1.5V +/- 10% */ + LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */ + LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */ + LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */ + LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */ + LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS), + 0 +}; + +static struct i2c_board_info sfe4003_hwmon_info = { + I2C_BOARD_INFO("lm87", 0x2e), + .platform_data = &sfe4003_lm87_channel, +}; + +/* Board-specific LED info. */ +#define SFE4003_RED_LED_GPIO 11 +#define SFE4003_LED_ON 1 +#define SFE4003_LED_OFF 0 + +static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) +{ + struct falcon_board *board = falcon_board(efx); + + /* The LEDs were not wired to GPIOs before A3 */ + if (board->minor < 3 && board->major == 0) + return; + + falcon_txc_set_gpio_val( + efx, SFE4003_RED_LED_GPIO, + (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF); +} + +static void sfe4003_init_phy(struct efx_nic *efx) +{ + struct falcon_board *board = falcon_board(efx); + + /* The LEDs were not wired to GPIOs before A3 */ + if (board->minor < 3 && board->major == 0) + return; + + falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT); + falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF); +} + +static int sfe4003_check_hw(struct efx_nic *efx) +{ + struct falcon_board *board = falcon_board(efx); + + /* A0/A1/A2 board rev. 4003s report a temperature fault the whole time + * (bad sensor) so we mask it out. */ + unsigned alarm_mask = + (board->major == 0 && board->minor <= 2) ? + ~LM87_ALARM_TEMP_EXT1 : ~0; + + return efx_check_lm87(efx, alarm_mask); +} + +static int sfe4003_init(struct efx_nic *efx) +{ + return efx_init_lm87(efx, &sfe4003_hwmon_info, sfe4003_lm87_regs); +} + static const struct falcon_board_type board_types[] = { { .id = FALCON_BOARD_SFE4001, @@ -603,6 +673,16 @@ static const struct falcon_board_type board_types[] = { .set_id_led = sfe4002_set_id_led, .monitor = sfe4002_check_hw, }, + { + .id = FALCON_BOARD_SFE4003, + .ref_model = "SFE4003", + .gen_type = "10GBASE-CX4 adapter", + .init = sfe4003_init, + .init_phy = sfe4003_init_phy, + .fini = efx_fini_lm87, + .set_id_led = sfe4003_set_id_led, + .monitor = sfe4003_check_hw, + }, { .id = FALCON_BOARD_SFN4112F, .ref_model = "SFN4112F", diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 7ab07575c6d3..1dab609757fb 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -36,6 +36,17 @@ extern struct efx_phy_operations falcon_qt202x_phy_ops; extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state); +/**************************************************************************** +* Transwitch CX4 retimer +*/ +extern struct efx_phy_operations falcon_txc_phy_ops; + +#define TXC_GPIO_DIR_INPUT 0 +#define TXC_GPIO_DIR_OUTPUT 1 + +extern void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir); +extern void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val); + /**************************************************************************** * Siena managed PHYs */ diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c new file mode 100644 index 000000000000..351794a79215 --- /dev/null +++ b/drivers/net/sfc/txc43128_phy.c @@ -0,0 +1,560 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2006-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +/* + * Driver for Transwitch/Mysticom CX4 retimer + * see www.transwitch.com, part is TXC-43128 + */ + +#include +#include +#include "efx.h" +#include "mdio_10g.h" +#include "phy.h" +#include "nic.h" + +/* We expect these MMDs to be in the package */ +#define TXC_REQUIRED_DEVS (MDIO_DEVS_PCS | \ + MDIO_DEVS_PMAPMD | \ + MDIO_DEVS_PHYXS) + +#define TXC_LOOPBACKS ((1 << LOOPBACK_PCS) | \ + (1 << LOOPBACK_PMAPMD) | \ + (1 << LOOPBACK_PHYXS_WS)) + +/************************************************************************** + * + * Compile-time config + * + ************************************************************************** + */ +#define TXCNAME "TXC43128" +/* Total length of time we'll wait for the PHY to come out of reset (ms) */ +#define TXC_MAX_RESET_TIME 500 +/* Interval between checks (ms) */ +#define TXC_RESET_WAIT 10 +/* How long to run BIST (us) */ +#define TXC_BIST_DURATION 50 + +/************************************************************************** + * + * Register definitions + * + ************************************************************************** + */ + +/* Command register */ +#define TXC_GLRGS_GLCMD 0xc004 +/* Useful bits in command register */ +/* Lane power-down */ +#define TXC_GLCMD_L01PD_LBN 5 +#define TXC_GLCMD_L23PD_LBN 6 +/* Limited SW reset: preserves configuration but + * initiates a logic reset. Self-clearing */ +#define TXC_GLCMD_LMTSWRST_LBN 14 + +/* Signal Quality Control */ +#define TXC_GLRGS_GSGQLCTL 0xc01a +/* Enable bit */ +#define TXC_GSGQLCT_SGQLEN_LBN 15 +/* Lane selection */ +#define TXC_GSGQLCT_LNSL_LBN 13 +#define TXC_GSGQLCT_LNSL_WIDTH 2 + +/* Analog TX control */ +#define TXC_ALRGS_ATXCTL 0xc040 +/* Lane power-down */ +#define TXC_ATXCTL_TXPD3_LBN 15 +#define TXC_ATXCTL_TXPD2_LBN 14 +#define TXC_ATXCTL_TXPD1_LBN 13 +#define TXC_ATXCTL_TXPD0_LBN 12 + +/* Amplitude on lanes 0, 1 */ +#define TXC_ALRGS_ATXAMP0 0xc041 +/* Amplitude on lanes 2, 3 */ +#define TXC_ALRGS_ATXAMP1 0xc042 +/* Bit position of value for lane 0 (or 2) */ +#define TXC_ATXAMP_LANE02_LBN 3 +/* Bit position of value for lane 1 (or 3) */ +#define TXC_ATXAMP_LANE13_LBN 11 + +#define TXC_ATXAMP_1280_mV 0 +#define TXC_ATXAMP_1200_mV 8 +#define TXC_ATXAMP_1120_mV 12 +#define TXC_ATXAMP_1060_mV 14 +#define TXC_ATXAMP_0820_mV 25 +#define TXC_ATXAMP_0720_mV 26 +#define TXC_ATXAMP_0580_mV 27 +#define TXC_ATXAMP_0440_mV 28 + +#define TXC_ATXAMP_0820_BOTH \ + ((TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE02_LBN) \ + | (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE13_LBN)) + +#define TXC_ATXAMP_DEFAULT 0x6060 /* From databook */ + +/* Preemphasis on lanes 0, 1 */ +#define TXC_ALRGS_ATXPRE0 0xc043 +/* Preemphasis on lanes 2, 3 */ +#define TXC_ALRGS_ATXPRE1 0xc044 + +#define TXC_ATXPRE_NONE 0 +#define TXC_ATXPRE_DEFAULT 0x1010 /* From databook */ + +#define TXC_ALRGS_ARXCTL 0xc045 +/* Lane power-down */ +#define TXC_ARXCTL_RXPD3_LBN 15 +#define TXC_ARXCTL_RXPD2_LBN 14 +#define TXC_ARXCTL_RXPD1_LBN 13 +#define TXC_ARXCTL_RXPD0_LBN 12 + +/* Main control */ +#define TXC_MRGS_CTL 0xc340 +/* Bits in main control */ +#define TXC_MCTL_RESET_LBN 15 /* Self clear */ +#define TXC_MCTL_TXLED_LBN 14 /* 1 to show align status */ +#define TXC_MCTL_RXLED_LBN 13 /* 1 to show align status */ + +/* GPIO output */ +#define TXC_GPIO_OUTPUT 0xc346 +#define TXC_GPIO_DIR 0xc348 + +/* Vendor-specific BIST registers */ +#define TXC_BIST_CTL 0xc280 +#define TXC_BIST_TXFRMCNT 0xc281 +#define TXC_BIST_RX0FRMCNT 0xc282 +#define TXC_BIST_RX1FRMCNT 0xc283 +#define TXC_BIST_RX2FRMCNT 0xc284 +#define TXC_BIST_RX3FRMCNT 0xc285 +#define TXC_BIST_RX0ERRCNT 0xc286 +#define TXC_BIST_RX1ERRCNT 0xc287 +#define TXC_BIST_RX2ERRCNT 0xc288 +#define TXC_BIST_RX3ERRCNT 0xc289 + +/* BIST type (controls bit patter in test) */ +#define TXC_BIST_CTRL_TYPE_LBN 10 +#define TXC_BIST_CTRL_TYPE_TSD 0 /* TranSwitch Deterministic */ +#define TXC_BIST_CTRL_TYPE_CRP 1 /* CRPAT standard */ +#define TXC_BIST_CTRL_TYPE_CJP 2 /* CJPAT standard */ +#define TXC_BIST_CTRL_TYPE_TSR 3 /* TranSwitch pseudo-random */ +/* Set this to 1 for 10 bit and 0 for 8 bit */ +#define TXC_BIST_CTRL_B10EN_LBN 12 +/* Enable BIST (write 0 to disable) */ +#define TXC_BIST_CTRL_ENAB_LBN 13 +/* Stop BIST (self-clears when stop complete) */ +#define TXC_BIST_CTRL_STOP_LBN 14 +/* Start BIST (cleared by writing 1 to STOP) */ +#define TXC_BIST_CTRL_STRT_LBN 15 + +/* Mt. Diablo test configuration */ +#define TXC_MTDIABLO_CTRL 0xc34f +#define TXC_MTDIABLO_CTRL_PMA_LOOP_LBN 10 + +struct txc43128_data { + unsigned long bug10934_timer; + enum efx_phy_mode phy_mode; + enum efx_loopback_mode loopback_mode; +}; + +/* The PHY sometimes needs a reset to bring the link back up. So long as + * it reports link down, we reset it every 5 seconds. + */ +#define BUG10934_RESET_INTERVAL (5 * HZ) + +/* Perform a reset that doesn't clear configuration changes */ +static void txc_reset_logic(struct efx_nic *efx); + +/* Set the output value of a gpio */ +void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int on) +{ + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_OUTPUT, 1 << pin, on); +} + +/* Set up the GPIO direction register */ +void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir) +{ + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_DIR, 1 << pin, dir); +} + +/* Reset the PMA/PMD MMD. The documentation is explicit that this does a + * global reset (it's less clear what reset of other MMDs does).*/ +static int txc_reset_phy(struct efx_nic *efx) +{ + int rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PMAPMD, + TXC_MAX_RESET_TIME / TXC_RESET_WAIT, + TXC_RESET_WAIT); + if (rc < 0) + goto fail; + + /* Check that all the MMDs we expect are present and responding. */ + rc = efx_mdio_check_mmds(efx, TXC_REQUIRED_DEVS, 0); + if (rc < 0) + goto fail; + + return 0; + +fail: + netif_err(efx, hw, efx->net_dev, TXCNAME ": reset timed out!\n"); + return rc; +} + +/* Run a single BIST on one MMD */ +static int txc_bist_one(struct efx_nic *efx, int mmd, int test) +{ + int ctrl, bctl; + int lane; + int rc = 0; + + /* Set PMA to test into loopback using Mt Diablo reg as per app note */ + ctrl = efx_mdio_read(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL); + ctrl |= (1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN); + efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl); + + /* The BIST app. note lists these as 3 distinct steps. */ + /* Set the BIST type */ + bctl = (test << TXC_BIST_CTRL_TYPE_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* Set the BSTEN bit in the BIST Control register to enable */ + bctl |= (1 << TXC_BIST_CTRL_ENAB_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* Set the BSTRT bit in the BIST Control register */ + efx_mdio_write(efx, mmd, TXC_BIST_CTL, + bctl | (1 << TXC_BIST_CTRL_STRT_LBN)); + + /* Wait. */ + udelay(TXC_BIST_DURATION); + + /* Set the BSTOP bit in the BIST Control register */ + bctl |= (1 << TXC_BIST_CTRL_STOP_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* The STOP bit should go off when things have stopped */ + while (bctl & (1 << TXC_BIST_CTRL_STOP_LBN)) + bctl = efx_mdio_read(efx, mmd, TXC_BIST_CTL); + + /* Check all the error counts are 0 and all the frame counts are + non-zero */ + for (lane = 0; lane < 4; lane++) { + int count = efx_mdio_read(efx, mmd, TXC_BIST_RX0ERRCNT + lane); + if (count != 0) { + netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. " + "Lane %d had %d errs\n", lane, count); + rc = -EIO; + } + count = efx_mdio_read(efx, mmd, TXC_BIST_RX0FRMCNT + lane); + if (count == 0) { + netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. " + "Lane %d got 0 frames\n", lane); + rc = -EIO; + } + } + + if (rc == 0) + netif_info(efx, hw, efx->net_dev, TXCNAME": BIST pass\n"); + + /* Disable BIST */ + efx_mdio_write(efx, mmd, TXC_BIST_CTL, 0); + + /* Turn off loopback */ + ctrl &= ~(1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN); + efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl); + + return rc; +} + +static int txc_bist(struct efx_nic *efx) +{ + return txc_bist_one(efx, MDIO_MMD_PCS, TXC_BIST_CTRL_TYPE_TSD); +} + +/* Push the non-configurable defaults into the PHY. This must be + * done after every full reset */ +static void txc_apply_defaults(struct efx_nic *efx) +{ + int mctrl; + + /* Turn amplitude down and preemphasis off on the host side + * (PHY<->MAC) as this is believed less likely to upset Falcon + * and no adverse effects have been noted. It probably also + * saves a picowatt or two */ + + /* Turn off preemphasis */ + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_NONE); + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_NONE); + + /* Turn down the amplitude */ + efx_mdio_write(efx, MDIO_MMD_PHYXS, + TXC_ALRGS_ATXAMP0, TXC_ATXAMP_0820_BOTH); + efx_mdio_write(efx, MDIO_MMD_PHYXS, + TXC_ALRGS_ATXAMP1, TXC_ATXAMP_0820_BOTH); + + /* Set the line side amplitude and preemphasis to the databook + * defaults as an erratum causes them to be 0 on at least some + * PHY rev.s */ + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXPRE0, TXC_ATXPRE_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXPRE1, TXC_ATXPRE_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXAMP0, TXC_ATXAMP_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXAMP1, TXC_ATXAMP_DEFAULT); + + /* Set up the LEDs */ + mctrl = efx_mdio_read(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL); + + /* Set the Green and Red LEDs to their default modes */ + mctrl &= ~((1 << TXC_MCTL_TXLED_LBN) | (1 << TXC_MCTL_RXLED_LBN)); + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL, mctrl); + + /* Databook recommends doing this after configuration changes */ + txc_reset_logic(efx); + + falcon_board(efx)->type->init_phy(efx); +} + +static int txc43128_phy_probe(struct efx_nic *efx) +{ + struct txc43128_data *phy_data; + + /* Allocate phy private storage */ + phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + if (!phy_data) + return -ENOMEM; + efx->phy_data = phy_data; + phy_data->phy_mode = efx->phy_mode; + + efx->mdio.mmds = TXC_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + + efx->loopback_modes = TXC_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + + return 0; +} + +/* Initialisation entry point for this PHY driver */ +static int txc43128_phy_init(struct efx_nic *efx) +{ + int rc; + + rc = txc_reset_phy(efx); + if (rc < 0) + return rc; + + rc = txc_bist(efx); + if (rc < 0) + return rc; + + txc_apply_defaults(efx); + + return 0; +} + +/* Set the lane power down state in the global registers */ +static void txc_glrgs_lane_power(struct efx_nic *efx, int mmd) +{ + int pd = (1 << TXC_GLCMD_L01PD_LBN) | (1 << TXC_GLCMD_L23PD_LBN); + int ctl = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + + if (!(efx->phy_mode & PHY_MODE_LOW_POWER)) + ctl &= ~pd; + else + ctl |= pd; + + efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, ctl); +} + +/* Set the lane power down state in the analog control registers */ +static void txc_analog_lane_power(struct efx_nic *efx, int mmd) +{ + int txpd = (1 << TXC_ATXCTL_TXPD3_LBN) | (1 << TXC_ATXCTL_TXPD2_LBN) + | (1 << TXC_ATXCTL_TXPD1_LBN) | (1 << TXC_ATXCTL_TXPD0_LBN); + int rxpd = (1 << TXC_ARXCTL_RXPD3_LBN) | (1 << TXC_ARXCTL_RXPD2_LBN) + | (1 << TXC_ARXCTL_RXPD1_LBN) | (1 << TXC_ARXCTL_RXPD0_LBN); + int txctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ATXCTL); + int rxctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ARXCTL); + + if (!(efx->phy_mode & PHY_MODE_LOW_POWER)) { + txctl &= ~txpd; + rxctl &= ~rxpd; + } else { + txctl |= txpd; + rxctl |= rxpd; + } + + efx_mdio_write(efx, mmd, TXC_ALRGS_ATXCTL, txctl); + efx_mdio_write(efx, mmd, TXC_ALRGS_ARXCTL, rxctl); +} + +static void txc_set_power(struct efx_nic *efx) +{ + /* According to the data book, all the MMDs can do low power */ + efx_mdio_set_mmds_lpower(efx, + !!(efx->phy_mode & PHY_MODE_LOW_POWER), + TXC_REQUIRED_DEVS); + + /* Global register bank is in PCS, PHY XS. These control the host + * side and line side settings respectively. */ + txc_glrgs_lane_power(efx, MDIO_MMD_PCS); + txc_glrgs_lane_power(efx, MDIO_MMD_PHYXS); + + /* Analog register bank in PMA/PMD, PHY XS */ + txc_analog_lane_power(efx, MDIO_MMD_PMAPMD); + txc_analog_lane_power(efx, MDIO_MMD_PHYXS); +} + +static void txc_reset_logic_mmd(struct efx_nic *efx, int mmd) +{ + int val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + int tries = 50; + + val |= (1 << TXC_GLCMD_LMTSWRST_LBN); + efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, val); + while (tries--) { + val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + if (!(val & (1 << TXC_GLCMD_LMTSWRST_LBN))) + break; + udelay(1); + } + if (!tries) + netif_info(efx, hw, efx->net_dev, + TXCNAME " Logic reset timed out!\n"); +} + +/* Perform a logic reset. This preserves the configuration registers + * and is needed for some configuration changes to take effect */ +static void txc_reset_logic(struct efx_nic *efx) +{ + /* The data sheet claims we can do the logic reset on either the + * PCS or the PHYXS and the result is a reset of both host- and + * line-side logic. */ + txc_reset_logic_mmd(efx, MDIO_MMD_PCS); +} + +static bool txc43128_phy_read_link(struct efx_nic *efx) +{ + return efx_mdio_links_ok(efx, TXC_REQUIRED_DEVS); +} + +static int txc43128_phy_reconfigure(struct efx_nic *efx) +{ + struct txc43128_data *phy_data = efx->phy_data; + enum efx_phy_mode mode_change = efx->phy_mode ^ phy_data->phy_mode; + bool loop_change = LOOPBACK_CHANGED(phy_data, efx, TXC_LOOPBACKS); + + if (efx->phy_mode & mode_change & PHY_MODE_TX_DISABLED) { + txc_reset_phy(efx); + txc_apply_defaults(efx); + falcon_reset_xaui(efx); + mode_change &= ~PHY_MODE_TX_DISABLED; + } + + efx_mdio_transmit_disable(efx); + efx_mdio_phy_reconfigure(efx); + if (mode_change & PHY_MODE_LOW_POWER) + txc_set_power(efx); + + /* The data sheet claims this is required after every reconfiguration + * (note at end of 7.1), but we mustn't do it when nothing changes as + * it glitches the link, and reconfigure gets called on link change, + * so we get an IRQ storm on link up. */ + if (loop_change || mode_change) + txc_reset_logic(efx); + + phy_data->phy_mode = efx->phy_mode; + phy_data->loopback_mode = efx->loopback_mode; + + return 0; +} + +static void txc43128_phy_fini(struct efx_nic *efx) +{ + /* Disable link events */ + efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0); +} + +static void txc43128_phy_remove(struct efx_nic *efx) +{ + kfree(efx->phy_data); + efx->phy_data = NULL; +} + +/* Periodic callback: this exists mainly to poll link status as we + * don't use LASI interrupts */ +static bool txc43128_phy_poll(struct efx_nic *efx) +{ + struct txc43128_data *data = efx->phy_data; + bool was_up = efx->link_state.up; + + efx->link_state.up = txc43128_phy_read_link(efx); + efx->link_state.speed = 10000; + efx->link_state.fd = true; + efx->link_state.fc = efx->wanted_fc; + + if (efx->link_state.up || (efx->loopback_mode != LOOPBACK_NONE)) { + data->bug10934_timer = jiffies; + } else { + if (time_after_eq(jiffies, (data->bug10934_timer + + BUG10934_RESET_INTERVAL))) { + data->bug10934_timer = jiffies; + txc_reset_logic(efx); + } + } + + return efx->link_state.up != was_up; +} + +static const char *txc43128_test_names[] = { + "bist" +}; + +static const char *txc43128_test_name(struct efx_nic *efx, unsigned int index) +{ + if (index < ARRAY_SIZE(txc43128_test_names)) + return txc43128_test_names[index]; + return NULL; +} + +static int txc43128_run_tests(struct efx_nic *efx, int *results, unsigned flags) +{ + int rc; + + if (!(flags & ETH_TEST_FL_OFFLINE)) + return 0; + + rc = txc_reset_phy(efx); + if (rc < 0) + return rc; + + rc = txc_bist(efx); + txc_apply_defaults(efx); + results[0] = rc ? -1 : 1; + return rc; +} + +static void txc43128_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) +{ + mdio45_ethtool_gset(&efx->mdio, ecmd); +} + +struct efx_phy_operations falcon_txc_phy_ops = { + .probe = txc43128_phy_probe, + .init = txc43128_phy_init, + .reconfigure = txc43128_phy_reconfigure, + .poll = txc43128_phy_poll, + .fini = txc43128_phy_fini, + .remove = txc43128_phy_remove, + .get_settings = txc43128_get_settings, + .set_settings = efx_mdio_set_settings, + .test_alive = efx_mdio_test_alive, + .run_tests = txc43128_run_tests, + .test_name = txc43128_test_name, +}; -- cgit v1.2.3 From 40e192c3ff7b1af680b0b03e94cadf1dad5fb82e Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Tue, 21 Sep 2010 15:24:25 +0000 Subject: X.25 remove bkl in getsockname Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c1bbf9ec71f4..dc6767ecdaf8 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -909,7 +909,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, struct x25_sock *x25 = x25_sk(sk); int rc = 0; - lock_kernel(); if (peer) { if (sk->sk_state != TCP_ESTABLISHED) { rc = -ENOTCONN; @@ -923,7 +922,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, *uaddr_len = sizeof(*sx25); out: - unlock_kernel(); return rc; } -- cgit v1.2.3 From 768190fdc058cc7405330f7782782df084c25d61 Mon Sep 17 00:00:00 2001 From: andrew hendry Date: Tue, 21 Sep 2010 15:24:45 +0000 Subject: X.25 remove bkl in poll The x25_datagram_poll didn't add anything, removed it. Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller --- net/x25/af_x25.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index dc6767ecdaf8..f7af98dff409 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -925,18 +925,6 @@ out: return rc; } -static unsigned int x25_datagram_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int rc; - - lock_kernel(); - rc = datagram_poll(file, sock, wait); - unlock_kernel(); - - return rc; -} - int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int lci) { @@ -1744,7 +1732,7 @@ static const struct proto_ops x25_proto_ops = { .socketpair = sock_no_socketpair, .accept = x25_accept, .getname = x25_getname, - .poll = x25_datagram_poll, + .poll = datagram_poll, .ioctl = x25_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_x25_ioctl, -- cgit v1.2.3 From d85b9004bc2047d79248b167cc151ff9a4b509c3 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 22 Sep 2010 17:56:20 +0000 Subject: igb: clear VF_PROMISC bits instead of setting all other bits This change corrects an issue in which we were setting all flag bits except for promisc instead of clearing the promisc bits due to the incorrect use of an |= instead of an &=. Signed-off-by: Alexander Duyck Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index c4d861b557ca..fd922e7db1d5 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4659,12 +4659,13 @@ static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) u32 vmolr = rd32(E1000_VMOLR(vf)); struct vf_data_storage *vf_data = &adapter->vf_data[vf]; - vf_data->flags |= ~(IGB_VF_FLAG_UNI_PROMISC | + vf_data->flags &= ~(IGB_VF_FLAG_UNI_PROMISC | IGB_VF_FLAG_MULTI_PROMISC); vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME); if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) { vmolr |= E1000_VMOLR_MPME; + vf_data->flags |= IGB_VF_FLAG_MULTI_PROMISC; *msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST; } else { /* -- cgit v1.2.3 From 308fb39a860c816be8741fe783ae7c64e9c1af5d Mon Sep 17 00:00:00 2001 From: Joseph Gasparakis Date: Wed, 22 Sep 2010 17:56:44 +0000 Subject: igb: Add support for DH89xxCC This patch adds support for the Intel(r) DH89xxCC series. The new device will be using Intel(r) i347-AT4 and Marvell(r) M88E1322 and M88E1112 PHYs. Support for these devices has also been added here. Signed-off-by: Joseph Gasparakis Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_82575.c | 18 +++- drivers/net/igb/e1000_defines.h | 31 ++++++ drivers/net/igb/e1000_hw.h | 2 + drivers/net/igb/e1000_phy.c | 206 +++++++++++++++++++++++++++++++++++++--- drivers/net/igb/e1000_phy.h | 2 + drivers/net/igb/igb_main.c | 2 + 6 files changed, 247 insertions(+), 14 deletions(-) diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 187622f1c816..bc183f5487cb 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -132,6 +132,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_82580_SERDES: case E1000_DEV_ID_82580_SGMII: case E1000_DEV_ID_82580_COPPER_DUAL: + case E1000_DEV_ID_DH89XXCC_SGMII: + case E1000_DEV_ID_DH89XXCC_SERDES: mac->type = e1000_82580; break; case E1000_DEV_ID_I350_COPPER: @@ -282,10 +284,18 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) /* Verify phy id and set remaining function pointers */ switch (phy->id) { + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: case M88E1111_I_PHY_ID: phy->type = e1000_phy_m88; phy->ops.get_phy_info = igb_get_phy_info_m88; - phy->ops.get_cable_length = igb_get_cable_length_m88; + + if (phy->id == I347AT4_E_PHY_ID || + phy->id == M88E1112_E_PHY_ID) + phy->ops.get_cable_length = igb_get_cable_length_m88_gen2; + else + phy->ops.get_cable_length = igb_get_cable_length_m88; + phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: @@ -1058,7 +1068,11 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) } switch (hw->phy.type) { case e1000_phy_m88: - ret_val = igb_copper_link_setup_m88(hw); + if (hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) + ret_val = igb_copper_link_setup_m88_gen2(hw); + else + ret_val = igb_copper_link_setup_m88(hw); break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index bbd2ec308eb0..62222796a8b3 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -634,6 +634,8 @@ * E = External */ #define M88E1111_I_PHY_ID 0x01410CC0 +#define M88E1112_E_PHY_ID 0x01410C90 +#define I347AT4_E_PHY_ID 0x01410DC0 #define IGP03E1000_E_PHY_ID 0x02A80390 #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 @@ -702,6 +704,35 @@ #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ +/* Intel i347-AT4 Registers */ + +#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */ +#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */ +#define I347AT4_PAGE_SELECT 0x16 + +/* i347-AT4 Extended PHY Specific Control Register */ + +/* + * Number of times we will attempt to autonegotiate before downshifting if we + * are the master + */ +#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800 +#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000 +#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000 +#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000 +#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000 +#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000 +#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000 +#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000 +#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000 +#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000 + +/* i347-AT4 PHY Cable Diagnostics Control */ +#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */ + +/* Marvell 1112 only registers */ +#define M88E1112_VCT_DSP_DISTANCE 0x001A + /* M88EC018 Rev 2 specific DownShift settings */ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index cb8db78b1a05..c0b017f8d782 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -54,6 +54,8 @@ struct e1000_hw; #define E1000_DEV_ID_82580_SERDES 0x1510 #define E1000_DEV_ID_82580_SGMII 0x1511 #define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 +#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436 +#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438 #define E1000_DEV_ID_I350_COPPER 0x1521 #define E1000_DEV_ID_I350_FIBER 0x1522 #define E1000_DEV_ID_I350_SERDES 0x1523 diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index cf1f32300923..ddd036a78999 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -569,6 +569,89 @@ out: return ret_val; } +/** + * igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link + * @hw: pointer to the HW structure + * + * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's. + * Also enables and sets the downshift parameters. + **/ +s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_data; + + if (phy->reset_disable) { + ret_val = 0; + goto out; + } + + /* Enable CRS on Tx. This must be set for half-duplex operation. */ + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if (ret_val) + goto out; + + /* + * Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + + switch (phy->mdix) { + case 1: + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; + break; + case 2: + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + /* M88E1112 does not support this mode) */ + if (phy->id != M88E1112_E_PHY_ID) { + phy_data |= M88E1000_PSCR_AUTO_X_1000T; + break; + } + case 0: + default: + phy_data |= M88E1000_PSCR_AUTO_X_MODE; + break; + } + + /* + * Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; + if (phy->disable_polarity_correction == 1) + phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + + /* Enable downshift and setting it to X6 */ + phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK; + phy_data |= I347AT4_PSCR_DOWNSHIFT_6X; + phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE; + + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + if (ret_val) + goto out; + + /* Commit the changes. */ + ret_val = igb_phy_sw_reset(hw); + if (ret_val) { + hw_dbg("Error committing the PHY changes\n"); + goto out; + } + +out: + return ret_val; +} + /** * igb_copper_link_setup_igp - Setup igp PHY's for copper link * @hw: pointer to the HW structure @@ -1124,18 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; if (!link) { - /* - * We didn't get link. - * Reset the DSP and cross our fingers. - */ - ret_val = phy->ops.write_reg(hw, - M88E1000_PHY_PAGE_SELECT, - 0x001d); - if (ret_val) - goto out; - ret_val = igb_phy_reset_dsp(hw); - if (ret_val) - goto out; + if (hw->phy.type != e1000_phy_m88 || + hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) { + hw_dbg("Link taking longer than expected.\n"); + } else { + + /* + * We didn't get link. + * Reset the DSP and cross our fingers. + */ + ret_val = phy->ops.write_reg(hw, + M88E1000_PHY_PAGE_SELECT, + 0x001d); + if (ret_val) + goto out; + ret_val = igb_phy_reset_dsp(hw); + if (ret_val) + goto out; + } } /* Try once more */ @@ -1145,6 +1235,11 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; } + if (hw->phy.type != e1000_phy_m88 || + hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) + goto out; + ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1557,6 +1652,93 @@ out: return ret_val; } +s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_data, phy_data2, index, default_page, is_cm; + + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + /* Remember the original page select and set it to 7 */ + ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, + &default_page); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07); + if (ret_val) + goto out; + + /* Get cable length from PHY Cable Diagnostics Control Reg */ + ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr), + &phy_data); + if (ret_val) + goto out; + + /* Check if the unit of cable length is meters or cm */ + ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2); + if (ret_val) + goto out; + + is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT); + + /* Populate the phy structure with cable length in meters */ + phy->min_cable_length = phy_data / (is_cm ? 100 : 1); + phy->max_cable_length = phy_data / (is_cm ? 100 : 1); + phy->cable_length = phy_data / (is_cm ? 100 : 1); + + /* Reset the page selec to its original value */ + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, + default_page); + if (ret_val) + goto out; + break; + case M88E1112_E_PHY_ID: + /* Remember the original page select and set it to 5 */ + ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, + &default_page); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE, + &phy_data); + if (ret_val) + goto out; + + index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT; + if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) { + ret_val = -E1000_ERR_PHY; + goto out; + } + + phy->min_cable_length = e1000_m88_cable_length_table[index]; + phy->max_cable_length = e1000_m88_cable_length_table[index + 1]; + + phy->cable_length = (phy->min_cable_length + + phy->max_cable_length) / 2; + + /* Reset the page select to its original value */ + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, + default_page); + if (ret_val) + goto out; + + break; + default: + ret_val = -E1000_ERR_PHY; + goto out; + } + +out: + return ret_val; +} + /** * igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY * @hw: pointer to the HW structure diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h index 565a6dbb3714..2cc117705a31 100644 --- a/drivers/net/igb/e1000_phy.h +++ b/drivers/net/igb/e1000_phy.h @@ -45,9 +45,11 @@ s32 igb_check_downshift(struct e1000_hw *hw); s32 igb_check_reset_block(struct e1000_hw *hw); s32 igb_copper_link_setup_igp(struct e1000_hw *hw); s32 igb_copper_link_setup_m88(struct e1000_hw *hw); +s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw); s32 igb_get_cable_length_m88(struct e1000_hw *hw); +s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw); s32 igb_get_cable_length_igp_2(struct e1000_hw *hw); s32 igb_get_phy_id(struct e1000_hw *hw); s32 igb_get_phy_info_igp(struct e1000_hw *hw); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index fd922e7db1d5..61892b80d7ad 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -71,6 +71,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 }, -- cgit v1.2.3 From 7b872a55c40b7e6f5e257c252f96dde911bd7b2f Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Wed, 22 Sep 2010 17:57:58 +0000 Subject: e1000/e1000e/igb/ixgb/ixgbe: set NETIF_F_HIGHDMA for VLAN feature flags If the netdev->features is set with NETIF_F_HIGHDMA, we should set the corresponding netdev->vlan_features as well to allow VLAN netdev created on top of the real netdev to be able to also benefit from HIGHDMA on 32bit system, reducing the performance hit that is caused by __skb_linearize(), particularly for large send. This is fixed in this patch for all Intel e1000, e1000e, igb, ixgbe, and ixgbe drivers since this should be beneficial to all devices supported by these drivers. Signed-off-by: Yi Zou Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 4 +++- drivers/net/e1000e/netdev.c | 4 +++- drivers/net/igb/igb_main.c | 4 +++- drivers/net/ixgb/ixgb_main.c | 4 +++- drivers/net/ixgbe/ixgbe_main.c | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8d9269d12a67..a1daceadca84 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -988,8 +988,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, (hw->mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_HW_CSUM; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index e2c7e0d767b1..4630bad52e74 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5683,8 +5683,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_HW_CSUM; netdev->vlan_features |= NETIF_F_SG; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (e1000e_enable_mng_pass_thru(&adapter->hw)) adapter->flags |= FLAG_MNG_PT_ENABLED; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 61892b80d7ad..f915e9cb302e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1858,8 +1858,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_IPV6_CSUM; netdev->vlan_features |= NETIF_F_SG; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (hw->mac.type >= e1000_82576) netdev->features |= NETIF_F_SCTP_CSUM; diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index c2f6e71e1181..80e62578ffa0 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -446,8 +446,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_TSO; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } /* make sure the EEPROM is good */ diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d03eef96c0ba..0ec4ef2d819e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6842,8 +6842,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_FCOE_MTU; } #endif /* IXGBE_FCOE */ - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; -- cgit v1.2.3 From 5cf42fcda0fdddfe7f5ea8629cb7b820bf7e91ab Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 22 Sep 2010 18:22:17 +0000 Subject: e1000: use work queues E1000 is using several timers that in a follow on patch will need to acquire the rtnl_lock in order to be safe. This patch moves the timer bodies into work queues which will allow the next patch to add rtnl_lock. Signed-off-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000.h | 3 +++ drivers/net/e1000/e1000_main.c | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 99288b95aead..a881dd0093bd 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -310,6 +310,9 @@ struct e1000_adapter { int need_ioport; bool discarding; + + struct work_struct fifo_stall_task; + struct work_struct phy_info_task; }; enum e1000_state_t { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index a1daceadca84..5b4c6c061414 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -123,8 +123,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring); static void e1000_set_rx_mode(struct net_device *netdev); static void e1000_update_phy_info(unsigned long data); +static void e1000_update_phy_info_task(struct work_struct *work); static void e1000_watchdog(unsigned long data); static void e1000_82547_tx_fifo_stall(unsigned long data); +static void e1000_82547_tx_fifo_stall_task(struct work_struct *work); static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev); @@ -1047,7 +1049,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->phy_info_timer.function = e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long)adapter; + INIT_WORK(&adapter->fifo_stall_task, e1000_82547_tx_fifo_stall_task); INIT_WORK(&adapter->reset_task, e1000_reset_task); + INIT_WORK(&adapter->phy_info_task, e1000_update_phy_info_task); e1000_check_options(adapter); @@ -2234,6 +2238,14 @@ static void e1000_set_rx_mode(struct net_device *netdev) static void e1000_update_phy_info(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *)data; + schedule_work(&adapter->phy_info_task); +} + +static void e1000_update_phy_info_task(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, + phy_info_task); struct e1000_hw *hw = &adapter->hw; e1000_phy_get_info(hw, &adapter->phy_info); } @@ -2242,10 +2254,21 @@ static void e1000_update_phy_info(unsigned long data) * e1000_82547_tx_fifo_stall - Timer Call-back * @data: pointer to adapter cast into an unsigned long **/ - static void e1000_82547_tx_fifo_stall(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *)data; + schedule_work(&adapter->fifo_stall_task); +} + +/** + * e1000_82547_tx_fifo_stall_task - task to complete work + * @work: work struct contained inside adapter struct + **/ +static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, + fifo_stall_task); struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; u32 tctl; -- cgit v1.2.3 From 338c15e470d818f215d651505dc169d4e92f36a4 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 22 Sep 2010 18:22:42 +0000 Subject: e1000: fix occasional panic on unload Net drivers in general have an issue where timers fired by mod_timer or work threads with schedule_work are running outside of the rtnl_lock. With no other lock protection these routines are vulnerable to races with driver unload or reset paths. The longer term solution to this might be a redesign with safer locks being taken in the driver to guarantee no reentrance, but for now a safe and effective fix is to take the rtnl_lock in these routines. Signed-off-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5b4c6c061414..c88439deb7d8 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -521,8 +521,21 @@ void e1000_down(struct e1000_adapter *adapter) e1000_clean_all_rx_rings(adapter); } +void e1000_reinit_safe(struct e1000_adapter *adapter) +{ + while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) + msleep(1); + rtnl_lock(); + e1000_down(adapter); + e1000_up(adapter); + rtnl_unlock(); + clear_bit(__E1000_RESETTING, &adapter->flags); +} + void e1000_reinit_locked(struct e1000_adapter *adapter) { + /* if rtnl_lock is not held the call path is bogus */ + ASSERT_RTNL(); WARN_ON(in_interrupt()); while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) msleep(1); @@ -2247,7 +2260,10 @@ static void e1000_update_phy_info_task(struct work_struct *work) struct e1000_adapter, phy_info_task); struct e1000_hw *hw = &adapter->hw; + + rtnl_lock(); e1000_phy_get_info(hw, &adapter->phy_info); + rtnl_unlock(); } /** @@ -2273,6 +2289,7 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) struct net_device *netdev = adapter->netdev; u32 tctl; + rtnl_lock(); if (atomic_read(&adapter->tx_fifo_stall)) { if ((er32(TDT) == er32(TDH)) && (er32(TDFT) == er32(TDFH)) && @@ -2293,6 +2310,7 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1); } } + rtnl_unlock(); } bool e1000_has_link(struct e1000_adapter *adapter) @@ -3160,7 +3178,7 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, reset_task); - e1000_reinit_locked(adapter); + e1000_reinit_safe(adapter); } /** -- cgit v1.2.3 From 6a08d194ee40806e0ccd5f36ed768e64cbfc979f Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 22 Sep 2010 18:23:05 +0000 Subject: e1000: use GRO for receive E1000 can benefit from calling the GRO receive functions. Signed-off-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c88439deb7d8..796523f2c6b1 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3664,13 +3664,14 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status, __le16 vlan, struct sk_buff *skb) { - if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) { - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(vlan) & - E1000_RXD_SPC_VLAN_MASK); - } else { - netif_receive_skb(skb); - } + skb->protocol = eth_type_trans(skb, adapter->netdev); + + if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP)))) + vlan_gro_receive(&adapter->napi, adapter->vlgrp, + le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK, + skb); + else + napi_gro_receive(&adapter->napi, skb); } /** @@ -3828,8 +3829,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, goto next_desc; } - skb->protocol = eth_type_trans(skb, netdev); - e1000_receive_skb(adapter, status, rx_desc->special, skb); next_desc: @@ -3992,8 +3991,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, ((u32)(rx_desc->errors) << 24), le16_to_cpu(rx_desc->csum), skb); - skb->protocol = eth_type_trans(skb, netdev); - e1000_receive_skb(adapter, status, rx_desc->special, skb); next_desc: -- cgit v1.2.3 From a02cec2155fbea457eca8881870fd2de1a4c4c76 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 22 Sep 2010 20:43:57 +0000 Subject: net: return operator cleanup Change "return (EXPR);" to "return EXPR;" return is not a function, parentheses are not required. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/atmdev.h | 2 +- include/linux/etherdevice.h | 4 +-- include/linux/netdevice.h | 2 +- include/linux/skbuff.h | 6 ++--- include/net/bluetooth/hci_core.h | 2 +- include/net/bluetooth/l2cap.h | 2 +- include/net/inet_ecn.h | 2 +- include/net/ip.h | 4 +-- include/net/ipv6.h | 35 +++++++++++++------------- include/net/irda/irlap.h | 2 +- include/net/irda/irlmp.h | 2 +- include/net/irda/irttp.h | 2 +- include/net/sch_generic.h | 2 +- include/net/sctp/sctp.h | 12 ++++----- include/net/sctp/sm.h | 10 ++++---- include/net/sctp/structs.h | 2 +- include/net/sctp/tsnmap.h | 2 +- include/net/tipc/tipc_msg.h | 10 ++++---- net/802/fc.c | 2 +- net/802/fddi.c | 12 ++++----- net/802/hippi.c | 2 +- net/802/tr.c | 2 +- net/8021q/vlan_core.c | 2 +- net/9p/client.c | 4 +-- net/bluetooth/rfcomm/core.c | 4 +-- net/core/flow.c | 4 +-- net/core/neighbour.c | 6 ++--- net/core/utils.c | 2 +- net/dccp/ccids/lib/loss_interval.c | 2 +- net/econet/af_econet.c | 4 +-- net/ethernet/eth.c | 2 +- net/ipv4/arp.c | 2 +- net/ipv4/datagram.c | 2 +- net/ipv4/inet_diag.c | 2 +- net/ipv4/ip_fragment.c | 4 +-- net/ipv4/ip_gre.c | 2 +- net/ipv4/netfilter/arp_tables.c | 2 +- net/ipv4/route.c | 2 +- net/ipv4/tcp_input.c | 10 ++++---- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 8 +++--- net/ipv4/tcp_westwood.c | 2 +- net/ipv6/addrconf.c | 2 +- net/ipv6/addrlabel.c | 5 ++-- net/ipv6/af_inet6.c | 6 ++--- net/ipv6/exthdrs_core.c | 4 +-- net/ipv6/ip6_output.c | 4 +-- net/ipv6/ndisc.c | 8 +++--- net/ipv6/netfilter/ip6_tables.c | 14 +++++------ net/ipv6/raw.c | 12 ++++----- net/ipv6/route.c | 14 +++++------ net/ipv6/tcp_ipv6.c | 2 +- net/ipv6/xfrm6_policy.c | 2 +- net/irda/af_irda.c | 14 +++++------ net/irda/discovery.c | 2 +- net/irda/ircomm/ircomm_tty.c | 4 +-- net/irda/irlmp.c | 2 +- net/irda/irlmp_frame.c | 2 +- net/irda/irnet/irnet_irda.c | 22 ++++++++--------- net/irda/irnet/irnet_ppp.c | 8 +++--- net/key/af_key.c | 4 +-- net/mac80211/rate.c | 2 +- net/rfkill/input.c | 2 +- net/rose/rose_link.c | 4 +-- net/sctp/protocol.c | 2 +- net/sctp/socket.c | 6 ++--- net/sunrpc/auth_gss/auth_gss.c | 2 +- net/sunrpc/auth_gss/gss_generic_token.c | 44 ++++++++++++++++----------------- net/sunrpc/auth_gss/gss_krb5_seqnum.c | 2 +- net/sunrpc/auth_gss/gss_mech_switch.c | 2 +- net/sunrpc/sched.c | 2 +- net/tipc/addr.c | 2 +- net/tipc/bcast.c | 2 +- net/tipc/bearer.c | 2 +- net/tipc/dbg.c | 4 +-- net/tipc/link.c | 6 ++--- net/tipc/link.h | 16 ++++++------ net/tipc/msg.h | 6 ++--- net/tipc/name_table.c | 2 +- net/tipc/node.c | 6 ++--- net/tipc/port.h | 2 +- net/tipc/socket.c | 2 +- net/tipc/subscr.c | 2 +- net/wireless/core.h | 2 +- 84 files changed, 220 insertions(+), 222 deletions(-) diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index f6481daf6e52..a8e4e832cdbb 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -449,7 +449,7 @@ void vcc_insert_socket(struct sock *sk); static inline int atm_guess_pdu2truesize(int size) { - return (SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info)); + return SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info); } diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index fb6aa6070921..f16a01081e15 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -71,7 +71,7 @@ static inline int is_zero_ether_addr(const u8 *addr) */ static inline int is_multicast_ether_addr(const u8 *addr) { - return (0x01 & addr[0]); + return 0x01 & addr[0]; } /** @@ -82,7 +82,7 @@ static inline int is_multicast_ether_addr(const u8 *addr) */ static inline int is_local_ether_addr(const u8 *addr) { - return (0x02 & addr[0]); + return 0x02 & addr[0]; } /** diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f7f1302138af..45dcda5bfda9 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1676,7 +1676,7 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index) */ static inline int netif_is_multiqueue(const struct net_device *dev) { - return (dev->num_tx_queues > 1); + return dev->num_tx_queues > 1; } extern void netif_set_real_num_tx_queues(struct net_device *dev, diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 9e8085a89589..b2c41d19735c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -601,7 +601,7 @@ static inline int skb_queue_empty(const struct sk_buff_head *list) static inline bool skb_queue_is_last(const struct sk_buff_head *list, const struct sk_buff *skb) { - return (skb->next == (struct sk_buff *) list); + return skb->next == (struct sk_buff *)list; } /** @@ -614,7 +614,7 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list, static inline bool skb_queue_is_first(const struct sk_buff_head *list, const struct sk_buff *skb) { - return (skb->prev == (struct sk_buff *) list); + return skb->prev == (struct sk_buff *)list; } /** @@ -2156,7 +2156,7 @@ static inline u16 skb_get_rx_queue(const struct sk_buff *skb) static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) { - return (skb->queue_mapping != 0); + return skb->queue_mapping != 0; } extern u16 skb_tx_hash(const struct net_device *dev, diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4568b938ca35..ebec8c9a929d 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -233,7 +233,7 @@ static inline void inquiry_cache_init(struct hci_dev *hdev) static inline int inquiry_cache_empty(struct hci_dev *hdev) { struct inquiry_cache *c = &hdev->inq_cache; - return (c->list == NULL); + return c->list == NULL; } static inline long inquiry_cache_age(struct hci_dev *hdev) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 6c241444f902..c819c8bf9b68 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -414,7 +414,7 @@ static inline int l2cap_tx_window_full(struct sock *sk) if (sub < 0) sub += 64; - return (sub == pi->remote_tx_win); + return sub == pi->remote_tx_win; } #define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1 diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 9b5d08f4f6e8..88bdd010d65d 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -27,7 +27,7 @@ static inline int INET_ECN_is_not_ect(__u8 dsfield) static inline int INET_ECN_is_capable(__u8 dsfield) { - return (dsfield & INET_ECN_ECT_0); + return dsfield & INET_ECN_ECT_0; } static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) diff --git a/include/net/ip.h b/include/net/ip.h index 7691aca133db..dbee3fe260e1 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -238,9 +238,9 @@ int ip_decrease_ttl(struct iphdr *iph) static inline int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) { - return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || + return inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && - !(dst_metric_locked(dst, RTAX_MTU)))); + !(dst_metric_locked(dst, RTAX_MTU))); } extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 1f8412410998..4a3cd2cd2f5e 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -262,7 +262,7 @@ static inline int ipv6_addr_scope(const struct in6_addr *addr) static inline int __ipv6_addr_src_scope(int type) { - return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16)); + return (type == IPV6_ADDR_ANY) ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16); } static inline int ipv6_addr_src_scope(const struct in6_addr *addr) @@ -279,10 +279,10 @@ static inline int ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, const struct in6_addr *a2) { - return (!!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) | - ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) | - ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) | - ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]))); + return !!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) | + ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) | + ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) | + ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])); } static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) @@ -317,10 +317,10 @@ static inline void ipv6_addr_set(struct in6_addr *addr, static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2) { - return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | - (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | - (a1->s6_addr32[2] ^ a2->s6_addr32[2]) | - (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0); + return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | + (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | + (a1->s6_addr32[2] ^ a2->s6_addr32[2]) | + (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0; } static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, @@ -373,20 +373,20 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a); static inline int ipv6_addr_any(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | a->s6_addr32[3] ) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | a->s6_addr32[3]) == 0; } static inline int ipv6_addr_loopback(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; } static inline int ipv6_addr_v4mapped(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; } /* @@ -395,8 +395,7 @@ static inline int ipv6_addr_v4mapped(const struct in6_addr *a) */ static inline int ipv6_addr_orchid(const struct in6_addr *a) { - return ((a->s6_addr32[0] & htonl(0xfffffff0)) - == htonl(0x20010010)); + return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010); } static inline void ipv6_addr_set_v4mapped(const __be32 addr, @@ -441,7 +440,7 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a * if returned value is greater than prefix length. * --ANK (980803) */ - return (addrlen << 5); + return addrlen << 5; } static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2) diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index 9d0c78ea92f5..17fcd964f9d9 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -282,7 +282,7 @@ static inline int irlap_is_primary(struct irlap_cb *self) default: ret = -1; } - return(ret); + return ret; } /* Clear a pending IrLAP disconnect. - Jean II */ diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 3ffc1d0f93d6..fff11b7fe8a4 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -274,7 +274,7 @@ static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self) if (self->lap->irlap == NULL) return 0; - return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD); + return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD; } /* After doing a irlmp_dup(), this get one of the two socket back into diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 11aee7a2972a..af4b87721d13 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -204,7 +204,7 @@ static inline int irttp_is_primary(struct tsap_cb *self) (self->lsap->lap == NULL) || (self->lsap->lap->irlap == NULL)) return -2; - return(irlap_is_primary(self->lsap->lap->irlap)); + return irlap_is_primary(self->lsap->lap->irlap); } #endif /* IRTTP_H */ diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 3c8728aaab4e..eda8808fdacd 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -601,7 +601,7 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) slot = 0; slot >>= rtab->rate.cell_log; if (slot > 255) - return (rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]); + return rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]; return rtab->data[slot]; } diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 2cb3980b1616..505845ddb0be 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -405,7 +405,7 @@ static inline void sctp_v6_del_protocol(void) { return; } /* Map an association to an assoc_id. */ static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) { - return (asoc?asoc->assoc_id:0); + return asoc ? asoc->assoc_id : 0; } /* Look up the association by its id. */ @@ -473,7 +473,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) /* Tests if the list has one and only one entry. */ static inline int sctp_list_single_entry(struct list_head *head) { - return ((head->next != head) && (head->next == head->prev)); + return (head->next != head) && (head->next == head->prev); } /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ @@ -631,13 +631,13 @@ static inline int sctp_sanity_check(void) /* This is the hash function for the SCTP port hash table. */ static inline int sctp_phashfn(__u16 lport) { - return (lport & (sctp_port_hashsize - 1)); + return lport & (sctp_port_hashsize - 1); } /* This is the hash function for the endpoint hash table. */ static inline int sctp_ep_hashfn(__u16 lport) { - return (lport & (sctp_ep_hashsize - 1)); + return lport & (sctp_ep_hashsize - 1); } /* This is the hash function for the association hash table. */ @@ -645,7 +645,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport) { int h = (lport << 16) + rport; h ^= h>>8; - return (h & (sctp_assoc_hashsize - 1)); + return h & (sctp_assoc_hashsize - 1); } /* This is the hash function for the association hash table. This is @@ -656,7 +656,7 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag) { int h = (lport << 16) + rport; h ^= vtag; - return (h & (sctp_assoc_hashsize-1)); + return h & (sctp_assoc_hashsize - 1); } #define sctp_for_each_hentry(epb, node, head) \ diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 4088c89a9055..9352d12f02de 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -345,12 +345,12 @@ enum { static inline int TSN_lt(__u32 s, __u32 t) { - return (((s) - (t)) & TSN_SIGN_BIT); + return ((s) - (t)) & TSN_SIGN_BIT; } static inline int TSN_lte(__u32 s, __u32 t) { - return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT)); + return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT); } /* Compare two SSNs */ @@ -369,12 +369,12 @@ enum { static inline int SSN_lt(__u16 s, __u16 t) { - return (((s) - (t)) & SSN_SIGN_BIT); + return ((s) - (t)) & SSN_SIGN_BIT; } static inline int SSN_lte(__u16 s, __u16 t) { - return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT)); + return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT); } /* @@ -388,7 +388,7 @@ enum { static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t) { - return (((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT)); + return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT); } /* Check VTAG of the packet matches the sender's own tag. */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index f9e7473613bd..69fef4fb79c0 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -847,7 +847,7 @@ void sctp_packet_free(struct sctp_packet *); static inline int sctp_packet_empty(struct sctp_packet *packet) { - return (packet->size == packet->overhead); + return packet->size == packet->overhead; } /* This represents a remote transport address. diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h index 4aabc5a96cf6..e7728bc14ccf 100644 --- a/include/net/sctp/tsnmap.h +++ b/include/net/sctp/tsnmap.h @@ -157,7 +157,7 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map); /* Is there a gap in the TSN map? */ static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) { - return (map->cumulative_tsn_ack_point != map->max_tsn_seen); + return map->cumulative_tsn_ack_point != map->max_tsn_seen; } /* Mark a duplicate TSN. Note: limit the storage of duplicate TSN diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h index 2e159a812f83..ffe50b4e7b93 100644 --- a/include/net/tipc/tipc_msg.h +++ b/include/net/tipc/tipc_msg.h @@ -107,7 +107,7 @@ static inline u32 msg_hdr_sz(struct tipc_msg *m) static inline int msg_short(struct tipc_msg *m) { - return (msg_hdr_sz(m) == 24); + return msg_hdr_sz(m) == 24; } static inline u32 msg_size(struct tipc_msg *m) @@ -117,7 +117,7 @@ static inline u32 msg_size(struct tipc_msg *m) static inline u32 msg_data_sz(struct tipc_msg *m) { - return (msg_size(m) - msg_hdr_sz(m)); + return msg_size(m) - msg_hdr_sz(m); } static inline unchar *msg_data(struct tipc_msg *m) @@ -132,17 +132,17 @@ static inline u32 msg_type(struct tipc_msg *m) static inline u32 msg_named(struct tipc_msg *m) { - return (msg_type(m) == TIPC_NAMED_MSG); + return msg_type(m) == TIPC_NAMED_MSG; } static inline u32 msg_mcast(struct tipc_msg *m) { - return (msg_type(m) == TIPC_MCAST_MSG); + return msg_type(m) == TIPC_MCAST_MSG; } static inline u32 msg_connected(struct tipc_msg *m) { - return (msg_type(m) == TIPC_CONN_MSG); + return msg_type(m) == TIPC_CONN_MSG; } static inline u32 msg_errcode(struct tipc_msg *m) diff --git a/net/802/fc.c b/net/802/fc.c index 34cf1ee014b8..1e49f2d4ea96 100644 --- a/net/802/fc.c +++ b/net/802/fc.c @@ -70,7 +70,7 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev, if(daddr) { memcpy(fch->daddr,daddr,dev->addr_len); - return(hdr_len); + return hdr_len; } return -hdr_len; } diff --git a/net/802/fddi.c b/net/802/fddi.c index 3ef0ab0a543a..94b3ad08f39a 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -82,10 +82,10 @@ static int fddi_header(struct sk_buff *skb, struct net_device *dev, if (daddr != NULL) { memcpy(fddi->daddr, daddr, dev->addr_len); - return(hl); + return hl; } - return(-hl); + return -hl; } @@ -108,7 +108,7 @@ static int fddi_rebuild_header(struct sk_buff *skb) { printk("%s: Don't know how to resolve type %04X addresses.\n", skb->dev->name, ntohs(fddi->hdr.llc_snap.ethertype)); - return(0); + return 0; } } @@ -162,7 +162,7 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev) /* Assume 802.2 SNAP frames, for now */ - return(type); + return type; } EXPORT_SYMBOL(fddi_type_trans); @@ -170,9 +170,9 @@ EXPORT_SYMBOL(fddi_type_trans); int fddi_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN)) - return(-EINVAL); + return -EINVAL; dev->mtu = new_mtu; - return(0); + return 0; } EXPORT_SYMBOL(fddi_change_mtu); diff --git a/net/802/hippi.c b/net/802/hippi.c index cd3e8e929529..91aca8780fd0 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c @@ -152,7 +152,7 @@ int hippi_change_mtu(struct net_device *dev, int new_mtu) if ((new_mtu < 68) || (new_mtu > 65280)) return -EINVAL; dev->mtu = new_mtu; - return(0); + return 0; } EXPORT_SYMBOL(hippi_change_mtu); diff --git a/net/802/tr.c b/net/802/tr.c index 1c6e596074df..5e20cf8a074b 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -145,7 +145,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev, { memcpy(trh->daddr,daddr,dev->addr_len); tr_source_route(skb, trh, dev); - return(hdr_len); + return hdr_len; } return -hdr_len; diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 889f4ac4459a..0eb486d342dc 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -27,7 +27,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, else if (vlan_id) goto drop; - return (polling ? netif_receive_skb(skb) : netif_rx(skb)); + return polling ? netif_receive_skb(skb) : netif_rx(skb); drop: dev_kfree_skb_any(skb); diff --git a/net/9p/client.c b/net/9p/client.c index dc6f2f26d023..f34b9f510818 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -61,13 +61,13 @@ static const match_table_t tokens = { inline int p9_is_proto_dotl(struct p9_client *clnt) { - return (clnt->proto_version == p9_proto_2000L); + return clnt->proto_version == p9_proto_2000L; } EXPORT_SYMBOL(p9_is_proto_dotl); inline int p9_is_proto_dotu(struct p9_client *clnt) { - return (clnt->proto_version == p9_proto_2000u); + return clnt->proto_version == p9_proto_2000u; } EXPORT_SYMBOL(p9_is_proto_dotu); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 7dca91bb8c57..15ea84ba344e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -179,13 +179,13 @@ static unsigned char rfcomm_crc_table[256] = { /* FCS on 2 bytes */ static inline u8 __fcs(u8 *data) { - return (0xff - __crc(data)); + return 0xff - __crc(data); } /* FCS on 3 bytes */ static inline u8 __fcs2(u8 *data) { - return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]); + return 0xff - rfcomm_crc_table[__crc(data) ^ data[2]]; } /* Check FCS */ diff --git a/net/core/flow.c b/net/core/flow.c index b143b86b1f2a..127c8a7ffd61 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -176,8 +176,8 @@ static u32 flow_hash_code(struct flow_cache *fc, { u32 *k = (u32 *) key; - return (jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) - & (flow_cache_hash_size(fc) - 1)); + return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) + & (flow_cache_hash_size(fc) - 1); } typedef unsigned long flow_compare_t; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a4e0a7482c2b..96b1a749abb4 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -122,7 +122,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh) unsigned long neigh_rand_reach_time(unsigned long base) { - return (base ? (net_random() % base) + (base >> 1) : 0); + return base ? (net_random() % base) + (base >> 1) : 0; } EXPORT_SYMBOL(neigh_rand_reach_time); @@ -766,9 +766,9 @@ next_elt: static __inline__ int neigh_max_probes(struct neighbour *n) { struct neigh_parms *p = n->parms; - return (n->nud_state & NUD_PROBE ? + return (n->nud_state & NUD_PROBE) ? p->ucast_probes : - p->ucast_probes + p->app_probes + p->mcast_probes); + p->ucast_probes + p->app_probes + p->mcast_probes; } static void neigh_invalidate(struct neighbour *neigh) diff --git a/net/core/utils.c b/net/core/utils.c index ec6bb322f372..5fea0ab21902 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -75,7 +75,7 @@ __be32 in_aton(const char *str) str++; } } - return(htonl(l)); + return htonl(l); } EXPORT_SYMBOL(in_aton); diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c index 8fc3cbf79071..497723c4d4bb 100644 --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c @@ -116,7 +116,7 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb) cur->li_length = len; tfrc_lh_calc_i_mean(lh); - return (lh->i_mean < old_i_mean); + return lh->i_mean < old_i_mean; } /* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */ diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index baa98fb83552..f8c1ae4b41f0 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -392,7 +392,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, dev_queue_xmit(skb); dev_put(dev); mutex_unlock(&econet_mutex); - return(len); + return len; out_free: kfree_skb(skb); @@ -637,7 +637,7 @@ static int econet_create(struct net *net, struct socket *sock, int protocol, eo->num = protocol; econet_insert_socket(&econet_sklist, sk); - return(0); + return 0; out: return err; } diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 85e7b4551326..f00ef2f1d814 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -387,6 +387,6 @@ ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len) l = _format_mac_addr(buf, PAGE_SIZE, addr, len); l += scnprintf(buf + l, PAGE_SIZE - l, "\n"); - return ((ssize_t) l); + return (ssize_t)l; } EXPORT_SYMBOL(sysfs_format_mac); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index dcfe7e961c10..4083c186fd30 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -567,7 +567,7 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, if (out_dev) omi = IN_DEV_MEDIUM_ID(out_dev); - return (omi != imi && omi != -1); + return omi != imi && omi != -1; } /* diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 721a8a37b45c..174be6caa5c8 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -73,6 +73,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_id = jiffies; sk_dst_set(sk, &rt->dst); - return(0); + return 0; } EXPORT_SYMBOL(ip4_datagram_connect); diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index e5fa2ddce320..ba8042665849 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -425,7 +425,7 @@ static int inet_diag_bc_run(const void *bc, int len, bc += op->no; } } - return (len == 0); + return len == 0; } static int valid_cc(const void *bc, int len, int cc) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index f4dc879e258e..168440834ade 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -116,11 +116,11 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a) struct ip4_create_arg *arg = a; qp = container_of(q, struct ipq, q); - return (qp->id == arg->iph->id && + return qp->id == arg->iph->id && qp->saddr == arg->iph->saddr && qp->daddr == arg->iph->daddr && qp->protocol == arg->iph->protocol && - qp->user == arg->user); + qp->user == arg->user; } /* Memory Tracking Functions. */ diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 714b6a80361d..0967d02fefd8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -659,7 +659,7 @@ drop: rcu_read_unlock(); drop_nolock: kfree_skb(skb); - return(0); + return 0; } static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index e8f4f9a57f12..8b642f152468 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -72,7 +72,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, for (i = 0; i < len; i++) ret |= (hdr_addr[i] ^ ap->addr[i]) & ap->mask[i]; - return (ret != 0); + return ret != 0; } /* diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e24d48dd99d3..ae1d4a41f1c6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2791,7 +2791,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi dst_release(&(*rp)->dst); *rp = rt; - return (rt ? 0 : -ENOMEM); + return rt ? 0 : -ENOMEM; } int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 1bc87a05c734..51966b3f9719 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2301,7 +2301,7 @@ static inline int tcp_dupack_heuristics(struct tcp_sock *tp) static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb) { - return (tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto); + return tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto; } static inline int tcp_head_timedout(struct sock *sk) @@ -3398,8 +3398,8 @@ static void tcp_ack_probe(struct sock *sk) static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag) { - return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || - inet_csk(sk)->icsk_ca_state != TCP_CA_Open); + return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || + inet_csk(sk)->icsk_ca_state != TCP_CA_Open; } static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag) @@ -3416,9 +3416,9 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, const u32 ack_seq, const u32 nwin) { - return (after(ack, tp->snd_una) || + return after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || - (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); + (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd); } /* Update our send window. diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f25b56cb85cb..43cf901d7659 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -55,7 +55,7 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) return 1; if (after(end_seq, s_win) && before(seq, e_win)) return 1; - return (seq == e_win && seq == end_seq); + return seq == e_win && seq == end_seq; } /* diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ea09d2fd50c7..05b1ecf36763 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1370,9 +1370,9 @@ static inline int tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, unsigned mss_now, int nonagle) { - return (skb->len < mss_now && + return skb->len < mss_now && ((nonagle & TCP_NAGLE_CORK) || - (!nonagle && tp->packets_out && tcp_minshall_check(tp)))); + (!nonagle && tp->packets_out && tcp_minshall_check(tp))); } /* Return non-zero if the Nagle test allows this packet to be @@ -1443,10 +1443,10 @@ int tcp_may_send_now(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = tcp_send_head(sk); - return (skb && + return skb && tcp_snd_test(sk, skb, tcp_current_mss(sk), (tcp_skb_is_last(sk, skb) ? - tp->nonagle : TCP_NAGLE_PUSH))); + tp->nonagle : TCP_NAGLE_PUSH)); } /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c index 20151d6a6241..a534dda5456e 100644 --- a/net/ipv4/tcp_westwood.c +++ b/net/ipv4/tcp_westwood.c @@ -80,7 +80,7 @@ static void tcp_westwood_init(struct sock *sk) */ static inline u32 westwood_do_filter(u32 a, u32 b) { - return (((7 * a) + b) >> 3); + return ((7 * a) + b) >> 3; } static void westwood_filter(struct westwood *w, u32 delta) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5bc893e28008..89aa54394a08 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -243,7 +243,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev) /* Check if a route is valid prefix route */ static inline int addrconf_is_prefix_route(const struct rt6_info *rt) { - return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); + return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; } static void addrconf_del_timer(struct inet6_ifaddr *ifp) diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index f0e774cea386..921dcf6c271a 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -513,10 +513,9 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) static inline int ip6addrlbl_msgsize(void) { - return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) + return NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) + nla_total_size(16) /* IFAL_ADDRESS */ - + nla_total_size(4) /* IFAL_LABEL */ - ); + + nla_total_size(4); /* IFAL_LABEL */ } static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 56b9bf2516f4..60220985bb80 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -467,7 +467,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) sin->sin6_scope_id = sk->sk_bound_dev_if; *uaddr_len = sizeof(*sin); - return(0); + return 0; } EXPORT_SYMBOL(inet6_getname); @@ -488,7 +488,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCADDRT: case SIOCDELRT: - return(ipv6_route_ioctl(net, cmd, (void __user *)arg)); + return ipv6_route_ioctl(net, cmd, (void __user *)arg); case SIOCSIFADDR: return addrconf_add_ifaddr(net, (void __user *) arg); @@ -502,7 +502,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return sk->sk_prot->ioctl(sk, cmd, arg); } /*NOTREACHED*/ - return(0); + return 0; } EXPORT_SYMBOL(inet6_ioctl); diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index e1caa5d526c2..14ed0a955b56 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -13,12 +13,12 @@ int ipv6_ext_hdr(u8 nexthdr) /* * find out if nexthdr is an extension header or a protocol */ - return ( (nexthdr == NEXTHDR_HOP) || + return (nexthdr == NEXTHDR_HOP) || (nexthdr == NEXTHDR_ROUTING) || (nexthdr == NEXTHDR_FRAGMENT) || (nexthdr == NEXTHDR_AUTH) || (nexthdr == NEXTHDR_NONE) || - (nexthdr == NEXTHDR_DEST) ); + (nexthdr == NEXTHDR_DEST); } /* diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 1838927a2243..efbbbce68f9e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -870,8 +870,8 @@ static inline int ip6_rt_check(struct rt6key *rt_key, struct in6_addr *fl_addr, struct in6_addr *addr_cache) { - return ((rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && - (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache))); + return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && + (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache)); } static struct dst_entry *ip6_sk_dst_check(struct sock *sk, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 69a0051cea67..b3dd844cd34f 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -228,12 +228,12 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, do { cur = ((void *)cur) + (cur->nd_opt_len << 3); } while(cur < end && cur->nd_opt_type != type); - return (cur <= end && cur->nd_opt_type == type ? cur : NULL); + return cur <= end && cur->nd_opt_type == type ? cur : NULL; } static inline int ndisc_is_useropt(struct nd_opt_hdr *opt) { - return (opt->nd_opt_type == ND_OPT_RDNSS); + return opt->nd_opt_type == ND_OPT_RDNSS; } static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, @@ -244,7 +244,7 @@ static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, do { cur = ((void *)cur) + (cur->nd_opt_len << 3); } while(cur < end && !ndisc_is_useropt(cur)); - return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL); + return cur <= end && ndisc_is_useropt(cur) ? cur : NULL; } static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, @@ -319,7 +319,7 @@ static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p, int prepad = ndisc_addr_option_pad(dev->type); if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad)) return NULL; - return (lladdr + prepad); + return lladdr + prepad; } int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 8e754be92c24..6b331e9b5706 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -82,13 +82,13 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); int ip6t_ext_hdr(u8 nexthdr) { - return ( (nexthdr == IPPROTO_HOPOPTS) || - (nexthdr == IPPROTO_ROUTING) || - (nexthdr == IPPROTO_FRAGMENT) || - (nexthdr == IPPROTO_ESP) || - (nexthdr == IPPROTO_AH) || - (nexthdr == IPPROTO_NONE) || - (nexthdr == IPPROTO_DSTOPTS) ); + return (nexthdr == IPPROTO_HOPOPTS) || + (nexthdr == IPPROTO_ROUTING) || + (nexthdr == IPPROTO_FRAGMENT) || + (nexthdr == IPPROTO_ESP) || + (nexthdr == IPPROTO_AH) || + (nexthdr == IPPROTO_NONE) || + (nexthdr == IPPROTO_DSTOPTS); } /* Returns whether matches rule or not. */ diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e677937a07fc..45e6efb7f171 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -764,7 +764,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, return -EINVAL; if (sin6->sin6_family && sin6->sin6_family != AF_INET6) - return(-EAFNOSUPPORT); + return -EAFNOSUPPORT; /* port is the proto value [0..255] carried in nexthdr */ proto = ntohs(sin6->sin6_port); @@ -772,10 +772,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (!proto) proto = inet->inet_num; else if (proto != inet->inet_num) - return(-EINVAL); + return -EINVAL; if (proto > 255) - return(-EINVAL); + return -EINVAL; daddr = &sin6->sin6_addr; if (np->sndflow) { @@ -985,7 +985,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, /* You may get strange result with a positive odd offset; RFC2292bis agrees with me. */ if (val > 0 && (val&1)) - return(-EINVAL); + return -EINVAL; if (val < 0) { rp->checksum = 0; } else { @@ -997,7 +997,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, break; default: - return(-ENOPROTOOPT); + return -ENOPROTOOPT; } } @@ -1190,7 +1190,7 @@ static int rawv6_init_sk(struct sock *sk) default: break; } - return(0); + return 0; } struct proto rawv6_prot = { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d126365ac046..25b0beda4331 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -217,14 +217,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static __inline__ int rt6_check_expired(const struct rt6_info *rt) { - return (rt->rt6i_flags & RTF_EXPIRES && - time_after(jiffies, rt->rt6i_expires)); + return (rt->rt6i_flags & RTF_EXPIRES) && + time_after(jiffies, rt->rt6i_expires); } static inline int rt6_need_strict(struct in6_addr *daddr) { - return (ipv6_addr_type(daddr) & - (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK)); + return ipv6_addr_type(daddr) & + (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); } /* @@ -440,7 +440,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) __func__, match); net = dev_net(rt0->rt6i_dev); - return (match ? match : net->ipv6.ip6_null_entry); + return match ? match : net->ipv6.ip6_null_entry; } #ifdef CONFIG_IPV6_ROUTE_INFO @@ -859,7 +859,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl dst_release(*dstp); *dstp = new; - return (new ? 0 : -ENOMEM); + return new ? 0 : -ENOMEM; } EXPORT_SYMBOL_GPL(ip6_dst_blackhole); @@ -1070,7 +1070,7 @@ static int ip6_dst_gc(struct dst_ops *ops) net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1; out: net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity; - return (atomic_read(&ops->entries) > rt_max_size); + return atomic_read(&ops->entries) > rt_max_size; } /* Clean host part of a prefix. Not necessary in radix tree, diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fe6d40418c0b..8d93f6d81979 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -139,7 +139,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, return -EINVAL; if (usin->sin6_family != AF_INET6) - return(-EAFNOSUPPORT); + return -EAFNOSUPPORT; memset(&fl, 0, sizeof(fl)); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 6baeabbbca82..39676eac3a37 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -199,7 +199,7 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops) struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); xfrm6_policy_afinfo.garbage_collect(net); - return (atomic_read(&ops->entries) > ops->gc_thresh * 2); + return atomic_read(&ops->entries) > ops->gc_thresh * 2; } static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index fd55b5135de5..bf3635129b17 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -573,9 +573,9 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name) /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) - return (-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; else - return (-EHOSTUNREACH); + return -EHOSTUNREACH; } /* Get the remote TSAP selector */ @@ -663,7 +663,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) __func__, name); self->daddr = DEV_ADDR_ANY; kfree(discoveries); - return(-ENOTUNIQ); + return -ENOTUNIQ; } /* First time we found that one, save it ! */ daddr = self->daddr; @@ -677,7 +677,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __func__); self->daddr = DEV_ADDR_ANY; kfree(discoveries); - return(-EHOSTUNREACH); + return -EHOSTUNREACH; break; } } @@ -689,7 +689,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) IRDA_DEBUG(1, "%s(), cannot discover service ''%s'' in any device !!!\n", __func__, name); self->daddr = DEV_ADDR_ANY; - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } /* Revert back to discovered device & service */ @@ -2465,9 +2465,9 @@ bed: /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) - return (-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; else - return (-EHOSTUNREACH); + return -EHOSTUNREACH; } /* Translate from internal to user structure */ diff --git a/net/irda/discovery.c b/net/irda/discovery.c index c1c8ae939126..36c3f037f172 100644 --- a/net/irda/discovery.c +++ b/net/irda/discovery.c @@ -315,7 +315,7 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, /* Get the actual number of device in the buffer and return */ *pn = i; - return(buffer); + return buffer; } #ifdef CONFIG_PROC_FS diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index faa82ca2dfdc..a39cca8331df 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -449,8 +449,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) } #ifdef SERIAL_DO_RESTART - return ((self->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); + return (self->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; #else return -EAGAIN; #endif diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 0e7d8bde145d..6115a44c0a24 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -939,7 +939,7 @@ struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots) } /* Return current cached discovery log */ - return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE)); + return irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE); } EXPORT_SYMBOL(irlmp_get_discoveries); diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c index 3750884094da..062e63b1c5c4 100644 --- a/net/irda/irlmp_frame.c +++ b/net/irda/irlmp_frame.c @@ -448,7 +448,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel, (self->cache.slsap_sel == slsap_sel) && (self->cache.dlsap_sel == dlsap_sel)) { - return (self->cache.lsap); + return self->cache.lsap; } #endif diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index e98e40d76f4f..7f17a8020e8a 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c @@ -238,7 +238,7 @@ irnet_ias_to_tsap(irnet_socket * self, DEXIT(IRDA_SR_TRACE, "\n"); /* Return the TSAP */ - return(dtsap_sel); + return dtsap_sel; } /*------------------------------------------------------------------*/ @@ -301,7 +301,7 @@ irnet_connect_tsap(irnet_socket * self) { clear_bit(0, &self->ttp_connect); DERROR(IRDA_SR_ERROR, "connect aborted!\n"); - return(err); + return err; } /* Connect to remote device */ @@ -312,7 +312,7 @@ irnet_connect_tsap(irnet_socket * self) { clear_bit(0, &self->ttp_connect); DERROR(IRDA_SR_ERROR, "connect aborted!\n"); - return(err); + return err; } /* The above call is non-blocking. @@ -321,7 +321,7 @@ irnet_connect_tsap(irnet_socket * self) * See you there ;-) */ DEXIT(IRDA_SR_TRACE, "\n"); - return(err); + return err; } /*------------------------------------------------------------------*/ @@ -362,10 +362,10 @@ irnet_discover_next_daddr(irnet_socket * self) /* The above request is non-blocking. * After a while, IrDA will call us back in irnet_discovervalue_confirm() * We will then call irnet_ias_to_tsap() and come back here again... */ - return(0); + return 0; } else - return(1); + return 1; } /*------------------------------------------------------------------*/ @@ -436,7 +436,7 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self) /* Follow me in irnet_discovervalue_confirm() */ DEXIT(IRDA_SR_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -485,7 +485,7 @@ irnet_dname_to_daddr(irnet_socket * self) /* No luck ! */ DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname); kfree(discoveries); - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } @@ -527,7 +527,7 @@ irda_irnet_create(irnet_socket * self) INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect); DEXIT(IRDA_SOCK_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -601,7 +601,7 @@ irda_irnet_connect(irnet_socket * self) * We will finish the connection procedure in irnet_connect_tsap(). */ DEXIT(IRDA_SOCK_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -733,7 +733,7 @@ irnet_daddr_to_dname(irnet_socket * self) /* No luck ! */ DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr); kfree(discoveries); - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } /*------------------------------------------------------------------*/ diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index dfe7b38dd4af..69f1fa64994e 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -166,7 +166,7 @@ irnet_ctrl_write(irnet_socket * ap, } /* Success : we have parsed all commands successfully */ - return(count); + return count; } #ifdef INITIAL_DISCOVERY @@ -300,7 +300,7 @@ irnet_ctrl_read(irnet_socket * ap, } DEXIT(CTRL_TRACE, "\n"); - return(strlen(event)); + return strlen(event); } #endif /* INITIAL_DISCOVERY */ @@ -409,7 +409,7 @@ irnet_ctrl_read(irnet_socket * ap, } DEXIT(CTRL_TRACE, "\n"); - return(strlen(event)); + return strlen(event); } /*------------------------------------------------------------------*/ @@ -623,7 +623,7 @@ dev_irnet_poll(struct file * file, mask |= irnet_ctrl_poll(ap, file, wait); DEXIT(FS_TRACE, " - mask=0x%X\n", mask); - return(mask); + return mask; } /*------------------------------------------------------------------*/ diff --git a/net/key/af_key.c b/net/key/af_key.c index 43040e97c474..d87c22df6f1e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -565,12 +565,12 @@ pfkey_proto2satype(uint16_t proto) static uint8_t pfkey_proto_to_xfrm(uint8_t proto) { - return (proto == IPSEC_PROTO_ANY ? 0 : proto); + return proto == IPSEC_PROTO_ANY ? 0 : proto; } static uint8_t pfkey_proto_from_xfrm(uint8_t proto) { - return (proto ? proto : IPSEC_PROTO_ANY); + return proto ? proto : IPSEC_PROTO_ANY; } static inline int pfkey_sockaddr_len(sa_family_t family) diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 4f772de2f213..b0cc385bf989 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -207,7 +207,7 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) fc = hdr->frame_control; - return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc)); + return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); } static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) diff --git a/net/rfkill/input.c b/net/rfkill/input.c index 3713d7ecab96..1bca6d49ec96 100644 --- a/net/rfkill/input.c +++ b/net/rfkill/input.c @@ -142,7 +142,7 @@ static unsigned long rfkill_last_scheduled; static unsigned long rfkill_ratelimit(const unsigned long last) { const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY); - return (time_after(jiffies, last + delay)) ? 0 : delay; + return time_after(jiffies, last + delay) ? 0 : delay; } static void rfkill_schedule_ratelimited(void) diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c index a750a28e0221..fa5f5641a2c2 100644 --- a/net/rose/rose_link.c +++ b/net/rose/rose_link.c @@ -114,7 +114,7 @@ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh) if (ax25s) ax25_cb_put(ax25s); - return (neigh->ax25 != NULL); + return neigh->ax25 != NULL; } /* @@ -137,7 +137,7 @@ static int rose_link_up(struct rose_neigh *neigh) if (ax25s) ax25_cb_put(ax25s); - return (neigh->ax25 != NULL); + return neigh->ax25 != NULL; } /* diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index f774e657641a..1ef29c74d85e 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -799,7 +799,7 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *len) static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp) { /* PF_INET only supports AF_INET addresses. */ - return (AF_INET == family); + return AF_INET == family; } /* Address matching with wildcards allowed. */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6a691d84aef4..535659fdbaa1 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3884,7 +3884,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, } out: - return (retval); + return retval; } @@ -3940,7 +3940,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, } out: - return (retval); + return retval; } /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) @@ -5594,7 +5594,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) /* Note: sk->sk_num gets filled in if ephemeral port request. */ ret = sctp_get_port_local(sk, &addr); - return (ret ? 1 : 0); + return ret ? 1 : 0; } /* diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index dcfc66bab2bb..597c493392ad 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1049,7 +1049,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) out: if (acred->machine_cred != gss_cred->gc_machine_cred) return 0; - return (rc->cr_uid == acred->uid); + return rc->cr_uid == acred->uid; } /* diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c index 310b78e99456..c586e92bcf76 100644 --- a/net/sunrpc/auth_gss/gss_generic_token.c +++ b/net/sunrpc/auth_gss/gss_generic_token.c @@ -76,19 +76,19 @@ static int der_length_size( int length) { if (length < (1<<7)) - return(1); + return 1; else if (length < (1<<8)) - return(2); + return 2; #if (SIZEOF_INT == 2) else - return(3); + return 3; #else else if (length < (1<<16)) - return(3); + return 3; else if (length < (1<<24)) - return(4); + return 4; else - return(5); + return 5; #endif } @@ -121,14 +121,14 @@ der_read_length(unsigned char **buf, int *bufsize) int ret; if (*bufsize < 1) - return(-1); + return -1; sf = *(*buf)++; (*bufsize)--; if (sf & 0x80) { if ((sf &= 0x7f) > ((*bufsize)-1)) - return(-1); + return -1; if (sf > SIZEOF_INT) - return (-1); + return -1; ret = 0; for (; sf; sf--) { ret = (ret<<8) + (*(*buf)++); @@ -138,7 +138,7 @@ der_read_length(unsigned char **buf, int *bufsize) ret = sf; } - return(ret); + return ret; } /* returns the length of a token, given the mech oid and the body size */ @@ -148,7 +148,7 @@ g_token_size(struct xdr_netobj *mech, unsigned int body_size) { /* set body_size to sequence contents size */ body_size += 2 + (int) mech->len; /* NEED overflow check */ - return(1 + der_length_size(body_size) + body_size); + return 1 + der_length_size(body_size) + body_size; } EXPORT_SYMBOL_GPL(g_token_size); @@ -186,27 +186,27 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, int ret = 0; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (*buf++ != 0x60) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((seqsize = der_read_length(&buf, &toksize)) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (seqsize != toksize) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (*buf++ != 0x06) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; toid.len = *buf++; if ((toksize-=toid.len) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; toid.data = buf; buf+=toid.len; @@ -217,17 +217,17 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, to return G_BAD_TOK_HEADER if the token header is in fact bad */ if ((toksize-=2) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (ret) - return(ret); + return ret; if (!ret) { *buf_in = buf; *body_size = toksize; } - return(ret); + return ret; } EXPORT_SYMBOL_GPL(g_verify_token_header); diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c index 415c013ba382..62ac90c62cb1 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c +++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c @@ -162,5 +162,5 @@ krb5_get_seq_num(struct krb5_ctx *kctx, *seqnum = ((plain[0]) | (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24)); - return (0); + return 0; } diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 2689de39dc78..8b4061049d76 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -331,7 +331,7 @@ gss_delete_sec_context(struct gss_ctx **context_handle) *context_handle); if (!*context_handle) - return(GSS_S_NO_CONTEXT); + return GSS_S_NO_CONTEXT; if ((*context_handle)->internal_ctx_id) (*context_handle)->mech_type->gm_ops ->gss_delete_sec_context((*context_handle) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index cace6049e4a5..aa5dbda6608c 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -376,7 +376,7 @@ int rpc_queue_empty(struct rpc_wait_queue *queue) spin_lock_bh(&queue->lock); res = queue->qlen; spin_unlock_bh(&queue->lock); - return (res == 0); + return res == 0; } EXPORT_SYMBOL_GPL(rpc_queue_empty); diff --git a/net/tipc/addr.c b/net/tipc/addr.c index c048543ffbeb..2ddc351b3be9 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -89,7 +89,7 @@ int tipc_addr_domain_valid(u32 addr) int tipc_addr_node_valid(u32 addr) { - return (tipc_addr_domain_valid(addr) && tipc_node(addr)); + return tipc_addr_domain_valid(addr) && tipc_node(addr); } int tipc_in_scope(u32 domain, u32 addr) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index b11248c2d788..ecfaac10d0b4 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -184,7 +184,7 @@ static void bclink_set_gap(struct tipc_node *n_ptr) static int bclink_ack_allowed(u32 n) { - return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); + return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag; } diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 52ae17b2583e..9c10c6b7c12b 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -63,7 +63,7 @@ static int media_name_valid(const char *name) len = strlen(name); if ((len + 1) > TIPC_MAX_MEDIA_NAME) return 0; - return (strspn(name, tipc_alphabet) == len); + return strspn(name, tipc_alphabet) == len; } /** diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 1885a7edb0c8..6569d45bfb9a 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c @@ -134,7 +134,7 @@ void tipc_printbuf_reset(struct print_buf *pb) int tipc_printbuf_empty(struct print_buf *pb) { - return (!pb->buf || (pb->crs == pb->buf)); + return !pb->buf || (pb->crs == pb->buf); } /** @@ -169,7 +169,7 @@ int tipc_printbuf_validate(struct print_buf *pb) tipc_printf(pb, err); } } - return (pb->crs - pb->buf + 1); + return pb->crs - pb->buf + 1; } /** diff --git a/net/tipc/link.c b/net/tipc/link.c index a6a3102bb4d6..b8cf1e9d0b86 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -239,13 +239,13 @@ int tipc_link_is_up(struct link *l_ptr) { if (!l_ptr) return 0; - return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); + return link_working_working(l_ptr) || link_working_unknown(l_ptr); } int tipc_link_is_active(struct link *l_ptr) { - return ((l_ptr->owner->active_links[0] == l_ptr) || - (l_ptr->owner->active_links[1] == l_ptr)); + return (l_ptr->owner->active_links[0] == l_ptr) || + (l_ptr->owner->active_links[1] == l_ptr); } /** diff --git a/net/tipc/link.h b/net/tipc/link.h index 2e5385c47d30..26151d30589d 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -279,12 +279,12 @@ static inline int between(u32 lower, u32 upper, u32 n) static inline int less_eq(u32 left, u32 right) { - return (mod(right - left) < 32768u); + return mod(right - left) < 32768u; } static inline int less(u32 left, u32 right) { - return (less_eq(left, right) && (mod(right) != mod(left))); + return less_eq(left, right) && (mod(right) != mod(left)); } static inline u32 lesser(u32 left, u32 right) @@ -299,32 +299,32 @@ static inline u32 lesser(u32 left, u32 right) static inline int link_working_working(struct link *l_ptr) { - return (l_ptr->state == WORKING_WORKING); + return l_ptr->state == WORKING_WORKING; } static inline int link_working_unknown(struct link *l_ptr) { - return (l_ptr->state == WORKING_UNKNOWN); + return l_ptr->state == WORKING_UNKNOWN; } static inline int link_reset_unknown(struct link *l_ptr) { - return (l_ptr->state == RESET_UNKNOWN); + return l_ptr->state == RESET_UNKNOWN; } static inline int link_reset_reset(struct link *l_ptr) { - return (l_ptr->state == RESET_RESET); + return l_ptr->state == RESET_RESET; } static inline int link_blocked(struct link *l_ptr) { - return (l_ptr->exp_msg_count || l_ptr->blocked); + return l_ptr->exp_msg_count || l_ptr->blocked; } static inline int link_congested(struct link *l_ptr) { - return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]); + return l_ptr->out_queue_size >= l_ptr->queue_limit[0]; } #endif diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 995d2da35b01..031aad18efce 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -104,7 +104,7 @@ static inline u32 msg_user(struct tipc_msg *m) static inline u32 msg_isdata(struct tipc_msg *m) { - return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); + return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE; } static inline void msg_set_user(struct tipc_msg *m, u32 n) @@ -289,7 +289,7 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a) static inline int msg_is_dest(struct tipc_msg *m, u32 d) { - return(msg_short(m) || (msg_destnode(m) == d)); + return msg_short(m) || (msg_destnode(m) == d); } static inline u32 msg_routed(struct tipc_msg *m) @@ -632,7 +632,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) static inline u32 msg_max_pkt(struct tipc_msg *m) { - return (msg_bits(m, 9, 16, 0xffff) * 4); + return msg_bits(m, 9, 16, 0xffff) * 4; } static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c13c2c7c4b57..9ca4b0689237 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -116,7 +116,7 @@ DEFINE_RWLOCK(tipc_nametbl_lock); static int hash(int x) { - return(x & (tipc_nametbl_size - 1)); + return x & (tipc_nametbl_size - 1); } /** diff --git a/net/tipc/node.c b/net/tipc/node.c index b702c7bf580f..7c49cd056df7 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -242,17 +242,17 @@ int tipc_node_has_active_links(struct tipc_node *n_ptr) int tipc_node_has_redundant_links(struct tipc_node *n_ptr) { - return (n_ptr->working_links > 1); + return n_ptr->working_links > 1; } static int tipc_node_has_active_routes(struct tipc_node *n_ptr) { - return (n_ptr && (n_ptr->last_router >= 0)); + return n_ptr && (n_ptr->last_router >= 0); } int tipc_node_is_up(struct tipc_node *n_ptr) { - return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); + return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); } struct tipc_node *tipc_node_attach_link(struct link *l_ptr) diff --git a/net/tipc/port.h b/net/tipc/port.h index 8d1652aab298..e74bd9563739 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -157,7 +157,7 @@ static inline u32 tipc_peer_node(struct port *p_ptr) static inline int tipc_port_congested(struct port *p_ptr) { - return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); + return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); } /** diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f7ac94de24fe..33217fc3d697 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1195,7 +1195,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) if (msg_connected(msg)) threshold *= 4; - return (queue_size >= threshold); + return queue_size >= threshold; } /** diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ab6eab4c45e2..1a5b9a6bd128 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -604,6 +604,6 @@ int tipc_ispublished(struct tipc_name const *name) { u32 domain = 0; - return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0); + return tipc_nametbl_translate(name->type, name->instance, &domain) != 0; } diff --git a/net/wireless/core.h b/net/wireless/core.h index 37580e090a3d..5d89310b3587 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -86,7 +86,7 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy) static inline bool wiphy_idx_valid(int wiphy_idx) { - return (wiphy_idx >= 0); + return wiphy_idx >= 0; } -- cgit v1.2.3 From 8dcb20038ade81f9a87c024e7f12ec74f0e95f33 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 28 Aug 2010 19:36:10 +0300 Subject: mac80211: Filter ProbeReq SuppRates based on TX rate mask If the TX rate set has been masked, the removed rates can also be removed from the Supported Rates and Extended Supported Rates IEs in Probe Request frames. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/scan.c | 2 +- net/mac80211/util.c | 37 ++++++++++++++++++++++--------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9346a6b0f400..3641563d90f8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1256,7 +1256,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, const u8 *key, u8 key_len, u8 key_idx); int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band); + enum ieee80211_band band, u32 rate_mask); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d60389ba9b95..1623e9d2086e 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -242,7 +242,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) local->hw_scan_req->n_channels = n_chans; ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, - req->ie, req->ie_len, band); + req->ie, req->ie_len, band, (u32) -1); local->hw_scan_req->ie_len = ielen; return true; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 737f4267c335..bfd19d76667a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -895,26 +895,33 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band) + enum ieee80211_band band, u32 rate_mask) { struct ieee80211_supported_band *sband; u8 *pos; size_t offset = 0, noffset; int supp_rates_len, i; + u8 rates[32]; + int num_rates; + int ext_rates_len; sband = local->hw.wiphy->bands[band]; pos = buffer; - supp_rates_len = min_t(int, sband->n_bitrates, 8); + num_rates = 0; + for (i = 0; i < sband->n_bitrates; i++) { + if ((BIT(i) & rate_mask) == 0) + continue; /* skip rate */ + rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); + } + + supp_rates_len = min_t(int, num_rates, 8); *pos++ = WLAN_EID_SUPP_RATES; *pos++ = supp_rates_len; - - for (i = 0; i < supp_rates_len; i++) { - int rate = sband->bitrates[i].bitrate; - *pos++ = (u8) (rate / 5); - } + memcpy(pos, rates, supp_rates_len); + pos += supp_rates_len; /* insert "request information" if in custom IEs */ if (ie && ie_len) { @@ -932,14 +939,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, offset = noffset; } - if (sband->n_bitrates > i) { + ext_rates_len = num_rates - supp_rates_len; + if (ext_rates_len > 0) { *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos++ = sband->n_bitrates - i; - - for (; i < sband->n_bitrates; i++) { - int rate = sband->bitrates[i].bitrate; - *pos++ = (u8) (rate / 5); - } + *pos++ = ext_rates_len; + memcpy(pos, rates + supp_rates_len, ext_rates_len); + pos += ext_rates_len; } /* insert custom IEs that go before HT */ @@ -1018,7 +1023,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, } buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, - local->hw.conf.channel->band); + local->hw.conf.channel->band, + sdata->rc_rateidx_mask + [local->hw.conf.channel->band]); skb = ieee80211_probereq_get(&local->hw, &sdata->vif, ssid, ssid_len, -- cgit v1.2.3 From 651b52254fc061f02d965524e71de4333a009a5a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 28 Aug 2010 19:37:51 +0300 Subject: mac80211: Add DS Parameter Set into Probe Request on 2.4 GHz IEEE Std 802.11k-2008 added DS Parameter Set information element into Probe Request frames as an optional information on 2.4 GHz band (and mandatory, if radio measurements are enabled). This allows APs to filter out Probe Request frames that may be received from neighboring overlapping channels and by doing so, reduce the number of unnecessary frames in the air. Make mac80211 add this IE into Probe Request frames whenever the channel is known (i.e., whenever hwscan is not used). Signed-off-by: Jouni Malinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/scan.c | 3 ++- net/mac80211/util.c | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3641563d90f8..78a8d9208cec 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1256,7 +1256,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, const u8 *key, u8 key_len, u8 key_idx); int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band, u32 rate_mask); + enum ieee80211_band band, u32 rate_mask, + u8 channel); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 1623e9d2086e..5171a9581631 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -242,7 +242,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) local->hw_scan_req->n_channels = n_chans; ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, - req->ie, req->ie_len, band, (u32) -1); + req->ie, req->ie_len, band, (u32) -1, + 0); local->hw_scan_req->ie_len = ielen; return true; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bfd19d76667a..aba025d748e9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -895,7 +895,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band, u32 rate_mask) + enum ieee80211_band band, u32 rate_mask, + u8 channel) { struct ieee80211_supported_band *sband; u8 *pos; @@ -947,6 +948,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, pos += ext_rates_len; } + if (channel && sband->band == IEEE80211_BAND_2GHZ) { + *pos++ = WLAN_EID_DS_PARAMS; + *pos++ = 1; + *pos++ = channel; + } + /* insert custom IEs that go before HT */ if (ie && ie_len) { static const u8 before_ht[] = { @@ -1013,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, struct ieee80211_mgmt *mgmt; size_t buf_len; u8 *buf; + u8 chan; /* FIXME: come up with a proper value */ buf = kmalloc(200 + ie_len, GFP_KERNEL); @@ -1022,10 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, return; } + chan = ieee80211_frequency_to_channel( + local->hw.conf.channel->center_freq); + buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, local->hw.conf.channel->band, sdata->rc_rateidx_mask - [local->hw.conf.channel->band]); + [local->hw.conf.channel->band], + chan); skb = ieee80211_probereq_get(&local->hw, &sdata->vif, ssid, ssid_len, -- cgit v1.2.3 From ed627be38a1a07c6986a9f17c299f6afc86ac6b7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 12 Sep 2010 01:48:33 +0200 Subject: airo: remove "basic_rate" module option The "basic_rate" module option is not implemented correctly. If the rate was set to zero it was supposed to set it to "basic_rate | 0x80". Unfortunately the check to see if what zero was wrong and it checked "!ai->config.rates" (which is always false) instead of "!ai->config.rates[i]". This option was just used for development and it wasn't documented anywhere. Instead of fixing it, we can just remove it. Reported-by: Stanislaw Gruszka Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c7528e5794d1..fdebbe7eebb6 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -217,7 +217,6 @@ static const char *statsLabels[] = { (no spaces) list of rates (up to 8). */ static int rates[8]; -static int basic_rate; static char *ssids[3]; static int io[4]; @@ -250,7 +249,6 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350"); module_param_array(io, int, NULL, 0); module_param_array(irq, int, NULL, 0); -module_param(basic_rate, int, 0); module_param_array(rates, int, NULL, 0); module_param_array(ssids, charp, NULL, 0); module_param(auto_wep, int, 0); @@ -3884,15 +3882,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) ai->config.rates[i] = rates[i]; } } - if ( basic_rate > 0 ) { - for( i = 0; i < 8; i++ ) { - if ( ai->config.rates[i] == basic_rate || - !ai->config.rates ) { - ai->config.rates[i] = basic_rate | 0x80; - break; - } - } - } set_bit (FLAG_COMMIT, &ai->flags); } -- cgit v1.2.3 From eb7d3066cf864342e8ae6a5c1126a1602c4d06c0 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 21 Sep 2010 21:36:18 +0200 Subject: mac80211: clear txflags for ps-filtered frames This patch fixes stale mac80211_tx_control_flags for filtered / retried frames. Because ieee80211_handle_filtered_frame feeds skbs back into the tx path, they have to be stripped of some tx flags so they won't confuse the stack, driver or device. Cc: Acked-by: Johannes Berg Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- include/net/mac80211.h | 16 ++++++++++++++++ net/mac80211/status.c | 1 + 2 files changed, 17 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 12a49f0ba32c..5d1187d7c5e5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -321,6 +321,9 @@ struct ieee80211_bss_conf { * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this * frame and selects the maximum number of streams that it can use. + * + * Note: If you have to add new flags to the enumeration, then don't + * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. */ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), @@ -350,6 +353,19 @@ enum mac80211_tx_control_flags { #define IEEE80211_TX_CTL_STBC_SHIFT 23 +/* + * This definition is used as a mask to clear all temporary flags, which are + * set by the tx handlers for each transmission attempt by the mac80211 stack. + */ +#define IEEE80211_TX_TEMPORARY_FLAGS (IEEE80211_TX_CTL_NO_ACK | \ + IEEE80211_TX_CTL_CLEAR_PS_FILT | IEEE80211_TX_CTL_FIRST_FRAGMENT | \ + IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU | \ + IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK | \ + IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK | \ + IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \ + IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC | \ + IEEE80211_TX_CTL_STBC) + /** * enum mac80211_rate_control_flags - per-rate flags set by the * Rate Control algorithm. diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 571b32bfc54c..dd85006c4fe8 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, info->control.vif = &sta->sdata->vif; info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | IEEE80211_TX_INTFL_RETRANSMISSION; + info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; sta->tx_filtered_count++; -- cgit v1.2.3 From 9094537c3a9ef9e127e844254a74186735c9a90b Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 20 Sep 2010 22:54:46 -0700 Subject: ath9k: Fix tx struck state with paprd Paprd needs to be done only on active chains(not for all the chains that hw can support). The paprd training frames which are sent for inactive chains would be hanging on the hw queue without getting transmitted and would make the connection so unstable. This issue happens only with the hw which supports paprd cal(ar9003). Signed-off-by: Vasanthakumar Thiagarajan Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8b327bcad695..a13387882636 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -270,6 +270,7 @@ static void ath_paprd_activate(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath_common *common = ath9k_hw_common(ah); int chain; if (!caldata || !caldata->paprd_done) @@ -278,7 +279,7 @@ static void ath_paprd_activate(struct ath_softc *sc) ath9k_ps_wakeup(sc); ar9003_paprd_enable(ah, false); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->caps.tx_chainmask & BIT(chain))) + if (!(common->tx_chainmask & BIT(chain))) continue; ar9003_paprd_populate_single_table(ah, caldata, chain); @@ -300,6 +301,7 @@ void ath_paprd_calibrate(struct work_struct *work) struct ieee80211_supported_band *sband = &sc->sbands[band]; struct ath_tx_control txctl; struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath_common *common = ath9k_hw_common(ah); int qnum, ftype; int chain_ok = 0; int chain; @@ -333,7 +335,7 @@ void ath_paprd_calibrate(struct work_struct *work) ath9k_ps_wakeup(sc); ar9003_paprd_init_table(ah); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->caps.tx_chainmask & BIT(chain))) + if (!(common->tx_chainmask & BIT(chain))) continue; chain_ok = 0; -- cgit v1.2.3 From 9cf13668a5f8165a81349defc5f82c57a4a8279b Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 21 Sep 2010 12:58:09 +0530 Subject: ath9k_htc: Fix beacon distribution in IBSS mode This patch ensures fair beacon distribution in IBSS mode by configuring proper CWmin based on slot time. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index bd1506e69105..1b72aa482ac7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -235,7 +235,14 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) ath9k_hw_get_txq_props(ah, qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + /* For WIFI Beacon Distribution + * Long slot time : 2x cwmin + * Short slot time : 4x cwmin + */ + if (ah->slottime == ATH9K_SLOT_TIME_20) + qi.tqi_cwmin = 2*qi_be.tqi_cwmin; + else + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; qi.tqi_cwmax = qi_be.tqi_cwmax; if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { -- cgit v1.2.3 From 59104f062435c7816e39ee5ed504a69cb8037f10 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Sep 2010 20:16:27 +0000 Subject: ip: take care of last fragment in ip_append_data While investigating a bit, I found ip_fragment() slow path was taken because ip_append_data() provides following layout for a send(MTU + N*(MTU - 20)) syscall : - one skb with 1500 (mtu) bytes - N fragments of 1480 (mtu-20) bytes (before adding IP header) last fragment gets 17 bytes of trail data because of following bit: if (datalen == length + fraggap) alloclen += rt->dst.trailer_len; Then esp4 adds 16 bytes of data (while trailer_len is 17... hmm... another bug ?) In ip_fragment(), we notice last fragment is too big (1496 + 20) > mtu, so we take slow path, building another skb chain. In order to avoid taking slow path, we should correct ip_append_data() to make sure last fragment has real trail space, under mtu... Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e42762023c27..3551b6dc7419 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -926,16 +926,19 @@ alloc_new_skb: !(rt->dst.dev->features&NETIF_F_SG)) alloclen = mtu; else - alloclen = datalen + fragheaderlen; + alloclen = fraglen; /* The last fragment gets additional space at tail. * Note, with MSG_MORE we overallocate on fragments, * because we have no idea what fragment will be * the last. */ - if (datalen == length + fraggap) + if (datalen == length + fraggap) { alloclen += rt->dst.trailer_len; - + /* make sure mtu is not reached */ + if (datalen > mtu - fragheaderlen - rt->dst.trailer_len) + datalen -= ALIGN(rt->dst.trailer_len, 8); + } if (transhdrlen) { skb = sock_alloc_send_skb(sk, alloclen + hh_len + 15, -- cgit v1.2.3 From 77555ee7228234257957fd54daa0b69178906320 Mon Sep 17 00:00:00 2001 From: Masayuki Ohtake Date: Tue, 21 Sep 2010 01:44:11 +0000 Subject: net: Add Gigabit Ethernet driver of Topcliff PCH Signed-off-by: Masayuki Ohtake Signed-off-by: David S. Miller --- drivers/net/Kconfig | 12 + drivers/net/Makefile | 1 + drivers/net/pch_gbe/Makefile | 4 + drivers/net/pch_gbe/pch_gbe.h | 659 +++++++++ drivers/net/pch_gbe/pch_gbe_api.c | 245 ++++ drivers/net/pch_gbe/pch_gbe_api.h | 36 + drivers/net/pch_gbe/pch_gbe_ethtool.c | 584 ++++++++ drivers/net/pch_gbe/pch_gbe_main.c | 2473 +++++++++++++++++++++++++++++++++ drivers/net/pch_gbe/pch_gbe_param.c | 499 +++++++ drivers/net/pch_gbe/pch_gbe_phy.c | 274 ++++ drivers/net/pch_gbe/pch_gbe_phy.h | 37 + 11 files changed, 4824 insertions(+) create mode 100644 drivers/net/pch_gbe/Makefile create mode 100644 drivers/net/pch_gbe/pch_gbe.h create mode 100644 drivers/net/pch_gbe/pch_gbe_api.c create mode 100644 drivers/net/pch_gbe/pch_gbe_api.h create mode 100644 drivers/net/pch_gbe/pch_gbe_ethtool.c create mode 100644 drivers/net/pch_gbe/pch_gbe_main.c create mode 100644 drivers/net/pch_gbe/pch_gbe_param.c create mode 100644 drivers/net/pch_gbe/pch_gbe_phy.c create mode 100644 drivers/net/pch_gbe/pch_gbe_phy.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 53c4810b119e..ef683a993dce 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2515,6 +2515,18 @@ config S6GMAC source "drivers/net/stmmac/Kconfig" +config PCH_GBE + tristate "PCH Gigabit Ethernet" + depends on PCI + ---help--- + This is a gigabit ethernet driver for Topcliff PCH. + Topcliff PCH is the platform controller hub that is used in Intel's + general embedded platform. + Topcliff PCH has Gigabit Ethernet interface. + Using this interface, it is able to access system devices connected + to Gigabit Ethernet. + This driver enables Gigabit Ethernet function. + endif # NETDEV_1000 # diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 18a277709a2a..b8bf93d4a132 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -298,3 +298,4 @@ obj-$(CONFIG_WIMAX) += wimax/ obj-$(CONFIG_CAIF) += caif/ obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ +obj-$(CONFIG_PCH_GBE) += pch_gbe/ diff --git a/drivers/net/pch_gbe/Makefile b/drivers/net/pch_gbe/Makefile new file mode 100644 index 000000000000..31288d4ad248 --- /dev/null +++ b/drivers/net/pch_gbe/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PCH_GBE) += pch_gbe.o + +pch_gbe-y := pch_gbe_phy.o pch_gbe_ethtool.o pch_gbe_param.o +pch_gbe-y += pch_gbe_api.o pch_gbe_main.o diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h new file mode 100644 index 000000000000..b925ab359fc3 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -0,0 +1,659 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _PCH_GBE_H_ +#define _PCH_GBE_H_ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * pch_gbe_regs_mac_adr - Structure holding values of mac address registers + * @high Denotes the 1st to 4th byte from the initial of MAC address + * @low Denotes the 5th to 6th byte from the initial of MAC address + */ +struct pch_gbe_regs_mac_adr { + u32 high; + u32 low; +}; +/** + * pch_udc_regs - Structure holding values of MAC registers + */ +struct pch_gbe_regs { + u32 INT_ST; + u32 INT_EN; + u32 MODE; + u32 RESET; + u32 TCPIP_ACC; + u32 EX_LIST; + u32 INT_ST_HOLD; + u32 PHY_INT_CTRL; + u32 MAC_RX_EN; + u32 RX_FCTRL; + u32 PAUSE_REQ; + u32 RX_MODE; + u32 TX_MODE; + u32 RX_FIFO_ST; + u32 TX_FIFO_ST; + u32 TX_FID; + u32 TX_RESULT; + u32 PAUSE_PKT1; + u32 PAUSE_PKT2; + u32 PAUSE_PKT3; + u32 PAUSE_PKT4; + u32 PAUSE_PKT5; + u32 reserve[2]; + struct pch_gbe_regs_mac_adr mac_adr[16]; + u32 ADDR_MASK; + u32 MIIM; + u32 reserve2; + u32 RGMII_ST; + u32 RGMII_CTRL; + u32 reserve3[3]; + u32 DMA_CTRL; + u32 reserve4[3]; + u32 RX_DSC_BASE; + u32 RX_DSC_SIZE; + u32 RX_DSC_HW_P; + u32 RX_DSC_HW_P_HLD; + u32 RX_DSC_SW_P; + u32 reserve5[3]; + u32 TX_DSC_BASE; + u32 TX_DSC_SIZE; + u32 TX_DSC_HW_P; + u32 TX_DSC_HW_P_HLD; + u32 TX_DSC_SW_P; + u32 reserve6[3]; + u32 RX_DMA_ST; + u32 TX_DMA_ST; + u32 reserve7[2]; + u32 WOL_ST; + u32 WOL_CTRL; + u32 WOL_ADDR_MASK; +}; + +/* Interrupt Status */ +/* Interrupt Status Hold */ +/* Interrupt Enable */ +#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */ +#define PCH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */ +#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */ +#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */ +#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */ +#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */ +#define PCH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */ +#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */ +#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */ +#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */ +#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */ +#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */ +#define PCH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */ +#define PCH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */ +#define PCH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */ + +/* Mode */ +#define PCH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */ +#define PCH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */ +#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */ +#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */ +#define PCH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */ + +/* Reset */ +#define PCH_GBE_ALL_RST 0x80000000 /* All reset */ +#define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */ +#define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */ + +/* TCP/IP Accelerator Control */ +#define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */ +#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 /* RX TCP/IP ACC Disabled */ +#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 /* TX TCP/IP ACC Enable */ +#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 /* RX TCP/IP ACC Enable */ + +/* MAC RX Enable */ +#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */ + +/* RX Flow Control */ +#define PCH_GBE_FL_CTRL_EN 0x80000000 /* Pause packet is enabled */ + +/* Pause Packet Request */ +#define PCH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */ + +/* RX Mode */ +#define PCH_GBE_ADD_FIL_EN 0x80000000 /* Address Filtering Enable */ +/* Multicast Filtering Enable */ +#define PCH_GBE_MLT_FIL_EN 0x40000000 +/* Receive Almost Empty Threshold */ +#define PCH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */ +#define PCH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */ +#define PCH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */ +/* Receive Almost Full Threshold */ +#define PCH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */ +#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */ +#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */ +/* RX FIFO Read Triger Threshold */ +#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */ +#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */ +#define PCH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */ +#define PCH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */ +#define PCH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */ +#define PCH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */ +#define PCH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */ + +/* Receive Descriptor bit definitions */ +#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400 +#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200 +#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100 +#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0 +#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080 +#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040 +#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020 +#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010 +#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008 +#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004 +#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002 +#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001 +#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200 +#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100 +#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080 +#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040 +#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020 +#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010 +#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008 +#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004 +#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002 +#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001 + +/* Transmit Descriptor bit definitions */ +#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008 +#define PCH_GBE_TXD_CTRL_ITAG 0x0004 +#define PCH_GBE_TXD_CTRL_ICRC 0x0002 +#define PCH_GBE_TXD_CTRL_APAD 0x0001 +#define PCH_GBE_TXD_WORDS_SHIFT 2 +#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000 +#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000 +#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800 +#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400 +#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200 +#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100 +#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080 +#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040 +#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020 +#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010 +#define PCH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F + +/* TX Mode */ +#define PCH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */ +#define PCH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */ +#define PCH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */ +#define PCH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */ +#define PCH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */ +/* Frame Start Threshold */ +#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */ +#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */ +#define PCH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */ +/* Transmit Almost Empty Threshold */ +#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */ +#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */ +#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */ +#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */ +#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */ +#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */ +#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */ +/* Transmit Almost Full Threshold */ +#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */ +#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */ +#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */ + +/* RX FIFO Status */ +#define PCH_GBE_RF_ALM_FULL 0x80000000 /* RX FIFO is almost full. */ +#define PCH_GBE_RF_ALM_EMP 0x40000000 /* RX FIFO is almost empty. */ +#define PCH_GBE_RF_RD_TRG 0x20000000 /* Become more than RH_RD_TRG. */ +#define PCH_GBE_RF_STRWD 0x1FFE0000 /* The word count of RX FIFO. */ +#define PCH_GBE_RF_RCVING 0x00010000 /* Stored in RX FIFO. */ + +/* MAC Address Mask */ +#define PCH_GBE_BUSY 0x80000000 + +/* MIIM */ +#define PCH_GBE_MIIM_OPER_WRITE 0x04000000 +#define PCH_GBE_MIIM_OPER_READ 0x00000000 +#define PCH_GBE_MIIM_OPER_READY 0x04000000 +#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21 +#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16 + +/* RGMII Status */ +#define PCH_GBE_LINK_UP 0x80000008 +#define PCH_GBE_RXC_SPEED_MSK 0x00000006 +#define PCH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */ +#define PCH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */ +#define PCH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */ +#define PCH_GBE_DUPLEX_FULL 0x00000001 + +/* RGMII Control */ +#define PCH_GBE_CRS_SEL 0x00000010 +#define PCH_GBE_RGMII_RATE_125M 0x00000000 +#define PCH_GBE_RGMII_RATE_25M 0x00000008 +#define PCH_GBE_RGMII_RATE_2_5M 0x0000000C +#define PCH_GBE_RGMII_MODE_GMII 0x00000000 +#define PCH_GBE_RGMII_MODE_RGMII 0x00000002 +#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000 +#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001 + +/* DMA Control */ +#define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */ +#define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */ + +/* Wake On LAN Status */ +#define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */ +#define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */ + +/* The Frame registered in Address Recognizer */ +#define PCH_GBE_WLS_IND 0x00000002 +#define PCH_GBE_WLS_MP 0x00000001 /* Magic packet Address */ + +/* Wake On LAN Control */ +#define PCH_GBE_WLC_WOL_MODE 0x00010000 +#define PCH_GBE_WLC_IGN_TLONG 0x00000100 +#define PCH_GBE_WLC_IGN_TSHRT 0x00000080 +#define PCH_GBE_WLC_IGN_OCTER 0x00000040 +#define PCH_GBE_WLC_IGN_NBLER 0x00000020 +#define PCH_GBE_WLC_IGN_CRCER 0x00000010 +#define PCH_GBE_WLC_BR 0x00000008 +#define PCH_GBE_WLC_MLT 0x00000004 +#define PCH_GBE_WLC_IND 0x00000002 +#define PCH_GBE_WLC_MP 0x00000001 + +/* Wake On LAN Address Mask */ +#define PCH_GBE_WLA_BUSY 0x80000000 + + + +/* TX/RX descriptor defines */ +#define PCH_GBE_MAX_TXD 4096 +#define PCH_GBE_DEFAULT_TXD 256 +#define PCH_GBE_MIN_TXD 8 +#define PCH_GBE_MAX_RXD 4096 +#define PCH_GBE_DEFAULT_RXD 256 +#define PCH_GBE_MIN_RXD 8 + +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ +#define PCH_GBE_TX_DESC_MULTIPLE 8 +#define PCH_GBE_RX_DESC_MULTIPLE 8 + +/* Read/Write operation is done through MII Management IF */ +#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000) +#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000) + +/* flow control values */ +#define PCH_GBE_FC_NONE 0 +#define PCH_GBE_FC_RX_PAUSE 1 +#define PCH_GBE_FC_TX_PAUSE 2 +#define PCH_GBE_FC_FULL 3 +#define PCH_GBE_FC_DEFAULT PCH_GBE_FC_FULL + + +struct pch_gbe_hw; +/** + * struct pch_gbe_functions - HAL APi function pointer + * @get_bus_info: for pch_gbe_hal_get_bus_info + * @init_hw: for pch_gbe_hal_init_hw + * @read_phy_reg: for pch_gbe_hal_read_phy_reg + * @write_phy_reg: for pch_gbe_hal_write_phy_reg + * @reset_phy: for pch_gbe_hal_phy_hw_reset + * @sw_reset_phy: for pch_gbe_hal_phy_sw_reset + * @power_up_phy: for pch_gbe_hal_power_up_phy + * @power_down_phy: for pch_gbe_hal_power_down_phy + * @read_mac_addr: for pch_gbe_hal_read_mac_addr + */ +struct pch_gbe_functions { + void (*get_bus_info) (struct pch_gbe_hw *); + s32 (*init_hw) (struct pch_gbe_hw *); + s32 (*read_phy_reg) (struct pch_gbe_hw *, u32, u16 *); + s32 (*write_phy_reg) (struct pch_gbe_hw *, u32, u16); + void (*reset_phy) (struct pch_gbe_hw *); + void (*sw_reset_phy) (struct pch_gbe_hw *); + void (*power_up_phy) (struct pch_gbe_hw *hw); + void (*power_down_phy) (struct pch_gbe_hw *hw); + s32 (*read_mac_addr) (struct pch_gbe_hw *); +}; + +/** + * struct pch_gbe_mac_info - MAC infomation + * @addr[6]: Store the MAC address + * @fc: Mode of flow control + * @fc_autoneg: Auto negotiation enable for flow control setting + * @tx_fc_enable: Enable flag of Transmit flow control + * @max_frame_size: Max transmit frame size + * @min_frame_size: Min transmit frame size + * @autoneg: Auto negotiation enable + * @link_speed: Link speed + * @link_duplex: Link duplex + */ +struct pch_gbe_mac_info { + u8 addr[6]; + u8 fc; + u8 fc_autoneg; + u8 tx_fc_enable; + u32 max_frame_size; + u32 min_frame_size; + u8 autoneg; + u16 link_speed; + u16 link_duplex; +}; + +/** + * struct pch_gbe_phy_info - PHY infomation + * @addr: PHY address + * @id: PHY's identifier + * @revision: PHY's revision + * @reset_delay_us: HW reset delay time[us] + * @autoneg_advertised: Autoneg advertised + */ +struct pch_gbe_phy_info { + u32 addr; + u32 id; + u32 revision; + u32 reset_delay_us; + u16 autoneg_advertised; +}; + +/*! + * @ingroup Gigabit Ether driver Layer + * @struct pch_gbe_bus_info + * @brief Bus infomation + */ +struct pch_gbe_bus_info { + u8 type; + u8 speed; + u8 width; +}; + +/*! + * @ingroup Gigabit Ether driver Layer + * @struct pch_gbe_hw + * @brief Hardware infomation + */ +struct pch_gbe_hw { + void *back; + + struct pch_gbe_regs __iomem *reg; + spinlock_t miim_lock; + + const struct pch_gbe_functions *func; + struct pch_gbe_mac_info mac; + struct pch_gbe_phy_info phy; + struct pch_gbe_bus_info bus; +}; + +/** + * struct pch_gbe_rx_desc - Receive Descriptor + * @buffer_addr: RX Frame Buffer Address + * @tcp_ip_status: TCP/IP Accelerator Status + * @rx_words_eob: RX word count and Byte position + * @gbec_status: GMAC Status + * @dma_status: DMA Status + * @reserved1: Reserved + * @reserved2: Reserved + */ +struct pch_gbe_rx_desc { + u32 buffer_addr; + u32 tcp_ip_status; + u16 rx_words_eob; + u16 gbec_status; + u8 dma_status; + u8 reserved1; + u16 reserved2; +}; + +/** + * struct pch_gbe_tx_desc - Transmit Descriptor + * @buffer_addr: TX Frame Buffer Address + * @length: Data buffer length + * @reserved1: Reserved + * @tx_words_eob: TX word count and Byte position + * @tx_frame_ctrl: TX Frame Control + * @dma_status: DMA Status + * @reserved2: Reserved + * @gbec_status: GMAC Status + */ +struct pch_gbe_tx_desc { + u32 buffer_addr; + u16 length; + u16 reserved1; + u16 tx_words_eob; + u16 tx_frame_ctrl; + u8 dma_status; + u8 reserved2; + u16 gbec_status; +}; + + +/** + * struct pch_gbe_buffer - Buffer infomation + * @skb: pointer to a socket buffer + * @dma: DMA address + * @time_stamp: time stamp + * @length: data size + */ +struct pch_gbe_buffer { + struct sk_buff *skb; + dma_addr_t dma; + unsigned long time_stamp; + u16 length; + bool mapped; +}; + +/** + * struct pch_gbe_tx_ring - tx ring infomation + * @tx_lock: spinlock structs + * @desc: pointer to the descriptor ring memory + * @dma: physical address of the descriptor ring + * @size: length of descriptor ring in bytes + * @count: number of descriptors in the ring + * @next_to_use: next descriptor to associate a buffer with + * @next_to_clean: next descriptor to check for DD status bit + * @buffer_info: array of buffer information structs + */ +struct pch_gbe_tx_ring { + spinlock_t tx_lock; + struct pch_gbe_tx_desc *desc; + dma_addr_t dma; + unsigned int size; + unsigned int count; + unsigned int next_to_use; + unsigned int next_to_clean; + struct pch_gbe_buffer *buffer_info; +}; + +/** + * struct pch_gbe_rx_ring - rx ring infomation + * @desc: pointer to the descriptor ring memory + * @dma: physical address of the descriptor ring + * @size: length of descriptor ring in bytes + * @count: number of descriptors in the ring + * @next_to_use: next descriptor to associate a buffer with + * @next_to_clean: next descriptor to check for DD status bit + * @buffer_info: array of buffer information structs + */ +struct pch_gbe_rx_ring { + struct pch_gbe_rx_desc *desc; + dma_addr_t dma; + unsigned int size; + unsigned int count; + unsigned int next_to_use; + unsigned int next_to_clean; + struct pch_gbe_buffer *buffer_info; +}; + +/** + * struct pch_gbe_hw_stats - Statistics counters collected by the MAC + * @rx_packets: total packets received + * @tx_packets: total packets transmitted + * @rx_bytes: total bytes received + * @tx_bytes: total bytes transmitted + * @rx_errors: bad packets received + * @tx_errors: packet transmit problems + * @rx_dropped: no space in Linux buffers + * @tx_dropped: no space available in Linux + * @multicast: multicast packets received + * @collisions: collisions + * @rx_crc_errors: received packet with crc error + * @rx_frame_errors: received frame alignment error + * @rx_alloc_buff_failed: allocate failure of a receive buffer + * @tx_length_errors: transmit length error + * @tx_aborted_errors: transmit aborted error + * @tx_carrier_errors: transmit carrier error + * @tx_timeout_count: Number of transmit timeout + * @tx_restart_count: Number of transmit restert + * @intr_rx_dsc_empty_count: Interrupt count of receive descriptor empty + * @intr_rx_frame_err_count: Interrupt count of receive frame error + * @intr_rx_fifo_err_count: Interrupt count of receive FIFO error + * @intr_rx_dma_err_count: Interrupt count of receive DMA error + * @intr_tx_fifo_err_count: Interrupt count of transmit FIFO error + * @intr_tx_dma_err_count: Interrupt count of transmit DMA error + * @intr_tcpip_err_count: Interrupt count of TCP/IP Accelerator + */ +struct pch_gbe_hw_stats { + u32 rx_packets; + u32 tx_packets; + u32 rx_bytes; + u32 tx_bytes; + u32 rx_errors; + u32 tx_errors; + u32 rx_dropped; + u32 tx_dropped; + u32 multicast; + u32 collisions; + u32 rx_crc_errors; + u32 rx_frame_errors; + u32 rx_alloc_buff_failed; + u32 tx_length_errors; + u32 tx_aborted_errors; + u32 tx_carrier_errors; + u32 tx_timeout_count; + u32 tx_restart_count; + u32 intr_rx_dsc_empty_count; + u32 intr_rx_frame_err_count; + u32 intr_rx_fifo_err_count; + u32 intr_rx_dma_err_count; + u32 intr_tx_fifo_err_count; + u32 intr_tx_dma_err_count; + u32 intr_tcpip_err_count; +}; + +/** + * struct pch_gbe_adapter - board specific private data structure + * @stats_lock: Spinlock structure for status + * @tx_queue_lock: Spinlock structure for transmit + * @ethtool_lock: Spinlock structure for ethtool + * @irq_sem: Semaphore for interrupt + * @netdev: Pointer of network device structure + * @pdev: Pointer of pci device structure + * @polling_netdev: Pointer of polling network device structure + * @napi: NAPI structure + * @hw: Pointer of hardware structure + * @stats: Hardware status + * @reset_task: Reset task + * @mii: MII information structure + * @watchdog_timer: Watchdog timer list + * @wake_up_evt: Wake up event + * @config_space: Configuration space + * @msg_enable: Driver message level + * @led_status: LED status + * @tx_ring: Pointer of Tx descriptor ring structure + * @rx_ring: Pointer of Rx descriptor ring structure + * @rx_buffer_len: Receive buffer length + * @tx_queue_len: Transmit queue length + * @rx_csum: Receive TCP/IP checksum enable/disable + * @tx_csum: Transmit TCP/IP checksum enable/disable + * @have_msi: PCI MSI mode flag + */ + +struct pch_gbe_adapter { + spinlock_t stats_lock; + spinlock_t tx_queue_lock; + spinlock_t ethtool_lock; + atomic_t irq_sem; + struct net_device *netdev; + struct pci_dev *pdev; + struct net_device *polling_netdev; + struct napi_struct napi; + struct pch_gbe_hw hw; + struct pch_gbe_hw_stats stats; + struct work_struct reset_task; + struct mii_if_info mii; + struct timer_list watchdog_timer; + u32 wake_up_evt; + u32 *config_space; + unsigned long led_status; + struct pch_gbe_tx_ring *tx_ring; + struct pch_gbe_rx_ring *rx_ring; + unsigned long rx_buffer_len; + unsigned long tx_queue_len; + bool rx_csum; + bool tx_csum; + bool have_msi; +}; + +extern const char pch_driver_version[]; + +/* pch_gbe_main.c */ +extern int pch_gbe_up(struct pch_gbe_adapter *adapter); +extern void pch_gbe_down(struct pch_gbe_adapter *adapter); +extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter); +extern void pch_gbe_reset(struct pch_gbe_adapter *adapter); +extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *txdr); +extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rxdr); +extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring); +extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring); +extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); +extern int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); +extern void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, + int data); +/* pch_gbe_param.c */ +extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); + +/* pch_gbe_ethtool.c */ +extern void pch_gbe_set_ethtool_ops(struct net_device *netdev); + +/* pch_gbe_mac.c */ +extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw); +extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw); +extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, + u32 addr, u32 dir, u32 reg, u16 data); +#endif /* _PCH_GBE_H_ */ diff --git a/drivers/net/pch_gbe/pch_gbe_api.c b/drivers/net/pch_gbe/pch_gbe_api.c new file mode 100644 index 000000000000..db53d2a943e0 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_api.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include "pch_gbe.h" +#include "pch_gbe_phy.h" + +/* bus type values */ +#define pch_gbe_bus_type_unknown 0 +#define pch_gbe_bus_type_pci 1 +#define pch_gbe_bus_type_pcix 2 +#define pch_gbe_bus_type_pci_express 3 +#define pch_gbe_bus_type_reserved 4 + +/* bus speed values */ +#define pch_gbe_bus_speed_unknown 0 +#define pch_gbe_bus_speed_33 1 +#define pch_gbe_bus_speed_66 2 +#define pch_gbe_bus_speed_100 3 +#define pch_gbe_bus_speed_120 4 +#define pch_gbe_bus_speed_133 5 +#define pch_gbe_bus_speed_2500 6 +#define pch_gbe_bus_speed_reserved 7 + +/* bus width values */ +#define pch_gbe_bus_width_unknown 0 +#define pch_gbe_bus_width_pcie_x1 1 +#define pch_gbe_bus_width_pcie_x2 2 +#define pch_gbe_bus_width_pcie_x4 4 +#define pch_gbe_bus_width_32 5 +#define pch_gbe_bus_width_64 6 +#define pch_gbe_bus_width_reserved 7 + +/** + * pch_gbe_plat_get_bus_info - Obtain bus information for adapter + * @hw: Pointer to the HW structure + */ +static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw) +{ + hw->bus.type = pch_gbe_bus_type_pci_express; + hw->bus.speed = pch_gbe_bus_speed_2500; + hw->bus.width = pch_gbe_bus_width_pcie_x1; +} + +/** + * pch_gbe_plat_init_hw - Initialize hardware + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * Negative value: Failed-EBUSY + */ +static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw) +{ + s32 ret_val; + + ret_val = pch_gbe_phy_get_id(hw); + if (ret_val) { + pr_err("pch_gbe_phy_get_id error\n"); + return ret_val; + } + pch_gbe_phy_init_setting(hw); + /* Setup Mac interface option RGMII */ +#ifdef PCH_GBE_MAC_IFOP_RGMII + pch_gbe_phy_set_rgmii(hw); +#endif + return ret_val; +} + +static const struct pch_gbe_functions pch_gbe_ops = { + .get_bus_info = pch_gbe_plat_get_bus_info, + .init_hw = pch_gbe_plat_init_hw, + .read_phy_reg = pch_gbe_phy_read_reg_miic, + .write_phy_reg = pch_gbe_phy_write_reg_miic, + .reset_phy = pch_gbe_phy_hw_reset, + .sw_reset_phy = pch_gbe_phy_sw_reset, + .power_up_phy = pch_gbe_phy_power_up, + .power_down_phy = pch_gbe_phy_power_down, + .read_mac_addr = pch_gbe_mac_read_mac_addr +}; + +/** + * pch_gbe_plat_init_function_pointers - Init func ptrs + * @hw: Pointer to the HW structure + */ +void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw) +{ + /* Set PHY parameter */ + hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US; + /* Set function pointers */ + hw->func = &pch_gbe_ops; +} + +/** + * pch_gbe_hal_setup_init_funcs - Initializes function pointers + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw) +{ + if (!hw->reg) { + pr_err("ERROR: Registers not mapped\n"); + return -ENOSYS; + } + pch_gbe_plat_init_function_pointers(hw); + return 0; +} + +/** + * pch_gbe_hal_get_bus_info - Obtain bus information for adapter + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw) +{ + if (!hw->func->get_bus_info) + pr_err("ERROR: configuration\n"); + else + hw->func->get_bus_info(hw); +} + +/** + * pch_gbe_hal_init_hw - Initialize hardware + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw) +{ + if (!hw->func->init_hw) { + pr_err("ERROR: configuration\n"); + return -ENOSYS; + } + return hw->func->init_hw(hw); +} + +/** + * pch_gbe_hal_read_phy_reg - Reads PHY register + * @hw: Pointer to the HW structure + * @offset: The register to read + * @data: The buffer to store the 16-bit read. + * Returns + * 0: Successfully + * Negative value: Failed + */ +inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, + u16 *data) +{ + if (!hw->func->read_phy_reg) + return 0; + return hw->func->read_phy_reg(hw, offset, data); +} + +/** + * pch_gbe_hal_write_phy_reg - Writes PHY register + * @hw: Pointer to the HW structure + * @offset: The register to read + * @data: The value to write. + * Returns + * 0: Successfully + * Negative value: Failed + */ +inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, + u16 data) +{ + if (!hw->func->write_phy_reg) + return 0; + return hw->func->write_phy_reg(hw, offset, data); +} + +/** + * pch_gbe_hal_phy_hw_reset - Hard PHY reset + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw) +{ + if (!hw->func->reset_phy) + pr_err("ERROR: configuration\n"); + else + hw->func->reset_phy(hw); +} + +/** + * pch_gbe_hal_phy_sw_reset - Soft PHY reset + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw) +{ + if (!hw->func->sw_reset_phy) + pr_err("ERROR: configuration\n"); + else + hw->func->sw_reset_phy(hw); +} + +/** + * pch_gbe_hal_read_mac_addr - Reads MAC address + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw) +{ + if (!hw->func->read_mac_addr) { + pr_err("ERROR: configuration\n"); + return -ENOSYS; + } + return hw->func->read_mac_addr(hw); +} + +/** + * pch_gbe_hal_power_up_phy - Power up PHY + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw) +{ + if (hw->func->power_up_phy) + hw->func->power_up_phy(hw); +} + +/** + * pch_gbe_hal_power_down_phy - Power down PHY + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw) +{ + if (hw->func->power_down_phy) + hw->func->power_down_phy(hw); +} diff --git a/drivers/net/pch_gbe/pch_gbe_api.h b/drivers/net/pch_gbe/pch_gbe_api.h new file mode 100644 index 000000000000..94aaac5b057b --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_api.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PCH_GBE_API_H_ +#define _PCH_GBE_API_H_ + +#include "pch_gbe_phy.h" + +s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw); +void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data); +s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data); +void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw); +void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw); +void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw); +void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw); + +#endif diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c new file mode 100644 index 000000000000..e06c6aea4527 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -0,0 +1,584 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include "pch_gbe.h" +#include "pch_gbe_api.h" + +/** + * pch_gbe_stats - Stats item infomation + */ +struct pch_gbe_stats { + char string[ETH_GSTRING_LEN]; + size_t size; + size_t offset; +}; + +#define PCH_GBE_STAT(m) \ +{ \ + .string = #m, \ + .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \ + .offset = offsetof(struct pch_gbe_hw_stats, m), \ +} + +/** + * pch_gbe_gstrings_stats - ethtool information status name list + */ +static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = { + PCH_GBE_STAT(rx_packets), + PCH_GBE_STAT(tx_packets), + PCH_GBE_STAT(rx_bytes), + PCH_GBE_STAT(tx_bytes), + PCH_GBE_STAT(rx_errors), + PCH_GBE_STAT(tx_errors), + PCH_GBE_STAT(rx_dropped), + PCH_GBE_STAT(tx_dropped), + PCH_GBE_STAT(multicast), + PCH_GBE_STAT(collisions), + PCH_GBE_STAT(rx_crc_errors), + PCH_GBE_STAT(rx_frame_errors), + PCH_GBE_STAT(rx_alloc_buff_failed), + PCH_GBE_STAT(tx_length_errors), + PCH_GBE_STAT(tx_aborted_errors), + PCH_GBE_STAT(tx_carrier_errors), + PCH_GBE_STAT(tx_timeout_count), + PCH_GBE_STAT(tx_restart_count), + PCH_GBE_STAT(intr_rx_dsc_empty_count), + PCH_GBE_STAT(intr_rx_frame_err_count), + PCH_GBE_STAT(intr_rx_fifo_err_count), + PCH_GBE_STAT(intr_rx_dma_err_count), + PCH_GBE_STAT(intr_tx_fifo_err_count), + PCH_GBE_STAT(intr_tx_dma_err_count), + PCH_GBE_STAT(intr_tcpip_err_count) +}; + +#define PCH_GBE_QUEUE_STATS_LEN 0 +#define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats) +#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN) + +#define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4) +#define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN) +/** + * pch_gbe_get_settings - Get device-specific settings + * @netdev: Network interface device structure + * @ecmd: Ethtool command + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int ret; + + ret = mii_ethtool_gset(&adapter->mii, ecmd); + ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half); + ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half); + + if (!netif_carrier_ok(adapter->netdev)) + ecmd->speed = -1; + return ret; +} + +/** + * pch_gbe_set_settings - Set device-specific settings + * @netdev: Network interface device structure + * @ecmd: Ethtool command + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int ret; + + pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); + + if (ecmd->speed == -1) + ecmd->speed = SPEED_1000; + ecmd->duplex = DUPLEX_FULL; + ret = mii_ethtool_sset(&adapter->mii, ecmd); + if (ret) { + pr_err("Error: mii_ethtool_sset\n"); + return ret; + } + hw->mac.link_speed = ecmd->speed; + hw->mac.link_duplex = ecmd->duplex; + hw->phy.autoneg_advertised = ecmd->advertising; + hw->mac.autoneg = ecmd->autoneg; + pch_gbe_hal_phy_sw_reset(hw); + + /* reset the link */ + if (netif_running(adapter->netdev)) { + pch_gbe_down(adapter); + ret = pch_gbe_up(adapter); + } else { + pch_gbe_reset(adapter); + } + return ret; +} + +/** + * pch_gbe_get_regs_len - Report the size of device registers + * @netdev: Network interface device structure + * Returns: the size of device registers. + */ +static int pch_gbe_get_regs_len(struct net_device *netdev) +{ + return PCH_GBE_REGS_LEN * (int)sizeof(u32); +} + +/** + * pch_gbe_get_drvinfo - Report driver information + * @netdev: Network interface device structure + * @drvinfo: Driver information structure + */ +static void pch_gbe_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + strcpy(drvinfo->driver, KBUILD_MODNAME); + strcpy(drvinfo->version, pch_driver_version); + strcpy(drvinfo->fw_version, "N/A"); + strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); + drvinfo->regdump_len = pch_gbe_get_regs_len(netdev); +} + +/** + * pch_gbe_get_regs - Get device registers + * @netdev: Network interface device structure + * @regs: Ethtool register structure + * @p: Buffer pointer of read device register date + */ +static void pch_gbe_get_regs(struct net_device *netdev, + struct ethtool_regs *regs, void *p) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + u32 *regs_buff = p; + u16 i, tmp; + + regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device; + for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++) + *regs_buff++ = ioread32(&hw->reg->INT_ST + i); + /* PHY register */ + for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) { + pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp); + *regs_buff++ = tmp; + } +} + +/** + * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled + * @netdev: Network interface device structure + * @wol: Wake-on-Lan information + */ +static void pch_gbe_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; + wol->wolopts = 0; + + if ((adapter->wake_up_evt & PCH_GBE_WLC_IND)) + wol->wolopts |= WAKE_UCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT)) + wol->wolopts |= WAKE_MCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_BR)) + wol->wolopts |= WAKE_BCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_MP)) + wol->wolopts |= WAKE_MAGIC; +} + +/** + * pch_gbe_set_wol - Turn Wake-on-Lan on or off + * @netdev: Network interface device structure + * @wol: Pointer of wake-on-Lan information straucture + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))) + return -EOPNOTSUPP; + /* these settings will always override what we currently have */ + adapter->wake_up_evt = 0; + + if ((wol->wolopts & WAKE_UCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_IND; + if ((wol->wolopts & WAKE_MCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_MLT; + if ((wol->wolopts & WAKE_BCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_BR; + if ((wol->wolopts & WAKE_MAGIC)) + adapter->wake_up_evt |= PCH_GBE_WLC_MP; + return 0; +} + +/** + * pch_gbe_nway_reset - Restart autonegotiation + * @netdev: Network interface device structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_nway_reset(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + return mii_nway_restart(&adapter->mii); +} + +/** + * pch_gbe_get_ringparam - Report ring sizes + * @netdev: Network interface device structure + * @ring: Ring param structure + */ +static void pch_gbe_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *txdr = adapter->tx_ring; + struct pch_gbe_rx_ring *rxdr = adapter->rx_ring; + + ring->rx_max_pending = PCH_GBE_MAX_RXD; + ring->tx_max_pending = PCH_GBE_MAX_TXD; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = rxdr->count; + ring->tx_pending = txdr->count; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; +} + +/** + * pch_gbe_set_ringparam - Set ring sizes + * @netdev: Network interface device structure + * @ring: Ring param structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *txdr, *tx_old; + struct pch_gbe_rx_ring *rxdr, *rx_old; + int tx_ring_size, rx_ring_size; + int err = 0; + + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring); + rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring); + + if ((netif_running(adapter->netdev))) + pch_gbe_down(adapter); + tx_old = adapter->tx_ring; + rx_old = adapter->rx_ring; + + txdr = kzalloc(tx_ring_size, GFP_KERNEL); + if (!txdr) { + err = -ENOMEM; + goto err_alloc_tx; + } + rxdr = kzalloc(rx_ring_size, GFP_KERNEL); + if (!rxdr) { + err = -ENOMEM; + goto err_alloc_rx; + } + adapter->tx_ring = txdr; + adapter->rx_ring = rxdr; + + rxdr->count = + clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); + rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE); + + txdr->count = + clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); + txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE); + + if ((netif_running(adapter->netdev))) { + /* Try to get new resources before deleting old */ + err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring); + if (err) + goto err_setup_rx; + err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring); + if (err) + goto err_setup_tx; + /* save the new, restore the old in order to free it, + * then restore the new back again */ +#ifdef RINGFREE + adapter->rx_ring = rx_old; + adapter->tx_ring = tx_old; + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); + kfree(tx_old); + kfree(rx_old); + adapter->rx_ring = rxdr; + adapter->tx_ring = txdr; +#else + pch_gbe_free_rx_resources(adapter, rx_old); + pch_gbe_free_tx_resources(adapter, tx_old); + kfree(tx_old); + kfree(rx_old); + adapter->rx_ring = rxdr; + adapter->tx_ring = txdr; +#endif + err = pch_gbe_up(adapter); + } + return err; + +err_setup_tx: + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); +err_setup_rx: + adapter->rx_ring = rx_old; + adapter->tx_ring = tx_old; + kfree(rxdr); +err_alloc_rx: + kfree(txdr); +err_alloc_tx: + if (netif_running(adapter->netdev)) + pch_gbe_up(adapter); + return err; +} + +/** + * pch_gbe_get_pauseparam - Report pause parameters + * @netdev: Network interface device structure + * @pause: Pause parameters structure + */ +static void pch_gbe_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pause->autoneg = + ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE); + + if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) { + pause->rx_pause = 1; + } else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) { + pause->tx_pause = 1; + } else if (hw->mac.fc == PCH_GBE_FC_FULL) { + pause->rx_pause = 1; + pause->tx_pause = 1; + } +} + +/** + * pch_gbe_set_pauseparam - Set pause paramters + * @netdev: Network interface device structure + * @pause: Pause parameters structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int ret = 0; + + hw->mac.fc_autoneg = pause->autoneg; + if ((pause->rx_pause) && (pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_FULL; + else if ((pause->rx_pause) && (!pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_RX_PAUSE; + else if ((!pause->rx_pause) && (pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_TX_PAUSE; + else if ((!pause->rx_pause) && (!pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_NONE; + + if (hw->mac.fc_autoneg == AUTONEG_ENABLE) { + if ((netif_running(adapter->netdev))) { + pch_gbe_down(adapter); + ret = pch_gbe_up(adapter); + } else { + pch_gbe_reset(adapter); + } + } else { + ret = pch_gbe_mac_force_mac_fc(hw); + } + return ret; +} + +/** + * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off + * @netdev: Network interface device structure + * Returns + * true(1): Checksum On + * false(0): Checksum Off + */ +static u32 pch_gbe_get_rx_csum(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + return adapter->rx_csum; +} + +/** + * pch_gbe_set_rx_csum - Turn receive checksum on or off + * @netdev: Network interface device structure + * @data: Checksum On[true] or Off[false] + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + adapter->rx_csum = data; + if ((netif_running(netdev))) + pch_gbe_reinit_locked(adapter); + else + pch_gbe_reset(adapter); + + return 0; +} + +/** + * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off + * @netdev: Network interface device structure + * Returns + * true(1): Checksum On + * false(0): Checksum Off + */ +static u32 pch_gbe_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_HW_CSUM) != 0; +} + +/** + * pch_gbe_set_tx_csum - Turn transmit checksums on or off + * @netdev: Network interface device structure + * @data: Checksum on[true] or off[false] + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + adapter->tx_csum = data; + if (data) + netdev->features |= NETIF_F_HW_CSUM; + else + netdev->features &= ~NETIF_F_HW_CSUM; + return 0; +} + +/** + * pch_gbe_get_strings - Return a set of strings that describe the requested + * objects + * @netdev: Network interface device structure + * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS] + * @data: Pointer of read string data. + */ +static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset, + u8 *data) +{ + u8 *p = data; + int i; + + switch (stringset) { + case (u32) ETH_SS_STATS: + for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) { + memcpy(p, pch_gbe_gstrings_stats[i].string, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + break; + } +} + +/** + * pch_gbe_get_ethtool_stats - Return statistics about the device + * @netdev: Network interface device structure + * @stats: Ethtool statue structure + * @data: Pointer of read status area + */ +static void pch_gbe_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, u64 *data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int i; + const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats; + char *hw_stats = (char *)&adapter->stats; + + pch_gbe_update_stats(adapter); + for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) { + char *p = hw_stats + gstats->offset; + data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p); + gstats++; + } +} + +static int pch_gbe_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return PCH_GBE_STATS_LEN; + default: + return -EOPNOTSUPP; + } +} + +static const struct ethtool_ops pch_gbe_ethtool_ops = { + .get_settings = pch_gbe_get_settings, + .set_settings = pch_gbe_set_settings, + .get_drvinfo = pch_gbe_get_drvinfo, + .get_regs_len = pch_gbe_get_regs_len, + .get_regs = pch_gbe_get_regs, + .get_wol = pch_gbe_get_wol, + .set_wol = pch_gbe_set_wol, + .nway_reset = pch_gbe_nway_reset, + .get_link = ethtool_op_get_link, + .get_ringparam = pch_gbe_get_ringparam, + .set_ringparam = pch_gbe_set_ringparam, + .get_pauseparam = pch_gbe_get_pauseparam, + .set_pauseparam = pch_gbe_set_pauseparam, + .get_rx_csum = pch_gbe_get_rx_csum, + .set_rx_csum = pch_gbe_set_rx_csum, + .get_tx_csum = pch_gbe_get_tx_csum, + .set_tx_csum = pch_gbe_set_tx_csum, + .get_strings = pch_gbe_get_strings, + .get_ethtool_stats = pch_gbe_get_ethtool_stats, + .get_sset_count = pch_gbe_get_sset_count, +}; + +void pch_gbe_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops); +} diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c new file mode 100644 index 000000000000..53c56cf8aca2 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -0,0 +1,2473 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" +#include "pch_gbe_api.h" + +#define DRV_VERSION "1.00" +const char pch_driver_version[] = DRV_VERSION; + +#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */ +#define PCH_GBE_MAR_ENTRIES 16 +#define PCH_GBE_SHORT_PKT 64 +#define DSC_INIT16 0xC000 +#define PCH_GBE_DMA_ALIGN 0 +#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ +#define PCH_GBE_COPYBREAK_DEFAULT 256 +#define PCH_GBE_PCI_BAR 1 + +#define PCH_GBE_TX_WEIGHT 64 +#define PCH_GBE_RX_WEIGHT 64 +#define PCH_GBE_RX_BUFFER_WRITE 16 + +/* Initialize the wake-on-LAN settings */ +#define PCH_GBE_WL_INIT_SETTING (PCH_GBE_WLC_MP) + +#define PCH_GBE_MAC_RGMII_CTRL_SETTING ( \ + PCH_GBE_CHIP_TYPE_INTERNAL | \ + PCH_GBE_RGMII_MODE_RGMII | \ + PCH_GBE_CRS_SEL \ + ) + +/* Ethertype field values */ +#define PCH_GBE_MAX_JUMBO_FRAME_SIZE 10318 +#define PCH_GBE_FRAME_SIZE_2048 2048 +#define PCH_GBE_FRAME_SIZE_4096 4096 +#define PCH_GBE_FRAME_SIZE_8192 8192 + +#define PCH_GBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) +#define PCH_GBE_RX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_rx_desc) +#define PCH_GBE_TX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_tx_desc) +#define PCH_GBE_DESC_UNUSED(R) \ + ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ + (R)->next_to_clean - (R)->next_to_use - 1) + +/* Pause packet value */ +#define PCH_GBE_PAUSE_PKT1_VALUE 0x00C28001 +#define PCH_GBE_PAUSE_PKT2_VALUE 0x00000100 +#define PCH_GBE_PAUSE_PKT4_VALUE 0x01000888 +#define PCH_GBE_PAUSE_PKT5_VALUE 0x0000FFFF + +#define PCH_GBE_ETH_ALEN 6 + +/* This defines the bits that are set in the Interrupt Mask + * Set/Read Register. Each bit is documented below: + * o RXT0 = Receiver Timer Interrupt (ring 0) + * o TXDW = Transmit Descriptor Written Back + * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) + * o RXSEQ = Receive Sequence Error + * o LSC = Link Status Change + */ +#define PCH_GBE_INT_ENABLE_MASK ( \ + PCH_GBE_INT_RX_DMA_CMPLT | \ + PCH_GBE_INT_RX_DSC_EMP | \ + PCH_GBE_INT_WOL_DET | \ + PCH_GBE_INT_TX_CMPLT \ + ) + + +static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; + +/** + * pch_gbe_mac_read_mac_addr - Read MAC address + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + */ +s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) +{ + u32 adr1a, adr1b; + + adr1a = ioread32(&hw->reg->mac_adr[0].high); + adr1b = ioread32(&hw->reg->mac_adr[0].low); + + hw->mac.addr[0] = (u8)(adr1a & 0xFF); + hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF); + hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF); + hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF); + hw->mac.addr[4] = (u8)(adr1b & 0xFF); + hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF); + + pr_debug("hw->mac.addr : %pM\n", hw->mac.addr); + return 0; +} + +/** + * pch_gbe_wait_clr_bit - Wait to clear a bit + * @reg: Pointer of register + * @busy: Busy bit + */ +void pch_gbe_wait_clr_bit(void *reg, u32 bit) +{ + u32 tmp; + /* wait busy */ + tmp = 1000; + while ((ioread32(reg) & bit) && --tmp) + cpu_relax(); + if (!tmp) + pr_err("Error: busy bit is not cleared\n"); +} +/** + * pch_gbe_mac_mar_set - Set MAC address register + * @hw: Pointer to the HW structure + * @addr: Pointer to the MAC address + * @index: MAC address array register + */ +void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) +{ + u32 mar_low, mar_high, adrmask; + + pr_debug("index : 0x%x\n", index); + + /* + * HW expects these in little endian so we reverse the byte order + * from network order (big endian) to little endian + */ + mar_high = ((u32) addr[0] | ((u32) addr[1] << 8) | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + mar_low = ((u32) addr[4] | ((u32) addr[5] << 8)); + /* Stop the MAC Address of index. */ + adrmask = ioread32(&hw->reg->ADDR_MASK); + iowrite32((adrmask | (0x0001 << index)), &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); + /* Set the MAC address to the MAC address 1A/1B register */ + iowrite32(mar_high, &hw->reg->mac_adr[index].high); + iowrite32(mar_low, &hw->reg->mac_adr[index].low); + /* Start the MAC address of index */ + iowrite32((adrmask & ~(0x0001 << index)), &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); +} + +/** + * pch_gbe_mac_reset_hw - Reset hardware + * @hw: Pointer to the HW structure + */ +void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) +{ + /* Read the MAC address. and store to the private data */ + pch_gbe_mac_read_mac_addr(hw); + iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET); +#ifdef PCH_GBE_MAC_IFOP_RGMII + iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE); +#endif + pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST); + /* Setup the receive address */ + pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); + return; +} + +/** + * pch_gbe_mac_init_rx_addrs - Initialize receive address's + * @hw: Pointer to the HW structure + * @mar_count: Receive address registers + */ +void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count) +{ + u32 i; + + /* Setup the receive address */ + pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); + + /* Zero out the other receive addresses */ + for (i = 1; i < mar_count; i++) { + iowrite32(0, &hw->reg->mac_adr[i].high); + iowrite32(0, &hw->reg->mac_adr[i].low); + } + iowrite32(0xFFFE, &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); +} + + +/** + * pch_gbe_mac_mc_addr_list_update - Update Multicast addresses + * @hw: Pointer to the HW structure + * @mc_addr_list: Array of multicast addresses to program + * @mc_addr_count: Number of multicast addresses to program + * @mar_used_count: The first MAC Address register free to program + * @mar_total_num: Total number of supported MAC Address Registers + */ +void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 mar_used_count, u32 mar_total_num) +{ + u32 i, adrmask; + + /* Load the first set of multicast addresses into the exact + * filters (RAR). If there are not enough to fill the RAR + * array, clear the filters. + */ + for (i = mar_used_count; i < mar_total_num; i++) { + if (mc_addr_count) { + pch_gbe_mac_mar_set(hw, mc_addr_list, i); + mc_addr_count--; + mc_addr_list += PCH_GBE_ETH_ALEN; + } else { + /* Clear MAC address mask */ + adrmask = ioread32(&hw->reg->ADDR_MASK); + iowrite32((adrmask | (0x0001 << i)), + &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); + /* Clear MAC address */ + iowrite32(0, &hw->reg->mac_adr[i].high); + iowrite32(0, &hw->reg->mac_adr[i].low); + } + } +} + +/** + * pch_gbe_mac_force_mac_fc - Force the MAC's flow control settings + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw) +{ + struct pch_gbe_mac_info *mac = &hw->mac; + u32 rx_fctrl; + + pr_debug("mac->fc = %u\n", mac->fc); + + rx_fctrl = ioread32(&hw->reg->RX_FCTRL); + + switch (mac->fc) { + case PCH_GBE_FC_NONE: + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = false; + break; + case PCH_GBE_FC_RX_PAUSE: + rx_fctrl |= PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = false; + break; + case PCH_GBE_FC_TX_PAUSE: + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = true; + break; + case PCH_GBE_FC_FULL: + rx_fctrl |= PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = true; + break; + default: + pr_err("Flow control param set incorrectly\n"); + return -EINVAL; + } + if (mac->link_duplex == DUPLEX_HALF) + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + iowrite32(rx_fctrl, &hw->reg->RX_FCTRL); + pr_debug("RX_FCTRL reg : 0x%08x mac->tx_fc_enable : %d\n", + ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable); + return 0; +} + +/** + * pch_gbe_mac_set_wol_event - Set wake-on-lan event + * @hw: Pointer to the HW structure + * @wu_evt: Wake up event + */ +void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt) +{ + u32 addr_mask; + + pr_debug("wu_evt : 0x%08x ADDR_MASK reg : 0x%08x\n", + wu_evt, ioread32(&hw->reg->ADDR_MASK)); + + if (wu_evt) { + /* Set Wake-On-Lan address mask */ + addr_mask = ioread32(&hw->reg->ADDR_MASK); + iowrite32(addr_mask, &hw->reg->WOL_ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->WOL_ADDR_MASK, PCH_GBE_WLA_BUSY); + iowrite32(0, &hw->reg->WOL_ST); + iowrite32((wu_evt | PCH_GBE_WLC_WOL_MODE), &hw->reg->WOL_CTRL); + iowrite32(0x02, &hw->reg->TCPIP_ACC); + iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN); + } else { + iowrite32(0, &hw->reg->WOL_CTRL); + iowrite32(0, &hw->reg->WOL_ST); + } + return; +} + +/** + * pch_gbe_mac_ctrl_miim - Control MIIM interface + * @hw: Pointer to the HW structure + * @addr: Address of PHY + * @dir: Operetion. (Write or Read) + * @reg: Access register of PHY + * @data: Write data. + * + * Returns: Read date. + */ +u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg, + u16 data) +{ + u32 data_out = 0; + unsigned int i; + unsigned long flags; + + spin_lock_irqsave(&hw->miim_lock, flags); + + for (i = 100; i; --i) { + if ((ioread32(&hw->reg->MIIM) & PCH_GBE_MIIM_OPER_READY)) + break; + udelay(20); + } + if (i == 0) { + pr_err("pch-gbe.miim won't go Ready\n"); + spin_unlock_irqrestore(&hw->miim_lock, flags); + return 0; /* No way to indicate timeout error */ + } + iowrite32(((reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | + (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | + dir | data), &hw->reg->MIIM); + for (i = 0; i < 100; i++) { + udelay(20); + data_out = ioread32(&hw->reg->MIIM); + if ((data_out & PCH_GBE_MIIM_OPER_READY)) + break; + } + spin_unlock_irqrestore(&hw->miim_lock, flags); + + pr_debug("PHY %s: reg=%d, data=0x%04X\n", + dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg, + dir == PCH_GBE_MIIM_OPER_READ ? data_out : data); + return (u16) data_out; +} + +/** + * pch_gbe_mac_set_pause_packet - Set pause packet + * @hw: Pointer to the HW structure + */ +void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw) +{ + unsigned long tmp2, tmp3; + + /* Set Pause packet */ + tmp2 = hw->mac.addr[1]; + tmp2 = (tmp2 << 8) | hw->mac.addr[0]; + tmp2 = PCH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16); + + tmp3 = hw->mac.addr[5]; + tmp3 = (tmp3 << 8) | hw->mac.addr[4]; + tmp3 = (tmp3 << 8) | hw->mac.addr[3]; + tmp3 = (tmp3 << 8) | hw->mac.addr[2]; + + iowrite32(PCH_GBE_PAUSE_PKT1_VALUE, &hw->reg->PAUSE_PKT1); + iowrite32(tmp2, &hw->reg->PAUSE_PKT2); + iowrite32(tmp3, &hw->reg->PAUSE_PKT3); + iowrite32(PCH_GBE_PAUSE_PKT4_VALUE, &hw->reg->PAUSE_PKT4); + iowrite32(PCH_GBE_PAUSE_PKT5_VALUE, &hw->reg->PAUSE_PKT5); + + /* Transmit Pause Packet */ + iowrite32(PCH_GBE_PS_PKT_RQ, &hw->reg->PAUSE_REQ); + + pr_debug("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + ioread32(&hw->reg->PAUSE_PKT1), ioread32(&hw->reg->PAUSE_PKT2), + ioread32(&hw->reg->PAUSE_PKT3), ioread32(&hw->reg->PAUSE_PKT4), + ioread32(&hw->reg->PAUSE_PKT5)); + + return; +} + + +/** + * pch_gbe_alloc_queues - Allocate memory for all rings + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter) +{ + int size; + + size = (int)sizeof(struct pch_gbe_tx_ring); + adapter->tx_ring = kzalloc(size, GFP_KERNEL); + if (!adapter->tx_ring) + return -ENOMEM; + size = (int)sizeof(struct pch_gbe_rx_ring); + adapter->rx_ring = kzalloc(size, GFP_KERNEL); + if (!adapter->rx_ring) { + kfree(adapter->tx_ring); + return -ENOMEM; + } + return 0; +} + +/** + * pch_gbe_init_stats - Initialize status + * @adapter: Board private structure to initialize + */ +static void pch_gbe_init_stats(struct pch_gbe_adapter *adapter) +{ + memset(&adapter->stats, 0, sizeof(adapter->stats)); + return; +} + +/** + * pch_gbe_init_phy - Initialize PHY + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + u32 addr; + u16 bmcr, stat; + + /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */ + for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) { + adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr; + bmcr = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR); + stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); + stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); + if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) + break; + } + adapter->hw.phy.addr = adapter->mii.phy_id; + pr_debug("phy_addr = %d\n", adapter->mii.phy_id); + if (addr == 32) + return -EAGAIN; + /* Selected the phy and isolate the rest */ + for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) { + if (addr != adapter->mii.phy_id) { + pch_gbe_mdio_write(netdev, addr, MII_BMCR, + BMCR_ISOLATE); + } else { + bmcr = pch_gbe_mdio_read(netdev, addr, MII_BMCR); + pch_gbe_mdio_write(netdev, addr, MII_BMCR, + bmcr & ~BMCR_ISOLATE); + } + } + + /* MII setup */ + adapter->mii.phy_id_mask = 0x1F; + adapter->mii.reg_num_mask = 0x1F; + adapter->mii.dev = adapter->netdev; + adapter->mii.mdio_read = pch_gbe_mdio_read; + adapter->mii.mdio_write = pch_gbe_mdio_write; + adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii); + return 0; +} + +/** + * pch_gbe_mdio_read - The read function for mii + * @netdev: Network interface device structure + * @addr: Phy ID + * @reg: Access location + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + return pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg, + (u16) 0); +} + +/** + * pch_gbe_mdio_write - The write function for mii + * @netdev: Network interface device structure + * @addr: Phy ID (not used) + * @reg: Access location + * @data: Write data + */ +void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data); +} + +/** + * pch_gbe_reset_task - Reset processing at the time of transmission timeout + * @work: Pointer of board private structure + */ +static void pch_gbe_reset_task(struct work_struct *work) +{ + struct pch_gbe_adapter *adapter; + adapter = container_of(work, struct pch_gbe_adapter, reset_task); + + pch_gbe_reinit_locked(adapter); +} + +/** + * pch_gbe_reinit_locked- Re-initialization + * @adapter: Board private structure + */ +void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + rtnl_lock(); + if (netif_running(netdev)) { + pch_gbe_down(adapter); + pch_gbe_up(adapter); + } + rtnl_unlock(); +} + +/** + * pch_gbe_reset - Reset GbE + * @adapter: Board private structure + */ +void pch_gbe_reset(struct pch_gbe_adapter *adapter) +{ + pch_gbe_mac_reset_hw(&adapter->hw); + /* Setup the receive address. */ + pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES); + if (pch_gbe_hal_init_hw(&adapter->hw)) + pr_err("Hardware Error\n"); +} + +/** + * pch_gbe_free_irq - Free an interrupt + * @adapter: Board private structure + */ +static void pch_gbe_free_irq(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + free_irq(adapter->pdev->irq, netdev); + if (adapter->have_msi) { + pci_disable_msi(adapter->pdev); + pr_debug("call pci_disable_msi\n"); + } +} + +/** + * pch_gbe_irq_disable - Mask off interrupt generation on the NIC + * @adapter: Board private structure + */ +static void pch_gbe_irq_disable(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + atomic_inc(&adapter->irq_sem); + iowrite32(0, &hw->reg->INT_EN); + ioread32(&hw->reg->INT_ST); + synchronize_irq(adapter->pdev->irq); + + pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN)); +} + +/** + * pch_gbe_irq_enable - Enable default interrupt generation settings + * @adapter: Board private structure + */ +static void pch_gbe_irq_enable(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + if (likely(atomic_dec_and_test(&adapter->irq_sem))) + iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN); + ioread32(&hw->reg->INT_ST); + pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN)); +} + + + +/** + * pch_gbe_setup_tctl - configure the Transmit control registers + * @adapter: Board private structure + */ +static void pch_gbe_setup_tctl(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 tx_mode, tcpip; + + tx_mode = PCH_GBE_TM_LONG_PKT | + PCH_GBE_TM_ST_AND_FD | + PCH_GBE_TM_SHORT_PKT | + PCH_GBE_TM_TH_TX_STRT_8 | + PCH_GBE_TM_TH_ALM_EMP_4 | PCH_GBE_TM_TH_ALM_FULL_8; + + iowrite32(tx_mode, &hw->reg->TX_MODE); + + tcpip = ioread32(&hw->reg->TCPIP_ACC); + tcpip |= PCH_GBE_TX_TCPIPACC_EN; + iowrite32(tcpip, &hw->reg->TCPIP_ACC); + return; +} + +/** + * pch_gbe_configure_tx - Configure Transmit Unit after Reset + * @adapter: Board private structure + */ +static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 tdba, tdlen, dctrl; + + pr_debug("dma addr = 0x%08llx size = 0x%08x\n", + (unsigned long long)adapter->tx_ring->dma, + adapter->tx_ring->size); + + /* Setup the HW Tx Head and Tail descriptor pointers */ + tdba = adapter->tx_ring->dma; + tdlen = adapter->tx_ring->size - 0x10; + iowrite32(tdba, &hw->reg->TX_DSC_BASE); + iowrite32(tdlen, &hw->reg->TX_DSC_SIZE); + iowrite32(tdba, &hw->reg->TX_DSC_SW_P); + + /* Enables Transmission DMA */ + dctrl = ioread32(&hw->reg->DMA_CTRL); + dctrl |= PCH_GBE_TX_DMA_EN; + iowrite32(dctrl, &hw->reg->DMA_CTRL); +} + +/** + * pch_gbe_setup_rctl - Configure the receive control registers + * @adapter: Board private structure + */ +static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 rx_mode, tcpip; + + rx_mode = PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN | + PCH_GBE_RH_ALM_EMP_4 | PCH_GBE_RH_ALM_FULL_4 | PCH_GBE_RH_RD_TRG_8; + + iowrite32(rx_mode, &hw->reg->RX_MODE); + + tcpip = ioread32(&hw->reg->TCPIP_ACC); + + if (adapter->rx_csum) { + tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF; + tcpip |= PCH_GBE_RX_TCPIPACC_EN; + } else { + tcpip |= PCH_GBE_RX_TCPIPACC_OFF; + tcpip &= ~PCH_GBE_RX_TCPIPACC_EN; + } + iowrite32(tcpip, &hw->reg->TCPIP_ACC); + return; +} + +/** + * pch_gbe_configure_rx - Configure Receive Unit after Reset + * @adapter: Board private structure + */ +static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 rdba, rdlen, rctl, rxdma; + + pr_debug("dma adr = 0x%08llx size = 0x%08x\n", + (unsigned long long)adapter->rx_ring->dma, + adapter->rx_ring->size); + + pch_gbe_mac_force_mac_fc(hw); + + /* Disables Receive MAC */ + rctl = ioread32(&hw->reg->MAC_RX_EN); + iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); + + /* Disables Receive DMA */ + rxdma = ioread32(&hw->reg->DMA_CTRL); + rxdma &= ~PCH_GBE_RX_DMA_EN; + iowrite32(rxdma, &hw->reg->DMA_CTRL); + + pr_debug("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n", + ioread32(&hw->reg->MAC_RX_EN), + ioread32(&hw->reg->DMA_CTRL)); + + /* Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring */ + rdba = adapter->rx_ring->dma; + rdlen = adapter->rx_ring->size - 0x10; + iowrite32(rdba, &hw->reg->RX_DSC_BASE); + iowrite32(rdlen, &hw->reg->RX_DSC_SIZE); + iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P); + + /* Enables Receive DMA */ + rxdma = ioread32(&hw->reg->DMA_CTRL); + rxdma |= PCH_GBE_RX_DMA_EN; + iowrite32(rxdma, &hw->reg->DMA_CTRL); + /* Enables Receive */ + iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); +} + +/** + * pch_gbe_unmap_and_free_tx_resource - Unmap and free tx socket buffer + * @adapter: Board private structure + * @buffer_info: Buffer information structure + */ +static void pch_gbe_unmap_and_free_tx_resource( + struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info) +{ + if (buffer_info->mapped) { + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_TO_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + dev_kfree_skb_any(buffer_info->skb); + buffer_info->skb = NULL; + } +} + +/** + * pch_gbe_unmap_and_free_rx_resource - Unmap and free rx socket buffer + * @adapter: Board private structure + * @buffer_info: Buffer information structure + */ +static void pch_gbe_unmap_and_free_rx_resource( + struct pch_gbe_adapter *adapter, + struct pch_gbe_buffer *buffer_info) +{ + if (buffer_info->mapped) { + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_FROM_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + dev_kfree_skb_any(buffer_info->skb); + buffer_info->skb = NULL; + } +} + +/** + * pch_gbe_clean_tx_ring - Free Tx Buffers + * @adapter: Board private structure + * @tx_ring: Ring to be cleaned + */ +static void pch_gbe_clean_tx_ring(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_buffer *buffer_info; + unsigned long size; + unsigned int i; + + /* Free all the Tx ring sk_buffs */ + for (i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + pch_gbe_unmap_and_free_tx_resource(adapter, buffer_info); + } + pr_debug("call pch_gbe_unmap_and_free_tx_resource() %d count\n", i); + + size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count; + memset(tx_ring->buffer_info, 0, size); + + /* Zero out the descriptor ring */ + memset(tx_ring->desc, 0, tx_ring->size); + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; + iowrite32(tx_ring->dma, &hw->reg->TX_DSC_HW_P); + iowrite32((tx_ring->size - 0x10), &hw->reg->TX_DSC_SIZE); +} + +/** + * pch_gbe_clean_rx_ring - Free Rx Buffers + * @adapter: Board private structure + * @rx_ring: Ring to free buffers from + */ +static void +pch_gbe_clean_rx_ring(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_buffer *buffer_info; + unsigned long size; + unsigned int i; + + /* Free all the Rx ring sk_buffs */ + for (i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + pch_gbe_unmap_and_free_rx_resource(adapter, buffer_info); + } + pr_debug("call pch_gbe_unmap_and_free_rx_resource() %d count\n", i); + size = (unsigned long)sizeof(struct pch_gbe_buffer) * rx_ring->count; + memset(rx_ring->buffer_info, 0, size); + + /* Zero out the descriptor ring */ + memset(rx_ring->desc, 0, rx_ring->size); + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; + iowrite32(rx_ring->dma, &hw->reg->RX_DSC_HW_P); + iowrite32((rx_ring->size - 0x10), &hw->reg->RX_DSC_SIZE); +} + +static void pch_gbe_set_rgmii_ctrl(struct pch_gbe_adapter *adapter, u16 speed, + u16 duplex) +{ + struct pch_gbe_hw *hw = &adapter->hw; + unsigned long rgmii = 0; + + /* Set the RGMII control. */ +#ifdef PCH_GBE_MAC_IFOP_RGMII + switch (speed) { + case SPEED_10: + rgmii = (PCH_GBE_RGMII_RATE_2_5M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + case SPEED_100: + rgmii = (PCH_GBE_RGMII_RATE_25M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + case SPEED_1000: + rgmii = (PCH_GBE_RGMII_RATE_125M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + } + iowrite32(rgmii, &hw->reg->RGMII_CTRL); +#else /* GMII */ + rgmii = 0; + iowrite32(rgmii, &hw->reg->RGMII_CTRL); +#endif +} +static void pch_gbe_set_mode(struct pch_gbe_adapter *adapter, u16 speed, + u16 duplex) +{ + struct net_device *netdev = adapter->netdev; + struct pch_gbe_hw *hw = &adapter->hw; + unsigned long mode = 0; + + /* Set the communication mode */ + switch (speed) { + case SPEED_10: + mode = PCH_GBE_MODE_MII_ETHER; + netdev->tx_queue_len = 10; + break; + case SPEED_100: + mode = PCH_GBE_MODE_MII_ETHER; + netdev->tx_queue_len = 100; + break; + case SPEED_1000: + mode = PCH_GBE_MODE_GMII_ETHER; + break; + } + if (duplex == DUPLEX_FULL) + mode |= PCH_GBE_MODE_FULL_DUPLEX; + else + mode |= PCH_GBE_MODE_HALF_DUPLEX; + iowrite32(mode, &hw->reg->MODE); +} + +/** + * pch_gbe_watchdog - Watchdog process + * @data: Board private structure + */ +static void pch_gbe_watchdog(unsigned long data) +{ + struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; + struct net_device *netdev = adapter->netdev; + struct pch_gbe_hw *hw = &adapter->hw; + struct ethtool_cmd cmd; + + pr_debug("right now = %ld\n", jiffies); + + pch_gbe_update_stats(adapter); + if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { + netdev->tx_queue_len = adapter->tx_queue_len; + /* mii library handles link maintenance tasks */ + if (mii_ethtool_gset(&adapter->mii, &cmd)) { + pr_err("ethtool get setting Error\n"); + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + + PCH_GBE_WATCHDOG_PERIOD)); + return; + } + hw->mac.link_speed = cmd.speed; + hw->mac.link_duplex = cmd.duplex; + /* Set the RGMII control. */ + pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + /* Set the communication mode */ + pch_gbe_set_mode(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + netdev_dbg(netdev, + "Link is Up %d Mbps %s-Duplex\n", + cmd.speed, + cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } else if ((!mii_link_ok(&adapter->mii)) && + (netif_carrier_ok(netdev))) { + netdev_dbg(netdev, "NIC Link is Down\n"); + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + PCH_GBE_WATCHDOG_PERIOD)); +} + +/** + * pch_gbe_tx_queue - Carry out queuing of the transmission data + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring structure + * @skb: Sockt buffer structure + */ +static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring, + struct sk_buff *skb) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_tx_desc *tx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *tmp_skb; + unsigned int frame_ctrl; + unsigned int ring_num; + unsigned long flags; + + /*-- Set frame control --*/ + frame_ctrl = 0; + if (unlikely(skb->len < PCH_GBE_SHORT_PKT)) + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; + if (unlikely(!adapter->tx_csum)) + frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; + + /* Performs checksum processing */ + /* + * It is because the hardware accelerator does not support a checksum, + * when the received data size is less than 64 bytes. + */ + if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) { + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD | + PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; + if (skb->protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); + unsigned int offset; + iph->check = 0; + iph->check = ip_fast_csum((u8 *) iph, iph->ihl); + offset = skb_transport_offset(skb); + if (iph->protocol == IPPROTO_TCP) { + skb->csum = 0; + tcp_hdr(skb)->check = 0; + skb->csum = skb_checksum(skb, offset, + skb->len - offset, 0); + tcp_hdr(skb)->check = + csum_tcpudp_magic(iph->saddr, + iph->daddr, + skb->len - offset, + IPPROTO_TCP, + skb->csum); + } else if (iph->protocol == IPPROTO_UDP) { + skb->csum = 0; + udp_hdr(skb)->check = 0; + skb->csum = + skb_checksum(skb, offset, + skb->len - offset, 0); + udp_hdr(skb)->check = + csum_tcpudp_magic(iph->saddr, + iph->daddr, + skb->len - offset, + IPPROTO_UDP, + skb->csum); + } + } + } + spin_lock_irqsave(&tx_ring->tx_lock, flags); + ring_num = tx_ring->next_to_use; + if (unlikely((ring_num + 1) == tx_ring->count)) + tx_ring->next_to_use = 0; + else + tx_ring->next_to_use = ring_num + 1; + + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + buffer_info = &tx_ring->buffer_info[ring_num]; + tmp_skb = buffer_info->skb; + + /* [Header:14][payload] ---> [Header:14][paddong:2][payload] */ + memcpy(tmp_skb->data, skb->data, ETH_HLEN); + tmp_skb->data[ETH_HLEN] = 0x00; + tmp_skb->data[ETH_HLEN + 1] = 0x00; + tmp_skb->len = skb->len; + memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN], + (skb->len - ETH_HLEN)); + /*-- Set Buffer infomation --*/ + buffer_info->length = tmp_skb->len; + buffer_info->dma = dma_map_single(&adapter->pdev->dev, tmp_skb->data, + buffer_info->length, + DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { + pr_err("TX DMA map failed\n"); + buffer_info->dma = 0; + buffer_info->time_stamp = 0; + tx_ring->next_to_use = ring_num; + return; + } + buffer_info->mapped = true; + buffer_info->time_stamp = jiffies; + + /*-- Set Tx descriptor --*/ + tx_desc = PCH_GBE_TX_DESC(*tx_ring, ring_num); + tx_desc->buffer_addr = (buffer_info->dma); + tx_desc->length = (tmp_skb->len); + tx_desc->tx_words_eob = ((tmp_skb->len + 3)); + tx_desc->tx_frame_ctrl = (frame_ctrl); + tx_desc->gbec_status = (DSC_INIT16); + + if (unlikely(++ring_num == tx_ring->count)) + ring_num = 0; + + /* Update software pointer of TX descriptor */ + iowrite32(tx_ring->dma + + (int)sizeof(struct pch_gbe_tx_desc) * ring_num, + &hw->reg->TX_DSC_SW_P); + dev_kfree_skb_any(skb); +} + +/** + * pch_gbe_update_stats - Update the board statistics counters + * @adapter: Board private structure + */ +void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_hw_stats *stats = &adapter->stats; + unsigned long flags; + + /* + * Prevent stats update while adapter is being reset, or if the pci + * connection is down. + */ + if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal)) + return; + + spin_lock_irqsave(&adapter->stats_lock, flags); + + /* Update device status "adapter->stats" */ + stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors; + stats->tx_errors = stats->tx_length_errors + + stats->tx_aborted_errors + + stats->tx_carrier_errors + stats->tx_timeout_count; + + /* Update network device status "adapter->net_stats" */ + netdev->stats.rx_packets = stats->rx_packets; + netdev->stats.rx_bytes = stats->rx_bytes; + netdev->stats.rx_dropped = stats->rx_dropped; + netdev->stats.tx_packets = stats->tx_packets; + netdev->stats.tx_bytes = stats->tx_bytes; + netdev->stats.tx_dropped = stats->tx_dropped; + /* Fill out the OS statistics structure */ + netdev->stats.multicast = stats->multicast; + netdev->stats.collisions = stats->collisions; + /* Rx Errors */ + netdev->stats.rx_errors = stats->rx_errors; + netdev->stats.rx_crc_errors = stats->rx_crc_errors; + netdev->stats.rx_frame_errors = stats->rx_frame_errors; + /* Tx Errors */ + netdev->stats.tx_errors = stats->tx_errors; + netdev->stats.tx_aborted_errors = stats->tx_aborted_errors; + netdev->stats.tx_carrier_errors = stats->tx_carrier_errors; + + spin_unlock_irqrestore(&adapter->stats_lock, flags); +} + +/** + * pch_gbe_intr - Interrupt Handler + * @irq: Interrupt number + * @data: Pointer to a network interface device structure + * Returns + * - IRQ_HANDLED: Our interrupt + * - IRQ_NONE: Not our interrupt + */ +static irqreturn_t pch_gbe_intr(int irq, void *data) +{ + struct net_device *netdev = data; + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 int_st; + u32 int_en; + + /* Check request status */ + int_st = ioread32(&hw->reg->INT_ST); + int_st = int_st & ioread32(&hw->reg->INT_EN); + /* When request status is no interruption factor */ + if (unlikely(!int_st)) + return IRQ_NONE; /* Not our interrupt. End processing. */ + pr_debug("%s occur int_st = 0x%08x\n", __func__, int_st); + if (int_st & PCH_GBE_INT_RX_FRAME_ERR) + adapter->stats.intr_rx_frame_err_count++; + if (int_st & PCH_GBE_INT_RX_FIFO_ERR) + adapter->stats.intr_rx_fifo_err_count++; + if (int_st & PCH_GBE_INT_RX_DMA_ERR) + adapter->stats.intr_rx_dma_err_count++; + if (int_st & PCH_GBE_INT_TX_FIFO_ERR) + adapter->stats.intr_tx_fifo_err_count++; + if (int_st & PCH_GBE_INT_TX_DMA_ERR) + adapter->stats.intr_tx_dma_err_count++; + if (int_st & PCH_GBE_INT_TCPIP_ERR) + adapter->stats.intr_tcpip_err_count++; + /* When Rx descriptor is empty */ + if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) { + adapter->stats.intr_rx_dsc_empty_count++; + pr_err("Rx descriptor is empty\n"); + int_en = ioread32(&hw->reg->INT_EN); + iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN); + if (hw->mac.tx_fc_enable) { + /* Set Pause packet */ + pch_gbe_mac_set_pause_packet(hw); + } + if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT)) + == 0) { + return IRQ_HANDLED; + } + } + + /* When request status is Receive interruption */ + if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) { + if (likely(napi_schedule_prep(&adapter->napi))) { + /* Enable only Rx Descriptor empty */ + atomic_inc(&adapter->irq_sem); + int_en = ioread32(&hw->reg->INT_EN); + int_en &= + ~(PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT); + iowrite32(int_en, &hw->reg->INT_EN); + /* Start polling for NAPI */ + __napi_schedule(&adapter->napi); + } + } + pr_debug("return = 0x%08x INT_EN reg = 0x%08x\n", + IRQ_HANDLED, ioread32(&hw->reg->INT_EN)); + return IRQ_HANDLED; +} + +/** + * pch_gbe_alloc_rx_buffers - Replace used receive buffers; legacy & extended + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring + * @cleaned_count: Cleaned count + */ +static void +pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring, int cleaned_count) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_rx_desc *rx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int bufsz; + + bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN; + i = rx_ring->next_to_use; + + while ((cleaned_count--)) { + buffer_info = &rx_ring->buffer_info[i]; + skb = buffer_info->skb; + if (skb) { + skb_trim(skb, 0); + } else { + skb = netdev_alloc_skb(netdev, bufsz); + if (unlikely(!skb)) { + /* Better luck next round */ + adapter->stats.rx_alloc_buff_failed++; + break; + } + /* 64byte align */ + skb_reserve(skb, PCH_GBE_DMA_ALIGN); + + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; + } + buffer_info->dma = dma_map_single(&pdev->dev, + skb->data, + buffer_info->length, + DMA_FROM_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { + dev_kfree_skb(skb); + buffer_info->skb = NULL; + buffer_info->dma = 0; + adapter->stats.rx_alloc_buff_failed++; + break; /* while !buffer_info->skb */ + } + buffer_info->mapped = true; + rx_desc = PCH_GBE_RX_DESC(*rx_ring, i); + rx_desc->buffer_addr = (buffer_info->dma); + rx_desc->gbec_status = DSC_INIT16; + + pr_debug("i = %d buffer_info->dma = 0x08%llx buffer_info->length = 0x%x\n", + i, (unsigned long long)buffer_info->dma, + buffer_info->length); + + if (unlikely(++i == rx_ring->count)) + i = 0; + } + if (likely(rx_ring->next_to_use != i)) { + rx_ring->next_to_use = i; + if (unlikely(i-- == 0)) + i = (rx_ring->count - 1); + iowrite32(rx_ring->dma + + (int)sizeof(struct pch_gbe_rx_desc) * i, + &hw->reg->RX_DSC_SW_P); + } + return; +} + +/** + * pch_gbe_alloc_tx_buffers - Allocate transmit buffers + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring + */ +static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int bufsz; + struct pch_gbe_tx_desc *tx_desc; + + bufsz = + adapter->hw.mac.max_frame_size + PCH_GBE_DMA_ALIGN + NET_IP_ALIGN; + + for (i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + skb = netdev_alloc_skb(adapter->netdev, bufsz); + skb_reserve(skb, PCH_GBE_DMA_ALIGN); + buffer_info->skb = skb; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + tx_desc->gbec_status = (DSC_INIT16); + } + return; +} + +/** + * pch_gbe_clean_tx - Reclaim resources after transmit completes + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring + * Returns + * true: Cleaned the descriptor + * false: Not cleaned the descriptor + */ +static bool +pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_tx_desc *tx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int cleaned_count = 0; + bool cleaned = false; + + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + + i = tx_ring->next_to_clean; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + pr_debug("gbec_status:0x%04x dma_status:0x%04x\n", + tx_desc->gbec_status, tx_desc->dma_status); + + while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { + pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status); + cleaned = true; + buffer_info = &tx_ring->buffer_info[i]; + skb = buffer_info->skb; + + if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) { + adapter->stats.tx_aborted_errors++; + pr_err("Transfer Abort Error\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CRSER) + ) { + adapter->stats.tx_carrier_errors++; + pr_err("Transfer Carrier Sense Error\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_EXCOL) + ) { + adapter->stats.tx_aborted_errors++; + pr_err("Transfer Collision Abort Error\n"); + } else if ((tx_desc->gbec_status & + (PCH_GBE_TXD_GMAC_STAT_SNGCOL | + PCH_GBE_TXD_GMAC_STAT_MLTCOL))) { + adapter->stats.collisions++; + adapter->stats.tx_packets++; + adapter->stats.tx_bytes += skb->len; + pr_debug("Transfer Collision\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CMPLT) + ) { + adapter->stats.tx_packets++; + adapter->stats.tx_bytes += skb->len; + } + if (buffer_info->mapped) { + pr_debug("unmap buffer_info->dma : %d\n", i); + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_TO_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + pr_debug("trim buffer_info->skb : %d\n", i); + skb_trim(buffer_info->skb, 0); + } + tx_desc->gbec_status = DSC_INIT16; + if (unlikely(++i == tx_ring->count)) + i = 0; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + + /* weight of a sort for tx, to avoid endless transmit cleanup */ + if (cleaned_count++ == PCH_GBE_TX_WEIGHT) + break; + } + pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", + cleaned_count); + /* Recover from running out of Tx resources in xmit_frame */ + if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { + netif_wake_queue(adapter->netdev); + adapter->stats.tx_restart_count++; + pr_debug("Tx wake queue\n"); + } + spin_lock(&adapter->tx_queue_lock); + tx_ring->next_to_clean = i; + spin_unlock(&adapter->tx_queue_lock); + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + return cleaned; +} + +/** + * pch_gbe_clean_rx - Send received data up the network stack; legacy + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring + * @work_done: Completed count + * @work_to_do: Request count + * Returns + * true: Cleaned the descriptor + * false: Not cleaned the descriptor + */ +static bool +pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring, + int *work_done, int work_to_do) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_buffer *buffer_info; + struct pch_gbe_rx_desc *rx_desc; + u32 length; + unsigned char tmp_packet[ETH_HLEN]; + unsigned int i; + unsigned int cleaned_count = 0; + bool cleaned = false; + struct sk_buff *skb; + u8 dma_status; + u16 gbec_status; + u32 tcp_ip_status; + u8 skb_copy_flag = 0; + u8 skb_padding_flag = 0; + + i = rx_ring->next_to_clean; + + while (*work_done < work_to_do) { + /* Check Rx descriptor status */ + rx_desc = PCH_GBE_RX_DESC(*rx_ring, i); + if (rx_desc->gbec_status == DSC_INIT16) + break; + cleaned = true; + cleaned_count++; + + dma_status = rx_desc->dma_status; + gbec_status = rx_desc->gbec_status; + tcp_ip_status = rx_desc->tcp_ip_status; + rx_desc->gbec_status = DSC_INIT16; + buffer_info = &rx_ring->buffer_info[i]; + skb = buffer_info->skb; + + /* unmap dma */ + dma_unmap_single(&pdev->dev, buffer_info->dma, + buffer_info->length, DMA_FROM_DEVICE); + buffer_info->mapped = false; + /* Prefetch the packet */ + prefetch(skb->data); + + pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x " + "TCP:0x%08x] BufInf = 0x%p\n", + i, dma_status, gbec_status, tcp_ip_status, + buffer_info); + /* Error check */ + if (unlikely(gbec_status & PCH_GBE_RXD_GMAC_STAT_NOTOCTAL)) { + adapter->stats.rx_frame_errors++; + pr_err("Receive Not Octal Error\n"); + } else if (unlikely(gbec_status & + PCH_GBE_RXD_GMAC_STAT_NBLERR)) { + adapter->stats.rx_frame_errors++; + pr_err("Receive Nibble Error\n"); + } else if (unlikely(gbec_status & + PCH_GBE_RXD_GMAC_STAT_CRCERR)) { + adapter->stats.rx_crc_errors++; + pr_err("Receive CRC Error\n"); + } else { + /* get receive length */ + /* length convert[-3], padding[-2] */ + length = (rx_desc->rx_words_eob) - 3 - 2; + + /* Decide the data conversion method */ + if (!adapter->rx_csum) { + /* [Header:14][payload] */ + skb_padding_flag = 0; + skb_copy_flag = 1; + } else { + /* [Header:14][padding:2][payload] */ + skb_padding_flag = 1; + if (length < copybreak) + skb_copy_flag = 1; + else + skb_copy_flag = 0; + } + + /* Data conversion */ + if (skb_copy_flag) { /* recycle skb */ + struct sk_buff *new_skb; + new_skb = + netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (new_skb) { + if (!skb_padding_flag) { + skb_reserve(new_skb, + NET_IP_ALIGN); + } + memcpy(new_skb->data, skb->data, + length); + /* save the skb + * in buffer_info as good */ + skb = new_skb; + } else if (!skb_padding_flag) { + /* dorrop error */ + pr_err("New skb allocation Error\n"); + goto dorrop; + } + } else { + buffer_info->skb = NULL; + } + if (skb_padding_flag) { + memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); + memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], + ETH_HLEN); + skb_reserve(skb, NET_IP_ALIGN); + + } + + /* update status of driver */ + adapter->stats.rx_bytes += length; + adapter->stats.rx_packets++; + if ((gbec_status & PCH_GBE_RXD_GMAC_STAT_MARMLT)) + adapter->stats.multicast++; + /* Write meta date of skb */ + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, netdev); + if ((tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) == + PCH_GBE_RXD_ACC_STAT_TCPIPOK) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->ip_summed = CHECKSUM_NONE; + } + napi_gro_receive(&adapter->napi, skb); + (*work_done)++; + pr_debug("Receive skb->ip_summed: %d length: %d\n", + skb->ip_summed, length); + } +dorrop: + /* return some buffers to hardware, one at a time is too slow */ + if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) { + pch_gbe_alloc_rx_buffers(adapter, rx_ring, + cleaned_count); + cleaned_count = 0; + } + if (++i == rx_ring->count) + i = 0; + } + rx_ring->next_to_clean = i; + if (cleaned_count) + pch_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); + return cleaned; +} + +/** + * pch_gbe_setup_tx_resources - Allocate Tx resources (Descriptors) + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring (for a specific queue) to setup + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_tx_desc *tx_desc; + int size; + int desNo; + + size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; + tx_ring->buffer_info = vmalloc(size); + if (!tx_ring->buffer_info) { + pr_err("Unable to allocate memory for the buffer infomation\n"); + return -ENOMEM; + } + memset(tx_ring->buffer_info, 0, size); + + tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); + + tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, + &tx_ring->dma, GFP_KERNEL); + if (!tx_ring->desc) { + vfree(tx_ring->buffer_info); + pr_err("Unable to allocate memory for the transmit descriptor ring\n"); + return -ENOMEM; + } + memset(tx_ring->desc, 0, tx_ring->size); + + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; + spin_lock_init(&tx_ring->tx_lock); + + for (desNo = 0; desNo < tx_ring->count; desNo++) { + tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo); + tx_desc->gbec_status = DSC_INIT16; + } + pr_debug("tx_ring->desc = 0x%p tx_ring->dma = 0x%08llx\n" + "next_to_clean = 0x%08x next_to_use = 0x%08x\n", + tx_ring->desc, (unsigned long long)tx_ring->dma, + tx_ring->next_to_clean, tx_ring->next_to_use); + return 0; +} + +/** + * pch_gbe_setup_rx_resources - Allocate Rx resources (Descriptors) + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring (for a specific queue) to setup + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_rx_desc *rx_desc; + int size; + int desNo; + + size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; + rx_ring->buffer_info = vmalloc(size); + if (!rx_ring->buffer_info) { + pr_err("Unable to allocate memory for the receive descriptor ring\n"); + return -ENOMEM; + } + memset(rx_ring->buffer_info, 0, size); + rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); + rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, + &rx_ring->dma, GFP_KERNEL); + + if (!rx_ring->desc) { + pr_err("Unable to allocate memory for the receive descriptor ring\n"); + vfree(rx_ring->buffer_info); + return -ENOMEM; + } + memset(rx_ring->desc, 0, rx_ring->size); + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; + for (desNo = 0; desNo < rx_ring->count; desNo++) { + rx_desc = PCH_GBE_RX_DESC(*rx_ring, desNo); + rx_desc->gbec_status = DSC_INIT16; + } + pr_debug("rx_ring->desc = 0x%p rx_ring->dma = 0x%08llx " + "next_to_clean = 0x%08x next_to_use = 0x%08x\n", + rx_ring->desc, (unsigned long long)rx_ring->dma, + rx_ring->next_to_clean, rx_ring->next_to_use); + return 0; +} + +/** + * pch_gbe_free_tx_resources - Free Tx Resources + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring for a specific queue + */ +void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + + pch_gbe_clean_tx_ring(adapter, tx_ring); + vfree(tx_ring->buffer_info); + tx_ring->buffer_info = NULL; + pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma); + tx_ring->desc = NULL; +} + +/** + * pch_gbe_free_rx_resources - Free Rx Resources + * @adapter: Board private structure + * @rx_ring: Ring to clean the resources from + */ +void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + + pch_gbe_clean_rx_ring(adapter, rx_ring); + vfree(rx_ring->buffer_info); + rx_ring->buffer_info = NULL; + pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); + rx_ring->desc = NULL; +} + +/** + * pch_gbe_request_irq - Allocate an interrupt line + * @adapter: Board private structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int err; + int flags; + + flags = IRQF_SHARED; + adapter->have_msi = false; + err = pci_enable_msi(adapter->pdev); + pr_debug("call pci_enable_msi\n"); + if (err) { + pr_debug("call pci_enable_msi - Error: %d\n", err); + } else { + flags = 0; + adapter->have_msi = true; + } + err = request_irq(adapter->pdev->irq, &pch_gbe_intr, + flags, netdev->name, netdev); + if (err) + pr_err("Unable to allocate interrupt Error: %d\n", err); + pr_debug("adapter->have_msi : %d flags : 0x%04x return : 0x%04x\n", + adapter->have_msi, flags, err); + return err; +} + + +static void pch_gbe_set_multi(struct net_device *netdev); +/** + * pch_gbe_up - Up GbE network device + * @adapter: Board private structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_up(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; + int err; + + /* hardware has been reset, we need to reload some things */ + pch_gbe_set_multi(netdev); + + pch_gbe_setup_tctl(adapter); + pch_gbe_configure_tx(adapter); + pch_gbe_setup_rctl(adapter); + pch_gbe_configure_rx(adapter); + + err = pch_gbe_request_irq(adapter); + if (err) { + pr_err("Error: can't bring device up\n"); + return err; + } + pch_gbe_alloc_tx_buffers(adapter, tx_ring); + pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); + adapter->tx_queue_len = netdev->tx_queue_len; + + mod_timer(&adapter->watchdog_timer, jiffies); + + napi_enable(&adapter->napi); + pch_gbe_irq_enable(adapter); + netif_start_queue(adapter->netdev); + + return 0; +} + +/** + * pch_gbe_down - Down GbE network device + * @adapter: Board private structure + */ +void pch_gbe_down(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); + + pch_gbe_irq_disable(adapter); + pch_gbe_free_irq(adapter); + + del_timer_sync(&adapter->watchdog_timer); + + netdev->tx_queue_len = adapter->tx_queue_len; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + pch_gbe_reset(adapter); + pch_gbe_clean_tx_ring(adapter, adapter->tx_ring); + pch_gbe_clean_rx_ring(adapter, adapter->rx_ring); +} + +/** + * pch_gbe_sw_init - Initialize general software structures (struct pch_gbe_adapter) + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048; + hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + + /* Initialize the hardware-specific values */ + if (pch_gbe_hal_setup_init_funcs(hw)) { + pr_err("Hardware Initialization Failure\n"); + return -EIO; + } + if (pch_gbe_alloc_queues(adapter)) { + pr_err("Unable to allocate memory for queues\n"); + return -ENOMEM; + } + spin_lock_init(&adapter->hw.miim_lock); + spin_lock_init(&adapter->tx_queue_lock); + spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->ethtool_lock); + atomic_set(&adapter->irq_sem, 0); + pch_gbe_irq_disable(adapter); + + pch_gbe_init_stats(adapter); + + pr_debug("rx_buffer_len : %d mac.min_frame_size : %d mac.max_frame_size : %d\n", + (u32) adapter->rx_buffer_len, + hw->mac.min_frame_size, hw->mac.max_frame_size); + return 0; +} + +/** + * pch_gbe_open - Called when a network interface is made active + * @netdev: Network interface device structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_open(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int err; + + /* allocate transmit descriptors */ + err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring); + if (err) + goto err_setup_tx; + /* allocate receive descriptors */ + err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring); + if (err) + goto err_setup_rx; + pch_gbe_hal_power_up_phy(hw); + err = pch_gbe_up(adapter); + if (err) + goto err_up; + pr_debug("Success End\n"); + return 0; + +err_up: + if (!adapter->wake_up_evt) + pch_gbe_hal_power_down_phy(hw); + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); +err_setup_rx: + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); +err_setup_tx: + pch_gbe_reset(adapter); + pr_err("Error End\n"); + return err; +} + +/** + * pch_gbe_stop - Disables a network interface + * @netdev: Network interface device structure + * Returns + * 0: Successfully + */ +static int pch_gbe_stop(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pch_gbe_down(adapter); + if (!adapter->wake_up_evt) + pch_gbe_hal_power_down_phy(hw); + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); + return 0; +} + +/** + * pch_gbe_xmit_frame - Packet transmitting start + * @skb: Socket buffer structure + * @netdev: Network interface device structure + * Returns + * - NETDEV_TX_OK: Normal end + * - NETDEV_TX_BUSY: Error end + */ +static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + unsigned long flags; + + if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) { + dev_kfree_skb_any(skb); + pr_err("Transfer length Error: skb len: %d > max: %d\n", + skb->len, adapter->hw.mac.max_frame_size); + adapter->stats.tx_length_errors++; + return NETDEV_TX_OK; + } + if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { + /* Collision - tell upper layer to requeue */ + return NETDEV_TX_LOCKED; + } + if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) { + netif_stop_queue(netdev); + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + pr_debug("Return : BUSY next_to use : 0x%08x next_to clean : 0x%08x\n", + tx_ring->next_to_use, tx_ring->next_to_clean); + return NETDEV_TX_BUSY; + } + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + + /* CRC,ITAG no support */ + pch_gbe_tx_queue(adapter, tx_ring, skb); + return NETDEV_TX_OK; +} + +/** + * pch_gbe_get_stats - Get System Network Statistics + * @netdev: Network interface device structure + * Returns: The current stats + */ +static struct net_device_stats *pch_gbe_get_stats(struct net_device *netdev) +{ + /* only return the current stats */ + return &netdev->stats; +} + +/** + * pch_gbe_set_multi - Multicast and Promiscuous mode set + * @netdev: Network interface device structure + */ +static void pch_gbe_set_multi(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + struct netdev_hw_addr *ha; + u8 *mta_list; + u32 rctl; + int i; + int mc_count; + + pr_debug("netdev->flags : 0x%08x\n", netdev->flags); + + /* Check for Promiscuous and All Multicast modes */ + rctl = ioread32(&hw->reg->RX_MODE); + mc_count = netdev_mc_count(netdev); + if ((netdev->flags & IFF_PROMISC)) { + rctl &= ~PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else if ((netdev->flags & IFF_ALLMULTI)) { + /* all the multicasting receive permissions */ + rctl |= PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else { + if (mc_count >= PCH_GBE_MAR_ENTRIES) { + /* all the multicasting receive permissions */ + rctl |= PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else { + rctl |= (PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN); + } + } + iowrite32(rctl, &hw->reg->RX_MODE); + + if (mc_count >= PCH_GBE_MAR_ENTRIES) + return; + mta_list = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); + if (!mta_list) + return; + + /* The shared function expects a packed array of only addresses. */ + i = 0; + netdev_for_each_mc_addr(ha, netdev) { + if (i == mc_count) + break; + memcpy(mta_list + (i++ * ETH_ALEN), &ha->addr, ETH_ALEN); + } + pch_gbe_mac_mc_addr_list_update(hw, mta_list, i, 1, + PCH_GBE_MAR_ENTRIES); + kfree(mta_list); + + pr_debug("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x netdev->mc_count : 0x%08x\n", + ioread32(&hw->reg->RX_MODE), mc_count); +} + +/** + * pch_gbe_set_mac - Change the Ethernet Address of the NIC + * @netdev: Network interface device structure + * @addr: Pointer to an address structure + * Returns + * 0: Successfully + * -EADDRNOTAVAIL: Failed + */ +static int pch_gbe_set_mac(struct net_device *netdev, void *addr) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct sockaddr *skaddr = addr; + int ret_val; + + if (!is_valid_ether_addr(skaddr->sa_data)) { + ret_val = -EADDRNOTAVAIL; + } else { + memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len); + memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len); + pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0); + ret_val = 0; + } + pr_debug("ret_val : 0x%08x\n", ret_val); + pr_debug("dev_addr : %pM\n", netdev->dev_addr); + pr_debug("mac_addr : %pM\n", adapter->hw.mac.addr); + pr_debug("MAC_ADR1AB reg : 0x%08x 0x%08x\n", + ioread32(&adapter->hw.reg->mac_adr[0].high), + ioread32(&adapter->hw.reg->mac_adr[0].low)); + return ret_val; +} + +/** + * pch_gbe_change_mtu - Change the Maximum Transfer Unit + * @netdev: Network interface device structure + * @new_mtu: New value for maximum frame size + * Returns + * 0: Successfully + * -EINVAL: Failed + */ +static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int max_frame; + + max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || + (max_frame > PCH_GBE_MAX_JUMBO_FRAME_SIZE)) { + pr_err("Invalid MTU setting\n"); + return -EINVAL; + } + if (max_frame <= PCH_GBE_FRAME_SIZE_2048) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048; + else if (max_frame <= PCH_GBE_FRAME_SIZE_4096) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_4096; + else if (max_frame <= PCH_GBE_FRAME_SIZE_8192) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192; + else + adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE; + netdev->mtu = new_mtu; + adapter->hw.mac.max_frame_size = max_frame; + + if (netif_running(netdev)) + pch_gbe_reinit_locked(adapter); + else + pch_gbe_reset(adapter); + + pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n", + max_frame, (u32) adapter->rx_buffer_len, netdev->mtu, + adapter->hw.mac.max_frame_size); + return 0; +} + +/** + * pch_gbe_ioctl - Controls register through a MII interface + * @netdev: Network interface device structure + * @ifr: Pointer to ifr structure + * @cmd: Control command + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + pr_debug("cmd : 0x%04x\n", cmd); + + return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); +} + +/** + * pch_gbe_tx_timeout - Respond to a Tx Hang + * @netdev: Network interface device structure + */ +static void pch_gbe_tx_timeout(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + /* Do the reset outside of interrupt context */ + adapter->stats.tx_timeout_count++; + schedule_work(&adapter->reset_task); +} + +/** + * pch_gbe_napi_poll - NAPI receive and transfer polling callback + * @napi: Pointer of polling device struct + * @budget: The maximum number of a packet + * Returns + * false: Exit the polling mode + * true: Continue the polling mode + */ +static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) +{ + struct pch_gbe_adapter *adapter = + container_of(napi, struct pch_gbe_adapter, napi); + struct net_device *netdev = adapter->netdev; + int work_done = 0; + bool poll_end_flag = false; + bool cleaned = false; + + pr_debug("budget : %d\n", budget); + + /* Keep link state information with original netdev */ + if (!netif_carrier_ok(netdev)) { + poll_end_flag = true; + } else { + cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); + pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); + + if (cleaned) + work_done = budget; + /* If no Tx and not enough Rx work done, + * exit the polling mode + */ + if ((work_done < budget) || !netif_running(netdev)) + poll_end_flag = true; + } + + if (poll_end_flag) { + napi_complete(napi); + pch_gbe_irq_enable(adapter); + } + + pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", + poll_end_flag, work_done, budget); + + return work_done; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * pch_gbe_netpoll - Used by things like netconsole to send skbs + * @netdev: Network interface device structure + */ +static void pch_gbe_netpoll(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + disable_irq(adapter->pdev->irq); + pch_gbe_intr(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); +} +#endif + +static const struct net_device_ops pch_gbe_netdev_ops = { + .ndo_open = pch_gbe_open, + .ndo_stop = pch_gbe_stop, + .ndo_start_xmit = pch_gbe_xmit_frame, + .ndo_get_stats = pch_gbe_get_stats, + .ndo_set_mac_address = pch_gbe_set_mac, + .ndo_tx_timeout = pch_gbe_tx_timeout, + .ndo_change_mtu = pch_gbe_change_mtu, + .ndo_do_ioctl = pch_gbe_ioctl, + .ndo_set_multicast_list = &pch_gbe_set_multi, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = pch_gbe_netpoll, +#endif +}; + +static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + netif_device_detach(netdev); + if (netif_running(netdev)) + pch_gbe_down(adapter); + pci_disable_device(pdev); + /* Request a slot slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t pch_gbe_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + if (pci_enable_device(pdev)) { + pr_err("Cannot re-enable PCI device after reset\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + pci_enable_wake(pdev, PCI_D0, 0); + pch_gbe_hal_power_up_phy(hw); + pch_gbe_reset(adapter); + /* Clear wake up status */ + pch_gbe_mac_set_wol_event(hw, 0); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void pch_gbe_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) { + if (pch_gbe_up(adapter)) { + pr_debug("can't bring device back up after reset\n"); + return; + } + } + netif_device_attach(netdev); +} + +static int __pch_gbe_suspend(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 wufc = adapter->wake_up_evt; + int retval = 0; + + netif_device_detach(netdev); + if (netif_running(netdev)) + pch_gbe_down(adapter); + if (wufc) { + pch_gbe_set_multi(netdev); + pch_gbe_setup_rctl(adapter); + pch_gbe_configure_rx(adapter); + pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + pch_gbe_set_mode(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + pch_gbe_mac_set_wol_event(hw, wufc); + pci_disable_device(pdev); + } else { + pch_gbe_hal_power_down_phy(hw); + pch_gbe_mac_set_wol_event(hw, wufc); + pci_disable_device(pdev); + } + return retval; +} + +#ifdef CONFIG_PM +static int pch_gbe_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + + return __pch_gbe_suspend(pdev); +} + +static int pch_gbe_resume(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 err; + + err = pci_enable_device(pdev); + if (err) { + pr_err("Cannot enable PCI device from suspend\n"); + return err; + } + pci_set_master(pdev); + pch_gbe_hal_power_up_phy(hw); + pch_gbe_reset(adapter); + /* Clear wake on lan control and status */ + pch_gbe_mac_set_wol_event(hw, 0); + + if (netif_running(netdev)) + pch_gbe_up(adapter); + netif_device_attach(netdev); + + return 0; +} +#endif /* CONFIG_PM */ + +static void pch_gbe_shutdown(struct pci_dev *pdev) +{ + __pch_gbe_suspend(pdev); + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, true); + pci_set_power_state(pdev, PCI_D3hot); + } +} + +static void pch_gbe_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + flush_scheduled_work(); + unregister_netdev(netdev); + + pch_gbe_hal_phy_hw_reset(&adapter->hw); + + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); + + iounmap(adapter->hw.reg); + pci_release_regions(pdev); + free_netdev(netdev); + pci_disable_device(pdev); +} + +static int pch_gbe_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) +{ + struct net_device *netdev; + struct pch_gbe_adapter *adapter; + int ret; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) + || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + ret = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "ERR: No usable DMA " + "configuration, aborting\n"); + goto err_disable_device; + } + } + } + + ret = pci_request_regions(pdev, KBUILD_MODNAME); + if (ret) { + dev_err(&pdev->dev, + "ERR: Can't reserve PCI I/O and memory resources\n"); + goto err_disable_device; + } + pci_set_master(pdev); + + netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter)); + if (!netdev) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "ERR: Can't allocate and set up an Ethernet device\n"); + goto err_release_pci; + } + SET_NETDEV_DEV(netdev, &pdev->dev); + + pci_set_drvdata(pdev, netdev); + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + adapter->pdev = pdev; + adapter->hw.back = adapter; + adapter->hw.reg = pci_iomap(pdev, PCH_GBE_PCI_BAR, 0); + if (!adapter->hw.reg) { + ret = -EIO; + dev_err(&pdev->dev, "Can't ioremap\n"); + goto err_free_netdev; + } + + netdev->netdev_ops = &pch_gbe_netdev_ops; + netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; + netif_napi_add(netdev, &adapter->napi, + pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT); + netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO; + pch_gbe_set_ethtool_ops(netdev); + + pch_gbe_mac_reset_hw(&adapter->hw); + + /* setup the private structure */ + ret = pch_gbe_sw_init(adapter); + if (ret) + goto err_iounmap; + + /* Initialize PHY */ + ret = pch_gbe_init_phy(adapter); + if (ret) { + dev_err(&pdev->dev, "PHY initialize error\n"); + goto err_free_adapter; + } + pch_gbe_hal_get_bus_info(&adapter->hw); + + /* Read the MAC address. and store to the private data */ + ret = pch_gbe_hal_read_mac_addr(&adapter->hw); + if (ret) { + dev_err(&pdev->dev, "MAC address Read Error\n"); + goto err_free_adapter; + } + + memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); + if (!is_valid_ether_addr(netdev->dev_addr)) { + dev_err(&pdev->dev, "Invalid MAC Address\n"); + ret = -EIO; + goto err_free_adapter; + } + setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog, + (unsigned long)adapter); + + INIT_WORK(&adapter->reset_task, pch_gbe_reset_task); + + pch_gbe_check_options(adapter); + + if (adapter->tx_csum) + netdev->features |= NETIF_F_HW_CSUM; + else + netdev->features &= ~NETIF_F_HW_CSUM; + + /* initialize the wol settings based on the eeprom settings */ + adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING; + dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr); + + /* reset the hardware with the new settings */ + pch_gbe_reset(adapter); + + ret = register_netdev(netdev); + if (ret) + goto err_free_adapter; + /* tell the stack to leave us alone until pch_gbe_open() is called */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + dev_dbg(&pdev->dev, "OKIsemi(R) PCH Network Connection\n"); + + device_set_wakeup_enable(&pdev->dev, 1); + return 0; + +err_free_adapter: + pch_gbe_hal_phy_hw_reset(&adapter->hw); + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); +err_iounmap: + iounmap(adapter->hw.reg); +err_free_netdev: + free_netdev(netdev); +err_release_pci: + pci_release_regions(pdev); +err_disable_device: + pci_disable_device(pdev); + return ret; +} + +static const struct pci_device_id pch_gbe_pcidev_id[] = { + {.vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_IOH1_GBE, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_NETWORK_ETHERNET << 8), + .class_mask = (0xFFFF00) + }, + /* required last entry */ + {0} +}; + +#ifdef CONFIG_PM +static const struct dev_pm_ops pch_gbe_pm_ops = { + .suspend = pch_gbe_suspend, + .resume = pch_gbe_resume, + .freeze = pch_gbe_suspend, + .thaw = pch_gbe_resume, + .poweroff = pch_gbe_suspend, + .restore = pch_gbe_resume, +}; +#endif + +static struct pci_error_handlers pch_gbe_err_handler = { + .error_detected = pch_gbe_io_error_detected, + .slot_reset = pch_gbe_io_slot_reset, + .resume = pch_gbe_io_resume +}; + +static struct pci_driver pch_gbe_pcidev = { + .name = KBUILD_MODNAME, + .id_table = pch_gbe_pcidev_id, + .probe = pch_gbe_probe, + .remove = pch_gbe_remove, +#ifdef CONFIG_PM_OPS + .driver.pm = &pch_gbe_pm_ops, +#endif + .shutdown = pch_gbe_shutdown, + .err_handler = &pch_gbe_err_handler +}; + + +static int __init pch_gbe_init_module(void) +{ + int ret; + + ret = pci_register_driver(&pch_gbe_pcidev); + if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) { + if (copybreak == 0) { + pr_info("copybreak disabled\n"); + } else { + pr_info("copybreak enabled for packets <= %u bytes\n", + copybreak); + } + } + return ret; +} + +static void __exit pch_gbe_exit_module(void) +{ + pci_unregister_driver(&pch_gbe_pcidev); +} + +module_init(pch_gbe_init_module); +module_exit(pch_gbe_exit_module); + +MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver"); +MODULE_AUTHOR("OKI semiconductor, "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); +MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id); + +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + +/* pch_gbe_main.c */ diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c new file mode 100644 index 000000000000..2510146fc560 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_param.c @@ -0,0 +1,499 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +/** + * TxDescriptors - Transmit Descriptor Count + * @Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD + * @Default Value: PCH_GBE_DEFAULT_TXD + */ +static int TxDescriptors = OPTION_UNSET; +module_param(TxDescriptors, int, 0); +MODULE_PARM_DESC(TxDescriptors, "Number of transmit descriptors"); + +/** + * RxDescriptors -Receive Descriptor Count + * @Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD + * @Default Value: PCH_GBE_DEFAULT_RXD + */ +static int RxDescriptors = OPTION_UNSET; +module_param(RxDescriptors, int, 0); +MODULE_PARM_DESC(RxDescriptors, "Number of receive descriptors"); + +/** + * Speed - User Specified Speed Override + * @Valid Range: 0, 10, 100, 1000 + * - 0: auto-negotiate at all supported speeds + * - 10: only link at 10 Mbps + * - 100: only link at 100 Mbps + * - 1000: only link at 1000 Mbps + * @Default Value: 0 + */ +static int Speed = OPTION_UNSET; +module_param(Speed, int, 0); +MODULE_PARM_DESC(Speed, "Speed setting"); + +/** + * Duplex - User Specified Duplex Override + * @Valid Range: 0-2 + * - 0: auto-negotiate for duplex + * - 1: only link at half duplex + * - 2: only link at full duplex + * @Default Value: 0 + */ +static int Duplex = OPTION_UNSET; +module_param(Duplex, int, 0); +MODULE_PARM_DESC(Duplex, "Duplex setting"); + +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +/** + * AutoNeg - Auto-negotiation Advertisement Override + * @Valid Range: 0x01-0x0F, 0x20-0x2F + * + * The AutoNeg value is a bit mask describing which speed and duplex + * combinations should be advertised during auto-negotiation. + * The supported speed and duplex modes are listed below + * + * Bit 7 6 5 4 3 2 1 0 + * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 + * Duplex Full Full Half Full Half + * + * @Default Value: 0x2F (copper) + */ +static int AutoNeg = OPTION_UNSET; +module_param(AutoNeg, int, 0); +MODULE_PARM_DESC(AutoNeg, "Advertised auto-negotiation setting"); + +#define PHY_ADVERTISE_10_HALF 0x0001 +#define PHY_ADVERTISE_10_FULL 0x0002 +#define PHY_ADVERTISE_100_HALF 0x0004 +#define PHY_ADVERTISE_100_FULL 0x0008 +#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#define PHY_ADVERTISE_1000_FULL 0x0020 +#define PCH_AUTONEG_ADVERTISE_DEFAULT 0x2F + +/** + * FlowControl - User Specified Flow Control Override + * @Valid Range: 0-3 + * - 0: No Flow Control + * - 1: Rx only, respond to PAUSE frames but do not generate them + * - 2: Tx only, generate PAUSE frames but ignore them on receive + * - 3: Full Flow Control Support + * @Default Value: Read flow control settings from the EEPROM + */ +static int FlowControl = OPTION_UNSET; +module_param(FlowControl, int, 0); +MODULE_PARM_DESC(FlowControl, "Flow Control setting"); + +/* + * XsumRX - Receive Checksum Offload Enable/Disable + * @Valid Range: 0, 1 + * - 0: disables all checksum offload + * - 1: enables receive IP/TCP/UDP checksum offload + * @Default Value: PCH_GBE_DEFAULT_RX_CSUM + */ +static int XsumRX = OPTION_UNSET; +module_param(XsumRX, int, 0); +MODULE_PARM_DESC(XsumRX, "Disable or enable Receive Checksum offload"); + +#define PCH_GBE_DEFAULT_RX_CSUM true /* trueorfalse */ + +/* + * XsumTX - Transmit Checksum Offload Enable/Disable + * @Valid Range: 0, 1 + * - 0: disables all checksum offload + * - 1: enables transmit IP/TCP/UDP checksum offload + * @Default Value: PCH_GBE_DEFAULT_TX_CSUM + */ +static int XsumTX = OPTION_UNSET; +module_param(XsumTX, int, 0); +MODULE_PARM_DESC(XsumTX, "Disable or enable Transmit Checksum offload"); + +#define PCH_GBE_DEFAULT_TX_CSUM true /* trueorfalse */ + +/** + * pch_gbe_option - Force the MAC's flow control settings + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +struct pch_gbe_option { + enum { enable_option, range_option, list_option } type; + char *name; + char *err; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + const struct pch_gbe_opt_list { int i; char *str; } *p; + } l; + } arg; +}; + +static const struct pch_gbe_opt_list speed_list[] = { + { 0, "" }, + { SPEED_10, "" }, + { SPEED_100, "" }, + { SPEED_1000, "" } +}; + +static const struct pch_gbe_opt_list dplx_list[] = { + { 0, "" }, + { HALF_DUPLEX, "" }, + { FULL_DUPLEX, "" } +}; + +static const struct pch_gbe_opt_list an_list[] = + #define AA "AutoNeg advertising " + {{ 0x01, AA "10/HD" }, + { 0x02, AA "10/FD" }, + { 0x03, AA "10/FD, 10/HD" }, + { 0x04, AA "100/HD" }, + { 0x05, AA "100/HD, 10/HD" }, + { 0x06, AA "100/HD, 10/FD" }, + { 0x07, AA "100/HD, 10/FD, 10/HD" }, + { 0x08, AA "100/FD" }, + { 0x09, AA "100/FD, 10/HD" }, + { 0x0a, AA "100/FD, 10/FD" }, + { 0x0b, AA "100/FD, 10/FD, 10/HD" }, + { 0x0c, AA "100/FD, 100/HD" }, + { 0x0d, AA "100/FD, 100/HD, 10/HD" }, + { 0x0e, AA "100/FD, 100/HD, 10/FD" }, + { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, + { 0x20, AA "1000/FD" }, + { 0x21, AA "1000/FD, 10/HD" }, + { 0x22, AA "1000/FD, 10/FD" }, + { 0x23, AA "1000/FD, 10/FD, 10/HD" }, + { 0x24, AA "1000/FD, 100/HD" }, + { 0x25, AA "1000/FD, 100/HD, 10/HD" }, + { 0x26, AA "1000/FD, 100/HD, 10/FD" }, + { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, + { 0x28, AA "1000/FD, 100/FD" }, + { 0x29, AA "1000/FD, 100/FD, 10/HD" }, + { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, + { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, + { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, + { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, + { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, + { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" } +}; + +static const struct pch_gbe_opt_list fc_list[] = { + { PCH_GBE_FC_NONE, "Flow Control Disabled" }, + { PCH_GBE_FC_RX_PAUSE, "Flow Control Receive Only" }, + { PCH_GBE_FC_TX_PAUSE, "Flow Control Transmit Only" }, + { PCH_GBE_FC_FULL, "Flow Control Enabled" } +}; + +/** + * pch_gbe_validate_option - Validate option + * @value: value + * @opt: option + * @adapter: Board private structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_validate_option(int *value, + const struct pch_gbe_option *opt, + struct pch_gbe_adapter *adapter) +{ + if (*value == OPTION_UNSET) { + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + pr_debug("%s Enabled\n", opt->name); + return 0; + case OPTION_DISABLED: + pr_debug("%s Disabled\n", opt->name); + return 0; + } + break; + case range_option: + if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { + pr_debug("%s set to %i\n", opt->name, *value); + return 0; + } + break; + case list_option: { + int i; + const struct pch_gbe_opt_list *ent; + + for (i = 0; i < opt->arg.l.nr; i++) { + ent = &opt->arg.l.p[i]; + if (*value == ent->i) { + if (ent->str[0] != '\0') + pr_debug("%s\n", ent->str); + return 0; + } + } + } + break; + default: + BUG(); + } + + pr_debug("Invalid %s value specified (%i) %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +/** + * pch_gbe_check_copper_options - Range Checking for Link Options, Copper Version + * @adapter: Board private structure + */ +static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + int speed, dplx; + + { /* Speed */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Speed", + .err = "parameter ignored", + .def = 0, + .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list), + .p = speed_list } } + }; + speed = Speed; + pch_gbe_validate_option(&speed, &opt, adapter); + } + { /* Duplex */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Duplex", + .err = "parameter ignored", + .def = 0, + .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list), + .p = dplx_list } } + }; + dplx = Duplex; + pch_gbe_validate_option(&dplx, &opt, adapter); + } + + { /* Autoneg */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "AutoNeg", + .err = "parameter ignored", + .def = PCH_AUTONEG_ADVERTISE_DEFAULT, + .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list), + .p = an_list} } + }; + if (speed || dplx) { + pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n"); + hw->phy.autoneg_advertised = opt.def; + } else { + hw->phy.autoneg_advertised = AutoNeg; + pch_gbe_validate_option( + (int *)(&hw->phy.autoneg_advertised), + &opt, adapter); + } + } + + switch (speed + dplx) { + case 0: + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + if ((speed || dplx)) + pr_debug("Speed and duplex autonegotiation enabled\n"); + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case HALF_DUPLEX: + pr_debug("Half Duplex specified without Speed\n"); + pr_debug("Using Autonegotiation at Half Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | + PHY_ADVERTISE_100_HALF; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case FULL_DUPLEX: + pr_debug("Full Duplex specified without Speed\n"); + pr_debug("Using Autonegotiation at Full Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL | + PHY_ADVERTISE_100_FULL | + PHY_ADVERTISE_1000_FULL; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_10: + pr_debug("10 Mbps Speed specified without Duplex\n"); + pr_debug("Using Autonegotiation at 10 Mbps only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | + PHY_ADVERTISE_10_FULL; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_10 + HALF_DUPLEX: + pr_debug("Forcing to 10 Mbps Half Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_10 + FULL_DUPLEX: + pr_debug("Forcing to 10 Mbps Full Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_100: + pr_debug("100 Mbps Speed specified without Duplex\n"); + pr_debug("Using Autonegotiation at 100 Mbps only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF | + PHY_ADVERTISE_100_FULL; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_100 + HALF_DUPLEX: + pr_debug("Forcing to 100 Mbps Half Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_100 + FULL_DUPLEX: + pr_debug("Forcing to 100 Mbps Full Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_1000: + pr_debug("1000 Mbps Speed specified without Duplex\n"); + goto full_duplex_only; + case SPEED_1000 + HALF_DUPLEX: + pr_debug("Half Duplex is not supported at 1000 Mbps\n"); + /* fall through */ + case SPEED_1000 + FULL_DUPLEX: +full_duplex_only: + pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL; + hw->mac.link_speed = SPEED_1000; + hw->mac.link_duplex = DUPLEX_FULL; + break; + default: + BUG(); + } +} + +/** + * pch_gbe_check_options - Range Checking for Command Line Parameters + * @adapter: Board private structure + */ +void pch_gbe_check_options(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + { /* Transmit Descriptor Count */ + static const struct pch_gbe_option opt = { + .type = range_option, + .name = "Transmit Descriptors", + .err = "using default of " + __MODULE_STRING(PCH_GBE_DEFAULT_TXD), + .def = PCH_GBE_DEFAULT_TXD, + .arg = { .r = { .min = PCH_GBE_MIN_TXD } }, + .arg = { .r = { .max = PCH_GBE_MAX_TXD } } + }; + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + tx_ring->count = TxDescriptors; + pch_gbe_validate_option(&tx_ring->count, &opt, adapter); + tx_ring->count = roundup(tx_ring->count, + PCH_GBE_TX_DESC_MULTIPLE); + } + { /* Receive Descriptor Count */ + static const struct pch_gbe_option opt = { + .type = range_option, + .name = "Receive Descriptors", + .err = "using default of " + __MODULE_STRING(PCH_GBE_DEFAULT_RXD), + .def = PCH_GBE_DEFAULT_RXD, + .arg = { .r = { .min = PCH_GBE_MIN_RXD } }, + .arg = { .r = { .max = PCH_GBE_MAX_RXD } } + }; + struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; + rx_ring->count = RxDescriptors; + pch_gbe_validate_option(&rx_ring->count, &opt, adapter); + rx_ring->count = roundup(rx_ring->count, + PCH_GBE_RX_DESC_MULTIPLE); + } + { /* Checksum Offload Enable/Disable */ + static const struct pch_gbe_option opt = { + .type = enable_option, + .name = "Checksum Offload", + .err = "defaulting to Enabled", + .def = PCH_GBE_DEFAULT_RX_CSUM + }; + adapter->rx_csum = XsumRX; + pch_gbe_validate_option((int *)(&adapter->rx_csum), + &opt, adapter); + } + { /* Checksum Offload Enable/Disable */ + static const struct pch_gbe_option opt = { + .type = enable_option, + .name = "Checksum Offload", + .err = "defaulting to Enabled", + .def = PCH_GBE_DEFAULT_TX_CSUM + }; + adapter->tx_csum = XsumTX; + pch_gbe_validate_option((int *)(&adapter->tx_csum), + &opt, adapter); + } + { /* Flow Control */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Flow Control", + .err = "reading default settings from EEPROM", + .def = PCH_GBE_FC_DEFAULT, + .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), + .p = fc_list } } + }; + hw->mac.fc = FlowControl; + pch_gbe_validate_option((int *)(&hw->mac.fc), + &opt, adapter); + } + + pch_gbe_check_copper_options(adapter); +} diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c new file mode 100644 index 000000000000..923a687acd30 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_phy.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" +#include "pch_gbe_phy.h" + +#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ + +/* PHY 1000 MII Register/Bit Definitions */ +/* PHY Registers defined by IEEE */ +#define PHY_CONTROL 0x00 /* Control Register */ +#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_ID1 0x02 /* Phy Id Register (word 1) */ +#define PHY_ID2 0x03 /* Phy Id Register (word 2) */ +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */ +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Register */ +#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */ +#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */ +#define PHY_LED_CONTROL 0x18 /* LED Control Register */ +#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */ + +/* PHY Control Register */ +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define MII_CR_SPEED_1000 0x0040 +#define MII_CR_SPEED_100 0x2000 +#define MII_CR_SPEED_10 0x0000 + +/* PHY Status Register */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +/* Phy Id Register (word 2) */ +#define PHY_REVISION_MASK 0x000F + +/* PHY Specific Control Register */ +#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800 + + +/* Default value of PHY register */ +#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */ +#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */ +#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */ +#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */ +#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */ + +/** + * pch_gbe_phy_get_id - Retrieve the PHY ID and revision + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + s32 ret; + u16 phy_id1; + u16 phy_id2; + + ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1); + if (ret) + return ret; + ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2); + if (ret) + return ret; + /* + * PHY_ID1: [bit15-0:ID(21-6)] + * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision] + */ + phy->id = (u32)phy_id1; + phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10)); + phy->revision = (u32) (phy_id2 & 0x000F); + pr_debug("phy->id : 0x%08x phy->revision : 0x%08x\n", + phy->id, phy->revision); + return 0; +} + +/** + * pch_gbe_phy_read_reg_miic - Read MII control register + * @hw: Pointer to the HW structure + * @offset: Register offset to be read + * @data: Pointer to the read data + * Returns + * 0: Successful. + * -EINVAL: Invalid argument. + */ +s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + + if (offset > PHY_MAX_REG_ADDRESS) { + pr_err("PHY Address %d is out of range\n", offset); + return -EINVAL; + } + *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ, + offset, (u16)0); + return 0; +} + +/** + * pch_gbe_phy_write_reg_miic - Write MII control register + * @hw: Pointer to the HW structure + * @offset: Register offset to be read + * @data: data to write to register at offset + * Returns + * 0: Successful. + * -EINVAL: Invalid argument. + */ +s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + + if (offset > PHY_MAX_REG_ADDRESS) { + pr_err("PHY Address %d is out of range\n", offset); + return -EINVAL; + } + pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE, + offset, data); + return 0; +} + +/** + * pch_gbe_phy_sw_reset - PHY software reset + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw) +{ + u16 phy_ctrl; + + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl); + phy_ctrl |= MII_CR_RESET; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl); + udelay(1); +} + +/** + * pch_gbe_phy_hw_reset - PHY hardware reset + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw) +{ + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV, + PHY_AUTONEG_ADV_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX, + PHY_NEXT_PAGE_TX_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, + PHY_PHYSP_CONTROL_DEFAULT); +} + +/** + * pch_gbe_phy_power_up - restore link in case the phy was powered down + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_power_up(struct pch_gbe_hw *hw) +{ + u16 mii_reg; + + mii_reg = 0; + /* Just clear the power down bit to wake the phy back up */ + /* according to the manual, the phy will retain its + * settings across a power-down/up cycle */ + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg); + mii_reg &= ~MII_CR_POWER_DOWN; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg); +} + +/** + * pch_gbe_phy_power_down - Power down PHY + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_power_down(struct pch_gbe_hw *hw) +{ + u16 mii_reg; + + mii_reg = 0; + /* Power down the PHY so no link is implied when interface is down * + * The PHY cannot be powered down if any of the following is TRUE * + * (a) WoL is enabled + * (b) AMT is active + */ + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg); + mii_reg |= MII_CR_POWER_DOWN; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg); + mdelay(1); +} + +/** + * pch_gbe_phy_set_rgmii - RGMII interface setting + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw) +{ + pch_gbe_phy_sw_reset(hw); +} + +/** + * pch_gbe_phy_init_setting - PHY initial setting + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) +{ + struct pch_gbe_adapter *adapter; + struct ethtool_cmd cmd; + int ret; + u16 mii_reg; + + adapter = container_of(hw, struct pch_gbe_adapter, hw); + ret = mii_ethtool_gset(&adapter->mii, &cmd); + if (ret) + pr_err("Error: mii_ethtool_gset\n"); + + cmd.speed = hw->mac.link_speed; + cmd.duplex = hw->mac.link_duplex; + cmd.advertising = hw->phy.autoneg_advertised; + cmd.autoneg = hw->mac.autoneg; + pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET); + ret = mii_ethtool_sset(&adapter->mii, &cmd); + if (ret) + pr_err("Error: mii_ethtool_sset\n"); + + pch_gbe_phy_sw_reset(hw); + + pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg); + mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX; + pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg); + +} diff --git a/drivers/net/pch_gbe/pch_gbe_phy.h b/drivers/net/pch_gbe/pch_gbe_phy.h new file mode 100644 index 000000000000..03264dc7b5ec --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_phy.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PCH_GBE_PHY_H_ +#define _PCH_GBE_PHY_H_ + +#define PCH_GBE_PHY_REGS_LEN 32 +#define PCH_GBE_PHY_RESET_DELAY_US 10 +#define PCH_GBE_MAC_IFOP_RGMII + +s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw); +s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data); +s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data); +void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw); +void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw); +void pch_gbe_phy_power_up(struct pch_gbe_hw *hw); +void pch_gbe_phy_power_down(struct pch_gbe_hw *hw); +void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw); +void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw); + +#endif /* _PCH_GBE_PHY_H_ */ -- cgit v1.2.3 From 543876c92837a8b208b5c99ec225c1f5a581900e Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Fri, 24 Sep 2010 21:27:41 -0700 Subject: stmmac: review the wake-up support If the PM support is available this is passed through the platform instead to be hard-coded in the core files. WoL on Magic Frame can be enabled by using the ethtool support. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/common.h | 1 - drivers/net/stmmac/dwmac1000_core.c | 1 - drivers/net/stmmac/dwmac100_core.c | 1 - drivers/net/stmmac/stmmac_ethtool.c | 14 +++++++++----- drivers/net/stmmac/stmmac_main.c | 26 ++++++++++++++------------ include/linux/stmmac.h | 1 + 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index 673ef86a063f..dec7ce40c27a 100644 --- a/drivers/net/stmmac/common.h +++ b/drivers/net/stmmac/common.h @@ -238,7 +238,6 @@ struct mac_device_info { struct stmmac_ops *mac; struct stmmac_desc_ops *desc; struct stmmac_dma_ops *dma; - unsigned int pmt; /* support Power-Down */ struct mii_regs mii; /* MII register Addresses */ struct mac_link link; }; diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index c18c85993179..65667b692024 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -239,7 +239,6 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr) mac->mac = &dwmac1000_ops; mac->dma = &dwmac1000_dma_ops; - mac->pmt = PMT_SUPPORTED; mac->link.port = GMAC_CONTROL_PS; mac->link.duplex = GMAC_CONTROL_DM; mac->link.speed = GMAC_CONTROL_FES; diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index 58a914b27003..94eeccf3a8a0 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -193,7 +193,6 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) mac->mac = &dwmac100_ops; mac->dma = &dwmac100_dma_ops; - mac->pmt = PMT_NOT_SUPPORTED; mac->link.port = MAC_CONTROL_PS; mac->link.duplex = MAC_CONTROL_F; mac->link.speed = 0; diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index b32c16ae55c6..25a7e385f8ec 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -322,7 +322,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct stmmac_priv *priv = netdev_priv(dev); spin_lock_irq(&priv->lock); - if (priv->wolenabled == PMT_SUPPORTED) { + if (device_can_wakeup(priv->device)) { wol->supported = WAKE_MAGIC; wol->wolopts = priv->wolopts; } @@ -334,16 +334,20 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct stmmac_priv *priv = netdev_priv(dev); u32 support = WAKE_MAGIC; - if (priv->wolenabled == PMT_NOT_SUPPORTED) + if (!device_can_wakeup(priv->device)) return -EINVAL; if (wol->wolopts & ~support) return -EINVAL; - if (wol->wolopts == 0) - device_set_wakeup_enable(priv->device, 0); - else + if (wol->wolopts) { + pr_info("stmmac: wakeup enable\n"); device_set_wakeup_enable(priv->device, 1); + enable_irq_wake(dev->irq); + } else { + device_set_wakeup_enable(priv->device, 0); + disable_irq_wake(dev->irq); + } spin_lock_irq(&priv->lock); priv->wolopts = wol->wolopts; diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index a908f7201aae..823b9e6431d5 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1568,9 +1568,8 @@ static int stmmac_mac_device_setup(struct net_device *dev) priv->hw = device; - priv->wolenabled = priv->hw->pmt; /* PMT supported */ - if (priv->wolenabled == PMT_SUPPORTED) - priv->wolopts = WAKE_MAGIC; /* Magic Frame */ + if (device_can_wakeup(priv->device)) + priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ return 0; } @@ -1709,6 +1708,12 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->enh_desc = plat_dat->enh_desc; priv->ioaddr = addr; + /* PMT module is not integrated in all the MAC devices. */ + if (plat_dat->pmt) { + pr_info("\tPMT module supported\n"); + device_set_wakeup_capable(&pdev->dev, 1); + } + platform_set_drvdata(pdev, ndev); /* Set the I/O base addr */ @@ -1836,13 +1841,11 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) stmmac_mac_disable_tx(priv->ioaddr); - if (device_may_wakeup(&(pdev->dev))) { - /* Enable Power down mode by programming the PMT regs */ - if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); - } else { + /* Enable Power down mode by programming the PMT regs */ + if (device_can_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); + else stmmac_mac_disable_rx(priv->ioaddr); - } } else { priv->shutdown = 1; /* Although this can appear slightly redundant it actually @@ -1877,9 +1880,8 @@ static int stmmac_resume(struct platform_device *pdev) * is received. Anyway, it's better to manually clear * this bit because it can generate problems while resuming * from another devices (e.g. serial console). */ - if (device_may_wakeup(&(pdev->dev))) - if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(priv->ioaddr, 0); + if (device_can_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, 0); netif_device_attach(dev); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 1d8baf719211..d66c61774d95 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -37,6 +37,7 @@ struct plat_stmmacenet_data { int enh_desc; int tx_coe; int bugged_jumbo; + int pmt; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); #ifdef CONFIG_STM_DRIVERS -- cgit v1.2.3 From bba50b99b2410e863b38afdcd0280eb37f8a8bcc Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 23 Sep 2010 12:46:25 +0000 Subject: ixgbevf: Refactor ring parameter re-size The function to resize the Tx/Rx rings had the potential to dereference a NULL pointer and the code would attempt to resize the Tx ring even if the Rx ring allocation had failed. This would cause some confusion in the return code semantics. Fixed up to just unwind the allocations if any of them fail and return an error. Signed-off-by: Greg Rose Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbevf/ethtool.c | 153 ++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 4680b069b84f..4cc817acfb62 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, { struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; - int i, err; + int i, err = 0; u32 new_rx_count, new_tx_count; - bool need_tx_update = false; - bool need_rx_update = false; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) msleep(1); - if (new_tx_count != adapter->tx_ring_count) { - tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if (!tx_ring) { - err = -ENOMEM; - goto err_setup; - } - memcpy(tx_ring, adapter->tx_ring, - adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_tx_queues; i++) { - tx_ring[i].count = new_tx_count; - err = ixgbevf_setup_tx_resources(adapter, - &tx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_tx_resources(adapter, - &tx_ring[i]); - } - kfree(tx_ring); - goto err_setup; - } - tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; - } - need_tx_update = true; + /* + * If the adapter isn't up and running then just set the + * new parameters and scurry for the exits. + */ + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; } - if (new_rx_count != adapter->rx_ring_count) { - rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if ((!rx_ring) && (need_tx_update)) { - err = -ENOMEM; - goto err_rx_setup; - } - memcpy(rx_ring, adapter->rx_ring, - adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_rx_queues; i++) { - rx_ring[i].count = new_rx_count; - err = ixgbevf_setup_rx_resources(adapter, - &rx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_rx_resources(adapter, - &rx_ring[i]); - } - kfree(rx_ring); - goto err_rx_setup; - } - rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; - } - need_rx_update = true; + tx_ring = kcalloc(adapter->num_tx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!tx_ring) { + err = -ENOMEM; + goto clear_reset; } -err_rx_setup: - /* if rings need to be updated, here's the place to do it in one shot */ - if (need_tx_update || need_rx_update) { - if (netif_running(netdev)) - ixgbevf_down(adapter); + rx_ring = kcalloc(adapter->num_rx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!rx_ring) { + err = -ENOMEM; + goto err_rx_setup; } - /* tx */ - if (need_tx_update) { - kfree(adapter->tx_ring); - adapter->tx_ring = tx_ring; - tx_ring = NULL; - adapter->tx_ring_count = new_tx_count; + ixgbevf_down(adapter); + + memcpy(tx_ring, adapter->tx_ring, + adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_tx_queues; i++) { + tx_ring[i].count = new_tx_count; + err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_tx_resources(adapter, + &tx_ring[i]); + } + goto err_tx_ring_setup; + } + tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; } - /* rx */ - if (need_rx_update) { - kfree(adapter->rx_ring); - adapter->rx_ring = rx_ring; - rx_ring = NULL; - adapter->rx_ring_count = new_rx_count; + memcpy(rx_ring, adapter->rx_ring, + adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_rx_queues; i++) { + rx_ring[i].count = new_rx_count; + err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_rx_resources(adapter, + &rx_ring[i]); + } + goto err_rx_ring_setup; + } + rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; } + /* + * Only switch to new rings if all the prior allocations + * and ring setups have succeeded. + */ + kfree(adapter->tx_ring); + adapter->tx_ring = tx_ring; + adapter->tx_ring_count = new_tx_count; + + kfree(adapter->rx_ring); + adapter->rx_ring = rx_ring; + adapter->rx_ring_count = new_rx_count; + /* success! */ - err = 0; - if (netif_running(netdev)) - ixgbevf_up(adapter); + ixgbevf_up(adapter); + + goto clear_reset; + +err_rx_ring_setup: + for(i = 0; i < adapter->num_tx_queues; i++) + ixgbevf_free_tx_resources(adapter, &tx_ring[i]); + +err_tx_ring_setup: + kfree(rx_ring); + +err_rx_setup: + kfree(tx_ring); -err_setup: +clear_reset: clear_bit(__IXGBEVF_RESETTING, &adapter->state); return err; } -- cgit v1.2.3 From c5256c51232d8312755e8de2b514c426b19b101a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 00:46:11 +0000 Subject: net: propagate NETIF_F_HIGHDMA to vlans Automatically allows vlans to get NETIF_F_HIGHDMA if underlying device supports it. On 32bit arches (and more precisely if CONFIG_HIGHMEM is enabled), it can help to reduce cost of illegal_highdma() and __skb_linearize() calls. Tested on tg3 , bnx2, bonding, this worked very well. This is a generalization of a patch provided by Yi Zou & Jeff Kirsher. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 2c7934f8cf3e..e0c0b86f57a1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5058,10 +5058,11 @@ int register_netdevice(struct net_device *dev) if (dev->features & NETIF_F_SG) dev->features |= NETIF_F_GSO; - /* Enable GRO for vlans by default if dev->features has GRO also. - * vlan_dev_init() will do the dev->features check. + /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, + * vlan_dev_init() will do the dev->features check, so these features + * are enabled only if supported by underlying device. */ - dev->vlan_features |= NETIF_F_GRO; + dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA); ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); ret = notifier_to_errno(ret); -- cgit v1.2.3 From cb4dfe562cac6fcb544df752e40c1d78000d0712 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 05:06:54 +0000 Subject: net: skb_frag_t can be smaller on small arches On 32bit arches, if PAGE_SIZE is smaller than 65536, we can use 16bit offset and size fields. This patch saves 72 bytes per skb on i386, or 128 bytes after rounding. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/skbuff.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b2c41d19735c..0b53c43ac92e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -129,8 +129,13 @@ typedef struct skb_frag_struct skb_frag_t; struct skb_frag_struct { struct page *page; +#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536) __u32 page_offset; __u32 size; +#else + __u16 page_offset; + __u16 size; +#endif }; #define HAVE_HW_TIME_STAMP -- cgit v1.2.3 From 807540baae406c84dcb9c1c8ef07a56d2d2ae84a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 05:40:09 +0000 Subject: drivers/net: return operator cleanup Change "return (EXPR);" to "return EXPR;" return is not a function, parentheses are not required. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/3c523.c | 2 +- drivers/net/appletalk/ipddp.c | 10 +- drivers/net/appletalk/ltpc.c | 2 +- drivers/net/atarilance.c | 24 +- drivers/net/atlx/atl1.c | 4 +- drivers/net/benet/be_cmds.c | 4 +- drivers/net/bmac.c | 2 +- drivers/net/bna/bna_ctrl.c | 6 +- drivers/net/bnx2.c | 20 +- drivers/net/bnx2x/bnx2x_cmn.h | 4 +- drivers/net/bonding/bond_3ad.c | 2 +- drivers/net/bsd_comp.c | 2 +- drivers/net/cassini.c | 4 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/chelsio/vsc7326.c | 2 +- drivers/net/cxgb3/cxgb3_offload.c | 2 +- drivers/net/de620.c | 2 +- drivers/net/defxx.c | 66 ++--- drivers/net/e100.c | 4 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/ethtool.c | 4 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/enic/vnic_rq.h | 2 +- drivers/net/eth16i.c | 12 +- drivers/net/forcedeth.c | 2 +- drivers/net/fsl_pq_mdio.c | 4 +- drivers/net/gianfar_ethtool.c | 4 +- drivers/net/hamradio/bpqether.c | 2 +- drivers/net/hamradio/hdlcdrv.c | 2 +- drivers/net/hp100.c | 6 +- drivers/net/ibm_newemac/core.c | 6 +- drivers/net/ibm_newemac/core.h | 6 +- drivers/net/igb/igb_main.c | 2 +- drivers/net/igbvf/ethtool.c | 2 +- drivers/net/igbvf/netdev.c | 2 +- drivers/net/irda/donauboe.c | 4 +- drivers/net/irda/irda-usb.c | 2 +- drivers/net/irda/nsc-ircc.c | 2 +- drivers/net/irda/sir_dev.c | 2 +- drivers/net/irda/smsc-ircc2.c | 2 +- drivers/net/irda/stir4200.c | 2 +- drivers/net/irda/via-ircc.h | 2 +- drivers/net/irda/vlsi_ir.h | 2 +- drivers/net/ixgb/ixgb_ee.c | 32 +-- drivers/net/ixgb/ixgb_ethtool.c | 2 +- drivers/net/ixgb/ixgb_hw.c | 14 +- drivers/net/ixgbe/ixgbe_ethtool.c | 6 +- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/ll_temac_main.c | 2 +- drivers/net/lp486e.c | 2 +- drivers/net/meth.c | 2 +- drivers/net/mlx4/en_selftest.c | 2 +- drivers/net/myri10ge/myri10ge.c | 6 +- drivers/net/myri_sbus.c | 2 +- drivers/net/netxen/netxen_nic_init.c | 4 +- drivers/net/netxen/netxen_nic_main.c | 2 +- drivers/net/niu.c | 13 +- drivers/net/pcmcia/nmclan_cs.c | 2 +- drivers/net/pcmcia/smc91c92_cs.c | 2 +- drivers/net/pcnet32.c | 4 +- drivers/net/ps3_gelic_wireless.c | 6 +- drivers/net/qlcnic/qlcnic_main.c | 2 +- drivers/net/sfc/net_driver.h | 2 +- drivers/net/sfc/nic.c | 10 +- drivers/net/sis900.c | 6 +- drivers/net/skfp/cfm.c | 10 +- drivers/net/skfp/drvfbi.c | 16 +- drivers/net/skfp/ess.c | 46 ++-- drivers/net/skfp/fplustm.c | 24 +- drivers/net/skfp/hwmtm.c | 30 +-- drivers/net/skfp/hwt.c | 4 +- drivers/net/skfp/pcmplc.c | 22 +- drivers/net/skfp/pmf.c | 62 +++-- drivers/net/skfp/queue.c | 2 +- drivers/net/skfp/skfddi.c | 32 +-- drivers/net/skfp/smt.c | 78 +++--- drivers/net/skfp/smtdef.c | 4 +- drivers/net/skfp/smtinit.c | 2 +- drivers/net/skfp/srf.c | 2 +- drivers/net/slip.c | 2 +- drivers/net/sun3lance.c | 4 +- drivers/net/sungem_phy.c | 2 +- drivers/net/sunhme.c | 2 +- drivers/net/sunqe.c | 2 +- drivers/net/tc35815.c | 2 +- drivers/net/tg3.c | 5 +- drivers/net/tlan.c | 2 +- drivers/net/tlan.h | 8 +- drivers/net/tokenring/proteon.c | 2 +- drivers/net/tokenring/smctr.c | 500 ++++++++++++++++++----------------- drivers/net/tokenring/tms380tr.c | 58 ++-- drivers/net/tsi108_eth.c | 2 +- drivers/net/tulip/de4x5.c | 36 +-- drivers/net/tulip/uli526x.c | 2 +- drivers/net/typhoon.c | 2 +- drivers/net/usb/sierra_net.c | 4 +- drivers/net/veth.c | 2 +- drivers/net/wan/dlci.c | 42 +-- drivers/net/wan/lmc/lmc_main.c | 4 +- drivers/net/wan/n2.c | 4 +- drivers/net/wan/pc300_drv.c | 18 +- drivers/net/wan/pc300_tty.c | 2 +- drivers/net/wan/sdla.c | 108 ++++---- drivers/net/wan/x25_asy.c | 2 +- drivers/net/xen-netfront.c | 6 +- 106 files changed, 762 insertions(+), 764 deletions(-) diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index a7b0e5e43a52..ca00f0a11217 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -463,7 +463,7 @@ static int __init do_elmc_probe(struct net_device *dev) /* we didn't find any 3c523 in the slots we checked for */ if (slot == MCA_NOTFOUND) - return ((base_addr || irq) ? -ENXIO : -ENODEV); + return (base_addr || irq) ? -ENXIO : -ENODEV; mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC"); mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev); diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 0362c8d31a08..10d0dba572c2 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -244,7 +244,7 @@ static int ipddp_delete(struct ipddp_route *rt) } spin_unlock_bh(&ipddp_route_lock); - return (-ENOENT); + return -ENOENT; } /* @@ -259,10 +259,10 @@ static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) if(f->ip == rt->ip && f->at.s_net == rt->at.s_net && f->at.s_node == rt->at.s_node) - return (f); + return f; } - return (NULL); + return NULL; } static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -279,7 +279,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch(cmd) { case SIOCADDIPDDPRT: - return (ipddp_create(&rcp)); + return ipddp_create(&rcp); case SIOCFINDIPDDPRT: spin_lock_bh(&ipddp_route_lock); @@ -297,7 +297,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -ENOENT; case SIOCDELIPDDPRT: - return (ipddp_delete(&rcp)); + return ipddp_delete(&rcp); default: return -EINVAL; diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index adc07551739e..e69eead12ec7 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -727,7 +727,7 @@ static int sendup_buffer (struct net_device *dev) if (ltc->command != LT_RCVLAP) { printk("unknown command 0x%02x from ltpc card\n",ltc->command); - return(-1); + return -1; } dnode = ltc->dnode; snode = ltc->snode; diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index b57d7dee389a..3134e5326231 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -362,7 +362,7 @@ static void *slow_memcpy( void *dst, const void *src, size_t len ) *cto++ = *cfrom++; MFPDELAY(); } - return( dst ); + return dst; } @@ -449,7 +449,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag, vbr[2] = save_berr; local_irq_restore(flags); - return( ret ); + return ret; } static const struct net_device_ops lance_netdev_ops = { @@ -526,7 +526,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, goto probe_ok; probe_fail: - return( 0 ); + return 0; probe_ok: lp = netdev_priv(dev); @@ -556,7 +556,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO, "PAM/Riebl-ST Ethernet", dev)) { printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 ); - return( 0 ); + return 0; } dev->irq = (unsigned short)IRQ_AUTO_5; } @@ -568,12 +568,12 @@ static unsigned long __init lance_probe1( struct net_device *dev, unsigned long irq = atari_register_vme_int(); if (!irq) { printk( "Lance: request for VME interrupt failed\n" ); - return( 0 ); + return 0; } if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO, "Riebl-VME Ethernet", dev)) { printk( "Lance: request for irq %ld failed\n", irq ); - return( 0 ); + return 0; } dev->irq = irq; } @@ -637,7 +637,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, /* XXX MSch */ dev->watchdog_timeo = TX_TIMEOUT; - return( 1 ); + return 1; } @@ -666,7 +666,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; - return( -EIO ); + return -EIO; } DREG = CSR0_IDON; DREG = CSR0_STRT; @@ -676,7 +676,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); - return( 0 ); + return 0; } @@ -1126,13 +1126,13 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) int i; if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL) - return( -EOPNOTSUPP ); + return -EOPNOTSUPP; if (netif_running(dev)) { /* Only possible while card isn't started */ DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n", dev->name )); - return( -EIO ); + return -EIO; } memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); @@ -1142,7 +1142,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) /* set also the magic for future sessions */ *RIEBL_MAGIC_ADDR = RIEBL_MAGIC; - return( 0 ); + return 0; } diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index e1e0171d6e62..4ba6431deeef 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2094,9 +2094,9 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring) { u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); u16 next_to_use = atomic_read(&tpd_ring->next_to_use); - return ((next_to_clean > next_to_use) ? + return (next_to_clean > next_to_use) ? next_to_clean - next_to_use - 1 : - tpd_ring->count + next_to_clean - next_to_use - 1); + tpd_ring->count + next_to_clean - next_to_use - 1; } static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 34abcc9403d6..0db28b411e87 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -98,9 +98,9 @@ static void be_async_link_state_process(struct be_adapter *adapter, static inline bool is_link_state_evt(u32 trailer) { - return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & + return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & ASYNC_TRAILER_EVENT_CODE_MASK) == - ASYNC_EVENT_CODE_LINK_STATE); + ASYNC_EVENT_CODE_LINK_STATE; } static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 9322699bb31c..a1b8c8b8010b 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1581,7 +1581,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length) int i; if (bmac_devs == NULL) - return (-ENOSYS); + return -ENOSYS; len += sprintf(buffer, "BMAC counters & registers\n"); diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index f3034d6bda58..ddd922f210c7 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -25,8 +25,8 @@ static int bna_is_aen(u8 msg_id) { - return (msg_id == BFI_LL_I2H_LINK_DOWN_AEN || - msg_id == BFI_LL_I2H_LINK_UP_AEN); + return msg_id == BFI_LL_I2H_LINK_DOWN_AEN || + msg_id == BFI_LL_I2H_LINK_UP_AEN; } static void @@ -1702,7 +1702,7 @@ bna_device_cb_port_stopped(void *arg, enum bna_cb_status status) int bna_device_status_get(struct bna_device *device) { - return (device->fsm == (bfa_fsm_t)bna_device_sm_ready); + return device->fsm == (bfa_fsm_t)bna_device_sm_ready; } void diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4ff76e38e788..3d1a5da98622 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -266,7 +266,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) if (diff == TX_DESC_CNT) diff = MAX_TX_DESC_CNT; } - return (bp->tx_ring_size - diff); + return bp->tx_ring_size - diff; } static u32 @@ -299,7 +299,7 @@ bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val) static u32 bnx2_shmem_rd(struct bnx2 *bp, u32 offset) { - return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset)); + return bnx2_reg_rd_ind(bp, bp->shmem_base + offset); } static void @@ -977,9 +977,9 @@ bnx2_report_fw_link(struct bnx2 *bp) static char * bnx2_xceiver_str(struct bnx2 *bp) { - return ((bp->phy_port == PORT_FIBRE) ? "SerDes" : + return (bp->phy_port == PORT_FIBRE) ? "SerDes" : ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" : - "Copper")); + "Copper"); } static void @@ -1758,7 +1758,7 @@ __acquires(&bp->phy_lock) u32 new_adv = 0; if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) - return (bnx2_setup_remote_phy(bp, port)); + return bnx2_setup_remote_phy(bp, port); if (!(bp->autoneg & AUTONEG_SPEED)) { u32 new_bmcr; @@ -2171,10 +2171,10 @@ __acquires(&bp->phy_lock) return 0; if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) { - return (bnx2_setup_serdes_phy(bp, port)); + return bnx2_setup_serdes_phy(bp, port); } else { - return (bnx2_setup_copper_phy(bp)); + return bnx2_setup_copper_phy(bp); } } @@ -7582,9 +7582,9 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data) struct bnx2 *bp = netdev_priv(dev); if (CHIP_NUM(bp) == CHIP_NUM_5709) - return (ethtool_op_set_tx_ipv6_csum(dev, data)); + return ethtool_op_set_tx_ipv6_csum(dev, data); else - return (ethtool_op_set_tx_csum(dev, data)); + return ethtool_op_set_tx_csum(dev, data); } static int @@ -7705,7 +7705,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; - return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size)); + return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size); } #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index d1e6a8c977d1..1ad08e4e88f4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -399,7 +399,7 @@ static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ barrier(); - return (fp->tx_pkt_prod != fp->tx_pkt_cons); + return fp->tx_pkt_prod != fp->tx_pkt_cons; } static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) @@ -632,7 +632,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) rx_cons_sb++; - return (fp->rx_comp_cons != rx_cons_sb); + return fp->rx_comp_cons != rx_cons_sb; } /* HW Lock for shared dual port PHYs */ diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 822f586d72af..2a47c1deb9f0 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -252,7 +252,7 @@ static inline void __enable_port(struct port *port) */ static inline int __port_is_enabled(struct port *port) { - return(port->slave->state == BOND_STATE_ACTIVE); + return port->slave->state == BOND_STATE_ACTIVE; } /** diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 88edb986691a..6e99d80ec409 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -429,7 +429,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) if (!db->lens) { bsd_free (db); - return (NULL); + return NULL; } } /* diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 32aaadc4734f..d6b6d6aa565a 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -419,7 +419,7 @@ static u16 cas_phy_read(struct cas *cp, int reg) udelay(10); cmd = readl(cp->regs + REG_MIF_FRAME); if (cmd & MIF_FRAME_TURN_AROUND_LSB) - return (cmd & MIF_FRAME_DATA_MASK); + return cmd & MIF_FRAME_DATA_MASK; } return 0xFFFF; /* -1 */ } @@ -804,7 +804,7 @@ static int cas_reset_mii_phy(struct cas *cp) break; udelay(10); } - return (limit <= 0); + return limit <= 0; } static int cas_saturn_firmware_init(struct cas *cp) diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 1950b9a20ecd..340b537dc97e 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1551,7 +1551,7 @@ static inline int responses_pending(const struct adapter *adapter) const struct respQ *Q = &adapter->sge->respQ; const struct respQ_e *e = &Q->entries[Q->cidx]; - return (e->GenerationBit == Q->genbit); + return e->GenerationBit == Q->genbit; } /* diff --git a/drivers/net/chelsio/vsc7326.c b/drivers/net/chelsio/vsc7326.c index c844111cffeb..106a590f0d9a 100644 --- a/drivers/net/chelsio/vsc7326.c +++ b/drivers/net/chelsio/vsc7326.c @@ -255,7 +255,7 @@ static int bist_rd(adapter_t *adapter, int moduleid, int address) else if ((result & (1 << 8)) != 0x0) pr_err("bist read error: 0x%x\n", result); - return (result & 0xff); + return result & 0xff; } static int bist_wr(adapter_t *adapter, int moduleid, int address, int value) diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index c6485b39eb0e..21db7491f613 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -64,7 +64,7 @@ static inline int offload_activated(struct t3cdev *tdev) { const struct adapter *adapter = tdev2adap(tdev); - return (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)); + return test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); } /** diff --git a/drivers/net/de620.c b/drivers/net/de620.c index f3650fd096f4..1c51a7576119 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -676,7 +676,7 @@ static int de620_rx_intr(struct net_device *dev) de620_set_register(dev, W_NPRF, next_rx_page); pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page); - return (next_rx_page != curr_page); /* That was slightly tricky... */ + return next_rx_page != curr_page; /* That was slightly tricky... */ } /********************************************* diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index e5667c55844e..417e14385623 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -1024,7 +1024,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } le32 = cpu_to_le32(data); memcpy(&bp->factory_mac_addr[0], &le32, sizeof(u32)); @@ -1033,7 +1033,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } le32 = cpu_to_le32(data); memcpy(&bp->factory_mac_addr[4], &le32, sizeof(u16)); @@ -1075,7 +1075,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, if (top_v == NULL) { printk("%s: Could not allocate memory for host buffers " "and structures!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } memset(top_v, 0, alloc_size); /* zero out memory before continuing */ top_p = bp->kmalloced_dma; /* get physical address of buffer */ @@ -1145,7 +1145,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n", print_name, (long)bp->cons_block_virt, bp->cons_block_phys); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -1195,7 +1195,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_uninit(bp, bp->reset_type) != DFX_K_SUCCESS) { printk("%s: Could not uninitialize/reset adapter!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1229,7 +1229,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) NULL) != DFX_K_SUCCESS) { printk("%s: Could not set adapter burst size!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1246,7 +1246,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) NULL) != DFX_K_SUCCESS) { printk("%s: Could not set consumer block address!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1278,7 +1278,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Set the initial values for eFDXEnable and MACTReq MIB objects */ @@ -1294,7 +1294,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialize adapter CAM */ @@ -1302,7 +1302,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_ctl_update_cam(bp) != DFX_K_SUCCESS) { printk("%s: Adapter CAM update failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialize adapter filters */ @@ -1310,7 +1310,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_ctl_update_filters(bp) != DFX_K_SUCCESS) { printk("%s: Adapter filters update failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1328,7 +1328,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) printk("%s: Receive buffer allocation failed\n", bp->dev->name); if (get_buffers) dfx_rcv_flush(bp); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Issue START command and bring adapter to LINK_(UN)AVAILABLE state */ @@ -1339,13 +1339,13 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) printk("%s: Start command failed\n", bp->dev->name); if (get_buffers) dfx_rcv_flush(bp); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialization succeeded, reenable PDQ interrupts */ dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_ENABLE_DEF_INTS); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -1434,7 +1434,7 @@ static int dfx_open(struct net_device *dev) /* Set device structure info */ netif_start_queue(dev); - return(0); + return 0; } @@ -1526,7 +1526,7 @@ static int dfx_close(struct net_device *dev) free_irq(dev->irq, dev); - return(0); + return 0; } @@ -2027,7 +2027,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->cmd_req_virt->cmd_type = PI_CMD_K_SMT_MIB_GET; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; /* Fill the bp->stats structure with the SMT MIB object values */ @@ -2128,7 +2128,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->cmd_req_virt->cmd_type = PI_CMD_K_CNTRS_GET; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; /* Fill the bp->stats structure with the FDDI counter values */ @@ -2144,7 +2144,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->stats.port_lem_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[0].ls; bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls; - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; } @@ -2354,7 +2354,7 @@ static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr) { DBG_printk("%s: Adapter CAM updated with new MAC address\n", dev->name); } - return(0); /* always return zero */ + return 0; /* always return zero */ } @@ -2438,8 +2438,8 @@ static int dfx_ctl_update_cam(DFX_board_t *bp) /* Issue command to update adapter CAM, then return */ if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return(DFX_K_FAILURE); - return(DFX_K_SUCCESS); + return DFX_K_FAILURE; + return DFX_K_SUCCESS; } @@ -2504,8 +2504,8 @@ static int dfx_ctl_update_filters(DFX_board_t *bp) /* Issue command to update adapter filters, then return */ if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return(DFX_K_FAILURE); - return(DFX_K_SUCCESS); + return DFX_K_FAILURE; + return DFX_K_SUCCESS; } @@ -2561,7 +2561,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) (status == PI_STATE_K_HALTED) || (status == PI_STATE_K_DMA_UNAVAIL) || (status == PI_STATE_K_UPGRADE)) - return(DFX_K_OUTSTATE); + return DFX_K_OUTSTATE; /* Put response buffer on the command response queue */ @@ -2599,7 +2599,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* Bump (and wrap) the completion index and write out to register */ @@ -2619,14 +2619,14 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* Bump (and wrap) the completion index and write out to register */ bp->cmd_rsp_reg.index.comp += 1; bp->cmd_rsp_reg.index.comp &= PI_CMD_RSP_K_NUM_ENTRIES-1; dfx_port_write_long(bp, PI_PDQ_K_REG_CMD_RSP_PROD, bp->cmd_rsp_reg.lword); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -2700,7 +2700,7 @@ static int dfx_hw_port_ctrl_req( udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* * If the address of host_data is non-zero, assume caller has supplied a @@ -2710,7 +2710,7 @@ static int dfx_hw_port_ctrl_req( if (host_data != NULL) dfx_port_read_long(bp, PI_PDQ_K_REG_HOST_DATA, host_data); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -2800,7 +2800,7 @@ static int dfx_hw_adap_state_rd(DFX_board_t *bp) PI_UINT32 port_status; /* Port Status register value */ dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &port_status); - return((port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE); + return (port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE; } @@ -2852,8 +2852,8 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); - return(DFX_K_SUCCESS); + return DFX_K_HW_TIMEOUT; + return DFX_K_SUCCESS; } /* diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 8e2eab4e7c75..b0aa9e68990a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2215,10 +2215,10 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu) static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ - return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && + return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && (nic->eeprom[eeprom_config_asf] & eeprom_asf) && !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && - ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); + ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE); } static int e100_up(struct nic *nic) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 796523f2c6b1..cb3f84b81793 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3600,7 +3600,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, adapter->total_tx_packets += total_tx_packets; netdev->stats.tx_bytes += total_tx_bytes; netdev->stats.tx_packets += total_tx_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } /** diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 6355a1b779d3..b7f15b3f0e03 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -368,7 +368,7 @@ out: static u32 e1000_get_rx_csum(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - return (adapter->flags & FLAG_RX_CSUM_ENABLED); + return adapter->flags & FLAG_RX_CSUM_ENABLED; } static int e1000_set_rx_csum(struct net_device *netdev, u32 data) @@ -389,7 +389,7 @@ static int e1000_set_rx_csum(struct net_device *netdev, u32 data) static u32 e1000_get_tx_csum(struct net_device *netdev) { - return ((netdev->features & NETIF_F_HW_CSUM) != 0); + return (netdev->features & NETIF_F_HW_CSUM) != 0; } static int e1000_set_tx_csum(struct net_device *netdev, u32 data) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4630bad52e74..5d5850b556cf 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1053,7 +1053,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) adapter->total_tx_packets += total_tx_packets; netdev->stats.tx_bytes += total_tx_bytes; netdev->stats.tx_packets += total_tx_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } /** diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h index 2dc48f91abf7..4b6f0212c8a2 100644 --- a/drivers/net/enic/vnic_rq.h +++ b/drivers/net/enic/vnic_rq.h @@ -143,7 +143,7 @@ static inline void vnic_rq_post(struct vnic_rq *rq, static inline int vnic_rq_posting_soon(struct vnic_rq *rq) { - return ((rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0); + return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0; } static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index ce22e15a3776..fb717be511f6 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -796,7 +796,7 @@ static int eth16i_receive_probe_packet(int ioaddr) if(eth16i_debug > 1) printk(KERN_DEBUG "RECEIVE_PACKET\n"); - return(0); /* Found receive packet */ + return 0; /* Found receive packet */ } } @@ -805,7 +805,7 @@ static int eth16i_receive_probe_packet(int ioaddr) printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG)); } - return(0); /* Return success */ + return 0; /* Return success */ } #if 0 @@ -841,7 +841,7 @@ static int __init eth16i_get_irq(int ioaddr) if( ioaddr < 0x1000) { cbyte = inb(ioaddr + JUMPERLESS_CONFIG); - return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] ); + return eth16i_irqmap[((cbyte & 0xC0) >> 6)]; } else { /* Oh..the card is EISA so method getting IRQ different */ unsigned short index = 0; cbyte = inb(ioaddr + EISA_IRQ_REG); @@ -849,7 +849,7 @@ static int __init eth16i_get_irq(int ioaddr) cbyte = cbyte >> 1; index++; } - return( eth32i_irqmap[ index ] ); + return eth32i_irqmap[index]; } } @@ -909,7 +909,7 @@ static int eth16i_read_eeprom(int ioaddr, int offset) data = eth16i_read_eeprom_word(ioaddr); outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG); - return(data); + return data; } static int eth16i_read_eeprom_word(int ioaddr) @@ -928,7 +928,7 @@ static int eth16i_read_eeprom_word(int ioaddr) eeprom_slow_io(); } - return(data); + return data; } static void eth16i_eeprom_cmd(int ioaddr, unsigned char command) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 6a44fe411589..ddac63cefbaa 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -4620,7 +4620,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* static u32 nv_get_rx_csum(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - return (np->rx_csum) != 0; + return np->rx_csum != 0; } static int nv_set_rx_csum(struct net_device *dev, u32 data) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d4bf91aac25f..8d3a2ccbc953 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -125,7 +125,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Write to the local MII regs */ - return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value)); + return fsl_pq_local_mdio_write(regs, mii_id, regnum, value); } /* @@ -137,7 +137,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Read the local MII regs */ - return(fsl_pq_local_mdio_read(regs, mii_id, regnum)); + return fsl_pq_local_mdio_read(regs, mii_id, regnum); } /* Reset the MIIM registers, and wait for the bus to free */ diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 9bda023c0235..ae8e5d3c6c1f 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -254,7 +254,7 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use /* Make sure we return a number greater than 0 * if usecs > 0 */ - return ((usecs * 1000 + count - 1) / count); + return (usecs * 1000 + count - 1) / count; } /* Convert ethernet clock ticks to microseconds */ @@ -278,7 +278,7 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic /* Make sure we return a number greater than 0 */ /* if ticks is > 0 */ - return ((ticks * count) / 1000); + return (ticks * count) / 1000; } /* Get the coalescing parameters, and put them in the cvals diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 14f01d156db9..ac1d323c5eb5 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -168,7 +168,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev) static inline int dev_is_ethdev(struct net_device *dev) { - return (dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5)); + return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5); } /* ------------------------------------------------------------------------ */ diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index b8bdf9d51cd4..5b37579e84b7 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -110,7 +110,7 @@ static int calc_crc_ccitt(const unsigned char *buf, int cnt) for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; crc ^= 0xffff; - return (crc & 0xffff); + return crc & 0xffff; } #endif diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 095b17ecf609..8e2c4601b5f5 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -1312,7 +1312,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, for (p = (ringptr->pdl); p < (ringptr->pdl + 5); p++) printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n", dev->name, (u_int) p, (u_int) * p); #endif - return (1); + return 1; } /* else: */ /* alloc_skb failed (no memory) -> still can receive the header @@ -1325,7 +1325,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, ringptr->pdl[0] = 0x00010000; /* PDH: Count=1 Fragment */ - return (0); + return 0; } /* @@ -2752,7 +2752,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin) hp100_outw(HP100_MISC_ERROR, IRQ_STATUS); if (val & HP100_LINK_UP_ST) - return (0); /* login was ok */ + return 0; /* login was ok */ else { printk("hp100: %s: Training failed.\n", dev->name); hp100_down_vg_link(dev); diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 3506fd6ad726..3bdb4fa32064 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2095,11 +2095,11 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf) if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { hdr->version = EMAC4_ETHTOOL_REGS_VER; memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); - return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev)); + return (void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev); } else { hdr->version = EMAC_ETHTOOL_REGS_VER; memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); - return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev)); + return (void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev); } } @@ -2293,7 +2293,7 @@ static int __devinit emac_check_deps(struct emac_instance *dev, if (deps[i].drvdata != NULL) there++; } - return (there == EMAC_DEP_COUNT); + return there == EMAC_DEP_COUNT; } static void emac_put_deps(struct emac_instance *dev) diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 9e37e3d9c51d..4fec0844d59d 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -410,7 +410,7 @@ static inline u32 *emac_xaht_base(struct emac_instance *dev) else offset = offsetof(struct emac_regs, u0.emac4.iaht1); - return ((u32 *)((ptrdiff_t)p + offset)); + return (u32 *)((ptrdiff_t)p + offset); } static inline u32 *emac_gaht_base(struct emac_instance *dev) @@ -418,7 +418,7 @@ static inline u32 *emac_gaht_base(struct emac_instance *dev) /* GAHT registers always come after an identical number of * IAHT registers. */ - return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev)); + return emac_xaht_base(dev) + EMAC_XAHT_REGS(dev); } static inline u32 *emac_iaht_base(struct emac_instance *dev) @@ -426,7 +426,7 @@ static inline u32 *emac_iaht_base(struct emac_instance *dev) /* IAHT registers always come before an identical number of * GAHT registers. */ - return (emac_xaht_base(dev)); + return emac_xaht_base(dev); } /* Ethtool get_regs complex data. diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f915e9cb302e..0394ca95f3ba 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5435,7 +5435,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) tx_ring->total_packets += total_packets; tx_ring->tx_stats.bytes += total_bytes; tx_ring->tx_stats.packets += total_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } /** diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index 103b3aa1afc2..33add708bcbe 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -153,7 +153,7 @@ static int igbvf_set_rx_csum(struct net_device *netdev, u32 data) static u32 igbvf_get_tx_csum(struct net_device *netdev) { - return ((netdev->features & NETIF_F_IP_CSUM) != 0); + return (netdev->features & NETIF_F_IP_CSUM) != 0; } static int igbvf_set_tx_csum(struct net_device *netdev, u32 data) diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c7fab80d2490..265501348f33 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -845,7 +845,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) } adapter->net_stats.tx_bytes += total_bytes; adapter->net_stats.tx_packets += total_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } static irqreturn_t igbvf_msix_other(int irq, void *data) diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 48bd5ec9f29b..b626cccbccd1 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -217,7 +217,7 @@ toshoboe_checkfcs (unsigned char *buf, int len) for (i = 0; i < len; ++i) fcs.value = irda_fcs (fcs.value, *(buf++)); - return (fcs.value == GOOD_FCS); + return fcs.value == GOOD_FCS; } /***********************************************************************/ @@ -759,7 +759,7 @@ toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir) if (fir) { memset (buf, 0, TT_LEN); - return (TT_LEN); + return TT_LEN; } fcs.value = INIT_FCS; diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 4441fa3389c2..cce82f101f50 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1514,7 +1514,7 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", __func__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); + return (self->bulk_in_ep != 0) && (self->bulk_out_ep != 0); } #ifdef IU_DUMP_CLASS_DESC diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index e30cdbb14745..559fe854d76d 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -1348,7 +1348,7 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) outb(bank, iobase+BSR); /* Make sure interrupt handlers keep the proper interrupt mask */ - return(ier); + return ier; } /* diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 1b051dab7b29..39d6e6f15d4f 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -336,7 +336,7 @@ static int sirdev_is_receiving(struct sir_dev *dev) if (!atomic_read(&dev->enable_rx)) return 0; - return (dev->rx_buff.state != OUTSIDE_FRAME); + return dev->rx_buff.state != OUTSIDE_FRAME; } int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 850ca1c5ee19..8c57bfb5f098 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -2051,7 +2051,7 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) */ static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self) { - return (self->rx_buff.state != OUTSIDE_FRAME); + return self->rx_buff.state != OUTSIDE_FRAME; } diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index e5698fa30a4f..41c96b3d8152 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -219,7 +219,7 @@ static inline int read_reg(struct stir_cb *stir, __u16 reg, static inline int isfir(u32 speed) { - return (speed == 4000000); + return speed == 4000000; } /* diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h index 5a84822b5a43..c6f58482b769 100644 --- a/drivers/net/irda/via-ircc.h +++ b/drivers/net/irda/via-ircc.h @@ -238,7 +238,7 @@ static void WriteLPCReg(int iRegNum, unsigned char iVal) static __u8 ReadReg(unsigned int BaseAddr, int iRegNum) { - return ((__u8) inb(BaseAddr + iRegNum)); + return (__u8) inb(BaseAddr + iRegNum); } static void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal) diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index 3f24a1f33022..d66fab854bf1 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -595,7 +595,7 @@ struct ring_descr { static inline int rd_is_active(struct ring_descr *rd) { - return ((rd->hw->rd_status & RD_ACTIVE) != 0); + return (rd->hw->rd_status & RD_ACTIVE) != 0; } static inline void rd_activate(struct ring_descr *rd) diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 813993f9c65c..c982ab9f9005 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c @@ -296,12 +296,12 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw) eecd_reg = IXGB_READ_REG(hw, EECD); if (eecd_reg & IXGB_EECD_DO) - return (true); + return true; udelay(50); } ASSERT(0); - return (false); + return false; } /****************************************************************************** @@ -327,9 +327,9 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw *hw) checksum += ixgb_read_eeprom(hw, i); if (checksum == (u16) EEPROM_SUM) - return (true); + return true; else - return (false); + return false; } /****************************************************************************** @@ -439,7 +439,7 @@ ixgb_read_eeprom(struct ixgb_hw *hw, /* End this read operation */ ixgb_standby_eeprom(hw); - return (data); + return data; } /****************************************************************************** @@ -476,16 +476,16 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) /* clear the init_ctrl_reg_1 to signify that the cache is * invalidated */ ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); - return (false); + return false; } if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { pr_debug("Signature invalid\n"); - return(false); + return false; } - return(true); + return true; } /****************************************************************************** @@ -505,7 +505,7 @@ ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw) if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) == cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { - return (true); + return true; } else { return ixgb_get_eeprom_data(hw); } @@ -526,10 +526,10 @@ ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index) if ((index < IXGB_EEPROM_SIZE) && (ixgb_check_and_get_eeprom_data(hw) == true)) { - return(hw->eeprom[index]); + return hw->eeprom[index]; } - return(0); + return 0; } /****************************************************************************** @@ -570,10 +570,10 @@ u32 ixgb_get_ee_pba_number(struct ixgb_hw *hw) { if (ixgb_check_and_get_eeprom_data(hw) == true) - return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) - | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16)); + return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) + | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16); - return(0); + return 0; } @@ -591,8 +591,8 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if (ixgb_check_and_get_eeprom_data(hw) == true) - return (le16_to_cpu(ee_map->device_id)); + return le16_to_cpu(ee_map->device_id); - return (0); + return 0; } diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index a4ed96caae69..43994c199991 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -410,7 +410,7 @@ static int ixgb_get_eeprom_len(struct net_device *netdev) { /* return size in bytes */ - return (IXGB_EEPROM_SIZE << 1); + return IXGB_EEPROM_SIZE << 1; } static int diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index 397acabccab6..6cb2e42ff4c1 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -167,7 +167,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw) /* Clear any pending interrupt events. */ icr_reg = IXGB_READ_REG(hw, ICR); - return (ctrl_reg & IXGB_CTRL0_RST); + return ctrl_reg & IXGB_CTRL0_RST; } @@ -209,7 +209,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw) xpak_vendor = ixgb_xpak_vendor_infineon; } - return (xpak_vendor); + return xpak_vendor; } /****************************************************************************** @@ -273,7 +273,7 @@ ixgb_identify_phy(struct ixgb_hw *hw) if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID) phy_type = ixgb_phy_type_bcm; - return (phy_type); + return phy_type; } /****************************************************************************** @@ -366,7 +366,7 @@ ixgb_init_hw(struct ixgb_hw *hw) /* 82597EX errata: Call check-for-link in case lane deskew is locked */ ixgb_check_for_link(hw); - return (status); + return status; } /****************************************************************************** @@ -531,7 +531,7 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, } hash_value &= 0xFFF; - return (hash_value); + return hash_value; } /****************************************************************************** @@ -715,7 +715,7 @@ ixgb_setup_fc(struct ixgb_hw *hw) } IXGB_WRITE_REG(hw, FCRTH, hw->fc.high_water); } - return (status); + return status; } /****************************************************************************** @@ -1140,7 +1140,7 @@ mac_addr_valid(u8 *mac_addr) pr_debug("MAC address is all zeros\n"); is_valid = false; } - return (is_valid); + return is_valid; } /****************************************************************************** diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 25ef8b197373..d4ac94324fa0 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -401,7 +401,7 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, static u32 ixgbe_get_rx_csum(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - return (adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED); + return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; } static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) @@ -988,8 +988,8 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset) case ETH_SS_STATS: return IXGBE_STATS_LEN; case ETH_SS_NTUPLE_FILTERS: - return (ETHTOOL_MAX_NTUPLE_LIST_ENTRY * - ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY); + return ETHTOOL_MAX_NTUPLE_LIST_ENTRY * + ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY; default: return -EOPNOTSUPP; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0ec4ef2d819e..4e0ce91321dd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -826,7 +826,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_ring->total_packets += total_packets; tx_ring->stats.packets += total_packets; tx_ring->stats.bytes += total_bytes; - return (count < tx_ring->work_limit); + return count < tx_ring->work_limit; } #ifdef CONFIG_IXGBE_DCA diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 3eda1bdbbb7a..0866a1cf4d7b 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -311,7 +311,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, netdev->stats.tx_bytes += total_bytes; netdev->stats.tx_packets += total_packets; - return (count < tx_ring->work_limit); + return count < tx_ring->work_limit; } /** diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 874ee01e8d9d..8762dcb84e8b 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -494,7 +494,7 @@ static u32 temac_setoptions(struct net_device *ndev, u32 options) lp->options |= options; mutex_unlock(&lp->indirect_mutex); - return (0); + return 0; } /* Initialize temac */ diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 3df046a58b1d..3698824744cb 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -460,7 +460,7 @@ init_rx_bufs(struct net_device *dev, int num) { } lp->rbd_tail->next = rfd->rbd; #endif - return (i); + return i; } static inline void diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 42e3294671d7..60135aa55802 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -461,7 +461,7 @@ static int meth_tx_full(struct net_device *dev) { struct meth_private *priv = netdev_priv(dev); - return (priv->tx_count >= TX_RING_ENTRIES - 1); + return priv->tx_count >= TX_RING_ENTRIES - 1; } static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c index 43357d35616a..9c91a92da705 100644 --- a/drivers/net/mlx4/en_selftest.c +++ b/drivers/net/mlx4/en_selftest.c @@ -107,7 +107,7 @@ static int mlx4_en_test_loopback(struct mlx4_en_priv *priv) mlx4_en_test_loopback_exit: priv->validate_loopback = 0; - return (!loopback_ok); + return !loopback_ok; } diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 24ab8a43c777..4f3a3c0d6d08 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1555,12 +1555,12 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) * valid since MSI-X irqs are not shared */ if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) { napi_schedule(&ss->napi); - return (IRQ_HANDLED); + return IRQ_HANDLED; } /* make sure it is our IRQ, and that the DMA has finished */ if (unlikely(!stats->valid)) - return (IRQ_NONE); + return IRQ_NONE; /* low bit indicates receives are present, so schedule * napi poll handler */ @@ -1599,7 +1599,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) myri10ge_check_statblock(mgp); put_be32(htonl(3), ss->irq_claim + 1); - return (IRQ_HANDLED); + return IRQ_HANDLED; } static int diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 617f898ba5f0..4846e131a04e 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -735,7 +735,7 @@ static int myri_header(struct sk_buff *skb, struct net_device *dev, int i; for (i = 0; i < dev->addr_len; i++) eth->h_dest[i] = 0; - return(dev->hard_header_len); + return dev->hard_header_len; } if (daddr) { diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index cabae7bb1fc6..9b05e7da83de 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -346,7 +346,7 @@ static u32 netxen_decode_crb_addr(u32 addr) if (pci_base == NETXEN_ADDR_ERROR) return pci_base; else - return (pci_base + offset); + return pci_base + offset; } #define NETXEN_MAX_ROM_WAIT_USEC 100 @@ -1792,7 +1792,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) done = (sw_consumer == hw_consumer); spin_unlock(&adapter->tx_clean_lock); - return (done); + return done; } void diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 73d314592230..2c6ceeb592b3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -177,7 +177,7 @@ netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count) recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); - return (recv_ctx->sds_rings == NULL); + return recv_ctx->sds_rings == NULL; } static void diff --git a/drivers/net/niu.c b/drivers/net/niu.c index e36a83845a1c..4cd92421708d 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -283,7 +283,7 @@ static int niu_enable_interrupts(struct niu *np, int on) static u32 phy_encode(u32 type, int port) { - return (type << (port * 2)); + return type << (port * 2); } static u32 phy_decode(u32 val, int port) @@ -3043,8 +3043,7 @@ static int tcam_flush_all(struct niu *np) static u64 hash_addr_regval(unsigned long index, unsigned long num_entries) { - return ((u64)index | (num_entries == 1 ? - HASH_TBL_ADDR_AUTOINC : 0)); + return (u64)index | (num_entries == 1 ? HASH_TBL_ADDR_AUTOINC : 0); } #if 0 @@ -3276,7 +3275,7 @@ static u16 tcam_get_index(struct niu *np, u16 idx) /* One entry reserved for IP fragment rule */ if (idx >= (np->clas.tcam_sz - 1)) idx = 0; - return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports)); + return np->clas.tcam_top + ((idx+1) * np->parent->num_ports); } static u16 tcam_get_size(struct niu *np) @@ -3313,7 +3312,7 @@ static unsigned int niu_hash_rxaddr(struct rx_ring_info *rp, u64 a) a >>= PAGE_SHIFT; a ^= (a >> ilog2(MAX_RBR_RING_SIZE)); - return (a & (MAX_RBR_RING_SIZE - 1)); + return a & (MAX_RBR_RING_SIZE - 1); } static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr, @@ -7796,11 +7795,11 @@ static int niu_get_sset_count(struct net_device *dev, int stringset) if (stringset != ETH_SS_STATS) return -EINVAL; - return ((np->flags & NIU_FLAGS_XMAC ? + return (np->flags & NIU_FLAGS_XMAC ? NUM_XMAC_STAT_KEYS : NUM_BMAC_STAT_KEYS) + (np->num_rx_rings * NUM_RXCHAN_STAT_KEYS) + - (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS)); + (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS); } static void niu_get_ethtool_stats(struct net_device *dev, diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 89cf63bb8c91..c1d8ce9e4a6c 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -521,7 +521,7 @@ static int mace_read(mace_private *lp, unsigned int ioaddr, int reg) spin_unlock_irqrestore(&lp->bank_lock, flags); break; } - return (data & 0xFF); + return data & 0xFF; } /* mace_read */ /* ---------------------------------------------------------------------------- diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 3d1c549b7038..7204a4b5529b 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -815,7 +815,7 @@ static int check_sig(struct pcmcia_device *link) ((s >> 8) != (s & 0xff))) { SMC_SELECT_BANK(3); s = inw(ioaddr + REVISION); - return (s & 0xff); + return s & 0xff; } if (width) { diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index c200c2821730..aee3bb0358bf 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -376,7 +376,7 @@ static void pcnet32_wio_reset(unsigned long addr) static int pcnet32_wio_check(unsigned long addr) { outw(88, addr + PCNET32_WIO_RAP); - return (inw(addr + PCNET32_WIO_RAP) == 88); + return inw(addr + PCNET32_WIO_RAP) == 88; } static struct pcnet32_access pcnet32_wio = { @@ -431,7 +431,7 @@ static void pcnet32_dwio_reset(unsigned long addr) static int pcnet32_dwio_check(unsigned long addr) { outl(88, addr + PCNET32_DWIO_RAP); - return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88); + return (inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88; } static struct pcnet32_access pcnet32_dwio = { diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 43b8d7797f0a..4a624a29393f 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -85,12 +85,12 @@ static const int bitrate_list[] = { */ static inline int wpa2_capable(void) { - return (0 <= ps3_compare_firmware_version(2, 0, 0)); + return 0 <= ps3_compare_firmware_version(2, 0, 0); } static inline int precise_ie(void) { - return (0 <= ps3_compare_firmware_version(2, 2, 0)); + return 0 <= ps3_compare_firmware_version(2, 2, 0); } /* * post_eurus_cmd helpers @@ -506,7 +506,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf, start[1] = (buf - start - 2); pr_debug("%s: ->\n", __func__); - return (buf - start); + return buf - start; } struct ie_item { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 17124f6e0a93..a3d7705a2dda 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -172,7 +172,7 @@ qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); - return (recv_ctx->sds_rings == NULL); + return recv_ctx->sds_rings == NULL; } static void diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 845be71bef63..44f4d58a39a6 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -985,7 +985,7 @@ static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue) static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue, unsigned int index) { - return (&rx_queue->buffer[index]); + return &rx_queue->buffer[index]; } /* Set bit in a little-endian bitfield */ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index c4de0014441c..394dd929fee7 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -104,7 +104,7 @@ static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, static inline efx_qword_t *efx_event(struct efx_channel *channel, unsigned int index) { - return (((efx_qword_t *) (channel->eventq.addr)) + index); + return ((efx_qword_t *) (channel->eventq.addr)) + index; } /* See if an event is present @@ -119,8 +119,8 @@ static inline efx_qword_t *efx_event(struct efx_channel *channel, */ static inline int efx_event_present(efx_qword_t *event) { - return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | - EFX_DWORD_IS_ALL_ONES(event->dword[1]))); + return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | + EFX_DWORD_IS_ALL_ONES(event->dword[1])); } static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b, @@ -347,7 +347,7 @@ void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) static inline efx_qword_t * efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) { - return (((efx_qword_t *) (tx_queue->txd.addr)) + index); + return ((efx_qword_t *) (tx_queue->txd.addr)) + index; } /* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */ @@ -502,7 +502,7 @@ void efx_nic_remove_tx(struct efx_tx_queue *tx_queue) static inline efx_qword_t * efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index) { - return (((efx_qword_t *) (rx_queue->rxd.addr)) + index); + return ((efx_qword_t *) (rx_queue->rxd.addr)) + index; } /* This creates an entry in the RX descriptor queue */ diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index ffdd8591d4bc..581836867098 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -832,7 +832,7 @@ static u16 __devinit read_eeprom(long ioaddr, int location) outl(0, ee_addr); eeprom_delay(); - return (retval); + return retval; } /* Read and write the MII management registers using software-generated @@ -2247,9 +2247,9 @@ static inline u16 sis900_mcast_bitnr(u8 *addr, u8 revision) /* leave 8 or 7 most siginifant bits */ if ((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV)) - return ((int)(crc >> 24)); + return (int)(crc >> 24); else - return ((int)(crc >> 25)); + return (int)(crc >> 25); } /** diff --git a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c index 5310d39b5737..e395ace3120b 100644 --- a/drivers/net/skfp/cfm.c +++ b/drivers/net/skfp/cfm.c @@ -542,8 +542,8 @@ static void cfm_fsm(struct s_smc *smc, int cmd) */ int cfm_get_mac_input(struct s_smc *smc) { - return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || - smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ; + return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA; } /* @@ -553,8 +553,8 @@ int cfm_get_mac_input(struct s_smc *smc) */ int cfm_get_mac_output(struct s_smc *smc) { - return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || - smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ; + return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA; } static char path_iso[] = { @@ -623,5 +623,5 @@ int cem_build_path(struct s_smc *smc, char *to, int path_index) LINT_USE(path_index); - return(len) ; + return len; } diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c index c77cc14b3227..07da97c303d6 100644 --- a/drivers/net/skfp/drvfbi.c +++ b/drivers/net/skfp/drvfbi.c @@ -267,7 +267,7 @@ void timer_irq(struct s_smc *smc) int pcm_get_s_port(struct s_smc *smc) { SK_UNUSED(smc) ; - return(PS) ; + return PS; } /* @@ -366,7 +366,7 @@ void sm_pm_bypass_req(struct s_smc *smc, int mode) */ int sm_pm_bypass_present(struct s_smc *smc) { - return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ; + return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE; } void plc_clear_irq(struct s_smc *smc, int p) @@ -483,9 +483,9 @@ static int is_equal_num(char comp1[], char comp2[], int num) for (i = 0 ; i < num ; i++) { if (comp1[i] != comp2[i]) - return (0) ; + return 0; } - return (1) ; + return 1; } /* is_equal_num */ @@ -522,18 +522,18 @@ int set_oi_id_def(struct s_smc *smc) i++ ; break ; /* entry ok */ default: - return (1) ; /* invalid oi_status */ + return 1; /* invalid oi_status */ } } if (i == 0) - return (2) ; + return 2; if (!act_entries) - return (3) ; + return 3; /* ok, we have a valid OEM data base with an active entry */ smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ; - return (0) ; + return 0; } #endif /* MULT_OEM */ diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c index e8387d25f24a..8639a0884f5c 100644 --- a/drivers/net/skfp/ess.c +++ b/drivers/net/skfp/ess.c @@ -135,7 +135,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) { DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ; - return(fs) ; + return fs; } msg_res_type = ((struct smt_p_0015 *)p)->res_type ; @@ -147,7 +147,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * error in frame: para ESS command was not found */ DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0); - return(fs) ; + return fs; } DB_ESSN(2,"fc %x ft %x\n",sm->smt_class,sm->smt_type) ; @@ -175,12 +175,12 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * local and no static allocation is used */ if (!local || smc->mib.fddiESSPayload) - return(fs) ; + return fs; p = (void *) sm_to_para(smc,sm,SMT_P0019) ; for (i = 0; i < 5; i++) { if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) { - return(fs) ; + return fs; } } @@ -199,10 +199,10 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, sm->smt_dest = smt_sba_da ; if (smc->ess.local_sba_active) - return(fs | I_INDICATOR) ; + return fs | I_INDICATOR; if (!(db = smt_get_mbuf(smc))) - return(fs) ; + return fs; db->sm_len = mb->sm_len ; db->sm_off = mb->sm_off ; @@ -212,7 +212,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, (struct smt_header *)(db->sm_data+db->sm_off), "RAF") ; smt_send_frame(smc,db,FC_SMT_INFO,0) ; - return(fs) ; + return fs; } /* @@ -221,7 +221,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (smt_check_para(smc,sm,plist_raf_alc_res)) { DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -242,7 +242,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, (sm->smt_tid != smc->ess.alloc_trans_id)) { DB_ESS("ESS: Allocation Responce not accepted\n",0,0) ; - return(fs) ; + return fs; } /* @@ -268,7 +268,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ (void)process_bw_alloc(smc,(long)payload,(long)overhead) ; - return(fs) ; + return fs; /* end of Process Allocation Request */ /* @@ -280,7 +280,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (sm->smt_type != SMT_REQUEST) { DB_ESS("ESS: Do not process Change Responses\n",0,0) ; - return(fs) ; + return fs; } /* @@ -288,7 +288,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (smt_check_para(smc,sm,plist_raf_chg_req)) { DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -300,7 +300,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index != PRIMARY_RING) || (msg_res_type != SYNC_BW)) { DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -319,14 +319,14 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * process the bandwidth allocation */ if(!process_bw_alloc(smc,(long)payload,(long)overhead)) - return(fs) ; + return fs; /* * send an RAF Change Reply */ ess_send_response(smc,sm,CHANGE_ALLOCATION) ; - return(fs) ; + return fs; /* end of Process Change Request */ /* @@ -338,7 +338,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (sm->smt_type != SMT_REQUEST) { DB_ESS("ESS: Do not process a Report Reply\n",0,0) ; - return(fs) ; + return fs; } DB_ESSN(2,"ESS: Report Request from %s\n", @@ -349,7 +349,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (msg_res_type != SYNC_BW) { DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ; - return(fs) ; + return fs; } /* @@ -357,7 +357,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ ess_send_response(smc,sm,REPORT_ALLOCATION) ; - return(fs) ; + return fs; /* end of Process Report Request */ default: @@ -368,7 +368,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, break ; } - return(fs) ; + return fs; } /* @@ -418,17 +418,17 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe */ /* if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) { DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ; - return(FALSE) ; + return FALSE; } if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) { DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ; - return(FALSE) ; + return FALSE; } */ /* premliminary */ if (payload > MAX_PAYLOAD || overhead > 5000) { DB_ESS("ESS: payload / overhead not accepted\n",0,0) ; - return(FALSE) ; + return FALSE; } /* @@ -468,7 +468,7 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe ess_config_fifo(smc) ; set_formac_tsync(smc,smc->ess.sync_bw) ; - return(TRUE) ; + return TRUE; } static void ess_send_response(struct s_smc *smc, struct smt_header *sm, diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c index 9d8d1ac48176..ca4e7bb6a5a8 100644 --- a/drivers/net/skfp/fplustm.c +++ b/drivers/net/skfp/fplustm.c @@ -112,8 +112,8 @@ static u_long mac_get_tneg(struct s_smc *smc) u_long tneg ; tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ; - return((u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) | - 0xffe00000L)) ; + return (u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) | + 0xffe00000L) ; } void mac_update_counter(struct s_smc *smc) @@ -163,7 +163,7 @@ static u_long read_mdr(struct s_smc *smc, unsigned int addr) /* is used */ p = (u_long)inpw(FM_A(FM_MDRU))<<16 ; p += (u_long)inpw(FM_A(FM_MDRL)) ; - return(p) ; + return p; } #endif @@ -887,7 +887,7 @@ int init_fplus(struct s_smc *smc) /* make sure all PCI settings are correct */ mac_do_pci_fix(smc) ; - return(init_mac(smc,1)) ; + return init_mac(smc, 1); /* enable_formac(smc) ; */ } @@ -989,7 +989,7 @@ static int init_mac(struct s_smc *smc, int all) } smc->hw.hw_state = STARTED ; - return(0) ; + return 0; } @@ -1049,7 +1049,7 @@ void sm_ma_control(struct s_smc *smc, int mode) int sm_mac_get_tx_state(struct s_smc *smc) { - return((inpw(FM_A(FM_STMCHN))>>4)&7) ; + return (inpw(FM_A(FM_STMCHN))>>4) & 7; } /* @@ -1084,9 +1084,9 @@ static struct s_fpmc* mac_get_mc_table(struct s_smc *smc, } if (memcmp((char *)&tb->a,(char *)own,6)) continue ; - return(tb) ; + return tb; } - return(slot) ; /* return first free or NULL */ + return slot; /* return first free or NULL */ } /* @@ -1152,12 +1152,12 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) */ if (can & 0x80) { if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) { - return(1) ; + return 1; } } else { if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) { - return(1) ; + return 1; } } @@ -1165,7 +1165,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) * find empty slot */ if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80))) - return(1) ; + return 1; tb->n++ ; tb->a = own ; tb->perm = (can & 0x80) ? 1 : 0 ; @@ -1175,7 +1175,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) else smc->hw.fp.os_slots_used++ ; - return(0) ; + return 0; } /* diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c index d322f1b702ac..af5a755e269d 100644 --- a/drivers/net/skfp/hwmtm.c +++ b/drivers/net/skfp/hwmtm.c @@ -232,16 +232,16 @@ u_int mac_drv_check_space(void) #ifdef COMMON_MB_POOL call_count++ ; if (call_count == 1) { - return(EXT_VIRT_MEM) ; + return EXT_VIRT_MEM; } else { - return(EXT_VIRT_MEM_2) ; + return EXT_VIRT_MEM_2; } #else - return (EXT_VIRT_MEM) ; + return EXT_VIRT_MEM; #endif #else - return (0) ; + return 0; #endif } @@ -271,7 +271,7 @@ int mac_drv_init(struct s_smc *smc) if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *) mac_drv_get_desc_mem(smc,(u_int) (RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } /* @@ -283,18 +283,18 @@ int mac_drv_init(struct s_smc *smc) #ifndef COMMON_MB_POOL if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc, MAX_MBUF*sizeof(SMbuf)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } #else if (!mb_start) { if (!(mb_start = (SMbuf *) mac_drv_get_space(smc, MAX_MBUF*sizeof(SMbuf)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } } #endif #endif - return (0) ; + return 0; } /* @@ -349,7 +349,7 @@ static u_long init_descr_ring(struct s_smc *smc, DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ; d1++; } - return(phys) ; + return phys; } static void init_txd_ring(struct s_smc *smc) @@ -502,7 +502,7 @@ SMbuf *smt_get_mbuf(struct s_smc *smc) mb->sm_use_count = 1 ; } DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ; - return (mb) ; /* May be NULL */ + return mb; /* May be NULL */ } void smt_free_mbuf(struct s_smc *smc, SMbuf *mb) @@ -621,7 +621,7 @@ static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue) t = t->txd_next ; tx_used-- ; } - return(phys) ; + return phys; } /* @@ -673,7 +673,7 @@ static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue) r = r->rxd_next ; rx_used-- ; } - return(phys) ; + return phys; } @@ -1595,7 +1595,7 @@ int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len, } DB_TX("frame_status = %x",frame_status,0,3) ; NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ; - return(frame_status) ; + return frame_status; } /* @@ -1764,7 +1764,7 @@ static SMbuf *get_llc_rx(struct s_smc *smc) smc->os.hwm.llc_rx_pipe = mb->sm_next ; } DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ; - return(mb) ; + return mb; } /* @@ -1797,7 +1797,7 @@ static SMbuf *get_txd_mb(struct s_smc *smc) smc->os.hwm.txd_tx_pipe = mb->sm_next ; } DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ; - return(mb) ; + return mb; } /* diff --git a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c index 053151468f93..e6baa53307c7 100644 --- a/drivers/net/skfp/hwt.c +++ b/drivers/net/skfp/hwt.c @@ -179,7 +179,7 @@ u_long hwt_read(struct s_smc *smc) else smc->hw.t_stop = smc->hw.t_start - tr ; } - return (smc->hw.t_stop) ; + return smc->hw.t_stop; } #ifdef PCI @@ -208,7 +208,7 @@ u_long hwt_quick_read(struct s_smc *smc) outpw(ADDR(B2_TI_CRTL), TIM_START) ; outpd(ADDR(B2_TI_INI),interval) ; - return(time) ; + return time; } /************************ diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c index ba45bc794d77..112d35b1bf0e 100644 --- a/drivers/net/skfp/pcmplc.c +++ b/drivers/net/skfp/pcmplc.c @@ -504,7 +504,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy) #ifdef CONCENTRATOR if (!plc_is_installed(smc,phy)) - return(PC_QLS) ; + return PC_QLS; #endif state = inpw(PLC(phy,PL_STATUS_A)) & PL_LINE_ST ; @@ -528,7 +528,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy) default : state = PC_LS_NONE ; } - return(state) ; + return state; } static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) @@ -547,7 +547,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) #if 0 printf("PL_PCM_SIGNAL is set\n") ; #endif - return(1) ; + return 1; } /* write bit[n] & length = 1 to regs */ outpw(PLC(np,PL_VECTOR_LEN),len-1) ; /* len=nr-1 */ @@ -562,7 +562,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) printf("SIGNALING bit %d .. %d\n",phy->bitn,phy->bitn+len-1) ; #endif #endif - return(0) ; + return 0; } /* @@ -1590,12 +1590,12 @@ int pcm_status_twisted(struct s_smc *smc) { int twist = 0 ; if (smc->s.sas != SMT_DAS) - return(0) ; + return 0; if (smc->y[PA].twisted && (smc->y[PA].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 1 ; if (smc->y[PB].twisted && (smc->y[PB].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 2 ; - return(twist) ; + return twist; } /* @@ -1636,9 +1636,9 @@ int pcm_rooted_station(struct s_smc *smc) for (n = 0 ; n < NUMPHYS ; n++) { if (smc->y[n].mib->fddiPORTPCMState == PC8_ACTIVE && smc->y[n].mib->fddiPORTNeighborType == TM) - return(0) ; + return 0; } - return(1) ; + return 1; } /* @@ -1915,7 +1915,7 @@ int get_pcm_state(struct s_smc *smc, int np) case PL_PC9 : pcs = PC_MAINT ; break ; default : pcs = PC_DISABLE ; break ; } - return(pcs) ; + return pcs; } char *get_linestate(struct s_smc *smc, int np) @@ -1937,7 +1937,7 @@ char *get_linestate(struct s_smc *smc, int np) default: ls = "unknown" ; break ; #endif } - return(ls) ; + return ls; } char *get_pcmstate(struct s_smc *smc, int np) @@ -1959,7 +1959,7 @@ char *get_pcmstate(struct s_smc *smc, int np) case PL_PC9 : pcs = "MAINT" ; break ; default : pcs = "UNKNOWN" ; break ; } - return(pcs) ; + return pcs; } void list_phy(struct s_smc *smc) diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c index a320fdb3727d..9ac4665d7411 100644 --- a/drivers/net/skfp/pmf.c +++ b/drivers/net/skfp/pmf.c @@ -328,7 +328,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, * build SMT header */ if (!(mb = smt_get_mbuf(smc))) - return(mb) ; + return mb; smt = smtod(mb, struct smt_header *) ; smt->smt_dest = req->smt_source ; /* DA == source of request */ @@ -493,7 +493,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ; smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ; } - return(mb) ; + return mb; } static int smt_authorize(struct s_smc *smc, struct smt_header *sm) @@ -511,7 +511,7 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm) if (i != 8) { if (memcmp((char *) &sm->smt_sid, (char *) &smc->mib.fddiPRPMFStation,8)) - return(1) ; + return 1; } /* * check authoriziation parameter if passwd not zero @@ -522,13 +522,13 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm) if (i != 8) { pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ; if (!pa) - return(1) ; + return 1; if (pa->p_len != 8) - return(1) ; + return 1; if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8)) - return(1) ; + return 1; } - return(0) ; + return 0; } static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm) @@ -542,9 +542,9 @@ static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm) if ((smc->mib.fddiSMTSetCount.count != sc->count) || memcmp((char *) smc->mib.fddiSMTSetCount.timestamp, (char *)sc->timestamp,8)) - return(1) ; + return 1; } - return(0) ; + return 0; } void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, @@ -1109,7 +1109,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x2000 : if (mac < 0 || mac >= NUMMACS) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_m = &smc->mib.m[mac] ; mib_addr = (char *) mib_m ; @@ -1118,7 +1118,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x3000 : if (path < 0 || path >= NUMPATHS) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_a = &smc->mib.a[path] ; mib_addr = (char *) mib_a ; @@ -1127,7 +1127,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x4000 : if (port < 0 || port >= smt_mib_phys(smc)) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_p = &smc->mib.p[port_to_mib(smc,port)] ; mib_addr = (char *) mib_p ; @@ -1151,22 +1151,20 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, case SMT_P10F9 : #endif case SMT_P20F1 : - if (!local) { - return(SMT_RDF_NOPARAM) ; - } + if (!local) + return SMT_RDF_NOPARAM; break ; } pt = smt_get_ptab(pa->p_type) ; - if (!pt) { - return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM : - SMT_RDF_ILLEGAL ) ; - } + if (!pt) + return (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM : + SMT_RDF_ILLEGAL; switch (pt->p_access) { case AC_GR : case AC_S : break ; default : - return(SMT_RDF_ILLEGAL) ; + return SMT_RDF_ILLEGAL; } to = mib_addr + pt->p_offset ; swap = pt->p_swap ; /* pointer to swap string */ @@ -1292,7 +1290,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; default : SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ; - return(SMT_RDF_ILLEGAL) ; + return SMT_RDF_ILLEGAL; } } /* @@ -1501,15 +1499,15 @@ change_mac_para: default : break ; } - return(0) ; + return 0; val_error: /* parameter value in frame is out of range */ - return(SMT_RDF_RANGE) ; + return SMT_RDF_RANGE; len_error: /* parameter value in frame is too short */ - return(SMT_RDF_LENGTH) ; + return SMT_RDF_LENGTH; #if 0 no_author_error: @@ -1518,7 +1516,7 @@ no_author_error: * because SBA denied is not a valid return code in the * PMF protocol. */ - return(SMT_RDF_AUTHOR) ; + return SMT_RDF_AUTHOR; #endif } @@ -1527,7 +1525,7 @@ static const struct s_p_tab *smt_get_ptab(u_short para) const struct s_p_tab *pt ; for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++) ; - return(pt->p_num ? pt : NULL) ; + return pt->p_num ? pt : NULL; } static int smt_mib_phys(struct s_smc *smc) @@ -1535,11 +1533,11 @@ static int smt_mib_phys(struct s_smc *smc) #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(NUMPHYS) ; + return NUMPHYS; #else if (smc->s.sas == SMT_SAS) - return(1) ; - return(NUMPHYS) ; + return 1; + return NUMPHYS; #endif } @@ -1548,11 +1546,11 @@ static int port_to_mib(struct s_smc *smc, int p) #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(p) ; + return p; #else if (smc->s.sas == SMT_SAS) - return(PS) ; - return(p) ; + return PS; + return p; #endif } diff --git a/drivers/net/skfp/queue.c b/drivers/net/skfp/queue.c index 09adb3d68b7c..c1a0df455a59 100644 --- a/drivers/net/skfp/queue.c +++ b/drivers/net/skfp/queue.c @@ -128,7 +128,7 @@ u_short smt_online(struct s_smc *smc, int on) { queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ; ev_dispatcher(smc) ; - return(smc->mib.fddiSMTCF_State) ; + return smc->mib.fddiSMTCF_State; } /* diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 8a12bd9d28ba..ba2e8339fe90 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -440,7 +440,7 @@ static int skfp_driver_init(struct net_device *dev) smt_reset_defaults(smc, 0); - return (0); + return 0; fail: if (bp->SharedMemAddr) { @@ -516,7 +516,7 @@ static int skfp_open(struct net_device *dev) mac_drv_rx_mode(smc, RX_DISABLE_PROMISC); netif_start_queue(dev); - return (0); + return 0; } // skfp_open @@ -565,7 +565,7 @@ static int skfp_close(struct net_device *dev) skb_queue_purge(&bp->SendSkbQueue); bp->QueueSkb = MAX_TX_QUEUE_LEN; - return (0); + return 0; } // skfp_close @@ -794,7 +794,7 @@ static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev) bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls; #endif - return ((struct net_device_stats *) &bp->os.MacStat); + return (struct net_device_stats *)&bp->os.MacStat; } // ctl_get_stat @@ -932,7 +932,7 @@ static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr) ResetAdapter(smc); spin_unlock_irqrestore(&bp->DriverLock, Flags); - return (0); /* always return zero */ + return 0; /* always return zero */ } // skfp_ctl_set_mac_address @@ -1313,7 +1313,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) { printk("Unexpected SMT memory size requested: %d\n", size); - return (NULL); + return NULL; } smc->os.SharedMemHeap += size; // Move heap pointer. @@ -1322,7 +1322,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) pr_debug("bus addr: %lx\n", (ulong) (smc->os.SharedMemDMA + ((char *) virt - (char *)smc->os.SharedMemAddr))); - return (virt); + return virt; } // mac_drv_get_space @@ -1363,9 +1363,9 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) if (!mac_drv_get_space(smc, size)) { printk("fddi: Unable to align descriptor memory.\n"); - return (NULL); + return NULL; } - return (virt + size); + return virt + size; } // mac_drv_get_desc_mem @@ -1384,8 +1384,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) ************************/ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) { - return (smc->os.SharedMemDMA + - ((char *) virt - (char *)smc->os.SharedMemAddr)); + return smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr); } // mac_drv_virt2phys @@ -1419,8 +1419,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) ************************/ u_long dma_master(struct s_smc * smc, void *virt, int len, int flag) { - return (smc->os.SharedMemDMA + - ((char *) virt - (char *)smc->os.SharedMemAddr)); + return smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr); } // dma_master @@ -1904,12 +1904,12 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc, pr_debug("fddi: Discard invalid local SMT frame\n"); pr_debug(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n", len, la_len, (unsigned long) look_ahead); - return (0); + return 0; } skb = alloc_skb(len + 3, GFP_ATOMIC); if (!skb) { pr_debug("fddi: Local SMT: skb memory exhausted.\n"); - return (0); + return 0; } skb_reserve(skb, 3); skb_put(skb, len); @@ -1919,7 +1919,7 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc, skb->protocol = fddi_type_trans(skb, smc->os.dev); netif_rx(skb); - return (0); + return 0; } // mac_drv_rx_init diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c index 6f35bb77595f..2d9941c045bc 100644 --- a/drivers/net/skfp/smt.c +++ b/drivers/net/skfp/smt.c @@ -127,22 +127,22 @@ static inline int is_my_addr(const struct s_smc *smc, static inline int is_broadcast(const struct fddi_addr *addr) { - return(*(u_short *)(&addr->a[0]) == 0xffff && + return *(u_short *)(&addr->a[0]) == 0xffff && *(u_short *)(&addr->a[2]) == 0xffff && - *(u_short *)(&addr->a[4]) == 0xffff ) ; + *(u_short *)(&addr->a[4]) == 0xffff; } static inline int is_individual(const struct fddi_addr *addr) { - return(!(addr->a[0] & GROUP_ADDR)) ; + return !(addr->a[0] & GROUP_ADDR); } static inline int is_equal(const struct fddi_addr *addr1, const struct fddi_addr *addr2) { - return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) && + return *(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) && *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) && - *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ; + *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]); } /* @@ -457,8 +457,8 @@ static int div_ratio(u_long upper, u_long lower) else upper <<= 16L ; if (!lower) - return(0) ; - return((int)(upper/lower)) ; + return 0; + return (int)(upper/lower) ; } #ifndef SLIM_SMT @@ -1111,11 +1111,11 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, #if 0 if (!smc->r.sm_ma_avail) { - return(0) ; + return 0; } #endif if (!(mb = smt_get_mbuf(smc))) - return(mb) ; + return mb; mb->sm_len = length ; smt = smtod(mb, struct smt_header *) ; @@ -1136,7 +1136,7 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */ smt->smt_pad = 0 ; smt->smt_len = length - sizeof(struct smt_header) ; - return(mb) ; + return mb; } static void smt_add_frame_len(SMbuf *mb, int len) @@ -1375,7 +1375,7 @@ static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path) pd_mac = (struct smt_mac_rec *) phy ; pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ; pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ; - return(len) ; + return len; } /* @@ -1563,7 +1563,7 @@ u_long smt_get_tid(struct s_smc *smc) u_long tid ; while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0) ; - return(tid & 0x3fffffffL) ; + return tid & 0x3fffffffL; } @@ -1654,11 +1654,11 @@ int smt_check_para(struct s_smc *smc, struct smt_header *sm, while (*p) { if (!sm_to_para(smc,sm,(int) *p)) { DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0); - return(-1) ; + return -1; } p++ ; } - return(0) ; + return 0; } void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para) @@ -1687,7 +1687,7 @@ void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para) return NULL; } if (found) - return(found) ; + return found; } return NULL; } @@ -1732,7 +1732,7 @@ char *addr_to_string(struct fddi_addr *addr) string[i * 3 + 2] = ':'; } string[5 * 3 + 2] = 0; - return(string); + return string; } #endif @@ -1742,9 +1742,9 @@ int smt_ifconfig(int argc, char *argv[]) if (argc >= 2 && !strcmp(argv[0],"opt_bypass") && !strcmp(argv[1],"yes")) { smc->mib.fddiSMTBypassPresent = 1 ; - return(0) ; + return 0; } - return(amdfddi_config(0,argc,argv)) ; + return amdfddi_config(0, argc, argv); } #endif @@ -1756,9 +1756,9 @@ static int mac_index(struct s_smc *smc, int mac) SK_UNUSED(mac) ; #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(NUMPHYS+1) ; + return NUMPHYS + 1; #else - return((smc->s.sas == SMT_SAS) ? 2 : 3) ; + return (smc->s.sas == SMT_SAS) ? 2 : 3; #endif } @@ -1768,7 +1768,7 @@ static int mac_index(struct s_smc *smc, int mac) static int phy_index(struct s_smc *smc, int phy) { SK_UNUSED(smc) ; - return(phy+1); + return phy + 1; } /* @@ -1779,19 +1779,19 @@ static int mac_con_resource_index(struct s_smc *smc, int mac) #ifdef CONCENTRATOR SK_UNUSED(smc) ; SK_UNUSED(mac) ; - return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ; + return entity_to_index(smc, cem_get_downstream(smc, ENTITY_MAC)); #else SK_UNUSED(mac) ; switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : case SC5_THRU_B : case SC11_C_WRAP_S : - return(1) ; + return 1; case SC10_C_WRAP_B : case SC4_THRU_A : - return(2) ; + return 2; } - return(smc->s.sas == SMT_SAS ? 2 : 3) ; + return smc->s.sas == SMT_SAS ? 2 : 3; #endif } @@ -1801,21 +1801,21 @@ static int mac_con_resource_index(struct s_smc *smc, int mac) static int phy_con_resource_index(struct s_smc *smc, int phy) { #ifdef CONCENTRATOR - return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ; + return entity_to_index(smc, cem_get_downstream(smc, ENTITY_PHY(phy))) ; #else switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : - return(phy == PA ? 3 : 2) ; + return phy == PA ? 3 : 2; case SC10_C_WRAP_B : - return(phy == PA ? 1 : 3) ; + return phy == PA ? 1 : 3; case SC4_THRU_A : - return(phy == PA ? 3 : 1) ; + return phy == PA ? 3 : 1; case SC5_THRU_B : - return(phy == PA ? 2 : 3) ; + return phy == PA ? 2 : 3; case SC11_C_WRAP_S : - return(2) ; + return 2; } - return(phy) ; + return phy; #endif } @@ -1823,16 +1823,16 @@ static int phy_con_resource_index(struct s_smc *smc, int phy) static int entity_to_index(struct s_smc *smc, int e) { if (e == ENTITY_MAC) - return(mac_index(smc,1)) ; + return mac_index(smc, 1); else - return(phy_index(smc,e - ENTITY_PHY(0))) ; + return phy_index(smc, e - ENTITY_PHY(0)); } #endif #ifdef LITTLE_ENDIAN static int smt_swap_short(u_short s) { - return(((s>>8)&0xff)|((s&0xff)<<8)) ; + return ((s>>8)&0xff) | ((s&0xff)<<8); } void smt_swap_para(struct smt_header *sm, int len, int direction) @@ -1996,7 +1996,7 @@ int smt_action(struct s_smc *smc, int class, int code, int index) } break ; default : - return(1) ; + return 1; } break ; case SMT_PORT_ACTION : @@ -2017,14 +2017,14 @@ int smt_action(struct s_smc *smc, int class, int code, int index) event = PC_STOP ; break ; default : - return(1) ; + return 1; } queue_event(smc,EVENT_PCM+index,event) ; break ; default : - return(1) ; + return 1; } - return(0) ; + return 0; } /* diff --git a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c index 4e07ff7073f1..1acab0b368e3 100644 --- a/drivers/net/skfp/smtdef.c +++ b/drivers/net/skfp/smtdef.c @@ -303,7 +303,7 @@ int smt_set_mac_opvalues(struct s_smc *smc) FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_T_REQ, smt_get_event_word(smc)); } - return(st) ; + return st; } void smt_fixup_mib(struct s_smc *smc) @@ -350,6 +350,6 @@ static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper) *oper = limit ; else *oper = mib ; - return(old != *oper) ; + return old != *oper; } diff --git a/drivers/net/skfp/smtinit.c b/drivers/net/skfp/smtinit.c index 3c8964ce1837..e3a0c0bc2233 100644 --- a/drivers/net/skfp/smtinit.c +++ b/drivers/net/skfp/smtinit.c @@ -120,6 +120,6 @@ int init_smt(struct s_smc *smc, u_char *mac_addr) PNMI_INIT(smc) ; /* PNMI initialization */ - return(0) ; + return 0; } diff --git a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c index 40882b3faba6..f6f7baf9f27a 100644 --- a/drivers/net/skfp/srf.c +++ b/drivers/net/skfp/srf.c @@ -165,7 +165,7 @@ static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index) for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) { if (evc->evc_code == code && evc->evc_index == index) - return(evc) ; + return evc; } return NULL; } diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 38547a8938fe..86cbb9ea2f26 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -944,7 +944,7 @@ static int slip_esc(unsigned char *s, unsigned char *d, int len) } } *ptr++ = END; - return (ptr - d); + return ptr - d; } static void slip_unesc(struct slip *sl, unsigned char s) diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 358c22f9acbe..7d9ec23aabf6 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -436,7 +436,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; - return( -EIO ); + return -EIO; } DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA; @@ -445,7 +445,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); - return( 0 ); + return 0; } diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index 4a4fac630337..d16880d7099b 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -88,7 +88,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) if ((val & BMCR_ISOLATE) && limit > 0) __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); - return (limit <= 0); + return limit <= 0; } static int bcm5201_init(struct mii_phy* phy) diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 45f315ed1868..5e28c414421a 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2497,7 +2497,7 @@ static u32 hme_get_link(struct net_device *dev) hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); spin_unlock_irq(&hp->happy_lock); - return (hp->sw_bmsr & BMSR_LSTATUS); + return hp->sw_bmsr & BMSR_LSTATUS; } static const struct ethtool_ops hme_ethtool_ops = { diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 72e65d4666ef..9536b2f010be 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -711,7 +711,7 @@ static u32 qe_get_link(struct net_device *dev) phyconfig = sbus_readb(mregs + MREGS_PHYCONFIG); spin_unlock_irq(&qep->lock); - return (phyconfig & MREGS_PHYCONFIG_LSTAT); + return phyconfig & MREGS_PHYCONFIG_LSTAT; } static const struct ethtool_ops qe_ethtool_ops = { diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 99e423a5b9f1..b6eec8cea209 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -1167,7 +1167,7 @@ static void print_eth(const u8 *add) static int tc35815_tx_full(struct net_device *dev) { struct tc35815_local *lp = netdev_priv(dev); - return ((lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end); + return (lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end; } static void tc35815_restart(struct net_device *dev) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e7a2ba8b20a2..fdb438dca9b3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5389,8 +5389,7 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) { u32 base = (u32) mapping & 0xffffffff; - return ((base > 0xffffdcc0) && - (base + len + 8 < base)); + return (base > 0xffffdcc0) && (base + len + 8 < base); } /* Test for DMA addresses > 40-bit */ @@ -5399,7 +5398,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, { #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) - return (((u64) mapping + len) > DMA_BIT_MASK(40)); + return ((u64) mapping + len) > DMA_BIT_MASK(40); return 0; #else return 0; diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 0564ca05963d..ec8c804a795d 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -3187,7 +3187,7 @@ static int TLan_EeSendByte( u16 io_base, u8 data, int stop ) TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); } - return ( err ); + return err; } /* TLan_EeSendByte */ diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index d13ff12d7500..3315ced774e2 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -442,7 +442,7 @@ typedef struct tlan_private_tag { static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3))); + return inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)); } /* TLan_DioRead8 */ @@ -452,7 +452,7 @@ static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2))); + return inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)); } /* TLan_DioRead16 */ @@ -462,7 +462,7 @@ static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inl(base_addr + TLAN_DIO_DATA)); + return inl(base_addr + TLAN_DIO_DATA); } /* TLan_DioRead32 */ @@ -537,6 +537,6 @@ static inline u32 TLan_HashFunc( const u8 *a ) hash ^= ((a[2]^a[5])<<4); /* & 060 */ hash ^= ((a[2]^a[5])>>2); /* & 077 */ - return (hash & 077); + return hash & 077; } #endif diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 16e8783ee9cd..8d362e64a40e 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -110,7 +110,7 @@ static int __init proteon_probe1(struct net_device *dev, int ioaddr) } dev->base_addr = ioaddr; - return (0); + return 0; nodev: release_region(ioaddr, PROTEON_IO_EXTENT); return -ENODEV; diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 0929fff5982c..63db5a6762ae 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -435,7 +435,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev) RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - return (0); + return 0; } /* Enter Bypass state. */ @@ -448,7 +448,7 @@ static int smctr_bypass_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); - return (err); + return err; } static int smctr_checksum_firmware(struct net_device *dev) @@ -471,9 +471,9 @@ static int smctr_checksum_firmware(struct net_device *dev) smctr_disable_adapter_ctrl_store(dev); if(checksum) - return (checksum); + return checksum; - return (0); + return 0; } static int __init smctr_chk_mca(struct net_device *dev) @@ -485,7 +485,7 @@ static int __init smctr_chk_mca(struct net_device *dev) current_slot = mca_find_unused_adapter(smctr_posid, 0); if(current_slot == MCA_NOTFOUND) - return (-ENODEV); + return -ENODEV; mca_set_adapter_name(current_slot, smctr_name); mca_mark_as_used(current_slot); @@ -622,9 +622,9 @@ static int __init smctr_chk_mca(struct net_device *dev) break; } - return (0); + return 0; #else - return (-1); + return -1; #endif /* CONFIG_MCA_LEGACY */ } @@ -677,18 +677,18 @@ static int smctr_chg_rx_mask(struct net_device *dev) if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, &tp->config_word0))) { - return (err); + return err; } if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, &tp->config_word1))) { - return (err); + return err; } smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_clear_int(struct net_device *dev) @@ -697,7 +697,7 @@ static int smctr_clear_int(struct net_device *dev) outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); - return (0); + return 0; } static int smctr_clear_trc_reset(int ioaddr) @@ -707,7 +707,7 @@ static int smctr_clear_trc_reset(int ioaddr) r = inb(ioaddr + MSR); outb(~MSR_RST & r, ioaddr + MSR); - return (0); + return 0; } /* @@ -725,7 +725,7 @@ static int smctr_close(struct net_device *dev) /* Check to see if adapter is already in a closed state. */ if(tp->status != OPEN) - return (0); + return 0; smctr_enable_16bit(dev); smctr_set_page(dev, (__u8 *)tp->ram_access); @@ -733,7 +733,7 @@ static int smctr_close(struct net_device *dev) if((err = smctr_issue_remove_cmd(dev))) { smctr_disable_16bit(dev); - return (err); + return err; } for(;;) @@ -746,7 +746,7 @@ static int smctr_close(struct net_device *dev) } - return (0); + return 0; } static int smctr_decode_firmware(struct net_device *dev, @@ -807,12 +807,12 @@ static int smctr_decode_firmware(struct net_device *dev, if(buff) *(mem++) = SWAP_BYTES(buff); - return (0); + return 0; } static int smctr_disable_16bit(struct net_device *dev) { - return (0); + return 0; } /* @@ -832,7 +832,7 @@ static int smctr_disable_adapter_ctrl_store(struct net_device *dev) tp->trc_mask |= CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_disable_bic_int(struct net_device *dev) @@ -844,7 +844,7 @@ static int smctr_disable_bic_int(struct net_device *dev) | CSR_MSKTINT | CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_enable_16bit(struct net_device *dev) @@ -858,7 +858,7 @@ static int smctr_enable_16bit(struct net_device *dev) outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); } - return (0); + return 0; } /* @@ -881,7 +881,7 @@ static int smctr_enable_adapter_ctrl_store(struct net_device *dev) tp->trc_mask &= ~CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_enable_adapter_ram(struct net_device *dev) @@ -895,7 +895,7 @@ static int smctr_enable_adapter_ram(struct net_device *dev) r = inb(ioaddr + MSR); outb(MSR_MEMB | r, ioaddr + MSR); - return (0); + return 0; } static int smctr_enable_bic_int(struct net_device *dev) @@ -921,7 +921,7 @@ static int smctr_enable_bic_int(struct net_device *dev) break; } - return (0); + return 0; } static int __init smctr_chk_isa(struct net_device *dev) @@ -1145,7 +1145,7 @@ static int __init smctr_chk_isa(struct net_device *dev) */ } - return (0); + return 0; out2: release_region(ioaddr, SMCTR_IO_EXTENT); @@ -1199,7 +1199,7 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca) * return; */ if(IdByte & 0xF8) - return (-1); + return -1; r1 = inb(ioaddr + BID_REG_1); r1 &= BID_ICR_MASK; @@ -1250,21 +1250,21 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca) while(r1 & BID_RECALL_DONE_MASK) r1 = inb(ioaddr + BID_REG_1); - return (BoardIdMask); + return BoardIdMask; } static int smctr_get_group_address(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static int smctr_get_functional_address(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } /* Calculate number of Non-MAC receive BDB's and data buffers. @@ -1346,14 +1346,14 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) */ mem_used += 0x100; - return((0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock))); + return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)); } static int smctr_get_physical_drop_number(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) @@ -1366,14 +1366,14 @@ static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) tp->rx_fcb_curr[queue]->bdb_ptr = bdb; - return ((__u8 *)bdb->data_block_ptr); + return (__u8 *)bdb->data_block_ptr; } static int smctr_get_station_id(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } /* @@ -1384,7 +1384,7 @@ static struct net_device_stats *smctr_get_stats(struct net_device *dev) { struct net_local *tp = netdev_priv(dev); - return ((struct net_device_stats *)&tp->MacStat); + return (struct net_device_stats *)&tp->MacStat; } static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, @@ -1401,14 +1401,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, /* check if there is enough FCB blocks */ if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); /* round off the input pkt size to the nearest even number */ alloc_size = (bytes_count + 1) & 0xfffe; /* check if enough mem */ if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); /* check if past the end ; * if exactly enough mem to end of ring, alloc from front. @@ -1425,7 +1425,7 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) { - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); } /* ring wrap */ @@ -1448,14 +1448,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, pFCB = tp->tx_fcb_curr[queue]; tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; - return (pFCB); + return pFCB; } static int smctr_get_upstream_neighbor_addr(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static int smctr_hardware_send_packet(struct net_device *dev, @@ -1469,21 +1469,22 @@ static int smctr_hardware_send_packet(struct net_device *dev, printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); if(tp->status != OPEN) - return (-1); + return -1; if(tp->monitor_state_ready != 1) - return (-1); + return -1; for(;;) { /* Send first buffer from queue */ skb = skb_dequeue(&tp->SendSkbQueue); if(skb == NULL) - return (-1); + return -1; tp->QueueSkb++; - if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) return (-1); + if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) + return -1; smctr_enable_16bit(dev); smctr_set_page(dev, (__u8 *)tp->ram_access); @@ -1492,7 +1493,7 @@ static int smctr_hardware_send_packet(struct net_device *dev, == (FCBlock *)(-1L)) { smctr_disable_16bit(dev); - return (-1); + return -1; } smctr_tx_move_frame(dev, skb, @@ -1508,7 +1509,7 @@ static int smctr_hardware_send_packet(struct net_device *dev, smctr_disable_16bit(dev); } - return (0); + return 0; } static int smctr_init_acbs(struct net_device *dev) @@ -1552,7 +1553,7 @@ static int smctr_init_acbs(struct net_device *dev) tp->acb_curr = tp->acb_head->next_ptr; tp->num_acbs_used = 0; - return (0); + return 0; } static int smctr_init_adapter(struct net_device *dev) @@ -1590,13 +1591,14 @@ static int smctr_init_adapter(struct net_device *dev) if(smctr_checksum_firmware(dev)) { - printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT); + printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); + return -ENOENT; } if((err = smctr_ram_memory_test(dev))) { printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); - return (-EIO); + return -EIO; } smctr_set_rx_look_ahead(dev); @@ -1608,7 +1610,7 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Initialization of card failed (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } /* This routine clobbers the TRC's internal registers. */ @@ -1616,7 +1618,7 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Card failed internal self test (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } /* Re-Initialize adapter's internal registers */ @@ -1625,17 +1627,17 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Initialization of card failed (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } smctr_enable_bic_int(dev); if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return (err); + return err; smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_init_card_real(struct net_device *dev) @@ -1703,15 +1705,15 @@ static int smctr_init_card_real(struct net_device *dev) smctr_init_shared_memory(dev); if((err = smctr_issue_init_timers_cmd(dev))) - return (err); + return err; if((err = smctr_issue_init_txrx_cmd(dev))) { printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return (err); + return err; } - return (0); + return 0; } static int smctr_init_rx_bdbs(struct net_device *dev) @@ -1763,7 +1765,7 @@ static int smctr_init_rx_bdbs(struct net_device *dev) tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; } - return (0); + return 0; } static int smctr_init_rx_fcbs(struct net_device *dev) @@ -1813,7 +1815,7 @@ static int smctr_init_rx_fcbs(struct net_device *dev) tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; } - return(0); + return 0; } static int smctr_init_shared_memory(struct net_device *dev) @@ -1871,7 +1873,7 @@ static int smctr_init_shared_memory(struct net_device *dev) smctr_init_rx_bdbs(dev); smctr_init_rx_fcbs(dev); - return (0); + return 0; } static int smctr_init_tx_bdbs(struct net_device *dev) @@ -1901,7 +1903,7 @@ static int smctr_init_tx_bdbs(struct net_device *dev) tp->tx_bdb_head[i]->back_ptr = bdb; } - return (0); + return 0; } static int smctr_init_tx_fcbs(struct net_device *dev) @@ -1940,7 +1942,7 @@ static int smctr_init_tx_fcbs(struct net_device *dev) tp->num_tx_fcbs_used[i] = 0; } - return (0); + return 0; } static int smctr_internal_self_test(struct net_device *dev) @@ -1949,33 +1951,33 @@ static int smctr_internal_self_test(struct net_device *dev) int err; if((err = smctr_issue_test_internal_rom_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; if((err = smctr_issue_test_hic_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; if((err = smctr_issue_test_mac_reg_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; - return (0); + return 0; } /* @@ -2468,14 +2470,14 @@ static int smctr_issue_enable_int_cmd(struct net_device *dev, int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->int_mask_control = interrupt_enable_mask; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) @@ -2483,7 +2485,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib struct net_local *tp = netdev_priv(dev); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; tp->sclb_ptr->int_mask_control = ibits; tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; @@ -2491,7 +2493,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_init_timers_cmd(struct net_device *dev) @@ -2502,10 +2504,10 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev) __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; tp->config_word1 = 0; @@ -2648,7 +2650,7 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev) err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); - return (err); + return err; } static int smctr_issue_init_txrx_cmd(struct net_device *dev) @@ -2659,12 +2661,12 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev) void **txrx_ptrs = (void *)tp->misc_command_data; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) { printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return (err); + return err; } /* Initialize Transmit Queue Pointers that are used, to point to @@ -2695,7 +2697,7 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev) err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); - return (err); + return err; } static int smctr_issue_insert_cmd(struct net_device *dev) @@ -2704,7 +2706,7 @@ static int smctr_issue_insert_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); - return (err); + return err; } static int smctr_issue_read_ring_status_cmd(struct net_device *dev) @@ -2712,15 +2714,15 @@ static int smctr_issue_read_ring_status_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, RW_TRC_STATUS_BLOCK); - return (err); + return err; } static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) @@ -2728,15 +2730,15 @@ static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, aword_cnt); - return (err); + return err; } static int smctr_issue_remove_cmd(struct net_device *dev) @@ -2745,14 +2747,14 @@ static int smctr_issue_remove_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->resume_control = 0; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_acb_cmd(struct net_device *dev) @@ -2761,7 +2763,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->resume_control = SCLB_RC_ACB; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; @@ -2770,7 +2772,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) @@ -2779,7 +2781,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if(queue == MAC_QUEUE) tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; @@ -2790,7 +2792,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) @@ -2801,7 +2803,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; if(queue == MAC_QUEUE) tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; @@ -2812,7 +2814,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) @@ -2823,14 +2825,14 @@ static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) @@ -2840,7 +2842,7 @@ static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_INTERNAL_ROM_TEST); - return (err); + return err; } static int smctr_issue_test_hic_cmd(struct net_device *dev) @@ -2850,7 +2852,7 @@ static int smctr_issue_test_hic_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, TRC_HOST_INTERFACE_REG_TEST); - return (err); + return err; } static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) @@ -2860,7 +2862,7 @@ static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_MAC_REGISTERS_TEST); - return (err); + return err; } static int smctr_issue_trc_loopback_cmd(struct net_device *dev) @@ -2870,7 +2872,7 @@ static int smctr_issue_trc_loopback_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_INTERNAL_LOOPBACK); - return (err); + return err; } static int smctr_issue_tri_loopback_cmd(struct net_device *dev) @@ -2880,7 +2882,7 @@ static int smctr_issue_tri_loopback_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_TRI_LOOPBACK); - return (err); + return err; } static int smctr_issue_write_byte_cmd(struct net_device *dev, @@ -2891,10 +2893,10 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev, int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); iword++, ibyte += 2) @@ -2903,8 +2905,8 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev, | (*((__u8 *)byte + ibyte + 1)); } - return (smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, - aword_cnt)); + return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, + aword_cnt); } static int smctr_issue_write_word_cmd(struct net_device *dev, @@ -2914,10 +2916,10 @@ static int smctr_issue_write_word_cmd(struct net_device *dev, unsigned int i, err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) tp->misc_command_data[i] = *((__u16 *)word + i); @@ -2925,7 +2927,7 @@ static int smctr_issue_write_word_cmd(struct net_device *dev, err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, aword_cnt); - return (err); + return err; } static int smctr_join_complete_state(struct net_device *dev) @@ -2935,7 +2937,7 @@ static int smctr_join_complete_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_JOIN_COMPLETE_STATE); - return (err); + return err; } static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) @@ -2959,7 +2961,7 @@ static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) } } - return (0); + return 0; } static int smctr_load_firmware(struct net_device *dev) @@ -2974,7 +2976,7 @@ static int smctr_load_firmware(struct net_device *dev) if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { printk(KERN_ERR "%s: firmware not found\n", dev->name); - return (UCODE_NOT_PRESENT); + return UCODE_NOT_PRESENT; } tp->num_of_tx_buffs = 4; @@ -3036,7 +3038,7 @@ static int smctr_load_firmware(struct net_device *dev) smctr_disable_16bit(dev); out: release_firmware(fw); - return (err); + return err; } static int smctr_load_node_addr(struct net_device *dev) @@ -3052,7 +3054,7 @@ static int smctr_load_node_addr(struct net_device *dev) } dev->addr_len = 6; - return (0); + return 0; } /* Lobe Media Test. @@ -3146,14 +3148,14 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev) if(smctr_wait_cmd(dev)) { printk(KERN_ERR "Lobe Failed test state\n"); - return (LOBE_MEDIA_TEST_FAILED); + return LOBE_MEDIA_TEST_FAILED; } } err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_LOBE_MEDIA_TEST); - return (err); + return err; } static int smctr_lobe_media_test_state(struct net_device *dev) @@ -3163,7 +3165,7 @@ static int smctr_lobe_media_test_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_LOBE_TEST_STATE); - return (err); + return err; } static int smctr_make_8025_hdr(struct net_device *dev, @@ -3212,7 +3214,7 @@ static int smctr_make_8025_hdr(struct net_device *dev, break; } - return (0); + return 0; } static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3225,7 +3227,7 @@ static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[0] = MSB(tp->authorized_access_priority); tsv->svv[1] = LSB(tp->authorized_access_priority); - return (0); + return 0; } static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3236,7 +3238,7 @@ static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[0] = 0; tsv->svv[1] = 0; - return (0); + return 0; } static int smctr_make_auth_funct_class(struct net_device *dev, @@ -3250,7 +3252,7 @@ static int smctr_make_auth_funct_class(struct net_device *dev, tsv->svv[0] = MSB(tp->authorized_function_classes); tsv->svv[1] = LSB(tp->authorized_function_classes); - return (0); + return 0; } static int smctr_make_corr(struct net_device *dev, @@ -3262,7 +3264,7 @@ static int smctr_make_corr(struct net_device *dev, tsv->svv[0] = MSB(correlator); tsv->svv[1] = LSB(correlator); - return (0); + return 0; } static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3280,7 +3282,7 @@ static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[2] = MSB(tp->misc_command_data[1]); tsv->svv[3] = LSB(tp->misc_command_data[1]); - return (0); + return 0; } static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3305,7 +3307,7 @@ static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) tsv->svv[0] = 0x00; - return (0); + return 0; } static int smctr_make_phy_drop_num(struct net_device *dev, @@ -3324,7 +3326,7 @@ static int smctr_make_phy_drop_num(struct net_device *dev, tsv->svv[2] = MSB(tp->misc_command_data[1]); tsv->svv[3] = LSB(tp->misc_command_data[1]); - return (0); + return 0; } static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3337,7 +3339,7 @@ static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) for(i = 0; i < 18; i++) tsv->svv[i] = 0xF0; - return (0); + return 0; } static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3358,7 +3360,7 @@ static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[4] = MSB(tp->misc_command_data[2]); tsv->svv[5] = LSB(tp->misc_command_data[2]); - return (0); + return 0; } static int smctr_make_ring_station_status(struct net_device *dev, @@ -3374,7 +3376,7 @@ static int smctr_make_ring_station_status(struct net_device *dev, tsv->svv[4] = 0; tsv->svv[5] = 0; - return (0); + return 0; } static int smctr_make_ring_station_version(struct net_device *dev, @@ -3400,7 +3402,7 @@ static int smctr_make_ring_station_version(struct net_device *dev, else tsv->svv[9] = 0xc4; /* EBCDIC - D */ - return (0); + return 0; } static int smctr_make_tx_status_code(struct net_device *dev, @@ -3414,7 +3416,7 @@ static int smctr_make_tx_status_code(struct net_device *dev, /* Stripped frame status of Transmitted Frame */ tsv->svv[1] = tx_fstatus & 0xff; - return (0); + return 0; } static int smctr_make_upstream_neighbor_addr(struct net_device *dev, @@ -3436,7 +3438,7 @@ static int smctr_make_upstream_neighbor_addr(struct net_device *dev, tsv->svv[4] = MSB(tp->misc_command_data[2]); tsv->svv[5] = LSB(tp->misc_command_data[2]); - return (0); + return 0; } static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3444,7 +3446,7 @@ static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svi = WRAP_DATA; tsv->svl = S_WRAP_DATA; - return (0); + return 0; } /* @@ -3464,9 +3466,9 @@ static int smctr_open(struct net_device *dev) err = smctr_init_adapter(dev); if(err < 0) - return (err); + return err; - return (err); + return err; } /* Interrupt driven open of Token card. */ @@ -3481,9 +3483,9 @@ static int smctr_open_tr(struct net_device *dev) /* Now we can actually open the adapter. */ if(tp->status == OPEN) - return (0); + return 0; if(tp->status != INITIALIZED) - return (-1); + return -1; /* FIXME: it would work a lot better if we masked the irq sources on the card here, then we could skip the locking and poll nicely */ @@ -3560,7 +3562,7 @@ static int smctr_open_tr(struct net_device *dev) out: spin_unlock_irqrestore(&tp->lock, flags); - return (err); + return err; } /* Check for a network adapter of this type, @@ -3675,7 +3677,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr) dev->netdev_ops = &smctr_netdev_ops; dev->watchdog_timeo = HZ; - return (0); + return 0; out: return err; @@ -3699,13 +3701,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, case INIT: if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) { - return (rcode); + return rcode; } if((err = smctr_send_rsp(dev, rmf, rcode, correlator))) { - return (err); + return err; } break; @@ -3713,13 +3715,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, if((rcode = smctr_rcv_chg_param(dev, rmf, &correlator)) ==HARDWARE_FAILED) { - return (rcode); + return rcode; } if((err = smctr_send_rsp(dev, rmf, rcode, correlator))) { - return (err); + return err; } break; @@ -3728,16 +3730,16 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, - rcode, correlator)); + return smctr_send_rsp(dev, rmf, + rcode, correlator); } if((err = smctr_send_rpt_addr(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3746,17 +3748,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_rpt_attch(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3765,17 +3767,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_rpt_state(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3786,17 +3788,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_tx_forward(dev, rmf, &tx_fstatus)) == HARDWARE_FAILED) { - return (err); + return err; } if(err == A_FRAME_WAS_FORWARDED) @@ -3805,7 +3807,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, tx_fstatus)) == HARDWARE_FAILED) { - return (err); + return err; } } break; @@ -3834,7 +3836,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, if((err = smctr_send_rsp(dev, rmf,rcode, correlator))) { - return (err); + return err; } } @@ -3899,7 +3901,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, err = 0; } - return (err); + return err; } /* Adapter RAM test. Incremental word ODD boundary data test. */ @@ -3942,7 +3944,7 @@ static int smctr_ram_memory_test(struct net_device *dev) err_offset = j; err_word = word_read; err_pattern = word_pattern; - return (RAM_TEST_FAILED); + return RAM_TEST_FAILED; } } } @@ -3966,14 +3968,14 @@ static int smctr_ram_memory_test(struct net_device *dev) err_offset = j; err_word = word_read; err_pattern = word_pattern; - return (RAM_TEST_FAILED); + return RAM_TEST_FAILED; } } } smctr_set_page(dev, (__u8 *)tp->ram_access); - return (0); + return 0; } static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, @@ -3986,7 +3988,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, /* This Frame can only come from a CRS */ if((rmf->dc_sc & SC_MASK) != SC_CRS) - return(E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length. */ vlen = (signed short)rmf->vl - 4; @@ -4058,7 +4060,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, } } - return (rcode); + return rcode; } static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, @@ -4071,7 +4073,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, /* This Frame can only come from a RPS */ if((rmf->dc_sc & SC_MASK) != SC_RPS) - return (E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length. */ vlen = (signed short)rmf->vl - 4; @@ -4133,7 +4135,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, } } - return (rcode); + return rcode; } static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) @@ -4145,7 +4147,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) /* This Frame can only come from a CRS */ if((rmf->dc_sc & SC_MASK) != SC_CRS) - return (E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length */ vlen = (signed short)rmf->vl - 4; @@ -4193,7 +4195,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) } } - return (rcode); + return rcode; } static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, @@ -4250,7 +4252,7 @@ static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, } } - return (rcode); + return rcode; } static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, @@ -4284,7 +4286,7 @@ static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); } - return (E_UNRECOGNIZED_VECTOR_ID); + return E_UNRECOGNIZED_VECTOR_ID; } /* @@ -4311,7 +4313,7 @@ static int smctr_reset_adapter(struct net_device *dev) */ outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); - return (0); + return 0; } static int smctr_restart_tx_chain(struct net_device *dev, short queue) @@ -4329,7 +4331,7 @@ static int smctr_restart_tx_chain(struct net_device *dev, short queue) err = smctr_issue_resume_tx_fcb_cmd(dev, queue); } - return (err); + return err; } static int smctr_ring_status_chg(struct net_device *dev) @@ -4371,7 +4373,7 @@ static int smctr_ring_status_chg(struct net_device *dev) } if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) - return (0); + return 0; switch(tp->ring_status) { @@ -4421,7 +4423,7 @@ static int smctr_ring_status_chg(struct net_device *dev) break; } - return (0); + return 0; } static int smctr_rx_frame(struct net_device *dev) @@ -4486,7 +4488,7 @@ static int smctr_rx_frame(struct net_device *dev) break; } - return (err); + return err; } static int smctr_send_dat(struct net_device *dev) @@ -4502,7 +4504,7 @@ static int smctr_send_dat(struct net_device *dev) if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) { - return (OUT_OF_RESOURCES); + return OUT_OF_RESOURCES; } /* Initialize DAT Data Fields. */ @@ -4524,7 +4526,7 @@ static int smctr_send_dat(struct net_device *dev) /* Start Transmit. */ if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -4538,7 +4540,7 @@ static int smctr_send_dat(struct net_device *dev) if(!(fcb->frame_status & FCB_COMMAND_DONE) || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) { - return (INITIALIZE_FAILED); + return INITIALIZE_FAILED; } /* De-allocated Tx FCB and Frame Buffer @@ -4549,7 +4551,7 @@ static int smctr_send_dat(struct net_device *dev) tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - return (0); + return 0; } static void smctr_timeout(struct net_device *dev) @@ -4610,7 +4612,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) { - return (OUT_OF_RESOURCES); + return OUT_OF_RESOURCES; } /* Initialize DAT Data Fields. */ @@ -4639,7 +4641,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) /* Start Transmit. */ tmf->vl = SWAP_BYTES(tmf->vl); if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete. (10 ms). */ for(i=0; i < 10000; i++) @@ -4653,7 +4655,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) if(!(fcb->frame_status & FCB_COMMAND_DONE) || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) { - return (LOBE_MEDIA_TEST_FAILED); + return LOBE_MEDIA_TEST_FAILED; } /* De-allocated Tx FCB and Frame Buffer @@ -4664,7 +4666,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - return (0); + return 0; } static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, @@ -4679,7 +4681,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4722,7 +4724,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, @@ -4737,7 +4739,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4776,7 +4778,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, @@ -4791,7 +4793,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4826,7 +4828,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_tx_forward(struct net_device *dev, @@ -4839,7 +4841,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev, if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4862,7 +4864,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev, */ tmf->vl = SWAP_BYTES(tmf->vl); - return(smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, @@ -4875,7 +4877,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4888,7 +4890,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); smctr_make_corr(dev, tsv, correlator); - return (0); + return 0; } static int smctr_send_rq_init(struct net_device *dev) @@ -4907,7 +4909,7 @@ static int smctr_send_rq_init(struct net_device *dev) + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) == (FCBlock *)(-1L))) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4943,7 +4945,7 @@ static int smctr_send_rq_init(struct net_device *dev) tmf->vl = SWAP_BYTES(tmf->vl); if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -4957,7 +4959,7 @@ static int smctr_send_rq_init(struct net_device *dev) fstatus = fcb->frame_status; if(!(fstatus & FCB_COMMAND_DONE)) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; if(!(fstatus & FCB_TX_STATUS_E)) count++; @@ -4971,7 +4973,7 @@ static int smctr_send_rq_init(struct net_device *dev) smctr_update_tx_chain(dev, fcb, MAC_QUEUE); } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); - return (smctr_join_complete_state(dev)); + return smctr_join_complete_state(dev); } static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, @@ -4984,13 +4986,13 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, /* Check if this is the END POINT of the Transmit Forward Chain. */ if(rmf->vl <= 18) - return (0); + return 0; /* Allocate Transmit FCB only by requesting 0 bytes * of data buffer. */ if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) - return (0); + return 0; /* Set pointer to Transmit Frame Buffer to the data * portion of the received TX Forward frame, making @@ -5006,7 +5008,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -5020,7 +5022,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, if(!(fcb->frame_status & FCB_COMMAND_DONE)) { if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) - return (err); + return err; for(i = 0; i < 10000; i++) { @@ -5030,12 +5032,12 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, } if(!(fcb->frame_status & FCB_COMMAND_DONE)) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } *tx_fstatus = fcb->frame_status; - return (A_FRAME_WAS_FORWARDED); + return A_FRAME_WAS_FORWARDED; } static int smctr_set_auth_access_pri(struct net_device *dev, @@ -5044,11 +5046,11 @@ static int smctr_set_auth_access_pri(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_auth_funct_class(struct net_device *dev, @@ -5057,22 +5059,22 @@ static int smctr_set_auth_funct_class(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u16 *correlator) { if(rsv->svl != S_CORRELATOR) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_error_timer_value(struct net_device *dev, @@ -5082,34 +5084,34 @@ static int smctr_set_error_timer_value(struct net_device *dev, int err; if(rsv->svl != S_ERROR_TIMER_VALUE) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); if((err = smctr_wait_cmd(dev))) - return (err); + return err; - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_frame_forward(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u8 dc_sc) { if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; if((dc_sc & DC_MASK) != DC_CRS) { if(rsv->svl >= 2 && rsv->svl < 20) - return (E_TRANSMIT_FORWARD_INVALID); + return E_TRANSMIT_FORWARD_INVALID; if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) - return (E_TRANSMIT_FORWARD_INVALID); + return E_TRANSMIT_FORWARD_INVALID; } - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_local_ring_num(struct net_device *dev, @@ -5118,13 +5120,13 @@ static int smctr_set_local_ring_num(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_LOCAL_RING_NUMBER) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; if(tp->ptr_local_ring_num) *(__u16 *)(tp->ptr_local_ring_num) = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static unsigned short smctr_set_ctrl_attention(struct net_device *dev) @@ -5140,7 +5142,7 @@ static unsigned short smctr_set_ctrl_attention(struct net_device *dev) outb(tp->trc_mask, ioaddr + CSR); } - return (0); + return 0; } static void smctr_set_multicast_list(struct net_device *dev) @@ -5159,7 +5161,7 @@ static int smctr_set_page(struct net_device *dev, __u8 *buf) amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); outb(amask, dev->base_addr + PR); - return (0); + return 0; } static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) @@ -5167,13 +5169,13 @@ static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) int err; if(rsv->svl != S_PHYSICAL_DROP) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); if((err = smctr_wait_cmd(dev))) - return (err); + return err; - return (POSITIVE_ACK); + return POSITIVE_ACK; } /* Reset the ring speed to the opposite of what it was. This auto-pilot @@ -5195,16 +5197,16 @@ static int smctr_set_ring_speed(struct net_device *dev) smctr_reset_adapter(dev); if((err = smctr_init_card_real(dev))) - return (err); + return err; smctr_enable_bic_int(dev); if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return (err); + return err; smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_set_rx_look_ahead(struct net_device *dev) @@ -5233,7 +5235,7 @@ static int smctr_set_rx_look_ahead(struct net_device *dev) *((__u16 *)(tp->ram_access)) = sword; } - return (0); + return 0; } static int smctr_set_trc_reset(int ioaddr) @@ -5243,7 +5245,7 @@ static int smctr_set_trc_reset(int ioaddr) r = inb(ioaddr + MSR); outb(MSR_RST | r, ioaddr + MSR); - return (0); + return 0; } /* @@ -5259,10 +5261,10 @@ static int smctr_setup_single_cmd(struct net_device *dev, printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = (unsigned int)smctr_wait_cmd(dev))) - return (err); + return err; tp->acb_head->cmd_done_status = 0; tp->acb_head->cmd = command; @@ -5270,7 +5272,7 @@ static int smctr_setup_single_cmd(struct net_device *dev, err = smctr_issue_resume_acb_cmd(dev); - return (err); + return err; } /* @@ -5287,7 +5289,7 @@ static int smctr_setup_single_cmd_w_data(struct net_device *dev, tp->acb_head->data_offset_lo = (__u16)TRC_POINTER(tp->misc_command_data); - return(smctr_issue_resume_acb_cmd(dev)); + return smctr_issue_resume_acb_cmd(dev); } static char *smctr_malloc(struct net_device *dev, __u16 size) @@ -5298,7 +5300,7 @@ static char *smctr_malloc(struct net_device *dev, __u16 size) m = (char *)(tp->ram_access + tp->sh_mem_used); tp->sh_mem_used += (__u32)size; - return (m); + return m; } static int smctr_status_chg(struct net_device *dev) @@ -5333,7 +5335,7 @@ static int smctr_status_chg(struct net_device *dev) break; } - return (0); + return 0; } static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, @@ -5355,7 +5357,7 @@ static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, err = smctr_issue_resume_tx_fcb_cmd(dev, queue); } - return (err); + return err; } static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) @@ -5409,7 +5411,7 @@ static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) break; } - return (err); + return err; } static unsigned short smctr_tx_move_frame(struct net_device *dev, @@ -5450,7 +5452,7 @@ static unsigned short smctr_tx_move_frame(struct net_device *dev, pbuff += len; } - return (0); + return 0; } /* Update the error statistic counters for this adapter. */ @@ -5493,7 +5495,7 @@ static int smctr_update_err_stats(struct net_device *dev) if(tstat->token_errors) tstat->token_errors += *(tp->misc_command_data + 5) >> 8; - return (0); + return 0; } static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) @@ -5530,7 +5532,7 @@ static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; tp->rx_bdb_curr[queue] = bdb; - return (0); + return 0; } static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, @@ -5542,13 +5544,13 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, printk(KERN_DEBUG "smctr_update_tx_chain\n"); if(tp->num_tx_fcbs_used[queue] <= 0) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; else { if(tp->tx_buff_used[queue] < fcb->memory_alloc) { tp->tx_buff_used[queue] = 0; - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } tp->tx_buff_used[queue] -= fcb->memory_alloc; @@ -5566,7 +5568,7 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, fcb->frame_status = 0; tp->tx_fcb_end[queue] = fcb->next_ptr; netif_wake_queue(dev); - return (0); + return 0; } } @@ -5587,12 +5589,12 @@ static int smctr_wait_cmd(struct net_device *dev) } if(loop_count == 0) - return(HARDWARE_FAILED); + return HARDWARE_FAILED; if(tp->acb_head->cmd_done_status & 0xff) - return(HARDWARE_FAILED); + return HARDWARE_FAILED; - return (0); + return 0; } static int smctr_wait_while_cbusy(struct net_device *dev) @@ -5624,9 +5626,9 @@ static int smctr_wait_while_cbusy(struct net_device *dev) } if(timeout) - return (0); + return 0; else - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } #ifdef MODULE diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 08182fde3dcd..c83f4f6e39e1 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -224,7 +224,7 @@ static int madgemc_sifprobe(struct net_device *dev) chk2 ^= 0x0FE; if(chk1 != chk2) - return (-1); /* No adapter */ + return -1; /* No adapter */ chk1 -= 2; } while(chk1 != 0); /* Repeat 128 times (all byte values) */ @@ -232,7 +232,7 @@ static int madgemc_sifprobe(struct net_device *dev) /* Restore the SIFADR value */ SIFWRITEB(old, SIFADR); - return (0); + return 0; } #endif @@ -271,7 +271,7 @@ int tms380tr_open(struct net_device *dev) { printk(KERN_INFO "%s: Chipset initialization error\n", dev->name); - return (-1); + return -1; } tp->timer.expires = jiffies + 30*HZ; @@ -298,7 +298,7 @@ int tms380tr_open(struct net_device *dev) if(tp->AdapterVirtOpenFlag == 0) { tms380tr_disable_interrupts(dev); - return (-1); + return -1; } tp->StartTime = jiffies; @@ -309,7 +309,7 @@ int tms380tr_open(struct net_device *dev) tp->timer.data = (unsigned long)dev; add_timer(&tp->timer); - return (0); + return 0; } /* @@ -343,23 +343,23 @@ static int tms380tr_chipset_init(struct net_device *dev) printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name); err = tms380tr_reset_adapter(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name); err = tms380tr_bringup_diags(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Init adapter...\n", dev->name); err = tms380tr_init_adapter(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Done!\n", dev->name); - return (0); + return 0; } /* @@ -877,7 +877,7 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy IrqType != STS_IRQ_COMMAND_STATUS && IrqType != STS_IRQ_RING_STATUS) { - return (1); /* SSB not involved. */ + return 1; /* SSB not involved. */ } /* Note: All fields of the SSB have been set to all ones (-1) after it @@ -887,21 +887,21 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy */ if(ssb->STS == (unsigned short) -1) - return (0); /* Command field not yet available. */ + return 0; /* Command field not yet available. */ if(IrqType == STS_IRQ_COMMAND_STATUS) - return (1); /* Status fields not always affected. */ + return 1; /* Status fields not always affected. */ if(ssb->Parm[0] == (unsigned short) -1) - return (0); /* Status 1 field not yet available. */ + return 0; /* Status 1 field not yet available. */ if(IrqType == STS_IRQ_RING_STATUS) - return (1); /* Status 2 & 3 fields not affected. */ + return 1; /* Status 2 & 3 fields not affected. */ /* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */ if(ssb->Parm[1] == (unsigned short) -1) - return (0); /* Status 2 field not yet available. */ + return 0; /* Status 2 field not yet available. */ if(ssb->Parm[2] == (unsigned short) -1) - return (0); /* Status 3 field not yet available. */ + return 0; /* Status 3 field not yet available. */ - return (1); /* All SSB fields have been written by the adapter. */ + return 1; /* All SSB fields have been written by the adapter. */ } /* @@ -1143,7 +1143,7 @@ int tms380tr_close(struct net_device *dev) #endif tms380tr_cancel_tx_queue(tp); - return (0); + return 0; } /* @@ -1154,7 +1154,7 @@ static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) { struct net_local *tp = netdev_priv(dev); - return ((struct net_device_stats *)&tp->MacStat); + return (struct net_device_stats *)&tp->MacStat; } /* @@ -1256,7 +1256,7 @@ static int tms380tr_reset_adapter(struct net_device *dev) if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", dev->name, "tms380tr.bin"); - return (-1); + return -1; } fw_ptr = (unsigned short *)fw_entry->data; @@ -1322,13 +1322,13 @@ static int tms380tr_reset_adapter(struct net_device *dev) /* Clear CPHALT and start BUD */ SIFWRITEW(c, SIFACL); release_firmware(fw_entry); - return (1); + return 1; } } while(count == 0); release_firmware(fw_entry); printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); - return (-1); + return -1; } MODULE_FIRMWARE("tms380tr.bin"); @@ -1363,7 +1363,7 @@ static int tms380tr_bringup_diags(struct net_device *dev) printk(KERN_DEBUG " %04X\n", Status); /* BUD successfully completed */ if(Status == STS_INITIALIZE) - return (1); + return 1; /* Unrecoverable hardware error, BUD not completed? */ } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST)) != (STS_ERROR | STS_TEST))); @@ -1390,7 +1390,7 @@ static int tms380tr_bringup_diags(struct net_device *dev) else printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); - return (-1); + return -1; } /* @@ -1464,7 +1464,7 @@ static int tms380tr_init_adapter(struct net_device *dev) { printk(KERN_INFO "%s: DMA failed\n", dev->name); /* DMA data error: wrong data in SCB */ - return (-1); + return -1; } i++; } while(i < 6); @@ -1473,11 +1473,11 @@ static int tms380tr_init_adapter(struct net_device *dev) do { /* Test if contents of SSB is valid */ if(SSB_Test[i] != *(sb_ptr + i)) /* DMA data error: wrong data in SSB */ - return (-1); + return -1; i++; } while (i < 8); - return (1); /* Adapter successfully initialized */ + return 1; /* Adapter successfully initialized */ } else { @@ -1488,7 +1488,7 @@ static int tms380tr_init_adapter(struct net_device *dev) Status &= STS_ERROR_MASK; /* ShowInitialisationErrorCode(Status); */ printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status); - return (-1); /* Unrecoverable error */ + return -1; /* Unrecoverable error */ } else { @@ -1503,7 +1503,7 @@ static int tms380tr_init_adapter(struct net_device *dev) } while(retry_cnt > 0); printk(KERN_INFO "%s: Retry exceeded\n", dev->name); - return (-1); + return -1; } /* diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index a03730bd1da5..5c633a32eaeb 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -219,7 +219,7 @@ static int tsi108_read_mii(struct tsi108_prv_data *data, int reg) if (i == 100) return 0xffff; else - return (TSI_READ_PHY(TSI108_MAC_MII_DATAIN)); + return TSI_READ_PHY(TSI108_MAC_MII_DATAIN); } static void tsi108_write_mii(struct tsi108_prv_data *data, diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 1d9fef74b39b..251c6ce15aea 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -3119,7 +3119,7 @@ dc2114x_autoconf(struct net_device *dev) if (lp->media == _100Mb) { if ((slnk = test_for_100Mb(dev, 6500)) < 0) { lp->media = SPD_DET; - return (slnk & ~TIMER_CB); + return slnk & ~TIMER_CB; } } else { if (wait_for_link(dev) < 0) { @@ -3484,7 +3484,7 @@ is_spd_100(struct net_device *dev) spd = ((~gep_rd(dev)) & GEP_SLNK); } else { if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0; spd = (lp->asBitValid & (lp->asPolarity ^ (gep_rd(dev) & lp->asBit))) | (lp->linkOK & ~lp->asBitValid); @@ -3502,15 +3502,15 @@ is_100_up(struct net_device *dev) if (lp->useMII) { /* Double read for sticky bits & temporary drops */ mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS; } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_SLNK); + return (~gep_rd(dev)) & GEP_SLNK; } else { if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0; - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); + return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid); } } @@ -3523,17 +3523,17 @@ is_10_up(struct net_device *dev) if (lp->useMII) { /* Double read for sticky bits & temporary drops */ mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS; } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_LNP); + return (~gep_rd(dev)) & GEP_LNP; } else { if ((lp->ibn == 2) || !lp->asBitValid) - return (((lp->chipset & ~0x00ff) == DC2114x) ? + return ((lp->chipset & ~0x00ff) == DC2114x) ? (~inl(DE4X5_SISR)&SISR_LS10): - 0); + 0; - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); + return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid); } } @@ -3544,7 +3544,7 @@ is_anc_capable(struct net_device *dev) u_long iobase = dev->base_addr; if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII)); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); } else if ((lp->chipset & ~0x00ff) == DC2114x) { return (inl(DE4X5_SISR) & SISR_LPN) >> 12; } else { @@ -4930,7 +4930,7 @@ getfrom_mii(u32 command, u_long ioaddr) outl(command | MII_MDC, ioaddr); udelay(1); - return ((inl(ioaddr) >> 19) & 1); + return (inl(ioaddr) >> 19) & 1; } /* @@ -4975,8 +4975,8 @@ mii_get_oui(u_char phyaddr, u_long ioaddr) a.breg[0]=a.breg[1]; a.breg[1]=i; - return ((a.reg<<8)|ret); */ /* SEEQ and Cypress way */ -/* return ((r2<<6)|(u_int)(r3>>10)); */ /* NATIONAL and BROADCOM way */ + return (a.reg<<8)|ret; */ /* SEEQ and Cypress way */ +/* return (r2<<6)|(u_int)(r3>>10); */ /* NATIONAL and BROADCOM way */ return r2; /* (I did it) My way */ } @@ -5144,7 +5144,7 @@ gep_rd(struct net_device *dev) if (lp->chipset == DC21140) { return inl(DE4X5_GEP); } else if ((lp->chipset & ~0x00ff) == DC2114x) { - return (inl(DE4X5_SIGR) & 0x000fffff); + return inl(DE4X5_SIGR) & 0x000fffff; } return 0; diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 1dc27a557275..74217dbf0143 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -1747,7 +1747,7 @@ static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset) if(cr10_value&0x10000000) break; } - return (cr10_value&0x0ffff); + return cr10_value & 0x0ffff; } static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data) diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 5dfb39539b3e..1cc67138adbf 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -541,7 +541,7 @@ cleanup: indexes->respCleared = cpu_to_le32(cleared); wmb(); - return (resp_save == NULL); + return resp_save == NULL; } static inline int diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index ee85c8b9a858..d1ac15c95faf 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -203,7 +203,7 @@ static inline void sierra_net_set_private(struct usbnet *dev, /* is packet IPv4 */ static inline int is_ip(struct sk_buff *skb) { - return (skb->protocol == cpu_to_be16(ETH_P_IP)); + return skb->protocol == cpu_to_be16(ETH_P_IP); } /* @@ -354,7 +354,7 @@ static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) static inline int sierra_net_is_valid_addrlen(u8 len) { - return (len == sizeof(struct in_addr)); + return len == sizeof(struct in_addr); } static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 5ec542dd5b50..0bbc0c323135 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -250,7 +250,7 @@ static int veth_close(struct net_device *dev) static int is_valid_veth_mtu(int new_mtu) { - return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU); + return new_mtu >= MIN_MTU && new_mtu <= MAX_MTU; } static int veth_change_mtu(struct net_device *dev, int new_mtu) diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 421d0715310e..1481a446fefb 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -97,11 +97,11 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, dest = skb_push(skb, hlen); if (!dest) - return(0); + return 0; memcpy(dest, &hdr, hlen); - return(hlen); + return hlen; } static void dlci_receive(struct sk_buff *skb, struct net_device *dev) @@ -211,14 +211,14 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in if (copy_from_user(&config, conf, sizeof(struct dlci_conf))) return -EFAULT; if (config.flags & ~DLCI_VALID_FLAGS) - return(-EINVAL); + return -EINVAL; memcpy(&dlp->config, &config, sizeof(struct dlci_conf)); dlp->configured = 1; } err = (*flp->dlci_conf)(dlp->slave, dev, get); if (err) - return(err); + return err; if (get) { @@ -226,7 +226,7 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in return -EFAULT; } - return(0); + return 0; } static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -234,7 +234,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct dlci_local *dlp; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; dlp = netdev_priv(dev); @@ -242,7 +242,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { case DLCI_GET_SLAVE: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave)); break; @@ -250,15 +250,15 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case DLCI_GET_CONF: case DLCI_SET_CONF: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; - return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF)); + return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF); break; default: - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } - return(0); + return 0; } static int dlci_change_mtu(struct net_device *dev, int new_mtu) @@ -277,15 +277,15 @@ static int dlci_open(struct net_device *dev) dlp = netdev_priv(dev); if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; if (!netif_running(dlp->slave)) - return(-ENOTCONN); + return -ENOTCONN; flp = netdev_priv(dlp->slave); err = (*flp->activate)(dlp->slave, dev); if (err) - return(err); + return err; netif_start_queue(dev); @@ -365,14 +365,14 @@ static int dlci_add(struct dlci_add *dlci) list_add(&dlp->list, &dlci_devs); rtnl_unlock(); - return(0); + return 0; err2: rtnl_unlock(); free_netdev(master); err1: dev_put(slave); - return(err); + return err; } static int dlci_del(struct dlci_add *dlci) @@ -385,10 +385,10 @@ static int dlci_del(struct dlci_add *dlci) /* validate slave device */ master = __dev_get_by_name(&init_net, dlci->devname); if (!master) - return(-ENODEV); + return -ENODEV; if (netif_running(master)) { - return(-EBUSY); + return -EBUSY; } dlp = netdev_priv(master); @@ -406,7 +406,7 @@ static int dlci_del(struct dlci_add *dlci) } rtnl_unlock(); - return(err); + return err; } static int dlci_ioctl(unsigned int cmd, void __user *arg) @@ -415,7 +415,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) int err; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; if (copy_from_user(&add, arg, sizeof(struct dlci_add))) return -EFAULT; @@ -438,7 +438,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) err = -EINVAL; } - return(err); + return err; } static const struct header_ops dlci_header_ops = { diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 43af85b8e45e..70feb84df670 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -1022,7 +1022,7 @@ static int lmc_open(struct net_device *dev) if (sc->lmc_ok){ lmc_trace(dev, "lmc_open lmc_ok out"); - return (0); + return 0; } lmc_softreset (sc); @@ -1110,7 +1110,7 @@ static int lmc_open(struct net_device *dev) lmc_trace(dev, "lmc_open out"); - return (0); + return 0; } /* Total reset to compensate for the AdTran DSU doing bad things diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 7a3720f09ce3..17d408fe693f 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -379,14 +379,14 @@ static int __init n2_run(unsigned long io, unsigned long irq, if (request_irq(irq, sca_intr, 0, devname, card)) { printk(KERN_ERR "n2: could not allocate IRQ\n"); n2_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->irq = irq; if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) { printk(KERN_ERR "n2: could not request RAM window\n"); n2_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->phy_winbase = winbase; card->winbase = ioremap(winbase, USE_WINDOWSIZE); diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index fbf1175a07f1..f875cfae3093 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -451,11 +451,11 @@ static int dma_get_rx_frame_size(pc300_t * card, int ch) if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { /* Return the size of a good frame or incomplete bad frame * (dma_buf_read will clean the buffer descriptors in this case). */ - return (rcvd); + return rcvd; } ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); } - return (-1); + return -1; } /* @@ -557,7 +557,7 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), RX_BD_ADDR(ch, chan->rx_last_bd)); } - return (rcvd); + return rcvd; } static void tx_dma_stop(pc300_t * card, int ch) @@ -1733,7 +1733,7 @@ static u16 falc_pattern_test_error(pc300_t * card, int ch) pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; falc_t *pfalc = (falc_t *) & chan->falc; - return (pfalc->bec); + return pfalc->bec; } /**********************************/ @@ -2819,7 +2819,7 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io) *br_io = 0; if (rate == 0) - return (0); + return 0; for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { if ((tc = clock / br_pwr / rate) <= 0xff) { @@ -2832,11 +2832,11 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io) error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; /* Errors bigger than +/- 1% won't be tolerated */ if (error < -10 || error > 10) - return (-1); + return -1; else - return (tc); + return tc; } else { - return (-1); + return -1; } } @@ -3207,7 +3207,7 @@ static u32 detect_ram(pc300_t * card) break; } } - return (i); + return i; } static void plx_init(pc300_t * card) diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 4293889e287e..515d9b8af01e 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -540,7 +540,7 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty) return -ENODEV; } - return(0); + return 0; } static int pc300_tiocmset(struct tty_struct *tty, struct file *file, diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index f4125da2762f..3f4e2b5684db 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -178,7 +178,7 @@ static char sdla_byte(struct net_device *dev, int addr) byte = *temp; spin_unlock_irqrestore(&sdla_lock, flags); - return(byte); + return byte; } static void sdla_stop(struct net_device *dev) @@ -267,7 +267,7 @@ static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char r resp = *temp; } } - return(time_before(jiffies, done) ? jiffies - start : -1); + return time_before(jiffies, done) ? jiffies - start : -1; } /* constants for Z80 CPU speed */ @@ -283,13 +283,13 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) sdla_start(dev); if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0) - return(-EIO); + return -EIO; data = LOADER_READY; sdla_write(dev, 0, &data, 1); if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0) - return(-EIO); + return -EIO; sdla_stop(dev); sdla_read(dev, 0, &data, 1); @@ -297,11 +297,11 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) if (data == Z80_SCC_BAD) { printk("%s: SCC bad\n", dev->name); - return(-EIO); + return -EIO; } if (data != Z80_SCC_OK) - return(-EINVAL); + return -EINVAL; if (jiffs < 165) ifr->ifr_mtu = SDLA_CPU_16M; @@ -316,7 +316,7 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) else ifr->ifr_mtu = SDLA_CPU_3M; - return(0); + return 0; } /************************************************ @@ -493,7 +493,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, if (ret != SDLA_RET_OK) sdla_errors(dev, cmd, dlci, ret, len, &status); - return(ret); + return ret; } /*********************************************** @@ -516,14 +516,14 @@ static int sdla_activate(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->dlci[i] = abs(flp->dlci[i]); if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); - return(0); + return 0; } static int sdla_deactivate(struct net_device *slave, struct net_device *master) @@ -538,14 +538,14 @@ static int sdla_deactivate(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->dlci[i] = -abs(flp->dlci[i]); if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); - return(0); + return 0; } static int sdla_assoc(struct net_device *slave, struct net_device *master) @@ -554,7 +554,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) int i; if (master->type != ARPHRD_DLCI) - return(-EINVAL); + return -EINVAL; flp = netdev_priv(slave); @@ -563,11 +563,11 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) if (!flp->master[i]) break; if (abs(flp->dlci[i]) == *(short *)(master->dev_addr)) - return(-EADDRINUSE); + return -EADDRINUSE; } if (i == CONFIG_DLCI_MAX) - return(-EMLINK); /* #### Alan: Comments on this ?? */ + return -EMLINK; /* #### Alan: Comments on this ?? */ flp->master[i] = master; @@ -581,7 +581,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); } - return(0); + return 0; } static int sdla_deassoc(struct net_device *slave, struct net_device *master) @@ -596,7 +596,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->master[i] = NULL; flp->dlci[i] = 0; @@ -609,7 +609,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master) sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); } - return(0); + return 0; } static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) @@ -626,7 +626,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; dlp = netdev_priv(master); @@ -641,7 +641,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL); } - return(ret == SDLA_RET_OK ? 0 : -EIO); + return ret == SDLA_RET_OK ? 0 : -EIO; } /************************** @@ -986,7 +986,7 @@ static int sdla_close(struct net_device *dev) netif_stop_queue(dev); - return(0); + return 0; } struct conf_data { @@ -1006,10 +1006,10 @@ static int sdla_open(struct net_device *dev) flp = netdev_priv(dev); if (!flp->initialized) - return(-EPERM); + return -EPERM; if (!flp->configured) - return(-EPERM); + return -EPERM; /* time to send in the configuration */ len = 0; @@ -1087,7 +1087,7 @@ static int sdla_open(struct net_device *dev) netif_start_queue(dev); - return(0); + return 0; } static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get) @@ -1098,48 +1098,48 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in short size; if (dev->type == 0xFFFF) - return(-EUNATCH); + return -EUNATCH; flp = netdev_priv(dev); if (!get) { if (netif_running(dev)) - return(-EBUSY); + return -EBUSY; if(copy_from_user(&data.config, conf, sizeof(struct frad_conf))) return -EFAULT; if (data.config.station & ~FRAD_STATION_NODE) - return(-EINVAL); + return -EINVAL; if (data.config.flags & ~FRAD_VALID_FLAGS) - return(-EINVAL); + return -EINVAL; if ((data.config.kbaud < 0) || ((data.config.kbaud > 128) && (flp->type != SDLA_S508))) - return(-EINVAL); + return -EINVAL; if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232)) - return(-EINVAL); + return -EINVAL; if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU)) - return(-EINVAL); + return -EINVAL; if ((data.config.T391 < 5) || (data.config.T391 > 30)) - return(-EINVAL); + return -EINVAL; if ((data.config.T392 < 5) || (data.config.T392 > 30)) - return(-EINVAL); + return -EINVAL; if ((data.config.N391 < 1) || (data.config.N391 > 255)) - return(-EINVAL); + return -EINVAL; if ((data.config.N392 < 1) || (data.config.N392 > 10)) - return(-EINVAL); + return -EINVAL; if ((data.config.N393 < 1) || (data.config.N393 > 10)) - return(-EINVAL); + return -EINVAL; memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); flp->config.flags |= SDLA_DIRECT_RECV; @@ -1171,7 +1171,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in { size = sizeof(data); if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK) - return(-EIO); + return -EIO; } else if (flp->configured) @@ -1185,7 +1185,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0; } - return(0); + return 0; } static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read) @@ -1200,7 +1200,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r { temp = kzalloc(mem.len, GFP_KERNEL); if (!temp) - return(-ENOMEM); + return -ENOMEM; sdla_read(dev, mem.addr, temp, mem.len); if(copy_to_user(mem.data, temp, mem.len)) { @@ -1217,7 +1217,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r sdla_write(dev, mem.addr, temp, mem.len); kfree(temp); } - return(0); + return 0; } static int sdla_reconfig(struct net_device *dev) @@ -1241,7 +1241,7 @@ static int sdla_reconfig(struct net_device *dev) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); - return(0); + return 0; } static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -1254,20 +1254,20 @@ static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) flp = netdev_priv(dev); if (!flp->initialized) - return(-EINVAL); + return -EINVAL; switch (cmd) { case FRAD_GET_CONF: case FRAD_SET_CONF: - return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF)); + return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF); case SDLA_IDENTIFY: ifr->ifr_flags = flp->type; break; case SDLA_CPUSPEED: - return(sdla_cpuspeed(dev, ifr)); + return sdla_cpuspeed(dev, ifr); /* ========================================================== NOTE: This is rather a useless action right now, as the @@ -1277,7 +1277,7 @@ NOTE: This is rather a useless action right now, as the ============================================================*/ case SDLA_PROTOCOL: if (flp->configured) - return(-EALREADY); + return -EALREADY; switch (ifr->ifr_flags) { @@ -1285,7 +1285,7 @@ NOTE: This is rather a useless action right now, as the dev->type = ifr->ifr_flags; break; default: - return(-ENOPROTOOPT); + return -ENOPROTOOPT; } break; @@ -1297,7 +1297,7 @@ NOTE: This is rather a useless action right now, as the case SDLA_READMEM: if(!capable(CAP_SYS_RAWIO)) return -EPERM; - return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM)); + return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM); case SDLA_START: sdla_start(dev); @@ -1308,9 +1308,9 @@ NOTE: This is rather a useless action right now, as the break; default: - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } - return(0); + return 0; } static int sdla_change_mtu(struct net_device *dev, int new_mtu) @@ -1320,10 +1320,10 @@ static int sdla_change_mtu(struct net_device *dev, int new_mtu) flp = netdev_priv(dev); if (netif_running(dev)) - return(-EBUSY); + return -EBUSY; /* for now, you can't change the MTU! */ - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } static int sdla_set_config(struct net_device *dev, struct ifmap *map) @@ -1337,18 +1337,18 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map) flp = netdev_priv(dev); if (flp->initialized) - return(-EINVAL); + return -EINVAL; for(i=0; i < ARRAY_SIZE(valid_port); i++) if (valid_port[i] == map->base_addr) break; if (i == ARRAY_SIZE(valid_port)) - return(-EINVAL); + return -EINVAL; if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){ printk(KERN_WARNING "SDLA: io-port 0x%04lx in use\n", dev->base_addr); - return(-EINVAL); + return -EINVAL; } base = map->base_addr; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index e47f5a986b1c..d81ad8397885 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -648,7 +648,7 @@ static int x25_asy_esc(unsigned char *s, unsigned char *d, int len) } } *ptr++ = X25_END; - return (ptr - d); + return ptr - d; } static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 788a9bc1dbac..630fb8664768 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -135,7 +135,7 @@ static void skb_entry_set_link(union skb_entry *list, unsigned short id) static int skb_entry_is_link(const union skb_entry *list) { BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link)); - return ((unsigned long)list->skb < PAGE_OFFSET); + return (unsigned long)list->skb < PAGE_OFFSET; } /* @@ -203,8 +203,8 @@ static void rx_refill_timeout(unsigned long data) static int netfront_tx_slot_available(struct netfront_info *np) { - return ((np->tx.req_prod_pvt - np->tx.rsp_cons) < - (TX_MAX_TARGET - MAX_SKB_FRAGS - 2)); + return (np->tx.req_prod_pvt - np->tx.rsp_cons) < + (TX_MAX_TARGET - MAX_SKB_FRAGS - 2); } static void xennet_maybe_wake_tx(struct net_device *dev) -- cgit v1.2.3 From 7a91b434e2bad554b709265db7603b1aa52dd92e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 26 Sep 2010 18:53:07 -0700 Subject: net: update SOCK_MIN_RCVBUF SOCK_MIN_RCVBUF current value is 256 bytes It doesnt permit to receive the smallest possible frame, considering socket sk_rmem_alloc/sk_rcvbuf account skb truesizes. On 64bit arches, sizeof(struct sk_buff) is 240 bytes. Add the typical 64 bytes of headroom, and we go over the limit. With old kernels and 32bit arches, we were under the limit, if netdriver was doing copybreak. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/net/sock.h b/include/net/sock.h index 8ae97c4970df..73a4f9702a65 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1558,7 +1558,11 @@ static inline void sk_wake_async(struct sock *sk, int how, int band) } #define SOCK_MIN_SNDBUF 2048 -#define SOCK_MIN_RCVBUF 256 +/* + * Since sk_rmem_alloc sums skb->truesize, even a small frame might need + * sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak + */ +#define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff)) static inline void sk_stream_moderate_sndbuf(struct sock *sk) { -- cgit v1.2.3 From 1b4bf461f05d56ced6d6b8f3b4831adc7076f565 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 17:26:35 +0000 Subject: rps: allocate rx queues in register_netdevice only Instead of having two places were we allocate dev->_rx, introduce netif_alloc_rx_queues() helper and call it only from register_netdevice(), not from alloc_netdev_mq() Goal is to let drivers change dev->num_rx_queues after allocating netdev and before registering it. This also removes a lot of ifdefs in net/core/dev.c Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 76 +++++++++++++++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index e0c0b86f57a1..72e99835e5b8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4964,6 +4964,34 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev, } EXPORT_SYMBOL(netif_stacked_transfer_operstate); +static int netif_alloc_rx_queues(struct net_device *dev) +{ +#ifdef CONFIG_RPS + unsigned int i, count = dev->num_rx_queues; + + if (count) { + struct netdev_rx_queue *rx; + + rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL); + if (!rx) { + pr_err("netdev: Unable to allocate %u rx queues.\n", + count); + return -ENOMEM; + } + dev->_rx = rx; + atomic_set(&rx->count, count); + + /* + * Set a pointer to first element in the array which holds the + * reference count. + */ + for (i = 0; i < count; i++) + rx[i].first = rx; + } +#endif + return 0; +} + /** * register_netdevice - register a network device * @dev: device to register @@ -5001,24 +5029,10 @@ int register_netdevice(struct net_device *dev) dev->iflink = -1; -#ifdef CONFIG_RPS - if (!dev->num_rx_queues) { - /* - * Allocate a single RX queue if driver never called - * alloc_netdev_mq - */ - - dev->_rx = kzalloc(sizeof(struct netdev_rx_queue), GFP_KERNEL); - if (!dev->_rx) { - ret = -ENOMEM; - goto out; - } + ret = netif_alloc_rx_queues(dev); + if (ret) + goto out; - dev->_rx->first = dev->_rx; - atomic_set(&dev->_rx->count, 1); - dev->num_rx_queues = 1; - } -#endif /* Init, if this function is available */ if (dev->netdev_ops->ndo_init) { ret = dev->netdev_ops->ndo_init(dev); @@ -5415,10 +5429,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, struct net_device *dev; size_t alloc_size; struct net_device *p; -#ifdef CONFIG_RPS - struct netdev_rx_queue *rx; - int i; -#endif BUG_ON(strlen(name) >= sizeof(dev->name)); @@ -5444,29 +5454,12 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, goto free_p; } -#ifdef CONFIG_RPS - rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL); - if (!rx) { - printk(KERN_ERR "alloc_netdev: Unable to allocate " - "rx queues.\n"); - goto free_tx; - } - - atomic_set(&rx->count, queue_count); - - /* - * Set a pointer to first element in the array which holds the - * reference count. - */ - for (i = 0; i < queue_count; i++) - rx[i].first = rx; -#endif dev = PTR_ALIGN(p, NETDEV_ALIGN); dev->padded = (char *)dev - (char *)p; if (dev_addr_init(dev)) - goto free_rx; + goto free_tx; dev_mc_init(dev); dev_uc_init(dev); @@ -5478,7 +5471,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->real_num_tx_queues = queue_count; #ifdef CONFIG_RPS - dev->_rx = rx; dev->num_rx_queues = queue_count; #endif @@ -5496,11 +5488,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, strcpy(dev->name, name); return dev; -free_rx: -#ifdef CONFIG_RPS - kfree(rx); free_tx: -#endif kfree(tx); free_p: kfree(p); -- cgit v1.2.3 From 83180af0b0ea166adf8249f4513beb7355f9b4c9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 21:46:03 +0000 Subject: net: fix rcu use in ip_route_output_slow __in_dev_get_rtnl(dev_out) is called while RTNL is not held, thus triggers a lockdep fault. At this point, we only perform a raw test of dev_out->ip_ptr being NULL, we dont need to make sure ip_ptr cant changed right after. We can use rcu_dereference_raw() for this. Reported-by: Andrew Morton Acked-by: Paul E. McKenney Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ae1d4a41f1c6..98beda47bc99 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2579,7 +2579,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, goto out; /* RACE: Check return value of inet_select_addr instead. */ - if (__in_dev_get_rtnl(dev_out) == NULL) { + if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) { dev_put(dev_out); goto out; /* Wrong error code */ } -- cgit v1.2.3 From a7855c78a24d6348e989bec616318e68c662e78b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Sep 2010 23:51:51 +0000 Subject: net: loopback driver cleanup loopback driver uses dev->ml_priv to store its percpu stats pointer. It uses ugly casts "(void __percpu __force *)" to shut up sparse complains. Define an union to better document we use ml_priv in loopback driver and define a lstats field with appropriate types. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/loopback.c | 20 +++++--------------- include/linux/netdevice.h | 6 ++++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 9a0996795321..4b0e30b564e5 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -74,7 +74,6 @@ struct pcpu_lstats { static netdev_tx_t loopback_xmit(struct sk_buff *skb, struct net_device *dev) { - struct pcpu_lstats __percpu *pcpu_lstats; struct pcpu_lstats *lb_stats; int len; @@ -83,8 +82,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, skb->protocol = eth_type_trans(skb, dev); /* it's OK to use per_cpu_ptr() because BHs are off */ - pcpu_lstats = (void __percpu __force *)dev->ml_priv; - lb_stats = this_cpu_ptr(pcpu_lstats); + lb_stats = this_cpu_ptr(dev->lstats); len = skb->len; if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { @@ -101,19 +99,17 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - const struct pcpu_lstats __percpu *pcpu_lstats; u64 bytes = 0; u64 packets = 0; u64 drops = 0; int i; - pcpu_lstats = (void __percpu __force *)dev->ml_priv; for_each_possible_cpu(i) { const struct pcpu_lstats *lb_stats; u64 tbytes, tpackets; unsigned int start; - lb_stats = per_cpu_ptr(pcpu_lstats, i); + lb_stats = per_cpu_ptr(dev->lstats, i); do { start = u64_stats_fetch_begin(&lb_stats->syncp); tbytes = lb_stats->bytes; @@ -147,22 +143,16 @@ static const struct ethtool_ops loopback_ethtool_ops = { static int loopback_dev_init(struct net_device *dev) { - struct pcpu_lstats __percpu *lstats; - - lstats = alloc_percpu(struct pcpu_lstats); - if (!lstats) + dev->lstats = alloc_percpu(struct pcpu_lstats); + if (!dev->lstats) return -ENOMEM; - dev->ml_priv = (void __force *)lstats; return 0; } static void loopback_dev_free(struct net_device *dev) { - struct pcpu_lstats __percpu *lstats = - (void __percpu __force *)dev->ml_priv; - - free_percpu(lstats); + free_percpu(dev->lstats); free_netdev(dev); } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 45dcda5bfda9..01bd4c82d982 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1050,8 +1050,10 @@ struct net_device { #endif /* mid-layer private */ - void *ml_priv; - + union { + void *ml_priv; + struct pcpu_lstats __percpu *lstats; /* loopback stats */ + }; /* GARP */ struct garp_port *garp_port; -- cgit v1.2.3 From 42099d7a3941d4aaf853caac92b3ae76149fc6e7 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Sun, 26 Sep 2010 19:58:07 -0700 Subject: net: r6040: store BIOS default MAC in perm_add Signed-off-by: Otavio Salvador Signed-off-by: David S. Miller --- drivers/net/r6040.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 63db065508f4..68a84198eb05 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -745,6 +745,9 @@ static void r6040_mac_address(struct net_device *dev) iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); + + /* Store MAC Address in perm_addr */ + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); } static int r6040_open(struct net_device *dev) -- cgit v1.2.3 From 87fd2e6c90acb45a5741207fc953190596f93841 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 21 Sep 2010 17:03:57 -0700 Subject: ath5k: Add bssid mask and rxfilter to debugfs. Helps with debugging virtual interfaces. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 58 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath5k/debug.h | 1 + 2 files changed, 59 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 6583a82a0783..0f06e8490314 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -483,6 +483,59 @@ static const struct file_operations fops_antenna = { .owner = THIS_MODULE, }; +/* debugfs: misc */ + +static ssize_t read_file_misc(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath5k_softc *sc = file->private_data; + char buf[700]; + unsigned int len = 0; + u32 filt = ath5k_hw_get_rx_filter(sc->ah); + + len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", + sc->bssidmask); + len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ", + filt); + if (filt & AR5K_RX_FILTER_UCAST) + len += snprintf(buf+len, sizeof(buf)-len, " UCAST"); + if (filt & AR5K_RX_FILTER_MCAST) + len += snprintf(buf+len, sizeof(buf)-len, " MCAST"); + if (filt & AR5K_RX_FILTER_BCAST) + len += snprintf(buf+len, sizeof(buf)-len, " BCAST"); + if (filt & AR5K_RX_FILTER_CONTROL) + len += snprintf(buf+len, sizeof(buf)-len, " CONTROL"); + if (filt & AR5K_RX_FILTER_BEACON) + len += snprintf(buf+len, sizeof(buf)-len, " BEACON"); + if (filt & AR5K_RX_FILTER_PROM) + len += snprintf(buf+len, sizeof(buf)-len, " PROM"); + if (filt & AR5K_RX_FILTER_XRPOLL) + len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL"); + if (filt & AR5K_RX_FILTER_PROBEREQ) + len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ"); + if (filt & AR5K_RX_FILTER_PHYERR_5212) + len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212"); + if (filt & AR5K_RX_FILTER_RADARERR_5212) + len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212"); + if (filt & AR5K_RX_FILTER_PHYERR_5211) + snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); + if (filt & AR5K_RX_FILTER_RADARERR_5211) + len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n"); + else + len += snprintf(buf+len, sizeof(buf)-len, "\n"); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_misc = { + .read = read_file_misc, + .open = ath5k_debugfs_open, + .owner = THIS_MODULE, +}; + /* debugfs: frameerrors */ @@ -856,6 +909,10 @@ ath5k_debug_init_device(struct ath5k_softc *sc) S_IWUSR | S_IRUSR, sc->debug.debugfs_phydir, sc, &fops_antenna); + sc->debug.debugfs_misc = debugfs_create_file("misc", + S_IRUSR, + sc->debug.debugfs_phydir, sc, &fops_misc); + sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, sc->debug.debugfs_phydir, sc, @@ -886,6 +943,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) debugfs_remove(sc->debug.debugfs_beacon); debugfs_remove(sc->debug.debugfs_reset); debugfs_remove(sc->debug.debugfs_antenna); + debugfs_remove(sc->debug.debugfs_misc); debugfs_remove(sc->debug.debugfs_frameerrors); debugfs_remove(sc->debug.debugfs_ani); debugfs_remove(sc->debug.debugfs_queue); diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 9b22722a95f0..4f078b134015 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -75,6 +75,7 @@ struct ath5k_dbg_info { struct dentry *debugfs_beacon; struct dentry *debugfs_reset; struct dentry *debugfs_antenna; + struct dentry *debugfs_misc; struct dentry *debugfs_frameerrors; struct dentry *debugfs_ani; struct dentry *debugfs_queue; -- cgit v1.2.3 From 67e0208acea29682f5766eb9f67f6f26117eef3e Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Wed, 22 Sep 2010 09:53:13 +0200 Subject: wl1271: Fix overflow in wl1271_boot_upload_nvs Due to miscalculation of nvs_len, excessive data was sent to the firmware. Fix this by first setting nvs_ptr to point to the first NVS table, and computing the total size of all NVS tables accordingly. Signed-off-by: Ido Yariv Tested-By: Tuomas Katila Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_boot.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index fc21db810812..e5a7f042645f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -274,11 +274,11 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) /* * We've reached the first zero length, the first NVS table - * is 7 bytes further. + * is located at an aligned offset which is at least 7 bytes further. */ - nvs_ptr += 7; + nvs_ptr = (u8 *)wl->nvs->nvs + + ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; - nvs_len = ALIGN(nvs_len, 4); /* FIXME: The driver sets the partition here, but this is not needed, since it sets to the same one as currently in use */ @@ -286,14 +286,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) wl1271_set_partition(wl, &part_table[PART_WORK]); /* Copy the NVS tables to a new block to ensure alignment */ - /* FIXME: We jump 3 more bytes before uploading the NVS. It seems - that our NVS files have three extra zeros here. I'm not sure whether - the problem is in our NVS generation or we should really jumpt these - 3 bytes here */ - nvs_ptr += 3; - - nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if - (!nvs_aligned) return -ENOMEM; + nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); + if (!nvs_aligned) + return -ENOMEM; /* And finally we upload the NVS tables */ /* FIXME: In wl1271, we upload everything at once. -- cgit v1.2.3 From 7a37081e2e25e58701b17c41579fd06bc353b392 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 22 Sep 2010 12:34:52 +0200 Subject: ath9k_hw: simplify revision checks for AR9280 Since AR9280 v1.0 was never sold (and the initvals removed), v1.0 specific revision checks can be removed and the 'v2.0 or later' check can be simplified to a check for AR9280 or later. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 14 +++++++------- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 6 +++--- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 4 ++-- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 +++--- drivers/net/wireless/ath/ath9k/eeprom_def.c | 18 +++++++++--------- drivers/net/wireless/ath/ath9k/hw.c | 15 +++++++-------- drivers/net/wireless/ath/ath9k/init.c | 2 +- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/ath/ath9k/reg.h | 9 ++------- 10 files changed, 36 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 3d2c8679bc85..9318ae736982 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -118,7 +118,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) if (!AR_SREV_5416(ah) || synth_freq >= 3000) return; - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); if (synth_freq < 2412) new_bias = 0; @@ -454,7 +454,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); @@ -484,7 +484,7 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) bank = NULL; \ } while (0); - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); ATH_FREE_BANK(ah->analogBank0Data); ATH_FREE_BANK(ah->analogBank1Data); @@ -525,7 +525,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, * for single chip devices, that is AR9280 or anything * after that. */ - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) return true; /* Setup rf parameters */ @@ -663,7 +663,7 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, */ REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { val = REG_READ(ah, AR_PCU_MISC_MODE2); if (!AR_SREV_9271(ah)) @@ -676,7 +676,7 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, } if (!AR_SREV_5416_20_OR_LATER(ah) || - AR_SREV_9280_10_OR_LATER(ah)) + AR_SREV_9280_20_OR_LATER(ah)) return; /* * Disable BB clock gating @@ -900,7 +900,7 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; - if (!AR_SREV_9280_10_OR_LATER(ah)) + if (!AR_SREV_9280_20_OR_LATER(ah)) rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index fe7418aefc4a..dc64afeeaa12 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -841,7 +841,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) if (!ar9285_hw_clc(ah, chan)) return false; } else { - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (!AR_SREV_9287_10_OR_LATER(ah)) REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); @@ -864,7 +864,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) return false; } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (!AR_SREV_9287_10_OR_LATER(ah)) REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); @@ -976,7 +976,7 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah) } if (AR_SREV_9160_10_OR_LATER(ah)) { - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { ah->iq_caldata.calData = &iq_cal_single_sample; ah->adcgain_caldata.calData = &adc_gain_cal_single_sample; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 94392daebaa0..fde45082a13b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -569,7 +569,7 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) ops->config_pci_powersave = ar9002_hw_configpcipowersave; ar5008_hw_attach_phy_ops(ah); - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ar9002_hw_attach_phy_ops(ah); ar9002_hw_attach_calib_ops(ah); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index ead8b0dd3b53..677e0c9d0481 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -333,7 +333,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, } if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -761,7 +761,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, regulatory->max_power_level = ratesArray[i]; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index e6186515d05b..966b9496a9dd 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -324,7 +324,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, minDelta = 0; if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -883,7 +883,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, ratesArray[i] = AR9287_MAX_RATE_POWER; } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; } @@ -977,7 +977,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, else i = rate6mb; - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) regulatory->max_power_level = ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; else diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 23f480d4c770..76b4d65472dd 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -223,7 +223,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) } /* Enable fixup for AR_AN_TOP2 if necessary */ - if (AR_SREV_9280_10_OR_LATER(ah) && + if (AR_SREV_9280_20_OR_LATER(ah) && (eep->baseEepHeader.version & 0xff) > 0x0a && eep->baseEepHeader.pwdclkind == 0) ah->need_an_top2_fixup = 1; @@ -317,7 +317,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah, if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { txRxAttenLocal = pModal->txRxAttenCh[i]; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[i]); @@ -344,7 +344,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah, } } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); @@ -408,7 +408,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, regChainOffset, i); } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (IS_CHAN_2GHZ(chan)) { ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, @@ -461,7 +461,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); - if (!AR_SREV_9280_10_OR_LATER(ah)) + if (!AR_SREV_9280_20_OR_LATER(ah)) REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); @@ -478,7 +478,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, pModal->thresh62); REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, @@ -696,7 +696,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, } if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -1291,7 +1291,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, ratesArray[i] = AR5416_MAX_RATE_POWER; } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) { int8_t pwr_table_offset; @@ -1395,7 +1395,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, else if (IS_CHAN_HT20(chan)) i = rateHt20_0; - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) regulatory->max_power_level = ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2; else diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0b2ff98b6f33..f2255a211637 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -565,7 +565,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_init_cal_settings(ah); ah->ani_function = ATH9K_ANI_ALL; - if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; if (!AR_SREV_9300_20_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_MRC_CCK; @@ -1312,7 +1312,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (tsf) ath9k_hw_settsf64(ah, tsf); - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); if (!AR_SREV_9300_20_OR_LATER(ah)) @@ -1857,8 +1857,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) /* Use rx_chainmask from EEPROM. */ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); - if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) - ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; + ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; pCap->low_2ghz_chan = 2312; pCap->high_2ghz_chan = 2732; @@ -1896,7 +1895,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_gpio_pins = AR7010_NUM_GPIO; else if (AR_SREV_9285_10_OR_LATER(ah)) pCap->num_gpio_pins = AR9285_NUM_GPIO; - else if (AR_SREV_9280_10_OR_LATER(ah)) + else if (AR_SREV_9280_20_OR_LATER(ah)) pCap->num_gpio_pins = AR928X_NUM_GPIO; else pCap->num_gpio_pins = AR_NUM_GPIO; @@ -1953,7 +1952,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_antcfg_2ghz = ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); - if (AR_SREV_9280_10_OR_LATER(ah) && + if (AR_SREV_9280_20_OR_LATER(ah) && ath9k_hw_btcoex_supported(ah)) { btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; @@ -2078,7 +2077,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) return MS_REG_READ(AR9287, gpio) != 0; else if (AR_SREV_9285_10_OR_LATER(ah)) return MS_REG_READ(AR9285, gpio) != 0; - else if (AR_SREV_9280_10_OR_LATER(ah)) + else if (AR_SREV_9280_20_OR_LATER(ah)) return MS_REG_READ(AR928X, gpio) != 0; else return MS_REG_READ(AR, gpio) != 0; @@ -2575,7 +2574,7 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len) int used; /* chipsets >= AR9280 are single-chip */ - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { used = snprintf(hw_name, len, "Atheros AR%s Rev:%x", ath9k_hw_mac_bb_name(ah->hw_version.macVersion), diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 573899e27b3d..de3393867e37 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -211,7 +211,7 @@ static void setup_ht_cap(struct ath_softc *sc, else max_streams = 2; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (max_streams >= 2) ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c5e7af4f51ab..7b6f66bf3739 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -454,7 +454,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) else rfilt |= ATH9K_RX_FILTER_BEACON; - if ((AR_SREV_9280_10_OR_LATER(sc->sc_ah) || + if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || AR_SREV_9285_10_OR_LATER(sc->sc_ah)) && (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PSPOLL)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index d01c4adab8d6..cabfa0356c9c 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -819,15 +819,10 @@ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11)) #define AR_SREV_9280(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280)) -#define AR_SREV_9280_10_OR_LATER(_ah) \ +#define AR_SREV_9280_20_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280)) #define AR_SREV_9280_20(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)) -#define AR_SREV_9280_20_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))) + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280)) #define AR_SREV_9285(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285)) -- cgit v1.2.3 From e17f83eafd37129f9e09425136e59bc4333bdb9c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 22 Sep 2010 12:34:53 +0200 Subject: ath9k_hw: simplify revision checks for AR9285 Since AR9285 v1.0 and v1.1 were never sold (and the initvals removed), its revision checks can be simplified similar to AR9280 Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 11 +---------- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 6 ------ drivers/net/wireless/ath/ath9k/hw.c | 8 ++++---- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/ath/ath9k/reg.h | 16 +--------------- 6 files changed, 8 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 9318ae736982..79dfe9dded52 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -701,7 +701,7 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, u32 phymode; u32 enableDacFifo = 0; - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index dc64afeeaa12..5d0815145b78 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -567,11 +567,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) AR5416_EEP_TXGAIN_HIGH_POWER) return; - if (AR_SREV_9285_11(ah)) { - REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); - udelay(10); - } - for (i = 0; i < ARRAY_SIZE(regList); i++) regList[i][1] = REG_READ(ah, regList[i][0]); @@ -651,10 +646,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) REG_WRITE(ah, regList[i][0], regList[i][1]); REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); - - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); - } static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset) @@ -664,7 +655,7 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset) ar9271_hw_pa_cal(ah, is_reset); else ah->pacal_info.skipcount--; - } else if (AR_SREV_9285_11_OR_LATER(ah)) { + } else if (AR_SREV_9285_12_OR_LATER(ah)) { if (is_reset || !ah->pacal_info.skipcount) ar9285_hw_pa_cal(ah, is_reset); else diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 677e0c9d0481..d6eed1f02e84 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -909,9 +909,6 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); - - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); } /* @@ -1109,9 +1106,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, } - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); - REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f2255a211637..1f41b4513c52 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1190,7 +1190,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) int count = 50; u32 reg; - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) return true; do { @@ -1787,7 +1787,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) regulatory->current_rd = eeval; eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1); - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) eeval |= AR9285_RDEXT_DEFAULT; regulatory->current_rd_ext = eeval; @@ -1893,7 +1893,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_gpio_pins = AR9271_NUM_GPIO; else if (AR_DEVID_7010(ah)) pCap->num_gpio_pins = AR7010_NUM_GPIO; - else if (AR_SREV_9285_10_OR_LATER(ah)) + else if (AR_SREV_9285_12_OR_LATER(ah)) pCap->num_gpio_pins = AR9285_NUM_GPIO; else if (AR_SREV_9280_20_OR_LATER(ah)) pCap->num_gpio_pins = AR928X_NUM_GPIO; @@ -2075,7 +2075,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) return MS_REG_READ(AR9271, gpio) != 0; else if (AR_SREV_9287_10_OR_LATER(ah)) return MS_REG_READ(AR9287, gpio) != 0; - else if (AR_SREV_9285_10_OR_LATER(ah)) + else if (AR_SREV_9285_12_OR_LATER(ah)) return MS_REG_READ(AR9285, gpio) != 0; else if (AR_SREV_9280_20_OR_LATER(ah)) return MS_REG_READ(AR928X, gpio) != 0; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7b6f66bf3739..00140489becb 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -455,7 +455,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt |= ATH9K_RX_FILTER_BEACON; if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || - AR_SREV_9285_10_OR_LATER(sc->sc_ah)) && + AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PSPOLL)) rfilt |= ATH9K_RX_FILTER_PSPOLL; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index cabfa0356c9c..7ff814d4a792 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -826,22 +826,8 @@ #define AR_SREV_9285(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285)) -#define AR_SREV_9285_10_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285)) -#define AR_SREV_9285_11(_ah) \ - (AR_SREV_9285(ah) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11)) -#define AR_SREV_9285_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ - (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ - AR_SREV_REVISION_9285_11))) -#define AR_SREV_9285_12(_ah) \ - (AR_SREV_9285(ah) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12)) #define AR_SREV_9285_12_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ - (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ - AR_SREV_REVISION_9285_12))) + (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285)) #define AR_SREV_9287(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287)) -- cgit v1.2.3 From a42acef0dd3548ffda03d245d41b95250354017e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 22 Sep 2010 12:34:54 +0200 Subject: ath9k_hw: simplify revision checks for AR9287 Since AR9287 v1.0 was never sold (and the initvals removed), its revision checks can be simplified similar to AR9280 Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 6 +++--- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 4 ++-- drivers/net/wireless/ath/ath9k/eeprom.h | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- drivers/net/wireless/ath/ath9k/reg.h | 9 +-------- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 79dfe9dded52..525671f52b45 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -669,7 +669,7 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, if (!AR_SREV_9271(ah)) val &= ~AR_PCU_MISC_MODE2_HWWAR1; - if (AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9287_11_OR_LATER(ah)) val = val & (~AR_PCU_MISC_MODE2_HWWAR2); REG_WRITE(ah, AR_PCU_MISC_MODE2, val); @@ -820,11 +820,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); DISABLE_REGWRITE_BUFFER(ah); - if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) || - AR_SREV_9287_10_OR_LATER(ah)) + AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); if (AR_SREV_9271_10(ah)) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 5d0815145b78..d7d1d55362e6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -833,7 +833,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) return false; } else { if (AR_SREV_9280_20_OR_LATER(ah)) { - if (!AR_SREV_9287_10_OR_LATER(ah)) + if (!AR_SREV_9287_11_OR_LATER(ah)) REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, @@ -856,7 +856,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) } if (AR_SREV_9280_20_OR_LATER(ah)) { - if (!AR_SREV_9287_10_OR_LATER(ah)) + if (!AR_SREV_9287_11_OR_LATER(ah)) REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 3030564a0f21..dacb45e1b906 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -101,7 +101,7 @@ #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) -#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_10_OR_LATER(ah) && \ +#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) #define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1f41b4513c52..25ed65ac992c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1989,7 +1989,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; - if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah)) + if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; if (AR_SREV_9285(ah)) @@ -2073,7 +2073,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) return MS_REG_READ(AR9300, gpio) != 0; else if (AR_SREV_9271(ah)) return MS_REG_READ(AR9271, gpio) != 0; - else if (AR_SREV_9287_10_OR_LATER(ah)) + else if (AR_SREV_9287_11_OR_LATER(ah)) return MS_REG_READ(AR9287, gpio) != 0; else if (AR_SREV_9285_12_OR_LATER(ah)) return MS_REG_READ(AR9285, gpio) != 0; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 7ff814d4a792..6d01e501b9b4 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -831,18 +831,11 @@ #define AR_SREV_9287(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287)) -#define AR_SREV_9287_10_OR_LATER(_ah) \ +#define AR_SREV_9287_11_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287)) -#define AR_SREV_9287_10(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_10)) #define AR_SREV_9287_11(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11)) -#define AR_SREV_9287_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11))) #define AR_SREV_9287_12(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12)) -- cgit v1.2.3 From 295bafb47b0d365e1b4f747dffef29e590f13233 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Sep 2010 20:29:01 -0700 Subject: mac80211: Support multiple VIFS per AP in debugfs. Create 'stations' sub-directory under each netdev:[vif-name] directory to hold all stations for that network device. Signed-off-by: Ben Greear Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/debugfs.c | 1 - net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/debugfs_sta.c | 2 +- net/mac80211/ieee80211_i.h | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index e81ef4e8cb32..ebd5b69f562e 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -368,7 +368,6 @@ void debugfs_hw_add(struct ieee80211_local *local) if (!phyd) return; - local->debugfs.stations = debugfs_create_dir("stations", phyd); local->debugfs.keys = debugfs_create_dir("keys", phyd); DEBUGFS_ADD(frequency); diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 20b2998fa0ed..3e12430591b7 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -409,6 +409,9 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) sprintf(buf, "netdev:%s", sdata->name); sdata->debugfs.dir = debugfs_create_dir(buf, sdata->local->hw.wiphy->debugfsdir); + if (sdata->debugfs.dir) + sdata->debugfs.subdir_stations = debugfs_create_dir("stations", + sdata->debugfs.dir); add_files(sdata); } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 76839d4dfaac..6b7ff9fb4604 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -300,7 +300,7 @@ STA_OPS(ht_capa); void ieee80211_sta_debugfs_add(struct sta_info *sta) { - struct dentry *stations_dir = sta->local->debugfs.stations; + struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; u8 mac[3*ETH_ALEN]; sta->debugfs.add_has_run = true; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 78a8d9208cec..40f747273389 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -564,6 +564,7 @@ struct ieee80211_sub_if_data { #ifdef CONFIG_MAC80211_DEBUGFS struct { struct dentry *dir; + struct dentry *subdir_stations; struct dentry *default_key; struct dentry *default_mgmt_key; } debugfs; @@ -899,7 +900,6 @@ struct ieee80211_local { #ifdef CONFIG_MAC80211_DEBUGFS struct local_debugfsdentries { struct dentry *rcdir; - struct dentry *stations; struct dentry *keys; } debugfs; #endif -- cgit v1.2.3 From 686b9cb994f5f74be790df4cd12873dfdc8a6984 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 23 Sep 2010 09:44:36 -0700 Subject: mac80211/ath9k: Support AMPDU with multiple VIFs. The old ieee80211_find_sta_by_hw method didn't properly find VIFS when there was more than one per AP. This caused AMPDU logic in ath9k to get the wrong VIF when trying to account for transmitted SKBs. This patch changes ieee80211_find_sta_by_hw to take a localaddr argument to distinguish between VIFs with the same AP but different local addresses. The method name is changed to ieee80211_find_sta_by_ifaddr. Signed-off-by: Ben Greear Acked-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 6 +++++- drivers/net/wireless/ath/ath9k/xmit.c | 3 +-- include/net/mac80211.h | 25 ++++++++++++++----------- net/mac80211/sta_info.c | 15 +++++++++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 00140489becb..9c166f3804ab 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -977,7 +977,11 @@ static void ath9k_process_rssi(struct ath_common *common, * at least one sdata of a wiphy on mac80211 but with ath9k virtual * wiphy you'd have to iterate over every wiphy and each sdata. */ - sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); + if (is_multicast_ether_addr(hdr->addr1)) + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL); + else + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1); + if (sta) { an = (struct ath_node *) sta->drv_priv; if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 85a7323a04ef..f7da6b20a925 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -328,8 +328,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_lock(); - /* XXX: use ieee80211_find_sta! */ - sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); if (!sta) { rcu_read_unlock(); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5d1187d7c5e5..73469d8b64bb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2432,25 +2432,28 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr); /** - * ieee80211_find_sta_by_hw - find a station on hardware + * ieee80211_find_sta_by_ifaddr - find a station on hardware * * @hw: pointer as obtained from ieee80211_alloc_hw() - * @addr: station's address + * @addr: remote station's address + * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'. * * This function must be called under RCU lock and the * resulting pointer is only valid under RCU lock as well. * - * NOTE: This function should not be used! When mac80211 is converted - * internally to properly keep track of stations on multiple - * virtual interfaces, it will not always know which station to - * return here since a single address might be used by multiple - * logical stations (e.g. consider a station connecting to another - * BSSID on the same AP hardware without disconnecting first). + * NOTE: You may pass NULL for localaddr, but then you will just get + * the first STA that matches the remote address 'addr'. + * We can have multiple STA associated with multiple + * logical stations (e.g. consider a station connecting to another + * BSSID on the same AP hardware without disconnecting first). + * In this case, the result of this method with localaddr NULL + * is not reliable. * - * DO NOT USE THIS FUNCTION. + * DO NOT USE THIS FUNCTION with localaddr NULL if at all possible. */ -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, - const u8 *addr); +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, + const u8 *addr, + const u8 *localaddr); /** * ieee80211_sta_block_awake - block station from waking up diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 44e10a9de0a7..ca2cba9cea87 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -838,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, mutex_unlock(&local->sta_mtx); } -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, - const u8 *addr) +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, + const u8 *addr, + const u8 *localaddr) { struct sta_info *sta, *nxt; - /* Just return a random station ... first in list ... */ + /* + * Just return a random station if localaddr is NULL + * ... first in list. + */ for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { + if (localaddr && + compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) + continue; if (!sta->uploaded) return NULL; return &sta->sta; @@ -852,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, return NULL; } -EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); +EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr); struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr) -- cgit v1.2.3 From 56af326830757f3e8a1742770d15dfd6e3c40e85 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 23 Sep 2010 10:22:24 -0700 Subject: mac80211: Support receiving data frames on multiple vifs. When using multiple STA interfaces on the same radio, some data packets need to be received on all interfaces (broadcast, for instance). Make the STA loop look similar to the mgt-data loop. Also, add logic to check RX_FLAG_MMIC_ERROR for last interface in mgt-data loop. Signed-off-by: Ben Greear Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 308e502a80eb..50c0803a63ba 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2609,7 +2609,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, int prepares; struct ieee80211_sub_if_data *prev = NULL; struct sk_buff *skb_new; - struct sta_info *sta, *tmp; + struct sta_info *sta, *tmp, *prev_sta; bool found_sta = false; int err = 0; @@ -2640,22 +2640,74 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_verify_alignment(&rx); if (ieee80211_is_data(fc)) { + prev_sta = NULL; for_each_sta_info(local, hdr->addr2, sta, tmp) { - rx.sta = sta; found_sta = true; - rx.sdata = sta->sdata; + if (!prev_sta) { + prev_sta = sta; + continue; + } + + rx.sta = prev_sta; + rx.sdata = prev_sta->sdata; rx.flags |= IEEE80211_RX_RA_MATCH; prepares = prepare_for_handlers(rx.sdata, &rx, hdr); - if (prepares) { - if (status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, &rx); - } else - prev = rx.sdata; + if (!prepares) + goto next_sta; + + if (status->flag & RX_FLAG_MMIC_ERROR) { + if (rx.flags & IEEE80211_RX_RA_MATCH) + ieee80211_rx_michael_mic_report(hdr, &rx); + goto next_sta; + } + + /* + * frame was destined for the previous interface + * so invoke RX handlers for it + */ + skb_new = skb_copy(skb, GFP_ATOMIC); + if (!skb_new) { + if (net_ratelimit()) + wiphy_debug(local->hw.wiphy, + "failed to copy multicast" + " frame for %s\n", + prev_sta->sdata->name); + goto next_sta; + } + ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, + skb_new); +next_sta: + prev_sta = sta; + } /* for all STA info */ + + if (prev_sta) { + rx.sta = prev_sta; + rx.sdata = prev_sta->sdata; + + rx.flags |= IEEE80211_RX_RA_MATCH; + prepares = prepare_for_handlers(rx.sdata, &rx, hdr); + if (!prepares) + prev_sta = NULL; + + if (prev_sta && status->flag & RX_FLAG_MMIC_ERROR) { + if (rx.flags & IEEE80211_RX_RA_MATCH) + ieee80211_rx_michael_mic_report(hdr, &rx); + prev_sta = NULL; } } - } + + + if (prev_sta) { + ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, skb); + return; + } else { + if (found_sta) { + dev_kfree_skb(skb); + return; + } + } + } /* if data frame */ if (!found_sta) { list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) @@ -2718,6 +2770,14 @@ next: if (!prepares) prev = NULL; + + if (prev && status->flag & RX_FLAG_MMIC_ERROR) { + rx.sdata = prev; + if (rx.flags & IEEE80211_RX_RA_MATCH) + ieee80211_rx_michael_mic_report(hdr, + &rx); + prev = NULL; + } } } if (prev) -- cgit v1.2.3 From 92e44948b2b3b2db8f39f17033f98ae2356156a5 Mon Sep 17 00:00:00 2001 From: Teemu Paasikivi Date: Fri, 24 Sep 2010 07:23:55 +0300 Subject: nl80211: Fix exit from nl80211_set_power_save If interface does not existk, when nl80211_set_power_save is called, (eg. module has been unloaded) it has been causing kernel panic. Added new goto target to avoid crash if get_rdev_dev_by_info_ifindex does not return dev and rdev pointers. Signed-off-by: Teemu Paasikivi Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f15b1af2c768..4ff827e8c362 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4990,7 +4990,7 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); if (err) - goto unlock_rdev; + goto unlock_rtnl; wdev = dev->ieee80211_ptr; @@ -5014,6 +5014,7 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) unlock_rdev: cfg80211_unlock_rdev(rdev); dev_put(dev); +unlock_rtnl: rtnl_unlock(); out: -- cgit v1.2.3 From 7c1e183186377e84e6f4e457be0514887f2df4ef Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 24 Sep 2010 15:52:49 -0400 Subject: Revert "mac80211: fix use-after-free" This reverts commit cd87a2d3a33d75a646f1aa1aa2ee5bf712d6f963. Author reports it conflicts with proper fixes, applied hereafter. Signed-off-by: John W. Linville --- net/mac80211/rx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 50c0803a63ba..29a582df6371 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2286,6 +2286,9 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, struct net_device *prev_dev = NULL; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + if (status->flag & RX_FLAG_INTERNAL_CMTR) + goto out_free_skb; + if (skb_headroom(skb) < sizeof(*rthdr) && pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) goto out_free_skb; @@ -2344,6 +2347,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, } else goto out_free_skb; + status->flag |= RX_FLAG_INTERNAL_CMTR; return; out_free_skb: -- cgit v1.2.3 From 20b01f80f72426e7ed2e773220da4357925383d5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Sep 2010 11:21:05 +0200 Subject: mac80211: remove prepare_for_handlers sdata argument The first argument to prepare_for_handlers is always the sdata that can just be stored in rx data directly (and even already is, in two of four code paths.) Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 29a582df6371..f59f6f51e39c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2513,10 +2513,10 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) /* main receive path */ -static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, - struct ieee80211_rx_data *rx, +static int prepare_for_handlers(struct ieee80211_rx_data *rx, struct ieee80211_hdr *hdr) { + struct ieee80211_sub_if_data *sdata = rx->sdata; struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); @@ -2656,7 +2656,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, rx.sdata = prev_sta->sdata; rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(rx.sdata, &rx, hdr); + prepares = prepare_for_handlers(&rx, hdr); if (!prepares) goto next_sta; @@ -2690,7 +2690,7 @@ next_sta: rx.sdata = prev_sta->sdata; rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(rx.sdata, &rx, hdr); + prepares = prepare_for_handlers(&rx, hdr); if (!prepares) prev_sta = NULL; @@ -2733,15 +2733,15 @@ next_sta: } rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(prev, &rx, hdr); + prepares = prepare_for_handlers(&rx, hdr); if (!prepares) goto next; if (status->flag & RX_FLAG_MMIC_ERROR) { - rx.sdata = prev; if (rx.flags & IEEE80211_RX_RA_MATCH) ieee80211_rx_michael_mic_report(hdr, &rx); @@ -2768,15 +2768,15 @@ next: if (prev) { rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(prev, &rx, hdr); + prepares = prepare_for_handlers(&rx, hdr); if (!prepares) prev = NULL; if (prev && status->flag & RX_FLAG_MMIC_ERROR) { - rx.sdata = prev; if (rx.flags & IEEE80211_RX_RA_MATCH) ieee80211_rx_michael_mic_report(hdr, &rx); -- cgit v1.2.3 From 4406c376895608375105013bf405ecac720ef558 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Sep 2010 11:21:06 +0200 Subject: mac80211: consolidate packet processing There are now four instances of vaguely the same code that does packet preparation, checking for MMIC errors and reporting them, and then invoking packet processing. Consolidate all of these. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 165 ++++++++++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 103 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f59f6f51e39c..13311f8960ab 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2443,18 +2443,13 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, } } -static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, - struct ieee80211_rx_data *rx, - struct sk_buff *skb) +static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) { struct sk_buff_head reorder_release; ieee80211_rx_result res = RX_DROP_MONITOR; __skb_queue_head_init(&reorder_release); - rx->skb = skb; - rx->sdata = sdata; - #define CALL_RXH(rxh) \ do { \ res = rxh(rx); \ @@ -2597,6 +2592,51 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 1; } +/* + * This function returns whether or not the SKB + * was destined for RX processing or not, which, + * if consume is true, is equivalent to whether + * or not the skb was consumed. + */ +static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, + struct sk_buff *skb, bool consume) +{ + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int prepares; + + rx->skb = skb; + rx->flags |= IEEE80211_RX_RA_MATCH; + prepares = prepare_for_handlers(rx, hdr); + + if (!prepares) + return false; + + if (status->flag & RX_FLAG_MMIC_ERROR) { + if (rx->flags & IEEE80211_RX_RA_MATCH) + ieee80211_rx_michael_mic_report(hdr, rx); + return false; + } + + if (!consume) { + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) { + if (net_ratelimit()) + wiphy_debug(local->hw.wiphy, + "failed to copy multicast frame for %s\n", + sdata->name); + return true; + } + + rx->skb = skb; + } + + ieee80211_invoke_rx_handlers(rx); + return true; +} + /* * This is the actual Rx frames handler. as it blongs to Rx path it must * be called with rcu_read_lock protection. @@ -2604,15 +2644,12 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_sub_if_data *sdata; struct ieee80211_hdr *hdr; __le16 fc; struct ieee80211_rx_data rx; - int prepares; - struct ieee80211_sub_if_data *prev = NULL; - struct sk_buff *skb_new; + struct ieee80211_sub_if_data *prev; struct sta_info *sta, *tmp, *prev_sta; bool found_sta = false; int err = 0; @@ -2645,8 +2682,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc)) { prev_sta = NULL; + for_each_sta_info(local, hdr->addr2, sta, tmp) { found_sta = true; + if (!prev_sta) { prev_sta = sta; continue; @@ -2654,65 +2693,23 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, rx.sta = prev_sta; rx.sdata = prev_sta->sdata; + ieee80211_prepare_and_rx_handle(&rx, skb, false); - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(&rx, hdr); - if (!prepares) - goto next_sta; - - if (status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, &rx); - goto next_sta; - } - - /* - * frame was destined for the previous interface - * so invoke RX handlers for it - */ - skb_new = skb_copy(skb, GFP_ATOMIC); - if (!skb_new) { - if (net_ratelimit()) - wiphy_debug(local->hw.wiphy, - "failed to copy multicast" - " frame for %s\n", - prev_sta->sdata->name); - goto next_sta; - } - ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, - skb_new); -next_sta: prev_sta = sta; - } /* for all STA info */ + } if (prev_sta) { rx.sta = prev_sta; rx.sdata = prev_sta->sdata; - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(&rx, hdr); - if (!prepares) - prev_sta = NULL; - - if (prev_sta && status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, &rx); - prev_sta = NULL; - } - } - - - if (prev_sta) { - ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, skb); - return; - } else { - if (found_sta) { - dev_kfree_skb(skb); + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) return; - } } - } /* if data frame */ + } + if (!found_sta) { + prev = NULL; + list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; @@ -2734,35 +2731,8 @@ next_sta: rx.sta = sta_info_get_bss(prev, hdr->addr2); rx.sdata = prev; + ieee80211_prepare_and_rx_handle(&rx, skb, false); - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(&rx, hdr); - - if (!prepares) - goto next; - - if (status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, - &rx); - goto next; - } - - /* - * frame was destined for the previous interface - * so invoke RX handlers for it - */ - - skb_new = skb_copy(skb, GFP_ATOMIC); - if (!skb_new) { - if (net_ratelimit()) - wiphy_debug(local->hw.wiphy, - "failed to copy multicast frame for %s\n", - prev->name); - goto next; - } - ieee80211_invoke_rx_handlers(prev, &rx, skb_new); -next: prev = sdata; } @@ -2770,24 +2740,13 @@ next: rx.sta = sta_info_get_bss(prev, hdr->addr2); rx.sdata = prev; - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(&rx, hdr); - - if (!prepares) - prev = NULL; - - if (prev && status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, - &rx); - prev = NULL; - } + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; } + } - if (prev) - ieee80211_invoke_rx_handlers(prev, &rx, skb); - else - dev_kfree_skb(skb); + + dev_kfree_skb(skb); } /* -- cgit v1.2.3 From 4b0dd98e70b6516c2c26f28091c2fb09f0ecf215 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Sep 2010 11:21:07 +0200 Subject: mac80211: clean up rx handling wrt. found_sta If a station was found, then we'll have exited the function already, so it is not necessary to have a variable keeping track of it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 56 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 13311f8960ab..2b6b4eab44dd 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2651,7 +2651,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct ieee80211_rx_data rx; struct ieee80211_sub_if_data *prev; struct sta_info *sta, *tmp, *prev_sta; - bool found_sta = false; int err = 0; fc = ((struct ieee80211_hdr *)skb->data)->frame_control; @@ -2684,8 +2683,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, prev_sta = NULL; for_each_sta_info(local, hdr->addr2, sta, tmp) { - found_sta = true; - if (!prev_sta) { prev_sta = sta; continue; @@ -2707,43 +2704,40 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, } } - if (!found_sta) { - prev = NULL; - - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) - continue; - - if (sdata->vif.type == NL80211_IFTYPE_MONITOR || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - continue; + prev = NULL; - /* - * frame is destined for this interface, but if it's - * not also for the previous one we handle that after - * the loop to avoid copying the SKB once too much - */ + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) + continue; - if (!prev) { - prev = sdata; - continue; - } + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; - rx.sta = sta_info_get_bss(prev, hdr->addr2); - rx.sdata = prev; - ieee80211_prepare_and_rx_handle(&rx, skb, false); + /* + * frame is destined for this interface, but if it's + * not also for the previous one we handle that after + * the loop to avoid copying the SKB once too much + */ + if (!prev) { prev = sdata; + continue; } - if (prev) { - rx.sta = sta_info_get_bss(prev, hdr->addr2); - rx.sdata = prev; + rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; + ieee80211_prepare_and_rx_handle(&rx, skb, false); - if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) - return; - } + prev = sdata; + } + + if (prev) { + rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; } dev_kfree_skb(skb); -- cgit v1.2.3 From 4080c7cdc23f26c6e6166a70f50fa43814552d81 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Sep 2010 11:21:08 +0200 Subject: mac80211: fix release_reorder_timeout in scan Even if the reorder timeout timer fires while scanning, the frames weren't received during scanning and therefore shouldn't be dropped. To implement this, changes to the passive scan RX handler simplify understanding it, because it currently checks HW_SCANNING independently of a packet's in-scan receive status (which doesn't make a big difference, since scan_rx() will only pick up probe responses and beacons, which can't be aggregated.) Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2b6b4eab44dd..8c666e9e8fb0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -389,24 +389,22 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) struct ieee80211_local *local = rx->local; struct sk_buff *skb = rx->skb; - if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) + if (likely(!(rx->flags & IEEE80211_RX_IN_SCAN))) + return RX_CONTINUE; + + if (test_bit(SCAN_HW_SCANNING, &local->scanning)) return ieee80211_scan_rx(rx->sdata, skb); - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && - (rx->flags & IEEE80211_RX_IN_SCAN))) { + if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { /* drop all the other packets during a software scan anyway */ if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) dev_kfree_skb(skb); return RX_QUEUED; } - if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { - /* scanning finished during invoking of handlers */ - I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); - return RX_DROP_UNUSABLE; - } - - return RX_CONTINUE; + /* scanning finished during invoking of handlers */ + I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); + return RX_DROP_UNUSABLE; } @@ -2495,10 +2493,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) rx.queue = tid; rx.flags |= IEEE80211_RX_RA_MATCH; - if (unlikely(test_bit(SCAN_HW_SCANNING, &sta->local->scanning) || - test_bit(SCAN_OFF_CHANNEL, &sta->local->scanning))) - rx.flags |= IEEE80211_RX_IN_SCAN; - spin_lock(&tid_agg_rx->reorder_lock); ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); spin_unlock(&tid_agg_rx->reorder_lock); -- cgit v1.2.3 From 554891e63a29af35cc6bb403ef34e319518114d0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Sep 2010 12:38:25 +0200 Subject: mac80211: move packet flags into packet commit 8c0c709eea5cbab97fb464cd68b06f24acc58ee1 Author: Johannes Berg Date: Wed Nov 25 17:46:15 2009 +0100 mac80211: move cmntr flag out of rx flags moved the CMNTR flag into the skb RX flags for some aggregation cleanups, but this was wrong since the optimisation this flag tried to make requires that it is kept across the processing of multiple interfaces -- which isn't true for flags in the skb. The patch not only broke the optimisation, it also introduced a bug: under some (common!) circumstances the flag will be set on an already freed skb! However, investigating this in more detail, I found that most of the flags that we set should be per packet, _except_ for this one, due to a-MPDU processing. Additionally, the flags used for processing (currently just this one) need to be reset before processing a new packet. Since we haven't actually seen bugs reported as a result of the wrong flags handling (which is not too surprising -- the only real bug case I can come up with is an a-MSDU contained in an a-MPDU), I'll make a different fix for rc. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 6 +-- net/mac80211/ieee80211_i.h | 38 +++++++++++++---- net/mac80211/rx.c | 102 +++++++++++++++++++++++++-------------------- net/mac80211/wpa.c | 2 +- 4 files changed, 91 insertions(+), 57 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 73469d8b64bb..fe8b9dae4dee 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -581,9 +581,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_SHORT_GI: Short guard interval was used - * @RX_FLAG_INTERNAL_CMTR: set internally after frame was reported - * on cooked monitor to avoid double-reporting it for multiple - * virtual interfaces */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = 1<<0, @@ -597,7 +594,6 @@ enum mac80211_rx_flags { RX_FLAG_HT = 1<<9, RX_FLAG_40MHZ = 1<<10, RX_FLAG_SHORT_GI = 1<<11, - RX_FLAG_INTERNAL_CMTR = 1<<12, }; /** @@ -618,6 +614,7 @@ enum mac80211_rx_flags { * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) * @flag: %RX_FLAG_* + * @rx_flags: internal RX flags for mac80211 */ struct ieee80211_rx_status { u64 mactime; @@ -627,6 +624,7 @@ struct ieee80211_rx_status { int antenna; int rate_idx; int flag; + unsigned int rx_flags; }; /** diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 40f747273389..945fbf29719d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -159,13 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result; #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) #define RX_QUEUED ((__force ieee80211_rx_result) 3u) -#define IEEE80211_RX_IN_SCAN BIT(0) -/* frame is destined to interface currently processed (incl. multicast frames) */ -#define IEEE80211_RX_RA_MATCH BIT(1) -#define IEEE80211_RX_AMSDU BIT(2) -#define IEEE80211_RX_FRAGMENTED BIT(3) -#define IEEE80211_MALFORMED_ACTION_FRM BIT(4) -/* only add flags here that do not change with subframes of an aMPDU */ +/** + * enum ieee80211_packet_rx_flags - packet RX flags + * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed + * (incl. multicast frames) + * @IEEE80211_RX_IN_SCAN: received while scanning + * @IEEE80211_RX_FRAGMENTED: fragmented frame + * @IEEE80211_RX_AMSDU: a-MSDU packet + * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed + * + * These are per-frame flags that are attached to a frame in the + * @rx_flags field of &struct ieee80211_rx_status. + */ +enum ieee80211_packet_rx_flags { + IEEE80211_RX_IN_SCAN = BIT(0), + IEEE80211_RX_RA_MATCH = BIT(1), + IEEE80211_RX_FRAGMENTED = BIT(2), + IEEE80211_RX_AMSDU = BIT(3), + IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), +}; + +/** + * enum ieee80211_rx_flags - RX data flags + * + * @IEEE80211_RX_CMNTR: received on cooked monitor already + * + * These flags are used across handling multiple interfaces + * for a single frame. + */ +enum ieee80211_rx_flags { + IEEE80211_RX_CMNTR = BIT(0), +}; struct ieee80211_rx_data { struct sk_buff *skb; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8c666e9e8fb0..0b0e83ebe3d5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); int tid; /* does the frame have a qos control field? */ @@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) /* frame has qos control */ tid = *qc & IEEE80211_QOS_CTL_TID_MASK; if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) - rx->flags |= IEEE80211_RX_AMSDU; - else - rx->flags &= ~IEEE80211_RX_AMSDU; + status->rx_flags |= IEEE80211_RX_AMSDU; } else { /* * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): @@ -387,9 +386,10 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) { struct ieee80211_local *local = rx->local; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); struct sk_buff *skb = rx->skb; - if (likely(!(rx->flags & IEEE80211_RX_IN_SCAN))) + if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) return RX_CONTINUE; if (test_bit(SCAN_HW_SCANNING, &local->scanning)) @@ -783,13 +783,14 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_check(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { if (unlikely(ieee80211_has_retry(hdr->frame_control) && rx->sta->last_seq_ctrl[rx->queue] == hdr->seq_ctrl)) { - if (rx->flags & IEEE80211_RX_RA_MATCH) { + if (status->rx_flags & IEEE80211_RX_RA_MATCH) { rx->local->dot11FrameDuplicateCount++; rx->sta->num_duplicates++; } @@ -822,7 +823,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) if ((!ieee80211_has_fromds(hdr->frame_control) && !ieee80211_has_tods(hdr->frame_control) && ieee80211_is_data(hdr->frame_control)) || - !(rx->flags & IEEE80211_RX_RA_MATCH)) { + !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { /* Drop IBSS frames and frames for other hosts * silently. */ return RX_DROP_MONITOR; @@ -879,7 +880,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) * No point in finding a key and decrypting if the frame is neither * addressed to us nor a multicast frame. */ - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; /* start without a key */ @@ -1112,7 +1113,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->last_rx = jiffies; } - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) @@ -1269,6 +1270,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) unsigned int frag, seq; struct ieee80211_fragment_entry *entry; struct sk_buff *skb; + struct ieee80211_rx_status *status; hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; @@ -1368,7 +1370,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) } /* Complete frame has been reassembled - process it now */ - rx->flags |= IEEE80211_RX_FRAGMENTED; + status = IEEE80211_SKB_RXCB(rx->skb); + status->rx_flags |= IEEE80211_RX_FRAGMENTED; out: if (rx->sta) @@ -1385,9 +1388,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) { struct ieee80211_sub_if_data *sdata = rx->sdata; __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || - !(rx->flags & IEEE80211_RX_RA_MATCH))) + !(status->rx_flags & IEEE80211_RX_RA_MATCH))) return RX_CONTINUE; if ((sdata->vif.type != NL80211_IFTYPE_AP) && @@ -1548,6 +1552,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) struct sk_buff *skb, *xmit_skb; struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; struct sta_info *dsta; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); skb = rx->skb; xmit_skb = NULL; @@ -1555,7 +1560,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) if ((sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && - (rx->flags & IEEE80211_RX_RA_MATCH) && + (status->rx_flags & IEEE80211_RX_RA_MATCH) && (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { if (is_multicast_ether_addr(ehdr->h_dest)) { /* @@ -1632,6 +1637,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; struct sk_buff_head frame_list; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); if (unlikely(!ieee80211_is_data(fc))) return RX_CONTINUE; @@ -1639,7 +1645,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) if (unlikely(!ieee80211_is_data_present(fc))) return RX_DROP_MONITOR; - if (!(rx->flags & IEEE80211_RX_AMSDU)) + if (!(status->rx_flags & IEEE80211_RX_AMSDU)) return RX_CONTINUE; if (ieee80211_has_a4(hdr->frame_control) && @@ -1690,6 +1696,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) struct sk_buff *skb = rx->skb, *fwd_skb; struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -1735,7 +1742,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_hdr->ttl--; - if (rx->flags & IEEE80211_RX_RA_MATCH) { + if (status->rx_flags & IEEE80211_RX_RA_MATCH) { if (!mesh_hdr->ttl) IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, dropped_frames_ttl); @@ -1945,6 +1952,7 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); /* * From here on, look only at management frames. @@ -1957,7 +1965,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) if (!ieee80211_is_mgmt(mgmt->frame_control)) return RX_DROP_MONITOR; - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_MONITOR; if (ieee80211_drop_unencrypted_mgmt(rx)) @@ -1972,6 +1980,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); int len = rx->skb->len; if (!ieee80211_is_action(mgmt->frame_control)) @@ -1984,7 +1993,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) return RX_DROP_UNUSABLE; - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_UNUSABLE; switch (mgmt->u.action.category) { @@ -2080,7 +2089,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) return RX_CONTINUE; invalid: - rx->flags |= IEEE80211_MALFORMED_ACTION_FRM; + status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM; /* will return in the next handlers */ return RX_CONTINUE; @@ -2102,10 +2111,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) static ieee80211_rx_result debug_noinline ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) { - struct ieee80211_rx_status *status; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); /* skip known-bad action frames and return them in the next handler */ - if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM) + if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) return RX_CONTINUE; /* @@ -2114,7 +2123,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) * so userspace can register for those to know whether ones * it transmitted were processed or returned. */ - status = IEEE80211_SKB_RXCB(rx->skb); if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, rx->skb->data, rx->skb->len, @@ -2136,6 +2144,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; struct sk_buff *nskb; struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); if (!ieee80211_is_action(mgmt->frame_control)) return RX_CONTINUE; @@ -2150,7 +2159,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. */ - if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) && + if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) && (sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; @@ -2284,8 +2293,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, struct net_device *prev_dev = NULL; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - if (status->flag & RX_FLAG_INTERNAL_CMTR) + /* + * If cooked monitor has been processed already, then + * don't do it again. If not, set the flag. + */ + if (rx->flags & IEEE80211_RX_CMNTR) goto out_free_skb; + rx->flags |= IEEE80211_RX_CMNTR; if (skb_headroom(skb) < sizeof(*rthdr) && pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) @@ -2341,12 +2355,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, if (prev_dev) { skb->dev = prev_dev; netif_receive_skb(skb); - skb = NULL; - } else - goto out_free_skb; - - status->flag |= RX_FLAG_INTERNAL_CMTR; - return; + return; + } out_free_skb: dev_kfree_skb(skb); @@ -2407,6 +2417,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, * same TID from the same station */ rx->skb = skb; + rx->flags = 0; CALL_RXH(ieee80211_rx_h_decrypt) CALL_RXH(ieee80211_rx_h_check_more_data) @@ -2477,7 +2488,12 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) { struct sk_buff_head frames; - struct ieee80211_rx_data rx = { }; + struct ieee80211_rx_data rx = { + .sta = sta, + .sdata = sta->sdata, + .local = sta->local, + .queue = tid, + }; struct tid_ampdu_rx *tid_agg_rx; tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); @@ -2486,13 +2502,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) __skb_queue_head_init(&frames); - /* construct rx struct */ - rx.sta = sta; - rx.sdata = sta->sdata; - rx.local = sta->local; - rx.queue = tid; - rx.flags |= IEEE80211_RX_RA_MATCH; - spin_lock(&tid_agg_rx->reorder_lock); ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); spin_unlock(&tid_agg_rx->reorder_lock); @@ -2519,7 +2528,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_ADHOC: @@ -2529,15 +2538,15 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 1; } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { - if (!(rx->flags & IEEE80211_RX_IN_SCAN)) + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!multicast && compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!rx->sta) { int rate_idx; if (status->flag & RX_FLAG_HT) @@ -2555,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_AP_VLAN: @@ -2566,9 +2575,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { - if (!(rx->flags & IEEE80211_RX_IN_SCAN)) + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_WDS: @@ -2602,14 +2611,14 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, int prepares; rx->skb = skb; - rx->flags |= IEEE80211_RX_RA_MATCH; + status->rx_flags |= IEEE80211_RX_RA_MATCH; prepares = prepare_for_handlers(rx, hdr); if (!prepares) return false; if (status->flag & RX_FLAG_MMIC_ERROR) { - if (rx->flags & IEEE80211_RX_RA_MATCH) + if (status->rx_flags & IEEE80211_RX_RA_MATCH) ieee80211_rx_michael_mic_report(hdr, rx); return false; } @@ -2638,6 +2647,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct sk_buff *skb) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_sub_if_data *sdata; struct ieee80211_hdr *hdr; @@ -2657,7 +2667,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || test_bit(SCAN_OFF_CHANNEL, &local->scanning))) - rx.flags |= IEEE80211_RX_IN_SCAN; + status->rx_flags |= IEEE80211_RX_IN_SCAN; if (ieee80211_is_mgmt(fc)) err = skb_linearize(skb); @@ -2808,6 +2818,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) } } + status->rx_flags = 0; + /* * key references and virtual interfaces are protected using RCU * and this requires that we are in a read-side RCU section during diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 43882b36da55..bee230d8fd11 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) key = &rx->key->conf.key[key_offset]; michael_mic(key, hdr, data, data_len, mic); if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_UNUSABLE; mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, -- cgit v1.2.3 From e2b626248b0799bd14be40ce290c6681a8419512 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 24 Sep 2010 17:58:50 +0530 Subject: ath9k_htc: Fix TKIP disconnect failure with HTC drivers The following commit removed splitmic. But forgot to add ATH_CRYPT_CAP_MIC_COMBINED flag for HTC drivers which causes TKIP to fail. Author: Bruno Randolf Date: Wed Sep 8 16:04:54 2010 +0900 ath/ath9k: Replace common->splitmic with a flag Replace common->splitmic with ATH_CRYPT_CAP_MIC_COMBINED flag. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 33850c952314..b100db2766cf 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -561,6 +561,9 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) common->keymax = ATH_KEYMAX; } + if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; + /* * Reset the key cache since some parts do not * reset the contents on initial power up. -- cgit v1.2.3 From 8d98efa84b790bdd62248eb0dfff17e9baf5c844 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Sun, 26 Sep 2010 19:07:59 +0000 Subject: Phonet: Implement Pipe Controller to support Nokia Slim Modems Phonet stack assumes the presence of Pipe Controller, either in Modem or on Application Processing Engine user-space for the Pipe data. Nokia Slim Modems like WG2.5 used in ST-Ericsson U8500 platform do not implement Pipe controller in them. This patch adds Pipe Controller implemenation to Phonet stack to support Pipe data over Phonet stack for Nokia Slim Modems. Signed-off-by: Kumar Sanghvi Acked-by: Linus Walleij Signed-off-by: David S. Miller --- include/linux/phonet.h | 5 + include/net/phonet/pep.h | 21 +++ net/phonet/Kconfig | 11 ++ net/phonet/pep.c | 448 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 479 insertions(+), 6 deletions(-) diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 85e14a83283b..96f5625d62fa 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -36,6 +36,11 @@ /* Socket options for SOL_PNPIPE level */ #define PNPIPE_ENCAP 1 #define PNPIPE_IFINDEX 2 +#define PNPIPE_CREATE 3 +#define PNPIPE_ENABLE 4 +#define PNPIPE_DISABLE 5 +#define PNPIPE_DESTROY 6 +#define PNPIPE_INQ 7 #define PNADDR_ANY 0 #define PNADDR_BROADCAST 0xFC diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h index 37f23dc05de8..def6cfa3f451 100644 --- a/include/net/phonet/pep.h +++ b/include/net/phonet/pep.h @@ -45,6 +45,10 @@ struct pep_sock { u8 tx_fc; /* TX flow control */ u8 init_enable; /* auto-enable at creation */ u8 aligned; +#ifdef CONFIG_PHONET_PIPECTRLR + u16 remote_pep; + u8 pipe_state; +#endif }; static inline struct pep_sock *pep_sk(struct sock *sk) @@ -165,4 +169,21 @@ enum { PEP_IND_READY, }; +#ifdef CONFIG_PHONET_PIPECTRLR +#define PNS_PEP_CONNECT_UTID 0x02 +#define PNS_PIPE_CREATED_IND_UTID 0x04 +#define PNS_PIPE_ENABLE_UTID 0x0A +#define PNS_PIPE_ENABLED_IND_UTID 0x0C +#define PNS_PIPE_DISABLE_UTID 0x0F +#define PNS_PIPE_DISABLED_IND_UTID 0x11 +#define PNS_PEP_DISCONNECT_UTID 0x06 + +/* Used for tracking state of a pipe */ +enum { + PIPE_IDLE, + PIPE_DISABLED, + PIPE_ENABLED, +}; +#endif /* CONFIG_PHONET_PIPECTRLR */ + #endif diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig index 6ec7d55b1769..901956ada9c8 100644 --- a/net/phonet/Kconfig +++ b/net/phonet/Kconfig @@ -14,3 +14,14 @@ config PHONET To compile this driver as a module, choose M here: the module will be called phonet. If unsure, say N. + +config PHONET_PIPECTRLR + bool "Phonet Pipe Controller" + depends on PHONET + default N + help + The Pipe Controller implementation in Phonet stack to support Pipe + data with Nokia Slim modems like WG2.5 used on ST-Ericsson U8500 + platform. + + If unsure, say N. diff --git a/net/phonet/pep.c b/net/phonet/pep.c index d0e7eb24c8b9..7bf23cf36b02 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -88,6 +88,15 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, const struct pnpipehdr *oph = pnp_hdr(oskb); struct pnpipehdr *ph; struct sk_buff *skb; +#ifdef CONFIG_PHONET_PIPECTRLR + const struct phonethdr *hdr = pn_hdr(oskb); + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = hdr->pn_sdev, + .spn_obj = hdr->pn_sobj, + }; +#endif skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); if (!skb) @@ -105,10 +114,271 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, ph->pipe_handle = oph->pipe_handle; ph->error_code = code; +#ifdef CONFIG_PHONET_PIPECTRLR + return pn_skb_send(sk, skb, &spn); +#else return pn_skb_send(sk, skb, &pipe_srv); +#endif } #define PAD 0x00 + +#ifdef CONFIG_PHONET_PIPECTRLR +static u8 pipe_negotiate_fc(u8 *host_fc, u8 *remote_fc, int len) +{ + int i, j; + u8 base_fc, final_fc; + + for (i = 0; i < len; i++) { + base_fc = host_fc[i]; + for (j = 0; j < len; j++) { + if (remote_fc[j] == base_fc) { + final_fc = base_fc; + goto done; + } + } + } + return -EINVAL; + +done: + return final_fc; + +} + +static int pipe_get_flow_info(struct sock *sk, struct sk_buff *skb, + u8 *pref_rx_fc, u8 *req_tx_fc) +{ + struct pnpipehdr *hdr; + u8 n_sb; + + if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) + return -EINVAL; + + hdr = pnp_hdr(skb); + n_sb = hdr->data[4]; + + __skb_pull(skb, sizeof(*hdr) + 4); + while (n_sb > 0) { + u8 type, buf[3], len = sizeof(buf); + u8 *data = pep_get_sb(skb, &type, &len, buf); + + if (data == NULL) + return -EINVAL; + + switch (type) { + case PN_PIPE_SB_REQUIRED_FC_TX: + if (len < 3 || (data[2] | data[3] | data[4]) > 3) + break; + req_tx_fc[0] = data[2]; + req_tx_fc[1] = data[3]; + req_tx_fc[2] = data[4]; + break; + + case PN_PIPE_SB_PREFERRED_FC_RX: + if (len < 3 || (data[2] | data[3] | data[4]) > 3) + break; + pref_rx_fc[0] = data[2]; + pref_rx_fc[1] = data[3]; + pref_rx_fc[2] = data[4]; + break; + + } + n_sb--; + } + return 0; +} + +static int pipe_handler_send_req(struct sock *sk, u16 dobj, u8 utid, + u8 msg_id, u8 p_handle, gfp_t priority) +{ + int len; + struct pnpipehdr *ph; + struct sk_buff *skb; + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = pn_dev(dobj), + .spn_obj = pn_obj(dobj), + }; + + static const u8 data[4] = { + PAD, PAD, PAD, PAD, + }; + + switch (msg_id) { + case PNS_PEP_CONNECT_REQ: + len = sizeof(data); + break; + + case PNS_PEP_DISCONNECT_REQ: + case PNS_PEP_ENABLE_REQ: + case PNS_PEP_DISABLE_REQ: + len = 0; + break; + + default: + return -EINVAL; + } + + skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + if (len) { + __skb_put(skb, len); + skb_copy_to_linear_data(skb, data, len); + } + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = p_handle; + ph->error_code = PN_PIPE_NO_ERROR; + + return pn_skb_send(sk, skb, &spn); +} + +static int pipe_handler_send_created_ind(struct sock *sk, u16 dobj, + u8 utid, u8 p_handle, u8 msg_id, u8 tx_fc, u8 rx_fc) +{ + int err_code; + struct pnpipehdr *ph; + struct sk_buff *skb; + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = pn_dev(dobj), + .spn_obj = pn_obj(dobj), + }; + + static u8 data[4] = { + 0x03, 0x04, + }; + data[2] = tx_fc; + data[3] = rx_fc; + + /* + * actually, below is number of sub-blocks and not error code. + * Pipe_created_ind message format does not have any + * error code field. However, the Phonet stack will always send + * an error code as part of pnpipehdr. So, use that err_code to + * specify the number of sub-blocks. + */ + err_code = 0x01; + + skb = alloc_skb(MAX_PNPIPE_HEADER + sizeof(data), GFP_ATOMIC); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_put(skb, sizeof(data)); + skb_copy_to_linear_data(skb, data, sizeof(data)); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = p_handle; + ph->error_code = err_code; + + return pn_skb_send(sk, skb, &spn); +} + +static int pipe_handler_send_ind(struct sock *sk, u16 dobj, u8 utid, + u8 p_handle, u8 msg_id) +{ + int err_code; + struct pnpipehdr *ph; + struct sk_buff *skb; + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = pn_dev(dobj), + .spn_obj = pn_obj(dobj), + }; + + /* + * actually, below is a filler. + * Pipe_enabled/disabled_ind message format does not have any + * error code field. However, the Phonet stack will always send + * an error code as part of pnpipehdr. So, use that err_code to + * specify the filler value. + */ + err_code = 0x0; + + skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = p_handle; + ph->error_code = err_code; + + return pn_skb_send(sk, skb, &spn); +} + +static int pipe_handler_enable_pipe(struct sock *sk, int cmd) +{ + int ret; + struct pep_sock *pn = pep_sk(sk); + + switch (cmd) { + case PNPIPE_ENABLE: + ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, + PNS_PIPE_ENABLE_UTID, PNS_PEP_ENABLE_REQ, + pn->pipe_handle, GFP_ATOMIC); + break; + + case PNPIPE_DISABLE: + ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, + PNS_PIPE_DISABLE_UTID, PNS_PEP_DISABLE_REQ, + pn->pipe_handle, GFP_ATOMIC); + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int pipe_handler_create_pipe(struct sock *sk, int pipe_handle, int cmd) +{ + int ret; + struct pep_sock *pn = pep_sk(sk); + + switch (cmd) { + case PNPIPE_CREATE: + ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, + PNS_PEP_CONNECT_UTID, PNS_PEP_CONNECT_REQ, + pipe_handle, GFP_ATOMIC); + break; + + case PNPIPE_DESTROY: + ret = pipe_handler_send_req(sk, pn->remote_pep, + PNS_PEP_DISCONNECT_UTID, + PNS_PEP_DISCONNECT_REQ, + pn->pipe_handle, GFP_ATOMIC); + break; + + default: + ret = -EINVAL; + } + + return ret; +} +#endif + static int pep_accept_conn(struct sock *sk, struct sk_buff *skb) { static const u8 data[20] = { @@ -173,6 +443,14 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; struct sk_buff *skb; +#ifdef CONFIG_PHONET_PIPECTRLR + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = pn_dev(pn->remote_pep), + .spn_obj = pn_obj(pn->remote_pep), + }; +#endif skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority); if (!skb) @@ -192,7 +470,11 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) ph->data[3] = PAD; ph->data[4] = status; +#ifdef CONFIG_PHONET_PIPECTRLR + return pn_skb_send(sk, skb, &spn); +#else return pn_skb_send(sk, skb, &pipe_srv); +#endif } /* Send our RX flow control information to the sender. @@ -308,6 +590,12 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) struct pnpipehdr *hdr = pnp_hdr(skb); struct sk_buff_head *queue; int err = 0; +#ifdef CONFIG_PHONET_PIPECTRLR + struct phonethdr *ph = pn_hdr(skb); + static u8 host_pref_rx_fc[3], host_req_tx_fc[3]; + u8 remote_pref_rx_fc[3], remote_req_tx_fc[3]; + u8 negotiated_rx_fc, negotiated_tx_fc; +#endif BUG_ON(sk->sk_state == TCP_CLOSE_WAIT); @@ -316,6 +604,40 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_CONNECT_RESP: + if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && + (ph->pn_sobj == pn_obj(pn->remote_pep))) { + pipe_get_flow_info(sk, skb, remote_pref_rx_fc, + remote_req_tx_fc); + + negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc, + host_pref_rx_fc, + sizeof(host_pref_rx_fc)); + negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc, + remote_pref_rx_fc, + sizeof(host_pref_rx_fc)); + + pn->pipe_state = PIPE_DISABLED; + pipe_handler_send_created_ind(sk, pn->remote_pep, + PNS_PIPE_CREATED_IND_UTID, + pn->pipe_handle, PNS_PIPE_CREATED_IND, + negotiated_tx_fc, negotiated_rx_fc); + pipe_handler_send_created_ind(sk, pn->pn_sk.sobject, + PNS_PIPE_CREATED_IND_UTID, + pn->pipe_handle, PNS_PIPE_CREATED_IND, + negotiated_tx_fc, negotiated_rx_fc); + } else { + pipe_handler_send_req(sk, pn->remote_pep, + PNS_PEP_CONNECT_UTID, + PNS_PEP_CONNECT_REQ, pn->pipe_handle, + GFP_ATOMIC); + pipe_get_flow_info(sk, skb, host_pref_rx_fc, + host_req_tx_fc); + } + break; +#endif + case PNS_PEP_DISCONNECT_REQ: pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); sk->sk_state = TCP_CLOSE_WAIT; @@ -323,11 +645,41 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) sk->sk_state_change(sk); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_DISCONNECT_RESP: + pn->pipe_state = PIPE_IDLE; + pipe_handler_send_req(sk, pn->pn_sk.sobject, + PNS_PEP_DISCONNECT_UTID, + PNS_PEP_DISCONNECT_REQ, pn->pipe_handle, + GFP_KERNEL); + break; +#endif + case PNS_PEP_ENABLE_REQ: /* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */ pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_ENABLE_RESP: + if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && + (ph->pn_sobj == pn_obj(pn->remote_pep))) { + pn->pipe_state = PIPE_ENABLED; + pipe_handler_send_ind(sk, pn->remote_pep, + PNS_PIPE_ENABLED_IND_UTID, + pn->pipe_handle, PNS_PIPE_ENABLED_IND); + pipe_handler_send_ind(sk, pn->pn_sk.sobject, + PNS_PIPE_ENABLED_IND_UTID, + pn->pipe_handle, PNS_PIPE_ENABLED_IND); + } else + pipe_handler_send_req(sk, pn->remote_pep, + PNS_PIPE_ENABLE_UTID, + PNS_PEP_ENABLE_REQ, pn->pipe_handle, + GFP_KERNEL); + + break; +#endif + case PNS_PEP_RESET_REQ: switch (hdr->state_after_reset) { case PN_PIPE_DISABLE: @@ -346,6 +698,27 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_DISABLE_RESP: + if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && + (ph->pn_sobj == pn_obj(pn->remote_pep))) { + pn->pipe_state = PIPE_DISABLED; + pipe_handler_send_ind(sk, pn->remote_pep, + PNS_PIPE_DISABLED_IND_UTID, + pn->pipe_handle, + PNS_PIPE_DISABLED_IND); + pipe_handler_send_ind(sk, pn->pn_sk.sobject, + PNS_PIPE_DISABLED_IND_UTID, + pn->pipe_handle, + PNS_PIPE_DISABLED_IND); + } else + pipe_handler_send_req(sk, pn->remote_pep, + PNS_PIPE_DISABLE_UTID, + PNS_PEP_DISABLE_REQ, pn->pipe_handle, + GFP_KERNEL); + break; +#endif + case PNS_PEP_CTRL_REQ: if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) { atomic_inc(&sk->sk_drops); @@ -519,6 +892,9 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; newpn->init_enable = enabled; newpn->aligned = aligned; +#ifdef CONFIG_PHONET_PIPECTRLR + newpn->remote_pep = pn->remote_pep; +#endif BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); skb_queue_head(&newsk->sk_receive_queue, skb); @@ -781,6 +1157,10 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, { struct pep_sock *pn = pep_sk(sk); int val = 0, err = 0; +#ifdef CONFIG_PHONET_PIPECTRLR + int remote_pep; + int pipe_handle; +#endif if (level != SOL_PNPIPE) return -ENOPROTOOPT; @@ -791,6 +1171,48 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, lock_sock(sk); switch (optname) { +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_CREATE: + if (val) { + if (pn->pipe_state > PIPE_IDLE) { + err = -EFAULT; + break; + } + remote_pep = val & 0xFFFF; + pipe_handle = (val >> 16) & 0xFF; + pn->remote_pep = remote_pep; + err = pipe_handler_create_pipe(sk, pipe_handle, + PNPIPE_CREATE); + break; + } + + case PNPIPE_ENABLE: + if (pn->pipe_state != PIPE_DISABLED) { + err = -EFAULT; + break; + } + err = pipe_handler_enable_pipe(sk, PNPIPE_ENABLE); + break; + + case PNPIPE_DISABLE: + if (pn->pipe_state != PIPE_ENABLED) { + err = -EFAULT; + break; + } + + err = pipe_handler_enable_pipe(sk, PNPIPE_DISABLE); + break; + + case PNPIPE_DESTROY: + if (pn->pipe_state < PIPE_DISABLED) { + err = -EFAULT; + break; + } + + err = pipe_handler_create_pipe(sk, 0x0, PNPIPE_DESTROY); + break; +#endif + case PNPIPE_ENCAP: if (val && val != PNPIPE_ENCAP_IP) { err = -EINVAL; @@ -840,6 +1262,13 @@ static int pep_getsockopt(struct sock *sk, int level, int optname, case PNPIPE_ENCAP: val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE; break; + +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_INQ: + val = pn->pipe_state; + break; +#endif + case PNPIPE_IFINDEX: val = pn->ifindex; break; @@ -859,7 +1288,14 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) { struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; - int err; +#ifdef CONFIG_PHONET_PIPECTRLR + struct sockaddr_pn spn = { + .spn_family = AF_PHONET, + .spn_resource = 0xD9, + .spn_dev = pn_dev(pn->remote_pep), + .spn_obj = pn_obj(pn->remote_pep), + }; +#endif if (pn_flow_safe(pn->tx_fc) && !atomic_add_unless(&pn->tx_credits, -1, 0)) { @@ -877,11 +1313,11 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) } else ph->message_id = PNS_PIPE_DATA; ph->pipe_handle = pn->pipe_handle; - - err = pn_skb_send(sk, skb, &pipe_srv); - if (err && pn_flow_safe(pn->tx_fc)) - atomic_inc(&pn->tx_credits); - return err; +#ifdef CONFIG_PHONET_PIPECTRLR + return pn_skb_send(sk, skb, &spn); +#else + return pn_skb_send(sk, skb, &pipe_srv); +#endif } static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, -- cgit v1.2.3 From af5ef241133b602a77b682009f112e7c3f7604e5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 26 Sep 2010 22:47:09 +0000 Subject: vlan: use this_cpu_ptr() in vlan_skb_recv() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 94a1feddeb49..f6fbcc0f1af9 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -177,8 +177,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } else { skb->dev = vlan_dev; - rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats, - smp_processor_id()); + rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats); + u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; rx_stats->rx_bytes += skb->len; -- cgit v1.2.3 From 290b895e0ba4552dfcfc4bd35759c192345b934a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 00:33:35 +0000 Subject: tunnels: prepare percpu accounting Tunnels are going to use percpu for their accounting. They are going to use a new tstats field in net_device. skb_tunnel_rx() is changed to be a wrapper around __skb_tunnel_rx() IPTUNNEL_XMIT() is changed to be a wrapper around __IPTUNNEL_XMIT() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + include/net/dst.h | 24 +++++++++++++++++++----- include/net/ipip.h | 12 +++++++----- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 01bd4c82d982..83de0eb7a071 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1053,6 +1053,7 @@ struct net_device { union { void *ml_priv; struct pcpu_lstats __percpu *lstats; /* loopback stats */ + struct pcpu_tstats __percpu *tstats; /* tunnel stats */ }; /* GARP */ struct garp_port *garp_port; diff --git a/include/net/dst.h b/include/net/dst.h index 02386505033d..aa53fbc34b2b 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -227,6 +227,23 @@ static inline void skb_dst_force(struct sk_buff *skb) } +/** + * __skb_tunnel_rx - prepare skb for rx reinsert + * @skb: buffer + * @dev: tunnel device + * + * After decapsulation, packet is going to re-enter (netif_rx()) our stack, + * so make some cleanups. (no accounting done) + */ +static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) +{ + skb->dev = dev; + skb->rxhash = 0; + skb_set_queue_mapping(skb, 0); + skb_dst_drop(skb); + nf_reset(skb); +} + /** * skb_tunnel_rx - prepare skb for rx reinsert * @skb: buffer @@ -234,17 +251,14 @@ static inline void skb_dst_force(struct sk_buff *skb) * * After decapsulation, packet is going to re-enter (netif_rx()) our stack, * so make some cleanups, and perform accounting. + * Note: this accounting is not SMP safe. */ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) { - skb->dev = dev; /* TODO : stats should be SMP safe */ dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; - skb->rxhash = 0; - skb_set_queue_mapping(skb, 0); - skb_dst_drop(skb); - nf_reset(skb); + __skb_tunnel_rx(skb, dev); } /* Children define the path of the packet through the diff --git a/include/net/ipip.h b/include/net/ipip.h index 65caea8b414f..58abbf966b0c 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -45,7 +45,7 @@ struct ip_tunnel_prl_entry { struct rcu_head rcu_head; }; -#define IPTUNNEL_XMIT() do { \ +#define __IPTUNNEL_XMIT(stats1, stats2) do { \ int err; \ int pkt_len = skb->len - skb_transport_offset(skb); \ \ @@ -54,12 +54,14 @@ struct ip_tunnel_prl_entry { \ err = ip_local_out(skb); \ if (likely(net_xmit_eval(err) == 0)) { \ - txq->tx_bytes += pkt_len; \ - txq->tx_packets++; \ + (stats1)->tx_bytes += pkt_len; \ + (stats1)->tx_packets++; \ } else { \ - stats->tx_errors++; \ - stats->tx_aborted_errors++; \ + (stats2)->tx_errors++; \ + (stats2)->tx_aborted_errors++; \ } \ } while (0) +#define IPTUNNEL_XMIT() __IPTUNNEL_XMIT(txq, stats) + #endif -- cgit v1.2.3 From e985aad723d7709e6bee566bacb100d33d9b791b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 03:57:11 +0000 Subject: ip_gre: percpu stats accounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le lundi 27 septembre 2010 à 14:29 +0100, Ben Hutchings a écrit : > > diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c > > index 5d6ddcb..de39b22 100644 > > --- a/net/ipv4/ip_gre.c > > +++ b/net/ipv4/ip_gre.c > [...] > > @@ -377,7 +405,7 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, > > if (parms->name[0]) > > strlcpy(name, parms->name, IFNAMSIZ); > > else > > - sprintf(name, "gre%%d"); > > + strcpy(name, "gre%d"); > > > > dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); > > if (!dev) > [...] > > This is a valid fix, but doesn't belong in this patch! > Sorry ? It was not a fix, but at most a cleanup ;) Anyway I forgot the gretap case... [PATCH 2/4 v2] ip_gre: percpu stats accounting Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets. Other seldom used fields are kept in netdev->stats structure, possibly unsafe. This is a preliminary work to support lockless transmit path, and correct RX stats, that are already unsafe. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 143 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 39 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5d6ddcb7403b..a1b5d5e03064 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -165,6 +165,34 @@ struct ipgre_net { #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipgre_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + /* Given src, dst and key, find appropriate for input tunnel. */ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, @@ -584,7 +612,7 @@ static int ipgre_rcv(struct sk_buff *skb) if ((tunnel = ipgre_tunnel_lookup(skb->dev, iph->saddr, iph->daddr, key, gre_proto))) { - struct net_device_stats *stats = &tunnel->dev->stats; + struct pcpu_tstats *tstats; secpath_reset(skb); @@ -608,22 +636,22 @@ static int ipgre_rcv(struct sk_buff *skb) /* Looped back packet, drop it! */ if (skb_rtable(skb)->fl.iif == 0) goto drop; - stats->multicast++; + tunnel->dev->stats.multicast++; skb->pkt_type = PACKET_BROADCAST; } #endif if (((flags&GRE_CSUM) && csum) || (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { - stats->rx_crc_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_crc_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } if (tunnel->parms.i_flags&GRE_SEQ) { if (!(flags&GRE_SEQ) || (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { - stats->rx_fifo_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_fifo_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } tunnel->i_seqno = seqno + 1; @@ -632,8 +660,8 @@ static int ipgre_rcv(struct sk_buff *skb) /* Warning: All skb pointers will be invalidated! */ if (tunnel->dev->type == ARPHRD_ETHER) { if (!pskb_may_pull(skb, ETH_HLEN)) { - stats->rx_length_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_length_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } @@ -642,13 +670,17 @@ static int ipgre_rcv(struct sk_buff *skb) skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); } - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); skb_reset_network_header(skb); ipgre_ecn_decapsulate(iph, skb); if (netif_rx(skb) == NET_RX_DROP) - stats->rx_dropped++; + tunnel->dev->stats.rx_dropped++; rcu_read_unlock(); return 0; @@ -665,8 +697,7 @@ drop_nolock: static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *old_iph = ip_hdr(skb); struct iphdr *tiph; u8 tos; @@ -694,7 +725,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev /* NBMA tunnel */ if (skb_dst(skb) == NULL) { - stats->tx_fifo_errors++; + dev->stats.tx_fifo_errors++; goto tx_error; } @@ -740,14 +771,20 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, + .proto = IPPROTO_GRE + } +; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error; } } @@ -755,7 +792,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -818,7 +855,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev dev->needed_headroom = max_headroom; if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -885,15 +922,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -913,13 +950,19 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) /* Guess output device to choose reasonable mtu and needed_headroom */ if (iph->daddr) { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_GRE + }; struct rtable *rt; + if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { tdev = rt->dst.dev; ip_rt_put(rt); @@ -1171,13 +1214,19 @@ static int ipgre_open(struct net_device *dev) struct ip_tunnel *t = netdev_priv(dev); if (ipv4_is_multicast(t->parms.iph.daddr)) { - struct flowi fl = { .oif = t->parms.link, - .nl_u = { .ip4_u = - { .daddr = t->parms.iph.daddr, - .saddr = t->parms.iph.saddr, - .tos = RT_TOS(t->parms.iph.tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = t->parms.link, + .nl_u = { + .ip4_u = { + .daddr = t->parms.iph.daddr, + .saddr = t->parms.iph.saddr, + .tos = RT_TOS(t->parms.iph.tos) + } + }, + .proto = IPPROTO_GRE + }; struct rtable *rt; + if (ip_route_output_key(dev_net(dev), &rt, &fl)) return -EADDRNOTAVAIL; dev = rt->dst.dev; @@ -1217,12 +1266,19 @@ static const struct net_device_ops ipgre_netdev_ops = { .ndo_start_xmit = ipgre_tunnel_xmit, .ndo_do_ioctl = ipgre_tunnel_ioctl, .ndo_change_mtu = ipgre_tunnel_change_mtu, + .ndo_get_stats = ipgre_get_stats, }; +static void ipgre_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipgre_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipgre_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipgre_dev_free; dev->type = ARPHRD_IPGRE; dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4; @@ -1260,6 +1316,10 @@ static int ipgre_tunnel_init(struct net_device *dev) } else dev->header_ops = &ipgre_header_ops; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } @@ -1446,6 +1506,10 @@ static int ipgre_tap_init(struct net_device *dev) ipgre_tunnel_bind_dev(dev); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } @@ -1456,6 +1520,7 @@ static const struct net_device_ops ipgre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ipgre_tunnel_change_mtu, + .ndo_get_stats = ipgre_get_stats, }; static void ipgre_tap_setup(struct net_device *dev) @@ -1464,7 +1529,7 @@ static void ipgre_tap_setup(struct net_device *dev) ether_setup(dev); dev->netdev_ops = &ipgre_tap_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipgre_dev_free; dev->iflink = 0; dev->features |= NETIF_F_NETNS_LOCAL; -- cgit v1.2.3 From 3c97af99a5aa17feaebb4eb0f85f51ab6c055797 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 00:35:50 +0000 Subject: ipip: percpu stats accounting Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets. Other seldom used fields are kept in netdev->stats structure, possibly unsafe. This is a preliminary work to support lockless transmit path, and correct RX stats, that are already unsafe. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 127 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 34 deletions(-) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index babd25278106..12b6fde6f65a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -131,8 +131,9 @@ struct ipip_net { struct net_device *fb_tunnel_dev; }; -static void ipip_tunnel_init(struct net_device *dev); +static int ipip_tunnel_init(struct net_device *dev); static void ipip_tunnel_setup(struct net_device *dev); +static void ipip_dev_free(struct net_device *dev); /* * Locking : hash tables are protected by RCU and RTNL @@ -141,6 +142,34 @@ static void ipip_tunnel_setup(struct net_device *dev); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipip_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, __be32 remote, __be32 local) { @@ -239,7 +268,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else - sprintf(name, "tunl%%d"); + strcpy(name, "tunl%d"); dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup); if (dev == NULL) @@ -255,7 +284,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, nt = netdev_priv(dev); nt->parms = *parms; - ipip_tunnel_init(dev); + if (ipip_tunnel_init(dev) < 0) + goto failed_free; if (register_netdevice(dev) < 0) goto failed_free; @@ -265,7 +295,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, return nt; failed_free: - free_netdev(dev); + ipip_dev_free(dev); return NULL; } @@ -359,8 +389,10 @@ static int ipip_rcv(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); rcu_read_lock(); - if ((tunnel = ipip_tunnel_lookup(dev_net(skb->dev), - iph->saddr, iph->daddr)) != NULL) { + tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr); + if (tunnel != NULL) { + struct pcpu_tstats *tstats; + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { rcu_read_unlock(); kfree_skb(skb); @@ -374,7 +406,11 @@ static int ipip_rcv(struct sk_buff *skb) skb->protocol = htons(ETH_P_IP); skb->pkt_type = PACKET_HOST; - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); ipip_ecn_decapsulate(iph, skb); @@ -397,13 +433,12 @@ static int ipip_rcv(struct sk_buff *skb) static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *tiph = &tunnel->parms.iph; u8 tos = tunnel->parms.iph.tos; __be16 df = tiph->frag_off; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *old_iph = ip_hdr(skb); struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ @@ -413,13 +448,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->protocol != htons(ETH_P_IP)) goto tx_error; - if (tos&1) + if (tos & 1) tos = old_iph->tos; if (!dst) { /* NBMA tunnel */ if ((rt = skb_rtable(skb)) == NULL) { - stats->tx_fifo_errors++; + dev->stats.tx_fifo_errors++; goto tx_error; } if ((dst = rt->rt_gateway) == 0) @@ -427,14 +462,20 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } } @@ -442,7 +483,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -452,7 +493,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - stats->collisions++; + dev->stats.collisions++; ip_rt_put(rt); goto tx_error; } @@ -488,7 +529,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -525,14 +566,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) iph->ttl = old_iph->ttl; nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -547,13 +588,19 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; struct rtable *rt; + if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { tdev = rt->dst.dev; ip_rt_put(rt); @@ -699,13 +746,19 @@ static const struct net_device_ops ipip_netdev_ops = { .ndo_start_xmit = ipip_tunnel_xmit, .ndo_do_ioctl = ipip_tunnel_ioctl, .ndo_change_mtu = ipip_tunnel_change_mtu, - + .ndo_get_stats = ipip_get_stats, }; +static void ipip_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipip_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipip_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipip_dev_free; dev->type = ARPHRD_TUNNEL; dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); @@ -717,7 +770,7 @@ static void ipip_tunnel_setup(struct net_device *dev) dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } -static void ipip_tunnel_init(struct net_device *dev) +static int ipip_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); @@ -728,6 +781,12 @@ static void ipip_tunnel_init(struct net_device *dev) memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ipip_tunnel_bind_dev(dev); + + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + + return 0; } static void __net_init ipip_fb_tunnel_init(struct net_device *dev) -- cgit v1.2.3 From 15fc1f7056ebdc57e23f99077fec89e63e6fa941 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 00:38:18 +0000 Subject: sit: percpu stats accounting Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets. Other seldom used fields are kept in netdev->stats structure, possibly unsafe. This is a preliminary work to support lockless transmit path, and correct RX stats, that are already unsafe. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/sit.c | 82 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 8a0399822230..011ecf55d34e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -63,8 +63,9 @@ #define HASH_SIZE 16 #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) -static void ipip6_tunnel_init(struct net_device *dev); +static int ipip6_tunnel_init(struct net_device *dev); static void ipip6_tunnel_setup(struct net_device *dev); +static void ipip6_dev_free(struct net_device *dev); static int sit_net_id __read_mostly; struct sit_net { @@ -84,6 +85,33 @@ struct sit_net { #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipip6_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} /* * Must be invoked with rcu_read_lock */ @@ -214,7 +242,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else - sprintf(name, "sit%%d"); + strcpy(name, "sit%d"); dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) @@ -230,7 +258,8 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, nt = netdev_priv(dev); nt->parms = *parms; - ipip6_tunnel_init(dev); + if (ipip6_tunnel_init(dev) < 0) + goto failed_free; ipip6_tunnel_clone_6rd(dev, sitn); if (parms->i_flags & SIT_ISATAP) @@ -245,7 +274,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, return nt; failed_free: - free_netdev(dev); + ipip6_dev_free(dev); failed: return NULL; } @@ -546,6 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb) tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, iph->saddr, iph->daddr); if (tunnel != NULL) { + struct pcpu_tstats *tstats; + secpath_reset(skb); skb->mac_header = skb->network_header; skb_reset_network_header(skb); @@ -561,7 +592,11 @@ static int ipip6_rcv(struct sk_buff *skb) return 0; } - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); ipip6_ecn_decapsulate(iph, skb); @@ -626,14 +661,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *tiph = &tunnel->parms.iph; struct ipv6hdr *iph6 = ipv6_hdr(skb); u8 tos = tunnel->parms.iph.tos; __be16 df = tiph->frag_off; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ __be32 dst = tiph->daddr; @@ -704,20 +738,20 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } } if (rt->rt_type != RTN_UNICAST) { ip_rt_put(rt); - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } tdev = rt->dst.dev; if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -725,7 +759,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - stats->collisions++; + dev->stats.collisions++; ip_rt_put(rt); goto tx_error; } @@ -764,7 +798,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -800,14 +834,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, iph->ttl = iph6->hop_limit; nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1084,12 +1118,19 @@ static const struct net_device_ops ipip6_netdev_ops = { .ndo_start_xmit = ipip6_tunnel_xmit, .ndo_do_ioctl = ipip6_tunnel_ioctl, .ndo_change_mtu = ipip6_tunnel_change_mtu, + .ndo_get_stats = ipip6_get_stats, }; +static void ipip6_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipip6_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipip6_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipip6_dev_free; dev->type = ARPHRD_SIT; dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); @@ -1101,7 +1142,7 @@ static void ipip6_tunnel_setup(struct net_device *dev) dev->features |= NETIF_F_NETNS_LOCAL; } -static void ipip6_tunnel_init(struct net_device *dev) +static int ipip6_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); @@ -1112,6 +1153,11 @@ static void ipip6_tunnel_init(struct net_device *dev) memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ipip6_tunnel_bind_dev(dev); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + + return 0; } static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) -- cgit v1.2.3 From 7fa7cb7109d07c29ab28bb877bc7049a0150dbe5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 04:18:27 +0000 Subject: fib: use atomic_inc_not_zero() in fib_rules_lookup It seems we dont use appropriate refcount increment in an rcu_read_lock() protected section. fib_rule_get() might increment a null refcount and bad things could happen. While fib_nl_delrule() respects an rcu grace period before calling fib_rule_put(), fib_rules_cleanup_ops() calls fib_rule_put() without a grace period. Note : after this patch, we might avoid the synchronize_rcu() call done in fib_nl_delrule() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/fib_rules.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 42e84e08a1be..d0787284cb07 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -225,9 +225,11 @@ jumped: err = ops->action(rule, fl, flags, arg); if (err != -EAGAIN) { - fib_rule_get(rule); - arg->rule = rule; - goto out; + if (likely(atomic_inc_not_zero(&rule->refcnt))) { + arg->rule = rule; + goto out; + } + break; } } -- cgit v1.2.3 From f91ff5b9ff529be8aac2039af63b2c8ea6cd6ebe Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 06:07:30 +0000 Subject: net: sk_{detach|attach}_filter() rcu fixes sk_attach_filter() and sk_detach_filter() are run with socket locked. Use the appropriate rcu_dereference_protected() instead of blocking BH, and rcu_dereference_bh(). There is no point adding BH prevention and memory barrier. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/filter.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 52b051f82a01..7adf50352918 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -638,10 +638,9 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) return err; } - rcu_read_lock_bh(); - old_fp = rcu_dereference_bh(sk->sk_filter); + old_fp = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); rcu_assign_pointer(sk->sk_filter, fp); - rcu_read_unlock_bh(); if (old_fp) sk_filter_delayed_uncharge(sk, old_fp); @@ -654,14 +653,13 @@ int sk_detach_filter(struct sock *sk) int ret = -ENOENT; struct sk_filter *filter; - rcu_read_lock_bh(); - filter = rcu_dereference_bh(sk->sk_filter); + filter = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); sk_filter_delayed_uncharge(sk, filter); ret = 0; } - rcu_read_unlock_bh(); return ret; } EXPORT_SYMBOL_GPL(sk_detach_filter); -- cgit v1.2.3 From 62fe0b40abb3484413800edaef9b087a20059acf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:24:33 +0000 Subject: net: Allow changing number of RX queues after device allocation For RPS, we create a kobject for each RX queue based on the number of queues passed to alloc_netdev_mq(). However, drivers generally do not determine the numbers of hardware queues to use until much later, so this usually represents the maximum number the driver may use and not the actual number in use. For TX queues, drivers can update the actual number using netif_set_real_num_tx_queues(). Add a corresponding function for RX queues, netif_set_real_num_rx_queues(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/netdevice.h | 16 +++++++++++++++- net/core/dev.c | 45 +++++++++++++++++++++++++++++++++++++++++---- net/core/net-sysfs.c | 32 ++++++++++++++++++-------------- net/core/net-sysfs.h | 4 ++++ 4 files changed, 78 insertions(+), 19 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 83de0eb7a071..b15732e22eee 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -976,8 +976,11 @@ struct net_device { struct netdev_rx_queue *_rx; - /* Number of RX queues allocated at alloc_netdev_mq() time */ + /* Number of RX queues allocated at register_netdev() time */ unsigned int num_rx_queues; + + /* Number of RX queues currently active in device */ + unsigned int real_num_rx_queues; #endif rx_handler_func_t *rx_handler; @@ -1685,6 +1688,17 @@ static inline int netif_is_multiqueue(const struct net_device *dev) extern void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq); +#ifdef CONFIG_RPS +extern int netif_set_real_num_rx_queues(struct net_device *dev, + unsigned int rxq); +#else +static inline int netif_set_real_num_rx_queues(struct net_device *dev, + unsigned int rxq) +{ + return 0; +} +#endif + /* Use this variant when it is known for sure that it * is executing from hardware interrupt context or with hardware interrupts * disabled. diff --git a/net/core/dev.c b/net/core/dev.c index 42b200fdf12e..48ad47f402ad 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1567,6 +1567,41 @@ void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) } EXPORT_SYMBOL(netif_set_real_num_tx_queues); +#ifdef CONFIG_RPS +/** + * netif_set_real_num_rx_queues - set actual number of RX queues used + * @dev: Network device + * @rxq: Actual number of RX queues + * + * This must be called either with the rtnl_lock held or before + * registration of the net device. Returns 0 on success, or a + * negative error code. If called before registration, it also + * sets the maximum number of queues, and always succeeds. + */ +int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) +{ + int rc; + + if (dev->reg_state == NETREG_REGISTERED) { + ASSERT_RTNL(); + + if (rxq > dev->num_rx_queues) + return -EINVAL; + + rc = net_rx_queue_update_kobjects(dev, dev->real_num_rx_queues, + rxq); + if (rc) + return rc; + } else { + dev->num_rx_queues = rxq; + } + + dev->real_num_rx_queues = rxq; + return 0; +} +EXPORT_SYMBOL(netif_set_real_num_rx_queues); +#endif + static inline void __netif_reschedule(struct Qdisc *q) { struct softnet_data *sd; @@ -2352,10 +2387,11 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (skb_rx_queue_recorded(skb)) { u16 index = skb_get_rx_queue(skb); - if (unlikely(index >= dev->num_rx_queues)) { - WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " - "on queue %u, but number of RX queues is %u\n", - dev->name, index, dev->num_rx_queues); + if (unlikely(index >= dev->real_num_rx_queues)) { + WARN_ONCE(dev->real_num_rx_queues > 1, + "%s received packet on queue %u, but number " + "of RX queues is %u\n", + dev->name, index, dev->real_num_rx_queues); goto done; } rxqueue = dev->_rx + index; @@ -5472,6 +5508,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, #ifdef CONFIG_RPS dev->num_rx_queues = queue_count; + dev->real_num_rx_queues = queue_count; #endif dev->gso_max_size = GSO_MAX_SIZE; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 76485a3f910b..fa81fd0a488f 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -742,34 +742,38 @@ static int rx_queue_add_kobject(struct net_device *net, int index) return error; } -static int rx_queue_register_kobjects(struct net_device *net) +int +net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) { int i; int error = 0; - net->queues_kset = kset_create_and_add("queues", - NULL, &net->dev.kobj); - if (!net->queues_kset) - return -ENOMEM; - for (i = 0; i < net->num_rx_queues; i++) { + for (i = old_num; i < new_num; i++) { error = rx_queue_add_kobject(net, i); - if (error) + if (error) { + new_num = old_num; break; + } } - if (error) - while (--i >= 0) - kobject_put(&net->_rx[i].kobj); + while (--i >= new_num) + kobject_put(&net->_rx[i].kobj); return error; } -static void rx_queue_remove_kobjects(struct net_device *net) +static int rx_queue_register_kobjects(struct net_device *net) { - int i; + net->queues_kset = kset_create_and_add("queues", + NULL, &net->dev.kobj); + if (!net->queues_kset) + return -ENOMEM; + return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); +} - for (i = 0; i < net->num_rx_queues; i++) - kobject_put(&net->_rx[i].kobj); +static void rx_queue_remove_kobjects(struct net_device *net) +{ + net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); kset_unregister(net->queues_kset); } #endif /* CONFIG_RPS */ diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h index 805555e8b187..778e1571548d 100644 --- a/net/core/net-sysfs.h +++ b/net/core/net-sysfs.h @@ -4,4 +4,8 @@ int netdev_kobject_init(void); int netdev_register_kobject(struct net_device *); void netdev_unregister_kobject(struct net_device *); +#ifdef CONFIG_RPS +int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); +#endif + #endif -- cgit v1.2.3 From 3171d026291d08c2a4cfe06302ce308b09605c4b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:24:49 +0000 Subject: net: Add netif_copy_real_num_queues() for use by virtual net drivers This sets the active numbers of queues on a net device to match another. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/netdevice.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b15732e22eee..c2bec990bd17 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1699,6 +1699,18 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev, } #endif +static inline int netif_copy_real_num_queues(struct net_device *to_dev, + const struct net_device *from_dev) +{ + netif_set_real_num_tx_queues(to_dev, from_dev->real_num_tx_queues); +#ifdef CONFIG_RPS + return netif_set_real_num_rx_queues(to_dev, + from_dev->real_num_rx_queues); +#else + return 0; +#endif +} + /* Use this variant when it is known for sure that it * is executing from hardware interrupt context or with hardware interrupts * disabled. -- cgit v1.2.3 From 657d92fe6d693b9674264bc7546e664714955425 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:25:16 +0000 Subject: bnx2: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3d1a5da98622..b10be27f340a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6202,7 +6202,7 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) } } -static void +static int bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) { int cpus = num_online_cpus(); @@ -6231,9 +6231,10 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) } bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); - bp->dev->real_num_tx_queues = bp->num_tx_rings; + netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); bp->num_rx_rings = bp->irq_nvecs; + return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); } /* Called with rtnl_lock */ @@ -6248,7 +6249,9 @@ bnx2_open(struct net_device *dev) bnx2_set_power_state(bp, PCI_D0); bnx2_disable_int(bp); - bnx2_setup_int_mode(bp, disable_msi); + rc = bnx2_setup_int_mode(bp, disable_msi); + if (rc) + goto open_err; bnx2_init_napi(bp); bnx2_napi_enable(bp); rc = bnx2_alloc_mem(bp); -- cgit v1.2.3 From 31b600b5fcd101acffb261f87f60f27085ca6509 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:25:27 +0000 Subject: bnx2x: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index efc7be4aefb5..05c05a496b15 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1207,8 +1207,8 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues = 1; break; } - bp->dev->real_num_tx_queues = bp->num_queues; - return rc; + netif_set_real_num_tx_queues(bp->dev, bp->num_queues); + return netif_set_real_num_rx_queues(bp->dev, bp->num_queues); } static void bnx2x_release_firmware(struct bnx2x *bp) @@ -1240,6 +1240,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; rc = bnx2x_set_num_queues(bp); + if (rc) + return rc; if (bnx2x_alloc_mem(bp)) { bnx2x_free_irq(bp, true); -- cgit v1.2.3 From 19221e75da32cecbd3fe83a8ac12755fe38a4602 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:25:44 +0000 Subject: cxgb3: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index f9eede0a4b86..a04ce6a5f637 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1399,7 +1399,10 @@ static int cxgb_open(struct net_device *dev) "Could not initialize offload capabilities\n"); } - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; link_start(dev); t3_port_intr_enable(adapter, pi->port_id); netif_tx_start_all_queues(dev); -- cgit v1.2.3 From a020ed4bb88356fea9e24ffcfd9692a835a3f122 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:25:57 +0000 Subject: cxgb4: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 75b9401fd484..4fb08e3c3f38 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2763,7 +2763,10 @@ static int cxgb_open(struct net_device *dev) return err; } - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; err = link_start(dev); if (!err) netif_tx_start_all_queues(dev); -- cgit v1.2.3 From 003ab6742a31662eb808f01273126830612cbda1 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:26:10 +0000 Subject: cxgb4vf: Use netif_set_real_num_{rx, tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 7b6d07f50c71..555ecc5a2e93 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -748,7 +748,10 @@ static int cxgb4vf_open(struct net_device *dev) /* * Note that this interface is up and start everything up ... */ - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; set_bit(pi->port_id, &adapter->open_device_map); link_start(dev); netif_tx_start_all_queues(dev); -- cgit v1.2.3 From fe06912333bb9776b0429100b195080809984ae4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:27:37 +0000 Subject: gianfar: Use netif_set_real_num_rx_queues() Do not set num_tx_queues or real_num_tx_queues, since alloc_etherdev_mq() does that. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index f30adbf86bb2..6180089bf67a 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -654,9 +654,8 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) priv->node = ofdev->dev.of_node; priv->ndev = dev; - dev->num_tx_queues = num_tx_qs; - dev->real_num_tx_queues = num_tx_qs; priv->num_tx_queues = num_tx_qs; + netif_set_real_num_rx_queues(dev, num_rx_qs); priv->num_rx_queues = num_rx_qs; priv->num_grps = 0x0; -- cgit v1.2.3 From 21adef3e2959160df31f8516883431e5595f9e50 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:28:39 +0000 Subject: igb: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0394ca95f3ba..55edcb74abf4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -988,7 +988,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter) * Attempt to configure interrupts using the best available * capabilities of the hardware and kernel. **/ -static void igb_set_interrupt_capability(struct igb_adapter *adapter) +static int igb_set_interrupt_capability(struct igb_adapter *adapter) { int err; int numvecs, i; @@ -1054,8 +1054,10 @@ msi_only: if (!pci_enable_msi(adapter->pdev)) adapter->flags |= IGB_FLAG_HAS_MSI; out: - /* Notify the stack of the (possibly) reduced Tx Queue count. */ - adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; + /* Notify the stack of the (possibly) reduced queue counts. */ + netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); + return netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); } /** @@ -1154,7 +1156,9 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter) struct pci_dev *pdev = adapter->pdev; int err; - igb_set_interrupt_capability(adapter); + err = igb_set_interrupt_capability(adapter); + if (err) + return err; err = igb_alloc_q_vectors(adapter); if (err) { -- cgit v1.2.3 From 847f53ff40a81c94367aabb2ef05f2b99cb5706d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:28:56 +0000 Subject: ixgbe: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4e0ce91321dd..c35185cb27fe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4088,7 +4088,7 @@ static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter) * fallthrough conditions. * **/ -static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) +static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter) { /* Start with base case */ adapter->num_rx_queues = 1; @@ -4097,7 +4097,7 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) adapter->num_rx_queues_per_pool = 1; if (ixgbe_set_sriov_queues(adapter)) - return; + goto done; #ifdef IXGBE_FCOE if (ixgbe_set_fcoe_queues(adapter)) @@ -4120,8 +4120,10 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) adapter->num_tx_queues = 1; done: - /* Notify the stack of the (possibly) reduced Tx Queue count. */ + /* Notify the stack of the (possibly) reduced queue counts. */ netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); + return netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); } static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, @@ -4550,7 +4552,9 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) ixgbe_disable_sriov(adapter); - ixgbe_set_num_queues(adapter); + err = ixgbe_set_num_queues(adapter); + if (err) + return err; err = pci_enable_msi(adapter->pdev); if (!err) { @@ -4675,7 +4679,9 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) int err; /* Number of supported queues */ - ixgbe_set_num_queues(adapter); + err = ixgbe_set_num_queues(adapter); + if (err) + return err; err = ixgbe_set_interrupt_capability(adapter); if (err) { -- cgit v1.2.3 From 1eb63a28148336b8a97ff5ee0ecd6830e76a7044 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:29:34 +0000 Subject: mlx4_en: Use netif_set_real_num_{rx, tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/mlx4/en_netdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 411bda581c04..79478bd4211a 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -1025,7 +1025,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, */ dev->netdev_ops = &mlx4_netdev_ops; dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT; - dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS; + netif_set_real_num_tx_queues(dev, priv->tx_ring_num); + netif_set_real_num_rx_queues(dev, priv->rx_ring_num); SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops); -- cgit v1.2.3 From 206d6b3270921fe4a207515beb1f7f7cd8aa3597 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:30:05 +0000 Subject: mv643xx_eth: Use netif_set_real_num_{rx, tx}_queues() Signed-off-by: Ben Hutchings Acked-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 2d488abcf62d..dd2b6a71c6d7 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2901,7 +2901,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; set_params(mp, pd); - dev->real_num_tx_queues = mp->txq_count; + netif_set_real_num_tx_queues(dev, mp->txq_count); + netif_set_real_num_rx_queues(dev, mp->rxq_count); if (pd->phy_addr != MV643XX_ETH_PHY_NONE) mp->phy = phy_scan(mp, pd->phy_addr); -- cgit v1.2.3 From c99202684f7a45c965cb13fa6bb647f2ce9d27fa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:30:34 +0000 Subject: myri10ge: Use netif_set_real_num_{rx, tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 4f3a3c0d6d08..3ad1a21ca8ce 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -990,7 +990,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) * RX queues, so if we get an error, first retry using a * single TX queue before giving up */ if (status != 0 && mgp->dev->real_num_tx_queues > 1) { - mgp->dev->real_num_tx_queues = 1; + netif_set_real_num_tx_queues(mgp->dev, 1); cmd.data0 = mgp->num_slices; cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE; status = myri10ge_send_cmd(mgp, @@ -3923,7 +3923,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed to alloc slice state\n"); goto abort_with_firmware; } - netdev->real_num_tx_queues = mgp->num_slices; + netif_set_real_num_tx_queues(netdev, mgp->num_slices); + netif_set_real_num_rx_queues(netdev, mgp->num_slices); status = myri10ge_reset(mgp); if (status != 0) { dev_err(&pdev->dev, "failed reset\n"); -- cgit v1.2.3 From e2209ba35aa7050fced05bf9c4244562fcaebd63 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:30:59 +0000 Subject: niu: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/niu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 4cd92421708d..c0437fd8d3f2 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -4501,7 +4501,8 @@ static int niu_alloc_channels(struct niu *np) np->num_rx_rings = parent->rxchan_per_port[port]; np->num_tx_rings = parent->txchan_per_port[port]; - np->dev->real_num_tx_queues = np->num_tx_rings; + netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); + netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), GFP_KERNEL); -- cgit v1.2.3 From c4f4adc7b7e03f9c0bfc81fccc8ad85d06dc8d88 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:31:07 +0000 Subject: sfc: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 5be71f49a205..fa6e0207de17 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1315,7 +1315,8 @@ static int efx_probe_nic(struct efx_nic *efx) efx->rx_indir_table[i] = i % efx->n_rx_channels; efx_set_channels(efx); - efx->net_dev->real_num_tx_queues = efx->n_tx_channels; + netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels); + netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels); /* Initialise the interrupt moderation settings */ efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true); -- cgit v1.2.3 From 5df8dbd7e517b581e0b8cbd72a99da17914a20b0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 08:32:59 +0000 Subject: 8021q: Use netif_copy_real_num_queues() to set queue counts This covers RX if necessary, as well as TX. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/8021q/vlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 2c6c2bd6e4a9..25c21332e9c3 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -321,7 +321,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) if (new_dev == NULL) return -ENOBUFS; - new_dev->real_num_tx_queues = real_dev->real_num_tx_queues; + netif_copy_real_num_queues(new_dev, real_dev); dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. -- cgit v1.2.3 From 2ddaad397c47de012dfb956b0c05540da1a0dde5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 Sep 2010 22:11:51 -0700 Subject: tg3: Use netif_set_real_num_{rx,tx}_queues() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/tg3.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index fdb438dca9b3..54fff5bb6f98 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8821,7 +8821,12 @@ static bool tg3_enable_msix(struct tg3 *tp) for (i = 0; i < tp->irq_max; i++) tp->napi[i].irq_vec = msix_ent[i].vector; - tp->dev->real_num_tx_queues = 1; + netif_set_real_num_tx_queues(tp->dev, 1); + rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1; + if (netif_set_real_num_rx_queues(tp->dev, rc)) { + pci_disable_msix(tp->pdev); + return false; + } if (tp->irq_cnt > 1) tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; @@ -8856,7 +8861,7 @@ defcfg: if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) { tp->irq_cnt = 1; tp->napi[0].irq_vec = tp->pdev->irq; - tp->dev->real_num_tx_queues = 1; + netif_set_real_num_tx_queues(tp->dev, 1); } } -- cgit v1.2.3 From 4d443a085de2b6bcae5e0a773c63b8731ff27101 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Mon, 27 Sep 2010 19:35:06 +0000 Subject: Documentation: Update Phonet doc for Pipe Controller implementation Updates the Phonet document with description related to Pipe controller implementation Signed-off-by: Kumar Sanghvi Acked-by: Linus Walleij Signed-off-by: David S. Miller --- Documentation/networking/phonet.txt | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt index cf76608a2d35..cccf5ff07ec2 100644 --- a/Documentation/networking/phonet.txt +++ b/Documentation/networking/phonet.txt @@ -182,6 +182,59 @@ The pipe protocol provides two socket options at the SOL_PNPIPE level: or zero if encapsulation is off. +Phonet Pipe-controller Implementation +------------------------------------- + +Phonet Pipe-controller is enabled by selecting the CONFIG_PHONET_PIPECTRLR Kconfig +option. It is useful when communicating with those Nokia Modems which do not +implement Pipe controller in them e.g. Nokia Slim Modem used in ST-Ericsson +U8500 platform. + +The implementation is based on the Data Connection Establishment Sequence +depicted in 'Nokia Wireless Modem API - Wireless_modem_user_guide.pdf' +document. + +It allows a phonet sequenced socket (host-pep) to initiate a Pipe connection +between itself and a remote pipe-end point (e.g. modem). + +The implementation adds socket options at SOL_PNPIPE level: + + PNPIPE_CREATE + It accepts an integer argument where-in + lower order 16 bits: pn_dev and pn_port pair for remote pep. + higher order 16 bits: 8 bit pipe-handle + + It sends a PNS_PEP_CONNECT_REQ on sequenced socket itself. On getting + PNS_PEP_CONNECT_RESP, it sends PNS_PEP_CONNECT_REQ to remote pep. On + getting response from remote pep, it selects the best possible Flow + control mechanism supported by remote-pep (modem) and then it sends + PNS_PEP_CREATED_IND to the sequenced socket and to the remote pep. + + It then updates the pipe state associated with the sequenced socket to + be PIPE_DISABLED. + + PNPIPE_ENABLE + It follows the same sequence as above for enabling a pipe by sending + PNS_PEP_ENABLE_REQ initially and then sending PNS_PEP_ENABLED_IND after + getting responses from sequenced socket and remote-pep. + It will also update the pipe state associated with the sequenced socket + to PIPE_ENABLED. + + PNPIPE_DESTROY + This will send out PNS_PEP_DISCONNECT_REQ on the sequenced socket and + the remote pep. + It will also update the pipe state associated with the sequenced socket + to PIPE_IDLE + + PNPIPE_INQ + This getsocktopt allows the user-space running on the sequenced socket + to examine the pipe state associated with that socket ie. whether the + pipe is created (PIPE_DISABLED) or enabled (PIPE_ENABLED) or disabled + (PIPE_DISABLED) or no pipe exists (PIPE_IDLE). + +After a pipe has been created and enabled successfully, the Pipe data can be +exchanged between the host-pep and remote-pep (modem). + Authors ------- -- cgit v1.2.3 From 98d633b64a55d6f3e943951ca35f283b0901d7db Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 8 Jul 2010 06:27:38 +0300 Subject: wl1271: remove deprecated ACX definition As of Rev. 6.1.0.0.335, the ACX_SET_SMART_REFLEX_DEBUG command is deprecated. This patch removes it from the wl1271 driver (it wasn't used anyway). Signed-off-by: Luciano Coelho Reviewed-by: Saravanan Dhanabal --- drivers/net/wireless/wl12xx/wl1271_acx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 4235bc56f750..5c8bb7fd2eb9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -1060,7 +1060,6 @@ enum { ACX_PEER_HT_CAP = 0x0057, ACX_HT_BSS_OPERATION = 0x0058, ACX_COEX_ACTIVITY = 0x0059, - ACX_SET_SMART_REFLEX_DEBUG = 0x005A, ACX_SET_DCO_ITRIM_PARAMS = 0x0061, DOT11_RX_MSDU_LIFE_TIME = 0x1004, DOT11_CUR_TX_PWR = 0x100D, -- cgit v1.2.3 From be86cbea1e9c3a4dd8faedcfa327495d09fe3531 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 27 May 2010 12:53:01 +0300 Subject: wl1271: Implement CMD_SET_STA_STATE to indicate connection completion to FW Implement the command function to send CMD_SET_STA_STATE to the firmware. This is used to indicate that association (and the related EAP negotiation) are complete. This is used to tune WLAN-BT coexistense priority towards BT, improving BT A2DP and SCO performance. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_cmd.h | 10 ++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index ce503ddd5a41..a338b1c93a29 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -746,3 +746,31 @@ out_free: out: return ret; } + +int wl1271_cmd_set_sta_state(struct wl1271 *wl) +{ + struct wl1271_cmd_set_sta_state *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set sta state"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->state = WL1271_CMD_STA_STATE_CONNECTED; + + ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send set STA state command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index af577ee8eb02..ce0476ceb84a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -55,6 +55,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, u8 key_size, const u8 *key, const u8 *addr, u32 tx_seq_32, u16 tx_seq_16); int wl1271_cmd_disconnect(struct wl1271 *wl); +int wl1271_cmd_set_sta_state(struct wl1271 *wl); enum wl1271_commands { CMD_INTERROGATE = 1, /*use this to read information elements*/ @@ -469,4 +470,13 @@ struct wl1271_cmd_disconnect { u8 padding; } __packed; +#define WL1271_CMD_STA_STATE_CONNECTED 1 + +struct wl1271_cmd_set_sta_state { + struct wl1271_cmd_header header; + + u8 state; + u8 padding[3]; +} __attribute__ ((packed)); + #endif /* __WL1271_CMD_H__ */ -- cgit v1.2.3 From c2c192ac6c16e2e8f5cc8cf54e02bb1d4e0e761d Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 27 Jul 2010 03:30:09 +0300 Subject: wl1271: Add trigger to net_device oper_state to change BT coex priority Add a trigger to net_device changes to monitor for oper_state changes in order to be able to inform the firmware when association is fully complete (including the EAP negotiation.) Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_main.c | 69 +++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 4134f4495b95..1098d1689b0e 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -350,6 +350,7 @@ struct wl1271 { #define WL1271_FLAG_IDLE (10) #define WL1271_FLAG_IDLE_REQUESTED (11) #define WL1271_FLAG_PSPOLL_FAILURE (12) +#define WL1271_FLAG_STA_STATE_SENT (13) unsigned long flags; struct wl1271_partition_set part; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 776cd7c41148..45d4ce36343c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -277,6 +277,67 @@ static struct platform_device wl1271_device = { static LIST_HEAD(wl_list); +static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, + void *arg) +{ + struct net_device *dev = arg; + struct wireless_dev *wdev; + struct wiphy *wiphy; + struct ieee80211_hw *hw; + struct wl1271 *wl; + struct wl1271 *wl_temp; + int ret = 0; + + /* Check that this notification is for us. */ + if (what != NETDEV_CHANGE) + return NOTIFY_DONE; + + wdev = dev->ieee80211_ptr; + if (wdev == NULL) + return NOTIFY_DONE; + + wiphy = wdev->wiphy; + if (wiphy == NULL) + return NOTIFY_DONE; + + hw = wiphy_priv(wiphy); + if (hw == NULL) + return NOTIFY_DONE; + + wl_temp = hw->priv; + list_for_each_entry(wl, &wl_list, list) { + if (wl == wl_temp) + break; + } + if (wl != wl_temp) + return NOTIFY_DONE; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if ((dev->operstate == IF_OPER_UP) && + !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) { + wl1271_cmd_set_sta_state(wl); + wl1271_info("Association completed."); + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return NOTIFY_OK; +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -814,6 +875,10 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } +static struct notifier_block wl1271_dev_notifier = { + .notifier_call = wl1271_dev_notify, +}; + static int wl1271_op_start(struct ieee80211_hw *hw) { wl1271_debug(DEBUG_MAC80211, "mac80211 start"); @@ -1783,6 +1848,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, } } else { /* use defaults when not associated */ + clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags); clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); wl->aid = 0; @@ -2307,6 +2373,8 @@ int wl1271_register_hw(struct wl1271 *wl) wl->mac80211_registered = true; + register_netdevice_notifier(&wl1271_dev_notifier); + wl1271_notice("loaded"); return 0; @@ -2315,6 +2383,7 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw); void wl1271_unregister_hw(struct wl1271 *wl) { + unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw); wl->mac80211_registered = false; -- cgit v1.2.3 From 76a029fbfb18c42f75c891842df26605ef87add0 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 29 Jul 2010 04:54:45 +0300 Subject: wl1271: Fix scan race condition In the scan state machine, the wl1271_mutex is unlocked first then relocked, and then the scan state variables are modified. This makes it possible for ieee80211_scan_complete to be called twice in some scenarios, as the scan completion event from the firmware may be processed while the mutex is unlocked. To fix the issue, move the ieee80211_scan_complete call last in the function. This is generally safer, but there still may be issues is functions calling the scan state machine rely on states checked before the unlocking of the global mutex. (forward ported from 2.6.32 -- this is not strictly needed anymore, because the mutex doesn't need to be unlocked anymore, but I'm applying this change anyway, so that the call to ieee80211_scan_complete is in the same place) Signed-off-by: Juuso Oikarinen Reviewed-by: Saravanan Dhanabal Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 2 +- drivers/net/wireless/wl12xx/wl1271_scan.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 45d4ce36343c..02ad6c648115 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1015,10 +1015,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, ieee80211_enable_dyn_ps(wl->vif); if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { - ieee80211_scan_completed(wl->hw, true); wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; + ieee80211_scan_completed(wl->hw, true); } wl->state = WL1271_STATE_OFF; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 9c80ba9b6be0..8ceaabe26e64 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -215,12 +215,11 @@ void wl1271_scan_stm(struct wl1271 *wl) break; case WL1271_SCAN_STATE_DONE: - ieee80211_scan_completed(wl->hw, false); - kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; wl->scan.state = WL1271_SCAN_STATE_IDLE; + ieee80211_scan_completed(wl->hw, false); break; default: -- cgit v1.2.3 From 5924f89d6597cd7ba014128ded64b2c7450c369c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 4 Aug 2010 03:46:22 +0300 Subject: wl1271: remove useless 11a check when scanning This code was a leftover of the previous scanning mechanism. The if is totally unnecessary, since both branches do the same thing. Signed-off-by: Luciano Coelho Reviewed-by: Juuso Oikarinen --- drivers/net/wireless/wl12xx/wl1271_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 02ad6c648115..b42ee484a86f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1624,10 +1624,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; - if (wl1271_11a_enabled()) - ret = wl1271_scan(hw->priv, ssid, len, req); - else - ret = wl1271_scan(hw->priv, ssid, len, req); + ret = wl1271_scan(hw->priv, ssid, len, req); wl1271_ps_elp_sleep(wl); -- cgit v1.2.3 From 4f35c0253ab7f32cf30eab5459e8256af1619ff1 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 4 Aug 2010 04:36:32 +0300 Subject: wl1271: fix forced passive scan When we get no SSIDs in the scan request, we should force a passive scan in all channels. This patch adds code to force the passive scan flag to be set in that case. Signed-off-by: Luciano Coelho Reviewed-by: Juuso Oikarinen --- drivers/net/wireless/wl12xx/wl1271_scan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 8ceaabe26e64..7f42ca9abab8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -100,8 +100,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, /* We always use high priority scans */ scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; - if(passive) + + /* No SSIDs means that we have a forced passive scan */ + if (passive || wl->scan.req->n_ssids == 0) scan_options |= WL1271_SCAN_OPT_PASSIVE; + cmd->params.scan_options = cpu_to_le16(scan_options); cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, -- cgit v1.2.3 From fa21c7a9e4be439e217fe72edbd39b643b643791 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 10 Aug 2010 08:22:02 +0200 Subject: wl1271: Change supported channel order for a more optimal scan The mac80211 inserts channels into a scan request in the same order the driver registers them. Use this fact to optimize scan by ordering the channels so that adjacent channels don't get scanned consecutively. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 86 +++++++++++++++++-------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index b42ee484a86f..8ce891aa2273 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2057,21 +2057,24 @@ static struct ieee80211_rate wl1271_rates[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* can't be const, mac80211 writes to this */ +/* + * Can't be const, mac80211 writes to this. The order of the channels here + * is designed to improve scanning. + */ static struct ieee80211_channel wl1271_channels[] = { { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, - { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, - { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, - { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, - { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, - { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, - { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, - { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, - { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, - { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, + { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, + { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, + { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, + { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, + { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, + { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, + { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, + { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, + { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, }; /* mapping to indexes for wl1271_rates */ @@ -2140,49 +2143,52 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* 5 GHz band channels for WL1273 */ +/* + * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this. + * The order of the channels here is designed to improve scanning. + */ static struct ieee80211_channel wl1271_channels_5ghz[] = { { .hw_value = 183, .center_freq = 4915}, - { .hw_value = 184, .center_freq = 4920}, - { .hw_value = 185, .center_freq = 4925}, - { .hw_value = 187, .center_freq = 4935}, { .hw_value = 188, .center_freq = 4940}, - { .hw_value = 189, .center_freq = 4945}, - { .hw_value = 192, .center_freq = 4960}, - { .hw_value = 196, .center_freq = 4980}, - { .hw_value = 7, .center_freq = 5035}, { .hw_value = 8, .center_freq = 5040}, - { .hw_value = 9, .center_freq = 5045}, - { .hw_value = 11, .center_freq = 5055}, - { .hw_value = 12, .center_freq = 5060}, - { .hw_value = 16, .center_freq = 5080}, { .hw_value = 34, .center_freq = 5170}, - { .hw_value = 36, .center_freq = 5180}, - { .hw_value = 38, .center_freq = 5190}, - { .hw_value = 40, .center_freq = 5200}, - { .hw_value = 42, .center_freq = 5210}, { .hw_value = 44, .center_freq = 5220}, - { .hw_value = 46, .center_freq = 5230}, - { .hw_value = 48, .center_freq = 5240}, - { .hw_value = 52, .center_freq = 5260}, - { .hw_value = 56, .center_freq = 5280}, { .hw_value = 60, .center_freq = 5300}, - { .hw_value = 64, .center_freq = 5320}, - { .hw_value = 100, .center_freq = 5500}, - { .hw_value = 104, .center_freq = 5520}, - { .hw_value = 108, .center_freq = 5540}, { .hw_value = 112, .center_freq = 5560}, - { .hw_value = 116, .center_freq = 5580}, - { .hw_value = 120, .center_freq = 5600}, - { .hw_value = 124, .center_freq = 5620}, - { .hw_value = 128, .center_freq = 5640}, { .hw_value = 132, .center_freq = 5660}, + { .hw_value = 157, .center_freq = 5785}, + { .hw_value = 184, .center_freq = 4920}, + { .hw_value = 189, .center_freq = 4945}, + { .hw_value = 9, .center_freq = 5045}, + { .hw_value = 36, .center_freq = 5180}, + { .hw_value = 46, .center_freq = 5230}, + { .hw_value = 64, .center_freq = 5320}, + { .hw_value = 116, .center_freq = 5580}, { .hw_value = 136, .center_freq = 5680}, + { .hw_value = 192, .center_freq = 4960}, + { .hw_value = 11, .center_freq = 5055}, + { .hw_value = 38, .center_freq = 5190}, + { .hw_value = 48, .center_freq = 5240}, + { .hw_value = 100, .center_freq = 5500}, + { .hw_value = 120, .center_freq = 5600}, { .hw_value = 140, .center_freq = 5700}, + { .hw_value = 185, .center_freq = 4925}, + { .hw_value = 196, .center_freq = 4980}, + { .hw_value = 12, .center_freq = 5060}, + { .hw_value = 40, .center_freq = 5200}, + { .hw_value = 52, .center_freq = 5260}, + { .hw_value = 104, .center_freq = 5520}, + { .hw_value = 124, .center_freq = 5620}, { .hw_value = 149, .center_freq = 5745}, - { .hw_value = 153, .center_freq = 5765}, - { .hw_value = 157, .center_freq = 5785}, { .hw_value = 161, .center_freq = 5805}, + { .hw_value = 187, .center_freq = 4935}, + { .hw_value = 7, .center_freq = 5035}, + { .hw_value = 16, .center_freq = 5080}, + { .hw_value = 42, .center_freq = 5210}, + { .hw_value = 56, .center_freq = 5280}, + { .hw_value = 108, .center_freq = 5540}, + { .hw_value = 128, .center_freq = 5640}, + { .hw_value = 153, .center_freq = 5765}, { .hw_value = 165, .center_freq = 5825}, }; -- cgit v1.2.3 From 2f63b011b4a6d3c0572147be5756212f5558fff0 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 10 Aug 2010 06:38:35 +0200 Subject: wl1271: Remove outdated FIXME's Remove outdated FIXME's from the code. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_boot.c | 17 +++++------------ drivers/net/wireless/wl12xx/wl1271_main.c | 7 ++----- drivers/net/wireless/wl12xx/wl1271_tx.c | 2 -- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index e5a7f042645f..f750d5a79089 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -251,8 +251,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) burst_len = nvs_ptr[0]; dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); - /* FIXME: Due to our new wl1271_translate_reg_addr function, - we need to add the REGISTER_BASE to the destination */ + /* + * Due to our new wl1271_translate_reg_addr function, + * we need to add the REGISTER_BASE to the destination + */ dest_addr += REGISTERS_BASE; /* We move our pointer to the data */ @@ -280,8 +282,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; - /* FIXME: The driver sets the partition here, but this is not needed, - since it sets to the same one as currently in use */ /* Now we must set the partition correctly */ wl1271_set_partition(wl, &part_table[PART_WORK]); @@ -291,9 +291,6 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) return -ENOMEM; /* And finally we upload the NVS tables */ - /* FIXME: In wl1271, we upload everything at once. - No endianness handling needed here?! The ref driver doesn't do - anything about it at this point */ wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); kfree(nvs_aligned); @@ -491,10 +488,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); - pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be - * WU_COUNTER_PAUSE_VAL instead of - * 0x3ff (magic number ). How does - * this work?! */ + pause &= ~(WU_COUNTER_PAUSE_VAL); pause |= WU_COUNTER_PAUSE_VAL; wl1271_write32(wl, WU_COUNTER_PAUSE, pause); @@ -548,7 +542,6 @@ int wl1271_boot(struct wl1271 *wl) if (ret < 0) goto out; - /* FIXME: Need to check whether this is really what we want */ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 8ce891aa2273..bbd075a88f2d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -251,7 +251,6 @@ static struct conf_drv_settings default_conf = { .host_fast_wakeup_support = false }, .roam_trigger = { - /* FIXME: due to firmware bug, must use value 1 for now */ .trigger_pacing = 1, .avg_weight_rssi_beacon = 20, .avg_weight_rssi_data = 10, @@ -2281,8 +2280,7 @@ static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, struct wl1271 *wl = dev_get_drvdata(dev); ssize_t len; - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; + len = PAGE_SIZE; mutex_lock(&wl->mutex); len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", @@ -2343,8 +2341,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, struct wl1271 *wl = dev_get_drvdata(dev); ssize_t len; - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; + len = PAGE_SIZE; mutex_lock(&wl->mutex); if (wl->hw_pg_ver >= 0) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index dc0b46c93c4b..0f99eff3b7ef 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -422,8 +422,6 @@ void wl1271_tx_reset(struct wl1271 *wl) struct sk_buff *skb; /* TX failure */ -/* control->flags = 0; FIXME */ - while ((skb = skb_dequeue(&wl->tx_queue))) { wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); ieee80211_tx_status(wl->hw, skb); -- cgit v1.2.3 From 03f06b7efc8cbc666bd096b68bdf955388e0b323 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 10 Aug 2010 06:38:36 +0200 Subject: wl1271: Move setting of wake-up conditions to ps.c from cmd.c This removes a fixme. Also, it removes a redundant setting of the wake-up conditions when exiting power save mode, which should improve performance. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 7 ------- drivers/net/wireless/wl12xx/wl1271_ps.c | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index a338b1c93a29..a516035350d5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -395,13 +395,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) struct wl1271_cmd_ps_params *ps_params = NULL; int ret = 0; - /* FIXME: this should be in ps.c */ - ret = wl1271_acx_wake_up_conditions(wl); - if (ret < 0) { - wl1271_error("couldn't set wake up conditions"); - goto out; - } - wl1271_debug(DEBUG_CMD, "cmd set ps mode"); ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index a5e60e0403e5..52a60959bb9c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -129,6 +129,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, case STATION_POWER_SAVE_MODE: wl1271_debug(DEBUG_PSM, "entering psm"); + ret = wl1271_acx_wake_up_conditions(wl); + if (ret < 0) { + wl1271_error("couldn't set wake up conditions"); + return ret; + } + ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send); if (ret < 0) return ret; -- cgit v1.2.3 From 165530974504e21d79a43e5f964bd9284e45a8f1 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 17 Aug 2010 03:50:04 +0200 Subject: wl1271: Remove acx_fw_version function It's not used anywhere. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_acx.c | 34 -------------------------------- drivers/net/wireless/wl12xx/wl1271_acx.h | 30 ---------------------------- 2 files changed, 64 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index f03ad088db8b..618993405262 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -86,40 +86,6 @@ out: return ret; } -int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len) -{ - struct acx_revision *rev; - int ret; - - wl1271_debug(DEBUG_ACX, "acx fw rev"); - - rev = kzalloc(sizeof(*rev), GFP_KERNEL); - if (!rev) { - ret = -ENOMEM; - goto out; - } - - ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); - if (ret < 0) { - wl1271_warning("ACX_FW_REV interrogate failed"); - goto out; - } - - /* be careful with the buffer sizes */ - strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); - - /* - * if the firmware version string is exactly - * sizeof(rev->fw_version) long or fw_len is less than - * sizeof(rev->fw_version) it won't be null terminated - */ - buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; - -out: - kfree(rev); - return ret; -} - int wl1271_acx_tx_power(struct wl1271 *wl, int power) { struct acx_current_tx_power *acx; diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 5c8bb7fd2eb9..ebb341d36e8c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -100,35 +100,6 @@ struct acx_error_counter { __le32 seq_num_miss; } __packed; -struct acx_revision { - struct acx_header header; - - /* - * The WiLink firmware version, an ASCII string x.x.x.x, - * that uniquely identifies the current firmware. - * The left most digit is incremented each time a - * significant change is made to the firmware, such as - * code redesign or new platform support. - * The second digit is incremented when major enhancements - * are added or major fixes are made. - * The third digit is incremented for each GA release. - * The fourth digit is incremented for each build. - * The first two digits identify a firmware release version, - * in other words, a unique set of features. - * The first three digits identify a GA release. - */ - char fw_version[20]; - - /* - * This 4 byte field specifies the WiLink hardware version. - * bits 0 - 15: Reserved. - * bits 16 - 23: Version ID - The WiLink version ID - * (1 = first spin, 2 = second spin, and so on). - * bits 24 - 31: Chip ID - The WiLink chip ID. - */ - __le32 hw_version; -} __packed; - enum wl1271_psm_mode { /* Active mode */ WL1271_PSM_CAM = 0, @@ -1076,7 +1047,6 @@ enum { int wl1271_acx_wake_up_conditions(struct wl1271 *wl); int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); -int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len); int wl1271_acx_tx_power(struct wl1271 *wl, int power); int wl1271_acx_feature_cfg(struct wl1271 *wl); int wl1271_acx_mem_map(struct wl1271 *wl, -- cgit v1.2.3 From 4e23b11b08ed116664cce6114546d5a96eb94e8b Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Fri, 13 Aug 2010 04:46:48 +0200 Subject: wl1271: Release interrupt *after* releasing the driver context The current order causes driver releasing to fail in various ways, and causes possible instability. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 3 +-- drivers/net/wireless/wl12xx/wl1271_spi.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index f2f04663627c..4c250d7dc3fa 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -274,9 +274,8 @@ static void __devexit wl1271_remove(struct sdio_func *func) { struct wl1271 *wl = sdio_get_drvdata(func); - free_irq(wl->irq, wl); - wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); wl1271_free_hw(wl); } diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index ced0a9e2c7e1..75cbf36146e2 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -416,9 +416,8 @@ static int __devexit wl1271_remove(struct spi_device *spi) { struct wl1271 *wl = dev_get_drvdata(&spi->dev); - free_irq(wl->irq, wl); - wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); wl1271_free_hw(wl); return 0; -- cgit v1.2.3 From 18c311b71899803de91f1ed41b9d87eb81017a91 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 17 Aug 2010 04:09:34 +0200 Subject: wl1271: Remove function cmd_read_memory The function is not used anywhere. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 35 ------------------------------ drivers/net/wireless/wl12xx/wl1271_cmd.h | 37 -------------------------------- 2 files changed, 72 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index a516035350d5..42e7d2f236c4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -421,41 +421,6 @@ out: return ret; } -int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, - size_t len) -{ - struct cmd_read_write_memory *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd read memory"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - WARN_ON(len > MAX_READ_SIZE); - len = min_t(size_t, len, MAX_READ_SIZE); - - cmd->addr = cpu_to_le32(addr); - cmd->size = cpu_to_le32(len); - - ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd), - sizeof(*cmd)); - if (ret < 0) { - wl1271_error("read memory command failed: %d", ret); - goto out; - } - - /* the read command got in */ - memcpy(answer, cmd->value, len); - -out: - kfree(cmd); - return ret; -} - int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates) { diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index ce0476ceb84a..92747cece15e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -39,8 +39,6 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); -int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, - size_t len); int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates); int wl1271_cmd_build_null_data(struct wl1271 *wl); @@ -161,41 +159,6 @@ enum { MAX_COMMAND_STATUS = 0xff }; - -/* - * CMD_READ_MEMORY - * - * The host issues this command to read the WiLink device memory/registers. - * - * Note: The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -/* - * CMD_WRITE_MEMORY - * - * The host issues this command to write the WiLink device memory/registers. - * - * The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -#define MAX_READ_SIZE 256 - -struct cmd_read_write_memory { - struct wl1271_cmd_header header; - - /* The address of the memory to read from or write to.*/ - __le32 addr; - - /* The amount of data in bytes to read from or write to the WiLink - * device.*/ - __le32 size; - - /* The actual value read from or written to the Wilink. The source - of this field is the Host in WRITE command or the Wilink in READ - command. */ - u8 value[MAX_READ_SIZE]; -} __packed; - #define CMDMBOX_HEADER_LEN 4 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 -- cgit v1.2.3 From 02fabb0eafde901ae51532ad15fdd4737b7d71e3 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 19 Aug 2010 04:41:15 +0200 Subject: wl1271: Enable/disable 11a support based on INI configuration Instead of hardcoding 11a support, enable/disable driver support based on the dual-mode-select parameter in the nvs-file general paramters. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 18 +++--------------- drivers/net/wireless/wl12xx/wl1271_boot.c | 22 ++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_init.c | 2 +- drivers/net/wireless/wl12xx/wl1271_main.c | 18 +++--------------- drivers/net/wireless/wl12xx/wl1271_scan.c | 2 +- drivers/net/wireless/wl12xx/wl1271_testmode.c | 14 +------------- 6 files changed, 31 insertions(+), 45 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 1098d1689b0e..763ece823c54 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -117,11 +117,6 @@ enum { #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) -/* - * Enable/disable 802.11a support for WL1273 - */ -#undef WL1271_80211A_ENABLED - #define WL1271_BUSY_WORD_CNT 1 #define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) @@ -363,6 +358,7 @@ struct wl1271 { u8 *fw; size_t fw_len; struct wl1271_nvs_file *nvs; + size_t nvs_len; s8 hw_pg_ver; @@ -476,6 +472,8 @@ struct wl1271 { bool sg_enabled; + bool enable_11a; + struct list_head list; /* Most recently reported noise in dBm */ @@ -499,14 +497,4 @@ int wl1271_plt_stop(struct wl1271 *wl); #define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ -static inline bool wl1271_11a_enabled(void) -{ - /* FIXME: this could be determined based on the NVS-INI file */ -#ifdef WL1271_80211A_ENABLED - return true; -#else - return false; -#endif -} - #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index f750d5a79089..b91021242098 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -225,6 +225,28 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) if (wl->nvs == NULL) return -ENODEV; + /* + * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band + * configurations) can be removed when those NVS files stop floating + * around. + */ + if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || + wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { + if (wl->nvs->general_params.dual_mode_select) + wl->enable_11a = true; + } + + if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && + (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || + wl->enable_11a)) { + wl1271_error("nvs size is not as expected: %zu != %zu", + wl->nvs_len, sizeof(struct wl1271_nvs_file)); + kfree(wl->nvs); + wl->nvs = NULL; + wl->nvs_len = 0; + return -EILSEQ; + } + /* only the first part of the NVS needs to be uploaded */ nvs_len = sizeof(wl->nvs->nvs); nvs_ptr = (u8 *)wl->nvs->nvs; diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 4447af1557f5..879bae095a63 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -61,7 +61,7 @@ int wl1271_init_templates_config(struct wl1271 *wl) if (ret < 0) return ret; - if (wl1271_11a_enabled()) { + if (wl->enable_11a) { size_t size = sizeof(struct wl12xx_probe_req_template); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, NULL, size, 0, diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index bbd075a88f2d..11e112ff79d6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -622,20 +622,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) return ret; } - /* - * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band - * configurations) can be removed when those NVS files stop floating - * around. - */ - if (fw->size != sizeof(struct wl1271_nvs_file) && - (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE || - wl1271_11a_enabled())) { - wl1271_error("nvs size is not as expected: %zu != %zu", - fw->size, sizeof(struct wl1271_nvs_file)); - ret = -EILSEQ; - goto out; - } - wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); if (!wl->nvs) { @@ -644,6 +630,8 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) goto out; } + wl->nvs_len = fw->size; + out: release_firmware(fw); @@ -2414,7 +2402,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; - if (wl1271_11a_enabled()) + if (wl->enable_11a) wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; wl->hw->queues = 4; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 7f42ca9abab8..8d30150f3f46 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -188,7 +188,7 @@ void wl1271_scan_stm(struct wl1271 *wl) ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, wl->conf.tx.basic_rate); if (ret == WL1271_NOTHING_TO_SCAN) { - if (wl1271_11a_enabled()) + if (wl->enable_11a) wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; else wl->scan.state = WL1271_SCAN_STATE_DONE; diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index 6e0952f79e9a..a3aa84386c88 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c @@ -199,19 +199,6 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) buf = nla_data(tb[WL1271_TM_ATTR_DATA]); len = nla_len(tb[WL1271_TM_ATTR_DATA]); - /* - * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band - * configurations) can be removed when those NVS files stop floating - * around. - */ - if (len != sizeof(struct wl1271_nvs_file) && - (len != WL1271_INI_LEGACY_NVS_FILE_SIZE || - wl1271_11a_enabled())) { - wl1271_error("nvs size is not as expected: %zu != %zu", - len, sizeof(struct wl1271_nvs_file)); - return -EMSGSIZE; - } - mutex_lock(&wl->mutex); kfree(wl->nvs); @@ -224,6 +211,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) } memcpy(wl->nvs, buf, len); + wl->nvs_len = len; wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); -- cgit v1.2.3 From 65cddbf1353212f8ab00c6084e3063d85c419201 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 24 Aug 2010 06:28:03 +0300 Subject: wl1271: Reduce rate used for last PSM entry attempt This patch reduces the rate of the null-func used to enter PSM on the last retry as precaution. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 4 ++-- drivers/net/wireless/wl12xx/wl1271_cmd.h | 4 +++- drivers/net/wireless/wl12xx/wl1271_event.c | 17 ++++++++++++----- drivers/net/wireless/wl12xx/wl1271_main.c | 8 +++++--- drivers/net/wireless/wl12xx/wl1271_ps.c | 8 +++++--- drivers/net/wireless/wl12xx/wl1271_ps.h | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 42e7d2f236c4..06b14f2abf55 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -390,7 +390,7 @@ out: return ret; } -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) { struct wl1271_cmd_ps_params *ps_params = NULL; int ret = 0; @@ -407,7 +407,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) ps_params->send_null_data = send; ps_params->retries = 5; ps_params->hang_over_period = 1; - ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set); + ps_params->null_data_rate = cpu_to_le32(rates); ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, sizeof(*ps_params), 0); diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index 92747cece15e..ff8e35e87d98 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -38,7 +38,9 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); +int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, + size_t len); int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates); int wl1271_cmd_build_null_data(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 25ce2cd5e3f3..bced8296a251 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -52,7 +52,7 @@ void wl1271_pspoll_work(struct work_struct *work) * delivery failure occurred, and no-one changed state since, so * we should go back to powersave. */ - wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true); + wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); out: mutex_unlock(&wl->mutex); @@ -70,7 +70,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl) /* force active mode receive data from the AP */ if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true); + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, true); if (ret < 0) return; set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); @@ -91,6 +92,8 @@ static int wl1271_event_ps_report(struct wl1271 *wl, bool *beacon_loss) { int ret = 0; + u32 total_retries = wl->conf.conn.psm_entry_retries; + u32 rates; wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); @@ -104,10 +107,14 @@ static int wl1271_event_ps_report(struct wl1271 *wl, break; } - if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { + if (wl->psm_entry_retry < total_retries) { wl->psm_entry_retry++; + if (wl->psm_entry_retry == total_retries) + rates = wl->basic_rate; + else + rates = wl->basic_rate_set; ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - true); + rates, true); } else { wl1271_info("No ack to nullfunc from AP."); wl->psm_entry_retry = 0; @@ -143,7 +150,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl, /* make sure the firmware goes to active mode - the frame to be sent next will indicate to the AP, that we are active. */ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - false); + wl->basic_rate, false); break; case EVENT_EXIT_POWER_SAVE_SUCCESS: default: diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 11e112ff79d6..81f92a0100d9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1341,7 +1341,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { wl1271_debug(DEBUG_PSM, "psm enabled"); ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - true); + wl->basic_rate_set, true); } } else if (!(conf->flags & IEEE80211_CONF_PS) && test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { @@ -1351,7 +1351,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_PSM, &wl->flags)) ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - true); + wl->basic_rate_set, true); } if (conf->power_level != wl->power_level) { @@ -1826,7 +1826,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && !test_bit(WL1271_FLAG_PSM, &wl->flags)) { mode = STATION_POWER_SAVE_MODE; - ret = wl1271_ps_set_mode(wl, mode, true); + ret = wl1271_ps_set_mode(wl, mode, + wl->basic_rate_set, + true); if (ret < 0) goto out_sleep; } diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index 52a60959bb9c..f75668e413fd 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -121,7 +121,7 @@ out: } int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - bool send) + u32 rates, bool send) { int ret; @@ -135,7 +135,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, return ret; } - ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send); + ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, + rates, send); if (ret < 0) return ret; @@ -158,7 +159,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, if (ret < 0) return ret; - ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send); + ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, + rates, send); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h index 940276f517a4..6ba7b032736f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.h +++ b/drivers/net/wireless/wl12xx/wl1271_ps.h @@ -28,7 +28,7 @@ #include "wl1271_acx.h" int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - bool send); + u32 rates, bool send); void wl1271_ps_elp_sleep(struct wl1271 *wl); int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); void wl1271_elp_work(struct work_struct *work); -- cgit v1.2.3 From 11eb54298fa7197cb4187f8a3474ead0709f76ff Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 24 Aug 2010 06:28:03 +0300 Subject: wl1271: Enable 11a support always, prevent scanning for unsupporting chips This patch always enables 11a band towards the mac80211, but prevents scanning (and hence the usage of) 11a band channels if the chipset does not support it. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_init.c | 15 +++++++-------- drivers/net/wireless/wl12xx/wl1271_main.c | 4 +--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 879bae095a63..5614a352528b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl) int wl1271_init_templates_config(struct wl1271 *wl) { int ret, i; + size_t size; /* send empty templates for fw memory reservation */ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, @@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl) if (ret < 0) return ret; - if (wl->enable_11a) { - size_t size = sizeof(struct wl12xx_probe_req_template); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - NULL, size, 0, - WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - } + size = sizeof(struct wl12xx_probe_req_template); + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + NULL, size, 0, + WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, sizeof(struct wl12xx_null_data_template), diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 81f92a0100d9..f0c253213cd8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2403,9 +2403,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) BIT(NL80211_IFTYPE_ADHOC); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; - - if (wl->enable_11a) - wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; + wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; wl->hw->queues = 4; wl->hw->max_rates = 1; -- cgit v1.2.3 From ed484a16b495ee7e13cb28fd6ff6053d10657633 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 1 Sep 2010 11:31:11 +0200 Subject: wl1271: Fix tid-configuration of TX frames Incorrect TID was configured for TX frames. This resulted in incorrect queues to be used for classes in transmission. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_tx.c | 4 ++-- drivers/net/wireless/wl12xx/wl1271_tx.h | 17 ----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 0f99eff3b7ef..1b8295c5dde4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -110,9 +110,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, /* configure the tx attributes */ tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; - /* queue */ + /* queue (we use same identifiers for tid's and ac's */ ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - desc->tid = wl1271_tx_ac_to_tid(ac); + desc->tid = ac; desc->aid = TX_HW_DEFAULT_AID; desc->reserved = 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 48bf92621c03..d12a129ad11c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h @@ -139,23 +139,6 @@ static inline int wl1271_tx_get_queue(int queue) } } -/* wl1271 tx descriptor needs the tid and we need to convert it from ac */ -static inline int wl1271_tx_ac_to_tid(int ac) -{ - switch (ac) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 4; - case 3: - return 6; - default: - return 0; - } -} - void wl1271_tx_work(struct work_struct *work); void wl1271_tx_complete(struct wl1271 *wl); void wl1271_tx_reset(struct wl1271 *wl); -- cgit v1.2.3 From 9987a9da3eda093ceeff14ad4926adb130a0d0ea Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Wed, 1 Sep 2010 11:31:12 +0200 Subject: wl1271: Fix AC/TID default configuration The WMM queue default configuration was incorrect, and caused uapsd mode problems (among possible others.) Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_conf.h | 2 +- drivers/net/wireless/wl12xx/wl1271_init.c | 20 ++++---- drivers/net/wireless/wl12xx/wl1271_main.c | 84 +++++++++++-------------------- 3 files changed, 39 insertions(+), 67 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index 0435ffda8f73..feb493ebe5bd 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -595,7 +595,7 @@ struct conf_tx_ac_category { u16 tx_op_limit; }; -#define CONF_TX_MAX_TID_COUNT 7 +#define CONF_TX_MAX_TID_COUNT 8 enum { CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 5614a352528b..349571fe04b3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -290,8 +290,16 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Default TID configuration */ + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + conf_tid = &wl->conf.tx.tid_conf[i]; ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, conf_tid->channel_type, @@ -304,16 +312,6 @@ int wl1271_hw_init(struct wl1271 *wl) goto out_free_memmap; } - /* Default AC configuration */ - for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - } - /* Configure TX rate classes */ ret = wl1271_acx_rate_policies(wl); if (ret < 0) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index f0c253213cd8..4b8f3662101f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -124,28 +124,28 @@ static struct conf_drv_settings default_conf = { }, .ac_conf_count = 4, .ac_conf = { - [0] = { + [CONF_TX_AC_BE] = { .ac = CONF_TX_AC_BE, .cw_min = 15, .cw_max = 63, .aifsn = 3, .tx_op_limit = 0, }, - [1] = { + [CONF_TX_AC_BK] = { .ac = CONF_TX_AC_BK, .cw_min = 15, .cw_max = 63, .aifsn = 7, .tx_op_limit = 0, }, - [2] = { + [CONF_TX_AC_VI] = { .ac = CONF_TX_AC_VI, .cw_min = 15, .cw_max = 63, .aifsn = CONF_TX_AIFS_PIFS, .tx_op_limit = 3008, }, - [3] = { + [CONF_TX_AC_VO] = { .ac = CONF_TX_AC_VO, .cw_min = 15, .cw_max = 63, @@ -153,64 +153,40 @@ static struct conf_drv_settings default_conf = { .tx_op_limit = 1504, }, }, - .tid_conf_count = 7, + .tid_conf_count = 4, .tid_conf = { - [0] = { - .queue_id = 0, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [1] = { - .queue_id = 1, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [2] = { - .queue_id = 2, - .channel_type = CONF_CHANNEL_TYPE_DCF, + [CONF_TX_AC_BE] = { + .queue_id = CONF_TX_AC_BE, + .channel_type = CONF_CHANNEL_TYPE_EDCF, .tsid = CONF_TX_AC_BE, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [3] = { - .queue_id = 3, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_BK] = { + .queue_id = CONF_TX_AC_BK, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BK, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [4] = { - .queue_id = 4, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_VI] = { + .queue_id = CONF_TX_AC_VI, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VI, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [5] = { - .queue_id = 5, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_VO] = { + .queue_id = CONF_TX_AC_VO, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VO, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [6] = { - .queue_id = 6, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - } }, .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, .tx_compl_timeout = 700, @@ -406,8 +382,16 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Default TID configuration */ + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + conf_tid = &wl->conf.tx.tid_conf[i]; ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, conf_tid->channel_type, @@ -420,16 +404,6 @@ static int wl1271_plt_init(struct wl1271 *wl) goto out_free_memmap; } - /* Default AC configuration */ - for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - } - /* Enable data path */ ret = wl1271_cmd_data_path(wl, 1); if (ret < 0) -- cgit v1.2.3 From c454f1d9a896d3519c756355b37bb39941093233 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 24 Aug 2010 06:28:03 +0300 Subject: wl1271: Move scan complete invocation into work function The current scan implementation can jam, if the scan request ends up containing no work. This can especially happen if there is a scan request with only 11a band channels for HW that does not support 11a. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 1 + drivers/net/wireless/wl12xx/wl1271_main.c | 4 ++++ drivers/net/wireless/wl12xx/wl1271_scan.c | 23 ++++++++++++++++++----- drivers/net/wireless/wl12xx/wl1271_scan.h | 1 + 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 763ece823c54..272cff44ab53 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -416,6 +416,7 @@ struct wl1271 { /* Are we currently scanning */ struct wl1271_scan scan; + struct work_struct scan_complete_work; /* Our association ID */ u16 aid; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 4b8f3662101f..0026e775bb0d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -634,6 +634,8 @@ static int wl1271_setup(struct wl1271 *wl) INIT_WORK(&wl->irq_work, wl1271_irq_work); INIT_WORK(&wl->tx_work, wl1271_tx_work); + INIT_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + return 0; } @@ -962,6 +964,8 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, struct wl1271 *wl = hw->priv; int i; + cancel_work_sync(&wl->scan_complete_work); + mutex_lock(&wl->mutex); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 8d30150f3f46..9f1da82ed8d6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -28,6 +28,23 @@ #include "wl1271_scan.h" #include "wl1271_acx.h" +void wl1271_scan_complete_work(struct work_struct *work) +{ + struct wl1271 *wl = + container_of(work, struct wl1271, scan_complete_work); + + wl1271_debug(DEBUG_SCAN, "Scanning complete"); + + mutex_lock(&wl->mutex); + wl->scan.state = WL1271_SCAN_STATE_IDLE; + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; + mutex_unlock(&wl->mutex); + + ieee80211_scan_completed(wl->hw, false); +} + + static int wl1271_get_scan_channels(struct wl1271 *wl, struct cfg80211_scan_request *req, struct basic_scan_channel_params *channels, @@ -218,11 +235,7 @@ void wl1271_scan_stm(struct wl1271 *wl) break; case WL1271_SCAN_STATE_DONE: - kfree(wl->scan.scanned_ch); - wl->scan.scanned_ch = NULL; - - wl->scan.state = WL1271_SCAN_STATE_IDLE; - ieee80211_scan_completed(wl->hw, false); + ieee80211_queue_work(wl->hw, &wl->scan_complete_work); break; default: diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index f1815700f5f9..1404e00dc963 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h @@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u8 band); void wl1271_scan_stm(struct wl1271 *wl); +void wl1271_scan_complete_work(struct work_struct *work); #define WL1271_SCAN_MAX_CHANNELS 24 #define WL1271_SCAN_DEFAULT_TAG 1 -- cgit v1.2.3 From 8c7f4f3166e16bb350bfc53955ea6cf9bfd34aab Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 21 Sep 2010 06:23:29 +0200 Subject: wl1271: Fix work cancelling when shutting down the driver The work cancelling has had several hazards, ranging from potentially executing work after the driver is in OFF state, to executing work after the driver and relevant memory structures are already removed. Fix these. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_event.c | 3 +++ drivers/net/wireless/wl12xx/wl1271_main.c | 3 +++ drivers/net/wireless/wl12xx/wl1271_ps.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index bced8296a251..e6c839af9038 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work) mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) goto out; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 0026e775bb0d..9ab4fc4f7b4b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -792,6 +792,8 @@ int wl1271_plt_stop(struct wl1271 *wl) out: mutex_unlock(&wl->mutex); + cancel_work_sync(&wl->irq_work); + return ret; } @@ -995,6 +997,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->pspoll_work); + cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index f75668e413fd..150dc674d8b4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -39,6 +39,9 @@ void wl1271_elp_work(struct work_struct *work) mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || (!test_bit(WL1271_FLAG_PSM, &wl->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags))) -- cgit v1.2.3 From 52a2a37550b604b3c3c7a044ff72d85b60165659 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 21 Sep 2010 06:23:30 +0200 Subject: wl1271: Separate interface removal to another function Do this so the interface removal can be triggered from an upcoming hardware failure recovery mechanism. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 17 +++++++++++------ drivers/net/wireless/wl12xx/wl1271_scan.c | 6 ++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 9ab4fc4f7b4b..e7f096fb6212 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -960,15 +960,10 @@ out: return ret; } -static void wl1271_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void __wl1271_op_remove_interface(struct wl1271 *wl) { - struct wl1271 *wl = hw->priv; int i; - cancel_work_sync(&wl->scan_complete_work); - - mutex_lock(&wl->mutex); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); wl1271_info("down"); @@ -994,6 +989,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&wl->mutex); + cancel_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->pspoll_work); @@ -1039,7 +1035,16 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, wl->tx_res_if = NULL; kfree(wl->target_mem_map); wl->target_mem_map = NULL; +} +static void wl1271_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1271 *wl = hw->priv; + + mutex_lock(&wl->mutex); + WARN_ON(wl->vif != vif); + __wl1271_op_remove_interface(wl); mutex_unlock(&wl->mutex); } diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 9f1da82ed8d6..20caceba435e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -36,6 +36,12 @@ void wl1271_scan_complete_work(struct work_struct *work) wl1271_debug(DEBUG_SCAN, "Scanning complete"); mutex_lock(&wl->mutex); + + if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { + mutex_unlock(&wl->mutex); + return; + } + wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; -- cgit v1.2.3 From 52b0e7a61fd4b67fe8efe295297d8549f052f786 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 21 Sep 2010 06:23:31 +0200 Subject: wl1271: Add hardware recovery mechanism There is some probability of hardware failures, which currently go largely undetected. Attempt to recover from these failures by shutting down the hardware, and requesting mac80211 to reconfigure it. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 3 +++ drivers/net/wireless/wl12xx/wl1271_cmd.c | 5 ++++- drivers/net/wireless/wl12xx/wl1271_main.c | 28 +++++++++++++++++++++++++++- drivers/net/wireless/wl12xx/wl1271_ps.c | 3 ++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 272cff44ab53..3576c1cb067f 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -408,6 +408,9 @@ struct wl1271 { /* The target interrupt mask */ struct work_struct irq_work; + /* Hardware recovery work */ + struct work_struct recovery_work; + /* The mbox event mask */ u32 event_mask; diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 06b14f2abf55..170b5a8bdabc 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, status = le16_to_cpu(cmd->status); if (status != CMD_STATUS_SUCCESS) { wl1271_error("command execute failure %d", status); + ieee80211_queue_work(wl->hw, &wl->recovery_work); ret = -EIO; } @@ -182,8 +183,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); do { - if (time_after(jiffies, timeout)) + if (time_after(jiffies, timeout)) { + ieee80211_queue_work(wl->hw, &wl->recovery_work); return -ETIMEDOUT; + } msleep(1); diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index e7f096fb6212..fecb0c313a1d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -235,6 +235,9 @@ static struct conf_drv_settings default_conf = { } }; +static void __wl1271_op_remove_interface(struct wl1271 *wl); + + static void wl1271_device_release(struct device *dev) { @@ -612,6 +615,26 @@ out: return ret; } +static void wl1271_recovery_work(struct work_struct *work) +{ + struct wl1271 *wl = + container_of(work, struct wl1271, recovery_work); + + mutex_lock(&wl->mutex); + + if (wl->state != WL1271_STATE_ON) + goto out; + + wl1271_info("Hardware recovery in progress."); + + /* reboot the chipset */ + __wl1271_op_remove_interface(wl); + ieee80211_restart_hw(wl->hw); + +out: + mutex_unlock(&wl->mutex); +} + static void wl1271_fw_wakeup(struct wl1271 *wl) { u32 elp_reg; @@ -635,6 +658,7 @@ static int wl1271_setup(struct wl1271 *wl) INIT_WORK(&wl->irq_work, wl1271_irq_work); INIT_WORK(&wl->tx_work, wl1271_tx_work); INIT_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + INIT_WORK(&wl->recovery_work, wl1271_recovery_work); return 0; } @@ -793,11 +817,11 @@ out: mutex_unlock(&wl->mutex); cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->recovery_work); return ret; } - static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; @@ -1046,6 +1070,8 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, WARN_ON(wl->vif != vif); __wl1271_op_remove_interface(wl); mutex_unlock(&wl->mutex); + + cancel_work_sync(&wl->recovery_work); } static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index 150dc674d8b4..e3c332e2f97c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -64,7 +64,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) test_bit(WL1271_FLAG_IDLE, &wl->flags)) { cancel_delayed_work(&wl->elp_work); ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(ELP_ENTRY_DELAY)); + msecs_to_jiffies(ELP_ENTRY_DELAY)); } } @@ -99,6 +99,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); if (ret == 0) { wl1271_error("ELP wakeup timeout!"); + ieee80211_queue_work(wl->hw, &wl->recovery_work); ret = -ETIMEDOUT; goto err; } else if (ret < 0) { -- cgit v1.2.3 From 78abd3207438b20e099b41cbed58d640cbd237a6 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 21 Sep 2010 06:23:32 +0200 Subject: wl1271: Add handling for failing hardware scan command Currently, the driver does not handle a failing hardware command to scan in any way - effectively, the scan machine will jam until the driver is shut down, and future scan requests will just return -EBUSY to user space, resulting in a type of busy-loop. The same problem occurs if the firmware fails to deliver the scan completion event - add timeout for this. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 3 ++- drivers/net/wireless/wl12xx/wl1271_main.c | 4 ++-- drivers/net/wireless/wl12xx/wl1271_scan.c | 30 ++++++++++++++++++++++++++---- drivers/net/wireless/wl12xx/wl1271_scan.h | 2 ++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 3576c1cb067f..cae489300e06 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -296,6 +296,7 @@ struct wl1271_rx_mem_pool_addr { struct wl1271_scan { struct cfg80211_scan_request *req; bool *scanned_ch; + bool failed; u8 state; u8 ssid[IW_ESSID_MAX_SIZE+1]; size_t ssid_len; @@ -419,7 +420,7 @@ struct wl1271 { /* Are we currently scanning */ struct wl1271_scan scan; - struct work_struct scan_complete_work; + struct delayed_work scan_complete_work; /* Our association ID */ u16 aid; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index fecb0c313a1d..c13175892960 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -657,8 +657,8 @@ static int wl1271_setup(struct wl1271 *wl) INIT_WORK(&wl->irq_work, wl1271_irq_work); INIT_WORK(&wl->tx_work, wl1271_tx_work); - INIT_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); INIT_WORK(&wl->recovery_work, wl1271_recovery_work); + INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); return 0; } @@ -1013,7 +1013,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) mutex_unlock(&wl->mutex); - cancel_work_sync(&wl->scan_complete_work); + cancel_delayed_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->pspoll_work); diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 20caceba435e..37f9ccbe738f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -30,8 +30,11 @@ void wl1271_scan_complete_work(struct work_struct *work) { - struct wl1271 *wl = - container_of(work, struct wl1271, scan_complete_work); + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, scan_complete_work); wl1271_debug(DEBUG_SCAN, "Scanning complete"); @@ -48,6 +51,11 @@ void wl1271_scan_complete_work(struct work_struct *work) mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, false); + + if (wl->scan.failed) { + wl1271_info("Scan completed due to error."); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + } } @@ -191,7 +199,7 @@ out: void wl1271_scan_stm(struct wl1271 *wl) { - int ret; + int ret = 0; switch (wl->scan.state) { case WL1271_SCAN_STATE_IDLE: @@ -241,13 +249,22 @@ void wl1271_scan_stm(struct wl1271 *wl) break; case WL1271_SCAN_STATE_DONE: - ieee80211_queue_work(wl->hw, &wl->scan_complete_work); + wl->scan.failed = false; + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); break; default: wl1271_error("invalid scan state"); break; } + + if (ret < 0) { + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); + } } int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, @@ -270,6 +287,11 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, wl->scan.scanned_ch = kzalloc(req->n_channels * sizeof(*wl->scan.scanned_ch), GFP_KERNEL); + /* we assume failure so that timeout scenarios are handled correctly */ + wl->scan.failed = true; + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); + wl1271_scan_stm(wl); return 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index 1404e00dc963..bb7af2a102fa 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h @@ -46,6 +46,8 @@ void wl1271_scan_complete_work(struct work_struct *work); #define WL1271_SCAN_BAND_5_GHZ 1 #define WL1271_SCAN_PROBE_REQS 3 +#define WL1271_SCAN_TIMEOUT 10000 /* msec */ + enum { WL1271_SCAN_STATE_IDLE, WL1271_SCAN_STATE_2GHZ_ACTIVE, -- cgit v1.2.3 From bea39d6a60b62f16e904be5a520bf55714d73021 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 21 Sep 2010 08:14:31 +0200 Subject: wl1271: Optimize scan duration Currently then dwell times for each channel in scans is set to an overly long value, and excessive number of probe-requests are transmitted on each channel (for active scans.) Based on testing, comparable results can be received with smaller dwell-time, and, with fever probe-requests - in fact, reducing the number of probe-requests to 2 seems to increase the number of found results. Configure more optimal values for per channel dwell times. Comparison for the different scan configurations (in my current office environment): dwell-time 60000 3x probe-req == ~60 results 40000 3x probe-req == ~50 results 30000 3x probe-req == ~40 results dwell-time 60000 2x probe-req == ~70 results 40000 2x probe-req == ~60 results 30000 2x probe-req == ~58 results The above are results for a cumulative 3 scan run. For individual scans, the number of results drop slightly more. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_conf.h | 39 +++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_main.c | 9 ++++++- drivers/net/wireless/wl12xx/wl1271_scan.c | 18 ++++++++++---- drivers/net/wireless/wl12xx/wl1271_scan.h | 3 --- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index feb493ebe5bd..ab716f517553 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -1016,6 +1016,44 @@ struct conf_roam_trigger_settings { u8 avg_weight_snr_data; }; +struct conf_scan_settings { + /* + * The minimum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_active; + + /* + * The maximum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_active; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_passive; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_passive; + + /* + * Number of probe requests to transmit on each active scan channel + * + * Range: u8 + */ + u16 num_probe_reqs; + +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1024,6 +1062,7 @@ struct conf_drv_settings { struct conf_itrim_settings itrim; struct conf_pm_config_settings pm_config; struct conf_roam_trigger_settings roam_trigger; + struct conf_scan_settings scan; }; #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index c13175892960..b2f2d457f28c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -232,7 +232,14 @@ static struct conf_drv_settings default_conf = { .avg_weight_rssi_data = 10, .avg_weight_snr_beacon = 20, .avg_weight_snr_data = 10 - } + }, + .scan = { + .min_dwell_time_active = 7500, + .max_dwell_time_active = 30000, + .min_dwell_time_passive = 30000, + .max_dwell_time_passive = 60000, + .num_probe_reqs = 2, + }, }; static void __wl1271_op_remove_interface(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 37f9ccbe738f..5c76b79a96bf 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -64,6 +64,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, struct basic_scan_channel_params *channels, enum ieee80211_band band, bool passive) { + struct conf_scan_settings *c = &wl->conf.scan; int i, j; u32 flags; @@ -91,10 +92,17 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, wl1271_debug(DEBUG_SCAN, "beacon_found %d", req->channels[i]->beacon_found); - channels[j].min_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); - channels[j].max_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); + if (!passive) { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_active); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_active); + } else { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_passive); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_passive); + } channels[j].early_termination = 0; channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; @@ -151,7 +159,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS; + cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; cmd->params.tx_rate = cpu_to_le32(basic_rate); cmd->params.tid_trigger = 0; cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index bb7af2a102fa..6d57127b5e6b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h @@ -40,11 +40,8 @@ void wl1271_scan_complete_work(struct work_struct *work); #define WL1271_SCAN_OPT_ACTIVE 0 #define WL1271_SCAN_OPT_PASSIVE 1 #define WL1271_SCAN_OPT_PRIORITY_HIGH 4 -#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */ -#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ #define WL1271_SCAN_BAND_2_4_GHZ 0 #define WL1271_SCAN_BAND_5_GHZ 1 -#define WL1271_SCAN_PROBE_REQS 3 #define WL1271_SCAN_TIMEOUT 10000 /* msec */ -- cgit v1.2.3 From 8eab7b4708b5ef4701ecbe5d659f99743b77b668 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Fri, 24 Sep 2010 03:10:11 +0200 Subject: wl1271: Increase connection reliability This patch improves connection reliability by choosing the lowest basic rate for null-func frames (which increases their range, as the firmware does not do rate fall-back for null-func frames.) Also, increase the PSM entry retry-counter. Signed-off-by: Juuso Oikarinen Reviewed-by: Teemu Paasikivi Tested-by: Tuomas Katila Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 10 +++++----- drivers/net/wireless/wl12xx/wl1271_conf.h | 16 ++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_event.c | 7 +------ drivers/net/wireless/wl12xx/wl1271_main.c | 10 ++++++---- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 170b5a8bdabc..4a56ab05e736 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -408,8 +408,8 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) ps_params->ps_mode = ps_mode; ps_params->send_null_data = send; - ps_params->retries = 5; - ps_params->hang_over_period = 1; + ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; + ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; ps_params->null_data_rate = cpu_to_le32(rates); ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, @@ -484,7 +484,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl) } ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); out: dev_kfree_skb(skb); @@ -507,7 +507,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, skb->data, skb->len, CMD_TEMPL_KLV_IDX_NULL_DATA, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); out: dev_kfree_skb(skb); @@ -584,7 +584,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl) return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, sizeof(template), 0, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); } int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index ab716f517553..60c50d1a9835 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -911,6 +911,22 @@ struct conf_conn_settings { */ u8 psm_entry_retries; + /* + * Specifies the maximum number of times to try transmit the PSM entry + * null-func frame for each PSM entry attempt + * + * Range 0 - 255 + */ + u8 psm_entry_nullfunc_retries; + + /* + * Specifies the time to linger in active mode after successfully + * transmitting the PSM entry null-func frame. + * + * Range 0 - 255 TU's + */ + u8 psm_entry_hangover_period; + /* * * Specifies the interval of the connection keep-alive null-func diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index e6c839af9038..7b3f50382963 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -96,7 +96,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl, { int ret = 0; u32 total_retries = wl->conf.conn.psm_entry_retries; - u32 rates; wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); @@ -112,12 +111,8 @@ static int wl1271_event_ps_report(struct wl1271 *wl, if (wl->psm_entry_retry < total_retries) { wl->psm_entry_retry++; - if (wl->psm_entry_retry == total_retries) - rates = wl->basic_rate; - else - rates = wl->basic_rate_set; ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - rates, true); + wl->basic_rate, true); } else { wl1271_info("No ack to nullfunc from AP."); wl->psm_entry_retry = 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index b2f2d457f28c..b7e9c69f3772 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -214,7 +214,9 @@ static struct conf_drv_settings default_conf = { .ps_poll_recovery_period = 700, .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 10, - .psm_entry_retries = 3, + .psm_entry_retries = 5, + .psm_entry_nullfunc_retries = 3, + .psm_entry_hangover_period = 1, .keep_alive_interval = 55000, .max_listen_interval = 20, }, @@ -1360,7 +1362,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { wl1271_debug(DEBUG_PSM, "psm enabled"); ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - wl->basic_rate_set, true); + wl->basic_rate, true); } } else if (!(conf->flags & IEEE80211_CONF_PS) && test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { @@ -1370,7 +1372,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_PSM, &wl->flags)) ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate_set, true); + wl->basic_rate, true); } if (conf->power_level != wl->power_level) { @@ -1846,7 +1848,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, !test_bit(WL1271_FLAG_PSM, &wl->flags)) { mode = STATION_POWER_SAVE_MODE; ret = wl1271_ps_set_mode(wl, mode, - wl->basic_rate_set, + wl->basic_rate, true); if (ret < 0) goto out_sleep; -- cgit v1.2.3 From 7a55724e0dc24cadaeb58f8306222a7802a24ff1 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 27 Sep 2010 12:42:07 +0200 Subject: wl1271: Add support for hardware GEM cipher This patch adds support for the hardware GEM cipher suite. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 2 ++ drivers/net/wireless/wl12xx/wl1271_cmd.h | 2 +- drivers/net/wireless/wl12xx/wl1271_main.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index cae489300e06..779b130fdb3e 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -117,6 +117,8 @@ enum { #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) +#define WL1271_CIPHER_SUITE_GEM 0x00147201 + #define WL1271_BUSY_WORD_CNT 1 #define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index ff8e35e87d98..33b946b4cb07 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -279,7 +279,7 @@ enum wl1271_cmd_key_type { KEY_WEP = 1, KEY_TKIP = 2, KEY_AES = 3, - KEY_GEM = 4 + KEY_GEM = 4, }; /* FIXME: Add description for key-types */ diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index b7e9c69f3772..cb18f22bbc5c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -1549,6 +1549,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); break; + case WL1271_CIPHER_SUITE_GEM: + key_type = KEY_GEM; + tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); + break; default: wl1271_error("Unknown key algo 0x%x", key_conf->cipher); @@ -2403,6 +2408,14 @@ EXPORT_SYMBOL_GPL(wl1271_unregister_hw); int wl1271_init_ieee80211(struct wl1271 *wl) { + static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + WL1271_CIPHER_SUITE_GEM, + }; + /* The tx descriptor buffer and the TKIP space. */ wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + sizeof(struct wl1271_tx_hw_descr); @@ -2420,6 +2433,9 @@ int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_CONNECTION_MONITOR | IEEE80211_HW_SUPPORTS_CQM_RSSI; + wl->hw->wiphy->cipher_suites = cipher_suites; + wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); wl->hw->wiphy->max_scan_ssids = 1; -- cgit v1.2.3 From 381bd10aff491216383291879b29461efb575119 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 28 Sep 2010 09:54:27 +0300 Subject: MAINTAINERS: Update git url for the wl1271 driver We are integrating wl1271 commits via a new git tree now and wl1271 development should be made on top of the new tree. Update the repository url accordingly. Cc: John W. Linville Signed-off-by: Luciano Coelho --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6cb1c759eeaa..529bfee8c4b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6321,7 +6321,7 @@ WL1271 WIRELESS DRIVER M: Luciano Coelho L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git S: Maintained F: drivers/net/wireless/wl12xx/wl1271* F: include/linux/wl12xx.h -- cgit v1.2.3 From d99bf6e707444af4df294f54a679f679018d7ec3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 27 Sep 2010 14:00:51 -0400 Subject: wl12xx: fix separate-object-folder builds Make this go away (happens when building with a separate object directory): Assembler messages: Fatal error: can't create drivers/net/wireless/wl12xx/.tmp_wl12xx_platform_data.o: No such file or directory drivers/net/wireless/wl12xx/wl12xx_platform_data.c: In function 'wl12xx_get_platform_data': drivers/net/wireless/wl12xx/wl12xx_platform_data.c:28: error: cannot open drivers/net/wireless/wl12xx/.tmp_wl12xx_platform_data.gcno drivers/net/wireless/wl12xx/wl12xx_platform_data.c:28: confused by earlier errors, bailing out Signed-off-by: John W. Linville Reported-by: Stephen Rothwell Cc: Signed-off-by: Ohad Ben-Cohen --- drivers/net/wireless/Makefile | 3 +-- drivers/net/wireless/wl12xx/Makefile | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 85af697574a6..a13a602edb13 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o obj-$(CONFIG_WL12XX) += wl12xx/ -# small builtin driver bit -obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/wl12xx_platform_data.o +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 078b4398ac1f..0d334d6f86f4 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -16,3 +16,6 @@ wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o obj-$(CONFIG_WL1271) += wl1271.o obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o + +# small builtin driver bit +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o -- cgit v1.2.3 From fc34ecd07f15358e2b29620fafeb8a6a9528ce79 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 28 Sep 2010 10:34:27 -0700 Subject: pch_gbe: add header files Fix build errors, more header files needed. drivers/net/pch_gbe/pch_gbe_main.c:965: error: implicit declaration of function 'tcp_hdr' drivers/net/pch_gbe/pch_gbe_main.c:965: error: invalid type argument of '->' (have 'int') drivers/net/pch_gbe/pch_gbe_main.c:968: error: invalid type argument of '->' (have 'int') drivers/net/pch_gbe/pch_gbe_main.c:976: error: implicit declaration of function 'udp_hdr' drivers/net/pch_gbe/pch_gbe_main.c:976: error: invalid type argument of '->' (have 'int') drivers/net/pch_gbe/pch_gbe_main.c:980: error: invalid type argument of '->' (have 'int') Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index b925ab359fc3..9a940a940a4a 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include /** * pch_gbe_regs_mac_adr - Structure holding values of mac address registers -- cgit v1.2.3 From bc01befdcf3e40979eb518085a075cbf0aacede0 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 28 Sep 2010 21:06:34 +0200 Subject: netfilter: ctnetlink: add support for user-space expectation helpers This patch adds the basic infrastructure to support user-space expectation helpers via ctnetlink and the netfilter queuing infrastructure NFQUEUE. Basically, this patch: * adds NF_CT_EXPECT_USERSPACE flag to identify user-space created expectations. I have also added a sanity check in __nf_ct_expect_check() to avoid that kernel-space helpers may create an expectation if the master conntrack has no helper assigned. * adds some branches to check if the master conntrack helper exists, otherwise we skip the code that refers to kernel-space helper such as the local expectation list and the expectation policy. * allows to set the timeout for user-space expectations with no helper assigned. * a list of expectations created from user-space that depends on ctnetlink (if this module is removed, they are deleted). * includes USERSPACE in the /proc output for expectations that have been created by a user-space helper. This patch also modifies ctnetlink to skip including the helper name in the Netlink messages if no kernel-space helper is set (since no user-space expectation has not kernel-space kernel assigned). You can access an example user-space FTP conntrack helper at: http://people.netfilter.org/pablo/userspace-conntrack-helpers/nf-ftp-helper-userspace-POC.tar.bz Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_conntrack_common.h | 1 + include/net/netfilter/nf_conntrack_expect.h | 1 + net/netfilter/nf_conntrack_expect.c | 62 ++++++++++++++++++++------- net/netfilter/nf_conntrack_netlink.c | 46 +++++++++++++------- 4 files changed, 79 insertions(+), 31 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index fdc50cae861f..23a1a08578a8 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -103,6 +103,7 @@ enum ip_conntrack_expect_events { /* expectation flags */ #define NF_CT_EXPECT_PERMANENT 0x1 #define NF_CT_EXPECT_INACTIVE 0x2 +#define NF_CT_EXPECT_USERSPACE 0x4 #ifdef __KERNEL__ struct ip_conntrack_stat { diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 96bb42af5fae..416b83844485 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -85,6 +85,7 @@ nf_ct_find_expectation(struct net *net, u16 zone, void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); +void nf_ct_remove_userspace_expectations(void); /* Allocate space for an expectation: this is mandatory before calling nf_ct_expect_related. You will have to call put afterwards. */ diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index acb29ccaa41f..b30a1f2aac00 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -38,20 +38,23 @@ static int nf_ct_expect_hash_rnd_initted __read_mostly; static struct kmem_cache *nf_ct_expect_cachep __read_mostly; +static HLIST_HEAD(nf_ct_userspace_expect_list); + /* nf_conntrack_expect helper functions */ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) { struct nf_conn_help *master_help = nfct_help(exp->master); struct net *net = nf_ct_exp_net(exp); - NF_CT_ASSERT(master_help); NF_CT_ASSERT(!timer_pending(&exp->timeout)); hlist_del_rcu(&exp->hnode); net->ct.expect_count--; hlist_del(&exp->lnode); - master_help->expecting[exp->class]--; + if (!(exp->flags & NF_CT_EXPECT_USERSPACE)) + master_help->expecting[exp->class]--; + nf_ct_expect_put(exp); NF_CT_STAT_INC(net, expect_delete); @@ -320,16 +323,21 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) atomic_inc(&exp->use); - hlist_add_head(&exp->lnode, &master_help->expectations); - master_help->expecting[exp->class]++; + if (master_help) { + hlist_add_head(&exp->lnode, &master_help->expectations); + master_help->expecting[exp->class]++; + } else if (exp->flags & NF_CT_EXPECT_USERSPACE) + hlist_add_head(&exp->lnode, &nf_ct_userspace_expect_list); hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]); net->ct.expect_count++; setup_timer(&exp->timeout, nf_ct_expectation_timed_out, (unsigned long)exp); - p = &master_help->helper->expect_policy[exp->class]; - exp->timeout.expires = jiffies + p->timeout * HZ; + if (master_help) { + p = &master_help->helper->expect_policy[exp->class]; + exp->timeout.expires = jiffies + p->timeout * HZ; + } add_timer(&exp->timeout); atomic_inc(&exp->use); @@ -380,7 +388,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) unsigned int h; int ret = 1; - if (!master_help->helper) { + /* Don't allow expectations created from kernel-space with no helper */ + if (!(expect->flags & NF_CT_EXPECT_USERSPACE) && + (!master_help || (master_help && !master_help->helper))) { ret = -ESHUTDOWN; goto out; } @@ -398,13 +408,16 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) } } /* Will be over limit? */ - p = &master_help->helper->expect_policy[expect->class]; - if (p->max_expected && - master_help->expecting[expect->class] >= p->max_expected) { - evict_oldest_expect(master, expect); - if (master_help->expecting[expect->class] >= p->max_expected) { - ret = -EMFILE; - goto out; + if (master_help) { + p = &master_help->helper->expect_policy[expect->class]; + if (p->max_expected && + master_help->expecting[expect->class] >= p->max_expected) { + evict_oldest_expect(master, expect); + if (master_help->expecting[expect->class] + >= p->max_expected) { + ret = -EMFILE; + goto out; + } } } @@ -439,6 +452,21 @@ out: } EXPORT_SYMBOL_GPL(nf_ct_expect_related_report); +void nf_ct_remove_userspace_expectations(void) +{ + struct nf_conntrack_expect *exp; + struct hlist_node *n, *next; + + hlist_for_each_entry_safe(exp, n, next, + &nf_ct_userspace_expect_list, lnode) { + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + } + } +} +EXPORT_SYMBOL_GPL(nf_ct_remove_userspace_expectations); + #ifdef CONFIG_PROC_FS struct ct_expect_iter_state { struct seq_net_private p; @@ -529,8 +557,12 @@ static int exp_seq_show(struct seq_file *s, void *v) seq_printf(s, "PERMANENT"); delim = ","; } - if (expect->flags & NF_CT_EXPECT_INACTIVE) + if (expect->flags & NF_CT_EXPECT_INACTIVE) { seq_printf(s, "%sINACTIVE", delim); + delim = ","; + } + if (expect->flags & NF_CT_EXPECT_USERSPACE) + seq_printf(s, "%sUSERSPACE", delim); helper = rcu_dereference(nfct_help(expect->master)->helper); if (helper) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 0804e0ef6500..b4077be5f663 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1560,8 +1560,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, const struct nf_conntrack_expect *exp) { struct nf_conn *master = exp->master; - struct nf_conntrack_helper *helper; long timeout = (exp->timeout.expires - jiffies) / HZ; + struct nf_conn_help *help; if (timeout < 0) timeout = 0; @@ -1578,9 +1578,14 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)); NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)); NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)); - helper = rcu_dereference(nfct_help(master)->helper); - if (helper) - NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name); + help = nfct_help(master); + if (help) { + struct nf_conntrack_helper *helper; + + helper = rcu_dereference(help->helper); + if (helper) + NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name); + } return 0; @@ -1921,24 +1926,32 @@ ctnetlink_create_expect(struct net *net, u16 zone, if (!h) return -ENOENT; ct = nf_ct_tuplehash_to_ctrack(h); - help = nfct_help(ct); - - if (!help || !help->helper) { - /* such conntrack hasn't got any helper, abort */ - err = -EOPNOTSUPP; - goto out; - } - exp = nf_ct_expect_alloc(ct); if (!exp) { err = -ENOMEM; goto out; } + help = nfct_help(ct); + if (!help) { + if (!cda[CTA_EXPECT_TIMEOUT]) { + err = -EINVAL; + goto out; + } + exp->timeout.expires = + jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ; - if (cda[CTA_EXPECT_FLAGS]) - exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); - else - exp->flags = 0; + exp->flags = NF_CT_EXPECT_USERSPACE; + if (cda[CTA_EXPECT_FLAGS]) { + exp->flags |= + ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); + } + } else { + if (cda[CTA_EXPECT_FLAGS]) { + exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); + exp->flags &= ~NF_CT_EXPECT_USERSPACE; + } else + exp->flags = 0; + } exp->class = 0; exp->expectfn = NULL; @@ -2109,6 +2122,7 @@ static void __exit ctnetlink_exit(void) { pr_info("ctnetlink: unregistering from nfnetlink.\n"); + nf_ct_remove_userspace_expectations(); #ifdef CONFIG_NF_CONNTRACK_EVENTS nf_ct_expect_unregister_notifier(&ctnl_notifier_exp); nf_conntrack_unregister_notifier(&ctnl_notifier); -- cgit v1.2.3 From 8d4780eb1ece4e8109b4f6b2e5e61f7fc593c3f4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 24 Sep 2010 21:59:57 -0400 Subject: mac80211: fix offchannel assumption upon association Association is dealt with as an atomic offchannel operation, we do this because we don't know we are associated until we get the associatin response from the AP. When we do get the associatin response though we were never clearing the offchannel state. This has a few implications, we told drivers we were still offchannel, and the first configured TX power for the channel does not take into account any power constraints. For ath9k this meant ANI calibration would not start upon association, and we'd have to wait until the first bgscan to be triggered. There may be other issues this resolves but I'm too lazy to comb the code to check. Cc: stable@kernel.org Cc: Amod Bodas Cc: Vasanth Thiagarajan Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7c8542627351..e24fa5be4264 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -110,7 +110,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) chan = scan_chan; channel_type = NL80211_CHAN_NO_HT; local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; - } else if (local->tmp_channel) { + } else if (local->tmp_channel && + local->oper_channel != local->tmp_channel) { chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; -- cgit v1.2.3 From 793e721d21fd7d2825e3b7e56ff5009ec6d052e9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Sep 2010 21:28:51 +0200 Subject: carl9170: remove non-standard ba session teardown 802.11n-2009 demands in 11.2.1: " When a STA enters normal (non-APSD) PS mode, any downlink Block ACK agreement without an associated schedule is suspended for the duration of this PS mode." The operative word is "suspended" and not terminated. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 43de9dfa5820..d28b4ff8d281 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1453,9 +1453,6 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, while ((skb = __skb_dequeue(&tid_info->queue))) __skb_queue_tail(&free, skb); spin_unlock_bh(&tid_info->lock); - - ieee80211_stop_tx_ba_session(sta, - tid_info->tid); } rcu_read_unlock(); } -- cgit v1.2.3 From b4c85d459c3a2c539a2d5885b12372e404bafc6b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Sep 2010 21:40:40 +0200 Subject: carl9170: angle brackets for wiki link "The convention seems to be angle brackets around URLS in Kconfig." -- Finn Thain (to update web addresses in the kernel) Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig index c5d3a3f2e55b..2d1b821b440d 100644 --- a/drivers/net/wireless/ath/carl9170/Kconfig +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -10,7 +10,7 @@ config CARL9170 but it needs a special firmware (carl9170-1.fw) to do that. The firmware can be downloaded from our wiki here: - http://wireless.kernel.org/en/users/Drivers/carl9170 + If you choose to build a module, it'll be called carl9170. -- cgit v1.2.3 From 042c53f6e84896701b67012ad525bc44ea6de25f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Sep 2010 21:48:31 +0200 Subject: carl9170: remove lost-frame workaround This patch removes some cruft, which survived the RFC review phase. Originally, carl9170_tx_ampdu_queue erroneously dropped a lot of frames. As a result the ampdu scheduler bogged down quite frequently and the affected BA session timed out. However this bug has been fixed and the WA and its debugfs counter is no longer useful. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 - drivers/net/wireless/ath/carl9170/debug.c | 4 --- drivers/net/wireless/ath/carl9170/tx.c | 37 ++-------------------------- 3 files changed, 2 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index d7c5482d74ce..20f2a77e54d2 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -364,7 +364,6 @@ struct ar9170 { unsigned int tx_dropped; unsigned int tx_ack_failures; unsigned int tx_fcs_errors; - unsigned int tx_ampdu_timeout; unsigned int rx_dropped; /* EEPROM */ diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 19b48369ffed..0ac1124c2a0b 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c @@ -798,8 +798,6 @@ DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d", atomic_read(&ar->tx_total_queued)); DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d", atomic_read(&ar->tx_ampdu_scheduler)); -DEBUGFS_READONLY_FILE(tx_ampdu_timeout, 20, "%d", - ar->tx_ampdu_timeout); DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d", atomic_read(&ar->tx_total_pending)); @@ -872,8 +870,6 @@ void carl9170_debugfs_register(struct ar9170 *ar) DEBUGFS_ADD(ampdu_density); DEBUGFS_ADD(ampdu_factor); - DEBUGFS_ADD(tx_ampdu_timeout); - DEBUGFS_ADD(tx_janitor_last_run); DEBUGFS_ADD(tx_status_0); diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index e0d2374e0c77..e6be5e6c1723 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1042,41 +1042,8 @@ retry: queue = TID_TO_WME_AC(tid_info->tid); spin_lock_bh(&tid_info->lock); - if (tid_info->state != CARL9170_TID_STATE_XMIT) { - first = skb_peek(&tid_info->queue); - if (first) { - struct ieee80211_tx_info *txinfo; - struct carl9170_tx_info *arinfo; - - txinfo = IEEE80211_SKB_CB(first); - arinfo = (void *) txinfo->rate_driver_data; - - if (time_is_after_jiffies(arinfo->timeout + - msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)) - == true) - goto processed; - - /* - * We've been waiting for the frame which - * matches "snx" (start sequence of the - * next aggregate) for some time now. - * - * But it never arrived. Therefore - * jump to the next available frame - * and kick-start the transmission. - * - * Note: This might induce odd latency - * spikes because the receiver will be - * waiting for the lost frame too. - */ - ar->tx_ampdu_timeout++; - - tid_info->snx = carl9170_get_seq(first); - tid_info->state = CARL9170_TID_STATE_XMIT; - } else { - goto processed; - } - } + if (tid_info->state != CARL9170_TID_STATE_XMIT) + goto processed; tid_info->counter++; first = skb_peek(&tid_info->queue); -- cgit v1.2.3 From cb139ecc0c030e8ccc736bd86cfef502c200825a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Sep 2010 22:49:34 +0200 Subject: carl9170: fix tx_ampdu_upload counter tx_ampdu_upload was not decreased when an a-MPDU frame had to be kicked out from the tx_pending queues. This broke ampdu aggregation, because the scheduler waits until tx_ampdu_upload drops to zero, before making the next aggregate. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index d28b4ff8d281..a8b0cec78b32 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -230,8 +230,15 @@ static void carl9170_flush(struct ar9170 *ar, bool drop_queued) for (i = 0; i < ar->hw->queues; i++) { struct sk_buff *skb; - while ((skb = skb_dequeue(&ar->tx_pending[i]))) + while ((skb = skb_dequeue(&ar->tx_pending[i]))) { + struct ieee80211_tx_info *info; + + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + carl9170_tx_status(ar, skb, false); + } } } @@ -1462,6 +1469,7 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { struct _carl9170_tx_superframe *super; struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info; super = (void *) skb->data; hdr = (void *) super->frame_data; @@ -1470,6 +1478,11 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, continue; __skb_unlink(skb, &ar->tx_pending[i]); + + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + carl9170_tx_status(ar, skb, false); } spin_unlock_bh(&ar->tx_pending[i].lock); -- cgit v1.2.3 From 9c655c8be9053a65886ac3e06420399a9bfdbd70 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 26 Sep 2010 23:06:56 +0200 Subject: carl9170: fix WARN_ON triggered by Broadcom HT STAs Broadcom's Windows driver for the 4313 advertises an ampdu density of 7 => 16 us. The AR9170 MAC on the other hand only supports densities up to 8 us. This patch removes the noisy WARN_ON, because there is nothing we can do about it. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a8b0cec78b32..84bd38e9961c 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1248,7 +1248,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: - if (WARN_ON_ONCE(!sta_info->ht_sta)) + if (!sta_info->ht_sta) return -EOPNOTSUPP; rcu_read_lock(); -- cgit v1.2.3 From 4bd437ea40b81fb4c047034de6dca1b5af496fb0 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 27 Sep 2010 01:36:38 +0200 Subject: carl9170: revamp carl9170_tx_prepare David Miller complained about the driver's excessive use of variables in __packed structs. While I did not fully agree with his sole "performance" argument on all accounts. I do see some room for improvement in hot-paths on architectures without an efficient access to unaligned elements. This first patch (dare I say?) optimizes an important tx hot-path in the driver: carl9170_tx_prepare. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 155 ++++++++++++++++----------------- 1 file changed, 75 insertions(+), 80 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index e6be5e6c1723..b575c865142d 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -760,8 +760,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) struct carl9170_tx_info *arinfo; unsigned int hw_queue; int i; - u16 keytype = 0; - u16 len, icv = 0; + __le16 mac_tmp; + u16 len; bool ampdu, no_ack; BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); @@ -773,6 +773,10 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES); + BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC > + ((CARL9170_TX_SUPER_MISC_VIF_ID >> + CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); + hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)]; hdr = (void *)skb->data; @@ -793,20 +797,37 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) txc = (void *)skb_push(skb, sizeof(*txc)); memset(txc, 0, sizeof(*txc)); - ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU); + SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); + + if (likely(cvif)) + SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, cvif->id); + + if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) + txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; + + if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) + txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; + + mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | + AR9170_TX_MAC_BACKOFF); + mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && + AR9170_TX_MAC_QOS); + no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); + if (unlikely(no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); if (info->control.hw_key) { - icv = info->control.hw_key->icv_len; + len += info->control.hw_key->icv_len; switch (info->control.hw_key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_TKIP: - keytype = AR9170_TX_MAC_ENCR_RC4; + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_RC4); break; case WLAN_CIPHER_SUITE_CCMP: - keytype = AR9170_TX_MAC_ENCR_AES; + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_AES); break; default: WARN_ON(1); @@ -814,48 +835,58 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) } } - BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC > - ((CARL9170_TX_SUPER_MISC_VIF_ID >> - CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); - - txc->s.len = cpu_to_le16(len + sizeof(*txc)); - txc->f.length = cpu_to_le16(len + icv + 4); - SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, - cvif ? cvif->id : 0); + ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU); + if (ampdu) { + unsigned int density, factor; - txc->f.mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | - AR9170_TX_MAC_BACKOFF); + if (unlikely(!sta || !cvif)) + goto err_out; - SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); + factor = min_t(unsigned int, 1u, + info->control.sta->ht_cap.ampdu_factor); - txc->f.mac_control |= cpu_to_le16(hw_queue << AR9170_TX_MAC_QOS_S); - txc->f.mac_control |= cpu_to_le16(keytype); - txc->f.phy_control = cpu_to_le32(0); + density = info->control.sta->ht_cap.ampdu_density; - if (no_ack) - txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); + if (density) { + /* + * Watch out! + * + * Otus uses slightly different density values than + * those from the 802.11n spec. + */ - if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) - txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; + density = max_t(unsigned int, density + 1, 7u); + } - txrate = &info->control.rates[0]; - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) - txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - else if (carl9170_tx_cts_check(ar, txrate)) - txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); + SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY, + txc->s.ampdu_settings, density); - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); - txc->f.phy_control |= carl9170_tx_physet(ar, info, txrate); + SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, + txc->s.ampdu_settings, factor); - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { txrate = &info->control.rates[i]; - if (txrate->idx >= 0) + if (txrate->idx >= 0) { + txc->s.ri[i] = + CARL9170_TX_SUPER_RI_AMPDU; + + if (WARN_ON(!(txrate->flags & + IEEE80211_TX_RC_MCS))) { + /* + * Not sure if it's even possible + * to aggregate non-ht rates with + * this HW. + */ + goto err_out; + } continue; + } txrate->idx = 0; txrate->count = ar->hw->max_rate_tries; } + + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); } /* @@ -878,57 +909,21 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << CARL9170_TX_SUPER_RI_ERP_PROT_S); - /* - * unaggregated fallback, in case aggregation - * proves to be unsuccessful and unreliable. - */ - if (ampdu && i < 3) - txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU; - txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); } - if (ieee80211_is_probe_resp(hdr->frame_control)) - txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; - - if (ampdu) { - unsigned int density, factor; - - if (unlikely(!sta || !cvif)) - goto err_out; - - density = info->control.sta->ht_cap.ampdu_density; - factor = info->control.sta->ht_cap.ampdu_factor; - - if (density) { - /* - * Watch out! - * - * Otus uses slightly different density values than - * those from the 802.11n spec. - */ - - density = max_t(unsigned int, density + 1, 7u); - } - - factor = min_t(unsigned int, 1u, factor); - - SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY, - txc->s.ampdu_settings, density); + txrate = &info->control.rates[0]; + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); - SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, - txc->s.ampdu_settings, factor); + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); + else if (carl9170_tx_cts_check(ar, txrate)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); - if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) { - txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); - } else { - /* - * Not sure if it's even possible to aggregate - * non-ht rates with this HW. - */ - WARN_ON_ONCE(1); - } - } + txc->s.len = cpu_to_le16(skb->len); + txc->f.length = cpu_to_le16(len + FCS_LEN); + txc->f.mac_control = mac_tmp; + txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); arinfo = (void *)info->rate_driver_data; arinfo->timeout = jiffies; -- cgit v1.2.3 From 4a79f2c517cce31c3b25aab0ec5078368b22c363 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 27 Sep 2010 12:22:16 +0900 Subject: ath5k: Remove unused variable for atim window It's not used and it's unlikely we will ever implement ATIM. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 - drivers/net/wireless/ath/ath5k/attach.c | 1 - drivers/net/wireless/ath/ath5k/pcu.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index b96bb985b56d..42e6e821259e 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1041,7 +1041,6 @@ struct ath5k_hw { #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version - u32 ah_atim_window; u32 ah_limit_tx_retries; u8 ah_coverage_class; diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 6e02de311cdd..cd0b14a0a93a 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -118,7 +118,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ah->ah_turbo = false; ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_imr = 0; - ah->ah_atim_window = 0; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; ah->ah_software_retry = false; ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 6a891c4484a0..71dca1023e72 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -600,7 +600,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) /* Timer3 marks the end of our ATIM window * a zero length window is not allowed because * we 'll get no beacons */ - timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); + timer3 = next_beacon + 1; /* * Set the beacon register and enable all timers. -- cgit v1.2.3 From 7f896126017830b29cf501d246ee32b81e359acd Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 27 Sep 2010 12:22:21 +0900 Subject: ath5k: Check and fix ATIM window This patch adds sanity-checks for the beacon timers and especially the ATIM window to ath5k. It is basically the same what i did for madwifi two years ago and fixes a problem in IBSS mode which has been described as "ramping" pings. See the code comments for a more detailed description and these links: http://madwifi-project.org/ticket/1154 http://madwifi-project.org/changeset/3867 http://thread.gmane.org/gmane.linux.drivers.madwifi.devel/6066 Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/base.c | 9 ++++ drivers/net/wireless/ath/ath5k/pcu.c | 91 ++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 42e6e821259e..0cba2e315d9a 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1195,6 +1195,7 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); void ath5k_hw_reset_tsf(struct ath5k_hw *ah); void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); +bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); /* ACK bit rate */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); /* Clock rate related functions */ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 95072db0ec21..4103765000ea 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1191,6 +1191,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, */ if (hw_tu >= sc->nexttbtt) ath5k_beacon_update_timers(sc, bc_tstamp); + + /* Check if the beacon timers are still correct, because a TSF + * update might have created a window between them - for a + * longer description see the comment of this function: */ + if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) { + ath5k_beacon_update_timers(sc, bc_tstamp); + ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, + "fixed beacon timers after beacon receive\n"); + } } } diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 71dca1023e72..604114fb34b1 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -640,6 +640,97 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) } +/** + * ath5k_check_timer_win - Check if timer B is timer A + window + * + * @a: timer a (before b) + * @b: timer b (after a) + * @window: difference between a and b + * @intval: timers are increased by this interval + * + * This helper function checks if timer B is timer A + window and covers + * cases where timer A or B might have already been updated or wrapped + * around (Timers are 16 bit). + * + * Returns true if O.K. + */ +static inline bool +ath5k_check_timer_win(int a, int b, int window, int intval) +{ + /* + * 1.) usually B should be A + window + * 2.) A already updated, B not updated yet + * 3.) A already updated and has wrapped around + * 4.) B has wrapped around + */ + if ((b - a == window) || /* 1.) */ + (a - b == intval - window) || /* 2.) */ + ((a | 0x10000) - b == intval - window) || /* 3.) */ + ((b | 0x10000) - a == window)) /* 4.) */ + return true; /* O.K. */ + return false; +} + +/** + * ath5k_hw_check_beacon_timers - Check if the beacon timers are correct + * + * @ah: The &struct ath5k_hw + * @intval: beacon interval + * + * This is a workaround for IBSS mode: + * + * The need for this function arises from the fact that we have 4 separate + * HW timer registers (TIMER0 - TIMER3), which are closely related to the + * next beacon target time (NBTT), and that the HW updates these timers + * seperately based on the current TSF value. The hardware increments each + * timer by the beacon interval, when the local TSF coverted to TU is equal + * to the value stored in the timer. + * + * The reception of a beacon with the same BSSID can update the local HW TSF + * at any time - this is something we can't avoid. If the TSF jumps to a + * time which is later than the time stored in a timer, this timer will not + * be updated until the TSF in TU wraps around at 16 bit (the size of the + * timers) and reaches the time which is stored in the timer. + * + * The problem is that these timers are closely related to TIMER0 (NBTT) and + * that they define a time "window". When the TSF jumps between two timers + * (e.g. ATIM and NBTT), the one in the past will be left behind (not + * updated), while the one in the future will be updated every beacon + * interval. This causes the window to get larger, until the TSF wraps + * around as described above and the timer which was left behind gets + * updated again. But - because the beacon interval is usually not an exact + * divisor of the size of the timers (16 bit), an unwanted "window" between + * these timers has developed! + * + * This is especially important with the ATIM window, because during + * the ATIM window only ATIM frames and no data frames are allowed to be + * sent, which creates transmission pauses after each beacon. This symptom + * has been described as "ramping ping" because ping times increase linearly + * for some time and then drop down again. A wrong window on the DMA beacon + * timer has the same effect, so we check for these two conditions. + * + * Returns true if O.K. + */ +bool +ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) +{ + unsigned int nbtt, atim, dma; + + nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0); + atim = ath5k_hw_reg_read(ah, AR5K_TIMER3); + dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3; + + /* NOTE: SWBA is different. Having a wrong window there does not + * stop us from sending data and this condition is catched thru + * other means (SWBA interrupt) */ + + if (ath5k_check_timer_win(nbtt, atim, 1, intval) && + ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP, + intval)) + return true; /* O.K. */ + return false; +} + /** * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class * -- cgit v1.2.3 From 11f21df36cbcffbfada9307e809d4372ece27f47 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 27 Sep 2010 12:22:26 +0900 Subject: ath5k: Increase "fudge" for beacon timers We use FUDGE to make sure the next TBTT is ahead of the current TU. Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer configuration we need to make sure it is bigger than that. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4103765000ea..94cc3354f3a6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1886,8 +1886,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) hw_tsf = ath5k_hw_get_tsf64(ah); hw_tu = TSF_TO_TU(hw_tsf); -#define FUDGE 3 - /* we use FUDGE to make sure the next TBTT is ahead of the current TU */ +#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 + /* We use FUDGE to make sure the next TBTT is ahead of the current TU. + * Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer + * configuration we need to make sure it is bigger than that. */ + if (bc_tsf == -1) { /* * no beacons received, called internally. -- cgit v1.2.3 From 28df897a42aa41d6318be5b9872c4bb5c8d8d7e3 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 27 Sep 2010 12:22:32 +0900 Subject: ath5k: Disable interrupts in ath5k_hw_get_tsf64 The code in ath5k_hw_get_tsf64() is time critical and will return wrong results if we get interrupted, so disable local interrupts. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/pcu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 604114fb34b1..095d30b50ec7 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -495,6 +495,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) { u32 tsf_lower, tsf_upper1, tsf_upper2; int i; + unsigned long flags; + + /* This code is time critical - we don't want to be interrupted here */ + local_irq_save(flags); /* * While reading TSF upper and then lower part, the clock is still @@ -517,6 +521,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) tsf_upper1 = tsf_upper2; } + local_irq_restore(flags); + WARN_ON( i == ATH5K_MAX_TSF_READ ); return (((u64)tsf_upper1 << 32) | tsf_lower); -- cgit v1.2.3 From eada7cad6005006b457f10a4c3e1881ff99d03a4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 27 Sep 2010 13:02:40 +0900 Subject: ath5k: Fix bitmasks and typos for PCU Diagnostic register As reported by Ryan Niemi, some bitmasks in the register definition for the PCU Diagnostic register (DIAG_SW) were missing a zero at the end. While at it fix some typos and add more comments. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/dma.c | 4 ++-- drivers/net/wireless/ath/ath5k/phy.c | 4 ++-- drivers/net/wireless/ath/ath5k/reg.h | 29 ++++++++++++++--------------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 58bb6c5dda7b..923c9ca5c4f0 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -244,7 +244,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Force channel idle high */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); /* Wait a while and disable mechanism */ udelay(200); @@ -261,7 +261,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) } while (--i && pending); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); } /* Clear register */ diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 4932bf2f35eb..61da913e7c8f 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1257,7 +1257,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, * Disable beacons and RX/TX queues, wait */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); + AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); @@ -1336,7 +1336,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, * Re-enable RX/TX and beacons */ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); + AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); return 0; diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 67d63081705a..a34929f06533 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -1387,10 +1387,9 @@ /* - * PCU control register + * PCU Diagnostic register * - * Only DIS_RX is used in the code, the rest i guess are - * for tweaking/diagnostics. + * Used for tweaking/diagnostics. */ #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ @@ -1399,22 +1398,22 @@ #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ -#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ -#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ -#define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ -#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ +#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */ +#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */ +#define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */ +#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */ #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) -#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ +#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */ #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) -#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ +#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */ #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) -#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ +#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */ #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) @@ -1426,17 +1425,17 @@ #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ #define AR5K_DIAG_SW_SCRAM_SEED_S 10 -#define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ +#define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */ #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ #define AR5K_DIAG_SW_OBSPT_S 18 -#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ -#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ -#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ -#define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ +#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */ +#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */ +#define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */ +#define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */ /* * TSF (clock) register (lower 32 bits) -- cgit v1.2.3 From dc4769f0bb949e312ad8d9b652047ff6709978c2 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 28 Sep 2010 01:53:42 +0200 Subject: carl9170: interrupt urbs must not set URB_ZERO_PACKET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes a bug in the driver which was exposed by CONFIG_USB_DEBUG: "usb 1-1.6.3: BOGUS urb flags, 40 --> 0" The transfer flag "URB_ZERO_PACKET" is only valid for bulk urbs. Reported-by: André Erdmann Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index eb789a9e4f15..c7f6193934ea 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -606,8 +606,6 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, carl9170_usb_cmd_complete, ar, 1); - urb->transfer_flags |= URB_ZERO_PACKET; - if (free_buf) urb->transfer_flags |= URB_FREE_BUFFER; -- cgit v1.2.3 From 93b05238027420978d785569f8c1aa4a6867bc13 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Sep 2010 12:53:14 +0200 Subject: cfg80211: always set IBSS basic rates IBSS started from wireless extensions is currently missing basic rate configuration, fix this by moving the code to generate the default to the common code that gets invoked for both nl80211 and wext. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/ibss.c | 19 +++++++++++++++++++ net/wireless/nl80211.c | 17 ----------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 27a8ce9343c3..8cb6e08373b9 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -88,6 +88,25 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, if (wdev->ssid_len) return -EALREADY; + if (!params->basic_rates) { + /* + * If no rates were explicitly configured, + * use the mandatory rate set for 11b or + * 11a for maximum compatibility. + */ + struct ieee80211_supported_band *sband = + rdev->wiphy.bands[params->channel->band]; + int j; + u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ? + IEEE80211_RATE_MANDATORY_A : + IEEE80211_RATE_MANDATORY_B; + + for (j = 0; j < sband->n_bitrates; j++) { + if (sband->bitrates[j].flags & flag) + params->basic_rates |= BIT(j); + } + } + if (WARN_ON(wdev->connect_keys)) kfree(wdev->connect_keys); wdev->connect_keys = connkeys; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4ff827e8c362..9c84825803ce 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4119,23 +4119,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) goto out; } } - } else { - /* - * If no rates were explicitly configured, - * use the mandatory rate set for 11b or - * 11a for maximum compatibility. - */ - struct ieee80211_supported_band *sband = - wiphy->bands[ibss.channel->band]; - int j; - u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ? - IEEE80211_RATE_MANDATORY_A : - IEEE80211_RATE_MANDATORY_B; - - for (j = 0; j < sband->n_bitrates; j++) { - if (sband->bitrates[j].flags & flag) - ibss.basic_rates |= BIT(j); - } } err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); -- cgit v1.2.3 From f2176d7240e4f455a6e007703c7512fbde926dc8 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 28 Sep 2010 14:39:32 +0300 Subject: mac80211: Fix WMM driver queue configuration The WMM parameter configuration function (ieee80211_sta_wmm_params) only configures the WMM parameters to the driver is the wmm_last_param_set counter value is changed by the AP. The wmm_last_param_set is initialized to -1 on association in order to ensure the configuration is made to the driver at least once on association, but currently this initialization is done *after* the WMM parameter configuration function was called. This leads to unreliability in the driver getting properly configured on first association (depending on what counter value the AP happens to use.) When disassociating (the wmm default parameters are configured to the driver) and then reassociating, due to the above the WMM configuration is not set to the driver at all. On drivers without beacon filtering the problem is corrected by later beacons, but on drivers with beacon filtering the WMM will remain permanently incorrectly configured. Fix this by moving the initialization of wmm_last_param_set to -1 before ieee80211_sta_wmm_params is called on association. Signed-off-by: Juuso Oikarinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 8b733cf6f3ea..77913a15f537 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -880,14 +880,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); - /* - * Always handle WMM once after association regardless - * of the first value the AP uses. Setting -1 here has - * that effect because the AP values is an unsigned - * 4-bit value. - */ - sdata->u.mgd.wmm_last_param_set = -1; - ieee80211_led_assoc(local, 1); if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) @@ -1367,6 +1359,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, return false; } + /* + * Always handle WMM once after association regardless + * of the first value the AP uses. Setting -1 here has + * that effect because the AP values is an unsigned + * 4-bit value. + */ + ifmgd->wmm_last_param_set = -1; + if (elems.wmm_param) ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, elems.wmm_param_len); -- cgit v1.2.3 From 1de19eccb3fe634e939cb40f30fdfda93a67fe93 Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Tue, 14 Sep 2010 15:21:20 -0700 Subject: iwlwifi: define 100 devices add new structures and defines need to identify 100 devices. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 73 +++++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 + 3 files changed, 81 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 56ef4ed0db47..19dbef06d52c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -50,14 +50,20 @@ /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 3 +#define IWL100_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL1000_UCODE_API_MIN 1 +#define IWL100_UCODE_API_MIN 5 #define IWL1000_FW_PRE "iwlwifi-1000-" #define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" #define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) +#define IWL100_FW_PRE "iwlwifi-100-" +#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" +#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) + /* * For 1000, use advance thermal throttling critical temperature threshold, @@ -310,4 +316,71 @@ struct iwl_cfg iwl1000_bg_cfg = { .chain_noise_calib_by_driver = true, }; +struct iwl_cfg iwl100_bgn_cfg = { + .name = "Intel(R) 100 Series 1x1 BGN", + .fw_name_pre = IWL100_FW_PRE, + .ucode_api_max = IWL100_UCODE_API_MAX, + .ucode_api_min = IWL100_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .ops = &iwl1000_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .set_l0s = true, + .use_bsm = false, + .max_ll_items = OTP_MAX_LL_ITEMS_1000, + .shadow_ram_support = false, + .ht_greenfield_support = true, + .led_compensation = 51, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .max_event_log_size = 128, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, +}; + +struct iwl_cfg iwl100_bg_cfg = { + .name = "Intel(R) 100 Series 1x1 BG", + .fw_name_pre = IWL100_FW_PRE, + .ucode_api_max = IWL100_UCODE_API_MAX, + .ucode_api_min = IWL100_UCODE_API_MIN, + .sku = IWL_SKU_G, + .ops = &iwl1000_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .set_l0s = true, + .use_bsm = false, + .max_ll_items = OTP_MAX_LL_ITEMS_1000, + .shadow_ram_support = false, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .max_event_log_size = 128, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, +}; + MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 646864a26eaf..005b07bea1e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4788,6 +4788,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, + + {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)}, #endif /* CONFIG_IWL5000 */ {0} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index a372184ac210..d5dc824ebbfb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -92,6 +92,8 @@ extern struct iwl_cfg iwl6050_2abg_cfg; extern struct iwl_cfg iwl6050g2_bgn_cfg; extern struct iwl_cfg iwl1000_bgn_cfg; extern struct iwl_cfg iwl1000_bg_cfg; +extern struct iwl_cfg iwl100_bgn_cfg; +extern struct iwl_cfg iwl100_bg_cfg; extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; -- cgit v1.2.3 From 6b5ce501428942d9dec864a41ee223307f421574 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 14 Sep 2010 16:23:32 -0700 Subject: iwlwifi: add iwl_nic_ops structure to iwl_ops iwlwifi driver supports multiple devices. Since some device needs special configuration we create a new iwl_nic_ops structure which is configurable per device. Currently there is only one function pointer inside this structure: additional_nic_config(). The iwl_nic_ops structure is added to the top level in struct iwl_ops, making it easier to change per device. Duplication of the iwl_lib_ops structure is no longer needed. With this new ops the previous function pointer set_calib_version is no longer needed since it is just a per device nic configuration. As part of the code restructuring, a bug is addressed. Indication of calib version to uCode is only needed for 6050 devices, however, current implementation set calib version for all 6000 devices for which DC calib is needed. To fix this, create iwl6050_ops for 6050 devices and only populate iwl_nic_ops in this structure. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 35 ++++++++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-core.h | 7 ++++++- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9f43f2770c96..8256034285a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -83,11 +83,10 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; } -/* Indicate calibration version to uCode. */ -static void iwl6000_set_calib_version(struct iwl_priv *priv) +static void iwl6050_additional_nic_config(struct iwl_priv *priv) { - if (priv->cfg->need_dc_calib && - (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)) + /* Indicate calibration version to uCode. */ + if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) iwl_set_bit(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } @@ -117,9 +116,11 @@ static void iwl6000_nic_config(struct iwl_priv *priv) iwl_write32(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); } - /* else do nothing, uCode configured */ - if (priv->cfg->ops->lib->temp_ops.set_calib_version) - priv->cfg->ops->lib->temp_ops.set_calib_version(priv); + /* do additional nic configuration if needed */ + if (priv->cfg->ops->nic && + priv->cfg->ops->nic->additional_nic_config) { + priv->cfg->ops->nic->additional_nic_config(priv); + } } static struct iwl_sensitivity_ranges iwl6000_sensitivity = { @@ -320,7 +321,6 @@ static struct iwl_lib_ops iwl6000_lib = { .temp_ops = { .temperature = iwlagn_temperature, .set_ct_kill = iwl6000_set_ct_threshold, - .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, @@ -396,7 +396,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .temp_ops = { .temperature = iwlagn_temperature, .set_ct_kill = iwl6000_set_ct_threshold, - .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, @@ -419,6 +418,10 @@ static struct iwl_lib_ops iwl6000g2b_lib = { } }; +static struct iwl_nic_ops iwl6050_nic_ops = { + .additional_nic_config = &iwl6050_additional_nic_config, +}; + static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, @@ -426,6 +429,14 @@ static const struct iwl_ops iwl6000_ops = { .led = &iwlagn_led_ops, }; +static const struct iwl_ops iwl6050_ops = { + .lib = &iwl6000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .nic = &iwl6050_nic_ops, +}; + static const struct iwl_ops iwl6000g2b_ops = { .lib = &iwl6000g2b_lib, .hcmd = &iwlagn_bt_hcmd, @@ -909,7 +920,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, + .ops = &iwl6050_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, @@ -947,7 +958,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, + .ops = &iwl6050_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, @@ -985,7 +996,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, + .ops = &iwl6050_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f0302bfe85f5..5daa1893fd03 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -137,7 +137,6 @@ struct iwl_debugfs_ops { struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); void (*set_ct_kill)(struct iwl_priv *priv); - void (*set_calib_version)(struct iwl_priv *priv); }; struct iwl_tt_ops { @@ -233,11 +232,17 @@ struct iwl_led_ops { int (*off)(struct iwl_priv *priv); }; +/* NIC specific ops */ +struct iwl_nic_ops { + void (*additional_nic_config)(struct iwl_priv *priv); +}; + struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; const struct iwl_led_ops *led; + const struct iwl_nic_ops *nic; }; struct iwl_mod_params { -- cgit v1.2.3 From 02796d77cb4cfb64b9465eabbdb13b3b7d1679e9 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 14 Sep 2010 16:23:42 -0700 Subject: iwlagn: set CSR register for 6050g2 devices For 6050g2 devices driver needs to set a special bit to CSR register so that uCode can do things correctly in calibration routines. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 24 +++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-csr.h | 3 ++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8256034285a6..83a5262d8bd8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -91,6 +91,16 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } +static void iwl6050g2_additional_nic_config(struct iwl_priv *priv) +{ + /* Indicate calibration version to uCode. */ + if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) + iwl_set_bit(priv, CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); + iwl_set_bit(priv, CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_6050_1x2); +} + /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { @@ -422,6 +432,10 @@ static struct iwl_nic_ops iwl6050_nic_ops = { .additional_nic_config = &iwl6050_additional_nic_config, }; +static struct iwl_nic_ops iwl6050g2_nic_ops = { + .additional_nic_config = &iwl6050g2_additional_nic_config, +}; + static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, @@ -437,6 +451,14 @@ static const struct iwl_ops iwl6050_ops = { .nic = &iwl6050_nic_ops, }; +static const struct iwl_ops iwl6050g2_ops = { + .lib = &iwl6000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .nic = &iwl6050g2_nic_ops, +}; + static const struct iwl_ops iwl6000g2b_ops = { .lib = &iwl6000g2b_lib, .hcmd = &iwlagn_bt_hcmd, @@ -958,7 +980,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6050_ops, + .ops = &iwl6050g2_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index ecf98e7ac4ed..2aa15ab13892 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -371,7 +371,8 @@ #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) -#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) +#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) +#define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008) /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) -- cgit v1.2.3 From 6d6a1afdc591e3f3ee66c39206923def43044ab6 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 14 Sep 2010 18:13:31 -0700 Subject: iwlwifi: send DC calib config to runtime ucode Since uCode is responsible for doing DC calibration, there's no need to let init uCode to do initial DC calibration then send results back to driver, then driver sends the results to runtime uCode. Driver can simply tell runtime uCode to do DC calibration. Actually, this patch does not disable DC calib for init uCode. It just prevent driver from saving and sending the DC calib results (from init ucode) to runtime uCode. The driver still uses 0xffffffff in CALIB_CFG_CMD for init ucode. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 23 +++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 83a5262d8bd8..51444c8e69ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -199,7 +199,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_BASE_BAND); if (priv->cfg->need_dc_calib) - priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); + priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 005b07bea1e0..e23c554b73a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2765,6 +2765,25 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) } } +static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) +{ + struct iwl_calib_cfg_cmd calib_cfg_cmd; + struct iwl_host_cmd cmd = { + .id = CALIBRATION_CFG_CMD, + .len = sizeof(struct iwl_calib_cfg_cmd), + .data = &calib_cfg_cmd, + }; + + memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); + calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; + calib_cfg_cmd.ucd_calib_cfg.once.start = cfg; + calib_cfg_cmd.ucd_calib_cfg.once.send_res = 0; + calib_cfg_cmd.ucd_calib_cfg.flags = 0; + + return iwl_send_cmd(priv, &cmd); +} + + /** * iwl_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's @@ -2801,6 +2820,10 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } + if (priv->hw_params.calib_rt_cfg) + iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); + + /* After the ALIVE response, we can send host commands to the uCode */ set_bit(STATUS_ALIVE, &priv->status); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 27e250c8d4b5..27350eebb132 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3800,6 +3800,21 @@ enum { #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) +/* This enum defines the bitmap of various calibrations to enable in both + * init ucode and runtime ucode through CALIBRATION_CFG_CMD. + */ +enum iwl_ucode_calib_cfg { + IWL_CALIB_CFG_RX_BB_IDX, + IWL_CALIB_CFG_DC_IDX, + IWL_CALIB_CFG_TX_IQ_IDX, + IWL_CALIB_CFG_RX_IQ_IDX, + IWL_CALIB_CFG_NOISE_IDX, + IWL_CALIB_CFG_CRYSTAL_IDX, + IWL_CALIB_CFG_TEMPERATURE_IDX, + IWL_CALIB_CFG_PAPD_IDX, +}; + + struct iwl_calib_cfg_elmnt_s { __le32 is_enable; __le32 start; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 74d25bcbfcb2..90a37a94c698 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -684,6 +684,7 @@ struct iwl_sensitivity_ranges { * @ct_kill_threshold: temperature threshold * @beacon_time_tsf_bits: number of valid tsf bits for beacon time * @calib_init_cfg: setup initial calibrations for the hw + * @calib_rt_cfg: setup runtime calibrations for the hw * @struct iwl_sensitivity_ranges: range of sensitivity values */ struct iwl_hw_params { @@ -710,6 +711,7 @@ struct iwl_hw_params { /* for 1000, 6000 series and up */ u16 beacon_time_tsf_bits; u32 calib_init_cfg; + u32 calib_rt_cfg; const struct iwl_sensitivity_ranges *sens; }; -- cgit v1.2.3 From 62cb3c6ac47a5ab7d8c67dbbf8cbdcd5ae735410 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 28 Sep 2010 17:43:10 -0700 Subject: iwlagn: API v5 for 6050 series device For 6050 series device, change the supported API version Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 51444c8e69ae..4d45932e901e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -51,7 +51,7 @@ /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 4 -#define IWL6050_UCODE_API_MAX 4 +#define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 5 /* Lowest firmware API version supported */ -- cgit v1.2.3 From 4465b469008bc03b98a1b8df4e9ae501b6c69d4b Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Sun, 23 May 2010 19:54:12 +0000 Subject: ipv4: Allow configuring subnets as local addresses This patch allows a host to be configured to respond to any address in a specified range as if it were local, without actually needing to configure the address on an interface. This is done through routing table configuration. For instance, to configure a host to respond to any address in 10.1/16 received on eth0 as a local address we can do: ip rule add from all iif eth0 lookup 200 ip route add local 10.1/16 dev lo proto kernel scope host src 127.0.0.1 table 200 This host is now reachable by any 10.1/16 address (route lookup on input for packets received on eth0 can find the route). On output, the rule will not be matched so that this host can still send packets to 10.1/16 (not sent on loopback). Presumably, external routing can be configured to make sense out of this. To make this work, we needed to modify the logic in finding the interface which is assigned a given source address for output (dev_ip_find). We perform a normal fib_lookup instead of just a lookup on the local table, and in the lookup we ignore the input interface for matching. This patch is useful to implement IP-anycast for subnets of virtual addresses. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/net/flow.h | 1 + net/core/fib_rules.c | 3 ++- net/ipv4/fib_frontend.c | 7 +++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index bb08692a20b0..0ac3fb5e0973 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -49,6 +49,7 @@ struct flowi { __u8 proto; __u8 flags; #define FLOWI_FLAG_ANYSRC 0x01 +#define FLOWI_FLAG_MATCH_ANY_IIF 0x02 union { struct { __be16 sport; diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index d0787284cb07..332c2e31d048 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -182,7 +182,8 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, { int ret = 0; - if (rule->iifindex && (rule->iifindex != fl->iif)) + if (rule->iifindex && (rule->iifindex != fl->iif) && + !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) goto out; if (rule->oifindex && (rule->oifindex != fl->oif)) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 7d02a9f999fa..981f3c59b334 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -153,17 +153,16 @@ static void fib_flush(struct net *net) struct net_device * ip_dev_find(struct net *net, __be32 addr) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, + .flags = FLOWI_FLAG_MATCH_ANY_IIF }; struct fib_result res; struct net_device *dev = NULL; - struct fib_table *local_table; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif - local_table = fib_get_table(net, RT_TABLE_LOCAL); - if (!local_table || fib_table_lookup(local_table, &fl, &res)) + if (fib_lookup(net, &fl, &res)) return NULL; if (res.type != RTN_LOCAL) goto out; -- cgit v1.2.3 From ab79ad14a2d51e95f0ac3cef7cd116a57089ba82 Mon Sep 17 00:00:00 2001 From: Maciej Å»enczykowski Date: Mon, 27 Sep 2010 00:07:02 +0000 Subject: ipv6: Implement Any-IP support for IPv6. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AnyIP is the capability to receive packets and establish incoming connections on IPs we have not explicitly configured on the machine. An example use case is to configure a machine to accept all incoming traffic on eth0, and leave the policy of whether traffic for a given IP should be delivered to the machine up to the load balancer. Can be setup as follows: ip -6 rule from all iif eth0 lookup 200 ip -6 route add local default dev lo table 200 (in this case for all IPv6 addresses) Signed-off-by: Maciej Å»enczykowski Signed-off-by: David S. Miller --- net/ipv6/route.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25b0beda4331..25476e7e708b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1169,6 +1169,8 @@ int ip6_route_add(struct fib6_config *cfg) if (addr_type & IPV6_ADDR_MULTICAST) rt->dst.input = ip6_mc_input; + else if (cfg->fc_flags & RTF_LOCAL) + rt->dst.input = ip6_input; else rt->dst.input = ip6_forward; @@ -1190,7 +1192,8 @@ int ip6_route_add(struct fib6_config *cfg) they would result in kernel looping; promote them to reject routes */ if ((cfg->fc_flags & RTF_REJECT) || - (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { + (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK) + && !(cfg->fc_flags&RTF_LOCAL))) { /* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) { if (dev) { @@ -2082,6 +2085,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, if (rtm->rtm_type == RTN_UNREACHABLE) cfg->fc_flags |= RTF_REJECT; + if (rtm->rtm_type == RTN_LOCAL) + cfg->fc_flags |= RTF_LOCAL; + cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; cfg->fc_nlinfo.nl_net = sock_net(skb->sk); @@ -2202,6 +2208,8 @@ static int rt6_fill_node(struct net *net, NLA_PUT_U32(skb, RTA_TABLE, table); if (rt->rt6i_flags&RTF_REJECT) rtm->rtm_type = RTN_UNREACHABLE; + else if (rt->rt6i_flags&RTF_LOCAL) + rtm->rtm_type = RTN_LOCAL; else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) rtm->rtm_type = RTN_LOCAL; else -- cgit v1.2.3 From 745e20f1b626b1be4b100af5d4bf7b3439392f8f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Sep 2010 13:23:09 -0700 Subject: net: add a recursion limit in xmit path As tunnel devices are going to be lockless, we need to make sure a misconfigured machine wont enter an infinite loop. Add a percpu variable, and limit to three the number of stacked xmits. Reported-by: Jesse Gross Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 48ad47f402ad..50daccad6a53 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2177,6 +2177,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, return rc; } +static DEFINE_PER_CPU(int, xmit_recursion); +#define RECURSION_LIMIT 3 + /** * dev_queue_xmit - transmit a buffer * @skb: buffer to transmit @@ -2242,10 +2245,15 @@ int dev_queue_xmit(struct sk_buff *skb) if (txq->xmit_lock_owner != cpu) { + if (__this_cpu_read(xmit_recursion) > RECURSION_LIMIT) + goto recursion_alert; + HARD_TX_LOCK(dev, txq, cpu); if (!netif_tx_queue_stopped(txq)) { + __this_cpu_inc(xmit_recursion); rc = dev_hard_start_xmit(skb, dev, txq); + __this_cpu_dec(xmit_recursion); if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); goto out; @@ -2257,7 +2265,9 @@ int dev_queue_xmit(struct sk_buff *skb) "queue packet!\n", dev->name); } else { /* Recursion is detected! It is possible, - * unfortunately */ + * unfortunately + */ +recursion_alert: if (net_ratelimit()) printk(KERN_CRIT "Dead loop on virtual device " "%s, fix it urgently!\n", dev->name); -- cgit v1.2.3 From 6d81f41c58c69ddde497e9e640ba5805aa26e78c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 20:50:33 +0000 Subject: dummy: percpu stats and lockless xmit Converts dummy network device driver to : - percpu stats - 64bit stats - lockless xmit (NETIF_F_LLTX) - performance features added (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/dummy.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--- include/linux/netdevice.h | 1 + 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 37dcfdc63456..ff2d29b17858 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -36,6 +36,7 @@ #include #include #include +#include static int numdummies = 1; @@ -55,21 +56,69 @@ static void set_multicast_list(struct net_device *dev) { } +struct pcpu_dstats { + u64 tx_packets; + u64 tx_bytes; + struct u64_stats_sync syncp; +}; + +static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + int i; + + for_each_possible_cpu(i) { + const struct pcpu_dstats *dstats; + u64 tbytes, tpackets; + unsigned int start; + + dstats = per_cpu_ptr(dev->dstats, i); + do { + start = u64_stats_fetch_begin(&dstats->syncp); + tbytes = dstats->tx_bytes; + tpackets = dstats->tx_packets; + } while (u64_stats_fetch_retry(&dstats->syncp, start)); + stats->tx_bytes += tbytes; + stats->tx_packets += tpackets; + } + return stats; +} static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); + + u64_stats_update_begin(&dstats->syncp); + dstats->tx_packets++; + dstats->tx_bytes += skb->len; + u64_stats_update_end(&dstats->syncp); dev_kfree_skb(skb); return NETDEV_TX_OK; } +static int dummy_dev_init(struct net_device *dev) +{ + dev->dstats = alloc_percpu(struct pcpu_dstats); + if (!dev->dstats) + return -ENOMEM; + + return 0; +} + +static void dummy_dev_free(struct net_device *dev) +{ + free_percpu(dev->dstats); + free_netdev(dev); +} + static const struct net_device_ops dummy_netdev_ops = { + .ndo_init = dummy_dev_init, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = set_multicast_list, .ndo_set_mac_address = dummy_set_address, + .ndo_get_stats64 = dummy_get_stats64, }; static void dummy_setup(struct net_device *dev) @@ -78,14 +127,17 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; + dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; + dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; random_ether_addr(dev->dev_addr); } + static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) { if (tb[IFLA_ADDRESS]) { diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c2bec990bd17..6f0845e0b888 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1057,6 +1057,7 @@ struct net_device { void *ml_priv; struct pcpu_lstats __percpu *lstats; /* loopback stats */ struct pcpu_tstats __percpu *tstats; /* tunnel stats */ + struct pcpu_dstats __percpu *dstats; /* dummy stats */ }; /* GARP */ struct garp_port *garp_port; -- cgit v1.2.3 From fada5636fe41fd1423fe4e6af7b9f609378acde6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 23:56:46 +0000 Subject: ipip: fix percpu stats accounting commit 3c97af99a5aa1 (ipip: percpu stats accounting) forgot the fallback tunnel case (tunl0), and can crash pretty fast. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 12b6fde6f65a..9e78f11da786 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -789,7 +789,7 @@ static int ipip_tunnel_init(struct net_device *dev) return 0; } -static void __net_init ipip_fb_tunnel_init(struct net_device *dev) +static int __net_init ipip_fb_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); struct iphdr *iph = &tunnel->parms.iph; @@ -802,8 +802,13 @@ static void __net_init ipip_fb_tunnel_init(struct net_device *dev) iph->protocol = IPPROTO_IPIP; iph->ihl = 5; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + dev_hold(dev); rcu_assign_pointer(ipn->tunnels_wc[0], tunnel); + return 0; } static struct xfrm_tunnel ipip_handler __read_mostly = { @@ -852,7 +857,9 @@ static int __net_init ipip_init_net(struct net *net) } dev_net_set(ipn->fb_tunnel_dev, net); - ipip_fb_tunnel_init(ipn->fb_tunnel_dev); + err = ipip_fb_tunnel_init(ipn->fb_tunnel_dev); + if (err) + goto err_reg_dev; if ((err = register_netdev(ipn->fb_tunnel_dev))) goto err_reg_dev; @@ -860,7 +867,7 @@ static int __net_init ipip_init_net(struct net *net) return 0; err_reg_dev: - free_netdev(ipn->fb_tunnel_dev); + ipip_dev_free(ipn->fb_tunnel_dev); err_alloc_dev: /* nothing */ return err; -- cgit v1.2.3 From dd4080ee575db1a2d0f40538aed5aa7662a06c54 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Sep 2010 02:17:58 +0000 Subject: sit: fix percpu stats accounting commit 15fc1f7056ebd (sit: percpu stats accounting) forgot the fallback tunnel case (sit0), and can crash pretty fast. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/sit.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 011ecf55d34e..2cb646079237 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1160,7 +1160,7 @@ static int ipip6_tunnel_init(struct net_device *dev) return 0; } -static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) +static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); struct iphdr *iph = &tunnel->parms.iph; @@ -1175,8 +1175,12 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) iph->ihl = 5; iph->ttl = 64; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; dev_hold(dev); sitn->tunnels_wc[0] = tunnel; + return 0; } static struct xfrm_tunnel sit_handler __read_mostly = { @@ -1220,7 +1224,10 @@ static int __net_init sit_init_net(struct net *net) } dev_net_set(sitn->fb_tunnel_dev, net); - ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + if (err) + goto err_dev_free; + ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); if ((err = register_netdev(sitn->fb_tunnel_dev))) @@ -1230,7 +1237,8 @@ static int __net_init sit_init_net(struct net *net) err_reg_dev: dev_put(sitn->fb_tunnel_dev); - free_netdev(sitn->fb_tunnel_dev); +err_dev_free: + ipip6_dev_free(sitn->fb_tunnel_dev); err_alloc_dev: return err; } -- cgit v1.2.3 From 8df40d1033d64597dcf1efd4f7547e817f7a953b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Sep 2010 02:53:41 +0000 Subject: sit: enable lockless xmits SIT tunnels can benefit from lockless xmits, using NETIF_F_LLTX Bench on a 16 cpus machine (dual E5540 cpus), 16 threads sending 10000000 UDP frames via one sit tunnel (size:220 bytes per frame) Before patch : real 3m15.399s user 0m9.185s sys 51m55.403s 75029.00 87.5% _raw_spin_lock vmlinux 1090.00 1.3% dst_release vmlinux 902.00 1.1% dev_queue_xmit vmlinux 627.00 0.7% sock_wfree vmlinux 613.00 0.7% ip6_push_pending_frames ipv6.ko 505.00 0.6% __ip_route_output_key vmlinux After patch: real 1m1.387s user 0m12.489s sys 15m58.868s 28239.00 23.3% dst_release vmlinux 13570.00 11.2% ip6_push_pending_frames ipv6.ko 13118.00 10.8% ip6_append_data ipv6.ko 7995.00 6.6% __ip_route_output_key vmlinux 7924.00 6.5% sk_dst_check vmlinux 5015.00 4.1% udpv6_sendmsg ipv6.ko 3594.00 3.0% sock_alloc_send_pskb vmlinux 3135.00 2.6% sock_wfree vmlinux 3055.00 2.5% ip6_sk_dst_lookup ipv6.ko 2473.00 2.0% ip_finish_output vmlinux Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/sit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2cb646079237..d7701782b639 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1140,6 +1140,7 @@ static void ipip6_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; + dev->features |= NETIF_F_LLTX; } static int ipip6_tunnel_init(struct net_device *dev) -- cgit v1.2.3 From b790e01aee74c23a5d92576177934f13aa51f718 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Sep 2010 23:05:47 +0000 Subject: ip_gre: lockless xmit GRE tunnels can benefit from lockless xmits, using NETIF_F_LLTX Note: If tunnels are created with the "oseq" option, LLTX is not enabled : Even using an atomic_t o_seq, we would increase chance for packets being out of order at receiver. Bench on a 16 cpus machine (dual E5540 cpus), 16 threads sending 10000000 UDP frames via one gre tunnel (size:200 bytes per frame) Before patch : real 3m0.094s user 0m9.365s sys 47m50.103s After patch: real 0m29.756s user 0m11.097s sys 7m33.012s Last problem to solve is the contention on dst : 38660.00 21.4% __ip_route_output_key vmlinux 20786.00 11.5% dst_release vmlinux 14191.00 7.8% __xfrm_lookup vmlinux 12410.00 6.9% ip_finish_output vmlinux 4540.00 2.5% ip_push_pending_frames vmlinux 4427.00 2.4% ip_append_data vmlinux 4265.00 2.4% __alloc_skb vmlinux 4140.00 2.3% __ip_local_out vmlinux 3991.00 2.2% dev_queue_xmit vmlinux Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a1b5d5e03064..035db6350037 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1557,6 +1557,10 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla if (!tb[IFLA_MTU]) dev->mtu = mtu; + /* Can use a lockless transmit, unless we generate output sequences */ + if (!(nt->parms.o_flags & GRE_SEQ)) + dev->features |= NETIF_F_LLTX; + err = register_netdevice(dev); if (err) goto out; -- cgit v1.2.3 From 153f0943382e9ae0bff7caa110a1a4656088d0d4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Sep 2010 00:17:17 +0000 Subject: ipip: enable lockless xmits IPIP tunnels can benefit from lockless xmits, using NETIF_F_LLTX Bench on a 16 cpus machine (dual E5540 cpus), 16 threads sending 10000000 UDP frames via one ipip tunnel (size:200 bytes per frame) Before patch : real 2m53.321s user 0m10.277s sys 46m0.597s After patch: real 0m32.063s user 0m9.237s sys 8m16.255s Last problem to solve is the contention on dst : 16118.00 28.3% __ip_route_output_key vmlinux 6135.00 10.8% dst_release vmlinux 3220.00 5.6% ip_finish_output vmlinux 2149.00 3.8% ip_route_output_flow vmlinux 1575.00 2.8% ip_append_data vmlinux 1481.00 2.6% ip_push_pending_frames vmlinux 1349.00 2.4% __xfrm_lookup vmlinux 1216.00 2.1% csum_partial_copy_generic vmlinux 1208.00 2.1% udp_sendmsg vmlinux Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 9e78f11da786..6ad46c28ede2 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -767,6 +767,7 @@ static void ipip_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; + dev->features |= NETIF_F_LLTX; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } -- cgit v1.2.3 From 8560f2266b36adb43238f1f9fd13958dd031901c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Sep 2010 03:23:34 +0000 Subject: ip6tnl: percpu stats accounting Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets. Other seldom used fields are kept in netdev->stats structure, possibly unsafe. This is a preliminary work to support lockless transmit path, and correct RX stats, that are already unsafe. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 93 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index f6d9f683543e..8be3c452af90 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -75,7 +75,7 @@ MODULE_LICENSE("GPL"); (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ (HASH_SIZE - 1)) -static void ip6_tnl_dev_init(struct net_device *dev); +static int ip6_tnl_dev_init(struct net_device *dev); static void ip6_tnl_dev_setup(struct net_device *dev); static int ip6_tnl_net_id __read_mostly; @@ -88,6 +88,34 @@ struct ip6_tnl_net { struct ip6_tnl __rcu **tnls[2]; }; +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ip6_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + /* * Locking : hash tables are protected by RCU and RTNL */ @@ -216,6 +244,12 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) } } +static void ip6_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + /** * ip6_tnl_create() - create a new tunnel * @p: tunnel parameters @@ -254,7 +288,9 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) t = netdev_priv(dev); t->parms = *p; - ip6_tnl_dev_init(dev); + err = ip6_tnl_dev_init(dev); + if (err < 0) + goto failed_free; if ((err = register_netdevice(dev)) < 0) goto failed_free; @@ -264,7 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) return t; failed_free: - free_netdev(dev); + ip6_dev_free(dev); failed: return NULL; } @@ -700,6 +736,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr)) != NULL) { + struct pcpu_tstats *tstats; + if (t->parms.proto != ipproto && t->parms.proto != 0) { rcu_read_unlock(); goto discard; @@ -722,7 +760,11 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, skb->pkt_type = PACKET_HOST; memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); - skb_tunnel_rx(skb, t->dev); + tstats = this_cpu_ptr(t->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, t->dev); dscp_ecn_decapsulate(t, ipv6h, skb); @@ -935,8 +977,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, err = ip6_local_out(skb); if (net_xmit_eval(err) == 0) { - stats->tx_bytes += pkt_len; - stats->tx_packets++; + struct pcpu_tstats *tstats = this_cpu_ptr(t->dev->tstats); + + tstats->tx_bytes += pkt_len; + tstats->tx_packets++; } else { stats->tx_errors++; stats->tx_aborted_errors++; @@ -1301,12 +1345,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) static const struct net_device_ops ip6_tnl_netdev_ops = { - .ndo_uninit = ip6_tnl_dev_uninit, + .ndo_uninit = ip6_tnl_dev_uninit, .ndo_start_xmit = ip6_tnl_xmit, - .ndo_do_ioctl = ip6_tnl_ioctl, + .ndo_do_ioctl = ip6_tnl_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, + .ndo_get_stats = ip6_get_stats, }; + /** * ip6_tnl_dev_setup - setup virtual tunnel device * @dev: virtual device associated with tunnel @@ -1318,7 +1364,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { static void ip6_tnl_dev_setup(struct net_device *dev) { dev->netdev_ops = &ip6_tnl_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ip6_dev_free; dev->type = ARPHRD_TUNNEL6; dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); @@ -1334,12 +1380,17 @@ static void ip6_tnl_dev_setup(struct net_device *dev) * @dev: virtual device associated with tunnel **/ -static inline void +static inline int ip6_tnl_dev_init_gen(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); + t->dev = dev; strcpy(t->parms.name, dev->name); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } /** @@ -1347,11 +1398,15 @@ ip6_tnl_dev_init_gen(struct net_device *dev) * @dev: virtual device associated with tunnel **/ -static void ip6_tnl_dev_init(struct net_device *dev) +static int ip6_tnl_dev_init(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); - ip6_tnl_dev_init_gen(dev); + int err = ip6_tnl_dev_init_gen(dev); + + if (err) + return err; ip6_tnl_link_config(t); + return 0; } /** @@ -1361,16 +1416,20 @@ static void ip6_tnl_dev_init(struct net_device *dev) * Return: 0 **/ -static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev) +static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); struct net *net = dev_net(dev); struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); + int err = ip6_tnl_dev_init_gen(dev); + + if (err) + return err; - ip6_tnl_dev_init_gen(dev); t->parms.proto = IPPROTO_IPV6; dev_hold(dev); rcu_assign_pointer(ip6n->tnls_wc[0], t); + return 0; } static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { @@ -1420,7 +1479,9 @@ static int __net_init ip6_tnl_init_net(struct net *net) goto err_alloc_dev; dev_net_set(ip6n->fb_tnl_dev, net); - ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + if (err < 0) + goto err_register; err = register_netdev(ip6n->fb_tnl_dev); if (err < 0) @@ -1428,7 +1489,7 @@ static int __net_init ip6_tnl_init_net(struct net *net) return 0; err_register: - free_netdev(ip6n->fb_tnl_dev); + ip6_dev_free(ip6n->fb_tnl_dev); err_alloc_dev: return err; } -- cgit v1.2.3 From bfa5ae63b823f4ffd3483a05f60a93a4a7b7d680 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Sep 2010 05:58:37 +0000 Subject: net: rename netdev rx_queue to ingress_queue There is some confusion with rx_queue name after RPS, and net drivers private rx_queue fields. I suggest to rename "struct net_device"->rx_queue to ingress_queue. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- net/core/dev.c | 8 ++++---- net/sched/sch_api.c | 14 +++++++------- net/sched/sch_generic.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 6f0845e0b888..ceed3474014a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -986,7 +986,7 @@ struct net_device { rx_handler_func_t *rx_handler; void *rx_handler_data; - struct netdev_queue rx_queue; /* use two cache lines */ + struct netdev_queue ingress_queue; /* use two cache lines */ /* * Cache lines mostly used on transmit path diff --git a/net/core/dev.c b/net/core/dev.c index 50daccad6a53..a313bab1b754 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2720,7 +2720,7 @@ static int ing_filter(struct sk_buff *skb) skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); - rxq = &dev->rx_queue; + rxq = &dev->ingress_queue; q = rxq->qdisc; if (q != &noop_qdisc) { @@ -2737,7 +2737,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, struct net_device *orig_dev) { - if (skb->dev->rx_queue.qdisc == &noop_qdisc) + if (skb->dev->ingress_queue.qdisc == &noop_qdisc) goto out; if (*pt_prev) { @@ -4940,7 +4940,7 @@ static void __netdev_init_queue_locks_one(struct net_device *dev, static void netdev_init_queue_locks(struct net_device *dev) { netdev_for_each_tx_queue(dev, __netdev_init_queue_locks_one, NULL); - __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL); + __netdev_init_queue_locks_one(dev, &dev->ingress_queue, NULL); } unsigned long netdev_fix_features(unsigned long features, const char *name) @@ -5452,7 +5452,7 @@ static void netdev_init_one_queue(struct net_device *dev, static void netdev_init_queues(struct net_device *dev) { - netdev_init_one_queue(dev, &dev->rx_queue, NULL); + netdev_init_one_queue(dev, &dev->ingress_queue, NULL); netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); spin_lock_init(&dev->tx_global_lock); } diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 6fb3d41c0e41..b8020784d0e9 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -240,7 +240,7 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) if (q) goto out; - q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle); + q = qdisc_match_from_root(dev->ingress_queue.qdisc_sleeping, handle); out: return q; } @@ -701,7 +701,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, } for (i = 0; i < num_q; i++) { - struct netdev_queue *dev_queue = &dev->rx_queue; + struct netdev_queue *dev_queue = &dev->ingress_queue; if (!ingress) dev_queue = netdev_get_tx_queue(dev, i); @@ -979,7 +979,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) return -ENOENT; q = qdisc_leaf(p, clid); } else { /* ingress */ - q = dev->rx_queue.qdisc_sleeping; + q = dev->ingress_queue.qdisc_sleeping; } } else { q = dev->qdisc; @@ -1044,7 +1044,7 @@ replay: return -ENOENT; q = qdisc_leaf(p, clid); } else { /*ingress */ - q = dev->rx_queue.qdisc_sleeping; + q = dev->ingress_queue.qdisc_sleeping; } } else { q = dev->qdisc; @@ -1124,7 +1124,7 @@ create_n_graft: if (!(n->nlmsg_flags&NLM_F_CREATE)) return -ENOENT; if (clid == TC_H_INGRESS) - q = qdisc_create(dev, &dev->rx_queue, p, + q = qdisc_create(dev, &dev->ingress_queue, p, tcm->tcm_parent, tcm->tcm_parent, tca, &err); else { @@ -1304,7 +1304,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0) goto done; - dev_queue = &dev->rx_queue; + dev_queue = &dev->ingress_queue; if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0) goto done; @@ -1595,7 +1595,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0) goto done; - dev_queue = &dev->rx_queue; + dev_queue = &dev->ingress_queue; if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0) goto done; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 2aeb3a4386a1..545278a1c478 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -753,7 +753,7 @@ void dev_activate(struct net_device *dev) need_watchdog = 0; netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); - transition_one_qdisc(dev, &dev->rx_queue, NULL); + transition_one_qdisc(dev, &dev->ingress_queue, NULL); if (need_watchdog) { dev->trans_start = jiffies; @@ -812,7 +812,7 @@ static bool some_qdisc_is_busy(struct net_device *dev) void dev_deactivate(struct net_device *dev) { netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); - dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); + dev_deactivate_queue(dev, &dev->ingress_queue, &noop_qdisc); dev_watchdog_down(dev); @@ -838,7 +838,7 @@ void dev_init_scheduler(struct net_device *dev) { dev->qdisc = &noop_qdisc; netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); - dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); + dev_init_scheduler_queue(dev, &dev->ingress_queue, &noop_qdisc); setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); } @@ -861,7 +861,7 @@ static void shutdown_scheduler_queue(struct net_device *dev, void dev_shutdown(struct net_device *dev) { netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); - shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); + shutdown_scheduler_queue(dev, &dev->ingress_queue, &noop_qdisc); qdisc_destroy(dev->qdisc); dev->qdisc = &noop_qdisc; -- cgit v1.2.3 From a64de47c091e4a337fa9763315cb6f2fbf0c583b Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 28 Sep 2010 17:08:02 +0000 Subject: arp: remove unnecessary export of arp_broken_ops arp_broken_ops is only used in arp.c Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/arp.h | 2 -- net/ipv4/arp.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/net/arp.h b/include/net/arp.h index 716f43c5c98e..f4cf6ce66586 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -26,6 +26,4 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, const unsigned char *target_hw); extern void arp_xmit(struct sk_buff *skb); -extern const struct neigh_ops arp_broken_ops; - #endif /* _ARP_H */ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 4083c186fd30..d9031ad67826 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -161,7 +161,7 @@ static const struct neigh_ops arp_direct_ops = { .queue_xmit = dev_queue_xmit, }; -const struct neigh_ops arp_broken_ops = { +static const struct neigh_ops arp_broken_ops = { .family = AF_INET, .solicit = arp_solicit, .error_report = arp_error_report, @@ -170,7 +170,6 @@ const struct neigh_ops arp_broken_ops = { .hh_output = dev_queue_xmit, .queue_xmit = dev_queue_xmit, }; -EXPORT_SYMBOL(arp_broken_ops); struct neigh_table arp_tbl = { .family = AF_INET, -- cgit v1.2.3 From 1b9f409293529da4630bfc5d6d8e7d7451a6ccb5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 28 Sep 2010 19:30:14 +0000 Subject: tcp: tcp_enter_quickack_mode can be static Function only used in tcp_input.c Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/tcp.h | 2 -- net/ipv4/tcp_input.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 914a60c7ad62..4fee0424af7e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -346,8 +346,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, } } -extern void tcp_enter_quickack_mode(struct sock *sk); - #define TCP_ECN_OK 1 #define TCP_ECN_QUEUE_CWR 2 #define TCP_ECN_DEMAND_CWR 4 diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fabc09a58d7f..eaf20e7e61da 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct sock *sk) icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); } -void tcp_enter_quickack_mode(struct sock *sk) +static void tcp_enter_quickack_mode(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); tcp_incr_quickack(sk); -- cgit v1.2.3 From 8681dc3abd54e845a2effab441921b4c4457c241 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 29 Sep 2010 01:05:37 +0000 Subject: bnx2x: Moved enabling of MSI to the bnx2x_set_num_queues() Moved enabling of MSI to the bnx2x_set_num_queues() - the same functions that handles the initialization of the MSI-X. From: Vladislav Zolotarov Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 05c05a496b15..8d42067a6989 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1185,8 +1185,10 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) int rc = 0; switch (bp->int_mode) { - case INT_MODE_INTx: case INT_MODE_MSI: + bnx2x_enable_msi(bp); + /* falling through... */ + case INT_MODE_INTx: bp->num_queues = 1; DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; @@ -1202,9 +1204,16 @@ static int bnx2x_set_num_queues(struct bnx2x *bp) * and fallback to MSI or legacy INTx with one fp */ rc = bnx2x_enable_msix(bp); - if (rc) + if (rc) { /* failed to enable MSI-X */ bp->num_queues = 1; + + /* Fall to INTx if failed to enable MSI-X due to lack of + * memory (in bnx2x_set_num_queues()) */ + if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) + bnx2x_enable_msi(bp); + } + break; } netif_set_real_num_tx_queues(bp->dev, bp->num_queues); @@ -1265,10 +1274,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error1; } } else { - /* Fall to INTx if failed to enable MSI-X due to lack of - memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); bnx2x_ack_int(bp); rc = bnx2x_req_irq(bp); if (rc) { -- cgit v1.2.3 From ef09aadf7bf1a17f4d4938855238c0fd8749a99f Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Tue, 28 Sep 2010 08:13:12 +0000 Subject: myri10ge: DCA update (resubmit) This patch contains the following DCA improvements to myri10ge: 1) Finally move myri10ge to use dca3 API 2) Disable PCIe relaxed ordering when enabling DCA on myri10ge. This provides a performance boost on Nehalem based Xeons 3) Make sure to properly initialize NIC's DCA state when it is enabled, rather than giving the NIC a bogus tag (0) and waiting for the first received packet to trigger an update. Not using a real tag can cause hardware exceptions on some motherboards when a CPU socket is empty. 3) Always update the cached CPU when our interrupt affinity changes so as to avoid excessive calls to dca3_get_tag() Signed-off-by: Andrew Gallatin Signed-off-by: Loic Prylli Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3ad1a21ca8ce..8524cc40ec57 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -225,6 +225,7 @@ struct myri10ge_priv { struct msix_entry *msix_vectors; #ifdef CONFIG_MYRI10GE_DCA int dca_enabled; + int relaxed_order; #endif u32 link_state; unsigned int rdma_tags_available; @@ -1074,10 +1075,28 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } #ifdef CONFIG_MYRI10GE_DCA +static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) +{ + int ret, cap, err; + u16 ctl; + + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!cap) + return 0; + + err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4; + if (ret != on) { + ctl &= ~PCI_EXP_DEVCTL_RELAX_EN; + ctl |= (on << 4); + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); + } + return ret; +} + static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { - ss->cpu = cpu; ss->cached_dca_tag = tag; put_be32(htonl(tag), ss->dca_tag); } @@ -1088,9 +1107,10 @@ static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss) int tag; if (cpu != ss->cpu) { - tag = dca_get_tag(cpu); + tag = dca3_get_tag(&ss->mgp->pdev->dev, cpu); if (ss->cached_dca_tag != tag) myri10ge_write_dca(ss, cpu, tag); + ss->cpu = cpu; } put_cpu(); } @@ -1113,9 +1133,13 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp) "dca_add_requester() failed, err=%d\n", err); return; } + mgp->relaxed_order = myri10ge_toggle_relaxed(pdev, 0); mgp->dca_enabled = 1; - for (i = 0; i < mgp->num_slices; i++) - myri10ge_write_dca(&mgp->ss[i], -1, 0); + for (i = 0; i < mgp->num_slices; i++) { + mgp->ss[i].cpu = -1; + mgp->ss[i].cached_dca_tag = -1; + myri10ge_update_dca(&mgp->ss[i]); + } } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) @@ -1126,6 +1150,8 @@ static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; + if (mgp->relaxed_order) + myri10ge_toggle_relaxed(pdev, 1); err = dca_remove_requester(&pdev->dev); } -- cgit v1.2.3 From 862ea4f263c68680558382c1475ad3032c7fd7d4 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 28 Sep 2010 08:18:55 +0000 Subject: de2104x: disable media debug messages by default Print media debug messages only when HW debug is enabled. Signed-off-by: Ondrej Zary Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/tulip/de2104x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 9124c5c638d8..8054009c4b22 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -948,8 +948,9 @@ static void de_set_media (struct de_private *de) else macmode &= ~FullDuplex; - if (netif_msg_link(de)) { + if (netif_msg_link(de)) dev_info(&de->dev->dev, "set link %s\n", media_name[media]); + if (netif_msg_hw(de)) { dev_info(&de->dev->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n", dr32(MacMode), dr32(SIAStatus), dr32(CSR13), dr32(CSR14), dr32(CSR15)); -- cgit v1.2.3 From 9812cb12c9d58c5d9aead84eb2e7864c68c80302 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 28 Sep 2010 08:46:17 +0000 Subject: de2104x: remove experimental status It should be ready after 8 years...remove the experimental dependency. Signed-off-by: Ondrej Zary Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/tulip/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 516713fa0a05..f3035951422f 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -11,8 +11,8 @@ menuconfig NET_TULIP if NET_TULIP config DE2104X - tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + tristate "Early DECchip Tulip (dc2104x) PCI support" + depends on PCI select CRC32 ---help--- This driver is developed for the SMC EtherPower series Ethernet -- cgit v1.2.3 From 65836112fc24bdf009554481b36b6ba0a690b855 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 28 Sep 2010 20:20:28 +0200 Subject: wl12xx: fix non-wl12xx build scenarios Support building wl1271-equipped boards without building the wl1271 driver itself, e.g.: CONFIG_MACH_OMAP_ZOOM3=y CONFIG_WL12XX is not set Reported-by: John W. Linville Signed-off-by: Ohad Ben-Cohen Signed-off-by: Luciano Coelho --- include/linux/wl12xx.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 95deae3968f4..4f902e1908aa 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -32,7 +32,20 @@ struct wl12xx_platform_data { int board_ref_clock; }; +#ifdef CONFIG_WL12XX_PLATFORM_DATA + int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); + +#else + +static inline +int wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + return -ENOSYS; +} + +#endif + const struct wl12xx_platform_data *wl12xx_get_platform_data(void); #endif -- cgit v1.2.3 From 6d0722a2cec2c23db3b0855ff8bb433175a16b44 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Sep 2010 23:35:10 -0700 Subject: ip_gre: comments change HARD_TX_LOCK no longer protects tunnels from dead loops, but xmit_recursion percpu counter. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 035db6350037..fbe2c473a06a 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -64,13 +64,13 @@ We cannot track such dead loops during route installation, it is infeasible task. The most general solutions would be to keep skb->encapsulation counter (sort of local ttl), - and silently drop packet when it expires. It is the best + and silently drop packet when it expires. It is a good solution, but it supposes maintaing new variable in ALL skb, even if no tunneling is used. - Current solution: HARD_TX_LOCK lock breaks dead loops. - - + Current solution: xmit_recursion breaks dead loops. This is a percpu + counter, since when we enter the first ndo_xmit(), cpu migration is + forbidden. We force an exit if this counter reaches RECURSION_LIMIT 2. Networking dead loops would not kill routers, but would really kill network. IP hop limit plays role of "t->recursion" in this case, -- cgit v1.2.3 From 1020660189bb72ae25fd68733ee473d29b8604b5 Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Tue, 28 Sep 2010 04:26:30 +0000 Subject: net: pxa168_etc.c recognize additional contributors Signed-off-by: Philip Rakity Signed-off-by: Sachin Sanap Signed-off-by: Mark Brown Signed-off-by: David S. Miller --- drivers/net/pxa168_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 75c2ff99d66d..18c0297743f1 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -4,6 +4,7 @@ * * Copyright (C) 2010 Marvell International Ltd. * Sachin Sanap + * Zhangfei Gao * Philip Rakity * Mark Brown * -- cgit v1.2.3 From e1a5964f0c32a75b17360cfc565d25aaedbff747 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 29 Sep 2010 22:33:50 +0000 Subject: Phonet: restore flow control credits when sending fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch restores the below flow control patch submitted by Rémi Denis-Courmont, which accidentaly got lost due to Pipe controller patch on Phonet. commit 1a98214feef2221cd7c24b17cd688a5a9d85b2ea Author: Rémi Denis-Courmont Date: Mon Aug 30 12:57:03 2010 +0000 Phonet: restore flow control credits when sending fails Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller Signed-off-by: Kumar Sanghvi Acked-by: Linus Walleij Signed-off-by: David S. Miller --- net/phonet/pep.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 7bf23cf36b02..552fb665645f 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -1288,6 +1288,7 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) { struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; + int err; #ifdef CONFIG_PHONET_PIPECTRLR struct sockaddr_pn spn = { .spn_family = AF_PHONET, @@ -1314,10 +1315,15 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) ph->message_id = PNS_PIPE_DATA; ph->pipe_handle = pn->pipe_handle; #ifdef CONFIG_PHONET_PIPECTRLR - return pn_skb_send(sk, skb, &spn); + err = pn_skb_send(sk, skb, &spn); #else - return pn_skb_send(sk, skb, &pipe_srv); + err = pn_skb_send(sk, skb, &pipe_srv); #endif + + if (err && pn_flow_safe(pn->tx_fc)) + atomic_inc(&pn->tx_credits); + return err; + } static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, -- cgit v1.2.3 From dd28d1a0b5ecc0f5512f658b1a8fd38bc4f4c98c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Sep 2010 11:53:50 +0000 Subject: ipv4: __mkroute_output() speedup While doing stress tests with a disabled IP route cache, I found __mkroute_output() was touching three times in_device atomic refcount. Use RCU to touch it once to reduce cache line ping pongs. Before patch time to perform the test real 1m42.009s user 0m12.545s sys 25m0.726s Profile : 16109.00 26.4% ip_route_output_slow vmlinux 7434.00 12.2% dst_destroy vmlinux 3280.00 5.4% fib_rules_lookup vmlinux 3252.00 5.3% fib_semantic_match vmlinux 2622.00 4.3% fib_table_lookup vmlinux 2535.00 4.1% dst_alloc vmlinux 1750.00 2.9% _raw_read_lock vmlinux 1532.00 2.5% rt_set_nexthop vmlinux After patch real 1m36.503s user 0m12.977s sys 23m25.608s 14234.00 22.4% ip_route_output_slow vmlinux 8717.00 13.7% dst_destroy vmlinux 4052.00 6.4% fib_rules_lookup vmlinux 3951.00 6.2% fib_semantic_match vmlinux 3191.00 5.0% dst_alloc vmlinux 1764.00 2.8% fib_table_lookup vmlinux 1692.00 2.7% _raw_read_lock vmlinux 1605.00 2.5% rt_set_nexthop vmlinux Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 98beda47bc99..ea895004caf3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2358,9 +2358,8 @@ static int __mkroute_output(struct rtable **result, struct rtable *rth; struct in_device *in_dev; u32 tos = RT_FL_TOS(oldflp); - int err = 0; - if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK)) + if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags & IFF_LOOPBACK)) return -EINVAL; if (fl->fl4_dst == htonl(0xFFFFFFFF)) @@ -2373,11 +2372,12 @@ static int __mkroute_output(struct rtable **result, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - /* get work reference to inet device */ - in_dev = in_dev_get(dev_out); - if (!in_dev) + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev_out); + if (!in_dev) { + rcu_read_unlock(); return -EINVAL; - + } if (res->type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; if (res->fi) { @@ -2385,13 +2385,13 @@ static int __mkroute_output(struct rtable **result, res->fi = NULL; } } else if (res->type == RTN_MULTICAST) { - flags |= RTCF_MULTICAST|RTCF_LOCAL; + flags |= RTCF_MULTICAST | RTCF_LOCAL; if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src, oldflp->proto)) flags &= ~RTCF_LOCAL; /* If multicast route do not exist use - default one, but do not gateway in this case. - Yes, it is hack. + * default one, but do not gateway in this case. + * Yes, it is hack. */ if (res->fi && res->prefixlen < 4) { fib_info_put(res->fi); @@ -2402,9 +2402,12 @@ static int __mkroute_output(struct rtable **result, rth = dst_alloc(&ipv4_dst_ops); if (!rth) { - err = -ENOBUFS; - goto cleanup; + rcu_read_unlock(); + return -ENOBUFS; } + in_dev_hold(in_dev); + rcu_read_unlock(); + rth->idev = in_dev; atomic_set(&rth->dst.__refcnt, 1); rth->dst.flags= DST_HOST; @@ -2425,7 +2428,6 @@ static int __mkroute_output(struct rtable **result, cache entry */ rth->dst.dev = dev_out; dev_hold(dev_out); - rth->idev = in_dev_get(dev_out); rth->rt_gateway = fl->fl4_dst; rth->rt_spec_dst= fl->fl4_src; @@ -2460,13 +2462,8 @@ static int __mkroute_output(struct rtable **result, rt_set_nexthop(rth, res, 0); rth->rt_flags = flags; - *result = rth; - cleanup: - /* release work reference to inet device */ - in_dev_put(in_dev); - - return err; + return 0; } static int ip_mkroute_output(struct rtable **rp, -- cgit v1.2.3 From 6af3b9ebfea38d0a057fbd7bdcecc61ac5662f02 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 29 Sep 2010 21:35:23 +0000 Subject: ixgbe: fix link issues and panic with shared interrupts for 82598 Fix possible panic/hang with shared Legacy interrupts by not enabling interrupts when interface is down. Also fixes an intermittent link by enabling LSC upon exit from ixgbe_intr() This patch adds flags to ixgbe_irq_enable() to allow for some flexibility when enabling interrupts. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c35185cb27fe..c35e13c01dbe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2233,7 +2233,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) * ixgbe_irq_enable - Enable default interrupt generation settings * @adapter: board private structure **/ -static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) +static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, + bool flush) { u32 mask; @@ -2254,8 +2255,10 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) mask |= IXGBE_EIMS_FLOW_DIR; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - ixgbe_irq_enable_queues(adapter, ~0); - IXGBE_WRITE_FLUSH(&adapter->hw); + if (queues) + ixgbe_irq_enable_queues(adapter, ~0); + if (flush) + IXGBE_WRITE_FLUSH(&adapter->hw); if (adapter->num_vfs > 32) { u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1; @@ -2277,7 +2280,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data) u32 eicr; /* - * Workaround for silicon errata. Mask the interrupts + * Workaround for silicon errata on 82598. Mask the interrupts * before the read of EICR. */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); @@ -2286,10 +2289,15 @@ static irqreturn_t ixgbe_intr(int irq, void *data) * therefore no explict interrupt disable is necessary */ eicr = IXGBE_READ_REG(hw, IXGBE_EICR); if (!eicr) { - /* shared interrupt alert! + /* + * shared interrupt alert! * make sure interrupts are enabled because the read will - * have disabled interrupts due to EIAM */ - ixgbe_irq_enable(adapter); + * have disabled interrupts due to EIAM + * finish the workaround of silicon errata on 82598. Unmask + * the interrupt that we masked before the EICR read. + */ + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter, true, true); return IRQ_NONE; /* Not our interrupt */ } @@ -2313,6 +2321,14 @@ static irqreturn_t ixgbe_intr(int irq, void *data) __napi_schedule(&(q_vector->napi)); } + /* + * re-enable link(maybe) and non-queue interrupts, no flush. + * ixgbe_poll will re-enable the queue interrupts + */ + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter, false, false); + return IRQ_HANDLED; } @@ -3048,7 +3064,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) vlan_group_set_device(adapter->vlgrp, vid, NULL); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); + ixgbe_irq_enable(adapter, true, true); /* remove VID from filter table */ hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); @@ -3145,7 +3161,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, ixgbe_vlan_rx_add_vid(netdev, 0); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); + ixgbe_irq_enable(adapter, true, true); } static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) @@ -3546,7 +3562,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_EICR); - ixgbe_irq_enable(adapter); + ixgbe_irq_enable(adapter, true, true); /* * If this adapter has a fan, check to see if we had a failure -- cgit v1.2.3 From 3a3b75860527a11ba5035c6aa576079245d09e2a Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 29 Sep 2010 21:38:49 +0000 Subject: e1000e: use hardware writeback batching Most e1000e parts support batching writebacks. The problem with this is that when some of the TADV or TIDV timers are not set, Tx can sit forever. This is solved in this patch with write flushes using the Flush Partial Descriptors (FPD) bit in TIDV and RDTR. This improves bus utilization and removes partial writes on e1000e, particularly from 82571 parts in S5500 chipset based machines. Only ES2LAN and 82571/2 parts are included in this optimization, to reduce testing load. Signed-off-by: Jesse Brandeburg Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/82571.c | 6 +++-- drivers/net/e1000e/defines.h | 2 ++ drivers/net/e1000e/e1000.h | 28 +++++++++++++++++++++++ drivers/net/e1000e/es2lan.c | 1 + drivers/net/e1000e/netdev.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ drivers/net/e1000e/param.c | 2 -- 6 files changed, 88 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index d3d4a57e2450..ca663f19d7df 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1801,7 +1801,8 @@ struct e1000_info e1000_82571_info = { | FLAG_RESET_OVERWRITES_LAA /* errata */ | FLAG_TARC_SPEED_MODE_BIT /* errata */ | FLAG_APME_CHECK_PORT_B, - .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ + .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ + | FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -1819,7 +1820,8 @@ struct e1000_info e1000_82572_info = { | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_TARC_SPEED_MODE_BIT, /* errata */ - .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ + .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ + | FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 93b3bedae8d2..d3f7a9c3f973 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -446,7 +446,9 @@ /* Transmit Descriptor Control */ #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ #define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ #define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ /* Enable the counting of desc. still to be processed. */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index f9a31c82f871..5ec0af59eeab 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -153,6 +153,33 @@ struct e1000_info; /* Time to wait before putting the device into D3 if there's no link (in ms). */ #define LINK_TIMEOUT 100 +#define DEFAULT_RDTR 0 +#define DEFAULT_RADV 8 +#define BURST_RDTR 0x20 +#define BURST_RADV 0x20 + +/* + * in the case of WTHRESH, it appears at least the 82571/2 hardware + * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when + * WTHRESH=4, and since we want 64 bytes at a time written back, set + * it to 5 + */ +#define E1000_TXDCTL_DMA_BURST_ENABLE \ + (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \ + E1000_TXDCTL_COUNT_DESC | \ + (5 << 16) | /* wthresh must be +1 more than desired */\ + (1 << 8) | /* hthresh */ \ + 0x1f) /* pthresh */ + +#define E1000_RXDCTL_DMA_BURST_ENABLE \ + (0x01000000 | /* set descriptor granularity */ \ + (4 << 16) | /* set writeback threshold */ \ + (4 << 8) | /* set prefetch threshold */ \ + 0x20) /* set hthresh */ + +#define E1000_TIDV_FPD (1 << 31) +#define E1000_RDTR_FPD (1 << 31) + enum e1000_boards { board_82571, board_82572, @@ -425,6 +452,7 @@ struct e1000_info { #define FLAG2_DISABLE_ASPM_L1 (1 << 3) #define FLAG2_HAS_PHY_STATS (1 << 4) #define FLAG2_HAS_EEE (1 << 5) +#define FLAG2_DMA_BURST (1 << 6) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 45aebb4a6fe1..24f8ac9cf703 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -1494,6 +1494,7 @@ struct e1000_info e1000_es2_info = { | FLAG_APME_CHECK_PORT_B | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, + .flags2 = FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_80003es2lan, diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c69563c3ce96..1aa4228e860a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2650,6 +2650,26 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* Tx irq moderation */ ew32(TADV, adapter->tx_abs_int_delay); + if (adapter->flags2 & FLAG2_DMA_BURST) { + u32 txdctl = er32(TXDCTL(0)); + txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH | + E1000_TXDCTL_WTHRESH); + /* + * set up some performance related parameters to encourage the + * hardware to use the bus more efficiently in bursts, depends + * on the tx_int_delay to be enabled, + * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time + * hthresh = 1 ==> prefetch when one or more available + * pthresh = 0x1f ==> prefetch if internal cache 31 or less + * BEWARE: this seems to work but should be considered first if + * there are tx hangs or other tx related bugs + */ + txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; + ew32(TXDCTL(0), txdctl); + /* erratum work around: set txdctl the same for both queues */ + ew32(TXDCTL(1), txdctl); + } + /* Program the Transmit Control Register */ tctl = er32(TCTL); tctl &= ~E1000_TCTL_CT; @@ -2872,6 +2892,29 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) e1e_flush(); msleep(10); + if (adapter->flags2 & FLAG2_DMA_BURST) { + /* + * set the writeback threshold (only takes effect if the RDTR + * is set). set GRAN=1 and write back up to 0x4 worth, and + * enable prefetching of 0x20 rx descriptors + * granularity = 01 + * wthresh = 04, + * hthresh = 04, + * pthresh = 0x20 + */ + ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE); + ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE); + + /* + * override the delay timers for enabling bursting, only if + * the value was not set by the user via module options + */ + if (adapter->rx_int_delay == DEFAULT_RDTR) + adapter->rx_int_delay = BURST_RDTR; + if (adapter->rx_abs_int_delay == DEFAULT_RADV) + adapter->rx_abs_int_delay = BURST_RADV; + } + /* set the Receive Delay Timer Register */ ew32(RDTR, adapter->rx_int_delay); @@ -4235,6 +4278,16 @@ link_up: /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = 1; + /* flush partial descriptors to memory before detecting tx hang */ + if (adapter->flags2 & FLAG2_DMA_BURST) { + ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); + ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); + /* + * no need to flush the writes because the timeout code does + * an er32 first thing + */ + } + /* * With 82571 controllers, LAA may be overwritten due to controller * reset from the other port. Set the appropriate LAA in RAR[0] diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 34aeec13bb16..3d36911f77f3 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -91,7 +91,6 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); * Valid Range: 0-65535 */ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); -#define DEFAULT_RDTR 0 #define MAX_RXDELAY 0xFFFF #define MIN_RXDELAY 0 @@ -101,7 +100,6 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); * Valid Range: 0-65535 */ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); -#define DEFAULT_RADV 8 #define MAX_RXABSDELAY 0xFFFF #define MIN_RXABSDELAY 0 -- cgit v1.2.3 From 828bac87bb074f3366621724fdfbe314f98ccc7e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 29 Sep 2010 21:39:37 +0000 Subject: e1000e: 82579 performance improvements The initial support for 82579 was tuned poorly for performance. Adjust the packet buffer allocation appropriately for both standard and jumbo frames; and for jumbo frames increase the receive descriptor pre-fetch, disable adaptive interrupt moderation and set the DMA latency tolerance. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/e1000.h | 1 + drivers/net/e1000e/ich8lan.c | 2 +- drivers/net/e1000e/netdev.c | 50 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 5ec0af59eeab..cee882dd67bf 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -453,6 +453,7 @@ struct e1000_info { #define FLAG2_HAS_PHY_STATS (1 << 4) #define FLAG2_HAS_EEE (1 << 5) #define FLAG2_DMA_BURST (1 << 6) +#define FLAG2_DISABLE_AIM (1 << 8) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 57b5435599ab..e3374d9a2472 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -3986,7 +3986,7 @@ struct e1000_info e1000_pch2_info = { | FLAG_APME_IN_WUC, .flags2 = FLAG2_HAS_PHY_STATS | FLAG2_HAS_EEE, - .pba = 18, + .pba = 26, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1aa4228e860a..992b622fe205 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2290,6 +2290,11 @@ static void e1000_set_itr(struct e1000_adapter *adapter) goto set_itr_now; } + if (adapter->flags2 & FLAG2_DISABLE_AIM) { + new_itr = 0; + goto set_itr_now; + } + adapter->tx_itr = e1000_update_itr(adapter, adapter->tx_itr, adapter->total_tx_packets, @@ -2338,7 +2343,10 @@ set_itr_now: if (adapter->msix_entries) adapter->rx_ring->set_itr = 1; else - ew32(ITR, 1000000000 / (new_itr * 256)); + if (new_itr) + ew32(ITR, 1000000000 / (new_itr * 256)); + else + ew32(ITR, 0); } } @@ -2920,7 +2928,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* irq moderation */ ew32(RADV, adapter->rx_abs_int_delay); - if (adapter->itr_setting != 0) + if ((adapter->itr_setting != 0) && (adapter->itr != 0)) ew32(ITR, 1000000000 / (adapter->itr * 256)); ctrl_ext = er32(CTRL_EXT); @@ -2965,11 +2973,13 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) * packet size is equal or larger than the specified value (in 8 byte * units), e.g. using jumbo frames when setting to E1000_ERT_2048 */ - if (adapter->flags & FLAG_HAS_ERT) { + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) { if (adapter->netdev->mtu > ETH_DATA_LEN) { u32 rxdctl = er32(RXDCTL(0)); ew32(RXDCTL(0), rxdctl | 0x3); - ew32(ERT, E1000_ERT_2048 | (1 << 13)); + if (adapter->flags & FLAG_HAS_ERT) + ew32(ERT, E1000_ERT_2048 | (1 << 13)); /* * With jumbo frames and early-receive enabled, * excessive C-state transition latencies result in @@ -3232,9 +3242,35 @@ void e1000e_reset(struct e1000_adapter *adapter) fc->low_water = 0x05048; fc->pause_time = 0x0650; fc->refresh_time = 0x0400; + if (adapter->netdev->mtu > ETH_DATA_LEN) { + pba = 14; + ew32(PBA, pba); + } break; } + /* + * Disable Adaptive Interrupt Moderation if 2 full packets cannot + * fit in receive buffer and early-receive not supported. + */ + if (adapter->itr_setting & 0x3) { + if (((adapter->max_frame_size * 2) > (pba << 10)) && + !(adapter->flags & FLAG_HAS_ERT)) { + if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) { + dev_info(&adapter->pdev->dev, + "Interrupt Throttle Rate turned off\n"); + adapter->flags2 |= FLAG2_DISABLE_AIM; + ew32(ITR, 0); + } + } else if (adapter->flags2 & FLAG2_DISABLE_AIM) { + dev_info(&adapter->pdev->dev, + "Interrupt Throttle Rate turned on\n"); + adapter->flags2 &= ~FLAG2_DISABLE_AIM; + adapter->itr = 20000; + ew32(ITR, 1000000000 / (adapter->itr * 256)); + } + } + /* Allow time for pending master requests to run */ mac->ops.reset_hw(hw); @@ -3553,7 +3589,8 @@ static int e1000_open(struct net_device *netdev) e1000_update_mng_vlan(adapter); /* DMA latency requirement to workaround early-receive/jumbo issue */ - if (adapter->flags & FLAG_HAS_ERT) + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); @@ -3662,7 +3699,8 @@ static int e1000_close(struct net_device *netdev) if (adapter->flags & FLAG_HAS_AMT) e1000_release_hw_control(adapter); - if (adapter->flags & FLAG_HAS_ERT) + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) pm_qos_remove_request(&adapter->netdev->pm_qos_req); pm_runtime_put_sync(&pdev->dev); -- cgit v1.2.3 From 82efee1499a27c06f5afb11b07db384fdb3f7004 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 30 Sep 2010 03:31:56 +0000 Subject: ipv4: introduce __ip_dev_find() ip_dev_find(net, addr) finds a device given an IPv4 source address and takes a reference on it. Introduce __ip_dev_find(), taking a third argument, to optionally take the device reference. Callers not asking the reference to be taken should be in an rcu_read_lock() protected section. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 7 ++++++- net/ipv4/fib_frontend.c | 32 +++++++++++++++++++------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 1ec09bb4a3ab..ccd5b07d678d 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -159,7 +159,12 @@ struct in_ifaddr { extern int register_inetaddr_notifier(struct notifier_block *nb); extern int unregister_inetaddr_notifier(struct notifier_block *nb); -extern struct net_device *ip_dev_find(struct net *net, __be32 addr); +extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref); +static inline struct net_device *ip_dev_find(struct net *net, __be32 addr) +{ + return __ip_dev_find(net, addr, true); +} + extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *); extern void devinet_init(void); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 981f3c59b334..4a69a957872b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -147,34 +147,40 @@ static void fib_flush(struct net *net) rt_cache_flush(net, -1); } -/* - * Find the first device with a given source address. +/** + * __ip_dev_find - find the first device with a given source address. + * @net: the net namespace + * @addr: the source address + * @devref: if true, take a reference on the found device + * + * If a caller uses devref=false, it should be protected by RCU */ - -struct net_device * ip_dev_find(struct net *net, __be32 addr) +struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } }, - .flags = FLOWI_FLAG_MATCH_ANY_IIF }; - struct fib_result res; + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = addr + } + }, + .flags = FLOWI_FLAG_MATCH_ANY_IIF + }; + struct fib_result res = { 0 }; struct net_device *dev = NULL; -#ifdef CONFIG_IP_MULTIPLE_TABLES - res.r = NULL; -#endif - if (fib_lookup(net, &fl, &res)) return NULL; if (res.type != RTN_LOCAL) goto out; dev = FIB_RES_DEV(res); - if (dev) + if (dev && devref) dev_hold(dev); out: fib_res_put(&res); return dev; } -EXPORT_SYMBOL(ip_dev_find); +EXPORT_SYMBOL(__ip_dev_find); /* * Find address type as if only "dev" was present in the system. If -- cgit v1.2.3 From 0197aa38df2ce550c0bfc96194b07ce6b68af814 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 30 Sep 2010 03:33:58 +0000 Subject: ipv4: rcu conversion in ip_route_output_slow ip_route_output_slow() is enclosed in an rcu_read_lock() protected section, so that no references are taken/released on device, thanks to __ip_dev_find() & dev_get_by_index_rcu() Tested with ip route cache disabled, and a stress test : Before patch: elapsed time : real 1m38.347s user 0m11.909s sys 23m51.501s Profile: 13788.00 22.7% ip_route_output_slow [kernel] 7875.00 13.0% dst_destroy [kernel] 3925.00 6.5% fib_semantic_match [kernel] 3144.00 5.2% fib_rules_lookup [kernel] 3061.00 5.0% dst_alloc [kernel] 2276.00 3.7% rt_set_nexthop [kernel] 1762.00 2.9% fib_table_lookup [kernel] 1538.00 2.5% _raw_read_lock [kernel] 1358.00 2.2% ip_output [kernel] After patch: real 1m28.808s user 0m13.245s sys 20m37.293s 10950.00 17.2% ip_route_output_slow [kernel] 10726.00 16.9% dst_destroy [kernel] 5170.00 8.1% fib_semantic_match [kernel] 3937.00 6.2% dst_alloc [kernel] 3635.00 5.7% rt_set_nexthop [kernel] 2900.00 4.6% fib_rules_lookup [kernel] 2240.00 3.5% fib_table_lookup [kernel] 1427.00 2.2% _raw_read_lock [kernel] 1157.00 1.8% kmem_cache_alloc [kernel] Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ea895004caf3..a61acea975f1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2487,6 +2487,7 @@ static int ip_mkroute_output(struct rtable **rp, /* * Major route resolver routine. + * called with rcu_read_lock(); */ static int ip_route_output_slow(struct net *net, struct rtable **rp, @@ -2505,7 +2506,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, .iif = net->loopback_dev->ifindex, .oif = oldflp->oif }; struct fib_result res; - unsigned flags = 0; + unsigned int flags = 0; struct net_device *dev_out = NULL; int free_res = 0; int err; @@ -2535,7 +2536,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, (ipv4_is_multicast(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ - dev_out = ip_dev_find(net, oldflp->fl4_src); + dev_out = __ip_dev_find(net, oldflp->fl4_src, false); if (dev_out == NULL) goto out; @@ -2560,26 +2561,21 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ - dev_out = ip_dev_find(net, oldflp->fl4_src); - if (dev_out == NULL) + if (!__ip_dev_find(net, oldflp->fl4_src, false)) goto out; - dev_put(dev_out); - dev_out = NULL; } } if (oldflp->oif) { - dev_out = dev_get_by_index(net, oldflp->oif); + dev_out = dev_get_by_index_rcu(net, oldflp->oif); err = -ENODEV; if (dev_out == NULL) goto out; /* RACE: Check return value of inet_select_addr instead. */ - if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) { - dev_put(dev_out); + if (rcu_dereference(dev_out->ip_ptr) == NULL) goto out; /* Wrong error code */ - } if (ipv4_is_local_multicast(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) { @@ -2602,10 +2598,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, fl.fl4_dst = fl.fl4_src; if (!fl.fl4_dst) fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); - if (dev_out) - dev_put(dev_out); dev_out = net->loopback_dev; - dev_hold(dev_out); fl.oif = net->loopback_dev->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; @@ -2639,8 +2632,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, res.type = RTN_UNICAST; goto make_route; } - if (dev_out) - dev_put(dev_out); err = -ENETUNREACH; goto out; } @@ -2649,10 +2640,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (res.type == RTN_LOCAL) { if (!fl.fl4_src) fl.fl4_src = fl.fl4_dst; - if (dev_out) - dev_put(dev_out); dev_out = net->loopback_dev; - dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) fib_info_put(res.fi); @@ -2672,28 +2660,23 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (!fl.fl4_src) fl.fl4_src = FIB_RES_PREFSRC(res); - if (dev_out) - dev_put(dev_out); dev_out = FIB_RES_DEV(res); - dev_hold(dev_out); fl.oif = dev_out->ifindex; make_route: err = ip_mkroute_output(rp, &res, &fl, oldflp, dev_out, flags); - if (free_res) fib_res_put(&res); - if (dev_out) - dev_put(dev_out); out: return err; } int __ip_route_output_key(struct net *net, struct rtable **rp, const struct flowi *flp) { - unsigned hash; + unsigned int hash; + int res; struct rtable *rth; if (!rt_caching(net)) @@ -2724,7 +2707,10 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, rcu_read_unlock_bh(); slow_output: - return ip_route_output_slow(net, rp, flp); + rcu_read_lock(); + res = ip_route_output_slow(net, rp, flp); + rcu_read_unlock(); + return res; } EXPORT_SYMBOL_GPL(__ip_route_output_key); -- cgit v1.2.3 From 66cfd1bd05a7a1c31c9cdbb2ddf5c57d1cddc5f6 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:30 +0000 Subject: tg3: Fix potential netpoll crash Up until now the tg3 driver would call netif_napi_add() for the maximum number of NAPI instances the driver could use. The problem is that netpoll could call tg3_poll() on instances that are not active. The net effect is that the driver will crash attempting to dereference uninitialized pointers. The fix is to only allocate as many NAPI instances as the driver would use in tg3_open() and deleted them in tg3_close(). Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 111 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 46 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 54fff5bb6f98..982ed44f0752 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -752,42 +752,6 @@ static void tg3_int_reenable(struct tg3_napi *tnapi) HOSTCC_MODE_ENABLE | tnapi->coal_now); } -static void tg3_napi_disable(struct tg3 *tp) -{ - int i; - - for (i = tp->irq_cnt - 1; i >= 0; i--) - napi_disable(&tp->napi[i].napi); -} - -static void tg3_napi_enable(struct tg3 *tp) -{ - int i; - - for (i = 0; i < tp->irq_cnt; i++) - napi_enable(&tp->napi[i].napi); -} - -static inline void tg3_netif_stop(struct tg3 *tp) -{ - tp->dev->trans_start = jiffies; /* prevent tx timeout */ - tg3_napi_disable(tp); - netif_tx_disable(tp->dev); -} - -static inline void tg3_netif_start(struct tg3 *tp) -{ - /* NOTE: unconditional netif_tx_wake_all_queues is only - * appropriate so long as all callers are assured to - * have free tx slots (such as after tg3_init_hw) - */ - netif_tx_wake_all_queues(tp->dev); - - tg3_napi_enable(tp); - tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; - tg3_enable_ints(tp); -} - static void tg3_switch_clocks(struct tg3 *tp) { u32 clock_ctrl; @@ -4338,6 +4302,11 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) return err; } +static inline int tg3_irq_sync(struct tg3 *tp) +{ + return tp->irq_sync; +} + /* This is called whenever we suspect that the system chipset is re- * ordering the sequence of MMIO to the tx send mailbox. The symptom * is bogus tx completions. We try to recover by setting the @@ -5083,6 +5052,59 @@ tx_recovery: return work_done; } +static void tg3_napi_disable(struct tg3 *tp) +{ + int i; + + for (i = tp->irq_cnt - 1; i >= 0; i--) + napi_disable(&tp->napi[i].napi); +} + +static void tg3_napi_enable(struct tg3 *tp) +{ + int i; + + for (i = 0; i < tp->irq_cnt; i++) + napi_enable(&tp->napi[i].napi); +} + +static void tg3_napi_init(struct tg3 *tp) +{ + int i; + + netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64); + for (i = 1; i < tp->irq_cnt; i++) + netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64); +} + +static void tg3_napi_fini(struct tg3 *tp) +{ + int i; + + for (i = 0; i < tp->irq_cnt; i++) + netif_napi_del(&tp->napi[i].napi); +} + +static inline void tg3_netif_stop(struct tg3 *tp) +{ + tp->dev->trans_start = jiffies; /* prevent tx timeout */ + tg3_napi_disable(tp); + netif_tx_disable(tp->dev); +} + +static inline void tg3_netif_start(struct tg3 *tp) +{ + /* NOTE: unconditional netif_tx_wake_all_queues is only + * appropriate so long as all callers are assured to + * have free tx slots (such as after tg3_init_hw) + */ + netif_tx_wake_all_queues(tp->dev); + + tg3_napi_enable(tp); + tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; + tg3_enable_ints(tp); +} + static void tg3_irq_quiesce(struct tg3 *tp) { int i; @@ -5096,11 +5118,6 @@ static void tg3_irq_quiesce(struct tg3 *tp) synchronize_irq(tp->napi[i].irq_vec); } -static inline int tg3_irq_sync(struct tg3 *tp) -{ - return tp->irq_sync; -} - /* Fully shutdown all tg3 driver activity elsewhere in the system. * If irq_sync is non-zero, then the IRQ handler must be synchronized * with as well. Most of the time, this is not necessary except when @@ -8920,6 +8937,8 @@ static int tg3_open(struct net_device *dev) if (err) goto err_out1; + tg3_napi_init(tp); + tg3_napi_enable(tp); for (i = 0; i < tp->irq_cnt; i++) { @@ -9007,6 +9026,7 @@ err_out3: err_out2: tg3_napi_disable(tp); + tg3_napi_fini(tp); tg3_free_consistent(tp); err_out1: @@ -9054,6 +9074,8 @@ static int tg3_close(struct net_device *dev) memcpy(&tp->estats_prev, tg3_get_estats(tp), sizeof(tp->estats_prev)); + tg3_napi_fini(tp); + tg3_free_consistent(tp); tg3_set_power_state(tp, PCI_D3hot); @@ -14604,13 +14626,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tnapi->consmbox = rcvmbx; tnapi->prodmbox = sndmbx; - if (i) { + if (i) tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1); - netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64); - } else { + else tnapi->coal_now = HOSTCC_MODE_NOW; - netif_napi_add(dev, &tnapi->napi, tg3_poll, 64); - } if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX)) break; -- cgit v1.2.3 From d309a46e42542223946d3a9e4e239fdc945cb53e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:31 +0000 Subject: tg3: 5719: Prevent tx data corruption This patch enables a bit that prevents read DMA overflows and adjusts the txmbuf margin from the hardware default. The combination of these modifications prevents a tx data corruption issue we were seeing on the 5719. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 12 +++++++++++- drivers/net/tg3.h | 8 +++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 982ed44f0752..b6388be1cd1e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7857,7 +7857,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(BUFMGR_DMA_HIGH_WATER, tp->bufmgr_config.dma_high_water); - tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE); + val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + val |= BUFMGR_MODE_NO_TX_UNDERRUN; + tw32(BUFMGR_MODE, val); for (i = 0; i < 2000; i++) { if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE) break; @@ -8037,6 +8040,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); + tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val | + TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K | + TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K); + } + /* Receive/send statistics. */ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { val = tr32(RCVLPC_STATS_ENABLE); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 44733e4a68a2..ec62f057ff6d 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1225,6 +1225,7 @@ #define BUFMGR_MODE_ATTN_ENABLE 0x00000004 #define BUFMGR_MODE_BM_TEST 0x00000008 #define BUFMGR_MODE_MBLOW_ATTN_ENAB 0x00000010 +#define BUFMGR_MODE_NO_TX_UNDERRUN 0x80000000 #define BUFMGR_STATUS 0x00004404 #define BUFMGR_STATUS_ERROR 0x00000004 #define BUFMGR_STATUS_MBLOW 0x00000010 @@ -1306,7 +1307,12 @@ #define TG3_RDMA_RSRVCTRL_REG 0x00004900 #define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 -/* 0x4904 --> 0x4c00 unused */ +/* 0x4904 --> 0x4910 unused */ + +#define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 +#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 +#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 +/* 0x4914 --> 0x4c00 unused */ /* Write DMA control registers */ #define WDMAC_MODE 0x00004c00 -- cgit v1.2.3 From f51a8903f14512f5ce61a74657db7f84f16b2717 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:32 +0000 Subject: tg3: Remove 5724 device ID This product was never released to the public. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 -- drivers/net/tg3.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b6388be1cd1e..035d0d94e2b3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -264,7 +264,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)}, @@ -12883,7 +12882,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719) pci_read_config_dword(tp->pdev, TG3PCI_GEN2_PRODID_ASICREV, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ec62f057ff6d..241e31487166 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -46,7 +46,6 @@ #define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */ #define TG3PCI_DEVICE_TIGON3_5717 0x1655 #define TG3PCI_DEVICE_TIGON3_5718 0x1656 -#define TG3PCI_DEVICE_TIGON3_5724 0x165c #define TG3PCI_DEVICE_TIGON3_57781 0x16b1 #define TG3PCI_DEVICE_TIGON3_57785 0x16b5 #define TG3PCI_DEVICE_TIGON3_57761 0x16b0 -- cgit v1.2.3 From 37a949c54857d8b2a38dbdc75bc8666c3292cbc4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:33 +0000 Subject: tg3: Cleanup missing VPD partno section This patch cleans up the default VPD partno section. New entries for 5717 asic rev devices were also added. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 71 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 035d0d94e2b3..3b275663bbd8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12532,44 +12532,49 @@ partno: out_not_found: kfree(vpd_data); - if (!tp->board_part_number[0]) + if (tp->board_part_number[0]) return; out_no_vpd: - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717) + strcpy(tp->board_part_number, "BCM5717"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718) + strcpy(tp->board_part_number, "BCM5718"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) + strcpy(tp->board_part_number, "BCM57780"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) + strcpy(tp->board_part_number, "BCM57760"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) + strcpy(tp->board_part_number, "BCM57790"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788) + strcpy(tp->board_part_number, "BCM57788"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761) + strcpy(tp->board_part_number, "BCM57761"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765) + strcpy(tp->board_part_number, "BCM57765"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781) + strcpy(tp->board_part_number, "BCM57781"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785) + strcpy(tp->board_part_number, "BCM57785"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791) + strcpy(tp->board_part_number, "BCM57791"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795) + strcpy(tp->board_part_number, "BCM57795"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { strcpy(tp->board_part_number, "BCM95906"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) - strcpy(tp->board_part_number, "BCM57780"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) - strcpy(tp->board_part_number, "BCM57760"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) - strcpy(tp->board_part_number, "BCM57790"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788) - strcpy(tp->board_part_number, "BCM57788"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761) - strcpy(tp->board_part_number, "BCM57761"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765) - strcpy(tp->board_part_number, "BCM57765"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781) - strcpy(tp->board_part_number, "BCM57781"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785) - strcpy(tp->board_part_number, "BCM57785"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791) - strcpy(tp->board_part_number, "BCM57791"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795) - strcpy(tp->board_part_number, "BCM57795"); - else + } else { +nomatch: strcpy(tp->board_part_number, "none"); + } } static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset) -- cgit v1.2.3 From 1da85aa3db6878639e407548dad5b2404443e2c5 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:34 +0000 Subject: tg3: Futureproof the loopback test There are other multiqueue modes 5717 and 5719 devices can assume. This patch makes sure that the loopback test is safe, should those other modes be enabled in the future. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3b275663bbd8..3c9f95dd61e0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10647,7 +10647,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tnapi = &tp->napi[0]; rnapi = &tp->napi[0]; if (tp->irq_cnt > 1) { - rnapi = &tp->napi[1]; + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) + rnapi = &tp->napi[1]; if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) tnapi = &tp->napi[1]; } -- cgit v1.2.3 From 2c49a44df33e22e1f48bd8d51781e7f38d55d002 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:35 +0000 Subject: tg3: Prepare for larger rx ring sizes This patch adds two new variables to track the size of the standard and jumbo rx producer ring sizes. The code is then pivoted to these variables from preprocessor constants. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 119 +++++++++++++++++++++++++++++------------------------- drivers/net/tg3.h | 2 + 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3c9f95dd61e0..af59a293b5ba 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -101,9 +101,9 @@ * You can't change the ring sizes, but you can change where you place * them in the NIC onboard memory. */ -#define TG3_RX_RING_SIZE 512 +#define TG3_RX_STD_RING_SIZE(tp) 512 #define TG3_DEF_RX_RING_PENDING 200 -#define TG3_RX_JUMBO_RING_SIZE 256 +#define TG3_RX_JMB_RING_SIZE(tp) 256 #define TG3_DEF_RX_JUMBO_RING_PENDING 100 #define TG3_RSS_INDIR_TBL_SIZE 128 @@ -120,12 +120,12 @@ #define TG3_TX_RING_SIZE 512 #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) -#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RING_SIZE) -#define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_ext_rx_buffer_desc) * \ - TG3_RX_JUMBO_RING_SIZE) -#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RCB_RING_SIZE(tp)) +#define TG3_RX_STD_RING_BYTES(tp) \ + (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp)) +#define TG3_RX_JMB_RING_BYTES(tp) \ + (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp)) +#define TG3_RX_RCB_RING_BYTES(tp) \ + (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RCB_RING_SIZE(tp)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) @@ -143,11 +143,11 @@ #define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ) #define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ) -#define TG3_RX_STD_BUFF_RING_SIZE \ - (sizeof(struct ring_info) * TG3_RX_RING_SIZE) +#define TG3_RX_STD_BUFF_RING_SIZE(tp) \ + (sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp)) -#define TG3_RX_JMB_BUFF_RING_SIZE \ - (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE) +#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \ + (sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp)) /* Due to a hardware bug, the 5701 can only DMA to memory addresses * that are at least dword aligned when used in PCIX mode. The driver @@ -4445,14 +4445,14 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, src_map = NULL; switch (opaque_key) { case RXD_OPAQUE_RING_STD: - dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; desc = &tpr->rx_std[dest_idx]; map = &tpr->rx_std_buffers[dest_idx]; skb_size = tp->rx_pkt_map_sz; break; case RXD_OPAQUE_RING_JUMBO: - dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; desc = &tpr->rx_jmb[dest_idx].std; map = &tpr->rx_jmb_buffers[dest_idx]; skb_size = TG3_RX_JMB_MAP_SZ; @@ -4507,7 +4507,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, switch (opaque_key) { case RXD_OPAQUE_RING_STD: - dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; dest_desc = &dpr->rx_std[dest_idx]; dest_map = &dpr->rx_std_buffers[dest_idx]; src_desc = &spr->rx_std[src_idx]; @@ -4515,7 +4515,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, break; case RXD_OPAQUE_RING_JUMBO: - dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; dest_desc = &dpr->rx_jmb[dest_idx].std; dest_map = &dpr->rx_jmb_buffers[dest_idx]; src_desc = &spr->rx_jmb[src_idx].std; @@ -4715,7 +4715,8 @@ next_pkt: (*post_ptr)++; if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & + tp->rx_std_ring_mask; tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx); work_mask &= ~RXD_OPAQUE_RING_STD; @@ -4739,13 +4740,14 @@ next_pkt_nopost: /* Refill RX ring(s). */ if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) { if (work_mask & RXD_OPAQUE_RING_STD) { - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & + tp->rx_std_ring_mask; tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx); } if (work_mask & RXD_OPAQUE_RING_JUMBO) { - tpr->rx_jmb_prod_idx = jmb_prod_idx % - TG3_RX_JUMBO_RING_SIZE; + tpr->rx_jmb_prod_idx = jmb_prod_idx & + tp->rx_jmb_ring_mask; tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); } @@ -4756,8 +4758,8 @@ next_pkt_nopost: */ smp_wmb(); - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; - tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask; + tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask; if (tnapi != &tp->napi[1]) napi_schedule(&tp->napi[1].napi); @@ -4813,9 +4815,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, if (spr->rx_std_cons_idx < src_prod_idx) cpycnt = src_prod_idx - spr->rx_std_cons_idx; else - cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx; + cpycnt = tp->rx_std_ring_mask + 1 - + spr->rx_std_cons_idx; - cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx); + cpycnt = min(cpycnt, + tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx); si = spr->rx_std_cons_idx; di = dpr->rx_std_prod_idx; @@ -4849,10 +4853,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, dbd->addr_lo = sbd->addr_lo; } - spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) % - TG3_RX_RING_SIZE; - dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) % - TG3_RX_RING_SIZE; + spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) & + tp->rx_std_ring_mask; + dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) & + tp->rx_std_ring_mask; } while (1) { @@ -4869,10 +4873,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, if (spr->rx_jmb_cons_idx < src_prod_idx) cpycnt = src_prod_idx - spr->rx_jmb_cons_idx; else - cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx; + cpycnt = tp->rx_jmb_ring_mask + 1 - + spr->rx_jmb_cons_idx; cpycnt = min(cpycnt, - TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx); + tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx); si = spr->rx_jmb_cons_idx; di = dpr->rx_jmb_prod_idx; @@ -4906,10 +4911,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, dbd->addr_lo = sbd->addr_lo; } - spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) % - TG3_RX_JUMBO_RING_SIZE; - dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) % - TG3_RX_JUMBO_RING_SIZE; + spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) & + tp->rx_jmb_ring_mask; + dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) & + tp->rx_jmb_ring_mask; } return err; @@ -6059,14 +6064,14 @@ static void tg3_rx_prodring_free(struct tg3 *tp, if (tpr != &tp->napi[0].prodring) { for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; - i = (i + 1) % TG3_RX_RING_SIZE) + i = (i + 1) & tp->rx_std_ring_mask) tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], tp->rx_pkt_map_sz); if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { for (i = tpr->rx_jmb_cons_idx; i != tpr->rx_jmb_prod_idx; - i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) { + i = (i + 1) & tp->rx_jmb_ring_mask) { tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], TG3_RX_JMB_MAP_SZ); } @@ -6075,12 +6080,12 @@ static void tg3_rx_prodring_free(struct tg3 *tp, return; } - for (i = 0; i < TG3_RX_RING_SIZE; i++) + for (i = 0; i <= tp->rx_std_ring_mask; i++) tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], tp->rx_pkt_map_sz); if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) + for (i = 0; i <= tp->rx_jmb_ring_mask; i++) tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], TG3_RX_JMB_MAP_SZ); } @@ -6104,15 +6109,16 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, tpr->rx_jmb_prod_idx = 0; if (tpr != &tp->napi[0].prodring) { - memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE); + memset(&tpr->rx_std_buffers[0], 0, + TG3_RX_STD_BUFF_RING_SIZE(tp)); if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) memset(&tpr->rx_jmb_buffers[0], 0, - TG3_RX_JMB_BUFF_RING_SIZE); + TG3_RX_JMB_BUFF_RING_SIZE(tp)); goto done; } /* Zero out all descriptors. */ - memset(tpr->rx_std, 0, TG3_RX_RING_BYTES); + memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp)); rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ; if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) && @@ -6124,7 +6130,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, * stuff once. This works because the card does not * write into the rx buffer posting rings. */ - for (i = 0; i < TG3_RX_RING_SIZE; i++) { + for (i = 0; i <= tp->rx_std_ring_mask; i++) { struct tg3_rx_buffer_desc *rxd; rxd = &tpr->rx_std[i]; @@ -6151,12 +6157,12 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)) goto done; - memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES); + memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp)); if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)) goto done; - for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) { + for (i = 0; i <= tp->rx_jmb_ring_mask; i++) { struct tg3_rx_buffer_desc *rxd; rxd = &tpr->rx_jmb[i].std; @@ -6196,12 +6202,12 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, kfree(tpr->rx_jmb_buffers); tpr->rx_jmb_buffers = NULL; if (tpr->rx_std) { - pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), tpr->rx_std, tpr->rx_std_mapping); tpr->rx_std = NULL; } if (tpr->rx_jmb) { - pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp), tpr->rx_jmb, tpr->rx_jmb_mapping); tpr->rx_jmb = NULL; } @@ -6210,23 +6216,24 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, static int tg3_rx_prodring_init(struct tg3 *tp, struct tg3_rx_prodring_set *tpr) { - tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL); + tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE(tp), + GFP_KERNEL); if (!tpr->rx_std_buffers) return -ENOMEM; - tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES, + tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), &tpr->rx_std_mapping); if (!tpr->rx_std) goto err_out; if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE, + tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp), GFP_KERNEL); if (!tpr->rx_jmb_buffers) goto err_out; tpr->rx_jmb = pci_alloc_consistent(tp->pdev, - TG3_RX_JUMBO_RING_BYTES, + TG3_RX_JMB_RING_BYTES(tp), &tpr->rx_jmb_mapping); if (!tpr->rx_jmb) goto err_out; @@ -9854,10 +9861,10 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * { struct tg3 *tp = netdev_priv(dev); - ering->rx_max_pending = TG3_RX_RING_SIZE - 1; + ering->rx_max_pending = tp->rx_std_ring_mask; ering->rx_mini_max_pending = 0; if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) - ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; + ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask; else ering->rx_jumbo_max_pending = 0; @@ -9878,8 +9885,8 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e struct tg3 *tp = netdev_priv(dev); int i, irq_sync = 0, err = 0; - if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || - (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || + if ((ering->rx_pending > tp->rx_std_ring_mask) || + (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || (ering->tx_pending > TG3_TX_RING_SIZE - 1) || (ering->tx_pending <= MAX_SKB_FRAGS) || ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) && @@ -13597,7 +13604,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) #endif } - tp->rx_std_max_post = TG3_RX_RING_SIZE; + tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1; + tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1; + tp->rx_std_max_post = tp->rx_std_ring_mask + 1; /* Increment the rx prod index on the rx std ring by at most * 8 for these chips to workaround hw errata. diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 241e31487166..9763298c22c6 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2762,6 +2762,8 @@ struct tg3 { void (*write32_rx_mbox) (struct tg3 *, u32, u32); u32 rx_copy_thresh; + u32 rx_std_ring_mask; + u32 rx_jmb_ring_mask; u32 rx_pending; u32 rx_jumbo_pending; u32 rx_std_max_post; -- cgit v1.2.3 From 7cb32cf23c63a371cf89bfaad3f911a1609241cc Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:36 +0000 Subject: tg3: Add extend rx ring sizes for 5717 and 5719 This patch increases the rx ring sizes for those asic revs that support them. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- drivers/net/tg3.h | 3 +++ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index af59a293b5ba..d6de46b60b7e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -101,9 +101,15 @@ * You can't change the ring sizes, but you can change where you place * them in the NIC onboard memory. */ -#define TG3_RX_STD_RING_SIZE(tp) 512 +#define TG3_RX_STD_RING_SIZE(tp) \ + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ + RX_STD_MAX_SIZE_5717 : 512) #define TG3_DEF_RX_RING_PENDING 200 -#define TG3_RX_JMB_RING_SIZE(tp) 256 +#define TG3_RX_JMB_RING_SIZE(tp) \ + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ + 1024 : 256) #define TG3_DEF_RX_JUMBO_RING_PENDING 100 #define TG3_RSS_INDIR_TBL_SIZE 128 @@ -113,9 +119,6 @@ * hw multiply/modulo instructions. Another solution would be to * replace things like '% foo' with '& (foo - 1)'. */ -#define TG3_RX_RCB_RING_SIZE(tp) \ - (((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && \ - !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) ? 1024 : 512) #define TG3_TX_RING_SIZE 512 #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) @@ -125,7 +128,7 @@ #define TG3_RX_JMB_RING_BYTES(tp) \ (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp)) #define TG3_RX_RCB_RING_BYTES(tp) \ - (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RCB_RING_SIZE(tp)) + (sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) @@ -4724,7 +4727,7 @@ next_pkt: } next_pkt_nopost: sw_idx++; - sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1); + sw_idx &= tp->rx_ret_ring_mask; /* Refresh hw_idx to see if there is new work */ if (sw_idx == hw_idx) { @@ -7612,8 +7615,8 @@ static void tg3_rings_reset(struct tg3 *tp) if (tnapi->rx_rcb) { tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE(tp) << - BDINFO_FLAGS_MAXLEN_SHIFT), 0); + (tp->rx_ret_ring_mask + 1) << + BDINFO_FLAGS_MAXLEN_SHIFT, 0); rxrcb += TG3_BDINFO_SIZE; } @@ -7636,7 +7639,7 @@ static void tg3_rings_reset(struct tg3 *tp) } tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE(tp) << + ((tp->rx_ret_ring_mask + 1) << BDINFO_FLAGS_MAXLEN_SHIFT), 0); stblk += 8; @@ -7949,10 +7952,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) BDINFO_FLAGS_DISABLED); } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) - val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) | - (TG3_RX_STD_DMA_SZ << 2); - else + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + val = RX_STD_MAX_SIZE_5705; + else + val = RX_STD_MAX_SIZE_5717; + val <<= BDINFO_FLAGS_MAXLEN_SHIFT; + val |= (TG3_RX_STD_DMA_SZ << 2); + } else val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT; } else val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT; @@ -8235,7 +8242,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); - tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); + val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + val |= RCVDBDI_MODE_LRG_RING_SZ; + tw32(RCVDBDI_MODE, val); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); @@ -12851,6 +12862,18 @@ static void inline vlan_features_add(struct net_device *dev, unsigned long flags #endif } +static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) +{ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + return 4096; + else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) + return 1024; + else + return 512; +} + static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -13606,6 +13629,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1; tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1; + tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1; + tp->rx_std_max_post = tp->rx_std_ring_mask + 1; /* Increment the rx prod index on the rx std ring by at most diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 9763298c22c6..f6b709a3ca32 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -26,6 +26,7 @@ #define TG3_RX_INTERNAL_RING_SZ_5906 32 #define RX_STD_MAX_SIZE_5705 512 +#define RX_STD_MAX_SIZE_5717 2048 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ /* First 256 bytes are a mirror of PCI config space. */ @@ -972,6 +973,7 @@ #define RCVDBDI_MODE_JUMBOBD_NEEDED 0x00000004 #define RCVDBDI_MODE_FRM_TOO_BIG 0x00000008 #define RCVDBDI_MODE_INV_RING_SZ 0x00000010 +#define RCVDBDI_MODE_LRG_RING_SZ 0x00010000 #define RCVDBDI_STATUS 0x00002404 #define RCVDBDI_STATUS_JUMBOBD_NEEDED 0x00000004 #define RCVDBDI_STATUS_FRM_TOO_BIG 0x00000008 @@ -2764,6 +2766,7 @@ struct tg3 { u32 rx_copy_thresh; u32 rx_std_ring_mask; u32 rx_jmb_ring_mask; + u32 rx_ret_ring_mask; u32 rx_pending; u32 rx_jumbo_pending; u32 rx_std_max_post; -- cgit v1.2.3 From c7ebfdaca0b89fe9d846e93b249303313612d0e3 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 30 Sep 2010 10:34:37 +0000 Subject: tg3: Update version to 3.114 This patch updates the tg3 version to 3.114. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d6de46b60b7e..16e1a95c65f4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,10 +69,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 113 +#define TG3_MIN_NUM 114 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "August 2, 2010" +#define DRV_MODULE_RELDATE "September 30, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3 From b33ffa5cbf52ee751bb8068218ebb3c742c5a515 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:34:30 +0000 Subject: isdn/gigaset: bas_gigaset locking fix Unlock cs->lock before calling error_hangup() which is marked "cs->lock must not be held". Signed-off-by: Tilman Schmidt CC: stable Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 707d9c94cf9e..e143050e1b5c 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -1598,13 +1598,13 @@ static int gigaset_init_bchannel(struct bc_state *bcs) ret = starturbs(bcs); if (ret < 0) { + spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "could not start isochronous I/O for channel B%d: %s\n", bcs->channel + 1, ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); if (ret != -ENODEV) error_hangup(bcs); - spin_unlock_irqrestore(&cs->lock, flags); return ret; } @@ -1614,11 +1614,11 @@ static int gigaset_init_bchannel(struct bc_state *bcs) dev_err(cs->dev, "could not open channel B%d\n", bcs->channel + 1); stopurbs(bcs->hw.bas); - if (ret != -ENODEV) - error_hangup(bcs); } spin_unlock_irqrestore(&cs->lock, flags); + if (ret < 0 && ret != -ENODEV) + error_hangup(bcs); return ret; } -- cgit v1.2.3 From c8701a08d6a4efeae45d84d0aa87172f23b14e3c Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:34:40 +0000 Subject: isdn/gigaset: fix bas_gigaset AT read error handling Rework the handling of USB errors in AT response reads to fix a possible infinite retry loop and a memory leak, and silence a few overly verbose kernel messages. Signed-off-by: Tilman Schmidt CC: stable Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 83 +++++++++++++++----------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index e143050e1b5c..131976d880d0 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -438,23 +438,27 @@ static void cmd_in_timeout(unsigned long data) return; } - if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: timeout, retry %d\n", - ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - } else { + if (ucs->retry_cmd_in++ >= BAS_RETRY) { dev_err(cs->dev, "control read: timeout, giving up after %d tries\n", ucs->retry_cmd_in); + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + error_reset(cs); + return; + } + + gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d", + __func__, ucs->retry_cmd_in); + rc = atread_submit(cs, BAS_TIMEOUT); + if (rc < 0) { + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + if (rc != -ENODEV) + error_reset(cs); } - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - error_reset(cs); } /* read_ctrl_callback @@ -470,18 +474,11 @@ static void read_ctrl_callback(struct urb *urb) struct cardstate *cs = inbuf->cs; struct bas_cardstate *ucs = cs->hw.bas; int status = urb->status; - int have_data = 0; unsigned numbytes; int rc; update_basstate(ucs, 0, BS_ATRDPEND); wake_up(&ucs->waitqueue); - - if (!ucs->rcvbuf_size) { - dev_warn(cs->dev, "%s: no receive in progress\n", __func__); - return; - } - del_timer(&ucs->timer_cmd_in); switch (status) { @@ -495,19 +492,10 @@ static void read_ctrl_callback(struct urb *urb) numbytes = ucs->rcvbuf_size; } - /* copy received bytes to inbuf */ - have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); - - if (unlikely(numbytes < ucs->rcvbuf_size)) { - /* incomplete - resubmit for remaining bytes */ - ucs->rcvbuf_size -= numbytes; - ucs->retry_cmd_in = 0; - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - error_reset(cs); + /* copy received bytes to inbuf, notify event layer */ + if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) { + gig_dbg(DEBUG_INTR, "%s-->BH", __func__); + gigaset_schedule_event(cs); } break; @@ -516,37 +504,32 @@ static void read_ctrl_callback(struct urb *urb) case -EINPROGRESS: /* pending */ case -ENODEV: /* device removed */ case -ESHUTDOWN: /* device shut down */ - /* no action necessary */ + /* no further action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(status)); break; - default: /* severe trouble */ - dev_warn(cs->dev, "control read: %s\n", - get_usb_statmsg(status)); + default: /* other errors: retry */ if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: retry %d\n", - ucs->retry_cmd_in); + gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__, + get_usb_statmsg(status), ucs->retry_cmd_in); rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ + if (rc >= 0) + /* successfully resubmitted, skip freeing */ return; - } else { - dev_err(cs->dev, - "control read: giving up after %d tries\n", - ucs->retry_cmd_in); + if (rc == -ENODEV) + /* disconnect, no further action necessary */ + break; } + dev_err(cs->dev, "control read: %s, giving up after %d tries\n", + get_usb_statmsg(status), ucs->retry_cmd_in); error_reset(cs); } + /* read finished, free buffer */ kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; - if (have_data) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(cs); - } } /* atread_submit -- cgit v1.2.3 From f3d531b99fb30945b4a64d6e2e86e1e62605aca5 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:34:51 +0000 Subject: isdn/gigaset: correct bas_gigaset rx buffer handling In transparent data reception, avoid a NULL pointer dereference in case an skbuff cannot be allocated, remove an inappropriate call to the HDLC flush routine, and correct the accounting of received bytes for continued buffers. Signed-off-by: Tilman Schmidt CC: stable Signed-off-by: David S. Miller --- drivers/isdn/gigaset/isocdata.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 2dfd346fc889..f39ccdf87a17 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c @@ -842,13 +842,14 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (unlikely(bcs->ignore)) { bcs->ignore--; - hdlc_flush(bcs); return; } skb = bcs->rx_skb; - if (skb == NULL) + if (skb == NULL) { skb = gigaset_new_rx_skb(bcs); - bcs->hw.bas->goodbytes += skb->len; + if (skb == NULL) + return; + } dobytes = bcs->rx_bufsize - skb->len; while (count > 0) { dst = skb_put(skb, count < dobytes ? count : dobytes); @@ -860,6 +861,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (dobytes == 0) { dump_bytes(DEBUG_STREAM_DUMP, "rcv data", skb->data, skb->len); + bcs->hw.bas->goodbytes += skb->len; gigaset_skb_rcvd(bcs, skb); skb = gigaset_new_rx_skb(bcs); if (skb == NULL) -- cgit v1.2.3 From befba36ab942c44ba1d3761a7439324fff83638f Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:01 +0000 Subject: isdn/gigaset: drop obsolete debug option Remove the debug flag DEBUG_DRIVER and associated code. It doesn't serve any useful purpose anymore. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/common.c | 26 -------------------------- drivers/isdn/gigaset/gigaset.h | 3 +-- drivers/isdn/gigaset/i4l.c | 2 -- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 3ca561eccd9f..db621db67f61 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -1026,32 +1026,6 @@ struct cardstate *gigaset_get_cs_by_id(int id) return ret; } -void gigaset_debugdrivers(void) -{ - unsigned long flags; - static struct cardstate *cs; - struct gigaset_driver *drv; - unsigned i; - - spin_lock_irqsave(&driver_lock, flags); - list_for_each_entry(drv, &drivers, list) { - gig_dbg(DEBUG_DRIVER, "driver %p", drv); - spin_lock(&drv->lock); - for (i = 0; i < drv->minors; ++i) { - gig_dbg(DEBUG_DRIVER, " index %u", i); - cs = drv->cs + i; - gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); - gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags); - gig_dbg(DEBUG_DRIVER, " minor_index %u", - cs->minor_index); - gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); - gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); - } - spin_unlock(&drv->lock); - } - spin_unlock_irqrestore(&driver_lock, flags); -} - static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) { unsigned long flags; diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index a69512fb1195..6dd360734cfd 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -70,7 +70,6 @@ enum debuglevel { DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ DEBUG_LLDATA = 0x00100, /* sent/received LL data */ DEBUG_EVENT = 0x00200, /* event processing */ - DEBUG_DRIVER = 0x00400, /* driver structure */ DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */ DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ @@ -727,7 +726,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, /* Deallocate driver structure. */ void gigaset_freedriver(struct gigaset_driver *drv); -void gigaset_debugdrivers(void); + struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); struct cardstate *gigaset_get_cs_by_id(int id); void gigaset_blockdriver(struct gigaset_driver *drv); diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 34bca37d65b9..9bec8b969964 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -201,8 +201,6 @@ static int command_from_LL(isdn_ctrl *cntrl) int i; size_t l; - gigaset_debugdrivers(); - gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx", cntrl->driver, cntrl->command, cntrl->arg); -- cgit v1.2.3 From 1d5a9edcd5f1fe6483afca33294ed0ebab793ebf Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:11 +0000 Subject: isdn/gigaset: bas_gigaset timer cleanup Use setup_timer() and mod_timer() instead of direct assignment to timer structure members, simplify the argument of one timer routine, and make extra sure all timers are stopped during suspend. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 65 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 131976d880d0..e865c5dc0282 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -588,10 +588,7 @@ static int atread_submit(struct cardstate *cs, int timeout) if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; - ucs->timer_cmd_in.data = (unsigned long) cs; - ucs->timer_cmd_in.function = cmd_in_timeout; - add_timer(&ucs->timer_cmd_in); + mod_timer(&ucs->timer_cmd_in, jiffies + timeout * HZ / 10); } return 0; } @@ -1356,12 +1353,12 @@ error: /* req_timeout * timeout routine for control output request * argument: - * B channel control structure + * controller state structure */ static void req_timeout(unsigned long data) { - struct bc_state *bcs = (struct bc_state *) data; - struct bas_cardstate *ucs = bcs->cs->hw.bas; + struct cardstate *cs = (struct cardstate *) data; + struct bas_cardstate *ucs = cs->hw.bas; int pending; unsigned long flags; @@ -1378,38 +1375,44 @@ static void req_timeout(unsigned long data) break; case HD_OPEN_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout opening AT channel\n"); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout opening AT channel\n"); + error_reset(cs); break; - case HD_OPEN_B2CHANNEL: case HD_OPEN_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout opening channel %d\n", - bcs->channel + 1); - error_hangup(bcs); + dev_err(cs->dev, "timeout opening channel 1\n"); + error_hangup(&cs->bcs[0]); + break; + + case HD_OPEN_B2CHANNEL: + dev_err(cs->dev, "timeout opening channel 2\n"); + error_hangup(&cs->bcs[1]); break; case HD_CLOSE_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout closing AT channel\n"); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout closing AT channel\n"); + error_reset(cs); break; - case HD_CLOSE_B2CHANNEL: case HD_CLOSE_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout closing channel %d\n", - bcs->channel + 1); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout closing channel 1\n"); + error_reset(cs); + break; + + case HD_CLOSE_B2CHANNEL: + dev_err(cs->dev, "timeout closing channel 2\n"); + error_reset(cs); break; case HD_RESET_INTERRUPT_PIPE: /* error recovery escalation */ - dev_err(bcs->cs->dev, + dev_err(cs->dev, "reset interrupt pipe timeout, attempting USB reset\n"); - usb_queue_reset_device(bcs->cs->hw.bas->interface); + usb_queue_reset_device(ucs->interface); break; default: - dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", + dev_warn(cs->dev, "request 0x%02x timed out, clearing\n", pending); } @@ -1540,10 +1543,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; - ucs->timer_ctrl.data = (unsigned long) bcs; - ucs->timer_ctrl.function = req_timeout; - add_timer(&ucs->timer_ctrl); + mod_timer(&ucs->timer_ctrl, jiffies + timeout * HZ / 10); } spin_unlock_irqrestore(&ucs->lock, flags); @@ -1809,10 +1809,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", ATRDY_TIMEOUT); - ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; - ucs->timer_atrdy.data = (unsigned long) cs; - ucs->timer_atrdy.function = atrdy_timeout; - add_timer(&ucs->timer_atrdy); + mod_timer(&ucs->timer_atrdy, jiffies + ATRDY_TIMEOUT * HZ / 10); } return 0; } @@ -2114,9 +2111,9 @@ static int gigaset_initcshw(struct cardstate *cs) ucs->pending = 0; ucs->basstate = 0; - init_timer(&ucs->timer_ctrl); - init_timer(&ucs->timer_atrdy); - init_timer(&ucs->timer_cmd_in); + setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); init_waitqueue_head(&ucs->waitqueue); return 1; @@ -2387,6 +2384,8 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) usb_kill_urb(ucs->urb_ctrl); usb_kill_urb(ucs->urb_int_in); del_timer_sync(&ucs->timer_ctrl); + del_timer_sync(&ucs->timer_atrdy); + del_timer_sync(&ucs->timer_cmd_in); gig_dbg(DEBUG_SUSPEND, "suspend complete"); return 0; -- cgit v1.2.3 From 60798c68bebf6009df9da634e79ebdd8c8227238 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:21 +0000 Subject: isdn/gigaset: try USB reset for bas_gigaset error recovery In error_reset(), if sending HD_RESET_INTERRUPT_PIPE to the device fails, try performing an USB reset. Also correct an error in the leading comment. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index e865c5dc0282..7520bc6f3871 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -350,7 +350,7 @@ static inline void error_hangup(struct bc_state *bcs) * reset Gigaset device because of an unrecoverable error * This function may be called from any context, and takes care of * scheduling the necessary actions for execution outside of interrupt context. - * cs->lock must not be held. + * cs->hw.bas->lock must not be held. * argument: * controller state structure */ @@ -358,7 +358,9 @@ static inline void error_reset(struct cardstate *cs) { /* reset interrupt pipe to recover (ignore errors) */ update_basstate(cs->hw.bas, BS_RESETTING, 0); - req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT); + if (req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT)) + /* submission failed, escalate to USB port reset */ + usb_queue_reset_device(cs->hw.bas->interface); } /* check_pending -- cgit v1.2.3 From 4cb5e42f6132bf2d2851f8dd67bd8499979c7ebc Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:31 +0000 Subject: isdn/gigaset: unclog bas_gigaset AT response pipe Recover from a lost HD_RECEIVEATDATA_ACK message by sending a zero-length HD_READ_ATMESSAGE command when ev_layer sends "+++". Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 7520bc6f3871..540f6d0bb754 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -1896,6 +1896,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) * The next command will reopen the AT channel automatically. */ if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { + /* If an HD_RECEIVEATDATA_ACK message remains unhandled + * because of an error, the base never sends another one. + * The response channel is thus effectively blocked. + * Closing and reopening the AT channel does *not* clear + * this condition. + * As a stopgap measure, submit a zero-length AT read + * before closing the AT channel. This has the undocumented + * effect of triggering a new HD_RECEIVEATDATA_ACK message + * from the base if necessary. + * The subsequent AT channel close then discards any pending + * messages. + */ + spin_lock_irqsave(&cs->lock, flags); + if (!(cs->hw.bas->basstate & BS_ATRDPEND)) { + kfree(cs->hw.bas->rcvbuf); + cs->hw.bas->rcvbuf = NULL; + cs->hw.bas->rcvbuf_size = 0; + cs->hw.bas->retry_cmd_in = 0; + atread_submit(cs, 0); + } + spin_unlock_irqrestore(&cs->lock, flags); + rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); if (cb->wake_tasklet) tasklet_schedule(cb->wake_tasklet); -- cgit v1.2.3 From c9c0c3043452d30ab87135ba3753ce7855a3a8e7 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:42 +0000 Subject: isdn/gigaset: fix bas_gigaset interrupt read error handling Rework the handling of USB errors in interrupt input reads to clear halts correctly, delay URB resubmission after errors, limit retries, and improve error recovery. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 106 ++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 13 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 540f6d0bb754..71e3fdee4410 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -109,6 +109,9 @@ struct bas_cardstate { struct urb *urb_int_in; /* URB for interrupt pipe */ unsigned char *int_in_buf; + struct work_struct int_in_wq; /* for usb_clear_halt() */ + struct timer_list timer_int_in; /* int read retry delay */ + int retry_int_in; spinlock_t lock; /* locks all following */ int basstate; /* bitmap (BS_*) */ @@ -595,6 +598,62 @@ static int atread_submit(struct cardstate *cs, int timeout) return 0; } +/* int_in_work + * workqueue routine to clear halt on interrupt in endpoint + */ + +static void int_in_work(struct work_struct *work) +{ + struct bas_cardstate *ucs = + container_of(work, struct bas_cardstate, int_in_wq); + struct urb *urb = ucs->urb_int_in; + struct cardstate *cs = urb->context; + int rc; + + /* clear halt condition */ + rc = usb_clear_halt(ucs->udev, urb->pipe); + gig_dbg(DEBUG_USBREQ, "clear_halt: %s", get_usb_rcmsg(rc)); + if (rc == 0) + /* success, resubmit interrupt read URB */ + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc != 0 && rc != -ENODEV) { + dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); + rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); + if (rc == 0) { + rc = usb_reset_device(ucs->udev); + usb_unlock_device(ucs->udev); + } + } + ucs->retry_int_in = 0; +} + +/* int_in_resubmit + * timer routine for interrupt read delayed resubmit + * argument: + * controller state structure + */ +static void int_in_resubmit(unsigned long data) +{ + struct cardstate *cs = (struct cardstate *) data; + struct bas_cardstate *ucs = cs->hw.bas; + int rc; + + if (ucs->retry_int_in++ >= BAS_RETRY) { + dev_err(cs->dev, "interrupt read: giving up after %d tries\n", + ucs->retry_int_in); + usb_queue_reset_device(ucs->interface); + return; + } + + gig_dbg(DEBUG_USBREQ, "%s: retry %d", __func__, ucs->retry_int_in); + rc = usb_submit_urb(ucs->urb_int_in, GFP_ATOMIC); + if (rc != 0 && rc != -ENODEV) { + dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", + get_usb_rcmsg(rc)); + usb_queue_reset_device(ucs->interface); + } +} + /* read_int_callback * USB completion handler for interrupt pipe input * called by the USB subsystem in interrupt context @@ -615,19 +674,29 @@ static void read_int_callback(struct urb *urb) switch (status) { case 0: /* success */ + ucs->retry_int_in = 0; break; + case -EPIPE: /* endpoint stalled */ + schedule_work(&ucs->int_in_wq); + /* fall through */ case -ENOENT: /* cancelled */ case -ECONNRESET: /* cancelled (async) */ case -EINPROGRESS: /* pending */ - /* ignore silently */ + case -ENODEV: /* device removed */ + case -ESHUTDOWN: /* device shut down */ + /* no further action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(status)); return; - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); + case -EPROTO: /* protocol error or unplug */ + case -EILSEQ: + case -ETIME: + /* resubmit after delay */ + gig_dbg(DEBUG_USBREQ, "%s: %s", + __func__, get_usb_statmsg(status)); + mod_timer(&ucs->timer_int_in, jiffies + HZ / 10); return; - default: /* severe trouble */ + default: /* other errors: just resubmit */ dev_warn(cs->dev, "interrupt read: %s\n", get_usb_statmsg(status)); goto resubmit; @@ -705,6 +774,13 @@ static void read_int_callback(struct urb *urb) break; } spin_lock_irqsave(&cs->lock, flags); + if (ucs->basstate & BS_ATRDPEND) { + spin_unlock_irqrestore(&cs->lock, flags); + dev_warn(cs->dev, + "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n", + l, ucs->rcvbuf_size); + break; + } if (ucs->rcvbuf_size) { /* throw away previous buffer - we have no queue */ dev_err(cs->dev, @@ -717,7 +793,6 @@ static void read_int_callback(struct urb *urb) if (ucs->rcvbuf == NULL) { spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "out of memory receiving AT data\n"); - error_reset(cs); break; } ucs->rcvbuf_size = l; @@ -727,13 +802,10 @@ static void read_int_callback(struct urb *urb) kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; - if (rc != -ENODEV) { - spin_unlock_irqrestore(&cs->lock, flags); - error_reset(cs); - break; - } } spin_unlock_irqrestore(&cs->lock, flags); + if (rc < 0 && rc != -ENODEV) + error_reset(cs); break; case HD_RESET_INTERRUPT_PIPE_ACK: @@ -2138,7 +2210,9 @@ static int gigaset_initcshw(struct cardstate *cs) setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs); init_waitqueue_head(&ucs->waitqueue); + INIT_WORK(&ucs->int_in_wq, int_in_work); return 1; } @@ -2286,6 +2360,7 @@ static int gigaset_probe(struct usb_interface *interface, get_usb_rcmsg(rc)); goto error; } + ucs->retry_int_in = 0; /* tell the device that the driver is ready */ rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0); @@ -2338,10 +2413,12 @@ static void gigaset_disconnect(struct usb_interface *interface) /* stop driver (common part) */ gigaset_stop(cs); - /* stop timers and URBs, free ressources */ + /* stop delayed work and URBs, free ressources */ del_timer_sync(&ucs->timer_ctrl); del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_cmd_in); + del_timer_sync(&ucs->timer_int_in); + cancel_work_sync(&ucs->int_in_wq); freeurbs(cs); usb_set_intfdata(interface, NULL); kfree(ucs->rcvbuf); @@ -2404,12 +2481,14 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) /* in case of timeout, proceed anyway */ } - /* kill all URBs and timers that might still be pending */ + /* kill all URBs and delayed work that might still be pending */ usb_kill_urb(ucs->urb_ctrl); usb_kill_urb(ucs->urb_int_in); del_timer_sync(&ucs->timer_ctrl); del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_cmd_in); + del_timer_sync(&ucs->timer_int_in); + cancel_work_sync(&ucs->int_in_wq); gig_dbg(DEBUG_SUSPEND, "suspend complete"); return 0; @@ -2431,6 +2510,7 @@ static int gigaset_resume(struct usb_interface *intf) get_usb_rcmsg(rc)); return rc; } + ucs->retry_int_in = 0; /* clear suspend flag to reallow activity */ update_basstate(ucs, 0, BS_SUSPEND); -- cgit v1.2.3 From bb7196d2bf30e4cb06fe5fed046c9084465e854c Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Thu, 30 Sep 2010 13:35:52 +0000 Subject: isdn/gigaset: improve bas_gigaset USB error reporting Rephrase some USB error messages to make them clearer and more consistent. Downgrade some warning messages that may occur during normal operation to debug messages. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 112 ++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 71e3fdee4410..178942a2ee61 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -172,7 +172,7 @@ static char *get_usb_rcmsg(int rc) case -EAGAIN: return "start frame too early or too much scheduled"; case -EFBIG: - return "too many isochronous frames requested"; + return "too many isoc frames requested"; case -EPIPE: return "endpoint stalled"; case -EMSGSIZE: @@ -203,13 +203,13 @@ static char *get_usb_statmsg(int status) case -ENOENT: return "unlinked (sync)"; case -EINPROGRESS: - return "pending"; + return "URB still pending"; case -EPROTO: - return "bit stuffing error, timeout, or unknown USB error"; + return "bitstuff error, timeout, or unknown USB error"; case -EILSEQ: return "CRC mismatch, timeout, or unknown USB error"; case -ETIME: - return "timed out"; + return "USB response timeout"; case -EPIPE: return "endpoint stalled"; case -ECOMM: @@ -217,15 +217,15 @@ static char *get_usb_statmsg(int status) case -ENOSR: return "OUT buffer underrun"; case -EOVERFLOW: - return "too much data"; + return "endpoint babble"; case -EREMOTEIO: - return "short packet detected"; + return "short packet"; case -ENODEV: return "device removed"; case -EXDEV: - return "partial isochronous transfer"; + return "partial isoc transfer"; case -EINVAL: - return "invalid argument"; + return "ISO madness"; case -ECONNRESET: return "unlinked (async)"; case -ESHUTDOWN: @@ -872,6 +872,7 @@ static void read_iso_callback(struct urb *urb) tasklet_hi_schedule(&ubc->rcvd_tasklet); } else { /* tasklet still busy, drop data and resubmit URB */ + gig_dbg(DEBUG_ISO, "%s: overrun", __func__); ubc->loststatus = status; for (i = 0; i < BAS_NUMFRAMES; i++) { ubc->isoinlost += urb->iso_frame_desc[i].actual_length; @@ -887,13 +888,11 @@ static void read_iso_callback(struct urb *urb) urb->dev = bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = BAS_NUMFRAMES; - gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", - __func__); rc = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(bcs->cs->dev, - "could not resubmit isochronous read " - "URB: %s\n", get_usb_rcmsg(rc)); + "could not resubmit isoc read URB: %s\n", + get_usb_rcmsg(rc)); dump_urb(DEBUG_ISO, "isoc read", urb); error_hangup(bcs); } @@ -1135,7 +1134,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); else dev_err(ucx->bcs->cs->dev, - "could not submit isochronous write URB: %s\n", + "could not submit isoc write URB: %s\n", get_usb_rcmsg(rc)); return rc; } @@ -1180,7 +1179,7 @@ static void write_iso_tasklet(unsigned long data) ubc->isooutovfl = NULL; spin_unlock_irqrestore(&ubc->isooutlock, flags); if (ovfl) { - dev_err(cs->dev, "isochronous write buffer underrun\n"); + dev_err(cs->dev, "isoc write underrun\n"); error_hangup(bcs); break; } @@ -1205,7 +1204,7 @@ static void write_iso_tasklet(unsigned long data) if (next) { /* couldn't put it back */ dev_err(cs->dev, - "losing isochronous write URB\n"); + "losing isoc write URB\n"); error_hangup(bcs); } } @@ -1232,10 +1231,10 @@ static void write_iso_tasklet(unsigned long data) if (ifd->status || ifd->actual_length != ifd->length) { dev_warn(cs->dev, - "isochronous write: frame %d: %s, " - "only %d of %d bytes sent\n", - i, get_usb_statmsg(ifd->status), - ifd->actual_length, ifd->length); + "isoc write: frame %d[%d/%d]: %s\n", + i, ifd->actual_length, + ifd->length, + get_usb_statmsg(ifd->status)); offset = (ifd->offset + ifd->actual_length) % BAS_OUTBUFSIZE; @@ -1244,11 +1243,11 @@ static void write_iso_tasklet(unsigned long data) } break; case -EPIPE: /* stall - probably underrun */ - dev_err(cs->dev, "isochronous write stalled\n"); + dev_err(cs->dev, "isoc write: stalled\n"); error_hangup(bcs); break; - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous write: %s\n", + default: /* other errors */ + dev_warn(cs->dev, "isoc write: %s\n", get_usb_statmsg(status)); } @@ -1304,6 +1303,7 @@ static void read_iso_tasklet(unsigned long data) struct cardstate *cs = bcs->cs; struct urb *urb; int status; + struct usb_iso_packet_descriptor *ifd; char *rcvbuf; unsigned long flags; int totleft, numbytes, offset, frame, rc; @@ -1321,8 +1321,7 @@ static void read_iso_tasklet(unsigned long data) ubc->isoindone = NULL; if (unlikely(ubc->loststatus != -EINPROGRESS)) { dev_warn(cs->dev, - "isochronous read overrun, " - "dropped URB with status: %s, %d bytes lost\n", + "isoc read overrun, URB dropped (status: %s, %d bytes)\n", get_usb_statmsg(ubc->loststatus), ubc->isoinlost); ubc->loststatus = -EINPROGRESS; @@ -1352,11 +1351,11 @@ static void read_iso_tasklet(unsigned long data) __func__, get_usb_statmsg(status)); continue; /* -> skip */ case -EPIPE: - dev_err(cs->dev, "isochronous read stalled\n"); + dev_err(cs->dev, "isoc read: stalled\n"); error_hangup(bcs); continue; /* -> skip */ - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous read: %s\n", + default: /* other error */ + dev_warn(cs->dev, "isoc read: %s\n", get_usb_statmsg(status)); goto error; } @@ -1364,40 +1363,52 @@ static void read_iso_tasklet(unsigned long data) rcvbuf = urb->transfer_buffer; totleft = urb->actual_length; for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { - numbytes = urb->iso_frame_desc[frame].actual_length; - if (unlikely(urb->iso_frame_desc[frame].status)) + ifd = &urb->iso_frame_desc[frame]; + numbytes = ifd->actual_length; + switch (ifd->status) { + case 0: /* success */ + break; + case -EPROTO: /* protocol error or unplug */ + case -EILSEQ: + case -ETIME: + /* probably just disconnected, ignore */ + gig_dbg(DEBUG_ISO, + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + get_usb_statmsg(ifd->status)); + break; + default: /* other error */ + /* report, assume transferred bytes are ok */ dev_warn(cs->dev, - "isochronous read: frame %d[%d]: %s\n", + "isoc read: frame %d[%d]: %s\n", frame, numbytes, - get_usb_statmsg( - urb->iso_frame_desc[frame].status)); + get_usb_statmsg(ifd->status)); + } if (unlikely(numbytes > BAS_MAXFRAME)) dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > BAS_MAXFRAME\n", - frame, numbytes); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds max frame size"); if (unlikely(numbytes > totleft)) { dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > totleft (%d)\n", - frame, numbytes, totleft); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds total transfer length"); numbytes = totleft; } - offset = urb->iso_frame_desc[frame].offset; + offset = ifd->offset; if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { dev_warn(cs->dev, - "isochronous read: frame %d: " - "offset (%d) + numbytes (%d) " - "> BAS_INBUFSIZE\n", - frame, offset, numbytes); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds end of buffer"); numbytes = BAS_INBUFSIZE - offset; } gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); totleft -= numbytes; } if (unlikely(totleft > 0)) - dev_warn(cs->dev, - "isochronous read: %d data bytes missing\n", + dev_warn(cs->dev, "isoc read: %d data bytes missing\n", totleft); error: @@ -1413,9 +1424,9 @@ error: rc = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(cs->dev, - "could not resubmit isochronous read URB: %s\n", + "could not resubmit isoc read URB: %s\n", get_usb_rcmsg(rc)); - dump_urb(DEBUG_ISO, "resubmit iso read", urb); + dump_urb(DEBUG_ISO, "resubmit isoc read", urb); error_hangup(bcs); } } @@ -1647,8 +1658,7 @@ static int gigaset_init_bchannel(struct bc_state *bcs) if (cs->hw.bas->basstate & BS_SUSPEND) { dev_notice(cs->dev, - "not starting isochronous I/O, " - "suspend in progress\n"); + "not starting isoc I/O, suspend in progress\n"); spin_unlock_irqrestore(&cs->lock, flags); return -EHOSTUNREACH; } @@ -1657,7 +1667,7 @@ static int gigaset_init_bchannel(struct bc_state *bcs) if (ret < 0) { spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, - "could not start isochronous I/O for channel B%d: %s\n", + "could not start isoc I/O for channel B%d: %s\n", bcs->channel + 1, ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); if (ret != -ENODEV) @@ -2086,7 +2096,7 @@ static int gigaset_freebcshw(struct bc_state *bcs) /* kill URBs and tasklets before freeing - better safe than sorry */ ubc->running = 0; - gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); + gig_dbg(DEBUG_INIT, "%s: killing isoc URBs", __func__); for (i = 0; i < BAS_OUTURBS; ++i) { usb_kill_urb(ubc->isoouturbs[i].urb); usb_free_urb(ubc->isoouturbs[i].urb); -- cgit v1.2.3 From 367e5e376922dcf52f92e1db436010fb828d3bfa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 30 Sep 2010 05:36:29 +0000 Subject: neigh: reorder fields in struct neighbour On 64bit arches, there are two 32bit holes that we can remove. sizeof(struct neighbour) shrinks from 0xf8 to 0xf0 bytes Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 242879b6c4df..7d08fd1062f0 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -94,7 +94,7 @@ struct neighbour { struct neighbour *next; struct neigh_table *tbl; struct neigh_parms *parms; - struct net_device *dev; + struct net_device *dev; unsigned long used; unsigned long confirmed; unsigned long updated; @@ -102,11 +102,11 @@ struct neighbour { __u8 nud_state; __u8 type; __u8 dead; + atomic_t refcnt; atomic_t probes; rwlock_t lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; - atomic_t refcnt; int (*output)(struct sk_buff *skb); struct sk_buff_head arp_queue; struct timer_list timer; @@ -163,7 +163,7 @@ struct neigh_table { atomic_t entries; rwlock_t lock; unsigned long last_rand; - struct kmem_cache *kmem_cachep; + struct kmem_cache *kmem_cachep; struct neigh_statistics __percpu *stats; struct neighbour **hash_buckets; unsigned int hash_mask; -- cgit v1.2.3 From bf746e62afc83be1baccc0cc9e128a9805ecd5fd Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 30 Sep 2010 13:35:34 +0000 Subject: enic: Remove dead code Removed code that is unused Signed-off-by: Stephen Hemminger Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 3 +- drivers/net/enic/enic_res.c | 17 ------- drivers/net/enic/enic_res.h | 2 - drivers/net/enic/vnic_dev.c | 104 ------------------------------------------- drivers/net/enic/vnic_dev.h | 12 ----- drivers/net/enic/vnic_intr.c | 5 --- drivers/net/enic/vnic_rss.h | 45 ------------------- 7 files changed, 1 insertion(+), 187 deletions(-) delete mode 100644 drivers/net/enic/vnic_rss.h diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 75869ed7226f..ae623206f180 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -28,11 +28,10 @@ #include "vnic_intr.h" #include "vnic_stats.h" #include "vnic_nic.h" -#include "vnic_rss.h" #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.2" +#define DRV_VERSION "1.4.1.2a" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 29ede8a17a2c..19a276cf7681 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -35,7 +35,6 @@ #include "vnic_intr.h" #include "vnic_stats.h" #include "vnic_nic.h" -#include "vnic_rss.h" #include "enic_res.h" #include "enic.h" @@ -149,22 +148,6 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait); } -int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len) -{ - u64 a0 = (u64)key_pa, a1 = len; - int wait = 1000; - - return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait); -} - -int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len) -{ - u64 a0 = (u64)cpu_pa, a1 = len; - int wait = 1000; - - return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait); -} - void enic_free_vnic_resources(struct enic *enic) { unsigned int i; diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 83bd172c356c..3c59f541cb5d 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -137,8 +137,6 @@ int enic_del_vlan(struct enic *enic, u16 vlanid); int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, u8 ig_vlan_strip_en); -int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len); -int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len); void enic_get_res_counts(struct enic *enic); void enic_init_vnic_resources(struct enic *enic); int enic_alloc_vnic_resources(struct enic *); diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 08d5d42da260..f99ddeed1c4f 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -186,21 +186,6 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, } } -dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, - enum vnic_res_type type, unsigned int index) -{ - switch (type) { - case RES_TYPE_WQ: - case RES_TYPE_RQ: - case RES_TYPE_CQ: - case RES_TYPE_INTR_CTRL: - return vdev->res[type].bus_addr + - index * VNIC_RES_STRIDE; - default: - return vdev->res[type].bus_addr; - } -} - unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size) { @@ -384,18 +369,6 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, return err; } -void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf) -{ - vdev->proxy = PROXY_BY_BDF; - vdev->proxy_index = bdf; -} - -void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) -{ - vdev->proxy = PROXY_NONE; - vdev->proxy_index = 0; -} - int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait) { @@ -488,13 +461,6 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, return err; } -int vnic_dev_stats_clear(struct vnic_dev *vdev) -{ - u64 a0 = 0, a1 = 0; - int wait = 1000; - return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait); -} - int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) { u64 a0, a1; @@ -528,19 +494,6 @@ int vnic_dev_enable(struct vnic_dev *vdev) return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); } -int vnic_dev_enable_wait(struct vnic_dev *vdev) -{ - u64 a0 = 0, a1 = 0; - int wait = 1000; - int err; - - err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) - return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); - - return err; -} - int vnic_dev_disable(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; @@ -680,26 +633,6 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, return err; } -int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, - int multicast, int broadcast, int promisc, int allmulti) -{ - u64 a0, a1 = 0; - int wait = 1000; - int err; - - a0 = (directed ? CMD_PFILTER_DIRECTED : 0) | - (multicast ? CMD_PFILTER_MULTICAST : 0) | - (broadcast ? CMD_PFILTER_BROADCAST : 0) | - (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | - (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); - - err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); - if (err) - pr_err("Can't set packet filter\n"); - - return err; -} - int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) { u64 a0 = 0, a1 = 0; @@ -748,19 +681,6 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, return err; } -int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) -{ - u64 a0 = intr, a1 = 0; - int wait = 1000; - int err; - - err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait); - if (err) - pr_err("Failed to raise INTR[%d], err %d\n", intr, err); - - return err; -} - int vnic_dev_notify_setcmd(struct vnic_dev *vdev, void *notify_addr, dma_addr_t notify_pa, u16 intr) { @@ -954,30 +874,6 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev) return vdev->notify_copy.mtu; } -u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.link_down_cnt; -} - -u32 vnic_dev_notify_status(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.status; -} - -u32 vnic_dev_uif(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.uif; -} - void vnic_dev_set_intr_mode(struct vnic_dev *vdev, enum vnic_dev_intr_mode intr_mode) { diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 3a61873138b6..008304b966a4 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -84,8 +84,6 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, enum vnic_res_type type); void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, unsigned int index); -dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, - enum vnic_res_type type, unsigned int index); unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size); void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring); @@ -95,25 +93,19 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring); int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait); -void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf); -void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev); int vnic_dev_fw_info(struct vnic_dev *vdev, struct vnic_devcmd_fw_info **fw_info); int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver); int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, void *value); -int vnic_dev_stats_clear(struct vnic_dev *vdev); int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); int vnic_dev_hang_notify(struct vnic_dev *vdev); int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, int broadcast, int promisc, int allmulti); -int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, - int multicast, int broadcast, int promisc, int allmulti); int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); -int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr); int vnic_dev_notify_setcmd(struct vnic_dev *vdev, void *notify_addr, dma_addr_t notify_pa, u16 intr); int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); @@ -123,12 +115,8 @@ int vnic_dev_link_status(struct vnic_dev *vdev); u32 vnic_dev_port_speed(struct vnic_dev *vdev); u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); u32 vnic_dev_mtu(struct vnic_dev *vdev); -u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); -u32 vnic_dev_notify_status(struct vnic_dev *vdev); -u32 vnic_dev_uif(struct vnic_dev *vdev); int vnic_dev_close(struct vnic_dev *vdev); int vnic_dev_enable(struct vnic_dev *vdev); -int vnic_dev_enable_wait(struct vnic_dev *vdev); int vnic_dev_disable(struct vnic_dev *vdev); int vnic_dev_open(struct vnic_dev *vdev, int arg); int vnic_dev_open_done(struct vnic_dev *vdev, int *done); diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c index 52ab61af2750..3873771d75cc 100644 --- a/drivers/net/enic/vnic_intr.c +++ b/drivers/net/enic/vnic_intr.c @@ -65,8 +65,3 @@ void vnic_intr_clean(struct vnic_intr *intr) { iowrite32(0, &intr->ctrl->int_credits); } - -void vnic_intr_raise(struct vnic_intr *intr) -{ - vnic_dev_raise_intr(intr->vdev, (u16)intr->index); -} diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h deleted file mode 100644 index f62d18719629..000000000000 --- a/drivers/net/enic/vnic_rss.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. - * Copyright 2007 Nuova Systems, Inc. All rights reserved. - * - * This program is free software; you may redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _VNIC_RSS_H_ -#define _VNIC_RSS_H_ - -/* RSS key array */ -union vnic_rss_key { - struct { - u8 b[10]; - u8 b_pad[6]; - } key[4]; - u64 raw[8]; -}; - -/* RSS cpu array */ -union vnic_rss_cpu { - struct { - u8 b[4] ; - u8 b_pad[4]; - } cpu[32]; - u64 raw[32]; -}; - -void vnic_set_rss_key(union vnic_rss_key *rss_key, u8 *key); -void vnic_set_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu); -void vnic_get_rss_key(union vnic_rss_key *rss_key, u8 *key); -void vnic_get_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu); - -#endif /* _VNIC_RSS_H_ */ -- cgit v1.2.3 From 2fdba3881154ee91927af7d7436d54eb05dcc3bf Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 30 Sep 2010 13:35:45 +0000 Subject: enic: Make local functions static Make functions used locally in a file as static Signed-off-by: Stephen Hemminger Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 6 +++--- drivers/net/enic/vnic_dev.c | 10 +++++----- drivers/net/enic/vnic_dev.h | 7 ------- drivers/net/enic/vnic_rq.c | 2 +- drivers/net/enic/vnic_rq.h | 4 ---- drivers/net/enic/vnic_wq.c | 2 +- drivers/net/enic/vnic_wq.h | 4 ---- 7 files changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 711077a2e345..a1f92f193976 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1972,7 +1972,7 @@ static int enic_dev_hang_notify(struct enic *enic) return err; } -int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) +static int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) { int err; @@ -2147,14 +2147,14 @@ static const struct net_device_ops enic_netdev_ops = { #endif }; -void enic_dev_deinit(struct enic *enic) +static void enic_dev_deinit(struct enic *enic) { netif_napi_del(&enic->napi); enic_free_vnic_resources(enic); enic_clear_intr_mode(enic); } -int enic_dev_init(struct enic *enic) +static int enic_dev_init(struct enic *enic) { struct device *dev = enic_get_dev(enic); struct net_device *netdev = enic->netdev; diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index f99ddeed1c4f..11dc8f73e4be 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -186,7 +186,7 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, } } -unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, +static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size) { /* The base address of the desc rings must be 512 byte aligned. @@ -525,14 +525,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done) return 0; } -int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) +static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) { u64 a0 = (u32)arg, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait); } -int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) +static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) { u64 a0 = 0, a1 = 0; int wait = 1000; @@ -681,7 +681,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, return err; } -int vnic_dev_notify_setcmd(struct vnic_dev *vdev, +static int vnic_dev_notify_setcmd(struct vnic_dev *vdev, void *notify_addr, dma_addr_t notify_pa, u16 intr) { u64 a0, a1; @@ -720,7 +720,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); } -int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) +static int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) { u64 a0, a1; int wait = 1000; diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 008304b966a4..3f0014312080 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -84,8 +84,6 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, enum vnic_res_type type); void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, unsigned int index); -unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, - unsigned int desc_count, unsigned int desc_size); void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring); int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size); @@ -106,10 +104,7 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); -int vnic_dev_notify_setcmd(struct vnic_dev *vdev, - void *notify_addr, dma_addr_t notify_pa, u16 intr); int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); -int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); int vnic_dev_notify_unset(struct vnic_dev *vdev); int vnic_dev_link_status(struct vnic_dev *vdev); u32 vnic_dev_port_speed(struct vnic_dev *vdev); @@ -124,8 +119,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg); int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err); int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len); int vnic_dev_deinit(struct vnic_dev *vdev); -int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); -int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg); int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done); void vnic_dev_set_intr_mode(struct vnic_dev *vdev, diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c index b236d7cbc137..34105e0951a5 100644 --- a/drivers/net/enic/vnic_rq.c +++ b/drivers/net/enic/vnic_rq.c @@ -115,7 +115,7 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, return 0; } -void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, +static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, unsigned int fetch_index, unsigned int posted_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset) diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h index 4b6f0212c8a2..37f08de2454a 100644 --- a/drivers/net/enic/vnic_rq.h +++ b/drivers/net/enic/vnic_rq.h @@ -202,10 +202,6 @@ static inline int vnic_rq_fill(struct vnic_rq *rq, void vnic_rq_free(struct vnic_rq *rq); int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, unsigned int desc_count, unsigned int desc_size); -void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, - unsigned int fetch_index, unsigned int posted_index, - unsigned int error_interrupt_enable, - unsigned int error_interrupt_offset); void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset); diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c index 4b2a6c6a569b..df61bd932ea6 100644 --- a/drivers/net/enic/vnic_wq.c +++ b/drivers/net/enic/vnic_wq.c @@ -115,7 +115,7 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, return 0; } -void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, +static void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, unsigned int fetch_index, unsigned int posted_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset) diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h index 94ac4621acc5..7dd937ac11c2 100644 --- a/drivers/net/enic/vnic_wq.h +++ b/drivers/net/enic/vnic_wq.h @@ -153,10 +153,6 @@ static inline void vnic_wq_service(struct vnic_wq *wq, void vnic_wq_free(struct vnic_wq *wq); int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, unsigned int desc_count, unsigned int desc_size); -void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, - unsigned int fetch_index, unsigned int posted_index, - unsigned int error_interrupt_enable, - unsigned int error_interrupt_offset); void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset); -- cgit v1.2.3 From 94d57c4cfaa43e29ca5fa5ff874048cfc67276f5 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 30 Sep 2010 13:36:05 +0000 Subject: enic: Update MAINTAINERS Update MAINTAINERS list Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3168d0cbd358..9ddb5ac923cd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1567,9 +1567,9 @@ S: Supported F: scripts/checkpatch.pl CISCO VIC ETHERNET NIC DRIVER -M: Scott Feldman M: Vasanthy Kolluri M: Roopa Prabhu +M: David Wang S: Supported F: drivers/net/enic/ -- cgit v1.2.3 From ddcb4541e917780ef7ccc68dd8df18ca0bc055d0 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 1 Oct 2010 13:58:00 +0000 Subject: gre: protocol table can be static This table is only used in gre.c Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/gre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index b546736da2e1..caea6885fdbd 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c @@ -22,7 +22,7 @@ #include -const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; +static const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; static DEFINE_SPINLOCK(gre_proto_lock); int gre_add_protocol(const struct gre_protocol *proto, u8 version) -- cgit v1.2.3 From 55747a0a73ea74a25fcebb0731e8d3f13fe8c09d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Oct 2010 16:14:55 +0000 Subject: ipmr: __pim_rcv() is called under rcu_read_lock No need to get a reference on reg_dev and release it, we are in a rcu_read_lock() protected section. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipmr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 10b24c02deb0..1a92ebd85196 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1805,6 +1805,7 @@ dont_forward: } #ifdef CONFIG_IP_PIMSM +/* called with rcu_read_lock() */ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, unsigned int pimlen) { @@ -1826,26 +1827,23 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, read_lock(&mrt_lock); if (mrt->mroute_reg_vif_num >= 0) reg_dev = mrt->vif_table[mrt->mroute_reg_vif_num].dev; - if (reg_dev) - dev_hold(reg_dev); read_unlock(&mrt_lock); if (reg_dev == NULL) return 1; skb->mac_header = skb->network_header; - skb_pull(skb, (u8*)encap - skb->data); + skb_pull(skb, (u8 *)encap - skb->data); skb_reset_network_header(skb); skb->protocol = htons(ETH_P_IP); - skb->ip_summed = 0; + skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_HOST; skb_tunnel_rx(skb, reg_dev); netif_rx(skb); - dev_put(reg_dev); - return 0; + return NET_RX_SUCCESS; } #endif -- cgit v1.2.3 From 4c9687098f245601e9d94178715ee03afbcc6f80 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Oct 2010 16:15:01 +0000 Subject: ipmr: RCU conversion of mroute_sk Use RCU and RTNL to protect (struct mr_table)->mroute_sk Readers use RCU, writers use RTNL. ip_ra_control() already use an RCU grace period before ip_ra_destroy_rcu(), so we dont need synchronize_rcu() in mrtsock_destruct() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipmr.c | 91 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 1a92ebd85196..e2db2ea616ff 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -75,7 +75,7 @@ struct mr_table { struct net *net; #endif u32 id; - struct sock *mroute_sk; + struct sock __rcu *mroute_sk; struct timer_list ipmr_expire_timer; struct list_head mfc_unres_queue; struct list_head mfc_cache_array[MFC_LINES]; @@ -867,6 +867,7 @@ static int ipmr_cache_report(struct mr_table *mrt, const int ihl = ip_hdrlen(pkt); struct igmphdr *igmp; struct igmpmsg *msg; + struct sock *mroute_sk; int ret; #ifdef CONFIG_IP_PIMSM @@ -925,7 +926,10 @@ static int ipmr_cache_report(struct mr_table *mrt, skb->transport_header = skb->network_header; } - if (mrt->mroute_sk == NULL) { + rcu_read_lock(); + mroute_sk = rcu_dereference(mrt->mroute_sk); + if (mroute_sk == NULL) { + rcu_read_unlock(); kfree_skb(skb); return -EINVAL; } @@ -933,7 +937,8 @@ static int ipmr_cache_report(struct mr_table *mrt, /* * Deliver to mrouted */ - ret = sock_queue_rcv_skb(mrt->mroute_sk, skb); + ret = sock_queue_rcv_skb(mroute_sk, skb); + rcu_read_unlock(); if (ret < 0) { if (net_ratelimit()) printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n"); @@ -1164,6 +1169,9 @@ static void mroute_clean_tables(struct mr_table *mrt) } } +/* called from ip_ra_control(), before an RCU grace period, + * we dont need to call synchronize_rcu() here + */ static void mrtsock_destruct(struct sock *sk) { struct net *net = sock_net(sk); @@ -1171,13 +1179,9 @@ static void mrtsock_destruct(struct sock *sk) rtnl_lock(); ipmr_for_each_table(mrt, net) { - if (sk == mrt->mroute_sk) { + if (sk == rtnl_dereference(mrt->mroute_sk)) { IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; - - write_lock_bh(&mrt_lock); - mrt->mroute_sk = NULL; - write_unlock_bh(&mrt_lock); - + rcu_assign_pointer(mrt->mroute_sk, NULL); mroute_clean_tables(mrt); } } @@ -1204,7 +1208,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENOENT; if (optname != MRT_INIT) { - if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN)) + if (sk != rcu_dereference_raw(mrt->mroute_sk) && + !capable(CAP_NET_ADMIN)) return -EACCES; } @@ -1217,23 +1222,20 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENOPROTOOPT; rtnl_lock(); - if (mrt->mroute_sk) { + if (rtnl_dereference(mrt->mroute_sk)) { rtnl_unlock(); return -EADDRINUSE; } ret = ip_ra_control(sk, 1, mrtsock_destruct); if (ret == 0) { - write_lock_bh(&mrt_lock); - mrt->mroute_sk = sk; - write_unlock_bh(&mrt_lock); - + rcu_assign_pointer(mrt->mroute_sk, sk); IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; } rtnl_unlock(); return ret; case MRT_DONE: - if (sk != mrt->mroute_sk) + if (sk != rcu_dereference_raw(mrt->mroute_sk)) return -EACCES; return ip_ra_control(sk, 0, NULL); case MRT_ADD_VIF: @@ -1246,7 +1248,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENFILE; rtnl_lock(); if (optname == MRT_ADD_VIF) { - ret = vif_add(net, mrt, &vif, sk == mrt->mroute_sk); + ret = vif_add(net, mrt, &vif, + sk == rtnl_dereference(mrt->mroute_sk)); } else { ret = vif_delete(mrt, vif.vifc_vifi, 0, NULL); } @@ -1267,7 +1270,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi if (optname == MRT_DEL_MFC) ret = ipmr_mfc_delete(mrt, &mfc); else - ret = ipmr_mfc_add(net, mrt, &mfc, sk == mrt->mroute_sk); + ret = ipmr_mfc_add(net, mrt, &mfc, + sk == rtnl_dereference(mrt->mroute_sk)); rtnl_unlock(); return ret; /* @@ -1309,14 +1313,16 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -EINVAL; if (get_user(v, (u32 __user *)optval)) return -EFAULT; - if (sk == mrt->mroute_sk) - return -EBUSY; rtnl_lock(); ret = 0; - if (!ipmr_new_table(net, v)) - ret = -ENOMEM; - raw_sk(sk)->ipmr_table = v; + if (sk == rtnl_dereference(mrt->mroute_sk)) { + ret = -EBUSY; + } else { + if (!ipmr_new_table(net, v)) + ret = -ENOMEM; + raw_sk(sk)->ipmr_table = v; + } rtnl_unlock(); return ret; } @@ -1713,6 +1719,7 @@ dont_forward: /* * Multicast packets for forwarding arrive here + * Called with rcu_read_lock(); */ int ip_mr_input(struct sk_buff *skb) @@ -1726,7 +1733,7 @@ int ip_mr_input(struct sk_buff *skb) /* Packet is looped back after forward, it should not be forwarded second time, but still can be delivered locally. */ - if (IPCB(skb)->flags&IPSKB_FORWARDED) + if (IPCB(skb)->flags & IPSKB_FORWARDED) goto dont_forward; err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt); @@ -1736,24 +1743,24 @@ int ip_mr_input(struct sk_buff *skb) } if (!local) { - if (IPCB(skb)->opt.router_alert) { - if (ip_call_ra_chain(skb)) - return 0; - } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP){ - /* IGMPv1 (and broken IGMPv2 implementations sort of - Cisco IOS <= 11.2(8)) do not put router alert - option to IGMP packets destined to routable - groups. It is very bad, because it means - that we can forward NO IGMP messages. - */ - read_lock(&mrt_lock); - if (mrt->mroute_sk) { - nf_reset(skb); - raw_rcv(mrt->mroute_sk, skb); - read_unlock(&mrt_lock); - return 0; - } - read_unlock(&mrt_lock); + if (IPCB(skb)->opt.router_alert) { + if (ip_call_ra_chain(skb)) + return 0; + } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP) { + /* IGMPv1 (and broken IGMPv2 implementations sort of + * Cisco IOS <= 11.2(8)) do not put router alert + * option to IGMP packets destined to routable + * groups. It is very bad, because it means + * that we can forward NO IGMP messages. + */ + struct sock *mroute_sk; + + mroute_sk = rcu_dereference(mrt->mroute_sk); + if (mroute_sk) { + nf_reset(skb); + raw_rcv(mroute_sk, skb); + return 0; + } } } -- cgit v1.2.3 From a8c9486b816f74d4645144db9e8fa2f711c1fc4b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Oct 2010 16:15:08 +0000 Subject: ipmr: RCU protection for mfc_cache_array Use RCU & RTNL protection for mfc_cache_array[] ipmr_cache_find() is called under rcu_read_lock(); Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/mroute.h | 1 + net/ipv4/ipmr.c | 87 +++++++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/include/linux/mroute.h b/include/linux/mroute.h index fa04b246c9ae..0fa7a3a874c8 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -213,6 +213,7 @@ struct mfc_cache { unsigned char ttls[MAXVIFS]; /* TTL thresholds */ } res; } mfc_un; + struct rcu_head rcu; }; #define MFC_STATIC 1 diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e2db2ea616ff..cbb6dabe024f 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -577,11 +577,18 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, return 0; } -static inline void ipmr_cache_free(struct mfc_cache *c) +static void ipmr_cache_free_rcu(struct rcu_head *head) { + struct mfc_cache *c = container_of(head, struct mfc_cache, rcu); + kmem_cache_free(mrt_cachep, c); } +static inline void ipmr_cache_free(struct mfc_cache *c) +{ + call_rcu(&c->rcu, ipmr_cache_free_rcu); +} + /* Destroy an unresolved cache entry, killing queued skbs and reporting error to netlink readers. */ @@ -781,6 +788,7 @@ static int vif_add(struct net *net, struct mr_table *mrt, return 0; } +/* called with rcu_read_lock() */ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, __be32 mcastgrp) @@ -788,7 +796,7 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, int line = MFC_HASH(mcastgrp, origin); struct mfc_cache *c; - list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { + list_for_each_entry_rcu(c, &mrt->mfc_cache_array[line], list) { if (c->mfc_origin == origin && c->mfc_mcastgrp == mcastgrp) return c; } @@ -801,19 +809,20 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, static struct mfc_cache *ipmr_cache_alloc(void) { struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); - if (c == NULL) - return NULL; - c->mfc_un.res.minvif = MAXVIFS; + + if (c) + c->mfc_un.res.minvif = MAXVIFS; return c; } static struct mfc_cache *ipmr_cache_alloc_unres(void) { struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); - if (c == NULL) - return NULL; - skb_queue_head_init(&c->mfc_un.unres.unresolved); - c->mfc_un.unres.expires = jiffies + 10*HZ; + + if (c) { + skb_queue_head_init(&c->mfc_un.unres.unresolved); + c->mfc_un.unres.expires = jiffies + 10*HZ; + } return c; } @@ -1040,9 +1049,7 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc) list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) { if (c->mfc_origin == mfc->mfcc_origin.s_addr && c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { - write_lock_bh(&mrt_lock); - list_del(&c->list); - write_unlock_bh(&mrt_lock); + list_del_rcu(&c->list); ipmr_cache_free(c); return 0; @@ -1095,9 +1102,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, if (!mrtsock) c->mfc_flags |= MFC_STATIC; - write_lock_bh(&mrt_lock); - list_add(&c->list, &mrt->mfc_cache_array[line]); - write_unlock_bh(&mrt_lock); + list_add_rcu(&c->list, &mrt->mfc_cache_array[line]); /* * Check to see if we resolved a queued list. If so we @@ -1149,12 +1154,9 @@ static void mroute_clean_tables(struct mr_table *mrt) */ for (i = 0; i < MFC_LINES; i++) { list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { - if (c->mfc_flags&MFC_STATIC) + if (c->mfc_flags & MFC_STATIC) continue; - write_lock_bh(&mrt_lock); - list_del(&c->list); - write_unlock_bh(&mrt_lock); - + list_del_rcu(&c->list); ipmr_cache_free(c); } } @@ -1422,19 +1424,19 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) if (copy_from_user(&sr, arg, sizeof(sr))) return -EFAULT; - read_lock(&mrt_lock); + rcu_read_lock(); c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); if (c) { sr.pktcnt = c->mfc_un.res.pkt; sr.bytecnt = c->mfc_un.res.bytes; sr.wrong_if = c->mfc_un.res.wrong_if; - read_unlock(&mrt_lock); + rcu_read_unlock(); if (copy_to_user(arg, &sr, sizeof(sr))) return -EFAULT; return 0; } - read_unlock(&mrt_lock); + rcu_read_unlock(); return -EADDRNOTAVAIL; default: return -ENOIOCTLCMD; @@ -1764,7 +1766,7 @@ int ip_mr_input(struct sk_buff *skb) } } - read_lock(&mrt_lock); + /* already under rcu_read_lock() */ cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); /* @@ -1776,13 +1778,12 @@ int ip_mr_input(struct sk_buff *skb) if (local) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); ip_local_deliver(skb); - if (skb2 == NULL) { - read_unlock(&mrt_lock); + if (skb2 == NULL) return -ENOBUFS; - } skb = skb2; } + read_lock(&mrt_lock); vif = ipmr_find_vif(mrt, skb->dev); if (vif >= 0) { int err2 = ipmr_cache_unresolved(mrt, vif, skb); @@ -1795,8 +1796,8 @@ int ip_mr_input(struct sk_buff *skb) return -ENODEV; } + read_lock(&mrt_lock); ip_mr_forward(net, mrt, skb, cache, local); - read_unlock(&mrt_lock); if (local) @@ -1963,7 +1964,7 @@ int ipmr_get_route(struct net *net, if (mrt == NULL) return -ENOENT; - read_lock(&mrt_lock); + rcu_read_lock(); cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst); if (cache == NULL) { @@ -1973,18 +1974,21 @@ int ipmr_get_route(struct net *net, int vif; if (nowait) { - read_unlock(&mrt_lock); + rcu_read_unlock(); return -EAGAIN; } dev = skb->dev; + read_lock(&mrt_lock); if (dev == NULL || (vif = ipmr_find_vif(mrt, dev)) < 0) { read_unlock(&mrt_lock); + rcu_read_unlock(); return -ENODEV; } skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) { read_unlock(&mrt_lock); + rcu_read_unlock(); return -ENOMEM; } @@ -1997,13 +2001,16 @@ int ipmr_get_route(struct net *net, iph->version = 0; err = ipmr_cache_unresolved(mrt, vif, skb2); read_unlock(&mrt_lock); + rcu_read_unlock(); return err; } - if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) + read_lock(&mrt_lock); + if (!nowait && (rtm->rtm_flags & RTM_F_NOTIFY)) cache->mfc_flags |= MFC_NOTIFY; err = __ipmr_fill_mroute(mrt, skb, cache, rtm); read_unlock(&mrt_lock); + rcu_read_unlock(); return err; } @@ -2055,14 +2062,14 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) s_h = cb->args[1]; s_e = cb->args[2]; - read_lock(&mrt_lock); + rcu_read_lock(); ipmr_for_each_table(mrt, net) { if (t < s_t) goto next_table; if (t > s_t) s_h = 0; for (h = s_h; h < MFC_LINES; h++) { - list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) { + list_for_each_entry_rcu(mfc, &mrt->mfc_cache_array[h], list) { if (e < s_e) goto next_entry; if (ipmr_fill_mroute(mrt, skb, @@ -2080,7 +2087,7 @@ next_table: t++; } done: - read_unlock(&mrt_lock); + rcu_read_unlock(); cb->args[2] = e; cb->args[1] = h; @@ -2213,14 +2220,14 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net, struct mr_table *mrt = it->mrt; struct mfc_cache *mfc; - read_lock(&mrt_lock); + rcu_read_lock(); for (it->ct = 0; it->ct < MFC_LINES; it->ct++) { it->cache = &mrt->mfc_cache_array[it->ct]; - list_for_each_entry(mfc, it->cache, list) + list_for_each_entry_rcu(mfc, it->cache, list) if (pos-- == 0) return mfc; } - read_unlock(&mrt_lock); + rcu_read_unlock(); spin_lock_bh(&mfc_unres_lock); it->cache = &mrt->mfc_unres_queue; @@ -2279,7 +2286,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) } /* exhausted cache_array, show unresolved */ - read_unlock(&mrt_lock); + rcu_read_unlock(); it->cache = &mrt->mfc_unres_queue; it->ct = 0; @@ -2302,7 +2309,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) if (it->cache == &mrt->mfc_unres_queue) spin_unlock_bh(&mfc_unres_lock); else if (it->cache == &mrt->mfc_cache_array[it->ct]) - read_unlock(&mrt_lock); + rcu_read_unlock(); } static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) @@ -2426,7 +2433,7 @@ int __init ip_mr_init(void) mrt_cachep = kmem_cache_create("ip_mrt_cache", sizeof(struct mfc_cache), - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, + 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); if (!mrt_cachep) return -ENOMEM; -- cgit v1.2.3 From a8cb16dd9cb571c45bb479a1e4721ce11220a216 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Oct 2010 16:15:29 +0000 Subject: ipmr: cleanups Various code style cleanups Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ipmr.c | 238 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 124 insertions(+), 114 deletions(-) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index cbb6dabe024f..86dd5691af46 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -98,7 +98,7 @@ struct ipmr_result { }; /* Big lock, protecting vif table, mrt cache and mroute socket state. - Note that the changes are semaphored via rtnl_lock. + * Note that the changes are semaphored via rtnl_lock. */ static DEFINE_RWLOCK(mrt_lock); @@ -113,11 +113,11 @@ static DEFINE_RWLOCK(mrt_lock); static DEFINE_SPINLOCK(mfc_unres_lock); /* We return to original Alan's scheme. Hash table of resolved - entries is changed only in process context and protected - with weak lock mrt_lock. Queue of unresolved entries is protected - with strong spinlock mfc_unres_lock. - - In this case data path is free of exclusive locks at all. + * entries is changed only in process context and protected + * with weak lock mrt_lock. Queue of unresolved entries is protected + * with strong spinlock mfc_unres_lock. + * + * In this case data path is free of exclusive locks at all. */ static struct kmem_cache *mrt_cachep __read_mostly; @@ -396,9 +396,9 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v) set_fs(KERNEL_DS); err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL); set_fs(oldfs); - } else + } else { err = -EOPNOTSUPP; - + } dev = NULL; if (err == 0 && @@ -495,7 +495,8 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) dev->iflink = 0; rcu_read_lock(); - if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) { rcu_read_unlock(); goto failure; } @@ -552,9 +553,10 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, mrt->mroute_reg_vif_num = -1; #endif - if (vifi+1 == mrt->maxvif) { + if (vifi + 1 == mrt->maxvif) { int tmp; - for (tmp=vifi-1; tmp>=0; tmp--) { + + for (tmp = vifi - 1; tmp >= 0; tmp--) { if (VIF_EXISTS(mrt, tmp)) break; } @@ -565,12 +567,13 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, dev_set_allmulti(dev, -1); - if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { + in_dev = __in_dev_get_rtnl(dev); + if (in_dev) { IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; ip_rt_multicast_event(in_dev); } - if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER) && !notify) + if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER) && !notify) unregister_netdevice_queue(dev, head); dev_put(dev); @@ -590,7 +593,7 @@ static inline void ipmr_cache_free(struct mfc_cache *c) } /* Destroy an unresolved cache entry, killing queued skbs - and reporting error to netlink readers. + * and reporting error to netlink readers. */ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c) @@ -612,8 +615,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c) memset(&e->msg, 0, sizeof(e->msg)); rtnl_unicast(skb, net, NETLINK_CB(skb).pid); - } else + } else { kfree_skb(skb); + } } ipmr_cache_free(c); @@ -735,9 +739,9 @@ static int vif_add(struct net *net, struct mr_table *mrt, dev_put(dev); return -EADDRNOTAVAIL; } - } else + } else { dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr); - + } if (!dev) return -EADDRNOTAVAIL; err = dev_set_allmulti(dev, 1); @@ -750,16 +754,16 @@ static int vif_add(struct net *net, struct mr_table *mrt, return -EINVAL; } - if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { + in_dev = __in_dev_get_rtnl(dev); + if (!in_dev) { dev_put(dev); return -EADDRNOTAVAIL; } IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; ip_rt_multicast_event(in_dev); - /* - * Fill in the VIF structures - */ + /* Fill in the VIF structures */ + v->rate_limit = vifc->vifc_rate_limit; v->local = vifc->vifc_lcl_addr.s_addr; v->remote = vifc->vifc_rmt_addr.s_addr; @@ -772,14 +776,14 @@ static int vif_add(struct net *net, struct mr_table *mrt, v->pkt_in = 0; v->pkt_out = 0; v->link = dev->ifindex; - if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) + if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER)) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); v->dev = dev; #ifdef CONFIG_IP_PIMSM - if (v->flags&VIFF_REGISTER) + if (v->flags & VIFF_REGISTER) mrt->mroute_reg_vif_num = vifi; #endif if (vifi+1 > mrt->maxvif) @@ -836,17 +840,15 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, struct sk_buff *skb; struct nlmsgerr *e; - /* - * Play the pending entries through our router - */ + /* Play the pending entries through our router */ while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) { if (ip_hdr(skb)->version == 0) { struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { - nlh->nlmsg_len = (skb_tail_pointer(skb) - - (u8 *)nlh); + nlh->nlmsg_len = skb_tail_pointer(skb) - + (u8 *)nlh; } else { nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); @@ -857,8 +859,9 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, } rtnl_unicast(skb, net, NETLINK_CB(skb).pid); - } else + } else { ip_mr_forward(net, mrt, skb, c, 0); + } } } @@ -892,9 +895,9 @@ static int ipmr_cache_report(struct mr_table *mrt, #ifdef CONFIG_IP_PIMSM if (assert == IGMPMSG_WHOLEPKT) { /* Ugly, but we have no choice with this interface. - Duplicate old header, fix ihl, length etc. - And all this only to mangle msg->im_msgtype and - to set msg->im_mbz to "mbz" :-) + * Duplicate old header, fix ihl, length etc. + * And all this only to mangle msg->im_msgtype and + * to set msg->im_mbz to "mbz" :-) */ skb_push(skb, sizeof(struct iphdr)); skb_reset_network_header(skb); @@ -911,27 +914,23 @@ static int ipmr_cache_report(struct mr_table *mrt, #endif { - /* - * Copy the IP header - */ + /* Copy the IP header */ skb->network_header = skb->tail; skb_put(skb, ihl); skb_copy_to_linear_data(skb, pkt->data, ihl); - ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ + ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ msg = (struct igmpmsg *)skb_network_header(skb); msg->im_vif = vifi; skb_dst_set(skb, dst_clone(skb_dst(pkt))); - /* - * Add our header - */ + /* Add our header */ - igmp=(struct igmphdr *)skb_put(skb, sizeof(struct igmphdr)); + igmp = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr)); igmp->type = msg->im_msgtype = assert; - igmp->code = 0; - ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */ + igmp->code = 0; + ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */ skb->transport_header = skb->network_header; } @@ -943,9 +942,8 @@ static int ipmr_cache_report(struct mr_table *mrt, return -EINVAL; } - /* - * Deliver to mrouted - */ + /* Deliver to mrouted */ + ret = sock_queue_rcv_skb(mroute_sk, skb); rcu_read_unlock(); if (ret < 0) { @@ -979,9 +977,7 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) } if (!found) { - /* - * Create a new entry if allowable - */ + /* Create a new entry if allowable */ if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 || (c = ipmr_cache_alloc_unres()) == NULL) { @@ -991,16 +987,14 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) return -ENOBUFS; } - /* - * Fill in the new cache entry - */ + /* Fill in the new cache entry */ + c->mfc_parent = -1; c->mfc_origin = iph->saddr; c->mfc_mcastgrp = iph->daddr; - /* - * Reflect first query at mrouted. - */ + /* Reflect first query at mrouted. */ + err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE); if (err < 0) { /* If the report failed throw the cache entry @@ -1020,10 +1014,9 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires); } - /* - * See if we can append the packet - */ - if (c->mfc_un.unres.unresolved.qlen>3) { + /* See if we can append the packet */ + + if (c->mfc_un.unres.unresolved.qlen > 3) { kfree_skb(skb); err = -ENOBUFS; } else { @@ -1140,18 +1133,16 @@ static void mroute_clean_tables(struct mr_table *mrt) LIST_HEAD(list); struct mfc_cache *c, *next; - /* - * Shut down all active vif entries - */ + /* Shut down all active vif entries */ + for (i = 0; i < mrt->maxvif; i++) { - if (!(mrt->vif_table[i].flags&VIFF_STATIC)) + if (!(mrt->vif_table[i].flags & VIFF_STATIC)) vif_delete(mrt, i, 0, &list); } unregister_netdevice_many(&list); - /* - * Wipe the cache - */ + /* Wipe the cache */ + for (i = 0; i < MFC_LINES; i++) { list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { if (c->mfc_flags & MFC_STATIC) @@ -1282,7 +1273,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi case MRT_ASSERT: { int v; - if (get_user(v,(int __user *)optval)) + if (get_user(v, (int __user *)optval)) return -EFAULT; mrt->mroute_do_assert = (v) ? 1 : 0; return 0; @@ -1292,7 +1283,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi { int v; - if (get_user(v,(int __user *)optval)) + if (get_user(v, (int __user *)optval)) return -EFAULT; v = (v) ? 1 : 0; @@ -1355,9 +1346,9 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int if (optname != MRT_VERSION && #ifdef CONFIG_IP_PIMSM - optname!=MRT_PIM && + optname != MRT_PIM && #endif - optname!=MRT_ASSERT) + optname != MRT_ASSERT) return -ENOPROTOOPT; if (get_user(olr, optlen)) @@ -1473,7 +1464,7 @@ static struct notifier_block ip_mr_notifier = { }; /* - * Encapsulate a packet by attaching a valid IPIP header to it. + * Encapsulate a packet by attaching a valid IPIP header to it. * This avoids tunnel drivers and other mess and gives us the speed so * important for multicast video. */ @@ -1488,7 +1479,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) skb_reset_network_header(skb); iph = ip_hdr(skb); - iph->version = 4; + iph->version = 4; iph->tos = old_iph->tos; iph->ttl = old_iph->ttl; iph->frag_off = 0; @@ -1506,7 +1497,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) static inline int ipmr_forward_finish(struct sk_buff *skb) { - struct ip_options * opt = &(IPCB(skb)->opt); + struct ip_options *opt = &(IPCB(skb)->opt); IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); @@ -1543,22 +1534,34 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, } #endif - if (vif->flags&VIFF_TUNNEL) { - struct flowi fl = { .oif = vif->link, - .nl_u = { .ip4_u = - { .daddr = vif->remote, - .saddr = vif->local, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + if (vif->flags & VIFF_TUNNEL) { + struct flowi fl = { + .oif = vif->link, + .nl_u = { + .ip4_u = { + .daddr = vif->remote, + .saddr = vif->local, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(net, &rt, &fl)) goto out_free; encap = sizeof(struct iphdr); } else { - struct flowi fl = { .oif = vif->link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = vif->link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(net, &rt, &fl)) goto out_free; } @@ -1567,8 +1570,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF)) { /* Do not fragment multicasts. Alas, IPv4 does not - allow to send ICMP, so that packets will disappear - to blackhole. + * allow to send ICMP, so that packets will disappear + * to blackhole. */ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS); @@ -1591,7 +1594,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, ip_decrease_ttl(ip_hdr(skb)); /* FIXME: forward and output firewalls used to be called here. - * What do we do with netfilter? -- RR */ + * What do we do with netfilter? -- RR + */ if (vif->flags & VIFF_TUNNEL) { ip_encap(skb, vif->local, vif->remote); /* FIXME: extra output firewall step used to be here. --RR */ @@ -1652,15 +1656,15 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (skb_rtable(skb)->fl.iif == 0) { /* It is our own packet, looped back. - Very complicated situation... - - The best workaround until routing daemons will be - fixed is not to redistribute packet, if it was - send through wrong interface. It means, that - multicast applications WILL NOT work for - (S,G), which have default multicast route pointing - to wrong oif. In any case, it is not a good - idea to use multicasting applications on router. + * Very complicated situation... + * + * The best workaround until routing daemons will be + * fixed is not to redistribute packet, if it was + * send through wrong interface. It means, that + * multicast applications WILL NOT work for + * (S,G), which have default multicast route pointing + * to wrong oif. In any case, it is not a good + * idea to use multicasting applications on router. */ goto dont_forward; } @@ -1670,9 +1674,9 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (true_vifi >= 0 && mrt->mroute_do_assert && /* pimsm uses asserts, when switching from RPT to SPT, - so that we cannot check that packet arrived on an oif. - It is bad, but otherwise we would need to move pretty - large chunk of pimd to kernel. Ough... --ANK + * so that we cannot check that packet arrived on an oif. + * It is bad, but otherwise we would need to move pretty + * large chunk of pimd to kernel. Ough... --ANK */ (mrt->mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && @@ -1690,10 +1694,12 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, /* * Forward the frame */ - for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { + for (ct = cache->mfc_un.res.maxvif - 1; + ct >= cache->mfc_un.res.minvif; ct--) { if (ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) { if (psend != -1) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) ipmr_queue_xmit(net, mrt, skb2, cache, psend); @@ -1704,6 +1710,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (psend != -1) { if (local) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) ipmr_queue_xmit(net, mrt, skb2, cache, psend); } else { @@ -1733,7 +1740,7 @@ int ip_mr_input(struct sk_buff *skb) int err; /* Packet is looped back after forward, it should not be - forwarded second time, but still can be delivered locally. + * forwarded second time, but still can be delivered locally. */ if (IPCB(skb)->flags & IPSKB_FORWARDED) goto dont_forward; @@ -1822,10 +1829,10 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, encap = (struct iphdr *)(skb_transport_header(skb) + pimlen); /* - Check that: - a. packet is really destinted to a multicast group - b. packet is not a NULL-REGISTER - c. packet is not truncated + * Check that: + * a. packet is really sent to a multicast group + * b. packet is not a NULL-REGISTER + * c. packet is not truncated */ if (!ipv4_is_multicast(encap->daddr) || encap->tot_len == 0 || @@ -1860,7 +1867,7 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, * Handle IGMP messages of PIMv1 */ -int pim_rcv_v1(struct sk_buff * skb) +int pim_rcv_v1(struct sk_buff *skb) { struct igmphdr *pim; struct net *net = dev_net(skb->dev); @@ -1887,7 +1894,7 @@ drop: #endif #ifdef CONFIG_IP_PIMSM_V2 -static int pim_rcv(struct sk_buff * skb) +static int pim_rcv(struct sk_buff *skb) { struct pimreghdr *pim; struct net *net = dev_net(skb->dev); @@ -1897,8 +1904,8 @@ static int pim_rcv(struct sk_buff * skb) goto drop; pim = (struct pimreghdr *)skb_transport_header(skb); - if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || - (pim->flags&PIM_NULL_REGISTER) || + if (pim->type != ((PIM_VERSION << 4) | (PIM_REGISTER)) || + (pim->flags & PIM_NULL_REGISTER) || (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && csum_fold(skb_checksum(skb, 0, skb->len, 0)))) goto drop; @@ -1971,7 +1978,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb2; struct iphdr *iph; struct net_device *dev; - int vif; + int vif = -1; if (nowait) { rcu_read_unlock(); @@ -1980,7 +1987,9 @@ int ipmr_get_route(struct net *net, dev = skb->dev; read_lock(&mrt_lock); - if (dev == NULL || (vif = ipmr_find_vif(mrt, dev)) < 0) { + if (dev) + vif = ipmr_find_vif(mrt, dev); + if (vif < 0) { read_unlock(&mrt_lock); rcu_read_unlock(); return -ENODEV; @@ -2098,7 +2107,8 @@ done: #ifdef CONFIG_PROC_FS /* - * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif + * The /proc interfaces to multicast routing : + * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif */ struct ipmr_vif_iter { struct seq_net_private p; @@ -2294,7 +2304,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) if (!list_empty(it->cache)) return list_first_entry(it->cache, struct mfc_cache, list); - end_of_list: +end_of_list: spin_unlock_bh(&mfc_unres_lock); it->cache = NULL; @@ -2335,7 +2345,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) mfc->mfc_un.res.bytes, mfc->mfc_un.res.wrong_if); for (n = mfc->mfc_un.res.minvif; - n < mfc->mfc_un.res.maxvif; n++ ) { + n < mfc->mfc_un.res.maxvif; n++) { if (VIF_EXISTS(mrt, n) && mfc->mfc_un.res.ttls[n] < 255) seq_printf(seq, -- cgit v1.2.3 From f009627b71eacfeede3d63b00a25afdf5e3e24bb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 1 Oct 2010 11:17:12 +0000 Subject: drivers-net-tulip-de4x5c-fix-copy-length-in-de4x5_ioctl-checkpatch-fixes ERROR: trailing statements should be on next line #23: FILE: drivers/net/tulip/de4x5.c:5477: + if (copy_to_user(ioc->data, tmp.lval, ioc->len)) return -EFAULT; total: 1 errors, 0 warnings, 8 lines checked ./patches/drivers-net-tulip-de4x5c-fix-copy-length-in-de4x5_ioctl.patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Please run checkpatch prior to sending patches Cc: Dan Rosenberg Cc: Grant Grundler Cc: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 251c6ce15aea..4dbd493b996b 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -5474,7 +5474,8 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) tmp.lval[6] = inl(DE4X5_STRR); j+=4; tmp.lval[7] = inl(DE4X5_SIGR); j+=4; ioc->len = j; - if (copy_to_user(ioc->data, tmp.lval, ioc->len)) return -EFAULT; + if (copy_to_user(ioc->data, tmp.lval, ioc->len)) + return -EFAULT; break; #define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */ -- cgit v1.2.3 From 1790c228fb3f57793160c0f0c20b55c398cab106 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 2 Oct 2010 04:37:07 +0000 Subject: drivers/atm/idt77252.c: Remove unnecessary error check This code does not call deinit_card(card); in an error case, as done in other error-handling code in the same function. But actually, the called function init_sram can only return 0, so there is no need for the error check at all. init_sram is also given a void return type, and its single return statement at the end of the function is dropped. A simplified version of the sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ @r@ statement S1,S2,S3; constant C1,C2,C3; @@ *if (...) {... S1 return -C1;} ... *if (...) {... when != S1 return -C2;} ... *if (...) {... S1 return -C3;} // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/atm/idt77252.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 1679cbf0c584..bce57328ddde 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -3152,7 +3152,7 @@ deinit_card(struct idt77252_dev *card) } -static int __devinit +static void __devinit init_sram(struct idt77252_dev *card) { int i; @@ -3298,7 +3298,6 @@ init_sram(struct idt77252_dev *card) SAR_REG_RXFD); IPRINTK("%s: SRAM initialization complete.\n", card->name); - return 0; } static int __devinit @@ -3410,8 +3409,7 @@ init_card(struct atm_dev *dev) writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG); - if (init_sram(card) < 0) - return -1; + init_sram(card); /********************************************************************/ /* A L L O C R A M A N D S E T V A R I O U S T H I N G S */ -- cgit v1.2.3 From a069ec917457e44e214fc34e50acd185110fa81b Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Thu, 30 Sep 2010 09:17:12 +0000 Subject: cxgb4: remove a bogus PCI function number check Remove a bogus PCI function number check from the driver's .remove method that causes pci_release_regions not to be called for function 0 if additional functions are attached and one of them is used as primary. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 4fb08e3c3f38..22169a73b7f7 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3863,7 +3863,7 @@ static void __devexit remove_one(struct pci_dev *pdev) pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - } else if (PCI_FUNC(pdev->devfn) > 0) + } else pci_release_regions(pdev); } -- cgit v1.2.3 From 10651db75a94c54a34bbf85fbee334d1114da3fb Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Fri, 1 Oct 2010 02:51:13 +0000 Subject: qeth: tagging with VLAN-ID 0 This patch adapts qeth to handle tagged frames with VLAN-ID 0 and with or without priority information in the tag. It enables qeth to receive priority-tagged frames on a base interface, for example from z/OS, without configuring an additional VLAN interface. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 2 ++ drivers/s390/net/qeth_l3_main.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 01c3c1f77879..847e8797073c 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -310,6 +310,8 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct qeth_vlan_vid *id; QETH_CARD_TEXT_(card, 4, "aid:%d", vid); + if (!vid) + return; if (card->info.type == QETH_CARD_TYPE_OSM) { QETH_CARD_TEXT(card, 3, "aidOSM"); return; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 5b79f573bd93..c094707fcbff 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2013,13 +2013,14 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) qeth_l3_set_multicast_list(card->dev); } -static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, - struct sk_buff *skb, struct qeth_hdr *hdr) +static inline int qeth_l3_rebuild_skb(struct qeth_card *card, + struct sk_buff *skb, struct qeth_hdr *hdr, + unsigned short *vlan_id) { - unsigned short vlan_id = 0; __be16 prot; struct iphdr *ip_hdr; unsigned char tg_addr[MAX_ADDR_LEN]; + int is_vlan = 0; if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : @@ -2082,8 +2083,9 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, if (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { - vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? + *vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME) ? hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); + is_vlan = 1; } switch (card->options.checksum_type) { @@ -2104,7 +2106,7 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, skb->ip_summed = CHECKSUM_NONE; } - return vlan_id; + return is_vlan; } static int qeth_l3_process_inbound_buffer(struct qeth_card *card, @@ -2114,6 +2116,7 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, struct sk_buff *skb; struct qeth_hdr *hdr; __u16 vlan_tag = 0; + int is_vlan; unsigned int len; *done = 0; @@ -2129,16 +2132,12 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, skb->dev = card->dev; switch (hdr->hdr.l3.id) { case QETH_HEADER_TYPE_LAYER3: - vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); + is_vlan = qeth_l3_rebuild_skb(card, skb, hdr, + &vlan_tag); len = skb->len; - if (vlan_tag && !card->options.sniffer) - if (card->vlangrp) - vlan_gro_receive(&card->napi, - card->vlangrp, vlan_tag, skb); - else { - dev_kfree_skb_any(skb); - continue; - } + if (is_vlan && !card->options.sniffer) + vlan_gro_receive(&card->napi, card->vlangrp, + vlan_tag, skb); else napi_gro_receive(&card->napi, skb); break; -- cgit v1.2.3 From 3abcdeda59c1d4cf2bf83311ed2d544355ec7c2d Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 3 Oct 2010 22:12:27 -0700 Subject: be2net: add multiple RX queue support This patch adds multiple RX queue support to be2net. There are upto 4 extra rx-queues per port into which TCP/UDP traffic can be hashed into. Some of the ethtool stats are now displayed on a per queue basis. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 82 +++--- drivers/net/benet/be_cmds.c | 40 ++- drivers/net/benet/be_cmds.h | 32 ++- drivers/net/benet/be_ethtool.c | 174 +++++++------ drivers/net/benet/be_main.c | 561 +++++++++++++++++++++++------------------ 5 files changed, 526 insertions(+), 363 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4faf6961dcec..1afabb1e6620 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -78,6 +78,8 @@ static inline char *nic_name(struct pci_dev *pdev) #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ #define MCC_CQ_LEN 256 +#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ +#define BE_MAX_MSIX_VECTORS (MAX_RSS_QS + 1 + 1)/* RSS qs + 1 def Rx + Tx */ #define BE_NAPI_WEIGHT 64 #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) @@ -157,10 +159,9 @@ struct be_mcc_obj { bool rearm_cq; }; -struct be_drvr_stats { +struct be_tx_stats { u32 be_tx_reqs; /* number of TX requests initiated */ u32 be_tx_stops; /* number of times TX Q was stopped */ - u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */ u32 be_tx_wrbs; /* number of tx WRBs used */ u32 be_tx_events; /* number of tx completion events */ u32 be_tx_compl; /* number of tx completion entries processed */ @@ -169,35 +170,6 @@ struct be_drvr_stats { u64 be_tx_bytes_prev; u64 be_tx_pkts; u32 be_tx_rate; - - u32 cache_barrier[16]; - - u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */ - u32 be_rx_polls; /* number of times NAPI called poll function */ - u32 be_rx_events; /* number of ucast rx completion events */ - u32 be_rx_compl; /* number of rx completion entries processed */ - ulong be_rx_jiffies; - u64 be_rx_bytes; - u64 be_rx_bytes_prev; - u64 be_rx_pkts; - u32 be_rx_rate; - u32 be_rx_mcast_pkt; - /* number of non ether type II frames dropped where - * frame len > length field of Mac Hdr */ - u32 be_802_3_dropped_frames; - /* number of non ether type II frames malformed where - * in frame len < length field of Mac Hdr */ - u32 be_802_3_malformed_frames; - u32 be_rxcp_err; /* Num rx completion entries w/ err set. */ - ulong rx_fps_jiffies; /* jiffies at last FPS calc */ - u32 be_rx_frags; - u32 be_prev_rx_frags; - u32 be_rx_fps; /* Rx frags per second */ -}; - -struct be_stats_obj { - struct be_drvr_stats drvr_stats; - struct be_dma_mem cmd; }; struct be_tx_obj { @@ -215,10 +187,34 @@ struct be_rx_page_info { bool last_page_user; }; +struct be_rx_stats { + u32 rx_post_fail;/* number of ethrx buffer alloc failures */ + u32 rx_polls; /* number of times NAPI called poll function */ + u32 rx_events; /* number of ucast rx completion events */ + u32 rx_compl; /* number of rx completion entries processed */ + ulong rx_jiffies; + u64 rx_bytes; + u64 rx_bytes_prev; + u64 rx_pkts; + u32 rx_rate; + u32 rx_mcast_pkts; + u32 rxcp_err; /* Num rx completion entries w/ err set. */ + ulong rx_fps_jiffies; /* jiffies at last FPS calc */ + u32 rx_frags; + u32 prev_rx_frags; + u32 rx_fps; /* Rx frags per second */ +}; + struct be_rx_obj { + struct be_adapter *adapter; struct be_queue_info q; struct be_queue_info cq; struct be_rx_page_info page_info_tbl[RX_Q_LEN]; + struct be_eq_obj rx_eq; + struct be_rx_stats stats; + u8 rss_id; + bool rx_post_starved; /* Zero rx frags have been posted to BE */ + u32 cache_line_barrier[16]; }; struct be_vf_cfg { @@ -229,7 +225,6 @@ struct be_vf_cfg { u32 vf_tx_rate; }; -#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ #define BE_INVALID_PMAC_ID 0xffffffff struct be_adapter { struct pci_dev *pdev; @@ -249,21 +244,21 @@ struct be_adapter { spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ spinlock_t mcc_cq_lock; - struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS]; + struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; bool msix_enabled; bool isr_registered; /* TX Rings */ struct be_eq_obj tx_eq; struct be_tx_obj tx_obj; + struct be_tx_stats tx_stats; u32 cache_line_break[8]; /* Rx rings */ - struct be_eq_obj rx_eq; - struct be_rx_obj rx_obj; + struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */ + u32 num_rx_qs; u32 big_page_size; /* Compounded page size shared by rx wrbs */ - bool rx_post_starved; /* Zero rx frags have been posted to BE */ struct vlan_group *vlan_grp; u16 vlans_added; @@ -271,7 +266,7 @@ struct be_adapter { u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; struct be_dma_mem mc_cmd_mem; - struct be_stats_obj stats; + struct be_dma_mem stats_cmd; /* Work queue used to perform periodic tasks like getting statistics */ struct delayed_work work; @@ -287,6 +282,7 @@ struct be_adapter { bool promiscuous; bool wol; u32 function_mode; + u32 function_caps; u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ bool ue_detected; @@ -313,10 +309,20 @@ struct be_adapter { extern const struct ethtool_ops be_ethtool_ops; -#define drvr_stats(adapter) (&adapter->stats.drvr_stats) +#define tx_stats(adapter) (&adapter->tx_stats) +#define rx_stats(rxo) (&rxo->stats) #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) +#define for_all_rx_queues(adapter, rxo, i) \ + for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ + i++, rxo++) + +/* Just skip the first default non-rss queue */ +#define for_all_rss_queues(adapter, rxo, i) \ + for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\ + i++, rxo++) + #define PAGE_SHIFT_4K 12 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 0db28b411e87..bf2dc269de12 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -71,7 +71,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter, if (compl_status == MCC_STATUS_SUCCESS) { if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { struct be_cmd_resp_get_stats *resp = - adapter->stats.cmd.va; + adapter->stats_cmd.va; be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); netdev_stats_update(adapter); @@ -754,7 +754,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, /* Uses mbox */ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, - u16 max_frame_size, u32 if_id, u32 rss) + u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id) { struct be_mcc_wrb *wrb; struct be_cmd_req_eth_rx_create *req; @@ -785,6 +785,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); rxq->id = le16_to_cpu(resp->id); rxq->created = true; + *rss_id = resp->rss_id; } spin_unlock(&adapter->mbox_lock); @@ -1259,7 +1260,8 @@ err: } /* Uses mbox */ -int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) +int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, + u32 *mode, u32 *caps) { struct be_mcc_wrb *wrb; struct be_cmd_req_query_fw_cfg *req; @@ -1281,6 +1283,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); *port_num = le32_to_cpu(resp->phys_port); *mode = le32_to_cpu(resp->function_mode); + *caps = le32_to_cpu(resp->function_caps); } spin_unlock(&adapter->mbox_lock); @@ -1311,6 +1314,37 @@ int be_cmd_reset_function(struct be_adapter *adapter) return status; } +int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_rss_config *req; + u32 myhash[10]; + int status; + + spin_lock(&adapter->mbox_lock); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_ETH_RSS_CONFIG); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, + OPCODE_ETH_RSS_CONFIG, sizeof(*req)); + + req->if_id = cpu_to_le32(adapter->if_handle); + req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4); + req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1); + memcpy(req->cpu_table, rsstable, table_size); + memcpy(req->hash, myhash, sizeof(myhash)); + be_dws_cpu_to_le(req->hash, sizeof(req->hash)); + + status = be_mbox_notify_wait(adapter); + + spin_unlock(&adapter->mbox_lock); + return status; +} + /* Uses sync mcc */ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 bcn, u8 sts, u8 state) diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index ad1e6fac60c5..b7a40b172d1a 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -147,6 +147,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PHY_DETAILS 102 +#define OPCODE_ETH_RSS_CONFIG 1 #define OPCODE_ETH_ACPI_CONFIG 2 #define OPCODE_ETH_PROMISCUOUS 3 #define OPCODE_ETH_GET_STATISTICS 4 @@ -409,7 +410,7 @@ struct be_cmd_req_eth_rx_create { struct be_cmd_resp_eth_rx_create { struct be_cmd_resp_hdr hdr; u16 id; - u8 cpu_id; + u8 rss_id; u8 rsvd0; } __packed; @@ -739,9 +740,10 @@ struct be_cmd_resp_modify_eq_delay { } __packed; /******************** Get FW Config *******************/ +#define BE_FUNCTION_CAPS_RSS 0x2 struct be_cmd_req_query_fw_cfg { struct be_cmd_req_hdr hdr; - u32 rsvd[30]; + u32 rsvd[31]; }; struct be_cmd_resp_query_fw_cfg { @@ -751,6 +753,26 @@ struct be_cmd_resp_query_fw_cfg { u32 phys_port; u32 function_mode; u32 rsvd[26]; + u32 function_caps; +}; + +/******************** RSS Config *******************/ +/* RSS types */ +#define RSS_ENABLE_NONE 0x0 +#define RSS_ENABLE_IPV4 0x1 +#define RSS_ENABLE_TCP_IPV4 0x2 +#define RSS_ENABLE_IPV6 0x4 +#define RSS_ENABLE_TCP_IPV6 0x8 + +struct be_cmd_req_rss_config { + struct be_cmd_req_hdr hdr; + u32 if_id; + u16 enable_rss; + u16 cpu_table_size_log2; + u32 hash[10]; + u8 cpu_table[128]; + u8 flush; + u8 rsvd0[3]; }; /******************** Port Beacon ***************************/ @@ -937,7 +959,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter, extern int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, u16 max_frame_size, u32 if_id, - u32 rss); + u32 rss, u8 *rss_id); extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, int type); extern int be_cmd_link_status_query(struct be_adapter *adapter, @@ -960,8 +982,10 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter, extern int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc); extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, - u32 *port_num, u32 *cap); + u32 *port_num, u32 *function_mode, u32 *function_caps); extern int be_cmd_reset_function(struct be_adapter *adapter); +extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + u16 table_size); extern int be_process_mcc(struct be_adapter *adapter, int *status); extern int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, u8 status, u8 state); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index d92063420c25..0f46366ecc48 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -26,14 +26,16 @@ struct be_ethtool_stat { int offset; }; -enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT}; +enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) #define NETSTAT_INFO(field) #field, NETSTAT,\ FIELDINFO(struct net_device_stats,\ field) -#define DRVSTAT_INFO(field) #field, DRVSTAT,\ - FIELDINFO(struct be_drvr_stats, field) +#define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\ + FIELDINFO(struct be_tx_stats, field) +#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\ + FIELDINFO(struct be_rx_stats, field) #define MISCSTAT_INFO(field) #field, MISCSTAT,\ FIELDINFO(struct be_rxf_stats, field) #define PORTSTAT_INFO(field) #field, PORTSTAT,\ @@ -51,21 +53,12 @@ static const struct be_ethtool_stat et_stats[] = { {NETSTAT_INFO(tx_errors)}, {NETSTAT_INFO(rx_dropped)}, {NETSTAT_INFO(tx_dropped)}, - {DRVSTAT_INFO(be_tx_reqs)}, - {DRVSTAT_INFO(be_tx_stops)}, - {DRVSTAT_INFO(be_fwd_reqs)}, - {DRVSTAT_INFO(be_tx_wrbs)}, - {DRVSTAT_INFO(be_rx_polls)}, - {DRVSTAT_INFO(be_tx_events)}, - {DRVSTAT_INFO(be_rx_events)}, - {DRVSTAT_INFO(be_tx_compl)}, - {DRVSTAT_INFO(be_rx_compl)}, - {DRVSTAT_INFO(be_rx_mcast_pkt)}, - {DRVSTAT_INFO(be_ethrx_post_fail)}, - {DRVSTAT_INFO(be_802_3_dropped_frames)}, - {DRVSTAT_INFO(be_802_3_malformed_frames)}, - {DRVSTAT_INFO(be_tx_rate)}, - {DRVSTAT_INFO(be_rx_rate)}, + {DRVSTAT_TX_INFO(be_tx_rate)}, + {DRVSTAT_TX_INFO(be_tx_reqs)}, + {DRVSTAT_TX_INFO(be_tx_wrbs)}, + {DRVSTAT_TX_INFO(be_tx_stops)}, + {DRVSTAT_TX_INFO(be_tx_events)}, + {DRVSTAT_TX_INFO(be_tx_compl)}, {PORTSTAT_INFO(rx_unicast_frames)}, {PORTSTAT_INFO(rx_multicast_frames)}, {PORTSTAT_INFO(rx_broadcast_frames)}, @@ -106,11 +99,24 @@ static const struct be_ethtool_stat et_stats[] = { {MISCSTAT_INFO(rx_drops_too_many_frags)}, {MISCSTAT_INFO(rx_drops_invalid_ring)}, {MISCSTAT_INFO(forwarded_packets)}, - {MISCSTAT_INFO(rx_drops_mtu)}, - {ERXSTAT_INFO(rx_drops_no_fragments)}, + {MISCSTAT_INFO(rx_drops_mtu)} }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) +/* Stats related to multi RX queues */ +static const struct be_ethtool_stat et_rx_stats[] = { + {DRVSTAT_RX_INFO(rx_bytes)}, + {DRVSTAT_RX_INFO(rx_pkts)}, + {DRVSTAT_RX_INFO(rx_rate)}, + {DRVSTAT_RX_INFO(rx_polls)}, + {DRVSTAT_RX_INFO(rx_events)}, + {DRVSTAT_RX_INFO(rx_compl)}, + {DRVSTAT_RX_INFO(rx_mcast_pkts)}, + {DRVSTAT_RX_INFO(rx_post_fail)}, + {ERXSTAT_INFO(rx_drops_no_fragments)} +}; +#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) + static const char et_self_tests[][ETH_GSTRING_LEN] = { "MAC Loopback test", "PHY Loopback test", @@ -143,7 +149,7 @@ static int be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; @@ -167,25 +173,49 @@ static int be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_rx_obj *rxo; + struct be_eq_obj *rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; u32 tx_max, tx_min, tx_cur; u32 rx_max, rx_min, rx_cur; - int status = 0; + int status = 0, i; if (coalesce->use_adaptive_tx_coalesce == 1) return -EINVAL; - /* if AIC is being turned on now, start with an EQD of 0 */ - if (rx_eq->enable_aic == 0 && - coalesce->use_adaptive_rx_coalesce == 1) { - rx_eq->cur_eqd = 0; + for_all_rx_queues(adapter, rxo, i) { + rx_eq = &rxo->rx_eq; + + if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce) + rx_eq->cur_eqd = 0; + rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; + + rx_max = coalesce->rx_coalesce_usecs_high; + rx_min = coalesce->rx_coalesce_usecs_low; + rx_cur = coalesce->rx_coalesce_usecs; + + if (rx_eq->enable_aic) { + if (rx_max > BE_MAX_EQD) + rx_max = BE_MAX_EQD; + if (rx_min > rx_max) + rx_min = rx_max; + rx_eq->max_eqd = rx_max; + rx_eq->min_eqd = rx_min; + if (rx_eq->cur_eqd > rx_max) + rx_eq->cur_eqd = rx_max; + if (rx_eq->cur_eqd < rx_min) + rx_eq->cur_eqd = rx_min; + } else { + if (rx_cur > BE_MAX_EQD) + rx_cur = BE_MAX_EQD; + if (rx_eq->cur_eqd != rx_cur) { + status = be_cmd_modify_eqd(adapter, rx_eq->q.id, + rx_cur); + if (!status) + rx_eq->cur_eqd = rx_cur; + } + } } - rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; - - rx_max = coalesce->rx_coalesce_usecs_high; - rx_min = coalesce->rx_coalesce_usecs_low; - rx_cur = coalesce->rx_coalesce_usecs; tx_max = coalesce->tx_coalesce_usecs_high; tx_min = coalesce->tx_coalesce_usecs_low; @@ -199,27 +229,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) tx_eq->cur_eqd = tx_cur; } - if (rx_eq->enable_aic) { - if (rx_max > BE_MAX_EQD) - rx_max = BE_MAX_EQD; - if (rx_min > rx_max) - rx_min = rx_max; - rx_eq->max_eqd = rx_max; - rx_eq->min_eqd = rx_min; - if (rx_eq->cur_eqd > rx_max) - rx_eq->cur_eqd = rx_max; - if (rx_eq->cur_eqd < rx_min) - rx_eq->cur_eqd = rx_min; - } else { - if (rx_cur > BE_MAX_EQD) - rx_cur = BE_MAX_EQD; - if (rx_eq->cur_eqd != rx_cur) { - status = be_cmd_modify_eqd(adapter, rx_eq->q.id, - rx_cur); - if (!status) - rx_eq->cur_eqd = rx_cur; - } - } return 0; } @@ -247,32 +256,25 @@ be_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); - struct be_rxf_stats *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats *port_stats = - &rxf_stats->port[adapter->port_num]; - struct net_device_stats *net_stats = &netdev->stats; + struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); struct be_erx_stats *erx_stats = &hw_stats->erx; + struct be_rx_obj *rxo; void *p = NULL; - int i; + int i, j; for (i = 0; i < ETHTOOL_STATS_NUM; i++) { switch (et_stats[i].type) { case NETSTAT: - p = net_stats; + p = &netdev->stats; break; - case DRVSTAT: - p = drvr_stats; + case DRVSTAT_TX: + p = &adapter->tx_stats; break; case PORTSTAT: - p = port_stats; + p = &hw_stats->rxf.port[adapter->port_num]; break; case MISCSTAT: - p = rxf_stats; - break; - case ERXSTAT: /* Currently only one ERX stat is provided */ - p = (u32 *)erx_stats + adapter->rx_obj.q.id; + p = &hw_stats->rxf; break; } @@ -280,19 +282,44 @@ be_get_ethtool_stats(struct net_device *netdev, data[i] = (et_stats[i].size == sizeof(u64)) ? *(u64 *)p: *(u32 *)p; } + + for_all_rx_queues(adapter, rxo, j) { + for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { + switch (et_rx_stats[i].type) { + case DRVSTAT_RX: + p = (u8 *)&rxo->stats + et_rx_stats[i].offset; + break; + case ERXSTAT: + p = (u32 *)erx_stats + rxo->q.id; + break; + } + data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = + (et_rx_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; + } + } } static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) { - int i; + struct be_adapter *adapter = netdev_priv(netdev); + int i, j; + switch (stringset) { case ETH_SS_STATS: for (i = 0; i < ETHTOOL_STATS_NUM; i++) { memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); data += ETH_GSTRING_LEN; } + for (i = 0; i < adapter->num_rx_qs; i++) { + for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) { + sprintf(data, "rxq%d: %s", i, + et_rx_stats[j].desc); + data += ETH_GSTRING_LEN; + } + } break; case ETH_SS_TEST: for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { @@ -305,11 +332,14 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, static int be_get_sset_count(struct net_device *netdev, int stringset) { + struct be_adapter *adapter = netdev_priv(netdev); + switch (stringset) { case ETH_SS_TEST: return ETHTOOL_TESTS_NUM; case ETH_SS_STATS: - return ETHTOOL_STATS_NUM; + return ETHTOOL_STATS_NUM + + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; default: return -EINVAL; } @@ -424,10 +454,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct be_adapter *adapter = netdev_priv(netdev); - ring->rx_max_pending = adapter->rx_obj.q.len; + ring->rx_max_pending = adapter->rx_obj[0].q.len; ring->tx_max_pending = adapter->tx_obj.q.len; - ring->rx_pending = atomic_read(&adapter->rx_obj.q.used); + ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used); ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 43a3a574e2e0..9a1cd28b426d 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -32,6 +32,10 @@ module_param(num_vfs, uint, S_IRUGO); MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); +static bool multi_rxq = true; +module_param(multi_rxq, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default"); + static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, @@ -111,6 +115,11 @@ static char *ue_status_hi_desc[] = { "Unknown" }; +static inline bool be_multi_rxq(struct be_adapter *adapter) +{ + return (adapter->num_rx_qs > 1); +} + static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { struct be_dma_mem *mem = &q->dma_mem; @@ -236,18 +245,27 @@ netdev_addr: void netdev_stats_update(struct be_adapter *adapter) { - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); + struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_erx_stats *erx_stats = &hw_stats->erx; + struct be_rx_obj *rxo; + int i; - dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts; - dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; - dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; - dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; - dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt; + memset(dev_stats, 0, sizeof(*dev_stats)); + for_all_rx_queues(adapter, rxo, i) { + dev_stats->rx_packets += rx_stats(rxo)->rx_pkts; + dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; + dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; + /* no space in linux buffers: best possible approximation */ + dev_stats->rx_dropped += + erx_stats->rx_drops_no_fragments[rxo->q.id]; + } + + dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; + dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; /* bad pkts received */ dev_stats->rx_errors = port_stats->rx_crc_errors + @@ -264,18 +282,11 @@ void netdev_stats_update(struct be_adapter *adapter) port_stats->rx_ip_checksum_errs + port_stats->rx_udp_checksum_errs; - /* no space in linux buffers: best possible approximation */ - dev_stats->rx_dropped = - erx_stats->rx_drops_no_fragments[adapter->rx_obj.q.id]; - /* detailed rx errors */ dev_stats->rx_length_errors = port_stats->rx_in_range_errors + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; - /* receive ring buffer overflow */ - dev_stats->rx_over_errors = 0; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; /* frame alignment errors */ @@ -286,23 +297,6 @@ void netdev_stats_update(struct be_adapter *adapter) dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + port_stats->rx_input_fifo_overflow + rxf_stats->rx_drops_no_pbuf; - /* receiver missed packetd */ - dev_stats->rx_missed_errors = 0; - - /* packet transmit problems */ - dev_stats->tx_errors = 0; - - /* no space available in linux */ - dev_stats->tx_dropped = 0; - - dev_stats->collisions = 0; - - /* detailed tx_errors */ - dev_stats->tx_aborted_errors = 0; - dev_stats->tx_carrier_errors = 0; - dev_stats->tx_fifo_errors = 0; - dev_stats->tx_heartbeat_errors = 0; - dev_stats->tx_window_errors = 0; } void be_link_status_update(struct be_adapter *adapter, bool link_up) @@ -326,10 +320,10 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) } /* Update the EQ delay n BE based on the RX frags consumed / sec */ -static void be_rx_eqd_update(struct be_adapter *adapter) +static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) { - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_drvr_stats *stats = &adapter->stats.drvr_stats; + struct be_eq_obj *rx_eq = &rxo->rx_eq; + struct be_rx_stats *stats = &rxo->stats; ulong now = jiffies; u32 eqd; @@ -346,12 +340,12 @@ static void be_rx_eqd_update(struct be_adapter *adapter) if ((now - stats->rx_fps_jiffies) < HZ) return; - stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) / + stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) / ((now - stats->rx_fps_jiffies) / HZ); stats->rx_fps_jiffies = now; - stats->be_prev_rx_frags = stats->be_rx_frags; - eqd = stats->be_rx_fps / 110000; + stats->prev_rx_frags = stats->rx_frags; + eqd = stats->rx_fps / 110000; eqd = eqd << 3; if (eqd > rx_eq->max_eqd) eqd = rx_eq->max_eqd; @@ -378,7 +372,7 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks) static void be_tx_rate_update(struct be_adapter *adapter) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_tx_stats *stats = tx_stats(adapter); ulong now = jiffies; /* Wrapped around? */ @@ -400,7 +394,7 @@ static void be_tx_rate_update(struct be_adapter *adapter) static void be_tx_stats_update(struct be_adapter *adapter, u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_tx_stats *stats = tx_stats(adapter); stats->be_tx_reqs++; stats->be_tx_wrbs += wrb_cnt; stats->be_tx_bytes += copied; @@ -651,14 +645,8 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - be_eq_notify(adapter, rx_eq->q.id, false, false, 0); - be_eq_notify(adapter, tx_eq->q.id, false, false, 0); adapter->vlan_grp = grp; - be_eq_notify(adapter, rx_eq->q.id, true, false, 0); - be_eq_notify(adapter, tx_eq->q.id, true, false, 0); } static void be_vlan_add_vid(struct net_device *netdev, u16 vid) @@ -820,40 +808,38 @@ static int be_set_vf_tx_rate(struct net_device *netdev, return status; } -static void be_rx_rate_update(struct be_adapter *adapter) +static void be_rx_rate_update(struct be_rx_obj *rxo) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_rx_stats *stats = &rxo->stats; ulong now = jiffies; /* Wrapped around */ - if (time_before(now, stats->be_rx_jiffies)) { - stats->be_rx_jiffies = now; + if (time_before(now, stats->rx_jiffies)) { + stats->rx_jiffies = now; return; } /* Update the rate once in two seconds */ - if ((now - stats->be_rx_jiffies) < 2 * HZ) + if ((now - stats->rx_jiffies) < 2 * HZ) return; - stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes - - stats->be_rx_bytes_prev, - now - stats->be_rx_jiffies); - stats->be_rx_jiffies = now; - stats->be_rx_bytes_prev = stats->be_rx_bytes; + stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev, + now - stats->rx_jiffies); + stats->rx_jiffies = now; + stats->rx_bytes_prev = stats->rx_bytes; } -static void be_rx_stats_update(struct be_adapter *adapter, +static void be_rx_stats_update(struct be_rx_obj *rxo, u32 pktsize, u16 numfrags, u8 pkt_type) { - struct be_drvr_stats *stats = drvr_stats(adapter); - - stats->be_rx_compl++; - stats->be_rx_frags += numfrags; - stats->be_rx_bytes += pktsize; - stats->be_rx_pkts++; + struct be_rx_stats *stats = &rxo->stats; + stats->rx_compl++; + stats->rx_frags += numfrags; + stats->rx_bytes += pktsize; + stats->rx_pkts++; if (pkt_type == BE_MULTICAST_PACKET) - stats->be_rx_mcast_pkt++; + stats->rx_mcast_pkts++; } static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) @@ -873,12 +859,14 @@ static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) } static struct be_rx_page_info * -get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) +get_rx_page_info(struct be_adapter *adapter, + struct be_rx_obj *rxo, + u16 frag_idx) { struct be_rx_page_info *rx_page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; - rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx]; + rx_page_info = &rxo->page_info_tbl[frag_idx]; BUG_ON(!rx_page_info->page); if (rx_page_info->last_page_user) { @@ -893,9 +881,10 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) /* Throwaway the data in the Rx completion */ static void be_rx_compl_discard(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) + struct be_rx_obj *rxo, + struct be_eth_rx_compl *rxcp) { - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; u16 rxq_idx, i, num_rcvd; @@ -903,7 +892,7 @@ static void be_rx_compl_discard(struct be_adapter *adapter, num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); put_page(page_info->page); memset(page_info, 0, sizeof(*page_info)); index_inc(&rxq_idx, rxq->len); @@ -914,11 +903,11 @@ static void be_rx_compl_discard(struct be_adapter *adapter, * skb_fill_rx_data forms a complete skb for an ether frame * indicated by rxcp. */ -static void skb_fill_rx_data(struct be_adapter *adapter, +static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, struct sk_buff *skb, struct be_eth_rx_compl *rxcp, u16 num_rcvd) { - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; u16 rxq_idx, i, j; u32 pktsize, hdr_len, curr_frag_len, size; @@ -929,7 +918,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); start = page_address(page_info->page) + page_info->page_offset; prefetch(start); @@ -967,7 +956,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, for (i = 1, j = 0; i < num_rcvd; i++) { size -= curr_frag_len; index_inc(&rxq_idx, rxq->len); - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); curr_frag_len = min(size, rx_frag_size); @@ -993,11 +982,12 @@ static void skb_fill_rx_data(struct be_adapter *adapter, BUG_ON(j > MAX_SKB_FRAGS); done: - be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type); + be_rx_stats_update(rxo, pktsize, num_rcvd, pkt_type); } /* Process the RX completion indicated by rxcp when GRO is disabled */ static void be_rx_compl_process(struct be_adapter *adapter, + struct be_rx_obj *rxo, struct be_eth_rx_compl *rxcp) { struct sk_buff *skb; @@ -1014,11 +1004,11 @@ static void be_rx_compl_process(struct be_adapter *adapter, if (unlikely(!skb)) { if (net_ratelimit()) dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); - be_rx_compl_discard(adapter, rxcp); + be_rx_compl_discard(adapter, rxo, rxcp); return; } - skb_fill_rx_data(adapter, skb, rxcp, num_rcvd); + skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd); if (do_pkt_csum(rxcp, adapter->rx_csum)) skb_checksum_none_assert(skb); @@ -1051,12 +1041,13 @@ static void be_rx_compl_process(struct be_adapter *adapter, /* Process the RX completion indicated by rxcp when GRO is enabled */ static void be_rx_compl_process_gro(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) + struct be_rx_obj *rxo, + struct be_eth_rx_compl *rxcp) { struct be_rx_page_info *page_info; struct sk_buff *skb = NULL; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_eq_obj *eq_obj = &adapter->rx_eq; + struct be_queue_info *rxq = &rxo->q; + struct be_eq_obj *eq_obj = &rxo->rx_eq; u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; u16 i, rxq_idx = 0, vid, j; u8 vtm; @@ -1080,13 +1071,13 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, skb = napi_get_frags(&eq_obj->napi); if (!skb) { - be_rx_compl_discard(adapter, rxcp); + be_rx_compl_discard(adapter, rxo, rxcp); return; } remaining = pkt_size; for (i = 0, j = -1; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); curr_frag_len = min(remaining, rx_frag_size); @@ -1127,12 +1118,12 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); } - be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type); + be_rx_stats_update(rxo, pkt_size, num_rcvd, pkt_type); } -static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) +static struct be_eth_rx_compl *be_rx_compl_get(struct be_rx_obj *rxo) { - struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq); + struct be_eth_rx_compl *rxcp = queue_tail_node(&rxo->cq); if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) return NULL; @@ -1140,7 +1131,7 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) rmb(); be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); - queue_tail_inc(&adapter->rx_obj.cq); + queue_tail_inc(&rxo->cq); return rxcp; } @@ -1166,22 +1157,23 @@ static inline struct page *be_alloc_pages(u32 size) * Allocate a page, split it to fragments of size rx_frag_size and post as * receive buffers to BE */ -static void be_post_rx_frags(struct be_adapter *adapter) +static void be_post_rx_frags(struct be_rx_obj *rxo) { - struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; + struct be_adapter *adapter = rxo->adapter; + struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl; struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct page *pagep = NULL; struct be_eth_rx_d *rxd; u64 page_dmaaddr = 0, frag_dmaaddr; u32 posted, page_offset = 0; - page_info = &page_info_tbl[rxq->head]; + page_info = &rxo->page_info_tbl[rxq->head]; for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { if (!pagep) { pagep = be_alloc_pages(adapter->big_page_size); if (unlikely(!pagep)) { - drvr_stats(adapter)->be_ethrx_post_fail++; + rxo->stats.rx_post_fail++; break; } page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, @@ -1220,7 +1212,7 @@ static void be_post_rx_frags(struct be_adapter *adapter) be_rxq_notify(adapter, rxq->id, posted); } else if (atomic_read(&rxq->used) == 0) { /* Let be_worker replenish when memory is available */ - adapter->rx_post_starved = true; + rxo->rx_post_starved = true; } } @@ -1323,17 +1315,17 @@ static void be_eq_clean(struct be_adapter *adapter, be_eq_notify(adapter, eq_obj->q.id, false, true, num); } -static void be_rx_q_clean(struct be_adapter *adapter) +static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) { struct be_rx_page_info *page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; + struct be_queue_info *rxq = &rxo->q; + struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u16 tail; /* First cleanup pending rx completions */ - while ((rxcp = be_rx_compl_get(adapter)) != NULL) { - be_rx_compl_discard(adapter, rxcp); + while ((rxcp = be_rx_compl_get(rxo)) != NULL) { + be_rx_compl_discard(adapter, rxo, rxcp); be_rx_compl_reset(rxcp); be_cq_notify(adapter, rx_cq->id, true, 1); } @@ -1341,7 +1333,7 @@ static void be_rx_q_clean(struct be_adapter *adapter) /* Then free posted rx buffer that were not used */ tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) { - page_info = get_rx_page_info(adapter, tail); + page_info = get_rx_page_info(adapter, rxo, tail); put_page(page_info->page); memset(page_info, 0, sizeof(*page_info)); } @@ -1519,92 +1511,101 @@ tx_eq_free: static void be_rx_queues_destroy(struct be_adapter *adapter) { struct be_queue_info *q; - - q = &adapter->rx_obj.q; - if (q->created) { - be_cmd_q_destroy(adapter, q, QTYPE_RXQ); - - /* After the rxq is invalidated, wait for a grace time - * of 1ms for all dma to end and the flush compl to arrive - */ - mdelay(1); - be_rx_q_clean(adapter); + struct be_rx_obj *rxo; + int i; + + for_all_rx_queues(adapter, rxo, i) { + q = &rxo->q; + if (q->created) { + be_cmd_q_destroy(adapter, q, QTYPE_RXQ); + /* After the rxq is invalidated, wait for a grace time + * of 1ms for all dma to end and the flush compl to + * arrive + */ + mdelay(1); + be_rx_q_clean(adapter, rxo); + } + be_queue_free(adapter, q); + + q = &rxo->cq; + if (q->created) + be_cmd_q_destroy(adapter, q, QTYPE_CQ); + be_queue_free(adapter, q); + + /* Clear any residual events */ + q = &rxo->rx_eq.q; + if (q->created) { + be_eq_clean(adapter, &rxo->rx_eq); + be_cmd_q_destroy(adapter, q, QTYPE_EQ); + } + be_queue_free(adapter, q); } - be_queue_free(adapter, q); - - q = &adapter->rx_obj.cq; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_CQ); - be_queue_free(adapter, q); - - /* Clear any residual events */ - be_eq_clean(adapter, &adapter->rx_eq); - - q = &adapter->rx_eq.q; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_EQ); - be_queue_free(adapter, q); } static int be_rx_queues_create(struct be_adapter *adapter) { struct be_queue_info *eq, *q, *cq; - int rc; + struct be_rx_obj *rxo; + int rc, i; adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; - adapter->rx_eq.max_eqd = BE_MAX_EQD; - adapter->rx_eq.min_eqd = 0; - adapter->rx_eq.cur_eqd = 0; - adapter->rx_eq.enable_aic = true; - - /* Alloc Rx Event queue */ - eq = &adapter->rx_eq.q; - rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, - sizeof(struct be_eq_entry)); - if (rc) - return rc; - - /* Ask BE to create Rx Event queue */ - rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd); - if (rc) - goto rx_eq_free; - - /* Alloc RX eth compl queue */ - cq = &adapter->rx_obj.cq; - rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, - sizeof(struct be_eth_rx_compl)); - if (rc) - goto rx_eq_destroy; - - /* Ask BE to create Rx eth compl queue */ - rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); - if (rc) - goto rx_cq_free; - - /* Alloc RX eth queue */ - q = &adapter->rx_obj.q; - rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); - if (rc) - goto rx_cq_destroy; - - /* Ask BE to create Rx eth queue */ - rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, - BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false); - if (rc) - goto rx_q_free; + for_all_rx_queues(adapter, rxo, i) { + rxo->adapter = adapter; + rxo->rx_eq.max_eqd = BE_MAX_EQD; + rxo->rx_eq.enable_aic = true; + + /* EQ */ + eq = &rxo->rx_eq.q; + rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, + sizeof(struct be_eq_entry)); + if (rc) + goto err; + + rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd); + if (rc) + goto err; + + /* CQ */ + cq = &rxo->cq; + rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, + sizeof(struct be_eth_rx_compl)); + if (rc) + goto err; + + rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); + if (rc) + goto err; + + /* Rx Q */ + q = &rxo->q; + rc = be_queue_alloc(adapter, q, RX_Q_LEN, + sizeof(struct be_eth_rx_d)); + if (rc) + goto err; + + rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, + BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, + (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id); + if (rc) + goto err; + } + + if (be_multi_rxq(adapter)) { + u8 rsstable[MAX_RSS_QS]; + + for_all_rss_queues(adapter, rxo, i) + rsstable[i] = rxo->rss_id; + + rc = be_cmd_rss_config(adapter, rsstable, + adapter->num_rx_qs - 1); + if (rc) + goto err; + } return 0; -rx_q_free: - be_queue_free(adapter, q); -rx_cq_destroy: - be_cmd_q_destroy(adapter, cq, QTYPE_CQ); -rx_cq_free: - be_queue_free(adapter, cq); -rx_eq_destroy: - be_cmd_q_destroy(adapter, eq, QTYPE_EQ); -rx_eq_free: - be_queue_free(adapter, eq); - return rc; +err: + be_rx_queues_destroy(adapter); + return -1; } /* There are 8 evt ids per func. Retruns the evt id's bit number */ @@ -1616,24 +1617,31 @@ static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) static irqreturn_t be_intx(int irq, void *dev) { struct be_adapter *adapter = dev; - int isr; + struct be_rx_obj *rxo; + int isr, i; isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); if (!isr) return IRQ_NONE; - event_handle(adapter, &adapter->tx_eq); - event_handle(adapter, &adapter->rx_eq); + if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr)) + event_handle(adapter, &adapter->tx_eq); + + for_all_rx_queues(adapter, rxo, i) { + if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr)) + event_handle(adapter, &rxo->rx_eq); + } return IRQ_HANDLED; } static irqreturn_t be_msix_rx(int irq, void *dev) { - struct be_adapter *adapter = dev; + struct be_rx_obj *rxo = dev; + struct be_adapter *adapter = rxo->adapter; - event_handle(adapter, &adapter->rx_eq); + event_handle(adapter, &rxo->rx_eq); return IRQ_HANDLED; } @@ -1647,14 +1655,14 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) return IRQ_HANDLED; } -static inline bool do_gro(struct be_adapter *adapter, +static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo, struct be_eth_rx_compl *rxcp) { int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); if (err) - drvr_stats(adapter)->be_rxcp_err++; + rxo->stats.rxcp_err++; return (tcp_frame && !err) ? true : false; } @@ -1662,29 +1670,29 @@ static inline bool do_gro(struct be_adapter *adapter, int be_poll_rx(struct napi_struct *napi, int budget) { struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); - struct be_adapter *adapter = - container_of(rx_eq, struct be_adapter, rx_eq); - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; + struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); + struct be_adapter *adapter = rxo->adapter; + struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u32 work_done; - adapter->stats.drvr_stats.be_rx_polls++; + rxo->stats.rx_polls++; for (work_done = 0; work_done < budget; work_done++) { - rxcp = be_rx_compl_get(adapter); + rxcp = be_rx_compl_get(rxo); if (!rxcp) break; - if (do_gro(adapter, rxcp)) - be_rx_compl_process_gro(adapter, rxcp); + if (do_gro(adapter, rxo, rxcp)) + be_rx_compl_process_gro(adapter, rxo, rxcp); else - be_rx_compl_process(adapter, rxcp); + be_rx_compl_process(adapter, rxo, rxcp); be_rx_compl_reset(rxcp); } /* Refill the queue */ - if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM) - be_post_rx_frags(adapter); + if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM) + be_post_rx_frags(rxo); /* All consumed */ if (work_done < budget) { @@ -1738,8 +1746,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) netif_wake_queue(adapter->netdev); } - drvr_stats(adapter)->be_tx_events++; - drvr_stats(adapter)->be_tx_compl += tx_compl; + tx_stats(adapter)->be_tx_events++; + tx_stats(adapter)->be_tx_compl += tx_compl; } return 1; @@ -1788,20 +1796,24 @@ static void be_worker(struct work_struct *work) { struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); + struct be_rx_obj *rxo; + int i; if (!adapter->stats_ioctl_sent) - be_cmd_get_stats(adapter, &adapter->stats.cmd); - - /* Set EQ delay */ - be_rx_eqd_update(adapter); + be_cmd_get_stats(adapter, &adapter->stats_cmd); be_tx_rate_update(adapter); - be_rx_rate_update(adapter); - if (adapter->rx_post_starved) { - adapter->rx_post_starved = false; - be_post_rx_frags(adapter); + for_all_rx_queues(adapter, rxo, i) { + be_rx_rate_update(rxo); + be_rx_eqd_update(adapter, rxo); + + if (rxo->rx_post_starved) { + rxo->rx_post_starved = false; + be_post_rx_frags(rxo); + } } + if (!adapter->ue_detected) be_detect_dump_ue(adapter); @@ -1816,17 +1828,45 @@ static void be_msix_disable(struct be_adapter *adapter) } } +static int be_num_rxqs_get(struct be_adapter *adapter) +{ + if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && + !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { + return 1 + MAX_RSS_QS; /* one default non-RSS queue */ + } else { + dev_warn(&adapter->pdev->dev, + "No support for multiple RX queues\n"); + return 1; + } +} + static void be_msix_enable(struct be_adapter *adapter) { +#define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ int i, status; - for (i = 0; i < BE_NUM_MSIX_VECTORS; i++) + adapter->num_rx_qs = be_num_rxqs_get(adapter); + + for (i = 0; i < (adapter->num_rx_qs + 1); i++) adapter->msix_entries[i].entry = i; status = pci_enable_msix(adapter->pdev, adapter->msix_entries, - BE_NUM_MSIX_VECTORS); - if (status == 0) - adapter->msix_enabled = true; + adapter->num_rx_qs + 1); + if (status == 0) { + goto done; + } else if (status >= BE_MIN_MSIX_VECTORS) { + if (pci_enable_msix(adapter->pdev, adapter->msix_entries, + status) == 0) { + adapter->num_rx_qs = status - 1; + dev_warn(&adapter->pdev->dev, + "Could alloc only %d MSIx vectors. " + "Using %d RX Qs\n", status, adapter->num_rx_qs); + goto done; + } + } + return; +done: + adapter->msix_enabled = true; } static void be_sriov_enable(struct be_adapter *adapter) @@ -1860,38 +1900,50 @@ static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) static int be_request_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, - void *handler, char *desc) + void *handler, char *desc, void *context) { struct net_device *netdev = adapter->netdev; int vec; sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); vec = be_msix_vec_get(adapter, eq_obj->q.id); - return request_irq(vec, handler, 0, eq_obj->desc, adapter); + return request_irq(vec, handler, 0, eq_obj->desc, context); } -static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj) +static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, + void *context) { int vec = be_msix_vec_get(adapter, eq_obj->q.id); - free_irq(vec, adapter); + free_irq(vec, context); } static int be_msix_register(struct be_adapter *adapter) { - int status; + struct be_rx_obj *rxo; + int status, i; + char qname[10]; - status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx"); + status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx", + adapter); if (status) goto err; - status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx"); - if (status) - goto free_tx_irq; + for_all_rx_queues(adapter, rxo, i) { + sprintf(qname, "rxq%d", i); + status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx, + qname, rxo); + if (status) + goto err_msix; + } return 0; -free_tx_irq: - be_free_irq(adapter, &adapter->tx_eq); +err_msix: + be_free_irq(adapter, &adapter->tx_eq, adapter); + + for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--) + be_free_irq(adapter, &rxo->rx_eq, rxo); + err: dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n", status); @@ -1931,6 +1983,8 @@ done: static void be_irq_unregister(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct be_rx_obj *rxo; + int i; if (!adapter->isr_registered) return; @@ -1942,8 +1996,11 @@ static void be_irq_unregister(struct be_adapter *adapter) } /* MSIx */ - be_free_irq(adapter, &adapter->tx_eq); - be_free_irq(adapter, &adapter->rx_eq); + be_free_irq(adapter, &adapter->tx_eq, adapter); + + for_all_rx_queues(adapter, rxo, i) + be_free_irq(adapter, &rxo->rx_eq, rxo); + done: adapter->isr_registered = false; } @@ -1951,9 +2008,9 @@ done: static int be_close(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_rx_obj *rxo; struct be_eq_obj *tx_eq = &adapter->tx_eq; - int vec; + int vec, i; cancel_delayed_work_sync(&adapter->work); @@ -1968,14 +2025,19 @@ static int be_close(struct net_device *netdev) if (adapter->msix_enabled) { vec = be_msix_vec_get(adapter, tx_eq->q.id); synchronize_irq(vec); - vec = be_msix_vec_get(adapter, rx_eq->q.id); - synchronize_irq(vec); + + for_all_rx_queues(adapter, rxo, i) { + vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id); + synchronize_irq(vec); + } } else { synchronize_irq(netdev->irq); } be_irq_unregister(adapter); - napi_disable(&rx_eq->napi); + for_all_rx_queues(adapter, rxo, i) + napi_disable(&rxo->rx_eq.napi); + napi_disable(&tx_eq->napi); /* Wait for all pending tx completions to arrive so that @@ -1989,17 +2051,17 @@ static int be_close(struct net_device *netdev) static int be_open(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; + struct be_rx_obj *rxo; bool link_up; - int status; + int status, i; u8 mac_speed; u16 link_speed; - /* First time posting */ - be_post_rx_frags(adapter); - - napi_enable(&rx_eq->napi); + for_all_rx_queues(adapter, rxo, i) { + be_post_rx_frags(rxo); + napi_enable(&rxo->rx_eq.napi); + } napi_enable(&tx_eq->napi); be_irq_register(adapter); @@ -2007,12 +2069,12 @@ static int be_open(struct net_device *netdev) be_intr_set(adapter, true); /* The evt queues are created in unarmed state; arm them */ - be_eq_notify(adapter, rx_eq->q.id, true, false, 0); + for_all_rx_queues(adapter, rxo, i) { + be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0); + be_cq_notify(adapter, rxo->cq.id, true, 0); + } be_eq_notify(adapter, tx_eq->q.id, true, false, 0); - /* Rx compl queue may be in unarmed state; rearm it */ - be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); - /* Now that interrupts are on we can process async mcc */ be_async_mcc_enable(adapter); @@ -2088,7 +2150,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) static inline int be_vf_eth_addr_config(struct be_adapter *adapter) { u32 vf = 0; - int status; + int status = 0; u8 mac[ETH_ALEN]; be_vf_eth_addr_generate(adapter, mac); @@ -2134,6 +2196,11 @@ static int be_setup(struct be_adapter *adapter) BE_IF_FLAGS_PROMISCUOUS | BE_IF_FLAGS_PASS_L3L4_ERRORS; en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; + + if (be_multi_rxq(adapter)) { + cap_flags |= BE_IF_FLAGS_RSS; + en_flags |= BE_IF_FLAGS_RSS; + } } status = be_cmd_if_create(adapter, cap_flags, en_flags, @@ -2455,6 +2522,8 @@ static struct net_device_ops be_netdev_ops = { static void be_netdev_init(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); + struct be_rx_obj *rxo; + int i; netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM | @@ -2476,8 +2545,10 @@ static void be_netdev_init(struct net_device *netdev) SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); - netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, - BE_NAPI_WEIGHT); + for_all_rx_queues(adapter, rxo, i) + netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx, + BE_NAPI_WEIGHT); + netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, BE_NAPI_WEIGHT); @@ -2611,8 +2682,7 @@ done: static void be_stats_cleanup(struct be_adapter *adapter) { - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; + struct be_dma_mem *cmd = &adapter->stats_cmd; if (cmd->va) pci_free_consistent(adapter->pdev, cmd->size, @@ -2621,8 +2691,7 @@ static void be_stats_cleanup(struct be_adapter *adapter) static int be_stats_init(struct be_adapter *adapter) { - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; + struct be_dma_mem *cmd = &adapter->stats_cmd; cmd->size = sizeof(struct be_cmd_req_get_stats); cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); @@ -2667,8 +2736,8 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; - status = be_cmd_query_fw_cfg(adapter, - &adapter->port_num, &adapter->function_mode); + status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, + &adapter->function_mode, &adapter->function_caps); if (status) return status; @@ -2703,7 +2772,6 @@ static int __devinit be_probe(struct pci_dev *pdev, struct be_adapter *adapter; struct net_device *netdev; - status = pci_enable_device(pdev); if (status) goto do_none; @@ -2736,11 +2804,8 @@ static int __devinit be_probe(struct pci_dev *pdev, adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; - be_netdev_init(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); - be_msix_enable(adapter); - status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); if (!status) { netdev->features |= NETIF_F_HIGHDMA; @@ -2784,12 +2849,15 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto stats_clean; + be_msix_enable(adapter); + INIT_DELAYED_WORK(&adapter->work, be_worker); status = be_setup(adapter); if (status) - goto stats_clean; + goto msix_disable; + be_netdev_init(netdev); status = register_netdev(netdev); if (status != 0) goto unsetup; @@ -2799,12 +2867,13 @@ static int __devinit be_probe(struct pci_dev *pdev, unsetup: be_clear(adapter); +msix_disable: + be_msix_disable(adapter); stats_clean: be_stats_cleanup(adapter); ctrl_clean: be_ctrl_cleanup(adapter); free_netdev: - be_msix_disable(adapter); be_sriov_disable(adapter); free_netdev(adapter->netdev); pci_set_drvdata(pdev, NULL); -- cgit v1.2.3 From 9a7241c21b06c3a3f8ebcf3e347bd68556369da7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 3 Oct 2010 22:14:37 -0700 Subject: sctp: Fix break indentation in sctp_ioctl(). Signed-off-by: David S. Miller --- net/sctp/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 535659fdbaa1..d4bf2a78cb8a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3617,8 +3617,8 @@ SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) amount = skb->len; } rc = put_user(amount, (int __user *)arg); - } break; + } default: rc = -ENOIOCTLCMD; break; -- cgit v1.2.3 From c7d4426a98a5f6654cd0b4b33d9dab2e77192c18 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 3 Oct 2010 22:17:54 -0700 Subject: net: introduce DST_NOCACHE flag While doing stress tests with IP route cache disabled, and multi queue devices, I noticed a very high contention on one rwlock used in neighbour code. When many cpus are trying to send frames (possibly using a high performance multiqueue device) to the same neighbour, they fight for the neigh->lock rwlock in order to call neigh_hh_init(), and fight on hh->hh_refcnt (a pair of atomic_inc/atomic_dec_and_test()) But we dont need to call neigh_hh_init() for dst that are used only once. It costs four atomic operations at least, on two contended cache lines, plus the high contention on neigh->lock rwlock. Introduce a new dst flag, DST_NOCACHE, that is set when dst was not inserted in route cache. With the stress test bench, sending 160000000 frames on one neighbour, results are : Before patch: real 2m28.406s user 0m11.781s sys 36m17.964s After patch: real 1m26.532s user 0m12.185s sys 20m3.903s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/dst.h | 9 +++++---- net/core/neighbour.c | 4 +++- net/ipv4/route.c | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index aa53fbc34b2b..a217c838ec0d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -43,10 +43,11 @@ struct dst_entry { short error; short obsolete; int flags; -#define DST_HOST 1 -#define DST_NOXFRM 2 -#define DST_NOPOLICY 4 -#define DST_NOHASH 8 +#define DST_HOST 0x0001 +#define DST_NOXFRM 0x0002 +#define DST_NOPOLICY 0x0004 +#define DST_NOHASH 0x0008 +#define DST_NOCACHE 0x0010 unsigned long expires; unsigned short header_len; /* more space at head required */ diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 96b1a749abb4..b142a0d76072 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1210,7 +1210,9 @@ int neigh_resolve_output(struct sk_buff *skb) if (!neigh_event_send(neigh, skb)) { int err; struct net_device *dev = neigh->dev; - if (dev->header_ops->cache && !dst->hh) { + if (dev->header_ops->cache && + !dst->hh && + !(dst->flags & DST_NOCACHE)) { write_lock_bh(&neigh->lock); if (!dst->hh) neigh_hh_init(neigh, dst, dst->ops->protocol); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a61acea975f1..c3cb8bd23638 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1107,6 +1107,7 @@ restart: * on the route gc list. */ + rt->dst.flags |= DST_NOCACHE; if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->dst); if (err) { -- cgit v1.2.3 From 5adbb9fb0c35c38022f79e09fecf15ba8f65f069 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:51 +0900 Subject: netfilter: nf_conntrack_sip: Allow ct_sip_get_header() to be called with a null ct argument Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/nf_conntrack_sip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 53d892210a04..2fd1ea2c1bb3 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -152,6 +152,9 @@ static int parse_addr(const struct nf_conn *ct, const char *cp, const char *end; int ret = 0; + if (!ct) + return 0; + memset(addr, 0, sizeof(*addr)); switch (nf_ct_l3num(ct)) { case AF_INET: -- cgit v1.2.3 From 001985b2c0cfad48e1dec8e30f4d432eac240dd2 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:51 +0900 Subject: netfilter: nf_conntrack_sip: Add callid parser Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/linux/netfilter/nf_conntrack_sip.h | 1 + net/netfilter/nf_conntrack_sip.c | 39 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index ff8cfbcf3b81..0ce91d56a5f2 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -89,6 +89,7 @@ enum sip_header_types { SIP_HDR_VIA_TCP, SIP_HDR_EXPIRES, SIP_HDR_CONTENT_LENGTH, + SIP_HDR_CALL_ID, }; enum sdp_header_types { diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 2fd1ea2c1bb3..715ce54d2fc4 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -130,6 +130,44 @@ static int digits_len(const struct nf_conn *ct, const char *dptr, return len; } +static int iswordc(const char c) +{ + if (isalnum(c) || c == '!' || c == '"' || c == '%' || + (c >= '(' && c <= '/') || c == ':' || c == '<' || c == '>' || + c == '?' || (c >= '[' && c <= ']') || c == '_' || c == '`' || + c == '{' || c == '}' || c == '~') + return 1; + return 0; +} + +static int word_len(const char *dptr, const char *limit) +{ + int len = 0; + while (dptr < limit && iswordc(*dptr)) { + dptr++; + len++; + } + return len; +} + +static int callid_len(const struct nf_conn *ct, const char *dptr, + const char *limit, int *shift) +{ + int len, domain_len; + + len = word_len(dptr, limit); + dptr += len; + if (!len || dptr == limit || *dptr != '@') + return len; + dptr++; + len++; + + domain_len = word_len(dptr, limit); + if (!domain_len) + return 0; + return len + domain_len; +} + /* get media type + port length */ static int media_len(const struct nf_conn *ct, const char *dptr, const char *limit, int *shift) @@ -299,6 +337,7 @@ static const struct sip_header ct_sip_hdrs[] = { [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len), [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len), [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len), + [SIP_HDR_CALL_ID] = SIP_HDR("Call-Id", "i", NULL, callid_len), }; static const char *sip_follow_continuation(const char *dptr, const char *limit) -- cgit v1.2.3 From 5b57a98c1f0d78a4c238d83c4ac70de3bd237b2f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:51 +0900 Subject: IPVS: compact ip_vs_sched_persist() Compact ip_vs_sched_persist() by setting up parameters and calling functions once. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/ipvs/ip_vs_core.c | 156 +++++++++++++--------------------------- 1 file changed, 51 insertions(+), 105 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 06c388bf4e33..70a5cacf86d5 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -193,10 +193,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, struct ip_vs_iphdr iph; struct ip_vs_dest *dest; struct ip_vs_conn *ct; - __be16 dport; /* destination port to forward */ + int protocol = iph.protocol; + __be16 dport = 0; /* destination port to forward */ + __be16 vport = 0; /* virtual service port */ unsigned int flags; union nf_inet_addr snet; /* source network of the client, after masking */ + const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; + const union nf_inet_addr *vaddr = &iph.daddr; ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); @@ -227,119 +231,61 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * service, and a template like * is created for other persistent services. */ - if (ports[1] == svc->port) { - /* Check if a template already exists */ - if (svc->port != FTPPORT) - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, ports[1]); - else - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, 0); - - if (!ct || !ip_vs_check_template(ct)) { - /* - * No template found or the dest of the connection - * template is not available. - */ - dest = svc->scheduler->schedule(svc, skb); - if (dest == NULL) { - IP_VS_DBG(1, "p-schedule: no dest found.\n"); - return NULL; - } - - /* - * Create a template like for non-ftp service, - * and - * for ftp service. + { + if (ports[1] == svc->port) { + /* non-FTP template: + * + * FTP template: + * */ if (svc->port != FTPPORT) - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, - ports[1], - &dest->addr, dest->port, - IP_VS_CONN_F_TEMPLATE, - dest); - else - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - if (ct == NULL) - return NULL; - - ct->timeout = svc->timeout; + vport = ports[1]; } else { - /* set destination with the found template */ - dest = ct->dest; + /* Note: persistent fwmark-based services and + * persistent port zero service are handled here. + * fwmark template: + * + * port zero template: + * + */ + if (svc->fwmark) { + protocol = IPPROTO_IP; + vaddr = &fwmark; + } } - dport = dest->port; - } else { - /* - * Note: persistent fwmark-based services and persistent - * port zero service are handled here. - * fwmark template: - * port zero template: + } + + /* Check if a template already exists */ + ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport); + + if (!ct || !ip_vs_check_template(ct)) { + /* No template found or the dest of the connection + * template is not available. */ - if (svc->fwmark) { - union nf_inet_addr fwmark = { - .ip = htonl(svc->fwmark) - }; + dest = svc->scheduler->schedule(svc, skb); + if (!dest) { + IP_VS_DBG(1, "p-schedule: no dest found.\n"); + return NULL; + } - ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0, - &fwmark, 0); - } else - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, 0); + if (ports[1] == svc->port && svc->port != FTPPORT) + dport = dest->port; - if (!ct || !ip_vs_check_template(ct)) { - /* - * If it is not persistent port zero, return NULL, - * otherwise create a connection template. - */ - if (svc->port) - return NULL; + /* Create a template */ + ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport, + &dest->addr, dport, + IP_VS_CONN_F_TEMPLATE, dest); + if (ct == NULL) + return NULL; - dest = svc->scheduler->schedule(svc, skb); - if (dest == NULL) { - IP_VS_DBG(1, "p-schedule: no dest found.\n"); - return NULL; - } + ct->timeout = svc->timeout; + } else + /* set destination with the found template */ + dest = ct->dest; - /* - * Create a template according to the service - */ - if (svc->fwmark) { - union nf_inet_addr fwmark = { - .ip = htonl(svc->fwmark) - }; - - ct = ip_vs_conn_new(svc->af, IPPROTO_IP, - &snet, 0, - &fwmark, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - } else - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - if (ct == NULL) - return NULL; - - ct->timeout = svc->timeout; - } else { - /* set destination with the found template */ - dest = ct->dest; - } - dport = ports[1]; - } + dport = ports[1]; + if (dport == svc->port && dest->port) + dport = dest->port; flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && iph.protocol == IPPROTO_UDP)? -- cgit v1.2.3 From f11017ec2d1859c661f4e2b12c4a8d250e1f47cf Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:52 +0900 Subject: IPVS: Add struct ip_vs_conn_param Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/net/ip_vs.h | 44 +++++--- net/netfilter/ipvs/ip_vs_conn.c | 171 ++++++++++++++++---------------- net/netfilter/ipvs/ip_vs_core.c | 64 ++++++------ net/netfilter/ipvs/ip_vs_ftp.c | 43 ++++---- net/netfilter/ipvs/ip_vs_nfct.c | 12 +-- net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 47 ++++----- net/netfilter/ipvs/ip_vs_sync.c | 33 +++--- 7 files changed, 211 insertions(+), 203 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 3915a4f4cd30..d4da774eca75 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -357,6 +357,15 @@ struct ip_vs_protocol { extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); +struct ip_vs_conn_param { + const union nf_inet_addr *caddr; + const union nf_inet_addr *vaddr; + __be16 cport; + __be16 vport; + __u16 protocol; + u16 af; +}; + /* * IP_VS structure allocated for each dynamically scheduled connection */ @@ -626,13 +635,23 @@ enum { IP_VS_DIR_LAST, }; -extern struct ip_vs_conn *ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +static inline void ip_vs_conn_fill_param(int af, int protocol, + const union nf_inet_addr *caddr, + __be16 cport, + const union nf_inet_addr *vaddr, + __be16 vport, + struct ip_vs_conn_param *p) +{ + p->af = af; + p->protocol = protocol; + p->caddr = caddr; + p->cport = cport; + p->vaddr = vaddr; + p->vport = vport; +} -extern struct ip_vs_conn *ip_vs_ct_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -640,9 +659,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, unsigned int proto_off, int inverse); -extern struct ip_vs_conn *ip_vs_conn_out_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -658,11 +675,10 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) extern void ip_vs_conn_put(struct ip_vs_conn *cp); extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); -extern struct ip_vs_conn * -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, - const union nf_inet_addr *vaddr, __be16 vport, - const union nf_inet_addr *daddr, __be16 dport, unsigned flags, - struct ip_vs_dest *dest); +struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, + const union nf_inet_addr *daddr, + __be16 dport, unsigned flags, + struct ip_vs_dest *dest); extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); extern const char * ip_vs_state_name(__u16 proto, int state); diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index a970d9691496..deeb906a797b 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -218,27 +218,26 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) /* * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. * Called for pkts coming from OUTside-to-INside. - * s_addr, s_port: pkt source address (foreign host) - * d_addr, d_port: pkt dest address (load balancer) + * p->caddr, p->cport: pkt source address (foreign host) + * p->vaddr, p->vport: pkt dest address (load balancer) */ -static inline struct ip_vs_conn *__ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +static inline struct ip_vs_conn * +__ip_vs_conn_in_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, s_addr, &cp->caddr) && - ip_vs_addr_equal(af, d_addr, &cp->vaddr) && - s_port == cp->cport && d_port == cp->vport && - ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && - protocol == cp->protocol) { + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && + ip_vs_addr_equal(p->af, p->vaddr, &cp->vaddr) && + p->cport == cp->cport && p->vport == cp->vport && + ((!p->cport) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && + p->protocol == cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); ct_read_unlock(hash); @@ -251,71 +250,82 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get return NULL; } -struct ip_vs_conn *ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p) { struct ip_vs_conn *cp; - cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port); - if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) - cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr, - d_port); + cp = __ip_vs_conn_in_get(p); + if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) { + struct ip_vs_conn_param cport_zero_p = *p; + cport_zero_p.cport = 0; + cp = __ip_vs_conn_in_get(&cport_zero_p); + } IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), cp ? "hit" : "not hit"); return cp; } +static int +ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, int inverse, + struct ip_vs_conn_param *p) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return 1; + + if (likely(!inverse)) + ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0], + &iph->daddr, pptr[1], p); + else + ip_vs_conn_fill_param(af, iph->protocol, &iph->daddr, pptr[1], + &iph->saddr, pptr[0], p); + return 0; +} + struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, const struct ip_vs_iphdr *iph, unsigned int proto_off, int inverse) { - __be16 _ports[2], *pptr; + struct ip_vs_conn_param p; - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) return NULL; - if (likely(!inverse)) - return ip_vs_conn_in_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_in_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); + return ip_vs_conn_in_get(&p); } EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto); /* Get reference to connection template */ -struct ip_vs_conn *ip_vs_ct_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, s_addr, &cp->caddr) && + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && /* protocol should only be IPPROTO_IP if - * d_addr is a fwmark */ - ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af, - d_addr, &cp->vaddr) && - s_port == cp->cport && d_port == cp->vport && + * p->vaddr is a fwmark */ + ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : + p->af, p->vaddr, &cp->vaddr) && + p->cport == cp->cport && p->vport == cp->vport && cp->flags & IP_VS_CONN_F_TEMPLATE && - protocol == cp->protocol) { + p->protocol == cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); goto out; @@ -327,23 +337,19 @@ struct ip_vs_conn *ip_vs_ct_in_get ct_read_unlock(hash); IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), cp ? "hit" : "not hit"); return cp; } -/* - * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. - * Called for pkts coming from inside-to-OUTside. - * s_addr, s_port: pkt source address (inside host) - * d_addr, d_port: pkt dest address (foreign host) - */ -struct ip_vs_conn *ip_vs_conn_out_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +/* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. + * Called for pkts coming from inside-to-OUTside. + * p->caddr, p->cport: pkt source address (inside host) + * p->vaddr, p->vport: pkt dest address (foreign host) */ +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp, *ret=NULL; @@ -351,16 +357,16 @@ struct ip_vs_conn *ip_vs_conn_out_get /* * Check for "full" addressed entries */ - hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port); + hash = ip_vs_conn_hashkey(p->af, p->protocol, p->vaddr, p->vport); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, d_addr, &cp->caddr) && - ip_vs_addr_equal(af, s_addr, &cp->daddr) && - d_port == cp->cport && s_port == cp->dport && - protocol == cp->protocol) { + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) && + ip_vs_addr_equal(p->af, p->caddr, &cp->daddr) && + p->vport == cp->cport && p->cport == cp->dport && + p->protocol == cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); ret = cp; @@ -371,9 +377,9 @@ struct ip_vs_conn *ip_vs_conn_out_get ct_read_unlock(hash); IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), ret ? "hit" : "not hit"); return ret; @@ -385,20 +391,12 @@ ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, const struct ip_vs_iphdr *iph, unsigned int proto_off, int inverse) { - __be16 _ports[2], *pptr; + struct ip_vs_conn_param p; - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) return NULL; - if (likely(!inverse)) - return ip_vs_conn_out_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_out_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); + return ip_vs_conn_out_get(&p); } EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto); @@ -758,13 +756,12 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) * Create a new connection entry and hash it into the ip_vs_conn_tab */ struct ip_vs_conn * -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, - const union nf_inet_addr *vaddr, __be16 vport, +ip_vs_conn_new(const struct ip_vs_conn_param *p, const union nf_inet_addr *daddr, __be16 dport, unsigned flags, struct ip_vs_dest *dest) { struct ip_vs_conn *cp; - struct ip_vs_protocol *pp = ip_vs_proto_get(proto); + struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol); cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC); if (cp == NULL) { @@ -774,14 +771,14 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, INIT_LIST_HEAD(&cp->c_list); setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); - cp->af = af; - cp->protocol = proto; - ip_vs_addr_copy(af, &cp->caddr, caddr); - cp->cport = cport; - ip_vs_addr_copy(af, &cp->vaddr, vaddr); - cp->vport = vport; + cp->af = p->af; + cp->protocol = p->protocol; + ip_vs_addr_copy(p->af, &cp->caddr, p->caddr); + cp->cport = p->cport; + ip_vs_addr_copy(p->af, &cp->vaddr, p->vaddr); + cp->vport = p->vport; /* proto should only be IPPROTO_IP if d_addr is a fwmark */ - ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af, + ip_vs_addr_copy(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, &cp->daddr, daddr); cp->dport = dport; cp->flags = flags; @@ -810,7 +807,7 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, /* Bind its packet transmitter */ #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) + if (p->af == AF_INET6) ip_vs_bind_xmit_v6(cp); else #endif diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 70a5cacf86d5..87602a62458e 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -193,14 +193,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc, struct ip_vs_iphdr iph; struct ip_vs_dest *dest; struct ip_vs_conn *ct; - int protocol = iph.protocol; __be16 dport = 0; /* destination port to forward */ - __be16 vport = 0; /* virtual service port */ unsigned int flags; + struct ip_vs_conn_param param; union nf_inet_addr snet; /* source network of the client, after masking */ - const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; - const union nf_inet_addr *vaddr = &iph.daddr; ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); @@ -232,6 +229,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * is created for other persistent services. */ { + int protocol = iph.protocol; + const union nf_inet_addr *vaddr = &iph.daddr; + const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; + __be16 vport = 0; + if (ports[1] == svc->port) { /* non-FTP template: * @@ -253,11 +255,12 @@ ip_vs_sched_persist(struct ip_vs_service *svc, vaddr = &fwmark; } } + ip_vs_conn_fill_param(svc->af, protocol, &snet, 0, + vaddr, vport, ¶m); } /* Check if a template already exists */ - ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport); - + ct = ip_vs_ct_in_get(¶m); if (!ct || !ip_vs_check_template(ct)) { /* No template found or the dest of the connection * template is not available. @@ -272,8 +275,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, dport = dest->port; /* Create a template */ - ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport, - &dest->addr, dport, + ct = ip_vs_conn_new(¶m, &dest->addr, dport, IP_VS_CONN_F_TEMPLATE, dest); if (ct == NULL) return NULL; @@ -294,12 +296,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc, /* * Create a new connection according to the template */ - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, ports[0], - &iph.daddr, ports[1], - &dest->addr, dport, - flags, - dest); + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0], + &iph.daddr, ports[1], ¶m); + cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest); if (cp == NULL) { ip_vs_conn_put(ct); return NULL; @@ -366,14 +365,16 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) /* * Create a connection entry. */ - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, pptr[0], - &iph.daddr, pptr[1], - &dest->addr, dest->port ? dest->port : pptr[1], - flags, - dest); - if (cp == NULL) - return NULL; + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, + pptr[0], &iph.daddr, pptr[1], &p); + cp = ip_vs_conn_new(&p, &dest->addr, + dest->port ? dest->port : pptr[1], + flags, dest); + if (!cp) + return NULL; + } IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u " "d:%s:%u conn->flags:%X conn->refcnt:%d\n", @@ -429,14 +430,17 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, /* create a new connection entry */ IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, pptr[0], - &iph.daddr, pptr[1], - &daddr, 0, - IP_VS_CONN_F_BYPASS | flags, - NULL); - if (cp == NULL) - return NF_DROP; + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(svc->af, iph.protocol, + &iph.saddr, pptr[0], + &iph.daddr, pptr[1], &p); + cp = ip_vs_conn_new(&p, &daddr, 0, + IP_VS_CONN_F_BYPASS | flags, + NULL); + if (!cp) + return NF_DROP; + } /* statistics */ ip_vs_in_stats(cp, skb); diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 9cd375f94d61..090889a3b3af 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -195,13 +195,17 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, /* * Now update or create an connection entry for it */ - n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port, - &cp->caddr, 0); + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, iph->protocol, + &from, port, &cp->caddr, 0, &p); + n_cp = ip_vs_conn_out_get(&p); + } if (!n_cp) { - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, - &cp->caddr, 0, - &cp->vaddr, port, - &from, port, + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr, + 0, &cp->vaddr, port, &p); + n_cp = ip_vs_conn_new(&p, &from, port, IP_VS_CONN_F_NO_CPORT | IP_VS_CONN_F_NFCT, cp->dest); @@ -347,21 +351,22 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ip_vs_proto_name(iph->protocol), &to.ip, ntohs(port), &cp->vaddr.ip, 0); - n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol, - &to, port, - &cp->vaddr, htons(ntohs(cp->vport)-1)); - if (!n_cp) { - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, - &to, port, + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port, &cp->vaddr, htons(ntohs(cp->vport)-1), - &cp->daddr, htons(ntohs(cp->dport)-1), - IP_VS_CONN_F_NFCT, - cp->dest); - if (!n_cp) - return 0; + &p); + n_cp = ip_vs_conn_in_get(&p); + if (!n_cp) { + n_cp = ip_vs_conn_new(&p, &cp->daddr, + htons(ntohs(cp->dport)-1), + IP_VS_CONN_F_NFCT, cp->dest); + if (!n_cp) + return 0; - /* add its controller */ - ip_vs_control_add(n_cp, cp); + /* add its controller */ + ip_vs_control_add(n_cp, cp); + } } /* diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c index c038458d0290..4680647cd450 100644 --- a/net/netfilter/ipvs/ip_vs_nfct.c +++ b/net/netfilter/ipvs/ip_vs_nfct.c @@ -140,6 +140,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, { struct nf_conntrack_tuple *orig, new_reply; struct ip_vs_conn *cp; + struct ip_vs_conn_param p; if (exp->tuple.src.l3num != PF_INET) return; @@ -154,9 +155,10 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, /* RS->CLIENT */ orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); + ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum, + &orig->src.u3, orig->src.u.tcp.port, + &orig->dst.u3, orig->dst.u.tcp.port, &p); + cp = ip_vs_conn_out_get(&p); if (cp) { /* Change reply CLIENT->RS to CLIENT->VS */ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; @@ -176,9 +178,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct, } /* CLIENT->VS */ - cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); + cp = ip_vs_conn_in_get(&p); if (cp) { /* Change reply VS->CLIENT to RS->CLIENT */ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c index 1892dfc12fdd..8956ef33ea6c 100644 --- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c +++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c @@ -40,6 +40,19 @@ struct isakmp_hdr { #define PORT_ISAKMP 500 +static void +ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph, + int inverse, struct ip_vs_conn_param *p) +{ + if (likely(!inverse)) + ip_vs_conn_fill_param(af, IPPROTO_UDP, + &iph->saddr, htons(PORT_ISAKMP), + &iph->daddr, htons(PORT_ISAKMP), p); + else + ip_vs_conn_fill_param(af, IPPROTO_UDP, + &iph->daddr, htons(PORT_ISAKMP), + &iph->saddr, htons(PORT_ISAKMP), p); +} static struct ip_vs_conn * ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, int inverse) { struct ip_vs_conn *cp; + struct ip_vs_conn_param p; - if (likely(!inverse)) { - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, - &iph->saddr, - htons(PORT_ISAKMP), - &iph->daddr, - htons(PORT_ISAKMP)); - } else { - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, - &iph->daddr, - htons(PORT_ISAKMP), - &iph->saddr, - htons(PORT_ISAKMP)); - } - + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); + cp = ip_vs_conn_in_get(&p); if (!cp) { /* * We are not sure if the packet is from our @@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb, int inverse) { struct ip_vs_conn *cp; + struct ip_vs_conn_param p; - if (likely(!inverse)) { - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, - &iph->saddr, - htons(PORT_ISAKMP), - &iph->daddr, - htons(PORT_ISAKMP)); - } else { - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, - &iph->daddr, - htons(PORT_ISAKMP), - &iph->saddr, - htons(PORT_ISAKMP)); - } - + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); + cp = ip_vs_conn_out_get(&p); if (!cp) { IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet " "%s%s %s->%s\n", diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 7ba06939829f..f68631f75f09 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -301,6 +301,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) struct ip_vs_conn *cp; struct ip_vs_protocol *pp; struct ip_vs_dest *dest; + struct ip_vs_conn_param param; char *p; int i; @@ -370,18 +371,17 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } } - if (!(flags & IP_VS_CONN_F_TEMPLATE)) - cp = ip_vs_conn_in_get(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport); - else - cp = ip_vs_ct_in_get(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport); + { + ip_vs_conn_fill_param(AF_INET, s->protocol, + (union nf_inet_addr *)&s->caddr, + s->cport, + (union nf_inet_addr *)&s->vaddr, + s->vport, ¶m); + if (!(flags & IP_VS_CONN_F_TEMPLATE)) + cp = ip_vs_conn_in_get(¶m); + else + cp = ip_vs_ct_in_get(¶m); + } if (!cp) { /* * Find the appropriate destination for the connection. @@ -406,14 +406,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) else flags &= ~IP_VS_CONN_F_INACTIVE; } - cp = ip_vs_conn_new(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport, + cp = ip_vs_conn_new(¶m, (union nf_inet_addr *)&s->daddr, - s->dport, - flags, dest); + s->dport, flags, dest); if (dest) atomic_dec(&dest->refcnt); if (!cp) { -- cgit v1.2.3 From 6e08bfb879574524cc9a67be960c684989fd986c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:52 +0900 Subject: IPVS: Allow null argument to ip_vs_scheduler_put() This simplifies caller logic sightly. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/ipvs/ip_vs_ctl.c | 13 ++++--------- net/netfilter/ipvs/ip_vs_sched.c | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e4ec8f364f8b..f7afcfe4dbc5 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1144,7 +1144,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, if (sched == NULL) { pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name); ret = -ENOENT; - goto out_mod_dec; + goto out_err; } #ifdef CONFIG_IP_VS_IPV6 @@ -1204,7 +1204,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, *svc_p = svc; return 0; - out_err: + out_err: if (svc != NULL) { if (svc->scheduler) ip_vs_unbind_scheduler(svc); @@ -1217,7 +1217,6 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, } ip_vs_scheduler_put(sched); - out_mod_dec: /* decrease the module use count */ ip_vs_use_count_dec(); @@ -1300,10 +1299,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) #ifdef CONFIG_IP_VS_IPV6 out: #endif - - if (old_sched) - ip_vs_scheduler_put(old_sched); - + ip_vs_scheduler_put(old_sched); return ret; } @@ -1327,8 +1323,7 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) /* Unbind scheduler */ old_sched = svc->scheduler; ip_vs_unbind_scheduler(svc); - if (old_sched) - ip_vs_scheduler_put(old_sched); + ip_vs_scheduler_put(old_sched); /* Unbind app inc */ if (svc->inc) { diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index 727e45b66953..9f94e328d31e 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -159,7 +159,7 @@ struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name) void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler) { - if (scheduler->module) + if (scheduler && scheduler->module) module_put(scheduler->module); } -- cgit v1.2.3 From 2fabf35bfcd89445c54cf1e6a5437dd3cf924a92 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:52 +0900 Subject: IPVS: ip_vs_{un,}bind_scheduler NULL arguments In general NULL arguments aren't passed by the few callers that exist, so don't test for them. The exception is to make passing NULL to ip_vs_unbind_scheduler() a noop. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/ipvs/ip_vs_ctl.c | 3 +-- net/netfilter/ipvs/ip_vs_sched.c | 23 +++-------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index f7afcfe4dbc5..5f20caf47a1d 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1206,8 +1206,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, out_err: if (svc != NULL) { - if (svc->scheduler) - ip_vs_unbind_scheduler(svc); + ip_vs_unbind_scheduler(svc); if (svc->inc) { local_bh_disable(); ip_vs_app_inc_put(svc->inc); diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index 9f94e328d31e..076ebe00435d 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -46,15 +46,6 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc, { int ret; - if (svc == NULL) { - pr_err("%s(): svc arg NULL\n", __func__); - return -EINVAL; - } - if (scheduler == NULL) { - pr_err("%s(): scheduler arg NULL\n", __func__); - return -EINVAL; - } - svc->scheduler = scheduler; if (scheduler->init_service) { @@ -74,18 +65,10 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc, */ int ip_vs_unbind_scheduler(struct ip_vs_service *svc) { - struct ip_vs_scheduler *sched; + struct ip_vs_scheduler *sched = svc->scheduler; - if (svc == NULL) { - pr_err("%s(): svc arg NULL\n", __func__); - return -EINVAL; - } - - sched = svc->scheduler; - if (sched == NULL) { - pr_err("%s(): svc isn't bound\n", __func__); - return -EINVAL; - } + if (!sched) + return 0; if (sched->done_service) { if (sched->done_service(svc) != 0) { -- cgit v1.2.3 From 85999283a21ab2dd37427fdd8c8e8af57223977c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:53 +0900 Subject: IPVS: Add struct ip_vs_pe Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/linux/ip_vs.h | 2 ++ include/net/ip_vs.h | 28 ++++++++++++++++- net/netfilter/ipvs/ip_vs_conn.c | 67 ++++++++++++++++++++++++++++++++++------- net/netfilter/ipvs/ip_vs_core.c | 36 +++++++++++++++++----- net/netfilter/ipvs/ip_vs_sync.c | 17 +++++++++-- 5 files changed, 129 insertions(+), 21 deletions(-) diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index df7728613720..0a9c44d64292 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -99,8 +99,10 @@ 0) #define IP_VS_SCHEDNAME_MAXLEN 16 +#define IP_VS_PENAME_MAXLEN 16 #define IP_VS_IFNAME_MAXLEN 16 +#define IP_VS_PEDATA_MAXLEN 255 /* * The struct ip_vs_service_user and struct ip_vs_dest_user are diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index d4da774eca75..b6b309d05e4e 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -364,6 +364,10 @@ struct ip_vs_conn_param { __be16 vport; __u16 protocol; u16 af; + + const struct ip_vs_pe *pe; + char *pe_data; + __u8 pe_data_len; }; /* @@ -416,6 +420,9 @@ struct ip_vs_conn { void *app_data; /* Application private data */ struct ip_vs_seq in_seq; /* incoming seq. struct */ struct ip_vs_seq out_seq; /* outgoing seq. struct */ + + char *pe_data; + __u8 pe_data_len; }; @@ -486,6 +493,9 @@ struct ip_vs_service { struct ip_vs_scheduler *scheduler; /* bound scheduler object */ rwlock_t sched_lock; /* lock sched_data */ void *sched_data; /* scheduler application data */ + + /* alternate persistence engine */ + struct ip_vs_pe *pe; }; @@ -549,6 +559,20 @@ struct ip_vs_scheduler { const struct sk_buff *skb); }; +/* The persistence engine object */ +struct ip_vs_pe { + struct list_head n_list; /* d-linked list head */ + char *name; /* scheduler name */ + atomic_t refcnt; /* reference counter */ + struct module *module; /* THIS_MODULE/NULL */ + + /* get the connection template, if any */ + int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb); + bool (*ct_match)(const struct ip_vs_conn_param *p, + struct ip_vs_conn *ct); + u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval, + bool inverse); +}; /* * The application module object (a.k.a. app incarnation) @@ -648,6 +672,8 @@ static inline void ip_vs_conn_fill_param(int af, int protocol, p->cport = cport; p->vaddr = vaddr; p->vport = vport; + p->pe = NULL; + p->pe_data = NULL; } struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); @@ -803,7 +829,7 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); extern struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb); +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb); extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, struct ip_vs_protocol *pp); diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index deeb906a797b..06da21e97405 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -148,6 +148,42 @@ static unsigned int ip_vs_conn_hashkey(int af, unsigned proto, & ip_vs_conn_tab_mask; } +static unsigned int ip_vs_conn_hashkey_param(const struct ip_vs_conn_param *p, + bool inverse) +{ + const union nf_inet_addr *addr; + __be16 port; + + if (p->pe && p->pe->hashkey_raw) + return p->pe->hashkey_raw(p, ip_vs_conn_rnd, inverse) & + ip_vs_conn_tab_mask; + + if (likely(!inverse)) { + addr = p->caddr; + port = p->cport; + } else { + addr = p->vaddr; + port = p->vport; + } + + return ip_vs_conn_hashkey(p->af, p->protocol, addr, port); +} + +static unsigned int ip_vs_conn_hashkey_conn(const struct ip_vs_conn *cp) +{ + struct ip_vs_conn_param p; + + ip_vs_conn_fill_param(cp->af, cp->protocol, &cp->caddr, cp->cport, + NULL, 0, &p); + + if (cp->dest && cp->dest->svc->pe) { + p.pe = cp->dest->svc->pe; + p.pe_data = cp->pe_data; + p.pe_data_len = cp->pe_data_len; + } + + return ip_vs_conn_hashkey_param(&p, false); +} /* * Hashes ip_vs_conn in ip_vs_conn_tab by proto,addr,port. @@ -162,7 +198,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp) return 0; /* Hash by protocol, client address and port */ - hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + hash = ip_vs_conn_hashkey_conn(cp); ct_write_lock(hash); spin_lock(&cp->lock); @@ -195,7 +231,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) int ret; /* unhash it and decrease its reference counter */ - hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + hash = ip_vs_conn_hashkey_conn(cp); ct_write_lock(hash); spin_lock(&cp->lock); @@ -227,7 +263,7 @@ __ip_vs_conn_in_get(const struct ip_vs_conn_param *p) unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); + hash = ip_vs_conn_hashkey_param(p, false); ct_read_lock(hash); @@ -312,11 +348,17 @@ struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(p->af, p->protocol, p->caddr, p->cport); + hash = ip_vs_conn_hashkey_param(p, false); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { + if (p->pe && p->pe->ct_match) { + if (p->pe->ct_match(p, cp)) + goto out; + continue; + } + if (cp->af == p->af && ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && /* protocol should only be IPPROTO_IP if @@ -325,15 +367,14 @@ struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) p->af, p->vaddr, &cp->vaddr) && p->cport == cp->cport && p->vport == cp->vport && cp->flags & IP_VS_CONN_F_TEMPLATE && - p->protocol == cp->protocol) { - /* HIT */ - atomic_inc(&cp->refcnt); + p->protocol == cp->protocol) goto out; - } } cp = NULL; out: + if (cp) + atomic_inc(&cp->refcnt); ct_read_unlock(hash); IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n", @@ -357,7 +398,7 @@ struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p) /* * Check for "full" addressed entries */ - hash = ip_vs_conn_hashkey(p->af, p->protocol, p->vaddr, p->vport); + hash = ip_vs_conn_hashkey_param(p, true); ct_read_lock(hash); @@ -722,6 +763,7 @@ static void ip_vs_conn_expire(unsigned long data) if (cp->flags & IP_VS_CONN_F_NFCT) ip_vs_conn_drop_conntrack(cp); + kfree(cp->pe_data); if (unlikely(cp->app != NULL)) ip_vs_unbind_app(cp); ip_vs_unbind_dest(cp); @@ -782,6 +824,10 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, &cp->daddr, daddr); cp->dport = dport; cp->flags = flags; + if (flags & IP_VS_CONN_F_TEMPLATE && p->pe_data) { + cp->pe_data = p->pe_data; + cp->pe_data_len = p->pe_data_len; + } spin_lock_init(&cp->lock); /* @@ -832,7 +878,6 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, return cp; } - /* * /proc/net/ip_vs_conn entries */ @@ -848,7 +893,7 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos) list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { if (pos-- == 0) { seq->private = &ip_vs_conn_tab[idx]; - return cp; + return cp; } } ct_read_unlock_bh(idx); diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 87602a62458e..ab9889380496 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -176,6 +176,19 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, return pp->state_transition(cp, direction, skb, pp); } +static inline int +ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc, + struct sk_buff *skb, int protocol, + const union nf_inet_addr *caddr, __be16 cport, + const union nf_inet_addr *vaddr, __be16 vport, + struct ip_vs_conn_param *p) +{ + ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p); + p->pe = svc->pe; + if (p->pe && p->pe->fill_param) + return p->pe->fill_param(p, skb); + return 0; +} /* * IPVS persistent scheduling function @@ -186,7 +199,7 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, */ static struct ip_vs_conn * ip_vs_sched_persist(struct ip_vs_service *svc, - const struct sk_buff *skb, + struct sk_buff *skb, __be16 ports[2]) { struct ip_vs_conn *cp = NULL; @@ -255,8 +268,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc, vaddr = &fwmark; } } - ip_vs_conn_fill_param(svc->af, protocol, &snet, 0, - vaddr, vport, ¶m); + if (ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0, + vaddr, vport, ¶m)) + return NULL; } /* Check if a template already exists */ @@ -268,22 +282,30 @@ ip_vs_sched_persist(struct ip_vs_service *svc, dest = svc->scheduler->schedule(svc, skb); if (!dest) { IP_VS_DBG(1, "p-schedule: no dest found.\n"); + kfree(param.pe_data); return NULL; } if (ports[1] == svc->port && svc->port != FTPPORT) dport = dest->port; - /* Create a template */ + /* Create a template + * This adds param.pe_data to the template, + * and thus param.pe_data will be destroyed + * when the template expires */ ct = ip_vs_conn_new(¶m, &dest->addr, dport, IP_VS_CONN_F_TEMPLATE, dest); - if (ct == NULL) + if (ct == NULL) { + kfree(param.pe_data); return NULL; + } ct->timeout = svc->timeout; - } else + } else { /* set destination with the found template */ dest = ct->dest; + kfree(param.pe_data); + } dport = ports[1]; if (dport == svc->port && dest->port) @@ -322,7 +344,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * Protocols supported: TCP, UDP */ struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb) { struct ip_vs_conn *cp = NULL; struct ip_vs_iphdr iph; diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index f68631f75f09..ab85aedea17e 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -288,6 +288,16 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp) ip_vs_sync_conn(cp->control); } +static inline int +ip_vs_conn_fill_param_sync(int af, int protocol, + const union nf_inet_addr *caddr, __be16 cport, + const union nf_inet_addr *vaddr, __be16 vport, + struct ip_vs_conn_param *p) +{ + /* XXX: Need to take into account persistence engine */ + ip_vs_conn_fill_param(af, protocol, caddr, cport, vaddr, vport, p); + return 0; +} /* * Process received multicast message and create the corresponding @@ -372,11 +382,14 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } { - ip_vs_conn_fill_param(AF_INET, s->protocol, + if (ip_vs_conn_fill_param_sync(AF_INET, s->protocol, (union nf_inet_addr *)&s->caddr, s->cport, (union nf_inet_addr *)&s->vaddr, - s->vport, ¶m); + s->vport, ¶m)) { + pr_err("ip_vs_conn_fill_param_sync failed"); + return; + } if (!(flags & IP_VS_CONN_F_TEMPLATE)) cp = ip_vs_conn_in_get(¶m); else -- cgit v1.2.3 From a3c918acd29a96aba3b46bf50136e7953a480d17 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:53 +0900 Subject: IPVS: Add persistence engine data to /proc/net/ip_vs_conn This shouldn't break compatibility with userspace as the new data is at the end of the line. I have confirmed that this doesn't break ipvsadm, the main (only?) user-space user of this data. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_conn.c | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index b6b309d05e4e..974daf52ba76 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -572,6 +572,7 @@ struct ip_vs_pe { struct ip_vs_conn *ct); u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval, bool inverse); + int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf); }; /* diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 06da21e97405..4adedefdf563 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -950,30 +950,45 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) seq_puts(seq, - "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires\n"); + "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData\n"); else { const struct ip_vs_conn *cp = v; + char pe_data[IP_VS_PENAME_MAXLEN + IP_VS_PEDATA_MAXLEN + 3]; + size_t len = 0; + + if (cp->dest && cp->dest->svc->pe && + cp->dest->svc->pe->show_pe_data) { + pe_data[0] = ' '; + len = strlen(cp->dest->svc->pe->name); + memcpy(pe_data + 1, cp->dest->svc->pe->name, len); + pe_data[len + 1] = ' '; + len += 2; + len += cp->dest->svc->pe->show_pe_data(cp, + pe_data + len); + } + pe_data[len] = '\0'; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) - seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %7lu\n", + seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X " + "%pI6 %04X %-11s %7lu%s\n", ip_vs_proto_name(cp->protocol), &cp->caddr.in6, ntohs(cp->cport), &cp->vaddr.in6, ntohs(cp->vport), &cp->daddr.in6, ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), - (cp->timer.expires-jiffies)/HZ); + (cp->timer.expires-jiffies)/HZ, pe_data); else #endif seq_printf(seq, "%-3s %08X %04X %08X %04X" - " %08X %04X %-11s %7lu\n", + " %08X %04X %-11s %7lu%s\n", ip_vs_proto_name(cp->protocol), ntohl(cp->caddr.ip), ntohs(cp->cport), ntohl(cp->vaddr.ip), ntohs(cp->vport), ntohl(cp->daddr.ip), ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), - (cp->timer.expires-jiffies)/HZ); + (cp->timer.expires-jiffies)/HZ, pe_data); } return 0; } -- cgit v1.2.3 From 8be67a6617b3403551fccb67b1c624c659419515 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:54 +0900 Subject: IPVS: management of persistence engine modules This is based heavily on the scheduler management code Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/net/ip_vs.h | 6 ++ net/netfilter/ipvs/Makefile | 2 +- net/netfilter/ipvs/ip_vs_pe.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 net/netfilter/ipvs/ip_vs_pe.c diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 974daf52ba76..a6b93a26d4e2 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -796,6 +796,12 @@ extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb); extern int ip_vs_app_init(void); extern void ip_vs_app_cleanup(void); +void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe); +void ip_vs_unbind_pe(struct ip_vs_service *svc); +int register_ip_vs_pe(struct ip_vs_pe *pe); +int unregister_ip_vs_pe(struct ip_vs_pe *pe); +extern struct ip_vs_pe *ip_vs_pe_get(const char *name); +extern void ip_vs_pe_put(struct ip_vs_pe *pe); /* * IPVS protocol functions (from ip_vs_proto.c) diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile index 349fe8819b89..4a87bf3c6293 100644 --- a/net/netfilter/ipvs/Makefile +++ b/net/netfilter/ipvs/Makefile @@ -14,7 +14,7 @@ ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ - ip_vs_est.o ip_vs_proto.o \ + ip_vs_est.o ip_vs_proto.o ip_vs_pe.o \ $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y) diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c new file mode 100644 index 000000000000..3414af70ee12 --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_pe.c @@ -0,0 +1,147 @@ +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include + +#include + +/* IPVS pe list */ +static LIST_HEAD(ip_vs_pe); + +/* lock for service table */ +static DEFINE_SPINLOCK(ip_vs_pe_lock); + +/* Bind a service with a pe */ +void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe) +{ + svc->pe = pe; +} + +/* Unbind a service from its pe */ +void ip_vs_unbind_pe(struct ip_vs_service *svc) +{ + svc->pe = NULL; +} + +/* Get pe in the pe list by name */ +static struct ip_vs_pe * +ip_vs_pe_getbyname(const char *pe_name) +{ + struct ip_vs_pe *pe; + + IP_VS_DBG(2, "%s(): pe_name \"%s\"\n", __func__, + pe_name); + + spin_lock_bh(&ip_vs_pe_lock); + + list_for_each_entry(pe, &ip_vs_pe, n_list) { + /* Test and get the modules atomically */ + if (pe->module && + !try_module_get(pe->module)) { + /* This pe is just deleted */ + continue; + } + if (strcmp(pe_name, pe->name)==0) { + /* HIT */ + spin_unlock_bh(&ip_vs_pe_lock); + return pe; + } + if (pe->module) + module_put(pe->module); + } + + spin_unlock_bh(&ip_vs_pe_lock); + return NULL; +} + +/* Lookup pe and try to load it if it doesn't exist */ +struct ip_vs_pe *ip_vs_pe_get(const char *name) +{ + struct ip_vs_pe *pe; + + /* Search for the pe by name */ + pe = ip_vs_pe_getbyname(name); + + /* If pe not found, load the module and search again */ + if (!pe) { + request_module("ip_vs_pe_%s", name); + pe = ip_vs_pe_getbyname(name); + } + + return pe; +} + +void ip_vs_pe_put(struct ip_vs_pe *pe) +{ + if (pe && pe->module) + module_put(pe->module); +} + +/* Register a pe in the pe list */ +int register_ip_vs_pe(struct ip_vs_pe *pe) +{ + struct ip_vs_pe *tmp; + + /* increase the module use count */ + ip_vs_use_count_inc(); + + spin_lock_bh(&ip_vs_pe_lock); + + if (!list_empty(&pe->n_list)) { + spin_unlock_bh(&ip_vs_pe_lock); + ip_vs_use_count_dec(); + pr_err("%s(): [%s] pe already linked\n", + __func__, pe->name); + return -EINVAL; + } + + /* Make sure that the pe with this name doesn't exist + * in the pe list. + */ + list_for_each_entry(tmp, &ip_vs_pe, n_list) { + if (strcmp(tmp->name, pe->name) == 0) { + spin_unlock_bh(&ip_vs_pe_lock); + ip_vs_use_count_dec(); + pr_err("%s(): [%s] pe already existed " + "in the system\n", __func__, pe->name); + return -EINVAL; + } + } + /* Add it into the d-linked pe list */ + list_add(&pe->n_list, &ip_vs_pe); + spin_unlock_bh(&ip_vs_pe_lock); + + pr_info("[%s] pe registered.\n", pe->name); + + return 0; +} +EXPORT_SYMBOL_GPL(register_ip_vs_pe); + +/* Unregister a pe from the pe list */ +int unregister_ip_vs_pe(struct ip_vs_pe *pe) +{ + spin_lock_bh(&ip_vs_pe_lock); + if (list_empty(&pe->n_list)) { + spin_unlock_bh(&ip_vs_pe_lock); + pr_err("%s(): [%s] pe is not in the list. failed\n", + __func__, pe->name); + return -EINVAL; + } + + /* Remove it from the d-linked pe list */ + list_del(&pe->n_list); + spin_unlock_bh(&ip_vs_pe_lock); + + /* decrease the module use count */ + ip_vs_use_count_dec(); + + pr_info("[%s] pe unregistered.\n", pe->name); + + return 0; +} +EXPORT_SYMBOL_GPL(unregister_ip_vs_pe); -- cgit v1.2.3 From 0d1e71b04a04b6912e50926b9987c1e72facb1f3 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:54 +0900 Subject: IPVS: Allow configuration of persistence engines Allow the persistence engine of a virtual service to be set, edited and unset. This feature only works with the netlink user-space interface. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- include/linux/ip_vs.h | 3 +++ include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_ctl.c | 57 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index 0a9c44d64292..5f43a3b2e3ad 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -336,6 +336,9 @@ enum { IPVS_SVC_ATTR_NETMASK, /* persistent netmask */ IPVS_SVC_ATTR_STATS, /* nested attribute for service stats */ + + IPVS_SVC_ATTR_PE_NAME, /* name of ct retriever */ + __IPVS_SVC_ATTR_MAX, }; diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index a6b93a26d4e2..52fbe2308c38 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -444,6 +444,7 @@ struct ip_vs_service_user_kern { /* virtual service options */ char *sched_name; + char *pe_name; unsigned flags; /* virtual service flags */ unsigned timeout; /* persistent timeout in sec */ u32 netmask; /* persistent netmask */ diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 5f20caf47a1d..a697591d0e23 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1134,6 +1134,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, { int ret = 0; struct ip_vs_scheduler *sched = NULL; + struct ip_vs_pe *pe = NULL; struct ip_vs_service *svc = NULL; /* increase the module use count */ @@ -1147,6 +1148,16 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, goto out_err; } + if (u->pe_name && *u->pe_name) { + pe = ip_vs_pe_get(u->pe_name); + if (pe == NULL) { + pr_info("persistence engine module ip_vs_pe_%s " + "not found\n", u->pe_name); + ret = -ENOENT; + goto out_err; + } + } + #ifdef CONFIG_IP_VS_IPV6 if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) { ret = -EINVAL; @@ -1184,6 +1195,10 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, goto out_err; sched = NULL; + /* Bind the ct retriever */ + ip_vs_bind_pe(svc, pe); + pe = NULL; + /* Update the virtual service counters */ if (svc->port == FTPPORT) atomic_inc(&ip_vs_ftpsvc_counter); @@ -1215,6 +1230,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, kfree(svc); } ip_vs_scheduler_put(sched); + ip_vs_pe_put(pe); /* decrease the module use count */ ip_vs_use_count_dec(); @@ -1230,6 +1246,7 @@ static int ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) { struct ip_vs_scheduler *sched, *old_sched; + struct ip_vs_pe *pe = NULL, *old_pe = NULL; int ret = 0; /* @@ -1242,6 +1259,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) } old_sched = sched; + if (u->pe_name && *u->pe_name) { + pe = ip_vs_pe_get(u->pe_name); + if (pe == NULL) { + pr_info("persistence engine module ip_vs_pe_%s " + "not found\n", u->pe_name); + ret = -ENOENT; + goto out; + } + old_pe = pe; + } + #ifdef CONFIG_IP_VS_IPV6 if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) { ret = -EINVAL; @@ -1293,12 +1321,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) } } + old_pe = svc->pe; + if (pe != old_pe) { + ip_vs_unbind_pe(svc); + ip_vs_bind_pe(svc, pe); + } + out_unlock: write_unlock_bh(&__ip_vs_svc_lock); -#ifdef CONFIG_IP_VS_IPV6 out: -#endif ip_vs_scheduler_put(old_sched); + ip_vs_pe_put(old_pe); return ret; } @@ -1312,6 +1345,9 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) { struct ip_vs_dest *dest, *nxt; struct ip_vs_scheduler *old_sched; + struct ip_vs_pe *old_pe; + + pr_info("%s: enter\n", __func__); /* Count only IPv4 services for old get/setsockopt interface */ if (svc->af == AF_INET) @@ -1324,6 +1360,11 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) ip_vs_unbind_scheduler(svc); ip_vs_scheduler_put(old_sched); + /* Unbind persistence engine */ + old_pe = svc->pe; + ip_vs_unbind_pe(svc); + ip_vs_pe_put(old_pe); + /* Unbind app inc */ if (svc->inc) { ip_vs_app_inc_put(svc->inc); @@ -2026,6 +2067,8 @@ static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc, struct ip_vs_service_user *usvc_compat) { + memset(usvc, 0, sizeof(*usvc)); + usvc->af = AF_INET; usvc->protocol = usvc_compat->protocol; usvc->addr.ip = usvc_compat->addr; @@ -2043,6 +2086,8 @@ static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc, static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest, struct ip_vs_dest_user *udest_compat) { + memset(udest, 0, sizeof(*udest)); + udest->addr.ip = udest_compat->addr; udest->port = udest_compat->port; udest->conn_flags = udest_compat->conn_flags; @@ -2539,6 +2584,8 @@ static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = { [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 }, [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING, .len = IP_VS_SCHEDNAME_MAXLEN }, + [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING, + .len = IP_VS_PENAME_MAXLEN }, [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY, .len = sizeof(struct ip_vs_flags) }, [IPVS_SVC_ATTR_TIMEOUT] = { .type = NLA_U32 }, @@ -2615,6 +2662,8 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb, } NLA_PUT_STRING(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name); + if (svc->pe) + NLA_PUT_STRING(skb, IPVS_SVC_ATTR_PE_NAME, svc->pe->name); NLA_PUT(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags); NLA_PUT_U32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ); NLA_PUT_U32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask); @@ -2741,11 +2790,12 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, /* If a full entry was requested, check for the additional fields */ if (full_entry) { - struct nlattr *nla_sched, *nla_flags, *nla_timeout, + struct nlattr *nla_sched, *nla_flags, *nla_pe, *nla_timeout, *nla_netmask; struct ip_vs_flags flags; nla_sched = attrs[IPVS_SVC_ATTR_SCHED_NAME]; + nla_pe = attrs[IPVS_SVC_ATTR_PE_NAME]; nla_flags = attrs[IPVS_SVC_ATTR_FLAGS]; nla_timeout = attrs[IPVS_SVC_ATTR_TIMEOUT]; nla_netmask = attrs[IPVS_SVC_ATTR_NETMASK]; @@ -2763,6 +2813,7 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, usvc->flags = (usvc->flags & ~flags.mask) | (flags.flags & flags.mask); usvc->sched_name = nla_data(nla_sched); + usvc->pe_name = nla_pe ? nla_data(nla_pe) : NULL; usvc->timeout = nla_get_u32(nla_timeout); usvc->netmask = nla_get_u32(nla_netmask); } -- cgit v1.2.3 From f71499aa11f884255b69ce6c3b3c398c821591a1 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:54 +0900 Subject: IPVS: Fallback if persistence engine fails Fall back to normal persistence handling if the persistence engine fails to recognise a packet. This way, at least the packet will go somewhere. It is envisaged that iptables could be used to block packets such if this is not desired although nf_conntrack_sip would likely need to be enhanced first. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/ipvs/ip_vs_conn.c | 6 +++--- net/netfilter/ipvs/ip_vs_core.c | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 4adedefdf563..1d1a529dbe24 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -154,7 +154,7 @@ static unsigned int ip_vs_conn_hashkey_param(const struct ip_vs_conn_param *p, const union nf_inet_addr *addr; __be16 port; - if (p->pe && p->pe->hashkey_raw) + if (p->pe_data && p->pe->hashkey_raw) return p->pe->hashkey_raw(p, ip_vs_conn_rnd, inverse) & ip_vs_conn_tab_mask; @@ -353,7 +353,7 @@ struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (p->pe && p->pe->ct_match) { + if (p->pe_data && p->pe->ct_match) { if (p->pe->ct_match(p, cp)) goto out; continue; @@ -956,7 +956,7 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v) char pe_data[IP_VS_PENAME_MAXLEN + IP_VS_PEDATA_MAXLEN + 3]; size_t len = 0; - if (cp->dest && cp->dest->svc->pe && + if (cp->dest && cp->pe_data && cp->dest->svc->pe->show_pe_data) { pe_data[0] = ' '; len = strlen(cp->dest->svc->pe->name); diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index ab9889380496..e5fef7aef0d4 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -176,7 +176,7 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, return pp->state_transition(cp, direction, skb, pp); } -static inline int +static inline void ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc, struct sk_buff *skb, int protocol, const union nf_inet_addr *caddr, __be16 cport, @@ -186,8 +186,7 @@ ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc, ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p); p->pe = svc->pe; if (p->pe && p->pe->fill_param) - return p->pe->fill_param(p, skb); - return 0; + p->pe->fill_param(p, skb); } /* @@ -268,9 +267,8 @@ ip_vs_sched_persist(struct ip_vs_service *svc, vaddr = &fwmark; } } - if (ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0, - vaddr, vport, ¶m)) - return NULL; + ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0, + vaddr, vport, ¶m); } /* Check if a template already exists */ -- cgit v1.2.3 From 758ff03387228824617cef9507e5682488bf9e0c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sun, 22 Aug 2010 21:37:55 +0900 Subject: IPVS: sip persistence engine Add the SIP callid as a key for persistence. This allows multiple connections from the same IP address to be differentiated on the basis of the callid. When used in conjunction with the persistence mask, it allows connections from different IP addresses to be aggregated on the basis of the callid. It is envisaged that a persistence mask of 0.0.0.0 will be a useful setting. That is, ignore the source IP address when checking for persistence. It is envisaged that this option will be used in conjunction with one-packet scheduling. This only works with UDP and cannot be made to work with TCP within the current framework. Signed-off-by: Simon Horman Acked-by: Julian Anastasov --- net/netfilter/ipvs/Kconfig | 7 ++ net/netfilter/ipvs/Makefile | 3 + net/netfilter/ipvs/ip_vs_pe_sip.c | 167 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 net/netfilter/ipvs/ip_vs_pe_sip.c diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index af3c9f48f2d7..a22dac227055 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -256,4 +256,11 @@ config IP_VS_NFCT connection state to be exported to the Netfilter framework for filtering purposes. +config IP_VS_PE_SIP + tristate "SIP persistence engine" + depends on IP_VS_PROTO_UDP + depends on NF_CONNTRACK_SIP + ---help--- + Allow persistence based on the SIP Call-ID + endif # IP_VS diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile index 4a87bf3c6293..34ee602ddb66 100644 --- a/net/netfilter/ipvs/Makefile +++ b/net/netfilter/ipvs/Makefile @@ -35,3 +35,6 @@ obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o # IPVS application helpers obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o + +# IPVS connection template retrievers +obj-$(CONFIG_IP_VS_PE_SIP) += ip_vs_pe_sip.o diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c new file mode 100644 index 000000000000..a0539f13e2b4 --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c @@ -0,0 +1,167 @@ +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include + +#include +#include +#include + +static const char *ip_vs_dbg_callid(char *buf, size_t buf_len, + const char *callid, size_t callid_len, + int *idx) +{ + size_t len = min(min(callid_len, (size_t)64), buf_len - *idx - 1); + memcpy(buf + *idx, callid, len); + buf[*idx+len] = '\0'; + *idx += len + 1; + return buf + *idx - len; +} + +#define IP_VS_DEBUG_CALLID(callid, len) \ + ip_vs_dbg_callid(ip_vs_dbg_buf, sizeof(ip_vs_dbg_buf), \ + callid, len, &ip_vs_dbg_idx) + +static int get_callid(const char *dptr, unsigned int dataoff, + unsigned int datalen, + unsigned int *matchoff, unsigned int *matchlen) +{ + /* Find callid */ + while (1) { + int ret = ct_sip_get_header(NULL, dptr, dataoff, datalen, + SIP_HDR_CALL_ID, matchoff, + matchlen); + if (ret > 0) + break; + if (!ret) + return 0; + dataoff += *matchoff; + } + + /* Empty callid is useless */ + if (!*matchlen) + return -EINVAL; + + /* Too large is useless */ + if (*matchlen > IP_VS_PEDATA_MAXLEN) + return -EINVAL; + + /* SIP headers are always followed by a line terminator */ + if (*matchoff + *matchlen == datalen) + return -EINVAL; + + /* RFC 2543 allows lines to be terminated with CR, LF or CRLF, + * RFC 3261 allows only CRLF, we support both. */ + if (*(dptr + *matchoff + *matchlen) != '\r' && + *(dptr + *matchoff + *matchlen) != '\n') + return -EINVAL; + + IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n", + IP_VS_DEBUG_CALLID(dptr + *matchoff, *matchlen), + *matchlen); + return 0; +} + +static int +ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) +{ + struct ip_vs_iphdr iph; + unsigned int dataoff, datalen, matchoff, matchlen; + const char *dptr; + + ip_vs_fill_iphdr(p->af, skb_network_header(skb), &iph); + + /* Only useful with UDP */ + if (iph.protocol != IPPROTO_UDP) + return -EINVAL; + + /* No Data ? */ + dataoff = iph.len + sizeof(struct udphdr); + if (dataoff >= skb->len) + return -EINVAL; + + dptr = skb->data + dataoff; + datalen = skb->len - dataoff; + + if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen)) + return -EINVAL; + + p->pe_data = kmalloc(matchlen, GFP_ATOMIC); + if (!p->pe_data) + return -ENOMEM; + + /* N.B: pe_data is only set on success, + * this allows fallback to the default persistence logic on failure + */ + memcpy(p->pe_data, dptr + matchoff, matchlen); + p->pe_data_len = matchlen; + + return 0; +} + +static bool ip_vs_sip_ct_match(const struct ip_vs_conn_param *p, + struct ip_vs_conn *ct) + +{ + bool ret = 0; + + if (ct->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &ct->caddr) && + /* protocol should only be IPPROTO_IP if + * d_addr is a fwmark */ + ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, + p->vaddr, &ct->vaddr) && + ct->vport == p->vport && + ct->flags & IP_VS_CONN_F_TEMPLATE && + ct->protocol == p->protocol && + ct->pe_data && ct->pe_data_len == p->pe_data_len && + !memcmp(ct->pe_data, p->pe_data, p->pe_data_len)) + ret = 1; + + IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n", + ip_vs_proto_name(p->protocol), + IP_VS_DEBUG_CALLID(p->pe_data, p->pe_data_len), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), + ret ? "hit" : "not hit"); + + return ret; +} + +static u32 ip_vs_sip_hashkey_raw(const struct ip_vs_conn_param *p, + u32 initval, bool inverse) +{ + return jhash(p->pe_data, p->pe_data_len, initval); +} + +static int ip_vs_sip_show_pe_data(const struct ip_vs_conn *cp, char *buf) +{ + memcpy(buf, cp->pe_data, cp->pe_data_len); + return cp->pe_data_len; +} + +static struct ip_vs_pe ip_vs_sip_pe = +{ + .name = "sip", + .refcnt = ATOMIC_INIT(0), + .module = THIS_MODULE, + .n_list = LIST_HEAD_INIT(ip_vs_sip_pe.n_list), + .fill_param = ip_vs_sip_fill_param, + .ct_match = ip_vs_sip_ct_match, + .hashkey_raw = ip_vs_sip_hashkey_raw, + .show_pe_data = ip_vs_sip_show_pe_data, +}; + +static int __init ip_vs_sip_init(void) +{ + return register_ip_vs_pe(&ip_vs_sip_pe); +} + +static void __exit ip_vs_sip_cleanup(void) +{ + unregister_ip_vs_pe(&ip_vs_sip_pe); +} + +module_init(ip_vs_sip_init); +module_exit(ip_vs_sip_cleanup); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0c200d935346fe0ebde9b6dffbb683dddd166fb9 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 4 Oct 2010 20:53:18 +0200 Subject: netfilter: nf_nat: make find/put static The functions nf_nat_proto_find_get and nf_nat_proto_put are only used internally in nf_nat_core. This might break some out of tree NAT module. Signed-off-by: Stephen Hemminger Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_nat_protocol.h | 3 --- net/ipv4/netfilter/nf_nat_core.c | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index df17bac46bf5..93cc90d28e66 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -45,9 +45,6 @@ struct nf_nat_protocol { extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto); extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto); -extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol); -extern void nf_nat_proto_put(const struct nf_nat_protocol *proto); - /* Built-in protocols. */ extern const struct nf_nat_protocol nf_nat_protocol_tcp; extern const struct nf_nat_protocol nf_nat_protocol_udp; diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 2c084b3a8f0c..e2e00c4da883 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -47,7 +47,7 @@ __nf_nat_proto_find(u_int8_t protonum) return rcu_dereference(nf_nat_protos[protonum]); } -const struct nf_nat_protocol * +static const struct nf_nat_protocol * nf_nat_proto_find_get(u_int8_t protonum) { const struct nf_nat_protocol *p; @@ -60,14 +60,12 @@ nf_nat_proto_find_get(u_int8_t protonum) return p; } -EXPORT_SYMBOL_GPL(nf_nat_proto_find_get); -void +static void nf_nat_proto_put(const struct nf_nat_protocol *p) { module_put(p->me); } -EXPORT_SYMBOL_GPL(nf_nat_proto_put); /* We keep an extra hash for each conntrack, for fast searching. */ static inline unsigned int -- cgit v1.2.3 From a8defca048fd11eb2d1a17ab61a60a856292dd4e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Oct 2010 20:56:05 +0200 Subject: netfilter: ipt_LOG: add bufferisation to call printk() once ipt_LOG & ip6t_LOG use lot of calls to printk() and use a lock in a hope several cpus wont mix their output in syslog. printk() being very expensive [1], its better to call it once, on a prebuilt and complete line. Also, with mixed IPv4 and IPv6 trafic, separate IPv4/IPv6 locks dont avoid garbage. I used an allocation of a 1024 bytes structure, sort of seq_printf() but with a fixed size limit. Use a static buffer if dynamic allocation failed. Emit a once time alert if buffer size happens to be too short. [1]: printk() has various features like printk_delay()... Signed-off-by: Eric Dumazet Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/ipt_LOG.c | 145 +++++++++++++++++++------------------- net/ipv6/netfilter/ip6t_LOG.c | 157 +++++++++++++++++++++--------------------- 2 files changed, 152 insertions(+), 150 deletions(-) diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 915fc17d7ce2..72ffc8fda2e9 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -24,16 +24,15 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog"); -/* Use lock to serialize, so printks don't overlap */ -static DEFINE_SPINLOCK(log_lock); - /* One level of recursion won't kill us */ -static void dump_packet(const struct nf_loginfo *info, +static void dump_packet(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb, unsigned int iphoff) { @@ -48,32 +47,32 @@ static void dump_packet(const struct nf_loginfo *info, ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); if (ih == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Important fields: * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ - printk("SRC=%pI4 DST=%pI4 ", + sb_add(m, "SRC=%pI4 DST=%pI4 ", &ih->saddr, &ih->daddr); /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ - printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", + sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); /* Max length: 6 "CE DF MF " */ if (ntohs(ih->frag_off) & IP_CE) - printk("CE "); + sb_add(m, "CE "); if (ntohs(ih->frag_off) & IP_DF) - printk("DF "); + sb_add(m, "DF "); if (ntohs(ih->frag_off) & IP_MF) - printk("MF "); + sb_add(m, "MF "); /* Max length: 11 "FRAG:65535 " */ if (ntohs(ih->frag_off) & IP_OFFSET) - printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); + sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); if ((logflags & IPT_LOG_IPOPT) && ih->ihl * 4 > sizeof(struct iphdr)) { @@ -85,15 +84,15 @@ static void dump_packet(const struct nf_loginfo *info, op = skb_header_pointer(skb, iphoff+sizeof(_iph), optsize, _opt); if (op == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i = 0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } switch (ih->protocol) { @@ -102,7 +101,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct tcphdr *th; /* Max length: 10 "PROTO=TCP " */ - printk("PROTO=TCP "); + sb_add(m, "PROTO=TCP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -111,41 +110,41 @@ static void dump_packet(const struct nf_loginfo *info, th = skb_header_pointer(skb, iphoff + ih->ihl * 4, sizeof(_tcph), &_tcph); if (th == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u ", + sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ if (logflags & IPT_LOG_TCPSEQ) - printk("SEQ=%u ACK=%u ", + sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq)); /* Max length: 13 "WINDOW=65535 " */ - printk("WINDOW=%u ", ntohs(th->window)); + sb_add(m, "WINDOW=%u ", ntohs(th->window)); /* Max length: 9 "RES=0x3F " */ - printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); + sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ if (th->cwr) - printk("CWR "); + sb_add(m, "CWR "); if (th->ece) - printk("ECE "); + sb_add(m, "ECE "); if (th->urg) - printk("URG "); + sb_add(m, "URG "); if (th->ack) - printk("ACK "); + sb_add(m, "ACK "); if (th->psh) - printk("PSH "); + sb_add(m, "PSH "); if (th->rst) - printk("RST "); + sb_add(m, "RST "); if (th->syn) - printk("SYN "); + sb_add(m, "SYN "); if (th->fin) - printk("FIN "); + sb_add(m, "FIN "); /* Max length: 11 "URGP=65535 " */ - printk("URGP=%u ", ntohs(th->urg_ptr)); + sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); if ((logflags & IPT_LOG_TCPOPT) && th->doff * 4 > sizeof(struct tcphdr)) { @@ -158,15 +157,15 @@ static void dump_packet(const struct nf_loginfo *info, iphoff+ih->ihl*4+sizeof(_tcph), optsize, _opt); if (op == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i = 0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } break; } @@ -177,9 +176,9 @@ static void dump_packet(const struct nf_loginfo *info, if (ih->protocol == IPPROTO_UDP) /* Max length: 10 "PROTO=UDP " */ - printk("PROTO=UDP " ); + sb_add(m, "PROTO=UDP " ); else /* Max length: 14 "PROTO=UDPLITE " */ - printk("PROTO=UDPLITE "); + sb_add(m, "PROTO=UDPLITE "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -188,13 +187,13 @@ static void dump_packet(const struct nf_loginfo *info, uh = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_udph), &_udph); if (uh == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u LEN=%u ", + sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len)); break; @@ -221,7 +220,7 @@ static void dump_packet(const struct nf_loginfo *info, [ICMP_ADDRESSREPLY] = 12 }; /* Max length: 11 "PROTO=ICMP " */ - printk("PROTO=ICMP "); + sb_add(m, "PROTO=ICMP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -230,19 +229,19 @@ static void dump_packet(const struct nf_loginfo *info, ich = skb_header_pointer(skb, iphoff + ih->ihl * 4, sizeof(_icmph), &_icmph); if (ich == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 18 "TYPE=255 CODE=255 " */ - printk("TYPE=%u CODE=%u ", ich->type, ich->code); + sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code); /* Max length: 25 "INCOMPLETE [65535 bytes] " */ if (ich->type <= NR_ICMP_TYPES && required_len[ich->type] && skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } @@ -251,35 +250,35 @@ static void dump_packet(const struct nf_loginfo *info, case ICMP_ECHOREPLY: case ICMP_ECHO: /* Max length: 19 "ID=65535 SEQ=65535 " */ - printk("ID=%u SEQ=%u ", + sb_add(m, "ID=%u SEQ=%u ", ntohs(ich->un.echo.id), ntohs(ich->un.echo.sequence)); break; case ICMP_PARAMETERPROB: /* Max length: 14 "PARAMETER=255 " */ - printk("PARAMETER=%u ", + sb_add(m, "PARAMETER=%u ", ntohl(ich->un.gateway) >> 24); break; case ICMP_REDIRECT: /* Max length: 24 "GATEWAY=255.255.255.255 " */ - printk("GATEWAY=%pI4 ", &ich->un.gateway); + sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway); /* Fall through */ case ICMP_DEST_UNREACH: case ICMP_SOURCE_QUENCH: case ICMP_TIME_EXCEEDED: /* Max length: 3+maxlen */ if (!iphoff) { /* Only recurse once. */ - printk("["); - dump_packet(info, skb, + sb_add(m, "["); + dump_packet(m, info, skb, iphoff + ih->ihl*4+sizeof(_icmph)); - printk("] "); + sb_add(m, "] "); } /* Max length: 10 "MTU=65535 " */ if (ich->type == ICMP_DEST_UNREACH && ich->code == ICMP_FRAG_NEEDED) - printk("MTU=%u ", ntohs(ich->un.frag.mtu)); + sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu)); } break; } @@ -292,19 +291,19 @@ static void dump_packet(const struct nf_loginfo *info, break; /* Max length: 9 "PROTO=AH " */ - printk("PROTO=AH "); + sb_add(m, "PROTO=AH "); /* Max length: 25 "INCOMPLETE [65535 bytes] " */ ah = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_ahdr), &_ahdr); if (ah == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Length: 15 "SPI=0xF1234567 " */ - printk("SPI=0x%x ", ntohl(ah->spi)); + sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); break; } case IPPROTO_ESP: { @@ -312,7 +311,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_esp_hdr *eh; /* Max length: 10 "PROTO=ESP " */ - printk("PROTO=ESP "); + sb_add(m, "PROTO=ESP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -321,25 +320,25 @@ static void dump_packet(const struct nf_loginfo *info, eh = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_esph), &_esph); if (eh == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Length: 15 "SPI=0xF1234567 " */ - printk("SPI=0x%x ", ntohl(eh->spi)); + sb_add(m, "SPI=0x%x ", ntohl(eh->spi)); break; } /* Max length: 10 "PROTO 255 " */ default: - printk("PROTO=%u ", ih->protocol); + sb_add(m, "PROTO=%u ", ih->protocol); } /* Max length: 15 "UID=4294967295 " */ if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) - printk("UID=%u GID=%u ", + sb_add(m, "UID=%u GID=%u ", skb->sk->sk_socket->file->f_cred->fsuid, skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); @@ -347,7 +346,7 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 16 "MARK=0xFFFFFFFF " */ if (!iphoff && skb->mark) - printk("MARK=0x%x ", skb->mark); + sb_add(m, "MARK=0x%x ", skb->mark); /* Proto Max log string length */ /* IP: 40+46+6+11+127 = 230 */ @@ -364,7 +363,8 @@ static void dump_packet(const struct nf_loginfo *info, /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -static void dump_mac_header(const struct nf_loginfo *info, +static void dump_mac_header(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -378,7 +378,7 @@ static void dump_mac_header(const struct nf_loginfo *info, switch (dev->type) { case ARPHRD_ETHER: - printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", + sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, ntohs(eth_hdr(skb)->h_proto)); return; @@ -387,17 +387,17 @@ static void dump_mac_header(const struct nf_loginfo *info, } fallback: - printk("MAC="); + sb_add(m, "MAC="); if (dev->hard_header_len && skb->mac_header != skb->network_header) { const unsigned char *p = skb_mac_header(skb); unsigned int i; - printk("%02x", *p++); + sb_add(m, "%02x", *p++); for (i = 1; i < dev->hard_header_len; i++, p++) - printk(":%02x", *p); + sb_add(m, ":%02x", *p); } - printk(" "); + sb_add(m, " "); } static struct nf_loginfo default_loginfo = { @@ -419,11 +419,12 @@ ipt_log_packet(u_int8_t pf, const struct nf_loginfo *loginfo, const char *prefix) { + struct sbuff *m = sb_open(); + if (!loginfo) loginfo = &default_loginfo; - spin_lock_bh(&log_lock); - printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, + sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, prefix, in ? in->name : "", out ? out->name : ""); @@ -434,20 +435,20 @@ ipt_log_packet(u_int8_t pf, physindev = skb->nf_bridge->physindev; if (physindev && in != physindev) - printk("PHYSIN=%s ", physindev->name); + sb_add(m, "PHYSIN=%s ", physindev->name); physoutdev = skb->nf_bridge->physoutdev; if (physoutdev && out != physoutdev) - printk("PHYSOUT=%s ", physoutdev->name); + sb_add(m, "PHYSOUT=%s ", physoutdev->name); } #endif /* MAC logging for input path only. */ if (in && !out) - dump_mac_header(loginfo, skb); + dump_mac_header(m, loginfo, skb); + + dump_packet(m, loginfo, skb, 0); - dump_packet(loginfo, skb, 0); - printk("\n"); - spin_unlock_bh(&log_lock); + sb_close(m); } static unsigned int diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 0a07ae7b933f..09c88891a753 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c @@ -23,6 +23,7 @@ #include #include #include +#include MODULE_AUTHOR("Jan Rekorajski "); MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog"); @@ -32,11 +33,9 @@ struct in_device; #include #include -/* Use lock to serialize, so printks don't overlap */ -static DEFINE_SPINLOCK(log_lock); - /* One level of recursion won't kill us */ -static void dump_packet(const struct nf_loginfo *info, +static void dump_packet(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb, unsigned int ip6hoff, int recurse) { @@ -55,15 +54,15 @@ static void dump_packet(const struct nf_loginfo *info, ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); if (ih == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ - printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); + sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ - printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", + sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", ntohs(ih->payload_len) + sizeof(struct ipv6hdr), (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20, ih->hop_limit, @@ -78,35 +77,35 @@ static void dump_packet(const struct nf_loginfo *info, hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); if (hp == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 48 "OPT (...) " */ if (logflags & IP6T_LOG_IPOPT) - printk("OPT ( "); + sb_add(m, "OPT ( "); switch (currenthdr) { case IPPROTO_FRAGMENT: { struct frag_hdr _fhdr; const struct frag_hdr *fh; - printk("FRAG:"); + sb_add(m, "FRAG:"); fh = skb_header_pointer(skb, ptr, sizeof(_fhdr), &_fhdr); if (fh == NULL) { - printk("TRUNCATED "); + sb_add(m, "TRUNCATED "); return; } /* Max length: 6 "65535 " */ - printk("%u ", ntohs(fh->frag_off) & 0xFFF8); + sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8); /* Max length: 11 "INCOMPLETE " */ if (fh->frag_off & htons(0x0001)) - printk("INCOMPLETE "); + sb_add(m, "INCOMPLETE "); - printk("ID:%08x ", ntohl(fh->identification)); + sb_add(m, "ID:%08x ", ntohl(fh->identification)); if (ntohs(fh->frag_off) & 0xFFF8) fragment = 1; @@ -120,7 +119,7 @@ static void dump_packet(const struct nf_loginfo *info, case IPPROTO_HOPOPTS: if (fragment) { if (logflags & IP6T_LOG_IPOPT) - printk(")"); + sb_add(m, ")"); return; } hdrlen = ipv6_optlen(hp); @@ -132,10 +131,10 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_auth_hdr *ah; /* Max length: 3 "AH " */ - printk("AH "); + sb_add(m, "AH "); if (fragment) { - printk(")"); + sb_add(m, ")"); return; } @@ -146,13 +145,13 @@ static void dump_packet(const struct nf_loginfo *info, * Max length: 26 "INCOMPLETE [65535 * bytes] )" */ - printk("INCOMPLETE [%u bytes] )", + sb_add(m, "INCOMPLETE [%u bytes] )", skb->len - ptr); return; } /* Length: 15 "SPI=0xF1234567 */ - printk("SPI=0x%x ", ntohl(ah->spi)); + sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); } @@ -164,10 +163,10 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_esp_hdr *eh; /* Max length: 4 "ESP " */ - printk("ESP "); + sb_add(m, "ESP "); if (fragment) { - printk(")"); + sb_add(m, ")"); return; } @@ -177,23 +176,23 @@ static void dump_packet(const struct nf_loginfo *info, eh = skb_header_pointer(skb, ptr, sizeof(_esph), &_esph); if (eh == NULL) { - printk("INCOMPLETE [%u bytes] )", + sb_add(m, "INCOMPLETE [%u bytes] )", skb->len - ptr); return; } /* Length: 16 "SPI=0xF1234567 )" */ - printk("SPI=0x%x )", ntohl(eh->spi) ); + sb_add(m, "SPI=0x%x )", ntohl(eh->spi) ); } return; default: /* Max length: 20 "Unknown Ext Hdr 255" */ - printk("Unknown Ext Hdr %u", currenthdr); + sb_add(m, "Unknown Ext Hdr %u", currenthdr); return; } if (logflags & IP6T_LOG_IPOPT) - printk(") "); + sb_add(m, ") "); currenthdr = hp->nexthdr; ptr += hdrlen; @@ -205,7 +204,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct tcphdr *th; /* Max length: 10 "PROTO=TCP " */ - printk("PROTO=TCP "); + sb_add(m, "PROTO=TCP "); if (fragment) break; @@ -213,40 +212,40 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph); if (th == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u ", + sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ if (logflags & IP6T_LOG_TCPSEQ) - printk("SEQ=%u ACK=%u ", + sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq)); /* Max length: 13 "WINDOW=65535 " */ - printk("WINDOW=%u ", ntohs(th->window)); + sb_add(m, "WINDOW=%u ", ntohs(th->window)); /* Max length: 9 "RES=0x3C " */ - printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); + sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ if (th->cwr) - printk("CWR "); + sb_add(m, "CWR "); if (th->ece) - printk("ECE "); + sb_add(m, "ECE "); if (th->urg) - printk("URG "); + sb_add(m, "URG "); if (th->ack) - printk("ACK "); + sb_add(m, "ACK "); if (th->psh) - printk("PSH "); + sb_add(m, "PSH "); if (th->rst) - printk("RST "); + sb_add(m, "RST "); if (th->syn) - printk("SYN "); + sb_add(m, "SYN "); if (th->fin) - printk("FIN "); + sb_add(m, "FIN "); /* Max length: 11 "URGP=65535 " */ - printk("URGP=%u ", ntohs(th->urg_ptr)); + sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); if ((logflags & IP6T_LOG_TCPOPT) && th->doff * 4 > sizeof(struct tcphdr)) { @@ -260,15 +259,15 @@ static void dump_packet(const struct nf_loginfo *info, ptr + sizeof(struct tcphdr), optsize, _opt); if (op == NULL) { - printk("OPT (TRUNCATED)"); + sb_add(m, "OPT (TRUNCATED)"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i =0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } break; } @@ -279,9 +278,9 @@ static void dump_packet(const struct nf_loginfo *info, if (currenthdr == IPPROTO_UDP) /* Max length: 10 "PROTO=UDP " */ - printk("PROTO=UDP " ); + sb_add(m, "PROTO=UDP " ); else /* Max length: 14 "PROTO=UDPLITE " */ - printk("PROTO=UDPLITE "); + sb_add(m, "PROTO=UDPLITE "); if (fragment) break; @@ -289,12 +288,12 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph); if (uh == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u LEN=%u ", + sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len)); break; @@ -304,7 +303,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct icmp6hdr *ic; /* Max length: 13 "PROTO=ICMPv6 " */ - printk("PROTO=ICMPv6 "); + sb_add(m, "PROTO=ICMPv6 "); if (fragment) break; @@ -312,18 +311,18 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h); if (ic == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 18 "TYPE=255 CODE=255 " */ - printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); + sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); switch (ic->icmp6_type) { case ICMPV6_ECHO_REQUEST: case ICMPV6_ECHO_REPLY: /* Max length: 19 "ID=65535 SEQ=65535 " */ - printk("ID=%u SEQ=%u ", + sb_add(m, "ID=%u SEQ=%u ", ntohs(ic->icmp6_identifier), ntohs(ic->icmp6_sequence)); break; @@ -334,35 +333,35 @@ static void dump_packet(const struct nf_loginfo *info, case ICMPV6_PARAMPROB: /* Max length: 17 "POINTER=ffffffff " */ - printk("POINTER=%08x ", ntohl(ic->icmp6_pointer)); + sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer)); /* Fall through */ case ICMPV6_DEST_UNREACH: case ICMPV6_PKT_TOOBIG: case ICMPV6_TIME_EXCEED: /* Max length: 3+maxlen */ if (recurse) { - printk("["); - dump_packet(info, skb, ptr + sizeof(_icmp6h), - 0); - printk("] "); + sb_add(m, "["); + dump_packet(m, info, skb, + ptr + sizeof(_icmp6h), 0); + sb_add(m, "] "); } /* Max length: 10 "MTU=65535 " */ if (ic->icmp6_type == ICMPV6_PKT_TOOBIG) - printk("MTU=%u ", ntohl(ic->icmp6_mtu)); + sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu)); } break; } /* Max length: 10 "PROTO=255 " */ default: - printk("PROTO=%u ", currenthdr); + sb_add(m, "PROTO=%u ", currenthdr); } /* Max length: 15 "UID=4294967295 " */ if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) - printk("UID=%u GID=%u ", + sb_add(m, "UID=%u GID=%u ", skb->sk->sk_socket->file->f_cred->fsuid, skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); @@ -370,10 +369,11 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 16 "MARK=0xFFFFFFFF " */ if (!recurse && skb->mark) - printk("MARK=0x%x ", skb->mark); + sb_add(m, "MARK=0x%x ", skb->mark); } -static void dump_mac_header(const struct nf_loginfo *info, +static void dump_mac_header(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -387,7 +387,7 @@ static void dump_mac_header(const struct nf_loginfo *info, switch (dev->type) { case ARPHRD_ETHER: - printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", + sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, ntohs(eth_hdr(skb)->h_proto)); return; @@ -396,7 +396,7 @@ static void dump_mac_header(const struct nf_loginfo *info, } fallback: - printk("MAC="); + sb_add(m, "MAC="); if (dev->hard_header_len && skb->mac_header != skb->network_header) { const unsigned char *p = skb_mac_header(skb); @@ -408,19 +408,19 @@ fallback: p = NULL; if (p != NULL) { - printk("%02x", *p++); + sb_add(m, "%02x", *p++); for (i = 1; i < len; i++) - printk(":%02x", p[i]); + sb_add(m, ":%02x", p[i]); } - printk(" "); + sb_add(m, " "); if (dev->type == ARPHRD_SIT) { const struct iphdr *iph = (struct iphdr *)skb_mac_header(skb); - printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); + sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); } } else - printk(" "); + sb_add(m, " "); } static struct nf_loginfo default_loginfo = { @@ -442,22 +442,23 @@ ip6t_log_packet(u_int8_t pf, const struct nf_loginfo *loginfo, const char *prefix) { + struct sbuff *m = sb_open(); + if (!loginfo) loginfo = &default_loginfo; - spin_lock_bh(&log_lock); - printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, - prefix, - in ? in->name : "", - out ? out->name : ""); + sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, + prefix, + in ? in->name : "", + out ? out->name : ""); /* MAC logging for input path only. */ if (in && !out) - dump_mac_header(loginfo, skb); + dump_mac_header(m, loginfo, skb); + + dump_packet(m, loginfo, skb, skb_network_offset(skb), 1); - dump_packet(loginfo, skb, skb_network_offset(skb), 1); - printk("\n"); - spin_unlock_bh(&log_lock); + sb_close(m); } static unsigned int -- cgit v1.2.3 From e55df53dd62c73185af46fb6ffa7074b05ceefc4 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 4 Oct 2010 21:00:42 +0200 Subject: netfilter: remove duplicated include Remove duplicated include. Signed-off-by: Nicolas Kaiser Signed-off-by: Patrick McHardy --- net/netfilter/xt_ipvs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c index 7a4d66db95ae..9127a3d8aa35 100644 --- a/net/netfilter/xt_ipvs.c +++ b/net/netfilter/xt_ipvs.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From f68c53015c5b9aa98ffd87a34009f89bdbbd7160 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Mon, 4 Oct 2010 22:24:12 +0200 Subject: netfilter: unregister nf hooks, matches and targets in the reverse order Since we register nf hooks, matches and targets in order, we'd better unregister them in the reverse order. Signed-off-by: Changli Gao Signed-off-by: Patrick McHardy --- net/netfilter/core.c | 6 ++---- net/netfilter/x_tables.c | 12 ++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 78b505d33bfb..8f014f22d132 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -105,10 +105,8 @@ EXPORT_SYMBOL(nf_register_hooks); void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - nf_unregister_hook(®[i]); + while (n-- > 0) + nf_unregister_hook(®[n]); } EXPORT_SYMBOL(nf_unregister_hooks); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index e34622fa0003..80463507420e 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -116,10 +116,8 @@ EXPORT_SYMBOL(xt_register_targets); void xt_unregister_targets(struct xt_target *target, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - xt_unregister_target(&target[i]); + while (n-- > 0) + xt_unregister_target(&target[n]); } EXPORT_SYMBOL(xt_unregister_targets); @@ -174,10 +172,8 @@ EXPORT_SYMBOL(xt_register_matches); void xt_unregister_matches(struct xt_match *match, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - xt_unregister_match(&match[i]); + while (n-- > 0) + xt_unregister_match(&match[n]); } EXPORT_SYMBOL(xt_unregister_matches); -- cgit v1.2.3 From eecc545856c8a0f27783a440d25f4ceaa1f95ce8 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 4 Oct 2010 23:24:21 +0200 Subject: netfilter: add missing xt_log.h file Forgot to add xt_log.h in commit a8defca0 (netfilter: ipt_LOG: add bufferisation to call printk() once) Signed-off-by: Patrick McHardy --- include/net/netfilter/xt_log.h | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 include/net/netfilter/xt_log.h diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h new file mode 100644 index 000000000000..0dfb34a5b53c --- /dev/null +++ b/include/net/netfilter/xt_log.h @@ -0,0 +1,54 @@ +#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) + +struct sbuff { + unsigned int count; + char buf[S_SIZE + 1]; +}; +static struct sbuff emergency, *emergency_ptr = &emergency; + +static int sb_add(struct sbuff *m, const char *f, ...) +{ + va_list args; + int len; + + if (likely(m->count < S_SIZE)) { + va_start(args, f); + len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); + va_end(args); + if (likely(m->count + len < S_SIZE)) { + m->count += len; + return 0; + } + } + m->count = S_SIZE; + printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); + return -1; +} + +static struct sbuff *sb_open(void) +{ + struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC); + + if (unlikely(!m)) { + local_bh_disable(); + do { + m = xchg(&emergency_ptr, NULL); + } while (!m); + } + m->count = 0; + return m; +} + +static void sb_close(struct sbuff *m) +{ + m->buf[m->count] = 0; + printk("%s\n", m->buf); + + if (likely(m != &emergency)) + kfree(m); + else { + xchg(&emergency_ptr, m); + local_bh_enable(); + } +} + -- cgit v1.2.3 From 31dee692e22eedaf2540fa543fa9c91df6ab8bda Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 4 Oct 2010 04:20:09 +0000 Subject: qlcnic: fix internal loopback test o Loop 10 times with delay of 1 ms to rcv packet. o Print garbage packet. o Try send/receive MAX(16) packet, instead of exit from test, if a packet is not received. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 26 +++++++++++++++++++------- drivers/net/qlcnic/qlcnic_init.c | 19 ++++++++++++++++++- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index cb9463bd6b1e..550cfe9a1b1d 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -636,6 +636,8 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset) } #define QLC_ILB_PKT_SIZE 64 +#define QLC_NUM_ILB_PKT 16 +#define QLC_ILB_MAX_RCV_LOOP 10 static void qlcnic_create_loopback_buff(unsigned char *data) { @@ -657,24 +659,34 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; struct sk_buff *skb; - int i; + int i, loop, cnt = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i < QLC_NUM_ILB_PKT; i++) { skb = dev_alloc_skb(QLC_ILB_PKT_SIZE); qlcnic_create_loopback_buff(skb->data); skb_put(skb, QLC_ILB_PKT_SIZE); adapter->diag_cnt = 0; - qlcnic_xmit_frame(skb, adapter->netdev); - msleep(5); - - qlcnic_process_rcv_ring_diag(sds_ring); + loop = 0; + do { + msleep(1); + qlcnic_process_rcv_ring_diag(sds_ring); + } while (loop++ < QLC_ILB_MAX_RCV_LOOP && + !adapter->diag_cnt); dev_kfree_skb_any(skb); + if (!adapter->diag_cnt) - return -1; + dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" + " not recevied\n", i + 1); + else + cnt++; + } + if (cnt != i) { + dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); + return -1; } return 0; } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 5c33d15c874a..908a25b5597a 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1693,6 +1693,18 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, spin_unlock(&rds_ring->lock); } +static void dump_skb(struct sk_buff *skb) +{ + int i; + unsigned char *data = skb->data; + + for (i = 0; i < skb->len; i++) { + printk("%02x ", data[i]); + if ((i & 0x0f) == 8) + printk("\n"); + } +} + static struct qlcnic_rx_buffer * qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, struct qlcnic_host_sds_ring *sds_ring, @@ -1723,13 +1735,18 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, if (!skb) return buffer; - skb_put(skb, rds_ring->skb_size); + if (length > rds_ring->skb_size) + skb_put(skb, rds_ring->skb_size); + else + skb_put(skb, length); if (pkt_offset) skb_pull(skb, pkt_offset); if (!qlcnic_check_loopback_buff(skb->data)) adapter->diag_cnt++; + else + dump_skb(skb); dev_kfree_skb_any(skb); adapter->stats.rx_pkts++; -- cgit v1.2.3 From ef1828058b8a37f7005be677686727bbbde77f6a Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 4 Oct 2010 04:20:10 +0000 Subject: qlcnic: fix eswitch stats Some of the counters are not implemented in fw. Fw return NOT AVAILABLE VALUE as (0xffffffffffffffff). Adding these counters, result in invalid value. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 12 ++++++++++++ drivers/net/qlcnic/qlcnic_ctx.c | 31 ++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 714ddf461d73..4667463d5523 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1169,6 +1169,18 @@ struct qlcnic_esw_func_cfg { #define QLCNIC_STATS_ESWITCH 2 #define QLCNIC_QUERY_RX_COUNTER 0 #define QLCNIC_QUERY_TX_COUNTER 1 +#define QLCNIC_ESW_STATS_NOT_AVAIL 0xffffffffffffffffULL + +#define QLCNIC_ADD_ESW_STATS(VAL1, VAL2)\ +do { \ + if (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) && \ + ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \ + (VAL1) = (VAL2); \ + else if (((VAL1) != QLCNIC_ESW_STATS_NOT_AVAIL) && \ + ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \ + (VAL1) += (VAL2); \ +} while (0) + struct __qlcnic_esw_statistics { __le16 context_id; __le16 version; diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 95a821e0b66f..a4c4d091739e 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -1016,7 +1016,14 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, if (adapter->npars == NULL) return -EIO; - memset(esw_stats, 0, sizeof(struct __qlcnic_esw_statistics)); + memset(esw_stats, 0, sizeof(u64)); + esw_stats->unicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->multicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->broadcast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->dropped_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->errors = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->local_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->numbytes = QLCNIC_ESW_STATS_NOT_AVAIL; esw_stats->context_id = eswitch; for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { @@ -1029,14 +1036,20 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, esw_stats->size = port_stats.size; esw_stats->version = port_stats.version; - esw_stats->unicast_frames += port_stats.unicast_frames; - esw_stats->multicast_frames += port_stats.multicast_frames; - esw_stats->broadcast_frames += port_stats.broadcast_frames; - esw_stats->dropped_frames += port_stats.dropped_frames; - esw_stats->errors += port_stats.errors; - esw_stats->local_frames += port_stats.local_frames; - esw_stats->numbytes += port_stats.numbytes; - + QLCNIC_ADD_ESW_STATS(esw_stats->unicast_frames, + port_stats.unicast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->multicast_frames, + port_stats.multicast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->broadcast_frames, + port_stats.broadcast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->dropped_frames, + port_stats.dropped_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->errors, + port_stats.errors); + QLCNIC_ADD_ESW_STATS(esw_stats->local_frames, + port_stats.local_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->numbytes, + port_stats.numbytes); ret = 0; } return ret; -- cgit v1.2.3 From c265eb6ecb63e4b3a6b86b617fa7fd955a0e0980 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 4 Oct 2010 04:20:11 +0000 Subject: qlcnic: fix diag register regs_buff[i] and diag_registers[j] array should use different index variable. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 550cfe9a1b1d..6a760140f792 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -343,7 +343,7 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring; u32 *regs_buff = p; - int ring, i = 0; + int ring, i = 0, j = 0; memset(p, 0, qlcnic_get_regs_len(dev)); regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | @@ -352,8 +352,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); regs_buff[1] = QLCNIC_MGMT_API_VERSION; - for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[i] != -1; i++) - regs_buff[i] = QLCRD32(adapter, diag_registers[i]); + for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++) + regs_buff[i] = QLCRD32(adapter, diag_registers[j]); if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) return; -- cgit v1.2.3 From b501595cbb8afeaa9aaa870b3d29ef051403511a Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 4 Oct 2010 04:20:12 +0000 Subject: qlcnic: fix endianess for lro ipaddress in ifa->ifa_address field are in big endian format. Also device requires ip address in big endian only. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 7 ++++++- drivers/net/qlcnic/qlcnic_hw.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 4667463d5523..7af3c6ce0b68 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -898,6 +898,11 @@ struct qlcnic_mac_req { u8 mac_addr[6]; }; +struct qlcnic_ipaddr { + __be32 ipv4; + __be32 ipv6[4]; +}; + #define QLCNIC_MSI_ENABLED 0x02 #define QLCNIC_MSIX_ENABLED 0x04 #define QLCNIC_LRO_ENABLED 0x08 @@ -1286,7 +1291,7 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32); int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter); int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable); -int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd); +int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd); int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable); void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup); diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index c198df90ff3c..68d56939a8d9 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -676,9 +676,10 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) return rv; } -int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) +int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd) { struct qlcnic_nic_req req; + struct qlcnic_ipaddr *ipa; u64 word; int rv; @@ -689,7 +690,8 @@ int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) req.req_hdr = cpu_to_le64(word); req.words[0] = cpu_to_le64(cmd); - req.words[1] = cpu_to_le64(ip); + ipa = (struct qlcnic_ipaddr *)&req.words[1]; + ipa->ipv4 = ip; rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) -- cgit v1.2.3 From 7e56cac4b68805470849ba373dd313ba0e7cdb81 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 4 Oct 2010 04:20:13 +0000 Subject: qlcnic: fix vlan TSO on big endian machine o desc->vlan_tci is in __le16 format. Doing htons and cpu_to_le64 again on vlan_tci, result in invalid value on ppc. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 7 ++++++- drivers/net/qlcnic/qlcnic_hw.c | 6 ++++-- drivers/net/qlcnic/qlcnic_main.c | 15 ++++++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 7af3c6ce0b68..9d80171a1fbf 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -898,6 +898,11 @@ struct qlcnic_mac_req { u8 mac_addr[6]; }; +struct qlcnic_vlan_req { + __le16 vlan_id; + __le16 rsvd[3]; +}; + struct qlcnic_ipaddr { __be32 ipv4; __be32 ipv6[4]; @@ -940,7 +945,7 @@ struct qlcnic_ipaddr { struct qlcnic_filter { struct hlist_node fnode; u8 faddr[ETH_ALEN]; - u16 vlan_id; + __le16 vlan_id; unsigned long ftime; }; diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 68d56939a8d9..712cfabc2825 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -375,10 +375,11 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, static int qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, - u16 vlan_id, unsigned op) + __le16 vlan_id, unsigned op) { struct qlcnic_nic_req req; struct qlcnic_mac_req *mac_req; + struct qlcnic_vlan_req *vlan_req; u64 word; memset(&req, 0, sizeof(struct qlcnic_nic_req)); @@ -391,7 +392,8 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, mac_req->op = op; memcpy(mac_req->mac_addr, addr, 6); - req.words[1] = cpu_to_le64(vlan_id); + vlan_req = (struct qlcnic_vlan_req *)&req.words[1]; + vlan_req->vlan_id = vlan_id; return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index a3d7705a2dda..6001f41a70ad 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -28,6 +28,7 @@ #include "qlcnic.h" +#include #include #include #include @@ -1834,11 +1835,12 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) } static void qlcnic_change_filter(struct qlcnic_adapter *adapter, - u64 uaddr, u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) + u64 uaddr, __le16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) { struct cmd_desc_type0 *hwdesc; struct qlcnic_nic_req *req; struct qlcnic_mac_req *mac_req; + struct qlcnic_vlan_req *vlan_req; u32 producer; u64 word; @@ -1856,7 +1858,8 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter, mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); - req->words[1] = cpu_to_le64(vlan_id); + vlan_req = (struct qlcnic_vlan_req *)&req->words[1]; + vlan_req->vlan_id = vlan_id; tx_ring->producer = get_next_index(producer, tx_ring->num_desc); } @@ -1875,7 +1878,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, struct hlist_node *tmp_hnode, *n; struct hlist_head *head; u64 src_addr = 0; - u16 vlan_id = 0; + __le16 vlan_id = 0; u8 hindex; if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) @@ -1928,7 +1931,8 @@ qlcnic_tso_check(struct net_device *netdev, struct vlan_ethhdr *vh; struct qlcnic_adapter *adapter = netdev_priv(netdev); u32 producer = tx_ring->producer; - int vlan_oob = first_desc->flags_opcode & cpu_to_le16(FLAGS_VLAN_OOB); + __le16 vlan_oob = first_desc->flags_opcode & + cpu_to_le16(FLAGS_VLAN_OOB); if (*(skb->data) & BIT_0) { flags |= BIT_0; @@ -1999,7 +2003,8 @@ qlcnic_tso_check(struct net_device *netdev, vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); skb_copy_from_linear_data(skb, vh, 12); vh->h_vlan_proto = htons(ETH_P_8021Q); - vh->h_vlan_TCI = htons(first_desc->vlan_TCI); + vh->h_vlan_TCI = (__be16)swab16((u16)first_desc->vlan_TCI); + skb_copy_from_linear_data_offset(skb, 12, (char *)vh + 16, copy_len - 16); -- cgit v1.2.3 From a1c0c459918e8c8ce152deba84f9ed27d7eb0e53 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 4 Oct 2010 04:20:14 +0000 Subject: qlcnic: sparse warning fixes Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ctx.c | 12 ++++++------ drivers/net/qlcnic/qlcnic_main.c | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index a4c4d091739e..75e3b19e35ee 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -742,15 +742,15 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, if (err == QLCNIC_RCODE_SUCCESS) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { - pci_info->id = le32_to_cpu(npar->id); - pci_info->active = le32_to_cpu(npar->active); - pci_info->type = le32_to_cpu(npar->type); + pci_info->id = le16_to_cpu(npar->id); + pci_info->active = le16_to_cpu(npar->active); + pci_info->type = le16_to_cpu(npar->type); pci_info->default_port = - le32_to_cpu(npar->default_port); + le16_to_cpu(npar->default_port); pci_info->tx_min_bw = - le32_to_cpu(npar->tx_min_bw); + le16_to_cpu(npar->tx_min_bw); pci_info->tx_max_bw = - le32_to_cpu(npar->tx_max_bw); + le16_to_cpu(npar->tx_max_bw); memcpy(pci_info->mac, npar->mac, ETH_ALEN); } } else { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 6001f41a70ad..59a213814334 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -521,9 +521,9 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) pfn = pci_info[i].id; if (pfn > QLCNIC_MAX_PCI_FUNC) return QL_STATUS_INVALID_PARAM; - adapter->npars[pfn].active = pci_info[i].active; - adapter->npars[pfn].type = pci_info[i].type; - adapter->npars[pfn].phy_port = pci_info[i].default_port; + adapter->npars[pfn].active = (u8)pci_info[i].active; + adapter->npars[pfn].type = (u8)pci_info[i].type; + adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port; adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; } @@ -723,7 +723,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) if (err) return err; - adapter->physical_port = nic_info.phys_port; + adapter->physical_port = (u8)nic_info.phys_port; adapter->switch_mode = nic_info.switch_mode; adapter->max_tx_ques = nic_info.max_tx_ques; adapter->max_rx_ques = nic_info.max_rx_ques; @@ -3762,7 +3762,7 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj, return ret; np_cfg[i].pci_func = i; - np_cfg[i].op_mode = nic_info.op_mode; + np_cfg[i].op_mode = (u8)nic_info.op_mode; np_cfg[i].port_num = nic_info.phys_port; np_cfg[i].fw_capab = nic_info.capabilities; np_cfg[i].min_bw = nic_info.min_tx_bw ; -- cgit v1.2.3 From aef3d898276e046bfa877cd20b8ee269b85161cd Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Mon, 4 Oct 2010 04:20:15 +0000 Subject: qlcnic: cleanup port mode setting Port mode setting is not required for Qlogic CNA adapters. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 59a213814334..4757908b29b5 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -46,11 +46,6 @@ char qlcnic_driver_name[] = "qlcnic"; static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; -static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; - -/* Default to restricted 1G auto-neg mode */ -static int wol_port_mode = 5; - static int qlcnic_mac_learn; module_param(qlcnic_mac_learn, int, 0644); MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); @@ -264,40 +259,6 @@ static void qlcnic_clear_stats(struct qlcnic_adapter *adapter) memset(&adapter->stats, 0, sizeof(adapter->stats)); } -static void qlcnic_set_port_mode(struct qlcnic_adapter *adapter) -{ - u32 val, data; - - val = adapter->ahw.board_type; - if ((val == QLCNIC_BRDTYPE_P3_HMEZ) || - (val == QLCNIC_BRDTYPE_P3_XG_LOM)) { - if (port_mode == QLCNIC_PORT_MODE_802_3_AP) { - data = QLCNIC_PORT_MODE_802_3_AP; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_XG) { - data = QLCNIC_PORT_MODE_XG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_1G) { - data = QLCNIC_PORT_MODE_AUTO_NEG_1G; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_XG) { - data = QLCNIC_PORT_MODE_AUTO_NEG_XG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else { - data = QLCNIC_PORT_MODE_AUTO_NEG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } - - if ((wol_port_mode != QLCNIC_PORT_MODE_802_3_AP) && - (wol_port_mode != QLCNIC_PORT_MODE_XG) && - (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_1G) && - (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_XG)) { - wol_port_mode = QLCNIC_PORT_MODE_AUTO_NEG; - } - QLCWR32(adapter, QLCNIC_WOL_PORT_MODE, wol_port_mode); - } -} - static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) { u32 control; @@ -1032,7 +993,6 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) err = qlcnic_pinit_from_rom(adapter); if (err) goto err_out; - qlcnic_set_port_mode(adapter); err = qlcnic_load_firmware(adapter); if (err) -- cgit v1.2.3 From 0bd9e6a964d86a19f54a9ba31168a37d64e451d1 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Mon, 4 Oct 2010 04:20:16 +0000 Subject: qlcnic: set mtu lower limit Setting mtu < 68 is not supported. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_hw.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9d80171a1fbf..42a288348aca 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -95,6 +95,7 @@ #define FIRST_PAGE_GROUP_END 0x100000 #define P3_MAX_MTU (9600) +#define P3_MIN_MTU (68) #define QLCNIC_MAX_ETHERHDR 32 /* This contains some padding */ #define QLCNIC_P3_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 712cfabc2825..9d3e16dbd043 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -758,9 +758,9 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) struct qlcnic_adapter *adapter = netdev_priv(netdev); int rc = 0; - if (mtu > P3_MAX_MTU) { - dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n", - P3_MAX_MTU); + if (mtu < P3_MIN_MTU || mtu > P3_MAX_MTU) { + dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes" + " not supported\n", P3_MAX_MTU, P3_MIN_MTU); return -EINVAL; } -- cgit v1.2.3 From 24824a09e35402b8d58dcc5be803a5ad3937bdba Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 2 Oct 2010 06:11:55 +0000 Subject: net: dynamic ingress_queue allocation ingress being not used very much, and net_device->ingress_queue being quite a big object (128 or 256 bytes), use a dynamic allocation if needed (tc qdisc add dev eth0 ingress ...) dev_ingress_queue(dev) helper should be used only with RTNL taken. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- include/linux/rtnetlink.h | 8 ++++++++ net/core/dev.c | 34 ++++++++++++++++++++++++++-------- net/sched/sch_api.c | 42 ++++++++++++++++++++++++++++-------------- net/sched/sch_generic.c | 12 ++++++++---- 5 files changed, 71 insertions(+), 27 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ceed3474014a..92d81edd5808 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -986,7 +986,7 @@ struct net_device { rx_handler_func_t *rx_handler; void *rx_handler_data; - struct netdev_queue ingress_queue; /* use two cache lines */ + struct netdev_queue __rcu *ingress_queue; /* * Cache lines mostly used on transmit path diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 68c436bddc88..0bb7b48632bd 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -6,6 +6,7 @@ #include #include #include +#include /* rtnetlink families. Values up to 127 are reserved for real address * families, values above 128 may be used arbitrarily. @@ -769,6 +770,13 @@ extern int lockdep_rtnl_is_held(void); #define rtnl_dereference(p) \ rcu_dereference_check(p, lockdep_rtnl_is_held()) +static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev) +{ + return rtnl_dereference(dev->ingress_queue); +} + +extern struct netdev_queue *dev_ingress_queue_create(struct net_device *dev); + extern void rtnetlink_init(void); extern void __rtnl_unlock(void); diff --git a/net/core/dev.c b/net/core/dev.c index a313bab1b754..ce6ad88c980b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2702,11 +2702,10 @@ EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); * the ingress scheduler, you just cant add policies on ingress. * */ -static int ing_filter(struct sk_buff *skb) +static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq) { struct net_device *dev = skb->dev; u32 ttl = G_TC_RTTL(skb->tc_verd); - struct netdev_queue *rxq; int result = TC_ACT_OK; struct Qdisc *q; @@ -2720,8 +2719,6 @@ static int ing_filter(struct sk_buff *skb) skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); - rxq = &dev->ingress_queue; - q = rxq->qdisc; if (q != &noop_qdisc) { spin_lock(qdisc_lock(q)); @@ -2737,7 +2734,9 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, struct net_device *orig_dev) { - if (skb->dev->ingress_queue.qdisc == &noop_qdisc) + struct netdev_queue *rxq = rcu_dereference(skb->dev->ingress_queue); + + if (!rxq || rxq->qdisc == &noop_qdisc) goto out; if (*pt_prev) { @@ -2745,7 +2744,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, *pt_prev = NULL; } - switch (ing_filter(skb)) { + switch (ing_filter(skb, rxq)) { case TC_ACT_SHOT: case TC_ACT_STOLEN: kfree_skb(skb); @@ -4940,7 +4939,6 @@ static void __netdev_init_queue_locks_one(struct net_device *dev, static void netdev_init_queue_locks(struct net_device *dev) { netdev_for_each_tx_queue(dev, __netdev_init_queue_locks_one, NULL); - __netdev_init_queue_locks_one(dev, &dev->ingress_queue, NULL); } unsigned long netdev_fix_features(unsigned long features, const char *name) @@ -5452,11 +5450,29 @@ static void netdev_init_one_queue(struct net_device *dev, static void netdev_init_queues(struct net_device *dev) { - netdev_init_one_queue(dev, &dev->ingress_queue, NULL); netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); spin_lock_init(&dev->tx_global_lock); } +struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) +{ + struct netdev_queue *queue = dev_ingress_queue(dev); + +#ifdef CONFIG_NET_CLS_ACT + if (queue) + return queue; + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) + return NULL; + netdev_init_one_queue(dev, queue, NULL); + __netdev_init_queue_locks_one(dev, queue, NULL); + queue->qdisc = &noop_qdisc; + queue->qdisc_sleeping = &noop_qdisc; + rcu_assign_pointer(dev->ingress_queue, queue); +#endif + return queue; +} + /** * alloc_netdev_mq - allocate network device * @sizeof_priv: size of private data to allocate space for @@ -5559,6 +5575,8 @@ void free_netdev(struct net_device *dev) kfree(dev->_tx); + kfree(rcu_dereference_raw(dev->ingress_queue)); + /* Flush device addresses */ dev_addr_flush(dev); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b8020784d0e9..b22ca2d1cebc 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -240,7 +240,10 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) if (q) goto out; - q = qdisc_match_from_root(dev->ingress_queue.qdisc_sleeping, handle); + if (dev_ingress_queue(dev)) + q = qdisc_match_from_root( + dev_ingress_queue(dev)->qdisc_sleeping, + handle); out: return q; } @@ -690,6 +693,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, (new && new->flags & TCQ_F_INGRESS)) { num_q = 1; ingress = 1; + if (!dev_ingress_queue(dev)) + return -ENOENT; } if (dev->flags & IFF_UP) @@ -701,7 +706,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, } for (i = 0; i < num_q; i++) { - struct netdev_queue *dev_queue = &dev->ingress_queue; + struct netdev_queue *dev_queue = dev_ingress_queue(dev); if (!ingress) dev_queue = netdev_get_tx_queue(dev, i); @@ -979,7 +984,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) return -ENOENT; q = qdisc_leaf(p, clid); } else { /* ingress */ - q = dev->ingress_queue.qdisc_sleeping; + if (dev_ingress_queue(dev)) + q = dev_ingress_queue(dev)->qdisc_sleeping; } } else { q = dev->qdisc; @@ -1043,8 +1049,9 @@ replay: if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) return -ENOENT; q = qdisc_leaf(p, clid); - } else { /*ingress */ - q = dev->ingress_queue.qdisc_sleeping; + } else { /* ingress */ + if (dev_ingress_queue_create(dev)) + q = dev_ingress_queue(dev)->qdisc_sleeping; } } else { q = dev->qdisc; @@ -1123,11 +1130,14 @@ replay: create_n_graft: if (!(n->nlmsg_flags&NLM_F_CREATE)) return -ENOENT; - if (clid == TC_H_INGRESS) - q = qdisc_create(dev, &dev->ingress_queue, p, - tcm->tcm_parent, tcm->tcm_parent, - tca, &err); - else { + if (clid == TC_H_INGRESS) { + if (dev_ingress_queue(dev)) + q = qdisc_create(dev, dev_ingress_queue(dev), p, + tcm->tcm_parent, tcm->tcm_parent, + tca, &err); + else + err = -ENOENT; + } else { struct netdev_queue *dev_queue; if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue) @@ -1304,8 +1314,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0) goto done; - dev_queue = &dev->ingress_queue; - if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0) + dev_queue = dev_ingress_queue(dev); + if (dev_queue && + tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, + &q_idx, s_q_idx) < 0) goto done; cont: @@ -1595,8 +1607,10 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0) goto done; - dev_queue = &dev->ingress_queue; - if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0) + dev_queue = dev_ingress_queue(dev); + if (dev_queue && + tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, + &t, s_t) < 0) goto done; done: diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 545278a1c478..3d57681bdb76 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -753,7 +753,8 @@ void dev_activate(struct net_device *dev) need_watchdog = 0; netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); - transition_one_qdisc(dev, &dev->ingress_queue, NULL); + if (dev_ingress_queue(dev)) + transition_one_qdisc(dev, dev_ingress_queue(dev), NULL); if (need_watchdog) { dev->trans_start = jiffies; @@ -812,7 +813,8 @@ static bool some_qdisc_is_busy(struct net_device *dev) void dev_deactivate(struct net_device *dev) { netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); - dev_deactivate_queue(dev, &dev->ingress_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + dev_deactivate_queue(dev, dev_ingress_queue(dev), &noop_qdisc); dev_watchdog_down(dev); @@ -838,7 +840,8 @@ void dev_init_scheduler(struct net_device *dev) { dev->qdisc = &noop_qdisc; netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); - dev_init_scheduler_queue(dev, &dev->ingress_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc); setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); } @@ -861,7 +864,8 @@ static void shutdown_scheduler_queue(struct net_device *dev, void dev_shutdown(struct net_device *dev) { netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); - shutdown_scheduler_queue(dev, &dev->ingress_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc); qdisc_destroy(dev->qdisc); dev->qdisc = &noop_qdisc; -- cgit v1.2.3 From 13f5bf18ba657d2d17c8fcf584e50359c718dd4b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Oct 2010 00:27:05 -0700 Subject: ipvs: Use frag walker helper in SCTP proto support. Signed-off-by: David S. Miller Acked-by: Simon Horman --- net/netfilter/ipvs/ip_vs_proto_sctp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 4c0855cb006e..2f982a4c4770 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -61,6 +61,7 @@ sctp_snat_handler(struct sk_buff *skb, { sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -89,8 +90,8 @@ sctp_snat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -102,9 +103,9 @@ static int sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp) { - sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -133,8 +134,8 @@ sctp_dnat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -145,9 +146,9 @@ sctp_dnat_handler(struct sk_buff *skb, static int sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; unsigned int sctphoff; struct sctphdr *sh, _sctph; + struct sk_buff *iter; __le32 cmp; __le32 val; __u32 tmp; @@ -166,9 +167,9 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) cmp = sh->checksum; tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb)); - for (; list; list = list->next) - tmp = sctp_update_cksum((__u8 *) list->data, - skb_headlen(list), tmp); + skb_walk_frags(skb, iter) + tmp = sctp_update_cksum((__u8 *) iter->data, + skb_headlen(iter), tmp); val = sctp_end_cksum(tmp); -- cgit v1.2.3 From 29fa060eab3f524d338566d34c1d9e704579ae5e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Oct 2010 00:29:48 -0700 Subject: net: relax rtnl_dereference() rtnl_dereference() is used in contexts where RTNL is held, to fetch an RCU protected pointer. Updates to this pointer are prevented by RTNL, so we dont need smp_read_barrier_depends() and the ACCESS_ONCE() provided in rcu_dereference_check(). rtnl_dereference() is mainly a macro to document the locking invariant. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 0bb7b48632bd..d42f274418b8 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -755,20 +755,22 @@ extern int lockdep_rtnl_is_held(void); * @p: The pointer to read, prior to dereferencing * * Do an rcu_dereference(p), but check caller either holds rcu_read_lock() - * or RTNL + * or RTNL. Note : Please prefer rtnl_dereference() or rcu_dereference() */ #define rcu_dereference_rtnl(p) \ rcu_dereference_check(p, rcu_read_lock_held() || \ lockdep_rtnl_is_held()) /** - * rtnl_dereference - rcu_dereference with debug checking + * rtnl_dereference - fetch RCU pointer when updates are prevented by RTNL * @p: The pointer to read, prior to dereferencing * - * Do an rcu_dereference(p), but check caller holds RTNL + * Return the value of the specified RCU-protected pointer, but omit + * both the smp_read_barrier_depends() and the ACCESS_ONCE(), because + * caller holds RTNL. */ #define rtnl_dereference(p) \ - rcu_dereference_check(p, lockdep_rtnl_is_held()) + rcu_dereference_protected(p, lockdep_rtnl_is_held()) static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev) { -- cgit v1.2.3 From cf93c94581bab447a5634c6d737c1cf38c080261 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 3 Oct 2010 23:43:32 +0000 Subject: net/phy: fix many "defined but unused" warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MODULE_DEVICE_TABLE only expands to something if it's compiled for a module. So when building-in support for the phys, the mdio_device_id tables are unused. Marking them with __maybe_unused fixes the following warnings: drivers/net/phy/bcm63xx.c:134: warning: 'bcm63xx_tbl' defined but not used drivers/net/phy/broadcom.c:933: warning: 'broadcom_tbl' defined but not used drivers/net/phy/cicada.c:162: warning: 'cicada_tbl' defined but not used drivers/net/phy/davicom.c:222: warning: 'davicom_tbl' defined but not used drivers/net/phy/et1011c.c:114: warning: 'et1011c_tbl' defined but not used drivers/net/phy/icplus.c:137: warning: 'icplus_tbl' defined but not used drivers/net/phy/lxt.c:226: warning: 'lxt_tbl' defined but not used drivers/net/phy/marvell.c:724: warning: 'marvell_tbl' defined but not used drivers/net/phy/micrel.c:234: warning: 'micrel_tbl' defined but not used drivers/net/phy/national.c:154: warning: 'ns_tbl' defined but not used drivers/net/phy/qsemi.c:141: warning: 'qs6612_tbl' defined but not used drivers/net/phy/realtek.c:82: warning: 'realtek_tbl' defined but not used drivers/net/phy/smsc.c:257: warning: 'smsc_tbl' defined but not used drivers/net/phy/ste10Xp.c:135: warning: 'ste10Xp_tbl' defined but not used drivers/net/phy/vitesse.c:195: warning: 'vitesse_tbl' defined but not used Signed-off-by: Uwe Kleine-König Signed-off-by: David S. Miller --- drivers/net/phy/bcm63xx.c | 2 +- drivers/net/phy/broadcom.c | 2 +- drivers/net/phy/cicada.c | 2 +- drivers/net/phy/davicom.c | 2 +- drivers/net/phy/et1011c.c | 2 +- drivers/net/phy/icplus.c | 2 +- drivers/net/phy/lxt.c | 2 +- drivers/net/phy/marvell.c | 2 +- drivers/net/phy/micrel.c | 2 +- drivers/net/phy/national.c | 2 +- drivers/net/phy/qsemi.c | 2 +- drivers/net/phy/realtek.c | 2 +- drivers/net/phy/smsc.c | 2 +- drivers/net/phy/ste10Xp.c | 2 +- drivers/net/phy/vitesse.c | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c index c12815679837..e16f98cb4f04 100644 --- a/drivers/net/phy/bcm63xx.c +++ b/drivers/net/phy/bcm63xx.c @@ -131,7 +131,7 @@ static void __exit bcm63xx_phy_exit(void) module_init(bcm63xx_phy_init); module_exit(bcm63xx_phy_exit); -static struct mdio_device_id bcm63xx_tbl[] = { +static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = { { 0x00406000, 0xfffffc00 }, { 0x002bdc00, 0xfffffc00 }, { } diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 4accd83d3dfe..d84c4224dd12 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -930,7 +930,7 @@ static void __exit broadcom_exit(void) module_init(broadcom_init); module_exit(broadcom_exit); -static struct mdio_device_id broadcom_tbl[] = { +static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM5411, 0xfffffff0 }, { PHY_ID_BCM5421, 0xfffffff0 }, { PHY_ID_BCM5461, 0xfffffff0 }, diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c index 1a325d63756b..d28173161c21 100644 --- a/drivers/net/phy/cicada.c +++ b/drivers/net/phy/cicada.c @@ -159,7 +159,7 @@ static void __exit cicada_exit(void) module_init(cicada_init); module_exit(cicada_exit); -static struct mdio_device_id cicada_tbl[] = { +static struct mdio_device_id __maybe_unused cicada_tbl[] = { { 0x000fc410, 0x000ffff0 }, { 0x000fc440, 0x000fffc0 }, { } diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index 29c17617a2ec..2f774acdb551 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -219,7 +219,7 @@ static void __exit davicom_exit(void) module_init(davicom_init); module_exit(davicom_exit); -static struct mdio_device_id davicom_tbl[] = { +static struct mdio_device_id __maybe_unused davicom_tbl[] = { { 0x0181b880, 0x0ffffff0 }, { 0x0181b8a0, 0x0ffffff0 }, { 0x00181b80, 0x0ffffff0 }, diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c index 13995f52d6af..a8eb19ec3183 100644 --- a/drivers/net/phy/et1011c.c +++ b/drivers/net/phy/et1011c.c @@ -111,7 +111,7 @@ static void __exit et1011c_exit(void) module_init(et1011c_init); module_exit(et1011c_exit); -static struct mdio_device_id et1011c_tbl[] = { +static struct mdio_device_id __maybe_unused et1011c_tbl[] = { { 0x0282f014, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index 3f2583f18a39..c1d2d251fe8b 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -134,7 +134,7 @@ static void __exit ip175c_exit(void) module_init(ip175c_init); module_exit(ip175c_exit); -static struct mdio_device_id icplus_tbl[] = { +static struct mdio_device_id __maybe_unused icplus_tbl[] = { { 0x02430d80, 0x0ffffff0 }, { } }; diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index 29c39ff85de5..6f6e8b616a62 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -223,7 +223,7 @@ static void __exit lxt_exit(void) module_init(lxt_init); module_exit(lxt_exit); -static struct mdio_device_id lxt_tbl[] = { +static struct mdio_device_id __maybe_unused lxt_tbl[] = { { 0x78100000, 0xfffffff0 }, { 0x001378e0, 0xfffffff0 }, { 0x00137a10, 0xfffffff0 }, diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 0101f2bdf400..ed43c0016c64 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -721,7 +721,7 @@ static void __exit marvell_exit(void) module_init(marvell_init); module_exit(marvell_exit); -static struct mdio_device_id marvell_tbl[] = { +static struct mdio_device_id __maybe_unused marvell_tbl[] = { { 0x01410c60, 0xfffffff0 }, { 0x01410c90, 0xfffffff0 }, { 0x01410cc0, 0xfffffff0 }, diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 8bb7db676a5c..0fd1678bc5a9 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -231,7 +231,7 @@ MODULE_DESCRIPTION("Micrel PHY driver"); MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); -static struct mdio_device_id micrel_tbl[] = { +static struct mdio_device_id __maybe_unused micrel_tbl[] = { { PHY_ID_KSZ9021, 0x000fff10 }, { PHY_ID_KS8001, 0x00fffff0 }, { PHY_ID_KS8737, 0x00fffff0 }, diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index a73ba0bcc0ce..0620ba963508 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c @@ -151,7 +151,7 @@ MODULE_LICENSE("GPL"); module_init(ns_init); module_exit(ns_exit); -static struct mdio_device_id ns_tbl[] = { +static struct mdio_device_id __maybe_unused ns_tbl[] = { { DP83865_PHY_ID, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c index 6736b23f1b28..fe0d0a15d5e1 100644 --- a/drivers/net/phy/qsemi.c +++ b/drivers/net/phy/qsemi.c @@ -138,7 +138,7 @@ static void __exit qs6612_exit(void) module_init(qs6612_init); module_exit(qs6612_exit); -static struct mdio_device_id qs6612_tbl[] = { +static struct mdio_device_id __maybe_unused qs6612_tbl[] = { { 0x00181440, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index f567c0e1aaa1..a4eae750a414 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -79,7 +79,7 @@ static void __exit realtek_exit(void) module_init(realtek_init); module_exit(realtek_exit); -static struct mdio_device_id realtek_tbl[] = { +static struct mdio_device_id __maybe_unused realtek_tbl[] = { { 0x001cc912, 0x001fffff }, { } }; diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 78fa988256fc..342505c976d6 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -254,7 +254,7 @@ MODULE_LICENSE("GPL"); module_init(smsc_init); module_exit(smsc_exit); -static struct mdio_device_id smsc_tbl[] = { +static struct mdio_device_id __maybe_unused smsc_tbl[] = { { 0x0007c0a0, 0xfffffff0 }, { 0x0007c0b0, 0xfffffff0 }, { 0x0007c0c0, 0xfffffff0 }, diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c index 72290099e5e1..187a2fa814f2 100644 --- a/drivers/net/phy/ste10Xp.c +++ b/drivers/net/phy/ste10Xp.c @@ -132,7 +132,7 @@ static void __exit ste10Xp_exit(void) module_init(ste10Xp_init); module_exit(ste10Xp_exit); -static struct mdio_device_id ste10Xp_tbl[] = { +static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = { { STE101P_PHY_ID, 0xfffffff0 }, { STE100P_PHY_ID, 0xffffffff }, { } diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 45cce50a2799..5d8f6e17bd55 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -192,7 +192,7 @@ static void __exit vsc82xx_exit(void) module_init(vsc82xx_init); module_exit(vsc82xx_exit); -static struct mdio_device_id vitesse_tbl[] = { +static struct mdio_device_id __maybe_unused vitesse_tbl[] = { { PHY_ID_VSC8244, 0x000fffc0 }, { PHY_ID_VSC8221, 0x000ffff0 }, { } -- cgit v1.2.3 From 10ff4c682972bf714c03ea71e169472cdc329a1e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sun, 3 Oct 2010 23:43:33 +0000 Subject: don't let BCM63XX_PHY depend on non-existant symbol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel doesn't have a symbol called BCM63XX. There is a symbol BCM63XX_ENET (introduced in 9b1fc55a0500, 6 weeks after 09bb9aa0ed that introduced BCM63XX_PHY), but the driver compiles without that, too. Cc: Maxime Bizon Cc: Florian Fainelli Cc: David S. Miller Cc: Ralf Baechle Signed-off-by: Uwe Kleine-König Signed-off-by: David S. Miller --- drivers/net/phy/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index eb799b36c86a..cb3d13e4e074 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -58,7 +58,6 @@ config BROADCOM_PHY config BCM63XX_PHY tristate "Drivers for Broadcom 63xx SOCs internal PHY" - depends on BCM63XX ---help--- Currently supports the 6348 and 6358 PHYs. -- cgit v1.2.3 From ee624599d32bc698212d3c04faf908dc01a40457 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 4 Oct 2010 04:35:39 +0000 Subject: caif: remove duplicated include Remove duplicated include. Signed-off-by: Nicolas Kaiser Acked-by: Sjur Braendeland Signed-off-by: David S. Miller --- net/caif/caif_socket.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 4d918f8f4e67..abcba5358b63 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From debf279a81c93d6942a50ec0fd3ba1f158b109fb Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Oct 2010 15:44:30 +0000 Subject: qlcnic: remove dead code This driver has several pieces of dead code (found by running make namespacecheck). This patch removes them. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 7 -- drivers/net/qlcnic/qlcnic_ctx.c | 169 ---------------------------------------- 2 files changed, 176 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 42a288348aca..a1fabdc10b59 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1323,19 +1323,12 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); /* Management functions */ -int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8); int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*); -int qlcnic_reset_partition(struct qlcnic_adapter *, u8); /* eSwitch management functions */ -int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8, - struct qlcnic_eswitch *); -int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, - struct qlcnic_eswitch *); -int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); int qlcnic_config_switch_port(struct qlcnic_adapter *, struct qlcnic_esw_func_cfg *); int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *, diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 75e3b19e35ee..1cdc05dade6b 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -556,32 +556,6 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) } } -/* Set MAC address of a NIC partition */ -int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac) -{ - int err = 0; - u32 arg1, arg2, arg3; - - arg1 = adapter->ahw.pci_func | BIT_9; - arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24); - arg3 = mac[4] | (mac[5] << 16); - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - arg1, - arg2, - arg3, - QLCNIC_CDRP_CMD_MAC_ADDRESS); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to set mac address%d\n", err); - err = -EIO; - } - - return err; -} /* Get MAC address of a NIC partition */ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) @@ -764,149 +738,6 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, return err; } -/* Reset a NIC partition */ - -int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no) -{ - int err = -EIO; - - if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - func_no, - 0, - 0, - QLCNIC_CDRP_CMD_RESET_NPAR); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to issue reset partition%d\n", err); - err = -EIO; - } - - return err; -} - -/* Get eSwitch Capabilities */ -int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, - struct qlcnic_eswitch *eswitch) -{ - int err = -EIO; - u32 arg1, arg2; - - if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) - return err; - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - port, - 0, - 0, - QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY); - - if (err == QLCNIC_RCODE_SUCCESS) { - arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); - - eswitch->port = arg1 & 0xf; - eswitch->max_ucast_filters = LSW(arg2); - eswitch->max_active_vlans = MSW(arg2) & 0xfff; - if (arg1 & BIT_6) - eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; - if (arg1 & BIT_7) - eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE; - if (arg1 & BIT_8) - eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; - } else { - dev_err(&adapter->pdev->dev, - "Failed to get eswitch capabilities%d\n", err); - } - - return err; -} - -/* Get current status of eswitch */ -int qlcnic_get_eswitch_status(struct qlcnic_adapter *adapter, u8 port, - struct qlcnic_eswitch *eswitch) -{ - int err = -EIO; - u32 arg1, arg2; - - if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - port, - 0, - 0, - QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS); - - if (err == QLCNIC_RCODE_SUCCESS) { - arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); - - eswitch->port = arg1 & 0xf; - eswitch->active_vports = LSB(arg2); - eswitch->active_ucast_filters = MSB(arg2); - eswitch->active_vlans = LSB(MSW(arg2)); - if (arg1 & BIT_6) - eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; - if (arg1 & BIT_8) - eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; - - } else { - dev_err(&adapter->pdev->dev, - "Failed to get eswitch status%d\n", err); - } - - return err; -} - -/* Enable/Disable eSwitch */ -int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable) -{ - int err = -EIO; - u32 arg1, arg2; - struct qlcnic_eswitch *eswitch; - - if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; - - eswitch = &adapter->eswitch[id]; - if (!eswitch) - return err; - - arg1 = eswitch->port | (enable ? BIT_4 : 0); - arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) | - (eswitch->max_active_vlans << 16); - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - arg1, - arg2, - 0, - QLCNIC_CDRP_CMD_TOGGLE_ESWITCH); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to enable eswitch%d\n", eswitch->port); - eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; - err = -EIO; - } else { - eswitch->flags |= QLCNIC_SWITCH_ENABLE; - dev_info(&adapter->pdev->dev, - "Enabled eSwitch for port %d\n", eswitch->port); - } - - return err; -} - /* Configure eSwitch for port mirroring */ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, u8 enable_mirroring, u8 pci_func) -- cgit v1.2.3 From e3d32687a624845e97f9717d9d2027b44b8c49a2 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Oct 2010 19:59:59 +0000 Subject: wimax: make functions local Make wimax variables and functions local if possible. Compile tested only. This also removes a couple of unused EXPORT_SYMBOL. If this breaks some out of tree code, please fix that by putting the code in the kernel tree. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/control.c | 18 ++++++++---------- drivers/net/wimax/i2400m/driver.c | 2 +- drivers/net/wimax/i2400m/i2400m-sdio.h | 1 - drivers/net/wimax/i2400m/i2400m.h | 9 --------- drivers/net/wimax/i2400m/rx.c | 2 +- drivers/net/wimax/i2400m/sdio-rx.c | 2 +- 6 files changed, 11 insertions(+), 23 deletions(-) diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index 9fb03082153a..12b84ed0e38a 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -98,7 +98,7 @@ MODULE_PARM_DESC(power_save_disabled, "False by default (so the device is told to do power " "saving)."); -int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ +static int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ module_param_named(passive_mode, i2400m_passive_mode, int, 0644); MODULE_PARM_DESC(passive_mode, "If true, the driver will not do any device setup " @@ -558,8 +558,9 @@ void i2400m_report_hook(struct i2400m *i2400m, * processing should be done in the function that calls the * command. This is here for some cases where it can't happen... */ -void i2400m_msg_ack_hook(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) +static void i2400m_msg_ack_hook(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, + size_t size) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1135,7 +1136,7 @@ error_alloc: * i2400m_report_state_hook() to parse the answer. This will set the * carrier state, as well as the RF Kill switches state. */ -int i2400m_cmd_get_state(struct i2400m *i2400m) +static int i2400m_cmd_get_state(struct i2400m *i2400m) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1177,8 +1178,6 @@ error_msg_to_dev: error_alloc: return result; } -EXPORT_SYMBOL_GPL(i2400m_cmd_get_state); - /** * Set basic configuration settings @@ -1190,8 +1189,9 @@ EXPORT_SYMBOL_GPL(i2400m_cmd_get_state); * right endianess (LE). * @arg_size: number of pointers in the @args array */ -int i2400m_set_init_config(struct i2400m *i2400m, - const struct i2400m_tlv_hdr **arg, size_t args) +static int i2400m_set_init_config(struct i2400m *i2400m, + const struct i2400m_tlv_hdr **arg, + size_t args) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1258,8 +1258,6 @@ none: return result; } -EXPORT_SYMBOL_GPL(i2400m_set_init_config); - /** * i2400m_set_idle_timeout - Set the device's idle mode timeout diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 9c8b78d4abd2..cdedab46ba21 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -122,7 +122,7 @@ struct i2400m_work *__i2400m_work_setup( * works struct was already queued, but we have just allocated it, so * it should not happen. */ -int i2400m_schedule_work(struct i2400m *i2400m, +static int i2400m_schedule_work(struct i2400m *i2400m, void (*fn)(struct work_struct *), gfp_t gfp_flags, const void *pl, size_t pl_size) { diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h index 360d4fb195f4..1d63ffdedfde 100644 --- a/drivers/net/wimax/i2400m/i2400m-sdio.h +++ b/drivers/net/wimax/i2400m/i2400m-sdio.h @@ -140,7 +140,6 @@ void i2400ms_init(struct i2400ms *i2400ms) extern int i2400ms_rx_setup(struct i2400ms *); extern void i2400ms_rx_release(struct i2400ms *); -extern ssize_t __i2400ms_rx_get_size(struct i2400ms *); extern int i2400ms_tx_setup(struct i2400ms *); extern void i2400ms_tx_release(struct i2400ms *); diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index fa74777fd65f..59ac7705e76e 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -910,28 +910,19 @@ struct i2400m_work { u8 pl[0]; }; -extern int i2400m_schedule_work(struct i2400m *, - void (*)(struct work_struct *), gfp_t, - const void *, size_t); - extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, char *, size_t); extern int i2400m_msg_size_check(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t); extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int); -extern void i2400m_msg_ack_hook(struct i2400m *, - const struct i2400m_l3l4_hdr *, size_t); extern void i2400m_report_hook(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); extern void i2400m_report_hook_work(struct work_struct *); extern int i2400m_cmd_enter_powersave(struct i2400m *); -extern int i2400m_cmd_get_state(struct i2400m *); extern int i2400m_cmd_exit_idle(struct i2400m *); extern struct sk_buff *i2400m_get_device_info(struct i2400m *); extern int i2400m_firmware_check(struct i2400m *); -extern int i2400m_set_init_config(struct i2400m *, - const struct i2400m_tlv_hdr **, size_t); extern int i2400m_set_idle_timeout(struct i2400m *, unsigned); static inline diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 8cc9e319f435..c4876d029201 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -922,7 +922,7 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq, * rx_roq_refcount becomes zero. This routine gets executed when * rx_roq_refcount becomes zero. */ -void i2400m_rx_roq_destroy(struct kref *ref) +static void i2400m_rx_roq_destroy(struct kref *ref) { unsigned itr; struct i2400m *i2400m diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c index 8b809c2ead6c..fb6396dd115f 100644 --- a/drivers/net/wimax/i2400m/sdio-rx.c +++ b/drivers/net/wimax/i2400m/sdio-rx.c @@ -87,7 +87,7 @@ static const __le32 i2400m_ACK_BARKER[4] = { * * sdio_readl() doesn't work. */ -ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) +static ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) { int ret, cnt, val; ssize_t rx_size; -- cgit v1.2.3 From 6a31d2a97c04ffe9b161ec0177a2296366ff9249 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Oct 2010 20:00:18 +0000 Subject: fib: cleanups Code style cleanups before upcoming functional changes. C99 initializer for fib_props array. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 121 ++++++++++++---------- net/ipv4/fib_rules.c | 10 +- net/ipv4/fib_semantics.c | 257 +++++++++++++++++++++++++---------------------- 3 files changed, 206 insertions(+), 182 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 4a69a957872b..b05c23b05a9f 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -225,30 +225,33 @@ EXPORT_SYMBOL(inet_addr_type); unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr) { - return __inet_dev_addr_type(net, dev, addr); + return __inet_dev_addr_type(net, dev, addr); } EXPORT_SYMBOL(inet_dev_addr_type); /* Given (packet source, input interface) and optional (dst, oif, tos): - - (main) check, that source is valid i.e. not broadcast or our local - address. - - figure out what "logical" interface this packet arrived - and calculate "specific destination" address. - - check, that packet arrived from expected physical interface. + * - (main) check, that source is valid i.e. not broadcast or our local + * address. + * - figure out what "logical" interface this packet arrived + * and calculate "specific destination" address. + * - check, that packet arrived from expected physical interface. */ - int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark) { struct in_device *in_dev; - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = src, - .saddr = dst, - .tos = tos } }, - .mark = mark, - .iif = oif }; - + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = src, + .saddr = dst, + .tos = tos + } + }, + .mark = mark, + .iif = oif + }; struct fib_result res; int no_addr, rpf, accept_local; bool dev_match; @@ -477,9 +480,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, } /* - * Handle IP routing ioctl calls. These are used to manipulate the routing tables + * Handle IP routing ioctl calls. + * These are used to manipulate the routing tables */ - int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) { struct fib_config cfg; @@ -523,7 +526,7 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) return -EINVAL; } -const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { +const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = { [RTA_DST] = { .type = NLA_U32 }, [RTA_SRC] = { .type = NLA_U32 }, [RTA_IIF] = { .type = NLA_U32 }, @@ -537,7 +540,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { }; static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, - struct nlmsghdr *nlh, struct fib_config *cfg) + struct nlmsghdr *nlh, struct fib_config *cfg) { struct nlattr *attr; int err, remaining; @@ -692,12 +695,11 @@ out: } /* Prepare and feed intra-kernel routing request. - Really, it should be netlink message, but :-( netlink - can be not configured, so that we feed it directly - to fib engine. It is legal, because all events occur - only when netlink is already locked. + * Really, it should be netlink message, but :-( netlink + * can be not configured, so that we feed it directly + * to fib engine. It is legal, because all events occur + * only when netlink is already locked. */ - static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa) { struct net *net = dev_net(ifa->ifa_dev->dev); @@ -743,9 +745,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) struct in_ifaddr *prim = ifa; __be32 mask = ifa->ifa_mask; __be32 addr = ifa->ifa_local; - __be32 prefix = ifa->ifa_address&mask; + __be32 prefix = ifa->ifa_address & mask; - if (ifa->ifa_flags&IFA_F_SECONDARY) { + if (ifa->ifa_flags & IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, prefix, mask); if (prim == NULL) { printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n"); @@ -755,22 +757,24 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim); - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return; /* Add broadcast address, if it is explicitly assigned. */ if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); - if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && + if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) && (prefix != addr || ifa->ifa_prefixlen < 32)) { - fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim); + fib_magic(RTM_NEWROUTE, + dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, + prefix, ifa->ifa_prefixlen, prim); /* Add network specific broadcasts, when it takes a sense */ if (ifa->ifa_prefixlen < 31) { fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim); - fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim); + fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask, + 32, prim); } } } @@ -781,17 +785,18 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) struct net_device *dev = in_dev->dev; struct in_ifaddr *ifa1; struct in_ifaddr *prim = ifa; - __be32 brd = ifa->ifa_address|~ifa->ifa_mask; - __be32 any = ifa->ifa_address&ifa->ifa_mask; + __be32 brd = ifa->ifa_address | ~ifa->ifa_mask; + __be32 any = ifa->ifa_address & ifa->ifa_mask; #define LOCAL_OK 1 #define BRD_OK 2 #define BRD0_OK 4 #define BRD1_OK 8 unsigned ok = 0; - if (!(ifa->ifa_flags&IFA_F_SECONDARY)) - fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, any, ifa->ifa_prefixlen, prim); + if (!(ifa->ifa_flags & IFA_F_SECONDARY)) + fib_magic(RTM_DELROUTE, + dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, + any, ifa->ifa_prefixlen, prim); else { prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); if (prim == NULL) { @@ -801,9 +806,9 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) } /* Deletion is more complicated than add. - We should take care of not to delete too much :-) - - Scan address list to be sure that addresses are really gone. + * We should take care of not to delete too much :-) + * + * Scan address list to be sure that addresses are really gone. */ for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { @@ -817,23 +822,23 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) ok |= BRD0_OK; } - if (!(ok&BRD_OK)) + if (!(ok & BRD_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); - if (!(ok&BRD1_OK)) + if (!(ok & BRD1_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); - if (!(ok&BRD0_OK)) + if (!(ok & BRD0_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); - if (!(ok&LOCAL_OK)) { + if (!(ok & LOCAL_OK)) { fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim); /* Check, that this local address finally disappeared. */ if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) { /* And the last, but not the least thing. - We must flush stray FIB entries. - - First of all, we scan fib_info list searching - for stray nexthop entries, then ignite fib_flush. - */ + * We must flush stray FIB entries. + * + * First of all, we scan fib_info list searching + * for stray nexthop entries, then ignite fib_flush. + */ if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) fib_flush(dev_net(dev)); } @@ -844,14 +849,20 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) #undef BRD1_OK } -static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) +static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) { struct fib_result res; - struct flowi fl = { .mark = frn->fl_mark, - .nl_u = { .ip4_u = { .daddr = frn->fl_addr, - .tos = frn->fl_tos, - .scope = frn->fl_scope } } }; + struct flowi fl = { + .mark = frn->fl_mark, + .nl_u = { + .ip4_u = { + .daddr = frn->fl_addr, + .tos = frn->fl_tos, + .scope = frn->fl_scope + } + } + }; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; @@ -899,8 +910,8 @@ static void nl_fib_input(struct sk_buff *skb) nl_fib_lookup(frn, tb); - pid = NETLINK_CB(skb).pid; /* pid of sending process */ - NETLINK_CB(skb).pid = 0; /* from kernel */ + pid = NETLINK_CB(skb).pid; /* pid of sending process */ + NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_group = 0; /* unicast */ netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT); } @@ -947,7 +958,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, fib_del_ifaddr(ifa); if (ifa->ifa_dev->ifa_list == NULL) { /* Last address was deleted from this interface. - Disable IP. + * Disable IP. */ fib_disable_ip(dev, 1, 0); } else { diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 76daeb5ff564..32300521e32c 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -6,7 +6,7 @@ * IPv4 Forwarding Information Base: policy rules. * * Authors: Alexey Kuznetsov, - * Thomas Graf + * Thomas Graf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -14,7 +14,7 @@ * 2 of the License, or (at your option) any later version. * * Fixes: - * Rani Assaf : local_rule cannot be deleted + * Rani Assaf : local_rule cannot be deleted * Marc Boucher : routing by fwmark */ @@ -32,8 +32,7 @@ #include #include -struct fib4_rule -{ +struct fib4_rule { struct fib_rule common; u8 dst_len; u8 src_len; @@ -91,7 +90,8 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, goto errout; } - if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL) + tbl = fib_get_table(rule->fr_net, rule->table); + if (!tbl) goto errout; err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result); diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 20f09c5b31e8..ba52f399a898 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -60,21 +60,30 @@ static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE]; static DEFINE_SPINLOCK(fib_multipath_lock); -#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \ -for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++) - -#define change_nexthops(fi) { int nhsel; struct fib_nh *nexthop_nh; \ -for (nhsel=0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nexthop_nh++, nhsel++) +#define for_nexthops(fi) { \ + int nhsel; const struct fib_nh *nh; \ + for (nhsel = 0, nh = (fi)->fib_nh; \ + nhsel < (fi)->fib_nhs; \ + nh++, nhsel++) + +#define change_nexthops(fi) { \ + int nhsel; struct fib_nh *nexthop_nh; \ + for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ + nhsel < (fi)->fib_nhs; \ + nexthop_nh++, nhsel++) #else /* CONFIG_IP_ROUTE_MULTIPATH */ /* Hope, that gcc will optimize it to get rid of dummy loop */ -#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \ -for (nhsel=0; nhsel < 1; nhsel++) +#define for_nexthops(fi) { \ + int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \ + for (nhsel = 0; nhsel < 1; nhsel++) -#define change_nexthops(fi) { int nhsel = 0; struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ -for (nhsel=0; nhsel < 1; nhsel++) +#define change_nexthops(fi) { \ + int nhsel; \ + struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ + for (nhsel = 0; nhsel < 1; nhsel++) #endif /* CONFIG_IP_ROUTE_MULTIPATH */ @@ -86,54 +95,54 @@ static const struct int error; u8 scope; } fib_props[RTN_MAX + 1] = { - { + [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_UNSPEC */ - { + }, + [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_UNICAST */ - { + }, + [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST, - }, /* RTN_LOCAL */ - { + }, + [RTN_BROADCAST] = { .error = 0, .scope = RT_SCOPE_LINK, - }, /* RTN_BROADCAST */ - { + }, + [RTN_ANYCAST] = { .error = 0, .scope = RT_SCOPE_LINK, - }, /* RTN_ANYCAST */ - { + }, + [RTN_MULTICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_MULTICAST */ - { + }, + [RTN_BLACKHOLE] = { .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_BLACKHOLE */ - { + }, + [RTN_UNREACHABLE] = { .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_UNREACHABLE */ - { + }, + [RTN_PROHIBIT] = { .error = -EACCES, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_PROHIBIT */ - { + }, + [RTN_THROW] = { .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_THROW */ - { + }, + [RTN_NAT] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_NAT */ - { + }, + [RTN_XRESOLVE] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_XRESOLVE */ + }, }; @@ -142,7 +151,7 @@ static const struct void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { - printk(KERN_WARNING "Freeing alive fib_info %p\n", fi); + pr_warning("Freeing alive fib_info %p\n", fi); return; } change_nexthops(fi) { @@ -173,7 +182,7 @@ void fib_release_info(struct fib_info *fi) spin_unlock_bh(&fib_info_lock); } -static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) +static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) { const struct fib_nh *onh = ofi->fib_nh; @@ -187,7 +196,7 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info * #ifdef CONFIG_NET_CLS_ROUTE nh->nh_tclassid != onh->nh_tclassid || #endif - ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) + ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) return -1; onh++; } endfor_nexthops(fi); @@ -238,7 +247,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi) nfi->fib_priority == fi->fib_priority && memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 && - ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && + ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 && (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) return fi; } @@ -247,9 +256,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi) } /* Check, that the gateway is already configured. - Used only by redirect accept routine. + * Used only by redirect accept routine. */ - int ip_fib_check_default(__be32 gw, struct net_device *dev) { struct hlist_head *head; @@ -264,7 +272,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev) hlist_for_each_entry(nh, node, head, nh_hash) { if (nh->nh_dev == dev && nh->nh_gw == gw && - !(nh->nh_flags&RTNH_F_DEAD)) { + !(nh->nh_flags & RTNH_F_DEAD)) { spin_unlock(&fib_info_lock); return 0; } @@ -362,10 +370,10 @@ int fib_detect_death(struct fib_info *fi, int order, } if (state == NUD_REACHABLE) return 0; - if ((state&NUD_VALID) && order != dflt) + if ((state & NUD_VALID) && order != dflt) return 0; - if ((state&NUD_VALID) || - (*last_idx<0 && order > dflt)) { + if ((state & NUD_VALID) || + (*last_idx < 0 && order > dflt)) { *last_resort = fi; *last_idx = order; } @@ -476,69 +484,69 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi) /* - Picture - ------- - - Semantics of nexthop is very messy by historical reasons. - We have to take into account, that: - a) gateway can be actually local interface address, - so that gatewayed route is direct. - b) gateway must be on-link address, possibly - described not by an ifaddr, but also by a direct route. - c) If both gateway and interface are specified, they should not - contradict. - d) If we use tunnel routes, gateway could be not on-link. - - Attempt to reconcile all of these (alas, self-contradictory) conditions - results in pretty ugly and hairy code with obscure logic. - - I chose to generalized it instead, so that the size - of code does not increase practically, but it becomes - much more general. - Every prefix is assigned a "scope" value: "host" is local address, - "link" is direct route, - [ ... "site" ... "interior" ... ] - and "universe" is true gateway route with global meaning. - - Every prefix refers to a set of "nexthop"s (gw, oif), - where gw must have narrower scope. This recursion stops - when gw has LOCAL scope or if "nexthop" is declared ONLINK, - which means that gw is forced to be on link. - - Code is still hairy, but now it is apparently logically - consistent and very flexible. F.e. as by-product it allows - to co-exists in peace independent exterior and interior - routing processes. - - Normally it looks as following. - - {universe prefix} -> (gw, oif) [scope link] - | - |-> {link prefix} -> (gw, oif) [scope local] - | - |-> {local prefix} (terminal node) + * Picture + * ------- + * + * Semantics of nexthop is very messy by historical reasons. + * We have to take into account, that: + * a) gateway can be actually local interface address, + * so that gatewayed route is direct. + * b) gateway must be on-link address, possibly + * described not by an ifaddr, but also by a direct route. + * c) If both gateway and interface are specified, they should not + * contradict. + * d) If we use tunnel routes, gateway could be not on-link. + * + * Attempt to reconcile all of these (alas, self-contradictory) conditions + * results in pretty ugly and hairy code with obscure logic. + * + * I chose to generalized it instead, so that the size + * of code does not increase practically, but it becomes + * much more general. + * Every prefix is assigned a "scope" value: "host" is local address, + * "link" is direct route, + * [ ... "site" ... "interior" ... ] + * and "universe" is true gateway route with global meaning. + * + * Every prefix refers to a set of "nexthop"s (gw, oif), + * where gw must have narrower scope. This recursion stops + * when gw has LOCAL scope or if "nexthop" is declared ONLINK, + * which means that gw is forced to be on link. + * + * Code is still hairy, but now it is apparently logically + * consistent and very flexible. F.e. as by-product it allows + * to co-exists in peace independent exterior and interior + * routing processes. + * + * Normally it looks as following. + * + * {universe prefix} -> (gw, oif) [scope link] + * | + * |-> {link prefix} -> (gw, oif) [scope local] + * | + * |-> {local prefix} (terminal node) */ - static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, struct fib_nh *nh) { int err; struct net *net; + struct net_device *dev; net = cfg->fc_nlinfo.nl_net; if (nh->nh_gw) { struct fib_result res; - if (nh->nh_flags&RTNH_F_ONLINK) { - struct net_device *dev; + if (nh->nh_flags & RTNH_F_ONLINK) { if (cfg->fc_scope >= RT_SCOPE_LINK) return -EINVAL; if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST) return -EINVAL; - if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL) + dev = __dev_get_by_index(net, nh->nh_oif); + if (!dev) return -ENODEV; - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return -ENETDOWN; nh->nh_dev = dev; dev_hold(dev); @@ -559,7 +567,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, /* It is not necessary, but requires a bit of thinking */ if (fl.fl4_scope < RT_SCOPE_LINK) fl.fl4_scope = RT_SCOPE_LINK; - if ((err = fib_lookup(net, &fl, &res)) != 0) + err = fib_lookup(net, &fl, &res); + if (err) return err; } err = -EINVAL; @@ -567,11 +576,12 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, goto out; nh->nh_scope = res.scope; nh->nh_oif = FIB_RES_OIF(res); - if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) + nh->nh_dev = dev = FIB_RES_DEV(res); + if (!dev) goto out; - dev_hold(nh->nh_dev); + dev_hold(dev); err = -ENETDOWN; - if (!(nh->nh_dev->flags & IFF_UP)) + if (!(dev->flags & IFF_UP)) goto out; err = 0; out: @@ -580,13 +590,13 @@ out: } else { struct in_device *in_dev; - if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK)) + if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) return -EINVAL; in_dev = inetdev_by_index(net, nh->nh_oif); if (in_dev == NULL) return -ENODEV; - if (!(in_dev->dev->flags&IFF_UP)) { + if (!(in_dev->dev->flags & IFF_UP)) { in_dev_put(in_dev); return -ENETDOWN; } @@ -602,7 +612,9 @@ static inline unsigned int fib_laddr_hashfn(__be32 val) { unsigned int mask = (fib_hash_size - 1); - return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask; + return ((__force u32)val ^ + ((__force u32)val >> 7) ^ + ((__force u32)val >> 14)) & mask; } static struct hlist_head *fib_hash_alloc(int bytes) @@ -611,7 +623,8 @@ static struct hlist_head *fib_hash_alloc(int bytes) return kzalloc(bytes, GFP_KERNEL); else return (struct hlist_head *) - __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes)); + __get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(bytes)); } static void fib_hash_free(struct hlist_head *hash, int bytes) @@ -806,7 +819,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) goto failure; } else { change_nexthops(fi) { - if ((err = fib_check_nh(cfg, fi, nexthop_nh)) != 0) + err = fib_check_nh(cfg, fi, nexthop_nh); + if (err != 0) goto failure; } endfor_nexthops(fi) } @@ -819,7 +833,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) } link_it: - if ((ofi = fib_find_info(fi)) != NULL) { + ofi = fib_find_info(fi); + if (ofi) { fi->fib_dead = 1; free_fib_info(fi); ofi->fib_treeref++; @@ -895,7 +910,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, case RTN_ANYCAST: case RTN_MULTICAST: for_nexthops(fi) { - if (nh->nh_flags&RTNH_F_DEAD) + if (nh->nh_flags & RTNH_F_DEAD) continue; if (!flp->oif || flp->oif == nh->nh_oif) break; @@ -906,16 +921,15 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, goto out_fill_res; } #else - if (nhsel < 1) { + if (nhsel < 1) goto out_fill_res; - } #endif endfor_nexthops(fi); continue; default: - printk(KERN_WARNING "fib_semantic_match bad type %#x\n", - fa->fa_type); + pr_warning("fib_semantic_match bad type %#x\n", + fa->fa_type); return -EINVAL; } } @@ -1028,10 +1042,10 @@ nla_put_failure: } /* - Update FIB if: - - local address disappeared -> we must delete all the entries - referring to it. - - device went down -> we must shutdown all nexthops going via it. + * Update FIB if: + * - local address disappeared -> we must delete all the entries + * referring to it. + * - device went down -> we must shutdown all nexthops going via it. */ int fib_sync_down_addr(struct net *net, __be32 local) { @@ -1078,7 +1092,7 @@ int fib_sync_down_dev(struct net_device *dev, int force) prev_fi = fi; dead = 0; change_nexthops(fi) { - if (nexthop_nh->nh_flags&RTNH_F_DEAD) + if (nexthop_nh->nh_flags & RTNH_F_DEAD) dead++; else if (nexthop_nh->nh_dev == dev && nexthop_nh->nh_scope != scope) { @@ -1110,10 +1124,9 @@ int fib_sync_down_dev(struct net_device *dev, int force) #ifdef CONFIG_IP_ROUTE_MULTIPATH /* - Dead device goes up. We wake up dead nexthops. - It takes sense only on multipath routes. + * Dead device goes up. We wake up dead nexthops. + * It takes sense only on multipath routes. */ - int fib_sync_up(struct net_device *dev) { struct fib_info *prev_fi; @@ -1123,7 +1136,7 @@ int fib_sync_up(struct net_device *dev) struct fib_nh *nh; int ret; - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return 0; prev_fi = NULL; @@ -1142,12 +1155,12 @@ int fib_sync_up(struct net_device *dev) prev_fi = fi; alive = 0; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) { alive++; continue; } if (nexthop_nh->nh_dev == NULL || - !(nexthop_nh->nh_dev->flags&IFF_UP)) + !(nexthop_nh->nh_dev->flags & IFF_UP)) continue; if (nexthop_nh->nh_dev != dev || !__in_dev_get_rtnl(dev)) @@ -1169,10 +1182,9 @@ int fib_sync_up(struct net_device *dev) } /* - The algorithm is suboptimal, but it provides really - fair weighted route distribution. + * The algorithm is suboptimal, but it provides really + * fair weighted route distribution. */ - void fib_select_multipath(const struct flowi *flp, struct fib_result *res) { struct fib_info *fi = res->fi; @@ -1182,7 +1194,7 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res) if (fi->fib_power <= 0) { int power = 0; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) { power += nexthop_nh->nh_weight; nexthop_nh->nh_power = nexthop_nh->nh_weight; } @@ -1198,15 +1210,16 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res) /* w should be random number [0..fi->fib_power-1], - it is pretty bad approximation. + * it is pretty bad approximation. */ w = jiffies % fi->fib_power; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD) && + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) && nexthop_nh->nh_power) { - if ((w -= nexthop_nh->nh_power) <= 0) { + w -= nexthop_nh->nh_power; + if (w <= 0) { nexthop_nh->nh_power--; fi->fib_power--; res->nh_sel = nhsel; -- cgit v1.2.3 From 1df9916e46451533463f227e6be57cc2cfca4c5f Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Oct 2010 20:14:17 +0000 Subject: fib: fib_rules_cleanup can be static fib_rules_cleanup_ups is only defined and used in one place. Signed-off-by: Stephen Hemminger Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/fib_rules.h | 1 - net/core/fib_rules.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index e8923bc20f9f..ac2fd002812e 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -106,7 +106,6 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *); extern void fib_rules_unregister(struct fib_rules_ops *); -extern void fib_rules_cleanup_ops(struct fib_rules_ops *); extern int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags, diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 332c2e31d048..cfb7d25c172d 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -144,7 +144,7 @@ fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net) } EXPORT_SYMBOL_GPL(fib_rules_register); -void fib_rules_cleanup_ops(struct fib_rules_ops *ops) +static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) { struct fib_rule *rule, *tmp; @@ -153,7 +153,6 @@ void fib_rules_cleanup_ops(struct fib_rules_ops *ops) fib_rule_put(rule); } } -EXPORT_SYMBOL_GPL(fib_rules_cleanup_ops); static void fib_rules_put_rcu(struct rcu_head *head) { -- cgit v1.2.3 From c61393ea83573ff422af505b6fd49ef9ec9b91ca Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Oct 2010 20:17:53 +0000 Subject: ipv6: make __ipv6_isatap_ifid static Another exported symbol only used in one file Signed-off-by: Stephen Hemminger Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/addrconf.h | 2 -- net/ipv6/addrconf.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 958d2749b7a9..a9441249306c 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -276,8 +276,6 @@ static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0; } -extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr); - static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) { return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8c88340278f5..ec7a91d9e865 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1544,7 +1544,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev) return 0; } -int __ipv6_isatap_ifid(u8 *eui, __be32 addr) +static int __ipv6_isatap_ifid(u8 *eui, __be32 addr) { if (addr == 0) return -1; @@ -1560,7 +1560,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr) memcpy(eui + 4, &addr, 4); return 0; } -EXPORT_SYMBOL(__ipv6_isatap_ifid); static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) { -- cgit v1.2.3 From a00eac0c459abecb539fb2a2abd3122dd7ca5d4a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Oct 2010 01:36:52 -0700 Subject: ppp: Use a real SKB control block in fragmentation engine. Do this instead of subverting fields in skb proper. The macros that could very easily match variable or function names were also just asking for trouble. Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 736b91703b3e..866e221643ab 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1547,9 +1547,11 @@ ppp_channel_push(struct channel *pch) * Receive-side routines. */ -/* misuse a few fields of the skb for MP reconstruction */ -#define sequence priority -#define BEbits cb[0] +struct ppp_mp_skb_parm { + u32 sequence; + u8 BEbits; +}; +#define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb)) static inline void ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) @@ -1878,13 +1880,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; mask = 0xffffff; } - skb->BEbits = skb->data[2]; + PPP_MP_CB(skb)->BEbits = skb->data[2]; skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ /* * Do protocol ID decompression on the first fragment of each packet. */ - if ((skb->BEbits & B) && (skb->data[0] & 1)) + if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1)) *skb_push(skb, 1) = 0; /* @@ -1896,7 +1898,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) seq += mask + 1; else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) seq -= mask + 1; /* should never happen */ - skb->sequence = seq; + PPP_MP_CB(skb)->sequence = seq; pch->lastseq = seq; /* @@ -1932,8 +1934,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) before the start of the queue. */ if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { struct sk_buff *mskb = skb_peek(&ppp->mrq); - if (seq_before(ppp->minseq, mskb->sequence)) - ppp->minseq = mskb->sequence; + if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence)) + ppp->minseq = PPP_MP_CB(mskb)->sequence; } /* Pull completed packets off the queue and receive them. */ @@ -1963,12 +1965,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) { struct sk_buff *p; struct sk_buff_head *list = &ppp->mrq; - u32 seq = skb->sequence; + u32 seq = PPP_MP_CB(skb)->sequence; /* N.B. we don't need to lock the list lock because we have the ppp unit receive-side lock. */ skb_queue_walk(list, p) { - if (seq_before(seq, p->sequence)) + if (seq_before(seq, PPP_MP_CB(p)->sequence)) break; } __skb_queue_before(list, p, skb); @@ -1997,22 +1999,22 @@ ppp_mp_reconstruct(struct ppp *ppp) tail = NULL; for (p = head; p != (struct sk_buff *) list; p = next) { next = p->next; - if (seq_before(p->sequence, seq)) { + if (seq_before(PPP_MP_CB(p)->sequence, seq)) { /* this can't happen, anyway ignore the skb */ printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", - p->sequence, seq); + PPP_MP_CB(p)->sequence, seq); head = next; continue; } - if (p->sequence != seq) { + if (PPP_MP_CB(p)->sequence != seq) { /* Fragment `seq' is missing. If it is after minseq, it might arrive later, so stop here. */ if (seq_after(seq, minseq)) break; /* Fragment `seq' is lost, keep going. */ lost = 1; - seq = seq_before(minseq, p->sequence)? - minseq + 1: p->sequence; + seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? + minseq + 1: PPP_MP_CB(p)->sequence; next = p; continue; } @@ -2026,7 +2028,7 @@ ppp_mp_reconstruct(struct ppp *ppp) */ /* B bit set indicates this fragment starts a packet */ - if (p->BEbits & B) { + if (PPP_MP_CB(p)->BEbits & B) { head = p; lost = 0; len = 0; @@ -2035,7 +2037,8 @@ ppp_mp_reconstruct(struct ppp *ppp) len += p->len; /* Got a complete packet yet? */ - if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) { + if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) && + (PPP_MP_CB(head)->BEbits & B)) { if (len > ppp->mrru + 2) { ++ppp->dev->stats.rx_length_errors; printk(KERN_DEBUG "PPP: reconstructed packet" @@ -2061,7 +2064,7 @@ ppp_mp_reconstruct(struct ppp *ppp) * and we haven't found a complete valid packet yet, * we can discard up to and including this fragment. */ - if (p->BEbits & E) + if (PPP_MP_CB(p)->BEbits & E) head = next; ++seq; @@ -2071,10 +2074,11 @@ ppp_mp_reconstruct(struct ppp *ppp) if (tail != NULL) { /* If we have discarded any fragments, signal a receive error. */ - if (head->sequence != ppp->nextseq) { + if (PPP_MP_CB(head)->sequence != ppp->nextseq) { if (ppp->debug & 1) printk(KERN_DEBUG " missed pkts %u..%u\n", - ppp->nextseq, head->sequence-1); + ppp->nextseq, + PPP_MP_CB(head)->sequence-1); ++ppp->dev->stats.rx_dropped; ppp_receive_error(ppp); } @@ -2083,7 +2087,7 @@ ppp_mp_reconstruct(struct ppp *ppp) /* copy to a single skb */ for (p = head; p != tail->next; p = p->next) skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); - ppp->nextseq = tail->sequence + 1; + ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; head = tail->next; } -- cgit v1.2.3 From e0e9b406470b8dd75a115cf82c4791f41615c4c3 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 14 Sep 2010 23:53:05 +0800 Subject: vhost: max s/g to match qemu Qemu supports up to UIO_MAXIOV s/g so we have to match that because guest drivers may rely on this. Allocate indirect and log arrays dynamically to avoid using too much contigious memory and make the length of hdr array to match the header length since each iovec entry has a least one byte. Test with copying large files w/ and w/o migration in both linux and windows guests. Signed-off-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 2 +- drivers/vhost/vhost.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- drivers/vhost/vhost.h | 18 ++++++++---------- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 7c8008225ee3..72ab71fdf053 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -243,7 +243,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, int r, nlogs = 0; while (datalen > 0) { - if (unlikely(seg >= VHOST_NET_MAX_SG)) { + if (unlikely(seg >= UIO_MAXIOV)) { r = -ENOBUFS; goto err; } diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index dd3d6f7406f8..344019774ddd 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -212,6 +212,45 @@ static int vhost_worker(void *data) } } +/* Helper to allocate iovec buffers for all vqs. */ +static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) +{ + int i; + for (i = 0; i < dev->nvqs; ++i) { + dev->vqs[i].indirect = kmalloc(sizeof *dev->vqs[i].indirect * + UIO_MAXIOV, GFP_KERNEL); + dev->vqs[i].log = kmalloc(sizeof *dev->vqs[i].log * UIO_MAXIOV, + GFP_KERNEL); + dev->vqs[i].heads = kmalloc(sizeof *dev->vqs[i].heads * + UIO_MAXIOV, GFP_KERNEL); + + if (!dev->vqs[i].indirect || !dev->vqs[i].log || + !dev->vqs[i].heads) + goto err_nomem; + } + return 0; +err_nomem: + for (; i >= 0; --i) { + kfree(dev->vqs[i].indirect); + kfree(dev->vqs[i].log); + kfree(dev->vqs[i].heads); + } + return -ENOMEM; +} + +static void vhost_dev_free_iovecs(struct vhost_dev *dev) +{ + int i; + for (i = 0; i < dev->nvqs; ++i) { + kfree(dev->vqs[i].indirect); + dev->vqs[i].indirect = NULL; + kfree(dev->vqs[i].log); + dev->vqs[i].log = NULL; + kfree(dev->vqs[i].heads); + dev->vqs[i].heads = NULL; + } +} + long vhost_dev_init(struct vhost_dev *dev, struct vhost_virtqueue *vqs, int nvqs) { @@ -229,6 +268,9 @@ long vhost_dev_init(struct vhost_dev *dev, dev->worker = NULL; for (i = 0; i < dev->nvqs; ++i) { + dev->vqs[i].log = NULL; + dev->vqs[i].indirect = NULL; + dev->vqs[i].heads = NULL; dev->vqs[i].dev = dev; mutex_init(&dev->vqs[i].mutex); vhost_vq_reset(dev, dev->vqs + i); @@ -295,6 +337,10 @@ static long vhost_dev_set_owner(struct vhost_dev *dev) if (err) goto err_cgroup; + err = vhost_dev_alloc_iovecs(dev); + if (err) + goto err_cgroup; + return 0; err_cgroup: kthread_stop(worker); @@ -345,6 +391,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) fput(dev->vqs[i].call); vhost_vq_reset(dev, dev->vqs + i); } + vhost_dev_free_iovecs(dev); if (dev->log_ctx) eventfd_ctx_put(dev->log_ctx); dev->log_ctx = NULL; @@ -947,7 +994,7 @@ static int get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq, } ret = translate_desc(dev, indirect->addr, indirect->len, vq->indirect, - ARRAY_SIZE(vq->indirect)); + UIO_MAXIOV); if (unlikely(ret < 0)) { vq_err(vq, "Translation failure %d in indirect.\n", ret); return ret; diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index afd77295971c..edc892989992 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -15,11 +15,6 @@ struct vhost_device; -enum { - /* Enough place for all fragments, head, and virtio net header. */ - VHOST_NET_MAX_SG = MAX_SKB_FRAGS + 2, -}; - struct vhost_work; typedef void (*vhost_work_fn_t)(struct vhost_work *work); @@ -93,12 +88,15 @@ struct vhost_virtqueue { bool log_used; u64 log_addr; - struct iovec indirect[VHOST_NET_MAX_SG]; - struct iovec iov[VHOST_NET_MAX_SG]; - struct iovec hdr[VHOST_NET_MAX_SG]; + struct iovec iov[UIO_MAXIOV]; + /* hdr is used to store the virtio header. + * Since each iovec has >= 1 byte length, we never need more than + * header length entries to store the header. */ + struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)]; + struct iovec *indirect; size_t vhost_hlen; size_t sock_hlen; - struct vring_used_elem heads[VHOST_NET_MAX_SG]; + struct vring_used_elem *heads; /* We use a kind of RCU to access private pointer. * All readers access it from worker, which makes it possible to * flush the vhost_work instead of synchronize_rcu. Therefore readers do @@ -109,7 +107,7 @@ struct vhost_virtqueue { void *private_data; /* Log write descriptors */ void __user *log_base; - struct vhost_log log[VHOST_NET_MAX_SG]; + struct vhost_log *log; }; struct vhost_dev { -- cgit v1.2.3 From 5c57a901dc96fc81d0041282269b43542f170d2a Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 30 Sep 2010 13:28:26 +0200 Subject: wl1271: Handle large SPI transfers The HW supports up to 4095 bytes transfers via SPI. The SPI read & write operations do not handle larger transfers, causing the HW to stall in such cases. Fix this by fragmenting large transfers into smaller chunks, and transferring each one separately. Signed-off-by: Ido Yariv Tested-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_spi.c | 140 +++++++++++++++++++------------ 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 75cbf36146e2..ef801680773f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -63,6 +63,11 @@ ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) #define HW_ACCESS_WSPI_INIT_CMD_MASK 0 +/* HW limitation: maximum possible chunk size is 4095 bytes */ +#define WSPI_MAX_CHUNK_SIZE 4092 + +#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + static inline struct spi_device *wl_to_spi(struct wl1271 *wl) { return wl->if_priv; @@ -202,90 +207,117 @@ static int wl1271_spi_read_busy(struct wl1271 *wl) static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - struct spi_transfer t[3]; + struct spi_transfer t[2]; struct spi_message m; u32 *busy_buf; u32 *cmd; + u32 chunk_len; - cmd = &wl->buffer_cmd; - busy_buf = wl->buffer_busyword; + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - *cmd = 0; - *cmd |= WSPI_CMD_READ; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; + cmd = &wl->buffer_cmd; + busy_buf = wl->buffer_busyword; - if (fixed) - *cmd |= WSPI_CMD_FIXED; + *cmd = 0; + *cmd |= WSPI_CMD_READ; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; - spi_message_init(&m); - memset(t, 0, sizeof(t)); + if (fixed) + *cmd |= WSPI_CMD_FIXED; - t[0].tx_buf = cmd; - t[0].len = 4; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); + spi_message_init(&m); + memset(t, 0, sizeof(t)); - /* Busy and non busy words read */ - t[1].rx_buf = busy_buf; - t[1].len = WL1271_BUSY_WORD_LEN; - t[1].cs_change = true; - spi_message_add_tail(&t[1], &m); + t[0].tx_buf = cmd; + t[0].len = 4; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); - spi_sync(wl_to_spi(wl), &m); + /* Busy and non busy words read */ + t[1].rx_buf = busy_buf; + t[1].len = WL1271_BUSY_WORD_LEN; + t[1].cs_change = true; + spi_message_add_tail(&t[1], &m); - if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && - wl1271_spi_read_busy(wl)) { - memset(buf, 0, len); - return; - } + spi_sync(wl_to_spi(wl), &m); - spi_message_init(&m); - memset(t, 0, sizeof(t)); + if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && + wl1271_spi_read_busy(wl)) { + memset(buf, 0, chunk_len); + return; + } - t[0].rx_buf = buf; - t[0].len = len; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); + spi_message_init(&m); + memset(t, 0, sizeof(t)); - spi_sync(wl_to_spi(wl), &m); + t[0].rx_buf = buf; + t[0].len = chunk_len; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); + + spi_sync(wl_to_spi(wl), &m); - wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); + wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + } } static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - struct spi_transfer t[2]; + struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; struct spi_message m; + u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; u32 *cmd; + u32 chunk_len; + int i; - cmd = &wl->buffer_cmd; - - *cmd = 0; - *cmd |= WSPI_CMD_WRITE; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; + WARN_ON(len > WL1271_AGGR_BUFFER_SIZE); spi_message_init(&m); memset(t, 0, sizeof(t)); - t[0].tx_buf = cmd; - t[0].len = sizeof(*cmd); - spi_message_add_tail(&t[0], &m); + cmd = &commands[0]; + i = 0; + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - t[1].tx_buf = buf; - t[1].len = len; - spi_message_add_tail(&t[1], &m); + *cmd = 0; + *cmd |= WSPI_CMD_WRITE; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; - spi_sync(wl_to_spi(wl), &m); + if (fixed) + *cmd |= WSPI_CMD_FIXED; + + t[i].tx_buf = cmd; + t[i].len = sizeof(*cmd); + spi_message_add_tail(&t[i++], &m); + + t[i].tx_buf = buf; + t[i].len = chunk_len; + spi_message_add_tail(&t[i++], &m); - wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); + wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + cmd++; + } + + spi_sync(wl_to_spi(wl), &m); } static irqreturn_t wl1271_irq(int irq, void *cookie) -- cgit v1.2.3 From 1f37cbc9363462c99794699442da39f36be0aaf7 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 30 Sep 2010 13:28:27 +0200 Subject: wl1271: Support firmware RX packet aggregation Instead of retrieving one packet at a time from the firmware, try to retrieve all available packets at once. This optimization decreases the number of transactions, which saves CPU cycles and increases network throughput. Signed-off-by: Ido Yariv Tested-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271.h | 5 +++ drivers/net/wireless/wl12xx/wl1271_main.c | 15 +++++++- drivers/net/wireless/wl12xx/wl1271_rx.c | 63 +++++++++++++++++++++++-------- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 779b130fdb3e..8a4cd763e5a2 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -130,6 +130,8 @@ enum { #define ACX_TX_DESCRIPTORS 32 +#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) + enum wl1271_state { WL1271_STATE_OFF, WL1271_STATE_ON, @@ -408,6 +410,9 @@ struct wl1271 { /* Rx memory pool address */ struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; + /* Intermediate buffer, used for packet aggregation */ + u8 *aggr_buf; + /* The target interrupt mask */ struct work_struct irq_work; diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index cb18f22bbc5c..8071da10dbc9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -2459,6 +2459,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) struct platform_device *plat_dev = NULL; struct wl1271 *wl; int i, ret; + unsigned int order; hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); if (!hw) { @@ -2517,11 +2518,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl1271_debugfs_init(wl); + order = get_order(WL1271_AGGR_BUFFER_SIZE); + wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); + if (!wl->aggr_buf) { + ret = -ENOMEM; + goto err_hw; + } + /* Register platform device */ ret = platform_device_register(wl->plat_dev); if (ret) { wl1271_error("couldn't register platform device"); - goto err_hw; + goto err_aggr; } dev_set_drvdata(&wl->plat_dev->dev, wl); @@ -2547,6 +2555,9 @@ err_bt_coex_state: err_platform: platform_device_unregister(wl->plat_dev); +err_aggr: + free_pages((unsigned long)wl->aggr_buf, order); + err_hw: wl1271_debugfs_exit(wl); kfree(plat_dev); @@ -2563,6 +2574,8 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw); int wl1271_free_hw(struct wl1271 *wl) { platform_device_unregister(wl->plat_dev); + free_pages((unsigned long)wl->aggr_buf, + get_order(WL1271_AGGR_BUFFER_SIZE)); kfree(wl->plat_dev); wl1271_debugfs_exit(wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 94da5dd7723c..bea133b6e489 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -74,7 +74,7 @@ static void wl1271_rx_status(struct wl1271 *wl, } } -static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) +static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) { struct wl1271_rx_descriptor *desc; struct sk_buff *skb; @@ -87,16 +87,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) * workaround this by not retrieving them at all. */ if (unlikely(wl->state == WL1271_STATE_PLT)) - return; + return -EINVAL; skb = __dev_alloc_skb(length, GFP_KERNEL); if (!skb) { wl1271_error("Couldn't allocate RX frame"); - return; + return -ENOMEM; } buf = skb_put(skb, length); - wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true); + memcpy(buf, data, length); /* the data read starts with the descriptor */ desc = (struct wl1271_rx_descriptor *) buf; @@ -116,6 +116,8 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) skb_trim(skb, skb->len - desc->pad_len); ieee80211_rx_ni(wl->hw, skb); + + return 0; } void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) @@ -124,31 +126,60 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) u32 buf_size; u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + u32 rx_counter; u32 mem_block; + u32 pkt_length; + u32 pkt_offset; while (drv_rx_counter != fw_rx_counter) { - mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); - buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter); + buf_size = 0; + rx_counter = drv_rx_counter; + while (rx_counter != fw_rx_counter) { + pkt_length = wl1271_rx_get_buf_size(status, rx_counter); + if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) + break; + buf_size += pkt_length; + rx_counter++; + rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + } if (buf_size == 0) { wl1271_warning("received empty data"); break; } + /* + * Choose the block we want to read + * For aggregated packets, only the first memory block should + * be retrieved. The FW takes care of the rest. + */ + mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); wl->rx_mem_pool_addr.addr = (mem_block << 8) + le32_to_cpu(wl_mem_map->packet_memory_pool_start); wl->rx_mem_pool_addr.addr_extra = wl->rx_mem_pool_addr.addr + 4; - - /* Choose the block we want to read */ wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, - sizeof(wl->rx_mem_pool_addr), false); - - wl1271_rx_handle_data(wl, buf_size); - - wl->rx_counter++; - drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + sizeof(wl->rx_mem_pool_addr), false); + + /* Read all available packets at once */ + wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_size, true); + + /* Split data into separate packets */ + pkt_offset = 0; + while (pkt_offset < buf_size) { + pkt_length = wl1271_rx_get_buf_size(status, + drv_rx_counter); + if (wl1271_rx_handle_data(wl, + wl->aggr_buf + pkt_offset, + pkt_length) < 0) + break; + wl->rx_counter++; + drv_rx_counter++; + drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + pkt_offset += pkt_length; + } } - - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); + wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, + cpu_to_le32(wl->rx_counter)); } -- cgit v1.2.3 From a19606b4333ff34e9b2863f37c20fe86b42be14c Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 30 Sep 2010 13:28:28 +0200 Subject: wl1271: Support firmware TX packet aggregation Instead of sending one packet at a time to the firmware, try to send all available packets at once. This optimization decreases the number of transactions, which saves CPU cycles and increases network throughput. Signed-off-by: Ido Yariv Tested-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_tx.c | 99 ++++++++++++--------------------- 1 file changed, 37 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 1b8295c5dde4..e3dc13c4d01a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -43,13 +43,17 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) return -EBUSY; } -static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) +static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, + u32 buf_offset) { struct wl1271_tx_hw_descr *desc; u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; u32 total_blocks; int id, ret = -EBUSY; + if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) + return -EBUSY; + /* allocate free identifier for the packet */ id = wl1271_tx_id(wl, skb); if (id < 0) @@ -82,7 +86,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) return ret; } -static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, +static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, u32 extra, struct ieee80211_tx_info *control) { struct timespec ts; @@ -133,59 +137,17 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, desc->tx_attr = cpu_to_le16(tx_attr); wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); - return 0; -} - -static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb, - struct ieee80211_tx_info *control) -{ - - struct wl1271_tx_hw_descr *desc; - int len; - - /* FIXME: This is a workaround for getting non-aligned packets. - This happens at least with EAPOL packets from the user space. - Our DMA requires packets to be aligned on a 4-byte boundary. - */ - if (unlikely((long)skb->data & 0x03)) { - int offset = (4 - (long)skb->data) & 0x03; - wl1271_debug(DEBUG_TX, "skb offset %d", offset); - - /* check whether the current skb can be used */ - if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { - unsigned char *src = skb->data; - - /* align the buffer on a 4-byte boundary */ - skb_reserve(skb, offset); - memmove(skb->data, src, skb->len); - } else { - wl1271_info("No handler, fixme!"); - return -EINVAL; - } - } - - len = WL1271_TX_ALIGN(skb->len); - - /* perform a fixed address block write with the packet */ - wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true); - - /* write packet new counter into the write access register */ - wl->tx_packets_count++; - - desc = (struct wl1271_tx_hw_descr *) skb->data; - wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", - desc->id, skb, len, desc->length); - - return 0; } /* caller must hold wl->mutex */ -static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) +static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, + u32 buf_offset) { struct ieee80211_tx_info *info; u32 extra = 0; int ret = 0; u8 idx; + u32 total_len; if (!skb) return -EINVAL; @@ -208,19 +170,22 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) } } - ret = wl1271_tx_allocate(wl, skb, extra); + ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); if (ret < 0) return ret; - ret = wl1271_tx_fill_hdr(wl, skb, extra, info); - if (ret < 0) - return ret; + wl1271_tx_fill_hdr(wl, skb, extra, info); - ret = wl1271_tx_send_packet(wl, skb, info); - if (ret < 0) - return ret; + /* + * The length of each packet is stored in terms of words. Thus, we must + * pad the skb data to make sure its length is aligned. + * The number of padding bytes is computed and set in wl1271_tx_fill_hdr + */ + total_len = WL1271_TX_ALIGN(skb->len); + memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); + memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); - return ret; + return total_len; } u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) @@ -245,7 +210,7 @@ void wl1271_tx_work(struct work_struct *work) struct sk_buff *skb; bool woken_up = false; u32 sta_rates = 0; - u32 prev_tx_packets_count; + u32 buf_offset; int ret; /* check if the rates supported by the AP have changed */ @@ -262,14 +227,15 @@ void wl1271_tx_work(struct work_struct *work) if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - prev_tx_packets_count = wl->tx_packets_count; - /* if rates have changed, re-configure the rate policy */ if (unlikely(sta_rates)) { wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); wl1271_acx_rate_policies(wl); } + /* Prepare the transfer buffer, by aggregating all + * available packets */ + buf_offset = 0; while ((skb = skb_dequeue(&wl->tx_queue))) { if (!woken_up) { ret = wl1271_ps_elp_wakeup(wl, false); @@ -278,21 +244,30 @@ void wl1271_tx_work(struct work_struct *work) woken_up = true; } - ret = wl1271_tx_frame(wl, skb); + ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); if (ret == -EBUSY) { - /* firmware buffer is full, lets stop transmitting. */ + /* + * Either the firmware buffer is full, or the + * aggregation buffer is. + * Queue back last skb, and stop aggregating. + */ skb_queue_head(&wl->tx_queue, skb); goto out_ack; } else if (ret < 0) { dev_kfree_skb(skb); goto out_ack; } + buf_offset += ret; + wl->tx_packets_count++; } out_ack: - /* interrupt the firmware with the new packets */ - if (prev_tx_packets_count != wl->tx_packets_count) + if (buf_offset) { + wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + /* interrupt the firmware with the new packets */ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); + } out: if (woken_up) -- cgit v1.2.3 From 117b38d0b9d3efb0adc3e636e73fc67bb53a13d1 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 30 Sep 2010 10:43:28 +0200 Subject: wl1271: Move work-init calls to hw allocation Due to legacy reason, dating back to when the wl1251 and wl1271 still were a unified driver, some work-structures are initialized on hardware startup. The hardware recovery code creates a scenario in which it is possible for a workstruct to be re-initialized while the work-function itself is running, which causes a kernel WARNing and a subsequent reboot. To remedy this, move the work initialization calls to the hw allocation, which is the logically correct place for them anyway. Signed-off-by: Juuso Oikarinen Tested-by: Tuomas Katila Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 8071da10dbc9..760a5814d4a4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -664,11 +664,6 @@ static int wl1271_setup(struct wl1271 *wl) return -ENOMEM; } - INIT_WORK(&wl->irq_work, wl1271_irq_work); - INIT_WORK(&wl->tx_work, wl1271_tx_work); - INIT_WORK(&wl->recovery_work, wl1271_recovery_work); - INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); - return 0; } @@ -2487,6 +2482,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void) INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); + INIT_WORK(&wl->irq_work, wl1271_irq_work); + INIT_WORK(&wl->tx_work, wl1271_tx_work); + INIT_WORK(&wl->recovery_work, wl1271_recovery_work); + INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); wl->channel = WL1271_DEFAULT_CHANNEL; wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; -- cgit v1.2.3 From d25611da0c75c4b0f72c73d66887d0470aacef40 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 30 Sep 2010 10:43:27 +0200 Subject: wl1271: Indicate disconnection on hardware failure In the event of a hardware failure, reconfiguring a live connection back with the wl1271 chip does not work as expected. The chip has management features which require setting up the association from scratch to work correctly. To ensure this is done every time, in managed mode, when associated, indicate connection loss to the mac80211 before asking to reconfigure the hardware. Signed-off-by: Juuso Oikarinen Tested-by: Tuomas Katila Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 760a5814d4a4..d826b6684e39 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -636,6 +636,9 @@ static void wl1271_recovery_work(struct work_struct *work) wl1271_info("Hardware recovery in progress."); + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + ieee80211_connection_loss(wl->vif); + /* reboot the chipset */ __wl1271_op_remove_interface(wl); ieee80211_restart_hw(wl->hw); -- cgit v1.2.3 From 644a48607cd40954b6fb095b39a3ccaa0204191e Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 5 Oct 2010 13:11:56 +0200 Subject: wl1271: Add extended radio parameter initialization Currently a command to initialize extended radio parameter tables in the hardware is missing. Add the initialization Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 33 +++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_cmd.h | 24 ++++++++++++++++------ drivers/net/wireless/wl12xx/wl1271_conf.h | 21 ++++++++++++++++++++ drivers/net/wireless/wl12xx/wl1271_init.c | 4 ++++ drivers/net/wireless/wl12xx/wl1271_main.c | 14 +++++++++++++ 5 files changed, 90 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 4a56ab05e736..596e333919ae 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -171,6 +171,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) return ret; } +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) +{ + struct wl1271_ext_radio_parms_cmd *ext_radio_parms; + struct conf_rf_settings *rf = &wl->conf.rf; + int ret; + + if (!wl->nvs) + return -ENODEV; + + ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); + if (!ext_radio_parms) + return -ENOMEM; + + ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; + + memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, + rf->tx_per_channel_power_compensation_2, + CONF_TX_PWR_COMPENSATION_LEN_2); + memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, + rf->tx_per_channel_power_compensation_5, + CONF_TX_PWR_COMPENSATION_LEN_5); + + wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", + ext_radio_parms, sizeof(*ext_radio_parms)); + + ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); + if (ret < 0) + wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); + + kfree(ext_radio_parms); + return ret; +} + /* * Poll the mailbox event field until any of the bits in the mask is set or a * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index 33b946b4cb07..ed80bec1aea4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -33,6 +33,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, size_t res_len); int wl1271_cmd_general_parms(struct wl1271 *wl); int wl1271_cmd_radio_parms(struct wl1271 *wl); +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); @@ -324,13 +325,14 @@ enum wl1271_channel_tune_bands { WL1271_CHANNEL_TUNE_BAND_4_9 }; -#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 +#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 -#define TEST_CMD_P2G_CAL 0x02 -#define TEST_CMD_CHANNEL_TUNE 0x0d -#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d -#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 -#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E +#define TEST_CMD_P2G_CAL 0x02 +#define TEST_CMD_CHANNEL_TUNE 0x0d +#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d +#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 +#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E +#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26 struct wl1271_general_parms_cmd { struct wl1271_cmd_header header; @@ -363,6 +365,16 @@ struct wl1271_radio_parms_cmd { u8 padding3[2]; } __packed; +struct wl1271_ext_radio_parms_cmd { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; + u8 padding[3]; +} __packed; + struct wl1271_cmd_cal_channel_tune { struct wl1271_cmd_header header; diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index 60c50d1a9835..5f78a6cb1433 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -1070,6 +1070,26 @@ struct conf_scan_settings { }; +/* these are number of channels on the band divided by two, rounded up */ +#define CONF_TX_PWR_COMPENSATION_LEN_2 7 +#define CONF_TX_PWR_COMPENSATION_LEN_5 18 + +struct conf_rf_settings { + /* + * Per channel power compensation for 2.4GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + + /* + * Per channel power compensation for 5GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1079,6 +1099,7 @@ struct conf_drv_settings { struct conf_pm_config_settings pm_config; struct conf_roam_trigger_settings roam_trigger; struct conf_scan_settings scan; + struct conf_rf_settings rf; }; #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 349571fe04b3..8044bba70ee7 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -222,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + /* Template settings */ ret = wl1271_init_templates_config(wl); if (ret < 0) diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index d826b6684e39..48a4b9961ae6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -242,6 +242,16 @@ static struct conf_drv_settings default_conf = { .max_dwell_time_passive = 60000, .num_probe_reqs = 2, }, + .rf = { + .tx_per_channel_power_compensation_2 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .tx_per_channel_power_compensation_5 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + }, }; static void __wl1271_op_remove_interface(struct wl1271 *wl); @@ -357,6 +367,10 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + ret = wl1271_init_templates_config(wl); if (ret < 0) return ret; -- cgit v1.2.3 From 5082b823f3b0c781fdbc52910af579e940f6f18e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 5 Oct 2010 14:58:49 +0300 Subject: wl1271: remove deprecated __attribute__ ((packed)) One __attribute__ ((packed)) has been accidentally introduced in commit be86cbea1e9c3a4dd8faedcfa327495d09fe3531. This patch changes it to __packed. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index ed80bec1aea4..a0caf4fc37b1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -454,6 +454,6 @@ struct wl1271_cmd_set_sta_state { u8 state; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; #endif /* __WL1271_CMD_H__ */ -- cgit v1.2.3 From 4b48e6876b641e1138f37a0fc11fb6a4fc3e24e1 Mon Sep 17 00:00:00 2001 From: ext Anand Gadiyar Date: Fri, 1 Oct 2010 22:33:26 +0200 Subject: omap: zoom2/3: fix build caused by wl1271 support Patch "omap: zoom: add mmc3/wl1271 device support" in the wireless tree still uses .wires in struct omap2_hsmmc_info. .wires has now been replaced with .caps in patch "omap: mmc: extended to pass host capabilities from board file" in the OMAP tree. This causes linux-next as of 20101001 build to break as below. Fix this. CC arch/arm/mach-omap2/board-zoom-peripherals.o arch/arm/mach-omap2/board-zoom-peripherals.c:217: error: unknown field 'wires' specified in initializer make[1]: *** [arch/arm/mach-omap2/board-zoom-peripherals.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 Signed-off-by: Anand Gadiyar Cc: Ohad Ben-Cohen Cc: Tony Lindgren Acked-by: Tony Lindgren Signed-off-by: Luciano Coelho --- arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 6aa0728fa15d..189a6d1600b2 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -213,7 +213,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { { .name = "wl1271", .mmc = 3, - .wires = 4, + .caps = MMC_CAP_4_BIT_DATA, .gpio_wp = -EINVAL, .gpio_cd = -EINVAL, .nonremovable = true, -- cgit v1.2.3 From 5a254ffe3ffdfa84fe076009bd8e88da412180d2 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 27 Sep 2010 09:07:26 -0700 Subject: wireless: Use first phyX name available when registering phy devices. Choose first available phyX name when creating phy devices. This means that reloading a wifi driver will not cause a change in the name of it's phy device. Also, allow users to rename a phy to any un-used name, including phy%d. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- net/wireless/core.c | 54 +++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 9c21ebf9780e..1684ad91763c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -178,26 +178,10 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, char *newname) { struct cfg80211_registered_device *rdev2; - int wiphy_idx, taken = -1, result, digits; + int result; assert_cfg80211_lock(); - /* prohibit calling the thing phy%d when %d is not its number */ - sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); - if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { - /* count number of places needed to print wiphy_idx */ - digits = 1; - while (wiphy_idx /= 10) - digits++; - /* - * deny the name if it is phy where is printed - * without leading zeroes. taken == strlen(newname) here - */ - if (taken == strlen(PHY_NAME) + digits) - return -EINVAL; - } - - /* Ignore nop renames */ if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) return 0; @@ -205,7 +189,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, /* Ensure another device does not already have this name. */ list_for_each_entry(rdev2, &cfg80211_rdev_list, list) if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) - return -EINVAL; + return -EEXIST; result = device_rename(&rdev->wiphy.dev, newname); if (result) @@ -320,9 +304,11 @@ static void cfg80211_event_work(struct work_struct *work) struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) { static int wiphy_counter; - - struct cfg80211_registered_device *rdev; + int i; + struct cfg80211_registered_device *rdev, *rdev2; int alloc_size; + char nname[IFNAMSIZ + 1]; + bool found = false; WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); @@ -346,16 +332,36 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { wiphy_counter--; + goto too_many_devs; + } + + /* 64k wiphy devices is enough for anyone! */ + for (i = 0; i < 0xFFFF; i++) { + found = false; + snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i); + nname[sizeof(nname)-1] = 0; + list_for_each_entry(rdev2, &cfg80211_rdev_list, list) + if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) { + found = true; + break; + } + + if (!found) + break; + } + + if (unlikely(found)) { +too_many_devs: mutex_unlock(&cfg80211_mutex); - /* ugh, wrapped! */ + /* ugh, too many devices already! */ kfree(rdev); return NULL; } - mutex_unlock(&cfg80211_mutex); - /* give it a proper name */ - dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + dev_set_name(&rdev->wiphy.dev, "%s", nname); + + mutex_unlock(&cfg80211_mutex); mutex_init(&rdev->mtx); mutex_init(&rdev->devlist_mtx); -- cgit v1.2.3 From 85416a4fa193754ef36e12b20bb02fe661cb7f17 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 2 Oct 2010 13:17:07 +0200 Subject: mac80211: fix rx monitor filter refcounters This patch fixes an refcounting bug. Previously it was possible to corrupt the per-device recv. filter and monitor management counters when: iw dev wlanX set monitor [new flags] was issued on an active monitor interface. Acked-by: Johannes Berg Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 32 ++++++++++++++++++++++++++++++-- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 44 ++++++++++++++++++++++---------------------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c981604b71e6..9e63fc28f859 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -68,8 +68,36 @@ static int ieee80211_change_iface(struct wiphy *wiphy, params && params->use_4addr >= 0) sdata->u.mgd.use_4addr = params->use_4addr; - if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) - sdata->u.mntr_flags = *flags; + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) { + struct ieee80211_local *local = sdata->local; + + if (ieee80211_sdata_running(sdata)) { + /* + * Prohibit MONITOR_FLAG_COOK_FRAMES to be + * changed while the interface is up. + * Else we would need to add a lot of cruft + * to update everything: + * cooked_mntrs, monitor and all fif_* counters + * reconfigure hardware + */ + if ((*flags & MONITOR_FLAG_COOK_FRAMES) != + (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) + return -EBUSY; + + ieee80211_adjust_monitor_flags(sdata, -1); + sdata->u.mntr_flags = *flags; + ieee80211_adjust_monitor_flags(sdata, 1); + + ieee80211_configure_filter(local); + } else { + /* + * Because the interface is down, ieee80211_do_stop + * and ieee80211_do_open take care of "everything" + * mentioned in the comment above. + */ + sdata->u.mntr_flags = *flags; + } + } return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 945fbf29719d..f6a6d78efcf0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1132,6 +1132,8 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); u32 __ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); +void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, + const int offset); static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 66785739dad3..1300e8859ea7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -148,6 +148,26 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, return 0; } +void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, + const int offset) +{ + struct ieee80211_local *local = sdata->local; + u32 flags = sdata->u.mntr_flags; + +#define ADJUST(_f, _s) do { \ + if (flags & MONITOR_FLAG_##_f) \ + local->fif_##_s += offset; \ + } while (0) + + ADJUST(FCSFAIL, fcsfail); + ADJUST(PLCPFAIL, plcpfail); + ADJUST(CONTROL, control); + ADJUST(CONTROL, pspoll); + ADJUST(OTHER_BSS, other_bss); + +#undef ADJUST +} + /* * NOTE: Be very careful when changing this function, it must NOT return * an error on interface type changes that have been pre-checked, so most @@ -240,17 +260,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; } - if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) - local->fif_fcsfail++; - if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) - local->fif_plcpfail++; - if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { - local->fif_control++; - local->fif_pspoll++; - } - if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) - local->fif_other_bss++; - + ieee80211_adjust_monitor_flags(sdata, 1); ieee80211_configure_filter(local); netif_carrier_on(dev); @@ -477,17 +487,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; } - if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) - local->fif_fcsfail--; - if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) - local->fif_plcpfail--; - if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { - local->fif_pspoll--; - local->fif_control--; - } - if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) - local->fif_other_bss--; - + ieee80211_adjust_monitor_flags(sdata, -1); ieee80211_configure_filter(local); break; case NL80211_IFTYPE_MESH_POINT: -- cgit v1.2.3 From 5c895691944862e782c285a871f5d3466797b4ef Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 28 Sep 2010 23:00:59 +0200 Subject: carl9170: support firmware-based rx filter The hardware rx-filter was essentially disabled, because of a serve, yet unidentifiable problem with iwlagn. Due to these circumstances the driver and mac80211 were left with the job of filtering. This is very unfortunate and has proven to be expensive in terms of latency, memory and load. Therefore the new 1.8.8.3 firmware introduces a flexible filtering infrastructure which allows the driver to offload some of the checks (FCS & PLCP crc check, RA match, control frame filter, etc...) whenever possible. Note: This patch also includes all changes to the shared headers files since the inclusion. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 2 ++ drivers/net/wireless/ath/carl9170/cmd.h | 10 ++++++++++ drivers/net/wireless/ath/carl9170/fw.c | 7 +++++++ drivers/net/wireless/ath/carl9170/fwcmd.h | 16 +++++++++++++++ drivers/net/wireless/ath/carl9170/fwdesc.h | 6 +++++- drivers/net/wireless/ath/carl9170/hw.h | 3 +++ drivers/net/wireless/ath/carl9170/main.c | 30 ++++++++++++++++++++++++++-- drivers/net/wireless/ath/carl9170/phy.h | 5 +---- drivers/net/wireless/ath/carl9170/version.h | 6 +++--- 9 files changed, 75 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 20f2a77e54d2..6cf0c9ef47aa 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -279,6 +279,7 @@ struct ar9170 { unsigned int beacon_max_len; bool rx_stream; bool tx_stream; + bool rx_filter; unsigned int mem_blocks; unsigned int mem_block_size; unsigned int rx_size; @@ -314,6 +315,7 @@ struct ar9170 { u64 cur_mc_hash; u32 cur_filter; unsigned int filter_state; + unsigned int rx_filter_caps; bool sniffer_enabled; /* MAC */ diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h index 0fc83d2336fd..f78728c38294 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.h +++ b/drivers/net/wireless/ath/carl9170/cmd.h @@ -59,6 +59,16 @@ static inline int carl9170_flush_cab(struct ar9170 *ar, return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); } +static inline int carl9170_rx_filter(struct ar9170 *ar, + const unsigned int _rx_filter) +{ + __le32 rx_filter = cpu_to_le32(_rx_filter); + + return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER, + sizeof(rx_filter), (u8 *)&rx_filter, + 0, NULL); +} + struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, const unsigned int len); diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 36615462b87a..ae6c006bbc56 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -257,6 +257,13 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (SUPP(CARL9170FW_USB_UP_STREAM)) ar->fw.rx_stream = true; + if (SUPP(CARL9170FW_RX_FILTER)) { + ar->fw.rx_filter = true; + ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | + FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS | + FIF_PROMISC_IN_BSS; + } + ar->fw.vif_num = otus_desc->vif_num; ar->fw.cmd_bufs = otus_desc->cmd_bufs; ar->fw.address = le32_to_cpu(otus_desc->fw_address); diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index d4a4e1dbef06..d552166db505 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -53,6 +53,7 @@ enum carl9170_cmd_oids { CARL9170_CMD_REBOOT = 0x04, CARL9170_CMD_BCN_CTRL = 0x05, CARL9170_CMD_READ_TSF = 0x06, + CARL9170_CMD_RX_FILTER = 0x07, /* CAM */ CARL9170_CMD_EKEY = 0x10, @@ -153,6 +154,20 @@ struct carl9170_psm { } __packed; #define CARL9170_PSM_SIZE 4 +struct carl9170_rx_filter_cmd { + __le32 rx_filter; +} __packed; +#define CARL9170_RX_FILTER_CMD_SIZE 4 + +#define CARL9170_RX_FILTER_BAD 0x01 +#define CARL9170_RX_FILTER_OTHER_RA 0x02 +#define CARL9170_RX_FILTER_DECRY_FAIL 0x04 +#define CARL9170_RX_FILTER_CTL_OTHER 0x08 +#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10 +#define CARL9170_RX_FILTER_CTL_BACKR 0x20 +#define CARL9170_RX_FILTER_MGMT 0x40 +#define CARL9170_RX_FILTER_DATA 0x80 + struct carl9170_bcn_ctrl_cmd { __le32 vif_id; __le32 mode; @@ -188,6 +203,7 @@ struct carl9170_cmd { struct carl9170_rf_init rf_init; struct carl9170_psm psm; struct carl9170_bcn_ctrl_cmd bcn_ctrl; + struct carl9170_rx_filter_cmd rx_filter; u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; } __packed; } __packed; diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h index 7cd811708fe5..71f3821f6058 100644 --- a/drivers/net/wireless/ath/carl9170/fwdesc.h +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -66,6 +66,9 @@ enum carl9170fw_feature_list { /* Firmware PSM support | CARL9170_CMD_PSM */ CARL9170FW_PSM, + /* Firmware RX filter | CARL9170_CMD_RX_FILTER */ + CARL9170FW_RX_FILTER, + /* KEEP LAST */ __CARL9170FW_FEATURE_NUM }; @@ -142,7 +145,7 @@ struct carl9170fw_fix_desc { (sizeof(struct carl9170fw_fix_desc)) #define CARL9170FW_DBG_DESC_MIN_VER 1 -#define CARL9170FW_DBG_DESC_CUR_VER 2 +#define CARL9170FW_DBG_DESC_CUR_VER 3 struct carl9170fw_dbg_desc { struct carl9170fw_desc_head head; @@ -150,6 +153,7 @@ struct carl9170fw_dbg_desc { __le32 counter_addr; __le32 rx_total_addr; __le32 rx_overrun_addr; + __le32 rx_filter; /* Put your debugging definitions here */ } __packed; diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index b1292ac5b703..2f471b3f05af 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -731,6 +731,9 @@ struct ar9170_stream { #define SET_VAL(reg, value, newvalue) \ (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) +#define SET_CONSTVAL(reg, newvalue) \ + (((newvalue) << reg##_S) & reg) + #define MOD_VAL(reg, value, newvalue) \ (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) #endif /* __CARL9170_SHARED_HW_H */ diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 84bd38e9961c..3cc99f3f7ab5 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -380,6 +380,13 @@ static int carl9170_op_start(struct ieee80211_hw *hw) if (err) goto out; + if (ar->fw.rx_filter) { + err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA | + CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD); + if (err) + goto out; + } + err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, AR9170_DMA_TRIGGER_RXQ); if (err) @@ -840,8 +847,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, struct ar9170 *ar = hw->priv; /* mask supported flags */ - *new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL | - FIF_OTHER_BSS | FIF_PROMISC_IN_BSS; + *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps; if (!IS_ACCEPTING_CMD(ar)) return; @@ -867,6 +873,26 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, WARN_ON(carl9170_set_operating_mode(ar)); } + if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) { + u32 rx_filter = 0; + + if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))) + rx_filter |= CARL9170_RX_FILTER_BAD; + + if (!(*new_flags & FIF_CONTROL)) + rx_filter |= CARL9170_RX_FILTER_CTL_OTHER; + + if (!(*new_flags & FIF_PSPOLL)) + rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; + + if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) { + rx_filter |= CARL9170_RX_FILTER_OTHER_RA; + rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; + } + + WARN_ON(carl9170_rx_filter(ar, rx_filter)); + } + mutex_unlock(&ar->mutex); } diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h index 53c18d34ffcc..02c34eb4ebde 100644 --- a/drivers/net/wireless/ath/carl9170/phy.h +++ b/drivers/net/wireless/ath/carl9170/phy.h @@ -423,8 +423,8 @@ #define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 #define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 -#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) #define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) +#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) #define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 #define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 #define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 @@ -561,7 +561,4 @@ #define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 #define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 -#define REDUCE_CHAIN_0 0x00000050 -#define REDUCE_CHAIN_1 0x00000051 - #endif /* __CARL9170_SHARED_PHY_H */ diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index 0e917f80eab4..ff53f078a0b5 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,7 @@ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H #define CARL9170FW_VERSION_YEAR 10 -#define CARL9170FW_VERSION_MONTH 8 -#define CARL9170FW_VERSION_DAY 30 -#define CARL9170FW_VERSION_GIT "1.8.8.1" +#define CARL9170FW_VERSION_MONTH 9 +#define CARL9170FW_VERSION_DAY 28 +#define CARL9170FW_VERSION_GIT "1.8.8.3" #endif /* __CARL9170_SHARED_VERSION_H */ -- cgit v1.2.3 From 35ecfe03d96b7cdaf6e50aba13af37e2c99deb57 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 17:15:26 +0200 Subject: ath9k_htc: remove use of common->ani.noise_floor It is unused aside from a single redundant debug message Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5124d04b240b..f12591f5d02a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -760,23 +760,12 @@ void ath9k_ani_work(struct work_struct *work) ath9k_hw_ani_monitor(ah, ah->curchan); /* Perform calibration if necessary */ - if (longcal || shortcal) { + if (longcal || shortcal) common->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, common->rx_chainmask, longcal); - if (longcal) - common->ani.noise_floor = - ath9k_hw_getchan_noise(ah, ah->curchan); - - ath_print(common, ATH_DBG_ANI, - " calibrate chan %u/%x nf: %d\n", - ah->curchan->channel, - ah->curchan->channelFlags, - common->ani.noise_floor); - } - ath9k_htc_ps_restore(priv); } -- cgit v1.2.3 From d9891c7804f27c5b0ea9eb51f42bf473b24338a0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 17:15:27 +0200 Subject: ath9k_hw: keep calibrated noise floor values per channel Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 40 +++++++++++++++++----------------- drivers/net/wireless/ath/ath9k/hw.c | 2 +- drivers/net/wireless/ath/ath9k/hw.h | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 67ee5d735cc1..6351e76792a6 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -346,34 +346,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) struct ieee80211_channel *c = chan->chan; struct ath9k_hw_cal_data *caldata = ah->caldata; - if (!caldata) - return false; - chan->channelFlags &= (~CHANNEL_CW_INT); if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { ath_print(common, ATH_DBG_CALIBRATE, "NF did not complete in calibration window\n"); - nf = 0; - caldata->rawNoiseFloor = nf; return false; - } else { - ath9k_hw_do_getnf(ah, nfarray); - ath9k_hw_nf_sanitize(ah, nfarray); - nf = nfarray[0]; - if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) - && nf > nfThresh) { - ath_print(common, ATH_DBG_CALIBRATE, - "noise floor failed detected; " - "detected %d, threshold %d\n", - nf, nfThresh); - chan->channelFlags |= CHANNEL_CW_INT; - } + } + + ath9k_hw_do_getnf(ah, nfarray); + ath9k_hw_nf_sanitize(ah, nfarray); + nf = nfarray[0]; + if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) + && nf > nfThresh) { + ath_print(common, ATH_DBG_CALIBRATE, + "noise floor failed detected; " + "detected %d, threshold %d\n", + nf, nfThresh); + chan->channelFlags |= CHANNEL_CW_INT; + } + + if (!caldata) { + chan->noisefloor = nf; + return false; } h = caldata->nfCalHist; caldata->nfcal_pending = false; ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); - caldata->rawNoiseFloor = h[0].privNF; + chan->noisefloor = h[0].privNF; return true; } @@ -401,10 +401,10 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) { - if (!ah->caldata || !ah->caldata->rawNoiseFloor) + if (!ah->curchan || !ah->curchan->noisefloor) return ath9k_hw_get_default_nf(ah, chan); - return ah->caldata->rawNoiseFloor; + return ah->curchan->noisefloor; } EXPORT_SYMBOL(ath9k_hw_getchan_noise); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 25ed65ac992c..1b066043d6cb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1239,7 +1239,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; - if (curchan && !ah->chip_fullsleep && ah->caldata) + if (curchan && !ah->chip_fullsleep) ath9k_hw_getnf(ah, curchan); ah->caldata = caldata; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index df47f792cf4e..1b6739bd93ff 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -342,7 +342,6 @@ struct ath9k_hw_cal_data { int32_t CalValid; int8_t iCoff; int8_t qCoff; - int16_t rawNoiseFloor; bool paprd_done; bool nfcal_pending; bool nfcal_interference; @@ -356,6 +355,7 @@ struct ath9k_channel { u16 channel; u32 channelFlags; u32 chanmode; + s16 noisefloor; }; #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ -- cgit v1.2.3 From 4f1a5a4b62c5335aafd5830866320c8918103a3a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 17:15:28 +0200 Subject: ath9k: do not return default noise floor values via survey Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a13387882636..fcba402d5a1e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2004,15 +2004,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; if (idx != 0) return -ENOENT; survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = common->ani.noise_floor; + survey->filled = 0; + if (ah->curchan && ah->curchan->noisefloor) { + survey->filled |= SURVEY_INFO_NOISE_DBM; + survey->noise = ah->curchan->noisefloor; + } return 0; } -- cgit v1.2.3 From 0bda652300dff8136c9d889f1133462c7c7d332c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 17:15:29 +0200 Subject: ath9k: remove the noise floor value in the ani struct common->ani.noise_floor is now only used for a similar redundant debug message similar to the one that was removed from ath9k_htc in an earlier patch. Remove it from ath9k as well now. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 1 - drivers/net/wireless/ath/ath9k/main.c | 10 ---------- 3 files changed, 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index dd236c3b52f6..5894fcc2c628 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -35,7 +35,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct ath_ani { bool caldone; - int16_t noise_floor; unsigned int longcal_timer; unsigned int shortcal_timer; unsigned int resetcal_timer; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index de3393867e37..11dc3ac20cd6 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -506,7 +506,6 @@ static void ath9k_init_misc(struct ath_softc *sc) struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index fcba402d5a1e..a801a08c4da2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -459,16 +459,6 @@ void ath_ani_calibrate(unsigned long data) ah->curchan, common->rx_chainmask, longcal); - - if (longcal) - common->ani.noise_floor = ath9k_hw_getchan_noise(ah, - ah->curchan); - - ath_print(common, ATH_DBG_ANI, - " calibrate chan %u/%x nf: %d\n", - ah->curchan->channel, - ah->curchan->channelFlags, - common->ani.noise_floor); } } -- cgit v1.2.3 From 17e5a8082894a4b66cb69e7ec16074f0f01281e1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 17:15:30 +0200 Subject: nl80211: allow drivers to indicate whether the survey data channel is in use Some user space applications only want to display survey data for the operating channel, however there is no API to get that yet. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index f0518b0278a9..edd21ae6acf7 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1400,6 +1400,7 @@ enum nl80211_reg_rule_flags { * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) + * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number * currently defined * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use @@ -1408,6 +1409,7 @@ enum nl80211_survey_info { __NL80211_SURVEY_INFO_INVALID, NL80211_SURVEY_INFO_FREQUENCY, NL80211_SURVEY_INFO_NOISE, + NL80211_SURVEY_INFO_IN_USE, /* keep last */ __NL80211_SURVEY_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a0613ff62c97..ecc0403b918a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -293,12 +293,14 @@ struct key_params { * enum survey_info_flags - survey information flags * * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in + * @SURVEY_INFO_IN_USE: channel is currently being used * * Used by the driver to indicate which info in &struct survey_info * it has filled in during the get_survey(). */ enum survey_info_flags { SURVEY_INFO_NOISE_DBM = 1<<0, + SURVEY_INFO_IN_USE = 1<<1, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9c84825803ce..0087c4323c53 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3489,6 +3489,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, if (survey->filled & SURVEY_INFO_NOISE_DBM) NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise); + if (survey->filled & SURVEY_INFO_IN_USE) + NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); nla_nest_end(msg, infoattr); -- cgit v1.2.3 From 39162dbe813a2c90b7b9018a74dc1befb9ff4205 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 19:12:06 +0200 Subject: ath9k: return survey data for all channels instead of just the current one Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a801a08c4da2..49ea45896b89 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1994,16 +1994,31 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; - struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_supported_band *sband; + struct ath9k_channel *chan; + + sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ]; + if (sband && idx >= sband->n_channels) { + idx -= sband->n_channels; + sband = NULL; + } - if (idx != 0) - return -ENOENT; + if (!sband) + sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; - survey->channel = conf->channel; + if (!sband || idx >= sband->n_channels) + return -ENOENT; + + survey->channel = &sband->channels[idx]; + chan = &ah->channels[survey->channel->hw_value]; survey->filled = 0; - if (ah->curchan && ah->curchan->noisefloor) { + + if (chan == ah->curchan) + survey->filled |= SURVEY_INFO_IN_USE; + + if (chan->noisefloor) { survey->filled |= SURVEY_INFO_NOISE_DBM; - survey->noise = ah->curchan->noisefloor; + survey->noise = chan->noisefloor; } return 0; -- cgit v1.2.3 From e32ee80b855914e48b1beb53e13203bc874288d8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 30 Sep 2010 02:44:56 +0100 Subject: ar9170: Remove MODULE_FIRMWARE references to two-stage firmware The combined firmware ar9170.fw is preferred and supports all devices. References to the older two-stage firmware are unnecessary. Signed-off-by: Ben Hutchings Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index a93dc18a45c3..5dbb5361fd51 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -54,8 +54,6 @@ MODULE_AUTHOR("Christian Lamparter "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); MODULE_FIRMWARE("ar9170.fw"); -MODULE_FIRMWARE("ar9170-1.fw"); -MODULE_FIRMWARE("ar9170-2.fw"); enum ar9170_requirements { AR9170_REQ_FW1_ONLY = 1, -- cgit v1.2.3 From 4bd530f3ab51c7d656bca29d927a50e5aa87175e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 30 Sep 2010 16:27:35 +0200 Subject: iwlwifi: change WARN_ON to IWL_WARN in iwl_mac_add_interface We can start restarting firmware or RF kill switch can be turned on during call to iwl_mac_add_interface(). That are normal working conditions, so do not print call trace, just print simple message instead. Signed-off-by: Stanislaw Gruszka Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5c568933ce48..b7adcf87280d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2003,7 +2003,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_lock(&priv->mutex); - if (WARN_ON(!iwl_is_ready_rf(priv))) { + if (!iwl_is_ready_rf(priv)) { + IWL_WARN(priv, "Try to add interface when device not ready\n"); err = -EINVAL; goto out; } -- cgit v1.2.3 From 663fcafd977f13e6483f7d4cf2ccdbc4fae81ed0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 30 Sep 2010 21:06:09 +0200 Subject: cfg80211/mac80211: allow management frame TX in AP mode Enable management frame transmission and subscribing to management frames through nl80211 in both cfg80211 and mac80211. Also update a few places that I forgot to update for P2P-client mode previously, and fix a small bug with non-action frames in this API. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 7 ++++++- net/wireless/mlme.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- net/wireless/nl80211.c | 10 ++++++++-- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9e63fc28f859..a7a78f28ff6f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1549,7 +1549,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, switch (sdata->vif.type) { case NL80211_IFTYPE_ADHOC: - if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: + if (!ieee80211_is_action(mgmt->frame_control) || + mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) break; rcu_read_lock(); sta = sta_info_get(sdata, mgmt->da); @@ -1558,6 +1562,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, return -ENOLINK; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: break; default: return -EOPNOTSUPP; diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 46f371160896..caf11a427507 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -876,21 +876,53 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, if (ieee80211_is_action(mgmt->frame_control) && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { - /* Verify that we are associated with the destination AP */ + int err = 0; + wdev_lock(wdev); - if (!wdev->current_bss || - memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, - ETH_ALEN) != 0 || - ((wdev->iftype == NL80211_IFTYPE_STATION || - wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && - memcmp(wdev->current_bss->pub.bssid, mgmt->da, - ETH_ALEN) != 0)) { - wdev_unlock(wdev); - return -ENOTCONN; - } + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + if (!wdev->current_bss) { + err = -ENOTCONN; + break; + } + + if (memcmp(wdev->current_bss->pub.bssid, + mgmt->bssid, ETH_ALEN)) { + err = -ENOTCONN; + break; + } + + /* + * check for IBSS DA must be done by driver as + * cfg80211 doesn't track the stations + */ + if (wdev->iftype == NL80211_IFTYPE_ADHOC) + break; + /* for station, check that DA is the AP */ + if (memcmp(wdev->current_bss->pub.bssid, + mgmt->da, ETH_ALEN)) { + err = -ENOTCONN; + break; + } + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_AP_VLAN: + if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) + err = -EINVAL; + break; + default: + err = -EOPNOTSUPP; + break; + } wdev_unlock(wdev); + + if (err) + return err; } if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0087c4323c53..cbbbe9ab452f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4828,7 +4828,10 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } @@ -4881,7 +4884,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { err = -EOPNOTSUPP; goto out; } -- cgit v1.2.3 From ea229e682633a18c1fa2c408400a6923cfc47910 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 30 Sep 2010 21:21:25 +0200 Subject: cfg80211: remove spurious __KERNEL__ ifdef The net/cfg80211.h header file isn't exported to userspace, so there's no need for any kind of __KERNEL__ protection in it. If it was exported, everything else in it would need protection as well, not just the logging stuff ... Cc:Joe Perches Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ecc0403b918a..5f4d8acf7abb 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2553,8 +2553,6 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -#ifdef __KERNEL__ - /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ @@ -2601,6 +2599,4 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, #define wiphy_WARN(wiphy, format, args...) \ WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); -#endif - #endif /* __NET_CFG80211_H */ -- cgit v1.2.3 From b1ae1edf9e9872d3aa657cc34ae40c9aadfbc72f Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 30 Sep 2010 12:22:58 -0700 Subject: ath5k: Allow ath5k to support virtual STA and AP interfaces. Support up to 4 virtual APs and as many virtual STA interfaces as desired. This patch is ported forward from a patch that Patrick McHardy did for me against 2.6.31. Signed-off-by: Ben Greear Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 275 +++++++++++++++++++++++++++------ drivers/net/wireless/ath/ath5k/base.h | 19 ++- drivers/net/wireless/ath/ath5k/reset.c | 4 +- 3 files changed, 249 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 94cc3354f3a6..2ed327a8d690 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -509,8 +510,71 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) } } +struct ath_vif_iter_data { + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; + u8 active_mac[ETH_ALEN]; /* first active MAC */ + bool need_set_hw_addr; + bool found_active; + bool any_assoc; +}; + +static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath_vif_iter_data *iter_data = data; + int i; + + if (iter_data->hw_macaddr) + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= + ~(iter_data->hw_macaddr[i] ^ mac[i]); + + if (!iter_data->found_active) { + iter_data->found_active = true; + memcpy(iter_data->active_mac, mac, ETH_ALEN); + } + + if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) + if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) + iter_data->need_set_hw_addr = false; + + if (!iter_data->any_assoc) { + struct ath5k_vif *avf = (void *)vif->drv_priv; + if (avf->assoc) + iter_data->any_assoc = true; + } +} + +void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif) +{ + struct ath_common *common = ath5k_hw_common(sc->ah); + struct ath_vif_iter_data iter_data; + + /* + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. + */ + iter_data.hw_macaddr = common->macaddr; + memset(&iter_data.mask, 0xff, ETH_ALEN); + iter_data.found_active = false; + iter_data.need_set_hw_addr = true; + + if (vif) + ath_vif_iter(&iter_data, vif->addr, vif); + + /* Get list of all active MAC addresses */ + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + &iter_data); + memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); + + if (iter_data.need_set_hw_addr && iter_data.found_active) + ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); + + ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); +} + static void -ath5k_mode_setup(struct ath5k_softc *sc) +ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) { struct ath5k_hw *ah = sc->ah; u32 rfilt; @@ -520,7 +584,7 @@ ath5k_mode_setup(struct ath5k_softc *sc) ath5k_hw_set_rx_filter(ah, rfilt); if (ath5k_hw_hasbssidmask(ah)) - ath5k_hw_set_bssid_mask(ah, sc->bssidmask); + ath5k_update_bssid_mask(sc, vif); /* configure operational mode */ ath5k_hw_set_opmode(ah, sc->opmode); @@ -698,13 +762,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, flags |= AR5K_TXDESC_RTSENA; cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, - sc->vif, pktlen, info)); + info->control.vif, pktlen, info)); } if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { flags |= AR5K_TXDESC_CTSENA; cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, - sc->vif, pktlen, info)); + info->control.vif, pktlen, info)); } ret = ah->ah_setup_tx_desc(ah, ds, pktlen, ieee80211_get_hdrlen_from_skb(skb), padsize, @@ -806,10 +870,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) list_add_tail(&bf->list, &sc->txbuf); } - /* beacon buffer */ - bf->desc = ds; - bf->daddr = da; - sc->bbuf = bf; + /* beacon buffers */ + INIT_LIST_HEAD(&sc->bcbuf); + for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->bcbuf); + } return 0; err_free: @@ -824,11 +891,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) { struct ath5k_buf *bf; - ath5k_txbuf_free_skb(sc, sc->bbuf); list_for_each_entry(bf, &sc->txbuf, list) ath5k_txbuf_free_skb(sc, bf); list_for_each_entry(bf, &sc->rxbuf, list) ath5k_rxbuf_free_skb(sc, bf); + list_for_each_entry(bf, &sc->bcbuf, list) + ath5k_txbuf_free_skb(sc, bf); /* Free memory associated with all descriptors */ pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); @@ -837,7 +905,6 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) kfree(sc->bufptr); sc->bufptr = NULL; - sc->bbuf = NULL; } @@ -1083,7 +1150,7 @@ ath5k_rx_start(struct ath5k_softc *sc) spin_unlock_bh(&sc->rxbuflock); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_mode_setup(sc); /* set filters, etc. */ + ath5k_mode_setup(sc, NULL); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; @@ -1750,6 +1817,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { int ret; struct ath5k_softc *sc = hw->priv; + struct ath5k_vif *avf = (void *)vif->drv_priv; struct sk_buff *skb; if (WARN_ON(!vif)) { @@ -1766,11 +1834,11 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ath5k_debug_dump_skb(sc, skb, "BC ", 1); - ath5k_txbuf_free_skb(sc, sc->bbuf); - sc->bbuf->skb = skb; - ret = ath5k_beacon_setup(sc, sc->bbuf); + ath5k_txbuf_free_skb(sc, avf->bbuf); + avf->bbuf->skb = skb; + ret = ath5k_beacon_setup(sc, avf->bbuf); if (ret) - sc->bbuf->skb = NULL; + avf->bbuf->skb = NULL; out: return ret; } @@ -1786,16 +1854,14 @@ out: static void ath5k_beacon_send(struct ath5k_softc *sc) { - struct ath5k_buf *bf = sc->bbuf; struct ath5k_hw *ah = sc->ah; + struct ieee80211_vif *vif; + struct ath5k_vif *avf; + struct ath5k_buf *bf; struct sk_buff *skb; ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); - if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) { - ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); - return; - } /* * Check if the previous beacon has gone out. If * not, don't don't try to post another: skip this @@ -1824,6 +1890,28 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->bmisscount = 0; } + if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); + int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; + vif = sc->bslot[(slot + 1) % ATH_BCBUF]; + ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, + "tsf %llx tsftu %x intval %u slot %u vif %p\n", + (unsigned long long)tsf, tsftu, sc->bintval, slot, vif); + } else /* only one interface */ + vif = sc->bslot[0]; + + if (!vif) + return; + + avf = (void *)vif->drv_priv; + bf = avf->bbuf; + if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || + sc->opmode == NL80211_IFTYPE_MONITOR)) { + ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); + return; + } + /* * Stop any current dma and put the new frame on the queue. * This should never fail since we check above that no frames @@ -1836,17 +1924,17 @@ ath5k_beacon_send(struct ath5k_softc *sc) /* refresh the beacon for AP mode */ if (sc->opmode == NL80211_IFTYPE_AP) - ath5k_beacon_update(sc->hw, sc->vif); + ath5k_beacon_update(sc->hw, vif); ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); ath5k_hw_start_tx_dma(ah, sc->bhalq); ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", sc->bhalq, (unsigned long long)bf->daddr, bf->desc); - skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); + skb = ieee80211_get_buffered_bc(sc->hw, vif); while (skb) { ath5k_tx_queue(sc->hw, skb, sc->cabq); - skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); + skb = ieee80211_get_buffered_bc(sc->hw, vif); } sc->bsent++; @@ -1876,6 +1964,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) u64 hw_tsf; intval = sc->bintval & AR5K_BEACON_PERIOD; + if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(sc, "intval %u is too low, min 15\n", + intval); + } if (WARN_ON(!intval)) return; @@ -2323,6 +2417,10 @@ ath5k_init(struct ath5k_softc *sc) ath_hw_keyreset(common, (u16) i); ath5k_hw_set_ack_bitrate_high(ah, true); + + for (i = 0; i < ARRAY_SIZE(sc->bslot); i++) + sc->bslot[i] = NULL; + ret = 0; done: mmiowb(); @@ -2382,7 +2480,6 @@ ath5k_stop_hw(struct ath5k_softc *sc) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "putting device to sleep\n"); } - ath5k_txbuf_free_skb(sc, sc->bbuf); mmiowb(); mutex_unlock(&sc->lock); @@ -2587,9 +2684,9 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) } SET_IEEE80211_PERM_ADDR(hw, mac); + memcpy(&sc->lladdr, mac, ETH_ALEN); /* All MAC address bits matter for ACKs */ - memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); + ath5k_update_bssid_mask(sc, NULL); regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); @@ -2687,31 +2784,91 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, { struct ath5k_softc *sc = hw->priv; int ret; + struct ath5k_hw *ah = sc->ah; + struct ath5k_vif *avf = (void *)vif->drv_priv; mutex_lock(&sc->lock); - if (sc->vif) { - ret = 0; + + if ((vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_ADHOC) + && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) { + ret = -ELNRNG; goto end; } - sc->vif = vif; + /* Don't allow other interfaces if one ad-hoc is configured. + * TODO: Fix the problems with ad-hoc and multiple other interfaces. + * We would need to operate the HW in ad-hoc mode to allow TSF updates + * for the IBSS, but this breaks with additional AP or STA interfaces + * at the moment. */ + if (sc->num_adhoc_vifs || + (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { + ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n"); + ret = -ELNRNG; + goto end; + } switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: - sc->opmode = vif->type; + avf->opmode = vif->type; break; default: ret = -EOPNOTSUPP; goto end; } - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); + sc->nvifs++; + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); + /* Assign the vap/adhoc to a beacon xmit slot. */ + if ((avf->opmode == NL80211_IFTYPE_AP) || + (avf->opmode == NL80211_IFTYPE_ADHOC)) { + int slot; + + WARN_ON(list_empty(&sc->bcbuf)); + avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf, + list); + list_del(&avf->bbuf->list); + + avf->bslot = 0; + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (!sc->bslot[slot]) { + avf->bslot = slot; + break; + } + } + BUG_ON(sc->bslot[avf->bslot] != NULL); + sc->bslot[avf->bslot] = vif; + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs++; + else + sc->num_adhoc_vifs++; + } + + /* Set combined mode - when APs are configured, operate in AP mode. + * Otherwise use the mode of the new interface. This can currently + * only deal with combinations of APs and STAs. Only one ad-hoc + * interfaces is allowed above. + */ + if (sc->num_ap_vifs) + sc->opmode = NL80211_IFTYPE_AP; + else + sc->opmode = vif->type; + + ath5k_hw_set_opmode(ah, sc->opmode); + + /* Any MAC address is fine, all others are included through the + * filter. + */ + memcpy(&sc->lladdr, vif->addr, ETH_ALEN); ath5k_hw_set_lladdr(sc->ah, vif->addr); - ath5k_mode_setup(sc); + + memcpy(&avf->lladdr, vif->addr, ETH_ALEN); + + ath5k_mode_setup(sc, vif); ret = 0; end: @@ -2724,15 +2881,29 @@ ath5k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath5k_softc *sc = hw->priv; - u8 mac[ETH_ALEN] = {}; + struct ath5k_vif *avf = (void *)vif->drv_priv; + unsigned int i; mutex_lock(&sc->lock); - if (sc->vif != vif) - goto end; + sc->nvifs--; + + if (avf->bbuf) { + ath5k_txbuf_free_skb(sc, avf->bbuf); + list_add_tail(&avf->bbuf->list, &sc->bcbuf); + for (i = 0; i < ATH_BCBUF; i++) { + if (sc->bslot[i] == vif) { + sc->bslot[i] = NULL; + break; + } + } + avf->bbuf = NULL; + } + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs--; + else if (avf->opmode == NL80211_IFTYPE_ADHOC) + sc->num_adhoc_vifs--; - ath5k_hw_set_lladdr(sc->ah, mac); - sc->vif = NULL; -end: + ath5k_update_bssid_mask(sc, NULL); mutex_unlock(&sc->lock); } @@ -2815,6 +2986,19 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, return ((u64)(mfilt[1]) << 32) | mfilt[0]; } +static bool ath_any_vif_assoc(struct ath5k_softc *sc) +{ + struct ath_vif_iter_data iter_data; + iter_data.hw_macaddr = NULL; + iter_data.any_assoc = false; + iter_data.need_set_hw_addr = false; + iter_data.found_active = true; + + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + &iter_data); + return iter_data.any_assoc; +} + #define SUPPORTED_FIF_FLAGS \ FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ @@ -2885,7 +3069,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons * and probes for any BSSID */ - if (*new_flags & FIF_BCN_PRBRESP_PROMISC) + if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1)) rfilt |= AR5K_RX_FILTER_BEACON; /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not @@ -3070,14 +3254,13 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changes) { + struct ath5k_vif *avf = (void *)vif->drv_priv; struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); unsigned long flags; mutex_lock(&sc->lock); - if (WARN_ON(sc->vif != vif)) - goto unlock; if (changes & BSS_CHANGED_BSSID) { /* Cache for later use during resets */ @@ -3091,7 +3274,12 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, sc->bintval = bss_conf->beacon_int; if (changes & BSS_CHANGED_ASSOC) { - sc->assoc = bss_conf->assoc; + avf->assoc = bss_conf->assoc; + if (bss_conf->assoc) + sc->assoc = bss_conf->assoc; + else + sc->assoc = ath_any_vif_assoc(sc); + if (sc->opmode == NL80211_IFTYPE_STATION) set_beacon_filter(hw, sc->assoc); ath5k_hw_set_ledstate(sc->ah, sc->assoc ? @@ -3119,7 +3307,6 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, BSS_CHANGED_BEACON_INT)) ath5k_beacon_config(sc); - unlock: mutex_unlock(&sc->lock); } @@ -3394,6 +3581,8 @@ ath5k_pci_probe(struct pci_dev *pdev, hw->max_rate_tries = 11; } + hw->vif_data_size = sizeof(struct ath5k_vif); + /* Finish private driver data initialization */ ret = ath5k_attach(pdev, hw); if (ret) diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 7f9d0d3018e8..b9f6d13b7675 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -58,8 +58,7 @@ #define ATH_RXBUF 40 /* number of RX buffers */ #define ATH_TXBUF 200 /* number of TX buffers */ -#define ATH_BCBUF 1 /* number of beacon buffers */ - +#define ATH_BCBUF 4 /* number of beacon buffers */ #define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ #define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ @@ -152,6 +151,14 @@ struct ath5k_statistics { #define ATH_CHAN_MAX (14+14+14+252+20) #endif +struct ath5k_vif { + bool assoc; /* are we associated or not */ + enum nl80211_iftype opmode; + int bslot; + struct ath5k_buf *bbuf; /* beacon buffer */ + u8 lladdr[ETH_ALEN]; +}; + /* Software Carrier, keeps track of the driver state * associated with an instance of a device */ struct ath5k_softc { @@ -188,10 +195,11 @@ struct ath5k_softc { unsigned int curmode; /* current phy mode */ struct ieee80211_channel *curchan; /* current h/w channel */ - struct ieee80211_vif *vif; + u16 nvifs; enum ath5k_int imask; /* interrupt mask copy */ + u8 lladdr[ETH_ALEN]; u8 bssidmask[ETH_ALEN]; unsigned int led_pin, /* GPIO pin for driving LED */ @@ -219,7 +227,10 @@ struct ath5k_softc { spinlock_t block; /* protects beacon */ struct tasklet_struct beacontq; /* beacon intr tasklet */ - struct ath5k_buf *bbuf; /* beacon buffer */ + struct list_head bcbuf; /* beacon buffer */ + struct ieee80211_vif *bslot[ATH_BCBUF]; + u16 num_ap_vifs; + u16 num_adhoc_vifs; unsigned int bhalq, /* SW q for outgoing beacons */ bmisscount, /* missed beacon transmits */ bintval, /* beacon interval in TU */ diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 58912cd762d9..5b179d01f97d 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, - sc->vif, 10, rate)); + NULL, 10, rate)); ath5k_hw_reg_write(ah, tx_time, reg); @@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * XXX: rethink this after new mode changes to * mac80211 are integrated */ if (ah->ah_version == AR5K_AR5212 && - ah->ah_sc->vif != NULL) + ah->ah_sc->nvifs) ath5k_hw_write_rate_duration(ah, mode); /* -- cgit v1.2.3 From 2234362c427e2ef667595b9b81c0125003ac5607 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 30 Sep 2010 22:17:43 +0200 Subject: cfg80211: fix locking Add missing unlocking of the wiphy in set_channel, and don't try to unlock a non-existing wiphy in set_cqm. Cc: stable@kernel.org [2.6.35+] Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cbbbe9ab452f..21061ccee557 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -821,11 +821,13 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); if (result) - goto unlock; + goto unlock_rtnl; result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); - unlock: + dev_put(netdev); + cfg80211_unlock_rdev(rdev); + unlock_rtnl: rtnl_unlock(); return result; @@ -5097,7 +5099,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); if (err) - goto unlock_rdev; + goto unlock_rtnl; wdev = dev->ieee80211_ptr; @@ -5115,9 +5117,10 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, threshold, hysteresis); -unlock_rdev: + unlock_rdev: cfg80211_unlock_rdev(rdev); dev_put(dev); + unlock_rtnl: rtnl_unlock(); return err; -- cgit v1.2.3 From f209f5298217cf54cd5a9163e18b08d093faf8d9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 1 Oct 2010 01:06:53 +0200 Subject: ath9k: fix channel flag / regd issues with multiple cards Since the regulatory code touches the channel array, it needs to be copied for each device instance. That way the original channel array can also be made const. Signed-off-by: Felix Fietkau Cc: stable@kernel.org [all] Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 37 +++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 11dc3ac20cd6..282bb482424f 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity"); * on 5 MHz steps, we support the channels which we know * we have calibration data for all cards though to make * this static */ -static struct ieee80211_channel ath9k_2ghz_chantable[] = { +static const struct ieee80211_channel ath9k_2ghz_chantable[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ CHAN2G(2422, 2), /* Channel 3 */ @@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = { * on 5 MHz steps, we support the channels which we know * we have calibration data for all cards though to make * this static */ -static struct ieee80211_channel ath9k_5ghz_chantable[] = { +static const struct ieee80211_channel ath9k_5ghz_chantable[] = { /* _We_ call this UNII 1 */ CHAN5G(5180, 14), /* Channel 36 */ CHAN5G(5200, 15), /* Channel 40 */ @@ -477,10 +477,17 @@ err: return -EIO; } -static void ath9k_init_channels_rates(struct ath_softc *sc) +static int ath9k_init_channels_rates(struct ath_softc *sc) { + void *channels; + if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; + channels = kmemdup(ath9k_2ghz_chantable, + sizeof(ath9k_2ghz_chantable), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; sc->sbands[IEEE80211_BAND_2GHZ].n_channels = ARRAY_SIZE(ath9k_2ghz_chantable); @@ -490,7 +497,15 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) } if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; + channels = kmemdup(ath9k_5ghz_chantable, + sizeof(ath9k_5ghz_chantable), GFP_KERNEL); + if (!channels) { + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); + return -ENOMEM; + } + + sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; sc->sbands[IEEE80211_BAND_5GHZ].n_channels = ARRAY_SIZE(ath9k_5ghz_chantable); @@ -499,6 +514,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = ARRAY_SIZE(ath9k_legacy_rates) - 4; } + return 0; } static void ath9k_init_misc(struct ath_softc *sc) @@ -594,8 +610,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_btcoex; + ret = ath9k_init_channels_rates(sc); + if (ret) + goto err_btcoex; + ath9k_init_crypto(sc); - ath9k_init_channels_rates(sc); ath9k_init_misc(sc); return 0; @@ -755,6 +774,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc) { int i = 0; + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); + + if (sc->sbands[IEEE80211_BAND_5GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); + if ((sc->btcoex.no_stomp_timer) && sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); -- cgit v1.2.3 From 9094a086f24bfb1d1f244883020c4d9453ffc0b6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 1 Oct 2010 01:46:13 +0200 Subject: ath9k_hw: remove some useless calibration data The percal struct and bitmask for the initial DC calibration are not used anywhere, so they can be removed. Signed-off-by: Felix Fietkau --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 16 ---------------- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 1 - drivers/net/wireless/ath/ath9k/calib.h | 1 - drivers/net/wireless/ath/ath9k/hw.h | 1 - 4 files changed, 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index d7d1d55362e6..f2da119bbf02 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -45,11 +45,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting ADC DC Calibration\n"); break; - case ADC_DC_INIT_CAL: - REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); - ath_print(common, ATH_DBG_CALIBRATE, - "starting Init ADC DC Calibration\n"); - break; case TEMP_COMP_CAL: break; /* Not supported */ } @@ -950,13 +945,6 @@ static const struct ath9k_percal_data adc_dc_cal_single_sample = { ar9002_hw_adc_dccal_collect, ar9002_hw_adc_dccal_calibrate }; -static const struct ath9k_percal_data adc_init_dc_cal = { - ADC_DC_INIT_CAL, - MIN_CAL_SAMPLES, - INIT_LOG_COUNT, - ar9002_hw_adc_dccal_collect, - ar9002_hw_adc_dccal_calibrate -}; static void ar9002_hw_init_cal_settings(struct ath_hw *ah) { @@ -973,16 +961,12 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah) &adc_gain_cal_single_sample; ah->adcdc_caldata.calData = &adc_dc_cal_single_sample; - ah->adcdc_calinitdata.calData = - &adc_init_dc_cal; } else { ah->iq_caldata.calData = &iq_cal_multi_sample; ah->adcgain_caldata.calData = &adc_gain_cal_multi_sample; ah->adcdc_caldata.calData = &adc_dc_cal_multi_sample; - ah->adcdc_calinitdata.calData = - &adc_init_dc_cal; } ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4674ea8c9c99..b41f5cda824b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -50,7 +50,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting Temperature Compensation Calibration\n"); break; - case ADC_DC_INIT_CAL: case ADC_GAIN_CAL: case ADC_DC_CAL: /* Not yet */ diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 5b053a6260b2..1fa56c91a894 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -59,7 +59,6 @@ struct ar5416IniArray { } while (0) enum ath9k_cal_types { - ADC_DC_INIT_CAL = 0x1, ADC_GAIN_CAL = 0x2, ADC_DC_CAL = 0x4, IQ_MISMATCH_CAL = 0x8, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1b6739bd93ff..235cb5357a22 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -692,7 +692,6 @@ struct ath_hw { enum ath9k_cal_types supp_cals; struct ath9k_cal_list iq_caldata; struct ath9k_cal_list adcgain_caldata; - struct ath9k_cal_list adcdc_calinitdata; struct ath9k_cal_list adcdc_caldata; struct ath9k_cal_list tempCompCalData; struct ath9k_cal_list *cal_list; -- cgit v1.2.3 From 8e0167a4bdce4adcea64d2197378673d332cda28 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 1 Oct 2010 15:25:05 +0530 Subject: ath9k : Fix for displaying the channel number In the ath9k debugging feature 'wiphy' the current channel used by the station is incorrectly displayed.This is because the channels available are sequentially mapped from numbers 0 to 37.This mapping cannot be changed as the channel number is also used as an array index This fix solves the above problem by calculating the channel number from center frequency. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d65a896a421d..7a5932a6691a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -488,6 +488,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; + struct ath_wiphy *aphy = sc->pri_wiphy; + struct ieee80211_channel *chan = aphy->hw->conf.channel; char buf[512]; unsigned int len = 0; int i; @@ -498,7 +500,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, "primary: %s (%s chan=%d ht=%d)\n", wiphy_name(sc->pri_wiphy->hw->wiphy), ath_wiphy_state_str(sc->pri_wiphy->state), - sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht); + ieee80211_frequency_to_channel(chan->center_freq), + aphy->chan_is_ht); put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); @@ -545,11 +548,13 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, struct ath_wiphy *aphy = sc->sec_wiphy[i]; if (aphy == NULL) continue; + chan = aphy->hw->conf.channel; len += snprintf(buf + len, sizeof(buf) - len, - "secondary: %s (%s chan=%d ht=%d)\n", - wiphy_name(aphy->hw->wiphy), - ath_wiphy_state_str(aphy->state), - aphy->chan_idx, aphy->chan_is_ht); + "secondary: %s (%s chan=%d ht=%d)\n", + wiphy_name(aphy->hw->wiphy), + ath_wiphy_state_str(aphy->state), + ieee80211_frequency_to_channel(chan->center_freq), + aphy->chan_is_ht); } if (len > sizeof(buf)) len = sizeof(buf); -- cgit v1.2.3 From bc86863de63e6ae7ec6f9f524604631608c6cb02 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 1 Oct 2010 14:05:27 +0200 Subject: mac80211: perform scan cancel in hw reset work Move ieee80211_scan_cancel() and all other related code to ieee80211_restart_work() as ieee80211_restart_hw() is intended to be callable from any context. Fix a bug that RTNL lock is not taken during ieee80211_cancel_scan(). Take local->mtx before WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) to prevent the race condition with __ieee80211_start_scan() described here: http://marc.info/?l=linux-wireless&m=128516716810537&w=2 Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- net/mac80211/main.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e24fa5be4264..494dba1b46a5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -295,7 +295,17 @@ static void ieee80211_restart_work(struct work_struct *work) struct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work); + /* wait for scan work complete */ + flush_workqueue(local->workqueue); + + mutex_lock(&local->mtx); + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + "%s called with hardware scan in progress\n", __func__); + mutex_unlock(&local->mtx); + rtnl_lock(); + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) + ieee80211_scan_cancel(local); ieee80211_reconfig(local); rtnl_unlock(); } @@ -306,15 +316,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) trace_api_restart_hw(local); - /* wait for scan work complete */ - flush_workqueue(local->workqueue); - - WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), - "%s called with hardware scan in progress\n", __func__); - - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) - ieee80211_scan_cancel(local); - /* use this reason, ieee80211_reconfig will unblock it */ ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); -- cgit v1.2.3 From d8ec44335c974cc8bf67ce70c63071d4e0702509 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Fri, 1 Oct 2010 16:02:31 +0300 Subject: mac80211: Add validity check for beacon_crc value On association to an AP, after receiving beacons, the beacon_crc value is set. The beacon_crc value is not reset in disassociation, but the BSS data may be expired at a later point. When associating again, it's possible that a beacon for the AP is not received, resulting in the beacon_ies to remain NULL. After association, further beacons will not update the beacon data, as the crc value of the beacon has not changed, and the beacon_crc still holds a value matching the beacon. The beacon_ies will remain forever null. One of the results of this is that WLAN power save cannot be entered, the STA will remain foreven in active mode. Fix this by adding a validation flag for the beacon_crc, which is cleared on association. Signed-off-by: Juuso Oikarinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f6a6d78efcf0..55d79db985fc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -369,6 +369,7 @@ struct ieee80211_if_managed { unsigned int flags; + bool beacon_crc_valid; u32 beacon_crc; enum { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 77913a15f537..c37086a12f51 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1639,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, ifmgd->aid); - if (ncrc != ifmgd->beacon_crc) { + if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) { ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); @@ -1670,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } - if (ncrc == ifmgd->beacon_crc) + if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) return; ifmgd->beacon_crc = ncrc; + ifmgd->beacon_crc_valid = true; if (elems.erp_info && elems.erp_info_len >= 1) { erp_valid = true; @@ -2214,6 +2215,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; + ifmgd->beacon_crc_valid = false; + for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || -- cgit v1.2.3 From e51f3eff9a7e17ddd749799d4291f7e33e9883b9 Mon Sep 17 00:00:00 2001 From: Bill Jordan Date: Fri, 1 Oct 2010 11:20:39 -0400 Subject: ath9k: add WDS interfaces to ath9k Enable WDS for the ath9k driver. Signed-off-by: Bill Jordan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 282bb482424f..d76003c06fe4 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -657,6 +657,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 49ea45896b89..e6ddf45506be 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1374,6 +1374,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: ic_opmode = NL80211_IFTYPE_STATION; break; + case NL80211_IFTYPE_WDS: + ic_opmode = NL80211_IFTYPE_WDS; + break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: -- cgit v1.2.3 From e8347ebad2f1b15bddb6ed3ed5f767531eb52dc3 Mon Sep 17 00:00:00 2001 From: Bill Jordan Date: Fri, 1 Oct 2010 13:54:28 -0400 Subject: cfg80211: patches to allow setting the WDS peer Added a nl interface to set the peer bssid of a WDS interface. Signed-off-by: Bill Jordan Signed-off-by: John W. Linville --- include/linux/nl80211.h | 3 +++ net/wireless/nl80211.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index edd21ae6acf7..73d9390d4ddb 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -387,6 +387,8 @@ * of any other interfaces, and other interfaces will again take * precedence when they are used. * + * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -489,6 +491,7 @@ enum nl80211_commands { NL80211_CMD_NOTIFY_CQM, NL80211_CMD_SET_CHANNEL, + NL80211_CMD_SET_WDS_PEER, /* add new commands above here */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 21061ccee557..fd92b6b7ff04 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -603,6 +603,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); } CMD(set_channel, SET_CHANNEL); + CMD(set_wds_peer, SET_WDS_PEER); #undef CMD @@ -833,6 +834,53 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) return result; } +static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; + struct net_device *dev; + u8 *bssid; + int err; + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + rtnl_lock(); + + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); + if (err) + goto unlock_rtnl; + + wdev = dev->ieee80211_ptr; + + if (netif_running(dev)) { + err = -EBUSY; + goto out; + } + + if (!rdev->ops->set_wds_peer) { + err = -EOPNOTSUPP; + goto out; + } + + if (wdev->iftype != NL80211_IFTYPE_WDS) { + err = -EOPNOTSUPP; + goto out; + } + + bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); + err = rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); + +out: + cfg80211_unlock_rdev(rdev); + dev_put(dev); +unlock_rtnl: + rtnl_unlock(); + + return err; +} + + static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev; @@ -5473,6 +5521,12 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, }, + { + .cmd = NL80211_CMD_SET_WDS_PEER, + .doit = nl80211_set_wds_peer, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { -- cgit v1.2.3 From 1be7fe8de9f25e173282f8f989f83bc5b5decfe9 Mon Sep 17 00:00:00 2001 From: Bill Jordan Date: Fri, 1 Oct 2010 11:20:41 -0400 Subject: mac80211: fix for WDS interfaces Initialize the rate table for WDS interfaces, and add cases to allow WDS packets to pass the xmit and receive tests. Signed-off-by: Bill Jordan Signed-off-by: John W. Linville --- net/mac80211/iface.c | 3 +++ net/mac80211/main.c | 3 +++ net/mac80211/rx.c | 1 + net/mac80211/tx.c | 3 +++ 4 files changed, 10 insertions(+) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1300e8859ea7..438a2f51420e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -24,6 +24,7 @@ #include "led.h" #include "driver-ops.h" #include "wme.h" +#include "rate.h" /** * DOC: Interface list locking @@ -311,6 +312,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) /* STA has been freed */ goto err_del_interface; } + + rate_control_rate_init(sta); } /* diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 494dba1b46a5..e127fbb8424e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -201,6 +201,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; else if (sdata->vif.type == NL80211_IFTYPE_AP) sdata->vif.bss_conf.bssid = sdata->vif.addr; + else if (sdata->vif.type == NL80211_IFTYPE_WDS) + sdata->vif.bss_conf.bssid = NULL; else if (ieee80211_vif_is_mesh(&sdata->vif)) { sdata->vif.bss_conf.bssid = zero; } else { @@ -211,6 +213,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, switch (sdata->vif.type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: break; default: diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0b0e83ebe3d5..b3e161ffa4b3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -819,6 +819,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) if (unlikely((ieee80211_is_data(hdr->frame_control) || ieee80211_is_pspoll(hdr->frame_control)) && rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && + rx->sdata->vif.type != NL80211_IFTYPE_WDS && (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { if ((!ieee80211_has_fromds(hdr->frame_control) && !ieee80211_has_tods(hdr->frame_control) && diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e1733dcb58a7..258fbdbedbdf 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) */ return TX_DROP; + if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) + return TX_CONTINUE; + if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) return TX_CONTINUE; -- cgit v1.2.3 From b72acddbbe521d1372e7e9106e9d72e1cbab3010 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 1 Oct 2010 10:54:04 -0700 Subject: ath5k: Print rx/tx bytes in debugfs This adds counters for tx and rx bytes, including any errored packets as well as all wireless headers. Signed-off-by: Ben Greear Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 ++ drivers/net/wireless/ath/ath5k/base.h | 7 +++++++ drivers/net/wireless/ath/ath5k/debug.c | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2ed327a8d690..d914a31cb0b6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1433,6 +1433,7 @@ static bool ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) { sc->stats.rx_all_count++; + sc->stats.rx_bytes_count += rs->rs_datalen; if (unlikely(rs->rs_status)) { if (rs->rs_status & AR5K_RXERR_CRC) @@ -1611,6 +1612,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, int i; sc->stats.tx_all_count++; + sc->stats.tx_bytes_count += skb->len; info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index b9f6d13b7675..9a79773cdc2a 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -121,6 +121,13 @@ struct ath5k_statistics { /* frame errors */ unsigned int rx_all_count; /* all RX frames, including errors */ unsigned int tx_all_count; /* all TX frames, including errors */ + unsigned int rx_bytes_count; /* all RX bytes, including errored pks + * and the MAC headers for each packet + */ + unsigned int tx_bytes_count; /* all TX bytes, including errored pkts + * and the MAC headers and padding for + * each packet. + */ unsigned int rxerr_crc; unsigned int rxerr_phy; unsigned int rxerr_phy_code[32]; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0f06e8490314..c2d549f871f9 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -587,6 +587,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, st->rxerr_jumbo*100/st->rx_all_count : 0); len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", st->rx_all_count); + len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n", + st->rx_bytes_count); len += snprintf(buf+len, sizeof(buf)-len, "\nTX\n---------------------\n"); @@ -604,6 +606,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, st->txerr_filt*100/st->tx_all_count : 0); len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", st->tx_all_count); + len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n", + st->tx_bytes_count); if (len > sizeof(buf)) len = sizeof(buf); -- cgit v1.2.3 From 99c15bf575b18e12c9373304a6a09a78f9c8a017 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 1 Oct 2010 12:26:30 -0700 Subject: ath9k: Report total tx/rx bytes and packets in debugfs. Includes pkts/bytes that may have had errors, and includes wireless headers when counting bytes. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 15 +++++++++++++++ drivers/net/wireless/ath/ath9k/debug.h | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 7a5932a6691a..74a4570dc87f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -701,6 +701,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DESC CFG Error: ", desc_cfg_err); PR("DATA Underrun: ", data_underrun); PR("DELIM Underrun: ", delim_underrun); + PR("TX-Pkts-All: ", tx_pkts_all); + PR("TX-Bytes-All: ", tx_bytes_all); if (len > size) len = size; @@ -714,6 +716,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct ath_tx_status *ts) { + TX_STAT_INC(txq->axq_qnum, tx_pkts_all); + sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len; + if (bf_isampdu(bf)) { if (bf_isxretried(bf)) TX_STAT_INC(txq->axq_qnum, a_xretries); @@ -808,6 +813,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); + len += snprintf(buf + len, size - len, + "%18s : %10u\n", "RX-Pkts-All", + sc->debug.stats.rxstats.rx_pkts_all); + len += snprintf(buf + len, size - len, + "%18s : %10u\n", "RX-Bytes-All", + sc->debug.stats.rxstats.rx_bytes_all); + if (len > size) len = size; @@ -826,6 +838,9 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) u32 phyerr; + RX_STAT_INC(rx_pkts_all); + sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; + if (rs->rs_status & ATH9K_RXERR_CRC) RX_STAT_INC(crc_err); if (rs->rs_status & ATH9K_RXERR_DECRYPT) diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 5d21704e87ff..822b6f3f23c5 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -89,6 +89,10 @@ struct ath_rc_stats { /** * struct ath_tx_stats - Statistics about TX + * @tx_pkts_all: No. of total frames transmitted, including ones that + may have had errors. + * @tx_bytes_all: No. of total bytes transmitted, including ones that + may have had errors. * @queued: Total MPDUs (non-aggr) queued * @completed: Total MPDUs (non-aggr) completed * @a_aggr: Total no. of aggregates queued @@ -107,6 +111,8 @@ struct ath_rc_stats { * @delim_urn: TX delimiter underrun errors */ struct ath_tx_stats { + u32 tx_pkts_all; + u32 tx_bytes_all; u32 queued; u32 completed; u32 a_aggr; @@ -124,6 +130,10 @@ struct ath_tx_stats { /** * struct ath_rx_stats - RX Statistics + * @rx_pkts_all: No. of total frames received, including ones that + may have had errors. + * @rx_bytes_all: No. of total bytes received, including ones that + may have had errors. * @crc_err: No. of frames with incorrect CRC value * @decrypt_crc_err: No. of frames whose CRC check failed after decryption process completed @@ -136,6 +146,8 @@ struct ath_tx_stats { * @phy_err_stats: Individual PHY error statistics */ struct ath_rx_stats { + u32 rx_pkts_all; + u32 rx_bytes_all; u32 crc_err; u32 decrypt_crc_err; u32 phy_err; -- cgit v1.2.3 From 1a92795dac419128eb511dce30a6aad672064b88 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 1 Oct 2010 22:01:24 +0200 Subject: p54usb: add five more USBIDs Source: http://www.wikidevi.com/wiki/Intersil/p54/usb/windows Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 063248b35069..d5bc21e5a02c 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -33,8 +33,17 @@ MODULE_ALIAS("prism54usb"); MODULE_FIRMWARE("isl3886usb"); MODULE_FIRMWARE("isl3887usb"); +/* + * Note: + * + * Always update our wiki's device list (located at: + * http://wireless.kernel.org/en/users/Drivers/p54/devices ), + * whenever you add a new device. + */ + static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ @@ -47,7 +56,9 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ @@ -60,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ @@ -80,6 +92,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ + {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ -- cgit v1.2.3 From 2a0cfeb826df6751933fd95a797ac18371992c3b Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:26:17 +0200 Subject: rt2x00: Don't overwrite beacon buffers in pairwise key setup rt2800 devices use parts of the pariwise key table to store the beacon frames for beacon 6 and 7. To not overwrite the beacon frame buffers limit the number of entries we store in the pairwise key table to 222. Also add some descriptive comments about this shared memory usage. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 21 ++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2800lib.c | 6 +++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2edc7742a7e9..e1583cf5894b 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1435,6 +1435,24 @@ /* * Security key table memory. + * + * The pairwise key table shares some memory with the beacon frame + * buffers 6 and 7. That basically means that when beacon 6 & 7 + * are used we should only use the reduced pairwise key table which + * has a maximum of 222 entries. + * + * --------------------------------------------- + * |0x4000 | Pairwise Key | Reduced Pairwise | + * | | Table | Key Table | + * | | Size: 256 * 32 | Size: 222 * 32 | + * |0x5BC0 | |------------------- + * | | | Beacon 6 | + * |0x5DC0 | |------------------- + * | | | Beacon 7 | + * |0x5FC0 | |------------------- + * |0x5FFF | | + * -------------------------- + * * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry @@ -1584,7 +1602,8 @@ struct mac_iveiv_entry { * 2. Extract memory from FCE table for BCN 4~5 * 3. Extract memory from Pair-wise key table for BCN 6~7 * It occupied those memory of wcid 238~253 for BCN 6 - * and wcid 222~237 for BCN 7 + * and wcid 222~237 for BCN 7 (see Security key table memory + * for more info). * * IMPORTANT NOTE: Not sure why legacy driver does this, * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c7076deaecea..daa32ae42866 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1031,8 +1031,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * 1 pairwise key is possible per AID, this means that the AID * equals our hw_key_idx. Make sure the WCID starts _after_ the * last possible shared key entry. + * + * Since parts of the pairwise key table might be shared with + * the beacon frame buffers 6 & 7 we should only write into the + * first 222 entries. */ - if (crypto->aid > (256 - 32)) + if (crypto->aid > (222 - 32)) return -ENOSPC; key->hw_key_idx = 32 + crypto->aid; -- cgit v1.2.3 From 144333313b156a9e99d80e39e034a3cba00adeaf Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:27:03 +0200 Subject: rt2x00: Split out parts of the rt2800_txdone function for easier reuse Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 100 +++++++++++++++++--------------- drivers/net/wireless/rt2x00/rt2800lib.h | 1 + 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index daa32ae42866..19534f272d76 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -630,15 +630,63 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) return true; } +void rt2800_txdone_entry(struct queue_entry *entry, u32 status) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct txdone_entry_desc txdesc; + u32 word; + u16 mcs, real_mcs; + __le32 *txwi; + + /* + * Obtain the status about this packet. + */ + txdesc.flags = 0; + txwi = rt2800_drv_get_txwi(entry); + rt2x00_desc_read(txwi, 0, &word); + mcs = rt2x00_get_field32(word, TXWI_W0_MCS); + real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + + /* + * Ralink has a retry mechanism using a global fallback + * table. We setup this fallback table to try the immediate + * lower rate for all rates. In the TX_STA_FIFO, the MCS field + * always contains the MCS used for the last transmission, be + * it successful or not. + */ + if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) { + /* + * Transmission succeeded. The number of retries is + * mcs - real_mcs + */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); + } else { + /* + * Transmission failed. The number of retries is + * always 7 in this case (for a total number of 8 + * frames sent). + */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + txdesc.retry = rt2x00dev->long_retry; + } + + /* + * the frame was retried at least once + * -> hw used fallback rates + */ + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); + + rt2x00lib_txdone(entry, &txdesc); +} +EXPORT_SYMBOL_GPL(rt2800_txdone_entry); + void rt2800_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; - __le32 *txwi; - struct txdone_entry_desc txdesc; - u32 word; u32 reg; - u16 mcs, real_mcs; u8 pid; int i; @@ -673,7 +721,6 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) * order. We first check that the queue is not empty. */ entry = NULL; - txwi = NULL; while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); if (rt2800_txdone_entry_check(entry, reg)) @@ -683,48 +730,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) if (!entry || rt2x00queue_empty(queue)) break; - - /* - * Obtain the status about this packet. - */ - txdesc.flags = 0; - txwi = rt2800_drv_get_txwi(entry); - rt2x00_desc_read(txwi, 0, &word); - mcs = rt2x00_get_field32(word, TXWI_W0_MCS); - real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); - - /* - * Ralink has a retry mechanism using a global fallback - * table. We setup this fallback table to try the immediate - * lower rate for all rates. In the TX_STA_FIFO, the MCS field - * always contains the MCS used for the last transmission, be - * it successful or not. - */ - if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { - /* - * Transmission succeeded. The number of retries is - * mcs - real_mcs - */ - __set_bit(TXDONE_SUCCESS, &txdesc.flags); - txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); - } else { - /* - * Transmission failed. The number of retries is - * always 7 in this case (for a total number of 8 - * frames sent). - */ - __set_bit(TXDONE_FAILURE, &txdesc.flags); - txdesc.retry = rt2x00dev->long_retry; - } - - /* - * the frame was retried at least once - * -> hw used fallback rates - */ - if (txdesc.retry) - __set_bit(TXDONE_FALLBACK, &txdesc.flags); - - rt2x00lib_txdone(entry, &txdesc); + rt2800_txdone_entry(entry, reg); } } EXPORT_SYMBOL_GPL(rt2800_txdone); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 600c5eb25c41..81cbc92e7857 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -153,6 +153,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); void rt2800_txdone(struct rt2x00_dev *rt2x00dev); +void rt2800_txdone_entry(struct queue_entry *entry, u32 status); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); -- cgit v1.2.3 From 96c3da7d7d7c37ee308ad6813947f48a71cca573 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:27:35 +0200 Subject: rt2x00: rework tx status handling in rt2800pci This patch changes the way tx status reports are handled by rt2800pci. Previously rt2800pci would sometimes lose tx status reports as the TX_STA_FIFO register is a fifo of 16 entries that can overflow in case we don't read it often/fast enough. Since interrupts are disabled in the device during the execution of the interrupt thread it happend sometimes under high network and CPU load that processing took too long and a few tx status reports were dropped by the hw. To fix this issue the TX_STA_FIFO register is read directly in the interrupt handler and stored in a kfifo which is large enough to hold all status reports of all used tx queues. To process the status reports a new tasklet txstatus_tasklet is used. Using the already used interrupt thread is not possible since we don't want to disable the TX_FIFO_STATUS interrupt while processing them and it is not possible to schedule the interrupt thread multiple times for execution. A tasklet instead can be scheduled multiple times which allows to leave the TX_FIFO_STATUS interrupt enabled while a previously scheduled tasklet is still executing. In short: All other interrupts are handled in the interrupt thread as before. Only the TX_FIFO_STATUS interrupt is partly handled in the interrupt handler and finished in the according tasklet. One drawback of this patch is that it duplicates some code from rt2800lib. However, that can be cleaned up in the future once the rt2800usb and rt2800pci tx status handling converge more. Using this patch on a Ralink RT3052 embedded board gives me a reliable wireless connection even under high CPU and network load. I've transferred several gigabytes without any queue lockups. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 150 +++++++++++++++++++++++++++++--- drivers/net/wireless/rt2x00/rt2x00.h | 17 ++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 34 ++++++++ 3 files changed, 188 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 005ee153e0cc..3806454b827b 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -660,6 +660,63 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } +static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + u32 status; + u8 qid; + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { + /* Now remove the tx status from the FIFO */ + if (kfifo_out(&rt2x00dev->txstatus_fifo, &status, + sizeof(status)) != sizeof(status)) { + WARN_ON(1); + break; + } + + qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1; + if (qid >= QID_RX) { + /* + * Unknown queue, this shouldn't happen. Just drop + * this tx status. + */ + WARNING(rt2x00dev, "Got TX status report with " + "unexpected pid %u, dropping", qid); + break; + } + + queue = rt2x00queue_get_queue(rt2x00dev, qid); + if (unlikely(queue == NULL)) { + /* + * The queue is NULL, this shouldn't happen. Stop + * processing here and drop the tx status + */ + WARNING(rt2x00dev, "Got TX status for an unavailable " + "queue %u, dropping", qid); + break; + } + + if (rt2x00queue_empty(queue)) { + /* + * The queue is empty. Stop processing here + * and drop the tx status. + */ + WARNING(rt2x00dev, "Got TX status for an empty " + "queue %u, dropping", qid); + break; + } + + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + rt2800_txdone_entry(entry, status); + } +} + +static void rt2800pci_txstatus_tasklet(unsigned long data) +{ + rt2800pci_txdone((struct rt2x00_dev *)data); +} + static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; @@ -684,13 +741,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) rt2x00pci_rxdone(rt2x00dev); /* - * 4 - Tx done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800_txdone(rt2x00dev); - - /* - * 5 - Auto wakeup interrupt. + * 4 - Auto wakeup interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) rt2800pci_wakeup(rt2x00dev); @@ -702,10 +753,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) return IRQ_HANDLED; } +static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) +{ + u32 status; + int i; + + /* + * The TX_FIFO_STATUS interrupt needs special care. We should + * read TX_STA_FIFO but we should do it immediately as otherwise + * the register can overflow and we would lose status reports. + * + * Hence, read the TX_STA_FIFO register and copy all tx status + * reports into a kernel FIFO which is handled in the txstatus + * tasklet. We use a tasklet to process the tx status reports + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * + * Furthermore we don't disable the TX_FIFO_STATUS + * interrupt here but leave it enabled so that the TX_STA_FIFO + * can also be read while the interrupt thread gets executed. + * + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ + for (i = 0; i < TX_ENTRIES; i++) { + rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); + + if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) + break; + + if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) { + WARNING(rt2x00dev, "TX status FIFO overrun," + " drop tx status report.\n"); + break; + } + + if (kfifo_in(&rt2x00dev->txstatus_fifo, &status, + sizeof(status)) != sizeof(status)) { + WARNING(rt2x00dev, "TX status FIFO overrun," + "drop tx status report.\n"); + break; + } + } + + /* Schedule the tasklet for processing the tx status. */ + tasklet_schedule(&rt2x00dev->txstatus_tasklet); +} + static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg; + irqreturn_t ret = IRQ_HANDLED; /* Read status and ACK all interrupts */ rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); @@ -717,15 +816,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* Store irqvalue for use in the interrupt thread. */ - rt2x00dev->irqvalue[0] = reg; + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) + rt2800pci_txstatus_interrupt(rt2x00dev); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) { + /* + * All other interrupts are handled in the interrupt thread. + * Store irqvalue for use in the interrupt thread. + */ + rt2x00dev->irqvalue[0] = reg; - /* Disable interrupts, will be enabled again in the interrupt thread. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); + /* + * Disable interrupts, will be enabled again in the + * interrupt thread. + */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); + /* + * Leave the TX_FIFO_STATUS interrupt enabled to not lose any + * tx status reports. + */ + rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); + rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); - return IRQ_WAKE_THREAD; + ret = IRQ_WAKE_THREAD; + } + + return ret; } /* @@ -788,6 +910,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); @@ -837,6 +960,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .irq_handler = rt2800pci_interrupt, .irq_handler_thread = rt2800pci_interrupt_thread, + .txstatus_tasklet = rt2800pci_txstatus_tasklet, .probe_hw = rt2800pci_probe_hw, .get_firmware_name = rt2800pci_get_firmware_name, .check_firmware = rt2800_check_firmware, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 7832a5996a8c..bab10adae537 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -521,6 +522,11 @@ struct rt2x00lib_ops { */ irq_handler_t irq_handler_thread; + /* + * TX status tasklet handler. + */ + void (*txstatus_tasklet) (unsigned long data); + /* * Device init handlers. */ @@ -651,6 +657,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_DMA, DRIVER_REQUIRE_COPY_IV, DRIVER_REQUIRE_L2PAD, + DRIVER_REQUIRE_TXSTATUS_FIFO, /* * Driver features @@ -884,6 +891,16 @@ struct rt2x00_dev { * and interrupt thread routine. */ u32 irqvalue[2]; + + /* + * FIFO for storing tx status reports between isr and tasklet. + */ + struct kfifo txstatus_fifo; + + /* + * Tasklet for processing tx status reports (rt2800pci). + */ + struct tasklet_struct txstatus_tasklet; }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 053fdd3bd720..b03e6e41dc1e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -812,6 +812,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; + /* + * Allocate tx status FIFO for driver use. + */ + if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && + rt2x00dev->ops->lib->txstatus_tasklet) { + /* + * Allocate txstatus fifo and tasklet, we use a size of 512 + * for the kfifo which is big enough to store 512/4=128 tx + * status reports. In the worst case (tx status for all tx + * queues gets reported before we've got a chance to handle + * them) 24*4=384 tx status reports need to be cached. + */ + status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, + GFP_KERNEL); + if (status) + return status; + + /* tasklet for processing the tx status reports. */ + tasklet_init(&rt2x00dev->txstatus_tasklet, + rt2x00dev->ops->lib->txstatus_tasklet, + (unsigned long)rt2x00dev); + + } + /* * Register HW. */ @@ -1027,6 +1051,16 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); + /* + * Free the tx status fifo. + */ + kfifo_free(&rt2x00dev->txstatus_fifo); + + /* + * Kill the tx status tasklet. + */ + tasklet_kill(&rt2x00dev->txstatus_tasklet); + /* * Uninitialize device. */ -- cgit v1.2.3 From a13ac9df0a2125507295da02444cd88bebf0df36 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:28:02 +0200 Subject: rt2x00: Fix SM PS check Fix a check for dynamic SM PS mode in the STAs HT caps. Since a value of 3 means "SM PS disabled" the previous check assumed in that case that "dynamic SM PS" was enabled and as such prefixed every MCS>7 frame with a unnecessary RTS/CTS exchange. Also, the bit shift was done in the wrong direction. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index ad3c7ff4837b..48b6ed426da5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -60,9 +60,10 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, * when using more then one tx stream (>MCS7). */ if (tx_info->control.sta && txdesc->mcs > 7 && - (tx_info->control.sta->ht_cap.cap & - (WLAN_HT_CAP_SM_PS_DYNAMIC << - IEEE80211_HT_CAP_SM_PS_SHIFT))) + ((tx_info->control.sta->ht_cap.cap & + IEEE80211_HT_CAP_SM_PS) >> + IEEE80211_HT_CAP_SM_PS_SHIFT) == + WLAN_HT_CAP_SM_PS_DYNAMIC) __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); } else { txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); -- cgit v1.2.3 From 87c1915d2c271a8998a79f16bcf5353e2c28db45 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:28:34 +0200 Subject: rt2x00: Implement HT protection for rt2800 Update the HT operation mode when mac80211 sends it to us and set the different HT protection modes and rates accordingly. For now only use CTS-to-self with OFDM 24M or CCK 11M when protection is required. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 99 ++++++++++++++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00config.c | 3 + drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 19534f272d76..4ecacea677ac 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1169,6 +1169,102 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } EXPORT_SYMBOL_GPL(rt2800_config_intf); +static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_erp *erp) +{ + bool any_sta_nongf = !!(erp->ht_opmode & + IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION; + u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode; + u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate; + u32 reg; + + /* default protection rate for HT20: OFDM 24M */ + mm20_rate = gf20_rate = 0x4004; + + /* default protection rate for HT40: duplicate OFDM 24M */ + mm40_rate = gf40_rate = 0x4084; + + switch (protection) { + case IEEE80211_HT_OP_MODE_PROTECTION_NONE: + /* + * All STAs in this BSS are HT20/40 but there might be + * STAs not supporting greenfield mode. + * => Disable protection for HT transmissions. + */ + mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0; + + break; + case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: + /* + * All STAs in this BSS are HT20 or HT20/40 but there + * might be STAs not supporting greenfield mode. + * => Protect all HT40 transmissions. + */ + mm20_mode = gf20_mode = 0; + mm40_mode = gf40_mode = 2; + + break; + case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: + /* + * Nonmember protection: + * According to 802.11n we _should_ protect all + * HT transmissions (but we don't have to). + * + * But if cts_protection is enabled we _shall_ protect + * all HT transmissions using a CCK rate. + * + * And if any station is non GF we _shall_ protect + * GF transmissions. + * + * We decide to protect everything + * -> fall through to mixed mode. + */ + case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: + /* + * Legacy STAs are present + * => Protect all HT transmissions. + */ + mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2; + + /* + * If erp protection is needed we have to protect HT + * transmissions with CCK 11M long preamble. + */ + if (erp->cts_protection) { + /* don't duplicate RTS/CTS in CCK mode */ + mm20_rate = mm40_rate = 0x0003; + gf20_rate = gf40_rate = 0x0003; + } + break; + }; + + /* check for STAs not supporting greenfield mode */ + if (any_sta_nongf) + gf20_mode = gf40_mode = 2; + + /* Update HT protection config */ + rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); + rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, mm20_rate); + rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode); + rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, mm40_rate); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode); + rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); + rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, gf20_rate); + rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode); + rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); + rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, gf40_rate); + rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode); + rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); +} + void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, u32 changed) { @@ -1213,6 +1309,9 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, erp->beacon_int * 16); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); } + + if (changed & BSS_CHANGED_HT) + rt2800_config_ht_opmode(rt2x00dev, erp); } EXPORT_SYMBOL_GPL(rt2800_config_erp); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index bab10adae537..75ac6624bf9e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -458,6 +458,7 @@ struct rt2x00lib_erp { short eifs; u16 beacon_int; + u16 ht_opmode; }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 4c7ff765a8bf..54ffb5aeb34e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -103,6 +103,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; + if (changed & BSS_CHANGED_HT) + erp.ht_opmode = bss_conf->ht_operation_mode; + rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 7862a840984a..c3c206a97d54 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -671,7 +671,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, */ if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | - BSS_CHANGED_BEACON_INT)) + BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT)) rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); } EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); -- cgit v1.2.3 From d13a97f07d86f462096007dbf0f2e0338692abc0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:29:08 +0200 Subject: rt2x00: Don't initialize MM40 HT protection to RTS/CTS on PCI devices Since HT protection is now configurable via mac80211 we don't need this special case for PCI devices anymore. The HT protection config will be overwritten as soon as mac80211 sends us a HT operation mode. Hence, bring the HT MM40 protection config in sync with the other HT protection registers and initialize it to no protection. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 4ecacea677ac..76b8783c5639 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2016,8 +2016,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); - rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, - !rt2x00_is_usb(rt2x00dev)); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); -- cgit v1.2.3 From 95192339c2de1e1a61baf289af3e3332403371c9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:29:30 +0200 Subject: rt2x00: Fix race between dma mapping and clearing rx entries in rt2800pci During rx, rt2x00lib calls rt2800pci_fill_rxdone to read the RX descriptor. At that time the skb is already dma unmapped but no new skb was dma mapped for this entry again. However, rt2800pci_fill_rxdone also moves the hw rx queue index, marking this entry to be available for reuse. Since no new skb was dma mapped and also the previous skb was unmapped this might lead to strange hw behavior. To fix this issue move the hw rx queue index increment to rt2800pci_clear_entry where a new skb was already dma mapped and can be safely used by the hw. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 3806454b827b..85a134cd62bf 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -241,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) { struct queue_entry_priv_pci *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; u32 word; if (entry->queue->qid == QID_RX) { @@ -251,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); rt2x00_desc_write(entry_priv->desc, 1, word); + + /* + * Set RX IDX in register to inform hardware that we have + * handled this entry and it is available for reuse again. + */ + rt2800_register_write(rt2x00dev, RX_CRX_IDX, + entry->entry_idx); } else { rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); @@ -599,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue) static void rt2800pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *rxd = entry_priv->desc; u32 word; @@ -641,12 +648,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure that is at the start of the buffer. */ rt2800_process_rxwi(entry, rxdesc); - - /* - * Set RX IDX in register to inform hardware that we have handled - * this entry and it is available for reuse again. - */ - rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); } /* -- cgit v1.2.3 From cb753b7253548b950e84843a00b4db8d0c54f578 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:29:59 +0200 Subject: rt2x00: Allow tx duplication for legacy rates in HT40 mode Make use of the IEEE80211_TX_RC_DUP_DATA flag to duplicate a transmission with legacy rates to both 20Mhz channels if set. Also update the related comment in rt2800.h to describe the behavior of the BW_40 flag for legacy rates. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 3 ++- drivers/net/wireless/rt2x00/rt2x00ht.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index e1583cf5894b..9bf50a1c48d0 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1982,7 +1982,8 @@ struct mac_iveiv_entry { * FRAG: 1 To inform TKIP engine this is a fragment. * MIMO_PS: The remote peer is in dynamic MIMO-PS mode * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs - * BW: Channel bandwidth 20MHz or 40 MHz + * BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will + * duplicate the frame to both channels). * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will * aggregate consecutive frames with the same RA and QoS TID. diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 48b6ed426da5..2023419ce0bd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -85,7 +85,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, txdesc->rate_mode = RATE_MODE_HT_MIX; if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + + /* + * Set 40Mhz mode if necessary (for legacy rates this will + * duplicate the frame to both channels). + */ + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || + txrate->flags & IEEE80211_TX_RC_DUP_DATA) __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); -- cgit v1.2.3 From b1ef7252f491b6dc09ffc4584da0f3cf564e05e5 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 2 Oct 2010 11:30:19 +0200 Subject: rt2x00: Add rt73usb device ID Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index cc6a72b09f46..f78bc2a29328 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2365,6 +2365,7 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, /* CEIVA */ { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, /* CNet */ -- cgit v1.2.3 From d4ce3a5ea16f82d73922b7bfb8a177e371493ffb Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:30:42 +0200 Subject: rt2x00: Add register definition for busy time on secondary channel Add the register definition CH_BUSY_STA_SEC for reading the busy time on the secondary channel in HT40 mode. Also update the comments about channel busy/idle time registers to express the used unit. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9bf50a1c48d0..f02ea129680e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -747,15 +747,20 @@ #define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) /* - * CH_IDLE_STA: channel idle time + * CH_IDLE_STA: channel idle time (in us) */ #define CH_IDLE_STA 0x1130 /* - * CH_BUSY_STA: channel busy time + * CH_BUSY_STA: channel busy time on primary channel (in us) */ #define CH_BUSY_STA 0x1134 +/* + * CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us) + */ +#define CH_BUSY_STA_SEC 0x1138 + /* * MAC_STATUS_CFG: * BBP_RF_BUSY: When set to 0, BBP and RF are stable. -- cgit v1.2.3 From c4c18a9dc16095fc8ada423f1e6ff3830d56d37c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:31:05 +0200 Subject: rt2x00: add field definitions for the TBTT_SYNC_CFG register Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index f02ea129680e..4930d29e1377 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -710,8 +710,14 @@ /* * TBTT_SYNC_CFG: + * BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots + * BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots */ #define TBTT_SYNC_CFG 0x1118 +#define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff) +#define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00) +#define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000) +#define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000) /* * TSF_TIMER_DW0: Local lsb TSF timer, read-only -- cgit v1.2.3 From 5a5b6ed6ce46be128f2a5a9e56f47193c3ac3e32 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:31:33 +0200 Subject: rt2x00: Don't enable broad- and multicast buffering on USB devices Since rt2x00 USB devices have no chance to know when a beacon was sent out in AP mode currently all broad- and multicast traffic is buffered in mac80211 but never sent out at all. Unfortunately we have no chance in sending the traffic out after a DTIM beacon due to hw limitations. Hence, instead of never sending the buffered traffic out better send it out immediately. Signed-off-by: Helmut Schaa Reported-by: Lauri Hintsala Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 7 ++++++- drivers/net/wireless/rt2x00/rt2800lib.c | 11 ++++++++++- drivers/net/wireless/rt2x00/rt73usb.c | 7 ++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 5843a6d8b627..103396495065 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1674,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. + * + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are + * capable of sending the buffered frames out after the DTIM + * transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. */ rt2x00dev->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 76b8783c5639..99b505f8e717 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3164,11 +3164,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * Initialize all hw fields. */ rt2x00dev->hw->flags = - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_AMPDU_AGGREGATION; + /* + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices + * unless we are capable of sending the buffered frames out after the + * DTIM transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. + */ + if (!rt2x00_is_usb(rt2x00dev)) + rt2x00dev->hw->flags |= + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f78bc2a29328..66939fd8689d 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2063,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. + * + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are + * capable of sending the buffered frames out after the DTIM + * transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. */ rt2x00dev->hw->flags = - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK; -- cgit v1.2.3 From 78be49ec2a0df34de9441930fdced20311fd709f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:31:55 +0200 Subject: mac80211: distinct between max rates and the number of rates the hw can report Some drivers cannot handle multiple retry rates specified by the rc algorithm but instead use their own retry table (for example rt2800). However, if such a device registers itself with a max_rates value of 1 the rc algorithm cannot make use of the extended information the device can provide about retried rates. On the other hand, if a device registers itself with a max_rates value > 1 the rc algorithm assumes that the device can handle multi rate retries. Fix this issue by introducing another hw parameter max_report_rates that can be set to a different value then max_rates to indicate if a device is capable of reporting more rates then specified in max_rates. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- include/net/mac80211.h | 6 +++++- net/mac80211/main.c | 4 ++++ net/mac80211/status.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index fe8b9dae4dee..47316a653ae1 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1109,7 +1109,10 @@ enum ieee80211_hw_flags { * @sta_data_size: size (in bytes) of the drv_priv data area * within &struct ieee80211_sta. * - * @max_rates: maximum number of alternate rate retry stages + * @max_rates: maximum number of alternate rate retry stages the hw + * can handle. + * @max_report_rates: maximum number of alternate rate retry stages + * the hw can report back. * @max_rate_tries: maximum number of tries for each stage * * @napi_weight: weight used for NAPI polling. You must specify an @@ -1131,6 +1134,7 @@ struct ieee80211_hw { u16 max_listen_interval; s8 max_signal; u8 max_rates; + u8 max_report_rates; u8 max_rate_tries; }; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e127fbb8424e..9c2f3f934c74 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -537,6 +537,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, /* set up some defaults */ local->hw.queues = 1; local->hw.max_rates = 1; + local->hw.max_report_rates = 0; local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->user_power_level = -1; @@ -612,6 +613,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) WLAN_CIPHER_SUITE_AES_CMAC }; + if (hw->max_report_rates == 0) + hw->max_report_rates = hw->max_rates; + /* * generic code guarantees at least one band, * set this very early because much code assumes diff --git a/net/mac80211/status.c b/net/mac80211/status.c index dd85006c4fe8..95763e036975 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { /* the HW cannot have attempted that rate */ - if (i >= hw->max_rates) { + if (i >= hw->max_report_rates) { info->status.rates[i].idx = -1; info->status.rates[i].count = 0; } else if (info->status.rates[i].idx >= 0) { -- cgit v1.2.3 From ba3b9e5e8c7a12d8ea46cb4a8217c2e9b0720e9c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:32:16 +0200 Subject: rt2x00: correctly set max_report_rates in rt61pci and rt2800 rt61pci and rt2800 devices can use up to 7 different rates per tx frame. However, the device uses a global fallback table. Hence, the rc algortihm cannot specify multiple rates to try but the device is able to report multiple rates (based on the retry table). Specify that behavior by correctly setting max_report_rates and max_rates. This makes rt2x00 and minstrel play nicer together. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 5 +++-- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 99b505f8e717..403e2ed0f44f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3188,12 +3188,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * As rt2800 has a global fallback table we cannot specify * more then one tx rate per frame but since the hw will * try several rates (based on the fallback table) we should - * still initialize max_rates to the maximum number of rates + * initialize max_report_rates to the maximum number of rates * we are going to try. Otherwise mac80211 will truncate our * reported tx rates and the rc algortihm will end up with * incorrect data. */ - rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rates = 1; + rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 8940070fe2a2..ac370f11e74f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2630,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * As rt61 has a global fallback table we cannot specify * more then one tx rate per frame but since the hw will * try several rates (based on the fallback table) we should - * still initialize max_rates to the maximum number of rates + * initialize max_report_rates to the maximum number of rates * we are going to try. Otherwise mac80211 will truncate our * reported tx rates and the rc algortihm will end up with * incorrect data. */ - rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rates = 1; + rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; /* -- cgit v1.2.3 From bc8a979e2d85c2bdd507a8b6b09fdafc11ebd73a Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 2 Oct 2010 11:32:43 +0200 Subject: rt2x00: Improve TX status entry validation The TX_STA_FIFO contains some information for identifying a outgoing frame, however matching by WCID and ACK status is not sufficient to 100% identify the macthing queue_entry structure (containing the SKB buffer) which belongs to the status report. Within TX_STA_FIFO we have a 4-bit field named PACKETID, which is currently used to encode the queue id. The queue ID is however limited to values from 0 to 3, which means 2 bits are sufficient to encode the value. With the remaining 2 bits we can encode a partial queue_entry index number. The value of PACKETID is not allowed to become 0, with the queue ID ranging from 0 to 3, at least one of the bits for the entry identification must be 1. That leaves us with 3 possible values we can still encode in the bits. Altough this doesn't allow 100% accurate matching of the TX_STA_FIFO queue to a queue_entry structure, it at least improves the accuracy. This allows us to better detect if we have missed the TX_STA_FIFO report, which in turn reduces the number of watchdog warnings regarding the TX status timeout. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 14 +++++++++++++- drivers/net/wireless/rt2x00/rt2800lib.c | 5 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 4930d29e1377..2a9f4020af1e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2004 - 2010 Ivo van Doorn + Copyright (C) 2010 Willow Garage Copyright (C) 2009 Alban Browaeys Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Luis Correia @@ -1353,6 +1354,9 @@ * PID_TYPE: The PID latched from the PID field in the TXWI, can be used * to match a frame with its tx result (even though the PID is * only 4 bits wide). + * PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3) + * PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3) + * This identification number is calculated by ((idx % 3) + 1). * TX_SUCCESS: Indicates tx success (1) or failure (0) * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) @@ -1364,6 +1368,8 @@ #define TX_STA_FIFO 0x1718 #define TX_STA_FIFO_VALID FIELD32(0x00000001) #define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e) +#define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006) +#define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018) #define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020) #define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040) #define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080) @@ -2024,6 +2030,10 @@ struct mac_iveiv_entry { * frame was processed. If multiple frames are aggregated together * (AMPDU==1) the reported tx status will always contain the packet * id of the first frame. 0: Don't report tx status for this frame. + * PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3) + * PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3) + * This identification number is calculated by ((idx % 3) + 1). + * The (+1) is required to prevent PACKETID to become 0. */ #define TXWI_W1_ACK FIELD32(0x00000001) #define TXWI_W1_NSEQ FIELD32(0x00000002) @@ -2031,6 +2041,8 @@ struct mac_iveiv_entry { #define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00) #define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) #define TXWI_W1_PACKETID FIELD32(0xf0000000) +#define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000) +#define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000) /* * Word2 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 403e2ed0f44f..8e507d0b5789 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -483,7 +483,8 @@ void rt2800_write_tx_data(struct queue_entry *entry, txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); rt2x00_desc_write(txwi, 1, word); /* @@ -708,7 +709,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) * Skip this entry when it contains an invalid * queue identication number. */ - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); if (pid >= QID_RX) continue; -- cgit v1.2.3 From 58ed826e5fb6db429c688284623ca62cb45b9d5c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:33:17 +0200 Subject: rt2x00: Enable rx aggregation in rt2800 Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 8e507d0b5789..028715730b2c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3452,8 +3452,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, switch (action) { case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_STOP: - /* we don't support RX aggregation yet */ - ret = -ENOTSUPP; + /* + * The hw itself takes care of setting up BlockAck mechanisms. + * So, we only have to allow mac80211 to nagotiate a BlockAck + * agreement. Once that is done, the hw will BlockAck incoming + * AMPDUs without further setup. + */ break; case IEEE80211_AMPDU_TX_START: ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); -- cgit v1.2.3 From 74ee3802c0021c1387795af234b3e4dc511a9bb3 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:33:42 +0200 Subject: rt2x00: Update comment about the AMPDU flag in the TXWI During testing with AMPDUs it turned out that the rt2800 hw will aggregate consecutive frames with the same RA and TID when the first frame in a possible aggregate has set AMPDU=1 in the TXWI. If a following frame has set AMPDU=0 in its TXWI it might sill end up in the aggregate of the previous frame. Update the comment accordingly. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2a9f4020af1e..eb8b6cab9925 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2003,7 +2003,13 @@ struct mac_iveiv_entry { * duplicate the frame to both channels). * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will - * aggregate consecutive frames with the same RA and QoS TID. + * aggregate consecutive frames with the same RA and QoS TID. If + * a frame A with the same RA and QoS TID but AMPDU=0 is queued + * directly after a frame B with AMPDU=1, frame A might still + * get aggregated into the AMPDU started by frame B. So, setting + * AMPDU to 0 does _not_ necessarily mean the frame is sent as + * MPDU, it can still end up in an AMPDU if the previous frame + * was tagged as AMPDU. */ #define TXWI_W0_FRAG FIELD32(0x00000001) #define TXWI_W0_MIMO_PS FIELD32(0x00000002) -- cgit v1.2.3 From 1f0280cb35ae252d6db3ce8f56b7a1dc174460e5 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:34:05 +0200 Subject: rt2x00: Fix oops caused by error path in rt2x00lib_start When rt2x00lib_enable_radio fails to enable the radio, rt2x00lib_start will call rt2x00queue_uninitialize to uninitialize the queues. Since, the queues are not initialized here but already in rt2x00lib_initialize we shouldn't uninitialize the queues here. Otherwise, a consecutive call to rt2x00lib_start will oops (see below) because it assumes the queues are already initialized. BUG: unable to handle kernel NULL pointer dereference at 00000010 IP: [] :rt2800pci:rt2800pci_clear_entry+0x1/0x40 *pde = 00000000 Oops: 0000 [#1] SMP Modules linked in: ... rt2800pci ... Pid: 5995, comm: hostapd Not tainted (2.6.27.8 #1) EIP: 0060:[] EFLAGS: 00210246 CPU: 3 EIP is at rt2800pci_clear_entry+0x1/0x40 [rt2800pci] EAX: 00000000 EBX: f698863c ECX: 00200296 EDX: f8d2dee0 ESI: f6988600 EDI: f5b6f000 EBP: 00000000 ESP: f6d75e4c DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process hostapd (pid: 5995, ti=f6d74000 task=f6ce2300 task.ti=f6d74000) Stack: f698863c fa00eaec 00000000 f5b6f000 00000000 f7b67000 f5b6e280 fa00c629 f5b6f000 00000000 fa00ca3d f7b67480 00000001 fa177d4c 01b6e890 f7b67000 00000000 f7b67000 00000001 00001003 00001002 c066c366 f7b67000 c0668ad0 Call Trace: [] rt2x00queue_init_queues+0x5c/0x90 [rt2x00lib] [] rt2x00lib_enable_radio+0x29/0xa0 [rt2x00lib] [] rt2x00lib_start+0x5d/0xd0 [rt2x00lib] [] ieee80211_do_open+0x21c/0x510 [mac80211] [] dev_open+0x56/0xb0 [] dev_set_rx_mode+0x20/0x40 [] dev_change_flags+0x7f/0x190 [] devinet_ioctl+0x515/0x690 [] __dev_get_by_name+0x74/0x90 [] sock_ioctl+0xd0/0x240 [] sock_ioctl+0x0/0x240 [] vfs_ioctl+0x2b/0x90 [] do_vfs_ioctl+0x25b/0x2a0 [] sys_ioctl+0x56/0x70 [] syscall_call+0x7/0xb [] add_card+0xad0/0xba0 ======================= Code: 83 78 08 0e 74 14 8b 02 8b 48 04 85 c9 0f 99 c0 0f b6 c0 c3 8d b6 00 00 00 00 8b 02 8b 40 04 85 c0 0f 99 c0 0f b6 c0 c3 66 90 53 <8b> 48 10 8b 58 08 8b 40 04 83 78 08 0e 74 15 8b 11 83 c2 04 8b EIP: [] rt2800pci_clear_entry+0x1/0x40 [rt2800pci] SS:ESP 0068:f6d75e4c ---[ end trace cff9a5c094bb8837 ]--- Reported-by: Joshua Smith Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b03e6e41dc1e..6f442b02b83e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -933,10 +933,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) /* Enable the radio */ retval = rt2x00lib_enable_radio(rt2x00dev); - if (retval) { - rt2x00queue_uninitialize(rt2x00dev); + if (retval) return retval; - } set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); -- cgit v1.2.3 From 01e946f22ae4bafe370d263f2ef499b8b232aec1 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:34:26 +0200 Subject: rt2x00: Improve cooperation between rt2800pci and minstrel In order to lower the impact of probe rates don't send a frame as AMPDU if the rate control algorithm sets IEEE80211_TX_CTL_RATE_CTRL_PROBE. Otherwise a whole aggregate would be send with a probe rate which might lead to numerous retries. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 2023419ce0bd..c637bcaec5f8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -73,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, /* - * Convert flags + * This frame is eligible for an AMPDU, however, don't aggregate + * frames that are intended to probe a specific tx rate. */ - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && + !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); /* -- cgit v1.2.3 From b34793ee27aa547fc9b4213f89036c9a0ecaad5d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 2 Oct 2010 11:34:56 +0200 Subject: rt2x00: Work around hw aggregation oddity in rt2800 If a frame is not meant to be sent as AMPDU or part of it the hw might still decide to aggregate this frame if a previous frame started an AMPDU. However, this will limit the usefulness of the reported tx rate since the reported rate will be the one specified in the TXWI of the first frame and thus it is not possible to reliably caculate the number of retrys by substracting the reported tx rate from the tx rate in the TXWI. To fix this issue, only report the successful rate for frames that were not meant to be aggregated but ended up in an aggregate. Example: Frame A (MCS7, AMPDU=1) B (MCS7, AMPDU=1) C (MCS12, AMDPU=0, PROBE_RATE) Although frame C shoudn't be aggregated the hw might sill put it into an AMPDU together with A and B. If the transmission succeeds the tx status will contain MCS7 for all three frames. In that case we should only report MCS7 as success rate and avoid reporting MCS12-MCS8 as failed tx attempts as this will affect the future rate control decisions. This oddity might strike us in other scenarious as well but the most common "wrong" report happened for frames used to probe a different tx rate. This improves the rate control decisions notable. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 028715730b2c..7f040b0eac36 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -634,9 +634,11 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) void rt2800_txdone_entry(struct queue_entry *entry, u32 status) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); struct txdone_entry_desc txdesc; u32 word; u16 mcs, real_mcs; + int aggr, ampdu; __le32 *txwi; /* @@ -645,8 +647,33 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) txdesc.flags = 0; txwi = rt2800_drv_get_txwi(entry); rt2x00_desc_read(txwi, 0, &word); + mcs = rt2x00_get_field32(word, TXWI_W0_MCS); + ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU); + real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); + + /* + * If a frame was meant to be sent as a single non-aggregated MPDU + * but ended up in an aggregate the used tx rate doesn't correlate + * with the one specified in the TXWI as the whole aggregate is sent + * with the same rate. + * + * For example: two frames are sent to rt2x00, the first one sets + * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0 + * and requests MCS15. If the hw aggregates both frames into one + * AMDPU the tx status for both frames will contain MCS7 although + * the frame was sent successfully. + * + * Hence, replace the requested rate with the real tx rate to not + * confuse the rate control algortihm by providing clearly wrong + * data. + */ + if (aggr == 1 && ampdu == 0 && real_mcs != mcs) { + skbdesc->tx_rate_idx = real_mcs; + mcs = real_mcs; + } /* * Ralink has a retry mechanism using a global fallback -- cgit v1.2.3 From 9eba612549f575d7dccda672ce932e15e7392d83 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 4 Oct 2010 11:17:30 +0900 Subject: mac80211: Add WME information element for IBSS Enable WME QoS in IBSS mode by adding a WME information element to beacons and probe respones and by checking for it and marking stations as WME capable if it is present. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- net/mac80211/ibss.c | 65 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 1a3aae54f0cf..ff60c022f51d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, memcpy(skb_put(skb, ifibss->ie_len), ifibss->ie, ifibss->ie_len); + if (local->hw.queues >= 4) { + pos = skb_put(skb, 9); + *pos++ = WLAN_EID_VENDOR_SPECIFIC; + *pos++ = 7; /* len */ + *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ + *pos++ = 0x50; + *pos++ = 0xf2; + *pos++ = 2; /* WME */ + *pos++ = 0; /* WME info */ + *pos++ = 1; /* WME ver */ + *pos++ = 0; /* U-APSD no in use */ + } + rcu_assign_pointer(ifibss->presp, skb); sdata->vif.bss_conf.beacon_int = beacon_int; @@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) return; - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && + if (sdata->vif.type == NL80211_IFTYPE_ADHOC && memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { - supp_rates = ieee80211_sta_get_rates(local, elems, band); rcu_read_lock(); - sta = sta_info_get(sdata, mgmt->sa); - if (sta) { - u32 prev_rates; - prev_rates = sta->sta.supp_rates[band]; - /* make sure mandatory rates are always added */ - sta->sta.supp_rates[band] = supp_rates | - ieee80211_mandatory_rates(local, band); + if (elems->supp_rates) { + supp_rates = ieee80211_sta_get_rates(local, elems, + band); + if (sta) { + u32 prev_rates; - if (sta->sta.supp_rates[band] != prev_rates) { + prev_rates = sta->sta.supp_rates[band]; + /* make sure mandatory rates are always added */ + sta->sta.supp_rates[band] = supp_rates | + ieee80211_mandatory_rates(local, band); + + if (sta->sta.supp_rates[band] != prev_rates) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: updated supp_rates set " - "for %pM based on beacon/probe_response " - "(0x%x -> 0x%x)\n", - sdata->name, sta->sta.addr, - prev_rates, sta->sta.supp_rates[band]); + printk(KERN_DEBUG + "%s: updated supp_rates set " + "for %pM based on beacon" + "/probe_resp (0x%x -> 0x%x)\n", + sdata->name, sta->sta.addr, + prev_rates, + sta->sta.supp_rates[band]); #endif - rate_control_rate_init(sta); - } - rcu_read_unlock(); - } else { - rcu_read_unlock(); - ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, - supp_rates, GFP_KERNEL); + rate_control_rate_init(sta); + } + } else + sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, + mgmt->sa, supp_rates, + GFP_ATOMIC); } + + if (sta && elems->wmm_info) + set_sta_flags(sta, WLAN_STA_WME); + + rcu_read_unlock(); } bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, -- cgit v1.2.3 From 2ee4e27cf25ab647137713ca16377d8d9e138ea2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Oct 2010 14:31:46 +0200 Subject: ipw2200: check for allocation failures If kzalloc() fails then return should return with -ENOMEM. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2200.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index cb2552a6777c..d04d76082777 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11470,6 +11470,10 @@ static int ipw_net_init(struct net_device *dev) bg_band->channels = kzalloc(geo->bg_channels * sizeof(struct ieee80211_channel), GFP_KERNEL); + if (!bg_band->channels) { + rc = -ENOMEM; + goto out; + } /* translate geo->bg to bg_band.channels */ for (i = 0; i < geo->bg_channels; i++) { bg_band->channels[i].band = IEEE80211_BAND_2GHZ; @@ -11505,6 +11509,10 @@ static int ipw_net_init(struct net_device *dev) a_band->channels = kzalloc(geo->a_channels * sizeof(struct ieee80211_channel), GFP_KERNEL); + if (!a_band->channels) { + rc = -ENOMEM; + goto out; + } /* translate geo->bg to a_band.channels */ for (i = 0; i < geo->a_channels; i++) { a_band->channels[i].band = IEEE80211_BAND_2GHZ; -- cgit v1.2.3 From ff4c92d85c6f2777d2067f8552e7fefb4d1754ae Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 21:14:03 +0200 Subject: genetlink: introduce pre_doit/post_doit hooks Each family may have some amount of boilerplate locking code that applies to most, or even all, commands. This allows a family to handle such things in a more generic way, by allowing it to a) include private flags in each operation b) specify a pre_doit hook that is called, before an operation's doit() callback and may return an error directly, c) specify a post_doit hook that can undo locking or similar things done by pre_doit, and finally d) include two private pointers in each info struct passed between all these operations including doit(). (It's two because I'll need two in nl80211 -- can be extended.) Signed-off-by: Johannes Berg Acked-by: David S. Miller Signed-off-by: John W. Linville --- include/net/genetlink.h | 18 ++++++++++++++++++ net/netlink/genetlink.c | 14 +++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/net/genetlink.h b/include/net/genetlink.h index f7dcd2c70412..8a64b811a39a 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -20,6 +20,9 @@ struct genl_multicast_group { u32 id; }; +struct genl_ops; +struct genl_info; + /** * struct genl_family - generic netlink family * @id: protocol family idenfitier @@ -29,6 +32,10 @@ struct genl_multicast_group { * @maxattr: maximum number of attributes supported * @netnsok: set to true if the family can handle network * namespaces and should be presented in all of them + * @pre_doit: called before an operation's doit callback, it may + * do additional, common, filtering and return an error + * @post_doit: called after an operation's doit callback, it may + * undo operations done by pre_doit, for example release locks * @attrbuf: buffer to store parsed attributes * @ops_list: list of all assigned operations * @family_list: family list @@ -41,6 +48,12 @@ struct genl_family { unsigned int version; unsigned int maxattr; bool netnsok; + int (*pre_doit)(struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); + void (*post_doit)(struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); struct nlattr ** attrbuf; /* private */ struct list_head ops_list; /* private */ struct list_head family_list; /* private */ @@ -55,6 +68,8 @@ struct genl_family { * @genlhdr: generic netlink message header * @userhdr: user specific header * @attrs: netlink attributes + * @_net: network namespace + * @user_ptr: user pointers */ struct genl_info { u32 snd_seq; @@ -66,6 +81,7 @@ struct genl_info { #ifdef CONFIG_NET_NS struct net * _net; #endif + void * user_ptr[2]; }; static inline struct net *genl_info_net(struct genl_info *info) @@ -81,6 +97,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) /** * struct genl_ops - generic netlink operations * @cmd: command identifier + * @internal_flags: flags used by the family * @flags: flags * @policy: attribute validation policy * @doit: standard command callback @@ -90,6 +107,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) */ struct genl_ops { u8 cmd; + u8 internal_flags; unsigned int flags; const struct nla_policy *policy; int (*doit)(struct sk_buff *skb, diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 26ed3e8587c2..1781d99145e2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; info.attrs = family->attrbuf; genl_info_net_set(&info, net); + memset(&info.user_ptr, 0, sizeof(info.user_ptr)); - return ops->doit(skb, &info); + if (family->pre_doit) { + err = family->pre_doit(ops, skb, &info); + if (err) + return err; + } + + err = ops->doit(skb, &info); + + if (family->post_doit) + family->post_doit(ops, skb, &info); + + return err; } static void genl_rcv(struct sk_buff *skb) -- cgit v1.2.3 From 4c476991062a0a59523c2bf193f09087f469686a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 21:36:35 +0200 Subject: nl80211: use the new genetlink pre/post_doit hooks This makes nl80211 use the new genetlink pre_doit/post_doit hooks for locking and checking the interface/wiphy index. This significantly reduces the code size and the likelihood of locking errors. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 1737 +++++++++++++++--------------------------------- 1 file changed, 533 insertions(+), 1204 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index fd92b6b7ff04..a96da47d0640 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -23,6 +23,11 @@ #include "nl80211.h" #include "reg.h" +static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + /* the netlink family */ static struct genl_family nl80211_fam = { .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ @@ -31,6 +36,8 @@ static struct genl_family nl80211_fam = { .version = 1, /* no particular meaning now */ .maxattr = NL80211_ATTR_MAX, .netnsok = true, + .pre_doit = nl80211_pre_doit, + .post_doit = nl80211_post_doit, }; /* internal helper: get rdev and dev */ @@ -704,28 +711,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; - struct cfg80211_registered_device *dev; - - dev = cfg80211_get_dev_from_info(info); - if (IS_ERR(dev)) - return PTR_ERR(dev); + struct cfg80211_registered_device *dev = info->user_ptr[0]; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out_err; - - if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) - goto out_free; + return -ENOMEM; - cfg80211_unlock_rdev(dev); + if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } return genlmsg_reply(msg, info); - - out_free: - nlmsg_free(msg); - out_err: - cfg80211_unlock_rdev(dev); - return -ENOBUFS; } static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { @@ -814,24 +811,10 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *netdev; - int result; - - rtnl_lock(); - - result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); - if (result) - goto unlock_rtnl; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *netdev = info->user_ptr[1]; - result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); - - dev_put(netdev); - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); - - return result; + return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); } static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) @@ -893,8 +876,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) u32 frag_threshold = 0, rts_threshold = 0; u8 coverage_class = 0; - rtnl_lock(); - /* * Try to find the wiphy and netdev. Normally this * function shouldn't need the netdev, but this is @@ -921,8 +902,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) rdev = __cfg80211_rdev_from_info(info); if (IS_ERR(rdev)) { mutex_unlock(&cfg80211_mutex); - result = PTR_ERR(rdev); - goto unlock; + return PTR_ERR(rdev); } wdev = NULL; netdev = NULL; @@ -1104,8 +1084,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) mutex_unlock(&rdev->mtx); if (netdev) dev_put(netdev); - unlock: - rtnl_unlock(); return result; } @@ -1185,33 +1163,20 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; - struct cfg80211_registered_device *dev; - struct net_device *netdev; - int err; - - err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev); - if (err) - return err; + struct cfg80211_registered_device *dev = info->user_ptr[0]; + struct net_device *netdev = info->user_ptr[1]; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out_err; + return -ENOMEM; if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, - dev, netdev) < 0) - goto out_free; - - dev_put(netdev); - cfg80211_unlock_rdev(dev); + dev, netdev) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } return genlmsg_reply(msg, info); - - out_free: - nlmsg_free(msg); - out_err: - dev_put(netdev); - cfg80211_unlock_rdev(dev); - return -ENOBUFS; } static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { @@ -1271,39 +1236,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; int err; enum nl80211_iftype otype, ntype; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u32 _flags, *flags = NULL; bool change = false; memset(¶ms, 0, sizeof(params)); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - otype = ntype = dev->ieee80211_ptr->iftype; if (info->attrs[NL80211_ATTR_IFTYPE]) { ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); if (otype != ntype) change = true; - if (ntype > NL80211_IFTYPE_MAX) { - err = -EINVAL; - goto unlock; - } + if (ntype > NL80211_IFTYPE_MAX) + return -EINVAL; } if (info->attrs[NL80211_ATTR_MESH_ID]) { - if (ntype != NL80211_IFTYPE_MESH_POINT) { - err = -EINVAL; - goto unlock; - } + if (ntype != NL80211_IFTYPE_MESH_POINT) + return -EINVAL; params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); change = true; @@ -1314,20 +1269,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) change = true; err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); if (err) - goto unlock; + return err; } else { params.use_4addr = -1; } if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { - if (ntype != NL80211_IFTYPE_MONITOR) { - err = -EINVAL; - goto unlock; - } + if (ntype != NL80211_IFTYPE_MONITOR) + return -EINVAL; err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], &_flags); if (err) - goto unlock; + return err; flags = &_flags; change = true; @@ -1341,17 +1294,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (!err && params.use_4addr != -1) dev->ieee80211_ptr->use_4addr = params.use_4addr; - unlock: - dev_put(dev); - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; @@ -1368,19 +1316,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto unlock_rtnl; - } - if (!rdev->ops->add_virtual_intf || - !(rdev->wiphy.interface_modes & (1 << type))) { - err = -EOPNOTSUPP; - goto unlock; - } + !(rdev->wiphy.interface_modes & (1 << type))) + return -EOPNOTSUPP; if (type == NL80211_IFTYPE_MESH_POINT && info->attrs[NL80211_ATTR_MESH_ID]) { @@ -1392,7 +1330,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); if (err) - goto unlock; + return err; } err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? @@ -1402,38 +1340,18 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) nla_data(info->attrs[NL80211_ATTR_IFNAME]), type, err ? NULL : &flags, ¶ms); - unlock: - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->del_virtual_intf) { - err = -EOPNOTSUPP; - goto out; - } + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev); + if (!rdev->ops->del_virtual_intf) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); } struct get_key_cookie { @@ -1486,9 +1404,9 @@ static void get_key_callback(void *c, struct key_params *params) static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 key_idx = 0; u8 *mac_addr = NULL; struct get_key_cookie cookie = { @@ -1506,30 +1424,17 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->get_key) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_key) + return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_NEW_KEY); - - if (IS_ERR(hdr)) { - err = PTR_ERR(hdr); - goto free_msg; - } + if (IS_ERR(hdr)) + return PTR_ERR(hdr); cookie.msg = msg; cookie.idx = key_idx; @@ -1549,28 +1454,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) goto nla_put_failure; genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct key_parse key; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; int (*func)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -1585,21 +1483,13 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) if (!key.def && !key.defmgmt) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (key.def) func = rdev->ops->set_default_key; else func = rdev->ops->set_default_mgmt_key; - if (!func) { - err = -EOPNOTSUPP; - goto out; - } + if (!func) + return -EOPNOTSUPP; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); @@ -1616,21 +1506,14 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #endif wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct key_parse key; u8 *mac_addr = NULL; @@ -1644,21 +1527,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->add_key) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->add_key) + return -EOPNOTSUPP; - if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) { - err = -EINVAL; - goto out; - } + if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) + return -EINVAL; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); @@ -1667,20 +1540,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) mac_addr, &key.p); wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 *mac_addr = NULL; struct key_parse key; @@ -1691,16 +1558,8 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->del_key) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->del_key) + return -EOPNOTSUPP; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); @@ -1717,13 +1576,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) #endif wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - - unlock_rtnl: - rtnl_unlock(); - return err; } @@ -1731,36 +1583,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) { int (*call)(struct wiphy *wiphy, struct net_device *dev, struct beacon_parameters *info); - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct beacon_parameters params; int haveinfo = 0; if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; switch (info->genlhdr->cmd) { case NL80211_CMD_NEW_BEACON: /* these are required for NEW_BEACON */ if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || !info->attrs[NL80211_ATTR_DTIM_PERIOD] || - !info->attrs[NL80211_ATTR_BEACON_HEAD]) { - err = -EINVAL; - goto out; - } + !info->attrs[NL80211_ATTR_BEACON_HEAD]) + return -EINVAL; call = rdev->ops->add_beacon; break; @@ -1769,14 +1610,11 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) break; default: WARN_ON(1); - err = -EOPNOTSUPP; - goto out; + return -EOPNOTSUPP; } - if (!call) { - err = -EOPNOTSUPP; - goto out; - } + if (!call) + return -EOPNOTSUPP; memset(¶ms, 0, sizeof(params)); @@ -1806,53 +1644,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) haveinfo = 1; } - if (!haveinfo) { - err = -EINVAL; - goto out; - } - - err = call(&rdev->wiphy, dev, ¶ms); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); + if (!haveinfo) + return -EINVAL; - return err; + return call(&rdev->wiphy, dev, ¶ms); } static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - if (!rdev->ops->del_beacon) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->del_beacon) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EOPNOTSUPP; - goto out; - } - err = rdev->ops->del_beacon(&rdev->wiphy, dev); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_beacon(&rdev->wiphy, dev); } static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { @@ -2049,12 +1859,12 @@ static int nl80211_dump_station(struct sk_buff *skb, static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct station_info sinfo; struct sk_buff *msg; u8 *mac_addr = NULL; + int err; memset(&sinfo, 0, sizeof(sinfo)); @@ -2063,41 +1873,24 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); + if (!rdev->ops->get_station) + return -EOPNOTSUPP; - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); + err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); if (err) - goto out_rtnl; - - if (!rdev->ops->get_station) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); - if (err) - goto out; + return err; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out; + return -ENOMEM; if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, - dev, mac_addr, &sinfo) < 0) - goto out_free; - - err = genlmsg_reply(msg, info); - goto out; - - out_free: - nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev, mac_addr, &sinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } - return err; + return genlmsg_reply(msg, info); } /* @@ -2127,9 +1920,9 @@ static int get_vlan(struct genl_info *info, static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct station_parameters params; u8 *mac_addr = NULL; @@ -2167,12 +1960,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) params.plink_action = nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - err = get_vlan(info, rdev, ¶ms.vlan); if (err) goto out; @@ -2234,19 +2021,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) out: if (params.vlan) dev_put(params.vlan); - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); return err; } static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct station_parameters params; u8 *mac_addr = NULL; @@ -2283,18 +2066,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) if (parse_station_flags(info, ¶ms)) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EINVAL; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EINVAL; err = get_vlan(info, rdev, ¶ms.vlan); if (err) @@ -2318,52 +2093,28 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) out: if (params.vlan) dev_put(params.vlan); - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - return err; } static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *mac_addr = NULL; if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EINVAL; - goto out; - } - - if (!rdev->ops->del_station) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EINVAL; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev->ops->del_station) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); } static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, @@ -2490,9 +2241,9 @@ static int nl80211_dump_mpath(struct sk_buff *skb, static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct mpath_info pinfo; struct sk_buff *msg; u8 *dst = NULL; @@ -2505,53 +2256,33 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->get_mpath) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_mpath) + return -EOPNOTSUPP; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); if (err) - goto out; + return err; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out; + return -ENOMEM; if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, - dev, dst, next_hop, &pinfo) < 0) - goto out_free; - - err = genlmsg_reply(msg, info); - goto out; - - out_free: - nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev, dst, next_hop, &pinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } - return err; + return genlmsg_reply(msg, info); } static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; u8 *next_hop = NULL; @@ -2564,42 +2295,22 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->change_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!rdev->ops->change_mpath) + return -EOPNOTSUPP; - err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!netif_running(dev)) + return -ENETDOWN; - return err; + return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); } + static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; u8 *next_hop = NULL; @@ -2612,75 +2323,37 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->add_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!rdev->ops->add_mpath) + return -EOPNOTSUPP; - err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!netif_running(dev)) + return -ENETDOWN; - return err; + return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); } static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; if (info->attrs[NL80211_ATTR_MAC]) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->del_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev->ops->del_mpath) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_mpath(&rdev->wiphy, dev, dst); } static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct bss_parameters params; memset(¶ms, 0, sizeof(params)); @@ -2708,32 +2381,14 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_AP_ISOLATE]) params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->change_bss) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->change_bss) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; - return err; + return rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); } static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { @@ -2812,37 +2467,26 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) static int nl80211_get_mesh_params(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct mesh_config cur_params; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; void *hdr; struct nlattr *pinfoattr; struct sk_buff *msg; - rtnl_lock(); - - /* Look up our device */ - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->get_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_mesh_params) + return -EOPNOTSUPP; /* Get the mesh params */ err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); if (err) - goto out; + return err; /* Draw up a netlink message to send back */ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOBUFS; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_GET_MESH_PARAMS); if (!hdr) @@ -2881,22 +2525,13 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, cur_params.dot11MeshHWMPRootMode); nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: genlmsg_cancel(msg, hdr); nlmsg_free(msg); - err = -EMSGSIZE; - out: - /* Cleanup */ - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - - return err; -} + return -ENOBUFS; +} #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ do {\ @@ -2925,10 +2560,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) { - int err; u32 mask; - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct mesh_config cfg; struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; struct nlattr *parent_attr; @@ -2940,16 +2574,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) parent_attr, nl80211_meshconf_params_policy)) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->set_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->set_mesh_params) + return -EOPNOTSUPP; /* This makes sure that there aren't more than 32 mesh config * parameters (otherwise our bitfield scheme would not work.) */ @@ -2995,16 +2621,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) nla_get_u8); /* Apply changes */ - err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); - - out: - /* cleanup */ - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - - return err; + return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); } #undef FILL_IN_MESH_PARAM_IF_SET @@ -3187,8 +2804,8 @@ static int validate_scan_freqs(struct nlattr *freqs) static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_scan_request *request; struct cfg80211_ssid *ssid; struct ieee80211_channel *channel; @@ -3201,36 +2818,22 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - wiphy = &rdev->wiphy; - if (!rdev->ops->scan) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->scan) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; - if (rdev->scan_req) { - err = -EBUSY; - goto out; - } + if (rdev->scan_req) + return -EBUSY; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { n_channels = validate_scan_freqs( info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); - if (!n_channels) { - err = -EINVAL; - goto out; - } + if (!n_channels) + return -EINVAL; } else { n_channels = 0; @@ -3243,29 +2846,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) n_ssids++; - if (n_ssids > wiphy->max_scan_ssids) { - err = -EINVAL; - goto out; - } + if (n_ssids > wiphy->max_scan_ssids) + return -EINVAL; if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else ie_len = 0; - if (ie_len > wiphy->max_scan_ie_len) { - err = -EINVAL; - goto out; - } + if (ie_len > wiphy->max_scan_ie_len) + return -EINVAL; request = kzalloc(sizeof(*request) + sizeof(*ssid) * n_ssids + sizeof(channel) * n_channels + ie_len, GFP_KERNEL); - if (!request) { - err = -ENOMEM; - goto out; - } + if (!request) + return -ENOMEM; if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; @@ -3353,18 +2950,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!err) { nl80211_send_scan_start(rdev, dev); dev_hold(dev); - } - + } else { out_free: - if (err) { rdev->scan_req = NULL; kfree(request); } - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); return err; } @@ -3643,8 +3233,8 @@ static bool nl80211_valid_cipher_suite(u32 cipher) static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; const u8 *bssid, *ssid, *ie = NULL; int err, ssid_len, ie_len = 0; @@ -3686,12 +3276,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) key.p.key = NULL; } - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (key.idx >= 0) { int i; bool ok = false; @@ -3701,35 +3285,25 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) break; } } - if (!ok) { - err = -EINVAL; - goto out; - } + if (!ok) + return -EINVAL; } - if (!rdev->ops->auth) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->auth) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); - if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { - err = -EINVAL; - goto out; - } + if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) + return -EINVAL; ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); @@ -3740,24 +3314,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) } auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(auth_type)) { - err = -EINVAL; - goto out; - } + if (!nl80211_valid_auth_type(auth_type)) + return -EINVAL; local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, - ssid, ssid_len, ie, ie_len, - key.p.key, key.p.key_len, key.idx, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, + ssid, ssid_len, ie, ie_len, + key.p.key, key.p.key_len, key.idx, + local_state_change); } static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, @@ -3841,8 +3406,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_crypto_settings crypto; struct ieee80211_channel *chan; const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; @@ -3857,36 +3422,22 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) !info->attrs[NL80211_ATTR_WIPHY_FREQ]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->assoc) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->assoc) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); - if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { - err = -EINVAL; - goto out; - } + if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) + return -EINVAL; ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); @@ -3901,10 +3452,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); if (mfp == NL80211_MFP_REQUIRED) use_mfp = true; - else if (mfp != NL80211_MFP_NO) { - err = -EINVAL; - goto out; - } + else if (mfp != NL80211_MFP_NO) + return -EINVAL; } if (info->attrs[NL80211_ATTR_PREV_BSSID]) @@ -3916,20 +3465,15 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) ssid, ssid_len, ie, ie_len, use_mfp, &crypto); -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; const u8 *ie = NULL, *bssid; - int err, ie_len = 0; + int ie_len = 0; u16 reason_code; bool local_state_change; @@ -3942,35 +3486,22 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_REASON_CODE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->deauth) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->deauth) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); if (reason_code == 0) { /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; + return -EINVAL; } if (info->attrs[NL80211_ATTR_IE]) { @@ -3980,23 +3511,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, + local_state_change); } static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; const u8 *ie = NULL, *bssid; - int err, ie_len = 0; + int ie_len = 0; u16 reason_code; bool local_state_change; @@ -4009,35 +3533,22 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_REASON_CODE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->disassoc) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->disassoc) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); if (reason_code == 0) { /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; + return -EINVAL; } if (info->attrs[NL80211_ATTR_IE]) { @@ -4047,21 +3558,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, + local_state_change); } static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_ibss_params ibss; struct wiphy *wiphy; struct cfg80211_cached_keys *connkeys = NULL; @@ -4086,26 +3590,14 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->join_ibss) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->join_ibss) + return -EOPNOTSUPP; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; wiphy = &rdev->wiphy; @@ -4123,24 +3615,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); if (!ibss.channel || ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || - ibss.channel->flags & IEEE80211_CHAN_DISABLED) { - err = -EINVAL; - goto out; - } + ibss.channel->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; - if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { - connkeys = nl80211_parse_connkeys(rdev, - info->attrs[NL80211_ATTR_KEYS]); - if (IS_ERR(connkeys)) { - err = PTR_ERR(connkeys); - connkeys = NULL; - goto out; - } - } - if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); @@ -4150,10 +3630,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) wiphy->bands[ibss.channel->band]; int i, j; - if (n_rates == 0) { - err = -EINVAL; - goto out; - } + if (n_rates == 0) + return -EINVAL; for (i = 0; i < n_rates; i++) { int rate = (rates[i] & 0x7f) * 5; @@ -4166,60 +3644,39 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) break; } } - if (!found) { - err = -EINVAL; - goto out; - } + if (!found) + return -EINVAL; } } - err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); + if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { + connkeys = nl80211_parse_connkeys(rdev, + info->attrs[NL80211_ATTR_KEYS]); + if (IS_ERR(connkeys)) + return PTR_ERR(connkeys); + } -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: + err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); if (err) kfree(connkeys); - rtnl_unlock(); return err; } static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; - int err; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - if (!rdev->ops->leave_ibss) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->leave_ibss) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + return -EOPNOTSUPP; - err = cfg80211_leave_ibss(rdev, dev, false); + if (!netif_running(dev)) + return -ENETDOWN; -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_leave_ibss(rdev, dev, false); } #ifdef CONFIG_NL80211_TESTMODE @@ -4229,20 +3686,12 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = { static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; if (!info->attrs[NL80211_ATTR_TESTDATA]) return -EINVAL; - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto unlock_rtnl; - } - err = -EOPNOTSUPP; if (rdev->ops->testmode_cmd) { rdev->testmode_info = info; @@ -4252,10 +3701,6 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) rdev->testmode_info = NULL; } - cfg80211_unlock_rdev(rdev); - - unlock_rtnl: - rtnl_unlock(); return err; } @@ -4346,8 +3791,8 @@ EXPORT_SYMBOL(cfg80211_testmode_event); static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_connect_params connect; struct wiphy *wiphy; struct cfg80211_cached_keys *connkeys = NULL; @@ -4376,22 +3821,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) NL80211_MAX_NR_CIPHER_SUITES); if (err) return err; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; wiphy = &rdev->wiphy; @@ -4410,39 +3846,27 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) ieee80211_get_channel(wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); if (!connect.channel || - connect.channel->flags & IEEE80211_CHAN_DISABLED) { - err = -EINVAL; - goto out; - } + connect.channel->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; } if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { connkeys = nl80211_parse_connkeys(rdev, info->attrs[NL80211_ATTR_KEYS]); - if (IS_ERR(connkeys)) { - err = PTR_ERR(connkeys); - connkeys = NULL; - goto out; - } + if (IS_ERR(connkeys)) + return PTR_ERR(connkeys); } err = cfg80211_connect(rdev, dev, &connect, connkeys); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: if (err) kfree(connkeys); - rtnl_unlock(); return err; } static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; - int err; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u16 reason; if (!info->attrs[NL80211_ATTR_REASON_CODE]) @@ -4453,36 +3877,19 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) if (reason == 0) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - err = cfg80211_disconnect(rdev, dev, reason, true); + if (!netif_running(dev)) + return -ENETDOWN; -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_disconnect(rdev, dev, reason, true); } static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net *net; int err; u32 pid; @@ -4492,43 +3899,26 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto out_rtnl; - } - net = get_net_ns_by_pid(pid); - if (IS_ERR(net)) { - err = PTR_ERR(net); - goto out; - } + if (IS_ERR(net)) + return PTR_ERR(net); err = 0; /* check if anything to do */ - if (net_eq(wiphy_net(&rdev->wiphy), net)) - goto out_put_net; + if (!net_eq(wiphy_net(&rdev->wiphy), net)) + err = cfg80211_switch_netns(rdev, net); - err = cfg80211_switch_netns(rdev, net); - out_put_net: put_net(net); - out: - cfg80211_unlock_rdev(rdev); - out_rtnl: - rtnl_unlock(); return err; } static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa) = NULL; - int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_pmksa pmksa; memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); @@ -4539,20 +3929,12 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_PMKID]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; switch (info->genlhdr->cmd) { case NL80211_CMD_SET_PMKSA: @@ -4566,62 +3948,32 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) break; } - if (!rdev_ops) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev_ops(&rdev->wiphy, dev, &pmksa); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev_ops) + return -EOPNOTSUPP; - return err; + return rdev_ops(&rdev->wiphy, dev, &pmksa); } static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!rdev->ops->flush_pmksa) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->flush_pmksa(&rdev->wiphy, dev); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - return err; + if (!rdev->ops->flush_pmksa) + return -EOPNOTSUPP; + return rdev->ops->flush_pmksa(&rdev->wiphy, dev); } static int nl80211_remain_on_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; struct sk_buff *msg; void *hdr; @@ -4643,21 +3995,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, if (!duration || !msecs_to_jiffies(duration) || duration > 5000) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->remain_on_channel) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->remain_on_channel) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( @@ -4665,24 +4007,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, if (channel_type != NL80211_CHAN_NO_HT && channel_type != NL80211_CHAN_HT20 && channel_type != NL80211_CHAN_HT40PLUS && - channel_type != NL80211_CHAN_HT40MINUS) { - err = -EINVAL; - goto out; - } + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); - if (chan == NULL) { - err = -EINVAL; - goto out; - } + if (chan == NULL) + return -EINVAL; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_REMAIN_ON_CHANNEL); @@ -4701,58 +4037,35 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u64 cookie; - int err; if (!info->attrs[NL80211_ATTR_COOKIE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->cancel_remain_on_channel) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->cancel_remain_on_channel) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); - err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); } static u32 rateset_to_mask(struct ieee80211_supported_band *sband, @@ -4788,26 +4101,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, struct genl_info *info) { struct nlattr *tb[NL80211_TXRATE_MAX + 1]; - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_bitrate_mask mask; - int err, rem, i; - struct net_device *dev; + int rem, i; + struct net_device *dev = info->user_ptr[1]; struct nlattr *tx_rates; struct ieee80211_supported_band *sband; if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->set_bitrate_mask) { - err = -EOPNOTSUPP; - goto unlock; - } + if (!rdev->ops->set_bitrate_mask) + return -EOPNOTSUPP; memset(&mask, 0, sizeof(mask)); /* Default to all rates enabled */ @@ -4824,15 +4129,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) { enum ieee80211_band band = nla_type(tx_rates); - if (band < 0 || band >= IEEE80211_NUM_BANDS) { - err = -EINVAL; - goto unlock; - } + if (band < 0 || band >= IEEE80211_NUM_BANDS) + return -EINVAL; sband = rdev->wiphy.bands[band]; - if (sband == NULL) { - err = -EINVAL; - goto unlock; - } + if (sband == NULL) + return -EINVAL; nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), nla_len(tx_rates), nl80211_txattr_policy); if (tb[NL80211_TXRATE_LEGACY]) { @@ -4840,29 +4141,19 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, sband, nla_data(tb[NL80211_TXRATE_LEGACY]), nla_len(tb[NL80211_TXRATE_LEGACY])); - if (mask.control[band].legacy == 0) { - err = -EINVAL; - goto unlock; - } + if (mask.control[band].legacy == 0) + return -EINVAL; } } - err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); - - unlock: - dev_put(dev); - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); } static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; - int err; if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) return -EINVAL; @@ -4870,44 +4161,28 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_FRAME_TYPE]) frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; /* not much point in registering if we can't reply */ - if (!rdev->ops->mgmt_tx) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->mgmt_tx) + return -EOPNOTSUPP; - err = cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, + return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, frame_type, nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; bool channel_type_valid = false; @@ -4921,31 +4196,19 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) !info->attrs[NL80211_ATTR_WIPHY_FREQ]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->mgmt_tx) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->mgmt_tx) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!netif_running(dev)) + return -ENETDOWN; if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( @@ -4953,25 +4216,19 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) if (channel_type != NL80211_CHAN_NO_HT && channel_type != NL80211_CHAN_HT20 && channel_type != NL80211_CHAN_HT40PLUS && - channel_type != NL80211_CHAN_HT40MINUS) { - err = -EINVAL; - goto out; - } + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; channel_type_valid = true; } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); - if (chan == NULL) { - err = -EINVAL; - goto out; - } + if (chan == NULL) + return -EINVAL; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_FRAME); @@ -4991,110 +4248,72 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct wireless_dev *wdev; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 ps_state; bool state; int err; - if (!info->attrs[NL80211_ATTR_PS_STATE]) { - err = -EINVAL; - goto out; - } + if (!info->attrs[NL80211_ATTR_PS_STATE]) + return -EINVAL; ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); - if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) { - err = -EINVAL; - goto out; - } - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) + return -EINVAL; wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_power_mgmt) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } + if (!rdev->ops->set_power_mgmt) + return -EOPNOTSUPP; state = (ps_state == NL80211_PS_ENABLED) ? true : false; if (state == wdev->ps) - goto unlock_rdev; - - wdev->ps = state; - - if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps, - wdev->ps_timeout)) - /* assume this means it's off */ - wdev->ps = false; - -unlock_rdev: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); + return 0; -out: + err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state, + wdev->ps_timeout); + if (!err) + wdev->ps = state; return err; } static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; enum nl80211_ps_state ps_state; struct wireless_dev *wdev; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct sk_buff *msg; void *hdr; int err; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_power_mgmt) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->set_power_mgmt) + return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_GET_POWER_SAVE); if (!hdr) { - err = -ENOMEM; + err = -ENOBUFS; goto free_msg; } @@ -5106,22 +4325,12 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); -nla_put_failure: + nla_put_failure: err = -ENOBUFS; - -free_msg: + free_msg: nlmsg_free(msg); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - -unlock_rtnl: - rtnl_unlock(); - return err; } @@ -5135,43 +4344,24 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = { static int nl80211_set_cqm_rssi(struct genl_info *info, s32 threshold, u32 hysteresis) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct wireless_dev *wdev; - struct net_device *dev; - int err; + struct net_device *dev = info->user_ptr[1]; if (threshold > 0) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_cqm_rssi_config) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } + if (!rdev->ops->set_cqm_rssi_config) + return -EOPNOTSUPP; if (wdev->iftype != NL80211_IFTYPE_STATION && - wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } - - err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, - threshold, hysteresis); - - unlock_rdev: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - return err; + return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, + threshold, hysteresis); } static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) @@ -5205,6 +4395,54 @@ out: return err; } +#define NL80211_FLAG_NEED_WIPHY 0x01 +#define NL80211_FLAG_NEED_NETDEV 0x02 +#define NL80211_FLAG_NEED_RTNL 0x04 + +static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + struct net_device *dev; + int err; + bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; + + if (rtnl) + rtnl_lock(); + + if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { + rdev = cfg80211_get_dev_from_info(info); + if (IS_ERR(rdev)) { + if (rtnl) + rtnl_unlock(); + return PTR_ERR(rdev); + } + info->user_ptr[0] = rdev; + } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); + if (err) { + if (rtnl) + rtnl_unlock(); + return err; + } + info->user_ptr[0] = rdev; + info->user_ptr[1] = dev; + } + + return 0; +} + +static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + if (info->user_ptr[0]) + cfg80211_unlock_rdev(info->user_ptr[0]); + if (info->user_ptr[1]) + dev_put(info->user_ptr[1]); + if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) + rtnl_unlock(); +} + static struct genl_ops nl80211_ops[] = { { .cmd = NL80211_CMD_GET_WIPHY, @@ -5212,12 +4450,14 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_wiphy, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_WIPHY, }, { .cmd = NL80211_CMD_SET_WIPHY, .doit = nl80211_set_wiphy, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_INTERFACE, @@ -5225,90 +4465,119 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_interface, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV, }, { .cmd = NL80211_CMD_SET_INTERFACE, .doit = nl80211_set_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_INTERFACE, .doit = nl80211_new_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_INTERFACE, .doit = nl80211_del_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_KEY, .doit = nl80211_get_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_KEY, .doit = nl80211_set_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_KEY, .doit = nl80211_new_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_KEY, .doit = nl80211_del_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_addset_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_addset_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_del_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_STATION, .doit = nl80211_get_station, .dumpit = nl80211_dump_station, .policy = nl80211_policy, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_STATION, .doit = nl80211_set_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_STATION, .doit = nl80211_new_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_STATION, .doit = nl80211_del_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_MPATH, @@ -5316,30 +4585,40 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_MPATH, .doit = nl80211_set_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_MPATH, .doit = nl80211_new_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_MPATH, .doit = nl80211_del_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_BSS, .doit = nl80211_set_bss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_REG, @@ -5364,18 +4643,24 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_mesh_params, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_MESH_PARAMS, .doit = nl80211_set_mesh_params, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_TRIGGER_SCAN, .doit = nl80211_trigger_scan, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_SCAN, @@ -5387,36 +4672,48 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_authenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_ASSOCIATE, .doit = nl80211_associate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEAUTHENTICATE, .doit = nl80211_deauthenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DISASSOCIATE, .doit = nl80211_disassociate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_JOIN_IBSS, .doit = nl80211_join_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_LEAVE_IBSS, .doit = nl80211_leave_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, #ifdef CONFIG_NL80211_TESTMODE { @@ -5424,6 +4721,8 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_testmode_do, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, #endif { @@ -5431,18 +4730,24 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_connect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DISCONNECT, .doit = nl80211_disconnect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_WIPHY_NETNS, .doit = nl80211_wiphy_netns, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_SURVEY, @@ -5454,72 +4759,96 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_PMKSA, .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_FLUSH_PMKSA, .doit = nl80211_flush_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, .doit = nl80211_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, .doit = nl80211_cancel_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, .doit = nl80211_set_tx_bitrate_mask, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_REGISTER_FRAME, .doit = nl80211_register_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_FRAME, .doit = nl80211_tx_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_POWER_SAVE, .doit = nl80211_set_power_save, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_POWER_SAVE, .doit = nl80211_get_power_save, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_CQM, .doit = nl80211_set_cqm, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_CHANNEL, .doit = nl80211_set_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_WDS_PEER, -- cgit v1.2.3 From 41265714810e20d91ddd7aaca30043b0f12190ad Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 21:14:05 +0200 Subject: nl80211: use generic check for netif_running Use a new flag that requires the netdev to be UP and use it to check instead of coding the check into all functions that require it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 97 +++++++++++++++----------------------------------- 1 file changed, 28 insertions(+), 69 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a96da47d0640..ca8d04cb172f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -411,9 +411,6 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) { ASSERT_WDEV_LOCK(wdev); - if (!netif_running(wdev->netdev)) - return -ENETDOWN; - switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: @@ -2083,11 +2080,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, ¶ms); out: @@ -2301,9 +2293,6 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); } @@ -2329,9 +2318,6 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); } @@ -2823,9 +2809,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->scan) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - if (rdev->scan_req) return -EBUSY; @@ -3296,9 +3279,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); @@ -3429,9 +3409,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, @@ -3493,9 +3470,6 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); @@ -3540,9 +3514,6 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); @@ -3596,9 +3567,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - wiphy = &rdev->wiphy; if (info->attrs[NL80211_ATTR_MAC]) @@ -3673,9 +3641,6 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - return cfg80211_leave_ibss(rdev, dev, false); } @@ -3826,9 +3791,6 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - wiphy = &rdev->wiphy; if (info->attrs[NL80211_ATTR_MAC]) @@ -3881,9 +3843,6 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - return cfg80211_disconnect(rdev, dev, reason, true); } @@ -3998,9 +3957,6 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, if (!rdev->ops->remain_on_channel) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); @@ -4060,9 +4016,6 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, if (!rdev->ops->cancel_remain_on_channel) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); @@ -4207,9 +4160,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; - if (!netif_running(dev)) - return -ENETDOWN; - if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); @@ -4398,6 +4348,9 @@ out: #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 +#define NL80211_FLAG_CHECK_NETDEV_UP 0x08 +#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ + NL80211_FLAG_CHECK_NETDEV_UP) static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info) @@ -4425,6 +4378,12 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, rtnl_unlock(); return err; } + if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && + !netif_running(dev)) { + if (rtnl) + rtnl_unlock(); + return -ENETDOWN; + } info->user_ptr[0] = rdev; info->user_ptr[1] = dev; } @@ -4504,7 +4463,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4512,7 +4471,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_new_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4520,7 +4479,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_del_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4568,7 +4527,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_new_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4585,7 +4544,7 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4593,7 +4552,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4601,7 +4560,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_new_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4659,7 +4618,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_trigger_scan, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4672,7 +4631,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_authenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4680,7 +4639,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_associate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4688,7 +4647,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_deauthenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4696,7 +4655,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_disassociate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4704,7 +4663,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_join_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4712,7 +4671,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_leave_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, #ifdef CONFIG_NL80211_TESTMODE @@ -4730,7 +4689,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_connect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4738,7 +4697,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_disconnect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4783,7 +4742,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4791,7 +4750,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_cancel_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { @@ -4815,7 +4774,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_tx_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, { -- cgit v1.2.3 From 6774889314ba507483e63c014fcb81adfc127202 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 21:14:06 +0200 Subject: nl80211: reduce dumping boilerplate Consolidate boilerplate code needed for .dumpit calls operating on netdevs. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 151 +++++++++++++++++++------------------------------ 1 file changed, 59 insertions(+), 92 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ca8d04cb172f..0c9497170f1f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -198,6 +198,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb) return res; } +static int nl80211_prepare_netdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, + struct net_device **dev) +{ + int ifidx = cb->args[0]; + int err; + + if (!ifidx) + ifidx = nl80211_get_ifidx(cb); + if (ifidx < 0) + return ifidx; + + cb->args[0] = ifidx; + + rtnl_lock(); + + *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); + if (!*dev) { + err = -ENODEV; + goto out_rtnl; + } + + *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_rtnl; + } + + return 0; + out_rtnl: + rtnl_unlock(); + return err; +} + +static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) +{ + cfg80211_unlock_rdev(rdev); + rtnl_unlock(); +} + /* IE validation */ static bool is_valid_ie_attr(const struct nlattr *attr) { @@ -1796,28 +1837,12 @@ static int nl80211_dump_station(struct sk_buff *skb, struct cfg80211_registered_device *dev; struct net_device *netdev; u8 mac_addr[ETH_ALEN]; - int ifidx = cb->args[0]; int sta_idx = cb->args[1]; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - err = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - err = PTR_ERR(dev); - goto out_rtnl; - } + err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (err) + return err; if (!dev->ops->dump_station) { err = -EOPNOTSUPP; @@ -1847,9 +1872,7 @@ static int nl80211_dump_station(struct sk_buff *skb, cb->args[1] = sta_idx; err = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); + nl80211_finish_netdev_dump(dev); return err; } @@ -2169,28 +2192,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb, struct net_device *netdev; u8 dst[ETH_ALEN]; u8 next_hop[ETH_ALEN]; - int ifidx = cb->args[0]; int path_idx = cb->args[1]; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - err = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - err = PTR_ERR(dev); - goto out_rtnl; - } + err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (err) + return err; if (!dev->ops->dump_mpath) { err = -EOPNOTSUPP; @@ -2224,10 +2231,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, cb->args[1] = path_idx; err = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); - + nl80211_finish_netdev_dump(dev); return err; } @@ -3034,25 +3038,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct net_device *dev; struct cfg80211_internal_bss *scan; struct wireless_dev *wdev; - int ifidx = cb->args[0]; int start = cb->args[1], idx = 0; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - cb->args[0] = ifidx; - - dev = dev_get_by_index(sock_net(skb->sk), ifidx); - if (!dev) - return -ENODEV; - - rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto out_put_netdev; - } + err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); + if (err) + return err; wdev = dev->ieee80211_ptr; @@ -3068,21 +3059,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, cb->nlh->nlmsg_seq, NLM_F_MULTI, rdev, wdev, scan) < 0) { idx--; - goto out; + break; } } - out: spin_unlock_bh(&rdev->bss_lock); wdev_unlock(wdev); cb->args[1] = idx; - err = skb->len; - cfg80211_unlock_rdev(rdev); - out_put_netdev: - dev_put(dev); + nl80211_finish_netdev_dump(rdev); - return err; + return skb->len; } static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, @@ -3130,29 +3117,12 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct survey_info survey; struct cfg80211_registered_device *dev; struct net_device *netdev; - int ifidx = cb->args[0]; int survey_idx = cb->args[1]; int res; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - cb->args[0] = ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - res = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - res = PTR_ERR(dev); - goto out_rtnl; - } + res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (res) + return res; if (!dev->ops->dump_survey) { res = -EOPNOTSUPP; @@ -3180,10 +3150,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, cb->args[1] = survey_idx; res = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); - + nl80211_finish_netdev_dump(dev); return res; } -- cgit v1.2.3 From 025e6be220e448c02045e8499c7db8ce4bc8eea2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Oct 2010 10:41:47 +0200 Subject: mac80211: fix deadlock with multiple interfaces The locking around ieee80211_recalc_smps is buggy -- it cannot acquire another interface's mutex while the iflist mutex is held because another code path could be holding the iface mutex and trying to acquire the iflist mutex. But the locking is also unnecessary, we only check "ifmgd->associated" as a bool, and don't use the pointer (in check_mgd_smps). Reported-by: Ben Greear Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 2 +- net/mac80211/ieee80211_i.h | 3 +-- net/mac80211/main.c | 2 +- net/mac80211/mlme.c | 2 +- net/mac80211/util.c | 20 +++----------------- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a7a78f28ff6f..94bf550bd4c9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1394,7 +1394,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, if (!sdata->u.mgd.associated || sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_smps(sdata->local, sdata); + ieee80211_recalc_smps(sdata->local); mutex_unlock(&sdata->local->iflist_mtx); return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 55d79db985fc..08509e212841 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1297,8 +1297,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, enum ieee80211_band band); int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps_mode); -void ieee80211_recalc_smps(struct ieee80211_local *local, - struct ieee80211_sub_if_data *forsdata); +void ieee80211_recalc_smps(struct ieee80211_local *local); size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9c2f3f934c74..e3717092115f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -333,7 +333,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) container_of(work, struct ieee80211_local, recalc_smps); mutex_lock(&local->iflist_mtx); - ieee80211_recalc_smps(local, NULL); + ieee80211_recalc_smps(local); mutex_unlock(&local->iflist_mtx); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c37086a12f51..2b2982782bcd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -913,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, mutex_lock(&local->iflist_mtx); ieee80211_recalc_ps(local, -1); - ieee80211_recalc_smps(local, sdata); + ieee80211_recalc_smps(local); mutex_unlock(&local->iflist_mtx); netif_tx_start_all_queues(sdata->dev); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aba025d748e9..4ee8f2b53cb7 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1297,16 +1297,12 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, } /* must hold iflist_mtx */ -void ieee80211_recalc_smps(struct ieee80211_local *local, - struct ieee80211_sub_if_data *forsdata) +void ieee80211_recalc_smps(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; int count = 0; - if (forsdata) - lockdep_assert_held(&forsdata->u.mgd.mtx); - lockdep_assert_held(&local->iflist_mtx); /* @@ -1324,18 +1320,8 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, continue; if (sdata->vif.type != NL80211_IFTYPE_STATION) goto set; - if (sdata != forsdata) { - /* - * This nested is ok -- we are holding the iflist_mtx - * so can't get here twice or so. But it's required - * since normally we acquire it first and then the - * iflist_mtx. - */ - mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); - count += check_mgd_smps(&sdata->u.mgd, &smps_mode); - mutex_unlock(&sdata->u.mgd.mtx); - } else - count += check_mgd_smps(&sdata->u.mgd, &smps_mode); + + count += check_mgd_smps(&sdata->u.mgd, &smps_mode); if (count > 1) { smps_mode = IEEE80211_SMPS_OFF; -- cgit v1.2.3 From 4198a8d036c998ca8cec1b08116ab9f6a3a9ffff Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 5 Oct 2010 13:27:17 +0900 Subject: ath5k: Don't wake internal queues We should only wake up queues which mac80211 knows about (queues 0-3). We have another internal queue ("CAB", queue number 6) which we use for power-saved frames. When transmitted frames are processed from this queue, we have to make sure we don't bother mac80211 with waking a queue it doesn't know about. this fixes: WARNING: at /home/br1/ath/wireless-testing/net/mac80211/util.c:275 __ieee80211_wake_queue+0xd6/0xe0 [mac80211]() Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d914a31cb0b6..dad726585637 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1711,7 +1711,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) } } spin_unlock(&txq->lock); - if (txq->txq_len < ATH5K_TXQ_LEN_LOW) + if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4) ieee80211_wake_queue(sc->hw, txq->qnum); } -- cgit v1.2.3 From 970bf9d40c03e48cc34ee2c1a70693a0e0fca3f6 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 5 Oct 2010 11:32:17 +0200 Subject: ath9k: get correct tx gain type in ath9k_hw_4k_get_eeprom The base_eep_header_4k structure contains information that the device supports high power tx gain table or not. However the ath9k_hw_4k_get_eeprom function does not return that value when it is called with EEP_TXGAIN_TYPE. This leads to that the tx gain initialization will use the init values from the original tx gain table even if the device inidicates that the high power table should be used. Changes-licensed-under: ISC Signed-off-by: Gabor Juhos Signed-off-by: Shu Hwa Shen Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index d6eed1f02e84..872e75b0b574 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -179,6 +179,9 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; struct modal_eep_4k_header *pModal = &eep->modalHeader; struct base_eep_header_4k *pBase = &eep->baseEepHeader; + u16 ver_minor; + + ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK; switch (param) { case EEP_NFTHRESH_2: @@ -204,7 +207,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, case EEP_DB_2: return pModal->db1_1; case EEP_MINOR_REV: - return pBase->version & AR5416_EEP_VER_MINOR_MASK; + return ver_minor; case EEP_TX_MASK: return pBase->txMask; case EEP_RX_MASK: @@ -217,6 +220,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, return pModal->version; case EEP_ANT_DIV_CTL1: return pModal->antdiv_ctl1; + case EEP_TXGAIN_TYPE: + if (ver_minor >= AR5416_EEP_MINOR_VER_19) + return pBase->txGainType; + else + return AR5416_EEP_TXGAIN_ORIGINAL; default: return 0; } -- cgit v1.2.3 From 691895e7e2204be9a717809fb78d6ff7c10b470a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Oct 2010 16:19:42 +0200 Subject: nl80211: fix remain-on-channel documentation The documentation for NL80211_CMD_REMAIN_ON_CHANNEL isn't accurate, an interface index is required by the command. Update it accordingly. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 73d9390d4ddb..c4efdfa24ed8 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -315,8 +315,8 @@ * channel for the specified amount of time. This can be used to do * off-channel operations like transmit a Public Action frame and wait for * a response while being associated to an AP on another channel. - * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify which - * radio is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the + * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus + * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be * optionally used to specify additional channel parameters. * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds -- cgit v1.2.3 From e7480bbb926c5816e4fbfca70748096bbe0e4978 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 1 Oct 2010 17:05:19 -0400 Subject: mac80211: fix channel assumption for association done work Be consistent and use the wk->chan instead of the local->hw.conf.channel for the association done work. This prevents any possible races against channel changes while we run this work. In the case that the race did happen we would be initializing the bit rates for the new AP under the assumption of a wrong channel and in the worst case, wrong band. This could lead to trying to assuming we could use CCK frames on 5 GHz, for example. This patch has a fix for kernels >= v2.6.34 Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2b2982782bcd..cd13aa82f835 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1291,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, rates = 0; basic_rates = 0; - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + sband = local->hw.wiphy->bands[wk->chan->band]; for (i = 0; i < elems.supp_rates_len; i++) { int rate = (elems.supp_rates[i] & 0x7f) * 5; @@ -1327,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, } } - sta->sta.supp_rates[local->hw.conf.channel->band] = rates; + sta->sta.supp_rates[wk->chan->band] = rates; sdata->vif.bss_conf.basic_rates = basic_rates; /* cf. IEEE 802.11 9.2.12 */ - if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && + if (wk->chan->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit) sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; else -- cgit v1.2.3 From caf586e5f23cebb2a68cbaf288d59dbbf2d74052 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 30 Sep 2010 21:06:55 +0000 Subject: net: add a core netdev->rx_dropped counter In various situations, a device provides a packet to our stack and we drop it before it enters protocol stack : - softnet backlog full (accounted in /proc/net/softnet_stat) - bad vlan tag (not accounted) - unknown/unregistered protocol (not accounted) We can handle a per-device counter of such dropped frames at core level, and automatically adds it to the device provided stats (rx_dropped), so that standard tools can be used (ifconfig, ip link, cat /proc/net/dev) This is a generalization of commit 8990f468a (net: rx_dropped accounting), thus reverting it. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/loopback.c | 8 +------- include/linux/netdevice.h | 3 +++ net/8021q/vlan.h | 2 -- net/8021q/vlan_core.c | 2 ++ net/8021q/vlan_dev.c | 11 ++++------- net/core/dev.c | 19 +++++++++++-------- net/ipv4/ip_gre.c | 3 +-- net/ipv4/ipip.c | 3 +-- net/ipv6/ip6_tunnel.c | 3 +-- net/ipv6/ip6mr.c | 3 +-- net/ipv6/sit.c | 3 +-- 11 files changed, 26 insertions(+), 34 deletions(-) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 4b0e30b564e5..2d9663a1c54d 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -64,7 +64,6 @@ struct pcpu_lstats { u64 packets; u64 bytes; struct u64_stats_sync syncp; - unsigned long drops; }; /* @@ -90,8 +89,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, lb_stats->bytes += len; lb_stats->packets++; u64_stats_update_end(&lb_stats->syncp); - } else - lb_stats->drops++; + } return NETDEV_TX_OK; } @@ -101,7 +99,6 @@ static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, { u64 bytes = 0; u64 packets = 0; - u64 drops = 0; int i; for_each_possible_cpu(i) { @@ -115,14 +112,11 @@ static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, tbytes = lb_stats->bytes; tpackets = lb_stats->packets; } while (u64_stats_fetch_retry(&lb_stats->syncp, start)); - drops += lb_stats->drops; bytes += tbytes; packets += tpackets; } stats->rx_packets = packets; stats->tx_packets = packets; - stats->rx_dropped = drops; - stats->rx_errors = drops; stats->rx_bytes = bytes; stats->tx_bytes = bytes; return stats; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 92d81edd5808..6abcef67b178 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -884,6 +884,9 @@ struct net_device { int iflink; struct net_device_stats stats; + atomic_long_t rx_dropped; /* dropped packets by core network + * Do not use this in drivers. + */ #ifdef CONFIG_WIRELESS_EXT /* List of functions to handle Wireless Extensions (instead of ioctl). diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index b26ce343072c..8d9503ad01da 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -25,7 +25,6 @@ struct vlan_priority_tci_mapping { * @rx_multicast: number of received multicast packets * @syncp: synchronization point for 64bit counters * @rx_errors: number of errors - * @rx_dropped: number of dropped packets */ struct vlan_rx_stats { u64 rx_packets; @@ -33,7 +32,6 @@ struct vlan_rx_stats { u64 rx_multicast; struct u64_stats_sync syncp; unsigned long rx_errors; - unsigned long rx_dropped; }; /** diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index b6d55a9304f2..dee727ce0291 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -33,6 +33,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return polling ? netif_receive_skb(skb) : netif_rx(skb); drop: + atomic_long_inc(&skb->dev->rx_dropped); dev_kfree_skb_any(skb); return NET_RX_DROP; } @@ -123,6 +124,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, return dev_gro_receive(napi, skb); drop: + atomic_long_inc(&skb->dev->rx_dropped); return GRO_DROP; } diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f6fbcc0f1af9..f54251edd40d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -225,16 +225,15 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } } - if (unlikely(netif_rx(skb) == NET_RX_DROP)) { - if (rx_stats) - rx_stats->rx_dropped++; - } + netif_rx(skb); + rcu_read_unlock(); return NET_RX_SUCCESS; err_unlock: rcu_read_unlock(); err_free: + atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -846,15 +845,13 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st accum.rx_packets += rxpackets; accum.rx_bytes += rxbytes; accum.rx_multicast += rxmulticast; - /* rx_errors, rx_dropped are ulong, not protected by syncp */ + /* rx_errors is ulong, not protected by syncp */ accum.rx_errors += p->rx_errors; - accum.rx_dropped += p->rx_dropped; } stats->rx_packets = accum.rx_packets; stats->rx_bytes = accum.rx_bytes; stats->rx_errors = accum.rx_errors; stats->multicast = accum.rx_multicast; - stats->rx_dropped = accum.rx_dropped; } return stats; } diff --git a/net/core/dev.c b/net/core/dev.c index ce6ad88c980b..7d149550e8d6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1483,8 +1483,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb_orphan(skb); nf_reset(skb); - if (!(dev->flags & IFF_UP) || - (skb->len > (dev->mtu + dev->hard_header_len))) { + if (unlikely(!(dev->flags & IFF_UP) || + (skb->len > (dev->mtu + dev->hard_header_len)))) { + atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -2548,6 +2549,7 @@ enqueue: local_irq_restore(flags); + atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -2995,6 +2997,7 @@ ncls: if (pt_prev) { ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); } else { + atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); /* Jamal, now you will not able to escape explaining * me how you were going to use this. :-) @@ -5429,14 +5432,14 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, if (ops->ndo_get_stats64) { memset(storage, 0, sizeof(*storage)); - return ops->ndo_get_stats64(dev, storage); - } - if (ops->ndo_get_stats) { + ops->ndo_get_stats64(dev, storage); + } else if (ops->ndo_get_stats) { netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); - return storage; + } else { + netdev_stats_to_stats64(storage, &dev->stats); + dev_txq_stats_fold(dev, storage); } - netdev_stats_to_stats64(storage, &dev->stats); - dev_txq_stats_fold(dev, storage); + storage->rx_dropped += atomic_long_read(&dev->rx_dropped); return storage; } EXPORT_SYMBOL(dev_get_stats); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index fbe2c473a06a..9d421f4cf3ef 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -679,8 +679,7 @@ static int ipgre_rcv(struct sk_buff *skb) skb_reset_network_header(skb); ipgre_ecn_decapsulate(iph, skb); - if (netif_rx(skb) == NET_RX_DROP) - tunnel->dev->stats.rx_dropped++; + netif_rx(skb); rcu_read_unlock(); return 0; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 6ad46c28ede2..e9b816e6cd73 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -414,8 +414,7 @@ static int ipip_rcv(struct sk_buff *skb) ipip_ecn_decapsulate(iph, skb); - if (netif_rx(skb) == NET_RX_DROP) - tunnel->dev->stats.rx_dropped++; + netif_rx(skb); rcu_read_unlock(); return 0; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 8be3c452af90..c2c0f89397b1 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -768,8 +768,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, dscp_ecn_decapsulate(t, ipv6h, skb); - if (netif_rx(skb) == NET_RX_DROP) - t->dev->stats.rx_dropped++; + netif_rx(skb); rcu_read_unlock(); return 0; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 2640c9be589d..6f32ffce7022 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -666,8 +666,7 @@ static int pim6_rcv(struct sk_buff *skb) skb_tunnel_rx(skb, reg_dev); - if (netif_rx(skb) == NET_RX_DROP) - reg_dev->stats.rx_dropped++; + netif_rx(skb); dev_put(reg_dev); return 0; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d7701782b639..367a6cc584cc 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -600,8 +600,7 @@ static int ipip6_rcv(struct sk_buff *skb) ipip6_ecn_decapsulate(iph, skb); - if (netif_rx(skb) == NET_RX_DROP) - tunnel->dev->stats.rx_dropped++; + netif_rx(skb); rcu_read_unlock(); return 0; -- cgit v1.2.3 From 110b2499370c401cdcc7c63e481084467291d556 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Oct 2010 04:27:36 +0000 Subject: net neigh: neigh_delete() and neigh_add() changes neigh_delete() and neigh_add() dont need to touch device refcount, we hold RTNL when calling them, so device cannot disappear under us. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/neighbour.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b142a0d76072..d6996e072a41 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1531,6 +1531,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct net_device *dev = NULL; int err = -EINVAL; + ASSERT_RTNL(); if (nlmsg_len(nlh) < sizeof(*ndm)) goto out; @@ -1540,7 +1541,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(net, ndm->ndm_ifindex); + dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; @@ -1556,34 +1557,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) read_unlock(&neigh_tbl_lock); if (nla_len(dst_attr) < tbl->key_len) - goto out_dev_put; + goto out; if (ndm->ndm_flags & NTF_PROXY) { err = pneigh_delete(tbl, net, nla_data(dst_attr), dev); - goto out_dev_put; + goto out; } if (dev == NULL) - goto out_dev_put; + goto out; neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); if (neigh == NULL) { err = -ENOENT; - goto out_dev_put; + goto out; } err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN); neigh_release(neigh); - goto out_dev_put; + goto out; } read_unlock(&neigh_tbl_lock); err = -EAFNOSUPPORT; -out_dev_put: - if (dev) - dev_put(dev); out: return err; } @@ -1597,6 +1595,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct net_device *dev = NULL; int err; + ASSERT_RTNL(); err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); if (err < 0) goto out; @@ -1607,14 +1606,14 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(net, ndm->ndm_ifindex); + dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; } if (tb[NDA_LLADDR] && nla_len(tb[NDA_LLADDR]) < dev->addr_len) - goto out_dev_put; + goto out; } read_lock(&neigh_tbl_lock); @@ -1628,7 +1627,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) read_unlock(&neigh_tbl_lock); if (nla_len(tb[NDA_DST]) < tbl->key_len) - goto out_dev_put; + goto out; dst = nla_data(tb[NDA_DST]); lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; @@ -1641,29 +1640,29 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) pn->flags = ndm->ndm_flags; err = 0; } - goto out_dev_put; + goto out; } if (dev == NULL) - goto out_dev_put; + goto out; neigh = neigh_lookup(tbl, dst, dev); if (neigh == NULL) { if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { err = -ENOENT; - goto out_dev_put; + goto out; } neigh = __neigh_lookup_errno(tbl, dst, dev); if (IS_ERR(neigh)) { err = PTR_ERR(neigh); - goto out_dev_put; + goto out; } } else { if (nlh->nlmsg_flags & NLM_F_EXCL) { err = -EEXIST; neigh_release(neigh); - goto out_dev_put; + goto out; } if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) @@ -1676,15 +1675,11 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } else err = neigh_update(neigh, lladdr, ndm->ndm_state, flags); neigh_release(neigh); - goto out_dev_put; + goto out; } read_unlock(&neigh_tbl_lock); err = -EAFNOSUPPORT; - -out_dev_put: - if (dev) - dev_put(dev); out: return err; } -- cgit v1.2.3 From d6bf781712a1d25cc8987036b3a48535b331eb91 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Oct 2010 06:15:44 +0000 Subject: net neigh: RCU conversion of neigh hash table David This is the first step for RCU conversion of neigh code. Next patches will convert hash_buckets[] and "struct neighbour" to RCU protected objects. Thanks [PATCH net-next] net neigh: RCU conversion of neigh hash table Instead of storing hash_buckets, hash_mask and hash_rnd in "struct neigh_table", a new structure is defined : struct neigh_hash_table { struct neighbour **hash_buckets; unsigned int hash_mask; __u32 hash_rnd; struct rcu_head rcu; }; And "struct neigh_table" has an RCU protected pointer to such a neigh_hash_table. This means the signature of (*hash)() function changed: We need to add a third parameter with the actual hash_rnd value, since this is not anymore a neigh_table field. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 16 +++- net/atm/clip.c | 4 +- net/core/neighbour.c | 219 ++++++++++++++++++++++++++++++------------------ net/decnet/dn_neigh.c | 13 +-- net/ipv4/arp.c | 8 +- net/ipv6/ndisc.c | 10 ++- 6 files changed, 170 insertions(+), 100 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 7d08fd1062f0..37845dae6488 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -138,13 +138,22 @@ struct pneigh_entry { * neighbour table manipulation */ +struct neigh_hash_table { + struct neighbour **hash_buckets; + unsigned int hash_mask; + __u32 hash_rnd; + struct rcu_head rcu; +}; + struct neigh_table { struct neigh_table *next; int family; int entry_size; int key_len; - __u32 (*hash)(const void *pkey, const struct net_device *); + __u32 (*hash)(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd); int (*constructor)(struct neighbour *); int (*pconstructor)(struct pneigh_entry *); void (*pdestructor)(struct pneigh_entry *); @@ -165,9 +174,7 @@ struct neigh_table { unsigned long last_rand; struct kmem_cache *kmem_cachep; struct neigh_statistics __percpu *stats; - struct neighbour **hash_buckets; - unsigned int hash_mask; - __u32 hash_rnd; + struct neigh_hash_table __rcu *nht; struct pneigh_entry **phash_buckets; }; @@ -237,6 +244,7 @@ extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_en struct neigh_seq_state { struct seq_net_private p; struct neigh_table *tbl; + struct neigh_hash_table *nht; void *(*neigh_sub_iter)(struct neigh_seq_state *state, struct neighbour *n, loff_t *pos); unsigned int bucket; diff --git a/net/atm/clip.c b/net/atm/clip.c index 95fdd1185067..ff956d1115bc 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -310,9 +310,9 @@ static int clip_constructor(struct neighbour *neigh) return 0; } -static u32 clip_hash(const void *pkey, const struct net_device *dev) +static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd) { - return jhash_2words(*(u32 *) pkey, dev->ifindex, clip_tbl.hash_rnd); + return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd); } static struct neigh_table clip_tbl = { diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d6996e072a41..dd8920e4f508 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -131,14 +131,17 @@ static int neigh_forced_gc(struct neigh_table *tbl) { int shrunk = 0; int i; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs); write_lock_bh(&tbl->lock); - for (i = 0; i <= tbl->hash_mask; i++) { + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + for (i = 0; i <= nht->hash_mask; i++) { struct neighbour *n, **np; - np = &tbl->hash_buckets[i]; + np = &nht->hash_buckets[i]; while ((n = *np) != NULL) { /* Neighbour record may be discarded if: * - nobody refers to it. @@ -199,9 +202,13 @@ static void pneigh_queue_purge(struct sk_buff_head *list) static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) { int i; + struct neigh_hash_table *nht; - for (i = 0; i <= tbl->hash_mask; i++) { - struct neighbour *n, **np = &tbl->hash_buckets[i]; + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + + for (i = 0; i <= nht->hash_mask; i++) { + struct neighbour *n, **np = &nht->hash_buckets[i]; while ((n = *np) != NULL) { if (dev && n->dev != dev) { @@ -297,64 +304,81 @@ out_entries: goto out; } -static struct neighbour **neigh_hash_alloc(unsigned int entries) +static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) { - unsigned long size = entries * sizeof(struct neighbour *); - struct neighbour **ret; + size_t size = entries * sizeof(struct neighbour *); + struct neigh_hash_table *ret; + struct neighbour **buckets; - if (size <= PAGE_SIZE) { - ret = kzalloc(size, GFP_ATOMIC); - } else { - ret = (struct neighbour **) - __get_free_pages(GFP_ATOMIC|__GFP_ZERO, get_order(size)); + ret = kmalloc(sizeof(*ret), GFP_ATOMIC); + if (!ret) + return NULL; + if (size <= PAGE_SIZE) + buckets = kzalloc(size, GFP_ATOMIC); + else + buckets = (struct neighbour **) + __get_free_pages(GFP_ATOMIC | __GFP_ZERO, + get_order(size)); + if (!buckets) { + kfree(ret); + return NULL; } + ret->hash_buckets = buckets; + ret->hash_mask = entries - 1; + get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); return ret; } -static void neigh_hash_free(struct neighbour **hash, unsigned int entries) +static void neigh_hash_free_rcu(struct rcu_head *head) { - unsigned long size = entries * sizeof(struct neighbour *); + struct neigh_hash_table *nht = container_of(head, + struct neigh_hash_table, + rcu); + size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); + struct neighbour **buckets = nht->hash_buckets; if (size <= PAGE_SIZE) - kfree(hash); + kfree(buckets); else - free_pages((unsigned long)hash, get_order(size)); + free_pages((unsigned long)buckets, get_order(size)); + kfree(nht); } -static void neigh_hash_grow(struct neigh_table *tbl, unsigned long new_entries) +static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, + unsigned long new_entries) { - struct neighbour **new_hash, **old_hash; - unsigned int i, new_hash_mask, old_entries; + unsigned int i, hash; + struct neigh_hash_table *new_nht, *old_nht; NEIGH_CACHE_STAT_INC(tbl, hash_grows); BUG_ON(!is_power_of_2(new_entries)); - new_hash = neigh_hash_alloc(new_entries); - if (!new_hash) - return; + old_nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + new_nht = neigh_hash_alloc(new_entries); + if (!new_nht) + return old_nht; - old_entries = tbl->hash_mask + 1; - new_hash_mask = new_entries - 1; - old_hash = tbl->hash_buckets; - - get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); - for (i = 0; i < old_entries; i++) { + for (i = 0; i <= old_nht->hash_mask; i++) { struct neighbour *n, *next; - for (n = old_hash[i]; n; n = next) { - unsigned int hash_val = tbl->hash(n->primary_key, n->dev); + for (n = old_nht->hash_buckets[i]; + n != NULL; + n = next) { + hash = tbl->hash(n->primary_key, n->dev, + new_nht->hash_rnd); - hash_val &= new_hash_mask; + hash &= new_nht->hash_mask; next = n->next; - n->next = new_hash[hash_val]; - new_hash[hash_val] = n; + n->next = new_nht->hash_buckets[hash]; + new_nht->hash_buckets[hash] = n; } } - tbl->hash_buckets = new_hash; - tbl->hash_mask = new_hash_mask; - neigh_hash_free(old_hash, old_entries); + rcu_assign_pointer(tbl->nht, new_nht); + call_rcu(&old_nht->rcu, neigh_hash_free_rcu); + return new_nht; } struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, @@ -363,19 +387,23 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, struct neighbour *n; int key_len = tbl->key_len; u32 hash_val; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, lookups); - read_lock_bh(&tbl->lock); - hash_val = tbl->hash(pkey, dev); - for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; + read_lock(&tbl->lock); + for (n = nht->hash_buckets[hash_val]; n; n = n->next) { if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { neigh_hold(n); NEIGH_CACHE_STAT_INC(tbl, hits); break; } } - read_unlock_bh(&tbl->lock); + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); return n; } EXPORT_SYMBOL(neigh_lookup); @@ -386,12 +414,15 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, struct neighbour *n; int key_len = tbl->key_len; u32 hash_val; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, lookups); - read_lock_bh(&tbl->lock); - hash_val = tbl->hash(pkey, NULL); - for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask; + read_lock(&tbl->lock); + for (n = nht->hash_buckets[hash_val]; n; n = n->next) { if (!memcmp(n->primary_key, pkey, key_len) && net_eq(dev_net(n->dev), net)) { neigh_hold(n); @@ -399,7 +430,8 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, break; } } - read_unlock_bh(&tbl->lock); + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); return n; } EXPORT_SYMBOL(neigh_lookup_nodev); @@ -411,6 +443,7 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, int key_len = tbl->key_len; int error; struct neighbour *n1, *rc, *n = neigh_alloc(tbl); + struct neigh_hash_table *nht; if (!n) { rc = ERR_PTR(-ENOBUFS); @@ -437,18 +470,20 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, n->confirmed = jiffies - (n->parms->base_reachable_time << 1); write_lock_bh(&tbl->lock); + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); - if (atomic_read(&tbl->entries) > (tbl->hash_mask + 1)) - neigh_hash_grow(tbl, (tbl->hash_mask + 1) << 1); + if (atomic_read(&tbl->entries) > (nht->hash_mask + 1)) + nht = neigh_hash_grow(tbl, (nht->hash_mask + 1) << 1); - hash_val = tbl->hash(pkey, dev) & tbl->hash_mask; + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; if (n->parms->dead) { rc = ERR_PTR(-EINVAL); goto out_tbl_unlock; } - for (n1 = tbl->hash_buckets[hash_val]; n1; n1 = n1->next) { + for (n1 = nht->hash_buckets[hash_val]; n1; n1 = n1->next) { if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) { neigh_hold(n1); rc = n1; @@ -456,8 +491,8 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, } } - n->next = tbl->hash_buckets[hash_val]; - tbl->hash_buckets[hash_val] = n; + n->next = nht->hash_buckets[hash_val]; + nht->hash_buckets[hash_val] = n; n->dead = 0; neigh_hold(n); write_unlock_bh(&tbl->lock); @@ -698,10 +733,13 @@ static void neigh_periodic_work(struct work_struct *work) struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work); struct neighbour *n, **np; unsigned int i; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs); write_lock_bh(&tbl->lock); + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); /* * periodically recompute ReachableTime from random function @@ -715,8 +753,8 @@ static void neigh_periodic_work(struct work_struct *work) neigh_rand_reach_time(p->base_reachable_time); } - for (i = 0 ; i <= tbl->hash_mask; i++) { - np = &tbl->hash_buckets[i]; + for (i = 0 ; i <= nht->hash_mask; i++) { + np = &nht->hash_buckets[i]; while ((n = *np) != NULL) { unsigned int state; @@ -1438,17 +1476,14 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour proc dir entry"); #endif - tbl->hash_mask = 1; - tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1); + tbl->nht = neigh_hash_alloc(8); phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); - if (!tbl->hash_buckets || !tbl->phash_buckets) + if (!tbl->nht || !tbl->phash_buckets) panic("cannot allocate neighbour cache hashes"); - get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); - rwlock_init(&tbl->lock); INIT_DELAYED_WORK_DEFERRABLE(&tbl->gc_work, neigh_periodic_work); schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time); @@ -1504,8 +1539,8 @@ int neigh_table_clear(struct neigh_table *tbl) } write_unlock(&neigh_tbl_lock); - neigh_hash_free(tbl->hash_buckets, tbl->hash_mask + 1); - tbl->hash_buckets = NULL; + call_rcu(&tbl->nht->rcu, neigh_hash_free_rcu); + tbl->nht = NULL; kfree(tbl->phash_buckets); tbl->phash_buckets = NULL; @@ -1745,18 +1780,22 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, unsigned long now = jiffies; unsigned int flush_delta = now - tbl->last_flush; unsigned int rand_delta = now - tbl->last_rand; - + struct neigh_hash_table *nht; struct ndt_config ndc = { .ndtc_key_len = tbl->key_len, .ndtc_entry_size = tbl->entry_size, .ndtc_entries = atomic_read(&tbl->entries), .ndtc_last_flush = jiffies_to_msecs(flush_delta), .ndtc_last_rand = jiffies_to_msecs(rand_delta), - .ndtc_hash_rnd = tbl->hash_rnd, - .ndtc_hash_mask = tbl->hash_mask, .ndtc_proxy_qlen = tbl->proxy_queue.qlen, }; + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + ndc.ndtc_hash_rnd = nht->hash_rnd; + ndc.ndtc_hash_mask = nht->hash_mask; + rcu_read_unlock_bh(); + NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); } @@ -2088,14 +2127,18 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, struct neighbour *n; int rc, h, s_h = cb->args[1]; int idx, s_idx = idx = cb->args[2]; + struct neigh_hash_table *nht; - read_lock_bh(&tbl->lock); - for (h = 0; h <= tbl->hash_mask; h++) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + + read_lock(&tbl->lock); + for (h = 0; h <= nht->hash_mask; h++) { if (h < s_h) continue; if (h > s_h) s_idx = 0; - for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { + for (n = nht->hash_buckets[h], idx = 0; n; n = n->next) { if (!net_eq(dev_net(n->dev), net)) continue; if (idx < s_idx) @@ -2104,7 +2147,6 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, cb->nlh->nlmsg_seq, RTM_NEWNEIGH, NLM_F_MULTI) <= 0) { - read_unlock_bh(&tbl->lock); rc = -1; goto out; } @@ -2112,9 +2154,10 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, idx++; } } - read_unlock_bh(&tbl->lock); rc = skb->len; out: + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); cb->args[1] = h; cb->args[2] = idx; return rc; @@ -2147,15 +2190,20 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie) { int chain; + struct neigh_hash_table *nht; - read_lock_bh(&tbl->lock); - for (chain = 0; chain <= tbl->hash_mask; chain++) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + + read_lock(&tbl->lock); + for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n; - for (n = tbl->hash_buckets[chain]; n; n = n->next) + for (n = nht->hash_buckets[chain]; n; n = n->next) cb(n, cookie); } - read_unlock_bh(&tbl->lock); + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); } EXPORT_SYMBOL(neigh_for_each); @@ -2164,11 +2212,14 @@ void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *)) { int chain; + struct neigh_hash_table *nht; - for (chain = 0; chain <= tbl->hash_mask; chain++) { + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n, **np; - np = &tbl->hash_buckets[chain]; + np = &nht->hash_buckets[chain]; while ((n = *np) != NULL) { int release; @@ -2193,13 +2244,13 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) { struct neigh_seq_state *state = seq->private; struct net *net = seq_file_net(seq); - struct neigh_table *tbl = state->tbl; + struct neigh_hash_table *nht = state->nht; struct neighbour *n = NULL; int bucket = state->bucket; state->flags &= ~NEIGH_SEQ_IS_PNEIGH; - for (bucket = 0; bucket <= tbl->hash_mask; bucket++) { - n = tbl->hash_buckets[bucket]; + for (bucket = 0; bucket <= nht->hash_mask; bucket++) { + n = nht->hash_buckets[bucket]; while (n) { if (!net_eq(dev_net(n->dev), net)) @@ -2234,7 +2285,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, { struct neigh_seq_state *state = seq->private; struct net *net = seq_file_net(seq); - struct neigh_table *tbl = state->tbl; + struct neigh_hash_table *nht = state->nht; if (state->neigh_sub_iter) { void *v = state->neigh_sub_iter(state, n, pos); @@ -2265,10 +2316,10 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (n) break; - if (++state->bucket > tbl->hash_mask) + if (++state->bucket > nht->hash_mask) break; - n = tbl->hash_buckets[state->bucket]; + n = nht->hash_buckets[state->bucket]; } if (n && pos) @@ -2367,6 +2418,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos) void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags) __acquires(tbl->lock) + __acquires(rcu_bh) { struct neigh_seq_state *state = seq->private; @@ -2374,8 +2426,9 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl state->bucket = 0; state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH); - read_lock_bh(&tbl->lock); - + rcu_read_lock_bh(); + state->nht = rcu_dereference_bh(tbl->nht); + read_lock(&tbl->lock); return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN; } EXPORT_SYMBOL(neigh_seq_start); @@ -2409,11 +2462,13 @@ EXPORT_SYMBOL(neigh_seq_next); void neigh_seq_stop(struct seq_file *seq, void *v) __releases(tbl->lock) + __releases(rcu_bh) { struct neigh_seq_state *state = seq->private; struct neigh_table *tbl = state->tbl; - read_unlock_bh(&tbl->lock); + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); } EXPORT_SYMBOL(neigh_seq_stop); diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 0363bb95cc7d..a085dbcf5c7f 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -48,7 +48,6 @@ #include #include -static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev); static int dn_neigh_construct(struct neighbour *); static void dn_long_error_report(struct neighbour *, struct sk_buff *); static void dn_short_error_report(struct neighbour *, struct sk_buff *); @@ -93,6 +92,13 @@ static const struct neigh_ops dn_phase3_ops = { .queue_xmit = dev_queue_xmit }; +static u32 dn_neigh_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) +{ + return jhash_2words(*(__u16 *)pkey, 0, hash_rnd); +} + struct neigh_table dn_neigh_table = { .family = PF_DECnet, .entry_size = sizeof(struct dn_neigh), @@ -122,11 +128,6 @@ struct neigh_table dn_neigh_table = { .gc_thresh3 = 1024, }; -static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev) -{ - return jhash_2words(*(__u16 *)pkey, 0, dn_neigh_table.hash_rnd); -} - static int dn_neigh_construct(struct neighbour *neigh) { struct net_device *dev = neigh->dev; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index d9031ad67826..f35309578170 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -127,7 +127,7 @@ EXPORT_SYMBOL(clip_tbl_hook); /* * Interface to generic neighbour cache. */ -static u32 arp_hash(const void *pkey, const struct net_device *dev); +static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 rnd); static int arp_constructor(struct neighbour *neigh); static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb); static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb); @@ -225,9 +225,11 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) } -static u32 arp_hash(const void *pkey, const struct net_device *dev) +static u32 arp_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) { - return jhash_2words(*(u32 *)pkey, dev->ifindex, arp_tbl.hash_rnd); + return jhash_2words(*(u32 *)pkey, dev->ifindex, hash_rnd); } static int arp_constructor(struct neighbour *neigh) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index b3dd844cd34f..998d6d27e7cf 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -91,7 +91,9 @@ #include #include -static u32 ndisc_hash(const void *pkey, const struct net_device *dev); +static u32 ndisc_hash(const void *pkey, + const struct net_device *dev, + __u32 rnd); static int ndisc_constructor(struct neighbour *neigh); static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); @@ -350,7 +352,9 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d EXPORT_SYMBOL(ndisc_mc_map); -static u32 ndisc_hash(const void *pkey, const struct net_device *dev) +static u32 ndisc_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) { const u32 *p32 = pkey; u32 addr_hash, i; @@ -359,7 +363,7 @@ static u32 ndisc_hash(const void *pkey, const struct net_device *dev) for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++) addr_hash ^= *p32++; - return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd); + return jhash_2words(addr_hash, dev->ifindex, hash_rnd); } static int ndisc_constructor(struct neighbour *neigh) -- cgit v1.2.3 From 3f66116e89521ef71ab0d63dc07a639def88a577 Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 4 Oct 2010 08:48:28 +0000 Subject: AF_UNIX: Implement SO_TIMESTAMP and SO_TIMETAMPNS on Unix sockets Userspace applications can already request to receive timestamps with: setsockopt(sockfd, SOL_SOCKET, SO_TIMESTAMP, ...) Although setsockopt() returns zero (success), timestamps are not added to the ancillary data. This patch fixes that on SOCK_DGRAM and SOCK_SEQPACKET Unix sockets. Signed-off-by: Alban Crequy Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/unix/af_unix.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c586da3f4f18..0ebc777a6660 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1511,6 +1511,8 @@ restart: goto restart; } + if (sock_flag(other, SOCK_RCVTSTAMP)) + __net_timestamp(skb); skb_queue_tail(&other->sk_receive_queue, skb); unix_state_unlock(other); other->sk_data_ready(other, len); @@ -1722,6 +1724,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, if (err) goto out_free; + if (sock_flag(sk, SOCK_RCVTSTAMP)) + __sock_recv_timestamp(msg, sk, skb); + if (!siocb->scm) { siocb->scm = &tmp_scm; memset(&tmp_scm, 0, sizeof(tmp_scm)); -- cgit v1.2.3 From 9ed51657f6ea2a08582d6a9be5404b044972b7e0 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 5 Oct 2010 13:11:30 +0000 Subject: ixgbevf: declare functions as static Following patch fixes warnings reported by `make namespacecheck` Reported by Stephen Hemminger CC: Stephen Hemminger Signed-off-by: Emil Tantilov Acked-by: Greg Rose Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbevf/mbx.c | 2 +- drivers/net/ixgbevf/mbx.h | 2 -- drivers/net/ixgbevf/vf.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbevf/mbx.c b/drivers/net/ixgbevf/mbx.c index b8143501e6fc..84ac486f4a65 100644 --- a/drivers/net/ixgbevf/mbx.c +++ b/drivers/net/ixgbevf/mbx.c @@ -308,7 +308,7 @@ out_no_read: * * Initializes the hw->mbx struct to correct values for vf mailbox */ -s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) +static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h index 1b0e0bf4c0f5..8c063bebee7f 100644 --- a/drivers/net/ixgbevf/mbx.h +++ b/drivers/net/ixgbevf/mbx.h @@ -95,6 +95,4 @@ /* forward declaration of the HW struct */ struct ixgbe_hw; -s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *); - #endif /* _IXGBE_MBX_H_ */ diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c index f6f929958ba0..bfe42c1fcfaf 100644 --- a/drivers/net/ixgbevf/vf.c +++ b/drivers/net/ixgbevf/vf.c @@ -368,7 +368,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, return 0; } -struct ixgbe_mac_operations ixgbevf_mac_ops = { +static struct ixgbe_mac_operations ixgbevf_mac_ops = { .init_hw = ixgbevf_init_hw_vf, .reset_hw = ixgbevf_reset_hw_vf, .start_hw = ixgbevf_start_hw_vf, -- cgit v1.2.3 From 5b27d42755fa6536a89f32b107fb2a53267696c2 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 5 Oct 2010 13:16:22 +0000 Subject: ehea: using wait queues instead of msleep on ehea_flush_sq This patch just remove a msleep loop and change to wait queue, making the code cleaner. Signed-off-by: Breno Leitao Acked-by: David Howells Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 1 + drivers/net/ehea/ehea_main.c | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 1846623c6ae6..5bae7daf40fb 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -491,6 +491,7 @@ struct ehea_port { u8 full_duplex; u8 autoneg; u8 num_def_qps; + wait_queue_head_t swqe_avail_wq; }; struct port_res_cfg { diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 190fb691d20b..7897bdf76e66 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -888,6 +888,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) pr->queue_stopped = 0; } spin_unlock_irqrestore(&pr->netif_queue, flags); + wake_up(&pr->port->swqe_avail_wq); return cqe; } @@ -2652,6 +2653,8 @@ static int ehea_open(struct net_device *dev) netif_start_queue(dev); } + init_waitqueue_head(&port->swqe_avail_wq); + mutex_unlock(&port->port_lock); return ret; @@ -2724,13 +2727,15 @@ static void ehea_flush_sq(struct ehea_port *port) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { struct ehea_port_res *pr = &port->port_res[i]; int swqe_max = pr->sq_skba_size - 2 - pr->swqe_ll_count; - int k = 0; - while (atomic_read(&pr->swqe_avail) < swqe_max) { - msleep(5); - if (++k == 20) { - ehea_error("WARNING: sq not flushed completely"); - break; - } + int ret; + + ret = wait_event_timeout(port->swqe_avail_wq, + atomic_read(&pr->swqe_avail) >= swqe_max, + msecs_to_jiffies(100)); + + if (!ret) { + ehea_error("WARNING: sq not flushed completely"); + break; } } } -- cgit v1.2.3 From a8bb69f78194dc483f6c4a4bf8860c1ede35fa25 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 5 Oct 2010 13:16:23 +0000 Subject: ehea: converting msleeps to waitqueue on check_sqs() function Removing the msleep() call in check_sqs() function, and replacing by a wait queue. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 1 + drivers/net/ehea/ehea_main.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 5bae7daf40fb..1321cb6401cf 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -492,6 +492,7 @@ struct ehea_port { u8 autoneg; u8 num_def_qps; wait_queue_head_t swqe_avail_wq; + wait_queue_head_t restart_wq; }; struct port_res_cfg { diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 7897bdf76e66..15401af30108 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -786,6 +786,7 @@ static void reset_sq_restart_flag(struct ehea_port *port) struct ehea_port_res *pr = &port->port_res[i]; pr->sq_restart_flag = 0; } + wake_up(&port->restart_wq); } static void check_sqs(struct ehea_port *port) @@ -796,6 +797,7 @@ static void check_sqs(struct ehea_port *port) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { struct ehea_port_res *pr = &port->port_res[i]; + int ret; k = 0; swqe = ehea_get_swqe(pr->qp, &swqe_index); memset(swqe, 0, SWQE_HEADER_SIZE); @@ -809,13 +811,14 @@ static void check_sqs(struct ehea_port *port) ehea_post_swqe(pr->qp, swqe); - while (pr->sq_restart_flag == 0) { - msleep(5); - if (++k == 100) { - ehea_error("HW/SW queues out of sync"); - ehea_schedule_port_reset(pr->port); - return; - } + ret = wait_event_timeout(port->restart_wq, + pr->sq_restart_flag == 0, + msecs_to_jiffies(100)); + + if (!ret) { + ehea_error("HW/SW queues out of sync"); + ehea_schedule_port_reset(pr->port); + return; } } } @@ -2654,6 +2657,7 @@ static int ehea_open(struct net_device *dev) } init_waitqueue_head(&port->swqe_avail_wq); + init_waitqueue_head(&port->restart_wq); mutex_unlock(&port->port_lock); -- cgit v1.2.3 From 5a37e8ca8536c47871d46c82211f399adf06fd44 Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Tue, 5 Oct 2010 14:23:57 +0000 Subject: bonding: rejoin multicast groups on VLANs During a failover, the IGMP membership is sent to update the switch restoring the traffic, but it misses groups added to VLAN devices running on top of bonding devices. This patch changes it to iterate over all VLAN devices on top of it sending IGMP memberships too. Signed-off-by: Flavio Leitner Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 60 +++++++++++++++++++++++++++++++++-------- drivers/net/bonding/bonding.h | 1 + 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index fb70c3e12927..ad6386671f28 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -865,18 +865,13 @@ static void bond_mc_del(struct bonding *bond, void *addr) } -/* - * Retrieve the list of registered multicast addresses for the bonding - * device and retransmit an IGMP JOIN request to the current active - * slave. - */ -static void bond_resend_igmp_join_requests(struct bonding *bond) +static void __bond_resend_igmp_join_requests(struct net_device *dev) { struct in_device *in_dev; struct ip_mc_list *im; rcu_read_lock(); - in_dev = __in_dev_get_rcu(bond->dev); + in_dev = __in_dev_get_rcu(dev); if (in_dev) { for (im = in_dev->mc_list; im; im = im->next) ip_mc_rejoin_group(im); @@ -885,6 +880,41 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) rcu_read_unlock(); } +/* + * Retrieve the list of registered multicast addresses for the bonding + * device and retransmit an IGMP JOIN request to the current active + * slave. + */ +static void bond_resend_igmp_join_requests(struct bonding *bond) +{ + struct net_device *vlan_dev; + struct vlan_entry *vlan; + + read_lock(&bond->lock); + + /* rejoin all groups on bond device */ + __bond_resend_igmp_join_requests(bond->dev); + + /* rejoin all groups on vlan devices */ + if (bond->vlgrp) { + list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { + vlan_dev = vlan_group_get_device(bond->vlgrp, + vlan->vlan_id); + if (vlan_dev) + __bond_resend_igmp_join_requests(vlan_dev); + } + } + + read_unlock(&bond->lock); +} + +void bond_resend_igmp_join_requests_delayed(struct work_struct *work) +{ + struct bonding *bond = container_of(work, struct bonding, + mcast_work.work); + bond_resend_igmp_join_requests(bond); +} + /* * flush all members of flush->mc_list from device dev->mc_list */ @@ -944,7 +974,6 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, netdev_for_each_mc_addr(ha, bond->dev) dev_mc_add(new_active->dev, ha->addr); - bond_resend_igmp_join_requests(bond); } } @@ -1180,9 +1209,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) } } - /* resend IGMP joins since all were sent on curr_active_slave */ - if (bond->params.mode == BOND_MODE_ROUNDROBIN) { - bond_resend_igmp_join_requests(bond); + /* resend IGMP joins since active slave has changed or + * all were sent on curr_active_slave */ + if ((USES_PRIMARY(bond->params.mode) && new_active) || + bond->params.mode == BOND_MODE_ROUNDROBIN) { + queue_delayed_work(bond->wq, &bond->mcast_work, 0); } } @@ -3744,6 +3775,8 @@ static int bond_open(struct net_device *bond_dev) bond->kill_timers = 0; + INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); + if (bond_is_lb(bond)) { /* bond_alb_initialize must be called before the timer * is started. @@ -3828,6 +3861,8 @@ static int bond_close(struct net_device *bond_dev) break; } + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work(&bond->mcast_work); if (bond_is_lb(bond)) { /* Must be called only after all @@ -4703,6 +4738,9 @@ static void bond_work_cancel_all(struct bonding *bond) if (bond->params.mode == BOND_MODE_8023AD && delayed_work_pending(&bond->ad_work)) cancel_delayed_work(&bond->ad_work); + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work(&bond->mcast_work); } /* diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c6fdd851579a..308ed10dca90 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -223,6 +223,7 @@ struct bonding { struct delayed_work arp_work; struct delayed_work alb_work; struct delayed_work ad_work; + struct delayed_work mcast_work; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr master_ipv6; #endif -- cgit v1.2.3 From e12b453904c54bbdc515778ff664d87a7f9473af Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Tue, 5 Oct 2010 14:23:58 +0000 Subject: bonding: fix to rejoin multicast groups immediately The IGMP specs states that if the system receives a membership report, it shouldn't send another for the next minute. However, if a link failure happens right after that, the backup slave and the switch connected to this slave will not know about the multicast and the traffic will hang for about a minute. This patch fixes it to rejoin multicast groups immediately after a failover restoring the multicast traffic. Signed-off-by: Flavio Leitner Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2a4bb76f2132..25f339672b28 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1269,14 +1269,14 @@ void ip_mc_rejoin_group(struct ip_mc_list *im) if (im->multiaddr == IGMP_ALL_HOSTS) return; - if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) { - igmp_mod_timer(im, IGMP_Initial_Report_Delay); - return; - } - /* else, v3 */ - im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : - IGMP_Unsolicited_Report_Count; - igmp_ifc_event(in_dev); + /* a failover is happening and switches + * must be notified immediately */ + if (IGMP_V1_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); + else if (IGMP_V2_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); + else + igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); #endif } EXPORT_SYMBOL(ip_mc_rejoin_group); -- cgit v1.2.3 From c2952c314b4fe61820ba8fd6c949eed636140d52 Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Tue, 5 Oct 2010 14:23:59 +0000 Subject: bonding: add retransmit membership reports tunable Allow sysadmins to configure the number of multicast membership report sent on a link failure event. Signed-off-by: Flavio Leitner Signed-off-by: David S. Miller --- Documentation/networking/bonding.txt | 8 +++++++ drivers/net/bonding/bond_main.c | 15 ++++++++++++ drivers/net/bonding/bond_sysfs.c | 44 ++++++++++++++++++++++++++++++++++++ drivers/net/bonding/bonding.h | 2 ++ include/linux/if_bonding.h | 3 +++ 5 files changed, 72 insertions(+) diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index d2b62b71b617..5dc638791d97 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -765,6 +765,14 @@ xmit_hash_policy does not exist, and the layer2 policy is the only policy. The layer2+3 value was added for bonding version 3.2.2. +resend_igmp + + Specifies the number of IGMP membership reports to be issued after + a failover event. One membership report is issued immediately after + the failover, subsequent packets are sent in each 200ms interval. + + The valid range is 0 - 255; the default value is 1. This option + was added for bonding version 3.7.0. 3. Configuring Bonding Devices ============================== diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ad6386671f28..6f5e6b453da6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -109,6 +109,7 @@ static char *arp_validate; static char *fail_over_mac; static int all_slaves_active = 0; static struct bond_params bonding_defaults; +static int resend_igmp = BOND_DEFAULT_RESEND_IGMP; module_param(max_bonds, int, 0); MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); @@ -163,6 +164,8 @@ module_param(all_slaves_active, int, 0); MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" "by setting active flag for all slaves. " "0 for never (default), 1 for always."); +module_param(resend_igmp, int, 0); +MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure"); /*----------------------------- Global variables ----------------------------*/ @@ -905,6 +908,9 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) } } + if (--bond->igmp_retrans > 0) + queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); + read_unlock(&bond->lock); } @@ -1213,6 +1219,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) * all were sent on curr_active_slave */ if ((USES_PRIMARY(bond->params.mode) && new_active) || bond->params.mode == BOND_MODE_ROUNDROBIN) { + bond->igmp_retrans = bond->params.resend_igmp; queue_delayed_work(bond->wq, &bond->mcast_work, 0); } } @@ -4933,6 +4940,13 @@ static int bond_check_params(struct bond_params *params) all_slaves_active = 0; } + if (resend_igmp < 0 || resend_igmp > 255) { + pr_warning("Warning: resend_igmp (%d) should be between " + "0 and 255, resetting to %d\n", + resend_igmp, BOND_DEFAULT_RESEND_IGMP); + resend_igmp = BOND_DEFAULT_RESEND_IGMP; + } + /* reset values for TLB/ALB */ if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) { @@ -5105,6 +5119,7 @@ static int bond_check_params(struct bond_params *params) params->fail_over_mac = fail_over_mac_value; params->tx_queues = tx_queues; params->all_slaves_active = all_slaves_active; + params->resend_igmp = resend_igmp; if (primary) { strncpy(params->primary, primary, IFNAMSIZ); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c311aed9bd02..01b4c3f5d9e7 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1592,6 +1592,49 @@ out: static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, bonding_show_slaves_active, bonding_store_slaves_active); +/* + * Show and set the number of IGMP membership reports to send on link failure + */ +static ssize_t bonding_show_resend_igmp(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct bonding *bond = to_bond(d); + + return sprintf(buf, "%d\n", bond->params.resend_igmp); +} + +static ssize_t bonding_store_resend_igmp(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int new_value, ret = count; + struct bonding *bond = to_bond(d); + + if (sscanf(buf, "%d", &new_value) != 1) { + pr_err("%s: no resend_igmp value specified.\n", + bond->dev->name); + ret = -EINVAL; + goto out; + } + + if (new_value < 0) { + pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n", + bond->dev->name, new_value); + ret = -EINVAL; + goto out; + } + + pr_info("%s: Setting resend_igmp to %d.\n", + bond->dev->name, new_value); + bond->params.resend_igmp = new_value; +out: + return ret; +} + +static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR, + bonding_show_resend_igmp, bonding_store_resend_igmp); + static struct attribute *per_bond_attrs[] = { &dev_attr_slaves.attr, &dev_attr_mode.attr, @@ -1619,6 +1662,7 @@ static struct attribute *per_bond_attrs[] = { &dev_attr_ad_partner_mac.attr, &dev_attr_queue_id.attr, &dev_attr_all_slaves_active.attr, + &dev_attr_resend_igmp.attr, NULL, }; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 308ed10dca90..c15f21347486 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -136,6 +136,7 @@ struct bond_params { __be32 arp_targets[BOND_MAX_ARP_TARGETS]; int tx_queues; int all_slaves_active; + int resend_igmp; }; struct bond_parm_tbl { @@ -202,6 +203,7 @@ struct bonding { s8 send_grat_arp; s8 send_unsol_na; s8 setup_by_slave; + s8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; char proc_file_name[IFNAMSIZ]; diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h index 2c7994372bde..a17edda8a781 100644 --- a/include/linux/if_bonding.h +++ b/include/linux/if_bonding.h @@ -84,6 +84,9 @@ #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ + +#define BOND_DEFAULT_RESEND_IGMP 1 /* Default number of IGMP membership reports */ + /* hashing types */ #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ -- cgit v1.2.3 From ebc0ffae5dfb4447e0a431ffe7fe1d467c48bbb9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Oct 2010 10:41:36 +0000 Subject: fib: RCU conversion of fib_lookup() fib_lookup() converted to be called in RCU protected context, no reference taken and released on a contended cache line (fib_clntref) fib_table_lookup() and fib_semantic_match() get an additional parameter. struct fib_info gets an rcu_head field, and is freed after an rcu grace period. Stress test : (Sending 160.000.000 UDP frames on same neighbour, IP route cache disabled, dual E5540 @2.53GHz, 32bit kernel, FIB_HASH) (about same results for FIB_TRIE) Before patch : real 1m31.199s user 0m13.761s sys 23m24.780s After patch: real 1m5.375s user 0m14.997s sys 15m50.115s Before patch Profile : 13044.00 15.4% __ip_route_output_key vmlinux 8438.00 10.0% dst_destroy vmlinux 5983.00 7.1% fib_semantic_match vmlinux 5410.00 6.4% fib_rules_lookup vmlinux 4803.00 5.7% neigh_lookup vmlinux 4420.00 5.2% _raw_spin_lock vmlinux 3883.00 4.6% rt_set_nexthop vmlinux 3261.00 3.9% _raw_read_lock vmlinux 2794.00 3.3% fib_table_lookup vmlinux 2374.00 2.8% neigh_resolve_output vmlinux 2153.00 2.5% dst_alloc vmlinux 1502.00 1.8% _raw_read_lock_bh vmlinux 1484.00 1.8% kmem_cache_alloc vmlinux 1407.00 1.7% eth_header vmlinux 1406.00 1.7% ipv4_dst_destroy vmlinux 1298.00 1.5% __copy_from_user_ll vmlinux 1174.00 1.4% dev_queue_xmit vmlinux 1000.00 1.2% ip_output vmlinux After patch Profile : 13712.00 15.8% dst_destroy vmlinux 8548.00 9.9% __ip_route_output_key vmlinux 7017.00 8.1% neigh_lookup vmlinux 4554.00 5.3% fib_semantic_match vmlinux 4067.00 4.7% _raw_read_lock vmlinux 3491.00 4.0% dst_alloc vmlinux 3186.00 3.7% neigh_resolve_output vmlinux 3103.00 3.6% fib_table_lookup vmlinux 2098.00 2.4% _raw_read_lock_bh vmlinux 2081.00 2.4% kmem_cache_alloc vmlinux 2013.00 2.3% _raw_spin_lock vmlinux 1763.00 2.0% __copy_from_user_ll vmlinux 1763.00 2.0% ip_output vmlinux 1761.00 2.0% ipv4_dst_destroy vmlinux 1631.00 1.9% eth_header vmlinux 1440.00 1.7% _raw_read_unlock_bh vmlinux Reference results, if IP route cache is enabled : real 0m29.718s user 0m10.845s sys 7m37.341s 25213.00 29.5% __ip_route_output_key vmlinux 9011.00 10.5% dst_release vmlinux 4817.00 5.6% ip_push_pending_frames vmlinux 4232.00 5.0% ip_finish_output vmlinux 3940.00 4.6% udp_sendmsg vmlinux 3730.00 4.4% __copy_from_user_ll vmlinux 3716.00 4.4% ip_route_output_flow vmlinux 2451.00 2.9% __xfrm_lookup vmlinux 2221.00 2.6% ip_append_data vmlinux 1718.00 2.0% _raw_spin_lock_bh vmlinux 1655.00 1.9% __alloc_skb vmlinux 1572.00 1.8% sock_wfree vmlinux 1345.00 1.6% kfree vmlinux Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/fib_rules.h | 2 ++ include/net/ip_fib.h | 17 ++++---------- net/core/fib_rules.c | 3 ++- net/ipv4/fib_frontend.c | 27 +++++++++++----------- net/ipv4/fib_hash.c | 5 ++-- net/ipv4/fib_lookup.h | 2 +- net/ipv4/fib_rules.c | 3 ++- net/ipv4/fib_semantics.c | 21 +++++++++++++---- net/ipv4/fib_trie.c | 10 ++++---- net/ipv4/route.c | 59 ++++++++++++++++++++---------------------------- 10 files changed, 72 insertions(+), 77 deletions(-) diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index ac2fd002812e..106f3097d384 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -31,6 +31,8 @@ struct fib_lookup_arg { void *lookup_ptr; void *result; struct fib_rule *rule; + int flags; +#define FIB_LOOKUP_NOREF 1 }; struct fib_rules_ops { diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index c93f94edc610..ba3666d31766 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -86,6 +86,7 @@ struct fib_info { #ifdef CONFIG_IP_ROUTE_MULTIPATH int fib_power; #endif + struct rcu_head rcu; struct fib_nh fib_nh[0]; #define fib_dev fib_nh[0].nh_dev }; @@ -148,7 +149,7 @@ struct fib_table { }; extern int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, - struct fib_result *res); + struct fib_result *res, int fib_flags); extern int fib_table_insert(struct fib_table *, struct fib_config *); extern int fib_table_delete(struct fib_table *, struct fib_config *); extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb, @@ -185,11 +186,11 @@ static inline int fib_lookup(struct net *net, const struct flowi *flp, struct fib_table *table; table = fib_get_table(net, RT_TABLE_LOCAL); - if (!fib_table_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) return 0; table = fib_get_table(net, RT_TABLE_MAIN); - if (!fib_table_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) return 0; return -ENETUNREACH; } @@ -254,16 +255,6 @@ static inline void fib_info_put(struct fib_info *fi) free_fib_info(fi); } -static inline void fib_res_put(struct fib_result *res) -{ - if (res->fi) - fib_info_put(res->fi); -#ifdef CONFIG_IP_MULTIPLE_TABLES - if (res->r) - fib_rule_put(res->r); -#endif -} - #ifdef CONFIG_PROC_FS extern int __net_init fib_proc_init(struct net *net); extern void __net_exit fib_proc_exit(struct net *net); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index cfb7d25c172d..21698f8c49ee 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -225,7 +225,8 @@ jumped: err = ops->action(rule, fl, flags, arg); if (err != -EAGAIN) { - if (likely(atomic_inc_not_zero(&rule->refcnt))) { + if ((arg->flags & FIB_LOOKUP_NOREF) || + likely(atomic_inc_not_zero(&rule->refcnt))) { arg->rule = rule; goto out; } diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index b05c23b05a9f..919f2ad19b49 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -168,8 +168,11 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) struct fib_result res = { 0 }; struct net_device *dev = NULL; - if (fib_lookup(net, &fl, &res)) + rcu_read_lock(); + if (fib_lookup(net, &fl, &res)) { + rcu_read_unlock(); return NULL; + } if (res.type != RTN_LOCAL) goto out; dev = FIB_RES_DEV(res); @@ -177,7 +180,7 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) if (dev && devref) dev_hold(dev); out: - fib_res_put(&res); + rcu_read_unlock(); return dev; } EXPORT_SYMBOL(__ip_dev_find); @@ -207,11 +210,12 @@ static inline unsigned __inet_dev_addr_type(struct net *net, local_table = fib_get_table(net, RT_TABLE_LOCAL); if (local_table) { ret = RTN_UNICAST; - if (!fib_table_lookup(local_table, &fl, &res)) { + rcu_read_lock(); + if (!fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { if (!dev || dev == res.fi->fib_dev) ret = res.type; - fib_res_put(&res); } + rcu_read_unlock(); } return ret; } @@ -235,6 +239,7 @@ EXPORT_SYMBOL(inet_dev_addr_type); * - figure out what "logical" interface this packet arrived * and calculate "specific destination" address. * - check, that packet arrived from expected physical interface. + * called with rcu_read_lock() */ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, @@ -259,7 +264,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net *net; no_addr = rpf = accept_local = 0; - rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); if (in_dev) { no_addr = in_dev->ifa_list == NULL; @@ -268,7 +272,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, if (mark && !IN_DEV_SRC_VMARK(in_dev)) fl.mark = 0; } - rcu_read_unlock(); if (in_dev == NULL) goto e_inval; @@ -278,7 +281,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, goto last_resort; if (res.type != RTN_UNICAST) { if (res.type != RTN_LOCAL || !accept_local) - goto e_inval_res; + goto e_inval; } *spec_dst = FIB_RES_PREFSRC(res); fib_combine_itag(itag, &res); @@ -299,10 +302,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, #endif if (dev_match) { ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; - fib_res_put(&res); return ret; } - fib_res_put(&res); if (no_addr) goto last_resort; if (rpf == 1) @@ -315,7 +316,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, *spec_dst = FIB_RES_PREFSRC(res); ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; } - fib_res_put(&res); } return ret; @@ -326,8 +326,6 @@ last_resort: *itag = 0; return 0; -e_inval_res: - fib_res_put(&res); e_inval: return -EINVAL; e_rpf: @@ -873,15 +871,16 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) local_bh_disable(); frn->tb_id = tb->tb_id; - frn->err = fib_table_lookup(tb, &fl, &res); + rcu_read_lock(); + frn->err = fib_table_lookup(tb, &fl, &res, FIB_LOOKUP_NOREF); if (!frn->err) { frn->prefixlen = res.prefixlen; frn->nh_sel = res.nh_sel; frn->type = res.type; frn->scope = res.scope; - fib_res_put(&res); } + rcu_read_unlock(); local_bh_enable(); } } diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 4ed7e0dea1bc..83cca68e259c 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -244,7 +244,8 @@ fn_new_zone(struct fn_hash *table, int z) } int fib_table_lookup(struct fib_table *tb, - const struct flowi *flp, struct fib_result *res) + const struct flowi *flp, struct fib_result *res, + int fib_flags) { int err; struct fn_zone *fz; @@ -264,7 +265,7 @@ int fib_table_lookup(struct fib_table *tb, err = fib_semantic_match(&f->fn_alias, flp, res, - fz->fz_order); + fz->fz_order, fib_flags); if (err <= 0) goto out; } diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 637b133973bd..b9c9a9f2aee5 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -22,7 +22,7 @@ struct fib_alias { /* Exported by fib_semantics.c */ extern int fib_semantic_match(struct list_head *head, const struct flowi *flp, - struct fib_result *res, int prefixlen); + struct fib_result *res, int prefixlen, int fib_flags); extern void fib_release_info(struct fib_info *); extern struct fib_info *fib_create_info(struct fib_config *cfg); extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi); diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 32300521e32c..7981a24f5c7b 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -57,6 +57,7 @@ int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res) { struct fib_lookup_arg arg = { .result = res, + .flags = FIB_LOOKUP_NOREF, }; int err; @@ -94,7 +95,7 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, if (!tbl) goto errout; - err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result); + err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result, arg->flags); if (err > 0) err = -EAGAIN; errout: diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index ba52f399a898..0f80dfc2f7fb 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -148,6 +148,13 @@ static const struct /* Release a nexthop info record */ +static void free_fib_info_rcu(struct rcu_head *head) +{ + struct fib_info *fi = container_of(head, struct fib_info, rcu); + + kfree(fi); +} + void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { @@ -161,7 +168,7 @@ void free_fib_info(struct fib_info *fi) } endfor_nexthops(fi); fib_info_cnt--; release_net(fi->fib_net); - kfree(fi); + call_rcu(&fi->rcu, free_fib_info_rcu); } void fib_release_info(struct fib_info *fi) @@ -553,6 +560,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, nh->nh_scope = RT_SCOPE_LINK; return 0; } + rcu_read_lock(); { struct flowi fl = { .nl_u = { @@ -568,8 +576,10 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, if (fl.fl4_scope < RT_SCOPE_LINK) fl.fl4_scope = RT_SCOPE_LINK; err = fib_lookup(net, &fl, &res); - if (err) + if (err) { + rcu_read_unlock(); return err; + } } err = -EINVAL; if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) @@ -585,7 +595,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, goto out; err = 0; out: - fib_res_put(&res); + rcu_read_unlock(); return err; } else { struct in_device *in_dev; @@ -879,7 +889,7 @@ failure: /* Note! fib_semantic_match intentionally uses RCU list functions. */ int fib_semantic_match(struct list_head *head, const struct flowi *flp, - struct fib_result *res, int prefixlen) + struct fib_result *res, int prefixlen, int fib_flags) { struct fib_alias *fa; int nh_sel = 0; @@ -943,7 +953,8 @@ out_fill_res: res->type = fa->fa_type; res->scope = fa->fa_scope; res->fi = fa->fa_info; - atomic_inc(&res->fi->fib_clntref); + if (!(fib_flags & FIB_LOOKUP_NOREF)) + atomic_inc(&res->fi->fib_clntref); return 0; } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index a96e5ec211a0..271c89bdf049 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1342,7 +1342,7 @@ err: /* should be called with rcu_read_lock */ static int check_leaf(struct trie *t, struct leaf *l, t_key key, const struct flowi *flp, - struct fib_result *res) + struct fib_result *res, int fib_flags) { struct leaf_info *li; struct hlist_head *hhead = &l->list; @@ -1356,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l, if (l->key != (key & ntohl(mask))) continue; - err = fib_semantic_match(&li->falh, flp, res, plen); + err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags); #ifdef CONFIG_IP_FIB_TRIE_STATS if (err <= 0) @@ -1372,7 +1372,7 @@ static int check_leaf(struct trie *t, struct leaf *l, } int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, - struct fib_result *res) + struct fib_result *res, int fib_flags) { struct trie *t = (struct trie *) tb->tb_data; int ret; @@ -1399,7 +1399,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, /* Just a leaf? */ if (IS_LEAF(n)) { - ret = check_leaf(t, (struct leaf *)n, key, flp, res); + ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); goto found; } @@ -1424,7 +1424,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, } if (IS_LEAF(n)) { - ret = check_leaf(t, (struct leaf *)n, key, flp, res); + ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); if (ret > 0) goto backtrace; goto found; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 04e0df82b88c..7864d0c48968 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1773,12 +1773,15 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) if (rt->fl.iif == 0) src = rt->rt_src; - else if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0) { - src = FIB_RES_PREFSRC(res); - fib_res_put(&res); - } else - src = inet_select_addr(rt->dst.dev, rt->rt_gateway, + else { + rcu_read_lock(); + if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0) + src = FIB_RES_PREFSRC(res); + else + src = inet_select_addr(rt->dst.dev, rt->rt_gateway, RT_SCOPE_UNIVERSE); + rcu_read_unlock(); + } memcpy(addr, &src, 4); } @@ -2081,6 +2084,7 @@ static int ip_mkroute_input(struct sk_buff *skb, * Such approach solves two big problems: * 1. Not simplex devices are handled properly. * 2. IP spoofing attempts are filtered with 100% of guarantee. + * called with rcu_read_lock() */ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, @@ -2102,7 +2106,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, unsigned hash; __be32 spec_dst; int err = -EINVAL; - int free_res = 0; struct net * net = dev_net(dev); /* IP on this device is disabled. */ @@ -2134,12 +2137,12 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, /* * Now we are ready to route packet. */ - if ((err = fib_lookup(net, &fl, &res)) != 0) { + err = fib_lookup(net, &fl, &res); + if (err != 0) { if (!IN_DEV_FORWARD(in_dev)) goto e_hostunreach; goto no_route; } - free_res = 1; RT_CACHE_STAT_INC(in_slow_tot); @@ -2148,8 +2151,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { err = fib_validate_source(saddr, daddr, tos, - net->loopback_dev->ifindex, - dev, &spec_dst, &itag, skb->mark); + net->loopback_dev->ifindex, + dev, &spec_dst, &itag, skb->mark); if (err < 0) goto martian_source_keep_err; if (err) @@ -2164,9 +2167,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto martian_destination; err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); -done: - if (free_res) - fib_res_put(&res); out: return err; brd_input: @@ -2226,7 +2226,7 @@ local_input: rth->rt_type = res.type; hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); - goto done; + goto out; no_route: RT_CACHE_STAT_INC(in_no_route); @@ -2249,21 +2249,21 @@ martian_destination: e_hostunreach: err = -EHOSTUNREACH; - goto done; + goto out; e_inval: err = -EINVAL; - goto done; + goto out; e_nobufs: err = -ENOBUFS; - goto done; + goto out; martian_source: err = -EINVAL; martian_source_keep_err: ip_handle_martian_source(dev, in_dev, skb, daddr, saddr); - goto done; + goto out; } int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, @@ -2349,6 +2349,7 @@ skip_cache: } EXPORT_SYMBOL(ip_route_input_common); +/* called with rcu_read_lock() */ static int __mkroute_output(struct rtable **result, struct fib_result *res, const struct flowi *fl, @@ -2373,18 +2374,13 @@ static int __mkroute_output(struct rtable **result, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - rcu_read_lock(); in_dev = __in_dev_get_rcu(dev_out); - if (!in_dev) { - rcu_read_unlock(); + if (!in_dev) return -EINVAL; - } + if (res->type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; - if (res->fi) { - fib_info_put(res->fi); - res->fi = NULL; - } + res->fi = NULL; } else if (res->type == RTN_MULTICAST) { flags |= RTCF_MULTICAST | RTCF_LOCAL; if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src, @@ -2394,10 +2390,8 @@ static int __mkroute_output(struct rtable **result, * default one, but do not gateway in this case. * Yes, it is hack. */ - if (res->fi && res->prefixlen < 4) { - fib_info_put(res->fi); + if (res->fi && res->prefixlen < 4) res->fi = NULL; - } } @@ -2467,6 +2461,7 @@ static int __mkroute_output(struct rtable **result, return 0; } +/* called with rcu_read_lock() */ static int ip_mkroute_output(struct rtable **rp, struct fib_result *res, const struct flowi *fl, @@ -2509,7 +2504,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, struct fib_result res; unsigned int flags = 0; struct net_device *dev_out = NULL; - int free_res = 0; int err; @@ -2636,15 +2630,12 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, err = -ENETUNREACH; goto out; } - free_res = 1; if (res.type == RTN_LOCAL) { if (!fl.fl4_src) fl.fl4_src = fl.fl4_dst; dev_out = net->loopback_dev; fl.oif = dev_out->ifindex; - if (res.fi) - fib_info_put(res.fi); res.fi = NULL; flags |= RTCF_LOCAL; goto make_route; @@ -2668,8 +2659,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, make_route: err = ip_mkroute_output(rp, &res, &fl, oldflp, dev_out, flags); - if (free_res) - fib_res_put(&res); out: return err; } -- cgit v1.2.3 From e2fa6f2ef6e48666b78d4b0f00914b06bb19d298 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 5 Oct 2010 15:46:04 +0000 Subject: bna: fix interrupt handling This fix handles the case when IRQ handler is called (for shared IRQs) even before the driver is ready to handle interrupts. Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index e380c0e88f4f..7210c34d2d5b 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -564,9 +564,11 @@ bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) static void bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) { - spin_lock_irq(&bnad->bna_lock); /* Because of polling context */ + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); /* Because of polling context */ bnad_enable_rx_irq_unsafe(ccb); - spin_unlock_irq(&bnad->bna_lock); + spin_unlock_irqrestore(&bnad->bna_lock, flags); } static void @@ -599,7 +601,7 @@ static irqreturn_t bnad_msix_mbox_handler(int irq, void *data) { u32 intr_status; - unsigned long flags; + unsigned long flags; struct net_device *netdev = data; struct bnad *bnad; @@ -630,13 +632,15 @@ bnad_isr(int irq, void *data) struct bnad_rx_info *rx_info; struct bnad_rx_ctrl *rx_ctrl; - spin_lock_irqsave(&bnad->bna_lock, flags); + if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))) + return IRQ_NONE; bna_intr_status_get(&bnad->bna, intr_status); - if (!intr_status) { - spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (unlikely(!intr_status)) return IRQ_NONE; - } + + spin_lock_irqsave(&bnad->bna_lock, flags); if (BNA_IS_MBOX_ERR_INTR(intr_status)) { bna_mbox_handler(&bnad->bna, intr_status); @@ -672,11 +676,10 @@ bnad_enable_mbox_irq(struct bnad *bnad) { int irq = BNAD_GET_MBOX_IRQ(bnad); - if (!(bnad->cfg_flags & BNAD_CF_MSIX)) - return; - if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) - enable_irq(irq); + if (bnad->cfg_flags & BNAD_CF_MSIX) + enable_irq(irq); + BNAD_UPDATE_CTR(bnad, mbox_intr_enabled); } @@ -689,11 +692,11 @@ bnad_disable_mbox_irq(struct bnad *bnad) { int irq = BNAD_GET_MBOX_IRQ(bnad); - if (!(bnad->cfg_flags & BNAD_CF_MSIX)) - return; if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) - disable_irq_nosync(irq); + if (bnad->cfg_flags & BNAD_CF_MSIX) + disable_irq_nosync(irq); + BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); } @@ -1045,14 +1048,12 @@ bnad_mbox_irq_free(struct bnad *bnad, return; spin_lock_irqsave(&bnad->bna_lock, flags); - bnad_disable_mbox_irq(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); irq = BNAD_GET_MBOX_IRQ(bnad); free_irq(irq, bnad->netdev); - spin_unlock_irqrestore(&bnad->bna_lock, flags); - kfree(intr_info->idl); } @@ -1094,8 +1095,15 @@ bnad_mbox_irq_alloc(struct bnad *bnad, sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); + /* + * Set the Mbox IRQ disable flag, so that the IRQ handler + * called from request_irq() for SHARED IRQs do not execute + */ + set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags); + err = request_irq(irq, irq_handler, flags, bnad->mbox_irq_name, bnad->netdev); + if (err) { kfree(intr_info->idl); intr_info->idl = NULL; @@ -1103,7 +1111,8 @@ bnad_mbox_irq_alloc(struct bnad *bnad, } spin_lock_irqsave(&bnad->bna_lock, flags); - bnad_disable_mbox_irq(bnad); + if (bnad->cfg_flags & BNAD_CF_MSIX) + disable_irq_nosync(irq); spin_unlock_irqrestore(&bnad->bna_lock, flags); return 0; } @@ -1485,7 +1494,6 @@ bnad_stats_timer_start(struct bnad *bnad) jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); } spin_unlock_irqrestore(&bnad->bna_lock, flags); - } /* @@ -2170,7 +2178,6 @@ bnad_device_disable(struct bnad *bnad) spin_unlock_irqrestore(&bnad->bna_lock, flags); wait_for_completion(&bnad->bnad_completions.ioc_comp); - } static int @@ -3108,7 +3115,6 @@ bnad_pci_probe(struct pci_dev *pdev, spin_lock_irqsave(&bnad->bna_lock, flags); bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]); - spin_unlock_irqrestore(&bnad->bna_lock, flags); bnad->stats.bna_stats = &bna->stats; -- cgit v1.2.3 From b7ee31c5af7f04b67d8b8e4f3b2bcb8bcfced8a3 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 5 Oct 2010 15:46:05 +0000 Subject: bna: scope and dead code cleanup As suggested by Stephen Hemminger: 1) Made functions and data structures static wherever possible. 2) Removed unused code. Signed-off-by: Debashis Dutt Signed-off-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bfa_ioc.c | 8 +- drivers/net/bna/bfa_ioc.h | 1 - drivers/net/bna/bfa_ioc_ct.c | 2 +- drivers/net/bna/bfa_sm.h | 2 +- drivers/net/bna/bna.h | 108 +-------- drivers/net/bna/bna_ctrl.c | 559 ++++++++----------------------------------- drivers/net/bna/bna_hw.h | 1 - drivers/net/bna/bna_txrx.c | 149 +++++------- drivers/net/bna/bnad.c | 29 +-- drivers/net/bna/bnad.h | 1 - drivers/net/bna/cna_fwimg.c | 2 +- 11 files changed, 170 insertions(+), 692 deletions(-) diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index 73493de98de5..e94e5aa97515 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -65,7 +65,7 @@ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ readl((__ioc)->ioc_regs.hfn_mbox_cmd)) -bool bfa_nw_auto_recover = true; +static bool bfa_nw_auto_recover = true; /* * forward declarations @@ -1276,12 +1276,6 @@ bfa_nw_ioc_auto_recover(bool auto_recover) bfa_nw_auto_recover = auto_recover; } -bool -bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) -{ - return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); -} - static void bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) { diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h index 7f0719e17efc..a73d84ec808c 100644 --- a/drivers/net/bna/bfa_ioc.h +++ b/drivers/net/bna/bfa_ioc.h @@ -271,7 +271,6 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc); void bfa_nw_ioc_disable(struct bfa_ioc *ioc); void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc); -bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc); void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c index 462857cbab9b..121cfd6d48b1 100644 --- a/drivers/net/bna/bfa_ioc_ct.c +++ b/drivers/net/bna/bfa_ioc_ct.c @@ -34,7 +34,7 @@ static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc); static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); -struct bfa_ioc_hwif nw_hwif_ct; +static struct bfa_ioc_hwif nw_hwif_ct; /** * Called from bfa_ioc_attach() to map asic specific calls. diff --git a/drivers/net/bna/bfa_sm.h b/drivers/net/bna/bfa_sm.h index 1d3d975d6f68..46462c49b6f9 100644 --- a/drivers/net/bna/bfa_sm.h +++ b/drivers/net/bna/bfa_sm.h @@ -77,7 +77,7 @@ typedef void (*bfa_fsm_t)(void *fsm, int event); ((_fsm)->fsm == (bfa_fsm_t)(_state)) static inline int -bfa_sm_to_state(struct bfa_sm_table *smt, bfa_sm_t sm) +bfa_sm_to_state(const struct bfa_sm_table *smt, bfa_sm_t sm) { int i = 0; diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h index 6a2b3291c190..df6676bbc84e 100644 --- a/drivers/net/bna/bna.h +++ b/drivers/net/bna/bna.h @@ -19,8 +19,7 @@ #include "bfi_ll.h" #include "bna_types.h" -extern u32 bna_dim_vector[][BNA_BIAS_T_MAX]; -extern u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX]; +extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX]; /** * @@ -344,9 +343,6 @@ do { \ * BNA */ -/* Internal APIs */ -void bna_adv_res_req(struct bna_res_info *res_info); - /* APIs for BNAD */ void bna_res_req(struct bna_res_info *res_info); void bna_init(struct bna *bna, struct bnad *bnad, @@ -354,7 +350,6 @@ void bna_init(struct bna *bna, struct bnad *bnad, struct bna_res_info *res_info); void bna_uninit(struct bna *bna); void bna_stats_get(struct bna *bna); -void bna_stats_clr(struct bna *bna); void bna_get_perm_mac(struct bna *bna, u8 *mac); /* APIs for Rx */ @@ -376,18 +371,6 @@ void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod, * DEVICE */ -/* Interanl APIs */ -void bna_adv_device_init(struct bna_device *device, struct bna *bna, - struct bna_res_info *res_info); - -/* APIs for BNA */ -void bna_device_init(struct bna_device *device, struct bna *bna, - struct bna_res_info *res_info); -void bna_device_uninit(struct bna_device *device); -void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status); -int bna_device_status_get(struct bna_device *device); -int bna_device_state_get(struct bna_device *device); - /* APIs for BNAD */ void bna_device_enable(struct bna_device *device); void bna_device_disable(struct bna_device *device, @@ -397,12 +380,6 @@ void bna_device_disable(struct bna_device *device, * MBOX */ -/* APIs for DEVICE */ -void bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna); -void bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod); -void bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod); -void bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod); - /* APIs for PORT, TX, RX */ void bna_mbox_handler(struct bna *bna, u32 intr_status); void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe); @@ -411,17 +388,6 @@ void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe); * PORT */ -/* APIs for BNA */ -void bna_port_init(struct bna_port *port, struct bna *bna); -void bna_port_uninit(struct bna_port *port); -int bna_port_state_get(struct bna_port *port); -int bna_llport_state_get(struct bna_llport *llport); - -/* APIs for DEVICE */ -void bna_port_start(struct bna_port *port); -void bna_port_stop(struct bna_port *port); -void bna_port_fail(struct bna_port *port); - /* API for RX */ int bna_port_mtu_get(struct bna_port *port); void bna_llport_admin_up(struct bna_llport *llport); @@ -437,12 +403,6 @@ void bna_port_pause_config(struct bna_port *port, void bna_port_mtu_set(struct bna_port *port, int mtu, void (*cbfn)(struct bnad *, enum bna_cb_status)); void bna_port_mac_get(struct bna_port *port, mac_t *mac); -void bna_port_type_set(struct bna_port *port, enum bna_port_type type); -void bna_port_linkcbfn_set(struct bna_port *port, - void (*linkcbfn)(struct bnad *, - enum bna_link_status)); -void bna_port_admin_up(struct bna_port *port); -void bna_port_admin_down(struct bna_port *port); /* Callbacks for TX, RX */ void bna_port_cb_tx_stopped(struct bna_port *port, @@ -450,11 +410,6 @@ void bna_port_cb_tx_stopped(struct bna_port *port, void bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status); -/* Callbacks for MBOX */ -void bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, - int status); -void bna_port_cb_link_down(struct bna_port *port, int status); - /** * IB */ @@ -464,25 +419,10 @@ void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna, struct bna_res_info *res_info); void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod); -/* APIs for TX, RX */ -struct bna_ib *bna_ib_get(struct bna_ib_mod *ib_mod, - enum bna_intr_type intr_type, int vector); -void bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib); -int bna_ib_reserve_idx(struct bna_ib *ib); -void bna_ib_release_idx(struct bna_ib *ib, int idx); -int bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config); -void bna_ib_start(struct bna_ib *ib); -void bna_ib_stop(struct bna_ib *ib); -void bna_ib_fail(struct bna_ib *ib); -void bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo); - /** * TX MODULE AND TX */ -/* Internal APIs */ -void bna_tx_prio_changed(struct bna_tx *tx, int prio); - /* APIs for BNA */ void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna, struct bna_res_info *res_info); @@ -508,10 +448,6 @@ void bna_tx_enable(struct bna_tx *tx); void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type, void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status)); -enum bna_cb_status -bna_tx_prio_set(struct bna_tx *tx, int prio, - void (*cbfn)(struct bnad *, struct bna_tx *, - enum bna_cb_status)); void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo); /** @@ -564,35 +500,20 @@ void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type, void (*cbfn)(void *, struct bna_rx *, enum bna_cb_status)); void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo); -void bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX]); +void bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]); void bna_rx_dim_update(struct bna_ccb *ccb); enum bna_cb_status bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac, void (*cbfn)(struct bnad *, struct bna_rx *, enum bna_cb_status)); enum bna_cb_status -bna_rx_ucast_add(struct bna_rx *rx, u8* ucmac, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); -enum bna_cb_status -bna_rx_ucast_del(struct bna_rx *rx, u8 *ucmac, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); -enum bna_cb_status bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac, void (*cbfn)(struct bnad *, struct bna_rx *, enum bna_cb_status)); enum bna_cb_status -bna_rx_mcast_del(struct bna_rx *rx, u8 *mcmac, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); -enum bna_cb_status bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac, void (*cbfn)(struct bnad *, struct bna_rx *, enum bna_cb_status)); -void bna_rx_mcast_delall(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); enum bna_cb_status bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode, enum bna_rxmode bitmask, @@ -601,36 +522,12 @@ bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode, void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id); void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id); void bna_rx_vlanfilter_enable(struct bna_rx *rx); -void bna_rx_vlanfilter_disable(struct bna_rx *rx); -void bna_rx_rss_enable(struct bna_rx *rx); -void bna_rx_rss_disable(struct bna_rx *rx); -void bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config); -void bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors, - int nvectors); void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config, void (*cbfn)(struct bnad *, struct bna_rx *, enum bna_cb_status)); void bna_rx_hds_disable(struct bna_rx *rx, void (*cbfn)(struct bnad *, struct bna_rx *, enum bna_cb_status)); -void bna_rx_receive_pause(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); -void bna_rx_receive_resume(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)); - -/* RxF APIs for RX */ -void bna_rxf_start(struct bna_rxf *rxf); -void bna_rxf_stop(struct bna_rxf *rxf); -void bna_rxf_fail(struct bna_rxf *rxf); -void bna_rxf_init(struct bna_rxf *rxf, struct bna_rx *rx, - struct bna_rx_config *q_config); -void bna_rxf_uninit(struct bna_rxf *rxf); - -/* Callback from RXF to RX */ -void bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status); -void bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status); /** * BNAD @@ -639,7 +536,6 @@ void bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status); /* Callbacks for BNA */ void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, struct bna_stats *stats); -void bnad_cb_stats_clr(struct bnad *bnad); /* Callbacks for DEVICE */ void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status); diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index ddd922f210c7..07b26598546e 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -19,6 +19,46 @@ #include "bfa_sm.h" #include "bfa_wc.h" +static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status); + +static void +bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, + int status) +{ + int i; + u8 prio_map; + + port->llport.link_status = BNA_LINK_UP; + if (aen->cee_linkup) + port->llport.link_status = BNA_CEE_UP; + + /* Compute the priority */ + prio_map = aen->prio_map; + if (prio_map) { + for (i = 0; i < 8; i++) { + if ((prio_map >> i) & 0x1) + break; + } + port->priority = i; + } else + port->priority = 0; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup); + bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority); + port->link_cbfn(port->bna->bnad, port->llport.link_status); +} + +static void +bna_port_cb_link_down(struct bna_port *port, int status) +{ + port->llport.link_status = BNA_LINK_DOWN; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN); + port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN); +} + /** * MBOX */ @@ -96,7 +136,7 @@ bna_ll_isr(void *llarg, struct bfi_mbmsg *msg) bna_mbox_aen_callback(bna, msg); } -void +static void bna_err_handler(struct bna *bna, u32 intr_status) { u32 init_halt; @@ -140,7 +180,7 @@ bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe) } } -void +static void bna_mbox_flush_q(struct bna *bna, struct list_head *q) { struct bna_mbox_qe *mb_qe = NULL; @@ -166,18 +206,18 @@ bna_mbox_flush_q(struct bna *bna, struct list_head *q) bna->mbox_mod.state = BNA_MBOX_FREE; } -void +static void bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod) { } -void +static void bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod) { bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q); } -void +static void bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna) { bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna); @@ -187,7 +227,7 @@ bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna) mbox_mod->bna = bna; } -void +static void bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod) { mbox_mod->bna = NULL; @@ -538,7 +578,7 @@ bna_fw_cb_llport_down(void *arg, int status) bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN); } -void +static void bna_port_cb_llport_stopped(struct bna_port *port, enum bna_cb_status status) { @@ -591,7 +631,7 @@ bna_llport_fail(struct bna_llport *llport) bfa_fsm_send_event(llport, LLPORT_E_FAIL); } -int +static int bna_llport_state_get(struct bna_llport *llport) { return bfa_sm_to_state(llport_sm_table, llport->fsm); @@ -1109,7 +1149,7 @@ bna_port_cb_chld_stopped(void *arg) bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED); } -void +static void bna_port_init(struct bna_port *port, struct bna *bna) { port->bna = bna; @@ -1137,7 +1177,7 @@ bna_port_init(struct bna_port *port, struct bna *bna) bna_llport_init(&port->llport, bna); } -void +static void bna_port_uninit(struct bna_port *port) { bna_llport_uninit(&port->llport); @@ -1147,13 +1187,13 @@ bna_port_uninit(struct bna_port *port) port->bna = NULL; } -int +static int bna_port_state_get(struct bna_port *port) { return bfa_sm_to_state(port_sm_table, port->fsm); } -void +static void bna_port_start(struct bna_port *port) { port->flags |= BNA_PORT_F_DEVICE_READY; @@ -1161,7 +1201,7 @@ bna_port_start(struct bna_port *port) bfa_fsm_send_event(port, PORT_E_START); } -void +static void bna_port_stop(struct bna_port *port) { port->stop_cbfn = bna_device_cb_port_stopped; @@ -1171,7 +1211,7 @@ bna_port_stop(struct bna_port *port) bfa_fsm_send_event(port, PORT_E_STOP); } -void +static void bna_port_fail(struct bna_port *port) { port->flags &= ~BNA_PORT_F_DEVICE_READY; @@ -1190,44 +1230,6 @@ bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status) bfa_wc_down(&port->chld_stop_wc); } -void -bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, - int status) -{ - int i; - u8 prio_map; - - port->llport.link_status = BNA_LINK_UP; - if (aen->cee_linkup) - port->llport.link_status = BNA_CEE_UP; - - /* Compute the priority */ - prio_map = aen->prio_map; - if (prio_map) { - for (i = 0; i < 8; i++) { - if ((prio_map >> i) & 0x1) - break; - } - port->priority = i; - } else - port->priority = 0; - - /* Dispatch events */ - bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup); - bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority); - port->link_cbfn(port->bna->bnad, port->llport.link_status); -} - -void -bna_port_cb_link_down(struct bna_port *port, int status) -{ - port->llport.link_status = BNA_LINK_DOWN; - - /* Dispatch events */ - bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN); - port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN); -} - int bna_port_mtu_get(struct bna_port *port) { @@ -1292,54 +1294,6 @@ bna_port_mac_get(struct bna_port *port, mac_t *mac) *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc); } -/** - * Should be called only when port is disabled - */ -void -bna_port_type_set(struct bna_port *port, enum bna_port_type type) -{ - port->type = type; - port->llport.type = type; -} - -/** - * Should be called only when port is disabled - */ -void -bna_port_linkcbfn_set(struct bna_port *port, - void (*linkcbfn)(struct bnad *, enum bna_link_status)) -{ - port->link_cbfn = linkcbfn; -} - -void -bna_port_admin_up(struct bna_port *port) -{ - struct bna_llport *llport = &port->llport; - - if (llport->flags & BNA_LLPORT_F_ENABLED) - return; - - llport->flags |= BNA_LLPORT_F_ENABLED; - - if (llport->flags & BNA_LLPORT_F_RX_ENABLED) - bfa_fsm_send_event(llport, LLPORT_E_UP); -} - -void -bna_port_admin_down(struct bna_port *port) -{ - struct bna_llport *llport = &port->llport; - - if (!(llport->flags & BNA_LLPORT_F_ENABLED)) - return; - - llport->flags &= ~BNA_LLPORT_F_ENABLED; - - if (llport->flags & BNA_LLPORT_F_RX_ENABLED) - bfa_fsm_send_event(llport, LLPORT_E_DOWN); -} - /** * DEVICE */ @@ -1357,7 +1311,7 @@ do {\ bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\ } while (0) -const struct bna_chip_regs_offset reg_offset[] = +static const struct bna_chip_regs_offset reg_offset[] = {{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS, HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0}, {HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS, @@ -1642,7 +1596,34 @@ static struct bfa_ioc_cbfn bfa_iocll_cbfn = { bna_device_cb_iocll_reset }; -void +/* device */ +static void +bna_adv_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info) +{ + u8 *kva; + u64 dma; + + device->bna = bna; + + kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva; + + /** + * Attach common modules (Diag, SFP, CEE, Port) and claim respective + * DMA memory. + */ + BNA_GET_DMA_ADDR( + &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); + kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; + + bfa_nw_cee_attach(&bna->cee, &device->ioc, bna); + bfa_nw_cee_mem_claim(&bna->cee, kva, dma); + kva += bfa_nw_cee_meminfo(); + dma += bfa_nw_cee_meminfo(); + +} + +static void bna_device_init(struct bna_device *device, struct bna *bna, struct bna_res_info *res_info) { @@ -1681,7 +1662,7 @@ bna_device_init(struct bna_device *device, struct bna *bna, bfa_fsm_set_state(device, bna_device_sm_stopped); } -void +static void bna_device_uninit(struct bna_device *device) { bna_mbox_mod_uninit(&device->bna->mbox_mod); @@ -1691,7 +1672,7 @@ bna_device_uninit(struct bna_device *device) device->bna = NULL; } -void +static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status) { struct bna_device *device = (struct bna_device *)arg; @@ -1699,7 +1680,7 @@ bna_device_cb_port_stopped(void *arg, enum bna_cb_status status) bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED); } -int +static int bna_device_status_get(struct bna_device *device) { return device->fsm == (bfa_fsm_t)bna_device_sm_ready; @@ -1733,24 +1714,13 @@ bna_device_disable(struct bna_device *device, enum bna_cleanup_type type) bfa_fsm_send_event(device, DEVICE_E_DISABLE); } -int +static int bna_device_state_get(struct bna_device *device) { return bfa_sm_to_state(device_sm_table, device->fsm); } -u32 bna_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { - {12, 20}, - {10, 18}, - {8, 16}, - {6, 12}, - {4, 8}, - {3, 6}, - {2, 4}, - {1, 2}, -}; - -u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { +const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { {12, 12}, {6, 10}, {5, 10}, @@ -1761,36 +1731,9 @@ u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { {1, 2}, }; -/* device */ -void -bna_adv_device_init(struct bna_device *device, struct bna *bna, - struct bna_res_info *res_info) -{ - u8 *kva; - u64 dma; - - device->bna = bna; - - kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva; - - /** - * Attach common modules (Diag, SFP, CEE, Port) and claim respective - * DMA memory. - */ - BNA_GET_DMA_ADDR( - &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); - kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; - - bfa_nw_cee_attach(&bna->cee, &device->ioc, bna); - bfa_nw_cee_mem_claim(&bna->cee, kva, dma); - kva += bfa_nw_cee_meminfo(); - dma += bfa_nw_cee_meminfo(); - -} - /* utils */ -void +static void bna_adv_res_req(struct bna_res_info *res_info) { /* DMA memory for COMMON_MODULE */ @@ -2044,36 +1987,6 @@ bna_fw_stats_get(struct bna *bna) bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1]; } -static void -bna_fw_cb_stats_clr(void *arg, int status) -{ - struct bna *bna = (struct bna *)arg; - - bfa_q_qe_init(&bna->mbox_qe.qe); - - memset(bna->stats.sw_stats, 0, sizeof(struct bna_sw_stats)); - memset(bna->stats.hw_stats, 0, sizeof(struct bfi_ll_stats)); - - bnad_cb_stats_clr(bna->bnad); -} - -static void -bna_fw_stats_clr(struct bna *bna) -{ - struct bfi_ll_stats_req ll_req; - - bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); - ll_req.stats_mask = htons(BFI_LL_STATS_ALL); - ll_req.rxf_id_mask[0] = htonl(0xffffffff); - ll_req.rxf_id_mask[1] = htonl(0xffffffff); - ll_req.txf_id_mask[0] = htonl(0xffffffff); - ll_req.txf_id_mask[1] = htonl(0xffffffff); - - bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req), - bna_fw_cb_stats_clr, bna); - bna_mbox_send(bna, &bna->mbox_qe); -} - void bna_stats_get(struct bna *bna) { @@ -2083,22 +1996,8 @@ bna_stats_get(struct bna *bna) bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); } -void -bna_stats_clr(struct bna *bna) -{ - if (bna_device_status_get(&bna->device)) - bna_fw_stats_clr(bna); - else { - memset(&bna->stats.sw_stats, 0, - sizeof(struct bna_sw_stats)); - memset(bna->stats.hw_stats, 0, - sizeof(struct bfi_ll_stats)); - bnad_cb_stats_clr(bna->bnad); - } -} - /* IB */ -void +static void bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo) { ib->ib_config.coalescing_timeo = coalescing_timeo; @@ -2157,7 +2056,7 @@ rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status) bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); } -void +static void __rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status) { struct bna_rx_fndb_ram *rx_fndb_ram; @@ -2553,7 +2452,7 @@ rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_promisc_enable(struct bna_rxf *rxf) { struct bna *bna = rxf->rx->bna; @@ -2584,7 +2483,7 @@ rxf_promisc_enable(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_promisc_disable(struct bna_rxf *rxf) { struct bna *bna = rxf->rx->bna; @@ -2623,7 +2522,7 @@ rxf_promisc_disable(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_default_enable(struct bna_rxf *rxf) { struct bna *bna = rxf->rx->bna; @@ -2654,7 +2553,7 @@ rxf_default_enable(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_default_disable(struct bna_rxf *rxf) { struct bna *bna = rxf->rx->bna; @@ -2693,7 +2592,7 @@ rxf_default_disable(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_allmulti_enable(struct bna_rxf *rxf) { int ret = 0; @@ -2721,7 +2620,7 @@ rxf_allmulti_enable(struct bna_rxf *rxf) * 0 = no h/w change * 1 = need h/w change */ -int +static int rxf_allmulti_disable(struct bna_rxf *rxf) { int ret = 0; @@ -2745,159 +2644,6 @@ rxf_allmulti_disable(struct bna_rxf *rxf) return ret; } -/* RxF <- bnad */ -void -bna_rx_mcast_delall(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - struct list_head *qe; - struct bna_mac *mac; - int need_hw_config = 0; - - /* Purge all entries from pending_add_q */ - while (!list_empty(&rxf->mcast_pending_add_q)) { - bfa_q_deq(&rxf->mcast_pending_add_q, &qe); - mac = (struct bna_mac *)qe; - bfa_q_qe_init(&mac->qe); - bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); - } - - /* Schedule all entries in active_q for deletion */ - while (!list_empty(&rxf->mcast_active_q)) { - bfa_q_deq(&rxf->mcast_active_q, &qe); - mac = (struct bna_mac *)qe; - bfa_q_qe_init(&mac->qe); - list_add_tail(&mac->qe, &rxf->mcast_pending_del_q); - need_hw_config = 1; - } - - if (need_hw_config) { - rxf->cam_fltr_cbfn = cbfn; - rxf->cam_fltr_cbarg = rx->bna->bnad; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); - return; - } - - if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); -} - -/* RxF <- Rx */ -void -bna_rx_receive_resume(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - - if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) { - rxf->oper_state_cbfn = cbfn; - rxf->oper_state_cbarg = rx->bna->bnad; - bfa_fsm_send_event(rxf, RXF_E_RESUME); - } else if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); -} - -void -bna_rx_receive_pause(struct bna_rx *rx, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - - if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_RUNNING) { - rxf->oper_state_cbfn = cbfn; - rxf->oper_state_cbarg = rx->bna->bnad; - bfa_fsm_send_event(rxf, RXF_E_PAUSE); - } else if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); -} - -/* RxF <- bnad */ -enum bna_cb_status -bna_rx_ucast_add(struct bna_rx *rx, u8 *addr, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - struct list_head *qe; - struct bna_mac *mac; - - /* Check if already added */ - list_for_each(qe, &rxf->ucast_active_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); - return BNA_CB_SUCCESS; - } - } - - /* Check if pending addition */ - list_for_each(qe, &rxf->ucast_pending_add_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); - return BNA_CB_SUCCESS; - } - } - - mac = bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod); - if (mac == NULL) - return BNA_CB_UCAST_CAM_FULL; - bfa_q_qe_init(&mac->qe); - memcpy(mac->addr, addr, ETH_ALEN); - list_add_tail(&mac->qe, &rxf->ucast_pending_add_q); - - rxf->cam_fltr_cbfn = cbfn; - rxf->cam_fltr_cbarg = rx->bna->bnad; - - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); - - return BNA_CB_SUCCESS; -} - -/* RxF <- bnad */ -enum bna_cb_status -bna_rx_ucast_del(struct bna_rx *rx, u8 *addr, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - struct list_head *qe; - struct bna_mac *mac; - - list_for_each(qe, &rxf->ucast_pending_add_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - list_del(qe); - bfa_q_qe_init(qe); - bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); - if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); - return BNA_CB_SUCCESS; - } - } - - list_for_each(qe, &rxf->ucast_active_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - list_del(qe); - bfa_q_qe_init(qe); - list_add_tail(qe, &rxf->ucast_pending_del_q); - rxf->cam_fltr_cbfn = cbfn; - rxf->cam_fltr_cbarg = rx->bna->bnad; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); - return BNA_CB_SUCCESS; - } - } - - return BNA_CB_INVALID_MAC; -} - /* RxF <- bnad */ enum bna_cb_status bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode, @@ -2978,39 +2724,6 @@ err_return: return BNA_CB_FAIL; } -/* RxF <- bnad */ -void -bna_rx_rss_enable(struct bna_rx *rx) -{ - struct bna_rxf *rxf = &rx->rxf; - - rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; - rxf->rss_status = BNA_STATUS_T_ENABLED; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); -} - -/* RxF <- bnad */ -void -bna_rx_rss_disable(struct bna_rx *rx) -{ - struct bna_rxf *rxf = &rx->rxf; - - rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; - rxf->rss_status = BNA_STATUS_T_DISABLED; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); -} - -/* RxF <- bnad */ -void -bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config) -{ - struct bna_rxf *rxf = &rx->rxf; - rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; - rxf->rss_status = BNA_STATUS_T_ENABLED; - rxf->rss_cfg = *rss_config; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); -} - void /* RxF <- bnad */ bna_rx_vlanfilter_enable(struct bna_rx *rx) @@ -3024,68 +2737,8 @@ bna_rx_vlanfilter_enable(struct bna_rx *rx) } } -/* RxF <- bnad */ -void -bna_rx_vlanfilter_disable(struct bna_rx *rx) -{ - struct bna_rxf *rxf = &rx->rxf; - - if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { - rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; - rxf->vlan_filter_status = BNA_STATUS_T_DISABLED; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); - } -} - /* Rx */ -struct bna_rxp * -bna_rx_get_rxp(struct bna_rx *rx, int vector) -{ - struct bna_rxp *rxp; - struct list_head *qe; - - list_for_each(qe, &rx->rxp_q) { - rxp = (struct bna_rxp *)qe; - if (rxp->vector == vector) - return rxp; - } - return NULL; -} - -/* - * bna_rx_rss_rit_set() - * Sets the Q ids for the specified msi-x vectors in the RIT. - * Maximum rit size supported is 64, which should be the max size of the - * vectors array. - */ - -void -bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors, int nvectors) -{ - int i; - struct bna_rxp *rxp; - struct bna_rxq *q0 = NULL, *q1 = NULL; - struct bna *bna; - struct bna_rxf *rxf; - - /* Build the RIT contents for this RX */ - bna = rx->bna; - - rxf = &rx->rxf; - for (i = 0; i < nvectors; i++) { - rxp = bna_rx_get_rxp(rx, vectors[i]); - - GET_RXQS(rxp, q0, q1); - rxf->rit_segment->rit[i].large_rxq_id = q0->rxq_id; - rxf->rit_segment->rit[i].small_rxq_id = (q1 ? q1->rxq_id : 0); - } - - rxf->rit_segment->rit_size = nvectors; - - /* Subsequent call to enable/reconfig RSS will update the RIT in h/w */ -} - /* Rx <- bnad */ void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo) @@ -3102,7 +2755,7 @@ bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo) /* Rx <- bnad */ void -bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX]) +bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]) { int i, j; @@ -3164,22 +2817,6 @@ bna_rx_dim_update(struct bna_ccb *ccb) } /* Tx */ -/* TX <- bnad */ -enum bna_cb_status -bna_tx_prio_set(struct bna_tx *tx, int prio, - void (*cbfn)(struct bnad *, struct bna_tx *, - enum bna_cb_status)) -{ - if (tx->flags & BNA_TX_F_PRIO_LOCK) - return BNA_CB_FAIL; - else { - tx->prio_change_cbfn = cbfn; - bna_tx_prio_changed(tx, prio); - } - - return BNA_CB_SUCCESS; -} - /* TX <- bnad */ void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo) diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h index 67eb376c5c7e..806b224a4c63 100644 --- a/drivers/net/bna/bna_hw.h +++ b/drivers/net/bna/bna_hw.h @@ -1282,7 +1282,6 @@ struct bna_chip_regs_offset { u32 fn_int_mask; u32 msix_idx; }; -extern const struct bna_chip_regs_offset reg_offset[]; struct bna_chip_regs { void __iomem *page_addr; diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c index 890846d55502..ad93fdb0f427 100644 --- a/drivers/net/bna/bna_txrx.c +++ b/drivers/net/bna/bna_txrx.c @@ -195,7 +195,7 @@ bna_ib_mod_uninit(struct bna_ib_mod *ib_mod) ib_mod->bna = NULL; } -struct bna_ib * +static struct bna_ib * bna_ib_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type, int vector) @@ -240,7 +240,7 @@ bna_ib_get(struct bna_ib_mod *ib_mod, return ib; } -void +static void bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib) { bna_intr_put(ib_mod, ib->intr); @@ -255,7 +255,7 @@ bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib) } /* Returns index offset - starting from 0 */ -int +static int bna_ib_reserve_idx(struct bna_ib *ib) { struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; @@ -309,7 +309,7 @@ bna_ib_reserve_idx(struct bna_ib *ib) return idx; } -void +static void bna_ib_release_idx(struct bna_ib *ib, int idx) { struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; @@ -356,7 +356,7 @@ bna_ib_release_idx(struct bna_ib *ib, int idx) } } -int +static int bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config) { if (ib->start_count) @@ -374,7 +374,7 @@ bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config) return 0; } -void +static void bna_ib_start(struct bna_ib *ib) { struct bna_ib_blk_mem ib_cfg; @@ -450,7 +450,7 @@ bna_ib_start(struct bna_ib *ib) } } -void +static void bna_ib_stop(struct bna_ib *ib) { u32 intx_mask; @@ -468,7 +468,7 @@ bna_ib_stop(struct bna_ib *ib) } } -void +static void bna_ib_fail(struct bna_ib *ib) { ib->start_count = 0; @@ -1394,7 +1394,7 @@ rxf_reset_packet_filter(struct bna_rxf *rxf) rxf_reset_packet_filter_allmulti(rxf); } -void +static void bna_rxf_init(struct bna_rxf *rxf, struct bna_rx *rx, struct bna_rx_config *q_config) @@ -1444,7 +1444,7 @@ bna_rxf_init(struct bna_rxf *rxf, bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); } -void +static void bna_rxf_uninit(struct bna_rxf *rxf) { struct bna_mac *mac; @@ -1476,7 +1476,18 @@ bna_rxf_uninit(struct bna_rxf *rxf) rxf->rx = NULL; } -void +static void +bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STARTED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id); + else + rx->bna->rx_mod.rxf_bmap[1] |= ((u32) + 1 << (rx->rxf.rxf_id - 32)); +} + +static void bna_rxf_start(struct bna_rxf *rxf) { rxf->start_cbfn = bna_rx_cb_rxf_started; @@ -1485,7 +1496,18 @@ bna_rxf_start(struct bna_rxf *rxf) bfa_fsm_send_event(rxf, RXF_E_START); } -void +static void +bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STOPPED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id; + else + rx->bna->rx_mod.rxf_bmap[1] &= ~(u32) + 1 << (rx->rxf.rxf_id - 32); +} + +static void bna_rxf_stop(struct bna_rxf *rxf) { rxf->stop_cbfn = bna_rx_cb_rxf_stopped; @@ -1493,7 +1515,7 @@ bna_rxf_stop(struct bna_rxf *rxf) bfa_fsm_send_event(rxf, RXF_E_STOP); } -void +static void bna_rxf_fail(struct bna_rxf *rxf) { rxf->rxf_flags |= BNA_RXF_FL_FAILED; @@ -1575,43 +1597,6 @@ bna_rx_mcast_add(struct bna_rx *rx, u8 *addr, return BNA_CB_SUCCESS; } -enum bna_cb_status -bna_rx_mcast_del(struct bna_rx *rx, u8 *addr, - void (*cbfn)(struct bnad *, struct bna_rx *, - enum bna_cb_status)) -{ - struct bna_rxf *rxf = &rx->rxf; - struct list_head *qe; - struct bna_mac *mac; - - list_for_each(qe, &rxf->mcast_pending_add_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - list_del(qe); - bfa_q_qe_init(qe); - bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); - if (cbfn) - (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); - return BNA_CB_SUCCESS; - } - } - - list_for_each(qe, &rxf->mcast_active_q) { - mac = (struct bna_mac *)qe; - if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { - list_del(qe); - bfa_q_qe_init(qe); - list_add_tail(qe, &rxf->mcast_pending_del_q); - rxf->cam_fltr_cbfn = cbfn; - rxf->cam_fltr_cbarg = rx->bna->bnad; - bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); - return BNA_CB_SUCCESS; - } - } - - return BNA_CB_INVALID_MAC; -} - enum bna_cb_status bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist, void (*cbfn)(struct bnad *, struct bna_rx *, @@ -1862,7 +1847,7 @@ bfa_fsm_state_decl(bna_rx, rxf_stop_wait, bfa_fsm_state_decl(bna_rx, rxq_stop_wait, struct bna_rx, enum bna_rx_event); -static struct bfa_sm_table rx_sm_table[] = { +static const struct bfa_sm_table rx_sm_table[] = { {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED}, {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT}, {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED}, @@ -2247,7 +2232,7 @@ bna_rit_create(struct bna_rx *rx) } } -int +static int _rx_can_satisfy(struct bna_rx_mod *rx_mod, struct bna_rx_config *rx_cfg) { @@ -2272,7 +2257,7 @@ _rx_can_satisfy(struct bna_rx_mod *rx_mod, return 1; } -struct bna_rxq * +static struct bna_rxq * _get_free_rxq(struct bna_rx_mod *rx_mod) { struct bna_rxq *rxq = NULL; @@ -2286,7 +2271,7 @@ _get_free_rxq(struct bna_rx_mod *rx_mod) return rxq; } -void +static void _put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq) { bfa_q_qe_init(&rxq->qe); @@ -2294,7 +2279,7 @@ _put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq) rx_mod->rxq_free_count++; } -struct bna_rxp * +static struct bna_rxp * _get_free_rxp(struct bna_rx_mod *rx_mod) { struct list_head *qe = NULL; @@ -2310,7 +2295,7 @@ _get_free_rxp(struct bna_rx_mod *rx_mod) return rxp; } -void +static void _put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp) { bfa_q_qe_init(&rxp->qe); @@ -2318,7 +2303,7 @@ _put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp) rx_mod->rxp_free_count++; } -struct bna_rx * +static struct bna_rx * _get_free_rx(struct bna_rx_mod *rx_mod) { struct list_head *qe = NULL; @@ -2336,7 +2321,7 @@ _get_free_rx(struct bna_rx_mod *rx_mod) return rx; } -void +static void _put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx) { bfa_q_qe_init(&rx->qe); @@ -2344,7 +2329,7 @@ _put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx) rx_mod->rx_free_count++; } -void +static void _rx_init(struct bna_rx *rx, struct bna *bna) { rx->bna = bna; @@ -2360,7 +2345,7 @@ _rx_init(struct bna_rx *rx, struct bna *bna) rx->stop_cbarg = NULL; } -void +static void _rxp_add_rxqs(struct bna_rxp *rxp, struct bna_rxq *q0, struct bna_rxq *q1) @@ -2383,7 +2368,7 @@ _rxp_add_rxqs(struct bna_rxp *rxp, } } -void +static void _rxq_qpt_init(struct bna_rxq *rxq, struct bna_rxp *rxp, u32 page_count, @@ -2412,7 +2397,7 @@ _rxq_qpt_init(struct bna_rxq *rxq, } } -void +static void _rxp_cqpt_setup(struct bna_rxp *rxp, u32 page_count, u32 page_size, @@ -2441,13 +2426,13 @@ _rxp_cqpt_setup(struct bna_rxp *rxp, } } -void +static void _rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp) { list_add_tail(&rxp->qe, &rx->rxp_q); } -void +static void _init_rxmod_queues(struct bna_rx_mod *rx_mod) { INIT_LIST_HEAD(&rx_mod->rx_free_q); @@ -2460,7 +2445,7 @@ _init_rxmod_queues(struct bna_rx_mod *rx_mod) rx_mod->rxp_free_count = 0; } -void +static void _rx_ctor(struct bna_rx *rx, int id) { bfa_q_qe_init(&rx->qe); @@ -2492,7 +2477,7 @@ bna_rx_cb_rxq_stopped_all(void *arg) bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED); } -void +static void bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx, enum bna_cb_status status) { @@ -2501,7 +2486,7 @@ bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx, bfa_wc_down(&rx_mod->rx_stop_wc); } -void +static void bna_rx_mod_cb_rx_stopped_all(void *arg) { struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg; @@ -2511,7 +2496,7 @@ bna_rx_mod_cb_rx_stopped_all(void *arg) rx_mod->stop_cbfn = NULL; } -void +static void bna_rx_start(struct bna_rx *rx) { rx->rx_flags |= BNA_RX_F_PORT_ENABLED; @@ -2519,7 +2504,7 @@ bna_rx_start(struct bna_rx *rx) bfa_fsm_send_event(rx, RX_E_START); } -void +static void bna_rx_stop(struct bna_rx *rx) { rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED; @@ -2532,7 +2517,7 @@ bna_rx_stop(struct bna_rx *rx) } } -void +static void bna_rx_fail(struct bna_rx *rx) { /* Indicate port is not enabled, and failed */ @@ -2541,28 +2526,6 @@ bna_rx_fail(struct bna_rx *rx) bfa_fsm_send_event(rx, RX_E_FAIL); } -void -bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status) -{ - bfa_fsm_send_event(rx, RX_E_RXF_STARTED); - if (rx->rxf.rxf_id < 32) - rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id); - else - rx->bna->rx_mod.rxf_bmap[1] |= ((u32) - 1 << (rx->rxf.rxf_id - 32)); -} - -void -bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status) -{ - bfa_fsm_send_event(rx, RX_E_RXF_STOPPED); - if (rx->rxf.rxf_id < 32) - rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id; - else - rx->bna->rx_mod.rxf_bmap[1] &= ~(u32) - 1 << (rx->rxf.rxf_id - 32); -} - void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type) { @@ -3731,7 +3694,7 @@ bna_tx_fail(struct bna_tx *tx) bfa_fsm_send_event(tx, TX_E_FAIL); } -void +static void bna_tx_prio_changed(struct bna_tx *tx, int prio) { struct bna_txq *txq; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 7210c34d2d5b..74c64d6c8801 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -28,7 +28,7 @@ #include "bna.h" #include "cna.h" -DEFINE_MUTEX(bnad_fwimg_mutex); +static DEFINE_MUTEX(bnad_fwimg_mutex); /* * Module params @@ -46,7 +46,7 @@ MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery"); */ u32 bnad_rxqs_per_cq = 2; -const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* * Local MACROS @@ -687,7 +687,7 @@ bnad_enable_mbox_irq(struct bnad *bnad) * Called with bnad->bna_lock held b'cos of * bnad->cfg_flags access. */ -void +static void bnad_disable_mbox_irq(struct bnad *bnad) { int irq = BNAD_GET_MBOX_IRQ(bnad); @@ -956,11 +956,6 @@ bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); } -void -bnad_cb_stats_clr(struct bnad *bnad) -{ -} - /* Resource allocation, free functions */ static void @@ -1111,8 +1106,10 @@ bnad_mbox_irq_alloc(struct bnad *bnad, } spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) disable_irq_nosync(irq); + spin_unlock_irqrestore(&bnad->bna_lock, flags); return 0; } @@ -2243,7 +2240,6 @@ static void bnad_enable_msix(struct bnad *bnad) { int i, ret; - u32 tot_msix_num; unsigned long flags; spin_lock_irqsave(&bnad->bna_lock, flags); @@ -2256,18 +2252,16 @@ bnad_enable_msix(struct bnad *bnad) if (bnad->msix_table) return; - tot_msix_num = bnad->msix_num + bnad->msix_diag_num; - bnad->msix_table = - kcalloc(tot_msix_num, sizeof(struct msix_entry), GFP_KERNEL); + kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL); if (!bnad->msix_table) goto intx_mode; - for (i = 0; i < tot_msix_num; i++) + for (i = 0; i < bnad->msix_num; i++) bnad->msix_table[i].entry = i; - ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, tot_msix_num); + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num); if (ret > 0) { /* Not enough MSI-X vectors. */ @@ -2280,12 +2274,11 @@ bnad_enable_msix(struct bnad *bnad) + (bnad->num_rx * bnad->num_rxp_per_rx) + BNAD_MAILBOX_MSIX_VECTORS; - tot_msix_num = bnad->msix_num + bnad->msix_diag_num; /* Try once more with adjusted numbers */ /* If this fails, fall back to INTx */ ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, - tot_msix_num); + bnad->msix_num); if (ret) goto intx_mode; @@ -2298,7 +2291,6 @@ intx_mode: kfree(bnad->msix_table); bnad->msix_table = NULL; bnad->msix_num = 0; - bnad->msix_diag_num = 0; spin_lock_irqsave(&bnad->bna_lock, flags); bnad->cfg_flags &= ~BNAD_CF_MSIX; bnad_q_num_init(bnad); @@ -2946,7 +2938,6 @@ bnad_init(struct bnad *bnad, bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) + (bnad->num_rx * bnad->num_rxp_per_rx) + BNAD_MAILBOX_MSIX_VECTORS; - bnad->msix_diag_num = 2; /* 1 for Tx, 1 for Rx */ bnad->txq_depth = BNAD_TXQ_DEPTH; bnad->rxq_depth = BNAD_RXQ_DEPTH; @@ -3217,7 +3208,7 @@ bnad_pci_remove(struct pci_dev *pdev) free_netdev(netdev); } -const struct pci_device_id bnad_pci_id_table[] = { +static const struct pci_device_id bnad_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROCADE, PCI_DEVICE_ID_BROCADE_CT), diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index ee377888b905..ebc3a9078642 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -248,7 +248,6 @@ struct bnad { u64 mmio_len; u32 msix_num; - u32 msix_diag_num; struct msix_entry *msix_table; struct mutex conf_mutex; diff --git a/drivers/net/bna/cna_fwimg.c b/drivers/net/bna/cna_fwimg.c index 0bd1d3790a27..e8f4ecd9ebb5 100644 --- a/drivers/net/bna/cna_fwimg.c +++ b/drivers/net/bna/cna_fwimg.c @@ -22,7 +22,7 @@ const struct firmware *bfi_fw; static u32 *bfi_image_ct_cna; static u32 bfi_image_ct_cna_size; -u32 * +static u32 * cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, u32 *bfi_image_size, char *fw_name) { -- cgit v1.2.3 From 72645eff4b2ad6cf2b016b54f9d6817cca0a621d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 07:42:43 -0700 Subject: iwlwifi: schedule to deprecate software scan support Hardware scan is the prefer method for all iwlwifi devices; especially for dual-mode functions. Schedule to deprecate the software scan support in kernel 2.6.40 Signed-off-by: Wey-Yi Guy --- Documentation/feature-removal-schedule.txt | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 +++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index be7030e4dd73..cd89d1e5a6a8 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -563,3 +563,13 @@ Why: superseded by acpi_sleep=nonvs Who: Rafael J. Wysocki ---------------------------- + +What: iwlwifi disable_hw_scan module parameters +When: 2.6.40 +Why: Hareware scan is the prefer method for iwlwifi devices for + scanning operation. Remove software scan support for all the + iwlwifi devices. + +Who: Wey-Yi Guy + +---------------------------- diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e23c554b73a8..e7dc8b92db66 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4296,9 +4296,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. */ if (cfg->mod_params->disable_hw_scan) { - if (iwl_debug_level & IWL_DL_INFO) - dev_printk(KERN_DEBUG, &(pdev->dev), - "Disabling hw_scan\n"); + dev_printk(KERN_DEBUG, &(pdev->dev), + "sw scan support is deprecated\n"); iwl_hw_ops.hw_scan = NULL; } @@ -4905,7 +4904,8 @@ module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); module_param_named( disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 116777122a79..8b6aa3d38db0 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3966,7 +3966,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * "the hard way", rather than using device's scan. */ if (iwl3945_mod_params.disable_hw_scan) { - IWL_DEBUG_INFO(priv, "Disabling hw_scan\n"); + IWL_ERR(priv, "sw scan support is deprecated\n"); iwl3945_hw_ops.hw_scan = NULL; } @@ -4291,7 +4291,8 @@ MODULE_PARM_DESC(debug, "debug output mask"); #endif module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); -- cgit v1.2.3 From 7cb1b0887fcc61918e3d64827fbef968bb67a57a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 08:10:00 -0700 Subject: iwlagn: reduce redundant parameter definitions move paramater definitions to a device paramater structure only leaving the device name, which antennas are used and what firmware file to use in the iwl_cfg structure. this will not completely remove the redundancies but greatly reduce them for devices that only vary by name or antennas. the parameters that are more likely to change within a given device family are left in iwl_cfg. also separate bt param structure added to help reduce more. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 121 ++---- drivers/net/wireless/iwlwifi/iwl-3945.c | 43 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 47 +-- drivers/net/wireless/iwlwifi/iwl-5000.c | 191 +++------ drivers/net/wireless/iwlwifi/iwl-6000.c | 523 ++++++------------------- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 40 +- drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 12 +- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 5 +- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 27 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 11 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 33 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 19 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 5 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 43 +- drivers/net/wireless/iwlwifi/iwl-core.c | 95 +++-- drivers/net/wireless/iwlwifi/iwl-core.h | 129 +++--- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 58 +-- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 12 +- drivers/net/wireless/iwlwifi/iwl-led.c | 6 +- drivers/net/wireless/iwlwifi/iwl-power.c | 4 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 17 +- 24 files changed, 565 insertions(+), 887 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 19dbef06d52c..134f54541330 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -126,13 +126,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; @@ -250,29 +250,16 @@ static const struct iwl_ops iwl1000_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl1000_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", - .fw_name_pre = IWL1000_FW_PRE, - .ucode_api_max = IWL1000_UCODE_API_MAX, - .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, +static struct iwl_base_params iwl1000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, + .eeprom_size = OTP_LOW_IMAGE_SIZE, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, @@ -283,6 +270,26 @@ struct iwl_cfg iwl1000_bgn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, }; +static struct iwl_ht_params iwl1000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +struct iwl_cfg iwl1000_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", + .fw_name_pre = IWL1000_FW_PRE, + .ucode_api_max = IWL1000_UCODE_API_MAX, + .ucode_api_min = IWL1000_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, + .ops = &iwl1000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl1000_base_params, + .ht_params = &iwl1000_ht_params, +}; struct iwl_cfg iwl1000_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", @@ -290,30 +297,13 @@ struct iwl_cfg iwl1000_bg_cfg = { .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 128, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl1000_base_params, }; struct iwl_cfg iwl100_bgn_cfg = { @@ -322,32 +312,14 @@ struct iwl_cfg iwl100_bgn_cfg = { .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 128, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl1000_base_params, + .ht_params = &iwl1000_ht_params, }; struct iwl_cfg iwl100_bg_cfg = { @@ -356,30 +328,13 @@ struct iwl_cfg iwl100_bg_cfg = { .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_A, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 128, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl1000_base_params, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 5d09686c3389..cfdff5487e3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -406,7 +406,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, unsigned int plcp_msec; unsigned long plcp_received_jiffies; - if (priv->cfg->plcp_delta_threshold == + if (priv->cfg->base_params->plcp_delta_threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); return rc; @@ -432,7 +432,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, if ((combined_plcp_delta > 0) && ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->plcp_delta_threshold) { + priv->cfg->base_params->plcp_delta_threshold) { /* * if plcp_err exceed the threshold, the following * data is printed in csv format: @@ -444,7 +444,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, */ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " "%u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, + priv->cfg->base_params->plcp_delta_threshold, le32_to_cpu(current_stat.rx.ofdm.plcp_err), combined_plcp_delta, plcp_msec); /* @@ -2421,7 +2421,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) } /* Assign number of Usable TX queues */ - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); @@ -2722,22 +2722,12 @@ static const struct iwl_ops iwl3945_ops = { .led = &iwl3945_led_ops, }; -static struct iwl_cfg iwl3945_bg_cfg = { - .name = "3945BG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_G, +static struct iwl_base_params iwl3945_base_params = { .eeprom_size = IWL3945_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, - .num_of_queues = IWL39_NUM_QUEUES, - .mod_params = &iwl3945_mod_params, .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, .set_l0s = false, .use_bsm = true, .use_isr_legacy = true, - .ht_greenfield_support = false, .led_compensation = 64, .broken_powersave = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, @@ -2746,25 +2736,28 @@ static struct iwl_cfg iwl3945_bg_cfg = { .tx_power_by_driver = true, }; +static struct iwl_cfg iwl3945_bg_cfg = { + .name = "3945BG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, +}; + static struct iwl_cfg iwl3945_abg_cfg = { .name = "3945ABG", .fw_name_pre = IWL3945_FW_PRE, .ucode_api_max = IWL3945_UCODE_API_MAX, .ucode_api_min = IWL3945_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .eeprom_size = IWL3945_EEPROM_IMG_SIZE, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, .ops = &iwl3945_ops, - .num_of_queues = IWL39_NUM_QUEUES, .mod_params = &iwl3945_mod_params, - .use_isr_legacy = true, - .ht_greenfield_support = false, - .led_compensation = 64, - .broken_powersave = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 512, - .tx_power_by_driver = true, + .base_params = &iwl3945_base_params, }; DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 943a9c7bfa7f..834c2f9c15d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -647,13 +647,13 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwl4965_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWL4965_STATION_COUNT; @@ -1724,13 +1724,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWL49_FIRST_AMPDU_QUEUE, IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -1792,13 +1792,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, int ret; if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWL49_FIRST_AMPDU_QUEUE, IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -2302,26 +2302,14 @@ static const struct iwl_ops iwl4965_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl4965_agn_cfg = { - .name = "Intel(R) Wireless WiFi Link 4965AGN", - .fw_name_pre = IWL4965_FW_PRE, - .ucode_api_max = IWL4965_UCODE_API_MAX, - .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, +static struct iwl_base_params iwl4965_base_params = { .eeprom_size = IWL4965_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_4965_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &iwl4965_ops, .num_of_queues = IWL49_NUM_QUEUES, .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_ABC, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = true, .use_isr_legacy = true, - .ht_greenfield_support = false, .broken_powersave = true, .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, @@ -2333,6 +2321,21 @@ struct iwl_cfg iwl4965_agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, +}; + +struct iwl_cfg iwl4965_agn_cfg = { + .name = "Intel(R) Wireless WiFi Link 4965AGN", + .fw_name_pre = IWL4965_FW_PRE, + .ucode_api_max = IWL4965_UCODE_API_MAX, + .ucode_api_min = IWL4965_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_4965_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, + .ops = &iwl4965_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl4965_base_params, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 21b4b23368e6..1b25ad63b5c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -170,13 +170,13 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; @@ -217,13 +217,13 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; @@ -504,27 +504,14 @@ static const struct iwl_ops iwl5150_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl5300_agn_cfg = { - .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, +static struct iwl_base_params iwl5000_base_params = { .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, .use_bsm = false, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, @@ -534,6 +521,26 @@ struct iwl_cfg iwl5300_agn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, }; +static struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +struct iwl_cfg iwl5300_agn_cfg = { + .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", + .fw_name_pre = IWL5000_FW_PRE, + .ucode_api_max = IWL5000_UCODE_API_MAX, + .ucode_api_min = IWL5000_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_5000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, + .ops = &iwl5000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, +}; struct iwl_cfg iwl5100_bgn_cfg = { .name = "Intel(R) WiFi Link 5100 BGN", @@ -541,29 +548,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5100_abg_cfg = { @@ -572,27 +564,13 @@ struct iwl_cfg iwl5100_abg_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -601,29 +579,14 @@ struct iwl_cfg iwl5100_agn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -632,29 +595,14 @@ struct iwl_cfg iwl5350_agn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -663,29 +611,14 @@ struct iwl_cfg iwl5150_agn_cfg = { .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5150_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5150_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, .need_dc_calib = true, }; @@ -695,27 +628,13 @@ struct iwl_cfg iwl5150_abg_cfg = { .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl5150_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5150_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, .need_dc_calib = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 4d45932e901e..5866ad868c32 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -162,13 +162,13 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; @@ -466,30 +466,16 @@ static const struct iwl_ops iwl6000g2b_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl6000g2a_2agn_cfg = { - .name = "6000 Series 2x2 AGN Gen2a", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, +static struct iwl_base_params iwl6000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, .adv_thermal_throttle = true, @@ -501,29 +487,16 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, - .need_dc_calib = true, }; -struct iwl_cfg iwl6000g2a_2abg_cfg = { - .name = "6000 Series 2x2 ABG Gen2a", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, +static struct iwl_base_params iwl6050_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, @@ -531,11 +504,57 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, + .chain_noise_scale = 1500, .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 512, + .max_event_log_size = 1024, + .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, +}; + +static struct iwl_ht_params iwl6000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +static struct iwl_bt_params iwl6000_bt_params = { + .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, +}; + +struct iwl_cfg iwl6000g2a_2agn_cfg = { + .name = "6000 Series 2x2 AGN Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl6000g2a_2abg_cfg = { + .name = "6000 Series 2x2 ABG Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, .need_dc_calib = true, }; @@ -545,32 +564,13 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, .need_dc_calib = true, }; @@ -580,41 +580,18 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -623,39 +600,17 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -664,41 +619,18 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -707,39 +639,17 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -748,41 +658,18 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -791,39 +678,17 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, - .advanced_bt_coexist = true, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; /* @@ -835,35 +700,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6000i_2abg_cfg = { @@ -872,33 +717,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6000i_2bg_cfg = { @@ -907,33 +733,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -942,35 +749,14 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6050_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .ops = &iwl6000_ops, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, }; @@ -980,35 +766,14 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6050g2_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6050g2_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, }; @@ -1018,33 +783,13 @@ struct iwl_cfg iwl6050_2abg_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6050_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6050_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, .need_dc_calib = true, }; @@ -1054,35 +799,15 @@ struct iwl_cfg iwl6000_3agn_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 84ad62958535..4c5ab783737f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -631,7 +631,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> rx.general.common); ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); @@ -786,7 +787,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> rx.general.common); } else { @@ -801,7 +803,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(ctx->staging.channel); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { stat_band24 = !!(((struct iwl_bt_notif_statistics *) stat_resp)->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); @@ -861,16 +864,17 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) /* If this is the "chain_noise_num_beacons", determine: * 1) Disconnected antennas (using signal strengths) * 2) Differential gain (using silence noise) to balance receivers */ - if (data->beacon_count != priv->cfg->chain_noise_num_beacons) + if (data->beacon_count != + priv->cfg->base_params->chain_noise_num_beacons) return; /* Analyze signal for disconnected antenna */ - average_sig[0] = - (data->chain_signal_a) / priv->cfg->chain_noise_num_beacons; - average_sig[1] = - (data->chain_signal_b) / priv->cfg->chain_noise_num_beacons; - average_sig[2] = - (data->chain_signal_c) / priv->cfg->chain_noise_num_beacons; + average_sig[0] = data->chain_signal_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[1] = data->chain_signal_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[2] = data->chain_signal_c / + priv->cfg->base_params->chain_noise_num_beacons; if (average_sig[0] >= average_sig[1]) { max_average_sig = average_sig[0]; @@ -920,7 +924,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) * To be safe, simply mask out any chains that we know * are not on the device. */ - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ active_chains &= first_antenna(priv->hw_params.valid_rx_ant); } else @@ -967,12 +973,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) active_chains); /* Analyze noise for rx balance */ - average_noise[0] = - ((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons); - average_noise[1] = - ((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons); - average_noise[2] = - ((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons); + average_noise[0] = data->chain_noise_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[1] = data->chain_noise_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[2] = data->chain_noise_c / + priv->cfg->base_params->chain_noise_num_beacons; for (i = 0; i < NUM_RX_CHAINS; i++) { if (!(data->disconn_array[i]) && diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index 5391b4627397..a358d4334a1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -39,7 +39,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) flag = le32_to_cpu(priv->_agn.statistics_bt.flag); else flag = le32_to_cpu(priv->_agn.statistics.flag); @@ -88,7 +89,8 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { ofdm = &priv->_agn.statistics_bt.rx.ofdm; cck = &priv->_agn.statistics_bt.rx.cck; general = &priv->_agn.statistics_bt.rx.general.common; @@ -534,7 +536,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { tx = &priv->_agn.statistics_bt.tx; accum_tx = &priv->_agn.accum_statistics_bt.tx; delta_tx = &priv->_agn.delta_statistics_bt.tx; @@ -734,7 +737,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { general = &priv->_agn.statistics_bt.general.common; dbg = &priv->_agn.statistics_bt.general.common.dbg; div = &priv->_agn.statistics_bt.general.common.div; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index d86902b83630..9ca6c91eaae6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -137,7 +137,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, continue; } - delta_g = (priv->cfg->chain_noise_scale * + delta_g = (priv->cfg->base_params->chain_noise_scale * ((s32)average_noise[default_chain] - (s32)average_noise[i])) / 1500; @@ -222,7 +222,8 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, return; } - if (priv->cfg->use_rts_for_aggregation && + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation && info->flags & IEEE80211_TX_CTL_AMPDU) { *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; return; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index c92b2c0cbd91..a5dbfea1bfad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -59,7 +59,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv) int iwl_alloc_isr_ict(struct iwl_priv *priv) { - if (priv->cfg->use_isr_legacy) + if (priv->cfg->base_params->use_isr_legacy) return 0; /* allocate shrared data table */ priv->_agn.ict_tbl_vir = diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 299fd9d59604..29ed6049c0f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -422,7 +422,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, * notification again. */ if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && - priv->cfg->advanced_bt_coexist) { + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { IWL_WARN(priv, "receive reply tx with bt_kill\n"); } iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); @@ -589,7 +590,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { u32 address = eeprom_indirect_address(priv, offset); - BUG_ON(address >= priv->cfg->eeprom_size); + BUG_ON(address >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[address]; } @@ -637,7 +638,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ - if (!priv->cfg->use_isr_legacy) + if (!priv->cfg->base_params->use_isr_legacy) rb_timeout = RX_RB_TIMEOUT; if (priv->cfg->mod_params->amsdu_size_8K) @@ -1424,7 +1425,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) * Internal scans are passive, so we can indiscriminately set * the BT ignore flag on 2.4 GHz since it applies to TX only. */ - if (priv->cfg->advanced_bt_coexist) + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; break; @@ -1463,10 +1465,12 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->scan_tx_antennas[band]) scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ - scan_tx_antennas = - first_antenna(priv->cfg->scan_tx_antennas[band]); + scan_tx_antennas = first_antenna( + priv->cfg->scan_tx_antennas[band]); } priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], @@ -1487,7 +1491,9 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_ant = first_antenna(active_chains); } - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ rx_ant = first_antenna(rx_ant); } @@ -1777,7 +1783,10 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != sizeof(bt_cmd.bt3_lookup_table)); - bt_cmd.prio_boost = priv->cfg->bt_prio_boost; + if (priv->cfg->bt_params) + bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost; + else + bt_cmd.prio_boost = 0; bt_cmd.kill_ack_mask = priv->kill_ack_mask; bt_cmd.kill_cts_mask = priv->kill_cts_mask; bt_cmd.valid = priv->bt_valid; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 57629fba3a7d..f865685fd5f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2939,11 +2939,14 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, * overwrite if needed, pass aggregation time limit * to uCode in uSec */ - if (priv && priv->cfg->agg_time_limit && - priv->cfg->agg_time_limit >= LINK_QUAL_AGG_TIME_LIMIT_MIN && - priv->cfg->agg_time_limit <= LINK_QUAL_AGG_TIME_LIMIT_MAX) + if (priv && priv->cfg->bt_params && + priv->cfg->bt_params->agg_time_limit && + priv->cfg->bt_params->agg_time_limit >= + LINK_QUAL_AGG_TIME_LIMIT_MIN && + priv->cfg->bt_params->agg_time_limit <= + LINK_QUAL_AGG_TIME_LIMIT_MAX) lq_cmd->agg_params.agg_time_limit = - cpu_to_le16(priv->cfg->agg_time_limit); + cpu_to_le16(priv->cfg->bt_params->agg_time_limit); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 9490eced1198..1e08eb455474 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -73,7 +73,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) int bcn_silence_a, bcn_silence_b, bcn_silence_c; int last_rx_noise; - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) rx_info = &(priv->_agn.statistics_bt.rx.general.common); else rx_info = &(priv->_agn.statistics.rx.general); @@ -124,7 +125,8 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, struct statistics_general_common *general, *accum_general; struct statistics_tx *tx, *accum_tx; - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { prev_stats = (__le32 *)&priv->_agn.statistics_bt; accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; size = sizeof(struct iwl_bt_notif_statistics); @@ -183,7 +185,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, unsigned int plcp_msec; unsigned long plcp_received_jiffies; - if (priv->cfg->plcp_delta_threshold == + if (priv->cfg->base_params->plcp_delta_threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); return rc; @@ -205,7 +207,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, struct statistics_rx_phy *ofdm; struct statistics_rx_ht_phy *ofdm_ht; - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { ofdm = &pkt->u.stats_bt.rx.ofdm; ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; combined_plcp_delta = @@ -229,7 +232,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, if ((combined_plcp_delta > 0) && ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->plcp_delta_threshold) { + priv->cfg->base_params->plcp_delta_threshold) { /* * if plcp_err exceed the threshold, * the following data is printed in csv format: @@ -242,13 +245,13 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, * plcp_msec */ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); rc = false; } @@ -262,7 +265,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(struct iwl_bt_notif_statistics), @@ -300,7 +304,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, iwl_recover_from_statistics(priv, pkt); - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, sizeof(priv->_agn.statistics_bt)); else diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 07b2c6cadf51..0c6c4d969706 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -114,7 +114,7 @@ static bool iwl_within_ct_kill_margin(struct iwl_priv *priv) s32 temp = priv->temperature; /* degrees CELSIUS except specified */ bool within_margin = false; - if (priv->cfg->temperature_kelvin) + if (priv->cfg->base_params->temperature_kelvin) temp = KELVIN_TO_CELSIUS(priv->temperature); if (!priv->thermal_throttle.advanced_tt) @@ -591,7 +591,7 @@ static void iwl_bg_tt_work(struct work_struct *work) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (priv->cfg->temperature_kelvin) + if (priv->cfg->base_params->temperature_kelvin) temp = KELVIN_TO_CELSIUS(priv->temperature); if (!priv->thermal_throttle.advanced_tt) @@ -640,7 +640,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); - if (priv->cfg->adv_thermal_throttle) { + if (priv->cfg->base_params->adv_thermal_throttle) { IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * IWL_TI_STATE_MAX, GFP_KERNEL); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 5950184d9860..77753b72f236 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -224,13 +224,13 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int ret; if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || - (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWLAGN_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, IWLAGN_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -286,13 +286,13 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || - (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWLAGN_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_ERR(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, IWLAGN_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -350,7 +350,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, if (ieee80211_is_back_req(fc)) tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; else if (info->band == IEEE80211_BAND_2GHZ && - priv->cfg->advanced_bt_coexist && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc) || skb->protocol == cpu_to_be16(ETH_P_PAE))) @@ -444,7 +445,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ - if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, first_antenna(priv->hw_params.valid_tx_ant)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8bfb0495a76b..e1dd76267dca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -307,7 +307,8 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) goto restart; } - if (priv->cfg->advanced_bt_coexist) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { /* * Tell uCode we are ready to perform calibration * need to perform this before any calibration @@ -330,7 +331,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) { struct iwl_wimax_coex_cmd coex_cmd; - if (priv->cfg->support_wimax_coexist) { + if (priv->cfg->base_params->support_wimax_coexist) { /* UnMask wake up src at associated sleep */ coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e7dc8b92db66..080121d3a3ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2256,13 +2256,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (pieces.init_evtlog_size) priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12; else - priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.init_evtlog_size = + priv->cfg->base_params->max_event_log_size; priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr; priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr; if (pieces.inst_evtlog_size) priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; else - priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.inst_evtlog_size = + priv->cfg->base_params->max_event_log_size; priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; if (ucode_capa.pan) { @@ -2732,7 +2734,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); priv->thermal_throttle.ct_kill_toggle = false; - if (priv->cfg->support_ct_kill_exit) { + if (priv->cfg->base_params->support_ct_kill_exit) { adv_cmd.critical_temperature_enter = cpu_to_le32(priv->hw_params.ct_kill_threshold); adv_cmd.critical_temperature_exit = @@ -2776,9 +2778,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; - calib_cfg_cmd.ucd_calib_cfg.once.start = cfg; - calib_cfg_cmd.ucd_calib_cfg.once.send_res = 0; - calib_cfg_cmd.ucd_calib_cfg.flags = 0; + calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); return iwl_send_cmd(priv, &cmd); } @@ -2831,13 +2831,15 @@ static void iwl_alive_start(struct iwl_priv *priv) /* Enable timer to monitor the driver queues */ mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(priv->cfg->monitor_recover_period)); + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); } if (iwl_is_rfkill(priv)) return; - if (priv->cfg->advanced_bt_coexist) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; @@ -2877,7 +2879,8 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } - if (!priv->cfg->advanced_bt_coexist) { + if (priv->cfg->bt_params && + !priv->cfg->bt_params->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ priv->cfg->ops->hcmd->send_bt_config(priv); } @@ -2930,7 +2933,11 @@ static void __iwl_down(struct iwl_priv *priv) /* reset BT coex data */ priv->bt_status = 0; - priv->bt_traffic_load = priv->cfg->bt_init_traffic_load; + if (priv->cfg->bt_params) + priv->bt_traffic_load = + priv->cfg->bt_params->bt_init_traffic_load; + else + priv->bt_traffic_load = 0; priv->bt_sco_active = false; priv->bt_full_concurrent = false; priv->bt_ci_compliance = 0; @@ -3224,7 +3231,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { iwl_chain_noise_calibration(priv, (void *)&priv->_agn.statistics_bt); iwl_sensitivity_calibration(priv, @@ -3423,7 +3431,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT; - if (!priv->cfg->broken_powersave) + if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; @@ -3748,7 +3756,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) ret = 0; - if (priv->cfg->use_rts_for_aggregation) { + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation) { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; /* @@ -3762,7 +3771,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, } break; case IEEE80211_AMPDU_TX_OPERATIONAL: - if (priv->cfg->use_rts_for_aggregation) { + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation) { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; @@ -4080,7 +4090,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) priv->cfg->ops->lib->recover_from_tx_stall; } - if (!priv->cfg->use_isr_legacy) + if (!priv->cfg->base_params->use_isr_legacy) tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) iwl_irq_tasklet, (unsigned long)priv); else @@ -4165,7 +4175,8 @@ static int iwl_init_drv(struct iwl_priv *priv) iwl_init_scan_params(priv); /* init bt coex */ - if (priv->cfg->advanced_bt_coexist) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b7adcf87280d..95cbc55a7a65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -232,7 +232,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->ht_supported = true; - if (priv->cfg->ht_greenfield_support) + if (priv->cfg->ht_params && + priv->cfg->ht_params->ht_greenfield_support) ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; ht_info->cap |= IEEE80211_HT_CAP_SGI_20; max_bit_rate = MAX_BIT_RATE_20_MHZ; @@ -247,11 +248,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; - if (priv->cfg->ampdu_factor) - ht_info->ampdu_factor = priv->cfg->ampdu_factor; + if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor) + ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor; ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; - if (priv->cfg->ampdu_density) - ht_info->ampdu_density = priv->cfg->ampdu_density; + if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density) + ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density; ht_info->mcs.rx_mask[0] = 0xFF; if (rx_chains_num >= 2) @@ -850,8 +851,10 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); */ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { - if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || - priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { /* * only use chain 'A' in bt high traffic load or * full concurrency mode @@ -919,8 +922,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else active_chains = priv->hw_params.valid_rx_ant; - if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent || - priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { /* * only use chain 'A' in bt high traffic load or * full concurrency mode @@ -1362,7 +1367,7 @@ int iwl_apm_init(struct iwl_priv *priv) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (priv->cfg->set_l0s) { + if (priv->cfg->base_params->set_l0s) { lctl = iwl_pcie_link_ctl(priv); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { @@ -1379,8 +1384,9 @@ int iwl_apm_init(struct iwl_priv *priv) } /* Configure analog phase-lock-loop before activating to D0A */ - if (priv->cfg->pll_cfg_val) - iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val); + if (priv->cfg->base_params->pll_cfg_val) + iwl_set_bit(priv, CSR_ANA_PLL_CFG, + priv->cfg->base_params->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from @@ -1411,7 +1417,7 @@ int iwl_apm_init(struct iwl_priv *priv) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (priv->cfg->use_bsm) + if (priv->cfg->base_params->use_bsm) iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); else @@ -2054,7 +2060,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out_err; } - if (priv->cfg->advanced_bt_coexist && + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && vif->type == NL80211_IFTYPE_ADHOC) { /* * pretend to have high BT traffic as long as we @@ -2317,7 +2324,8 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) { if (!priv->txq) priv->txq = kzalloc( - sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, + sizeof(struct iwl_tx_queue) * + priv->cfg->base_params->num_of_queues, GFP_KERNEL); if (!priv->txq) { IWL_ERR(priv, "Not enough memory for txq\n"); @@ -2828,33 +2836,34 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) txq = &priv->txq[cnt]; q = &txq->q; /* queue is empty, skip */ - if (q->read_ptr != q->write_ptr) { - if (q->read_ptr == q->last_read_ptr) { - /* a queue has not been read from last time */ - if (q->repeat_same_read_ptr > MAX_REPEAT) { - IWL_ERR(priv, - "queue %d stuck %d time. Fw reload.\n", - q->id, q->repeat_same_read_ptr); - q->repeat_same_read_ptr = 0; - iwl_force_reset(priv, IWL_FW_RESET, false); - } else { - q->repeat_same_read_ptr++; - IWL_DEBUG_RADIO(priv, - "queue %d, not read %d time\n", - q->id, - q->repeat_same_read_ptr); - if (!priv->cfg->advanced_bt_coexist) { - mod_timer(&priv->monitor_recover, - jiffies + msecs_to_jiffies( - IWL_ONE_HUNDRED_MSECS)); - return 1; - } - } - return 0; - } else { - q->last_read_ptr = q->read_ptr; + if (q->read_ptr == q->write_ptr) + return 0; + + if (q->read_ptr == q->last_read_ptr) { + /* a queue has not been read from last time */ + if (q->repeat_same_read_ptr > MAX_REPEAT) { + IWL_ERR(priv, + "queue %d stuck %d time. Fw reload.\n", + q->id, q->repeat_same_read_ptr); q->repeat_same_read_ptr = 0; + iwl_force_reset(priv, IWL_FW_RESET, false); + } else { + q->repeat_same_read_ptr++; + IWL_DEBUG_RADIO(priv, + "queue %d, not read %d time\n", + q->id, + q->repeat_same_read_ptr); + if (priv->cfg->bt_params && + !priv->cfg->bt_params->advanced_bt_coexist) { + mod_timer(&priv->monitor_recover, + jiffies + msecs_to_jiffies( + IWL_ONE_HUNDRED_MSECS)); + return 1; + } } + } else { + q->last_read_ptr = q->read_ptr; + q->repeat_same_read_ptr = 0; } return 0; } @@ -2881,13 +2890,13 @@ void iwl_bg_monitor_recover(unsigned long data) return; } } - if (priv->cfg->monitor_recover_period) { + if (priv->cfg->base_params->monitor_recover_period) { /* * Reschedule the timer to occur in - * priv->cfg->monitor_recover_period + * priv->cfg->base_params->monitor_recover_period */ mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( - priv->cfg->monitor_recover_period)); + priv->cfg->base_params->monitor_recover_period)); } } EXPORT_SYMBOL(iwl_bg_monitor_recover); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5daa1893fd03..6228b1c2ec96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -255,20 +255,12 @@ struct iwl_mod_params { int restart_fw; /* def: 1 = restart firmware */ }; -/** - * struct iwl_cfg - * @fw_name_pre: Firmware filename prefix. The api version and extension - * (.ucode) will be added to filename before loading from disk. The - * filename is constructed as fw_name_pre.ucode. - * @ucode_api_max: Highest version of uCode API supported by driver. - * @ucode_api_min: Lowest version of uCode API supported by driver. - * @pa_type: used by 6000 series only to identify the type of Power Amplifier +/* * @max_ll_items: max number of OTP blocks * @shadow_ram_support: shadow support for OTP memory * @led_compensation: compensate on the led on/off time per HW according * to the deviation to achieve the desired led frequency. * The detail algorithm is described in iwl-led.c - * @use_rts_for_aggregation: use rts/cts protection for HT traffic * @chain_noise_num_beacons: number of beacons used to compute chain noise * @adv_thermal_throttle: support advance thermal throttle * @support_ct_kill_exit: support ct kill exit condition @@ -286,15 +278,73 @@ struct iwl_mod_params { * sensitivity calibration operation * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation - * @scan_antennas: available antenna for scan operation +*/ +struct iwl_base_params { + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues;/* def: HW dependent */ + /* for iwl_apm_init() */ + u32 pll_cfg_val; + bool set_l0s; + bool use_bsm; + + bool use_isr_legacy; + const u16 max_ll_items; + const bool shadow_ram_support; + u16 led_compensation; + const bool broken_powersave; + int chain_noise_num_beacons; + const bool supports_idle; + bool adv_thermal_throttle; + bool support_ct_kill_exit; + const bool support_wimax_coexist; + u8 plcp_delta_threshold; + s32 chain_noise_scale; + /* timer period for monitor the driver queues */ + u32 monitor_recover_period; + bool temperature_kelvin; + u32 max_event_log_size; + const bool tx_power_by_driver; + const bool ucode_tracing; + const bool sensitivity_calib_by_driver; + const bool chain_noise_calib_by_driver; +}; +/* * @advanced_bt_coexist: support advanced bt coexist * @bt_init_traffic_load: specify initial bt traffic load * @bt_prio_boost: default bt priority boost value - * @need_dc_calib: need to perform init dc calibration * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation * @ampdu_factor: Maximum A-MPDU length factor * @ampdu_density: Minimum A-MPDU spacing +*/ +struct iwl_bt_params { + bool advanced_bt_coexist; + u8 bt_init_traffic_load; + u8 bt_prio_boost; + const bool bt_statistics; + u16 agg_time_limit; + u8 ampdu_factor; + u8 ampdu_density; +}; +/* + * @use_rts_for_aggregation: use rts/cts protection for HT traffic +*/ +struct iwl_ht_params { + const bool ht_greenfield_support; /* if used set to true */ + bool use_rts_for_aggregation; +}; + +/** + * struct iwl_cfg + * @fw_name_pre: Firmware filename prefix. The api version and extension + * (.ucode) will be added to filename before loading from disk. The + * filename is constructed as fw_name_pre.ucode. + * @ucode_api_max: Highest version of uCode API supported by driver. + * @ucode_api_min: Lowest version of uCode API supported by driver. + * @pa_type: used by 6000 series only to identify the type of Power Amplifier + * @need_dc_calib: need to perform init dc calibration + * @scan_antennas: available antenna for scan operation * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -305,9 +355,9 @@ struct iwl_mod_params { * * For example, * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { - * Driver interacts with Firmware API version >= 2. + * Driver interacts with Firmware API version >= 2. * } else { - * Driver interacts with Firmware API version 1. + * Driver interacts with Firmware API version 1. * } * * The ideal usage of this infrastructure is to treat a new ucode API @@ -318,59 +368,28 @@ struct iwl_mod_params { * */ struct iwl_cfg { + /* params specific to an individual device within a device family */ const char *name; const char *fw_name_pre; const unsigned int ucode_api_max; const unsigned int ucode_api_min; + u8 valid_tx_ant; + u8 valid_rx_ant; unsigned int sku; - int eeprom_size; u16 eeprom_ver; u16 eeprom_calib_ver; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues;/* def: HW dependent */ const struct iwl_ops *ops; + /* module based parameters which can be set from modprobe cmd */ const struct iwl_mod_params *mod_params; - u8 valid_tx_ant; - u8 valid_rx_ant; - - /* for iwl_apm_init() */ - u32 pll_cfg_val; - bool set_l0s; - bool use_bsm; - - bool use_isr_legacy; - enum iwl_pa_type pa_type; - const u16 max_ll_items; - const bool shadow_ram_support; - const bool ht_greenfield_support; - u16 led_compensation; - const bool broken_powersave; - bool use_rts_for_aggregation; - int chain_noise_num_beacons; - const bool supports_idle; - bool adv_thermal_throttle; - bool support_ct_kill_exit; - const bool support_wimax_coexist; - u8 plcp_delta_threshold; - s32 chain_noise_scale; - /* timer period for monitor the driver queues */ - u32 monitor_recover_period; - bool temperature_kelvin; - u32 max_event_log_size; - const bool tx_power_by_driver; - const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; + /* params not likely to change within a device family */ + struct iwl_base_params *base_params; + /* params likely to change within a device family */ + struct iwl_ht_params *ht_params; + struct iwl_bt_params *bt_params; + enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ + const bool need_dc_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; - bool advanced_bt_coexist; - u8 bt_init_traffic_load; - u8 bt_prio_boost; - const bool need_dc_calib; - const bool bt_statistics; - u16 agg_time_limit; - u8 ampdu_factor; - u8 ampdu_density; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 265ad01a443f..fc340311ea0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -356,7 +356,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, const u8 *ptr; char *buf; u16 eeprom_ver; - size_t eeprom_len = priv->cfg->eeprom_size; + size_t eeprom_len = priv->cfg->base_params->eeprom_size; buf_size = 4 * eeprom_len + 256; if (eeprom_len % 16) { @@ -872,7 +872,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, struct iwl_rx_queue *rxq = &priv->rxq; char *buf; int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (priv->cfg->num_of_queues * 32 * 8) + 400; + (priv->cfg->base_params->num_of_queues * 32 * 8) + 400; const u8 *ptr; ssize_t ret; @@ -971,7 +971,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, int pos = 0; int cnt; int ret; - const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; + const size_t bufsz = sizeof(char) * 64 * + priv->cfg->base_params->num_of_queues; if (!priv->txq) { IWL_ERR(priv, "txq not ready\n"); @@ -1415,7 +1416,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, const size_t bufsz = sizeof(buf); pos += scnprintf(buf + pos, bufsz - pos, "%u\n", - priv->cfg->plcp_delta_threshold); + priv->cfg->base_params->plcp_delta_threshold); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1437,10 +1438,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, return -EINVAL; if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) - priv->cfg->plcp_delta_threshold = + priv->cfg->base_params->plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; else - priv->cfg->plcp_delta_threshold = plcp; + priv->cfg->base_params->plcp_delta_threshold = plcp; return count; } @@ -1550,13 +1551,14 @@ static ssize_t iwl_dbgfs_monitor_period_write(struct file *file, if (sscanf(buf, "%d", &period) != 1) return -EINVAL; if (period < 0 || period > IWL_MAX_MONITORING_PERIOD) - priv->cfg->monitor_recover_period = IWL_DEF_MONITORING_PERIOD; + priv->cfg->base_params->monitor_recover_period = + IWL_DEF_MONITORING_PERIOD; else - priv->cfg->monitor_recover_period = period; + priv->cfg->base_params->monitor_recover_period = period; - if (priv->cfg->monitor_recover_period) + if (priv->cfg->base_params->monitor_recover_period) mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( - priv->cfg->monitor_recover_period)); + priv->cfg->base_params->monitor_recover_period)); else del_timer_sync(&priv->monitor_recover); return count; @@ -1614,9 +1616,14 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, char buf[40]; const size_t bufsz = sizeof(buf); - pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", - (priv->cfg->use_rts_for_aggregation) ? "rts/cts" : - "cts-to-self"); + if (priv->cfg->ht_params) + pos += scnprintf(buf + pos, bufsz - pos, + "use %s for aggregation\n", + (priv->cfg->ht_params->use_rts_for_aggregation) ? + "rts/cts" : "cts-to-self"); + else + pos += scnprintf(buf + pos, bufsz - pos, "N/A"); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1629,6 +1636,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, int buf_size; int rts; + if (!priv->cfg->ht_params) + return -EINVAL; + memset(buf, 0, sizeof(buf)); buf_size = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, buf_size)) @@ -1636,9 +1646,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, if (sscanf(buf, "%d", &rts) != 1) return -EINVAL; if (rts) - priv->cfg->use_rts_for_aggregation = true; + priv->cfg->ht_params->use_rts_for_aggregation = true; else - priv->cfg->use_rts_for_aggregation = false; + priv->cfg->ht_params->use_rts_for_aggregation = false; return count; } @@ -1716,7 +1726,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); - if (!priv->cfg->broken_powersave) { + if (!priv->cfg->base_params->broken_powersave) { DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); @@ -1743,27 +1753,27 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->sensitivity_calib_by_driver) + if (priv->cfg->base_params->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (priv->cfg->chain_noise_calib_by_driver) + if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); - if (priv->cfg->ucode_tracing) + if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics) DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); - if (priv->cfg->advanced_bt_coexist) + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); - if (priv->cfg->sensitivity_calib_by_driver) + if (priv->cfg->base_params->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); - if (priv->cfg->chain_noise_calib_by_driver) + if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &priv->disable_chain_noise_cal); - if (priv->cfg->tx_power_by_driver) + if (priv->cfg->base_params->tx_power_by_driver) DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &priv->disable_tx_power_cal); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index a45d02e555cf..88f4a80d4733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -332,7 +332,7 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { - BUG_ON(offset >= priv->cfg->eeprom_size); + BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; } EXPORT_SYMBOL(iwlcore_eeprom_query_addr); @@ -364,7 +364,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv) * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (priv->cfg->shadow_ram_support) + if (priv->cfg->base_params->shadow_ram_support) iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } @@ -484,7 +484,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= priv->cfg->max_ll_items); + } while (usedblocks <= priv->cfg->base_params->max_ll_items); /* OTP has no valid blocks */ IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); @@ -512,8 +512,8 @@ int iwl_eeprom_init(struct iwl_priv *priv) if (priv->nvm_device_type == -ENOENT) return -ENOENT; /* allocate eeprom */ - IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size); - sz = priv->cfg->eeprom_size; + sz = priv->cfg->base_params->eeprom_size; + IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz); priv->eeprom = kzalloc(sz, GFP_KERNEL); if (!priv->eeprom) { ret = -ENOMEM; @@ -554,7 +554,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!priv->cfg->shadow_ram_support) { + if (!priv->cfg->base_params->shadow_ram_support) { if (iwl_find_otp_image(priv, &validblockaddr)) { ret = -ENOENT; goto done; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index db5bfcb036ca..86c2b6fed0c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -108,13 +108,13 @@ static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) BUG_ON(idx > IWL_MAX_BLINK_TBL); IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); led_cmd.on = iwl_blink_compensation(priv, blink_tbl[idx].on_time, - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); led_cmd.off = iwl_blink_compensation(priv, blink_tbl[idx].off_time, - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); return priv->cfg->ops->led->cmd(priv, &led_cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 63c0ab46261f..49d7788937a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -278,9 +278,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->cfg->broken_powersave) + if (priv->cfg->base_params->broken_powersave) iwl_power_sleep_cam_cmd(priv, &cmd); - else if (priv->cfg->supports_idle && + else if (priv->cfg->base_params->supports_idle && priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index c54c20023e7c..eaae49ee0c60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -259,7 +259,8 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, queue_work(priv->workqueue, &priv->scan_completed); if (priv->iw_mode != NL80211_IFTYPE_ADHOC && - priv->cfg->advanced_bt_coexist && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && priv->bt_status != scan_notif->bt_status) { if (scan_notif->bt_status) { /* BT on */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8b6aa3d38db0..43db5f38e3e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1581,16 +1581,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); - if (capacity > priv->cfg->max_event_log_size) { + if (capacity > priv->cfg->base_params->max_event_log_size) { IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->max_event_log_size); - capacity = priv->cfg->max_event_log_size; + capacity, priv->cfg->base_params->max_event_log_size); + capacity = priv->cfg->base_params->max_event_log_size; } - if (next_entry > priv->cfg->max_event_log_size) { + if (next_entry > priv->cfg->base_params->max_event_log_size) { IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->max_event_log_size); - next_entry = priv->cfg->max_event_log_size; + next_entry, priv->cfg->base_params->max_event_log_size); + next_entry = priv->cfg->base_params->max_event_log_size; } size = num_wraps ? capacity : next_entry; @@ -2519,7 +2519,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv) /* Enable timer to monitor the driver queues */ mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(priv->cfg->monitor_recover_period)); + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); } if (iwl_is_rfkill(priv)) @@ -3881,7 +3882,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; - if (!priv->cfg->broken_powersave) + if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; -- cgit v1.2.3 From ab63c68adaabb670f0513d5b63f3b233b16ea8b4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 20 Sep 2010 09:12:31 -0700 Subject: iwlagn: rename iwl5000_tx_power_dbm_cmd iwl5000_tx_power_dbm_cmd really should be iwlagn_tx_power_dbm_cmd, so rename it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-commands.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 29ed6049c0f7..48c48f1fac37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -491,7 +491,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr) int iwlagn_send_tx_power(struct iwl_priv *priv) { - struct iwl5000_tx_power_dbm_cmd tx_power_cmd; + struct iwlagn_tx_power_dbm_cmd tx_power_cmd; u8 tx_ant_cfg_cmd; /* half dBm need to multiply */ @@ -512,8 +512,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) */ tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; } - tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; - tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; + tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; + tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; if (IWL_UCODE_API(priv->ucode_ver) == 1) tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 27350eebb132..16dda2dce615 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -420,12 +420,12 @@ struct iwl4965_tx_power_db { /** * Command REPLY_TX_POWER_DBM_CMD = 0x98 - * struct iwl5000_tx_power_dbm_cmd + * struct iwlagn_tx_power_dbm_cmd */ -#define IWL50_TX_POWER_AUTO 0x7f -#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6) +#define IWLAGN_TX_POWER_AUTO 0x7f +#define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6) -struct iwl5000_tx_power_dbm_cmd { +struct iwlagn_tx_power_dbm_cmd { s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ u8 flags; s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ -- cgit v1.2.3 From a8029bb79ec6de4acab5a6d3b931990152e8d5c1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 20 Sep 2010 09:12:32 -0700 Subject: iwlwifi: remove uncorrect comments some structure belong to _agn devices, not just 5000. Fix it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 16dda2dce615..953e536fe072 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1042,7 +1042,7 @@ struct iwl4965_keyinfo { u8 key[16]; /* 16-byte unicast decryption key */ } __packed; -/* 5000 */ +/* agn */ struct iwl_keyinfo { __le16 key_flags; u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ @@ -1168,7 +1168,7 @@ struct iwl4965_addsta_cmd { __le16 reserved2; } __packed; -/* 5000 */ +/* agn */ struct iwl_addsta_cmd { u8 mode; /* 1: modify existing, 0: add new station */ u8 reserved[3]; -- cgit v1.2.3 From 898dade1162970fe7af45e47062f9d1d999c46e6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 20 Sep 2010 09:12:33 -0700 Subject: iwlagn: rename iwl5000_tx_resp iwl5000_tx_resp really should be iwlagn_tx_resp, rename it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 14 ++++++++------ drivers/net/wireless/iwlwifi/iwl-commands.h | 10 +++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 48c48f1fac37..f5445d575fec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -40,7 +40,7 @@ #include "iwl-agn.h" #include "iwl-sta.h" -static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) +static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp) { return le32_to_cpup((__le32 *)&tx_resp->status + tx_resp->frame_count) & MAX_SN; @@ -172,7 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, - struct iwl5000_tx_resp *tx_resp, + struct iwlagn_tx_resp *tx_resp, int txq_id, bool is_agg) { u16 status = le16_to_cpu(tx_resp->status.status); @@ -223,7 +223,7 @@ const char *iwl_get_agg_tx_fail_reason(u16 status) static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, - struct iwl5000_tx_resp *tx_resp, + struct iwlagn_tx_resp *tx_resp, int txq_id, u16 start_idx) { u16 status; @@ -390,7 +390,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, int index = SEQ_TO_INDEX(sequence); struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_info *info; - struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le16_to_cpu(tx_resp->status.status); int tid; int sta_id; @@ -408,8 +408,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); - tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; - sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; + tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> + IWLAGN_TX_RES_TID_POS; + sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> + IWLAGN_TX_RES_RA_POS; spin_lock_irqsave(&priv->sta_lock, flags); if (txq->sched_retry) { diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 953e536fe072..fe652568fec7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1959,12 +1959,12 @@ struct iwl4965_tx_resp { #define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 /* refer to ra_tid */ -#define IWL50_TX_RES_TID_POS 0 -#define IWL50_TX_RES_TID_MSK 0x0f -#define IWL50_TX_RES_RA_POS 4 -#define IWL50_TX_RES_RA_MSK 0xf0 +#define IWLAGN_TX_RES_TID_POS 0 +#define IWLAGN_TX_RES_TID_MSK 0x0f +#define IWLAGN_TX_RES_RA_POS 4 +#define IWLAGN_TX_RES_RA_MSK 0xf0 -struct iwl5000_tx_resp { +struct iwlagn_tx_resp { u8 frame_count; /* 1 no aggregation, >1 aggregation */ u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ u8 failure_rts; /* # failures due to unsuccessful RTS */ -- cgit v1.2.3 From 58a39090a13cf296afc17ed8fd793a55340b63db Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 08:14:21 -0700 Subject: iwlagn: define 130 series of WiFi/BT combo devices add new structures and defines need to identify 130 devices. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 44 +++++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ 3 files changed, 56 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 5866ad868c32..43ec8988feb0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,11 +53,13 @@ #define IWL6000_UCODE_API_MAX 4 #define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 5 +#define IWL130_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 #define IWL6000G2_UCODE_API_MIN 4 +#define IWL130_UCODE_API_MIN 5 #define IWL6000_FW_PRE "iwlwifi-6000-" #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" @@ -75,6 +77,9 @@ #define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" #define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) +#define IWL130_FW_PRE "iwlwifi-130-" +#define _IWL100_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode" +#define IWL100_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api) static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { @@ -810,6 +815,45 @@ struct iwl_cfg iwl6000_3agn_cfg = { .need_dc_calib = true, }; +struct iwl_cfg iwl130_bgn_cfg = { + .name = "Intel(R) 130 Series 1x1 BGN", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL130_UCODE_API_MAX, + .ucode_api_min = IWL130_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000g2b_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, +}; + +struct iwl_cfg iwl130_bg_cfg = { + .name = "Intel(R) 130 Series 1x2 BG", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL130_UCODE_API_MAX, + .ucode_api_min = IWL130_UCODE_API_MIN, + .sku = IWL_SKU_G, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000g2b_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, + .bt_params = &iwl6000_bt_params, + .need_dc_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, +}; + MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 080121d3a3ae..a6dce616ee3c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4822,11 +4822,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, +/* 100 Series WiFi */ {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)}, + +/* 130 Series WiFi */ + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, + #endif /* CONFIG_IWL5000 */ {0} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d5dc824ebbfb..eb3812a35862 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -94,6 +94,8 @@ extern struct iwl_cfg iwl1000_bgn_cfg; extern struct iwl_cfg iwl1000_bg_cfg; extern struct iwl_cfg iwl100_bgn_cfg; extern struct iwl_cfg iwl100_bg_cfg; +extern struct iwl_cfg iwl130_bgn_cfg; +extern struct iwl_cfg iwl130_bg_cfg; extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; -- cgit v1.2.3 From 6497827f53eb90dcf30c5d6414c83238f722e8ae Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 3 Oct 2010 19:07:16 +0200 Subject: ath9k_hw: clean up calibration flags The calibration actual calibration flags are only used by the per chip family source files, so it makes more sense to define them in those files instead of globally. That way the code has to test for less flags. Also instead of using a separate callback for testing whether a particular calibration type is supported, simply adjust ah->supp_cals in the calibration init which is called right after the hardware reset, before any of the calibrations are run. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 51 +++++++++++---------------- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 36 +++++-------------- drivers/net/wireless/ath/ath9k/calib.c | 2 +- drivers/net/wireless/ath/ath9k/calib.h | 9 +---- drivers/net/wireless/ath/ath9k/hw-ops.h | 6 ---- drivers/net/wireless/ath/ath9k/hw.h | 4 +-- 6 files changed, 31 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index f2da119bbf02..f0525fb62a2c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -20,6 +20,13 @@ #define AR9285_CLCAL_REDO_THRESH 1 +enum ar9002_cal_types { + ADC_GAIN_CAL = BIT(0), + ADC_DC_CAL = BIT(1), + IQ_MISMATCH_CAL = BIT(2), +}; + + static void ar9002_hw_setup_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal) { @@ -45,8 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting ADC DC Calibration\n"); break; - case TEMP_COMP_CAL: - break; /* Not supported */ } REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), @@ -91,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah, return iscaldone; } -/* Assumes you are talking about the currently configured channel */ -static bool ar9002_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - - switch (calType & ah->supp_cals) { - case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ - return true; - case ADC_GAIN_CAL: - case ADC_DC_CAL: - if (!(conf->channel->band == IEEE80211_BAND_2GHZ && - conf_is_ht20(conf))) - return true; - break; - } - return false; -} - static void ar9002_hw_iqcal_collect(struct ath_hw *ah) { int i; @@ -872,24 +858,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) /* Enable IQ, ADC Gain and ADC DC offset CALs */ if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { - if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) { + ah->supp_cals = IQ_MISMATCH_CAL; + + if (AR_SREV_9160_10_OR_LATER(ah) && + !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) { + ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; + + INIT_CAL(&ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling ADC Gain Calibration.\n"); - } - if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) { + INIT_CAL(&ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling ADC DC Calibration.\n"); } - if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { - INIT_CAL(&ah->iq_caldata); - INSERT_CAL(ah, &ah->iq_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); - } + + INIT_CAL(&ah->iq_caldata); + INSERT_CAL(ah, &ah->iq_caldata); + ath_print(common, ATH_DBG_CALIBRATE, + "enabling IQ Calibration.\n"); ah->cal_list_curr = ah->cal_list; @@ -980,7 +970,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah) priv_ops->init_cal_settings = ar9002_hw_init_cal_settings; priv_ops->init_cal = ar9002_hw_init_cal; priv_ops->setup_calibration = ar9002_hw_setup_calibration; - priv_ops->iscal_supported = ar9002_hw_iscal_supported; ops->calibrate = ar9002_hw_calibrate; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index b41f5cda824b..9e6edffe0bd1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -18,6 +18,11 @@ #include "hw-ops.h" #include "ar9003_phy.h" +enum ar9003_cal_types { + IQ_MISMATCH_CAL = BIT(0), + TEMP_COMP_CAL = BIT(1), +}; + static void ar9003_hw_setup_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal) { @@ -50,10 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting Temperature Compensation Calibration\n"); break; - case ADC_GAIN_CAL: - case ADC_DC_CAL: - /* Not yet */ - break; } } @@ -313,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = { static void ar9003_hw_init_cal_settings(struct ath_hw *ah) { ah->iq_caldata.calData = &iq_cal_single_sample; - ah->supp_cals = IQ_MISMATCH_CAL; -} - -static bool ar9003_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - switch (calType & ah->supp_cals) { - case IQ_MISMATCH_CAL: - /* - * XXX: Run IQ Mismatch for non-CCK only - * Note that CHANNEL_B is never set though. - */ - return true; - case ADC_GAIN_CAL: - case ADC_DC_CAL: - return false; - case TEMP_COMP_CAL: - return true; - } - - return false; } /* @@ -772,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + ah->supp_cals = IQ_MISMATCH_CAL; - if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { + if (ah->supp_cals & IQ_MISMATCH_CAL) { INIT_CAL(&ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling IQ Calibration.\n"); } - if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) { + if (ah->supp_cals & TEMP_COMP_CAL) { INIT_CAL(&ah->tempCompCalData); INSERT_CAL(ah, &ah->tempCompCalData); ath_print(common, ATH_DBG_CALIBRATE, @@ -807,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah) priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; priv_ops->init_cal = ar9003_hw_init_cal; priv_ops->setup_calibration = ar9003_hw_setup_calibration; - priv_ops->iscal_supported = ar9003_hw_iscal_supported; ops->calibrate = ar9003_hw_calibrate; } diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 6351e76792a6..6c38c72915c1 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -186,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) return true; } - if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) + if (!(ah->supp_cals & currCal->calData->calType)) return true; ath_print(common, ATH_DBG_CALIBRATE, diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 1fa56c91a894..b8973eb8d858 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -58,13 +58,6 @@ struct ar5416IniArray { } \ } while (0) -enum ath9k_cal_types { - ADC_GAIN_CAL = 0x2, - ADC_DC_CAL = 0x4, - IQ_MISMATCH_CAL = 0x8, - TEMP_COMP_CAL = 0x10, -}; - enum ath9k_cal_state { CAL_INACTIVE, CAL_WAITING, @@ -79,7 +72,7 @@ enum ath9k_cal_state { #define PER_MAX_LOG_COUNT 10 struct ath9k_percal_data { - enum ath9k_cal_types calType; + u32 calType; u32 calNumSamples; u32 calCountMax; void (*calCollect) (struct ath_hw *); diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index ffecbadaea4a..9c4dd0ec9a15 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -276,12 +276,6 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah, ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); } -static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType); -} - static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) { ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 235cb5357a22..246c707cea00 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -535,8 +535,6 @@ struct ath_hw_private_ops { bool (*macversion_supported)(u32 macversion); void (*setup_calibration)(struct ath_hw *ah, struct ath9k_cal_list *currCal); - bool (*iscal_supported)(struct ath_hw *ah, - enum ath9k_cal_types calType); /* PHY ops */ int (*rf_set_freq)(struct ath_hw *ah, @@ -689,7 +687,7 @@ struct ath_hw { u32 atim_window; /* Calibration */ - enum ath9k_cal_types supp_cals; + u32 supp_cals; struct ath9k_cal_list iq_caldata; struct ath9k_cal_list adcgain_caldata; struct ath9k_cal_list adcdc_caldata; -- cgit v1.2.3 From 9dbebc7fd07ab66341dce8d001272db400c11e03 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 3 Oct 2010 19:07:17 +0200 Subject: ath9k_hw: merge codepaths that access the cycle counter registers The cycle counters are used by ANI to determine the amount of time that the radio spent not receiving or transmitting. They're also used for debugging purposes if the baseband watchdog on AR9003 detects a lockup. In the future, we want to use these counters to determine the medium utilization and export this information via survey. For that, we need to make sure that the counter is only accessed from one place, which also ensures that wraparounds won't occur at inconvenient points in time. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 119 +++++++++++----------------- drivers/net/wireless/ath/ath9k/ani.h | 13 +-- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 +-- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 14 ++-- drivers/net/wireless/ath/ath9k/hw.h | 2 + 5 files changed, 65 insertions(+), 92 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 45f477ad7608..3fba81e3a61f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -549,47 +549,15 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) { - struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - u32 txFrameCount, rxFrameCount, cycleCount; - int32_t listenTime; - - txFrameCount = REG_READ(ah, AR_TFCNT); - rxFrameCount = REG_READ(ah, AR_RFCNT); - cycleCount = REG_READ(ah, AR_CCCNT); - - aniState = ah->curani; - if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { - listenTime = 0; - ah->stats.ast_ani_lzero++; - ath_print(common, ATH_DBG_ANI, - "1st call: aniState->cycleCount=%d\n", - aniState->cycleCount); - } else { - int32_t ccdelta = cycleCount - aniState->cycleCount; - int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; - int32_t tfdelta = txFrameCount - aniState->txFrameCount; - int32_t clock_rate; - - /* - * convert HW counter values to ms using mode - * specifix clock rate - */ - clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;; + int32_t listen_time; + int32_t clock_rate; - listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate; + ath9k_hw_update_cycle_counters(ah); + clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000; + listen_time = ah->listen_time / clock_rate; + ah->listen_time = 0; - ath_print(common, ATH_DBG_ANI, - "cyclecount=%d, rfcount=%d, " - "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n", - ccdelta, rfdelta, tfdelta, listenTime, clock_rate); - } - - aniState->cycleCount = cycleCount; - aniState->txFrameCount = txFrameCount; - aniState->rxFrameCount = rxFrameCount; - - return listenTime; + return listen_time; } static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) @@ -1041,45 +1009,52 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, - u32 *rxc_pcnt, - u32 *rxf_pcnt, - u32 *txf_pcnt) +void ath9k_hw_update_cycle_counters(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); - static u32 cycles, rx_clear, rx_frame, tx_frame; - u32 good = 1; + struct ath_cycle_counters cc; + bool clear; - u32 rc = REG_READ(ah, AR_RCCNT); - u32 rf = REG_READ(ah, AR_RFCNT); - u32 tf = REG_READ(ah, AR_TFCNT); - u32 cc = REG_READ(ah, AR_CCCNT); + memcpy(&cc, &ah->cc, sizeof(cc)); - if (cycles == 0 || cycles > cc) { - ath_print(common, ATH_DBG_ANI, - "cycle counter wrap. ExtBusy = 0\n"); - good = 0; - } else { - u32 cc_d = cc - cycles; - u32 rc_d = rc - rx_clear; - u32 rf_d = rf - rx_frame; - u32 tf_d = tf - tx_frame; - - if (cc_d != 0) { - *rxc_pcnt = rc_d * 100 / cc_d; - *rxf_pcnt = rf_d * 100 / cc_d; - *txf_pcnt = tf_d * 100 / cc_d; - } else { - good = 0; - } + /* freeze counters */ + REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); + + ah->cc.cycles = REG_READ(ah, AR_CCCNT); + if (ah->cc.cycles < cc.cycles) { + clear = true; + goto skip; } - cycles = cc; - rx_frame = rf; - rx_clear = rc; - tx_frame = tf; + ah->cc.rx_clear = REG_READ(ah, AR_RCCNT); + ah->cc.rx_frame = REG_READ(ah, AR_RFCNT); + ah->cc.tx_frame = REG_READ(ah, AR_TFCNT); + + /* prevent wraparound */ + if (ah->cc.cycles & BIT(31)) + clear = true; + +#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field + CC_DELTA(cycles, AR_CCCNT); + CC_DELTA(rx_frame, AR_RFCNT); + CC_DELTA(rx_clear, AR_RCCNT); + CC_DELTA(tx_frame, AR_TFCNT); +#undef CC_DELTA + + ah->listen_time += (ah->cc.cycles - cc.cycles) - + ((ah->cc.rx_frame - cc.rx_frame) + + (ah->cc.tx_frame - cc.tx_frame)); + +skip: + if (clear) { + REG_WRITE(ah, AR_CCCNT, 0); + REG_WRITE(ah, AR_RFCNT, 0); + REG_WRITE(ah, AR_RCCNT, 0); + REG_WRITE(ah, AR_TFCNT, 0); + memset(&ah->cc, 0, sizeof(ah->cc)); + } - return good; + /* unfreeze counters */ + REG_WRITE(ah, AR_MIBC, 0); } /* diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index f4d0a4d48b37..15f9d67a18c8 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -93,6 +93,13 @@ struct ath9k_mib_stats { u32 beacons; }; +struct ath_cycle_counters { + u32 cycles; + u32 rx_frame; + u32 rx_clear; + u32 tx_frame; +}; + /* INI default values for ANI registers */ struct ath9k_ani_default { u16 m1ThreshLow; @@ -130,9 +137,6 @@ struct ar5416AniState { int32_t rssiThrLow; int32_t rssiThrHigh; u32 noiseFloor; - u32 txFrameCount; - u32 rxFrameCount; - u32 cycleCount; u32 ofdmPhyErrCount; u32 cckPhyErrCount; u32 ofdmPhyErrBase; @@ -166,8 +170,7 @@ struct ar5416Stats { void ath9k_enable_mib_counters(struct ath_hw *ah); void ath9k_hw_disable_mib_counters(struct ath_hw *ah); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, - u32 *rxf_pcnt, u32 *txf_pcnt); +void ath9k_hw_update_cycle_counters(struct ath_hw *ah); void ath9k_hw_ani_setup(struct ath_hw *ah); void ath9k_hw_ani_init(struct ath_hw *ah); int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 525671f52b45..a11ca0247793 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1225,8 +1225,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, aniState->firstepLevel, aniState->listenTime); ath_print(common, ATH_DBG_ANI, - "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", - aniState->cycleCount, + "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1478,15 +1477,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d CC=%d listen=%d " + "MRCcck=%s listenTime=%d " "ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, - aniState->cycleCount, - aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); return true; @@ -1579,8 +1576,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = true; /* not available on pre AR9003 */ - - aniState->cycleCount = 0; } static void ar5008_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index a491854fa38a..e15574caf61a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d CC=%d listen=%d " + "MRCcck=%s listenTime=%d " "ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, - aniState->cycleCount, - aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); return true; @@ -1116,8 +1114,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; - - aniState->cycleCount = 0; } void ar9003_hw_attach_phy_ops(struct ath_hw *ah) @@ -1232,7 +1228,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah) void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status; + u32 status; if (likely(!(common->debug_mask & ATH_DBG_RESET))) return; @@ -1261,11 +1257,13 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) "** BB mode: BB_gen_controls=0x%08x **\n", REG_READ(ah, AR_PHY_GEN_CTRL)); - if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt)) + ath9k_hw_update_cycle_counters(ah); +#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles) + if (ah->cc_delta.cycles) ath_print(common, ATH_DBG_RESET, "** BB busy times: rx_clear=%d%%, " "rx_frame=%d%%, tx_frame=%d%% **\n", - rxc_pcnt, rxf_pcnt, txf_pcnt); + PCT(rx_clear), PCT(rx_frame), PCT(tx_frame)); ath_print(common, ATH_DBG_RESET, "==== BB update: done ====\n\n"); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 246c707cea00..87dbb8502469 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -765,6 +765,8 @@ struct ath_hw { int coarse_low[5]; int firpwr[5]; enum ath9k_ani_cmd ani_function; + struct ath_cycle_counters cc, cc_delta; + int32_t listen_time; /* Bluetooth coexistance */ struct ath_btcoex_hw btcoex_hw; -- cgit v1.2.3 From 435c1610f46dc4d86a6633adb037b18109e6ffdc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 5 Oct 2010 12:03:42 +0200 Subject: ath9k_hw: clean up register write buffering Throughout the code, DISABLE_REGWRITE_BUFFER is always called right after REGWRITE_BUFFER_FLUSH. Since that's unlikely to change any time soon, that makes keeping those ops separate rather pointless, as it only increases code size and line number counts. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 4 +--- drivers/net/wireless/ath/ath9k/ani.c | 6 ------ drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 ++------- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 - drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 ---- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 1 - drivers/net/wireless/ath/ath9k/calib.c | 1 - drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 -- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++---------- drivers/net/wireless/ath/ath9k/hw.c | 14 -------------- drivers/net/wireless/ath/ath9k/hw.h | 10 ++-------- drivers/net/wireless/ath/ath9k/mac.c | 4 ---- 12 files changed, 7 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 5894fcc2c628..cee0191704f5 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -102,14 +102,12 @@ enum ath_cipher { * @read: Register read * @write: Register write * @enable_write_buffer: Enable multiple register writes - * @disable_write_buffer: Disable multiple register writes - * @write_flush: Flush buffered register writes + * @write_flush: flush buffered register writes and disable buffering */ struct ath_ops { unsigned int (*read)(void *, u32 reg_offset); void (*write)(void *, u32 val, u32 reg_offset); void (*enable_write_buffer)(void *); - void (*disable_write_buffer)(void *); void (*write_flush) (void *); }; diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 3fba81e3a61f..a1894d240773 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -180,7 +180,6 @@ static void ath9k_ani_restart_old(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -215,7 +214,6 @@ static void ath9k_ani_restart_new(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -643,7 +641,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* @@ -737,7 +734,6 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, @@ -991,7 +987,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* Freeze the MIB counters, get the stats and then clear them */ @@ -1261,7 +1256,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ath9k_enable_mib_counters(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index a11ca0247793..7b26292daf35 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -613,14 +613,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah) rx_chainmask = ah->rxchainmask; tx_chainmask = ah->txchainmask; - ENABLE_REGWRITE_BUFFER(ah); switch (rx_chainmask) { case 0x5: - DISABLE_REGWRITE_BUFFER(ah); REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); - ENABLE_REGWRITE_BUFFER(ah); case 0x3: if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); @@ -630,17 +627,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah) case 0x1: case 0x2: case 0x7: + ENABLE_REGWRITE_BUFFER(ah); REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); break; default: + ENABLE_REGWRITE_BUFFER(ah); break; } REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (tx_chainmask == 0x5) { REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, @@ -726,7 +724,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } @@ -818,7 +815,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); @@ -849,7 +845,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9271(ah)) { if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index f0525fb62a2c..15f62cd0cc38 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -522,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) REG_WRITE(ah, regList[i][0], regList[i][1]); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index fde45082a13b..78bdf0cec5f0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } udelay(1000); @@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah) REG_WRITE(ah, AR_PHY(0x20), 0x00010000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); @@ -627,6 +625,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); - } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index cd56c8692705..c00cdc67b55b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ar9002_olc_init(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 6c38c72915c1..6d509484b5f6 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) } } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 872e75b0b574..4fa4d8e28c64 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -508,7 +508,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } } @@ -840,7 +839,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ath9k_hw_4k_set_addac(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b100db2766cf..bbb54bc28a44 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv) atomic_inc(&priv->wmi->mwrite_cnt); } -static void ath9k_disable_regwrite_buffer(void *hw_priv) -{ - struct ath_hw *ah = (struct ath_hw *) hw_priv; - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - atomic_dec(&priv->wmi->mwrite_cnt); -} - static void ath9k_regwrite_flush(void *hw_priv) { struct ath_hw *ah = (struct ath_hw *) hw_priv; @@ -397,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv) u32 rsp_status; int r; + atomic_dec(&priv->wmi->mwrite_cnt); + mutex_lock(&priv->wmi->multi_write_mutex); if (priv->wmi->multi_write_idx) { @@ -420,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = { .read = ath9k_regread, .write = ath9k_regwrite, .enable_write_buffer = ath9k_enable_regwrite_buffer, - .disable_write_buffer = ath9k_disable_regwrite_buffer, .write_flush = ath9k_regwrite_flush, }; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1b066043d6cb..98c97653c21b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* This should work for all families including legacy */ @@ -676,7 +675,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ath9k_hw_init_pll(struct ath_hw *ah, @@ -741,7 +739,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9300_20_OR_LATER(ah)) { REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0); @@ -885,7 +882,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * Restore TX Trigger Level to its pre-reset value. @@ -933,7 +929,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9300_20_OR_LATER(ah)) ath9k_hw_reset_txstatus_ring(ah); @@ -1031,7 +1026,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) REG_WRITE(ah, AR_RTC_RC, rst_flags); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); udelay(50); @@ -1070,7 +1064,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) udelay(2); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (!AR_SREV_9300_20_OR_LATER(ah)) udelay(2); @@ -1374,7 +1367,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); r = ath9k_hw_rf_set_freq(ah, chan); if (r) @@ -1386,7 +1378,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ah->intr_txqs = 0; for (i = 0; i < ah->caps.total_queues; i++) @@ -1434,7 +1425,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * For big endian systems turn on swapping for descriptors @@ -1684,7 +1674,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); beacon_period &= ~ATH9K_BEACON_ENA; if (beacon_period & ATH9K_BEACON_RESET_TSF) { @@ -1712,7 +1701,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); @@ -1758,7 +1746,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); REG_SET_BIT(ah, AR_TIMER_MODE, AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | @@ -2176,7 +2163,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } EXPORT_SYMBOL(ath9k_hw_setrxfilter); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 87dbb8502469..d558c51236f9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -70,19 +70,13 @@ #define ENABLE_REGWRITE_BUFFER(_ah) \ do { \ - if (AR_SREV_9271(_ah)) \ + if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ } while (0) -#define DISABLE_REGWRITE_BUFFER(_ah) \ - do { \ - if (AR_SREV_9271(_ah)) \ - ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \ - } while (0) - #define REGWRITE_BUFFER_FLUSH(_ah) \ do { \ - if (AR_SREV_9271(_ah)) \ + if (ath9k_hw_common(_ah)->ops->write_flush) \ ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ } while (0) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 3efda8a8a3c1..e5784595bd0f 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) @@ -530,7 +529,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { REG_WRITE(ah, AR_DMISC(q), @@ -553,7 +551,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | AR_D_MISC_POST_FR_BKOFF_DIS); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * cwmin and cwmax should be 0 for beacon queue @@ -585,7 +582,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); break; case ATH9K_TX_QUEUE_PSPOLL: -- cgit v1.2.3 From 71ea420992149294e74da3fa34ca8f111326bb6d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 4 Oct 2010 20:09:46 +0200 Subject: ath9k_hw: add a helper function to check for the new ANI implementation Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index a1894d240773..9856a1b0ca2d 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -109,6 +109,11 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); } +static bool use_new_ani(struct ath_hw *ah) +{ + return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; +} + int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1178,7 +1183,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) memset(ah->ani, 0, sizeof(ah->ani)); for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { + if (use_new_ani(ah)) { ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW; @@ -1230,7 +1235,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) * since we expect some ongoing maintenance on the tables, let's sanity * check here default level should not modify INI setting. */ - if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { + if (use_new_ani(ah)) { const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; -- cgit v1.2.3 From 093115b7fd641f03d89404252044c976928764cb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 4 Oct 2010 20:09:47 +0200 Subject: ath9k_hw: clean up ANI state handling ANI state is kept per channel, so instead of keeping an array of ANI states with an arbitrary size of 255, move the ANI state into the channel struct. Move some config settings that are not per-channel out of the per-channel struct to save some memory. With those changes, ath9k_ani_restart_old and ath9k_ani_restart_new can be merged into a single function. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 338 +++++++++------------------- drivers/net/wireless/ath/ath9k/ani.h | 8 +- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 10 +- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 7 +- drivers/net/wireless/ath/ath9k/hw.c | 4 - drivers/net/wireless/ath/ath9k/hw.h | 3 +- 6 files changed, 110 insertions(+), 260 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 9856a1b0ca2d..6bae601c63a3 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -114,27 +114,6 @@ static bool use_new_ani(struct ath_hw *ah) return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; } -int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (ah->ani[i].c && - ah->ani[i].c->channel == chan->channel) - return i; - if (ah->ani[i].c == NULL) { - ah->ani[i].c = chan; - return i; - } - } - - ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, - "No more channel states left. Using channel 0\n"); - - return 0; -} - static void ath9k_hw_update_mibstats(struct ath_hw *ah, struct ath9k_mib_stats *stats) { @@ -145,76 +124,30 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, stats->beacons += REG_READ(ah, AR_BEACON_CNT); } -static void ath9k_ani_restart_old(struct ath_hw *ah) +static void ath9k_ani_restart(struct ath_hw *ah) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); + u32 ofdm_base = 0, cck_base = 0; if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; aniState->listenTime = 0; - if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { - aniState->ofdmPhyErrBase = 0; - ath_print(common, ATH_DBG_ANI, - "OFDM Trigger is too high for hw counters\n"); - } else { - aniState->ofdmPhyErrBase = - AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; } - if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { - aniState->cckPhyErrBase = 0; - ath_print(common, ATH_DBG_ANI, - "CCK Trigger is too high for hw counters\n"); - } else { - aniState->cckPhyErrBase = - AR_PHY_COUNTMAX - aniState->cckTrigHigh; - } - ath_print(common, ATH_DBG_ANI, - "Writing ofdmbase=%u cckbase=%u\n", - aniState->ofdmPhyErrBase, - aniState->cckPhyErrBase); - - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); - - REGWRITE_BUFFER_FLUSH(ah); - - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - aniState->ofdmPhyErrCount = 0; - aniState->cckPhyErrCount = 0; -} - -static void ath9k_ani_restart_new(struct ath_hw *ah) -{ - struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - - if (!DO_ANI(ah)) - return; - - aniState = ah->curani; - aniState->listenTime = 0; - - aniState->ofdmPhyErrBase = 0; - aniState->cckPhyErrBase = 0; ath_print(common, ATH_DBG_ANI, - "Writing ofdmbase=%08x cckbase=%08x\n", - aniState->ofdmPhyErrBase, - aniState->cckPhyErrBase); + "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); @@ -235,7 +168,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, @@ -307,7 +240,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1)) { @@ -339,7 +272,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) /* Adjust the OFDM Noise Immunity Level */ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; @@ -391,7 +324,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); @@ -402,7 +335,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) */ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; @@ -448,7 +381,7 @@ static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); @@ -459,7 +392,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (ah->opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel > 0) { @@ -515,7 +448,7 @@ static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) { struct ar5416AniState *aniState; - aniState = ah->curani; + aniState = &ah->curchan->ani; /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && @@ -568,16 +501,13 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) struct ar5416AniState *aniState; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); - int index; if (!DO_ANI(ah)) return; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; + aniState = &ah->curchan->ani; - if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION + if (ah->opmode != NL80211_IFTYPE_STATION && ah->opmode != NL80211_IFTYPE_ADHOC) { ath_print(common, ATH_DBG_ANI, "Reset ANI state opmode %u\n", ah->opmode); @@ -606,17 +536,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | ATH9K_RX_FILTER_PHYERR); - if (ah->opmode == NL80211_IFTYPE_AP) { - ah->curani->ofdmTrigHigh = - ah->config.ofdm_trig_high; - ah->curani->ofdmTrigLow = - ah->config.ofdm_trig_low; - ah->curani->cckTrigHigh = - ah->config.cck_trig_high; - ah->curani->cckTrigLow = - ah->config.cck_trig_low; - } - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); return; } @@ -638,7 +558,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & ~ATH9K_RX_FILTER_PHYERR); - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -655,7 +575,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) */ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); @@ -731,7 +651,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) * enable phy counters if hw supports or if not, enable phy * interrupts (so we can count each one) */ - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -749,16 +669,18 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, int32_t listenTime; u32 phyCnt1, phyCnt2; u32 ofdmPhyErrCnt, cckPhyErrCnt; + u32 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + u32 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; listenTime = ath9k_hw_ani_get_listen_time(ah); if (listenTime < 0) { ah->stats.ast_ani_lneg++; - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); return; } @@ -769,60 +691,55 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (phyCnt1 < aniState->ofdmPhyErrBase || - phyCnt2 < aniState->cckPhyErrBase) { - if (phyCnt1 < aniState->ofdmPhyErrBase) { + if (phyCnt1 < ofdm_base || phyCnt2 < cck_base) { + if (phyCnt1 < ofdm_base) { ath_print(common, ATH_DBG_ANI, "phyCnt1 0x%x, resetting " "counter value to 0x%x\n", - phyCnt1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_1, - aniState->ofdmPhyErrBase); + phyCnt1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); } - if (phyCnt2 < aniState->cckPhyErrBase) { + if (phyCnt2 < cck_base) { ath_print(common, ATH_DBG_ANI, "phyCnt2 0x%x, resetting " "counter value to 0x%x\n", - phyCnt2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, - aniState->cckPhyErrBase); + phyCnt2, cck_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); } return; } - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; + ofdmPhyErrCnt = phyCnt1 - ofdm_base; ah->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; + cckPhyErrCnt = phyCnt2 - cck_base; ah->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; if (aniState->listenTime > 5 * ah->aniperiod) { if (aniState->ofdmPhyErrCount <= aniState->listenTime * - aniState->ofdmTrigLow / 1000 && + ah->config.ofdm_trig_low / 1000 && aniState->cckPhyErrCount <= aniState->listenTime * - aniState->cckTrigLow / 1000) + ah->config.cck_trig_low / 1000) ath9k_hw_ani_lower_immunity(ah); - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); } else if (aniState->listenTime > ah->aniperiod) { if (aniState->ofdmPhyErrCount > aniState->listenTime * - aniState->ofdmTrigHigh / 1000) { + ah->config.ofdm_trig_high / 1000) { ath9k_hw_ani_ofdm_err_trigger_old(ah); - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); } else if (aniState->cckPhyErrCount > - aniState->listenTime * aniState->cckTrigHigh / + aniState->listenTime * ah->config.cck_trig_high / 1000) { ath9k_hw_ani_cck_err_trigger_old(ah); - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); } } } @@ -833,14 +750,13 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); int32_t listenTime; - u32 phyCnt1, phyCnt2; u32 ofdmPhyErrCnt, cckPhyErrCnt; u32 ofdmPhyErrRate, cckPhyErrRate; if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (WARN_ON(!aniState)) return; @@ -851,7 +767,7 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "listenTime=%d - on new ani monitor\n", listenTime); - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); return; } @@ -859,55 +775,20 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); - phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - - if (phyCnt1 < aniState->ofdmPhyErrBase || - phyCnt2 < aniState->cckPhyErrBase) { - if (phyCnt1 < aniState->ofdmPhyErrBase) { - ath_print(common, ATH_DBG_ANI, - "phyCnt1 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_1, - AR_PHY_ERR_OFDM_TIMING); - } - if (phyCnt2 < aniState->cckPhyErrBase) { - ath_print(common, ATH_DBG_ANI, - "phyCnt2 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, - AR_PHY_ERR_CCK_TIMING); - } - return; - } + ofdmPhyErrCnt = REG_READ(ah, AR_PHY_ERR_1); + cckPhyErrCnt = REG_READ(ah, AR_PHY_ERR_2); - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; ah->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; ah->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; ath_print(common, ATH_DBG_ANI, - "Errors: OFDM=0x%08x-0x%08x=%d " - "CCK=0x%08x-0x%08x=%d\n", - phyCnt1, - aniState->ofdmPhyErrBase, - ofdmPhyErrCnt, - phyCnt2, - aniState->cckPhyErrBase, - cckPhyErrCnt); + "Errors: OFDM=%d, CCK=%d\n", + ofdmPhyErrCnt, cckPhyErrCnt); ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / aniState->listenTime; @@ -922,8 +803,8 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, cckPhyErrRate, aniState->ofdmsTurn); if (aniState->listenTime > 5 * ah->aniperiod) { - if (ofdmPhyErrRate <= aniState->ofdmTrigLow && - cckPhyErrRate <= aniState->cckTrigLow) { + if (ofdmPhyErrRate <= ah->config.ofdm_trig_low && + cckPhyErrRate <= ah->config.cck_trig_low) { ath_print(common, ATH_DBG_ANI, "1. listenTime=%d OFDM:%d errs=%d/s(<%d) " "CCK:%d errs=%d/s(<%d) -> " @@ -931,22 +812,22 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, aniState->listenTime, aniState->ofdmNoiseImmunityLevel, ofdmPhyErrRate, - aniState->ofdmTrigLow, + ah->config.ofdm_trig_low, aniState->cckNoiseImmunityLevel, cckPhyErrRate, - aniState->cckTrigLow); + ah->config.cck_trig_low); ath9k_hw_ani_lower_immunity(ah); aniState->ofdmsTurn = !aniState->ofdmsTurn; } ath_print(common, ATH_DBG_ANI, "1 listenTime=%d ofdm=%d/s cck=%d/s - " - "calling ath9k_ani_restart_new()\n", + "calling ath9k_ani_restart()\n", aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate); - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); } else if (aniState->listenTime > ah->aniperiod) { /* check to see if need to raise immunity */ - if (ofdmPhyErrRate > aniState->ofdmTrigHigh && - (cckPhyErrRate <= aniState->cckTrigHigh || + if (ofdmPhyErrRate > ah->config.ofdm_trig_high && + (cckPhyErrRate <= ah->config.cck_trig_high || aniState->ofdmsTurn)) { ath_print(common, ATH_DBG_ANI, "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " @@ -954,20 +835,20 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, aniState->listenTime, aniState->ofdmNoiseImmunityLevel, ofdmPhyErrRate, - aniState->ofdmTrigHigh); + ah->config.ofdm_trig_high); ath9k_hw_ani_ofdm_err_trigger_new(ah); - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); aniState->ofdmsTurn = false; - } else if (cckPhyErrRate > aniState->cckTrigHigh) { + } else if (cckPhyErrRate > ah->config.cck_trig_high) { ath_print(common, ATH_DBG_ANI, "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " "ath9k_hw_ani_cck_err_trigger_new()\n", aniState->listenTime, aniState->cckNoiseImmunityLevel, cckPhyErrRate, - aniState->cckTrigHigh); + ah->config.cck_trig_high); ath9k_hw_ani_cck_err_trigger_new(ah); - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); aniState->ofdmsTurn = true; } } @@ -1064,6 +945,8 @@ skip: */ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) { + u32 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + u32 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; u32 phyCnt1, phyCnt2; /* Reset these counters regardless */ @@ -1090,16 +973,16 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; u32 ofdmPhyErrCnt, cckPhyErrCnt; /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; + ofdmPhyErrCnt = phyCnt1 - ofdm_base; ah->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; + cckPhyErrCnt = phyCnt2 - cck_base; ah->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; @@ -1110,12 +993,12 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) * clobbers the error counter so the trigger threshold * check will never be true. */ - if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) + if (aniState->ofdmPhyErrCount > ah->config.ofdm_trig_high) ath9k_hw_ani_ofdm_err_trigger_new(ah); - if (aniState->cckPhyErrCount > aniState->cckTrigHigh) + if (aniState->cckPhyErrCount > ah->config.cck_trig_high) ath9k_hw_ani_cck_err_trigger_old(ah); /* NB: always restart to insure the h/w counters are reset */ - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); } } @@ -1154,7 +1037,7 @@ static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah) /* NB: always restart to insure the h/w counters are reset */ if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); } void ath9k_hw_ani_setup(struct ath_hw *ah) @@ -1181,54 +1064,51 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); - memset(ah->ani, 0, sizeof(ah->ani)); - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (use_new_ani(ah)) { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW; + if (use_new_ani(ah)) { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; + } else { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; - ah->ani[i].spurImmunityLevel = - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; + } - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { + struct ath9k_channel *chan = &ah->channels[i]; + struct ar5416AniState *ani = &chan->ani; + + if (use_new_ani(ah)) { + ani->spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; - ah->ani[i].ofdmPhyErrBase = 0; - ah->ani[i].cckPhyErrBase = 0; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; if (AR_SREV_9300_20_OR_LATER(ah)) - ah->ani[i].mrcCCKOff = + ani->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; else - ah->ani[i].mrcCCKOff = true; + ani->mrcCCKOff = true; - ah->ani[i].ofdmsTurn = true; + ani->ofdmsTurn = true; } else { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD; - - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD; - - ah->ani[i].spurImmunityLevel = + ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; - ah->ani[i].ofdmPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD; - ah->ani[i].cckPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD; - ah->ani[i].cckWeakSigThreshold = + ani->cckWeakSigThreshold = ATH9K_ANI_CCK_WEAK_SIG_THR; } - ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; - ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; - ah->ani[i].ofdmWeakSigDetectOff = + ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; + ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; + ani->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; - ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; + ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; } /* @@ -1249,23 +1129,11 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; } - ath_print(common, ATH_DBG_ANI, - "Setting OfdmErrBase = 0x%08x\n", - ah->ani[0].ofdmPhyErrBase); - ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", - ah->ani[0].cckPhyErrBase); - - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); - - REGWRITE_BUFFER_FLUSH(ah); - - ath9k_enable_mib_counters(ah); - if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; + + ath9k_ani_restart(ah); + ath9k_enable_mib_counters(ah); } void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 15f9d67a18c8..98cfd8154c71 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -19,7 +19,7 @@ #define HAL_PROCESS_ANI 0x00000001 -#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) +#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan) #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) @@ -130,17 +130,11 @@ struct ar5416AniState { u8 ofdmWeakSigDetectOff; u8 cckWeakSigThreshold; u32 listenTime; - u32 ofdmTrigHigh; - u32 ofdmTrigLow; - int32_t cckTrigHigh; - int32_t cckTrigLow; int32_t rssiThrLow; int32_t rssiThrHigh; u32 noiseFloor; u32 ofdmPhyErrCount; u32 cckPhyErrCount; - u32 ofdmPhyErrBase; - u32 cckPhyErrBase; int16_t pktRssi[2]; int16_t ofdmErrRssi[2]; int16_t cckErrRssi[2]; diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 7b26292daf35..ea9f4497f58c 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1048,7 +1048,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); switch (cmd & ah->ani_function) { @@ -1231,9 +1231,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; s32 value, value2; switch (cmd & ah->ani_function) { @@ -1518,16 +1518,12 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah, */ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) { - struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; struct ath9k_ani_default *iniDef; - int index; u32 val; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; iniDef = &aniState->iniDef; ath_print(common, ATH_DBG_ANI, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e15574caf61a..efb05599b84c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -747,9 +747,9 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) static bool ar9003_hw_ani_control(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; s32 value, value2; switch (cmd & ah->ani_function) { @@ -1065,12 +1065,9 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; struct ath9k_ani_default *iniDef; - int index; u32 val; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; + aniState = &ah->curchan->ani; iniDef = &aniState->iniDef; ath_print(common, ATH_DBG_ANI, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 98c97653c21b..05e9935ef160 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -370,10 +370,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; - ah->config.ofdm_trig_low = 200; - ah->config.ofdm_trig_high = 500; - ah->config.cck_trig_high = 200; - ah->config.cck_trig_low = 100; ah->config.enable_ani = true; for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d558c51236f9..506346384c4f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -346,6 +346,7 @@ struct ath9k_hw_cal_data { struct ath9k_channel { struct ieee80211_channel *chan; + struct ar5416AniState ani; u16 channel; u32 channelFlags; u32 chanmode; @@ -752,8 +753,6 @@ struct ath_hw { /* ANI */ u32 proc_phyerr; u32 aniperiod; - struct ar5416AniState *curani; - struct ar5416AniState ani[255]; int totalSizeDesired[5]; int coarse_high[5]; int coarse_low[5]; -- cgit v1.2.3 From bfc472bb736bf309158ea76897d255a283d0d31c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 4 Oct 2010 20:09:48 +0200 Subject: ath9k_hw: remove code duplication in phy error counter handling Split out the PHY error counter update from ath9k_hw_ani_monitor_*, reuse it in ath9k_hw_proc_mib_event (merged from ath9k_hw_proc_mib_event_old and ath9k_hw_proc_mib_event_new). Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 142 +++++++------------------------- drivers/net/wireless/ath/ath9k/hw-ops.h | 5 -- drivers/net/wireless/ath/ath9k/hw.h | 4 +- drivers/net/wireless/ath/ath9k/main.c | 2 +- 4 files changed, 34 insertions(+), 119 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 6bae601c63a3..d5c9df5c4569 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -661,21 +661,15 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) REGWRITE_BUFFER_FLUSH(ah); } -static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, - struct ath9k_channel *chan) +static void ath9k_hw_ani_read_counters(struct ath_hw *ah) { - struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); - int32_t listenTime; - u32 phyCnt1, phyCnt2; + struct ar5416AniState *aniState = &ah->curchan->ani; + u32 ofdm_base = 0; + u32 cck_base = 0; u32 ofdmPhyErrCnt, cckPhyErrCnt; - u32 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; - u32 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; - - if (!DO_ANI(ah)) - return; - - aniState = &ah->curchan->ani; + u32 phyCnt1, phyCnt2; + int32_t listenTime; listenTime = ath9k_hw_ani_get_listen_time(ah); if (listenTime < 0) { @@ -684,6 +678,11 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, return; } + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; + } + aniState->listenTime += listenTime; ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -691,7 +690,7 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (phyCnt1 < ofdm_base || phyCnt2 < cck_base) { + if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { if (phyCnt1 < ofdm_base) { ath_print(common, ATH_DBG_ANI, "phyCnt1 0x%x, resetting " @@ -723,6 +722,19 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; +} + +static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + struct ar5416AniState *aniState; + + if (!DO_ANI(ah)) + return; + + aniState = &ah->curchan->ani; + ath9k_hw_ani_read_counters(ah); + if (aniState->listenTime > 5 * ah->aniperiod) { if (aniState->ofdmPhyErrCount <= aniState->listenTime * ah->config.ofdm_trig_low / 1000 && @@ -749,8 +761,6 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); - int32_t listenTime; - u32 ofdmPhyErrCnt, cckPhyErrCnt; u32 ofdmPhyErrRate, cckPhyErrRate; if (!DO_ANI(ah)) @@ -760,35 +770,7 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, if (WARN_ON(!aniState)) return; - listenTime = ath9k_hw_ani_get_listen_time(ah); - if (listenTime <= 0) { - ah->stats.ast_ani_lneg++; - /* restart ANI period if listenTime is invalid */ - ath_print(common, ATH_DBG_ANI, - "listenTime=%d - on new ani monitor\n", - listenTime); - ath9k_ani_restart(ah); - return; - } - - aniState->listenTime += listenTime; - - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - ofdmPhyErrCnt = REG_READ(ah, AR_PHY_ERR_1); - cckPhyErrCnt = REG_READ(ah, AR_PHY_ERR_2); - - ah->stats.ast_ani_ofdmerrs += - ofdmPhyErrCnt - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - - ah->stats.ast_ani_cckerrs += - cckPhyErrCnt - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = cckPhyErrCnt; - - ath_print(common, ATH_DBG_ANI, - "Errors: OFDM=%d, CCK=%d\n", - ofdmPhyErrCnt, cckPhyErrCnt); + ath9k_hw_ani_read_counters(ah); ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / aniState->listenTime; @@ -798,7 +780,8 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "listenTime=%d OFDM:%d errs=%d/s CCK:%d " "errs=%d/s ofdm_turn=%d\n", - listenTime, aniState->ofdmNoiseImmunityLevel, + aniState->listenTime, + aniState->ofdmNoiseImmunityLevel, ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, cckPhyErrRate, aniState->ofdmsTurn); @@ -943,10 +926,8 @@ skip: * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ -static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) +void ath9k_hw_proc_mib_event(struct ath_hw *ah) { - u32 ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; - u32 cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; u32 phyCnt1, phyCnt2; /* Reset these counters regardless */ @@ -973,72 +954,15 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - struct ar5416AniState *aniState = &ah->curchan->ani; - u32 ofdmPhyErrCnt, cckPhyErrCnt; - - /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ - ofdmPhyErrCnt = phyCnt1 - ofdm_base; - ah->stats.ast_ani_ofdmerrs += - ofdmPhyErrCnt - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - cck_base; - ah->stats.ast_ani_cckerrs += - cckPhyErrCnt - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = cckPhyErrCnt; + if (!use_new_ani(ah)) + ath9k_hw_ani_read_counters(ah); - /* - * NB: figure out which counter triggered. If both - * trigger we'll only deal with one as the processing - * clobbers the error counter so the trigger threshold - * check will never be true. - */ - if (aniState->ofdmPhyErrCount > ah->config.ofdm_trig_high) - ath9k_hw_ani_ofdm_err_trigger_new(ah); - if (aniState->cckPhyErrCount > ah->config.cck_trig_high) - ath9k_hw_ani_cck_err_trigger_old(ah); /* NB: always restart to insure the h/w counters are reset */ ath9k_ani_restart(ah); } } - -/* - * Process a MIB interrupt. We may potentially be invoked because - * any of the MIB counters overflow/trigger so don't assume we're - * here because a PHY error counter triggered. - */ -static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah) -{ - u32 phyCnt1, phyCnt2; - - /* Reset these counters regardless */ - REG_WRITE(ah, AR_FILT_OFDM, 0); - REG_WRITE(ah, AR_FILT_CCK, 0); - if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) - REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); - - /* Clear the mib counters and save them in the stats */ - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - if (!DO_ANI(ah)) { - /* - * We must always clear the interrupt cause by - * resetting the phy error regs. - */ - REG_WRITE(ah, AR_PHY_ERR_1, 0); - REG_WRITE(ah, AR_PHY_ERR_2, 0); - return; - } - - /* NB: these are not reset-on-read */ - phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); - phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - - /* NB: always restart to insure the h/w counters are reset */ - if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || - ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) - ath9k_ani_restart(ah); -} +EXPORT_SYMBOL(ath9k_hw_proc_mib_event); void ath9k_hw_ani_setup(struct ath_hw *ah) { @@ -1144,7 +1068,6 @@ void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) priv_ops->ani_reset = ath9k_ani_reset_old; priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old; - ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old; ops->ani_monitor = ath9k_hw_ani_monitor_old; ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n"); @@ -1158,7 +1081,6 @@ void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah) priv_ops->ani_reset = ath9k_ani_reset_new; priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new; - ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new; ops->ani_monitor = ath9k_hw_ani_monitor_new; ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n"); diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 9c4dd0ec9a15..f42c1980e654 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -128,11 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); } -static inline void ath9k_hw_procmibevent(struct ath_hw *ah) -{ - ath9k_hw_ops(ah)->ani_proc_mib_event(ah); -} - static inline void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 506346384c4f..a87840bab2ad 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -575,8 +575,6 @@ struct ath_hw_private_ops { * @config_pci_powersave: * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC * - * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI - * thresholds being reached or having overflowed. * @ani_monitor: called periodically by the core driver to collect * MIB stats and adjust ANI if specific thresholds have been reached. */ @@ -620,7 +618,6 @@ struct ath_hw_ops { void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, u32 vmf); - void (*ani_proc_mib_event)(struct ath_hw *ah); void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan); }; @@ -980,6 +977,7 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. */ extern int modparam_force_new_ani; +void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e6ddf45506be..d9c2e2d93136 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -713,7 +713,7 @@ irqreturn_t ath_isr(int irq, void *dev) * it will clear whatever condition caused * the interrupt. */ - ath9k_hw_procmibevent(ah); + ath9k_hw_proc_mib_event(ah); ath9k_hw_set_interrupts(ah, ah->imask); } -- cgit v1.2.3 From 8eb4980c33c35e97a0a226fdbc07e38da0f1f4aa Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 4 Oct 2010 20:09:49 +0200 Subject: ath9k_hw: remove function pointer abstraction for internal ANI ops The code gets more concise and readable when making the new ANI functions fall back to the old ones if ANI v2 is disabled. This also makes further code cleanup easier. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 58 ++++++++++++++++----------------- drivers/net/wireless/ath/ath9k/hw-ops.h | 5 --- drivers/net/wireless/ath/ath9k/hw.h | 11 +------ 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index d5c9df5c4569..b9595647810a 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -103,12 +103,6 @@ static const struct ani_cck_level_entry cck_level_table[] = { #define ATH9K_ANI_CCK_DEF_LEVEL \ 2 /* default level - matches the INI settings */ -/* Private to ani.c */ -static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) -{ - ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); -} - static bool use_new_ani(struct ath_hw *ah) { return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; @@ -165,9 +159,6 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) - return; - aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { @@ -237,9 +228,6 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) - return; - aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, @@ -317,13 +305,18 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) } } -static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) +static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) { struct ar5416AniState *aniState; if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) { + ath9k_hw_ani_ofdm_err_trigger_old(ah); + return; + } + aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) @@ -374,13 +367,18 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) entry_cck->mrc_cck_on); } -static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) +static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) { struct ar5416AniState *aniState; if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) { + ath9k_hw_ani_cck_err_trigger_old(ah); + return; + } + aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) @@ -444,12 +442,17 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) * only lower either OFDM or CCK errors per turn * we lower the other one next time */ -static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) +static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) { struct ar5416AniState *aniState; aniState = &ah->curchan->ani; + if (!use_new_ani(ah)) { + ath9k_hw_ani_lower_immunity_old(ah); + return; + } + /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) { @@ -573,7 +576,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) * This routine should be called for every hardware reset and for * every channel change. */ -static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) +void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) { struct ar5416AniState *aniState = &ah->curchan->ani; struct ath9k_channel *chan = ah->curchan; @@ -582,6 +585,9 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) + return ath9k_ani_reset_old(ah, is_scanning); + BUG_ON(aniState == NULL); ah->stats.ast_ani_reset++; @@ -745,12 +751,12 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, } else if (aniState->listenTime > ah->aniperiod) { if (aniState->ofdmPhyErrCount > aniState->listenTime * ah->config.ofdm_trig_high / 1000) { - ath9k_hw_ani_ofdm_err_trigger_old(ah); + ath9k_hw_ani_ofdm_err_trigger(ah); ath9k_ani_restart(ah); } else if (aniState->cckPhyErrCount > aniState->listenTime * ah->config.cck_trig_high / 1000) { - ath9k_hw_ani_cck_err_trigger_old(ah); + ath9k_hw_ani_cck_err_trigger(ah); ath9k_ani_restart(ah); } } @@ -814,23 +820,23 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, aniState->ofdmsTurn)) { ath_print(common, ATH_DBG_ANI, "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_ofdm_err_trigger_new()\n", + "ath9k_hw_ani_ofdm_err_trigger()\n", aniState->listenTime, aniState->ofdmNoiseImmunityLevel, ofdmPhyErrRate, ah->config.ofdm_trig_high); - ath9k_hw_ani_ofdm_err_trigger_new(ah); + ath9k_hw_ani_ofdm_err_trigger(ah); ath9k_ani_restart(ah); aniState->ofdmsTurn = false; } else if (cckPhyErrRate > ah->config.cck_trig_high) { ath_print(common, ATH_DBG_ANI, "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_cck_err_trigger_new()\n", + "ath9k_hw_ani_cck_err_trigger()\n", aniState->listenTime, aniState->cckNoiseImmunityLevel, cckPhyErrRate, ah->config.cck_trig_high); - ath9k_hw_ani_cck_err_trigger_new(ah); + ath9k_hw_ani_cck_err_trigger(ah); ath9k_ani_restart(ah); aniState->ofdmsTurn = true; } @@ -1062,12 +1068,8 @@ void ath9k_hw_ani_init(struct ath_hw *ah) void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) { - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); struct ath_hw_ops *ops = ath9k_hw_ops(ah); - priv_ops->ani_reset = ath9k_ani_reset_old; - priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old; - ops->ani_monitor = ath9k_hw_ani_monitor_old; ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n"); @@ -1075,12 +1077,8 @@ void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah) { - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); struct ath_hw_ops *ops = ath9k_hw_ops(ah); - priv_ops->ani_reset = ath9k_ani_reset_new; - priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new; - ops->ani_monitor = ath9k_hw_ani_monitor_new; ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n"); diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index f42c1980e654..6564d1f0ffb1 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -271,9 +271,4 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah, ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); } -static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) -{ - ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning); -} - #endif /* ATH9K_HW_OPS_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a87840bab2ad..c982a24146d2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -509,14 +509,6 @@ struct ath_hw_antcomb_conf { * @setup_calibration: set up calibration * @iscal_supported: used to query if a type of calibration is supported * - * @ani_reset: reset ANI parameters to default values - * @ani_lower_immunity: lower the noise immunity level. The level controls - * the power-based packet detection on hardware. If a power jump is - * detected the adapter takes it as an indication that a packet has - * arrived. The level ranges from 0-5. Each level corresponds to a - * few dB more of noise immunity. If you have a strong time-varying - * interference that is causing false detections (OFDM timing errors or - * CCK timing errors) the level can be increased. * @ani_cache_ini_regs: cache the values for ANI from the initial * register settings through the register initialization. */ @@ -561,8 +553,6 @@ struct ath_hw_private_ops { void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); /* ANI */ - void (*ani_reset)(struct ath_hw *ah, bool is_scanning); - void (*ani_lower_immunity)(struct ath_hw *ah); void (*ani_cache_ini_regs)(struct ath_hw *ah); }; @@ -977,6 +967,7 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. */ extern int modparam_force_new_ani; +void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); -- cgit v1.2.3 From 95792178a58716a6afaeb5ab9654f1a0f17a5e8e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 4 Oct 2010 20:09:50 +0200 Subject: ath9k_hw: merge ath9k_hw_ani_monitor_old and ath9k_hw_ani_monitor_new After the last rounds of cleanup, these functions are now functionally equivalent and can thus be merged. Also get rid of some excessive (and redundant) debug messages. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 83 +----------------------------- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 5 -- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 2 - drivers/net/wireless/ath/ath9k/hw-ops.h | 6 --- drivers/net/wireless/ath/ath9k/hw.h | 8 +-- 5 files changed, 3 insertions(+), 101 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index b9595647810a..f2a907b4acb8 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -730,40 +730,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah) } -static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ar5416AniState *aniState; - - if (!DO_ANI(ah)) - return; - - aniState = &ah->curchan->ani; - ath9k_hw_ani_read_counters(ah); - - if (aniState->listenTime > 5 * ah->aniperiod) { - if (aniState->ofdmPhyErrCount <= aniState->listenTime * - ah->config.ofdm_trig_low / 1000 && - aniState->cckPhyErrCount <= aniState->listenTime * - ah->config.cck_trig_low / 1000) - ath9k_hw_ani_lower_immunity(ah); - ath9k_ani_restart(ah); - } else if (aniState->listenTime > ah->aniperiod) { - if (aniState->ofdmPhyErrCount > aniState->listenTime * - ah->config.ofdm_trig_high / 1000) { - ath9k_hw_ani_ofdm_err_trigger(ah); - ath9k_ani_restart(ah); - } else if (aniState->cckPhyErrCount > - aniState->listenTime * ah->config.cck_trig_high / - 1000) { - ath9k_hw_ani_cck_err_trigger(ah); - ath9k_ani_restart(ah); - } - } -} - -static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, - struct ath9k_channel *chan) +void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); @@ -794,54 +761,26 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, if (aniState->listenTime > 5 * ah->aniperiod) { if (ofdmPhyErrRate <= ah->config.ofdm_trig_low && cckPhyErrRate <= ah->config.cck_trig_low) { - ath_print(common, ATH_DBG_ANI, - "1. listenTime=%d OFDM:%d errs=%d/s(<%d) " - "CCK:%d errs=%d/s(<%d) -> " - "ath9k_hw_ani_lower_immunity()\n", - aniState->listenTime, - aniState->ofdmNoiseImmunityLevel, - ofdmPhyErrRate, - ah->config.ofdm_trig_low, - aniState->cckNoiseImmunityLevel, - cckPhyErrRate, - ah->config.cck_trig_low); ath9k_hw_ani_lower_immunity(ah); aniState->ofdmsTurn = !aniState->ofdmsTurn; } - ath_print(common, ATH_DBG_ANI, - "1 listenTime=%d ofdm=%d/s cck=%d/s - " - "calling ath9k_ani_restart()\n", - aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate); ath9k_ani_restart(ah); } else if (aniState->listenTime > ah->aniperiod) { /* check to see if need to raise immunity */ if (ofdmPhyErrRate > ah->config.ofdm_trig_high && (cckPhyErrRate <= ah->config.cck_trig_high || aniState->ofdmsTurn)) { - ath_print(common, ATH_DBG_ANI, - "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_ofdm_err_trigger()\n", - aniState->listenTime, - aniState->ofdmNoiseImmunityLevel, - ofdmPhyErrRate, - ah->config.ofdm_trig_high); ath9k_hw_ani_ofdm_err_trigger(ah); ath9k_ani_restart(ah); aniState->ofdmsTurn = false; } else if (cckPhyErrRate > ah->config.cck_trig_high) { - ath_print(common, ATH_DBG_ANI, - "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_cck_err_trigger()\n", - aniState->listenTime, - aniState->cckNoiseImmunityLevel, - cckPhyErrRate, - ah->config.cck_trig_high); ath9k_hw_ani_cck_err_trigger(ah); ath9k_ani_restart(ah); aniState->ofdmsTurn = true; } } } +EXPORT_SYMBOL(ath9k_hw_ani_monitor); void ath9k_enable_mib_counters(struct ath_hw *ah) { @@ -1065,21 +1004,3 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath9k_ani_restart(ah); ath9k_enable_mib_counters(ah); } - -void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) -{ - struct ath_hw_ops *ops = ath9k_hw_ops(ah); - - ops->ani_monitor = ath9k_hw_ani_monitor_old; - - ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n"); -} - -void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah) -{ - struct ath_hw_ops *ops = ath9k_hw_ops(ah); - - ops->ani_monitor = ath9k_hw_ani_monitor_new; - - ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n"); -} diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 78bdf0cec5f0..a0471f2e1c7a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -572,11 +572,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) ar9002_hw_attach_calib_ops(ah); ar9002_hw_attach_mac_ops(ah); - - if (modparam_force_new_ani) - ath9k_hw_attach_ani_ops_new(ah); - else - ath9k_hw_attach_ani_ops_old(ah); } void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 064168909108..02c970819f79 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -333,6 +333,4 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) ar9003_hw_attach_phy_ops(ah); ar9003_hw_attach_calib_ops(ah); ar9003_hw_attach_mac_ops(ah); - - ath9k_hw_attach_ani_ops_new(ah); } diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 6564d1f0ffb1..0a4ad348b699 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -128,12 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); } -static inline void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - ath9k_hw_ops(ah)->ani_monitor(ah, chan); -} - /* Private hardware call ops */ /* PHY ops */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c982a24146d2..87627dd63463 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -564,9 +564,6 @@ struct ath_hw_private_ops { * * @config_pci_powersave: * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC - * - * @ani_monitor: called periodically by the core driver to collect - * MIB stats and adjust ANI if specific thresholds have been reached. */ struct ath_hw_ops { void (*config_pci_powersave)(struct ath_hw *ah, @@ -607,8 +604,6 @@ struct ath_hw_ops { u32 burstDuration); void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, u32 vmf); - - void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan); }; struct ath_nf_limits { @@ -969,8 +964,7 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); extern int modparam_force_new_ani; void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); void ath9k_hw_proc_mib_event(struct ath_hw *ah); -void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); -void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); +void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); #define ATH_PCIE_CAP_LINK_CTRL 0x70 #define ATH_PCIE_CAP_LINK_L0S 1 -- cgit v1.2.3 From fbab7390f954e3517c72d12cfd9a1502699aa368 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 5 Oct 2010 20:36:40 +0530 Subject: ath9k: remove unnecessary power save flags. drv_config callback is called only after the ack for the nullframe is received and so driver need not do anything special for this. So remove NULLFUNC_COMPLETED, PS_ENABLED flags and bf_isnullfunc flags from ath9k as mac80211 already handles them properly. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ---- drivers/net/wireless/ath/ath9k/main.c | 18 ++++-------------- drivers/net/wireless/ath/ath9k/xmit.c | 30 ------------------------------ 3 files changed, 4 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9f8e542ef47e..de2b18ee7f77 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -241,7 +241,6 @@ struct ath_buf { dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer */ bool bf_stale; - bool bf_isnullfunc; bool bf_tx_aborted; u16 bf_flags; struct ath_buf_state bf_state; @@ -349,7 +348,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); -void ath9k_enable_ps(struct ath_softc *sc); /********/ /* VIFs */ @@ -573,8 +571,6 @@ struct ath_ant_comb { #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) #define PS_WAIT_FOR_TX_ACK BIT(3) #define PS_BEACON_SYNC BIT(4) -#define PS_NULLFUNC_COMPLETED BIT(5) -#define PS_ENABLED BIT(6) struct ath_wiphy; struct ath_rate_table; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d9c2e2d93136..d0694cb685fa 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1484,7 +1484,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&sc->mutex); } -void ath9k_enable_ps(struct ath_softc *sc) +static void ath9k_enable_ps(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; @@ -1551,20 +1551,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) { unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); - if (conf->flags & IEEE80211_CONF_PS) { - sc->ps_flags |= PS_ENABLED; - /* - * At this point we know hardware has received an ACK - * of a previously sent null data frame. - */ - if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { - sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; - ath9k_enable_ps(sc); - } - } else { + if (conf->flags & IEEE80211_CONF_PS) + ath9k_enable_ps(sc); + else { sc->ps_enabled = false; - sc->ps_flags &= ~(PS_ENABLED | - PS_NULLFUNC_COMPLETED); ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f7da6b20a925..aa447770eb2b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1648,13 +1648,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_buf_addr = bf->bf_dmacontext; - /* tag if this is a nullfunc frame to enable PS when AP acks it */ - if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { - bf->bf_isnullfunc = true; - sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; - } else - bf->bf_isnullfunc = false; - bf->bf_tx_aborted = false; return 0; @@ -2081,18 +2074,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) break; } - /* - * We now know the nullfunc frame has been ACKed so we - * can disable RX. - */ - if (bf->bf_isnullfunc && - (ts.ts_status & ATH9K_TX_ACKED)) { - if ((sc->ps_flags & PS_ENABLED)) - ath9k_enable_ps(sc); - else - sc->ps_flags |= PS_NULLFUNC_COMPLETED; - } - /* * Remove ath_buf's of the same transmit unit from txq, * however leave the last descriptor back as the holding @@ -2236,17 +2217,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) txok = !(txs.ts_status & ATH9K_TXERR_MASK); - /* - * Make sure null func frame is acked before configuring - * hw into ps mode. - */ - if (bf->bf_isnullfunc && txok) { - if ((sc->ps_flags & PS_ENABLED)) - ath9k_enable_ps(sc); - else - sc->ps_flags |= PS_NULLFUNC_COMPLETED; - } - if (!bf_isampdu(bf)) { if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; -- cgit v1.2.3 From 845d708e62f08a45ff716fdb270c52585cad31d0 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 5 Oct 2010 20:36:41 +0530 Subject: ath9k: Introduce a wrapper for power save disable. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 40 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d0694cb685fa..74c2dc8a8b8a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1498,13 +1498,32 @@ static void ath9k_enable_ps(struct ath_softc *sc) } } +static void ath9k_disable_ps(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + sc->ps_enabled = false; + ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { + ath9k_hw_setrxabort(ah, 0); + sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | + PS_WAIT_FOR_CAB | + PS_WAIT_FOR_PSPOLL_DATA | + PS_WAIT_FOR_TX_ACK); + if (ah->imask & ATH9K_INT_TIM_TIMER) { + ah->imask &= ~ATH9K_INT_TIM_TIMER; + ath9k_hw_set_interrupts(ah, ah->imask); + } + } + +} + static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_conf *conf = &hw->conf; - struct ath_hw *ah = sc->sc_ah; bool disable_radio; mutex_lock(&sc->mutex); @@ -1553,23 +1572,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) spin_lock_irqsave(&sc->sc_pm_lock, flags); if (conf->flags & IEEE80211_CONF_PS) ath9k_enable_ps(sc); - else { - sc->ps_enabled = false; - ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); - if (!(ah->caps.hw_caps & - ATH9K_HW_CAP_AUTOSLEEP)) { - ath9k_hw_setrxabort(sc->sc_ah, 0); - sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | - PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK); - if (ah->imask & ATH9K_INT_TIM_TIMER) { - ah->imask &= ~ATH9K_INT_TIM_TIMER; - ath9k_hw_set_interrupts(sc->sc_ah, - ah->imask); - } - } - } + else + ath9k_disable_ps(sc); spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } -- cgit v1.2.3 From 53f73c09d64f1fa7d7e6e8b6bb7468d42eddc92d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Oct 2010 19:37:40 +0200 Subject: mac80211: avoid transmitting delBA to old AP When roaming while we have active BA session, we can end up transmitting delBA frames to the old AP while we're already on the new AP's channel, which can cause warnings. Simply avoid sending those frames, but still tear down the internal session state, since they are not really necessary anyway as we will implicitly disassociate when sending the association to the new AP. Signed-off-by: Johannes Berg Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 8 ++++---- net/mac80211/agg-tx.c | 14 +++++++++----- net/mac80211/debugfs_sta.c | 3 ++- net/mac80211/ht.c | 17 ++++++++++------- net/mac80211/ieee80211_i.h | 12 +++++++----- net/mac80211/iface.c | 3 ++- net/mac80211/mlme.c | 18 +++++++++--------- net/mac80211/pm.c | 2 +- net/mac80211/sta_info.c | 2 +- net/mac80211/sta_info.h | 2 ++ net/mac80211/util.c | 2 +- 11 files changed, 48 insertions(+), 35 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 58eab9e8e4ee..720b7a84af59 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) } void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason) + u16 initiator, u16 reason, bool tx) { struct ieee80211_local *local = sta->local; struct tid_ampdu_rx *tid_rx; @@ -81,7 +81,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, "aggregation for tid %d\n", tid); /* check if this is a self generated aggregation halt */ - if (initiator == WLAN_BACK_RECIPIENT) + if (initiator == WLAN_BACK_RECIPIENT && tx) ieee80211_send_delba(sta->sdata, sta->sta.addr, tid, 0, reason); @@ -92,10 +92,10 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, } void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason) + u16 initiator, u16 reason, bool tx) { mutex_lock(&sta->ampdu_mlme.mtx); - ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); + ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx); mutex_unlock(&sta->ampdu_mlme.mtx); } diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 8f23401832b7..d4679b265ba8 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head) } int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator) + enum ieee80211_back_parties initiator, + bool tx) { struct ieee80211_local *local = sta->local; struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; @@ -185,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); tid_tx->stop_initiator = initiator; + tid_tx->tx_stop = tx; ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_STOP, @@ -577,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator) + enum ieee80211_back_parties initiator, + bool tx) { int ret; mutex_lock(&sta->ampdu_mlme.mtx); - ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); + ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx); mutex_unlock(&sta->ampdu_mlme.mtx); @@ -672,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) goto unlock_sta; } - if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) + if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) ieee80211_send_delba(sta->sdata, ra, tid, WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); @@ -772,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, sta->ampdu_mlme.addba_req_num[tid] = 0; } else { - ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); + ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, + true); } out: diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6b7ff9fb4604..50c40ea3cb4d 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -196,7 +196,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu else ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); } else { - __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); + __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, + 3, true); ret = 0; } diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 11f74f5f7b2f..4214bb6e12fc 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, ht_cap->mcs.rx_mask[32/8] |= 1; } -void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) +void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx) { int i; cancel_work_sync(&sta->ampdu_mlme.work); for (i = 0; i < STA_TID_NUM; i++) { - __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR); + __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx); __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_LEAVE_QBSS); + WLAN_REASON_QSTA_LEAVE_QBSS, tx); } } @@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work) if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) ___ieee80211_stop_rx_ba_session( sta, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_TIMEOUT); + WLAN_REASON_QSTA_TIMEOUT, true); tid_tx = sta->ampdu_mlme.tid_tx[tid]; if (!tid_tx) @@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work) else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) ___ieee80211_stop_tx_ba_session(sta, tid, - WLAN_BACK_INITIATOR); + WLAN_BACK_INITIATOR, + true); } mutex_unlock(&sta->ampdu_mlme.mtx); } @@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) - __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0); + __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, + true); else - __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT); + __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, + true); } int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 08509e212841..76c2b50ec6f8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1175,10 +1175,10 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, void ieee80211_request_smps_work(struct work_struct *work); void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason); + u16 initiator, u16 reason, bool stop); void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason); -void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); + u16 initiator, u16 reason, bool stop); +void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx); void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee80211_mgmt *mgmt, size_t len); @@ -1192,9 +1192,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, size_t len); int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator); + enum ieee80211_back_parties initiator, + bool tx); int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator); + enum ieee80211_back_parties initiator, + bool tx); void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); void ieee80211_ba_session_work(struct work_struct *work); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 438a2f51420e..e99d1b60557c 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -796,7 +796,8 @@ static void ieee80211_iface_work(struct work_struct *work) __ieee80211_stop_rx_ba_session( sta, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_REQUIRE_SETUP); + WLAN_REASON_QSTA_REQUIRE_SETUP, + true); } mutex_unlock(&local->sta_mtx); } else switch (sdata->vif.type) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cd13aa82f835..5695c94c49aa 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -921,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, } static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, - bool remove_sta) + bool remove_sta, bool tx) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; @@ -960,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, sta = sta_info_get(sdata, bssid); if (sta) { set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, tx); } mutex_unlock(&local->sta_mtx); @@ -1124,7 +1124,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); mutex_lock(&local->mtx); @@ -1197,7 +1197,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", sdata->name, bssid, reason_code); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); mutex_unlock(&sdata->local->mtx); @@ -1229,7 +1229,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", sdata->name, mgmt->sa, reason_code); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); mutex_unlock(&sdata->local->mtx); @@ -1880,7 +1880,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "No probe response from AP %pM" " after %dms, disconnecting.\n", bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); mutex_lock(&local->mtx); ieee80211_recalc_idle(local); @@ -2204,7 +2204,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } /* Trying to reassociate - clear previous association state */ - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); } mutex_unlock(&ifmgd->mtx); @@ -2318,7 +2318,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, memcpy(bssid, req->bss->bssid, ETH_ALEN); if (ifmgd->associated == req->bss) { - ieee80211_set_disassoc(sdata, false); + ieee80211_set_disassoc(sdata, false, true); mutex_unlock(&ifmgd->mtx); assoc_bss = true; } else { @@ -2401,7 +2401,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, sdata->name, req->bss->bssid, req->reason_code); memcpy(bssid, req->bss->bssid, ETH_ALEN); - ieee80211_set_disassoc(sdata, false); + ieee80211_set_disassoc(sdata, false, true); mutex_unlock(&ifmgd->mtx); diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ce671dfd238c..e3e2bce3bb41 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -46,7 +46,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) list_for_each_entry(sta, &local->sta_list, list) { if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); } if (sta->uploaded) { diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ca2cba9cea87..aeaf2d6fccc8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -633,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) * will be sufficient. */ set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); spin_lock_irqsave(&local->sta_lock, flags); ret = sta_info_hash_del(local, sta); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 810c5ce98316..cf21a2e8134f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags { * @dialog_token: dialog token for aggregation session * @state: session state (see above) * @stop_initiator: initiator of a session stop + * @tx_stop: TX DelBA frame when stopping * * This structure is protected by RCU and the per-station * spinlock. Assignments to the array holding it must hold @@ -95,6 +96,7 @@ struct tid_ampdu_tx { unsigned long state; u8 dialog_token; u8 stop_initiator; + bool tx_stop; }; /** diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4ee8f2b53cb7..0b6fc92bc0d7 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1221,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) mutex_lock(&local->sta_mtx); list_for_each_entry(sta, &local->sta_list, list) { - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); clear_sta_flags(sta, WLAN_STA_BLOCK_BA); } -- cgit v1.2.3 From e31b82136d1adc7a599b6e99d3321e5831841f5a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Oct 2010 19:39:30 +0200 Subject: cfg80211/mac80211: allow per-station GTKs This adds API to allow adding per-station GTKs, updates mac80211 to support it, and also allows drivers to remove a key from hwaccel again when this may be necessary due to multiple GTKs. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 7 +- drivers/net/wireless/libertas/cfg.c | 4 +- drivers/net/wireless/rndis_wlan.c | 12 ++-- include/linux/nl80211.h | 12 ++++ include/net/cfg80211.h | 9 ++- include/net/mac80211.h | 24 +++++++ net/mac80211/cfg.c | 32 +++++++--- net/mac80211/ieee80211_i.h | 2 - net/mac80211/key.c | 95 ++++++++++++++++++---------- net/mac80211/key.h | 3 + net/mac80211/rx.c | 41 +++++++----- net/mac80211/sta_info.c | 10 +-- net/mac80211/sta_info.h | 6 +- net/mac80211/tx.c | 2 +- net/wireless/core.h | 2 +- net/wireless/ibss.c | 2 +- net/wireless/nl80211.c | 87 ++++++++++++++++++++++--- net/wireless/sme.c | 2 +- net/wireless/util.c | 12 +++- net/wireless/wext-compat.c | 38 +++++++---- 20 files changed, 293 insertions(+), 109 deletions(-) diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 60619678f4ec..c6c0eff9b5ed 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -161,7 +161,7 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index, } static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct iwm_priv *iwm = ndev_to_iwm(ndev); @@ -181,7 +181,8 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, } static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr, void *cookie, + u8 key_index, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params*)) { @@ -206,7 +207,7 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { struct iwm_priv *iwm = ndev_to_iwm(ndev); struct iwm_key *key = &iwm->keys[key_index]; diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index cb3b855d949c..1dc44bc6511f 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1438,7 +1438,7 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy, static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 idx, const u8 *mac_addr, + u8 idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct lbs_private *priv = wiphy_priv(wiphy); @@ -1498,7 +1498,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { lbs_deb_enter(LBS_DEB_CFG80211); diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 719573bbbf81..71b5971da597 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -540,11 +540,11 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, - struct key_params *params); + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params); static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr); + u8 key_index, bool pairwise, const u8 *mac_addr); static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -2308,8 +2308,8 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev, } static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, - struct key_params *params) + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; @@ -2344,7 +2344,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, } static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c4efdfa24ed8..e451f176e662 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -801,6 +801,9 @@ enum nl80211_commands { * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING * for non-automatic settings. * + * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly + * means support for per-station GTKs. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -968,6 +971,8 @@ enum nl80211_attrs { NL80211_ATTR_CONTROL_PORT_ETHERTYPE, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + NL80211_ATTR_SUPPORT_IBSS_RSN, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1659,11 +1664,14 @@ enum nl80211_auth_type { * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) + * @NUM_NL80211_KEYTYPES: number of defined key types */ enum nl80211_key_type { NL80211_KEYTYPE_GROUP, NL80211_KEYTYPE_PAIRWISE, NL80211_KEYTYPE_PEERKEY, + + NUM_NL80211_KEYTYPES }; /** @@ -1694,6 +1702,9 @@ enum nl80211_wpa_versions { * CCMP keys, each six bytes in little endian * @NL80211_KEY_DEFAULT: flag indicating default key * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key + * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not + * specified the default depends on whether a MAC address was + * given with the command using the key or not (u32) * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ @@ -1705,6 +1716,7 @@ enum nl80211_key_attributes { NL80211_KEY_SEQ, NL80211_KEY_DEFAULT, NL80211_KEY_DEFAULT_MGMT, + NL80211_KEY_TYPE, /* keep last */ __NL80211_KEY_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5f4d8acf7abb..0f77515266b8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1130,13 +1130,14 @@ struct cfg80211_ops { struct vif_params *params); int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, void *cookie, + u8 key_index, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params*)); int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr); + u8 key_index, bool pairwise, const u8 *mac_addr); int (*set_default_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -1304,6 +1305,7 @@ struct cfg80211_ops { * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the * control port protocol ethertype. The device also honours the * control_port_no_encrypt flag. + * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1314,6 +1316,7 @@ enum wiphy_flags { WIPHY_FLAG_4ADDR_AP = BIT(5), WIPHY_FLAG_4ADDR_STATION = BIT(6), WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), + WIPHY_FLAG_IBSS_RSN = BIT(7), }; struct mac_address { diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 47316a653ae1..33aa2e39147b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1041,6 +1041,13 @@ enum ieee80211_tkip_key_type { * @IEEE80211_HW_NEED_DTIM_PERIOD: * This device needs to know the DTIM period for the BSS before * associating. + * + * @IEEE80211_HW_SUPPORTS_PER_STA_GTK: The device's crypto engine supports + * per-station GTKs as used by IBSS RSN or during fast transition. If + * the device doesn't support per-station GTKs, but can be asked not + * to decrypt group addressed frames, then IBSS RSN support is still + * possible but software crypto will be used. Advertise the wiphy flag + * only in that case. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -1064,6 +1071,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, + IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, }; /** @@ -2582,6 +2590,22 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); void ieee80211_request_smps(struct ieee80211_vif *vif, enum ieee80211_smps_mode smps_mode); +/** + * ieee80211_key_removed - disable hw acceleration for key + * @key_conf: The key hw acceleration should be disabled for + * + * This allows drivers to indicate that the given key has been + * removed from hardware acceleration, due to a new key that + * was added. Don't use this if the key can continue to be used + * for TX, if the key restriction is on RX only it is permitted + * to keep the key for TX only and not call this function. + * + * Due to locking constraints, it may only be called during + * @set_key. This function must be allowed to sleep, and the + * key it tries to disable may still be used until it returns. + */ +void ieee80211_key_removed(struct ieee80211_key_conf *key_conf); + /* Rate control API */ /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 94bf550bd4c9..8b0e874a3d65 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -103,7 +103,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, } static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, + u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -131,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (IS_ERR(key)) return PTR_ERR(key); + if (pairwise) + key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; + mutex_lock(&sdata->local->sta_mtx); if (mac_addr) { @@ -153,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr) + u8 key_idx, bool pairwise, const u8 *mac_addr) { struct ieee80211_sub_if_data *sdata; struct sta_info *sta; @@ -170,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, if (!sta) goto out_unlock; - if (sta->key) { - ieee80211_key_free(sdata->local, sta->key); - WARN_ON(sta->key); - ret = 0; + if (pairwise) { + if (sta->ptk) { + ieee80211_key_free(sdata->local, sta->ptk); + ret = 0; + } + } else { + if (sta->gtk[key_idx]) { + ieee80211_key_free(sdata->local, + sta->gtk[key_idx]); + ret = 0; + } } goto out_unlock; @@ -195,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, void *cookie, + u8 key_idx, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params *params)) { @@ -203,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, struct sta_info *sta = NULL; u8 seq[6] = {0}; struct key_params params; - struct ieee80211_key *key; + struct ieee80211_key *key = NULL; u32 iv32; u16 iv16; int err = -ENOENT; @@ -217,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, if (!sta) goto out; - key = sta->key; + if (pairwise) + key = sta->ptk; + else if (key_idx < NUM_DEFAULT_KEYS) + key = sta->gtk[key_idx]; } else key = sdata->keys[key_idx]; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 76c2b50ec6f8..f0610fa4fbe0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -549,8 +549,6 @@ struct ieee80211_sub_if_data { struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; unsigned int fragment_next; -#define NUM_DEFAULT_KEYS 4 -#define NUM_DEFAULT_MGMT_KEYS 2 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; struct ieee80211_key *default_key; struct ieee80211_key *default_mgmt_key; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 6a63d1abd14d..ccd676b2f599 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -68,15 +68,21 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) might_sleep(); - if (!key->local->ops->set_key) { - ret = -EOPNOTSUPP; + if (!key->local->ops->set_key) goto out_unsupported; - } assert_key_lock(key->local); sta = get_sta_for_key(key); + /* + * If this is a per-STA GTK, check if it + * is supported; if not, return. + */ + if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) && + !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)) + goto out_unsupported; + sdata = key->sdata; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, @@ -85,31 +91,28 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); - if (!ret) + if (!ret) { key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; + return 0; + } - if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) + if (ret != -ENOSPC && ret != -EOPNOTSUPP) wiphy_err(key->local->hw.wiphy, "failed to set key (%d, %pM) to hardware (%d)\n", key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); -out_unsupported: - if (ret) { - switch (key->conf.cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_AES_CMAC: - /* all of these we can do in software */ - ret = 0; - break; - default: - ret = -EINVAL; - } + out_unsupported: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_AES_CMAC: + /* all of these we can do in software */ + return 0; + default: + return -EINVAL; } - - return ret; } static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) @@ -147,6 +150,26 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; } +void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) +{ + struct ieee80211_key *key; + + key = container_of(key_conf, struct ieee80211_key, conf); + + might_sleep(); + assert_key_lock(key->local); + + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; + + /* + * Flush TX path to avoid attempts to use this key + * after this function returns. Until then, drivers + * must be prepared to handle the key. + */ + synchronize_rcu(); +} +EXPORT_SYMBOL_GPL(ieee80211_key_removed); + static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) { @@ -202,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, + bool pairwise, struct ieee80211_key *old, struct ieee80211_key *new) { @@ -210,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, if (new) list_add(&new->list, &sdata->key_list); - if (sta) { - rcu_assign_pointer(sta->key, new); + if (sta && pairwise) { + rcu_assign_pointer(sta->ptk, new); + } else if (sta) { + if (old) + idx = old->conf.keyidx; + else + idx = new->conf.keyidx; + rcu_assign_pointer(sta->gtk[idx], new); } else { WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); @@ -355,6 +385,7 @@ int ieee80211_key_link(struct ieee80211_key *key, { struct ieee80211_key *old_key; int idx, ret; + bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; BUG_ON(!sdata); BUG_ON(!key); @@ -371,13 +402,6 @@ int ieee80211_key_link(struct ieee80211_key *key, */ if (test_sta_flags(sta, WLAN_STA_WME)) key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; - - /* - * This key is for a specific sta interface, - * inform the driver that it should try to store - * this key as pairwise key. - */ - key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; } else { if (sdata->vif.type == NL80211_IFTYPE_STATION) { struct sta_info *ap; @@ -399,12 +423,14 @@ int ieee80211_key_link(struct ieee80211_key *key, mutex_lock(&sdata->local->key_mtx); - if (sta) - old_key = sta->key; + if (sta && pairwise) + old_key = sta->ptk; + else if (sta) + old_key = sta->gtk[idx]; else old_key = sdata->keys[idx]; - __ieee80211_key_replace(sdata, sta, old_key, key); + __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); __ieee80211_key_destroy(old_key); ieee80211_debugfs_key_add(key); @@ -423,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key) */ if (key->sdata) __ieee80211_key_replace(key->sdata, key->sta, - key, NULL); + key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, + key, NULL); __ieee80211_key_destroy(key); } diff --git a/net/mac80211/key.h b/net/mac80211/key.h index cb9a4a65cc68..0db1c0f5f697 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -16,6 +16,9 @@ #include #include +#define NUM_DEFAULT_KEYS 4 +#define NUM_DEFAULT_MGMT_KEYS 2 + #define WEP_IV_LEN 4 #define WEP_ICV_LEN 4 #define ALG_TKIP_KEY_LEN 32 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b3e161ffa4b3..b67221def584 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -846,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) int keyidx; int hdrlen; ieee80211_rx_result result = RX_DROP_UNUSABLE; - struct ieee80211_key *stakey = NULL; + struct ieee80211_key *sta_ptk = NULL; int mmie_keyidx = -1; __le16 fc; @@ -888,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) rx->key = NULL; if (rx->sta) - stakey = rcu_dereference(rx->sta->key); + sta_ptk = rcu_dereference(rx->sta->ptk); fc = hdr->frame_control; if (!ieee80211_has_protected(fc)) mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); - if (!is_multicast_ether_addr(hdr->addr1) && stakey) { - rx->key = stakey; + if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { + rx->key = sta_ptk; if ((status->flag & RX_FLAG_DECRYPTED) && (status->flag & RX_FLAG_IV_STRIPPED)) return RX_CONTINUE; @@ -912,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) if (mmie_keyidx < NUM_DEFAULT_KEYS || mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) return RX_DROP_MONITOR; /* unexpected BIP keyidx */ - rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); + if (rx->sta) + rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); + if (!rx->key) + rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); } else if (!ieee80211_has_protected(fc)) { /* * The frame was not protected, so skip decryption. However, we @@ -955,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); keyidx = keyid >> 6; - rx->key = rcu_dereference(rx->sdata->keys[keyidx]); + /* check per-station GTK first, if multicast packet */ + if (is_multicast_ether_addr(hdr->addr1) && rx->sta) + rx->key = rcu_dereference(rx->sta->gtk[keyidx]); - /* - * RSNA-protected unicast frames should always be sent with - * pairwise or station-to-station keys, but for WEP we allow - * using a key index as well. - */ - if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && - rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && - !is_multicast_ether_addr(hdr->addr1)) - rx->key = NULL; + /* if not found, try default key */ + if (!rx->key) { + rx->key = rcu_dereference(rx->sdata->keys[keyidx]); + + /* + * RSNA-protected unicast frames should always be + * sent with pairwise or station-to-station keys, + * but for WEP we allow using a key index as well. + */ + if (rx->key && + rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && + rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && + !is_multicast_ether_addr(hdr->addr1)) + rx->key = NULL; + } } if (rx->key) { diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index aeaf2d6fccc8..6d8f897d8763 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -616,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) struct ieee80211_sub_if_data *sdata; struct sk_buff *skb; unsigned long flags; - int ret; + int ret, i; might_sleep(); @@ -644,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) if (ret) return ret; - if (sta->key) { - ieee80211_key_free(local, sta->key); - WARN_ON(sta->key); - } + for (i = 0; i < NUM_DEFAULT_KEYS; i++) + ieee80211_key_free(local, sta->gtk[i]); + if (sta->ptk) + ieee80211_key_free(local, sta->ptk); sta->dead = true; diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index cf21a2e8134f..9265acadef32 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -199,7 +199,8 @@ enum plink_state { * @hnext: hash table linked list pointer * @local: pointer to the global information * @sdata: virtual interface this station belongs to - * @key: peer key negotiated with this station, if any + * @ptk: peer key negotiated with this station, if any + * @gtk: group keys negotiated with this station, if any * @rate_ctrl: rate control algorithm reference * @rate_ctrl_priv: rate control private per-STA pointer * @last_tx_rate: rate used for last transmit, to report to userspace as @@ -254,7 +255,8 @@ struct sta_info { struct sta_info *hnext; struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; - struct ieee80211_key *key; + struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; + struct ieee80211_key *ptk; struct rate_control_ref *rate_ctrl; void *rate_ctrl_priv; spinlock_t lock; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 258fbdbedbdf..96c594309506 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -532,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) tx->key = NULL; - else if (tx->sta && (key = rcu_dereference(tx->sta->key))) + else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) tx->key = key; else if (ieee80211_is_mgmt(hdr->frame_control) && is_multicast_ether_addr(hdr->addr1) && diff --git a/net/wireless/core.h b/net/wireless/core.h index 37580e090a3d..2d1d4c70113c 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -375,7 +375,7 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); /* internal helpers */ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, struct key_params *params, int key_idx, - const u8 *mac_addr); + bool pairwise, const u8 *mac_addr); void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, size_t ie_len, u16 reason, bool from_ap); void cfg80211_sme_scan_done(struct net_device *dev); diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 8cb6e08373b9..f33fbb79437c 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -160,7 +160,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev->ops->del_key(wdev->wiphy, dev, i, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0c9497170f1f..8826888cc14e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -93,6 +93,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, + [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, @@ -168,7 +169,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, }; -/* policy for the attributes */ +/* policy for the key attributes */ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, [NL80211_KEY_IDX] = { .type = NLA_U8 }, @@ -176,6 +177,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, + [NL80211_KEY_TYPE] = { .type = NLA_U32 }, }; /* ifidx get helper */ @@ -306,6 +308,7 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct key_parse { struct key_params p; int idx; + int type; bool def, defmgmt; }; @@ -336,6 +339,12 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) if (tb[NL80211_KEY_CIPHER]) k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); + if (tb[NL80211_KEY_TYPE]) { + k->type = nla_get_u32(tb[NL80211_KEY_TYPE]); + if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) + return -EINVAL; + } + return 0; } @@ -360,6 +369,12 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k) k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; + if (info->attrs[NL80211_ATTR_KEY_TYPE]) { + k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); + if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) + return -EINVAL; + } + return 0; } @@ -369,6 +384,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) memset(k, 0, sizeof(*k)); k->idx = -1; + k->type = -1; if (info->attrs[NL80211_ATTR_KEY]) err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); @@ -433,7 +449,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, } else if (parse.defmgmt) goto error; err = cfg80211_validate_key_settings(rdev, &parse.p, - parse.idx, NULL); + parse.idx, false, NULL); if (err) goto error; result->params[parse.idx].cipher = parse.p.cipher; @@ -516,6 +532,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, dev->wiphy.max_scan_ie_len); + if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); + NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, dev->wiphy.cipher_suites); @@ -1446,7 +1465,8 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) int err; struct net_device *dev = info->user_ptr[1]; u8 key_idx = 0; - u8 *mac_addr = NULL; + const u8 *mac_addr = NULL; + bool pairwise; struct get_key_cookie cookie = { .error = 0, }; @@ -1462,6 +1482,17 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + pairwise = !!mac_addr; + if (info->attrs[NL80211_ATTR_KEY_TYPE]) { + u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); + if (kt >= NUM_NL80211_KEYTYPES) + return -EINVAL; + if (kt != NL80211_KEYTYPE_GROUP && + kt != NL80211_KEYTYPE_PAIRWISE) + return -EINVAL; + pairwise = kt == NL80211_KEYTYPE_PAIRWISE; + } + if (!rdev->ops->get_key) return -EOPNOTSUPP; @@ -1482,8 +1513,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (mac_addr) NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); - err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr, - &cookie, get_key_callback); + if (pairwise && mac_addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + return -ENOENT; + + err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise, + mac_addr, &cookie, get_key_callback); if (err) goto free_msg; @@ -1553,7 +1588,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) int err; struct net_device *dev = info->user_ptr[1]; struct key_parse key; - u8 *mac_addr = NULL; + const u8 *mac_addr = NULL; err = nl80211_parse_key(info, &key); if (err) @@ -1565,16 +1600,31 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + if (key.type == -1) { + if (mac_addr) + key.type = NL80211_KEYTYPE_PAIRWISE; + else + key.type = NL80211_KEYTYPE_GROUP; + } + + /* for now */ + if (key.type != NL80211_KEYTYPE_PAIRWISE && + key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; + if (!rdev->ops->add_key) return -EOPNOTSUPP; - if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) + if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr)) return -EINVAL; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); if (!err) err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, mac_addr, &key.p); wdev_unlock(dev->ieee80211_ptr); @@ -1596,13 +1646,32 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + if (key.type == -1) { + if (mac_addr) + key.type = NL80211_KEYTYPE_PAIRWISE; + else + key.type = NL80211_KEYTYPE_GROUP; + } + + /* for now */ + if (key.type != NL80211_KEYTYPE_PAIRWISE && + key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; + if (!rdev->ops->del_key) return -EOPNOTSUPP; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); + + if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + err = -ENOENT; + if (!err) - err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr); + err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr); #ifdef CONFIG_CFG80211_WEXT if (!err) { @@ -3212,6 +3281,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) return err; if (key.idx >= 0) { + if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; if (!key.p.key || !key.p.key_len) return -EINVAL; if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || diff --git a/net/wireless/sme.c b/net/wireless/sme.c index f161b9844542..e17b0bee6bdc 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -698,7 +698,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev->ops->del_key(wdev->wiphy, dev, i, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); #ifdef CONFIG_CFG80211_WEXT memset(&wrqu, 0, sizeof(wrqu)); diff --git a/net/wireless/util.c b/net/wireless/util.c index fb5448f7d55a..76120aeda57d 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy) int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, struct key_params *params, int key_idx, - const u8 *mac_addr) + bool pairwise, const u8 *mac_addr) { int i; if (key_idx > 5) return -EINVAL; + if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + return -EINVAL; + + if (pairwise && !mac_addr) + return -EINVAL; + /* * Disallow pairwise keys with non-zero index unless it's WEP * (because current deployments use pairwise WEP keys with * non-zero indizes but 802.11i clearly specifies to use zero) */ - if (mac_addr && key_idx && + if (pairwise && key_idx && params->cipher != WLAN_CIPHER_SUITE_WEP40 && params->cipher != WLAN_CIPHER_SUITE_WEP104) return -EINVAL; @@ -677,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) for (i = 0; i < 6; i++) { if (!wdev->connect_keys->params[i].cipher) continue; - if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, + if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, &wdev->connect_keys->params[i])) { printk(KERN_ERR "%s: failed to set key %d\n", dev->name, i); diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 7e5c3a45f811..6002265289c6 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -432,14 +432,17 @@ int cfg80211_wext_giwretry(struct net_device *dev, EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *addr, - bool remove, bool tx_key, int idx, - struct key_params *params) + struct net_device *dev, bool pairwise, + const u8 *addr, bool remove, bool tx_key, + int idx, struct key_params *params) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err, i; bool rejoin = false; + if (pairwise && !addr) + return -EINVAL; + if (!wdev->wext.keys) { wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), GFP_KERNEL); @@ -478,7 +481,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, __cfg80211_leave_ibss(rdev, wdev->netdev, true); rejoin = true; } - err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); + + if (!pairwise && addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + err = -ENOENT; + else + err = rdev->ops->del_key(&rdev->wiphy, dev, idx, + pairwise, addr); } wdev->wext.connect.privacy = false; /* @@ -507,12 +516,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if (addr) tx_key = false; - if (cfg80211_validate_key_settings(rdev, params, idx, addr)) + if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr)) return -EINVAL; err = 0; if (wdev->current_bss) - err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params); + err = rdev->ops->add_key(&rdev->wiphy, dev, idx, + pairwise, addr, params); if (err) return err; @@ -563,17 +573,17 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, } static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *addr, - bool remove, bool tx_key, int idx, - struct key_params *params) + struct net_device *dev, bool pairwise, + const u8 *addr, bool remove, bool tx_key, + int idx, struct key_params *params) { int err; /* devlist mutex needed for possible IBSS re-join */ mutex_lock(&rdev->devlist_mtx); wdev_lock(dev->ieee80211_ptr); - err = __cfg80211_set_encryption(rdev, dev, addr, remove, - tx_key, idx, params); + err = __cfg80211_set_encryption(rdev, dev, pairwise, addr, + remove, tx_key, idx, params); wdev_unlock(dev->ieee80211_ptr); mutex_unlock(&rdev->devlist_mtx); @@ -635,7 +645,7 @@ int cfg80211_wext_siwencode(struct net_device *dev, else if (!remove) return -EINVAL; - return cfg80211_set_encryption(rdev, dev, NULL, remove, + return cfg80211_set_encryption(rdev, dev, false, NULL, remove, wdev->wext.default_key == -1, idx, ¶ms); } @@ -725,7 +735,9 @@ int cfg80211_wext_siwencodeext(struct net_device *dev, } return cfg80211_set_encryption( - rdev, dev, addr, remove, + rdev, dev, + !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY), + addr, remove, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, idx, ¶ms); } -- cgit v1.2.3 From d537f5fdfcc9c57c1e3b9fb316a4bed2bf7597e7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Oct 2010 21:34:11 +0200 Subject: nl80211: fix error in generic netif_running check Yikes! The error return keeps a netdev reference and the rdev mutex locked, fix that! Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8826888cc14e..9942f0b061ff 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4418,6 +4418,8 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, } if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && !netif_running(dev)) { + cfg80211_unlock_rdev(rdev); + dev_put(dev); if (rtnl) rtnl_unlock(); return -ENETDOWN; -- cgit v1.2.3 From 5e7ee098ce2795e0c2628686dd97fc64bcc11594 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 6 Oct 2010 07:50:06 +0200 Subject: b43: N-PHY: simplify channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 5f0ce35bbe27..74c32b06efa1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -73,7 +73,8 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, u16 value, u8 core, bool off); static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); -static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel); +static int b43_nphy_op_switch_channel(struct b43_wldev *dev, + unsigned int new_channel); static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) { @@ -223,7 +224,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) if (i) b43err(dev->wl, "radio post init timeout\n"); b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); - nphy_channel_switch(dev, dev->phy.channel); + b43_nphy_op_switch_channel(dev, dev->phy.channel); b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); @@ -3438,18 +3439,6 @@ static int b43_nphy_set_chanspec(struct b43_wldev *dev, return 0; } -/* Tune the hardware to a new channel */ -static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) -{ - struct b43_phy_n *nphy = dev->phy.n; - - struct b43_chanspec chanspec; - chanspec = nphy->radio_chanspec; - chanspec.channel = channel; - - return b43_nphy_set_chanspec(dev, chanspec); -} - static int b43_nphy_op_allocate(struct b43_wldev *dev) { struct b43_phy_n *nphy; @@ -3570,7 +3559,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, } else { if (dev->phy.rev >= 3) { b43_radio_init2056(dev); - b43_nphy_set_chanspec(dev, nphy->radio_chanspec); + b43_nphy_op_switch_channel(dev, dev->phy.channel); } else { b43_radio_init2055(dev); } @@ -3586,6 +3575,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) static int b43_nphy_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { + struct b43_phy_n *nphy = dev->phy.n; + struct b43_chanspec chanspec; + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { if ((new_channel < 1) || (new_channel > 14)) return -EINVAL; @@ -3594,7 +3586,10 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev, return -EINVAL; } - return nphy_channel_switch(dev, new_channel); + chanspec = nphy->radio_chanspec; + chanspec.channel = new_channel; + + return b43_nphy_set_chanspec(dev, chanspec); } static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) -- cgit v1.2.3 From 106cb09a145a5c6d8e206af41284c300b13c408c Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 6 Oct 2010 07:50:07 +0200 Subject: b43: define B43_SHM_SH_CHAN_40MHZ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 3 ++- drivers/net/wireless/b43/phy_common.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 8674a99356af..72821c456b02 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -186,7 +186,8 @@ enum { #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ #define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */ #define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ -#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */ +#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ +#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ #define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ /* TSSI information */ #define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */ diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 8f7d7eff2d80..7b2ea6781457 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -294,8 +294,10 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel) */ channelcookie = new_channel; if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) - channelcookie |= 0x100; - //FIXME set 40Mhz flag if required + channelcookie |= B43_SHM_SH_CHAN_5GHZ; + /* FIXME: set 40Mhz flag if required */ + if (0) + channelcookie |= B43_SHM_SH_CHAN_40MHZ; savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie); -- cgit v1.2.3 From 78159788e1d0909ffa6beb714dcca7f3aa4574a2 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 6 Oct 2010 07:50:08 +0200 Subject: b43: N-PHY: don't duplicate setting channel in shared memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's already set in PHY common code. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 74c32b06efa1..52ce4383a056 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -73,8 +73,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, u16 value, u8 core, bool off); static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); -static int b43_nphy_op_switch_channel(struct b43_wldev *dev, - unsigned int new_channel); static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) { @@ -224,7 +222,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) if (i) b43err(dev->wl, "radio post init timeout\n"); b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); - b43_nphy_op_switch_channel(dev, dev->phy.channel); + b43_switch_channel(dev, dev->phy.channel); b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); @@ -3352,12 +3350,6 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, b43_chantab_phy_upload(dev, e); - tmp = chanspec.channel; - if (chanspec.b_freq == 1) - tmp |= 0x0100; - if (chanspec.b_width == 3) - tmp |= 0x0200; - b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp); if (nphy->radio_chanspec.channel == 14) { b43_nphy_classifier(dev, 2, 0); @@ -3559,7 +3551,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, } else { if (dev->phy.rev >= 3) { b43_radio_init2056(dev); - b43_nphy_op_switch_channel(dev, dev->phy.channel); + b43_switch_channel(dev, dev->phy.channel); } else { b43_radio_init2055(dev); } -- cgit v1.2.3 From 259b62e35bf44a97983f275de569929a7d2bd5dd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:08 +0200 Subject: mac80211: reduce number of __ieee80211_scan_completed calls Use goto instruction to call __ieee80211_scan_completed only ones in ieee80211_scan_work. This is prepare for the next patch. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5171a9581631..830c02bc398a 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -651,27 +651,25 @@ void ieee80211_scan_work(struct work_struct *work) container_of(work, struct ieee80211_local, scan_work.work); struct ieee80211_sub_if_data *sdata = local->scan_sdata; unsigned long next_delay = 0; + bool aborted; - if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { - bool aborted; + mutex_lock(&local->mtx); + if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); - __ieee80211_scan_completed(&local->hw, aborted); - return; + goto out_complete; } - mutex_lock(&local->mtx); - if (!sdata || !local->scan_req) { - mutex_unlock(&local->mtx); - return; - } + if (!sdata || !local->scan_req) + goto out; if (local->hw_scan_req) { int rc = drv_hw_scan(local, sdata, local->hw_scan_req); - mutex_unlock(&local->mtx); - if (rc) - __ieee80211_scan_completed(&local->hw, true); - return; + if (rc) { + aborted = true; + goto out_complete; + } else + goto out; } if (local->scan_req && !local->scanning) { @@ -682,23 +680,23 @@ void ieee80211_scan_work(struct work_struct *work) local->scan_sdata = NULL; rc = __ieee80211_start_scan(sdata, req); - mutex_unlock(&local->mtx); - - if (rc) - __ieee80211_scan_completed(&local->hw, true); - return; + if (rc) { + aborted = true; + goto out_complete; + } else + goto out; } - mutex_unlock(&local->mtx); - /* * Avoid re-scheduling when the sdata is going away. */ if (!ieee80211_sdata_running(sdata)) { - __ieee80211_scan_completed(&local->hw, true); - return; + aborted = true; + goto out_complete; } + mutex_unlock(&local->mtx); + /* * as long as no delay is required advance immediately * without scheduling a new work @@ -725,6 +723,15 @@ void ieee80211_scan_work(struct work_struct *work) } while (next_delay == 0); ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); + return; + +out_complete: + mutex_unlock(&local->mtx); + __ieee80211_scan_completed(&local->hw, aborted); + return; + +out: + mutex_unlock(&local->mtx); } int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, -- cgit v1.2.3 From e229f844d7223b7063bea1e649203ac521a58fe1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:09 +0200 Subject: mac80211: keep lock when calling __ieee80211_scan_completed() We are taking local->mtx inside __ieee80211_scan_completed(), but just before call to that function we drop the lock. Dropping/taking lock is not good, because can lead to hard to understand race conditions. Patch split scan_completed() code into two functions, first must be called with local->mtx taken and second without it. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 75 ++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 830c02bc398a..6964a4598176 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -249,12 +249,12 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) return true; } -static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) +static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, + bool was_hw_scan) { struct ieee80211_local *local = hw_to_local(hw); - bool was_hw_scan; - mutex_lock(&local->mtx); + lockdep_assert_held(&local->mtx); /* * It's ok to abort a not-yet-running scan (that @@ -265,17 +265,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (WARN_ON(!local->scanning && !aborted)) aborted = true; - if (WARN_ON(!local->scan_req)) { - mutex_unlock(&local->mtx); - return; - } + if (WARN_ON(!local->scan_req)) + return false; - was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); - mutex_unlock(&local->mtx); - return; + return false; } kfree(local->hw_scan_req); @@ -289,23 +285,25 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) local->scanning = 0; local->scan_channel = NULL; - /* we only have to protect scan_req and hw/sw scan */ - mutex_unlock(&local->mtx); - - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - if (was_hw_scan) - goto done; - - ieee80211_configure_filter(local); + return true; +} - drv_sw_scan_complete(local); +static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, + bool was_hw_scan) +{ + struct ieee80211_local *local = hw_to_local(hw); - ieee80211_offchannel_return(local, true); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + if (!was_hw_scan) { + ieee80211_configure_filter(local); + drv_sw_scan_complete(local); + ieee80211_offchannel_return(local, true); + } - done: mutex_lock(&local->mtx); ieee80211_recalc_idle(local); mutex_unlock(&local->mtx); + ieee80211_mlme_notify_scan_completed(local); ieee80211_ibss_notify_scan_completed(local); ieee80211_mesh_notify_scan_completed(local); @@ -366,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; int rc; + lockdep_assert_held(&local->mtx); + if (local->scan_req) return -EBUSY; @@ -447,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan) return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; } -static int ieee80211_scan_state_decision(struct ieee80211_local *local, - unsigned long *next_delay) +static void ieee80211_scan_state_decision(struct ieee80211_local *local, + unsigned long *next_delay) { bool associated = false; bool tx_empty = true; @@ -458,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *next_chan; - /* if no more bands/channels left, complete scan and advance to the idle state */ - if (local->scan_channel_idx >= local->scan_req->n_channels) { - __ieee80211_scan_completed(&local->hw, false); - return 1; - } - /* * check if at least one STA interface is associated, * check if at least one STA interface has pending tx frames @@ -535,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, } *next_delay = 0; - return 0; } static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, @@ -651,7 +644,7 @@ void ieee80211_scan_work(struct work_struct *work) container_of(work, struct ieee80211_local, scan_work.work); struct ieee80211_sub_if_data *sdata = local->scan_sdata; unsigned long next_delay = 0; - bool aborted; + bool aborted, hw_scan, finish; mutex_lock(&local->mtx); @@ -704,8 +697,12 @@ void ieee80211_scan_work(struct work_struct *work) do { switch (local->next_scan_state) { case SCAN_DECISION: - if (ieee80211_scan_state_decision(local, &next_delay)) - return; + /* if no more bands/channels left, complete scan */ + if (local->scan_channel_idx >= local->scan_req->n_channels) { + aborted = false; + goto out_complete; + } + ieee80211_scan_state_decision(local, &next_delay); break; case SCAN_SET_CHANNEL: ieee80211_scan_state_set_channel(local, &next_delay); @@ -726,8 +723,11 @@ void ieee80211_scan_work(struct work_struct *work) return; out_complete: + hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); + finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan); mutex_unlock(&local->mtx); - __ieee80211_scan_completed(&local->hw, aborted); + if (finish) + __ieee80211_scan_completed_finish(&local->hw, hw_scan); return; out: @@ -796,6 +796,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, void ieee80211_scan_cancel(struct ieee80211_local *local) { bool abortscan; + bool finish = false; cancel_delayed_work_sync(&local->scan_work); @@ -806,8 +807,10 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) mutex_lock(&local->mtx); abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || (!local->scanning && local->scan_req); + if (abortscan) + finish = __ieee80211_scan_completed(&local->hw, true, false); mutex_unlock(&local->mtx); - if (abortscan) - __ieee80211_scan_completed(&local->hw, true); + if (finish) + __ieee80211_scan_completed_finish(&local->hw, false); } -- cgit v1.2.3 From 4136c4224ccf1907d309e1cdfaefef9da97dbc5e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:10 +0200 Subject: mac80211: assure we also cancel deferred scan request This is partial revert and fix for commit 85f72bc839705294b32b6c16b491c0422f0a71b3 "mac80211: only cancel software-based scans on suspend" When cfg80211 request the scan and mac80211 perform some management work, we defer the scan request. We do not canceling such requests when calling ieee80211_scan_cancel(), because of SCAN_SW_SCANNING bit check just before the call. So fix that problem. Another problem, which commit 85f72bc839705294b32b6c16b491c0422f0a71b3 tries to solve, is we can not cancel HW scan. Hence patch make ieee80211_scan_cancel() ignore HW scan (see code comments). Keeping local->mtx lock assures that the deferred scan will not become "working" HW scan. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 3 +-- net/mac80211/pm.c | 3 +-- net/mac80211/scan.c | 35 +++++++++++++++++++++++++---------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e3717092115f..915ecf87e4ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -307,8 +307,7 @@ static void ieee80211_restart_work(struct work_struct *work) mutex_unlock(&local->mtx); rtnl_lock(); - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) - ieee80211_scan_cancel(local); + ieee80211_scan_cancel(local); ieee80211_reconfig(local); rtnl_unlock(); } diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index e3e2bce3bb41..e37355193ed1 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -12,8 +12,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) struct ieee80211_sub_if_data *sdata; struct sta_info *sta; - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) - ieee80211_scan_cancel(local); + ieee80211_scan_cancel(local); ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 6964a4598176..4dbef714d946 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -793,24 +793,39 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, return ret; } +/* + * Only call this function when a scan can't be queued -- under RTNL. + */ void ieee80211_scan_cancel(struct ieee80211_local *local) { - bool abortscan; - bool finish = false; - - cancel_delayed_work_sync(&local->scan_work); + bool abortscan, finish; /* - * Only call this function when a scan can't be - * queued -- mostly at suspend under RTNL. + * We are only canceling software scan, or deferred scan that was not + * yet really started (see __ieee80211_start_scan ). + * + * Regarding hardware scan: + * - we can not call __ieee80211_scan_completed() as when + * SCAN_HW_SCANNING bit is set this function change + * local->hw_scan_req to operate on 5G band, what race with + * driver which can use local->hw_scan_req + * + * - we can not cancel scan_work since driver can schedule it + * by ieee80211_scan_completed(..., true) to finish scan + * + * Hence low lever driver is responsible for canceling HW scan. */ + mutex_lock(&local->mtx); - abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || - (!local->scanning && local->scan_req); + abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); if (abortscan) finish = __ieee80211_scan_completed(&local->hw, true, false); mutex_unlock(&local->mtx); - if (finish) - __ieee80211_scan_completed_finish(&local->hw, false); + if (abortscan) { + /* The scan is canceled, but stop work from being pending */ + cancel_delayed_work_sync(&local->scan_work); + if (finish) + __ieee80211_scan_completed_finish(&local->hw, false); + } } -- cgit v1.2.3 From 6eb11a9a311a0f7e5b9b66c18f7498a26c9ec206 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:11 +0200 Subject: mac80211: do not requeue scan work when not needed When performing hw scan and not abort it, __ieee80211_scan_completed() is currently called from scan work, so does not need to reschedule work to call drv_hw_scan(). Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 4dbef714d946..9aab921f7ca8 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -269,9 +269,9 @@ static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, return false; if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { - ieee80211_queue_delayed_work(&local->hw, - &local->scan_work, 0); - return false; + int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); + if (rc == 0) + return false; } kfree(local->hw_scan_req); @@ -656,15 +656,6 @@ void ieee80211_scan_work(struct work_struct *work) if (!sdata || !local->scan_req) goto out; - if (local->hw_scan_req) { - int rc = drv_hw_scan(local, sdata, local->hw_scan_req); - if (rc) { - aborted = true; - goto out_complete; - } else - goto out; - } - if (local->scan_req && !local->scanning) { struct cfg80211_scan_request *req = local->scan_req; int rc; -- cgit v1.2.3 From 3aed49ef17c7bc8397420529ac976fe058818e3d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:12 +0200 Subject: mac80211: compete scan to cfg80211 if deferred scan fail to start We nulify local->scan_req on failure in __ieee80211_start_scan, so __ieee80211_scan_completed will not call cfg80211_scan_done. Fix that. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 9aab921f7ca8..80e017df5f31 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -665,6 +665,8 @@ void ieee80211_scan_work(struct work_struct *work) rc = __ieee80211_start_scan(sdata, req); if (rc) { + /* need to complete scan in cfg80211 */ + local->scan_req = req; aborted = true; goto out_complete; } else -- cgit v1.2.3 From 09be251e9005ebd67e5eabcaad904edb7ecacc55 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 6 Oct 2010 11:22:13 +0200 Subject: Revert "iwlwifi: do not perferm force reset while doing scan" This reverts commit 7acc7c683a747689aaaaad4fce1683fc3f85e552. It was applied to avoid possible warning in ieee80211_restart_hw, however reason of the warning were races in mac80211, currently hopefully fixed. Not reseting device when performing scan is bad for two reasons. When forcing reset from iwl_check_stuck_queue(), in case of fail, reset will be repeated until scan finish. But since firmware is in bad shape, scan only finish after scan_check work (about 7s). So we will delay the reset, what is not good behaviour. When forcing reset from iwl_recover_from_statistics(), we will not repeat the reset, so we will not perform reset at all when needed. Signed-off-by: Stanislaw Gruszka Acked-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b7adcf87280d..3532e1dadf10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2737,11 +2737,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; - if (test_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_INFO(priv, "scan in progress.\n"); - return -EINVAL; - } - if (mode >= IWL_MAX_FORCE_RESET) { IWL_DEBUG_INFO(priv, "invalid reset request.\n"); return -EINVAL; -- cgit v1.2.3 From b206b4ef062d83c0875a085672ed50e8c8b01521 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 6 Oct 2010 18:34:12 +0900 Subject: nl80211/mac80211: Add retry and failed transmission count to station info This information is already available in mac80211, we just need to export it via cfg80211 and nl80211. Signed-off-by: Bruno Randolf Acked-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/cfg80211.h | 8 ++++++++ net/mac80211/cfg.c | 4 ++++ net/wireless/nl80211.c | 6 ++++++ 4 files changed, 22 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index e451f176e662..c08709fe36fc 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1137,6 +1137,8 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID, @@ -1150,6 +1152,8 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_BITRATE, NL80211_STA_INFO_RX_PACKETS, NL80211_STA_INFO_TX_PACKETS, + NL80211_STA_INFO_TX_RETRIES, + NL80211_STA_INFO_TX_FAILED, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0f77515266b8..e76daaa7dc25 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -401,6 +401,8 @@ struct station_parameters { * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) * @STATION_INFO_RX_PACKETS: @rx_packets filled * @STATION_INFO_TX_PACKETS: @tx_packets filled + * @STATION_INFO_TX_RETRIES: @tx_retries filled + * @STATION_INFO_TX_FAILED: @tx_failed filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -413,6 +415,8 @@ enum station_info_flags { STATION_INFO_TX_BITRATE = 1<<7, STATION_INFO_RX_PACKETS = 1<<8, STATION_INFO_TX_PACKETS = 1<<9, + STATION_INFO_TX_RETRIES = 1<<10, + STATION_INFO_TX_FAILED = 1<<11, }; /** @@ -462,6 +466,8 @@ struct rate_info { * @txrate: current unicast bitrate to this station * @rx_packets: packets received from this station * @tx_packets: packets transmitted to this station + * @tx_retries: cumulative retry counts + * @tx_failed: number of failed transmissions (retries exceeded, no ACK) * @generation: generation number for nl80211 dumps. * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that @@ -479,6 +485,8 @@ struct station_info { struct rate_info txrate; u32 rx_packets; u32 tx_packets; + u32 tx_retries; + u32 tx_failed; int generation; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8b0e874a3d65..2e5a3fb38efe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -327,6 +327,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_BYTES | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED | STATION_INFO_TX_BITRATE; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); @@ -334,6 +336,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->tx_bytes = sta->tx_bytes; sinfo->rx_packets = sta->rx_packets; sinfo->tx_packets = sta->tx_packets; + sinfo->tx_retries = sta->tx_retry_count; + sinfo->tx_failed = sta->tx_retry_failed; if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9942f0b061ff..524f55402838 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1890,6 +1890,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_TX_PACKETS) NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS, sinfo->tx_packets); + if (sinfo->filled & STATION_INFO_TX_RETRIES) + NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES, + sinfo->tx_retries); + if (sinfo->filled & STATION_INFO_TX_FAILED) + NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, + sinfo->tx_failed); nla_nest_end(msg, sinfoattr); return genlmsg_end(msg, hdr); -- cgit v1.2.3 From 3207390a8b58bfc1335750f91cf6783c48ca19ca Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Oct 2010 21:18:04 +0200 Subject: cfg80211: fix BSS double-unlinking When multiple interfaces are actively trying to associate with the same BSS, they may both find that the BSS isn't there and then try to unlink it. This can cause errors since the unlinking code can't currently deal with items that have already been unlinked. Normally this doesn't happen as most people don't try to use multiple station interfaces that associate at the same time too. Fix this by using the list entry as a flag to see if the item is still on a list. Cc: stable@kernel.org Reported-by: Ben Greear Tested-by: Hun-Kyi Wynn Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/scan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 5ca8c7180141..503ebb86ba18 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) bss = container_of(pub, struct cfg80211_internal_bss, pub); spin_lock_bh(&dev->bss_lock); + if (!list_empty(&bss->list)) { + list_del_init(&bss->list); + dev->bss_generation++; + rb_erase(&bss->rbn, &dev->bss_tree); - list_del(&bss->list); - dev->bss_generation++; - rb_erase(&bss->rbn, &dev->bss_tree); - + kref_put(&bss->ref, bss_release); + } spin_unlock_bh(&dev->bss_lock); - - kref_put(&bss->ref, bss_release); } EXPORT_SYMBOL(cfg80211_unlink_bss); -- cgit v1.2.3 From 494486f8fd0eec956c5df823581df5dcf5409a6f Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 6 Oct 2010 16:40:40 -0400 Subject: mac80211: avoid uninitialized var warning in ieee80211_scan_cancel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/mac80211/scan.c: In function ‘ieee80211_scan_cancel’: net/mac80211/scan.c:794: warning: ‘finish’ may be used uninitialized in this function Signed-off-by: John W. Linville --- net/mac80211/scan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 80e017df5f31..523db930dabb 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -791,7 +791,8 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, */ void ieee80211_scan_cancel(struct ieee80211_local *local) { - bool abortscan, finish; + bool abortscan; + bool finish = false; /* * We are only canceling software scan, or deferred scan that was not @@ -818,7 +819,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) if (abortscan) { /* The scan is canceled, but stop work from being pending */ cancel_delayed_work_sync(&local->scan_work); - if (finish) - __ieee80211_scan_completed_finish(&local->hw, false); } + if (finish) + __ieee80211_scan_completed_finish(&local->hw, false); } -- cgit v1.2.3 From 85407885d5d8e9eed9be8e4d33c519646b90d09f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 6 Oct 2010 13:40:58 -0700 Subject: [PATCH net-next] tg3: Set real_num_rx_queues for non-multiq devs Commit 2ddaad397c47de012dfb956b0c05540da1a0dde5 entitled "tg3: Use netif_set_real_num_{rx,tx}_queues()" added a new call to netif_set_real_num_rx_queues in tg3_enable_msix(). This call also needs to be added to the legacy path to correctly reflect the actual number of rx queues. Signed-off-by: Matt Carlson Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tg3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 16e1a95c65f4..e5b9ec5797c1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8906,6 +8906,7 @@ defcfg: tp->irq_cnt = 1; tp->napi[0].irq_vec = tp->pdev->irq; netif_set_real_num_tx_queues(tp->dev, 1); + netif_set_real_num_rx_queues(tp->dev, 1); } } -- cgit v1.2.3 From ceb7e1c7c5ab86ca686d523f99ca473a1f3a984d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 6 Oct 2010 03:14:54 +0000 Subject: cnic: Pass cp pointer to BNX2X_HW_CID. Preparation work for upcoming firmware interface changes. Signed-off-by: Michael Chan Signed-off-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/cnic.c | 13 +++++-------- drivers/net/cnic.h | 9 ++++++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 2ab6a7c4ffc1..0e31d5aa1dd2 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1209,7 +1209,7 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid, kwqe.hdr.conn_and_cmd_data = cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) | - BNX2X_HW_CID(cid, cp->func))); + BNX2X_HW_CID(cp, cid))); kwqe.hdr.type = cpu_to_le16(type); kwqe.hdr.reserved = 0; kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo); @@ -1461,7 +1461,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], struct cnic_context *ctx = &cp->ctx_tbl[req1->iscsi_conn_id]; struct cnic_iscsi *iscsi = ctx->proto.iscsi; u32 cid = ctx->cid; - u32 hw_cid = BNX2X_HW_CID(cid, cp->func); + u32 hw_cid = BNX2X_HW_CID(cp, cid); struct iscsi_context *ictx; struct regpair context_addr; int i, j, n = 2, n_max; @@ -1673,8 +1673,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], } kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS; - kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp->ctx_tbl[l5_cid].cid, - cp->func); + kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp, cp->ctx_tbl[l5_cid].cid); done: cqes[0] = (struct kcqe *) &kcqe; @@ -3885,7 +3884,6 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) struct eth_context *context; struct regpair context_addr; dma_addr_t buf_map; - int func = CNIC_FUNC(cp); int port = CNIC_PORT(cp); int i; int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); @@ -3931,7 +3929,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE; context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), + CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), CDU_REGION_NUMBER_XCM_AG, ETH_CONNECTION_TYPE); @@ -3959,7 +3957,6 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) struct regpair context_addr; int i; int port = CNIC_PORT(cp); - int func = CNIC_FUNC(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); u32 val; struct tstorm_eth_client_config tstorm_client = {0}; @@ -3998,7 +3995,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) cp->l2_single_buf_size; context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), + CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), CDU_REGION_NUMBER_UCM_AG, ETH_CONNECTION_TYPE); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 275c36114d85..6c099811eee7 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -335,9 +335,7 @@ struct bnx2x_bd_chain_next { #define BNX2X_ISCSI_GLB_BUF_SIZE 64 #define BNX2X_ISCSI_PBL_NOT_CACHED 0xff #define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff -#define BNX2X_HW_CID(x, func) ((x) | (((func) % PORT_MAX) << 23) | \ - (((func) >> 1) << 17)) -#define BNX2X_SW_CID(x) (x & 0x1ffff) + #define BNX2X_CHIP_NUM_57711 0x164f #define BNX2X_CHIP_NUM_57711E 0x1650 #define BNX2X_CHIP_NUM(x) (x >> 16) @@ -372,5 +370,10 @@ struct bnx2x_bd_chain_next { #define CNIC_FUNC(cp) ((cp)->func) #define CNIC_E1HVN(cp) ((cp)->func >> 1) +#define BNX2X_HW_CID(cp, x) (((CNIC_FUNC(cp) % PORT_MAX) << 23) | \ + (CNIC_E1HVN(cp) << 17) | (x)) + +#define BNX2X_SW_CID(x) (x & 0x1ffff) + #endif -- cgit v1.2.3 From 1420398db4d5e236583d3ab392637df255bd5c6b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 6 Oct 2010 03:16:06 +0000 Subject: cnic: Use pfid for internal memory offsets. The pfid (physical function ID) is the same as PCI function on production devices. The pfid for future devices will be different and will be used for internal memory offsets. Signed-off-by: Michael Chan Signed-off-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/cnic.c | 144 +++++++++++++++++++++++++++-------------------------- drivers/net/cnic.h | 1 + 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 0e31d5aa1dd2..50cded7fff51 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1246,8 +1246,8 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) { struct cnic_local *cp = dev->cnic_priv; struct iscsi_kwqe_init1 *req1 = (struct iscsi_kwqe_init1 *) kwqe; - int func = cp->func, pages; - int hq_bds; + int hq_bds, pages; + u32 pfid = cp->pfid; cp->num_iscsi_tasks = req1->num_tasks_per_conn; cp->num_ccells = req1->num_ccells_per_conn; @@ -1264,60 +1264,60 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) return 0; /* init Tstorm RAM */ - CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(pfid), req1->rq_num_wqes); - CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); /* init Ustorm RAM */ CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(func), + USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfid), req1->rq_buffer_size); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(pfid), req1->rq_num_wqes); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(pfid), req1->cq_num_wqes); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid), cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS); /* init Xstorm RAM */ - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(pfid), hq_bds); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid), cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS); /* init Cstorm RAM */ - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(pfid), req1->cq_num_wqes); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(pfid), hq_bds); return 0; @@ -1327,7 +1327,7 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe) { struct iscsi_kwqe_init2 *req2 = (struct iscsi_kwqe_init2 *) kwqe; struct cnic_local *cp = dev->cnic_priv; - int func = cp->func; + u32 pfid = cp->pfid; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; @@ -1339,21 +1339,21 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe) } CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]); + TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]); CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4, + TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4, req2->error_bit_map[1]); CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn); + USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]); + USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4, + USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4, req2->error_bit_map[1]); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn); + CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn); kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS; @@ -1804,37 +1804,37 @@ static void cnic_init_storm_conn_bufs(struct cnic_dev *dev, static void cnic_init_bnx2x_mac(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int func = CNIC_FUNC(cp); + u32 pfid = cp->pfid; u8 *mac = dev->mac_addr; CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(func), mac[0]); + XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfid), mac[0]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(func), mac[1]); + XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfid), mac[1]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(func), mac[2]); + XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfid), mac[2]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(func), mac[3]); + XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfid), mac[3]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(func), mac[4]); + XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfid), mac[4]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(func), mac[5]); + XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfid), mac[5]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func), mac[5]); + TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[5]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func) + 1, + TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[4]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func), mac[3]); + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[3]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 1, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[2]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 2, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 2, mac[1]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 3, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 3, mac[0]); } @@ -1850,10 +1850,10 @@ static void cnic_bnx2x_set_tcp_timestamp(struct cnic_dev *dev, int tcp_ts) } CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), xstorm_flags); + XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), xstorm_flags); CNIC_WR16(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), tstorm_flags); + TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), tstorm_flags); } static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], @@ -1928,7 +1928,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], cnic_init_storm_conn_bufs(dev, kwqe1, kwqe3, conn_buf); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->func), csk->vlan_id); + XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->pfid), csk->vlan_id); cnic_bnx2x_set_tcp_timestamp(dev, kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_TIME_STAMP); @@ -3283,30 +3283,30 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int func = CNIC_FUNC(cp); + u32 pfid = cp->pfid; cnic_init_bnx2x_mac(dev); cnic_bnx2x_set_tcp_timestamp(dev, 1); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_VLAN_OFFSET(func), 0); + XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(func), 1); + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(pfid), 1); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(func), + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(pfid), DEF_MAX_DA_COUNT); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(func), DEF_TTL); + XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfid), DEF_TTL); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(func), DEF_TOS); + XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfid), DEF_TOS); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(func), 2); + XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfid), 2); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(func), DEF_SWS_TIMER); + XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfid), DEF_SWS_TIMER); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(func), + CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(pfid), DEF_MAX_CWND); return 0; } @@ -4123,9 +4123,13 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int func = CNIC_FUNC(cp), ret, i; int port = CNIC_PORT(cp); + u32 pfid; u16 eq_idx; u8 sb_id = cp->status_blk_num; + cp->pfid = func; + pfid = cp->pfid; + ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ, cp->iscsi_start_cid); @@ -4133,7 +4137,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) return -ENOMEM; cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_PROD_OFFSET(func, 0); + CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; cp->kcq1.hw_prod_idx_ptr = @@ -4147,41 +4151,41 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) /* Only 1 EQ */ CNIC_WR16(dev, cp->kcq1.io_addr, MAX_KCQ_IDX); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_CONS_OFFSET(func, 0), 0); + CSTORM_ISCSI_EQ_CONS_OFFSET(pfid, 0), 0); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0), + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0), cp->kcq1.dma.pg_map_arr[1] & 0xffffffff); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0) + 4, + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0) + 4, (u64) cp->kcq1.dma.pg_map_arr[1] >> 32); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0), + CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0), cp->kcq1.dma.pg_map_arr[0] & 0xffffffff); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0) + 4, + CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0) + 4, (u64) cp->kcq1.dma.pg_map_arr[0] >> 32); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, 0), 1); + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfid, 0), 1); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_SB_NUM_OFFSET(func, 0), cp->status_blk_num); + CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfid, 0), cp->status_blk_num); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(func, 0), + CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0), HC_INDEX_C_ISCSI_EQ_CONS); for (i = 0; i < cp->conn_buf_info.num_pages; i++) { CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i), + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i), cp->conn_buf_info.pgtbl[2 * i]); CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i) + 4, + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i) + 4, cp->conn_buf_info.pgtbl[(2 * i) + 1]); } CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func), + USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid), cp->gbl_buf_info.pg_map_arr[0] & 0xffffffff); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func) + 4, + USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid) + 4, (u64) cp->gbl_buf_info.pg_map_arr[0] >> 32); cnic_setup_bnx2x_context(dev); @@ -4386,7 +4390,7 @@ static void cnic_stop_bnx2x_hw(struct cnic_dev *dev) index_values[HC_INDEX_C_ISCSI_EQ_CONS]), 0); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_CONS_OFFSET(cp->func, 0), 0); + CSTORM_ISCSI_EQ_CONS_OFFSET(cp->pfid, 0), 0); CNIC_WR16(dev, cp->kcq1.io_addr, 0); cnic_free_resc(dev); } diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 6c099811eee7..ef2c25e4962d 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -272,6 +272,7 @@ struct cnic_local { u32 chip_id; int func; + u32 pfid; u32 shmem_base; u32 uio_dev; -- cgit v1.2.3 From 541a78103f097cd5120e55aaba56d099a64f153c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 6 Oct 2010 03:17:22 +0000 Subject: cnic: Fine-tune ring init code. Initialize the rings only during cnic_uio_open() and shut them down during cnic_uio_close(). Check for the new bit CNIC_LCL_FL_RINGS_INITED before checking for ring interrupt. Signed-off-by: Michael Chan Signed-off-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/cnic.c | 24 ++++++++++++++++++------ drivers/net/cnic.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 50cded7fff51..4e9d4ae1f303 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2202,13 +2202,14 @@ static int cnic_l2_completion(struct cnic_local *cp) static void cnic_chk_pkt_rings(struct cnic_local *cp) { - u16 rx_cons = *cp->rx_cons_ptr; - u16 tx_cons = *cp->tx_cons_ptr; + u16 rx_cons, tx_cons; int comp = 0; - if (!test_bit(CNIC_F_CNIC_UP, &cp->dev->flags)) + if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) return; + rx_cons = *cp->rx_cons_ptr; + tx_cons = *cp->tx_cons_ptr; if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) { if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) comp = cnic_l2_completion(cp); @@ -4202,17 +4203,20 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return ret; - cnic_init_bnx2x_tx_ring(dev); - cnic_init_bnx2x_rx_ring(dev); - return 0; } static void cnic_init_rings(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + + if (test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) + return; + if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { cnic_init_bnx2_tx_ring(dev); cnic_init_bnx2_rx_ring(dev); + set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { struct cnic_local *cp = dev->cnic_priv; u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); @@ -4235,6 +4239,8 @@ static void cnic_init_rings(struct cnic_dev *dev) cnic_init_bnx2x_tx_ring(dev); cnic_init_bnx2x_rx_ring(dev); + set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); + l5_data.phy_address.lo = cli; l5_data.phy_address.hi = 0; cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, @@ -4254,6 +4260,11 @@ static void cnic_init_rings(struct cnic_dev *dev) static void cnic_shutdown_rings(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + + if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) + return; + if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { cnic_shutdown_bnx2_rx_ring(dev); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { @@ -4286,6 +4297,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) (1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data); msleep(10); } + clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } static int cnic_register_netdev(struct cnic_dev *dev) diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index ef2c25e4962d..481618399b1f 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -192,6 +192,7 @@ struct cnic_local { unsigned long cnic_local_flags; #define CNIC_LCL_FL_KWQ_INIT 0x0 #define CNIC_LCL_FL_L2_WAIT 0x1 +#define CNIC_LCL_FL_RINGS_INITED 0x2 struct cnic_dev *dev; -- cgit v1.2.3 From 560131f313ea9b9439742138289b6f68d61531ec Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:18:47 +0000 Subject: bnx2x: create folder for bnx2x firmware files Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 4 +- firmware/Makefile | 3 +- firmware/WHENCE | 4 +- firmware/bnx2x-e1-5.2.13.0.fw.ihex | 10191 ---------------------- firmware/bnx2x-e1h-5.2.13.0.fw.ihex | 12849 ---------------------------- firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex | 10191 ++++++++++++++++++++++ firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex | 12849 ++++++++++++++++++++++++++++ 7 files changed, 23046 insertions(+), 23045 deletions(-) delete mode 100644 firmware/bnx2x-e1-5.2.13.0.fw.ihex delete mode 100644 firmware/bnx2x-e1h-5.2.13.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 67587fe9e358..3696a4b6547b 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -66,8 +66,8 @@ __stringify(BCM_5710_FW_MINOR_VERSION) "." \ __stringify(BCM_5710_FW_REVISION_VERSION) "." \ __stringify(BCM_5710_FW_ENGINEERING_VERSION) -#define FW_FILE_NAME_E1 "bnx2x-e1-" FW_FILE_VERSION ".fw" -#define FW_FILE_NAME_E1H "bnx2x-e1h-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) diff --git a/firmware/Makefile b/firmware/Makefile index 9c2d19452d0b..44b3aae66b84 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,7 +32,8 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.2.13.0.fw bnx2x-e1h-5.2.13.0.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-5.2.13.0.fw \ + bnx2x/bnx2x-e1h-5.2.13.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index ae5f8a47f292..1d3936c2e2f7 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -679,8 +679,8 @@ Found in hex form in kernel source. Driver: bnx2x: Broadcom Everest -File: bnx2x-e1-5.2.13.0.fw -File: bnx2x-e1h-5.2.13.0.fw +File: bnx2x/bnx2x-e1-5.2.13.0.fw +File: bnx2x/bnx2x-e1h-5.2.13.0.fw License: Copyright (c) 2007-2010 Broadcom Corporation diff --git a/firmware/bnx2x-e1-5.2.13.0.fw.ihex b/firmware/bnx2x-e1-5.2.13.0.fw.ihex deleted file mode 100644 index 651f4346d89e..000000000000 --- a/firmware/bnx2x-e1-5.2.13.0.fw.ihex +++ /dev/null @@ -1,10191 +0,0 @@ -:10000000000028B0000000600000068800002918E9 -:100010000000161400002FA800000098000045C042 -:10002000000073C400004660000000CC0000BA2845 -:1000300000009A700000BAF80000009400015570AA -:10004000000057BC00015608000000B80001ADC810 -:100050000000CE200001AE880000000400027CB049 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000060400CC0000000418 -:10010000020400DC00100000020400E012140000F1 -:10011000020400E422140000020400E8321400008B -:10012000060400EC000000040104012400000000AB -:1001300001040128000000000104012C000000005F -:10014000010401300000000002040004000000FF70 -:1001500002040008000000FF0204000C000000FF81 -:1001600002040010000000FF02040014000000FF61 -:1001700002040018000000FF0204001C000000FF41 -:1001800002040020000000FF020400240000003EE2 -:1001900002040028000000000204002C0000003FC0 -:1001A000020400300000003F020400340000003F61 -:1001B00002040038000000000204003C0000003F80 -:1001C000020400400000003F020400440000003F21 -:1001D00002042008000004110204200C00000400A6 -:1001E000020420100000040402042014000004197A -:1001F0000204201C0000FFFF020420200000FFFF7B -:10020000020420240000FFFF020420280000FFFF5A -:1002100006042038000000020204204000000034E0 -:100220000204204400000035060420480000007C41 -:100230000204223807FFFFFF0204223C0000003FB7 -:100240000204224007FFFFFF020422440000000FC7 -:1002500001042248000000000104224C00000000BC -:10026000010422500000000001042254000000009C -:1002700001042258000000000104225C000000007C -:10028000010422600000000001042264000000005C -:1002900001042268000000000104226C000000003C -:1002A000010422700000000001042274000000001C -:1002B00001042278000000000104227C00000000FC -:1002C000020424BC000000010C042000000003E82C -:1002D0000A042000000000010B0420000000000AB6 -:1002E0000205004400000020020500480000003222 -:1002F000020500900215002002050094021500205E -:1003000002050098000000300205009C0810000063 -:10031000020500A000000033020500A40000003028 -:10032000020500A800000031020500AC0000000238 -:10033000020500B000000005020500B40000000640 -:10034000020500B800000002020500BC0000000227 -:10035000020500C000000000020500C40000000506 -:10036000020500C800000002020500CC00000002E7 -:10037000020500D000000002020500D400000001C8 -:1003800002050114000000010205011C000000012B -:100390000205012000000002020502040000000125 -:1003A0000205020C0000004002050210000000409F -:1003B0000205021C000000200205022000000013BC -:1003C0000205022400000020060502400000000A89 -:1003D0000405028000200000020500500000000714 -:1003E0000205005400000007020500580000000844 -:1003F0000205005C00000008060500600000000423 -:10040000020500D800000006020500E00000000D13 -:10041000020500E40000002D020500E800000007CE -:10042000020500EC00000027020500F000000007B4 -:10043000020500F400000027020500F80000000794 -:10044000020500FC00000027020500040000000176 -:1004500002050008000000010205000C0000000178 -:100460000205001000000001020500140000000158 -:1004700002050018000000010205001C0000000138 -:100480000205002000000001020500240000000118 -:1004900002050028000000010205002C00000001F8 -:1004A00002050030000000010205003400000001D8 -:1004B00002050038000000010205003C00000001B8 -:1004C00002050040000000010406100002000020A8 -:1004D000020600DC00000001010600D80000000058 -:1004E0000406020000030220020600DC00000000F7 -:1004F00002060068000000B802060078000001143F -:10050000010600B800000000010600C8000000005D -:100510000206006C000000B80206007C0000011416 -:10052000010600BC00000000010600CC0000000035 -:100530000718040000950000081807600014022343 -:10054000071C000034D40000071C800034CF0D3697 -:10055000071D00000A191A6A081D14605D7402253F -:100560000118000000000000011800040000000055 -:1005700001180008000000000118000C0000000035 -:100580000118001000000000011800140000000015 -:1005900002180020000000010218002400000002E0 -:1005A00002180028000000030218002C00000000C0 -:1005B000021800300000000402180034000000019E -:1005C00002180038000000000218003C0000000182 -:1005D000021800400000000402180044000000005F -:1005E00002180048000000010218004C000000033F -:1005F0000218005000000000021800540000000122 -:1006000002180058000000040218005C00000000FE -:1006100002180060000000010218006400000003DE -:1006200002180068000000000218006C00000001C1 -:10063000021800700000000402180074000000009E -:1006400002180078000000040218007C000000037B -:100650000618008000000002021800A400003FFFFE -:10066000021800A8000003FF021802240000000086 -:1006700002180234000000000218024C00000000C2 -:10068000021802E4000000FF061810000000040039 -:10069000021B8BC000000001021B80000000003420 -:1006A000021B804000000018021B80800000000C2C -:1006B000021B80C0000000200C1B83000007A1204B -:1006C0000A1B8300000001380B1B83000000138805 -:1006D000021B83C0000001F4061A2000000000B2D3 -:1006E000061A23C800000181041A29CC0001022740 -:1006F000061A1020000000C8061A100000000002B0 -:10070000061A1E3800000002061A1E300000000201 -:10071000061A080000000002061A0808000000027D -:10072000061A081000000004041A1FB00005022871 -:10073000041A4CB00008022D061A22C8000000203E -:10074000061A400000000124021A4920000000009F -:10075000061A14000000000A061A145000000006D1 -:10076000061A150000000002041A150800050235DB -:10077000061A151C00000009061A15800000001456 -:10078000061A09C000000048061A0800000000020E -:10079000061A08200000000E041A1FB00002023AD8 -:1007A000061A2C2800000002061A23480000002028 -:1007B000061A449000000124021A49240000000097 -:1007C000061A14280000000A061A14680000000621 -:1007D000061A154000000002041A15480005023CE4 -:1007E000061A155C00000009061A15D00000001456 -:1007F000061A0AE000000048061A08080000000275 -:10080000061A08580000000E041A1FB80002024120 -:10081000061A2C30000000020200A2800000000135 -:100820000200A294071D29110200A29800000000F6 -:100830000200A29C009C04240200A2A00000000070 -:100840000200A2A4000002090200A4FCFF000000B4 -:10085000020100B400000001020100B80000000124 -:10086000020100DC000000010201010000000001A3 -:1008700002010104000000010201007C00300000C0 -:1008800002010084000000280201008C000000002A -:1008900002010130000000040201025C00000001BE -:1008A000020103280000000002010554000000308E -:1008B000020100C400000001020100CC00000001A0 -:1008C000020100F800000001020100F00000000138 -:1008D00002010080003000000201008800000028B2 -:1008E0000201009000000000020101340000000439 -:1008F000020102DC000000010201032C00000000E4 -:100900000201056400000030020100C8000000017F -:10091000020100D000000001020100FC0000000103 -:10092000020100F400000001020C10000000002091 -:10093000020C200800000A11020C200C00000A0022 -:10094000020C201000000A04020C201C0000FFFF13 -:10095000020C20200000FFFF020C20240000FFFFFB -:10096000020C20280000FFFF060C203800000002C7 -:10097000020C204000000034020C2044000000352E -:10098000020C204800000020020C204C0000002136 -:10099000020C205000000022020C20540000002312 -:1009A000020C205800000024020C205C00000025EE -:1009B000020C206000000026020C206400000027CA -:1009C000020C206800000028020C206C00000029A6 -:1009D000020C20700000002A020C20740000002B82 -:1009E000060C207800000056020C21D00000000107 -:1009F000020C21D400000001020C21D800000001EB -:100A0000020C21DC00000001020C21E000000001CA -:100A1000020C21E400000001020C21E800000001AA -:100A2000020C21EC00000001020C21F0000000018A -:100A3000020C21F400000001060C21F80000001057 -:100A4000020C223807FFFFFF020C223C0000003F8F -:100A5000020C224007FFFFFF020C22440000000F9F -:100A6000010C224800000000010C224C0000000094 -:100A7000010C225000000000010C22540000000074 -:100A8000010C225800000000010C225C0000000054 -:100A9000010C226000000000010C22640000000034 -:100AA000010C226800000000010C226C0000000014 -:100AB000010C227000000000010C227400000000F4 -:100AC000010C227800000000010C227C00000000D4 -:100AD000020C24BC000000010C0C2000000003E804 -:100AE0000A0C2000000000010B0C20000000000A8E -:100AF000020C400800000365020C400C0000035487 -:100B0000020C401000000358020C40140000037552 -:100B1000020C401C0000FFFF020C40200000FFFF01 -:100B2000020C40240000FFFF020C40280000FFFFE1 -:100B3000020C403800000046020C403C000000055A -:100B4000060C40400000005E020C41B800000001AD -:100B5000060C41BC0000001F020C423807FFFFFFDB -:100B6000020C423C0000003F020C424007FFFFFF26 -:100B7000020C42440000000F010C4248000000003B -:100B8000010C424C00000000010C4250000000002B -:100B9000010C425400000000010C4258000000000B -:100BA000010C425C00000000010C426000000000EB -:100BB000010C426400000000010C426800000000CB -:100BC000010C426C00000000010C427000000000AB -:100BD000010C427400000000010C4278000000008B -:100BE000010C427C00000000010C4280000000006B -:100BF000020C44C0000000010C0C4000000003E89F -:100C00000A0C4000000000010B0C40000000000A2C -:100C1000020D004400000032020D008C021500207D -:100C2000020D009002150020020D00940810000033 -:100C3000020D009800000033020D009C000000022D -:100C4000020D00A000000000020D00A4000000053D -:100C5000020D00A800000005060D00AC0000000217 -:100C6000020D00B400000002020D00B800000003F5 -:100C7000020D00BC00000002020D00C000000001D7 -:100C8000020D00C800000002020D00CC00000002AE -:100C9000020D010800000001020D015C00000001CE -:100CA000020D016400000001020D01680000000255 -:100CB000020D020400000001020D020C00000020E1 -:100CC000020D021000000040020D0214000000405E -:100CD000020D022000000003020D02240000001893 -:100CE000060D028000000012040D030000240243E0 -:100CF000020D004C00000001020D00500000000237 -:100D0000020D005400000008020D00580000000809 -:100D1000060D005C00000004020D00C40000000489 -:100D2000020D011400000009020D01180000002945 -:100D3000020D011C0000000A020D01200000002A23 -:100D4000020D012400000007020D01280000002709 -:100D5000020D012C00000007020D013000000027E9 -:100D6000020D01340000000C020D01380000002CBF -:100D7000020D013C0000000C020D01400000002C9F -:100D8000020D01440000000C020D01480000002C7F -:100D9000020D000400000001020D00080000000127 -:100DA000020D000C00000001020D00100000000107 -:100DB000020D001400000001020D001800000001E7 -:100DC000020D001C00000001020D002000000001C7 -:100DD000020D002400000001020D002800000001A7 -:100DE000020D002C00000001020D00300000000187 -:100DF000020D003400000001020D00380000000167 -:100E0000020D003C00000001020E004C0000003208 -:100E1000020E009402150020020E00980215002018 -:100E2000020E009C00000030020E00A0081000001E -:100E3000020E00A400000033020E00A800000030E3 -:100E4000020E00AC00000031020E00B000000002F3 -:100E5000020E00B400000004020E00B80000000002 -:100E6000020E00BC00000002020E00C000000002E2 -:100E7000020E00C400000000020E00C800000002C4 -:100E8000020E00CC00000007020E00D0000000029D -:100E9000020E00D400000002020E00D80000000183 -:100EA000020E00E400000001020E014400000001F7 -:100EB000020E014C00000001020E01500000000271 -:100EC000020E020400000001020E020C00000040AD -:100ED000020E021000000040020E021C000000047E -:100EE000020E022000000020020E02240000000E6C -:100EF000020E02280000001B060E03000000001274 -:100F0000040E0280001B0267020E00540000000C59 -:100F1000020E005800000009020E005C0000000FE5 -:100F2000020E006000000010060E006400000004C5 -:100F3000020E00DC00000003020E01100000000F92 -:100F4000020E01140000002F020E01180000000E16 -:100F5000020E011C0000002E020E00040000000121 -:100F6000020E000800000001020E000C000000014B -:100F7000020E001000000001020E0014000000012B -:100F8000020E001800000001020E001C000000010B -:100F9000020E002000000001020E002400000001EB -:100FA000020E002800000001020E002C00000001CB -:100FB000020E003000000001020E003400000001AB -:100FC000020E003800000001020E003C000000018B -:100FD000020E004000000001020E0044000000016B -:100FE0000730040000C900000830076800130282BF -:100FF00007340000334B00000734800037090CD35E -:101000000735000030161A96083572F051A2028496 -:10101000013000000000000001300004000000006A -:1010200001300008000000000130000C000000004A -:10103000013000100000000001300014000000002A -:1010400002300020000000010230002400000002F5 -:1010500002300028000000030230002C00000000D5 -:1010600002300030000000040230003400000001B3 -:1010700002300038000000000230003C0000000197 -:101080000230004000000004023000440000000074 -:1010900002300048000000010230004C0000000354 -:1010A0000230005000000000023000540000000137 -:1010B00002300058000000040230005C0000000014 -:1010C00002300060000000010230006400000003F4 -:1010D00002300068000000000230006C00000001D7 -:1010E00002300070000000040230007400000000B4 -:1010F00002300078000000040230007C0000000391 -:101100000630008000000002023000A400003FFF13 -:10111000023000A8000003FF02300224000000009B -:1011200002300234000000000230024C00000000D7 -:10113000023002E40000FFFF06302000000008003B -:1011400002338BC000000001023380000000001A4F -:10115000023380400000004E023380800000001007 -:10116000023380C0000000200C3383000007A12060 -:101170000A338300000001380B338300000013881A -:10118000023383C0000001F40C3383801DCD650061 -:101190000A3383800004C4B40B338380004C4B407B -:1011A00006321AA0000000C206321020000000C85B -:1011B0000632100000000002063214000000004059 -:1011C00006325098000000040632508000000005EE -:1011D00004325094000102860632500000000020C4 -:1011E00004322830000202870233080001000000A8 -:1011F00004330C00001002890233080000000000D4 -:1012000004330C400010029906321500000000B4AF -:1012100002321DC80000000006324000000000D865 -:10122000063217D0000000B402321DCC00000000CE -:1012300006324360000000D807200400009200003E -:1012400008200780001002A9072400002CD100000C -:10125000072480002AE50B350824DC6062DA02AB43 -:101260000120000000000000012000040000000038 -:1012700001200008000000000120000C0000000018 -:1012800001200010000000000120001400000000F8 -:1012900002200020000000010220002400000002C3 -:1012A00002200028000000030220002C00000000A3 -:1012B0000220003000000004022000340000000181 -:1012C00002200038000000000220003C0000000165 -:1012D0000220004000000004022000440000000042 -:1012E00002200048000000010220004C0000000322 -:1012F0000220005000000000022000540000000105 -:1013000002200058000000040220005C00000000E1 -:1013100002200060000000010220006400000003C1 -:1013200002200068000000000220006C00000001A4 -:101330000220007000000004022000740000000081 -:1013400002200078000000040220007C000000035E -:101350000620008000000002022000A400003FFFE1 -:10136000022000A8000003FF022002240000000069 -:1013700002200234000000000220024C00000000A5 -:10138000022002E40000FFFF062020000000080009 -:1013900002238BC000000001022380000000001027 -:1013A00002238040000000120223808000000030F1 -:1013B000022380C00000000E022383C0000001F45D -:1013C000062250000000004206221020000000C843 -:1013D000062210000000000206222000000000C0CB -:1013E000062225C00000024004222EC8000802ADDB -:1013F00002230800013FFFFF04230C00001002B588 -:10140000022308000000000004230C40001002C565 -:1014100006223040000000A00622354000000010E7 -:10142000062236C000000030062240000000020004 -:10143000062235C00000002006223840000000309F -:1014400006223000000000080222511800000000AF -:10145000062223000000000E0622241000000030A7 -:10146000062232C0000000A00622358000000010D5 -:1014700006223780000000300622480000000200EB -:10148000062236400000002006223900000000300D -:1014900006223020000000080222511C000000003B -:1014A000062223380000000E062224D0000000305F -:1014B00002161000000000280217000800000002B9 -:1014C0000217002C000000030217003C000000047B -:1014D0000217004400000008021700480000000244 -:1014E0000217004C0000009002170050000000900E -:1014F00002170054008000900217005808140000E2 -:10150000021700600000008A0217006400000080DB -:1015100002170068000000810217006C00000080C4 -:10152000021700700000000602170078000007D0C4 -:101530000217007C0000076C02170038007C1004C2 -:10154000021700040000000F0616402400000002ED -:10155000021640700000001C021642080000000144 -:101560000216421000000001021642200000000195 -:10157000021642280000000102164230000000015D -:10158000021642380000000102164260000000010D -:101590000C16401C0003D0900A16401C0000009C52 -:1015A0000B16401C000009C4021640300000000861 -:1015B000021640340000000C0216403800000010F3 -:1015C0000216404400000020021640000000000106 -:1015D000021640D800000001021640080000000179 -:1015E0000216400C0000000102164010000000012D -:1015F00002164240000000000216424800000000AF -:101600000616427000000002021642500000000060 -:101610000216425800000000061642800000000238 -:1016200002166008000006140216600C0000060096 -:1016300002166010000006040216601C0000FFFF86 -:10164000021660200000FFFF021660240000FFFF6A -:10165000021660280000FFFF02166038000000201C -:101660000216603C000000200216604000000034BA -:101670000216604400000035021660480000002396 -:101680000216604C00000024021660500000002585 -:101690000216605400000026021660580000002761 -:1016A0000216605C00000029021660600000002A3B -:1016B000021660640000002B021660680000002C17 -:1016C0000216606C0000002D0616607000000052CB -:1016D000021661B800000001061661BC0000001F80 -:1016E0000216623807FFFFFF0216623C0000003F4F -:1016F0000216624007FFFFFF021662440000000F5F -:1017000001166248000000000116624C0000000053 -:101710000116625000000000011662540000000033 -:1017200001166258000000000116625C0000000013 -:1017300001166260000000000116626400000000F3 -:1017400001166268000000000116626C00000000D3 -:1017500001166270000000000116627400000000B3 -:1017600001166278000000000116627C0000000093 -:10177000021664BC000000010C166000000003E8C3 -:101780000A166000000000010B1660000000000A4D -:10179000021680400000000602168044000000058A -:1017A000021680480000000A0216804C0000000566 -:1017B0000216805400000002021680CC00000004D3 -:1017C000021680D000000004021680D4000000043D -:1017D000021680D800000004021680DC000000041D -:1017E000021680E000000004021680E400000004FD -:1017F000021680E8000000040216880400000004BD -:10180000021680300000007C021680340000003D8B -:10181000021680380000003F0216803C0000009C49 -:10182000021680F000000007061680F40000000594 -:101830000216880C01010101021681080000000057 -:101840000216810C00000004021681100000000442 -:1018500002168114000000020216881008012004FC -:1018600002168118000000050216811C0000000508 -:1018700002168120000000050216812400000005E8 -:101880000216882C2008100102168128000000088A -:101890000216812C000000060216813000000007AD -:1018A0000216813400000000021688300101012078 -:1018B0000616813800000004021688340101010177 -:1018C0000616814800000004021688380101010153 -:1018D00006168158000000040216883C010101012F -:1018E00006168168000000030216817400000001E2 -:1018F00002168840010101010216817800000001F2 -:101900000216817C000000010216818000000001A7 -:1019100002168184000000010216884401010101C1 -:1019200002168188000000010216818C000000046C -:10193000021681900000000402168194000000024B -:10194000021688480801200402168198000000054C -:101950000216819C00000005021681A0000000050F -:10196000021681A400000005021688142008100148 -:10197000021681A800000008021681AC00000006D3 -:10198000021681B000000007021681B400000001B9 -:101990000216881801010120021681B8000000011A -:1019A000021681BC00000001021681C00000000187 -:1019B000021681C4000000010216881C0101010109 -:1019C000021681C800000001021681CC000000014F -:1019D000021681D000000001021681D4000000012F -:1019E0000216882001010101021681D800000001C1 -:1019F000021681DC00000001021681E000000001F7 -:101A0000021681E400000001021688240101010190 -:101A1000021681E800000001021681EC00000001BE -:101A2000021681F000000001021688280101010160 -:101A300002168240FFFF003F0616824400000002AB -:101A40000216824CFFFF003F021682500000010088 -:101A5000021682540000010006168258000000029F -:101A600002168260000000C002168264000000C0FE -:101A70000216826800001E000216826C00001E0022 -:101A800002168270000040000216827400004000BE -:101A900002168278000080000216827C000080001E -:101AA00002168280000020000216828400002000BE -:101AB0000616828800000007021682A400000001BA -:101AC000061682A80000000A021681F400000C0825 -:101AD000021681F800000040021681FC000001009F -:101AE0000216820000000020021682040000001787 -:101AF00002168208000000800216820C000002001C -:101B0000021682100000000002168218FFFF01FF7B -:101B100002168214FFFF01FF0216823C0000001330 -:101B2000021680900000013F021680600000014014 -:101B30000216806400000140061680680000000262 -:101B400002168070000000C00616807400000007B6 -:101B50000216809C00000048021680A00000004889 -:101B6000061680A400000002021680AC00000048A7 -:101B7000061680B0000000070216823800008000C0 -:101B800002168234000025E40216809400007FFFD4 -:101B900002168220000000070216821C00000007C7 -:101BA000021682280000000002168224FFFFFFFFB9 -:101BB00002168230000000000216822CFFFFFFFF99 -:101BC000021680EC000000FF02140000000000017B -:101BD0000214000C0000000102140040000000018B -:101BE0000214004400007FFF0214000C00000000FB -:101BF00002140000000000000214006C000000004D -:101C00000214000400000001021400300000000172 -:101C100002140004000000000214005C0000000038 -:101C2000021400080000000102140034000000014A -:101C30000214000800000000021400600000000010 -:101C40000202005800000032020200A0031500202A -:101C5000020200A403150020020200A801000030C7 -:101C6000020200AC08100000020200B000000033C5 -:101C7000020200B400000030020200B8000000318F -:101C8000020200BC00000003020200C000000006C7 -:101C9000020200C400000003020200C800000003AA -:101CA000020200CC00000002020200D0000000008E -:101CB000020200D400000002020200DC000000006A -:101CC000020200E000000006020200E4000000043E -:101CD000020200E800000002020200EC0000000224 -:101CE000020200F000000001020200FC00000006F9 -:101CF0000202012000000000020201340000000284 -:101D0000020201B0000000010202020C000000010A -:101D10000202021400000001020202180000000288 -:101D200002020404000000010202040C0000004052 -:101D300002020410000000400202041C0000000423 -:101D4000020204200000002002020424000000021D -:101D5000020204280000001F060205000000001215 -:101D600004020480001F02D5020200600000000F80 -:101D70000202006400000007020200680000000B7D -:101D80000202006C0000000E060200700000000459 -:101D9000020200F40000000402020004000000013E -:101DA00002020008000000010202000C0000000115 -:101DB00002020010000000010202001400000001F5 -:101DC00002020018000000010202001C00000001D5 -:101DD00002020020000000010202002400000001B5 -:101DE00002020028000000010202002C0000000195 -:101DF0000202003000000001020200340000000175 -:101E000002020038000000010202003C0000000154 -:101E10000202004000000001020200440000000134 -:101E200002020048000000010202004C0000000114 -:101E3000020200500000000102020108000000C878 -:101E40000202011800000002020201C400000000AA -:101E5000020201CC00000000020201D400000002D6 -:101E6000020201DC00000002020201E4000000FFA7 -:101E7000020201EC000000FF0202010C000000C899 -:101E80000202011C00000002020201C80000000062 -:101E9000020201D000000000020201D8000000028E -:101EA000020201E000000002020201E8000000FF5F -:101EB000020201F0000000FF0728040000B5000046 -:101EC00008280768001302F4072C000035D500002D -:101ED000072C80003A3E0D76072D00003B471C067C -:101EE000072D800022BC2AD8082DC770471202F6A1 -:101EF000012800000000000001280004000000008C -:101F000001280008000000000128000C000000006B -:101F1000012800100000000001280014000000004B -:101F20000228002000000001022800240000000216 -:101F300002280028000000030228002C00000000F6 -:101F400002280030000000040228003400000001D4 -:101F500002280038000000000228003C00000001B8 -:101F60000228004000000004022800440000000095 -:101F700002280048000000010228004C0000000375 -:101F80000228005000000000022800540000000158 -:101F900002280058000000040228005C0000000035 -:101FA0000228006000000001022800640000000315 -:101FB00002280068000000000228006C00000001F8 -:101FC00002280070000000040228007400000000D5 -:101FD00002280078000000040228007C00000003B2 -:101FE0000628008000000002022800A400003FFF35 -:101FF000022800A8000003FF0228022400000000BD -:1020000002280234000000000228024C00000000F8 -:10201000022802E40000FFFF06282000000008005C -:10202000022B8BC000000001022B8000000000008A -:10203000022B804000000018022B80800000000C62 -:10204000022B80C0000000660C2B83000007A1203B -:102050000A2B8300000001380B2B8300000013883B -:10206000022B83C0000001F40C2B8340000001F41C -:102070000A2B8340000000000B2B8340000000056A -:102080000A2B83800004C4B40C2B83801DCD650013 -:102090000B2B8380004C4B40062A3C400000000480 -:1020A000042A3C50000202F8062A300000000048D2 -:1020B000062A1020000000C8062A100000000002B6 -:1020C000062A31280000008E022A33680000000032 -:1020D000042A3370000202FA042A3A70000402FC57 -:1020E000042A3D0000020300042A15000002030236 -:1020F000062A150800000100022A197000000000DD -:10210000022A197800000000042A19600002030462 -:10211000062A4AC000000002062A4B000000000404 -:10212000042A1F4800020306022B080000000000DA -:10213000042B0C0000100308022B08000100000013 -:10214000042B0C4000080318022B080002000000BA -:10215000042B0C6000080320062A3A8000000014BB -:10216000062A3B2000000024062A14000000000A72 -:10217000062A145000000006062A3378000000D812 -:10218000022A3A3800000000042A3C5800020328C2 -:10219000042A3C680010032A062A5020000000028E -:1021A000062A503000000002062A500000000002FB -:1021B000062A501000000002022A504000000000D1 -:1021C000062A50480000000E022A50B80000000104 -:1021D000042A4AC80002033A062A4B1000000042B3 -:1021E000062A4D2000000004062A3AD00000001400 -:1021F000062A3BB000000024062A14280000000A2A -:10220000062A146800000006062A36D8000000D806 -:10221000022A3A3C00000000042A3C600002033C11 -:10222000042A3CA80010033E062A502800000002A1 -:10223000062A503800000002062A5008000000025A -:10224000062A501800000002022A50440000000034 -:10225000062A50800000000E022A50BC0000000137 -:10226000042A4AD00002034E062A4C1800000042FD -:10227000062A4D3000000004021010080000000182 -:102280000210101000000264021010000003D000C1 -:10229000021010040000003D091018000200035055 -:1022A00009101100002005500610118000000002E6 -:1022B0000910118800060570061011A00000001812 -:1022C000021010100000000006102400000000E0C2 -:1022D0000210201C0000000002102020000000015D -:1022E000021020C0000000010210200400000001C4 -:1022F000021020080000000109103C0000050576CE -:1023000009103C200005057B0910380000050580F8 -:1023100002104028000000100210404400003FFF5F -:102320000210405800280000021040840084924AA5 -:1023300002104058000000000610806800000004F1 -:1023400002108000000010800610802800000002AB -:102350000210803800000010021080400000FFFFD3 -:10236000021080440000FFFF0210805000000000B7 -:102370000210810000000000061081200000000211 -:1023800002108008000002B502108010000000005A -:10239000061082000000004A021081080001FFFFC1 -:1023A00006108140000000020210800000001A8028 -:1023B0000610900000000024061091200000004A42 -:1023C000061093700000004A061095C00000004AF5 -:1023D000021080040000108006108030000000020F -:1023E0000210803C00000010021080480000FFFF37 -:1023F0000210804C0000FFFF02108054000000001B -:102400000210810400000000061081280000000274 -:102410000210800C000002B50210801400000000C1 -:10242000061084000000004A0210810C0001FFFF2A -:1024300006108148000000020210800400001A808B -:102440000610909000000024061092480000004AF8 -:10245000061094980000004A061096E80000004A12 -:102460000212049000E383400212051400003C10A5 -:10247000021205200000000202120494FFFFFFFF79 -:1024800002120498FFFFFFFF0212049CFFFFFFFFF0 -:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0 -:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0 -:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C -:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68 -:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48 -:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28 -:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8 -:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7 -:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7 -:10252000021204F4FFFFFFFF021204F8FFFFFFFF97 -:10253000021204FCFFFFFFFF02120500FFFFFFFF76 -:1025400002120504FFFFFFFF02120508FFFFFFFF55 -:102550000212050CFFFFFFFF02120510FFFFFFFF35 -:10256000021204D4FFFF3330021204D8FFFF3340BD -:10257000021204B4F00030000212039000000008C0 -:102580000212039C00000008061203A000000002D3 -:10259000021203BC00000004021203C40000000485 -:1025A000021203D000000000021203DC0000000051 -:1025B0000212036C00000001021203680000003FD9 -:1025C000021201BC00000040021201C00000180805 -:1025D000021201C400000803021201C8000008032F -:1025E000021201CC00000040021201D000000003E2 -:1025F000021201D400000803021201D800000803EF -:10260000021201DC00000803021201E000010003D5 -:10261000021201E400000803021201E800000803AE -:10262000021201EC00000003021201F0000000039E -:10263000021201F400000003021201F8000000037E -:10264000021201FC0000000302120200000000035D -:10265000021202040000000302120208000000033C -:102660000212020C0000000302120210000000031C -:1026700002120214000000030212021800000003FC -:102680000212021C000000030212022000000003DC -:102690000212022400000003021202280000240398 -:1026A0000212022C0000002F02120230000000096A -:1026B00002120234000000190212023800000184E4 -:1026C0000212023C000001830212024000000306D5 -:1026D0000212024400000019021202480000000623 -:1026E0000212024C00000306021202500000030610 -:1026F00002120254000003060212025800000C8667 -:102700000212025C000003060212026000000306CF -:1027100002120264000000060212026800000006B5 -:102720000212026C00000006021202700000000695 -:102730000212027400000006021202780000000675 -:102740000212027C00000006021202800000000655 -:102750000212028400000006021202880000000635 -:102760000212028C00000006021202900000000615 -:1027700002120294000000060212029800000006F5 -:102780000212029C00000006021202A000000306D2 -:10279000021202A400000013021202A800000006A8 -:1027A000021202B000001004021202B40000100471 -:1027B0000212032400106440021203280010644037 -:1027C000021201B0000000010600A0000000001687 -:1027D0000200A06CBF5C00000200A070FFF51FEFBC -:1027E0000200A0740000FFFF0200A078500003E088 -:1027F0000200A07C000000000200A0800000A000F9 -:102800000600A084000000050200A0980FE0000070 -:102810000600A09C000000140200A0EC555400002B -:102820000200A0F0555555550200A0F40000555582 -:102830000200A0F8000000000200A0FC55540000B7 -:102840000200A100555555550200A1040000555540 -:102850000200A108000000000200A22C00000000FD -:102860000600A230000000030200A0600000000784 -:102870000200A10CBF5C00000200A110FFF51FEFD9 -:102880000200A1140000FFFF0200A118500003E0A5 -:102890000200A11C000000000200A1200000A00016 -:1028A0000600A124000000050200A1380FE000008E -:1028B0000600A13C000000140200A18C5554000049 -:1028C0000200A190555555550200A19400005555A0 -:1028D0000200A198000000000200A19C55540000D5 -:1028E0000200A1A0555555550200A1A40000555560 -:1028F0000200A1A8000000000200A23C00000000AD -:102900000600A240000000030200A06400000007CF -:1029100000000000000000000000002E0000000089 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:10297000002E0050000000000000000000000000D9 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000050008D5A -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000008D009200920096C0 -:1029D0000096009A000000000000000000000000C7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000009A00DB00DB00E900E900F7BE -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000F700FE00000000000000000000000001 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B2000000000000000000000FE01030103010E90 -:102B3000010E01190000000000000000000000006C -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000119011A00000000000000000000000010 -:102B90000000000000000000000000000000000035 -:102BA000000000000000000000000000011A0152B7 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD000000000000000000001520176000000002B -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000017601B5000000000000000097 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C300001B501F0000000000000000000000000ED -:102C40000000000000000000000000000000000084 -:102C500000000000000000000000000001F002354C -:102C6000023502380238023B00000000000000007C -:102C70000000000000000000000000000000000054 -:102C80000000000000000000023B02760276028095 -:102C90000280028A00000000000000000000000026 -:102CA0000000000000000000000000000000000024 -:102CB00000000000028A028B0000000000000000FB -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE000028B029D000000000000000000000000B8 -:102CF00000000000000000000000000000000000D4 -:102D0000000000000000000000000000029D02B270 -:102D100002B202B502B502B80000000000000000D7 -:102D200000000000000000000000000000000000A3 -:102D3000000000000000000002B802E600000000F1 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000002E6036D00000000000000000B -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D9000036D0374037403780378037C0000000060 -:102DA0000000000000000000000000000000000023 -:102DB000000000000000000000000000037C03BBD6 -:102DC00003BB03C303C303CB0000000000000000EB -:102DD00000000000000000000000000000000000F3 -:102DE000000000000000000003CB041F041F04319A -:102DF0000431044300000000000000000000000057 -:102E000000000000000000000000000000000000C2 -:102E1000000000000443044D00000000000000001A -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E4000044D0453000000000000000000000000DA -:102E50000000000000000000000000000000000072 -:102E600000000000000000000000000004530456B1 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E900000000000000000000456045B0000000079 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC00000000000045B045C045C046E046E04807B -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF000048004ED0000000000000000000000005D -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000004ED04EECE -:102F200004EE050205020516000000000000000086 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA000000000000000000000010000000204C05A -:102FB0000003098000040E4000051300000617C03E -:102FC00000071C800008214000092600000A2AC0D2 -:102FD000000B2F80000C3440000D3900000E3DC066 -:102FE000000F42800010474000114C00001250C0FA -:102FF0000013558000145A4000155F00001663C08E -:103000000017688000186D4000197200001A76C021 -:10301000001B7B80001C8040001D8500001E89C0B5 -:10302000001F8E8000209340000020000000400020 -:1030300000006000000080000000A0000000C00050 -:103040000000E0000001000000012000000140003D -:1030500000016000000180000001A0000001C0002C -:103060000001E00000020000000220000002400019 -:1030700000026000000280000002A0000002C00008 -:103080000002E000000300000003200000034000F5 -:1030900000036000000380000003A0000003C000E4 -:1030A0000003E000000400000004200000044000D1 -:1030B00000046000000480000004A0000004C000C0 -:1030C0000004E000000500000005200000054000AD -:1030D00000056000000580000005A0000005C0009C -:1030E0000005E00000060000000620000006400089 -:1030F00000066000000680000006A0000006C00078 -:103100000006E00000070000000720000007400064 -:1031100000076000000780000007A0000007C00053 -:103120000007E00000080000000820000008400040 -:1031300000086000000880000008A0000008C0002F -:103140000008E0000009000000092000000940001C -:1031500000096000000980000009A0000009C0000B -:103160000009E000000A0000000A2000000A4000F8 -:10317000000A6000000A8000000AA000000AC000E7 -:10318000000AE000000B0000000B2000000B4000D4 -:10319000000B6000000B8000000BA000000BC000C3 -:1031A000000BE000000C0000000C2000000C4000B0 -:1031B000000C6000000C8000000CA000000CC0009F -:1031C000000CE000000D0000000D2000000D40008C -:1031D000000D6000000D8000000DA000000DC0007B -:1031E000000DE000000E0000000E2000000E400068 -:1031F000000E6000000E8000000EA000000EC00057 -:10320000000EE000000F0000000F2000000F400043 -:10321000000F6000000F8000000FA000000FC00032 -:10322000000FE0000010000000102000001040001F -:1032300000106000001080000010A0000010C0000E -:103240000010E000001100000011200000114000FB -:1032500000116000001180000011A0000011C000EA -:103260000011E000001200000012200000124000D7 -:1032700000126000001280000012A0000012C000C6 -:103280000012E000001300000013200000134000B3 -:1032900000136000001380000013A0000013C000A2 -:1032A0000013E0000014000000142000001440008F -:1032B00000146000001480000014A0000014C0007E -:1032C0000014E0000015000000152000001540006B -:1032D00000156000001580000015A0000015C0005A -:1032E0000015E00000160000001620000016400047 -:1032F00000166000001680000016A0000016C00036 -:103300000016E00000170000001720000017400022 -:1033100000176000001780000017A0000017C00011 -:103320000017E000001800000018200000184000FE -:1033300000186000001880000018A0000018C000ED -:103340000018E000001900000019200000194000DA -:1033500000196000001980000019A0000019C000C9 -:103360000019E000001A0000001A2000001A4000B6 -:10337000001A6000001A8000001AA000001AC000A5 -:10338000001AE000001B0000001B2000001B400092 -:10339000001B6000001B8000001BA000001BC00081 -:1033A000001BE000001C0000001C2000001C40006E -:1033B000001C6000001C8000001CA000001CC0005D -:1033C000001CE000001D0000001D2000001D40004A -:1033D000001D6000001D8000001DA000001DC00039 -:1033E000001DE000001E0000001E2000001E400026 -:1033F000001E6000001E8000001EA000001EC00015 -:10340000001EE000001F0000001F2000001F400001 -:10341000001F6000001F8000001FA000001FC000F0 -:10342000001FE000002000000020200000204000DD -:1034300000206000002080000020A0000020C000CC -:103440000020E000002100000021200000214000B9 -:1034500000216000002180000021A0000021C000A8 -:103460000021E00000220000002220000022400095 -:1034700000226000002280000022A0000022C00084 -:103480000022E00000230000002320000023400071 -:1034900000236000002380000023A0000023C00060 -:1034A0000023E0000024000000242000002440004D -:1034B00000246000002480000024A0000024C0003C -:1034C0000024E00000250000002520000025400029 -:1034D00000256000002580000025A0000025C00018 -:1034E0000025E00000260000002620000026400005 -:1034F00000266000002680000026A0000026C000F4 -:103500000026E000002700000027200000274000E0 -:1035100000276000002780000027A0000027C000CF -:103520000027E000002800000028200000284000BC -:1035300000286000002880000028A0000028C000AB -:103540000028E00000290000002920000029400098 -:1035500000296000002980000029A0000029C00087 -:103560000029E000002A0000002A2000002A400074 -:10357000002A6000002A8000002AA000002AC00063 -:10358000002AE000002B0000002B2000002B400050 -:10359000002B6000002B8000002BA000002BC0003F -:1035A000002BE000002C0000002C2000002C40002C -:1035B000002C6000002C8000002CA000002CC0001B -:1035C000002CE000002D0000002D2000002D400008 -:1035D000002D6000002D8000002DA000002DC000F7 -:1035E000002DE000002E0000002E2000002E4000E4 -:1035F000002E6000002E8000002EA000002EC000D3 -:10360000002EE000002F0000002F2000002F4000BF -:10361000002F6000002F8000002FA000002FC000AE -:10362000002FE0000030000000302000003040009B -:1036300000306000003080000030A0000030C0008A -:103640000030E00000310000003120000031400077 -:1036500000316000003180000031A0000031C00066 -:103660000031E00000320000003220000032400053 -:1036700000326000003280000032A0000032C00042 -:103680000032E0000033000000332000003340002F -:1036900000336000003380000033A0000033C0001E -:1036A0000033E0000034000000342000003440000B -:1036B00000346000003480000034A0000034C000FA -:1036C0000034E000003500000035200000354000E7 -:1036D00000356000003580000035A0000035C000D6 -:1036E0000035E000003600000036200000364000C3 -:1036F00000366000003680000036A0000036C000B2 -:103700000036E0000037000000372000003740009E -:1037100000376000003780000037A0000037C0008D -:103720000037E0000038000000382000003840007A -:1037300000386000003880000038A0000038C00069 -:103740000038E00000390000003920000039400056 -:1037500000396000003980000039A0000039C00045 -:103760000039E000003A0000003A2000003A400032 -:10377000003A6000003A8000003AA000003AC00021 -:10378000003AE000003B0000003B2000003B40000E -:10379000003B6000003B8000003BA000003BC000FD -:1037A000003BE000003C0000003C2000003C4000EA -:1037B000003C6000003C8000003CA000003CC000D9 -:1037C000003CE000003D0000003D2000003D4000C6 -:1037D000003D6000003D8000003DA000003DC000B5 -:1037E000003DE000003E0000003E2000003E4000A2 -:1037F000003E6000003E8000003EA000003EC00091 -:10380000003EE000003F0000003F2000003F40007D -:10381000003F6000003F8000003FA000003FC0006C -:10382000003FE000003FE00100000000000001FF59 -:103830000000020000007FF800007FF80000026F27 -:1038400000001500000000010000000300BEBC20C5 -:103850000000000300BEBC2000000001FFFFFFFFCE -:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 -:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 -:1038800000000000FFFFFFFF00000000FFFFFFFF40 -:103890000000000300BEBC20FFFFFFFF000000008F -:1038A000FFFFFFFF00000000FFFFFFFF000000031D -:1038B00000BEBC2000002000000040C0000061806D -:1038C000000082400000A3000000C3C00000E480AC -:1038D0000001054000012600000146C0000167808C -:1038E000000188400001A9000001C9C00001EA8070 -:1038F00000020B4000022C0000024CC000026D8050 -:1039000000028E400002AF000002CFC00002F08033 -:103910000003114000033200000352C00003738013 -:10392000000394400003B5000003D5C00003F680F7 -:103930000004174000043800000458C000047980D7 -:1039400000049A400000800000010380000187000D -:1039500000020A8000028E0000031180000395001F -:103960000004188000049C0000051F800005A300CF -:10397000000626800006AA0000072D800007B1007F -:10398000000834800008B80000093B800009BF002F -:10399000000A4280000AC600000B4980000BCD00DF -:1039A000000C5080000CD400000D5780000DDB008F -:1039B00000007FF800007FF800000174000015008F -:1039C0000000190000000000FFFFFFFF40000000A2 -:1039D00040000000400000004000000040000000E7 -:1039E00040000000400000004000000040000000D7 -:1039F00040000000400000004000000040000000C7 -:103A000040000000400000004000000040000000B6 -:103A100040000000400000004000000040000000A6 -:103A20004000000040000000400000004000000096 -:103A30004000000040000000400000004000000086 -:103A400040000000400000004000000000007FF83F -:103A500000007FF80000050900003500FFFFFFFFB0 -:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 -:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012 -:103A80004000000040000000400000004000000036 -:103A90004000000040000000400000004000000026 -:103AA0004000000040000000400000004000000016 -:103AB0004000000040000000400000004000000006 -:103AC00040000000400000004000000040000000F6 -:103AD00040000000400000004000000040000000E6 -:103AE00040000000400000004000000040000000D6 -:103AF00040000000400000004000000000001000F6 -:103B000000002080000031000000418000005200D1 -:103B100000006280000073000000838000009400B9 -:103B20000000A4800000B5000000C5800000D600A1 -:103B30000000E6800000F700000107800001180087 -:103B400000012880000139000001498000015A006D -:103B500000016A8000017B0000018B8000019C0055 -:103B60000001AC800001BD000001CD800001DE003D -:103B70000001EE800001FF0000007FF800007FF8E8 -:103B8000000004480000150010000000000028ADEF -:103B90000000000000010001000D0205CCCCCCC1EA -:103BA000FFFFFFFFFFFFFFFF7058103C0000000009 -:103BB0000000000000000001CCCC0201CCCCCCCC39 -:103BC00000000000FFFFFFFF400000004000000079 -:103BD00040000000400000004000000040000000E5 -:103BE00040000000400000004000000040000000D5 -:103BF00040000000400000004000000040000000C5 -:103C000040000000400000004000000040000000B4 -:103C100040000000400000004000000040000000A4 -:103C20004000000040000000400000004000000094 -:103C30004000000040000000400000004000000084 -:103C40004000000040000000000E01B7011600D641 -:103C50000000FFFF000000000000FFFF0000000068 -:103C60000000FFFF000000000000FFFF0000000058 -:103C70000000FFFF000000000000FFFF0000000048 -:103C80000000FFFF000000000000FFFF0000000038 -:103C90000010000000000000007201BB012300F3CF -:103CA0000000FFFF000000000000FFFF0000000018 -:103CB0000000FFFF000000000000FFFF0000000008 -:103CC0000000FFFF000000000000FFFF00000000F8 -:103CD0000000FFFF000000000000FFFF00000000E8 -:103CE0000010000000000000FFFFFFF3318FFFFF16 -:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308 -:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69 -:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7 -:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3 -:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7 -:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61 -:103D50000C30C305C30C30C3CF300014F3CF3CF399 -:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4 -:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387 -:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98 -:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367 -:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2 -:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347 -:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45 -:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327 -:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6 -:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307 -:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47 -:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6 -:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2 -:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6 -:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60 -:103E50000C30C305C30C30C3CF300014F3CF3CF398 -:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3 -:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386 -:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97 -:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366 -:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2 -:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346 -:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24 -:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326 -:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45 -:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306 -:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46 -:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5 -:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1 -:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5 -:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F -:103F50000C30C305C30C30C3CF300014F3CF3CF397 -:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2 -:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385 -:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96 -:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365 -:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC -:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378 -:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62 -:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325 -:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23 -:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305 -:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45 -:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4 -:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0 -:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4 -:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E -:104050000C30C305C30C30C3CF300014F3CF3CF396 -:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1 -:104070000C30C30CC30C30C3CF3CF300F3CF3CF384 -:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31 -:104090000C30C30CC30C30C3CF3CC000F3CF3CF397 -:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B -:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377 -:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61 -:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324 -:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24 -:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304 -:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45 -:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3 -:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF -:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3 -:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D -:104150000C30C305C30C30C3CF300014F3CF3CF395 -:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0 -:104170000C30C30CC30C30C3CF3CF300F3CF3CF383 -:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94 -:104190000C30C30CC30C30C3CF3CF300F3CF3CF363 -:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B -:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376 -:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61 -:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323 -:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57 -:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337 -:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76 -:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316 -:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6 -:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34 -:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6 -:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12 -:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6 -:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE -:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396 -:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6 -:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376 -:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96 -:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356 -:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56 -:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336 -:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75 -:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315 -:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54 -:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5 -:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33 -:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5 -:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11 -:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5 -:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED -:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395 -:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5 -:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375 -:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95 -:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355 -:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335 -:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74 -:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314 -:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53 -:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4 -:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32 -:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4 -:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10 -:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4 -:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC -:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394 -:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4 -:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374 -:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94 -:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354 -:1044E0000040CF3CCDCDCDCD000C0000000700C07A -:1044F00000028130000B81580002021000010230DE -:10450000000F024000010330000C0000000800C052 -:1045100000028140000B816800020220000102407D -:1045200000070250000202C0000F0000000800F067 -:1045300000028170000B819800020250000102709D -:10454000000B828000080338001000000008010002 -:1045500000028180000B81A80002026000018280BD -:10456000000E82980008038000028000000B802863 -:10457000000200E0000101000000811000000118AD -:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B -:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B -:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B -:1045B000CCCCCCCCCCCCCCCC00002000000000007B -:1045C0001F8B080000000000000BFB51CFC0F00360 -:1045D0008A7BD81818F67020F843015F646260B8CF -:1045E0000CC45781588099812198918121849178B8 -:1045F000FD71A208F61321A019C240330419184E08 -:104600000B23C40F02D5988830307C878A5503D994 -:104610000CA2D471FF40E375529862AB2510ECF503 -:1046200058E491F10634792E4954FE4602FA071AED -:10463000DF5744E50B2940E86CA8F803347961A8FA -:10464000FC79A8BF1E2A6237F702541E005BBBD25A -:1046500053600300000000000000000000000000A4 -:104660001F8B080000000000000BED7D0B7854D577 -:10467000B5F03E73CE9C9949662627214F1E6112E4 -:1046800020028638BC0228B74E480850691D6C5578 -:10469000B468070810F296A297D6F6CB04428C8035 -:1046A00036F8FB408B3ABC2A2A6AC048510187A7DA -:1046B000E8F5F606AB9656EB8D68519147E456A5A2 -:1046C000FF6DAFFF5A6BEF9D39673201ECD77BFF6F -:1046D000FBDFEF8F9FDF619FBDCFDE6BAFD75E6BE0 -:1046E000EDB5F7D86D1EA65FCDD8D7F807CF7A1BEA -:1046F000632C23F67CC4CE7E18743356B0CEB7C27A -:104700009D0EEF77E56D4FF63196B37BAD3205DE4A -:10471000E7AC6F53E615C6BE0FB8A0723CBCDFB560 -:10472000562981F7396FB42973F1E9B0B14E68CFDA -:10473000345F0AC3270B3096C9D890894CFC05DC3E -:1047400039C58C0DC47F4217E78C64C6C63196B755 -:10475000D216092BF03E5439937919DB0470E5A485 -:10476000C177EA5FF6D9B16D8376BCCBC998537334 -:104770006A5FE733963B9BD9183C072FE3EFF1EFD5 -:104780006BF83F2F6C2D0F61A6721E963DE92760D6 -:1047900048E6619EAFD544F076EBC151B179CAE7E6 -:1047A000FA465FA65BEBFD5E3E97DCF6897E177CE2 -:1047B000FD18B61BCA5824AE7D6D58D7D815F00425 -:1047C00004B417F6FE7E262B29463ADCCAA6D0B3DF -:1047D0005EF3DD8878A93F62676180BBBEE1443942 -:1047E00096D92E850DCBEBFDFD2866277A943045B2 -:1047F0003B81F3F5322FCE4FADF13D540E786E482C -:104800000E9461BF0F2787E829DF67CF9B9E1D02AB -:10481000784A17158619D0FDDC3AC5EF80CF3F5690 -:1048200022BA1DE851FDFD86A269D0EE6D3D740DE2 -:104830007EB7488DB6D861FCDA390D054001D6A99E -:1048400073FE19BCABE4530DE83698B1704A1AD226 -:1048500085B1E3263AE0DFF1E1A2ACF68DC78B3DEE -:104860002BB01F0D7B89D07CE5FBBCF0912143E38D -:10487000C663C5040F433819EB5212D175F08B256E -:1048800047B4A2BEC7FBCF9F4798CB21E00EE95BA0 -:10489000EBD123CB01BFA52FD8A357033D6A3728FF -:1048A0001107946D7B5D01A4CF99CD5006BA443DAC -:1048B0003AB53F6D38A95CEFE8BCF72A2877BFA06E -:1048C000B28DD8EDF0241BCADD09013B1B0765C082 -:1048D000C742172FD66ED8772BF657B9CBC15C4895 -:1048E000CF17177DF72A282F027EC326B55B9AF4CF -:1048F000FE505E1C51DAB17C760A23FE08A7E991CE -:104900002D30DE596F67E6F5202F271B9DCC07A0C1 -:10491000ACF074667E1FF8A82AB2BD1CBFABDAA645 -:10492000F811EDA52F6C399C83F37A12F80AF8A8D8 -:104930007A6B32F349FCC1FF27602A5743FD129876 -:1049400027CAFF22D656CE541C7FADEEF3C4F075B5 -:10495000B2D1A0717AE4E9491807BEAB7B56F1E306 -:1049600014EB6C2C847275E645D7EC4D6E9C5F930E -:104970005EE0C179DDA563BB4591B93B5165554505 -:1049800036E8E5505FB57E83BEB010F1067AAF1011 -:10499000E1EA67856B9D1A40FC2E49756E54013F14 -:1049A000CC1DC8BE2E01FF9C6C043556102B57A1A0 -:1049B0007C933E89E8B34CEDCB9554E2D7EAAD2A1F -:1049C000F359F889D33F7C94D33FBCC713D99217CE -:1049D000A3DF1283EB4949BF25A9829E5A77712232 -:1049E00078EE457A003C6D882F78AE11F07927B3C8 -:1049F000120DE8E20D30436117E7CF363B9BCB60E9 -:104A0000EC37D982803609CA3ABB8DF91933B4DA4A -:104A1000401994FFC2826FE07C18F3FB8280E71696 -:104A200085CDC6791F4260613E2D393AE1AF6D6A8E -:104A3000F126551130A76379E12F57E5D1F76FD1F2 -:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3 -:104A5000FD7BD88E392FFC7D5BF995D6F1CBABE48D -:104A6000F71FD1F8EE0BC36F4C9B6C1D7F5A0D7D69 -:104A70005FEFE0F4EA4E75463642B9D9E50F684873 -:104A8000378D45F1BD9656B011DBA9921F5867408E -:104A900085EFDDDB52C7AC6266BE98F2271CCF0300 -:104AA000D262E68B948949167E4C0DA459CAD093E4 -:104AB00071E2F2981E0A789D048FDE5F277D51D245 -:104AC000DF49F0DEB1D745E53BAEE4F0DED1DF4DA6 -:104AD000728630B01C28EBA12B0CD37A04702A2CE0 -:104AE0009BB12F94904B196F7EEFB3E1FB2495356A -:104AF000E07C921C8CF4D15D79C59BC226FCB40E7F -:104B000002FA42395DD1391E055EEF1AB4307BAE30 -:104B1000699C9641FAEC8D85FCFD7C378E17CC5450 -:104B2000500FEADD0586BBF7388EFC8996719CB97B -:104B300095344E5EDC388EDCCAB8719CB3378AF788 -:104B4000629C21171AE7AEFC2BADF3C9ADA2718AA6 -:104B5000E2E7935B15374E129F0FBC17E3F8117F06 -:104B60007DCE67C864EB7C06D7D03857E138E34D7B -:104B7000F3195C13378E9BC6C1F7380E18523E9658 -:104B8000057477742F24FABFE2227B4177849EC09C -:104B90007ED9BB2E46FAC407E366A15E81C519E43F -:104BA0005753D2689C2F9380FE6E339DB93EA22747 -:104BB000E89F05024416018840FFD4091EADD8368F -:104BC0002BB7099FBB4AB3E7A25D72BFC73F0C4436 -:104BD000E7CCAE527D7E02FB66419BFD4497857F0C -:104BE00085DE9BC28637C0F81DA86C4CE513A0BFBC -:104BF00018E8ADE3A0BFF0F9B1B04F3F02FDC674B5 -:104C000033BC4D348F131AC7E389F57C1DF972ED5F -:104C1000513B187B38CC5B8500F70D621A0BDAC06C -:104C2000F833C959BDA047F78B8EC846A2476080AC -:104C30000DF89CADEB07B812EDC0CEFC83B047E198 -:104C40006F800D6CD99B5BB71FC266EF2873072D71 -:104C500081F9CEEE586B1F00E533F6AE5BFD6E5367 -:104C60003FB3EDC771DE4EF80FFBB92964B7D8A783 -:104C70003FA8B4966F89B3576B947C410F31AE2F28 -:104C800062477ADD90C9E1B9059F63B0DA207ADD29 -:104C90006AF06F253CF577DA5994D6A3AE0C5688A6 -:104CA000F8C820BB2824D79538F86EB53B0341A03F -:104CB000E7AD3F56098FF1F076ED4D0ED8C05EEAB4 -:104CC0005AF76F76B4BF2F06FF0F9759EB59988F9D -:104CD00027F12AF9E0C6D925FD3E32B5BB2934A318 -:104CE000DF47267EF941E52C4BF996869B2CED7F1C -:104CF000B86CAEA57E6E78B1A57E7EEB6D96F28225 -:104D0000B61F5BDA2F5AD764A95F1CB9DB525FBDAF -:104D100075ADA55CDBFEB0A57DFDAE0D967ADBDE44 -:104D200011D7A23CAE785B65689F7DE13E712FDABA -:104D3000575F189A1FDBD421AF811C7ED2984DFC9F -:104D40007DB2D147CF33BBC63AD11EAF4F02798671 -:104D5000B57EAFF28770EB64D423D01E74F87EE585 -:104D6000C370189CA7D7141FF1BDBA4E6751605588 -:104D700085A5F5F075B71AABD7BAA07E6CDFF5EA5A -:104D80003A2D61BDD6A525ECF7ACD25D80F65DF875 -:104D9000770E8676605FF603FC0DC0F5A2AFFA537E -:104DA0003656D96ED23B27141BF1C10DCA9413A8F5 -:104DB0009F6B742EEF353B72A6A03F58A3470B1A8A -:104DC000DC1718AF1D80C9C27EF2695E8B230362B7 -:104DD000F24BF41B6291FBA52CF447D4CFA7F6A9A4 -:104DE000A46759F440EEF746E1F88113F89EEDCA46 -:104DF000A0F5F19DC640BF8FC09F3BD6389D9EBF9A -:104E00006F0CF6FB0874CD7B8DB3A9FC7E63889E86 -:104E10005D8D95F43CDED840F51F352EA3F289C692 -:104E2000303D3F696CA5E7C9C636AA3FD5B88ECAE2 -:104E3000671A23F4ECF103843DCAD285FD27EC7593 -:104E40005839A87C4ECC41857F73BFD59F8D727D2C -:104E5000CEFD6501DAB9E78E816192C03F94CF78CB -:104E60007EEB9B7E015AEF174680FE637BD7BB9299 -:104E7000387D5C36369D81FEB97B98CE34183FE98B -:104E800095CBC95E86F71A237D19F1CFF224E81F6E -:104E9000E79C75713AF5F0C723FF5E8CF1871B84A0 -:104EA0003E4C3AA03670BA6DF223DD4CF8E376D969 -:104EB0000B429FC7E1916CB99CDEF83C9D21F1D972 -:104EC000998B7180FB95E0081BF0C1B90E07CDEB03 -:104ED000DCEEE408C36F313832E94278E370546F96 -:104EE000751966FD50DB9E6A58F5458E61D617E749 -:104EF0008E6CF2A2DC2FC9B6191F8D45FE0808FE84 -:104F0000E07C27FBAF6DCF33DC967EACE5736DCADA -:104F100074F48340B9A77C3F817F209F4BB275E337 -:104F20002390EF935B87A4E0B8E0C71938CEA94679 -:104F3000C3E0E3661B66BEAC599644ED257C7DF567 -:104F4000FBF7860F2D830F9D8C50FFF5906FEE675A -:104F500033ED4F14CF61BBED5FE2BAE380FFBFA634 -:104F600078804665D96F7DBB1A765C81EFB759C6EC -:104F700083EF7CD287C6F5AA6FBA6BEC84292E50DA -:104F80008763907FE4243A87A0C714E8EFACE66E0D -:104F900055609CE9361FD5D70B7EAC7576E9217834 -:104FA00075BA83D3A3AF714E361EF169A03F2A9D17 -:104FB000E091C13895ED23CA503F9EEE58911902F9 -:104FC000BEAD56CFDD114CF07DAB4DE1F044ECDDD4 -:104FD0005DA6F9C8380A63D0AF33063F72FA0953A9 -:104FE000395E5FCBE77DD82FF047DDB6A3E55701EB -:104FF000FC75BB3ED7118EE9B6D07DB68CD8FC15BA -:105000009C3FF453B5F5031DE7F7893D5C70E70558 -:10501000F4546F38DDD914B793F0855927DA31F39A -:105020007AE28ABE1BDF05D1FCF49FEC6C15C0C18F -:10503000FE02ADA0DE2E6A2B58D08BF89AD7514DC8 -:10504000F1C54F6DD26E6A2B46FE38CD6CD3717EA2 -:10505000A7D99BDEB126FC75D8B8DDCF5AB91D1390 -:1050600086FF101EB0672D76CDA275D6F242765D12 -:1050700026EA8D85F7DB590450B418ED22C91F309C -:10508000EFCD366EEF2E620D2D68CF690EEE1FCC80 -:1050900033983600E0AAFDD5A3C568F7BF6CB311FD -:1050A0007D649C61711A87BB2A3DA207A0FEC38E56 -:1050B000B1375C85DCE788B4E0BACC52987F0BEB63 -:1050C0008DCFF9AD56F82E067F3CBC8C2DB7C02194 -:1050D000FB9570A85B95402401DFBD26F94EE89151 -:1050E00034D56AE767C595DFB389F8A5CA54A4F338 -:1050F00069C319B6A550BD3F8AF1911D0EFF0AA0E4 -:10510000EFEDB66017EA67B00B8A98A9DDEDB6102F -:10511000BD3FA5BCB110ED53A6458BD0BF8735452B -:10512000437ED0053FA849DE228CC77A18AC9F2069 -:10513000970E840FFA69F154CE6445187F053985BE -:10514000FEEEF1961F51A0EC727730ECCF916D8D91 -:105150002FBB7CD6723DFE03E9309C511C2779B8E9 -:10516000B51E162C86FCE6F15BDFFFEF1E3C458981 -:105170006FBDC4D2F074BAA32A8CCF266AA7CC76AE -:10518000739D93C34F7E39B45F2AECF93AE60B5313 -:105190009C389BF3C1D219368267A9C7E70F43BD7C -:1051A000A20518CA1FC6AACDEB58FD7910B97EA674 -:1051B000B2D6AD235FD69FD75804F47D912DE4512C -:1051C000C723FE0264E73A01595F03C89A7BBAC558 -:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811 -:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B -:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF -:1052000062EDF212F557FBAB67768601FF55CF3D95 -:10521000E005E2B34FB5B64C3FBCAFD9B2D28B7C00 -:10522000FC8916F6E2BC3F8DA8D313F1F30DAA2238 -:10523000FCB1805B417F58D0E9E453ABBF8B78FF72 -:10524000728BDDC026F55B1D510710B1AE6331E7EF -:10525000A7AD8E0F78F9AECF919EF5BBACF256F5A7 -:10526000C4039918EF040C71BF9145C97EAEDBFCF5 -:10527000C772B447EA5937E989F8EF70FCF369B4AB -:105280007ECDD5537AD7CBFD977AC1F7F51DAB3FCD -:1052900057BD58B6CA77A5F047A6A99E748A2B4D6C -:1052A0006013906E120F2CC2EDE1154F3E54F401C5 -:1052B000C0716AF33F79154BDC88EB8773EDF31F00 -:1052C0007FC9D7B75E3F23FCF9D87711FACEB78BE9 -:1052D000DBEF6C377FD6D8A35EF4976A36D8FD2013 -:1052E00099ACE6994DBF7C04F9FA770E8A33543FA6 -:1052F00073E89D2BA15CBDDD9E3E934FC3AD64C69C -:10530000E8510FFF2F1B13C37FD5F38774DF28FEEF -:10531000FEA769313A546FDFA7B351BDF156DABE2B -:105320004FEF7227A047FB07E5686FAF78F22B1DA0 -:10533000E5EAD3BD0ACBCAEBFD7DE5864364CF2108 -:105340009E887E823E3DF4EA45A7E8775F1A47EDE6 -:105350000C5CBFFAA2D3485CFB32888F9F7D09E3C7 -:10536000F7BF77F871FE95CFFEC88BF3F8586BE066 -:10537000FCFCE8CACC008C5B690F671AF4E4EF2BE5 -:105380001FBB9DF86CD1D1DB33291EC00239365AC0 -:1053900043C33938BF05EBAFA7F92D6421E2B7CA83 -:1053A00047D56004E3591A9BBE3D813CBC21E4E132 -:1053B000E38D0E5C7BD8C7A860D13F7C53A57D02EE -:1053C000C66EA378C3ED721F822DA1F2174E4EA7B1 -:1053D0004DAA4DC6379C163EDD7C5727D2E7E4A088 -:1053E0004016C627010F61812F05F58E7A746A1663 -:1053F000A70FF369C5E23BD08BA5F81EDB77DA0374 -:10540000AE22CB77621DE3E32F15E303DC49688FFF -:105410007D9C09F64D82F97DA54ABD0CF68689BFB3 -:105420004C72CDE57CF3DD5CAEA59C47664DC7FABA -:105430003FBDC5E507BFC3751DE08A6651FDBEEFE0 -:105440002BA4071C2C9A489E37DB853C5BEBE5FEC2 -:1054500024C0ADE1FA14E313E83F8DF04F76DAC2D1 -:10546000FBE13B935EAEC7F1A89D1E7B6F5AD71739 -:1054700009F97F5515FBA342FED97A2EF77DDBBDD6 -:1054800061EE1FD823BF7C04E515E413D7999A6712 -:10549000EC419CF767DB0EBC7333F0F567ED524EC1 -:1054A000AD7A335E4E2B778C6789E4F433B79F2552 -:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17 -:1054C0004C9CDE947AB02FFCC5EBC135AA2FA11EEF -:1054D00084BFB758716FBE93FC26F9ACEAE9DAC114 -:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3 -:1054F000F8FA1785BE9174B62F67610FC64BF7A8EF -:10550000E45F9F05985A80BE67B7E54530EEBCD290 -:10551000C5E317678D6E6F1A3C57A6F2727786DE69 -:1055200082FA41BEEF76F1F8F6D960B737D5E45785 -:105530007CB05BF5FAA0BE2BC2A627F23740F3126F -:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0 -:10555000D27E7645D38D5EDC073EBB7BC8CF513F04 -:105560002D780D0C4C80F72CDA812938BD80867996 -:1055700009F305BD3F61E10727C3FCE6EFE6FE4204 -:10558000C59A38FBDEBD54477D03F6FD716B5C9B0D -:10559000F34D95E8A772BDB5BE8AAD21BA55C5F1E8 -:1055A0005148F8811334C147A3D968E187F1F885E0 -:1055B000D05753D5C29FA39D71F6088F2B9EDBADAC -:1055C00012FECF6D532218F7A1F8EE24A47FB7CEB8 -:1055D0004CFEF229E437BD6F393EF5C21F8AEF84D5 -:1055E00026353BDF2DFA053C4FEDFC5DC1CB58FE67 -:1055F000D56F73DF65BDDB97EEFD33ED1F9FDDEBF0 -:105600002038CEEE7D35F74E2CBFE4F0239C679713 -:105610003B68FF2CBCD7131986F58380DEB86EEE8D -:10562000F9AAA88BD69D66A2D33C8DEF779CDBFDB3 -:10563000EFEF2B987FB0DBE1C379D4EFE57921F56B -:105640002FB928EE7276CF57C521F7DF6F3E753A36 -:105650000B11FF79D8EC1DC8AFA97C1FA0FEE5494E -:105660009B9A703FBC639F8EFB2BA5AFFCB508F5E2 -:10567000CBD91DDC4E3863EF7A0CF7416BB5A1CB6B -:10568000ED28F768B3F507BBD3BE604AB830115EAA -:10569000381ECE021E705E80974AD48B7DE1A359DE -:1056A000E3FEE67F3F7C7C7E2B8E5FB37B02C94DA1 -:1056B0000C2F4A80BFF7449C0ACD9FBFDFFB5511DA -:1056C000DA3D9FB537D13A7EB1796FFA1F376F2532 -:1056D0007A29F3DEFFDF9CFFA76B7C5D8A9783DE70 -:1056E0007CFEAB3BA8FCACC74FF05EA2FC1FFF9F4B -:1056F00046F71D4077EFC5E9AED8FFBBCEFB62741D -:105700007F4DD0DD63605EC1D93D7FA578B99CFF38 -:10571000C5E6EDFB7F74DED2FE5965F3B7E543FBCA -:10572000352CDAE90338570EBFAE0DC34CE0260422 -:1057300013D923413BF78F5485C761D8201E1762C8 -:10574000C29FA014301FC65116925DA7B95BC8CE88 -:10575000649ABF3300F85835729E9F7235D89863AB -:10576000212C0F9CECA7F8669C5FA58DFCF611B46C -:10577000EF9B9B003E18A7D9A319602931FB705BF2 -:10578000D45144CF0FF079978867D90DDDE257B82F -:10579000E3FC0297CF5AEF10FD3BD97E03F3889CC0 -:1057A0007E8D45B01D6B0B9BF3071CCCF41DD417ED -:1057B0006200D6643F7E53FC35F5E06F4C6700F124 -:1057C00037C246712D4AEA237CF823AB781E85D375 -:1057D0008ACF964EC4A3C6C0FFE3F322BF91097FD0 -:1057E00051135D68C36D0197B59DF08B2E4A1F4E16 -:1057F0008FDC1A419F25167A48BC5F802E167A48A6 -:10580000FC7E53BAC4D3231EFFDFB7F3B89BA49327 -:1058100025BF2383FB2151F0435EDDB689E21DA73E -:105820009FFAE0BBC8A7D52FABCC09DF9FD9E661B3 -:1058300051945F2DA2A33F55D5A1268CF34ABBBC42 -:10584000FA390FF179D50E4764267C5FB5F3C32290 -:10585000B29B96771F1E807181A7144EBF7057119F -:10586000EEDB5569DC3F88EF6FBD9DC7054EBD98E7 -:105870003C1BE30FCA569EAF58D57EA3DD61DA7795 -:10588000FE5F769EF70AED489EC34F2AB4DEF4868B -:105890008FFB05A79E54387CBBEC11CC7BACDABAED -:1058A000410FA15FB9F5738A63973EF78CB78BFC04 -:1058B00045D5EA3F6F55899EF024BAC5FBB1751DE9 -:1058C000B5E427D4B50B3F31CE8FAA7E6ECFCE3054 -:1058D000A0A6FAF927BC187F39D9B9C54BFEE956FD -:1058E000EE7F6A6E2DB17F7A31BFB4FDEE847EE922 -:1058F00049FC07F813FBEC71FEFCD67E97B67FF9E6 -:10590000CC178F619CF4D48ECF1E43B86BFEE3DFBF -:105910001E43FB9EED75195B60BEF54FBD4DF12634 -:10592000F9DDBB424ECF0C62E11C6877E6770ECA08 -:105930001F39B3E7E35CF4E7CE6CFF7326FAF54B4F -:10594000F74CCDC2792F7DA1348B259077F944BED9 -:105950008C5C429C309E0E073A0E901F72FA988320 -:10596000FCBE9EF8427B2D8FD7F8445C615BE23829 -:10597000ACF487EB3A3E2CE7F131E1175F2C8EF067 -:1059800016D0F18A4BA0D73611278AA3D769FC0716 -:10599000D0E5AB387A7DC1428FE7E03E6447BF3E39 -:1059A000E308D14BC0938CEF1EB6076C3ACAC18E88 -:1059B000E41E3ACD443A3DF3452EC6C33FB177933A -:1059C000DDD3BDC761A07F5FB5E7B72417675E3839 -:1059D0004AF15326E2AC6758CF1F8F8B29627E9B1A -:1059E0003D3CFE20F08DF1099F97DE8B3804E75790 -:1059F000199FE82B2E314117794F22EE5CBBF95DE0 -:105A00009DC5C579948948A70F2CF17139EFF8FE2F -:105A10000CC4C304737C2D71DC47FACD313AF1B864 -:105A20009A8C9F9DD920E26EF07EE018F407791CD5 -:105A3000A33EA2FC96259043195F1BA3C7C961E44E -:105A4000D2E26A1783F76FC5C7309DAF0B122FA73D -:105A5000FE92580F7F47E7723DDD169AA99BF6B379 -:105A60007F28F65924BE24BCA7441EDEA9A7548A69 -:105A700007B5B41F207D1A2FCF757D9C83B855E7DD -:105A8000F1D6BA5DFB8A50EF9CDAFF22F15DDDB6FC -:105A90000FF430F47378EBF33AB727399FA39E8E57 -:105AA00098F4F4A967F715F1B81FCFBB8DEFBF5A73 -:105AB000F45FBFDBDA7FFDB6CF2DFD5787DB75BE08 -:105AC0005E5E789C935AE0469CEFC94E3B437D77DF -:105AD000B25D9D1E496407EA76CB3E68CB519DD6E8 -:105AE000AB716F26517EEED2A3D3DF4DC17D3A104C -:105AF00033B47F3B9A385F75FC2C3000E9D271F4E7 -:105B00006615D78D9D8847931D5CFC5643A907E415 -:105B1000B5F8BDE03864AB783D30E198CD02378C04 -:105B20009385FAB819FAC17C7ACC1FC2FD51D55BB6 -:105B30003E1DE1510D9BE14AB87EF2FEECEE2043A2 -:105B4000BBDC6E58F395B3AF1371B4A8356F3D5BF2 -:105B500067C3711F9CD992FCB81FB0644460F421E4 -:105B6000CCAB5F904D71E29CEFF1EF4E1BEEB0EDD0 -:105B70008AD8BE6DF279E81FF3606C91B573E0BB13 -:105B800064AD5DC17D007832A4CBEDB6D0463D0357 -:105B9000DBE9CC07AAF1315DD128FF429C7B91FD66 -:105BA000C9767DED07CB7348AA807F88D80F1EC4C5 -:105BB000BA14DC0F5EEFE1E79106BBD3E9BCD12656 -:105BC00061AFF970DF15DB3558D7ED8B9E476AB5AD -:105BD00096D34B4B6E1BEC073F58BFA354037D90ED -:105BE0007E63C9F60106EE4BDF5F8A79F7E94F94D1 -:105BF0008CCE81F26C475119D5FF4BC9E85C28FF68 -:105C0000A8755219D5572B9417B847EF2E0DBB63C3 -:105C1000F29901C62DE65B80DCEE47B93D1D3CD50F -:105C200082B5B5D77FA9F3F3302C88F31F3491CF19 -:105C30007FA0FBBDED38DFC1B6AE26E4BFC7F77C61 -:105C4000958AED7CCCA0791AACD9C07D797835F1F4 -:105C5000EB0BE4FFC4E7C1487E7F2E39F41B84E3DD -:105C6000EE79C31F2A479D5AE3273E8ADF276646FF -:105C70003AD1A542D005E1749AF2902BF12402E9C1 -:105C80009B3203C751C235EAD7977F73784E487E5F -:105C900011E7C04CE7A43E45381F4E0ED133FE9CA1 -:105CA000D47E3DF819F253CEC2F3B908BF3CFF547D -:105CB000BAC84D718173BB59C491407EE4736323AC -:105CC000CBD086F65DFFB623F4671C37FF15DF8E59 -:105CD00023D0DF1515BA1F53D7AE58362E431BCB32 -:105CE000F884D09E1074CB465AA27CDDC1F8B91C52 -:105CF000871240BFF1EC8F0CD2BF032B66925F710D -:105D00003639AF1DF327CEDEC9F300608557500E3C -:105D100006ED4E89A2FF037CFC651C1F7F695D6751 -:105D2000ACE39EFDDAB7AB8BFA33447F60E864A244 -:105D3000DCF0BFB32AB7B3CF36FA080E300BF7E169 -:105D40007A7AA9E3653BACE7F400EFFD1D26BCE7DA -:105D50003AFAA45F9E83D38F9EF1F45BE86CC8454A -:105D600039AE0AB697A36BFAF1C23B8A91A9DFD686 -:105D7000439761FB9AD99D8779CE504301EEB3F5E5 -:105D8000A62F3F8F95B97B6E931DE315481F5F6F5C -:105D90003A5EB1CC9FA1F5B3D0752CC27FC5EECFD2 -:105DA0006D08BFA4E74322CF3FFEFB6F3914316E6D -:105DB0004D931DE324BB74B267E3DB4DC74355E34A -:105DC00063E52267318D9B65E3F18EDEEDF9FA170D -:105DD000EBD749E7B2FAE2C72283F707F8FFB61913 -:105DE000FFDFED1BFFB3B01DE09F9EDF00FF3762BA -:105DF000FBBEF02FEDE86AA117AA711F05F8E88F26 -:105E000081EB3287C2F8E5AA9BE460F11695E40FB6 -:105E1000DACFCCC98CE991C5931AF6E17C173FAA79 -:105E200010BF568873A69F89BCFEF87CA885B3C3B3 -:105E3000B4BFD32B2F2A12E7D7C5E5BBD7C7F87657 -:105E400030CF53E3E7B6542117A58B0A53D01EDA9F -:105E50006BF7FD0BD9D9AFA96C6302FC6F402633F9 -:105E6000D1755083CD9227CB2A522DFD962D2AA491 -:105E70007DEF251EDF05FDAAC1CBACEB765ED87A9F -:105E8000CE6848ABF59CD1B0B6FE96F697ADCBB7D1 -:105E9000D48F888CB4D45FBE758CA53CAAFD4A4BC8 -:105EA000FB2B764DB1944747BF6D693FF6C8759699 -:105EB000F2F8CE9B2DED271C9B67A99FD45565A9B1 -:105EC000BFEA932596F23F74FFC46AA7D818E94742 -:105ED00096A490BE3CD8383117F3B1D938A50CF14F -:105EE000592AF2090FDEA6DB0C2F3E0B6C06E8AD3B -:105EF000FD0B66D2BA7FF0B6CC808F9EC501F46BE5 -:105F0000983A795CA27CCDA9C6A45C735E54A9D3EF -:105F10006ED16F530D6B79A743ECFB0DE67CF372EA -:105F20009C7CD91B2647C13264FD170FCDC2F140BE -:105F3000CEF60A3DB7F792F45C6643319641CE0E39 -:105F400026923326D6D912C14FF00CE8981F59E695 -:105F5000A1F538802F7DF43EAC81BC4C71FA071E50 -:105F6000C279D9FCE9C88465B38307797F625D662D -:105F7000C36DDF645D96729E6D13F96B693C7FEDB6 -:105F8000E1050529CC84DF3F386CC28E6EE34FE318 -:105F900088AB276F35DFFCFE9324CD942FA72C9A76 -:105FA00049F922D97DE8453D3B7FC666D0C77A8E48 -:105FB0008F9EF27DCB6C5BC23CB06EA147A5BD3518 -:105FC00022666F75233D4E67BFF920E629D5CDE9DE -:105FD000267B2BDBD676DB619CD7EBAA885FFAF8B1 -:105FE000F92A61272F9871DF6D87715FFA9F87917A -:105FF0007E92E3AC6F9C3E43339D231FD887DF74B2 -:10600000B993C3F358E3F0191594B76DF0F3A2A256 -:10601000FFDC706D39DACD8345BEE983B6C4F92E55 -:106020006ED14F16921CE135DC2427A717BEE7D5A9 -:10603000601E8FC0EAE5C47DDB2B3A8BB91D16F0DC -:10604000E339D4DCE82D0F62FBDC6C8DF25DE3C735 -:10605000CF9A136ACDC3F8679ACDEFA672B782EDD7 -:106060001D3F65AC1FB46FFE0F95E069DE3F89F2FE -:106070003F1CEE0686FBA9725E07D21E21FCA81DFE -:10608000C9B40E32B12F2EE3AD5F645774A2BDF1D7 -:10609000C5FD761AEF0B98A301FD7FD1A1D2BEEB0F -:1060A000E1B4A4A80DCA6AAB87D6EF5CB43DA1FDEC -:1060B000C20E4FC49717C38BB66E329D87710CE426 -:1060C000F36F4E7347DC7934EF749CB78453CE7B07 -:1060D000501F7E6689803BE7B29E731A0CF95835D3 -:1060E00034EA77412A3F8719699C28E8659D4F4B20 -:1060F000F675D7DE84E787DE5219A686F8BADA6825 -:10610000FE0B61FE115F6FFC9EF6E57D695309CEC3 -:106110001284535D574EF3A076F05DEDE30A7B24C5 -:106120000FF930349DE8DADF46E7027BD9074E2EBF -:106130005F339C3C2F57CF2E98B1B91F3E87925C9E -:106140007CC7D9E7BA1F74727D44CF6F70BF00ADB2 -:10615000FF521FA9019BB073B95EEAB19FF4D00F43 -:106160009C19B1B29AF2D322ECB76FFB6CFB3E1DC7 -:10617000ED333723FB59EACDBEEC33B4CB90DFA42B -:106180005DB6386E9E30BF1A31BF9A44F3EBA56FEF -:106190006F6E9076CD12E705ECCA0C3DB13E7A5297 -:1061A000D0A1DED019C59B688D02BDB3D846E78D5E -:1061B00099167199CF97AF774ABB6EF73E1DF10CD8 -:1061C000F3463C6783FF5C4E7AC79E302FFC62FE2D -:1061D00048FEEAC21D47B03FB07311FA736DBE941A -:1061E000B40BD817F665AFBBCC78BDCF29F2B96335 -:1061F000787C40E0F18184784C073CDA2CF6E1CEE3 -:10620000021FE1F117CE0BD887A7BFF77E31AE474B -:106210006704BEEA7AFC5CAE9FFBC32285F1AA5AF2 -:10622000CC5F76F232EE07E15E0CC6E18A6CC127E4 -:10623000B0FFFA5DD673873F73F2381973F373B307 -:10624000B2BF4CA1EFC1AFFED61F7DA4F7FF11E78F -:1062500013F3AFBB8AD1BF5AF1C26529689795ED98 -:10626000BCC9C0E7B9F4A1B49E9DDEE908209CA793 -:10627000D378BEDEE99D130E63FCE1B3C623F96655 -:106280007D7FFAD9A3C576E8E7F48EA3C51AE507A2 -:10629000472C7661EDD7BF29C6735832AFBA875FF6 -:1062A0009C7C9DB8DFC5E31A19997A0BE68B9F4F4A -:1062B0004A257C3D9069BB3751BC06D527EDDB7B79 -:1062C00074DAA75C32C2B7C28DF19A3C83F2705780 -:1062D00028819C05B8CF32CBE9C77D80F47C363C61 -:1062E0002F055118626EC0A7E3601B1D374DEA34BD -:1062F000F6A17924E3385A29D7B7DDD7EB9437963E -:10630000ACF91E9A03E5ECD91AAD7732AEE348E654 -:10631000E792655CA7079ED7ECB40E2DC90BB59527 -:10632000C0774B26A5D177DE59EF10BF9CF5D9C2B7 -:10633000769C8FD64DF19D9F370ECF180A78347218 -:106340006C33C8A6F90B60CB94FFEFD5583805EC39 -:106350009BD5C0FF4381FF3B1A9DD4BE05EC432370 -:106360008DEE4988DDF361929B1D8D06B5FB65635B -:10637000367D775FA38F9E3D7604E3DF5139817EC2 -:10638000FDCF7ADED3C8EF1391E57F1B07761AD0D5 -:106390003B7D025015F0922ECE9FCBFA471A5F1B21 -:1063A0005236542003F0D9BFC6D8B0EA02F0A63B5B -:1063B00022A978C4F872170B974DC43CBFEE7BCB73 -:1063C00053F17CC45D656523008FB8BF7D2590CAFD -:1063D000755F339E4FCDA9F13561DC2F6797D28E63 -:1063E000EB57CEAEB525B88F00EDE8DCA0EC37C397 -:1063F000C5F55CF2818795FC51B8B9C0F7E5D99E27 -:10640000E448A2F3A5E35C5CCFF95D7C7F70B5D86E -:1064100057EF9EE526BD987CC045FC92B3FB72DA2F -:10642000DF73F7B1AF1CDF4FF2813F531CD8ADB41F -:10643000EDC37D4AB680DB9F929FFAFA0EDBEB97A5 -:10644000D0FEAC5FA3B83098BD34BFD3B30612BE44 -:10645000B1BD598F9FD513DB650181A795F6C47136 -:106460007A8DF171C67576D37E26DEDB84F8CE791F -:10647000AB4D417FFDB4C2F331FA033E764039673C -:10648000721BDDEBF49C3354EE82EFFE641C2B5840 -:1064900009E0B80A7F9F8BDF497CA845BA13F5490C -:1064A000CEEE0FF8391F5B978EF96F8BEE7E9EE272 -:1064B0008FAA1ECCE3E5952B313E99E10D6E403E4F -:1064C00061E1E7CB0E029F3C20CE2DE31BD47BABDA -:1064D0005DA21C6E6F0E009FACB6F3F2A2BB9F23B1 -:1064E000BE596D0F2EC673CF586E86FE57A7B6677E -:1064F000DBA0EC6E7AA6F9C8202CCBF6CF34872728 -:10650000831DEA92FA39988378EF291B501E652A79 -:106510006BBCCC9CFC29E7577BE0CF870700BFD43E -:10652000EDE6F7DCF4E06DD75A05D7A35F361EF130 -:10653000356B424EA4FE8075FEB26C467E8A1E51BB -:1065400022F90ADEF7D19A69CE57F941B222E21652 -:10655000F0BD39FE1877AE8D8ECAE0FADCCCF3427E -:10656000E2E9FA7652495B52069E470DAD52510F51 -:106570003E633728AFBE4B23BD7D4AE6D537D8C929 -:106580001EAC11E75CEDCB43AB46A05CDCA2F9315D -:10659000BE509DD75682F650F58B79FE2616CBD38A -:1065A000AD4E6DCF1CE38EE5E9CAF20A1197CA4AD7 -:1065B0006D484D2DC4FD98B5B9B85F52C7DA6EFD70 -:1065C00009C2FB86CA90DF3FDD372905EF1DAA858A -:1065D00032C6C16A3B8EEA2168776512BFEFA6AE6C -:1065E00003F8C6CDEFA1091430B641339250CFFF66 -:1065F00032D030124DE24DAE5F97B9FE81B127F235 -:106600000306D2F995BB8F353BB1AC1B23D8682C60 -:10661000FF6B33F259F5681BE559B2F0BF1E0C0C45 -:1066200015FBBD506E750D9A6A8E7BE7887386F5F3 -:10663000EBDD741E0CD6E58DC8DF75EB6C61DC3FBD -:10664000B3393BE91CD02B2E26E8633D3F75BFC212 -:10665000F56178018FA72E9D91F66D3A3FB532DF37 -:10666000085F20AE5B793E89CE49C9F295493EEA82 -:10667000BF520BD33E52E5792F9DAFFAFB8DE7B4A5 -:106680009CD7EA3D9E9BE091E3D5C4C623BA1E1871 -:10669000F3FA8343816E4BB7DB6D0E13DF2DDD2ED6 -:1066A000F6E75D812CEC2743E77866E80F02AFD16F -:1066B0001D37BC1CD6B241FF4BF90E9F6B2E9B8C35 -:1066C000748BD533ABFC07D01FBF274996FFBDB9EC -:1066D0006C6082F64971EDF365FFEA4AEC3F1E9E5D -:1066E0008CA458D909EDB5BF3A7ACA08DF5A5B5C69 -:1066F0007F69B2EC5E89E34BBE6ABD3BFD5018F882 -:10670000EA9ED4B612D4FFDD0B980FEFD1427EF58E -:106710009BF46DAB8BCB75E5F97C0BBD63782FB02B -:10672000D0E5E3C66CCBBEE7A2394B697FB6D52571 -:10673000E8C5C2FC9CCDFA012C628A07FD7F38FEB9 -:106740005638AEEC038E6FFD17C3E1B38C1783632D -:10675000A805BEBF158E8D37147C3B0F9A3CA084D4 -:106760009DF9B82EFC8CE7C5A9A965BE26DC97F972 -:10677000994671FD618CE7BBE46BEC883606E5A7B2 -:106780002D807110B69CDB2BF0BED53E86D621F253 -:106790001786EC76CCC5BC8DFCCAC0627CB2818504 -:1067A000B4EF23F749998813CA7D9E61062BC17BFC -:1067B000FF8E27CDA5752A3F38A71AE3EAAA675CA2 -:1067C00012AE870FD822611C2F7C1F1F2FC31669A2 -:1067D00077A2BDE41D6AE07A97E1E5FA8FAD2AA4BD -:1067E000F56FA32D7FE46D00C74AA524E935C47376 -:1067F0006A3EC5C7F13DDEB3B351AC5B6AAADFC0E8 -:10680000756AA358B75608FD2EDF27A705E7A21D16 -:10681000F1F355D3A63A27A11E0AB4F683F5E6DEB6 -:1068200055D356664FC2F5C697EF84F5E5DEA469E9 -:106830002B9D30998D4DBEFE466AAC3CECAFB05AF4 -:10684000939E98B632007AA7D9BDA40AED1CA83F42 -:10685000847EE2136952EFF0FA7CA9A7502F811EC3 -:10686000539B7ACA61D44BF93D7A671AE99DCD8F63 -:10687000A9545E0AE3A11D03F308E3FD60DDC33400 -:10688000F28F5C004B12945D23F269FF0CE6CD920F -:10689000D0FF1FC1EBE57E873ECC46FB1DD81EF125 -:1068A000E8CAE1EDF559FCBCB4EE7193DF26F74F71 -:1068B00054B17F9724F254146316F9C1CE35639610 -:1068C000A01FE51C6ADD9FD6E3F259D4F8FC1677C9 -:1068D00094ECAEB62411BFEEC7B2E9DE04F11E2C73 -:1068E000E531F8CCBCA9B984EED3F33003F3A9B3F6 -:1068F000435166B697E4D301EBA8CF24370E370B8C -:1069000024CAA75898CCED61F7798DFB890AD8374E -:10691000B88E7A841D2EEC23BBBCE7286EDD95F67D -:10692000925DDCA7B774C6942C3C97A4BA034EB40E -:1069300073F61963689F4665FE6B4B4CF64E737495 -:1069400006C5273523C0D0CE795DD839AAE1676660 -:106950003BA7A5111C7058AB361517D0FD358FB865 -:10696000A2CE2148DF076C7ED41B07C65485158C48 -:106970004F2E6324A79B8A33A7E03EC3062D98724F -:106980000BCACB5B309E8FD38DEF73AF50309EFE22 -:1069900085339882FAE09E5466F1A3AE4DE6FEC8B8 -:1069A0009624AE7FA49FD002F044010EEDFC48BABD -:1069B000CF67B4B04BF53965142FC334208C7F3AC0 -:1069C0005803E587CAFBEA1CD9364BFEA376BE887E -:1069D000E2895B92F83872DCBBC47D83B2EC640D53 -:1069E0003C6E0C3C9EC87FAB15703AC01EF2917D88 -:1069F00012B7FFDFDB3E227B45D2A7C74E51F8B965 -:106A0000D0BEECA3FAF3368B9E8D9D67D7492F9F9E -:106A100011F705C83C10B7D0672DD9A1B6ABF2620B -:106A2000F70368221F648DB81780656BDDE673F885 -:106A3000C9188F81FA669117921C77AEDFE55E4A1E -:106A4000FE826BB8663907E66421FACEE1B3BED7A1 -:106A5000B2E3EF0B08F7E48151DEA2C61E56E872DE -:106A6000006EEF0E107958A793DFA77823D8BB07E5 -:106A70009CB42FC1CF89CA78D837B58F5F47BB8AFE -:106A8000FCC2E9A3B1DF45B81E613C9B0573F8A6C3 -:106A9000633BA3BCA1247F17E3778E91BDA54A3D3C -:106AA000177EBE19FDA80CB37D67B2D72E5FFD7CA3 -:106AB000737321F91D545E74771BE9C1952E595EDD -:106AC0004D6558AFA2E8F7B09D0E1FF2137C1F4032 -:106AD000B961371490BDACE6834B0B7097E1FD872D -:106AE000B83FB0D3B111ED59F06BE7B94C71B2D3E7 -:106AF0009E63B9AC30617F614B7FB9DFAC3F18BF9B -:106B000003F38C647D99775D54E5DFF9F03B36B093 -:106B1000F3FD30F4FFC00B0EBA9744DEB31CCFAFC9 -:106B20005392B9FF8E7AC39CCFA9CFA90820734A8C -:106B3000F974642759F2BFA5BC6AE787937CCAEF52 -:106B40005E4FE2FBC79A16A0B89A76BE90E47F8BA0 -:106B5000A06B4BA3719171D2FA18670CF5D3F7387B -:106B6000C5424F30B13FA619E67B64FA92D7F8FDD3 -:106B7000C078FD269F52BFED15FDCF4DB6C697AB31 -:106B8000D6B51F4616FA892D54913C1EF3BEDEF38E -:106B9000E2525C638B16A1BCDDDEFB7D1D4EEE4731 -:106BA000224E50B0F5B6FDC8AE0DC9A1F54950AEA4 -:106BB0004A16FB00D9B0AEA9B86EF1BCA587B11ECC -:106BC000F31B42BE87A6A29E9A554EF1EBE7928335 -:106BD000BFC1EFEEBEAE98620512EED58D3CDF4E22 -:106BE000EA4B37E20BDA3BB4061EF77407A2685F84 -:106BF000DC97FCF6540DF950E372B06CF5FE951875 -:106C000017716A7EE22BA7DBE6C3F5DD09FE1DAE38 -:106C10007B4D6E1BC59356E03DC0F0BE599969A0EF -:106C2000BC2EF1E467B10BE847ED7CA6D0BFD67B64 -:106C300075FEFEE3A4D3F7BDEEEF3930298AFD6976 -:106C40007E46F93388840F4D7A55AEEBF1DFC5F7F8 -:106C50002FF129F1EBD04284571DED8604703D9948 -:106C60006CDDB7CD92FA33F59D8228BCAD55BABC28 -:106C7000689F805E7C12F9A46E54F7AF151FE9D3AC -:106C80004C6ECF84E57D0596FB91645C5E7573BBAD -:106C900046C2BFE4B5079CE67DA77878E3D74B777B -:106CA000A1353FC3393029EEBEE0263E8E1624BE04 -:106CB000B14F0E38514E9A8C3106DA2BCD9AEFB780 -:106CC00001CA2BB193DD0C76B8657CF9BC47DC0FAB -:106CD0007C54D851F1F51E719F72FCFBCF85FD707D -:106CE000CFBE9B480FF7453F3C508DF4F5E433038E -:106CF000CFE7D805BCDE8BF4DB171FDDBB8FC77574 -:106D0000B589CE08BA58F1E3A9F66000CF93A9A3DC -:106D100019D9BBEA203E3ED0D2C0B8B0775C1A1B6E -:106D20006E5A67EF1E7A1DBFDF39C3A0F37DAAC775 -:106D3000164C64674A3C1D4C96F75470BEC9967C4D -:106D400033ECF7740FBA896FBA13F1CDC164AEAFEB -:106D5000100E333DEF1E9A9F95883E31BDC8F9EA6B -:106D6000627CD121EE4BAC45DC807F5323CEDB9F90 -:106D700012F704CD4B16F70519DC2E96F75F7468F1 -:106D80008164B4ABE6F5EC5307E85C4A8D2B903296 -:106D900009F9F228B77B3F2EE1F7967D6C0FA4200E -:106DA0009E3F3EAA2A4DB4CFCFF302659ED5C7764B -:106DB000DFEA91503FFF176AA089AAADF6DC2916D9 -:106DC00018FBCF68DFEE5269FF28EFBEB9EA2868EA -:106DD0005F01861EF2D1BC527718D7DF8EDF37BC39 -:106DE0008F7A68FE630EDF7218E7E0BAB15F62F96E -:106DF000C41A8FCF4171B27C05EF155FBA36CFA0B0 -:106E0000FDA3654CD81943CB4B8732F614FE53C60D -:106E10009D9D74CFB8A80FB694C1FC466674D8DCAB -:106E20000053C41D6CC1734E2B9B82D9E8FF5DBB20 -:106E3000A6A005E38F999981CEAB411FAF5833BC13 -:106E40001CFDC18E47447FE1112DE8EFBD6C0BE5C1 -:106E50002950FFD49A29E594973B44F67F03D5CF78 -:106E60007BFCB22F8F1988D3CA728C9915CF91F001 -:106E7000D49697826E5F30599697E8584E4F669633 -:106E800038983DE64F529CADA3C77FBCA31CE3607E -:106E9000F3A734946AD07F9EE7A72D85201A13DAD2 -:106EA0004A8C005E99EBB9AF3C39036FCD0B54E3CC -:106EB0007A32D2737F39CE27BD9FB5FF7455C45344 -:106EC000D9BA16ECAF07BEF0D6168CAFCAF66FDE95 -:106ED000F34E4B78608CEFBF1BBB5FE93BEE0CBA07 -:106EE000B7EE3086D8729775EB3C9F57E4DF0CEC19 -:106EF0002AE27945A23CBC8BE75DCB72362F772C1A -:106F00004FBCCEFFDCCBE5AD232971FDCFDC5C5F50 -:106F100000DCA4E7538EB1C0B6047254E17653BBD3 -:106F20004360E739D362F274AD83B18998DFE4E45A -:106F300070CA7EE2BFBF538CC3C2D7A6211FCF1435 -:106F40007C3EC4AFF03CA55DC911FC3D06F0B2B477 -:106F5000EFC17CB68A78C45617FBE12C183A338906 -:106F600085F0DE9C8C7E502EA4EF03DBDDB1FEDECF -:106F7000E022CCA60E096EC6FEA666E58C5E9117D1 -:106F8000EB07E06E768EB1C0AD4D4CC3FA707F8CCE -:106F900093F4E0B390CF03F884F005C33C8DBF1F9A -:106FA000D0D139321FF5EF484CBA31E9F9E2CEEBD6 -:106FB000E83CCD52AFD81FF1F1EF334A79DE4BF701 -:106FC0008BC9FCFE4C676781793FEB21B7C833B8AA -:106FD0006BE643740EBAD3CEE8FCC2F6920BE61D04 -:106FE000D6605CCE6437D66851F2C76A302E371649 -:106FF000FB7B83CE1F623F3E117FC6B85AC68AC450 -:10700000F497EB60CD798385FBF5D697B1FED35924 -:1070100078ECC5E715EBCFEA37F6EE4F17717C81B8 -:10702000774DE05D4F0CE75EC9A7806F9B89BF1667 -:10703000087E93FB8167768ED868DE7F95E7864071 -:107040003F3F8DBF8F10EE4C227FA5580B5C83ED28 -:107050008B3BD3687F40F287E40B49D78EB4068A16 -:10706000B7743FACD039AE78B80E49B8D6F17BFBD7 -:10707000B2E68454F33DE3521EA0FF0ED1FFB8895F -:10708000243F8F727900B9B905E517EF61C179F82E -:10709000BB8ACCBF4720E12F425E1C4F74E4F87FCF -:1070A000C125F25738DE7AE3BFFF45E8994BF42C4F -:1070B000EEDC4FF3ACE9436EABBC5E9EC7762CEAC8 -:1070C000F541BB3182FF3BDA3FA47BC53A76A94C40 -:1070D000F1F179A3DE2AEED1C7E35F9D02FA38AB66 -:1070E000A70CFAD28774E8D19F51A733D6FE07DEEA -:1070F000F1D39A515F8A7B7BD355586DC6C4E0F8B3 -:10710000939BDB57134389E3580D5E8F458F3DBC3E -:107110006C0AFB10E67FA59BE75F4DEC0AD3EFEA14 -:1071200048B98ED753FD3C9C8E86E7FF929E725DD8 -:10713000444FB9A49EE2EF0FA1CD3B06D7D7AE22B4 -:1071400005ECE60A5B2013FDAF8F8EFE84CEA72CE4 -:1071500012F939A3303F07D7CD63415A573EC54A8C -:107160009EA733D09381F9DAD63C1DB6999F6B8DDB -:10717000E7AB181F8585FD26E010EBC1B58EAE6725 -:10718000793CC32ACFB20C70D6D98698EADD7CDD73 -:107190009274007A37D33DC7428E8FEFCCDA80FAF3 -:1071A000F64D0FCFB3491F12188DF3977209EBAA52 -:1071B000E013DB0FAF7373BD715D02FE9DECE17AEE -:1071C00076C13ACE371DFFBBF41AC47BC79B69A9B1 -:1071D000CB4D7AA24CC8B1EC57EA21F99DAC9F2265 -:1071E000FA9BE6E17251E6E67C877024CA272833D1 -:1071F000ADAFC43FAD9C7F60BE61337FBF29FA8DC8 -:10720000E153ACAB02CFB53AE017F0B7D51EEE8F25 -:10721000F949C59D36EAAF629787F2322BDA391EFB -:107220002BDAF6D9AA4DF889EF6FA987CBD1067171 -:107230000FED211BF01BE2DDCDE13BB33387F4E71B -:10724000220FB71B2EBE6E5C9A9ED920F23180BEF3 -:1072500094BF58FBD2800D563DCDFB4BEF175A81A2 -:10726000E7F0D21F627ECC29033C451580FB4B8F93 -:10727000D03B7A40C7F3B6DD0F33DA8F1F362730A5 -:10728000DA07E5FAA07B8C02FD15B4713D5C7C3F0A -:10729000D83128774EB92EBCB6CD3CDE9D1E8FE589 -:1072A0001C61C53A8EBF6160FF3C8D4FE8E759B263 -:1072B000E3393CC71F6CBF0AE34EF2FB5641FF8B1C -:1072C000C1578CF08D8BC187FD53FE8A3BB81CFBE8 -:1072D000ADFBCD8E01E67E1FE8E977DE1417EAF9F3 -:1072E000B5B0EE9074860EE0B98B8ADDA906DE9308 -:1072F00000F26C437F478E5BA1C9DFCBE92AC67BD6 -:10730000C20B7AC69174FDDD33E6F96FF2B8FFAEB9 -:10731000F4EDD043349FEEED00AF2F86978EF6B993 -:10732000CB5DB84E1C637E5C2724BCC3E674793108 -:107330005FA45EAC1F305F1BFA2FE9BFF0B1158868 -:10734000B7CE29744F423C5F4B3A0D675C7EA49FD9 -:10735000361C03FC50DEED2912FA87919F7BFCA5B9 -:107360003D4FF37B2D385DEAE7703A7679425F7ADC -:1073700032627208FA9CEE2FAEB8BF471FB5F3F722 -:107380009DB973009FBFF64839B7D2253DD8EEA20C -:107390004B66055F9F7E71546415A7338DDFD1EE78 -:1073A00089280A9EA36D68427F5BEA0984C79CAF67 -:1073B00024E1E9A123033A8E8ABD1F3687F7570FD0 -:1073C000F28E7C54A33628390AE9018AAF66A11EE1 -:1073D0008072563B6FC776F3FB1B249E6A6E844E09 -:1073E000C1EFFC574F21CD43E22B6B4ED45653884F -:1073F000F9CAFB077F64A2F311B15F8078B98EFCF4 -:107400000DAEAF6BD4E040F45B599683CEA1C23A87 -:1074100044FAE5908B692EE8EF5578E2BA3455BD11 -:107420008DCE094D1DA2901C830690F11EFA3DAE33 -:107430006BAF4EE6795B7FF9D1509C674632E743EC -:10744000E8C729FA71D23A28D6837FC905BB4E898D -:10745000E9E5438A42FD1CFA87CB37AE50627C894E -:10746000FDA1FD7448993590D6CB8E0C911CD46546 -:10747000C927EBBD9E75E562BDD95F44FF2EE66F5F -:107480002A774D039E9A30BD3D8A574E3785D56980 -:10749000FF08E34E057FD385FAD3CBF9FA505E5847 -:1074A000F5225CC314BA5FF97052A890DFD3CBC742 -:1074B000C914719B4C91AF8CF6023E235EAEFF4720 -:1074C000A6F0E78FC533D39B38CEB356D4D78B7B8A -:1074D000AD579524CE671BE8552CF1966BC5BE05BC -:1074E000DEFFEBE57EA7C8B3E5FB1C60DF137E4B38 -:1074F000EF9A43FB765F745E9FC2EF6FE0FAE04362 -:1075000025F0EB1B157C06E9FEBCF0DB2AE5BF7F0E -:107510006404BC98DF549B94380FBB44CCAF56CC6A -:10752000FFE3467EDFC27CDC4F03FD31D6CBE7B103 -:10753000A86D6C39D27BD11A85F6D3E4BEBDA46F99 -:10754000E57AD5124F9F8FFB69FDFE163FCADF8794 -:107550001F35CEE247C971E3FDA9E38DD996B8FF87 -:10756000BCB621E29E0BDE7E3EF313DCF35B0758D4 -:10757000F6FF586BC6A5DD030AFE5338217C3AE9B5 -:107580005BF9FE78A39385CD707C3294F21E067A67 -:107590004337217D637024B3B0190E3699FFEE9501 -:1075A0008BC75DC10EE7FE0B3C37B8C94EA77B6A9F -:1075B0007BE260A03F8C14D4472573BDE3637E83D8 -:1075C00094AF9AC989FD8771C2CF1DE7E6FE71CAE3 -:1075D00031E94F27F9502F4A7B3CFEBB861EBEB5D2 -:1075E000DA93178B3F00FF86CDFE517CBF2DA2DFC3 -:1075F0006FCE2FF97DF04BC17F89DF5D3C3944F1BF -:107600003DD6A6502ECA8432AB1FF48897AFE78FC1 -:107610007893E97B695757CCB1B67B0CDB8DC76794 -:10762000F225C573CCF6BB3204F51FEF4FFEEE4ECC -:10763000DEC93729FFF377E827427F6FA404B6201D -:107640007FAC11F9F21BFE7A207B3EDA43FF6CA778 -:10765000FDFA924797AEC07C6677BB62D0F9A35D16 -:107660005679F8CEB2F6C115808F7641A71A3F9FA2 -:10767000478D3FAA0F75637E351F7F60FB3E453304 -:10768000F1DBC04ADEEE25AFDD129FD98B65E867DE -:10769000B7D7907ECBBE19E9D83EA0A11DD01F7FE1 -:1076A000EF06E0E9DFC0C88EEE3F4EA1FEBF336EAD -:1076B0008382BFBF25E7D96A9B5568C077AD99C95A -:1076C0007E5C6F328DD0419C67CD7BD1282E8F138D -:1076D000DEEBD4D0BF1A6E040EA1DCC979F954A335 -:1076E0003FDAEDC9EF71F8DA7AE24A7CBD616CB538 -:1076F000B04337727B4C654718B7C7695DCF5C3EB6 -:107700009CD63D399FCC34B16E64B210E61F43FB6A -:1077100056B2539C7CDDCF5CCE7F2F4FD233E667D1 -:107720008E18837EE69035516D1E7CF7D27A5BC24F -:10773000FB353E14788779BC6F9EC7C5F4956C679E -:10774000EF23CE28F93D797A62FF9DB17BA9BEE493 -:10775000D1F49B492E9B75BA0F51E27FB811FC1CE6 -:10776000E1E9DFBE4141DC1C177905C7573DADA0FB -:107770001DF9A3C5CC5013F0538FBC2EDB31B8C21A -:10778000A437A17FA2C786B83C71196F71A570FF9D -:10779000E71623C852C653DE2EF9CF8B37F3DFDD51 -:1077A000E8131F97882FA592DBE535B3F9EF8E9686 -:1077B0003CAA11BDAB9BF9EF0ED66CDB4EE7ECD8C3 -:1077C0004F991FE5BDA67DBB5201E3566FDBAE2C82 -:1077D00030E16F404D84F2AB2FF3C87D8728D9CDBF -:1077E000F17C8DF102B4530EBBB8BC9F2A71877136 -:1077F0001FE2943D5483ED4EE524FB719F52E2FB62 -:10780000D5EDD3E8BE03CF0E47149FADB68DD94E4C -:1078100068D73A52F7231F0D3742C3102F695AB069 -:1078200003BF4F4DF7F8711FC3E7606368BDBE44E7 -:107830003C4C88E387093FE57272638A57C805A309 -:10784000BCA7AB533CD27E22FD74D8CEE7B1837186 -:107850007823DEC0B814E4C323FC7713FAD74415A9 -:10786000CC17891F37C64F812B11FE4B87B35D475D -:10787000BD5E2DF44CC9A39B950F4D70CF40A30A5C -:10788000F973DB0605E364504F7A06DA33CC4BEA32 -:10789000BF8DFBA5D550BFC0A457E43C12E897208C -:1078A000C2E77EAFF320D72F51BE2F20E08DA7E790 -:1078B0009C141F8D5F0EE601BDD7C3C3D12F3E9C24 -:1078C0009F44FD49798F97CF3982CFFBAFDFACD88A -:1078D000DCB47F4276A4844FB67B23654A08E199E5 -:1078E00030BD93F050BB5EA3F94CD583436F33C9D1 -:1078F000435D0AB7E3F6DFF83EDDFF73FFAF8E129C -:107900003FD6823F4DFE44DB51FD7A5C57C24FAA01 -:10791000B8DF750D3749D883E25EAC6B3AB8FEAD7F -:10792000EDD8AEE13D92924FF34EEEA7FBB46ADB89 -:107930001D0CFD28E0BFA548EF783EBD547A821E9D -:10794000E27E525817F1BC501EFA39523F47843D2F -:10795000CADCFCFDBD024F31FE09B5A458F4AB8B67 -:10796000E422EFE498FD989759EB57E8BCA48427EC -:10797000BD34B17D2EF5A2D4D718370C9AF4FA5A3B -:10798000A4EB782A47B93FCAF2715D9670C6D3E975 -:10799000E514AEBF13F0D3232909D62BB97EE73DFA -:1079A000B643C37B91249F5C83F435F1C99329FCD2 -:1079B0007EDD275334EAFFC112BEBFF8A09DAF534E -:1079C0000F3639295FF2D59B78FE96E7663D8ACF60 -:1079D00043B67935587FA83F87A3D5B69CCED781CB -:1079E000FC3D95427CE2655C0F72BD77FFF35C6FF6 -:1079F000D584DDE4CFD684BE5F4179ADE92E3FDD8D -:107A0000F7193AA85FEF89E1359E8F7C3BF6D1EFFD -:107A10001D5FD3CEE50DF426F1510C7F1CCF524EE5 -:107A2000A43C44E4FE0DF001B77BB8BF5428CE3B24 -:107A3000563AFD745EB252C4550BC5B9C7E2630134 -:107A40005A0FE6093A14D982AFE2BC2AD6C4C5550A -:107A50002FD1EEAF5EF6FA08FC5DB0AAEC23F494E9 -:107A6000F2087EA9456EDF11FEDF1E41EF3F08F9E7 -:107A7000AF1ED74EF256FD5103C9A97B3AD757EE38 -:107A8000F7AC7A96B17BC47CD7D0775393DBCB71BC -:107A90005F78EAE30ADDABD9179C8BF01C18FA6F0C -:107AA000EB0F78E7A23C8BDF8792E765CE08393988 -:107AB000B55515BF97D9A05FC8AEBE587F2CFA96B2 -:107AC00042F795089FEFD4B6D2497F44BF736B0A43 -:107AD000FD7EC967DBBEF7E33FA6E3EF835CEDC73E -:107AE000F53F7D4590F8A53BC3E5DFC8E3ACD33156 -:107AF0000ED5D47EC08BE76B3E7DFA8A31A88FF11C -:107B0000DE2D9CFFC9E7D5658897E54F3CF72DAC86 -:107B1000AF8E28FDD02E3DB5F5F1FFC0DF81AADC88 -:107B20005C4FBFF3BCE2E957C8BEFF3F75A9C786EB -:107B300000800000000000001F8B08000000000013 -:107B4000000BD57D0B7854459A689D3EFD24DDA140 -:107B50003BE93CC9A393404025A1131208F2EA2453 -:107B600084872076408620AFE61D20241198591C7A -:107B7000DD9B8620221767E2EA28F8DA0E838A3333 -:107B8000CE18306A90A0CD43C4195D5B040767919D -:107B90006DD4419090F446671677B8C3ADFFAFAA95 -:107BA000749F930EA83BCE776FFCFC8A3A754E3DCE -:107BB000FE77FDFF5FD51A5FF3DF52ED8454EFE9E6 -:107BC0006F3510422EFEF2E1716428218D2D8DFA61 -:107BD000A099902F7FD98CF5C3CFBFF4C67FD3F780 -:107BE0006ADCB14E78EFCB970FE9E1798D47EB6A0C -:107BF000A125F11CD5CFB2D0D2FB824C1209994AF3 -:107C0000D8DF637B0FE91D79B4DE221142BF27550F -:107C10007ADFA02CFA5DCB5EED1233BCE123A49891 -:107C20008EFBFCC2511EA8B7251092127EBE554F86 -:107C3000BCC6385AF623C444CB4BA566AFD49F903C -:107C4000D565E6AD505EFA8DA9CA47BFABD50773BF -:107C50006D309FA1C405F578AB86900418E76E5D82 -:107C6000AD19BFC77E3ED21102651EF192F34308E3 -:107C7000A16FEDBE361CC6FB2DBE4FDF2B3115129A -:107C8000327BDE3909E61333B45EB71AE7F96BD6F7 -:107C90004E571DD93E623D1D8F8E7B0DFEC687CB94 -:107CA0003CAB19DFA700C132B5B532CD01EBB71B34 -:107CB0009CB07EB1BED46A4FA3853EBF6DBDC729BF -:107CC0003B0879FDC289890368FDF921D270195EEC -:107CD00097A5856EDA7FADD78CE3ACD950463EA32D -:107CE000F31D6F95F0FB442BB1DF4AD753A12576E6 -:107CF0003394849CD41542FFCF62BBC3405CA488FC -:107D0000966FCE7E7623FDE4319D27A518FAD91A09 -:107D1000D03BA0DCCDE64FBFB79A0BB13FEBADF047 -:107D2000BD91AC85EFBA364EB36F93B0DF802E2E87 -:107D30003C6F424219B3F2587F4500A7C9DE2A784A -:107D40009F38F4B8BE2FE115C4A3377F7E1E940F71 -:107D5000B1F96A8807E825514F4B84AB27AB92D223 -:107D6000CD7C6B6995B5385C26F663ED6AB83E0547 -:107D7000ED149E67AC2E2CC99E784246F57E4F943A -:107D800002FE876777EA8374DC470F9C43BAAD0530 -:107D9000BA85F13D9FEB611D826E9708BADD7F0EBB -:107DA000E976499B84F454DB56A0077ABDD4E022DF -:107DB0009F69699DD3DF63527039D0B577BFC9FA27 -:107DC0002C8553A7A0CFEDE7CECB141ED96D290E7D -:107DD000099EEF6774FA9646E30538BDB5EB96E663 -:107DE0004629729E1B113E5235413EA9AD273E03E6 -:107DF0006D2F7D7AFD8929B4BEA69A380D943E6A0E -:107E0000557494F5CCA75B805E6C35A4C8E480758E -:107E10009E9D3880F65F5B438A814F5327B8F643B7 -:107E20009DB4496410D4ABDD4B61FCDBEC2B9D327F -:107E3000EDDF36C1DD0AE3DD661FEB94697F8FA5B8 -:107E4000B76C31D2766F05B13EEB00FC36956969AF -:107E5000FDB10A87954292C26D7732B493217AE7D9 -:107E6000B340C79EA535D05F6DF25C27D0492FFE89 -:107E7000DFBF7108CCB7D6D1CF69A2EF4F6D939019 -:107E8000AE88D74C60FEB514BE509FEA1BED83F957 -:107E90005CE6F01370ECD40516C0FC3A5F31102F8D -:107EA0006D9F3A81D1AB6D420BCA8FB7F74F3A2E17 -:107EB000E587E9D2F2AAC10FF538AD5572825C228E -:107EC000330D91786DD291856EFA9D6D32EB2767F7 -:107ED0003BC3EF739C9F9E03B981A59EF36F13A3D1 -:107EE00077AB37DF4DE9E132C73FFC3968BFABF113 -:107EF0001F143F4BFDC84F352FB2FEEC0657C1BAD9 -:107F000008FAB59713E4E33D26B2B0923EDF63630F -:107F1000A59A5EDFE5F3C87A662DE27D09C53BE0F0 -:107F200035753B7D0E70A3740170A378443AB8CDCB -:107F3000BE02F1B664BB7417E2D13B82403D219E84 -:107F4000AD53DD7F80CBC53D26779144FB0B255893 -:107F50009CBB24988F4B63827A81CDB98BC0F7EE9E -:107F6000DD305E4292C9D91821AF08711769E8382F -:107F700017122D0CDFBEF7B533F2801F1DD86F82AC -:107F80004CFC04E50FC976E785BFABC861FD55F031 -:107F9000FEA63579F349368307C285C3C3B7B15FFF -:107FA00055A43CFD08E041FBF5DD44AA406EBCA5AC -:107FB000276623F46FA5E3D0FE12778DFEE5369C8D -:107FC0005F23BEF7A6D58A6545BCBBA81E44708E4C -:107FD0007B3DC045AC530D8FF91C1E87672F28D001 -:107FE000001DDF697602DF3D7A405A8C74ED355210 -:107FF000A604BA677C48283E802F88478BF8A8AD36 -:1080000077FBA2D37D25F259ADDDE4344948F72E44 -:10801000D47F5EB38FD13DD37F319399BE0239595E -:1080200099D75B1E083903FA0DE859F045EDB860A1 -:108030002EE0F7DBCA954E1DE3F34E0A07E023C19D -:108040003796D719BF6CDBE82885F66D94EF23F1DE -:108050007D4CEF45FE3D96DDCF09FDC23CDD96B07F -:108060007C4FB4BAFBD9609E1AFF166D56581ED7C6 -:10807000BEFE60AE270AFD09796CD4323967F4C5BB -:10808000F858BF6C3C2305B7A5104B2FE8A3980DFB -:108090000C3EEA7ED26D664E8F46EBE7548F4FA7BB -:1080A00048EA9F43C8648D27DD46FB5F630C1EA32F -:1080B0009825191B427A984722E82EE09F5D313EB1 -:1080C000905B8989C4B32F4ABFFD6D8CDE045E9A34 -:1080D000E2181F25C6B2F747D918BD0CB5313E2DA1 -:1080E000E3EF8BF90BFA77683CE788DCB71E13DF08 -:1080F000D17961BB980FFD7E2B61FA17E79BB829F8 -:1081000077D7B6087C84F9E8A642C053CE76BF760E -:10811000B1393C8ED0A76AFCC3FC817F603D95439A -:10812000FB7EAFE910E347353D4EE17C62B0112C98 -:108130009B74FE3F235FDD6D21BB607E3B882B9EE1 -:10814000CEABEE8DC18C1F5CA15CE8FF609C6737F5 -:10815000E063E4044EE7F4F90CFA7CB596780D146C -:1081600027ABF7E87C4123E3996BF4FF62C0139DD2 -:108170004797C5E895299DBF1FE7A982EFBD65C454 -:10818000E907BDF4532A3F80FF88BF18E44B1D095F -:10819000C6029C6BE5402EA1F8BF1AE3990FF4F8D4 -:1081A000A9269001CF090922BD9E31C5E613DA5FE9 -:1081B000ABDE9FFE4F30EF7764B28BF6D34D5C534E -:1081C000611DDD014D9C97AEE393B60F7F73807EFA -:1081D00035FFC0E5F9F70294B6C52C789296F38C7A -:1081E0001AA37678181E672CD1E5EB8F395D2434FD -:1081F00032BB2BB4D1E003F8A8DF1B1FC7F05F77B9 -:10820000259578E3239F33395AA70DE9C184ACBB88 -:108210009241BC74DC4F34A4BA258A9DF9A18DE942 -:10822000AB564AFAD1DA4F733ADBA323B93B603E2F -:10823000CD540E02FCB40E9417D58F6439B7D16AB1 -:108240006B76E818D811A15F4828FFCFE898DCA129 -:108250007F771A4784F5279827601F565BBD7E0DF0 -:10826000951BD5EB2D7E391F9F6BC700EEBC562D9D -:10827000C8C1C55C2F2EA97FFB1B2996B66B8971DF -:108280000CFDEE0BF3D258500BCB7FBC2E118CEFB4 -:10829000A4794DC89F844CB0823D2EB9A6C9D7623F -:1082A000AE67CF69D16E477AA1F82D8F733F09F879 -:1082B0009ED79FC17BDEBA189F3742FEDDC1E1A386 -:1082C000A6B33D40A374BE6725A657D4E3BC1057A0 -:1082D0003609FAFDABC5FD1CF6BFEE32CAB379070D -:1082E0004C19A0B7565FD1205EBA0A02B91BB28002 -:1082F0009E43197FA0F05BDD6EB07A1DD0AE57E0D3 -:10830000F5D3062AD072C3F5C517064E246680AB96 -:10831000730BE079C9D618E21D129E1F18D240B720 -:10832000B55708F6B3B8FDEDD320A76BB541A48BC4 -:10833000C54633C2BDF68A16E741B6EA3A82E27B09 -:108340003ABFF858573BCCDBFBC018DBF95BE8C3FE -:1083500024FA1CD7E5390CFCF4784C2C71313EF032 -:108360000DA6F3EF363AFAC75138D4E929DE876112 -:10837000376E6384DD44D22C4ABCB6BFF30DCC67A4 -:10838000A9D1A307782CABAAD703BFCDEBEF2FB6AB -:108390000E8DC4E718F9DA2DDF1E9FCF73F9F2892D -:1083A0009ED27B14FE3ACDE5EF782E273E49657CC0 -:1083B000F14906A9DE07E5CDB4A4DF7D92CDEB85BA -:1083C000ACAEEEE72AE78B4FF2991EF2AE657A412A -:1083D000FD5E271FAF3CCE751EE0269E0F8F63CF3C -:1083E0005F88735D043853397799D3A1DF46FB9BCF -:1083F000F7A601E9906C0EE5021E7BD695CBE79BB4 -:10840000187D5EB670BF5F437FF43D17DAE36F9867 -:108410007CB0BF20D3A8DC0539BB369D809CA5E38A -:108420005EC5F772E9B8F89E01D741B652F94B190B -:10843000ADABD88178D9564AE913F8FFA0C10AFC40 -:108440002FE849D0919A7E4C7142AF31FD7A07E80E -:108450005719F5AB298EE9573DF02FED51CFECBC04 -:1084600081886FA433F9DBE3FBA09170F8BAE3E3F2 -:10847000509FFBF3DC79BDE12CE4DF27FD9474E130 -:10848000E3781CC0DFEB81731C7BCF9EC3F499B0F3 -:10849000FB6FE1EBDACDE5B428857E1A3959696FB7 -:1084A000ECE6F263B72D164B8A97C1B07EA1D77A5E -:1084B000E1FB29866FFADE5058CF3C4368413CD53A -:1084C0004B3FA2F68EBE10BF7B1EBEEBE57F98C071 -:1084D000F469DD5A0B017D3F228ED9B1A4289401A5 -:1084E000FD9121B4CC03FEA3F246BA31FE60AF9FEA -:1084F0004279E4F65807DB57CA7440E09921C40179 -:10850000FD517897C62584E1AD1EEF0C3451FB6E0A -:108510006A9CA43D0F382A200580AF051F7C659911 -:108520004FBBBC6C357A35543FFC58E3B903FAE9CC -:10853000B8E71DB4E7CFE8FDB94DE628ED7AFF3383 -:108540008F4BE1F6852FC85E3D9533AD818E5FCCB4 -:10855000A674B938203B61C8C5F7FDF9BD91602705 -:1085600007744ED8AF523B61BB96CEFB8C86E1932D -:10857000D42BF7FBAB38DEA9BDA42523C2F249E812 -:10858000FB95C43F08EC8225C4A587F2D3BB574CAA -:1085900023145ECBCCEB516E5D5C3B05EDE0E5C496 -:1085A0008BED4BB6EA3E8DD413CB9A94F5153B94E4 -:1085B000F5953E65FDD24F18BDF5A67B665F259407 -:1085C00047B71B1EE17479491FBDBD318ED169F9D2 -:1085D00003D31E47FE0FE88881D2C9FA83A5492438 -:1085E000CAFBA2ACBB924D7C117A286C57E412DF17 -:1085F00070E8EF2AFAF9A01FD8BFAE37B992609F92 -:1086000071A92CFA3CFE778FDDD2AF8F7E63B1DF8C -:108610004BD9D75F67DD1523BED7FB7B33F64BED18 -:10862000A7A8DFEFE670B81417BDDDD7D37F32EA15 -:10863000C5F0778C0FC2E3A4A15EADBB6255E8E93B -:1086400070BB9DE955BEFFA778F5A2BDCBED39AA59 -:1086500010ADE763C2724CD78FCD47F0CD671231B2 -:10866000A6A0BFEC612E479DF960F77E067615F057 -:10867000ED24C71B413AD525F78ECAD56687F94A3E -:10868000BD1E4A8F5F0623EC82B6388B1DF5B99369 -:1086900038615CC10F0BEEA9E8EFA178FB8FFBCA34 -:1086A000933C4323E9CE8BE3D7EA853D6756E871D7 -:1086B000A2D2F34BDADE417B6DA9D19D0BC2E94F0B -:1086C00007EF413E594EDC89C01F5D07076778FE02 -:1086D00007FA5DCC67A677918ED9E714A8946F67E7 -:1086E000F0F9CC6C67F6A2C6E8D2E1382EE2B026EB -:1086F000E2169CCD970A592DAD8FED993F3813099D -:1087000019C3E72FC1F714BE637949167B9261DE66 -:108710000618978E6722BE64281B47391D508E9716 -:10872000DC5A360F1FE27922A94F83F735C6A0CC59 -:10873000D649679008DFF7C00BEB165EDF7C67F762 -:108740008265F0DC6C41F9A3E7F3F846C84D2331AC -:10875000C2BA0D66FF4558978597DE32667F7BB3B8 -:1087600089B391BED68FB41018D76CBEEC85C55AAC -:10877000895582BAC9DAED877DC865ABD9AB198650 -:10878000F2F4FFA03C95DE5D0E78A1F29BF9A5FA0C -:108790006AD7FA71FF23E4631C9F5F23978F2984B4 -:1087A000C1C14EDC875C94AEFFC5B27C1A89053529 -:1087B000EEC1F177C64E3E0EF305C0A39E9FACFD01 -:1087C0003452CF24B8B50AF99754A5ACA77894755C -:1087D00023396305FA95FCEEE46BF1B8AF1B027E1A -:1087E0001A1D973777F663F312F49316AF51D82119 -:1087F0006EBECFAF8DD313F40F261A8D6418DA2511 -:1088000069F1CC2E394B314DF7832194E705E35DB7 -:10881000837E41E1BCE503D9B989E2698BC5B151D9 -:108820000BF6DE1CC9F92C92678B1FFC3ECD0B6C3E -:10883000CE6DD06E72FDFCFF40FB0732017BAB0EAC -:10884000FCEDF1F0A2B514BE6BCEB0E27BF6F210F7 -:10885000FA49430F12B4A77AD1E9553A7F0AEF5F7C -:10886000429DC2B76EA975F58BF4FD14778C538ABF -:1088700068DF0DED749E12A70B783E7E04EC6BD979 -:108880005F4E7B41C0057E0B978CFAB0AEBDE08891 -:1088900099CE23C753E004B21DD8CEE32A76838F46 -:1088A000C51528D7D279CC32B279D4B597DE514CE0 -:1088B000DB07068613882FC41C77CCAD81260DDD1F -:1088C0004FC3776531E8CF3AC9FD4A84CB83912AFB -:1088D0007E1B1DA67F6C2F10756A36B84630770553 -:1088E000D6ED8C0F9C44FC31FEBC9584FFE0FBF27E -:1088F000707F288F26849BC3FC469756687436D6B3 -:10890000D0F7DEAA9C84745807FB2E8A8F915AFFF9 -:1089100021E0EFD1BC2CE02559DC84F0DCB6D17F1E -:108920005897052E14B70CF511D6071BA1BFB192AD -:108930001FCB8CAA871B81AC5E03E30CED4E4F0569 -:10894000F0E3960A6205FBABB1C4E9B4D2A6D955EF -:10895000CCEF3AABCAE8033FFE2C2D61F12EAD27D8 -:10896000EB4794AF7E348FF97BA13E2FC29F22E26A -:108970001B27E93E666F147BE0B578A6C7C4F77580 -:108980009BF58A38D2CBF1CCBFB5337EE24FE2D92A -:10899000FCB280FFEE8BE77265081902722582EF48 -:1089A000BDF05E47E9EFFB920BCA762E1766B91E43 -:1089B000D1A11DCFE58390C36EE043FA5D4072E91B -:1089C000007E1F9731F89F285D89F26136F1E073D0 -:1089D0004A203A77A41F6972843D44C799E556DA64 -:1089E00047B3AB947541AF62DC391E65FB0C61DFA8 -:1089F0004E56DAB7F3FEE9AA0DF56FD2736BAE658A -:108A000062DC04F7FF75144F2C6EA2657194CD7A69 -:108A10001FD849756D77BF95007C741FE17CB457F2 -:108A20005A3A14FDB0D2B2083B62408D4F02B93FB2 -:108A300098AE2980780D61BCE8A4CE7708E228279B -:108A400057D215D3791ED1B378E45113F1823F5A2E -:108A5000D0A76506F3A75232C6B8489A35C609F4BE -:108A6000B4555388FED7ADB11667A4BF73DB464A31 -:108A700077117E578781145A39DD44DBFFBEC9E583 -:108A8000E16312F37F7BE71871BF9790E356C41B35 -:108A90001264721AFC883F897788F7D1CF01F1BA46 -:108AA000E1B4F449CC9EE9F95E269BD1EFA8923F50 -:108AB00009F14EF4F727F4CF43BF7D557BC16E9487 -:108AC000376693739014EEBFCAD3AC5D06FE83F68F -:108AD00066ED527398EE4E00BD02DE62480CD06B1C -:108AE0008F1F6F9F01FD783FD6B83F02BAACD1FB14 -:108AF000F389929EF1795F7A6C05A7175D997BCE19 -:108B0000323A9FAEF7F4CCAF751F417E7D79BF0D31 -:108B1000FD90DA1904F5C9E65282F4D0D52CA1FDF6 -:108B2000F685AD1AF7019BA526D4139D7113117F0D -:108B3000ABCC47715F5BFD94EED348BB6BD56E65E4 -:108B40007D3509E0BEBAE6C55EF48CF24BC8C7DAE3 -:108B500056E57764A0523E1670B95FE876CEAC80D9 -:108B6000A9573973D8BE9AF80D741DC5EFEAB9FF3D -:108B7000771ED39BE43909ECAD2ECB0599F13993DF -:108B8000C7C5BC3FB51E2AE6F6D4382AB760FF2910 -:108B9000EC23FA3ED68F6ADAE5644D785E45FC3BFD -:108BA000619709B92DF0525A424809A5FB643B97D9 -:108BB00043D9241BF04AFB477EA0E37AF571D8BF66 -:108BC00017F66DA3F97814EF5ED0B35E8DD10774FC -:108BD000B445AA47396D245C5E4B1E94CBAF79BD7A -:108BE00032C07514A99F398DBE37C61888017850D8 -:108BF0007A48B32784E9A491F833F64A0A7AC1F691 -:108C00000EDBEFA3D28BD02FFE8F997D3195AE185E -:108C1000FAA980400E2D8F4A6C5F38C9FCA816BE99 -:108C2000FFBD660AD2C364E2D3C2FC2AAC4A3C4F01 -:108C30004A56D6A7387AD1810CE3BA383CA70E51F0 -:108C4000B6BB845C234AB99645AE229EC983C77ED3 -:108C50000C7E81980D6408D81DD442447E53CB838A -:108C60007176B3C23E8A88838CB317F78E83747192 -:108C7000BFEEAD24B8FC45A937BD74BEB5414E8EDC -:108C8000A02B41C7AFF3BC09E94D1E6F2D62FEC09A -:108C9000B09E67F43282D76E057AA3EF2F147492D8 -:108CA0004932814EC6B699FC32856B01EFE756A07A -:108CB0009BC2B03EF76BCC0E7D36D08773AB2CF7E2 -:108CC000B6DB13E31C4827C3352EA49362E28C075E -:108CD000FC94185B1AB530FFFD230778CC0ABA580C -:108CE00062473942E902F9AA975E54B6ABE846E01A -:108CF000EF38B7972711EF40188F8AB1A3602FFB89 -:108D0000B318DD541017D2C9DBD953783CDAA3C5A8 -:108D10007E88521F961B9574A0A62B3AA226725CE1 -:108D2000359DF54537994037421FC6DF986EEEEF07 -:108D30009B6EEEBF1EDDA8E945C893BD266B39D8F2 -:108D4000A575D512CAE1E1EF0D6C84FAE0355998AA -:108D5000D7B2D7E644BBB5AE9EB517055C32E4BDCD -:108D6000E4ACE7ED59EE72A8D76D60F187E2932C81 -:108D70002F66E07DACBD6053FD110BE8772FFBFE45 -:108D8000F58B5BE458DAEEDBC2BF2F6D2A877ADD04 -:108D900056F6FD17103FA2F81D71DAD708CF6FDA2B -:108DA0009EE564DB4F66CF8EE774BA57DA7704BF6F -:108DB0006B62DFAD3866EC47D00E6676EB38BECE20 -:108DC000F14FB175DA3FBB6DB283D2EFB29017EDC0 -:108DD000A6F39A9A11286FFAD867964A4D695052AD -:108DE000BA4139E33252BACE66F1C55D7488437632 -:108DF00066078AB81CE40944E6051CB233FFA37871 -:108E00002F318EB038F21316F4078BB8A1FF712200 -:108E1000019FC11AB9FE8F1A479C94538FF1C34921 -:108E200099227E18D42EA6E3165CFB6A62347FCAB0 -:108E3000713EEE059EF7209E57FBB23440177B81B2 -:108E400048520148AB7F0776D35EF0BF32A5E125DB -:108E500025805756FFC8BE62DBD6340A5F4DBDD6AB -:108E60000B4A2683EEBF68D7D303C4DF3FB6F7FCB7 -:108E70002769891FF413D1B2F92F6FA47A500ACB56 -:108E8000A55942EC8C19847C7A27C7D367766E6F1C -:108E90000C27C341DECCE278FB91B15EC7F4659349 -:108EA0004EC5FF5F20FFEFECD36E56B6ABE4433503 -:108EB0001F7739B797579210DA05E7251F9617766F -:108EC000327B79B5F924DA155D4F303BB18604D198 -:108ED000EE50FB0F57EF51D6D7B428EB756DCA7A19 -:108EE000579E17C7E9DAB96604F8EFAA77BC877E00 -:108EF000E16A21277C4A39410D2426271EBF19FD2E -:108F0000361A2395134500AE7E9847329CB8E2414D -:108F10001E8092BD46EB0FC22729B4AE711B1350C1 -:108F20005E4C8EFF5C8C2F639CF63D97238C979E46 -:108F30007DA14A4E14087FCCC038F45709B951C0FE -:108F4000ED123259BD6F7C14F96F38AFE52428F764 -:108F50003DC2CEA0DFA39D11D0987D1A4DA45DE146 -:108F6000437E2C34523D812CE434B2FD4A1351E14E -:108F70007730ACEB3AFB2665BB0AFF62DF3282E357 -:108F80007F0EF10C007CDC49DC6F817E38F171B51D -:108F900062BFF4F11F270A7F0AEE9BBEFB7EC9FF6A -:108FA000BDF64B3D783751FB9196E533A60CFA059B -:108FB000C4BD5B4D98CF5927313C27CE399911E973 -:108FC0003F3CD14012B4117CDF38C56084F860A307 -:108FD0008EED27664CFD64C4E208B9F192B1746A63 -:108FE0004231E021F0937F87FDC53B32C17C99F689 -:108FF00004C47B77137D4EE9ADFBA95B9C5EFAF858 -:10900000928EC51BBF90EA97438A9398C7F20DBF13 -:109010003369A91E5B21FBDE08427C55F2BD5A4331 -:10902000DB4EE93D73A0FFD51ABF9EF9ED0218276C -:1090300015FDF7ED87F4A2BED31F667A3124F573D0 -:10904000323FAE373732DE5495C8F657EFC7B9977F -:1090500001DE85DE13F18433774FEA0FAAE16BE27C -:10906000EA0F714E490BB1A7DEE341BEC0E608BF6F -:10907000F21953F4B8C0DA04265FF7016FD1FFED9F -:1090800036D73A18F702DFFF5DE0F1AE0BB12CFEE8 -:10909000F5BF7ADE67E5A309CCDF7D81C7C72EC4A3 -:1090A00029F78DE2BDC778F97983D1B839029F8E4F -:1090B000C70DF53ECC93E27921EB09DB27EDB735FF -:1090C0006F8B8887362794EE837925E4B8F42900DE -:1090D000BFFD4C0F433C1AE2C64556CF76C04BADA0 -:1090E00083B820EE4A1C41FD4C883FC2BE13ED07F9 -:1090F000462F5D26568A79352754EE83EFBAEE0E59 -:10910000223E7BEA954C3E3627B871DCAE59A29DD3 -:10911000D71F0A72FC33FF81F067F7150F53C7BFE3 -:10912000A8E26076B689C93175DC7BBE90633CEEFF -:109130003D8FCBA1F9EDCC3FBEC048B60CA0ED0BE6 -:10914000DB93D87E31D69BAB887B7B63BE531E837B -:10915000A0CFAEF4404FBCF6898878ED1A1EEF5BC5 -:1091600023D6D7AA5CDF9B097DC66BDF4C8812AF84 -:1091700055E705BC0AFA7D60189E6BAD6CFD157253 -:109180004DB91EE4C45282F9E16BDF59D268A4F5EF -:10919000B50F82E70FFE98BDBA86C3ABAFF925B80D -:1091A00035C4A1F013F7238E887D718A274E51476D -:1091B0000B3822BF724075AAE2FBF4FA6CC5FB992A -:1091C0001B6E56B467790B15F59CADB72ADE1FD41C -:1091D00054A6A80FDE719BE2FD0292D31FE3B1C734 -:1091E00065F095909B7C3314EDB7ECB94BF1FD170E -:1091F000A4FEB131F4BD5613D303C4EB0A0CA57021 -:1092000059CAE79FD7B258F17DA3D432C24FDF5F6E -:109210001A60FEF6616DAB14FD5D8A9DC8F6113CC7 -:10922000FE584FFF6372DC21A33DD4269127A4DEB4 -:10923000F1C8EAF687B70C20BDED0AFA877A7E15E9 -:10924000D5F36047A9ED0C39D16247FD904A52AF82 -:1092500045F055980ECC6887753F25A33FAD800C2F -:109260007E7C0CC247477C8EDEF8EA26CCCFD3FD4D -:10927000A2C509FEB215EF2C41FA33242BE9C0E454 -:1092800050D241CC10251D589C4ABCF72F51E25DAD -:109290000D679B4B4907028E02CEF193957421E036 -:1092A0005B42FF03F81692D031CC9FF6494E3F89BE -:1092B00012EF6D6BC675DCC86ECB53C173F8515796 -:1092C000A319E1C4F2A9849D64E0FE69B5DF5CD80E -:1092D0001F6313B9DDC3FB117EEE2D9217ED9C9E2B -:1092E0007856893FC39F05F64E3D61FE127769624D -:1092F0004254BF1A3EEFCBAF26E028EC99D560CFA1 -:10930000D07196110FCAA5CFB93DB3C2FC28C605CE -:109310002FFD91C1B79AF8505E7FD77839D889244C -:10932000C2DFA886A3D42EF92DC0075C6EA7927663 -:1093300021B73D983741C9CE3842115F50DAA1C4F8 -:109340002545CA2761978AF1043C85DC12E3194858 -:10935000BD9C0C7CA092636488DA4E55FA3D849FD4 -:1093600004078B88638CEC894FB07D62D8EFC5FC15 -:109370001C7266562301FBDB2AFC1A81B9F05CF8EB -:1093800035D4FBFB1BC545677AA5E09359BDE3A126 -:1093900022BE4A97F9D9BFD38FC7488E74186FC6BB -:1093A000EB831388269A5FCE79FA00ED47D684E2E4 -:1093B00023FD65C27FFDB614C479FF88B8EE27117E -:1093C000F6422D699938370BFC9F546FC542C9FC92 -:1093D0003EA44D6D97B278A286AE04E87B358988AD -:1093E000176685DBB12EF7AE8B3C971BE97747926A -:1093F000559C5BC965ED4CBE89FD5B5FFB2511CFBC -:109400007F4B4F615218CE6B793191EF33F3493E68 -:10941000F44FF9AA2511F7E7940FA548BEEBC983CD -:10942000C1F65E7CA75ABF88E7CB9622F4BB2C8995 -:109430005CEFB78087B023BEA26B83725BA203CBC5 -:1094400035FDCE7CE482E6A24046A4BD5BA76779E9 -:10945000C1A445693F9F4CD47078B9E46F03A7BE9F -:10946000F1C0F3C2381EBEAD3D24F2C204FCFE289A -:10947000E46018DE671572AC67DFD603EFB3D1E4A2 -:109480009C80C7E5E2C0738027D9723211E0FC5797 -:109490008BFB33C04FFAE9E0794903FAAEE3B92711 -:1094A000417FB5C9B83FAA1DCBF2836AF763B09C70 -:1094B00074B61B301E58DD7604EDB28E062A4007C6 -:1094C000F60D9F9E75AAE0DCD73E45ACE3BF557410 -:1094D00026F244E8FAFEA6A0A7DEEBFF5B347A137F -:1094E000F94915F2D0FEC188FD483BDFF798B46E0C -:1094F0006D12FDAEE8C3B458804B85DC7E2C15E0C0 -:10950000B05EC2F347E30DC40B7EFE147E0EAD24A5 -:1095100058EFB4527824A799F13CD1E01FCB6E8864 -:10952000637EB27E5DDC125A7ED94087A6FB8DC178 -:1095300092C68D7446F69DFD6911C4D7E661DEF1D1 -:109540007C038BFB67FD24C69F43E5C39B7A6204C3 -:109550003ED365D7E3798B904DC67D865D2613801B -:10956000AE049CED316C1DE279E9D3BB25C86312D2 -:10957000CFC7378686AFA5E539C07771789DE3CB35 -:1095800043C3EBCD61388BFC40A20D65CC88E08BEA -:1095900037393C6A13F45B400F761AF9FE8FEF03FC -:1095A00089558BF2633D8FB39F194477A2D88FDF23 -:1095B00002F958B52657FF91E0E7823C025A7C6DCC -:1095C00075F5B7E1FA1D682FAFE7765527CFDB5E5B -:1095D0003FA52C09F6517DE53D952631FBBE86C79A -:1095E000BFC5F31AAD1FF3956A20DF3822DFE9BB50 -:1095F000E61B8BFCF13EE160D3122D8543AD44DCCC -:10960000D77BEFC0DFE4A8FBDCEA24CD75F3DF16DF -:10961000F2F589FCB65AC86FA38FD6EF2F4D2251B1 -:10962000FAEBD133576E55E49189FCE8DA2BE3303D -:109630008FACFC810E3CF707FD38CCE1FCB6BEE0F8 -:10964000FC66229B472DE4850D8F7CCEE446B87FD7 -:109650003BE2E1570040F073B4C9E88FFDD571CD0E -:10966000E45D51E6FB501283CFCD095AE48F5BFCD9 -:10967000C4D51C657CF19E38170270AECCEB3DBFA3 -:10968000D6B2E002983FE4AD461BAF2189EDAFC5ED -:10969000BC5BE382CB399DE3B98C9EBA5589C77F09 -:1096A000E572BFF5B660069E2F9A123D3F5EE07BE5 -:1096B00084B65E0278042D9E03686FCEA6956190F5 -:1096C000D7EFD7B0FC29C6677DE13D0C6F8D229F97 -:1096D000B037BCF58867D19FD88F5CDC2163BCFFB5 -:1096E000E209CE97C46596287F2DE2FAEA226171DD -:1096F000838B4D12EE43167B08D940E5CBA2DDAB40 -:10970000316EB3FCD9E15B404DC1F3FBA81C599409 -:109710004CC8385A2EDEAC8CDB2EDDDE2B4E4322BD -:10972000F522353B715FBDFC51E577D564FB7F8247 -:10973000DD53ADB26B06733FD7BE249ECF37828C0C -:1097400000F9BEF6D9AFF490B2DB17BD7F49F97AC4 -:10975000A016E4A015CBA349AEFD49141E1F26791F -:10976000DA416E777DC0E0D05DD3CDE4FE5376D490 -:10977000370610CEF49F86B92CFEFA001517107725 -:109780003318985D23EC39595E27C7D2F6517F5ABA -:109790001F07F8B3FF7AD264B0F7137E1DE3027897 -:1097A0006D2B7515C0FE7F5BA519F3188C0616F797 -:1097B000F5FD6AD46108030C6C79B80CF69FD6F6F7 -:1097C000437EF08F6CD5FC279E2BD93A8EE5B98964 -:1097D00071EADA2BF7C27C32EE647A635B96ABC037 -:1097E0001AD12FE1F6592D8759D7C1C13F1F4DF12D -:1097F000F8E471348FE9FAB2D10F773361F814F9D4 -:10980000543076A41DDA41F50F24E589FACD2D9266 -:109810005F47D7B3A6752FC62F6A36F913E7829E26 -:1098200079418BF11F313FFB9B296510E711FA65E8 -:10983000AE6445FD2FECEC3944FCB1385115A783DB -:1098400039DCBE9E1BC3E0BB983833E0BBBB8C2425 -:1098500016FCD373CB5B8A51FFACD6D940AF8B7863 -:1098600047DFF640743F51ED7316763E560AE542E7 -:10987000275FD27D0761FEA2A8E78D4CC99CCF72FD -:10988000B9BD3790B820BE56FBC6E066F00718FA9F -:10989000B1382C953BC69242B4778DB08F5979C0C0 -:1098A000E467FE6A1F3F07EB2A807C90BA1969853E -:1098B0009897709ACA0F0B9C2F0C66209F52B92262 -:1098C00051DD969D1C334D4BE9BB3695DA53B4EE12 -:1098D000DE91CCEAD9C1E51A5ADF905CC8EA3707B5 -:1098E000CF437D53F258562F0C2E9769FDE9E4A91A -:1098F000AC0E1B3B4A58BF4A9E31CD0BF6848DEB14 -:109900006B6710CF05D7BE3E5813E9A77C2C99C9C9 -:10991000A52FB9BFF5CB2CB27006C07B4810CF9DE8 -:1099200089F77E9A2CEC5B96DF2BD629BE23C9D112 -:10993000FB2FE0DFADE4E779C7C790AD2616A7F2AD -:10994000C652F81F6D1F8C71B6C4E438E68FB3D2CF -:109950007E8AC2FD08388AFEC4B8AB40AF82BCD54F -:10996000317FA9681F97CCE4381D67338E3394C1CB -:10997000BF76465A01E08DE24BCBF1A565FBCE6682 -:109980001C17FAB5E5A37C1F0EFEEEA357E9FB59A1 -:10999000E179ABE9632AA78F958D2CBE18B2E5203B -:1099A0001D8D8F61F61E2952AEE3690E87C7926D39 -:1099B0000C8E3DF84892709C460EC7340AF7BCEFF7 -:1099C000BEEEF93FD0BA23F0E592A1BDEDA65D91C0 -:1099D000EB11F9DAA29F2F37AABE2B617953B5712B -:1099E00039F8DD032662C4E76457CF7759F9CCCE46 -:1099F00004FB53DCD740BCE3D04950C3A546CFFDA0 -:109A00000B2D3C7F70A08B9D3F9E31AD88AFCFCAA0 -:109A1000D7673546DCBBD0C38F274319775A7AD333 -:109A20006F0FDC7BFA1B5AC8FB53F075B4FE803F06 -:109A3000FAC2C7CFFFDEF810F354C1B307CEAAF9BC -:109A40000978023FE3774395F428E6B92959E40BF6 -:109A5000ABF83AEB7B8E57CABE5B730FCF03762809 -:109A6000E9794D6B9606E2E7E2BBC9E0634F08FB7C -:109A7000DBF625F37D6B1A49EB23FFEDD5E4E87E99 -:109A80003A7CAEDEBF75D958DEB3DA6FD095E00C04 -:109A9000C0793EEF65763E7DB4CADE80F8CB3E737A -:109AA000F8BBB03E51D6E514C607BDFD40213C4F82 -:109AB0005B64287BD9E1A47B9DE4EA695A6A571468 -:109AC000F52F5B9745EBA79257A1BC2E1A50F65580 -:109AD0001695DF7F485ECDEAB7947D950DF51DABF9 -:109AE000D9FBE35D2F837C27DED5D326A484ED87C5 -:109AF000D3C90E849B5CAE21404706F96E27E84926 -:109B000001CFBECA2283A63E9A7D7AAE870E587CCC -:109B1000A284EBE712B13F0F6A15FBF3AE5876DE75 -:109B2000B80BF4295D6F47B2E77C32D829311D0BA1 -:109B3000B268579B62CEEAC11E925C5477819FC384 -:109B40006125F3209FAE639B1BEC23B2CA69D4222C -:109B50003CB9DF89AEED1AEDE7C01B2FDC3B800D71 -:109B6000E386798CE2FC5FF7C6377F81F868DD9782 -:109B70006627B8F546B5EF5C07F6D5A8F6DF7FC3D4 -:109B8000F42D3BA721E63D0AFC87F479499B01E7C8 -:109B90003FAAFDA665F0FEE80FDB73803EC69EF18E -:109BA000378238E83AF8DA00C5F90CF285F47DCE50 -:109BB00067F4C0E34FD478EA8FF030A624003CAEBF -:109BC000629E5467C2892D41B4D394E760A85D8E2C -:109BD000F1D56ED2CF097102718E5BEDAF3C5D495C -:109BE000D7479F8F0DD11944D8CBE3AFD0FD7D84EB -:109BF0009D5D4A6C8A7AB93145F17E85354BD13EFF -:109C000029F92645FB144781A23E75C828C5FBB734 -:109C10003B4B15F53B4AA628DEAF74552AEA05FEF4 -:109C200016C5FBC38FB729DB4F3A100FC3CFB8CB94 -:109C3000C18E77063C8D508EEC682AEFEF20BDFC7C -:109C4000B445415F233C1F7DB5BED84FA29C5F59F0 -:109C5000E541FF7EAFF32BA5EC7C7BA7869DDF1053 -:109C60007ED9AB319EB180A7B7250A760AEC71C6C2 -:109C7000503CE0AB62E143982FD51D22E8CF6AD576 -:109C8000077F361AF4FC7C19EDDE569E67D35A9591 -:109C9000E7035FDE6929F82AC4E9BDF3D9F980B189 -:109CA000D4C2C575434C53023C7914EB2E252B5579 -:109CB00078BA5B51AFB0DEA3787F52F24645FB1411 -:109CC000C7832A3C3DACA8DFEEDCA9C253B30A4FE0 -:109CD0002F28DAC77E1E6C04361ADFE1952D74FE3C -:109CE000B79E6E2A07BC8C3EE39D0FFC52E4F7340E -:109CF00082382C3E5A7F044A3FDD4F819FEA7043F1 -:109D00003296471B1CE8673AD63004CBE30D4E7CF5 -:109D1000FEBB86122CDF6D7061F96F0D93B10C34B0 -:109D2000B8B16C6968C1F7F735B4614921980EFA8A -:109D3000C21EDF73AF423AECE73B35C15A88A0AE92 -:109D4000DB7900E56467BF6027D43791D7A74D80E2 -:109D5000F35CB09902FB0A4A8ACFFB525D7F49A1AE -:109D6000F54D29AC2EF2125A34AE02B0AF1FD8799D -:109D700064BB369D90FB37BA93AD365637D23A2244 -:109D80001BFAF01ED9EE4A23E437A0326EC5FA342E -:109D9000A8779958FBA69D47A679513FB0F8F19D49 -:109DA000E1F8F10330AE3A7EFC9B0B0E0BF8534EFC -:109DB0005C1D6C81759DE0FE231729D02DA265A93D -:109DC000B640077AF1B4CA8E10659DA6B409FA6D43 -:109DD000D13867615EF06D3A0279E83324B61FED41 -:109DE000B10353991CEFBADD80FB9D931AD732CC97 -:109DF000779242CF00BCF6A49C44BDD265096500B1 -:109E00001C9E4BF990D51342CF48CE88BA8EADF345 -:109E10005F534EE03E22CA3A77A7448993BF90C26F -:109E2000E3067E573A9EEBE5F59395AE35A0274EB7 -:109E300096BA06C17C4EB80DC83F5EB7C507F99605 -:109E400044EB2A9E15E157C949D5E17777EA199F76 -:109E500091BBE4A8E7CD4B53999D857883FDDC9CAD -:109E600018B4C34F6AA29F179F93CAF4F5A57ED179 -:109E7000FD2B77F1F6B29916ECAF6BBD09E3B75D38 -:109E8000EEC1680775D5532851FEE8BA507FF91521 -:109E90006C3788D016C629E77239F59BF6757F3E78 -:109EA00045DF3FBB3EC68932DC7A33EAA7BBF8CB3D -:109EB000F3E38D68B7CC9F915E067A692E8F772D7C -:109EC000B0681331ECA5B5E9E18AA0A5E6822DA022 -:109ED000FE97DB2BF5365AAF4EBB7B0B94AB063EA1 -:109EE000AC87239A3543F76E01F3710D65AD62DCE3 -:109EF0002F05DF6BA0F35AB84176B0FD933877B8E1 -:109F0000FA3BE557083A3CC9F364287C715F38375F -:109F100095ED7BC4777339BD5D4CE1765B1EC9BBA3 -:109F2000A68CE35C063AE998FF5E6E1F7E77653B80 -:109F3000B7DB3ED2B371D5F7508871E771BC9FD4BF -:109F400013970476DC5D16A48FFCAAAF3615D3F503 -:109F5000E7B75B35188717723CC0EE032BFEDC8336 -:109F6000726E6447F0B95304E9BC0DF8E4467A6AAE -:109F7000A67723EA87515F53FD0372F1AAE7EC2924 -:109F80006CB5473D8FE96FA8E6F2B11EE5DAD186E0 -:109F90000D583FD6E0C5F278C3562E1F9BB0FDDDAD -:109FA000861D5C3EFAB87CDC83CFDB1BAAB07CA3A9 -:109FB000C183E55F2DEEB8D40420360FE667BEB549 -:109FC000D340E0DEB4EE7603D229E580679EB44349 -:109FD000FE8BC10AE7EED479306A79DB83FFD65E67 -:109FE000F76164A41647E4BD807D96D937FD9C20B7 -:109FF0000E0BC893114F24DD0EF2F984C36101BB2F -:10A0000075646A32ABBB1C161DAD973C41EB54BE68 -:10A010009CF0382C065A1F959AC2DABD0E8B89D651 -:10A020006F7D2285B5FB0806A9C73F91713BC89F8C -:10A0300052221D057E2837664D8094D90A6BE9515E -:10A04000E08349C98B26001FFC36C5817438C5B131 -:10A05000F128D4A70E69D6C2511B97B960337C573B -:10A0600066AFD4C27713D2EEDE0CDF4D1CF8B036EB -:10A07000F2BBC943F76E86FA3467B316ECC1DFA6AC -:10A08000B0F3FDA21F5117ED42BE8A3CAD61ED6EEB -:10A0900094E3F96D6E94E3022E657756DE0F7EBA77 -:10A0A000BA36C92AC13CEE947A82EF900B577B9561 -:10A0B000720B95B3D39FB8C9B291F2571DD46FC537 -:10A0C000FA431BA3CBDD99A951F4CB1F389F82DE45 -:10A0D000847CE83FE8D97D1E2FF3F5D5B52FB22C4F -:10A0E000427DE5B1807EDD9FC2F4E541AE1F2FF3D6 -:10A0F000B29B3FAFD3B8E6C3384B53FBE4EB6A687F -:10A10000A77CAB3A27D0473BE7EB55A95C3FF07BF8 -:10A1100013D610769EE846F95A2B23F76F5990977D -:10A12000D3720CF245D5F90F3570CE28A7771E30C3 -:10A13000958B2CEFB14D993FDAB3FFE8C7E41E1CB5 -:10A140005F844D4763DFEB7E2035E1BAEB56B6F313 -:10A1500075AF242CBF59BD0EE24940DE12F9CEBDC9 -:10A16000D7138CBE9E5EEBE0F7EEA9F2ACA91DF40E -:10A1700038CCA762A18580FF26524E9CBA8E9C5097 -:10A18000CB9DBF973CBB8EBC79319ABC11E79DD566 -:10A19000A5B0E7E09C14E4DBC17D2FE0A7FFA74456 -:10A1A000CF6BD04F5759E82F1AD89FD9834867767D -:10A1B0009BE775782EE959DC5DE4B15ED0787F0BC2 -:10A1C00076D1B12796A01CEA04E540F9F10D5A07B3 -:10A1D000B9536475FB017E6408A39FBEF233DFE6CA -:10A1E0007AB177C9F849E42976357F93817EAC1B33 -:10A1F000D07B5F70A890C704E13C4077490C9A3C43 -:10A200001D12F14B85906F9D88764447BA5E0BE531 -:10A21000DF7B9FD8919E8BFDABF78B1D29254636A2 -:10A22000EEC4C950B6E93D3B16C13E699401F749F9 -:10A23000EFF3FCBEE99F5EB583BE9A2EFB13F3A538 -:10A24000DEFBCC8E77E69539F27BEF37E9FA26C054 -:10A25000FA6EB4EF741B03710046F5FEB366C35F7C -:10A2600008E4458FDE7095C07D6437DE8F1219C417 -:10A2700044E169E711288B3F77611ACE880BF547D7 -:10A28000A01CF535DB9EDF289FE8D62B2D47D8F1A3 -:10A29000F0A1CAFB164A7ECFF6ABBCEC754FDB2AA9 -:10A2A000AF324FADD45F8C7914723016CACB5210D6 -:10A2B000FD5EB286DDC320EE5FA0FBD8C401C5B051 -:10A2C000EF65F952E321CF884EAEE2A71F2FB817F2 -:10A2D000F9DE84F64FCF3EF6150DE609B46A5DFD52 -:10A2E000C7C23E76C320E7465AFF8F40C22F0ED02A -:10A2F000B2CEFA1712797F5BCD866E45BD6363F8E7 -:10A300009E20C883AEF99B8C7AA78690AD80AF1A49 -:10A310007258BF36420F9296FFEC81FB302AE72A33 -:10A320000170B8AFD24C77D1F72AF97E83781B59E8 -:10A330009DEFB308F9EC7617EDB73281BF4F664F4A -:10A34000C77ABA68AF62F541A2BFD7D8FB29A2CEBF -:10A35000FBBB49D47FCEEA59E2FB16F67D9E18FF7F -:10A36000BDDBB1DDC2DE1F3F60FD74900342BE570E -:10A370000CE0F925FC7E1F2AEFA70C48B86E5E8919 -:10A38000B29DEB03719F4FC54FA7C4BC07FCDC22F5 -:10A3900061EE5BCD7D3AF46F5F8A6BC98F3C9F2C79 -:10A3A000F250DCE51617D87B6B5E1DBC4BE6F93826 -:10A3B000606F6CE3F1E50AD98CF188EEED4CCEF7D5 -:10A3C00065AF2DDFF0BA029FBDDAF93DCA18A8A328 -:10A3D000E35D7E2809F3DBC9C000C6C3570C90C4F7 -:10A3E000F92A3CDF2AF2BDEC39C405FB53FB6B268E -:10A3F000764FE5E70194BFCB5F63FEDE353B8FA070 -:10A400009E5B2C3B908E0F6779D600DD765AD87D07 -:10A4100084CB37BC81FCBA2193DB09D6D050053CF4 -:10A420007BC3FF9E1BC0FF9E7F24FCD57E66713ED2 -:10A430007AD577CC4BEBB4B038A893E3E9538D636E -:10A440000487D723B09ECBCB02B9361992860389F5 -:10A450002CEFE8DD62D80775D75BF09EA379EB3E61 -:10A46000C98F3C97224AB5FD7F0EF8A8380CAFE69D -:10A47000DEF07D16F0731DF82ADB7F60F826698315 -:10A480007A27C44D4FB37BC746043ED547E6BBBCD5 -:10A490003580E9DDFEFC1E6A75DED65B032C0C4FB1 -:10A4A0003C1EB366C6BB63201E23F8617C0C6901A9 -:10A4B000FF3AA56B27A76B27D0B5A0DF705C867E1F -:10A4C0001785BFC2F44B147969EF0E50DE0B46E1DD -:10A4D00016B801DD06FE9174DB4AED5F8C63BE6247 -:10A4E00042FF891ACE5F71B80A786BD3AE0F676DE1 -:10A4F000DA0F03676D9A43E17F10F0EE4B3FA9F14D -:10A5000023E61D854F8BBF0F9F36A67339A50D62BD -:10A510009EA81AEF3169BDF0DE3FEDFA7857B6FF1D -:10A52000C07857C34D5DD6F0F8A6FA795E9A88FFD9 -:10A53000FE3070FCFFCD7F3EBFFE90A27DE18677AE -:10A5400014ED8BBC1F28EA638281722073E10F1F18 -:10A55000772184F6E5F7F5ABF7E54F9FFEF20A0D9C -:10A56000C4DB4A02CC9FFF65BA67531A85F3FB1A16 -:10A570005FA385C275E49916766F57752EE60FAD09 -:10A58000E373FC6ACC7F9DBD97D2CD57C480FE4E4D -:10A59000FFA19BB48EBCDE74507A45435C11796890 -:10A5A000A5469BD685FE1AE28A46370F70BAC1FCD3 -:10A5B0001FCAEF5546A2B3533EAFAA9230DFA98A15 -:10A5C000B07C685AFA3DB47DBA96F8E1DEE34AB34E -:10A5D000D66FC0389FF23CB381DF8B4CECF18A73AD -:10A5E000CDB24BC6BCB459252C3E7897B905CF9354 -:10A5F000CE39BEE9F2BDB49D6CF616B37C6B71FE2C -:10A60000EC8F9AEF12F77B208DF17997C4E3C89213 -:10A610000EEFC7527F37378DF1D97479A30CF92E1D -:10A62000A10F08DADD82EFE8FA8E1B0AD9F90AF8E1 -:10A630005D8A4AA2F30FC6F3CE0F97C3FB35271DE1 -:10A640000897BA928DF980C7BA09D239437E785FEC -:10A6500053B7E16BECA7427EB111DEEF3ECD5CE17A -:10A66000233BE83EC511E9AF0C2E00BEBCD1FE472E -:10A67000CCFB4C831FE9E96CC3712CDF1FF7FB6235 -:10A68000B033820D81A87EC9EFEB1F107E01E12758 -:10A69000107240DCCBB7378DCB05A33400EF53D31A -:10A6A000B252C8CBD7D27AD92B076E205F0FFC23CA -:10A6B000E5EBB7A5F39A64A617D5F4ADA66B41CF29 -:10A6C000709F37FC1EC15DD4DE03BD3A9778F36AF4 -:10A6D000A89CAD5AD1A41B2D7D7FBA5E65FE3C833C -:10A6E000443967F2DDE5B983E54796CBB83F10F909 -:10A6F00009020F9DBDF1D69D767D3B53D9FE0FB764 -:10A70000E33F5FF0FDF41A51D80396F45EEBB6A573 -:10A710005F7FDDCAF61F78DD11E75F16C89AF07912 -:10A720000FC81F063BAECBC7CE33566735E13DF2AF -:10A73000A424140B76E3CA8332D221D1BAB42911EE -:10A74000F74D7510FF47408F2BC6ACC07370BDEE40 -:10A750008932B7E2B938F57D51225FB896F7A3BECA -:10A7600037AA96E709D7AAF27646A4F3FCE042524C -:10A77000C8F22B9476A9BAEC6C200ABF64E7D50620 -:10A78000F4038C4B6FF999372D8C8709E9BDECB830 -:10A79000C937C0DBE47F24DED4F42A5B76E379A8F2 -:10A7A000EF4AAF57335DF3D313C272781EE47015CE -:10A7B000C13DEE061FDCF72FEEC7EE92D87D345D6B -:10A7C000E708FA8D6E74BFF2A8931E3CCF39F25D94 -:10A7D00097CCF20858BE81B05384DD32BA2324B33B -:10A7E000FBEDF939289E17F46DE5973360453B473B -:10A7F000F8DFFE5E7E6BA1E70E1A995C13FEC1A224 -:10A80000A01BEDB84E9DBF18EEB3F7EE3745B5036C -:10A810007E96AEB9EE3DAE7FB5787E06F43293CB30 -:10A8200077719F6B85CCEE7BEE0EC8E8BF5BFFCFE8 -:10A830001FFEF649C78DF7F575D6EEA8FB2251D657 -:10A8400069D87989C27207E6EDC17E09FC77C29F9B -:10A85000A77EFFF5CC321FCCAF421E83F76B76EF9D -:10A8600060F3E90B2F751B42387E9FED7CFCBA83A9 -:10A87000C5D6C8FB30CEA5F7ECCFACE78D61BC7E6A -:10A880005BFC8F0D5529EC9BFFD7F70DD3656A3A1A -:10A8900052FD9827F9987D4A989D3A8F04B05C4004 -:10A8A00042587A08CBA75F4C9C582E256E2CA76582 -:10A8B0007A4EA5637E4B2811F3215FFDEB50A09BE0 -:10A8C000CBE3463741EEDC0F65A775153870FCAE5B -:10A8D00057FE9A01792D37E2FFF858D70598A73A25 -:10A8E000AEF16FA532C64F88712DCAFB4A7E4B026E -:10A8F00099C0E262DB12B390DFC2F22FA959C83FC0 -:10A9000088B7E69DD3B0FC909512DEE7DA16D42026 -:10A910006BE52DCBF2C1FD3C6DADAC3D6F8DCD2710 -:10A92000D17ADE28136BBFDBE683730FF34910F98E -:10A9300071219C7A90E11C0C936FE2FE736AB167FF -:10A94000839DB5ACDDC8F2F7497020C8F1FC3EF636 -:10A95000371332189F0FCB66727B5899D20FD18F65 -:10A96000B7AFCC2C5B960171D90C574C065DDFB0AC -:10A97000B8C0B6478AD02F8FBFB3F2C5A87B307E50 -:10A9800028BE6BCA2CB3C27B2F492CDFDC7B90FF27 -:10A990006E01092546DE273A2DB33C11DE4BCF2050 -:10A9A000DC6E8E0E57F83D3A7794FD9CC8671C0606 -:10A9B0007B2AF48FB37BA95E92583DFF19EB1D9B58 -:10A9C00087A20FDF0B766D53A66730AC63989E109D -:10A9D00033CCFF69836F17DA9FF519E08F5CF18C38 -:10A9E000410376C1C754ADC2B9927F6F3062F90995 -:10A9F000DDE742F91F749F0BE539BACF85F233BA10 -:10AA0000CF8572D91527251A42DEC970B9603D225B -:10AA1000DEA69EEF28016F31FE413D8EBF32D3830B -:10AA2000F0EDC1F77EE28378C84BB6506ADC75E87A -:10AA3000AD6F39E3E5FBBDE8F959C332D8BE36BF87 -:10AA4000558B7A3CBF2D18BB3CE2BDE9197A6CCF1F -:10AA50007BE5733C27DA69ED81AF4BA24B9EAE617B -:10AA6000F5E9CFE4227C5766BA96C1BA297FCF8038 -:10AA700075E4B77DF82F709E87F68F79045D52E8F4 -:10AA800031B4F355EB50C341ACEB255B601B7CFF4D -:10AA9000D22BD9B0122A6F08E31BA02329DA7A3708 -:10AAA000E27CEF30848AE09CCA1DD7E4A879C32BEE -:10AAB000334B11CE12D05B42049C38BEBE2F5FF7E1 -:10AAC000C4B3399D1271BF06C84E07E8A1ABB1608F -:10AAD000D755F2787D5BEBC0F7617DDEE33219E498 -:10AAE00040FA55F0DD0E8E1F51E61DD4BB014F2FED -:10AAF0001D3C3F10EE5FA5781908F7B16ECD18A484 -:10AB0000F02FE68DFAE68947ECF83EFCB21A95CFB5 -:10AB1000CD15904F32D778E82D58D27CEBB90AC8C2 -:10AB20002759982C1D837291236B22E491887CF71E -:10AB300025434A8F012B4D7356A23D560AC225422A -:10AB40001F941B63F865D042FFC42BEA9392072839 -:10AB5000DE9FE2C851B44F1D728BA25D8C3BCD3994 -:10AB60005CF1DEB0B85036ECBFE83AD8FDD7CFCABA -:10AB7000987797F7CAC9DB6EA1F5E9CFCDC2FBFE86 -:10AB80005EE2EDD3F795E3EF0B765178EAA92175F4 -:10AB9000A1E4C1C71E81CE54F67DCDC15F1E7339BD -:10ABA000AE63DFDFC0AE17F27575BBB118E4EBB76B -:10ABB000B5F3D578792583DF1FC2EDFEBEE8A58702 -:10ABC0001F2407A3177EDF969A5E20B394D11F2B14 -:10ABD000A79F60E7C0BEAB1CFB13C8B18873983D4C -:10ABE000A5CADF364CEF7C7F1DF8DFDF93099EABF3 -:10ABF000E3E7F396C3BFE5309D93A5CDF7C37D5240 -:10AC0000F4B917EC4F3807EAA2FD5FCEE07653CDDA -:10AC1000A1FB538AC2ED64FD39C5FBE43E698BA2FA -:10AC2000BE394B59DF5EBA25F2FBBEE4E1F21D8B63 -:10AC3000F41E3CBF2945FD3D57319F8AC326CCCF2A -:10AC4000BB1DF24EE8A3DAA20FB4106FBDBD0FFD1D -:10AC500029E4CE1C99D4476BBF92C1E28ED30E9BE0 -:10AC6000309FE5BBF6FB318525E60BBEC6F4E7C792 -:10AC7000FD03DA48BCCB99ACFFCBC50FFFF35F20D7 -:10AC8000EEB99F60FEE6651B93FBF9AD5F6834B4D7 -:10AC90001CD68FD14BBE35A8017DD2551DE385FC56 -:10ACA000FCBA9516CCEB1C961DFAC85840484CE6E9 -:10ACB000B69F1B29BDFD110E3346E8D32ED8E3D035 -:10ACC000BAFD5F1FBC6333FDF7D4C326BFE67BAC80 -:10ACD000C74E6D28D47F658CBF1700DD70BD02BEE6 -:10ACE000F3BAFB498F9E017900EB87FA6D990FBD8E -:10ACF000FF289D77DD3B8CBF21534EBD6F9F1BB15D -:10AD00006F274F31BE34D2FFC09E5B75B4490FFB35 -:10AD1000B91BF3770BE6CD7C5BBECECFBC211F9F6A -:10AD2000984AF152B79FDD33D1DD3E08CFB5F6A585 -:10AD3000BFEB766890FF44BDB35D9E0CF4AA3E273E -:10AD40002EE049ACB98A7B9CD68EFDAF19A027D7DF -:10AD50001ED4B2648FBEC6D9AA218E88715E7AC312 -:10AD600050CD7EA792CDBF4BE8E7837F8E2B1DCAC7 -:10AD7000CA8D51F41CD5CB3A3BE8E54AF67B0BA7CC -:10AD80000E269501FC4F49C4EFC073572CCF78268F -:10AD9000EB0E9E9BF1FE90E421DAC87B0EC53E725D -:10ADA000D6C15983C08EFCA875F1298A19B22833FF -:10ADB00007E96536F1A2DD7BCAE64E077FC3741E44 -:10ADC000EF3F650B75803C3E35364682F83DED7FA2 -:10ADD0003389B8AFEF94CE9DCEEE831079C5377F1F -:10ADE000AF7BDB2AE4FB4AA742BC7A1EB1C23EF22B -:10ADF0000E99D9B5E44DC69742DED549813898E71A -:10AE0000B4CC19EB3221FEBBE167B8AFEC819B9665 -:10AE1000FFDED3B7B46B7BF6AF7B24764F8993D933 -:10AE2000FBB5632EFD62369C73A3FB6C89CE677104 -:10AE3000DB21BC8747BDAFEED9DFFC0FFDA3BDF71B -:10AE400047EE87607DC2EFADDE27F5D8E5C2BE7B59 -:10AE500096E5B91F19FB78E76A5A5FFF6C0CC2F1DF -:10AE6000E233062FC8EF8BBB0CB8DFB918173AB323 -:10AE70000EEAFBF29C5E1C2D17CF7709FA5EA171DA -:10AE8000FC01F40EF99D0EEFDDF8E26903FEBEC78A -:10AE9000CA5FDEB40BF64F5FA43B7EFD22F8F77E5F -:10AEA0009D80F7019064F6FDED9C1F81BF1C141F6F -:10AEB000F2F316B41B56BE9C82F24BE0EFC2D326CF -:10AEC0003C077FF1F8CCFEE007EBD0EC65BF3329FF -:10AED0009BBD208757EF32A1DD47F49E9760FDE5CB -:10AEE000CFDF3E7B388CFF610281F574B5BF8CFEED -:10AEF000C7307EA3EBF5EEF61C26077AF42CCB9B2D -:10AF00005D18BEA7F915E87F0D11F720B2BCD94234 -:10AF10005962BF3BF950F473E0C73299BD5823FC26 -:10AF200025F1C4980C7CE821ECDEC78706E33DBB25 -:10AF30006733F9F96512E2E71D05BD9DA93D80FE65 -:10AF40001203CBD7EBE35ECB1399367C7FB9F16B61 -:10AF500085DFA476C315657D28FB1DE6C246C7F0D4 -:10AF6000BB69B98EC3F9BF92DCA7607DAB5A1E7E68 -:10AF7000F55D84CB533FF9238C7BDC8C7E1AF22E5B -:10AF8000839F7AFFB2DC18E271876685DD7B7EE7FE -:10AF90001F307FE4FC2BB7E0EF942D9603E7E17EB2 -:10AFA000AC4E4BE0ECBDB4DC77FC04E2453DDF5E2B -:10AFB000717889C9951A58C770C85F715FCA44BE55 -:10AFC00065FCFEE9B63C849FF0D3765D8CBEBF1273 -:10AFD000F314FD8BF989FEC57BDF707C5DD607F22B -:10AFE000412FFB200E11B1AECBB1817CF8295C5F03 -:10AFF0003ACBE7BE1C47EB117473A378CDFF055C19 -:10B00000F134E600800000001F8B08000000000003 -:10B01000000BAD580F6C13E7157F77679F1D623BE0 -:10B020008684FC217F383B10D2262447FE786902B3 -:10B03000E39A908822B69AC0B48CC138DA42293497 -:10B040008D97C086E8242EF5C43F819A69DD46A716 -:10B05000D2192618D2404D3340AC02E68256C8863B -:10B060005A77651ADD2274CB5A16AD2149195B85D2 -:10B07000D42D7BEFBB3B9C73025BABD98A5FBEFBDD -:10B08000BEEF7DEFFDDEDFEFDA00E26A15C0B3B997 -:10B090006F80A31AE8137667037C05CC4F56A6038E -:10B0A0004200ABE87F099FD7FDF62EE703580DBDA0 -:10B0B0004E2806B8CE776F130580E1DEEF3B550FC3 -:10B0C0002D5AE2BF590AC0697FE4C7CB00C6E9B375 -:10B0D0007832057000ADA3CFB840BF1AC04CFC6DEC -:10B0E00084D208F2B9E5F7687C25C02C8973DC743A -:10B0F000E3742114D23A9C97E33548FB5C7214E563 -:10B10000D9C6878B24DCF7AC18AF0021B96F1BAF11 -:10B11000B2E7C3DCD58D10A4E3E215612FC0E8745B -:10B1200011B80CA433E58492857CFE01F251E4331E -:10B13000EA84B63E3CB7A6898FF4313D1C833ACAF7 -:10B14000C703C7E4AB29C3E7E5008BE8B9DB943B51 -:10B1500080CF2BEDEB93FAD8C767249EE95793C9AC -:10B16000477ACB27E3F1B8391F85B840B8E2679535 -:10B170001B716F307107500440BB3C678E9F737B1F -:10B18000E24205CAED736B02EAD3700EED82E3066C -:10B1900047FC4DA29C02B07D06AE3DEB1CBE2707CE -:10B1A000E1905BE6203EF5A67939E4B506D7EDE2FD -:10B1B0002240E7BAA187D17D5C82C9F1451863546A -:10B1C00001BF8328C2CFE8120833DA021146974242 -:10B1D0000FA3CBA097D1E59060141E8E4721402786 -:10B1E0007DC77F331DC9634FF3E3486BBE0A915E91 -:10B1F000CF641CBE4938D43E08078D237FFCAC3891 -:10B20000B4809ACBF8A5E25150CAFC3B150F17F950 -:10B2100023DA2D0D62B94417812E105D4C8E8B7C84 -:10B220001E05C941E32650D8B8F97FC4A14E571D69 -:10B230006AF91478344DED173B4CBF1827DD6726AB -:10B24000ED745292D8D8B217A09CE1F993ED683D05 -:10B25000AF496FFCBBE407F841AC31ECC8C3717572 -:10B260006357318E8F49ADC6B8A1F117411C1F8FAE -:10B27000AD0C3B1E21BF6EAC76CA00DDDDABC24B10 -:10B28000705E4DF35500C615B495F0E43F5BFD06C6 -:10B29000FE6AF736D98F71A4167A64D2CFED42CC0C -:10B2A000103FA158803AA4454BE3179DB86E89A87A -:10B2B000F6503CB6BBE33E0971DFDADD9C03A8EF34 -:10B2C0006ED158EFC27DEEAAA45EF85C4BC3715FED -:10B2D0005F591717BCFFF9C8F790544B72CCD58053 -:10B2E000E438CDC986251B73DA304F0C279CB04F4C -:10B2F0004A9EF3A31CF508C901EE1220BBE7BB0D63 -:10B300003EC37D65656497930412CD6705AA09B7AE -:10B310000F73C22769FDA8D7F0AF936487DAFBD318 -:10B32000DF4BCACF697DEAF3D10F5100DC7F415278 -:10B330005F27793BD23F2DA1BC34B2E0BD5D7A20BE -:10B34000E9A71C9EBF06F58E2A1013591E59E8BFA7 -:10B35000897914D006E368CFD10DC80771A809AB6D -:10B3600051273EFEC29AB1102629E27B8ECEED1007 -:10B37000F5A205B8EFA5953744C3CF0A0C3F33F3C8 -:10B38000D0F90BFDCFE71BC3304C88AB8E0B77FF9A -:10B39000F927C4AFE3B647A6E5C9787AB90B7CB400 -:10B3A000C863CB1B569CD59F75C5051F8D1FDA4002 -:10B3B000EB16BD37504C7A2D1ED0A35EE273FE0F04 -:10B3C000F9861C665D503EE13E4F5D6816283903E4 -:10B3D000749E16622EC4AB938B5CF2D2F824276B5A -:10B3E00028FF5FDDE81F19B45EF1E4A15E9B4CBD50 -:10B3F000DAFB8FEEF222DDF4CA93CBA182C2C1C97F -:10B40000F2B7845F8AFF2DC79DC97CCE7ED110A87C -:10B410006707589FB8487ED0DE6B5FD701FB3FA619 -:10B42000BCD33131CFA35CC392378BD9CBAC57405F -:10B430002504F93D6DEE253D3C24F77931E6E29097 -:10B440001EEA92FD3436E3074EBCC0FCD25A0FAF61 -:10B450006432DB5BF1F4CC1E943D338957E53197C0 -:10B4600042B8571ECB5148BF4A11D68519DE31E686 -:10B470007795E81B1CFAD36BD3C7823C9EF3DAF9AD -:10B4800052193328BCB15381BFCC49CAD769C653BE -:10B49000B370A249443FB8FD14F83124A1B3FFA70B -:10B4A00051378E3BF702AD80DBF4837C6E0FF131B8 -:10B4B000E253DF5F9D4BF63E65C6A72B97076902F7 -:10B4C0004E69D234904A93630B5F97699FF4D21907 -:10B4D000B679AF3CCBB63FA32E68DFAF2989F21017 -:10B4E000E56363FF74E561DBFADDBE962BE4978BC1 -:10B4F000121B97132E994BAB6CF32170B3FEA1B6C0 -:10B50000C023C7703FDC31EA791D7E593D808840F9 -:10B51000FA35E8003F467BD40F3B6C764FD3D11F02 -:10B52000715DDAB50976C73F97641FCF0F987E50DB -:10B53000000513FD2089B3E71E8ECC0FFA7111E1CF -:10B54000EC1563D8724CC22904733268BEF68A00C7 -:10B5500031867B971CC7E733C376BC73DAEC78E798 -:10B56000A9767CF337D9F12D8CD8F19DBDDD8E679E -:10B5700040B3E357BCA7DEB67E6E4FA36D3CEFE051 -:10B5800032DBFA8762ADB671D9F1D5B6F5F37B9FA0 -:10B59000B0CD579EDD6C9BB7FC2AD5EE0BE29DB675 -:10B5A00075A976AFBEB2C3C6D7B2B386DFFFA79D7B -:10B5B00037A7D8F95B281BC5DDDBBEA1FD14865F6C -:10B5C0004E37F252B3B030A190BD173A65B2E93BA5 -:10B5D00052669397E2DDAC4361B30E417817B37BBB -:10B5E000D8F41339215FA23C5A753DDCE4C3718D58 -:10B5F0001EB944E93834D4D39421313791FCB89E34 -:10B60000337179BC8E03872D5E709C9DC46DA5D669 -:10B610002D64E0E2864F6351962EC9A9F0FC567363 -:10B620009EAB33F2FA0A250D1C13F058643E072A2C -:10B63000DAC86FA131052BCDFB00F6E520525FCEB5 -:10B64000BB63D1C054FDA47C50607D92CAFAA6CBE6 -:10B650009CEA24BACA9D28A2FA75285B7D298079C4 -:10B660007E849725D667717A94941A25C558D17926 -:10B6700027AC9453FF8EFFCEC2BCCB5F0D6B1E2652 -:10B68000BE5F47F955539EC301F55000F11FE4FC1E -:10B69000BBAA71EFDBF51F1551FD71098804E6C1E6 -:10B6A0004C9FF2133A47DBBD703AB35B0EEA8779E1 -:10B6B00054E725D63F683B38761FF888983D3221FD -:10B6C0004EF73859DD01F37EB4D6C4CBBA1FAD3185 -:10B6D000CF1F44169B304FAF3D7B99E1B2257718C1 -:10B6E0001C99CCDF589FF46481A76A1FE9A454CB4E -:10B6F000ADF3E9B9755FCA173E4B5D6C16CA33F4FA -:10B7000029FA458B6EC91D62F7B97BFB4F1875E4AA -:10B71000FEFC355667937A1BFC07F7A6B3FA32B8DE -:10B72000B7B0916892FF08E3BF36F2AECD4FD66D49 -:10B730007FDFE67FEBB53FDBE6F5AC31673EEAAF96 -:10B740009FC96BF93AE277EBB42B44F746B4DB358B -:10B75000B28BC55F3F306F099DF7DFF5FC1BC377E8 -:10B760006067021C73927ADED8799D8DF59D3AA3AD -:10B77000A97A5AF74C8B8A17A1D481F619E3A6C986 -:10B78000470293CFD91C34FAF08147B31BA9CE0EE0 -:10B79000148A0E839618E3BC3AB7316E594A74D4B2 -:10B7A000E9D943F7CC010E140EFD610DA7BCBA1EFA -:10B7B000F97E3B5BFD98FCB363F3588503E3A1A3DB -:10B7C00052FF0647A97FBA7A87F4E7B0BDCB9BC189 -:10B7D000E42CA1BE6388D72A38CC0515C19C15D4AA -:10B7E000970F4DD346A812971C99618C45233E4272 -:10B7F000C17FB178A8F1ABFF263E1F70429CFC567A -:10B80000FB25173BCAFC4D175BBD2C9EDAE8DE45D5 -:10B81000F75DBA6F8CA619D419E4987E620AA55E0A -:10B820009D682868E4B566617F0947FDC1411750EE -:10B830003CE0390AF515DA7957EC288EB35176EAEF -:10B84000537E2D1AFD7CD5AF5C71CA1B1BDD77982A -:10B850009DF28201C62FAB183317F2C97AD1158B2E -:10B86000927C7AA26805CAD7E3C4FE85E2FA1ACEB2 -:10B8700023DF5B07E61DD937C11E7941E37E084F00 -:10B880000118F3398769BEBD7FF006E5918B01B5DC -:10B890003088FC0779294479A4DDF7A648F9A73256 -:10B8A00028B17D282FD317F3C1773986B3DBFF0189 -:10B8B000FAEB3A4C3619747FE3D5B9C15ABAA7E806 -:10B8C00022F1438F60FDDFFDF4BFB521F1C372A407 -:10B8D000235EB988CEB1CE45392A898FA5B72547D1 -:10B8E00092CF83FD7AA37BCC16BF375FDE5D4271BA -:10B8F0005225700C9FD4F52D262E034EA3FF4B9D91 -:10B900005F4FF6AC9DC23EF3007291BAA661AD43A3 -:10B91000BA927042FC6E7D0DF5617D8BB280ECDBDE -:10B92000DEEA91296F59FC918FFAFA03CEF92427A8 -:10B93000FC25B2C3E6C8F7CE5C9592F3E87FCCAEA7 -:10B94000DA01C35FDA2FBC7FE3793CE5999FCDAF85 -:10B95000A63C6DED4FC579C42BB1F73B4F087186FE -:10B9600023E2BB9AF8F75DF95D36E162E1FC79719B -:10B970001D2D4C88C47FF4F0DD2209F7B79FBB7CF6 -:10B980009DFCB6DD7CBF00A7ECEF0D102F8DEE9374 -:10B99000F7EA08E5D6D96C9A9BD8B7B9ACFD050E85 -:10B9A000FB7E6CD0793CEF94796F394BF9628AFB5E -:10B9B000EDA904CF4AF4A95CEC0BA9FE60BDA77AFF -:10B9C00063D5FBADEFF22C0EB60680CD935C6457C9 -:10B9D0004E7F8BD51FEBFD4594C3BA8AB8758AEAB2 -:10B9E0000BE497A076B17A24CC46BBE2BEBEDF2C36 -:10B9F00033EF69467DAB35EB592DF121F9CB335847 -:10BA00009DAB31CF0DB9B17F0A52A9D0CCF734E646 -:10BA1000FB8CBD6FD9EE77FF01E91E35E2601400A3 -:10BA200000000000000000001F8B08000000000064 -:10BA3000000BFB51CFC0F0038AD5151818D6293159 -:10BA400030DC5266607055616038278F90A31556C0 -:10BA5000E5A04CFF0B4606865740FC0688DF319276 -:10BA6000AE5F4B18C15EC9CBC0A00DE4D7006955CD -:10BA70000106062E205B0788F701F9F780F81510FC -:10BA8000BB08313070F331309802B11810EB02E589 -:10BA90007D81F4373EECE6EB09E3B7FFB9002A5F9E -:10BAA000521095CF20805F7F97207E796921D2C385 -:10BAB000C44E9DFCF868A240EF40E09B0CA87C0BB4 -:10BAC0005906062F3906861E7908FF1A92FC3CA0FB -:10BAD00098A52C345CC5816907C8BFCC80DD5C1992 -:10BAE000A0BC36507E15D41C00DF43986568030067 -:10BAF00000000000000000001F8B08000000000094 -:10BB0000000BE57D097C54D5D5F87DF3DE9B2DB384 -:10BB1000852C842D4C58141070085B1094C9860134 -:10BB2000020C8B881675588410208980FD51B51F32 -:10BB3000139688967E0DA2965AB0030D82FDB00D25 -:10BB4000183560A0C366B1451B5C10BB7C1D16D9BF -:10BB50000C2404A5A3C5FADD73EE7D99F75E664853 -:10BB6000B4FEBF7F7FFF7F102FF7DDFDDCB3DD73F9 -:10BB7000CEBD910D76424613F235FCD07499400843 -:10BB80004989A6F4E79F5FA71232C94CFF2512929C -:10BB90002FDA081942C8441B099A689D89A3E8C78F -:10BBA0006442DEAD128222B4A1F502C3082926EC5C -:10BBB0006792446A85DB0969CE7AB562909B10C1B1 -:10BBC000EB25CB3369EA769199908E3AF085E020A7 -:10BBD000C4996520A40F6BF335FD9BE8B5625F4AFD -:10BBE0003EA9A083269FE2EBACA9DF71460F4D79F9 -:10BBF000277F3F4D7997A24C4DBE5BD91D9AFADD48 -:10BC000097E768F21981719AFA3DD74ED1E47B57D4 -:10BC1000DEAFA97FEBC6D99AF2BEC1624DF96D3B8A -:10BC20009668F203AA1FD3D4BFBD76A5A67C50E8C0 -:10BC3000694DF9E0A3CF68F243EB5FD0D41F7E7269 -:10BC4000ABA67C44F8579AF29117766BF27736EDF3 -:10BC5000D5D41F1D39A8C967933F68EAE79ADFD793 -:10BC6000E4F35D7FD6D4BF3BED8CA67CACFB534D9B -:10BC7000B98207E3FB5CD37C9FE0F987A69D447CF7 -:10BC800014D884184919A6665289A99554636A2361 -:10BC9000F5989E49F7DF8FF8F962A08250BC5B15DA -:10BCA00068FAEF249ABE9BD5D3E9EF0FBD7909A1BD -:10BCB000783B91754D269A6D2191E299C94C0216F7 -:10BCC0008A0A8E08C5B7248A771182A92B42F16DA2 -:10BCD00030C5BB8819D30E910EF83D29E2C2343924 -:10BCE000D219BFA744D2304D8DF4C0B463C48D695E -:10BCF0005AA41FA69D227D30ED1CC9C4765D221E6C -:10BD00004CBB46EEC0EFDD225998A64772F07BF798 -:10BD100088175377641CA61991024C7B44A660BD1A -:10BD20009E111FA6BD22F7E3F7DE911998DE129946 -:10BD30008DE9AD113FA67D22C598F68D1461DA2FED -:10BD4000B204DBDD1629C3B47FE431FC3E20B21C13 -:10BD5000D381919598DE1E0960EA893C8DF50645F0 -:10BD6000D6629A197906BF0F8E54623A24F2027E87 -:10BD70001F1AD988E9B0C8564C8747829866457E15 -:10BD800085E988C80E4CEF88ECC6762323D5988EBB -:10BD90008AECC5EF77466A31BD0BF02D09F02E8491 -:10BDA000A937F27BFC9E1D398A694EE43DFC9E1B3F -:10BDB000A9C7342FF227FC9E1F3989E998C8694C1E -:10BDC000EF8E84312D885CC2746CE402A6E322CD30 -:10BDD000D86E7CA409D3C2C897F87D422482A9C238 -:10BDE000EF4896DC1056F0AF07FC7FA6EBDC6D94B5 -:10BDF0002F11BFE16B9A121BC58311D1FAFA94720D -:10BE00003BE49332C5AB048ADF899417023F9C5808 -:10BE10002604EFCEA0F8911C3E0C7939CBE436D144 -:10BE2000FC03A44906FC25A4DEEE1B40C88111E7F3 -:10BE3000BB8629BEBE9B12EA46911B7E90DFCA30AC -:10BE4000A79EC06F1BA430FD3E31F9608ADF06ED6E -:10BE5000296D64027AD3F101BF293A025F7E402244 -:10BE600001079DEA71E86104D60B99687E6621F1AD -:10BE700066D2FA15234C3382749C8A4C5F918FA64C -:10BE80003FCEF0CD80F4F7403C74FE87787A9C1862 -:10BE900030FD32DD85E9CC477A337ACAA340ECD451 -:10BEA000361C1E4865ED88AD291DD6D7DE7612A159 -:10BEB000ED8646EBBF4C7C1FC2F7400EE953668B04 -:10BEC000D6A3DF4F42BD18DFFF1CEB7BAD813202F2 -:10BED0000AFF400763701BC827E2764E867999DD1A -:10BEE000CE29F6F8F37A7285ABBFD44B3DCF20CE86 -:10BEF000EF4981CCA866FC256DCA00EC1FE561C046 -:10BF00006AC1FE450E7FA5DD67004FDAEE3D8BAFBF -:10BF100091C9537757848BCDD52EB8D076D7112EB3 -:10BF2000126D676F7FBBF869258333F1BA711EFC10 -:10BF30007BA9890404BA8EA66DF6E0D60CC06137E1 -:10BF4000F2CF221767A0C9141854AE1725C21208E1 -:10BF500039BC3F2164A0F573B6D9B7821ED09813BF -:10BF600078DE0770DE2A936DB4CACAFD3F3AF173DA -:10BF70009ACFD9221313CD2F48786E18A170BB55D4 -:10BF800010D8F801EF815EB47F3F517EBC02F43FD0 -:10BF90009FB0FE1B054647816D4E84EB85BCAA8A87 -:10BFA00091340DEF5B5C48281F3F4FC1DA89E2F7FF -:10BFB000022B9120A51CDC88F009C867C38A7C414C -:10BFC0007A96A279B1757E3EE415FAA7EB5E1094DD -:10BFD000A379FA77E10E6D5E052FDCF7268B1CDC6A -:10BFE0008A78D585C1478197B70B831F87579E45B0 -:10BFF0000E1892115E41E0034EC18D7028B2C82127 -:10C0000091F65344E1082458B4EFA95480D3C21DDB -:10C0100016D759D5B88BAB1335F9D2DA4EAEB32A51 -:10C0200039DA7CF4970EA0D3256906D759CADF1AEE -:10C03000567893CED22DBBB2A20053053F16576758 -:10C04000B86C9A7EB4F9E64AA180E1B7DB396D405D -:10C050007C3C5B9266749DA5A47A690793B797565A -:10C06000985D304EC30A978B8D9B86A902AF45CB56 -:10C07000AD585F995FBC7EBFEBF9115243CE9881FA -:10C080009FD3B29EF1EBC7A527E93323D2499D7C0C -:10C090001DF0C64CFF7E6D403CC2BCD26F69B51826 -:10C0A00030DD0EDF776AC6A3EDDCE754F2253EDD16 -:10C0B0004AE49C0A2F97420748A766DC673FEDD108 -:10C0C00049FB6B946C6B418F9AC0F1A714EA517EC7 -:10C0D000B0D81C36FAE9A7CB356C3FE28D7369C541 -:10C0E0008E2EC0D78ACC9546605645D57DF3809E6E -:10C0F0002ED7AC4A05F9B2506CFEBE2F46FB1F2B63 -:10C10000741B949BB4F232C8E749FBD5D019B1B582 -:10C11000AC9BE61B0C74285BEB7E7F2A30B953B2D4 -:10C12000F3F8989174FE25B5578D308F0982FFA7DB -:10C13000424A74FD02AC9FF653BCE39411D677419A -:10C140000EDCF278C64DE0D96A9EB6B47309AAF93E -:10C1500005A82249E9757616A757E2BEF7CF943EA7 -:10C160002FFE41264FD379901BB4162D4FE7A573B0 -:10C1700089CF01F09A5DB310F9CF45E03F208749A0 -:10C18000E530C08FCBC45000EBBB4CDE730C56C106 -:10C19000EFA060E4F0A1AA2CE507261C0AE1D6096D -:10C1A000F895A9A8A25E1C08DFA500E74BC2D7C876 -:10C1B0004F8202F2B322F63D40CCE5B88EB58C1F1B -:10C1C00005E81FC83F5CA9E54FF3376AF3F3C8944D -:10C1D0005489F29779CFCAB447CADFD4FC8FC2EF33 -:10C1E0006581C9DDF9A4ACC245E7BFD948F789CE5E -:10C1F0007FB68B485DE8FA16BFB179D82C9A7F5B81 -:10C200006072ECD20A3AFD5B683F1DD8FA8B970743 -:10C210008DDEFEADD777A666F0F49104FB63F2B134 -:10C220005891BFC42D0D436E4995DCF8EBEF5223B6 -:10C230007A2D0EA847BFABF8F39CB5DAF5B5B57EFD -:10C24000FD7A097906F1AD78C7640278A6AC47D9C2 -:10C250002F653DF20EC11B8C4107618EAF0A5F6BEB -:10C26000E2F053F48ECF75F92F75F9AF757905BFEC -:10C27000654EDF14EF3F1786023D378D6178123629 -:10C28000B2F30CAB678CD6FBF266F54C9C5E68BDD6 -:10C29000AF6F56CF12ED4F32A4B4AEB7F88D575EE4 -:10C2A0000F50FC2EFECD730E42F1F1A25499EAA17B -:10C2B000DF176D5BE300385D90020EC09B8B41B1D0 -:10C2C0002016BC46180445DFB00974DF4B14FC1F70 -:10C2D000553E11E4FBF56DB2EB69BA2FA53B4C213D -:10C2E00013DDEF929A05856420E64FB1FC93570168 -:10C2F0003F4A6BE5D3EA7D2DDEFE5CAADB8EFBD0E8 -:10C30000C5003A30097521342DA9FA640CE8D1A58D -:10C31000A409F159DF0EC687A31DE5D7B38CCED68D -:10C32000E5CAB9B1947D22A5353FBA0AE7C65222C3 -:10C330009D56E35111E032D5F3FA19ECC9705E2035 -:10C34000C3C970E02B0A1C483005F9F2AA977F3A5E -:10C35000F0149D4743D51F1C820A3E544342B83413 -:10C3600057CFF95BD24DE4C2158A9FE41675BB2006 -:10C37000B673D7D20974A4D93A962E92438E9114EB -:10C380009E8BB6C81E8A9964D12BBF7CE9054A777B -:10C39000E46393A73785F7C2578E9CB883E617EE00 -:10C3A00092930BD9326C426A743F4AE95FB0CB2852 -:10C3B000F02F7EF588D13D807D7FA243741F16EE5D -:10C3C0003A6024035AC32DB7FA80316C8BB11FD564 -:10C3D000A7C6803EB3EAE5BF1B61BF2FEE1748C773 -:10C3E0008CD6ED8BB61C41FD05E084FBC7F7A76535 -:10C3F000BF5AED5368E2DE2158CF05FC3ADE3ED944 -:10C4000041560F453CFEF55E3A7ED19F4C1E587F4B -:10C41000D1AF973A601DE7A53286CF9BD7A47AE9C2 -:10C42000B8457220D58529FB5EF4E2A38867F38FB7 -:10C430003F8A7A19C58F4E069419814EB0BE873750 -:10C44000DD83EB9B47FC886F459B455F10F880447C -:10C450000A76C5A087DF707A38BF95724ABABEF3F4 -:10C46000C01F41CF7D4FE4FCF111D4231FE56BA524 -:10C470009A0CE63F37B37DAA301814BB9C5983A7AA -:10C48000554F221FBDD4CDDBD1D51FE1A0F04DE427 -:10C49000A7E2F1FC8E6C7F18FFC57614EF72E13BCA -:10C4A000D4AF97BD96819A769C5FB2F197F1F1E98E -:10C4B000BCADA07F9C4F657242BFBE3F1914FE48C1 -:10C4C000E5AB0ABF5474CDE8BCEA2946D70A9D07FC -:10C4D000271740F9671F30FA8176207FE8BC421D9C -:10C4E000B1FCC03401F980898462D17395CCE959DB -:10C4F0005B4E3934EA6F74DE92E054E309EDBF031A -:10C50000C21FF59279CFD2762A7DBA14C6C37AC6F5 -:10C51000E8F78C28DDCEE7F4FF2BA0FF8428FD93FD -:10C520004D29ED3A9F2D92832FBD00F44AE933E067 -:10C53000067A957DB0EE4F771E3A713FC5EB4FAB53 -:10C54000153AD5F24D3D9D16ED7E94007EEAE9F454 -:10C55000D3AE6524269DD2EF31E9B46BF87F856FA9 -:10C560002A703BAE831BE583BFD8EB8E0F3F3D1F88 -:10C570002C35B863F241FAF30119D61AEF147C5343 -:10C58000F0ACF8BF1677077ED3828F0ABEB5E0A362 -:10C59000826FFA756AE1A62FDF04FC46A51FC82B3F -:10C5A00049C04EF7B9699F88E7C4467793A3031D36 -:10C5B000778D853C047A76A38BE71359BE29C5583D -:10C5C000017C41F9DE642133003F1B7D4D8E449593 -:10C5D000FE7CAA4E74B8697938480A62E9D594E3BA -:10C5E000E2F86112AFBC1CE1972FDAD2970F81738A -:10C5F00095E801DD6D6EF9BD0E305934D6F59C34E9 -:10C60000837E7FF86D116D1A8D56C74098173DB720 -:10C610004B9D287CE7F07DBE4002CF8FA2EB9A5362 -:10C62000C7F4E2B9EBB4F098675B66043E43F5CF1C -:10C63000281EA8F045F113146DD296179375B85FB4 -:10C64000C53AFCF1F3F34E2791E3CF2032889F37B0 -:10C650000CD0DF12CEA7F2C5FE936650B8371E1578 -:10C660008989E69BEB445201EBDC290409D0712057 -:10C6700005F1B084F207A23A1736009E19E3D36F92 -:10C68000C36B7F1DF638ADB2E8F53F0FFC394D1B8B -:10C690005EFFF8963721FFC647E97F26ADEBE7EE50 -:10C6A000FFE241E0EF8DFB4D04ED24FB7F97FE3868 -:10C6B000E4F79A3C68E75869F2A27EBCDF1EEC0DF5 -:10C6C000E5DD987D69D5BEBF0F0CA3BC598DFB94E9 -:10C6D00027B2734473DD3FFE5B488694AE0AE4E8FC -:10C6E000FE04D4AF4BF75A8270E86CDCF7F7617E3A -:10C6F000DB77B79E1223F123FED9C98CDD80AF8989 -:10C70000CC9E56FAE6885F96D3F117D71C30CEA19F -:10C71000E5B9BFFD6A20F095C6DD4C3FB822875FC2 -:10C72000241E422689CF95CB74BFAE80AED699F237 -:10C7300025F14476C0160B2E0C0E8D140EB02E0A69 -:10C740009722E087F1E031EFDF161E571F84F117C3 -:10C75000D50D2762861A2E82977DB707CD02AE9F30 -:10C760007DDFFFF781C0773FAD2E47F9DDD6BAD721 -:10C77000C0BA53FE5F5AB7106ACFBAABFE6DD7CDC1 -:10C78000F0BF9FC8E4919E0E5AE3F91BDFC7FCAFD0 -:10C79000ED1E9C6F3BE9FFF0BFEDFABFE5BEEF1663 -:10C7A000D01FD7D6BE9FF9B75D775BFBFE36DF772C -:10C7B000BB0BECBD8DFBBE4A27AAF5B7B56E83F463 -:10C7C000EFCADF6EBE6E45EFA93794B986D0F97D0A -:10C7D0004C2AEFC9A0E91FBDD792E1384A69C017BA -:10C7E000EBDC9029B1738309EC4C50F11E41B11779 -:10C7F000D56BFCB85D8B50CF98E8FD31EA07442A31 -:10C80000ABCFA6F5EB73E6789EC61A9927FD909FED -:10C810007627CF6BCF531373C61F05BDEEDD723A7B -:10C820003F885BE826B9A8A644267945D403698ADF -:10C83000FADF87E963B0DEA42CED79E23EDD79E032 -:10C84000DE19DAF27B78FFD3C9332960779B3E97F4 -:10C85000D9DDEE25656B5CAA7DBA47D78F4322DC14 -:10C860004EF2EDE037B7057E4B101E245BF46C23CF -:10C87000ED801F61F0AE9F3628087618227918FCEB -:10C88000A62FF6A01D949F3365DE5EB6ADAD07BA48 -:10C890009589F67CA99C13DB8233E1E74FECAF4727 -:10C8A00014EEB257C4F3A7AA5F848BB21FDF741FC4 -:10C8B00094FDFBB6FB310CF62386FF6C81D97C0F0F -:10C8C000F82FCC7D043CB74F5A27621C8CB9BF802F -:10C8D00070F465C9E8DFF9C4E01B068A73E1E0E1A2 -:10C8E000258FB16E3D009F051C8EF34819EA9DE42B -:10C8F000C6D75F8F02BF114286967B099940CF2130 -:10C90000F34609212B5DF77C89049C9960D714C8F4 -:10C9100069B55D33A8CDC3CF5DA9D17EDAAA1F8FDB -:10C920003F7CD7E9DF283F3ADD8B9E572095707812 -:10C93000497D4E7CA88EC1B1749110EC817814921F -:10C940007D2ABFCEC71CAFFFF6C460E473D93F1980 -:10C95000E0C4F3ABB71FEAFBA55CDF6F0EB89D60C8 -:10C96000AF69AEEBE9047B4CF3D15C879A2F2AE9DF -:10C97000717E8E7C7F8519D3C63CA15284F31669E3 -:10C980009A887238CF4280EFE8DBED9114BB4B19E7 -:10C99000F333D21F7118EC23FB994F9B3A3BA8F657 -:10C9A0006DDD848BD2C0D6FB003FA7557E927F15EC -:10C9B000BE706E05B81EB784C7F862ACF70F1C7E58 -:10C9C0008507BF30829D604A5D860C709992276A08 -:10C9D000E26E0E49FC3C35980C8679151E1CEB184E -:10C9E00001FB7254F458287C4BEBAE1AFD31FC6D00 -:10C9F0007A7842FF60173E237BE6013CCFFCD842A9 -:10CA000002941EDEE1FE1F5AE405FE45BBF2827D64 -:10CA1000EC0389F915FACACC2E3EB5305B4EA1E382 -:10CA2000F6AF710D0211D399D7EF2BBBB1BC0B6FD1 -:10CA3000A7D4EBBC88D53B657495C45AFF04235B2F -:10CA4000FF7CE2F97E96F0EFB76FD93FB187724075 -:10CA5000BEE709C8475AE33541FA682E1082207FA5 -:10CA6000E11C8BF94201E5FF3B06561E98C2E4A586 -:10CA700082F77A380B3283B3327E86CCF0D92833F2 -:10CA8000F8287056E0AB9FAF529FF2ABD16AFBCA59 -:10CA9000A4DA41BF06FDA4A44E7081E9AF440A1B8D -:10CAA000810E4B6BD7CBE02FB8CFCDFA25926FA07C -:10CAB000DA5FDB5796703E873247A2FE786D1DD352 -:10CAC0008FBD73AF3A400F7AC7E0F9E348A0C7774C -:10CAD000458C278807C73FAFD8312D4F52F79B8130 -:10CAE000F39CBA285B0673D0F7161D903BAAF0A9F9 -:10CAF000AFDC01CB95EF9D17B933E13B1D0FE7117B -:10CB0000F84F13D946BBE85F5D9F9340CBBF579664 -:10CB1000C8F0B0A8FA8011F319585F194F19474FA0 -:10CB20004FD30A1334F939B9E1AE009742536899EB -:10CB300027069E1E96153FC93794135E8AB703FFDA -:10CB40007F901357C77863C06D83DC4A3E748C2591 -:10CB50001F9694BB3B02FC97ECEBD9118863C9DBB1 -:10CB6000F9A9B1E4C3872B983FF023CACF206D9C6D -:10CB700046E5C3ED2AF930CD82F8A16FF743B99DA0 -:10CB8000F241D9AFFF653EF321C88718745D296B68 -:10CB9000E5C3F4BA59281FA64F13895B658F7B52F2 -:10CBA000E67EAEB8F2213BF53ECCCB9E841878F3FE -:10CBB000213F97005C218571404EFC96F37DBDBC02 -:10CBC00088C7CFA71805EEAF6E839FFF5F82B3C201 -:10CBD000CF97D0F30BE881ADF19020BF5E721FE5D7 -:10CBE000E702E023E3E74B1EE076491D7FF5017F76 -:10CBF0001DA2E6AFAC7D899FC983D2DA8C9FCEA4FB -:10CC0000E5F757CA1E33AD7F7F94DF0E53F3DBDFAA -:10CC1000727E4BE19CEE8AB1BF33662610B7965FF9 -:10CC2000F5023E7566D0EFFABF0A78FF8E887EC4A3 -:10CC30004FB81C3F36E87743C07E9E6C94107F3E11 -:10CC4000E1FCEBCA8AE0B43C4AC7B973993EBC78B0 -:10CC5000A7887028A9617A5E492F6BD04DF36332A3 -:10CC6000BF407FE0C27DCC1F48015598ADDAC78533 -:10CC7000EF842BBA40F91601FD99F33C0BD18E4F8E -:10CC800036323BB199FE61711D5EB4232FE6F05A36 -:10CC900050B705EDCD0B825A3BF4E25EE32EC2396C -:10CCA00040E1BF0B77E8CA3D4FA1BF6231D89B5529 -:10CCB000E70F91EB0F0F8BA1FEAF426CE71FD9B9C5 -:10CCC0004ABFFF4ABD96F517FD8BEB3F4ED73FE4B9 -:10CCD000BB5F7F7BD72D1B39BD679221401F9F18FB -:10CCE000BC48EF81DFD3F5D371E6AEEFDD511D67B0 -:10CCF00094C4E9F21D83BFA213D42B11B0DEFC4D06 -:10CD0000BB8EA4D2FCCC6A3208CCF4F3376AE5625D -:10CD10008B1CAE71A39C9D59B64B98DD1FE04DCA8C -:10CD200000CFE6649AFCE04F3D6E6942FEA5E0DD6F -:10CD30009D4686CF23F9B8673A37E5E139A25670A8 -:10CD4000215D842CEC5C41E16FA1F94323FE3E861A -:10CD5000C31BED31A5B56C7F4AE97E005D8DA9E36B -:10CD6000F91D4C0FFB1E9537E80FAB3B2043BB2250 -:10CD70005A3F09F94D3F8D9F0BFC73D9A9AA7DDB62 -:10CD8000778AE1ED36C14362EC5B1FFA27E6BE7D90 -:10CD900047F8AAC0E34E23D7E7F9FE1DB7D4170E14 -:10CDA000463F94E0D90A95EB12D18F72B6B227EEC6 -:10CDB000E3788EBF7ABC06FDDEADB2274D8689438F -:10CDC000BC658105E3DC70DC1E4CFF51F313FDB93B -:10CDD000B994D4A31E3341F0FF5552C5B54DE7F1C8 -:10CDE000278A9F5655EFA7F24DEA91349701F8E450 -:10CDF0005225DE12E28753316E097F0E751BF6D184 -:10CE00004CBADE6B6B450FF87FEE35B84F8C02FAEB -:10CE10007D5A268097D78EC95EA6772620DF9DF59E -:10CE2000CE19194C21B3284C60BF67FD90F1D73360 -:10CE3000D019FDF6272AB7BCE0AB27D543217E7871 -:10CE40009AE740BE9BEECB3D438EAF013FDCD45C06 -:10CE5000D7891300DFA74402F03DBD3617CF274B1B -:10CE60001F1110AF4F523842FB7BA6659C3841C75B -:10CE70007D606D0AFAD5667A8FE4039ECD9964B71A -:10CE8000817F6D7C1F91F855707C80D4A39D626674 -:10CE9000D923F7C07C8BA81C003B6B51DDF1FC8EC5 -:10CEA00090DF2478DCB4FFD280DFD8916E61FDC6BC -:10CEB000AB46B0B7CCA3F5607B4A37B17AA55582B3 -:10CEC000C702F858B71EF9CEBC2A81B8A03ED5F7E4 -:10CED000CCACDFA099F65BBF89B6A7F9F9D01EFAF2 -:10CEE000AD4A9C0E7EB4D263226B9F55FE16F0A510 -:10CEF00079B41D2D26F5558F607F0B3609248DF6EC -:10CF0000579495F19F59D0DF31D903E51F1DF8994A -:10CF100011E6FD201DAF13ED7F8E18CE87FAE47168 -:10CF2000C1B50DED4D2C4EB691D301F9A013A32F31 -:10CF300081E7B91EA8C8C3F78D3D109FE62D2FAF1E -:10CF400080758503291970042AADBD6A04BDEE2CD5 -:10CF500085B39FEA6D67781CDBA1C0196358C5A72C -:10CF60009A8C3DB1FDDCDA6CA4EF87890FFDDDFE04 -:10CF70007226874FADB10405D03F6417CAC9436B11 -:10CF80006E7D1ED67FE51519FDA357BA85D11E7B90 -:10CF90007E934C02748EAB3689C837CEEF64762010 -:10CFA00071B38CF9F98F1A317F68D3D431C00FCFA8 -:10CFB00053F8031EE66ECE37427E3EE5EBA618FC24 -:10CFC000639EBB98F10B1D7F98BF514BFFADF8C519 -:10CFD000B2318CBFEBF8C1E2AE1568E7D3F38952EA -:10CFE0006253F84326E4EB439D107F4B8EC904F453 -:10CFF000B912C9F5E046C09B9916F01453BA081D42 -:10D0000001BE762D28B803B4FC7B0FED190AF03B66 -:10D0100007F006BA589784FED479C1590857259E5F -:10D0200070FE462D3E2BF14BF7F945E255CB81A220 -:10D0300004E255D5FBE887142FE9780FD50A418B18 -:10D0400000F9536F3D3A04F32EC0C392E55C9EAEE7 -:10D05000B323DE7EF483AB6B002F1F7C42C0F993B9 -:10D0600080BF02E44AC946C10D76CCF94FB0F6F351 -:10D07000697BC0978F7EC6F087E2B11BF0BC64D39A -:10D08000FAB7B07E95E086FE3FDA320BE56F51408D -:10D0900024585E750AF5632A07300EE850404C05A7 -:10D0A0003C2F596D72C13E2AF8A2E0DF2999F9EDB3 -:10D0B00089D933702A6DB7C5E8C675EBF14E9C91DE -:10D0C00081F855BA5346FC280D307C3AF58A8878A9 -:10D0D0007868CDBD883F57B60971F02FD7D809F0D1 -:10D0E0002FC8CA5BF0EF6581E31FC3EBF3CB183E9B -:10D0F000E64239E0DF6B5C3F25C4A6D63B14FC5307 -:10D10000F0A92DBC6B2597E2E01BD58DA7C3BC967B -:10D11000AEB1E0BC732BF64C5F8E7423A37F3EB799 -:10D12000E207A940A7F3241687A1C071B1C4E27435 -:10D130005ACDE3D97263A7F6CC47378F0351B9981C -:10D14000097211E24A42749CDFEDFC25C6AF5DFE18 -:10D15000D5298C4B5CF826DD775AFFCA4E3B09A1D6 -:10D160003E1D44FE525C23625C289142C3A6AAEE97 -:10D170008F28F1160B7F6347F816EF36050B69FB16 -:10D18000E2D7CF0C447FF8CAA6B7807E02BF1298C0 -:10D190005D3E101E3815E22A2516F7A197BB234CD9 -:10D1A000CC5ED3B0276106E83FC28E03E84F2AAEBB -:10D1B000BE5736A9EC931E938CE3D27AEC9E0BDD1E -:10D1C00077F023C2FC260F50CFAF9CF5F732A39B1C -:10D1D000E25A19F5A2E21D5BD0AE57BAE32AC6BDEA -:10D1E000E6FEE61507C0A1B456D4C643ED104326AB -:10D1F0008CD7124F99187FD2C42595D4B07B1925AE -:10D20000D53CEE471717B3F037FB5E0F50D02C7CA0 -:10D2100075BB03E8E852FD3607C093F687F14493E7 -:10D22000B2E2C41BB5156754FD54CC38A34BF00FC4 -:10D230008A200F9AB4F1996407E35374D787F9628F -:10D24000D833157D65E12B9FBF0871AF0DBB3F7DC6 -:10D2500011E6BDE89FD75E84B80DB2DFE202FDA102 -:10D26000F4571F62FCA0D26EB9899F7F5EDE8E717B -:10D2700097573E36A1FE7765DFF974D00FAEECFA12 -:10D280002215E22997EDCB47FBC3B2D7723B921828 -:10D29000E75B2505BC0CB623EE53BF0F876AC4902D -:10D2A0008DCEF3F24913D2774BBC58F562167FE767 -:10D2B000E671623B63C7D52AF14D25355327DD0959 -:10D2C000FCAD86C9F19678A7B6E2C33EA0FB797B98 -:10D2D0003BF66D278FFFD3EDDB65F807DD9FE74C4D -:10D2E000DAF8B0CF6B1EFEC50B505613FB3E9942C9 -:10D2F000C76DC14B89DB9D63F2064D4037BBFF0B09 -:10D30000E3F060BF0ADD20E73F4F07BBE505B90941 -:10D31000ED814DFB4C2E88DB2ADEF711D2C795D765 -:10D320008E635C2CE1F1B35748CB0F8B77E43689E1 -:10D33000D22A3B8B2BE37087B833B703BFF3F832A5 -:10D3400086B74ADC59BC78B30F4D3DF8BD0B1617B4 -:10D35000B7D85D6F04F8ABE3D0842CD8A7539AF804 -:10D360003D65DDFAFE5C0087E1EAB8C978F17C5CD6 -:10D370001F6FD927C687AF6CE171942DF19184742A -:10D38000CD84781F26EF4A83C24724063D2A719335 -:10D39000F57A7A0CB62F5EB2EDF97E3B781C32310D -:10D3A000FB930297861BB1F9F1A79CBEE9B9E49201 -:10D3B00049752FE5217E2E51E2C894F9565433B9B0 -:10D3C000DBB083E9857A7A2EE1F676FD385FF0717D -:10D3D0004A6A0F0C04BED370700FC73786CF253B47 -:10D3E0004F19039C3F07D5FC19FA8BC14F4433EB0F -:10D3F0008F9E6363F657BAF36ACCFE2E49DE7B61DB -:10D40000FE97EA999E71A95A2C08C6E8FF32973F09 -:10D410002DEBB61BF15C253AACC87F96D9B34E3ADA -:10D4200093213562FCC2AA721EEFF0434F1AC079F5 -:10D43000957D1C81F9AC01F8A8CE99B2CB4F40CFB5 -:10D4400091D37C43E0FCA4CC572937261B4850BD20 -:10D45000FF5200EF474EECF17709E44BFD0AEDBDBA -:10D460008E7AC9752489F6579F2778409F6D8D67FE -:10D47000DAFE277B458D3D0C6CCFB0AE668F01F791 -:10D48000D36E08B9681562B7D4A7E141CE4DDC521E -:10D490002A8674A35FFBE9153BBAC13D2B07F1084F -:10D4A000506EF7B4DC6FC1FE9C4417671D201FC08F -:10D4B0007D481B67264EE23A0076096B1FD207FCB7 -:10D4C000D62E62F5C0FB0A1BF8BDC775763FCADBD6 -:10D4D000B874E361F75E143B91334BD2DC8B49F4B3 -:10D4E0006AF349BA7B900ABFC62B7414FE63F8BB7B -:10D4F0000F89F96CFD60AFEAAD9A6F620AF184A002 -:10D500007C820DE3996D36363F65BE743EC80F28A8 -:10D5100098D87CFA8703A087D379E9E898E0BD27FB -:10D520003ABFD3BAF969F4B8FBCC5C3E4844023E3A -:10D530006233D7130EE7666D9C698040BC81B305EA -:10D54000AEB49CF693214C3241DC820B4EC13D714E -:10D550003C5DBBAE2EF57DB15AF8C708F4171D36F9 -:10D56000829FDF2CC0F19974045C032048F54600CB -:10D57000C64F6D4A3E84FAA2AFE6389E3F17571F4A -:10D58000C77203E4699A94E0CEEB328890A7D6E69E -:10D59000E5A5F5857AB3D20C1ECC1F96808E26FBAE -:10D5A000D30C8360FA79AB0F8F22643B29EB07160B -:10D5B00025F36AEFE1A3DD00AF083AED48C07B1820 -:10D5C0007073BB92A70C10DE57D86E6DC97BCD94DB -:10D5D0002F6EEFD1920F40BE0A807F078CE73DBCD3 -:10D5E0001AE27CCCBED5663AEEE4CD06A4BBD111DE -:10D5F0001B9E3F48B803F26742CAACBE18F7A55B52 -:10D60000EC3CBC5E5B7C7C3B8F479EECF77BE0AAEE -:10D61000F7702E8F892B3C18EE63379A673F6F5651 -:10D62000D3E1E666B1079DDFF3B0F7B4BDB3C03513 -:10D63000AE0F9D9F739381C5CF9AFD3F87FABD9F23 -:10D64000F01BA0CA68125E2A001FFE4B32CE47199B -:10D65000A7621F3B5755AC31045722FEBA05906FA5 -:10D66000D1FD0BEBF6AF89ED5FED29DCBF92BA532C -:10D670006CFF6AB71C30727B3C9C5BB613CF2E30BC -:10D680003DED5A3B234FA2FB92646AAA807D95C967 -:10D69000F4BCC2BE08D7DFC4842B9F5F5B70DD7E05 -:10D6A00061EB8F06825EDF60F0F426517829F54E3B -:10D6B00098599CD864ABBF0EC6297D365C01E7DF64 -:10D6C000BD17DE433F70EF86E6D0403ADFDEA3B8F9 -:10D6D00039858FBBBD612BFA33B7031EBBC175EF14 -:10D6E0005F0972323E3C187EB7C0A3E614C2C70081 -:10D6F00079FA7D37BF4791532B78414E2499A81C66 -:10D70000A5E91FCDEC1C73C62CF294D9199D0D3DD3 -:10D7100024D08B73A619F03CE5E46974FD3CFECF80 -:10D720002C69E48BB29F0A1E11529900E79C02A754 -:10D73000FF2F5ABC7926A1072D1F7DF6F452B0EBBE -:10D7400029EDB6AD209EB9AAFBD0147FF668DAE5C4 -:10D750003F6A057BA8521FF032D63981B6BB04ED73 -:10D76000601C58C79EB3CD22C0BBBDFBAAFF5EBFE5 -:10D77000828ED72B3EFDF8B2D9BD22FDF77F9A15D8 -:10D78000BF23D347BCD17B7FFF047C586C0E3BA6E4 -:10D79000D1FD2DC9BE660438AC4CB8323296DF33A9 -:10D7A000DE3CEA6FDC6A03397D30628A798FA0AF94 -:10D7B00085E917EFAE98E1013FFC532DF704983C43 -:10D7C000CBE37C37AF577121635AAAB83130587018 -:10D7D000B9990F5FE8FC0AB27649203FF3894A5EA7 -:10D7E000323BC504D0479ECA1109C6A9B9648D7CD5 -:10D7F0001B0FF67207BC0B52761886BF3B4D7B0F92 -:10D8000074D2A85312BC5730368B8A6301DEA7D17D -:10D81000968FD7DD139DEC9DE5C9E3E5D7F0FF4179 -:10D820005CE7A4ACFB3C796A392155F6817D3EFE6C -:10D830009518536F7CB4053E3E84EB1B160A9FDBA4 -:10D84000619DB3563399747378E8E1A8874BDE5F26 -:10D85000E6317BA10E1E77DFA83C9C14030EADD7EA -:10D860005DD907E4A6023F3D1CEAA12EEA4DA620A1 -:10D87000E881F55218E1584FE118E07EAB7CF53EA7 -:10D880002BF3E1FAC378FE5D0F4F3D1CA97E81FAB0 -:10D89000C3D80176B4831D0378611C40E50726FADE -:10D8A000FDED5E32791A785F6834C619DE45105690 -:10D8B000E40DA12C0FFD322EE65FA1F29CE1C35FC7 -:10D8C00098FDAA30C2E63FC6CDE265283C4EEBE0AB -:10D8D000715A87079A738B7E9E6FC03F46C4C00FF4 -:10D8E0008E078B2CFC7C934EDC70FF7FD8C7439C4B -:10D8F0008C2FC4968FA323BE967E98DEC1DEE710E0 -:10D9000088BFE5BB8BF613F2CA18FF996B76217DB1 -:10D91000E4126F12BC07014186304F655E8305DF5C -:10D920000F2D29F07ED3D824F5FB10CAF8CABEE427 -:10D9300072F8E592C0013887E612E933F5BA95FE30 -:10D940002A2C5CCFEA4EBAA39F1C8CA143A3FD29CD -:10D95000EB4B4A22217C3F4430E33D27FA5FC0D89D -:10D96000213A9E123F9A689F526941BF4E196171D8 -:10D970001221DCCF1C5E9EC3DF6922E6B8EFF29075 -:10D98000AF13A2F37BD12248F86E029FDFE5A3E636 -:10D9900000C46B3C26F8B7021C1A846303015E5472 -:10D9A0001FBB05EFE9EBCAAF9D3C5C02E5B4DE3C72 -:10D9B000ACC7D7B5506476327AFEC7F7505AF371C8 -:10D9C000664FA3E426C1FC15FCCFB132FA1E4FDC32 -:10D9D0005DF1BD34E297203D6C61F7D0EE3EF90C6D -:10D9E000EEDF1FAC771F057A2B204109DFF9716943 -:10D9F000F1B04D3CEDA33FFFF2775DA4A67480EB40 -:10DA000041CBADBD408E29FAC27B16DF6F61BD07E9 -:10DA10002D8C3F9FF60E7D17E4C2ECECC12786D01B -:10DA2000D460F6E1BB0B0F035E517866015ED1B6A0 -:10DA300007A1EB4E88574761DFE6ACD5E19599D950 -:10DA4000D36653B605EBC8592B7FA99E570BBCB8BC -:10DA50005C6C4B3F2487A9429F0AEF2D30FC3C6849 -:10DA60003105406FCB798AC547CC21FE172B057C49 -:10DA70000740A3AFCFB530BBF7DC9F5990CE69E329 -:10DA80004D65E0E7B2F0F71CFAB077775AC6AB54B1 -:10DA9000B5877D37A7221ECEE5FEC3B3023BB7CCC8 -:10DAA000B5E4B37BBF1BE566353EEAC78FDBAFAE9F -:10DAB000DD4181D9490ECA6E8C0753DA5DB1303928 -:10DAC000DE6CEEBDC97093FBE0F3CC1DFA4B49D17F -:10DAD000FC398B65462CBD40E9AFE55CDE729E30BB -:10DAE000AE39DC357A9E3094CB47B4E709F9C8BF2C -:10DAF000729EB03F2D1F594DDBBF6DF3A55A617C5F -:10DB0000C9D717E0FE1CD70FA926D3576D974EB57E -:10DB100032FD3075790E393338FA3E9B20D199E0C9 -:10DB2000FB1AFE729037D20C82FC9FF2998762C575 -:10DB30000525DA733A5B8746E9EF2983BBAA92C5CC -:10DB40002BA0BFD7B77C36EA7353971761DA78FA00 -:10DB5000C62D4087391C9EB75A995E5A9AC0E84331 -:10DB600010FCB7427FF55ED10EFED485B522F7D703 -:10DB7000B177ADA64E1053E0FB19B38CE7C08376A6 -:10DB8000B6AF67087B9F26E7B8C95743D31B247BF2 -:10DB90009C55A5EFDD2079982769A9E8BF56EE2BA3 -:10DBA0009E21196CBE6B997FA0796D06C6311F94BA -:10DBB000B5F6A85156A60F8FB2B2FD9DCDDFB103C9 -:10DBC0007C82F724664B6EB40FCE8E18D93B6A74F4 -:10DBD0001E886F166D3FF956163F91CFE13F1BE44B -:10DBE000E460A8A7EF4762FD73BCD5C3FD4D4BEEC3 -:10DBF0005880D30DE21D6745BEEE96003E39430EB8 -:10DC00009F04FED6363F0F08C0CF4B6F08A1EE60D1 -:10DC10002FAB91F17CD6C0F5FBCB35875267D3741F -:10DC2000F1AEF71D700EFC9E95E95397A57A7C77AF -:10DC300062D16B22DE9BA6689AFA3D6C3F6718BBE7 -:10DC4000F7C1EE2D2872EE8EAF7A76F5613D76FF44 -:10DC500040D1AF72CD8120CCEF60B98876292A07F8 -:10DC600035EF90E4D7B07B097ABDEB11ABCCE3354F -:10DC7000D93E2E73B171E2D16D4EC44A822ABACD1B -:10DC800091DC12CC3F27E220410AF7CB17B66E9801 -:10DC900048F13C9026E3398F1E7F0EA3DEA7F8C122 -:10DCA00003344FC739CCD773A466EA34785FE52DC7 -:10DCB00052B67A00AD9317F6273322A6A7B4615166 -:10DCC000BD2BDFA5D5F7F4FA6041DDFAD5F0164B90 -:10DCD000037C80F1CD268C236EA5279AEF8EA91F99 -:10DCE00012B21EF1F08ED77E391EDE9FB8E3A2C1BC -:10DCF00005F39B6C7533FB62CD357C1FA18484A634 -:10DD00004379498DE80AD1564748CD6D201715391A -:10DD1000AEC02574E390D903FCDE22BA56C23ACDD8 -:10DD2000F7D820CE626463FF64906707CD32DA21B2 -:10DD3000732CBD6D7354F87C3099BD1B7024B9A74A -:10DD4000F6BB79C36D20D7F6F0B8B5C3E7EEB7855B -:10DD5000B1DED464D4CB1439AED357157BD7D8DE1B -:10DD6000628BBD4BADE71271D3B3165A3EFE561906 -:10DD7000EFBDE58599DFB4951CBFE15FCDCF239A58 -:10DD8000EF055C3F6825D7A370D6E8A16F58B95E50 -:10DD9000E9260340AF0CDDD8B010EFCBD625B8563E -:10DDA000A23D81E92D8D678B374C80EFC744661FFC -:10DDB000B921221D1DDCBFB07B5845BF5422E0BEF7 -:10DDC0005D1F74F5CA9B745FAE7F62F504E0B354C7 -:10DDD0007D5B6CBF5890C329D499D9D9039DD93B99 -:10DDE00018ECDC7957F4DCF90EF001784706C443EF -:10DDF000DAA65346381F5FA6AA38E2175D34E0D78B -:10DE00005DDEB0A8BE7F738AF3DFC956EFFBC01F8B -:10DE10000324A70B55424891D59B0D71E04D938982 -:10DE20006B2B5DCFBE0B39824CF3A3B66578049A99 -:10DE3000DF0D8A25F0CDD7C420C493EC867B6BB46C -:10DE4000DF05F595C60C3A6EA04644BBFE026E1F78 -:10DE5000BF2007D21355F85199C0F8C905D9FF0B57 -:10DE6000E8E7C2C726B4775FF8C41A53AECE48605D -:10DE70007CF74D2ECF3213DC980F35EC7DAB339D04 -:10DE80005728E21A04702FDE7155847793EEE4FA76 -:10DE900057E1B3F5ABC12E33715393047CC71774AC -:10DEA000E583489DB2C323831C9AB6D327839A3D4A -:10DEB000BDA60CE39066D4561E81FCFDA16ACCF78A -:10DEC0004FF047002E77AD6D3A04E8D2AB9248F898 -:10DED0008ECF674CAF4AE5F3E811F11C7422366728 -:10DEE0001B00BF5BC67FA25E02D57DE26A363EEDB7 -:10DEF000CF9040D77D5759532EC8B5F4E5ACBF74C9 -:10DF000072A0DCE98EF63BFA46BDA0B617BCF898C5 -:10DF1000AD88F15B06F7F4C73B6FC173197159F116 -:10DF20005D454E4F398FDBD00F70FD07CC0F707DF4 -:10DF300010D3A7AFFFC0160CC4D0A7A378163231F8 -:10DF4000FC52F08D9859DE6B067CFBFEF36556A003 -:10DF50009B649FDBA88E3FCCD950D8EF6DE8DF6281 -:10DF600042BB5CCB78EBD97810880B78ADC8B1D9BF -:10DF70003AFF4B940F30BAA05D04615C2525C24A7C -:10DF80001751E749280DE6939EC0F85C95D13D13E3 -:10DF9000C6ABB29A5C30DE6C736F23F0AD16FB2615 -:10DFA0008F4F1BC9F5CB7D170E26C1BE5F1F549E38 -:10DFB0000E7A73C8F073E4536DE1DD4FACDEE10916 -:10DFC00038CF00EAF94AFD3DE7ACFD414EBE69603D -:10DFD000714FC433AB3BAC5769378DA7BBB99F4E6C -:10DFE000A193E47AE2DDD21F41E5DDAD82C7A4044E -:10DFF000468F4ABA5B7607189DB1B8CEDDF690B968 -:10E0000027D0F39E9E984FF6119B07E2586A7B7BC0 -:10E01000C05F43F9C0A404955DEA4ECE1F92EB9B0E -:10E02000902EDB7B1E18C6E11B92AA397D11E453AA -:10E03000405F8C7F87BAF0F778D0FF077C83EF4F83 -:10E0400027210DE3C1719F95752773BEB08CD33D19 -:10E05000C001CA4B795E295FCCE1952FF677AAE320 -:10E06000C75AC9F5E56904F4C7FCE59D312DE5F310 -:10E070005D605E8FF6D205C9EBD14E9AECADC474EB -:10E08000415E257E4FDB340BF163C1C6D8EF8C1D9A -:10E09000E57AD9E50B06F69E94C1DA19F04F297F8F -:10E0A000C72A737EE97F1CF0E162CD86E707BAA339 -:10E0B00076DFEB96CA89F703FE6F135DE5B03F5537 -:10E0C000F9823B065EA9E107F02AADFA1CFDA62500 -:10E0D00024CCFCA6DC2FAAF84F83558C9F5EE4FA73 -:10E0E000599155AB57562618383FAD1F7F3B1D3F02 -:10E0F000D4DC2B13FC4121292C4A6CFFD06E047C0C -:10E10000D885F8FE74FA638047821DF51EE0ABBB2C -:10E1100054F8B170E7968ACEF49F77DD60F77742C6 -:10E1200012B1A9F9B782270A3FD6AF6F2BC75F0597 -:10E130000F4746E5D4D6046E1FED49FB2D59DF8C01 -:10E14000F6D137147A067C037A5EABE0DB20037BE2 -:10E15000374D4BC7C3BF23FEBEE79917D2D1FE9000 -:10E1600045E916DE5903BA8E8117BF6DE103FEBD86 -:10E170000931E4C145C1FF8BA49ED1F67BCE8DEB66 -:10E18000375BD5CFCF389E5F97FDDD5D31E01585DC -:10E190002BE90CF850447706E04036092E75DC7BFD -:10E1A000F22666E7AFE7F055BED7EBE03D3AFABEA0 -:10E1B0005C3D8377931144765A90E905C430AE33C1 -:10E1C000C8F90556EF38B4B7AC37107C4F55C84185 -:10E1D0007C4FAE7AEEDC574320B5F440BF09711B8B -:10E1E000008F163CE5C6F3E0CA972C8897E71258D3 -:10E1F0009CC4CA2A99E1A75C89F875F193E2EEE024 -:10E20000770950B9DE3B86DCF9AD4E9EBFCAE5A862 -:10E2100082773DD631BCAB92BCD644155E6E27DE0C -:10E220004CE6EF6772251E3E46F1C83548C1A3593A -:10E23000F47B8FB56111F68BEEE335A0DF9EEB9A90 -:10E24000909FC5DB47C5BFA6ECA7C2E787DBB4F745 -:10E25000FA641B5B4F729C7880A89CD3F26578FFB0 -:10E26000CF36544B0F70E552594F23874B3CBA9829 -:10E270006363EF3E57FC75C38340CF15EBAD9E95AE -:10E2800024EAA751FCA7CA3C3ADA048D3F47EF675E -:10E290006934FB536D2ABC023FA01BF93DF3AB2848 -:10E2A000BF8760C93616E7B4078A808F9CB506D54C -:10E2B000F7776F958857CAA470B565E0BA6F0516F1 -:10E2C00042F3C9CB8DA4173D775D1F71E0B083D6B3 -:10E2D0009FD0142EBC9D2E718F313C6D12D87D893C -:10E2E000B718F40CB4D103FE37B07E89AB5A33CFE4 -:10E2F000811CDECAFE54FC754E5A2C3F8002C77842 -:10E30000FB3287C3C3C9CBF5F46FE1E59FB69B7EB3 -:10E31000034EA0DFBB48A01CE22FE8011DE3D65A44 -:10E32000E8971ED8A1FF029B967E957C0CFA2DB033 -:10E33000A9E9371266F4CBE9D459257B63E92DD3DB -:10E340006DEC9CECACCACF0679E4F461D839D00D01 -:10E35000D2FB024AEF40C701A0DB8E004F86673D2B -:10E36000BC9518EFD8A38AE9E3D713D97A17DCE96B -:10E370003D00EF252FA0E7018156ADE4F41E1FEE0E -:10E3800021A7C0E49B13F8CC5DA3C2B92087DD6050 -:10E39000EFE888BFFA023765F428120CD17D77DFE9 -:10E3A000208C7F7CF2C2838F01DF586FC37B4F8A42 -:10E3B0005C4A4DF017DB86C6A76B8A975EB0572D77 -:10E3C000F9C2C6CE8D71FCE2A3971B48AF24C4F3FB -:10E3D000A56A3C1FED6B1201AE4909FE34399190DC -:10E3E000D5B69C31E66E747D1954EFA5F9729A5F2B -:10E3F00007F6B70E61C2F315B64EDFDE5EB77A9D43 -:10E40000F72DB0D7BD94E05D09EB82380048EFEA04 -:10E41000D224227F6BA75FBF14EC77743DA7EFE98E -:10E42000F7D22CFA75F67DBE0A2855ECC9C3B93D62 -:10E43000B9B46E10DA995576E50DB0FE7876E5B68A -:10E44000C67570BAA7F88DE73F47569308FC51E1AF -:10E450002B5B6C1D383E8709BCD7AED017F025D09A -:10E460007795F802B03BDAD15F11447C85BC333339 -:10E47000CA6FD6551A62C63F55DB6C1A7A51F82915 -:10E48000A9FBC7EB8F29EF2C32FE5AADE6AF5595AD -:10E49000A75399FECADE2D5BCA6D001B567AFED8C3 -:10E4A0002B397AEF7984C91880F716E981CEED52BD -:10E4B000C54F0A7542C80E71795FD222C0A32F0DD5 -:10E4C000986EF80F5F4106D8594E1A90FF96F07B70 -:10E4D0004D59DD09BEC353CBEDA3D9676C5EF0FF88 -:10E4E000370A66E49F8DA7AC0190AB8D7603DACF37 -:10E4F0000FEF33215D5CEB65E5F68FA0C64EA2F809 -:10E5000073AE1D9B9304FCFF79EED77CFEBE5BD0FF -:10E510006EA9D8732589C2BC0384E9B07B9939CB35 -:10E520003BA3BD55B1EFA69A67092C8888F52F99B2 -:10E53000D9BA5225BF00F6F12D6DC43F9CB1191513 -:10E540003DF82F00DFD227C24638E72A7AB022AF43 -:10E55000BB37F438007110DD0B98396D4B83C10067 -:10E56000EBDB42D12831A3355EB5E04FEB38838B2E -:10E570001AB9B486C519B4E479BB5FF03883D167A2 -:10E580004FBF8AEFE999FD1F6BDAE5A75863BDD34A -:10E590003D7DF963D83E1EDE4F37B0F779F4DF13C7 -:10E5A000EC9C6F4B655DF07ED4DFBE9FE08E61C753 -:10E5B00099FED7D9F87B24F476B7E8F8FFE1C9A330 -:10E5C000FB26DBB9DF2F9DA4835FAD2D3FA67EDE4A -:10E5D00027647FB758F2491F67A78CD7BA3D3B978E -:10E5E000B5D43312FF2E1BEB3753D5EF283BD37F27 -:10E5F000A60B04E3DFC95704E5B4822714EEDDED72 -:10E60000B47CD83B67065BD1CFD324021FB876B267 -:10E610005757F4AFC739872AF321C4DF3B561CC7CD -:10E6200074788727C6FA46D8997C9E2E333F85702A -:10E630005F6FB40B4CB7980475DC7E6F65BF74FEDA -:10E64000D88396E178BF11ECF9B1E0A7F7D3F606CD -:10E650001FEA5006174F0C7C52FC820A9C2BB2BD5D -:10E66000D912B3A7E13DB5642FE39FC90504FD6B43 -:10E67000C3052FC263BC3D03E7B785C7C75D3BC673 -:10E68000E2598765BBF1F73C51393116E03A9A847B -:10E690005F35A8E2AD143CA97885CA638DBD31A071 -:10E6A000394F27723EEC82F72654F5DC4F000F8875 -:10E6B000CA81AEABCD9A7CFA321791547222D19BAB -:10E6C000A6C977F5B9AC708EEA5AE0D6B453F04ECD -:10E6D00089F7C39F6458B70BDF3DEAC0E7335CF0AE -:10E6E00023DE005F033BF202BE9F74BDF371BD05E4 -:10E6F000E16B6ABC51D6DBD6BA4EAF70232F3CBB60 -:10E7000082CE97F28539EB32CAD310EE2E02E78B18 -:10E71000732BCCF8FD61DE3EF1D959788F3671B597 -:10E720001BEDB889DEB2B7E09E4F62991BEF15CCA6 -:10E73000AD1404B0F7503E83ED36AF7061AAECB76C -:10E740008B960BB6E83BE3F1E4D75A7BBBE5D75A8F -:10E750007B0CF965307BDE06BFFFE23AD10D78B164 -:10E76000AAB003DAFD3654B3FB6E87EA58DCDD86C7 -:10E77000E94C8E28E35E79CD89F2E28AF2FB54BC43 -:10E780005FA64EC178802F5381CF6EB3F99FB7AB90 -:10E79000F8E586BAA116FEFEB246FED01F17DC7F52 -:10E7A00040DF9C007AD2A0B5524FA4FB1761BE6433 -:10E7B0005E78B0A527E0A9FF7D78A7F4DAC9CFD2AB -:10E7C00061FF143F9FE20754C651FC8482E0DF6E74 -:10E7D00057F1A9D67E40ADFF4A7498314E374B644D -:10E7E00071BA2A394B601F57813E48F16CD5292BED -:10E7F000C263D5578CDEE83C5F85710EDB8721FE56 -:10E8000028F294CE73E0BB243ACF524353BAFA9D18 -:10E8100052D53CEB6E3E4F5D1C2B9F97689770BEA8 -:10E820008DC4EA8179D51A3D27FD2067AF58D19E66 -:10E83000D7E8BDC302EFCD36923B2CF00E6DB5CDBF -:10E840007F14F643ECD6E4003DFB50DDE0BE30DF44 -:10E8500078FED8265BCE31A84FD7F7474847BBC2D2 -:10E86000D77EED8EAEEF267EDCF7A1FE3758FF5F38 -:10E87000BEC9FA4BE1F767300339EA5302E7BB7AC6 -:10E88000BC12EA0E7C01F143947E306E33904E82CE -:10E89000AB289C2A0630FC227309FFFD395A3CD86C -:10E8A00066F335C07C14BABB097C9A609D1B6DBEB3 -:10E8B0006648611E700F84F299CFB8BC7AD568881B -:10E8C000EA5149498C5F3525128CAFD1FBC913ED54 -:10E8D00053FE01ED52FBF80557FF6F84E792E3A664 -:10E8E000F00B615C84720F7531F87321BEAB466E1C -:10E8F000D0FE9E1D2D1CAA6D3E8703FC3839EC3DD1 -:10E9000039C02B78FFED26F0E8E04078F85320B5C9 -:10E91000CB145F002859B3D200CE8D666F2AF895CC -:10E920007697333834BEC3E0B0E7AC01F1F839D2A2 -:10E930000FE92ED3D0FC20F44FF9477758D7A8A67B -:10E940006A01CEBF1D8BDC06E0B35D9A3CA2E1E616 -:10E9500078DBD381FCDE7F8B83EDC352D887C1C7C0 -:10E96000987DE62678DBCF91F28DE03ED891D27E7D -:10E97000FE42F16AB8438557ED8D9B12F8FD497D43 -:10E980007FF43C84FE83037B4CC88F4A76B3FBA2A2 -:10E9900025FBCFE3B9BB64AF0991326FAF85DD7B57 -:10E9A000A861E557B263C70178E1978F817CA87EA3 -:10E9B000C4A395BB0166AFF436BB7A8951BF6AD256 -:10E9C00004768F60158F4752FCAB0E8E6749DD7C55 -:10E9D0005E902B49F904EF13386C2CAEB0F57D0135 -:10E9E00046B729BC9DCBE51600DEFAFB0329F09E55 -:10E9F00034F38F23BE8806AB07E47E5281AE9EAD12 -:10EA000000FDAF29BAFB06F31DDCFF6A2469C0478D -:10EA1000AA2DB1EF097DE650F43A2B9EEB243EAFD0 -:10EA2000C376237BE7C56EC6752F49244985989721 -:10EA3000509EEBFB69C12BAF41730F25A9C0AA798A -:10EA40006721C5D74193EF38A3B3A67E277F0F4D2B -:10EA50007997A27E9AF26E65999A7CF7E57768EAD3 -:10EA600067508453E77BAE1DA7A9DFBB728A267F60 -:10EA7000EBC6FB35F5FB06676BCA6FDB51AC291F94 -:10EA800050BD4493BFBDF6314D7D318E9EBD87C3D1 -:10EA90005954F46CFB103FDE3BB29B0593EA3CF704 -:10EAA0002CAF97ED284803FFF76AFB9834386F1EA8 -:10EAB0004E1CE60CC7E85749BFED396CB743D0D8B8 -:10EAC0005773B8FDECCA41CA45E0F7591CA27880DB -:10EAD000BFBFC9BFDBC1F5A9596EA8CFDFB5903C58 -:10EAE000B88EE90E33DAC5F4FD3FEB706BEC758A36 -:10EAF0005E2F1A3CAE42213EBC3E6B27BCF67E47E1 -:10EB0000F03AA18B1752CE6FFA76571DCC7E4AF998 -:10EB1000ED07C00F5BCE69A449F4E139EDB32B01D9 -:10EB200002FC94A0DE124F0F50C61704DF5FA11F36 -:10EB30003D3FF52D9FC7CE99062FDED78A777EBB46 -:10EB4000CAD71F3DBFE5CFC0FD48346AE0F4B71611 -:10EB50003AF76ACE6FAB1387E1F96DB5EC4D6BCF29 -:10EB6000F9ED6FC0938602DCD9BEB6ECA7D1E3669F -:10EB7000F73CB5FA4B6B7D9BCA3FBACE0DA0C709D7 -:10EB8000A0972531FD7B377B0F4019B71DFAB6E4FE -:10EB90006C87BE6D229EB59288FB657532FD7AA9A1 -:10EBA00045FC56FA7592F31BC8BFF7640FC6FFBF4A -:10EBB000374124F02ECBB582E1788F3A1E3E7EC0DD -:10EBC000ED2FEF39197CDBB25FBCB7A2E8A6F72FB7 -:10EBD000DE1BCBE22CA7E8DEDF1DE164783095A7D1 -:10EBE00014406887B8FCBA1DE3E52F8FFB107F6FD8 -:10EBF000D2E59AC14302F87BC23CCB20DE2660B34B -:10EC0000A37D6FCAD8A143CAED2A3CE2BF8F2CF77F -:10EC10008D771C60BF99B2AB674AC0161F7FA6F202 -:10EC2000F511297C0BC653BF79117F5FCD943DBD93 -:10EC300053987D511B9FA6B7FB4C595E82F8A6E402 -:10EC4000174708C6A3B5E42576DF787144C2F8B546 -:10EC50006ECE96F8F6F49BBD9BD65E78EABF2BF09D -:10EC60007C6FEC45766FDE125BDF58E1143476245E -:10EC7000FDBD9578F731E6F1FEAF158CC0FBF7537B -:10EC80008CEEDEEDB1532970AABF713E01F8C27E51 -:10EC9000B80F13A3FF879C8C9FEDF77E920466E963 -:10ECA0006C73532EE07F36B783C788D75F0A7434FE -:10ECB0003A52F09DC4EB3FE1D4C6EB1738195FD14F -:10ECC000C7EBB775DF68B231B67C9BC1E14EE1F7A7 -:10ECD00021D0EBD2CD32C6FBCDA7730880FD6D8B62 -:10ECE0008CF6B7F76F9808F841CE6F927F09F169FB -:10ECF000459B7B6E7E96E68BC69AD06F337F0B7BEF -:10ED000087848CB504C12F5BB4E5D1547857FC538C -:10ED10004AB78BA8D2347FF373180FF3FED9A7310B -:10ED2000FEFA22D033FD5EF4D593D301FE7B8C95A1 -:10ED3000B70DA2E9A29D82E6FE447195459357E284 -:10ED4000FE94FD2342F45E859BCA91979CDAFB53A7 -:10ED500083A3FEAE979CE8EF0A639C7CC904767F90 -:10ED6000EAD039767E3FD28BC50586C6DE5B388811 -:10ED7000AE636C0A7BBF451F4748C03906EFABF056 -:10ED800038DFB11F4B2DF75C58B9D796AFBA3FF0BB -:10ED9000D68A32DC97B13F637693B1192CEE3D6E83 -:10EDA0007C615AAB7B007D406EB68A2B8CDEEF39DE -:10EDB0001D0B6F0EE9E8FAD039164738EF187B3F84 -:10EDC000AB2DBEF9019FF7FB67FB3DF06B0A8FF798 -:10EDD0000B18177FFFC6DD6BF07D1A9F40209EF356 -:10EDE000FC8DD8F7C8529C8ADEE46FB96F03FB3301 -:10EDF000B560414B1EC8F21EDF239AFB38EDE737A2 -:10EE000037E7274F3AD93D4A3D7FD7E3FDFF29FE3B -:10EE10003E65EC9174B89F4FD397F09EFE2EC61FAF -:10EE2000F574AEE7E733747C30CAC70D9A78E319FE -:10EE3000C00786AAF9B911F9FCFF00D1E7EDCB00B4 -:10EE4000800000001F8B080000000000000BDD7D2B -:10EE5000797C54D5F5F87DF3DE2C496692C96412AD -:10EE6000B2336189A088C3BE457D098B51080EB8B5 -:10EE7000A1824E02216C21816A456BBF1948C08076 -:10EE800060635D8A8A76A041D1A20D8835D6A01331 -:10EE9000A5086A357EC5AFD62A0D82088812412D95 -:10EEA0006DA5FCCE39F7DECCBCC984A5B5FFFCE26C -:10EEB000A7BDDC77F7B39F73970914319DB9190B80 -:10EEC0000CD782B50A631BED7EB33395B1A1F66012 -:10EED0004A2163ACCEB921C13F80B1941476ABCF47 -:10EEE000CED869FCBB3C9C76D88BE2B0FEAFE2FC8E -:10EEF00076E730A8F75666114B646CC8DB4D8A1F65 -:10EF0000EA1F53D8B4A618ED4EC5991883FA5BCD05 -:10EF1000BC7C2BD61B102ECF74169E8A837EB7D94D -:10EF200020857A8CD99C07FAC1BC988925A98C9533 -:10EF300028FE4C1CB7D2D67E5F29942EDCFDBD0581 -:10EF40008AD843167FBA3614D69369F16ECCEB3A61 -:10EF50006E1F271F376D4911DB3F8431AB8D05E2F2 -:10EF60000633A6682C601E8CE3F8979AA0BD368DF8 -:10EF7000B155008F3D3037ACCFFAA59B581A633F8F -:10EF8000B131FA0B14319C0C0B7C161FAC85714E01 -:10EF900031FD425CFFBF987E11CEEB13A60FC0BCC3 -:10EFA0001CB74EAC533331FF9618F028772A7C1CDF -:10EFB000E6CBF739205FC4FC91F090A9CFA951BDF1 -:10EFC000C2876FCC6D87F2CFF7DD94CB20DDF1D017 -:10EFD00088A4F618F565FA8B9A6AEF38687A6F8D0F -:10EFE0009FD224C6749CCF9A9A39DE717D187342E1 -:10EFF0001EE7556EF1E52747F433C499CC18AC27CA -:10F0000071D4D6B65E40270756AB4EC503293315DB -:10F0100063FBFDC1A4E26D03783BB7A11D9FA70A66 -:10F02000E4C57AC3BAEDDA3FDA05EC4E335C2FA3C0 -:10F030007EBB5B67B9C09385796DD8DEF2D9553652 -:10F04000D60BFA537427E6253D8C8211901EEEC133 -:10F050004FA3605CC57FAB93DAE929B2FC741E8EC6 -:10F060005F4C79393ECB763196D13DBC98A2CFC268 -:10F070007E0E31BD1CD3664BE02227ACB7399ECD46 -:10F080008945CFF3117FB09EFE4E412FCCEE3C78E8 -:10F0900091180FE6F76482BE10FB3966F355637A68 -:10F0A000595647AD8A7413E714F5DB19E21DCA6F90 -:10F0B000C77296DECEAE06785F06935D05D9970FD0 -:10F0C0007DC63C00A7C48E03CC03E32722FE62C0AA -:10F0D0002D2199C3ED0F8C15C7E63B4E670131CF4B -:10F0E00046E017933BCC2F4F41BB2D0390EFFC82A2 -:10F0F000EFF4AB503E34FED2A5AC82F25EBAC784C8 -:10F10000F4E16E637A10E121E02EFBFFC469A17E79 -:10F11000910F9533F0E143E7C9878DBF9C648AC3A3 -:10F1200079DEC5BC7D3D58EE596683FC138B9DDEB0 -:10F130005590EFBD1A080DEAE72C89DFA042FDA02B -:10F14000E0A79E0FB26571503B6F5D8786F261D27A -:10F15000DD6D9A0DEAE7D5B56B289F5EBAEBD15C01 -:10F16000A4ABC39F5FA53AB0FF6F64FF0020E0F738 -:10F17000314E8E4336B2B427E2A709E79D1AC15734 -:10F18000F1FEDF22BF5F56DD31D60AD57297300D12 -:10F19000E5E561C5FFEB94DED86FFCB4E000442FD9 -:10F1A000A7B7970E1EE95F06F9ED92DF95A24C9680 -:10F1B000CE5841A399E059D0F8D02D08EF82C62B44 -:10F1C0003405AA3CA185140DD759AD6B01C8BFEB1E -:10F1D00034D3F8873F9FD753C1F9FED9CAFAC68006 -:10F1E000EF9BA2FF2681E7972DB1E97667A7DCE1C7 -:10F1F000FC34862952BEEE443A04F99AD81BE0B199 -:10F20000F0CEE3245F9F727A68FC27B4A69D993400 -:10F210002FE60DC0A7799BDE23792FC791F5E66F06 -:10F220005EBF02EB65DFE61CA47AB05D7B1CD2CF2B -:10F23000F7711C5FDFDF191F5CAA10FD0FF25D1C68 -:10F24000830F59C86A4A270CD878AADB4C2301AF30 -:10F250001D1D8528F7A0CB65C89757257B681DB273 -:10F26000DDFA0E673CF2CBD9F4C14181CF73A5C35F -:10F270003792B9DC0A74D59B47115EE7A1373B840E -:10F28000DE3CF16FE94DA12FA5FE94E54A32C7E7B8 -:10F290003DCE6EF5A6923CACABDE74B3E0BD03612F -:10F2A0003DECA8C9BB91751D3720E4DBD178DD9A10 -:10F2B0000C6981C27C386EE2D1CF98122187160B7F -:10F2C000BEDE2AE9C0C56E9D12631D95A23FD3F430 -:10F2D0000E4B3BF6D3A210FD775DAF85EA815CEC67 -:10F2E00081F3BEAC27C84DA5ABDC8C818F5CAC9F95 -:10F2F000F5B6FE3A12C9E8E4C60440FF99F0D10B16 -:10F30000EBFF2A4EEF8DEB93F01F7C5ABDD537A053 -:10F310002BFC2F1470BECCA1F7C7767F137CD61DB3 -:10F320005E4625737BE6AA648E97AD0E512FCE58AC -:10F330006F6632874B45B2912F23F0372A3986DD2D -:10F3400023E5F0D1785F0196FFE1D0D604A42389AC -:10F3500027297FA2F115E6B3A5341EC0793CB68FEC -:10F36000D63FB27DB41E0AB70FD0BCD7231D21BF34 -:10F37000211D79B89E583F203C3F49E77EB1CE1F02 -:10F38000E2F52908BFE8793A8F9A9433CD33B9C3AF -:10F39000AD20FF27EB4E4A5F3E6452705ECE0E4DAD -:10F3A000C17939857E8CD683202E045C793F6F0825 -:10F3B000B9B1E2AB99E988E71585FEF46AA83FD9AF -:10F3C000A1CF4238DCE3D4CB717EA50E7D36E64F6B -:10F3D000C571FE1F95ACCFC1EFC9C28E8A9E67B5BD -:10F3E000C01FC0B30AEB258E6301D487979FB40773 -:10F3F00041C4020860DEA01F12756711EAB1C4752E -:10F40000CC8B749A92D0D16A857CC743CCBB01F275 -:10F41000F9018FC98AFAED367D19A62BBE52C9EEC5 -:10F420005C51C882CBA81F6E87B2BA5E41D2DFC0E2 -:10F430006F91F4BA4CC079593297736087D42473B2 -:10F440007E5A9A1C6187483EEACEAE88E0C3FAF342 -:10F45000E4C35FE078E7C1870F083E7CF05CF8F01A -:10F46000B1301F3E8AF5CFC687CF083E7CE32C7CA7 -:10F47000B85BC0ED5D513F061F3E138B0FDD821E52 -:10F4800024BD231FA2BE0F2577CACFDFC5A2F77305 -:10F49000E0CBE6E473B00B3BFB3B47FAEFCEFE1B41 -:10F4A000E33AB3FDB7C7EEA4F5487E067E793399FB -:10F4B000F48EFE16C205F8E56DCE2FB1F9AB53DF21 -:10F4C000747039C1584302D28F9CE7E702AF00AF96 -:10F4D0000FB01FC967D24F91F0EBA40761F71E155B -:10F4E0006962C7670CE502C06D6F24BD3E25F82533 -:10F4F000309211BF8047558476E54B47C18E44ABAF -:10F50000CFC5E75BB0B6ED756475A635244C757450 -:10F510000FA72217B773BA83138C7F2C963C6D41CB -:10F52000BCD9BBDAF3D1F8FA44ACC7E952CE88AF04 -:10F53000B3CD43C20FE77109CDC3635A15A1E7CD1F -:10F540002E45F2B7E682F4F2711D2AA3798512C026 -:10F5500085EA94A72C1BDA0FEDDADE1E6E6F77C1F9 -:10F560003C2FD7A1FD80707B189FE45DEFDB409EB0 -:10F57000919DAC9B503FADC8E3F4104DF78D683FB3 -:10F580000C88C0574326E1EB3E9B3F13FB6FD43CF6 -:10F5900026B4EB1AEB9D4A80F0581D8FF463B7EB4D -:10F5A00044B731E490C7757E72A88F8BCBA1BEAEF5 -:10F5B000739043035C9D72E822ACEF3C8B1C1A23D2 -:10F5C000EA17B8B87CE94E0E5D26EA1509F8C69030 -:10F5D00043635C31ECB96D369DFA8DC1A79763FD2D -:10F5E0004CA7AEBBB85E2B7445E835683716F3F709 -:10F5F00089F6AB1B4CFDC87E66F1DE587E86CF6572 -:10F6000037D829970AFF81B5FCF3F7770D67AC0A65 -:10F610008BF83C7DAED4B03FD1D8F0591AE21FFE32 -:10F620000C7195079679DFED83787B476568873E97 -:10F63000F03FED168477737CE240764978DCAA7F50 -:10F640000041A6005EFE61A254E27161CBD2210CA2 -:10F65000FC88C2FD3FE4A25D796CDF3F283ED261A9 -:10F660002FF3E3F83BB6F338C989B767A6A07D2E20 -:10F67000C75F8CF882798D5707348560BDC777598D -:10F68000BCA86F55E6F95501CCA76A979905494E74 -:10F69000311BD637F3E932F3AE156D6A22E6B58039 -:10F6A000886F28A7C99FF12421DD9A77A90CF990CA -:10F6B000B9797980D9969E067F3369A4897922E247 -:10F6C00021C97A3CF344C427528A5D867CAA2FD391 -:10F6D00050BFC7B45E86F20CFF8586F2AC39830D4D -:10F6E000F99CEAD186FA3DC1DF89CCE705AE32D478 -:10F6F000EF5D3FD590EFDB7093A1FE056BCB0CE582 -:10F70000FD83F30CE515BB9FB7A05F7DD1A6C58631 -:10F71000EF1737DD6568070069EB0374328B71F80A -:10F720005FD2BCCC507F56FBBC4948B78342AB8C00 -:10F73000ED1ACC07383C030CE1F905F35B90CE34AD -:10F74000D6B1330BE0BE30A87843506D6E735E6F58 -:10F75000E4872FDF2CDEA50C8479ADE5ED643F73E3 -:10F7600083C6FC7C7533F14F349EAB58AF24CF5029 -:10F77000A40395059530DEE76F32B66718EF827601 -:10F78000F3C57AA2E9E20B56FD7001D247406FEB58 -:10F7900093165EB799350D0FE17741274E412772D9 -:10F7A000FD72FE72DD4EF80FCB41E15B90CE663705 -:10F7B0002BEC51A5EBFAE6B4DCBF222BC63A190BB1 -:10F7C0005AD0DF8E9EFF0E97C37D3001FE91CB7223 -:10F7D000316EC5BAF0879DE4F1F1756AD00A74AD57 -:10F7E00006FA45F18771FDD1703C5F7EF10838580B -:10F7F000D38DFC12E7898FA6B7E121D615AE09FD9E -:10F800008C7C24E128E1EAF066C6A42B0FFCC7E15A -:10F81000ABB31F13BE1D08DF8BC2F03D66F39F40E4 -:10F82000397CE2A36F55A23B7FFB10D463DDE9A5D1 -:10F830006447D1DF44FD5CAC5F9500723109FAF991 -:10F84000EC877CE4B74EB9BCA4CC3B0EE4A2A2F892 -:10F85000594A6AF87B9BAE3A8602BEE637AB5ED465 -:10F86000C3C7347BBD72092DD3E34C43252DF1C6AC -:10F87000F128F1A6B4BCFE7705E0056DFC168CBF3F -:10F88000167B6D384FC6A6539C5301F7E67402E908 -:10F89000D9C414D2BF3AA3F8DF71E6AD85FE6A1D64 -:10F8A000BFBFE82CF110570AD90FFEB478B43F3A25 -:10F8B000DA4F3C87DD6B6D4E1C678ADF4FEB198199 -:10F8C0001304BB9A39014E11F12268978DE34E79EA -:10F8D000FC9709680FBF74E0B84AFAE51337D9C33B -:10F8E0004F315F7F940F5DEDEB00E93D69AF837FA2 -:10F8F000D43B85DBDB7D5322FDA34EBBFACCFD80E0 -:10F90000DDD10FED99EE52E53595F4698712EFDD03 -:10F9100010439F8E4C31EAF94BC3F1B8912911FA8B -:10F9200073E1ED2776E23C00DE63709E0E07D8356A -:10F93000CA39D93597633FBF4A4824BAEED8AD06D5 -:10F940002F8006C76D9E2417DA9142CF2A1AE8103D -:10F9500057843F6B730DD0866079FF2416C34F9197 -:10F960006911D64B09E75F8B33FAA32B06F3794D68 -:10F9700011EB5C29ECA7F2146EE754611C2E251CD8 -:10F9800087AB9AC6E3CC0F45C52FCB531C547FA53C -:10F99000BDA81CD7BF224F21BB6985A218F6915282 -:10F9A000530ACB71BDB78AFECBA16F1CF7A95E7C51 -:10F9B0005EEE28FF3D0FEB0FC394F70B9CD41FE9BD -:10F9C000CFA2AA31E1392F45C4B1E399B4BF896F01 -:10F9D000260ABE9920E4E5957D415E1273E993C63F -:10F9E00043F93851CED4757BAC503EF10233433AE3 -:10F9F0001B877209E5BCD3FC597BBFB09C9FD0AF7D -:10FA00007A078A872BD2E17B843C2966BE2CA483AB -:10FA10002B3DC6EF13F74C388CFC3A9169D40F7D1F -:10FA2000CFE3704D7085E97D594AA7BCF79C06BEAF -:10FA30000EC5FB1F28C1F8C39F54EF066AD53624B4 -:10FA4000D22FFB85C0DB6AE1A7E03E12FA1F2E91A0 -:10FA500046C3E717293CEEB0DBEEFB05C2F3214BB2 -:10FA6000DB4F70BE214B7B6D128EF301A37132E729 -:10FA7000E8AD981FE6F3308C13AFC863762FD2E75A -:10FA80002013C541DC7EE7380BE4DDEB14B4849928 -:10FA9000596301C7E0B05C684EC913F3AA6D4D828B -:10FAA000FA49EBBE61BDC87F708E73A21C9AC56215 -:10FAB000C6359F167431E5F15E1AFA614936450F75 -:10FAC000C658C7D302CF201736E13A2EB7ED1BA296 -:10FAD000907EE07E07BAB2F47F074CC18D4AD7F61C -:10FAE00076FBD8E7900E251D5FAAB2EA2D764E5F11 -:10FAF0005322E458B3A4A7738C470F9BC362C64D2F -:10FB0000DF17782AB7F95EC1F90EDBE3A1FD8E0A93 -:10FB100029EF679998067478A320C31BD7B5FE9D7B -:10FB2000EC8B1F4E9F56A5DDCEA87F86FB0F150BD5 -:10FB30001C41DC8FA868C90B50BC698E42FB245560 -:10FB40002DEFF9305F3174A893E46482A21CEC4776 -:10FB5000263FE37251630725FDA90248D0FF34A177 -:10FB600067409FAC4E807555AC5BDF9A01457F01C5 -:10FB7000C301F1FF9089FB7FD1EB4A8BE7F059314C -:10FB800005FCE04128764FACDC918D78AEBE50F19B -:10FB900082B1B2F4F8EE5D978AB85826961FDFADB1 -:10FBA0004B3F3293A61162309FA7E23BF3BA2D9DE3 -:10FBB000E481CC0730DF88CC361AECB5078EEFAE87 -:10FBC0001B40F44B7A8969200F2E0EF3FB47AAFFE6 -:10FBD000A39FC1BAAF0365BC6430A61A9B4E784A96 -:10FBE000A7755E2BD619F807530EDAC270B9AE6549 -:10FBF00037C1FB23338C07CC632EE2A031DF954461 -:10FC0000FBC9603FD03AAFB7358C47BD7ECCD2310F -:10FC1000D08BF184ED1FE60460FC4F7F7EC2C18073 -:10FC2000EEFEAA7538F0FBA1BBDF77E880DF4FEF6F -:10FC3000568B917E6F117A52C22DCECDE9E166B717 -:10FC40008FB9511ED69C1AEE8F8C0B2D4925FD368F -:10FC50003708338CB097E66F4A400BAE335FD994C8 -:10FC600062C84BBD576965D5B1E2A097BA39BEE607 -:10FC70006E5E6FC9F2E0F87E178E7F08F40BD2CD6E -:10FC8000A16D8E20FAEF723E659B0759D09EFA6BEC -:10FC90008B9585D03FD3DACCCCCEE5A602F4EA171B -:10FCA00074193DCF9DAF24507FE50F71395B0A6316 -:10FCB0002D01B8FA5BE6923C8D5E47F9A79E093D9F -:10FCC00000DEE52BC172F1F0FA7703DEFC4BEEF9B2 -:10FCD00006EDD3E87596068CF27566BD312FE57E8C -:10FCE00085C037889B7AB4F3CB1B8CF52A5AEEA5D6 -:10FCF000FE2B502ECBEFB0FE216E61170E67235006 -:10FD00000ED7DA7B25F9CFA0678FD680419ECFD85A -:10FD1000911A1BA5876A18A5CCED217C2C6879EF78 -:10FD2000A748370B9BB758B09FBAE078279033B3FA -:10FD3000B600C7A33D8DFBE3D07406EE8FC33C6BCA -:10FD4000712219B87FEE1BEF067C999D51FBE5628D -:10FD50007DD305FC99DD45F4351DD73310BF6BDF2E -:10FD600046AEE7F8AE21361C77B25CD70858977AD2 -:10FD7000EEEB92EB91EB93E595203763C90549DFF4 -:10FD8000CCCDF5CDACC6292B320114B5DBBFA038E4 -:10FD900000137E8826F0A3D957911FA231F033F8C3 -:10FDA0003AB91F12607B58049D45D35105C2019991 -:10FDB000D8C9DBD9847FD2493F2D6B081E12CFD022 -:10FDC000613ADFB70CA5E3BE25D0D181283A32E4F1 -:10FDD000CB1B8CF9AFCDEDB9C8DF402F0722E1FB7B -:10FDE00075D4791999CE70F7E2EBF7E8139C505E61 -:10FDF000CE7C2B9CB4FE06E2C3435AC3CE9F21DFC8 -:10FE00003572BAFFABC0FBC76E5F2DE29D69FA4049 -:10FE1000946F45CB325437D42B5DAD38919F66D665 -:10FE20000D9A807C3898E9D4DF8C6EECCB8D02FE85 -:10FE300065D5666601E3A0CCC348AE956D53833C9F -:10FE40004EA7DB4B00BE73041E2A576EB164403AC6 -:10FE5000A7BA82DB3D41CE2F0057B27BE6AD6EA53F -:10FE60003802F85131F94DEAA9CA266379155B4D7C -:10FE700078A88AB27F82921EBDCC8BF4E8FFA9C31A -:10FE8000A6249D7DBDAC6B9C88E248C777F5257B99 -:10FE9000F8B8C7D303EBF901E76D68E76BFE11F81B -:10FEA0001DE044FAB263694210EDFD7D27C18F4524 -:10FEB0001BD4E91F6101B8B47F9C437A5CD2A75C74 -:10FEC0004F956D35D1671533FAC9A5E09061FCB740 -:10FED00074634A10CF0340FF039BD18EDA68263B40 -:10FEE00029C016A733A033DF7233C9C3B2E664F268 -:10FEF000D3CBEAF8BE51D9E6E4A0CAE30F7B30EEDB -:10FF000022F1B0AF6EAC2583F094E745FDCB9ACDDE -:10FF100006FA96F889F673E7D5B7EE4CF7741F0723 -:10FF200089C0CF816EF07320123F7BA2F0C3EE4EEA -:10FF3000E17266D11FFBE23ED9F1EA38AF1AC36F16 -:10FF4000927A886503010E0FC7138B33393E98E60A -:10FF50004D437C9E583D8CF0158DA7E27FCD247CCF -:10FF6000B08F1D0CE3CC337AB35BA7C2F75B15CE21 -:10FF70001F336AAF2C467DFD959033EF827CD22DE6 -:10FF80008CBD07F24907F9F43EC82DCC7F50934E43 -:10FF9000F90F6B3C94FEB9A61FA50784DD27F9066F -:10FFA00008C08276E309C12F27A4FC62B7A5A3E9A4 -:10FFB00050FCAFF7879930741BB8EBAAF160CF5CA7 -:10FFC000AD1BF5DDB46B8DFAACDDEC9C908E76EE5E -:10FFD0004A85F653CA7C630CF599E6B14C417FBD66 -:10FFE000DF90F077B25F3D96A9C0EF374E4A31D42B -:10FFF000BFBE3ECB904F48F5D0FCA614F7367CBF71 -:020000021000EC -:1000000069FA45867CE94900C210A46617E1E13629 -:100010001B13F104178FF38AF334DF568FE871074F -:10002000CCF7DBB7CD541E8D0F89D7596B4DCC0F54 -:10003000539BB916D606FD1E68003C41BB2F3F728C -:1000400030A4E3159B87BC3312F2FB369B295EBBC1 -:10005000AF2EE53EB48FF66D4E4DC438B07F852A85 -:10006000EC08A78545C8ABB1754BE99C4D69D0EA52 -:10007000257B6147E00999F728C8F78CF3CB1E353B -:10008000887139C01F8F673C63A57D884360B7398D -:10009000412F1C52581DA6A85892A0FCBBB6D420D4 -:1000A000F273F1BF543D1DE9E99938B1CFA4507FF7 -:1000B00047DEEBBB6115D197A729447C6B25FF6711 -:1000C000663B5F1F53066721FE0F25333D192651FE -:1000D000B9F8C3BD1AE0696E7EDBC010B49B9E17F1 -:1000E0004ABD01DA1D6D34D3B91BECD709F9CADF5B -:1000F0005AD77339A2F7407F220CCFE0405CF70C4F -:1001000093EFF254C0DF91D9C18124CFEE4E25BECA -:100110008A86FB018B9FE01B403E50C2F231CC67C8 -:100120007CFF10845A06CA9999666F1AEAA703AB36 -:10013000CD647782FE48C4F119DB4A747C40F34CED -:10014000C0751FA8CF6328AFE4B865AB55F2B39074 -:10015000FEA8FEFDAA1F6C0426F554A05EF1B31E96 -:100160005DE9E6278B46F4C0F544DBB732FD1A782B -:10017000D51F612FCCDBAEFAD03F6243DBB56B2FCE -:100180008E5C471DDFB748E7FDDF26E4FA825E6F2D -:10019000ECB59B50AEF74E42BFE7F01E95E8EC7011 -:1001A000AF86E1E9BDF178CC6BC3EF80FC97258188 -:1001B000831AE49FB0FA17205CE79B563FA140BB2F -:1001C000632DFBEF1B03ED8E3C6BF6E2B0F39E99C3 -:1001D000DB93F619847DDD556EE9D23E4853D2D1CA -:1001E0008E7092DEF6D4C120B4FE20CDF366D6B474 -:1001F0001CF1E65CC0BFEF1FE65885719A99C01EDE -:100200009176F77E33B70BFE2795FBB552BFB7A4A7 -:1002100072F932D3C4E99ABDA2909F8AF64E9F0824 -:100220007D2CE5F29A546E4774EA65D644F26A363C -:100230009EDB81F52DD8640D06F3A88D13F97C2E75 -:10024000470FDB8D7202C69D6779F661E4A10AD67D -:1002500046FAF3883938BB2D0FDBAFAF73517BB350 -:1002600097E2C5429FD88081501E5508BEAB6C50A6 -:100270008221E21BAE17CB45FF0CF54C84FCEAAAA9 -:10028000578CFAA45CE8D17216156F6E30EA375FAE -:100290000277E2E7C1B8A82FC3F302FB186036DB90 -:1002A0001FDC3999E6AD788331E651C13A422ACE56 -:1002B0007B33DF77889E57F43ACE759EB3BD53C625 -:1002C000250F8D18376ADE12DE14B08EC08384FBD2 -:1002D000EC0087E7EC1685F0F5B9B0CBE4BE8BC433 -:1002E0007B05F34DC6F384150F82BCCC0BD341A71D -:1002F000DEDF12A4FD952F5943A21DE87EC1DA2D41 -:10030000D78FC276EBDE23FF62BA2BD4D794CC58BA -:100310004AE0F355C53931F655A2EC831F0B3E3840 -:100320007B6DB86807F0286F54F5B881867AD45E83 -:10033000DA077302010BC661E788F8E6D9E659854A -:10034000F5069FCB7C63DB33FFE9BCBF4F15F1B9EA -:100350002EF650DF987E54A71D7416FDFB89399444 -:1003600083FAB7234723FDF3ADE6FDB0D08DFAB88D -:100370002FF905DDC9D7D9420F97A35E86F4E0DADD -:10038000E713D16FFFFCC1E7693FD7F26C7922DA3E -:10039000C507D7CEBC2F002C7570F34CD2C3158F78 -:1003A0004A3DECB744EAF7B16B4B7FFD73A4CF4DE8 -:1003B00071B41F317B875FD8DDE0B7A01C5CAB3028 -:1003C000D20B0F72B95781FA6A00E9AB0BB0DE4F5E -:1003D00067FB2F403A8FF84E7AECA733FD23A83DF8 -:1003E0007386D0EF02C919427D25F5A9D4B39AC905 -:1003F000DF270DE1A5BEFDC19DB0FEAFB6AAE4DECC -:1004000055AAEB739DB8CFD18DDCFEF7E16DEA8480 -:1004100077DE39C0BB0CE14DF60F87F767F51CCED0 -:10042000FB5773B8AFD8DC3B11FDDBCFEA7B93DD24 -:10043000F3D9E6BE04EF59AB00DE64F77A8C764F51 -:100440003DC01BED7C84378C5BB6C323E0EDE5F04B -:10045000AE177A67354F6775816BE01694273FFDBD -:100460008DD58BFAFC505C2815FD91435B5486E7D3 -:100470002C3AED2261BF48387FC71A9E403BAA8BB9 -:100480003D73BF95617C76EE0B8E2083FC11A5B089 -:100490000722E068C31B89385E78FC4E3B665ADA57 -:1004A000B0083BE61CF1B390F9E81EC2C296373E95 -:1004B000423B5ED1B95FBFD0660F21DF82BF73348C -:1004C000529E2B1E94691827F1DA6C4807D9CCE3A9 -:1004D00023BB46EE77F919EE777DDFF79B5B1613AA -:1004E0003F77E447C6C9ABE243668C2F756C510871 -:1004F000DF95B715261632DC4FABA679DC9EC6F524 -:10050000B1A2EB1437B402DDC4C3784BD23C24CF84 -:10051000158F93C711D7C1B88EF07CA3BF4F46D2B9 -:10052000437D6E8F1D77DE98C6ED804AD5447EC729 -:10053000020BF73FE47996E5621ECBD3B81F726FCA -:100540001A3FCF770CCF8340BFC72EB58AF3D9E3CC -:10055000289ED9193F9170736A5F77CA2BE42BAD3F -:10056000231BE1B477F47B66946B7BB12D19D380A8 -:1005700080E168C7F0F6EF98EDF56857DE3CF20DC4 -:100580008A83EE8DF379D0DEDA9B6AF3221D05B6FD -:100590005B89FEEE89E7F16FE64ED2909F6E12F214 -:1005A00076468155C720EFCD05F7F830857102B842 -:1005B00009B1A2F0F5E54847B7A6EFBFDD064B5AF3 -:1005C0006AE2F6CA5217A373409780B98E71583CFD -:1005D00022733AE54C74638C5B2FC0F8EC68C60953 -:1005E0006A24C1D39007B852FEE587AF9BF8603606 -:1005F00063FFCB3C17239E17204C900E4A93C8FFF5 -:10060000BF1AE3C42E4C35A2AFA91A0B98785A8FA3 -:10061000213519379E2CD679DD48164A82F5857624 -:1006200033435CFD8690297401C0ED6A2DD48AF0B5 -:1006300033D93C66F4037CC5CA60F48F172C3BB7F2 -:10064000F9BEF3B07FE283059037F1C38B1D772AA3 -:10065000C10D00A79B81B9912E6FD1D80E7530C7FF -:100660001BD25D95CB13A07A8B14B13FC4E3F91272 -:100670002F83A0FB48F8DE2CE607FDD427627B4BD6 -:10068000ECB8D1C769D2FFE576E67CC1A7F3259D1A -:100690006D36F2E73F249FA03D0B70BB59A4DDD11E -:1006A000F9DF44FF7F1374FEF9798E576965215A8B -:1006B000F7762BE1518E7BB548BF4BE3F6B29C87B2 -:1006C000A45F26E24F2690184847071A6AC95E9A27 -:1006D0001315FF6591712A3556BE53EE984E636A25 -:1006E000E99885F3512E8B237EB9D9D2D4B7DADEBF -:1006F000B51ED8D184A24ABB8DECBF85AC9DC7B3D3 -:1007000084DD2FEDC5B968E761BCB291DBB59AB065 -:10071000C74BC13F43A22BAD8FB077E17F939BB70F -:100720008CC7783E18267EDAB7B0DBE8DCC6E40575 -:10073000463BC92CEC2273945DC4A2CF85083B29AB -:10074000FA5C882AF817EA727F459C0BD184FDDB9E -:100750004947696681CF80611F7E3A6B33F3FB6244 -:10076000227E27F4F378D5DE0FE5CD7425DE8BF6F7 -:10077000FEB14247C09484F125338D371DF800E562 -:10078000C82771FC7CC58CA49F4E463B787AA24555 -:10079000C3F45367AFA41B18CA1B55EC1B0527E213 -:1007A0003E532DCA4D9EBF57CFA62898C86F7C0BCD -:1007B000F767AEFD01E64BF92727EAE0BF1DFBA373 -:1007C000280F401EE975B9E4DBDFF2FC43B2FC7789 -:1007D0003CBF52966FA3F18EAD91FD8BFCFD51E5B0 -:1007E0004BA3CA1FE1F9F13DB64D0C207CC4BED32A -:1007F000F4D10AED3BCD41BE02F84D5F16227A9A44 -:100800006E7A8DA7452C84FB8E67ABB7A8876F0ED9 -:10081000EA67D571C081F6C99D19FA1CB4AFAE4D17 -:10082000F5FB7AA05F3845095870FF714F305FE8DB -:10083000AF98E7E7E7083E5D98EEA3F6D2DE857E47 -:100840006EFC77FA39D5A34B3F653D52CFBF9FDD94 -:10085000E97C7D11FDCCFF77FA1998619C8FB4FF7C -:10086000DEC8D457E0FAD801B7E15CE4FCFFF1261A -:10087000A1FDC8F05C24807EFEB2A6DC21D0FFFC86 -:10088000E75ECA9D1D115F5878D2C474B013AB4E99 -:10089000324ABF6CFDB3C503F359B8ADD53201EA96 -:1008A00055413A36625E0BE4B960D6AE4D8DB05F0D -:1008B000EEED6112FC743FBFC7F5DC61DA3F9E6F5D -:1008C0006A3AF828F2E3681E678C5EDF4F7AF0FD23 -:1008D000BEBD783E20867F727F0F6E8F6CCFD61B99 -:1008E000709D8B5146423AB636F6F98A8F457FD3D2 -:1008F000E3B93C9F39DC61F35C82FBD9FE5ABCAFA3 -:10090000377B5DDE608C57DF915AF4688F33C67F8A -:100910003B78FCB785C77FA7BBDA6E0365C53EF899 -:10092000D5FBF7DAC05F9DF82BD6B91F8C71D56265 -:10093000ABE4BB2313C715503C8FF2CD3D0EDC1B3F -:1009400080F6BBE2F9F99119232E8E4779D09E9754 -:100950006072829C08B84B3FC079CC1871E904FCE6 -:100960005E6875E497F2FD03A28B80DBD784EBC64B -:10097000FA18BFF15B783CCFFFA64AF13CFFC004F8 -:100980007FACF307CF09387CD083DB67BB00CD6831 -:1009900057C979C8F1C120BBAD0DFA3BB02C63102B -:1009A000DE8BFCD85DB887E022C6FFD8ED6F8D1CCA -:1009B0001F963B10BF9FEB3C5E1174B147E0CD57D3 -:1009C000A0323D42DE4F1D9760C85F3B2985E9910B -:1009D00071E56BB30CF969D37B1BEADF34EB22437F -:1009E0007989B56D68F579D8F9550E473C9E6FF851 -:1009F000B4E5BBFFBB19EDD746D5ABC07AE66EDFD9 -:100A0000F87F63A0D6713C364CF6A887E27B47F0AE -:100A1000BC21F29EA66B91FB525FB1363AA719B189 -:100A2000EF61D85F9AEFDC41E7447FAC7DA9133DCD -:100A3000C4BEC7603C628E7AE8835C3C5FB2D0CEB5 -:100A4000D7F3D54BFB2C74BF03F507D0F715D8505F -:100A5000453E0F50BC7D6CF33EBA47F7500F2E97C2 -:100A600017662FD2C002655590A2DC9F00F22909BB -:100A7000E8A3AD955DBC0DCF57E739E83C4CE5C91F -:100A8000A98CA5201D05062C827AF3EB8B29BFF0DB -:100A9000643CF5FBAEDA3681CED1BFA8D0BE484962 -:100AA000D68C65682760FD9FC07825BFBBA218E182 -:100AB000B3701B3F3753A2FEEF50EC67414331B593 -:100AC0002F51D92E05ECA18963B97E2D415B06F229 -:100AD000EA70C72AD4ABAA2594FF18CA138B83E403 -:100AE00049D2C99B68FCAA93366A9F95CEED3473B0 -:100AF0003B9FD7F8933EFA2EF19E97DECB70EFD353 -:100B00009CDAA895D9B13EA3FA579DBC9052B9CEB4 -:100B100037FBFDC68D72CC9CFAED043C27FCA65B2E -:100B200071927915256F4F548F486231E4914CAD25 -:100B300042CEDE7C929F43EF95A98F4887794EBEC7 -:100B4000BB5DC37D2A66B739115E93470EF2CC8E2A -:100B5000E023F5B51BD1336056778719F5F9CD90B1 -:100B600046CAE35BBB91C797A69B0CF776A47E6150 -:100B7000C11BC9FEBE45DE53167C72A1A82FDBB790 -:100B800091ED04787CC14A76D4984CBF2F1DCADB06 -:100B90000AD9B4AD241FDB72717FE8C79A3FE0D950 -:100BA000A6903FD34EF730268FF498D03EBC2EDD72 -:100BB00064B0D3CEB68E2251FF5D952D417DF2EE0D -:100BC000E597B7E9D05FEBCF860C41B92FC79D9D64 -:100BD000CEEF9D3367C70FE8B756BD92E041BE2EFA -:100BE000C1BDD6A161BB1DBE338C7356BD62DD8015 -:100BF000E799AA12C16F87F1C7BE1A17423A6E7DF4 -:100C0000354E43FDF075B67F36E273ECAB178CC3FF -:100C100073747A8B556364DFE81508B7EEE67B36AC -:100C2000F9144D67922FFDF59C5F4A059D9609FECC -:100C3000F30B3E3A51DD83F8F0C4DD30695847D9F3 -:100C4000DDCAC5DBD01EF038E81C96E4CB12F4F305 -:100C5000E07BC945C9E4EF46F01DF1E182934EEA1D -:100C6000AFF2A447F0B98BF292DFCA04BF48FAF69C -:100C7000093BE26799FE87111E25B5C0EF787F73A7 -:100C800059C650E4A330BD589C4857402FE9B323C0 -:100C9000E8A1B615E8C541F44272C8076924BD5CF5 -:100CA0002DEF1531E7843498F7E4BA3CC3BDA2C7F1 -:100CB000CE93EEEB05BD94D9437DD15E3557C77910 -:100CC000F19EE47137DF875ABC92C36FB1D93716F2 -:100CD000ED87C58F285EC00CD915288F867F546D8F -:100CE000898CABDE787220F3C0FAAF39D987D23B5A -:100CF00052FD4F231C4A4F5E2FE035F0DFDAEF1C28 -:100D0000A6F3389A3968F5AEC7FDC438BF8AF83DF6 -:100D100094C39C0F44C4D130EE87F13FB90F2AE34E -:100D20006A56DC378ED093DF690DB9E8E77489AF76 -:100D3000151AF70B17B4FEEF7013941FC9D329CE01 -:100D400036C3E47F1DE979DED4E07366C8CF5FF374 -:100D50007C22C6F5253C9BB4505FD4934D00478C54 -:100D6000F735AD568B83DC9E49E0FB7C9CAE251DA0 -:100D700047D3F7BC93BD889E4E545B49EF9C007AE5 -:100D800065117A275ADF483AAED498F05B93E8DCD5 -:100D90008894FF617DB3FEBED148774735A2FFB08E -:100DA000BE99EA2BE4F44FE7CEA3E9FFC59A743A63 -:100DB0004F24F548B4BE8996EB525F7D92E1FF1E49 -:100DC000E154F4DB7F3EFF317CBA4AE37AEB2ACD73 -:100DD00041F4F3DF92FBFF3C4FFA3F2CEA83FD4ADC -:100DE0007621CAF5C8FEC66416256640794A06D73C -:100DF000ABFF6D799F92717EF29E65F0F99F4DDE9B -:100E0000E76770791F2DDFF1A222CAF763DBFBD3FE -:100E10003EFC5E06FA00F55E4B8267A390FFA41FBE -:100E2000E293826792FFDBB367E667C496FF1764BD -:100E3000FC07F2FF7CF944D26F77FC32F15E6E9FC3 -:100E400031B4CF9448FB8CC365D7855C0F44D86917 -:100E50003C9E027CD55789E49B0DF78D46BE39E652 -:100E6000F6E25940C927926F24BFDC2CF8E356A163 -:100E700017247FBC9AE1BF11E125F963C1D668FD53 -:100E80007066FABAD95DCD503FDC0A69247D593BC2 -:100E9000F583912F6EE9A4AB73E38B4919E766479D -:100EA0002CCAE0F7DCFF8B74B508E927065D2DFE40 -:100EB0004FE8AAABFDFAE150BCAF766228D0515E94 -:100EC000988E26BEC5B8DDD09BDBFF9D7462C9A19C -:100ED000B8CEC4D3FC1CAFA45389DF68B9F85CA6B4 -:100EE000EF61C4B7F41BFE5BF2EFB1F3C4F3CA7356 -:100EF000C4F36681E71FD15E7C31165E99D36588A5 -:100F000047007F5F43765C48A32341DDE1D5BC9673 -:100F1000F397CC2F0F6952EFA6A0DE057A69FE4F3A -:100F2000E8A5642C13F18D4393304E39F11722CF8D -:100F30008E4E423EBC7EA42C3FBC5AEF837286C9C3 -:100F4000FD038A8FBCAB8A7CE0C8DBE3605E131FC5 -:100F500060E1FD05281F5F90D4194F41D743D6FFAC -:100F6000F0912FDE5E4DFCCCCFF9307FBBC6F7D5BC -:100F7000447E28E41D11F99151F975BC7EA2D6CEAC -:100F8000F8B9CC20D7032A6E3572FAF145D82580FE -:100F9000C909787E62F236C589F1909B0A8ED1FE2E -:100FA0007378FDC727E905B82FA888FCF76FE37AA7 -:100FB0006FDAC6F3A71EF9C7EA8026FA4BA37819A1 -:100FC000FD599B145DC5F320239560AFBCAE703E08 -:100FD00015A5F7F04F33B66778CEEA7CDA239EA9E1 -:100FE0007D2F6A1FB29EC7F83714C4BE27E2C8140B -:100FF000F5445C81FA07585ED314FB1E4CAAA8DFA7 -:1010000086FB4504AFA43508BF368B8467E21AA47B -:10101000A7F18CE77B3E9A581218C0A7AF47ADFFE7 -:101020004CF35732BBAEDF636C1F3A13FCAC5DDA96 -:101030000BFA9963A4A724CDB7E304CC23C9AD3838 -:10104000D13E5EE88B5B8D7E40983E324A703D6DAE -:101050009D71FD68FACF2C41FA5FC864FDEC35E460 -:10106000E7983AEB737E90F405EDFBF1F7F7A8FDF6 -:10107000A847B3D6207C003F544E79ED0CFCD01429 -:10108000952F88E21F41FFC4BF28E7013E7D63C85A -:101090009969023E5F8973E46D45DC5E6C13F7E28B -:1010A0009664F238AD3F93DB637324DE23EECDB05C -:1010B000083C3371AF2662DD04A71BDD72DD052518 -:1010C00093605D6D2E5EBE3873E49A4076381FDD06 -:1010D000DF6D990525B83F11EE7FF49F506FDC2836 -:1010E000E0B62473CC9F025C1E2AC89795442080EA -:1010F000F76D4A80CE61215DC458B7DE95AE0251CE -:10110000ED75F319DA4FE8DA5E8F6ACFCCEEF3694A -:101110002FF036290AAFC551781D17959F2EF34140 -:1011200083FC9372B1ACF9FEE5696E8C4F2A74A70B -:10113000374CCF57113DCF774AFA9DF827A4D730C7 -:101140003D4F22384F6D92F2B0640DCAC329280F6B -:101150004787F3D7A0BCA0FCE4123D29525F5CBDD9 -:1011600046073CDF502FEBFBA8FE4D75B2BF29545C -:101170002EF1C802534B70FC1B870A7D11B8E64F55 -:10118000583EAF85B7FFEDA3D7FE29D0E70CFCD0C2 -:101190001005977551F94054FD07CFA25FEAA2DA16 -:1011A000DF1D55BE3A2ABF362A5F6F6C5F3A4B216E -:1011B0003E2C057A40449C8D2F5FCEECF47F3AF5AF -:1011C000A96227BBCDC057136B79FE8F8F9696D43B -:1011D0000F88C867CE2C89E40BB9BF0AB23680FAF3 -:1011E000CADC8DBC7CBE3BBAEC17AD6F79F95FF100 -:1011F0009F19B4CF63B00B5E578DF95655CE7BD196 -:101200009F6E1B10B91F5A5D8271966EF75DD8C232 -:101210009271917649A092E844AE53D69F70EAB499 -:101220008AE3FD25B3B2A411F7758AC47EA48BA707 -:10123000A0D754D49B55222E3301CF0363BDF85061 -:10124000DFC59176086BCAC775B6FE8CDF9308D4EC -:10125000027E30CEC6BC168CABB426252D7912EAA0 -:10126000BFFE337509EAD1BD4B52E81CD66559DC87 -:101270008E7C3DA9675A39E45B136EB5E0FDF3D669 -:101280007BC653FA9AAAAFE8005EFBFBA37797D818 -:10129000FB637912C1E7BBCC25254B81CE4FE225FC -:1012A0002568EF7739D3F01E075B6566FC3D24EFB8 -:1012B0001344376BAC83D08F2E5D7A11ED5F953D73 -:1012C000346502DDD3586EA67D0DF8A3FB3AFE55BA -:1012D000E3E99CD7AC3A9106AEA0F4D57FFDA636E3 -:1012E00011CF2D3CAED0FD904BBF6D7A0BDF5DAAC8 -:1012F000A8EFED45D4BC02763D9EBFFA6CED0574B7 -:101300002F647F5C359D7385FA0CEB57FCE07967A1 -:10131000F250ACAF3AF148C941F88EF6F0C195EA07 -:101320000605E795E888C7733C074F79DE41BB1691 -:10133000CA9DCBE0FBC1E573D3D0CE3AA878121595 -:10134000BCC7F0D8AA92F40C7C3FC12AF0B9CA51AC -:101350000A7C5D6AEAA417D21FB393793E356B55B8 -:10136000C94698FFC1472EA0736EBFCCD2D3B2003E -:101370004EB766EB3DB286E13CB99E7AF55F7CDF05 -:10138000F0E5A36569484F79599C8E5F39599656A7 -:101390001661EFCCFE4A23BCBF6AF1DC86F37C35D4 -:1013A0003E47A1F3E8AC2905E3DEB3849F09F4BB13 -:1013B000E4F91876CF0F992AF57BC0BA84ED8779C6 -:1013C000B7DE7BDD5807C0A5F54585F0308BF96B9E -:1013D00031CF9A63EF8BFE90563410E71FA6FF754E -:1013E0002467C9DF80FCC8AC47D604D00610E73BB1 -:1013F00019BE3E85FCBA392E1807F09CE5D6276049 -:101400007D96DE943FD511C1A7A2FEA7017E7EF98D -:1014100053A88FFEDEA781BF3822F72F64FD8A44D0 -:1014200047008D8F2F1C0E0DF1B657AB3988E71E84 -:10143000673F6E263D31FBF1D4BB3B701D405F7DA5 -:1014400059D775D46599895FBADF2F7DDAC8B7ECB3 -:10145000E933F2EDD4C7369534DABBE7DB0AE1D7DE -:101460004C78DC4CE7F82B863934DCB72C7AFC8FCF -:101470001BE9DEF1A2B8C1787FA3E2712BE1B7DDF1 -:10148000E10838715F35D1A125632AE8616916E763 -:10149000B3B12AD36C8329A57B1B723FF0F092076E -:1014A0001EC663A64758F0FA1100BFE3882880CB18 -:1014B00071796F2D6A7FB072F7F396427686FDC11F -:1014C000B3EC0BE20D78E4DB73DD1FBC232B7A7FDA -:1014D000D09C8FFB8F15627F70EC3A1ED7A958C243 -:1014E000DF65199BC2E3C4076A02F81832AE37E021 -:1014F000C47BD60F727D54C194A00DFE79C5BA4548 -:10150000F45EED1121874AF15DB501C85FDE5CF440 -:10151000EB673F1E4770AD7862EEFF3D02EDDA9754 -:1015200096B823FDE835821EA07F86F798653F5F59 -:101530002CFD792ECABFB1BF067F18EF4326B3E753 -:101540006ECC433C65E4E23EA6AC57B1EC67F9BC17 -:101550001EF8D3E03797AE54797CEA052BE9479023 -:1015600009E92CE23EFAACBADD16CB80F0FDB8CF2B -:10157000208F4F2C44DC93B320BCE4BD2DFC4B1FCB -:101580002EEC730FC91B7A6F7ABA49A1FB5D20E973 -:10159000E85ED4CB593C1EDA94C5EDDED25C2FDD7B -:1015A0000FAABCCFEA5DC6CF2BB1CE7BF1781ECCA3 -:1015B000D4369BF62D7F6FA5384A555D9C1E97C883 -:1015C000CF536C1D40E7C6350BEEB778B85C795940 -:1015D000D05F9567CA15482F50FE9186E7D51C5CF1 -:1015E0007E56268BF700A1BD09C63986FFEACDFBE2 -:1015F000CD181831BE22BE433F9EC470BFBB4CAC59 -:101600001EE33458BFFF408463CAF5D3707ECFAA6F -:10161000C4C7B0F8FB46A23DF8AC3A04FDE0D29551 -:10162000AF4F588BF92D83F046072B7DEE7DD22FDF -:10163000F305FEDBC5B9B932C8E33B057B041FF9EE -:10164000551E1FDA23E025E9409657AEE4E7A72AA6 -:10165000975BC9DEA95CFA21F55BE9684B43395D0C -:10166000F98299EE797F28E65DB634A7E023A0AB36 -:10167000327312BD2BBE205062C1FC820685F2E19E -:1016800076A9B948A75FD6BD9888F4B33F2ED41782 -:10169000F556C7A2382F9E5794F1B92FEBFA6EC0BA -:1016A00038CE2C679B03EF6BCDBAADB70BE5FC5E74 -:1016B00067C882E57B9BF24C98D79DCE02CCEBDAD3 -:1016C0002594FF529C57A13FA41785E379C1E6D723 -:1016D0002DBD60BC1FC47ABF7AF6FD7CD46B95B972 -:1016E0006DF9A87F800EF2B310CECF28A4B7176E85 -:1016F000E6E7F8251D2C443A00BE9B27E860E1B6DA -:1017000017EF407E5888F81FDC958E804E77D0F713 -:10171000ADEB2730DE7E07D289D47790AF33BB3074 -:101720005E27F2300EE64F213C8751F9385E1E18D5 -:10173000C0CF03B6D3F9C62A719FB3533E7583E772 -:10174000CC6CB17FB6D44AF236339BAFBB7DE50B90 -:101750008988C7AF9E7D7D27C6892BB78256F7C47F -:10176000E00B01972A844322AD83EC902A5C7762D8 -:10177000180E9DF42FF8B18AF175CA755769020EDB -:10178000B25CB4CFCAE6EB5CC004DCB65DC0F94F16 -:10179000F01BF233BDBB24D6E77719DF97D7C5FA24 -:1017A000FA8B7401D005DE5F63787D53CA0928FA8D -:1017B0006ACB7A8A13497CC9794FCDF6483DA22776 -:1017C000BBC2786C37C57E5F7B54369727FB96F794 -:1017D000C86D06B87D09FE189D37007AD522C693DC -:1017E0007423C71BFBDB2957E17AA1FF10F62FC733 -:1017F000DD1B48D0B09FBD8CF307D227CA4FC997D5 -:10180000636B675C3508CF4307BE72F4467B5BE0D1 -:101810006F6A367F0750473B01DAEBCD0AC5A9F75F -:1018200009FF7FDFF21713CB22E0E413F3967486EF -:101830007F18BF92F3DDE5E271DFE8794B3924E7E9 -:101840003DF69E1BAEC2EF72FE925E257D4A384A7F -:101850003A95F703A3E995684DEA4FD520EF493F44 -:101860005E91FD8DC56FEFFA3D3ADF6937D5A5EF83 -:1018700088BCF7B65F9C77EF48653CDECF806A2373 -:10188000F48ED4F3117A65B516A157AADC3ABDB728 -:101890003367E8A27CD4632F64F37329475893A578 -:1018A00010FA5B70A86D42A2276CAF5EFA6D48C556 -:1018B000F76E166CE3E7D724DC171CDD41F45F29D3 -:1018C000EE6F95AE7CBF6404D2F9D366DAE72C5D87 -:1018D0003E9EEE69CFDD387338D211DEFB40B97E13 -:1018E000B871D810FE5C9B33ED7ABCFFD1F8C0F51F -:1018F00037C1F759CDAA97E43BF4837C5B7AFB10A0 -:10190000A6D07ADB4B70FFB4E34ED58976FE988D76 -:10191000C3EEC6FA631C3D93713D7A630AE5752DEB -:1019200089F483B48FE5B9BE5A33A78B5F67737FA1 -:10193000F5E1CE5411E7F96AF371FFBD637D1CBD7B -:101940007335DD22EEBB6EEF417E489505AF5ED26A -:10195000FD59B2C7E658982D839F0FB765C0F7DDD4 -:10196000E6B6DB518FECBEDD3188EE1FA83F0C2FB1 -:10197000E3FE23CDA324C5F8AE949CC71382DEA357 -:10198000FB93ED7789F3D9FBC5FC0FD73D7D3DEA8D -:10199000C1C39BFABA70DD5F6C8FA3F771BE887A02 -:1019A000AFF37CEFB301FD46DD175B46F36BCAB6C0 -:1019B000F3FB5CC28E93F47ED6FB5C9FB8A3F6115A -:1019C000CE7C3EE9680DA37BE7B7812D8EEDC72560 -:1019D0009C7A1ECF05CE6EB03AF1DECF01A477DC43 -:1019E000BF7A41E5F7936D9CFE0F6C1914447F7329 -:1019F000F627FC1ED68EFBEFA17309E5605FE2D1EE -:101A0000CD4E7BF9C1FBAF473638EEF5AFC88076D7 -:101A1000C737F173145DDE77D8FDFCCEC8F71DCE55 -:101A2000D74E3E57FB58C6233EC936BE1F20E12A7B -:101A3000FDA45701FF230787E1F475CD1CB28F8FFA -:101A4000D6F8293DA6ECBB6F0CD2AD2389EE37BC8E -:101A5000DCFC808AEFD1546E1BF403FAC5A3ED4978 -:101A60004EE4D7AF6B96D0FEE8D19A6AFEEE4AE715 -:101A7000BBCA414A2FDDD64AEDBE6E1ED282F78127 -:101A80005FB12709B91FBD1FC4F1D8DD3D67B9AEED -:101A90002377727CCA791FD9343311D7D5FA584AC3 -:101AA000CB28C463429213EDBC0A714EE4E05A6E37 -:101AB000471FB2253D3909E07368DD3569F85E508E -:101AC00079EBB5D7E3F7D9DB1527DAFFDEED531253 -:101AD000D13FFB5C6B4FC4FB5F9FAF95F7C682F4B1 -:101AE0007EEFE86246FB55A3431AF3E4D1D633D127 -:101AF000C9A8A31ADDCFFD12F7B1305EF2433CC591 -:101B00004B98D89F2A7F89C7593AFD59E1CF8D114B -:101B1000EB1E91E392FB0EF47DEC48FEFD8B75CF3E -:101B20004FC6FE0E379A9D38EFAF1BF93B16F3C038 -:101B30000FC3AB008736713F675E93427EF1E14D84 -:101B4000A0A7615D958BCC3ADD6B8DA2BFB1508EA5 -:101B5000E72225FDCDD38344D7D1EF8C24B326BA19 -:101B6000FFF663D1E3C539467FAD930EBBC3BF809B -:101B700013F22DD2A1C4F3BCB5FC7D5B57D3A042B8 -:101B8000A42789F7E87B0EB51646F71902A6787ADE -:101B9000177A8ADD635660FDD7B8DBC7A1F87C24CD -:101BA00087CB4575AC49C7FB7AAC96BF63D0253E61 -:101BB0009DC3E5E89B398CD2B21C7EDE58DE5B9378 -:101BC000292C2487DE654C707DE7812AD7E46C9A46 -:101BD000ACC1FCA78C71DDDEDBCBD8CD39CF4DD6C7 -:101BE000806EA70C71BDD00BF2331EDFCCF397B81B -:101BF000869921BF54F9DDE47190BF2B479F9293E2 -:101C00001A1E47F60BDFAFC5EF8752FC37E40C43D3 -:101C100039CEDF2D3BA6740C5C9217AEFF9EC2F648 -:101C2000BEAC84F3ED6646EFE594E1FC53BB4F3761 -:101C3000E4E8FE9C6131CA19A3FB6365017E1F08BD -:101C4000FE7CB6343AA746F45426EF07D51BEF07BF -:101C5000312FBF9F26EF6DC97B59FDC3F7CDD69DB0 -:101C6000CF7DB363E27E5CF4BD3FA585DF97AB0D0E -:101C7000B0F638C243D47D9F04FE7EE3E217BEDA9D -:101C800081643557DA2BA86C8787DF3960E9FCBCA3 -:101C9000C0ED820EBFA8617DFA002B5FDDD696E80D -:101CA00081C91E9D1CCA47FEF658FDF508A72FD610 -:101CB000D5662F76E3FD58AB7712D43F14E4F74F87 -:101CC0001708BB9335A60A3E57439743BD5D79FD80 -:101CD000E99D8B5F0A7A3A9A17CAC577870279DC41 -:101CE000CF817A74FEAD78D915A958EFE8967BFAC2 -:101CF0009403DEACF8AE9F8B5286F7C5AE84BE4728 -:101D0000BAE8BD3FA6D2FE6E90FAC37A89A8D73D45 -:101D100033D379FC9DDF2F947892F0EF82179802ED -:101D2000DAA5261B33E3FCFBB3754ED4C7123FF292 -:101D30007DDBC52FF038CA62A5BD2E05F3CF2A740E -:101D40007EEE0B1BBF0FD455CF6DB420A8E7AC9B24 -:101D50006978C748BE23FB63C7835ECA11F7C20711 -:101D6000B14191EFF45688B6E3D5E91E7C677471F2 -:101D7000AA8DDE3759FC786FD2272C703BD181AC0D -:101D8000C7D6A5107DACC85309CE739B19BD4F545F -:101D9000D29C49E71D2735BB284D3C994EDF0F3FAC -:101DA000F9D6502E7F381E4A9EEA41EF8A973C753D -:101DB00041117F74AFCB3B49FC3D6DBB8DEE1B2FBA -:101DC000DECDF5D2E2EB548A5332710FCC27A6E375 -:101DD000B3D7535CC7C762BF0FEC93EF03EBE63397 -:101DE000BE0F2CE16B15F8897E2FF8BADD43D2D1F6 -:101DF0005F95EF05CBF708DBC47DAFE87783EF494C -:101E00009C40EF064FD3B91E897E37580BC479D159 -:101E1000BE3567DBF9BB16FEE87784DB355CF7F58A -:101E200005FC1DE1EBA619EFD3990BBE21396D2EF0 -:101E3000E8F28E9219E9DBEA33D6FFBBD42FFD59C5 -:101E4000FF33BED39C6DA1F7F0347CC71CF2D78B57 -:101E5000779AD18E43FBFCB8CEDFDFB3C6F375B7FC -:101E6000B1A1E9C8F7FFBFBF4F7EB677C9A3DF2195 -:101E70008F7E7F7CC8AE5F1AF2C3DA1E35D41FF1A5 -:101E8000D10643F9A8F6670CE5630E6D35E42FED36 -:101E9000F883A1FEE5275F33E40BD95B86FA636D17 -:101EA000EF1BF2E39D7F31D4BF227DBFA1FC4ACF5F -:101EB0009786F289FD4E18D7A3F927E4223F7BFFCE -:101EC00069683799797E81EF7BDFE036D1BB26C523 -:101ED000B946BA1B97C3E30AAC0FCB45F9355E9DF3 -:101EE00044EF241D6F52F8FBD2DDE8B124B0F7B403 -:101EF000887192751B3882E17C4AB1D3904FF5A569 -:101F00001BEAF798E6319467F8FB19CAB3E6780D37 -:101F1000F99CEA9186FA3D97E8867C5EA0D850BF8E -:101F200077BDCF90EFDB30CD50FF82B57E4379FF98 -:101F3000E01C43F9459BAA0DF98B9B9618EA5FD2EA -:101F40001C30940F0AD51BCA87EC6A30E487B5AD04 -:101F500035D41FF151D0503EAA7D93A17CCCA1264F -:101F600043FED28E6643FDCB4F860CF942B6DB5062 -:101F70007FACED3D437EBCF3CF86FA57A4EF33949C -:101F80005FE9396C285FF0A597EE4BB397F97ED8DF -:101F9000C47EDF18CACD6E46EF6057B2782FEE3B95 -:101FA0004ABBA6C4FB7743BF4FE6F2380AD0527B48 -:101FB0001CBE1F19F051FCC7850702514EE13D754B -:101FC000173F4F339DE2486ED26FA48A3C78BE071C -:101FD000EC8044F4AEF2F2D04E4E08DB63D9A72376 -:101FE000CED79DCD1EDB96CB681EFB73FD4FE7A6BB -:101FF000A2FFB16502BDFBCE022B701EF23DC07781 -:10200000A2DEBB96E995B6432CF25DECDD710DD9ED -:1020100083CFE0BF5F693BCAF0BDEDCE7E45BC42D9 -:1020200081F52D8EE8FF3EF017B43E8C35D400FFCD -:10203000808DF4CB1A27E51FAC49A7FCC3351E4A97 -:10204000D7D6F4A3F4D11A2F95AFAB1949F9276A63 -:1020500074CA076B8A29DD50E3A3EF8D35D328FFBF -:1020600024F8C5986E023F19D367C0DFC5F2CDE0F2 -:10207000FF62FEB99A00A54D35F5F47D6B4D03E581 -:10208000B7D5ACA5FCEF6B829436D76CA2F40F35B4 -:102090004D54DE52D34CF9576A42940FD5ECA2FC52 -:1020A0006B356D94DF51F311E577D6B453BAABE6D7 -:1020B00010A56FD67450F9DB3527297F54C45DF71E -:1020C000E51AF723645EBE5B21EDBFC968BF2371CB -:1020D0008C347F6DB0DFA3ECE8687C1C11E3E03B3F -:1020E000BD43816ECD99F91B6A23FCA7AFC478F27A -:1020F000BD8AE8772798B04FE5FBB0F23D8BD962F7 -:102100005E1582FE87217DF623FA7CFB7CFC05E9C7 -:102110000F5E9BEA3F45F499630A903F6CE7F791A5 -:10212000EF48F5B39EC370DFB07C278DE7F4D2FE95 -:10213000618935947AC3507A079EE272DD8D572506 -:10214000CE89775BFECAE16CB4A78BFFA5D27B6416 -:10215000EF981DF4BB97293D395C527A9A0CE93F00 -:1021600053FDAE9E907EEFA8BEC504F3FFFEB245C0 -:102170004FFE242FEC275F8DAE26F8375398C74CBF -:10218000E71199FEC73CB49BC0B0C2FC0D2C40695E -:10219000C0EDCFC275DD080637E6FDA3ADB9B1D6F7 -:1021A000153DAF7C31AF7C311F99F64FF3F7C5FE7B -:1021B000BE77E834AF77465D918FEB92F39A27DED6 -:1021C0009D98CC3A9EC0F97DBFFD9B834AEF30FCC1 -:1021D000A53F4EEF02A0BFB34811EFFF75797F8096 -:1021E000CAA7DFAE907D3603FC19DC2792EF0D1CE9 -:1021F000AF36937CC4F709701FED78F5E776246756 -:10220000A8C7709FA3160FF64079EDCF15A2AFE9CE -:10221000F88E08B49F9196C7EF4B339B8E7A787AED -:102220008B753DD2E974B0F7D07F02FA2844B8CF5D -:102230001BA5D27DF5774CC17C85F693CB2D0ACCBE -:10224000ABC2ED35FC8E4434FE178AFB07F23BD05F -:10225000D54484D7D72F8DE847F1F7574679104EEC -:10226000B5267EEF28F0A62A7EDF8B8B6675CCC55F -:10227000145F649AD78B71A212714FA555654B629A -:10228000BD1F5F29F0F44E3A7F5FB0366A9FA5BC50 -:1022900027F72FCB7BF2B873C96BBBE99DA585BB34 -:1022A000F87B906C68FB80C877793AD7B3E4CDFEB1 -:1022B0007D22D651D5BC8F9FAF60ED0322CF9FAF5B -:1022C00010E34BFA512D0EFF7A7BE4FC3AE97901D9 -:1022D000D17332D0736FA2E783B8AF38D9EA49BA65 -:1022E00041C15FC7635FE3FB47FE5F3BE93C913C55 -:1022F00057348BF928AD00F423FDFA02F7D37BB7EE -:10230000F358137D5F387226FD3E6D15EB18970E5E -:1023100070BBAE7EE91FF1B9C06B1AEE1F8F71D58D -:10232000A9C1D23F623AA5513988FE29F0C3CF1125 -:102330001FED4AF5723CC279D3E6C2E5B83538598B -:10234000E5F8606F717C00BDE8AAABEB3A81FE97BF -:1023500013FD27EBB40E35B1D840FFD397315D7133 -:1023600087CFC777F2C3C8F97FC52D60A675D0BEE9 -:1023700079D52B5617E2791EE3FA3A6CFF493DCD29 -:10238000F5FF7CD0FF58EF88A0E723398CEE211CA5 -:102390005118DD6F97F623CBF5A70FEE1DD6B74783 -:1023A0004CC1E189BD491FAFC3F9EE4CBF86DE0FBA -:1023B0009AEFB6D1FBB0479283B951EFA1D07B4DD4 -:1023C000327E759F99C793A2E7A58CDCC97FE7C4CD -:1023D000C202B82F81BFF33D1CF938D3427C568B23 -:1023E000A0C5385891CF13ABFF3AD1EFAE53DCCF35 -:1023F0000DE4F0774BBA8CE314E3C4F371A4DEE888 -:10240000FC5DF13466186F7BCF3CCE070E9DE6BFB6 -:10241000D4944C7226C3E66FC1F5CB788EF4FF7668 -:10242000E57DD187FCF41F6AE93D267ABF00CFF530 -:102430005CC6E5D13B660FBD4BFC4E611EC5EDA5EC -:102440009CBD7A248F7B5D2DE35C055171AEA8386D -:102450000B2B881DF762CC6BC671FBB34F247C2815 -:10246000BEF25A8166F83DB1D784DF79BCD83D947D -:102470007E2FCAC3CF5925A6F0F7463A1C2AD1D9D8 -:10248000EB01AF1D7F9F6495888FAE8E7A177CD548 -:10249000D0C54E3C176075F0F73ED714C5CF893CC8 -:1024A000BFEECEE7EFC33C995F98E18174803D5861 -:1024B000446A59D73C387F45ACE72227C0DB84F615 -:1024C000A64FC439E5EFDC8C23BD2CF17CAE7AF944 -:1024D000192DB82C1ED7EB66C4778EB536929F6A3D -:1024E000931EC2A3D4B3F2A71E47B9C1345F3F1CE9 -:1024F000A775783CB343FDEF5B2D147F7AC554F686 -:102500006B7C97B8E3CF5686E71C9A1C591A1AB70A -:102510004DA72E1C47A963CC04FE3E274BC0774431 -:102520000739D96F7E874812F7C92CE9CFF80E809A -:10253000DC6E52D82EFE0E979E80EFE13599D88939 -:10254000CB617EFF0FA64C086300800000000000F6 -:102550001F8B080000000000000BED7D0B7854D5A8 -:10256000B5F03E33674E66269370327930E40167EA -:1025700092C98B4CE290F054AA93106840D0E15578 -:1025800083243A58F446854C8AB445AF5F339000B3 -:1025900001F42FA2B548BD7640A568B50D4A6D6C13 -:1025A00023770242B197EA606D8BBDB57FF0F6F7F5 -:1025B0006AAD12C47AB1A5E5AEB5F63E9939930974 -:1025C000A2BD7FFFEFBFDF8D1FEEECB3F7D98FB554 -:1025D000D77BAD7DF28CA3F6FECB18639359C0CCAC -:1025E0004A18D34A838A96CBD854D641F57B954076 -:1025F000DBEE1C289D565F18FAD58E33F919D4D915 -:10260000C78E48A9C458E0986C313B18EBF3041D01 -:10261000F8DE05FCB90A9EBB4C16C5CBD84685B57D -:10262000F54299E1B3336665F47301FE05CE953149 -:1026300056C7D858CDC4D814C6BA5DFE985F8ABFB5 -:102640009F5C32551E1AD4DF2FC6FF17AA6FA58BC9 -:10265000BA9931AF23D22061C52F6BEA54C6E8770F -:102660008DB12A95052D30451A0B30DC0F9BEEB34A -:1026700006AAB1B1517DAB02FBF9A50BE9179997F9 -:10268000C90CFBE9F3FC6102A3F51EB267D6B031B9 -:102690008C851BB4FB1A2743F953B3AF8B7AA993EC -:1026A00071FCCC6C1635C1F3A10C73648F9BB1C364 -:1026B00061EDA95EA81F96AB088EF774C266000490 -:1026C0005B3BA1A2C4E7DB3A798DAA013CD332CCB3 -:1026D0005F3A8C702E32A9A5B08FCDF3ED4D1180ED -:1026E000E3BD0DF6362C73CA2C8C01BC97165B68C3 -:1026F0003D7BCBEABF5D0CF5564760B6A47138B0A0 -:10270000BC381CE001E3FB0D32DC6F8BCA06A5442C -:10271000B830804B06DF00BE770DDF32BB4666E186 -:10272000314EC65E9EF1F663BD304EC64E587736CA -:10273000BCDF71460EC23AD8F90B57D901DE01BD94 -:10274000FF4C89BD9978CEF0EFCD0AB13F37C15328 -:102750007D4B6F375F3ADC2D4BD6573058EFA64E86 -:1027600017C1AB47F2F9C7C27872C7A93BF0F94667 -:10277000193A02BCC25E25F238CE23072A703FFA0E -:10278000782BCB1A6ED0004E19D3FE907E0BF4FB43 -:1027900028CFA42170366A377DDF8EE777329DE13E -:1027A0007B99D9B1B647A17DE8F572B60786F9E8FD -:1027B000D6E00415CE630B9CD39B1E5C4D64AC69C4 -:1027C0003A9683634D2E02AE8B9741177FCE447BA2 -:1027D00084EA6FB98BE99C00FEA2FF20F5DFA26CB2 -:1027E000B7DA711EB755DD9380F7579959472FCC4B -:1027F000F775A40B7CEF7C97B63003EB12D5EFEFA7 -:10280000DC19F89D07D713A1327B7E840501DFEC2C -:1028100015612D0CFDAC1B5810DF4F86E7DB6E9960 -:10282000DEB71E7A8869D02FDBE39382D02F673E14 -:102830008CA7C399D1B987C7D442BF3D80309311CB -:102840003EF64838055D5E93DB704CCE1CFDFC9275 -:10285000F180093CD0CFD3FA577310F902632E13DD -:10286000E2DB5A2BC7D3C6622BA379D729BBD3602F -:10287000DE27B42C5AF787390D639877F4F91E8157 -:10288000F309033D4580AEB0DCD3A9B230E0C963A3 -:10289000802F58DFDBA951B9AFB382CA273B7DD463 -:1028A000FE54E774AA7FAFD34FF5DECE26AA3FD3FE -:1028B00019A0FA81CE66AA3FD719A4B2AFB38DCAC8 -:1028C0001F7576507B7FE73AAA5F9506E786FBA9DE -:1028D00008BB16C179F4DCA9F83580CFA038C7C38E -:1028E000FEE26C1F9CB7ADC2043407E5F11D0CF786 -:1028F000637399FC1138874DAE1DEC8B505AA66658 -:10290000F448C057363EEDE8918031DBE4FB19F224 -:102910008347A4701BF331F693483020CF60CCE39B -:10292000FA528313EA3F8BDCB2DD0A785BA62D6C8A -:102930005E9F50D7326A6FDBAFC6EB13BCBB653B03 -:10294000B4BFAADDBA3D47E2EB60F98CFD26727B8D -:10295000603DE051B4988511EE436E2582F8B812BF -:10296000CF4BC6F5ABB4FEAB5997CB04EB9FA02978 -:10297000B54837D03FCA722EBDFFA0A6D1F3E4F709 -:102980002ED6CF34F992FA31F345C6C376E922E365 -:1029900058A5C5D618AC7D9B45F08F5C07F18F1EFE -:1029A0000BBB310070EFB1F1F2CA6289F8ACB3B879 -:1029B00061B71BE6DDEDE672ABC716561B70FE6A0B -:1029C000930FF9055BE7FE7931CCF7959FCA6CABA5 -:1029D00016C7CFFF1078503A2183CBCF7FB4464A39 -:1029E000619ECF4F78BADB09F5D2477D3E33F4DFE5 -:1029F000C67C76C493F03D26F638D4BF3BB9C4B943 -:102A000010BA574DF98113F9ED5237E70311C69A01 -:102A100010DFD66FBC65C220941F9DE07C4A71F325 -:102A200079765B621D749E531C6C0F0981EDE9C8B9 -:102A300077D6BBE090A631661AC74BC5A25E8FFD64 -:102A40001410D461588FF29769D6008CD7752EADCB -:102A500009F90863B174E4638A2DA866C1F3ED61D6 -:102A600013F1852ECD119160DC6D8EDA631AF24F71 -:102A7000D5E42B45387A4D04C76EC7172266E4CFDC -:102A8000D2FA36942F11F519AB1B9E47BC2615E9D7 -:102A90003CE25FD484F57050F6956A8241607BD049 -:102AA00019D98AE3B2A17FB90CDB5B980FE1B03191 -:102AB000EF4F87D2A1DEB554F599796F4D06B93342 -:102AC0000E7F8329BB2C831BD2711DCB787FF8CD61 -:102AD000B710E5701A3FBFAF0FCC558B49EECB61F5 -:102AE000A14748178010658BCFEA83F61A476D938C -:102AF0001F4A39A3D6AAC13EBBD55AEB0ADA3F73A7 -:102B0000803284228FF853976A22398CED5F447AA1 -:102B1000EF662F7AF28894A8BDDBB16300E121DF74 -:102B2000CC985BC3F5C17C3ADF0378584B661ED363 -:102B3000601F3DB738691FB2E4A33ABB59A675E7D9 -:102B40006BF628AB013EAF2C38C6807FE45B6F9FED -:102B50008FF5716DF2EF0613F8F4D8A0B19EDB6C1F -:102B6000AC6733A85BE3F32E7273FC4D865B323C9B -:102B7000C6A9DD2770FDE382323D4C5EFF43EA03C8 -:102B800059F50CD7E9A075E6396EAA070801CA0500 -:102B9000D623FEFDADEBAC511759DD307F4D8E894C -:102BA000D496CBD8D0061C779BC0F71E373FCF38C2 -:102BB0005D9975BADC8A7439619D898513E48E3B11 -:102BC0006C67E184F94A7A9C867AE9F67C43FFF2E5 -:102BD0009DC586F6CAC844437BD5BE5A43BDBAF7E5 -:102BE0007243FFCBFA1A0CF549D17986FE75C716E8 -:102BF00019EA5362D71BFA4F3B7993A17DC6E06D6A -:102C000086F62BDE5E63A87F6EE82E437F5DDF4E87 -:102C1000968FDD822F7C5A3D3BCD05989D305FB26B -:102C20001E9FAC875BFFDAA56D407CCE54089F6584 -:102C300094E7505F73A7124943FCBFD2A7217FB925 -:102C40004BE0A3B7DC7F1F9E5B7DA695E482ECE0A2 -:102C5000FD64C71CD253C6EF04BE54875A231B6EB3 -:102C60004F47FEDC190E783CF175DBD4ED0CE9B76B -:102C70003EB3890D3AE2EFCBAA9F0533703E8DE655 -:102C8000B3AA61EA67D3E0FD847D1D34999803F906 -:102C9000F88042FA7A6F46818CF4D7FB97898D547D -:102CA000665C3107F17D92CA1EFD3EF4EF95D83186 -:102CB000067A52AF899D059D8D3D936447E9F6D311 -:102CC0007813B363B95B1ABC83A19DD271A2612C46 -:102CD000233BEB59DCF7BDA043E0BEEEADE17AD675 -:102CE000C6BC791AEA653DEEDE63C5B89E5C902BE2 -:102CF000480872C0877A85BEDF37C479CAC53D836C -:102D000028FFD6645935D49764EBF6C0EF005E8F88 -:102D100058069FE8827AB7A4AE42BB237CA7C3F7CC -:102D20003843FD91C34DCB30D56D80717BD7FBE52A -:102D30002C68EFDDC27CDD481F39F51BB2E07969F4 -:102D4000E10A9313E9C1B37E0396AFA01E0BF0AB6B -:102D5000F4EE3665437BD5E4FA6686B25785F9B260 -:102D600047C72773E64E86FB611EF92DC42BD4BAE4 -:102D70002FC0D2EB9D70DE30AF0DCF5BA292E06032 -:102D80003BE788D8B0EEE170B1F9A5483AD4733C7E -:102D90007EC9EFC5F776D2F9DAA2463D16ECCF37F9 -:102DA000DC53509F359EAB6C7D80D6B7CDC4E9A275 -:102DB000274B3B8EF2B9C7ED717669F175EA7CE578 -:102DC0006D618FEACF75BE723DDA1453E2FA0DE001 -:102DD000F94E5309EA67DB19F227DBDDDB19E2B5AF -:102DE0004D0D6B0CF5F0AF8509CF75FDF60E413337 -:102DF0008DC5CD5694D767736A499FB5ADDB4BE758 -:102E0000950C37DBA089F92F02D7CCB25D24DF8186 -:102E1000016B68871FCA73B4ED4EA1F76FD0389D60 -:102E20006D01328E79098FACC8AF2DC2CE004C3007 -:102E3000A17C3BAB326E27F6BAA97E4716AFEBE317 -:102E4000DC915B3BF662FAB70DECC260C23EB6C0E5 -:102E50003C08978DE71736215C994CC4C1B6FDC577 -:102E6000BB7B2BC252D8351B04BCBFAE71F88E574A -:102E700018D905BE9CF94D24FF5C4FD2F905CE153B -:102E800093109E56EC24F883116DEEA0F55B74F957 -:102E900064BA7019AD595360FD05F8A4184B2EDFC4 -:102EA000A0CBC00509F97F823CE305C9F702FE3BD0 -:102EB000C803637BF94E63BD3292F47E98BD86F2FF -:102EC0007F25E3F0AADA676CFF16CA71E01B2B8539 -:102ED0001C67DB2D24EFACB0A20B5CFEC6E521F035 -:102EE000876B7A63F5E9304ED1748B414E1624F628 -:102EF00003F8D5DE6A0AA0DDA0FB5F74B807DA4CE0 -:102F00001685E84123380D3F17FE9664FE3D3E8D41 -:102F10009FCB212523B2C1CDFD12C1326E6707813F -:102F200024EF957DBF6A417BEC98D907983D7C9E44 -:102F3000C9E7BF6F583F0ECC2F267B77B00EED6FE1 -:102F40009C2F98309FEE37292C0F2E2A86FE1F3497 -:102F5000E54CC6734A2B6416A463DD2FA2DBF9BBD4 -:102F6000115760BC6DBE573B0EC33A369F4C239F32 -:102F7000C66CF3F1639D505F532413DF53A7ADFA82 -:102F800036DAD30DFF0AEDF0CE664D1B4BFAFC315D -:102F90000BD9F50D02DF1B849DA6FB4F6E2BE6FAC5 -:102FA000F42DA28437ECDC4E8FDA51EFADDA073C1A -:102FB000DB882FE9BCDD4F7A71756F72BB9F21BD35 -:102FC0004F14F80075473DD427897A2F93B25538AE -:102FD000E7CB9A070FA1C9E17DE9881DF5B0FD3661 -:102FE0008E1F4F0ABD2F8F49BE28AC3F6F9FC3175E -:102FF000817E1966B63F06FBF0BD28BF399800CF29 -:103000009A7E63DDCB12EA6E5C87B17E8FD621217A -:103010005CEE690154842D6F28CEC879AB8A21CC2F -:10302000CB10FF669B1D93D0EE5A53EF6008D7B4C8 -:1030300053E5DF8C219F396166283FD474EDBE468D -:10304000785FFD976CDF7A2D7EFE4F76228B67ECE2 -:10305000C10B3ED6ED89FBA99E82F34479F33DB0C6 -:10306000C7B1BD17CE15EBCF803D8EE501B0C7F1DE -:10307000F973608F63BD0FEC712C7F04F6383EEF5F -:10308000077B1CEB7BCBEA1F4CF66F25FAF9E2FEBF -:10309000AD4149F76FA5015C1BD04E9C92E0E70A59 -:1030A000723FD7278FE3D7C721FFE1887186FD885C -:1030B0005615FD27C5F0C61878FEDE9DBFDE8B7263 -:1030C000658114DC87F8BD7ACA9B0AD7B38714ECF4 -:1030D000FFB00DF01FF854E128FEC32B679DBA2303 -:1030E00017ECF41F15B72E443BFFCADB4FD58D8775 -:1030F0003A2B39C6EBDF39F56C01F0EA5B4AB6F0E2 -:10310000FAFDA7CE1642FB18F6ECC2C619E47724E6 -:1031100039F6B0C49A13F5C09F08FA0CADDB41FC38 -:1031200014E400433874E505488E9ECE19CA5C014C -:10313000FD43B94379375D84CF87D63D48F2AA2B4A -:10314000F3F7A4A7740DCB151FC9157D5E5DAE7C8A -:1031500020704F972B6B6CBC3ADC2F5842CFEF1787 -:10316000FE1F1629A57AB68DD7FF5783F60ADA47D0 -:10317000001FB2870F674EFCFA4CB43F9B645F1A86 -:10318000D4EF77D4DA502E9D15F40BE386D1DE0F01 -:10319000CFB6461EC743CDD1881E9DFAF8391E54BE -:1031A000CE9853ACE3C5CBED51F40774355AF7A074 -:1031B000DEB9C3514CE3754D57C2E887D1EB1B2EE6 -:1031C000BFDC8A7A4756A6D38D759D3FE9FE5BF832 -:1031D00031E3B80D62BB0D5647D49C89E861F943D1 -:1031E000A23EED6031C21F9F090C17A0B7AF9570CA -:1031F000BCAA63BE667CAE481D6144C68771EDB84B -:103200008F0CE1CF44093535611FFE02BE2F7D1FB3 -:10321000194A58EC83F4A91D0E5314F5C21DB02FA2 -:103220001CEFDF8B35824FF2BE18BA6861DC59D3D0 -:10323000C5BAD59907701DB34DFE6E7CEFC8C72D7A -:1032400039887E7358878CCF4BC0F245FF2DA07410 -:10325000F7858BE827C9FEDB2BFF4DA2FDB0DB1500 -:103260003A17A58CEF7B97127133328423E31665EE -:103270008C8EBF2525FC7CE3F8EB67484F5D4E3F05 -:10328000C75F7528733DE26FD650DE06DA5734E526 -:103290007924E371F2F9D4206D73396046F87ED257 -:1032A00079EAE7A8E341B2FCFA5A89AA9FAF8BF604 -:1032B000E9AFE074A0EB5B0CECA18C91F0DB04E3D4 -:1032C0006965F1BAE20A901E6DC9F155A09FB7EB8E -:1032D000AFE6B6547EDE1B049CD667DA49BFEECA61 -:1032E000E4FAF540E63C835DD408769204F861CEBA -:1032F00066BD4847E631D7939FCC3C1635285C57CE -:1033000092DE3A663ED75B55D05B53CCAB9732EA40 -:10331000AD29F4D961BDD5398FEBAD990AE9AD0F6F -:103320006728CDBB53F09BA9255C2F1CC07DA4B0A2 -:103330000BC11E247FA56E0F2A6A90EC3A7D9F5325 -:10334000055DE9FDD3D40E86FE33B3E2D3502F35AD -:10335000DBB99E9906DBAC4890DFFAFC934A785CB7 -:1033600025AB9CEBFB262BD74FAE7C45EA4805F7F7 -:103370005089EE5F498D777F03DE105FA875287E48 -:10338000D40F6A1DAE06D40F467B0F4CD2F0DBCEB5 -:10339000385FF1FD75AA99E48FEC73219EF55A060A -:1033A0009F7D05EDBD230E9237BD1985349EAE5F1E -:1033B000835D1BAE8041F6FF1928D134D29E053BB8 -:1033C0006B4B09C6BFD6E44DE6E3829E573D52AF34 -:1033D0004CF61B0CD37BE65E377F2F320EDF93D685 -:1033E0004C1F8B78954CEF7A59E4FA69D14A5857BB -:1033F000D1B86354EACFFF8999C90F97DC3F327C7B -:103400000E5C2E57C26463CC248F23B8EEF7D6BE71 -:103410009AE783A5B4CB67482E7FD0317DCC668DEB -:10342000F3DB7D2867BE2413BF2DBC7520CB9970BC -:10343000CEBB3AFB8A640FC61762458D1EF2F7F9C0 -:1034400053ADF7B83E7F7402F1678BC0032D27366A -:10345000B71CE0AE394C3E542540F81AF840BD9CEC -:10346000D5A8C2FC459DCCE780BA9BA9E4F72ABA4F -:1034700060267C2B3ABC8CF07842CE9014F626CC99 -:1034800083AC38217EF2614723D167D1D8617B8F2D -:10349000E20C1FE64417227D7FF8005F51D1A3C6DE -:1034A0007690B1E497BE65AD3D8226E384BB5513AB -:1034B000D68BBE2DB14237AEE3B07B33FA757E9822 -:1034C0004E7E1DF34E0FF965BE2D050F105C23DAFD -:1034D000574C2562B3D06FF557ED7BB6921C8BCD60 -:1034E0002539F665137B3C85DFE9E725DC8FF19A0A -:1034F000C0F722D7CB452BEBB03C4EE77DA9F4C4F7 -:1035000004DFDE3C663BC5C5C20DAC02EDC31E0B3D -:10351000E0550A7AF57B387F19E6C7027E36B45645 -:10352000602CB324F4BC7D4F3EF9641ECA6D46F690 -:103530006472BC36BDA2971AD37D7E86FE0949F51A -:10354000733EAB865D618C03FDC59C12AFC77804EA -:103550009F766F7261FF468FCF857430E09EEABA26 -:1035600009E0E770282C2D810FEB78F262C654D267 -:1035700043F471D664145FD42E57801F6B1791D318 -:103580000AFAC7519F3934C3AAC17A37396A63A886 -:103590006F6D72E4D4929FDD017C23C1EFE4701C57 -:1035A000253C74F8B83FCE81FC17FD4E62FF03EE58 -:1035B000A3B47FBDDFBB820F397C511EA7046B060D -:1035C000FBD9E44018ED0C5B0E23BBD266E5F49406 -:1035D0000EC7614DE023FABCBF2BE1F6DAA6C2DAD2 -:1035E000583DAD4F46CF01DBE4AA75913C4438A36A -:1035F0003E3A6E581F25FF4AB180B33E4ED700DFDA -:1036000067609DCBDF988D7668C0E5C1711D375925 -:10361000C3281732265F743CAF4732F887E2E3AD28 -:103620009B25C62BC6F1CC19B52A8E67413E910267 -:10363000FF6688757D56FF19405425BB8D71FD0AC4 -:1036400030DE954A8FD04BABF0838D7C8FF349B73A -:10365000B05F804FCEF6A0DD52F8E6D17AEAC5ED34 -:1036600016E75CB94286F3FA004ED02CC5EDF8643B -:103670007DA6DE3C44724D9747BA7CDA85FA8C12FF -:10368000A7A77CCEB958415B80E4B6941320BC0157 -:10369000FD4643BA31637C3805DCB608F84B99D354 -:1036A00035A497C6F38305F8DEC18CB70B5882BFEB -:1036B0004DE7872F7EBCD786ED1FB6355C546FD1A2 -:1036C000E3C7A3C58D33EFFAFD9712F596D1E2C893 -:1036D0009F143F3E94A9909FEE11C9C897BA043F2A -:1036E000FA9AC00B6771F02B88478F48011FE98D4C -:1036F000C29FE22D0FDE89E733BE47616138CF8379 -:103700001F4F75217E5C2A7C753F7BBED0A7F21DC2 -:103710007B25A4D3FCB688847EF282B65EC97F91F5 -:103720007E8B3C9C9EF5FE1631FE55F29019E5D538 -:1037300055828E0BCEC9AC22410F5CE0E1FA944574 -:10374000E8EF99879EB0E178874C819E32940F997B -:1037500026EDF1047AB7DC5A6B6D48840FC67F52B0 -:103760009CDF773DC37A17D947BABCB5E8722247C8 -:1037700036C889503AC75B5DDF095DCEED21490A45 -:103780003E86F03E7DF9EFAF4196755AEA55304ED0 -:10379000FE49F18F61BDC61459A1DB31482F3E5956 -:1037A000FDF120BC3FE93BF5440F535890CA698CAA -:1037B000EB7DA0473DE321FD0E969C70BE0C5D0F96 -:1037C000799FBC8F473C5CDEDD2BC7C8CF7AEF7991 -:1037D00089F878327CFEE8D1FD5AC371BE8BFA4974 -:1037E00035F493BA316E65F463D61D33D6A7C48C15 -:1037F000F5692793FDA2FE5F24FA451F06BA427EB3 -:10380000A0FB410BC3917A15D65BC47A296E58D0C0 -:10381000E634C0F54AB3C8A7607E29D13F5B202FAC -:103820007807DFFFFDF0B98749CFBA45B4FF43E31E -:10383000CAAF74A3ED3CEC67D5085EFF3077D16C5E -:103840003CD7647F6B514742FC918DF4B3DEF2B0FC -:10385000C5D01EF04F223B60F112A37F96D691CBCC -:10386000F75B503B72FE4F9E17FE3947CEAF8FBBC2 -:103870000BF80DF251761ECE752AC28DA1C78115A7 -:10388000C95109E3D7F91DCC8FFA70C15AE64F151B -:1038900007282CE578900C6716BE8AE0374B3CCBA6 -:1038A0007798C94ECF5F6B223D301FF801F2816BD4 -:1038B0005601B940BD6095467AE4B56D26867280A2 -:1038C0009DEF34BC0FCB257FA77EEEBB703CD4238D -:1038D00057B38809F7D33191E889D6556CF08BBF7F -:1038E000C9E16525785D3BDD62F06B16A11F3301F0 -:1038F0002E3A1E14243D7FC1A31AE802E45961291F -:10390000E13F9773A528E76049EFCD38B917F3D9A0 -:10391000AEDCC068BF4359F608CF93188E27982FA6 -:1039200094037FB2CEAA40BFCA36D56EC27C8683CE -:103930005983DF62598CD594B270E34CC6FED93EF0 -:10394000542541FDF2D24777F4C0A11CB40D7D1778 -:103950009DBD0EC7938B9A3E17AF67661EA43A9B18 -:10396000CE3419E063C719609F7675DE3E33CC6FA5 -:10397000F73AC8096967C3744AFBE9BE5CBB07F341 -:1039800041BA4B4DA427B1C476D8C7774A553DBF3D -:103990008CF2DD58138FEF278E2FE75C64FC7930B3 -:1039A000FEE44F31BE95AF3F0F1F817CC9C3F5A325 -:1039B0009F1AC7C7F3456751E2FC623C998577635C -:1039C000FC05E673487C3E15F34DF29831BF6078F4 -:1039D0003E15E6ABFE3BECA779E479582E761ED770 -:1039E0007FBAF3E836F969BDE11A07D93F0C9A4D61 -:1039F00053D1CEE0F3D964F6A25CCBE1DA3D350ECB -:103A000057D0F7685CE8BEFE8280B305E1AC2A04BB -:103A1000E7D1E07648E5F94E5B547B64BDFBFFC11E -:103A200079B9F87925CE877AE325CF773DCC97739E -:103A3000E9F3217C917E86E10B67B221EFD2E10BA5 -:103A4000AB0A5F0A7C0FC1B8A604B8C6F38A1E523F -:103A500051FFB75902561FF0DF03A53C5FD19BB35E -:103A6000C84A7906B98BAC98BFB7D1EB68C278DD8C -:103A700046CF12AB25414E6FF4B6503BF4A77C28DD -:103A80006FD48EEE0956CD6264FF6F99D9E85A81E2 -:103A9000F8D3C1F3ABF47C235D1E3211BFA47DC10A -:103AA0008B633E7760E810F4DFD23199F2C9C664C7 -:103AB000FD89F2A8B6B5F97CD8FE2D8C33813EF194 -:103AC000A0883321A2921FADE6F247312E5B5BBA8C -:103AD00046C2748EC25546F9949F94A7537B26D64E -:103AE00080F9586C05CFB772B5C849F2D048B7DB3A -:103AF00010AE3C2F2A2271F81AC6FB3D32E95CD485 -:103B0000EFF730B4EF9E85B1CC46FA32617E523287 -:103B10003DCA8A5FAD47BD7C8D89D65180217F101B -:103B200071B5D5F35D2BE079E1CDB24F82E763BD8E -:103B300077539E1268F5A46F78BDC71BB03E629F95 -:103B40002B8DFB48DE57F2BA4170911EA29F57EDB4 -:103B5000195F3ADA51B5A58B288F8C7E747A372796 -:103B6000ED271BED5F93DF0672CCEE49D81733F4D7 -:103B70001376DA7F6DFD242213D25172FCEB6B01B8 -:103B80005A671AF359157AAF85EC453DAE968FB456 -:103B900083E73E9EF1B844F2FB53F9FBCCC5E36CDE -:103BA0006976303D81FEA4DBECE4BF4C4B833A9C4C -:103BB0008FA430EB3878BE4BF8FDD64B4CC67A7CE0 -:103BC000BE28E5A9774981ED3E3796DC5EB26405F3 -:103BD000280F11C3B48976E721CCEF80F635B7BA48 -:103BE000C7A2DF6E0C10440CED661197D2FD24992C -:103BF0002583CB517E1797952CB6A27C46C7D2E57C -:103C00008C5DB6B7E8FEF0CC385DA69DCB675A82D6 -:103C1000FD922677509E47DAB9F1067F4A54D85D67 -:103C20007ADD9F2337E27C73D02EC0BC26A676E3D4 -:103C30007BF500142DD13F7ACE6518273E7EA16119 -:103C4000DE28D8CF897180D1C74F675A45E2F8C5C1 -:103C5000A38C5F9634BE9A72FCF8B8D9867137CAC5 -:103C60009C5F8473EC9154FEBC95650D5797E58E6F -:103C70009E87F6C532E177B302CBC7B893C09BCD20 -:103C8000AE0ECA4B33DB797CD422E2258733DA8847 -:103C90005FB142635E5A0353656CDF9839E798045D -:103CA000ED0D0EA39E7ED5F937CDC877AE928D7AF5 -:103CB000BA9F75107E5EC98CCF2D85463E40BA36C0 -:103CC000FAFD3326C7287F2DD7417906A3F90F7E49 -:103CD000D3C928AFCA921EE840197777D9B4EC8DC2 -:103CE000D3A13E86E3D7D6B2F98BD11FF41B81C78F -:103CF0001B81EE118E2D6BC6EE36278CDBA2444B5A -:103D0000518EB498781E3FFDC0FCBFC9CD277F6A95 -:103D1000F2BC94099CE08F6AED90029E847DFC4683 -:103D2000D0C5F07C7714EC463D7678BEB4E8149AA2 -:103D30006F381F48CC97F7D9E67B43D0B33E5FEB93 -:103D4000578CFB6B5562B4BF561313F9FF7CBE371B -:103D5000707FEECF309FC8EB1A9EEFABC6FDB5A6C5 -:103D6000C5687FADC3F6A4982FEFB3CD97A6745066 -:103D70003CE63E899FEBA1BD4BEE477FFCD9F96B3A -:103D800034C437DD3EA3FB3366BA3F4372EFDA42F9 -:103D900085F4067DDC7D9DD3995FE17E1B2C2B662F -:103DA0004A740FA072BAE4C778D8C340F7FE32F461 -:103DB0004BA9D41EE97451B9A753A3F231B007FD42 -:103DC000E49FF251FD6C19B787EF1BA72E5B89FAB0 -:103DD00042BD9DE741CFBC0234D1B8BD0506D82114 -:103DE0001BE61B7E814DDA8A68BE93C323A7312F61 -:103DF00082E7649FF462AC13EA6933CC1AE677A7D2 -:103E0000B9592095DFE57D913FB359CF9BFF9CC405 -:103E1000E3EDA08FD4C3FE6F14A066E6F912EA5555 -:103E2000D77E358BF491962583192AACE30669D2A7 -:103E30002F3C008FFF2DF4911BC7733A4EB62773AA -:103E400050B24CC6BC3E732402BF2ECE584CF6E88E -:103E5000E2A58C39E1FD6BF13D902BAF087DE6E5E5 -:103E6000C13486F65AB891C7996FB8DB6847DE67E8 -:103E70008BAAA8C7DD372987E179B4AC35B66F16B0 -:103E8000F182C54976E5B5497934A065F27C10DC4C -:103E9000F30CC6DE2DCBC8A13C589147F384F00B40 -:103EA000B1C21C4AB676CEF58CC1F8639A92FA7EFE -:103EB0008E3E5E8EE03B2CC74F70D0F3CA99F9A9B5 -:103EC00049F4BE984F7F6F97F4D4B88BF935416FA2 -:103ED0007B6BB082CB67D4AF59B931DFE7ECFCE242 -:103EE000AF37B254783B24A35F415FFFFF2D7CFDC9 -:103EF00011EE17CA57667D3899DF432B6489F7CFD7 -:103F0000F47CAAC5C37599A15EB954AFBA86BC78D2 -:103F1000DEAF7D2EDDB795F04FE80FD1D74D17D22C -:103F20003FFD78C3EB70F98BB83F4EDC1314E38D83 -:103F300006E7E47C07DD6F433F53E3FED8AEDD3C8C -:103F40002F323FA7E11DBC3F85CFDF34E095F19EC6 -:103F500054D7C01312DA17DFC27B5F727C3EF4D3F2 -:103F600086497F35DEDF1A218F19BF97A3AFA74B94 -:103F70006115648F9A803FC07C0B1C83B2A4A1DFC3 -:103F80007D88EEF3DD59CECF057387F97D18AEE756 -:103F9000990B4C3C7F6382C6F53ECFD0F8C4B8D0B5 -:103FA0000DE55CAE2F487F75AD06F26F49F9938B36 -:103FB000313F69C19857D7BAA17E5DF97717CB8099 -:103FC000470B0A5EFDD00D3ADBB2F2A778BDEAD509 -:103FD0000F8BA1BEBCFC695EBF8211505ACBBFB72C -:103FE00018F9EA0DE5AAF0F3C50A71BE0512A78F0C -:103FF000CF5A9AD34C29E3F7FF50AEFB139905E74C -:1040000009F4FFE424F2A380EE7FF527C51BB12954 -:104010000FEF13899F9C4CD267E6E1EF00CFABE531 -:10402000E800BE6FB24609AEE59837534128F0C0AC -:10403000858BE44724E39104E8BA0EF5654D652DC0 -:10404000A01F77AD63415B49029E33BFC0739EC71B -:10405000A3AF479F7FC4BAE0486567E2BA1EA67166 -:10406000F4759D9E9416C67B677AFC545FD7696988 -:10407000E811744644AB0697E2B99ECE181A2F4158 -:104080005DAB5097503D77E811C99750B7F073BCBE -:10409000B7FC27A4F7AC95FCF79623BF541C74BF5C -:1040A000AD47E879DB728361C6F57BCA770C17F1FF -:1040B0007B038D93257F627CFF9B02BFF22A7839B8 -:1040C0003B6D7BC709C0C7D00189AD87FEA1F367EF -:1040D00015B4C717F49F52D0EE6E3F704A41BBBA79 -:1040E0001DEB304EFBC30AF1AB64781754980D7189 -:1040F00074DD9E385254B63107D6D3BE52F2618A6F -:10410000EC9AE7B366637DCD0ADC2563D7CFDC3F4D -:104110001BC9BB3530B011CB1BD9E0118C172C0B50 -:104120001AF5FCE56D46BDBCB5C3A84FDFB81D4E02 -:1041300007E4D78DEB0A0CEF31D490613DCBC47905 -:104140002E73DD1333D7603DE1BE8E44644DFE9D7A -:10415000E57C07501AFD160BFA25A2E3F6662BF94B -:104160005F8F14F13CFBD02A33E50585101DB0DECE -:1041700021097F969FF8A32EBF67F79D395A80EFDC -:10418000AFB2101C58D81F43FF43B3C0A71B9B9B63 -:10419000DE413C6BD66EE3727CC25E0BF957825CEB -:1041A0001FD784FFBBA5EFBE4627EA9F6B25F26FA2 -:1041B0002C6F33EAEBADF80BEA6FEBA448D48D70AB -:1041C00032B6DFB8CE587FBD5CC8DB2A568574F2A4 -:1041D000DB7249A67BC5A2FE87A25FBE1C8589EE65 -:1041E0009202A710EF5629D11A946B774941AAEB96 -:1041F000EDF0BC9DCB1D2EEF4D4051C4772DDCAFB3 -:10420000105E2D113E2E1F21FF13F403F3C87A4ECA -:1042100005F7B777D9026BC95E7A4152511F69948D -:10422000FDB2D31BB76793F13157E0F7CB6CD08B5E -:10423000EB2A43A003FCCB168F89A03FACEC9F5721 -:10424000507E63599DE433113D9BD8BA5A2C65E2E8 -:104250000FA86FDAA02C33F73613BFBE4C5179FE8E -:10426000A08B25F201FF134C4278E1D271DEAB0B3B -:104270008F7D8CE778CDCE7BCE20BFF394F86BEFAB -:1042800083F56DB3F1F9B73D2F91FEDAEE3D4A7C2F -:10429000712CA009CEDBEE12FCB10FF8A3BEFF62B9 -:1042A000BCD70FFC0A2F8ECCF7D2BCE3F4F8809E6B -:1042B0005F1B6D305D00BE3356CC5B50A311BCF26A -:1042C0006EEB9570DF452CBC1EFD44328E991B2F82 -:1042D000753FFED278BCFA9B789EAB5D830AE9DF1E -:1042E000225E9DA2DFEE94FDFCCCE047986D3E9FE0 -:1042F0008971E5352F945C34AFC26C3519E8D5A2CD -:10430000DA0D747D758591CE17F88CF47DEDF4127D -:1043100043FB427F95A17D71539DA1BE347085A161 -:10432000FF75CDB38CF6BE6B9EA1BF4D5B64A8A795 -:10433000575C6FE89FE1BBC9C86F727A297F40B1B3 -:104340008607831ADEAF676CBA33CEAFAB32AD9857 -:1043500064CCEC753607963D93D2A2786E3DF93C5D -:104360009E9AF6D2975D5184FA98A7ACF5507E5785 -:104370008A3460BCC82AECBC897733033FFFA72A84 -:104380008EE77AB9A42278632594DE7D5A01CF970F -:104390008E4DC4F3B1A20311F1F8392BE91D972515 -:1043A000E9BF4535F5CB2AF0BDBBFD73C92FD5C795 -:1043B00054BC57BB47E1F94CE1E778FEACB76FD08E -:1043C000E44FA0B7FF53C1E5FD37020D949FD4DE43 -:1043D0000FD20CF17BE79B0AFAEDDAFB0732516E44 -:1043E000D404DE5450BF8E3F17F2441EB263FCF279 -:1043F000FBBDA9F3D0BE51A1D0F84705BF6DFD327A -:10440000E7B78070F3D13ED2F967EB7EBEBFD6A589 -:104410000AD1B7CE47817F1AE261C97C79F9CCC84D -:1044200046A45DE0A306FBE5C62573DE417B0824B8 -:1044300035E931C0478DED859B88BE6F4CB26FBAB0 -:104440002A86F9A9F702D0CBC98029E5BEF654C95E -:10445000B4AF93C15904EF6F00DCD06EFCC60838CE -:1044600071F87D127C9E16FE44FD9C92FB7DA78A0E -:104470009FD3D3A3F0CB77059FDD23C56A919985A0 -:104480000276C2D3E556EB52CC33385AF4D1268C9F -:1044900027B4FE40425B96FDEBC04B799877A0ECC9 -:1044A0003F9287F910A1DE23790CE0B4CAA2AD4790 -:1044B000BD18F0C0B71ECEA5BD2F4AEB5FDD5B3740 -:1044C00080CF57F7493E6485A10367E6D03ED9E027 -:1044D00026D4E3F78CB2AEFD153CAFADBF42E37915 -:1044E000F7419813E5EC8134B2635BF7031FC275A3 -:1044F0003D2FD13D8C3D5BACCDA9F493A7AAF877B5 -:104500001B5EDCA2308CA3AC82F7711F478B8E2A16 -:1045100056C49BFD12D984A1DE134BD11F1F5A6BC9 -:104520006118B7D5D7F75E51ECB7B8FFD7575A180F -:10453000DE2FEC5AC9E3B1AFAF35D338E69B2D542B -:104540005F762BCF133EBCF2DF3615C0B8AFAF920B -:1045500028BF7ED6CD7F3C8AF565B7723D28197F8E -:1045600087F135093F97058D7837024FDB3E1B9E5B -:104570009EAC10F66B15AB41390BE73E7B2CE2CFBE -:104580009D8CEE37369F3F6C190BEB2DDEA4FA3075 -:10459000B45B6D8E6CCC43BE7098B74F5AB55BE27E -:1045A000FC45A37BEF053D0A43BBF15D715EEFE285 -:1045B00079E5E2D68624CC6B6372AC18D7E716791E -:1045C0005CCF5858F37EF423C99CBF54FFD0B53B51 -:1045D000D18FB44BE0A3CEF7AAC0DEDF4F7EE8DE7A -:1045E0007CBC8FFEB485FBC7C68BF14A4B86E62C9C -:1045F0008432BD92CFFF47B10EBDFE9CC07FF687CF -:104600004709BE0BAC1CEEF3D6455B701FB7C8C1A3 -:104610003F23FF9B3FFE97AB50AEF514FFD44BDF1B -:1046200065611349AE85C4791C9EF1EF0FDF81F9F6 -:104630007695763AC785871E8AE1B9B67B64CA3318 -:10464000B4954E1E1BBC881F21744E33DCEF6BEFFC -:104650003F33C79F82AEF757F1FD578B7B7CAC9FF2 -:10466000FB0F801FCBD36BE3FDF4FDEB7E0F5BE90B -:1046700063744E777C894DE2F7FBEFA37196AF3AF6 -:1046800021E1BD94EB2C7E8B03E0FCCB316C29DA6D -:10469000C13FED64744FED38DE570356F272A74AFE -:1046A000F598B8B7F66AA746E5754A603CCA95A57D -:1046B0002F769422BC0E173D18C0EF359C3E2EF489 -:1046C00059A6F2FB8E02F7CEF69B9915DACF1E9013 -:1046D00022E43411EBBFE15C3E0B023FF9B5B81F99 -:1046E000B77ADDCF89CFF9DACECC413B63D2AA537A -:1046F0009BB01E5AF7C739A837FC16E404E257A846 -:104700004F622E18A7E59C93DE5FDD7742417BFE6A -:1047100069D3D01C847FF8A044F7AA421D67887F24 -:104720003E2CFC2B37546671BED13FC944E7E99F4C -:10473000C8ED1371FE0313FF9489FCCBBA4E7BE5E1 -:104740000A3CC763663AC7AD0D43996A8A73390953 -:10475000E3A24FFBD7221F2FB9BD5909935FB6596A -:10476000E06D72FBF59526DD0EB7883C2526C17AF3 -:104770005A047EB532FE9DA0963E296A07BA6DEDB9 -:104780009F45FE8DD68E8B7F0766347CBBD4B29D51 -:1047900071FF865E47FB2B315F0BED2FE37DF5301C -:1047A000E1555A91676CF022FA5D68309FE227ED7F -:1047B0003D8CE225ABCF4DA4F2FDE737D3BD27AB4F -:1047C0007DE841940BACCC447AFDEAB051BF992D01 -:1047D000E876B6D06FD654827D52C186ED13B043D1 -:1047E000BE5CC9ED90CC43CC609F243F27FBC42A1C -:1047F000FC86305CF09914EB9E57D57057652ED22D -:10480000D576C26F06F88D7895BCCF8D959C3E7598 -:104810007A5E76E81D05F5DD505F6A7A5E5A55BF0F -:1048200011D7B36594FCBBAB05BDAFDEC9085EA173 -:104830009D4E82D37B6C67A001F0F23D5807DE5F8E -:104840003F1D08A467C1FBA78381748CCFE9F4DF07 -:10485000BED34EEF6DF12CCAC6EF6DECAAE4F1F3B6 -:10486000F7FB665911CE37ECE474A7CFF7DBE8B25B -:104870006CA49F29962105FD9385FDA73251AF9B1E -:10488000F2FCE26CA4BFD1D6B975A258E7BAFCA578 -:1048900074EF077ECC40F7B70B3916DA105510FECF -:1048A000B7AF6384BF03CFFD6B3BD2EFFBFDE92ABB -:1048B000CAC9F75E480F23BF3F7D302D6282A156E3 -:1048C00089EF24BD6719BC86F4C7E7CD94AF103AD1 -:1048D000F8EE83488FA1E7D2E81ECDEDFD9BCFA077 -:1048E0009C5BD53FF71D19CBA7FEBEF4B07ADDF86F -:1048F000A589F9C5EF76EECB47FEF9BECCF9C4ED3C -:104900007DCF923E7BFBF9B335983FF8DE0B7F9E5F -:104910008AFC2CF4CF67A7221F0BFDF8EC546C0F18 -:10492000FD30BD23957EF2E32AEE3FD1E5A3FB35B2 -:10493000D9E067B959E087BB7B7B137ECF60CA891A -:10494000251407D0DBA794F27BCC537ED1987D73DE -:10495000C27BDD3199F225269F684C5F998097D7FD -:104960005759747FCDA5F947441E82EE1FD9129383 -:10497000F9BDBA36337DBF6E798CC7DF93FD268CC7 -:1049800005AEAEC6F3BE35D787DFF1C1FBEB181716 -:10499000397D676984EEAF87AD473C097AD0B2981C -:1049A000299A867E90FEB428EA43CB62F2A9B40429 -:1049B000BFC86FD56736A21ABF2C68F46324FB41C9 -:1049C000E027434E889FB4AE8D5A7439B500E6FF98 -:1049D000E546A662DC66847FA4F9F3E48749F69392 -:1049E00068B107ACF89EE6E1DFDDD1F54C3CAF03E2 -:1049F00029E87DC344CEB7743AEA8E99E81CBA63BD -:104A00000D560F94FF28DA0F80D80C635E50FFE23A -:104A1000C7D14EEF3E7F5D3AC2ABFBB5450CBF2B15 -:104A2000715A6DB096E27BE73F6F5DEA8DE3C70890 -:104A3000FE3191F3C7617D6014393753CCFBF79297 -:104A400077D3279A84BFE1FF6F790776F55513B9BD -:104A50005DBD9CFB3DB85D9D2C2774FEAB8F1B128A -:104A6000F01EC97FDF21FD05EC5FE2BFA1891AF5C9 -:104A70002BEC5F984D76F16B4BB235C7C8F14B64A8 -:104A80009FC9E91D39BEAEAF85C2FE2356B463FC93 -:104A90003CFF34B444A2EF4B850212E9D9A1164B76 -:104AA00004DBF5F5C496F0B8E0529F44DF0BD1F576 -:104AB0003F5D3F1C6E9F0CEDEEB8BEA8EB85B100CC -:104AC000F78B2EF15BA8FD3A25780BC2E9B7511B95 -:104AD0003D9F32838F0B7CE008FA3FAFFB8244DFBF -:104AE000F3D2F5451D3F93F5C90FFA4B2EFA9DBA47 -:104AF00087055EEAF4353E892E7439B5AB92C3A7BB -:104B00001DE57436CAE98F9541C7E87A37C8E9BB15 -:104B100070FDBB2A19BD3FF917722095DD9D21C696 -:104B2000DF8AE7066561ECC57A5C6F118B515ED454 -:104B300068F2F3B62A4E0FA3B5EFAABC343AFE8151 -:104B400098FFEF45C7FB27FEF7D05B87F53F25F5BC -:104B50003EE755D5FF6822C0D56EEEA0FB51EC5F55 -:104B60002CE4B74EEE1712F218E499018F8F142936 -:104B700026B47B426DDCEEEFC9D25E21FBE4257EDC -:104B8000EFFE7691AF74DB3995CA1EFC8018B67FB4 -:104B9000D94D7E9BDBF69DB0F8E1FDE56BA549E8BC -:104BA0000F5ADE66DC4F4FAE7F6EA21FBC675C2FD4 -:104BB000C515C28F9768387E2B6E16FD213DF91101 -:104BC0008C3DB6A31FE7327C9E70DF02E6592D9E16 -:104BD0005F21FC3B2C490FF8F1C0EBE4EFC1B810AA -:104BE000D2AFD22F515E48E818F777B4F773BEF012 -:104BF000769B44FCE46D919F115A6723FFB6AE4744 -:104C0000BC23FADD7AA744FADE08BDC26F8CBBACC8 -:104C10007EEC17C41793F508E7013E0EC65BD02F54 -:104C200073A468AA84F5D56017E2F74B439A766DB2 -:104C3000015F1F8B107FF11BFC281F1CFB37B22369 -:104C4000973F2FB16CD23B92E22F3DF392E22F4778 -:104C50008F14E03842CF50E13FF41F26EB19ED7D71 -:104C6000272C68177C529C45A91AF6B7905F708272 -:104C7000CCFDAC13FA2515FD4913049CA66DB113A8 -:104C80009CE6BCB1321BE95C3F9FF717F2F37AFF59 -:104C9000F50FEBF1BDA96FC82AF2DB1FBFBEF6E727 -:104CA00005BCAE59357C6F6D3ADA21EFBFB1261DD8 -:104CB000E1F86328F13B4A3F3C29A7F41FAE15FCFD -:104CC00008E45B4115E6DBDE2DFCC632C8B78CB8C4 -:104CD000FF25F9BD1DC21EEBC1EF1B21FE3DCFE339 -:104CE000DB3DE382F3A8FE5031CF239639BE3EDB95 -:104CF0009FA5A2BE57059BC538ECF7ECAC1BE32B78 -:104D00003DB9C19F127D3C6422FC85F7F97727F6F7 -:104D10006B24EF106418FFA8015963A5BCC61C8A58 -:104D200083E8DF85190776A8F88EC2128CBB5689F6 -:104D300038488D9DC938FE364B706B25C65D0664BC -:104D4000DF7A7C47F665E3F79292E3317A7C588FFD -:104D5000CBE871E2D1E23212CE53C3F12CF13B2702 -:104D60007AFC857D81E76F764DEFA0FBAF63B12FB5 -:104D7000F1CF11F194D5686F26C753EEAAD4FB1B6F -:104D8000E3695B2B9E217CFBB471B41F4C1C6D7ED0 -:104D90008D9E27CF3F39EB833CB25FFEF21F9924F3 -:104DA000CFFACF92DC393D9426EE710E723F75BF7B -:104DB00085ECF5D36007E526C8B35F55F2710FF5B2 -:104DC000CF227C3C106B4CC7FE7FADE4F0D9F2DA09 -:104DD00092C5A84F876332CFC766DCAE391093A760 -:104DE00070FD60049C364D4C0127AB3D751ED054C0 -:104DF00081D753ABF8BE67BDCEED95D05A1E3F505C -:104E000005BD859A14E227478BF224DD8F3C365589 -:104E10007CE1F921E2B3ADB7F2F8EE25C717FA0647 -:104E20002CAC3885DFB6690EF19B4BF5D732B482D6 -:104E3000A7C6F9F3769D9F5473FFADAB8AE7F33BAA -:104E40003B26D5E377F1F47DA78023F35E5A9C2FB0 -:104E5000B3FAD2FA2DACB8B47E9B2B529C5F8A7EFB -:104E6000DFB8C47E3FB8C479D353D1578A7E7FBCA4 -:104E7000C4795FAAFC9FF8E7703D39BE991C0F4DBD -:104E80008E73A6BD747318DB364BF70C4511BA99B7 -:104E9000CF35E3F7D3E5ACC7ACC8D7E6CFE0F180B8 -:104EA0002D8DD6C86E291E17D5E1F55135D7BB54C7 -:104EB000EF99307E3F71BC3FD6980D747C7A062303 -:104EC000BBE1B44D7C0F4956C72DA4F353E97B38A1 -:104ED0003DB6D4F1A527C578A3F191A29AFAF3556E -:104EE00053E8FE50CAEF54DC2FF440B58F91BF86D3 -:104EF000C9DAB84534AF360EE5CC9817F9F3CC28AB -:104F0000A3FC3E68772F22FD5973E3FA7688B897A1 -:104F1000735E991BFD744E90B71817B90FE323E425 -:104F2000D757A99F3E5F9797CFB7C3C2248C63859D -:104F30002B795E056BE935C4358E5BA2BF5B2151D1 -:104F40005C632CD2FBCF4C51EF1E373F1784AFF779 -:104F5000804AF19697677CA782EEC58B38C71D2AD9 -:104F6000EF7218ED0C58C71D2FD411FE2E3F34E3FD -:104F7000572DA80F7A6482F3083D5CD85727857DAA -:104F8000A8DB5783682726D81B555ED3687CA92ADF -:104F9000155FDA2171FB37FC336EFFD629BE92C450 -:104FA0007CAA69021E2BA2DC0FABDBB535FE88297B -:104FB0000FE05077A7399A06B2B76E53B582FCBAA4 -:104FC0006E53919DFC4A2BF79B7478A73AF77AB100 -:104FD000CE2DC786282EF16CF23D732F8FBB0E09A4 -:104FE000FCE9C2B385FA1DA572178ADF3133557308 -:104FF0002ABF782BE8FDB8BE153D7CBD7A1CA435D0 -:10500000AACDC2794E1D19DA84656D9B7B16F90D08 -:10501000579DD984723374FEECD1ABC80FA068A938 -:10502000EE0B586BCCB48E6751114178CD95296F3A -:10503000B76EAE4CE7ED6CB5911DEEB430337E9F8C -:10504000D5B990CBB1DAA69C5958674BB2480ED768 -:105050001ED3B26EF6C6ED7CE7DCB5B908A74F8A61 -:105060000FE9FE82EB14FF4D788E9F363EB4FAF8BE -:105070006B946776C3A0313EA4C77B468B0FE9F1E2 -:10508000D950D387867872481E9A837E95BA174E78 -:10509000517C38D427A92E773C6E143A704621F8FB -:1050A0008A7811F457F0BD3A38F6714EFCDE008F65 -:1050B0001F3D87F9B80A7E4F4FA5BCDB1F613E6ECE -:1050C000197E4F8FE7E31EC47C5C05EF7FF07CDC2C -:1050D0004322BF37D47F86E24D3D5E63BC428F479B -:1050E000DC2505B679730DF10AAA27C72BCC766E9D -:1050F00087868E59E8BBE8A1E356E2B3F5FD2B267F -:10510000A03EA67FAFBC1DE30509FEA5F7FD3E1B33 -:10511000DEEF793FE0B3619CA06EE01D4523BE1336 -:105120002DC014A67639A6A0BD8F70A03CBFFE7A14 -:105130001BC2F513FDFA7DFFE3D7FF347EFD8C38EB -:105140005D12FFA80D98E85E79ED31BFEDE604FE33 -:10515000B025C0FDC35B3CC5447F0F048AB356260F -:10516000FAF19BB8FDE69CEBB1253E5F54C3EF0F0F -:1051700038A5D4F70B5EF7EAFED711FCF6756F4A37 -:105180007D27753C604B13E723BABF7F647CC0F773 -:105190009227C1CFFFFECFACF47717069E4F23793D -:1051A000FED10B697B50EFAE6D5A392103EAB5276A -:1051B000D3989BCB23435C617993C96FCB4C154744 -:1051C000F017D0F74293E3054D26E2EFC3F18226B4 -:1051D000F914D5857E7EC3997FCFC04F643F2B45A0 -:1051E0007AD0BE7876B5E41B6023E3073070019B6C -:1051F0000EBB68E27682AFD94A76C127C5155A0E32 -:105200009CD8887E82496C7B0F7E7F7292C7A48275 -:10521000284A1157E0F99DB5428F48F60F207EA02D -:10522000DC4FF60B665673399459CDFD983B51AF60 -:10523000CF8D8FA3BF977CEE5F147269343FE3621A -:10524000D1DEDD54BB05CF2D3CDFC490FF77373571 -:10525000583D09E3B9AB79DECC0E8C53E424C62962 -:10526000783C22393EA1F3A7BA818FE7E0B93FD05D -:10527000CFFD472117F767D61DACA77B26F17572C6 -:10528000FC7CC0357CCF308BF17D312BF773915F87 -:10529000A176FE8787F0EF12B04016FD9D83D07196 -:1052A0004F9703F9C87C798AA4917F7BD8DF8DFE64 -:1052B000A8C5AFB4CDC37CE0BAA5934EE0B92C6DC0 -:1052C000B150DED1E2579AE9FBE3BABCAA5BBA7BE4 -:1052D00003FEDD9AA51592CFA6617B5303B65FFD51 -:1052E00054143D7B6C01AE0EE825761C7A17937F33 -:1052F000BBBE1AD65BB750F8BD5BB85C5DDABFD0F9 -:10530000C23F6E659473878B3E22BBF96C7F1DF99B -:10531000B3B331DEEA8DCB99BA1740FE64C4E5CF52 -:10532000DF2A77BE58CDEDC0CB40FEE07A9C0B79EA -:105330005C30F9FCDDE2FC479327A3F14F941FFC9E -:10534000EFF2840B24575CEE6A684F4F8BCB5FB54E -:105350000FEA6347C7BF87847E95358AFEF580C014 -:10536000F751F335FAFE3E7EEFEDD5FF3DE257BA39 -:105370007DA3FBBF757BE8F702CE7AF9AEC08BBF89 -:10538000395F198562CA7C6567EA7CE51B7A25FA74 -:105390000E8BC8573EA2B0FAFD3998A727EE2544D8 -:1053A00002A4DF1CD9F5EB4D4FE4E0BD044945B143 -:1053B000B3BAF704C9E7D5A0CF901ED4FF2EF74BA0 -:1053C000F5F2FCD2D57DC6FB0F7AE9ACE1F1F646E9 -:1053D000D80FF991451EDF9C039CAE437E25A2B9F0 -:1053E000D12FF41539D12F14D262B97A7E6084CBD3 -:1053F000A594797CED6C88F2FDDADB241FCA83CF9B -:10540000EC27F2F3FCBE4BF513FDBCDA987F7AAEC5 -:105410008ADFFB690E4A12EAA356536015E5F71EB0 -:1054200094D45479A2EF087973B5F0D3EE55381EB1 -:10543000ECBD5CA2BC5ABC1783E7BBF720CF9FDF53 -:105440005BCBF3E775BFAC9E175F19F7CBD27D1826 -:105450003D9F5ECF8FD7EF872EDC698FA27EB1CDC7 -:10546000D2EB423A1CFE4E0FEA22D06E17DF194FE4 -:105470005EE72FAAEB775553BF51F59B3F56A7D058 -:105480006FFCC24EFB73F5A87AF95FAB8D7A39D504 -:1054900093F5F2FF2ABFEC37C43E53F9D552EB67C0 -:1054A00023FABD7889FD7E980A1E5DB6D4DF0B6DA8 -:1054B000AD11FC37E9EF92B011F77BB87CEB91B4FA -:1054C0005F5D41712E0BC5B974FED293C1C7F78AD7 -:1054D000F1F4F2F3359CCF8CF65DC945A2DF5AC9D1 -:1054E0005F553305BF1F6FF49355F71AFD6497F5A9 -:1054F000390DF549D17C43FFBA63C586F629B189D8 -:1055000086F669276B0DF51983971BFA5FF1768391 -:10551000A1FEB921A39FECAA738B92EE1D71FCAE84 -:10552000078C487C6F96F58B867E056DC67D15755C -:1055300018F735619D715FFAB8EEB0717F253DC6F1 -:10554000FD39D17FEFFDECFEFB9857E3DFC1E92F7A -:10555000A1EFFEED68F2D077AEF5FB7FFF09FEEF1D -:10556000D922F072000000000000000000000000DE -:105570001F8B080000000000000B53E16760F8512A -:105580000FC15BF918182EF021F8F4C01CCC0C0CDC -:105590009C40ACC8C8C02001C4FC40CC06C49E0CD2 -:1055A0000C0CFF81F81B10BF05E22740EC0CC40770 -:1055B00058B09BE3C6CAC0E001C4DC40B378988908 -:1055C000B7DF8917C17ECCC3C0700E889FF1D0377A -:1055D0000C061B5E27403FBB7E43ED3A2932F0FEAE -:1055E00006612131609A1447F0A78AA3CA0B8B2168 -:1055F000D8C9D294D9950FD40F00F19321F080032C -:1056000000000000000000001F8B080000000000E8 -:10561000000BED7D0B7C94C5B5F87CBBDFBE92DD45 -:10562000CD26E44900370960501E4B80C84BDDF0A1 -:105630003252C40411828A2CAF10027914A9A5FF3A -:10564000DABB0B2804AADE5851A37F6A17041B2D6E -:10565000DA80D11B6DE02EA208D56A684551AB0DEA -:10566000888808498C8F6AB57ACF3933DF66E7CBF3 -:105670002E89B6FE6FFFBF7BC3AF1DE79B993367D3 -:10568000CE3973E6CC9999B3268383192E60EC1B2F -:10569000FCBB9C319B893136A62B6D573A86AB39C2 -:1056A0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D45 -:1056B0007907C3779FA1306867EC5EBF8BF2BFF0BC -:1056C00017525AEB2FA27A77FA4B287FBBDF47E9B4 -:1056D000667F197DAFF157537E837F0DA59BD4451F -:1056E000692C05FA66458559C98C553D9393B719C0 -:1056F000725B668D4F504743FE15233366017C9FD6 -:105700004AFD31D5BD69E0E8AE7A1A9E9BD449FDC9 -:10571000104EED128E17B3325B8C7A5938CE3B9710 -:105720000878F6D69A9CE4A8F50623BCDB4B00DE8D -:1057300050287085AC39D1E15D8CF03697A8BC5EFD -:1057400072B0263B3A3C0FD6ABB941C04B0F586301 -:10575000D41B83F536DC20F0EBE7ABC98ADEEF78AB -:10576000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4E04 -:105770005D2CF246CC263136AEAB9D3E652CC0701A -:105780009C2AF315121FDC995F7F93CFD84D081325 -:10579000DA0726B19011FA0F24B1E0FA2CA9FE4CD9 -:1057A000AADFDAF7EB6F52A5FA014394FA26D6A0E6 -:1057B00060F9CF518E80EFF7F97329DD28E4E7BE59 -:1057C000A106C6B05DBA393808DADDE3F790BCDC73 -:1057D000ED1F4BE5770939FC7721674121670FA25F -:1057E0009C41BA15E5CC8CFDF95A4B014EFBDE7895 -:1057F000B6D94DF2B598F05419C1DFB077C8F6CDDF -:1058000000FFBE1B569DDE06F46F6B1EE63142BDE7 -:105810007B866AF2C5BC2CB9ABDE3DB34F38170DA1 -:10582000257A97219CBB3D827F2A0C2CA2DEDD339A -:10583000C2F52AB0DE5D9E30BC5064BF774D09D7FB -:105840005B457C56584983BD3B5F763085E623082F -:105850000AD1D784F48579F9EC80EB9456689F924D -:105860009C97C6A0DDFD381FCD38EFDC4417AD3D59 -:10587000D2D907DF332CAC1AE10365F71B015FD3E4 -:105880006C7722D2E5F66B8B98328CB1BEA23C3598 -:1058900050A464015CFB9C2205BF9B6643397C7766 -:1058A00089F2E435BCFC762C7774952762397C4FFD -:1058B000AA8672C8DBE7F2F23BFCC089C15DF5360F -:1058C000019F7DC4EF74FE1DD88AF4318DE6A98650 -:1058D000F713282440BF83988EE9C27FD3A07B337F -:1058E00016DABBF0B50DAEA7BC86DFA6C17194D7A2 -:1058F000F0B15DD82F6321A47D97F465DE5C311F84 -:1059000058773A277AB3A5F24CD593A0029D325F1F -:1059100032B200B02013C413E1E9DB153103E1D941 -:10592000E3FC4BEEDDFC330D95E9A0A547053D34C6 -:105930003A6CEC2FD3C13240A6C3C601321D2C17DE -:105940009C9F0E3B989BE81C8B1E5ABF9B87C8FDF3 -:10595000C65D24F7BBF922B9DFB88BFF39FDD664E9 -:10596000C9FD5AB3E57E6BB2E57EAD39FF58BF4C39 -:10597000F5C064407DA5FD5D28E9B7AB99EF2CB675 -:10598000473D87F349D373A6641FF3D9BBF809EBEE -:105990001463F99170064B7A15E07C8AF5008EF756 -:1059A000FC705C3A3883F470BE16F8B0483DDD0DEB -:1059B0000E1BA81F8749E1ED428688FE99EA6345E0 -:1059C0008EC8761E5DFF39FAFE9D8A1887E1BCFD00 -:1059D000BB7574CDD6E39326F06186F3D183B97499 -:1059E00070B2F470DC029F90725E386EFD382E1437 -:1059F000FD071469FD027A0CEB6AD70EF8D13A95CF -:105A00006709EE04FD10DAF7E5295C07CE355EEB99 -:105A1000B640FDFD232DA1CBA1FC5CB0206881F236 -:105A2000C94F1E75A21D53F1A451C572C33E1BADD3 -:105A30002F6D3B142AAFB2B4DC3901CA3B9E34B29D -:105A4000EDD45DA601C7774AE81416E2F9521BCFE0 -:105A5000566CDB7F23B62F6BB2301BC0AB787AD984 -:105A6000CC09905F76C8C4B04AC5CEB5E6BE905F9B -:105A70001E541A300FF8D23A15C8B3057742FD7597 -:105A8000FBBE6C43FCCF359A06213E67609D70C318 -:105A90003AF192A3257536D0A73CB87B1AB62FDF12 -:105AA000A57840C301FE3B0F6620FE8F281E0BB079 -:105AB00070457D3C7347CC97538D461AEFAA6D4ACB -:105AC0009001BC65AC761AD2B302898378782C41F8 -:105AD0009BD235DFCEF8EBA83F2D5FF108F407ED40 -:105AE0002B1F573C38E44A03F3E13C6E7BDA56F255 -:105AF000901DC7BBD63CD881E3DC68C67ACB820B4D -:105B00009FB2B911CF6DE66988EFD66DE6D2A14894 -:105B100047B6A06828E2F77F65FCEA8C5E1CEFAA16 -:105B20009196ED46C083D943036739BAEBD933B0B8 -:105B30005EB923D6CF72067A9FD6EFA0B97858D730 -:105B4000F72F0D89A43F56D41B99DBDAD58F261F7A -:105B50008123423EF63A88DE1A3F57B9F814D0F84E -:105B6000B92A51F057EDC89F35AC3B3E77225FC84C -:105B70009E7651FA0B583731DD02EB3CD2EF5EB026 -:105B80009FDC64977BE8FB03602761BA15EC244C2B -:105B90001F043BC92DEC24ACB71DEC244C77809D31 -:105BA00084DF1F067B1CD37AB0C7F1FBA3608F6331 -:105BB000BACB1FA0EF8FFB6B286DF0D752BA07F955 -:105BC0000669A33F48F59EF2D753DAE46FA0EFCF02 -:105BD000F89B28BD5DD0D1399115E03AEAF432172F -:105BE000923D6986B7C004F9A4229E4FBD21506042 -:105BF000867CAA0FF24097BE2B430516C8F7ADE688 -:105C0000E5036E6193AC901F10E0E5D9B77B27D90F -:105C1000209F5DCBCB076F0D4C8A83FCE0202FBF0C -:105C2000685768523CE42F6AE0E5C39BD9643BE4C3 -:105C30008787783EEF25EF6407E4F35A783EFFCF7D -:105C400081C94EC8E7B7F2F6E3CF068DEE28EBEF39 -:105C50001E937B31AA9C03CADB5E3503F266F74DC7 -:105C6000A8128F2AA728DF68F252F9FB4ABB578592 -:105C700075BED1ECA5F22F94CF29FF94C947E5F169 -:105C800006A580F2661F95F737C451BEC914A0F26D -:105C900011863E3C6F0E507981A15F01C27FC61410 -:105CA000A4F26B0C8378DE1CA4F25FA8C30BA640A1 -:105CB000FDC70DBEBDA8EFD62BBE32B40F99DA904A -:105CC0008EFA4AB32B77E2E0D0CECC30D33CD8F377 -:105CD00087FC87681EE05F32E64B1F46BB14E01C62 -:105CE0002438268063EC194EDECB632538792F9754 -:105CF00069705E2138B6DEC1D9F3F278199F97CB6F -:105D00003538C7088EA377E3CA7B65A28CCF2B2BCF -:105D10003538C7094E62EFF0693C2AD3A7F168987D -:105D20003E67707D589FD23B7C46BF26D367F46B9D -:105D300061FA7C4CF864F40E4EE36B327D1A5F0B13 -:105D4000D3E72B82D3BF77E31AFDBA4C9FD1AF873D -:105D5000E96332209CACDEC179EA6D993E4FBD1DEE -:105D6000A68FD380F419D4BB71E5BF23D327FF9D41 -:105D7000307DD2089F21BD83F3D43B327D9E7A27AC -:105D80004C1F37E133AC77E3CAFF8B4C9FFCBF84D9 -:105D9000E93384E08CEC1D3E4DEFC9F4697A2F4C59 -:105DA0009F3C8233A677F88C3D25D367ECA9307DE4 -:105DB00026109C71BD83D3744AA64FD3A9307DA60B -:105DC000109D2FEDDDB8C6BE2FD367ECFB61FA5CEA -:105DD00045700A7CF5840F03388ED8709E3927D31E -:105DE000E7997361FACC213853014E4ECF70C6B794 -:105DF000C9F419DF16A6CF02827365EFE03CD32603 -:105E0000D3E799B6307DCA88CE57F56E5CE3DB6583 -:105E1000FA8C6FE7F4A9B278263BD0BE4B649EEDB6 -:105E2000D0E492930D079C9037D99907C1BEA48402 -:105E300076207C582BC92E543D9A9DE2616887CE0E -:105E400070BA3DE8F7316AF6086BA1FD827D57A272 -:105E5000E40FFAD230E916C4D701565BA45D923044 -:105E6000364EB28712BD4952BE4F615FA97E4A517C -:105E7000B6549E567291549EE1CB93F29965E3A578 -:105E8000FAFDAB2749F90BD64C97EA67056649F945 -:105E90009C9AEBA4FA836A1749E517D6954BE5431C -:105EA00082ABA4FCC5F5FF47AA3FAC619D543EA25E -:105EB00069B3543E32F40B293FEAD00352FD312D31 -:105EC000DBA5F24B8E3D2A958F6BDD23E5279C7E6B -:105ED000466707CAFBFFF5058CDB831966B20743EB -:105EE0000E33E5CDFB6C64FFEFC73CF0D3DC7706E7 -:105EF000E5CDCF2E7627E37E1A01C07A5FD0B7ECCE -:105F000042F4F7DC3CDE77A10BBEDF6CF68D70450A -:105F1000F1477854DF3E03F98B5A14968EA9DB8043 -:105F2000699C51ECD72D5CBE3666E53F148890D352 -:105F30009AFE30FF207FD86026FB5593EF8DFD4BF6 -:105F4000D31746F4B3A1BFB964FB50FE7DB11DFB6E -:105F50002B7A11E75995B96330E2A5EFC7923D5608 -:105F6000EAC73AA08CFA790DFB89F07B590694E9CF -:105F7000FAB1966C17DF453FC7705CB1FAD9983D0E -:105F80005E1ECF8072EAE75D5D3F1B0794EBFA89E6 -:105F9000E3E381EFA29FF7CE3B9E9C89F2782E58D7 -:105FA00049FD74E8E866B960A5AE1F3BF583DF17CD -:105FB000933F17760169C0674B4729C9C17FDA58FB -:105FC00000E4C29C59FE6BCCB3B76C6C10F6E38650 -:105FD0007EA11ECBE5FEA3A70D49349ECFE280FF34 -:105FE00011766AD77E3640FBE2A5024516048C6026 -:105FF0007F5B296473C9AEE20137B9216D3A30F095 -:106000006EEC678BC33308F26D4D93CD8BA3C8D371 -:10601000D25AD3A9D648BF88B6BF99C472ABA1FFE4 -:106020005D369794D7D2958A8B097F04E54FC0BE21 -:1060300085C17EE0CFB02F6040AA774D7C9FF60EE1 -:10604000EC6F30DF0AFB1B2C676C2DB53B21FCB4D9 -:10605000276E578248EFCF7EF24313E9F1007B357C -:106060003D15FD6EFC6FC19A78F4F187F15B18E87D -:1060700023E5415D661AD2695F48FBDF8EA72DC11B -:10608000ED48D79A4CA0A9A897CDD8EBB0C9CD4878 -:10609000A26CA6612C63B3AB8BA7A6D12C52FAAF2E -:1060A000023C67358E34410BD6666ABDD163EF8200 -:1060B000CBBCA613481F2BFC4338D714423EA2FF8B -:1060C0006B8BE4FC5CA676E581DF838DD9826FA2C1 -:1060D0005FB7D7847C2D4AE5F8CCC5340F8BB9BFA8 -:1060E000A3C4C5DB6AF8542D36B110ED4F03290C5B -:1060F000FDD18164AA779DB6CFD4E15762B27A8B85 -:1061000080AE250B8D44573DBE6FEE8BF71A86434C -:106110005A73B7095D9B3DE13FCF2797B332DE9FAE -:1061200046574D5E4E09FE9E40FE43FA3EF21FF07A -:106130003E29F8DF25C79CFF5516DF4CE47FC7FDDD -:106140004646FC127C9F23F8BEB456E6FB1CF49333 -:1061500043FD39ABB382EBB17E5D1F89BF307099CF -:106160000EB5774D05B5DA0DFFB7851C5C57B3FB4F -:106170007964EFF565BAF1093EDC28F8305F478FA6 -:1061800039826FF305DF96B1C06D19E43F0A9AD0EA -:106190002F36AF4C61A82FAA7EAAF1AD55E29B4FD6 -:1061A000E39B0EDF1B05DF6EFC09E79B1EEF56C16C -:1061B000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2BBA -:1061C000A0E75BAD38777099D1DE29F616F439195E -:1061D00051FF9AC22BFB9C8CD00BD716154BF9B9EB -:1061E00025F3A4FAF37C0BA5F2EBCB964BE5F3ABCE -:1061F0007F28E517ACF989547F6160AD54BEB8665D -:106200009354BEB4F62E29BFACEE7EA9FEF2E03662 -:10621000A97C45FD23527945C36E295FD5F4B4545A -:10622000DFB06FC8D5285F2F1D3532F4977DEA792E -:106230009FFC759F7A4C1EAC538932370EE5D94DC1 -:10624000F27CCA9F4BE969BF87E4FD8C7F2CA56D6A -:106250004D07ECE87FAC8A03BD9F0876B8F1CDB559 -:1062600035FD70BD81F6E3196B36B6AE0D40FE000C -:106270001E46C1BC99516766A1510CA4BB6F589EC4 -:106280003B8C11E5AD3D94D7A92CD4A77BF98CD6D6 -:10629000E8DFDB958EC119E8277CC3C27646F8EBB0 -:1062A000BA9F57B04CB42B62959F35B0B2C8F3ACCF -:1062B00093467E4EE2344E3A698474A599CFFF9599 -:1062C0007B32263127E64383ABA3F85DC2FD350060 -:1062D0003269C8E71C69DE2FABBBB86B9E33EC2775 -:1062E0009BE476797094F47D45FD04A95DAEE27B74 -:1062F000D708F5CEEE37D27ACD4207065C330CF1E3 -:10630000F39EC4EFAC2985ECAE16BFB7CFC9818C24 -:10631000FDD15F48E9ABFE224A5FF397507ACCEF9C -:10632000A3F44D7F19A57FF65753FA8E7F0DA5ADC7 -:10633000FE00A527FC35949EF4D7527ACA5F47E940 -:10634000697F90D233FE7A4ACFFA1B286DF337511A -:10635000AAE9CF9EE4EFB4585FCFA0FC459133F398 -:10636000AD6C5DCDC42E398B532DEB50CE34FACEAF -:10637000A8B308794895E42111D76192B31ECAEBFE -:106380004C420E63B58F5E8EF2D6F77B9037C6D641 -:10639000911CCC1472F75DE58DA1373E05E52953BC -:1063A000274FB21C6A72A4E9815CA568B83AA64B73 -:1063B000AE661AB99DA4C9D5CFD14E8C626FDDA04F -:1063C0002A62FDE3F611F36518D07E5B25FCFECC56 -:1063D0009D4EF94ED1F77A00D782F5D4602EAE23C8 -:1063E0009DB97F1B8CFEF1CE6316867EF858E3D3F1 -:1063F000CB4B6CBA7B69FF501A84456D54F7725BC6 -:106400001CA7ABCDC00A591E9ECFE61FF3013FE388 -:10641000FEF3E23CDCD7C27795915D15F41447F1A9 -:10642000B73394F1B49EE9ABD53FF5C097F9786ED8 -:106430003E53CCF3B803467EAE1D7AC8734DC4F903 -:106440000CECB7D3D1EFDC31C8EC22FB21D457A63A -:1064500063B0AF44C703833E1B8CE71B9B400E71A8 -:106460007E750E1C9CC0CE231F3DE9F99EE8B9281D -:10647000D8B797F434333C37027A6EC7FB2FBDA5EB -:10648000674F7AB227FD786233A7B353D8A7B1E834 -:10649000DC3E09E65D1439BE475565396603F97976 -:1064A00087467FDC9746D0FF52BB9BEA3FB7EFADF4 -:1064B00001ADD04F67E385098C9FE7905DD7F1A4CC -:1064C000B0DBDD99321F5BFB125C0DCE734FBE3E1D -:1064D00000F7C9B76106E6D993F145BF5253BAE058 -:1064E000F5F61C3ED6B8767FCBF9D99EAACDCF96CD -:1064F00001284F9F093D10737C3DC9298E0FE05C38 -:10650000A5F0F16D3016FD0EF54C787CA3537A356D -:10651000BEAA04335346007E0EB3992530B643F528 -:106520001D54691FE7690DA09F625FBC673DB0A461 -:10653000CA79E6E5901BDBC9FE8C15F536976C3FF2 -:1065400025BA64FB29C315693F751E7AC8E903FCA7 -:1065500056A51B5C2747E13AE715EB1C5F5735FC56 -:106560002A1AB25C76098E9CEFAC550A1B489EDC59 -:1065700009B3A39C9769E9AA74B3EB24AC5767EA03 -:106580007312B0DF337EAB8BAFAF2E17EF37DD1555 -:10659000B9BEAE5C1347F535FC62C1FD67E3C75871 -:1065A000237BD78AEB2294E5C4AE1F939FEA27662C -:1065B0003A976E367D86F6BB2D57B3DF55CA6B70A2 -:1065C000AB1A8C01CB08FCBE4BEA0FDAB9B53366C7 -:1065D0006C175B6E54764AE327F0DF8A07EFB46FDF -:1065E000B5129F7D003101E0B5ABF61A94AB132ACA -:1065F0009FCF55424E2BACAD669F9BC8DD82F2BC4F -:10660000682CD326CCDCB7404F7FF0A289EE69B16D -:10661000AF007A7ED7558125ACC8894ECF458D2BEA -:1066200066E0BAFD8141DB0FD7E6E3B8CF31432105 -:10663000EAA573EC8FCE5111F3758889FB63580D71 -:10664000DFE704E01F8E6F69ADBCEF595627E74BBB -:10665000D9AC54D4B7A55B4C2C08B82FC77D933662 -:106660006ED0BF1926EED758C6AA37E03EFD5E139E -:10667000F7F72C72313513F0AAF88F5FE6A3DFC766 -:1066800063E27687769EBC3C89E35D3E3B68F642DA -:10669000FD771B47CD018D0BED831BC8FE29669E40 -:1066A0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA61 -:1066B00076AE2DF048AE57BCC1287AEE329322F662 -:1066C0007F7C7ECC36C9FE9C7926D9EFA3C981494F -:1066D000C8C109D577B5690CE73BF251513BCCBE37 -:1066E000887AE6AE7AB3CF57CF82F58C546F9E2965 -:1066F00005EB754CA3FD3103791ADA55CFD605EFBA -:10670000460E4FAE57F11F8F3D15007929FFED3D25 -:106710004E06EBE6076A6DAA07BEAFDC799BD30B8A -:10672000E96935E0447E7E10341646A3C796303DB5 -:10673000BC7605FD69423E594D80FC149FED34B98D -:10674000C8CF5F6F0959404E2B1B97CF60C3297F7D -:106750009CE7377E64C47C93CCAFF25FDF93EAE6BC -:10676000F76CB83F8985C8CEADDCF1DE345C2FAA6A -:106770005807C999BE1DF6FF7912CDEB85E684EE68 -:10678000E58027F913AAC42CAB6AFCF9474627E633 -:1067900065F92813F62AD209F7F9B7991CC9A7E2B7 -:1067A000217B09BB04E7B9460F16E476EBFA47EE06 -:1067B0001B7E1CF039BBE345A73234523F7039EBE6 -:1067C0006C58FC2BAB21B61E6903398CB48F00309A -:1067D000B57337097BBB99A72B4D2127DE6759B9C4 -:1067E000CDE40109642B1F3332BC07C0DEB004D1F5 -:1067F0002FBAE2B1E75F1B0F745FB1DB943C830FEC -:10680000C7AEA476F1A50AFEB726AF8B0FE54F3CC5 -:106810006F760FE3DF6F49EAE2C78ADDFBCD6C5884 -:1068200077FA4D6ED86F6EB547E14BC3F169B8CEBC -:10683000AE7FE4AF66F4277EB04F616959DDDB9728 -:106840006D7B9ED63BA413F151F029CCB76EFC0AA8 -:10685000CD7C6634D573A11E8CC5AF6542EF823CFA -:106860003FFE0CDEFF79D3E2C1F1973D7E9313C763 -:10687000F1BE5ACDE5FA97B7A5E2FC2E3305525D7D -:1068800094F2EF650FFE88E46DD9911FA592BDC00B -:10689000BC1906D2C5810C1CDFD2ADD7D2F84A99FB -:1068A0008FE4AEEC97C622BC8FF8A9CA0A77479945 -:1068B00017716685F0797F3B183230BEF7717F899A -:1068C000FAEC8F46BA17C5D80FE9DED88FC45861E5 -:1068D000E5A3FCA756CEA7E3424FE24496E475C772 -:1068E000C616E4CF99FEDE343CE7003A0404BD94BA -:1068F0006F00AEF1C8D434CE1FE656F3453BD0EF5F -:1069000093F13BD66F31796DC3A576421FF2FE57E6 -:106910008BFE01EF385CAFDE4F8D6EEF8D11E383A0 -:10692000BF1616215F11F39BCFF71D9BF8FCD6E62F -:106930007BB0B810CB3F7995CF1F6C87EB03E01588 -:106940004AA3F2FDB315D207B0AF8E36AF7798C425 -:10695000BC96CBC152A4F51EF0569584483901F877 -:1069600049447FDA07976E817611F65715F647F599 -:10697000CC5DDF23D68765420F98CC30FF2FEE9A8F -:10698000FF6C2B9FF73DD9932B4DC1871FC0F9FAA0 -:1069900086C51370E37C3515E1B83FDC75E0B5EBD7 -:1069A00040AE3F6CD0E6A9AC3FF5F3B46CCF1816FF -:1069B0006D9E7E6887FD55B4790ADFA3CE537B2B8D -:1069C000C9F1F7AD3F35BA0D35CB7A13F5E033EEAB -:1069D000D8F4D3EBC1DF9BDC4447BD1E84BF5759BD -:1069E0007E77B9D3E44D93B3F2DF545C80FA262C62 -:1069F0008F9ABC85E5519337FD3865BAE9CBFF2AFC -:106A0000F4CDF5D6C26BD02EB67630DAAF14CC36D4 -:106A100006719F6CFD84D17C9F74433CE5E71A5B53 -:106A20009F409BEFAD8AB9C3701DBF9E054CFCDC37 -:106A3000BCD64476EA57DF7C3311C6739DA0EBF5D4 -:106A400040E6AB800F25AA128A033CE7A92C909060 -:106A500084FE62859D88C0E3FA32398F7F97A576E0 -:106A6000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8488 -:106A700029ED2FC0708E90A3E2667E4E51355A09E3 -:106A800066D3FC6B558B22F6098F99B99D7164CA48 -:106A90003563907E05738725907CD70EA17D609528 -:106AA000D05B9D017702EAF3CEE61CDAF7751E5A39 -:106AB000ECF045D15F07849C3D2FCE59DAED4AAD0D -:106AC00011E4BD9D7590DD12B0DBA2FADDEACC06C3 -:106AD00061EF08BEC19F11FA2F1172380F9A26E498 -:106AE00045F06DF6551FA8CEEE7CC0BF1311FB8696 -:106AF0007F94BE28D748DF03B6D6694551FC338F53 -:106B00000A7D7DD9B35F98719D9BD25CA0221DA7A1 -:106B1000D88D92BF63BB365F87B2A188D765CF2E71 -:106B2000BF630CC871D521A3C706E3AB6AFEC8ECEE -:106B30008BB27FD3D313E1A3FDD86AE6F6F15153AC -:106B4000D152A4EBD16BF979EE9FCC9E8A6878CEB6 -:106B5000B6723CE7B1A24F472BFF7AF42D98EB08B1 -:106B60004D027A74DAF9FDE4EEF2C7E77DA74B092E -:106B7000AE55500E8D3C9FCCEFFF4E63BE3B262A98 -:106B800034DF2F8FD45F054DC58FE17D96CA66C572 -:106B90006580F24AB5D58C725CD5B45B45BBFC0709 -:106BA0006EFECE82A9D5C36647F8B75ACDDC9F7476 -:106BB000E06FD7CD47FA7E3CDBC2102FEFD08F9C21 -:106BC000B8DE7FDC3C8AE641AC71FDC1EFB9660AF4 -:106BD000FAE3CD5C9FE9E5615A72BC94BF7632EB73 -:106BE00087E7BC97595A6FF244E1DF3A0B9FA7BD84 -:106BF000D66FD6FF61FA6D22E8372ED7A648FD364C -:106C0000DDC2E53E42BFA545D36FABD6BAD3502E09 -:106C100056EDCD4943BEAE3ABC34259A7E7B41EC5D -:106C20006B0F8B7BD2EDFD40BF8D88D06FFD40BFD9 -:106C300045F1838FB66876670FFACDFADF33FF5ED2 -:106C400040FD1665BC5708B9D3F45B61F35AD26FA7 -:106C500085FD8CD27DA4CB2CC28E8BA9DF16DE7372 -:106C60002DE54D9EF828F2837445FD7658E839EC01 -:106C700007F5DCCF2CDF4ECFCDB3727C7BD473FF16 -:106C80004D74D6F4DCAAFE0AD92FDDE590EBB95598 -:106C9000595CCFADDACBF5DCAA415CCFE9F5DBA4DA -:106CA0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF39 -:106CB0005762F258A1FE0CB7F6BEA07A4CA4BEFBF8 -:106CC000992586BEF380BEB3F7ACEF5E417DA792F7 -:106CD0001E1B88F3482F1FD307C64BF7D58E7E7136 -:106CE000EA37BFC5F9F20723DD077ADDC0F743FBBA -:106CF000BE38350AE7DDCB880FCC979D42FEDAFC23 -:106D000063499F4E1ECAE77BC5A1385A272A1B1527 -:106D10003EDE5B94A01BD781BF7D4EFBE4F97BF97F -:106D20003E79AE85D383FDD8C8DF4500091646C835 -:106D300043C9E7E5E4E72B519915EDD70587A67F11 -:106D40008076EB82CF6BC8DE5D80DFF17EC5EED64C -:106D50000D99D0EFFCE50AED3798B80FA1DD97B893 -:106D6000BE793FDD5FD1DF83D0F4F9FC6AF9FB0225 -:106D70009D5D7F408C13EC59A20B7BC518D53F77E6 -:106D8000404F0F0F1F7FC56A6E1F87E901F4712BFB -:106D9000DDE9011C9DB130B56BFCF39F8471257753 -:106DA0008D4BA3877E7CDAFE6481981BB1C6ABD184 -:106DB000AFDB78357AEAC6FDBC45D84517B36138F4 -:106DC000CF5E37F8EE188372F17B183FE03367DE51 -:106DD000A0B4483DFCA2D0E757F98E4F497523BDBA -:106DE000F8FBBBEBCA763F9F0AE3B8DA9B9587575F -:106DF00011AEFD9BD9877E8403B60ED26B9A5C5D83 -:106E000068E572FE7701E7685FD7145A3F9A141756 -:106E1000CD97904E6F897B6155404F9C8F554D6249 -:106E2000BD0179C3F9364D5B7F90FEF09F573573F6 -:106E3000FA57552B44FF99ACE320D2B73259F1846D -:106E400000D4B4A6DDB7E13DAA176CF01DE76D993B -:106E5000E2D9CEC961CF488D2A976A34B964D54347 -:106E6000C8AFA0AD830BB05E12BE17793D05ED1320 -:106E7000BDBD7199A5E528E271D98F4D6C1BEB6EF4 -:106E80007F68FCCE857FDF44BBCFD383FC0E12F638 -:106E9000E50B486F3BD2B5C38C725F15E2EB8656AB -:106EA0005EA5BAA7107D347A37C1BA309AD31BDFFA -:106EB0007DE9E979B5964779C6FACD8A09DB5F099C -:106EC0007CE80345930D5F1CD4E417DF89E9E98270 -:106ED000FBFF8C88F98E7A29F2DCB1B2E908D16522 -:106EE000FA6A30AB22E88EFAEA7CF4E9361F9AF6A9 -:106EF00047BD07F56DE7C38556793EECB375BC38E1 -:106F000002FD5B7B15D207AC3951DADF5F61E5FB2F -:106F1000A603361FC96DC76113DDF7D6EB8DB182AD -:106F2000FEB89F887C0737190782E7BB2E1B7B576B -:106F3000C3239BCB4FA4BE7EC1E6233EC5823F4DFB -:106F4000C08F652F85F1C5FEF03CC52DF7A75F2FDB -:106F5000343F4F4FE3BA46ACF7DF755CE1F349D6F7 -:106F60006266DC9FBFDB1C71CE3447F8F9353F58B1 -:106F700044BD999631B1EBA1BF2504E37E61D743AF -:106F8000E4D73DF7E8F19928B72B7E676456E073A4 -:106F9000DB2E070BF17B14665C57CB1B8D51CF4565 -:106FA000185B4FF8ADF8AD83F44AF91E4B7006B488 -:106FB0002F7FEADDE1E89F6A5BC7F54BE051211FB7 -:106FC00081D6E1785E5EAEF2F3623DBC1F0B79398B -:106FD000FB747C09EA47A59EBFEB2C6F986BB2440B -:106FE000ECCB2BF1C08DD7A37BC8814714F28377FC -:106FF000C76F2DAFF708D77BE54DA620BE0F2DAF8D -:10700000DF46FBD9AAFA8FCC68C74DFEED63644713 -:10701000543519653F61BD3164213FA6F138A67A28 -:107020007F5D656305CDC7CA06E10FD3F98B56FCBA -:1070300076EF530120CD8A277EED443D73A665A7E8 -:1070400093FC70F5DCCFA6DAD5E87EB89EFC6F0D18 -:107050009BA2FADFCEE07FC0FCDB6A95FD6FACBE81 -:107060004FAFCEC1573CF6E983782E7476CF870FA9 -:1070700022DE2BBFFEF8C19FA27DB2CFE6C2F5AEE5 -:10708000EAD1A3E457D7DA3D25E655DB23BF7EF8E6 -:1070900001987F6D6F58E8FE55DBDEF707B8619CFD -:1070A0006DBBBF4845FFE5EABD5369DFB2FAC9C908 -:1070B00069E7BB47827219ECC579889E0F071A8D64 -:1070C0000CDF419E3B66213B23EC476DA8E07E69C7 -:1070D000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52F3 -:1070E0005CF71A4D1E377D177EC09EFCA6AF023F8F -:1070F00047F4826FBB845F5CC7B773F81FC09F3FC4 -:1071000059657FF3A78D4B7FF5009635F689E937F2 -:107110000DF5825EDAB9D636ABF71D2BCE873DBFB3 -:1071200021FF34F20B6C6ED6F6D8A703D0DF70DAED -:10713000D47123DDBFD86BA17B42E57B5FA7F9D17A -:10714000F6E4113A2F62E25CA98D85FFF83980D808 -:10715000CB54ED70707FABA03BFA63DD4EFA2EFC92 -:10716000AE5C6E357F6C2C3F6C1F9BB8072ECED962 -:107170002A76BC65663ABFB63216F9745C3A17D403 -:10718000C6AD87E7423A5C12799E10CBCF2DF468EA -:10719000984FFC1CA16D9B385F089F1B30D62F0FAA -:1071A000EFBFF3F3EEAAA0F23A8B321FB5F304A7B8 -:1071B0004D371F83BD3B47E819DFEF460FC5C6F7C4 -:1071C000AD1A5DCE7E155D1F0FB129E2FD812FD76F -:1071D00016B1EE2C10EB4925D08BBF27E3F89E1596 -:1071E000FBBBB38F1A83B80FDED07080F4AA7E5E2B -:1071F00057B2E8F143C6DBB83EA96CDA3F1CF5CFC5 -:10720000D9679F26B9ABDC75DC1C003807EB9F30D3 -:10721000B70EED9273D4D7C1087D7DF6F1FDC3F9A9 -:107220003907DF47EAE15F21E05735CBF0AB767DE8 -:1072300024C15F116830BBEC3DF77346F5CEC5F154 -:107240009E6931515C94330DC6C268F14A86622052 -:10725000A9942E3A6D70F0F771C62433D991AB1D05 -:10726000638F2524636A76E33E7AFD5A7E1F72FDA2 -:10727000CF3CE9C897F58973E81CA856474757B231 -:10728000AB00F7D7AE2945A351ACF47A20D16B906F -:10729000F05EED284CC3F7DCB70A7B84A91E7ABFE9 -:1072A00067744E2BC471185D06972DEA3ACAE199AE -:1072B000EC45142FC2E492DFD37DEFF11FDCFDE437 -:1072C000F80F817EFF68FC07467130FEDFC77F083C -:1072D000603FFF02F11F42E4B7D1E23F247FCFF1CC -:1072E0001FD63239FE83E06738FE83E0E7FFC67FB2 -:1072F000F8FF2BFE8331EEEF53303E8316FF21253E -:10730000CE3C3532FEC38571095323E33F8C8B4B52 -:107310009F1A19FFE10771595323E33FCC8FBB68D4 -:107320006A64FC87AAB8515323E33FAC8D9B48792C -:107330002DFEC3DD7153A7CAF11F664E9D02F9B63B -:1073400038DFDF71BD8A15FFE13D9C2C637A8EFF2B -:107350000070CC716362C77FD0C38915FF01E02440 -:10736000109C18F11FBAE11323FE03C049273831DE -:10737000E23F74C32746FC078093457062C47FD008 -:10738000C38915FF01E05C1497123BFE831E4EACCF -:10739000F80F006714E11323FE43377C62C47F00BB -:1073A0003813094E8CF80FDDF08911FF01E04CA570 -:1073B00071C588FFA087132BFE03C09949F8C488C4 -:1073C000FFA087132BFE03C0994BF8C488FFD00D94 -:1073D0009F18F11F008E8FF08911FFA11B3E31E233 -:1073E0003F009CE5042746FC073D9C58F11F00CE5A -:1073F0002A821323FE831E4EACF80F00E7A7042752 -:1074000046FC876EF8C488FF00706E253831E23F75 -:1074100074C32746FC07807307C18911FF410F27FA -:1074200056FC0780732FC18911FF410F2756FC07B7 -:1074300080F32B821323FE43377C62C47F0038F530 -:10744000248731E23F74C3E7BBC67FB085062A3983 -:1074500014FF81E24486E33F247FEBF80FCD88EFF1 -:10746000FFC67FF89F19FFE166BBEFEB38F2837E22 -:10747000B7F80FB6F86F17FFE1667B517C3CEE2F33 -:10748000BF65FC87D4F86F17FF01FA498F1F13BB44 -:107490009F58F11F7274FDF414FF01FA1974DEF1A4 -:1074A000C488FFE0D1D1EDFB8AFFF045DCF9E33F72 -:1074B000FCCBC559806D0A9EFF149328B27F99B802 -:1074C0000BD7C6FF93E32E90B1F0AF1477417BBF8B -:1074D000DF60C2F5EA4DC1F7D7845CBC25E22F1C02 -:1074E0008B197F217815F94597CBF117A60B3ECE66 -:1074F000F3C9F2309DF1F386E953B278BCCC325D2A -:10750000FC855CF9FC7A86EFC81400C7AEF2C8E3CC -:107510003822E46166C947CF217BAE1E1B3DFEC207 -:107520002CC18F621D5DA60BBE158BF47A7C920276 -:10753000F23CA3EC888A749DE96E55C9AFFD038DBA -:107540007F6E897FB3055C3DBEB304FF665DC9F9FC -:10755000A7C7FB55E49F13D2B251C43F3DDE7A3C2E -:10756000F5FC6791FC8E889B51C0E4B80B93AD721B -:10757000DC85A92E39EEC215E972DC852BDD72DCC3 -:10758000851FE4CA7117AEF2C87117AE1E2BC75D16 -:1075900028F6AED5C57DD8A48BFB70972EEEC3FD23 -:1075A000BAB80FDB74711F1ED1C57DD8AD8BFBF04F -:1075B000B42EEEC37E29BFB8E6B0547F69ED112921 -:1075C000BFACEE0DA9FEF2E071A97C45FD07527932 -:1075D00045C34752BEAAE90BA97E6FE33EBC2ADE33 -:1075E00003BF26DE031F13EF81DF8C11F7E1AF3FEE -:1075F000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC86 -:10760000838D15F7215C1E23EE4357FB6F1FF72177 -:1076100025F99FFF0E3FC7CECF3727C44FCAB1A76A -:107620007CF777F8D716C9EF99E796C8EF9973EC0E -:107630005C9FCFF3C9EF9AAF2F93DF3597D97CD9F1 -:1076400088873EEEC384786F8E1DF5A5789F1FC294 -:10765000F7A9B0363E8BEF53217D0EE33E407A1002 -:10766000E33E407A08E33E40FA7B8CFB00E94B188E -:10767000F701D29731EE838A712302226E448D88FE -:107680001B512BE246D489B811411137A25EC48D3B -:10769000681071239A44DC8810C139E13F44E949FC -:1076A0007F0BA5A7FCC7283DED6FA5F48CFF34A583 -:1076B00067FD1D94B6F93FA7B4B7712334B9FC3305 -:1076C000DA0D66EC9FCBB126A733EC033744CA69C9 -:1076D00091FDA20D28A7B1E245CC459AA6C48E170C -:1076E000112E8F112FA2AB7DEC781169A3BFBF784B -:1076F00011FF16CFE5F51F8D1731BF5A8E67B060A9 -:10770000CDF9E34594D98A56A35C6AF2F86FF1FC8F -:10771000BCAAA77811DBEC8A58AF812E6877015D8F -:1077200068BDEEE1BDFD738E8773713FD1997BD14A -:1077300079E31CE8E52236BD795C83EBBEE73811BE -:107740003DD155ABFF66398F5FF06FF1E78F5FD0AA -:107750002D4E444FF105067D467AB2B771227A5A12 -:10776000177AA2E7ACEF394E444F7AB5277DFAC7B6 -:10777000E99CCE13E2CF1F8F231C17CEDA72901A2A -:10778000BBBC34B555F10EBC60B68BFC27EDBBC459 -:10779000BD312F73BB52F93B75B437DBF7240C674F -:1077A000F47EDDC5BCC09F78F15DD9B57F3F9EA753 -:1077B000DFEA64DEC4248A07EF36E6E03E6CA415F7 -:1077C000FD29158D1FBDFC3B806B6B36D27DB276DB -:1077D000C0A185EC3E6F22F22D9EDD4EFB743CE392 -:1077E000FAA64FE47B66DDEF37609588F39BA946E8 -:1077F0003BED9B3AB7F27B9E4676F17D1347D37DF6 -:107800006A167413FFC84E5D21F0ECC414EBFBAC98 -:10781000643F2E3BFC447E88F1F3CA48BF419F423F -:10782000D94F5367730EC777952CE06D41FB7B8969 -:1078300080975224FB6F3E5C547808CFE997F84A52 -:10784000E91E425A89ECCF61E2DD386EC7C2F7E526 -:10785000009FD226853DA0747F475ED67CD706DC8C -:10786000E72C0FEAED6F968B7256CEE23CB8EF5DD7 -:10787000512F973B1CE23E879DD97B45B7D60BEF36 -:107880009B987C5EBA7942587F9783EEC32E3BBCAF -:10789000D88CCCB2A4CB74B3B965BAC5E7CAF4D15D -:1078A000D3CFE191E9A3A75FC258D9FFA5D14FBBC0 -:1078B0006FA832715F34C8EF91767B87DFB48DF0AB -:1078C000D4D34F4FAF510E714FA28B5E45D6545259 -:1078D000F98467861A22F9D6CF874C7B48C1FFEE20 -:1078E0009F1C5C4BAD3C0E15F5563A07CD9425BC5C -:1078F0005D3CCE078C2BCB3C341F70478FFEDD7870 -:10790000F66721F7EFB26F20BDA9F8B9E38BA07439 -:107910002BCADB08FEFB0BE4AFD27E3781795CB863 -:107920008F6AF05BDD4B543C1764EE2503F13CD0CD -:1079300045E99DE2DD6FFB5046FBFE86D027A97826 -:107940008E76675EC74CF43F542D6545B87EFDC802 -:10795000C9DF5D6C12E90827F7CF6C2E3230EF6873 -:10796000FC1D1E635041BFABCB7BF872B4479B4DEF -:107970006E7A47ECEA78F97A2A1F45EFA3330CB503 -:1079800023111FA84FEF6BDB9BDF752E8ED0C36DCD -:107990004D770FC1FBC5F71BA2BFEB2D7568EFDB61 -:1079A000F8FD8E115D71064A1D63281EC19DD9D058 -:1079B0004F657127F15193CB0982FECF954E27FC7D -:1079C0009E6C56DCE8AF9B66BCE107C300BF714705 -:1079D00055AEBFC4BDEED1A2FED3CC938EF88EBB04 -:1079E0009429387FC6BDC13C0124717529DDA7FBF0 -:1079F0009D73DA21E4D7946690279C0F67ED1EBC37 -:107A00002A3FA645BE2F9738C57700EF175E728CC8 -:107A1000913EBBE498AABF1F63C4FDFEB856F9FBB4 -:107A200004DDFE739D26774E968A72B7E52B23E11F -:107A3000D5DEC13CEB006EFB92BE746EDBFE09230B -:107A40003BB1FD2B6361B4FB25773BB8DFEB7E33A5 -:107A500023FD7D7FA99DDE393C5B5A7E01DA179FAD -:107A6000FDC47741343F65849D96C0DF9F7B13D86A -:107A70005894C35B154EEFDA8CA228EB9626779AC2 -:107A80001C6AF297511AE78B765F33D9C9EDA34987 -:107A9000A5B98A19E5679FC290AE6DEB00AFF3AC54 -:107AA000DB01B62E13F1A96AFA98EE61599B95A8ED -:107AB000BFCBF384C3C9EF03AE0BACC5FB1737C311 -:107AC00024423D9561AECD8A063FC0B6905DFA80F6 -:107AD000C3CDDF0D58451C21B53603EF23B4354D1A -:107AE000BE7203E0F900CC07E4EFFD260FE11DA80C -:107AF000608CEE930A7F5DBF996CDBE608FB77AF85 -:107B0000A3E030CAED6107B71BFBF83C0AE2EDF9D0 -:107B1000FB5F9D08BFFD730BF1AFAFB037B57627A4 -:107B20001D9C3E254EEF016CCFCA9249F9787C4EE0 -:107B3000F7923EE837077A47B1AFB4753DC9C7E859 -:107B40007C22C96E089272F27ADD2EE9BE7780E659 -:107B50008D360F584861F85E5FD36F4AB31272805A -:107B6000DC8FB6DA4378FF2CA90CC69D8CF13CACB7 -:107B70001C5E8B7A56F66B813CE6A371CFE8BD3F65 -:107B80003A5211BEA6F7347D796B22D747B7DEA5EE -:107B9000523CD0AD6AAB0DFDA9595EF7240C4D9354 -:107BA000A4BAE95E4AFF323E0FE3737E9918B6032A -:107BB00060928FFCDAB820DA7BA60C94A714A49705 -:107BC000EF4307A4C30F753C8BE682C7C6FAF0FBF0 -:107BD00053424F08BB669A58EFC6BD67E0EF284393 -:107BE00097B3C8F7457A3D0172FF27FCFD9EFBDF86 -:107BF00053294E68583F944EA3F58919871E403982 -:107C00009BF022E3C751423FB8E01FD2E792977C36 -:107C1000EB118DEFAA17F4FC66216B388F3FCD3640 -:107C2000EA10CCB7C875D629D67BA1476E2A1EB8F4 -:107C30001EE797264717DCE231FA22E8A86F1FF605 -:107C4000532AD6F077770EEA91978C783FACBD0037 -:107C5000F80D747912E70BD03BF193E095C8F72D3E -:107C6000CD57D850BE6F0D4D72CD803689D6226269 -:107C70005E22F3923F270FA8837122D69350C07ED5 -:107C80005D2DCA72A6E03DAE42C9DFA3FD2E1E0CDB -:107C900094F812E603C871E43D564D3EF5F2A8C9CA -:107CA000EF7ADC60E1F91D7ACC21352A0DC4200B76 -:107CB000DBEA423DABD997EBC3F65C22ED33560BC2 -:107CC000BB68BD7D9A95D4C0FE645ACF57E3FA04D1 -:107CD000E35F9DC2681E68E3D0CB63D5E706168CD0 -:107CE000D81F54A91D748FAFEA73330BF6C171FB13 -:107CF00026E1B835BA8C1474D1D321DB29F69B82E6 -:107D00001EB1F1CC77E1FDD944AB976D243C27D16E -:107D10003DE786509E15D7DBDB7478F602BF39D17C -:107D2000F053ED31F013F1DB2630DFEF5A415EF313 -:107D30006FAACBE0EB057B353D827FFA7933B6A99C -:107D4000FA803962BE687E5DFD3C19D1CCAE41BA85 -:107D50008F0BA90CCF5F7B9A2F9F88F156C5737A42 -:107D6000B5CFE9188CF2B943F5553BC9BE6835600B -:107D7000DCDFF6A719CD67CFFE934E8A6FD4D2BB56 -:107D8000FBE99A1DA5D94FFA7A9AFDA4E95DED7E2B -:107D9000F876A7CF8FFD2B4D209F30FEF52EBE2FFE -:107DA000DAEBF0ADC3EFF130063C4A62B9A12CFE2C -:107DB000FE5596FF58F21EAF93E706A013FD4E1630 -:107DC000E8FF414A773CB4FEA73813F9790BCC663B -:107DD000D443FDF219EFAC92D1FDC97EC3990FD700 -:107DE000A77E79FCDE5F50ACDBDB84BED5D2BD8ED6 -:107DF000A2FB117F93CA0296BCEF8E37A28AF7B11D -:107E0000B73BBDF7A1FC590BBD348E4C17F3A0FD59 -:107E100099A93628F86E3269A55BE1F7B059D73BCE -:107E200026809739C35D80729289FB68ACDF1C3D68 -:107E30008ED6134E9364677A58384ED513D82FD800 -:107E40009907CD80779F195ADC2BEDDCC6A3209DC6 -:107E5000DA1C7308E9B64F156E8F27727AE9F703BB -:107E60004878C44F15F9DBCC4CB525B1AEDFE13411 -:107E700058C98E8F679E06D44B2F3BB3C5B9A8A7B0 -:107E800006F3FFAE7658138776C9F19D13677954D0 -:107E9000A8E2BCB47338EE99409E0F23BE6D133B2D -:107EA00007DF4AC4E818C0E5C66B94E2E268F46FE5 -:107EB0003249F4B7E13E3B520F3ACCB48F6C53E2F7 -:107EC0003C38CFDA962B1C4FC52AE206A9F2FE5F9A -:107ED000E8234DBF763AB308FF7816A07D00B37A49 -:107EE000AC748F5DE08F7115C9AFB3373EB81DCF4D -:107EF000A3747114F57116272FB6D3BD8B2D7B6D2E -:107F0000B42FED2CE2E7F39DCD16D2BFB1E6691A8E -:107F10002A83F3C40B04BA7520DDD24CD589A8F7A7 -:107F2000D2E6F3F9AFA7473B0E14F73B7F3005A32A -:107F3000BD57D7D2F4F4BEC56897A567A453AA7DF0 -:107F4000AFB3AB51EF611B1314294EDF10E851ECB6 -:107F5000738C09F0FD9CEF8FAF7959D7BDF6BA3815 -:107F60004EBF4EDFF8848751AE40E0E8F704B473AB -:107F70004DB19FD7E22769FD6CF15B8B31E467DD82 -:107F8000A2E9365C075298F7CA793829B798D84ED3 -:107F90006A972BDD77BDD73FB218DF276726F07BC6 -:107FA000B49F6C994AEF9953D93ADB60A043699129 -:107FB000C183FE80738BDE741A407E1665B6E4A31F -:107FC0009C26987C990963C87545FB8D6525E660FC -:107FD00008E8955C070A81E818B892E8B8D010D58F -:107FE0003F9C9DC0F79D6F89F5243D7D40F19251E6 -:107FF00091F97E44574D8E60FE642C19DD150F13E8 -:10800000F87951429479D06E624DF85E42D347C9F7 -:1080100042CC347DA8C97132CE0FB4E38A403F49C7 -:10802000E77D5035B5EBF70C95E617BE403BD679AA -:10803000E924D237306F6B48CE73B9FEB4A13E8BC2 -:10804000F05BB5EF7DBD3FBE637AFB671F3BF05D24 -:10805000CB5FD40E07EAAFD3B7FCC98171C0DEBED7 -:1080600085EF936FD4D9FF5709F90826144D41BA0B -:108070002EF0FF3D3FD25E636BB8FF7979507EBF33 -:108080008AF7BF23FD80150DFAFB00011EA74CFCEB -:108090003EA79E0FEB041F96EFDA66CE7463FFBE19 -:1080A00039D8FF69B1BF39DDE8A0F7141A3E8B76E5 -:1080B0008D34A3CDFF97668B78A7D762E27AD93B40 -:1080C00003DFE7F804DDF4781EDC174FF096DEC31B -:1080D000DFAF2E84BED6805EF435F3384AFA712CB9 -:1080E0007DDB3D0DFDE84B3729B48FC3FAB7C03AAD -:1080F000E15BB391DEF1E8C7B93020FB73F4F11A0C -:10810000B5FDC032C1FF25F86BBC3951E23836F3FA -:10811000F774CB74F645E7A19C781CFF9A0461675D -:10812000E7B34B306EE79E43D909D1E26168E95964 -:1081300071DE8FF7FA313DED67944E4970F3785D4B -:10814000CD476E46B9AA6CDA4DF111F705DFEB3376 -:108150001EAA14347F6144A12A10F6D87C618FEDE9 -:10816000615C6EC08EDE8CF27FF9E73A3B5A8CF38D -:10817000064DEE0F2591DCDC80E31A8EDFD54FA291 -:108180008DEBEE04F9FD576FC7A58D471B9F565E1B -:1081900021DE9FEBDB69723E45C8DD921DC51BFAEF -:1081A0000229D6EF7D7F8088234771B63439D2CB40 -:1081B000C932C1B7B03C34DF41E3D2F806F29E2E9B -:1081C000DE25A5A33FA327B9D0F3BFCDD43A00E75E -:1081D000AB9EFF6D31CE7DB627F0738D256EEF34EB -:1081E000F4AF8079B8C115613F9C566B0FFE14E760 -:1081F000D10E2EC791EB22194B2F9A689D5DE57029 -:10820000A725DA05DFC6E1FB454B00EB69FD9CF2D3 -:10821000D7CC1A48E78DB5B3060EA4771B946AE550 -:10822000A5F77FEC44FBB43D97917FA1CD21E37B83 -:1082300004179B319872FAAF545BBE7E0B75D08EDB -:10824000168ADF7AEA2BE19FF8CA52186D9C6713F1 -:10825000B81DA8DD3FB951CCA31B9BF97BBB455B87 -:108260008BCDE4075823DFD77849714DCB84A6BE68 -:10827000869166E4B39E1F4B3D57D03BF06E7C6108 -:10828000B7135F97EADFB5897B4C0B847CCC74B95C -:10829000859DE6A377C44BEA8C64DF2F7357D3FE2A -:1082A00066851AFD3DD61897E1BCE3D18F6361A3C3 -:1082B000427A4F8FFFB21D6B37F465387E3EBEEEBB -:1082C000E308F5233D23C6C95A2FE7EF32C5BAFDAF -:1082D0005F995EED8C008000000000001F8B08009D -:1082E00000000000000BB57C0D7854D5B5E83E7356 -:1082F000CEFC24334926FF21413C21111212E29089 -:1083000084000171F24BC4080301826075405184FE -:1083100090207A5BEFABB79990682DFA7AA358CB8F -:108320006DEDFD062BAD0A4880A08126E9041403FB -:10833000040D820A96D68014B1053280B5587D8F1F -:10834000B7D6DAFB64664E92426F5F87D69D7DCECC -:108350003EFBACBDFED7DA6B9F65ECD94B720E636A -:108360000FB7CB8CE53356FBACEC65A98C2D63CAFB -:10837000E9BE0C46BF6BA9F85F67E59204C6EEC57F -:108380003F5568DB57553278AE5CAE9985CFF56FB7 -:1083900090995982EB1EEF53C971D036498E461819 -:1083A000C71E379EEEB33066817FD746D33C8C25FF -:1083B000E0FCFCD723B1A75260FEB38AFFBD08786A -:1083C000EE2CC0E181799678F873F47EF8FF32C71D -:1083D0008C2F2478DFFDEDF229730E5E5D6D32C0C7 -:1083E000F8A52F496C1D8CBFFF69DD78B12EFD3AD1 -:1083F0001EDAF0A3B9E91981710F7B9F0BE9C3DA8B -:108400005456C0D87D023EF6EA7F05EE73F84DAEB5 -:1084100008C632ED117167B3A05BC0265D4B63AC3B -:10842000CE1A99C3A2A03533C2233B64F46E02B8BE -:10843000D644C08201CE355BA3BD1EC4E3EA68C644 -:1084400046C0B8F68D26B70DE6C4DFED8C9DAB6F48 -:108450009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB1AD -:1084600089408FB6E7685CB7E29A6487FE2A4BDFE3 -:108470008FEF5683F03899D363995C696286C07C2C -:10848000FA7659B3F1CBBEA0751621FC56F86312EB -:10849000C02FFF3DF8D5C4685B006EFDBC7FAADF2E -:1084A0001002F74A85395B6C81F568E326DA0DB472 -:1084B0001EFDF37A7A30E6A5717ABAAC443A04D15B -:1084C00017E15400AF3D1D56EF5A89F888E0F67465 -:1084D0008411DC1793D6CD3D93C7D8617C00E0AE04 -:1084E0001DF132F55F515C6E7B3C5EF48F728DC77F -:1084F0006762199B323CDE6046C6607C2ECE0FE37D -:10850000768539F3988CD75DB1C807D31BFAAA2CAE -:1085100040AA3AFBA40A05DE33FDB9BEAA30E83F03 -:10852000629FCCFB9BFA8E5A1C8C35B02915A5F0A6 -:10853000FC63700FE7BB5E9B6F762D66C05735807E -:10854000534B0CB4C7C6BC8DF256D35B5921454280 -:10855000CB984FCA057E7046FAAC39D4678530AEE9 -:1085600033CAFD1FB8BE55579B2EC938EE98C2E5D9 -:10857000A53B8EF0A000EC61F05C53B853B503BE90 -:108580009A622C8EC654BAEE098BC1BE535583AE87 -:108590006BF4C0E7108E2603734643DB75604C54C2 -:1085A0005FF6F078EBAA57AB14A0FFBEFA0C6AF5A1 -:1085B000F78B4CF674073C5F6460EE16DBE0FBAFB4 -:1085C00022BF109DD414A4736DB789E41C7F12F0F0 -:1085D000FD2AA1876A81405100CFAA63CC171E896A -:1085E000E3CABF50B06D95D8E910BE6281BE3C3C75 -:1085F000DC37DAD6E27C4A309F703C152BA9554A0D -:10860000D07B4B6D99217D39D19081EB6172B8633C -:1086100013E0574E31ACDE01EB976F8616F0A1D810 -:108620001DF212689B4BA6CB4BA16D34B2852DD8A1 -:108630001AD8F2603C750879D2DA4B76D76F90EE93 -:1086400017DEEF2DB0929E1A6927F916EB6D941C78 -:108650003ED4439E2EE6D804D79A6417E37CDCC24E -:10866000908F7F2FE671980D3B55E0D7F7EC0F12F6 -:10867000FF3AA20C8FA642FFA3E615150AF0AF231E -:10868000C570251578F478F34ADECF325C190DFDFC -:108690004F9A6B787F2A4C99CCD8C9E655159E6CB9 -:1086A0009C97EB31B6C59985EF510C12C9A9B2D789 -:1086B000E46D843F9B22393F3519812F6370BC4A9A -:1086C000E39F6A28DE6C05FE578A9DEA6A1BC73560 -:1086D000F2C3FFB4D5F0285B0DAB118FD822BECF0B -:1086E00088756B7460ADCEAC39A8175A9C5973234A -:1086F00010AFEECF11AF793DBDD3510FB77EF0492A -:10870000813B9BD30BE7C9EB612C12D673E1AD9B88 -:1087100036CA52803E97EC45E7515F4BA0A61F87B3 -:108720007549AA9DDD0372D7E864AA09D695C85E8B -:10873000B2A3FD30207D4005B532AE5F3AA35C5F49 -:10874000E2736CA48FEC4CB5DDF515BE5FD3CFACF6 -:108750003766483DACD757A69CC765067C1093D2B8 -:10876000767C29EAF3DF9A1DB7A8088F933D0E7037 -:108770006C333085C5107B642870DFCAC21DEB5096 -:10878000DE1D2CC903F2856823E0E01707F6D02828 -:1087900064485B073C5FCAA09D8470DD4AEB929100 -:1087A0009F2630978C7AAB8079ADD8F677BC9584CC -:1087B000F87A3E8CDDE782D6F22A737A83F4467E1D -:1087C000B444F89F1563A436DCD83217F934FC1290 -:1087D000B3A31FD0FF0B9382F38360DC89D71DFB0B -:1087E0000D0CE1FCB5D16B8F82BE3F53515F6681AA -:1087F000F9FA059DB5799F37A999D1D0AF8A91082B -:108800002FBF2EE2F6D8FF85C9FB722AE2C7B2DA83 -:108810001B2457E3A3F9B8BAB8E2B1D1F07C4B47B7 -:1088200038C3F74FEA0C3720FE376FC90D433ED8E7 -:1088300086B881F5C798ED8FE07C315700DE54BAD9 -:10884000EE24BC2AEA8428C06BE14C9BBA0EF0FEF1 -:10885000EBB09699C8F7FEAD06F632BC629BC93103 -:1088600007FBDB2EAB76D4B3BF4E6D09A7F56C3595 -:10887000D07AB685FBC7AD01B8D7652815089F62C9 -:10888000650AEA5FC550AC3E02D7A74573FDA8E96B -:10889000E39A6895FACF4BF0FE5C1C57447253265E -:1088A000DB48DEFAFDCC6B86F7C4CFEB95911EE179 -:1088B00073809590DF159FCC703E17121A5A9BD18A -:1088C000AB929E75DA9600DDA70B3D3BFD644D250E -:1088D0008BC48EE3D854986F9FCDC8705DB7B13EFE -:1088E000D902FDDBAE32870FF9E7AA427E981DFE62 -:1088F00005FB7B65629E5F494C898271455FAA0AD0 -:10890000F257110BF5DBCA36947F81F6ADC4A2BBDA -:108910008EFE5C24B64AE03ACCB3285AF861A3D85C -:10892000A86BA4CF60D6046147555C7FF67FE1BA9F -:10893000FA2B4C0E5CFF769BF3E3A9A8077B8D6CAA -:10894000131B5E8E7E550F1A7D0C08C7D570E68D01 -:10895000253EB421FDC76D68F684C17AC7A5F3F939 -:1089600091DF506F8CFD455C2CEAED8868AE4FB40A -:1089700056E32FE4237B14E723FBAD01F9FB5E7480 -:108980002A8DD3E409F90BE7D963F42E760D61172C -:10899000812FBF877CB9DDC62A90CF9F1961598886 -:1089A000F2A4BD67B7E07B7DFB54C39A2E23AEFBD8 -:1089B0002FA0FF01EED2E4ABA660FBDD15C7E12DD1 -:1089C00093BF25BFFA62BB44FE7C423BD7D7C17C34 -:1089D000316268BE7801F17A3DBED0C7011A5FEC02 -:1089E000B81E5F74FF637CF18B68E1DF0ECB17DF8D -:1089F00046E2FA1FEB2849647FC78F69137C30DC9D -:108A0000FD2956AED7F4D7DB053E779B9AEFCC41D4 -:108A1000B9BFCBE040B906AAA7CC05FBB23B9C3F4F -:108A2000C794D569D8DFAE703DB2BDDD4C7A64BB6A -:108A3000CDED267B9D6461E82730C5DDF77DD47FD1 -:108A4000C916755D10DF3E2EF4408BD137E573F407 -:108A50007F0F70FA4EBE2B5736C1B8110F70B9CECA -:108A60003F67DA28C33CD53145BE6818DF17CDED26 -:108A700062DD1918057C597BC644FAEDADCE23E5BD -:108A80004E1BF9374EE4AF497B8E941767E378CEDF -:108A900047DDA2D5FA53704D3164768E25017E5D97 -:108AA000C24E4C615C0FB9903F72027DE634523C7D -:108AB000A6F1413563596827E6F639CA908DAA2A8E -:108AC00042E95BED9B4971DFFCE3CEB20858D77CED -:108AD00097EEBEA07FB58EFEE007FF01E564D5E608 -:108AE000DE4E1BF2ADCAED698B697516F77B56A792 -:108AF000A1FFAFC911FD004F2DBFCF78795D901D4B -:108B00005763F83A9F752874DFD367F2DE0297FE49 -:108B100037E3CFB5087BF3AD90E3DCC7DE588CFCC0 -:108B20009BB7DCB90FF1BF284EA6EBFFC97C96348A -:108B3000A48F4321FFABC5A8967C2E05C631C595F1 -:108B40006183FB7BE2C3F3F0FDD531EE6B4827A6D2 -:108B5000F8BBF1B94985B9792857B6094DB1687F95 -:108B600034B801AE8A4DB6001C1A5CE785FEA98EAA -:108B700059720DF180CFA15E693B75D682CF6B74BF -:108B80006FE9B8C4E91D447FA47780FED27DD8D7B1 -:108B9000F06011ADD6FFE7E9EF1B89F41896FE18D7 -:108BA000F747FE8FE83F2A6608FA833F958ED73550 -:108BB0007FAAC5047E7576A0AFD1BDDA5E44E31C02 -:108BC000265819FA4F9D1057A21CBAA3D1B9613B80 -:108BD000EDFC5DFDBF3F3B0A5C4036292686CB930A -:108BE000C93F06FD8D093E89FCBE0920F0F7909F24 -:108BF0003592F49D43E0879D95A4B319DC05BF969B -:108C000082FE9F2F16E56082B9D287FCBEC33A3D33 -:108C100005FDB75CEBB434E4A737331E3B8426E78D -:108C2000CDE4E53B5F51037E8EA6D7F68969B5F7A3 -:108C300097C770FADF0E6A16FD3D740D83E1D0F41C -:108C4000379205E1907CD5866B56D2C7ED7D80AF1B -:108C5000DB110EC06B97C45A517F17199C7125E820 -:108C60008FC5FB14EED77D3D4A05BEA96C7FF73852 -:108C7000C25B69B1F930DFC21CC6F37D41F912BD98 -:108C80009FABF9259ADFAFF92D5A7C89FE0DDECF17 -:108C9000C7EB00BFDD0C00A2FDF159BC0DF0FEE7F3 -:108CA0002FAB994E21AF0AACA352AC6336EB25B87B -:108CB000D8B7D7AE4D03FACC12F8A8EC86B8300777 -:108CC000EF337617E0E12E85C78B7739203E0CE233 -:108CD000A3D99343FBF89B9E1098E77AE3F5FA7FBC -:108CE000AAC817FCB371A6D676831D3A0D0C70B0D6 -:108CF0009EC73485A3658F82F1803BD380FC5827C3 -:108D0000EC1A84C943DB2321AF8586BE1C07E0B77C -:108D10006BCF3764FFF6EEF9E623F4E7A67CA130CB -:108D2000333C5FF8457E14EA07E60A9DB7EE8FAD47 -:108D300056C6AF13FFD48AB5EFAFC78C18C267A170 -:108D4000F637E79F5F8FF37D7946E1BC2DDE5F6EDE -:108D500072A7DB6DD8F2787FBFC4FD1DEDFE7E23C8 -:108D6000C00DD737C568717FAF42F919F89983E80C -:108D70007C17C6FBB901BADE75AEE20B2567307D04 -:108D8000F0F7FF23DED7E2FCB744FCC0F69D30A924 -:108D900000D78CD64714F4A36724C9CC19F4DE3B62 -:108DA000542B7306C5FB6FC4E8FC907DAFAD9F05E7 -:108DB00076A4AE477684A1BCB66F3F9483FD5ED99E -:108DC000611D828FF4F89DD1FE8882FC9F10CBE557 -:108DD000E67AEF2F1C077C722BD29D911F77B14052 -:108DE0002239D2D377EF9E9FC7F6650F8FEFE1E868 -:108DF000AFA7C36FCE1747215EAE470F3DDF76C2E8 -:108E00003A3DB03E1FACD303FED6DE7A3BF5DFAE73 -:108E10004FA2BEC6AF751DBF8C457F4DE3D3B25880 -:108E2000CE375376AF8F65B600BD347C5D1474AB1E -:108E3000668EF9B3E0CF5D922382F48487F5261520 -:108E400004EC55F5B172F233347B552D671B51FF9D -:108E50006AF60AD3C2A8CFF4F6697E7A9111D5AA30 -:108E6000DE2EC1028DC8BFD50B43AF57F4342B1192 -:108E7000D433109D2449E043F8D51A3C1F3217C162 -:108E8000ABA7A7069F1E2ECD9FAE1674837596E1E5 -:108E9000D2E7AA45B48E417655ACF746EDA93936EE -:108EA00034CEBA72AEF4FD9C21F87538BED5DFD74A -:108EB000F44039BE20975A0FFA1109B10944AFF2B4 -:108EC000AB26E6047BC14686B1CF82F3EFAF649256 -:108ED000BD7B54D8DFE1F8A6F6AA81B96303FC6331 -:108EE0006C7BCE8AFCB35B69B662DEF136DB9CC676 -:108EF00028C053E91F8BE7A15F57D76760989A2A6C -:108F00006BBFB40FE3F6BAE3CC81FAB0B8BDAB04E3 -:108F1000F9ED6DA557A638FA4BC69E0BF20FDBDABA -:108F20001BADE83FB5C5C914A7EF8FE6FCA8DD6F00 -:108F300089E5FCD776E6F22CE710F73F13F74B4FA5 -:108F4000E51AD148F6C74750BEA1FC6903ADBF542E -:108F5000B25755A2FF718791FC7A885BFEF07DCCF9 -:108F600037B599B763AABEACED878FD881102DFFB6 -:108F7000E7B30633E60FE6488E97615CB9EAEFC2C5 -:108F80007EF9BC54DA8799F47F65F25FFD774B94E4 -:108F9000F7280776C17EF93DA95ECC3FEC9178DFDA -:108FA000D3C1F3FECCEE899D05EFF9A03276C23A2B -:108FB000E229AD7F4BEE3A261838289E7A6C17DFEF -:108FC0003F7AAC4CA2FDA3327B0AF304F155F9D3EE -:108FD00040CF3CE0C7F6C462E4DFAA0A997983F87F -:108FE0007ABECBCABC41E3F7877178FC92D98BF982 -:108FF000124D5E670AFEAE5E181B327E0EE37EE205 -:1090000042D66C44F9AE13F0D415013CF0FC4C117F -:10901000A7DEED4E09796F256641606856DC68B2BF -:109020008FB3BFEC23B33A473E796C31BC87657090 -:10903000F9D0E4AC4CAE69223E48921C181FCF9781 -:10904000C0AB9451DF85CAD1ECC9A1FD394EBD7EBC -:10905000089577BD1ED7E47C7E876CC4387A7E91F4 -:10906000E46043E803BD3FADD703930C8E7730AE89 -:109070009E7BD549FC35480F9CACF887F4C05B203B -:109080005B93415E7FA4E9839BD84DA80FCAE42D72 -:10909000EB913FFAC1AE9987E00FCD2E68F176399A -:1090A000C827F2033BCFF725CAAE829CC606E2ED85 -:1090B00001FD007E8363087FE657B16921FB490308 -:1090C000FA22C86F3016FCF37E4319F88BA65C8435 -:1090D0006F24F3E4919EA2FC1EB43ECAB3255DA2A8 -:1090E0003C4A1DC4F114CFB35F125CA8D7A498000A -:1090F000DFEBFD092D4F3B42E409F4FC3090B79BB8 -:1091000067F4229F69FC506EE772513E4FA6FCB98E -:109110009E3FB4F75D8F2F7C12F085F477F842C83C -:10912000D38DF2C5218D1FD259FA8DF083C6071A4F -:109130005FE8EDC5415DDE65387B71F23AF6E29D90 -:109140000C23E965BD9DD0ECC28138AE7FC7C7F264 -:109150007D8A9999F36DE8578C407D80FE9EB037EB -:109160000379A30D9C0FDEE95BAA486837500FA472 -:1091700006E15DE44D35BEAB7D9A51FEB052E89FED -:109180008B1D3C9F56572A7B2DF06749FB73EB796B -:10919000DF48F9B622A54BB1C0BCB31D9203F3352D -:1091A0004E917F9B75D5E455293F3FF47E7A95E03B -:1091B0001B8C7370FC6CA7E4851074901EAABACA4D -:1091C000EDBE5E1F5589FDF22ADD7EB9294ED0F530 -:1091D0006676F3BFD2EEC7C72570B919868EDAF36B -:1091E0001A1D35FA4DC0B1283FFBBE36A911DC3F30 -:1091F00046FACDB8AAD03CA3E242FD962FCFE7FEB7 -:1092000027C574627C5DFB25937BFCF0F05FCF2F5C -:10921000BD59F3C3855FAEBD7726C8780A3A863A52 -:10922000FBA1BDE7BAF6423CAFA7D3E4B8D0784281 -:10923000A387A64707E15BE8D9E1E8753D3DABE9C7 -:10924000B37FB59ED5E6D7EC80F65EBDFE1D2E3E03 -:10925000D3F4E9531B0D9417B94DC4C1B7893CEB46 -:109260008342CE970B7DDBFF178B01FDAC6D9DDC40 -:109270001F7198ED87D06F08E4F3385D9F8C601EF6 -:10928000DC2F674AAF85F62F8B81A4B87F99CCF786 -:109290002FB7283E17E96987C21A405EFE2AF216E8 -:1092A0004FEEF52C463DFDE4E93106DA47577CBD2B -:1092B00018174FCA55683F28DAAC52BEF76287D9F3 -:1092C0008ECFF5EFFE5E9711E7F90B7360A8F67687 -:1092D0008779603F06F54299DC23635EBEDF0FBEEF -:1092E000388C9FB6D05782F1CE6DACB711E3EA420D -:1092F000A4E310F47B55675FF479FB920EEE27959B -:1093000044F0BA9FE980467CEFF43613F985D7CB59 -:10931000DB177DC9C85F1A94AF6FE37A0606119F09 -:10932000DC68DEBE107D3DE0E39FE8F40E1B267F87 -:10933000BFCDC4F773FC478C0CFD5E762E6EC8BCA7 -:10934000CBF5F2F8BB3BC39D6A24EEBB71FF7C7783 -:1093500067B253CD197E7C4E9FBF18F395DBB6CC18 -:1093600055284E14F9CF41FB223AFCED9058931545 -:10937000F369ED8E528C3F86DBE728F63B69DE1BF6 -:10938000C51B63CD9CCEA27EE9762163DBCE863BF6 -:1093900091BFB79D4D76223CBB057F6AFCBEFBCCDE -:1093A000E570DACF343955DC07F6475B1C2F13BF65 -:1093B000723E6F1931C68BFBADDB853C6C0BF71F22 -:1093C000CC8A0BDECFE0FB179DF59EAA33E9B4DF14 -:1093D0002D61BE51DB27F680BC505D4E0C237E32E2 -:1093E000B21686EF6D74B29F633B7D9A1A85F8BE04 -:1093F0001CA7ED47AA519467F8F64A816BFC60BC44 -:10940000EFA877513D496BFDC22A05607CB3DE4D64 -:109410006D5BFD726AF7D4AFA6FB6B0F453E8E768F -:10942000BFCEB9A04A09D21B9FC5F3FC526ED6E944 -:1094300012E473F60D6318EF4C7FA24F463D71FBAB -:1094400055584748DD887219F14CF9CBB4403F5567 -:109450005A12867C79FB55E8078D97E2A3391D9A4D -:1094600094A65B0A485A881FC2E29D17E3E0FA0FF0 -:10947000ED2E7F5C3CF241F5BE0B8CFA97F1FA0EB3 -:10948000E96EF9028CCBF31551DE380FF3C6B9340F -:10949000ED62C4DFC42E13ED7B6BF9DB5C31AFF3FF -:1094A000ABD03C729EC8DBBEC9FA289F9C6F81C0BE -:1094B000CA807071FA39A5F94912E6FBE24D0EAC8B -:1094C000579898E6CAC37C6B573CA3FC695757C2B0 -:1094D0004815F0E054785ED7A9E575D9DFCFEB7673 -:1094E0007F1AE9217D057E0AEAA7EEA3910E1FED02 -:1094F000FF59C8FFDB810F627D4338AF1760F3E689 -:10950000511EFD760B5F07D89FF878CAFBF9F61D50 -:1095100086E77E7B99F17DC4DE93B43F5D62C84CE3 -:10952000EC0338F74963A3B07DF1D3C86C6A8F466A -:109530009E47FC741AAC2ABEF7C37A56857567CE6F -:10954000F76DB49F31FD7D9B82EDE1FA3EAA477B2A -:10955000BFFE1CB547EAFDD41EADBF4AED3B701DF2 -:10956000F9E7103C8F6DEEE2087A6EC7A20813C2CD -:10957000DB19C9B668EFC17A335FB8AF1593F9EF5D -:10958000C57FBECE7213D83BB37BBC3481B113F11F -:109590009FCF54A07F68C6A87FFF0BDCFFDD4F2E56 -:1095A000ACB3005CF38EDA5A7BA0FFE94F2EAEB36A -:1095B000A19E3D140ECA0EF546FF41907496873663 -:1095C0003D9971053B19FAB1A2EFE99F590A245F51 -:1095D00050D297C580B5A6FCC43FD302785C6075B5 -:1095E000FF1BF64D9E976696DE847DE6C17A2EBF00 -:1095F00064A4F89E8D94E2B07E6599DD7D2C3EC812 -:109600007E3BA53FD2FE51815362D1714457DACFE0 -:1096100062F653B1C1F2B6CC5E760CE971473CDF1D -:10962000BF9A384D7206D749E8C74D3CA396229D94 -:109630000ACE9537613BBB229AFAAE85939A509E2B -:109640004B6DC33D5F42CF2F8837127F162B524898 -:109650007D887E5C1E3013FAC7FE03E1941798786C -:10966000CCDD8875A36549A9B9B2D0798CFAD11B34 -:10967000711F6D62E587A5B1283F36C981E6A180DB -:10968000F535C5C661FD231644E1BA9E2BC1FA9D8E -:1096900089AAE440B41539BB5AF1F9224784A308DA -:1096A000FDF1636A299A9CA3CA84C3F9306E46BA55 -:1096B000ECB0C044477D774CBD00FDA28C28CAE3C6 -:1096C0001629ABAF1CA67E84A341C5756CFC792D11 -:1096D000CD63267BBE6356C97F20FF14BBA228E75B -:1096E000576A3B3537B82E0CD64D7017D9656F9831 -:1096F00084FCFD83523BF4778C9218CACF515FE60D -:109700009FE97E77B81A0680EE30D94B71BE1D26D0 -:10971000C9BE96FAAE121CEF196354314F541EF7AE -:1097200045C8FC334AA5296710FEECA80978AD624C -:10973000E4A590FB3D8BAC64272ADFCF267FA8678A -:10974000510AD98BCAF7A71563DB63E07E7AE5FB84 -:10975000951574DFC0E3DFCAC5DF718A3EC5BB95CE -:109760008B5751BF4B4AFC777CDF95ECA85CCCA3B0 -:10977000CD4CFF7AAE12ECFFADCE24F9CF1579BCFB -:109780002243E6FA6900FFA307F83E4465B6145287 -:1097900037372BFF54483DA86BDA1721FDB9A59741 -:1097A00042EA43E7557E1DD25F304FAA0A1E5F7A18 -:1097B000209FEC6BBEA85FD2F24B458285DEA9CF1D -:1097C000A82A05B93C00ED03A01F8A7A45DE55E1C1 -:1097D000717506FC433D586AD3E577994AFBD91564 -:1097E000DD7CDFBA3CCE783AD83E54C84F707F411A -:1097F000B7FEDC0346B293B9D132E5AB34F82A4662 -:10980000863EAFF95F1502CE1D0677530CE5C79C67 -:10981000BDE87F68F06BEFD7E0AE90EF29A5EDBF14 -:10982000EBC0AF87170025FF4D0FC78178118780E8 -:10983000BF41FE5937AF4B835FDC50765BF3CF2BD4 -:10984000414F4507EB299B1487F576C3E9296DDE67 -:10985000E1FC306DDE6576173DEFDCFAD9D1423997 -:10986000A89F7A2A3626B8FFDA67EB43EEC79FAA8D -:109870008A0EEE6FFAAC0AEF4F57D4461BF0E34165 -:1098800026393CC89F3DAA82FBCF25C79C4DD89660 -:109890009D746399299B71C6D384EDD4F3DE1E3386 -:1098A000ACEB8E0C59C5B85DF33FF4F09A13781CFD -:1098B00072F0AA6AC5FDD31D1ED58AFEFB8E275401 -:1098C0002BFA1F3B9CAC02E331679A6135FAF3CE69 -:1098D0002C5E677855E8E16FE2F9F35A7B5A717FA5 -:1098E000837A11EBC2D127A8FDDA4F75E007D1AF1B -:1098F000CA1EEC571D54BC367CDFC127BCB6E07DC8 -:10990000C21BF5ABFE8C363A1EF96C4E887C96581D -:10991000EEAE0A96EF32FB9290FB9FC6A904FF8C35 -:10992000A48743C6DDA13E12D2077F3103FD9146D5 -:1099300013A33A598F81D7C9EAF1F8A8C0A3C36627 -:1099400047378619E354AA6BD38F739470FCE9AF41 -:10995000A727F0B86823C80CB6F72470F8F475B1DF -:10996000FA3EC47C0B713E983909F9DC61355C0123 -:109970005797391392EEA47AD93CC3A369D0AF4E5E -:10998000C8E2FDA9869D581F7B774236EFDF6AC883 -:1099900033821FF02B36FE4EAC07AF0D13759D0FB3 -:1099A00024D27E9816DF2886532F2EC638738F91C7 -:1099B00061FEFE1913D8BDDCC0BEB9D5CCE352ABF5 -:1099C00089D76D3F957AF429D41B6A987B7A02F97E -:1099D00051C52AE2EFBCDD42759D8FED2E4B44FA56 -:1099E000DF93C0F35C593BA726A17EF917BC7F56D5 -:1099F000C2C4E1DF8F75BE38CFF91D59E47F67DD42 -:109A00000CE89502F887F098AE87419840E72598D2 -:109A10003309F36C8DD1269AE79E04CE7F37DA0E98 -:109A2000AAFB8D32ACDE0EEDFD82FE0FE07B095FFE -:109A3000FE51737063CEEE1F35773CEF237D6539A1 -:109A4000D78F7EACFF3B11B4AFC246FA69FFE5E3A6 -:109A50007BB21CE89F7E12CEF1B7D03BBAB14FC5A6 -:109A6000FA0DEF4D582F9191E8AE453C2C327B6FAB -:109A700021FEB1AD8EC0F96FB41E78F07B21800459 -:109A8000FA544FE1F4D1DE0B38B5A03DF8589C03F1 -:109A9000D1E080F7FF00F9408367000E5D5DB89666 -:109AA00067AEFBA381F20C7512E83DE8EF3CC91CE0 -:109AB0001E98E7A2E6AF8BBC266E45E17BA61C5E36 -:109AC0005A628336BF6D258F737B95903CD7A4E394 -:109AD0008A7EBF83ECD654ED795D9E71AA886BA710 -:109AE000EAE2DA1713849D4966C9C1798035226E8E -:109AF000B8DC333A0AFD4CD45132E0D5A4CA6C72BA -:109B00004C40CE5B21EE674171BFC667E38FD9EF52 -:109B100047B8C71F63F7915DD7E61DC82F70BC5CBF -:109B20003ECEF132A12FE3A7D3A06FEC3632AF1AAD -:109B3000584F2107955DC6FFE078BBC98B75CB05F3 -:109B4000077E99E7834BE624035383F010A6863300 -:109B500035482F5A336242FAB2866F61CFF3C4FCA4 -:109B6000118EE49079F6C49477A37DCFB32D27FBB3 -:109B70001E357974C83CAC4709B1F3B028DABF9CF4 -:109B80000840FD0CF05A704C09B1E793E23CB86212 -:109B900036F9A4A2B3FFCD32CA41E199D0EB0786D2 -:109BA000A3CB70F863393F45FFEE1FC55FB4331494 -:109BB0007FB115A1F88B7785E22F7161289E46B899 -:109BC00043F192B27C5CC8FD9B56E786F46F7EBC85 -:109BD00030647C2A18A4E07EDAD33343C6DFD23C5B -:109BE00037A43F76C3A290F199DEA521F7B35E5D5D -:109BF0007143F41EDFB226649C9EDEB7B6FDAF90C3 -:109C000079357A7BE0DFBF82DEE6C4507AA70AFDB1 -:109C10001AEDE4F565FD46DBD312E8234C13A15E93 -:109C20008B6E7FF76BCC43788A55AA9FF3CC64B4D4 -:109C30000FFD82EC92500FA5C0148634AA5FA7FADC -:109C4000BB1F1B0C21FBE28989DCBE2726F27CCDE1 -:109C5000CF4DFCDC520AF88F64870C2C102F031EAA -:109C600022315EA678FAC7CF60BCDC14DD97A14232 -:109C70007C6CC6FE4D017DB9C8AC36F6013E26C8E7 -:109C80005C1F829E4C4B84F93F919E30723FC263B1 -:109C9000443F22C5C23C91B9643F287F1CCDE224D9 -:109CA000ACC78F0AE869F51A106BDF8A2C3A07F502 -:109CB0001E4282FEAF2586ECE8DD9A7E5A9E49FA66 -:109CC000E9B22DD40FBBFC401A5D3F71AF99F6FB92 -:109CD0004F883A446DFDE784DEFA53BD85DAF3F52B -:109CE000F6103DB67CE3FA08F41F4F64707F51BB59 -:109CF0005E82789B88AD2CEC9AC58EF9AC7BC0381F -:109D00004701BE5775F7452E62E43716E3BA6B3745 -:109D10005EB9F74DE8D719FC09DC3E7878BDCCC7B1 -:109D20008CFCCFEA6F5888FF343791C7E973C5FCC4 -:109D30000BA0B1039E1600FEA3B17D775A39F2271E -:109D40005CA7F369B3BB19D59FCC71A7D23EE35191 -:109D5000E6F8701780F89D4495E09CC75CB45FFFFF -:109D6000D1BDAB2270DCC07CDA3CC028E86F7C1C23 -:109D7000ED312660DC7F1BAF6F80F759F0BAEB9EA8 -:109D80009427D10E69EFFB88B92F7C88FBDDCC418D -:109D9000F36AF3331613A29F762C5FF9692CBC6F1C -:109DA000CD0103E513D6749829EEEA5FF1D7AD2F04 -:109DB000C2FDFB52FA6E42BBFCC98A6FC6203FDC73 -:109DC000BD01F410ACB130CAFD7062509C72E281EA -:109DD0002B11781FECEBA617D1386E36537DEF2789 -:109DE0002B368F09F6471F4D2CAAC5E7D8E41B3B3D -:109DF0006F58F27A6622D563097E7A58F0D39AD7E3 -:109E0000C6921FB52662809F787F13AFEFD0D6F140 -:109E1000A1E0C715AF7F5D107CCE7407F0913A8644 -:109E2000EF6BA920533B7B2EE7E0FD57147713C25D -:109E3000D779F57424F677BEF737829FCDBB31789A -:109E400051063D0581FD65EDDCE5C2F6D83CA43B3D -:109E5000C85933CEBFE837AF5DF81DE2A763F3A65C -:109E6000EFE3981B3C7FC9847D71083C807DA1F89D -:109E7000A09F85F3731D428F2AB8839E86E7991CA5 -:109E80002AF1B3931DC27D97C62E03C3BA9548DC51 -:109E9000B409CAB345CA06CD08392D49A09F855ECD -:109EA0007925F1E49D4DE4E787FA3DF96FAF08F1BC -:109EB000775CF08FFC9D97DC8D9807BAAEDFE333BB -:109EC0002C3145DDB8FF0381B0532A105B38F06BAD -:109ED0004B14FB22420F77A21C61FD3FCE85F97A1D -:109EE0005F383F670CA602F5F80F604DF8B02945C2 -:109EF000B4D2C50C0BE8C5BD897F78E669D09396CE -:109F000074BE5EEC37E2DFDD9CDF06FCABB7C791C9 -:109F10009E62DFC2DB100F225FA1A7533EC8078BF2 -:109F20000D9233F1BC6FFFDF22314FBB35467D1FF1 -:109F3000E9E03F20D33E4D98D2678A1E222E7B1344 -:109F4000F59E89FB4D546FDEC6F38116D5C9300EE0 -:109F500008B3DB27049FB36B17FA6ED5FE4F469903 -:109F6000800E170C3D91D9307FCDAE1D91E8C6DF34 -:109F70006B747F8A7CB7F2C40705763ACFB671144A -:109F80009D03F08DA6BA83F10AF328B983E1A8DB1B -:109F9000904BC6B8760325E3D9F8F6BC87501FD599 -:109FA000F9F83A716E2CFCCB6C63D4BFD8D6188309 -:109FB000F3D5FDB62319E567733C8F135FBF3A8E67 -:109FC0003FAF3005C77F99182DF8D96BC03863B300 -:109FD000884F2E5E35D038EDFDE3DB8A643BF043DD -:109FE000B6AF792FC543ED6615E91AF60AE378682E -:109FF0000F2339AFEB9CC1309FDF1FCD1C12DCDF7C -:10A000001AEEFF039D33EB30AB981F0DB337B31837 -:10A01000987FABD80FCD048EC2F34ADA75ED7D611F -:10A02000ED3FC55802F981F2B4614A33BBCD168CBD -:10A03000E708C2733CF2533CBEC767C0FC88FF16FA -:10A04000C65E26B80270327AAF066726F9735B4D9A -:10A05000FEB3787E05E0B223FD33198793B58F55A3 -:10A0600031BE0FB33B691D6176D5E19106C35597AB -:10A07000C3BC68BF7FBC960DC82BCA6F5D78A06F4C -:10A080000119D83A9A09F9B63F5B3A2DB80F8A649C -:10A0900072E0F9711B629E6D1A49718347C63816CA -:10A0A000DA88185CA7CACF3B636A2897E301F7C533 -:10A0B000AD167E7F603CF0B70DFB363ECE1165B726 -:10A0C000CE94484E28AF572BE4FD31C977F67690F1 -:10A0D000D3BFF8F6E6A8004BCDBB7B884F571ADA02 -:10A0E0005F1C0FF7375ADCF94980CFB74E1AE81CCE -:10A0F000E99F5E0BF35662FCB87B63827308F9D06C -:10A10000CFFFC3E36B9F4F41FAEF9654CC9BF61BF6 -:10A11000FDA310DEDAF6CF4D548FD0768AEA938E07 -:10A1200024B99DF89EC96D0DB46F3C8535D3BE71C1 -:10A1300096387FDD92C4F5C7E563635E6E08C2FFA3 -:10A140008349DC0F637EF7CD2837ED423E3BD12FAC -:10A15000817697F08F7675DD9DA606E5FD1AD8DE2F -:10A1600014C4F75AF636B5DAF57E2F3FCF98F5913D -:10A17000E53E6710FFB993B89FE716EFF327B917CD -:10A1800024A1DC769D3645AA785EA56514DA911681 -:10A19000F09FEC43E065406E757254A7F84D38BEF1 -:10A1A000EE1C3F770A746EC2FAFFCD1FB58D5B02BD -:10A1B000D77701AEB1DED373C24C758FBB8CAE14B2 -:10A1C0001CDFF0E15739A8B72A1069F0BFAF3A5643 -:10A1D000DE8C7803BE2F0E47F9DACE488F69F299EC -:10A1E0008DF209CF6723DFE7633F93F4F056532FD7 -:10A1F0003FF7B98B9FFB04BE273900BEB7A39F90E2 -:10A200006D0739A0E7C7927C6FED35D0F9540FE8A0 -:10A21000F15BA85F5C85FDADBDA576926FCCC3E711 -:10A22000A29CFAF6D23C2D108320E924E60AF61F00 -:10A23000DB1323898F35FD783091EBFF960C350ABF -:10A24000EBFFADB21C2217417690F7859DECDD50F7 -:10A25000FCEC0BD3D0DE09BB20FC27769CEBF94746 -:10A2600085AD5AF34EE1EC2DB0CE3587E5817A6E9F -:10A27000F4577D824FF60AFF15ED849AC7EB67F01D -:10A28000FAC40DBCCEB5C0B9BA04CB38265734EFEA -:10A29000C3B6D0D55282678EA72DECDDC7CF1EF393 -:10A2A000F3E3AD7BEFC8C27DEAFE136686FB24AD07 -:10A2B0007FF3FFE175C0C3773B01FF43D825580EFC -:10A2C000F11F58EA149634F87EBFA4E98FF9952857 -:10A2D0006F175BE5401FEC612D3038F67F9D54F51C -:10A2E000AC07004B1BE17C1D59A230D94D6DFF918D -:10A2F000BF25A02DD8758CFB4DAD266716F24FEB10 -:10A30000E8D0F3FA5AFB62123FE79C6F6643E625FA -:10A310000F09BB37C6C39E413EAA6D95ED5EA0FBFB -:10A320008556D96902FFE6ACD39D806765CE31CFF3 -:10A3300082A968E745DCA87D4F6519FA2760A71E4A -:10A340007C61501EDF807CF450BBC47E066B5EFED9 -:10A35000D2D0FB0A35629E87DB36EE4F013AAE78EB -:10A3600025745C8DA813ABD1F92F8792447C98C6D5 -:10A37000D2D02F01FE21BD605458B719F8F5C16441 -:10A380007707C61B9BC5770C407F921C7608BEDC06 -:10A390002AEA04FC5B25DAD7CB7CD52B1BE0F942FB -:10A3A000C52BA39D62D0E23EC164A7BB1CF10BEBA1 -:10A3B0003E86FB35CB851E5CAEF9655EBE9F01E631 -:10A3C00096FCB229CCDB1889EB7E5572F854FC8ED2 -:10A3D000C8A03A5C5A779D5877CD8623FB318C5BB9 -:10A3E000D5123AAE4EACBB4EB76E6D5FFBCF49BADD -:10A3F00073C837B86FF16723F7133E10F368F7CDD2 -:10A4000023B83EAC05F0906E355ED9EBE57E9D0D30 -:10A41000BFC373BF80F77E41EF3AE633A5C0B8559E -:10A420002FF075B26743EB3F1F6C7DC484F1959E9E -:10A430002F966F31923F0A8833A1BFA8E78B156230 -:10A44000DD2B74EBAE754B3AB8B89F3C18AE960551 -:10A4500048D7555B8C0CEB11F5702D6B59528E7CE7 -:10A4600036985F395D5688F90270AEA6737C370A5C -:10A47000E7A811822FC7B17144978AD81BA28BDE3F -:10A480008FDDBE7F9C15E5FB72F7688ADF35BAEB7E -:10A490009F2F177EF08C0D8CDA0B6D25D6F118A747 -:10A4A000F4181C924AF156E478C0475E87CC2AA182 -:10A4B000DFDF9EB6DE0378CF3D9C5F85F17CDE61F9 -:10A4C000039D77DBD99D4FFBC07907D263D3281F4B -:10A4D000EDA0EFCDC03C643FFB7B72D7E3B980FEBB -:10A4E0009ED27C9C57827168E773851D68E8C9B568 -:10A4F000069FEF2E18C1E3F5A7923EFB31FAE13338 -:10A50000B61BE97CC30CA3FF3DAC9FDAD9ADD0BE2E -:10A5100075CDE1A56BC390AEAF49B46FBDBF774DAC -:10A52000DC62E4AB76A31DF7A1FBDBFF6D2FDEF74A -:10A530006C91E87B12751D65595BA19FBB31CF11F2 -:10A540007CDE2B375A25F8D8082BC5C3336E3292E0 -:10A550005D3C9F6CFD25FA372B9C1B498ECFEFD9B4 -:10A5600069A2FAB9AD1243D3BF3F69DF1B888FF3ED -:10A570006F1E31A1935DD27AC4D4F777ECFD052F1D -:10A5800004FE1407379B304E59B551EBF799904EA6 -:10A590002EE1FFD4BE728AFA2BDA24D2332B5E92DC -:10A5A000E93CFBBE8EB74CC8C7B55B2496981A74BD -:10A5B0007F8314F21D84A58CF3C152A1675632EF3C -:10A5C00053C9306E6533AF23604F87D6E5AEDC32BA -:10A5D00087BEDBB4AC79687DF3B0E0EB87301EBC9E -:10A5E00015BF83143AEE61EDBB5C3A7E7E5CE3E717 -:10A5F0004C9689FCFC55911A950DD7BF3AB2E2E60C -:10A60000A1CEB1F7083BACD9C1CB3E03D911FDB8FF -:10A610008B6D5708DEBA9ECB26B483E5ED9708EF25 -:10A6200095ED5D54C7711773D7209EEE6AB7DA5166 -:10A630008E2BFBB85E9AD96EF67A25BCDFD284F4F5 -:10A64000ECEFE4758B9E3D12F92F9ABE7A48E0EF4D -:10A650002181BF874041A7E4A21FCBE3DE873336C9 -:10A66000EE8F81FBB5E27ACD817D91E8EFCD6497E5 -:10A67000EE457AC07B18BE87BD148AE73B1987E395 -:10A68000CE2DBCDE596FAFFA4764CDA6FC23C49D26 -:10A69000084FCD96503CD7EAE2ED7523B87DDEA495 -:10A6A000C373A59F59B3110E5576786974AF82EFC5 -:10A6B000EDCE9128BFDAADA6450DB5FFA8B5EF09DF -:10A6C000BF59EBCF16E7AB5BECCDB6E038D894CCF6 -:10A6D000EDFF8A29B207E934103FA4EFCB510D8179 -:10A6E000F801E286DF8C88E771041674BC3B526681 -:10A6F000717181F8E18749EB2B73A15FB785CBF9C5 -:10A70000C5C9301F7EDF4B61E45FD66D31D339C0E0 -:10A710003AA03BC509EDFC1C83AB5D2A437A83FF5D -:10A72000FDEE888978AE8619E360DD73DA389FCF55 -:10A7300029BD447C72209DAFF7B2A2260EE58F6B37 -:10A740007E389EC35283CF3F805CE2F8DA765E0F9C -:10A75000D4BAF7EB51A9A8D73AFE3A6A09B45746DA -:10A76000F0F56B7E9E1FFCBCD1DCCF3986FEE78303 -:10A770009ADCD8F93EDA83C2CE30A989F8BBD6D8A4 -:10A78000F2760CFA4D5BF9BE3DDB6DC46F9CB18671 -:10A790000F5E6F8A81755F7C5DA27A347CFE09E072 -:10A7A000B38B4B5B4EA31FFDD5560BF98F0F828FDA -:10A7B000383D77B03C6A72AB7D77AA81AD257F7258 -:10A7C0002D6BA27695E0E38B6D8D26CA9B79839ED7 -:10A7D0001F3DD8EF58A5E33B537228BF357C104E80 -:10A7E000FE5FFF01D98EFB2780A7FF4E0EC687F0C4 -:10A7F0002F5AF786113DFB8FD8C85EFC49F0D979F6 -:10A8000091376E982CD3FA0D53789BD5F9D668A45E -:10A810001FE21BEBDE3777BE358E9FA7F612DE57A1 -:10A82000BE8A49F120385BAC94DBD3FA0D1F2CA211 -:10A83000EFF0D4ED19806B8C292E00D770FC2F49D6 -:10A840003C1E3448A1F160DD6ED9155CEF05EBB913 -:10A850000FF54F929003A6F813D02F1999AC92FDE3 -:10A860006A68E7F43474F016DEBF80E73B8CF4FED0 -:10A8700041F78B3D3578FFAB542BDF4FBEEAA9C4BF -:10A88000FE7747CB544FF9DD0F568C0DD69B0CE16C -:10A89000047AD619FD0914371E31107C75472E270E -:10A8A000A4DB501F6D2CB567A3DEE1FA6EFF68EBE9 -:10A8B00072E4630FBE373130CF6BC2DE325C6F1291 -:10A8C0007A152FF079C57AD7B2B9223EE67C942D5D -:10A8D000FC3D882B26264F1C1C57DCA83F09F6E0C0 -:10A8E000E86209EB89140FC6B53B8F737DD0D0F1B8 -:10A8F000D0A7C8E7759F98A9BEEABB9D0F8DA53A62 -:10A900005BB7FB56F42BBEEA7CF856CAF3496B09D9 -:10A910002E0FC29784FECB8709580FBAAAE3C3044F -:10A92000B2AFBB26AEF744A09F927B275E07BF81E4 -:10A93000F80FFC17E2BF9D3DF99ABF62C579571D1C -:10A94000505C889F5507F20F55A21F71B8381FD56C -:10A95000B874389FFC953CF4576C01FF455B4F651C -:10A9600032AF77E9EF0AA33C81C44673FE61E92167 -:10A97000FC53D3FA0ED9F59A3639A46E507BCE9D8E -:10A98000ACF07D7E8D7F5A2427F1C776DED6B4EDFC -:10A99000A4F5AD34B610BD1BB618F9FDADBCD5EAB3 -:10A9A000AA3D2CC683F8388497800E334D5EFA6E2C -:10A9B000C5C154EEBFEBE9F15932CF631C3CE1BE97 -:10A9C00019F9E560917BAC7D08FBE061C53C3E95E3 -:10A9D00004BE5BF97925FDB853C93C8E8F8C0D3DC3 -:10A9E0003F3A605F9239FFCC340DFD3DBD9F69F267 -:10A9F000C4D83306E08BA39546FB3AE1B78F08FA3B -:10AA00005E42D55D46F20F8E32FB3B5867384BD322 -:10AA1000AF93B95DD5F2DDAE0D2ADFD7197CAE91CB -:10AA2000F4E47C6D3EFD7969E1D7CCD7F935EB359F -:10AA3000FD37868D41FDD722CEB9ADC90CF306E7AF -:10AA4000A3F4ED7EB18F81E775B06DC8FC98F23646 -:10AA500007BB4EBC41756627C2D8689E97A3FCF51C -:10AA6000AA61F2D70D03F2382F84BF347A5C10DF6D -:10AA700055D1D3E30D81776D9F2D5CECB39D56DCF2 -:10AA80006F24535DD67913FF8E9A9FE2AB864CEE0E -:10AA90001F5D2893685F1CE01C650ED2EB1746F023 -:10AAA000B8EABB0B24CA9B76E1788C9F5A24AAABE8 -:10AAB0005EE5EB35211F8D695DF224C9AB871D630F -:10AAC00041DFA9986DE17671806EDABA07EC568C99 -:10AAD00087EBE1386A713CDAC159C2EEE9CF218DCA -:10AAE00065BDE51857563B2507EEDBEBE93D77E101 -:10AAF0008477E2FF013A9F4B761F21FDD67B7901D7 -:10AB0000E63F0F667E3E0AED65ED307CFB3BC1B74C -:10AB1000DAF7591C63D546FC3EC98F12DD9F207EB3 -:10AB2000FB0DDF468E63F87CDF7FAF91902E8CE8C3 -:10AB3000319C9C9C12F39D4A16DF258CE3FB24CBB1 -:10AB4000B18FF26AF48EA4FC42F68DED4B35EC7EAB -:10AB50003707F5D6C5AE0339A6203A9E5F03F28EBD -:10AB6000F6A3635F826A0BE63303F1972469FCA6C0 -:10AB700008BB18CA77E791EFB2B1FD30321DF5EE90 -:10AB8000F6A391B7E07CBB783BC09FED328D837814 -:10AB900067CCFC8860F89E24F82EB4F07918EB1B83 -:10ABA00053353EF87EE3707C6B4CE1F584217CAB41 -:10ABB000ADB705BF8783FE7DA799BE8783F9E6E819 -:10ABC00020B9484DE1F230497CFF660AF3D0F70026 -:10ABD0002789EFE04C51984F89C17D2E9FCCF765B6 -:10ABE000F9798602C1BF93145F17D6394C11FB3235 -:10ABF00085AC97C64D677E6A9DCC4EE7148A9983D3 -:10AC0000DAC916DF9D9876C96E69A1FA3F5F821294 -:10AC10007DD622CE430C41B7C0FA15FAEE0DF1A550 -:10AC20008CE76186FE6E4A650A9773FA3807D2F799 -:10AC300002A3FC147EDF0C5F325561155877749BBC -:10AC4000C22CE100EFF6B70D24BF9D7DAA17EB40A3 -:10AC50001DB1E2B92F18D5BB4E7272F944D382757B -:10AC600012DA7AF5782884F9303F364981C892F0B3 -:10AC7000E8A3F7DDCEF8398D22A6D207566EC78F2E -:10AC800027935EF7539C54027112EA7583C543F80B -:10AC900028C3E4CA44BEBF1109F314364BEC38EEA6 -:10ACA00057A4F1F56AF3170223E0B9BD32B15E4C47 -:10ACB000811E8FE1FB1E9154385C6AE7DF094AA0D0 -:10ACC000EF04DD285EFB13F8772123EFF75FFC7EAE -:10ACD0007E60FFC781DF0D8A0C7C8FD281E74C300C -:10ACE0007FE753CE07FBCD77A72CAD4E9918A897D9 -:10ACF000636EA6A25FA1AF9743F49D0B3ADFACD57C -:10AD00007BBCEA9DABE2B9B98571163A4F9B6B19D2 -:10AD10009587762B23D15D9D42751F5B6EA14914EB -:10AD2000EF44574480CFADCC3919F11CA8D7E3DFED -:10AD30004F1A38CF94C0E8FC9FD5CCEB199F01B9CE -:10AD4000C0EF178154A958D7C29E28A1FAC7A7A25D -:10AD50002D0E3C87604678AD01781B2DA2EE47573B -:10AD600077D96833D0F7381B59389DE79E15E6FE32 -:10AD70001EAEFFB188623A2F9DB56D5A12F983B0AD -:10AD8000DE69DA7A0D83EB10B1FE0F9FD3D7FF692E -:10AD9000EBC2E3EBF85EBBC097B64EBB76DEC7A94D -:10ADA000849CF7D1D6FF4C385FA71177E2D3E859DE -:10ADB00015F5837E7D1A3FFC3FDDFB356D605C0041 -:10ADC00000000000000000001F8B080000000000D1 -:10ADD000000B7B2ACBC0F0A31E818565181826F1D5 -:10ADE000A18AD112CFE066607804C42C3C0C0C859B -:10ADF000407B23807424101F01E2A340ACC2CBC06F -:10AE0000100BC471403C07C89F0BC4A5409C05753E -:10AE1000632B0B03433B107702713710EB30333059 -:10AE2000E832136F7FBE0803C31309045F51126831 -:10AE3000A734FDFC3FD8F00A7DFADA276DC0C0B018 -:10AE4000D502C15703B2B759A0AAD96E81DF8C1DB4 -:10AE500068F23BD1F8BBF0E83FAB87CAB7D540E515 -:10AE60004B693130782285899D067EB7A0E30AA020 -:10AE7000DE4A200600FB72DB43680300000000008E -:10AE800000000000000000001F8B08000000000010 -:10AE9000000BE57D0B7854D5B5F03E731EF3C8CC9E -:10AEA0006412420818C2092FA30D382121058AED2A -:10AEB000400091A206B50A1575C22309794DC0C795 -:10AEC0008FB56D0682111034582C51A39D2028781F -:10AED000830E3448908003581A7A5183D7FA687BDE -:10AEE000BD4129200412F185DEB6FE7BADBD4FE6E3 -:10AEF0009C9319E0DEDBFFBFFDEF1FBFF6B0CFD99B -:10AF00008FB5D76BAFB5F6DA7B648B8B484308F906 -:10AF100016FE7E40C8748910D23FFA74BE4E549219 -:10AF200048485D0E2DA710923E9C848840C8E46A74 -:10AF30005ACE23E4D13B49C89A49C8FE2316FCBE29 -:10AF4000CACFCAB45DD8720DFD3E82BD7F328BB6CA -:10AF5000A3EF9FBC2062BBE04C12DA4CCB4984F6D5 -:10AF6000368CD021FCF89CECADB78FA2F51BEFB46A -:10AF700010AB4AC8137418329E1017F1D9096DBA74 -:10AF80006A38EBEFF19996E745013E46D2E6D3F2F7 -:10AF9000EA29C5F9AB69698DCCE06A9853FC7C90CD -:10AFA000F6EFB10CC379D07A4F3A69BDC7DE2F21D5 -:10AFB000AB69BB0D732D427136ADD7A4CC0E65477E -:10AFC000E7AF3DE71289B70B5A2DE3E0E9E3CF88FD -:10AFD00002CF5F4CB4E0386BAB193E683DC592467A -:10AFE000484BC7019B9FF6B7B6A2E5E834FAFD913E -:10AFF000E1162FC52079A4E380FD4A3A7E30CFE2E6 -:10B000001D416BA74B11C1E38C8E379E50C0C7D238 -:10B010007ADE1D36D5D9B73EED7712CC7B0DC5BB98 -:10B0200098196D3706E0A4EDD6529285E9B8BF9421 -:10B03000BD8761DC5FDE902C0449B4DEF50024D4CA -:10B040009B6B21115A8F483D3642C7593DF16DDB4C -:10B05000085A7F75A1052641D67AB5EF5E3B81FE81 -:10B06000A68E3C3C1CE87A3DFD0EF3C87E7C36CCB7 -:10B07000FBB1290A01FCFF52A0F5288A1B8A941F04 -:10B08000027CAE6AE281F7F4E98B85D756C18670FF -:10B0900090351B08C9270002FEADF685560E05FE49 -:10B0A000CA235E28A77B697B67DFF69D8215E9D2FC -:10B0B00020070702FEE2D16F38C7E7EAAC2576A089 -:10B0C0000721F56985A308590F78824125BF3ACB3E -:10B0D00015ADBF5260F85927139F40E79790A7849A -:10B0E00096513C5BB23D7360BE4EBF42AEA3E55588 -:10B0F0004270A0087419A590CD2AF2857D042DAF69 -:10B10000BD2AD90BFC572784D324F87E03FD4EBB00 -:10B110003C5038660EF067A357417EA6FC7318F0CA -:10B12000BDD69F4C56ABF8BD03DB3B877BAC880993 -:10B130000A0FC54B3FCA4B80D79C9BEAAE1F06F453 -:10B14000196BF10085560B93D4F9203F49360F8CCB -:10B150002F8FBD19E927F74F16888EDE3F077A53E8 -:10B160003C3DAA16FE1C9E4FE77D943482D65F9329 -:10B17000F34A03D0E999FB6D48BF67C6762C06B940 -:10B180007AF242EEFB7E944BC5BB99F6F36CCE8906 -:10B190004C42077C7CFA474980BFC1C3EBEF216E6C -:10B1A000FA9CD953434653F8487DE1824CE413E1BD -:10B1B000168AD7C14B15A2DA182DBF25F09DF8C20B -:10B1C000D9ACECA4F319CCE9DCD2F1B6AD08FA9B0A -:10B1D0004B2223DDF8DE969A1CD53383F348249561 -:10B1E000F6FFE4C24328E7CF5C9DEA65729E86FCC9 -:10B1F00092C1FB4987FA54BFA4D94830813E07B7B2 -:10B20000F7DC0C700DCE3A3117E0DCFFC62101E807 -:10B21000F6ECE85415F45192BF837452BA0FCE7E07 -:10B22000F741A8E77286D20AB3B1FE5FB19D09FE6D -:10B2300066D5B709F0B64DA83E0CF409E658BC8CAB -:10B24000DE4C0FAEB93735047A64B0E34FB3C4A116 -:10B25000C80784A452F83C04E5A44E88D88641BBB4 -:10B260000758BB212424009E076705178B6EA8EFA3 -:10B27000170A5D7DC76D018D08F241391DF875BB58 -:10B2800042CA0A63C8C16B5C9EEB04321BF9994841 -:10B290007F03BE1992C4F8462B3F0BF0D071B7BFA5 -:10B2A0009EFCC36C0ACFAF960ECD11293C8F42BBDA -:10B2B0001872B396CB81A39D04058AD7FDBFFB9D71 -:10B2C0001DF0B6DD424AA1FEA4ACB0AD93D315E8A3 -:10B2D000B190B0FE1BB337DA505F0859C8770BC77F -:10B2E000293EFB6890BFE5829FB64FF330BDECF27C -:10B2F0002A21D0CBAEB4A060A1F0A8D9C4B33193B9 -:10B300007517A4F89B07FF00469758FD356B9342CD -:10B31000ABE9F779D954D0006F1457163AEE02C250 -:10B32000E639CF5BB718E84748A105F0B9DAC3E8BA -:10B33000D308E3D0A934A6B37ED6DE4742CB818FB3 -:10B340003CACFD706842E9363CEF95FF25D07ED3DA -:10B35000793B907B68979016B259683BB5DA4210FA -:10B360003E29725800BA8F4A55019EC634EFBFCCB1 -:10B3700004F8674BDE8DF4F3708083F6D3586DF1DB -:10B38000A1BEC8539A404FAFF6313DAFE12B938F2A -:10B390009BEE8D0874EE2493EA49C4932F62F74024 -:10B3A000399BC19399C7E6D50BFF2825B49C364E2F -:10B3B000B74508D4D3F050CCFB2BE6F370A68556E6 -:10B3C0004A00771E839BAECB084F7AB6D2047290A8 -:10B3D0009EC6FA53297E34BC035C0E0DAE3C5A1F48 -:10B3E000F4B0576902567070F88AB3193CFB8FBCF1 -:10B3F000DD2EB0FE50AE1C1C5E079F3F017853B996 -:10B400005EA7FD35CB1141A4F5436389BA918DA6A2 -:10B410004AF9D1EF8F57533CD082938F43D65B517B -:10B420001EE8ABE0B7940FE6D7D37256543E46AC55 -:10B43000B41AE4C5C9E74DEA991C51B68940BB4C22 -:10B44000C2CA1628D379146719E58C7875650A87FE -:10B450000BF89DEA9F65E315C63F57313B86105DAB -:10B460003DE0F3B1EA736BF0BB82EB7AC64F150394 -:10B470007C83AB53278BA04FDA9FBAD9027C752F00 -:10B48000B18889C8CF42AFFEA2E3ED5812B1C32400 -:10B490001DED85C980B78CEAE4C90AE0B1DD8F658E -:10B4A000477BB50F9FB0348D216410D18D9309FA7D -:10B4B000D553DE4CF14AAA9530E8EBB17A38E9F77A -:10B4C0008CD7EB6701BD1E5E7C6820C86FAAA9FD02 -:10B4D00068CB5094D3C1AFD35A38FE899F41FD55F4 -:10B4E0005C9F3800E231F87C1D9E839D54CF523D15 -:10B4F0009D4111AC8C89EA8BD557BD9BE37772FED9 -:10B5000049C667049E66BDA2AB7F15AF1F142E5AB5 -:10B51000EF04D6D3E0317F3F2758504FB9C0CEA4B7 -:10B52000F87D8C78E6E0BAECB5E0BA98C0DF87BD6C -:10B530000726233DC3C42B6482BEFD9B55CF073F26 -:10B540008197A06FA530CA8992E140FB90CA710231 -:10B55000AC7B8D527529BC0FA73B08E88503530FC0 -:10B560000980CFF456FF109043CDCE9DEC0DA7C1BE -:10B57000FB470EFBAF44F98C63376A76A2793E57DE -:10B580005CBB1CF5C1107F4F3BACF7CE0AC97B1DDD -:10B59000F0979FC2E5443DA992EF52F8BDC165A066 -:10B5A00067553F2D0FA0CF0AFE2C65DF57D594E6D7 -:10B5B0001E97A2FDAE1A4EED51AA17D777ACB7DD94 -:10B5C000007646B54505BE5DEB7DDBE673427972DC -:10B5D0003FC0734BA166F74504182FFD1D1FDA7994 -:10B5E000633D8A0794D6286B64A047B75E344E7DCE -:10B5F000770CC0416EA5441C189F8E74BEC867F1BD -:10B60000D61380C5A25B47F667EDC0F5E50D721550 -:10B61000D2455B57B475047BA4FA653E97A347D423 -:10B62000B04D407D456597D2673ED7234EAE37A9D2 -:10B630001E667A8EAF276B17A7E27AA2E94FB0ADEC -:10B640004149CCE7FA766DCEF3493750989CA06714 -:10B65000412FA591C9B0FE8E003D03FA490A0A3078 -:10B660005EE3580F598DEB98519F8EA8667AF09142 -:10B670003482FC44D7A12658EF1AD3C369D04F6354 -:10B68000F501C1AF5B3FB5F5CE55DD41400FCECBE7 -:10B6900063EBDCBC6C36DE1F00416319BCA057CDE8 -:10B6A000EBDE2F26EE406599C0ED2D33FE050BB382 -:10B6B000031F9BF936E271ED82C7F149EA37607FDB -:10B6C00069364683555907F0FD1ABF653AD8DDEB58 -:10B6D000A58E95C329FCEBA7CF5382F4FB1A2FF359 -:10B6E000BB564F9CF73CAC6B568BC2E0AA2E457BF9 -:10B6F0003581C3B501FA463F5141BFE8BE3B37AE85 -:10B700001C4AFB49A37E8CA042A590CD4ABF3B8139 -:10B71000A6A0BFFD1106BF974C2631E0FF57C1C15F -:10B72000FC507F47FB08A4A7C503F026787B6CE09C -:10B7300027AAD40F53558057B58F42782D9E656A3E -:10B74000B4FDEFB9BF70172CFC60DFCF79773AC832 -:10B75000D7BA3B995F6686FFBE49A1760B8E43D070 -:10B76000AD73C5C1EB5CD060A07FBC2184CB95C517 -:10B77000E03A2E307A3DD631F97AF4930AE97BDA51 -:10B78000D1E31D43ED20DF667BEF99840F73D0DE9C -:10B7900031AD33972A0F36E9FB51D6F00CE4B76D83 -:10B7A00016D45384303D27108BFAED305844185C82 -:10B7B000C87A547FAF90237316D0FA2B763A09E0FB -:10B7C0004BE38774DEE7EA6ACA0731E6DD2E88F1CB -:10B7D000E8CEEC0C4EF70E18AFFFA5E94FA5D90E39 -:10B7E000765B385437A80CFC8F6AE6EF8623075047 -:10B7F000FFA44FB90DFD942D4DA97316005F65F997 -:10B80000BC800E0D1EB04F62F989332CB68BFAEF57 -:10B81000F1F47043C50AF47B1B3A62CF7FA285F92D -:10B82000DB61AA27BDD9F1C7CFB7303B3AC9C2F90E -:10B830006EEAA134FD7AA6ADABDA3A3B582241510B -:10B84000B71EDECAF1675E3789546F1BC9F81CFD4D -:10B85000C786052C0EB161A205E32B1A9FD37A6926 -:10B8600080573A0FB4E7281F86C09E7B8CD4A3DC98 -:10B870000469FBCDA42FDC7712CB65CD6F029F5FEF -:10B88000EF78DCBFBE8BEBAB7539F7DBA12B3A5EF3 -:10B890001AF047C0CDF464A58BD9B1053BE5C80FBC -:10B8A000281C954D02DA59967D7684F3DC265AA63B -:10B8B0005D475C0AD63FEBB1613960ED78F47BB44B -:10B8C000DCB35324684766392CC0AF2738BF923C9D -:10B8D0005A067BD8CE8A954DFBEF82FE4A5BADC4FB -:10B8E0004EFBAFDC5D72E3F768B9A45D2650A5722C -:10B8F000F33265102D2F0A096128774FA60B15E04A -:10B9000025590981DFDEEDEE48FD119DF7E91A1B8F -:10B91000512928B5AE8ED45B293ECA42DBA741BB74 -:10B92000B2660134229DC7E64303615E5B052FF8D2 -:10B93000F7E55B120CF6E0093A951FD0EF4BE83CB7 -:10B94000412E4B48FD3458E72A37AF53545DFCE194 -:10B95000748D07C7D1CA955BE938B45DD54B8217A2 -:10B96000A65865217ED043E776DB673FE784F92D53 -:10B970005346BA605E0F2B50AF2454F48A5D05F82D -:10B980009A9469F47B59639302F1AD8095DC0D7E46 -:10B990006EF9967E46B81A4494D72549B68DA0CF45 -:10B9A00089D39776F3A8BE743E5D4375ECC868B939 -:10B9B0000CF421F2614899A5AB3F444C427E2DDF47 -:10B9C000221AED6CBEFE078F32FA07F7BA30EEA7E7 -:10B9D000D16F09F79735FA2D49E2F4947AF263C1F1 -:10B9E000F328D083C2530FF8A2CF351C3EF7443260 -:10B9F00009E22E6E1FF10831F8DAFCAC974911B05C -:10BA0000EE3F2D9F35491A88EEC362883C7956CCAB -:10BA1000993485967F6F29DC6C41FDE155418E3468 -:10BA20003FFB590B93CBBA810AE2AF7E6AFE732CBF -:10BA30003E4170DDAB9F5AFC3CD805B4FD360BCAC5 -:10BA4000216D3F2A7E7BCFB47186F69E69A55AFB95 -:10BA50009DD8DE76F1F6F5D32618C79F56A6B5DF3A -:10BA60008BF03B2F0EBFE7BA89C6F1AFABC0F60132 -:10BA70002BA3574F920DED9A1576AF4F6276540473 -:10BA8000DE4BC92337423D51E307D2E103FBDBD94B -:10BA90009C346635D1F3C5E437000E1795163D5F2B -:10BAA000248E7318F831C9976C28D39E3C27BEC3E7 -:10BAB000CB3088DB86F0288314D4179306D910DEA8 -:10BAC000FBF7D9B17CFF0406EFFD839C2867B8B66D -:10BAD000503ADEAFF8AFD1DBADB0324128E94DD1FD -:10BAE000FF11E037FA5EB5C07B8748AA513F5B097A -:10BAF000EAA38733F39F0BEAF0B37230A52F2D9F93 -:10BB000005FBA77F14AF0F0F2E4E2BD28D53375846 -:10BB100099BD319BBD9FEF84F10ABB010F01A56761 -:10BB200024D895E671AC43C719C6B16594E238DFF5 -:10BB300098C6B166949AC6B1CDDEC8DFF371FE0235 -:10BB4000F38A37CEC3432718E7935186E35845D38A -:10BB50007C32CA4CE338D87CE87B3E8E5DBCD87C16 -:10BB6000864D34CE6748058E93222A86B89575484F -:10BB700085691C278E03EF611C92CEFC1BC5DA532E -:10BB80008CF47FCD4EC09E56ACFE17A05FF2473BB3 -:10BB9000417DA2D27107805E49C6FD827FB524E354 -:10BBA0007CBE7450FA3BF5740E6A7601DA3B0B39B1 -:10BBB00088245487FE7915E7D105CDB33296C1B3F9 -:10BBC000B520AD08FCECF52E2FC44FCFB51628F3E9 -:10BBD00063D8050BEBE5139D06FEE57A6F32C9AA23 -:10BBE000063F8BDB015AF904D55F84EAAD8FA8FECE -:10BBF00082E74999EA69FAFE38D56F44D1C3BB0C94 -:10BC0000DB9D90181E4F34B275E4CB7547658CF3FD -:10BC100005C93B59741EB7F1692CAC4F60BE028751 -:10BC200023C0E9D1B3DB1ADA88F4F05D01760F693D -:10BC3000E84771C5EB0D057C517149C6E215601FDF -:10BC4000FD78E5F6DF40B57785A2C14BE87C67B7A4 -:10BC5000AC93AFA0E57372E75D5EA7AE9FD9F247E4 -:10BC6000306F1BFD0FFA99E3A765DDF877941ACBC7 -:10BC70007712295AA6749B2A0EE5F4E0E3AA21194B -:10BC8000E8755B2A83E74E788E81CF1EA4D75D1EB0 -:10BC9000D6568327F0A04C22B81E75F667C66D7F76 -:10BCA000ACE7D7D615137C77C9365F21A5E75D0FC2 -:10BCB00088884733BC9DFB127C16EA5775367C2674 -:10BCC000837F7929F8EF5E6AFC4E826C3C0DAF1AD7 -:10BCD0001FDC3E7B52BFE3BA7A73FCD7F73BAEE37F -:10BCE000973B4A6719CA7756CF31D4BF7B6991E138 -:10BCF0007B517091E1FBFC958B0DE585F50F18EA02 -:10BD000097342C337C5F145A65F85EBE659DA15C48 -:10BD1000197ED2503FD0DA64F86ED977D54D208F96 -:10BD2000B5BF1709D8675F384F3C0AF6D5174E09DB -:10BD3000FDAA2AE0352A87A76AD290BF4FD7A8F874 -:10BD40003CD79A8BFB6301079567BAD66FA83DBCB9 -:10BD50006CE544D023B43ED5E14FD7BEB52C487D29 -:10BD6000F78D10A4A67C2F362824D20FFC98E45E11 -:10BD7000BEEE1175DF3B2FF1BD812E58B97DBF8B13 -:10BD80009DB1DF770B3D23C1BE0B7E60C5FD9B7867 -:10BD9000F603FDBB82C4F01FB46717C437747AE79B -:10BDA0003591D9D5D788935F13E9B34261F25EB17B -:10BDB00063E064881754289191D531ECECDEF1C230 -:10BDC000149801D00F939745A12BA2F28BF41B6618 -:10BDD00090FB1B2CFE7DA09FBBF68B6C7F207230EE -:10BDE00003F669AE117DAFC17BD2DA1FD7C7776B7F -:10BDF0007CFD8E0F27E4FD9AE9F8FC434D613F88F6 -:10BE00001FFDA96636963FACF1E3B3B3A6149F1F9E -:10BE1000D554E3F7E3354BB17CA22688CF53352BBD -:10BE2000F179BAA61EBF77D53460F95C4D089F9AA8 -:10BE30001C68F62849E1F61FB7D7E9CA81E5F37C0B -:10BE40000E22FD7707CAB5370DE4FABCF3CB91603B -:10BE5000E79E7FDF8A41F4787832F35B7CFAF970F1 -:10BE6000BD2F0E51FAE7F6FD6E7730FAD82D643A01 -:10BE7000F867AB462804E2EA8ED7BE83F6327D2F00 -:10BE800011D49721AF7E1FB1B77F98F3804BD34970 -:10BE9000AB7FE2A97FCF9F970DF461F4751C14ABC3 -:10BEA00019DD9EF302DD74F86376D94EAECF4D787E -:10BEB00094B8DC99F179B6BF86CF8E0C88B7548AD6 -:10BEC000851689BE3BDF62C5799D6F4B60FBD89EAE -:10BED00094CB8AE7956FB17BF4FAA1329CE431EA06 -:10BEE0008B811EBDBE38DFFE9C1BE47E499AC57364 -:10BEF0003C17F8C3C7F983F19DD67F6538D3E33487 -:10BF0000F4632C9FAF17A6B37D4535F1D618FE819B -:10BF1000F65C92A6788E53BD707ACBB0441897FA2F -:10BF2000711E18A7ABC6E361E3A679F47C59B1D4BE -:10BF300081F535F8E2F5FBF7860F76FC3EB6B15891 -:10BF400013C469E2D58F4B0FE97305FC03D2267F3A -:10BF500009EB8E234B5B77242C6BFD06C262D07AF3 -:10BF60000DBC6F368C47DBA99A0F0DEDE2D35D2235 -:10BF700027347A523D791DCF0FA1CC8C74F6D31E95 -:10BF800013697FDD927325C479332515F55D0006AD -:10BF9000A2FC5469EB54FC2AA2BB03E39EE334B930 -:10BFA000576FFF2365B94FFE59C67806F90BED9D13 -:10BFB0007E97F9D705A4D00D4EC6BC96F299A0275E -:10BFC0003FB168F6407D3ECCFB2CB1E07EFE59F2DD -:10BFD000B63B576797954A3C3EB992ADCF41FA1FA1 -:10BFE000CC8FDA6986F5BAA4C1582E2637A7823CD1 -:10BFF00014AF9761C7962C82F55EB76F325BF2E0A3 -:10C00000BC4B48751DD829AB65B68F3ACF43A42BDE -:10C01000285C95BB9EC9077B3620317DAFF9CF8B5D -:10C020009219DC652921C547BF7FDC927BDBF708CD -:10C03000B40FD5815E0BBA8837563C66FE4A237C26 -:10C040009782DF0C2F21CB0D7068FD6A70885B84AE -:10C0500098791A3F93041ED761F2B15632DAAF8F46 -:10C06000733C68E50DA672A3A9BEC62732E7934CC0 -:10C07000C9FF38E89F4A5BCF34B4D308E58FEC683A -:10C080003D255A6FC3C5EA59A19E88F51AA5B1F19D -:10C09000EBD9A3FD35C5EAAF72D7B65782949FCAD4 -:10C0A0005E7EC20D41DF4FA4FA54887F556C7EC876 -:10C0B0000D783A2505DD40EF4F4262CCB8E07BBDFC -:10C0C000F8F23905F02390B529DE5F7CE446D0D73D -:10C0D0005F6E96312F26B0C51AB1523EAE6A593402 -:10C0E00013E2F7B47C8C951FFE14F60D03AD467A6F -:10C0F00096BDF0442AC489282699BD4D22687754FC -:10C100006DFAF334D0E301D2837C686E07E35F48B5 -:10C1100046B92F5212FB7ED7F215025CCE022D8F4C -:10C120007C0A79090113FF94F6AE279D0AC411DA3F -:10C1300025570AFAE5DF25DF053DA0E18384983D18 -:10C1400051BB75C3E863149EAE4DFFEC160C7E37F1 -:10C15000E3C3F3E1F9BF7A558DAF67CE717F28DA7B -:10C160002E84EDD45666FF9036F6AC90236EB03731 -:10C170002B9A642FE55052B1EDB9E79F023FED03D2 -:10C180002BFA69E5DB7EF3EE045A2EDF2EA7CC6492 -:10C19000D3710AA951BA04E8FF968E89D2A1ECD7CF -:10C1A000BF51D451ECFD4F93A3F428DFBE5F21A310 -:10C1B000FAE2AF20BC5FE974C6A04BF8D834B057A0 -:10C1C0006AB77EA580DFF5C93E810CC8ECDBBEB442 -:10C1D000E937B81E029E908E9C4EBD74EB43AFC8EB -:10C1E0008DAFE6613D0FE8C978F47A91EBE5CA5D61 -:10C1F0002E9204F1CF3F584333818E2FDDE38679B1 -:10C200009C94AA195F3FF3502AECFF95CAC1540FC2 -:10C210003ED9FBD267EF437E2B11AA53D93EA66FBE -:10C22000208F970F84F92D6CFC11CEAF98F891EF09 -:10C230004A9F110B213EFC8544A66F8F211737C8FA -:10C240006CFFE9E4462B24F9919360E7837DFDB60A -:10C250008871564216E33ED87D5A1C972CC1F217BE -:10C260007C5F6AB86CD1FC439B815F373DDC01F495 -:10C27000393DD83700E0A47808727C09B0DF2F1E62 -:10C280009D3A80D187E51B603BAAFF0BE03DD4EFD0 -:10C2900090719F50D78EEB4B36FEBD7C7C0AB70366 -:10C2A000D6B393A96CBFD23CBFA57C7EF4AF83E824 -:10C2B000F84B27DF4CDE37AD62F2ADC97B68D67430 -:10C2C000F8FEF93B4C7EA01DAC1F14AEC800FCBEAE -:10C2D000FF5601F581954462C9F52699CBB5F17BEE -:10C2E00080CA29C40528DC12E43344F984F69F8C03 -:10C2F000F847BFA4783D6DA7B3CF02301ED653A236 -:10C30000EF75EB4709D703D365A3FC93C6FE97658A -:10C310002F56C82408A665C50756F4BB2BB6C98599 -:10C3200030EF33CD07DFFD31E5EB33614D4E8DFA54 -:10C33000D32CA7A53B360BC09F66393D534A57EB1C -:10C3400058724ADFC794D3D2CEFF2BFA53C35BC0D7 -:10C350008437AA07872459E2E3CFAC075DB21A53AA -:10C360000FD2BF77487E5FBED3F84DE3336AA10D8D -:10C3700001FDDDCB8F1ABFF5F2A3C66FE6791AF186 -:10C3800066FE3E010C350A57E16E19FD928A36B6FB -:10C390007F43DB1DBA220FF1E3C3E58BD41FBA2222 -:10C3A000455F0E99CA61537D9FA95C68AAEF3795D6 -:10C3B000AB0DF52B5A0F2A2CC92862A8675DFA1419 -:10C3C000F938867DAFAD3381964F9520F0437A8F53 -:10C3D000027A4E5E4E4D33889FED15D1DFEA567BD3 -:10C3E000DCC9F4FD4376E6C7767B783989957BFA1C -:10C3F0002B75A0E7B4F73D7616E7EC2EEC7127E934 -:10C40000FCFB636DA21BF6833B432C1FB52F3CB591 -:10C4100028379D24DE7716179C2A3A339682FF56DA -:10C420002F7AC1355CB0EC7637ECBB75B70DBB69C4 -:10C43000367DBFF0B008E633E976B847035C24E800 -:10C440009306E6F3FC09FA778A047F3911F226DABB -:10C45000987DBD608DC91E76DEAB607ED97A5D5C4D -:10C460004BC7FF65BC9FD246E3F732B206F9AFCCAB -:10C47000240F7EEE0F1CD5E42187E4B0FD6DC2FCD5 -:10C4800058AE77A78AD937CDA678EF6E17316FF6F9 -:10C490007C9B48EA609ECD02EE7392607F94AB2A4B -:10C4A000D283FA4EC34B17C88D125F1F75EDFCD7B0 -:10C4B000FC07813F5EF9E3E8A7E9B3EB950F46EE91 -:10C4C00081F2AEF732FE48FAD62FD8F735EE237652 -:10C4D000EFB3629CAB7BDF6F331E84F2AB568C7381 -:10C4E000752FB7E23E4A709F2B3402BE0F66FE40A6 -:10C4F000EDDEAF46B33CC91548A7BFC8CC1F39DF36 -:10C50000F6EF1F42FEC8F9363A2BB00BF625A0DC39 -:10C51000045EB5A3FFDDBDF7AB7CBFF3EF379F2A09 -:10C5200085F891FF5C64F60EE0D724160F0EEC1927 -:10C53000FF1CE43757B6EC5720CE5EF0DA5F478336 -:10C540009EECDEC1EC9D7372E7B3B01F66553E5D95 -:10C550002E533C9F03E11944C873CA988260762C1D -:10C56000BC303C74533CC0BC285E4A41BFC7C34783 -:10C5700086F28F8A8F4FEF627AECBB98671FC58B6C -:10C58000E063EF5D219B80F367EFF77D351AF4CC14 -:10C5900099F032B4472E35EF6B15B6CFF23F67DE18 -:10C5A00042E472E63DF71F96DE8CFF3F82F5B57FD1 -:10C5B0005F39E8CBE7BBEEC7F24B2E2FC27B99F277 -:10C5C000FFD3FF6974DF41E9EEBE34DD9FFE879D36 -:10C5D000F7A5E87E98D3DDE581FDE5EEBD7FC5B822 -:10C5E000A936FF4BCDFBD5FF47E7ADD9EB332CD5B3 -:10C5F0004766D1FA4748647D2185F3F5F4A9EFCC6D -:10C60000A25F7F1BC71E39ADB0F8C76F09CB130CF3 -:10C61000A6092CCF83FB450584ADEB05592568673A -:10C6200014643D82F60191AA8FE4507CCCC858E88E -:10C6300065F96063F01CCA7503AFF5623CD0E41F76 -:10C64000165C7D7D3BF829079751F8E83807078B82 -:10C650001E6A299129E972C43A1A9FC7E079C83D38 -:10C660001DEB4D711AFDA399E0DFE8FCBDEB55E32E -:10C67000F769BCFFE9E4400AE4934CF7CA2404F5E7 -:10C6800048FD0AFD3EF234533F87C0AFD5C5CBFE0F -:10C69000A3F84BB7323FF2B764C9911CC05FBA8CA4 -:10C6A000F1C04BE28FB0FCAFEB06E6E079142279E3 -:10C6B000117F330655727C32BF59E2ED25675D0765 -:10C6C000C8AD44A8DFCBEC32F49735BFF7527826DB -:10C6D000DC9F96F8D01ADEA57419F35675FD225E1C -:10C6E000347AFC47E9A0D1EF3F4B8F73267AA47FC1 -:10C6F000EE91403E0BB8FD3FE5F30E11CBE95E092C -:10C70000F7A3B8FD3FC9992481FD7FAD745404B9E6 -:10C710002CB1B5CE8038BDCD2B205F5FD96541FFF0 -:10C72000C6962720DEB31A242C1FB578C682A17DB9 -:10C73000E3F7769D7980407CD8A7A0E14D0A597C2B -:10C74000FE2FDF7E3B513BAF81DF09B981FA5F0BE2 -:10C750001A49C441E7B75022C1C46488EF0AE423F0 -:10C76000437CD75886BFEFA746FBB954FD787AE4DF -:10C77000EFFDDC45F5D647942976C313F755282BF2 -:10C78000E8FCE3EFB6317C058E90D050D40B3EB17F -:10C7900050B76FF68895E98F5D7FDA910B71B149DB -:10C7A000DDD9894C9F0E47BF20C0FD82F3444D84E4 -:10C7B000FC83F36DC312715FB05D74F963C465B639 -:10C7C00072FFF99F209F823EBB37917A3887D14D07 -:10C7D0007A301E1BDC648BB9BF7BBF558B3771BAB7 -:10C7E000D13F513B6FA462BE4830514FB7AE999FC5 -:10C7F00048A3FBD201FE3ED2ED97FC57F10BFE3A67 -:10C80000E077ABBD735AACF3602B39FE6E3CF0356C -:10C81000C631AF6E6BB200FF5EBDC962D86F0C5AF5 -:10C82000B9DF35868C01B86E3C6077E5015DDA458D -:10C830002FE40F06DA3E55FC31F6ADCCF884FE212C -:10C840002EBECFCAE2FC7BE4F07CC0EB9EB336CCBC -:10C85000CFD9ADD497C782F34A3BD3730B49F89E27 -:10C86000D199FF78F89DD4ED8C4C063F7313E1719C -:10C870000C33FF11E4E3F35B089E0F05BF14F4C211 -:10C88000F966760E98A2642DF8D354DE7FA08FCB84 -:10C890005CD9BAFD9FC00EA86A133C903A5B25751F -:10C8A0002A106F0DB42689B0EEE6A85A5EA567D4AB -:10C8B000AD3AB9D86765F9C60727ECB903C6FDAC30 -:10C8C0004B21608FF85EEF71C3BAFD595B6E62ACAD -:10C8D000BC79EDF9EB1A32638A04FD10C4BB991FD1 -:10C8E000B29B1D86F2F744FF2090AF1BAD9DF77AF7 -:10C8F00063D0CF6F637C76D9FA2DF4FF997E7B47A6 -:10C90000D36F7EB150274759B63EFA6D402CFDB625 -:10C9100044500700DE97EC1D3600E8BAE4B0DC3F77 -:10C92000967EDB56C3F6F35EE6F9B0DD2D54BF5DAF -:10C93000A3D36F2D36CC8B33B74BB659F8BA7809E1 -:10C94000FD16FAEF91BF6DA0DF62CC77848DE90D03 -:10C950004DBF8D6E3B86FA6D748BC590379A6EBB5A -:10C96000947E13FADF0AF670BBEC4D88C13FDBB84A -:10C97000FDFD32CFC3837140CFDD6163FB9B97AB7D -:10C98000E7B2ED8CDE97D473FF4D78D6F4DC929D40 -:10C99000DA3947331F323DB76437D57302F023D3FA -:10C9A000734BF6B27B1CCCFA2DAB8F7E2358BF2A7B -:10C9B000C2DA075A3337CCA5FD8DF1C95E1BAD3FF6 -:10C9C00026AAEFC6EAF5DD1D3676EF421F7DD77E3B -:10C9D00079FA6E27D777548F0D05FD6AE60F6F9BA6 -:10C9E00031EF78CFF893CDBF06797943C47DC3A3E7 -:10C9F000FC5CDA9BE34FE6017F35DB98FEADE5FC9E -:10CA000077AE2688FD17BCCEE657E964F9C8552DE8 -:10CA1000CC3EAC6A16422AFDE7B4095F2B00FFA2A8 -:10CA2000BD021940CBB3ACAC3E7941DBF722337386 -:10CA300074FCB0605C39C6ED1748C40671F972E742 -:10CA4000B44F201E5F3E8EC5F1CBF9FB45873BEB13 -:10CA5000209EBDE84901F73D09CF07D0F21B4BDA14 -:10CA60009661BCD69C17A0E9F34521E3FB72533EC7 -:10CA700063139FE72CB113F142DE1263E62534996C -:10CA8000F1D1CEF1B149C475B3171F143F6A665F87 -:10CA90007C508ACECC498DCE7FD11B745E79D17902 -:10CAA00069F830CF4F8B3B97F376F1E6ABE1AFCF30 -:10CAB0007C357C9AE6FD1CE80D5008392417F2629B -:10CAC000281FA0DE08FE4EC4F3FB8593460CD0EB76 -:10CAD000E1AD5C9FE7D64F2A1848005FA41AF8A67C -:10CAE000B861F1A18174DE63DF57C7C0F2F8BD09F8 -:10CAF000563FEC8F6EB5F7A05ED3F8EA1BCE57EF2A -:10CB0000723CEE19548DE75403AD8207EC8A40C4A1 -:10CB10008EF80B50FCC1F995003FBF18A0FC05F240 -:10CB200074F0C92F19BEF60A2AC4C7A769EB0FE033 -:10CB30009FD6CF6D63F80F8404C47F1EE9C1FD91B9 -:10CB4000AA06C11BA1F5AB5A1763DE83A66FE99F46 -:10CB5000534F0F1D3F4AB1F8112BE9D6BF725EEF5C -:10CB6000466BFDBBC09F37BE2093261D7F66D1FF5D -:10CB7000BE8D41270D9F97E2CB0B1C4FDB008F4EE4 -:10CB8000C0570FB39F225FE3391AED7B400A1AF0BA -:10CB900058F0D4858BE269AC8627E053D0536D45BD -:10CBA00022948B5B05D22FB3EF3C617F522FB78B62 -:10CBB000F61E63FD3F23E0BD2566BED5E6DD876F2B -:10CBC000E3F02B9C4B03BFE872F9F61B13DFBE6941 -:10CBD000EF39920B7CBB5760F183B624C3FEE22091 -:10CBE0003B5BFFB7DA297FC3BED661D9BB51ED2BC2 -:10CBF000DF097CFD02BB5F7F2EE92A9808E43D6EC9 -:10CC0000B1611E19C23194D9957ABDBACD4EFADF01 -:10CC10009A17BFFF81BCFF78768D561E05E341BE93 -:10CC2000572B1D2F2B3A9E59AF6B7EFEA5E635F292 -:10CC3000BF38AFDE3C4CD281FB4E9992FF31AB2E18 -:10CC40000FEE369E67442140FB4A572FDB76917AE0 -:10CC500024CD83E79FEEF1687CC6F2DD0B791EFBE5 -:10CC60005471E27BB07E7EE663FB7C7916F2FB8931 -:10CC7000A09F27CB788EEFB32332C66B3F9BC2F2C7 -:10CC8000386F7AE3A004F1999B4039517CDC34562B -:10CC9000407F058E61C1BED92E6ADFF846E27C7204 -:10CCA000E11C57CEA6FA02387F3C664BA8169EDEE2 -:10CCB000829E9437018F93440278ECF0F52B80FB31 -:10CCC00093EEF933C1FB43E83A8BEDC7B493FE50C2 -:10CCD0006F82AF3FBA03E35BD617407C74D641A79F -:10CCE00013EE67C96AB4509F218ABF0924540B719F -:10CCF0009BF1C77DB700BCA5D45E80B873695B5358 -:10CD0000AD1BCA8D8257A5FD0782FE696E3A8F6DF5 -:10CD10000D9F4EFB0EC823AD07DD041A59BDC0267A -:10CD2000B87808DEAFC33C9BE24D021EFCDA161257 -:10CD3000888DF51BB2D17EB735D2F679B04ED0F6DC -:10CD4000D0EFA64FDFB905E4FD88C8DA37B37DEA36 -:10CD500062DA4E05BEDDB418FB5BD4289034DA5F8E -:10CD600069335B074A8FC85EF8DEB2FF495CC7666D -:10CD7000D2F1066682DE8F4C8132C9153C18EFACC9 -:10CD8000188974EBE6724E268E60FA43E065EE3742 -:10CD90006876D3BB7696EF5BEC5DA6F4A3FDBC3959 -:10CDA000AE7F26A405045A3FC5FDE7E314CF7EDA23 -:10CDB000E5519EB77170DCC74AA76E1DFACCCEEE66 -:10CDC000B75AD03A09F319169242CC67B8713CB3FE -:10CDD000D7DEBAD61E822B0EDE927BD2E1FDC16B6E -:10CDE000AD68FF9EDB26231F9D1BDC89F1E9938D37 -:10CDF000329E1BAE6D64F7739D6C66EBB8F80CDB6E -:10CE0000D72F7129583ED878CB3458DF4E6E62E761 -:10CE10001D0B9E99AA40B9A449F0B2FB8B987ED411 -:10CE2000FCB7620FCB47D0F45F259F779FBC45933B -:10CE3000BEABD4D61B93BEAB847D65373C8DEF0370 -:10CE4000C4C9F420D8FD40F7C8D7C8BF554764020D -:10CE500076BFF071D734CCC7DA2B603C7F7C9BE087 -:10CE6000837DFDD2F7AD21B457434577FF04F4F835 -:10CE7000075622A890D74EF14EF5C3386BCF9F7E50 -:10CE800041DF7F72D4069930944F8A10CF5AFE67E3 -:10CE9000DE6696C79277747D2A9CB72453FAA1BEAA -:10CEA0002D6910895FA7373E117CB7FC98E965BCF6 -:10CEB0009F42A35F9E525F0CEBD83007D34BEA66CC -:10CEC000197244C8611E27A1F6349EBF5DB47B5D14 -:10CED000AA42EBD5F1FC8F457BD7A58AF47D2DAC1A -:10CEE0005FB4FE2285F5BF689FE069D2F5AFB5D784 -:10CEF000FAD3FA51761BFB19B697972FB31F0D0E75 -:10CF00006DFC78F6F8B87FB9B01EEE8B19F79688ED -:10CF100049C7E33E9E394CBFDFA13DB5F86BFE3BF0 -:10CF200016E2D3E16DDC9F1CC4A7E38B96B154BE1F -:10CF300029DD6E681542004ACBD8634A651E963DCE -:10CF400020CF553C4E5B3585ED5BB5E41C5D01F2B1 -:10CF50003D334F403E2041BFD22F05ED2015F6173F -:10CF60004AF258FB12DA1EE4AEE5492687541FA8A0 -:10CF7000A02FAA1AD74DC3FA9B0415FA6F692AC2CB -:10CF8000F5BE749C48F0FBA663687F94B61E4B0107 -:10CF900079A5F2B91ED6DFAA8956BCCF4B933B4D7B -:10CFA0008EDF92F97D4D36CF28C8EB7F10808A2125 -:10CFB000BFE211C2FCD46619E52C308EC9E55BDBFB -:10CFC0004494E783D7DE8E72786EB310478E0B14CD -:10CFD00038977C32C4BEF7CAF15681CB31D30F27C4 -:10CFE0009D4CAE0BE03BC8F14E81FB83CC1E34CB95 -:10CFF000B126979792DFF22D26798E23B71D52E73F -:10D00000AD30EE3DD7DA11EE82EFEF7EF71ED43F62 -:10D0100032E67D147CFF8154D077C512CB57D2F015 -:10D020005829B17CB63E70AC5FA60CBC2C788C70D5 -:10D030003C6D7745F587087CCEEEE10A6E9291CF84 -:10D04000CD72F85F959FBF973C1FE6FCA3C123EE0E -:10D0500065ED217F2C42F1F4DBE6E7304FF5EC8BF8 -:10D06000C76E043C97EFA17C4BE77BAED9C5EF7B45 -:10D0700009E13A53D622621E389122F9B7B8F47208 -:10D08000C9F290CA5F76217F94ED60F9A465AF7C08 -:10D090003C1AF34496F7607E55F0456E6F063B47A9 -:10D0A000035F97492C1FCA2CE7B73A98FDD9B53BC7 -:10D0B0006136CC43D8C2CEE997856F97810FB57A98 -:10D0C0003F74C85A3DDCBF0C52BE85FD75804F7F52 -:10D0D000EE5CCB83EADACAE4BEAC55467FA96C4B62 -:10D0E00013C6B1035B3EC53CF78297B761FC20D005 -:10D0F0002A1AF31EB788B87F459FB84F65CE3FAC5C -:10D100006AA9C4FDB6AA30CFEF33E5BF95BFBCF71F -:10D110009520454DF9AF5F70831E38DDB1D90DF80C -:10D12000A4FD61DEE0F73F970C7951F1F37B7DC6FA -:10D130007CC2F0AA98F984A7E11F94C11F70707E89 -:10D14000D5F230B7F4E379DA91FCC218F1FBDE7363 -:10D150003BDBBE7816F2DCBB769C7916E0AEF8DBE2 -:10D1600067CF423E13D967C77529F0E2EF314F58B8 -:10D170006BF70B07F7F3B7BE80F9D5E73EB0A29F78 -:10D18000736EEFC90CC85F3BB7FDEB5488C7DDBBBE -:10D19000772AC62BEFDD593080C4D0EFDA13F8328E -:10D1A0007419F9DD663A1C6C3988795767DFB7A2C4 -:10D1B0003EEBCD0B0D57B23C5B95E78336C7CEA354 -:10D1C000D7F218AB5A6EB9E95AD0CF2DCC9EEBCD21 -:10D1D0006BBC541EE83B949ED75C06DD9A799EAFEB -:10D1E000896E67E11F943E6113DDBE6859F8ABA7F5 -:10D1F000E05B4BBFB879A091CBC09796A7FF738730 -:10D200006F8F03CEFDED4808A6317A85660A60EF80 -:10D210007D9101E71A4EC93D98EFD1B3D7EA817CE1 -:10D22000C6B2BDEFA17C9CDB7914E3AA84E7C99F59 -:10D2300023BD7F2CAF59E0F3DBE462F9A31CEF9030 -:10D240005FAABAF13DCF23657CABE597C6CB2BED4A -:10D25000710C6571687E6EA092FA49FCDEACDE7CD2 -:10D2600053611CD0E998214F579BB7B93F0FD79B0B -:10D27000D1FCE8D879BB5ABE60944E6C1DD1F29FA8 -:10D28000CF35F1BC69FA3E7D0CE4C1B1F53A10121C -:10D29000DE2331E451CB8F3EE330E545872E2F2F3F -:10D2A000FA52F0FE67F1F1A183C5AB35BC74FD25E0 -:10D2B000B63E561298DD49FD533901F705987F7A3D -:10D2C00037F74F357C69F0D68599DDD0B585F907FC -:10D2D0006679AE8A735F520A1FA7AA75FF68D03BB2 -:10D2E0005D0776737E63FC5CD57C8CE5DD52FD1CAE -:10D2F000D2EB677EBF84B9BF0CDE5FA02D767F8145 -:10D30000E64F63F6775AF2DD0EF09FEE6076D2E9D3 -:10D31000B0383DD6FD36B604D9903F50E762F76588 -:10D32000886E07DA47F7BAC6BD9F98024F05F37AB1 -:10D330006A97F13CA09F79F15ED15AD70C02F03C7C -:10D3400004F8D1C519648F9F809D26A715E6896AC8 -:10D3500014DE5E7AA45848484F7F29920EFAFCC327 -:10D360009C9332F4F76FA6F8C8BF49A46E0085EB12 -:10D37000DF828277991ADFAED6CAFE9F8A86784608 -:10D3800095B5E743B0CFC96B76DC0F17F7D9831893 -:10D390001F7B96DDAB7170E757CFE3BD3CBFB21288 -:10D3A0006E170AA00F4A789CE2E4CEAF9EFD77B0DC -:10D3B00023A1311DBFE4595A1FECE7E604B4F7BBC3 -:10D3C00077248E863840C96B0FDE08FAA204741FDA -:10D3D000D8992F0F08D5D2FE4EF467E513DB06E38C -:10D3E000B980F21D2ECC273CB8735715E8FB732F7C -:10D3F0002710D0F767E5CEBF4139B0279134A9682F -:10D40000F7A9FA7575119154BD3D570E65437E0B12 -:10D41000C1FC168CBF517E2E6F4DC4F31FBA7A5CCF -:10D420009E8383F83D518340EEA8DDA81AF39ED970 -:10D43000F705094C7F05AC3DF7B3FB1058FD80D2D2 -:10D4400053CCCAF58398DC7660FDC51ABFF2EF7D38 -:10D45000FB65F503092C1E10ED87B5AFB2B2FB35A5 -:10D46000CCF4FD6982C0CFE3FEF5CA58F74FC48003 -:10D470009FDDCB259020DCBF4AB6DB314FAB428924 -:10D480008C847CF55714B6FF51E18E8C847CF53D7D -:10D490005CFF55386899BE1FC4E180FA5026B6CEAD -:10D4A00097F05EA75D76BC0FAFF235970FFD8457FE -:10D4B000BE3AF1741EE4AB25609E74E56BFF0BE988 -:10D4C0005F698DDC05FCDFB3DD8AF793766D3F9CE9 -:10D4D000017643971CC948BEC8BE4E65D86AD8A716 -:10D4E000D6E671BA66E90438C7AB9D332C8BA32FFF -:10D4F000DE4860791D4D09BE5F313D67BC5FE67453 -:10D50000CD6CC3BD8965B6D87AAC19F4822E8E274E -:10D5100046CF153643BF674967DD204A924AA107C7 -:10D52000F7C7CBB664A683BF7BC07E25EE5B1D909C -:10D5300055F407E1A9D7C7A76ABCB9129EA7CFCAFD -:10D5400095281CDD4D9F160F22901F689F1D4B3F95 -:10D55000ED4D48407E2AB359639EDFFC1DE7B76D51 -:10D56000206F63D978DEECE8B807E49002704C7461 -:10D57000AA389F32EA07B07BA2E6E4EACF6D2F9289 -:10D58000EAB11E952FC4C722B25EC973F6D52B8BA4 -:10D5900096E6E54AB9A8B0BEE9E537314A27124C0C -:10D5A000413B49E23424EB071AF2FD25B9D006F8D5 -:10D5B0005248A1471281D4F528A70E12C6A7939A04 -:10D5C000216C1DAA26101F3FC5F767AD92FA18DE21 -:10D5D00037D32EA23EBF14DEDE4B7023DC56A99A51 -:10D5E00078D1DE98E9017B4C08FAC9B7941F6A6BC1 -:10D5F000A6E7B273E1C407796E6EC2E0737B0E7D5D -:10D600000DF601E533768FD5F749A8968E07C78CBE -:10D6100031FE3799DD676F1EEF2F9C0E24B8DF7047 -:10D62000DF39FCF568F7E781BF9EF8B771B01FE3FB -:10D63000F49008D84B094E1249180DF7E449A7F5A4 -:10D64000F2EB26AC3C94B233E835CF44E377335F5A -:10D6500013AFF479AF5E14B1FDE7A6F69F5FACBDE2 -:10D66000868F806DA3F7786E142F0E3E87E064EFEF -:10D67000854EC0C768B7B716E8A8F47CF820E06309 -:10D68000B493F983290D44EFAFE53A99BE5AC1EF3F -:10D690009FA67F854E5D7FC463C3F8E82A8EF7DEC0 -:10D6A000FA5ADCA44F7DBB0478ED53DF1EAFBE23D6 -:10D6B000767D573C781262C39314A7FF60ECFA554D -:10D6C000AFBDF7664485974C6F40709E9F5BCE75EB -:10D6D000827F95F8616A11E30AB61F60A29B03F886 -:10D6E0008FF28363B8EE3DFC5FB68E7E4363D09FBE -:10D6F0004490EF8A383CB4EC1C48E1FB310777CA10 -:10D7000026B65F39F75E1627FAB18DE5971EE3F767 -:10D7100001CD6D607EF5DCA56C1F9194B2733E1E49 -:10D72000FA1F8C77277442E97D67BD108A64C2BDF9 -:10D730003526FBB5F77E9C450AD42F32C55D347E75 -:10D74000D2CE23CDE7F67526E7CF85A4C705726F45 -:10D750003EF7FE3AD76B9ADE0FAE2359706E5FB478 -:10D7600038BCB03F2AF273A6C4CDEEF323BEC1ECA1 -:10D770007E392D8F2B4B4D84F58D84F97BBECFB236 -:10D78000E47A7580FE9C9674C181F783D4CADE3436 -:10D79000D083F2056AD751574DB93094A8BA736453 -:10D7A000D49E43E1963DECBE44C953484AC00EE4C2 -:10D7B000F703909419BD76D75B140F4BD6A9786EFA -:10D7C00075A193D999BF7015DEE31C0BF6E5382FD0 -:10D7D000BBE7D648C7E04E36BF5A985F665FB86B66 -:10D7E00015AF17EDCE19D462C0388E177FDF41B464 -:10D7F000AAEFA9208FFF2CB3DF2BE8830746BFF3E6 -:10D8000029C9782FFB02F7EA0F814FD7F0FB0857A1 -:10D81000D664E173754D1ADA9D75355E7C6A78B110 -:10D8200079EBF1DE37DB70D69FCDE3677605B56522 -:10D83000209F42F25447A06C4BAF2660EFDA7BF199 -:10D84000538FF8517ACB7E2C5B3DEC7723E486999D -:10D850008867DA9E94D0EF4B5CFEA7404EECEAD589 -:10D86000867BE4AC69634CF70D9AF0A6F1C7368667 -:10D87000BFB502E30F33FED6CA1D2AEC2BAFBDBEE7 -:10D88000F7DE19C41F35EF19FE7EC7F6D9E2E2CFE5 -:10D89000938CF6EB82FCBABB204FFA11BEBFF87036 -:10D8A000CD38C4D72A7E8FE443353E7C8A803F3A08 -:10D8B0003F6B7690C0FDE8ECB721E8D359E883FBD5 -:10D8C000678177017FA293E1D39A568DFB6B362750 -:10D8D000C397E80C225E6427C397E864FCA6F0B205 -:10D8E00004F8CBC5F6F89EE2EF00F0972D7D82019B -:10D8F0005F4ACAE4CBC3DF93147F148E142E5F6695 -:10D900003CA428EC7E4A4DAEE2D9714FD0F9C3BA9F -:10D91000BDA186E0B37F1C7F71A88BAD9B2996EAE1 -:10D92000FD32E02399F0F52448D2F3094B3D84BF42 -:10D93000B42051A12C303848FD60C3BD92A24732BB -:10D94000DDCBA66E003E587F58B640BEBCB874868C -:10D95000E13CA838DB97A4223EFD784FF323352A1B -:10D96000D26F1DD011EE01E5FED7439C9E0FF37BD5 -:10D97000285771F958CBE5E5312E27B5FCDEE435A3 -:10D98000D3599E554A8E85DF571621FA3CA6246F3F -:10D990009828142EB4A9557CE23D8BE47D6B680475 -:10D9A0006D97904D7CC02749EF3F1062F735160EFA -:10D9B000043B2849BB7F71A29A34070FC24624E674 -:10D9C000775055887E4C8725D63D55B5DE03368881 -:10D9D00087C68327C1EBCB7C888E97D0E042FBBD06 -:10D9E0009FBF70CE425A76362460FC2F81FF3E8B5B -:10D9F00093C25DA2A377BC7BA837BAAE4F74517AAD -:10DA00007A0046FA7CBC6118FE2ECB137221FE8E82 -:10DA1000CB137C3DD5EE39D7DA7DC3F5A33BEF6A56 -:10DA200083DFBA5EF6613BCF44A3FCAFE7FA3679F9 -:10DA30008A91CF357D7BBC57DFFA87023CA917A6B8 -:10DA4000A01E4BB939B6DEAD9515BCB7BC761493A4 -:10DA5000F36091C2CEB5F4D50318A73EEF1FB911FC -:10DA6000F4A8C657CB09D33B41E2F0E23AC4EFB782 -:10DA7000D1ECE095700F20D7AFF01487B3DF1F48CB -:10DA80009DCBEEF35DC3EFB17A94F215C17B4FBD30 -:10DA9000F89CE162FB13CB6D63F03EB55AA705F528 -:10DAA00084F48135042687B47FBC07E20592ECED4F -:10DAB000F041BCCF2585E1DEDC5A671EDEFB2E245B -:10DAC000E57980FE5FBA160CB9583E1D9D28DE9799 -:10DAD000E94929241F65E36E009E5F913D37138855 -:10DAE0001B6E48A9B603DEC6BB585CBFA1281FF158 -:10DAF00048F17B93AB7FB49F01B367F4DE8305DD10 -:10DB00006E88730EE60E17B397487A900CD7C979D2 -:10DB100083F63B276A9064E9E47DF9886904F68717 -:10DB2000FACA791C3DB699E9B115426C3DA6D9995E -:10DB30009A1E934DFA417BD60D996E38A7A5A4780D -:10DB40008177E119B478C1BE7BA5EE8E24C443353C -:10DB5000E081A4CDE8F55F7F3014ECC7FC98FC664B -:10DB6000D65F0B7AD7735F2AD0E994AC0E9803FC8A -:10DB70007438F67A3EE9F1AB1E033E58F03B51D0C3 -:10DB8000EFA7945C5889EB69F18571F82C6D988E3C -:10DB90007C4F200AAEF3C34E36DEE706B84E36F0B1 -:10DBA0003C80463904F919271BEEC3FB4A20CF5BA2 -:10DBB000D4EDEF933C15ED4BED9EB193A17BDCFAD8 -:10DBC000FDDDE25FD87D60B7C6E3AFE2C6D87E3D3B -:10DBD0009E35828D3CE2CD027B98DA373D11B07FD5 -:10DBE000365ABD41122D071FB7C7CC4F5CE29AFAD7 -:10DBF00004E07D89CBF70CC83971B27B41E3F3397E -:10DC00001BF7046C02C37ED3533C4F53F2BBF5F7B2 -:10DC1000BBF5DEC7C9E324C416E7BB43FB7D8338ED -:10DC2000DFDD2C9F8378627FD7FC8484A89FD00A95 -:10DC3000F3A86C3853F701E289FB091CEE533283D9 -:10DC4000FBD4F356F63B3726BE38C5F34716090C0E -:10DC5000AF1A7F9FEAB577FC780F8D99FF848D57B7 -:10DC60006D184FFBFDAC5DC6385C05E51FE01B6120 -:10DC7000E378CC5F171E1FFF18E4257D7E44C4EFB8 -:10DC800065176CF8BDEB67DE0D7321CEF3868CF75C -:10DC9000757FDE3E3591C5798C71E8856EB6CE9F75 -:10DCA000E6725F7C6135F2672F7FD42F5440AE8AD5 -:10DCB0002F3C8AF64CF11601EF8924C19E43932430 -:10DCC000CE8713A0FDD969CB01DF13EB717FA3646D -:10DCD000B3D5BB5AE84BE7D32ED570AF7A49E71AD4 -:10DCE000EC97507B2A45B7DF7D8AE701975C60F7A8 -:10DCF00003124F90A401DF73BD13E55FE3BDAF5D79 -:10DD0000F6D871F66FB83D537C6182C16F88CEEF53 -:10DD1000FB4C3EF97A5ED2398EC1D53B9F0DE36351 -:10DD2000CD273A8F89D8BE2B29F6F8991CCF276AC0 -:10DD30004AE1E406295558BDE2FAFB14D027C58D07 -:10DD400049C9826E5E250DE5863C8C92C622659E91 -:10DD5000AEDF281D1CBF9D343C4A87CC47E5EB96BF -:10DD60003B61BD2F74B961BC8D8BF27FA2427F4CA9 -:10DD7000FF7C22D76754A37EB9C71DEB5C43A65B2B -:10DD800035C4954A1A387DA89D9CA7A38F46177362 -:10DD9000FB134D25F93F8178F293EC5690F87AC742 -:10DDA00044B7CCD8789BD08BB72CCC07BA34DEBE26 -:10DDB00063C8FBE983374E5F0D2FDA7B6A1FE502EC -:10DDC000BE2640C0A93FF4C3E87F297C45C7E5F4DF -:10DDD0009F147B1EFEDE792C25416A3F2CB8E43C63 -:10DDE0001E2441DB45E6A1D19F5C6DA0BFFFD11190 -:10DDF000D7811C6AF45E70E049E4DF05541E615F60 -:10DE0000FE64FD7D86F5210A5F1CBA0F0F92ECFCC3 -:10DE1000FF7374FF440E6640DE57701D5B474E6D06 -:10DE20007C24438FE725AE490B812E6453FFCB5AE8 -:10DE30003F8293BDED2AAE4B32C6C376BBFC0137A1 -:10DE40007D5FCAFDEA1549D346C65AF7A95F381166 -:10DE5000E2CFB535D32742BC4DE67623FCB216D8C7 -:10DE60009B70057AACFBB5EA395D1FAAA9C6F835E7 -:10DE7000B10589477FDE9730BBE81BC2E22D5A3BD4 -:10DE800045F67B20FEA908A410ED39C9BF32330F37 -:10DE9000E2182939411DFE1E7533BB6E4DDA010FA4 -:10DEA000E4935A69FF108FB1A54BE78DFB94AC9CAE -:10DEB000238C97613E724A98603C339BBED7E15BEE -:10DEC00049A1705EC4DF946C6EDC2F9208B3D3B4AA -:10DED000F9D337B89E3DCCD7A5E510C74D013BCC53 -:10DEE00082FED07A1EA7FC654D21C78384EB98354E -:10DEF00089D5571219DC76885B8BB0AE46B0EC82C0 -:10DF00001B7644BC9A0C7F7F3489A8F83B7DFD4882 -:10DF1000A40EEF3199D4793FBCF725F8B7001F7CE8 -:10DF200039B0E34301E2D085FE2B61FD6D108339EA -:10DF30002AADFF2BB12707EAC1EF7BBD9FCC9E43E3 -:10DF4000206FD9AFDB9762F772AAFAB89EB93C642A -:10DF5000A964DAAFF9CB95FAEF4D09BE5D0047CA67 -:10DF6000C702EEC3D4DAD9BD3EB5AEDB1261FD3EC9 -:10DF7000CAE985F407FE696776CC79494D4CC6F845 -:10DF80006656EEEB86F1BD86B2C4FDB74D941F25F3 -:10DF9000DDBDACC3259F05F865443D7DAFA75F8C13 -:10DFA000B85AB213AFBF8DB90FA3C147C725803F81 -:10DFB000F1C234B6BE9AF8608FC0E00FBAB8BF4560 -:10DFC0008222D0738E765FB0B48295B5DF8B002A43 -:10DFD00052383ED0F617C80A56E6FB9481796C1F7A -:10DFE000D20CCF9CB6873B20AE3FA76DE07CD89F7C -:10DFF0009AE31CF96778EE917B0E24801D789F8050 -:10E00000E73F7EFCFBD7E504FADCF9CE463C6F7CAB -:10E0100096CBDD5DA407EF61F7130FDF270FE1FB60 -:10E0200079F00373580ECBE0A7CF8D847E74032D57 -:10E03000DDF97AE80630DBEE6AEFF90DA8017FD84A -:10E04000330DF700B476ADDE43ACCCDA45F160E3D6 -:10E05000F6A80DE7159DB70DF1F0416FDE7810E9D8 -:10E06000D18B277EAF928697DE7927DE3603E2BC1E -:10E07000F1F4D91C67D69FD9E60783CB8CA7CFE1F3 -:10E0800013B5233F77FBEC8954BF7DECF639E0599B -:10E0900061EBC99086A2BCB8A15C25FA87A4523C6A -:10E0A0009C1DECBFB23FE0A3A3DF65E9D10FED4CAF -:10E0B0000F90BC0C9C8F76EFFBC1074EBAC0EEAC44 -:10E0C000DBF95E063C2BC5CEB5B7637C53447FE8D5 -:10E0D0007CCB95173D1FF621C49DE8FA372251E30A -:10E0E0004336BFBBF9F99ABB5B12F07CCDDD4B45E3 -:10E0F000C3BDCD772F65797744EA187DABC15E5FEC -:10E1000011B71F880398FB99BF7432F9B81FECB39D -:10E110007A26615CE059C65FF3A7F844C8479EB011 -:10E1200052C078CBF8E36A6B272DCF0F25E1EF1DA6 -:10E13000CD7F60492EDC4350D5C1E27B03C4C53995 -:10E140003F83F8C901B68E437931C8B7D3A73A7572 -:10E15000F1FE2EB93A07EEDD0BDEE9F401FF14DD26 -:10E16000EAFB007F2F91C721B47575574311E6B1C3 -:10E1700016CD55C701DD8BC276FCFDC1221B911C5B -:10E18000548F1549C406CF010A91ECF074101B3C62 -:10E19000F397B37BB28B1B66A17DE01E57A8C0FD31 -:10E1A000B7456D2F7C01ED4BA4C87E76AE85E1A707 -:10E1B000A8EDF0D7C03F0B7D859877F89D2D8AC1DB -:10E1C000FF1B153696AF6935967322C6726EBBB1CA -:10E1D000BC15EE38D3D91107F65A719D283FC3CE2E -:10E1E000E9BD2AC0DA04F1602BCA5341795B3EECE9 -:10E1F000479F79C96581EF7BFECAFCDE9EAD76BC88 -:10E20000EF6DFF1F1CC40179852FDB37C2F7338EFA -:10E21000703EC4E1687DF63B5B85E191E0BFBD7275 -:10E22000B5E6A78746C3BC5EF91BCB93E9D96AC59F -:10E23000DF4F39B3FB8597605FECCCD62BD0CE7A1D -:10E2400055085AA0DFE02A467F339F966F31FAC502 -:10E25000F727327DD32D307C5FD9609CF755216341 -:10E26000F9E789CC9F9A4774EF3361FF5EAD4B832A -:10E2700075F5B9D8F70D3FC4E5E2C517158D6F45A3 -:10E280007E3F1B5175E797F644F7EFEEBD02F22A89 -:10E29000001743A3EFCB4DE36AFD1726B27DF814B8 -:10E2A000BE3FD3F38688F8396DFADDC25EBBAEA6F9 -:10E2B0007AE014DD3A54DCB03FB508FCA3C6FDA9F2 -:10E2C000F374EB4BC5D683A977605E9284BFCB54C1 -:10E2D00031E7F94727A4C07B310CF0C277887B7502 -:10E2E000857FE3867AD4DE1D23EAF05ED270DFC03C -:10E2F000293A39FD8FF2A5264F15DC3ED935AE639C -:10E300001AE4899737B0DF6F2A0FFFE816F8FD454A -:10E31000D2C8CE99E64BA450A4F253B1FD473F8436 -:10E32000DFE30A3C33D60BF0D02E6E85F7E5CD9FA8 -:10E33000E27982D5A6DF11D09EFB387D69FD888504 -:10E34000D65F7D9BB314F413EDF775281FC8DA88E8 -:10E35000F79BB84FB1382D7DFF3EFC24CAA9C9C137 -:10E3600037EFA04DCF90F0BB3764C2BC8D7C46F92F -:10E370005600BBAB67B380BF6B4B2DADFC9BC1A4FC -:10E38000F62DC3BC5BFAFDEE58E79D17858CFD9812 -:10E39000E9FF07CEBFF42F4BCF47E67AFD6606F1C3 -:10E3A0005C62C552AAEF74767EC5F17ABCCFD13CCF -:10E3B0000E06E174F906B05EAA28DF76EDFE21C1F3 -:10E3C00096CFF36687B132DE5B08FC4A19A5FC6A7A -:10E3D0003245057CDF4CA6C3F35521F2A828323D17 -:10E3E0008171A06D09A827BA3C9DCF3F0DFCD53C9B -:10E3F0000AE34F83F879CF2E3582F73C76F3F86441 -:10E40000978795CBDAEC980773E6AC827A7459F863 -:10E41000A01BE8D1F592DD02BF4B7A667BBFC990A5 -:10E4200027D91566F7FF9E0EF7C3DF7F8DB76E996C -:10E43000F581B64E1E837FC27A9AE8FB06D65BB2A0 -:10E4400082E5910EE8579D13EBF724B476294A75BF -:10E450000EF829FF1B63EBB5D4008000000000001C -:10E460001F8B080000000000000BDD7D0B7854D5E9 -:10E47000B5F03E73CEBC92996466324926218F096D -:10E48000841020E024860814EB24040C187542D173 -:10E49000A2B638804080BC44DB46A55F26244242B9 -:10E4A00051428D08087140B1F48A6DB0A8C106EFE1 -:10E4B00080F86AB537DADE5EB5FDB92370295A1ED9 -:10E4C00023F452DBDBD67FADB5F799993349AABD6A -:10E4D000F7B6FFF7FDE9478FFBECC7597BADB5D722 -:10E4E0005A7BADB5F744BE6EF1EC2D60F0172850A5 -:10E4F0009C8C5DF2BB3C9BA0BC4482573318333AE2 -:10E500007C465B3A63D672C6BCF0CFF186BC5786B8 -:10E51000FA53B2E79BB6718CDDC57C0686CF72BF1D -:10E52000818D853E9DD0388BB1650A0B290E782EE2 -:10E53000F4BE2F4DA53263D07FD92E29D801FDEF2F -:10E54000DA6C64CCC4E8EF33F8B7A217CAC5B1F2ED -:10E550002A16343019FE63575C3B187F95123A2A0D -:10E56000A530B6DAC442C930EEEAA7B4FDD6B01081 -:10E57000C1D370E03363FCF8303FC600B4FF64EAF7 -:10E58000BCBC6EDB34C69C0628C3BC236FEB8388FF -:10E5900087FF907D34AF35CC4FE3DCDE5AC54EA506 -:10E5A00031D67C5F6BD65DF0BCD87A7FD65D5743A1 -:10E5B0003DC201DFB730DE9FC1BCF601CED654B3F9 -:10E5C000502EC0B71CE69B5406E541293405CB26E6 -:10E5D000164829E3EF53CBF87CBD71F0D5B31EFA92 -:10E5E0005EFD2EED7BF68B34C267031BA27AF654D8 -:10E5F0005C3DE0A341E0A1E100BC8FC3C3CC03526A -:10E60000C07A1596821D19005FD359C63641A9E913 -:10E61000D06746CDF8AC8731C04366126366A0D799 -:10E62000A3125BD45F42FD26D64D8136F8771D9646 -:10E63000DBA9DD0981BF476F5991E587765BEC5017 -:10E64000CE16089E0EDFD0E1C7A91C32C17792AE6C -:10E650008E96A9BE623D2FD7D98A6BB6E730B64DEC -:10E66000EFCFB2011297C9BED77480BF271DFE5BE2 -:10E6700090DF96E9BC790ACE97798B7C00076BE531 -:10E680007878ACAC65624B490CAE187C9CBEDBA4C0 -:10E69000FE900EF82C7058F2EC7323DF46F47E4B9C -:10E6A000AC5DB34DA279A41E0BBF3606E9FEBCC417 -:10E6B000F642BB1DD287AF8D817E3BE6B9590794E8 -:10E6C0005D4027B90CDFB34E09F0527EA8EEEE573D -:10E6D00091CEE5499EF1F0683C5429375A68FE779F -:10E6E000FA009ECCE4963D3AA8CFBCB3B80CF91B17 -:10E6F000E67DE702787FAFCD4DDFCBB270BABBD6F7 -:10E70000070AD696E0F77D77BF0ADF8B4C49F2E027 -:10E71000F733015756073DBBCCD88EB54BD8EED159 -:10E72000143E7EBA4EBEB30ECB65BCEC582779F7CB -:10E7300012F36DA579671A590DC289EF8325B46468 -:10E74000BC07A93EC8E93BBBA514C7CB1CC79F4E5D -:10E75000432807C7794BA5F760968E6520BCF0DF8C -:10E7600000CFBD072B331DD0FFAD732645970A4F51 -:10E77000176343D84E0959183E0B8B797B93685F1A -:10E780003A3B131783334FDBEEA2DE9B7A35E0254D -:10E79000F08ECC901EBFB37853EDD0EE4B063E8F7B -:10E7A000443AF6217D603ECD9F02E46971745B744A -:10E7B000C580E3357FAAB0E0D5B1F7E7DA4C2C5835 -:10E7C000142B37D41F9B8BED1AD9D006E4ABC6FEB1 -:10E7D00064168CE3F72F258DFC5D95BF9B3FD5B16B -:10E7E000401AB16F8ECF8AF8896C588EF01F91D87D -:10E7F0003E86F5061688FB7EF3A70E6D390A67067E -:10E800008D136BC7B4ED067E4FEDD8F4700A7EE72A -:10E81000822D9CE210F3C37ED9326B41BA5C0CEAC4 -:10E82000027A58C717DCBCFE226335FD96587B750B -:10E83000BC0B8B0C2C44788FD0B8889700C8B69D41 -:10E84000839F18DC506E183C4A7851F9211E3F8195 -:10E8500038B991D13114D2C19AFE856D55578919B5 -:10E8600048714C5DBF6BBABCB3A05ED669D67372FB -:10E8700079747D93587954270B79D0D0553D2BBEB0 -:10E88000CCDBC7FA37D654C3FA2F2FE1FD4FD89A05 -:10E89000DE58AFC4E411CC230FF1122D9B12CA161F -:10E8A000284F892BDB12EA9D09F5AE84720E6F7F2B -:10E8B000CE1ACA933D8C7D645B5BA3807C3997152F -:10E8C0005A2C417973C7BD35D520E71ACB87BC32A6 -:10E8D000CACF41C923B118FE9A3CCC1B04FC593C59 -:10E8E00061C3B212C4C3D06BB8FE1B06249B047C68 -:10E8F0006EE93F18A232F673C7F5EB97A85F43FFA6 -:10E9000087D46FD4F18B75B48E37159FA4768000B1 -:10E91000DB69A0D35799C45201A5058AFF8FA8BF10 -:10E920001AFB7FC3F52E8B18F8FCB81CBC90E57D54 -:10E9300085E4E011C986EB2ECA7738AE25C6EF6AAA -:10E94000FB5F4D19FC571C26F9DE4FDA1568FF7F77 -:10E950001A7F338D01A97E854D66A05C0D4E447DE6 -:10E96000BC93F927A21EFA7AE3F8A33A6877421F0C -:10E97000DECD005FC5F64D350AB43B610DE74A2098 -:10E9800043266DEDE5E5F4F06EC46760EBA384DF2C -:10E9900013B9E15C1D94A7DA43BC3C3EBC1BCBB76A -:10E9A0006E7D8697A7847365E83F3670A0A61ACA65 -:10E9B000FB6C23AFD77C3B97E32A7C97C779B3EDF9 -:10E9C000E9C8765C4FECD603C6401E2E5EFDF1B35F -:10E9D000FB000F8BEF4F2639B5EFDC57E6FB68FEE7 -:10E9E000019F5201F290B33ED763248F15B203B258 -:10E9F00050773962F4B0E60DB949CE4F6A3988FADA -:10EA00003E737109C9F94F53BDEDF669B1E7271996 -:10EA1000F00438DAED362E97659D97DA3F6025BB16 -:10EA2000678B99CF07D60DD1D722E8512EE6536ECA -:10EA3000D7D133CF3687C6FB40F2EE30C9F8640138 -:10EA400033D2735512D91977EC01B90072B957C096 -:10EA5000DDBB75623000E3DF21311FCA8D5EBB373D -:10EA60000BE5C30B7F91EFC4F9F69642199E3F1652 -:10EA7000F2BEB7CE9B658FD38BBD7B78BD2A777AEC -:10EA80000B787F55DF6476F0EF646E99B817E791E5 -:10EA9000AC302F96972F2ADADB4E7A7B01CD9B790B -:10EAA000BD5912CCF7F4AAB13AB42355FAA4157A99 -:10EAB0006FC2F9DC8EE35B627452BFDF8EF346BD3A -:10EAC0002F83DE87F93EE0F0D3FCC10E984A76A092 -:10EAD000B003DA71BED362F8654A781ABEFFFF0848 -:10EAE0004FF760FDFF144F23C88B00B66B6C0579A0 -:10EAF000A18B9317027FDBA4903E93CB0B0FEA39D7 -:10EB00007CBF00E4E3ED36FF468447FDFEE2071AD2 -:10EB1000C9EE53E14AFED68B355F65C3D759A25D76 -:10EB200076E203D366067AEC84A19FE4E289F9CC0D -:10EB3000D38EF243C7EA118FAA5D5971FF9AB718B5 -:10EB4000D8B397ED32D1B95BF266E1BCBA81AE269B -:10EB5000D4C37586E0BE82985EECB50777AC40BA48 -:10EB6000DE52E209B8493FD27A0BB42653BB5E7B32 -:10EB70009829583FC36D034890CE448FC86D86E0F6 -:10EB80005E09E9CDF9A577D5A4604022BA07A8FFB0 -:10EB90006D9C7F7AEB18D9F7BDB7B9886FCC2C681C -:10EBA000467846E3838C0E467CC414EFD43A6B0C53 -:10EBB0000F3F13EB3AB93CFCFCBFA11DB9D94C7611 -:10EBC00024EA4CDC77B19E4C8217E8F902F187BA4F -:10EBD0005F7A242BB889F6679E0AA4C746AB7709EB -:10EBE000C1FFED6437C2BFCBCCBA4C65B8FD609DA8 -:10EBF00024EF043CACE73186F6D99DC23EFBF7FA20 -:10EC00004B56B4035EB573FB0A19C504F26F29E3D2 -:10EC1000F54BD7257F88FB99A5EBE49011F62BAC3B -:10EC20006B8E371CB7CF208E82F1FC425EB2ED11A5 -:10EC30002BF28D1FFBA5E0F87FB4BA2D5886FE534A -:10EC400091ECD0BF38D6FF3DB16E17CB1C7ED69667 -:10EC5000EC46FC26CAF5F754F87A1EF3C67F4FFD42 -:10EC60004EE2B8B08F7B1FF105780FA5A23DFF6D76 -:10EC700099E89A08AFD31079C80CF58BDB64FB7A5E -:10EC8000C0A7BFD54AF355E1BD3333722DEDAF12A6 -:10EC9000C63F93DC54A1E0FCC5FE83ADD3EEBF18A4 -:10ECA00033C4CAC017CB5984F631C3DE8B7D6BE207 -:10ECB000BE8FB1BF18E3DBA9EB85B9A504F8055FEA -:10ECC000B92505E9E69738DDA2F44E805BC5A7ECCF -:10ECD00018199F4E433817E595BFD5487848ECAFD3 -:10ECE000EABDC7CCB03E80AFB64B12F1E3F6FB9263 -:10ECF000498F3113A763F3EA2437F2E74E43E469FF -:10ED00005A372F1919D2F5A239F202C9A342EE37A8 -:10ED1000B8F833790FB6BB90CEF9FAC2613DAD2792 -:10ED20000E0CD83B3F93F752BDC4C7BDD09EECC676 -:10ED3000F5D88C9884EF3707FEAB8D01FE4EE9F8CD -:10ED40003EB87940BBDFBD00FFEACB6272E122E34F -:10ED5000DF090C703900335D45DFB923896D82719D -:10ED60009B749217EDA3A6D593821D9C5F4CB85E51 -:10ED70001A04484D3AD8F795C5D67793EE6411EE4C -:10ED80009B1A4C9B87E414AA3F8EFB2D86FB25E83B -:10ED9000B71A3B150CE7E7A6CDBFFD33C2DD7448BB -:10EDA0004BF786187F489F49D83F8E5F0A627C40A8 -:10EDB000F635CA876A161C2F713F0C96936B8682B4 -:10EDC000E8876916FE89F463E1B9C81FD6F27EB6FA -:10EDD000149ECD67B97D317370CF2BB8CFB5D70CEA -:10EDE000E5E2349B5BD75E7DFAEA187D5538670C07 -:10EDF0006E9571FFA6DA2571FBC7890BA6C43FD7B4 -:10EE0000533FDC8FE2F7C2F80AD785C2F5D936A1A5 -:10EE1000CF40EF91DC5DDE3381F41EEA25945FEA9A -:10EE20007E16E519CA8F271D558B1C30CF92B4AAC8 -:10EE3000AF38A6F1EF901D8F9BA019C3F199A85789 -:10EE4000D476B8AF6DB18CDE2EEAE7D991CAE583EE -:10EE5000225179C54FF57B36117C0AF1CBDADD05FD -:10EE6000246F557F4C83F043AD10FE9B15C27FB3DA -:10EE700072BB91B9E3FD55416DB941ACF74616E659 -:10EE80007EACFD501FEFB7A966212BD6A3FF069FCE -:10EE9000FDDAFECD2C385B41FA0E7C668C7FCF7A92 -:10EEA000F97CEF1474DF61E67E9B99EBF6C8DC1900 -:10EEB000C5E79B5AE62D7810F5C49B7AF22FFC87A4 -:10EEC000A0938A17A3A3EAEB88EF24DC8F61BB072A -:10EED0008D8497D3A08F0F0ABFC602DC67B6F9B343 -:10EEE0000A0B113DB6BC05D6E1F8DDF492B91EF966 -:10EEF00065B343A7E1A72A879ECAE4EF41BCB727C1 -:10EF0000935D0D689E8A7C543156D5936C2AFA998C -:10EF10003ED483BD05E5A65B2D7E1C2F8C76019427 -:10EF20007708F9B5C361A0F1D472741F27F805BE44 -:10EF300043E3A1DFC517C707C168FBADC25EE4723A -:10EF400061DBAA24924731BED531E2DB129F01FD7D -:10EF5000452F0939F2122094F651FD662E47142EE2 -:10EF60009F5E3A3B89E4DE1B1FAF26B972695112DE -:10EF7000334AD4DE2B61FDF3C6E07A28DF25FCA8F6 -:10EF80002F49DC0E0C1CB1D2380D06FF0EF42B34C9 -:10EF90003C37DE0314632F1882DF7F1AEB5F369352 -:10EFA000DFAA2185C3D9F0D21892933FD6079FF9E3 -:10EFB00001F9218C649F3524B953A9FE27690CEB14 -:10EFC000BB92FD8348CF6C23B71B1B0CA1223BE0F7 -:10EFD000F16490DBBF2751D0E0F88356B26B00CCD0 -:10EFE0002CFCFEA9EE4CCF26770C2FA71E9A4CFCCA -:10EFF000BF4DCFE91638CCFD9A27F5BEB959503E22 -:10F00000F97CA907768EECA2CF1032008CCD5BB8CC -:10F01000BDB64CE7EE6B45D9F472B247B3DF7C78EE -:10F02000652DD637AF5E7713CAC1D1D633CAF37810 -:10F030007FED0516C9A3FD66FDD8FE107CF7C2E082 -:10F04000440FA947E60262039FD878DBD37AC03722 -:10F05000F2D7113DF1EF171D1FE78BFB3FD42FF8BF -:10F060009D6690BF513F32C9DFB8B23C5299D3B3CD -:10F07000F9A54C619F69EBEF48F55F40B9D6F4DD27 -:10F08000DF9F6825FC4648FEB11EEE1F3FADF72E00 -:10F09000463EB557870C4BE3F6B78634BE8E9619BD -:10F0A000855E672143FCBA53EB2BAAB47CAE3EF5D8 -:10F0B000697C1F691DE2727C78BD4EAC9BAF185114 -:10F0C0006F71D70DECA7CF727F8621CD4DF533CF71 -:10F0D000860CCBA09CBF2E6458219EB82E00DF2149 -:10F0E00013CCFBF40E2B5FCF80061C67C57446F66D -:10F0F000C80A19ECD0327CEF1E08035DCE3C6FE7E6 -:10F10000FCF527C00AE07B0913ED8C60B782DC7A3E -:10F11000B1530AA15DBF64BB71AFB900D7B157B697 -:10F12000223D774B24B796745616ED80F2EA43538E -:10F1300088FE29D3395FAE0EDA49FFCD147270997B -:10F140003168203BFA19EEA783F1C91E6E804E5933 -:10F1500065C3F180F25BC30F416D9C6166BF90A7F0 -:10F16000FBE3E20B63E3E47A7F427FB0E3B4FC119C -:10F1700050F50E9773CC9D89724E95C34687AF3478 -:10F180008DE4526126D217E8C9E5E44189F0DAC876 -:10F190005AB8DE10F23EFA5DA12FCEC801AE978CB0 -:10F1A0005BE93937AD80E8B61AF50DF9CDF9FE6E99 -:10F1B000343E989BA6137271643EB85EF041C35909 -:10F1C00016BA16BED7B08E851AA7F2A7752AE941DE -:10F1D000AE0F4D229E61E2F18ECFD38B897A70986B -:10F1E000DE4BD0779906A1DF049DE3FDD9A8EF6738 -:10F1F000AE0BCAE8D7CCB379AFCD4C8FD92FCDEFBA -:10F20000994CEEABB0EC63632DE89FA97CC685FEFC -:10F210005DD88FE3BA4A06BCEC81F7BB55FBD6C577 -:10F22000E7EB3270FED52B3E566A41BA0CD17E35E3 -:10F2300092CE6CC88F2A3E775BA15F19F6E3EB2D67 -:10F24000DADFC43A93E2FA57BD6426B97AE5B035FD -:10F250006824BBC39F6F87F1327E65243BF4C24BA9 -:10F2600056D29F1784FE73AAFB7EB681E8D38A74B8 -:10F270004D476EAA1A83FE5326CD1F832250B5C375 -:10F280001AEDA3F9B3457DC1D0AD9CAF8CB45FBC82 -:10F29000620F7F13CB000F43FBBA05E98CFEF643E8 -:10F2A000B34B1F80F7CD3E8B8763DF5F8AFC6A9488 -:10F2B000EFBD15FD2A73E57591FB601E8DB9169B98 -:10F2C00011BA54E7FFFA97B741F9A3437A66443A73 -:10F2D000EF9BBD888D1D5DFEAE0AEA4F86E3D6CB5F -:10F2E0009AFDDA7263BFB6DCCC9493E13879FC58AE -:10F2F0009AD5796632C90ECF67C0DF4663CBD93D58 -:10F3000000AFF1C746D2470D69FE5D69E837D545C4 -:10F310005E433C1BF3CF4D453F4555FE9F28AE73E2 -:10F32000E5DBCC83705F315792FEBEB2C3EC0EC4F6 -:10F33000C9AF66C1FFBD79B554DFBBD3E896787D10 -:10F34000EDB40AB407E9DBF867D201FE9BB7CFFB47 -:10F3500088F64D68B543B917ED4BECF79C146C4734 -:10F36000FB713BD77BE7C17E34A1FE14EBA9591E8C -:10F370009C6B82FFEC75D44C44F9A2FC59F121FD41 -:10F3800037E25071F6EEE1E8FAE47E9C1BD08F3351 -:10F390008EFC3887516E349AC2864A18E7BA3FFF0E -:10F3A0008EE4F2CAD6A564D7C7EC5C23C99195F761 -:10F3B000F9E9FD2B3BAEA7799D8179237ECEECE662 -:10F3C000FBB995399620C2779D9DDBBF2BA19F2469 -:10F3D0000DC74B221E7EB3EB7A17D2FB378C7F2FE3 -:10F3E000D0CFED84DFD8865248FEB85B52D0CE6BCA -:10F3F000DE7EFD4728B756EE963DA8C7D9112BF9FA -:10F400003D56EE9E3371B905C7B99C568978EB9B82 -:10F410006393E9BDEC0B72FFC9D075F05EE9BBC622 -:10F420008DEBE4F86E2387CF6E7A1AE1BFEECF3210 -:10F43000F1BDA2637EB4577B0DDE89B8DEDCBBF67E -:10F44000CD45BCFEA62E5B47ED9F95980DF1606FF4 -:10F45000CDC0F72B25C587EBAB7EFBAADA787BA462 -:10F46000334D267C57E6AFCB085B88DF6F453DD731 -:10F47000B85B4F76DDF1051FFCF236678CDF57CAAB -:10F480003DB7CE8CB3379A77DD28F8013436E06982 -:10F49000A5C093317F5D117EF7F3F87FE5FA9622E0 -:10F4A0001E8FF9EBEB20BABE77F1F5F007D0F7B479 -:10F4B0005FCF7168ECFBD1F641AABFD9E461DE7D74 -:10F4C000168A1B7A719F9BE754A83ECFC9ED6CE565 -:10F4D0000F6BF7BF0DF0F7A7F98D4E789FCFBCA546 -:10F4E000485777C45605E6244E89EC1FB6CBC8EDC5 -:10F4F0004985FBDDB6A5B3A737C5C1998DE3A5D373 -:10F50000FAB43961DC0BEFFFE935C45F53DEB9A90A -:10F510003C9EF63B8A4F590679DCD2E2F131E48B0E -:10F52000E6C13A7657494C1E367BB8BC4E9CD77222 -:10F5300027DF67343B23344E753A5F67AABF77678E -:10F540006B12F9F5763A8366BEBF0D3094E73795B6 -:10F55000CB3CDE22EC129FF09399BCAF308CC730CD -:10F560008FEC190FE521EFA9CE3428BF5D3EC723EC -:10F5700043D9E27DB26B2CCEDBA317F5E3C85FF86D -:10F58000D6AC4AB24F6EF2CAF45D569F42FBF521EB -:10F59000EFCF9D77C1776F66DEB4D3F08D1A50D66A -:10F5A00048C721FC36DA018ABFDC19E75FBDD133D9 -:10F5B0002FED74BCBEF472FD8FFBF17E113718097C -:10F5C0000F2569953311BFD77D99D3E1E367F9FE24 -:10F5D000E36333F763ABED3EB6723D53EB94841DAA -:10F5E000D89F87723E5AFE5AB1260EEC34F4E7E1FA -:10F5F0003AFBADA41D6775978EE2B3ABBA18C5632D -:10F600003FFEFE8B79286F3FDAF762DED238F812C0 -:10F61000FBA9CF5B9D5ABF94EA87748AB8F4528FD6 -:10F6200091FBFB46F143AAEDD976BE1FBB08D21D64 -:10F63000F94EED77B13EC98B76E545662279B67411 -:10F6400050F835BDDE4227EE1FD4FE09E36F41FEC0 -:10F6500001B8A40189F6E7C9251192AFAB4CBED71A -:10F66000C6B8312FC54BF499877494905FBD069C42 -:10F67000B722F67946C5D788F45CDEA3A56396D396 -:10F6800026E2944EA2BBA1C9A2A07EC8E810F2FA5D -:10F690001B3ADABF18B25D16944BD715257562DC9C -:10F6A000DD99943215FDE6B9D9C5D43E50C5F93A75 -:10F6B00090C1C86F95C55A2492B736EEE7CE99CE61 -:10F6C0006C98E7F1A293DB832EE6D92E933DD82FD9 -:10F6D00091BF5FCC5F95EBC82F28E73E964CC42FB7 -:10F6E000D2A044F69DACEB5F8CE38EC63FBD09FC17 -:10F6F000D3FB0FE69F3EF57BC3F8C74F71BAA52E2B -:10F70000D3C8FC23FCAA5FB8FD6871C26F98543F50 -:10F71000B384F3AD15E3D59A2C21792AC98773F107 -:10F72000FED45D6067E27E448D2B8EE958E2E6767A -:10F73000FA5018F7E5C9D79848CF7D47375480F677 -:10F740007C629C11286B47798F3286FC8AAD55BE4E -:10F75000D36971FAFE08DF3734DDE7A5F7B307B9DF -:10F760007E6F2E3490DDD93C200590CE4D3E43D0A7 -:10F770005440719525A4B71F32BB799CC4DD4E71EE -:10F78000926FBB791C25EA470DF73D80FC566F212F -:10F79000BF4362BCE585BFC8FCFBE3197DBFB794DE -:10F7A000C7777AE7B9C9AF911847635DDAF5ABC699 -:10F7B000512E5A0131F0BDA59BCD44876C99E39938 -:10F7C000A59AB87E192E07C85F9B315D1046C43BD1 -:10F7D000A2EB1A240396B345BD1A9FB196F80AD03E -:10F7E000C2BD3DEDB93793D2FF967C86D6EFFCD5EE -:10F7F0007C8680B116F3194C683D8B7A041BF4ADFE -:10F800005AF69ADD18BF89D52B60379A0624F1BDC8 -:10F81000E76F9853087890D4EFAFDFE4B550BC5849 -:10F82000F3BD78F89484F1F530BEC52DDA070ECC1F -:10F830009BA3505C52D47FD68DF91B5BF4DAF108A0 -:10F84000A5A23F16D4EF1DCF9CFB9DCD3931BD0F36 -:10F850007680297D5A4CFF6FFCA0B6E72AF856B295 -:10F86000EDB201F5AAAAC79B9D3CBF2171BD3AD25A -:10F87000F97A05FBD5914E7283DBB5B5223E09F6C8 -:10F88000EC5C5C5ACDEB7C0CE393602F64A4631EAC -:10F89000C3FBE7CE1C45FA2DF898ECF9E64F15EEC0 -:10F8A0007701BB03ED7393E07336A0277DABF2C104 -:10F8B0006A217F7AEDA0EF915F8F48D302C4172DA4 -:10F8C00079B7000DEE4FF7BA697CB1EF4A847746FD -:10F8D0003AF793341757ED28C2F19F9218EAFB4D7F -:10F8E000C52733D02E691EFC3063795CBF55038F6A -:10F8F000121E56EDD78F38FF19E9DCBE6C3AFC3C7E -:10F90000F9073F0E4AB496EB9560F74C28D7D7EB32 -:10F91000D04263E5C125B791BF7F91818D87F9E51D -:10F920000B7DD4BCFF2B8199B83F837F12BCDAE9F1 -:10F930005B417A6FE7229305E30ECDC54BEF263C82 -:10F94000D892BC88874DC55559F89DA6BAB9368A54 -:10F9500013807D85F54DF7DD4E7E1315AE4D03FA10 -:10F960001AB4BB2AC0CEFA11C09DEB985FE381F5B3 -:10F9700037463E587A8F05E3C223CBDF7FC9E0F4D8 -:10F98000EC947C819BCBC94FC8E2FD7EF903DC9EE1 -:10F99000AB4B3768FCC275E9DCCE9C15189A8DBC60 -:10F9A000F7B2124E46BBB799793FC1FD25F359DC3A -:10F9B000FB884E5C8E38DBDCE43F3239C3DFB90AAA -:10F9C000EB6729B47F604AF811FCEE856EA76713D8 -:10F9D00013FC8BE5FB4A822847FF39DDBF18F9ACE1 -:10F9E00042D88F170E5F5F8A7E36D53EEADE630E01 -:10F9F000621CB0DBEAFE6E0DCAC13F283CEE6D8A88 -:10FA00000CCD467AFCD141E3769B83DD48FFC0569E -:10FA10003DD51FB6FA5721DF9CADAB29A2BC1B4BCD -:10FA2000A008E3BC7A670F433B01B60BE44F3039C3 -:10FA30007D0CE3A1B3034B1409E57C82DD315BE46B -:10FA40008F92F084F755428C8D072E3863A225D013 -:10FA5000F9595ACC0E79E34F0B157CA9DA273A13E2 -:10FA60008F67552F4A6232F2FD86C86B3AF45F3BCE -:10FA700087C87E6DEC97E83B8DC5CF513ED81A9173 -:10FA80007714CDFF51C2940FB53E3D59E8F14ECEEB -:10FA9000EF6C88F6CBEC00A7276361CA938AED234D -:10FAA000DAA99D3A9E41F8DD1B85DF053418D53F64 -:10FAB00094AEDA07EBC553CDEBE2DFDD260D7965B9 -:10FAC000C46BA9A4F117ABCFA7D2B97D987A2C3219 -:10FAD00017D76FE4B09AA7C9F330774C9BE441D3B2 -:10FAE00069589EE6C02773916FC0D0A6F5DA34F04E -:10FAF000C5F234BF2FF60DFFEB799A1EC9BB179ED6 -:10FB00003F4AB773BF959AA7E9E1F853E36C89F9C7 -:10FB10009917B2420ACFB70AF7ED43FE1C30521EC6 -:10FB200057EDC0EBEFA17EAC35B17E8C4326DA19E0 -:10FB30006DB6AF0C22DF5F3C7FA6EF418679BA2F0E -:10FB400078285F23C17E48DC27ECC52659A3DB7BE0 -:10FB5000EF46E9C9EDBD68F97FDDDEE3F67C601FA5 -:10FB6000CF0F50E579B3D89F5DACBF94827AE6445D -:10FB7000149E843C86A7441EC3E0C8790C8AC8073B -:10FB8000027B3D407C7290C775DE783A99E4C725C8 -:10FB90009BB217EDA5F3D6C83711598AB0933A8FA7 -:10FBA00018DD282F40DE91FC0E1CD4F3380DC66DF5 -:10FBB000308EF3F24411C711F1A29792C96E6948D1 -:10FBC00071A7627F354EF363A16F1A92787CA62BE2 -:10FBD000D97F397D84B8CD1E617FED81A16C38DE7F -:10FBE0007B4611C7060181FB9D877279DC41C46D9C -:10FBF0002E8AB8CDA9625DC8C0FD10E4A77277292E -:10FC00002C0BEADDEF99836EEECF32E940EF2F53F4 -:10FC1000E3362F733FD532119F39B5602EE5072D9E -:10FC2000C7FC7719FD18DCCF1CCDC767361DCE6722 -:10FC30000D888B9D28620280F56BE0B5A493D09E61 -:10FC4000707742998C656F4F0D7C7769A78EF6238C -:10FC5000CBBAB4FEF22B9BEEAE41FDBDB193C71FF4 -:10FC6000035D12E9EF65CCEB427B43E587828C3480 -:10FC7000A273A053E7C5EFCCC8E0FE04407D90E638 -:10FC8000279E9D7AE1671770B4335D089F3A893FDC -:10FC900037DA949A11F5B218AF53DF62AA443B36B3 -:10FCA00057477EDE2B06EF22F2933A8A886E9DD666 -:10FCB00096AE1A5E4F6BE58A39E2A3FA6B156EE8D1 -:10FCC00031B703E564668688DF24CC77798FB69CEC -:10FCD000187F5815D4969731FF842C3C87B05FFB72 -:10FCE0003E3383CBA92B9B0A849FDF437EFE4EBD10 -:10FCF000FBDD029453DD0AC9C9F61C8E2F5D2E7FF1 -:10FD00008EB5572F22FBC00E7605C1CBE11F7BAD10 -:10FD100053427DD969E77CF93F853B11DECA8C22CD -:10FD20006E27A07187EBA85B0A727C71B8BFA8BF71 -:10FD3000626986F01708F9132DFFEFEF37393F7628 -:10FD4000CB62BDD948FE2C15F1C65392E7E910BE2F -:10FD5000B7805D00702FEB96CBD03E99FD150BCD93 -:10FD6000A3E96573D008F58DEBC279B88E9AAAC263 -:10FD7000452D23E015A15554B905ED963A617F80D4 -:10FD8000EBB64B1B871A1E57F47E2B231DF721A7BA -:10FD90000EBE8EF43E6826BD04FF75D488FE8EC369 -:10FDA00005642F4D4DF5B765A03E4F0AF57DAF00B8 -:10FDB000ED136E1F350E1AF7A0FDB7B4537B6E8698 -:10FDC0006DD6C6B9589783FC19AC57FB1ECFA768F0 -:10FDD000FA0D8B7B713DBFCDE09F8876DD755FE6C8 -:10FDE000F1F5F3AB740CE9BB4CF6AC403972DEAC08 -:10FDF000B5BBCF5B39BDFAA274F614219DFB46A5B5 -:10FE0000B3A708E9BC4CC7FCF1E334229DAFC6ECB4 -:10FE1000734EE7F3CF5F5384743E77F09A22A4F3D6 -:10FE2000367D8F17D7CD930EFF5EC4CFE9393EB232 -:10FE30009BD4BCC92FCA8F8732B4FA305AFE3BF923 -:10FE40003F46D383A1281C5A3DE834B873501E2E78 -:10FE50003519FFAA3EC4BF11FD692623F9235EFEB2 -:10FE6000D3E58751BF050665B23FD4F15E56FCE38A -:10FE7000D05FF0F27B2E4F401A7DFC066157B94CE3 -:10FE80002C807E0FD5DE57EDC64479FC0B319FD315 -:10FE900019DE1AB4B355FF6CBD18D314BCCCEDD326 -:10FEA000A724F2BF9ADCFD3C7FFEC8121BFA67CF85 -:10FEB00006B93FB6E9F952F2D7AE0ABE12C2FC2724 -:10FEC0003628D970DFB0EAA90F53309E0DFBD0530E -:10FED0001971F19539621F7A36782A05E3DEF0FD53 -:10FEE0006AFC7EB2336240FE6D82FD1934614D4A78 -:10FEF00084CE0D353919E9FBF201ED7E4D8D4FEEC3 -:10FF0000F41948DEED1C9482B83FCB30F80B7250E8 -:10FF10003FB11CDB99E4D87AF924C36BCB9C161F44 -:10FF200017F65ECE88CB570AEF48253E0CEB999723 -:10FF3000EC801D56219778BCE63F77D9833C7F89BA -:10FF4000B7FFCF600195557DBD429CC35B21CEE1DB -:10FF5000A1FC0E25C8EFF87234DEAC9E3703791E83 -:10FF60001A29FE1D97B714DFBF8945447EDE674618 -:10FF7000CDB8D17C9D965237C0BDE66B163A67D896 -:10FF80000C7CDD5A16E3C3063115950F9B845FB7D1 -:10FF9000B9FE24ED039AF17C05DA551ECE870DB02B -:10FFA0003FC2FCCDC475CBFAB5F98CA3ADE329995A -:10FFB0005ABD122DFF83FC98D333B5EB579DBFEA92 -:10FFC000078FCE7350E2EB2B615E89FBCA44FFB50D -:10FFD000BA2FFCA272EDE64CAD5C8B96FFC172EDC0 -:10FFE0008ECCD1E49A363EF037CBB5C4384121F7F8 -:10FFF0007F639C00E3B6FFD338C147EE9E0C1DCF54 -:020000022000DC -:10000000C3D7C44FBBA4969B4CE330AEC8E3CB8DA3 -:100010005623C56113E3AACDEEB9228E38F4CB196D -:10002000A8370FE919EAF37ACB4A8A5736CB070C7F -:1000300078A470583C51394A76FBDF1A575F9F19F4 -:100040008DAB17605CFD15CBE5347F1C3DAB4AC022 -:10005000C02F193DDF68B3A053B2C88B30290166A9 -:100060008FEB3F5ABFDE4C6E27BF22F2635C069EC9 -:10007000C7BEC50AFB3098BF4BC7F377EE4FF76D8D -:1000800043F9687273FC3E71F8AB0CCF1D3DA1EFD4 -:1000900027391268B478501EAA7E17757C45F80F70 -:1000A000BE28DFFF2081EF7FF077E6FB447C0CA8C1 -:1000B00072E76F8D876D07DC68D607A3B8D75B182A -:1000C000CF2918CEC7A38D331A3FFF34D3F75A2652 -:1000D000C947EF54CACBFD82F226B93C720AFD3BF8 -:1000E000EC90D18DFB0D933897C13667893C4A4F10 -:1000F000451DE513F3730DEAF98FD1ECC20FA3721E -:100100009ADB851F8E2AA7FF7B76E1030EDF299CF1 -:10011000E7E94A6F11EACD8D56801FF77BDF378EF6 -:1001200078CE423D0F00FCC4CF9B3CCBE3E0897C02 -:10013000F58704FDF287BFB37E194D9EEA5D2A1C48 -:100140007F67795AFFC714F47B8E3E4E80E0A8A8E3 -:100150001AF28AB815C3B8913A8FE6219E7F96218C -:10016000F2AAD4F7116117DEE9F266BAA0FFB9F777 -:100170004D26960A2610F218DA633E0BC5039AFA4A -:10018000799E48D33A46715FF51C65D3401D43BB49 -:10019000AF3FCD5F8079601B3FB004E454F4932FF0 -:1001A0006068EF5D789F971BD2FCE3294F6C5D5828 -:1001B0001377A8F8ECF206F46700BCE41F708AFC21 -:1001C0004C15BE3A179767EAF32681EFE8BC9C1CF2 -:1001D0004ED62F07D14E4C760F911FA9E91037DE6E -:1001E0002A642FF9EBD91A079D9F683A54594AE7B8 -:1001F000CDFBCDA568E756FCAAD686FE8973D73A13 -:1002000029CF204F0EAF423BEB9FD3FDB3105E6B67 -:1002100079701EDAA9F960A7A2DD7BEEE0BC527FFF -:100220009CBF7B1BFABB61DC6D56AD3F9B99789EF2 -:1002300078FD5E9E077CD8EA9F8BF8DD66E6F006C7 -:10024000B68ABC67E1E74E5CFFEABA8F9E73BCC317 -:10025000447169552E6CD3333FEA3D559E94883CDA -:1002600039C007CFD31BACE3F91EA26C716AF3153A -:100270004F67CC2941784AD0D13B0DEF518848E8EF -:10028000775F2EE2F0D78B7C0A357FCAA8F8BE8E46 -:10029000EDD9BA9A58FC7D2CF617F177912793FC8B -:1002A00029B79FC7DA0CC43756585FE41F01BE4117 -:1002B000FACC8A0CCDC6F34485BDA15988CF973FAF -:1002C000D5113E94BAB7287E928A648371C66D0EAA -:1002D000774F403F8AED17D7225DDC3DB62A445D5B -:1002E0007F9AAF91E0505A8A715F59F5AF7A9E07B5 -:1002F000782499FC03BD790D940778E103E388E73E -:1003000046D46780ADA7BCBFB1033F273FBEF59081 -:1003100034623E6797CBC2CF0D078628BF8CCD7263 -:10032000123E9423BFA2B8AFD2AD9007A353EFD52E -:10033000E139A8403B23FFE5F85E9B0EE9922FF2DE -:100340004B2EBEFC5F53FDB44F51FDF6419E0FA4F2 -:100350000F6FC07D97D21EFE32AC60D678C8AE6BF0 -:100360002AC1F1224D3CAF3D99219FE40F8C5BFFE8 -:100370002528E777D99884F2E7A535F9E42F857920 -:100380008E1F619E77BB78FE8E722459877A4BD977 -:10039000CA28FF50B1675411DC8F4219C65923F89F -:1003A000468D4702B82ED44777BAFCBB11CFD17324 -:1003B00032AD49FC9C8C3877696DFDE0593C7FD2A9 -:1003C00067E0E70C8FBD3C7901F9EDBA1509E970DA -:1003D000C5BE24DF06EFF78B756B558698CD128F5F -:1003E000FF63946F39F608CF4B53F49C4F946EE73C -:1003F0001EF40B7E9AEAA7BCD26B3B4332C5B36CAA -:10040000A71FA971C7ED6BB6733DD2B49FEFA713B9 -:10041000F7319FA73F8EBAB47649B4FC0FB24BDEDA -:100420004AD01B7FF3FE8469F77589F649E23E6E78 -:1004300098DD9D30DE68768A9AD75115FB0EF1C3A0 -:100440002B56D50E0A68F25EAA2CE2DC9B493BFED5 -:1004500053224F47CD83C9E870B7635E79E4DB8CE4 -:10046000FC6C6A3E4EA08AEF1B023A139D8773B163 -:100470001ECAC319C3429244F67F98CE7566623E87 -:100480000EF47BDF3596E0DECD3C5D32C943B784A8 -:10049000709B318F83F236833B56E0776EB1D07715 -:1004A000CC98C7713586E2BD3B507ECEAEE77188F1 -:1004B0006CD0B7C8B7D9859C0FCD8B783E879AAFE3 -:1004C000A1E657A878A812F8CD9EB0A200F707DDE4 -:1004D00092FFFBEA79DAF873D2D1F3D1ABC6D279C5 -:1004E00093E8F9B94226EABFD839E9447CAAF91D54 -:1004F0005536BF2D2B7DF87959953FE2E84670EDD2 -:100500003CC2EDF5AA7A03C17F71D57CF2235E5C13 -:10051000A563B86EAA068D9CDF12BEB7337A0F466C -:10052000D04CF75D08BA7F9EBD0AF42C463FEDB172 -:10053000B69AAB4F036E8FB7F9E879D12CF5CB574C -:10054000D179C6C528992E67EDACC57B0A2E5A23F2 -:100550007978CFC1E5EC076FA4727AE404965376FC -:100560001EBA11EF3DB8383ED287F71E14EEACE448 -:10057000F5C883D98C5D9555716380E6CDFD4EB38A -:1005800063E7B3CB113F8D2CBC6188FC3B3C7F1FE4 -:10059000F3FD900E2E8B81EC1997C8B364D522EF32 -:1005A00012233050EEC82AA578B585B90F0D617DAC -:1005B0000E3F2704F5C4BF1DE3B95FD824E8CA7213 -:1005C000543F523880F2A9A3C04EFDA372F490317B -:1005D000C8FD59FCFBEF3C3F85E24B6AFE2863B641 -:1005E000DC855328DF445356EF37608A2D17ED859D -:1005F0000EBDB04B45392DD55F97156717BD33E755 -:100600005B25B80ECEBFF04021CAA5EB0D60B78FB9 -:1006100020877E9DCDE5D045BDA54B023BEDE7296A -:10062000FEDB719CF79217CFB5C3BC16A5551AEC2B -:10063000086FE0FB32CAC574416FFB420E9FBDDA02 -:10064000272D87713BCCB07EA17FBA5FF1529EBD52 -:100650007FA1740BC0DD2171790B9D52695F52EC53 -:100660004EC5FCE506715E5216EB7E46FF5619ED4F -:10067000E977DB06662A8531F87E2EE2CB3F2F60D4 -:1006800077D68DB0DF6DCDE2727B81EC9E827CB43B -:10069000411A78AB360BDFBBE9FD9C94D672CC3B9C -:1006A000BE3EB9A51CF5CFB0F7A9F0BE24AE6CE4F0 -:1006B000ED1A4C913C3C9FEC4DF6AFCBC2B8D092BA -:1006C0000F296EF9CDEC774E60DEC13BFA9ED92939 -:1006D000A85F0AC4B97EE1377C6D82EA3734F1F253 -:1006E00064EE378CE6734DE1F964B50BF939C55A00 -:1006F00091AF30D7C6CFF5CC2D2FF074008837B12D -:100700008882726FEE7BBE14DCB7B385FE72DF9415 -:10071000D1ED19E6D2BBE3D7EB3C775C19FEDD5097 -:10072000AC2DDFE8D1966F9EFEE709F1E53DC9DE0D -:100730001D38EF1F4B3CFF313083D9689E4E298016 -:1007400076C7E417B3C5F94E9EA7F74F625FF4E290 -:100750007446F519FB4D7B31FF5DF533CBA27EB2BC -:100760008B99F21DFCBE00D4571149E4FB39299640 -:10077000C25EB8DBC6F1076D0D30CE0B4BDCB43E6C -:10078000322C3AF6655C43E526B2432AC69892902D -:100790006F8E09BE53CFEBAA7C58A1301FE62FC045 -:1007A000A717E2F31DBDED28FA97031F31C6E955DF -:1007B000A950FEA1F81663ED547E4CF0F7310153B9 -:1007C000E0DB0AADE757AD06A2A7FC13790FEA09F3 -:1007D0008CCDA0DFF8D2E649049FBA7E6055173A67 -:1007E00033C8A52DC655740844B1B02754FE460B36 -:1007F00008DB8DC1FF2C203E27791399C6EF4FF8F7 -:100800007901972791AD0E711E8CC7CB724DD171B6 -:10081000BD386E56F43BFCBC51862843554807F35F -:10082000FE4D560197CB83AFFF81F4B2C5E3C7EF0E -:1008300018524C744E465D37B6CEDFBE553B03E7CB -:1008400059F40D9AE77CAB0DE7590C6CBDC8414FCC -:100850006F1A8DC7D78F9CE471E33AF94ACDE199BD -:100860004A1CDF40FF46DE3F59DBDF05FD1D71FD01 -:1008700053A07FC9F0FE4F594D21DD541CA7C21D66 -:1008800026791EA2C9CC17F3923378BFF9221FB480 -:100890003005DAA3BE29D6E66BB0E91E13BFAF431D -:1008A0009B9F71BDB42E0BD7D53C53E36018C67B1C -:1008B0005DD0ED7A9DFF77783FDDEB8B8B8EE37A11 -:1008C000AB310515DC0FDDC0421B9098172BFD4F97 -:1008D000D8C7913CF80BAE8B26D93FC101E5F3FA9E -:1008E0009EC2BB0B68BD7C96356D38BC2A5FA8F0F4 -:1008F000227F209F45F92301EE289D6EEAA744B68A -:10090000DD60F7E053B583186BE1F9C6EEDCD8BCC7 -:100910008089E69A5A0AD10E79BD3D4072E37AFB8E -:100920002394D7F4E7317E6736C0B5E8AA4FE85E76 -:1009300013E65A3201ED7B80373D3BFDFF1DBCAA1B -:10094000BD372CDFF6238326DF76B475A57EB799F5 -:10095000F1FB69660FEEA1FCD9E685160F9E836850 -:10096000C6FCCF728A2F911D87E784E99E13C924A4 -:10097000ECAE2F9A97CBD7616FA39BECB7A81C174F -:1009800079E5BDA51CEEDEBBDDEA3D27DCBE5BC222 -:10099000F83D29EA3D27CB6D54AFE69FF7EEE17EA7 -:1009A000BCDEE727D07929B0DFC85E60A93A0E5FC8 -:1009B00081F67E15FC933262F9D2DBF4DCDEDCA931 -:1009C000F354209E77621CE8AFC47FBF9AADF59BBD -:1009D000A8E544BFDE930EFFEDC817CB4BBC7912E0 -:1009E000F0CF3203F7DB017FEDC2B31535ACE5295B -:1009F000BC3F701E6BF9856E1CF1979FF86BF22758 -:100A0000FC5EC1187F2DE1FC1520A1A4F25794AF24 -:100A10008A13F3ABFCABB17DAFBDFF574D68A70E9A -:100A20001A892E6A9E5CE23A8E83E7B49EC3E394F1 -:100A3000658267ED48F07C113E8FE7AF4CC6F979CF -:100A4000347ECF5458C05A16E3F73DC9FE76843F32 -:100A5000CAF71BF87E6418DCB285F8E3D6DB649E27 -:100A60003F9ECCF515C62BB2E0FB75E2FBB7767363 -:100A70003EBAD56A20BEAB1B6CA47C2256CDE30ED9 -:100A80001EF81FDF077A09BF8B44BF85CE523DB2E7 -:100A9000ECC25A6D7C6291458D7FF8F4B81E6F5D93 -:100AA000A83F19AFEF17B1CD9F60DEDB228C63A8A2 -:100AB000FDE0BB8F6747E31813308E715CECD32FDA -:100AC000027F23FFBF9ABE72D7DDC0B7131E2F2946 -:100AD000437FCE9C8C554F6D85F2F7764EA2F2ABDC -:100AE0001977DCFB0ED6F71551B91A2F71C1FD46E7 -:100AF00023EF5F5C71DBFC02F8EE71B31817D715BA -:100B0000EEFB92FCBD75D0CE35756C19E623560B05 -:100B1000F970F16E9E0F7FC355569EE2B9D24D7E9D -:100B2000A3EA2451FF753EEE5BA5FF568679A9D551 -:100B300063238BE93EC6B21F4FC2F271E993C5230E -:100B4000C54D26174BA189809F6A076F5F5BF6FD35 -:100B50006CDCC75757F1F2644F65F738ACD75D5A74 -:100B60003CD2B9D09F8AF5143DF724D6E98BDE0F2D -:100B7000E99C93CF2479708ABEE91FF27B892C927D -:100B80000DFD8F3E6F81827ED2D95E9EB758656A19 -:100B9000CFC2FDEF4D7E4339E69FDA4CA5C7D1CEDB -:100BA000489D5E390DE93BDBC4F4A89780CFFF85F3 -:100BB000F8FC9A4FF25290B92C5A3E57F9A84EE5DC -:100BC000EF6A2D1FC3FAFCD7ECF4CF97AFA3F13136 -:100BD0007CFFDFB1FFA22F69F54A74BC84F596381B -:100BE000FE687200FFE2E55C0C8E7E5A573998155C -:100BF000360ED75D8FBAEE220887413744E73EF2C2 -:100C000025CF243AF0388AFE57E1CB05D9C6CA86EB -:100C1000C3857F8A6A9771086CB60CFC2EAF877EFD -:100C20005EE688C105DF676350EF6FE0F0EC965A2F -:100C3000B8DC1076B1BA3F6E52E73BA09D6F45120B -:100C40003FEFEC42FF05F673964EFA6B70370BBD23 -:100C5000B9D0E47BC80873B8C5BE8CF8E1AB2CF002 -:100C60003CDA27C654BF634C3AEEBB0247C205E4E8 -:100C7000CFA5BC01A077DA9838FB44852B111F4D16 -:100C8000A3C8C344B813F110A3CF10D957EAF9A9E8 -:100C9000E8BC12E6D361E5EB3532CDA8DE5F528CBD -:100CA000EBE26D699227DE9E7E3B416F27C2A5DA9B -:100CB00011AA5E55E1417F11FF7EA41DCF90DD3862 -:100CC000662CD99D2ADF640AB80C3A69C438EA8DCB -:100CD0006374AA7F4E43C7C4734E2ABED4BCA044DB -:100CE0003CA9793DC3E23509F1C8D1DA49603F8FAB -:100CF000710CC79F1AEF7144FD5C029FA512C93F9A -:100D000087F073CDF6F0F309B5ADFC9C7C6D0D4C0E -:100D10000070FFB6F01FA8787EC8EEBF8DF347784D -:100D20001AEED3BF3BEF698A73A8F7C825E267F9CB -:100D300028F8198DCF47833F2DD5B712BF7B5E1A98 -:100D4000AAC0CA2DE9E2FE41E62FC07560B715546E -:100D5000A21F02E4EA679FE1660EAB80AEE50E7F5C -:100D600033F2F957996F0ED2D751E3D773FF3A2375 -:100D7000FFED5AB1DF9A23F4EDA55D32C507AABD98 -:100D8000131F9B8576E21B7A16A4F5EE25FDB94666 -:100D9000C07F099FD8DEC2F5EECA377F54012B868B -:100DA0004DD8AE8BDDAF00FF26069334F72B4CDE1B -:100DB000EFD094A7F4676BDA5F353056535F1A9A19 -:100DC000A4A9BFFA8D324D79DAD04C4DFB6BDEAB66 -:100DD000D2946784E76BDA7FE9EC024DF9DAC8ED6B -:100DE0009AF6A7C4BE9805BC43C51978BF389FEFD3 -:100DF000759F2ED5F4FB6DCADC37900FEFDACCF37C -:100E0000972B01339A7B267AB85DD102FFE374F504 -:100E10002988AF15606F63DEF2CAED5ABBA37E70FE -:100E2000EB0694A5897915AB594B155E49979857F0 -:100E3000516D5BA243BEFBA731C2EEB8865D23EEC7 -:100E400085F9AB742D62E3FF5B7435BAB47435BBBE -:100E5000B5744D2ED6D2D5EAD1D23575BA96AE76C6 -:100E6000AF96AE69355ABAA6FBB474CD5CA4A56B37 -:100E7000965F4BD731F55ABAE6B668E99ADFAAA56C -:100E80005F4160B5965E09F456E5E5B8AEB59A7671 -:100E900051BAFBEA291F667CCFFD9A7155BA07E06B -:100EA0007F9CEE2D94AFFEB7D29DB120F95F13E980 -:100EB0007E3681DEA0AF3E42B90076C6397C2E9ADE -:100EC00020EC79DFC876862A7FE2F57AFCBE75349D -:100ED000B9344C8F897DECA87A2C611FFB3E66F1FA -:100EE000907DB499FC3CB709FEBC8CAF66A01FF5A1 -:100EF00007A49FDF0740A6035CEF23DCF09DF79378 -:100F000026939FE10E16D2D3BDBF98890883DE8950 -:100F100089C932DEE7E3A6E732A1BF970B3F8437EA -:100F2000D99F92C3FD0FF919F8DD9C217EFFF25B7A -:100F3000695FE89E8293E887079D721AFDF0F0BC16 -:100F400060E6FC7046950F5EE676C6E16DE96C8959 -:100F5000F4323A7C703FBBF4AB12C51996FE9E3F4B -:100F6000C7E770BB37F1D9D1AAE28DEF876EC871A0 -:100F700093FECD61FDC27E637ECB381A87FBCD9F89 -:100F8000E4F78F3E2B3165BA838E49111D334D1C1A -:100F9000AE67F5CC84F87B86F9DD8897EF28209A38 -:100FA000789EFE24E487A5BF7F672CFAB164D975CB -:100FB00013DE2F3D1DBF0770CCF95A8B847EDD4CAC -:100FC000578B847EA361EF0FDD2FE1F9C26899F1A1 -:100FD00076F8877850FD73C53A1EA78EDCCDF717DB -:100FE0004F7D9D91DFA9A3355019C0F8940C0607D9 -:100FF000E6B1E8F979E41B72B8DF2D8B0DD1BDA6FF -:10100000EC3561178AFBE04B44DEFB0511E759B173 -:10101000C7C4304FA2E4E05107C67556002D875073 -:101020009F297EBA5FA364C7AB0E7ECFB8DE8EE782 -:10103000D8543D3A3ABD1576262E7F1CE8D8329218 -:101040001E5F93CBE3B31D6D35B3302EA3C2F360A7 -:101050009B7716F287AC7818C693F0DE9DF8FC33C8 -:101060008313EAE3D6AF62A9D194F5161F5D66B18A -:10107000A1AD85F84C2FEE07DA98B3D616FFBB0169 -:10108000AB7374E21EF200433B9B8B7A7C2A675061 -:101090003EFC91F17DA8D105E3C4CBB57BF358BCF0 -:1010A0005FB9ABCD47F06E90FC7E1CC458C842E6D9 -:1010B00014CC5BC0B397F07EC7F56F601E8DC1BACC -:1010C000D613728F8E37A34BB9122F971EC801B952 -:1010D000941C934BDF6D3B4B78EA685B44DF037CE9 -:1010E000318C9F05B2B87DDAD1B684DEEBC0CE423A -:1010F0007E7A65C784A36EA83F01FFF09E1CA39370 -:10110000C3C5CAF3483F2D167C803EAB5CE09F13FD -:10111000AD7AE2B37B722D415C84F7BC3DFE28DEE4 -:10112000F369005E92FF06B8A3DF11783208B904B4 -:10113000FCE4C3F566C856C8FFEBB02D203AFD7736 -:10114000C753F16B3033BA87C6906B21BFCD17857B -:10115000F37B39097ABE3C8FE4E83D022FAFECE027 -:10116000794727EE6564BFDE731FF7BFDDD3C8285C -:10117000FF9BB5C25F458C6F54799D8E3781C0CB84 -:101180009E361034458C3DDC66C293572C19FD64A5 -:10119000E36274ECF12A7674C76FAD76D6E1F3E1C1 -:1011A000E9A77B50AC6C99F5BB217CA28F1BBF6F6C -:1011B0006B6141B43329160BDFB7D74319BE9F22A9 -:1011C000EA53FCBC9C2AEA5317F172AEF739A91A0C -:1011D000014B8883E45A1CF30A51EEDDC5F8B95B74 -:1011E00071EE7EB790BB632C8EBA6AACFF1AA37CFB -:1011F0007CB5FE71519F6539D9350EE5F2426DFF20 -:101200001D020F9996933DB3295EA2AD57E31BE9EA -:10121000964B6F50FF126DFDA3A2BFD57269683661 -:10122000D6176ABFFF90A84FB67079C87CFCFE54F1 -:10123000B5FE3BA2DE8CF5F87D8FB6BE5B7CBF436E -:101240000A127DE88E585C3FE9DC5FDAD7C6AEC58E -:10125000F5D3D316A175F470DBA7442709992C3D6B -:10126000B6AE6CAD6CC4F3E092906729EEB0D73B9C -:1012700082BC53EB1D367EDE5D7619888F8C16217D -:101280002FC43A8CCA0BA9C5C3998BFBB13F8F9F62 -:1012900061815D41FB220FFE909F73EED5317F9CF3 -:1012A000DCCA6E4862FEB8F6AEBB1C9A72C6D7B2F4 -:1012B00035ED9D0BC76AEA2DE59334F5CC9B4BEBDE -:1012C00065ADE0ABA492324DBD7A0E9FF5E46AECB9 -:1012D000677DE14C4DBB4BC56EFAFD9033F3D4DF17 -:1012E00019F198502EACB58ECD44BDF34CDB74345F -:1012F000B2D9B3B09EF0E8D4013BCF2F3E807159F4 -:10130000B4D7DBBCF47E1FD483E5C29E84F5E686A9 -:10131000F67BDA6C547EA2CD45CFDD6D6E7A3EDE73 -:10132000564CF53BDA3C547E0CC6C7E7A3300EBEE4 -:101330007FA4AD86CA5BDB7C54DED2B688CA0FB50B -:10134000F9E9F99DB67A7ADFDDD642E58D6DADF427 -:101350007CB02D40CF8EB62EAABF46D0FB8038C7BA -:1013600078A0929F4B4EA4E3AC5C49732F983596BE -:101370003F302B17F307FAC39AFBDD71DE349E99D9 -:10138000CF3F71BC3A1C0FBE3B890DB527F3754C9E -:1013900071C7F1039EF5C9C0EF635A381D0A0622D2 -:1013A000549F55CF695127E065CE00CBA9E0C750C7 -:1013B000B1DD0569A82A99C76129BF8CB9609E155E -:1013C000E27E1C62BBA00EE152A673BDA9D2353AE3 -:1013D0006F3B8713E73F12BC5F13F397CBFBF9FD1D -:1013E00017353D2164FB246F0BDD7F615AE40BE16F -:1013F000EF57387D7E3A8F3FE9D3B9B0B90139F361 -:10140000E997991B9E390DDA7D4FF65D659AFD854A -:10141000FCE9C3CC7D358C5BA2DD9F2415AED5F4F1 -:1014200033E5DCAFA93738D76BEA97AE29D8E0426D -:101430007C8E61149F316E6E6718525CDEBB95E046 -:10144000DA24F07E4172D379DEC041353ECFEDF330 -:10145000EF09BDC24C9B693D4CB0F362516A4087B5 -:101460007AE1DC8F52491E3DFD842E88FED7892CFF -:10147000A8C3F53F19CC3DAC9F8237E8CA74A58A52 -:101480008CE552E696B17C358BD0FE04ECF3F5B9D1 -:10149000DC3E7FC28CF1C15CFFF778DE5288F466D7 -:1014A00091A06791BA1FD9AE24FA65BB72890FB5B6 -:1014B000E7993A859DDE6EAFC8C4B8E88551F2CA97 -:1014C000ACAE9933F177B4AC59D3E9A9BE7FC8ADBE -:1014D0001BF19CEEE3025F2ADF4F0426177CFF38E6 -:1014E000CEE37CF9BB19B8DD6B2A8C10FF5F90BC92 -:1014F000AE2588D73765CE878359342F45E05539D7 -:1015000058E95A02F853DE1EE709B0D8779E6EF309 -:10151000CE549458B948E445EE6FAB9B591DF7FE85 -:1015200075014F311BAA41FD545CA2F30469649715 -:10153000467E990B7BBC78CE5C29631E146F1359D1 -:10154000CF7AD4D5CA5F64CA73518ECD606ED81776 -:10155000582C21867941AF47E7C934BFAFF43B5BD4 -:10156000752ADD17981D957BA813F1F79486907F57 -:101570007ED7ABE7F33AA6AD2FB6F0FC9D15C58636 -:10158000A05BC2B07A0FDD8BA7F4490C4D7FE52F2D -:10159000B3090FEC8564E2BFE4ED53E94AED9B1417 -:1015A000FF0F91BEE743EE1774E3042F42BBC6C999 -:1015B00086BD688F4D40BCE0840A8B09AFCBC57CEB -:1015C000F7B72D213CFD5ACCA33337011EE6F1E2DB -:1015D000BD912B7A55FF87769E0F9557DD8CF7ECE2 -:1015E000750CC9C256D2E273937E682AFE36DDF9C5 -:1015F00030C025139CBF46FACBDB2BE8F795408122 -:10160000D0FC1A9F80FD7E01C9A31AD2DBD374944B -:101610009F9AC857A7841C6BC9E5797F56D79767EF -:10162000E2EFBCC5CAB3883F9FD1B162CA2FD1F1E6 -:10163000FDA59ABF0186831BF775A579BAE83D1A07 -:10164000F3515FDB7594F727EF49A2F389B25DA1EF -:101650003CE34E4BB56D358E635328AE32579E3505 -:101660008476B3D1AEBB1AEDEEE37BEF1FC2FC1262 -:10167000395761E82FEAB429DCEEC8D1513E9662B1 -:10168000AF36611CA6C872BA12F17974CF37C9BFE0 -:10169000217F43E488087F925E90AC93B5D0F881B7 -:1016A0001C45DCE7E1AD2DCD10210437EE7F6A3E0D -:1016B000423FCA71DB2533DA2B6ECB0AF2A715E65F -:1016C00015D07CF4186F83F213EB2ED9516EBDB98F -:1016D0006783A300EDE7A0423648F19F3BB2E9DC07 -:1016E000F91E039D8B57F19A1F503471BBDC566D68 -:1016F000D99810BFD3279C4BCACA2B107A6E110BF6 -:10170000C5CD47EFE2FB35E6B4D07EA7304F629FF0 -:10171000E962E531A2BC5F1FC8F6007E8EED5991EB -:101720008FF3BA72D84F79BEA3D9FB1FE7BAD5DFC2 -:101730004332EBE87ED59019F37E9F6A63E968DF58 -:1017400099820AE55DEF13F2ACD0C2F9DF90CFF9D0 -:101750003CF159D8C3D79D722029988C74B3F59762 -:1017600005804F26BF328FB941FF15DABCE43F2C0C -:101770006C35A463FEC0DC1F5A884F2E5992C84FA7 -:10178000A8B42679F07DC7DE8A62771CDCC1365B9F -:101790003AE6E5EC6D33A5A39C0A8E225FC7D975A6 -:1017A00094AFECD6F17CBAF9791CAEF979FCBE970E -:1017B00079A2FCA4125880703E09F4C43CE9A39BB2 -:1017C000B93DBCB6DD4470AC7D731CD955A3E1EDC9 -:1017D000E936573ADE0FBF77B32E1BFD4795DD85FF -:1017E0009BF09E84B5567E4FAC9C3AE9314C4567E0 -:1017F0003FD533B4DF3B52667A96C5C97739755603 -:1018000031F2952C07B2D12F7267DEFC9B315F124B -:10181000E8B713CB2BFB4A79D91AC8C6FCCAE6BE77 -:1018200069BC9C1ED889F995DFEA9BC1CBB9816C54 -:10183000FC1DA9B6BE6B79797C60279637F655F208 -:1018400032FA9E40766EE99B7333CAD90E83A71E87 -:1018500005F20F00FE1280BF5F3CB70ABCA8F5CFAF -:10186000E17BC0F321F14CAC7F41F41B18A5FE25B0 -:10187000513F38CAF82F8B7EA151FA1F13FD8E8F6E -:10188000D2FF35D1EF8D51EA7F22EADF1A65FC9F46 -:10189000897E43A3F47F57F4FBC528FD7F29FABD59 -:1018A000374AFD07A2FED709E39F10EDC3E2FD58BA -:1018B000EBE60F42C07763418EA05C2AB66E76E0FD -:1018C0003ADFDB554EFCDF51C1E33B2ABF8FC5DF5A -:1018D0006F827A5D3EBF4F4A97CFE33CCF88F1815C -:1018E0000FB720DFAD7D5BA63C9B0E9DE76C10E53E -:1018F000E8261DD9036BDFE4FBF3B5DD4A30FEFCBF -:10190000C53309F06F10F0750A789FCCE3F139A365 -:10191000CB955E1BEF47B269CB9896857217E4377B -:10192000E5ED167757751597638C4C471688D26886 -:101930000AE17D0D8A55E8055B794F31C26751E8B0 -:101940009CBA625742FBB1BFAB9CEC3B15BE4E8BC1 -:1019500042F775C956AE07E6FE70960DEDAC4EE641 -:101960001FF2627F9742F6FBD1AE321BCA3D83F570 -:101970002E1BAEDF76379F5775537112CA6BF92154 -:101980001DC9EFE336BEDEFB5C3AF25B805EA1F37D -:101990002C20AF3DA82326B0503B9D8F78F885259D -:1019A000DCAFC7ACA515745E448D434B4A9CFD7FEC -:1019B00059E0275FE81105F50B3C9F2C17E71C0247 -:1019C000DCFF0464738D893BAF79394FE6E740D47F -:1019D00038A25C4BF716E5AD5334FEF79C7BB5653A -:1019E0004382DE5012F4CAB82E9093717AA7206019 -:1019F000D3944FE609BF8E8779D07E9DFBC3CD245B -:101A00000F2FA17E9346977B51F92BE4F193E21EB1 -:101A10009E2703FC1CF1D1CD653F417AAFEDD6D1B5 -:101A2000BDD35F548E3E93C7B87FDA0F7A07ED19A6 -:101A30008565E37EE9F3F0305EEF73D0BD0A9F83E6 -:101A40008FF18F963B50DE8EF72BA47786E98DCFF2 -:101A5000C1D7B392E73D3FD2D19EC4ED6A1B9F77B9 -:101A6000678693DF4724CE1FCAC25E7B50F8C195BC -:101A7000D4B96EFC89904E7B0B9537489ECC1BA049 -:101A8000FD46C96FC3F21B8E24AE777293880FF7A1 -:101A9000A32D43F71C16F8D03FD21F34A8F71486A5 -:101AA000F0FF0E627E8E7A0FA28BEC33710F63EF24 -:101AB000CDD5D85EB14D469373DA138F6DD1830DBA -:101AC0007AD0C0A2EDF13CD533C775E29EC4DD5B90 -:101AD000D05E3D98C434F7401E443F3A8D17DC82F7 -:101AE000F73EC2F76E90610F767DFEF7B658B26290 -:101AF000F054B90F6C69A73C59BE2FB1337E4FF734 -:101B000079773805970BEC4FAECAC77DF99ED3198C -:101B10009ADF5D13ED5345FBA6C148D30137B59F4E -:101B2000960FEBA07120925242EB2B5211DF3E45F3 -:101B3000ECF7E3DA7F89C61FA57DB10ACF81776F05 -:101B40002DE1ED2B71FC0BEE7006E5BC24C0933645 -:101B50007CFCEBFF1A3C9344FBF3A177A9FD05162F -:101B6000CE985240FD6EC27E17DF7AB742CC3B035F -:101B7000ED64908A37E37B34B7F8EFB1B490FDDCC5 -:101B80006FEAB1A1BD66D6F7F850EE16E2BD4ED3AE -:101B900063CF05F985DCAE4A78DF6F6269B5C88F1F -:101BA000AD3ADABFF49B86CA4AD09E7ED102320F8C -:101BB000F5C23A0FCAC181F05A4F09B4EBCB99452F -:101BC000FB8A8386967E3ADFBBC442E74FFB6C3DBF -:101BD000365C3F667B8F0DE308F27DDC7E52965AC1 -:101BE000FC4F213F85D6162F8F5BBF556E3DC1DF61 -:101BF000FDAA6533EE03BAF59E9E0968675B15CAB8 -:101C00003F57960ECEA7F3823FD03192EF30AF2AE6 -:101C1000287736EAE8BEFA87DD4BEF413C30C5E76E -:101C2000AB827E79E98A84E72F1E547C268C5F186C -:101C300085DDD6E7E1BFF7AA7E7787B02F77E4F39B -:101C40007BABBA971C287E0DFAF5B5AEEDC7EF99C0 -:101C5000279A18E699F5E59CE9C6F3A28FBB60C701 -:101C60000B78B034E8E8F75A1EAF8536A9E8CF30D4 -:101C700068FC15CF4AFDD43ED0A8A37D82A5C4A0A0 -:101C8000F16FA435E8BCE8773CE0F66F427EBBFA22 -:101C90006DE506FC9E6BBC6243FDF490EB17261DC0 -:101CA000C09952AE1DD7364B3B8EA35A5BEFACD5D5 -:101CB000D6672CD4D6BBBE6648F0D768CB29C847B8 -:101CC0008847900116D04349BC8A2559AED0EF858C -:101CD00075FB77F54C8036C6E440E96B006FD2A403 -:101CE00024DAEF6F7C3509171FC81F467267E314AB -:101CF0004679AFC772BFE9427D9A889FBE1C03CD6B -:101D0000D75208F82CC0FDFA59FA5D2F0B8B6B5790 -:101D100080F8F13E93CFF7EFCC5581FE394672F053 -:101D200059D57F7C0B3F4FD5D7CAFDD20F2DE27915 -:101D30008134830A5CDFBC7D0AFECED854F4DB77A5 -:101D4000DD8DF98E8978CDC4FC3239C61F1BD4F3E2 -:101D50002B787AB2828B655C7797DCFCFECD970599 -:101D6000DF1C14F72D44DB23FE3218DFCAC2786F64 -:101D7000E6ABFE077E1E609B1A8F1165BCC610CBBA -:101D8000078F3B6EC0F5B46DA1A30CD7D346619706 -:101D9000A5E618BC1301DE47DE3004A4ABA0ACB04E -:101DA000E37AD0E7071DFCBB86379302789EEA11E1 -:101DB00057399DCFFA389FFBF39EABF4FCBC96D607 -:101DC000A342E7DF1E717ACC65DCDEC0BBAE19A58D -:101DD00016816971B4B68CF6A98F783D665CAF8FB9 -:101DE000E478CC989F6CCE526CB88E1D2E85EED1C7 -:101DF0007AC4E4B7A1DDE2000588BF1F67C8ED998A -:101E000047E7920087BA0A1E1260228F0FF3E8D2CA -:101E100004BEFA5C77D9F0FCBAB3F0D0B7D0AF9E6D -:101E200086E3A5F07E8827BBC0D3A57C37CF4B16B1 -:101E3000E3A7DDF51CB5C7BFCE8AB8F13C9CBF0C4B -:101E4000F358907E074D7C5F1D273A3EF392DF7E6C -:101E5000C34F38DEDA73F9FD4186358CF661CF5514 -:101E6000FAF71F45FC6425D13E3BDB955D85FC916F -:101E7000FDC6CE05780E61C34FB8FE342CE7F1A63F -:101E80006C8599BE8CF34EF7DB108F89EB30EB78C5 -:101E90004F1D32DBFF054658D4C60080000000000D -:101EA0001F8B080000000000000BD57D0B7CD4C503 -:101EB000B5FFFCF6954DB249360F424248D8CD8B5E -:101EC000401E6CC24344D4E5114445BA913722FE0A -:101ED000420204482080F6A6D69AC50445C51A2AAF -:101EE0002A5AD48D02C58ABA5440ACE85D1E5AAA5B -:101EF00056D3AAB7542B4D842AC82B86F65EDA7ABD -:101F0000ED7FBE676692FD2D89D2DEDBCFE7FEE373 -:101F1000A71DE637AF33E79C3973E69C33B33B9399 -:101F2000D82D3E076349136DCC6567F4F777FEBF84 -:101F3000740B5B674E622C650AFF5E10F63D2D65E3 -:101F40007C7E0963A9D38DF5D35858DECDEB1DEE09 -:101F5000BC8DC53336A0DA58EF89D8A3A5CC845CF4 -:101F6000D877F3B7E79BB5F67B078F60CC9F6EF110 -:101F70006C75319619311E635F4721AF3193EBEFDA -:101F8000398C8D772532D60FDFEB5DBE62C676DAEF -:101F90009C131C298C75AE649EA779FBF12FAF9F13 -:101FA000FB36CFFF67A6C319C56B651C6E692BE2B4 -:101FB000DFD95E7D30EA6FB6E84FC5F2F2CD47FA61 -:101FC00033BFC658542CAB0F723CD94C4C47FA77F0 -:101FD000FC5D8D71AC34CE78179FD448C67817015C -:101FE00053DA3F9F06070E2C747AD09FBBCDCEFBF1 -:101FF0000D5A9C85169E1FF9D4A30F5A33310F0E2C -:10200000E3189AB6978D66ECB9437CDC013CE77F18 -:10201000E2C189165E1ED35DEE47F94E9349E4FD99 -:102020008107278E656CE0A1E01A8793B18AA7B675 -:102030003F68E7788BFE9528F7F1BCDF02BCD40E31 -:102040006AE7F33B90B594E6DFF4BB2816C5EB15C1 -:102050009B3D9B90671F47B3AD3CBF7DF7D8D92E02 -:102060005EAF296E944B2F626C9A4BA3F95720ED0B -:1020700077F1BCCC368FEE715CFCFD7A8937C63CBB -:10208000475A397D8B9FB1B1FB786101E006BD5A9B -:10209000A3034F83BE2D8F72A663ACDA29685EBDA1 -:1020A000E7BEACFD3C7D25AEA2CAC5DB57C74D4C93 -:1020B000053C191718D39339DD1AED4CE7B8CA4817 -:1020C000F999C6387C03530E8D630EF04DDB1A2749 -:1020D000D2FA18A687F165C6050BD387A33F2FF563 -:1020E000873F7B2AB850FC3527E96C0D87C7CF7135 -:1020F000BD15DCE98CE9D04AC0F813BDED6A7D64FA -:10210000834FD9EC6011B84EE0C1C6716A2DE3A9C6 -:10211000C3128AEAA5FE6DB29ED9EE089987F1D462 -:10212000F9E611EAD76139DD6EEFA9670F58081F8C -:10213000AC9605F234C2933F0AF98424CA33AFD770 -:1021400095920AFE6784DC0C0B3B14C5C725EEE5AF -:10215000EB279D85287D82A3C791834A99899FC5D6 -:10216000327C62E0E3A7199B1CCED72A350D3211D1 -:102170007CB90DA67EC7397E0A0F46131C96752CB6 -:1021800010CD07CB053D38DD72D7B380C58D7AB64B -:102190007EC793D1CE25F9C06962345E7028D6D54A -:1021A000A6371DEB5902D197E4CEA61856037CA999 -:1021B000F1185B43FC10907CB1B9D1497454E5032C -:1021C0006B0F44D031C94047552FE3C200A2674F7F -:1021D000BF01EA2FA36117F143C6852CC927AE6F53 -:1021E000E93FBB8FFED3A87DDFFD0FA4F19F087DE3 -:1021F000903895A3E2C79DBB127D3C8DB6B6F83CE6 -:10220000BDE039E356A39C1CB6D72877155EA2AD76 -:10221000DE940A8EFFE8DB4C9E56DEDF65478CF5C8 -:1022200026BB3F4CC47AECA91F4A9986FA75A2FED8 -:1022300015278CF57DE37647D417F05D7DC1582FC7 -:10224000923E91F072B8FACD08836B823DCAD07E7F -:1022500076E54570F59B1506D73569C6FAFA9ADE1C -:10226000E1BABE20EA1BE152F5BE33FAD2EA45CE0E -:1022700063DAE4A83EF02EEACF9A7D69FDDE54F3DE -:10228000CDF56E69881CC72FF72BBEB6F83A4EC63F -:102290003FF812486E3079A3F93EEA649D0CEBA832 -:1022A0004BAEAB24E6A4F5CC17BE8675F53EFE9981 -:1022B000CED810B7EF2BC8AF0976EFBC8779D58998 -:1022C00072BF6253788F97A3735FF18DC517F31FA9 -:1022D0006377115CAF6ABACE689FB57BB6F2F55DE5 -:1022E00098C1ECE95C0F606981EC1BE3188B752BDE -:1022F00079CD450D8773A8C4DDF30382AB12699DC8 -:10230000079200CF3F3A6E7FB737C9DDAFA77E6433 -:10231000BD9EFA024F365B7025E0ECAC7378B03F9F -:102320007C8022DEEE9999512133C7D739AB639D6A -:10233000C6E5CC91D8F96FF6E378783F5E77A1FFD8 -:10234000D9B3AEBD1B79ED40B26B1587EF5C65FB71 -:1023500028E0D51BABE7BA391CB5767D502A9FE241 -:10236000994C7D7002F0EB4B26BCF27F14FB7A8512 -:102370005FC0335113F84F4ED08B31CE4453DB93B3 -:102380003E7CB3B48D423BE6EC47F09DB17179D70A -:10239000CBFA5778182FFBD96FF57CD5C9E7B77FF3 -:1023A0004382A789C35B9D3C6BFE0A5EB4D0E44BBD -:1023B0000D990D705F81F16A1D9583D201B755C2E9 -:1023C0006DEF27F1EECDFD26B89B301EF6B51F68E8 -:1023D00081AD6E414BE45FF62706EEE3F928D3F9B1 -:1023E0000F203F3A8B4D1EBE47B0CD5CBFB0F37D92 -:1023F000E53D89EF27B8FA634FA2EFEBF03D2D469C -:10240000B44F7BC41468E2ED7DE35F213A3DB3DC59 -:10241000E131F3B12A99CB06BEAD625E1BE0FFE36A -:10242000B8BFBDD6CEE737C7AD4FC73C6E4936659E -:102430007D4070E885159CDFD85881FF6FE307C6A3 -:10244000D69BD828C66E94FAC14289C769CC6BC5A1 -:102450003833986EC5B8BF396BF3422FFD0D7450F9 -:102460000EEF2CE6A7EF735880D29B5888EADFCC9A -:10247000DA29FFEBD892CC060E5FC5A383F3B01E1A -:10248000C3F0BE54F2CB2D29825F3EEF0FBC6FEC40 -:102490007749FC5BA109FC0D71EBABDDB45E5D29F6 -:1024A0001EC0E49C30D01717B67E26F613FC677169 -:1024B000E67DD3FA69EB8A2F61C3481E38D2391EF4 -:1024C000AE91A4BCC6BB6C0AE60B0982F5FA1DB935 -:1024D0005ECBCD0E96C2E9D2E63207A2382C93C766 -:1024E000AD4CC37C7FB186FD6A38A7DF2FC69959F2 -:1024F00013D5F452BBA9B2BFA903279D847EF20E67 -:102500000BA58CE0EDCA2FE88712387EA69A7734A7 -:10251000738D9B4D1E68FDB43D4CAE5D9BB2D3C226 -:10252000B8FE725DAEF1FB94229E0F93BB5399A54A -:10253000A79CD37F3FF003B9C35ACCE0DF47DD71DE -:1025400029D057D85036549C0F3835C2E6D365FF92 -:10255000DA768EB77BCBAD3F093E5A9578763EE969 -:102560001D16319FE5EF9A49AFFCB49181F3D87104 -:10257000AE1F7AF319FB8CEB17C89F684CA3F40BC2 -:10258000AE0F203DDD5840E5671B3D94FFD2EDFBCB -:1025900009E8B460DD9716EC4BF7442B7C0B3856FA -:1025A0004BBEBB2773D4A37FE578BDE71DBE303893 -:1025B0003C35C19649007B75E6A777417F5EFDAC4F -:1025C000E641BD65FBBC36078767E121FD6E90796A -:1025D000F13BED532126EAA0BF72BDE15EAB6F3740 -:1025E000C61BF9E1F1549D57F0EEEB783399D7FF14 -:1025F000BC7134C175B2D14B709D6A9C4C694CB6AC -:10260000EF55D4F7B22F6DA87FC38E0E4B06AF5F88 -:10261000EED5BC588F57795920C0E1D96415F27DA9 -:102620001397EF589FE38A6F7CE25606F9ABBF81A0 -:10263000F63392AACA93F9F7A9A32B2DA837EB2B4F -:102640002ED3DC3D7CF8EDEB50E0A34ED2E5CCEB95 -:102650001AE1E9CC9EC2EF5CC1FB7BFDB0999939D0 -:102660005C5D174C0457D79198009456556FD56E02 -:1026700033E993AB326D01E06FD5EEC2FED0A74EC9 -:1026800071BAB1FC9EF14E3DFF6F2E3D4C8E9E4ABD -:102690000AFEE74790539F0839C5F5CDCF1E871C2A -:1026A0001B38C003BA9FB572BD1C8866F5B1D8C788 -:1026B00096DBE4FAE27206F95331E21C3CEA858CBF -:1026C000F1582F18CF65EB9143F92F3C9AFD7D57B8 -:1026D000CF78DB830B3F7A9CE7CF044C7E2BDF6700 -:1026E000CEB0E0D99F438E6E7178703EB847E3F06C -:1026F000601FDD3A80F2059A25A681F83940EBB5D6 -:102700004073591AB8FCA9FDD96303C04FAF721CBE -:102710008CE6E5AF6E8825F9F4AAD573B401FD3DCA -:1027200021FAFBC90FBFF7E95EA40FD4957D0F48CE -:10273000CE4E227C57FF68C950B4E7FB344BE7FD0F -:102740003DF7B2168AE6EBB378E3FEBBD2397CC321 -:1027500036779806F0B4748BD684B430F3BAC36677 -:102760005E6ECF76111CC377B8CD19585603021F81 -:102770005D4DFBB7715F2FDAF8E5781C2FD5FE3E73 -:10278000540B7ED18AF370D691329DF0D742FDEC86 -:10279000DE37EDFD9B18E6C13507C05D69F3D07EDD -:1027A00012F0B782CE67F402CF7D58D33EFF63A00C -:1027B000EF193DD583FD658FC91F3F06F58F5A6818 -:1027C0009E2F6FF975BC95E713765959342FAF2BAF -:1027D000ED9C84FA75992E3A87673E79CD64E0675F -:1027E000F9AEDDADD44FADDDA3619DED3EFF6606D4 -:1027F000CE43D7324F1EF86E97C8DF3FD1EB01BFF3 -:10280000D5B4FE59E4DB7C94F799FD6E0BEA5709C9 -:102810003DE751B98FB1F6129277C4CAAE1E7ADD88 -:10282000CF8B51BEC9ED4FAF77F4EC7F7CDF2ACC64 -:10283000E6E5E936D9DE392DCBF70FEC5B36B90F7B -:10284000A9FE1EB5317F34EF27937FD7B0AFDAC42E -:102850007EBB95CB17F08BDA6FF9B857648BF65EB9 -:10286000C8C90CBEB996F2F9643C1A15A03DFD1218 -:10287000C7577AD28A1821CF94FE313BB9E9B57691 -:102880008ED73FC5EBD7607E0BE57ECD2C9E34CC3A -:10289000EF58BC7732C6AFB57766610E7C3F9C823D -:1028A000FC7233D79F72C2F427FBA5ED875109DE76 -:1028B0001BD1FE52EB8F8DE95DFE8EED1A4DF2F7C6 -:1028C00035297F57FFD9C44A797EF5C351244F6813 -:1028D0004FEB052FAFF1F5AE73F9F2EFB01BF0F44B -:1028E000CA3FB59BE9FC71C854FB26DF4F69E86C11 -:1028F000FC5F6753C208CA7B41E6ABFE64EAF57C25 -:10290000A8524EA77ACCCBFB95D1DE70F5574E1B63 -:10291000F5EF48BAA4F99AFB98AF395ECC771FE679 -:10292000CB69B7FACB329297FB2E719E9951DE3567 -:10293000A06FE43C38DCF7E07B24DCDDFCDD79696A -:1029400070DFA631BF09EBEC4B5B00EB6C1F07138C -:10295000EB76DF92A200D6F31E9BC8FBE36DA47F4B -:10296000EE8B637EC88F7D15A901BF1B729009FD98 -:10297000B41F13E5D1B2FD9C546A3F208AF33FCFC8 -:10298000B39B6264FFF56F17A37C4D868743C0F548 -:10299000DBC0BA6CD26FCD64373C22E5F5C6C4D03B -:1029A0004D66FE7DE397F90CE31C61A18C15A857D9 -:1029B0001343726863A2373D89E371CFD766DA1794 -:1029C0003696F2BC83E434D977365678D313797EC1 -:1029D000AEA4CBC6D6C0D647D05F4581C7CFC719F6 -:1029E0006066F554CF2DFAF9C82ADAFD4ED285AFCC -:1029F000635AE7EF672F0801CFFAD4580BEC221C7B -:102A0000E3E91A87FFF1EA3C46F252DABD664B1A57 -:102A1000CCEDE103AF7D14F45AF13767E1D668C815 -:102A2000E31935D164973A5273579C8B8F374337EC -:102A300087A2A0FF4D2F37D89DDECFF6D2B8FC601D -:102A400021CF09A12AE0F1F54E3B835CEE8B9E7508 -:102A5000C171C9C7C3F8A1C626E4C709A90FBD1231 -:102A6000A7BF0B7E5FB1F7DAE4E361FA5EF5C2F26D -:102A70007CB2FB565FDAF9AE09741A46EBD56F02E9 -:102A80007F04A389FE936FB413BDBB1CA6A76197F7 -:102A9000BC45CAAB261C84F9F7A6DD5181BBF8B74B -:102AA0001551A19990579CFECF6E035D5F8B26FA5E -:102AB000D7DA043FD5FEBC90F86B8FCDEB5E8BFE72 -:102AC0005F8F22BAD7C6BB12A8FCAD6426F98FF47B -:102AD00086DA98507E22C7E7BA58FD24F0C6F98EF0 -:102AE000ECC1B536F1FDA8E4ABA3BC0FC0E1AF8FDC -:102AF000237E6432AF7F3F99CE535C1F25FED51FE6 -:102B00002CA4BC6EF3A62FC4FA58154BF01D95F6F5 -:102B1000B4A3B589C4DFF31E5CF60EE3F43CEADB34 -:102B2000766F3EAF77749FD5837DE9F70DE6908D84 -:102B3000D3F5EC1DC7466DE2F9F6BB3ECED2C3EC31 -:102B400068F3EEAA9B8276F396DE3115FB655FF89B -:102B50009E571BC5656E0F9D5272BCE61C8E7F4F43 -:102B60008E6ECBE1F35C51D4BE0872EFACADED4993 -:102B70009C0F3E4AD0A3F1FDDC2B9F6F237968E9BF -:102B8000CC877EBEDCC2F9007C29F7CF15922F5F7F -:102B9000CCD113509FE38FF4F1D8A23621F7EEB8D1 -:102BA0003439FFC5BEAD7B343ECEB2987DCB2935DE -:102BB000074AD0CF292D14AFE5007F5C8FE3FD9D40 -:102BC0007686E241075D9E9B966D37CE0B7FB0AB5C -:102BD0002CC33F78BB654133D955F8FE6E03FCCB5F -:102BE00060E935F813845CE1FD3C4DEBD0F1FBF975 -:102BF000DFE7F85FFAEC9032E893CB12F7FEF00AC9 -:102C0000AAC7DB293E375F9C57F3B9181E31BFD3E3 -:102C100092CF4F33290767DBBACFE1D083CE3EDFB7 -:102C2000DFC037679F1D42F92FB44E2D86C37556FE -:102C3000CA23E6098EAAC001C21B1C057DF611F944 -:102C40007D59727014E48F9247CC1E2CA17375418C -:102C5000B004E74925CF982F984FDF03C17CB4DF3C -:102C60006312760AFAC3BC9FCB68253CD8C57A5C50 -:102C7000FA5C21E1458D1349BFC8F94ECD11FE0123 -:102C80000EEF2D3E5E7FF0269BA17C48C0989F29C9 -:102C9000EB0F8AA0CB0073E7FE28C8FB6718ADD7FF -:102CA000C8716FCE11F6F49FFEB49B0E66795E6418 -:102CB0002E457F97D0B7ADC0F7EFBAF17D6B069781 -:102CC000A7CB30C7EC9EF9EF29D53320F7CF9A84F4 -:102CD0009D7A4F22CF1741CF11F8547985C7483ECE -:102CE000BAEB778B32E04F5997D3EDE7E80F7E6B65 -:102CF00082BCE4F2A2C92AF0F14563CDF0E3169C50 -:102D000047EBD3AB2D3DF359B4A9D48EF5B278730C -:102D1000A97D41D879A769FBF0C32E4E97D3DB2D4F -:102D2000643668B2047E083DBA69BB39E867546E00 -:102D3000F7F2FAA71D07DE45BD459B13CBA0F7AA06 -:102D4000F68B37DD965E1D86EFC2ED46FC17078DCC -:102D500079D8A3C3F33F822E38F21F6F571A32E699 -:102D6000871F36E63FFFE0D69960E397470B7E3F2B -:102D700011880BC04F55F3F1A4C3D8D74EEC793965 -:102D80001EF459F649F59B38B72CDE64E4334E3710 -:102D90000D7ABD7F9B46FCB12410B9EEE47ABF6882 -:102DA0003DAE5176CD82703E89A4E729169CE9E5B7 -:102DB000FC54DBB06A38FC21355338E372782E0FAF -:102DC0006EB0C16F10395E5FEB9E39BC2ED8AB2A56 -:102DD000478BB2310DE3D931187DD7FF7A12D65B1C -:102DE000E5FD1AEDFF952F0D3E04F9DDB173CE75AB -:102DF00094CE9C4C7850F6B3C5FBB4501CCF3B47E7 -:102E0000BBF6B6F3760B031AED0F0B9AA37AE41018 -:102E1000FF5FF5FA083836869573F817EFDDFF1770 -:102E20008DF75FB3D9D86E09C717E4FED22D7F8F17 -:102E30000AFFAECE7D63F6B59A31EF850A7EFF5567 -:102E40000CF3122E482E3AA4BE721C192EEFA39238 -:102E50007C6DD85FC66C14EDB8C0AAC47CEB1C3680 -:102E600017E65B6767A1580EC7E1389BD7C9BF9FBC -:102E7000DF1447F6A945515C2F2CA3944597A19DDB -:102E800087F6E9CFDE3393BE5287B1D1CF531A9D77 -:102E90007FEA606C44FE19915FC242340FF08B37B9 -:102EA0007C7E01639EB5887353AD25B41FF858CA64 -:102EB000DAC5B987D3D11BE68FABE5F33C92047D2D -:102EC000C8D87E050B52FD157BFF1E15FE3DCC4E6E -:102ED0004AE73975AE34DB9817FAB1F9CE18DAEF54 -:102EE000B9208E017FAED5BC8FD9CD48C5BCFC1BA7 -:102EF00084FE33B755EC175C3FCD077E366E18E283 -:102F0000819E3297EBD9D1D02396C450BD8D898C48 -:102F1000EC2B1BE7E40B3DFBEB974218A7F3618D0D -:102F2000EC231B4B45BF1B1F1842E590871A8D13DE -:102F3000457ACBC60A559E497AD247002D1D7AAEF6 -:102F4000FCDECF45DF0798BDF9D0D7D943D174DE79 -:102F5000577AED33497A7C6EBF9EF92A3D98D55C4D -:102F60009AFEB755EE779D1B84FFF7B8E67BD31426 -:102F7000A6970ECA15FBC3A8F1DE6DB21EF901AA11 -:102F80004D15F75DCDE1A97EC4E46A72F7E09D7945 -:102F9000BDF998FFF10DD165E0B351E385BDE76858 -:102FA000A990DBB1239837C0D3825CB17F14E49A37 -:102FB0000C695A0CE73FDECFF172611F8E1BE123D3 -:102FC0003B1BD7D9487E47CE638484AFDAE67BEBE0 -:102FD000CA5EE0E9E6838942CF38BE527B5AC0C55B -:102FE000E9CAF3A37E144DF6B9E3725F51F8E77CAA -:102FF0003392F66929AF36483ED900FA633F5B2227 -:10300000CE413D7C62E483B99AC02B7B40E8A71B8C -:1030100013455EF1013FEFB0BF824FCA19E1BDAF6A -:10302000738F9AE7C65651CEE93D05F48E3CF728DA -:103030007A334B6024CE8D7DD17BC1E8C4519A890F -:10304000FCD67EF8ADB1D7115EEEB504EEE2700CA1 -:10305000B408FC675A047F71A9EC8F29A3FA5E1BA0 -:10306000CF573EB4987979FDCA0C46F6205E9F256D -:10307000A03EEF06712CD82BD0AE3241F45BD99F25 -:10308000D13981FEB8BCCA459A4DFD7A4D49A27D21 -:103090007C19B5F79B447BAF85A78372843EDFB96B -:1030A000362AF034E4F33D99F9E08329E38D7CF08E -:1030B000EFB962BF57E9D03C97342A79D2B0BE1736 -:1030C000340FA1FDA229DA57B71B747B5EE8FF9588 -:1030D00077DF7CC348C0F742B207E07D317527F93E -:1030E0001B1634CFB9ED439C1BB647D3F76BF2F4F4 -:1030F000DB7347420F74CDDFCD3F2C9871D096C65D -:10310000DBEBC18A333FE7E954FFCE77A10F4C9D3B -:103110006EA6FA5399B08FB26631CE0DFE2F2D698F -:10312000BCBF1BC66A1433D011EDCC5AC9E1AF94B1 -:10313000F4BB5BF26F53349BFD3307E0CACCCFE6A0 -:10314000DF6F8086D98BFFEA90AA3F4EDB0CBD660D -:10315000D004B1BE547DF4837EDF92EB6983C48BCF -:10316000CA73BC52FDEA75511D39F148ADA1C13C8D -:10317000EDCC1FFF30F86A4A369BB40978FF9E19E0 -:10318000B10A1CDECE4A5AF771F92EF0A9CE588842 -:10319000E223024388AF3BC67576DCC3F31DAD83E3 -:1031A0003D64F391E7E885385FB9502EE498922F9B -:1031B000479DED71C4AFF25C5D2559E38F0D131E81 -:1031C000B98CD7AF72D83AB01F2C7C785A3CE24CFD -:1031D000AA369A453CC77AE3B99A9F7F5F045D227D -:1031E000CFC991E761F00CF8A87ABD467C38A8C930 -:1031F000634B2739A63931BF6A472817F2BDDA1366 -:10320000ED41F9E9466FF2F15CF8232653CABEE2BC -:10321000781F057B2CA3208E0379FA3EE0A9B2A586 -:1032200092CE8BB1453AC9A7BFE5BA08CF53604FDC -:1032300084BCB1B4A7631DD6A9EF49CE7C07F17356 -:1032400034031E3AACCE7CC0D5B136DA847D73CA65 -:103250005D82AFF93AB35B78FB7B2D2C06EBFD3E2C -:10326000D97EDE1A8BAF95E707DA99252E097C55B2 -:103270004A7C5D3658DF003C9CF8011B8DFDBF6A1F -:10328000FD068247F105B3B44D4C867EB7D55D7619 -:103290001FEBE1A3B2C1E3DF47BB6E7E98AE111F07 -:1032A000F0747F0EF1C38D47503E657C2877551131 -:1032B000FC58B5CC0B3F421AF3C01ED0C53A499F0B -:1032C000E8E2FA04E49992274A6E703EF022AE4793 -:1032D000D157C98F6D8D1C248ED7ED8D764A7FDA3C -:1032E000E864162E037634A651FE854617A5C1C69E -:1032F00002FAFEB3460FE577358EA6FC9E462FE513 -:10330000F7364EA6F4E78D3EFACEF1427248C91563 -:10331000258F143F29B914C947F3397AAF2AA3F688 -:1033200024F794BCC33C4C653DF248D1375BF3F9BC -:10333000D3DC9063ED73202FCACDA79F7F197692BF -:103340001A8727CA05BC08B9D7E5B0939CCFB2B19C -:10335000BD38AF37ADF476DC13B6AFDE54A3314BD6 -:10336000189FDE5C1FCD2C617C7C4B43A2213FAFBC -:10337000E1FD37FAF3FEB544DD91C7E1387AE7673E -:103380004FFC967F7FEACE2FF2406F0EC7D64731B3 -:10339000EE1D31DD702421DF6C25FD61508C380776 -:1033A000E10F7459C0C4FA7CEACEBFD2FAEE688845 -:1033B000729979BD050D5184AF8F40278ED7DF4BB1 -:1033C0003A55AE3DF6FCCB58E777D848CE2D6896F7 -:1033D000EB721DC76798BEF6693A23BD4CF33206FF -:1033E0003FCCA73FB085F89ECF3ED5EC010DBA0F7C -:1033F0003F24CDE3DFF575BFA0F82BADE130E9C385 -:103400003AE2B26027F05B0DF1585A838CD36A1F01 -:103410006888A38A1DE1B5413E80A741B70505072D -:1034200018D6356BD19CD802AAE5F7EA751AE91BC4 -:10343000DDFA429E99E8589F6BA1F45DAC71DA2FDA -:103440005A687F52FCCAE585378075D1526A5B1491 -:10345000268717C8EF5505264AD5F7FA5C1BF5F302 -:103460002E8403EFF7BE826CDB4292732E1BE48046 -:10347000AABFA0A0ECEEEC11E8675C0A0B5B8FDE44 -:103480003C0BB5AF47A017CE477661FFAFED631F8A -:10349000507AC909FCF372829FCE5B4B5F78EE05D0 -:1034A000F8C7967E1C45745A3A4CDA238A02A3A6C2 -:1034B000913EE375687C9ECB25FD273EF7497C3B1A -:1034C0002F5FB14BD82F79DA8174F91D3564D75A43 -:1034D000EEE1EB230972D5E8473EF4C2C7F1ED7483 -:1034E000AEF06720BE906F0B192C0DFEA2639360A7 -:1034F000175FC13AEF465C5764BB15DA57F1C2BE9D -:103500002FFCE4CA7F59FEDA9F53098EDDE7532171 -:10351000D756BCB63655EF65DE2B22FCD7CA6FAE48 -:10352000EC602BD8FA2FE1778BACB72A4FFAB52F86 -:103530006397919DC2C2288E61955DE0A12B909703 -:10354000C07A19AF7BDC4D5CB0F3736897C595E02A -:10355000E1709EEB238EEFE53CB13F9F917ED473EB -:103560003BCCA4179EDB1147FCBF7CC7436F5EC1F9 -:10357000F3CBB7681896D5B136C2D3F25D66660F45 -:103580003FDFC06E93DC379CCB9E8BAB073F2D0992 -:103590006ADEAD45F0CBBB12FA85EB8B929F964568 -:1035A0000547111D24FCF749FD48D55BB2EF211BEF -:1035B000E8C5EB9D25BDE5C558E8DAFCAFF35DC075 -:1035C000796AF370F2EB2E09EE5C4EFBFE8E582703 -:1035D000A6F885D5688F0AE489F514C813FAC629B8 -:1035E00069FF3DF58299E40FE0C43AFC4213765E30 -:1035F000D56E9B6CB74DE2ED863CB11E55FD25C1E5 -:103600008EF85C5EFFF3BDEF531A94F35AE2682B19 -:10361000C17EF9F9AED8C9014A7F3CE9553EDE9931 -:10362000E0B8142D6C5DBD9627E286CF6C364F0650 -:10363000BE5840C51905693EA776646874AE05BEDC -:10364000397E4EED7A29DE44EBD62FDA493A9AECF0 -:10365000C29EEAB6B8A4FDC2EE849E31976B75098E -:103660005CDED5ED12F10091DF557D5A6FE9E0F790 -:103670004E9BE07FE9BF97FE25C489903F3ECE1662 -:10368000C0FE3A7F986BD64D90676F5B053D06BADA -:103690001EC5B96AFE7BC964AF586575F547FE4F14 -:1036A000EF58C97E3E7FB85CE769ED23619FEC70FF -:1036B0008B7DBD761D5F217CCA0338FDFD7C7EB508 -:1036C0000113C5531ECBCB26B81EAF31796DE4E78D -:1036D00008E5C34E79D4C6FC66E8C93F8B26FDAE2B -:1036E000365BD8DD1F07BFF3B43629949F0C7B9758 -:1036F000A463ED8DBC3C8C9EB54F87F2A1B79CB600 -:10370000093B1ECA9D48CB44BD26C937E807FD7654 -:10371000B89D6749BFDC1DC7A0E79B5E8E13F6848A -:103720009F4493DF41F57B5EF25593F473F9B70A3A -:10373000F80017F4E625B6967CE8956ADC25F12DAD -:1037400034DE6939DE929816E13F907161A84FE34B -:103750005B9917E7F1CE67A3483FFD22BD6D0FC609 -:10376000FFE2D921E407EF700716EDA572AEB7713D -:103770003A2CFD695408F09E7C368EFC9C27AD42A5 -:103780000F3A19974A7AD0E1B847E6A3BFAE2D5158 -:103790001AEC292735664B43F9D67EE4AF5ADAD8BE -:1037A000407E82A57CB9C31FCDD3C9F02B9FDC3AE4 -:1037B00084EC2C277F6926FF22FFBE0EDF75D632F0 -:1037C000FF76ACBBEDB16467FBE2A77F1B12EE7F17 -:1037D00050E9D22D467B92A2BF2A4FC917EB2B2569 -:1037E0005FE0312D5FEC3375B1C147B2699E62BDB8 -:1037F000723AD0798BAF8F54D8A78F065F49D51C0A -:10380000C07328FFC7C0FB7671AEF9628795FC22B2 -:103810004B5F8EF392FDE69ECB4CD82F969A85FE99 -:10382000BB94B39B48857D68697C3ED98738BEE9E7 -:10383000FCD8B9D52CC711E39EDC9629ECEF219971 -:10384000DF531C009F4F4962B7DC48FACDE612E017 -:10385000F5FC965813F8828FE385DF7EE9EDDF17DC -:10386000F84C5844FA38431CF428F8CB85BCACBB60 -:10387000E78A04C4C3B0F7CC0CA2EFBCC5D31FF2D7 -:1038800030125F8BF3A5BCDCF3840DFEB35ABE5E31 -:10389000101FB44CFA4D97FD54237D6ED9DD573C73 -:1038A0004A72F05D2BCBE3709C0E3E141F4E8F0AC4 -:1038B000D94F4F7B0FD55FC6EB8BF66FC7133CDB41 -:1038C000AC1EC01349C74B6EFF53F325B5EFE68F0F -:1038D00020DFD74B2E9EF779D6F6DD8F2147764431 -:1038E0007BFCF435487EE753D6E022CCFBD4F3D101 -:1038F000245F4E258AF5FE3997877E1BE0B8FE418E -:10390000B26FFC661A83E85E1C30F6ABC69D992F39 -:10391000E46F5DB22701FE8C3A4E07F4C7E9F21D51 -:103920006AFF9E95DA47CE63A46CD7BD3E9F8F2574 -:103930007E393540D0E3D40B83695FE948147CCEEF -:10394000E1CDC239E554A2487153067CB0549E4380 -:103950004F8D0BD2B9FB94B693D20EAB68B7B4417E -:10396000FA6D39DFA5816FC093F05BD9D7B7418F6E -:10397000807D7A5419A5A1A8A48BEDCCE04FEC432F -:103980002FE40B7B16D41AC875F26F907E12B441E7 -:103990001EEB528FABDD71B1BF8CFCA03B34F2FB50 -:1039A0003C20D729A04E51F671CE8FCBFC9A17F14F -:1039B00046CB9A572E01BF2FABDF7013F85DCD6356 -:1039C00099854DC6F9AA4333133C1DD17CDD000F08 -:1039D000E1E365F7E07793821720A7929E49CAF545 -:1039E000E67CB15F21DFC2FBAB6DD6D6D3386E75F6 -:1039F0009E14F35378E268B1C14EC6CFF9A2BC8FD2 -:103A0000F92B3823E7AFE009E60BFB4487DBF5E051 -:103A100058D0FB5766B29F9EFF6A7842D237E8655E -:103A200038B175DB8B39FCAFF1BD1AFDF821DFB081 -:103A30009E618FE670E66F36FA3F0AB618F3437759 -:103A400018F345BB8CF9927DC6BCE79031BF558E0B -:103A5000ABF084732EE2DA70CE458A73AE2B5F9C96 -:103A60007391C7391729CEB9F88E732EF238E72231 -:103A70008F732EF238E722C53917DFCF4AF95D2B55 -:103A8000ED8EA003C557BD12ADFCE0B45ECECD49AE -:103A900025F9A9FC99E7961451BEDB9E5361277B5B -:103AA0008E8AD3B929413F924F7EC3B6BBD34137EB -:103AB0004B3BD97157FC5CD8716BCBA21DB02FB4B6 -:103AC000AFFDFC6EA84F2509FA27F914D7D4B94DDC -:103AD000C42B85486EB4AF71BD77B5A01FD93954DA -:103AE000DC4D25F6BBA4BEE918E94761EB8D7E935A -:103AF000483F4AA4FF24920F94DFE4296B673AE41D -:103B0000FDB167EDEB01FF31691F63B39DA47F2910 -:103B1000BDBA5BFF7A407B1AFBF6D7F949D4BEEBFE -:103B200030D7B77BD96F555A75A18CF4C6EEFC7AA5 -:103B3000CD44712369F1B40FAD963065699D1DF7D1 -:103B400040DEC599681F3FEF30D1B9E0FC0766D26F -:103B50002306433F0F9BCF90408C81BF0AB7274578 -:103B6000F8FF0618EA0FDB9B1DE1FF1B6AF44B4DC3 -:103B70005FB31FE7EB69EB871BEA55FBAE88C0A379 -:103B8000845BEAA54D776CCA82FC591DD745F0AF1E -:103B9000DE1D4D71B5D51C5E2FFC72C87014D4D8D3 -:103BA000BD5381BF9AA03511FB7C95DC7F58837192 -:103BB0003FAEB130BF33A987EF6A9CCC9BC8DB9F77 -:103BC000296DD966E2743B63DAFCC85817FC4AAD2C -:103BD000594ECE57B76AC1D4CB797F7FB3E84583BE -:103BE00039BF6559433F9C0779B93387ADE1F58EFD -:103BF000AD7F299EF46EC9675956670CE8DDDA621D -:103C0000A67301EC52E6A41E7E686D498EC975F458 -:103C1000CCB387FE5FD1FC385D3CB8A7D8E538301F -:103C20007035F4B8A0986FCD38CD4F7AB29CCF2ABA -:103C3000B9AFB05CD1CFAD327F5C9E17D4FC4E0FD4 -:103C4000D95FE2821FB3716F961972DCB4631BEE09 -:103C50000FDC19A35F337824E225F37E3B968FBBFC -:103C6000F44311AFFBC78D13E22F87FEF9BCD533A8 -:103C700085E7EF6979C68673F1524BC0867367CDCD -:103C8000B3AD362F4FAFD9DE4ADF176DAFA4F3F6D1 -:103C900062564FE7C8132AFE56E2A366BCB6D9C9DE -:103CA000E17E61B0901B3531226EA3DC3CF60DC481 -:103CB000A59FDFAE9562BED37D3B6D95B03FCB7ABD -:103CC00091EBA3EB9D69E5FD604F0A0ABF675FEBCF -:103CD0006146A880D6C3B40B2E4AA75F184AE7D81E -:103CE0000F99AF98E44451C479F61D1187DCB54FA4 -:103CF000AC831A5B28651AD6C9EB565A27755C7EC9 -:103D00008D2EC33999B1313CF58D351BF875C5C47D -:103D100058033FCF6649063FF24C5CDA0CCB4F9F0D -:103D20009263A83F6B7A6104FF97F594931C196323 -:103D30008833A9BBC3EFD2289E65BCF13B4FEF206F -:103D40003EBBCED0BE8EDDD8530FE7E02DBF263C64 -:103D500033D666C379ABC624E26A66EB1DF27B3BC1 -:103D60007DE71331ACC341399EDF8A7DD14A767934 -:103D700065979E8D7FE7F4B62F7242CB71111F0AB3 -:103D8000FB8221BE900340E74F26E85027ED3D75AA -:103D900005C2DE53E76FB321FE96E3DF92C151B255 -:103DA000BC45237B1EAF6FCF4812F93BF07D97F1E6 -:103DB000BE01FABB80F2C3E64AAC97C8F2E57CDEEE -:103DC000D03396C34E033B93EA5FF6ABF873F1260C -:103DD000A3DD6839EC396174FC72B08BF874E9F6D4 -:103DE0009D6F0EE07899E64B2CC5FAA90D56582B1D -:103DF0008B2EE63325DFCFD798C8CFDDF5CE41E255 -:103E0000B3AE1A0BF1F3B7E163B957D83323F96FA7 -:103E1000119F0FFCB28B76699E8026EA012F03C0AA -:103E2000971178C9E8055F0A4FDD788B285F8C7F92 -:103E30008C40DC801608B97BC38BC4A3EA3F024FD9 -:103E40006CB4110F8B74D77B90378B0E9B59E0129B -:103E5000E6BD18F3C3F87C7E18FFC60BC24EA2FC69 -:103E600006332F5828DFCD273E113F3D7D8A715DF7 -:103E700076F38D4FAC93191752A9DDFF36FF7C1BEB -:103E8000DF28B823E393D5FD9EFF1A2CED8423D9B8 -:103E9000485AFF971837ACF67B85E741778EA678AE -:103EA000A22E4736E90FDDFB8DD358BE2A2E9BE2AA -:103EB0008875699F53725797F5D43895BCDC351CCB -:103EC0007C3C301576D7BB9B73B2DAC3F4127DAD60 -:103ED00095ECA6596B9229AD8C76A662BFA85C635F -:103EE000F6611FFCF4DEFEA9A361875F6B4D99C2EA -:103EF000BBFEF47B23B25831F2E5941EDB10353B58 -:103F0000DC9EAD525781D80FEAEE3C42FBD719D365 -:103F10003BF1B3B1CED6EE8E4748CDB2B5EF8F723E -:103F200072D5A3D5A20F2A401CA1D6BACD09BC399F -:103F30005B4B608F1E06DAF5EBD11396AE2DEF0FBB -:103F4000FB57EDD7079FC4FEAEAFB1A642CF3CF9F9 -:103F500001DFFF34DABF483F3881F8E314F8AD627F -:103F6000E97EDB098D79E1BF5962DE5FE234ECA7BF -:103F7000FB66028E5762F46105E4A70D6C4BC3F833 -:103F80001E3FC54BEA6BF2127AB397A874C526A1FF -:103F9000BF6D53F65A69D785DE8E3CF4763885A01E -:103FA000B7230FBD1D29F4767CAF90F6FA414D9DE5 -:103FB000A53877FAC7B3827ADA5F1D05D0CB576B85 -:103FC000311EC89BD59AA73FEC606C4BBAD85723DB -:103FD000E8ABD22B3BB96E15C6EF575FB0B3F0F824 -:103FE000B1712CD1909F604F37D42F77BA0DE5D7A0 -:103FF000A40D31945FEB2A35E4AF2FB8DC50FF06F7 -:10400000CF3843FE3BA3AF35D4AFF05618F2D326DA -:10401000CF31D49FE1AB3494CF9ABDC4503E475FBB -:1040200069C8DF54F33D43FD9BEBD718CABDCC698B -:10403000C1FEB60FE7298EF7D7719EE2E9EA5FE588 -:1040400039C2E93A7682A9BE377BFC7725FF6E1A22 -:10405000E25D09FECC94F74032E57D8EE60217F171 -:104060006706EEEDD379B62D1D7C13592FB27C6C0B -:10407000EC81F32E4EC33F6C9F39DDC2E5C3D8CB34 -:104080000E0CCFE1F9A421F74FB770B932F68A03CD -:104090002F65F3FC80216F88F26107CEA3FCFE211F -:1040A0000F8AFC3446AA45F690F1D3FD7C1E63AF1F -:1040B000CE5EEF11F6905EE32D550A3C206E11782E -:1040C000401AE2FC89F400E74FA487387F56E732B4 -:1040D000F626E74FA487F9B912DFDFE2E74AA4EF3B -:1040E000F07325D277F9B912691B3F5722FD4DE3D2 -:1040F0006C4A3F68D4A9DD7F34D6507AA4B19EBE05 -:104100007FD4D840E9EF1BFDF43D50A0EC0721B26D -:10411000B3287FD272F8F16087DB6B3D1DEE6755E7 -:10412000FE40E5FF6BAA67EDB158A7ED96C4CFEC52 -:104130003D7EBDBEE5AC857D16A66FB5C67A9F2BCC -:10414000203BC94027C96BF97DBC362DB38CA77FB6 -:1041500071E93B41EF1965556B13DCB807526F05E8 -:10416000BF7C68EAFD5E707381B03FAC1AE2DD434C -:104170007C22FDD8CA8FDC1D9F12E6E73685C5C5B7 -:10418000D05F587C8BF237AB789AABEC223E4FF97C -:104190009355DC8CEAAFFC02237977E53A0BE927EB -:1041A00071161642FF2A3EE64A7BB014F10257D63A -:1041B0003A280EAD3FFF6E2BA37A5E334FB7FC99C2 -:1041C000D72FE9F15FF797F0F37282BFFC824E764A -:1041D000D72BA5FF1EEDEDA2DC8FF6889D829EC138 -:1041E00053B2AB3D8138A7B21E7F3AEAC78AFA21A3 -:1041F000F497FB9F7CBCF89EF59399142C453C5595 -:10420000E67207C5536D1E17A2FB5B2BDCFAA7A055 -:10421000932FCAF9492CAD9F9C4CD8092AA4DEFBE8 -:104220000D74F81CED147E149E155D147EC3E28E91 -:1042300008AF7DD129923E917451F428BFD0836795 -:10424000E0E9623AF4D009F6D8FF2B74186109D27C -:10425000FDBFA85ABB07707D1B5D6EE96493709F1C -:104260007870B6DE0C3C575E70BD897C151B370933 -:104270005B932AF77C4BF92C94F7EBBBFCB63ECA58 -:10428000DF8E56F1085E4729A7CB04293F56970BCE -:10429000FC4E769B09BF138A16933ECA1C42AF732D -:1042A000F1FF204F267DE56B467F93528CFAA1F2F9 -:1042B000075F27FB9B1CE107BE4EEA8DD745E885CB -:1042C000A38648BDCFCDDCE2DC27EEB94F94FB746A -:1042D00086A4730E3FCC8F051D996E81D03A847BE6 -:1042E000EE25B807EEA7FCB52C40E9F52C44FBD62B -:1042F0000D5CC021FF1DC6289EF160ECD4792B789F -:104300007F13864FC8C5F7B07B7DD70CE947F7FA16 -:10431000FEE00CBBD77760A28BF48603F61CD26359 -:10432000B00EAC6176B45F72B98F5086837C5F400B -:10433000FA06DF17723993FF82EF0BC85F57B0861A -:10434000A1DD249731DE44B5BFDE399E5986F72DB5 -:1043500077AF2F796520EC2B6F270E9E08BBF3DB20 -:1043600089974DC47CDF4EEC6F1269948DD2E29731 -:10437000737BD3B3141FF68C378959922FC6AFC203 -:1043800067241E157EFF097CAEEC0D9FCDC001ECAD -:104390007AF6F7E3D3B2E1FF12EBBFEEE5E2FE807F -:1043A000FF2440435CB25DE025D2BEF379231B08B5 -:1043B000FCB22D09F4FD36C94357368CA1FA5735A6 -:1043C0008CA6F95D11A3DF35848F73BA2C94CF3599 -:1043D00007F6F9E626BA7F7BE605B307FA77ADD98B -:1043E000B5DE83B5FEB6B82FC7BE3A98057F1BDB96 -:1043F000D27BDC6EAD5DE1CD4FF8F4667B9BC5FEF4 -:1044000027EE11ABFD776094887755F759FBDA8F6B -:1044100047C508B932304AC8414527DE8EF219BC7B -:104420009F515C6E643C1843FAF78824EF63C0A781 -:104430003A4723BE09FBD455A1C204E427E33CC993 -:10444000F36FC9FB696F0DAD4FC9E6F83E68D39FA6 -:10445000413B66FECA8C75DD94A7D13DF7AEC339EA -:1044600029C0F756B5EE4A5849F87B034A3FEE1E7D -:104470002FC54C7EF155F08FA6E0DC64277BD1552B -:104480002C9FFCA613E5F8E5BFACA27710D4BD8F36 -:10449000A83493F1FD1C578CE13D98D88224433E0B -:1044A000CE33C0503F6174B6A13CD13BD4509E3C4A -:1044B000B9CC90EFE71B63A8DF7FF678E3BB6EFA19 -:1044C0007586FA1935371AF24A7E65884F2CB37E05 -:1044D000AEA1FDA0860586FA6EFF52E3FB367E6F25 -:1044E0005B412AE49EF8CB59B7CA50FEE37871AF1E -:1044F00061B26311BD5791D772BB717C49A78C041F -:104500004127E612F2D5CFFF03DF94A719E5ED04AA -:10451000A7F1BCCDF5410DFB7B46BDC5F0FDD3FF3A -:10452000219D23F1D2C5B7A610EA431FE2F9ABF4EF -:10453000A10FC2AE3131C5EA0930614F0F9F17ECB0 -:10454000E9E178803D3D3C0F7BBAF15D2823DD61D8 -:104550004F0F2F1F7ED848F7916D46BA5F76C4483B -:1045600077C58F91F4B9BCDDC80F91F4B9E244046A -:104570007F487ACCE6FFFD5DDC93267A4D7268ECCD -:1045800071F73F4F9FD4A19C3E853DF4F9EF0C3D60 -:104590007D683FDC4F3F9F6503BD3AC57B7D2BA502 -:1045A000FC54F184FCBC2BEED3DD6E26FFFE515390 -:1045B0000BBD9774C0A9BBD1FE96A27A0DFE8334C1 -:1045C000E6DBB988C337FFDFA3C89F307F90B8D739 -:1045D000C98ADA29CE5EC9B9F919228E65C850791F -:1045E000BEF0887896A2A1422F8CF33829EEB5B29E -:1045F00048DC23E0C782ACF9C5E09F77A2F16E6189 -:10460000D74661BF6FB78AFBA57ECE47F08B414F7F -:10461000841E9729F5A8A6DFD9ED807FF02666D8FD -:10462000178704EC86B8CBC2ED4E43BE389866A817 -:104630003F6CAFCB505E1A2A30940F3FEC31E44709 -:10464000B68D36D4BFEC88D790BFBC7DB2A1FE1525 -:10465000277C867C06EB7C0CF81DA489F368F5505A -:1046600011C7C3D710F993E6DF9328EE0FCA73AAD8 -:10467000D283553CAE2EF92E529F1E64D329BEB76D -:10468000299D79E81E805D9E4F9851CFD6653CAD3F -:10469000D24799DF184FABE268BBF571A97F2B7D3C -:1046A000382C8ED61B1E473B5FDEF38DDCF7EA25E8 -:1046B000DD23E11F6413F36DFA9E8DEE2D28B822E1 -:1046C000E1F99B8CEFDC6AEFFDFEC89D4385BFFDE1 -:1046D0009739BEEF825F9F84F8C8E96D3C4FBB9F5E -:1046E000F357D30F6C9EBB5CDF3EDEFC61623EF392 -:1046F0004CA65B2A8A286E69F6CFC2C6FFA11C773A -:104700007591D6EBFCE62788B822966073817FFB13 -:104710001E4FE033CDC69AE99E8B8C3BBF797DF06E -:104720000198C8E7D95AACE2FDB28015FC30653C6F -:10473000D79F4A61B7FAFA2107D7339E6CB0901D14 -:10474000E2E1A137CCF0E7F6DC2318C4CF17E00F85 -:10475000E82A3897D88B44DCEC9EA162FD979BBF7A -:10476000EA8EFF267B3A63527E8B734B2FFC467C8E -:10477000A8E6F1AF8E038FC4933A1732B9EFE44A3B -:10478000B814FEBACFF1127F2A1EDFB5D2EA7BDA67 -:104790004171FD9311CFA4E837B048F0E589A182BB -:1047A000DEA80779D457BD72735102ECB55DCC9584 -:1047B000E0FC067BE4BF0A2F0AFF7DDDEFE94B3EFC -:1047C0005C2417FAB8EFD3177FD2DF3F70EF274C86 -:1047D0003E88F812498F40AE89FCB9F7C419D771E9 -:1047E000FF4281DF7D6ABFF0F3F3A4514E30D897CA -:1047F0009BD69AA59C10FB2AF40D7C5FB8D64AFA8A -:10480000066B10F1C835521633E64B1D3302FE58C5 -:104810002BBD67759597913EB2C0610BB4F2FA95C6 -:10482000FEC87DD54BEDC95FE3C2BB259EBB617F52 -:10483000AF5A67ACB7D821DEF55A18712E5D2CCF70 -:10484000A58B23CEA5D185725FF6300FE94DD2FF3F -:10485000ACE0ECE6AB400EC505E39C6A16F6128AA6 -:1048600057EAB6E3C3BF10F68E26C7674C01F6EDD4 -:10487000664BAF7164DDF8ECC34F7E1A7E7217D6BB -:104880007F17DDFFE9DA152DFC68CA7F21EB9FF663 -:104890009FA772D4476F674ADB4AE047EAF677443E -:1048A000F84DBA1CA6F8D1E86F87787F41C5012C76 -:1048B000FD6BA0C419E6E7D4DB4D86B88BC8545F06 -:1048C000B39BE2025A2D7A59219FC7298BC78EF7D5 -:1048D00022EF751C48C57DED29D25E13096FB71E06 -:1048E0003A56137E42BFD043BB266BA48772B9C829 -:1048F000B08E943FBB828552902AFF81BE6E34E118 -:1049000059F90F2A43A309CE194D8BAD78B2AFFDEB -:10491000B13BCA635C3D7E85F64C118FD2977F61B7 -:10492000DA050FF537FDC218EAA7A2D02DEE7135D2 -:104930003FB0127C34743BB3629EED11F1D82ADD96 -:104940005F28ECDF470B95DC96712E6B34A1676B0B -:104950004CC5BD90DC56F9F32D325F2EF2ABD78AF1 -:104960007CBB7CC7689BB437609E48311F9C8B77AB -:10497000487B04E68114F3C077C829E421A7908717 -:104980009C421E720A29E414BE2F60BEAC52B3F0E2 -:10499000834C0C5B37F0834C0CD383E00709CFC307 -:1049A0000F125E1F7E90F072F841C2CBE10709CF73 -:1049B000C30F125E1F7E90F03C1B7D6D4F1E72CDAB -:1049C0005B61C84FE3FAF8C4B0750B3F4878FFF05D -:1049D0008318FAD3571ADADFC41A0CEDE10709AFCE -:1049E0007F4B8366F093DC22EFA5576D4A22FE9839 -:1049F000E3F6FDB090D3F70FB15FDF66C539CDBCEC -:104A00006F099D9FEA623C82CE2D9305DD4D4CD00F -:104A1000B9730ED1F90E9BC8978BB8D8DEFC0D1375 -:104A20007385BF0129FC0D48E16F400A7F03DEC397 -:104A300086BF0129FC0DF80E7F0352F81B90C2DFE0 -:104A40008014FE06A4F0372085BF01EDE06F400A18 -:104A50007F03BEC3DF8014FE067C3F0ABF476E0F94 -:104A60005CD0DB730DE73BCE8786F39DD39087DE6A -:104A70001E5E1F7A7B7839F4F6F072E8EDE179E892 -:104A8000EDE1F5A1B787E7DB86BA685D427F0F6F7E -:104A900007FD3D3C5FDCE27F0336A61B369F3D846D -:104AA000B43D4E7B52E3A2E0BDE78ECD80DFA83D52 -:104AB0005ACB4AE44BDEAA9D9C3191EB67BA8C2F0E -:104AC0002B619DF4BEB32EDFADD1438CE2618BFF31 -:104AD0009226E482BA37843F4EF7D25D8CCE011520 -:104AE000723F55ED3DCC6926B925EBF7E47BAF1756 -:104AF00039BEAA47F2320C0E7E402C451C44E91DFB -:104B00008E32C4716F3369220EF22E11871AC95783 -:104B1000E6222197B699761E88415C4BA546EFC5E3 -:104B2000E75BD861BCE35DDC525F067DE15461A2C6 -:104B30009C57FD18C4C528B8951D90CB09BA5735A8 -:104B4000B693D9AA8BF09E18B32D847CB7093D018A -:104B5000ED707E2CF46BDEA7C3F8FBCF85627FD3AC -:104B6000FD2BC754F3EF853BEAC7E0BED69418D1BE -:104B7000EE274FC5131EA7366B4FE35EDCD81DCC66 -:104B80008BFB975F4B795AB8C369ABA6719D74CF05 -:104B90004BF55BB9398BEEA555B2F6896964CBD775 -:104BA000E81D7385373EBF43981F17F187ADA48F6B -:104BB0008AFB2231F2BE88BA27E2B6F8424347F6B2 -:104BC000DC17B972446239E2B5D83EF1EEDE0D234E -:104BD0002AD7F6E3FDEB01F1EEDE957FAA7F83F2A3 -:104BE0005BC4BB7BC406A3681CDAD706FB357AEF2F -:104BF00061AABFD594E2C2FDD135D654D4DFC13C01 -:104C0000507F0633710F52C157C4DA4C78779C6FCE -:104C1000310793C3F8884B80E9A07BA9C74AEF41CD -:104C200054589C56C88DC87DFCE278BA083D2122B4 -:104C30001EA2E98E2359E66CD87B4C9E10E4D6EE7A -:104C400058D21794BE5329E3A0CE37BF41EF59572E -:104C5000EE14FA81CEE500E49F8A8FA8CB0964990F -:104C6000A02F0C682D49328BFDBF08F791FC2FCD8A -:104C70001CEDC23DC637285EBF72EDC804715F47A8 -:104C8000F81FAA259EAA65FC0B2B72A642EF54EFD3 -:104C900098969BC726D07DB716A1CF29FB4BE5AFD1 -:104CA00086BF093A573E21DF03595749F78022E36F -:104CB00050947EA8DE3B59D26CA5F89625117AE077 -:104CC00032A9072E8BD003AF2B8AD003D5FB74B249 -:104CD0004EE5AF0ECE203DA55EBCC7376F8DD05BD5 -:104CE000D84EF18EFDBC35134C78B762DE6EAF47FF -:104CF000EB853FDE93FACB140C9A8C389F0194CE4F -:104D0000BC9046E9AC0B052407701703F46F7F8550 -:104D1000913EFDBED4576620CE0FF7E3FC51329E84 -:104D20008F91BE54CA9CE5901B43BDDA4198AFA752 -:104D300058F5B588239CD2CAE83ECC0DD06B78C11B -:104D40006CE839C3C1E7EE72BA173059A3FB1537C7 -:104D50008C5829F99AF339039FFB25DFFA28DFBD28 -:104D60001F48FED6FD1D167A97D5AFD9F02E9B2E83 -:104D7000CFB38A7F23F97CBEFCBD09E61076A66E10 -:104D80003B1480A5C755AE9A097D713E6C7703240C -:104D900021398AE28A447973D155339B71B8F91F5E -:104DA000DA27E6A9DF61E07A16E4E9CDB796DA16EC -:104DB00084C9958A92F1CF14F7EBA1FB82EE7B6355 -:104DC00045FDA1FFAFBA37AFFF37DD5FACE278C674 -:104DD000FA989FD07E1B5EC6DD52C4BC1347E33DEC -:104DE00066354F1642BCDA5C99FF75D1E2FF585721 -:104DF00044F8A17C60C794997E5A2F425EDD047905 -:104E000065869CD29F2CC2FD0E7BFB24D023B6A8C6 -:104E100053DE8797FB51843DE2D745820E91768918 -:104E2000AA2221C799C5957513DD5375915D4FC1B0 -:104E3000FFA9D5786F50A5BF54FB48E3BF26DEFE1F -:104E4000CB54FDE7901F8F98C4FDED01E61626EDCB -:104E500043E27732E4FA61F23D831EFA73A901FA64 -:104E6000DFAB39C3E9AFAFD3C4BDE93EEC38ACA08A -:104E7000F3B1ADB0E3358ADFE7782A5FF0D153B7FD -:104E8000DB48FF9E676B7B03EF34293C7EDCF0231D -:104E9000ABF89D97501EDE9F9A5B1F4DEFBD569459 -:104EA000F8DA4097D8220FD1E319C494F2FAED4E04 -:104EB000DFFB984FDDFAFD4FE2FEF88A7D6EBAD730 -:104EC00058B9B7F46EBC6B5151A21F4179A5C369A3 -:104ED000C3FEBDBC3991F6B3F9FDE5FD42D6497E6E -:104EE0002A85FFCE2261C7DA5622FA3F27CF21104A -:104EF0009415867A32AE38629D28FB60A49D21F21B -:104F00003D81BED68FB227C07E600BB32F2AFB84B3 -:104F1000B5E0D339D83FE7D98CF7E154EA2E96E7CC -:104F20005C790E5CD8BD7F154DEA0F7D798346BF55 -:104F30005B53ED70CDBA9CE7AB0F5B1129C8A6247B -:104F4000B9C43B12F78A772416F0F50A79334FC6B5 -:104F50000D556F1A4DEBAD3AC0D3E4BED7E54D1BEE -:104F60000E66BE02FE0979E99E78B5D36B4B0A5BEB -:104F7000F7552D9AE19EB9CA27160B7BDC3C3C61A4 -:104F80005E0679E1B6E12D97795CAD401C9ABBD8FD -:104F900065F0BBF27A14C730259BBD29DEF1E170C4 -:104FA000BBC5786561FD2F6831DE97E7F5C5BB1499 -:104FB000C571D45FA593CF1BF60FA793E0E47820CB -:104FC0003C753EC0FB73D138448FAA50C08AF3F6BB -:104FD0003CC44FF0FC5C67C08A7116348B772BF4AD -:104FE000F5621C7D5DA2AD18FA92C569CB04FEE4A2 -:104FF000BBF61C3E9283D51C2FB8FFA3EE0146E200 -:10500000A752C25BDD9268D4C35A3658418F397DAE -:10501000DC9FBF41D27D41F338BAFF5C6DF1527C19 -:10502000BD2EF1FBC795D1F7C13F3067E3A35637DB -:10503000CF5F592CF8F70689D729D9A13C7A9F660A -:1050400065B40770CE71B6D0FCBAF1FB30C7878665 -:1050500077507C845FCE177EC491556F34D2B307EE -:105060001E81DFEA8D95B4DE1659749B331C8E4D7C -:10507000FBF370AF670E5FDF7877873975BA6FF330 -:10508000D9C3B3B2689E1C4EE035CEE39A84F7666E -:10509000389F101F2B7E51F783D5780B8BC53DC1F0 -:1050A00085C5BDDBD77BD6A597F49B264E5FD8BDC3 -:1050B000FB5A97365C34E2E3DAAAC53B6091EB54C5 -:1050C000AD4FB52ED53A55EBF749AB2F94A6F5C8A1 -:1050D00019BEDFD6FFAC173C3D23E19D2BE9CAF199 -:1050E0007A28FC5ED1FA62218FE6651BD73BFA4332 -:1050F000BFB7ABF2F1A13CDC0354F5D5B8F3E4EF54 -:105100007481EFC16FB74BBAA3FE2AAA6FBC1F51BF -:10511000D52D2F76AC4D85BCD8A991BEBBEA818335 -:1051200099FF063DF679A1C79EAADDBA3C1D76031C -:105130004B202BFC7DA6EA90900F0BB9FE0379B1B2 -:1051400048EED3D7E4E9F7168F0CABF7D0F3F9BAF2 -:10515000902F21C897DF3FFFEA87635C3DFBA78262 -:105160007FC1BA5F5B2B1DE1F8127C7E5F4117DDCA -:10517000FBAA72D85C88B3AD6AAE2479CBD2F87939 -:10518000420B8B938AE083CA668DDECDAA6A18151E -:1051900030FF2FCAE5AAF515F4368FA2937A7F4324 -:1051A000EDA70AFE1D12FEB9928F5F94EB6F6E8D14 -:1051B000DBB688D6BDDB5605FE97E573AA8DDFBB4F -:1051C000E9D4ED672EBA3B4DDE63A173C97AABB06B -:1051D000EFED88237DF5D4AA97DF9DC9EB7DF148DB -:1051E0006B16F41305C76269C75B28ED718BA4DEEB -:1051F000CAE9F47A71989C5DFC94A053D50BBFFA70 -:1052000004EF43CDCB96F2EC0171BF7C417027D106 -:105210006DCEBA0D5637AFF76EB1DB20A7ABEA4BB8 -:105220009DB04FCF5DD76A851C78B758E02D92DFCF -:10523000E7C9B8548557EC3B5A98FF42D587FCDB49 -:10524000C9C7B97565743CE232D438FF25F9B8AAEC -:105250003E3109E355D557FE10E71E25EF23D7DD74 -:10526000B168B11E16F0FEB02E8F8DF3D03DDB7904 -:10527000F2F7A522EB9F9574FBB155BC2398111B47 -:105280007C96E20A56C478201F7273DB031817FC61 -:105290000CB86D26F1EE606E6DFB978083ABC51484 -:1052A0009F8214EF1D414D4EE5F9A74DE23E10627D -:1052B0004B90A694087E80690AE52CA59DDE3F0BE5 -:1052C0008BCF34F0AB8D6D5987F7576C298C7EEFFF -:1052D00045F1A7EA47F1A7E2DFBEE6E728B9B4F94E -:1052E0001D734B3B4481270BF728E63F3898DEE7D8 -:1052F000FFB679DAE43B78DDF38D12BF5B70D17CC9 -:1053000073C5B9A5EFF96E2C4FED65BE91F354EB63 -:1053100044C55E77FB155A845FE198C6F72FDEEE31 -:10532000D8CA688AFB52F35276EF4B8D97F79424D4 -:10533000493B427B1CF4C879F2F7205848E4F1BDA0 -:1053400022ECBBDAF7D5BB614A3E1FAF97FB226B5D -:105350007F00EB9935E4D03B19475B8EC5E1FD8EAC -:1053600063E3047CAADDAD5671EF95C5D95C783F47 -:10537000919FAFE8771F1636F7A773E4CD0D392458 -:10538000176EF6270ABB83D4EF174939187B6BE5F4 -:10539000DD97A1FE26B753E3E32C74783EDB44EDA2 -:1053A0000B3DD007633756D8B249EF15E700E50744 -:1053B000BA55633EBACF043989F565DA9F8B7D67AC -:1053C000F126710E986262EBE02F1CD4E49B940EE0 -:1053D00039F1987837926D36BEAB7420CF777D095E -:1053E000F016F11ED9ADD6A0B73FE438D7376067C5 -:1053F0005AE8F091DEFE969493473776D0FBE40AA4 -:10540000AF17DD53B1897BA99D7126B2BF5DEA7DDF -:10541000956AE94F527CA3FC518FE3FF2E079E4C07 -:10542000B4AF959BE7D1BB3E776F9C4069F586F2A0 -:1054300047FCC5B80FEB4B1D43705BC93E565D374B -:1054400041DC1F7D3A2A11E79B2CAB3F2B5C2FAD33 -:105450006EBD87EEA99C688DA67B2A139D1513133C -:1054600053E8BD5DBAF7A5EA7D5FAECBA575130C19 -:10547000F74C16F23E1107FBE7602CC595AAFB23FB -:1054800077C6E8DF2DE927EE915CEE12F747D2A947 -:10549000BEAB577BB84A3F6B14F711C2EEC54C9DAB -:1054A000C3DBD7D6BD148F7E963DFCFE288E19D85F -:1054B0009FEE02DDBAEFC56C12F7629A705E821E33 -:1054C00099E49B3907F8FFA599F0DFD77835F851B3 -:1054D00092B073C4CD8104D25BF510B3C19FAC3BD5 -:1054E00019E9C527CCAC017A80D25FD4F747245E96 -:1054F0004E24B464813F966C7B340BFBCBC938914E -:105500009FB76DD65B9057FA9628A19F5B18E9C3A9 -:10551000557EA15FB39A24F52E66F47CF8634B6246 -:10552000C53B3CF2FE8C824BBDB77AD222DE8BC1EA -:10553000BD18F0FBC796D042D0F763AEBFE21CFBAC -:105540007D29C73E6E31D3EF8EF8F942811EF2718C -:10555000CB4B71B89FABF4B572F3EFBD788F66D5C6 -:105560006E714F15EF9AD39B95D20EB25CDA41560D -:10557000BD629D84DF1DE1FA177DA9B5846CBDD1A4 -:105580006FA9D4AFBAF3BB76D2B9AD7687D01F6A14 -:10559000831DA43F287D44DD8B5BB6A383F409D52E -:1055A0006EF92E8197BA5DE27B25E2D6E5EF856A3A -:1055B000B9384F6B94FFA468C1AC3596F07C25E5F3 -:1055C0003F2952F6914ED207EF2BF80D9DC3EB9A6F -:1055D00065BF3C6F0D1BEF0D30693FF13DC781F694 -:1055E00062DF57E575BB12A97DA82E661DF679EF1F -:1055F00072870569539D83F6FDCDF5A602CB0800A1 -:1056000017E3811EB74FC66FF55BF61FD1B01FA41D -:10561000B3CE8378F7F580533F027E55BF67A9EE7E -:10562000BD9C7BEDF3E1E8FFAA41EDE7F1C6837590 -:105630004DDD2CF827DA4BE43C8ADA8783AFFB1D7B -:1056400010F2F9092B5B47EF075B7C0C76FB90F4BB -:105650002BFAFF6212BF2FA1859E09D7AF52860990 -:105660003DDC1725FC8B5EB77E12707C47B3169726 -:10567000E24CED32E7A17FF53B2A4A4F1D2FE5733F -:10568000A63C5FD906A439C0C79AD74BF710EF2ABA -:105690003A50857DF9FE4E3BFDBEAA8AC31BDF1939 -:1056A000437A6BE680C9B49FA97B29078A4C7EBCEC -:1056B0007B7E3FB38BB8007B845E6B8AA678646D7B -:1056C000DF2FFE02799E61FEF2207EA724E3DF3405 -:1056D0007AFF727ED7674FE03766E6B14029BD8317 -:1056E00097A89B86410E774DEED039C9EE7706ED2F -:1056F0001EB14FB070F8F77DEF2FF149A61EB8CE5E -:10570000757E46EF0A9EEBB493BD76FC3EF9DE5EF5 -:10571000043CE7D25C1417CDEB85F0BECA3987890B -:10572000DE191BBFEF20BD9B375EBDAB6737BEAB3D -:10573000C7DA3213614F261B2A570A529B04DDAE8B -:105740004A309E13F38689F356DE30213F14FEBAA9 -:10575000EC67DFD6B59E75B842F9EFD5EF4DD5446D -:10576000D1EF4D75EDCBF9C6F713DE87FEC0F5829C -:10577000F5D9DEE261FD7AF6CF19122F6A1F36CB1A -:10578000FE6748FCCC7098043E227E6F43F187A2EE -:10579000BF8257D157D18DDDDEF606EE05717A1541 -:1057A0003FC8884E97119DFEF2CE5A5CF31F60F6FB -:1057B00076E8EEFF8B740A450F869EF0B0F8FDADDB -:1057C000C8B84656C0689DCF37C7901D5097EF8226 -:1057D000F3F5FD06D6B75AD78326B717637F3CCAC1 -:1057E0008FDE80ABDD14A4EFDF1D26E20907B2B621 -:1057F00074197F33127A59937CFFB8FB770C973872 -:10580000E8BD917301F5FE71E0B1457CDC8D338A12 -:10581000C8AE7F8EC9F55ED3FD4EB678FFB8FB9D4E -:105820006CB39FEC247362C8CED3FD4E769E78EFA6 -:10583000FA558DE5E31D5A7F859DE2E323DFC9E636 -:10584000FBCCB3F0673C5E13437E28F53EF278A7AD -:105850005E0F3A46BE8FFC88E69BB310FD153BA851 -:10586000BFF639312F6C13680EC18E73B4218EDEF2 -:1058700085567CA9ECD783FC1D8F014FEA5EE71F9C -:10588000247F29BCAB7B6D0AFF8ACFFC5646F73FCD -:105890004107BC2BABDE67D7EE907243DD277CDD82 -:1058A000E342FA40A2BE0E7037ADE47283ECE2ED43 -:1058B000B761BE4F7C2FCE0BB88E9A8CBFDFABD2B8 -:1058C0008786990CBF133A5FEE57F355DC7F83311F -:1058D000EE3FF21DCDE404DFC3C378FB33DAFBA354 -:1058E000F0F19DFF36F71A47F2A45CFF2362F5271B -:1058F000505FDD7F50FAE13BA59F67D2EF8D7C754D -:10590000907E5771AED31740BDE85CE10FF8437A43 -:105910003BDDD7F8C39CBF66923DF90EF1FEE7A5CB -:10592000C279F17D5AC10FAB178A78C30C564FFC70 -:105930009BD6734F331A70FCFF769FB6E7BEEBE43D -:10594000E1C729EEC247BF5711498FB151075E72B7 -:10595000F193CA6F877D318BEE93261C58EDE6F9E3 -:10596000A32F9E15F98C03E7DD9C36ED2F9E13F9CE -:10597000C203E7711FF5D3173B45FE0A46FEACE3B1 -:105980002F7E390BF74FFBBBF53F825E332FD4BF21 -:1059900081EDF5C335372E74D37DCA8ACC02719F51 -:1059A000F26394CF485DB03641EBB94F69F2F8FE2F -:1059B00008BE3DF7A5E06F3787157CF2CFA6EA3E1B -:1059C000A992B77DC945B5EEFE55F761D53A66DBBC -:1059D0003CEBAC6042FF3F7D4F9579F8BCFE1F9BCE -:1059E0004A017000800000001F8B080000000000CA -:1059F000000BB57C0B7854D5B5F03E73E6994C920C -:105A000049C80B02E104420C18D299BCC05BEA1DE4 -:105A10002089015A1B6CB52018068D90D76442A8C6 -:105A20002DB5D80C0611A8DE0B5754B068274000DE -:105A300035E8A0012718EA00922252BF98FB37F2FE -:105A4000FD5FE10B3E90979310B557EF55B96BADE5 -:105A5000BD4FE64122DAFE7FF8DAEDDAEFBDD77B03 -:105A6000AD7D86B1B196F3D18CFEAEC98C1D3FFCE5 -:105A70009EA249646C4681D16A90A034772BC602FD -:105A80000EBB01DE7595F935B1BC9F36B45FA2D768 -:105A900066C17E7566EA973908FD72B1DF9F476B74 -:105AA000B1BE416F356430F6B48EB94D098CC5680E -:105AB0008EC8B84ECC2063CDD07FAC8131631E63DD -:105AC000297AC6B01DFA312394BB06F97AE3121A7B -:105AD000563098675C85D9DA9C81BBF53056C8583A -:105AE000DA28FF68DC5FDA4A3DD5C7687A94063366 -:105AF000638126FFDC0F33192B8E8ACD653F8052E0 -:105B0000CFB2711F4C13656D85F54AE4AFBAD20070 -:105B10006EEC906CB0342B36946F671319ABD702D0 -:105B20009088FF33795A711D6D77F51EE8D7939CE5 -:105B300066DD08E0D8D4832C331FC6BBCA72D804F4 -:105B4000C68E5A1C39D62468679B241C1F9DC3C768 -:105B5000FFAC2C7A870CE3FB0FDF54E880BA3B0CD8 -:105B6000CA0166652CDF3B7A81F61680E39442C950 -:105B700002B075EC02ED688053940312B41BDDA3F0 -:105B80001714DF82E7335A3ECC66EC174C62718003 -:105B9000970CAD63BA15CEEB2CFB44CF34D83EA0A6 -:105BA0002F9F0AF76A854960FDA4A3704FB0CF818B -:105BB00039319E1D703E96A314627BBA6E20D602C8 -:105BC000F7D1FF95B6CC63A671B13F87FA6BF8F7B2 -:105BD000AF8C3DD72953BD0AABE5375689EED79533 -:105BE000697E0CEFAF3ED568A4B2F36A29C379B4DD -:105BF000E59977C03C763D5B529E73FDF801AB861C -:105C0000F695B10E103A86C8CBCE14F8BF28A6C2BE -:105C10006E369DB1965F41C5BFF0763809D34FD23D -:105C200008F896ADC5DAB0FE76EC1F6C6776230BEC -:105C30008E775AA76E5D9B29D6433C2F639E497091 -:105C40008434D62031B8BF54E627FCBC644BA07323 -:105C5000D11FE0E9D94453CB46A45719E8328F4A03 -:105C60006681322D1AD683F6B4374C1EA4AB5D265E -:105C70004EB7991A5EEED2F0FEFA28E6463A1D07B4 -:105C80003083F26D9BE377B6249AC74FF3C8FB6D60 -:105C9000488FA39997D64F616EDA8FDA6F2CEB3667 -:105CA00021CCB40359844F5933EC7D26D9666E4616 -:105CB0003A0B34D9D947DA607D203A765528FEEA86 -:105CC00071BC3974DC2C1AA78E77AED2B08F46E146 -:105CD000E1FD443FCE4C8DDD9383E3D89B521ED62D -:105CE00077EBCB6382E37A9B8CEC23B8D7FFD3C4EA -:105CF000A83CDD64A1F5FF6F532A957F6B52A8FE87 -:105D00006C5336957D4D56AA7FBF693A95772D8A9B -:105D10002940FA77F966B28F8C42CEC0FF9C5E9D17 -:105D2000A32F04EE9D393C1DBD26E8A83763F8F685 -:105D30006E6C077CF6DECAF1D97F3FF3ECC820BA5F -:105D40005C6B49B81EFF30C284E7EB8F610BBC70FF -:105D50004F6F1748347FFF680EEFB7EA683EBB8687 -:105D60006DC5F16F17E8F9FC133455D86E4FE0F3A9 -:105D7000F666010CFB59307DE6CBC897F664A8CFD8 -:105D80000BC2BD5378BB7D0CAF57F7ABB6FFCE66E9 -:105D9000E17428F0DEAF83F57388DE697EB5FFD746 -:105DA000459C0F23FB7B3235659E61EE23C1C6FB0C -:105DB000135FC07DB8910F3242F8A25E21BE50E958 -:105DC00050A5BF976CFC9E330D82CE4127D0FDA11C -:105DD0006E40F99A027C20D1BDD8199C679724F8AF -:105DE00025921FA04439AEF283CA072ABDA7019F9E -:105DF0004909C173FC28825ED5F2B495E3A53B390D -:105E0000E601C26BA7CE02A210FA03221310BEB3A2 -:105E1000C00EE34A1E35370C27BFE2FED97B50E5A2 -:105E2000C108F770DDF9F5BCFCBEE727F986721BE7 -:105E3000E9761879F5B53581F6A3D26D92CDFE5F7E -:105E4000483FFD92492BC54169E2741379FEB70BB7 -:105E5000F83954FA79C9C6B8BEC4734EBC5EDEA91F -:105E6000E7193AE77246722F338AD747E2573D5710 -:105E700088DC8BB11506EF93316E0F8C057B606368 -:105E800046907E03495F2E43FDB5CDAAD0FEFEA00D -:105E90009109FFAA3E19AA97E425F373C2F40CB343 -:105EA000001E070E1B88BFFD1A56F50A8C6B255580 -:105EB000113CF76D362E0F06174CD2AC827D05FED5 -:105EC0006E76A3DE0A8C19382BC1F8C0563040C854 -:105ED0007EB0FF584A66EC7ED029A897AE809C63BE -:105EE000598CC9DB3E3F2BC1BE976D9319DA350142 -:105EF00010DB328C733D19E331F2718CC1B83A3149 -:105F0000AE79EBA777217D9D07FA44FBE62353FD8D -:105F1000040676CFEC6D3ABAC765317A0FD61FDB2F -:105F2000FAC48945009F6F9714B4374A6533B5D7D3 -:105F30003C2F7B709D3A73E94509EC9C407BCB5329 -:105F40005150EFDCAB63261857DA2E59FD30FF7243 -:105F50006F0CDE0C5BB645F77E5F76506EDE26F486 -:105F600058D52EC90314C3AAB687B7D7EC0A87EB56 -:105F7000983608C3FCB36C318964FF4D6636B4FFB4 -:105F8000D89604545643723B92AE506D237EEC8DEE -:105F90005C1E33F659F21D4097F2E1CFD3DF377321 -:105FA00078BE80CF01FCC9E7FCFED57BAB1732FF82 -:105FB00093D1ACC00BE7AC3F6CB2B8E160F51D32D9 -:105FC0009D23E08DA37B7645F5DD4E7C7A48B6A017 -:105FD0001DB6C127BBB1DDD969DAA98173D61F907F -:105FE00018DA9F4E9FC1C3EFE9EA326C5FEE335976 -:105FF000146C3F6460328C0F00DE4C88C7717D8466 -:106000007FC42BDAA7F0F763A928887F19F19518C8 -:10601000C457F356BE9FF37B397E4AE5D55AC25723 -:106020008BC45242F0FC67CD8B43F8C27EB3B7FD00 -:10603000B50BF1BC0CF6675010EF32E1F93CE0070C -:10604000E7D51FFE28BDCF1CC4B70CF8FEAD3A1E25 -:10605000FA2FBF01BEAB987B1DDA73DF17CF69C87B -:10606000FF4964F79EFF03DABD31608F23E908FB27 -:1060700038A9B6F778222C589170D9B902EA27A529 -:10608000BEC232C14E90E21D8F225F9F9DF39747A3 -:10609000101D3D735FB4215D34EBFA5A9F860A7779 -:1060A0007CB41579B03F63FEF6D7609DE2842FD3B0 -:1060B000F723BFFCC96041727A42F023FE1901FF49 -:1060C0004EC6EF1BF0780ECFEFEC34F80D708FACAE -:1060D000BDC43E640F4C407DECD5A39C2AD10F5427 -:1060E000AC407B1CE6C375242023E4EBDACE3F9F53 -:1060F00096609CA424B2C5081BCD7E19E769D35DC8 -:10610000193A37CC2359FE42FDDA6C13E8FC1353DD -:106110007EA4A0FC695EC81C5113BF4DCE3392F320 -:10612000CF0A7F6544FB6F0479AFDA7DCC3D361E24 -:10613000F90BEF82F30F973BCBA733F127F842C05F -:10614000556BDCB146E8BCFC666B2A9EFF63A4B3CA -:1061500058A4BF53DA51B0AFBA5689F0568FF483C2 -:10616000FE15EA37A8EFF70A39F27C77F1A8442C3C -:10617000252B702AABEE94AD7E68AFF6717ABA8E9D -:106180006E84FCA869E3F2E33A3A6A0338C44EAB82 -:1061900047BA5261C0F7C9A0FC987A0DF6FBF234F9 -:1061A00026F4955BD05B4E5C1FD0CB2053E22C399C -:1061B000217A4BE2F6962A576EDA0AA23E64DDC9CE -:1061C0001E23D386AC7BF35E4B183CD59B1AD6FFBF -:1061D000073E25ACDDE6CF0E6BCF3F610D830BBBD9 -:1061E000A787F59F76DA1E06DFD25716D6FF8717E8 -:1061F000CAC3E0C11C38CF3076C7901E4A95C2FA98 -:10620000CF514C61F3CFCB8E0F8307CDE27E841D3F -:10621000A8DAA75FD8B81D1459AAF7FB136BF83A90 -:10622000AA5FFCD3E9E1EBCDB787AFF75DF1B21B15 -:10623000EC7E2DD8F57B413F62F902D8FF5AB0EBD6 -:10624000DBC0FE47F825B0FFB1F482FD8FF5AF80CB -:10625000FD8F703BD8FF081F047F05615F531995C0 -:10626000879ACAA9FE46F7D725D63D21D63D29D61D -:10627000FD47EF492D9D6593345F009FCE4CB8A834 -:1062800047396C6FEC2BC538C0C05B32DB810CE248 -:10629000F09C684A447D348AA1DDC2CA07DEC63854 -:1062A00045FD8189968D0AEAA1FF7C07DB03EDB2EB -:1062B00082F2FCA8EF83589CE7CA17C087F938EE32 -:1062C0008358F48FEBBE64046F847605E039FB419C -:1062D00030903D03720DFB67AAB047CFA02C6FDB57 -:1062E000AF477CD4EEDD4FED6F7975E1ED7B5BC29E -:1062F000DA2DD81FCA5AAD87FCFB4B3E753E3FF5E1 -:10630000AFCB94EC68175FDAFB9FC9CBB05FDBBB08 -:10631000C9F77DCB7D7F72F0C51C94EB4ED0C37E58 -:1063200073701E67874EC07CDF7599FB4B1350114D -:10633000B4496C121457D826B60AE45DADAFB50E59 -:10634000E5506DF6221DCB207924E20D206DD15E43 -:1063500042E71EEEEF8AF7D3D8FB60DE37BCC76F8B -:10636000B723FE3A8FC5E2BAFDED72983F73771EF0 -:10637000B75BEFCED313DEAEB41F8B55A07D83F792 -:1063800018BF6FAD9FCE7D54C0FD50D23DFB643A27 -:1063900077F5171ABA7F75BEFBF3649A678E6F5252 -:1063A0000C9EABC7CBD773E529B4CE9CCCA595B8D2 -:1063B000FF93A90B0B65B2F34030A35C9D32AF1580 -:1063C000E303B55ED93E9CBFB546CCDBA5E374F8CC -:1063D00056E6AB5D63803E4E968DB291CC17FD7E46 -:1063E00093C7EDF152BD2313F5428F5989413A7E8F -:1063F000B86C620CE2F52896585FB653EF80B2A6EF -:106400009DAFD763E98E457AEB69CF97D16E51E79F -:106410005B89EB1686D0F510DEDC84A72A4F8B193A -:10642000E709E28FD7BBF2B81D7ED2F3EE5D68A715 -:10643000F464475B112F5D7A46FE6D2DE015F54142 -:106440004F675A0BDE83BA9E4BE0A33F5B43780D48 -:10645000F874A2DFA25616D64FC7F1B52B7C3F16B3 -:10646000CFB97F5B847AE959B0ABA1BA4ED7908C93 -:10647000E7FF787BF8FEAAC43DD7E9FCC9C921F43F -:106480005AD731C42F66A2EF0E953F14C2A78AC710 -:106490009E6C6EB7F5A41A3CE82FD6ED6F25BABEF8 -:1064A0003EBED39D81767EDAAF8D1437BC913FAB73 -:1064B000DA01217E0F433F4E5736B1503321A8EF0A -:1064C000AFD9EC2FE615A23F544EFE5E0F1B588647 -:1064D000CADF8976701CCADDBF3D85EB0EB683BD71 -:1064E00007EB3A8DBEB91F829D35680546817D0F49 -:1064F0006ED779847F6246FB7499B04F3F561C4536 -:1065000032E857E71A0D9DAF2E278ADBB5424E7E43 -:10651000B23FE3A748AF7527648B11ED50F05B08DD -:106520006EE37641BD37E3DF67A0BDDDA6233B40C8 -:10653000B53B9CC2EE382FECD9F36B06F464AF1E6A -:1065400096D813B08F2ADFE6AE346877E6CC257B89 -:10655000D529B751FC71F9D670BBA0DA130ED7EE6E -:106560000D879D117683EAB7F5E40DD90F93D1FF1E -:10657000289167A4201F7C2CF0A9FA232BA75A533B -:1065800090DF376895B96A3C00EFC975F8D56ADCC9 -:10659000AFA72ECA4A7EC1AA43749FFD9F71BFA3B5 -:1065A0003F9571FB88F17BEDF771FA76E924EE6790 -:1065B00000B9D27C46C9B3069AFADD83B124971894 -:1065C0002B437E685CC8FD483BC65CA1DC9727E294 -:1065D0004511FAF2566D9F1C1F221F3ECB9B40FBBC -:1065E0002FD63307EAA9953156D25BE38DDCDE2E38 -:1065F00059EDB5211D8C07FFD81012CF1E6F1E90CC -:10660000B0DFAE8778FC5CF5EFE76B2DBAF810BD14 -:106610000792276C7E90247CFC8DE6B7C0FCE6E0F8 -:10662000FC70DF7178DF9F1658491FA7CF67AC9BBE -:10663000F8B181F8513DCF15A0B362A0338C9920F9 -:10664000DEEAB61FA138B09375933F521ACBF751CB -:106650008AFB41388A97967C2E37CAF3F9BD350BF1 -:1066600058955B6FE5DBE3F3A1DC9BEF48CAA77AA3 -:106670000BD1E54A412B60A7A4F40D23771BFFC281 -:10668000FDAA4F810F90CFEF699094CC303B88D317 -:10669000B78B57B1CBCCDB3B03EFC16DEFCE4E4692 -:1066A0003F8AF3D59255262533844E5D48E7702FF7 -:1066B0005596EA1FA3DDED5895AC60BCDF85743FAD -:1066C00001AF91D37522FC43FFE23A3AF786C3F05B -:1066D000B71DE9AB9E19ACA8475CBEC876AB16E304 -:1066E0003AF9F9C0073707F9205DD0658B43F2A06E -:1066F000DC6FF94ACBE3588B258A5BDD0995489717 -:10670000F487FDAA667A70FE3B01447F886D4924B8 -:10671000BEA14690233F17E7BD53EB3F827C7C5CD4 -:10672000E7CDC078CA7127CFEB2C646070807C59AC -:10673000CCBAA9EC8DAE3FE0A7C9DDE3D06F7ECF28 -:1067400061A0384ECBDA1D31284F73D95ACBF96C82 -:1067500054EE6CEFB5FC91ED0A2024765EC50BC5B6 -:10676000853611FE55BCEECDB7CF47FC8F34BEF653 -:10677000AF076E4797A2F681567D0A279BEEECA2E3 -:1067800020FE5CCC9B8DFB55F135843FD8F358B887 -:1067900087056CA008FD1A156F46F8371CDED4FB80 -:1067A0004CD70DFC0CAF0CF412C997487CAAF75BD0 -:1067B000CF1A743CCED5F0CE42E87FF75A8D82F6E0 -:1067C000E175F8BD011EFC26DEE48F91C8DF1C09CF -:1067D0002F2A3E54FC9C8EE7E34EDF23539CEEFFB2 -:1067E000355EDECA773CFA6DFC18C97F23F1DB9277 -:1067F00055117C19C17F2ABE1CAB6289CF543CD68F -:10680000298CFCD6BACE18AB8705F167867F883F06 -:10681000CC53503CA65D62CF48DF850FFB28AF11FB -:10682000891FA00D3BCAF59D11FCA7E26D24F9A3B9 -:10683000CAAF33CC7FDC22517E80F3E7AF0C1ECC95 -:106840002FAAF901350F704CC8BFC8F20CD81D989B -:1068500077D998DD9384F65AAF5E9D87E71FCFAC5A -:10686000E91EB702C69F99C9CB5EB4D342607B14C0 -:106870008FC39D196D70E3BD9D9126CF423D7E462D -:10688000FAF5ED1C4ED12B082F4C996501B857A78E -:10689000C6ED1E1672D843E59985D38AA99FC4DE3A -:1068A000C4FB5024564EEB48524219ECE7CC0393FC -:1068B000F29A59F0FCAFE4737BD62BE4F9501CFB41 -:1068C0003712C5B197800AB060BC7DD6D36513A0DE -:1068D000FEEC83136D94FF6B0C5F1FF56806C50714 -:1068E00037D37CB77E31A05B9A13DCD790FE2BBEEA -:1068F000CAEB2B27913F512570684F98CCFD58CF9C -:10690000C438D447AA7E1A3CF1AA39347E7911F4EE -:1069100017D387C0931F4F0FD56F4776FF3E0BE706 -:10692000A9D2BB73AD507FA1E50FE9680754ED7E96 -:10693000348BECD2DD1BB2D0BFA8DAF1FB2C3BC10B -:10694000D10EF26FB4FCDC97F7DDB27363881DFCE7 -:106950006021F70B161B8F94A07D3AF7E64F1EC1FE -:1069600078F8A407258A8BDDC3BA1F41BD5991CDA4 -:10697000F9886D31925C87F928EFD83AF927BB5036 -:106980009E9FCCFE405709FD4C055ABA8F0AE67906 -:106990002C05E361EB258A8705FB8FA33CE6D2B586 -:1069A000923E3511F561BC4D56705C3CEDE3DEF571 -:1069B000B62EACAF58CDEBE71A3CED3D38CFD37ACD -:1069C0006BAB8213954F280FC90B9B0AB8DFB5E458 -:1069D0003189EC71759D494F25B7849ED35420F4BD -:1069E000F98C6EE2FF9F0ABCFC78F5BB6FA62A9873 -:1069F0004F72C41540FB3B4F9ECF44F9559C7031FC -:106A000007E97C92DEF14C359E7B8781E28705B9F0 -:106A100069720AF4CFFBE5CC27B05CB27AE933D5D2 -:106A20001807DD6A243F4ADD5FA3A468D0DF3CD6A7 -:106A3000F28B7BF1DE2E3C69243BBAB1E5A614361D -:106A40000C9FAAE51EC0BF92C5D8F34D462A5F6CC5 -:106A5000B230058EB8AF2995E0979B142AD9024E23 -:106A60005F8DC25F1D69BE7CF0F715905705EB6125 -:106A70003EB0376D26FB143CE7A429CE1D1BC4B9DC -:106A800026C1789B3B6336DE43C186155D688A2646 -:106A900017F0FCE2DB3DEBD3C98E5E7DEEB96A6890 -:106AA0005F5A509E5F00F76DDC7E95FCFC631D8F86 -:106AB00056505C7F87819F4F9CFBC2935929CF60C2 -:106AC000DCF52D1DF9DFAEEDE79EDB00E57D8FAD3A -:106AD000D087D2FB773DAF4DECE7467C35D23D7C8D -:106AE0007FBEFA7D3AF1CF0EE0AB9C7F9CAF5CABF2 -:106AF000D7D0FD3D5A507E37DEFB059D3B1DF9E9A1 -:106B0000C2E41F119DBB0F4B74FFAA1C57C72F1067 -:106B1000E7ADD5781F237B50C8F1CFC1F3C3FB3D50 -:106B2000D2F17116DAC39FFB167EEBB90F36610600 -:106B30001DE35A462A23DB8BF48E8956385F9186F3 -:106B4000DBC191ED0F17A871719E6FC73F8C0BD7FA -:106B500009FDE9848DC525A0FE93FC51B998E7B8DD -:106B6000EDA216FD2FF0EBDE0FB72FD9FB217A7CBB -:106B7000A4FDDEA8ACC779B441B93BEDB486F943B6 -:106B8000F4F62D7D51CC1FB2EE90DF01757ACCB3B7 -:106B9000748C26B98078C3BC4CA063F20E842FEAB3 -:106BA000391E0307C1BFE27115261705CF79B1E37E -:106BB000722ECAD9C8F3D61FBA4CF451E77BF4AA97 -:106BC00044E79F73519B7BE3F31FD97D3917F1771E -:106BD00051D757847E5440DF978B78A87F9DCBF3A5 -:106BE000EF7B0F6A7DF57A3D8FEF4916F2074BE494 -:106BF0002BE4C7074E703FBEBE6327C9D3C14E1EEC -:106C00004F7169BA4B5330FED070AE0BE5D9602A94 -:106C1000F7AF607E3BDEDB8C89420F6A07D2E783E9 -:106C20005C3B2AF2B5AA5F7701F9578FF378EBE85E -:106C30003D526E3443BBE212F233D457ACCA58878C -:106C4000747EC193849120F676EEFFD453FCED8DD3 -:106C5000688B4C762BD486E06FE81C1E993F9C61B4 -:106C6000AA9F1ECDEC21FD5C7AE5A7E41F9FE47985 -:106C700032D714CE4FEC10E727E7DA23FAD490F995 -:106C80005E52E587B01FE7BEF13FC497A76CF6538D -:106C900028CFA25116E27CA9711E4912FD8A827981 -:106CA0004073A7F0C7CB646A77F964361AC7A4C6E5 -:106CB00050BEBE8C6DD2A2BD3B977967F077327D16 -:106CC000FFF643689FF7869C8FEFB1C07EA6FC71EC -:106CD000699423B311ED238D24EED55B303F549F8F -:106CE00015727B6B862C911E1B181D4D76CA9C0558 -:106CF000CEC5B85FB55F9996EB339887EC2CE61953 -:106D0000C8C57C26F30FE4629E53ED77D71BD10DE7 -:106D1000A41799B7E0AE9075C61472BDF929E69F25 -:106D2000419EB844FEB344FEEA29F4A31A0FF33C93 -:106D300061AF26E33D7CAFE5867B46BC5E06BCDAF0 -:106D400051FF3898DD8EFC3335C983FCE3DA2731F7 -:106D50007CB756DF61D881719D7A5D5F32D2F306D0 -:106D6000DF5FF548CFAE03EFEA95A9389EC781C033 -:106D70005ED7E0FDBA84FE72FA6E7A0FE36ECE1330 -:106D80005C8B3AB5EF925F5FDBBE9FFCF73AE6277C -:106D9000FFBDAE2D9C5E0653799C3D923FC6142AE2 -:106DA000617C31672BE78BBB64D680728E89B8E932 -:106DB0009CD414B24782E3849D285F7E04ED97FE45 -:106DC00009925582A9FAA3DC6BD12E7267717BA65A -:106DD000FF4F2F162C23B9E229F819BE8B11F6EEBE -:106DE0009CF59BB572C87EE674F238617F14AB3AAD -:106DF00048F8768C453CA4E7958F2DE4EF6472E962 -:106E00009D8F86C73523CFF1AC88E39CC4384F4EA5 -:106E100070DFF3D2D2B81C631EA29F2E0D5F5F7D80 -:106E2000F7A28E5F21E869C81F92787C6A24B98234 -:106E300079944A9147A91479944A9147A91479946D -:106E40004A9147A91479944A9147A91479944A918F -:106E500047A9147914AC3F895BA5F7703B9F417A31 -:106E6000E8421E1B13847B1322E031E1FD7B13A457 -:106E700070788C44FD8B0B773EE3CEC138A645C8B5 -:106E8000252506EDAF0B261E5FEA8871CC2D84FA0E -:106E9000CA39CDBBF97B443BBD67294E58B818F9B8 -:106EA0006B30D1C0500EB90B1DF3111F274ECCCE45 -:106EB000DC4CF2D164C53C77EFDD37C7515CEE2D79 -:106EC00099C9B0E4CCECFCB50500CF344B44B720F5 -:106ED000277E50AEFA9330CFEC4E9ECF2891EB2A0E -:106EE00071FEC6D1A67C8A6BE53B161586C40F4A97 -:106EF000C72CCF443BA84BA7BC87F154F75F740C59 -:106F0000FD2835FEA6F6EBCD9B598DFB9A933D717E -:106F10006D1ECA1B602E946F763D6BC37DD935D133 -:106F20005233C92B458BFC5F2DF03D4BE1F6B05F32 -:106F3000AF6813D06F8F9A99E85678BEAA52E4AB27 -:106F40002A45BE0AF1730AE36650BE03F55876433C -:106F50003D9691EFB9761794AF24BA6503E9A1EF96 -:106F6000C1E6225F7139938EF4FC8288C367178A69 -:106F70007769F9E50FF2715E9AA756C4DF2EEBC26E -:106F8000F378EAB8E07846E51D3FE0F299C5E9F903 -:106F90007BD7B1CC8DEF69EF786D34C593021E8D30 -:106FA0005B170730F038CA2FF61AF76F592AE797A0 -:106FB0003B5E4DA17ECD220EEA4CE8CE4A40BD2B71 -:106FC000F84A850F7EC3DFF938F30086F275899F92 -:106FD000CF794777563CC001C9A4C1F8B873076F91 -:106FE000EF117CE79C20E613E761466F3AE2A3FFCE -:106FF000F06BE9F702BCD1EC5FC6E5BD3F8BE43432 -:10700000F367E17BA1CB92F72CBEB7FDF5C17F59A9 -:1070100084EF6B2FEBBCCF21FCDB8333382CED3FAF -:107020006B096D4FF2A6E37BDC5F1FFCE1227C9FC6 -:107030007B3969FF73F1D61058F7CA596CD73F3CBA -:10704000635131F49F67F09C6842BA7999D397698C -:10705000DF81F3783FB51DDC5E9FB5EFC0955750DB -:107060001F1F88A17CBDAF3083EEBBB963CF6348DF -:107070006F81FD3AE2838D6D7F7DEEB7D4CF4061A5 -:107080009479066F01865CDC457FBB1BF7352FDAF0 -:10709000FB19C29B8B6EA37DCE1BC5F9F9A9A2B9C2 -:1070A0008B903F0307F6FD0AF96F5E1C18B2B89F7C -:1070B000174D849F9A572717631C2010D35D81F3C7 -:1070C000D7BF60B0229DD6BC9A320BE302C70B79C2 -:1070D0007CBA7ACAA674D4AF9A43CFEFFE2DC629E4 -:1070E0005F30517EC695C0EDBB1AB9A56805E16F4A -:1070F000E76E7C371278DE4479D26A9803D7ABDE2C -:107100003D89E2EAAF7FFD4105E2A144DEBE1BEB13 -:107110003FDB65D2E03DF4E8ED713F423EECD191BA -:107120009F592DE0EADE517C3FD17DA584BFC44D3F -:10713000E9A85F6B46FDE676DCF73C79D373E8E7B8 -:10714000B03D06CA155C7C1EEE0DC65D6CD5D12B1C -:10715000D5C0F3315AA497CBD2A68A6770FE56DE0B -:10716000EFB26913DDA7BBF52686EB413F86F2EA55 -:10717000B2B439ACFE62EB9E5CF4432FBD308FFCA1 -:107180005195CE557EA9D96508D387240992C57B30 -:107190000952B36E66063D5B2DC04B07B7059E6175 -:1071A000C1F197DA747E3DDC51B581ADC5F7C12AD6 -:1071B0003FD4A4DD5686E7ABD1B464A1BD529DDFB8 -:1071C00057817C71D1C48CA9F88E4EE8AB9AF63504 -:1071D000F3D1EE1D693FB1E25DDFE7820F3FF79922 -:1071E0003CA1F9C1C8F26F4D4C3915F26EF89E06FC -:1071F00003D9EEEA7C6FEBBD75E89FD52770F97176 -:1072000016FAB7811C331771B9B76455787FA9880E -:10721000BF4BACD7F765A1DE53E7FFA650956B7D5A -:107220005928AF22C7CD9385BC7951227953D32EEB -:107230009D93E19E6A8C6E0FBEDFA94167929F53BA -:107240007B4DE2E3528BC4BDC3D8A78B3268DD9A75 -:107250003693DD04E36AA3FA62D11EAA8BE98B455B -:107260003B277048663B04BA1293057E2608948536 -:10727000C41DABBD3ABB2977183CA3DD84EF73F086 -:10728000BF61FDB622CE2755BE685A8F59FA8A9043 -:107290004EABB6878FC3735942F82FE0DB991CEAD7 -:1072A0008FDBC4BEFBA573C427FD5FBF9F8E78AF85 -:1072B000D1B0B59847BC24F1EF1E00A6EF1E2E8971 -:1072C0007C64CDDFCD51482F973EAF23BE0D487D66 -:1072D00024D7CE1C5C407229A0EB23B9D65354416D -:1072E000F22110DF578172EACCC17ADE3EBAAF429A -:1072F00081F64E84B17D1C237D7FB9E801921FF396 -:1073000064FEBE81EDD459781C687D6F13F9153A7F -:1073100025D4EFBE52A4E66DF4C173CB41BE093053 -:10732000655F3BF2619599E239603FB5BD8276DEDB -:10733000C2642BC6C5AB701CA7037D68FE2F31E16C -:10734000CB65889F45718E3B8B308F9DD347FE0365 -:107350005035D9E9F57F32901FD9AF1BD88D722AED -:1073600037CEB1B008F651A7EF5E87A1A72BBABE02 -:107370002ECCFBCD95B93C627B385D057276F2EF81 -:107380002444FEB0BA88CB5FD05BAC05E942E2F89A -:107390003DE67BF514CA9540F74492C7917C73D1C2 -:1073A000F7442CCA87D3A0C7DD217EFEE9A57B2840 -:1073B0004FBF00DF654079EFDA707A18FCEA67E4C6 -:1073C000EFB1C742EA910EB784C3917484F4E80F19 -:1073D000933B6EA29B3D82AF6A6775D7E33D0CC1BC -:1073E00077002C87C04723E088FEAC9CDB097BF04C -:1073F000BF61DEBA71FE5EF2CFF7F177B1CDA0BF0B -:10740000083E104D7963CD3ED04F895C3FA15EA808 -:107410008DEDA6B854E08081F2230F777C4CEF19F4 -:10742000810E29FE52DBF15A32FAED3EF4139248F6 -:107430000F26D33B95031DC9E86FA8F5751A6F9603 -:10744000788F4F76BA5AEF94FD59B8FF5AA93B1777 -:10745000DB7D8516D11F60196146E7A89338BFB35D -:107460000E99E47924DEF60A7A05B9904BEF2C0EDA -:10747000F1B8802A07AA853C398AF5399CEF2D6A34 -:107480005E49C2F772D1C3CA879B8A547BB881E236 -:1074900036BB8A147EAF623CCDCBE34AD45EFFFAA2 -:1074A000E5DC0939384E11E342E4D0C4A05C41FE6A -:1074B0004F25FE7F58970CE7AA794EB236A39C5A07 -:1074C000BCA614BAB3E5DA15A5142F13EF3F23F7C2 -:1074D000154947F6228EDF1A4D7C4962C87C97C059 -:1074E0005D4FCD233943EFE8EF4F7CBC14E313BF6E -:1074F00058BC99E87948DF84F2399E673B97E3C826 -:1075000036D734D7D3F1F286967529C3EC23729F10 -:10751000D58E96D264E5FA7A75BF974CEAFE66E995 -:107520009242EF61C19AD22428971BFFD17BE0E7FA -:10753000BDD461F0A35EAD5EBC625DDC3074739D52 -:107540003ED81EA2BF26207E3D94D71869FF9165C4 -:107550009DE4EFC5381103BE6A25FE027E09D10BFA -:107560006542BF0EC51BAA968E47BF9339968E47BC -:107570003D037C55611DC6AFC42F4B34F476C34D1B -:1075800065E47E3E2BE271D2B222CE2FA76CF66F5D -:1075900050BE8EF4BD85619AF4ADDF5BA46906DF51 -:1075A000417E4B4B8E51300F54323B9AF73B6CB2BD -:1075B00060DCA6FFF09714D7ED7FC4BC80E70BCC4E -:1075C0006C34B477A54EDD11AA473CD3385F46171B -:1075D00070BBC595ADFBF6B8504ECC505C88EC86C0 -:1075E0009C68CA93047C9F92DEEAEF2CB4603E2331 -:1075F000D00DDE21F093EBEBFF4A46FD1AE8FC8844 -:10760000DE8305BEFA98DE896D10EFF48EFAC43B76 -:10761000AB6E2586BE8B2BFBA014FB6D1465303E34 -:10762000C0E35A6AA9FAFF21FEEF946985C3FABF45 -:10763000090E73685C4049192E8E121A17C8D4F2CD -:10764000B800961817C8CCE4710184312E8025C685 -:1076500005B01EE30208635C00618C0B208C710195 -:107660002C312E80F59F89EF1FFA4130F178A599D2 -:10767000E4FA4A7CDF0EF7B7F230CF3BAD6C9529C8 -:107680007F8BDF3FA07EBBEEDD4CBB7837E3DD4C6C -:10769000793CD701D98A2872E9068E631CC7B55F89 -:1076A000B2AE41B9D2B480D6DFD059F8DE62AC6F49 -:1076B000D559350AD111C7638B44EFF46B3A5B2976 -:1076C000EE549C72584FF56D12C338E95D06EEE733 -:1076D0003A65A8CDA33C28D9C14E4337F91FB57BE5 -:1076E00025A532F49DC6F4AB2407D47CF232DEC467 -:1076F0009C5E935239CC3B90A177E7E2DDF432CC2B -:1077000033E37B71F92B7AD7EF04877414D2E156F7 -:10771000FEFED902FF88DF23DE35D574EE5F87EFEA -:10772000A122F3CD43DFD345E49DEBA789BCB28D05 -:107730007F5F51F664E5BE03B0DEE02603D91BEEA1 -:1077400042C703D39230EF6FA7F8C8F1C326F28B7C -:107750003EDC7C53587C84E53B1E9C46F9F9B11411 -:10776000AF68D449A48F67974D4CC17B9C7D42473D -:107770007AA737AF7C35F66B9CAA503CAAC4C01ED2 -:10778000A079C47B29151F25CD924703F05266A529 -:1077900077F64BE09A305ED9AF33AFC7774D4B18D1 -:1077A0007FE7A0D24DE36689E8060304789F15E2DF -:1077B0003E9774FEF94B7CC7709F81DBAD691A9EC2 -:1077C000BF4EDBC8DF33DCCF1C7AD4B3CB91BA64B5 -:1077D000D28F7FEA837A47F4D8746E972B2938FFCB -:1077E000D2933A7A6F5B92F2932C07E9E9627AC7F7 -:1077F00020F917C9D76E1E997F22DF311CD771B9C6 -:1078000002F748FE5017D225C5651C549E6CAAA2EB -:10781000F277E27B88EBDFFF0F9C453F312D25C6D9 -:107820008A726EC4EFDDA2BEFD7BAF17C4FBB53418 -:107830004D4FBE82F7F177B315EF437D2778CA56D7 -:10784000BE1FF1648F656E0B7D0F061210EEB5142E -:107850000F22615CDB6BC7EF8E060E4B167A977CAE -:107860009D7CDCFC08BE1371654A1649C1F8F7A679 -:107870009264D877E9840CDAB7CBC7E3A37443C921 -:10788000183FE7F84ACF731C9B5618AC9F27F82681 -:1078900000FD399DFCD083F4F61DE2A6BBB0BF9B72 -:1078A00099E87B6AFA83FDCCBB791CC54F55BA19A0 -:1078B0006C4BD98174F39E90FB8B17BFAB43FDDFFC -:1078C0009BEFE8C17D54545E7D2499CE377CFC4A01 -:1078D0007DA71E19BF0A959FFF3FDEA79F6A6AA07A -:1078E000F29DA655547637B9A93D44FE5F1A41FE74 -:1078F00047C63FAF227F47C63F99518923FD09FC08 -:10790000CDE3CD11F1CEB251F7AE87FB9BBD456FF4 -:10791000C52A35FE89EF87579A491EFCF7B461E303 -:107920009EEABD99294E3AC84C7978FFB3B2276ACE -:1079300035D0AE9DCEF1A7C61D913FF07CC81F5833 -:10794000227F68B541FE78560F2C5CC0F5BC9BF4D5 -:10795000BC89F0BA6E0DC80F80EF639630F97125BF -:10796000427E80C371377D57D56960182754DF5137 -:10797000CE82E28BBC61E48997CB937151DEE7E95B -:107980007BFFFA287A9F7B5CBC873BBE81BF87ABBD -:1079900064E5B4EE30722516F171DFA881B37F8003 -:1079A000FEF7FDDE4CF6CABAD1CB8AFE19B9724D8C -:1079B0007CD7F234FEAE80F6DB7E57E03109F3A1CE -:1079C0008DF7301BE259FD5D811491CFFE1EBF2B58 -:1079D000306D7AE177FF5D815BA78F5F1CFABB0298 -:1079E000B7FA3238ACFEAE001BBF7884DF15983D85 -:1079F0003DE9FADF15B86D3AF71747FA5D01B02790 -:107A0000CB705C92CD3E07CB34B1CFC8EF694F8AC3 -:107A1000FC5D97C6B118CBD258B796EA359E02FAEC -:107A20000E5EE3FD25F981F98E9FE3794B9FB04D02 -:107A3000C90638CDE02539D99B67BF13EBAFD9EC28 -:107A400077E13A917173C42DFAF7B09FBBB13DF263 -:107A5000DD958ACF15D3B9DC6814E58CE6E1BF2744 -:107A60006F9CCEF3F237DA37ECB706D71BDAFFA6F6 -:107A7000A505B81FD86F2DD6C37EEBB064E684B0E1 -:107A8000EF53AFA73337D155E3744E5F20CFE67D78 -:107A9000C8ED412AB3B49E78B41FC73CE489C7FD42 -:107AA0008E691930E177107F740F9850BFFF71F520 -:107AB0008009EBFF68E7EF9523E77F793AF703B298 -:107AC000660CD0F8F168E3937D3E108FF65356D5DF -:107AD00087EB28DFB27732E997F142BF8C7F68826B -:107AE000AF0FE86DFCB638CA67B3E2446AAF3172D3 -:107AF0003EAD79A8F2E00185BEDB9AF76188BD331F -:107B0000D903FB0EB3BFB483FCDD25C0784F7B7572 -:107B10000423CDA27DE564FCDDE5182137D04E5B62 -:107B20000C72C159F5E69794F7C7F1381FE66891D2 -:107B3000FE7CBA41F17D9A05FDD0E50BD674915FCC -:107B4000B875A85EF899FBD7A1DF0CF65B587D4DA0 -:107B5000E5912ED437B57BC3EB9D0D57C97F05FB4F -:107B60002DACFE9E5F9ED3F3DF2F08AF07FCEE45E2 -:107B7000BA54F17B5CE79D8C7EDE71679495BFDF24 -:107B8000F7D2EF95EC10DF3FEFFC8F599C6E04BEEF -:107B900061BC3774FCC8F4D14CFDDDB35836F2C378 -:107BA0008D4A552E0DFDFE899EB929BE373786E4D4 -:107BB0008E4BF855F59516D2F369F546925F25720E -:107BC0009415E1A1DF3F2993859CF212FFF7DC1E9B -:107BD0004F713C3A00C2095329EF93DCCCE1812478 -:107BE00003C987124D79DD1E28DFD4847FC7FE2CA0 -:107BF000CA0719F9977F87E9D27BF977E25AA5106E -:107C0000FDDC66C9BE0DBF7B6C96441CB1DA4CF935 -:107C1000827E8C2FC279B6C47BB62D8375B6DC9973 -:107C200043F6713FE3F2D4BD80E7ADB6C4972F5E53 -:107C300081ED0BA750FBC16F263E5E80F653759415 -:107C400015EDA72D366E5F6F999F4DEDAF4BCA1A9C -:107C50003CB7FB2146EB6C99CFCFBDE5F171E2FB60 -:107C60000B8F09F9794B8B7D34E6A366591C1710ED -:107C70005F63443E6E4B06D443F99454BEF07E9C41 -:107C8000672ADFEFEF6C0AC98FE30BA73CBE5B21CD -:107C900035E2C7BC906B6E0CF9C1FF0BB81F749432 -:107CA000704700000000000000000000000000001D -:087CB00005020D0000000000B8 -:00000001FF diff --git a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex b/firmware/bnx2x-e1h-5.2.13.0.fw.ihex deleted file mode 100644 index ea3e254335b1..000000000000 --- a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex +++ /dev/null @@ -1,12849 +0,0 @@ -:1000000000003BE8000000600000068800003C5053 -:1000100000001968000042E0000000AC00005C50E5 -:1000200000008DF800005D00000000E80000EB001B -:100030000000E3140000EBF0000000940001CF0882 -:10004000000058E80001CFA0000000C40002289082 -:100050000000F9640002295800000004000322C0D7 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:1001800002040014000000FF02040018000000FF39 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200204203C00000000DE -:100240000204204000000034020420440000003575 -:10025000060420480000001C020420B80000000131 -:10026000060420BC0000005F0204223807FFFFFFE5 -:100270000204223C0000003F0204224007FFFFFF6F -:10028000020422440000000F010422480000000084 -:100290000104224C00000000010422500000000074 -:1002A0000104225400000000010422580000000054 -:1002B0000104225C00000000010422600000000034 -:1002C0000104226400000000010422680000000014 -:1002D0000104226C000000000104227000000000F4 -:1002E00001042274000000000104227800000000D4 -:1002F0000104227C000000000C042000000003E840 -:100300000A042000000000010B0420000000000A85 -:1003100002050044000000200205004800000032F1 -:10032000020500900215002002050094021500202D -:1003300002050098000000300205009C0810000033 -:10034000020500A000000033020500A400000030F8 -:10035000020500A800000031020500AC0000000208 -:10036000020500B000000005020500B40000000610 -:10037000020500B800000002020500BC00000002F7 -:10038000020500C000000000020500C400000005D6 -:10039000020500C800000002020500CC00000002B7 -:1003A000020500D000000002020500D40000000198 -:1003B00002050114000000010205011C00000001FB -:1003C00002050120000000020205020400000001F5 -:1003D0000205020C0000004002050210000000406F -:1003E0000205021C0000002002050220000000138C -:1003F0000205022400000020060502400000000A59 -:1004000004050280002000000205005000000007E3 -:100410000205005400000007020500580000000813 -:100420000205005C000000080205006000000001F9 -:100430000605006400000003020500D80000000665 -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C000020500E00000000D020500E80000000742 -:1004D000020500F000000007020500F80000000718 -:1004E000020500E40000002D020500EC00000027DA -:1004F000020500F400000027020500FC00000027B0 -:10050000020500E00000001D020500E800000017E1 -:10051000020500F000000017020500F800000017B7 -:10052000020500E40000003D020500EC0000003779 -:10053000020500F400000037020500FC000000374F -:10054000020500E00000004D020500E80000004741 -:10055000020500F000000047020500F80000004717 -:10056000020500E40000006D020500EC00000067D9 -:10057000020500F400000067020500FC00000067AF -:10058000020500E00000005D020500E800000057E1 -:10059000020500F000000057020500F800000057B7 -:1005A000020500E40000007D020500EC0000007779 -:1005B000020500F400000077020500FC000000774F -:1005C0000406100002000020020600DC000000010A -:1005D000010600D80000000004060200000302200B -:1005E000020600DC00000000010600B80000000068 -:1005F000010600C800000000010600BC0000000069 -:10060000010600CC000000000718040000A900004B -:10061000081807C800070223071C00002C2C000044 -:10062000071C800038930B0C071D0000293119317D -:10063000081D686052F40225011800000000000047 -:10064000011800040000000001180008000000006C -:100650000118000C0000000001180010000000004C -:100660000118001400000000021800200000000122 -:1006700002180024000000020218002800000003F5 -:100680000218002C000000000218003000000004D6 -:1006900002180034000000010218003800000000B9 -:1006A0000218003C00000001021800400000000495 -:1006B0000218004400000000021800480000000179 -:1006C0000218004C00000003021800500000000057 -:1006D0000218005400000001021800580000000435 -:1006E0000218005C00000000021800600000000119 -:1006F00002180064000000030218006800000000F7 -:100700000218006C000000010218007000000004D4 -:1007100002180074000000000218007800000004B5 -:100720000218007C00000003061800800000000290 -:10073000021800A400003FFF021800A8000003FFF9 -:100740000218022400000000021802340000000019 -:100750000218024C00000000021802E4000000FF32 -:100760000618100000000400021B8BC000000001EE -:10077000021B800000000034021B804000000018B3 -:10078000021B80800000000C021B80C000000020C3 -:100790000C1B83000007A1200A1B83000000013806 -:1007A0000B1B830000001388021B83C0000001F4B0 -:1007B000021B1480000000010A1B148000000000CE -:1007C000061A1000000003B3041A1ECC0001022711 -:1007D000061AA020000000C8061AA00000000002AF -:1007E000021A1ED000000000061A1ED800000006E3 -:1007F000061A36E800000004061A36E0000000027F -:10080000061A500000000002061A500800000004FA -:10081000061A501800000004061A502800000004B0 -:10082000061A503800000004061A50480000000460 -:10083000061A505800000004061A50680000000410 -:10084000061A507800000002041A404000020228F4 -:10085000061A400000000002061A400800000002CC -:10086000041A62C00020022A061AD1000000000209 -:10087000061A200000000124061AB000000000281B -:10088000061AB1400000000C061A330000000014E4 -:10089000061A33A000000068061A81080000000252 -:1008A000061AD1C800000002061AD1D800000020A4 -:1008B000061A249000000124061AB0A000000028A7 -:1008C000061AB1700000000C061A33500000001424 -:1008D000061A354000000068061A81100000000268 -:1008E000061AD1D000000002061AD25800000020DB -:1008F000021A292000000000061A30000000000241 -:10090000041A30080005024A061A301C00000009CB -:10091000061A320000000008061A5000000000020B -:10092000061A508000000012061A40000000000263 -:10093000061AD0C000000002021A2924000000009C -:10094000061A304000000002041A30480005024F29 -:10095000061A305C00000009061A32200000000868 -:10096000061A501000000002061A50C800000012BB -:10097000061A400800000002061AD0C80000000253 -:10098000021A292800000000061A30800000000228 -:10099000041A308800050254061A309C0000000931 -:1009A000061A324000000008061A5020000000021B -:1009B000061A511000000012041A401000020259D9 -:1009C000061AD0D000000002021A292C00000000F4 -:1009D000061A30C000000002041A30C80005025B8D -:1009E000061A30DC00000009061A32600000000818 -:1009F000061A503000000002061A5158000000127A -:100A0000041A401800020260061AD0D80000000242 -:100A1000021A293000000000061A3100000000020E -:100A2000041A310800050262061A311C0000000990 -:100A3000061A328000000008061A5040000000022A -:100A4000061A51A000000012041A4020000202679A -:100A5000061AD0E000000002021A2934000000004B -:100A6000061A314000000002041A314800050269EC -:100A7000061A315C00000009061A32A000000008C6 -:100A8000061A505000000002061A51E80000001239 -:100A9000041A40280002026E061AD0E80000000284 -:100AA000021A293800000000061A318000000002F6 -:100AB000041A318800050270061A319C00000009F2 -:100AC000061A32C000000008061A5060000000023A -:100AD000061A523000000012041A4030000202755B -:100AE000061AD0F000000002021A293C00000000A3 -:100AF000061A31C000000002041A31C8000502774E -:100B0000061A31DC00000009061A32E00000000875 -:100B1000061A507000000002061A527800000012F7 -:100B2000041A40380002027C061AD0F800000002C5 -:100B30000200A294071D29110200A29800000000E3 -:100B40000200A29C009C04240200A2A0000000005D -:100B50000200A2A4000002090200A270000000002E -:100B60000200A274000000000200A2700000000059 -:100B70000200A274000000000200A2700000000049 -:100B80000200A274000000000200A2700000000039 -:100B90000200A27400000000020100B40000000185 -:100BA000020100B800000001020100DC00000001A9 -:100BB0000201010000000001020101040000000127 -:100BC0000201007C003000000201008400000028C7 -:100BD0000201008C0000000002010130000000044E -:100BE0000201025C00000001020103280000000075 -:100BF0000201607000000007020160800000000137 -:100C00000201055400000030020100C40000000190 -:100C1000020100CC00000001020100F80000000108 -:100C2000020100F00000000102010080003000001D -:100C3000020100880000002802010090000000006E -:100C40000201013400000004020102DC0000000186 -:100C50000201032C00000000020160740000000784 -:100C60000201608400000001020105640000003000 -:100C7000020100C800000001020100D000000001D4 -:100C8000020100FC00000001020100F4000000016C -:100C9000020C100000000020020C200800000211CD -:100CA000020C200C00000200020C201000000204C4 -:100CB000020C201C0000FFFF020C20200000FFFFA0 -:100CC000020C20240000FFFF020C20280000FFFF80 -:100CD000060C203800000002020C20400000003406 -:100CE000020C204400000035020C204800000020C7 -:100CF000020C204C00000021020C205000000022B9 -:100D0000020C205400000023020C20580000002494 -:100D1000020C205C00000025020C20600000002670 -:100D2000020C206400000027020C2068000000284C -:100D3000020C206C00000029020C20700000002A28 -:100D4000020C20740000002B060C207800000056D6 -:100D5000020C21D000000001020C21D4000000018F -:100D6000020C21D800000001020C21DC000000016F -:100D7000020C21E000000001020C21E4000000014F -:100D8000020C21E800000001020C21EC000000012F -:100D9000020C21F000000001020C21F4000000010F -:100DA000060C21F800000010020C223807FFFFFF9C -:100DB000020C223C0000003F020C224007FFFFFF14 -:100DC000020C22440000000F010C22480000000029 -:100DD000010C224C00000000010C22500000000019 -:100DE000010C225400000000010C225800000000F9 -:100DF000010C225C00000000010C226000000000D9 -:100E0000010C226400000000010C226800000000B8 -:100E1000010C226C00000000010C22700000000098 -:100E2000010C227400000000010C22780000000078 -:100E3000010C227C000000000C0C2000000003E8E4 -:100E40000A0C2000000000010B0C20000000000A2A -:100E5000020C400800000411020C400C00000400C9 -:100E6000020C401000000404020C40140000042195 -:100E7000020C401C0000FFFF020C40200000FFFF9E -:100E8000020C40240000FFFF020C40280000FFFF7E -:100E9000020C403800000046020C403C00000005F7 -:100EA000060C404000000002020C40480000000A0E -:100EB000020C404C000000F0060C40500000001FE7 -:100EC000020C40CC00000001060C40D00000003AAB -:100ED000020C41B800000001060C41BC00000003F8 -:100EE000020C41C800000001020C41CC00000001CE -:100EF000060C41D00000001A020C423807FFFFFF29 -:100F0000020C423C0000003F020C424007FFFFFF82 -:100F1000020C42440000000F010C42480000000097 -:100F2000010C424C00000000010C42500000000087 -:100F3000010C425400000000010C42580000000067 -:100F4000010C425C00000000010C42600000000047 -:100F5000010C426400000000010C42680000000027 -:100F6000010C426C00000000010C42700000000007 -:100F7000010C427400000000010C427800000000E7 -:100F8000010C427C00000000010C428000000000C7 -:100F90000C0C4000000003E80A0C400000000001B7 -:100FA0000B0C40000000000A020D0044000000325B -:100FB000020D008C02150020020D00900215002089 -:100FC000020D009408100000020D0098000000338C -:100FD000020D009C00000002020D00A000000000B5 -:100FE000020D00A400000005020D00A8000000058D -:100FF000060D00AC00000002020D00B4000000026B -:10100000020D00B800000003020D00BC0000000249 -:10101000020D00C000000001020D00C80000000227 -:10102000020D00CC00000002020D010800000001CA -:10103000020D015C00000001020D016400000001CE -:10104000020D016800000002020D02040000000110 -:10105000020D020C00000020020D021000000040F2 -:10106000020D021400000040020D022000000003E7 -:10107000020D022400000018060D0280000000127C -:10108000040D03000024027E020D004C000000014C -:10109000020D005000000002020D00540000000884 -:1010A000020D005800000008060D005C000000045E -:1010B000020D00C400000004020D00040000000145 -:1010C000020D000800000001020D000C00000001EC -:1010D000020D001000000001020D001400000001CC -:1010E000020D001800000001020D001C00000001AC -:1010F000020D002000000001020D0024000000018C -:10110000020D002800000001020D002C000000016B -:10111000020D003000000001020D0034000000014B -:10112000020D003800000001020D003C000000012B -:10113000020D011400000009020D011C0000000A4C -:10114000020D012400000007020D012C0000000721 -:10115000020D01340000000C020D013C0000000BE8 -:10116000020D014400000007020D011800000029D3 -:10117000020D01200000002A020D012800000027B6 -:10118000020D013000000027020D01380000002C84 -:10119000020D01400000002B020D01480000002755 -:1011A000020D011400000019020D011C0000001ABC -:1011B000020D012400000017020D012C0000001791 -:1011C000020D01340000001C020D013C0000001B58 -:1011D000020D014400000017020D01180000003943 -:1011E000020D01200000003A020D01280000003726 -:1011F000020D013000000037020D01380000003CF4 -:10120000020D01400000003B020D014800000037C4 -:10121000020D011400000049020D011C0000004AEB -:10122000020D012400000047020D012C00000047C0 -:10123000020D01340000004C020D013C0000004B87 -:10124000020D014400000047020D01180000006972 -:10125000020D01200000006A020D01280000006755 -:10126000020D013000000067020D01380000006C23 -:10127000020D01400000006B020D014800000067F4 -:10128000020D011400000059020D011C0000005A5B -:10129000020D012400000057020D012C0000005730 -:1012A000020D01340000005C020D013C0000005BF7 -:1012B000020D014400000057020D011800000079E2 -:1012C000020D01200000007A020D012800000077C5 -:1012D000020D013000000077020D01380000007C93 -:1012E000020D01400000007B020D01480000007764 -:1012F000020E004C00000032020E00940215002085 -:10130000020E009802150020020E009C0000003022 -:10131000020E00A008100000020E00A4000000331E -:10132000020E00A800000030020E00AC00000031E8 -:10133000020E00B000000002020E00B40000000423 -:10134000020E00B800000000020E00BC0000000207 -:10135000020E00C000000002020E00C400000000E7 -:10136000020E00C800000002020E00CC00000007C0 -:10137000020E00D000000002020E00D400000002A5 -:10138000020E00D800000001020E00E4000000017F -:10139000020E014400000001020E014C0000000199 -:1013A000020E015000000002020E020400000001C3 -:1013B000020E020C00000040020E0210000000406D -:1013C000020E021C00000004020E02200000002099 -:1013D000020E02240000000E020E02280000001B74 -:1013E000060E030000000012040E0280001B02A281 -:1013F000020E00540000000C020E0058000000090C -:10140000020E005C0000000F020E006000000010E1 -:10141000020E00640000000B060E006800000003CE -:10142000020E00DC00000003020E000400000001B8 -:10143000020E000800000001020E000C0000000176 -:10144000020E001000000001020E00140000000156 -:10145000020E001800000001020E001C0000000136 -:10146000020E002000000001020E00240000000116 -:10147000020E002800000001020E002C00000001F6 -:10148000020E003000000001020E003400000001D6 -:10149000020E003800000001020E003C00000001B6 -:1014A000020E004000000001020E00440000000196 -:1014B000020E01100000000F020E01180000000EC5 -:1014C000020E012000000000020E012800000000B2 -:1014D000020E01140000002F020E011C0000002E5D -:1014E000020E012400000000020E012C000000008A -:1014F000020E01100000001F020E01180000001E65 -:10150000020E012000000000020E01280000000071 -:10151000020E01140000003F020E011C0000003EFC -:10152000020E012400000000020E012C0000000049 -:10153000020E01100000004F020E01180000004EC4 -:10154000020E012000000000020E01280000000031 -:10155000020E01140000006F020E011C0000006E5C -:10156000020E012400000000020E012C0000000009 -:10157000020E01100000005F020E01180000005E64 -:10158000020E012000000000020E012800000000F1 -:10159000020E01140000007F020E011C0000007EFC -:1015A000020E012400000000020E012C00000000C9 -:1015B0000730040000E50000083007D8000502BD30 -:1015C000073400002EF7000007348000311A0BBEEC -:1015D00007350000356F18050735800038C42561D0 -:1015E0000736000014C5339308363400398002BF33 -:1015F0000130000000000000013000040000000085 -:1016000001300008000000000130000C0000000064 -:101610000130001000000000013000140000000044 -:10162000023000200000000102300024000000020F -:1016300002300028000000030230002C00000000EF -:1016400002300030000000040230003400000001CD -:1016500002300038000000000230003C00000001B1 -:10166000023000400000000402300044000000008E -:1016700002300048000000010230004C000000036E -:101680000230005000000000023000540000000151 -:1016900002300058000000040230005C000000002E -:1016A000023000600000000102300064000000030E -:1016B00002300068000000000230006C00000001F1 -:1016C00002300070000000040230007400000000CE -:1016D00002300078000000040230007C00000003AB -:1016E0000630008000000002023000A400003FFF2E -:1016F000023000A8000003FF0230022400000000B6 -:1017000002300234000000000230024C00000000F1 -:10171000023002E40000FFFF063020000000080055 -:1017200002338BC000000001023380000000001A69 -:10173000023380400000004E023380800000001021 -:10174000023380C0000000200C3383000007A1207A -:101750000A338300000001380B3383000000138834 -:10176000023383C0000001F40C3383801DCD65007B -:101770000A3383800004C4B40B338380004C4B4095 -:101780000A331480000000000233148000000001BE -:10179000063220000000010206328020000000C84E -:1017A000063280000000000206323DA8000000045E -:1017B00006323D800000000904323DA4000102C150 -:1017C00006323D00000000200632500000000400F8 -:1017D0000632400000000004063240D00000000243 -:1017E00006326B680000000204326B70000202C215 -:1017F00006326B1000000002043274C0000202C402 -:101800000632DA40000000020632E0000000080064 -:10181000023308000100000004330C00001002C66F -:10182000023308000000000004330C40001002D610 -:1018300006322450000000B406322AD00000000214 -:1018400006321000000001A002323DB80000000086 -:101850000632500000000020063251000000002037 -:101860000632520000000020063253000000002023 -:10187000063254000000002006325500000000200F -:1018800006325600000000200632570000000020FB -:1018900006325800000000200632590000000020E7 -:1018A00006325A000000002006325B0000000020D3 -:1018B00006325C000000002006325D0000000020BF -:1018C00006325E000000002006325F0000000020AB -:1018D00006326B780000005206326E080000000CE1 -:1018E0000632DA880000000206322720000000B429 -:1018F00006322AD80000000206321680000001A03D -:1019000002323DBC00000000063250800000002082 -:101910000632518000000020063252800000002074 -:101920000632538000000020063254800000002060 -:10193000063255800000002006325680000000204C -:101940000632578000000020063258800000002038 -:10195000063259800000002006325A800000002024 -:1019600006325B800000002006325C800000002010 -:1019700006325D800000002006325E8000000020FC -:1019800006325F800000002006326CC0000000526A -:1019900006326E380000000C0632DA9000000002B9 -:1019A00002322A300000000006324010000000021F -:1019B0000632D0000000000602322A340000000087 -:1019C00006324020000000020632D0180000000657 -:1019D00002322A38000000000632403000000002C7 -:1019E0000632D0300000000602322A3C000000001F -:1019F00006324040000000020632D04800000006D7 -:101A000002322A400000000006324050000000026E -:101A10000632D0600000000602322A4400000000B6 -:101A200006324060000000020632D0780000000656 -:101A300002322A4800000000063240700000000216 -:101A40000632D0900000000602322A4C000000004E -:101A500006324080000000020632D0A800000006D6 -:101A6000072004000093000008200780001002E611 -:101A7000072400002ADE0000072480002E050AB893 -:101A80000824E4A061D202E8012000000000000068 -:101A900001200004000000000120000800000000F8 -:101AA0000120000C000000000120001000000000D8 -:101AB00001200014000000000220002000000001AE -:101AC0000220002400000002022000280000000381 -:101AD0000220002C00000000022000300000000462 -:101AE0000220003400000001022000380000000045 -:101AF0000220003C00000001022000400000000421 -:101B00000220004400000000022000480000000104 -:101B10000220004C000000030220005000000000E2 -:101B200002200054000000010220005800000004C0 -:101B30000220005C000000000220006000000001A4 -:101B40000220006400000003022000680000000082 -:101B50000220006C00000001022000700000000460 -:101B60000220007400000000022000780000000441 -:101B70000220007C0000000306200080000000021C -:101B8000022000A400003FFF022000A8000003FF85 -:101B900002200224000000000220023400000000A5 -:101BA0000220024C00000000022002E40000FFFFBF -:101BB000062020000000080002238BC00000000166 -:101BC0000223800000000010022380400000001269 -:101BD0000223808000000030022380C00000000E3D -:101BE000022383C0000001F40223148000000001DE -:101BF0000A231480000000000622100000000042AA -:101C000006227020000000C80622700000000002BA -:101C1000022211E80000000006223000000000C08F -:101C2000062240700000008006225280000000045E -:101C30000622670000000100062290000000040058 -:101C400004226B08002002EA02230800013FFFFF84 -:101C500004230C000010030A022308000000000007 -:101C600004230C400010031A06228100000000A08B -:101C7000062286000000004006228C000000003C86 -:101C80000622B0000000020006228800000000804A -:101C900006228DE00000003C0622404000000006C5 -:101CA00006228380000000A006228700000000407A -:101CB00006228CF00000003C0622B8000000020062 -:101CC00006228A000000008006228ED00000003C20 -:101CD000062240580000000606228000000000088E -:101CE000022211480000000006223300000000021A -:101CF000062260400000003006228020000000081C -:101D00000222114C000000000622330800000002ED -:101D1000062261000000003006228040000000081A -:101D200002221150000000000622331000000002C1 -:101D3000062261C00000003006228060000000081A -:101D40000222115400000000062233180000000295 -:101D50000622628000000030062280800000000819 -:101D60000222115800000000062233200000000269 -:101D70000622634000000030062280A00000000818 -:101D80000222115C0000000006223328000000023D -:101D90000622640000000030062280C00000000817 -:101DA0000222116000000000062233300000000211 -:101DB000062264C000000030062280E00000000817 -:101DC00002221164000000000622333800000002E5 -:101DD0000622658000000030021610000000002876 -:101DE00002170008000000020217002C0000000388 -:101DF0000217003C00000004021700440000000825 -:101E000002170048000000020217004C000000907A -:101E1000021700500000009002170054008000904C -:101E20000217005808140000021700600000008A22 -:101E300002170064000000800217006800000081A3 -:101E40000217006C000000800217007000000006FE -:101E500002170078000007D00217007C0000076C12 -:101E600002170038007C1004021700040000000F65 -:101E70000616402400000002021640700000001CFC -:101E80000216420800000001021642100000000184 -:101E90000216422000000001021642280000000144 -:101EA0000216423000000001021642380000000114 -:101EB00002164260000000020C16401C0003D09085 -:101EC0000A16401C0000009C0B16401C000009C4B0 -:101ED0000216403000000008021640340000000CDA -:101EE0000216403800000010021640440000002096 -:101EF0000216400000000001021640D80000000158 -:101F000002164008000000010216400C000000010B -:101F100002164010000000010216424000000000BE -:101F2000021642480000000006164270000000023F -:101F30000216425000000000021642580000000045 -:101F40000616428000000002021660080000042409 -:101F50000216600C00000410021660100000041449 -:101F60000216601C0000FFFF021660200000FFFF49 -:101F7000021660240000FFFF021660280000FFFF29 -:101F800002166038000000200216603C00000020AD -:101F90000216604000000034021660440000003564 -:101FA00002166048000000230216604C0000002466 -:101FB0000216605000000025021660540000002642 -:101FC00002166058000000270216605C000000291D -:101FD000021660600000002A021660640000002BF8 -:101FE000021660680000002C0216606C0000002DD4 -:101FF0000616607000000052021661B80000000171 -:10200000061661BC0000001F0216623807FFFFFFC2 -:102010000216623C0000003F0216624007FFFFFF0D -:10202000021662440000000F011662480000000022 -:102030000116624C00000000011662500000000012 -:1020400001166254000000000116625800000000F2 -:102050000116625C000000000116626000000000D2 -:1020600001166264000000000116626800000000B2 -:102070000116626C00000000011662700000000092 -:102080000116627400000000011662780000000072 -:102090000116627C000000000C166000000003E8DE -:1020A0000A166000000000010B1660000000000A24 -:1020B0000216804000000006021680440000000561 -:1020C000021680480000000A0216804C000000053D -:1020D0000216805400000002021680CC00000004AA -:1020E000021680D000000004021680D40000000414 -:1020F000021680D800000004021680DC00000004F4 -:10210000021680E000000004021680E400000004D3 -:10211000021680E800000004021688040000000493 -:10212000021680300000007C021680340000003D62 -:10213000021680380000003F0216803C0000009C20 -:10214000021680F000000007061680F4000000056B -:102150000216880C0101010102168108000000002E -:102160000216810C00000004021681100000000419 -:1021700002168114000000020216881008012004D3 -:1021800002168118000000050216811C00000005DF -:1021900002168120000000050216812400000005BF -:1021A0000216882C20081001021681280000000861 -:1021B0000216812C00000006021681300000000784 -:1021C000021681340000000002168830010101204F -:1021D000061681380000000402168834010101014E -:1021E00002168148000000000216814C0000000425 -:1021F0000216815000000004021681540000000203 -:1022000002168838080120040216815800000005D3 -:102210000216815C000000050216816000000005C6 -:1022200002168164000000050216883C2008100197 -:1022300002168168000000080216816C000000068A -:102240000216817000000007021681740000000170 -:102250000216884001010120021681780000000169 -:102260000216817C0000000102168180000000013E -:102270000216818400000001021688440101010158 -:1022800002168188000000010216818C0000000403 -:1022900002168190000000040216819400000002E2 -:1022A00002168848080120040216819800000005E3 -:1022B0000216819C00000005021681A000000005A6 -:1022C000021681A4000000050216881420081001DF -:1022D000021681A800000008021681AC000000066A -:1022E000021681B000000007021681B40000000150 -:1022F0000216881801010120021681B800000001B1 -:10230000021681BC00000001021681C0000000011D -:10231000021681C4000000010216881C010101019F -:10232000021681C800000001021681CC00000004E2 -:10233000021681D000000004021681D400000002C1 -:102340000216882008012004021681D8000000052A -:10235000021681DC00000005021681E00000000585 -:10236000021681E4000000050216882420081001EE -:10237000021681E800000008021681EC0000000649 -:10238000021681F0000000070216E40C00000000B5 -:1023900002168828010101200616E410000000043E -:1023A0000216E000010101010216E4200000000015 -:1023B0000216E424000000040216E42800000004D1 -:1023C0000216E42C000000020216E00408012004BA -:1023D0000216E430000000050216E4340000000597 -:1023E0000216E438000000050216E43C0000000577 -:1023F0000216E008200810010216E4400000000860 -:102400000216E444000000060216E448000000073B -:102410000216E44C000000000216E00C010101204D -:102420000616E450000000040216E010010101014C -:102430000216E460000000000216E46400000004DC -:102440000216E468000000040216E46C00000002BA -:102450000216E014080120040216E47000000005D2 -:102460000216E474000000050216E478000000057E -:102470000216E47C000000050216E0182008100196 -:102480000216E480000000080216E4840000000642 -:102490000216E488000000070216E48C0000000128 -:1024A0000216E01C010101200216E4900000000168 -:1024B0000216E494000000010216E49800000001F6 -:1024C0000216E49C000000010216E0200101010157 -:1024D0000216E4A0000000010216E4A400000004BB -:1024E0000216E4A8000000040216E4AC000000029A -:1024F0000216E024080120040216E4B000000005E2 -:102500000216E4B4000000050216E4B8000000055D -:102510000216E4BC000000050216E02820081001A5 -:102520000216E4C0000000080216E4C40000000621 -:102530000216E4C8000000070216E4CC0000000107 -:102540000216E02C010101200216E4D00000000177 -:102550000216E4D4000000010216E4D800000001D5 -:102560000216E4DC000000010216E0300101010166 -:102570000216E4E0000000010216E4E4000000049A -:102580000216E4E8000000040216E4EC0000000279 -:102590000216E034080120040216E4F000000005F1 -:1025A0000216E4F4000000050216E4F8000000053D -:1025B0000216E4FC000000050216E03820081001B5 -:1025C0000216E500000000080216E50400000006FF -:1025D0000216E508000000070216E03C0101012098 -:1025E00002168240003F003F0216824400000000B5 -:1025F0000216E524003F003F0216E5280000000017 -:1026000002168248000000000216824C003F003F84 -:102610000216E52C000000000216E530003F003FE6 -:1026200002168250010001000216825401000100CE -:102630000216E534010001000216E5380100010030 -:1026400006168258000000020216E53C0000000059 -:102650000216E540000000000216826000C000C0C3 -:102660000216826400C000C00216E54400C000C02B -:102670000216E54800C000C0021682681E001E0057 -:102680000216826C1E001E000216E54C1E001E0083 -:102690000216E5501E001E00021682704000400027 -:1026A00002168274400040000216E55440004000CB -:1026B0000216E55840004000021682788000800033 -:1026C0000216827C800080000216E55C800080009B -:1026D0000216E56080008000021682802000200043 -:1026E00002168284200020000216E56420002000EB -:1026F0000216E5682000200006168288000000020D -:102700000216E56C000000000216E57000000000F3 -:102710000216829000000000021682940000000061 -:102720000216E574000000000216E57800000000C3 -:1027300002168298000000000216829C0000000031 -:102740000216E57C000000000216E5800000000093 -:10275000021682A000000000021682A40000000100 -:10276000061682A80000000A021681F400000C0878 -:10277000021681F800000040021681FC00000100F2 -:1027800002168200000000200216820400000017DA -:1027900002168208000000800216820C000002006F -:1027A00002168210000000000216821801FF01FFCD -:1027B0000216821401FF01FF0216E51001FF01FF5E -:1027C0000216E50C01FF01FF0216823C0000001317 -:1027D000021680900000013F021680600000014058 -:1027E00002168064000001400616806800000002A6 -:1027F00002168070000000C00616807400000007FA -:102800000216809C00000048021680A000000048CC -:10281000061680A400000002021680AC00000048EA -:10282000061680B000000007021682380000800003 -:1028300002168234000025E40216809400007FFF17 -:1028400002168220000F000F0216821C000F000FDC -:102850000216E518000F000F0216E514000F000F16 -:10286000021682280000000002168224FFFFFFFFEC -:102870000216E520000000000216E51CFFFFFFFF26 -:102880000216E6BC000000000216E6C000000002CE -:102890000216E6C4000000010216E6C800000003AC -:1028A0000216E6CC000000040216E6D00000000686 -:1028B0000216E6D4000000050216E6D80000000764 -:1028C000021680EC000000FF02140000000000016E -:1028D0000214000C0000000102140040000000017E -:1028E0000214004400007FFF0214000C00000000EE -:1028F00002140000000000000214006C0000000040 -:102900000214000400000001021400300000000165 -:1029100002140004000000000214005C000000002B -:10292000021400080000000102140034000000013D -:102930000214000800000000021400600000000003 -:102940000202005800000032020200A0031500201D -:10295000020200A403150020020200A801000030BA -:10296000020200AC08100000020200B000000033B8 -:10297000020200B400000030020200B80000003182 -:10298000020200BC00000003020200C000000006BA -:10299000020200C400000003020200C8000000039D -:1029A000020200CC00000002020200D00000000081 -:1029B000020200D400000002020200DC000000005D -:1029C000020200E000000006020200E40000000431 -:1029D000020200E800000002020200EC0000000217 -:1029E000020200F000000001020200FC00000006EC -:1029F0000202012000000000020201340000000277 -:102A0000020201B0000000010202020C00000001FD -:102A1000020202140000000102020218000000027B -:102A200002020404000000010202040C0000004045 -:102A300002020410000000400202041C0000000416 -:102A40000202042000000020020204240000000210 -:102A50000202042800000020060205000000001207 -:102A600004020480001F032A020200600000000F1D -:102A70000202006400000007020200680000000B70 -:102A80000202006C0000000E020200700000000E46 -:102A90000602007400000003020200F400000004BB -:102AA0000202000400000001020200080000000110 -:102AB0000202000C000000010202001000000001F0 -:102AC00002020014000000010202001800000001D0 -:102AD0000202001C000000010202002000000001B0 -:102AE0000202002400000001020200280000000190 -:102AF0000202002C00000001020200300000000170 -:102B0000020200340000000102020038000000014F -:102B10000202003C0000000102020040000000012F -:102B2000020200440000000102020048000000010F -:102B30000202004C000000010202005000000001EF -:102B400002020108000000C8020201180000000291 -:102B5000020201C400000000020201CC00000000DB -:102B6000020201D400000002020201DC00000002A7 -:102B7000020201E4000000FF020201EC000000FF7D -:102B800002020100000000000202010C000000C867 -:102B90000202011C00000002020201C80000000045 -:102BA000020201D000000000020201D80000000271 -:102BB000020201E000000002020201E8000000FF42 -:102BC000020201F0000000FF020201040000000008 -:102BD00002020108000000C8020201180000000201 -:102BE000020201C400000000020201CC000000004B -:102BF000020201D400000002020201DC0000000217 -:102C0000020201E4000000FF020201EC000000FFEC -:102C100002020100000000000202010C000000C8D6 -:102C20000202011C00000002020201C800000000B4 -:102C3000020201D000000000020201D800000002E0 -:102C4000020201E000000002020201E8000000FFB1 -:102C5000020201F0000000FF020201040000000077 -:102C600002020108000000C8020201180000000270 -:102C7000020201C400000000020201CC00000000BA -:102C8000020201D400000002020201DC0000000286 -:102C9000020201E4000000FF020201EC000000FF5C -:102CA00002020100000000000202010C000000C846 -:102CB0000202011C00000002020201C80000000024 -:102CC000020201D000000000020201D80000000250 -:102CD000020201E000000002020201E8000000FF21 -:102CE000020201F0000000FF0202010400000000E7 -:102CF00002020108000000C80202011800000002E0 -:102D0000020201C400000000020201CC0000000029 -:102D1000020201D400000002020201DC00000002F5 -:102D2000020201E4000000FF020201EC000000FFCB -:102D300002020100000000000202010C000000C8B5 -:102D40000202011C00000002020201C80000000093 -:102D5000020201D000000000020201D800000002BF -:102D6000020201E000000002020201E8000000FF90 -:102D7000020201F0000000FF020201040000000056 -:102D80000728040000C00000082807A8000B03491A -:102D9000072C000032FC0000072C800035780CC0A6 -:102DA000072D00003AC11A1F072D800039E228D0F4 -:102DB000072E00001C3E3749082E3710391E034BE2 -:102DC00001280000000000000128000400000000AD -:102DD00001280008000000000128000C000000008D -:102DE000012800100000000001280014000000006D -:102DF0000228002000000001022800240000000238 -:102E000002280028000000030228002C0000000017 -:102E100002280030000000040228003400000001F5 -:102E200002280038000000000228003C00000001D9 -:102E300002280040000000040228004400000000B6 -:102E400002280048000000010228004C0000000396 -:102E50000228005000000000022800540000000179 -:102E600002280058000000040228005C0000000056 -:102E70000228006000000001022800640000000336 -:102E800002280068000000000228006C0000000119 -:102E900002280070000000040228007400000000F6 -:102EA00002280078000000040228007C00000003D3 -:102EB0000628008000000002022800A400003FFF56 -:102EC000022800A8000003FF0228022400000000DE -:102ED00002280234000000000228024C000000001A -:102EE000022802E40000FFFF06282000000008007E -:102EF000022B8BC000000001022B800000000000AC -:102F0000022B804000000018022B80800000000C83 -:102F1000022B80C0000000660C2B83000007A1205C -:102F20000A2B8300000001380B2B8300000013885C -:102F3000022B83C0000001F40C2B8340000001F43D -:102F40000A2B8340000000000B2B8340000000058B -:102F50000A2B83800004C4B40C2B83801DCD650034 -:102F60000A2B1480000000000B2B8380004C4B4088 -:102F7000022B148000000001062A29C8000000046A -:102F8000042A29D80002034D062A208000000048A8 -:102F9000062A9020000000C8062A900000000002C7 -:102FA000062A21A800000086062A20000000002032 -:102FB000022A23C800000000042A23D00002034F85 -:102FC000042A249800040351022A2C500000000017 -:102FD000022A2C1000000000042A2C0800020355CD -:102FE000042A300000020357062A300800000100BE -:102FF000062A404000000010042A40000010035937 -:10300000062A6AC000000002062A6B0000000004C5 -:10301000042A840800020369022B08000000000053 -:10302000042B0C000010036B022B080001000000B1 -:10303000042B0C400008037B022B08000200000058 -:10304000042B0C6000080383062AC000000000D88F -:10305000062A24A800000014062A254800000022A1 -:10306000042A25D00002038B062A266800000022CD -:10307000042A26F00002038D062A27880000002279 -:10308000042A28100002038F062A28A80000002224 -:10309000042A293000020391062AA000000000281B -:1030A000062AA1400000000C042A29E00002039334 -:1030B000062A502000000002062A503000000002BC -:1030C000062A500000000002062A501000000002EC -:1030D000022A520800000001042A6AC8000203956F -:1030E000062A6B1000000042062A6D200000000432 -:1030F000062ABCD000000002062AC360000000D8E7 -:10310000062A24F800000014062A25D80000002210 -:10311000042A266000020397062A26F800000022EF -:10312000042A278000020399062A2818000000229A -:10313000042A28A00002039B062A29380000002246 -:10314000042A29C00002039D062AA0A0000000282E -:10315000062AA1700000000C042A29E80002039F3F -:10316000062A502800000002062A503800000002FB -:10317000062A500800000002062A5018000000022B -:10318000022A520C00000001042A6AD0000203A1A6 -:10319000062A6C1800000042062A6D300000000468 -:1031A000062ABCD800000002022AC6C000000000A7 -:1031B000042A29F0001003A3062A50480000000E3C -:1031C000062AB00000000006022AC6C40000000063 -:1031D000042A2A30001003B3062A50800000000E93 -:1031E000062AB01800000006022AC6C80000000027 -:1031F000042A2A70001003C3062A50B80000000EEB -:10320000062AB03000000006022AC6CC00000000EA -:10321000042A2AB0001003D3062A50F00000000E42 -:10322000062AB04800000006022AC6D000000000AE -:10323000042A2AF0001003E3062A51280000000E99 -:10324000062AB06000000006022AC6D40000000072 -:10325000042A2B30001003F3062A51600000000EF0 -:10326000062AB07800000006022AC6D80000000036 -:10327000042A2B7000100403062A51980000000E47 -:10328000062AB09000000006022AC6DC00000000FA -:10329000042A2BB000100413062A51D00000000E9F -:1032A000062AB0A800000006021010080000000165 -:1032B0000210105000000001021010000003D000A6 -:1032C000021010040000003D091018000200042341 -:1032D0000910110000280623061011A00000001894 -:1032E00006102400000000E00210201C0000000076 -:1032F0000210202000000001021020C00000000287 -:10330000021020040000000102102008000000014B -:1033100009103C000005064B091038000005065056 -:10332000091038200005065506104C000000010069 -:1033300002104028000000100210404400003FFF2F -:103340000210405800280000021040840084924A75 -:1033500002104058000000000210800000001080A1 -:10336000021080AC00000000021080380000001045 -:103370000210810000000000061081200000000201 -:1033800002108008000002B502108010000000004A -:10339000061082000000004A021081080001FFFFB1 -:1033A00006108140000000020210800000001A8018 -:1033B0000610900000000024061091200000004A32 -:1033C000061093700000004A061095C00000004AE5 -:1033D0000210800400001080021080B00000000184 -:1033E0000210803C00000010021081040000000068 -:1033F00006108128000000020210800C000002B5B7 -:103400000210801400000000061084000000004A32 -:103410000210810C0001FFFF06108148000000022D -:103420000210800400001A80061090900000002412 -:10343000061092480000004A061094980000004AC6 -:10344000061096E80000004A02108000000010807C -:10345000021080AC00000002021080380000001052 -:103460000210810000000000061081200000000210 -:1034700002108008000002B5021080100000000059 -:10348000061082000000004A021081080001FFFFC0 -:1034900006108140000000020210800000001A8027 -:1034A0000610900000000024061091200000004A41 -:1034B000061093700000004A061095C00000004AF4 -:1034C0000210800400001080021080B00000000391 -:1034D0000210803C00000010021081040000000077 -:1034E00006108128000000020210800C000002B5C6 -:1034F0000210801400000000061084000000004A42 -:103500000210810C0001FFFF06108148000000023C -:103510000210800400001A80061090900000002421 -:10352000061092480000004A061094980000004AD5 -:10353000061096E80000004A02108000000010808B -:10354000021080AC0000000402108038000000105F -:10355000021081000000000006108120000000021F -:1035600002108008000002B5021080100000000068 -:10357000061082000000004A021081080001FFFFCF -:1035800006108140000000020210800000001A8036 -:103590000610900000000024061091200000004A50 -:1035A000061093700000004A061095C00000004A03 -:1035B0000210800400001080021080B0000000059E -:1035C0000210803C00000010021081040000000086 -:1035D00006108128000000020210800C000002B5D5 -:1035E0000210801400000000061084000000004A51 -:1035F0000210810C0001FFFF06108148000000024C -:103600000210800400001A80061090900000002430 -:10361000061092480000004A061094980000004AE4 -:10362000061096E80000004A02108000000010809A -:10363000021080AC0000000602108038000000106C -:10364000021081000000000006108120000000022E -:1036500002108008000002B5021080100000000077 -:10366000061082000000004A021081080001FFFFDE -:1036700006108140000000020210800000001A8045 -:103680000610900000000024061091200000004A5F -:10369000061093700000004A061095C00000004A12 -:1036A0000210800400001080021080B000000007AB -:1036B0000210803C00000010021081040000000095 -:1036C00006108128000000020210800C000002B5E4 -:1036D0000210801400000000061084000000004A60 -:1036E0000210810C0001FFFF06108148000000025B -:1036F0000210800400001A80061090900000002440 -:10370000061092480000004A061094980000004AF3 -:10371000061096E80000004A021205B00000000101 -:103720000212049000E383400212051400003C10D2 -:103730000212066C00000001021206700000000078 -:1037400002120494FFFFFFFF02120498FFFFFFFF25 -:103750000212049CFFFFFFFF021204A0FFFFFFFF05 -:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5 -:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5 -:10378000021204BCFFFFFFFF021204C0FFFFFFFF95 -:10379000021204C4FFFFFFFF021204C8FFFFFFFF75 -:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55 -:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D -:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D -:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED -:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD -:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD -:1038000002120500FFFFFFFF02120504FFFFFFFF8A -:1038100002120508FFFFFFFF0212050CFFFFFFFF6A -:1038200002120510FFFFFFFF021204D4FF802000E8 -:10383000021204B4F0005000021204B8F0001000AC -:1038400002120390000000080212039C000000080E -:10385000021203A000000008021203A400000002EC -:10386000021203BC00000004021203C000000005A5 -:10387000021203C400000004021203D00000000082 -:103880000212036C00000001021203680000003FF6 -:10389000021201BC00000040021201C00000180822 -:1038A000021201C400000803021201C8000008034C -:1038B000021201CC00000040021201D000000003FF -:1038C000021201D400000803021201D8000008030C -:1038D000021201DC00000803021201E000010003F3 -:1038E000021201E400000803021201E800000803CC -:1038F000021201EC00000003021201F000000003BC -:10390000021201F400000003021201F8000000039B -:10391000021201FC0000000302120200000000037A -:103920000212020400000003021202080000000359 -:103930000212020C00000003021202100000000339 -:103940000212021400000003021202180000000319 -:103950000212021C000000030212022000000003F9 -:1039600002120224000000030212022800002403B5 -:103970000212022C0000002F021202300000000987 -:103980000212023400000019021202380000018401 -:103990000212023C000001830212024000000306F2 -:1039A0000212024400000019021202480000000640 -:1039B0000212024C0000030602120250000003062D -:1039C00002120254000003060212025800000C8684 -:1039D0000212025C000003060212026000000306ED -:1039E00002120264000000060212026800000006D3 -:1039F0000212026C000000060212027000000006B3 -:103A00000212027400000006021202780000000692 -:103A10000212027C00000006021202800000000672 -:103A20000212028400000006021202880000000652 -:103A30000212028C00000006021202900000000632 -:103A40000212029400000006021202980000000612 -:103A50000212029C00000006021202A000000306EF -:103A6000021202A400000013021202A800000006C5 -:103A7000021202B000001004021202B4000010048E -:103A80000212032400106440021203280010644054 -:103A9000021205B400000001021201B00000000192 -:103AA0000600A000000000160200A0EC5554000023 -:103AB0000200A0F0555555550200A0F400005555E0 -:103AC0000200A0F8F00000000200A0FC5554000025 -:103AD0000200A100555555550200A104000055559E -:103AE0000200A108F00000000200A18C5554000063 -:103AF0000200A190555555550200A194000055555E -:103B00000200A198F00000000200A19C000000004B -:103B10000200A1A0000100000200A1A400005014B6 -:103B20000200A1A8000000000200A45C00000C003C -:103B30000200A61C000000030200A06CFF5C000055 -:103B40000200A070FFF55FFF0200A0740000FFFFFD -:103B50000200A078F00003E00200A07C000000005A -:103B60000200A0800000A0000600A0840000000564 -:103B70000200A0980FE000000600A09C00000007D3 -:103B80000200A0B8000004000600A0BC0000000372 -:103B90000200A0C8000010000600A0CC0000000336 -:103BA0000200A0D8000040000600A0DC00000003D6 -:103BB0000200A0E8000100000600A22C00000004A2 -:103BC0000200A10CFF5C00000200A110FFF55FFFE6 -:103BD0000200A1140000FFFF0200A118F00003E0A2 -:103BE0000200A11C000000000200A1200000A000B3 -:103BF0000600A124000000050200A1380FE000002B -:103C00000600A13C000000070200A15800000800C7 -:103C10000600A15C000000030200A1680000200073 -:103C20000600A16C000000030200A17800008000E3 -:103C30000600A17C000000030200A1880002000031 -:103C40000600A23C0000000400000000000000008C -:103C50000000003100000000000000000000000033 -:103C60000000000000000000000000000000000054 -:103C700000000000000000000000000000310032E1 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA000000000000000000000320056000000008C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000000000000056008C000000000000000002 -:103CE000008C009000900094009400980098009C34 -:103CF000009C00A000A000A400A400A800A800ACA4 -:103D000000AC00B100B100B300B300B5000000008A -:103D100000000000000000000000000000000000A3 -:103D200000000000000000000000000000B50102DB -:103D30000102010A010A01120112011B011B0124E7 -:103D40000124012D012D01360136013F013F0148BB -:103D5000014801510151015A00000000000000001B -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E00000000000000000000015A015F00000000F7 -:103E100000000000015F0160016001610161016259 -:103E2000016201630163016401640165016501666A -:103E300001660167000000000000000000000000B3 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000167016C016C0179017901860000000095 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB00000000000000000000186018700000000F3 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000018701BE00000000000000008B -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100001BE01E9000000000000000000000000F8 -:103F20000000000000000000000000000000000091 -:103F300000000000000000000000000001E9021A7B -:103F40000000000000000000021A022102210228E5 -:103F50000228022F022F02360236023D023D0244A1 -:103F60000244024B024B02520252028A000000003D -:103F700000000000028A028E028E029202920296D5 -:103F80000296029A029A029E029E02A202A202A631 -:103F900002A602AA02AA02FA02FA031103110328D6 -:103FA0000328032B032B032E032E03310331033489 -:103FB000033403370337033A033A033D033D034019 -:103FC00003400381038103880388038F038F0393D6 -:103FD000039303970397039B039B039F039F03A3F1 -:103FE00003A303A703A703AB03AB03AF03AF03B064 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:10401000000000000000000003B003C20000000028 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000003C203D703D703DA03DA03DD5D -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:1040700003DD040A00000000000000000000000052 -:104080000000000000000000000000000000000030 -:10409000000000000000000000000000040A050D00 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C0000000000000000000050D0514051405188F -:1040D0000518051C000000000000000000000000A2 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000051C055C00000000000000003E -:10410000055C05650565056E056E05770577058017 -:1041100005800589058905920592059B059B05A4E7 -:1041200005A405FD05FD0613061306290629062D1F -:10413000062D063106310635063506390639063DA7 -:10414000063D064106410645064506490649065014 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000006500656000000008D -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A0000000000006560659000000000000000054 -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D0000659065F0000000000000000000000001B -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:104200000000000000000000065F066E066E067DDE -:10421000067D068C068C069B069B06AA06AA06B996 -:1042200006B906C806C806D706D70748000000002A -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000748075B075B076C076C077DE1 -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000010000000204C00003098000040E4029 -:1042F00000051300000617C000071C8000082140BD -:1043000000092600000A2AC0000B2F80000C344050 -:10431000000D3900000E3DC0000F428000104740E4 -:1043200000114C00001250C00013558000145A4078 -:1043300000155F00001663C00017688000186D400C -:1043400000197200001A76C0001B7B80001C8040A0 -:10435000001D8500001E89C0001F8E800020934034 -:10436000000020000000400000006000000080000D -:104370000000A0000000C0000000E00000010000FC -:1043800000012000000140000001600000018000E9 -:104390000001A0000001C0000001E00000020000D8 -:1043A00000022000000240000002600000028000C5 -:1043B0000002A0000002C0000002E00000030000B4 -:1043C00000032000000340000003600000038000A1 -:1043D0000003A0000003C0000003E0000004000090 -:1043E000000420000004400000046000000480007D -:1043F0000004A0000004C0000004E000000500006C -:104400000005200000054000000560000005800058 -:104410000005A0000005C0000005E0000006000047 -:104420000006200000064000000660000006800034 -:104430000006A0000006C0000006E0000007000023 -:104440000007200000074000000760000007800010 -:104450000007A0000007C0000007E00000080000FF -:1044600000082000000840000008600000088000EC -:104470000008A0000008C0000008E00000090000DB -:1044800000092000000940000009600000098000C8 -:104490000009A0000009C0000009E000000A0000B7 -:1044A000000A2000000A4000000A6000000A8000A4 -:1044B000000AA000000AC000000AE000000B000093 -:1044C000000B2000000B4000000B6000000B800080 -:1044D000000BA000000BC000000BE000000C00006F -:1044E000000C2000000C4000000C6000000C80005C -:1044F000000CA000000CC000000CE000000D00004B -:10450000000D2000000D4000000D6000000D800037 -:10451000000DA000000DC000000DE000000E000026 -:10452000000E2000000E4000000E6000000E800013 -:10453000000EA000000EC000000EE000000F000002 -:10454000000F2000000F4000000F6000000F8000EF -:10455000000FA000000FC000000FE00000100000DE -:1045600000102000001040000010600000108000CB -:104570000010A0000010C0000010E00000110000BA -:1045800000112000001140000011600000118000A7 -:104590000011A0000011C0000011E0000012000096 -:1045A0000012200000124000001260000012800083 -:1045B0000012A0000012C0000012E0000013000072 -:1045C000001320000013400000136000001380005F -:1045D0000013A0000013C0000013E000001400004E -:1045E000001420000014400000146000001480003B -:1045F0000014A0000014C0000014E000001500002A -:104600000015200000154000001560000015800016 -:104610000015A0000015C0000015E0000016000005 -:1046200000162000001640000016600000168000F2 -:104630000016A0000016C0000016E00000170000E1 -:1046400000172000001740000017600000178000CE -:104650000017A0000017C0000017E00000180000BD -:1046600000182000001840000018600000188000AA -:104670000018A0000018C0000018E0000019000099 -:104680000019200000194000001960000019800086 -:104690000019A0000019C0000019E000001A000075 -:1046A000001A2000001A4000001A6000001A800062 -:1046B000001AA000001AC000001AE000001B000051 -:1046C000001B2000001B4000001B6000001B80003E -:1046D000001BA000001BC000001BE000001C00002D -:1046E000001C2000001C4000001C6000001C80001A -:1046F000001CA000001CC000001CE000001D000009 -:10470000001D2000001D4000001D6000001D8000F5 -:10471000001DA000001DC000001DE000001E0000E4 -:10472000001E2000001E4000001E6000001E8000D1 -:10473000001EA000001EC000001EE000001F0000C0 -:10474000001F2000001F4000001F6000001F8000AD -:10475000001FA000001FC000001FE000002000009C -:104760000020200000204000002060000020800089 -:104770000020A0000020C0000020E0000021000078 -:104780000021200000214000002160000021800065 -:104790000021A0000021C0000021E0000022000054 -:1047A0000022200000224000002260000022800041 -:1047B0000022A0000022C0000022E0000023000030 -:1047C000002320000023400000236000002380001D -:1047D0000023A0000023C0000023E000002400000C -:1047E00000242000002440000024600000248000F9 -:1047F0000024A0000024C0000024E00000250000E8 -:1048000000252000002540000025600000258000D4 -:104810000025A0000025C0000025E00000260000C3 -:1048200000262000002640000026600000268000B0 -:104830000026A0000026C0000026E000002700009F -:10484000002720000027400000276000002780008C -:104850000027A0000027C0000027E000002800007B -:104860000028200000284000002860000028800068 -:104870000028A0000028C0000028E0000029000057 -:104880000029200000294000002960000029800044 -:104890000029A0000029C0000029E000002A000033 -:1048A000002A2000002A4000002A6000002A800020 -:1048B000002AA000002AC000002AE000002B00000F -:1048C000002B2000002B4000002B6000002B8000FC -:1048D000002BA000002BC000002BE000002C0000EB -:1048E000002C2000002C4000002C6000002C8000D8 -:1048F000002CA000002CC000002CE000002D0000C7 -:10490000002D2000002D4000002D6000002D8000B3 -:10491000002DA000002DC000002DE000002E0000A2 -:10492000002E2000002E4000002E6000002E80008F -:10493000002EA000002EC000002EE000002F00007E -:10494000002F2000002F4000002F6000002F80006B -:10495000002FA000002FC000002FE000003000005A -:104960000030200000304000003060000030800047 -:104970000030A0000030C0000030E0000031000036 -:104980000031200000314000003160000031800023 -:104990000031A0000031C0000031E0000032000012 -:1049A00000322000003240000032600000328000FF -:1049B0000032A0000032C0000032E00000330000EE -:1049C00000332000003340000033600000338000DB -:1049D0000033A0000033C0000033E00000340000CA -:1049E00000342000003440000034600000348000B7 -:1049F0000034A0000034C0000034E00000350000A6 -:104A00000035200000354000003560000035800092 -:104A10000035A0000035C0000035E0000036000081 -:104A2000003620000036400000366000003680006E -:104A30000036A0000036C0000036E000003700005D -:104A4000003720000037400000376000003780004A -:104A50000037A0000037C0000037E0000038000039 -:104A60000038200000384000003860000038800026 -:104A70000038A0000038C0000038E0000039000015 -:104A80000039200000394000003960000039800002 -:104A90000039A0000039C0000039E000003A0000F1 -:104AA000003A2000003A4000003A6000003A8000DE -:104AB000003AA000003AC000003AE000003B0000CD -:104AC000003B2000003B4000003B6000003B8000BA -:104AD000003BA000003BC000003BE000003C0000A9 -:104AE000003C2000003C4000003C6000003C800096 -:104AF000003CA000003CC000003CE000003D000085 -:104B0000003D2000003D4000003D6000003D800071 -:104B1000003DA000003DC000003DE000003E000060 -:104B2000003E2000003E4000003E6000003E80004D -:104B3000003EA000003EC000003EE000003F00003C -:104B4000003F2000003F4000003F6000003F800029 -:104B5000003FA000003FC000003FE000003FE00138 -:104B600000000000000001FF0000020000007FF8CC -:104B700000007FF800000CDF0000150000000001BD -:104B80000000000100000001FFFFFFFFFFFFFFFF2B -:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 -:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 -:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 -:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 -:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 -:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0 -:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0 -:104C200000000000FFFFFFFF00000000FFFFFFFF8C -:104C3000FFFFFFFF00000000FFFFFFFF000000007C -:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF -:104C500000000000FFFFFFFF00000000FFFFFFFF5C -:104C60000000000300BEBC20FFFFFFFF00000000AB -:104C7000FFFFFFFF00000000FFFFFFFF0000000339 -:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92 -:104C900000000000FFFFFFFF0000000300BEBC207B -:104CA000FFFFFFFF00000000FFFFFFFF000000000C -:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F -:104CC00000000000FFFFFFFF00000000FFFFFFFFEC -:104CD0000000000300BEBC2000002000000040C017 -:104CE00000006180000082400000A3000000C3C0FB -:104CF0000000E4800001054000012600000146C0DC -:104D000000016780000188400001A9000001C9C0BE -:104D10000001EA8000020B4000022C0000024CC09F -:104D200000026D8000028E400002AF000002CFC082 -:104D30000002F0800003114000033200000352C063 -:104D400000037380000394400003B5000003D5C046 -:104D50000003F6800004174000043800000458C027 -:104D60000004798000049A40000080000001038064 -:104D70000001870000020A8000028E0000031180FB -:104D8000000395000004188000049C0000051F80AB -:104D90000005A300000626800006AA0000072D805B -:104DA0000007B100000834800008B80000093B800B -:104DB0000009BF00000A4280000AC600000B4980BB -:104DC000000BCD00000C5080000CD400000D57806B -:104DD000000DDB0000007FF800007FF80000192ABA -:104DE0000000350000001900001000000000000065 -:104DF00000000000FFFFFFFF400000004000000037 -:104E000040000000400000004000000040000000A2 -:104E10004000000040000000400000004000000092 -:104E20004000000040000000400000004000000082 -:104E30004000000040000000400000004000000072 -:104E40004000000040000000400000004000000062 -:104E50004000000040000000400000004000000052 -:104E60004000000040000000400000004000000042 -:104E7000400000004000000000007FF800007FF8C4 -:104E8000000005C700001500FFFFFFFFFFFFFFFF49 -:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:104F0000FFFFFFFFFFFFFFFF400000004000000029 -:104F10004000000040000000400000004000000091 -:104F20004000000040000000400000004000000081 -:104F30004000000040000000400000004000000071 -:104F40004000000040000000400000004000000061 -:104F50004000000040000000400000004000000051 -:104F60004000000040000000400000004000000041 -:104F70004000000040000000400000004000000031 -:104F800040000000400000000000100000002080F1 -:104F900000003100000041800000520000006280EB -:104FA0000000730000008380000094000000A480D3 -:104FB0000000B5000000C5800000D6000000E680BB -:104FC0000000F700000107800001180000012880A0 -:104FD000000139000001498000015A0000016A8087 -:104FE00000017B0000018B8000019C000001AC806F -:104FF0000001BD000001CD800001DE000001EE8057 -:105000000001FF0000007FF800007FF80000112E73 -:105010000000350010000000000028AD0000000076 -:1050200000010001000D0205CCCCCCC5FFFFFFFF45 -:10503000FFFFFFFF7058103C000000000000000060 -:1050400000000001CCCC0201CCCCCCCCCCCC0201F9 -:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA -:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA -:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A -:10508000CCCCCCCC00000000FFFFFFFF40000000B4 -:105090004000000040000000400000004000000010 -:1050A0004000000040000000400000004000000000 -:1050B00040000000400000004000000040000000F0 -:1050C00040000000400000004000000040000000E0 -:1050D00040000000400000004000000040000000D0 -:1050E00040000000400000004000000040000000C0 -:1050F00040000000400000004000000040000000B0 -:10510000400000004000000040000000002625A0F4 -:1051100000000000002625A000000000002625A0B9 -:1051200000000000002625A000000000000E023252 -:10513000011600D60010000000000000002625A087 -:1051400000000000002625A000000000002625A089 -:1051500000000000002625A00000000000720236BA -:10516000012300F300100000000000000000FFFF1A -:10517000000000000000FFFF000000000000FFFF33 -:10518000000000000000FFFF000000000000FFFF23 -:10519000000000000000FFFF000000000000FFFF13 -:1051A000000000000000FFFF000000000000FFFF03 -:1051B000000000000000FFFF000000000000FFFFF3 -:1051C000000000000000FFFF000000000000FFFFE3 -:1051D000000000000000FFFF000000000000FFFFD3 -:1051E000000000000000FFFF000000000000FFFFC3 -:1051F000000000000000FFFF000000000000FFFFB3 -:10520000000000000000FFFF000000000000FFFFA2 -:10521000000000000000FFFF000000000000FFFF92 -:10522000000000000000FFFF000000000000FFFF82 -:10523000000000000000FFFF000000000000FFFF72 -:10524000000000000000FFFF000000000000FFFF62 -:10525000000000000000FFFF000000000000FFFF52 -:10526000000000000000FFFF000000000000FFFF42 -:10527000000000000000FFFF000000000000FFFF32 -:10528000000000000000FFFF000000000000FFFF22 -:10529000000000000000FFFF000000000000FFFF12 -:1052A000000000000000FFFF000000000000FFFF02 -:1052B000000000000000FFFF000000000000FFFFF2 -:1052C000000000000000FFFF000000000000FFFFE2 -:1052D000000000000000FFFF000000000000FFFFD2 -:1052E000000000000000FFFF000000000000FFFFC2 -:1052F000000000000000FFFF000000000000FFFFB2 -:10530000000000000000FFFF000000000000FFFFA1 -:10531000000000000000FFFF000000000000FFFF91 -:10532000000000000000FFFF000000000000FFFF81 -:10533000000000000000FFFF000000000000FFFF71 -:10534000000000000000FFFF000000000000FFFF61 -:10535000000000000000FFFF000000000000FFFF51 -:10536000000000000000FFFF00000000FFFFFFF34F -:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4 -:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF -:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025 -:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9 -:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095 -:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3 -:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B -:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A -:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065 -:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D -:10541000302FFFFF0C30C30CC30C30C3CF3CF30064 -:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748 -:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083 -:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A -:10545000302FFFFF0C30C30CC30C30C3CF3CF30024 -:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC -:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3 -:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE -:10549000310FFFFF0C30C30CC30C30C3CF3CF30003 -:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8 -:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094 -:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2 -:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A -:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299 -:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064 -:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C -:10551000302FFFFF0C30C30CC30C30C3CF3CF30063 -:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747 -:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083 -:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519 -:10555000304FFFFF0C30C30CC30C30C3CF3CF30003 -:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB -:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042 -:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD -:10559000310FFFFF0C30C30CC30C30C3CF3CF30002 -:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7 -:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093 -:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1 -:1055D0001CBFFFFF0C30C305C30C30C3CF30001419 -:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298 -:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063 -:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B -:10561000302FFFFF0C30C30CC30C30C3CF3CF30062 -:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6 -:10563000056FFFFF0C30C30CC30C30C3CF3CC00060 -:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518 -:10565000310FFFFF0C30C30CC30C30C3CF3CF30041 -:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA -:10567000320FFFFF0C30C30CC30C30C3CF3CF30020 -:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC -:10569000310FFFFF0C30C30CC30C30C3CF3CF30001 -:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6 -:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092 -:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0 -:1056D0001CBFFFFF0C30C305C30C30C3CF30001418 -:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297 -:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062 -:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA -:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0 -:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5 -:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF -:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517 -:10575000310FFFFF0C30C30CC30C30C3CF3CF30040 -:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9 -:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0 -:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB -:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1 -:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5 -:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091 -:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4 -:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD -:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296 -:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061 -:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69 -:10581000302FFFFF0C30C30CC30C30C3CF3CF30060 -:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744 -:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F -:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B -:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0 -:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC -:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94 -:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC -:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74 -:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB -:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54 -:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA -:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34 -:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88 -:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14 -:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63 -:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3 -:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B -:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3 -:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B -:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3 -:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB -:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93 -:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB -:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73 -:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA -:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53 -:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9 -:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33 -:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87 -:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13 -:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62 -:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2 -:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A -:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2 -:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A -:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2 -:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA -:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92 -:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA -:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72 -:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9 -:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52 -:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8 -:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32 -:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86 -:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12 -:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61 -:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1 -:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39 -:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1 -:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09 -:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1 -:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9 -:105B7000000700C000028130000B815800020210B3 -:105B800000010230000F024000010330000C000051 -:105B9000000800C000028140000B81680002022062 -:105BA0000001024000070250000202C0000F000086 -:105BB000000800F000028170000B81980002025082 -:105BC00000010270000B8280000803380010000002 -:105BD0000008010000028180000B81A80002026021 -:105BE00000018280000E829800080380000B0000F4 -:105BF000000100B0000280C0000580E80002014002 -:105C000000010160000E017000038250CCCCCCCCAE -:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4 -:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C4000CCCCCCCC04002000000000000000000000 -:105C50001F8B080000000000000BFB51CFC0F003B9 -:105C60008A59051918AC84117C7A607E4ECAF43BBF -:105C7000F232303803B12B103700F1616E06862303 -:105C8000DCC4EB3F298F607BCB32309403F1766923 -:105C90000606133984B8AE0203C33C203F012AF63E -:105CA000144867CB53E6EEC182155431C564951193 -:105CB0006C452CF2C858094DBE461995AF4C40FFB3 -:105CC00040E3781D547E8F16847EAD0DA113D0E481 -:105CD0007BA1F28E507F25EA6037D789487FA7B233 -:105CE000A0B9078DDFCA88CA37E340E52741D5034D -:105CF000000749300AC8030000000000000000004F -:105D00001F8B080000000000000BED7D0D7854D5BE -:105D1000B5E83E73CE9C9949CE4C26BF4C20C04975 -:105D2000082168A4C70069B0584F2060A8D40E1499 -:105D300069AC8A032244082452EBC3ABFD328100D4 -:105D4000010204B13414A44300A5B7B43752B4D44B -:105D5000523AE0A7C5D6F7BDE0B356AFB66FB4145C -:105D60007F8A12F3AED6BE6BEBDB6BEDBD93734E49 -:105D7000664810BDED7DEFC6CFEFB0CFD93F6BAF1A -:105D8000BFBDD6DA6BEF71BBFC246F34211FC3DFBC -:105D90007584FC2F8D1092DBFF747B4934FD738476 -:105DA00064E698D1441921C372CC389944DF075571 -:105DB000DD23F5B713CF9399334350AF25D70C119B -:105DC000DA474BE67C1281BE227584E411A2780981 -:105DD000FE89FAEEE05C2F29C3577FFB587C9709B8 -:105DE00059172CCA8076CEFE09891132D95A7611FC -:105DF00022FAA4EDBC006F068557A72F289C699353 -:105E00005CB1EB0B29DC7A0CE14E2FA070D3F2C908 -:105E100091CF78C7D0F2A66B5D86075BDF4D480552 -:105E200021ABA02FDA76D35571FE5D31A03C433E05 -:105E3000DCAC427B9D181E5AF65FD51857B19DA960 -:105E4000E5D37641C2DA054B97CC261308C930D585 -:105E50007EB8583D9C7F3AAFE7D1E9F7D2FEEFE933 -:105E6000A4ED3D3900A50409FB69FF958EEFA5332C -:105E7000DF807ED389A55F3A8FEDF08F7C42BE40F4 -:105E8000FC39E7A0F3CF93CF031E487516215306C4 -:105E9000E2AF1F6F51A42F217536B8041D3418636B -:105EA0000C21D7B7265E72E550784C17013CCD9493 -:105EB00035DF185ADE765A463C6CABEDF106359C60 -:105EC000DFEC7CDA6E34EF677425C5039DCF9E2628 -:105ED0005AF60CC46FC1A46E13F8C33FA95B22B479 -:105EE000BF0283906C3A9F60232D17D176247E6683 -:105EF0000CE52FF2009B6F94FEF771513F1E331992 -:105F00000A88E6C07326E091E2A9E01EC7FB4A8634 -:105F1000BF4C62C16B217213E2E90EC0DF95C8F37A -:105F200063117FD12CC4EB50F127E011F80B723EC6 -:105F3000BEBE2651AB00DF4CA5F8037C513CA6D376 -:105F4000F9F6BEE489C985D08DD91D027C8BF95440 -:105F500032FED9C2E1DA08F81B879F5CAE1021BE81 -:105F6000B22E93C94B5C82727A199D01EDCF6732D4 -:105F7000FCCD903509C6DB5CCAF8940E20B92A071F -:105F8000C245FFB0FD660A8F668167B3B7CB2BD1E0 -:105F9000F2760A6F14F04F8E04811FC5BC3DBACB58 -:105FA00086572594E6E07306A7806FBBC9E4D80244 -:105FB00007BE27DD5DAD1285F383192EB2491ABCE9 -:105FC000DF6D7DFDD8FB77F63B287C89A0AF98CEAE -:105FD000EF8367656313C5CF66BDABD545E1D85682 -:105FE000CDE63B90CE97395E4F8FB77892653C8374 -:105FF000C9CBA73E0EC9B4CFAB32E80B965DFE38D5 -:1060000024B87034D03F153D3E35F8750ABF054FB2 -:10601000BEE2A004FDFBAE7AD04B50EE8F78010EAD -:10602000E73803E0758CEB1C47298D9A0A96ECFA49 -:10603000C8138C1162D12F58478727D3CBE9865DCF -:106040009FF84AEDFAD9A9CF15D03701686FD7D795 -:106050003D42CF083D3D69887AC6AC43788B48DF26 -:106060001FCAF3182ECFD30F253ABC147FC57B84EB -:106070009E7EE057A5941F0E829EA6E5831D04D741 -:10608000C38347498CC935D3D713786713B8DEF972 -:10609000419FBEB1E3E7CA76731AE89D3262BA7CCB -:1060A000B49F31878911A7EF0F93F8DCF1A0C78E59 -:1060B000B1F97BE97F563D7D05C7E395871B5D40C0 -:1060C000CF317BEC78BC82E3B7ECA8E33DC7DF15AA -:1060D0000EFC6D837F507CE54B1C8F634909E27198 -:1060E000EA10D73B8E47A7BEEEC3E31EAAAF29DE58 -:1060F000B2830C8F2D6D2E02FAA137E642FD585A5D -:10610000D8E842FDC9F5F6783EBFF17CBD3BC0F151 -:1061100027E02C9E6D5401DEC612E324E8E5CC7620 -:106120008A37027ABAA00ACA3B1E22489FB10FE9F9 -:106130002EAEDF109E4CBEFEEEA82E7F16E4A2F718 -:1061400021C590E9380789B1C62BF5E3379B8F9FAE -:10615000CDF1F86543B6F1A1938ED91CAF4EFC94F6 -:106160001EB0E37FAC834E63DAEDE56C075D6E90A5 -:106170001CF6C710E9E15148D49305E518DA755EBD -:106180008AFB5C5A967FFC940978D63AD8BBCC3609 -:1061900057AC908EE36F6165A54D8955513CDC0687 -:1061A00086172D8F6B2531B047E56A9324281EC7CB -:1061B00005E344A678CBAE268837E2B02F05FD8AEA -:1061C00039131473FECFF872B90FE8B52348F10EF6 -:1061D000EBE26C85B7377CE1ABFAF1EED40F5FAB45 -:1061E000B5E3FDA670BA0D5FB3F46C5B79E2E9E14B -:1061F00017A593D01F828F04DE06D0A1D55EF65777 -:10620000DBCB4EFD13951CFA678874524F91529068 -:106210008B71AE34A3B37060BDED928BDB43DED8DF -:10622000593ADE4222910CDAFF0A921805F83EA68E -:10623000E9F87DA52B9107E50BA467E7C831FDFDC3 -:106240008F52C83189DAED1245EF6A0AD2702F8970 -:10625000A7A33D4CC2DE3C4401E245A2FFDF8AFC1D -:10626000A2B8005F2382EC3D896628500E11F1A789 -:10627000239D3CFC9FF9AB9FF98B44E92BF1A70CC4 -:1062800074A4E3BB4904F9C14BDAB19C46BAF0A946 -:10629000916E7C06A8C68667900425786611039FD8 -:1062A000E48AD8637194C30782C8F7BE3F908FD346 -:1062B000FBE7B38ED36D3809FF48CA053AC4895746 -:1062C000EEE7433FE7436AAFA15ED64A19FF6A9300 -:1062D000E8BA5A86F28F7E17F988E2B702C665F5EA -:1062E00005BEB772BB7A4B9317F5CDE6A6203ED517 -:1062F000A98D61002FB33AD17107A55786AE1AD781 -:10630000D3F90FABEE89839CF85B99DF966630FC7E -:106310009EDCF8C44B8BE8FBB6428DF9412DCC9E38 -:10632000CDE0586C9B9C88ADA5F06D2DF41A56FFFE -:1063300040E8A7ADD7260EEDA7DF3B75DA23FDEBCE -:10634000AC3E9258037253A08226229B27FC930EE8 -:106350007A2DADB8A7C9AA77B40F65A6BC0AA25119 -:10636000E02B3ABF282CEF4EBE6A2BBF02F562DB52 -:10637000A967894E2B14D5C44DC0977F2A3565E98E -:106380003CFC35BA2BAA8154465E053C67B4062511 -:1063900093E22FAB5A9F0632AA119DE96BA53B04ED -:1063A000F23BA0FF91F1D01DB4BFE8B5AA7110D99E -:1063B0004A77CDF7A796872D1BEFFDBA99C4AE0A91 -:1063C000BA24A4FBA96BF3F2C1FFF591607EFA2415 -:1063D000902F951C8475EBDA25A32349DAF5CB5968 -:1063E0005CD835499FA9DAA5CBA4B1CBD26F898BF4 -:1063F000C9A1CBE5C5676619E3A3A252EE17B71290 -:106400003396040E93C3AF2971C2FC39DDF559E20E -:10641000EB6DAE2FB648A4B62BC9F74E0ECF0C7954 -:106420008F09EB6FC646B64EFA28A85D14BE2285CA -:106430003E2DED66F1FA87F8F312F450DE4320307A -:106440003943D3833EC7B8E259FE09C6DD46C79536 -:106450005D415CF704DE9DF4144F97CB87F53EB8A1 -:10646000F6C5101881A9E0D4414687D167017F861F -:1064700050D713BD943D9DE35D6A7F5F74B1793859 -:10648000FB2507985D95C1D7AF93534A9AD1EF9DED -:106490002DFC50BBDE007F18F451E701BAF01782E3 -:1064A000DE60E5CD318276566F1965E42288277467 -:1064B000A3BE2D20119463FA09CBAD5CFFAD07FD9F -:1064C000479FEF93F02DAEC9A04762A7145A69F613 -:1064D000A4BBA7258B1FDD09F231F9D2D6A92FD293 -:1064E000E7426F7829F4AF19674C505B99F3249415 -:1064F00027A75C51F60CCDB5C80D91055F30796AC0 -:10650000E1FC0E723387966B8A93C3D9B9B1223FEF -:1065100082FDE9C3D1EE50F4E1D67E3BBFCCE46A04 -:1065200087437E3AB8FCAF017EBCB479E6D5D0672C -:10653000D08899A02EE7471B9F06BACD93221B5CFB -:10654000B4DEBC7BC26E903FED40375D23F1FD268B -:10655000C0478DDE0E94239AD91D85E7E6B245A883 -:106560009F7B436CEAA9F82ACD74D9FD27A73F3851 -:1065700044791C6F44A701BC7AED7B277375A05347 -:10658000E461806B64F86415A05DD3CF9859167AE6 -:106590006597327DB882F371E66C4A37D0778A19F5 -:1065A0009AE387688EB91FE63BD4F153F13DD89D3D -:1065B00080AF6CCEE72D06E3732107195C0E5AE01D -:1065C0003BE06B12E3FB96607930D93AB187AFF3C9 -:1065D000DFE37C5F4092EBA193AE4BB7C3C6D367BA -:1065E000095DC1009EF749E469987F1697B3CCEA2C -:1065F000980BE011F234DB38539D9D03768A5E0ED2 -:1066000076B118F71DCE6F0BBDE6AFA17D4D71B30E -:106610009245E735AE8C18A05E6715674A563EFF77 -:106620006D5FFDF0F3505F2BEB46BF7CB076DD7CF9 -:106630007EF3A4F0CBC87F0FB42B5EA47BF815ECDF -:10664000E7816EE2B5E89B228E6779E3A92AA04331 -:106650006F2309025FCED71B9F9680BF43E1752E43 -:10666000CB3C66E9763B9EF2F99BD0EFC8463B7F78 -:10667000D69076855CC2BA314A8AF400BCB31FE872 -:10668000467833AB993F4CE1EE45BDF2E9C3FDF1ED -:10669000C5E07E13843517E47D1FEA330A9F225339 -:1066A00038C6CD8E2B5988F7330AC047F1ACCA16CD -:1066B000391FAA7CEF00E0260F2EE72DF08F29600E -:1066C00027477264E03B61F7264E12E66FD9E396E6 -:1066D000C25E0E84A8BD4CE525B32641C03FCE3E28 -:1066E0002D1BD7D32AC36A8804FE9FB063B3B85C5E -:1066F0000AB8B6723B794B5308E5285BEB390D714C -:10670000FEADF92E630D01F9AD40FB6D4755220436 -:106710007E60B0B262E31DB47D5B938EF5373619AF -:10672000D87E4353253EDB6B5E47FB776B88D9BF32 -:106730009B9B4AB9D3C1E0CE1276728D885FDAE1B5 -:10674000A2ED6DFB1FA23E0959E25A4596F63AD3D7 -:106750003783B54F9F648F8BF5B53787D6DE67D803 -:10676000DB57998956F087833CEE2FF45E80D7097A -:1067700056BAD06F1678F694DAE9DE5E937C3F471E -:106780003C9DE3113DCD367F12AD43F85671F85272 -:10679000F5B38EC75F44D9CDED4567BD15325F1F98 -:1067A000F9BE54908FB5C3A4F8B0C461B239DF6D9F -:1067B0009DCDFC321264F13AE197B909B1F9656EE9 -:1067C000BE1F8565D4F751A68F1DF08BF62A6F9FEB -:1067D0000A0ED5D9DF59DA4F85A51F079CA9E073AA -:1067E000EE939137EDFDA4D65F8E76E7874687015D -:1067F000EDC06A28B596B31CE5E18EFA458EEF57D9 -:1068000038BE973BCAD738EA4F7394BFE4A83FD746 -:1068100051FEBAA3FE22C7F7658EEFAB1CE57FB22F -:10682000D72FBBEB93E1F7FF333C09B91A88979850 -:106830006D9FD7295745243E2A0E7E43E6734BE0D1 -:106840005342969473CC1761712D129F60F55FFFD0 -:10685000A845FE00EB58E747665A98CAD581F6E787 -:1068600003A08FC4FBF3D2AB81F13A21F56A7C25FA -:106870008B03B5A3DCA411E5F544295049C2F8996E -:10688000575B8C28F716D3F7567DD5CEE4AD18FCB0 -:1068900022DA2EBA5D45BB2F3A92C4C6D2766A81FF -:1068A000BDBE9BF74F7258FFF89EF65BAE307F215E -:1068B000146EAF02D91D5EDB75129E4EFC84A64796 -:1068C000AF7E06E20B3B981F7E6006F5032C7AEE46 -:1068D0006685E9B7DB944BF64B5F9C28F7F77FE0C2 -:1068E0005B9AD14CAB1C0020C0EFFF963706F18CB1 -:1068F00051109F639B07189F1B49F81F8FC381BBD3 -:1069000008EBCB48ED34C6DBF4BAE029D0757395BB -:10691000121CEF7B52CF7818CF957EFE6AB62EFE02 -:10692000ED63B47B38FE429B2B12518A3FB24D354A -:10693000C61258520D94238F425A3CE5C01E0CDFFC -:106940006B61D565EF157F16C4D9C2585641EFC2A9 -:106950003A067C24C3FE761CCB7E92C07206B76FCB -:10696000C781B3087E00D125A6270D09F6994237C5 -:10697000503F3CC9BA1196AAC62993FBE39492CE24 -:10698000E29152DB337F91205E594A74B64FC5E3E2 -:10699000821B65E96388B70687B6CF13BAC54E5721 -:1069A000A2B49339163EBEA58F9E0C5F63426CFE67 -:1069B000A16D6A23F8310766D9F940D497954BF653 -:1069C00007774E18F3D9F141A63206E119C807B787 -:1069D00006213E2D4529DED2878EB7A06C7E5DC193 -:1069E00079122CFF40326F053A89B242CC05D6F2BB -:1069F0006FE5F0422847A791D246ADBF1FFA7E71DE -:106A00008AF74B93BD1F27ECD5B36CFD2EE1323EC8 -:106A10006C4FD005766461C7AA34AB7D55C2D7E907 -:106A2000473B8EF860BEBBEB93EB3FF1DCC2FDBD94 -:106A300054F502527718E841262BE460127BFC499A -:106A4000E06F8B1E0D38ECC2EA966815B4CFAA75BC -:106A500011880BD3F51DEDBA426E1FEE9C1A9554AA -:106A60002A873B7611B48FB35A16F9ACF3C9E7F312 -:106A7000D9393B2F0DEC957D8B177D09FD156AF7F4 -:106A8000CB181F8F6C82FEF36BD83EBF13BECD7C3C -:106A90007EED8B199E9CDFD355124926874F2ADC49 -:106AA000CF55A212C9EBDF37D97CF2BE5F8DA7E3C9 -:106AB0009554BA0C9FDE0FE7B83E7B2981F84ABF98 -:106AC00046096E027BAA43B5D999FBF63CB86B31F7 -:106AD000F837F43DA88347AE6D1C1EA6703DFAE55D -:106AE00025CFDE057CBFCE45401F0938B432BB9DA3 -:106AF0007BB24F3EEDE3D27E991F47970F39C9FE17 -:106B0000C9E5E2A3838F9B8A4F9CEBA9930F2E6567 -:106B10007DB851BEFCF9FD18E490C293C7F3B58669 -:106B2000D5EACC6FE37294ED158A848D93C7F92C66 -:106B30006BF6833EE0B35DB5E5283FBDB31749A0D2 -:106B40004F441E54AAF152C193EE6EF7411C74D704 -:106B5000E207A56478CB8FB0F890F3BDE966FAB48C -:106B60004D6997A07DAA7AA3DC9C1FB85CE5F379F8 -:106B700085A6C6C380AF3C43216B28BE76CC5E544D -:106B800055027C47E510E22AD53504ED877C93ED6C -:106B90000B0529BE9EA4EBDECEC5C488D37A3B4D3F -:106BA000D5B61F23E4D0C98F3B175F5CBF10AB7F06 -:106BB0004EF95F716B6C7FB09814831DB523857D92 -:106BC00076A9F80D2D76B1F86875F920FABCF9525E -:106BD000D7A9F9D7023F0E35DFCDA12FC853BB6629 -:106BE00095805F6B507D4192E1C7AE1F06C387134E -:106BF000FF13009FE99F1D3E9DDFB3DD3CBE3D447A -:106C00007CB4D516FD0FDC034F51DF391FD14EE4A4 -:106C1000A77D91F4C820FF2670E818F0260C7C565A -:106C200093303EBB95C857DCB4FE4CD28865117FCB -:106C3000AA53828C1E3CFF45EC732BD319DF8F9B2C -:106C400048629DB07E4C9DCB377F15F39C178C36E8 -:106C50000A47127F8A903538EF118EF558C427867F -:106C6000D5B7CF2EA7FD8E98EDC2F8C588CA23B63A -:106C7000752CC0E547F4B7BB7268EBF3238EF5F9CA -:106C8000112581F95D8F54AE6986E546C97A339442 -:106C9000ACFDB80E3B5EB77ED4E50B278167F7E20B -:106CA0006398C7B5BBF2E2F1934706E19B7172723C -:106CB0007BF68B1EB6AFB43BD37B334B2E5A6DCBDA -:106CC0004320B256681D77F74724337C517D629785 -:106CD00097AD6E9E6FE0277EE0FF54F810CFCF1A7D -:106CE0000F8F4E6B5C164ED2BEC4C3EC89759924CF -:106CF0002A533E79F4652506790E84EBE18A9BF5EB -:106D000018D80BEB404950FDFB6815C1EF1599FCF5 -:106D1000FBC33AE6558DE8205195AE67235E5ABC19 -:106D20002393D66B5B4C3DC7C2FEF76DC6A956D800 -:106D3000177EE20517C6732B7C71AF41E755C9D7A3 -:106D4000C1DD8B4F61DE71748F628C45FD2E11A900 -:106D500002BD785B1CF3845B61EBBDF1A04FA7ED36 -:106D600077E909ECE79B534E7975D82F2FE8F6C2E7 -:106D70003CB754B2F5F2C8E2A2AF96205AED79269C -:106D800033E5A9DD261D6FCB62B65F9199E8F67AEF -:106D9000E87C02B50AB99EC217D0D87CDBD6911820 -:106DA000AC53E53C9F442273D01FCE77E409E5390C -:106DB000F24D82C6CCB760DF3F08FBFB3009B97EDD -:106DC000C755A06F1B5C3C0DD54439F5F3F9F90D9F -:106DD00013EBCF948FFB60DF77578B12C4F5CFD1C5 -:106DE000AF731E411239694AD80F8EB3EB21B64EEC -:106DF00006276B06D558B429873B48E1CEA643B693 -:106E0000D8E11678758EE37794DF14FC3C828C050C -:106E10003D24E2CC027E27DFE654C48E3E4FE7BB22 -:106E2000FB050DD7EBDD95CFDFD200EB7CA907F397 -:106E300023BEF4C1A1FA7FA1CF5FBF77AC189E3704 -:106E4000E41F98D4007880FC8889A42F8E97073D92 -:106E5000A3FDCAF59A18AF6C5F8B3B075F45FDB485 -:106E6000BCE5D4CB75108FCEAF2768FFE62B8C3FE7 -:106E7000FD2DAE5833853FE79A76E48711B571044E -:106E80005AABED92A29678A7C8FBF6D747308FE2AF -:106E9000FADA76CCF7F6F3B8AF7F523BDA4933E44F -:106EA00057BD68AF71FA89FC77217F4EFA942CEEBA -:106EB000AE817E46B42806803DA2BED105709554B1 -:106EC000D2358BD2ADA4A34B62FE1FCBA76729CFCF -:106ED000F419AEC3BC2CB287E5178A3CF040BD9DC7 -:106EE0007EC1BEFCF9880BFCEFC20EC7F770CD1B4C -:106EF0008C0FEDF42C52393D4B781E21C7C3088E00 -:106F0000872DF57C7F4EF3C62E66D7BEC0F7E75EB1 -:106F100084F98F1BF8FDA614FAF746D0BFE0B7BA84 -:106F2000BA5B011FE41A17FA714E38B6D633BD7733 -:106F30004075D9ECF8CB1DFF36AEFF6557E2EF3256 -:106F40007E7DDFFCFF3EE3DFFF771E7FD3DF19FF8F -:106F5000BBFECEF33FF41F3CFFF9A592CD4FEB549F -:106F6000BDD8DF4F3C223E66D7DFB22BB9BFFDBA9A -:106F7000EAB2E5138BFCC4E9B5E6428897F80D76D2 -:106F8000DEC3D9DF0CF9B956D083BB785E36D5A302 -:106F900026E4A9664C1179324CFFD570FD57C3F534 -:106FA000DF91147AB5BC92E9776A5FC4F442583233 -:106FB000DAD19F099C56303FFB08A1CB0CE835DDA8 -:106FC00093343F3B8FC3EDD4A7795C9F963FE7781E -:106FD000CFF5A8739D2FEC8B9F128C9FFE7795E7C2 -:106FE000033BF4AAC0C3AE4A662FE7CC4D6E0FB682 -:106FF00039E8A84D6AC4FC03273D5E57997F2DE808 -:10700000B1D06BBEA2E6A6A67782D3FB3A4EEFDFE5 -:10701000A83C1F8AE789A4A277A5878DF379FFD9B9 -:107020005033CC265C857490399D64D2D68DF15F47 -:10703000F24D62F52FB77E44ED1058FF35CD584321 -:10704000CB9FCF212E9174FF91D89FA37FEE6E1618 -:107050004795735487BFE5B483BD513837B3DB74AC -:10706000C5A285604F74EE5E09EBD30B6998A7BC8F -:107070003BB3E339F4E7DA272A0087B01B098FCF47 -:107080008249C1F2509CFB4E76BB7FF7475D71B0E1 -:10709000BF828512C6FD5AF50773929EC773D8FB4F -:1070A0009AC76FF377C9F543B3DBD7727A537F3151 -:1070B000D76391EFB5FE9913591E547510F67724D6 -:1070C00073A60BE2E9A9FA8148EF39CB7E539D62A2 -:1070D0008E84FE24F01F4BFBFD47420A587C5ECC99 -:1070E0007FA8E707EAEF62FBDE1CAF39D7747D2A81 -:1070F0007EA4F0FB453D919FE7ACE7F4C7AF779BDB -:1071000053607E43857F2F301CC4B3CBE49A64F177 -:107110008304D7AF5AF8B1676FA25527CD93587C37 -:107120009F9A6DD6FDB4B61CA52659BCEB975C4E54 -:107130007EA3EA5CAFC7499684F92404E625E4D12E -:1071400039FED57CDCAB2F73FC17B85C5FCDE59ABC -:107150001003F763528D5BC5F586787ED271137C80 -:10716000DE552A8F6B0C32EE1C3ECF399739DFF398 -:107170007CDC39439CEF423EDEC2CB1CF7433EEE43 -:10718000C2218E7B37C7EFDD978967C52BF17E86DD -:1071900086E7663E5EF3658E1BE4E3360F71DCED39 -:1071A0001CBFDB2F13CF057CDCED0E3CA792DFCE9E -:1071B000CB1CAFD4CBE4E700975FA75E13E36BF97A -:1071C000AE30B4DF1DB2F77383878D2F9E24FE315E -:1071D000FAAF23F8BEEE9495F72E32938C2BEA3B50 -:1071E000D7E354E3DCC2E335E229C609F0FDD02938 -:1071F000D7D07192E047D4BF5A657A3055FFCB386B -:107200003CCB2E711EA27E15F43F3975FFF7713805 -:10721000EE73C03F58FFA2FE9C41E06FE570B45E84 -:1072200022FCA2FEC241FAFF0E87E33B9708BFA8EB -:107230007FF720F87984C3F1C825C22FEA370FD22F -:10724000FFE31C8EC72F117E517FFB20F8798AC384 -:10725000F1D425C22FEA1FE89377BBFC69E23E0612 -:107260008394429EF1289266E0FD0646E224F801EE -:10727000DA6A76BF01E9729E87B29CA3A2227EF2EF -:10728000BE9228D4DF7B178BFBEDBD9AA01FB137D0 -:1072900097E729F3B896C6EDC1BD57B338C8DE10DD -:1072A000FD6EF1CF44BC68AFC1F29C7B0B581EB39E -:1072B00056D68E26260E97C74D441DF269D8B92A98 -:1072C00061EF89F3556B799C6AAF49304EB5B78C45 -:1072D0009577579398ABD072EEAA348EF9A760D801 -:1072E000423CB6FFDC984956975BF23156C731DF16 -:1072F00040E179231421C49697E138AF25F60F6F4A -:1073000032CC19A0E60A27B1FDBCC2B0DD7FA88748 -:10731000435CB4FEEFB99E0C4E4A7E9EE6B05761C8 -:10732000F4E3F99AF3F8FC05DECA393DB7CE79AF3C -:107330007B3A9DE7B353DD983FFAEC698EC7A9729B -:107340008CED9F1377B27338A9E26C5A47E3293862 -:107350009F7BD373C40032FAF798EB748CAB7D84B7 -:10736000FC8771353AEE4D7BDA15E0BF591DFA7492 -:107370008807CE7B4E5FAB41DE7507314C40EF474F -:10738000DFC07EB25A881163A46A0EA29DEB88CF3B -:10739000F17393223E07E16AAB7F398BCFBBBC25EB -:1073A000B80EB6EECAAB3D36FB7516F733BF627A40 -:1073B000ECE725F9F9C7590E3FB3C36B8FD7691DA9 -:1073C000E11910FF96E79D31E1FCF3B8B0141C46BB -:1073D0003FDF16DEAE407C72D69E46CC5F4FB5BF17 -:1073E00095F1F05CBFD57E17FBD9BFD973717B5D7A -:1073F000C41944DCE134E4157BC04F0F71BA30BED0 -:1074000012FC91354FB2F1498797E9910E2F8BE32A -:10741000FF179F7CBA7CF23BAF3DFED001DFA83C5A -:107420009618C9F7E9EBBCEA7FC9EB674087802F64 -:10743000391D487D862D8F58E45539F1B681E34DCD -:1074400094BD29CEBD14F8F83AEBF4EB5F8D54C12E -:10745000BC449C8690FB1DFB9B538D8BC5256471A2 -:107460005F8CEB5519E653EAE3FA47210AF6EF98E9 -:1074700007CA7D1E9E53643038FA5BC7CFAB89794B -:10748000B98BC326DCB742C7C0FD3EC8573F520682 -:10749000EB63D0366FD3C7D69B4DA58CDF36952ACC -:1074A000B174965F65BFB7A8B8D39BCCAE104F62DE -:1074B000BDB7A26820BC6A71246A8547E5F038FB35 -:1074C000999B129E3A5BFCEB52E1F18C27A41BF8CE -:1074D000568911A697BF61EBCF551AC3F3FDA9FAE0 -:1074E00051743E2F075D528DEF2DB0E741A93969E8 -:1074F000367E57B42C479E9483BFFAE242431BCF9B -:10750000796EB1859F4771B6F729EDC44882779FA0 -:10751000EECCC788211D9CE76ADC4107DC8EFEDBD0 -:10752000E05D923C1C71DFD006BEAE6D5462686FA8 -:1075300045299890EFB98EF3A5128CE1BD5EDFF678 -:107540004949E74F8CE4EBAD529C1C7E6F811DEFE7 -:107550006A4E969D0E4AF2731C1B85DC070F98F647 -:107560007BAC9C727EDCB8D87ADE77AF96F43BF9C0 -:10757000633AA5833EC73D0943A4AFF261369E6BD3 -:10758000EF2B53BD0AF15A2A2398CFEBAC7F46E08C -:10759000EFD54E845FE8E9F43D22AFF693CD4392F8 -:1075A00008DF27B7B74F29875CCFC99CAF9F1E6400 -:1075B000FEA9E89B56ECCC2B1C1A7D7D20F7B0EE83 -:1075C0002926BF0CCB2EF7A9C6234136DF4B95FBEE -:1075D0004F0A67764D84803E53431112A1EB7C7EA7 -:1075E000A81DF7C935A9270AFE1895291DE8BC3B37 -:1075F0005B67F76658EA4DA3EDDC85AEA81BF24049 -:10760000F87D30D110E982FA108FE92CEBAFA74951 -:10761000240CFCAEE52A61782FFACB986AEF8F9A9A -:1076200009B2F51C96C817405787CEDF3D85FAA7EB -:10763000B4BD4AEDD07DC9F4491AB343D39FF29942 -:10764000982710D662C092F9936298CF995F470C41 -:10765000F0E74A3ABA498476FA6D8063327CA7F340 -:10766000D620FFA31DF7ED733CECDC7A7E7DBBB426 -:10767000D0324E691AE3EF6973BDB84E7CA38A9D80 -:10768000DBEB0E2D6AAF82F12AF97D7A390A194EA9 -:10769000F1E17FC9C3FCCF490902F809F2BC863782 -:1076A0009B48F9E2B184BCDDE4C5E7F9A6203E833E -:1076B0001FFDCF10E4B9AC9B5CA143BEF507FEBA39 -:1076C000D1B06EBCDB14C2EF5BBE65E8904F249F67 -:1076D0007A19EF8FE8E7F7A84C2A210F366102FDEF -:1076E0002CF3EFF459F6F9FBE645E7BB908EB3595E -:1076F00072DD0EE3417911F2A957562DF91F2AF7D1 -:107700001BDDEB48F8B132B8C72426DD5D6679EFA2 -:10771000A3761BACAF938348F77E7CC69A39BEAF85 -:10772000067F37FF398ED7B99517DD37696B8A77B2 -:10773000578FED2F6B29CEBBCD714FBB2E0DE2467F -:1077400070D8938E377D6EE930C0D743EEE4F72FC3 -:10775000C8C1894631D48DE6BB500EF93D2BABC66E -:10776000EBC3322DFDCFE17C299FFA29E237BD8C96 -:10777000E587D0BFD9F996FCFF82481DDE8F441AF9 -:10778000D93918B10F39FAD644336C498C5E6D3F44 -:107790001F33939FF32C5CE7C2FCD7C229A843494F -:1077A0006133BBBF6ABF6C94037F3F4C5EC88403E8 -:1077B000EB0514BE9154540BA3F67EF62F99FD0CE5 -:1077C000C401C4B9D1B52DACBF51BA715A87F849BB -:1077D000990BEDE5D1C4F042FFA3351781734563E2 -:1077E00088A59F4238476BEFD7096FA1DFE5827804 -:1077F0008780671439EA3573B07F12A3ED0BA89B1D -:107800003722097CCE71C6887A579597C7499271FD -:10781000494F33EC0B0D187F907E9BD2B81DEE279D -:1078200001D0E77B2436FFE8B3B27110E87AF72184 -:107830008CD714ACEAC075BD238DD977EBA93DA0D8 -:10784000B9C14EA1CFB1A9F9500E52C465E0FA9169 -:1078500094FF1E4DABDA9606F1B0B469DB800FD30E -:1078600014FD6B783FE76937817DCC34B31DE50F9C -:107870002E64023B6373595106C85B5AA39AD45FC6 -:107880006B4973237C7BD22405F242296FE1BC94BF -:107890007AFD3B3369B13BD7FC1E8CF397DC083E85 -:1078A000C5FBD0A25A1DF873FAD2328C7FF5764808 -:1078B00018FF7A438AA990AABD7C5EE304B82F67BB -:1078C0004E66E41168B7548EAF77537856DCDA58B9 -:1078D00002F8990DF97EB9305C94F98305AF1B0A63 -:1078E0009C072B50E26ECADFDEE0A997D8335A0519 -:1078F000FCEE859330949E8162F32DF09BFCFC1C82 -:10790000924C7AA2901718984AC8EB16BA814F6722 -:107910002DC39EAEB59C0AFF833D17D3B6AF8F85AE -:1079200055DE3025B40B62883F35684C0038E5D011 -:10793000E9BC62CB3AE7E1F3F34C5FC4EF4932B9FB -:107940007F6310AB7FEBE1F3021DFEBAA5BD3B6484 -:107950002FCBC14F771EC2EE967EF1D77340C7B5CD -:107960008FBB31EE39FD7177FC3A5A5EB14FC2756B -:10797000C67582E9F5770F4828F771BF8A7AE09DCE -:10798000A017CB0D9EEEAD5FA0E59EC765D28968BE -:10799000A9C57BA5CE89F5F4182B2FE10ED28A7DDF -:1079A0002717407F75C73C04D689153F5D7AE317DA -:1079B000687929E563A8B2E260B33A9C96EF8A49F8 -:1079C0005D50BE308D209F45B3D418E4B55C08747B -:1079D000E7DDA4E13A46F471B0BFDD9D378FF2E3F5 -:1079E000B2D86333A1DDB2C3124452E93C0E3E93D8 -:1079F0004FE15AF17D09D7C7E587D2D95D2B1C7FAE -:107A0000E7E854AEA3DF57D179823E5C4ADA6702D9 -:107A1000BD561CDCAE5AD7B9B79B4A31F5439457D3 -:107A20007C9F8E43DBADFC9164C0145742BE03AC17 -:107A3000973FF5D5EED7607ECD6A891FE6B54185C3 -:107A40007A4B630B9FF0E900DF3E7526FDBE6CCFDD -:107A50003E754919E08DDC0EEBEAF2435712DD4228 -:107A6000D7731D32FA0BAB32BD9D78BFA966BF0F2D -:107A7000A51F2E62836B19D71BD4EF53ADE7DD9E94 -:107A800048CF443E5D7E48B68D23E81F3D43D879FC -:107A9000B49FFBF13C9AA09F58AF04FD56890BFFA1 -:107AA000949E8A64F06C057AC0B91BEADFC0F3C10A -:107AB000A6103E1F6AD2914E3B018FE3585E0ABC6E -:107AC000A7725B05F756054CB8180CCEA5985590D3 -:107AD00087991566E5BC5B23927E113B5D3C77BAC6 -:107AE000230BC1C8999AFEDD190AF5C776AA91BB86 -:107AF00021641D543A6754D335AF3E3D5C916ED935 -:107B0000F75B2FB1F37D9F4BD771FEEBF355C4F7B5 -:107B1000CEDB2AF6F3F813AE933B6F5BF208C4C7D3 -:107B200069FB2FA6837FC1F7FF52B5CF5B50696B0E -:107B30009FB7A04EB49F89EDBD176FBF73C135F6D7 -:107B4000F1172C13ED6F44F8B58BC39F77FB54FBF3 -:107B5000F8B7D763FB060FA36F4FA617F3AD5B7C97 -:107B6000461CF4315EA83609F2C94B3AA19E5877FB -:107B7000A8E637217F5B3B9C59BE8958F968DA0239 -:107B80008003F2B2AC7C9451996693AB4C33CB56E4 -:107B9000CEAE196EAB9F1B2EB27D1F567B85832FF9 -:107BA000353CBF8865000A0C730AA73A5C457D54D2 -:107BB000359CD9C1F79EF061F9DE6BD8FCEE1DAEA5 -:107BC000A11C03CCE097DFAB463E67BDBF95C03D2F -:107BD0004854A7DEA945EE8379F4BFD75DF03E8D0A -:107BE000E73BA57908EABB0D8515FBA3167CB68E8D -:107BF000A4FC40CB2DE92AC33BA7C386914B425638 -:107C00007B7DFD48B516FC0D787F8706E385D7C3DD -:107C1000780D6A4F09D81DCE713C4595B671BCA34D -:107C2000EA709CEDE92C9E2AC6F18CAA738CE3AD18 -:107C3000EDE4EFF9383B80CF528DB3A1E81AFB7C1D -:107C4000462DC371F63AC6D9306A99639C34361F03 -:107C5000FA9E8F13BBD8389E3153EDF3195D8FE335 -:107C6000FCC0399FD1F58E71341C07DEC338D4F0C7 -:107C7000D5E1BE2CD5D3B304E9FF0B1FDA39AA270F -:107C8000F228DA39AFF8D0CEA1B54CA8474A997F8F -:107C90007B4F7A16D2E783344A7FCD4AE728CF3B21 -:107CA00088A25F7C270791C4284454BFADE43CB848 -:107CB000F8F09C51CDF03C363DB410FCD187FC1857 -:107CC000C77BF7D874F58E24FAE8CE76F7B98485A9 -:107CD0009FFBF42A8FC786D2D93EA4289FE3F19F49 -:107CE000D7214E449F6FB809FA436779BCA81FDEBD -:107CF000666C778EEFEB9DDBC3D6A90FB69F71A3A1 -:107D00001D11252F9451B8E7F369DCD96EBF2FB34D -:107D100081D3A3E7A71E760E889823F03EBC8E6C15 -:107D20005BBCF07727BEFC0CCBBB2323E0DEDFAFD0 -:107D3000B73EF634547B515A3872159D6FEDD1ED34 -:107D4000EE11B4FCAE3BB1C0D02CFDD4BAF1DCBD19 -:107D5000F0436E8EB86DF6F32D75F6F26D0E7BFA6C -:107D6000D5F422B13FCBC6D5636EA0D77CD863A52E -:107D700024BC0D9E987C17447A2D08B2B6029E86CC -:107D8000FBDD248EEB5D2217E39CD15C8CD344C4D5 -:107D9000BAE5806F81DB6B86293D17DC27231E9DAA -:107DA000F0264EA49B2EEAE7243AFEB71BCEF10C38 -:107DB00006FFEDABEDDF49D46DBB8740F0C1D76A5C -:107DC000ABF69FB5F0C7CD9159FBCFDAF034C7566B -:107DD000BEADF1665BFDDB572FB47D5F18BDCBF602 -:107DE000FD8ED6BB6DE53BDBEFB3D55FDAD16CFB27 -:107DF0007E576CA3EDFBF243DB6DE5155DBB6CF5C7 -:107E00001B8EEDB37D779D18FF15F4037F23E37977 -:107E1000E7F7B5735BC17E7B3FA8E07ECE9B7CFF1E -:107E2000EE6D7EDFCF4AE0BD29203F13BDE0373441 -:107E3000A45179A6B6C4042D777DEB54D02304AFAA -:107E4000D428D746AC8F5267770A3F9F2877A8245B -:107E50009E0DDB2BFD71D81EB9FFBB92A0DF27A6BC -:107E6000FE2E772849BF2B092569BF17A49E12B0A3 -:107E70001FA32F7B929E03EF974B32825CE43EC997 -:107E8000F32E5267F5DFE66B2C3EF44CFAB4F95A48 -:107E90002EDC8FC1E4BDFE48FE34F01BEAD57849E4 -:107EA000B27D9BBEF1BA24BC3770BEC6E4E5AED845 -:107EB000085B3C6DF9A13136B97F292D729346EBF1 -:107EC0009D3F29A39E25F1A7467DF52A18DF9C0F2B -:107ED000EFC9B15C5C1F5F6C32F79FA57EC04B4D54 -:107EE00035F8FCD7A6F0FEB3D4257CB5A916CBBFD8 -:107EF0006F8AE033D15487CFD79B1AF1FBD9A6D52F -:107F0000583ED714C5E79B4DADF87CBBA91DBF9F5C -:107F10006FEAC0F2BB4D317C0A3910F62E09737B33 -:107F2000526C981056EEE57390F3441CD3C0FBA33B -:107F30007AB50F4AC08EEE7DC98379B7A9F0E4E423 -:107F4000BBD4F43371BD5F12B3C799C5D397C6E8EC -:107F5000E373911AC891D83856C5385ADA2FAE440F -:107F60007B9CBE57D865B231634E927B3BF142E4B5 -:107F70006183D349D43FF7DD7FAF585406F42942DB -:107F80003CA53D253732BAED37BE7AD5E0F8439BA4 -:107F90002F7F201EA55FFC6E14C4A7DEC915F8EC68 -:107FA0001E05C12D450BEF023EEC3DEAC179F51EE1 -:107FB0004F67F92810541B42FEEBF243BE98553F21 -:107FC000ACE8CA8CD9F5457ECCAA2F7A4FEF0F804A -:107FD000DCAF0AC9B1B313813F4CCE1F8CEF44FF15 -:107FE0002BBA0A639AAD1F7BB9B75DAAC17B1F8903 -:107FF0009E312F89FF219EAB422A8EF3F6A1319844 -:108000007F40FDC4D85916EF8CB17143312B5FD638 -:10801000AF4E8F9DCDEE872F55BF9F367C841C259C -:108020007FF0A63E8F3BD89328FFA6E2FD6EC7DD0A -:108030001FC0BAE3A1FF7F8CF9420A9645BF0D5DD0 -:1080400072D403E779C961DB78B49D2E7C7458AF94 -:1080500052D3DD9E0FFE7BE0255CB7D9F9F2089C78 -:108060002FA7FD5D50B456E973FDE7CB1B385FAE1B -:10807000F026D4087DF5CED13117CD0779BBE97450 -:1080800050190B7904ED7871445DD7F86AD08FEF01 -:108090001C5D9B07F1B4E572EFBDC9CECD7EA8B1E2 -:1080A000381B89B97B1296F988F80C21B45F6F3FB1 -:1080B000FCC0E9E72C65A7BE164F979FC5DD571E8C -:1080C0003E33F30B14FE95C7DE53018E635AC4E5AD -:1080D000B7CC5FE2E7EB971D7A4D85F9BDE98E9647 -:1080E000DC7F113D35104E2D64DB0F8D926E90E3D9 -:1080F00045EC3718809FBEF60A15CDB77EED26F009 -:10810000BB0E62BF429C7B584CC201C0D7A2A3CB1E -:10811000313EFCD61337707BAEBD02F8E31DE2AAF8 -:1081200081F9BD439E0F4CB4E0AFD8CFFC18D2CA42 -:10813000EC18712E90DAB336BB666987BDBC84CC6F -:10814000CD03BDB1E42137895114DD452CF72FD182 -:1081500079E7F899BDBB9434AE077B4EF130FF60F0 -:1081600051902823A83E5DF193872BC0EEBFD2CF5C -:10817000F61D451CE3AE2C66EF2DCB89A9B09FF010 -:1081800087A313E77F01B8CF135B0FEB32C948BE5B -:10819000FF7747AB1DBEC1E077C22BCEBD0F88A7CE -:1081A0007038E44352D2FCB4297ECE775C8FACF1B8 -:1081B000DBEDFC0D8EF26C3F8FB3CA44063ABF1361 -:1081C000F4465D19F81DCFD9468F788CB53ADCA7F7 -:1081D000150E037F51BB6002B1D4FBA316C1F7E7B4 -:1081E000A5E796E03973253E01F3F1BC04F314557D -:1081F000CE0F725A6002F91CC4491BD1A95FEB0B68 -:10820000744279BD9F9D836A0039A5FD6D09CC3C00 -:108210000D717D2F698F9B85B0FF6D8F7FFB747B08 -:10822000391DE409F409BC007A1804E345E9A5F610 -:108230007A7EC35E5ED687A7B86C3DF711F06A718F -:10824000F89D2152A99CB7DACD2BBD0C7EB8111C2C -:10825000EADFC3EDF995448F62DE6288F1C13DB378 -:1082600058DEC43D7EDD88D2EF9262E2F9880DD0FF -:10827000D4B28E357C28919845AF37283D2AF065D9 -:10828000C3870ABEDFAB45BE057855898976AE97B0 -:10829000220DF6AF15ADC666F792027E2FA0237FA2 -:1082A000A1CD1FB4F97B422FB8B95EA4FA62833F17 -:1082B00017F460CF4CB6AF9E50D9FE0EABA7F6D7E1 -:1082C0006B033852D5F3F5D7DB9EACDE8A9FFCF00A -:1082D000892895F765FFF2ED006CA6BDA5B4E741CE -:1082E000FE43FDC17501E0E337956800E6FD562CBD -:1082F00079DEFB2FB9BE837C27382FBF92D3E9EDFF -:108300007FDE7C23E0FD83836E3C6FDF70C813F754 -:108310005022AE3C7A17E3A7439ED7587903FE6EEE -:1083200054C331BBBC2D7BF4DB793A6EEE4547F08C -:10833000FBD8D17E5E79E08F33C11E69203DA8272E -:108340009CED60FC0FB370FD5A08E7FE9DDF45BE53 -:108350005503E7FB86A39B31AFAAE1E82CCCA36AC7 -:1083600070C8791DF7438EF9EDBFB321F04162CC9F -:108370002E5EFBFDEF4C788DC273FEC0AF03922DD5 -:108380007EC4F4446FD71DDF7B524FADDFDFE57E47 -:108390007D7FBB18B6D38F313B9E1C67CF7A773C6D -:1083A000007E53FD3EB7413508A9FFE1FE47BE0BF5 -:1083B000FCFDB207E30DCB7FF8F48BD7D0F2F2C708 -:1083C000DC39B3D93434C80316748133EE90AF2B43 -:1083D000E8B0ECC74FABFA55ECFD0359FDF458FE7D -:1083E000D849955C35107FD3BB4EAAECFCB9832EDF -:1083F0005DAFCD04BB7BEDF7FFAC827CBD75422247 -:10840000C30A07B6AFDBF734DA758027A423A75376 -:108410001FDD06D02B7EE39393B05E10D6B1C1E88A -:10842000F55DE0995CE4EB1F3D09FB05FFEA3100D7 -:108430000F753FFA4600E6F386D2C8F8FBE175797E -:10844000B08F5EE78EE605F1C9DED7EDFD26F2DDE1 -:10845000D233DFCC637950663EFB5DA3683EC60134 -:10846000F7DC84F35C4222C87F750FCB9887FEBE91 -:10847000426A1E4B221FD705981E7BA3D38397DF2A -:10848000BD010A17FCC5E7E5183B6FCBF212BF2907 -:10849000F63DE0DE465A7EDFCBE8951B70897BAD6A -:1084A000BC36BE3DB0A11BE8F4F6487318C42B29B6 -:1084B0001EA21C6F12E821F9CC8C618C4E44572A05 -:1084C000783BAA27A7C37BA8DFED367D136CEDF8B8 -:1084D000BAC6C6BF878F4FE14E03FBEC8D3C6AEFF7 -:1084E0002499DFF280907F6A7F58F8CC22E74CEE27 -:1084F0000F6C64722EE43E36A706BEFFDB0B4C8E7B -:10850000A01DACF314AEF830FC7E729E847AC14399 -:10851000E2C9E4FB809BCBB7FD3BF5CAD1BE157C1D -:1085200042E15760DDEAE717B6CF4BE980F6DB9210 -:1085300087687BAB7D0EE3623DB5FFBD65BD5FCA5D -:10854000F5C13501C7EFEEECC91DD27D79F5EED846 -:1085500023DF05F9A5F20AEB4FFD0FDD9827F2A7FF -:10856000C34FBDF875CAE77FEA12726BD7A74EB941 -:10857000AD3B32992493DB3F6906492AB7F47D521B -:10858000B9D512C8CFFF51FA54E06F51C09EE7240D -:10859000F4632A3C3AF5E3DFFC3AE2D3A91FE9DFB2 -:1085A0000BA462201F0AFE137CB7EC072BF0774167 -:1085B000FAF853F05F1F7F0AFE73CED78E3FE7F7BE -:1085C0002BC15011F162FA74AF21513FC4537F2E79 -:1085D000633CF50285693DA5F385C385788E789D5A -:1085E0008FF9E717823D81AC32BC0707CB3DB9EA72 -:1085F0007AD017E27D8F8FC5BF2F847B02D63C9047 -:10860000D78ECB01D8EF4AC4484D327F846A648448 -:108610002341527D67F1E20B60FFC17869A362409C -:10862000B719B2366A35F8F9EDECBCFCE2E6AF05F5 -:10863000601FFEC2F131DB407FDDF9AC4CF8EF2862 -:108640002A906F7207A7FF9B24BA732A9DE71DC764 -:10865000995FB1B82D39BF2CE3F59768F7A8A097BB -:10866000A85FF0BA351EBE8CFF9E64DD1EC7FBE31B -:1086700037205F2D73F05584FB8D3F147C7535B921 -:108680009AFB6D2E6B3EDB0CB96C1BD825174EB3D5 -:108690003864EF7119E9D17B5862F94F100F9E02CF -:1086A000FCD0A35AF3D8CE03FF25B9DFA0EFFBE33C -:1086B000BFABB89F56A97FE29509BBE9F3FC132F26 -:1086C00097FC0CCA3FF9EDA857C8C0FAD34FFC0578 -:1086D000F7B32F9CF0201C174EFC72D4FD507ED2B5 -:1086E00083F7D55C58E361F99F27FCB1B1F07D2495 -:1086F000CB175AFBF33F4F48E0BAD482747B29C0B2 -:10870000FCB1DEE3FFFE7BC81FEE3DEED1611E0D26 -:1087100027D2717FABE1491FC6692EFCFCCF15D66D -:108720007CA6CB9DCF4A7E1FE2053FA9853CE50B89 -:10873000996CDFA0E16753F6C339A215474FAAB081 -:108740001F33FD177F9D007AE7C211664FBCEB4EC9 -:10875000EC857DD63F046EDFE086F82EACD7C309EA -:1087600069CA885D0FF7E10CC40BC3C3058A07987B -:1087700017C54B1DE8CB54F8F83FFFB0F8786F01F0 -:108780008C5F7FFCF32837FD78914CF6DE1F83A3C6 -:108790004D74FEECFD893F4F00FBE84F5DCDB8CE38 -:1087A0000F36EFFC8CFFD7E62DC58732EFCA7FD896 -:1087B0007933FE3F11D059DE9F430E06F2F94FEE9A -:1087C000C5F28FFC06C23B44F9AFFD879DFF27A48D -:1087D000FB114AF7C0E074FF6F196C5FF81F6FDE82 -:1087E00083D1FD594E777F10F2102EFCFCAF185F3D -:1087F00017F31F6CDE3BFF93CE5BD8439B5C467B3D -:108800005121E461C7BB750AE7BAD2B9ED1096925F -:1088100079DEB513AE6732987F214B2C6E4346B29A -:10882000F811E1FE46DFEF416AEC7C95A2AD67F7F7 -:10883000912906DEAFB7E98A4506E67690F29722DF -:10884000502E988ABF73EBF4BB942BBE741AECFEC7 -:1088500096660A1F1DA7C5AF04A9E544DCA5AEB8FE -:1088600067023E5F83E7061EFF7207559BDFA13953 -:10887000FC059F6EFFEEE1FD7BC9A920E42F790D79 -:1088800005F3537DA43D6ACD37F0104B3BFABD1381 -:108890007E10D0624F5E2AFEFE9CC1FC4F592AEF2B -:1088A00086BC5832DEC5EE3727EC5CF1A60223B653 -:1088B00089E55D78EDF85CDF0D785408F50FD9BCDB -:1088C000D0AF24DC9F5478174AA9CBF4D9EB717F41 -:1088D0006950FA307A8CAAE7F45965A387C0FB4542 -:1088E000E862A387C0EFA5D2C5490F27FE7F95C1D7 -:1088F000E274824EB67C905CE697C4A981FCCBC33F -:10890000FB312EF2CE3FBF7623F0E9F29FC9C44B74 -:10891000DBBF7BD84FE220BF4A4C053F6BD95119D2 -:10892000E3C2FF174BEE49A70080000000000000E3 -:108930001F8B080000000000000BED7D7B7C54D5F0 -:10894000B5F03E33672633999964F29ACCE4C52496 -:10895000811834E0248480823A218020F43AA008EF -:108960007AA38E10209827485BDAEA8F09411A1EF5 -:10897000B641E5A1453A2028ADD8061AB9A0A8838A -:108980003CC4566FA3E5DEA2450D8A82C823A51715 -:108990003FDACF5BBEB5D6DE3B73CE6402DAAFBF43 -:1089A000FBFDF3E59F937D1E7BAFBDDE6BEDB5F761 -:1089B0005CBE0C7FB73076595C196B652C83B1BAFD -:1089C0005F3B184B67ECC19D09E1C9F970DDF5E922 -:1089D000503684B1734B7A0E65C3FDD02F15DF5628 -:1089E0007C3DD43DF40EB8FFA0CAEE0F9444FB9139 -:1089F000D754A781B1E18C9DD9639B11B633A66C86 -:108A0000DB771FF5DB31DD94A044DFB33A4D342E24 -:108A1000BCE7C7E7A15F28E1414ADFFE186BE1FD33 -:108A2000FD42E1F0ED3685AD08DFB64DE620C0D160 -:108A3000B4EDCF663FC051F5EB1793BA61BCA6DD2C -:108A400046162966F47799E173632461285D8FE304 -:108A50009531BF5DA960AC11FFF5C2B5B361324B72 -:108A6000826BC7CA3F1B93F07BD327DD96E8F7756F -:108A7000BF7E7557085053F79BE793BC703DDDB53B -:108A8000358995507F0F98931953EDAAEE7DECF739 -:108A9000526ADF7E605CC65C709FDF624D1DCBF961 -:108AA000789DDF39C9103E06FD48B8617EA7F11FE9 -:108AB0000F63239D8EF4CFAF83FF47B011978D7066 -:108AC000DD96C6D80D7DF114C55788D3F3C58B1B31 -:108AD00043809F333BBFDC88F0D7FFFD2F1B7F0413 -:108AE000F863AF599D5B61DE4DBFFC8F24A4AFFCE2 -:108AF0006EAA53A1EFCEE5B29007DE3BF77E423877 -:108B000004B7CEBD7A32CF0BF33DB7E3AF2E2FBC07 -:108B1000BFF0D5719938FF852F5565327BFF709C6A -:108B20005BCC5838410B5798E8E8DD0D9D664273E1 -:108B3000AFB8C6D0637FE7FE3C84F3ECD1045F029C -:108B4000E209EE2D2A43FA009D86F2F6C380DFC6C5 -:108B5000ED3FFEB371683C3C87B20D6EA4EBA7E31A -:108B6000114EC622D9CC8DF8ED59E6B4F77DBF97EA -:108B70005E47809ED77F03BA6D5FCEC7ED00BA25F2 -:108B8000F5A5DB59FC07E8D38474B345E976910574 -:108B90007FEE298476671AD1351EBE22DF005FB5CD -:108BA0000AEFFF26A7FF874E949F9DB65E7A4D463B -:108BB0007ABD78318F01BD4F997AEE63E58CF5BCB3 -:108BC0009AE0DC0CF71F7CF58F2427E75E7AD78CC0 -:108BD00074843FBB02F33AC77AFFBA709E8D8A98BD -:108BE000E716472421298AF7C6F09409DE24BA7FC4 -:108BF0009CEE8739FF22FEB2913EE17D772A71E833 -:108C0000D1E12CA079B07006CDBB61CB9FCCC83729 -:108C1000924E481F6524D2EBF878BC2FE924E71D5B -:108C2000DB9F13F1304243B72D5C0EFBD2B5C7CCAE -:108C30000AE3D10BE0C5EF105E689FDB94A02AC960 -:108C4000FC7E0ECCE39C89CDE84038C2CA1FE3D13C -:108C500097B125349F1762E552CCEF6A727935B827 -:108C6000FF51BC3CE37452FF123F67BE8EAF9F0FB3 -:108C7000A19C03FCBBEDC183C83F8C59C227A09FB8 -:108C8000FB99C2920BA37893F09E5119E9DD33BF93 -:108C900034864330FF651DFB49CFC6CA37CCCBDFD6 -:108CA0001167BC3F8AF11A77EF1B8A7AE8CC1B7BED -:108CB00088FF1AB71F3787A09F43DB7E63EE2E899C -:108CC000F23BEAEFB0467F9FF9D5BEA1A46FB1FF9A -:108CD00038FAE684E8BF69AFBEFFA6ED7FD6F55F40 -:108CE00017EA303BED571FE7B4EA9F8EF33DDD6591 -:108CF00062A8FF4E77182784E38CFB96B05F124F73 -:108D0000CBDE35931D2B7F2F319C00785AF8EE84F3 -:108D10003F25A7E3D5EC05D4B2CE16CE579D8FF8EC -:108D2000B3912E9DEFDE63447BB20BF1784DB4DF3F -:108D30008A23CD550E90DB8A63817264AB587D30F7 -:108D4000E2A84107378C9389FA7929F4E3857E9864 -:108D5000EA7307A05F63D2F809088FD169705AE3FC -:108D6000DA55DE9FC91E604180CB0476DBABE1277C -:108D7000F7D4A4A12C19A7E731A05E5800EC85FA1E -:108D8000D96D66C52AC0C70C89BEADD0EF82C1FEC1 -:108D9000D283D05E30DBED0BC173CF1DFCBBB34E75 -:108DA0007BC8703DB6F3C22847B64B46E605D5777B -:108DB00046797B0E039560137C95DD61233B6353FD -:108DC000BDEBAAA16DAB557D8051F6993D989B9264 -:108DD00081DF99E93B4F8AA27E8EF34E6249286F6C -:108DE000B27FF99EEC97A991A1387F66612A03BBF7 -:108DF00092C338DC46319F42D6A5207FB74E49DA70 -:108E00008CED0D8E5AB2FF79AC679F1FE8F66CD2DD -:108E1000F8C3A8C7E05F03BE97DBACB7EF0316E962 -:108E2000DBF92135467EBD8600F05F619BFE7E7AD0 -:108E300055E5FC013EC6EE4BE99CA082FE4E9F5ECE -:108E4000B9231B703A69C57BBCFD7C65A907DAFFB5 -:108E5000B1BA61A20A7A24FDF795A579D0BE90FA3D -:108E60008389F4BC0E907423A8FED54327864AA2BA -:108E7000729B0160261B499E6F463C9C0D9C598647 -:108E80004F1BA67D658647F817403CE48EE478C802 -:108E9000B11FDBC1E0FD0186EE16E4CB9FBFFABF38 -:108EA00052F03D2F73D27C9D6CA9F3730B4E9E8DB7 -:108EB000BC3CEC4AFA4C659F4B3E3446E520D91544 -:108EC000BC3D05F86AD9CCE275E351D7D6FB88BF23 -:108ED000606427D943F9BE339DE85323E883705A71 -:108EE00080CF66F357582D6B177A68AC13C7514281 -:108EF000F5C6CBD77D7B78664ABE713007DE57EB6F -:108F0000BD045757867F36E2EBAF1941BACAFBEE74 -:108F10009933BC41C0EFCD2981B9380FCF9C4B7933 -:108F200008FFE41446FD55CDB5FBD1AE5ED80BEA83 -:108F30002F8E5CC9EBE6C5CCA70EEAFFF9D4D4E0CE -:108F400077B1FF82D7BD3B0F437FD7D7987D5618A7 -:108F5000E2FA45E53E358DF109A1DF21E8E6465A02 -:108F6000A2DC7D8F8551EECE27287E3FB4CF3FE433 -:108F700024BD9C5333F930DAB3F3B6FC8E08DEFF20 -:108F80009197E4113C0005E521776F72C49A44FC87 -:108F9000FC550C3F7FA5E75FFDB8E72F7B77775344 -:108FA0007F4ED11F3844F03C57D0E9BC91FBE5E738 -:108FB000177B090E701FF7A1BDFDA6E33D9922FCAA -:108FC00024419F47ACFE35480FC0FF3A2DFE7FD6A7 -:108FD0003F1D37E27B4047BAC6D2718EA5390FF5E7 -:108FE000C283818EF1A0B1D9C939DFAB40E69E9230 -:108FF00012DC82EFD7CFE83A6422689A8B506EFB7E -:10900000D259217DEEDAFB408B09DA4D48276F5F9C -:109010007A5EBFA894E8A6A16F07F67FFDDE3F1B2E -:10902000107E49D7750AB703B1DFBF92A28871EBF2 -:109030005B4C80CF0BBBCDE4FFC6BE7730C54BEF9A -:10904000C9F6504B854F0539CD34B060BC7E0FF664 -:10905000E9D7E24B88037F6F7F4EDE1FE0FF4D2D87 -:10906000FE7FD73FFEFF5DE0FFDFBF25FE8F209D27 -:10907000FBC3BFF4BBEB847EA863ABC8DFFCCC3F73 -:10908000D53510C61F6FB4933CCCDB6A243984F706 -:10909000277B5C517D32EF86E67D38DF79CF28C4AF -:1090A000B73541AEE7BF9C33F910EAF7D9ED7AFF47 -:1090B00069CE8C9019E19CBB5E7F7F5E38261E6472 -:1090C0001ABD0E7C7126CABF03B8DE7193BD340A87 -:1090D000F9A89A5B928CFED26B26EFEFC91F7FCB6B -:1090E000C836C7C17F5E6A3ED963D9CE6D06246992 -:1090F000EC3CABB11A505FCA7EC7CE2DC944BF66E7 -:1091000081C37BC5386CC022BD5DCF0F2532AFA6B1 -:10911000DFC2B6545D7B507B96EEFD6BD617E89EA2 -:109120000F0E5FAB7B7EDDB6325D7B48C78DBAF735 -:10913000AFDF3D46D72E8DDCA67B7FD8E1A9BAF6FE -:10914000F0AE7B74EF8F383A53F7FC86EE0775CF9D -:10915000479D5AA06BDFD4F343BD1F6360A427591A -:10916000A2427AF3C0E253152790E1CA95B188CFA5 -:10917000AA91FCDD03F3CD0667125E8B0C4EE08FE7 -:1091800037664F263FE0C07C97DF4BD70A3FC63F8C -:10919000CC38BA3C18C7CF1DE7FCA2E28466DC2AB3 -:1091A0008B49A7E7C639F5ED61A9227E18C0F9669B -:1091B00064AA5EBE8CCD9323666866CD1B9889E356 -:1091C000819C8D4AE57246D7ABCA59527305B641A8 -:1091D000CE2A53E3C81913F6B652F0135CFDE632FB -:1091E000642C07D9653FDEF4D2FD900AF1CA188BD2 -:1091F0002FE720CECBE04B47261C3B237080F72780 -:10920000EC332B367C1BFB2CE5DC6DF086C8AEA561 -:1092100032CA2F3D35BB289969F07B4FAA41E883BC -:10922000761E473AB70D53251E0BB4F7270C578B04 -:10923000A3F795B9933351EEDCFDE845B3BB70F06D -:1092400016D0C7664F3E5DE5FD65330C13C271E86D -:10925000DB90CAE30CE9770D8EFA5D0D88DFB3EE83 -:10926000F7D60E027C3556F790DFE536B4CF3F8453 -:10927000F3FAAD91E7CDC0B342BD305BF8D1B3276F -:109280003E3EFF10E8A7D9EF0C22FD24C7D9B03825 -:109290003258EB37E4F413576D13F06C5CEC1F5C41 -:1092A0003388E022FD20FDF4BC50C3788C7706B0F3 -:1092B000668A1BD71A586DBC7E968B7E3291E40865 -:1092C000AFD34E727276CEB12415E691E8082E47E0 -:1092D0007E9B797D5705F7C7FCBEA9C03F79917B7E -:1092E000D7E2FB796E958595BEE3675607DBF261A1 -:1092F0007E4B530D3E3BB57B147C3FE161C6D2E013 -:10930000FDA57F37123C4BDFB88161BC96606F666C -:10931000E8D7CA79ED4F7D9AF063ECB4911D64E80B -:109320009202FEBE2B687FD15DD3857EC7C5274DD7 -:1093300034DE4598A313FABFD8690CA3F37E283511 -:10934000316280B6B1CD41F63B0F7D50787F4EA79C -:1093500023ECCD8FE2455D3F9A45C0DE25E4F0F970 -:109360002F4DB587EDF934EFD5386F09A79C776E8F -:109370003F71682495DB59E62FD6D1D903315917AF -:109380008EAD82F30FFD189F34519C383BC54E7053 -:1093900086178706D798FACE6F997BEAED77033C5C -:1093A000AD478CCC08FD78BBDB091F73001F616FD4 -:1093B0005F7C9FF5E67F653012DC11E447E3FAF14C -:1093C000342F867E3D7CD7F073853D9D8F7C199C24 -:1093D0004074CE32B0ADF97DE7F1662ACFDF1E4E84 -:1093E00075D2D5EC2EE272E21E38780BF4F736EA2D -:1093F000290B8BE707FC3E95FBD3748DD54F600797 -:109400004308C785F50AD1F3A412369B006575772A -:1094100036933F20F593D16F24FF43EA290917E8DB -:10942000B10F5235F6D198FCF050ECB77F7F6DC785 -:109430003E33FA6B4E46FE9AD4A3FDF96BE8A721A2 -:10944000FF493FED54CC3C617E5F8AF97D196F7E08 -:109450007DF4EF3DCDD2CFF973EA15FCCC0C737CD3 -:10946000FD744D1AA74393D3CC283F85F132FA0FF0 -:10947000F30CE1CD988752C3D6291AFC64A5493F65 -:109480008FFB1BFDE9BDABC525052B4B48FF5EE8F7 -:10949000F226A7C235FD53A5395E3FC6452F0C43C2 -:1094A0003ACDB356DAD2004E679A1E5F4F2DEF6366 -:1094B000BFD2D238FEE8DA077F76C09F41E727EEB9 -:1094C0002AF212FE3C6957F013CFDEF15105DAA5FE -:1094D00073024F8DBD712FD7D35960AC30AFD5C05B -:1094E000FCCF9E28E6EDCB0AAD7A50BE6EA33D3090 -:1094F00008FB6FDA3DF159ADFDFE3A95E7D3983D93 -:1095000095F2ADB23F97D0FB1067DFFC9997F4FF5F -:109510005748DF68BCDD5D81F156EB4BD724A37F54 -:109520003676D7DD4EBC5E481F48783DBB2BC18FD9 -:10953000709E4D057D6CC7F688439887F872F1E1FF -:10954000542D5DCEFEEADD0A13F47376E7BB152ACF -:10955000E63344BEA6D71E5DFE434500BE0F8D61B7 -:10956000C5CD760D9F58B8BD78D2CAF31D192EF31C -:1095700032763DC4231929F4FD1A97E12778DF6874 -:10958000F943DE0994B398FCCE93266FAB1DF80C1B -:1095900062391FAE132C18ECF7CCC6FCCE1437E59D -:1095A000655A15AE4743B3791C9A5EC08AF3A13F52 -:1095B00093C168C4EF7A3CCCB7195E4938D01E41DC -:1095C000B597D8D5E147F0CB1353099FA3CE3815F3 -:1095D0008C27643E48ADE2FDF54C3387376BF24093 -:1095E000EE192AD9459BDAC1504F3F90914AF0CBF2 -:1095F0007C50D5D419814A84EB5103C533A078152A -:10960000D487D9621EF99E9DCBA56FA3BA902D1960 -:10961000267FD84AE0FF8180E724AFC18FF9D7A425 -:109620009CC85113F877D94B19FB44E347DACC4275 -:10963000DEDE3192BC39BEBEC53203FC235B22CFD5 -:10964000AB260596CDC7BC38DEFFD732A40BFF9EF4 -:10965000E863C434150B2503C88E91FA7E25FD3AC4 -:10966000175B7C0381A1772E76D2F5B9C56E82EBAC -:10967000F1C55EBAFE747131DDEF4F4EAF767D6C91 -:10968000318CABE1A7F4118015986FBA91913C3FF2 -:1096900036BC2279661C7F405E9F5E7CD835769012 -:1096A0004020D023ABDEB969453ED119850866F765 -:1096B000CE72FF68C61E35F9E73360ADD5695F8F9E -:1096C000C5BCD54AC54079AAC7D3DE5C1ECAC1ABAA -:1096D00097E86EDBFF3EC37CA7A7BC5D4179F7D45A -:1096E000B7131F947775B1A0B8EF87B6E708BFFF2F -:1096F000A895E379156313105EBBC202783D67E558 -:10970000FEE0E756AE1FBF10D72169C18D28C7FF05 -:10971000E53C5AF42880672DF9200FD73B6CFBFFFE -:109720004AF960E350B305E5C3B3F738AD83180DCC -:10973000DD660626F9F5273EA6FC9AD11CC8E7EDA2 -:109740009756603B2329B0095D3616FA78E2013757 -:10975000C80DF2C38D848D10CAF14AAB68878E1193 -:109760001E569A78FBF527FE44F35E690ACC43BC8B -:10977000607B29F4B732A5C36D80B6BDE5FDE587F2 -:109780006FC2B67CFFFDE521F8FEE534A96F021E2D -:10979000D41FBD6D27B48768DA2A6F330BBFCAF9AF -:1097A00035ECFFEBA16CE0D7C6BD4A0782E6D9BB1A -:1097B0005AC1797A76AF267CD31FC8074E83F2A4AC -:1097C000969019BF7F6EF161E752A0B39ADAE64234 -:1097D000BC5FE30EFAFDF1F21319D2FF85F7B579FC -:1097E000B6B0A9A75BE38F7B18971BB614F4431C94 -:1097F000FF626846E517E9D0CF934A708511F5CC32 -:109800008B2627EA11D6C5F5D019D1170B67917FA2 -:10981000536FE54DD392E08AC1A827EE557D183FDE -:10982000D7E5B757A27DAFDB93EF6B61517EA94BB4 -:10983000E9709521FFA4E8DBAD22EF9299D29C92CA -:109840005282EB11ABF370BDA091B5DFF74384F703 -:109850006D23433FFD8B7D37248F827603B4D16F18 -:1098600068E87CD78CFCF9443AD79F8D9DC03FD0E7 -:10987000CF2A902F3F38329B546722EAA7E7FCCDCE -:10988000D7A28BF7F5137F9B6805FA3E5FE077223E -:10989000BDDDE9A61516701A9F373B07B3526CDB86 -:1098A00089BFEA4A0D5C8E98FDB77E55AC7F42FBBE -:1098B000F813136FD3E6773DB82E03786EDA600F96 -:1098C0001992C9DEFC6FB4B78DEB0D21D45F064B46 -:1098D0009719E9EBC6B55DA28F93F0B650EAF3187D -:1098E0007DBD7062EA6DD85EF86881337485FC6571 -:1098F000ED251B0B6BFCA327D2B91CD7AA215A4715 -:10990000A9BD9444CFFF79E3595978D895C6B3D30C -:1099100073395E7D743CA2EBFEB2DFAE1D08745B52 -:10992000B8C36448D0F0DDC21D62BDDAEACFC47EA0 -:1099300032CC4CE01DFC7DC0AF9ADFDB0EA920E7E6 -:109940008FF5CAF98015634723DDA2CFD9489D1E44 -:10995000F063BCF958A2D403D7C47F3F31E6FD02BF -:10996000D9F6AD189BD3179E8CC468DB02EFABFF12 -:109970009DD0DB46F8561B62FA4B95E38FA4FE247C -:109980005F1D4FABFC6D68203C4F69AFC4FA8D9EE4 -:10999000D9CC8B7619F9D5A7D1FBC7D3B85CD75EE4 -:1099A0002AD4D13B8AF722DDFD938BDDBA75BFB98E -:1099B000D50B697DF238EA79EC878528AEAADD906F -:1099C000CDC21A7FEAFFC3F18FC231AA1F386EFEE3 -:1099D0001F86235F279F513806EAEEFFA3706CBEF7 -:1099E000ABE8B67C78658D12B214A05D78C440797E -:1099F0001363CA586F0BAE3F3CA2929F872E09D6C5 -:109A00007F14A8ECB05A86F2D3EEC7389F2DE1F947 -:109A100023B8DF662A233B447E70E1DE8407D04F03 -:109A20002BA8F5CFC32BCB29A1F50DB92EC8441E09 -:109A30004CAE670C72B24A159CB751190F909D2A13 -:109A40000854D7A13367749427A27D5C630887709C -:109A5000BCD0E37CBC0C43B8C382BA3769A013ED19 -:109A60005D4612D77F6C4509D9BFCD86826BE7036F -:109A70001C8F2A95896F219E530A28FF8BF717C0E8 -:109A8000FDCDC26E19537C4EB4539B85DD6A15FA29 -:109A90005DDEB7A5061E407FE254FAC2DB2C37A07C -:109AA0001EF2B7A581BD3999BE7085DB83F6C65B12 -:109AB0006001FB72F2C987C8DE6C6EF1663953A291 -:109AC000ED41FF0DD69AF4C4432BD05F596A5FF085 -:109AD00020FA3BF0FCB716D0B3CFA70ABD239E17E0 -:109AE000F4EA29D04BA0C78C2DBDED10EAA5825E0B -:109AF000BDF310E99D2D1B8DD47E07C643FF07E6FD -:109B00001132E27C07A9E4D75B019644685B071732 -:109B1000D03A11CC9B25A27F3D983F97F97CF3204A -:109B200003E5F3F17DC4A3D5C3DF374F613E5CD7B6 -:109B3000323BEC1487C8F501A358A74A14751A8A5A -:109B4000730AC5779655650B301EB30CD4AFC39A14 -:109B500063EA398CB1F51DF608F95F5FA48BBC7E12 -:109B60001A735F2E8CDE07BD5D8657D7DD4B2B1138 -:109B7000DE050EE634625E2518A175CE58BB66017F -:109B80003BEAD5C887C5CEFCF1EA090E65703FD621 -:109B90007E49A5F8E64905FC1BB4A30ECE67D23F6B -:109BA000323925DFEAEDAEF4974C297C2E0B278E57 -:109BB000C9C4F8DD68F75BD0CFD9E72CA3BC80918E -:109BC000F96EAFD4F83B4B231329FFA63AFDE48787 -:109BD000178A38D1E8F431AD9FB36C310496D73091 -:109BE000F66C45D1189487A7AD114B21D2778D81A2 -:109BF000E2BDFD650F8614CCBF2D6224A7CF56B8F9 -:109C0000C6601E7D931A48BE17E5E5088CE7E5742B -:109C1000E3EBB9AD0AE68B2F5A02C9A80F1E43BE6B -:109C2000D7E0E5D7021F7F4FE7FAE75113978B651F -:109C3000004F04E0502F5D47F9ADD5193CEF61AE00 -:109C40001E4BF91F33E003F37B09AC39E4A4F9F2AE -:109C50007C5D82DBA0AB0B542F0DA5EFFF9E6ED079 -:109C6000C5D56D304FAF467F595988F27588E3AD41 -:109C700071FC977732783C62017FC84BFE49CC3A41 -:109C8000775FFF88FC15499F5E3F4501FFE40AF1BD -:109C90005813C4CB5A7DDFA4F690FE6D827818EF7E -:109CA0009F735AC83F94750F76A1CF96B983EDA3E1 -:109CB00090CF139386621E40651D84945558F7809B -:109CC000FAD0ADF6F4F23FC87CAB356933BEB75479 -:109CD000D441D87C7AF94964ED113FCA67B1466E28 -:109CE00018E23B44FD2678F5F7190B328C33547794 -:109CF0006C9D44A8B71E8AEAF954F614AE5F4BBFB8 -:109D0000375BD4239DB57D447934F07B2BD3681D1C -:109D1000A087E21699EFF9B67E7221F68179844523 -:109D20007FA938817236657C3EDEB7A99C4FC0158D -:109D30005713CA30BC1A3F2F05E67FB7B07FE9C67C -:109D400076AA1B795DC4B3FFE59CE1A1380AF0490E -:109D5000F53689BE6E8A17859F66ECD58F1F2FF763 -:109D6000EBFDCE90D6CF5BB9E6E3E54B79BC42ED97 -:109D7000D79F8890FE7CD42ADBAF501BEC5C04E3B9 -:109D800025B62BC18B7C08DFFB51DED85D45E4672F -:109D90001B0B5816E2636C9285F4A67157C266F4E9 -:109DA00083212E7E394DB35E7CD671340FFDE138B0 -:109DB000FD8574FDE57DBBFE60FC4EACC791CFC751 -:109DC00026AD8F18F9775EFC8EE5747D1482FED780 -:109DD000BC94C056000A9F36E9E55D5E370B7946B4 -:109DE0007DA3AD873457D7F891A9A55C27B813593F -:109DF00044C34F52CED54B835944232785197C5DEC -:109E00005555FD9447522F95D0F3BFA34CD338CE70 -:109E1000AB8C93DACF38C3487FF43F4E85D02F4CBC -:109E2000AC5FA9545723F5427F721EBB4E16AB1789 -:109E3000E555EAC5CC0CDEFFBE0C7DFEF5C1F51D77 -:109E40008790854EDB830732A83EEA58129AF07A53 -:109E5000436428F2F1677DEF37E2E4DE4EE379FFF9 -:109E6000A26DF3DF4076EDCA085E443FE8B71962A1 -:109E70007DD20DF6D088F60EEC4509E5732FA6636A -:109E80003E37E85D378EA13CDD45F9DC6457A00420 -:109E9000FB5F36B582720E12EE958B799D9AD4B324 -:109EA000763548F8B2A8217E7506C186337621C37F -:109EB000344955109F5C8E8EAEB940726055FDC41A -:109EC0005756A7C18B7E8115E242D4BB2D4E035F4E -:109ED000BF715B28FFBF4C810811F4C68294822BAE -:109EE000AE8F9B2FB9C8DE02246EADDEFEE78F93E6 -:109EF0002EEC837E1CD5C9FD06B69FDB6144C2A74C -:109F00001A7D2CFD81D8EF62FB97F894F8B5205E9E -:109F10004BC81EC6F537AC2EFD7A66A6D4B71947D6 -:109F20008B2270B741E94E42BF06F4A8D5857A7AF4 -:109F3000484F92C14BFAD7C5FDA090E06B66D7F2AF -:109F4000B5CC53CB7949F817BC35DBA25D7F898549 -:109F500037D6CEDA4BF4750B56AFBE6E41EE0B30F2 -:109F6000AA01E21BD368BF05E5A4C559E6443F67D3 -:109F7000A9EAFDA39FEA2D4CE46F83FFAE1B5F5E51 -:109F80001F03F947384A5D065D5D8DBC3A701D259B -:109F9000CE77535C5C4F3DB6EF6ED2C3AA8FAF3322 -:109FA000C5D28FB176E21747117352FE54C09B742D -:109FB000957EFBE3A39FECB3929FAC8EB484B1AECD -:109FC00033763CA329E05750EF9632F2938DB97C5B -:109FD0007CE3204675E049E5A9AC5883C765EEA946 -:109FE000F47C41869321BD8D0E43201EBF483C0D5D -:109FF0007419747CE3967CE3F9A008E540C33781CB -:10A00000787C33D0C5F515C2A1A5EF327741663C07 -:10A01000FA44F522E7ABABF1C54C1BF7733ACD5CC4 -:10A020006F36208E205EAACF302FC3FCF7190B7F2E -:10A03000CEFCC5DC2FB3709E9B69CB0BA33FD4A98C -:10A04000FA6DE897CDEC5DB7F5D37E8F7AAB3FF92B -:10A0500006B48FEF72BFF964A5BD4D817E4E9AFCA8 -:10A06000C988EF93EF1A95165A07E7F573B20EE910 -:10A07000A4C9BBF25A783EEB67467F0B3DD6FB8303 -:10A0800067987FD83BE81FEF36D27A4BFEE30F1874 -:10A0900087C0FB35E028223FCDACB287D00E777E5B -:10A0A000D0FC11EAA3591B13BC4BB08E65FDB0AFB9 -:10A0B000B0FDF92A873781F26C058A07F35FABF3AD -:10A0C0009DB46EB2888978EECE4955A0437F89430E -:10A0D000CBFC35CCF973269F87568E85795E9BD154 -:10A0E00069B0034CCABAD04A0BD0EFD196801BE3BB -:10A0F000C70ED7F495183FBA5CFEAE5B205E3CE11C -:10A10000BA7B12B63B9F96FDDDB3D20F7AF91543A9 -:10A11000305F81E7B6CC872651FD6AA1EC7F193DFF -:10A120009FF9F36BBE3A0AFD97AE5B3F09736E155C -:10A13000D5E2FBD03304DFECD1B2BDD9563510BE29 -:10A14000B7315D1ECD148D47294FD7D9EB5F3D3711 -:10A1500009E3CF59639AAB54E87FC9BAED2B4B4062 -:10A160004446B4573AFDD0FEF1BA3726D980DF3ADB -:10A1700099BF0EE3DD95EB0E4CB2DC04FDA7E9FBC5 -:10A180004F378A7C6CE8F04ACCE3F5C2C7DE5FE962 -:10A190001F187D7F983B61552827CAFFFF22F81FB3 -:10A1A000F8FD572E5C07B4741FC2145DDEA21E3387 -:10A1B000AF7B15F52939DD4379DD8D681777F33AE3 -:10A1C00065D976F376E792F8F6FECF6E2E779D8905 -:10A1D000F19F7F24F439C0EDC7FA95E4A3CCBF3DCD -:10A1E0008E3C1D74D949FE0E82BF67498DCAD5EDDC -:10A1F00020DB23B1FEC7C2E194FDC47E7F4CE8277B -:10A2000016BA3D15F978B2E0F3429FC2EB7876DBDF -:10A21000C283D0DF6311F50E98CF3691CFD8666533 -:10A22000F74F81A15D892CB803FDCF346897D0F733 -:10A23000FE1DF6687F6F735166E30A035BB0BF7162 -:10A24000999ED2D6FC683F00F7524B990E6E75640A -:10A250002A3E0F65CD2FD1E0B384CF03F884F005FB -:10A26000C3BC700BC84B67D7B5052B600A2B5D5E6E -:10A270005DDC57D13595F6A5FCA79BFB3FCCCBBF4A -:10A28000CFA8E275213D7B6C94A76096AE22A49383 -:10A29000FCEE92C047D58F27AFC3F7EABB4C8CEAE0 -:10A2A000FF77545ED11FA8C7BC9EC67FAC5723144E -:10A2B000CFD5635E6F18F6F7B619ED18F6E315F90A -:10A2C0006BCCCB65B4C6A7BFB487F5975258685816 -:10A2D0005FBD19ED3F9D9E5F6D5ED1FEF47167DF3E -:10A2E000FECC621D40E05D157837C7877340A6E05D -:10A2F00053C0B741C35FB305BF81F6243FE0DCAE76 -:10A30000C19B57E46BC7E5FB6E403FBF700BEACBC8 -:10A31000AE448A5B2A54FF247CBFA22B95D6172417 -:10A320007F48BE9074ED4C6DA67C4DCF530AD9C1C9 -:10A3300058B88A245CEB158223B33A687C40039FAB -:10A340009407E8BF53F45F3E92E4E7192E0F2037DD -:10A35000F7A2FCE27A25CEC3D73D74EA90BEF0FFA7 -:10A3600014EDDF70A223C7FF4B5651CFC1F1D617B2 -:10A37000FFD957A1671E3DAFE87A83E659DF8FDC2E -:10A38000BEED4E2238338F4692BCF0DE1382FF3B87 -:10A390003B3E4D1A8572B1DBC8142F9F37EAAD0AD8 -:10A3A000A98FD99CB7C780FECBEC6D83BEF4221D6C -:10A3B0007AF567C46289BEFFAA7BCEE4A5F02C3D86 -:10A3C00081CB6BBA11AC4D59148E6999DCCF1A1937 -:10A3D0008CEF97BEE776D07389EFA71655B14F6122 -:10A3E0007E3F73F1F5CF91DD2105E922E53A564F25 -:10A3F0002DCCE4F2383FF3FF919EB25E454F59A554 -:10A400009EE2F70F427084EFB95CDD4315F09F6B5D -:10A410000C7E17C66127DEFD21EDE3982BEA5686F8 -:10A4200060DD0ADACDA301B22B5FE0435EBFF20824 -:10A43000C680B3DBF5F52B6C0BDF271ACB57513EEB -:10A440000A09FF5DC021ECC1ED09DDBFE245C67A16 -:10A4500079966D80B3D150A8796EE7764BD201E83A -:10A46000BD94A546E5F8935D999B50DF0E73F3BC50 -:10A47000627AA1BF14E72FE512ECAAE013C3FD53E3 -:10A48000ED5C6F4C8DC3BFCF08F99CBD9EF34DE7CB -:10A49000DFAA2621DE3BDF4B4D59A2D1135B851D80 -:10A4A00094FD4A3D24BF93CF9F15FCB12D3389DA2B -:10A4B0005B5D0E91E731C4DD37B755635F897FDAA5 -:10A4C00038FFC07C435AFE1EE65674F6B5D7AE0A76 -:10A4D0003C379801BF80BF6DA65016D6ED54741955 -:10A4E000A8BF9ADD0EAA07ACE9E078AC69DF67A8DF -:10A4F000D3E027B6BFFFC8E4FEC02603AF233A6807 -:10A50000007E43BCDB397CE77679487F1E16EF5D21 -:10A51000DD6E7C333DB3C9CCEB4881BE54CFD7F060 -:10A5200072F626BD9E6E11F80FB6E23EB6F475CCFB -:10A5300087B55680A78802704F770BBD63F69B7175 -:10A54000DF6ACF538CD6F30755FB4BBDD06E0AD8CC -:10A55000CB14E8AFA89DEBE18A27C18F41B9B3487E -:10A56000BBF0D676ED78C7321D221EE1FC5CB39EAF -:10A57000E36F10F83F2FE015FAF915F9F11C9E4F23 -:10A58000D6768CC2FC93FCFE0B41FFABC15781F029 -:10A590009547E1C3FE919F983DB004FB6DFCC3CE8F -:10A5A0006C6DBF5F65727D9B6E9C39C68A7A7E3505 -:10A5B000D81D92CEE07EDC9750B337C5B982913C6E -:10A5C0001B30EE91E3D6883C24C85DC514985A51DF -:10A5D000EF3892AEEFBFA89DBFEAE6FEDC3F8BBE30 -:10A5E0009DE620CDA76707C0EB8DE2A5B3E38125EB -:10A5F00056B41347990FED84847750757712D69D22 -:10A600003409FB01F33560FC92FE332F6B45BC75BA -:10A610008D3163FC14CBD7924EC58CCB8F8CD38AF3 -:10A62000718100DAB9EEA142FF308A773F79F9D51E -:10A630001756507CC5E9D254CDE958E90E4E7767DC -:10A6400044E510F47905EAAB9A277BF55107BFDFA3 -:10A6500095570DF8BCDE2DE55C4F97F4408715D774 -:10A6600035245F9FDD3324BC82D399C6EFEC708420 -:10A670001505F7A136B760DC2DF504C2A3ADC39470 -:10A68000F0F4D291011D8744EF0FAAE6FD3581BC9D -:10A69000231FD51B9B158F427A80F2AC99A807A087 -:10A6A0009DD9C1DF637BF9B908124FF5D3A1538857 -:10A6B0003BFDEE129A87C4576675C4500FB72658F3 -:10A6C000AAFC2734FEDA61B1DE8078994AF106D718 -:10A6D000D7F5C6400EC6AD2C3381F671821D22FD22 -:10A6E00072D0CA542BF4F7265CD12E8D33CEA77DC1 -:10A6F00034E30A159263D00032EF13417FFAF65B20 -:10A700006C24FFECEB8706E23C336C9C0FA11F8BA3 -:10A71000E8C7427650D883DFE7815FA744F5F2416E -:10A7200045A17E0EDE74DD66AA2D147C89FDA1FF95 -:10A730007450999243F6B23343141771F8FBB7671C -:10A74000DD79F85C1B2F627C178D374B57DD0A3C97 -:10A7500035624247C4E044E9289FFC7D807F1CC4E9 -:10A760009B5698FF0382AF0FE6878C4908D7209845 -:10A7700037DC3A94182C69B647C77189FC8D4BD4E5 -:10A78000EFA2BF80578387EBFF9F78B8BDF8505C7E -:10A790005D49F1F33D17C5F38FED5C4FAFA88CBF5A -:10A7A0006FFB11615764DC79BB58EF80B8F3113748 -:10A7B0008F3B45FD295F1F01FF9EF05BF5E36A5A61 -:10A7C000F7BBD8352D999F87C0F5C12C51FF79FF74 -:10A7D00023D37E8A7C7602EBCC010F9F0A7E39E17F -:10A7E000F427619D544362FC3AE267053C0D020F79 -:10A7F0002717F3F30B66E1BA1CF0DF1A37F7F3E61D -:10A80000B60F1B8F749FBB4AA17539B9FE2FE95C47 -:10A81000BBC1A8CBAFCFC275B9B47F249E2AED27A8 -:10A820009E2AD7C55372DCD8B8EA93C56EDD3AC00C -:10A83000CCF642717E047F7F16F311DCB3DAB27579 -:10A84000EB88AC2DE31BEDFBC7382A14173EB3EEA3 -:10A85000FE278B2D2CA485E3D440AA9F78C41D7CB1 -:10A86000C5AD83C3C642BA7CE86827ED27B2F23C87 -:10A870002CF8E33C8E81EB263BF9EB13D09FEDCD1A -:10A8800087811E7126A35EAADCEF1E1E8D1FA49C6D -:10A89000D58F8E1F47AC117ED01A178F93938FCA16 -:10A8A000B83AD18BFA51FAE5B1DFBDD7CBBF7ABF49 -:10A8B000F26A7908E0E390364E8AEDF794FB1F8D3B -:10A8C000BF0BFBE197A2FF91F8BB627490F27CACE6 -:10A8D0005DA19A961163F5F1D0D768D787E3D5A625 -:10A8E0008B876AAAF5EF310FB7FFCC63D3F9F1FD7F -:10A8F000E153EBC72B85A807797F8D822FF24FBFDD -:10A9000047F5A4A33DDC2FF265F9133C705D25EA01 -:10A91000C95759F97EFE4DFFBDDF3D0BFDA3774CB6 -:10A92000B4FECF7673BEA97C66612B9E0F60EF509C -:10A930009CDAFDABDF59A4F86B40AED3847EACF754 -:10A94000F1F9D4FB22E68176AC2FE670E474EC5387 -:10A95000540DDFE5D4F2F7723D265D5E3C5FB4072F -:10A96000789C328ED937311DDFF7ABE81764752834 -:10A97000643FB39A19F9D559E50AF5FF9DF24DCA1E -:10A98000AC92E87CDB0C534A9CF05D9BCBE643FB2E -:10A99000F3C3ACE0351E84EF582482E672C4B12EB6 -:10A9A00015E3AD5559FE62C4839CA7D7E8CC423F5E -:10A9B000DE768CC3D7DE9B67E2F687B195C22FDDCA -:10A9C000CCFD33233BCCB87F4E76DEB5A498ECA00B -:10A9D0009C8F2B55D811170BEEB4D3FB6DE4B758F1 -:10A9E000B81FE05A5244FEBCA46B34EE1C5C867166 -:10A9F00067E1AA883A13BE7B798321EE7915E305D6 -:10AA0000DE611E95DA795C4D6FC9F74CFDE41D25BA -:10AA1000DFDB26C48FE7C112D2F3CA67D2EF21F978 -:10AA20005C6A6698AF96F85F9515B813E1C9EAD8E5 -:10AA3000A4206E3E11750A9F24F27CFC272B5E50E9 -:10AA4000D0BF7C681E731A59FF70D72F32FA6BB4CF -:10AA5000F2BCD44C7491F14A141E9E8769F070FBCD -:10AA6000B42F2B5083E337EE5E4D71F5BC2DC7CD6F -:10AA7000575C87F88678536AB9BF5E3FC342F54C8E -:10AA800095CFA844F7BAA5665A37ACDFBE83F6A7C0 -:10AA9000B187990FE5BFBE63875203E3D66DDFA18F -:10AAA000CCD6E031BB3E4CF5DBD738E47A4484FCAD -:10AAB000E958FEC63C02FA2F87AC5CFECF54DA435D -:10AAC000B83E71C614ACC7F7CE786C3E5CC79478BC -:10AAD0007F73C7AD745E8063674204AF6D86CD6ED1 -:10AAE0000BBCD776ADD987FCB42A2BB81CF192AA3F -:10AAF000063AF1FB9474870FD737BC09AC8CECF79E -:10AB000037C4C38818BE18F130979757847E813FA9 -:10AB1000AAA77AD6C3FD725C5E427D75C8C4E7B150 -:10AB20009371780D1EFF7A944B763895C6CDAA8F17 -:10AB300028587F113B6E94AFFC1B3D19DF06CE0EEB -:10AB400033EAF93AA16F2A9FD9A27CAA81FB458FEB -:10AB500091E0CBDABE49C1FC193C277D03EF33AC51 -:10AB600077CADACEE3D53A783E5BA35FE43CE2E80D -:10AB7000994E84CF7EACEB00D73311BE5E20E08DC2 -:10AB8000A567C4E3A5F1C783BB40F7CDA1628C974D -:10AB90000F1524527F52EE63E534E2E17E65D686DE -:10ABA0002D8AC14EEB2AE45F4AF8E47BBEAC310744 -:10ABB0003C84872EC243C30695E633CE1C18385F0B -:10ABC000230FEF89FEDE98FE119DABF3E4BFBD4B72 -:10ABD000FCD8007136C519EDEF9AA7A19D09FDC2F9 -:10ABE00088EB6093B88BC2D68A73A72675723DDC5A -:10ABF000D0B9439D658FF269FEE937E8BCAA868E1D -:10AC00000486F115F0DF518427964FBF293D411F7F -:10AC1000F1F829641679BE603EC63F524F1B84FC92 -:10AC2000333BBF7F41B4A3FC133CEDD1E9592BC9A1 -:10AC300045FEE9B237B0DEB3C1A7D0791D129EF44C -:10AC4000AAF87EBBD48F526F633E31A0D1EF1705B7 -:10AC50005DA11DE1712A2B403B2DE18CA5D3802CF9 -:10AC6000AEC7E3F0D3DF11DE58BB25ED79FEC69DFC -:10AC70002AEEBF917C3209E9ABE113479699E07067 -:10AC800064A9D4FFDA4ABEEEB8D6C4EDD5DA160B05 -:10AC9000D561BE7937AF0B73DC638EE0F5A06166DA -:10ACA0003D3E3F98C5E168332CA1FD68207F49599E -:10ACB00019C827498CEB41AEF79EFC0DD75BF521F7 -:10ACC0003BC5B9F5C13B6B68DD3FDDEAC37A591678 -:10ACD0003C609EE688E235968FBC3BF799711E93E7 -:10ACE0003AB8BC81DE243E8AE22FAC9313290F864A -:10ACF0005E3F2198CFFD201E479588FD81B5161F28 -:10AD0000ED2FAC15F9D612B14FB0E2A89FECC14CB3 -:10AD100041878DF6C0755998A75915936FFD8671B7 -:10AD200040DDA2DF51DCF5A0FB2DBA4A79847855CD -:10AD300027B73766713F3B5F5C2BB3389FD495775D -:10AD400090BCD59D682639B54FE0FACA7E2CC62F37 -:10AD5000648F09BE5B45E38EB3758CC7F5E2713F26 -:10AD6000579CADAC7F38E7E23E2B8CE736EC4F7A50 -:10AD700000E5F96B882634FB70A666713939B30D8E -:10AD8000104EF6A8D97C253FFB6AFDB1C81185CECF -:10AD9000F910B83CB3BDEA86CF707D675BB20FF7A0 -:10ADA000D37FB9FD8E1F7C06709FD9728B0FED7F0C -:10ADB0007A6B80F8A527C3EADBCCF3AF13303FD51D -:10ADC000D2B13F09F7ED7CF1C2F565A88FE7657157 -:10ADD0003D75FA37C645889725CFFFFA667C5E1722 -:10ADE00056D2D02F3DB3EDE77FCF827E6AB734E1F4 -:10ADF0000962ACF585D7C9DF378437F1FBDB92C92F -:10AE00007FFDE2D9D53723BE5B3B5AE9F9E96737C5 -:10AE100051FB8DE77FFDDADFE0BDFA4012ED673EC2 -:10AE2000FD9B7D4497FAA04A75E7BD7C1CAB077774 -:10AE3000ECE37A10ED37F2FD0CAE9F241F4BFEFDC4 -:10AE4000E2F9FB6FD0DA0379BF4DE469DA12B97D1C -:10AE5000F852C869DD187B1B5EBF7CD14AE76E36AD -:10AE60009ABB8B307EAF2FE17CF17D818FFA8EF91A -:10AE7000A6463B7D4FFDFC27303D5E87007F627D0F -:10AE800017BCB5E532D529FD8AEB99443612F33863 -:10AE9000D3AB8FF37D9B25CDA63A82F305FE1C66CE -:10AEA000AD7D5EB1307EDCB83ACBAECBD366754EAD -:10AEB000C9F192DC27F80669FCDAACDA60AB03EE84 -:10AEC000DFB630E8C37DEF2F9F7A6F3CEE4F78BE40 -:10AED000581946F4372ADC7E85EC344E03AE0F4118 -:10AEE0005CF1AC9013084BD36F84F98C53593A6ED4 -:10AEF000DD1DC7D81113E985ADF41CFC17F2CBBCDE -:10AF0000AF4FDF8AFECC5A53D0331CFB6913766FE8 -:10AF10000B871FBE77DACBA83FE78DDC0F5F80DFA2 -:10AF20009D6F999C8E7E3BF4DB65D2C459C09179AC -:10AF300068F7B0BF72C4D384D00CB23F5E33CD4F3C -:10AF40009EE709F31F7AEF90A87CC6E691503F6117 -:10AF5000DE775F56E55ED433F2EAEA270FC3B2F933 -:10AF6000737FB69FAEDFF47CD037A69FE3F6FB95E8 -:10AF7000E3C4B78DC8B7387EF084CE7ECF927CBB59 -:10AF8000E738F1EDACDDDC7E37EE2E3523BF7EB940 -:10AF9000D8CF3E0507B651F0DF5AA57B0EEDFFDA9C -:10AFA00063A57D7DE7247FAE3AFE39D69B16ECF68D -:10AFB000509EE0DC1ECEA7070D068AEF0F6EBE6E18 -:10AFC00053ABD2D76E821F4D72D2D8CC841FBDF046 -:10AFD0003DF4BB1A6A799D79630C1FE56FFC641917 -:10AFE000F24B0A78BD583F037ECA78DA1759CF86EC -:10AFF000A39C668DF5EFC9A6F53F1E7767D5823E07 -:10B0000081F66DE9F37C789455CA58F07791FFD2B8 -:10B010006FF2613E6C6D6EC732F48B43E3189D9BFB -:10B02000BAD6D43E06E3DBB5E3BC4EC024E06D0BDC -:10B03000F9CDACD82CEC570DF9DB8DEE7FF551BE78 -:10B040003A56FEF7B490DFD6E84DF4E139B6937680 -:10B050002B0BB89F6267087F23E017DB93C2A3C264 -:10B0600008CF59813F89C773A62E3A4FF7DC4B09A9 -:10B07000743EE1A4B19C5F53C67690FE7873CFAD69 -:10B08000649F255F3A7625909D4E559D0AE62F18C0 -:10B09000BB23414BD77651879B22EC48E12A4EDFF8 -:10B0A000C46CEE6724661BC4D52CF85C9EB712A254 -:10B0B0007CC259417FFCF36ACE6B6AA889903CD56B -:10B0C0006FE7FDA527F84B1FD2F0AFF497E47A2B7A -:10B0D000AEBF4E89C3DF3E0147FEC60544F759B5F2 -:10B0E000E23C8755DC8F60C0178837A023F1C16D23 -:10B0F000E973896EB35629F7101D431594D7947ED2 -:10B10000576CFFE5D95C2F6EB306CAB18EAF27C36B -:10B11000E1C3FA806D297E03AD0F94A6507E2323F0 -:10B120008DFB8119C20F8CCA7DA0DC00E39C7239B3 -:10B1300038BDC3BF57316FEDCFF6C6F5EBFAC6EF9A -:10B14000BCBFC9EDA1A118CFC8F563898F704BE2D0 -:10B150000CAD3EBD51E0233C98CD40BD0171829DB8 -:10B16000F2EB4E1807F3049B473DCBF304FC5CE77E -:10B17000C26C9EA71B97162847BF2CA330B090DB4C -:10B180004F3ECF587CEC13F6FD8DE9F795627CDAE3 -:10B1900078A7DD8772F7E42BCA4CE2EB90050FFB32 -:10B1A00001BEE772080E13D5ADB1A04AF4686C0E6B -:10B1B00084E3F3FD1492B346F0F3D0BF9F847C9EEA -:10B1C0004E7C1FE67CCFED9FCC23A09ED4AEAB4837 -:10B1D0007D20F50CDA37E46729178D377717217D45 -:10B1E000BFA95E3967E2727E0EF0807224E5C6F177 -:10B1F000329797152DDE4A7CBE02E45E4BEFD8B83D -:10B200000BE1C4F855EAF71F66051AB3318E3044D6 -:10B2100096D1DE52A18F1B5F5E5E146F7F90D4C704 -:10B2200016711EA6256C0B6BD741B0B6C25146D71E -:10B2300010DA23DBA2F87996966C695FFBD4A5B58A -:10B24000640FEF5B97E642DB85F2B3D946FBD4642B -:10B25000DE29B6DF87B2155D7E47C625B89E81EF31 -:10B260003F23E4A75DF0E573D932CF1BD6F1BFD7FA -:10B27000103C8E7505FDD931F9DD3F2B0F26C791A6 -:10B28000F63496FE723D06E733A5A4FFF7DAF731F0 -:10B29000B1CEA7E7C717859CD46533BAB69B2217F2 -:10B2A00049AEE63B18D5F3AC67FE345CE77BED1A9C -:10B2B0002E0FFE9E22EC7F606ED09A9311CDF7E2A6 -:10B2C0007D8C3FEB54164A009AD46D3385B5FB64F0 -:10B2D0007E86B58600C779872564043EAFC80DEE2B -:10B2E00045FE0A8DE1FBE1423FB4D2FA1438D2C3E5 -:10B2F00051BF34B1EE24C473A3B1AB08F393D5AE00 -:10B30000E03EA4FF2786AE3C5ED7C1D7CF8E897CB6 -:10B31000EE3191CFED344772BF9F1E3D9FEE02E3A9 -:10B32000755517BA0CA918F77DB8FB0F2FBE025F31 -:10B33000DFFBCAD97B7F84D85A61BBEF6770ADB69B -:10B340001803AA26EF76CC115FCF7E20F8A8B7EEBF -:10B35000A925216E3E7F6B0E7FAF2966BD7A6B0EED -:10B36000D7A7D17D4F7CBDFAC37ECEB5BA2147D4D5 -:10B370004B8A7AACD8E737E7707EDB666245EB1123 -:10B380009E4D0E5AE7672A3F8FACF6897C1FAECFE1 -:10B390007716F0F3EF7BD62864078E99B8FE81BF4D -:10B3A0003B2D15513B8A6E0AFA89B5CE50C400FA7E -:10B3B000A376A12382E760C27D7534CA5AC8497555 -:10B3C000C133857D9CD5FCE65F319F51AB32CB68A4 -:10B3D000F8EEA4BD2609CDC39CEF3E8447CCB0CC8B -:10B3E000EA76513F2ACE57F34F365EB65DC9AFD3EA -:10B3F000EF1BF9454E80E5C0FCAB9339BEAB1FE2B5 -:10B40000E7ECCAF77F23E43696DFB621AF02BC1F14 -:10B4100029DCBEC48EE3CC1DF302F253B53B60A31E -:10B42000FE1F3A4B7AADFA152B9D7F5487EB5CA03B -:10B43000F2CE9776152DCA47BEEEC9FB23E6C9F6B4 -:10B4400026505D721DAE7769D6A7FB5BEFEA7F9D44 -:10B45000CB6B46FE6DBCA410FD67EE7DF328EAEBD6 -:10B4600046B59BF862A6C54E786FBCA4D273D6666B -:10B470003AA3DDDFB6D0EDCF47B8433F1E9D42EB88 -:10B480006599709FF0574CE7632C10F5E0CEDC60B7 -:10B4900031BEB7CE96743FC67D172CFC3CA4263334 -:10B4A000AFFB6662DFB0A43FCB71E8E9BBF7ADBF8D -:10B4B000225C3596209D2B397B06C4C946A447647F -:10B4C000B8B3444BD7D1DFEA5C5B7B0ED7371F9A0A -:10B4D00079DD4F5FBEE67A69AB7C2F8BCBC787796E -:10B4E000AC76275EAF852B7CF761816897F1766C2F -:10B4F0003F33857C7C3894DBA5D0025BDCF33CEEEB -:10B5000014E3FD22C73F19F125EF3F25E4CF99EB66 -:10B51000BF1DEF83DEBB03F51EF0632405FAAB7E8F -:10B520009DFFBE005BDA4375A7BDF32A12F0BAE2B5 -:10B53000C3F5FD68BFF7607FF09E9FFCF3D7ACB406 -:10B540006F8D4D063D8C7A77412E43BD0BE3CEC403 -:10B55000F1A1DF480ABD9740F3606DA08F41E0CEB6 -:10B560000FF7125D5654029F968BF3F2BD51BE92B7 -:10B57000FC14CB474D424FC5598F6F42B862D7E399 -:10B580000112A237F1DBB7D8FF352A8DEB7F90E7A8 -:10B590001FE4905D8D0CD1D6F3493C4B3DF861A280 -:10B5A0009E2F4C02CE16F15E2F9EC5F953E985DC25 -:10B5B000BEC93860B5A0BB557C27AFD25EC5E6F3E7 -:10B5C000ADA25F6B4E92A4CB6308A7B4737DE8BDB8 -:10B5D00081D31BDE7B9CF44742CF7D6960A7EE02DE -:10B5E000FF07CF9F84EFECF85D9F7CC4586E5F9B94 -:10B5F000163818DAFF0D39A24EBBBC87AFB715C39A -:10B600007508CA1FE81DE5EAF4C3D8DF037AEED750 -:10B6100058EF01E329583F944A6AC08BFD01BE9F51 -:10B62000D7E23B76BC63F808FCBD1D39625F5C293C -:10B630002B457ADDF7EE5F1CF77AF17C72BE1FF7BF -:10B64000337BF025ECE7CC0FDE22FFFE983952D495 -:10B650006E8FF3DC1CD9B84E893EBFFF17C610FEB3 -:10B660001E4567D79935D3812F6776197D38E4CC8D -:10B67000872FBE3302FDE62E13AD1B81DFB00ACF4C -:10B68000E73C26EA0059B33EFE7F57D047EE0B96C3 -:10B69000FA49DAFF79CCC7F552223F0FFD93F973CF -:10B6A000695F700D0B1CC2F3D0BF583091FCE2B93A -:10B6B0002C48E771CF6AD39F871B7B8E6EECF9B95C -:10B6C0009880477CC59EA3FBE5F7AE9C2F97F52B92 -:10B6D000B1CFFF26F8F1CB7EEACB4F0BFE95F500FC -:10B6E0004DB21EE0D52BD70334C5D40344FD0C590D -:10B6F0000FF035AF0778555F0FF0E598F8705C10E4 -:10B700007034E1393A71FB4DA2FB5F165C799E4DB6 -:10B71000782E4EDC7DDF76BADF5F3D822D57E0A9C3 -:10B720009F7A8C845CD9BF47678F6DB9DE183F2B39 -:10B73000879E37C5D435449FF37A06991700BA52CD -:10B74000FD9CF4EF62F7C3CB7CBC949F4F1566F170 -:10B75000501E6DB5881B7C43D11FFE14FD2C94DF59 -:10B760005BBDAF7503A8B37E7443915A1095AFD8F3 -:10B77000F9005F9ED6EE3B1F902BCE6FF0311FED90 -:10B780004B147271DF0FC625633EFFE387AB74FB7A -:10B79000CD7AF7A39BA57F67D7D9731663EF67EDC3 -:10B7A0007E8BFCB71A4B80F6BD7DF6EA0FC8CECF74 -:10B7B000610117CAC9F957AFC90BFE5FD87909CF24 -:10B7C0001DA1074CDC6F4F27FF64AA80E78EBDDC0C -:10B7D0007F3458FC261AC7CFBC4E1785E61C5E5036 -:10B7E000B678EEDD4DBDF097D07919A305FC0A7E41 -:10B7F0000FF8BD495CD9CCA01BE196FBF881EBDCCE -:10B80000786DBDC1E7C5EB2D4A40659AFD9DE359B2 -:10B81000730EBE6FB0741BC5F962742E7C42145F48 -:10B82000D47688F6D23B2FDC371BEFDBF9F9C26602 -:10B8300001473057EC5BB6300BCE3BC11EF982D6C8 -:10B84000FBC4353486FBE3A1025E479C88E717C042 -:10B85000B876FBD9104ED6C99CB42FDFEABC10C114 -:10B86000B844F3BB1035B9C335BF0BC1223C5FD51B -:10B87000DFF398DF8D4815F0B50A3DE9C1F3050BFC -:10B88000E91C05D2938F3BE6D079E219F685B40E18 -:10B89000FD54D2045AA77421E2B13E7E82E61C0414 -:10B8A000789E11D09F7F903943DFF604F56D0B3BF6 -:10B8B00046F55C4A24E0BE9C163DE7D124F4CD9DBC -:10B8C000891CAE3B1379FCD69AABDF971990BFE782 -:10B8D00092CACF4938E7B258B0AE02FC93D65CEEBC -:10B8E0009F7C0494863891FFDE4BE92DFE416BCAA4 -:10B8F000F1774C8CBE2540A7650E6F8B8A7EDFDD0D -:10B90000E277BFD40EAA57D8745F8A0FEB6B9659B3 -:10B910009D9598070DE5F2FC4F93D8A70114A9DB7C -:10B920000EDF6D9A9A4DEFA557F550FEB467392397 -:10B93000BFAA0F9F7E0DFC0FF87E16DB787E438D2D -:10B94000AF0BF7ED7AFC46AA3396CFB7E07380537E -:10B95000117C81F76FA988FE2E53E1DED2FD78FEBF -:10B96000240B2A3E9E8EF412BF4F13FE7CD3DECAF8 -:10B97000DB87035C855DC3888D07EE15EB2FE90936 -:10B98000627D989FBF1BFBFE407C1FDAB6C3DE7F43 -:10B99000ADC7470688BBF1BB31369AF711917F627C -:10B9A000423F8C8891BF515179A0E7A5A2DD24EADE -:10B9B00001F1CC087F054F6FD07BE95C3E7C4CFEEB -:10B9C00071B9BD9145FFB09FAA68BFA4A7C6461F25 -:10B9D00047E510A65866F1B5D6C37B07A7F075F406 -:10B9E000116A641FCAFB28712D155736B39DF0BB31 -:10B9F000A225F286291F532D0123B62B9CCB5BB1C8 -:10BA00009F9B94085DF366AC6E4535EDCD2B14FC21 -:10BA1000161C87F2B96C1CDFDFDC3AD2E773C2A3D5 -:10BA2000E933787E76DA0C0BD54D4F53F9794C4CCF -:10BA30000DE6DF0572765735CF0B63BB5A937791CE -:10BA4000EB204720BED911C73FF0E671BB25BF6F81 -:10BA500012753EF2790E1EF40C001AF2C67F9C4B52 -:10BA6000F684AFF77E962BFCB462561CF3FB315F75 -:10BA7000901EA8FC5D7F7A42FF5CE88969FE274C36 -:10BA8000E4DF0B7D21F57240D42F75897354DE1FDE -:10BA9000C3F1FE5EE53CD21777B266D2E777B1908C -:10BAA00009F1DBABFF2768FC2318675A40EF2F4DE5 -:10BAB0009F11EB57717E95E3DE1DD43F9F2AFDDE7B -:10BAC000097ABFB7FAFB5FA7905DCC7CAEE1F2804C -:10BAD000689D52534C9D52A3A8536ADA3DFF60867D -:10BAE000A64EA9692FAF536ADC7DB53AA51E5A57F9 -:10BAF0003A620AEFC3F59623F3402400CEFDA2AECE -:10BB0000E500D6B59445F9D23195E75D817D69FDB3 -:10BB100024C769F3213FB519CA284FDB96E4F069C1 -:10BB2000F3A22B5A80EF34F959599774A49FB8B8EF -:10BB3000388FC7A96B159E270FDD6DA13830A33054 -:10BB4000A05B97C830B2A3986FFC58F8416B451EB4 -:10BB500004D7F586C135AC70FFA6F77BDCEF84F91E -:10BB6000C9187D9491E6A375818CE42194DF9FB17F -:10BB7000B7740BE91BBBD587F5FCB2FF19C14D2A81 -:10BB8000D60B35EDDDA4D6D8A37C372A4FF0AB8D8C -:10BB9000D9905F7BF37D3B1328DFF7993D704B1EF7 -:10BBA000CCA7DE1C19CAF4FC4CF7FBB36B7305BFC2 -:10BBB00098C604EE9E0DF09C7FC7CCF35E0F3392C7 -:10BBC000D7DFEC49A17CA53A95917D595AC9F8EF88 -:10BBD000BB6C52C89F3B99C2CF0D5A3A85911D3C10 -:10BBE000973A9EE8378F850FE1B940B51B4CBAF301 -:10BBF0007F1EDCA26FD7B30EB237F5DBFBF033E963 -:10BC00002DA91F1B98D7887AA8B153FF3D1BA8D731 -:10BC10008FA5C21E0C9B36B6D504DF0D3370BDC593 -:10BC20001EF6654FA5B8BB9ADB51F61C9D3775DE35 -:10BC300071CAC8E59CEBE3E151ADA9B34BC3857F65 -:10BC400075B3CA7F1741FA4BC3C5EF241C30EC35DE -:10BC5000D26FF20878CAC577D24F93FA5AD2A5723A -:10BC600024FEC603443779C2DF2960054857E89FA0 -:10BC7000E441C140891F714CBFB7304A8C0774E75B -:10BC8000E7CD192C61E4A3654A33E9690B13FA5A2D -:10BC900009925EFEB750C8887C70036BBE037FBFFD -:10BCA00073B4A5CB467EA93DF868DEF0289FB4B2F8 -:10BCB00048DE0E45C72FF4FC4CCAEFE2F28BB42BE2 -:10BCC00091F7B9BF3189811F08E3FA3FE07ED001C7 -:10BCD00085C78BE00F1EC078F1778689C40F13618A -:10BCE0001AF8DE38A79ECEB7BAF5ED89DE3E7C6045 -:10BCF000D4FEFE04489C8AF04C2AD6BFE797FA8D02 -:10BD0000E9F55B3EFB9AD7C12F3FF45DCC1BD816FB -:10BD1000B162F463C073F4C5FB7DD16DC25EC459DA -:10BD200037D99697D177DDE4BCC8FFDEC8BAE76C97 -:10BD300057FAF2CDB9838B8C6E0D7F497E7E59D434 -:10BD40005928AF8BF5D9729E2F8CDA79CE3715A290 -:10BD50007523F21DBCFF96E417F13B2137EDB64683 -:10BD6000F077704A453F3722FF9445ED7AC460F77B -:10BD70009A0B904F7C6D46635F7FDE95EA257E19B6 -:10BD800066F013BF0C67BE34A4D3484B47AB8AF0B0 -:10BD9000EF19911DB4EBF8E31DE20F05F883F2599A -:10BDA0007DECA3FE790CFF483A1E167EF4ADCC4B19 -:10BDB00071C404E14747F239FF54D9EF54F1FB371E -:10BDC0000B78BE612C2E28D23E53BD5DACB2E8F993 -:10BDD0002096BF60448376DC587EEB8F6F0620DFB1 -:10BDE00048BB987675BE39DF3FDF9CBF12DFC4F2D7 -:10BDF0008BD42B3BACCE2A3BE6B76A15D2C7C3DE49 -:10BE000019D88AED6B1AF2A90E66478A6F3F3D6F0B -:10BE1000E6CFCBBBFC46AC93295C289EE707AAB0D3 -:10BE2000DDB488AF530C3FC2EB68063ECC9F972E23 -:10BE300069DE8FFBFA9A42FCFB97BF5846FB9BC218 -:10BE4000CBC4F795ED55D86E6AE3DF9FC4F5A6EB3A -:10BE5000B1FE2DDC8AF707AFCAF7F1B094FBB5B796 -:10BE6000083EDDA1ECDC4FDFB5F3EFE61EB224D2D5 -:10BE7000EF060ABFF56631CF5B36F079A67F7A1BF5 -:10BE8000FD8EE8EC9E10F94F9F1BEAE9776AFA8B6A -:10BE90003F2B95F61CBCDE8AFA040FDFB2005F1759 -:10BEA000F0F5C8CD30C47503B83F28D7F1B0AE4027 -:10BEB0005B4770DD001E17C9F75CA97C1F1A7BDA8F -:10BEC00041F962B9CE1859C71494339CA3F003E228 -:10BED000AE3BDE5AD84CEB8DB70E90EB8DDD2A9E33 -:10BEE000A35E7AF92FE3E3E559CA06F03CD0295165 -:10BEF0002721EFD786F3E977C1762093D03EFAF079 -:10BF0000EFA92DCE056762DFDA8E7CDEF60FD8F062 -:10BF1000D3B61CC0AFA159C573D4589E42FBF6FEE0 -:10BF2000A58B459293FAC27FABCA2266BEEF8EE024 -:10BF30009FD36ADECCF74F72BD344DAA9DD18348A2 -:10BF40004EEF1474FACE00E1770C63C350DF4C134C -:10BF500074BBCB027E2BE9B576538CFC4F1980FE67 -:10BF6000C653FDFACFFAE731FAA1568C3B47F8CD1C -:10BF7000F3F0F7478D78BE3BF79F4F3DC5FDE607D1 -:10BF80005907E523CF3FCDFDC506981EF24B9FDF35 -:10BF9000E7DAA66F3774C4FE2E6C88FAEFF3BBABFA -:10BFA000253CAF7BFEA9860ACCEFD5AE7F87F2C7D2 -:10BFB000B5525F84F5FA021C0CAE2FD65D4B791D8D -:10BFC0008385FF2EE630D017586F320CEB48A1FF67 -:10BFD000A162DFFE72FC84EFD77F6800E98D09540F -:10BFE000674AFD19697DF71DBF374A1F693762F53A -:10BFF00045A9CCD70C4CA57C96D41FA5C24F611384 -:10C0000062E3C727490E8789D64F06E8E320E97720 -:10C01000C0F7E4777419EC618341EB6784492ECB58 -:10C020002C602F48947C1626F6FFC7D0F971A273B6 -:10C03000FF7194FE790C1FC838A642F0C1DDCC4FC9 -:10C04000F1D12EC107EFBDCF7FBF6D9A7D21F1E108 -:10C05000FB1F70BF53C651DF3E7E8AFC43F1532F56 -:10C06000DDADE04FDAF07728260E5A83EBE49D56DB -:10C07000FE7BD50AA7B3EBEE2379DAFCE27BF8BBB3 -:10C080002B9ADF73689D9860C175C456138F2FA6D5 -:10C090004EFAB062A6467F0C49ABDC85F85AA6740E -:10C0A0007DEF4F186FBC25CE4FDD9B4174BFD0C5CF -:10C0B000EF5FD8709D2F04B7BF3489F3A894E63999 -:10C0C000581A25E198237EA765AE31FC5A37AEC7D2 -:10C0D0002AE15DF50AFDAECA01ECBFCE1031F3BC1A -:10C0E0005E17E5E965FFFDE72943A4CFCC6F70FB40 -:10C0F000D8A324FA789E37A4FBBD9E035E1E6F551D -:10C10000E406BA060C8FDABFD8BA8363F36FA57D55 -:10C11000A9FFC5FCC9B82EAAA8FCF79963C7C53A00 -:10C1200083A59A3CF5316BFCF5838F849ECF435CED -:10C13000C1F88BB2FD1FE33C4F89B8F094581F3B08 -:10C1400095C4D7CB4E0BFD9CE715EB79E27A4AAC50 -:10C15000A79D4AD5C793F23D83977F7762B125B0FB -:10C16000544357EFBA8466CC4B64148ABA92858CD8 -:10C17000C74F7B5274E72438BC9579DE0C7C4F9C0A -:10C1800033B087DB655CC7C675E6F559C14B88B728 -:10C19000462FF3E33A2DF3769BEFC0F54AB13FF714 -:10C1A000BCE09BF3567E957039BC53F2BC88EFF926 -:10C1B000DD44D7DEF6946ED297FF072EE42C97006D -:10C1C000800000001F8B080000000000000BD57DE0 -:10C1D000097C54D5F9E8B973670B9909939040101D -:10C1E00088938D246461B261D86492808A22262C5F -:10C1F00015651B50C2964DA0FDA5D5BE0C06117944 -:10C20000DA426B5BFCBBBC01C16AB52562B0B126EA -:10C2100076544AA1D53A22286A6A4754D69044A057 -:10C22000567FF2FBFBBEEF3BE764E6DE4CD89EFA9E -:10C23000DE4BFC7972EEB9F72CDFF9F6F37D07BB24 -:10C24000B322C999C058F7ECA099A98CD965FD21F2 -:10C250005E871F031BCCD862FCCB09A5D5E657F33C -:10C26000E0EF0DA6CE6026B5B36F52185354E665C5 -:10C270007150C964CE0A3B3E9DE0389A0D4514B416 -:10C28000433F7566DB066534BD5E6185FEE68BFE69 -:10C29000D870BB11FB9FC7BB62F3DBF67FA5C43030 -:10C2A000B6C0CAD60F83F6856D43CC3003B62CC614 -:10C2B0003BD291836F4C761C8571156FB4FA4D3467 -:10C2C000F48D3F93FA968C19D951393F5A8797319B -:10C2D0005CD78800AD6B63694FD27F1531D6D36EC2 -:10C2E000716C83716ADAFE7A588175D5C8F5B568C4 -:10C2F000D797ED54182BC69AD5F7A995B15B98C27C -:10C3000006423FAD364F36C2ABC61AA479428FE61D -:10C310008A5C18EDFE09B1B4FE21F03DCCE7C546BC -:10C3200037FBC41482E72A075FFF14B5BADC1CCFC1 -:10C33000D8993B99C3028F56EDBFA3C90AF5550F93 -:10C3400030071FDD6D6063A07F01AFFEE69750618F -:10C35000604EABA8E3B07306306766A83ED413A75F -:10C36000A943BF0CE7B152F43B6CD9559AEF47D4BF -:10C37000A768DEBFBA6194A63DD95BA0A9A76E18D5 -:10C38000A7793F7D5399A69EB1E546CDFBF92C7563 -:10C39000208375D6ED53990F409BE59BA169CF7E15 -:10C3A000FA76CDF7C758FDAF27C07B2D5131790CF8 -:10C3B000F0A8292A661B96CCEB0EE4007CEE14EB69 -:10C3C000C86D5EACE9E754CC75FB705FEF0C544D63 -:10C3D000638057A35B5768FA5DA956F37DDB643A27 -:10C3E0001284EFEAE117E159C07AF60E03FCA8F5D2 -:10C3F000292E3F342FDDC2DBE577CB5BB7D277CB7D -:10C400007DDAE72B9FD6D6BD652CB3DE06EB74DA5A -:10C41000E38F02BEB2ABD855DF84D155080FE025BB -:10C4200018EFCC63AACF928CF0C9F8CD04828F8923 -:10C43000F99C7DF7EB0C632E3FBEFF9CDDE585FA92 -:10C44000D2FD77D07C2C895A3C88726AF1203A530D -:10C450008B07769776DF079668F75D0FDF58F7A8AA -:10C460000BC277D00D5ABC90702D81DF6F13AE8F49 -:10C47000E8E059B8C7DD642338B159D631083F3EEA -:10C480005F0BAB50592AFC1D0F7C069EBB7817EC46 -:10C49000B4C3E63500FE3CE3548CC427443FF94660 -:10C4A000FFABB89EF58A97E17751CC9788FCA2A99B -:10C4B000C49FE4877D29B0D6E3CEB1CF6C15BF47CA -:10C4C000BAAF36FBF3B05DF6F799CD43CF3B953766 -:10C4D000AA18AC9719FD79C40FAD8CC697701C33A0 -:10C4E00080E3F14A5661C6715E14F8FCE9FBCB08A3 -:10C4F0008E55AC7EAF1BC63BF50187EF72E6A5F704 -:10C50000966CD2C2A10FFC747003B471E2B875626C -:10C51000DD2B18F31952FBC2536953FCF63C04435C -:10C520009BE4DB9E6F0A39DA213CC7B1DE1FE2DFF4 -:10C5300012BEF08212CE9F703CC7E0D078129E925D -:10C540006FC9712CAC5E4D443AD0F13196A9DD270C -:10C55000864C620CFD473F7F021E6A8D13830DC619 -:10C560007E70F28C5D23C6618B3D8908272BDB44EE -:10C57000FBB751716D50611CF5EAE42606F02C748E -:10C58000B855DCAF6216988BCF4BACCD4D46E8EA80 -:10C590006A76DE41F834E4A99A6F0685D6A1C8759B -:10C5A00079156684FA44519FE955828F26E37AFE15 -:10C5B000FA158E3B519433B184FD83657EF2217C64 -:10C5C0003C41718EC0F166FC292301F166BD52CF5A -:10C5D00074F33BFC32F4A31A7A06E17B5398C7C884 -:10C5E000E5AE8FE4CD5F9520CDFB07CC7D1F965245 -:10C5F000BED5B2E6EBE642BDB605E4560C96517EDA -:10C60000154AD6AA8327331EC1BA015682F8BD1235 -:10C61000EB72DF9343ED5457FBD6D7C21A86C65D43 -:10C620005CBE3F98EC10F2B167246FE7FC6D998017 -:10C63000D73229B77CDAF975E01F4319FB8B1960F3 -:10C6400052807464F51A063296980C7489F3CC63A0 -:10C6500079D83FD0D5F064E87F701CD0A1124E7716 -:10C66000FC7DD9DE87EE74EB67F5B0B96301DEF6C9 -:10C6700022B30758EE1DE1EBBD0478483D6221BEB0 -:10C680000BE37DE174525933A0E35D373617059211 -:10C6900050FECB7DAA33334F33EA2DCD0934AE7C27 -:10C6A000EE4E360878013E5E029CFADF8734D28770 -:10C6B000E43E5CAA3E347E109FBF84DF75C9820FC2 -:10C6C00086E07DA3069E0CE099AB81F78D91E02D6D -:10C6D000E171BA38F014EE936A3F3818E13C2FB19B -:10C6E000E2966400C188C3C1A38A01E55DE7538F68 -:10C6F000A2FC6A555D48C3B513397FAB7D492592CD -:10C70000EF6AB3F814F87E59EBEBA4977536020381 -:10C7100035F50F9FDE75EAE0DC170E7CFFE43AAAE0 -:10C720007478B6E0EDB3F6F94E5ADF8AE4840BAEC6 -:10C730005FDB2ED67FEA476C61450EAE2F67603017 -:10C7400027346E26EE37BCFFD3988A7A845BD13BC0 -:10C75000C363102E53D4B6BD57211CD6282E0B8C84 -:10C760003BC9C2BC51B0BF431BCAD927B04725C182 -:10C770007A9703E09138DCE652011E193F542B7C76 -:10C78000D0EF3FD7AC8EBB03CA938D30743A3C5781 -:10C790000C1584676CD7473F81FE32ECF35C1BA11C -:10C7A00036DF02F38171927F14ED4F05FEF067339F -:10C7B000B3229D9952EA0F4C857E7B625517EABFE2 -:10C7C000F12A9B8C7825E11C1FCDD7219F973EBE77 -:10C7D0005D09DA42CF2735F514AE82F2E66427AD63 -:10C7E0004BAE7352794F21EA3B12CEF1A9FC7D6624 -:10C7F000EC499A114617D9021E1DA8CF013C6B13B4 -:10C80000CCEB51FE7559799DB93349EF5D63E57401 -:10C81000D11195E443B9D8016B0D507F7E3BB385B0 -:10C82000F1C328F7C06B60DDEC6D95ED80E29CC331 -:10C830003D3096E0E1E0FD083DAB8BB11B104E6B47 -:10C84000A6960D898332A189C3478F273B93159AFA -:10C850005FF597407085A1E7D546BFD961C3E7660C -:10C86000CDF3230037AF25545F7C3CED3A46FCC541 -:10C87000B51EDFBF634334F386E9552D621EFDC14B -:10C88000A536D6C88C008F5A85555CE8BD97FF5BEE -:10C8900025F8EAE7FFAEE02F09E591D7F76632B752 -:10C8A00067CAEF9FF61BD43B6B03266681476B5E1E -:10C8B0002A1DC222F4D70BE72FC733DFA0B0BA314D -:10C8C00048F0A8FDF25A7A5E7E7FA719F11EFB712F -:10C8D000C2F33551EE21AE0BC0395BC0B9F6CB586F -:10C8E000E61D14FE9CE355A8FF786AFF1D0210F0B8 -:10C8F000D6DBAAFA76C0A7BFDB67B8615B84F97E96 -:10C900002DD63F2AC148F492ED67EEAD11C697EFE0 -:10C910000D8E033E6DE370AECCED3BBF96B2E002F0 -:10C920009CFF3593993BD278A7C57B72DE2D71C1F0 -:10C930002A81F7232BED617587761FA3C5F82D3764 -:10C940000693B0FFAEA96C4E7384FEE57E8F31D6A0 -:10C950002B088FD2444F06F291EA5BA10278326431 -:10C960009EDFE0C909D15D7FFB1E8237D85D851748 -:10C9700082B799DA657F270E08BA646E9B02F4B419 -:10C9800048C8AB45DB574E03DED96BBF9CD802F6D7 -:10C990000B0C7182D5BF6EC7FA2685EC93C51EC6F7 -:10C9A0001A80EF54ED285C8F626B512263D7C6F179 -:10C9B000E7F760B9CE1492B3F47F370B978B72FC14 -:10C9C0003B1FD4EAADCBD8839FA3DE73E200E70F11 -:10C9D000A09E92FD5DF5B0B6BF65DB6F3A86F35C55 -:10C9E000A6D37F3250C103FD233545D81363D81831 -:10C9F0009403AB769C35C738FBA7839340EF69E976 -:10CA0000C82F1D548E49718F4A81FDE87E9BCF73DC -:10CA10004A8A272F05FD0D6FF3799DA93EC3E5C412 -:10CA200063F1249F2CC8CCE14FCB5CABAF09E6711E -:10CA30003FB09328808FC5C2F520A9FFA9EA6A35C7 -:10CA400006DAC77EB6260EF737FED9EB6FC0FE12A8 -:10CA50009E8D76E37A3696BAF3D15FB0B1D2E66AAC -:10CA6000822EADF03DCA0FDFEFC6BE76156A07CD48 -:10CA70009BCB8621DAB5BDEA477FCA06C3E77B8731 -:10CA8000C1FB1BAE65AE26161AA7AEADF2799C4F60 -:10CA9000D22C2E673626BBF31D61FD32A1CFD50AFD -:10CAA000D875B767FC7C3CECEFA3FB489D86F5A5E9 -:10CAB0000C44BE318AF17D66E7014E80273876B896 -:10CAC000DEDA09F28A6584EAA39A15BF09D653D340 -:10CAD000F2BC01E561F5BDFEC173512E3D63746D7D -:10CAE0000B9B5FFC9F8796396342F268AEE2207D24 -:10CAF00041EAE5B731F99343783347E0CD6D421F02 -:10CB00009F1BCDE1BB98B992F0BBDBAD2CC60024D6 -:10CB100035B7BCB998E4D54A532CEA3FB89648FBE0 -:10CB20002DCBFEFC4AB54FD9BD0AEC7B97D2331210 -:10CB30003B3989BE1EEE5FF26D4BEEDBCFDD298205 -:10CB40000E470AFD308DB9EDB0EEDA5732B66E847D -:10CB500026CB00D8C702E24BD69202D28FAD68F73F -:10CB60002C7F39CAAFC484E0C21CEE7C03FA09668C -:10CB70000C2FD8883AE961E02F40605DA66012D1A1 -:10CB800031F01D0564DFC329932B8D80E7B55781F4 -:10CB9000FE05F5D7B655F27A4AB0CA00F593292BAF -:10CBA0002B8D8097B5A38247B17E2EE547BC5E10E2 -:10CBB000AC52A13E30751D7F1F0D4140ACE1A9FF75 -:10CBC000B3D20BFD9F8C15F2DD155C80F853FBA7EB -:10CBD0000CC3C6B0F55A5339DF3A19C5DF3B99CCBF -:10CBE00016CE4078670647E23C7BF12245EAC39BBC -:10CBF000A894EB94DFB1C4C8FD3F99C2FB5F5E2EE1 -:10CC0000F49268B601E106DBE48D01F8EF69CBD858 -:10CC100086EF6F488913F0827E8A42FD4838CAFE4B -:10CC2000E4B82B50EE223F36013F0EE3A3CD295C42 -:10CC30006EC238EB689C1C0EFFDA19C3F371DF601B -:10CC4000BF8C62BF8CDC4EDDCAE707FDC6E611FF74 -:10CC50002F34C2FB7BCEC3FBC9A179EBF1A35DE00E -:10CC6000C7F2266084A4A7A5121E4D8AE6FA212BDE -:10CC7000D2AE63602A879F353596AFB3773F86285B -:10CC8000344E9380E370807BEEE5AFFB2D319F6FD8 -:10CC90007BDD61FBE556B1BD356B5BF87A18DBAC2B -:10CCA000E9E7E45ADD77254080388FB854FAEEFE84 -:10CCB0002866A5E76C5BEF77C9795C2F457DB546A3 -:10CCC000E8D5CC7B2D3915AA05D7A8D910303BB1B2 -:10CCD000BD5971FB103FD3607D08DF19D38AC4FAB8 -:10CCE0001C627D0EBE3E9F064FD9C19EA459F6BE62 -:10CCF000F8DB0BF7DEFE720A447F1ABA8ED41FD21D -:10CD0000477FFBA1A47ECBFB21E7A983672F9C75FE -:10CD1000F393F0447AA6EF72B4F828E779AE3FBAFD -:10CD20004EBEC2F14AF977353F867D44FDC4A9C5A0 -:10CD3000E79A9664C3E29CD077ADB897C521FF5CB3 -:10CD40005AAAB07387B3E1C8BFBD65DC8FEADD6561 -:10CD5000713539C9AF97995A1CD1AF47CFF5F65EF7 -:10CD600077AC9929A41769FD0CDD09AE801BF5D4B9 -:10CD7000D3CCB503FA1DAFD33BBA613F77D942DFBD -:10CD800085E489B6FE43C13FFBFA8D7A92707E45F9 -:10CD900096B2179C2EC6CA52B712BF2E1A58B63A70 -:10CDA00019EAD7A73E49FCBA6858D95974CD4C4DF9 -:10CDB000DDCEEBD9656753B0FEE476FEFE24F70BBB -:10CDC000C8DF99777BE5E4A121FDE1C654278DAB4F -:10CDD000961B18E29145BDCB857252C2B3BFB2C853 -:10CDE00062A88FA4BFCEECA5677E9E5122E4738912 -:10CDF000B4E783468D3DDF1D63F5AA00D76E94A787 -:10CE0000B0DE05A99E3908FFBAE8CE05A80ADF1BE7 -:10CE1000FD9119F521C50DFA06FA459C0E360FE66F -:10CE2000A9746EAC203D7085CB6A24780A3F15AC9E -:10CE3000ED1BE8E7E5579EB97B181FA602E73156C0 -:10CE4000D07FDD2B5F7DF121CAD1933617AA816394 -:10CE5000DB1E598DFAD5D8B6BF7FC5E5AD8DCEA9FD -:10CE6000E4BCC7A2BF119E97B45A68FE63DBB296BA -:10CE7000E0FBE3DF694B45FC98D8E16F4276D0DDFB -:10CE8000FEC7619EF0732B764CF926FBF2F58B5EA4 -:10CE9000787C6666A85F023C7EC2E171BE0AFD8AAC -:10CEA0005D0907D607494F1BCEFD98E27BD0CB33F7 -:10CEB00091CECFB0012E3C57E8B6F37EF4FECDC341 -:10CEC00095B03E783EB1076610A6374FFAD20A0CED -:10CED00024542F65B19A7AB975A8E6FD298E644D60 -:10CEE000FBF589599AF6A9CE7C4DFDA6CCB19AF7EF -:10CEF0006F76956AEAB7944CD5BC5FE9AED4D4F3AB -:10CF0000FDCD9AF70BF7B56ADB0F3A691F0A3B2A8A -:10CF1000CA519F77053C4D585ED3B9A97CA093F5C3 -:10CF2000F1EB16057D4DF87CFCF9FA623FEBEBDF87 -:10CF3000652B3C741E60C17D51C3CE074A03448FEC -:10CF40005D069733DC8F3B6FB067672AF97101ECA0 -:10CF500000EC6BAD3D8370BFA62C7C488DC17DE994 -:10CF600061E4FF6A31077F361EE5FC7C95F4DE162E -:10CF70002323FDB1654EAE0F7D7F8795E08B1F2289 -:10CF80009F9A1F4DFC642268B8B46E3C0355709F95 -:10CF90003C9A7597B2E5BA7DBA4B539FE2F8B1E679 -:10CFA000FDEB13D76ADAA73A1FD0EDD3664DFD66C5 -:10CFB000D723BA7DDAAADBA76734ED133F0D3621FC -:10CFC000194DEAF4AA7698FFB8C39BCA715FC67779 -:10CFD00078E723BD14F93D4DC442F6D4BF8EA51F9A -:10CFE000EC2AF46BBDD69848E59E4627F9A5F6369F -:10CFF0006652B9AFD145CFFFD65842E51B8D6E2A98 -:10D00000FFD178039581C60A2A9B1B9BE9FD5D8DA4 -:10D01000AD54020447A0BC881F24E40FD4D1DEEF36 -:10D0200032046BF1C4F5B327CF115FEC1A10ECC2D8 -:10D03000FABDEC2CF1C5401A233AB4A633E2635D85 -:10D0400069EE6569509E4BE5F56E936D03CA816686 -:10D05000833B1FF5EBAF9E3CBFD93882B1FBD65660 -:10D06000243A6279DD0A75DA6C34CCBCE737BB87C9 -:10D0700033F67B1419E3A85E89F5EE28DE7EEEC94F -:10D08000F3955E9A1F3F6F9E153A6FFE2A35C2795F -:10D09000F3EF8F3BEDE86F39703EC38EEB3A20FC27 -:10D0A0004B6E966F5A0465A931DF8472F1B04E8FD2 -:10D0B00090E5BF6CA5065C4FB3C1351BF514EF8D31 -:10D0C00026B603F8C50C85DBA3BD7A601A9747DD49 -:10D0D000375BC8DE3968702F413C073EFD04C2EB68 -:10D0E000AA34FB0C845FB7BD2709E1909866E3F58D -:10D0F000849E27145758DDC4D7199B163DA39F75EE -:10D100000E4E8BB0CE61690E1A9FF9DD2350FECA18 -:10D11000FAC14A770DCA8983A5EE749CCF810A0BA8 -:10D12000D18FB7C2EE4B4726677417CF0EF3BBFC07 -:10D130002ACD44FB36CBCCE98CDDAEFA7644B0D3B5 -:10D140005E48E3FA3EED1BDA73B745931E7ED0C00E -:10D1500096ED8A00C7BFA77139776A4064FFCB1B81 -:10D16000027E6533EDD45FF79A283AEFEDAEC82022 -:10D170003DA8BB1EA004F4D17DBCFEF46E6AB7C806 -:10D18000A3303AD79C2BF8D4EFDB56FFFB10BCFF43 -:10D19000D19A6817F170C728924FB78B97E70FB2F3 -:10D1A00092DE327FC68832944B73C5F9D802BB71C8 -:10D1B000301D931963CD0EE8E74E5BFE7A14FF55E0 -:10D1C000F195E658A82F1B7ED77A2C57A46D36C749 -:10D1D00041599DF3FC7A541F6B80B48AC95E0ABE24 -:10D1E000D908F35AD8A03AB9FD24E49A7BE565C57D -:10D1F00063483C4438229E027CC92E7C53C05B7E2F -:10D20000F7A680E7DC34A1B7E5B2DC6FB4E73E0BEC -:10D21000114F3AE7BF39B21F3FBDB65DE86DEF9AD7 -:10D22000F9B82B9F36F9C2FD4972DC7F88791C342E -:10D2300033B7827ADCED76C28FBC3967EF2D86F585 -:10D24000E7B5390C746E2FF9788091FFBEF8530F53 -:10D25000F1B96B3A834F1D6284E7AD4827179353AA -:10D2600033BD6B493E8C3D07F207F9E279CF478722 -:10D27000880F2E137CB09EF8D79EC606AAEF6DF4D9 -:10D2800052B9AF7183E0839BA8FD8DC62D820FFA42 -:10D29000041F7C9A9EB735CEA1F295468FE083FCA1 -:10D2A0005C7586C0A779899E7548FFF2FC7296D599 -:10D2B000634278FDE5110B53F17CA2CD42780A144C -:10D2C000F0C4A3F1182F63716C74F68D9BD1F3DB5E -:10D2D000DEFDD79DF3AE49746FC27DE98D9341FDAC -:10D2E000ECEAFEF1E70073DA919F3CBDBD82F8C71E -:10D2F00001A7D38E7AEB3369953350AF3DE076DAF0 -:10D300004D50FFDDF64ADEEE71DA2D507F366D06A8 -:10D31000AF7B9DF628A83FB75DD47D8C0EB59FDF0F -:10D320007EEB0CF4639432650FD243B9357932B099 -:10D330006B908FA57B900EAE4F5C3419E9C099E6D7 -:10D34000247C98EA5CBB07EB37656E350E72A2371A -:10D35000347F1D7E57165F69C4EF260FBF6B1D7E9D -:10D36000775DDA6663F87737E43CBF0EEBD35C5B3E -:10D370008DA80F3AD3F879A9EC47D665BBE4AF681E -:10D3800027209E8E6EAB203E9ED75A417C5CC2A564 -:10D390006C56E57DE8A7AB6B551C0ACE6396D27B35 -:10D3A00058AF800E517B1EA805F8AC7FFBE2B8B5E4 -:10D3B000188782F57154FFC5DAC87CF72F88077A81 -:10D3C000BEFB9EA053949B95D0CF7B403FBBA09EBD -:10D3D0002ED657D7B6C8BE88EC198F1DE56B761AC6 -:10D3E000978BA385DC5C28EA778AFABF6CEEB7706E -:10D3F0009C77FBA7EB0FB01DE8B68ACFA30F5D6B40 -:10D40000DB055D770838B2A29E24ACD7B04DE42787 -:10D41000BC587CD7F270FB2D19E3249A29FE421FD9 -:10D420002751CD02BCBF665D9C050B9AE93CB63521 -:10D43000EC39F123617F0CE07C6F0E326BC0BF7F53 -:10D44000A78973C7BEEBFE4AF0ABFED6AD6D17EBF6 -:10D450005ECE7C14D7A65F07F324106DADB41DA477 -:10D46000FDECBB9E60E4F5F45907B7DF651C8BF457 -:10D47000CB831E14955E8C7CD0CED07F13CE270E2E -:10D480005D804FE8F9D1B7C5E72EC06F92709E7AE4 -:10D490007E23E3B3F4A5D4E7A0EEC5F83CEF2B510F -:10D4A000E4A7FFC4E9C9C27EBACB7ABE30A07D161C -:10D4B0001F243C6B002B0F9F2B667E4E0F5F8CC48E -:10D4C0007D3B6EF0FE01F5A2921D8F119FEA42E1B5 -:10D4D00000F4E8823AF29D2D575514E0772C93E33F -:10D4E0004FB7C2E5A2A47BD007A91C9BCEE551DFB4 -:10D4F0009269E21ABBB77E95447EAC8BE07B7F706D -:10D5000098A24E087A91DF974493CAD3A930BF02FC -:10D51000FA5F67E960D2233A47988D587EDB7662DE -:10D52000E78891D4BFDE5EEC1C5A62E5E35E7703C8 -:10D5300096AD66CF964568278DB5909DF496880781 -:10D540009C1ECDE3A7DEC27362786FFA91F3F128D7 -:10D55000BFF4F666E7FE7965CEBCBE7627AC7332C3 -:10D56000AEB3FA63C37DF8EC72EDD0EA862F987102 -:10D5700010C8ED86F3CC587829762953915D141C98 -:10D5800076BD8E65F1A781B83C27DA9F527F10F6F1 -:10D59000E945E2904A7AB8BE30E93CCB3416A19F07 -:10D5A00069009DDF28257FE776AB28E5B9C8043EF2 -:10D5B00005B6C060F39953347148894628E7A9C17C -:10D5C0003158EF62013A27D1DBB37F157E28B06B6B -:10D5D00037A6935F8AC727C18E0C42FC9DF293F752 -:10D5E00017DC4D7C208AF4A15EBB76B781E20C5A31 -:10D5F0008CEE8113D1AE6D4877AD85FABF0209BFBD -:10D600007A19CA3AC717043749BFD50D67099EBDB5 -:10D61000E703C2EFBBC904F207CAEAFF56490E5539 -:10D6200033B681F68DBD665E15261759F3E7BDF05A -:10D630001F0D7CAF12014876D684996EF8AE52D891 -:10D640001FCCDBCEEBC2EE626CC44C37F453992096 -:10D65000DE679B79FB08D9FE0B5E4F97FD7D3E830D -:10D66000EA43655DF49725EBFB793D598E7792F798 -:10D670009F2BEB165EB7F3F75F48FFC34CE40B92AA -:10D68000DFBF942EE4443ECB177139EDE9C5178C0A -:10D690004BD1B60BF9B0F019D56B1E8DFB3335FAB3 -:10D6A0004DA4EF668562E7AAEF3191BFFB545C732E -:10D6B000DEEA307B45C6B15494DBDDA8FFD5BC98CB -:10D6C000B14D15F13CA87F7CE1E47AF914D546E729 -:10D6D00013671EE47CBF3FFDADAAE165CD7EF66910 -:10D6E00057156E8FE3C11D8C77FAA1215BC9BE4827 -:10D6F0000BD0F9F98782DF0D06DE5A12178A178BD5 -:10D700004F656EB457E3FF08FC19F7F8D300F1E357 -:10D71000AA3F72FF6FCD23AF93DC5BAC3AC99F5B2E -:10D7200096E3F918E1D3650F905FB1AAE1159AD796 -:10D73000992C61573A7A72C2E179A22FFC4F5F04AB -:10D74000FEA7BF4FF8EBFDCE2B6C7B68BD2B2E33B5 -:10D75000AEADCBCECF455D629F8E189C6304BC2CD2 -:10D7600023012EA7970446C6AA18741C18CCE3966A -:10D77000DE2846BBE84CBD9DE1BECF5BFDCF3C4FF4 -:10D7800004BFAFDE1EB80DC72C0EC12B61641FF89D -:10D790000EC5F12E005F6DFB770CDF21C6A0D98589 -:10D7A000E7A88719F5332670C41C1E1F337624C7DB -:10D7B000CB81ADFCDC481FF73576A49DEF93389FF5 -:10D7C000A999F1C6043C9F91F430299A35A3BF1D55 -:10D7D000F0DA25F0DA85782DF137744E03DF45A0B5 -:10D7E000AF10FE6AE1EAEE0BD7C9232F8CB7DAF649 -:10D7F000EF18AE2DA00FD3B9E6EE28F2A7E8E1BCF2 -:10D8000074243FDF92F06EB8089C1BBE2338378C1F -:10D81000746AFC1112DEFDC927FDFEC87947A0D34A -:10D82000E22BA1D3AF33847D630C529CA97EDF1B16 -:10D83000FBEE7BD345E8A9E9FBA4273DDCF465B505 -:10D8400038EFD43FDF3A92FBCDBE2B38FEFFE64FD8 -:10D850009F5FFFAAA67D61C37E4DFB22EFDB9AFA94 -:10D860008460A01CD15CFAC7AF3DDEF33AD6AFD4DA -:10D87000CFDE9F7F7DFA0B4B0D78FE5612E0FEFD4A -:10D88000C5999E2F90AFBC65F035D901AED77434E1 -:10D89000AB741EE6CBA773C0D5628E6727FCE7A3E7 -:10D8A000BB016FCE320BF93FFDAF66199DB97DF11B -:10D8B000A0F44B95B9C3F4C4526BAC11F5A75260F8 -:10D8C0007991F0E66B8137140F04F43EC7CA4CF12E -:10D8D00040E773E62814FF3487F1786A28FD1E6854 -:10D8E0009F6E647E0BD42B6D46BF85CEFD78BEC384 -:10D8F0006C3E4D663182C686F65DFC20B28367E1E0 -:10D900004398AFEA56299E6D76093F2FBCDDD66C51 -:10D9100042797ADBBE7B4FDF0DED6C9DB798C76B0C -:10D92000CBFCB50F0C97730EF8F5484EE7DD8A383F -:10D9300057564C2E8C73D57FF7D6484E67D3D5B546 -:10D940002AC6BFF4BCCD48EF967407EBDB6729E02D -:10D95000F919E3709DCCE4CF8841FD797339BE5F3E -:10D960007DD04970A92B599B87FB583759F9D8921C -:10D9700017B26FEA1ACE919E3E457DAE09DF3F7326 -:10D9800098BBC6AFE9F4AA68AF84FC97C105489775 -:10D9900017B383E4BC3B1AFD844F1F35EEA3F2ADF1 -:10D9A0006BFF5E8C7A46B03110D17F79A5FE02E91B -:10D9B00027907E03C907FE754FF910C4CB74C917B1 -:10D9C000ACCA30E40BCCC84BC92FB333FAF0D7D173 -:10D9D000191796ABDAF6EF98BF5E2A9E572772B9F1 -:10D9E000A8C76F3D5E4B7C86CF8A1518F776D0F7B7 -:10D9F00050AECE65DEDC6AE0B373966E328D57AE04 -:10DA00001CAF57D83E4D6211F2542E9F9F3B79BCFC -:10DA100064B94AF6818C5790FBB03843F81943FB40 -:10DA200056957161B9A86DFFDEF5F84F175C995CEA -:10DA3000639AFC86B57DF1F5BE8BE0EB7DDF27BEFA -:10DA400086E5CF2C500DA17C118C27463DAEDBC75F -:10DA5000F32197256F8AA1E0CC929E18D41B97B72B -:10DA6000AB8487CCE8360E057C5D2AF0B593F9DFF0 -:10DA7000457C5C3A6129E5D12D7B2C725C71AD78D7 -:10DA80007F85ADC58CEB5CB15DFB5EAD882BAE7E5A -:10DA90004EEB17AD9D70FD31ECB75617CFF36C868A -:10DAA000881F2E60053CEE42AB9FEACBAE46A6F146 -:10DAB00057769D6F247FC00BBF3DF94BEF8430FB41 -:10DAC000BF2FDEB65F046FDBFF6FE2AD6ADF4E791A -:10DAD00055978BB73F1AE53E80F396FC781EF226E9 -:10DAE0001877DECB169F17CF478B9DDCBFA9F89A1E -:10DAF000F0BCADFB2B46FEA3C5C2CFD95F5EBA8C8E -:10DB000037187BD0D7C4E30DDC2AE6898ED957516C -:10DB10008EC715856FD4933ED2EFB995CCAF12F175 -:10DB20004397CAD7A45F6FCCF17AD2B35C0107E9FF -:10DB300043E3BE6C7E1DE5E3B7E5EF96F270FC2093 -:10DB4000EEBF280A56909ED765F217BF877AC24B60 -:10DB50005111F5047326D78B667A179978BE619FA9 -:10DB6000F34073269E070AFE6FB0BA4D08A7296AD4 -:10DB7000E7AF6E45FC09A8E4DF5BF3D377FEF0A8BE -:10DB8000F3E2767F9DE32CE90DFDE9FF75069E7FAC -:10DB90005150EEA4383FB4A7D0BF27FD7DFAF78BD4 -:10DBA0004695256692FF6942C08DF3D9C2E7D3DF5F -:10DBB000FED4357CAEF12FF6377E5D7BB1637118F4 -:10DBC0001DDC96A948BBC371D41ADADF4BC5838923 -:10DBD0003D7334FACFFFEB76C57415544B909FB963 -:10DBE0008A8FEBAF8CEBB1F35880CA05AC874A0F34 -:10DBF000E3F1F78B998BCA3B451EF3DE2CCFCD9911 -:10DC0000781E61EA194CF1932F7E9D837873FADABE -:10DC1000F19B30D6EEBBD2E3BAF39D347EF7EEAF84 -:10DC200093300EE6627C614DA2DB9319E1FCF91F93 -:10DC3000A52A9DB7B0C38F929CA814B730B0C9FC79 -:10DC40001CED0B6732E143882F0ED92AF9229ECFB3 -:10DC5000E67E6CE0F124CB155F3ABCDA1A34106929 -:10DC6000E52E49F6A9586FE1EDB935B13E05EAB99F -:10DC700063A378FB5DB13EF4A3CF6741A2C78540A3 -:10DC8000A2582E629CEFDDC1DC3CDF81F5A4A01E12 -:10DC9000B6A4CDCAE3FD59300DF97B5E3FF64F5B6C -:10DCA00026E7D3A353383F1F5DA6F553DC2BF8C0FE -:10DCB000275965FF447A3A96E96EC272745C60E354 -:10DCC0002F8BC86FCFD07E3836F6C774DE28BF1BC7 -:10DCD00030AA6C03C26FA7C2E3D3BDED168A8F8052 -:10DCE0002F065784C5F5EFCD2AFF19F6F72BE1F77C -:10DCF000EB0FAEF09D266F36444F5E9ADF68B4B9E5 -:10DD0000C8FF0E0F4A685CAA3FF5F4B459EB72C81D -:10DD1000C7EF45BD77C028CFFFC2798D363366C3C4 -:10DD2000F93F6EF16D23FDB43E09FD954B9FB01890 -:10DD3000506F781FC42DE6A17CD868A5F29F6007BC -:10DD400063F92FB083B1FC18EC602C3F013B18CB7A -:10DD5000255FE683B060AC2CCBDD9A591C3A9FD38B -:10DD6000CFF77901CFDEF1DBCD34FE27591E826F6C -:10DD7000EF7EBFC47C78A8B333B6E7AAB80BE05BEC -:10DD8000FF7C86C3459E17EADB7F2BF63DAFC54877 -:10DD9000F23DAF35185315F6DEDE4C33B5E7EEFE37 -:10DDA00094F250BB1CBDF0752BB0E4E9065EDFFBBE -:10DDB000F46282EF2759EE7F225C81BEFF86655EAA -:10DDC000EB3BBFC0FC1FE89FE20EBA959E5F931D20 -:10DDD000A05B871E0E725D3B63031BF1FB9DBB5373 -:10DDE0007025C06F18A71BC42325D27AD7D27C6FA9 -:10DDF000B1F414615ECB2DDFA811E38C3FC92A2555 -:10DE000038FF18F12D210C4E62BFAE94AE7BCFBF10 -:10DE1000059E32797F07F24E27CAA1F331A8EF554C -:10DE20008AF3FDD696B4B7707DDE7D2A4B7712FE5D -:10DE30006AE8CE91C5F14496B9EDE60ADCA79DEDFE -:10DE400047D3EEB4D1BEA42DC171B3D235FEC7DC29 -:10DE5000B15FFDD72FE3E97D070E751BDB3A05E3C4 -:10DE60004FE65A5FFD0B2E69BEE3E329187FB230FF -:10DE700051D98BE52267F275187722E3E3EFC82CBE -:10DE8000DD8BA434CD55497A5A2932973079506EBA -:10DE90008DC643C1DEFA14C7204DFDFAC4619AF75E -:10DEA000A73A5335ED3765666BDAE5B8D35C859AEA -:10DEB000F746C7F5A4A07D06EB207A603B548AD3D1 -:10DEC000CBDD7DF0C66CA84F7F6AB60BD5929DA2C4 -:10DED0007DFAAE721FEE4737C0D30C0AD4F1920719 -:10DEE0007EFD4BEC4CA7FF57B73FB9D7EDBC0CFDFF -:10DEF000BF1FBD5FF2D9956DD662E4B3976A07E89C -:10DF0000F7272F4B6B17F48737BD74A13839DEEC38 -:10DF100057D98E08788311A91C0F7939FD00CF1FBE -:10DF2000BB5C7EF619F2B34121FAE82D757EB9D1BA -:10DF300066D75BABD14FFFA6CA281F4FE4F555E16A -:10DF4000DF6A08DFD99D5BEF1B1A4FCFBDA8E762E0 -:10DF50007EA91BFAAFCA12FEEFEA57EF1B5A146AEA -:10DF6000676B3ED6BCCFEE51D66BEAEB92B5F507A8 -:10DF70004BD7877FDF1F5FACDAB2C8ECA1FC4FC57F -:10DF8000ED8BC01FE47CA6BC1645717D3763BC0ACF -:10DF90003CAA2D7ADB88E7B437F7234725FFB94D34 -:10DFA00065F591DAEF12FD4E7B2D8AE2602EB7DF28 -:10DFB000F701961467F8472E47DF1F183086EFFBEE -:10DFC0003D595C0F3D5DBCF9A75FE0F9E84B8CE281 -:10DFD0003E4FC772FE9FD772CC608072F4008E2FC6 -:10DFE000798EA001E54AF7B2682FC6F5D72DB75351 -:10DFF0003CE8E8949E77ADB0F5EB9ED9FBB015F602 -:10E00000ED034C820C93ABDD681441FDA1ACBDB3B4 -:10E01000D6C1DF37BD16E5375CC17A1EC2730994DD -:10E0200083659CCE1720DE08F9823EF6BAFB58AF16 -:10E03000BC41BE80EBC7FA9E67F61F7C18F5F0FD69 -:10E040009CCE31C24E6FDFCF0DB3EFD9639C2EADA6 -:10E05000F0CBE39474F4BD6793D976413A6FA6B8D8 -:10E060009B4BA5EFA7919EB32F48CF076E82FDA9CA -:10E070007B89DF6B71A62D9DF262FB93E7755B5484 -:10E08000A24359EF6A536F40BCD5E7A14BB832B7F2 -:10E090008BE853DE1BB56AE27F66A0DC5CD56EE4DC -:10E0A0004122FD8DB34165CEB07176BE625946798D -:10E0B0006E62FEDD525EB7FF3BAE3487976B23C8BE -:10E0C0003D90D3A67894D3950AD99587DA87942181 -:10E0D0009C0E29CCEFA4BC2D1EA73C937787CF6D57 -:10E0E000745F496226C5274BFB52DA95B3DB67A7FD -:10E0F000A35EF96ECBE243B073ECC3AC541AEF5697 -:10E10000E6253DF8506CC508F44B4C17F1018762C9 -:10E110007B3A912F1F9A18ADE0793FF4BF0EFB9721 -:10E12000EB3A64AA18C1EF9F9071C9A3AEE89EB8FC -:10E1300029EA3DA537E1F9F63CE640BBF21695EB3E -:10E14000B9ECCF9C3E25DFAB53027138CFBD5933BC -:10E150004E67C177431A7E26FCAA026E461E877858 -:10E16000A97A6EAF3DFBB4C2EF457171FDBF76C2B7 -:10E17000A95FDD8A797260772B309FC5ADAFD2BDC4 -:10E180003F7A3BBBD7DEF93FF4A7F6B5972A2CA31D -:10E19000C2FCE47ABBA9574F97FADE0E1E27FFFA9E -:10E1A000C4DF74AD84FA9A1DD104C7134F58BCC89C -:10E1B000C74F6CB390FD7322AEA76335D677E5BA2F -:10E1C000BC349A4B732FDA5283F33D943FEC6F26A5 -:10E1D000BAD7E3D8E3163FC67B2C7F326B1BDA53EA -:10E1E000C746389F7D0EFD81CF26D03D03CCC3BFEF -:10E1F000BF59D023D29713540FF5B776D22396BFC9 -:10E200003094F898DCBFE38F47511EFD897D3307BA -:10E21000A2BFACD3F03CE5F130D5E6457EBC725BE5 -:10E2200014E9810D0E4FD628585FF96F6FBEB510F7 -:10E23000C77F2781E17ABADB5E207F65687F23CBC9 -:10E24000F7336DA99C0FF4CA5B1E77BB10E36E53C6 -:10E2500029EE7634C2B786C97B1779DC6D81AAB8FE -:10E2600029EFE0A1C879E4EE515C7FAC96FE9341C2 -:10E27000CC9A8874E861B4DEEE8732B6A1BD33670C -:10E28000545CEFFD4C3C5F52E25B47EDCBE43FB1A9 -:10E29000F078BFA8C8E7D8D346F1BCE22AEB398DA5 -:10E2A000FFA6B6E12B8D5FA5368791DC2D6872162F -:10E2B000DE05E56A01E7E52915B7E0FA56346F7E19 -:10E2C000F10D82CB633FFA00C7DD6723BF0D7B836F -:10E2D000C34F6FCF54593F17F4B45573CFCCD147C8 -:10E2E000DEA37893A3BBB3F370DF16AB81A3781FD3 -:10E2F00057973DF0D1DD50EEDA7780F6453FDF3EAF -:10E30000E7F60AE72BD5B88E4118EF52B16414D165 -:10E310002DA7F7231B73097ED29FDB7D22B2BD257B -:10E32000E729FB97F393FDCBF7568BFD3A6D0EE48F -:10E33000A17C4ECC746AD6753A2690176BC3E7DC85 -:10E340009F773A0EEA6178F35D9DEFDC2EFC3C8707 -:10E350000D6B7F6806FCEB6CFEA5C913CE472FF34F -:10E360005C47CE57C695CA3CDA874789F388116C5B -:10E37000443FF9B75B90CEAAFBE6DFD2F3FEF26F23 -:10E380007BF36DFFCDF36D657E6D51B9A13E3CCF42 -:10E3900056F2C3A26C789E83E7FE5AF95E345AFBAC -:10E3A0007E7FFCB1209BDBD7458322E7BBEE1FC5F8 -:10E3B000DB9B989FDF3F28E4E278017779EF97D4E1 -:10E3C000536A05DF96799EE3DB78DCE67891B70344 -:10E3D0005C80F25CFBDCEF96984D7255DECFA74077 -:10E3E0005FF3E222E50B07681ED7B21E2ADDCC617F -:10E3F000C412C04FE5645641E575AC9ECA1BD826D1 -:10E400002A6F64CD544E63012AD928BF88F7BC8790 -:10E41000E7994E5D6A40F95A746B64BDF8D445E1E2 -:10E42000E0A5FB032F170ED7317ECF5F1F780CCFEF -:10E4300024FCD6C3439FAF399105E9E2924988B8DD -:10E44000A968073B29BEB59CB9A93EE512E1501267 -:10E45000F418797EAF0E1EE591F1E29CA0FF9FA219 -:10E46000EC2C0EED5356B693DFDF20F60B0CB144C7 -:10E47000E4FFFA7D94CF8BA2CBCE3A8145389E6DD6 -:10E480009C4D79DC8565AB53A19E92BD6936E579DB -:10E490008F2F7B01F3BCD39EDDCCEBA3CB0A4D2E9B -:10E4A000D022D7FE6236E6337A44DCB447C44B331D -:10E4B0004FBEE69E2CCFDA1FD2BD639E113617AE3B -:10E4C00053E685ABA9FC7C35E906FF6B2678AFDD0A -:10E4D000E189CE46B965F5C738514F583B85EE8F77 -:10E4E000BADFCCDF97F7D9C8F5C97B6E76EDCA5E87 -:10E4F000ADA45C7C1ED0FF50ECDFB3369DF2E33C54 -:10E50000BB15910F5736640EF08DCE8089617E81E8 -:10E510001CCF94E249C2F71926C5035D0C1372B8EB -:10E5200073577636EE5356B638DF8F4F2E4438DEAB -:10E530009A529185EFCBBCE82CDC9784FECBCA6C59 -:10E540007706BEAF7F2EF3B2C7657B72B1BD2EFAE0 -:10E550003CE59B75E5BFB33E98DC374FBDC9CD7C2C -:10E5600066E22BDAFCF4EE2566BACFA9A8C2D38402 -:10E5700021CAD7CCEB1983FA31F45B929D80F7095D -:10E580000693F2E1BB8767F2FC777DBE77FB2BFB3E -:10E5900035F9ED92CE7AF3DBCFF0FCF6107D3DB28B -:10E5A0009A85E5B74BBA9174370EF3DB63B09EB52D -:10E5B00004DF9BF84E07E5B74FEA088AFCF6F7B48C -:10E5C000F9EDEEFF5C517EFB3171EFDB312BBF2F9C -:10E5D00049DE27B56A373FFF5DA5F0FBA456FD9ED7 -:10E5E000DF2725EDC265627D35FB77ACC773BE655D -:10E5F0008FDD41F75131710FAA137EC3ED42792FA0 -:10E60000A93E0FA60EED41D29BFDA477E9F361EA86 -:10E610001E2B277BB04EA747AFC816F6A090674CBD -:10E62000E87F4BC5B7B80E1BD96766D23B573DBED6 -:10E63000DAE5C0BAA02BF6D87374EE26DF678F0D2B -:10E64000225C9074B67C8342FAAB84DFE8A72C6E20 -:10E65000BAC7F8A921A4B782BE2DF2987DDCCF0FEE -:10E66000B882F1F03B637B52504FDED99EE9020E37 -:10E67000CBFED4EFFDD3CFE9EE9F7E5273FFF419AA -:10E68000FC1FEA69C70D3EEC670CCBFCF904A81728 -:10E690001F37BA7CCED07DCC17BB7758C2DF22F6AD -:10E6A000EB72EF21D6DFF72CF31FF4F711DF2FEE1B -:10E6B000239ED8CF7DC416B54D25FDE19C51732F07 -:10E6C000F135629D254EE6C37B7EC7751A35FB5F2B -:10E6D00012DCC4501F8A3A68D4F8112C4E6DFD39F3 -:10E6E000890FE27E91BEF0B6F5C2D342F04CFB0D2D -:10E6F000C15377CFB38453EF3DCFC36D84F7E3F6B7 -:10E70000BFA0223FB8DCFBBEBFEFFBBD2F769FB79B -:10E71000FE9E6EFDBDDCFDDDF32DF73DDFBF4AF350 -:10E72000BE7EDF0BF7FD447B0FB5D86F2FFC7E9BC1 -:10E73000FB7D325BF877C57EF7E00568C0CFFE1140 -:10E7400073FC4124CBE9D1E23E3869D74F30919D2B -:10E75000F5967350B91DE95FC8A90A21A75845333A -:10E76000AF0B7C7105781C41C1617E7F455190C71C -:10E77000138C391E393FE896124573BEDBF7DE6213 -:10E780009E673CFE3C8FD3D39FFBCBBCA14A7794C2 -:10E79000F6FE867EF288A41F07F47866463DDEC04A -:10E7A000EFB38B70CFF11635353C8FC843FE9D59C2 -:10E7B000D64012E27354B2273E2721946F3409F3F6 -:10E7C0008A14B20785501AF8038CF3ECC624DBAB2D -:10E7D000307FD4F603CC9381E93B8263B8B98B3F99 -:10E7E000C9399E1139C0078F288EF585F0ED3FC6D7 -:10E7F0009D4A42F964C173ED023AF7BD3A27FCDC49 -:10E8000057DCCF1F343849BFF0FE4421FBE11476BA -:10E8100036368C5E3798445EA3EEDF2F10F694FCFC -:10E82000F70B8E4017CB806FCF6FE579D42B133B5E -:10E83000851DC6EF71BD63B88DEE7F62EE4217B7DE -:10E84000C3A57D354CBD1CB979B1F8A29589273493 -:10E85000762E7B6ED0259D2786D6CDFB3FF24034A9 -:10E86000C99B230F8C203F5FA8FF2EB2FBE7D76B1D -:10E87000E38C1736BCAFC1BF45DE8F35EDC1F81E46 -:10E88000D330587FF0C5A1D7CD05F89DDE6D198333 -:10E890007406FB362B27CC0E0E3E943199EB0117F4 -:10E8A0005BE7299A4787881395EBFCA8F130D5835D -:10E8B0008D415D3C8F576397CAD2FC1AA37B727A55 -:10E8C0009401AE487E9693395C6FEF1079901D22CB -:10E8D0000FB243E42D76883CC50E91A728F3473B41 -:10E8E00014E6C6788A798AFB8945C9943F7A17AEBF -:10E8F000B36E454F1EE6DBD58D0E2E5054CA1F5DFC -:10E9000083CF23E48FE661DEFB1F726EFD01EAF91F -:10E91000C70778E95E92A79E9BC1EB664E1F2FE664 -:10E920004CFC01CF27F5FC0FECE75345F5D3FD1761 -:10E930002F29749ECADC41F38C0BE497DE97C3CF7A -:10E9400017D6EB4AF2452760FF4CE47B3D3892F244 -:10E950007EB65828EF07C6A1FC2B79FEAFCFCF2A91 -:10E96000F8B3C58F7C43FA611EC94996F702937FBD -:10E9700025FEE7169EB7150C24619E17C6FBE0BD69 -:10E9800019EC2073F33C307E7F9FDC87477244DCB8 -:10E99000195EA45F14CA13ABD97FE423E42365395D -:10E9A0009EC771FD327FA926E6558A9BD899E3A4BC -:10E9B000EF60BEB45EE007EB1482731F3FDC0EFC19 -:10E9C0005E9FFFDEDFFA4F2F09FC3A2739943F158F -:10E9D0009637B53327CC5F26E711EAE7C2782DFDDD -:10E9E00049217FD7FD23914E0AD00F1EC1CEDE2BC9 -:10E9F000E0D2618AECBFFB384789983F5790C11835 -:10EA0000FA0BE57D93EF209CD0EF749B8BFB4119B3 -:10EA1000BFB7AE6686CD857C4BF68FF7E53E7F812E -:10EA20007196A754BC89EB5F51CFFD7DB2BD5BE110 -:10EA3000FBEA7D88E34BCD2BEF7F74378CB2FCB7BC -:10EA4000B985C8A7E5F77A3877D979FEDE62D54F60 -:10EA50007004F87E80FBA4F7F35D295C2F377F1AE2 -:10EA6000E045F730F6F583032285E96F16F9FD706E -:10EA7000EDFD6616FC771860BC1661F7B408BBA7FD -:10EA8000D524FE9D1C9D1DDC12E071442D89668AF3 -:10EA90001362E2DF7590727FCDDB3CAE684D32A32E -:10EAA000769C1FEEAF12DC4B72A8F79E2A05E42B72 -:10EAB000C0EF94C3A3E6A21FDAB39AE4927A35ECCE -:10EAC0002FFA4DFF76A3B0E7B89C2B1672AD18FB5A -:10EAD000C175E40C24795724C61D63AD277D7A2CBB -:10EAE000F30AFF8EF0833CB097ECC0FF0D9F4D61A1 -:10EAF00077606800000000000000000000000000D7 -:10EB00001F8B080000000000000BFB51CFC0F0037A -:10EB10008AF92C181856593130DCB0666070B4612F -:10EB200060D86C8E90BB218E6053133F97A74CFF2B -:10EB30003C4906860540BC0888974892AEFFB71648 -:10EB4000825DACCAC0F007C87701D25FD519186ED4 -:10EB500003D97F81B803C85F03C43B805804C8BF92 -:10EB600009A499D518189E00E97F40BE34907D44D1 -:10EB70000DBBF9FFB5F0DBBF5D0395FF128D7F4143 -:10EB80001DBFFE284DFCF2AF09C863C35EF6E4C7A3 -:10EB9000471F057A0702AF474BD7E2A60C0C7A66EF -:10EBA0000C0C85D0B4BF0649BE192826610A617FC6 -:10EBB000D103E617207F258E7CF11528CF0F94EF27 -:10EBC00037C76FBF38335A7AE1C154F39609C1AEE3 -:10EBD000174295DB248CA9FEA708030300E92850FF -:10EBE00078D80300000000000000000000000000D2 -:10EBF0001F8B080000000000000BE57D0F7454D54A -:10EC0000B5F7B973EFDC9924772693106042024E72 -:10EC100012D458038C18302613B821098424E0003C -:10EC20007E34565A07E421B640A3B5ADEDF395E125 -:10EC30008F315AACD0F2FAD4767DDF40D5D5F6B913 -:10EC4000DE0A8A4A43422790502488112DD66AFB57 -:10EC5000A276D9F81AED80C1C6EFA38FEFEC7DCE76 -:10EC6000C9CC3D994942F5AD7E7F64B537F7DE7377 -:10EC7000CFD9679FBDF7F9ED7DF63963B7B988E75E -:10EC80000A422EC17F0B09F95C2E21645EFC2A9E8C -:10EC90002F729270C61C42B29C077A67E710B2D8F6 -:10ECA00050FD4B7C844C75AEED26A5840488C3E7EB -:10ECB0005008E9525EE89D4DEF8FBBEC7E0781FF67 -:10ECC000EE22643E21773BE99FB4FCF173F40AEF36 -:10ECD0003FB145082D5FAB361205BE772A7E870F00 -:10ECE000CA9BC6B22984D410F6DF8273A446A1CF92 -:10ECF0006BBC773492D984547B68AD4EF6EE12FE2D -:10ED0000BF49082D5F4158FDA6D3FABE82EC3AA751 -:10ED1000BAE12EA60667D1FA2EEAD6F7DE257F24C1 -:10ED20006E2897F0BC80F603FEA03CB88AB872DE6D -:10ED3000CBA07FDF406EB8A4D2AB3689901BE37CBA -:10ED400091AF848409994C483BFF5E23C1D9704F31 -:10ED5000C833D87EB6E0635D3FF1D27EE79411FF01 -:10ED600012CA87A9756617A17CADA8D1191F6BE7D8 -:10ED7000E7F61B84FCE083B63C52423F8F6C423E78 -:10ED8000E6703E767DF0FC9B5B806F7504F976D86B -:10ED9000EECF0D968CA62750979D46683D7B824707 -:10EDA00033B01E42FEF3D2145E4F11211DC1C2CCFE -:10EDB0005092EFC4F591AD1E421CF1FBDD26A96B0C -:10EDC0003346977B1E06731E54BF06E9ACE0BCFCBD -:10EDD00081429ADAB0DD261CA7C39CFE6EF368461A -:10EDE0007F09BC8F66D8683FC2E76CE4495A45C7C3 -:10EDF000E0A274A077BB698BC2F38E413D02FC2078 -:10EE0000DEB6BC15B346D37FF8DCBAB9D8AFD0268E -:10EE10004BBBDF1FA4FD35A07FCF642CA6F59C1F44 -:10EE2000B479543AAE7BF8F3C3A1B60C0F7C37909B -:10EE30008DE3F9C856FAF7D5A9F9F1C8822F1786DC -:10EE40000C28E7B4F263F0FC89223A6E1D7B353F53 -:10EE5000F46B3C7E7E9FB723EEB3FDD16A0FAD37D6 -:10EE600010F32BA017D983844C2A00BDE838E6861E -:10EE7000F16D24A84781E0A2B42B593FFCAA0FDE14 -:10EE80009F52413E029E28F663841EA0EF6AA0D3E3 -:10EE90008BD747797B3F8471C4FE6D4FBB8AD27B91 -:10EEA000BE4CC37AF69BDBAB34ACEF62540579DC25 -:10EEB000C4E429C717DA6607FEAF27FEB00FEA25BC -:10EEC000D8EFFFCEFBFF635E9F68A76330BB4A03AA -:10EED000FA9A881FD4A456BDAF0BBE0F6C64F4CF52 -:10EEE000B8B75901FE5D715F3F5E239CCEDDF03DFA -:10EEF0002D90DF1C53806FD3EF89E275EFB6B7BA60 -:10EF000080BECC9D240D6CC19E1A5B167CB767F148 -:10EF1000B43478EF0E52C5A7F620E0F7DCD54DFBF0 -:10EF2000B3B746433AF70E52FED372EEB0C70F7A2C -:10EF3000ED0EFBF8D5EF87F2BFE4FC38CCDBEDE457 -:10EF400074B8C3262FD75C02E5DCE1305E23BC9F9A -:10EF5000C4B719E5EE6E2E77BFB4873E077CCF1994 -:10EF6000245E42F5F9F087F5B9D0AEA85F2EFFD444 -:10EF7000E3FFF37A783F7990BC6D9F0DD7E85A682C -:10EF8000EF6AE8871BEEFBD62A68A722A847E6456A -:10EF90001B21C5713B95331C5C7A13DAC75AD42305 -:10EFA00061072A06759B9299A86735A8077BB91E49 -:10EFB000D40C46514EA89E1DB3513E853FA07A46C3 -:10EFC000E5EB70D086E3FD444C473B4C8AA3792B9C -:10EFD0005CA3F5A8E3DC86B9C06FA14FA3EDC7FF22 -:10EFE0001BFAB597F62394C4AE89F684BEC9EFC761 -:10EFF000D5374F18F5AD83EA5B18F819B4A5CD04E1 -:10F00000FD6BB5A19E786BDABA98BE6C427DCB5988 -:10F01000CFE899BA26827A309EDEEDF579AA34A837 -:10F02000BF89E969C7E03BDB1C301E6B08B71317CB -:10F03000BBE03E702FD36B59CF643DCC0CF4A17E66 -:10F0400016EC8C11B8FA7634A25CD356D250FF522B -:10F05000E86107E861E9FF3F7A5823E671CA982C16 -:10F06000CAFFFA186178C8B30FF150AD8FE3A182DF -:10F07000D76FFD2A7DFFA23D03C7F5C5C9F421DE88 -:10F08000AB110238E3CA7F5973372D5F9F23F0CF4E -:10F0900046D4EF3AAEDFC7E011D59FAA7E85CCCF2C -:10F0A0008672EFEEAEA6E54F0E103FBC3AE9531163 -:10F0B0004F750F12AC4FE8671DEF6F37BC07791B18 -:10F0C0002611D04F81236AB97E9FCC61EFBB2F12EE -:10F0D000B403A2FC49A244547A7F9CCBDFF9E2DB63 -:10F0E000FF87BB90903F6F8BCD8ED2E7FF6E8B7DFD -:10F0F000DD468BFE7E99EF69B81FE0E5FE83CBE924 -:10F1000020C70D27AE0DDDA450FC5349621BEE86CF -:10F11000EFBC458FCC2550DF47330865ED57AFFE78 -:10F12000CB7BA4102869D383AEB85E89FA443D2F07 -:10F1300078434D0A1D8F81C8BB6E18BF0F0E7E34F9 -:10F140001BAEC49884386B3C3C1610E315EBDB0116 -:10F15000B883D450B9981F978BA9B1BE63886387D1 -:10F1600018FE22759B711C2A3D8C4F5D17CEE6C19F -:10F170007747385D9DE7FAF2D01ED659EBE9B4F730 -:10F18000AF09B2FAF1FB80878DA3A0A75DD8074530 -:10F19000E025365E01FE7DB9D637690EE57FF909B7 -:10F1A000D5BF8D7E573EDC5F4392D89D889285FD0A -:10F1B000AA18B0CA67E785E32AF085D2AB02BD95ED -:10F1C000B13E95D96D2657012E5795B133167B2E3A -:10F1D000DAEF8C9D699803F66380D9A7547CEDE63D -:10F1E000FD38CAC7FB88D04F12C900FA7B28FD0F33 -:10F1F0008DF17DAD47B5D02DF4ADDA9961C1E70B46 -:10F2000087B325BC6FA5778116457E2D007E91D4EE -:10F21000FCFAB6928DF52F1CFEDBF825DB11516F41 -:10F2200027F0B164345D04845BD0ADFE9FCFD74E30 -:10F230006E67A8BFD20DFA4AFA0FA8A08FB5AA81AF -:10F24000F6A5E26625E248B02FA29F0BB95E4DBD40 -:10F2500048D06E980304CB1D8E31FB9F8ACEA35BF2 -:10F260004DEC5FD645DF4E98571719C17CD09BAE49 -:10F27000C97F647AA69C43FD322FBED7FB55CAFFD7 -:10F28000535CEF0E6FADC3EBCB5B9B912F014371D2 -:10F290005D0F54CD64FA562DEC1A9F4F4E70FB71E2 -:10F2A0009CCF33AF6E0DE1F357B66EE47C65FD592C -:10F2B000C4FB1335AA0D18CF6E6711CEFB0B355367 -:10F2C0004BE65755C4AC7274CC47F18E0178EBA86D -:10F2D000713DCCC7D43F46BCC2EB19F92E5F6953D0 -:10F2E000E6C4EFCF0A5CC4CBFDCAFF2CF3EB6ECEB5 -:10F2F000C0F9A02216AA05BED63629C4097C9D3EB7 -:10F30000AB318B3EFF7C93759C457D3D39EF4E02C2 -:10F31000BE5704825A905E6BA3B7683E57EA71E805 -:10F32000D1828DD7E1F832FDA988F5D798948E2542 -:10F330009E8246F44787351BD8C3463ACFF5A35E75 -:10F340007890CF62FE3895A3D64500EF0DEECF0042 -:10F35000FABB3DEA64B86E87C981CA51ED458A4F50 -:10F36000E78CD1FEB046794E2BD2A2CC5FA3F5C07C -:10F37000B5C750F9F3208E470FAD179E77FDF5877F -:10F380008D737300F7ABC89F00F9DAA9EB60FEF24A -:10F39000DB91DF426F851C741B6C7EEC8959E7475B -:10F3A000C4B7F455CFE0F76F5E09F323B1235E12C3 -:10F3B000F8577C7FC4B87DEF0AD03BA2FA0919FD4B -:10F3C0007DF066D5A247E57EAB9ED5974EB2DCF7C1 -:10F3D0000CAEFBF15DD05E2C9DB517DE64A1F78805 -:10F3E000C1E6DF9E08C30762BE16EF0344D66FB9BD -:10F3F0003F8B4EF9C1CE50F9043B53FD49A951430F -:10F40000EBABC9513DA097C73CDBCE82BE7C10F868 -:10F41000F53760DEAD2BB1D2DF3138977DEF5591F6 -:10F42000BEF69CEBF1FEB0D72EFA6F2C037AE02FDC -:10F43000FAFE08E97F7536AD7755C44AD78A6086EB -:10F44000E57E73DD24896E6B5CA8FAE2068CEF2CF6 -:10F450002AEDDA914DEFCBC11415419CC961F92E0B -:10F46000E0B4DE97437C877EB78048CF2F2EC6B8A6 -:10F470004E39C475C473E0A764C7E93DD221E6796B -:10F48000593EC57C9D4A7EDB6D6423C443C8D0CA07 -:10F4900071E242DB93CEF744DBABC0F897739CD0AC -:10F4A0006E6FCB80E795E798FD2443D949F18D3CF9 -:10F4B000EF13F2359423C14FE209939CF9C8C7A416 -:10F4C000FD127C69A5C37209F00EC749F87112FDDF -:10F4D00096BF9F02FA4DFBB3B8E9408687CA5775BD -:10F4E000CC86F2D561EC41FD6CF7AB5C1FFB2F25A0 -:10F4F000CA674353D529880FD2F204F4B7C3B80BB7 -:10F50000F537781DD35FAADFA88F01AA8F897858B5 -:10F51000C8BF2CEF03247CF67A68977CF4DA2AC003 -:10F52000C10759BBB2DE53BD433D3E4FD4547A8E22 -:10F530007AD943F532593B97AFE73613DA3F7FD09C -:10F54000C570F7283D7FB56612B4E754587B9FB16C -:10F550009E1FE1FA23CBF7687D5F6480FD3F6FC893 -:10F56000FACEECDD62D7BBAFCE66C52D7AFF59E986 -:10F570007BA0789F0A5049E8F178FAFEB7EA794A09 -:10F58000FD9DA07ECBCFB7D814A62F29F433AEF7BC -:10F59000612CB7C3458A213ED6AEA4FBB717809E27 -:10F5A000B3788D5C3E5DE5F51267F80FB43F6BA94B -:10F5B00053964959BD99F4CF808156737DA8775BE6 -:10F5C0006CFD53E0FECF2436E55A15FC067208E2C6 -:10F5D000408A49C8BD9424C5E7216BA8A3D5A2865B -:10F5E0002ED968796520FA890203790FF101AEBB43 -:10F5F0005A09D954FADC41F963D0F2443B83788F3D -:10F6000022201CA7E55C09963B8D28C6CFCBEC8356 -:10F61000FD426ED05F5BE379EF5A5A2F892A97AE8D -:10F620008DF7F3297B24CF6F403F233FDA02F1A609 -:10F63000C774FF93BED1FDFCC426FC9FCBEBE7272C -:10F640005456909F36C6CFB02DDD0FF12CB97E53A6 -:10F65000BDECFACFA6D36B05F071CE683E2A839439 -:10F660007FC007ED3F2F81BF57E16572A5FE593777 -:10F6700021BE425467E4CA2474ACE774B4A8E66CB3 -:10F68000E0B75ADD86FC390CE36F00FF72C8371211 -:10F69000E4AB52D5B17F6A0369C67985446D6037A2 -:10F6A000C61B0FBB463415C6B1EF12DADB164E9FF0 -:10F6B000833E37E6A61E2FB5C11F8BD271227F660F -:10F6C000E37478A9552EBFC6E9FF32D0358F992152 -:10F6D000A8BFDCCBEC90FA27BD3992448E7708FEA8 -:10F6E000737EC9E50FDFC2FA2FCA7F87CBFD372FA4 -:10F6F0005FFE574F2D4A3D6E42DE95C1E3A9C6AF6E -:10F7000039D9FC364BB5713AC2CA44F4A15265727C -:10F71000A956D37183FED55AF9F86DCE8F55BCDE4C -:10F720002F2A6633C8C3D54AF06E15DAA9E943FD1E -:10F730002B847AE8F36B89790F3CA7EFBF01E5488A -:10F740009DF53D7DFE2D7CDED487EB4AE279976204 -:10F75000FE23FFEE9FB05ED3FA9ECAE156784EE5D7 -:10F7600085A873E1B90FE9A172429C602FF6DDFE16 -:10F7700005E02BFDFE7EAC9F9CB17C6F070391CD15 -:10F78000AECA5C767D1CE48EFB993B9A4CE4AB4E92 -:10F790009AB91FCCE6AD057CDE728202C33CECD187 -:10F7A000715ED4D2CC48945EB33D5113E278934855 -:10F7B0005F18FCA8D5D27CDBB4C63ABF7C61BD75AE -:10F7C0007E59B329CF72FFA57B8A2CF7A1FBAEB57A -:10F7D000D4B76EE7F596FBF5BB2A2CF71BF6565B04 -:10F7E000BEDFF8E306CBFB2F3FB1CA72BFE9E95B8E -:10F7F00093AE4B8AF9EE41DBDB9BC01FDB01AF12FE -:10F80000E60B2DBEEE686338CCFA1D153F9F361F00 -:10F81000CA110C29C872AA49EB96AF8FE8CFDD96C2 -:10F82000F9F668B820C74B596A166806C6DBC26687 -:10F83000DFCC29F1F9BCDA47E76337F8E1C9D757DC -:10F84000355EAE8AF457C3B8999AB59CC6D7590DA0 -:10F850007F0CE329F23AABE663F3B44CEF19D5958C -:10F86000037689D6EDC3F555237B42EBABE3F68FE8 -:10F870005AC209F58FB75705FD2C4ADDAF05A531F2 -:10F8800015C89B68BFE2745A718F58DF5EC68A92B2 -:10F89000F282273280DE653E86874829C3374EFADA -:10F8A0008FCDB38CFF0DBC7CF01E8F1DE2C8C11A3A -:10F8B0002B9D0D1C3F513DD4C04E94174BEF81CE74 -:10F8C000D950CE8A93BAB93CAA1A5FE79E4FE6E3B5 -:10F8D0003870BD5D21F4B696C5278827F9FA77FD03 -:10F8E000302D84819888256FE06471513A7CB7ACE3 -:10F8F00095F81C149F3C386F9B6711D5FF46D3EEDB -:10F90000AFA3A5ABFD2C1E5E6FAAB8CE7B4531BB65 -:10F910006FAC51224B287DF5A13E8CE735AE8F6C44 -:10F9200083EBB48D510DE990F8FAB82F926553E34B -:10F93000FCCDE3FCCA137CE57C14767CDA26EB383C -:10F9400036965AF9B59CF353E6F372CEC7E5121F0B -:10F9500045FCAC44E3F22CF17119C7A1CE794563A3 -:10F96000FA758FF33897901F4D9AD784FD1899DF59 -:10F97000B8FCB6801D079CE7E13885CF7B55331571 -:10F98000F4836ABD0AF2B776E63E4B7C73C9885CA5 -:10F99000323A6BF97897E7BF8A71CDCE1C3EEE9470 -:10F9A000AFB5F3E372D83093E563ECE4FDEEE038F5 -:10F9B000BA9DC72D5BBC67D4C4B857C78CBE7C3F0B -:10F9C000BD7FE942DF9AAF517A1AF3157F1DB41B50 -:10F9D000E271565EEFE1EBB6E5037D27CEF561DC23 -:10F9E000E7A59CA231E38802BFCBF250EE0FD6C050 -:10F9F0007CB224FA0B15FA5F1EA36C53002747351F -:10FA0000C05F8DDEBB358C73E5DFA541BCB1367FB1 -:10FA10005F35B41B20A1DD5510F7CAB1FBA33E88AA -:10FA2000FB8477BA419F4B985E6EA4FF12F552D0CB -:10FA30005D31D8AC019D4B7C92FFC2E5A8D62B3D31 -:10FA40009FB904E52820C9D13D420FAF245726CAEB -:10FA50008F8817E8E70AB91E26971F310EFFCEC719 -:10FA6000E1773C7EFC268F7FBEB1D587D75F6D2DB9 -:10FA7000C6E73D5BFD78FFFAD632BCFF358FCBBEC3 -:10FA80000A71568C930679BCB509EF7B79FC54C892 -:10FA9000E7037CBDA356EDC0F860833FE4F424ACDB -:10FAA0002B3470BA51A4015F9414255DBF75CC3816 -:10FAB00084FC3B3322FF04EDC0CAC682FD0F51BE59 -:10FAC00038BE434280171D477FA15D45E5BAA1AE10 -:10FAD000C0BE01DA0BB769D7D3FA1AA2BFD08AE049 -:10FAE00079E375F6DB93B42FDA49D5BE6CB756D5FA -:10FAF000A9921F2AD68F4261E8E7D458280AF40554 -:10FB0000BCBACF9104F777E56EF0825CB59C0B79B7 -:10FB100041AE5A72D93A032059901B9DCBA9281F98 -:10FB2000F05AD7D7754E77077D0EF476C4C65EF7C8 -:10FB3000167A20CA55686DAAC748DD3F397EB4538E -:10FB400049EE8F5ED46CF89D1BFA4FED37B5851AE0 -:10FB5000E8198828D03F958A0DE8976110B42F19CD -:10FB6000FE10B7B7D6F939AB2C18AC827239C4BFC6 -:10FB700004CC96D1EF05B951CB16BF0FF327294915 -:10FB8000B0C7E0CFC8FE7CE2BD8A262AECCA86ABAD -:10FB90005C8EF1D7E022D47A1DA3EF7B03D6F8AFB9 -:10FBA000C1F95BEE3BF11BB097DFF3DB58B91CB634 -:10FBB0004E7ABE6C1DE2AD728EF71D6437964F27EC -:10FBC0006D78DDC1F97DBEEC0C81F95BD5281ECEC8 -:10FBD000017A9C9130FDDE2DD96DCDB0F25BA13C58 -:10FBE0005903B87940B3F8114A19B3DF4EF0C3C1D5 -:10FBF0003FE1B824EEBF85C82560FE0471D24EBB3C -:10FC0000D5CF12D7DF6ACC0FB1D9A5FCB6FFEBF97F -:10FC100077FC33E59FF0FF46F0DBB13B09ACA788EA -:10FC2000FC3E51FE57521C49CF7FBBC64CC2F72A3F -:10FC30003BE3FB7576096F05E476D2C2C04F9DFAAF -:10FC40004969CAE87A52B54706E68E138FDAC6FCD0 -:10FC500044CDC3FAC7F373A8BBAD58FC0EA7E905A2 -:10FC6000BF6FD4F75E9B454F47D3CDF8F359D3BB55 -:10FC7000903A9A705D2EEC7019C3892B7C1427D2B0 -:10FC80003F57184C4E4F572991ED28A7A6C58FAA6C -:10FC90002B5BF23EDA25EA67E8F339FEA6F4B742B9 -:10FCA000BDB49E5772C57723F6C47669CEE87A82D2 -:10FCB000350CF790F0CF9726C60582545C8AE74250 -:10FCC000BDEC7B5AB4EB52323AB8DD0A96DDB5DCB6 -:10FCD00070C3BDA93C0A38AE24011F005F673AAC6F -:10FCE0007C96EC5FCD28BB67B5B78BA9FC1EA2ED57 -:10FCF000D4A9CD8D35B4FC923DEB0EBE88E408FF4F -:10FD0000C297B4DE53F0C78D80F6AC7885F8599E63 -:10FD10004575D887EB822B7214122900FAAD742C2A -:10FD2000CE97FCAB1CB91FBB711C8F6A741EA1E37C -:10FD300075948EE36EF47B93FB49C27F5B583084ED -:10FD40007E92F0E308F7E33CF45F221EABE4E5AB00 -:10FD5000EEF169B07E5025C58F2B47F28109FA4933 -:10FD60000B8995DE4AEECF554AFE9CD0F79F0ABD1F -:10FD700015FE2AB78737093FA93239BE10D70E2999 -:10FD8000BF8DE247B3ED32F4800055B4BD4632C2B8 -:10FD9000278B7C75155CD516A57CBDC99FC6F2AFB7 -:10FDA000299D9AB0E7C82786B797F3F237F974947C -:10FDB000FF804741FBDE384E3C2250C6D6555E36AA -:10FDC0001496371826AFE17A11A7A786FEEFDEB9A1 -:10FDD000D09E552EF27D7DD59939306F28FE0819B9 -:10FDE0002DAFB57C5CE1FBFBB2C14FA1BE7636AC5A -:10FDF00067C8F1883E0899527F9CFA4A05A3FDF92D -:10FE0000057C7CABFC04C47E943FBF808FEF8251A5 -:10FE1000FEBA1567BF1C7B07F3ACCE9728B82ED26D -:10FE200055F031FA09629D26CEBFE3E84F05CA3E80 -:10FE300062790323FE08AB6FB9A8AFEC18E617DEB2 -:10FE4000EF3986791CA74FB0F5EBD35ACC007F640D -:10FE5000A9C05794A35191FF5E007912ACBE28CF80 -:10FE60006778D9F96A06D84D9117D21948BE3EB7BE -:10FE70005065F16371CDD7198E2BD6D9FC23EEC511 -:10FE8000F88EC8937AAA94F97BDFB68CBB5C3F945A -:10FE90006FC2B85FB42438467E41A3C4678F6EC575 -:10FEA0001BE3E15AD14F990F723F47E98BCEE260D5 -:10FEB000ABEDE6747D72BC1D31DFC9E5573893E7C1 -:10FEC000CD549559E38E72DECC6A7BA804EAAFD696 -:10FED000949D993EB46BA84F472F1A8863CEC78E66 -:10FEE000EE8461ED196271CF4AA2F23C1AB311D6C9 -:10FEF000D3C43E871A1EA790E918AFFDCAA17EF4AD -:10FF0000B3AB866335207F3705BAD0AE2EA37675A6 -:10FF10005212BBBA581DDC3909F4D7AFA07D78F96D -:10FF2000ADBE9A494C9F313FD5AC2CD226811C786E -:10FF300092C7A116703949A577F4430D70C344F5F3 -:10FF40006EA53E82836EB85434FE38A59287F3B115 -:10FF5000F35F4B161F15D7EA14E3BB8548FCEDB0E1 -:10FF6000C695E57A449C87A81DF9A0CFC2FF95CB22 -:10FF70007D5B67F1FE9E597790FE04BF4ED803BDAE -:10FF8000ACCD80F8446FD9D8F3859CAF5645ACEB27 -:10FF9000CED54EEBBA73AB66FEA36EC1496B99BF6B -:10FFA0005AB616FDD5E5250EF457BB66DD81FEA9D0 -:10FFB000F0AB5B6E3C807117914725FC5399EEDEE8 -:10FFC000DC670C28371EDDC28FEF74B03C20F0DBFD -:10FFD0007DE8B7BF8DF94572F9430EC6AF2735F3FB -:10FFE0000740FF4EBBE95D0BEB87B31CFE27938CEC -:10FFF000C31B0EA6DFBD29D6514FC382C664EC07D2 -:020000021000EC -:10000000F2419E6F841F2BF60D4DF532BD6DE07EE3 -:100010006C45C95AD4C72C2FF55B816F7EE6B79229 -:1000200041AB9FBADCE8CB83F197E73B7588FBB522 -:1000300013F45B1F48637214F210A797BE4FD328C6 -:1000400034A5F3E82E75D173C08F07B208FA03A761 -:10005000B3F4C8FE24F18617B9BDAB553759E4ADEA -:1000600092E312BDA6DF8078C0E9A1B1F3F21E923F -:10007000707A6131A972B8E11AAB027ED07BD3816C -:10008000D718E64B7F77D686C264F5ED6FD592CE52 -:100090004B6FF1715BC9E7BBAC3A169FDC52A263B0 -:1000A000BC776ADDDBC7514E1BB99C2E7360BF7BEA -:1000B0006769382EBD3716B4C17A65EF2C27E6275D -:1000C00074CD7AE1ADBBC1AE96297CBFD9468BFC1D -:1000D00056525C9D0EF57B55C42B5BA8FF920EDF3C -:1000E0007BED0CBFF03C90CD7C4C4F1F64F8E64399 -:1000F000816F381F5709F96F14F1502B8EA2E6C497 -:10010000B24E43F8FAC312562DB5534C1F3E6C64E1 -:10011000F1CC2DA2FF870EEC043D6CE072D475612A -:100120008317F5F5D0018CA7B5CC5A8BF1A3AEDCC3 -:10013000B33ADC6FF6BEA7C3BD8C33C4386F297BDE -:100140001671482F1FE7CD1077A7F2BFC4CBF0552B -:1001500074CAB5769F11CF6396F1DDCA681AF67F2F -:10016000D5451BFA9D2BF9F747A6FC4987EFB64406 -:10017000A91E53FBDEA0F5CF00DC9221E1C50F9F45 -:100180003B900FFADD33FB8F58EE8AB2B75B80EEFF -:10019000696507308E9F77E8407736AD7F7931F11A -:1001A0009BBED1EDD7F2F9694B0EDB07B1C51F0934 -:1001B000C33EB00F8608CE4F0B9F3B56ADF892ADB5 -:1001C000B79804708858AFD1BC7CBD83AF3B908B8F -:1001D0009794C4F16AD0424EB0BF2D65AFBA81DEAC -:1001E000C283EA5A90EB9AE7AEFF22C81FB9D1E169 -:1001F000B992F6E703CFAFDD5719ECFD1DACBE0594 -:1002000021CA8F869203F91B668DB62B237A53F28F -:1002100097AD214AC7E9A52FE4035E7B95DA5B1F02 -:10022000B4C7ED95EC272D94E6D3C090B4CE24F559 -:10023000D7A5ADB8D1310FC6F347DE820479A2FA53 -:10024000BF0EE8DFFCA8D303FA9275E8155D05BB85 -:100250004671FB920479DECCE5A5C16076AF6516E8 -:10026000896C5740CEDE6BAC007D7B5165FB500E38 -:10027000BDCDF23EA579A197CF1742AE7B73DF715A -:1002800083DC7D7890EB47D8A624C6918CB2D8CD7C -:10029000301E823F1D929D0990E4F3C22907C3A935 -:1002A000951A7B6F50BB0DEBD4F27B13FC28C04139 -:1002B000DC9F12EFD73B18DE15D7CBC82BF8E177C0 -:1002C000A8BE77ED3AEABD1DED9381787DF3A103D9 -:1002D000C5B00633E5E0811A9EF78DFE98CAFB395A -:1002E00095F8D03E2D379CB87E20CBB7BD6C5F14FF -:1002F00060B3989FC111D7A6C4ED869A187F48E2D3 -:100300007F91B0F9DACC843C2C3AAF13B01FD55EA4 -:10031000167795E524ABECC04E361F50294C58C7D4 -:1003200095E5B6C10879617D9AEACDFB6C3D93CE27 -:10033000531097501BFD389E5C3E6DF41FCC7B190B -:100340007EAB7CDA8B750B4E91E978C4C1D7C5388A -:10035000EE17F37296B71FE95B6EB4E543FB53BD2E -:10036000FDE86751BB9E0F572167C24E8FC8DFACB7 -:100370001BEAC14E815CC392F7E9B2EBD3C1DE3513 -:1003800078193E21521CBDD73BB69FD12DC9E369D8 -:100390000FF3AB1ACA48BA2713F49DC59B7A1FCE38 -:1003A000DE9791108FDB630FFDAB6372FCDE5DF2B5 -:1003B000F97A8F1BEC0BCBC72AA766CB5E148F6331 -:1003C0008A78A958BF13F1D15171CC922ECCD7B2F3 -:1003D0008B3C0ABE9E372A8F6782F9678EED6D9A35 -:1003E0009FAF93200E6BE4F1B7A1B9E3C441B70905 -:1003F0005C76DC31797C5CF628F72BDF00E341AFDB -:10040000B7383C783520BF8492DA9B961CAF1DE04C -:10041000F8E572F4F3840ADFB176DE7458FD4AF130 -:100420003C8E83991E4C2D3BD09D88832B5B296F7E -:10043000E838E9AD6406C94C2D77CB47ECDEB3163E -:10044000F91AC1C5E3E061215F83AAF967C7BCD48B -:10045000E51A381DA9DEB7CC723441FE142D47A62B -:1004600066B2EBD5F4DA3DFB40BE8D3E3F09B82BBA -:10047000818EDEC70E613F5ED6D9FE97DE0B1B0A6A -:10048000611EEFD24CE29C3771F991F5C939CFF476 -:100490006DA3FAD799EFC4FD7E9D5E86375E81928B -:1004A00009F2B45E0F799C93718A304936377242F3 -:1004B000CEC168D64C6CFFD66D19FDF70413ECFA6B -:1004C0002E78958BE70660BF1ED4FB31BFE6365A07 -:1004D000BB83B673CC50A7ACA3F7454E66F78F85A8 -:1004E000ED16BE886B9193C9DD7A3D58047492B6BF -:1004F00066D4B3B58A1A04FD27FE89C5E576B4270C -:10050000CF132D8DD73F07EB3F48EB07DCE0E771BA -:1005100077E2999234CECEFB1D25A40EF4E57B59EB -:10052000563F739693E9D99C78FD1589F5CF7132C2 -:10053000F9A7CF17E0F3A7D9F35CFEBCAA88E5A919 -:10054000093E8A7A6BE3F5D5E27787D877939D7C6D -:10055000BD80D32DF0BD9CCF74431A1B8F2AA17789 -:100560009A8278BB9CE26FC4F7DABE6318BF73F25D -:10057000FD91690E7CDF916B477CDFF10941FCD96D -:10058000E962F1C8AE0B676FFD2ABDD78689251FCA -:10059000DCC165481B7A0AE36FE5F97C3F1BD7573E -:1005A000B16FEB486CBF655D55ECF3E974F23C0C40 -:1005B0005EDF025E1F9170BBE897C039ED7C9F4EF5 -:1005C000B9E8DF407407DA958128F6ABD2C3D68349 -:1005D000BBB2BE81FEF503179ABD8971C1AEE9C7F2 -:1005E000D9BEFD7C4A77499C2E8DE3B1F261DBA632 -:1005F00003C00F4DC18CEDAAE88B1905B4FF8B4EDB -:10060000A8FE34E8BFE4672CC9E779D41CE7A6C28A -:10061000F5BF54623F80FA6D19178B80FE2353FE9D -:1006200055053C5A1E7D43059C5EA9B1BCDD851273 -:10063000FE6887F33A809EBFDA2236DAAF9EF3EF88 -:10064000A9307F5C311CC17E4F1BEEC3BC89BC014D -:1006500016DF5D30534985EB7764421E868FED735C -:100660002DF7EFAEC9867A87F8BEE5D8F94940D7AD -:10067000685C6FC529015F15F67B04E7E7B3B8D264 -:10068000E5E2E94AEED708BF408C3FE503EEE36AB6 -:100690001FBEDB09F36315E76B61BE8DF907D30B52 -:1006A000D7A07FF089EE817CDF073C5F77A27F4097 -:1006B000DF837F5009FE4126C4E5FAF236B846F7DB -:1006C00047C853E1D0C75B43B4FC11FBEB79806BA7 -:1006D0008F5E782A0FECB2C80B17B85E9477695515 -:1006E000CF83BD16790802E73B04CE8F3513D8CFF0 -:1006F0005F396CB3E07C0797AB4A83E955FB5F0930 -:10070000AE7375BDFF5E6F01FDBEF34516879E1A81 -:10071000EB5713717E39E777E7277D78FE8890FFE6 -:10072000CEF7D939221DF97C7F0AC7F98B092BBF77 -:100730001870BEFBF271FEEC3466774C8EE317F353 -:100740007C54F1BE9FDB7119DFCBEF2F17DF138EC7 -:10075000DFE3B8D82AB75DBB0A713DA5DCE364FBD3 -:10076000CD0662CFDE45AF5362A127F600BF2FA6AC -:10077000FBE13307F7BFC6CDE794F0FE5412D79BD9 -:10078000287D9495DF8F7A5249F504F6938FD2072E -:1007900019FFE7C78E41F90584E955F57088AD8FDB -:1007A0008D83F72B8DFE3CC4FBC38BDF677EC3D8E4 -:1007B00078DF94F297EA663AC6F64FD3AC786C814C -:1007C00088770C37B378E47033C623170C717B79C4 -:1007D00081D94B319E0F70B913F65CE867E785B39A -:1007E0006A28C16E8EC8F730DB872BBEEFCC6778E6 -:1007F000FF275A1FEA73E7D0DCF4C438958CF73B27 -:1008000001EF97401C89E2FD39A0BF04ED5E27E0AF -:10081000FD04BDA578FF9AB404FCE61E5A5DEF8185 -:10082000F5E009E613083F7631F8B1D909F152A78E -:10083000D58F4D25DF67F9FC1DE7671F9B7F86FB82 -:100840008E25F253E3B8D60178724E7CFF7A672A80 -:10085000BE7E62DDC72CF2B53B8727E637515C5B75 -:100860009F363975B94A4E47AAF70F5CD011D702A7 -:100870001E9F3A875DAFA6D7EE8FFBF212712D3126 -:10088000181EEB7CEC37B83FB8338BE2D992443E6C -:100890006F1B077FB0FB055E3B5F87B1E20922CD8E -:1008A000FFED2E260747291EC1F848DAAF908F1DAD -:1008B0009F9CC5F6657C22F0888C4388843F04BDEC -:1008C000EDF98CEF476267BEEB877D7327C43E531B -:1008D0002B2E91F9353E1EE9437B2ECB7987CBC475 -:1008E000BCAB383ED1116F3C60677843E0138A3B64 -:1008F0008EAD05DC3140481A89D32F708AC01D6245 -:100900007E6C1FE6E72D79F8BC20E19411FBFF29EE -:10091000718AA847C629723D9D3CAFA39DE2966DA2 -:1009200088638EE33C3B51FC22E395F17049E54C32 -:10093000864BDAFDEC3C268167645C52E7EBC23CF7 -:1009400040815F268A5304CE91F18A4C5727E09765 -:1009500092387E91F18A2C4785F9642DC4F7058E73 -:1009600049A59F50EE0E771CDFA42A47ED33E29E87 -:1009700094F50CC52E17F7FC1AEC4A6ADCC3C6B90D -:10098000F222C13CA05478E4017F3F3B8F489A3764 -:100990008EE49F7913F7690EE83E157111B5934601 -:1009A0006A3C24F46EA4BF60074AE2F3524ABE0CCC -:1009B00070FDC81F7BFD65A27849CC17B3D3D87CE6 -:1009C000906A1D323D9DE1AA070B997F2CBF8FE7EE -:1009D00095587113C99985F2FD55BE2F39158E2290 -:1009E00024E66671A930B683F9E480C34037E7F3A3 -:1009F000BC024A6A70269909718D20BC8775AC7952 -:100A00004A244C495B01CFE9B856D5B075A033B341 -:100A1000D83913A7AB1C38AEA73E6479875D2E1674 -:100A2000573D7D5D9A7F3F25E143A897CEB767D2BA -:100A3000FA4A615CA78B7E66B37E2ECB886EC27548 -:100A4000F0EBAFB5850B46DB8707D3391DD906AE72 -:100A5000A735F0F814AC07E6CD1DBD1FA035BD00CD -:100A6000FB0DF9EF79B4DC4E5BDF770BE9A3341BA8 -:100A70005B3F95F9FADB7445E4EB841D097C689CC7 -:100A8000E934D3A83CA67D8EE50374D638709D2941 -:100A90000D96CC69BD0F1517BA92C987E897FCFC73 -:100AA00061DEEF33D363787EC6CB3C8F77B3A68409 -:100AB00081DF6880617E9A346DDF43B4E8D274765A -:100AC0006ECCCBCFBD8271A197B2381F4C05F31508 -:100AD0004EFB983E853D4604F655D2EFEDABC7D0B0 -:100AE000E7BEAA25C51C8F1105D6C9E08FC2D1FC6F -:100AF0005E55A762BF577976DD05F3C699BA5733BD -:100B0000E0DCC7E54336027AB7CA537E073CEF7292 -:100B10003139063E03FE5F55F3F9AFC0F3C646EB2D -:100B2000781C4C2F44FE56686C3C60FCF2E68E6EDE -:100B3000977848489F92C0FFC00BDF5412D62144DB -:100B40007E8A3345BE5EAA7E2B8976578DC719A74C -:100B500096EDDB0DFB5B82A5ECFCCB061F09C37A8F -:100B60006E839F440BB87C61DE4CF74CB6AF87EBCD -:100B70005756D9BED642884B0E696C9D599A5F2A4A -:100B8000E858E567439C9C8DCFE9792AE2910AC831 -:100B90006BC4F32B197E6F30D722FE6F7CB87B5766 -:100BA00021BC57F36BAB7C6C1DD492477588C5DDB7 -:100BB000564872EE92E2FA157E290F90E7EF75160D -:100BC0003FE101F979309BCBCF5C05F5E815C5F71E -:100BD0007061C23C7363BAF0CB88CF9E201F23F2B2 -:100BE000C0C757E67B2A7ECA7C92E542E6F7699742 -:100BF000C4AF14FC4FC5EF8AB2AABF2B7F3FB03BF6 -:100C0000EC20B75DF63FE6B37815B5C109F644E6CA -:100C1000DB0786CF0576E2CC108B87BD34DDF74548 -:100C20003C8F8AEA319E9FC9F5213E0E541FDC8914 -:100C3000FAFCFA0CD0672A6776A8A7D154CC34D036 -:100C4000BF830FDC85FD063D75C7F548E6FF28FD2F -:100C5000A3FFD304BD45A3F548CE0FFB5BF5EF4ED4 -:100C6000B0E7946F73D37D7815F6B49178BE98B8D9 -:100C70000F55AC937715B40461FF78C3808DC07CA9 -:100C8000D33EF48CB60EF6A5D62938AD19A40FE9DB -:100C9000355A59FEC3558FDF4B203FFDE1E9C40FA4 -:100CA000F6CA6865F910F43DE64308BC2ECE4DA4A3 -:100CB000EF4DE687B376EB79BB2EBF359F67E5E056 -:100CC000225C4FE82EE6F148EE37883C5622ED6371 -:100CD000698127B9F1FD1EAD1722E83FB4A7D8D727 -:100CE00022AEB21F205F7B8EFEEC2BE00754CED4E9 -:100CF0003D00292A87A24EA8EFBB2547EB105FD500 -:100D0000291E5867EBF9B86D07A172B4B2E49DA42F -:100D1000B8E4F0073FF4433F0EDB77FBB3C13E6C12 -:100D200067F356DAD525D3D78D817B427555750586 -:100D3000B353E78DDC9AC1E7F7AE3BF73F08EBD939 -:100D4000833AC643EB393E6ED07637ADA3E3D9BDC7 -:100D500054F16FA3CFBBAFD9D37C14E2C8EFEBC083 -:100D600071D27BE1A97CF0234E3EE66C82FA7B3E99 -:100D70007EEAC7983732A8CF87FE8ED07FA5C1DE26 -:100D80007FF8FC09B0332B8B5796423B691AD90D7B -:100D9000F274C550DB9B70AE41C3803E0FECCFCAEE -:100DA000BA7DCE7F003ED53DEBBC925EA70DF96AC1 -:100DB000613C33D243733228BD792505F7E7403BC8 -:100DC0007EE23791AF7D04F8BA528A3F5672B96914 -:100DD0005F5AE04A8C639C192A74617E421DCF4F92 -:100DE00058AA06C10F3EE3B9D28571C73A9697203B -:100DF000F36B25C7E92BEB0AA627C3E385757F4173 -:100E00001CDE7E8DA32919BF6FE2FC4EFBD386FD4D -:100E1000D0DFB41F393D00AFD352E45B6667F07C8E -:100E200052EFC4E22002CF50BE3AED0971108AF7AA -:100E30006FCE4888AF5C6EFBF519CC0E0CAAA12FC3 -:100E400001FF2B781C64BCF843F938EB6E548E908C -:100E50004F2B797C62A5884FD4174CB7C42788E9FB -:100E6000053B7B06D6DDC0CFD6566C013A7A3F6093 -:100E7000EB6EA9E477E5CCA76E3D9A60EF7AED269C -:100E8000EE97ECBE86F949FF55F23B226775CFB667 -:100E900096D2E70F95AC9C0CF62F418E5B613C2EF1 -:100EA000578E65FEB52F2D7211232ECF428E47CB64 -:100EB000A582FEA890EF54E301E5C01F5D398E3F87 -:100EC0007A66E9D549E53F5ECFB931F5A086CBD545 -:100ED0004D5CAE2A89E9C173A9F2DE44BFF557DC47 -:100EE0001E8FC889AB0FE341E1279DB83EDE7941F3 -:100EF000C7F3CD3B9FD8F8139837BA871679DEC36E -:100F000079BCCAB38AD2750DF80F25383EDD5A4236 -:100F1000BCFB8D0CB11E6ECDDFFD37CF1FB2ABD841 -:100F20003C6B54517ECFE1F3C4E70A9E4887F97CBD -:100F30000ECFA39FDDA1279D973984202539AFD8F7 -:100F400000FA971CB4963346F691B7D960DDEF737B -:100F50004F4BEFF9FE6739DFB13723F9BE6731DF59 -:100F60003A2F8C1D47FC39F7AB9FE6F9BCFFC6CF83 -:100F7000ED6BE3E7DC3E03FB56E9F520EC5BA5CF28 -:100F80009F877DABF4FE10DFB74AF227762EBB3881 -:100F90008749E77C68CD8D58D607C53EEDF652955A -:100FA0009D53E1D5F11C548A9B6C987FC2F1A22D10 -:100FB00023E0D4E9B8EAFF4130FFE4EBEFF7A13CCE -:100FC000ECE2F3AC8C633A243911573DCE470DE285 -:100FD000589DD3434DC1123E602037F3A6EE7B28C7 -:100FE000014FFF2F2E172DDC6F0B5F209127957877 -:100FF000F9972E90A71E421C45C22AE00EF88B8A54 -:1010000070FD00411C575FFA00FA5F80030197E111 -:10101000F96085101F7D1EF15CFDD0FC3BF8FAC124 -:10102000281C37C23715F9C4F079E92B1827A91FF6 -:10103000482E6FF1BCA5A6EE9909FB0C1A87C43A9D -:1010400005A5644A7C5FB92EC9955C4F56A982E319 -:10105000B2AC98EDFB12EB1C623C7734F7617E4733 -:101060006FA9C307F1051927CA385F2F65FBC2B402 -:101070001BD9FED4FA0B2CCF1005664AFCFC349D1C -:10108000E7EDB67B427E38AFA4C12FE1DE189BF7B7 -:101090002A8BAD785EC6FBFA802EE1FD309B0FB740 -:1010A000B3F13CFD21413FEAC9BD2C3E70D8EB6352 -:1010B000F24722E8F72CF4DAAE7BC807EB526CBF9C -:1010C00065F9103B6FB37CC087FBA7170E92E855FC -:1010D000B3213E4A5AF13C20897F0B095B7758E8DF -:1010E000F5754F86F8A34676C23930539C6B4DD0C8 -:1010F00003DDDB8CFB6BAA9D0A9E934DF8FA98E00A -:10110000AF9E7E6A07A8C0429ECF277E1762AAF3D1 -:1011100000CA813E4E5C56AC7FE95CEEC47A56153F -:10112000AFBF6A90E5B1C97290E53CF7269CA3BCBD -:1011300068C8C0753179DCE5715D64C4DE7D04E2A8 -:10114000F617D2FDDB619C9D6C9CC538EA6A870A64 -:10115000FB3588C6C64BAC7355CABF0F21ED8393D0 -:10116000E912E71F7CC590F685711CBF8853D79A9A -:1011700076C0B2BE22AF031CE6F9083FD1D839A22F -:101180008707C75EAF3ACCD7AB886782E70EF2F32A -:10119000022ACA483AE09C8A41C2E4EB615B2471AE -:1011A0007D4BDE27EE1E5C5D8FE7AB793C789E427F -:1011B00005A1D7523CE715F31B4D72C0B21E6772F2 -:1011C0007BAFF3B898AEB07E093EC9F4DD3664F566 -:1011D00087BE18B6EE6FB8F55EEB7E8C5B9AF32C8B -:1011E000EF976C2CB2BCAFF55D6BB9FFBCD77ACE74 -:1011F000CF7F0B59CFF959D5542D9D63673DE7E754 -:10120000A63AEB393F0DE6AD92FE9AD67507A58F4B -:10121000AF5FBC5534569C37617FE198E7FEA01F55 -:1012200098645F8BBC3FF1AC21E28D563DE80E57D0 -:10123000B17371067C7BABE8FD51E2D7D0C1E5E725 -:10124000FF887D7BB55EB69E337ABF1DA34BD84128 -:1012500079DF8F38B7AF62B00FE5A0523E9FCF9BCA -:10126000FC7CBE570C8E17C4391729CEB318357FB6 -:101270004FB47F7C1D6FDCFEF176CB49DF3138E760 -:101280002355FF26DAAF91BC2D383790F2A30F1EFD -:10129000E5B2F706D5B79D59C5789E85DDB92866B4 -:1012A0004C8EC73B8979FDC4F66DF3383E31578DBE -:1012B000539EE9BDDDE9637261327CB45331237022 -:1012C000CE5DFC3C0B827640E7F3A97CAE45DA4E5E -:1012D0006296501685179128E28D42676407AC83A9 -:1012E000E6B27DA32DD7D870FE693967EE86FC93F0 -:1012F000D66B34DCB758AB1A585ECF67F35300D6C1 -:10130000A0203FE2A4D964398FC3BBDD037AA2FFDA -:1013100098BD4FD59F8E5CB63E2C3F2F72313CD48A -:10132000A505F35C281FA697AD4744F0DC32916F0A -:101330009B2ACF9602470FDA6D22F0011BBFFB619B -:101340003D2589FEFA5D4CCF02254AC40E79A337AC -:1013500093887D0CBFB2C36B4B1ACFC875F1B8E848 -:10136000C54B781E9D2ECEC7CB63E7E37549E74E8C -:10137000E6F27E1E7039991C143CC5F6A34AE79428 -:10138000D7FB3690443C5BCEE7193DF60EC6994E2E -:101390000F8C8DC3C5FAD32EBE4FB9FA822D988C0F -:1013A000FEDFBB3496176CD893F66F3DA7B7638604 -:1013B000FFB5209583967FB6E1F9D2016FCB34DC7F -:1013C000C7EDFA07C2E25D8CFE7AAEA7016F640733 -:1013D000A1E31788BEF128FC3E875EE6C0F5E7D39F -:1013E000D7507C426568578CE2C58278FF5C7CBE32 -:1013F00009EC3D5A5754CACECD8778CF9201964713 -:10140000BEBC6C1F3F77A51FF725CABF0F525E17E2 -:1014100032615E5EDE18DD81F8C7EFABC2DF0B2103 -:10142000FE6D6CBD50DE3F6920EEEA186272DFF19E -:10143000537F17FEFE8657E046B3B1764AFC7CAF79 -:10144000CA734777C2128C7CBE977C8E90F0CB74A7 -:1014500009570A7FAC81448E69CAE838732A7FEC49 -:101460009F5C1C8F5C43FD313AFEB73958FE6CE03F -:101470003EA50C9CC6B4FB945CB05F2D7C9C5EAB1F -:101480000C615E404B8AFD747FE472FF5A6514F76D -:1014900029751484BCFE31CAE7BA542CAF5F64E7E7 -:1014A00078E84E96D73272E5795C42AE0BDD0E7667 -:1014B000AEA19BF9DB0B2F3D9D37D6FC591E0811C1 -:1014C000E80FB52F49F365F689F6A3EC3C0ABDF5A4 -:1014D0009D9A64FA2CF470BD1EFC890BF61D2ACD72 -:1014E0009134B403133F7F728EFAE9EDCD9F0CF374 -:1014F0001968FFA4FD5F7CA01F3B42D6DF7512D7A1 -:101500009346C889FCF71ECD007FF377E9A1C3603D -:10151000F720DE0DFB053B62CF38D19E4A7C97EB6E -:10152000B9CDCDC653F7B1F7E437A66F65429CE459 -:1015300006371B17BBD3EC81FA67DACDE340DF83B4 -:101540008B92AF43BAB44527A1DC7546F01494EBF7 -:1015500088EDC7F8F12769E64BF0BC54334FC375EB -:101560008FDD7C99D9E91ACF7BC5F17D0CA9C6190D -:10157000162EDE2B4EE4D7A7E3B3DD19EC87F6E990 -:101580003C18322E739CDDF45A07730BFDBEBF323C -:10159000F97A7B0B9727AA67989F25F6B904BCC4F4 -:1015A0004C367F89F274FCCF035D0FEAE120ECD763 -:1015B0003A3DCD46F627D839712E414B8CF985E757 -:1015C000EF51F633BF90E0FD4FEF2CD80FEBBB3758 -:1015D000CFE07ACCF759DC7E8F75DFB368F7CA4C61 -:1015E0006542FAF9CD4C260777673AF0BA2D93D1C8 -:1015F0003B61FDCC61F5083DD535765DEE61ED9F33 -:10160000E1F57FCCEFA91EE6B8991EF6BB2E6F7CE4 -:101610007EB8AAE8D3CB87D007DD6FCD33FD16D7D0 -:101620000761AF289DD7B8518E9A43E99747E79451 -:10163000F2CF408EC57E033543B1C4C303DC7EDEEA -:10164000E416B8C8AC7433FD5D00D731F477919BD4 -:10165000E96F8DDBAABFB56EA6BF8BDD4C7F97B857 -:101660003F85FE9E05FD81FC3C1EC727A7AC768703 -:10167000E2E255D07EBDA6F07DDBE40F4A82FF5149 -:101680003F1022269B2C9F48C40D14BF9AB85FE3DD -:10169000356B7D3D7CDEA276EC4B506F0FD7DF1DA6 -:1016A000BF65FC033E3E93442F051F55C75A2FE4E8 -:1016B000C5A79AE7026EB6BFBDCAC1F6539013B470 -:1016C000FD5996FE6C067E8DF4274C3DBBE4FD096A -:1016D00027ED4F9FB5BE84FEDC0BF58AFE2CBC7453 -:1016E0006A4C7D0C087DF4445598B7035AF279A1F1 -:1016F000DDCDE6CDDF67983BA17E59BEC475179757 -:10170000AF54FB5EBAB445BB80DFE51AB383C4882F -:10171000F6AB09FD2B2F5E2BFA1DB225C6D906921A -:10172000DBC947DD237AF728CADF5EB64F87CAF5E3 -:1017300063D0CE6D933CAB715FD747CC6E9EFDEB13 -:101740007D76F89D94A69C3DF7C3F5A49BE5BDACC2 -:101750003D57E88661E8AF64FB1D5B72D9F9682DDF -:101760008AF59CB4937C7ECCCD147EF5C4CF11C792 -:10177000B392FF4EF31BE54F07B74BFD69459767E3 -:1017800097E67D06EDDF3C83203E6ED9A7E33E035E -:10179000A137B7C1D8B2730D4CC8A3F812BDB7D1E9 -:1017A000FB7E70BA291DA17C42BC73B15C58C77323 -:1017B0000FCCD7983D327F0DE34BEDD0596E875E4D -:1017C000877B6A877EF369ECD0336EA637AD54868B -:1017D000FA400EB508DF8FC3FD11DED7F2E2639643 -:1017E000B89DF0A73A06F61B61C81B2C66FB4F5349 -:1017F000B52BF205C7FB3D82AA7F5EE70427600791 -:10180000C575104715BF5FD701ED1BD09EAD11F810 -:101810007A92A8B80E2FD7D7329DCFFB2E2ECFB9F4 -:101820001BD0BF927FBFAEDA1BD93597D613387164 -:101830003B3B2FE1E2ED64F52CC0272102E76AEA89 -:10184000F40AFBDA05DDAECCAB2CF1409D28DAE2E0 -:1018500092B81DA98E91E8C252C437B87F0BEAF145 -:10186000F17A42B360BECFC273564F1627CF4FD81E -:10187000A58672322727F041FADD0B3AFE93E13D4F -:101880001DFF2999F370FCA766B279C80BF7BFE179 -:10189000E3B84B0DE6C1F3500E5B82A6E5F379F990 -:1018A000E9999F819CEC20EC776F417E13D7ABF7D1 -:1018B00070FBF0B3C9A11268AFE6A72BBAA7D14F4E -:1018C00036B5ADC5738A175E11FBE865CA1F92A7CE -:1018D000E37A60CBC3D679E4071CFFFC3C53ACF73A -:1018E0005D1E8EA0F6EFC64CA48FD9BFB097FDBE8B -:1018F000E7DADCC2EF31F8481DCC29F1736A6B3CA2 -:101900002B6AE0F70ABFFC74C15C38D74AE7F67966 -:10191000B1B74B5F07E30ABFFF94C49E378ED8412F -:101920006ABD2DF354F2FCD42F65B2F993EAF1B2FB -:101930004CA6BFCB81CE7D93CD9B32E7FDFDECA3C2 -:10194000B043218DD91BEA3785C16F5A3DDCDC03DA -:10195000D35413D9530BEB1B542E3700BD5F701EAD -:10196000E8613F9D129E06ED5279BC83CBE3462E83 -:101970005F777279FCF2A7E9D76A687C5E6AFC2916 -:1019800070B8C0DFD4CE7F2B93E1649FFBB399374F -:1019900076F0FA42EECB9C376EF90CDAA778E3FBCF -:1019A000C0C7924C3226BE7D94CBD5639923F8F6FE -:1019B00031F86EA1D37C3C33116F949CF803E4C9D9 -:1019C000C5F14697CAF1869618CF0E50FCC5F3EACA -:1019D000D6DBE6C7F5448F25C7216599237ECACF9C -:1019E000D0AEEC6238A46C846EFF4004F4701AD759 -:1019F000F737983D5EABF7AF07FB7C3E8B7D1FCB87 -:101A000062E3F81CAFEF6DC59534BEF942E608EE0F -:101A10007901DBBB8FB5A7665CC77EB743D815BB22 -:101A200082ED88F87059B6B59D79D9360B4E95DBA5 -:101A3000E98EF7AB1BE5F81EB1EFD7EC81760371A9 -:101A4000BE4613F90AF6C5363F819F1CD7A5C27161 -:101A500009FC7B05FBD3CADA19E15F28B99DC5DF14 -:101A60003564B8F475A02F957CBCC5E5E37771F9B2 -:101A7000F81D978FDFC37737CF60E370DB24EB7EF1 -:101A8000F277F977F7723E89F192E9FF7A362B37D0 -:101A9000C20FDF892712716DA0386B7513C42D5BDF -:101AA00055BFCD375ADEE87F336D09F6581F88E001 -:101AB0003C510FF296C4EEFE25CEAFBFE0B8D43055 -:101AC0007E75A5F0E3EECC66FDBE257F5FCD646834 -:101AD0003F7CC9F27B2D5FD8D8A526FA09FF1BBE33 -:101AE0005F0B5400800000001F8B08000000000006 -:101AF000000BE57D0B6014D5D5F09D9DD9D94DB275 -:101B00009B4CDE1B48C224040D1A708110A304995B -:101B1000BC780688BC4445591E86F04A22624BAB0D -:101B2000FE2C2684A76DB43EB045BB2054AC682380 -:101B3000A64A31D00D08E2B3A1ADA2B58F2008A806 -:101B400008216A5DAB7EFCF79C7B273BB3D905D4AB -:101B5000B65FFBFFF1EB77B977EEDCC7799F73CF08 -:101B60009DBDFEC3E373350721E7E06F44B0AC4A87 -:101B7000B010924C48FD0CF741359F10AFCBE2DE20 -:101B80004A7AF65B1E2F63BF51D93E298EF67BE35E -:101B90002C5136D37E374C11345F1E21233B89E60E -:101BA000A3E37F192F103294104591B0FF1509ACB3 -:101BB0003E4AEE985B1966FEBEFCF9689568CD74E6 -:101BC0009CD10AD17684E977295FE7A8E8F0E38C15 -:101BD0008271E8F331848D13FA7C1C7F3EAA24FCC9 -:101BE000FB97C1F8741DD35DCF94271058CF26AB57 -:101BF00087F6CBB16AB90A6D5F53D2B128DC7B4E50 -:101C0000A9240F9E4751D059071372337DD742073D -:101C100098494B9996EB45CF6085CEEBA1E070D10A -:101C2000E7B45BAFCA01840C726843A0FD8B282D1A -:101C30001FCA7C491B0AE3DC6BD50AA04E889F9023 -:101C400002422610F637C1EEF08BB1F41F85D65351 -:101C50001D76D6762E1BFEFF0CE5F8E58408C42F12 -:101C60009CBB1CEA3E11C6BF5A3DF8B640FB5FADB7 -:101C7000BF77520A792F5D391EC3EB22AE0BE1B359 -:101C8000CBFA90EAB0F4DCA75EEE7278EC0087BF86 -:101C9000447BC6C33AEB5D9B1D2A85F72B9E66BB32 -:101CA0009BB61F8E2308C7BFC66813613FF5BB48AC -:101CB00075336D176384BA6603FCA6280C9F531511 -:101CC00086FF36499B0AFD47D8B56930EE944C8AA9 -:101CD000273AEECCC48EA546B8CFE474309DE3EB32 -:101CE0006699F50B5DE754DEAF4812BC31B026C7EC -:101CF000C163620A8507E9FECBB1D0FA58F8974A6A -:101D0000FB9D54A64D4FA2385B2DBA2DB42EE70A89 -:101D100048CFA1E32EE2EB9D2B572E82F512B54E54 -:101D2000AD7452FA90C3D3C731DEBF3C025D66F199 -:101D30007596C1F330EFA771FE284B6A13097DBF7A -:101D400088F35B68BF490922E36337191D6E9C7AEB -:101D500085D13F5D773DD297C2D69D63AD5C09FBCF -:101D600098A11C2A8FA7CDC5F7244D2349000F0B3E -:101D7000B165219CEC84C249E270A2CB24505F6221 -:101D80006775297A1189A365A6CBB76E20C0AFC14C -:101D9000EA5669FDBD93EF8984D2D9D6FBBB0442D4 -:101DA000E5C5AE4E4212B3601C1946843FCB39A143 -:101DB000E778F4992AE9F351D05C739268364ABF08 -:101DC000D714764E22B1A6F7C9393A9EA3B3DD2BBC -:101DD00000FEECC41B730592F11F735270541C2F4C -:101DE00095CE0BFB913F253ED88FE6F2549081842F -:101DF000C47776FCAC16DB1DEE51B82FE2007E0BEB -:101E0000EE7309F29FBE2ED9D1F1D88F69FFD6CFDC -:101E1000A2DD77C3BE3B477EC0D643BC4EE06BB16C -:101E2000C2EDC983F76CB83E0BFD0FF86C7880AE3D -:101E30003797AF1726C937AC9FF4DCCF7AB1F27968 -:101E4000C0C74C3BD16207A37CD809F5BE56DA81E6 -:101E5000C2B151117C5EDAAFF1FEB9ABB3405EAFF7 -:101E600097DCFD08D039D929503A1F46E75D46E591 -:101E70008E5C481C0AADCB2EB6FFC67B9236C508D9 -:101E8000F05C2233E8F3619DFE2F040A8758575512 -:101E90008542F721F3F7050A38785F501532633031 -:101EA000D06DBB48503EB8101E3AFF689712E1381B -:101EB0005D373C02FA2A9388D74EFB0B2E36EE355F -:101EC000A453247D010F5411D0B284B8B16C143DD9 -:101ED0006F02FDD9658A57BA7EBBC5EE5B2100FE55 -:101EE0002A5F1B8D702F538EE706E5592439049025 -:101EF0003BAEC355FCEE72AF7C6978BEFA30C83792 -:101F00001F32B94CF986CE33259BC99DFDCE8E1963 -:101F100046BE5FAA30B9B494F33D91189FCD95B5F4 -:101F2000B380C7487CBE8CBF9706CA07F89884E781 -:101F3000E39FC7B3F54CB9DBD7D88BC26F4282E0C1 -:101F4000063D5CBE7D96D45B0DF693B9BE3B97AC67 -:101F5000917894C3EE93BE24D03E32EAF7C677C898 -:101F600074187F16979F27F8B8EFC7B375C4703DF4 -:101F70007E44704E0F0717677CB71C74C2F8C4C349 -:101F8000E022C60CEAF4D379486F3E8F55C079DA67 -:101F9000B2997C8C4F30CF13CBE53895FBC9F12833 -:101FA000F77DE9D0EF152B5B5FE8BCE9C179D37110 -:101FB000DE456CDEB120E781FFD5832F829C2FE2C6 -:101FC000743AB6D343C0EE011EB61404E5BDACFAB4 -:101FD000C53ADA5E1441CEF70FCED31FE7A9637876 -:101FE000DC9EA25D06EBA476C1E550B6652B282FDA -:101FF000DFE865219B295FCE4ACBFE11884D7D9C91 -:102000004D7C9F6D598DAED9145F722771DB90CED8 -:10201000AB51EE1571F952BFCB43E0B9B7179599A3 -:1020200086F7E5CED976E2C0ADFCCF39BD3FF051A1 -:1020300067769C270C5EF472DD72268A88BA18DFF8 -:102040005BC2DF0BEDE778606F0C8CBF16FA5F4A5E -:10205000F996EB1BBA615CDF58CE3BF59D9B633A6A -:1020600068BF5DB9734CEBC1E7948F1A731F8B0186 -:102070007BA93583EA0190532F8B28271B9D0C8F5A -:102080008D6955C4638073A9CB2F1E8771BE9A4397 -:10209000A651FC15B93CE4126770DD45B9555E21C7 -:1020A00009DB9F8BA2E3CC89BF04E946CEF3909174 -:1020B0000E804B33A9A2FB9715BFE8A6656927F1EF -:1020C0008FC887FE54CE0B6C3CD5691C8734C3384F -:1020D000B29BD203BCD7E9C7F5EC3A797E383AF225 -:1020E0002C26F9ADF325B5EB6A802ECA946BCBE2B2 -:1020F000E9F80BB6670D16E9F8235D6DF2EC3C9438 -:10210000DBB5401F9B92B53AA49FFF257B6E3AF149 -:102110005901EFA332991E985023F83653F83486AC -:10212000D8098D9C4E2F0DDA37AB61FDA450B71343 -:10213000B435F1E7B783EF893FBF1DFC93F8F07624 -:10214000F0FDF1CC0E7E209ED9C10F4249EDE08713 -:10215000E2BF831D3C5C21BA1DEA43F8C7B37AFD98 -:102160009F983D1ABAFEF9F1CC0E5B4DF7DA0E746A -:1021700029F92446E78C4FAFE67C3AF624E597BC74 -:102180009EF4DF4AE9DF4BE9AF8BDA4D6256647AA1 -:10219000F25F245F163FC0F8BEDEB517F9EEB79CBC -:1021A0003F5BF9FCADB96205E0F315222AA2D073BA -:1021B000BCC60C8F0BE47A28FF695F99E9B9D4E5B6 -:1021C0005B3F18F8E6E01C372C2B941F655A560D20 -:1021D00008AEFBF79C0FBBE51311A49117C1873024 -:1021E0008E6700D819F112F05F3D61F37A0F8AA86B -:1021F0002722F111A59B77E30DF31503B00DEBA793 -:1022000074F367C02FE5B3BF7C177AF93EA70FEAD6 -:10221000871C87F192787D5604FFE2E3F86EBBE0FD -:10222000639C7706D343CE7895BD479264D02F9AAE -:10223000989109F2858E7B16C6DD1377FE710341F6 -:10224000BD1340BA5DC6C67D1E8CECE49EE38E4A8B -:10225000A0F6479871EC5C8EDF10C15F50B85D430B -:10226000F2BAED136B02FAED6C7D4F246BB684E489 -:1022700020DF1471BBE525C1AC9753B93E57B83F79 -:102280002726B0FE646EF7B80A8CA3C353B7036663 -:1022900071F9A08F93C4F92F2E4161EBAA66EF1359 -:1022A0005E1FC9FD270A97DEB82E3B7B7E21BFE863 -:1022B0002E85C52D2671BBAA1336C8F41BC27574B2 -:1022C00024BF2B68F7F507B81037EB9FC6E143DB57 -:1022D000F3B0BD82ADE352450D1B3F88841F1DFE48 -:1022E00052025F4F2E1B9F78BBE17625EC53A797D8 -:1022F0004870DB13C7E056A0C3AD818F13220FD601 -:1023000049CD7625CC3E47727AD5EB31B966F910C6 -:10231000299E9215D413E3111FF96CDD91E22BFD78 -:10232000F87E2FE378A0EF4D41F839D87AEF52BA12 -:10233000DBAFC3F67436DECC60FB0D388F8BF58FC8 -:10234000E4F7CFE4EB9A9AD08DA759385E127B2F31 -:10235000349EA09737F2F54D0FAEAF1ADFCB61EF89 -:102360004941BC2FC4F6D1ACFDFAF44D65C92AE051 -:102370008D8E037AC2C5F4C10DD56DA2D1DEB93EF2 -:1023800042FC4DE2F35605D7FB7DDCA7C6F67F2263 -:10239000AEBBFD87386F119B3792FC3811C7C6BBA7 -:1023A0009DEFE31AF08BE918F101922B2581D714E8 -:1023B000ED1E45BBA406343FE88F924F6515E474CB -:1023C000B9E8F00A541E4BAA1DFDE4288968E0D73D -:1023D000B67DF63D57471ED6FDA0D7574515DBC144 -:1023E000EF5C9D25B9411F16DF2B31FFFA9405E5FF -:1023F000FD4871118EB357D1EDDC5B4D7EB4AAA8B8 -:102400001551B00EBB4854E6FF578CA7CF477079E3 -:10241000BDD79E6881F18665B078C108B50AFD75A3 -:10242000F215F3A335FA1F93DF1AEA6599BF27A5C2 -:10243000D711014BB3BF2D93F567C581A817D08E77 -:102440001AD669F6BF6575E409185F2686F7E8BCF9 -:10245000DB129C49684FE5907EE728FFD872056241 -:10246000BB02FC6CCF76C0CF18B54A29A1FBB1A541 -:102470007BEC208773ACFEDE104F684897DD5E6012 -:10248000C3FBCBEC59E06F3551FF1CE1A0255C3B51 -:102490002088275B9146800E294E90BFBA4B072BB0 -:1024A000854486C7B7136C580EE275FD7928DEB3F4 -:1024B00013A319FF13BBF7582EC80981C4513A5C06 -:1024C0004C3A32811EC534C6E735968E14A89F213A -:1024D0009D2949B4AC6F924687F37FD6F1B8D41AE0 -:1024E0004B787BE95EEB9857010E12C40DAEC0B875 -:1024F00080C7D637183FD0ED553D8E10C96E6D148C -:102500002BDF04BA1614FF17D0BFA7FDEB65FB4EF7 -:1025100067725A2FF5758C4F64FC6E4BB463BF3DE8 -:10252000779692D92AE2E908C7D3C12B012A5973B9 -:1025300015C0D3CB590FE6405CCA9E757F12F0E7F9 -:1025400068C2ECD372FA8E8B962B1D9E9309067B84 -:10255000634CCE2CB49B8A32EBD09E5A15C12FBD52 -:1025600085AF43E27432C8E1390BFBDA7AFF123BE4 -:10257000BC2F2995D150EE094CC292DABD9FC0F311 -:1025800055E9AC7E213CBCC4F939D2FA47815E8062 -:10259000784D7AF73E84C4647CEE950707F761585E -:1025A0009F3531CCFA3EE5FA485F9794C3E932D7BC -:1025B0004C77457CBFA989BABF78D174F7D6C5D00E -:1025C0005DE87EC7642D1DDD9F04D7AFEF57DF3F69 -:1025D000DD6F1FD86FB9C4F6BF55F168300485B3FD -:1025E0000AFBECB12F7B78BDEF48B47CD3FD3C985F -:1025F000D0F7E2F7F30DC69D96F80DE0B47FB8E68C -:102600000279D2904CE993E2A94160A5DEFF0B6EFE -:10261000A7FDFC9BE32BA5DF37D85FB14B7811F406 -:10262000E108CF9152D86E59D120503BC08F930111 -:102630000F2579F74AB369BDF1CE39283FF70FAFBF -:10264000C375AF729AD7AB9742228FE3676AC87F90 -:102650000D9CFFCA09F323F57E4F72F918CA1FA11A -:10266000E385F2F54A873617D62524323D1BF4FF61 -:10267000DA45A3FF57C2F5D770FB6DA6F8C770EE19 -:10268000FFADFA34DBE1A51BEDA27AED9FE2FF7D01 -:10269000419F809F945E6237FA7F0DF6526C5F9582 -:1026A000A18DBE2209F4B1E8BE9B20FCD01FF40A24 -:1026B000A2B2358C3FB82A43F68FA0CF6D0AF90538 -:1026C000ACAF94EA4B88BFD8148D5C32A0A75FB83A -:1026D000D75E4A206ED2A590E7C01FBBD07E1E48B1 -:1026E000BCC464474AE017F2F1D12F54EA4807C648 -:1026F0007B4A09D835D0AEA25DA5118F13F408F539 -:102700000B0DF2A9CB7E1BF27BE87C546E3D027C64 -:10271000DEA0303E0EF507BB389FEB7236941ECA22 -:102720005D8C6EA2E8D2AD4C6EFC2271684FBAF897 -:10273000E6F2696E19B800D79115FBC1559B1AE8EE -:1027400094C0E59993C8F8A9D2F14C033CD7C70FC0 -:10275000C50FDDB906F174B06758FC86DA6BD48E0C -:10276000B2527B6DAD109C7F0DA78348F888A4AF53 -:10277000F775CBB5D038D16DE6F317C54B920A5833 -:102780005C9F8481BFC8EDA4D5945FE0FC668DD5C5 -:10279000ED02BFA2BE5FD1DB1EA0BF7E32B377A425 -:1027A00026D7B561FC90B511E2DAEF2526203CA3CF -:1027B000732C26FB8C7A0626FB31D2BE095F9795D7 -:1027C000EF4B0078E61AE119B2EF3205F70D663DDE -:1027D0008C1B6B71133FE58BD84CE24681156BC1A6 -:1027E00038ACCEE70AE7735D1E3814F6DEB0A4BE3F -:1027F000EC7C4F74748A145FEB92A83D4DC7A9D747 -:10280000F6A25ED5DF8FE3FB770C67F14687D3AF87 -:102810002861E4DD8F2F80DF264D8A2FA3EBFBB1EB -:10282000C2EC6F69B8A5D287F12816AF5538ECC451 -:10283000E27C3BD8ED05E0780F85F5EC508C712BF0 -:1028400091AF27C649D7731E39B98AF3B75EB7A9C6 -:102850001D65B07E294B53E20DEB1F94A4EB9576DA -:10286000E4EF48E3DDC3E5BC2DDD4DAAE8BC768787 -:10287000DB0FE75A36ADAA00FC05BBEA26730CED68 -:1028800076AD6088CD80F7A67EF2F4707CB92089A1 -:10289000C97FA7A455C27B4E4522704EE6E4F6726E -:1028A000A47123ADE342F38D8A349F1ADEAE884DC6 -:1028B00062FC270DDF5109729A0C9048BF307A42B2 -:1028C000E0FD62E50E15F88AD2A327DC7867126571 -:1028D0000EEF7F117FE8767771CBC16CBADE7A8715 -:1028E000E416407E159E6C570D7281EAF509490683 -:1028F0007B59747850BE892A3B771F6D63FEF6FEC4 -:10290000E1E673B2299C5E5EE56524B97079928533 -:10291000DB4DFF9A7D7E53FC0D4A2226B834015CC4 -:1029200008F0D77D0DF561E42585CF926F039F6593 -:102930009CBE1EB9007C32FECDF0B9105F07F9CC09 -:102940004B8E86916FF54E396D8E89FFA91D12A1B0 -:102950005F95A13D121FEAF4310AF002FCD0A49960 -:10296000E2027292B79DF995B79BF59CB8C8CDE588 -:1029700033F9AA808539E12FDE41FC31B1C1F1E59F -:1029800032733CE1C9241E17882251009F2EF72480 -:1029900001F214A22C3306410834853409A02752D1 -:1029A000609C81D44FE6F23C540F266BCC4FEE4D29 -:1029B000EA04A657D2717D497C1DA17A308DFA3583 -:1029C000108F0154833FDD5B82182F3CD5F01C5CD7 -:1029D000F05AD05F76119F00E3A7930E2CFB402A9C -:1029E000021D3F8BB40B39147FF796570D02F9FD8A -:1029F00062C83E2E648FEAA56E7F2CFB37C1FB9D1B -:102A0000FF5E78AF2835C0BBEB3BC27B0A973BA18A -:102A1000F1BC31DDF1BCA617310EF715B33FDABEBC -:102A20009631BED790C5E279E562C506B0E7C7A882 -:102A30003201FD26E576AC833C27DDEE049704E207 -:102A40005C7ADCCFDE6F4EE560782E9D4438E1D9AC -:102A5000908AF2CC998CF286D91123F8FAC7A8553E -:102A6000F62CD5E83F3599CECF644E07635C25E858 -:102A70003F357C757EBBE362FDA43DD2030EB06B97 -:102A800074FFA83E670EDA3DA1EFF9A5A63F435CAF -:102A9000D29F6353575078BCCCE5D5CBFD1E928CAA -:102AA000E7BFA17E906E578DE0EB2FCD997510FC9E -:102AB000AE31CA6C06130E0799CFD3E0EAC273F0A9 -:102AC000DF7E65417FAB8BFB5B63B89F05FE4E9558 -:102AD000B3E73E87279BCFD574FF694CB7FFD4245B -:102AE00019FDA73111FCA7D1B6CE57AF80BC9057C6 -:102AF00045CC0B8904DF50BF2954FF8C4E667A67A2 -:102B000076323F270A81A71EEF0B3D976ED4F94F0F -:102B1000F20A46FE0F9D5FDE3B06CF05896288C73D -:102B20006607E38982E625CB0607E38761E2863301 -:102B3000920D71435D8FE9746CA37DED78CE1C3EE0 -:102B40009ED89A75A02FF30B5F4C04FC972B2C6E2C -:102B5000A4AF8FFA85F3930D7E615127D3DBB6FFC7 -:102B600053D7B182C297241037F30FEA547B3EBA91 -:102B700013896B591C1DF3B4C638048C874BFE288F -:102B8000AC979D72FBA268DDB6F76109FC84524ADE -:102B90003F5142907EC670FFA221E7E83AA0AFAE57 -:102BA0005392FB7C7E7799430CA1D3E8601DE55BD3 -:102BB00082A9BE5AF2AC647CDB2B086F11F2C1B261 -:102BC0004DF9675B25AD11F63DCAAEAD4AFECFC4E7 -:102BD000FBCF605D8272E05BE13D380FD30760B3ED -:102BE0009134C37C0EDA7815CCA322FD77C7A59764 -:102BF000123C8FD90638033FF763E28338CB0BD6FC -:102C00009744D0478D7C9CAB49932AF765EB857E32 -:102C10004F6C756D5A0BF238390BC77BC1E1590FF8 -:102C200036E4C12DD22088DBD4ABCFDA217F76EF1A -:102C3000D6C6F40E03FF1D7CC2D3279C7FA897F451 -:102C40002FCE5288FB8A65A5265A5CD82E42BD87B6 -:102C50007DB6A54581799ED86A0F6B4775713EBFD9 -:102C60007A0BB36B47E75ADC1402A48878A50438C2 -:102C70008F7113B79F36C40CD8D15E02BA284B446B -:102C80003F9FD6F7C5D27ACC500DFD83FE0376E088 -:102C9000FBFD3F2E71B33C4AAF6330ADAFCB2D1976 -:102CA000BA16FA477BDE04FC513DD324A13E6D8E5B -:102CB000813C8098019392A98D4B620452192E0E8B -:102CC000F84132B3F39EB0EA7095300F72EF5619A7 -:102CD000F9EB609A88FC46E1B608EA7F4F8B2194B5 -:102CE000124999E62D03389693E67AF0A7CAD46B79 -:102CF0005F8C25DF027EF93B14E0FF756087875902 -:102D00005F1B5F1F0A114A3F07B634DC40C2E45123 -:102D1000EB74F88B18ED1380C31A7EAE4B5C939066 -:102D20007E22E3FB6EA41F67B3BF3E9AC2F1EAEDB9 -:102D30004DBD8CE3EF4F564DF1371DDF90FF4CAE8C -:102D400080FC5B0FE6D3D69FB420FC5EC9137C02E7 -:102D500085CF815C91DA6C745539765F3F5A5FCFCD -:102D6000E9B862FBA1865E00A494245CEF2BB98FC6 -:102D7000D9597EEBC5C7AF87503E5800E7C9141F2D -:102D8000A394689F4AF1B51086C887FC1CBBCF4F3F -:102D9000E76B73B697C6D1295E4816DC9B815E72DD -:102DA0008902F2035D100B439442EB2032909E9215 -:102DB00008E673AD2BC8DB0CF2766DBADA0CF98637 -:102DC000BB07D831DF2C349F78B750F7623CE499C9 -:102DD000C40B28AF0FE4FE1ECFE90EA4DB08D02BF6 -:102DE00026FCD2E70D098C4F63F2CDF6677E4A16BA -:102DF000F7B389D756105C574C8E5D8BA284F45282 -:102E00003C7BFF608EE0037A3BA872F940F7BB156C -:102E10001201A91D346D4064BCBEDC6F94AADBC5F1 -:102E200082BE4F4BCF7DBC20F85667C33EFAD37DA0 -:102E3000D0BA3357C0F99DCADA5B099685F3E01C16 -:102E40003374FD35298C2E654A76B920DF9A578F69 -:102E500031E6C7C885B74E70C4621E13DA95A9B9AA -:102E600002D35F27D9796E8FFC6C857864137EA8B6 -:102E7000D591121C2FE6D3E7BE0FF9BFE30A057FF9 -:102E800014AC87E737D3FF6B03FD22E7CC62F9D799 -:102E9000B99B703F630BAD6E38CB19EBF03595D015 -:102EA000FACB1F4818CF1E97330AF3AB43E75FAB4B -:102EB00010FF680ADF97F3248477D4258FE1386FF9 -:102EC000E45950DE8C837C6CC85F36E655A33E34F3 -:102ED000E7738F13FFAC1543B39BF12B91BCBD403F -:102EE000BE4F7099E1E73C693E2FAEC8B799EAE35F -:102EF000F2E49078A597C58733185DBCD45FF06D78 -:102F0000CE0AD2D9D893093EA033F8130B4C7034B3 -:102F1000ED33A653D6007E07FB3FFE1338278951B9 -:102F200057DD8AE7E01CFE3A9DC470BC3BD39FFF8F -:102F30003EE8291DFEA17470F1F8BFB6B218F09FEB -:102F4000AF9FDF87E03F04DF1883D4F7D1B727DED8 -:102F500071FEAC9EF8D6E9A0C7BEEF69599D4DF150 -:102F6000FA8A933E003C6F927D770B413C5D10AF37 -:102F700039C548376B952607C8FDA84B8E3AC0DF88 -:102F8000D0E98288ADF946BFE39F85EF92F50273E1 -:102F900026DD820FE27ABF83475705E77936A53BE6 -:102FA0009FE8D914D013952C8FA35E1BCCEE5DE562 -:102FB000337DDA433EA4B07B1D6DD697D2CF97A761 -:102FC0005AE1F010381FAB877C3BBA3F79FD2CB833 -:102FD000D140E429B3505E92F5028BCB17FD01E599 -:102FE000FB5C976FA510663EB464709D2A937B4589 -:102FF00089D89F4CD7F3922A5FC5F54F61F58B5D59 -:10300000D7EBFFA4751DA0B4420CFEE7446E37EB6E -:1030100076F70407CB3B9C5024223EDED822F830C2 -:103020003F92F6F3523A59C0C97622B703BB0A9FC2 -:103030006D1CA4823DA899EC4EA1A80DEDBEB8422E -:10304000B33F18AF459BF09F383AC1544FAEEC6583 -:10305000EA9F3A3DDB1C57F05C667ADEBB7AB0A98A -:103060009E5177B5A97F9F6525A67A9677ACA97FF3 -:10307000DFD5934CF57E4D3798FA5FBA61B6E979A2 -:103080007FDF02D3F3CBB72D31D50734FFD0D4FF88 -:103090008A9D779B9E0FF2AF353D1F72F03E537DA8 -:1030A00068FB4F4DFDAF7C7BB3E9F9551DBF343D47 -:1030B0001F767287A93EBC7397A9FF88C05E53BD77 -:1030C00098BC6AEA5F6AFF83A95EAEBC6BEA3FCA3E -:1030D00075D4F47C8CFA91E9B94E07E3723F31B5AF -:1030E0008F777F19724FA712E59B0CF180BEF0A875 -:1030F00009CB68D2CCCE75483B962F1578DCA94019 -:103100009F8F7A1B2121A9DEDBF957389A7EA3B065 -:103110006F1CB39F3462949F7A7E2AF55BBC5194F6 -:10312000146203946E8750BA0B08582A012A591367 -:1031300021DE138565422011DB1303F15826057A41 -:10314000637B72200DCB94405F2C53035958BA0215 -:1031500097639916E88F65AFC0107CAF77601096C3 -:10316000E98161D89E11B80ACBCC4029B6F7091481 -:1031700063A906C6619915188365766032F6EB1B64 -:10318000B816CB9CC08DD8DE2F703D969704E660B4 -:103190007969601696B9818558F60FCCC7F2B2C02E -:1031A0006DF8DEE5815BB1CC0BDC81ED03023FC045 -:1031B0007260A01ECB2B022BB07407D661BF418179 -:1031C00035580E0EFC04DB8704EEC5323FF0336C3D -:1031D0001F1A7818CB82C063585E19D8846561E0E5 -:1031E000492CAF0A3C81E5D58167F1BD618167B0AB -:1031F0002C0ABC80EDC303BFC1F29AC03E6C1F1104 -:1032000068C3520BBC8AEDC58197B12C09FC01DB68 -:103210004B0387B02C0BBC8BEDE58177B01C1938C4 -:103220008AE5A8C0112C47073EC2724CE0032CC7A8 -:10323000063EC1F7C605CE625911F812DBC707BEBC -:10324000C0B25BDE45CC57F658D09FE57E6A647FFE -:10325000C18B72D2CAEFC5416E35E6FFD709BE51A8 -:10326000943452933A305E682DB461BCF026D26932 -:1032700065E7D0ED4ED04B6D579D488738DA1BC9B6 -:10328000FE0C63BE8395C701CAC553188F9A90B4CC -:103290003719F4E94DB419F28C88760EF32027F033 -:1032A0003CC89B24EA60D1A51E8211AEC27E7E1B63 -:1032B000ADCFA820DA60DABFF12A1BDE2F6A1C4CE2 -:1032C000FD205ADE93C5F2657DA94C5F3ECCCBC78D -:1032D00053D9F9CB5F0B589EEB8C5BFB317E2A4BAD -:1032E000BC80DFC4E0307420CF8F757466627EECE2 -:1032F00045BEF7A714FE1EEFBF3CB5F2C954BA0E87 -:103300006F09C9AD7304FBD1F6A723B43F03F220C4 -:10331000B47DAF85E1C3FB96C8FD84CAB849E7F127 -:1033200013DE58DE7ED98BFD82F5DF45F043095967 -:10333000C1CE0FF77E50711DD587130B4537951CF5 -:10334000E4CFCB770E3FD68FCD0B71506F8988F1CC -:103350008B194587F627D2FA8CA5F19877DFBDAE99 -:10336000122B3E9FE07AEBB217E9D66FAAFBCDF0A5 -:1033700063A6789307EDAEDB388D12CDFA8F0EFD84 -:1033800039D22B8BFBDE0693AB20FFAC386EBB66CD -:10339000F59D2F3F866836A299E89EC16B1DAC1F34 -:1033A0007C7F62B7C0BCB1BC0F852BEA7D6FACECF3 -:1033B000AB17C07957E380EE62F23AC9F9E2CB006D -:1033C0004F092E4E920E07D83191E029B8581C347F -:1033D000AE487379297E1ABE16316EBC2FBE4001ED -:1033E000FAFF91232715F843E2FD1ADADEC1F856F9 -:1033F0005C7E27F13A58FC5EB5C139BA1DCB95CB3E -:10340000DD58362C2FC4726DFA7D76889788C9985E -:10341000094CA232E6623C489FDF1A3FDB5EEC2695 -:10342000E4CB87BE1E07212411E20CD444F89AD6BF -:1034300057509FE2642AA3CF375CC71CC00F2753A5 -:103440005596876F61E7C631F97E0DE28D316EA525 -:10345000445283EDF89784ED9BC11F798374AC9F30 -:103460000C70D4D87D8C7A7EDFB4BEB81F87ABFEDB -:103470005E08DE43F02CCA6E3CB716A369FFBCC8D9 -:103480007875B9585E02D09744E9EB6FB06EB037EB -:10349000B5180B8CA7E3B74BEAC47CAA7A217CDE73 -:1034A00065B68BC987064553CE778E4214E91F4611 -:1034B00079EAC8DB1942CF0E94AF58877C2E2EAF25 -:1034C00076A46AB92E3A7EF3355C0EA427A01CA020 -:1034D000EDF75D4DD7BBD3C2FC146F828CFC4281EB -:1034E0001087792F76356ED279F220562D5734C950 -:1034F0000AE7036A1CC06B15CFD7831BCA4639F095 -:10350000AFEA1794173E961719D27FA785F3557423 -:1035100014EE4BE4F0D0DF9BEE62F2F8C1ACCAF1DE -:103520002E8C8FA8E92057697D22C08BEE3F1DF8B5 -:103530008AD6AFC5BAD25D9F8CFD5DAC3F26D25C0A -:10354000841CA6EFDD80EF49DDE3CCC0BAA37BDEAF -:103550009B719EA4EEBA079FA7B3FE173B8F5E76C2 -:10356000EFFFF74C4E7E2A697109143E95CBE65465 -:103570009651BD3D79D97C2CDF5BDEAE815C3D4E42 -:10358000E54903856B6571DF24F073268FEFEB50FF -:103590000DF43A8FC735F7AEB68E067D57B246ACFE -:1035A000DC82FCB4C214B7FBBECBCAE34D6C1D5524 -:1035B00094C7EFA424376FC3A1CB1A0CF6E86CE2D2 -:1035C0009681DEE7ACB606E99A18F853616D3B2D9B -:1035D0009E1F5D0FFB582BF2F30ACEAFF184FBF375 -:1035E0006A4AE579F40E596D239E30F2B8277C08BB -:1035F000F907E5834F1D391897A5969A3DDCB83A2F -:103600009C22CD372F42FC5787930E6FBDFDE8FA01 -:10361000210AB3AB7D2638CEB96728C62BE7F178EF -:103620003D89B773FE64FDAAE83C3BE03D49538108 -:10363000DEA11E4EBEE8F356D17FDD39381C7C3941 -:103640001CD65A991E0F81EFF10DFD62410F85E2E4 -:10365000EF62E15C6B23789FA273AB93C59192A656 -:10366000E3F8D57C7E923403D753CDE77B714F8C42 -:10367000DF42FB976C756E063FF84C89F7C14A90A4 -:103680004F9BAD98CF76F79E756FFD0CEE7D6CB2BB -:10369000E299C9FC98070AE0FCF42F5C8E5205D031 -:1036A00006DF4FF010FD4F1360FC79848D7F463F9D -:1036B000FFD81A87F03C59B6A571182D3B762FAE6E -:1036C00080B8CB893DE30F80DF3C3F9A4878979DD7 -:1036D0002832F29FD77ACC6C1F48C1BAD8B33E0FBC -:1036E000EA86F8D17C9FF59891CE176E33D78DF08E -:1036F000B218E1A59699E1A5969BE025FCD6E917BD -:103700000DF02A8BEA97047A7DBF4BC5F1AAA35628 -:10371000A6007CAA77AFC172E1B628EF31C3BC8B9B -:103720009BE34DF5DA9D695EA35EE93AF8582CD02B -:10373000E11297E83D46F5DCA9E55A3DD831A79757 -:103740008FC652C7FFE2E62CAFC3348EB9DED52454 -:103750008C66F2598D9B721E7E5DE292719E0FB750 -:10376000317FF3C3E5762FCC736AB9E265F3BABC57 -:10377000CC8E62F05AB42CC67B6C48707D91C6FD2D -:1037800067AF8F901672D44EF0CECEB9F3E8ED88C5 -:103790007249FA5446FDD16AFD3BD08D9DFEEF1C67 -:1037A000C65125ACEBE3D6368B5EC8272664BB69D1 -:1037B0003EFA9E7ADCC06F91F582F93B13FD21162B -:1037C00086F2999D8378E01C848E774672AC8638A9 -:1037D000827E0E520B13D1BE8BED1DB287367DDC7F -:1037E000D2F7BCF7CC299EB2402F57DB9B6450B672 -:1037F000D5CDFDCB809F3E6EA94F01F9B150ECFABB -:103800005EB8FB5EA5699C6F7DD64EB3BFE8D3D78B -:10381000992599F88C38BAF74DEBA722E40B8F4F16 -:1038200063F66CCDF6432387D1F5D7EC3C2B63DEF2 -:103830005A9A677C9A61FF023F075AB0ED888CF66E -:10384000A7D57BC91DE7B3EF7BACD3E132E51D7A89 -:10385000493BF0E7EC42A233EC75EF5279F3C1AB90 -:103860005602E787E42BDA8B3ECFE44FE792CA5843 -:1038700080D7EC9685287F3E786EDC01967FD45405 -:1038800000F4F131B160DEDCC7E4F7B1430CF05B6A -:103890009626EB7144BB31BF852E300DF3D3AB1BA5 -:1038A000DBE1DE988D485E2E9704F6BD1A9F80F20C -:1038B000AC9AB57B897D05EE633593475EFA1FD4DC -:1038C0006F6932CBA7791BCCF52A322905F2BBAB45 -:1038D000EEB7420611996F947F147E33D3581EFBC6 -:1038E0003C52D708F6DC2332C5135DFF6C8548BD1A -:1038F000A91E5AFCFC2305B3687D791A3BDFF990B9 -:10390000FB19F3C13CA5CF172CF3C95A5ECFFD1D9F -:103910006D19326D18C1F198DE5AA0DBAD448538BF -:103920007E6FF85776E4FDF76E11F1DCA937B41B12 -:10393000E4F39CD5E6FD5D68FFA1FB25E43EDCC712 -:10394000826DD7A2DFA6EF47C797BE1FEBB6F0F791 -:103950007C1FE4F4DA7DBECAE1A7FBDD4FA631FB94 -:103960005DAF3787D47F1D52D7E9DBCAF99BD2FD03 -:103970009369C9C0CF9D23199D74C8C6F35039D827 -:10398000AFF97CFD6C9C5F68BF5F9FAF5F5470BCFC -:103990005DE1FA2D7EFEA9E7C01F5DF0AB0762E195 -:1039A00030E803A92905F284166D5D190B703A29D8 -:1039B0007963816E3EF089A3C3C1ABB31B5E9A43AA -:1039C000A078AFD1E9BF68C504D0EF7FDF6A55C0EA -:1039D0002FACDD66F3C3F7976A5AE6E3790DAD1FA6 -:1039E00061F55578AFB276A7F53D235E173CFE40F2 -:1039F0000AE677106F6F769EEEEF0D9F0EAAD9F252 -:103A0000FE48F0936B4927D273E87B307F2001E5B5 -:103A1000F52C39AEE7733D6E5ACB9A486DCBBAB3ED -:103A20001037AD6D197302F8BE9648EF19E9A91A5F -:103A3000689AFA2B47D278DEDD95E44A902F3A3C1B -:103A4000882F19E573FD130F0D3C42D7736ACBAB7A -:103A5000B182D15FE5E7ED5DCD73FE96781EFD7016 -:103A60009AD2A9313F5E97BBEA4EBA80545A6D652F -:103A7000E522AB3F761885EBA24D56BC1FBAE8A9EC -:103A8000C77EF153C8237AC786E71F0B9FDAFFD69C -:103A9000D5B4BEF0196B5205DB8603CE8375BCD45A -:103AA000D2FFC1F9848E8705CFEE9721FF0BDAC1D3 -:103AB0003FD0F1B1F09936990CE809BFD2E636B99A -:103AC000C311062FCD4746E23DA3273E9701EF1FC6 -:103AD000EC11486A56CFF7AB37ED473B06E08478E8 -:103AE000E478EAC65B0F7CF927ECCAC77E0AC8ED0A -:103AF0000BE16B1FE8D564A4EBA777D17554FFC920 -:103B0000E60638543F7D5B2CECE78454C7E8FB9114 -:103B1000952990E7566DF5A62858B2F6EA476F4703 -:103B2000BA9B77E8F61476CF414BE3F91D69B0CF25 -:103B30005B364EC57D56110FD25FF5236225E4C179 -:103B40007C2691D1CF84E18FEA5E4CAF9ED84C9118 -:103B50004BF77902E46552D0DFD1EF35DFDE1D0788 -:103B600061E7909FF173C86B7A594CFAA59B6EB7C9 -:103B7000AC42B9FA6186960AE793140EBA1C45F96D -:103B80002A1E2A4F657862F218DFA3F4570AEDD097 -:103B9000BFDD8AE7C286F7B8FC64F32FE5F3D3757F -:103BA00047833D722285E98DD0FDDDCFF747E0C226 -:103BB0008681CE0C7CCEF87ECB1AC6E73ADFFBAE10 -:103BC0001D0DCF3FFD23E323780FF4115D973F15C3 -:103BD0009FB74D11502ED8883F1C7F6FB172FE36B3 -:103BE0003FA71209ED399D4EE8FA25F81E59905E5F -:103BF000E83C098807B457AAEEA7EF1BECEC5A98EB -:103C000017FBC9C1F6AC201FCFE3F2604E2FB33CC7 -:103C1000201B932F2A2EB0C8EAFBC54F817F29BFF6 -:103C20007A55E05F2BDEBBF968FBBEB76EA074FE71 -:103C300051B3CEB766791ACAB7D53B6EC7F86028BC -:103C4000DF7E945E47C2F26D3ABF3717CAB7E91DEF -:103C5000FF5679AAC36F5D08FCA87CFCF92E3532AB -:103C60001C43E5E3A5BDD4B0F291FEFD9114F4A48C -:103C7000439DFE74BA5BF0E4E23E2087BAE953A7A5 -:103C8000BF6EFAD4E92F74BF66F8853E9F02C94E15 -:103C900006FBC17A37F13A29BE3B778BF8BDA433D6 -:103CA0006A672CC47F5646919960879F51783D9EE4 -:103CB000D53B93E54690137A7B67148B579EA9EC0E -:103CC0008C8D37D8D7475AC55888EF76F8C2DFE7CA -:103CD000C08C443A7F4784FB1E7A3CE24C74EC4033 -:103CE0009C2F3AD307F82A171D99CBF2C10F13F175 -:103CF0003B3E73575C170BF921675AFB4E9C4EDB1A -:103D00006F79997FC6CFAB496914CE7338DE4F12F5 -:103D1000EF8345747F735A99FD3C777D783AD1CF14 -:103D2000CDAB1C4B659047D46E0DD20781E7EC3BC1 -:103D30000BD51B43DA5BC7213D2D08A1270FF78F59 -:103D4000DE047A82B8EB203288FB2716633E48B93E -:103D5000983711BECB79E6A08879EB5DAD226984F6 -:103D60007D6E177C04F8DB9B8C745943E58731FE2C -:103D70007B0AE8EE3CF7E84EFDFA2F0577D02E8B54 -:103D80009E7B77E0CF6879EAB9772E7901EACF1F79 -:103D9000CE7C9784F1B3F67C7133C8FF337B6C041F -:103DA000E32A7B5ECABC03EABB6C987774E66E9B21 -:103DB00086F6F41E27E6D19DC960F1D4FADD9F0F87 -:103DC000C47C74D2C0E8AB37BBB7D5D5FAE55FF198 -:103DD0007E6D2BDD15E8DB3D31688FD7EE8AF281F1 -:103DE000937A66F7E705C6F38BEFBA9F1A99C5EF8A -:103DF000CF38C974887B9D896771EBDA17AE7A0C6E -:103E0000F2E117B7B4C9706FA7F4B75F0F04797305 -:103E10006607B3234E5B3B1E256E42627ADF768FC8 -:103E200095C2F934D87694571EEFDD321ECE377A1C -:103E3000C285C1E10C8503EC8BC2A51AE464247829 -:103E400064FFC7C2E3ECCD30FFA2D62BF1FC210802 -:103E5000174163ED4E9F5DC0FDB3F63D9F0F0479A2 -:103E6000FC51F30AD4EF17DA77F1FF73FB16FC1756 -:103E7000B36FCF7FECBE19FD1F07FD94DC930F7A63 -:103E8000D2F9F3DFC3FAD34E37AEF722F9DFDB9B6B -:103E9000C51DFEF3F6FF2DF1BE43C0FC950BE1FD01 -:103EA000E7FFB5787F99E3DDA9409EC499DD5F67A0 -:103EB00012C3FE2FB4EF3DFFA5FBD6EDA0764B9DC0 -:103EC000924FD7F70E699A9A45CBDF699F2481DB21 -:103ED0006A8B704E73BA37F32B6C02CBFB265305FB -:103EE0003DBED46ECA7B4AAF467B6382760FFB3EF3 -:103EF0009354D70E79A7ED2573DC6BB1C7E0B73DBE -:103F0000509F329CD7CDFED684927107C1CE7B6381 -:103F1000055D1FE4F965480ADCE598A8896817D2B1 -:103F200012EDC137334762BF8985667FE3FA103FE0 -:103F3000E1BAE9E6E753F9F8D3C87DC910A79B3683 -:103F400097C5E9AE23752B8DDF519B1A32CE2B100E -:103F50004033D891DF147E6ABA0EBF25080F52ACE9 -:103F60009FDB5D007E84C1BB7DCA20965F2CB919A2 -:103F7000FCA62D7663DC94FBA156FEBED5B1BA1D1E -:103F8000F8D64ACCFEA7EE475E08CE84FBA7385E83 -:103F90007610EE564D44FFD4302EC245C7C737C504 -:103FA000838EBF6F8B8F2EC087E15C572FE7DB6757 -:103FB0002D8473083BE4BBD37D4D5CCFEE8FD8F3EB -:103FC00004846365A115EF4DBE6FA92C00C3B962CF -:103FD000C895353F64C3BA013EF3391CAB481DDABE -:103FE0009DE4AB73E78A0AF0F40FEDD6F91A21E3EA -:103FF000A95F525524F8A3E9BEE749C41B3718E26C -:10400000A00279CF1807F599EBF0774D4A709C0B19 -:10401000F58F241FFED9E5DFA83C7A8F22FB089498 -:1040200098374324A3FF38B395C1B17691E0CB46CE -:104030003AF25B8DE7BF0FA4B378E3DFEE1C827228 -:10404000AEF8C703E2985F9B8FF93CB5DCDEEFF278 -:10405000AA7110CFE96AED1B07F19AAE83A5B1E111 -:10406000F2780E71BFF20FCBED589E29139AC43827 -:10407000BC773201F570591401B913FADEEDE97A13 -:104080005CA68E9D4B1296875FC5F7318FBE1A973F -:1040900060C0DBFAF11F48037BE201FEDE339CAB1C -:1040A0007C57F8821F0B703D14D53132DCF709576D -:1040B00071F855ECFD4286F8C1A4D62CFCBEE4A4F0 -:1040C00032D194A7BA3C9DFB5343C8105857C5DE64 -:1040D00031B157015E0E8AEE280ADFDAD6B3B22775 -:1040E000CCF95C283C617C88231FB5BAAB009E47A5 -:1040F000EF89C2FBFFAFF3F3A23CFE5D48F87410FA -:10410000C4CF9AD2593EC8FBE92C8E3EB9A2D89AA8 -:104110004CE7CD6B5106415E592FDEFFFD74159FB4 -:10412000F7E6EFE9FD7A2D62FD8EC84A4DB8FDC76E -:10413000640AFC3CC4FDBD42E13F0F6FC53F76FA07 -:10414000E15E5C5799C0EFCD84D23541FEE81A2D6F -:10415000F840FF821F8BF50A01F5FFEB7ADEDD24C4 -:10416000A62F75BA0F85F36E0E677DFEBFF0FA5E5F -:10417000AE377438EBF00D5DAFDE9FCAAB11C67879 -:10418000CBC49D839E06FBA4A655502C74A81AA9E7 -:1041900043063EACDD79AF15CE17AEE7BFCF42A4E4 -:1041A000CA81C6F3DDF7D3D9EFBCEC1B3C0CEDC7DD -:1041B0004FD633FB589B7B3616ECA0D72DEEDF0D88 -:1041C000037E7C43347DD73CB47C77B9B2A0CC6A03 -:1041D0001C370BD7397951B115C243372E6AB3A6B4 -:1041E0001AE8E97DC8C31A1A6CEFB548C5FC453A10 -:1041F0001FAEC3FB231B817C8CBCE6F69218FAFC35 -:10420000C6BA784687D5CD6D32D6D97786F5F9F41A -:104210007942F9694A458CA93EA7B4231DE0526151 -:10422000F32F7587A1536F867EAEF20DF58446E9B4 -:1042300076E0FF0F7AE2ECC870DF419D98D1433FF2 -:10424000A486D30F4B56A8A900FF25BBFBA602737B -:104250002C79B93C259C7E7873393B3F3CCCF32EBE -:10426000CF4CA1FAE10A837E981285F411FADE554B -:104270001917A91F747CFD9BE5CC9BA01FC2F0758C -:104280004586593F4C6B9D85FA61DA1491A8867872 -:104290005C69068FDF46D40FC529D763DDEA8E0936 -:1042A00043376F72BF04E00A25CC037AE28E0C26F6 -:1042B000F743F5452479AE5CAC3CFF5F82B32ECF6B -:1042C0009750FF85FD0E4E281D1294D74BAE17F068 -:1042D000F74B96EC66F27CC94D3C2E19225F2B41C0 -:1042E000BEE61BE52B7BBFC6C3F441EDCEAC8766B3 -:1042F000D0E7373459DD76DAFF86A0BC2D30CADB33 -:104300003B32241DCE994A18FC4E9F114354B3BC36 -:10431000CA01397574D04B79CF02DDBFCEEE99BD9D -:10432000CFF5F86B835ECA8778FAEFF9B89B391D31 -:104330009D5E4E1694513894CE65F6F0E2ED22C2A1 -:10434000A1A685D97935DB04BCCF3B72F017786E16 -:10435000B870373B3784EFF9161BF0B8F0F58EC60E -:10436000DEF07C9380E79E55EE85ECDEDF061627B7 -:10437000B6D3FF205F624D74EC6682793A1AC69B11 -:104380001773B855D83A0FC0FB158F0BEE4D28D7D1 -:10439000CCF1E9C539633F00BF60E1B69076F71A0A -:1043A0003CCF580C7167831FD2C6F7778BE8CF7B61 -:1043B00016F2027F2786FDBDB3B65038547F4738CA -:1043C0001CA270C8FFF670A86DBD17F36FBEEBFEA0 -:1043D000F76570FB7030C9077E79DFA221FF7B5F34 -:1043E00011F15EF1DC7BFBA51AF3940E6530BBE2A4 -:1043F000758BA7310DFAD5B0FBC7F3363EB31FAEB0 -:1044000086CF682683206C3F6F83594F76EBE51685 -:1044100015F5EE8CBA6704F89EFF2D22C1DF019BD3 -:1044200033D8E681F3D743519D28CF743AFC12E884 -:1044300090C2FD0B3EEFD15E9D65E857EC1414E48D -:1044400013F89E06D4291EA2603F577D3E92C31DDD -:10445000E333B53B199E6A295E80CF46527B17F441 -:10446000C88D54EFE079596B9B15FA57D37E892894 -:1044700077DCE8EFEAFA09CEEF8A530C78DB7D842B -:10448000D1EF56C14DC2E02D97FE773EBC45C29795 -:104490006E3F5C2CDE74787CA9CB6F8EBF4351EDF0 -:1044A0001543F09C8AFD0E10698DC77395634D7D91 -:1044B000118F519982E9BB32DD7805FD68882F5D47 -:1044C0000B0BC70FD747619E1CCE9BCDEC21A37C65 -:1044D00009F5A36B493BDA35629AE7E174435ED88C -:1044E000349EBFD27DAE1BEC37392339723FE22AAE -:1044F000C1F31F3DBF167E390AF3C1787D5F46C107 -:10450000E11974BF9FAC16F17EF27516F5AD22E08D -:10451000E3B5560274F9C96B568DD9A13128876766 -:10452000BD7ED40AA19159905F40FBCDBA8BC9DB07 -:10453000A330186DFB13D5631A7CB784340F85BC88 -:10454000FD29EEB672C8DB9E9A7F68259CD34D2E5E -:1045500055DE7A0BE0BB462400DFF75697A2BF7208 -:10456000DBAD02D2F5DBCBF1B7B0C8D429596FBDB2 -:1045700045E7BD6975329EB3CDD0F69703BDCD99A1 -:10458000E874C039DDB85C91780C70BC89B463DC28 -:104590006246DDAD5361BDD5542F40DCB5BAF55050 -:1045A000792AD4370AF83B6AB55E8F0C57A0DA3700 -:1045B0009C9521FE5245FB017A6A37B27EB55B04B9 -:1045C000BCDF5345E503ECAF6A8B40E022493BB5C5 -:1045D000FFEC6C5C9F9D8EDBBE91BE4FEBF3E07DEC -:1045E00018774B3CFEDE5DED6BEC7E5055E18A03A7 -:1045F000209FAAE87BF43169DF722B8E377FA340BE -:104600002035B8BA30EB478530DE6B56FC2EC8E15A -:10461000B6876558F7CD74BE343AFE1CB1A31CF3BF -:10462000ACEF1014CC83FEEA07C80767381F90D799 -:1046300096313E13789DDB85BA7EBC37339BE5BB54 -:104640002F5BD108FBEAF02667814B54BBF3AC0C1F -:1046500076DEB1E5F0E1198A379E07B7CF7B54EEDD -:1046600030C8A9A733FBB2EFE4EF2C463EBF855418 -:10467000E2B9B86705D3CB475646F904B047AC0A50 -:10468000EACD7D2B2F7D10F67FFA292B9E979ECEAB -:10469000E8C0F8EC898D56FC6E48FD4611E5C889E6 -:1046A000ED2C2E243E3275641AC08FCA01A0BB7D4A -:1046B0001B4B659087277C02BE5FFAC8ED292CEE64 -:1046C0006B961F55EA0294178F4431F9306F43F807 -:1046D000F3D588F262E94826DF43E4C1E2F4468C70 -:1046E000FB85CA895AE2D0E5C360A8B7FBD3907EA8 -:1046F0006B5EB312B0EF6A24E5E60D403733A2E0FB -:104700002499F2857F3FC8B74F7C82EAA5CF6F9C82 -:10471000F99BA100BFE3006FE08BF58978BE5AE5F5 -:104720009B8570D5F311E76D30D3B39EF774BD4709 -:104730000CDEF3A1FFBBB13A8668867E87EFA274D8 -:1047400049E79BB953C0EF211DBEEBC881DBF3B134 -:10475000AE001DD62CE37A75BD13E9F6F00FCEAE90 -:1047600004BABCF94E01D74FBC9E46D02B351B0472 -:1047700015E29AF3EE64EFCFA3EF03BD1C7E98D150 -:104780000FA56315E8BC66E3BD07B0FF164185F1D0 -:104790000F6F9A857AB8DA2B127CBEE508DACB5413 -:1047A0001F60DED03EAF9802745ED3605300AF3A14 -:1047B000BDE8F477847F7F9AD8DD0327C3EF536485 -:1047C000AAECBE7C08DD89D3B390BE6AB75B915E6C -:1047D0006ABD8C9E8E3C25221DEE5B79DD48A09F34 -:1047E000D35B8508F447E92B3F485FE223567C7F83 -:1047F000DE132CBEB06F23A3EB132DCC3E2D7DA476 -:104800001FFA35F35EB712167F200EA3FD71213A11 -:104810000CA5BB1E7A89D36124BAF3589BA741FE2D -:10482000C1ACA7E9FAD520BC4A1B7F807180D2C6F3 -:10483000EB71BF3AFFC0BD16C8DB98DBB482E5332D -:104840004A2CBFE71BAF2B641DCB339D41FA175990 -:10485000FE899FAEE3A5ED8FA11DF0F12F8F607E45 -:10486000E3C21728FE69FFD3DB9DC48F76B60FE540 -:10487000CC821611F34B89E42F986CB8BFA5E7657D -:104880002CFC9513E1BE6087CD5741DF5FF0DCD192 -:1048900081784E7E37B353BDBF64DF9921DE8E81B0 -:1048A00093213F5362F921A1FA3790C9E230A77EE4 -:1048B0001383DF6312B6B5E139D382E6EBAC36433E -:1048C000DCF24CA615E7A5FDD83D338A7F385F841E -:1048D000F5197F4F42CF0B39F504E39F053BAD68D7 -:1048E0001F2DD8B609E37DB5DBCE62FE6CE9AF9E25 -:1048F0008A0538D4EE14CDF953DB44BF0DF3BCC4A4 -:104900002336F65D0E531E534D0BBBDF51D3CCF354 -:104910008442F26716FE6AF7735E0A9A85CF3E1EDE -:104920000BFCF461FBD65880271D0FF38F2616462B -:10493000C84FBA505E52F31A9E97341E7FA7233495 -:104940002FE943F807D5E3997D42F2BAB631B9456C -:10495000B15F10EE1E926EBF2C7CEAB347218FF63A -:10496000D48E8F1E85F52FFA9F4F1E85BC0EB22761 -:104970004A017BA2F6976F62FEA1FE5E611F664F41 -:104980009D7EE271CCDF3CFD8E0DEDC2D3BB4F644A -:1049900082BD70FA992F52202F73E9EE728C4F2C42 -:1049A000FD7529DE0F8DE46F027DFA2E227F34140F -:1049B0001FFB5A44BF83AEF3E3B76DC8FFDD7966D2 -:1049C000CD8B59FE9ECAF3CBB687CFD3D5F3A16A60 -:1049D0005A264F1C0EF2AE85E9F5EEFCA80BE595C4 -:1049E000FD91E2F58A8BC0DF769E3FD83C3E6C5E3F -:1049F000D9C7F00F8AA76921F8FBACE5969FFF1491 -:104A00009EB584BFA7ADF3F585E0A6E701F7EDA35A -:104A1000CDEA037CB4E349CCE303BC55A8A0FF3F37 -:104A2000CB84F8E6496B27C60D3B77DB14C8F75AF1 -:104A3000B0FB30F2CBE95F1FC23C5BC2F3714F9316 -:104A4000EE3F9637C96317B55B9C2C1F8DC31FF2D1 -:104A5000D5D4586CE779698C8EF57CB548796A0FA6 -:104A6000F5C966F1439E9FBC586D971547105F804E -:104A70001FA110F075C494FFA7EF3B743C05E070D4 -:104A8000A531FF32523E20B7D37BE08BC9E5D39BE3 -:104A9000783E66779E2521E983213F88E9C35A9FA6 -:104AA00070381C7EF5FCCBFBFA70BF53E74FDFC5B7 -:104AB000E55D5E78DDDF0E2E0D7DD8FD001D3EA785 -:104AC000BE0A2FA79FE2FC4EFD96ED7D0CFECD4C5D -:104AD000EEB7E87967FA7A1B9B995E3EB58DD98D62 -:104AE000A1FC5D13E1F7B45EE8C3E20D353BDB06E4 -:104AF000821C3AB5F7379CEE7CFC1ECE11D9CBE573 -:104B0000B6CF28B723FC7ED97E3E1EF577C38E57DD -:104B1000BBFD6CD8F13E94B4EB60FD1FB6333BE4B3 -:104B2000C36631ECEF20FCAA8FD5E407363A65F472 -:104B3000BBC4D86894474B9D856FC377DD963A65B3 -:104B4000CC77A85FC1F323EE72E3EF78D43BC7E2E2 -:104B5000F74B57027C0C7EA855F1E0EF4E585D955F -:104B6000F9E05F85DEEB94932CC467C4BFE4C5FB1A -:104B7000BD13B23F9740EFB42F37DF1B699794FD09 -:104B80008974BCF632C10DF66E4F3A338F7FAD2675 -:104B90009AE26710AB867D75B9D9F7D09C16BF42F3 -:104BA000BB106754BB0B1D3D95FD5E35FC4C179C3F -:104BB00083AF5D6ECF817B5CB1C48DDF1976BABBEC -:104BC000EFCFE0787124246F9BFF5EB5830B95389F -:104BD000A2B441DC223A97FDFE8342A2DDF0FDA2A1 -:104BE0009FC46A78AF69BDD3837A3822DFB8D9BD54 -:104BF0001A3D9E1457C8EE51FE5FBBEBC4160080F1 -:104C0000000000001F8B080000000000000BB57DB5 -:104C10000B7854C5F5F8DCBD77379B6437D9900421 -:104C2000C2FB6EDE0921591E09A82837E16110D0A8 -:104C30000511505137E1FD4AE2A396AA9505621A83 -:104C4000296D8380528BBAD050FD5AB480B4828DC6 -:104C50007603D162AB36A0566DD52E101194C70ADB -:104C6000948FFAC3F29F7366267BEFCDE681ED3F0A -:104C7000FDEA30F7CE9DC779CF3967660921E40A8E -:104C8000FD7F92A6B485EC04FFA09E4C747537FCA2 -:104C90005723A4373CA77F2A211365072123E977EF -:104CA000132C811809DF4FC9A2EF1DEC1392944A0F -:104CB0003C41783FD5E1F1D3F60E876F0A49206475 -:104CC0004382F6A6444BE2518E8672A12B955C4935 -:104CD0002724B120E4B7D0C789A3E973DD3CE89F5E -:104CE000E475E2FC8E9AE677543FBFFEAA33E5787E -:104CF0003CAD2844B922D3F1ECAD84D0D2E951CEF9 -:104D0000C13891FEFC4429A1E3F0792612FA9EF6FF -:104D1000E396362A57E83A5CC425910C1CCFF4DDA3 -:104D20000017F60F75DAEF5EF8C73584F45BA6B6A8 -:104D3000D8E83ABD76C90560E843E7DA0A40505A38 -:104D40006D008CA71CA21EB49102DA6ECF215B8885 -:104D500096CB771EC2F716A8D332395E1DDF7F18B7 -:104D600021930359DEB43C68579166F160BD554903 -:104D700025A46E9A2FCD320CA69FD5D0328090E715 -:104D8000494DBE44DFDB6BDDAD07AF27005A3A1952 -:104D900078EF6ED50AE03DAF131224741DCFC7B56E -:104DA000D7357B1AADA7B7D7FD506F04E05F0BE393 -:104DB000B95B6BE9F7BB54EF44958E3BED190B9152 -:104DC0005208197BC91190800E42BD08E90B9FD58E -:104DD000C4015EAEC0DFD84809F025A99176E6F798 -:104DE000E676749EE53BE9FAA7F92ABCE347103260 -:104DF0004A627025AED088E94E9847E56CB538F226 -:104E0000DDB467CEC9E9747EB3294D11FA3CB1DC3B -:104E100075532E9D5FE2160A2D15DAFBEE82796737 -:104E20003DE2B300798C25A1FB258A4FF2490ACED9 -:104E3000478C53F79A8CF45BF79825B01AE957958D -:104E4000BC43F5F80B99F01766F8DB7B04F157D5F6 -:104E50007484E16FEFD666C07F5593E48A51613D5B -:104E60009E5D9488C8FD816BBCCA408AD798701D2E -:104E7000E0D54A4679A7C4225CEF85F574802B9F64 -:104E80005F77707DFEC4B61F17D2A6FE53164F166D -:104E900089C04BB4DBACDA102E7DD27D8F021CAA08 -:104EA0003786EA62E9BC5E3D7138C147E79B75EA27 -:104EB0005CB090CE376B0CB271FBB8CF9FDAD66C7A -:104EC000A3FF7C1EE898BEC826BED52E4757F060CB -:104ED000F4DD0E8F3D47103E16A8D3E7BB6D64117D -:104EE000E0B56CAFA40580BE63C83D5E5AAE572DD9 -:104EF000B88EEDAACC4B89E1F154BAA2D2EFCB66C1 -:104F000058B4002D137919597F2DB6DBAE2A580AF3 -:104F100078087C0A3A22A4217E1AC5635A8EEF597A -:104F200023DD3C119F4EDF8F6D3B7A3FB144BEDBEA -:104F3000BE9278E75923ED28FD3C6CF86EC2F7E28B -:104F40007C0591F64097402766FCD0EF7630BC3E5A -:104F5000110FEBD8D7764E0678F714AFE6E7AD2BF6 -:104F60007DDEF1D6CEF9C75B2A7B01AEE6E7418054 -:104F70002FC2C7EE6FCB05A92D91440A6AB9AF2F96 -:104F800008F35B6E0F25CCA0F8AD2A3D6F0338AC5B -:104F90008E3F739D2F4A3F9DCDA3F5728EC34BD795 -:104FA000B7FF520CC2DBDCFE2B8ECF7757CEF68ECE -:104FB000A704FA785C42210A5B3F793F93EA87F1C4 -:104FC0005CEE8ECF5C3285092DC5CFE5B8742586A1 -:104FD000A0425068BB09F084CEAF7CF42E85A44378 -:104FE0009DB613F2D88DFD6E2345800F6B1B3CB729 -:104FF000D3FF811E999C79D349D02FAD4A684D22A9 -:10500000057D6B9A84FAE7C6CB0D2DA0BB6E4CB321 -:105010001AF4DC24D5589F0C7A4F37CE348DE29D9C -:10502000BF3F8FFF0DE0FA6E56296869FF3767C6EC -:1050300005FC74C9B78CBEDD3B5EA72F0E7D2BDF50 -:10504000E32DE8089FD16E011F2FC2F595580A9FE6 -:10505000225867452DD3495DC3C30C47335CC67FD7 -:10506000B2600A29EC08979EAEBF1DAE84FC04D640 -:10507000375993C95A7704AE66F8D0BFA9D0EE501D -:10508000296D27815D704AB1D0FAA46B2422EC828D -:10509000097ABCF3F999E16A869FB03726F3EFDE0F -:1050A0000678517A9A2C6F71003D4CFA61EBF864E6 -:1050B0002AC7260D64F825410A5CAAD76F20083359 -:1050C00080EB36A43B9715ED0CAAD7197D7C32F105 -:1050D000A444C79F7289BEA3F39CA84A01CA2200B8 -:1050E00097A326B81C35D1C551FDBACDF37D05FE79 -:1050F000714D147A511A7281EF8BDCDC3E1944D465 -:105100002B541F957C3C3291C987E87A72EC256F4D -:105110007B3F0C1E0D483712F1B53F77D17E829A46 -:10512000358582818CB3BB904FC6116D4D9B1D4060 -:1051300021E33CC5BC4EA6793537FDBE944C5AD30D -:10514000A687F327429F33788FE3F01B47FCCD728D -:105150000294CA05FDBA457F93C47A0693C1600FD5 -:1051600035AB2AD3FBBC3FB1BEE4641294E804C360 -:10517000923DB04D82F913BFAD57643C2BC7EFC7CA -:1051800099D36F75A3DCAA21002F305B009F65FCCB -:105190007D99DD1184F910BBF5543B5EC086217307 -:1051A0005CC787205CC895F8C8FC2ADC92723C3743 -:1051B00032BFD307ED7E99D2B5A7AF6FBE9BCEF3BA -:1051C00094F47621C08BDA65D920CFCDEFCF7FD490 -:1051D0005205EF69BB05D88EAF6BA92C21DD845F2A -:1051E0008B096C734793E7AB98FCB5534BB42442DF -:1051F000F765718CCF2713AF02F6E5FE58C6672D11 -:10520000B18B911F26929ADAA1B4BFBFC4DD78108A -:10521000F86C12F163BB092E231D7647A73791F076 -:10522000DD60F74ECEB59AEC683FE2677F6C4E26A4 -:10523000E8B3FDB14C2E0BFBE149B7778D1BDF0FB7 -:105240000A805C3EAA15BF0B7AA2B274C4DF46D2B4 -:10525000D262F7DA009FF381BE285C47037DD16FED -:10526000F743D77D91BED601FEE6D69BE8CB9E8C58 -:10527000FD7BA91883799569D66FF476753BDCB808 -:105280009EECCE5E242D0AC9A5709DC7E9747F6C83 -:105290008C1FECB8B2C7291F53F8CD25BE671B245D -:1052A0009887D560BFCF8BB5A2BD37EFE7B1C8EF08 -:1052B000F4E32D3574C805F4F95ADA0FC95507E837 -:1052C000F53A69D07D0FF8B7AB488FF35CEC591B0A -:1052D000EDA36F2FE8974A370A4FB2D97A4E4F970E -:1052E000E6F13BEDD7F4DD7E89CC06BDBADFAA0E30 -:1052F000F0E8F4C76E37B39BCED9B3B658D23B872C -:10530000D3027BB2A68C88D48FC7C6CE8E66278880 -:10531000FE045C23FB8B130D2D6322FB0BCBAA2F0A -:105320004CFB8B2FFEABFDC5A1AD5FB4D6D2F934DB -:10533000647AFF0EF446146F1EC07D13B71729A5BB -:10534000E44DD3E1E1EF6E66CFF45E318E1CA3A491 -:10535000146327FED8E194DF15E2B70E87F6BE5539 -:10536000168A57653641FD43E50DDA99E6F57E9CD0 -:1053700059F6198C27F8B02C8ED239E5BBC72D6AA7 -:105380006303D8D37F96A96D49475F3117EDBC5BA6 -:10539000572CC6F2ECD1CBD9C0FF651CAEA7417F1C -:1053A000835D1DCFF8A73A9EF1CB2B69BED340FF9A -:1053B000AD9AEC1C49FB5BBA57F6C4E0F2C38360BC -:1053C0007DB74E9553E1F931BB15F789FB9D0CCFA5 -:1053D000C78854BE13ECDE4331DE3DB45C9056EA20 -:1053E0004AD7D9830BD2C6639D9453C38ED2DF7D37 -:1053F0007646F7C7889BCDBB5EF26CA78FCED5BB38 -:1054000013810EF75B89C1EEB0A4337BD992CEE055 -:1054100058798932E108465F3574FC4A45B5819D6B -:105420005F79C986CF611E487FB1C67EE2793FF1C0 -:10543000EDFD48E80CD81F6BEE4761CF391D9BF19D -:10544000F0A87B5C22AC67419AE64A4779AF2A0014 -:105450009FB2912D1F81DCEB5ECEFB2590F3D5979B -:10546000A5E060BAFE537BACB87F3BC5EDFFD37BB4 -:105470000EF4AEA4E5F25DEF25C03ED19DCEF075F1 -:105480005A694D80F92DFB1DB59B0B906C7BDF8914 -:10549000DFCF2D59CB86B1EBF5DFB5DF660CF062BF -:1054A0003B3AC19288FD35CEEE0FC0FCF6AF926755 -:1054B00003DEA87E14F69704F270C21E598B2DEC01 -:1054C00068978D4AB7727E63787CC0C5C6E98C8FB9 -:1054D000CB2EC593808E8FCB145581F9975D4AC032 -:1054E000E7A74F6CDB7033A57B7F9A15F781747B40 -:1054F000D48276A1C4FAA56CDD9249C769E1EB7943 -:1055000063CFAD33AEA3FF7C13F40C6D333EE44B9D -:10551000614C4D777125113B6B82CB680F9AED453D -:10552000A1B7CA9BD6D7F62700F7C0ADD7011D9EFD -:105530005008D061077BDA7E632776E37A84C7ABB5 -:105540007B7E89FBA53EE92AE3AB3DE727021D5799 -:1055500091E04CE8B76A8FEC0AD2D66F903D434099 -:105560007F08FDDEBEDFB97CC0EE01F91F2BBB5604 -:10557000C33AEDB739540AA7EBCE16A4A09EB35B8D -:10558000CB41FE95C56639E6EAE8797F8A5C0E7400 -:10559000F0464A86F1B97DC310D073FB2C4C1EB582 -:1055A0001CBFC311C276B7A6A0BD26F4BBC93E1569 -:1055B000FEB0495972209ADD4BE42D1B63E9FBC90B -:1055C000395622839D1E5A827ABF837EBFECC37DEB -:1055D0008059CF0BB8534823BF74B04F237036D8CF -:1055E000A98FA6533B6D08D2C050B03B8397372C90 -:1055F00085799E6D8A77AD46BF03B36BCEB62DD944 -:1056000030159EBF2DA31FE5EC6519F969FFEB4B23 -:105610000787747C4C3505E2E9E2B0AFCFFC81E24C -:10562000E7E2E7711E3F3C56760E89B62F16FB2542 -:105630003A723F4B1ACEBF9F6534B21BEE4F6F8854 -:10564000EC4F37A6E3FE343C11D446DA962336A05D -:105650008BD3D45487F9FA29F2B753B8DEA0856406 -:10566000976E3E2FA44BDCDFA13D0D72C54FCAFAE9 -:1056700053E3842C8AD34AAF03BB731A716DA3EB37 -:1056800079ED449964A5F531DBDD1E89D67783E198 -:105690000974FB3B39B09DC2613795C7BB69BF8BAD -:1056A0005B1B6C6E3AAE7F0F9DD4285AA7880438D6 -:1056B0009CB0FA0725E9E8645606932B27ACBEE7B1 -:1056C000A09F131FC710D8079EF83C2EAABE1D9C92 -:1056D000C1F4ED1FB89EFB37A7F7E0A957DFEC47F1 -:1056E000E715BCE41A06705FF2C2D772051DE77AAF -:1056F0006E974DD9D85A0BFE9B9BB78415903FDE11 -:10570000806B02A8DAE92F78ACA09766ECF05AC15A -:105710000C9FB9A7C60AEF67EF6D7803EA770477A5 -:1057200062FD7CBAEF8F00971BEAC307805C321BD7 -:1057300088027C412E307BEB533E8FF44B9EFD89DB -:1057400048D5A516A0F3F6F11F6955C0F4B9B9966E -:105750008D4FFB7B0BF074434D781CE8B7412B5801 -:105760007F8348F3AA4435D2EFD8CBAD92DEAFF0B9 -:10577000EC438E454CEE32B80F7AB8DFD6B5C82769 -:10578000AE38D0F782AFCA1E766880EF8B3F880BA9 -:10579000C4B881CE98BD7DF1078E803F8ABD1DA122 -:1057A000B3600CA32F416FC4CEEA9A1DE8EDC12768 -:1057B0006BE2407EA478559B4F87C7B20D53F2DF52 -:1057C00082FE6363D07FD73EDE7A361EFD3E1FE841 -:1057D0005AE8B34AA007835F4AC803C617B48B00D0 -:1057E0008C2B4A22AD76117D9D04D3603E9F03DC55 -:1057F000E9778D36750E8CD71817E382F12AED59AB -:1058000036905FED7E5070265239721DB73B5F3B7C -:10581000B13F19F07E71D8AA41B03F085A7E81F29B -:10582000AA3BBABB2D5DFB0FD3B7FE41B0BF12ED53 -:10583000F71D8F2B007DF9079077801F4FC56058AB -:10584000AFF8AE7F06D3F7945F70FD824F525A894E -:10585000B6B50041A5EDD6C1A337E70B51EEB6AA08 -:105860007EC667D44E01BE7306ED19C0CFFB32B0C1 -:105870009EE2250E0F7D5FBD37CB23AB28077A67ED -:10588000A446E4C3F55C3EA4B486912F7BBA4FF8DE -:1058900096C337A8ECE4FC45504E017F31391EEC2D -:1058A000CFE490BF3FE005E406C74F5F89960B3910 -:1058B0009EC5BA53B85CB84EAC0BEC375A2FC960D2 -:1058C000F247BC1FC9E136412E480C45F1FFB4D365 -:1058D000DD8ABE04ECC9092BFA635992C1E6BBD834 -:1058E000BE1EFDAA8B53D6A33F35456BC072F1F89F -:1058F000067C9EB6A502E963F166C9E01F15E5CFF7 -:10590000B87D76FA8405F51BB1C4F503FA13EF37B9 -:10591000723BA44FBAAF0CE07C72CF86270BD588C0 -:105920007FF8626CC3CD7700FD6F975DAB003F8D54 -:105930001324350A5DE9E107F0AA6EFCD744985FAD -:105940001509D5817C569B24949FEA5E5AF6A1C422 -:10595000DFC8E4E9496EA72D8A33DA97B338DC4E05 -:10596000585B2717D1F183E73287835F27A88464C8 -:1059700085E18F007F801C7621BDAF1DF410D09192 -:10598000E444FB07E4EA2E1D7D2CDDB1B5AE1FFD1E -:10599000E70D975DC364EC8738F4F25BD08990C75C -:1059A000E6F52DE6781574785D444F2DCEE07E54F3 -:1059B0004059D5FA73E8477D94E3AF11E80DF8B983 -:1059C0005ED0DB300BCA5B131F8FFA1FC9F77D4F08 -:1059D0003C3D08FD13A329DF52BE3E097C1D852EE8 -:1059E000EADAE5806F5546147D7052F23D979C11BE -:1059F000F97EDFF19BF22B75FDF8383C2E5A7D8342 -:105A00005D51E015812BE907F4B0886206E040B6ED -:105A1000482EB00BC5FB942D2C1EF014E723F15C2F -:105A2000D405BCC702BC3310DE4FC17CA95D600346 -:105A3000959D16607601B1DCD40FF4FCE238ED26BA -:105A4000F4C7ACB710F02F11A90CE93DA571D3F143 -:105A50006F4742199B8EF1156A77031D2D7E5CC539 -:105A60007DE2EA5FC5225DBE98918EEB5ADD6865E6 -:105A7000F4696D40FA3AF9F992C1109FF153BD9E55 -:105A80001545EFD499F4F943194C8F0ABA4B5FC707 -:105A9000E8AE51D1E2927474F93CD18683DC167A77 -:105AA000A5337A8CD0916B98A0A30AFA3CBD3E2412 -:105AB00003BE281E5F053ACC58174679D6191E45F5 -:105AC0001C4EE053C8F9FFF0F98BF1DFE6723E851A -:105AD000DB3B1DF1BACAC00FD747F8E12F0C3F11CD -:105AE0007EB0AA91F5FC9EC3A533BEC8CF7461BF3A -:105AF000759F6EB81BF8B96E7D9C673589C4734479 -:105B00009C55CCE3334E879DC56376A9BE4F334C7D -:105B1000F14215E53D8BBF4CE076FA7DDB63D0BEEC -:105B2000D807AF408EB4C505C0BE14DFE528445386 -:105B30008613F255861BE79F032284D65356D84816 -:105B4000261DF7E235CD2D09B4FDD470684A115DEC -:105B5000E23E5B68C62DE01726DA12B033D0970F0D -:105B6000F47F8AF54B5C3B0DF3FC1787B7C04FDD24 -:105B7000A773D3A2C50B041C3BC34B7E268F9FF19A -:105B8000F766FE6F15FAAAC7FCEB4F04FEBD81F85D -:105B90005741FC845C262ED0D3EDFC7B99B0F85C99 -:105BA000A6917F453D0AFF2666EAF9F75288F12F54 -:105BB000E7D3C446AB16CD6E19986965EB6A9C5065 -:105BC0000AFA28D14BD06F429789FCBE98F23BF07D -:105BD000B11FF8B60FC093C9DF74ADE16E789FDED8 -:105BE000C8ECF18B496CBD8BAFD79A65E07FBA1FCB -:105BF0009068D306CEEF9DC33D982831FD9608727C -:105C0000E68631A171A08755881BF481F531FC8EA1 -:105C10001D4302418A77F53261F2E3F3A7EF7E0874 -:105C2000E4C67A87274B8DE8A54FD37DC332533B1B -:105C3000E76B4A971AF8B1EEFBB783ED1F3B899FDC -:105C40008F5D2123FD513ABF365307FFB1DEB00C03 -:105C5000704D8EF7A55993E83EB0316BBA7D205D4B -:105C60009F9BDABDB45E4EEBEBC02FD72B4478FD83 -:105C70000947DFFF224F2033F330F8F1966768932E -:105C8000328B31AE3D19E67343FFB08CF2AD87F134 -:105C9000FF6AF0EBD1F51CBD2DFF5715F469E5ED5A -:105CA000DE3A782BFCCCA3B89FB9BA6918FA9F7575 -:105CB000FEE63B60BCCEFCCDDD8D9BC0F99ED237AD -:105CC000EEFF12468765908F42AE2CCAECC5E939CB -:105CD00044A60F8DF017C825B077451E02F8239D06 -:105CE00018CF0820FD413D717844DEAC6BB094477D -:105CF000A3EFEF673AA2CA53D2F47FBF7FA884AE66 -:105D0000175E31F9FAFD4C9D7C6D6C38DA9BD9AF8A -:105D100054FB537BE27EEE03D8B0DAF3D74CA0BB42 -:105D20007765F4C35C1363F34BE02FD088EAEACDC8 -:105D3000FB03B66B9282CE425AFF46221AF837BF57 -:105D400091B1DCF0A8B7DC0DFE968F2C287FABC09C -:105D50007EA3F0193D9804ECF49F7BB9DFB4F4986E -:105D600043833C81B3921DE5E7D923717ED0AB67B5 -:105D70009D16F4ABB7BC16837C713E338EFB41029B -:105D8000067F8988F79C7F7B6E32C8FF2779FCF3FA -:105D9000C958E68F7DF2F66CF4630A7FAFA250D843 -:105DA000F782B41E0AD75E6037F7473FACF0FFF6C4 -:105DB000B657482CE9888DA3D8D9FA7A2B3E09FC2E -:105DC000E75BBBC997F84DA64DD8C38D00E7EA47FE -:105DD0004236D8EF0A7B58E8EDC1A7D29B216F620B -:105DE000703973AF6D3D65B1C03AB752724A727780 -:105DF000A42F41475B3BE625ECCAD4EBA7C7585E0E -:105E0000427B9D7FF71CCF4B18DB76F465B0F328FF -:105E1000BF6F357C372135CE17456ECD5CF1307EB6 -:105E2000DF19FDCFB4105F343DF21ED72344A9E93A -:105E30000F7A8AFCF3C178358A3F67E6A795A900F7 -:105E400017B31F2E32FEA338FE3B99EDF1CE411061 -:105E50007FEB2EDE699EF7DFACBE81D1F494C0B338 -:105E600079BC8EDFB3FD597B3B1BF1ED72B07E87B1 -:105E7000EBFA55B2981D345362F17CF22D417D2D21 -:105E8000E884C2FD0BA08B92778E8D88C338505862 -:105E9000067970FEA3CC01188FEF643F2AE6432DEC -:105EA000E7AC68791F743C6F343C48594C8FCEB4D2 -:105EB000B23886747B16FA0766C6C648313AFBE4E8 -:105EC00074BBBED50C71DBFDB1A346A2DFD3AA0E15 -:105ED00088063F733CF774264178025C3C51E849E0 -:105EE000C49D059CEB4AB55285F9D5C83650811A38 -:105EF00093A329E504E36FA3240DE1910C467331CC -:105F0000D03FCBA73BFFB68C72A1A4540D4008959F -:105F1000EA8BA4AC62CCCF7AD9A2CBCF127452F761 -:105F200022D5CB06BFA3DFB0AF4EE2F2985A8FDA8C -:105F30002E5D3BF5119001117D30A0D66EA80F7A31 -:105F4000C045149DBE48D2D20CF5015E571CECA78B -:105F50000694AB86EF04DD89FC40FC4B8175BB02E7 -:105F6000901FD18BCF6794E443BA01F9067EE561B7 -:105F70001C9F74BD4559B41C5B1E3AAFA71BB1DE14 -:105F8000EED67574259D0F15606D2BE97CA95C9884 -:105F9000BBCEBD2A0DE1EE22B0CF38BED28ECFE708 -:105FA000F3EF933656D4F5A54324D5AAE8CF4DD2C6 -:105FB0006ADEEC0BF99835B44EFFE6354812F87DF1 -:105FC000A89CC1EF9E59E9C252E0DB45DF4BF4BD0E -:105FD000BF8CE4427CA7333DE6CD7218ECBE2EF4B4 -:105FE0009837ABB8A31EB3D83D6F417EC0F2265997 -:105FF00005BA5833A517FAFF36EC943CE08F3BD036 -:10600000C4F2F436CC64FA448C7BE67789A837CEA8 -:10601000488CCF494B12F2417512C74D6D12C66BB9 -:10602000CFF2FDF6B24C9F2F4B672F6D682A8EC5BD -:10603000B8AD492FD13F9744BFC3D89D04F6D3B024 -:106040007A2503E5C022F89E2C088D88CD00BAF58C -:10605000BD37460239706110E0D31C0F1471431133 -:106060004F7C25CD77AF7EFC8E7142637C4B4EB06A -:10607000E7029F8D96E33CB251FF12C0EB1AB013BA -:1060800029DDAD391287F059F32DE33F3ACF1F02D6 -:106090009C5B9C25484F42CFD27916BE4B3ACEB37B -:1060A000DA12463FA26E9E7559C55DCDD39407CBDB -:1060B000E7D50E7F1ED7929D0ACEFF2C89F3C03CF8 -:1060C000F7DA3C1FF9400F9F8943BF9FC04F15E788 -:1060D000B1B3141F129DE7D9BD23622D0EB08F7C82 -:1060E0004F02BCE481E104B0CF0F348DC883F57456 -:1060F00016DFDD9B59F67416F299EF19E43357E871 -:10610000FC4B6A64FD5DC485B742FBAB80CFAFBB7F -:10611000C6A3113ED58AA35E628E75B4C3242EA792 -:10612000CD74273535FF1BF29228BF615EA87F1022 -:1061300009ACA170AB1BCAE88FCC232AEA65139D7A -:106140002CCBF4BE0AF8127CDA057C5E8779DF93EB -:10615000E90D4209F3E83F1CE5D2FE2CA6DF5EB64E -:1061600059F07B96DF9244305FC71C77FF38B3F25B -:106170002DFC5ED85FB93EC95570557C70B86BF880 -:1061800005912E9673382D877830E4B3EDB19E32A9 -:10619000E44D98E0F0FD4CEF270C0E94CE46323AD9 -:1061A0005B43BA844708DADF93E93B06A5D34AE9A3 -:1061B000058032BA220DE0BC4BD5303F61F72A068C -:1061C0008FB3EF3078EC6BB3205D6F22F9C897C3C3 -:1061D0002DE7EE86FEA97C390DEB1A13DE29C1BE30 -:1061E000B9CF22D50272B97FD8235BBAA6DBAFB391 -:1061F00070FFE4BBC0F1703FE061C4DBCCAFD305FE -:10620000DD5EE274DB53B84BD95DF27507BAB26656 -:10621000A746E8AAA7F958942E48FF5E1DFBA3FBEA -:10622000288C3B34EF8B417955B55B42795EF5FAAA -:1062300017B85FAF7A35068972FCABB1F8FEDC1E89 -:10624000F6FE4C69F43C8284EC5EA8A796EFBCD7BE -:106250006BD4D37ED4473FD3CEB932E5485C367990 -:106260002A3BA7B086E73D89F86C02A7B3E4815EBC -:106270000DF450F20482F984090E96A7D8F13C027D -:10628000E3DB54FE9DCBA54A0067F3F904398EE5A4 -:106290001FA692755F039C92CB8DEF531DE518AF3F -:1062A0004D359D6310F02ECEE6F6B38DA4811CD93A -:1062B00069CAC710E5FE6C6E07D626E17E50E1F391 -:1062C0006A71DA906EEF73DA71DDF72591E429587F -:1062D0005750FF9BFB1165926621AAFE9C45791CD5 -:1062E0005175F651AAB797A1DE67763F43FBBEBE54 -:1062F00074C3FBFE8BF20DEF07D60C37D407AFB893 -:10630000D6D0DE4D01A0AF67D4DF64689FD530DD05 -:1063100050CFD97C87A17D5EA0D2F07EC80B4B0CFC -:10632000EF87EEBCCF502FDAFB90A1BDDC895DFE7C -:10633000A36CB63F92855DEE1CE903BA929D762967 -:1063400046B7FFABE4F8284D284F83B879AD7362A8 -:106350001AEC4F5B92A83EEEC2EFF65DF76D7E81C0 -:106360007F6E7F9571BFDB99FD548A50FAAB3A403E -:10637000E9A008ED2F7F36F72354A8D03E6C437D6B -:10638000A278701D3313ECE84F33F75F99AD1AFC18 -:106390007C621F205B3CAE2952E7F01274D91DBC11 -:1063A000EA395CFF5B78FDCD946F24F67BE6EFFE67 -:1063B000986DE1F6B86F5BB67E5F47C2B217F775AE -:1063C00017CEF809C85182764D75BC0BFD12663B9D -:1063D000408CFF4A9AF7372057CDF2D4BB62016B4D -:1063E00067A11B0CB9F3FDDE1FB3CDFBBD09B311D3 -:1063F0001F4936039C5E6CC7B366D8EFD52695E07F -:106400007EAFD6AAA5F564BFF762364178D7035EA2 -:1064100075FB3AD9E6515D28E78DF64B47FB9CEAC0 -:106420003FBACE0D60D749609725337B7DB784EBAB -:1064300016E37E07FBFCFDEC1ED8E731C453AFC862 -:1064400088BFBF67337BFCFE58F93BD9E3C7AE4634 -:106450001F1EB67A30CFFDF05499ACA2703C5F3E5F -:10646000AA0F89228F45F93EF7DF6CCB2188B7EE62 -:10647000FC1F87572EEAF2BCC7E1492C8F733AD034 -:10648000916EDCD81C46171939DC7F13C3FC18A7A2 -:106490007FEFC47309A76FFA208138212F6EC4489B -:1064A0003FE43913CF0390B7E37738D14F387D52AB -:1064B000F1C8554E1D5D8D66701EF7CA3B09E0FFA1 -:1064C00099BE2B23D5EFE89C9E32F8FA8812CAC6F3 -:1064D000BCED3F9CECADD272FABEAC54E6A734E6FC -:1064E000BB99FD46D3575419F878F925890492755C -:1064F00075A515F30A975F52F0F9E96CA35FA953EC -:1065000078F5109EE6E7029E87279D1C04FEF43373 -:10651000B1D1ED8F5B38BCDBE9C7744EA6B3F31F76 -:1065200025BCFFF3E5D7F4013937DDA666F5C4CF06 -:1065300025E0D47AF98B789013AFC3F99B28FD1727 -:10654000E5B0B8D2EBDAE7703C8294DAC3E380EED0 -:106550004BB93F3DCAB9807139E087B954FE3F3924 -:10656000173025C7782E202D478D7A2EA0BBF34DEE -:10657000D36CD1F55D6E047E1F00BFDEFF8CD505A8 -:10658000F35A08B613F8EFB65AD17FF7DEE51802D2 -:10659000F1942FB6587F09796E8B9EC9786623AD2A -:1065A0002F9A1483F19F855BAD2C3E37293600AEC0 -:1065B000AA455BBFD77B2E1DEF2BCAB7CBB2E8FB3A -:1065C0006736615ECD7B6D6B31BFFB24F0337DBEE2 -:1065D000E8DB1FCD04F8EFB3350C190676FF0EC9C2 -:1065E000704E634963ACA12EF20805FE881439BFD2 -:1065F000A1527DF2608EF1BCD68848DCECC11CE66D -:106600002FC13CFCAAA9ECBCD681E36CBFFF462697 -:10661000CB330C4E9A3565185DC7A4542BFA4BCC7E -:1066200079898420D2C9029E373CE96305CFE54EC3 -:106630001AEA443BF0CD95358807FA9D6382EEBC9B -:10664000C2A49F33BFCB2437CBABEF345FD194A729 -:1066500028CE0F75C84F8C9C1F3A1A8D6E36E4F009 -:106660003C45CED7078EB37CC4056FCB6C5DDDC8CF -:10667000CDF7F93ADE6BCBBFEB250A8FF7CA991439 -:106680007FEFF28D8F81DFEB0BAF44203FF48BCB9C -:10669000D1CFAD7DDEAE5F7DEDE77A003FB7962FBF -:1066A0006EAF035BDEE6BDD770EEA7E7F2A66B79AF -:1066B000322B87C521CCF2DD4CF7FFBFE4FBF44958 -:1066C0006F0CF23BB1FC1594A77631F968E673B311 -:1066D0003C17F332CF77F925D990BF9CCBE54044E6 -:1066E0009EDBF03D35F7713DFE1225B046423BE0A2 -:1066F000831CDA6EA423905C4A87A8756D8BEFCA61 -:106700007F43F7CF1F43FB3BDCBE4FA04CFE4BBF8C -:1067100032D0F723DEDE89F987673BC9436F769B6A -:10672000F2DA2463BCE0CB9CD266C8E77F50A5A513 -:10673000CEBE1E499990E73D7CC9F9F3A710B7ACCE -:106740007AEB22F2E7269B2F0DFC03FE7E36CFF676 -:106750002879231772AEEE3CC316EE9F27B9B9868F -:10676000781FF889306FE1681CFA89D6A669DFC006 -:106770007C9E4BD3FE0FCA2169DAE51C1D5E6AF9C7 -:106780003A154B74BBB83857D0BF17F5F8FC322A0E -:106790007FA3D0A19ACBCE01943E79FB20F0C77D98 -:1067A0007EE48E41201F5B368DEA32DFED67C09FAD -:1067B000547EFE18E47E56249EFA13CE37C2DF3D87 -:1067C000DFE6CDD6E769C9B949385EC235BB5BD3D0 -:1067D000299DB4AD93517EB739587EDB318752DEA7 -:1067E00058C0BE4B317CA7B0FD07D03DE563C5A1C5 -:1067F0007CA39747C5B90CAE9DADB33897ED136C2C -:10680000C46387EF6D476FB2831E9525CDC5FCFF2E -:106810008C1EAEA123003DFC88CBB19369BEA2DCE7 -:1068200062F88EE9DB6BB8BE551C26FD3AA0EBF88A -:1068300078639A3632978E3F314D2B86FEF6DAFC1E -:1068400043806FF6C645CF57BB2E97D923FFCEE1C5 -:10685000F4421C68BFE27832C6E96FC865717A0DF0 -:10686000CA1BFA87D7401E7AB3DBC5DB87F0DC1D75 -:106870007D3F01DE93B410B905F2E7E864E17CC422 -:106880001F4E1C2520BF12C26D04F269124C79B054 -:10689000A2FC0787DBAB3CEED991EFD83CBD1CFED8 -:1068A0008D945FE0BCA8E01788AF43BEC483AA8F75 -:1068B000F31DCBF7687CA297047196744DB5007DEB -:1068C00040FE29C827737ED08E5C76FE1DF850EA04 -:1068D000820FE7F379F6940F1B9F98628985793EC2 -:1068E0004430AF8372C26A3BAD3F7B9FCB03E7C7A7 -:1068F00032D611DC070D5C11B70DF649351C1F832C -:106900003792D5B1B4B59BE7F7897C6A776D48C1FA -:1069100073060FB1FCBD939FDF243BA1FFAF45FF82 -:10692000C67C4191DFE7CFB518ECC2DBD27D0F23E7 -:106930003E4DF9D89DE7817D9907790E3F11FCCE38 -:10694000F370C6F03C9C318D9BD01F37A6F14645B5 -:10695000A24D9E558212ECF79EADD114D037CFE5F3 -:10696000B2BC9CEEF2E39EE6FDFB01CFA99DE75988 -:106970003ED92E773AE4593E999BAACB2BFB01CB0B -:10698000B3FC7E2ED323CFF23C9A676B98BF6EC9BF -:106990000B8750DE8B71443B918F37E001968FF768 -:1069A000AC128A05FAB9184BDAF3CC57A1533E342E -:1069B0002CFAF90591576ECC271F1C0E97623E10DA -:1069C00021784F42BF3CD5A007B7865D71C02FDD4F -:1069D000E983DFE75E9D3E782A8FF14D14BDD9949F -:1069E0007B757A33087443F5E60128AF5A6F727DE0 -:1069F00029F4A7787F88E373562ED39F51F4E621BC -:106A00008E5783DE4C2101CCD320A72C1E7DBEA83F -:106A100028BDBCDF97D3B50F61BE63B83F25E1D475 -:106A20005122E9E45019E76B71FFC4F3BDC83DD3AF -:106A3000A2ACE37ACE9F963961BCAF22A1498A9A73 -:106A400087D6ECB689F8ED1730EF1B0653B92975D8 -:106A5000949B51F07106E6D9FF6DED0010C9B54960 -:106A60008DF1603E75818F73B968C768E7A114F036 -:106A70001F7EC5B88F14F0FF86C3C396A5FD1BC645 -:106A8000F913E7B3CEF0129BC7F0D12F8FD9332281 -:106A90007F7DB7C91E1D91C7E0322ACFC8973AFC47 -:106AA000C5E645B17B841C7E39DDEB80F7AF9ED80F -:106AB0001D0F7424F024E48F195F113E5B85E352AF -:106AC00038A7E6A576D43FE27BB31E8A7CEFC7F9F0 -:106AD0006E053A1AC9F27DF07C013FA720E627E84F -:106AE000DCC3D779205D73E715779CA7EB9445EA63 -:106AF0006A9E49E11409F83F497361F98713160941 -:106B0000E6E50A2B982FEFE2FAD1AC07A9B8E074BA -:106B1000C3FA798ACB8DBAD32C0FB1AED49706FEC7 -:106B2000FFDE59DAC83CE423AD18CABC2CAD04E63C -:106B3000D9EC66788ECDD346435DE40B98E7A9E5A2 -:106B4000B5E71D8C857609E3891FF421DC370371D5 -:106B500096049EC790A0B9CA408F256C21982790B3 -:106B60001C1F6E8E81F8DF26E2817353D97ED50219 -:106B7000FBAF8C07B4D550D69DE6F7E694123C7770 -:106B8000D99E47579B8E7974C06F7A7A9DCEE73134 -:106B90003D8FF125B5436EC963F39A06A5B0430452 -:106BA0001F756657E8F87076DED5F1E13DD0FE2A14 -:106BB000F8706E1EE3C379793DE0C3A579ED7CB82A -:106BC00004DA77C7870F71FE7BAA1B3EFC39A7CF7B -:106BD000E7F23A95A30FE54595A38C1E04BD031F6C -:106BE00082BE6FE0FD51F9B9321ABDF7802FEBF389 -:106BF0007A6017B6F7D743FAEFCCFE8BCFEFDAFE09 -:106C0000DB0279E3BAFD1EE597A7617E945F7E0102 -:106C100025E5972D8C5F54965F6EE2AF767D136607 -:106C20007202F2F3F4795ABFCB6BD737DB01CEE6B1 -:106C3000BC9C31267FFE3B9CBE9B7899103E4A400F -:106C40002E50B8BDA4A7D7E739BFF847B3BC53AAA5 -:106C5000D9CAC0AEDC778ADA91003E2E0FC66C6EC0 -:106C60003D007623511AE2E11EACCEE0D42B5F1535 -:106C7000F99551E144C7FF633479DA04787374B449 -:106C8000E7CDF8DA91C7E83CC4E1F15DE721E00720 -:106C9000F328C279A896B53A3DFF41445EBD0F780E -:106CA0001B3B3E2C139C57301EE227429E9201F460 -:106CB000FB911DBFFF24F2FD27B0DEB11AFDBE20FF -:106CC000F27D12B8F233408E51798676B286E71C97 -:106CD000EBDC8C1ECC74DF6863E724DAF1D5D00FCF -:106CE000F1E5557D5F42FF8D0A3B4FD258EF92D8B8 -:106CF000394196EFFB5E8686FC1A450E85AF520E33 -:106D00005DC843FB4CFB1794DDC9A1CB9CBFA91CFC -:106D1000FA3F681FCAE95A0EC5E7337839F2997C01 -:106D2000E94C0E25F076BDF225839F522787E2F3CA -:106D3000A3C8A107550687287C9A985F0CFE15CD3D -:106D400095CFF834295FA7D7E877C9D09F17BE4FF2 -:106D5000C5BC33CCB7F093384FB47D869AEFE86961 -:106D60001EB59A9FDA31FF8C749347BDE1D1900D27 -:106D7000E02DF29CC4B8E6FC6981C7AAA65523C8D9 -:106D800050C8D3BA3C08ECCAB347BE41FFC8DECCFA -:106D90004A0FACB3E5B55186BC2C31FE7DDC9F3685 -:106DA000412ED809FED973076DE8F79489FAD418F3 -:106DB0003A9FEA8356124039C5EE2910F130EBC1F3 -:106DC000BA56F0C75B89EEDE28DCCFA88940B7D67B -:106DD00083ECFE2692C2DEFB897D15DEB738DA1819 -:106DE000E74FD28C71FEE4F25EA6B8BF31CEDF670A -:106DF000B631CEDFD7678CF3F75F34DC14F737C6D4 -:106E0000F907AF2833C5FD8D71FE8CFAE9A6B8BF2E -:106E100031CE9FB3D918E7CF0B18E3FC0BDF7AD93B -:106E200006FBEA212FDC678AFF1BE3FD1420AD99E6 -:106E3000BAFB648AF6AE36B49F1762F7940D0BAEB8 -:106E4000357ED7C0EE39F0D3FF013CBF203E1BD0CA -:106E50009942C26FF687FC9680E409D2668BF7EE02 -:106E60002A817238F78B2FDC6CBC1F6171C058FF10 -:106E7000EACFE507210FAC1A9888F653FD82140873 -:106E8000B83BC7FBD2178CDF0B3FEF52BE9E73DCC3 -:106E90002838B745C6F3CC663A59F8D6ADFC5E3112 -:106EA000AD15EE8F107010F4E2E2F422E625E0B1A9 -:106EB000545E867C2EE020EED7AA32ADBFC37AF7AF -:106EC0006EC5EFCCEB36AF6353BE31CE473AF08997 -:106ED00083E509D175419C5CF6E79AF8C40887CE32 -:106EE000E0D753BE51391C62D28C7C13ABC699E9F2 -:106EF0000EF16D86677CAE919FCCF0747AFA45A551 -:106F00002F713F2AAE07E2217B25F2B4D411AE8B5C -:106F10009AD6D7F58F424F840430CFC30CDFE67C7E -:106F200063BC6597EA6B01F978FEA30B32E2D517D3 -:106F30001A01FAAC8BFCB383BC7D4FE3ED87F2758D -:106F4000FE1173BCFD2CE449EACEAB48ED78D34C7E -:106F5000799207FE0D7124FA8DCF067ED8728F9D2F -:106F6000DD1766CE5FF3FD331FF5B046D00F788E88 -:106F700078D6D0FED6387F3FA41BBFC8B1FC62963E -:106F80005F00FA6B6C3874FE25E85E6975C138D114 -:106F9000EE29359D3F3C0DDF77760FE4F3C49B4728 -:106FA000A2C4ADC5FE55D8ED749F74219FD9331787 -:106FB000A1BFF67D52BB7DDD753F228FACB352DAA7 -:106FC0002FA35E0D4B719E68F798C50E31EEFF75CD -:106FD000E73D6387E8F468D5F7CEBF09F3A0F07604 -:106FE0000CA1F3743AA97D23F5C8BE71413F4FC58A -:106FF00027205D87DF9203396EB8DF4A4DEC55D00C -:10700000F19E2691575803F73025C3F3BCC4AEF266 -:107010002FCA4CF76099EF33AA1BCEE695CED7392D -:1070200085DB5125BC2ECEA5097F5CF56CE66FDEB5 -:1070300064F263960C71627B6F665909ACBFCE2D0A -:10704000A1FD5427498678D2F1FC527CEFE1FD97EF -:1070500000EF15E3F93A9C578A691F7F8EB73F9777 -:10706000CFFA857BB180FE6CB21C159ED70D61F303 -:10707000FF3BB7A3BEC3FD34EFC78CEC783F8DF95F -:10708000FEC489B9352D201ECC71DFDF75773FCD69 -:10709000FB13A3C67F01BEF1BD22743F6388F19E3E -:1070A000C4609C6FC354F047BC237BB6E157AD234B -:1070B000F4FBB48A21CC2E5DC7F72D1057C2FD0812 -:1070C0002FCD70AAE0706AC8F45600FD6DB2B5DE2F -:1070D0000FF41BB4B1FB42C31F101CA7DF22AD1974 -:1070E000EAC55E15CF57D4B98903EE190A0FB3A0CC -:1070F0005F24C5E71A0FF7FEA66C917A0138855C0C -:10710000B02AC4EFA4F4B276881BF1B08EAC6986C5 -:107110007B5112B77C4DD2713FE11AEF0279348F67 -:1071200044F5733ECCE963DA33E90AECCB12EDD1D6 -:10713000EF79787888C863F33E04F431D67E6484AE -:10714000847A82ED43606B8BFF69B318CE358BF286 -:10715000BD8C717EF84ED0F3F532A9D9E56074A6E6 -:10716000BF7F6DED90ABF34F172F2251FDA8DBF9D8 -:10717000BA72546F03C0BDF87D15E31F0B85DC9F09 -:10718000672170CFE9ED9C1C6FDFC2F2E1C9E52BEE -:10719000576461C713EC9F403C62E1326700E21321 -:1071A0000B9BDC78FF1F592461DCA4BAE99017EA35 -:1071B0000B478E74A1BC8C9724B807124C08261F6D -:1071C00015725CD09FCC8144FB9FCDF50DD52BEB88 -:1071D000E2E9BA166ED9DA0CE72CFE410D08C0FFC1 -:1071E000267E6EDEBC2E713F5DE4FEBC4F36E9EFBD -:1071F000E7B6ACFAC707C6FBF3FEF1C17F737FDECB -:10720000BEDFFCE303B89FDB7C7F9EE0FB8F64DF87 -:10721000470FD37FDF4695F28AE1502A640EE229B8 -:107220000DD73983AFD3FF0D918EDB2370B9ADE954 -:107230002D84F747563A1E651E6B19038DF5A14440 -:107240008C2F8B7CA499F68609A0D7CFDAC28570E3 -:107250005EECEC6B1F0E84BC834F7F78DE097908EF -:10726000FF54C24E787EE291F79C1AC5EFA78FB00B -:107270007BB6EEE6FA52C0ED1F9C1E0A0BBC87815E -:107280001EEE59F96D89FEBE20B22215F5DCE280B2 -:107290008C292C428E2C7D211E2CB9F6FAF29DC928 -:1072A00086BAD07FCB63484D34BFA8AB80F1CDE226 -:1072B0001D5B6DFD5518DFD706E39F80C4694A3713 -:1072C00027F638D14E16F3A9DC31CC0676D53F9B94 -:1072D000624810F66B4AAB959D37D5A648945E7D03 -:1072E0009C2ECDF37CF3F578EC6FFE26266F2BE811 -:1072F000582B285C7D4DECBE4FF33AE67FAA4EEC4E -:1073000043E13DFF716AC1A8ACFD23146FBE153F78 -:10731000C2FC71F33A2BFCE6FB3D3594F70B397E4A -:10732000E7D61BDF2F6CFA31F6338FA8EB204F72B4 -:107330007E83F9FDA42F8048179AF2D16D055C1E5B -:10734000979051208FF7DB3312A39D3B15E5A9954C -:107350002E64A22F57DAB13CB192607978888A7096 -:107360005FD674E841A09FAABDBBF01EA696C0845C -:10737000144AD6E4C6A6DBF1FEDA1B79DCFCAE8E3D -:10738000F78BA6151443FE91E9BC375FF71C8E07F7 -:1073900071FE7B0EACB7109E2B17F4EB397730C320 -:1073A00001E3BAC5BA46D175C93D5F97588F589F5A -:1073B00078BF9CCACFA8F1704EE787B9BC9ED7387A -:1073C000ADAE1F05C59AD7BE40FF00E1FB92F6FBAC -:1073D00091ED3F6E85798F27A67D899FBC4F74F410 -:1073E000B69068783FAC99AE049EA9DEC6EFED7CFE -:1073F000DFD24E4F4D3F41B8087CC30D82FA7BA9C6 -:10740000285D19F609948E0CF5F90DC6FA196B680A -:1074100010F0FB42D3EF459C31E5D388D25390CE98 -:10742000E0A06A13E1DCD07CE2AD6379C7ECDCE17B -:1074300009A5E1CD87810F1B191FFC93E37F6781AD -:107440007716E09F285A21DE17B9BAAF0C171F57DD -:10745000AC935CC05F736B87E1FD43C38986FDDD40 -:10746000D589DDF910E7FFCA1A2BB15163A1928EBD -:107470000172AE728F2CEEFB724CED0DF7D7303EE1 -:107480005AFEF82E5B5F5A2EAA59C8ECA100E31BE6 -:1074900071AFB6A03FA19F96AC6B46BF03DD6F19DD -:1074A000F8AB1ACE8114021F9B9ED7DC8878A836D1 -:1074B000D945DF2BE0FB330FF1007DFA1E74DAE1D2 -:1074C0001C5977EB261DFD49E86F3A77300BEDE547 -:1074D00073AADA07DAF912D83DFE92E21B05CF292A -:1074E000BC508F8657C5E3BDC6472EC944C5FB5562 -:1074F0007CA3E0BC7FE8EF0309BBAF8DD1AB586F35 -:10750000B57D1DEEA3AB4DF45A41376CE027AED8E4 -:107510009E8C796AB4FFC2BD605F6DB7A2FDE4279F -:10752000F7A5C1BD1ADEC7D8BDBC957B93701F5FA0 -:1075300059CBE24B953B92F09C30DD47BF0FFE19D3 -:10754000818F23B5E36C7D115F6EBC2F8CECB5FA97 -:10755000F93DE748E7024F1DF7C1263CD537BF99F3 -:10756000A676DC17EBF0D4D6099E0CF758FE5AC865 -:10757000118E27F208973FF7BE910571B57335B1AB -:107580001E39CAFEAAFD3EE379D7623E9DF03F96C2 -:10759000F713BFAFE0E90D783DBFAE18F166C657EF -:1075A000F97FE6225EC8DF9D04FCD27765907BA65A -:1075B000D3E7F7488C5FEE5A33A91CF4F9810266D1 -:1075C0001FFF95CA2D2D879043546E69546EBD4799 -:1075D000E519D43F589986F50F57AA587EBC321743 -:1075E000CB366E170A3EA2846003BBF2AD0266EF93 -:1075F000BC5520FCC10FA4816951FE9FF78A2DE084 -:10760000EAF5CF9F3981DA3BB768467D387B8651F2 -:10761000DF85ACAE89707ED9FF38BB17AED27B9DBB -:10762000A13D5154DB34D8D7E78E883C477E536D5B -:1076300070FEFEF629C986F633EBFB1BEA470A54B7 -:10764000764F507986E1F91D738618EA15FCDE5BEA -:10765000A28E46BE7980E7C912329AE185E7DF5CE7 -:10766000A819D5E7FB74BE17DEB6E27B333E045E95 -:10767000E76D96898FF6377733955F748A6D0D14B1 -:107680004FF4BBAF3E72C2591952B763C4BBA36972 -:10769000FDC80E96AF7BA436F9A7603F1DD9919A1D -:1076A000007E635F9DCCED0C17DEF726FA1D57BBFD -:1076B0000AF3722A023178EEA2A2C5FFACA8C34F2A -:1076C0002EA089077CF3BE1C084A883FE6F7F875B0 -:1076D0000CC62D4E50BBCE45F5C40989D4420907CE -:1076E000C512E9FB7FB5A60680AFCBFF236B6940CF -:1076F0004FBF8EE5712909FBFBF250D6B6B5485F46 -:10770000EACE20F26F0CEE8FE686D8FA8834BC3FC2 -:10771000E0FF4412D192E82496DFF7E1670AC5D36F -:10772000E2ECD642B817678E3B983A8B7E77AAD1A7 -:10773000CAEEE9A7FDBA687DF96F62F8FD8F5A1F9E -:10774000D86F44E019288475A7F6F3A60EA5FCF1BE -:10775000E5824021CAB5475291AFCC706FB3F910A2 -:10776000BE7EE003292227237CC6E28D54B8F505AE -:107770007933D7EAE90DFAAA6D9D95DD8FA76809DF -:10778000ECFEC9DD48C76D8A3A11D6DD56EFC6FB5F -:1077900083C4B895EB648DDD5F49E912DAAF977D5C -:1077A00070DF8FD05BFE7AC907F70299E9E6FE7BAE -:1077B00047619EBFD9FE15E519CAAB3E9D1DB1E4D8 -:1077C00035197FD7838C0C29330CF783B1DF3F2128 -:1077D000BED186FCDB65E97FFACC6141BB2611F6A0 -:1077E0004527DF9791CE4EA63794A465403ACDFE4B -:1077F00092EFD3FA5753FDC7E11CF13D837D65003D -:10780000D7A59675CF4A1638777DECA770CFEE973F -:107810002F5A3D30EC925F2F1E8C71096E7F77944A -:107820005B9AB0177AC33D5115AA0BF5B85A2B11C4 -:10783000B6FE00CEF34EB2F331C09B6B197B7EAC2B -:10784000D8B916FC03734DE7D88EF17B3A660C6508 -:10785000F244E8FB0D4399DD34D7C2E89ABC2EB15F -:107860007BB4F8EF5F087D20E4B590FBF38632FB34 -:1078700042C86B6A39A0DC5A00B747D1752E7B210C -:1078800086F9D355E202382E6668225B873279B1D9 -:10789000C4F6E293C04B0B492BEAD32FAD8105AD63 -:1078A0006EF87E6B6D2FFCDEEA41FF32D72F70CD74 -:1078B0003FC8A5859CFF963748781F14E17A723E31 -:1078C000EF9FBC608DE88DF428FAC5A457E673BD20 -:1078D0003A9F98ECC006A3BEF3C6B3CDFE123A2E73 -:1078E000E8CFC8BCA8FD4C61B7C01778F3669CB759 -:1078F000E4094499C742120EC2BD58CB77307FBD10 -:10790000795EE675F4749E0B3CD3C6278DD48D6BDF -:107910009AB780373AB8757810705FE067F05CD03E -:10792000C4E21F9F737B4DC46BCCF85F48BC3743E8 -:107930003EE2C28D547EBA23F420E860F1AE00C668 -:1079400067BE220D090ECA07CB36EF9A798D0AFB66 -:10795000FC43B80F99D32B9865492224D97FE8C9F5 -:10796000F281DDC727FE577022FC7E71FC8EC26556 -:107970007E23BB3F5CD78EE7DDFB91AE17F9FD366A -:10798000F0DF2EE2FED0EEE659ADB073FEDDCF970C -:10799000C1F17F3DEF778776661F6545DD6FB5DB0B -:1079A00045DDE8E34FACC181A08FC30315D4471771 -:1079B00014CF87A529A09FB370DFD099BC5DC0F517 -:1079C000F27CD0D3B43CBEF965BCE7E9F38D2F63FC -:1079D0003CD8F6E2FC04B0978F6F9EFB53380771DA -:1079E0007CC75CD4CB0B9F167AD967D3EBFB719B1A -:1079F0002B9EFB21D0E90BB118C758D0E2E3F63833 -:107A0000DDD7805CA4E3A19ED8C8E4E042D05F0546 -:107A1000A8BF72A0DD830B7C3940EFBAE7A8D71E60 -:107A20009CEB1B85DF135790DDB3EA0A82FE12FA46 -:107A300055E8DD57FBFA2E0F053E92DFFEE0077496 -:107A4000FDA777CBE8D3592E6F1D04BF0FD3991C28 -:107A5000FFEEF0B6B4C3DBDD03785702BCD11E6283 -:107A6000F03E5ACFE07C6C1D837BDD8E8C04D80702 -:107A70001FADCF403BE8E88E2C84F7BCB514DE6820 -:107A800007AB463BA89EC21BEC7F80371DB7B245B3 -:107A9000E5F0F63078D7733DB48E95F33AC0D57FD4 -:107AA00037C895077F19E3C1FBBA6383A9B04F3983 -:107AB000B14B2690A7D16E27717B46C0F95FA4E138 -:107AC00059B0AB3AD837EB6308F87317FFCE89E7A4 -:107AD000A4BE944AFB00024E35FC2901C68B8CDF04 -:107AE0006ED7780A8B75764D0FF15345BC788EA111 -:107AF000AAE94F1F815D0FD72CC1BEBF4ADC8FB1F1 -:107B0000D7783F86A4824CC3F3B2763BD0C100F352 -:107B1000FD213EFCBD9C8B595FDF7D1FF273385BFE -:107B2000EF57AF8E0B5AC11F15DE2521BE973F5070 -:107B30009A504A200E5783F3985AC8F4B3A469E8C0 -:107B4000678CA1741347C7F3C265C2F05C7531BF7F -:107B5000E3163AAE33325FF3F39B4110817E7744F4 -:107B6000F753FF908FB35CB6E03E64998DED4744C8 -:107B70003ECC5D85CC6EB8AB90ED4BE616B27C93F7 -:107B8000B3903C45FB3D7B7D0CCFEF1E8FFE4F71CC -:107B90003F8222E0E652CE187E674209E3EFC07CC6 -:107BA00076ED21BC7FF733F8168D6B8A8012B06BAF -:107BB000D8F7EF5AD9BD2E778EFE13FA4D3F8BF5CD -:107BC000AA607F7D966AF7001DF9E11E3C4A7F3F5F -:107BD0008A63FE729292A8007FDDC1E5ED5D63626B -:107BE00034D04B778EF991174A3A8E1F821675A5BD -:107BF000071E033ABA27EDD8F7EC7449AB2CCC6ECC -:107C000059D58B601E511135DFC16F4B5FEDB992B5 -:107C1000DC15DD18FDDCCBC09F7B2D6104351AE13E -:107C200069A853B8627DC34BA5B3360E20E430512A -:107C300087029E97014C800E2A12D12F700BF89567 -:107C40007B41A9207D4D5788DFC2CA7A07DEFBC180 -:107C5000FCCC37F375DE369A0413E9FA826F118390 -:107C60001F7E56D012CCA170BB45093603FC2C7682 -:107C7000D50AFB026FB9341CF6CBCB56F76CBEBFEE -:107C80007A69CAAC8D6368DDC2F21CC23F90F09E77 -:107C9000963B2973035DDEAD90167938C31BD05D2A -:107CA000752F761F79F85E89C79398FF5FE0651896 -:107CB000ED5E0FDF3BF9FC683FF509F0BD2DBA5FC3 -:107CC0006937A753616F2EE57CBA54D0D90E237F54 -:107CD0001E167C02F62D85DB9DBCEC8CCEFFCAFB0C -:107CE000FF6B21F35FBD7695E32D8F2141FDEF56AC -:107CF00089716FE1E53B85CC6E16F310F44BB85FEC -:107D0000CA422506D0515BC31AB4971699FCC444E5 -:107D1000EFBF92A3D5DBE58EE50A94B6F03C988FD1 -:107D200074432CF2CB9DB69D59EC9E1963BBE50DB7 -:107D30008CFE973BEC68078AFBC5C53E40D88D8B0F -:107D4000C1DE037BBF91D9B70AB7CB2BE87E0D8884 -:107D5000CE4A42B5FD61DF5CAFB37F519E717FCFEC -:107D60009E613E18E74E871DE39F372F33DA4B564F -:107D70006E475A3BFEFE9D31AF84DB4BE6BC129949 -:107D8000F3316DCBF6313CAF44E1F6B0A0A30F0B5D -:107D9000ADDCAFE237C4F1E790562BBF778EF9F731 -:107DA000B89E9E203BF03E863912BB67EB6CA9D390 -:107DB0006FA172E9137ECFCDB91A76CE79CE0FD8E6 -:107DC00039DEBB121FBC19ECE239093605CA4FF87F -:107DD000EF7D7DEA4A4F9C4540FEC83CEEF4935946 -:107DE00010BF59037294D59FD2C6A0178DD79FF8A4 -:107DF00010DECFB84CE78DF50DB3343ADED937F845 -:107E00007B3FAD437CE831C1C79B597D9378BF85EB -:107E1000D51F17EFB7B2FA4F44FFBCBEDEF47E9514 -:107E2000E9FDCF597D70D1D6597EB0E379DC6ACEB9 -:107E3000B512C6AD34E0330ACF39AB83485F732C3B -:107E4000FB5959468210B7ECAEDDE422AF06FA5A70 -:107E500076B639C15E99314CC37AFE505F7E11C54A -:107E6000CF926992DF06F1CBF703D95C9F45CFC76C -:107E7000E7FA699287F527EC5FDACF88A2E2ABEFE9 -:107E8000E7A3A20EFD8CF92EFD34769CCF84EFB2D1 -:107E9000AED861C67E843DB86DB8E6837991F1D7DE -:107EA00019FC9C4B1FF524823D49DE65BFBBB574B0 -:107EB000F5CE412368FF4B5FDA376881CEFF5075FE -:107EC00049261A95C3D597242CBF6AFED806F74BCE -:107ED00054ED69B64D2C80DF0B6AB68DD3CD6B990E -:107EE000C833262165BACE9E995F64E17CC57E7752 -:107EF00068E94B2731FEBCD4B2F3F8D3C097D73230 -:107F00003FA4797D53F9779F417E4194FDCAD222E7 -:107F100026879F1EA92D01B84D0198D1F6E3D644BE -:107F2000CFD3D8C3FB9B13C7E4FBDC12A75D2D8224 -:107F300078B86F0D9CFF5BB0C53D1CFCDA5387968B -:107F40003D50D4A57F38CCFCC34DCC3F3CA757EB6C -:107F500003547991DFFE36F814DCFB3CF929D21E7C -:107F60004F06BF2B1E8747BEFB70D6F831E8EFC324 -:107F7000FA1345879E82F3DF07F9EF31DC356A6833 -:107F80001CC885903BDEE2A2FC3CA3A0E2B780BF08 -:107F9000BB465D3F119E97C638B32B589C01E962E2 -:107FA0004681772DBC87F6E0DFF1D998BFCFF76720 -:107FB00019FD7DBEC2785FB4FC857A0E87DF16B1ED -:107FC000F31B072D749EC323F310E35303ED815677 -:107FD000DA5FDBEABEC3E09CE5CE82D297909EF8E2 -:107FE000F83B0B7CBFD08F0F1409CF7B3A8FCD4568 -:107FF0004C9FBEC4F1E61D43E94D27F7A78F8F378D -:10800000D4674C49269ADEEF3CA3BFA13E7B4E8647 -:10801000A1FD1DF38618DE4F8D691D597315767FFE -:10802000B5D31907F9119F36FDEB6F77823DDB2839 -:10803000E3EF172D7E6DFBDFE0F7BCCED10527A364 -:108040007DAAA2FFEFCB83EC775889A229FA38D614 -:1080500069D2FA24C47D75F191A8F163111F59EA20 -:108060006AC13CCDFF368EF56E118F630D87D475D6 -:10807000D0471F0C823C952A075BD7E97D47F0F774 -:108080004C20CFE34A09C47F091A89D59756E1EFFE -:10809000C88DE3BF275D5DC4E473D5807B15B8B799 -:1080A000A09A9620FF2752399548E9A4B5990CDD8E -:1080B0000379DB6E27E6D52CBF742BFAF50FC6F9D2 -:1080C0000BEEA5ED96D64FC27AD5A578ECF7AF7238 -:1080D000EB44CCCF7F45C2F8C9D4FE77AD86F943D7 -:1080E000FBFBE978537F7B6339C0A96A0FCBBF994B -:1080F0002A1F1E09FD2C6B9884DF4F95C94189DA30 -:10810000498997EEC47EA7828D43EB7289732DE86F -:108110005DD916CCFE05C8159B13E54AF5A558FC9C -:108120006EF238A69F2F16B17D8B35C4E635E1D2AD -:10813000347C2FF07FB928DD709ED49ADAA8C07DF8 -:10814000ADD69084ED6FBA34044BB1CE3FE7FE124A -:108150007F9FCC9A7A6122E4DFFE394572A1D9650E -:1081600092BBE76B4625EAF7D3FF0F762BD097003B -:10817000800000001F8B080000000000000BCD7D78 -:108180000B7854D5B5F03E73CEBC9299C9E4C9843E -:108190002470024908106032791042209310109127 -:1081A000C000550906199047401E21BEE295FB67A5 -:1081B0004212088216B5BF45453A205AB4B6372256 -:1081C00056DA224E006DACFE366A1F786B6D502F6A -:1081D00082458DE0B5F416E5AEB5F6D999394382FE -:1081E000D0DEFEFF1F3EBE9D75F63EFBB1D6DAEB3C -:1081F000B5D73EB978117ECA19BBA895E6F332F31C -:10820000263276D37989790B18FB3ADF9BE04E66EC -:108210006CD6861EC592C418B3599C4F66025C92F8 -:10822000AF2ECF0BBF271FA961EA18783FA9D7E867 -:10823000B5C1FB504EB185EB1731E6ED0098B11E8C -:1082400065AE3DFCDCE53630968CCF9B192B827EEB -:10825000FBDAFD8CB114C66E7632FED3088D52194E -:10826000336AEDC5FBDD12D4C1BC022F98834FC227 -:10827000EF291EFF6837F4D35DC1E6EFC77E94EEA9 -:108280002173ECFF73F3AF9699454AA0757871DCC2 -:108290005925AAE15EE8CFDDB78E0095DFB68E0CDA -:1082A000ADFDAF65D6D801F3F8757979B717FAEB5C -:1082B000BCA7A04056C3E356B84D8417E6ECBDC03A -:1082C0000A195B773856BD17D6590D3442B8F725D1 -:1082D00073704F263D67521296E63D12D4AF73F489 -:1082E000E6F860FC292F5B436C2CF4FBB25561303F -:1082F000CE1B85FE0AA4E794974754490E98E421C3 -:10830000B3C2A0DD75E3BC9588B781E67B318A4FA7 -:108310004429D6CBAA261A583163B759F86BD3E64D -:108320004881B838C6FCEDD73206735D7C7E1E638B -:10833000C04F4BCEC712ECDFCE9F9FAB1F340DF169 -:10834000786E034C1AD6B1648334E600AC8BA97600 -:108350007736E0A13A6DE146E640BC1B68BDD5A387 -:10836000E3832DD0F4BA29F680218EE8D185F45824 -:108370007D3E9EFA5B733E93C6597B3E91E075E766 -:10838000AD542E393F9A9E0BFEF6217F437983C769 -:10839000BF1EF151DD72CD741CC7BF31B5D06F8BDC -:1083A000E4179313F90AF8C5B53C821F5A3A815F66 -:1083B000ECC42F8A17F0EA8332925F6623FDF31034 -:1083C00013CE692930EF59AD99867B59B8FE4EA47A -:1083D0007FD195F3FD2D1ABF2CB185B20DD09FB181 -:1083E000DEEADE08F33A9BA44E43BC346CE1F86B42 -:1083F00030FAA6D861DE0D8F486EA00CBBA5D86EF2 -:108400006180A7E2E3F5267F04BFD79C1FCB54C051 -:10841000C7BCF35954568FF1B722FD179FBF41A334 -:10842000D3582A995A62C0F9DC8E74557142259C42 -:10843000CEDAFCBEAC1F3FE82E18FFCB378C545F62 -:10844000E40DDC8CF33106CDEEDD309F5356BF8C4E -:10845000F43D95C19C0FC1144F1959C009F4BA6578 -:1084600087CC02D0FF5228FD509E8A67DE780FE24B -:1084700013D699CBFBBE08FFFF53D93E840D07BA34 -:1084800036FCFE7D6518632B73BAC786A0DFDA8AD7 -:1084900050F28DD0EF99BD467700C65DDDF976B11B -:1084A00001EA3FC9F40E6232A06AB07F17D275D5D7 -:1084B000DCE04F8C00DF7ADFF38E096A189F1D4ADB -:1084C000285B81F73B008F019857C736797A90F087 -:1084D000CF62E78C09F3B5E0E368FE5E757E38E1B4 -:1084E000E75CBD79CC01E45FE0577CBE46E3F35B1B -:1084F00091EF890F39BF0B3E5EA37079B5C6161791 -:108500000CC03A8C3DBC5DF5BF01FF01CAD71ED837 -:108510007D7F29F2DD1985F87FB5B64FAAE5B9BE92 -:108520000ACEFFEE1678FE62930B9015E6FFA9E7E0 -:10853000E750BBB8F337517F82EFA3E579C4BE6142 -:108540000CDE7B31DFFF16E2A9F2477F7BFEDFE125 -:10855000D10C2594F358129676E29F7F96DCFFDDCE -:1085600055F2FF31ADFD74335BE4CBE3723DB2BF36 -:10857000144FE5695CC7676E89CBDF7FB2BCFFEC47 -:108580002AE5FD1FAE50DE4BF95CDE47CB7706FDDA -:10859000A17CFFFCA5914194FFEF33D007A8F70E13 -:1085A000C5AA4F6AF29FF4434C5CF072F2FFD1C24D -:1085B0005BA4FCFEE5BF21FF1F90FF7FEF3E11FC97 -:1085C00018BD5FAEDBDA4D7A81BD283194BF62FF02 -:1085D00074C570BC748DE27A20BC6F24DA570CF637 -:1085E00055B614B96FF6DC5F8AFBE6F324770B1BF4 -:1085F00078DFDCA4ED93459A5E10FBE3D17C7F61CC -:108600007EC4FE58BD3F5A3F5C9EBF6E4AAA67A813 -:108610001F164119C95FE63EFDA0DF1713F2AF6ECA -:108620005F8CD0DA7F1B5FCDFCE7F3D5CC01F8AAD5 -:108630003A3FF9EFE7AB687E3A57FFFB4215E67326 -:10864000AE10F82833CC3FD7BDCEB8DD30DCEE7E9F -:108650009245F0892923D882ED2EB27AC463B43CC6 -:10866000147CBB05EC009CA7A07B574C206F7DDEE3 -:108670003F4FFEDD997F7576EFD2FC2B931F9B91C8 -:10868000CED8EFFF9CBDF8607F74655E6E1784E9FD -:10869000629E47765C08149C34305D8D3BF8FE1278 -:1086A000705B48117A3711F52EF0CB43FF08BF54A9 -:1086B0004F815F0723FCBBF9DE74E8EFBB1A1C781F -:1086C000773ED2E7861251FFFB1DDE2C9433F06B10 -:1086D000298DE06516C2AF061F3F5E85FCFB505F2B -:1086E0007D00EBA796C569EF332FBA1EA2FDFEFCF5 -:1086F000DF1EDF46FB793BDFBFFE1EC53726022E9D -:1087000004D81E019744C13B797B87D2C39C848FD8 -:1087100020DFAFD0BFE4E1FCE38BB04B8092D3E22B -:10872000D1AE3C2039EF05FA2F28FBDC84F40AAFE8 -:10873000BF87D6BFF690A4C11F1DF70269161CE0C3 -:10874000F0F1FC533B028AD61FE079B58666738749 -:10875000E495818EAB4BA4E0B0CC4BF17CBC4F3E9A -:108760008979802AD6BFCF4C8557F73EEE6F7A7F46 -:1087700018BD1F325FC5F83796316FD07669BB538D -:10878000A2DD058045FF80CB79B0BE60DEA5ED7B24 -:10879000B5F6DD068386AFAF7720FEBA4D029F1790 -:1087A0007678CB80FE8CC3FF957F617E208F4FDF74 -:1087B0001BB5FECBCDFFBD7CBDDD803FAAFEFDD04D -:1087C000E5F0F7C125F8D3F8A74ECF4F718AEFD85F -:1087D0003998475C92E444FB78ADCFBA0DFD803008 -:1087E0007F986B703DDD56D6C7CF7AFEB7D454C1A3 -:1087F000FAD632511FF308F93986BEF67C3FF4F100 -:1088000017F3E6023FA10980EF2779AC8F046C448F -:108810001FAA2738EB32FBA1230A2E8BDA3F1AFF5F -:10882000D3FE45390FF8C9EE47CE1478387E3E9511 -:10883000D87C9493DD95DC5EEC1EC6CB791E89EA6C -:10884000277A381DA66865774C041ED2C374869FAC -:1088500010FA2311EB263CD52469EB0E8CAC990958 -:10886000EBEE4EE0F5D5FBB31F099485E1E8FE661B -:10887000EF1F59837CD3D77F60C4BB88D71A0D6F95 -:10888000F3F6E7BE1BE0F250C27DB9861804A87566 -:10889000400AC8B0EE35C817FDAC3BCD73C9BE0A5F -:1088A00044BDEF355EE6FDCC4BDFF746BDCF8C49CE -:1088B00057F3BE46B79951749D1E45D7AA28B8569E -:1088C000C0419DFC137271C9C107DA52601EB7EE38 -:1088D0009350CD44F07309F1F3AD4EC1BF13DE45A3 -:1088E000791FE6E75282E776087E9DF808CAFF39CD -:1088F000280F4BC3F03C94170497D578C745EA8BF3 -:1089000049547F63BB683F99E005ADA2BFF2475071 -:10891000BE0A3A02FA6A70BC9A42A12F2ADEC5F654 -:10892000AB0EF1F737792ADFBDEC7ED81E85979D17 -:10893000517020AAFDF7BE45BFB446BDBF21AA7E37 -:108940005B14BC230A6ED7BFBF78A944FB7031F01B -:108950000312E2DBF6E5C39E3E3BB54F9F4A36B2BB -:10896000DB74FBEABA160E073DB36BDA6D11F07ECD -:108970005F8D266F695F1819FF01591B407D651CCB -:10898000405EDE3F105FE646EB5B5EFF27FC351581 -:10899000ED60A6B30B8ECA7AB853D6E61DB8F9DDE2 -:1089A000DBF3F0A18017D6A07F70DDF7F5EB02BFF7 -:1089B00055ABBFA9A6AA2CC22E6137119F88758A14 -:1089C000F6D3BEBE28E3783FDDBFA0662FD4D756CE -:1089D00086B2EBB14CE025E83519F5E63A2D2E3399 -:1089E000ED25D9877AAD362694DD106987B08E1CC7 -:1089F0005C67E73D32D127D002F4C1381B739B304E -:108A0000AED21917D7F814B43F7A8FDC887AF4FD08 -:108A1000C6C4149C7F6A01B7238FC60D4D590670DA -:108A200067EC22930AED3A374FA5F288ECDDD40BC0 -:108A30007BED379E5535B691581F47F8E9DEBFAC40 -:108A4000A619F6C13B1E95DEF72738530EA2FD7C12 -:108A5000AF913DA9E27CDCBB886FEE33E7A31FBD7D -:108A6000B879740ADA934BFEF79C69A9D06E499BDA -:108A7000D12D513B3616E7EDBF77AA09EB97B66AC1 -:108A800065E01A2A5FFEE6891607B4EF7D5C72EF97 -:108A900081F693BEEC787D2CC02BDA87BB913487AE -:108AA000CF1B9813C6F960C788A00CFCF8A1B5FECF -:108AB000D559BC3DC3F62B2EA86FCE2AC4F6B2738F -:108AC00023B43F09CFD11E3EB945DE23E1BC1CF6DD -:108AD00018099674F26BF54DB46BA1DEB9119E9F27 -:108AE0006C5B998276D649497548B0FE5E4F638DBE -:108AF0000BF865C50EB346BFC6D4C5B0AF171BFA99 -:108B0000F885F4C7F2780EF7EEBFABE64998FFC9D7 -:108B100047463810CF6B0BBC5F78501F157ACF7A61 -:108B200092719E5C4FBDFC8DBC08EDF15F9C59922B -:108B30008271BB0B1A1F1F3EBF24654984BDB3FC65 -:108B40005385E8FEB249BD1DE7F9724C8684F12CCD -:108B5000A07B22C6BD976A7E26F06FE3F3FDD83D69 -:108B6000BFF7C844A78FCC8DEC43D8549D5BAF9F13 -:108B70006207BC74BE28111D96327F0BC2ECA0E4C4 -:108B800046FA45BFFF9BB195D682A248FEDF4272EE -:108B900096FC0D80139FDF44FA906D800713A03C74 -:108BA0006A253FDDF8AC3568057C2E4DF24EC3F6E4 -:108BB000CCD59133D71EB14FB5F67F0CD8A9FD1F88 -:108BC000A13DFA7B7F0CFCC1CE6C97DAFD2B1CF625 -:108BD000001A1F1FDBED0AD2ED7DA5E9E4DDF0DE12 -:108BE000F2C78DA427963F9EBCA117D701FC95CD57 -:108BF0002E5D87BFC048F81D70DFB2EFD754E9FC87 -:108C000089872FBB6FC7143C5CB3376FE07DBB42D5 -:108C1000F36BA63D6EF4E1BE5B51645718E89BCA46 -:108C2000C75F7912F7C78AF5568F1926BEE27133EE -:108C3000D1B7C76E0F38A1DEEFB02BF1504E2CE04C -:108C4000FCB0B040A5728ACC148B87CA568CAF9EFC -:108C500085F924027CBAF1A187C7C3389FB0E00D23 -:108C6000E3017F6791508097B307648A3F32C5ABB9 -:108C700054833CAD635C8EAC79ED795305FC5A5757 -:108C8000BF6226FA812B83C60F7A341FEFA2B64C3F -:108C900094BFEBF823D0C3FAFA756CDB17F2586275 -:108CA0007B13EEDF351D51F5F5D77C8C719C754C2F -:108CB000F9A047C479611EF30AEC49274703E06134 -:108CC0001EC0103B5B6FCC61B0C41536D887B0DED8 -:108CD000293B797C6745A31C3443FB29893C5EFC16 -:108CE0005113D07F04AD3BE00478C5F7B85E5AC19C -:108CF000A4A0057EBD66E77A05F7CF2B1E8EA7C51B -:108D000012F3E17EF8D0EA1E82FEFDF2C7AD84DFE9 -:108D100015BB56FEEE1178AFA7B93A29D29F5EA9CE -:108D2000F105F4CF2C09E17E3E6EFED7212807A77E -:108D3000FC00FC6258EF8A78F6939A4CA457EA102C -:108D4000D5166EB762E33D39BC1DF8D5B0EEC55BF4 -:108D5000641EA77AC14C7A1264838BE4B886CFA5CF -:108D6000ADAF994C7928D7B775CBD0FE0380651B82 -:108D7000E12BA0E1D184F85A84EFA6F2775CC59A82 -:108D80009DAE92DCF1E3FA6A0DD2A2B9A4077A4D46 -:108D90002807BE5FC0EDDE6D5AB97888FB668A434E -:108DA000DF6F76A35CC31F59CC03FCB03586EEE5BC -:108DB0001807663F35533C655DABD56B75909FE2F8 -:108DC000DD8FF3539862C2731795CB97EF6B7CB826 -:108DD0004E9D730DF20DD41F57A07E8D9DCBD135C6 -:108DE000F180776ED77A0D30CEE7F8DB70DE6FEA70 -:108DF000D888F125ED39F4A33AC2FD7619583BC65F -:108E000065B0FDC8B188C7C41BE6E3FC7E2CD37EE9 -:108E100086C5DF5F8276E18FE502F487176F393A06 -:108E20006D07C2CFE53BB1CBC53F7987F4CCAD1A16 -:108E3000FD7BD03F40BD03F073507668FBC92FF334 -:108E40003851878627C107A27ECD16238FDFB799B9 -:108E5000C9EE59D3FC7BEA778DBD3B05E5F59A1742 -:108E60008CC528D79FD7E6BDA439A3EC38F0D5121E -:108E7000639C538247AB03D52684576F97080EBF78 -:108E8000973C04F9F4CFAD2F3A907F3EB486B251AF -:108E90007FF5AEB7BAF7E002B438DD9F5BB3F76099 -:108EA0003C67A9B3DB2E41FDD2DB8727A0BC7FDF67 -:108EB000193261FDFB1D990684BD4E6719C25E65BE -:108EC0001CC17F0651D6A1F9ABC86F6B254EE7D503 -:108ED000CF1E350D83F18E17F0B8F9A73F7E270717 -:108EE000F5DB9A21DD39A887800F72D210CFCF48E9 -:108EF000A4BFD73E2B7BAD63C37CB016F900F6DD73 -:108F00002A8D0FD61E78F12EDC0F6B91FE9E4BF949 -:108F100008F8F4183DDFBF7B1AE3EF1F433E117AD8 -:108F20000FE05623C6DF4C1A0CE320FCAE864FA898 -:108F3000AFE2F581BC7A1E5733A19DBAEEA031D0C5 -:108F400013716E34109DBF2AD0CED19ACD2477BF35 -:108F5000D2D6DDB3E50507D2F1D31F1F7D15E3C5DA -:108F60006BF6837657FBD9171A5ED6211E1CB40EFA -:108F7000B247D6E1BA1D613CF4F1BFB61FD731BE8E -:108F80004EB1EE758A860751AFBDFF176D9DAB9947 -:108F900086B70323F8FED3F61BEE6794AB627DFE23 -:108FA00004FEBEE0D3F442BE3E6321E7D7D5C0172E -:108FB000EE3CE21FAF49C809A8FAF4B9DD142F123C -:108FC000F412F31E5BA80A79E78D4F08D3B1C7C02E -:108FD000EA3AFA89B3241772FC9D681B34E420E056 -:108FE000EDCFE097A1FD85FCAA448C27F8468C378D -:108FF000E5477366E07AA1FF10F62FC67D3F10AB00 -:10900000603FEF33BE3F903F517E8A7D39A565E1D9 -:109010008C7C07B6FBD43E3C0FD7CBC71F5BE8A4C4 -:10902000F7BD682FC0FBDE8312C5AB4F687180139C -:109030006D2F3A9644E0294F7B4FF019FE601C4B90 -:10904000CCB72B81C77FA3E72DE49098F794CD3759 -:10905000CEC0E762FE825F057F0A3C0A3E651B9236 -:10906000C9AE89E657E235A157659DBC27FD784D0D -:10907000FA1726BFEDD2E7D1709FFDD4EA3A9615D4 -:10908000A1D73FC4380FCA93A7E520C913065C1BBC -:10909000A17784BE6F5E7F8D13CF198DCF4A6E345A -:1090A0007D22F4CC362542CFD415AECF417DF6607B -:1090B000E1302EF793BCA7919EAB4F754F73A8611B -:1090C000FB75D29721390EE36107323D917A75F530 -:1090D0009963B40FD6B0EE4DE87F2DDEF24EF578F1 -:1090E000E4F7A78D74EEB9B86DAA09FD81954FDE3E -:1090F000528CFCF441FB7092EFA7F71615107F31EC -:1091000067CA0DB00F96EE7DE88605F07CE941D97F -:109110004D721EFAC1FDBBF88E0226D1BA7BAAF1B0 -:109120003CB5F76ED98976FFC4278B3660FB89F68C -:10913000A1F1B80EEFDE4482BD4A1CE909612FBFE0 -:10914000AFC9CB1623E78F0DDABEBAADAFE4FC335F -:10915000A5A52507CFE37B77839CC6736993DA11B6 -:10916000C2F15E1A447EC93A70A35C40FF5312B745 -:10917000CFEA4CCC92EAA1E7965478FE9AB1FB0E66 -:10918000D427AFDD61CF6FC609C8178A97707F9269 -:10919000E60176348D2FF026E6714F21D74FD1FDB1 -:1091A00089F7BBD0FF40B9AACDFF74EBD337A03EFF -:1091B0003CBD2F3B01D7FDF14BD676B4AB3E3672AA -:1091C000F9D867EF048D1F45DA6B60DFE960B0E71F -:1091D0007430F0F1477AFB7023CDEBBE429BCE9EFC -:1091E000137C5FBB3E3B2E320F21DA8E6759D1E7ED -:1091F0003DE3E3583F724794679A0051C0A873D08B -:10920000B68771AB62BF7EBE1BEDFEED66A719D6B9 -:10921000F911F23D9E67BD2007F1FC066D74DC0775 -:109220001F3D971F44FF73F97BFE69D8FFB10736D6 -:10923000539EC232B033074911F6F3F71EB801D975 -:10924000FFACDBBF2915DE3BBB8FE75540B52DCA10 -:109250006E7E3555FDC7EDE62BB597459CE2E7855B -:109260009ADDEC666EC4B3C0AFF09F5E063E28F197 -:1092700084F1F559531DD9CB679AFC547E2E9DB8C5 -:109280007F22F2AF3DCEBD075EFBC5C187E434A4AB -:10929000F381FC0BE82F97DAE29CB86F3F6B6AA46E -:1092A00043CB334DF5540A3A8B38DDA4039DF4DEED -:1092B00067070B0E4D84F70EDBE2B81EB8E49C88FE -:1092C000D3333A8FE4B6F5E307E173B1AE4FEEE680 -:1092D0007415F3FE64DF2D0E5C57E7638987262043 -:1092E0003D63E39C68F7ADD0F2474EEEE076F5299A -:1092F0004BDC533331EF64E7BC1406F27659E77761 -:109300006EC0E7CB5F929CE80FB85F9AE3C078EB42 -:109310007F283D0E2796F05E08E7A304659447A5D5 -:10932000D3199D63958614A666D2D130F1CB8433D0 -:109330004A10F34EFE8CE75B1847B910437114A630 -:109340009D5B2DFB198FBFF4F9B99A9F37515B775D -:109350004A5102E76FEDF99412FEFCE39DCFCFC2B4 -:10936000FE4EEF353A71DE9FED3552FFABC03F3315 -:10937000C07C4FEDE37ECFAA0E89FCE5D3FB406FA6 -:10938000C3BAD6AC377A4D7197F2E114A8EFB18524 -:10939000F970953748FCCD347EB4C0BF8BC32EE541 -:1093A000C778D6B109F1F18FF2A5AD48EFC7F5F155 -:1093B000E3407CA0E10BF731F2A3A0F72AA00B9EBB -:1093C000CF2674E457205F09FA0B3911A864B9A8B5 -:1093D0005F5B4C2C17F37802861837EEEF3936D5E1 -:1093E00028011EE625F554A138BDBB88CB49798AF2 -:1093F000C16B40FDD2622639102D47B28BB8BDF447 -:109400002CF234FCAF2872723B8AD5933F224AD0AB -:109410003B19A8C7E7C426FCA70A4D3C2F7C7F81D7 -:1094200002F39F3331E18EE16EE09B171E5FA000D7 -:10943000FFCE2948786118C065453B393C2EA1C84C -:10944000087073F3AE055500D71479DD45C9E17195 -:1094500044BFF0BC009FFF7CB4BF18CB75261BC96E -:10946000E9CFA5DEB18D99E1F66F49ECFD5F48616A -:10947000B8C7C886A09D57D137FFFECB8D45DE7299 -:109480003EAEFEF912C6DA28FF2EF0CBE312F7C784 -:109490007C9614CA6323BE5A62B185C8AF6F379EEB -:1094A000E9A337F2913B4E41BACED2F868B612EA40 -:1094B000C4F747B256E7490B99523B2F260E2CBFF3 -:1094C00061E3B193A23FE097CF8DB05EE06B09D826 -:1094D000B311B68C0448AE05F9251DFAE55FB1DF7E -:1094E0009600EBB1121D6A9DC86712F31B2E42B99C -:1094F00026D63116E3276B62870491EF1B5EF8F4E2 -:1095000018B2D74A61BFF84B88DF6F77F2F5307F2A -:1095100029F1E31D1A3F7EDCC4EAB360EBCDEEEE29 -:1095200076A830E933B34239B8DFFF34C45F5784DB -:10953000FEFECE96F406E09F4FF79BDD33A1FDA91A -:10954000E0F314BF5BADD9A56C6FB2B6EFE550394F -:10955000B4EBCA1CB907F54B4311D7D76732434365 -:10956000EE41B991C9FD2068477972D3375E938C7B -:10957000EDCE3CB7396B19D0CFACB0803D814AE617 -:1095800080755F0B7D97006C0458A673E020D10BAB -:10959000DB3950DFABB7B8789C9EF950AE087A093A -:1095A0003A5C421F9802DAAD060B33E2FC47B29DEB -:1095B000CE93B1613A7D6C013C621CCD027884FD92 -:1095C0003D15830F85884F1E7769907A5A1311FED7 -:1095D000B144797797EAC1274D88F2BA9DB790FCDC -:1095E000117247857FFDC99DAB8E1FED9CD2AFDC0C -:1095F000790CE50EAC83E5B3FC8BDC4024FAAED0ED -:10960000DE9D2AD7AA0ACE3BD9E2C6B85AC3E3C325 -:1096100049DFB00BBF217F58B4633B13895F3665C8 -:10962000CA84F79507259E1F79308DA95035F360C0 -:1096300022958EF3A9F4FCF453AF1772B9C4E95222 -:10964000FDC3419594AFFAC311548A7934687C37CD -:1096500055CEEB08A11D61837900DCF01AD75B0DB4 -:10966000D7CB14DF6428A2539098FCC7676BA73848 -:10967000908FF5D9F9D245B2DFD538A48BAF4B66C0 -:10968000C83FE07504389E2DCD8867B3CBC0D47E2B -:10969000EC0FB34627AB1AC3D408FF43098CFC6E0A -:1096A00019C665BF637407A1BEC5EAD883FB8905E7 -:1096B000BCDDE847CCD7DEEBB672FE88CD4DD0BD21 -:1096C000BFD931AD0BF96DBE97EB1DBB7BB06E7C86 -:1096D000B3BCDA884CC6FCDC5E14FC407C09E3CEEB -:1096E000F649A45FAF9F0FF511FD1ACBBE20396E6E -:1096F0002CD3DB99669FBEDD1F84DE19C94646D296 -:109700003F8C779B17EDF4B35E3BF13168F7EF9731 -:10971000017C439791E17ACD317C5D671153181F2D -:10972000F5CA418C9B6C463CC0F3B8123D3EE3BD8C -:109730007AFC254ED7E323D9A75FFFA0F9C374F5C0 -:10974000A9FE51BAFAB43A8F0ECEA82FD5B51FDABA -:1097500058A98333033374ED87B7CFD5C1D9DB174D -:10976000E8DA8FD8B144573F32B84A573F7A5F831F -:109770000E1ED3F12FBAF6E30E6ED4D5E787EED5E1 -:10978000D517743DA8838BBA1FD5B51F7F7C8FAECC -:109790007E42CF33BAFA89A7F6EBE049BD3FD7B591 -:1097A0002F3F7F440757B0D775EDA758DED1C1537F -:1097B0009D7FD0B5BFC6F5A1AEFE5AF5CFBAFAEB84 -:1097C00072CFE9F93586CBBF6AF7DF74EF7D9EE68D -:1097D0001F558C3A533EA320DFB62C945822C6D591 -:1097E000BBE659500EE4156B7248E3C3E1453C2ECD -:1097F000C1B2D810946753E5990CE376673BB87F04 -:109800003D90BE8B0375A5448C1BEFB58003198674 -:1098100013A73B7570B2CFA56B3F68BEAAAB4FF5DF -:10982000E7EAEAD3EADC3A38A3BE44D77E68A35716 -:10983000076706A6EBDA0F6FF7E9E0ECEDF375EDDD -:1098400047ECF0EBEA4706EB74F5A3F7D5EBE03114 -:109850001D8DBAF6E30E0674F5F9A1765D7D41D74C -:10986000761D5CD4BD43D77EFCF1A0AE7E42CF3ED8 -:109870005DFDC4531D3A7852EF415DFBF2F3211DAB -:109880005CC15ED3B59F62794B074F75BEAB6B7FF2 -:109890008DEB84AEFE5AF5B4AE7EF59FDD213A071E -:1098A000F8053F57BB2EF70B5DBD3109EC5A8C43D1 -:1098B000B218379E5F0AFBA7DAFD575DBFF7160F98 -:1098C00023FB0278A9C72AA37DE4A3F85102261638 -:1098D000025FC6811043BE4257A196E25049A4EFF1 -:1098E0004835A99827047602000986CC4CB4A763B2 -:1098F000C3765BFAC5822BB7DB76409F388F5F1645 -:10990000FBEF2B4E467FE5B96968B7AF64814D38F0 -:109910000FD07B713DB03FDEB4EAE319A2BCD602A2 -:10992000F88918EF35EBF674CF65FCFE6B2D67A850 -:109930007D5FBF5A9C4382F53544F47F3FF8150A9A -:10994000D875DB9B60FF80C3F8609393E0EF35B977 -:10995000087EB849A57247532E958F36B9A97E6700 -:109960005309C1BB9ABC04079BA653B9A7C947CFEB -:10997000F736CD27F829F0A3B1DC077E3596CF80E6 -:109980007F8CF5CF82BF8CF04F9A02547634B5D3DA -:10999000F3FD4DDB093ED0B483E09F3605A93CD8EA -:1099A000B48FCA9F377550FDA1A683041F6E0A119C -:1099B0001C6AEA22F8485337C1C79A8E13FC6A53CF -:1099C0000F955D4DA7A8FC55532FD5BFD1749EE0D0 -:1099D000335ADCF6956249776F4AC08C55113F08BF -:1099E000FB7016DAF9C81C25C6CF74767E94BD1DAF -:1099F0004D8F4FB4718C95602E62FC7070CE9E9628 -:109A0000083FEB2D6DBCCD312C6005F9D66CE07EA6 -:109A10006D7302A33C6EA6D9AF2B34BE6449DC6ED5 -:109A20005DAECD6B85C6FF45C89FB9C49F6F5C8D89 -:109A30005F21FCC65163FC27883F330C01F29F6D08 -:109A4000C11CB49FABC7F83F42B97EB67ED9AB34D8 -:109A50009ED34DE78FD5E650F28D181F794DA6782D -:109A6000DE40E3ADD3F2CD07AC3F7C3A1DEDEDE92E -:109A7000DFC87EC4D39B46FB7C8C17FCA598FBA754 -:109A80007F2936E8CA77C6F8BFC2797E65AFBFD9ED -:109A900000F3FF6AF2FAA76ECB0CFBD3B3D1250516 -:109AA0003F680E538D94D7C8BCAF644257D78381AB -:109AB00085F08D2C40E577F2FC17715D35608823C9 -:109AC000EC2F350FE96F5DD1F38A19CFE71533DE3F -:109AD000A02BA5B17EEBF8229C9797E6F5E6846B68 -:109AE00072705D625E956355ED3E44EF2E9CDF57CC -:109AF0002F7D71521A1EC6BFF0DB375568F928EB6F -:109B0000251E9713F69A96CF22FC8EDA3BA420DA14 -:109B1000EB0BC1DFC173A6F734FBF33D2BD7CF6747 -:109B2000EB8D24276BA518379EC79DADFF0F1BB289 -:109B300035B467785ED282894250DFF2AF12F159B4 -:109B40002DF463807E8AC666D27A6A99C58BFAB88C -:109B5000F6907937F26B2D987FE867019FE48C4788 -:109B60003E9920074C6007BF6908E648742EBDCCBB -:109B700024C1FC5624017F0C1B980FD66AF719C428 -:109B800073E02F37F6F7D9CFC6E7521CFFF0041564 -:109B9000F1D562E0F79802BF92DD3C3F868B687991 -:109BA000E2188A4F32C5EDC6F852B576EFA5536676 -:109BB0008DCFF5233FE78EE7FBEB4D97717A90FA57 -:109BC000D59FD7CC18CFFDD0195ABBEA23AF65E09B -:109BD000BDADB55D46F24358614F9ECFDECF7A1AD8 -:109BE000B7DE9915C1D7EB0E9EE0F91AAC272F32DC -:109BF0009FFD56AD5FC147B2C9EEDF6D8B9C1F1F45 -:109C00001FF87A0EE2E1AB78E0EBE1C4D727D1CEC2 -:109C10009E6556E36E84B207501482D2FF0327E597 -:109C200027893CA5A5CC47E50A6003E4635FE00112 -:109C300013E27F15EBA0E76B4B6E1982F03AD65B0F -:109C4000E5423FA2BDF91517CC72DEF607A6625CAD -:109C5000766E70F12B58CED92B9D44BF15F6C512E8 -:109C6000E4E31EA9BE6D308CB7E0D98AB634783EE5 -:109C70004BE6F460AF737A00BF78E5844BD709FBFD -:109C80006015ED83782FAD43764CD7ED83DA8DCC1C -:109C90002B2585F3EDFBF645C9AD7F4A433F48E9E7 -:109CA000A5F3F77587CD0948E7558CEBEDB01D2876 -:109CB000F435B7036E053B00DB7DA2F1F327198C69 -:109CC000EE357C228163E709DB916C88DFE5191EA4 -:109CD000D6BB9F1882C58EE1A4979B71BEAFBAE632 -:109CE000A9182FBB35C9E296B13E3E38849FA3F632 -:109CF000C9777631361CEFBADFC8E34FD1F3924A09 -:109D00005EFD2BDA0D66130BE0B906EC6B568CFB8F -:109D100079B089F6590BA216E366953EB5BFFE5B96 -:109D2000B57EBBBEE6FE6F00D683F77C2E19C7A9B1 -:109D30008D13C3C711FA03C723F991C274E3ED1958 -:109D4000CFF7F59B762FCDBFD9104FF2E60F43FD2D -:109D5000BB91EF44DC47F8855D991F6791FF7EA1B9 -:109D6000251DED73E05F9EC73899CBA5378D6A003E -:109D7000E1372B3229EE2FE4EDEC121E279B2DE26A -:109D800062655171B1A8780C2BEB3F4EC698DB8809 -:109D9000E38E64EF09FC501CE6489942740F00DD25 -:109DA00031CE7C44F34F2B62B95F9E509248EB4C0E -:109DB000B8368BF8CD91C842740E659789DF8EB2A4 -:109DC0007C5B42849CB8578BAF6E033B8845C4D5FF -:109DD000EF2D6CB060BEC1661BBFFF785F654C5D48 -:109DE000647E7CE2649EFFF2C3C915AC04F0976701 -:109DF0000B5692BAF62A2AAE47D2D637DA09F83786 -:109E000060D73E2D4EEAB6F0B85415E96B41F72BFA -:109E1000D5D7CF28C18D31B8FE2446FBD0BEC34A6A -:109E2000F254EEF08630557BD9E4B9EF223F33C5CA -:109E3000978BE37416C7301BB4FFAAD344FEFD61B1 -:109E4000C3921F9870FFBD6B6678DED9614F535087 -:109E50005F747C3DAA8A4AFBC4698CC739630D20B4 -:109E600028F29DEC897F43A269F7D54CAEA3933EBF -:109E700002147748AC8B51DCCD1B6B009FACC3C088 -:109E8000CE95C3FCF6DB3C0F8D2316F4C9B8DEA1DA -:109E900093FC9F227F15B37A82EF33F9EA76C3F8F9 -:109EA000F72558886F3CA906BA3FC8FE6AA3BC1FB5 -:109EB0005F97624415F76299FFDCF808BBCCE73284 -:109EC0001831FFA7CD04F23B0FE32831FCCC8A7197 -:109ED0007BDF773E87E6F78D264F5B5DDE6EBC88C5 -:109EE00032205E9D4A6F5FDC84F8329DE27D02CFB6 -:109EF00091F47416EBE8E93746D2B304E8392692B8 -:109F00009E5EE96AE8F90E26A1155DCAC7814AF589 -:109F100081AA42AEFF30952E9A8F2BCC936C980776 -:109F2000D3E9900D48D7CE98B43C8CDB093E167C23 -:109F3000DD0F3FAF3F8A72255D71E279B2B93A8693 -:109F4000CE67047F0BBE9E5EDAC7DF8F95023E1799 -:109F5000DA7C5351F644F337C6CF22F9B876407E07 -:109F600067CEC87D3E0BEC8DB804B4934EEDED8802 -:109F7000E0E3DAFA2F142E772E96C71487E37DB329 -:109F8000CA24F64124BDE1FF07B9DAFAC84E52C827 -:109F90003F1378BD52FC1BBFD39C8B76DF26BCFFE2 -:109FA00008F86A97DCDE411807AB3F711B3E6FD3A0 -:109FB000EE2507F24CDC1ED3F695E86FD9E4CA69AA -:109FC000B8FFEDE3CFC42E87765FA51854444E9BAF -:109FD000BAE4DF689F1E8F65F89E23B1BBEE09DAF5 -:109FE0007723189E277EB5D23F14CFF7B7009D3E4A -:109FF000A0A4EDE020039D7DF50CC27D07C875F19E -:10A00000D2EFE2CF99561F24F80F138669E78C5ED2 -:10A01000AD7D0FB5DF62DA6E89C171322DCE3D1193 -:10A02000FC5FAEC5E35B4BC4FD9F1615F3DF5A4BD7 -:10A03000B83DFB50D3BE491F65E37C3A267D04F34F -:10A04000499C19647EE0EB98DC808AA923966FA670 -:10A050004878CF818D621D18A7C7E7CD63C2FDAFD9 -:10A06000D4FAB5A09D03F4B36C0CA89172D662909B -:10A07000FCFDE5C9FC718242FBD5B29151BDE5C83A -:10A0800023F4FD80C42CB784F9D5968DDB199EDFAF -:10A090005843FC795296575A1AD16FD24C9877048C -:10A0A0005F007F05E2402E59F6006316221D6228EC -:10A0B0005E193DEEACE4CA2EC531309F44F31BD38C -:10A0C000F84DF08D5827DD8089F80E40D5300BE92A -:10A0D000C9B646D36EB4CF7795C4135EBE4CAA8C76 -:10A0E00063FDD8A7A2DC057C1030A33F6DA1720FE1 -:10A0F000F8E38111E84FBB087E0AFC712CF7813F21 -:10A100008EE533E08F63FDB3E08F23FC13F0C711BE -:10A11000EE007F1CE1FDE08F237C00FC71847F0A50 -:10A12000FE389607C11FC7F2E7E08F63FD21F0C735 -:10A13000112E37037FE07A7203AEB940D7F6BB4DDC -:10A140005ECC33FC6D0997A747BDC312DD407F6B22 -:10A15000AE8162E5D6371E64B81EABCB40F7CC3675 -:10A16000B91E64B7A09F5B6C277BABEDC7DC8EB1DB -:10A170002A0F31943BBBA4401D73C3782537D5E229 -:10A18000B960966B7D6502C0474A16EFB4C0FEC841 -:10A1900051E7CC6F8E8055BB67D573CE303C346FA2 -:10A1A000B7029E0CFBE5C15B76E215239C07E61720 -:10A1B000BF55B2BC16F3EA43C318D923BD9926CACA -:10A1C000E3598AF4CAC6F9F373C0EB588B0BCF3945 -:10A1D00087AAE02D49D49EE24C57DAFEB7252A3DE6 -:10A1E0008F7EEF72ED0C8557D48EC997E90FEBA5E2 -:10A1F000CBF46391E659BA61EE5B8D9A9C4AB691B5 -:10A200009C6AC7B80FE0BDDDCACBFC52BECF8DA59E -:10A21000950F4F80F2E1099CAEEDD680B312C71FB7 -:10A2200063A03C07D698F9CE3018EFCE5F290CF327 -:10A2300045057F9ED1F8207BA89DEBEB7B2C74CE4F -:10A240007FCDD01FB726009CFD84DB8DF9105B9974 -:10A250003B06F924B0CD4079913F2A1C9E30079AE5 -:10A260008F2E7A2101E5FA8C097C1E412D8FA8B929 -:10A270006DF9508C537DF51697877FD3C6D96DEC59 -:10A28000AE277A16D918CFCBDA4EF648B30B880D25 -:10A290003AD390CA4B93D1B900DB99C030C0BC6DA2 -:10A2A000D3D7E32DE80FB69C374FE779B5DD649F30 -:10A2B00098AC7E673C3CDF1E30905C68516D940723 -:10A2C000B7D5E6E9C27BD301A781F265B7E61908E5 -:10A2D0008FADB61B82E8072852731DEAB1A073BF89 -:10A2E00025139E07F30C94FF18F4CE9D8E70C0CFFB -:10A2F000BF47413F58EF4FA0FBE25B59EFEBE3B0A4 -:10A30000BE96DB696D29FF752416E3E2D73BDDFCC1 -:10A310001886A9983746296406F4C77B36C6E23CFE -:10A320006A98E6EF06C8BF759839FDBEDB79AD7354 -:10A3300018D91911E75D668CE1B92D6EA81F6BF372 -:10A340004C47FF53B17B2C9817D8EAF45816D3FA30 -:10A35000793E1BE56B40BF2D4E03F9C1587F0BEED4 -:10A36000F75646F97083B5FA56DB839D880F651959 -:10A3700063992ACE4F09449E275A869775A9B08EB5 -:10A38000F6E509B40E457213CC962934EFC16A0C78 -:10A39000DD937EC854DD85F6E460CBAD74EE955A4E -:10A3A000A7E8CEA506F9F570F27C3D9CC894F0B9FB -:10A3B00016F2D9041197D3E32D1A1FA9CED6B77080 -:10A3C000FEA97EBAC47BC9FC1F717E2FBE82E13C10 -:10A3D0006D34CF14DB920AB49B9299AF19F9EF1F39 -:10A3E0009DE758E75C4B268C3F36C940E6D138D60E -:10A3F000BB11FBDDAAF17B7B26A767785FC9625F93 -:10A40000364D48C6F305033874E1FE3303E0D8E95E -:10A41000CE17127470F6F6C1BAF623760CD3D58F28 -:10A420000C8ED2D58FDEE7D1C1633A4A75EDC71DD8 -:10A43000ACD4C1F9A119BAF6055D73757051F70274 -:10A440005DFBF1C797E8EA27F4ACD2D54F3CD5A025 -:10A450008327F5FE8BAEBDB0EFA3F5E3DD13B87D2A -:10A4600071B576BDD93558F7DD9C68BF21DAEEB7F6 -:10A470007CD3A26E447E7698889F15D4E7780E7DB3 -:10A4800037F79F2C93DD2AE5396BFC5854EEDD84B9 -:10A49000F2B4C26121BDA0D8783BC5368DEC9521C0 -:10A4A0003B4CF43D1FC5C9FAEA63513E37052665AA -:10A4B0006587E76D756E67B87F2B1CD319E6298910 -:10A4C000F715A797F9318F1B3FD28376923340ED72 -:10A4D000AC2ABC1FB18EC30603B3A11C073F0FFDFE -:10A4E0008381FC3AE1CF09FF6D20BF4DF86B430C2F -:10A4F0002C06CBDD52CF6DE8DFE7D5BF553988910B -:10A500005FB70FF9F53EBC078EFEDC586E67B5A548 -:10A51000CC5031DED39ED9D1350CE7936CA0382ACC -:10A52000D8CDEEB911F6E2DB9AFE5186B5F7A0FE62 -:10A530006B88B7A8682F2996DD933E027CED32F632 -:10A540003C8DF18B56C9B9BA03E5E2DD36CA0F7905 -:10A5500048C39B6A37146C847E3B9ABD0ADEF7EFD2 -:10A56000D8C2DCADB83F922A36C6C3F3ECF4C506B8 -:10A570000C138DC86ADE88E5B109FC3C6864DE6EA8 -:10A580004322D48F2EAC988F7131D9B99BFCD981DD -:10A59000F84976EC60B81E96A59C44BE42EBFE22BC -:10A5A0004CBD2201E80DE35A91DE12958407EB7948 -:10A5B0005BD08A7016C78BD52B0563256EB7627E7C -:10A5C0005D45C20EA2AFB067D1CEF5737FF76DE4E3 -:10A5D000A3A4997ABA2A96BD848FAD06BE2FDAE37A -:10A5E000D537503FB7676625B4A8E1790AB9F24775 -:10A5F000CD0E17CF855C998D3938C961FB06F87C83 -:10A6000007C6E7ACCA76BAE769DDB09D215F5BF1AA -:10A61000563CD9FB01D547FAC3A7CB4FAB1A36DF5F -:10A6200082FAFA5C9287EC596BE34F697ED178B37A -:10A63000F6F03CB581F0EAC87994F43B086015FD6A -:10A64000FE2329B6BAC8B8A828EFD2FC13A3C8279E -:10A65000024F02F5D93991AFE48DE5F38BE7F0D1E4 -:10A660009C0534BFDB923D832E676F5BC1DFF447EF -:10A67000D07D8BE2B3201EDA2ECC994EEB56683398 -:10A68000B0AD5FE7EDA678B3E62FDDA5E1B7B58401 -:10A69000E3738889DF337027CDA4EFA40DC6F84893 -:10A6A00041385E32AA94E737BA034CE6F1BEBEFCED -:10A6B00076C3C571346715EF1FE09920F2631AE382 -:10A6C000FA0C9A74623ECBF076459F0FAFE9F334F3 -:10A6D000FE3BC87F7DFD881D7A786430EAFD00FB73 -:10A6E0000DEA7BB477299EB14F5FFF18EA6D901396 -:10A6F0004B35BDCDB6F3FC120BCCE822D7B761FDCC -:10A7000007F260564777452CF49351A2CF3B498B13 -:10A710006C07F8F3AC34D0BD1211DF1178F7D519FE -:10A720008C26E27F55770E27E239D1F25ABAE7CC70 -:10A730007ADC5715B1B12ACA598C77F8CDDC7FF78E -:10A74000833F739FE2FE7D2DFA5F5D32E561097AFA -:10A7500046D37F6F9F3DEC2B2F253FBAA700FD7A94 -:10A760001CCF1F319E88CB6497FBA7623B119F399A -:10A770003B5D794552C3F116113F7818F719B4DBE8 -:10A78000EA7EBBFE28CCE3E87133C54AA6CA6F74E3 -:10A7900035619E55864272CE397EF50FD04FAFFCA3 -:10A7A00003D4635C52550791FDDE65A47841A5C6CC -:10A7B000EF959A5F26E2320BB579D7940A7B281081 -:10A7C000C3FDFF500CDAB9A3F7818CD6F34B2CAF45 -:10A7D000E771BA311DD1F55ECA7F1AA5F103E6AD66 -:10A7E00055A460BA18873B9894E8043A8F9BDF73AE -:10A7F000045D8CBCD75E8941BBEB392BE78F673496 -:10A800003B2F85496ECCEF4FD9677307A19D5D66DD -:10A81000CF75C33ADCC7145D9EDAD8437A388F45CA -:10A82000C099380F3DBC4DADC7A36BB6AD165811DE -:10A83000967C47A9964792C37290FFA6CAB67CF44D -:10A84000B31A2A6C0CF16A3E31E2FBDD2857DE9226 -:10A8500019EA0B67ACFA4015BCEF7C3DD1DDAC8644 -:10A86000E9FF0CF8DBA8471EBEE866ADC670FCEB3E -:10A8700059A067169D4F3BA9BE03E88AF07EF0BF42 -:10A88000B3E87C3A979EFF14FC6F840F82FF8DE53E -:10A89000CFC1FFC6E787C0FF46F887932B1EC4B819 -:10A8A000D97BD00EF92226FF806538C6CB6D32DD0C -:10A8B000DF89E6C7CDF51FDA6E049936CA953C33B9 -:10A8C00019F9E17699EE45432733D1BF8D8CBF4509 -:10A8D000C623C3F1B71E49C4DFCC409F519A7FD92C -:10A8E0001787F3F338DCB7F7E315FD509CF3927E3E -:10A8F000FAE29D96C047B928B2241607CF3FBDFBA8 -:10A90000DF9F427D24A7FAF7E23E5953F48189DBA9 -:10A91000E7FC5E56BAB68F765A793E6ABA96471405 -:10A920001DE79C3CE5C46DC980B2177F7ED3428C85 -:10A93000134CBEF544C11080BF29FD25877F78E206 -:10A94000F934C0D3D289ED1C7EE8C4B97437E671FE -:10A95000EC5F88F9C38E44AE07776AF79B047E8F5D -:10A9600069FB665DE313A4EFC11E61888F96141F17 -:10A97000E9E1CF937A1D8BD1AE4BEE4D597219BDE3 -:10A98000B1AEF1297A7FA7E43E15C4794FB0F0BC8F -:10A99000554D2F9DD57857E8A5062B07C57C187314 -:10A9A000D1F387B47811F3A6D17B89560E1F759425 -:10A9B00092FEBABF52FDB5CACF3FC98F3EEA18F525 -:10A9C0005DCCCB6B99AED0B9E443368F15F5DBE7A0 -:10A9D000DABAA0FF00C60902532D745EC492E6D312 -:10A9E000BE4E10E324D5523E4382369F63A53121EB -:10A9F0008C23B45459F6A01C7DD0368CFA6B2931C7 -:10AA000005307E23E08DA5301FC067BC2321136174 -:10AA100021E7447C99E1E91CF45BA92DBB52E44990 -:10AA2000588C6722ED701BEB26FE711B5419EDC884 -:10AA30000D13395F1530F77C7C6E92EA03C88CB831 -:10AA40000E43E43AD42AFD3AD4A9BA75480D9610BB -:10AA5000DA8F2D53611DD0FE98BD98E61B4D37B19E -:10AA60009E0F4B55C257F43A99762E25EE1F543A55 -:10AA7000CB0EE0BCA61ABCAD38AF57FE5A9B841F64 -:10AA8000E89BC6EA157C3E3C9C0FD47A35F91693B8 -:10AA90003F94F839DAAD265A9F71329FCFA3A66052 -:10AAA000265D0C5182A9787E3C101F674E8CE663B0 -:10AAB0002FC3FDD592E0E57CECEC7534231FC7F77E -:10AAC000A66CA47585FAA54F343F47D32B6F22138C -:10AAD000DF079111FFDF465F41D7E8F334C12F1B39 -:10AAE000263A05BD5DB4CED010DD7923F4A0F6770B -:10AAF000CEBE09FA5323CEE54C2E1FD9E3C62477E8 -:10AB00002EC6A55BBE91FBBD7F59ABE1A9D9114310 -:10AB1000767A8B83DBE99D8E193AFFAA0AFC2D3CDD -:10AB20008F96135907EE2B396E01C5DBE441689906 -:10AB3000115BE8EDDFB899DCFE757A2E7BFF4AE900 -:10AB40009175DF73BBC4FE4D98C1ED5F8789ECDF63 -:10AB50009D76D3FCDDFDC89DC289DC4FEAC475F447 -:10AB6000E35F825F49714FE1579A9C7EF20FC53ACD -:10AB70000BB57D26DA9B9DF50CE370B2C9ADA2BD85 -:10AB80002B6BF764312F3A37C22E10E38F9BC8ED41 -:10AB90008EC1E53C5F53E4C74FFEB554DF1FDED7DF -:10ABA0004C147649FF7CF70FF00DC9098FCDE445B1 -:10ABB000BBC36373511EF940EFE151F8A984B09C07 -:10ABC000717F532C933E52DC742FA0C3D8F3FCAF9B -:10ABD000D16F7CC5467AA7C39E4EFD09BBBD2296A8 -:10ABE000517E33F8C9815CE8ECB9BFC18E3484FD75 -:10ABF00063F0D7364F8C38D73CD27092CE8BA2ED13 -:10AC0000D5E8F843DF7E773C95C9E7134CC5FD2BAB -:10AC100035940C42BE8ADEEFA2CC70158C5A0AF332 -:10AC2000CA48CDA7523C7F9CC9D3FBFB6EDBAE3E2E -:10AC30003A703D3D12068B93493FEFC2797F7AFB14 -:10AC4000DB296E15EFEB7E417AFA6C7D49DC66E418 -:10AC5000F7DC0492AFE9DAFD33319FF4959DF109F9 -:10AC600036CC03EC1D89F973C126DFA82A23C50D54 -:10AC7000BDFDCDF757DAFE63A1A12CF2BB446A52A9 -:10AC8000F7B52300EFAACDE056697F3949FF0939AE -:10AC900050A1C4573981CF339A98DBA6E2A79B9D78 -:10ACA000143FCBB82813BF651CE5DF971E9AD42B41 -:10ACB000E1778FFAC6D1F2A4C439CC97F555B43FE9 -:10ACC000330631D68D7210F43DCAF92F934273705A -:10ACD0007F7FF93D3EA38C27F4F5A07329BEBDFC10 -:10ACE000F698A00A5D0FDD00F3C3F9FC4062E99914 -:10ACF000388FA3999B313EF4622CC587E41D59140B -:10AD0000DFB93ED5BF7F22CCE3D3A07AA761B8B626 -:10AD10005868B7E6AE18FA2EC14EA9FB5ACACBB88E -:10AD2000C340DF6D8DC6D75B13B95FF9F644BECF64 -:10AD3000325CC59CDEAEC2514B13AF7C3F7D83DFDE -:10AD4000D601FA6E8D0BD2799EC82BDB66EC9FAFD5 -:10AD5000CACAB87CE993C71AFE2CE80521BF489AF5 -:10AD6000DDB7EF99679E4961FC8AE2307E6E197902 -:10AD7000BE1C9315A4CA18B797E48FE4F47239EB9C -:10AD8000AC770580BF377F2DF73BBEBD4C93D31901 -:10AD900077BAB07D95EAA6B233A3F8F862C09FCD2A -:10ADA0006662E608392CF8245ACF37D8875DD6DF9B -:10ADB00037813C562F138F306979649B8E4CB0E0FD -:10ADC000774B37D93CDD687F6DB22579285E6F03FC -:10ADD000B91111BFB2D95E253EB4B9795CCF86F204 -:10ADE00017E357B8FE3C9CFFABB47ED1EEB4268788 -:10ADF0006CEE109DAB5ADDDBA99D45F1D1FD3B4BBF -:10AE000012A37C088B937FEF3426CBC02CFDC8E3C4 -:10AE10000F501E433F9BF23CDD95343F05AF65B1BB -:10AE20004D2E8F8BF421E219DE3F6A2F8E8BC4CF1B -:10AE3000500DCF2D9D7C7DBEC654675501FAB5BE21 -:10AE400094B222EC678905BFAF27DB0B2FDB4F6E77 -:10AE500019972BE17E1E49A94AA47E86623FB2DD86 -:10AE6000E3C47E8CDA775BA3F15CA4BDFFF7C6DD9B -:10AE70000083940F447821C2847474892E6D183F26 -:10AE80004BECEF3D2E173335FF05E4624519CC6BD3 -:10AE90004DDE07AFF23DC6FD96846B79BED1592DCC -:10AEA000DF3C3A4F23DA8E11FA47E823E847C67EA3 -:10AEB0001E453B6644781F0DE6128BA5D5F9F87E3A -:10AEC00049F211BF805DA3E27E91B57CC1E8F56CCB -:10AED000D6F027394A54D41755177AD2F0BDC3F6A5 -:10AEE0005369DC8ED59F471FFBEB5356ACFFB2AEC8 -:10AEF000F2B2F68A387F1EE8DCD9F12F9FAC8FB40E -:10AF000057063A87FEB6F3E7230E13C5F97649FADA -:10AF1000FBF5CD9A1CDA5026E232FEDB901EBB24F4 -:10AF20009F9B5F98E6F199A272FF9DF87C48BB89D0 -:10AF30000580AE87FF5AECF247F473A57816F1FA54 -:10AF4000C19A3D35D8F69484FB74705D50C2787B0D -:10AF50005A5D87E4BD4CBBD9655C8F8BF646ADFF6F -:10AF600072A557467D55EEE47A31EDBCC27223E4FA -:10AF7000CE8C32BE7F8D9AFDEE38F2B415FB3B626B -:10AF8000F0B5E7A07E7018D42723F6BB71A5C75291 -:10AF900019B1BE163C47EA878ECF94F5D95DA4BFA0 -:10AFA00085BE350A3D91A4E8F4C4BA58CEC7C2DEC6 -:10AFB0005957CAFDA175B1DC2F7FD1E57F02F7F3A8 -:10AFC000E7A59FCC1AAEE23DDB0E139EBB7FDB797B -:10AFD0004A9F7D63082E16FE0CF2BF5B71FEA2072E -:10AFE000DECFFF6105D97B45F8E512198F70B9FDF9 -:10AFF00007F6D473385E014E3D82DE2CEABB860331 -:10B00000AD67277E4BAD08E37FDD14C7BDEF82D46B -:10B01000EF7D8A2FCB84BDD0776E78D938AC8A711A -:10B02000D84C3C07D3C7490BBAF47051B71E1E7FEA -:10B030003C3AEEEAFD6D64DC7527EC33941322CEC6 -:10B040009A1E0856E03DF30CD641E7906975093A1F -:10B05000BC4E96B5FC0CFCBC7244FC374DA93E8D31 -:10B06000EF9FEE5B5780E9EE07542DBD133FC519E6 -:10B070008EE3AA84AF15D7CE9D8A748D8EE766D4F1 -:10B080002BBAFB84D171DCE53BF5F70D7DDE7CF25C -:10B0900007E67D471FFF1579EDB8DE34CFA5E37FC6 -:10B0A000FBB8F03FE1D2F145BF8F82FC21F9AA7DC8 -:10B0B000C73803ABB01F2524E179F8E07A46DF33C7 -:10B0C0004EBB9D79FB3B57489BC4F1158D671628F5 -:10B0D00027FC4DD19E0DB6F1BCD7C1B71BC81E1CB5 -:10B0E0000C7281FEDEC16AC612014E5BAD923D3923 -:10B0F000BBCEC0503FB00B4DBAF761BA144F1574B8 -:10B100007FD4C6F37A33D6B0A001D7533F8AF61363 -:10B11000CD6B982EEEAEFB2EC1EC12FD7DDF8CA820 -:10B120007BBE820FD2A29E1F2A73EAF605E8B9B44D -:10B1300049C4275CFF65A3FE83297D3AE1F8539853 -:10B1400087377923E3DFC3898FD1BE87D3775E2129 -:10B150005F047E3D6299928BF6CA56678C01F32399 -:10B160000EC7F73CC6E2191B338905F0FB9D2FC7BC -:10B17000F48E96009EF0D29E5DED4094C3D6DE1F05 -:10B180006130D9B6EDE99BA747C08EFB5F22989549 -:10B190003015BF2F84B9ABB8EF629C33F6E1F77C72 -:10B1A00063F26C149C8C61FAEFF8B496AADB30BFA2 -:10B1B000A435DBA0DDB38EA887753C35C929F2E242 -:10B1C000284F8F4DE7F90291FD639EF780FDCF80F8 -:10B1D000FE0BAFA27F0B9F7F0A3E023D9382F3C717 -:10B1E0003838F68FF4C5A051E4F85A7F0A0BECC644 -:10B1F000F31D18CF26F1F19C98BF92C2F4F90A7D95 -:10B20000E33961BC31FF17D633FF527A182F478FCD -:10B210000557478F568397E61B186B233F08BF8758 -:10B2200085DFBDB36AE359B5EF7F215E5B8BC378E1 -:10B23000053B90FA85E6CD17353C633E628AD344E0 -:10B24000781E086F479C3C7F6A8B3326D89CF9FF99 -:10B25000805E2E4EAFC8F1D09EBCE2F116C0784998 -:10B26000573E1EE217F74F1F7E81261B53AE1CBFB1 -:10B2700030ABC095E0F708F46B88C06B384FE9112C -:10B2800027FA0556A3CF82799BCF4FE2F98F7949F0 -:10B29000732D94B7903C97F290DBF26C9457DF9645 -:10B2A000F51D8B31424FB7E5D5523DB4A7FCAABC82 -:10B2B000500C8629D818D64D71802D65552EF40B6B -:10B2C00003F53C5F4BE42F097DC8B4F3515A17BC1A -:10B2D0001837E940EF1168BFA5BE90F2D3E2E2FF54 -:10B2E0008BF2B2B6D6B9DD58FF189E63813DF1B03E -:10B2F000768E858C4AF1B4B1A54FE0B9AF27BB413A -:10B30000C2E3A6F4D57AFD34382AEFC7F345772592 -:10B31000E677B1C53C7FCB55AB44E943FDBEDD8A42 -:10B3200078E579564189E357D7DFE949C9A4E7B6FB -:10B3300064ED6115D0EFF3D097ACDF5F06CC778A70 -:10B34000DE8F8AC94BDF29630D069A471AA6108043 -:10B350008AF38C99E95A0CCFD39729F4FDDA417915 -:10B360001B28EF09AC7CB237F2F2DEA844F89275E4 -:10B370002ED5AF237A5DD1F316DF5716F4F27CE1B8 -:10B380008E45FFCA933D97F2D2E847EC77396A3D84 -:10B39000600F5B930CF45DB998AC8875315D3BCD63 -:10B3A0007FFB9F857F3F8971FB39FA5CEC7FF1FB66 -:10B3B0004766E6B698E83D715F879FB70DC6BD83C7 -:10B3C000741FC2787E78F4FBC5FC7DE6E2E76FE689 -:10B3D0001866C1FB3AD2AA188A639ACD00E37D1E93 -:10B3E000ED7B658F6AF1B6668929A99EC8F1429402 -:10B3F0005F2F5BAECB42BFE188659E93EEC9697E4D -:10B400009431DE47F98D2C3741E78F1ED1EEBB35E5 -:10B41000ACCC1C84F1BB38A8EB46BF5A715B90DE04 -:10B42000226EE218DE7313EAF16193872FB2002EC9 -:10B430000EA3135CCAD8B8C3193FC0EF148BFD69C3 -:10B440003ECFBFF7D1072BF5943F623E3F44F73C18 -:10B45000A4F96102F626295538DE34F40F92F1DEA4 -:10B46000B8B315DFAB00E4E8BE2FA07D3FE4D2FE09 -:10B47000D375CF43E05F479E0B0CDC7FACEE3B0502 -:10B4800066F077FAEF3F27AA7F67BFFD87FB4DD4B1 -:10B49000F5DBA670B911488A09F617DF5B36B9F2F9 -:10B4A000BAC94503E7B72D9DACC5E12C20FAF11CC4 -:10B4B0004AE39FCDAE7ACA779363F8B9A911C4085D -:10B4C000F2D3517B1DC92D96AECF7713DF2769C309 -:10B4D000EF8E407DA54D6FAF57B0DEA3E324F4534C -:10B4E000F5F6FA645439783EC5A2EDF87A3A273574 -:10B4F000A6EBE5C2456DBF18EC85DD941F976CA3E4 -:10B50000BC8681E20BEF3531CADB32C6FAEA51E77D -:10B51000FDEBE1F143DB4A008EE37CB6F5F0CC4570 -:10B5200018377A4FE3E736900374CFB561D06E39A0 -:10B53000A2DF5A53281BF54AAD81DF17A01F18FF61 -:10B54000BDE4C114678D1E577C7F46C00BEBA54937 -:10B550005911EB7B4FDB1F7DE3DD96B61BEDDABEA9 -:10B56000F1CCA1221AAF2FFF481B2FE5EF1BEF8F65 -:10B57000DAFE16E32DBC53BFBE85A66E5ADF42ED40 -:10B58000FBA762BC3FE2FA32FF8EF1B4BCB1BEF160 -:10B59000EED2AF6FA1B99BD6B7B0CFBFD4C64BF92F -:10B5A000FBC613F90E66737D1DF2D340790F22DFBF -:10B5B00021C795A8CB77C09B2715598C3D2071BE1C -:10B5C000787D72CD0F30CE7F6E66839BEC14CDDF1D -:10B5D000A37B4432DD23223D3A3B9DDB21A2FF7D4C -:10B5E0004D25CC3B82C783B0CC2D93E89EC2C812B8 -:10B5F000C98BE76C3B417EE077F476C13EC7FA60C9 -:10B60000938BCA3D4D2A957BC1BFF452FCCB4DF0C4 -:10B6100085C9DC5F7C20D559B314ED8F8A189EA7AD -:10B620005D36112CDBB0FF06FBE58815F3216F605A -:10B63000F9F8772D7376707C2655A5D0F7F663F26E -:10B640008F753701BCB9445631FF7CB3DA7F3CE7D4 -:10B650002F5ABECF662DBF3280F72E49A9803F59A1 -:10B660004C7F3F8BFFC833E95ECEECBBE2C9BEA97D -:10B67000FD4E8FDD09F3B859CAFF6D16E0E34F9A0E -:10B680007DB368C80C9207D1FE69126AAA42CC3B0E -:10B69000948341F8759E7D1EF9B7F3AE672C01DEE9 -:10B6A0009F8DEF819EFAB5661FBDD96366E8FF05E1 -:10B6B000AAF8F9F5CD1BF47EE903D69013EDC20785 -:10B6C000F29318D2A3F6767DFD6613DF6FF3A2FC2A -:10B6D000D4D951793FE23B8A9BF1D7098C7D395906 -:10B6E000FB8E9196F7B35F8B33B1F4044A0617F7DC -:10B6F0003DCD66D6EFB9A4E82F11041DBD97E42512 -:10B700003C88BC77263F9B8FEF8BF1C47B8F4ACF61 -:10B71000A65E2E6E0A76E0C99E5CAEEFD15EB7964D -:10B72000EBE7796EE6B0EF56B1FEF8B657C1388553 -:10B7300098FF3F8B5F8FE27A414EFF7ACA9785FC74 -:10B740003E5E3A8BBC8727F2BFE6F5C10A7D9FF8C3 -:10B750007A01BA7AF390DEBF9914EBBE97F84FB333 -:10B760004742EF1A2EC65E7D7F7DF370793374F702 -:10B7700060B5FE06C2F340DFADA09FE2709CB7A5A6 -:10B78000D9EDA27B77C9FC9C6D7052E569BCE78559 -:10B79000F51FE8F84B7F9FABA5F36909FD96C7F04D -:10B7A0001E9C31224E54D721B5D9B0DF208F2B8576 -:10B7B0009EA6F86F7A5D486ACD0BDF1B8A968BE9EF -:10B7C000ABF5F7D2A2BFC7586DEB512415E3FDBD11 -:10B7D00074DFB1AD5C3B9F411C63BB646E4FCA69B3 -:10B7E000069E2F3254E5F66556EF90C8F38E55E568 -:10B7F000DC6EA88E7DFB761544AFBFBC6311E645B9 -:10B8000055C7BD7D7B26C0B7943FB708BFB3589DD1 -:10B81000F6F69799206F9795EFE7F0E8B7BF1C060B -:10B82000F08AF2E7398CF91E80A495E50716A1BCD1 -:10B830005D552EBEBFD84DF7BFE554CE477F776923 -:10B8400036F4BB2F6F2B17714B46F7BD7D877E7982 -:10B850001CE5944FC479BDFAF34DA67D7FF13AC142 -:10B860005E490EB29766E0EF80CFEBB4EFF6182C8E -:10B8700021C2EB88F07751BE7735DFED09DFB7E7FE -:10B88000DF9D6A69647EFDF715BD1AFFF3BC2131A7 -:10B890001F31FE25F3C2EF0B2644CE6B27F523E6BE -:10B8A000F579BE39208D0B9FD78A797D2EF5EEC2B2 -:10B8B000A047CF94DEC548D7CFEDBD43F0EFAB94A2 -:10B8C0008786FA094EEEDD25B9236023A7E323E539 -:10B8D000FF87ECA951A9DE47CA317FCFC4BF83D00F -:10B8E000AED9915B93FD01F4EB81DF286F3390C1FA -:10B8F000EF3B5415EAFF0EDC131A7F1579F9F9F4C2 -:10B9000054F3F6FAB70AF1BBEC126B86F6EB2E9CF9 -:10B9100033A1DF5F7DE88409FDFBB5074E98D07F3A -:10B920005F8B30F4B376A7A9DFBF4357EA95C5FE16 -:10B93000D5F92BAF64E4B425C17CD62EE5DF016BCD -:10B94000F859FC54841B16E32AF1EFF93D37155FD3 -:10B950005BE8EB6CC37211EB7905CF256AFC7A3F8B -:10B96000E2A63ABDDDBFB05E6FAF2FDA0ED401BDE7 -:10B97000B6A8312DEA7B80FC3B83351A3D6B5CDB3E -:10B98000BAF13B06352CEA3B83011E47BA89AF006A -:10B990004A7D7CA41AFF9E15AE63B54C71DE57320A -:10B9A0003629784F6E5DBD44F97B530F7E61A27AD4 -:10B9B0006887E74A2983F9F7F484FC14FAFDA6970F -:10B9C000761B315E10FDBDC145F3A7D377C5E7AB4C -:10B9D000ABB87E1FFABBA909F03CFA3B82B507B9A8 -:10B9E0007EAF6D9482F8DDDE9BEAF4FEC042D6DDC8 -:10B9F00086FECCC27AFDF3458D7AF823A1D746B3F3 -:10BA0000D1B83F4E974B0AED170D3E93F1BB37432C -:10BA100030BE3BD5C7BCC027AB4DA1B1A8E7DCA960 -:10BA20007E82453D3C5F8BF27FA07DF8FF4BF9DFC6 -:10BA30005818855400800000000000001F8B08008B -:10BA400000000000000BED5A7D70545596BFB7FB07 -:10BA500075A7BBF341E73B31045EBE58244D68D265 -:10BA60000441778AD7DD494FF8723A40866008343E -:10BA7000B350152549478953B1CADD341063072DEA -:10BA80004B59B4C0F28F06C5D51ADD0D92C1CED286 -:10BA9000301D302C3A387676D08171B582CB3A524F -:10BAA0008E9088A3B8CB167BCEBDEFD1FD3A2F8AFE -:10BAB000B353FEE16E527073DFFD3EF77CFCCE396E -:10BAC0009710E1A3B1D984E8082537F484EC344811 -:10BAD00056E7024202EDD47E5024A419DB4D84FDCA -:10BAE000DC28C1FF797F56D74FAE3B244A480DCCA6 -:10BAF00063F676119CE718B51E844FB5822464D98D -:10BB0000E03B254D0369D0177F96C4CB05928E90FC -:10BB10005C427E43C66CA48C90592930610E94AB74 -:10BB2000A78502B0EEAC5F6D0A50986F9683DA7508 -:10BB3000B0AFE5B0E3EE6A2C05B21ECABB0542CC3D -:10BB400050CED20F34E1BA649ED17A90EDB7809096 -:10BB500085842CC33F619CF432A11FC37970EBB87C -:10BB6000EEF2E9A7BFA619307EEFE3137A28CBCB1C -:10BB7000A4EAA7607F8F99F9FA8F0DD1D07698A7A4 -:10BB8000C376EA1CF6CB97085BB7A3202D8AFD4944 -:10BB9000D8F0C79BE72F8576D14AD6674165858D5A -:10BBA000AD5B28D30E56261F433F1A75E96E5442EB -:10BBB0003F79DD1F794476EEBCFB06289EBB9804D6 -:10BBC000B65358AF0CD6413A2A2521A6C04518DFF6 -:10BBD00008F7340DFAE90B7DCF2F8171ED0563462F -:10BBE000528AEDE346EF5CCD7EAF2EA9D1E8270166 -:10BBF00001617F0F58395DEAF4D73380F2E4816345 -:10BC000065F9C436F97E94526FD21151E107F86795 -:10BC1000B05A88383B5E5F3E3B5B555F692F52F5FB -:10BC2000FFC9A232557B8354A96A5F5DEF50D51BD3 -:10BC3000BD77A9FAAF6D72ABEA2905CB54FDCDE211 -:10BC40002A553D75F63DAAFEE9F69FA9DA49CE4090 -:10BC500081379D10A32930E6033A04815717C1FDAF -:10BC6000A518D382741A219519D0194A8BC39C86C2 -:10BC700065707E4A14EF2D785B4615D653DE7CB096 -:10BC8000208A549FF68AC909E52F68C8950D73006C -:10BC9000997C0340C7390F13299440CF636E1DBBB5 -:10BCA0004FA5DC26F9FECE09A5ED25B1086E047E70 -:10BCB0006273F07E4C16F813F9F88829847C3C0FE7 -:10BCC000E6248BE3F32CF138BB251CF7B0B414F950 -:10BCD000948489B502FA1D30C2CD423D70C4C8C6F5 -:10BCE000D9C2633A2941DE042797CFA7BDAEA53854 -:10BCF0007F47845A09F2F7DE8F8CA20DEBC319122D -:10BD00009455DE8F8C242DF1FB05237EEF10C62D7C -:10BD10005628FF69405F1FD2E09341C9C8F8F95423 -:10BD2000B191C94FCB83FA500A65FCBFC209FCD65A -:10BD300024CB61CBA1F1A81ED66F013D13804F4DDE -:10BD4000E27D2B08CA93CFC0F48D097E519E9E2EB2 -:10BD5000CC3840E671F92179846C94A5E99E45516F -:10BD600003D2ABB9D510D74FF06FE31ACF255A05E0 -:10BD7000F376267D9FDEC7E47B63A2BE427A49E963 -:10BD8000391F833C924A62BB01F272CEABD33CD7DF -:10BD900009B7C0CE75CEE766F47E1AE8A6A748C7F5 -:10BDA000643A71FA7D1B7D5EC5BB4EB8A7E47EFF89 -:10BDB000E2A6BCDF14FAD2E2E4ED0768AC1A95996A -:10BDC000DF6B617CDA6CDAB4F5A203E9FF651F452D -:10BDD000FAFF92921498FFFDE137F344E4F3432312 -:10BDE0007963309F7F60248F009FB519C4ED420EA8 -:10BDF000E303FB76B8978E7094EDBF7DC0318CDF86 -:10BE0000DBC3D48EAAD03F38E161E724637DD6340A -:10BE10005C577B5F31598FBF2F898CCFFC3E5833E5 -:10BE200007C7A7844214EF1DF410EE6B889227A178 -:10BE30007EA0DFD414D298E70CD21BC6BFD16F24EA -:10BE400002F0491B8CC7739C2A3E653421DF1C829B -:10BE500073513CC768632ACEDF6520228DEFEFB3B4 -:10BE6000E2D88778FEF39B0D2400DF776ED6337A15 -:10BE70009FEFD2B379F45BFEA3AF08EAEB80FF52E9 -:10BE800060AB27375F3D5504F39E6F853A9CD7BD65 -:10BE9000C5C0E46FDDFD94F54FE65F855F9F95F9C2 -:10BEA000739D4FCD6FC9FC3A894F5BBF1B9F7E15B9 -:10BEB000E7D32AB4B370EF75F9C83F0F11FB419473 -:10BEC0009FEB270DF9B0DFD23EAB7D07D4E7EA4305 -:10BED0008FE4A15E38C9DBE7B7EDA75CBF88F7E068 -:10BEE000B98A8246B28B221FF1FBB23845568A646A -:10BEF0009CA6A2BC0AB152D443B0B484F7FC9A8188 -:10BF0000341DB2E177AE5FE6BE5EB07F5702DF0E52 -:10BF1000499C1F15BD576924BE4369D87FE0B6060A -:10BF200098E755188FDF67C8F355948D7B1AA09C4E -:10BF3000E3E47A3047DE87527F4FE67FD22A50A46F -:10BF4000E34A13A7FBB2EEE87A3C47E974DF6DA839 -:10BF50003757CC78AF0DED5AB0F42D9B0FF747EC67 -:10BF60003AECEF97E97E72F11F9EDB06E735DF6E54 -:10BF700061F7DA70625F0CEFB9A35C2078EFE68AB4 -:10BF800005F93E0DFE534AFFB512E2CB8ED73B2298 -:10BF9000131E4943AE47DD5CAFCE35F2F393081074 -:10BFA000A990E963615175BC9F727E4276B0FEE64E -:10BFB0008A17D83D6DBB9FCC67708A3CC5CEDDDC4F -:10BFC000364A37C13C6B0D92210DE8FCDEB4A6ADBC -:10BFD000172B0879AB0754241CE44C8F89F8FE0A10 -:10BFE000F0528F95D5633D05ACFEAF3D222B7367B4 -:10BFF000787F84F4697CA3B302E975B2F819AF0BBA -:10C00000D6B972C6C0E840888BD1699BCC7B5723D8 -:10C010007A6282F6AB833444687CFF1BAE15111F35 -:10C02000E893DFE37A30B0BDFBB74CCFD95B273C58 -:10C03000621AF2D5853EACFBBBFFE441DCF021D8AF -:10C0400009E42F7F9892029867FDB56C36BE3D3C9F -:10C050006A14910F74E31EA47FE03825C897FECEC2 -:10C0600009A63F9F837349B0EFBF756672BD1199F2 -:10C07000AFE3F7B980E314F9FE87E7FC6706EA2F20 -:10C0800053B7F8CE5D788FA7F5EC1E77B9C633AC01 -:10C090001AF7720EE625297CFF5826B737190315C3 -:10C0A0007618D724F36D72FB43323F02850D881357 -:10C0B000F08702DDD6CBFCD50247990678617D98E2 -:10C0C000462D20B72D11F72501CB4E4A3E52E903EC -:10C0D000423E4AC0C953F1DBAD961D385F45BCBE38 -:10C0E000CE079326E09CE6D65434A209EB07185FEE -:10C0F000A51497E7FBBE01DFF9C700AFC17D75004E -:10C10000101281EFDBAF55B2F2F2D0A322CA89C977 -:10C1100032FE0CDA05324BC7707D7B408D6F36CB1B -:10C1200072BBD9CDE5F929271510F782DEAAC473B1 -:10C13000DB0B7D7B902FFF58FC5EC609F8DC668C1C -:10C140005611EDEF1D88874D284FB06E25DCCF6B63 -:10C150001AFBBED7EDDAE7CC45B97A92F13701FE8A -:10C1600046BE4A3EE70B32EE51E479DD894B46C4C8 -:10C17000BBFEB0B63C77B99D2FE07EFA09A9D7B2D5 -:10C1800073F7C9F2DEBE97327AF9F766333A7D4625 -:10C19000F67A5DC0979FC13E0E005F5EF17A533321 -:10C1A00061FC159F37352B2D2EFF1D7B53D9B8FE13 -:10C1B000F255D99BA03E847C0FE7B81C769B90CEAD -:10C1C0001BF672B953D6FB30BA2E1BE5A7C6306EEC -:10C1D000B443FBF4C8850CC4753543ABB351FEA61C -:10C1E000DAE7CB2E7E1FEDDDDBB65ECCE6FCA007EA -:10C1F00079DA2ADB31FF8EA811E9BFB59B30FE1D2D -:10C200003EF27E07CAEFE548AA15EDDE67C7520386 -:10C21000A8EFAF1C4F09E960AA36E477D0679F19F1 -:10C22000C6EE66F871486F45FFCC7FFCD367501EA1 -:10C23000FD47401A61DEAD914727D0BEB545965EF9 -:10C2400012B07CE5FB9587F6EE9FB3F32AF54F7BA2 -:10C250004C22EACFCB02D7135BC387199EDD7AFD50 -:10C260006A95D786E7FCAF85A8CFFCBFBABA10F5B0 -:10C2700098FFE8D585D8EE7F3DB5530B9FBCEFD630 -:10C2800033BA2AF6B1E4AC2025F6EB95F9A3A4F76E -:10C29000C9FA52A05FCDE81ABB5E8CB7D754E8BC90 -:10C2A000D8BFE6DDDAEC2D89E362423D7E5F305A8D -:10C2B0009BBA39812F1F721B643D04520DFA679D92 -:10C2C0004CC375058FC7F455581702328EA0371826 -:10C2D000DE26A2B010FD7782CE3DE98F090CCF0497 -:10C2E0005AF5A10A686F8EE9247315F3EF038938B4 -:10C2F0008310EFF2B978DFF7E6DA7789CCDE931EA8 -:10C30000AC3F5411427B4F02A691F2041CB42EA6FE -:10C310008BA600DF344552A28887D6C5840BAC2E8D -:10C32000E3A30FADAF3D826E27E0A38B893807F002 -:10C33000D045355E22E9B85F052FBD87B80AF06C9D -:10C340004B57D480F60A7092AAFFC6A61F5F423FE1 -:10C350006C63B7FA7B494CD0AD84739680BA433294 -:10C36000F4C7F698503E149C89F735A821EFFB5D81 -:10C37000FCBE1439EA8DE9D83DF4C65CA672289F4C -:10C3800095E568D0AA230198BF37B2FA20FAE9BD33 -:10C39000D7D7A622BD7ACFAE223B50DEAD2E5305B5 -:10C3A0008EBBFE6353A32DCE1F93F4878BEBC73850 -:10C3B0001ED0B673CDF2BEBE2F7BB7D6F5C3B07715 -:10C3C000E0576F70E532BFBA99C73DB85F9D6C27E3 -:10C3D00014FDABCCFB847CCF93F5EF25865FC0FFCB -:10C3E00065FAF70997C8FA4D8F346433BFF8EC9AB1 -:10C3F0006C316DF2FC65825D97659B3CBF82D7FC1A -:10C400000169C4847E8CA467F2E95F434314EB5E48 -:10C41000CA70B67FBD2184EDCA7E626B28EBD768F7 -:10C42000A721338DE33F051FDE6C5F00ED2571BC56 -:10C43000A8E0C29897323F688D6460EDB9337C8F75 -:10C44000B86AF07C66F6BD66319F17F4C008FA47FB -:10C450006B7F4A09D303325E54F833194F7E1E298D -:10C460009BF64D71A3E764BE54E46B46925C28765C -:10C470006A48B6D31D68A71D68A7BF36A21C4C85A5 -:10C48000BBC14EEF73B171848D5FF0AEE0D5F2BBEE -:10C490006DB21CBDACDC5BEC0D27EEB798C4B6A347 -:10C4A000BF3895FDEC9771CC54ED43323EFC3639E4 -:10C4B0003E2B9FEFFB92E3D80F448E6FE23FA3F633 -:10C4C00039EF753BCF23FF5AF49D3127CADDAF0DFD -:10C4D0002C6E9DDCEF09D91E833D53DDCF48B15151 -:10C4E000877E8FBF95C7018299E23BCC3F79534F3E -:10C4F000709EADD70A194EBBEF5A262B838584DB7D -:10C50000D1074B58DCE6BE97460D128C6FEEA2F3B6 -:10C51000311ED4DCAA3E4F30575A9A18070F160E18 -:10C520009C42B90A1C2C1371FE163C2CC6435A338C -:10C53000433B317E81719C79F8DD12A703ACD32E89 -:10C540007FBF4B8EEF90241C7074F83C8BF7F8077C -:10C550002941F93546407FA03E39CDE31D1D11AE7E -:10C56000173EE936337DF289C0CFE1EFA6A1ED3465 -:10C570008E232E459ECA43399B842724C01379718C -:10C580003CD1FEC2BB4C1F26E387AC41BE8EBF4DE3 -:10C590001FC278CC48F1428AF576F007F311278A5A -:10C5A000E24F8AF8BE4888E91549152739701BB74C -:10C5B000FB9F9FFE77E647360F5192CD7087142B75 -:10C5C000CF8BE38E8DC165CCFE2B3863E3CC532338 -:10C5D00045389F8C33ACF08BF1C3649CD1111E3570 -:10C5E000A05F30094F24E1880AB73A2E3853E07132 -:10C5F000D699116AC578D24C999E77F45B182EF6BD -:10C600007CB0391BE55CB99FCB0DFCBE2E9FFFC2F1 -:10C6100089E3167E205851DF1E3DDFF5DB225E17D1 -:10C620004D228EEB4A453FE4F2070FA4223D8F4294 -:10C6300049405E5F3F2768C60FFF3E1E37BED38D61 -:10C64000F6ED61396E2C807D4B8FC75F92C7BD269A -:10C650008F0B829BC1E28E4384F16FB0D0B78CD533 -:10C66000F79592832CEEC3F9F57024D38A78AF1234 -:10C670000EDB0D7AE21F2DA417F32BC15CDF5B4CA0 -:10C680003EF6E918FFC2789697091C1299BD4392AD -:10C6900061FEA3CA087BA9267C3190B739F2BD158B -:10C6A000821F8AF917D8CD9A1B40A74A390F5265C5 -:10C6B0002102CEFF98C1B7EB76CCBB0C0BF6ED3860 -:10C6C00046B06737A44FCEC70077B37D2979198A62 -:10C6D00079976FC8CB505CA78AF31BCBC31089DE58 -:10C6E000488DE75FC84FBD2C29B473512741BF73F4 -:10C6F000B187F0EF93F3298F3B35F229FBD0FE3061 -:10C700007DABCEA7ED9AFD1AE3B7EF9A473BEB520C -:10C71000E64B5E5FE47E67D2FA0B323FCF63FECB1F -:10C720007F7F95C1EC59E42AB33B57C653488CC56B -:10C73000EDC6789C3A6260FEFA15F0837213ECD96C -:10C74000974E4E87131137E3C7C1586D2AF62F96BF -:10C75000ED65FFD935AB57229FC4047B05DB25F778 -:10C760006B0663420DC70793E874D0A5919F3259B9 -:10C77000B83E4FE6CF46993F1BDD9CEEEEF3DC5F03 -:10C78000F177F1FC815596377F27657AE554711E64 -:10C7900055E2C8F95AF985A171A6675BEEA5F68046 -:10C7A00038757E61B7EC6724EBA18EF0217E6FC9EE -:10C7B00071DB7A0FD33BB71AB725E80D2F8CEBE965 -:10C7C0000145AFCCE571DC3BDC5676DEACCEF9CE74 -:10C7D0007C123FBF063DC55AAD3CDEE47EF3EA6EF7 -:10C7E0002D2FD829DD5ABF17A55B5B77F016FB9D6F -:10C7F000BDC57E73B4E44CA35F8EF3D6CEF18966DB -:10C80000BFFFA379D0E43C67725E3439DF99F2E66A -:10C810009600B63D4A1F1F8F2275338E3451105932 -:10C8200021F30513CAC98AC53C2FD05F6B0AEDA757 -:10C83000F1FCA842AF020FC75F56DB44201BE83C67 -:10C84000438AD566833C5F594C98FF70C5CCF3038F -:10C8500044B01636B0FBB316AE02BD1F346BE79979 -:10C860007E5D27E3E929F4C9128F733ACA8B1571EB -:10C87000B9C63D1E96E394D63061711B228885AB04 -:10C88000D8BA6221DA9B696FF0EF195122ED67FB8C -:10C89000124B56311C2D96E0FE76CBF9AFAC65B34A -:10C8A0004A305E97057617F3234F619E84F901564F -:10C8B000D64F59EFF95ABEDE6E03A198CF0ADCCEEF -:10C8C000DF57907FB3AAF21B670CD18B9B28CB6FED -:10C8D000DC81FB7F5B17B51D28E1F782F4B50D5AAB -:10C8E00059DEE5378BFF61B68FADC3F31DDBACBC02 -:10C8F000CB49F437601FDB8E3918FF369F58FCBBDD -:10C90000F5880BCB0546E749785CF6B3CEC97EA225 -:10C91000E2678DA1BF98E0772CAFD54DA59796D74C -:10C920006AC8D56ECAFDE0C0DBDC0F7618ED659DE8 -:10C9300009F7B4B696F3C3A6288FC72AFE6D9514DF -:10C94000D2E5011D1C0FE9A32960AF1D7D738DA8E1 -:10C95000B71D7DC516165FDA7C48A7D05BEBDE37C6 -:10C96000D5723BD27F7A9CE5270E27E5299FAF350C -:10C97000B2F62C991F9FAF251C4F55083BD10C4F89 -:10C98000FB6BAB5E2B3EDE02F81FF7B729C8F7AB97 -:10C99000E4435AA2A21BD7B93032DE8765756B8992 -:10C9A0009BC50FDB26FAD07EFAAF5F3DB584C50389 -:10C9B0008C22E2ABE479E778F46CFDC30848905E22 -:10C9C0004B8510F6732C15D87D67B598993F9E65F9 -:10C9D00020FA34AC37707B565D9FE3C63A5993C951 -:10C9E000EC71F56931738B2DEEEF672DEDCA453A89 -:10C9F0007D5B9E48891BE4CE907620BF7DD73C515D -:10CA0000FB99B3463CF78631759E48C9FB4C952788 -:10CA100052F2B4FEFA2F547965BF30EEC1F88AE3C2 -:10CA2000D8059627F687A9B5A0249E3FF20F4E1889 -:10CA3000197DE5BC11F437E2B8C11E9E3F3A02EB06 -:10CA4000631986F34AB08F7F86F3621981F3E2F7A8 -:10CA5000E33DB35919EDB1B3F244CF22563A806D9C -:10CA60000AB330EF34C1F24E2FD5AAF3164A5EC294 -:10CA70005EE8FD05D229216FC1EAC9790BBD85FBAE -:10CA8000A3FED306FB01F8EE3F63627AD619D934D0 -:10CA90001371D997A3BE99569607C8667EA5C20F93 -:10CAA0009725BB3913FD01AFDD8CF902C7F025A333 -:10CAB000C8F44EB4089F3275083123FAFD4807893F -:10CAC000E139A719E9FAADF1FDF0FFC7F7BF4B7CDB -:10CAD0007F5E5C2E99FEA8F6EAA4FD589E96CC5B7C -:10CAE00012F443BF97C789FBCB4B99FCEDF19666D7 -:10CAF0006E4E8CE7D7733F2E6B69B939F17B97C7C0 -:10CB0000C0711F255E2D3DF6F5D4FAF66B2D7D4BD9 -:10CB1000A6C80BF4D7733DA2C4FD27E709EC6F96B6 -:10CB200027C4FB2FBF0D7C0A7EEBF0500AB3E75FF2 -:10CB30001E4B3980F8BBBA7EF3CC74A8579F4B21AB -:10CB400025DC1EA9F20BCDF53AC99CA1954F908A20 -:10CB500074C0B793F206F53AA6DF6FE60DEA850BCF -:10CB6000AC2EE3F40D137F482FA148FF5010FD8C2D -:10CB7000C3EDD43E4C26E71160E222B2084E517F4D -:10CB800096E595ED9DD42E8ADF9E5FC893E30C1D3C -:10CB9000E14C3DF279CB1B84E0BBADC979867A8646 -:10CBA000F7ABC993C15A7C8F55AEB3A23D4B8E17DC -:10CBB000209FA0FD4F8E13CEABE3F7384FC62B61FD -:10CBC00019DF57CBB84419977CFFBD75EA7C4472D6 -:10CBD0007B97DCDE5B5FDD8FF71758A12368077A50 -:10CBE000EB5DA6F284F95C75FC1DCD6ECC5BE42494 -:10CBF000E62D787E22395FA1E829C7F0D71EBCFF59 -:10CC00003D111E4FF217F0F8A6E3B8F334CA7D7C4D -:10CC10009FDCDEEE813B8E311C65CF24FC5CC4C4FE -:10CC2000E35E2CCE50BDE28B13A9483F2FD82BD406 -:10CC30004B67CA77A6A13E5921D45091C5BB6FC698 -:10CC4000BF313EB5FA9DD66504ED7FE3FC51A47B70 -:10CC5000E37A037B87A4D8ABD5EF347978FBFE1D4C -:10CC6000166C9F4DED6611BFD7BBF0FBF257A218B3 -:10CC7000E9232B91DA2037B13317059497DC19BEDD -:10CC80009FA17FE46890E3E0EBB97D6D8C34184898 -:10CC9000DA647B77B2F84BE6475F8D38587C3B1BF4 -:10CCA000F3AFB6B8BD701C033B94FE97B343BD759C -:10CCB0005646CF796087703F590D3C4F987CFF2EC8 -:10CCC000F9FEA7B22B53E951B423BA455C6E684113 -:10CCD000DCFE8AE85FDF11B7C3D630D4F3BF21EEA4 -:10CCE0002DE3ACCC2970D82F657E9FF2FD46F8FB72 -:10CCF00089831FAAFB81C4C1653F4789872B7E5169 -:10CD00009A8C639532DDC3E9FEBF7EBF8CC651F3BA -:10CD1000FD7296F6FBE50D03147186F27E79C44828 -:10CD20009C8772F0DD1E25DB51BE430D0CE78C3C69 -:10CD3000FBFBBE97E17BC720B5A2F9691F1865769A -:10CD4000BA1D700DC343914F799C6A80BF376D0F38 -:10CD500053492B0EBA40B6CFB512617AA35D7ED788 -:10CD6000E719E4721D8F13FD5C488C13F9C558AEAA -:10CD7000F25E30C4ED93E6BBBE0E32CEDE0376B477 -:10CD8000527B14BE27C78D92E3454FCAEF00A78C94 -:10CD90001B49DFEDBDDF9FEAD2733E061650E2CF9E -:10CDA00005B53C4ED4E4A314E737E9BC6DECDDEFE8 -:10CDB000716AD57A3F9AEAE17667B91CBF7DD1C81E -:10CDC000F9E1C53B297B4FBF9CF038ED8BC7F9BB20 -:10CDD000FA17ABF9BB7A255EABBC97BF3D1EAFDD42 -:10CDE00083F15AE59DBDF26E9E9010BB8786BD967D -:10CDF00028E28DC70C0305288FCA7BA3A375DCDE50 -:10CE0000595248A7967C7E55E73C5AC7FAE9A6884E -:10CE100077FAF23D1A71209FECB7157BA6C4E9A200 -:10CE2000275785D3593D19A7FFA5E2B547EAC8544E -:10CE3000FBBF5F1BAF4DEA77F116FB9DABD3A0C7DD -:10CE40004E397E924CDF1E8FA287A75B193FDDDC37 -:10CE50003FE1F95C39EE3522DBB920157F7717CB3E -:10CE60007F1958FE4BD133C1743EFFDDB29E51CACB -:10CE70007BE53268D08ED374C9ED730AA595788F9F -:10CE8000952FA9E3667307D471B379E12C557D7EA4 -:10CE9000F436557FC7E952557B4D6C8EAAFD8E73D3 -:10CEA000D5AAFAE2B13B55FDEFFAC4A5AAFF685C2A -:10CEB0001D375B724D1D3753F8DB091C9138CE6D61 -:10CEC000FA1B55BFA256F5B98A3BD5E79AD9AD3EB4 -:10CED00097326F49407DBEB2A0FA7C5918D7B7FD92 -:10CEE000F971FDF15A518EEB979971DCEEFA7233BC -:10CEF000E2183DE631E1FBFF001DADB367003400F1 -:10CF000000000000000000001F8B0800000000006F -:10CF1000000BE3146060F8510FC1D3F9191836F310 -:10CF200023F8F4C0C79819188E83302303C33E201A -:10CF3000DE0AC46B80F83D0303C352203D078827F7 -:10CF400003711710BF048AD5B1623787858D81813F -:10CF50000D884F02CD3AC54CBCFD8A7C08F6215E97 -:10CF60000686B5407C9497BE6130D8F00C41FAD962 -:10CF7000F50C6AD76ED181F73708B38A3330304A5F -:10CF800020F8FD12A8F26CE20876960C6576950101 -:10CF9000F50300295128158003000000000000005F -:10CFA0001F8B080000000000000BED7D0978544540 -:10CFB000B670DDEE7B7B49BA3B9D90952574802051 -:10CFC0002A4BCB1201113B2189010306440928D2C7 -:10CFD0006C2184249D01661E3EFDFF6E0842C4D173 -:10CFE000898A1AFC195F83E004079DE0A0139DC0A5 -:10CFF000348B8833E804C70597795F401E204212BE -:10D00000A338E8F3C9AB73AA6EBAEB763769B7FFFA -:10D01000F97FFF840F8ABA55F7D4A9B3D5A9537500 -:10D020004F149D9524DD40C825F8A1E5AB0A2124C5 -:10D03000255876489DC3E581C1F6B55E177119097B -:10D0400079C06BC272BD379DB8AEA0CF47EB8AFCEA -:10D050001642EEF7DAF1F9E3DE122C1FF59662F9CB -:10D0600088D78DFD1EF29663F92B6F0D96F77A8B9C -:10D07000B0BDCEBB0AEB372A0BD2605C425CA6ACDB -:10D0800064423C2F0F1CB981D6D6678E4F9047D390 -:10D09000FA5FF5449F45DF1B2D17F987D206B9A427 -:10D0A000286B74B09F8AE78D4A5E5F80F3F8581D45 -:10D0B000EB67AA792D3B72BF2C3286E2395646FCCB -:10D0C00089A564727672C47E8301DE2343D93C89CC -:10D0D000DDF9DAA0C8F0AE06780F0DE5F825DB27FC -:10D0E0000F8A0CCF09FD7EE5E4F0D23B0F0F8CDCFC -:10D0F0006F0CF4AB7372787D7DA60191C71D0FFD97 -:10D1000062E013C589105F8BD19F9DF5FDF9455CE9 -:10D11000F42FC5A763AF79EB0609F9370DE8B4D64C -:10D12000BEFCCC163A4E7BCB30A7DE41C8672E67DB -:10D1300082DD1213DF6E8179C4C0B752182706BE94 -:10D14000CD8D916F0BA05F0C7C5B02FD62E05B6597 -:10D150008C7CFBD94F846FF7021EDF836F1B62D478 -:10D16000B75FC5C8B78D31F26D538CFAF6648C7C0D -:10D170007B2A946FEA73B5DC4124B48B372A253BB4 -:10D18000A09F27B3CD3620EB27C1BF3DDF53EFF67D -:10D19000C7C8BF5763E4DF11A04F0CFC3B1A23FF45 -:10D1A000DE89917F1FC4A8776DB8CE58E4AFDA86C8 -:10D1B00010FCB93400FEB5D84F5DCDEB7AC03B8989 -:10D1C000908C7039504BCA51940799B8DBD9BA5535 -:10D1D000F0CDA51C425698E87FE9FBBE3C12D0D3A7 -:10D1E000F17D36E2AF9584FE9F039E84E47F732930 -:10D1F00055E8EFD345EC4F74D0FE30C815E5FF6617 -:10D20000EF102CEBB91C6D2ED2A13CF8920D285FCB -:10D210004F789DD8DEE01D8BE5635C2E3772397A3E -:10D2200000E4EE0A90C3522E574CEE082971945335 -:10D23000BA76EC89271B1C28576609F09499BCDD47 -:10D24000BBE7CAAD1B28FCCD35BA2BB785C8D913AF -:10D2500045AA7C51C94C0EF67BA2FC846DC150A43A -:10D26000B70DE03414EBD47EBED07E0DEEEE7EBD65 -:10D27000A0DF63C55CBE6412081DF7B1D2EE7EE983 -:10D2800012A5CBBD12296DB284F3658AC4F4942A29 -:10D290000AF243E6F4DD9F7796B4D1F76DF6916913 -:10D2A00084964F827EA2FE39B054DFAFA7747653C6 -:10D2B0007A641A494D13E04B5A2585E22B8F752469 -:10D2C000821C3D34CE45242B21FDA19D8EDF677449 -:10D2D0001BC9A265E2F836220D837EB49DD6537831 -:10D2E0007BC650DA4EE13C04EDD6607B2A6F4F736B -:10D2F000F0F7AF63ED0F7B098EAFF6BB8FF2D94D20 -:10D30000F15B47F1C5E7C5C4057494293BFD21F3E2 -:10D310009F2DE971DE95BC54F1BF2FFB54C6FCA1D3 -:10D32000417CCD832F66CC0FC1EFBEC173B0AEE29E -:10D3300063BEA212EBFD57F5A69E18D707124EE763 -:10D34000D49903847687EC443FCD71444F7C945F3D -:10D350000E2A9E91F8F30515E71F54FF5C8C1EDA28 -:10D36000F6BB3574589721D2C1D05BA4C3BADE2274 -:10D370001D0C7D2E4F87299203E147A3873AEE8645 -:10D380002BC571E3AE12C7DD7095386EDCD53FCC8E -:10D39000B8EBFB89E31A33C571D7678AE31AFB7FC1 -:10D3A000BF7189ECA40F99B9200EF8679E60DF2E3B -:10D3B00010F7C3A0DF60E7F4C9413B27DB4B88DBF4 -:10D3C00012E42791E9CB39A170EE14EC2A85F37FA2 -:10D3D000381CD7E5E1D83570E66AE16CE37048A8FF -:10D3E0009D0E8343EED0CEE3B7FCBD802E647CBAA5 -:10D3F000BE92126BE87B4ECDF8B76BC7DF0D760C93 -:10D40000E6A1BBECF80E0D5DE768F1D9C3E110DDD4 -:10D41000E5E841EC1A38B3B5700E713801E9B27025 -:10D420004AB5F3785DE5AB24AC5F941EC382EF751B -:10D43000E4759E423FE845C5B19DB64B7FB2066E8E -:10D44000A0FD8F6C91FC465A0FEC8DC7F5E3FCB63E -:10D45000E958DF778D11D789F3CEC97E23B527939D -:10D460005E78DB06F6A5EA05BD0C75DDDE8F6D6D19 -:10D47000142F8FB1F5C1EBE8F3CE17F4642B4A6398 -:10D48000A10EE87E8ACB2659C5EA656656ADDAB2AA -:10D49000EF4E805BDE6C24660AA7EAA525D3AEA317 -:10D4A000F5258715025DAAB6AF36F4A6F5A57EA9C7 -:10D4B00009EA1D79A41CF469CDDEFF6C87F5E8FC50 -:10D4C0006E251BC63F4BD70907B5C747ACADA9337F -:10D4D000291E15FE5D85F05EC54EC9492D1CC57718 -:10D4E000FBA10CC07787E434527A2F6B8C270ED5C2 -:10D4F000DED1BFA776EB71FECBE9FC0985B784D4FA -:10D5000017023DAB803830BED3E8374B417D3BEB53 -:10D510003D8CE3A9F5AA1D743CFA7EF5739213A61F -:10D520005AAD236EC0B3FD2573E9531698E76AC35D -:10D53000602BCC6FBD01FA2DF1CF7FD1EC003CB751 -:10D54000180A01DFCD5B0C6543817E645EC950C063 -:10D55000EF2F227E0D7A17CC77F935C6AD7AE0A78A -:10D560002530688635DCCE9EA5EB952364FDAC2086 -:10D57000CCEE13D96F983E2CF8FC257D22CAC1B29F -:10D58000463D7184DA0D2E1FBEA384F9317BACFEBB -:10D59000ED59413E2EB77379E57C5C9EC8F92A7738 -:10D5A000E6CC18168ECF83C01723F38FA07C98AEDD -:10D5B0009B0EF47F1C48BFC7A8FFE440FFC889CF7B -:10D5C0009FA07E12949BA99F04E593D44F82D24FD3 -:10D5D000FD24E8B795FA49506EA37E123C7F9AFA73 -:10D5E000E7503652FF1C9E3F43FD7228777A7DF844 -:10D5F000FC396F1D964DDE7A2C9FF73660B9DBEB58 -:10D60000C77E2F7A1BB16CF636E1F397BDCD58B6C5 -:10D61000780358EE053ED332E06DC572BFF7189619 -:10D6200007BD6DF8DE21EF192C7FC9E96E9B4072B2 -:10D63000652A2F3617B1039B928A5DB9E0AF249516 -:10D64000B07AEA1DBE5C03ADA7BA699DD2B1776519 -:10D6500020D748EBBD6B587BE63D24CF44EB993E89 -:10D66000D63EE097AE3C33AD0FA867ED8337FBF2B3 -:10D67000E2687DB09FB55FB53390174FEB5735B17A -:10D68000F6E12D649285D68707587DE411D7242BC7 -:10D69000AD8F6C65F59C0F7D936CB49ED3C6DE1F79 -:10D6A0007F2E302981D6C777B2F6895F937C3BAD58 -:10D6B0004F2412D6F32CB9F989B49E6767F5C2BE20 -:10D6C000F3654784F57DAFD2B6104CDACF7539B922 -:10D6D00032F513F61ADA5680C95DAFBB21571E47E3 -:10D6E000E9A79045D0BE4957C4EA06B212DA7FAB2B -:10D6F0009B8EF5FD8A03DBF7E8E6B0BAC181ED7FCA -:10D70000D52DC4FA41C585EDC77595AC6E7061FB2A -:10D7100067BA9FE378871437B62BFAFFCDEA06374E -:10D72000B63F2CAFCFCDA7FD2BF56E8F8ECA75AD52 -:10D73000E42E2703415E9BD2C11EAEE37EEB2C9DFF -:10D7400003E57E5D8601F56CEF7FE53C857A063F5B -:10D75000C9502F7B1AFC5E0A6715C251281C7DCF69 -:10D7600070267E33568033F19B7215CE6A84638EA9 -:10D770000DCEDE6FC68BF87C53A1C2D9A0A3F6BE36 -:10D78000D61ADBBC265E9A20E273A95285F308E222 -:10D7900093181B3E01E55A014E4059A2C2D98C7024 -:10D7A0005262C3C7651827C0711996AA70B6239C28 -:10D7B0008CD8E0040CD789F81896A9709E43FAF427 -:10D7C0008B6D5E2EE3F5223EC62A15CE1F109FAC50 -:10D7D000D8E0ECB78AF4D96FEDA64F00E164C73604 -:10D7E000AF3C9B489F3C5B377D5E433857C606671E -:10D7F000BF4DA4CF7E5B377DDE4438C3629B575E4E -:10D8000082489FBC846EFA7C8070AE890D9F83290C -:10D81000227D0EA674D3E724C219131B3EF9A92258 -:10D820007DF253BBE9731EE18C8B0DCEC154913E4A -:10D830000753BBE9F305C2B93EB679E5A789F4C938 -:10D840004FEBA6CF258493EB6E447C0885638D0E49 -:10D85000E7503F913E87FA75D3C7A407380514CE29 -:10D86000C09EE114668AF429CCECA64FA21EF46295 -:10D87000726C700E658AF43994D94D9FDE88CFD4CE -:10D88000D8E655D85FA44F617F461F8FB173921DB4 -:10D89000FCC644E2DC4A5F9994FCB383B0EE2816E0 -:10D8A000E204B047A4C036804FD756F44B65A7EAD0 -:10D8B000073909F8B9C5368713E2017AD5DF21ADFA -:10D8C000B81FB1EC4C14E24D2FE9F38603BE56EAC3 -:10D8D0001586FA3D0963E3047F2BD19524D47B158B -:10D8E000F516FAA7940C10DAD34AAF12DA33DC2318 -:10D8F000857A9FF2F142FF7E357942BDFFAA294227 -:10D90000FF2CDF0CA13EB06E8ED03FBB7E81D07E5F -:10D91000454385D07EA57FB950BFBAF15F85FEC370 -:10D920009AD608ED239A3708EDD7041E16EAA30EFF -:10D930003F21F41FD3BA5568BFF6D83342FBB8B6BF -:10D94000E785FA75675E16FA5FDFB95FA8DF70F1E9 -:10D95000CF42FF5CF237A13EC9F481D0BFC0FE9137 -:10D96000D07E63FA271A3F568C5FD4E612E6CF6664 -:10D9700018D09F0D580D5837EC35B3FD0DD49321B9 -:10D980000E518C75C3FE858E6488070000EA4FE453 -:10D99000F62EBF02E255BF18EFBE02E2B8BF30B8A4 -:10D9A00047D823F841EDB2FB1E3DC6135B25920E0E -:10D9B000A54307659C9EC7138C4C7ED767E53CE565 -:10D9C0000BD183BA7ED4BFA0F5F57A8AC798A0FEA2 -:10D9D000ACEF57963E3F649C75FD0CA55B87B2E7A4 -:10D9E0000B2D305EC97D309EC7D03918F0D28E63C2 -:10D9F0001C305618C794598EE36C84715282E31818 -:10DA000033CB35E3984AB7F2E77C9CC7406FA28DD1 -:10DA1000B37EC078713E991538CE16CD38EB332BD6 -:10DA200034E3C4B1F9D0E77C9CA72E378E71E004B3 -:10DA3000713EFD2B719CE7B4F3E95FA919C782E33E -:10DA4000C0731887F4A5BB9834CA67636719CAC145 -:10DA50009FCC182733F4A9F80DD4C90766920DE3BB -:10DA600038E8B8B41F199244859A907FD127217F56 -:10DA7000BE88A3FC0F89A705F7E33EDCD72FE62875 -:10DA8000123FC588EE93AAB96C2EDA393D738583AF -:10DA900096CD07063D02E36CB43AB369BDBD7992F9 -:10DAA000616104795A5CAF9C6A0B91F3EEFD591EDB -:10DAB000195243C75F1167477CD4BA5A26E9C4E7B5 -:10DAC00027E8BE8BD0FDC987749F42E87EE5238599 -:10DAD000ED33FF9DEECFA0DE46F767D04EC86A7CDF -:10DAE000EF048F339FF8A5E4077A7F71D7CF145CDA -:10DAF000277CE4ADF4548826B09F79ABE2291382E9 -:10DB0000F8CDF7F512EAD41CF7D1A5E3BE16E3076A -:10DB10009D2F19FD5B81AE757D284D79BF0184BCB9 -:10DB2000BB77EA21C986D53EBAB184CCAC995E9068 -:10DB3000865A24F55B4EF19CB1FB1A85BE41DA95FD -:10DB4000B63B9D96205CE2524E007D4CF40FC0B96E -:10DB5000A588D643C6BFB544ACCF2272B04EF97D7E -:10DB6000523F80B0F83F1FD7E15280AF25748E1925 -:10DB700094D5B3A01C09CD2C5E536A67EFAAF87840 -:10DB8000162A2480FB6B5F0AC4B1892F19FBCD5183 -:10DB9000F7C91AFC4A1593AB84D2B574BE1EE9AA24 -:10DBA000C5F7FDBDF12EDD705AD63DA24068B627FF -:10DBB000FC67BBC57652CEC653E9AACACB29CEDFD5 -:10DBC00013C07F5A9E06FE53BC4F72FE07E598F1C4 -:10DBD000DF63744F03FE776ED213E417E7FB6D9C8F -:10DBE000EF8BEB45BEDF06E771B4FF6D2BB358BC7E -:10DBF000A9A197C05F3A71910EF50F1550B31A861F -:10DC0000FFDFB91CCCA9DBF50AB0F7F672CDFC3802 -:10DC10001FEEE47C98ABA1C76D9C6F7339DF961043 -:10DC2000DFBD1918BFF02B10D79B5D2E11B0179ECA -:10DC3000BB55BEB5097C73AB7CD3E07B27E7DB9D8E -:10DC40007731BE69F16EE37C6B6BF84C2103C2F156 -:10DC5000D6E2396F95665E3E2DDFEAB95CDA0DE0FB -:10DC60004F4D77E5AE3819D2FF96A2C92B4E86D814 -:10DC7000855B4BA60BF559A5B385FEB3DDF385F6A1 -:10DC8000DBCB970AED736B7E26D4E7ADBA4BE83F4A -:10DC9000DFB75A685F58779FD0BEB8FE21A1BEA4F7 -:10DCA0006193D07FA97F8BD0BEAC7187D05ED5B495 -:10DCB0004BA87B9A5F12FAEBF65E7933C8D791B71F -:10DCC000F504E27D179CA731CE78C1A938A1CF49D0 -:10DCD000AF03E5F89477089667BC4E94F3B3DEB1D2 -:10DCE0005856834C8E033B7BC002F1534F1CB5FB4F -:10DCF00089741D97C7ADA99B00EB0D6D1F4FC8BF61 -:10DD0000CA37ACF1F5A55A00716F4AFFE206030964 -:10DD10008C2254BA7B77CB73A73EA4BDAD87F606A1 -:10DD200099047A85B717B7457EDE21750ECE80B887 -:10DD3000EC7B46B23D24DE187EDE42FA805F11ADF8 -:10DD4000FD9C8E94879EF76C95D939CF117DDE5658 -:10DD500099E2556960FA5FF97C461EB1413D30B8E1 -:10DD6000C67299F19A283269C0E78182DE2F69B8BC -:10DD70003AA8E704C661F674A97F94F07C59E3756C -:10DD8000C27B6F48EE2D80C7B97D7A5CAF49E04019 -:10DD9000E62DC3003FD75619D6D1E614F4BB5ABDC1 -:10DDA000AE15271542DEF41661F996B704CB77BCA1 -:10DDB000A5581EF3BAB17CDF5B8EE587DE1A2CFF17 -:10DDC000DDBB0ACB36AF0FCB13DE3A2C4F7AEBB16B -:10DDD0003CE56DC0F28CD78FE5596F2396E7BC4DBB -:10DDE00058B67B9BB154ED674FF27786AFAF674172 -:10DDF0000E8DE1727670EDBC35757D837276582E8E -:10DE0000433953E95BDC60E4F2902AC8C35F611DCB -:10DE10004E0179E9A1BD41E17218EDFDC8ED206F19 -:10DE2000BD7F047923640DCA8105E4EE7BC81B81A4 -:10DE300053841490A73E1A7912E550952355CFDFED -:10DE4000904ACE817CA9726591993FA4CAD5FDE024 -:10DE50002746F0B77A2B125FFF987F4402B93A2029 -:10DE6000D9727E5E417C2EAC77F1B16B29B856E851 -:10DE700027FB87C03AD235E4ABC110DFEF3A4685C5 -:10DE8000202BFAFCB4F2129DEE2EDC3F94F929F31C -:10DE90007B85B79BE3185DCD3A524446C2F972CEFA -:10DEA0003137E567DC9FAE1E09FB66FA5C26490048 -:10DEB000C7EF9C1EE1BC800C2248E79EE8ABF63F12 -:10DEC000F5C47FE6C0B9BF05F49CCE3DEE80BE86AA -:10DED000E9EF53CE5B42CE973C46673AC4C13BB3B1 -:10DEE0000D76E63F4C12E94826E1F9814AC703D98D -:10DEF0005F0C86F399FBA81C827E750D1A9C402E40 -:10DF0000231F3DD9FB9EE8B900E61B133D0D04CE4F -:10DF1000B9283DB7C27DC758E9D9939DECC93E9E4B -:10DF2000D8C0E87C84FBA7D1E8AC9E8769F1B845EE -:10DF300091391FB81C933B34F42F15E8DFD7EAC0A2 -:10DF4000FE07F77E9009E7785DBBAF48204343DFCB -:10DF50002F60E73DDDEFE70B7A20FDE9EF99B03F59 -:10DF60003EF8C2BB58AE254C0F375A4AE62A6382A8 -:10DF7000F062BD47106D5E1E4512E7D5837E76A424 -:10DF8000AAFAD99A09F2B49BDB81B0F9F5209FEA8D -:10DF9000FC0EC0FC289CA920D3741EF972C95DC276 -:10DFA000FC46A7E0BC7B9A9F27C140A411143FAB5D -:10DFB000C14012A83C2AEEB50AEEEB9C6D3E885398 -:10DFC000EC8D77D65296786C67DF0838E03D319E4D -:10DFD000B1ACD15C23FA4F8935A2FF945113EA3FCB -:10DFE000751D7ECAE6A6F82D4FD7D79CEC05EB9C95 -:10DFF0008BAF736C5D55F1AB6ACAAAB10870C47A75 -:10E0000057BD54C4EEE13812664638EF53CBE5E90C -:10E01000061CE76CE3C00418F7ACD754C3D6577B93 -:10E020000D1B37BD26747DAD5C155F73725410BF38 -:10E0300068707F68FCA844908F4CB02ED2B681D116 -:10E04000FB47E5A7FCB901CFD55B942FC07F370F05 -:10E0500051FD7719EB2A5C4F93DE671C01CF770ADD -:10E06000E3D1F71CEAD938BC175D6E64724AE5A7A4 -:10E070001ECEBB08DF1F9890CF6E0A3181C2EB9095 -:10E080002D7520577E85E9B387CB6995A9CDE076BC -:10E0900020B95B41AE178C55E5DC31EB036AA73F35 -:10E0A000FE8B82F7CCC8D7147A4EF0AAC3225262F4 -:10E0B00083A0EA82DDCB8A61DDFEF8C59BF83EBD18 -:10E0C0003E07E67D9EE88AC02E9D276FDA4685E8EA -:10E0D000EB6985C5B1481DDBE7F8E81F98DFE27AF8 -:10E0E00071DFB3A441AC979119A9606FCB362AC4F4 -:10E0F0004F715F0AFB2675DED4FEBEABD811B92581 -:10E10000A4661DECD31F5358BC67819DC87DA8BD74 -:10E11000AEFAC3AF7320EED3AE307F573D0F5F9A98 -:10E12000C4F6831533FD0617EDFFD1EE51B7518BC1 -:10E130004BDFF7AF43FF673A716E27E1745F5827F3 -:10E14000E2D713FE5A7C553F28EC5C9EE391DC2815 -:10E1500045BC2FF535B773AA7E2419EC42DC274D58 -:10E160005357E540E172E057DC56430AE33BF05178 -:10E17000923B0DEE907E8660BF24C398E8FD8CD064 -:10E180004F8FFDD258BFCE42DC1F132A4F4383FD71 -:10E19000CC41787DD9B862BFAA3F3CFBA28FCA4B65 -:10E1A000C5EF1EB511BA6E7E2CD7A73AE9F3CAEDBA -:10E1B000F7DA5CB43C23FB6CC0CF8FFDFA88F77DA7 -:10E1C0006F31A8F470592488A771F924753E8C53D7 -:10E1D0007CB15DB1E33942A33160A4F259BD7B69E2 -:10E1E00031198EF5E3ACBEFE533DD49B457E55FC04 -:10E1F000E6D15407BB27C4E24924807E6EF5B6FF02 -:10E200002884F5C2433A51CEB4EFC1F8179350AF0A -:10E21000E71B12C2DBF162702ABCCF7E3CBBEFFF72 -:10E22000546F8372F269D0238F464ECAB9DF0AF465 -:10E2300082FD7EBEC19A8CF6FE5A722DE8BB4A174B -:10E24000E267FE6BED8EC7871FA7789DDBF6179BF5 -:10E250003434D44E3079EB6A5AF86F265D747BD231 -:10E260004EE531D44FA280F13D4733F7BB5B58599F -:10E27000A9046C701FA7728BE2A492482A9FD51341 -:10E28000B89F40DE33FA213EBAECD957DE194FE988 -:10E29000BF6C97925CCCA663915283FCF1D0BFAB6C -:10E2A0004606F951F1FB570C8E61ECF93D4941BE30 -:10E2B0002CDBB5CF408685D37152D33E439B2502DC -:10E2C0007F9A8E17C27A5BBBE31F06882B7EBC57F2 -:10E2D000226959E1EF976F7905D73DA013F293F3C7 -:10E2E000AB9B7F617C0B4C7B7934F6B3833DEC892F -:10E2F0006FD9B09F4B41F97EEE65B8C7F4BED10926 -:10E3000074287F6E850DE6735AAE6172FEEB7B5307 -:10E3100041DFCB155FAA1D4BF6BCFCC99FA3FC2DAA -:10E3200039FAF354F41F882B4387B6D99701F35C6D -:10E33000BCF9569C671971A31C96FF5A5F02F74CF3 -:10E340002FC8A46857043DF98B81ED5F4E6FA5CCB3 -:10E35000A5F33C0DF8817D7B53EFDF8E71F39FE1D8 -:10E360003DB89FF339D39510EB174C8C5F5B0C3A9B -:10E37000351E6A12E477DBFA56E0D3D97EAE343824 -:10E38000F7A074F071BA4997285CFDD18234C62792 -:10E39000E29073F87BD4DE4F82E7D0BF5571998746 -:10E3A0000BEF71FBC8C65FC9C7A778C7C1FA753A3A -:10E3B00035B2FFF70F3E3FFAD34A42E42C44DF99CF -:10E3C000FE6FBB8FE9BBAAFFFEE945D0FEF95B4CAF -:10E3D0008FE03D582F285E81346CDF375342FB407D -:10E3E000F7D991F47C9BC2F55C6CA73B1C5CFF5594 -:10E3F00039A1F8CB5242A8BCD07192900FB83F2EF1 -:10E40000DB48DF0FF1CB3C302EF633049F87AC1B8B -:10E410004BB85D38A4B10764734A4C7E74A5E27FA3 -:10E42000FA09D0DFF78C4E9F03F4572981F97FB2A8 -:10E43000F3C03B73A89C7FD2A4EAAD6857B57A5B62 -:10E44000FEFC1812496F3FB1D07D5724BDA5CF23E4 -:10E45000EAADA50DE5F9FF965D55E9D7AEA11FD848 -:10E46000C7971DD1E9A8B58F1B0C8E88F691FEBC0D -:10E470004572C2E550953F55EE2A7E5BD51FEC50A4 -:10E48000B77CAAF2D72D9FAAFC69E72BD24FDBFEFF -:10E4900007D06F8AD7EDA64DD3C07F3675128CC3D7 -:10E4A000E7CED4E33D4DD3E784DDD3B8231EEBB3F1 -:10E4B000F46DBF079FF083AA59C3609DBF9DF814F8 -:10E4C000766E5FAFA01FFBF5A54B13E87CE670FAF4 -:10E4D000DE4EC93D95F2A35496027114CFD932F1A4 -:10E4E0002524413C59222742F0B8BD5CACC3CFC4BF -:10E4F000D4209C9EFA7F5BBFFBBB9647295F4F648D -:10E5000013F2372871FF411DEB10799ADEC2CE312C -:10E510003CA325FF00D4C336B924641FE13132FB8C -:10E520007334FF963140BFDC59C312989C0FC6FD6F -:10E53000A287DBB12E9F2301EC7B57CB40DC177603 -:10E540001D5E687547B06707B89CBDC2CF613A2CA5 -:10E5500052BD9ECA7D07E944BFC66731478CCBCD0B -:10E5600031AA769AF38DFEE8E9F8A55C0E67D357D9 -:10E57000134686F06DE6D48F655B381FE0E744C82C -:10E58000BEE2FBD217E41AE87BC0DC565812217EAB -:10E5900053C9E93771FF970658F7F25B7265A063BC -:10E5A000BE452FC4431619B9BE0E254301AF89FBE2 -:10E5B000973E3086CAB1E7B0DE69A6F3F3B47C6A51 -:10E5C0007047D8DF69E909F0C1BFDC6A64FEF2DB9D -:10E5D0004AC962A0EBDBB7B2F3DEBF199C5591F0DC -:10E5E0004C37337F733629B9305AFAE9D1377796E9 -:10E5F000359047E9D16561F7B5C3E58FE97D975D52 -:10E60000F2AF96400EF5AC9ECCEE371712F703131F -:10E6100024D4F71B42ED576EF3F467E13E4D758B42 -:10E6200064D7D1F66AB9CD0072EC69DE2583DF7E4E -:10E630009383B8707F2DD70C9B1912FFA2CB1ED2EB -:10E64000EBC05773E6027D3F9B692480976BE8A778 -:10E650003658FF3F6B19857A106D5EAF7BC9B47C6D -:10E6600005E0307BA69587C2E478A17EEB24D21723 -:10E67000CE81271ADB563823F02FDFC4E42C66FB4B -:10E6800066FAFFCCBE4DA0F68DC9B5126ADF2CA686 -:10E6900030FB9616C9BE2D5FED4803B958BE672002 -:10E6A0007EBFB5FCB5C52991ECDBAB7CDFFB1ABFA7 -:10E6B00007DED197DAB71121F6AD2FB56F11E2E47D -:10E6C0005FC46ADF4CFF33FAF72AD8B708F3359BEB -:10E6D00044FB56D4B21AED5B515FBD705F8998A8B8 -:10E6E0007D8BBF9C7D9BFFE8AD58579CF111E407E3 -:10E6F000E80AF6ED356EE7601CB0733798587C3346 -:10E70000563BD72F563BF73F4467D5CE2DEF27A179 -:10E71000FF122E87CCCE2DCF62766EF91E66E7965D -:10E7200067333BA7B56F7961F68DBD5F3D84BE8FC2 -:10E73000FBC7ACC7EF80FB84A58AD344FB173BD44F -:10E74000EF276AC684DABB1B4C32D239CCDE393FA4 -:10E75000C5EF607AB2777F057B978D766C10E89174 -:10E76000563EA60C8A17EEB3BDFDE5A9DFFE0EF4FA -:10E77000E5753DDE177A57C7F6477BBF3C350AF48F -:10E78000EE2113B3BF4B4C8C9FED5E1FDAD3494390 -:10E7900099BE57DDC3E857BD5B62F35DA9F73B60E7 -:10E7A0001DF8EA22EE9FE7EE61FBE759C6D69478A2 -:10E7B000B897F42F0A61DF7D90E2F921F2507AB127 -:10E7C00002E380CFC7D9B6C2FEB2542626F063E773 -:10E7D0001D9EF231F8AFF32ED6A1DF3B0F9EC33959 -:10E7E00009BF27A1DEA398D3BCEB953E24FC7EC4D1 -:10E7F0004423E3C3C415927F4B16DC4710DBE76963 -:10E80000FCFA757C9ED49F45BA90BFEA23C6EFD62A -:10E8100069E9E164F3AF5AA917E9512345A407E573 -:10E8200068F1FCD4E0FCE7BED0B6AE0FB42F957013 -:10E830003FA5D2433B4F953EEA7E651ED7114FCB95 -:10E840002E05F8A59DBF4ABFB079ABF4D4CCBF4E1E -:10E85000B51F579361A06FEFEADC0F8C01F9F83315 -:10E86000A503C5EBB6D9D969A1F6F8416E97A6BA4A -:10E870008FE7A73A806EECBBC439E5BB5E49A5F3D0 -:10E88000B9D9953512BE1FBEF52B831BE20B07CC01 -:10E890009D68DF54F9FA84CB7B80C379BBB73D1FF9 -:10E8A000D79166C98E7A13D0D82F7E7FCC730FD3C1 -:10E8B000AB03D23FD6F5198D7485658014AAEB1091 -:10E8C000F081FE776A0BE38307F840FF3B8D741EEF -:10E8D000023A57274BCE00F46FDE752FC8CDAB66DA -:10E8E000FA1CF4B75C72B2EFCB882523F5B2F2299B -:10E8F00047924F0C4EE404D7C579D02F29DCEF980E -:10E90000686C7D1BF09848F5610B09F74354BE0F06 -:10E91000A17F2E45BAF7D3831C7FCCE5F355A0B772 -:10E9200005E8DA69007FC61360EB87DAEE911DF91E -:10E93000481F95DECD747D18CDE8AD8B40CF9BD5BB -:10E940003AA7A7A74552E0FDC974FFDA4B82D3ADC1 -:10E950002F0FA9720CDFC369E901F1808C10BD078C -:10E96000FB147A3E59DD7C14E932652575AF42E827 -:10E970000E76EB72F489A617D5CD3F8C5E7CA2D1C2 -:10E980008BBDE6CEBF8C80F8D71E09ED0369491414 -:10E99000F6FBF166E6671C30BB517E3B5F53F0FE31 -:10E9A000B9D68E7CCDE51EF617A1DFFD4D8289809C -:10E9B0009DB39BC9472A1E03981C85DAEF57CD6E7D -:10E9C000E45734F8717C1D8EE63FA9F51B613CB815 -:10E9D0008FE810C70BF32F78FCA7A779A5F171BFBB -:10E9E000EBBCBACF3349AB81B0F8FF0A63C8B9D4E6 -:10E9F0006DFC5CA03B4E16EC67375DA61FC45F0242 -:10EA000074DEAFEE7C0AE3BFE79F393E0DE477D9B1 -:10EA10001FF5C444F9DCBED34A02ECDE8501D6D929 -:10EA20008ADDFA88E72884D4B2EF1C7F6745FB5261 -:10EA3000F1BCD15F4CDFAF78F1A3E110B76A5FC3DF -:10EA4000EC8CEF192E1FBEB6E170BE5E21B3736170 -:10EA50002DBCEBB8BC9C7B29BE14ECA4D4C8BE5F13 -:10EA6000AD689AA51843F6E923CD0A8E4BFBE1BDAC -:10EA700065DF0E09E3E5E1F8AD66F07630FB57D1CE -:10EA8000ACF8E13BD88AC62DB8BFF5347E6A00BF2A -:10EA90006ED2EF9E65DFD736EBC5F861A33E60C44A -:10EAA00038A7FEB87138D35B49884755A15E563701 -:10EAB000F13899267EB4EC777B5EF451D22CFBFDC5 -:10EAC0006F6C606FCEB66EB7617CAE91C5DF648B44 -:10EAD0001C393ED7535CAEE93E1E979B7A9A0C0FC9 -:10EAE0008FCB9D85FF503D9C6FE6FAAAC6351B7BF8 -:10EAF000C5747EBEECD90B4FC279D2B9E73F79120B -:10EB0000F0AFFCE6B327EF867389BD663BAC7F9E12 -:10EB100067DEC6F8BBFADEDD5CCEDB77FCE6E92714 -:10EB2000A81EB6BF67C47B5BED7B4E67C2F78CED5A -:10EB3000BBBE4C85F8E6CA3D05B89F59F9C2A4B4DE -:10EB4000CBDD3F01F9F4C7707EA2E5C781DD7A0213 -:10EB5000DF739E3F6644FFA33BCEDA54C5E2D70E77 -:10EB60001E5FDD19F9BC4A8D0756EFBEE5E6EB6185 -:10EB70001DDCAD381DF89CC7077B8AABBE45F93A52 -:10EB80002206FEEDE4F1F3A6A911E3AAE7E13F9422 -:10EB90004F9BCC625CF5C2EEC5FFF604B4EDEE15FA -:10EBA00035AE1A88816EEA795899D9B5CD0CFAF14B -:10EBB000FC6F318E0D7CA33E39697FF64226C4235B -:10EBC000CE289D77E23DE53D46BC6754B1E75DD474 -:10EBD00097F6178EE23913E1E751EDA4FB879D1BF1 -:10EBE000F0BD8E679B95C56339FD215EEBB0E17387 -:10EBF0001E976572ACC66BA3C569DF37B3FB50EADD -:10EC0000F95CD5B60F0C4413FF96C602BF8E0BE716 -:10EC10008AEABCB5F0EC40876B43CF1FA2C5C3B9ED -:10EC20005D0DE3173B7768DFC2CF23BACF1908E940 -:10EC30003B12CEC7D9B9B9C72FBD1B89BFEAF9C3EB -:10EC4000DB5AFDF4C776EED033DEDF8D2EAF9AD9D6 -:10EC5000FE56A5CFB9AF23DBE94EAEEF749DE93088 -:10EC6000E3B9315B67E6F175A69AD28D7DF7C6F000 -:10EC70003DC7F781E79ED1FB61BFBCAEE900DA5B1F -:10EC8000AD9E571316FFD28E27C531FFA0BA79DF8C -:10EC900070B047E7F6BF84F257BDF3B8C147E11C37 -:10ECA0006AFCBDA16D6850DEC18EFB43ECF8B9E78C -:10ECB000F60D67E72291F3B4D8387C4F8B08DFB3A9 -:10ECC000F35301FE325F93C16EE9799CB3B26B16C8 -:10ECD000CCF76CAB42E03EFBD9267D913FC2B89F9A -:10ECE000C13A362648A77556F61D9F3EC9807EE676 -:10ECF0004AEBD863F0FDF84AABC101FBEDDAD5EC85 -:10ED00005E65EDFF72A6035F6A136FC373A37A0D8E -:10ED10001DEDC9F65CD887DBF34B46835869ED419E -:10ED2000A24B27E0BDD25A94E6B0405E2FE6A71072 -:10ED3000D989DF19EA6D8545300FBD5D6737475CBE -:10ED40005F193CC5C2F2662876F1BBBFEF9007831E -:10ED5000403E8E6F9D07A3539307A3FCC6FFD7F2D7 -:10ED600060F8609C9F401E8C00C677D43C18C93F59 -:10ED7000721E0C882F8D0EC983D1A9C983C1F9F8E1 -:10ED8000CF3C18FFCC8301A59A07E39D0D65059044 -:10ED9000A742CD83716683A700F252A87930BEDA0C -:10EDA000B08AD5791E0CCBFDAB0B42F36064DEBF9D -:10EDB00001DBD53C18CEFB1F2908CD839177FFE6F8 -:10EDC00082D03C1833EFDF5E109A07A3ECFEE70A0F -:10EDD000843C186BFF500079305E8F77B7C6A5442E -:10EDE000CF83D11CE788290F0685F31EC2899207BD -:10EDF000430B275A1E0C0AE744DC98E87930C2F02E -:10EE000089920783C2F904E144C98311864F943C77 -:10EE10001814CEE738AF287930B470A2E5C1A070DD -:10EE2000FE0BE144C983A185132D0F068563884F2E -:10EE3000899E07230C9F287930289C048413250F72 -:10EE400046183E51F2605038E908274A1E0C2D9CA6 -:10EE5000687930289C2C8413250F86164EB43C18F4 -:10EE600014CE55F163A2E7C108C3274A1E0C0A67F6 -:10EE700014E213250F46183E51F260503813104E1D -:10EE8000943C185A38D1F26050380538AF287930A0 -:10EE9000B470A2E5C1A070A6213E51F26084E113D6 -:10EEA000250F0685330BF1899207230C9F287930B3 -:10EEB000281C37E213250F86164EB43C1814CE5288 -:10EEC0008413250F86164EB43C1814CE7284132575 -:10EED0000F46183E51F260503877239C287930C293 -:10EEE000F0F9AE7930CC8141D240CC8381F938BB86 -:10EEF000F360247FEB3C18BF027CFF9907E39F7906 -:10EF0000307E8C3C18B75ADD7F8FC77DE377CB838B -:10EF100071265E9337A2873C18B75A4BCE823C7F4E -:10EF2000DB3C1817E2BF5D1E0C3ACE3F2E374EB4C5 -:10EF30003C183ACBB7CB8341C7912D632E339F2822 -:10EF40007930122C62FE901F2B0FC6B1F8249C4F13 -:10EF5000B43C183FB97C13749B05FBB4E9288AE4E0 -:10EF600027937F62B485C70D7FA8FC1330E99C9F6F -:10EF700052FE09358F419302EBE1FB9CEFEF70B934 -:10EF8000F880E7A13816350F857F2AC677978A79EA -:10EF900028A6703ECE768BF23085B0739429F9594D -:10EFA000FE5AD8AF976BF2500C11CFE98BDD47F3C7 -:10EFB000293832D529CEE328978769A59F1E04F604 -:10EFC000DC3C36721E8A199C1FD3357499C2F936FF -:10EFD0009D97B7C3A739549E8BCB8FCA40D7698EF4 -:10EFE0003619E3F437A9FC7308FC9BC9E16AF19D6B -:10EFF000C1F9376332E39F16EFB7807F14EFB7CACA -:10F000004721FFB4786BF1D4F29F84F23B247F4810 -:10F010002E11F34F4C3289F9270AEC62FE891BD37B -:10F02000C5FC13931D62FE899B8688F927A63AC505 -:10F03000FC13378F15F34F4C77ADD6E4BFB84F9321 -:10F04000FFE2214DFE8B4D9AFC175B34F92F766859 -:10F05000F25FECD2E4BF784993FF629F505F58F7AC -:10F060009AD07F71FD51A1BEA4E13DA1FF52FF7175 -:10F07000A17D59E3C7427B55D3A742DDD3FCA5D080 -:10F08000BFA7FC036FF1EFA1DFE1DF431FE3DF4325 -:10F09000BFDF43FE8B772C4BD785E6BF78DFE25985 -:10F0A0000779098E5B1C3CAF40E4FC16DDED51F2A4 -:10F0B0005F04DFFFF6F92F52927FF87C043A2BFBB6 -:10F0C0001EB0B7254F674DF9EEF9086E2D11BFEB55 -:10F0D0009E552A7ED7ADB3B2EFB567BBC5EFBB6F08 -:10F0E0002F17BFEF1E11E796000F6DFE8BDE1697F0 -:10F0F000CE0AF692E72908C077BAD9106F2BC2F270 -:10F1000020E4BFC886785B29968721FF052DFF0C78 -:10F11000F92F687904F25FD0F20DC87F910DF933B1 -:10F120007C3C7F461DCF9F51CFF36734F0FC197EA6 -:10F130009E3FA391E7CF68E2F9339A79FE8C00C233 -:10F1400039E13D8CE5496F2B96A7BCC7B03CE36D18 -:10F15000C3F2ACF70C96E7BC9D58B67B2F62196BD7 -:10F16000FE0C552E3F04BFE10A189FC9B32AA757CA -:10F170003FF0C8BAD0FC19231ED884721A2D6F46EE -:10F180000E7CD397123D6F46777B94BC19C1F7A3D1 -:10F19000E7CD481BFDE3E5CD986BF961F266CCAD98 -:10F1A00011F33ACC5B75F9BC1923E24A6E41F9E3DD -:10F1B000F238D7125BDE0C9F55E2DFE553BA80DFF1 -:10F1C00045E982EB750F79070E5A9F1E02FB89AE47 -:10F1D00021575D36DF83562EA2D39BE57798F32324 -:10F1E000E7CBE889AE6AFFF72B581E87B9966F996F -:10F1F0002FA3877C0B07B3BF403B196BBE8C9ED6F9 -:10F20000879EE839E347CE97D1935DEDC99EBE391D -:10F2100085D1B9770F7456BF97AE34B51EC297ED3E -:10F220002E546D997F0F9F3BD38EF1998E9DFC5E7E -:10F230009C8B38ECA9EC7B7DF0373B9E4F184EF051 -:10F240003B7E3B7151FEC4F3E7D2CE7DFBE05EC056 -:10F250005A1B71252681B3471CFA81B00FBBC60427 -:10F26000F19AAADD9FBEF1470AD7DCA2C7FB721D47 -:10F27000148756F4FB5C89C0B778F24BDCA7C3193E -:10F28000DDA55EA1DF756B7E0F0774490D9E3F15EE -:10F29000E82DB86FEADACCEEB3EAC9D58F4F188DF6 -:10F2A000F7C689DF81FC433F7519C7B38B10670030 -:10F2B000FAEFB4E2FDD525AF2D34C0A070DE1A1AE6 -:10F2C00037E85524C6811ACCB6E1706F2F5DBDBFFB -:10F2D000E773B5821FBE88C34D2911E3449F2C28D4 -:10F2E0003A0CFEF3227719DEAB482B15E346847FF8 -:10F2F000470FDB32F03365C2EF75FAD97DCFB0EF3F -:10F30000EA9BB7209E4BFD9AFB4B8D625DA5DB39D6 -:10F310002BBF9762219698E8D676C5E31392BF3D3E -:10F32000DD8CE922DDCC0E916EF14344BA68E966CA -:10F33000758A74D1D22D61AC185F53E9A6DEA7FCA3 -:10F34000A1E89664E3F73C82F42A31A5A2C9473CC0 -:10F3500033E400CAB7561FFA5802F01B7E48BF6458 -:10F36000FF6A7CCB6995C16EA533D0445AC4DE8B4D -:10F37000077D80FCBDC489FAA0FE3E8A78F2219701 -:10F38000FB8FC8255AAE987EF0F802DABA19E46D00 -:10F3900004FB3D1A18AF4A22B89F5388D30EFBA82E -:10F3A00026AFC9B94881734DE25C940DE799762C7C -:10F3B0001FE4DF3B770C25B8EF6F0A7C9E0AF70647 -:10F3C0001E1CD9390DE20F9EC5A404D6AF59096C95 -:10F3D0007D5DC64B5B028BCF6C28D111D768F87D61 -:10F3E0004A7ABF44C76BB7BB5EBB01FCD116763F00 -:10F3F00080D83BDFB81DDB47E1F7E119BAFA6B00B3 -:10F400001FDA1FBF2BEE68F9C8B630C40EB7373FFE -:10F410007225DC6BDDA48BFC3D73818DFFFE1D7EB0 -:10F420003F654430DF42816D0CE6657870001DA7B2 -:10F430007A7A17F25195CBEB38FD0F964D41FC5E71 -:10F4400068911C10AF2BD4DF71D3308ADFB8B76559 -:10F450007EAF97DD5F1FCDFBD79AA9FEA2FDAAFF65 -:10F460001BFC9E95974ECA980F71744D19DE13FCC4 -:10F47000A3ADF030F02BC7D5340AE429BF2511CF56 -:10F48000713D1F12277E9AD52ADE07CCE1F7B673AD -:10F49000DA881F84E2DA6362FBB836B17E9D66FFCC -:10F4A00039DFC6F5D4465241EE367EAD9760FDE8B1 -:10F4B000E824CE3514DF8E45BD71FC8ECF09FA8964 -:10F4C0001D5FEB8B22DD8F596E63FCDB642068BF10 -:10F4D000379559F0DEF9FEB28AFEE05F7C7197BB8A -:10F4E0007FA43865889F96C0BEBB772590B12087E2 -:10F4F0006B2546EFFA8C9208EB962A77AA1CAAF2A3 -:10F50000975116E78E740FF5339B847296573644E5 -:10F510003280FCEC9530FCD5BE86E2759975DB47F0 -:10F52000D6F4017C3CCD9FE17D32538BE48A744F4D -:10F53000E7619B8DDD6F5CE35B0DF7467E419508CF -:10F54000EC5486A13E2B127C1FD9887EE95D3607DC -:10F550007BCFC4F320C9F519709FA2BD79D2E475A1 -:10F5600014CF27A83EC07AB5497122DEBE2A42F0E8 -:10F570009E2C8FD7F59D46B66C08F17F37DB721B4A -:10F580006D145EA38D7D6FD9CBED94006FE77FFD89 -:10F59000C306F03B2E1A917FBDB9BFA9BE7780D3B9 -:10F5A000675C826B2BBC4FE0979F51E3E374DB9C5D -:10F5B0008B46415C9ED23BC40E06F9E663F951DCF2 -:10F5C00004CF3F922C3A9443E27239ECC27D761F0D -:10F5D000EA8DAA07242011C853A0DA37A9450A5892 -:10F5E000A9DC8F365902708F2EA99CCE3B19F29A56 -:10F5F0009818BC56F99C18D7A2F29803CE3DC1AB1F -:10F60000F3104805F8AADD53EDE5DA44668FD63EDF -:10F6100024635ED4CD729B19E2A9592E471EA4889B -:10F620004C921D78AFA65F3971520C49FCC05F2720 -:10F6300076FB0154C9AFF9463F2FD2775B176DCCEB -:10F64000DF1E97E0FE33D06BF8E1CEFDE02E38CD23 -:10F65000A417BBFFC5ED04F76B0AF97A37EE3F74C8 -:10F66000EC7BD1C00D24F43B2AAD9DD86466EBFC45 -:10F67000B8EBD9BA37EEBC05D7BD6E3B515688EB17 -:10F68000D4C8965107E09EC5C80F997E126E1FEC34 -:10F69000F40FD029E7B04F0FF4F9B67641CB6F12D3 -:10F6A0003075D787EAE01C86EA5BC8FB673576646D -:10F6B000C5F441B5185EE672D4FF1EA7DE1D4247B1 -:10F6C000EDFBDD714AC9D4FDDC3110ECC8113DDC25 -:10F6D0000BE9C8A5F3A3F3DFC8F525F173FF649820 -:10F6E000D7C6961BCD20DF6B0379F662FA4EA2A92E -:10F6F000049997485C18CF19493D32C88F518B4205 -:10F7000041FD41A58424A4C03DB42221DE432C49FF -:10F710003CFF4B00F9D22DA7548E43EFE5AAF2A986 -:10F720009547557E6BE1A005CE0721624E4BBDD4B7 -:10F7300084878146B2D90EEBBBEA5FD6727FAED624 -:10F740009CE9C7EF977C19E81FADE4FE51ADA5D049 -:10F7500084E6605F32AEEB2B217E42E9B03285D980 -:10F7600079753E5AB9F45CD4137FC83EC12377E261 -:10F770007D44CF45033E5FA7B807C0FC55FA5CC384 -:10F78000E9A3A58794C0F79D9C2E3DE39B63877BEF -:10F79000C1892617598FF8E6E13DEEA6C04813ACA3 -:10F7A000BFF76AF08D01CF6B13C684E3295BA2E03B -:10F7B00099CCF0BC8EB8FFD846E53767455D6D3C07 -:10F7C000EA15792B3D275CAFB47AA4EA8D1AE7BD20 -:10F7D000B6B2FE005EBBED416F3CF18C2E4EA5042F -:10F7E000EF5739F7C4A31DD1EAD3E77CFE9E7846D4 -:10F7F000BF058A7B06CCCFA3EBCC043919EE20BD24 -:10F800008A2992C39BF5A8E7A435B67BF8AA7FA501 -:10F81000FA55DA7EAA5FA5DA63F51EFCDA04F77CF6 -:10F820009003A999CA2DC5A7D6CEF64B9B6DEE4580 -:10F8300080573CC53D0EF68D430259ECFB5F512FBE -:10F84000A2E941BC46CE9B0232AE0B3EBA2E644BBF -:10F85000E178A8E30F4A48647CA45A0EEB7DDF1CD4 -:10F86000C206AB269837A7EF70E28675ABEF4876F5 -:10F870009F714D02B3BFB5096CDD52CBCDB692BBC3 -:10F8800051BF65E2338EFCEE7803AA70DF7C6D8297 -:10F89000EB2EA087A9C885F3E863274EF04BFBC881 -:10F8A0004D127C379A54E990D83D7312FC7E8BC27E -:10F8B000EB53ECC8057DED03FB6BE8DF1239CFD8C5 -:10F8C000A309EAFD5EE67F3A49771EAF471398FF2A -:10F8D0007908529FF42A56F382A9E7394E09E8D4F1 -:10F8E0006EBD0D916EBF20313F3D91D14BBB4F009E -:10F8F000C287FEFEBD7B0D44362791E0EF59D599B6 -:10F90000D0BF8F27CE26B057BB1206F0734C671DB1 -:10F91000D47F25779A128706E55D95E30727CC709B -:10F92000422A52DBF55DC3614F45E57A27D0BF7DA2 -:10F9300042D760CC41493A3399FCB8F442BE209595 -:10F940000FCD8AC00733ECC343EDA4D53004FCD1FE -:10F950007629CE09F72CDA974A0C5FC9C4F329C976 -:10F96000C23CD3E3997FDDC1EDD53B09592827AAD5 -:10F970003DA6F3AB83523B0F8F11EF7490CE3DF158 -:10F98000FEAD706EA5C93FA9CD4F3969A105EF7FC6 -:10F990006CDC63C6FD6B57093BC7EF6A31A27D8EF5 -:10F9A000A6B7696DE688711CB5A4F47B0BE897A631 -:10F9B000D424823D4C9B7BD2067CD7D2A543F25DFA -:10F9C0007308F645AF2B11BFBB55CBF4F49B121750 -:10F9D000D1FEE91993B1549F3758E488F7CD4F739E -:10F9E000BD52E5F14A3A22DF0F9D06793CEF7EF3E6 -:10F9F0001D1709DEDF6F8863746C886374EC728F87 -:10FA00004F781AE4CD9781FAB0583D07E5FB7F3572 -:10FA1000CF943ADE46AF2951A62AD0B0608A19D6D3 -:10FA20008914E29A3C1B9475A342E03BA2C7BC3BFD -:10FA300012F3318E6D12EFF9DAD9BDE1CF3716E04E -:10FA400077DEA9648D7930A5475989CE09F183F312 -:10FA50000BDEB7E9A83C2DE8D39A03F2FBBAE22605 -:10FA6000F63118EAC2FDC99252833F40F996DC4054 -:10FA70000D05A5CB7F03D85B39A8008000000000EE -:10FA80001F8B080000000000000BB57D0B7854D5DB -:10FA9000B5F03E73CE3C92992433794E1EC009E1F5 -:10FAA0009D108724BC1F4E9E448830BC0485EA808C -:10FAB00028CF2488D6DFB6DECBC444F4A2B745E90C -:10FAC000AFF4D6DB7FB0A2A8200182069AA413402F -:10FAD000E4113408A8A8AD5129620BC908EAC5D6BB -:10FAE0007BFDD75A7B9FCCCC4922D8DE4E3EBFED62 -:10FAF0003E8FBDD75EEFB5F6DA872EC977134B641C -:10FB0000CCB7D8C0B64A8C7D87BF1B43ADD96E60D9 -:10FB10002C89B196383BB54EE70CC7D284F07E8570 -:10FB200063693E63D5D6D85C16876D7F3F8B85F1C0 -:10FB30008A58EAD202685BACAE5A95B12546AFDD71 -:10FB40000ECF774EBA3CA48EE12FD8DF3392B12E80 -:10FB5000236B94E2B01F606C0C4350F8CFED56ED70 -:10FB6000D097F0FFE1FD448B2D20C3B8CCA35CEC13 -:10FB7000B0F047BE1B281E4D66CC285E939ADEF877 -:10FB800046CA652C7672116370DFCA5C8FB22CB8DE -:10FB9000318CA99E18C6A2D833F6F3D98C19F07D02 -:10FBA000584757F3BBFD7C00C71FFEE54A0C83FB9B -:10FBB0001F29C118570E63171E3C15E3B6C1F50780 -:10FBC000E5723FF46F4740C687F0926F870BA31929 -:10FBD0007BC4EE1981EBBA63DD7F8FF1DA42F7D98E -:10FBE00003703195B1157E19E7E6F0C27FABB659C7 -:10FBF00019B384FA95F509117DC018E1B5D2CCD6B8 -:10FC0000D4DB7AD26305D203E65DB17D8B295DC575 -:10FC1000F9BD93ECD0BFA0C0AB80EF0B0D317E5F80 -:10FC200066089E25DB4799D2E1D6474D661680755A -:10FC300030A5DDC86C84B50A09F0E61578D3C37920 -:10FC4000B8C54AE3DDF57F65BF1996BA18E67A2094 -:10FC50001E9E6F5A51C1727BAEE3AE3FA86529402C -:10FC6000BCBBFE4D623E953FFF601E3CFFC0235F64 -:10FC700020DDF4EB5CEC337ED211B16E376300CF44 -:10FC80003241EF3B1F8DBCBFACE9311A6729F39AB3 -:10FC9000909E776DD4DFBFE933E4BB654C095D0707 -:10FCA0003C5C3E9265453CDC618F493C0F20038FF4 -:10FCB0008DFD0EDEDF7D64609C37A7277EB5F6E202 -:10FCC0003AE06F33637F5E67A1F6C23A46ED08BB48 -:10FCD0004AF459DD74F27EE4AFAAC65D261CA7C5BE -:10FCE000FFA78409F04861D3373232572173DF7B95 -:10FCF0000EF0F92326B3EF007FBB19E79FF546CF3F -:10FD00003D48AF1BAF96D37DFDFA1769FC7F249E5B -:10FD1000F86711AE3B17AF2B5FF6B6AE9FE2BA8025 -:10FD20009FD95858977CFDEBD2D6A3AD4FBB5F2926 -:10FD300003DFF5F2BEC6EF23843E58FADCACF5696A -:10FD4000808ADAE6CFFA77103FB1D328BF1A3F2D69 -:10FD50001374D2F38D46C76EFE68FA775A9F463FFA -:10FD6000E07FA7C1896DC06918D7934FF47CA1E7E4 -:10FD7000834E63477F945F3D1F744A6C416FEBFA7B -:10FD800037FB405AD752D55D6687FB7731CF7A3B38 -:10FD9000AD67235DBFA06C3CFC3394ABE7385F7765 -:10FDA000EB3933973776DCE847BDB936464D71D825 -:10FDB00004FD80CE9DBBCC3E7C4E9BE7FC3AB77BDE -:10FDC0009011F15E4EED9FD779DC830687EEDFFD63 -:10FDD000AB2BB12ABCDF358C95A3DC77C644C2BB04 -:10FDE000CF2E133CFB900EC87F4AFBFF7C803AE984 -:10FDF000B9F631A847CF7FFB5FB11E78BEEB5B73CE -:10FE0000796FEB3C2DE807EAE5B413F8EC7621674F -:10FE1000B73755125D963C33CB84FCCC1EE0F8B46A -:10FE2000C01FEAD7B6A8D867711D8B1B24D2237ACE -:10FE30007ADCE59AFA39EADB3BFD85F47E0FFAB00D -:10FE4000C789BE77213D8685E831D6A1727854F8FE -:10FE500003BEB943F0CD79658DC9007AE4FC3380E7 -:10FE60006F007995C2DCBDE9C1FE0ECE877DAD473E -:10FE7000BF8EBEE05FF65CCDFA3486EB1F654AEBC1 -:10FE800045EF68EBBF8BB96249EF88F5B28E1B492D -:10FE90005EAB2D7C5E6D9D2B9AEE9C817C51B519DD -:10FEA000E895D973DDA87717F7026F997CD168813F -:10FEB000F7BA1E905CA86FFBA283A627EE12F85A31 -:10FEC000B96DF10C349A8B613E3913F5D1176FC6B9 -:10FED00024A25C415FFA1E7A35C91F9B711D8CE319 -:10FEE0007B09E07B8374FDF45BB6B9D03D28ECB9A7 -:10FEF00015FE9BDC83C2F5998EAE6CDBACD0F3644F -:10FF0000B7DD26B4C7F10EA1BF845EEE5BBE60E133 -:10FF100000E7DA1D0EB26F6C8D83F46375D3165350 -:10FF2000B8DDD5E44B93B7B10E3BF15955E313F46B -:10FF30001CE85FD501FD4A4BC7CF6F55C3F0394E62 -:10FF4000D051AE30A1FEEE4B7F82BEF9B2236C9D44 -:10FF5000231CC2AE08FD7B2DFDA0C1AD1F57D307EA -:10FF60001ADC1ADF6BEBD1F37D5FF0E9E9C2989FF1 -:10FF7000FB0B3AFAAC427A84F5115E05F0DBD66CE5 -:10FF8000F53F04F0B6491C7E5F7314C1DFE92C769F -:10FF90009F033FAF2A7521B527F0C554F4EB3CD33E -:10FFA000109F9A3FC70A1222FC247DABF93779C211 -:10FFB0009FDA1BE5CE0713093F4F02F2C3949A8ED6 -:10FFC000391620D9AD8EEDE50A8C3FE5898E395181 -:10FFD000D05FE8D8C1FB5B3B4E595C8CD5B057CAAB -:10FFE0004BA07F3BA013C7BB565B60F62C44F95D6A -:10FFF0000D7E9205ECD1EAD3430EA1DCAD6EAF28A5 -:020000022000DC -:1000000097C0EEAC068323813DAA74C706ACB9D471 -:100010006713E0B9E7EDDE65C42F57EBC86EAD3E60 -:10002000AD70B9399248EB5700F62878AF2E1AFC1C -:1000300055C0575DBCC5559B49D77D51F1D877ABAD -:100040006AD8758D1EF81EC25167606E07B4AD4741 -:1000500087C4757C8FDD6E5DC72A14E08383EB2C2B -:10006000D4EAEF179AEC83D0EE151A98B7377DF9DA -:10007000A483FB8DC0E4E948E7AA23269277FCA17C -:100080001F5829F4511510280EE0A93CCD02D1B11A -:10009000F85CD9E70AB60D12FB24C25F61A1BEDC91 -:1000A00037DCD7DB56E17883C3F984E3A948912A8A -:1000B00094B0794B6C51117D39C5300CD7C3E468CD -:1000C000D756C0AF9C6E58B31BD62F0F8016F0A129 -:1000D000D85DF2626837164F9197405B6BE476B556 -:1000E000D6C09687E3E905811FADFDC0E1D98A74CA -:1000F000BFF456FB182BE9AB0C3BC9B9586FADE404 -:100100000A50DCD4CA5C5BE15A9DEC619C8FEB1910 -:10011000F2F11B621C97D9B047057E6D747C40FCE0 -:10012000EB8A33DC9B09FDC0131FF17EBAE14A263E -:10013000F0F781273ACA15900757B6E1CA40E81F81 -:100140007AE2637E7F220C0906EAF0139F94FB6C2F -:10015000382ED7676CBB3B1BE7510C12C9A972C084 -:10016000E4AF85FFAD8BE5FC54073C82FCF786B01D -:10017000B3EB6B8A5EB602FF2B456E750D8CE3C741 -:100180008069F4DFDF6A7894AD068A53B0457CBF9E -:1001900029D6ADD18135B8B367A15EA87767CF8E78 -:1001A00041BC7A4F225EF3DBDAA7A03E6E78FBFDFE -:1001B00031E8AF22BD709CFC3688DD603D975EEB78 -:1001C000B7450E8B473F7014BEE3003996DCDC9FC9 -:1001D00094543B5B047257EB66AA09D695A28BEB4D -:1001E0001A18D72FCFDB3D7FC4F7584680EC4DA1BE -:1001F000C3FB31CEAF8F57597B7CAF7A59AFB74C29 -:10020000B90FC8E8E7C4A737BEB704F5FBEFCDAE1A -:10021000C12AC2E5660F003C3B0D4C61F1C426C308 -:1002200094028C3FA35D1B50EE5DCCE90339C330D3 -:100230008D80845FE298B0B855AC07DE2F61D08E18 -:1002400045F86EA0F5C9C857A3984746FD3586F90D -:10025000ADD87635BFE644BC3D19C5EE40BFCFB240 -:100260008DB9FD61FA63403CF7F726251809EE6861 -:1002700063FD6CE4D7E82F981DFDAAAEFF34293842 -:100280003E08C874BCEE3A6C6008E70B46BF3D0EF2 -:10029000FAC1E18AFA2C0B8DD725E8AD8DFBA44974 -:1002A0001DEE407D93C0FB2F1472FB1CFCDCE47F31 -:1002B0003613F16359E30F932F673CF75BBD494554 -:1002C000F1F1D0D63747339C7F6C4BB401E9F0F2A3 -:1002D000F6BC28E4879D881B587FBCD97E0F8E17FB -:1002E0007F05E0CDA4EB6EC2ABA28E8A03BC4E9814 -:1002F00066533700DE5F88AA9F86FC1FDC6160CFF3 -:10030000C2143B4DAE59D8DF7959B5A3BE7D21B398 -:100310003E9AD6B3C340EBD9191D1CB116E0DE30AE -:100320004C2947F8142B53500F2B8622F51EB83E4C -:10033000349EDB574D2F2F88E7F2F3A404F3E7E157 -:100340007385243FA5B28DE4AE2BC8FC669827695F -:100350006EBB8CF4889E05AC847CAF046406FD49BA -:100360001E46498D4936A35F257DEBB62D06BA4F53 -:1003700011FA76CA87AB2B78DCE33A3D11C63B68AD -:1003800033325CD764D621A33F38F92A7305907FB6 -:10039000AEF278C60E7FE83F3DAFF3074BC578EE6F -:1003A000A0BD042F17B2483FAE7473D9E712CDA396 -:1003B0002A68A78B2DBAFBE8E7C5621B193795C5DC -:1003C0000BFFA63FEBFF1DE937E05E98EF3E3B9F3A -:1003D000AF54CEF915AEAFABDCE4423CECB2B9DFC2 -:1003E0009D887AB1DDC8B6B2BEE5E979883FFDE007 -:1003F000730CBB6A65FE7CE2471BAE67C4E68DBE2C -:100400002858F788417C7CE43BD42343FF333101F7 -:10041000F5F855A15FB456E333E4277B1CE727FBCF -:100420000D2139BC333E939ED3E40AF90CC7D96F32 -:10043000F42FF4F46227813FEF44FEDC6563144738 -:100440003D966A598072A5CDF3BCE0637DBBBE6664 -:100450006DAB11D7FD15D80380BB24EDAA29DC9E16 -:10046000EF49E27C552A7F4BFE766793C4D0CF4F8D -:100470006EE2FA3B9C3F527BE78F5F225EAFC51F67 -:100480005ABCB0FB87F2C791BF8F3F365C933FBE2B -:100490008D453CDCD75C9CC2BEC7BF6914FCD0D77D -:1004A000FDF156AEE7F4D75F1178DD67DA383D1716 -:1004B000F5C0CD0617CA39503F7D36AC635F347F37 -:1004C0008F296BB2B0BF4BE17A65579399F4CA2E6E -:1004D0009BD74B76DC6961E83F30C5DBF133D487CD -:1004E0006916754318FF2E8DE7FC566F0C8CFF0CB8 -:1004F000FDE2A39CCEE36ECE934DF05CEA522EE774 -:1005000005174C5B300E2B4D28DC817C7402751670 -:10051000B4D5E7E029407CD53913E9BBD75A4E96CC -:10052000617E11FC1E37F2D9D8FD27CB8A72F07993 -:10053000AE4FF78A56EB8FC735C5B3EE78D723ECAD -:10054000C678C6F59207F92437D4676E23C56B1AAF -:100550003FD447033F805CCC67AA3116869C73CE9C -:10056000F330984336A73C92CEF303D3283E9C7BCE -:10057000BAFD55D0CC6C9E47775FF0C17C1D1F80C3 -:100580009D3D1E8FFED2F180C980F399D664737FA2 -:10059000684D16F293264FF4033CD5FF61D8B31B88 -:1005A000C2EC7B6C0297A3C75D0ADDF77598FC83EC -:1005B000E1D2BF33FE5EBDB03F9FA33C63FC70DF62 -:1005C0002B0BD18EE62F771F44FC4F4F92E9FA2F69 -:1005D00058C09285F47129E497D51BD5E2CFA4D0F9 -:1005E000734CF10CB3C1FDFD49D1F9387F6982F735 -:1005F00022D28929C123F8DED80979F9285FB651BA -:100600007509688F34B801AEF2ADB6101C1A5C677C -:10061000055F94262CBE88EBC7F750BF347E7CDE86 -:1006200082EF6B74AF6FFE82D33B8CFE48EF10FD00 -:10063000A53BB0AFE1E12BA157B4FE3F4A7F2D7F30 -:10064000704DFA637E20F6EFA2BF352129447FF07A -:10065000B3E2B1AFF7B3EA4DE077E7F4BC5EE82868 -:10066000A4E75D265821FA552D1077A23C7A1DB4D7 -:100670002FB0C7CEE7EAFAC3F9FEE022B2C109F112 -:1006800084F76A537008FA21A30212F985A340F097 -:100690001791FF95417ACF25F0C4CE4BD2F961DC9A -:1006A00045FF2E1DFDC34002FA51A3CC1501E4F70E -:1006B000DDD629E9E8D7E5592765215FBD3AECBECB -:1006C000E368825E4D5BBEE73935E4FF68FAEDA072 -:1006D00018569BBF2081EBA11B41DDA21F882E6312 -:1006E000381C9A3E47F2201C5260BEE13B2BE9E5E4 -:1006F000A60EA0C78D0807E0A155620DA8CF0B0D6F -:10070000EEC462F4D392020AF7F7BEE98FF9C18A08 -:10071000A637DE43782B703F04E35097F162773EB3 -:1007200062604F3F58F357B4B840F367B4F813FD15 -:100730001EBC3F405CB79B0140B447018BBF06E63F -:100740007FF2B23ADC2DE4568175548875CC64EDA5 -:100750000417FBF6BBEF26017D66087C541C81B8AC -:100760003117EF337633E0E16685C79337BB207EE0 -:100770000CE3A399E322FBF89B921C1AE75ACFEBF8 -:10078000EDC044DDFECC3FDA1E017BF409B8CEC7D4 -:10079000D6F1B874C240D9A7A0E11C9769407EACDD -:1007A00016F60DC2E85EEDD24BC22F9E60E8C8750A -:1007B000017E5BF7FF8DECE081FD7F7B07FDBCF1E7 -:1007C0009F2BCC0CEF4FF8BC200EF5041BA7125F3B -:1007D00069E356FFA9C1CAF875E2FF2AB1F6C30062 -:1007E0008F7B28C267A1F677179FDC84E37D794E63 -:1007F000E1BC2DE62F337907611EBBCCC4F3018722 -:1008000025EEFF68F70F1B016EB8BE2941CB0BB474 -:1008100093DDC79F398CCE37633E202F44D79B2F63 -:10082000947FAEE4F6A40FFEFE37F2015A1E60ABD1 -:10083000C01F3B78D6A4025C531BEE51D0BF9EEA8A -:1008400094993B6CDE9B542B7387E5039E49D0F94A -:1008500023075FDC3403EC49759BEC8A42796DDA3F -:10086000753C17FBEDB2CBDA0B1FE9F13BB5E91E86 -:1008700005F9DF98A8927C5F6BFE0923804F6E40DC -:10088000BA33F2EB3AC74824477AFA1ED8FFEB8412 -:100890008E9CBEF1DD17FDF574F8DDC522DAEFB9E7 -:1008A000163DF47CDB02EBF4C1FA02B04E1FF85D9A -:1008B00007D6D9A97F689D93FA1ABF5637FF36012C -:1008C000FD368D4F4B1338DF8CDFB72981D942F4C9 -:1008D000D2F0F5A1B0577BA3347FC3356F065C3AE5 -:1008E00005768718D4C7DA9D6342F66BFEE932F2CB -:1008F0003734FB355F5E544A6A53D82F4C23A35ECE -:10090000D3DBA9B9EA6223EBCD3E2D88EC97B76D16 -:100910005462A867203A4992C087F0B33538CE3088 -:100920000FC1A9A7A706971E1E6D7D9A7F3D5FD0B8 -:100930006FCEA04C23C2DFC3AE8A75E2409887B861 -:100940005EBBFAB58E9FAF5C28792BB717BEED8BD7 -:100950007FF5F7357D508613E451EB43BFC298987D -:100960004C742BBB6A626EB01B2C238A7D1A6657AF -:1009700058C550E29F7B851DEE8B7FAAAECACC9BEB -:100980001FE22363E31356E4A37DCA462BE6272721 -:10099000DB66D5C6019E4AFE543417FDBCEA0E0341 -:1009A000C3145669D3170731AEAF7E8FB9502F16D7 -:1009B00035B51623DF1D52DA658AB3BF64EC893082 -:1009C0007FB1B1A9D68AFE5463A24C71FC6107E7DE -:1009D0004BEDFE9644AE3F1ACF5D9EE1EEE5FE196B -:1009E00071BFE4E33CE2A3B24741AE310E4D8AA1B0 -:1009F000BC4489649F53817EC84D46F2F3218EF931 -:100A000023EE035E6A34EFC2D47E69E323F7D88114 -:100A100010F5FFFD698D19F30BB324D7B3F05C9982 -:100A20001A6CC57ED9DC4CAA7B18FB3F32F9B3C1E6 -:100A30005B25CA8B9401BB60BF6C51A61FF313FBEF -:100A400025DEF735F37D0266F725CC8079DEAE48EA -:100A500018B581784AEB0FCEDBC0042387C557F762 -:100A6000ED9549CFDC572AF971BFA9D49ECE7C61A0 -:100A70007C55F6A889D635BB29A508F9784EB9CC9E -:100A8000FC61FC1D107EE13C0FC4E161EF1D8EE2B4 -:100A900070051703DC52486EA7093E9FC5B89F3802 -:100AA0007F4142C47BF0C62D688F6E6D8238157A07 -:100AB000D344FC7AAB373D625E0FE37ECD09162C42 -:100AC0008983F1FB250D24FE9B11B48F0EA8A87716 -:100AD000CE24A25E63C3B89C6872572AAFAE237E51 -:100AE00070F27DB2791248938CFA2F529E668E8BEB -:100AF000ECCF72F7A83788907FBD5ED7E47E5EB3F7 -:100B00004CFB72F30A2517EB453FE8FDECB1D17DB4 -:100B1000E8856FD587E37AD30B1F96FF5D7AE135C1 -:100B2000082BC681FCFE3451E8877EAC1FEA875251 -:100B300079FB26E4972EB077E65EF845B3175A3C6A -:100B40005E06F24AF27E91EF67945E4D65BEFC5000 -:100B50003CDEAD2FC09F70F5E2E73C9D984572D416 -:100B6000AD5F34FD11E64F18C7FCE3FE4429F89150 -:100B7000A63C842F83E02B633C1F588685439897BF -:100B8000737E41F9966A88F329DE67BF25B850CF96 -:100B900049F12139D0FB195A5ED72AF2087ABEE80A -:100BA000CEF3CD35521D8CC61765762E1F65736545 -:100BB000CABBEBF9449B4FCF1F015D5EE69AFC2157 -:100BC000E4EC87F24773A2D8571DC4065D0F5F6837 -:100BD000FCA0F187DE8E1CD3E567FAB2236FA21D5D -:100BE00019DDB71D797D9891F4B5DE7E68F6E27760 -:100BF000495C2F6724F27D8E69C3E7D9D0EFB02618 -:100C0000F13A0DCD0E75E79736737E78BD63892274 -:100C1000A13D41BD9019867F916FD5F8AFEA51890A -:100C2000F28D15422F7536F3FC5B7589ECB7C0FF6A -:100C300016373DB189F78D949F2B545A150B8C3B79 -:100C4000D325B930AFE316F9BA196E89E7EB5C9199 -:100C5000FBF42D3AFACE117C349305EBD01FD7EB81 -:100C6000A53957B95FA0D74F73C4BEFB1CDDBEFBCF -:100C7000554DDE07B001FF4C7FC09CF4FDFE80F6B1 -:100C8000BE46478D7E2AEEC5A11C1DFCC6A4C670BB -:100C9000FF19E937F5AA42E3D893045F0A7FE6CB50 -:100CA0008B79BFA0984F3C5FDDF485C93BB26FF8EC -:100CB000AFE5B7C6A29F3E3AE4B76BF34E53184B6D -:100CC00047C74C674F6689EB3FD47E0CD7AD43A333 -:100CD00083A6477BE059E8D9BEE8742D3DABE9B364 -:100CE0007FB69ED5C6D7EC8036AF5EFFF615B769E6 -:100CF000FA74FD1603E54B268BF878B2C8C3CE4FC5 -:100D0000E2F1C1AD493CEEECFACA62407BB9B38571 -:100D1000FB272EB3FD38FA05A17C1FA7E7C331CC12 -:100D200087FBEC4C69B7D0BE67119012F73DD3F842 -:100D3000BEE77625E0213DED52580DC8C9397C0F3C -:100D4000E679F8806F21EAE9873F1962A0FD7725EF -:100D5000D08EFEC9D83C85F68F1C6695F2C19DCD1C -:100D6000663BBED7B5EFFFB41A719CAF980B43B882 -:100D700043CDE6EEFD1BD407A5729B8CF9FBAE209C -:100D8000C8083C3F6941A018E3A0C9ACBD16E57B8B -:100D900002D2B117FAFD2A498BB37BCFEF17377315 -:100DA0003FAE3846263F6E8AAFBD18F7ADA62892F3 -:100DB000AB169FD5E5F75FD1C51FA1FCBEAAF0FA1F -:100DC000435DFEBE91EB99EBCDEB4F40DD067CBC65 -:100DD0005EE373A16F581FF9FD9D26BEEF133C69BA -:100DE00064E807B30B89BDE663AE95E7DFD712ED84 -:100DF0005663719F8EFBEBFB5AD2DC6A6EDFCFE746 -:100E000076048BD03CEEDC3E5BA1FA35911FEDB150 -:100E10007FD2C7FE88BBD17E08D5695FFB21C55F45 -:100E2000AA94F6B95EBC69750B4CD43FDDC8B49F7B -:100E30009BE474E7F96837F2F9CEF3696E84EB79D5 -:100E4000C1A71ADFEF3B77399AF6414D6E15F78F40 -:100E5000830E8BEB59E25BCEEFF5A943FCB84FFB59 -:100E60001B21173BA383C7B213C3F73DF83E47CB03 -:100E7000BA47679F33D27EB984F9486D7FD907722C -:100E800043753DF18CE20F23AB67386FAD9BFD1AC4 -:100E9000DB2993D438C4FBE5446D1F538DA33CC4B8 -:100EA000B757A8CE508FFFDDEB9807EB511AD659F4 -:100EB0003C0AC8FFABEBECD46F5CE7A476FF3A9535 -:100EC000DA878EC73E8076BFDA6DF22861FAE39D3D -:100ED00064EE77E5657F524CC5DF7F6354873EE55E -:100EE000C10E19F5C58D57611D117527CA65C43727 -:100EF000E537B342FD4C69710CF66FBC0AFDB0E7F3 -:100F0000AF2439B83DAA53EA462793B4105FFC2DAD -:100F1000C9DD9104D7EF71783EC176B734FFE02583 -:100F200046FD73BC7FAB7C099ECB0F14525E391F0C -:100F3000F3CA7934EC42C4DFE85613ED976BF9DD60 -:100F40003C4DFEBE8ECC33E78BBCEEABAC83F2CD1A -:100F5000051608B40C0817A79F5B9AE794301F98F2 -:100F6000647261BDC3E82C4F3EE6635B9318C547CE -:100F7000ADADC9196A0E720FCFFBBAB5BC2FFBFE1F -:100F8000BCEF918F627DA4B7AE9A687FFAC8A9586A -:100F90005780F60B2DE4FF69F5C82DD1BCCE8065D6 -:100FA0002CA03CD38DA29ED162F69A93495F050E88 -:100FB0009E80F77E7F99F17DC7F60F695FBBD830C1 -:100FC0003C05EB7E0F4A43E3B07DEAA3D81C6A4F91 -:100FD000C55E44FCB418AC2ACE7B669D5A82756D02 -:100FE00027D6B112AC637B6B9D85DA93EBECD49E74 -:100FF0005AE7A4F675B88EFC731C9E477E71BF65D8 -:10100000A37D92296FD9146CF316C650BBFBB6189A -:1010100013C2DB12CBB66BF360BD5A203AD080C945 -:10102000FED6A7BC8F59FA81DD337B474AA3186BE4 -:101030007BCA3B5D990CE34EEDFF93AFE0FE9BC98D -:10104000CB1EB3005C734FD91ADAA0FF76F2F2C759 -:101050006CA86F8F4783D2C3F5AE38EE1E0474437D -:10106000A590C605978D837E82D65F31BD641263DD -:10107000B71477643360ADECE495D32D80C75BACD7 -:10108000DE1F63DFE44B9A5ED20FFBCC87F5604135 -:10109000C948713FCB9012B1FE65A6C3FB4672589A -:1010A000FD9E5BFA13ED338D714BCC41871F8CB4E1 -:1010B000EFC5EC1F2784CBDB4C47E91B488F89C960 -:1010C000BC0E78F424C91D5E5FA17F6EF439B504AF -:1010D000E934E642591DB633CB1DD4F72C185B8793 -:1010E000F25C62EBEBFD627ABF3C99D78D1429521A -:1010F000445D89FEB97C6026F48F8347A3294F3075 -:10110000FAB4B716EB4F4B9D9979B2A6FAA8EFD86F -:1011100082FB6DA32BCE9424A0FCD824179A89318E -:10112000ACA32E01EE17DAB1A00AD7F54431D6FFF1 -:101130008C562517A2ADD0DDDA80EF17BA625C8538 -:10114000E88F9F564BD0F49C52469D2880E7A60E10 -:10115000925D1618E854E0A68997A05F382C8EF2AD -:10116000BC85CA9A2B27A81FE3AA51711D5B7E5D1F -:1011700045E398C9AEEF9E51FC2FC83F459E38CA43 -:1011800009023E4AC2EBCA60DD0477A15DF6474919 -:10119000C8DFFF5A6287FEEEFE1296CBC37CC3FF08 -:1011A00042F78F44AB5100E86E93BD04C7DB6D92EC -:1011B000EC0F51DF538CCFFB861855CC1F9525467D -:1011C000458C3FB5441A7F0EE1CF891B85D7CA33C2 -:1011D0001C11F7DB6EB3929DA8782B87FCA2B6DBBF -:1011E000D2C95E54BC35A908DB3603F7D32BDEAA7F -:1011F00028A7FB061E07572CFC915BF429EEAD587F -:101200005849FD5629E52738DF959CB83CCCAF4DB1 -:101210001B945AA244F8810349FEF3447EAFD030B8 -:101220007CD32480FFDEA37C9FA2222733E2F9191E -:1012300005524978FDA8675254447F7689A324BC9F -:101240000E756E456A44FF96B99911FD92A3056427 -:10125000BF410F5494801E380AED5260C1025107FD -:10126000A5E59F0A054B15B68BBCACC2E3EB61F05C -:10127000877AB0C41669A77747733B5FCED6D0068E -:1012800049F911BEBF5D9668FC24DC4E94CB15363F -:101290005E97158987BCA346B2977931921FE3FA0E -:1012A00092A34BEBD0F4966744BEAFF961E5023EE2 -:1012B0006D5EE673B7A33FA2C1ADCDAFC15F2E2F68 -:1012C0002AA17CF735D6A18797C17A503FE8E1681B -:1012D0004A16FE1AF81FE4AF897324F04BECCD7E5A -:1012E0006BFE7A05E82B47B8BEB2498958B7D79745 -:1012F000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9F2D -:101300009E9A2087F5333F4E880FEFBFF8E9A688F5 -:10131000FB491FCF7184F7B77E3A07EF4F51D45A7C -:101320001BF0E53126B97CC8076DAA1203F4283EEC -:10133000EDAEC3B6F4432F96ABB2A9E77C75D84E99 -:10134000BCE86F33C3BA6E1A26AB18BF6B7E881E1B -:10135000DEBF26F3BCC3B1ABAA15F75977FB542BFC -:10136000FAF3BB1F54ADE887EC76F37319EE2C0348 -:101370009D8F7167F37AC5BF24F3BA834EF1BED651 -:10138000FA8DDE4E841BEBCCD137A8FA264875E5E2 -:10139000C7D0BFCAE9E95F1D53FC369CEFD8837EF6 -:1013A0005BF87EE2F5FA577F041E43380A99E40998 -:1013B000D723C596284FB8DC96DA1D11FD93C20FCE -:1013C00099EA4C8D78EF263533E239F01B87A15F1F -:1013D000526B62546FEB33F07A5B3D1E57A4F0F80A -:1013E000CE65B3A33B83FB66726FE7915CC5865EF7 -:1013F000CFB7A5A4707FF03F5218C1352B85C3A786 -:10140000AFAFD5F76BF17C0FE293B99CC8E72EAB79 -:10141000E10AB8BCACE0E927A6535D6DBEE1DE2C65 -:10142000E8573CBD753AAFAB35ECC13ADB194F3FDD -:10143000CFEFDF60C837823FB0CDF7C274AC2BAFBF -:101440008AE2F5095551A23EB46E7444DCA3183EFD -:101450007E6A21C69FFB8D0CF3FC8F99C00EE6853A -:10146000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A837 -:101470003F3E8BF2E6A5509EB148453C5EB45BA86A -:101480003EF4BE7DA529C807B35278DE2B7BCF443E -:10149000279D2FFBE7C151FC7D7060FD308E73717D -:1014A0007736F9E5D903189D27D1E801E1335D8F3F -:1014B00082F081CE6330B713F36FB50E138D332BEB -:1014C00085F3E3F5B63DEA89E30C6B7641BB2085F5 -:1014D000C7CDB7E2BC046FB0FF2CDCD0B307FBCFA5 -:1014E0001EC9FB486F59CE0BA27F1BFC510CEDC3EC -:1014F000BC1FCDF1C63282B46FF3EEA26CD706BA30 -:10150000CEF1B8C03FB0B643C5FA0F7F3FACB718B5 -:10151000E8F42E457CDC66F60F26BEB2AD89C179B3 -:10152000AEB7DEB8EFF921E0047B327F3CA79736F7 -:101530003FE0D882747C579C3BD1E001387E8C70B0 -:10154000687075C3A3AB3FEF147E7B278E971BCAD1 -:101550005357FFC940798A6A09F424F4F77CC85CC0 -:101560003E95E8437950DCD2C2F9C69F58526C834D -:10157000B6A071158F8FDB9588BC9866CF268AE759 -:10158000C7BEA744D8A38922FE1DAFCB4F4E6C9C8B -:101590004EE7F826EAE2E25FA488BC651A4B0BCF5F -:1015A00023AC15F1C6E5B68171E89F2A10E7CA8021 -:1015B0006F932AB371F121BDD0B08E459C53D4F8FE -:1015C00070E469FB9D38DFC8D3EC0EF207B471BB41 -:1015D000F3131C2F97DFE37819D531ECE949D037A5 -:1015E0001E3132BF1A5AE7040E2A833087E2A4CB99 -:1015F000176C645FC61C9D43F5DE66A781A961EB8D -:101600008F52A3991AA62FADC3E223FAB2A04F5D61 -:1016100054A41F902FE68971A5458CB73FBEEC08F6 -:10162000FA05F9B6E5E417C48D1B18311E6B532279 -:10163000FC833CE67163DCE802FAE27ED998D34A87 -:10164000841F302EB091CEA18EFB30F2FA847391BC -:10165000FD037DD1A52FFCB1DCA7D12FFCA1F87330 -:10166000B823F197501E89BF244F24FE521644E23E -:1016700027D51B898FF4E52322EEF75B9317D11F43 -:10168000F0C08488E733C18085F7B31E9D16F1FC56 -:10169000E08DB323FA4337DF16F1FC70FF9288FB2D -:1016A000D9DB56FE207A8FAC5F1BF1BC9EDE37344F -:1016B000FE34627C8DDE3EF8FBDFA437730AFF50F8 -:1016C000D03B51D859879BD7AD75196D8FE2797C86 -:1016D0003C3682FACE81E7E963D1FEAB5497E79BB3 -:1016E000C6685FFB97B24742BD940EA8356451BDF2 -:1016F0003CD5F5FDDC6088D867B73BB93F647772AD -:101700003DFE6B133F2F950EFE26D929030BC5D93D -:1017100016AC77648299AC8F639C5DE7E818A63AB3 -:10172000306F07FDC921BDAAE9D1DBCC6A6D07E89E -:10173000975132D793A03FFB39619EF7A5078DDC07 -:10174000FFF019D1FF48B7305F6C1ED919CA433B6F -:1017500058A284E700E2427A5CFD0E887570653617 -:101760009DC37A134140BF5975D17ED3AD9A9E5A1D -:101770003E9CF4D4655BA4FF767969165D3F7BBB24 -:1017800099EA07CE8A3A470D0FFAF3D6DA396CEDAB -:10179000FEF22D9B62D0EF3C2BCEFF6AD7270BFCCD -:1017A0004D76CAC2FE59D6603E6C1118F138C07B26 -:1017B000E5918ED8DB18F99B9370DD555BAEDCFEAE -:1017C0002AF4AB0DC1646E377CF4DEFC77F9B9EE18 -:1017D000F97F8BFCAE408593C7F91562FC5BA0B125 -:1017E000039E6E013A38B07D635219F2275CA7F36D -:1017F00071338F3023CAF32C6F26D54D9C62AE33E4 -:101800007B01C4F94E95E09CCB3C46CC5BBD737B21 -:10181000650C3ED73D9E360E300CFA25EF3A7CC65D -:1018200064CC1B4CE67513309F05AF7B16A53F8C2F -:1018300076499BEF1DE6BD7406E83B9BB9685C6D7D -:101840007C86E9F9303DB57BF9AA8F1260BEB547B9 -:101850000D948F58DB6CA678AD6BE57FED780AEEC2 -:10186000DF91DED10FEDF6FB2BFF3604F9E1D6CD8B -:10187000325381DEAADD7BA7336C5FE5ECD22B31DE -:10188000781FECEED6A7D058BE6CA63AE2F757BE4A -:101890003C24DC8FAD74162EC7F7D8B8EB3BEF585D -:1018A000FCD2F014AAF712FCB442F0D3DA178792F4 -:1018B000BFB536A69B9F787F2BAF1BD1D67146F064 -:1018C000E3CA97BE89F8CEC46EE023D5CCF7C5D461 -:1018D000A160EFDB2EE7D2771F8CDE7F75C2BC2DB7 -:1018E000573F89C5FE9E37FF4AF0B3B9D7072FCAC5 -:1018F000A26F4C687F5A3BEFB9A029211FE90E72F5 -:10190000B601C7BFED772F5EFA00F1D3FCF2D69F88 -:10191000E133D779FE7397967714F6C625F001F672 -:1019200086E28B2E16CDCF9308FF46C11DF92CFA07 -:101930009E874A7CED66C7711FA7B6D5407526B154 -:10194000B8091496AF8B950D9A51725B9CA0AF8528 -:101950009EF97FCEDB2AEAA83E20D21F2A38B43275 -:10196000C20FF2C05FAF7ED033DE5ACC2FE9FDA1AB -:10197000F101C36253DCF7F84587A6F5EA17414049 -:10198000ED96C688AD21F835E8F4F37E2157F53899 -:1019900016E6FF03D1FCFC33980EF47B7F9ACAF560 -:1019A000B72D83F1F36952E7300BE8CB16E7A2C7F6 -:1019B0001F856B96417CDDD8AFA53335F9C47FDD3B -:1019C0007ED7A111A4B7D8B7301BE243E43DF4742D -:1019D0002BC0F3ECF9617227DE0F1CFE6B2CE67D49 -:1019E00077C4AB6F213D824765DAFF89523A4C8E4E -:1019F0005EE2BB57510F029FCAA9DC1E581A797EBE -:101A0000D1A2BA19C60F5176FBA8F0737F8D4E1E76 -:101A10004F561E7EBFBF09E871C9D0169B03E3AFC6 -:101A2000DEBB3B16DDFF0C93F703E4C35567DF1EF7 -:101A300063A7FCCD96FE180FD607F87730462ACC60 -:101A4000A7E4F584A37A332C2601CFE927503BB2D3 -:101A5000297F19F2597580AF13C7C642BEE18D12B6 -:101A6000F53B1B6BE371BCEADF37A7A13CBD9CC40F -:101A7000E3CD97AE66F3F715A6E0F341A74310D385 -:101A80006FC0F8E46511D7745E95E9396DFE918DEC -:101A900085B21DF82127B0F100C5514D6615E91A30 -:101AA000F51CE378688A22B9AF6E99CAD0EE77390F -:101AB000984B82FB3BA2837FA4F36ECD6615F3ADFA -:101AC00051F68D2C1EC6DF21F659870347E179298F -:101AD000EDBA365F54D3D31873203F50DE374AD95E -:101AE000C826DBC2F11C437876A4723EDA111D30A1 -:101AF000609E253898B16709AE109C8CE6D5E01C35 -:101B0000EEC7F3843B4CC1F3786E06E0B223FD8749 -:101B1000330E276B1AAA629E20CAEEA67544D955C9 -:101B2000974FEA0957752EF3A35DFFF943AC5B6E3F -:101B3000518EABA3437D0BC8C08E814CC8F9CF1F1B -:101B40002FC908EF836219177A7FC8AF363E5E3718 -:101B500089E2099F8CF12FB431F1B84E95D6A76078 -:101B60008A298FE301F7DBAD167EBFFB79E06F1B9F -:101B7000F66DFC39579CDD3A4D2239E1F5B8421F2C -:101B8000DC2705CEDF08A4FD2A702057055856BF74 -:101B9000B19FF87495A1E9A99170FFEE28AF2B15BC -:101BA000E67BED43039D6BFDF38B51FE0AC0C7B08E -:101BB0007D5B92DDBDC8877EFC47DE7BE8C974A4EF -:101BC000FF3E49C53C6C973148DF37A96AFACC44DF -:101BD000F50D8D1F53DDD39BA9DE4938CFB8C61A4A -:101BE000DA8F1ECF36D27E74B6380F5EEFE4FAE39A -:101BF000F2E921CFD684E17F492A972F16F40E40CF -:101C0000B96912F2D9827E0AB47B85BFB4B7F5D622 -:101C10002C352C7F58C30EA423BE1F6287A8D5AED7 -:101C200077F9F9B9CAEC772C77B8C3F86F9190F7C8 -:101C300045A9224F96EA9D8DF0AE6AFDC414ABE231 -:101C40003999FAFE6857EAC19FB2F782976EB9D503 -:101C5000C951B51234E1F3D517F8F957A0731D9E99 -:101C60003778F99DC6118BE1FA5EC035D695FACE6C -:101C70009AA9BE72AFD1938ECFD79CF93A17F55679 -:101C8000090201F07CDDBC6A00E20DF8BE281AE50D -:101C90006B17233DA6C9670ECA27BC9F837C5F8054 -:101CA000FDE1A4877798DAF9F9D3BDFCFC29F03D72 -:101CB000C901F0BD1DFD861C3BC801BD3F94E47BFE -:101CC00047BB81CEC9FA408F0FA67ED11CECEF68CE -:101CD0002FB1937C635E3F0FE5347080C6A987D82F -:101CE000044927314FB83FD9E88C25BA69FAF1B0D9 -:101CF00093093BA1C6E17903AB2C47C845983DE465 -:101D00007D612F4FFC2AF0F82FD176B8855D10FE4B -:101D100014F3E6939EBF57D8AAB5AF4F98B91DD616 -:101D2000B9F684DC5D3F8EFE6B40F0C901E1CFA2C5 -:101D30009D5013783D0E5E1FBD99D7D58E71AF298A -:101D4000C6B3CFE3CA371EC47682A7BE18CF3E4FB4 -:101D50005AD07E909F81E6E7D91B0EDC948DFBDE86 -:101D60005D67CD0CF75D1AFE1AFCE34B8087FB5BC9 -:101D700000FFBDD825580EF11F58EC74E6EC79BF72 -:101D80004BD2F4C7A90AE4C7CE0639D40740AA80CB -:101D9000C1B1FFDBD4938FFBA09F95E67E3E15FD7E -:101DA000ED742FB55D27FF9A8CB660EF69EE47356D -:101DB00098DCD9C83F0D0323BF1FA0B54FA61A89D1 -:101DC0000E057D7CBFEB482ACF6F0EF1B1C7908F17 -:101DD000AA1A64BB1FE87EA941769BC01F3AEFF6A2 -:101DE00026E3D99C0BCC77CB44B4F3228ED4BEF738 -:101DF0007217FA2960A7EEFE65EFFB0FAB99F65B51 -:101E00006340BE5AD624B1FF001C2C7F26F2F9D5C0 -:101E1000DAF76A1AB71CC6EF88AD7C4E771FFD153E -:101E2000FA0E46A41F732455F827592C0BFD13E016 -:101E300023D20F46851D3103DFAE48F7EE437BFC0E -:101E4000B2F8BE02E85192C77D4E615744FD417021 -:101E500007AF2B1EBECD2F1BE0FD098A5F467BC559 -:101E6000A0C57D87716E6F197D87C9E73E8DFB3EEA -:101E7000CB853E5CAEF9697EBE3F026637C24FAB92 -:101E800016AB1FCFFCB5B1B8FE6D12C5CBABB645D6 -:101E9000EEA7548BF5AFDE7CF2309ABCCA7ADD7DBA -:101EA000B1FE6ADDFAB57DF3CF5323EBBFAE773FCA -:101EB000E42F46EE37BC2DC6D1EE9BD2B87EAC8265 -:101EC0006520DD56FB65BF9FFB7936FC5ED09D62C9 -:101ED0005D770AFAD33AE1B9CA6D923F803CFE7849 -:101EE000649DE95DF58BCB90AE7A3E5929D6BD7CD9 -:101EF000BB91FC55FCFE0FCA9D9E3F568AF5AFD4A0 -:101F0000ADBFCA2BE9E0E37E744FF8EA6F413A5760 -:101F10006E37B2DEE0D3E8B552E3EB3EE0D5E0D475 -:101F2000E0FEA1F0F64F13F9AD116C04D1A93CE12C -:101F3000BAE8A4F773771D1E41DF5BBB7C6420C544 -:101F4000FB1A1FE8DF2F137EF2D4CDDC6FBCD45810 -:101F50006C1D89F14C9BC125A9149FC58E04BCE45E -:101F600037CBAC02FA5D4D599BF0FB8379270AE62B -:101F700060FC9F7FC240E7EFF61C29A07DE7FCA331 -:101F80008312B228CFEDA2EFE3C038645FBBDAF270 -:101F900036E1F984AEB692021C5782E7D00FC8131F -:101FA00076A2A62DCF1A7EFE7C4C1A8FEFD73B3F30 -:101FB000FD39FAE9537719E99CC55463F04DACDB60 -:101FC000DA7344A17DF2D527963C1485F47D51A2A5 -:101FD0007DF2C3ED6B1317229F3519EDB8EFDDD5F8 -:101FE000F4E30378DFB75DA2EF5E54379766EF80C6 -:101FF0007EDE967C57F8F9B33C874AF0B1542BC586 -:10200000CF53FB19C96E5E4CB3FE16FD9F95EE2DA6 -:1020100024DF17F7EF3151DDDE0E89A1293BEC3CBF -:10202000F80AE2E3E2AB274DE88417379C34757C6D -:102030008F3F70C92FB300C5CD1B4D18C7546ED14B -:10204000FA1D26A49347F84755CF7D4CFD95E8CF60 -:10205000C37C2B9F91A97EF760F36B26E4E7AAED82 -:10206000124BC90CBBBF598AF85EC312C6F960890E -:10207000D03FAB987F7D1A3CB76A23AF5B608F4639 -:10208000D6016BFCBD42F0F7AAEDB3E8FB533DBEB1 -:102090005B8871E30DF81CE7EF659B23EFAF107CC5 -:1020A000BD42C7D73F4913FA67381B8E7CFD75A127 -:1020B0001A9703D7BF3EB972406FE7ECDB84BDD6F9 -:1020C000ECE5E58081EC8DFEB9CEC62B046775DBAF -:1020D0006513FAA7654D5F10FE2B9A5AA97EE46638 -:1020E000E65D8DF8BAB9C96A47B9AEE8E07A685AD0 -:1020F00093D9EF97F07E3DD53977B5F0BA49DF7EB9 -:1021000089FC1C4D8F69DF775C26F0B80C14787A57 -:102110001EFABB3C6EAE1271F28A615B0EE33E7B2F -:1021200095B8BFFAE8C158F40FA7B12F6E47FAC0AF -:102130007C0CE763CF44E27DBAD08BD3B773BDA8E4 -:10214000B76B5DA9D933298F09712AC2B57A7B246F -:10215000BEAB74F1F963693C3FF6820EDF15416650 -:10216000CD413854D9E5A7A7DB159CF7482ED85B9D -:10217000B4936AD6F77E87F14DE1676BFD99E21C57 -:1021800078BD7DA32D3C6E8E4AE7FEC2CAF1B20F28 -:10219000E9D51D6F0C3A98AB1A42F106C419CD6906 -:1021A000493CEEC082923732649698188A371E7185 -:1021B0006EAAC8837EF5762EF79DE3603C3C7FAD2A -:1021C00030F247ABB79BE99C6235D09FE28A267E0E -:1021D0009EC2D3249522DDC15F3F9A86FBB19852FF -:1021E0008575CF6AE47C3FABE40BE297A383F87A72 -:1021F0002F2B6A4A6FFEBBE6B7E3F93035CC7FAFD1 -:102200000239C5E7AB9A783D52C3816FFA67A29E47 -:102210006BFEAFFE8BA1FD5AD845CD2F0C825F38E7 -:1022200090FB45F4BDC9BB857C2DB3F37DBABB855E -:10223000FD61521DF17995B1FE503CFA593B78BDD4 -:1022400000DB871F8503FDF8F64B75F1B0EECE97E6 -:1022500024AA87C3F7F17B949D4BEA3F41BFFBEB78 -:102260001D16F237EF06BF654A5E4FB9D4E45BFB3B -:102270006E560D7B88FCCF87581DB595829F3B1B02 -:102280006BE9FBA09ABF42EF0FECE98F540ABEAF97 -:10229000D4F15F547A24DFD5BC1D4D7E63D751D96C -:1022A0008EFB3180AFDFA485E345F8210D07A288BE -:1022B000AE5D276D6447FE2CF8EDA2C83FD78C9326 -:1022C000090F86F1BCCD6E796D20D211F18EF5F734 -:1022D0002FB7BC36829FFBF613FE576D9323BE0FBC -:1022E0005B591FF9FDD79AB76FA3EF0855EFEF863B -:1022F0006B88293104575F7220493C8E34489171B4 -:1023000064F53ED9135E7706EBB903F551BA900731 -:10231000A6049331FF35009D0680AFA689D3D5D0A2 -:10232000CC5B98FF169E2731D2FC3DEE17F956E3A1 -:10233000FDAF33AD7CFFFAAAAF02FBF70F94A9AE55 -:10234000F3FEB7570E0DD7A30CE104BA561B83C991 -:10235000146F9E34107CD5272F270FB2A15EDA525E -:1023600082DF0F9D2EF4DFE181D6E5C8CF3E9C379A -:102370002534CECB69BC7E8FE17A9DE86DFC928FCF -:102380002BD6FB109B2DE26ACE4F39697CBD108F96 -:102390008C4BEF251EB95EBF13ECC3A98512D63353 -:1023A000293E8C87F7BCC7F5424DF3B28F90DFAB67 -:1023B000DF37539DD7FD2DCB8652BDAFD77B03FAB8 -:1023C0001B5FB7ACB881F283D24304970FE173A2CD -:1023D0005F732619EB522B9BCF2493DDDD3B7A9361 -:1023E0002F06FD97BCE9781DFC09E23FF06B88FFE2 -:1023F000F6B415687E8C15C7AD3CAA78103F95479A -:102400000B8E57A07F71A2A800D5B974A280FC984A -:102410007CF4636C21BFA65B4FA6733FA6AB358AE5 -:10242000F20B121BC8F9870D8AE09FD50DAF93BD43 -:102430005FDD2847D42F6AEFDD99AED038CB34FE6C -:10244000A997DCC41FBB78BBBA710FAD6F95B19E65 -:10245000E85DB3DDC8EFEFE0ADF67D581F8BF721E7 -:102460003E8EE325A0C334933F03F3D3C732B99F15 -:10247000AFA7C7E7E93CFF71ECAC7700F2CBB14204 -:10248000EF507B2F76C2C78A785C2B097C37F073BC -:1024900053FAE73E4B97C4774222CFB76AEDA9744F -:1024A000AE3FA7997AFF2EE06FD2B57309EC3143A6 -:1024B0000146C546FB06E1D7A7867DD761CECD464E -:1024C000F2174E31FBEB58EF3843D3B3E3B87DD569 -:1024D000E7CBE789F73C9B55BE5FA43B3F334F3BBF -:1024E000DFA43BEF364FF83BF374FECED3E9C28F47 -:1024F0001FC286A01EAC17E7EFD60E8FF287E7B398 -:10250000F4ED61B12F82E787B0AD19FE2EE57D8E27 -:10251000B59E7D85EADDCE46B1813CAF47F9EFCA75 -:102520003EF2DF35DD72393782CF34BA5C12DF8399 -:10253000D1D365B7A6AFC4BE5DB4D8B7F31BBDBBDE -:10254000519E2B2D174DBCEE3068427D56339CFBBF -:102550004D974A25DA6F0738FB9BC3F4FBA5541E41 -:102560007FDD7F8B4479D7567C1EE3AC7A89EABC49 -:102570002B03ED26E4A7210D8B1F26B9F5B1D32C33 -:10258000ECBB1A332DDC4E76D34F5B77B71D8BF740 -:10259000717D9C482D3E8F767186B083FA735143CE -:1025A000597B593AC033DF2DB9B01EA02F3ACF5E08 -:1025B00030EA7544C3F5D2BB33DDFB4E3ACA79FB32 -:1025C000E55B308F7A6CF867FDD18E56F5C1C71F79 -:1025D0000B3CEBBF2BE31AAAD6E2F7556A9DDE0E41 -:1025E000D29F866F6347301CA7E3376B25A4132364 -:1025F000FEEF4B7E3E13E37E96CEBF770FB8A77DEE -:102600009755E9BC4EEB98D19F41798A9CEBDBF75B -:10261000AAD9F7462EEAB3CED6A3B9A630BA5E5CE5 -:102620000B7A00ED4AF3C164D516CE7706E237493E -:10263000D2F84F11F632920F2F221FE6607B2676DA -:1026400010EAE35DA76207E3787B79DBCDAF4DFC51 -:102650007BF6101F0D9917130EDFC304DFA57A3E1A -:102660000E631D43E68C0CBF5FDB171F5B33888F47 -:102670003B22F8585B6F3D7ECF07E38016337DCF5A -:1026800007F3D78E3039199AC1F5CF58F1FD9EF175 -:10269000CC47DF391C2BBEE3335E6101251EF7CD2D -:1026A0000232DFF7E5E72DC6087E1EAB045AB18E75 -:1026B00062BCD8E799C0DAE9B9292C48AD9BD9E9C1 -:1026C0001C451173513BCE12988EEE544E7D3DD574 -:1026D00025069215C7798B38AFD10BDD42EB57E851 -:1026E000BB3DC49F329ED7E9FDBB2FB333B8DCD3CB -:1026F000C74590BE9718E5B9F07B6D38C9448595FC -:10270000637DD3648559A201DE5D870C24CF2D1D26 -:10271000AA1FEB535D09E2BDCF19D5E18E75737920 -:10272000459383F518DA7AF5789800E3619E6DACED -:10273000029128E13140F3DDC8F8399242A652FDFA -:10274000736946A6D0F7418AA38A218E427D6FB075 -:10275000F8081FD33354BA8FFB25B130CE848D12C5 -:102760007B0FF73FB2F87AB5F1270023E0F9C2E911 -:1027700019DC9E614AF5BD78BE8F124B05CD2576DA -:10278000FE9DA364FACED1F5E2B52B997FEF32F628 -:10279000CE60E7CF0A42FB492EFCEE516CE83B9B32 -:1027A0002EEDDF830844FE7B1077642CF911F2A331 -:1027B00056AFC7BCFCDF7DD0D7EB85D5E7B10B6149 -:1027C000E7B0B5BA926DFED92A9EF35B9068A1730B -:1027D000BF7996FEF968C7063ABD34FEFBD2F6C152 -:1027E0003498E21FED8909F1BB95B9C721BE437545 -:1027F00083FC3B50DDE7AE92199D57B49A797DE595 -:1028000063201FF81D26902E15EB68D883C5548FC2 -:10281000B9DE6171E1790933C26D0DC15D6B11DF04 -:1028200005B5F07D717D3D68ADCD40DF1DAD65D155 -:10283000740E3D29DABB2E03E0BA2FA688CE776747 -:10284000EF9CE444BF317CFD93B4F51B7AD647C2BC -:102850007A1FC9E8A51E515BA7F6EF76D805FEB42E -:1028600075DBB5734A6E25E29C92868FC7A2F9BAD2 -:102870008DB8F39F45EFAAA837F4EBFDFFDC29BC28 -:1028800016A064000000000000000000000000002E -:102890001F8B080000000000000BB3D36660F851E6 -:1028A0008FC0C19A0C0C5DD2A862B4C41D120C0C6E -:1028B0009780F80B106702EDF5926460F006E26D08 -:1028C00040BC1D88C5A518180280381088FB80FC04 -:1028D0007E204E07E224A81BB30519187281381F09 -:1028E000880B815848808141588078FB8B151918D6 -:1028F0005EAB22F85A6A0C0CC91AF4F3FF60C3816C -:10290000B6F4B5EF16D0BEE56E08BE0490BDC20D9C -:1029100055CD4A37FC66AC42935F8DC65F83477FD7 -:10292000810D2A7FAB292A7FAF3903C3072435DB0A -:102930004CF1BB051D2B00FDA788274C9730A2F258 -:102940002732A1F2F9A17C00BE1E313CA803000091 -:1029500000000000000000001F8B080000000000C5 -:10296000000BED7D0D7854D599F0B93F736726992A -:1029700099DC24433260126E7ED0A001879860B04B -:10298000586E20E147A30E082CB440262888166D07 -:10299000C49FC6DD500609BF0921E14F70D11D104B -:1029A0005DEA63FBC5565B75BB7682D646AB356880 -:1029B000D787767765A015BFBA761BD96D976EBBA2 -:1029C000F57BDFF79CCBCCBD9900FEECB7BBDFF30A -:1029D000C5C7E770EE3D3FEF79CFFB7FDE73C725BC -:1029E000FB59701A631FE31F9413731963B5A9B2DF -:1029F000C5C362D9398CE576488CD530B6B25D89CD -:102A0000CF827F1676B4BC82F5E56D6EC35DCA5881 -:102A1000FF036E7F0DD44F6F57C26EE8DAA8F8A897 -:102A2000BEACCB15761BF07CEB472FE7E3FB8D525A -:102A300098419DB1BB199BCCD81A0FFC13EACB2A45 -:102A4000921DF8FEDD2D523886AF99E99B04EF6F99 -:102A500065FC7DF3038AC664A8EFBBAD894D64ECC9 -:102A6000961E98C5430DD9C7BC3D63058C45F82318 -:102A7000D6B205DE57A6DE4758D7470AF46B8E3923 -:102A80009EEF9BF53E0BE07B2DF51CD6730CFF31C2 -:102A900085B14B993F783A1BFE1D66E18F15281BC7 -:102AA000F2191B9DC297B3640CA01FC5D85CC65C0D -:102AB000AC1CC6A9BDCCC5CA607D161EDB381E97EE -:102AC000354984C7653E46F577E74AF1074BA91FAC -:102AD0009B5E0D253C2FC88332C8CC4228231E960E -:102AE000C806F8E7B65DF61EAE7F034E359ADA27C4 -:102AF00002F07E018BBA18C0F7672C46E56216A774 -:102B0000F2CB2C41702C6543252AD4EF52129B182E -:102B1000CC130E45A7E3FEFEAEFED8BB12BCBFBF72 -:102B20005AAA9D0225F3E5D1BA2FB43E6B7E954596 -:102B3000AEC37118935D113F63E3AD751E66B18A34 -:102B400020637A8F8FD3CB61D6CFA03EBE41D04BCE -:102B5000E3FB7208D6DDF33C0B633D049B3905EAC9 -:102B6000A1AEACF806A8F73C1EAB47BC1C6B01CC71 -:102B700043FF638D6E295A05A54B7745A00CA98CA0 -:102B80002980A7FA86F59202EDE646F938E34D4D25 -:102B9000665742FD704C52C573ECAFEB314987FA72 -:102BA00078A83F28E17BDDC5609C86865C57B20A29 -:102BB000F1DD334687B2E2B0969001BFF5A64ECF65 -:102BC000195B4474355ED0DA5C93F79B7B38CFCFCA -:102BD000E83DFBD3C7D67BC0EF25457CDF8E1D2E9D -:102BE000CB417859D4DEBF4865314F5E0ACF3BD721 -:102BF000C10B770ABFBB0E976D45BC1DEB53C3825B -:102C0000946DE3C3B8BD0DF0FE4C951C560CE4B3B7 -:102C1000220E7F85EED77DA97176AE83F697A5E06B -:102C20006854A6F6133E4C46FC38B706DA57A5DAC8 -:102C30003F81ED018E3D080FF55B73D48BF3441893 -:102C4000CD33123DBCB04EA77E83621DD7FCEF3062 -:102C5000EDD3DC861689CF2BE06BB0C36795167C6D -:102C6000238D7F4CC0658D6FCDF7C4BA10958D4A0A -:102C7000D523F7E2BA8E687C5DF38DC77723FE8E8D -:102C800078C231A83F79DDDF8CB91786B862FAF3D4 -:102C9000973FC370BEE50FDF8EEB7A2E8BD6F5D44F -:102CA00087675EBB910D9FF72D81879F9E9B3F4459 -:102CB000756BFEB9A63446023AAB34A5840BE8E541 -:102CC00058FD571EBED7C07ABF89F2A4D23C664ACF -:102CD000504E846168BF99FAA78F419E554277E4B0 -:102CE000C7490D520BB67BE2C687BE741F3CFAA9DA -:102CF0008BC37DC55F72B82FBB7EED9308EF653740 -:102D0000AEFDF93350BF028520F0DDA537ED5FF34E -:102D100077F0CF6F2CFCCBE57B18C9855836C09176 -:102D20006B4A0CF777D9F7DD36B972EC793FC99564 -:102D300042B33486FCB7AC4F22F9DCDFE866417C55 -:102D4000FF3377DC8DFCF5806452FB67DD71940FF7 -:102D5000C75C8CA13C5E76DC1B477E61AB9691BC68 -:102D60008E58F2DACC5F7A2F8CF76E8325CF399D9F -:102D7000D27B58DFBBE62FB65F0DFDCF98AE308A11 -:102D80004D4B5E38F1FCAEC06FA4BE9CE860999AD2 -:102D9000748533D043739B6293DBF50D2789AE9620 -:102DA00041C9D2F874AEE0B3650DBF10FCA9935CC5 -:102DB00072C2F3466D617126BA3B25E0490A7A7BFF -:102DC00017F7FB32840F7A21DD742971254D4EC32C -:102DD0009F2B3281EA3164E95BB6D8E1B4E4764BEB -:102DE0002CDBA6AF40FEFE0BCACDE6B67CDBF3B90A -:102DF00039AC76EAA793C37F20399C94081ED0BFD4 -:102E0000B4FF91B81447B968EDCF1D627F22158CCD -:102E1000D6F3AB03523C06FBFBAB23627DFBA4B8AD -:102E20002211BD9AA73D382ECC599EDAFFDBC5FE94 -:102E3000A7F68FE3C7C2574ACFE56E4A02082DBEF8 -:102E40004809CA6B8B7F2CFCF6EFF95109EE5F61E4 -:102E50005B69771DC2794021FEFDB0FE6431EEDB77 -:102E6000BB2EC02BF48F1C7E2CC07C29F85B841CED -:102E7000FCA003E8059E4B0867651A9C026E17D6F6 -:102E8000A1DDED0D521FF2E92FC5BC56BF1F6D9994 -:102E90003113F173478FC4103FB71FE95DF6E7B0F8 -:102EA000FED5F1EC304EF1ABC6E2C02500CF8A1E54 -:102EB000FB7E9EDA727300E9E6C3BEFC021CE7F6F5 -:102EC000A9090DE15C9D78553380CE6699BD5A32D3 -:102ED000035D7DD8B72180ED3F547B6EBC06E7D9FA -:102EE000A784D7C3F8AB8F94CE34399D12FDAE16AC -:102EF000F83DA9F6CC1C03F0B57CA39CE4C17B7D16 -:102F0000CAEC7806F9F97549213A58DDE696719DC3 -:102F100023D1CB871D2E96C079D404E173A4761FEC -:102F2000F4B5D0FBFE070A6F40FBEDF67617C98BB0 -:102F3000DBDBDC444FAB1BA4389352FCB642C0BB76 -:102F40007AB742EF4F9A12C90F6BBF6E17F476F241 -:102F5000F055AFA0BE3F03F207E5EE8C8D3FD42EB7 -:102F6000013CACD8C2E5D1C9DDB94BEF413922F4FF -:102F7000E51D62DCDBE28A8D3F56B667DBF623DABD -:102F8000956FAB9F3E927F631DD2759742FAF39681 -:102F90008D8F6921924F767B13396C5241CABE3CAA -:102FA000C186165C23A5E8C9A29F5BDBC0DE0C0CC2 -:102FB000B7375B8E48648F5EB49DD90676E6C4E170 -:102FC00076A6254722689F95A7E4882537EE52A26A -:102FD000638300C7AF5DD1CBF2CB496E3C20D522D5 -:102FE0009DE8BF45BB92C5945A946F172B2F68B1CB -:102FF000161FC1DF7B1D405719E87506D215CC336B -:10300000B3A73F233DCF900C1A2F4537B704886FE5 -:10301000715080A3D96376219C97C0C4DE6A2A9937 -:1030200092C74B15EA9B1166A087536BA5F8A15276 -:10303000DECE87F214E0BA069E37775D1EDF26A14A -:103040005D087FA83FDBB8DD0DED4C7F1E3D3725C9 -:10305000288BDA4B5FC6FDB904048056CDDBE33C18 -:103060006067114AA07DC25D4D5D6301288BA19F01 -:10307000CCFBD37B6C1720391EA7F5E2F8384E85C0 -:10308000125F8372C6A2E36542EE805CAD5481BEDE -:103090009A595618F566735BF979ED971BC276F964 -:1030A00071539D5D0FCC35EDF2FFE6D997D8DA2F3D -:1030B0008894DBDEFFD9A22B6CEF1747AFB2D5BFE8 -:1030C000BCEA0BB6F64B5B67D8FDA49FE6D27AD676 -:1030D00008BE1C09EED785BCFC89C33EB5CAA6EB69 -:1030E00013356FC33EB175EEF0E3509C98C316F5EF -:1030F000A5C9159F2C113E7F036CC2FD833F7D4CFB -:10310000780CF1799BFEC2DD9A89EE34D10FCD2582 -:10311000B4979CED4F2C8679D2FAFD9B24111D9E0D -:10312000EBC73C3DBF04905B80937300F577B264BE -:1031300009EE9B3BD7A0F777C9C902ACFF860DED1E -:10314000CDC7FDF5258B917F9A55F69C9483FDC2E2 -:103150001E37CC07D6106B03FA6869FBD171B4E354 -:103160002423C89660DDE34B207FB30ED787490B3D -:10317000EFC087BDA1E88712C021B5F7FF5EC2F797 -:10318000DF6706EA61962CCA45FF11A74AE7C3A686 -:1031900019AC15F175A2D18E37AF58C7CF2599DA82 -:1031A0003DC7CCDF221F9D9474BE3E01EF36C93C63 -:1031B0008BF35970BF9BAB6BECD3C1ADC8B508F7AF -:1031C0008F08EE0DAD2C99AD8C0CF715CC74CBA3FC -:1031D00086C373969959999ECF0276CDF4FC7237C7 -:1031E000AB447BF58494155E5F8AE5D03F7E0DF895 -:1031F0002AF60D5FF87163385D4C957369FE666160 -:10320000EF16B64B896CB44F9987EC57D6F390E91B -:1032100041B926445C4B9B7412D7CF3A1ACDA427F0 -:10322000B55E66482CBDDDB97D6F73537B4BDE58B0 -:1032300072CBC2A725572CF965E1D539FE48720635 -:10324000C753F310FEE824399D4E74C0C70484C7E9 -:10325000ACC6FDB3F60DDCC898A77AE47DB3E414E0 -:10326000B463E8FF8FB45F8027B2EB5C6146787A85 -:103270003738B4F42958F7401BD7D7EF1631B20FBF -:10328000CFB45D359083F8F1782A103F857C2A56BB -:10329000181C5A87F2D5A726FA11AE42A1BFBC8CE2 -:1032A000EBAF4266ECB81AFDFBF6934BB09DB53F11 -:1032B000B9627F9A617FD01F69F60D15A39DE44620 -:1032C000BD06EDDC2077512E17B6BFFF1FA8170BE8 -:1032D0001D7A112161E9706455EDB8DA481FFFA32A -:1032E0008D685F5AE35287F4FD0F6A2711BF85EDA1 -:1032F0009BEF5602B6F1A58F110F426EA3D9756EE2 -:103300009E52B457E5843B90A20B275C56BF91E8D0 -:1033100084A5CF536EAB933DE1ACBBC39A4D3EBF8A -:10332000FBC7F29C56DF79E8CD399E93BE9D7C2089 -:10333000F0F029E87413A7532E172CBEFDCFA2D3AB -:10334000A8B5AFB1DC3B8EA07EEDD2C2B30CB413F6 -:10335000867EC8ED04B77108E92C266555C2FB6866 -:10336000874A76A36557F4AFFDEB2D65F0FC44ADBD -:103370004C7EC489F59CEEF73CC0ED514B6F478500 -:10338000DE46BB00F10A76C3809B971E1CC7BFFEBA -:10339000E65209E0F61843FD6E6CDF6690BD9A5365 -:1033A00017D71BA18C571CF28C3352722919CBCF23 -:1033B0005B0EFBF5AD5C635984ECEBE8E8B9FED439 -:1033C000FB1FCB5C3F4D2B6179B361BCE45639FCEC -:1033D00020F44FBAEC7ACC2AD7285C5F26BDAC0427 -:1033E000FDE091DA0D29965ED535DA97F903C771BC -:1033F0009F46DA07D8019DE298E7E890E31DE6A131 -:10340000F1937EBB1E3A29F49005FF27D0AB0B8BBE -:10341000813EF64A99E1FE488C177D0E0080FD8EB4 -:10342000AACCCCD4CEB9EE7F10FD12B24AF3EDA8EF -:10343000D8391BF73B1653C2E9FB61957FA170FD9C -:103440009933B721B711DAB1F599DBE589768FDDCC -:1034500097B508FD2B409D8AF19A504C9F371BE38E -:103460009153F326A18FFD63D43F30EFEEC819BD11 -:10347000C5F789F051105246C6C79BB2CCF7D1C1EF -:10348000B77BC05D43F999943C147F6989B933F2E5 -:10349000B125A79CF2C8A9E724D3646DD5C3E58AFA -:1034A00035EE27D567201FB2945129BBFD9C3EBB4A -:1034B000587A1C410E94C82CDA97C13FBD5AE17866 -:1034C000EA8FF138856ACAA4B7662A4D4C023C6D72 -:1034D0000832920779B8D7C8B70D2C0E2860F92C9E -:1034E0003CE0437912945982FC56A71F6836A11F0D -:1034F00018E4A0317D54597F213C0FCE5F49E70C81 -:103500002CC2E5AD0EFF713E32495FB8055EA3B136 -:103510004914E7CC6BB2CB7137FA81201FF506C78F -:10352000F3F933E9BCC1CDD29EC33AAE52FCC1D34C -:1035300060DAB36A5683FC59BDFFAA5D8B61FC9AC1 -:10354000476E7E1BCBC907EFC9FF1294758FEFBA88 -:1035500019CB92D7A26333C553AD123885C9750014 -:103560009F8F19EE9C91DB19EB9508DAD5B08F1D72 -:10357000480FC9587916D2F72A85F37FFF022D80AC -:10358000F119750B97ABEA7C401ED13FF7D39B53E3 -:10359000FE34F915AAF093947685E20849BD8CE2D1 -:1035A0002D87B6C81A96206763388F357FAF88534A -:1035B000778A78AB13BEDE92A162948327D67F44CC -:1035C000F6A1A2678567C37C5D7E5642708878410C -:1035D000B3D8BFE4DA7A4F7ABC48117E4EC7D139EE -:1035E0000306D2C18012F61AC4371A8E1BDD329D33 -:1035F00061FC65961E66684F740ABF47F1990CF727 -:10360000355B6733D1AF85575A08FB57B17002FB62 -:10361000B7F7236E61BDE6EDC8073FB896DB2127FB -:103620004AED721B48A80BF694CD2A5AAF226D368C -:1036300005275D8534FF7BA540C8554EAF6FD44E3E -:10364000796C1BD0C1736EF31E65D427E023875CB1 -:10365000FF01B009EEDBA3925D9E5BE541271FB53C -:10366000496417AA265FE74CE5C346D4931BC16E95 -:103670002C3486F3CBC6D719D98D1B81FF62A5994F -:10368000F8A75A421971B1FC93D79E2B611CE3B382 -:10369000F2CF5F2AE29C4EF00FD05902ED984725F9 -:1036A000A3730AACEF3BFB1A7F3C055E3F7B604592 -:1036B000F635507E2FBEF1FA6B60FEDB1FDF938D77 -:1036C000FBFCE8ABC04FE7F1E32D7E6A461BF63CFE -:1036D000713663AD9D9F8CF515C44F6F295C7FF5E6 -:1036E0002FF8DD1B57FF7F7E3A1F3FBDAD007D4E9B -:1036F000FBD3D9E2E879E45B7311D3D0DE823626BE -:10370000D27934682F7D6A16E17B9D8BCB31BFCB9C -:10371000CBED8E107FEF1CEF6FD44F1E3F5850FE45 -:10372000D9F9749DCFFCE8F3E077903B246F4E8C81 -:10373000B3F37DA78BD3DDAF5C9F787DEF7CE17326 -:10374000581FD8F564DF5DA73203FD80892F7848C4 -:1037500058BC3A6EE311648969F03C94C7DFBBF34F -:10376000485EC6D18E19522AA9BFC9B81DDF54B30D -:10377000F9083F9718AC5804FEF21CF817DA23D763 -:10378000F9B85F01E3B0108CBFDA1B2D5647D17832 -:10379000E45FBEFAFCBE20CA97D73D66093E674982 -:1037A0003517CF072CBB63647E57D9E9343FEB69EB -:1037B0008D111CA72ED5285E89622C00F5ADA5972A -:1037C000529C928563C725AC8FD219CA71251859AE -:1037D0004C76489BDB9805F5AD6040C58244B72424 -:1037E0003795F6DE5000E500D825F85E8DCDF568FA -:1037F000E8BF8C923108CDDC6D1F91DF7DA298CBA4 -:10380000DB8E298CCE69061EF8B7A532DA3BED6E49 -:103810003AB700BB91F8352AE44632383DD4827E6F -:1038200046911696A0BE29F68BE35FE3F2C4F44CF2 -:103830004E8F8FF078474B88FBBB4EBB6FF3D72F73 -:103840007BD3C0F17EF85AD7E550BEFEE4CF5FBF10 -:103850001CDEBDF1ADD76A30EEEDAED36C714737EB -:1038600033DE447B0B7CA68486F2397672096E6661 -:10387000CAAF9362889F688D3F8EEB45DE46FC247D -:10388000A728FC7C11FE42005F40C0D71D3C554577 -:10389000F3C4DEFF8F4CF29EFE260B3D02ED36E7B1 -:1038A000DD1F4739929A6F12C9A728C827F423A3AE -:1038B000BE9E256B683E7FF841ECF347D8D5C9A979 -:1038C000F3C2435BE6B5209EE72EF0E84867EED8EA -:1038D000E6BB91CE9DEB3CE37BF0520CCDD9E607E5 -:1038E0003E715768A697EC5F7698F64334B1E0D600 -:1038F000418160DC01FA2F5BC132F437A03FAE1387 -:10390000E419DADB563F206313D77BC637FD528AB2 -:10391000F78B7885D5EFA69844E7043795031B9479 -:103920000FC7D3069FFC93AFE1B94B4CD1154E079F -:10393000A18A34BCE19F3D6EC6E9E2B27D76BD0B43 -:10394000F32F2CC5F73185E8C5C92FE3E3F6F61B45 -:103950007CE73FD71FBE9F1CCF1305BF59FD2DF835 -:10396000085E29537CDD7E2E73539DBD3E77183E45 -:10397000CE0FD774D57E6ED3E0B38F3733687F3FD9 -:10398000BBC85EDF80F19B4FB26E07DF3D3DC6FCDA -:103990008EFA19FC7A4BEEBEEF89FC2D8DA38619A9 -:1039A0008ED3BF60EFFC794007853AB73B0AE72F1B -:1039B0006CC8AD4139C5449E4966FBA350E87BA560 -:1039C000FD252507FD5193B74F2E796B460E9E17A7 -:1039D000D7313A4F8FAAF7C4728C943DD2AF966715 -:1039E000219E3F7F7BE46E6F7ADE4DCA1E79E055E3 -:1039F000A326833DA2DE239930CEAC25608F54A54B -:103A0000DB23AD12CAA0EC25608F90DD117D0FF194 -:103A100035925DF263CBBEF767B6ABFFA0723D0B8C -:103A20007AE69F3E8B9E19E735FF45FD1CEC8169C8 -:103A300025C6CA48063AFC40E5F10E4B7F36061310 -:103A40000A9E9D83DE545DF0FCDABAE44B288E3B7F -:103A5000F49D415C37ACC7E5AAFDF4EB39A372785D -:103A600026AA3C0F66A47EDF1AC15FF16A5E61B7C9 -:103A7000D8F7BB7FC13BBA8CFE0BF831E8BF247D81 -:103A800065DB302E7826A652BC4E9DBF72F75CA433 -:103A900027B0B3393D9FDFBEBE7648B6F1F1B4B36F -:103AA0005936BEAF67F673BA191EFB395DA36E3F78 -:103AB000A79B15B29FD3CD31ECE774D757DACFE986 -:103AC0009CF6FDCCD1AEFF9EF67DA891113F5DC066 -:103AD000BE077EBA09E969247EBA2EDFB83F92613B -:103AE000BFAB356EA7AEF6461620DD4D33B85D1779 -:103AF0008DADA77CC0BC28C89B528A1B52DCCB8AE8 -:103B00006B59712F2B2FD08A6739E35756DCCB8A3C -:103B10006349311EB76AF6445720BCCDED27659442 -:103B200023FA73300F3282758E372C3EC7E5414B36 -:103B30007BE6B89C33FE3662BB4FC9579F837E58E5 -:103B40008FEBB5F403F0F9839F85CF416E6DC3F120 -:103B5000FE05F97D14C9936EDABF0AC035DAE9B003 -:103B60000F1AC6E9179CDE8FF138F5B89BF8F6629C -:103B7000FD5F4C749061D3A2E083633C2B1A2B252C -:103B8000FD62F18DC5274EFF78187FFC57F3CF45B6 -:103B9000FAC7C03FDF739D471F017F3C8FF89E56D9 -:103BA000C9F1EBE4078BFE8124125235EE773481A4 -:103BB000ED2D7A672F864D8473A2F06B4E8CD6C89C -:103BC000BF38F1FCBFF373D8E73DE171628DF87E39 -:103BD0006277417C5B698ACF2C7E6AF7447FEC4A2E -:103BE000CB03B1F21D0F7BCCD7F17948ED4BA0BFD1 -:103BF000129ACDC21B0CE2B363FC39E7535F9851B4 -:103C0000FCF433FB657B5D713C1F6A91869632F252 -:103C10005B99867CAB0A79F26256F424E2B3797A36 -:103C2000A484D3D3D0381FC0F58B0E85FCB5CFCA82 -:103C30004FCD23E1FF1C3EA243AEDAE1F901E97268 -:103C40000BE55B28A4C5374819E495C0579C85C788 -:103C5000E0FA603FFF1DF19857C5245A8EE0E366F5 -:103C60008FF907D767B33F14AD36C5C780378F8646 -:103C700072B11AF0563E1C6F275D7CFD4EFA0BA9FF -:103C80004919E93F0472748394764E2AF062AD6755 -:103C900024F96CD169DA7943484B5FEFFFA372D9FD -:103CA0009297977BA293711FDC6644C83F93F6D727 -:103CB000296786DB41329D339E01BB07BB5DAC7C2F -:103CC0009D76D68B87256CEA5985CA6BCFD2E109E0 -:103CD000FBE2D96C2ACDB3F954D69FCDA572FAD99F -:103CE0004BA89C717634950D67011830711ACF96E8 -:103CF0005239F3EC1554CE3A3B9ECAD967AFA2763F -:103D000073CE4EA2F2BAB35FA0F2FAB353A874DA3C -:103D10003FC67A95E4B725BF2CF9EE94DF96FCFBFD -:103D2000BF26BF630D1765FF80FEFBAA761EF93D17 -:103D300092BC00BEBE4F4B971329FD7CBFF619F80D -:103D4000FAB8E053E0DFF7300EE3012F8EE2546162 -:103D50001EA70A189A81791AFBB0096CA9BF3472A0 -:103D600012E306CD0B3C7A0CE01E28D5483E6D0BC5 -:103D70006A74EEB659D2477379904C20FDED0C6908 -:103D800034DEB63F2A5ECC5F7869544100E7E9F63D -:103D9000CB3AB6FF566E72DF2D788E3F85850FC108 -:103DA000782BF6ECF1A4FBE1FBD13800F802B1A7C7 -:103DB0001903BEDE38EA774B713EDF5446F118280E -:103DC000CD4CF962DF748BF36975288478DAEA9355 -:103DD000491F74EB1E91879A1C68413FB74E66DB02 -:103DE00060DE0DA3DFD98260ABE3CA7694417D67C4 -:103DF0005D991737E9E9573E08913D01EF10142806 -:103E000013A23473607F3ABD61E37CE76D8A31B4FD -:103E10000E8915FBBBAB476EB7C93F1042FAE89855 -:103E200034B9F21698BF7752C1689C7F7BCD511B85 -:103E30003E14DD1E4F5130E0887E785D92E26A1BB1 -:103E400064634719AC2F20F2AD01CCCA485ADE8119 -:103E5000058712867570B8120A5F0F2B80E7B97557 -:103E6000895892AFD7C4B8ABCF970CA1BFA8D49D47 -:103E7000A6785BA73FB988EA0E38ACF17FAB5979D9 -:103E8000019C6F7C826F9A277D7B11E5915769B405 -:103E90006FDDAEA105588FAD75B1C733C46F36085D -:103EA0007EDE5679FEB88CEAB3C3D1EDB5FB8B1636 -:103EB0003CEF8BD20947B36B6854A6FDFBB4F35FAC -:103EC00068DD9FF77C9D23E40F5CEEB6EF4340C8AE -:103ED000F3E629DF0EE1B9B8054FA704FB50F3F96B -:103EE000EF43F3142EAF3FEFF5FE4F1BF7F71A8F9A -:103EF000AB009FCE2EC738E398C9218CD7FAAC7897 -:103F000074384EF949018C47532F83F490AAF3314A -:103F1000149525900FE5EC0F13B84F4AB566282489 -:103F20006733EFBB12DE44796D4EFEB4E0A6BFC925 -:103F3000C274A0F343AF159F36D4C9FCBE04C67F3C -:103F400015669DCFF2F8B4D55FAD90291E4D81EC7A -:103F5000B47154D0C3788EA3609C3A6FF8FCDF4DE7 -:103F6000D1A37DFE221E1F5754EE07BE27717CC4CD -:103F70005E5528DFB3EB792EDFD87146F2BBABD6A6 -:103F8000A073951DF03FFA0FB15A5F1CE95671E41A -:103F9000E39DA99C1E42396AC5C5693E7E3E4071BB -:103FA0006ECC53A4B8B9C12AF07DB700CD1A47B57D -:103FB000E2F2956B26613BBFC13CCFC1FAFC752C88 -:103FC0007109C01B74B76EBDBC34433CBC72CD37A5 -:103FD0009E8479773F35FD574F427D971C7EB50E05 -:103FE000DAE57FB98EF0EA8C876FAB944D1DE583DF -:103FF000CF7708F7156C68A28B5B7BA4183ECFF6D1 -:10400000F90EF2FD6E0D298817D0938817AF332F64 -:10401000321DDF6508C7CE8179F06FEFD679CB709E -:104020005E841BF32B57F4D66BA867824BECE71723 -:10403000FE267BDD5B658773ABD8BF0BD1BF330F2B -:10404000B1C79CB708E9F64C5063286F36AEBDFA8D -:104050004692FBDB1536AE3403FD3AD6D5A9B948F6 -:10406000FF771BF57B2B506F346894D7D31DF7C6B1 -:1040700031C57B7B5DEADCC466BF1B1A3FC7AA91D2 -:1040800013EE4C76BC381F0B8867CC710ED63D5BA7 -:1040900026BBA6BB87CF638DD75DF79607E5C448DF -:1040A000E33E3DC63CE2467B2A9A7751F72EEEDB93 -:1040B000E8E2743D458B4BA5688FEA0B17417DF311 -:1040C0003899EC2126FCBFEE6BF979E2C39A61BB0B -:1040D0005FB169CA4AB21B6E72EB82BFC02E9C9060 -:1040E000BA6F71C06BBEE086E7EA733012D803EF97 -:1040F000E5866F44BA680C7E4476D4AD45B28EF442 -:10410000B5624F23AD6BB32EB304DABD6A2B19A988 -:104110004DACD5C4F3004CD444BA9B036F64BA17BA -:10412000913CD40970CE195738691BD4DC45AD9445 -:10413000C7D26848E4875D07984179D0521C51A5E1 -:104140002AEC37FF1DB4FBE6044B65F4F7AF535977 -:104150008396669F835D7CCC9DB6AE13E3F604E543 -:104160002A9C1FE6C1F91779E83E811BEDE32B532A -:10417000F6F14444649A9DFC6B342A319E5194F8C4 -:104180003DE5797F3F29E3BCEC0556BD4DFAE47E61 -:1041900035F897BFC4FD8C33A31F530D3F6B5CE212 -:1041A000EB9AD827716FE5B027F21B1CDF8A074C0A -:1041B000D4F8FDE6CD2D2C1C4B8BAB6C7EFECF8F47 -:1041C000A3BD6AC55FCEE5DD09382DB837492C8B14 -:1041D000F4BC27FA0777BA5FCC926573277C7E70B0 -:1041E00067C897F3D5023F8D15FC93575BE145B93E -:1041F0003916F37D701FDAB93C31E1BFF47C1F45FD -:10420000305F30DCDA2F1BC3E59222EE4D015D4BAF -:1042100068C73AF38114CCFB99385C6E1C10F47FAC -:104220008947E4FF4C6693B91F6E3FBFF22FE57AD2 -:104230009FB5E665BC87FA7DA1F75F147E6542DC19 -:104240006B3C2AEE2DBEBCCE203FEF957595540EEB -:10425000AC0BD3F3D7D6D55199BA5FC5E7CD177656 -:10426000988A41353CE7F7B1B801F0FA47AD192813 -:10427000453EAFE3F7BBBB9B4E6D2927BB919F5BD0 -:104280006C2EAA4E14A2FF02B0E643DDE5EBF3F07C -:104290007B5EE6606501577388F7FFEAF30A275DE6 -:1042A000E8D6FE3BF6DBC75A19CABB8069DFEFECE4 -:1042B000B0D3BFE1FBEF2ABAB87DEFC57FC03E7E29 -:1042C000C9DAF7ABD9D5FCFB0C17278F918F2A855C -:1042D0001C1803FC7400FC79B7C2F3D5F3799EABCC -:1042E00019E2FC66AABC1E1B2FDABB3809B1813C5F -:1042F0009ED75ECCCF13A81FE695E37B0C4BBEC0C8 -:10430000E35B2C47E4BF8F15E3AC16E34EACA67B12 -:10431000BBFCFC9FF5E958FA5892EAB9C007580669 -:1043200059AB84C81CC306C9DF2E9686A86E487A8E -:1043300016D6CBA47019F7C3E3A43FCB15F3DB1556 -:1043400084FC88CCE345C9C5644F825E46B91857E2 -:10435000238B50BE6C68D3C28089737972787F0ECC -:10436000CB0D7D350378FE118BC9247F94E75896D9 -:104370007E25D97BA4BF36ACCF3B984DF91A49CAEC -:1043800073DFEF29B5E9A989BE85D7E9B05F1B4581 -:104390003E9D0BFAB30CF9A7563E1D8C5B92E9BD0E -:1043A000556EF46B8B32F9FD0F7B2411CF488EA62E -:1043B00038A0D8D7F85439E37DC67D1E6ED73C5A55 -:1043C0009AD99E66EC411A6FBF47778C9B6CA1FB14 -:1043D000333A8F6F64B94CCAAFD9D8C6EFE95BF8EE -:1043E0001B0D762DDAC31BFBE6CF46FE8E55AA9435 -:1043F0006F0EEBF721FE5C222F79E3F8E0C16C1E13 -:1044000097284539DD8FF8AB4DC35F706513E2AF78 -:10441000E3559EDF0BFADCC732E41B5AF873F9D878 -:104420001733BDB7CA8E51DAA24CF7868F7A2C3B70 -:104430003D59CAE984E32FEB5A3592A97D42E0BB8E -:10444000A48C45CF87BF7E8F6E1BD73AF755468821 -:104450007749BE04C5B9266ADCCED8B098E375C3E7 -:10446000F3D71C8FA69D43FC12879C928A075B7131 -:10447000634B6FB67BA2FFE81995D297ECFB8CE4F7 -:104480002E7BC17310F72DC339C4294F6D867388F5 -:104490009E8BFBBECB58C1B787B61C9D87F3FC55DE -:1044A0001D23FB2AF00C9F37576771B914BF536067 -:1044B0004A1867B926A2D7A3FDE66A6726E6CF8C1D -:1044C00015719BC2F63E05E922087B5928E1BDA67D -:1044D000640CBF67327637233F512D9CB96ABD21EA -:1044E00044695A7E94C286FA697DED9AF1782981F1 -:1044F000F553D40F63C4FB40FBCC5FA1DC1C1389D4 -:10450000521E2EF48BF9D1BE10782CF072BE5DDEF7 -:10451000109624681F0C26293EE994EB63003F9710 -:10452000A4D96F015167ABB89C96E13FD4F3F91160 -:10453000BBDC1EE7B8171D70E4BDE47A45BEBB25A1 -:10454000B78BF8A64E5007E54C7E794ABF3AE04358 -:1045500019569DEA1FB0EA9F113E2004A2670B1E68 -:10456000BC4A8972778F4BFFCA53A89FEB359E4791 -:1045700026EECB650BBCFBD061867603535E3171B2 -:104580005F7784F97769CE4C9D477E68769D759FED -:104590008EDF5786328671BA6C31BF75AF2E9B198C -:1045A0006F96033D649B49BA57A75BDF55305902AC -:1045B000F370749F4C7974BA2F42F2A9678147C790 -:1045C000EF7C68E29E9E4BDC1FCF364FD3FDBAECEA -:1045D00061EBE3F7EB2CB8B3B3AADE2C376CF3AC8A -:1045E000C7F836AC7D74C6FB7575DC4FCA36791CCE -:1045F000226D7CBA5FB7636A99ED7E1DCD837E9C88 -:10460000A03FEB9E9D13AE73FD6A32DB6913C27649 -:104610003BE242F7EB5C217BFB1D17C8CFFAC4F7E6 -:10462000EB041E86B573D8832ECB0E1D2533DCBF5D -:10463000330D327D4724F7A3646486447109D2F7B1 -:10464000969D97C787FA6F67E7E55979FD0E3BCFCF -:10465000B2DF7267DBF1EDB4FBDC5511EA73B176C2 -:10466000DE2EFC07D0CB435E879DD794993E9CF20B -:10467000229F0DEEBE12C6395AFB2305F3D576E50F -:10468000F2EF1FB161FEC15B33685F7CFC7B47BB0F -:10469000A6F4ABF8FD9BDF2D656427597104B78044 -:1046A000795791BC9EC2EE5D0F117E82020F4DF8CC -:1046B00001B21AC2557C1CF199E9C5BC85FC26469D -:1046C0008D0A2BC2B4EFF85902992E6DC554D4E36C -:1046D000F58895343CCDF0D8BF13D0A8E73BF6D190 -:1046E000BECFE7CEC11FE4DF539863D8F7DDF29366 -:1046F000D09CC5F9AEAFB4D3C1092932A84097A761 -:10470000B34A85FD33A8A3BEEC5EEB22BBF1A12525 -:10471000655BAF447F3528EBFC3872681CDA47CD07 -:10472000474D2FDA79DB23D3BDE3E0FD431D4A1863 -:10473000CDC3A796AC7915EBB1DD2EB2839EEA9B73 -:1047400057B0228DEF36EF5EB07031BEEF70917EC4 -:104750005FB1E7BE81D220F677D5A67F6FAA65E369 -:104760007D3AFA6D6FD47A33DA31576771BB64A33F -:1047700096A4F8D3C6791A43976B6349FDE8156888 -:104780003F5CA365BC4F7E57969BDFE773B54A2815 -:10479000DF0BA399EF0558EDC6D6FC96CE3182B358 -:1047A00065867E9CEBFA7932D61F827DD5A5143DB5 -:1047B000E5097ADA5874EFD60A5CDF40E67B875663 -:1047C000B9366B1CA7D3889DCF5D854DA371DD2EB7 -:1047D0007764A01E89AB50D6312EE272B7466E4682 -:1047E0007BF46A175238DBDCF1C38645B82F614988 -:1047F00097609EA01A59457416CC62A80F1A964469 -:104800005A112F85A0FF30B45758F44B3AA728AC63 -:10481000D39817EA9E253D0917BCF75444AF42BC14 -:10482000BFB4967FE7A530E8A37B4185117E0E5784 -:10483000D8EE6668326C0417D845FE814471222791 -:104840001F59EB6A5ECAE5F8EEB5BF1D95E97B33EB -:104850001559658457AF615FB707F52E8C33D51CAA -:104860005C42F8AE71B338F1AF9BE87B57AD8BE09B -:10487000DA35E5E45710AEDFFD3E8BF6FB5A664AAB -:104880000857FE103F67B5E6C96F1A54783C9CF391 -:10489000A193EF2C7E70C2B773F63C3A8FDBCC0647 -:1048A000E723BE636765A2A3CD456BBCE971D15612 -:1048B000417FB00F245F623AA3FD56FE95ADC77CE1 -:1048C000D88D5F8C54227FBCEDE5F756EF5BAAD103 -:1048D0003A1E9AAB51BCF1217F2BD1FDA98DAEF0D0 -:1048E000210447D517E27EEE2EAE0863BCEDEFF053 -:1048F000F039CD3FD83DEA4B9588CF2FFE218B8FE5 -:104900003345B5C6F919D17BAD97E09CA1B4FF6CD6 -:1049100005DAA14BE4C9943BBD6A09C92F9790E31E -:104920002F2FC9AB473F2570C372C6E5218F5304B3 -:10493000D656F3FB0C0EB99FA85377CFA05DE2F1DA -:104940009F7A21EFC6DE30BD1ED7592FF482A966AB -:10495000FE2E63AE685F381441936C58FC2757E80D -:104960008FB1BB1DCF855EC81D16071FACB819E4FB -:10497000CF97B2841D3942DC67D79279C40F678024 -:104980001F282E5D7292E83F067202EDE637A4649E -:104990006845DA7998F59DB99F887850C42CA53C74 -:1049A000E1B7443CE8A7E2BB73EF8878D071110F00 -:1049B000FAB98807FD03C683F0FB61DECB69DFC669 -:1049C000D57DD48F719C9D350B3C068C33551F7C57 -:1049D0000981FCA239E813F9F7046FD0D24373CFF1 -:1049E0001FA74A205C6E8C4B71385F16DFA37B4596 -:1049F000C03520E07A4DC065E941941B48676CAC36 -:104A0000AA67928741B555C2F35E9417FD4192178C -:104A10003C4F3CB84632260C971330DEE8743BDD41 -:104A2000A2BF53A37C44C7CEF11FCDE2F70E5F5A5D -:104A30003B6B3F0BA6C9A3C8C2554877F9B03F28C6 -:104A40008FA24D5C8E47F1DE459A5CB5E269B023DA -:104A500061D23B37703C8D245F2E24570A1D72654E -:104A600037CA15A8EF46B9124C972BADFDB8EE200A -:104A7000CA1596D243C1C827932B3FF396D9E22497 -:104A8000967CB91AD898ECC430E853FFA7D7A76F23 -:104A90000B397121BD6AE57F044C467A7D0FE685AE -:104AA000A03F339ED13D1CC51CA47CA2DC7617C35D -:104AB0007C90ADD86534FA330B291F64C77C8F8E88 -:104AC00074F1B09408213EF7493D5EBE2F7A3FDA7B -:104AD0000BDB26F038C98E3FDEE3453BFBA5DB0B45 -:104AE00002788ED39B6BE581E88B6F85FAA94646E9 -:104AF00074B262CF0A5BDEC3CFB3F2081FB9319044 -:104B00003F808F876FE7FA4737781E089419F34084 -:104B1000DC3E110F526321A48F6D52D4437198462D -:104B200099F4546F98E7AFF4825F8EE783BD0D3B35 -:104B3000E7A07EDE70ABCC285FBCB2E71E94331DCD -:104B400013161AC897AED1656FA239BEC1277BD3A1 -:104B5000F348F13841ABE6E786A2347300E4CD5E5A -:104B6000D338DFFD5155F87DD8DF7D9E3CF8CEDC93 -:104B7000D0688C13F4362E0CE1BCBDA322A13CCA34 -:104B80004F1943F6C0C6519B1663FCA963B9C6D240 -:104B9000EDA461F305EDF6B51567541B78FE488763 -:104BA000CCFDCB5C713E0D7C5589784B5F27C2A94B -:104BB0009A3C7F04D7ABF0F5D2F74D731BC03FACE6 -:104BC000E2EB47FF55F7E9A3517EA80D3C7F64B3A4 -:104BD0005F5F8C7EA3130E6BFC6BB3259B7FA45B86 -:104BE000790BF56BF8396211CF5BE8759D3F6FA1CA -:104BF00043C843CB6F1C091F2EC73975AFD71E079B -:104C0000B4E0B952944E3846CA17F8B4F35F68DD81 -:104C10009FF77C23E511ACC9966CF72B72AD7C969F -:104C2000C635219413163C9B2F903FF269E16A6EC2 -:104C3000E4ED3FEFF5FE4F1BB73E9BEB47E0D301A2 -:104C4000BC47D931716608E5502A1E3334508EF6C0 -:104C50009CB8CF68E58FB874FE4F55E5DFB993B3C4 -:104C60008BE83BCBEA749E3F427F19F240363136E7 -:104C70001BFD1D55C46F9C7C7A21F89D792337FB61 -:104C800084DF1875CC27F2449823EF440DF1FC1211 -:104C90002B9FA44B82F50553F92023CEEBC0DB7884 -:104CA00021F7DF73F41FB6EE30BF5F69E59F0CCBD1 -:104CB00023992AEFC72D18964722F2517A728D3820 -:104CC000CF13E77925A836319E372C8F64EAF4108C -:104CD0007E53725A89E87703A3EFEFF67879BD77B0 -:104CE0000E8BE3F7CE7AB18EFC54CB28AF65587E9D -:104CF000C9D43584278D4596F1F31D7EDE6FE1C161 -:104D0000995F72417ABB401E49D0677D8F2242F382 -:104D1000F4F8C33FA923F8643A8F2FF8D2F170FA60 -:104D2000F897F8B89CEC1179783DB9F67CBCFBC4D7 -:104D3000BE548876CEFDD58B385D77D5EB1477776A -:104D400037F078E5B0EF40D4D8FD01673CEF8490B0 -:104D5000D7175ABF33AEB76D84FB660B7C3C8FEB25 -:104D6000A12587282FF6CC2AD0B380AF87319FA505 -:104D7000E6E2F3595ECFE2F92CBD46FDC24B518FFE -:104D8000453586F2B417F359E0FD868611F2594491 -:104D90003CD18A8F8E94CF927BEE3CDE9ECFD27B2D -:104DA0002BCF67E9EDE1F358E3F53654939D35D207 -:104DB000B84F8F31651FEE7FC5C59D9F4E2B89FC77 -:104DC00019E6AFF4946AFA8306D20BA7E7AE468DD4 -:104DD000E8BBCBC5FDD8D868EE3733351E5A086D11 -:104DE000B6F8138B289E2CF2327AC5FDF9BFCF326C -:104DF0006CF67167E3774368D7031DBEAC733EA1C1 -:104E000071F2D5D2F5600332B7DE62A24F3990CD90 -:104E1000E308AED0B181BA343ADD22F41DE2470690 -:104E2000FCE44AE7F015950B28BA4F7F6B047DBE72 -:104E300091CDE7B7E890A993C2FCFC8F55A01CB1B7 -:104E4000FCD761ED3CBCDD30F9E390233D98DF8673 -:104E5000154B9EDC60C9133B5D5AF28339E4CC39B3 -:104E6000793287DBE9E7E409C80FFCD499530EF5E2 -:104E70007AB9BEB0E071A3600639F29E2B6C8BD379 -:104E800038E5CE85F8E8F3963B2F65E70BFB83CB3F -:104E90009D20D206F24DB6758EC8EF3D9C99FA2042 -:104EA000C9438FCAD7ED8930FA9D00ACA33CF7E027 -:104EB000394A46B95E2D51BC419C8BE48BEF0F3EC5 -:104EC000EC0A537EDAC3C0CFE8E74D309CF6D9F93F -:104ED000CF159CE7490FAFFD1AF7CF00DFE8775DEC -:104EE000AC1CB2E4C487D97CDDE7E8CBE4705AF4AB -:104EF0009546CFF47D018B7EAD712D3A66C8A00535 -:104F0000E7A15741D7188EA638754C8A631CC4CACE -:104F100023B3C67BC3C7ED9191EE5759EDBE63F93C -:104F20005DE7E2C17A40A77CB21EBA6FCEBA38FD07 -:104F3000CD61BBD53555944FA032CA278894A03F88 -:104F400073D867F78BAD7CB06925E110CA890DC2B3 -:104F50004EB7F2C8ACBCB4C3BE5CEB9CD9969FB64E -:104F60006184FBD96F9EC3CFC57FFF04BFDBB6DA78 -:104F70006B3E8E7211F0658AEF39511E9A35EE77CD -:104F8000059E5EF7984FFA3EC3FDC917B3EC7957FB -:104F90009D3EC31117E0789DA8C7EAE93E5E94DF05 -:104FA000AB729EAB8F74FFD5796FEFDCFD5771FE4E -:104FB000DEEC89BE4CF0BFC8F3DFF470F46027FB71 -:104FC000FCD673C06BFE04C7EF14FC3D2DC8EFED9B -:104FD000BCEF89BE8DCFAF63DCAFB6EC9CC3D80EFF -:104FE000FAFB5F06A90DF4B2A996D36B5125A3EF86 -:104FF0008F4F6FE5F51D4BF9774DFB5FE7F73EB639 -:1050000045F9F74CA15F9F0C78D9319EEBC3FD5554 -:10501000BCDF7EBCDF847C5AC1EDAE3C8CDE2B282D -:10502000AEA3544EAFE9F14E80F70796CA1417DDD0 -:1050300023F822C04C8A736CABE4F3ECAA909F1067 -:10504000DFA359740BD43B67AF9C8CF74BB68B78BE -:10505000CABEC52B9FC0BCBE0F02E582EE1274EF24 -:10506000B5E7F86D141F7968499EB412D6B8EF60A1 -:10507000E6FC962ABF2AFAC5DC229E24CA8486E56D -:105080005653E4ADB632F13DF69886F1A76706793E -:10509000DE6AF7EA678ECD447D5C29539E59D7E0DE -:1050A00051EF65B8EE3A9ED753A426A474FFC5EB22 -:1050B00077713BADE6A8C7A81ADEFE99C1A3447775 -:1050C000DB01EF4A9AFF270B38BBD19F807E7B5DC7 -:1050D0003D0333A1DDDE717952CC48B51BEDE7FC11 -:1050E000D7BD4416DFA167F41D874EF39407E5662C -:1050F000279E7F40FBEE1A2B2FB587EE65ED9D3383 -:10510000790EE6896FBB81074BBBC287C84FEE990A -:10511000CDEDB2BD12B4837DD9D7A25D4FF7985AB9 -:10512000799C08CA8C71A25E4C0446BC8A733B4AC7 -:105130007D81793B1BFA06709EA23AFE7D8BA29A76 -:10514000CCFD5F08B8A9FF3E578CE29F23EDDFBF7F -:10515000FA383E3BABF8790163718A4BED167E1746 -:1051600053A346FA77425B021C3F3B5DCCC478995F -:10517000AF4E23BD2E870DB243FD603F623C6E9B58 -:10518000145B8CF921B1491A7B9C30627AC761FCAF -:105190006E425E18E96F939408E1779563E3787C3B -:1051A000FB686427DDBB3A00763485835982F4546A -:1051B00077348FEE431D8D540F527F5F85EEB634EA -:1051C0000AE6CDD38722199B74D9A6AD68D7744E51 -:1051D0009175CCDBEC94EAA3385E2CD7437164D78D -:1051E0009479B47FAE517952BA3EBAD1CFF5C2D0DC -:1051F00084C88D7E585768CAA95C8C5B6EAF7D658C -:105200001FEEDF23F77B888E1EA91DBC1BE7D97F0D -:10521000F6AAE351E24B7E5EF768EDE952B47B7685 -:10522000359DCA45FC15637C0EF46171058FA3A101 -:105230000624FB4CED6137031E8BDB3466A4E96367 -:105240002FE3E779F8E79B4C728FFE9E193CE569E6 -:10525000C1F196B0C4A5017AEEC1789625678AEBB4 -:1052600058A200E4E1FE15EFC4304FEE91890574B9 -:105270008FB248BC27C909E39588F1FADF78653D0C -:10528000B67BB4BAC04079513C30340F954471D5E7 -:10529000698AB385ACFB1F5163FFAD449F327DA784 -:1052A000B238FCCE5FE03A02BE3ED273D09EE266D8 -:1052B000CE7504269AF7F9018FDF945A5F1D174CBB -:1052C000F963F487FC782FBF975D9CF50F7395B455 -:1052D0007CDB121117D8240DCE26BBF4016E878F0C -:1052E00065719273C555B1BB79BE6D94F26D9DF336 -:1052F0006EF79FD3AF12DDA3CE6F12F74AF8EFD847 -:105300009488DFB171D27D28945FD57155AABE2FE4 -:105310007A8AE8FF69CDB82BD3F71EF609B9B049F0 -:10532000F863D6F86373F9F856FD519DD3E3D32F94 -:10533000E75D5F05EBF9ABB6B24918FFDC31821FC0 -:10534000B732C0E92F7B002C1CD003FDAFBDE6C5F2 -:105350007C96A765B60AE5547D55C293AC12788455 -:10536000F1C91783F10F84BFED41B9F4D54025C1D0 -:10537000B5622A8F1B74563D48E740219DEB1DE422 -:105380004F94EFBE504CC2B8F7F21AA61F12F19616 -:1053900018E09FEECECB2C95D7BF3D97FC1CE015B7 -:1053A0007EAF067393268BDF9F28C773A24D778B42 -:1053B000FC5919F1DD29E601BEA5790E148971EEBB -:1053C000E3F63FFA17D8BF5CCC535EF7DDAFA11E02 -:1053D0002FD2395DA4E0EBF3107CAD3223F8D4C4B6 -:1053E000ABE8876E9F546020DD1C0885DF6E82FA73 -:1053F000F2452AC5E3CB6B381C075A65FA3D207F7E -:105400009D7690EE8F99A02FD2F06588798B6A12E5 -:10541000129E6B19AD7C5DD0CE8B72D108033C50CF -:1054200037C4BACEC13F4923F88B3C83985B740ED6 -:105430000F2B713CA0DF9575BC9F3FD4B705E5D815 -:10544000F23A0E37E87782A728AC1D447D5F14E25C -:10545000E32D07FC1C925270655B70D5C9947F5593 -:1054600054A31D443F385BC0B732CCE1E97FFDD483 -:1054700080C4C73370BC6C016FB6583F25EC16086A -:10548000FD00E33DE54AD4E3BD9C5353987188CFBA -:1054900046F12CEBFDAE56C003E0C72FE661BBDD45 -:1054A000C44FB0C4D8C732FFFD10232D6E51B15B7D -:1054B000B3D5FD62FF58177F4E7E1CA9445E9785C9 -:1054C0005FB7B2CADE8FD5A4D5CBF07E19A7F7F5AA -:1054D000D7F2F38E0313B87D847EC739FE463A9F18 -:1054E000623CD615C4F71AE9BB9276FBB8C5AD0588 -:1054F000D3513E140F3C3C4F86F514DDCB64258719 -:10550000E8593A27FF60BE6FAF49D0FDD9EC81481A -:105510001ECABB92D6BCE9F8FDB7EC8128D5B3070B -:105520005A4D9E7F062E4C1EE6EBA5CD538A729AED -:10553000E7D3B156AD0FE55A6D3A9CF0BEE4E59E57 -:10554000B9D87FF3DDAF8C46FE2D70F4F7E470FF21 -:10555000A1F8656815C0F94FAFC5F6567C271B2129 -:10556000CEA3F2652C8B7D208FA12C11F97796BCF0 -:10557000E89CF0CEA4A84FD00FE5E3B144BA9DEF6C -:105580002CA1FD78D13E269DB7DD696A3752BC69F2 -:1055900020C0E34D0161AFF630633FE9F71A9EEF9B -:1055A000E1C3E7A03FFA6A8E4EA7FDEC6361A4E772 -:1055B000E2B63FB9D3E5F5CD8152710F3A4174AFF0 -:1055C0009564D1F91EF0317DDFF480DA4AE7AC7DD5 -:1055D00045FC5CF3E89C5724C467D1733C4FDBB2B5 -:1055E00097A7D72442F8BCEBD5E865C49F23D89F82 -:1055F00096BDE95CCF25F50F923C181B655E3C5FBC -:10560000F3AF56298FB5240A7055A15C00922E0481 -:10561000F86B62EB916E8C28AF1BAB45B90ACAAB35 -:10562000C1BE5D3750FE4B576ADCAD1560D7A2FD99 -:1056300034B8DB7303DA2BAD608D18682F9EF2E06F -:10564000F754BA5BA7E7239E9F8958F66542C2F1DB -:105650008B7E6A92BD58AB6B3AC66126B813A3D352 -:10566000CFE90ECC79A79ABE2736FFE2F2C946D21F -:1056700027088B9CA647FAAB8E927E79C23F9EF498 -:1056800090A5572C3D4223827CB945F0519791F06B -:105690004824AF807701CE5B508E001DFB8BB83C59 -:1056A0000739CCE59CA54FEEE67ADF929F15629C08 -:1056B0005B50DE42BFEEDA27726F40B922E4AC3FA6 -:1056C00064CCC4F3B90A215F991A9370BE0353F8EE -:1056D000F72A030E795AD1CAC7E90A31A227D04363 -:1056E00007916E0E1425E89EF881D6A352FA3D5319 -:1056F0004BDF055A930CF77F5C1D9783E3845CFDB9 -:105700008EDFE0F4E9E172F59CDE13F276AB79947A -:1057100089EFC266CCC3FA7BA1CF7B2A0E915FB022 -:10572000EDD653844F2B1E1A12F1D0EEAAB7E8FD26 -:10573000F628BF07B0CB9C3E87E08F2CD728FFB45C -:10574000E6E89C32F4379A966B68D79D0C1458E7BC -:105750005FDE85684FB6AE22FBD727F6F1A1301386 -:105760007EA7467ED67D4BBF3D80FD43E0174906B0 -:1057700036EAF3B891CEF17B0A88EFE82075F6D5CA -:1057800018F41D08E73ABE17E0DFA5F5479303E3D9 -:10579000685F65BAD2E3AB61E4772E07BF0E87DDA1 -:1057A000AD86BD13E0FDEE26595FCF52FDFF578059 -:1057B000E7A34DF4F37B0A3B179FDE8271BE9D4B3E -:1057C000C577CE1CF0DFD7D8E751681E8C09501E74 -:1057D00073C6EFED57F9B3F8F7176AFA06D09E0FC4 -:1057E0005471B85E0C181CEF831C8F3D1199F8683A -:1057F000D760B517F59DD36E7C24FBDD493CAFC562 -:10580000AE6F2E542F76C8FD09EEBEEB48DE7D53F9 -:105810002679C518977712930DFC5D8D9600A7A782 -:105820002A21AF3B5C89FD9857D0F1AC8FAD375240 -:10583000745124C6EC6C9533FE7EDAA180C2F77FEA -:10584000F8BE73FB41ECFB93020F17DA7F0CB3A099 -:105850003DDD17DF34E60E94E3ADDC7FEE4BBC4557 -:10586000794745B31792DF73E4E0A5E40F14559927 -:10587000B6DFD7CC1EC16FADC8F19C371E30923C4D -:10588000DEB7BA83FCEC7D8399EFC514E4F0BCB4B9 -:105890003E9097F87D9391E6D77338FFFD5340D043 -:1058A000DD9C77E87B19697AF665A16749DF16AB5D -:1058B0002CA6A4E5394C10F873EA4FA6C63D97D63E -:1058C000109D13FEF689F38B874C99F06ED1399EAB -:1058D0001F205E611DA6A0433ADFE861710FF24D03 -:1058E000AC89E77938E19EE0972F6A7DC11CEE878D -:1058F0009C9B4FF8EB13FD1CEE9DB5F7D33D4798ED -:105900002F84F421FDE03F4ED37DA8675DF47BB684 -:10591000339E752530A675E741FE7B8BF28B5E8248 -:10592000F39F0FF3EFAB27FCDC1EFBB5CE7FAFE898 -:10593000ABEEC1EE2F407DE85985913D1907C505B5 -:10594000F47A5AD02B7B8ED7577A79F5CE83FDCB5C -:1059500070BC55CFF13CCC3B9FBFEDC62F40FDB690 -:105960000117DD19B8F3F1F5DA18A8DF1E97FAB0C0 -:10597000FE9BE98C7EEF3396A7519CEB3781C18269 -:105980000580EF0FD679987119C649070BE6031EFB -:10599000EE883F3D13FBDDF1941446B69DF1ECE338 -:1059A000AF8C06B8EEFC8644F95F5F39926DB30B9D -:1059B0004FC352A6C1FB3507F9EF46DEC67A662211 -:1059C0003EEE7CBC977EFFD0C2E707EB2A9991F6AA -:1059D000BB61777EE369FA3DC3BBBE25D1EF2BDE09 -:1059E00025F37B44FFFCBC77D1633E5CDF7AED524C -:1059F0003FAE6BB386ED6E8BB77C17539AEE881F64 -:105A0000D466C2FB3B0E1CD456A25FE666CDA87FCF -:105A1000BE72E40A9BDC39BD4F21FF604DAE87EEBC -:105A2000D7339F199A3761F83E7FB08ED9E0BAC359 -:105A30008A13A8716D6E5A7B97CEFDDFAF1C516C37 -:105A4000F3587640EC18D70BB1BFF553FCDCDABF46 -:105A500035C2EFB6F66F8D15885787266782A71B6C -:105A6000F703E0E959A753B9735D88CADDEB0CDA97 -:105A7000A7BD884728BB04DC81A9AC1EBFCF1F305F -:105A800079DA715E93598F77CBF222BC5EB0244AEB -:105A90007EC848768C55EE75455BD087ECDCD13FEF -:105AA0004B05BB67AF16BD1B235F7AC7ABB31AA00C -:105AB000FE3739918D39246FC206F29DE59F7F3DF7 -:105AC00087CBDD4DA335C2F7DEA5931F532CFF0B0B -:105AD000E37E4B573E81F604F4DF9E437C1BA6EF2A -:105AE000748DD4BF60599DAD7FC1B25556FF3DD472 -:105AF000DF73FEFE7B975D639F7FD91D56FF4708CE -:105B00007EDFF9E12F689E6A9FBF7935F5FFAA9B7A -:105B1000EFEF50AE87F2E93BBCE1848BFC6746DFD8 -:105B2000E750F32E3D44DF4F3A17671A3451CFFA4E -:105B30009ECAAD463996A2A3E9DFC475F881BBD2EF -:105B4000E928A72ECBC657B9669EAD9E3F7B8CAD8C -:105B5000FDA84899ED7DE1A2CB1D74E9D3290F96EC -:105B6000717D6A629C13E0D4C6F0EF35D58FF1D019 -:105B7000FAEE7FD14BF5FBAFE1EBBB7F8C8FF89852 -:105B80007417ECFBFD5AF4CA74FB18D62561C8EBF8 -:105B9000193D3A90539BFEDC90F17996C27FC72E57 -:105BA000CBCDF5E5E6D2C98FC5D2F0B9A518E8018D -:105BB000EA6FE768B638CFE6E295A196B479361574 -:105BC0006B8B0E55F1E7B7A01DAF47FE0EE7FBAAA2 -:105BD000367429DAAFCE79DC6575B6793C25AB68C9 -:105BE0009EA4631E77C92AC73C9E4587C47331CFE4 -:105BF00029A49391E6D95C768D7D3D2577D03CBF75 -:105C0000C6796AD3D6537287639E2CBE1E782EE661 -:105C1000F9CD79D7533ED5BE9EB1AB699E7F77CC87 -:105C2000E31EBBDA318F8FE6C1E7380F2BE27E949B -:105C3000E61E5A49FBFF032FC33890E68EFE355D02 -:105C400052F97B2FC585A19589EDFE0FF9438DD2C1 -:105C500000800000000000001F8B08000000000012 -:105C6000000BE57D09785445B670DDBEF7F69274F9 -:105C7000773AFB420837801034C40E840CE0320DB2 -:105C8000411E3A80C1155CA0C3923DE988380F4798 -:105C90009D34041111B551D4A0C034080EF840034E -:105CA000132040C006D4C119D438CF7199059B4543 -:105CB0008210930651F1CDE25FE754DDF4BD9D0EF5 -:105CC00030CBFFBF79EF8FDF4C51B7F6B3D539A793 -:105CD0004E55939C0442461172308EA62308F92635 -:105CE000C67DB5C34AC8F7F0F74342FFBC8424F32E -:105CF0003485903984FFF9170BA490905A33CBCE9A -:105D0000DE3C256B01A42D45692505F41F2B6CCEC7 -:105D10002B14423A5B8A8CB372C3FDA9E91C9F7CA9 -:105D20003298C3DA7E4FC2E378C7929C3A3A7E59E2 -:105D30009C03E7A3E64FD6D3BC899063F504D376E2 -:105D400099CC28A6DF4FD4D3090CD6CE7701B63B29 -:105D500029D17F26D17495E0F70A745DCB3F90C9B5 -:105D6000001CE6C31CBA8E3BF832E6F862093187A4 -:105D7000E7E1311117B40BED32F9D709F0D5D5C7EA -:105D8000904693C64442D4F9F627E48FFB26BD2DF6 -:105D9000D831DBC7309290BB966C7D0BAA7D2494E2 -:105DA000F49D4BD73BB579B9DC87E63BE5E074A7BA -:105DB00055D3CF54F918ACDB4CFF837EA6B9695E8E -:105DC00033FEDDE5FAFCBD440AE7B309B9CAD19F49 -:105DD000E3838FABF865C0D71D744DE91485F74296 -:105DE0003A0C8A1D88AFE90ED6569D8FE72199049B -:105DF000603E523099E4424932D673433DA5E7FCF8 -:105E0000A6CB665731C5E7F407458463E47C83FB82 -:105E1000625D863C9A367E2593FE979EFF8CF9FA4A -:105E200072E265E3A97055E9E0CEA9639E3DA1A1A8 -:105E30008F69EE1B9F3DA183D3145DFEDEBA69BA64 -:105E4000FA33E697E8CA4BBC15BAF2594BEED3E5E4 -:105E5000E7F81ED4D52F6B5CA02BAFF03FAE2BAF75 -:105E6000DAB85C97AF695AA9ABEF6959AB2B37EC3D -:105E70001B7233A1706CF8AD484C148E5F5B4F3EC3 -:105E8000754D12A49213E07EAA3E0DE9FA74BD820C -:105E9000692DD0DE28E09FE16637C5932726544A56 -:105EA000E20979C477ED9225D7D2BC91968FA6D41A -:105EB000EE1BBBC49B49C8128782742F361A4980D7 -:105EC00092AA4012BAE93A246ACA8397286F944882 -:105ED0006078CF723118FD7B97101A9441D7E1FD9D -:105EE000D44436083DF93CCC97A40F49EBBDBCC364 -:105EF00040CA9B34726783C380F349768CDDE0A08F -:105F0000F4506D64FC5EBD2D7D2CB1433E30A8CEB7 -:105F10007A91F19AE86452A11FC62F15FE3E61FEE8 -:105F200045FC0DD0F1FDE038F77A071DAF63BF38AF -:105F300015E6410207B36E1D0AE3BB36C077D242B5 -:105F40003B49A7FC5DEF7AF6C415847C523F01D330 -:105F5000DFD5173F7B4226E40FF553317FA4DE8D5A -:105F600069B0BE1CD363F575587EA27E3EE64FD65F -:105F70007B313D55BF04D3D3F53E2CEFA86FC47CD5 -:105F800067BD1F53950FA83C9A510C7C5A5C6C005E -:105F90003E9D6B21FC8FE5CFF13588F4DF6DC8D7CE -:105FA000CE34E0EB73D66F0665507A3BF70925A631 -:105FB000ECDEE1144977BDE3CF6500FC95FA29F1E9 -:105FC00024F62CB7C430FC580C6402A1F2E7F12B84 -:105FD0008C44A2E3C7BC71D53A311BBF4B403A7425 -:105FE000E3704EB145E97F20417C5D0A4F6AFD9325 -:105FF0002FFEA970662EE0A73FD249CC41B18EE1B9 -:10600000ED6527E0ED52F093387F45C25178E38F7C -:1060100059415AFFCB64159E6D5984A6B73A8A4FF1 -:10602000011D9C6B36E1BACEB5C6FA09F4E14842CF -:10603000BAE81D6E6C1E551B2D3EAD7CA8698AF713 -:10604000E9E545BA4F2B2FCE1D7AD90E7C3F374D4F -:10605000F49D180EF4E1E2F4C1E84EEDBFA629DB91 -:1060600067D5F5A3CF9FF309139A50CE2B71B70DC7 -:10607000ED7D9E73D38C38CEE98D03E260DCD3F5E1 -:10608000661F8CD351EFF0B171D37C5ABAAC9E1F0E -:10609000EB3B91189E5F6FFDFEB3E7474833396EC7 -:1060A0002608FAEF07F45EBF577C48E78DC5401F0E -:1060B000ADF237B0EFC4E4A8FB8E8479B55F4F939F -:1060C000E8355D0DDF37EBC6A3ED94932A9EFA5FAA -:1060D0000CEF1239A9AE93CAC9A15476039D52623E -:1060E000463CBB698F71B4BF2EC9BA44A0E398E2A5 -:1060F000152CF7C040949E6ACC41A35B4170B781D8 -:106100009E3573A4CAF7CA9DBFA724F7C5AF65B271 -:1061100014CAFF4C7BA7E5322F9D4D8AED848E3744 -:10612000B3B96A22C8C92F76FC88EB29BE4258F75A -:1061300097C43001F8E44BF21BFB708D5E3639DEFC -:10614000C8E6B784EDCF5EFA1FAC8FEA69BAFDBA34 -:10615000AC519F2F25B7A4003F94AE90899FCEBD30 -:1061600002F67B75DD94EFAF8F677A5C19A95B0C43 -:106170007ACA52994C057CCF7410A90F9513353B00 -:10618000571796D0FCEDF106A4ABD354BF53A81C0F -:10619000AA48607A4C6592DFE8A2E5C79B87DF7169 -:1061A0000D81F6FEC520D7BC36E2DC407AC27DD632 -:1061B00012FDFC2E35FFC8F912B210E7ABCE43ED4D -:1061C000579D87B85170F9A3E8B3B3E285B09E4CF0 -:1061D000D3FBE3F5FAEB7CC86BF4DB4722F20B232D -:1061E000F22A9DC89C4E4CF1EEF9F1C94017A1F17D -:1061F000A8A7114A1FB9E17AC670BD472E56CF0431 -:10620000F544ACB7F062F52CE1FE1E8B56AF66E7A5 -:10621000961D5E4A4F95AF3F6727549E7F21F952E6 -:106220009CF47BF58647ED00A75392D70EF8FEC28B -:106230002F4E8806AF7DDDF0725905B02390B4294A -:10624000DC5F7D6232E849DF6C901D22ADE2D968E7 -:106250000A9828FDD636574C2479983FCAF28F9D6C -:106260001521DFA2C767E5CF9F4B516C8807A66F4A -:106270009300EA1DB5EB3F1F0F72DC434248879144 -:10628000ED60FC0B09C8F725C6B89EE5749EA827EB -:106290007B389F799A9F382BDA21BDB11DF8CC133A -:1062A0004147E5DDFB4BD0584CE7F37ABC2DE9E4E0 -:1062B0005534FB03F20390072A5C889FE9150D9B78 -:1062C0005EC83B4AE7D5B1FED77621572B47183D2C -:1062D0009E6B9AF5B3DD4AEFF2A693DB45E1767E3D -:1062E0006CA7B4303D88B4B2B45A0ED841EFAC5E5E -:1062F0002B3B29A592EA2D2FBFF222D86B9F9AD073 -:106300005EABDAF2D647A369BE6AAB9C34912DC767 -:106310002AA484F1E3A1FF9B3F2C8C8FCA5FBC654C -:106320005486B2EF0F2784F152B575BF910CED0979 -:10633000C7A2A6FDC6A0350A7E9A8E8E07BDA561AE -:10634000D3B746B0BFBED82790D4EC9EEDCBD7BE16 -:1063500085FB22C009F1C9F1D58DBF1E780B4CDE3B -:106360005D80F51C202F2F85371F97D3353B6D247B -:106370009ECEA3FC7726FF44C0E76BF7DB613DEDC3 -:10638000521DA3F3D58FA6B8E8F8E5B237C5812929 -:10639000FB5EBEE601A4BF32A12EC581FCE44A37F4 -:1063A000A0ECF6A6C33AE7ACBA1DD7594ADC488739 -:1063B000E5ABC5623F4DBF96C884AD51F8A43081AE -:1063C000F149FB3A8A5CBACE76D0FB41DFFE8DE81C -:1063D000DF80F6E97D04E4FF037CCD74A7C4FCD71D -:1063E00066862F6B8241B517CD3AFA5DFF581BE0E8 -:1063F000E9745F572ACC93C2C1CBE1267C4FFB15D1 -:106400003FB82195E1892852216F47F78322F80E82 -:10641000F5DB6497254FD78ECB4F36FE3C3E3E9D35 -:10642000770CEC6FED2954BF8FB2BE99B03EDC17EC -:10643000E93EA7A1330DBF33FE5FFF38E37795FF39 -:10644000FD532640F9F90F191F413BD84FE8BC0214 -:10645000A958BEFF3601E5838904A2F1F97A99F3C0 -:10646000B9BEDC43F915FC042A9DD0F94B429C9639 -:106470005EE838098807B4574A57D0F65AFD06C671 -:10648000C57AC6F077CDBE52C6E5427E029507B109 -:1064900061794056255F961E592D132FA89CD59FD4 -:1064A0009AD01EAFDE2217C3FACF6C3EF8D15D94AE -:1064B000CECF34A97CAB97AB917C5BBE6D8300746F -:1064C0001AC9B767CAE92E1E8D6FE9F7A87C5B1E53 -:1064D000FC7F2A5755F84D4BD0CB532A1FFB810A1E -:1064E000D11B1C23E5E3D7A06F25F7948FF4EF436E -:1064F00052D8930E55FA53E98E6A70FD40AE77D3A9 -:10650000A74A7FDDF4A9D25FE47AF5F08B2CEF0F78 -:106510003612A593E25D54A3A3F8AC6E15FC26E4F5 -:1065200073EFDB7D0A104E2EDCDE88EFED3E49DA9C -:10653000BC3F22DF1451DF15912F8EA8EF8EC8D7F4 -:10654000E9EA57B71C3412C47F4057CF34FF257295 -:106550003C8A3DA8EE3F9EE6B3462FD04566C8086C -:10656000724F5E485537F0AFED15D1BFD6A584EC1C -:1065700009F4FBA31666A77539783E9EE543C9C6A4 -:10658000C520F7D4EF210B41FBBCAB38648FD7D8C3 -:10659000FF475B45BB42CB837E3241EB4708CFA729 -:1065A00001F11D24BD9533BF61578C3D0FC78BC9C9 -:1065B000F203FDDD205AB3E683BDE7139D947CC84A -:1065C000EC0577DA09A5B3AED601374FA5DFE7BCF6 -:1065D0002382BA4DD1E392D229DDCCE2747C8A7851 -:1065E0009FBF96AE6F562BD3C3672F8B4EF795BCCC -:1065F0007EA9759E11E42BD5A38F69FDA295641920 -:10660000D25DF9AA88EFAD3F42FEA88CE00F37B704 -:106610001FF6AAFC914FF251BE10C2EC5F2E976F8D -:1066200010736F9E4AF1D07548242605EC59912CC1 -:1066300086756E16FCE02F20DE64E4B35A124279B0 -:10664000A8C2A903F86870EF72AA63FB1F0B1F02B0 -:106650007AD9F1FBBC9768DAB1E3D3417B20BFF371 -:10666000E3ACDF939EF58BF67D371DF6B3AE7D264A -:10667000F48B75EDFB65D64390DF6D42BF58D74272 -:10668000930BF8C0BBCFE6BF02CAFB32FBA161EFA0 -:10669000B77941DC5F1721DE4E2530FBE55CEB9FCF -:1066A0008E084990D25581FEB02F16F9C8B3DB820F -:1066B000F67AD7DE6F0BDDD67FDE7A6A8DC48DF475 -:1066C000682353B701FDC633FFB167CFA89717D032 -:1066D000F16B9AF71B67D1F2A237FE9207F2B36B08 -:1066E0001BD38B3AE5E01AE224E4AB84B2C765F031 -:1066F000F301336510F274E2C61BBDB9D1E0C2E00C -:10670000D045E100EBA2702907B9DF1B3C62128D76 -:1067100048EFFF7AF0383B9DC9B51F10F00B85E1BB -:1067200022B8D8779BDF2CE0FAD9F77DDFE681DC51 -:1067300039D3B400F5954BAD7B48E2BF2A1DFCBDB3 -:10674000EB160297B3EE09FFB2F866F4FF5E8282A1 -:10675000F38CE4839E74BEF3C7987FCDE6C4F95EE4 -:1067600026FF97FF6FC3FB368A77FBA5F1FED8FFA4 -:1067700058BCBFC3F16E7398409EEDFD0BFA59D51E -:10678000F55F6ADDAFFC0F5DB7AAC7DF64A83B3CCD -:1067900085D63F4C022B8AE93CDFCCBCE1C329B44F -:1067A000F497BDE8271F25323BF097A07C80FD972A -:1067B00026F837A05DC1ECA622C2F6F5A29C32D421 -:1067C000378A729E40BD81487587F3293C6ECA9A0C -:1067D000E35C8AD5877DE2A6F97F4BBFCE89FEC3F5 -:1067E00008FBB1E8CA1B0F81FD7270019D1F1DE7F8 -:1067F000605FD1413527322E530E98F2303D0AE9C1 -:10680000DBF609586F9C556F3F4D04BB47630FDEA5 -:10681000A8E8CBC7F3FE2790034912ED7F825326E9 -:106820007EA8477C8BB4E7CEE323FAD946754CADFE -:106830007FED6F859F3989D999BF24730FE703FCDA -:106840003265F41F5E127E006F8457BE7F29E856C2 -:106850009213E17753460D8727B3AB25DE5EB22E48 -:106860006E03BE9508B58B995E86F6B46A175F0A0B -:10687000CE84DBDB121F5A85BB9449ED6D7DBF08CA -:1068800017151F7F2B1E54FCFDBDF8F81DE0634457 -:10689000181F99E71D12F06711B707C69D6F1331D6 -:1068A0009FE994F0FC85DB0363ACF112D803D74970 -:1068B0001F88C09765E65D95708E60760A48D7831D -:1068C0003B0C68EF980B04847B4EA384F90F0C8E6D -:1068D00011A0684FBE66E7990709F8935D46A67850 -:1068E00017337FFE9FBFFFFEDA42F0ABB0BF32FA34 -:1068F000BF49D41E9BBD8A0462E8FAE648C40B2156 -:106900000E737C0239A6F307EBF3F0777D4AB89F4C -:106910004BD5EF4D8EFCB3D39D546E1DBB82905D65 -:10692000903267BFA4B59B7FD0CAE0E5394CFCFD2F -:10693000512EB8C462CD39DBBF2731F9B1F30FDB7B -:106940008683FF6C4C576E1C93A70506A04B0FB7B0 -:106950000BCE11250EE215CEB50E88C373C443A22B -:10696000CD1DC56FB389DBD3FF518F4E65D2B59E68 -:10697000F844B09B4808FDB7DEF5E6A8E7C13393BD -:106980000C9C6E38DEE89F5808E7166CFC39B46939 -:106990009C166F1D13BF90F27AE201FE8E69CE57EE -:1069A000FE51F882FD0EF0DD64098E2F8E223FE647 -:1069B00071F84D3EF01DFA3BAF6C5D6B00FABD7295 -:1069C000BD41773E599DC4EDAE616418CC6BF201B8 -:1069D0008BAD00F07248745AE8FA3CAD678DEE2832 -:1069E000E75C91F084FEC18FFE6A123B17D8233713 -:1069F000CD02B8EEF9D24CBC14BFBB8CBEAA68F372 -:106A00004C4A61726E0E69BA3F2FFB5F0FBE63BACC -:106A1000AC81B16067AE27DCAF11497F04E9F8DCD7 -:106A200046E287FD14EC52900BE73613DCCF294881 -:106A30009E04BB9AF2FB0FB57E9AC12D5BFF03F457 -:106A400080DA56C161A0E5B552D008FE584F4BBC64 -:106A500008FB6EBE425C783E2C3986DEA6E18B5781 -:106A6000932484EFC1D17BEE8671BFEA3012D04708 -:106A70005C6F86ECB06F7FD53A1CF9A0B775FDA2AC -:106A80009E548E93A11F260F23E92177738C2E7FAE -:106A90008DE8CE00FE9A6C0ACE7346C1DFC4644610 -:106AA00067972DDFFCFF9FC9B70F55F9E6168B35A9 -:106AB0007C9494CCE85E23DF52A3C9B7B982920AD2 -:106AC000709FBB77402AE075EE3B727234F9B6A531 -:106AD0009E9DFFBD4EF911D2AE662ADFAED6C8B775 -:106AE000662ADFB27BB6FBEBE5CA37FF7F0FFF6D8F -:106AF00001F91665BDF11C7EAA7CCB6B3D8AF22D97 -:106B0000AFD940148DDFC99C7C29F92624DF06FA11 -:106B1000F021D9191B857EB670FDFB751EB707E302 -:106B2000809CFBB764765E7AB9722E3D85F1C925EB -:106B3000E5DC7F139C553937773B9573D9D1E890C5 -:106B4000C9B9B9BBA89C13801E999C9BBB9730FF09 -:106B50005B847CCBE921DF08D6AF0DB0F69E96ECC6 -:106B600017EEA1FD0D73C94E33AD3F2C2CEF4668D7 -:106B7000E5DDBF254B08E71EF2EED0E5C9BBED5CB5 -:106B8000DE5139D61FE46B247D385B6374F93DA375 -:106B9000DA37FF02F8E55D11CF173F30B073A0F789 -:106BA00046B517007DADE4F3F170FAEBACF762FF88 -:106BB000456FB2F5D56C66FEEFDA66A61FD6AE1746 -:106BC000FD0AFDE7F8D1DF1961FE157B05924AF356 -:106BD000534CBEE7AD20837F2E13762E4626E66B00 -:106BE000E861F6C82AF4E33758ECEB08E5E3D9127C -:106BF0003183BFBECA3AFE0BF0D3578D64FEFD2A27 -:106C0000FE9DF0B801350EB2B4E5BEB7FB909EF123 -:106C100003934D0C8F935F16FC6BB3217E495F5E2F -:106C20001511FFF8145FE71431887021EF8B51E3E1 -:106C3000189E8A84C7210E0FBA7E1D3CFC425478F0 -:106C4000508C4ECC4F09AFBFE2DDE062F0E757ACAD -:106C500014F0DC578547E43A55F8A8FEE92ADEDE51 -:106C6000D37A1F9EFB47AE5F855F8F75ABF08C5864 -:106C7000BF2F999F7BE593E1104F43E901E587F72B -:106C800057140E749CE23157A46AE5F1F31C0EC34D -:106C90007D638AD209C08DD401FD9436DEF7763A41 -:106CA0005DFF884F9461B04D5E33DAE48673D44D56 -:106CB0009610CA3795BEDA557AE7FDECC9A81B8B4A -:106CC000F67A8BE000FDC213B0201C3D94CE2CB4AC -:106CD000CAC195DF8CE770749890AFF8BE43E16E3F -:106CE000A0F5C7ABFB10853BF0CDF0D6B3789E5B2B -:106CF0004042785E52DB283803741DB52D0C5EAA25 -:106D0000BCA57F562D3EA2D0A3148D1E0938890B39 -:106D1000C3FB6015AF37D9E4FB08CE6126537A5F19 -:106D20004BC278CCA1FF011E23F1A4C2F352F4F9A7 -:106D300039D73FB6001CAD00AF10D3A302745FB0CB -:106D400085CB3D925707C7A2172F30FADA2B287050 -:106D50009ED00D27A0575A3EA295D12BC04D01B809 -:106D6000B79688902FA5F04DCCEEB94E38BFD4F22F -:106D70006FC5DEA3ACFFD5829344A15F75DDBDD1A5 -:106D8000EF3F4AB7ED1174FB9E25747838D0ED5E65 -:106D900081F9115AE375E78EA61476EEBEC942E971 -:106DA0001BCEBBDE919DEB949E7C7E81C313F47F52 -:106DB00045E3971A020B80B3C08D668C3FC379F40C -:106DC00067FAA556BE6EB190E4DB0A7AEFDFC8ED34 -:106DD00081DEF41B353F14C603B9D742C7CB098FF8 -:106DE0001729DF557BFF52EB4A4CF9C7D6D51DBF9B -:106DF00049DAF0FCC914EF7E2809FD3F2C3EE90E6C -:106E00001E9F4467807A96A65E5AF288DEEB913424 -:106E100033EEC3F7F3B8F81B442BF1D2757CE5923F -:106E2000914EE92EFDDB6B412E8FA5FB084DBE3A3E -:106E30003CE2E37BB05CC4F3A89BDF4DAC8173BA4A -:106E40009B4118D1EF37E70BB8FF7E009D8D023DC7 -:106E5000D64C5C264EC2B47CE40FE2D16F94BFDE08 -:106E600057A4507E1AB6D1DF00A9B32894F41EC0EF -:106E70006F8C48007E6DAEC422D8BFEEFF9CE48BC1 -:106E80000AEEB3D8CFB0432419EA8D7625A3393062 -:106E9000AA794511F847A71CB45A81CE73561988B0 -:106EA0005B43BFA389BF01FC36A34EB86E05FE2B22 -:106EB000A7FA02F89DCB5BD736D821BF4A702AB417 -:106EC0007F8FD73DDE4EE7B5A5F1ECF8AB800F69BB -:106ED0003DE8C6B38AD5F3AC179C102A5BDABA1C1E -:106EE000E3714AD70BC401F5FD0231B37EFD66DACA -:106EF000EF9655B43DCD97417BE877FDD90F6F05EF -:106F00003E3F2CB2F69BD9B975296DA700BDAEBF27 -:106F10000FFBAB58259034DA5FF96626FFCB0FCB19 -:106F20004E286FDEBF12F7B18974BCF46C90F78104 -:106F3000719027C30507FA3B33EF42BEEEE27C4D6A -:106F40003AA632B921F03CB71B54BDE9400A8B0F79 -:106F50002E752E3026D27EDE1B999C0D61029E96E8 -:106F6000B3781E7D82C2D94DE1FC018FE73838F23B -:106F7000B831A8D97F3E4B19807438BB650CC6392F -:106F8000CC21C518E7307914D3D7DEBFCEE217E89D -:106F9000BCDE974399F0FDE07526D47F3BB7C878F7 -:106FA0005EDCD93788FEE9F6553281788D86552228 -:106FB000CAC5F6CD6C1F1757DF3E3E1DE0B74170C6 -:106FC00082DC3CB8AAC808FB5ABB5FC0F645AB1FC1 -:106FD0004861760C9387AADD56EAA8D0ED1F91F29E -:106FE0004D957F351C0E9172AE46DD6722E45C0D37 -:106FF0009C37DB21D57FF7102B937FA0F703DE03AF -:10700000DF21FDD61E9609E8FDC2F18EF118B70505 -:10701000FB262D1FD52AB8E09CBFFC13931FF55506 -:107020007FC98C9F80FCFED4440405E2E029DCA9E2 -:107030005C18690AFDE159FAFD8B0FCC102143E978 -:10704000A404E1ACC68B166C60F12D051FAC482979 -:1070500005388C4B44395BD62812B7465E7C21B884 -:107060006EBD8BC963C7068D3C2A30FA4A61FF7238 -:10707000A43239A86C902166846CE7F289EAD32E99 -:10708000D01B2A762D4F31D27A8B793C48C5DEE56C -:107090002954349006D8B768FD0A23EBBF629FE0FD -:1070A00058ABE95F6DAFF6A7F663DCA5EF67C05E8E -:1070B0009EBFCC7ED479A8E3F7A68F8FFCCF0B2B95 -:1070C00004DADFC8F7450C521E797CE200ED7987BF -:1070D0009AAAFED7C20F0DC4A581DBC83FC4109782 -:1070E000862E9A4750FEA6789BD4C2F4A1E611479B -:1070F0008D35059877003FD7723F6DED38766ED5A8 -:107100009CFFC122E0EF890502D201F1BA8D8949C5 -:10711000A8072970BE5056C0DA97D1F6C077CD2B9C -:10712000191F5279A080BCA85DB57C3CD65F2F2882 -:10713000D07FF3DA12DCE7CB478A04CBD71F45BDFB -:10714000A3BCE56812F02BE5CF15B0EFD65E6B72ED -:10715000007FA87CA7F2F1FB328B0F2166C750B8E5 -:10716000075096A244E55FF1306176EA6619F9CEE0 -:107170003392F1E5FB5B44E4E783D7DD391EF8B0D9 -:107180007383D00B1F533E2D08F3A9B89AC5EB9417 -:107190006D62F6CAC1554C3EB437333DB168B53C5B -:1071A00009F265EFCA84F9BD983E78B9FCDC434F1B -:1071B000D9189D9F7BE3DFC972D347F7D3F9DDFC74 -:1071C0001A9DBF128657D1F50FDAD14F7FFD345C7F -:1071D000AF2A874A2516CF34DBB780C5FB4A2CEE91 -:1071E000ED6F9E57C43C1E4BB185E58808F41ECF59 -:1071F000E2A4D7CB48EF91FCF88FF2D13F8BAFB729 -:10720000733A52E723EE65ED21AE2C40E1F8CBCD89 -:107210002F635CEB97AF1E9D0C78AEDA43E997AE17 -:10722000B773B38D04406E497EDC6F2A9B458C1F7B -:107230002752A0F0569B963F597C52D5EB36A49B23 -:10724000CA6D2CEEB472C7F13C8C175918C2B82B1A -:10725000EFAB5CDFF406F380BE2B25162715C9EFD4 -:10726000635299FED9B12B762AAC43D8B81FCF5BB5 -:107270002B9BEE9481FEBAE547AAACD6C3734C2F84 -:10728000A55F386787F94D19AA9DDF02C453C72649 -:10729000C6FF952DB2DF02F3DBB816FDD99E8D67D0 -:1072A000313EBEE8F52DE847F0B488FAB8C88D2223 -:1072B0009E63D114CFAB22E3136B9B6BF0DCADB6B6 -:1072C00089C7FF45C4C555BDBE77879782A6EA1713 -:1072D0003FB7833C38DDB6C10EF0A4FD615CE1F53B -:1072E000E7255D7C54EFF1C02E7DBC61D3E33CDE2D -:1072F00070523BC9EB196F781AFE01FB4D6A44BC12 -:10730000E6C6441EDF1D282C8EE2CFEFBEF7B3E5A4 -:10731000EB351027DFB1EDCC1A987FF55FBF5A032C -:10732000F14D649F05F729CFABBFC5B862B5DD82CB -:1073300054466F9D9B7E8E71D99D9F9AD0DEE9DC6D -:10734000DB9E05F16D9D5BBF4B01FFDCBCBD37A033 -:10735000FF72DEF6A2541245DEAB29D0A7FF32E25F -:10736000C223F171B0F920C6617DF98909E55B7727 -:10737000FC68530D8BCB5578DCE8E6E871F86A9C25 -:10738000636DF3AD375F07F2BA99E977DD718F97D7 -:107390008A17FD90E2F5EACBC0DF661E17DC3429C0 -:1073A0006ABCE897F00F8AA79FA5EAE345BF6E9EE7 -:1073B000F3B317A1AC39B1D778D1C065C04D8DF307 -:1073C000AF4E75BD9A0A7CB42DD69BC6F0E69F28B9 -:1073D000801EF87516DC8F382587300E24B4D7E46C -:1073E00080B8C7CABD1F23BF746EFF00FDAD84C740 -:1073F000D97792EE3F160F2DF075AEB7B138530E18 -:107400007F884355ECF89DC79B323A56E3507B8BFF -:107410003F0DA6F2FBC3FCDE410DB59B589C7A38AC -:107420002E551809F83AAA8BEB55D71DD99F83CB57 -:10743000D1705C75F4385F358EB027BED8BEA2C659 -:107440004D77AEE5F1D6F47BE630889363FBB9C7A0 -:107450002F7C1C0DBF6A5CF5EF23F0ABAEAF37BEDF -:1074600050F9F352F3FE7BE1F26E2AF367ABF0E9D9 -:10747000F8737439FD0DE7776AB77E9DAAB16F671F -:1074800070BB55859B3ADFC54D4CAFE8D8C8EC873B -:1074900048FEA6EB71458BB397D298FE5BDBB23FFB -:1074A0000FE450C7815D9CEE185DD76E3ECAE27452 -:1074B000A9DCF66BE536617EE4C8FEECBC3F4F6BA1 -:1074C000F4FE3C9BCF46EDEFB4E4BA13E67FBA8DF1 -:1074D000E951A79BC409FE28FD5FE0FB52F7BA6D96 -:1074E000468C9712ED31A84FCDB38DFC242E095256 -:1074F00023C6FD342CE071428F38D300CE0DB69BED -:1075000008CCE751808FC6FF203BDC04F43839AD4E -:10751000B84054C2F355CB8D4906E2D7E25F0A6406 -:10752000827C3F92DF2E437F9F45F84D3E93C8E219 -:10753000543AAFCFBC827381D2BBDEADE6DD0F8B98 -:107540003A3F47AD297404F477F28605FDD6E23E52 -:107550008B17FD666B2CB8CE83DBBF7D05E0D5F9BC -:10756000331361E7089430A85C28E3FE8BF6EDDF67 -:10757000AEF913E899D0988E5FB686D607FD7A7378 -:107580002CDA035DDBE2F2509F7CE3A1C92037CA0D -:10759000600F033DEFF5547F03EDEF6432CB9FDCCA -:1075A000D217EF13546DB361BCE1C1ED3B6B41FEEB -:1075B00077BE1E0BC7D1E44B39F857C87BF6C49190 -:1075C000B50AEA818A76BFAD2092A2D5F3AA20AF90 -:1075D0008B7F2168A7A33F8ED273554B1CDE1FD132 -:1075E000D4E3FCECCD60F7650219C077549FD48DCD -:1075F000A396DF96D69FDFEF0DFD98BDAFC0EA7B67 -:107600008CA15296F76530BE6DC3FA252ABDF2F201 -:107610009EFDB2FA33D2FAEBEAA9ED6B4DA42E1A15 -:107620001F54A709FC7EEF5F06477BCF22CAFCF1FF -:10763000FB0302F11A400FD86AC138AE6A636010CA -:10764000C4B7EF30B2F3916A7B6010C4B7EFE1F2D8 -:10765000AF3A86E6E9F70C3E0FA80F79620EBE0638 -:10766000F8AED969214BC17E7FC3E6023CD7ECF866 -:10767000F6E44B0510CF168B7EAB9A37FE1DF15FFB -:10768000630A4C07FA0F6D359175B47EC7D677B291 -:10769000408FE8900359091739F7A96932E9CEB14B -:1076A000D5759CAEF70F84FBEBEABDC5CA5EE4C599 -:1076B000DE34A68F2E4F733D9D867C6D75A0BC86F3 -:1076C000FE44E8A76580F65E73A5125D8EAD4A9311 -:1076D00075F768C5F03DC555D0EF9724B83883A23B -:1076E000A44608E1F979E5C6B343C11EFEECA757ED -:1076F000E1B9D667C6D05090DB9F6585866AE5F113 -:10770000A97AB322C9E897C0B46BEDD9D20C02F1C3 -:107710008396A9D1E4D396B4589C47E5C3B151EF01 -:1077200083EEE6F4B61A6830998D0B7E0875DCCFCF -:107730008C7E23CC23375DC1F2CA4CBF11BE576D7E -:10774000DC3540F7EE84E4C37A94BF101E156485DF -:10775000B1C0DA53AE54CCB72A12DE8F96FEAB9B83 -:10776000DEC4309ED0C909716A1C877467423FA885 -:107770007A1F40928BCD002F2329764822A0DA87EA -:107780007C1A439A30B5527584ED437504E28A4EF3 -:10779000F1F35B93A43C0DF2C3744844797E29B89D -:1077A000FD32CD8EF3364975C4897AC74407E8D5D2 -:1077B00082D74DBEA7F4D050BF71C00976FEEF82CC -:1077C00038383B61F3B33BDEFE0EF4034A6768676B -:1077D0007BAF27FE063A9E6464793296F8A39DC774 -:1077E00077703C10EF7E943F5612FE0BD17C2C4AF2 -:1077F000283A6EDC5F47829D6B759000E84DB1566C -:107800001288A5A935573AADE55F3B61F9FE949C16 -:1078100041AE39AED59747D235714AE7BBE5A2886C -:10782000EDCF47B43F7FB1F62A3C3CE601D9ECFEF0 -:107830003B834B0C5F8377ACF34210E09167773664 -:10784000001E8DA1230F013CF2ACCC4E4C6A245A91 -:107850003B6E403A93578B04B65FD2BF62ABA63FF4 -:10786000E230A3FFF4710EF7EEFAAA5FA5477D8B15 -:107870000470ED51DFD25BFD98E8F56DBDCD273684 -:10788000FA7CE27BE9DF1BBD7EED1B1FBF1750E0DA -:1078900023931B1231A8F7A007A483BD157724A555 -:1078A0008451053B2788C05B0CD01FA58798819A1F -:1078B000EFF07FB91AFCF58F827F1240BA2BE1F30B -:1078C000A1796B3A9DDF5D7CBAE3D6B373CC7BE6DE -:1078D000313FD25D0FB3FB42477FCAEEEDDFD3C825 -:1078E000ECED7BE6B3733352CEEE0139E87F30DE48 -:1078F000BDD009C5F7BD3EC11FC886777022F4D739 -:10790000EEF7761E90A07E49843F46A527F5DED28D -:107910002CAE5F6773FA9C434236E0FBC87BF4CD24 -:10792000692C2E8D9A632E58DFDD7C7DEA3EE05D6A -:107930004E72E05D00D110E384F31191DF5B257698 -:1079400023BBB77A5B824EFE9CCB51E260BF236FB4 -:10795000F2EFFC3DA2B9372AA9DA7B5ED285587CCA -:107960007FA44176A6815C942FFC8828942F8C17E5 -:10797000061045730F8DEA77C8ECB283A01F4772DB -:10798000149332D00BE3399D25DDD4AD87BD4FE193 -:107990003277B982F760EF4C67FBCBD28CE239408B -:1079A00017A27DA4D36DED8957EF76B6BE06585F5A -:1079B00076CF7937189D4ED4436FA21A04FA7B9C78 -:1079C00066988F68523E56803F7F2D13B0FF7BC272 -:1079D00081E1F35C52821FE25F66DB971E01BA5DB4 -:1079E00056EFC073B425F539982EAD4F433D7471F1 -:1079F000BD1353152E66A7CF2552389B07B2FECC78 -:107A00000E37D333E83E04F11792A32E0079736644 -:107A10001D01FDD7D20D1F1FC2C7D89D7763DE049D -:107A2000799ACA8D1311BEB43D29033F6A867B192A -:107A3000C0C7A25C49140D5D98D286E9F23DE0A66C -:107A4000D2C71606BF2705461F91F07B526E53E042 -:107A5000FCF9C91BBBDFB541F851759FC1EF57EC6D -:107A60007CAE57F83912509F9D5DB8783AC4553FA7 -:107A7000C1CF211FAB1F89F07A1CE2BA06837DE0DB -:107A8000C25404F8513A32E57A8948DB9B143667D0 -:107A900093B5D8652860B40BF013AD0C9EA6B43A2C -:107AA0003C8F335B19BC44AB17E1225B19BC442B00 -:107AB000A33723CF4B00BFE1D81EBF53F835A78FA4 -:107AC000003C8CD6C1CB9834F6F2E0B792C28FCE90 -:107AD0002389F357241C92E09E426E98AF7AD3EB31 -:107AE0009EA3EB877DFC050A1F48937BB11F933350 -:107AF000981C4D32D4ED97011E0984EF2F5E9259E8 -:107B00004858A822FCA57989027981CD83ACD7E3B6 -:107B100055744811EFBE292F001DAC784736C03987 -:107B2000A938FF47BAFBA4E25457BC82F0740BB0EB -:107B30003F3F51AF20FE96031E07C3FEC8ECB1477E -:107B4000393E1F033E41FC32FE7892F3CBD39C4F6B -:107B50001A9CECFEC4B2092C2E2B29DFC0DF430B8C -:107B6000106DDC53BCB38918E9BC50C756300DA06A -:107B70009EF189C97F056D179B4B5C4027F19F3CA7 -:107B8000E8C7B592E274D08BE2B9FE4BAE55E2A7DE -:107B9000E145DA80C4EC102A0AD1AE6933447B0790 -:107BA000ABC179C00C7ED3DEE6B37FCA0EA4CBD2C4 -:107BB000AB313C9824BA8BA7CDA1796B632CFA0723 -:107BC000639DEEC24781CF1B6D48A7563AFF320D29 -:107BD000DE637BC1EB8B19371A32281D8AA0B451A2 -:107BE000FC3ED338C002707E4E2E4E07F9FA1CDFE1 -:107BF00067290E14ED3954079793F6822B75F6EC2E -:107C00000AD985ED1CD7EAE5C00A2E7713C6E9E943 -:107C10005D95BB1F75CB5D7732CC27E5C238E4C7D5 -:107C2000A45BA2CBDF06D9E88577051A86327EF7FA -:107C30009618D97D989EF200FDDAE7DC83D6813C68 -:107C400055E96B2161F2C74B629CB81FF177745400 -:107C5000FD7809BC37C8E52CA4E24023D24DCA3DCB -:107C6000068CCF5BC6DFCB7A8AD217A43E4A5F90E0 -:107C70005E97C1CE33169A87E1BB6D0D5603CA0BD2 -:107C8000E95393DF0AFAEAFE510EF02348B2B3CD6E -:107C900005FE409BD4B48E40BD0233BC2721C417DF -:107CA00038800EBEB1CDEE77B1383C8A4E01E8C8BF -:107CB00091544C8EE5E2E901DE7B911DB710F02B6B -:107CC000BE90546701B8E56630BBABB1A410E14883 -:107CD000E13B362339DC4FEAD49BBADFDB826E5FAF -:107CE000E8E5FECCE40CAE47677AC9400DBF370A21 -:107CF0005C0F53BC2447C3F70BAF184FE05CA927B8 -:107D0000BFF722CF363079B648882ECF54FD539531 -:107D10006772849C50D3C5FD26E8EE7719939C408A -:107D2000BB907A0D144592F7EA27EF8E4738CC02C4 -:107D30003890B49BBAEDDA1FF607BDB2302ABD45C4 -:107D4000CAB1D9DDFBBA2B05F0744A5652A7013DE2 -:107D5000BDD3DBBEEE2A453AF4F551605FDAFFCCC5 -:107D60008FD0AF73E2199B0272A8ECC2E3B83F94C4 -:107D70005E18856979E38DB89F0BCF4E2A047A6827 -:107D80005F7543DEA7E0E7F1D970DF6E6F2C1A84D0 -:107D9000E791BE5805E23BDA1B697941B81CE2C5A0 -:107DA000454DBC0001EFBBE6FE372950502F55DF93 -:107DB0003DA3769D7D34F885568B782FACF4599B86 -:107DC0000BF4CFDEE8AF7455747F00DE614AC70163 -:107DD00073408FDE6F1F1D0AD07E67AF63E7080D0B -:107DE00046D7C900E84DCF58F01CB22121FABB207C -:107DF00073326E580672604E86EB39C49395BD534C -:107E0000DA3B3FB0F14FC221339C63BDC8DF4791DD -:107E1000DCF629BA7336768E7592FB5988B997F2DB -:107E2000185EAEF4526E67F122C411BD5CB53362C8 -:107E3000C3764613ACA3A6F1CCE24F115EDCCEE0D4 -:107E4000F33E25B3799F7AC5E45F1885FE4FF1F8BC -:107E5000940A81C157E58353DDFA911BDFC389A4DE -:107E60005361DD901746D17EBF3A24E3BE514DE900 -:107E70000BE96ADD288C8F179E19F534C40D9F3FDE -:107E80002C6279E5050B96773CE27C01E29E42EF9D -:107E9000CA04E4D3F94337C4313F91DE8F7D6F1FAD -:107EA00026178E71F9507AE109A4DF6E3AF1CD31CF -:107EB00002FF955E788AD1F74601DFAD24DEEA77CE -:107EC000C70CE4F4391ADA574C5A08F0BED687E7E3 -:107ED00024651B4C4ED00722F17C2C43D1F93DCABE -:107EE00082CBB05F42F5AF24CD79FA291E675C766C -:107EF00081BD57481C5E9206FCC0E553988EF5EF95 -:107F0000D07658A2FBE9CF71FDA7F4C2353A3B23E6 -:107F1000BCBEEBF17B29DFFFCB82A3301F5ECF0B12 -:107F2000A3A2AD27BC8E6BB17E477CF4F1D3399C04 -:107F30004FD6971317956FE54656AFD4F78011E4E7 -:107F40004EE9AAF80441B3AEB2C62A5D9C47D9AA4D -:107F500012E34C4DBF613C2C7E778C14C643FA4B28 -:107F60000B262DB4825E502CF7017E5A5751F81320 -:107F700005FA63F2E90BD99705F2BABDF17E7BB43D -:107F80007B13E97D22F0D3C8F143F5EA020D7E545C -:107F9000BC44B63FB9B6ACF027E08F5EC95E21E9BC -:107FA0005DFE44E02D3B3ADC8675C32D07E38D2E44 -:107FB0000DB7AB7471453DE0C6F1ABC245FD4EF562 -:107FC000A8ABFA8C80F108BBBFD3C8F07F297885B5 -:107FD000C7E5F81F137D1D53BBD7319F7829A3CE6A -:107FE000BEE43A1E225EF345D6A1E29FBCA2C3FFC7 -:107FF000D497D6221FAAF89E7D6025D2EF6CCA8F37 -:1080000070DEDFEE7BC01E2DBE686A6F781FE8252C -:10801000B985FFF7F0FE85ECCD82B832EF720BDA4E -:1080200023A7D63D91A585F39C8C31F7025EC8FA53 -:10803000E4CBDA3FBC639D87C0BEF43E23A33F6D13 -:108040006B86BB0CDA97733B7C51FCF841D1F4830F -:1080500047EB0F0D013F5D437D1BA632D72F09E88B -:1080600097D9A82FB9A2BDEFB5A40F932B8FD6B780 -:1080700031BFA7D94B1CDAFBC484E94FFF4598BF39 -:10808000466D6794DD0EF09F1A05528C7A9FE45E70 -:10809000925D007E8FA47CAF067E8BFBB0FB48CB4D -:1080A000D20E38E03EB189F60FFE1C73A6744E7FE7 -:1080B000CEC9F2F9C2A722C437CB494D04FDA1B9FC -:1080C000F4BB06DEC6A4369D7F3A120E92D98EE727 -:1080D0004D1261FA9CBA7EFA05F7A5C7F8BEB482C4 -:1080E000FB359FAF6F42BFFFC2583BEE7F8BFB1942 -:1080F000983D6596F0BD1A533CAB6F8C63F3B68028 -:10810000DF5B847D3580791BBCE823E2D36802E421 -:10811000E38922403E910416E33B2963823F86EFC8 -:10812000CE34B71FF0F84D7ADB1101FCD8C5EEC193 -:10813000B0FF368ADE7C85D6FF9918CA877A59B493 -:10814000E8930496F6837868B7E65C8BBD13AA685B -:10815000FD8291F97EF3A588F39E3F0FD6962F4FAF -:1081600073BD0EF368B0B07786928E0B789ED360A5 -:1081700061EF0D35D8EE88837DFC577D98DE8E74D7 -:1081800000747488E933E724252E81F94995377501 -:108190007E7EB3F2A6661C89DB7BEB295D4A9A736F -:1081A000958192CB007473858F7ED7CE338A3F2E14 -:1081B000C18ACFF2463DCF51E70771FB0047F1C2BC -:1081C00078B4D722E9614FB79FD92B023EA7A9EF18 -:1081D000174B8B583E9EA87F687F7DDAAD8F2E624D -:1081E000797ECEE999C9CE311B4AE2303E4E9DC719 -:1081F000B4D6C7DA404F9DD69A3E0BCEB7A65907E4 -:108200007D0EE91E39742016F4C00704BC5772D7DE -:108210006FDF946369BAFDC375789FF9732E4FA71A -:108220009310BE0BEF260E7ECEEEC7EF338993E799 -:108230009B64B0EBEF09F86F9F4473F7BEE99F04AE -:108240006ADBF443A1B7400CB89B1CE3F10C416D11 -:10825000D7E27C9BE559BBEEF54B665C4F78BD667B -:108260005CBFBA3E3A53847F377CF87B4D2A3CC4CE -:108270009974DD945EA6C5DD7113B9885E3ECD9A12 -:10828000F3393B3461F38984CF7928A2FA63471F1D -:1082900017C9A4F8FB7D1F970069B5399425F547E8 -:1082A0003E91215F2BBAFB41E8F3977DDD8393017B -:1082B0000E6D8997253F8F5818FF1F017A8638AFBA -:1082C0000B49B82EF51DFA830FB6DB40EF5CBCFD01 -:1082D000637C67B9460C3E7927FA4345B49BCE359B -:1082E0000FBEE8FDB323E0A7A2FB5FDF4CF59E25A0 -:1082F0005BE70C89F1C98CE6588CC79F315FD4BD10 -:10830000233D633E8BE723525BDE6D3A7D7D51AFAB -:10831000FD80BF20B29F59F38BC8F1E1704EEB187E -:1083200083FE83358CBE668D738910EF3C7A89801D -:10833000E7ADA34E282D419A9FE58F77027BCE7A39 -:10834000F03F07C03B07B56DCC1F982ADE97FF08AA -:10835000F8590EB07D1CF2F7019D585D8A55735E89 -:10836000D021D7E5C37B7FDE7BAD2EE0FF92DB5CC7 -:108370009FE27BBEDC5FA1EEAB3B1B4B304EB6E415 -:108380001E6524E0BFA4C9E2C2D44CA4182AC74A7F -:1083900024628634D548240BA431C40C69E142F62A -:1083A0006E7769E314D40FEC238B8DF01E6F49EBCD -:1083B000CFBF86F6655260BF9017864F49EB3BDF13 -:1083C000015EE7B88A319EF1AA8D469D1D38B449F9 -:1083D0009FBFBA459FCF0FE8F3C30FE9F31B3209E4 -:1083E000D2D14CF3ADB900AF037B4D742F82F83F6F -:1083F00013C6BB1C13187EBC9B2C280F8BAA5A0BD0 -:10840000C10E3EF39ACD0076F49EBFFC02CFC3436B -:108410005B6209C459EDFF5D0C898178C5D72DEBEE -:10842000A0BC8AE20EFC9755AF5BD6821DBEE34A24 -:10843000D58EF7E7C17A76FC95C5D7843699FC705E -:108440003E7E66D7CF5F83F3B4339BFAA07E754C34 -:10845000F01A6260FC2F98FF33C8DF8B0BF2F7E253 -:10846000AA36EAEDE2B9994CCE04175E13174D6FA8 -:1084700052D39CB4C4DC71746E5D8F9B66801F68A0 -:1084800070A31E2E6ABD217EFDF78778FFA3893178 -:108490004CA7D91027E06FB0C3FEFB72F477921798 -:1084A00072FE79F5D5EE76227F278E289A7B53616E -:1084B000F94DE6F581F80D807FFFF0F72AA2998F3C -:1084C000463F99C0FBFFCACCE29993F8FBFDA7EBAE -:1084D0000FE1BEDFADF7D5BB5CE334F9D2C6FD29B1 -:1084E00025603FADDA9F325303AFEA4D0753EEC626 -:1084F000B827093CB8A47ADA2B4F81BFA27A93D867 -:1085000004F38472805B47D35B76A847F5E161E0B2 -:108510000709EBA337B8C669F8F86FA55B95DFAA22 -:10852000B9FEB27364DB788853AF6A149C50ADAA6D -:10853000E9F65B2701BC57B17BAE85122916297F6E -:10854000556FBDFD4743216E66F50827CC877671D0 -:108550001B7CAFDA7C16EF332C8DF8DD0335DD9D07 -:10856000C9F4425A3F60A0F597DE612D07F945FB3B -:108570007D13F20772D6E1FB2AF653ECFC817EFFF5 -:10858000C440F5965363BDEFDD4D9B9E214D1F4DBD -:1085900002BF52A39E1E297D0BA097853608CE757B -:1085A000F87561E12DA072BB1660BC2F2D9F11EDF7 -:1085B000BE75855FDF4F24DE3FE2F3A57F395AFAAF -:1085C00089AC9738D18BF1E4D5F3A93CD4F809AA4A -:1085D0004FF8F07DC9C8718896AE993E41149087D6 -:1085E0005B2CEAFB4782B990C7E90E60797C571192 -:1085F000E894124AD595649C02F0BE854C80743490 -:10860000C815784F7F64531ED4DF2D045F7909FBB2 -:10861000B3A11CEF7004F09DC90C7ECFB44361F987 -:108620002EEEE754CB2B5B2D186773E64B23CAD98C -:10863000054D07318EBEE3358BC140E5C199AD894B -:1086400063211EB3A389BD537CBA2971ACF122FB0F -:1086500076A4DC50F7D3A3F04FBAEFFE29D3F54D43 -:1086600026EC538B58BC6A6A625D7EB4DFBF50DB78 -:108670002519EBF2C18E09DD6B75AE433879B32550 -:10868000F483A739214EA84460FD1AFB158B7D6940 -:108690007D1BAD0BFEE8844322FE5EC371D1F963FE -:1086A000C7007C4F1EF5A0D9056E7C9F922C62718D -:1086B00095B324129028BDCD82FD280FF32897672B -:1086C000AD1230AE6CF632FD7AE09D5CED3E5A4163 -:1086D000FCEC7D0BAD1FB13FC4BBD0FD06DEB53455 -:1086E000B3F88BCAF5FA76552480F3A9DEFCBD29D0 -:1086F0001ABCBE26EABA5C99B02EE11633CEEBFE68 -:10870000E7E2D8798F91B8603F0D3D6743F95E4548 -:10871000DCD8DF5D7C5FF73C58E29A0D7278FE2C66 -:10872000D7EC44B86FCBF63F34F990BF05DC77AA9D -:10873000C691405FF6EE06817DB5AA55080C85BC52 -:108740009978EDC3D877787F00D6ADBD5F534E7C66 -:10875000385EF92AFD77F221C36B35BFC748D66B67 -:10876000CAFB837EC6E051BDD9A4F3EB8CDE2C7826 -:108770006D78DFD5DF9042E7577B8ACA0A0271AA7B -:10878000DF9B74FD433CCF08DCF78985E2EDB96ED1 -:10879000B9EE1F122DCEFF0887E373B797A603BF6C -:1087A0003E0D7A6B0607F448945BDC7F4002663A24 -:1087B0004ECCF0EE3C96172E64F9C9AB5F99DC788D -:1087C0002DB5F364379E0BCD128BDF86FB602FF740 -:1087D00073DFD2978E33CBE0CA92906F5D83D01F48 -:1087E0003A9FC1E185617543EAA2E8812A9E9F17FD -:1087F0009A02702EEBDDC5F42F5B4148D6EEAFD563 -:108800007D993C8A3B10C47B13A1ED02DEB35C2949 -:108810001CC5FB882B6F5408D8F769144F208F575D -:108820000A649140E152D03CE5BEB700CF05314E1D -:10883000F8B98B9AE631628D15D7CFF4B4D8BAB5B2 -:10884000709E933A236718D0395DF78C5BE8F7FB8D -:10885000FA2A385EBA95E13D6DA1371B7E072AEEF4 -:1088600040F17D6F011F0E8DC17BB2A91456B60475 -:108870004C9780FE9546160850EF393BEB3FD920C8 -:10888000CE9802F9612C9FF0B0E05A87C4B71CFB68 -:108890004F359109304FF80E7AA419FC0A58EE674B -:1088A000F82DAACB87FE5207B034C918C8847E0EB3 -:1088B00077E3DB8D76C53CBE8FCDDB3A2615ECBC6D -:1088C000C31DD4E0A672EB709AAA0F05ACF8FB505A -:1088D0000373587D6E17CECB67F70D92B2F4F5BADD -:1088E0006457DC7090A31F303DFEBCD585FEE96B5C -:1088F0008CD1FD592FF5657A8BE78240FC9A7DC0BB -:1089000033F51BD42B3D1724DDF78E7AB32ECEB969 -:10891000BAFC00DEBBAF216D18875DD314AB8BDBD7 -:10892000BD2626FAB82A7D7B2E88C41B755CA3FE63 -:10893000FB8544E24D8C562F45FF9DAE43976FF962 -:10894000B67B1DF09D8C0CDAC11E9CC8F5DA2EBFDB -:10895000C12B5F1DC64BA723A8DB773A1596EFE224 -:10896000E7716AB9DA7FE75423BF57C4DE5506F8CA -:10897000780713F262EB59F44757B7EE1FCF7EDF4B -:108980008BD185164E5E8DFC4869680B18286FFFE9 -:10899000A6EFA9A7728750123BA0F2F1E9A75C9459 -:1089A0006F5344838EAF630BBAF91CC5CB7306912A -:1089B000CB85334F8DBB569B67F5C3ED3B268FA30D -:1089C000BA7D412E6BFF87BE5FBEB77060582ED157 -:1089D000756415DB34797344DE4AF34335794744D3 -:1089E000795244795A443E93D5EFB005B2442721D9 -:1089F000ED7DCF4E9646C13976603ABC28B0ACE1E9 -:108A0000ABC9E368BEA6A00DE3676A5B05271EEB52 -:108A1000ABF1F14EA667599D41FC3DBBD882B6B77C -:108A2000410E54B7080E81D2BBB5692BC6D554434D -:108A30003B45D3AE89D99DD54D47B15DAFFDE71814 -:108A4000909F97E61CC37AEAF9D19DA4FBF73A2ED2 -:108A500080BCAC696A67FB70C4F95167BAEB20CA85 -:108A6000C388FBAF1EE8D71AA67BB5FEEF87B6FE1C -:108A700016BA899D77768144EBFFB1A67D04E84B59 -:108A8000F0C625C8FDE705FF10D89F5F24EE21B092 -:108A90001FDD5B73C57E03AD77440EAE86A71A0655 -:108AA00065596E96A89C3E620BF615A82CC9599381 -:108AB0007833C0F34872105F68F8E99A2456DE37BD -:108AC000D817CE5D73B37EC8F257045743FEB63550 -:108AD00057B2FCD0605F91B6EFEFBDEA6680FF064B -:108AE0004774BEED9BC5E4B93ABFB27C575A16E84D -:108AF0009BD56CBF80EB97662A17A7579EDEB28185 -:108B0000C261FA4F62515E6DE8B8F5A6625CBFB70C -:108B100018E2DCD813EF7C3F43B92CA11E900E7BEA -:108B20005842181FB6AC3605E5FD95755B61DF4F01 -:108B30009D9E8BF2FE7CA6AB3E6B4438FD76004BCF -:108B4000EBB3D87D8F54D180F106A90FD9500F7A9D -:108B50009A9F2751BE41FC5A393E866531F9372C20 -:108B60008BD949197D6FA887F5DCC5F5D3158FFB27 -:108B7000375928FC7F07449284FE6DD477EF5E4B13 -:108B8000E5461CC453B8D2411EDC0DFEDFDC705E2E -:108B9000D5DF57E4D3BC356CA7AD98E24AD7C60100 -:108BA000AD58CBCA5579B3229BB557F79DD406066D -:108BB0009FD4A787AC8375C44A04EF5FCC993A6809 -:108BC000DD02DCBF6FC1F912972B1DECEF1315FD11 -:108BD0000DA057AAF8792CDF3511D723B278751577 -:108BE0004FEAF8F57CDDB344BAFFD3753ED4CF8DA0 -:108BF00070A4FA401E0B2E60FA403D386293C3F019 -:108C0000255270047CFF5F04A7FB60DDFF289CA257 -:108C1000C88B9FC2B835F3A9BC3068E40587DFF381 -:108C200042404E2DD0BC5F42BF831D78675FF7A3E3 -:108C3000599A739CE90FD5A0FEA7CE2BF6DF774E8D -:108C4000B893F4E4B348FDECC8EFCCCBD00F686C1C -:108C500042B978E426E25C00F2839FCBAAFA65E190 -:108C60004FAA0E831D752E4BC4761615AF42F1D652 -:108C7000520AA7C7E9B60AF7D1BD53587C8FBA6F1D -:108C8000AEE0EFEEAE78F02A8CF3EB2241FC5D36DD -:108C9000EF4882F2AFBB7CDA202CA7F8F65A80DFCF -:108CA0002B62F0770756E413BC67B362DA9558BEBF -:108CB00047F52B4D33E3382BA6307A5A51C1E230B9 -:108CC000611F01B8F5460F290DCCBF4124579E36D0 -:108CD0001EE05D8EBFD882E0F68F41AF5C6641BD7D -:108CE00012F64E3C1FF1A5E27814AFDBB390BED96B -:108CF0003C663D9BEE5F8AE33AD13E7FCCE62A415B -:108D000079F548AC02F35F65214BCCC3C01C218BC5 -:108D100050EEF1F910DF0B18E73183EB6B9F959F55 -:108D2000B3813EF02697374030602FCF24AC7CE6ED -:108D3000C3B147C1BE99F9B088F70BC9921B5CFA61 -:108D4000F30E3AD714F08FF3BFC6900DE0E08676AD -:108D500076E8FFBF6CF09E89FB6176BF9778697BF0 -:108D60004D3CF4C7C0BFE06717D9FC497DAC12ED9C -:108D70005DD08FB97CA7F37769C753C789EC97DAC1 -:108D8000779F00BC28DC03700F2CF488C87FAF5598 -:108D90003FDF2463E8490B2D9F5E2FC62FA4F0749C -:108DA000CFB7E17AD5F9CE480D5DC77E1756DFFF04 -:108DB000C9D8DA42F087ABF60879586F8F815FA285 -:108DC0003B2F629C34DA353DBE737B36D20E24E4F1 -:108DD000AF266DBDEE7B1A8A10317F4E578A200177 -:108DE000DEDC3C7EA11BDF11F356E169E8171D9E16 -:108DF00049C6605F905BEEF9268443647B75FF7B18 -:108E0000C142BC6027360A02D263E383B1B89F1126 -:108E100033C3A3A7324601FA7CD118C23826EF6EBD -:108E2000F6FB9F5D96D00E944B03993FA1EB3D71ED -:108E30002DD4EB4C6674DDB94BE6FC44D83B12EF05 -:108E400089EBB05C60FD762E88C5F828B8FF698490 -:108E50007B99DE3FD5837F45B5E38FEF60EF29C077 -:108E6000EFF668ED60B8375B3E2C2C1FF07D18E004 -:108E7000E79658EE277257E07877C71088C3A83571 -:108E80000818D75B5B7925DE2321FC1DE76A3EB518 -:108E90005A03B5078785F9BCD6706C10D853D5E650 -:108EA00065F8BE332D7F13EC30F899DDEEDFF1C8A5 -:108EB000EE49D7B5CBCEFC05EFB537EBF15F1DA67C -:108EC00013BC1F57A9A59BEC303DA0BE0D72621CC0 -:108ED000C17BF9369E8F9DD0E6073F8D87FB2D9293 -:108EE0000FB0776B6D054D04FCA69E534CDF18DD6B -:108EF000BAF620D8BFF113DAC0E2A2F599DF2DF25D -:108F0000FED0A8D6E522D875AA9EA2B12B87DC3266 -:108F1000549BB2FBB660A7C27841F804FC21B1FDB6 -:108F2000ED79BEBFD17D10E5F11CDF60DC07619FEC -:108F30000239A6DAB920D7408EBCDC6FECD47E743F -:108F40009D79CAD85BFBB1739821A8D77B2FEFBC62 -:108F500049AD07F6EEC5FD610C6EA195714C4EC092 -:108F60000F80829FF8D7F25A7CD71B042F9DEFDC2D -:108F7000D5D92877553F4D35F7539572BF4E29F710 -:108F8000EB805F551BF70A7E4B6DBE9AF37D0DFC9F -:108F90009E14BE17600AC7BD823F671C09D8A01C7B -:108FA000FC3A7676BF4EDBDE43FC4512D2F9F7265B -:108FB000DDBB582BD87A6770BCAFB4307FCEE88762 -:108FC000D78ACC49C5D61B37CC95FD6841F87DAE14 -:108FD000CF399E54B818FB8DBD17E01E23B2F7CDD4 -:108FE000438FB2DFBB3E41F7E7ADDCDF718B15EF9E -:108FF00017BB06425C82E4C8BA25CAEFB62EDD6D07 -:10900000C177FA97F563E7C1EAF7B1FDD8FD5DF4E2 -:109010000301DC17C4A29E4DC19C077454D85FDDC8 -:109020002F491EF89F8EF2F8CEDA3BAC6EE82FC8BF -:10903000FDE22BFBB17D6B653FF6DEBF9AEFB6EB31 -:1090400038BDA8E758E08FD1FAAFFDDDF599FF44B0 -:10905000DD5F9FAF8841B914A65B03DE9F8CCD2DE9 -:1090600036821F6937972325DC5EDF0D07B4204F5A -:109070009AB8DF59724C87DF05DA7D2A17E325930A -:109080008C4CBEECBE2B8640FCDEA1D3AF3EF11E65 -:109090002D3F77CA88EFE1CDE6FED6DD0271C178BB -:1090A000DEED26F423561B99BE58BD6F28D3538C92 -:1090B000EE9510D7EDDD26A35FABDAEEDFF40A966E -:1090C000A73B2966E13E28D37377C5B2F631FEFF90 -:1090D000780DECCE7DA94E2FAD3F3FCDBD0FF09A60 -:1090E0006152E2887AAE2A84EF8B1EF333BDF81802 -:1090F000081E18A7D5C67F47CE953E87F673FCF1AC -:10910000545C0F95B7A83F1D7FCA84E766CF778F61 -:10911000CBFC9FC7E4627C2FE6D8F67C27B52C49B0 -:1091200057B13100FE6DCFD34C9F9B6550D6007C6C -:10913000C8BE58A7CE1E7DAA8CBD1F51F9F0E48B86 -:109140009D63837CD7FA773B49280BEDD1F2FE4D26 -:10915000104FDAD93AC4C98EABD2F090A4969F2FA3 -:109160009F90197C437B65A4E7CBED1FE8A2FB77BA -:10917000EE4482BFDFA63D4F8B3C87E8996778F4C9 -:10918000EC4EE57A9BBEFCD64C7708E45BED33DF12 -:109190001E99AFC078219487C4C7FCE92764D774AF -:1091A000A0DBF871015D9C9659617C35CBC4F77BDF -:1091B00012306AF9502D2F1C4BA29EDB9814A60783 -:1091C000D8F8B97364F9FF014BC990C00080000062 -:1091D000000000001F8B080000000000000BC57D90 -:1091E0000B7854D5B5F03E73CEBC92996426992481 -:1091F00093F7C93BE4014308112DEA24040C98D2EB -:1092000009A062B538BC41C943B0BDB1C5662011E3 -:1092100002A2861A1128E0848762D5367801A34617 -:10922000EF8048B1D5FBC7475BB4F7F78B4A2952AB -:109230008188964BEFB5F55F6BED7D92394322D86F -:10924000DBDB3F7CB0D967BFD65E6BEDB5D65E7B0E -:10925000ED1DB36A602C81C1CF4C334B64EC1AC650 -:109260007F324F316FD0C6984555A9FC9A5321D310 -:109270007CC867AE0C991689D40FE909230B59CA2B -:1092800021DD620FEECCC2965E86FD2C9A00FF8532 -:10929000A68B64D66629C3EF6A4FBF8BB193079C38 -:1092A0009EF5F09D7DF995CC2A189BCB443D336B00 -:1092B000B7C431F67C9B14B240BDB99BCD3BADD059 -:1092C0005FC56AAF6C87FCC076C9B313EACD6DABDE -:1092D000CCDF02F93BF7977A64681A83E3603EE8D3 -:1092E0000CCA50FF9AE649ECE3718CCD37074D0A62 -:1092F0007C674F4B6C0FA3FEDBB0FF65D02819E0F5 -:10930000F90A7FAE1F4A176F36C364F9DCBFC27F0C -:109310008261F96CE8B7BB4B66305FB617BE170EBB -:109320007D5FA6840E49318CD57747B4677F330FB4 -:10933000D643405980F0E832B13B7C369A74525D96 -:1093400029637FC0FF263366CAF48D53C76326376F -:1093500069861DE65DC5E735B04F22BCD6B326133E -:10936000C37E3AE319BB3A6C5C0B0B45437A520E51 -:1093700050F922F3464A6BD42C1AEF4ED66F62395D -:10938000D8EF80C907E3D9FB80AE2597CEBF06F999 -:1093900060FCC87C3055F0C1B2532C742D8CB76C76 -:1093A000250BD58FE6A91DD2450A0BC4005E170117 -:1093B0000E62451A55C6F1AA160EE16569509F471F -:1093C0007CAA6178463C869737F67C650ECF279954 -:1093D00018B3C60DD119084570274D6A1ADB047001 -:1093E0005EB3322833985F4ABA77522EC01B5DCEE7 -:1093F000E7DB78DC6251C760DEC7B2A1DE17699592 -:10940000CFE54179A3C2BCDD501E0D78E982EFDBC8 -:10941000AD2C80FD3F9EA752BF6E13E75FA3E263B2 -:10942000636D4897BE9001E992C01CC88F1A3EB781 -:10943000DBA15D19B693A8DD607B0B6B8B0A6B5FBC -:10944000F5A29531582F175EB007CD509529FE4CE7 -:1094500027F497F87B335B0FF9B32FDA97607F67B8 -:109460008D6C7637D477C9ACA99BF8650DE1FF8781 -:1094700048D7F1C84D55A90C795F9A96CADC58BEF9 -:109480009ABED73B81BF86A1EF607956DFCD9CAFF6 -:10949000CCEA4E18EF82B3FF079807785800F2CB5A -:1094A000550E77E3FE49637F04DF1B7D360FC7BE91 -:1094B0007F2CF2AB59BEE7660BF0D71479E5C0BD3F -:1094C000308FFA749BC30C4DAA33FFE3B7B742FE4B -:1094D00093FD4666463AEF99349B655F0A87962E60 -:1094E0000D1A3FEA0F5B2F77EDD5E7EBBBF5F94699 -:1094F000A67CD4AFF101A0608B6A779D8C26D9E160 -:10950000F90AF8DB6C6E3AD505F09A5F327B56C1EA -:10951000E706D5BF03D7538361E028E2D99CF9E978 -:10952000683FE0A52AF3CBA3A988FFFB9807E1BE1B -:1095300060AD9C4BF4D862550361F2AB51F07F678C -:10954000462D95776E35AB122FAF1D0F726B092D1F -:1095500061AA623100FE1B374FFD441A4DE516A487 -:109560004727F029B57B4E0AAE82764B362FAE6583 -:10957000507E86054D1680E70F623D35CABD532CDF -:10958000F0DFCEB89A51285F94BF2A3EA4FF5AEC70 -:10959000EAEA217CBD34B83E2D1D27002F373289E1 -:1095A000C5E2BC9DFE97709EF5967E5325F473FD33 -:1095B0005FBF20B9BCB8F9D59C13E350DE78E71241 -:1095C000BD617E284716DF7B88BE4B332C04DFC984 -:1095D000745BD00CDF5FDD62E679A789F227B74BB9 -:1095E000945FDC2D052D5958FF627C25CAEFED46AE -:1095F00087995D8AA748BCFC71DBEF621880FC4745 -:10960000102DB8BE98A329C667C7B2A69819A58819 -:10961000AF1B3E41F9B578BBEC09A19C7ED9EEC9E0 -:1096200063989F3C6AA10DDB7F1E5F89F8DB31D90F -:1096300021D377D987728829DEBEEBE1BBB2E32A5A -:1096400015D7CB91ED1CEEC54ECB1348E7EBFF2AA7 -:1096500013FF2B06E6DF67433A7847E1BA53B7EDCD -:109660009982F8FD635D8A81EA3F2B3107E2C3D915 -:109670009C88DF174B8A0FD7D992CD4B6B59CC10F2 -:10968000DED7A832E1BD32736562BF8DF8FE66D4C5 -:1096900077F5DB81CF71FC19EFFFF656D710DF4B62 -:1096A00033364FBF06FB7FD248FCA5F5D3B8EDDBC0 -:1096B000823F180B019E160B3C993357E6E3F8974F -:1096C0005B0F8B5737E53B6C975F1783EB7D1BACCC -:1096D0008F62C6FEAA4AEC2BA0034B8B233D33D2EC -:1096E0007AD4F493ADD0C0F5BE8779F7409A64661A -:1096F0005E09E457769642E5D95926C287F297E586 -:109700007BDF04F89F53FDD15990CF64DEB1A86789 -:10971000D40147552CF4664306294738CCC13D2473 -:10972000E7200F78DA94C09E581F066786E80FD6A8 -:10973000AB0BFB39FBDE9747118F0D199F8E46BD92 -:10974000DD78F10B930AF4B4F54A24676D1E1F43CC -:10975000FE68ECAD630B4A86E463A387CBEF4BE472 -:109760004C9691CB33D700F533359BCBB74E275F63 -:109770009F5B9BA38228F7B6BA8256043ABA3CC0D4 -:1097800050BE4F2F973D08B666A7F82C9C5E16EF8B -:10979000AB4C467EF5C81E14F17DDE8FDBE221FF67 -:1097A00066F9648F0C799B77577B36CEDB6314E5C3 -:1097B00039019CF71B132BC95E99EE95695CB624A1 -:1097C0002688AAA2CFFB8E6B018CFB1DE67DE404EC -:1097D000D0B1069437D2B10FC7067A9D71F8272011 -:1097E0005EB4F97CDB33F59113E1768697DB03F009 -:1097F00089EBB1F2E1F1305AADBC0EFBB9FE3A4E45 -:1098000087D3CF9A83AB61FCD356D03361FAE2B4ED -:109810009DEB1D5F9624ECC2EE0C94FB837965945E -:1098200001D7FD3D0E8E0F97A93B03D7DB9F247D0B -:109830003F77B6CB2C08726669BBC48200E2E9A709 -:109840009ECF40F9FBC99EE733E685C117D94E4B41 -:10985000BFAB8DD7F198D702E3CD63DA78A1341C82 -:109860006F9EC7FC21CA0FD63ED9DB1F663F90848E -:109870000CABCF367B497E9F83D5887CA7B53BB7A1 -:1098800024CA8B76E63966094A30D4BC5E3964C690 -:10989000FEBCDE5C17D0BB416B1FD17FA7E01FA9C8 -:1098A000470AD9A17E74C900C9DBA516DFD15428A7 -:1098B0005A8A7484FA53918E12F2ABD784F35624E9 -:1098C0002ECFCF387C7767C1BC1676E8E9989EE545 -:1098D000E0F375B8B83DD86053505F24B6326E07D8 -:1098E0007EDF10447DED8A8A19CDC08E31A5B86D1A -:1098F00028A7AECF8F6A33C4E2F78C20D64F4F290A -:10990000A476812ACEDF8144166C95B0CB2689ECF3 -:1099100040473F53E07BDA04E6580FD9DE2C6E2730 -:10992000BA9967B34C7662B78476A286074DBE2398 -:10993000DFA0DC3B2D59886FA45E89EC3ED9D03D79 -:1099400007FB1D898FB644F0D1967F321FED1A9127 -:109950008FFC2AF191DB323C1F81DCFC46F559C0BB -:10996000A700BE9204BE1E16F265E0FB16A21BFC09 -:109970004838DF5AD15FADC5169247939CF87450B2 -:109980007E433FDBC0FEC47D4A32DACF90A6B6CE1E -:1099900055B9FDDED72F417FD1575948EF3D60E8DB -:1099A000CB423B3FA9A8691FF247D29C92B256B264 -:1099B0004FD29C28F751D6E0FC1B9A27F9B81D001E -:1099C000FD221FD599683FD1706FA58FDB0135B49B -:1099D0003E1A375855D467937AB356217F34AE0474 -:1099E000FB08E56F4FD79645906F9865F3A09D6291 -:1099F000B5CC2CC176AC5DBFCED649DD641707A6C9 -:109A0000320FCAED734143C03806E56CFF8E1FA1CB -:109A10001E5F5AE209A8B8DE045FE632D20B9D4E03 -:109A20006F721CE0F5E0DF64DA17758E853CA42FB9 -:109A3000097A76D679939D909FB7C14A78EFECE288 -:109A4000E5E7EC8020E83F45E6FDB1580BD73397BA -:109A5000CA030BE23D7102D37E36633E45CB773CB1 -:109A600046768CB6DE3BB3383CF6125F165ABEB76C -:109A7000ABE3FAA260BD27CA066D531440BB3B1A84 -:109A8000C7E4792F0EF7A8010049C1EC7F6FAC9EA7 -:109A9000189EE7F587DA3F30A33A8DF4EB60398200 -:109AA0000D7A57CB7BAD00C75AFB50B902F6A4A57F -:109AB0004712ED27CC980CAAF89C24C60F281BBD92 -:109AC000808F87AD4C375E387C4A44FF46E8DFA67E -:109AD0008AFA8152DFE45C80B74C6BBFAAC30BF0FB -:109AE0003D6CD4F7472815ED31A38DF7EBDCD73764 -:109AF0006E481BD2FF600FD8B3C70FD9016BDFAF21 -:109B0000ED180363453B3E37A17ED5F479A34B2284 -:109B10003B2372BD2665F3F50A766D5236C90D6E8C -:109B2000EFD6A2BD2B939D3B059756E34A1F43FBFF -:109B300012EC86D46CB21B3E3D7908BE77CE384D10 -:109B4000767EE34585EC8F46B03FD06EB7F4727BEE -:109B500096F51849EF6A74BF53C89F4E27E87DE415 -:109B6000D397A5F1C8A78C3565DC043468C9F6E63F -:109B7000211CDA7E2C12DEEBB2B95DDE5858B52519 -:109B80001FFBDF2D31D4FBEB0B3F4A44FBA4B1F7A5 -:109B9000C3C48561ED96F63C4A7858BAD738ECFCD8 -:109BA000AFCB9669FE0D2F1CF0E27A3F1D94682D15 -:109BB0002F5182EBD0AE5CB2C480961A2B0FCEBD73 -:109BC00015D73D9B6D627930BF5CD44BB89FD83BB5 -:109BD00033700DEEDBE0AF049FB6FA16D1FADE3A31 -:109BE000DB62635908E7BCBB090F8E282FE2617D59 -:109BF0006155328ED35037C581FE9346B0B3B0BCA9 -:109C0000E1DEEF923F45836B7D8FB106EDAF0AB089 -:109C1000B7FE15E04E8F9B56E381F5982AEF1BBBEC -:109C200002F29B4690BFBFC9E1F46C937C81EFE0E8 -:109C3000BA7F41627BD4A1F2CC1E6ED7DD9CCDED04 -:109C400040EDFBCDD9DCDE9C18E89B84BCF78AD2C2 -:109C50001F8DF66F23F37E86FB4EE6B3A97B884EFD -:109C60005CEEB85A54F22B595CFD0F8CC1F2890A94 -:109C7000ED2798D2FF088E7B769DCBB39E09FEC55B -:109C8000FCBD2541DA3F64FBE7237D2B841D79F67B -:109C9000851BC6CE2B19B293D6755983AB010FEB3A -:109CA000ECEA4F6A50BEFD4521F9C62C037D939026 -:109CB0001EFF1547FDAEB306D721FD031B8D54BE15 -:109CC0002FC5DF807C79AAAE261FF7C1CC16C8AF9E -:109CD000037E32BA3A18DA0BB07D203F83C5E563C4 -:109CE0002AE42705E62A12CAF908FB6312FA796802 -:109CF000DF0083C3F72A21B6F2800B4E5A6809B4FD -:109D00007D153F648F1CFB7296821F353BC560F149 -:109D10002FC5A6D5B3A3988C7CBF66E0A801E61337 -:109D2000EDEA233BB6BE5BA271EA0B9F33A1DFE4F1 -:109D3000AE6EBE2E1BC53E00F09781F6C0DAEC6811 -:109D4000A1C7DB38BFB33EDA47B367383D19837A22 -:109D5000F6F0FDC42AAAA7F5675ACDFD5EF5C21F2D -:109D6000037290CA7F922D897DED6A9176F0548CB2 -:109D7000BB49EAF3CA88D7B192279C6FB4F4292172 -:109D80002F620F0F4CC1F53B00FC857E992D52DDF3 -:109D9000DDAFC1FCB68C2FF2A009E5067692CBF0C0 -:109DA0003BB022E0BDBCE7B329C8376070D37A6D01 -:109DB000E8A994EB6DA4B769FF9814DDD485E54953 -:109DC0007714925E8D1AC7EE9801DF7F2EF09A6CA1 -:109DD000E37E2EF7EA40D6F2121CDF77F76B387E6F -:109DE0006914F929938036F6384ADBD12FE466AB43 -:109DF00024ACF7680CEF3FC120DF5157427297F255 -:109E0000711EC9BB13D29E6C27F76799590DC28981 -:109E1000DF693F069C81FB59F473613F49393C3D42 -:109E20009B1C5250406C65FD3BF6207FF6981D88C8 -:109E3000A7DA9E5F1E477D596B61DD32DA2B117602 -:109E4000C6CAF49987903FCF9D39B9E37EF8F6E80A -:109E50004D073D7EA28BDE7E88DC2FECC42AC92311 -:109E6000DB7BBFCBD6DB7B83F97FB8BDC7EDFAC008 -:109E70009E68754F983C6F14FBB4734BCEC7A09E81 -:109E8000F97890BF404F570CD92BF376477F88EB7A -:109E90006AD0EE8FB01B8E3D111D40FA9FEFB69237 -:109EA0009F4E41BB07E039631FF80122C765F27975 -:109EB00025DC3FEC337A56437F8D779EFEB901D681 -:109EC0009DD205764F2CDAFB6A2CC9D9D765B60727 -:109ED000ED32C5EB40BF8706BFE29CE2F696A05C80 -:109EE000E4F35F660AE5931D64624B281F13CA47BB -:109EF000BBE725A1779645411EBE37BBFD7F41BA22 -:109F0000A598B9BCC276F8BD4BD85B5D801207E25C -:109F1000E538ECBBB384FEC6FDCF83E9C1F5E4C7E9 -:109F2000B1103D3F7EC5BC13FD3C1F171A4226EE03 -:109F300097203F96DAAEB064A8AF1EB70655EEEF95 -:109F4000B21840FFCF7FF8AE37705F31FF15EEC714 -:109F50009A7FE7CAE9B8FFF878C61413CA9B85CC84 -:109F60004F7EE7C58CFBA197B220F757338701C717 -:109F7000BB0BC4C656143501C0FE55F059324868B3 -:109F800057A86D9027A3D9DB5103E3CE6B33D0BE26 -:109F9000647EBBDE9F7E61FDDD35A8C7D7B619B8EC -:109FA000FDD82E911E9FCFBC6EB43B34BC16E4C4CA -:109FB00073FF689BC18BE35C9F6322FE03120569FC -:109FC0007E226D330A3FBC80631533843035483CB4 -:109FD0005DEB506A86D3CF5A7F6DC6260BFAC30657 -:109FE000D20DE407BE60F2CE263F6A5C3E433F627C -:109FF0009BBDA9BD8697D39AB9601DF051F9B50AEA -:10A0000037F8981A87F2323D87DB0F91F35DD8A1BC -:10A01000CF479E4F2C0DEAF3F399BF203907FD4639 -:10A02000FAEFE9395C5E5D589F25CE013C740ED095 -:10A030006654DFCE4279B54E2179B92A8DE3CB90B3 -:10A04000CED36C67F56CE25F27D817042F873FFBF0 -:10A050005A97847AB3CDC9F9F27F0A7724BC37E4E2 -:10A06000E413BC6D68E4C1786DEBA420C71787FBCF -:10A070004AFD174B72F4726830FF8FDF77727E5C97 -:10A08000278BF5E6203934CFC1E7F4B1E479228497 -:10A09000DF6D601F00DCF3D7C96568A74C9A69A320 -:10A0A0007934BC62257F6BFDCAFE0CB267ABFAF354 -:10A0B0009B86C12B42AB68F20BEACD73C13E01D740 -:10A0C0006DBBFE9C0A342D0B3F779A99E6BD2F2776 -:10A0D00001F7231FEFFB25D27B9F95F413FCEF9034 -:10A0E00019E5D70B596437E5A7F9EFCF41BD1E1528 -:10A0F000DAF16416DA29DC4EAAEF3577A11D38AF04 -:10A100002DECDC0BFFD9A03F0763ED71E4DF609D10 -:10A11000FAEF4BB645B4BBE45C8CEBFB4D26FF2855 -:10A12000B4EFAEBFCE9B8C72F5CC520343FACE9700 -:10A130003D8B508E9CB1EAEDEF33764EAFDD8374EC -:10A14000F6E4239D778F48674F3ED279BE81F9C3ED -:10A15000FBA9473A037D97093A9F3970553ED2F9DA -:10A16000D37D57E5239D37193BBCB86E7665FAF76A -:10A17000221E4F4CF691FD04F22AFF9BF0E38B1157 -:10A18000FCF8E2FF1E3F52BB91F4E1D19CE1F5A146 -:10A19000CBA4A6A13C9C67317FAD5EC49F61FD6BE3 -:10A1A0001633F9255EF9F2F3879E403BA457263B10 -:10A1B00044EBEF15C59F837E85578EBB3D0169E457 -:10A1C000FEEF16FB18B78505D0FFA1D9FD9AFD1843 -:10A1D000298FDF17783C9DE3FD36ED1785BF768923 -:10A1E000E8D312FC9CDBA9BB25F2C75AD46E2FDA48 -:10A1F000BD0D2FCF75A0BFF65490FB671B0E8C25AD -:10A20000FFEDD2E0ABA154B40B7B2507EE1F96EE19 -:10A21000FE3006CFBB613FFA494ED87E74B2D88F6C -:10A220009E0A7E1C83E7E230FE54D4CBD1AE0113EC -:10A23000F26F03ECD3A00A6B50068E627F0D2EE600 -:10A2400009A0A8E8D1EFDBB4F3CBAD3E13C9BBAD99 -:10A25000BD5210F76989267F561AEA2796E6A07341 -:10A260002EB15EFE33C79B983B3EFCDCD8FB971CAF -:10A270007EAE4CEDFBB7C4121FF61B9997EC802DF8 -:10A280007621971492537FDEE6A47D0FFD40FD3FBB -:10A2900007B328AFE9EB450A0B2980F745B3BCEFBC -:10A2A00021DD507E8722E477787EF03C9AF571FDBF -:10A2B00002F23C34DCF9B838A7C6F3DDF0F60D6CD9 -:10A2C00080DAE139AFAE5F6D1FC09AC6AA00F75DB4 -:10A2D000B7DB3C68BF34025F37970DF1E1323115CF -:10A2E0008D0F1B849FB771C947B41F68EC911CE8A0 -:10A2F000DF5DE6E17CB80CF649E6D197AE5BD60DA2 -:10A300007C1806F748EB785CAE7E1D0FE6FF49FE31 -:10A31000CCEB72F5EB579BBFE6171F9C67AFC4D71A -:10A3200057C4BC22F79791FE6C6D7F78A572EDA69D -:10A33000087CDCF4BF8C8F91E4DADCDC91E49AFEDB -:10A34000BCE01BCBB5C873835CEE07C773033CD777 -:10A35000FD9F9E1B7CA276241A480F7A75E7A96898 -:10A36000A7E338EDDB65B20FA6C8FC1CBADE6E268B -:10A370003F6DE4796BA33A459C2FF6FDF66AD49FB6 -:10A38000FB8D0CF5FA12DB623ACF6C949F3139D415 -:10A3900061CE19954364BF7FD3F3F775B983E7EFB7 -:10A3A0005978FEFEAAEDF3787F185DAB4AC0D02F36 -:10A3B000A1389661E5F623824FA245FC8445093019 -:10A3C0006758FB91DAFD3497DBCBAF8A381AB7892F -:10A3D000B5637CC6C3F6682FEE4BDC061EE7D3924E -:10A3E000EDDB8E72D2A2723C3FFEC22DCC00F37F19 -:10A3F000DCD84DF224506FF3A05CD4FC305AFF56E9 -:10A40000B15FBD52FE3F30C8779CFF07F3FF247950 -:10A41000F06FDA78DFF49C6C33E046B74E189D8716 -:10A42000BD81E73B5997F2F348FD8CC4D76FE7FA3B -:10A43000DECC25B9E01D4DE7FE572877A2CB073EBD -:10A44000467F0FDB6F5671DF817E0FD2971B92B96B -:10A450001E533C158867B0F72A304EEA03FCEFD54F -:10A4600023DB87A706E513B70F4F8D289FFE3EFB22 -:10A47000F04799BED3C867272ABDF9A83FD7DA01AC -:10A480007EDCF73DC5E36BB659397F6E93385FB21A -:10A49000E678CD7F42F30A3CCBCFC723F98AE5E9C2 -:10A4A000F96A30FF4F96ABB64138FE97E5EA92FF66 -:10A4B0008A413FE8C8FD04886E15557D84B78197B1 -:10A4C00025B633CC3FDDD8C7E3D4D205BCDAF70BD1 -:10A4D000C2DE5D94E7CDC078AF4FDFB358582C98FB -:10A4E00042C8636897F96C743ED0D0CDE3481A56E1 -:10A4F000323A0F6E40FF6709FA05EB18DA7FCFA9F1 -:10A50000FEC2BCF1789E610BC8B1E8379FC1D0EEA6 -:10A510003BFB1ECF37A8FE122C6F5CD9AF3B87A840 -:10A52000F8EAF335E8D70078C94FE042BF4D189DEF -:10A5300066E7F1F84B2DBD29027EF4E313FF77CBDC -:10A5400041B417A3D53E3A1768D8CF8DB80AD94B76 -:10A55000FE7B76571C433E6AD85F39F635AA6F1DDD -:10A560008BF66EC5EF6B1DE8A7F8F45A17C51F648C -:10A57000C8FD4BD1DE3A92ED9F84F8B09707A7A2B1 -:10A58000BD9A09F62ADABF9FEE9B3A16E1D6E4DFC0 -:10A5900026F47F43BF9BEC7AFF36B378B3EE47FFD8 -:10A5A000F7CE24DA3FEE4BF17F1BE7BFC9CAE10DBE -:10A5B0006CB4F2F52AFCDE91EB5F5BF749B281C621 -:10A5C00049BACD42E7D49A5CD864647E4BCE903CC5 -:10A5D0001927E2E9001F3C9EAFB78EC78188BCCD2A -:10A5E000A58F6B3C9D33791CC2332E4FA1760B2D6A -:10A5F0000312FAE1178AF3F91B449C85166775C6A6 -:10A60000E15B80F8602B6B86CEE5B3B1BD83F3BF11 -:10A61000889F89BEC8EDE86C8789F8C6DECEF8B998 -:10A6200012F00DD267E240DFA458984F6E6768229F -:10A63000E2F3958B06C28752F7069DA7C422D9A0E4 -:10A640009F9C0DFDEB0AD09FE278F75AA48BDAE1CC -:10A65000A842D43DA7FAEEC9A375DE5488FBCBAA65 -:10A66000DF1879BCE0CBD1640774662CA378C1B342 -:10A67000EF03BF665DAA0FB434C056537C6076CF3B -:10A680003BE4D7B7EF97868DFB7C38CFC6E36F02EC -:10A690007D1487C626BA081FCACBBF0FA0FDA1AC88 -:10A6A00053C893D166F41AAC48D7558CFCF0799D09 -:10A6B0000E03D22553C49D9C7BE5BF47FB69BFA217 -:10A6C000F9F1833C4EC8D8BF06F75FCAAAFEEB601B -:10A6D00005B3FAFD4E4303FA3D8D030DE437793996 -:10A6E0009AFCA3993D39ABBF05F9CC76079350FE90 -:10A6F000BC785726F27500E69937CC3C9BF38CB4B6 -:10A700005E9497A30DA8B7948D8CE214156762151B -:10A71000C1FD28E4A19FE5826FB4F34900D78DFA0B -:10A7200068519E7F37D23B5AC801D61C45FE44BBB8 -:10A73000C2FD1EF6E6F79F5D05F91DC21F7BF89569 -:10A74000E219E4BF5BA74848870BCEB9990EF8FE23 -:10A750008B3C6E8FD8953EE6B085E3FF30C56566CD -:10A76000BFCCE3D61423E713659DAB0BFD835FA439 -:10A77000F929FEF4DAB6904CE75B8E138FD4A8610A -:10A78000FB9BCD5C8F34ECE5FBEAC8FDCCE5F4C760 -:10A79000B13CBD5D3E98FF27D925EF0C8EFF77EECB -:10A7A00053987E7F17699F44EEE72EB1BF23FA1BB3 -:10A7B000C94ED1E23CAA86C6217E78D5AED94101E8 -:10A7C0005D1C4C958D8FCB2CFAFE9F12F13B5A5C91 -:10A7D0004C62ABBA0AE3CF07EE63E46FD3E276B420 -:10A7E000389D4015DF47040C20F7B2F07CA883E2C7 -:10A7F0007352594892683FD0CFB07D12C6E940FBF2 -:10A80000FEBC6C827F3BF3B4CB24175509E1B762E1 -:10A810007C473CC21DDCB208C7BBC946E35931BE08 -:10A82000239EF611B48E537C3CAE73D2121E0F9A47 -:10A8300002FA17F329B99C2FADB34D14E7A9C56DE2 -:10A8400068F11D1A5EAA04BE530A1665E17E418BAB -:10A8500003D914157CCA2A63FC8790FB4B0D24F79F -:10A86000B5F8BACE3C3588FC7E0EE3406D571EEF3E -:10A8700011895F2DEEE3FA747F72FE788AFB203D2A -:10A88000AAC56B68FC1246C78015C6DFFA32B7DF6F -:10A89000AB969808FE734BA7917FF1DC5203C3750A -:10A8A00054D56BE6FC1731DED6D92616C27E95A0AC -:10A8B00015E5A7C60797B35F81AE85E8BF3DDCB25B -:10A8C00037E704ACF9232DDD949EB34ADDF2184C32 -:10A8D00007E6A0A41AFD64C64CE56A8C6319C8900B -:10A8E0008075CAF6E6CEA27CC2C007989FF6E4AC9B -:10A8F000590AE8897379033B24A8EF2FF87026E5FD -:10A90000912753189BF0C46F660668DEDC1F35493B -:10A91000F8A3CC4EFFB5F909785FA07F4D1FF97DF4 -:10A9200078DC3FC605223DDC3613D9376E118FC95E -:10A93000AA457C269ECC40BE35792C9D67DB98BA13 -:10A94000BF0FCBD3CC5CDF33CECFAD79DC5F4C2AED -:10A950001265679AE65FEA0FA0BC6ACD7252FB41AE -:10A96000B9BADF1CE47E2E3EFE5B074AE91C4A8B27 -:10A970003365CC913EAB94E25174F987ADFC5C94A5 -:10A98000298E74B41F5A8DC24E15F9A834FF77F37F -:10A99000C3ECA4B726FF4B09AE8733077F948B72B5 -:10A9A000EA0613D8F1C3C8A5D4422E97CE196DED8F -:10A9B00012D86D6FA4FAE723BE8E47CF99E284794F -:10A9C000CD8EAF343911DEC05332CAC904416FE7AE -:10A9D0002C0E9FB3DA272D847E5BADB09EA17D82C5 -:10A9E0005FF192BDEE9F25DD0470B74AC27E676AB3 -:10A9F0002CD9ED856A2C9EFB2D6B7E87E2AE6521FE -:10AA000007642107DE6EE9CF55F240E5766F94D1F9 -:10AA1000DE7E479C3FBF93C5EEA81B66FFBB299F08 -:10AA2000DB873364B514F9C875FFC4776A812F6476 -:10AA3000932748F44BB7ABC8EF87EC15EE7EE84799 -:10AA4000CABCAF1CE3965BD3EF2BC7B81339CEE378 -:10AA5000F685E537E5733EAEC67A88B7E8A672D4C8 -:10AA600063FFB0FE62A1BF92BFBFBFC17ECC1CAE70 -:10AA70006596810C05D6A7C7EDDF8A74BB30F74316 -:10AA80003A8FFD41CA5B1F60FCC45BC68E4931280A -:10AA900087B224C1B7DC5E3B5AA0F93D79DCFBD11B -:10AAA00062EEF70439C4E32B4BF93D9BDA598CD69F -:10AAB00073AD88BB98E2E0F796A69467795A616A0D -:10AAC000D3D98082727ACA715F0CD28FCDF297FB94 -:10AAD0004A47B6C398DBA886CB95A96A581EFEDE06 -:10AAE00058A8CF7FDBA3CF7F67C25F0BC2F31BDD0C -:10AAF000DEE771DE2F493C8E33703573D03C5D52FA -:10AB000000EDA5E2E753BA847F97E20D7F26F67346 -:10AB1000CF4F60549EB8D7B213EF1F687E7259941E -:10AB200017BB9925338EF0417A764012718B2E3AFD -:10AB30000B6207EF7670FC415D13F47370AE4AEB65 -:10AB400038D16660D7E15A2FB790FDA4AD8B562B54 -:10AB5000F037E0B122D51285FCDE6AF46CC6BEE4A3 -:10AB600028B38A7AB532C6427DCB3F56482FADB264 -:10AB70009A29F4F5F0835194AF50980FE33500C44F -:10AB80005998BE65F4049B70BE500FE7DBEA64245D -:10AB9000AFE40A13E969E897E87A78A321C868FE68 -:10ABA000950AC5630A98B5750723D1F7C7C4BA9645 -:10ABB0000D2C44722CC54272EC08F48FFD1E7E5D94 -:10ABC000EE223F5BA17A3B969FB714D0FD9CC6C195 -:10ABD0007B478A01812B147694B397DF0FD3D6B3CA -:10ABE000265F22D73348C15C5722E320AAF80F4CD6 -:10ABF0002311F53E237B5E3B3F4CB768E58A17C7C0 -:10AC0000491EACCFEF67258A7C6A4116AD37A81282 -:10AC10003294A1FDF1CBBF20DF6AF261C7DA1F9346 -:10AC20007CB814FF85DFA7FC34BB83E3BF200DD7BE -:10AC3000A11C559086FAAED5E9517D61F94258467E -:10AC4000B3E3103F500FF2336B3ECC55C2FC83A9E7 -:10AC5000052A094BA8E78D07380E5BD5345CAFC3D6 -:10AC60008C5BCFC78DFEC78EEB8671A1DE613B8CFE -:10AC70000BF5765BCD2143CC70E34F5071BCCB8D8F -:10AC80000BE824A44E137806BE08A05FEAB0DD40AE -:10AC9000FC394DC4EF1E4EE0E3B1427D7C4D6E1495 -:10ACA0008C4FFE587D3CCD0DD2B636D4CB8F596338 -:10ACB00076223FFE52F0C9D1E81FE7A25DF5CB39FD -:10ACC000F94750AE4C895DD5864C328D7593BCD119 -:10ACD000E4DE85E40F2B300FF2EF9A02A0FB0FB2F7 -:10ACE000DF9A839D1F713E968BFA0FE4C3B70A1259 -:10ACF0002E855FE3470D6EE4435C07837C1801BF3C -:10AD0000C6476C7A3705206E07BB1453CD4E65AC31 -:10AD100089C789ABE943F303269E6269E2F35815BC -:10AD200020B86F703E42F168D78EF2FB10DED96317 -:10AD30003ECB50B0B27B6E01EEC300DEBAFF9FF097 -:10AD400046DAE5978B97D6E08A5CC7DAF8D28CBDF5 -:10AD5000142FDD38CB46F1D39344DC69E31203C5ED -:10AD600011C1FE8DECFE066609A21CBE46D8D15A62 -:10AD70001CFF8B12F77F060E98D53D61F6F8A57182 -:10AD8000D42AC5690756F278EB417BBB9EDBDB8397 -:10AD90007A4DDC1BE81CCB6579E7DD2AC553BC2462 -:10ADA000F1FA81B98CDBEB75A27CA143C45BC05C7A -:10ADB0001287E2D93BBB18F17FA73D9BCA5364AE13 -:10ADC0007FD8B7B8FEE9CCE2F664E7ADF9540EFBE4 -:10ADD000825188F7F932D8CFFCFC9EEF0FF2F87859 -:10ADE000917EDA4D05DC2E1BB473443ED22FBB2B73 -:10ADF000D3BF05F9656189374302BE9A6FE27E577A -:10AE0000E0BB6D7867A68635ED5672F0FE45D3BB84 -:10AE1000861CE2BBC789EF8A81EF72747C172C18FD -:10AE2000CFE52F0A538DEF06F9AD30325ECEFF1419 -:10AE30008EDBE9ECFE7D03EE2B7ACD44072DEE315F -:10AE4000729D87C173C2C8E171C932C1B36F3878CE -:10AE5000AE84FFC3F92D89713E1F691D24292C6022 -:10AE60002F1B5A071BDDFE10C23FB81ED6F07DE433 -:10AE70002570CB36E28B9B6F9539BF46737D8EE78D -:10AE80004DC9307E9D18FFE675BE6A27D6AB930884 -:10AE90000F75BDF51417C6AAF9B99107FE203CAD90 -:10AEA00042CE69E75BB345FB998E3A23FAE366D558 -:10AEB000EACF9966DBF839D6CDB38C1F85DB3DB37D -:10AEC000D986CF308E71369E4369F5818FDE2F187B -:10AED0003C872AC073A823C2CF720EF81AF9FEB5B8 -:10AEE00084C5DBEE06BE2BF8694919FAE326272E46 -:10AEF000DDBD11F24F6E2DA2FC6B89B7DDF3169606 -:10AF0000EFC8A77CB541223E3D57CFDB1756DC3A50 -:10AF10002D2B06E5BFE817D713EED7A3FC9D755080 -:10AF2000CF3D3ABB0CE34BAB85DFE0DCDD8CCA6F79 -:10AF30001C63E721BB8B55F2FB554789F2EFF17E8D -:10AF4000DF18FBBB328C33AECE1E9883FCFD46D996 -:10AF50004B45983F227D3667B873AFE24229340AE9 -:10AF6000F0521DC7EBD7963D95827E98EA2A9E2F18 -:10AF7000F654AECBC172C3F939C3DDFF8D12FB9E0F -:10AF8000C1FB6C625D3FEFFD90EEAFF92C9207A71D -:10AF9000E89BF021F91D984D72A0EBCCE7CD52D083 -:10AFA000CF3DC9CBE350AB2CAB92517E4DF79BCA42 -:10AFB000319ED861197B04E30C6227548E47BA4E48 -:10AFC000B230A22BF0794C21FAB5AFFA2C230699B6 -:10AFD000CBA6E7738D8FEA34FEAED6F331AC4F5774 -:10AFE000E1F8CBCBDB91F818C6CFC0F6B3BFA5D73D -:10AFF0003783FD45ACB7C8FE479203F8132E178779 -:10B00000E0E8A6759586D17D39B8EE3AB475370675 -:10B01000E13019FAE81E4FA6E429A20BAD133C1645 -:10B02000D24711706BF0A5836C636597C2853F8A28 -:10B03000662F72081C8E441C9797433B2F8B1B82F4 -:10B040000BC6BF1EE9C0D67078B64B4D5C6E88FD4E -:10B0500081E6CF68D0E6DBA39F6F4514BFD7EE46ED -:10B06000BF13B6738D2DFA3AB81B853E9D65F13D31 -:10B07000688639DCE49C4FFC700B683427CCFF6F8A -:10B08000A9FE3AC447AB1478B93F8BFCF114FF0119 -:10B09000F49E51186607687045E2A36104791809A7 -:10B0A00077241E86E8D3978CA9761F6E705E11F305 -:10B0B00069B5F3F53A30DECCDFB550C01485FC9BA2 -:10B0C0005211C5A16870BD2971BF6440E2F78F3489 -:10B0D0007B2212BEC87B7A1A5CE8EFE3700CACC22C -:10B0E0003B820F166A7E3E4EAF24019FC9200D7B26 -:10B0F0001EFE60A141F3B3EAE819797F4DC39B16A8 -:10B10000E715892F2D4EEB9273B78873E591EA49C5 -:10B1100060A7A7C65D8A47EDDC2E6ED04FC9FD4003 -:10B1200003F7DA490EC60DFA298F2968DF4FF21CA2 -:10B1300052D02EAFAD8109000DDE147E1F0DDF0F42 -:10B1400064F8B71492DEEE1F8FFE959F4C7D82CE81 -:10B15000AB3E30703F7D247EF68C809F91F87D243D -:10B16000F8A3D27C4FE2B867A4BE0A2CECCC16E759 -:10B1700042CC9F85EBC1E9C8AA44FF11C8D7AFBE36 -:10B18000C24D2B16015DCB33FDBFC076B730DF64F7 -:10B19000A46F5C8DDFC8CF4918F9E1978BFDE3649C -:10B1A000A177CF6FE3F11ED5DE518F4D44BBF198EF -:10B1B000910569DD7B497FDE25E03F0F2A3684F566 -:10B1C0009FB193FE5DFCFA7C8AE328D86C187A4F15 -:10B1D00003FE8E0A46E9DED328DE1BA7CB9776A7AF -:10B1E000E8EA8FE9C9D6958F0D15E9CAC71D2BD39B -:10B1F000E5C7F75DA3AB7FD5F12A5DFEEAFE69BA2C -:10B20000FADF3A354397BF76E0BBBAFA1F0FFA0F61 -:10B2100084DD10F0F615C2BC1788795F7F719EAE91 -:10B22000FD9F62A61C437E5CB081C7A55702867451 -:10B23000EF8B7470FBA209FE207D27B3018A076C97 -:10B24000084A9E10C3F836BDFDB1B4A78BF078B99B -:10B25000FBF805AEB90634B94F170AFBE32A761599 -:10B260008F67FD7ABAE6B3BCBF8BAE66B79EAE56AB -:10B27000554FD7E8423D5DED1E3D5D6327E8E9EAA5 -:10B28000F4EAE91A5FA3A76B824F4FD7A4D97ABA21 -:10B2900026FBF5744D5DA2A76B7A939EAE99CD7A8D -:10B2A000BA6505EED4958F446F4D9EE6B42FD7D581 -:10B2B0001FA4BB6F09C537E575FC50D7BF46F70023 -:10B2C000FC41BA17301187F93FA47BE1283DBD410D -:10B2D0006F8D1A359EEC8D124C671708BBDE37BC9C -:10B2E000BDA1C99F70FD1EBEAF1D492E5DA2CFC47A -:10B2F0003E77447D16B1CF7D8F81BEA5413690DF6C -:10B30000EA56C19F87A338DE3FC7A2ABA11ED499DE -:10B310000070BD8770C338EF4515933FE2BBACDBCF -:10B3200088FDDFCEFA289DC30628F53307E9EF79BB -:10B33000CC43E902E63309FFC4F45109E8B7E8AFAA -:10B3400040FD7F61EE5B1FD0B9D61BF157F40EC5EF -:10B3500047787E92C7D849210F4EE0390AE4CF5A88 -:10B3600007F5ABEA0AC3DB49E16F9C3749223DCDC3 -:10B37000E4288AEF9A778B44E744F3FE93A78B4641 -:10B38000493C1E24226D6DD6F0C7F7473B47A90400 -:10B39000471AEB16F61CF3DB72A81F7EEEB1CB4406 -:10B3A000FB58B785C3F7ACC4940971741D8EE8EAE5 -:10B3B000B670789E35320BE2F369E65791180F2884 -:10B3C00020A2F83D8C22E48F79FFF95636FAE9A2E3 -:10B3D000A25E98557D359ECB0456919FFC7B4CEF29 -:10B3E00027BFBD49223FF9F7004E48DD0E8F1BED08 -:10B3F0007C2DFFB080B71AEBC1F7247793847EA928 -:10B400007F587FFB7FC8EBFD9DFD0DF6C3385CF8D0 -:10B4100083F4D3FC9E85061E27317037DF1FEDFEB7 -:10B420001EE3FEBBE6406500CF45653094308ECA12 -:10B43000C8EFC7EF1CC5FD9EC9AC8FFC0BECA8661E -:10B44000D7FA49FE9688FB1767C5B9E2A22E0BC34F -:10B45000389D927D87E2F01C7111F0601FEA61C592 -:10B460004FEFBF946C792D8EFBFD8C4EBC57A9E934 -:10B47000FF91F9546127C3EE3100DF350D677FBCC2 -:10B480005AC4E3035A5BFA46E139A006CFFD2DC743 -:10B49000282F2B1E86E797F83E5478FCA3C905E5B4 -:10B4A00061F24EB141FB303964B4F9E89195352D24 -:10B4B0007D74BE6814EF58AD4D5BEEF087D9898777 -:10B4C0004609FBC71260B84FE02A0A53E524CAB503 -:10B4D000FF627C1F6D76433FE1F2F362020B3F1F78 -:10B4E000686F394EF0AE91FC7EECC49CCB4256A006 -:10B4F0008F59C1BBC0F07DCB0DC7308ECB645FEEE2 -:10B5000009A923E3CDEC562E84CBD3B723E4E94F2E -:10B510005A068A719CD6967E0D5F0CCF6B03C9DCF0 -:10B52000BE6E6DF984BE1BC03E447E7B754BC1214F -:10B5300015CA3F80BFF8DE8ED9C5E162175DA457FA -:10B54000E7083E405F5C3AF0CF07CD46E2B315E92D -:10B55000363A2758F166DE212FAC67134C57FE06AA -:10B56000700F8DC3F16412F214F8C987F2C194A26E -:10B57000D079419C6306D1E9EFED4FC3AFC9CAE86A -:10B580009D2453BA8DEC822B85F36FA3F83B408347 -:10B59000F6C94517C9FF15022FDABB4F1FDCC3C818 -:10B5A000DFB3E25EEE375C51CFE81E026B869F8A06 -:10B5B00021BED1F44C02BE50031F3B5A60C5411757 -:10B5C0000FB55898BF00EC108CDBCF19A2638757DA -:10B5D000716288C1C66A571DA60F4D38D181E2EF4E -:10B5E000E1895FF4618A670438BEA38905D13EA66C -:10B5F000B37F18DFB904F2307E8C288FF1F37CAC76 -:10B60000288F9DCDF3E9DEE7A46A042CE23C2BDD14 -:10B6100016373517E5F402C6EF818B7720B60B7D20 -:10B62000916A8BABABC6F2DB19DD0BD1CA7F2ACA9C -:10B63000936D1FB5E7A01E99A56FBF45E021C9F620 -:10B6400051C7243AF7D2976BE74A09B6F3C7A87DEA -:10B6500089BEFC51D1DE6E3BDF3709CB73F5E33F8A -:10B6600028CAA36D5C1E321FE3EF1588F20744B9A8 -:10B6700015CB717C0F2F97B5773944BD75020E8CB1 -:10B68000A923BFEB28EE77DDD1622921BAB45C246F -:10B69000FA3CD4C2287F6B511CC909430DC7779C63 -:10B6A0008BF383A3990DFB4EC1AD42AEC5A8FD5EE1 -:10B6B000EF30724F2B8F73F0771864B789F8C96C2D -:10B6C000137243ACC741B92135793893713FFDE519 -:10B6D000F81A16DA05B48F32E007F93AED1E03F3D3 -:10B6E00087C9CB946551CC1F56DFBD204E974FBC08 -:10B6F0003D4557DF352B5B576E2B2FD295B35971D4 -:10B70000B46E960BFE8A2A29D3956BEF43B0DDA267 -:10B710009E58BFC6DC6B74F5CE17AAB1C8E327A745 -:10B7200082FEA178068F05E5C3727B7612EA9FA799 -:10B730005B2610729E857505462B7BC6C9E3DC9F90 -:10B74000C1F34328FF598B97BEEF817215D25DB0CC -:10B75000EE54A8DFD5E2A0FCE32D6E4AB7B7A8945B -:10B76000FEB4A590CAB7B47828FF18F48FE9A3D027 -:10B770000F7E7FA4A586F21B5B7C947FB86536E5BF -:10B780001F6CF153FA40CB12FABEAEA589F26B5B87 -:10B790009A29BDBF2540696B4B3B6F57C4F5CC332D -:10B7A000E25EED3395FCBE7C241D3B8B841F52C4AE -:10B7B000ADD887E2563A8B306EA5BB9FEC702D6EEC -:10B7C00005E74DFD59F9FC23FB7BAA88DB6F45ACEF -:10B7D0006F55345FCF743E9CD7E3591D0D7C9FDAC3 -:10B7E000C4E990D53340E5C94B382D9E12FCC95CA5 -:10B7F00001965641510254EFACD45715CDCFD529FF -:10B80000CE91B9619E15E2FD2662BBA001E15226F0 -:10B8100070FDA9D17570DE4E0E27CE7F3878F70BFC -:10B8200078E5F26EFE2E4B4D4708D93ECADB44EF59 -:10B83000B25866FB420AA42E9F9FDE8928BA3805BB -:10B840003667206F2E5EC75448D396E9F76D290BF3 -:10B85000CA74FB22F9E2434C0539602BD1EFAFA249 -:10B860007297EBDA59D27EA82B37B956EBCAE7DDCF -:10B8700095B5C68DF84CE5E74BE60DAB5832C0B533 -:10B88000B07323C1F59198C75949A5FBE5817D5A4D -:10B89000BC05DF5F3C29F40BB36C207BACC0C9B3A3 -:10B8A000F9B10103EA874FFF3596E4D2138F1B826B -:10B8B000E84706F164C0F55F0C661F9697B27ECA32 -:10B8C00063A80CE6C73255C6FC383640FB2BD85F60 -:10B8D000BC5F8471ABB2FF712BE4CFA4FB9FE4711A -:10B8E0007321D29FF9829EF9DA7E6AB312E95FEE84 -:10B8F0002F22FF8DFE7E5D9BD85FB459B99F6E9558 -:10B90000B32209EDD6B323C439DADDAF1E5D00F8EA -:10B91000B6271FA274D02FA71A86BD3FFE4504FF8D -:10B920008F026617FCFF05F2FF99F2B713D10DD510 -:10B93000903B40EBE0ACE475CF45FCBE2E737E84BB -:10B940001D17CE4F11F855F655BAE7021E953773FD -:10B950003C013634CE132DC773300E41CBE78B3804 -:10B96000DDBD2DC9B9D561DFD5624EC742D657833B -:10B97000FAAAB0C4E00962C75E87CE8F61CDEDF050 -:10B98000E27B084A19F3A0981BC53A56A3EE56FE6F -:10B9900026539C9572F86AA6C27EC6660B318C4B04 -:10B9A000D3FA65C21F728F909B5F38AA63E99DCB63 -:10B9B0009441F9873A927D61F3F6211F7DD169E4C4 -:10B9C000F33AAC2F2FB471BFE1A242535095F05D12 -:10B9D000B50E7AC751D921B1B42C846312E1811D0F -:10B9E0008C263E8CDE3C9A0560BD943BFD9662F44D -:10B9F000DB85D483861CC19350AFBED8B413EDB39E -:10BA000002C48B0DF1726B6E350E9D5B48F85D289C -:10BA1000E63DBE98D3AB2D3D021EE6F1E27BA78B3F -:10BA20003A353F8E7E9E0F96577D07DF856CED93EE -:10BA3000B95A8BC0E77A63DFE8B9D0F5997E804BBD -:10BA40002638C717A30DBAB98205488FF3F9D53F39 -:10BA50002EB1AD5924976A488F8F37B0F0F3532D2C -:10BA60009D58CCE5EFB1221E876A771F257E1CCA40 -:10BA70001F39BA00F0F1B48115D2B9B181EF8FB599 -:10BA8000781D19FD0078AFA158C845D6C6A6A1DE1D -:10BA9000761A28FE54EE8AA27BB3B253A1B8F736C9 -:10BAA0005BB5E34EECC7A1D039D11479621FDAD16E -:10BAB00066A7611CDAE14776FEB00FE386E4748581 -:10BAC000A1DFABCDA1703B24CD40F1808AB3DA82F7 -:10BAD000E74AF9B6139588CF435D3FA07722E4EF9C -:10BAE0008B981DE117330A92B5B126EA3F90A688DC -:10BAF000F766BCB56313C591888AFBA19A4F70BFE6 -:10BB00007DC471DE8AFB02D5B688FC81F715F37D12 -:10BB1000A211CF0F21FFF8CAF34E945FAF77AD8922 -:10BB2000CB427B3AA8902D52F8D7D6147A0FA1CBEE -:10BB300044EF356878CD0C28BA73C8F4667DDE1CF6 -:10BB4000711E698CB827B75C8C8F2797A1B0F91844 -:10BB5000DD7CFFC65C36DAFFDC572CDEE914F97BAE -:10BB6000447EAF3190E201FC1CEE5A9489F3BAF0A6 -:10BB7000829FE2CE47B2FF2715AB62BC80D540EF73 -:10BB80000287AC1887BEBB8579D0CEB30415BA073F -:10BB9000B047C8B35C1BE7FF3B4AF87A8D4C733B58 -:10BBA000F8BA539E890A4623DD1CDD650158E7C5B6 -:10BBB000AF4E652AE8C15C87D780FEF7DC66930745 -:10BBC000EDCF29BFB0119F9CB7F1382EA5F9011513 -:10BBD000BFB7EEAC2854C3E00EB6383C289F76B60B -:10BBE000583C181B1F1C41BEE6380D143FAF1A7895 -:10BBF0003CE72EB11E7715F3F788760A39B34B0967 -:10BC0000CC403877013D316EFFD0066E1F2F5F6547 -:10BC1000213896BF9E43F6D548787BA2C5EDC9452D -:10BC200078361852D05F55B92E773DBEDFB1DCCEE5 -:10BC3000DF3796638B1EC3AB11ECD74686F67C6B61 -:10BC4000CC359EF961F25D8E9D58887C25CB8114A0 -:10BC5000F4E7F43C7DE1268CE705FA6DC57CA8F895 -:10BC6000839B307E77AF3D9082F1BDC78A3FE2E58E -:10BC70000981AD18DFDB577C9297A707520C903FE4 -:10BC80005E7C9A97E705B662BEBFF82CCFE3D91B5E -:10BC9000C8CE53C5E76F0AA0BFC5E4598202F9E7D1 -:10BCA000007F092CB16E919E1678D1CA9FC3EFB068 -:10BCB00001DB2FD2C8F283A25DCF08E52F8AF2DE26 -:10BCC00011FA7F45B40B8DD0FEB068776484F647D7 -:10BCD00045BB632394FF4A94BF3142FFFF2EDAF540 -:10BCE0008DD0FE6DD1EEDD11DAFF56B43B3E42F948 -:10BCF000FBA2FC3F22FAFF40D4EF17DFB3ED1BDEBF -:10BD000047FF7D36C811944B85F60D71B8CE77B6D6 -:10BD10009713FFB756F0732A8DDFB32546EF0EDF7A -:10BD200056C2DF3BBBAD84CB71A584F339F0E1C3D0 -:10BD3000C877CBDF94299EA8D5E039154439BADEFF -:10BD400040F6C0F2D7F97E7DF93A25187E1F486B80 -:10BD5000AFC1BF06E103C66DC314D6DB97C5FC9C1B -:10BD6000D1EC767B6AC3E499D1A1CF83BC602877FC -:10BD7000417E53DC78E1BAAAF6C2723CEB339005FF -:10BD8000A2D45B42F88E8862177AC151DE5188F0E6 -:10BD9000D9147A3F4193F3CCE6D6F935DA6C0ABD73 -:10BDA0002727DB79F9945F4C74A09DD5C6FC7D5E96 -:10BDB0006CEF56C88E3FD45EE640B967B22F70E094 -:10BDC000FAFDB894E3BDBAA1300AE5B5FCA081E460 -:10BDD000F711075FEF3BDC3CCE0AF40ADDAF0279D6 -:10BDE000ED411D51C042AB506EEE7DE8E05CEEE7E8 -:10BDF00063F6B115747F493B579794B07D406D0948 -:10BE0000C74FA6D0230AEA174877958B7B3701EEF8 -:10BE10008FCA54983B35ECFE706D89CCEF3D69E7D5 -:10BE2000A1722DBDAB95B152D19D23A4DDA3CF9BB3 -:10BE300022F48612A15772DA414EEACE4F1CBAFCA8 -:10BE4000B74A849FC7C33C68C74EF9C5069287E7C7 -:10BE500051BF4923CBBD41F92BE4F12E4400CAD197 -:10BE600000BFDF7E6843D9AF90DECBD719E83DEB4A -:10BE70002B95A30AE218F090E797482FC0845270E0 -:10BE8000DF74393CE4197D71F4DEC765F091F76821 -:10BE9000791CCADB3CBF42FD5FA2372E83AF67250A -:10BEA000CF713FD2D11925EC6A6000F4DBC545752E -:10BEB000E1F9BE49F853B438652549E1EFF58B7BCC -:10BEC000B2B2E0E3FB99578DCBC1F78A9AC8BFBFE6 -:10BED00062DF3D6EB4DBD71AFC0ECC1F8B9B368025 -:10BEE000E32C874D3FE26F2FF641EF72BE7D33FAB0 -:10BEF0004DBA8326ED5DCD10FEB30FE38FB4773BD3 -:10BF0000DD64AF897CD5CDD530DF6EC5518C266818 -:10BF100047C9E44D46B049F799D8607DBCEFF7F4C6 -:10BF20001183E8EFC64DD52097F64531DDBBA5FB63 -:10BF3000D0CF4EF9E99BF09D5218EF4619F6663BBB -:10BF40009F99B5C976F5103CBB9FFDEEA655E8B0AC -:10BF500013FB1427E3EFCD9F51FB6390B4B05F59FF -:10BF60005F82FBF5AE1389E1FB75AD7EACA8DFD037 -:10BF70003BD0F08C4AF53B4A801FEA7B06624A08B8 -:10BF8000DF0315E1F563841F20ACFEA6AFAB5FA80D -:10BF9000C1F3CCDB3797F0FADBB0FE59B53F9162C5 -:10BFA0007A22E089BFB4FF9D04FF08FD1789FA6774 -:10BFB000426F53FDB3AC3FB1348BDA3D85E39C7BDC -:10BFC000E3ED0A31EF443CC779D7E6FD197E6FC136 -:10BFD0003E707FA734A9F8BDDBD2E140FBCD6AEC0F -:10BFE000F0A11CCEC5F7C7260CA5CFA2F2187FE999 -:10BFF000F7487EEEB6B0F85AE4D76603ED6F7AFAEA -:10C000000D0F205FEE489BE8C0FDF33E535F5909DA -:10C01000DAAF076C64BF1A323FB5A2DFDC5CC0D771 -:10C02000BFD5D9E42981BC35BD84DE0F95EF5DDE37 -:10C030004DEF98DFC7DFF7527E6CF2EF46FE0A2D18 -:10C040002F5C18B6BE7797F27B96EB5EB36DC0FDA2 -:10C05000C13AA3A7A300ED70BB42719FCA8F0F4ED8 -:10C0600023FBF0E70646F21FE65905FDB6CD55E87D -:10C07000F7300C94CEEB2B217CF87C55502F2341CC -:10C0800091F07ED0FD8ACF82E71D6661D7EDF0F09A -:10C09000FB61DAB81784FD79A184BFB7B623EDC27E -:10C0A0007B8B5DF8FE8389EE75DA961942A618BC83 -:10C0B000E7B6F3D462A46774FF3ABCE71C95A238D4 -:10C0C000707E3FAD85323A97EBA6EF817A03ED1B88 -:10C0D000E29719BCE87F8CCA35E9FC1D361827DCCD -:10C0E0001F1233DAFF47A4E7B837951B11CFEEBB19 -:10C0F0000DF43EEA83EE772D068033A65CDFDE3159 -:10C1000051DF3EAE5A5FEEAAD59727CED297BB6FCE -:10C110003745F875F4F9268DAF4026D8404F45F1E4 -:10C12000221665BBD082FB9EB5AF4531A2CFCA4D6A -:10C130001D05B83EA307085F514551E417589B6C95 -:10C1400022B9BEB694FBF50FA79B6EA43CCC0BF9AD -:10C150006347DA51DA8F5C8217DBA9BF62FF3616BC -:10C16000F61DFDF2A3BD96521E57C3DC15E8C7634A -:10C17000240F9F95BC9E4388EFB7B8BF624733F743 -:10C18000633F388BC741D20C2A70BDF3FA31960D4C -:10C190007DB82F8BB1B5DF8DF19D91784D14E70DF2 -:10C1A0003BF0762FF29D9FBF1BBD46BB6785DF2B03 -:10C1B000E8D604BD8B366BB478EF4FD809B1EEF8F2 -:10C1C00092B6B0FB1A89C26FF2F0C47956D41FFB45 -:10C1D000C43B2283FDA934280F79457F54A9E6AFDB -:10C1E000E1ED3769E73C229FE0E4F97D47E26EC468 -:10C1F000F5B569565C19EEF7D70AFB2E36CDE41D6E -:10C2000005F37AE49829208D81BCC28E18C12ED8FE -:10C2100017C7C735BD1E15C07B818FB8CBE99E619E -:10C22000AD80FBB94ACF3BB8DE07601DED84FE1F31 -:10C230007179AC65E2DC3400F051A8159828876A62 -:10C24000CB68BFFB88D76345BDF9489AC78A71DAC6 -:10C25000D664C581716B716E85DE897BC4E277A07F -:10C26000FD13078AD484E749E91D53E97E1DE0DA0E -:10C2700050C18F1A98886FC4F8C27881CF1DEE051F -:10C280000E7C97C195BBFF5FD04F1F8FFDC5F07629 -:10C290008827A7C0D3AC5295E07689FEE3173C47C8 -:10C2A000F5F1A7AD22AC3F4147D35416C47D9A3671 -:10C2B000BED6CF60FFCC4BE7006B7EC5F1B62A9DA2 -:10C2C000BF8F65BA8BD17EEEB94AFF5EE4B381E4DD -:10C2D00028927729EE942AE4A394635B67E0BD8BF0 -:10C2E00035BF8AE2E32CE4FC9EA230CB7538EF0424 -:10C2F000BF03F118B95E938F74D421536A74895CBB -:10C30000BFC90A6B97E32E5DC7C96E5755FEE8613A -:10C31000D673C47A493E36F07DEC3F725D6F8FFE76 -:10C32000602CD72361DFE5CBE7DBA4FE7524879380 -:10C33000155A67E911E3E13B7B98979841C5B8E846 -:10C34000DDA54EC1C7A0974A91EF1D936CFCBC9D23 -:10C35000F8ABEAF90DDFFD35E42FE0EFF3815AA9E0 -:10C36000C73AFA482FF6F80BB0FE36C5FF38FAD3B5 -:10C37000B71D4FA2F72BCDD1FCFD5153C47B299A99 -:10C38000BED85DCAFD486AC4BB9BDF34ED4E4B2B63 -:10C390007678B0BFB77F6B49F8C7DB3F6947BA57BC -:10C3A000D9604D3F5372F326BCFF6C7D93973F0DD0 -:10C3B000F980827859467E97C31977D2FC5BDF33C8 -:10C3C000933FAB54F66CC63CFBBD95FC717B0F4CA8 -:10C3D0009C8DEBA4D55EA1A2BD7F40ACE37F156927 -:10C3E000E4BC6493C78FF640E4F7674B35FF9BE7E7 -:10C3F0007817D0B7749789DE711A8C8FE8B2F2780B -:10C400005461872E10F26CC1C1F5198718BEC35153 -:10C41000F75A29B45F60AF4E4478522F4ACC0FF2DE -:10C420006F9B389F4D753D27A19C49731DA9447989 -:10C430009FCEFA56A1DC486FD29F97A55E54A8DD27 -:10C44000BE142FF5873F18076A62624DC7F9D92AD3 -:10C4500094F329FCBCC5E488E271A1EE6ADD3D6A73 -:10C46000ED7DDBB7851C35014E8D6590DA147E6F4E -:10C470003FA2FEEF443D19FDF6E8FC771C3D4EFD62 -:10C48000DA944FC3E34D715F4A426B193FFF043C9E -:10C4900005701FCA62E3F879A9D7AB86C7DFA68209 -:10C4A000DC359761FC4980E24492C5BD082DAE079A -:10C4B00030E044BF9B16F7B193E9ED112DD5F6E7B7 -:10C4C000B9CD32ED3B8A5FB5F2FD413B0B5A25F405 -:10C4D0008731923BB91BF8F9B4E617BB0D1713EA85 -:10C4E000257C0F97C6EBA6386ACDAE02FA92DC59CE -:10C4F00017F1CE94F68EB66134E78B6D2D0EA2A3A4 -:10C50000569EE68FA4A3FE9C53AB977A3195F9E330 -:10C51000C3FB0D527FA9CDFB891F522F6650F9B680 -:10C5200016F532FD678FD07F32F1CBC8FDA751F9E8 -:10C53000F6D0BBCEE9808A9F0EEC77FA54942BA1FB -:10C54000A99E61F09C7A8F5E4E8EE9D1CB5D0D2F56 -:10C55000DB14AFAB0EF0BDED1E83A78B61FCA9BE53 -:10C560005E4DD66F9CFC5D6BAD7EC83513EB2FE343 -:10C57000F5BF754A5FDF577920B23EC177FD457D33 -:10C58000BD48FA44C20B7025DC1406D7248BFEF795 -:10C59000DACD9E7B095C09B784C175835B5FDFBF21 -:10C5A0006A78B86E2C347F2D5C5ABDEF4CB8B27AE5 -:10C5B00091F39859631E01EFBCFE2DB3AFACDFDBE6 -:10C5C000967C7DBD3B9A23C7096871DB3A7B24BE0C -:10C5D00099DBEF0E364071269ADD11C71C22FE8BC7 -:10C5E000DB0DEFE07F93197B60B46FCEE804C4BF2E -:10C5F000F7F64755BC1FC3F515ABE5EF56C2BEA411 -:10C6000034FC5DEE21B85653BF2F61BC13E9598B42 -:10C6100007EDCEE254664946E3CB1DCCC6F7C7EA28 -:10C62000476BF29AC7971709DC3D9BD2BDDC49EBFB -:10C630003C1887F07CD371EF1DEDBD67F4F8A1FACB -:10C6400023F95B343C994CDDF47B1D06EA6D1ED466 -:10C650000FEF6211B4DB75B3398476B516877A3C77 -:10C660007ACED10495DE3D588DFDCFBE65EA1ACC59 -:10C670004B87E3D5E536BC37D5AFDD2F5D83785BDF -:10C6800066F167261AE87CB500F7C3CC172F2E2376 -:10C69000FB4A878BD3D0E0A99638FEA3D2FC0FE3E8 -:10C6A00038D586BE1D3EFCA6F4F17DB62381BFBB06 -:10C6B00084EFEB0CB3FE353C54897E0E193D5F0EC2 -:10C6C000C0FC0E6D8CA57BF80BE26F99836FB22CCA -:10C6D00034F812F1003D0CEEED04B76D6E6632C217 -:10C6E0006D14705B1204DEBDB95F07F760BCCC7DD2 -:10C6F00092F67E3AE59F0F38E9BEBBD9F0F9BB331D -:10C70000510F971A3C68776E03FB02DF77FB3F02FD -:10C71000DFDBF18C258EBED3BB6F6E71EFCBBDC955 -:10C7200040EFBCF8AA5E203AED6AB07970DF3E9720 -:10C73000A9F4EEEA7C710FE60F95FFFD723FCCEF96 -:10C74000A5D1FE83388F3BE20D19EF121CFE627AF1 -:10C75000476BE295C5CF6AE7F033847DB050E07156 -:10C7600026F352DCEE4DCC6FC471DF3E6BF2A25D5E -:10C77000FAB68847BE8505E8FBAD2C48E96D2C4428 -:10C78000F5BF872FCA42FEADE8D1E9CD005FDD637A -:10C790000579B81EC3F0FE06D219F8E50E17E79723 -:10C7A0003F2621DE3B13AE887FEB248EBF0746FB7E -:10C7B0007FC3D7ABEAF2204C8E4969E847195C3F4A -:10C7C000D5099CFF1447DED7AD9FBEF3DA7D7FAF5E -:10C7D0002DB902DFFBE23F3778EFA278718CCB777F -:10C7E000011DFA547ECF11C4863D0074AAA9942974 -:10C7F0006E6FED67E27E363A31A0DE2FC7CAF43E97 -:10C8000099762E395DF4373D8DDF57ACAD9CD91646 -:10C810000B7899F2657F7908D29A34FDFDC5A9AEEF -:10C820002E7AD27C5AAEFEFB8DAC830E886B4BF415 -:10C8300071E6D323FC9F87706CE0AB8BA345BC648F -:10C84000112B0ABF6FF01DD1F67CEDE7A673307E89 -:10C85000C918FF57488FE5DFFEC31CDAD729ECCD96 -:10C860007130BF867F97C99EFCA80566528071D53E -:10C8700016E60583FF24D815983FD5E2A6F434D8F0 -:10C8800001987EDA5248E5675B3C949F35C667198C -:10C8900003FDCE6BFF4C417DB4568BC7167068719B -:10C8A000856B45FCC40AFBF2E318BFB08202DE19B7 -:10C8B0002CF68E2908FE9D3DDD473185EF32EE4393 -:10C8C000566C94C8AFB3F0887F0D9279F11BFDD3FD -:10C8D000514C8CFFCD8944DCA7D7A31D0BACBF22E4 -:10C8E000CE9B340658C0DBFBE1D178A8FFC7960980 -:10C8F00004DF272D5E82EF4F2D3594D68FF1A5539F -:10C900003DF619BDF3F4ED673E54F0F7B34DF64A2A -:10C91000E4BFBFCECB8241C0EB662397EF9B41BE05 -:10C92000E3FAAC2C9DB1FD1E86F2D75F80F3BC29E3 -:10C930006EFEE478F83E7DC25C05EBDDF225E8A0F2 -:10C94000AC213EBC1C5F9F794522FC9C79C549F80F -:10C95000D0F0542FE875E660F177F0DDB3578EC95B -:10C96000147F7AFEA281E03B7F3C8AE25323DB2FD7 -:10C970003F909384F6D89F807E78F0B1FC4031F9E7 -:10C98000E3FFF4ECBFA8E171BF7F8AEBBEF03ECAC3 -:10C99000A9FFCBE514D89B27B7A21C4B4BA1F77B73 -:10C9A00006E3D5585334EAB10693585F206730FF49 -:10C9B000A728BE0FAEF8796A15AE171C0FE3BDCCE1 -:10C9C000E2F760407F1FFC10FA3BB8D54DEFFD7CCD -:10C9D000BAEFB16C1C7F6FF7C2F7B742FF6782FCFA -:10C9E000F7609C61DD675F4479BADB467ECBB512A8 -:10C9F000C085FA744F0AE50B2525AA999C19411E9A -:10CA00008722A90ABE7FB6ECB92D29C85F784F1DD1 -:10CA1000E3EA5FDA184D72EA25A3E78366EC6F3B21 -:10CA2000EFEFC987EEFDA807D307EBCBEE4539370B -:10CA300086C7312EF8C9D2226C0FFA9A7EDFF3D363 -:10CA4000CF4B21F48394761E5A8D714C63B67D686A -:10CA5000488174EC6EA915D3E2F469C7D07F70D712 -:10CA60001895DA8F7B264BC6D8F4A294E0FBD7F357 -:10CA7000B8119D7E2FE9FCAC0AB7999A9E2F92BA05 -:10CA80004F77E1BE38E37819BFDFC5DFAF3ED03B5B -:10CA9000F39DDB18CE032C08847BAE89E22E583040 -:10CAA000D085743EE32FF4D0BB2ABEC016E4AF336A -:10CAB000FE44BA5F78D01088C1DFE314F880FFBE6F -:10CAC000A1E777BF1583F114B1FB8D0C7F2F76FDA5 -:10CAD000D88129141F92AED27E3C7DC70D35889F28 -:10CAE00086FD07BAA89F65160FFA63971CF89CEE9F -:10CAF000BDB0A93C0EF5CC7E9E7FA0DA4BEF9D2FFA -:10CB0000E9FA33CFF7F928EF930359747F623EB700 -:10CB1000771E13FA8CF58F66E1EF2169F47A008AAB -:10CB2000B17C73562019DFBDD2F420E8AF8770FDC9 -:10CB3000A1DB91DA3B66F27BF257A8BF4C421F693A -:10CB4000FD3D66E2EFF4A218C1DF8BB3CDC4F5EE74 -:10CB50001E9037C82F9ADE857177E0BA3589FB328F -:10CB6000A9A064C7C27C521F3373F97D85E347DEF9 -:10CB700067D5EC90D9F1AD746FF5D354FFCF701C2D -:10CB8000EDFE2A533CF4AEE0EF53BD4F8F49E0EF8A -:10CB900075E01C402FFE02F30D32D85139617694B6 -:10CBA000E5CAF4E2DF52BD07709C2BAD1F29872731 -:10CBB0000AF857D80D8487158F9AC91F3651DC4360 -:10CBC0009D78FE7834CA93157F2E23B9D2CAD8B087 -:10CBD000F879B985C779FF1BFA1120BDF68B7E99CC -:10CBE000F623470CCB8E827E2510C87F38D01A5B87 -:10CBF0004E792F92FBBA2F0CC3EE17B514E8F52E21 -:10CC0000C9E92FF5FE87EBBF74D0EFCD64B6B82B22 -:10CC10009AF7D0FB3EFAF96BEF6CC1FCFA51BFAF4B -:10CC2000F8CC40FCBBE2B332929BBD57385FABCB34 -:10CC30007B12E18C9C0FC0FF29D22712FE417E1F80 -:10CC4000B832F8BF2F31FA7D43A0AEC8BFDD2BDE6E -:10CC500031E85D5A42EF691CC4F748506ECEE0F7E8 -:10CC60008E7AC5FDE4DE0407BDF7F19291E703B7C4 -:10CC70008AF6E27DC8DE5B53F87B1DE6A65F97620D -:10CC8000FFAD3C3EAED718A4DF53FBFF00D94A30BE -:10CC900097008000000000001F8B080000000000CB -:10CCA000000BE57D0B78D4D5B5EFFECF2B33C9242F -:10CCB000998490072161F220040D3879F10C3040FD -:10CCC0008268D10610058C71420284BC088FF6C4BC -:10CCD000969AC100A2C51A8E886851070A14156D6C -:10CCE000A888A8C13382505A5F69B51E5B2D4D04D8 -:10CCF0009F3C1282F6620FB7BDFBB7F6DE99F90FC3 -:10CD000089DADED3EFBBE7BBF1D3EDFEEFF75A6B69 -:10CD1000AFB5F65A7BED69FFD12097D7C998D13AC4 -:10CD200037E7743E63EFF90C5E7334632D9AFF5658 -:10CD3000630163DE0B16B63B8DB12D31FEE4E53C9D -:10CD4000BF65D95554FF3DC666B6E5E0BB3B2996A5 -:10CD5000A707FF66BCBDD4CEF3B93CCFD39734361A -:10CD60009FCA67BB9362787E6178D468760DCFEFF7 -:10CD7000F0EDDE1A87EFD9D4CF10236BA47A69A225 -:10CD80009F3F9A45BB3F30FE97C4D8A366E6B5C522 -:10CD90003236DEB568B8AB9031CF8D1126168D4294 -:10CDA0007792C6E7F348D57076AFC6B3AD0F3116AC -:10CDB000CFD87C2BA33F351E2A5AC730364F7C660E -:10CDC0000B16EFB679F87CE655DBBAB4D17C1DD5ED -:10CDD00077453AF978F33C467F5814AF705389BBD6 -:10CDE000335BD4FD7B3AC675D3B8AC6A10CFF0D4B0 -:10CDF000E4AF647CDC977BACEC5E0E97BFE36F4ADC -:10CE000020E510636C30639FDAC4F8F56D531F386A -:10CE1000ADFAE3FF565BEC1BB56894A7FA181F7FC9 -:10CE2000FF104F01FA5F7EE8BA074E5B03F5AA16C2 -:10CE30009764314360DCD07142C76B01DEF878C380 -:10CE40008047DEA485171880BF369B0FF863A69E27 -:10CE50003F2CE5F996F957B9EEE5D99973AC6E8D8B -:10CE6000E3A1F740982F4CC3F77037D6D57238D26C -:10CE700067E0F9DB3501FF168DD177EF7EB36F37B1 -:10CE8000FF5667F13DB187B7AB7B79A48B8FCC0E92 -:10CE90005AF87F50FE6284288F72A7AD2F40790226 -:10CEA000E1F725B3339ACA7F6D64541EEECF8AE151 -:10CEB000F06E4AF4CC71F1790F09E3F8B7A35FF192 -:10CEC000FDA4A4BF93BC5BE0D7DB1849FD3299F702 -:10CED000FC7090EF5E5A8F3B6931F2ABAEA6F578ED -:10CEE000300F3E2FD6A0D17A4F3A7CF764F1F293FF -:10CEF000ED83691E71921E4E96FEE58DB1BCDEC9B2 -:10CF0000434617FAFCA0C9E8B744A15CE0439B6321 -:10CF1000CDDAC6DB9D7A31D215C6CBCBEEAF7D1D07 -:10CF2000DFCBEEAA9F4569CD9A1B19AFDF79D7FBFE -:10CF3000A99E9C2BF15156C75B05E1F14E97BB1E94 -:10CF4000F87DC4E569C47A97E7742E619CAECE5B28 -:10CF50003A1E6346C6DE1DEA5985EFDD2F7CB20717 -:10CF6000DF399EB24A47F16598389D807E3B471372 -:10CF70005D2F97F49B9EEBB903FD713896B30CC6F9 -:10CF800022723A2C98075B33F85BD1C9E7EDBB0FEF -:10CF90006A7C9CDAF0F6064A8DBED1E8E78CE68F13 -:10CFA000D232088E1EECBFB30E7F14F0E131F03C9C -:10CFB000C74FED5EFDBAF067E2F3AAC5FFF076B5A4 -:10CFC0006D46B70DFB87F92C987F2DB304EAA7892E -:10CFD0007D083AE0FDECA4FD6AFFA0FC871C0F353C -:10CFE0004F8CCCBB97E3A736E6D04F26523DDE4EA2 -:10CFF000ED17E39579B59E2BE723D67756EE83B3ED -:10D00000FC8B19F4B32F4CD03F13F471FE892449E3 -:10D010003F826ECF3F31C287F9C4CB7D735EF31A76 -:10D02000C2D1EE47CCB59BCF8BB9DAC6CC1E85D921 -:10D03000B78D9913C9D856C9D76A07B58D01BF52A4 -:10D04000FC8B59DB46CFE6E52CBB6DF49C5101FE11 -:10D05000C74ADBB2E8BBAF2D0BED0F1A5835E0A97C -:10D06000E653F354F20E828755ECD79AA7AE26F812 -:10D07000A8715AC047C08FC12FA2AE5CF7CB2E4D0E -:10D08000ECFFC83109E06B03E13F3B71500E58C91A -:10D09000F90596DBDDBCDF11DB2CBA7E54BD913E79 -:10D0A000FDF75FA17F4E6FC342F039C4D8F34A1831 -:10D0B0009F2FFB198713BB72BC3765BB279FECC33F -:10D0C0009F51E09331A7A21B27C149E0E90F1685C4 -:10D0D000A7D5C99C5FD70226E901781DCCF524436A -:10D0E000AE9C471EF22686E779DA20E1AFF20AEE1F -:10D0F000A1F477D71F962477F2F6FFE532D0BC4231 -:10D10000E1BA96C30FE52D66767B296FFF79F38927 -:10D110008CD3E6C07A3E6E76BBB9A8E9CB2FD99600 -:10D120006BC5BE5BBA3DD7BA2808EE2D7BF34F38EE -:10D13000395ECFEE356124D662F2FD64421CBE1B1F -:10D14000DBBC8CCAAD6E5EFFACFDC89BA8B7647B30 -:10D150004C9ED11968BF745B89BB2A08FE57EFD576 -:10D16000E363549B3E7FCD217DDE9CCB881EFED1A8 -:10D1700076B97E7D3EFF843EFFC93BAB6FC63678F5 -:10D180007E9CD8379FFA227D560ED7EAF7679C809F -:10D190001CFDF4E0F351C057ED9FAA8E2733AC433A -:10D1A0004FA71C8F9A89AFD7BB47237A59E60BDD6F -:10D1B000BF926F5CB1AFD712BEB0B382E92614BF85 -:10D1C0006758DBCD6E4E5F754D6F67408FA99EC56A -:10D1D0000919F2BB6DB385D9AF1C6F20FEC1EC6E8F -:10D1E00027E3F457314E944D689ACE4EF1FED8A6FF -:10D1F000DFCEC07EADF8B146FA46C5B3235E05DD8D -:10D2000074ED5F703DA537CF24385432B705FC70FC -:10D2100069BBE68FE479C738E7A14EDE6EB14F7384 -:10D2200061DE8BD68505F819FFB76A53C83CB60492 -:10D2300095F3F92F3DF4CA571AEFBF7ABBBEDD3222 -:10D240000E2FC88F9A5D7F0F0BFECE152182D784DB -:10D25000F61D46AC7BB19CBF927FCC3B99617D13A0 -:10D260004413761AFFE172C332CC539C5B1890834F -:10D2700013B688F69CF15560DDF5768B13EBAEB7EF -:10D28000327F049FCF89488BDBC1BF5FDC1649FA30 -:10D29000C39230E6B5E651CA6C7968E78A46BB8F1F -:10D2A000DF32929E54CF790FF5F3B8E66B413F46DB -:10D2B0004DE47F26F2CB989FD603BA7107AFD3A770 -:10D2C000CFB3D641A497D499FCAF002E35AC93E0F0 -:10D2D000CD383EDD0A8E1C6E757C9DEFC542FFD2B7 -:10D2E000B75FCEDAA8FEF2437F0F0BFECEF54C6699 -:10D2F000E5F5B787F394E6EF23381A2DCC6DE0F30C -:10D3000034DE19EEF3921E521A0E3A354B7D79CB6C -:10D310003DEE2CCC7BBDE6CE72808F6DB6B9C0C71A -:10D3200016EE1072684B0CD75FE3486FA6F60BA1A0 -:10D330004F414F5920F8DD9698363FF8FE9607D3B7 -:10D34000843EF53723C1A5E73E9B6FA7067D5AE8CB -:10D350003D5B368FA0F6E097A44FDD1729DACF1694 -:10D3600070DD32D8E1F3F2FC1F31C524E8D9EE2C90 -:10D370002BB5E37A5A5A404E297DFA67C33C7701B0 -:10D38000DF6ABD4AFF66D5DF4EDFDC2DE567CF667D -:10D390003E4FDEFF69ADF4B821481F7E2057F0FFF5 -:10D3A00031D3DC7B643D17EA551966DF3B85CFB787 -:10D3B0006AABC1D99216803B73BBB300E7D39B6DB8 -:10D3C00079A0B331D3189D274EE60A7E1E51C0DCEA -:10D3D0003E9E6E97FD6ECF35E8D2C4704E7FBC9FE7 -:10D3E000D3257E33F01B59506A813CE4329CF87996 -:10D3F000E83AF6E60AB9596529FDCDA47EE6D34799 -:10D4000007C5426F39BD42DB29E625F03CE6DF6DFA -:10D41000AE165AB7989F823BA79B4292F7926FC570 -:10D42000F4D189EF091B47ED66A54F03FF9A8E4E95 -:10D43000089E5BEE1B45785C28F1CCEEB3493A615F -:10D44000ECAF282F7152F9379DB7D43A391D5039B6 -:10D45000C7B71FF80E3D6F297C3393AFB0347260AD -:10D460007C2F1A173346E3A04E36316F18870B64B2 -:10D470001EC1E51E93EF2E3E9FA12601FF1493A02F -:10D480002FCE9DBDE17954DF6DE1F98A07963237E1 -:10D49000AF5F91CC5C9AA8CFA2519F7763E42964D7 -:10D4A00006DA55448B7E2B1298EF2EA9F7835F6521 -:10D4B000224DA77EDD8658D13E2A8FDA7B0DA2BD94 -:10D4C000DBC4D3611962BFF4AC0FA3FD5371774A7B -:10D4D00016E860D6343D1DE4E709BA51E9E3794E18 -:10D4E00029675C89D8DF8BD68D24B9D1622BAD7FBB -:10D4F0000EF87A3A82F4C18A0DB7DD5088F93D33CF -:10D50000081A0EFBFCC6FD63406F8BD62DF8DEEFCC -:10D51000711ED96BA3EFED799EF3B9D0B73567F9DA -:10D5200073FCC3A279472D89BCBDA76DF6B91779E5 -:10D530007AA377FF9BD00B6EBCC948F56F646D7FF3 -:10D54000F923F8C23A31CE0DDE0BA644DEDF0D45DD -:10D550001A437997CD91BA82CFBF42E2EFAF721FE3 -:10D56000B4D8D8FC5FDA31AF94AC74FEFD0668AA7B -:10D57000FDE881E3F2A49E3855DB0EBD67D874B197 -:10D58000BF547DF4837E27031EBC9E59C245E539F6 -:10D590005CA97ED5C6B0AE8C28A466FF089E2E2E50 -:10D5A0009866CBE3F566A5B3193837F5DC61643BC3 -:10D5B00069BE3D15B4EF23B39CD8F71EC6FCC4F773 -:10D5C0007C2389EEBBA6F674DDCDF35D3B46B85AED -:10D5D00088AF8BF3FB620723F9DE3555F035C55F65 -:10D5E0004E3A3A23895EE579BE5292C6474DD3B78B -:10D5F0008EE5F52BED962EC883C50FCE8D72F27990 -:10D60000566EE1E7792EC7D826FD799E9FB733F293 -:10D61000065F792E0F3D7F83664047559B34A2C33A -:10D62000612D2E4B12F131CD81F555D9FD99907FA9 -:10D63000552E9B0BE5679BDD0F9CE6FAE1F9E69919 -:10D6400094B2CB1CEE7C9E5701797CDF8FCDF7B86E -:10D6500000A78AD60A3A4F46E478883F2D97743758 -:10D660008B835903BF317526611F76E5CAEFB18EF2 -:10D670002C3BD1B38D010E5D664716E6D5B5DE664F -:10D6800080DC9C7597A06BBECFAC26DEFE1E130B14 -:10D69000C77EFF1BDAF37596AD3595EEE0F9A1561E -:10D6A000668A8C055DE5125DFFBCC063061C3EFD0D -:10D6B000111B07BDA072D3669A8FA20B66EA281EC3 -:10D6C000043D6F775A1ECED78A8E7E5E30EDDABC6F -:10D6D000607AB849233AE0E92B19440F7366113D8B -:10D6E0004CF367AEE4F32A31D63137EC0C89CC1514 -:10D6F000C6E7DFCB7A489FE8E5FA04E499E2278A97 -:10D700006F703A705BE303F8DDD3CCA7C279F2DE29 -:10D71000662BA54F363B9889C3775F7322E59F69D7 -:10D720007652DAD69C4DDF7FD9ECA2FC81E671946B -:10D730003FD8ECA6FCA1E69994BED85C4ADF155F01 -:10D74000E270213EA4F88AE2478A9E145F0AA5A3EC -:10D750007227F606B527BEA7F81DD661C80BF023C1 -:10D7600085DF74ADD49B98063ED6B900FCA2C47880 -:10D77000F6E9E7397C7BABEDAE3027E022F85EAF0F -:10D78000DD4A723ED5C20EE1FCDFB2C2DD75779094 -:10D790005CBDB55A63A620BABDADD1C64C41747B01 -:10D7A0007B538C2E5FD6F4F6B104DEFFDF533C5E74 -:10D7B000E0E5E49D1F3FFA9FFCFBE3777E3E1CF80B -:10D7C000E6F3D8FD10C65D13DE378F58E4D79949CC -:10D7D000CE0C0B17E7A461E1E29C843FE0671113D4 -:10D7E000FBF4F13BFF4AFBBCAB29CC6984FE017C16 -:10D7F00071F87E20F1B5A8298CE058B1FED4D3CFC2 -:10D8000063BFAFB110BF5BB44EEECF8D1CAE417A9B -:10D81000DB87498CF433CDCD581387DF873FB2F8CF -:10D82000B9EC671F6A569FC61B6AFCD054C6BF7B03 -:10D8300036FEEA3DE8DB5AD309D28F3D56BBDF887E -:10D84000F979CD6783FBD39A8E533DD63934E6E31D -:10D8500008DA8A0C708C28705BC02740DBC0DFA21E -:10D86000EC230CFB9BB56A8EE17C5D55F27BD546C3 -:10D870008DF40E05FF27F28CB4AF4EE79A08AFD3B4 -:10D88000B0670713032339A5E896F30DB70FFBA381 -:10D8900035D7B224881F2F92DF2BB30D94AAEFA7A0 -:10D8A000F9B6443FD3B0B978BFF766A75B1613BF8C -:10D8B000735AC00F54FD45D9791BD20BD0CFD43841 -:10D8C00016B42F9FCB33C97939841CB37239C6DBA8 -:10D8D000D50D200F947EF229FE773CCD9FCE5F358B -:10D8E000CF3CF5CC8BB04BBC1F4678AAB946DA3793 -:10D8F000727C63E6925EE3B66B7C9D0D12FFC54FB2 -:10D90000FD29AA93972F3F20ECA73CED42DAB0A661 -:10D910009AEC650D2EBE4FB00F0E993FEC0CA2CBCA -:10D92000579F793FAA93CE17DE644322527F32E39A -:10D9300069C381533318FA633D1B1CF62BDB2DD7CB -:10D940002ED33953ADA3E4F097F134BE76299EEA85 -:10D950001F5E1FDF9F1D6439337DD8B77FC9CEE0BE -:10D96000D6D9D596B34D178C7CBECBD7CCFC0474DE -:10D970001E5AFF93BCC838D00F1BCBC6921DC3C420 -:10D980000CC0F74AAB8043AF6F7834FB1AFBCBF285 -:10D990006DBC1157B57A4DCE68179F6F37ECE7FD18 -:10D9A000D4CFC91772FD1CDF478C9FA5BAF719E9C0 -:10D9B000BCD0BD2F92E8BF61DF03C727F27CC32E26 -:10D9C0000DC3B27AD641706A386064D6607906FBBE -:10D9D000CEA081E759FB546423E869599BE6DECD6C -:10D9E000E7D36B75460F0E9A8F2D5FD0536D58DBC2 -:10D9F0001882AB9CFFDF253F53F596B53F6001BE13 -:10DA000078BDF3A4BFFC228291DD8CF5BC89799EA0 -:10DA1000D99EEF827D6F59DBFE0692FFFB221CC36D -:10DA2000F93A3E97767ED5CFE07CB19F06E70BBDF5 -:10DA3000E38CB4E79E79C6487C08F3C43EFC1C7AAC -:10DA40006ED03C93E53C93F3857E7304FBB130507C -:10DA50007F595B575426AFFFC9A1B7291D2EC7595F -:10DA600066EF180DB9F9C98188993E4A7F3AE325D6 -:10DA70003EDEB9B6A9715AD0BECACB3753BFE7B69E -:10DA80001B67025ECC3748EAF96DB49E33FB9235D2 -:10DA90003ADF02DE5CCF3F73E0D92803ED5BAF686D -:10DAA00027F168B00A3B6D588C53EA99D656E81BAB -:10DAB0000BB97617CDF95DFD810B247F43BFABFA1F -:10DAC000B4DF9270FEEE21BB06FF33807EEB1D02B9 -:10DAD000E725C69C04EC83F26B9CB7DC0A3EF69A01 -:10DAE00059E061A8F3219CABCADF1A44768B956696 -:10DAF0006702F25FBCCE0F827CDEE5F9727F27768B -:10DB000016C2CED99526E47ADD467E50E1EB19C2E5 -:10DB1000F1EEE54BAEF31999273FE0279A9F9F4E10 -:10DB2000EB7BA4DAE0B6909FC59F05BBE7490BF3FA -:10DB300092DFE89736E10F481776FD47A4BFA82E7D -:10DB4000D69F3508F62F89C7BA39BC3C089F753B6C -:10DB5000FD59D05FCE5A849D0FE50EA479A25E8B4D -:10DB6000A41BF4837EBBD21CE749CF7C2E9241DFFD -:10DB7000373C1F29EC0A3FB7ED0C0B929BD592AEB8 -:10DB8000B8CEE4C5FABDBBC5FC302FE8CFCB2CAD79 -:10DB900059D02FD5B8CBA25A69BCB372BC65E1ADE0 -:10DBA000C23F6111F648D4A7F1CD8CFC283D4F84CB -:10DBB000919EFA7952C7418CFFF9132319E47857E3 -:10DBC0009A6FC9212AE7FA1BC747CD93617ECCF72C -:10DBD000B327227D8CD7FFCC2CF4A1CF22E3491FA1 -:10DBE0003A11B9B59CFC32BBC234D8553ED3982506 -:10DBF00011E5BB851FA3A6B989FC0F357CBBB33CDF -:10DC00004A67B258948F247BCB67BFE6FB54A3EFDF -:10DC10001BF1DDC35ACB7F807DB73782EC6E9F3F0F -:10DC2000F95F23FBF35BD4ECD2DB97141DA8F27BE6 -:10DC3000245FBA47C2F1BE7C07E1BF3EA26D6B3ADA -:10DC4000AD53EC578E073A77F1FD110F7BF7C9B64C -:10DC500017E2353BE0ECCFFA29E0BE579C6F3EDF80 -:10DC60006726BF4BCDF3916EB2E3DC3DD600795110 -:10DC700063147A708D81838FA7DA9D7BB3A067B719 -:10DC80003C61CB033C38BCE91CD9B3DB28C711E3AA -:10DC90007EB62745D8F5FD327F7014D9F567C5B239 -:10DCA000DBE7909EB37D34E07A7157840174C1C77D -:10DCB000716B1C3E353FF8A18067F412D2CBF9FEA0 -:10DCC000237E5927F965FDDD13A327623FBD6564F7 -:10DCD000D00B2E9A5C09E087A1F0FA40F295DA8326 -:10DCE0008F5AE0B7ABE3FBC6C3F74DADF48FD53E1B -:10DCF000A9915E57BB61E243C407DF34B3E17C1EE8 -:10DD000067DB1E880AC6C771C9CF02ED5D54BF9696 -:10DD1000D717ED5F8BA2F9EC31BB309F503C7EEB07 -:10DD2000F64F1ABF55FB3EFA68E3727DF495EBBEE1 -:10DD3000C83ABEFF3EF8C93E1BD9AF38DE53A177C3 -:10DD40009C31B72DC1BACF3C6D233E732646ECF70C -:10DD50004F383FF48EC03CBE733FD9377E37974172 -:10DD60001E2CF5E9FB55E3BE26F96FFD205734EC78 -:10DD700064F51C0FE88FE3E5BBD4FE2D33B50F5DD2 -:10DD8000C793685718B43F9F8E207A393344E0E335 -:10DD9000CC332348AE74C5083AE7F34DC579E54C5A -:10DDA0008C481994114E0735F23C7A666A1B9DBF68 -:10DDB000CF68FB29ED328B76354DD26FCCE92E1131 -:10DDC00074039A843FCCBAA903FA04ECD563F22811 -:10DDD000F587C55E6977067D420E651408F9C53082 -:10DDE0005EBCF47F909ED266015FF6483DAE6EDF6A -:10DDF000957E38E0B76E9F467E2483EA87CF3A4E01 -:10DE0000D9CB393DD67A35B70DF359B76219F991A7 -:10DE10001A37DF0A7A57EBA835B199380F7569467A -:10DE20009A4F978DEF1BC02178BC20BD2B32300E4E -:10DE300073C4939E49CA754C819057C8B7F2FEEAE5 -:10DE4000D6699B689C3475AE14EB5370E260B1C028 -:10DE50005EC6CFFBA27C80F5AB7986AE5FCD6778DE -:10DE600081B05374A539EF2F02BEDF30BA704EBFB8 -:10DE700078393F3AF66BF4329CDCFAECC67CFE79DA -:10DE8000A0293EFF2F257FAB855D9ACF336BBBDE8C -:10DE90001F92BD4B9FBF6A9F3E9F73409F1FDDAE89 -:10DEA000CFBB5ED5E787C871159C70EE758E10E705 -:10DEB0005EA438F73AC3C4B917799C7B91E2DC8B36 -:10DEC000EF38F7228F732FF238F7228F732F529C7F -:10DED0007BF1BDB240F0EF3A6977041EE097612F05 -:10DEE000D8949F9DF64BF78278E29FCA4FDABD2CFB -:10DEF00087F27D769DD956B2EB90ED86EB25738740 -:10DF00007A6E282884FFB4634312F066EA247BEE1D -:10DF1000F217853DB72ECF66879DA173FD271BA005 -:10DF20003E650DF5CC41FD6E73CF1EA203939FF8A5 -:10DF300046E75AE75B5304FEC8DEC1ECB1743EA964 -:10DF400080BC8B1D188FA17E15B649EF4709F5AB34 -:10DF500084FA5342E940F9511E37F72481DF9F7A52 -:10DF6000C2BA09F33F25ED646CBE95F42FA557970F -:10DF700018ED04A795F7693B21A75615C452FBDE9F -:10DF8000135CDFEE47DEAAB4F252BED0AB557E93EF -:10DF900066203F8DC74D7268959C53AAD6D37537BE -:10DFA0006824D24072FCA2DD40E7828BEF18498FD3 -:10DFB00018B1CDA05BCF485FB88EBEAEDE1B1BE2B2 -:10DFC0000F1CA2AB7FCDA1F4107FE0557A3FD54D59 -:10DFD0006B5FC1F97AEEA67C5DBDAAD289217094EF -:10DFE000F3967A69CB9A6DA9E03FAB227B69FEABD1 -:10DFF0009EB3D1BD8B2A2E5FDC7CDDD5C870FE5868 -:10E000006D75DF08F855B7996360D7AA94F2873524 -:10E01000E9E571B589791DB101BAAB7630770C6F3E -:10E020007F2EB7758F81E3ED9C61FBD62227FC4BD9 -:10E030003B521D9CAE566B6DF1E3797FA7623C3B72 -:10E040000AF87E4E35FB7F52067EB93F83ADE5F57B -:10E050004E6D7A368AF46E4967A9664738F0BDA3DB -:10E06000D548E702D8A7600F52F4B0A3755078A640 -:10E070003DB0CE00FE2FD3FA385EE8DE48AFFDC8D3 -:10E08000D055D0E3DAC47AABA76A5ED293E57A566C -:10E090004AB9C2D6897E56CBFC69795E50EB3B3BD0 -:10E0A000F295D14EF8359B0FA51AC1C70DFBF6248A -:10E0B00041BF48F0B463FF54EF18FE9F457CDC9AE3 -:10E0C000DF1B19FCC81F6D991E351EFAE7D366D7F2 -:10E0D0002C9EBFBBF567169C0B6A4C3E0BCE9DD5A4 -:10E0E0004FECB0C0FF7FEDDE1DF47DC9DE0A3A6F54 -:10E0F0002F658D748EFCD42CE4B48247F5346DBB4F -:10E1000083CF3BB350F0D7EA70711FA4C458742C6E -:10E110000EEBDDABE562BD3795EEB754F0EFEF4A9D -:10E120003E1CBA3F7A5F9F5B321876A536E1071D29 -:10E13000683FCCF38FA4FD30F7521AA5375DBA9A29 -:10E14000CE55BF67A5A3884FE4849C675F370ABBA1 -:10E1500059BBD807D5167FDC5CEC9397CDB44FEA5A -:10E160004DB07DE39CCCD8049E96161975F4BABCCC -:10E17000384247CFF359ACCEAF7C331BA2CBDF3450 -:10E180002B4357FF969BAE0EA1FFBC4039F191097E -:10E19000BAFB2BF56BBC4E8DEC68D3F4DF79BA86F5 -:10E1A000E8EC7A5DFB7A3627500FE7E05DBF253853 -:10E1B00033D661C179ABDA20EEEBCCF774C9EF9DB1 -:10E1C000F49D2F44B70F8765B8FE53C84533D9E790 -:10E1D000957D7A3EFE3FA33FB9C8112DC78D360A03 -:10E1E000FB8247AF7774D0F993093CD44B7B4F7DCA -:10E1F000B6B0F7D47B3B2C8D7682BF299983A4A13E -:10E2000055237B1EAF6F4D8E15F935F87EC01CB0BF -:10E21000B330D1DF25949F305660BF849637F075B8 -:10E2200043CF6880BD86EC4C333F213B931A47F6C1 -:10E23000AFE874E936BDFDA801769D207C2E2B74D5 -:10E2400012BDD6ECDD7F7C0887CFDCD2985CECA3D6 -:10E25000BAB6D9E68A9C2BE94DF1F98BD506F27B4B -:10E26000F7BE7E94E8ADB7DA4474FD4D7069700B6B -:10E27000BB66281D2EE1EBB2F2F1971CD05C3E4D3F -:10E28000D4037C86803E43E093DC0FDC14BCFAE0D0 -:10E290001752BE14FF5380FB049ACF9FD61F5C42D7 -:10E2A000E0A9C60981171BA787C7128FF32DF09F1E -:10E2B00025278CCCF72DD6BF14EBC43CF83A318F10 -:10E2C000399784DD44F9136EBE64A27C1FDD94721D -:10E2D00078E561DFE9F7691F1D958A7D33EF523CD0 -:10E2E000B5FB57D1D337D1919ABFE2DB817D74174B -:10E2F000C98DE58591711F7356C1FFBF90F882E407 -:10E30000AF03EBA55EC1473D7A3933ECCE7174EFB4 -:10E31000A8D79E4E7A459F1C72E8CB5746A627A0E9 -:10E32000DC23ED768A1F7B643D354E052F770E0288 -:10E330005D0F8D873D76C3BA8CD4CE207DC5B3DE0C -:10E340001C0F7B61EADA419456D81CF19023156BBF -:10E350008DA5908F1FDE93103F0EF6F9F5E6B859A4 -:10E36000BCEB0FEF284865A3902FA1F4D4E6B0F9D9 -:10E37000C1766E956E2B147A68FD9DEF915C3B67BC -:10E38000783D6A3EF6DDFAE7A270F5A676FDDB631E -:10E390001C5C25B93BC6F35021F95177EC71006E36 -:10E3A0008E1DA361A7FE396C688303FA43CDFA92F0 -:10E3B00004D8C5EAFE76F431C87DCF5A733CF4CF59 -:10E3C000CFDEE1725123B9467AC3A73646E7A54F9F -:10E3D0007747F8E0BFFF54636EF87796195F19ED41 -:10E3E000D0C9D9F69B318FBD099E9F1716627CDF7D -:10E3F0009E448CEFF2D2FD4CCFDAE1D1FDD95154DD -:10E40000BA7C9BD0EBF6283BAEB4F7429F471EFA8E -:10E410003C1B21F479E4A1CF23853E8FEFC7A41DD7 -:10E420007F584B4F2ECEA3DE692CBB91E4AE3D1B33 -:10E43000FAFA2A2DDC457AA6E64A807D8CBD1323A4 -:10E44000E46D087E553AA987EB5C41743FE59295EF -:10E4500005DF339BCA6274F9E9D6245DFD12479A41 -:10E46000AEFCDAC491BAF2EB9CB9BAFC77B2C7EB56 -:10E47000EADFE09AAACB7F77DC75BAFAB3DDB37531 -:10E48000F9B93317E8EACF2BADD095DF327F99AEDB -:10E490007C8167852E7F6BF51DBAFAB735AED595B1 -:10E4A000BB99C304B9D78E731687FBCB3867F17459 -:10E4B000D51BC3EDC1782D9A6E68ECCF4E7F5EEA16 -:10E4C0004313C7BA3F037DA418041DF2D40D15E20F -:10E4D000B2942BC9CCAF89736E4712E826B45E683C -:10E4E0007951C4918B4E8EC32507636F35713E52AF -:10E4F00034F6487E06CF3F336681C84F3CF26C3A13 -:10E50000CF1F3CB8F55613E71F45D71CB988F2D189 -:10E5100063CB457E2E2395E3C898BF2DF4F2751486 -:10E520004D49DFE41276927EEF69AA1470C0FD4671 -:10E53000C001A99FD327D2239C3E91BECAE9B3CA8A -:10E54000CCD8714E9F484FF0F326BEFF869F37917F -:10E55000BECECF9B48DFE4E74DA41DFCBC89F47719 -:10E56000CDF3297DA7D943EDDE6DAEA6F4BDE64619 -:10E57000FAFEC7E6264A3F68F6D2F7C431CAAEE0D3 -:10E5800027FB8BF23335C0BF07FBDC21F3D9603F9B -:10E59000ACF2132ABF604B23EB8CC03EED34C57C3C -:10E5A0006C0DF8FB06E6B326F671901EB639D19DC8 -:10E5B0003186C61FEA207F8FFC3E4D9B9B02D7DF32 -:10E5C000ADA33D23C7707CCFCBAB5C1FCDF9C79407 -:10E5D000CB8D66D0CBEFE53DD5D0FE2F4B3A891BD6 -:10E5E000EB1E8D7693ADE21EDE64ABB86737D9D4EF -:10E5F000D9027ED4F22573E21ECD2B9116E24F2D67 -:10E60000F7987CB0536A5F30CA4F8A63946FF9B24F -:10E6100083EEE54D76B81249DEC87C9FFF1C7F4132 -:10E62000F765943F5BDD9329FEA2733AF480497647 -:10E630008B332CC4FF0EBFF52B91EFAAF9308CA7BA -:10E64000FCE4BBBE647EC3E8803F7CB2B5230D769C -:10E650008249ABADAEE0FB3FCAEFAD7DD161843CFA -:10E6600051F77CD4386ABE9126DE5F5EE01ECF642F -:10E67000475B2EEE35B4D4DBA9BF04FEDD9247F52F -:10E68000DC466AD7960B3BF0A43ABB0BF66DE56F00 -:10E690004F90EBE6F5689DC55F78E8BEC12479DF51 -:10E6A00000FD5845B917FD4C8AF32799B0FE468BFB -:10E6B0000BF6D04735DE3E2FE0FF47FD88A0FD8BEF -:10E6C00079A2DFCCBFF0F9426F77BB09BE73D5F9F1 -:10E6D000CD29F3523E33EB34B25F1965FEB7A33D4B -:10E6E000CB81F7D230C79F22689F67A4C0CE315B31 -:10E6F000EAED5F432FABFF7BE8C52DF03D94913DE4 -:10E700002D946E145E149E07A22385F7A0FB5A84F5 -:10E71000E7BEFB57B29F50FA1A88AE143D4DB60AB9 -:10E72000BC03AFB847A3E848FBA26D07ADA3CE4A30 -:10E73000724ED151281D5C4947822E5BBE67A5FEF3 -:10E74000AEA4A300FE018F7F9E8E3A8C90BBFF2863 -:10E75000FDDCDEC36644F3A27BAFF15C86DCA8B8C7 -:10E76000E43C8E7C259B3A0324A5CA1F40F9E02B8C -:10E77000CB43E94BD57F7180FE3C5FF498A383E8DF -:10E78000729294817F18A0FE6BF25EFC6B3675DF8F -:10E79000C36DCFE574305DF2E1552582BE66A619E2 -:10E7A000C99F313D6729E9F7CC2EF46327FF87EC39 -:10E7B0006DD2BF7EBD6C37E372E93A8C33234EAF26 -:10E7C0007F5F2FF5EE9921FEF6EB73AE253DFCFA47 -:10E7D000103DFBBD31528F4E6369E27CBD89F4DF91 -:10E7E00062B91F9325BE339C4656C4E15EC23C26E7 -:10E7F000088157CF5BDCE8EF5AE6A5FC75CC47E90A -:10E8000077989FF4801BB8C040FEBB8CD1FDD1A38C -:10E810001137962DE7FD4DCF9F9E89EF75D69E54FB -:10E820008B01B7033D9F413E34183D7F869E792E74 -:10E83000C53302E7E323C54ED2C38E5833482FC4F5 -:10E840007E3207D92B7FCDE56826977347B99C4563 -:10E850007A8CCBD94C2EEF7EC5E52CF2D767AF650D -:10E860006837C3A9BFDFA3DA7FC7319D99060D2C96 -:10E87000C7BE33FA85A1B063BD1633A218787B2DCD -:10E88000666C31D6FB5A4C8241A461164A473D9FC3 -:10E89000D99FDEAAE83530DE0C1A2F14BE0A9EA1DD -:10E8A0007054F0FD27E039686CE195F0BC0CFD1E5A -:10E8B000F653EBDB5189E9F033CA78BA08C107EBAC -:10E8C0009F1F958075D459055C26354DA47472D36D -:10E8D0007866CA273F9317F0FD0C4B80C139C4CE30 -:10E8E000C64CD328FF3D495BD9099EE198C7D93C66 -:10E8F0007F16D7C8D827DB5BA2703FF3DC334617FF -:10E90000CE357546E72617ECE4AF19455CD0E5A394 -:10E91000A9F06FB25DFDDF97AEB32AF87909AE3F7B -:10E92000BBC64DFB8DC13B1B1FD06B8686897BC64A -:10E93000E45EC81B58CF19132EF8CCD030C11F1578 -:10E94000BE783B2177793F63385F4BBE3F9CCE3525 -:10E9500005C3DC45580F3F2F505C516F7604D92B0F -:10E960007E23E31227FBAFA6B8BC9938B7F3EFC6F6 -:10E97000F0A89DD8F7BF917189BF18E4B916EDAF23 -:10E980004DCB4B043CA630E157B9CE6A76F9F99CE1 -:10E99000AE1B2BF7E168365AC6F5E8CE1FCA4ED239 -:10E9A0001B6724393499653D043B41F10933D9098A -:10E9B000FAEEBB250ABF68EF898B46F09592488D29 -:10E9C0000D4A0BC4E784251A9833486FB739C399A9 -:10E9D00033687F4464C7EAF291AE21BAFAD1E3D238 -:10E9E00075E531EEAB74E58366E6E9F2834B27E823 -:10E9F000EA27CC9FA6CB2779AED7D54FAE9EA3CB27 -:10EA00002BBE972C3EB194C685BAF6C39A16E9EA96 -:10EA1000A7796B74E50A0FCCEBEEC88E075F147F05 -:10EA2000191B57EAEAFD344AC49BCCB42F9985FDE3 -:10EA30003EBCF507FA79195FD7287ED429F8AD973F -:10EA4000FF033A2A49D4F3DFE90EBD5D23B9D1A40F -:10EA5000CB6FF847F1ECB94A87E7507870BCBBFC44 -:10EA6000A8CFE5B797E74B7E5D69827E01FF45F051 -:10EA7000FCE1BF085E2FFC17C179F82F82EBC37F42 -:10EA8000115C0EFF457079FE093D9E0B3BF4781E2C -:10EA9000FB9E1ECF8AFE06C2C7F84E3D1D84E26370 -:10EAA000E2A7217421F1309FFFD31F1EE828C2E99D -:10EAB0007F7A2323FBDC37E1E58510BC4C1AE9693A -:10EAC000C77E9D3FE862AA0578EAF18CC079F233EF -:10EAD000692709BDC7E9E5EA00C521FCC048F1374F -:10EAE000270DAD1AF8B23FC5736C2CAF7F7B4E2358 -:10EAF000D14F222BDDBF84CFA7FC3FC2C88F533E2E -:10EB00004CC4EBB29C4E8A7350FCAE3C59DC237A69 -:10EB100063AC3CBFB9C47DA28EB1429F8D7439E80D -:10EB2000DE71458E88E3E0C7AED4F251A09FD76D69 -:10EB300023400F5B84DFA413F1C271817861E89BED -:10EB4000D0EF52A47ED5F207AB15EB18B18DE9E4F6 -:10EB5000E4489F5577EFF5EABD0E5D7E545BA2AEAB -:10EB6000FE35879CBAF25C7FB6AE3CFF844B972F94 -:10EB7000EC18A7AB3FF63DB72E3FBE73A6AEFEC462 -:10EB80004F4B75F964D6F330E03B4C13E77D2BE730 -:10EB90004B740FCC29E281CAEF8E1171A0D20EA066 -:10EBA000F469751FDA23E92E544F1F66117A6A4BF8 -:10EBB0001213E730AB3C6F31BDBEEE91F799959ED5 -:10EBC000CABCFAFBCCEA1E739F5E2FF576A51F0721 -:10EBD000DD637607DF632E97F1DBA1F22F6E9CB029 -:10EBE000EF85CE7F9845ACB7E50E0BC58DA879852E -:10EBF000CE67799EA0DBDDD6FEE377D2C769D47FEE -:10EC0000516EE99071BCDE6366978FEC28578CE7F4 -:10EC1000EAF4E25CF9238BEB2EE7378F577E8D58B1 -:10EC20004F99C170FBEC1CBA2F36FF9741E3E78D7B -:10EC300013F41D3F41EB777DE5D1E23E178BB638EB -:10EC400041BF038F27E0996861EB28CE48DEFBBF08 -:10EC50006D53DB7D23785199A5D54CC60BE63383E4 -:10EC60001E664DE3FA542EEC822F3E62E7FAC6632D -:10EC70004D26B2F38C1F37AC8C6B627D711CC3F8D0 -:10EC80007903F4019D05E79427C71B699C85E3C4BC -:10EC9000FA4A8C97FBEEDF93FF8231C9BF19DD87FB -:10ECA000E987DE880ED53AFE55F7F115DD86C249B3 -:10ECB0009D2F99943B99725E0A7E6A3F28F8A97845 -:10ECC00008E70A73E94E3BC555CCC43D3285BF9772 -:10ECD000C70B7EB409F02814F5C08F06AA5762CC82 -:10ECE00089863DBC9739A31D5F63EFFD17C62910C8 -:10ECF000FC078AAF1A883F5CC1170688B71A883E9E -:10ED0000E9EF1F88BB0AE20FE25E8FC4872FD34072 -:10ED10007EF4BB23F5FBF8857102BE1EB98FB97C6A -:10ED2000B5E7EAF90483FDBE65BD51F2092157A19B -:10ED30006FE0FBE2F566D237182BDD8A38A28FB67A -:10ED400098E97EEB64B773864BF8E749EF20BF176D -:10ED50009F5A85572F4FB97CDF093D780A736D8024 -:10ED60003FA372A3BE7CA97DC66790E78B43CEA567 -:10ED70004BE5797569C8B9F4A971521EBB988BF43B -:10ED800024E9E7AF9675FAE8C897112DED2EB43F48 -:10ED9000794AF7C2145C9CF0D7E407F21C7EE1D9F3 -:10EDA00090D3EB4CFDDED7EB83DF00F711CEE23ED4 -:10EDB0008213FBBD97E2AD7A0FD8849F52F983642A -:10EDC000FDB3DE8B548EFAE8ED5C6EC768E8217DFA -:10EDD000FEA3103F54AFDD10350EFDED33537FEA37 -:10EDE000BE45CD5F7DA31D41FE644FA75177BFE5B2 -:10EDF0008AF9AF7D8EEE5FDC1DE379077CFC8CC960 -:10EE00006505FEEEB11F89479CFC2C69B7099D6F13 -:10EE10009FDE59A4093FAC57C4CDF6CED4E81E00FE -:10EE2000E7830CFB46DD1B98CDFC7148953FC6B3CC -:10EE3000713CC159F9632AFCE3699EF35A969AC35F -:10EE40007995CE87D794843B037E9ACE1471EF6771 -:10EE5000207FCDDC4BB9D4DF4D9726523F17C7A595 -:10EE600009BD6BDD7D2B404757ED6566ACB333E4E0 -:10EE7000DEBB4A2B25BFF18E577C5ADE275AAB11D9 -:10EE80009DAFD498BA5F447C5AE52FB6CA7C89C836 -:10EE9000AF5A2FF29D66F1CECC1E696FC03A9162D7 -:10EEA0003D3817EF93F608AC0329D681EFE04BC845 -:10EEB000832F210FBE843CF81252F0257C5FC44A98 -:10EEC00053738DC2AF541CB46FE0572A0ED27BE04F -:10EED000570ACEC3AF145C1F7EA5E072F89582CBB3 -:10EEE000E1570ACEC3AF145C1F7EA5E03C1B775DE3 -:10EEF000200F3EE69EADCBCFE5FA7771D0BE855FA1 -:10EF000029B87FF89574FD7956E8DADFCA9A74ED6E -:10EF1000E1570AAE7F7B93A6F33BDD2EDF03A8DC2F -:10EF20003688E8E3A5D1A5AEF17CBFFE39E26FDFFC -:10EF300033E31C606C5F06BA5D591FEE12786E9D5C -:10EF400029F06E6002CF3D0B08CF6B2C225F22EEC2 -:10EF50001FF7E7BF29360BFF0D52F86F90C27F8372 -:10EF600014FE9BE2E1C27F8314FE1B7C87FF06290F -:10EF7000FC3748E1BF410AFF0D52F86F90C27F8312 -:10EF800076F0DF2085FF06DFE1BF410AFF0DBE9F5F -:10EF9000841F29E8DD0CE8E999BA731DA743DDB9A0 -:10EFA000CEA1CB434F0FAE0F3D3DB81C7A7A7039DE -:10EFB000F4F4E03CF4F4E0FAD0D383F3ABC739893E -:10EFC0005F425F0F6E077D3D383FAAD57B0CB6A32D -:10EFD0001BB69F7F156967A4F698C659C18A170E9C -:10EFE00094C1CFD669D3526338A7346B2F9615F3EB -:10EFF000BC47DEE31BCD7A0CC037F9D939DE3C7E45 -:10F0000046F78E477D9544E5CAAF4B7F1CEFB907A5 -:10F0100018E9FDC764BCA76AEF620E2352553F9002 -:10F02000EFBF5EE8F8AA1EF1CBA079F083612EEE67 -:10F0300099E4AEB1E7E1BEFC1E8326EE9BDE25EE31 -:10F04000FB86D2D56EC997F618F61F09C7FDA10A2F -:10F05000CD8538862C133B61CE039C1AF3A01FDCB0 -:10F06000373E46AEAB7102EE1FA9792B3B20E7136A -:10F0700014BF56D4C32C557C9C495F30CB62F077CB -:10F080008BD00BD00EE7C5ABBD9A7B67107D3F34AC -:10F090005EC8378F77C5842AFEFDEA7D8D13101771 -:10F0A000372B5CB4FBF9E35104C71BD7693B117FD5 -:10F0B00058B48FB911EFEA93F3BE7A9FC35245E378 -:10F0C0003A289E4EF55BB13D95E2FF2A586731E242 -:10F0D0002B5881C6E01F5570E3EB7B15EBCBE25B51 -:10F0E000C54CFAA788CB099771392A1E272CA6B4DC -:10F0F0000A724BC5E54C2A8829C1BD38D6CE5C08BA -:10F1000003BEA1A062FD60DEBFC7E776E15ED1A4C9 -:10F110002F1A8F517E5729E5890CC6D03824D7463F -:10F1200078357A5FE346EF0E439C13F1BA6BCDF16D -:10F13000A8BF8FB9A0EE70514371A76A7E39ACC3E6 -:10F1400060D38077767450101D710E7013F09EEBB3 -:10F1500032D3FB1BB34D0E33F846A81CBFF2DE6260 -:10F16000889E1072BFA465CD7BA9C674DC2F31B810 -:10F17000FCE05BCF4590BEA0F49D0A79DFECE2BADB -:10F1800063836FE1E515FB857EE0D9A611FF53F798 -:10F190004DEA337CA906E80B43768C8E350AF90FCD -:10F1A000BE78C6FBECCDD8A215EB8F515C44C5FAF6 -:10F1B000C268111725FC1055124E55F25E11CB7125 -:10F1C000C443CFFC90F31DF708BA97184D7185AD75 -:10F1D000429F53F616A50FAAF7632ADEC83F0EBC5E -:10F1E000573C2ADF65D95841F157A1F77C6AA5BE83 -:10F1F000B76C9D99EE0F2D0BD1076BE57DA1DA1051 -:10F200007DF0DCF8107D509E5FD47DDE8A378ECE97 -:10F21000237DA5D14C7EB9B2B5427F61FB990FF138 -:10F220000C656BA71BF06E48D9736E97D60F9DBC0B -:10F2300025F598599D3682EB9C4BC994DE7C298933 -:10F24000D25B2E897B94887D011D74BEC0488F7E61 -:10F250005BEA2DF370AF12F188DE30797F9291DE98 -:10F2600094CB1C25E01F57B9B5A350FB66993DEB25 -:10F27000716F73D60E46F1473740BF41FC17F41D3E -:10F28000D8DD0BD24A280E63A646F12C3714AC9079 -:10F29000F4CDE99D81DEBD927E4B29DF2717249DA9 -:10F2A0007BBC5D26C0FD06AF66C13B7C1E798E55DA -:10F2B000741C4AEFE511D2FE6417F6A53EFB132637 -:10F2C0008B476DBCD1B7E17E6B396C764398403C7F -:10F2D0008779648E281FF162F46DEB70A8F9BFB4D2 -:10F2E0004B94190C22DE89EB5BE0ABB7ADCEB52CAD -:10F2F0000AE22F5F4C9C3663626100EF8B42E2F4BE -:10F3000056DE333CE1EBE2452B399CB14FCAA33BBF -:10F31000BFC729945D3B81B98BF999750163EAF107 -:10F320001E3FEE052E94F9D52F8EFBD3463BC187A9 -:10F33000F2D327A4DEE625BE2AF8D6ADE05B46F080 -:10F340002BCFD409C4AF3A67001F11393DF21D021B -:10F35000299742EC10AB2738C57A43EC11953982D6 -:10F360009F339333F5568A0B76923D4FCDFF43B3CF -:10F370003E4EB3CF2F3241CA93E67F4D7CC3FFCAC6 -:10F38000F0DC86F56D3588B8F921C65626ED42B415 -:10F39000FF15FF60F21D8900FEB99E467E74CD11F7 -:10F3A0008C7FCF464DC4A90F60BF61D93D0FEF865A -:10F3B000FDAED9C210E7FA7896A0A3C77F60213DC1 -:10F3C000BCCCD2710CEF642938BEDFF4EF66B2CB4F -:10F3D00033FF70BCFFB5B0D1E6027FFE6262E92A5E -:10F3E000CC3B22C745F898C1B719FA3F9952FA7D2C -:10F3F000C2D7A6571E43DCFEF2F6348A23AD3894FA -:10F40000BB01EF897C31D1F3C309F0E3DA1D16C8E3 -:10F41000F186753124D7CA13645C27EB213F9582AE -:10F42000FF031384FDEABA2241C7DDF23C028639AC -:10F430005B574FDEE30ED927CA2E186A5F087DC7D7 -:10F4400061A0FDA3EC08B01B5882EC8ACA2E61CEE5 -:10F45000FE7001E46899451F7FA8D25795DD4D9E47 -:10F460000717F7C9B19C1909D09B376B0EC8B12A91 -:10F47000BBF396F13C5F75C28C1B986C56AC53BCC9 -:10F48000DF718F78BF6311DFAFE03765F23E56D58D -:10F49000B6F1B4DFAA7C3CCD1F785FDEBAF968CA4A -:10F4A0000BA01FBF9BE2F2AB1C6E4B6CD0BEAF6CCF -:10F4B000D57471FD2A7F6082B0C39571351DF0BB94 -:10F4C0006D759A056FE89471F502F7FB5E9DE0D4C7 -:10F4D000C555F37A74AF61563A3B2EDE4FE2F34ED8 -:10F4E00013E3E505F5BFA855FF3E01AF4F7AD1CB39 -:10F4F0001322097F150EBEEE34A40E9A278703C18E -:10F50000A9E73EDE9F93C6217C54FA7D669CBBCB67 -:10F51000709F82E7173A7C668CB3689D782FC4B3DE -:10F52000498CE3D918631905BDC9E4B0A4007E383D -:10F530002CC7D1FC880F5671B820DE4AC55D86C243 -:10F54000A742CEB7AA3546AF8FB56E36031F0B065E -:10F5500078AFA047D2EDA2755329DEBCCAE4A678E5 -:10F56000068F84EF472B6CF7C22FB060CB43E63495 -:10F570009CB32708FB738FDC77B3D2FDC3E95DA092 -:10F58000153617E6B9C0D14AEBEB83EF831C1E1A80 -:10F59000DE9F2925F872BAF0E27E5ED5163D3E0365 -:10F5A000F311F0ADDA5241FB6D89C9637104CF6389 -:10F5B000DB2BC3710F6501DFDF78EF88393C14DF87 -:10F5C000F4F183B7A4D23AF93CE91E94CB3903EFA6 -:10F5D000FC703A213A56F4A2E2B2D578D689222EAE -:10F5E000D33AF19BF6A59BF49A168E5FD8BB07DA47 -:10F5F00097160476F1712D55E2FDB5D07DAAF6A7D8 -:10F60000DA976A9FAAFDFB98B9D49FA805F80C97D2 -:10F61000B78DBFEC074E33E47C174ABC72B8BE1AF4 -:10F620001CC775CD4481D7B274FD7E477FE837652E -:10F63000A2D8EF65D3FCC31177A9EAAB71CB6245C1 -:10F640003BD03DE82D65A2A1AFFE4AAAAF8F47A9E6 -:10F65000ECE317FBD6C7835FECD748EF5D79DFD1CA -:10F66000947F833EFBB4D067CFD4ED6E4882DE68D2 -:10F67000F2A506BF8B55E517FC6131D77FC02F96E9 -:10F680004839DD9EE7C99918B47FAB1E783ACB2381 -:10F69000F88B1FFCE583A75FFAFD0467407EAAF99B -:10F6A0002FDAF85B73853D185E627DF766F7529C32 -:10F6B0005DA5DDE2C4FDE5CA7515C46F59223F574B -:10F6C00068017C87D241C53A8DDE17AB6C1AE333F3 -:10F6D000FE37F2E5CA4DB3E94D248527F5DE899260 -:10F6E000A76AFEDF95F35F28E978CE44B1FF16568E -:10F6F000A75996D0BE4FB35482FE65F9822AFDF712 -:10F700003E3CF5F9977336607F206E88CE279BCC00 -:10F71000C2CEB72F92F4D5332B9F7FF3665EEFF303 -:10F72000AD3B52A19FA8792C95F6BCC5D22EB7440B -:10F73000EAAD1C4F15C1785AFAB8C053E5336FFCD7 -:10F7400009EF7295A54B7E769F88E75FD4B69FF050 -:10F75000B660E366731AAFB762629AEE9E4C652399 -:10F760003FE872782EDCB8C30C3EB062A2805B2802 -:10F77000BD97C9FBBE0AAE903B5A90DF42D507FF4A -:10F78000DBCFC759BDC21605FBB41AE71149D7959F -:10F790008D31B118AFB2B1E2273877287E1FBAEFAA -:10F7A0004ED9C47E58C4FBC3BE3C35D54571CDF09F -:10F7B0006BF52757374BBCFDD42CDE6F4C8E687B26 -:10F7C0000270485E1EEE027FC8CCEC24BF31E819FF -:10F7D000F3B618C47B8F99759D17300FAE52D3FDC9 -:10F7E00014A478670A2A763CCFEF3488F8AB74A368 -:10F7F000489F97F0E1E57E94B3B84E7A77AEEFDD9F -:10F80000A4107AB5B05D1BF1DE8D258EB95A9C012E -:10F81000FA54FD28FA54F43BD0FA7E21F9C837ADEA -:10F82000EF549AB44764BB5211A7527EFF0817ECFD -:10F8300033DFB44E8B7C7FB06FBD9C58C7C5F6B329 -:10F84000DE4C716E1978BD5B4AE2FB596FE83AD520 -:10F850003E5177DAFBFC0BADC2BF704AE3F28BB7C7 -:10F860003BB5C246F7BFD4BA94FDFBDBC621BC3D15 -:10F870003156DA133A23A1479685CBFDEF17797CF1 -:10F880009F1DF45DC97DF55E9BE2CFA71BA55C645F -:10F890009DF7613FB3A60C7A9FE464EBA948BC973F -:10F8A000726AAA989F6AB7DA2CE28C59A4C589F7C4 -:10F8B0000FF9F9EA6413FC3EEB12E81C795B53067E -:10F8C000F185DBBC31C2FE20F5FB25920F46ACAEC4 -:10F8D000D88077BE176F4B73687C9CC576D7C7DB23 -:10F8E000A8FDD52EE883115B665BD249EF15E700D2 -:10F8F000E5275AADB1528A1B039FC4FE32BC920960 -:10F90000B9B3749B3807CC32B08DF0130E6B299DC0 -:10F9100091043EF1B04671E66CBBFE1DABB1F9A59A -:10F92000E7E9FC17F20EDC6A739B3B017C9CEB1B46 -:10F93000B0372DB69792DE5E2FF9E4C92D5DF41E27 -:10F94000BD82EB15F13F161107DC1369203BDCB7D4 -:10F950008D03AA927E254537CA2FF508FE331E7007 -:10F9600032925C2B3196D17B4A1BB64CA7B46A739A -:10F97000C956EF28C41F97C64FA0799BC94E56554C -:10F980003F5DC4EBEE0C8BC1F926D5EC4D0DD64B8B -:10F99000AB76DC4DF13F9FEEB051FC4FB163767119 -:10F9A0004C1CBD774CF175AA5E6A91E03B35F5D3EE -:10F9B00075F13B8B799F7867F3CBB608BA1FA6E247 -:10F9C00072EA123C494583457CCE78A788CB49A290 -:10F9D000FACE7EEDE22AFDB859C47904C51BDDB824 -:10F9E00080B7AFAB7F360AFDD43EF8F6188781ECBE -:10F9F00050C3D17F5FBCD136116F9425CF4BB3621A -:10FA00004B6F5E00F8FFDA48F01F68BCEA439ACEFD -:10FA10008F779B2F9AF4568F9F59E047F63818E955 -:10FA2000C59F1A5913F400A5BFA8EFE3255C3E8DCE -:10FA30006E4D057D2CDBF3502AE4CB6791225FB637 -:10FA4000E796DF805F79768509FDDCC4481FAEF458 -:10FA50000AFD9A55C7AAF7486DE59C8EA6174588FA -:10FA6000778FB6E9E3CDD53BB79F99C4FB3C883788 -:10FA700002BDBF6FF22F067EDFE7FA2BCEB1A9459C -:10FA8000823EDF6F35CEA07B437CA3400F79BFF56C -:10FA9000D948C4432B7DADC4F8811BEFFFAC7C4E2D -:10FAA000C405E37D7A7A2B54DA411AA41D64E50B70 -:10FAB000E619C971A47FD1973A93DFD21FFE6AA4D9 -:10FAC0007ED5973FB09FCE6D75FB84FE50D7D6454F -:10FAD000FA83D24754DC61EDBE2ED22754BB860395 -:10FAE000022EF507C4F78A6C83B2A3B8B54C9CA765 -:10FAF00035CA7B5FCC2F5F6B0ACEE795AF05B39F0E -:10FB0000A0EC233DA40FDE9BFD3B3A87D7AF93FDCE -:10FB1000F2BC3968BC6A1051A1F89E61477BA7EE20 -:10FB20007C577F2086DAFBEBC33742CEBB1BEC262B -:10FB3000A42DF57692FBDB1B0DD9B8A7EED6C25DDE -:10FB4000D0E3DAE5FDADC1B5EFDA603F48623D478D -:10FB5000F1DEAE3FC5F3C322DE6F025E773106E20F -:10FB600089BA0F7F928FFE270FEBBC883735CCDA2E -:10FB70009472F8295A8AE43A723AF341D7838F088B -:10FB8000FEFCA8996DA4779B4DA50CF67BBFF42FC6 -:10FB90007ABF32D0FBB3ED9AFF67C1FAD521499FF6 -:10FBA000A561C2CFB873B46713E6F15DCD3C2A9767 -:10FBB000EE1D1A87A3FF6EE987547AEA34C99F5372 -:10FBC000E4F9CA3224D10E3A56F7ED34B79BE23D40 -:10FBD000EFCA395209F9FCE31E2BC50B4CEB092780 -:10FBE000BD3565C84C9267EADD7615F77324C7E02A -:10FBF000C57BF43F6656712FC01AA2DF1A6C743FA2 -:10FC0000596BFFD557E0EBC9C60B47A3715FF6DF11 -:10FC1000347A7FB4BCF7E347DF62380FFB72291EEA -:10FC20003AC5B307EB39D93BB3CBC351F763479B15 -:10FC3000D525E4050B5E47FB1D5F45C51A02F3EBB6 -:10FC4000EEF998DE75ECEEB192DD765ABB7CE730CA -:10FC5000643EDD894EBA27CDEBD1FBCFDD7603BD07 -:10FC6000EF36ADFD28BD57384DBD6768D5BF67C8B5 -:10FC70003A52626057265B2A570EE25B04FE264723 -:10FC8000EBCF8BAF15097DF1B522ADDFF7EE55DC7B -:10FC90008A922B2FDBF7DC26EC52629F2E577EFEDA -:10FCA0004BE9A44FF4B6677CED3B166F43AFE0FA27 -:10FCB000C2856BDC6F171506E4EA3C0927259F55C2 -:10FCC000DCC23C09AF797683804FC8EFAE28BA0911 -:10FCD000A58B50BC2B7CB21F741C433C16C7E3A8F9 -:10FCE000FB19E1EF24E1EFABD7D7E3D985214677C4 -:10FCF0009727EDFF45FCF96D23A0473C68203D4266 -:10FD0000DD77F4C8F7DAD5BD4796CD881F941BC3BD -:10FD1000C95EE891EFB4733E700C7C40EDFF613337 -:10FD20003B47418E9EE44774CCAFD3D046DF532788 -:10FD3000A5D37E1DCA3A92E4FD9C42E86FC6C0FB83 -:10FD4000D444F72D9AEFE125B87F39CF4EF7DCBBCD -:10FD50007D21EF53CB77CCBB99E40FF3D53BE67C09 -:10FD60003FF3765B1688F2BE77CC87333A476DC98E -:10FD70006559D0BFD4EFFE0CF88EF9B258B29B3E55 -:10FD8000F2886F24E4817ABF7A4A8A2771D2E02B05 -:10FD9000DFAFDEAA952EC0EFC0784789F9762E082E -:10FDA0007F668F00B71FF69E934D91F46EB7A253F6 -:10FDB00065E71EE6ED7A18705271B57F96F4A6E0FD -:10FDC000AFE20AE342F0A0E8CE6B6614870B7C201A -:10FDD000CEA8EFF763D648FEA2E23A5F763991FEED -:10FDE00038D5933B09FB70058733D9D13BBF87F5E5 -:10FDF0003E7A47A41BF33B297FD722745F154D320F -:10FE0000287F31C50D944BF956AEE2049AF4710285 -:10FE1000A1EF9C860F2D9D0CB89DD3DE1E838FAF66 -:10FE2000FF6F63BFF74FAE9D24F84466A267C624F8 -:10FE30009273D374FAE4EBB99FA4D0EFCC5C3E3A52 -:10FE400014F2EF9694D2EBD0AF2D53F80FFE9CD462 -:10FE500049711E7F5EF0D714B23FAF11EFB37EDB66 -:10FE6000795E19D72CE861D562712F319935121D51 -:10FE70002706E2656D98C7FFB4B8E640DCF15EFA8C -:10FE80007D91979BDB324E0FEF07EF61479E75F236 -:10FE9000938DF7F0CBE514F71B7D64551ACF6F3CBB -:10FEA0007CB49CE27C938F5C4CE3B8B9F7F0AB2256 -:10FEB0007FF5918B880BDE74F898A80FFFC110C6F0 -:10FEC0007E72F878B997E3E38ED19EFB81AF9B2FCA -:10FED000351E8338FEFDDA398BD328AE75764AB6E7 -:10FEE000886B5D07BCCF8B5FB43E5A0BC4B5EE9BED -:10FEF00024DA755F10FBA0FB82A0F330F083C1FF12 -:10FF00007CAAE27B151F1E885FAA7DF8AF8A4F5638 -:10FF1000FB99ED716D348318BDFF74DCF093936829 -:10FF20005DFAB8E16E73CF63E457BAC09CE013AFDB -:10FF300044BEEB84BC682914718D5A4F8713F73186 -:10FF40008A0A44BEE54287137C1E79D8B7BA634457 -:10FF5000BCA38A8B6DB9E04FC23E2942FC22AF5F41 -:10FF6000DCD3530E3E5A84FBBC69E8FFF851391EBE -:10FF7000437FBB2E88B8C36E5B87D321C7413F7CCC -:10FF8000DC34F0C7A2D556BA77D472A17105F55307 -:10FF900066EF1B570B19D7FAF5E34ED782C6CDECA7 -:10FFA00015F19D18D7A91BD74F71C1BC3F8A3FEDF2 -:10FFB0008E7125E2DCAFF2C528E7F987E4EF54142F -:10FFC00039FD46C8011527956091EF71CB730BAFD2 -:10FFD000477199BB7AC53ACF37FB6BB09F8A25DF53 -:10FFE0002EB608B9C90CE12EDCC72E315E3E9E8CC0 -:10FFF000F3C90BE27C521C56BA1DFBB1C124F80DAB -:020000023000CC -:100000008B53BF97D6B1ECE7BCDEEFE293E9F7C5BF -:1000100086261E6499381F2F9F9903B9C1F5EE33C8 -:10002000C0F7EF58AB267E874BB49F3B3382EEA1DF -:10003000741F1E5188FD3327CCF91CE3FBB677D221 -:1000400057B44FE7443B0B71E2E93DFC5F229FE070 -:100050007C0EFE5D2BFB8AF473E5AFBD25E0AFFDA2 -:100060005F18A77EE6398BD0CF7AE89DE6FF9A2409 -:10007000DEA7E3FA3BE91F3DD7C97737739C852894 -:100080004F35F744016EDD974DE2DD5AD6137553B7 -:10009000907FF6B176F19E6D285D1F9E2CE4C0F234 -:1000A0004C3BBD77D69068B552DA7E6106FD1E8C5A -:1000B000A93413E703B7A57FBBE32F260B7995B6C9 -:1000C000C112F0BF73F9E10E672AEF65E318DBF1A7 -:1000D000FDF0BEF317448C65B83C8F79131F2F36A3 -:1000E000E9EABB51BFAF9C8967DA54FB9C97ED8F5F -:1000F000AF33C9F180E725E2FE44A8BC689812DB63 -:10010000F75E21C9DD381BDDBBCA344A7B1EAFEB6D -:1001100020BBA0F0DF26FF878DE2E876D9041D66BC -:100120001A44BACB20E37DA5BD4F9D637E3CC53309 -:1001300069CA60EAC74FFD18F7E742AF48626D34FD -:10014000BED2CF543DAE87D988C9C8DF7B2B321AC7 -:10015000FA85E73B93A7964E2E045D7BD947417203 -:10016000E27C44545330FE1A8C7ABBE73B93A75190 -:100170003BD5BEBE693AFB88E211FD443FF59906C6 -:100180003AB73618D9ABF4BB03AC83FC99AADDBBF4 -:100190009C4F7E44EF36B8297D8FF3CB8FE8BEDFCE -:1001A0007C4A3F68F6D0F793CDD594763637D2F7B0 -:1001B0000F9B9B28BDF9D6C802D0FFF2436BD947ED -:1001C00041F2B1BECDEC09BE5FF3EED4FEE9E8FB2F -:1001D0009385DFE6DDB4FECBEF57E593053EBB1715 -:1001E0000B3D93D3E53A47ECC0FA4277A4B897F0B9 -:1001F000D234717EED4E12F9C6C9E2BD50B7816DA1 -:1002000043FB97A65928FF6EBA81DE7570C78A7EB8 -:10021000DFCD32909E76FD8CA90D80933B9E7FCFE3 -:100220000BE4DFBD4A94BB8788EF6ABEAA7CD294F8 -:100230003E3B4296381F0BFF3BA777EABF0FBFC577 -:10024000627EA1F5D57DFA5078FC56EE5BDA17D0C8 -:10025000DFB10FD282F6458393F685A243457F0D29 -:1002600053C47ECD0C9374CE6517C10F320CE7E3F7 -:10027000041BF907DDF05FF0F5EC92F1EE57EC07A7 -:10028000E90F50FB41ED0345EFC97C9F097F87587B -:10029000C72463FF76FA87268B7577C447927EDC86 -:1002A000DD6E7640DE4C320ABF4377FBBC02DC0BCE -:1002B0002FB9DBDED81FFF7A53B6FFA7E1A0F8C144 -:1002C0000070B862FD1669B7FF07D74FFC0D7C7B45 -:1002D000B1B897194AAFED9395DD5DD0ED3B93DD55 -:1002E00007413FDD9ACD84734AB7ADFF7BE42F4DC4 -:1002F00013FB42D14FC31426DFA1E1EBCCB892DF50 -:10030000A9F5F4AD732923BE9729E38D43F1ABD64C -:1003100015C4F75E9F3C38004FC6B8BEC2FB195AE1 -:1003200067A773AAA2DFF383BF5A02F9357FB253DE -:10033000F8990C46F91EAC90277DDF3523C55D0585 -:10034000C91906BDA5E7B0F0C7F9F93909FE2CD8DF -:10035000A083E3AE2D53C4BA7BE7171A602738FF9A -:1003600017BB1772EBFC909E93D04BCE6F13EF9D93 -:10037000F31E6769B83782F81F277EB745F8418CAE -:100380000F7F7912FAD092878DA4BF9CC7B199B71D -:100390005BFEA0F89D3B757FB04EB66BD976F166DB -:1003A000FA7D334E9FD07F3EB235A4432F9EFEF0A0 -:1003B0008327F0FEFA92E734989BD951D8DD79FE75 -:1003C000E3BD46F13BAB32EE6486BCDF5FB35BDC82 -:1003D000EFAF43BC09F497033BB6E2F727EBF79A7C -:1003E000998D7F9F8177D2F8384BDB22F94192F7C4 -:1003F000BB451F377A2DF36E803DB97ABBFE7BCDAE -:100400002E7DBE2EE4DEA23645FE9EC148964BF7F9 -:1004100013B7087BB1E2DB57EABB5E82AF7BA5BABC -:10042000AFFB05BDEF6D3CFC65EA8776919F2DF330 -:100430005D3C7FEE4B017F05B706C9F3CF25B18246 -:1004400036BEBE86C33607EC000D2F083BC1F9B699 -:100450006882F3F2F04EF22BB0178D0EE861F71CB4 -:1004600032925DA1BEDDF633FC2E6DC3731ABD570B -:100470005B7F28CC27E0736109CA971EB2399C289C -:100480007F318CC1FE7C9EE30DF762CFA77412FE14 -:100490008157D825F8DF2CFC7E85C2BFF161E14F82 -:1004A0005EF284C4CFB65526C2AB4F63096957E2EA -:1004B00049E1F95786A7FAF08476D31FFEFD7189CA -:1004C0007786789BA3DB2AE9773114BE2D873F4AD4 -:1004D00085DEABF06CE478FEA16AEF94EFE17D0D70 -:1004E0009EAB8167FB3F8EE73F423E1692DEFBF1FB -:1004F0004FA1F7465AC88FAEEC1ACA6E31B8F6DD76 -:1005000063717CE0E189CF929E5B1E7BA67E052312 -:100510003BDAB5536047BBEE0DFCAC2FFBDDF54F6E -:10052000E5823E5ACC9DF4BB31DE18F1AE7C77DA21 -:10053000ECEDCFF3F18A63BF4ADD8F7DF37218B91A -:100540004FE6CA7D893F6BF0BB80ED36B2B7D5B7B9 -:100550008709FBDA01BDFFAC3B49FC4E5F89A5A7CB -:100560007C05F472DE1FC651E7C1DA76F9FB2FF283 -:10057000FC56ABEC0CFB42DE8772BC41F5EAA68868 -:1005800078DB8C84494EF0A19605CC139EF175FC66 -:100590009E11BF57BF9737A01E3800DF57FA1FF3D1 -:1005A000EAED1C8AFF2C95BF2FD9B73F64BE7AAD08 -:1005B00037CA6A24BAA3771BEA1E15BFAFF809E849 -:1005C0002E2A404F0D323EEDD8F77F63C2EF3475CF -:1005D000EF12F7233887DC8A7BFA67DB443C5C4DFB -:1005E00041D718BF13BFD321F8D0B27D9ACF99D687 -:1005F0000F1D31DF06F1AE7D083DEDFBFA770FEF01 -:100600000DF091517FE7F0DC51C2A4DCF2F61B3F04 -:10061000D927BF427EC7E37F5A3C776F0E5FCFD7A3 -:10062000F81BAF4DD4BFE3729D53FF3B4DDFC9D6DE -:10063000FF4E53AF5DC247EA834A4F3D3445C8F190 -:10064000D054C1F706977E1C752EFEEE38FD78B3A8 -:10065000DDFAF1BE2D5EFE5571ADDF04BFE372DC45 -:100660001372DCDFC871FF5938A974A0F1FE7F4D09 -:10067000FF0F822563C60080000000001F8B08006A -:1006800000000000000BB55B0B7C94D595BFDF7CB0 -:10069000F3CC7308210904C2242421608803245464 -:1006A0002B94C9D300D6065C2D68840152C83B80C8 -:1006B000B5D2D6FE3208222F5BA8D1A2224E82E10B -:1006C000A1613B118289863A286411AD1B698BFDBB -:1006D000FD56DCF828F23213A374E5575DF6FCCF23 -:1006E000FD3E321942B5DDDDE4A737E7BEBE73CF6C -:1006F000FB9C7BA929CE317C394588DC9873E69E2A -:1007000008215CAB7A8A12B385E87B43154D0E2134 -:1007100084DB7BBC3E5688DA8EE1625332C1257D94 -:100720006F1A00B78DB36FA2F18DED7F781BE3BD1B -:1007300007558785C65F6BFF280AFB5CFC325C8827 -:10074000E158F7519420B8FAB2C2F0261A77103C5B -:10075000AB5515FE4CDACFE83363FC62AA0E7BCDB5 -:1007600082DA929656730FB5557B5B79FC0D9F69C3 -:10077000F0F8DEC641E376CCA7B6CAE88DB2537B6B -:10078000BE5DDFCFCFF3AB53159717FD7BFF10B7DF -:100790000CF35ADE895B4AED15FCCCBCB6FDF4D0F7 -:1007A0000B996E5A57D341FB440CEC53D361D26082 -:1007B0008977756A6B510CD14BB428228D9A8B6264 -:1007C000AB584DF4AC6A6FAE16D45F95718F49107B -:1007D0005D023EB518DFA71F8388A37576FA8BE804 -:1007E00077D1F779D452DAF755DFB1DB5DD4063A29 -:1007F0005F8FC2770307697EE6003ED35D44BF1C6E -:10080000B4662146D0BA83AF4739687CA3EF7549F7 -:100810006FA39FCFFD9A0607A8653AB7AB7CEE8A17 -:100820002F55A6BFBEDFAD2E95F799D59E168973BD -:100830009DF4C9EFCD7539647FEAE232E07F226131 -:10084000418E9ACC78BB000726CE69DE44A854F9C5 -:1008500068DFCC6BE9B654DBB7CB24E6FBC0B7D47A -:10086000035DA3483E4E140F9F4C2357E7DDE33250 -:10087000F0BC22B33B7505CD3B19E188B4D37E0FA4 -:10088000158F8B045F5F438BFEE25D6637B595077E -:10089000E5F74EDABBA3206F270F4E553DCAC07E49 -:1008A000776ADF15C2C3ED00DF3CCCA7726F63042B -:1008B000F619E09FEC9FEBB2F3FC13DE77EEBA87FC -:1008C000CE773223DC09BE749945B98FE5843E8228 -:1008D000EF752636820EFAF7E6821FB42E9061601D -:1008E000BEF6B69BB479F7348B41F34CCCB78BCFC3 -:1008F0000DC6C7EEFDE097F7D0FCEA675461A1EEA4 -:100900006AD38A389CFF931D83F12BD7E85C6DF284 -:10091000C7C505C96B75C7557D8960F9EED0F5C3AC -:10092000C1FCD4F978324395782558BC8250AE6E1C -:100930006D66B92675F3D8A6702BECD4268677277A -:100940002B74FEC407ACCEB584FF738A366EA03616 -:1009500086608384CDD45AA97DC624FBA1B6583FB6 -:1009600086D8A9106C2A1E976348A17DD4D6C9E009 -:10097000EBAB335D8FBA088FCD334B66CC043EA210 -:100980006F99A06FD65C8AF08868210AD5F79EC05F -:1009900077FB0F9A04EC478DB5A3F26392D37E27C1 -:1009A000290AE1DDBFC3E4F5B0FCB9229469422C09 -:1009B000BB49EACD270EF734751CCD5F63E0F355D4 -:1009C000B7A85E1BCDEBAD271210C93F6D4DFE01E0 -:1009D000E4B5FAB86AB7D2B9F37DC9BF9A0EB8C503 -:1009E000E4B4D0FA5A1F75125CBB57F13AE4FE0228 -:1009F0007A597313CBBA3863AB4D1159D4AEE9337E -:100A000063DE99C38A788CE66D0E8B6A02DE3599B7 -:100A1000B3CF2951D4AA5BD627D27ECBB79B3EEC6D -:100A2000B1CAB557E8BFBACE6D2CB715DEC1FD55BA -:100A30007B07C335C23800D3FECDF8E36621DA5C0C -:100A400091B1676EA0BF2788095754D0697A3CF4EA -:100A5000E104F84AF2241A88D82385B86F92331E2D -:100A60007ABFD1E8980D3A043A4D76D0ABEEF081DA -:100A70000AE0EDAD0E731AE8A8B5AB5F61BA06BE29 -:100A800020BADF486D82E0F30784A46FA05DCA79C5 -:100A90009D49F15AB19E68C8FB5915EF1A1A0A7898 -:100AA000FAA3D83E09510CBD58B520C7003B073505 -:100AB0001684CAAF747D506C46251AADD4FFEF1969 -:100AC0007BD4614176E23F5D298C7F8159B87DD42A -:100AD0007F5FA4331A723FD61A9505BCC65A93BCE1 -:100AE000A0FB5863DF1A7C7FF328C5F1106D7D24CD -:100AF000EBE5C90AE0DA0827E44449586C043D36BE -:100B00008F5A6C84BC8FB5FB324A3207E0028C43AB -:100B10001F8497BF5714E136E23BCF8D54FC06DAB1 -:100B20003F6023FCA02746BB09F8054C121662CD96 -:100B300020FCC82231FCFF8E9F9DF08B18C08FF8DF -:100B40001D8DF59F67137DA84D9A2B4437DB8515C6 -:100B50006C17747A5E24792F205EA529526EAA77CD -:100B60001C29C2788DE85E8F754551F21C45380FFF -:100B7000E030D9AAB9925FB95A7B7FAEF42FBAFDA3 -:100B8000ECC8751973A9DD9E5B62465BA866C6F763 -:100B90000C61EF5729569693CF49FF608FEF5DA107 -:100BA000D8533306E45BD7AB3AD975557FAA7EBFDD -:100BB000CB2C52F0395777068D970BA9D78B56DB84 -:100BC000ECA9C17A043D237A94DB2B6E13A46FEE5B -:100BD000D571F6D4A9D4AF5E340BC89EA65FB1F42C -:100BE0007B256508FDF285E865FB60D86F9372EEA2 -:100BF0008F54BC6B09FFD4DCC17A97A4E941A35B95 -:100C0000E1F3357E6564D853AA7841F33BA9737547 -:100C10008C7638CC2BCFF5C23FDE496029FA1B62B7 -:100C2000594F7990ECD7BF68E7BCD3E83F02FB711E -:100C3000CCE44BB6D3D0B11AAB13FB2F1014E89011 -:100C40005D2B15DDDC9E0AAF6DF3F3E69E3190AFB0 -:100C500077DD1627E2B0C6754D91B0E359629DFD70 -:100C60004C06820AB1F7CAD4EBC7332438E28CCEE3 -:100C70001738628A53C06F9DAFDB735D79B939D77E -:100C80005F5FF5A7B6DBBF03FB757FB3395E8A49AB -:100C900077C6B401BEE97CAD131EC65BE7D755FE2F -:100CA00011EEA3410FF5E25CB633CFAA82E30A8DC1 -:100CB0007F56FA1D8A7F3A7D676A7C58DE21ED51A6 -:100CC000285F757AFF9036C4F7C98FEE607E080BF7 -:100CD000DBBF50BE7F135F28C22CC5507EAC458061 -:100CE0009F8906691F1397919C10DEF708F7E11E94 -:100CF0006AEF0A7FCBC472A8F1E75EF087A6BE2B2D -:100D0000BCDFCF48FEBFE34F476EC903C17A18AAC4 -:100D100077D7D3B36A87F3DF75BF479686F42B4442 -:100D20003F43F44FE7977B7514EBD9553EAA2D52FC -:100D30005F357E45D0EF90FA863FE87B35ED8AD768 -:100D40009FFC2DF44F21C4896F8F85E89DCE9FEBCA -:100D5000D91DDD4E9D16FE63763AFFA9141907785A -:100D60007E62F136034E3794C3EE9D9A28DB039AD8 -:100D70007D0B6D4F539CA3901FDB94717204FCF5A7 -:100D800029B3BE8FCDDB4CF89F5ED33D6625AD3FCA -:100D90009D2BDB53880B836057985804BB7E7AA445 -:100DA000C5033A9D5626E4C13F9C561EB85DC2F16C -:100DB0006607E005F17976824F99E47CDDAFE8F6CD -:100DC000FFF482EF14F03C451C053D1C8A28E1EF3E -:100DD000284A4C31E173FAFEB4296BC5C0F99B7205 -:100DE0000DBCCEABD96FC283E9DEF753C5DB445DE2 -:100DF0008BE05208FFE4BCDF14A750FFFB3F1B371A -:100E000019FC75AD1AFC7DF8EBE41B016FE37DBEA8 -:100E1000F7659F6971905FBAEA270B3E93FD6539CC -:100E200006E84BB9C64357CC8468F0A7DF3B2E1ABF -:100E30007E47F743FDC70F44B883F8768EFC9418BD -:100E40001F044F783429D88F1DD9BD391DFB949BC1 -:100E50003D594EEA3FDBF87412E28DF2DD8FA47348 -:100E60001CBC7B633AF299F2A6CDE92E86C3DD9CC9 -:100E70004F19E5B92FECBF79D7A6A0B8BB2A5F659B -:100E8000FC4BAD470AE16F67DFF0E9C3769A97F64E -:100E900033C50EF1BA57743F0CFFB810F131F2B7F9 -:100EA000062BDB73DACF05FE374FF8FE73D0E31362 -:100EB000191F99CA68DEE55C23D367A1F06E89A784 -:100EC00071B141B1378BE0F9631A317FF13AC59CBA -:100ED000003BB062D864D58175C3188F251B267777 -:100EE000A17FE183B27FB6C57BF024F6F98DD9D915 -:100EF000EC607B9352326900FFCBB9665EB7688BBA -:100F0000C2F1BFFE9DB427E21A83CF7959E3BFF83F -:100F1000CAA2802F3FD0F872DB83EF1C4DA07DED7D -:100F2000B1EE2BB01B6F3F7E26D54FFD0531E7326A -:100F300021E76966F75315387793C5897364672588 -:100F4000AAF1347FCA8F731F43BBE8C1C54F55C098 -:100F5000DE6EB772DEA6E3B74A711A608F5F6FFC70 -:100F6000E112D0EDECE3568EDB57358E8F1743E858 -:100F7000A9DEEE21FE3B28D1D9576FE5F6857ABB75 -:100F800070903CECAF4F60F8B7F50E6EC57C295FF2 -:100F9000ABB4FCF87AFB4DFD325C38289ECDDE60A8 -:100FA000130EB2534971AE517974CEB489354D1BCD -:100FB000B573A5D1FAC99EE47CD0217BE3CA2E8407 -:100FC000BCE63C998FBD797243128CF2F2073FD890 -:100FD0005941E373F34AC6E551BF75C7675C57785B -:100FE000BDE39185A0777993459E4F3BF7D9C7D351 -:100FF000E39FA2FD3D6F9838DFAFDBF1C1CE8DD40A -:101000002EDDB2D21C2CEFDFF6BCC91A3EDFA4578E -:10101000D7A3C33FAE579B93587F9A48AF32FF790F -:10102000BDAA7B700DD3EF81BC92D9A0FB59932749 -:1010300009FA7476C20C9673CF6185E9AFDB717DD6 -:101040007DB176DE2A836FCBF4E4013B7E496433C5 -:101050007D8F747C928EB8F752FB82BF7BEE437417 -:101060006E3F9DBB9DE8EB1F7FEDF834B37B9C93F7 -:10107000CE37CD20E3DD6BE2D63C83562FE83697A2 -:10108000444A9A2BA8CB68FE93FC98279AF0A9EEC5 -:1010900054FC6159F067B79E3322DFA3BCF1C3E073 -:1010A00038827E3E0CF2DBD7C3F79BDA5AEC9336DC -:1010B0006077BFF36783F007F9E99B7BC2843FE861 -:1010C000BB57F313EA33139F7A3B46B25D00DF8CC4 -:1010D000A8C7754C68027CCE2CF9D87B88E22659CB -:1010E000C711EAB481739EEBB890053B1B7ADEDA38 -:1010F000972FB07C54B73FF299C2E79F75CE98F511 -:10110000CDE73FB2FB4216F877CED4330DF956AF98 -:10111000B9270B7CA87D45DAF37F940E7A7FC5064C -:101120003A08E979AD62653929542F72DDA0F7B824 -:10113000AC1BD476EC627BDADF29EB377586EEA246 -:1011400078D43B567CD0057BD69F20F328DADF0588 -:10115000BA4D1FA7F941635FD25CB26B2F5E950752 -:1011600099FF9D85FE8EC73EBE6AD80191152E104F -:10117000579C873E53FFC2D5C9EB21E767BD23A625 -:10118000C03EBE99F5B75AAEF7BD1A6E5739EEA1FB -:10119000DE20FE5D3D875715AE41F58070E10A9A6D -:1011A000576776FC80E3E313AA405C573751EA9314 -:1011B0007859EA53CDBA23E684A0FD76429F186F92 -:1011C000192FCE7EF56FAC975B66BA3AA197E1B066 -:1011D00085D82F21DAAB28DA3CE27FAD864344A7DD -:1011E00096F717AB3C5ED7AE8A91589310E94DA3A2 -:1011F00073148BAD46C4D3B3856F3AEA36C2D8F3C5 -:10120000CB5B687CCEABEAD44D82F3A745259C57D7 -:10121000BA5357213E32281A5D7DD97383FD599EFA -:10122000F453D35585FD58DFC8708E5366CDAF2972 -:1012300005BEFABCAC61721EEDC37196F0F665CDC9 -:10124000857EFAFBB2E6450ECCBBEBD5F015EC176C -:10125000852FFBAEA0EF84E5CBFAE8E7E447202733 -:10126000759764BDA350FDEA09C4E7AB0E93BC209B -:101270003E3424BF6B801D273A83AF1788AF2EF80A -:101280001FB770B9A03F934678A13F75FB15614425 -:101290009DA8C3D2843A52ADA9270EF2BCB1FD4F2E -:1012A00066C8735DDB3B66C724AC9775275248B6AA -:1012B000E3759AFFAA691FFF2EEA7C35C7A517AD13 -:1012C00031BEC3F97BD5C156CED3AB859FF3F4EACB -:1012D00096C1F2D29FE0E0BA48A87E84E53B06E9D9 -:1012E000C5ACED522FEE52C50AD839A1D569672594 -:1012F000C4733C32B04EC6BB2EF5C2C3885F022910 -:101300008A53A1AD02619E75888B3CE9329E09FC2F -:10131000EE85EC656C57BCD977D0B9025ABC3B6BF3 -:10132000C336A31A84CFAC4E59970C8489F243CCB0 -:101330006FF768F041B84A22F27358AFB2605703B2 -:101340000659470D3D47BD562F3A817A52E600DED9 -:10135000731213A51D135E969F2E83FCBECB40E334 -:101360005306D62FC997EB07F2215907BB9E5DD9CB -:101370004DFC2923FEEC253EA37D9EFC7119D999D5 -:1013800016F2C780FF95FC315A5F7D06F7BF58EF14 -:1013900064F860FD4D0C1FAA7731DC5E5FCCEDCBAD -:1013A000F525DC7F02A87E17FF7BBA11F2D0051D60 -:1013B0001B35009F8A0981470D9E7F2A46190C8F95 -:1013C00052787E76FED38D1ED48B66DA35FD764458 -:1013D00022FE3A6B9375A8B33659876A1DE5BE2580 -:1013E0009FC6CB66ADDD2DF350573AE615C42CE011 -:1013F000FCB59FF257D8A395F9EE3CF0E5F8F1FC67 -:10140000D46D6C276D5C073D75F70DD15C077C834F -:10141000F271FA746EC6D475D904E746282CBF64FD -:101420002F6E2CD1F34ADA27BF53DEA314AAD56559 -:10143000D87FD548DB54D8DFCF5DEEDB80874EEF19 -:10144000A251CB53110F75991CEFA28EEBF9BD4938 -:10145000209FD2EB7DFABC0E57EEDD58372B63DCB4 -:10146000BA29B03BA464B0732EB368015E2E43B8B2 -:10147000B296ED96C3083B70B726C7790E1917FBD5 -:10148000CD0E630CEA3761B9B11E5AD7A5F1F9B890 -:10149000C6E7131A9FDF429D8CDAB7A91F6D37F597 -:1014A000A39D01FA4A7965BA3D915752C6F22BFACB -:1014B0009200EB75C1D9D02F696F9220D75B34F9B8 -:1014C0004DD0EC4D576E49955CE7E37DAAB47ADBCD -:1014D00005ED1E443FAFBE6E60BDE076DE8DC2639B -:1014E000859D7F49E69D6234C52304CF7B299EED0F -:1014F000906ABD23F363D2F37953651E200E58E43E -:10150000BC04470EF464AD566FEDF51A3C26D4A723 -:1015100063BAD363E07F35FDD2E143FFADB2BDAE28 -:10152000994230B5AF28F27C35F3BAD38761BD62FA -:1015300033707DBB498E9FD4F4AF2645DB4F3B8F84 -:10154000B0FA92C08FC0E197929610BC29C2BF4CEE -:10155000DA7D7F3ADB6BE14F9F07BBA8F8DE174EC1 -:101560008A2B0BA62E318E043D7C3B015717E42CB1 -:1015700031DE8CF1D6F7EDC1E3237C498A1D70B6CC -:101580001C1FD1BA7398330836BDF83EC6CD869C71 -:10159000250504CFB1788FD7436E7E2BE5CBB6BF40 -:1015A000ED0CE856D521E3F6BCFD6D175F845F6E48 -:1015B0008B74C2BCEFCB4F667AAFEDD8B305F2D6D1 -:1015C000DB2AEF0336B5FC69E7CF799E05D724B453 -:1015D000AF2F5BD077561EFDE362E03527DCF705C1 -:1015E000E0878ECE643CE70C977AFDC8D1BC25D04D -:1015F000D3DEB6FD3F81FECD89A68016F8BC60E340 -:101600003A44E5810905D0D3DEC8EE85D8BFF67926 -:101610008B13725A79203E0FF58143F9B21E5E3169 -:10162000716B12FCACE1E57DBB7F8EFBD5E76D7C79 -:101630002F541723E3BC4AB571DA4AE6DFAEDD4F1B -:1016400003EF7D36BE9FAD40AD8AE08ADD695CC7A1 -:101650007FE5EB8F16820F85EA8EDDE8FFE2399B8E -:10166000017438697645CF801E9E3471BE59A1C180 -:1016700015A7864B7CC27B8A987FB15B93E0672B72 -:1016800087FFF476E03D47DDBA13F98ED863E1BBFE -:101690008973FB886EB4EE5CB3690AB8DCBB2FD2E9 -:1016A0000879B9A06C5DF814F66F96F32ED8B632AF -:1016B0003D3DCDE305BE47F304ECD60565DBA0FE5A -:1016C00073CD7BB2908F9E7F7E0EE7A5BAFCEAFABF -:1016D00052F99C65905F644B40F6A852FB5BD83D85 -:1016E0002282FC6D85069E3FF464EF536260FDF933 -:1016F0001693DF4C34AAB08875D698017DA84CBCEF -:10170000B518E7AB3434A6236EA998DAB3107A7112 -:10171000CE26AC0934EF4DCD6F551E5C3317F1EF7B -:10172000F5F0B9A2D9A34B09D27F5D6AB77983EFEF -:101730002543DBF7EA85FDADB401F8DE15168EE131 -:10174000F5FDDE34FBAA91A7D5C648FBF13ECD6F6F -:10175000213BF6B5E6EF16AD1E3CBF3F3F86BF5FAF -:101760006BEE4987FFD3F70FE46B7EC3D8930E7BF4 -:1017700015BA6E0EC211D8911714B6239507950F9E -:1017800054A253A5D5E355411761D6CF69BCA2C871 -:101790007509D334BAD3DA0D05C9FCDDCA169BCB63 -:1017A00046EBAAC27AA210175547F64421DEE97D1E -:1017B00059154D1ABB62E334FEA4682C0BAA3756A8 -:1017C000F84C2E5BD6107C46FC44F396E36FFAFE91 -:1017D0003305297C9EF2F670FE9EB0F74C839C96F2 -:1017E000EF18BC0EE7B207E95F6FFBAEB8E0BC3C98 -:1017F00045C33BA07CC07A12F8FAC324F0BDD220C6 -:10180000D6E1FEF23CADC1BD26C1C22A61BEF7AC35 -:10181000FC6B4418E4E5FCA56AD6DB5EA587EDDA2F -:10182000DB0573D92EF59A7AD8AEBD7EF42EB60FAD -:10183000BDC37A16C24EBD5DB05C8E8FEC59E8A078 -:10184000F1FD3A3C46B0DF7FEF680DDB8F39AA7CB3 -:1018500057217699ECB21EB4E1543DE71726477044 -:10186000FE7DBA40ABF70CF087F32E5D6F7A85638F -:10187000FF41E8617904D775288E6A7911F1DE821B -:101880003827DE6B94639D940373F07D636CCCE525 -:1018900065E0CF1DA3DD450539B8DFECE13C82A44E -:1018A0009AFD4DEDEF2C9C4F064C7DBB61A7D247B6 -:1018B000BB6717101ED5E6EEF5D984D245534F17F6 -:1018C0004AE4B355698FC41E2957BD99BBE43D8DC9 -:1018D000765F79B7467F41494C23E44291FC7DBD58 -:1018E000FDC05BB02BBDDDE3D81E87EACDB9F6C7DE -:1018F000A2601FFE4C7EDC1394EFFF79F11EBE67E1 -:101900009D8FF720D42E5937581EFABFBA83F33E65 -:10191000B125A81F72D830180E9523C8A37F90DD7B -:10192000F130DDB76B7A5595D75D0B3A5C85E711E1 -:10193000AC06C1AF85C021F345898C13B6C3FF1334 -:101940003DAAC7F84F719EBEDF2460C7D792FF62E1 -:10195000B82DDC8B7CC5B09FFC53ACF44FF00B551D -:1019600051DD5C9FEA6DB3F07DEF431D9F24E1FCE8 -:1019700024875C87A9EA78290EF9FB3E2D5F203F7A -:1019800018C7EF63DA3AE29077E8FDD5065F3AF0E0 -:10199000A28888E375BDBF46F5A703FF2AA53B0BC8 -:1019A000E3FBF2EDDA7C8255C082CF51AD487D1762 -:1019B0001D2ADBF350BE3DA9C92BD9852C7EDFF152 -:1019C000B2AC0FE876A042B327AFA13F53EABD5DAA -:1019D000BF57A2A515D0F721EC4342811E17AFE0F7 -:1019E000FACDE3050E096BEB795F595FE2F1DA5747 -:1019F0002E64A564629D362FD80E8D1BB02BD0FFB0 -:101A000004D6FF874C7174AECA9D8A732DEC54E9DD -:101A10009A229A2E961B571671DD4C78386F0BC59B -:101A20002B548E2617483A551A8615C606ED779E12 -:101A30006C7AC214B6337ED89D1FC53E5A843AC50F -:101A40000F4BE5BB81ABFE2658CF719E1DD28E4356 -:101A50006DAE18AE95E3E52B1AD7C70F8147289EC8 -:101A600015EEC6A238C7B5FD3ABEE76D3A7E79A637 -:101A700011C17498BFA66804B5CBADFF2C1DE479E5 -:101A8000CF7758FCF0AB15A52BD7470F2137D7F8E8 -:101A9000831D41FE2B05FCF5F2FDC6F5F00F6DAB85 -:101AA00015FF29D48B04E95533EB17E94B905FB848 -:101AB000B920A4EE50BE782CE26AE15E3C167E8628 -:101AC000F46AA17388FC920CE42803BF19F1701B1F -:101AD0008ACF5F0AE4BBA49B0BA49E6F99E90AC05E -:101AE0006ECE500D1C8787EEF765818C27BAE322F6 -:101AF000EFD7DF7380D9335449B74443FFDBD0B706 -:101B0000C4B84807EE830AF3C3E5BCC3363BEA37E3 -:101B100081C397B9BE1B783862BEBC378810236971 -:101B2000BC2B615253B01FF975A13C6F78B68C5B2A -:101B3000EA324C7FBF3E941979B53EC47143663892 -:101B4000DF97F4B67FCE7E2BD09963C7BD466F3743 -:101B50006587A44F755FFF571CFC6B6FE75FF81D2F -:101B60005AEF579FF0FBB48DDAFBC0D7DAB5F75DBB -:101B7000DD8E48F4078A3F2AC2BC4D5A3B5027905D -:101B8000F562BDD5F35FBD1E1094078F2E1C3A0F72 -:101B90008E714704D7091CF143D55582EB04A9691E -:101BA000B24E801675825493AC1300469D002DEA08 -:101BB00004E8479D0030EA04805127008C3A015A1E -:101BC000D409D0FFC57CF95E2640422CEB97116CFE -:101BD000DFEF6B56BD88CFEF3B2CEFA1EE6B54F8D7 -:101BE0009DD645FA3EFCDC35EF750E6AEF757CDB61 -:101BF000F85EAFAE4D75825575A6BE63A8EBD4B541 -:101C00002ACE35B02FF5F3F9FB1B3B73DE2D457F54 -:101C1000B3C96970804F97E250AFAAEC6CE6FA53F3 -:101C200041FC6133F3B74511A897DE6591796E8D5C -:101C30004ABD53F83E94E3E01A4B37E71F557B1536 -:101C40007B59F07DEE4D9FB11D586B8B6A029E351E -:101C50003E9BBD6C88F71F7C2FEC1057EF9B97C9FC -:101C600029A226A288EF9B97E19E995AA17E65E45E -:101C7000FB634A4C87431EF1AE2A0366DD2EF53E18 -:101C8000E43D556567EBFA4471ED3D342A03E07F8E -:101C9000E8FDB3BB3032F64C380C85988CB8A9F807 -:101CA000F1B2FD6DF4BDFEAD168E3B56E6BB97431B -:101CB0008E8E995C5C273976D8C6F9D1C7DBC60F02 -:101CC000AA937CEE725717F2FDFC68AE5BAC32292A -:101CD000EC97F38BC7C5F3BB81E326F63F1DAE92AD -:101CE0005ACC5B35C9C1F5A9428BB89FF7D1DE69E3 -:101CF00051CBFA54B856F11A085E2C9C66E8CF22F4 -:101D0000221BCB8B296203DE532D12F27D832E37EB -:101D1000ABB6291C1770A1200EF79292BE8B3AFF2A -:101D2000ED32DE2F2CB5C8F835D120EFB31337C90B -:101D3000F72D3F126E33FCED72F28B68C94FFEAE89 -:101D400087FADDE1A393647CEE88C7FE8B4F98F899 -:101D5000BD6F61FCF7D3DDECAF0BF81D83E2BF472D -:101D6000BD72C3F5F527F41DC33193B42F4447CE9C -:101D70008BBA20975C9F71737BA2BE9CDB1933A545 -:101D80009DBEFA2E91786407FEE17DEF235F4C8CB7 -:101D90008F74C2DEE97A7FCDFBC430D9EAEF13C776 -:101DA000502B82DE276E713978FF44C3C9A90ED04B -:101DB000E3AF114ED0437FA7B86566C92EF0C915B1 -:101DC000253CF82EEE51B6125D8B701005756E9F96 -:101DD0004B45DDFAB062E777D1D7D8C96D0FE31D67 -:101DE0004F5DAA62571CA8876F2D8C23BC8B529223 -:101DF00019EFBA76592F650AC5A19EAEE983CBDDEE -:101E0000563862A07F8EA617BD345FCAC92D5EC842 -:101E1000DBB7A8A33E87F91E6173366BF91AF83E4B -:101E2000E786315C4FD5E5A6BF25BE0972F346A112 -:101E3000F433A5A5EF98100774E5BA8FE2FC0BCB3D -:101E40003E7B388ECF37741D8BEC28DF4B86D6B1A6 -:101E500074BBBC5BAB83C37E1AB53AAB51ABB31A50 -:101E6000B53AAB51ABB31AB53AAB51ABB31AB53ABD -:101E7000AB51ABB31AB53AAB91EB772BB87DBB7EC8 -:101E800035B7DDF51E1E0FB2FFEF5DC7FE87D641E9 -:101E90003FC2BCD03AA8B03AA2D98F927ECBFA7397 -:101EA00048DDB378F8920D44BFFC06B3135D7A1D8C -:101EB00014EF97EF8B607B70B170C8FAA74EB7082C -:101EC000AE97F60BDB14D03F2F639CD140E37FD558 -:101ED000F8A0D71FA11F381FF4032DF4C39836A014 -:101EE0001FCF984985B3A5BFF7B0BFB7315FD7AF54 -:101EF00021FB41F052611F643F2E86D80F4A3CEE11 -:101F0000061ECB3AE5BB26FDFD661E355F4E19C2A7 -:101F10009EF8A43D1913E6DB87EF8CA90DE3F7C10A -:101F2000C7B4F758C736CA777165A284BF3B845DD2 -:101F300089023F960EEF7BFF699ABF747304C72D29 -:101F4000EB472E9BF6BFB12B9F150AA6DB6FEAFD70 -:101F5000951F132E056152FE0ACC2203F735C210DD -:101F6000C67A50A86E51703FBAEA5E31197C2EB025 -:101F700094EC009EF1DAFDB688D5EAADC6EE8A3D56 -:101F8000049F8C4B74E25E6B74C22181F74F8575A0 -:101F9000C599B08BFE31EE09453978BFBC55C1FA01 -:101FA000F04C79FE3B8AC39B205781C3E373C0EF9B -:101FB0007916471BEA00CEA284A5C8F3E7453B7219 -:101FC000500770768D9270BCA34D7122944D585A73 -:101FD000C0EFCFAC5B3FB6E2DD9A22A2E95C96612E -:101FE000EE1C7CA7A6F85399378B3EF6633717C9CA -:101FF000FC6BC46BC28F7BABBE59917C7F26321DBC -:102000003918A7B8F2BB45241F7FFC9EEB16AC4FD6 -:10201000D4F08CC72DA20AAE76DBD09ED0EEF3BAF8 -:102020000CEE52B445511E23F71BBCD968DF34F8BF -:102030007E8C7E92E722EC57F4D8E4891904275A63 -:102040007C6C273B5CAE5BB1FFAB335DC5180FAD5D -:102050009F83B7C8F3099FDB302FF41D96CECFA521 -:102060004552EECB8AA4FD98BE56DEC786F2BDACC3 -:10207000C8A0D9B7BF8F37E15B8AEFE9F88BAD8B8A -:10208000B3810FE17B2FF0247C17625C44C470BDE8 -:10209000E3FA72E6E1EF951549F9227B56F5B1B402 -:1020A00067DCA61BBDC3103F8EFA857718F01DD5DF -:1020B000D867C3BFC378D6D367837F7FF6C13E1B83 -:1020C000FA9F75C977D2A1FB3716C9F713E9D3FB7D -:1020D00078FD58FA5637C7E97DC31047A5977FBCEE -:1020E0005EDEBB64B07F19ABF997B1BF4869EF21E1 -:1020F000791BFB6434DF6F8B82581EAFB44A3DAD51 -:10210000FC45D9A1366AC76F277C83E2AF095EC25E -:102110007B505C64EC97EF2D09069DF69A1886CCEF -:1021200022BEAA11F2BDE528CD6E206E2B25BB5034 -:10213000537EF432BF03C07AEC8F3B5BC85FBB4970 -:10214000C2E4AE918F2E9FBFA68BF3C3ED57FBB5B4 -:102150007CB3753DF2678ADF06F557961DE982BFAD -:10216000A9DA3BB8BF66C5679CC752FC36A8FFDE3C -:102170001F7FC0EF6CEADA07F7137F9F029F75FE9F -:102180001E33F92620DF3B5613E694FF7EC0B712BC -:10219000FADE541DC1EF6777FD3A8FE546E737ADAC -:1021A0006FFA76F2B196E77BF24406F4E19BDA5ED1 -:1021B000D8A7B441F6C9C375BED9916C77EAB4FC0F -:1021C000AAB6CCCE7E3EB1D6CAF6AB500D7302AEE7 -:1021D000354A3B238A55CD4EF958FF4FDE3E8CEBF6 -:1021E000797C00C03193F8DD71DC5A09F78DB0B00D -:1021F0007D28349454EFA1F6A86105DB8104BCB8B6 -:1022000024BE3F03FBA0427F655DB5CEEC53E4FDE9 -:10221000BE2307F9AE7EDFD4B0D1DB7A10F9B2E28B -:102220007D7219EA8A7746F0FD4100F5463A4FC3C0 -:102230003069471B16A4B31F088892D2958843E6DD -:102240008771FDB16198E351DC2736544CE438FACC -:10225000D07F4BBFDB37D7EA441CD530D9B106EF6E -:10226000551A7EE1E0F15714B99FE751499F86B9AD -:10227000F2FC0D15319CF7E87C6868748DC4FDD4C0 -:10228000CC31EEFF00DF4769F7730DC9D44FED1372 -:102290004AC9821F619F4912DF19331DAC77C716E7 -:1022A0004C7C74B783DD891FF74475B32307E5C5FC -:1022B000FF033C759D8B10370000000000000000FC -:0822C00005020D000000000002 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex new file mode 100644 index 000000000000..651f4346d89e --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex @@ -0,0 +1,10191 @@ +:10000000000028B0000000600000068800002918E9 +:100010000000161400002FA800000098000045C042 +:10002000000073C400004660000000CC0000BA2845 +:1000300000009A700000BAF80000009400015570AA +:10004000000057BC00015608000000B80001ADC810 +:100050000000CE200001AE880000000400027CB049 +:10006000020400480000000F020400540000004594 +:1000700002040058000000840204005C0000000636 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000060400CC0000000418 +:10010000020400DC00100000020400E012140000F1 +:10011000020400E422140000020400E8321400008B +:10012000060400EC000000040104012400000000AB +:1001300001040128000000000104012C000000005F +:10014000010401300000000002040004000000FF70 +:1001500002040008000000FF0204000C000000FF81 +:1001600002040010000000FF02040014000000FF61 +:1001700002040018000000FF0204001C000000FF41 +:1001800002040020000000FF020400240000003EE2 +:1001900002040028000000000204002C0000003FC0 +:1001A000020400300000003F020400340000003F61 +:1001B00002040038000000000204003C0000003F80 +:1001C000020400400000003F020400440000003F21 +:1001D00002042008000004110204200C00000400A6 +:1001E000020420100000040402042014000004197A +:1001F0000204201C0000FFFF020420200000FFFF7B +:10020000020420240000FFFF020420280000FFFF5A +:1002100006042038000000020204204000000034E0 +:100220000204204400000035060420480000007C41 +:100230000204223807FFFFFF0204223C0000003FB7 +:100240000204224007FFFFFF020422440000000FC7 +:1002500001042248000000000104224C00000000BC +:10026000010422500000000001042254000000009C +:1002700001042258000000000104225C000000007C +:10028000010422600000000001042264000000005C +:1002900001042268000000000104226C000000003C +:1002A000010422700000000001042274000000001C +:1002B00001042278000000000104227C00000000FC +:1002C000020424BC000000010C042000000003E82C +:1002D0000A042000000000010B0420000000000AB6 +:1002E0000205004400000020020500480000003222 +:1002F000020500900215002002050094021500205E +:1003000002050098000000300205009C0810000063 +:10031000020500A000000033020500A40000003028 +:10032000020500A800000031020500AC0000000238 +:10033000020500B000000005020500B40000000640 +:10034000020500B800000002020500BC0000000227 +:10035000020500C000000000020500C40000000506 +:10036000020500C800000002020500CC00000002E7 +:10037000020500D000000002020500D400000001C8 +:1003800002050114000000010205011C000000012B +:100390000205012000000002020502040000000125 +:1003A0000205020C0000004002050210000000409F +:1003B0000205021C000000200205022000000013BC +:1003C0000205022400000020060502400000000A89 +:1003D0000405028000200000020500500000000714 +:1003E0000205005400000007020500580000000844 +:1003F0000205005C00000008060500600000000423 +:10040000020500D800000006020500E00000000D13 +:10041000020500E40000002D020500E800000007CE +:10042000020500EC00000027020500F000000007B4 +:10043000020500F400000027020500F80000000794 +:10044000020500FC00000027020500040000000176 +:1004500002050008000000010205000C0000000178 +:100460000205001000000001020500140000000158 +:1004700002050018000000010205001C0000000138 +:100480000205002000000001020500240000000118 +:1004900002050028000000010205002C00000001F8 +:1004A00002050030000000010205003400000001D8 +:1004B00002050038000000010205003C00000001B8 +:1004C00002050040000000010406100002000020A8 +:1004D000020600DC00000001010600D80000000058 +:1004E0000406020000030220020600DC00000000F7 +:1004F00002060068000000B802060078000001143F +:10050000010600B800000000010600C8000000005D +:100510000206006C000000B80206007C0000011416 +:10052000010600BC00000000010600CC0000000035 +:100530000718040000950000081807600014022343 +:10054000071C000034D40000071C800034CF0D3697 +:10055000071D00000A191A6A081D14605D7402253F +:100560000118000000000000011800040000000055 +:1005700001180008000000000118000C0000000035 +:100580000118001000000000011800140000000015 +:1005900002180020000000010218002400000002E0 +:1005A00002180028000000030218002C00000000C0 +:1005B000021800300000000402180034000000019E +:1005C00002180038000000000218003C0000000182 +:1005D000021800400000000402180044000000005F +:1005E00002180048000000010218004C000000033F +:1005F0000218005000000000021800540000000122 +:1006000002180058000000040218005C00000000FE +:1006100002180060000000010218006400000003DE +:1006200002180068000000000218006C00000001C1 +:10063000021800700000000402180074000000009E +:1006400002180078000000040218007C000000037B +:100650000618008000000002021800A400003FFFFE +:10066000021800A8000003FF021802240000000086 +:1006700002180234000000000218024C00000000C2 +:10068000021802E4000000FF061810000000040039 +:10069000021B8BC000000001021B80000000003420 +:1006A000021B804000000018021B80800000000C2C +:1006B000021B80C0000000200C1B83000007A1204B +:1006C0000A1B8300000001380B1B83000000138805 +:1006D000021B83C0000001F4061A2000000000B2D3 +:1006E000061A23C800000181041A29CC0001022740 +:1006F000061A1020000000C8061A100000000002B0 +:10070000061A1E3800000002061A1E300000000201 +:10071000061A080000000002061A0808000000027D +:10072000061A081000000004041A1FB00005022871 +:10073000041A4CB00008022D061A22C8000000203E +:10074000061A400000000124021A4920000000009F +:10075000061A14000000000A061A145000000006D1 +:10076000061A150000000002041A150800050235DB +:10077000061A151C00000009061A15800000001456 +:10078000061A09C000000048061A0800000000020E +:10079000061A08200000000E041A1FB00002023AD8 +:1007A000061A2C2800000002061A23480000002028 +:1007B000061A449000000124021A49240000000097 +:1007C000061A14280000000A061A14680000000621 +:1007D000061A154000000002041A15480005023CE4 +:1007E000061A155C00000009061A15D00000001456 +:1007F000061A0AE000000048061A08080000000275 +:10080000061A08580000000E041A1FB80002024120 +:10081000061A2C30000000020200A2800000000135 +:100820000200A294071D29110200A29800000000F6 +:100830000200A29C009C04240200A2A00000000070 +:100840000200A2A4000002090200A4FCFF000000B4 +:10085000020100B400000001020100B80000000124 +:10086000020100DC000000010201010000000001A3 +:1008700002010104000000010201007C00300000C0 +:1008800002010084000000280201008C000000002A +:1008900002010130000000040201025C00000001BE +:1008A000020103280000000002010554000000308E +:1008B000020100C400000001020100CC00000001A0 +:1008C000020100F800000001020100F00000000138 +:1008D00002010080003000000201008800000028B2 +:1008E0000201009000000000020101340000000439 +:1008F000020102DC000000010201032C00000000E4 +:100900000201056400000030020100C8000000017F +:10091000020100D000000001020100FC0000000103 +:10092000020100F400000001020C10000000002091 +:10093000020C200800000A11020C200C00000A0022 +:10094000020C201000000A04020C201C0000FFFF13 +:10095000020C20200000FFFF020C20240000FFFFFB +:10096000020C20280000FFFF060C203800000002C7 +:10097000020C204000000034020C2044000000352E +:10098000020C204800000020020C204C0000002136 +:10099000020C205000000022020C20540000002312 +:1009A000020C205800000024020C205C00000025EE +:1009B000020C206000000026020C206400000027CA +:1009C000020C206800000028020C206C00000029A6 +:1009D000020C20700000002A020C20740000002B82 +:1009E000060C207800000056020C21D00000000107 +:1009F000020C21D400000001020C21D800000001EB +:100A0000020C21DC00000001020C21E000000001CA +:100A1000020C21E400000001020C21E800000001AA +:100A2000020C21EC00000001020C21F0000000018A +:100A3000020C21F400000001060C21F80000001057 +:100A4000020C223807FFFFFF020C223C0000003F8F +:100A5000020C224007FFFFFF020C22440000000F9F +:100A6000010C224800000000010C224C0000000094 +:100A7000010C225000000000010C22540000000074 +:100A8000010C225800000000010C225C0000000054 +:100A9000010C226000000000010C22640000000034 +:100AA000010C226800000000010C226C0000000014 +:100AB000010C227000000000010C227400000000F4 +:100AC000010C227800000000010C227C00000000D4 +:100AD000020C24BC000000010C0C2000000003E804 +:100AE0000A0C2000000000010B0C20000000000A8E +:100AF000020C400800000365020C400C0000035487 +:100B0000020C401000000358020C40140000037552 +:100B1000020C401C0000FFFF020C40200000FFFF01 +:100B2000020C40240000FFFF020C40280000FFFFE1 +:100B3000020C403800000046020C403C000000055A +:100B4000060C40400000005E020C41B800000001AD +:100B5000060C41BC0000001F020C423807FFFFFFDB +:100B6000020C423C0000003F020C424007FFFFFF26 +:100B7000020C42440000000F010C4248000000003B +:100B8000010C424C00000000010C4250000000002B +:100B9000010C425400000000010C4258000000000B +:100BA000010C425C00000000010C426000000000EB +:100BB000010C426400000000010C426800000000CB +:100BC000010C426C00000000010C427000000000AB +:100BD000010C427400000000010C4278000000008B +:100BE000010C427C00000000010C4280000000006B +:100BF000020C44C0000000010C0C4000000003E89F +:100C00000A0C4000000000010B0C40000000000A2C +:100C1000020D004400000032020D008C021500207D +:100C2000020D009002150020020D00940810000033 +:100C3000020D009800000033020D009C000000022D +:100C4000020D00A000000000020D00A4000000053D +:100C5000020D00A800000005060D00AC0000000217 +:100C6000020D00B400000002020D00B800000003F5 +:100C7000020D00BC00000002020D00C000000001D7 +:100C8000020D00C800000002020D00CC00000002AE +:100C9000020D010800000001020D015C00000001CE +:100CA000020D016400000001020D01680000000255 +:100CB000020D020400000001020D020C00000020E1 +:100CC000020D021000000040020D0214000000405E +:100CD000020D022000000003020D02240000001893 +:100CE000060D028000000012040D030000240243E0 +:100CF000020D004C00000001020D00500000000237 +:100D0000020D005400000008020D00580000000809 +:100D1000060D005C00000004020D00C40000000489 +:100D2000020D011400000009020D01180000002945 +:100D3000020D011C0000000A020D01200000002A23 +:100D4000020D012400000007020D01280000002709 +:100D5000020D012C00000007020D013000000027E9 +:100D6000020D01340000000C020D01380000002CBF +:100D7000020D013C0000000C020D01400000002C9F +:100D8000020D01440000000C020D01480000002C7F +:100D9000020D000400000001020D00080000000127 +:100DA000020D000C00000001020D00100000000107 +:100DB000020D001400000001020D001800000001E7 +:100DC000020D001C00000001020D002000000001C7 +:100DD000020D002400000001020D002800000001A7 +:100DE000020D002C00000001020D00300000000187 +:100DF000020D003400000001020D00380000000167 +:100E0000020D003C00000001020E004C0000003208 +:100E1000020E009402150020020E00980215002018 +:100E2000020E009C00000030020E00A0081000001E +:100E3000020E00A400000033020E00A800000030E3 +:100E4000020E00AC00000031020E00B000000002F3 +:100E5000020E00B400000004020E00B80000000002 +:100E6000020E00BC00000002020E00C000000002E2 +:100E7000020E00C400000000020E00C800000002C4 +:100E8000020E00CC00000007020E00D0000000029D +:100E9000020E00D400000002020E00D80000000183 +:100EA000020E00E400000001020E014400000001F7 +:100EB000020E014C00000001020E01500000000271 +:100EC000020E020400000001020E020C00000040AD +:100ED000020E021000000040020E021C000000047E +:100EE000020E022000000020020E02240000000E6C +:100EF000020E02280000001B060E03000000001274 +:100F0000040E0280001B0267020E00540000000C59 +:100F1000020E005800000009020E005C0000000FE5 +:100F2000020E006000000010060E006400000004C5 +:100F3000020E00DC00000003020E01100000000F92 +:100F4000020E01140000002F020E01180000000E16 +:100F5000020E011C0000002E020E00040000000121 +:100F6000020E000800000001020E000C000000014B +:100F7000020E001000000001020E0014000000012B +:100F8000020E001800000001020E001C000000010B +:100F9000020E002000000001020E002400000001EB +:100FA000020E002800000001020E002C00000001CB +:100FB000020E003000000001020E003400000001AB +:100FC000020E003800000001020E003C000000018B +:100FD000020E004000000001020E0044000000016B +:100FE0000730040000C900000830076800130282BF +:100FF00007340000334B00000734800037090CD35E +:101000000735000030161A96083572F051A2028496 +:10101000013000000000000001300004000000006A +:1010200001300008000000000130000C000000004A +:10103000013000100000000001300014000000002A +:1010400002300020000000010230002400000002F5 +:1010500002300028000000030230002C00000000D5 +:1010600002300030000000040230003400000001B3 +:1010700002300038000000000230003C0000000197 +:101080000230004000000004023000440000000074 +:1010900002300048000000010230004C0000000354 +:1010A0000230005000000000023000540000000137 +:1010B00002300058000000040230005C0000000014 +:1010C00002300060000000010230006400000003F4 +:1010D00002300068000000000230006C00000001D7 +:1010E00002300070000000040230007400000000B4 +:1010F00002300078000000040230007C0000000391 +:101100000630008000000002023000A400003FFF13 +:10111000023000A8000003FF02300224000000009B +:1011200002300234000000000230024C00000000D7 +:10113000023002E40000FFFF06302000000008003B +:1011400002338BC000000001023380000000001A4F +:10115000023380400000004E023380800000001007 +:10116000023380C0000000200C3383000007A12060 +:101170000A338300000001380B338300000013881A +:10118000023383C0000001F40C3383801DCD650061 +:101190000A3383800004C4B40B338380004C4B407B +:1011A00006321AA0000000C206321020000000C85B +:1011B0000632100000000002063214000000004059 +:1011C00006325098000000040632508000000005EE +:1011D00004325094000102860632500000000020C4 +:1011E00004322830000202870233080001000000A8 +:1011F00004330C00001002890233080000000000D4 +:1012000004330C400010029906321500000000B4AF +:1012100002321DC80000000006324000000000D865 +:10122000063217D0000000B402321DCC00000000CE +:1012300006324360000000D807200400009200003E +:1012400008200780001002A9072400002CD100000C +:10125000072480002AE50B350824DC6062DA02AB43 +:101260000120000000000000012000040000000038 +:1012700001200008000000000120000C0000000018 +:1012800001200010000000000120001400000000F8 +:1012900002200020000000010220002400000002C3 +:1012A00002200028000000030220002C00000000A3 +:1012B0000220003000000004022000340000000181 +:1012C00002200038000000000220003C0000000165 +:1012D0000220004000000004022000440000000042 +:1012E00002200048000000010220004C0000000322 +:1012F0000220005000000000022000540000000105 +:1013000002200058000000040220005C00000000E1 +:1013100002200060000000010220006400000003C1 +:1013200002200068000000000220006C00000001A4 +:101330000220007000000004022000740000000081 +:1013400002200078000000040220007C000000035E +:101350000620008000000002022000A400003FFFE1 +:10136000022000A8000003FF022002240000000069 +:1013700002200234000000000220024C00000000A5 +:10138000022002E40000FFFF062020000000080009 +:1013900002238BC000000001022380000000001027 +:1013A00002238040000000120223808000000030F1 +:1013B000022380C00000000E022383C0000001F45D +:1013C000062250000000004206221020000000C843 +:1013D000062210000000000206222000000000C0CB +:1013E000062225C00000024004222EC8000802ADDB +:1013F00002230800013FFFFF04230C00001002B588 +:10140000022308000000000004230C40001002C565 +:1014100006223040000000A00622354000000010E7 +:10142000062236C000000030062240000000020004 +:10143000062235C00000002006223840000000309F +:1014400006223000000000080222511800000000AF +:10145000062223000000000E0622241000000030A7 +:10146000062232C0000000A00622358000000010D5 +:1014700006223780000000300622480000000200EB +:10148000062236400000002006223900000000300D +:1014900006223020000000080222511C000000003B +:1014A000062223380000000E062224D0000000305F +:1014B00002161000000000280217000800000002B9 +:1014C0000217002C000000030217003C000000047B +:1014D0000217004400000008021700480000000244 +:1014E0000217004C0000009002170050000000900E +:1014F00002170054008000900217005808140000E2 +:10150000021700600000008A0217006400000080DB +:1015100002170068000000810217006C00000080C4 +:10152000021700700000000602170078000007D0C4 +:101530000217007C0000076C02170038007C1004C2 +:10154000021700040000000F0616402400000002ED +:10155000021640700000001C021642080000000144 +:101560000216421000000001021642200000000195 +:10157000021642280000000102164230000000015D +:10158000021642380000000102164260000000010D +:101590000C16401C0003D0900A16401C0000009C52 +:1015A0000B16401C000009C4021640300000000861 +:1015B000021640340000000C0216403800000010F3 +:1015C0000216404400000020021640000000000106 +:1015D000021640D800000001021640080000000179 +:1015E0000216400C0000000102164010000000012D +:1015F00002164240000000000216424800000000AF +:101600000616427000000002021642500000000060 +:101610000216425800000000061642800000000238 +:1016200002166008000006140216600C0000060096 +:1016300002166010000006040216601C0000FFFF86 +:10164000021660200000FFFF021660240000FFFF6A +:10165000021660280000FFFF02166038000000201C +:101660000216603C000000200216604000000034BA +:101670000216604400000035021660480000002396 +:101680000216604C00000024021660500000002585 +:101690000216605400000026021660580000002761 +:1016A0000216605C00000029021660600000002A3B +:1016B000021660640000002B021660680000002C17 +:1016C0000216606C0000002D0616607000000052CB +:1016D000021661B800000001061661BC0000001F80 +:1016E0000216623807FFFFFF0216623C0000003F4F +:1016F0000216624007FFFFFF021662440000000F5F +:1017000001166248000000000116624C0000000053 +:101710000116625000000000011662540000000033 +:1017200001166258000000000116625C0000000013 +:1017300001166260000000000116626400000000F3 +:1017400001166268000000000116626C00000000D3 +:1017500001166270000000000116627400000000B3 +:1017600001166278000000000116627C0000000093 +:10177000021664BC000000010C166000000003E8C3 +:101780000A166000000000010B1660000000000A4D +:10179000021680400000000602168044000000058A +:1017A000021680480000000A0216804C0000000566 +:1017B0000216805400000002021680CC00000004D3 +:1017C000021680D000000004021680D4000000043D +:1017D000021680D800000004021680DC000000041D +:1017E000021680E000000004021680E400000004FD +:1017F000021680E8000000040216880400000004BD +:10180000021680300000007C021680340000003D8B +:10181000021680380000003F0216803C0000009C49 +:10182000021680F000000007061680F40000000594 +:101830000216880C01010101021681080000000057 +:101840000216810C00000004021681100000000442 +:1018500002168114000000020216881008012004FC +:1018600002168118000000050216811C0000000508 +:1018700002168120000000050216812400000005E8 +:101880000216882C2008100102168128000000088A +:101890000216812C000000060216813000000007AD +:1018A0000216813400000000021688300101012078 +:1018B0000616813800000004021688340101010177 +:1018C0000616814800000004021688380101010153 +:1018D00006168158000000040216883C010101012F +:1018E00006168168000000030216817400000001E2 +:1018F00002168840010101010216817800000001F2 +:101900000216817C000000010216818000000001A7 +:1019100002168184000000010216884401010101C1 +:1019200002168188000000010216818C000000046C +:10193000021681900000000402168194000000024B +:10194000021688480801200402168198000000054C +:101950000216819C00000005021681A0000000050F +:10196000021681A400000005021688142008100148 +:10197000021681A800000008021681AC00000006D3 +:10198000021681B000000007021681B400000001B9 +:101990000216881801010120021681B8000000011A +:1019A000021681BC00000001021681C00000000187 +:1019B000021681C4000000010216881C0101010109 +:1019C000021681C800000001021681CC000000014F +:1019D000021681D000000001021681D4000000012F +:1019E0000216882001010101021681D800000001C1 +:1019F000021681DC00000001021681E000000001F7 +:101A0000021681E400000001021688240101010190 +:101A1000021681E800000001021681EC00000001BE +:101A2000021681F000000001021688280101010160 +:101A300002168240FFFF003F0616824400000002AB +:101A40000216824CFFFF003F021682500000010088 +:101A5000021682540000010006168258000000029F +:101A600002168260000000C002168264000000C0FE +:101A70000216826800001E000216826C00001E0022 +:101A800002168270000040000216827400004000BE +:101A900002168278000080000216827C000080001E +:101AA00002168280000020000216828400002000BE +:101AB0000616828800000007021682A400000001BA +:101AC000061682A80000000A021681F400000C0825 +:101AD000021681F800000040021681FC000001009F +:101AE0000216820000000020021682040000001787 +:101AF00002168208000000800216820C000002001C +:101B0000021682100000000002168218FFFF01FF7B +:101B100002168214FFFF01FF0216823C0000001330 +:101B2000021680900000013F021680600000014014 +:101B30000216806400000140061680680000000262 +:101B400002168070000000C00616807400000007B6 +:101B50000216809C00000048021680A00000004889 +:101B6000061680A400000002021680AC00000048A7 +:101B7000061680B0000000070216823800008000C0 +:101B800002168234000025E40216809400007FFFD4 +:101B900002168220000000070216821C00000007C7 +:101BA000021682280000000002168224FFFFFFFFB9 +:101BB00002168230000000000216822CFFFFFFFF99 +:101BC000021680EC000000FF02140000000000017B +:101BD0000214000C0000000102140040000000018B +:101BE0000214004400007FFF0214000C00000000FB +:101BF00002140000000000000214006C000000004D +:101C00000214000400000001021400300000000172 +:101C100002140004000000000214005C0000000038 +:101C2000021400080000000102140034000000014A +:101C30000214000800000000021400600000000010 +:101C40000202005800000032020200A0031500202A +:101C5000020200A403150020020200A801000030C7 +:101C6000020200AC08100000020200B000000033C5 +:101C7000020200B400000030020200B8000000318F +:101C8000020200BC00000003020200C000000006C7 +:101C9000020200C400000003020200C800000003AA +:101CA000020200CC00000002020200D0000000008E +:101CB000020200D400000002020200DC000000006A +:101CC000020200E000000006020200E4000000043E +:101CD000020200E800000002020200EC0000000224 +:101CE000020200F000000001020200FC00000006F9 +:101CF0000202012000000000020201340000000284 +:101D0000020201B0000000010202020C000000010A +:101D10000202021400000001020202180000000288 +:101D200002020404000000010202040C0000004052 +:101D300002020410000000400202041C0000000423 +:101D4000020204200000002002020424000000021D +:101D5000020204280000001F060205000000001215 +:101D600004020480001F02D5020200600000000F80 +:101D70000202006400000007020200680000000B7D +:101D80000202006C0000000E060200700000000459 +:101D9000020200F40000000402020004000000013E +:101DA00002020008000000010202000C0000000115 +:101DB00002020010000000010202001400000001F5 +:101DC00002020018000000010202001C00000001D5 +:101DD00002020020000000010202002400000001B5 +:101DE00002020028000000010202002C0000000195 +:101DF0000202003000000001020200340000000175 +:101E000002020038000000010202003C0000000154 +:101E10000202004000000001020200440000000134 +:101E200002020048000000010202004C0000000114 +:101E3000020200500000000102020108000000C878 +:101E40000202011800000002020201C400000000AA +:101E5000020201CC00000000020201D400000002D6 +:101E6000020201DC00000002020201E4000000FFA7 +:101E7000020201EC000000FF0202010C000000C899 +:101E80000202011C00000002020201C80000000062 +:101E9000020201D000000000020201D8000000028E +:101EA000020201E000000002020201E8000000FF5F +:101EB000020201F0000000FF0728040000B5000046 +:101EC00008280768001302F4072C000035D500002D +:101ED000072C80003A3E0D76072D00003B471C067C +:101EE000072D800022BC2AD8082DC770471202F6A1 +:101EF000012800000000000001280004000000008C +:101F000001280008000000000128000C000000006B +:101F1000012800100000000001280014000000004B +:101F20000228002000000001022800240000000216 +:101F300002280028000000030228002C00000000F6 +:101F400002280030000000040228003400000001D4 +:101F500002280038000000000228003C00000001B8 +:101F60000228004000000004022800440000000095 +:101F700002280048000000010228004C0000000375 +:101F80000228005000000000022800540000000158 +:101F900002280058000000040228005C0000000035 +:101FA0000228006000000001022800640000000315 +:101FB00002280068000000000228006C00000001F8 +:101FC00002280070000000040228007400000000D5 +:101FD00002280078000000040228007C00000003B2 +:101FE0000628008000000002022800A400003FFF35 +:101FF000022800A8000003FF0228022400000000BD +:1020000002280234000000000228024C00000000F8 +:10201000022802E40000FFFF06282000000008005C +:10202000022B8BC000000001022B8000000000008A +:10203000022B804000000018022B80800000000C62 +:10204000022B80C0000000660C2B83000007A1203B +:102050000A2B8300000001380B2B8300000013883B +:10206000022B83C0000001F40C2B8340000001F41C +:102070000A2B8340000000000B2B8340000000056A +:102080000A2B83800004C4B40C2B83801DCD650013 +:102090000B2B8380004C4B40062A3C400000000480 +:1020A000042A3C50000202F8062A300000000048D2 +:1020B000062A1020000000C8062A100000000002B6 +:1020C000062A31280000008E022A33680000000032 +:1020D000042A3370000202FA042A3A70000402FC57 +:1020E000042A3D0000020300042A15000002030236 +:1020F000062A150800000100022A197000000000DD +:10210000022A197800000000042A19600002030462 +:10211000062A4AC000000002062A4B000000000404 +:10212000042A1F4800020306022B080000000000DA +:10213000042B0C0000100308022B08000100000013 +:10214000042B0C4000080318022B080002000000BA +:10215000042B0C6000080320062A3A8000000014BB +:10216000062A3B2000000024062A14000000000A72 +:10217000062A145000000006062A3378000000D812 +:10218000022A3A3800000000042A3C5800020328C2 +:10219000042A3C680010032A062A5020000000028E +:1021A000062A503000000002062A500000000002FB +:1021B000062A501000000002022A504000000000D1 +:1021C000062A50480000000E022A50B80000000104 +:1021D000042A4AC80002033A062A4B1000000042B3 +:1021E000062A4D2000000004062A3AD00000001400 +:1021F000062A3BB000000024062A14280000000A2A +:10220000062A146800000006062A36D8000000D806 +:10221000022A3A3C00000000042A3C600002033C11 +:10222000042A3CA80010033E062A502800000002A1 +:10223000062A503800000002062A5008000000025A +:10224000062A501800000002022A50440000000034 +:10225000062A50800000000E022A50BC0000000137 +:10226000042A4AD00002034E062A4C1800000042FD +:10227000062A4D3000000004021010080000000182 +:102280000210101000000264021010000003D000C1 +:10229000021010040000003D091018000200035055 +:1022A00009101100002005500610118000000002E6 +:1022B0000910118800060570061011A00000001812 +:1022C000021010100000000006102400000000E0C2 +:1022D0000210201C0000000002102020000000015D +:1022E000021020C0000000010210200400000001C4 +:1022F000021020080000000109103C0000050576CE +:1023000009103C200005057B0910380000050580F8 +:1023100002104028000000100210404400003FFF5F +:102320000210405800280000021040840084924AA5 +:1023300002104058000000000610806800000004F1 +:1023400002108000000010800610802800000002AB +:102350000210803800000010021080400000FFFFD3 +:10236000021080440000FFFF0210805000000000B7 +:102370000210810000000000061081200000000211 +:1023800002108008000002B502108010000000005A +:10239000061082000000004A021081080001FFFFC1 +:1023A00006108140000000020210800000001A8028 +:1023B0000610900000000024061091200000004A42 +:1023C000061093700000004A061095C00000004AF5 +:1023D000021080040000108006108030000000020F +:1023E0000210803C00000010021080480000FFFF37 +:1023F0000210804C0000FFFF02108054000000001B +:102400000210810400000000061081280000000274 +:102410000210800C000002B50210801400000000C1 +:10242000061084000000004A0210810C0001FFFF2A +:1024300006108148000000020210800400001A808B +:102440000610909000000024061092480000004AF8 +:10245000061094980000004A061096E80000004A12 +:102460000212049000E383400212051400003C10A5 +:10247000021205200000000202120494FFFFFFFF79 +:1024800002120498FFFFFFFF0212049CFFFFFFFFF0 +:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0 +:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0 +:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C +:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68 +:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48 +:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28 +:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8 +:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7 +:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7 +:10252000021204F4FFFFFFFF021204F8FFFFFFFF97 +:10253000021204FCFFFFFFFF02120500FFFFFFFF76 +:1025400002120504FFFFFFFF02120508FFFFFFFF55 +:102550000212050CFFFFFFFF02120510FFFFFFFF35 +:10256000021204D4FFFF3330021204D8FFFF3340BD +:10257000021204B4F00030000212039000000008C0 +:102580000212039C00000008061203A000000002D3 +:10259000021203BC00000004021203C40000000485 +:1025A000021203D000000000021203DC0000000051 +:1025B0000212036C00000001021203680000003FD9 +:1025C000021201BC00000040021201C00000180805 +:1025D000021201C400000803021201C8000008032F +:1025E000021201CC00000040021201D000000003E2 +:1025F000021201D400000803021201D800000803EF +:10260000021201DC00000803021201E000010003D5 +:10261000021201E400000803021201E800000803AE +:10262000021201EC00000003021201F0000000039E +:10263000021201F400000003021201F8000000037E +:10264000021201FC0000000302120200000000035D +:10265000021202040000000302120208000000033C +:102660000212020C0000000302120210000000031C +:1026700002120214000000030212021800000003FC +:102680000212021C000000030212022000000003DC +:102690000212022400000003021202280000240398 +:1026A0000212022C0000002F02120230000000096A +:1026B00002120234000000190212023800000184E4 +:1026C0000212023C000001830212024000000306D5 +:1026D0000212024400000019021202480000000623 +:1026E0000212024C00000306021202500000030610 +:1026F00002120254000003060212025800000C8667 +:102700000212025C000003060212026000000306CF +:1027100002120264000000060212026800000006B5 +:102720000212026C00000006021202700000000695 +:102730000212027400000006021202780000000675 +:102740000212027C00000006021202800000000655 +:102750000212028400000006021202880000000635 +:102760000212028C00000006021202900000000615 +:1027700002120294000000060212029800000006F5 +:102780000212029C00000006021202A000000306D2 +:10279000021202A400000013021202A800000006A8 +:1027A000021202B000001004021202B40000100471 +:1027B0000212032400106440021203280010644037 +:1027C000021201B0000000010600A0000000001687 +:1027D0000200A06CBF5C00000200A070FFF51FEFBC +:1027E0000200A0740000FFFF0200A078500003E088 +:1027F0000200A07C000000000200A0800000A000F9 +:102800000600A084000000050200A0980FE0000070 +:102810000600A09C000000140200A0EC555400002B +:102820000200A0F0555555550200A0F40000555582 +:102830000200A0F8000000000200A0FC55540000B7 +:102840000200A100555555550200A1040000555540 +:102850000200A108000000000200A22C00000000FD +:102860000600A230000000030200A0600000000784 +:102870000200A10CBF5C00000200A110FFF51FEFD9 +:102880000200A1140000FFFF0200A118500003E0A5 +:102890000200A11C000000000200A1200000A00016 +:1028A0000600A124000000050200A1380FE000008E +:1028B0000600A13C000000140200A18C5554000049 +:1028C0000200A190555555550200A19400005555A0 +:1028D0000200A198000000000200A19C55540000D5 +:1028E0000200A1A0555555550200A1A40000555560 +:1028F0000200A1A8000000000200A23C00000000AD +:102900000600A240000000030200A06400000007CF +:1029100000000000000000000000002E0000000089 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:10297000002E0050000000000000000000000000D9 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000050008D5A +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000008D009200920096C0 +:1029D0000096009A000000000000000000000000C7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000009A00DB00DB00E900E900F7BE +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A80000000000000000000000000000000000046 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD00000F700FE00000000000000000000000001 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B2000000000000000000000FE01030103010E90 +:102B3000010E01190000000000000000000000006C +:102B40000000000000000000000000000000000085 +:102B50000000000000000000000000000000000075 +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000119011A00000000000000000000000010 +:102B90000000000000000000000000000000000035 +:102BA000000000000000000000000000011A0152B7 +:102BB0000000000000000000000000000000000015 +:102BC0000000000000000000000000000000000005 +:102BD000000000000000000001520176000000002B +:102BE00000000000000000000000000000000000E5 +:102BF00000000000000000000000000000000000D5 +:102C000000000000017601B5000000000000000097 +:102C100000000000000000000000000000000000B4 +:102C200000000000000000000000000000000000A4 +:102C300001B501F0000000000000000000000000ED +:102C40000000000000000000000000000000000084 +:102C500000000000000000000000000001F002354C +:102C6000023502380238023B00000000000000007C +:102C70000000000000000000000000000000000054 +:102C80000000000000000000023B02760276028095 +:102C90000280028A00000000000000000000000026 +:102CA0000000000000000000000000000000000024 +:102CB00000000000028A028B0000000000000000FB +:102CC0000000000000000000000000000000000004 +:102CD00000000000000000000000000000000000F4 +:102CE000028B029D000000000000000000000000B8 +:102CF00000000000000000000000000000000000D4 +:102D0000000000000000000000000000029D02B270 +:102D100002B202B502B502B80000000000000000D7 +:102D200000000000000000000000000000000000A3 +:102D3000000000000000000002B802E600000000F1 +:102D40000000000000000000000000000000000083 +:102D50000000000000000000000000000000000073 +:102D60000000000002E6036D00000000000000000B +:102D70000000000000000000000000000000000053 +:102D80000000000000000000000000000000000043 +:102D9000036D0374037403780378037C0000000060 +:102DA0000000000000000000000000000000000023 +:102DB000000000000000000000000000037C03BBD6 +:102DC00003BB03C303C303CB0000000000000000EB +:102DD00000000000000000000000000000000000F3 +:102DE000000000000000000003CB041F041F04319A +:102DF0000431044300000000000000000000000057 +:102E000000000000000000000000000000000000C2 +:102E1000000000000443044D00000000000000001A +:102E200000000000000000000000000000000000A2 +:102E30000000000000000000000000000000000092 +:102E4000044D0453000000000000000000000000DA +:102E50000000000000000000000000000000000072 +:102E600000000000000000000000000004530456B1 +:102E70000000000000000000000000000000000052 +:102E80000000000000000000000000000000000042 +:102E900000000000000000000456045B0000000079 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC00000000000045B045C045C046E046E04807B +:102ED00000000000000000000000000000000000F2 +:102EE00000000000000000000000000000000000E2 +:102EF000048004ED0000000000000000000000005D +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000004ED04EECE +:102F200004EE050205020516000000000000000086 +:102F30000000000000000000000000000000000091 +:102F40000000000000000000000000000000000081 +:102F50000000000000000000000000000000000071 +:102F60000000000000000000000000000000000061 +:102F70000000000000000000000000000000000051 +:102F80000000000000000000000000000000000041 +:102F90000000000000000000000000000000000031 +:102FA000000000000000000000010000000204C05A +:102FB0000003098000040E4000051300000617C03E +:102FC00000071C800008214000092600000A2AC0D2 +:102FD000000B2F80000C3440000D3900000E3DC066 +:102FE000000F42800010474000114C00001250C0FA +:102FF0000013558000145A4000155F00001663C08E +:103000000017688000186D4000197200001A76C021 +:10301000001B7B80001C8040001D8500001E89C0B5 +:10302000001F8E8000209340000020000000400020 +:1030300000006000000080000000A0000000C00050 +:103040000000E0000001000000012000000140003D +:1030500000016000000180000001A0000001C0002C +:103060000001E00000020000000220000002400019 +:1030700000026000000280000002A0000002C00008 +:103080000002E000000300000003200000034000F5 +:1030900000036000000380000003A0000003C000E4 +:1030A0000003E000000400000004200000044000D1 +:1030B00000046000000480000004A0000004C000C0 +:1030C0000004E000000500000005200000054000AD +:1030D00000056000000580000005A0000005C0009C +:1030E0000005E00000060000000620000006400089 +:1030F00000066000000680000006A0000006C00078 +:103100000006E00000070000000720000007400064 +:1031100000076000000780000007A0000007C00053 +:103120000007E00000080000000820000008400040 +:1031300000086000000880000008A0000008C0002F +:103140000008E0000009000000092000000940001C +:1031500000096000000980000009A0000009C0000B +:103160000009E000000A0000000A2000000A4000F8 +:10317000000A6000000A8000000AA000000AC000E7 +:10318000000AE000000B0000000B2000000B4000D4 +:10319000000B6000000B8000000BA000000BC000C3 +:1031A000000BE000000C0000000C2000000C4000B0 +:1031B000000C6000000C8000000CA000000CC0009F +:1031C000000CE000000D0000000D2000000D40008C +:1031D000000D6000000D8000000DA000000DC0007B +:1031E000000DE000000E0000000E2000000E400068 +:1031F000000E6000000E8000000EA000000EC00057 +:10320000000EE000000F0000000F2000000F400043 +:10321000000F6000000F8000000FA000000FC00032 +:10322000000FE0000010000000102000001040001F +:1032300000106000001080000010A0000010C0000E +:103240000010E000001100000011200000114000FB +:1032500000116000001180000011A0000011C000EA +:103260000011E000001200000012200000124000D7 +:1032700000126000001280000012A0000012C000C6 +:103280000012E000001300000013200000134000B3 +:1032900000136000001380000013A0000013C000A2 +:1032A0000013E0000014000000142000001440008F +:1032B00000146000001480000014A0000014C0007E +:1032C0000014E0000015000000152000001540006B +:1032D00000156000001580000015A0000015C0005A +:1032E0000015E00000160000001620000016400047 +:1032F00000166000001680000016A0000016C00036 +:103300000016E00000170000001720000017400022 +:1033100000176000001780000017A0000017C00011 +:103320000017E000001800000018200000184000FE +:1033300000186000001880000018A0000018C000ED +:103340000018E000001900000019200000194000DA +:1033500000196000001980000019A0000019C000C9 +:103360000019E000001A0000001A2000001A4000B6 +:10337000001A6000001A8000001AA000001AC000A5 +:10338000001AE000001B0000001B2000001B400092 +:10339000001B6000001B8000001BA000001BC00081 +:1033A000001BE000001C0000001C2000001C40006E +:1033B000001C6000001C8000001CA000001CC0005D +:1033C000001CE000001D0000001D2000001D40004A +:1033D000001D6000001D8000001DA000001DC00039 +:1033E000001DE000001E0000001E2000001E400026 +:1033F000001E6000001E8000001EA000001EC00015 +:10340000001EE000001F0000001F2000001F400001 +:10341000001F6000001F8000001FA000001FC000F0 +:10342000001FE000002000000020200000204000DD +:1034300000206000002080000020A0000020C000CC +:103440000020E000002100000021200000214000B9 +:1034500000216000002180000021A0000021C000A8 +:103460000021E00000220000002220000022400095 +:1034700000226000002280000022A0000022C00084 +:103480000022E00000230000002320000023400071 +:1034900000236000002380000023A0000023C00060 +:1034A0000023E0000024000000242000002440004D +:1034B00000246000002480000024A0000024C0003C +:1034C0000024E00000250000002520000025400029 +:1034D00000256000002580000025A0000025C00018 +:1034E0000025E00000260000002620000026400005 +:1034F00000266000002680000026A0000026C000F4 +:103500000026E000002700000027200000274000E0 +:1035100000276000002780000027A0000027C000CF +:103520000027E000002800000028200000284000BC +:1035300000286000002880000028A0000028C000AB +:103540000028E00000290000002920000029400098 +:1035500000296000002980000029A0000029C00087 +:103560000029E000002A0000002A2000002A400074 +:10357000002A6000002A8000002AA000002AC00063 +:10358000002AE000002B0000002B2000002B400050 +:10359000002B6000002B8000002BA000002BC0003F +:1035A000002BE000002C0000002C2000002C40002C +:1035B000002C6000002C8000002CA000002CC0001B +:1035C000002CE000002D0000002D2000002D400008 +:1035D000002D6000002D8000002DA000002DC000F7 +:1035E000002DE000002E0000002E2000002E4000E4 +:1035F000002E6000002E8000002EA000002EC000D3 +:10360000002EE000002F0000002F2000002F4000BF +:10361000002F6000002F8000002FA000002FC000AE +:10362000002FE0000030000000302000003040009B +:1036300000306000003080000030A0000030C0008A +:103640000030E00000310000003120000031400077 +:1036500000316000003180000031A0000031C00066 +:103660000031E00000320000003220000032400053 +:1036700000326000003280000032A0000032C00042 +:103680000032E0000033000000332000003340002F +:1036900000336000003380000033A0000033C0001E +:1036A0000033E0000034000000342000003440000B +:1036B00000346000003480000034A0000034C000FA +:1036C0000034E000003500000035200000354000E7 +:1036D00000356000003580000035A0000035C000D6 +:1036E0000035E000003600000036200000364000C3 +:1036F00000366000003680000036A0000036C000B2 +:103700000036E0000037000000372000003740009E +:1037100000376000003780000037A0000037C0008D +:103720000037E0000038000000382000003840007A +:1037300000386000003880000038A0000038C00069 +:103740000038E00000390000003920000039400056 +:1037500000396000003980000039A0000039C00045 +:103760000039E000003A0000003A2000003A400032 +:10377000003A6000003A8000003AA000003AC00021 +:10378000003AE000003B0000003B2000003B40000E +:10379000003B6000003B8000003BA000003BC000FD +:1037A000003BE000003C0000003C2000003C4000EA +:1037B000003C6000003C8000003CA000003CC000D9 +:1037C000003CE000003D0000003D2000003D4000C6 +:1037D000003D6000003D8000003DA000003DC000B5 +:1037E000003DE000003E0000003E2000003E4000A2 +:1037F000003E6000003E8000003EA000003EC00091 +:10380000003EE000003F0000003F2000003F40007D +:10381000003F6000003F8000003FA000003FC0006C +:10382000003FE000003FE00100000000000001FF59 +:103830000000020000007FF800007FF80000026F27 +:1038400000001500000000010000000300BEBC20C5 +:103850000000000300BEBC2000000001FFFFFFFFCE +:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 +:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 +:1038800000000000FFFFFFFF00000000FFFFFFFF40 +:103890000000000300BEBC20FFFFFFFF000000008F +:1038A000FFFFFFFF00000000FFFFFFFF000000031D +:1038B00000BEBC2000002000000040C0000061806D +:1038C000000082400000A3000000C3C00000E480AC +:1038D0000001054000012600000146C0000167808C +:1038E000000188400001A9000001C9C00001EA8070 +:1038F00000020B4000022C0000024CC000026D8050 +:1039000000028E400002AF000002CFC00002F08033 +:103910000003114000033200000352C00003738013 +:10392000000394400003B5000003D5C00003F680F7 +:103930000004174000043800000458C000047980D7 +:1039400000049A400000800000010380000187000D +:1039500000020A8000028E0000031180000395001F +:103960000004188000049C0000051F800005A300CF +:10397000000626800006AA0000072D800007B1007F +:10398000000834800008B80000093B800009BF002F +:10399000000A4280000AC600000B4980000BCD00DF +:1039A000000C5080000CD400000D5780000DDB008F +:1039B00000007FF800007FF800000174000015008F +:1039C0000000190000000000FFFFFFFF40000000A2 +:1039D00040000000400000004000000040000000E7 +:1039E00040000000400000004000000040000000D7 +:1039F00040000000400000004000000040000000C7 +:103A000040000000400000004000000040000000B6 +:103A100040000000400000004000000040000000A6 +:103A20004000000040000000400000004000000096 +:103A30004000000040000000400000004000000086 +:103A400040000000400000004000000000007FF83F +:103A500000007FF80000050900003500FFFFFFFFB0 +:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 +:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012 +:103A80004000000040000000400000004000000036 +:103A90004000000040000000400000004000000026 +:103AA0004000000040000000400000004000000016 +:103AB0004000000040000000400000004000000006 +:103AC00040000000400000004000000040000000F6 +:103AD00040000000400000004000000040000000E6 +:103AE00040000000400000004000000040000000D6 +:103AF00040000000400000004000000000001000F6 +:103B000000002080000031000000418000005200D1 +:103B100000006280000073000000838000009400B9 +:103B20000000A4800000B5000000C5800000D600A1 +:103B30000000E6800000F700000107800001180087 +:103B400000012880000139000001498000015A006D +:103B500000016A8000017B0000018B8000019C0055 +:103B60000001AC800001BD000001CD800001DE003D +:103B70000001EE800001FF0000007FF800007FF8E8 +:103B8000000004480000150010000000000028ADEF +:103B90000000000000010001000D0205CCCCCCC1EA +:103BA000FFFFFFFFFFFFFFFF7058103C0000000009 +:103BB0000000000000000001CCCC0201CCCCCCCC39 +:103BC00000000000FFFFFFFF400000004000000079 +:103BD00040000000400000004000000040000000E5 +:103BE00040000000400000004000000040000000D5 +:103BF00040000000400000004000000040000000C5 +:103C000040000000400000004000000040000000B4 +:103C100040000000400000004000000040000000A4 +:103C20004000000040000000400000004000000094 +:103C30004000000040000000400000004000000084 +:103C40004000000040000000000E01B7011600D641 +:103C50000000FFFF000000000000FFFF0000000068 +:103C60000000FFFF000000000000FFFF0000000058 +:103C70000000FFFF000000000000FFFF0000000048 +:103C80000000FFFF000000000000FFFF0000000038 +:103C90000010000000000000007201BB012300F3CF +:103CA0000000FFFF000000000000FFFF0000000018 +:103CB0000000FFFF000000000000FFFF0000000008 +:103CC0000000FFFF000000000000FFFF00000000F8 +:103CD0000000FFFF000000000000FFFF00000000E8 +:103CE0000010000000000000FFFFFFF3318FFFFF16 +:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308 +:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69 +:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7 +:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3 +:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7 +:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61 +:103D50000C30C305C30C30C3CF300014F3CF3CF399 +:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4 +:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387 +:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98 +:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367 +:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2 +:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347 +:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45 +:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327 +:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6 +:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307 +:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47 +:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6 +:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2 +:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6 +:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60 +:103E50000C30C305C30C30C3CF300014F3CF3CF398 +:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3 +:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386 +:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97 +:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366 +:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2 +:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346 +:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24 +:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326 +:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45 +:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306 +:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46 +:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5 +:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1 +:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5 +:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F +:103F50000C30C305C30C30C3CF300014F3CF3CF397 +:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2 +:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385 +:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96 +:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365 +:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC +:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378 +:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62 +:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325 +:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23 +:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305 +:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45 +:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4 +:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0 +:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4 +:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E +:104050000C30C305C30C30C3CF300014F3CF3CF396 +:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1 +:104070000C30C30CC30C30C3CF3CF300F3CF3CF384 +:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31 +:104090000C30C30CC30C30C3CF3CC000F3CF3CF397 +:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B +:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377 +:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61 +:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324 +:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24 +:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304 +:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45 +:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3 +:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF +:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3 +:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D +:104150000C30C305C30C30C3CF300014F3CF3CF395 +:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0 +:104170000C30C30CC30C30C3CF3CF300F3CF3CF383 +:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94 +:104190000C30C30CC30C30C3CF3CF300F3CF3CF363 +:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B +:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376 +:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61 +:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323 +:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57 +:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337 +:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76 +:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316 +:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55 +:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6 +:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34 +:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6 +:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12 +:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6 +:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE +:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396 +:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6 +:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376 +:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96 +:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356 +:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56 +:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336 +:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75 +:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315 +:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54 +:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5 +:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33 +:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5 +:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11 +:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5 +:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED +:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395 +:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5 +:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375 +:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95 +:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355 +:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55 +:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335 +:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74 +:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314 +:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53 +:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4 +:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32 +:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4 +:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10 +:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4 +:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC +:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394 +:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4 +:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374 +:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94 +:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354 +:1044E0000040CF3CCDCDCDCD000C0000000700C07A +:1044F00000028130000B81580002021000010230DE +:10450000000F024000010330000C0000000800C052 +:1045100000028140000B816800020220000102407D +:1045200000070250000202C0000F0000000800F067 +:1045300000028170000B819800020250000102709D +:10454000000B828000080338001000000008010002 +:1045500000028180000B81A80002026000018280BD +:10456000000E82980008038000028000000B802863 +:10457000000200E0000101000000811000000118AD +:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B +:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B +:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B +:1045B000CCCCCCCCCCCCCCCC00002000000000007B +:1045C0001F8B080000000000000BFB51CFC0F00360 +:1045D0008A7BD81818F67020F843015F646260B8CF +:1045E0000CC45781588099812198918121849178B8 +:1045F000FD71A208F61321A019C240330419184E08 +:104600000B23C40F02D5988830307C878A5503D994 +:104610000CA2D471FF40E375529862AB2510ECF503 +:1046200058E491F10634792E4954FE4602FA071AED +:10463000DF5744E50B2940E86CA8F803347961A8FA +:10464000FC79A8BF1E2A6237F702541E005BBBD25A +:1046500053600300000000000000000000000000A4 +:104660001F8B080000000000000BED7D0B7854D577 +:10467000B5F03E73CE9C9949662627214F1E6112E4 +:1046800020028638BC0228B74E480850691D6C5578 +:10469000B468070810F296A297D6F6CB04428C8035 +:1046A00036F8FB408B3ABC2A2A6AC048510187A7DA +:1046B000E8F5F606AB9656EB8D68519147E456A5A2 +:1046C000FF6DAFFF5A6BEF9D39673201ECD77BFF6F +:1046D000FBDFEF8F9FDF619FBDCFDE6BAFD75E6BE0 +:1046E000EDB5F7D86D1EA65FCDD8D7F807CF7A1BEA +:1046F000632C23F67CC4CE7E18743356B0CEB7C27A +:104700009D0EEF77E56D4FF63196B37BAD3205DE4A +:10471000E7AC6F53E615C6BE0FB8A0723CBCDFB560 +:10472000562981F7396FB42973F1E9B0B14E68CFDA +:10473000345F0AC3270B3096C9D890894CFC05DC3E +:1047400039C58C0DC47F4217E78C64C6C63196B755 +:10475000D216092BF03E5439937919DB0470E5A485 +:10476000C177EA5FF6D9B16D8376BCCBC998537334 +:104770006A5FE733963B9BD9183C072FE3EFF1EFD5 +:104780006BF83F2F6C2D0F61A6721E963DE92760D6 +:1047900048E6619EAFD544F076EBC151B179CAE7E6 +:1047A000FA465FA65BEBFD5E3E97DCF6897E177CE2 +:1047B000FD18B61BCA5824AE7D6D58D7D815F00425 +:1047C00004B417F6FE7E262B29463ADCCAA6D0B3DF +:1047D0005EF3DD8878A93F62676180BBBEE1443942 +:1047E00096D92E850DCBEBFDFD2866277A943045B2 +:1047F0003B81F3F5322FCE4FADF13D540E786E482C +:104800000E9461BF0F2787E829DF67CF9B9E1D02AB +:10481000784A17158619D0FDDC3AC5EF80CF3F5690 +:1048200022BA1DE851FDFD86A269D0EE6D3D740DE2 +:104830007EB7488DB6D861FCDA390D054001D6A99E +:1048400073FE19BCABE4530DE83698B1704A1AD226 +:1048500085B1E3263AE0DFF1E1A2ACF68DC78B3DEE +:104860002BB01F0D7B89D07CE5FBBCF0912143E38D +:10487000C663C5040F433819EB5212D175F08B256E +:1048800047B4A2BEC7FBCF9F4798CB21E00EE95BA0 +:10489000EBD123CB01BFA52FD8A357033D6A3728FF +:1048A0001107946D7B5D01A4CF99CD5006BA443DAC +:1048B0003AB53F6D38A95CEFE8BCF72A2877BFA06E +:1048C000B28DD8EDF0241BCADD09013B1B0765C082 +:1048D000C742172FD66ED8772BF657B9CBC15C4895 +:1048E000CF17177DF72A282F027EC326B55B9AF4CF +:1048F000FE505E1C51DAB17C760A23FE08A7E991CE +:104900002D30DE596F67E6F5202F271B9DCC07A0C1 +:10491000ACF074667E1FF8A82AB2BD1CBFABDAA645 +:10492000F811EDA52F6C399C83F37A12F80AF8A8D8 +:104930007A6B32F349FCC1FF27602A5743FD129876 +:1049400027CAFF22D656CE541C7FADEEF3C4F075B5 +:10495000B2D1A0717AE4E9491807BEAB7B56F1E306 +:1049600014EB6C2C847275E645D7EC4D6E9C5F930E +:104970005EE0C179DDA563BB4591B93B5165554505 +:1049800036E8E5505FB57E83BEB010F1067AAF1011 +:10499000E1EA67856B9D1A40FC2E49756E54013F14 +:1049A000CC1DC8BE2E01FF9C6C043556102B57A1A0 +:1049B0007C933E89E8B34CEDCB9554E2D7EAAD2A1F +:1049C000F359F889D33F7C94D33FBCC713D99217CE +:1049D000A3DF1283EB4949BF25A9829E5A77712232 +:1049E00078EE457A003C6D882F78AE11F07927B3C8 +:1049F000120DE8E20D30436117E7CF363B9BCB60E9 +:104A0000EC37D982803609CA3ABB8DF91933B4DA4A +:104A1000401994FFC2826FE07C18F3FB8280E71696 +:104A200085CDC6791F4260613E2D393AE1AF6D6A8E +:104A3000F126551130A76379E12F57E5D1F76FD1F2 +:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3 +:104A5000FD7BD88E392FFC7D5BF995D6F1CBABE48D +:104A6000F71FD1F8EE0BC36F4C9B6C1D7F5A0D7D69 +:104A70005FEFE0F4EA4E75463642B9D9E50F684873 +:104A8000378D45F1BD9656B011DBA9921F5867408E +:104A900085EFDDDB52C7AC6266BE98F2271CCF0300 +:104AA000D262E68B948949167E4C0DA459CAD093E4 +:104AB00071E2F2981E0A789D048FDE5F277D51D245 +:104AC000DF49F0DEB1D745E53BAEE4F0DED1DF4DA6 +:104AD000728630B01C28EBA12B0CD37A04702A2CE0 +:104AE0009BB12F94904B196F7EEFB3E1FB2495356A +:104AF000E07C921C8CF4D15D79C59BC226FCB40E7F +:104B000002FA42395DD1391E055EEF1AB4307BAE30 +:104B1000699C9641FAEC8D85FCFD7C378E17CC5450 +:104B2000500FEADD0586BBF7388EFC8996719CB97B +:104B300095344E5EDC388EDCCAB8719CB3378AF788 +:104B4000629C21171AE7AEFC2BADF3C9ADA2718AA6 +:104B5000E2E7935B15374E129F0FBC17E3F8117F06 +:104B60007DCE67C864EB7C06D7D03857E138E34D7B +:104B7000F3195C13378E9BC6C1F7380E18523E9658 +:104B8000057477742F24FABFE2227B4177849EC09C +:104B90007ED9BB2E46FAC407E366A15E81C519E43F +:104BA0005753D2689C2F9380FE6E339DB93EA22747 +:104BB000E89F05024416018840FFD4091EADD8368F +:104BC0002BB7099FBB4AB3E7A25D72BFC73F0C4436 +:104BD000E7CCAE527D7E02FB66419BFD4497857F0C +:104BE00085DE9BC28637C0F81DA86C4CE513A0BFBC +:104BF00018E8ADE3A0BFF0F9B1B04F3F02FDC674B5 +:104C000033BC4D348F131AC7E389F57C1DF972ED5F +:104C1000513B187B38CC5B8500F70D621A0BDAC06C +:104C2000F833C959BDA047F78B8EC846A2476080AC +:104C30000DF89CADEB07B812EDC0CEFC83B047E198 +:104C40006F800D6CD99B5BB71FC266EF2873072D71 +:104C500081F9CEEE586B1F00E533F6AE5BFD6E5367 +:104C60003FB3EDC771DE4EF80FFBB92964B7D8A783 +:104C70003FA8B4966F89B3576B947C410F31AE2F28 +:104C800062477ADD90C9E1B9059F63B0DA207ADD29 +:104C90006AF06F253CF577DA5994D6A3AE0C5688A6 +:104CA000F8C820BB2824D79538F86EB53B0341A03F +:104CB000E7AD3F56098FF1F076ED4D0ED8C05EEAB4 +:104CC0005AF76F76B4BF2F06FF0F9759EB59988F9D +:104CD00027F12AF9E0C6D925FD3E32B5BB2934A318 +:104CE000DF47267EF941E52C4BF996869B2CED7F1C +:104CF000B86CAEA57E6E78B1A57E7EEB6D96F28225 +:104D0000B61F5BDA2F5AD764A95F1CB9DB525FBDAF +:104D100075ADA55CDBFEB0A57DFDAE0D967ADBDE44 +:104D200011D7A23CAE785B65689F7DE13E712FDABA +:104D3000575F189A1FDBD421AF811C7ED2984DFC9F +:104D40007DB2D147CF33BBC63AD11EAF4F02798671 +:104D5000B57EAFF28770EB64D423D01E74F87EE585 +:104D6000C370189CA7D7141FF1BDBA4E6751605588 +:104D700085A5F5F075B71AABD7BAA07E6CDFF5EA5A +:104D80003A2D61BDD6A525ECF7ACD25D80F65DF875 +:104D9000770E8676605FF603FC0DC0F5A2AFFA537E +:104DA0003656D96ED23B27141BF1C10DCA9413A8F5 +:104DB0009F6B742EEF353B72A6A03F58A3470B1A8A +:104DC000DC1718AF1D80C9C27EF2695E8B230362B7 +:104DD000F24BF41B6291FBA52CF447D4CFA7F6A9A4 +:104DE000A46759F440EEF746E1F88113F89EEDCA46 +:104DF000A0F5F19DC640BF8FC09F3BD6389D9EBF9A +:104E00006F0CF6FB0874CD7B8DB3A9FC7E63889E86 +:104E10005D8D95F43CDED840F51F352EA3F289C692 +:104E2000303D3F696CA5E7C9C636AA3FD5B88ECAE2 +:104E3000671A23F4ECF103843DCAD285FD27EC7593 +:104E40005839A87C4ECC41857F73BFD59F8D727D2C +:104E5000CEFD6501DAB9E78E816192C03F94CF78CB +:104E60007EEB9B7E015AEF174680FE637BD7BB9299 +:104E7000387D5C36369D81FEB97B98CE34183FE98B +:104E800095CBC95E86F71A237D19F1CFF224E81F6E +:104E9000E79C75713AF5F0C723FF5E8CF1871B84A0 +:104EA0003E4C3AA03670BA6DF223DD4CF8E376D969 +:104EB0000B429FC7E1916CB99CDEF83C9D21F1D972 +:104EC000998B7180FB95E0081BF0C1B90E07CDEB03 +:104ED000DCEEE408C36F313832E94278E370546F96 +:104EE000751966FD50DB9E6A58F5458E61D617E749 +:104EF0008E6CF2A2DC2FC9B6191F8D45FE0808FE84 +:104F0000E07C27FBAF6DCF33DC967EACE5736DCADA +:104F100074F48340B9A77C3F817F209F4BB275E337 +:104F20002390EF935B87A4E0B8E0C71938CEA94679 +:104F3000C3E0E3661B66BEAC599644ED257C7DF567 +:104F4000FBF7860F2D830F9D8C50FFF5906FEE675A +:104F500033ED4F14CF61BBED5FE2BAE380FFBFA634 +:104F600078804665D96F7DBB1A765C81EFB759C6EC +:104F700083EF7CD287C6F5AA6FBA6BEC84292E50DA +:104F80008763907FE4243A87A0C714E8EFACE66E0D +:104F900055609CE9361FD5D70B7EAC7576E9217834 +:104FA00075BA83D3A3AF714E361EF169A03F2A9D17 +:104FB000E091C13895ED23CA503F9EEE58911902F9 +:104FC000BEAD56CFDD114CF07DAB4DE1F044ECDDD4 +:104FD0005DA6F9C8380A63D0AF33063F72FA0953A9 +:104FE000395E5FCBE77DD82FF047DDB6A3E55701EB +:104FF000FC75BB3ED7118EE9B6D07DB68CD8FC15BA +:105000009C3FF453B5F5031DE7F7893D5C70E70558 +:10501000F4546F38DDD914B793F0855927DA31F39A +:105020007AE28ABE1BDF05D1FCF49FEC6C15C0C18F +:10503000FE02ADA0DE2E6A2B58D08BF89AD7514DC8 +:10504000F1C54F6DD26E6A2B46FE38CD6CD3717EA2 +:10505000A7D99BDEB126FC75D8B8DDCF5AB91D1390 +:1050600086FF101EB0672D76CDA275D6F242765D12 +:1050700026EA8D85F7DB590450B418ED22C91F309C +:10508000EFCD366EEF2E620D2D68CF690EEE1FCC80 +:1050900033983600E0AAFDD5A3C568F7BF6CB311FD +:1050A0007D649C61711A87BB2A3DA207A0FEC38E56 +:1050B000B1375C85DCE788B4E0BACC52987F0BEB63 +:1050C0008DCFF9AD56F82E067F3CBC8C2DB7C02194 +:1050D000FB9570A85B95402401DFBD26F94EE89151 +:1050E00034D56AE767C595DFB389F8A5CA54A4F338 +:1050F00069C319B6A550BD3F8AF1911D0EFF0AA0E4 +:10510000EFEDB66017EA67B00B8A98A9DDEDB6102F +:10511000BD3FA5BCB110ED53A6458BD0BF8735452B +:10512000437ED0053FA849DE228CC77A18AC9F2069 +:10513000970E840FFA69F154CE6445187F053985BE +:10514000FEEEF1961F51A0EC727730ECCF916D8D91 +:105150002FBB7CD6723DFE03E9309C511C2779B8E9 +:10516000B51E162C86FCE6F15BDFFFEF1E3C458981 +:105170006FBDC4D2F074BAA32A8CCF266AA7CC76AE +:10518000739D93C34F7E39B45F2AECF93AE60B5313 +:105190009C389BF3C1D219368267A9C7E70F43BD7C +:1051A000A20518CA1FC6AACDEB58FD7910B97EA674 +:1051B000B2D6AD235FD69FD75804F47D912DE4512C +:1051C000C723FE0264E73A01595F03C89A7BBAC558 +:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811 +:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B +:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF +:1052000062EDF212F557FBAB67768601FF55CF3D95 +:10521000E005E2B34FB5B64C3FBCAFD9B2D28B7C00 +:10522000FC8916F6E2BC3F8DA8D313F1F30DAA2238 +:10523000FCB1805B417F58D0E9E453ABBF8B78FF72 +:10524000728BDDC026F55B1D510710B1AE6331E7EF +:10525000A7AD8E0F78F9AECF919EF5BBACF256F5A7 +:10526000C4039918EF040C71BF9145C97EAEDBFCF5 +:10527000C772B447EA5937E989F8EF70FCF369B4AB +:105280007ECDD5537AD7CBFD977AC1F7F51DAB3FCD +:1052900057BD58B6CA77A5F047A6A99E748A2B4D6C +:1052A0006013906E120F2CC2EDE1154F3E54F401C5 +:1052B000C0716AF33F79154BDC88EB8773EDF31F00 +:1052C0007FC9D7B75E3F23FCF9D87711FACEB78BE9 +:1052D000DBEF6C377FD6D8A35EF4976A36D8FD2013 +:1052E00099ACE6994DBF7C04F9FA770E8A33543FA6 +:1052F00073E89D2BA15CBDDD9E3E934FC3AD64C69C +:10530000E8510FFF2F1B13C37FD5F38774DF28FEEF +:10531000FEA769313A546FDFA7B351BDF156DABE2B +:105320004FEF7227A047FB07E5686FAF78F22B1DA0 +:10533000E5EAD3BD0ACBCAEBFD7DE5864364CF2108 +:105340009E887E823E3DF4EA45A7E8775F1A47EDE6 +:105350000C5CBFFAA2D3485CFB32888F9F7D09E3C7 +:10536000F7BF77F871FE95CFFEC88BF3F8586BE066 +:10537000FCFCE8CACC008C5B690F671AF4E4EF2BE5 +:105380001FBB9DF86CD1D1DB33291EC00239365AC0 +:1053900043C33938BF05EBAFA7F92D6421E2B7CA83 +:1053A00047D56004E3591A9BBE3D813CBC21E4E132 +:1053B000E38D0E5C7BD8C7A860D13F7C53A57D02EE +:1053C000C66EA378C3ED721F822DA1F2174E4EA7B1 +:1053D0004DAA4DC6379C163EDD7C5727D2E7E4A088 +:1053E0004016C627010F61812F05F58E7A746A1663 +:1053F000A70FF369C5E23BD08BA5F81EDB77DA0374 +:10540000AE22CB77621DE3E32F15E303DC49688FFF +:105410007D9C09F64D82F97DA54ABD0CF68689BFB3 +:105420004C72CDE57CF3DD5CAEA59C47664DC7FABA +:105430003FBDC5E507BFC3751DE08A6651FDBEEFE0 +:105440002BA4071C2C9A489E37DB853C5BEBE5FEC2 +:1054500024C0ADE1FA14E313E83F8DF04F76DAC2D1 +:10546000FBE13B935EAEC7F1A89D1E7B6F5AD71739 +:1054700009F97F5515FBA342FED97A2EF77DDBBDD6 +:1054800061EE1FD823BF7C04E515E413D7999A6712 +:10549000EC419CF767DB0EBC7333F0F567ED524EC1 +:1054A000AD7A335E4E2B778C6789E4F433B79F2552 +:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17 +:1054C0004C9CDE947AB02FFCC5EBC135AA2FA11EEF +:1054D00084BFB758716FBE93FC26F9ACEAE9DAC114 +:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3 +:1054F000F8FA1785BE9174B62F67610FC64BF7A8EF +:10550000E45F9F05985A80BE67B7E54530EEBCD290 +:10551000C5E317678D6E6F1A3C57A6F2727786DE69 +:1055200082FA41BEEF76F1F8F6D960B737D5E45785 +:105530007CB05BF5FAA0BE2BC2A627F23740F3126F +:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0 +:10555000D27E7645D38D5EDC073EBB7BC8CF513F04 +:105560002D780D0C4C80F72CDA812938BD80867996 +:1055700009F305BD3F61E10727C3FCE6EFE6FE4204 +:10558000C59A38FBDEBD54477D03F6FD716B5C9B0D +:10559000F34D95E8A772BDB5BE8AAD21BA55C5F1E8 +:1055A0005148F8811334C147A3D968E187F1F885E0 +:1055B000D05753D5C29FA39D71F6088F2B9EDBADAC +:1055C00012FECF6D532218F7A1F8EE24A47FB7CEB8 +:1055D0004CFEF229E437BD6F393EF5C21F8AEF84D5 +:1055E00026353BDF2DFA053C4FEDFC5DC1CB58FE67 +:1055F000D56F73DF65BDDB97EEFD33ED1F9FDDEBF0 +:105600002038CEEE7D35F74E2CBFE4F0239C679713 +:105610003B68FF2CBCD7131986F58380DEB86EEE8D +:10562000F9AAA88BD69D66A2D33C8DEF779CDBFDB3 +:10563000EFEF2B987FB0DBE1C379D4EFE57921F56B +:105640002FB928EE7276CF57C521F7DF6F3E753A36 +:105650000B11FF79D8EC1DC8AFA97C1FA0FEE5494E +:105660009B9A703FBC639F8EFB2BA5AFFCB508F5E2 +:10567000CBD91DDC4E3863EF7A0CF7416BB5A1CB6B +:10568000ED28F768B3F507BBD3BE604AB830115EAA +:10569000381ECE021E705E80974AD48B7DE1A359DE +:1056A000E3FEE67F3F7C7C7E2B8E5FB37B02C94DA1 +:1056B0000C2F4A80BFF7449C0ACD9FBFDFFB5511DA +:1056C000DA3D9FB537D13A7EB1796FFA1F376F2532 +:1056D0007A29F3DEFFDF9CFFA76B7C5D8A9783DE70 +:1056E0007CFEAB3BA8FCACC74FF05EA2FC1FFF9F4B +:1056F00046F71D4077EFC5E9AED8FFBBCEFB62741D +:105700007F4DD0DD63605EC1D93D7FA578B99CFF38 +:10571000C5E6EDFB7F74DED2FE5965F3B7E543FBCA +:10572000352CDAE90338570EBFAE0DC34CE0260422 +:1057300013D923413BF78F5485C761D8201E1762C8 +:10574000C29FA014301FC65116925DA7B95BC8CE88 +:10575000649ABF3300F85835729E9F7235D89863AB +:10576000212C0F9CECA7F8669C5FA58DFCF611B46C +:10577000EF9B9B003E18A7D9A319602931FB705BF2 +:10578000D45144CF0FF079978867D90DDDE257B82F +:10579000E3FC0297CF5AEF10FD3BD97E03F3889CC0 +:1057A0007E8D45B01D6B0B9BF3071CCCF41DD417ED +:1057B0006200D6643F7E53FC35F5E06F4C6700F124 +:1057C00037C246712D4AEA237CF823AB781E85D375 +:1057D0008ACF964EC4A3C6C0FFE3F322BF91097FD0 +:1057E00051135D68C36D0197B59DF08B2E4A1F4E16 +:1057F0008FDC1A419F25167A48BC5F802E167A48A6 +:10580000FC7E53BAC4D3231EFFDFB7F3B89BA49327 +:1058100025BF2383FB2151F0435EDDB689E21DA73E +:105820009FFAE0BBC8A7D52FABCC09DF9FD9E661B3 +:1058300051945F2DA2A33F55D5A1268CF34ABBBC42 +:10584000FA390FF179D50E4764267C5FB5F3C32290 +:10585000B29B96771F1E807181A7144EBF7057119F +:10586000EEDB5569DC3F88EF6FBD9DC7054EBD98E7 +:105870003C1BE30FCA569EAF58D57EA3DD61DA7795 +:10588000FE5F769EF70AED489EC34F2AB4DEF4868B +:105890008FFB05A79E54387CBBEC11CC7BACDABAED +:1058A000410FA15FB9F5738A63973EF78CB78BFC04 +:1058B00045D5EA3F6F55899EF024BAC5FBB1751DE9 +:1058C000B5E427D4B50B3F31CE8FAA7E6ECFCE3054 +:1058D000A0A6FAF927BC187F39D9B9C54BFEE956FD +:1058E000EE7F6A6E2DB17F7A31BFB4FDEE847EE922 +:1058F00049FC07F813FBEC71FEFCD67E97B67FF9E6 +:10590000CC178F619CF4D48ECF1E43B86BFEE3DFBF +:105910001E43FB9EED75195B60BEF54FBD4DF12634 +:10592000F9DDBB424ECF0C62E11C6877E6770ECA08 +:105930001F39B3E7E35CF4E7CE6CFF7326FAF54B4F +:10594000F74CCDC2792F7DA1348B259077F944BED9 +:105950008C5C429C309E0E073A0E901F72FA988320 +:10596000FCBE9EF8427B2D8FD7F8445C615BE23829 +:10597000ACF487EB3A3E2CE7F131E1175F2C8EF067 +:1059800016D0F18A4BA0D73611278AA3D769FC0716 +:10599000D0E5AB387A7DC1428FE7E03E6447BF3E39 +:1059A000E308D14BC0938CEF1EB6076C3ACAC18E88 +:1059B000E41E3ACD443A3DF3452EC6C33FB177933A +:1059C000DDD3BDC761A07F5FB5E7B72417675E3839 +:1059D0004AF15326E2AC6758CF1F8F8B29627E9B1A +:1059E0003D3CFE20F08DF1099F97DE8B3804E75790 +:1059F000199FE82B2E314117794F22EE5CBBF95DE0 +:105A00009DC5C579948948A70F2CF17139EFF8FE2F +:105A10000CC4C304737C2D71DC47FACD313AF1B864 +:105A20009A8C9F9DD920E26EF07EE018F407791CD5 +:105A3000A33EA2FC96259043195F1BA3C7C961E44E +:105A4000D2E26A1783F76FC5C7309DAF0B122FA73D +:105A5000FE92580F7F47E7723DDD169AA99BF6B379 +:105A60007F28F65924BE24BCA7441EDEA9A7548A69 +:105A700007B5B41F207D1A2FCF757D9C83B855E7DD +:105A8000F1D6BA5DFB8A50EF9CDAFF22F15DDDB6FC +:105A90000FF430F47378EBF33AB727399FA39E8E57 +:105AA00098F4F4A967F715F1B81FCFBB8DEFBF5A73 +:105AB000F45FBFDBDA7FFDB6CF2DFD5787DB75BE08 +:105AC0005E5E789C935AE0469CEFC94E3B437D77DF +:105AD000B25D9D1E496407EA76CB3E68CB519DD6E8 +:105AE000AB716F26517EEED2A3D3DF4DC17D3A104C +:105AF00033B47F3B9A385F75FC2C3000E9D271F4E7 +:105B00006615D78D9D8847931D5CFC5643A907E415 +:105B1000B5F8BDE03864AB783D30E198CD02378C04 +:105B20009385FAB819FAC17C7ACC1FC2FD51D55BB6 +:105B30003E1DE1510D9BE14AB87EF2FEECEE2043A2 +:105B4000BBDC6E58F395B3AF1371B4A8356F3D5BF2 +:105B500067C3711F9CD992FCB81FB0644460F421E4 +:105B6000CCAB5F904D71E29CEFF1EF4E1BEEB0EDD0 +:105B70008AD8BE6DF279E81FF3606C91B573E0BB13 +:105B800064AD5DC17D007832A4CBEDB6D0463D0357 +:105B9000DBE9CC07AAF1315DD128FF429C7B91FD66 +:105BA000C9767DED07CB7348AA807F88D80F1EC4C5 +:105BB000BA14DC0F5EEFE1E79106BBD3E9BCD12656 +:105BC00061AFF970DF15DB3558D7ED8B9E476AB5AD +:105BD00096D34B4B6E1BEC073F58BFA354037D90ED +:105BE0007E63C9F60106EE4BDF5F8A79F7E94F94D1 +:105BF0008CCE81F26C475119D5FF4BC9E85C28FF68 +:105C0000A8755219D5572B9417B847EF2E0DBB63C3 +:105C1000F29901C62DE65B80DCEE47B93D1D3CD50F +:105C200082B5B5D77FA9F3F3302C88F31F3491CF19 +:105C30007FA0FBBDED38DFC1B6AE26E4BFC7F77C61 +:105C4000958AED7CCCA0791AACD9C07D797835F1F4 +:105C5000EB0BE4FFC4E7C1487E7F2E39F41B84E3DD +:105C6000EE79C31F2A479D5AE3273E8ADF276646FF +:105C70003AD1A542D005E1749AF2902BF12402E9C1 +:105C80009B3203C751C235EAD7977F73784E487E5F +:105C900011E7C04CE7A43E45381F4E0ED133FE9CA1 +:105CA000D47E3DF819F253CEC2F3B908BF3CFF547D +:105CB000BAC84D718173BB59C491407EE4736323AC +:105CC000CBD086F65DFFB623F4671C37FF15DF8E59 +:105CD00023D0DF1515BA1F53D7AE58362E431BCB32 +:105CE000F884D09E1074CB465AA27CDDC1F8B91C52 +:105CF000871240BFF1EC8F0CD2BF032B66925F710D +:105D00003639AF1DF327CEDEC9F300608557500E3C +:105D100006ED4E89A2FF037CFC651C1F7F695D6751 +:105D2000ACE39EFDDAB7AB8BFA33447F60E864A244 +:105D3000DCF0BFB32AB7B3CF36FA080E300BF7E169 +:105D40007A7AA9E3653BACE7F400EFFD1D26BCE7DA +:105D50003AFAA45F9E83D38F9EF1F45BE86CC8454A +:105D600039AE0AB697A36BFAF1C23B8A91A9DFD686 +:105D7000439761FB9AD99D8779CE504301EEB3F5E5 +:105D8000A62F3F8F95B97B6E931DE315481F5F6F5C +:105D90003A5EB1CC9FA1F5B3D0752CC27FC5EECFD2 +:105DA0006D08BFA4E74322CF3FFEFB6F3914316E6D +:105DB0004D931DE324BB74B267E3DB4DC74355E34A +:105DC00063E52267318D9B65E3F18EDEEDF9FA170D +:105DD000EBD749E7B2FAE2C72283F707F8FFB61913 +:105DE000FFDFED1BFFB3B01DE09F9EDF00FF3762BA +:105DF000FBBEF02FEDE86AA117AA711F05F8E88F26 +:105E000081EB3287C2F8E5AA9BE460F11695E40FB6 +:105E1000DACFCCC98CE991C5931AF6E17C173FAA79 +:105E200010BF568873A69F89BCFEF87CA885B3C3B3 +:105E3000B4BFD32B2F2A12E7D7C5E5BBD7C7F87657 +:105E400030CF53E3E7B6542117A58B0A53D01EDA9F +:105E50006BF7FD0BD9D9AFA96C6302FC6F402633F9 +:105E6000D1755083CD9227CB2A522DFD962D2AA491 +:105E70007DEF251EDF05FDAAC1CBACEB765ED87A9F +:105E8000CE6848ABF59CD1B0B6FE96F697ADCBB7D1 +:105E9000D48F888CB4D45FBE758CA53CAAFD4A4BC8 +:105EA000FB2B764DB1944747BF6D693FF6C8759699 +:105EB000F2F8CE9B2DED271C9B67A99FD45565A9B1 +:105EC000BFEA932596F23F74FFC46AA7D818E94742 +:105ED00096A490BE3CD8383117F3B1D938A50CF14F +:105EE000592AF2090FDEA6DB0C2F3E0B6C06E8AD3B +:105EF000FD0B66D2BA7FF0B6CC808F9EC501F46BE5 +:105F0000983A795CA27CCDA9C6A45C735E54A9D3EF +:105F10006ED16F530D6B79A743ECFB0DE67CF372EA +:105F20009C7CD91B2647C13264FD170FCDC2F140BE +:105F3000CEF60A3DB7F792F45C6643319641CE0E39 +:105F400026923326D6D912C14FF00CE8981F59E695 +:105F5000A1F538802F7DF43EAC81BC4C71FA071E50 +:105F6000C279D9FCE9C88465B38307797F625D662D +:105F7000C36DDF645D96729E6D13F96B693C7FEDB6 +:105F8000E1050529CC84DF3F386CC28E6EE34FE318 +:105F900088AB276F35DFFCFE9324CD942FA72C9A76 +:105FA00049F922D97DE8453D3B7FC666D0C77A8E48 +:105FB0008F9EF27DCB6C5BC23CB06EA147A5BD3518 +:105FC00022666F75233D4E67BFF920E629D5CDE9DE +:105FD000267B2BDBD676DB619CD7EBAA885FFAF8B1 +:105FE000F92A61272F9871DF6D87715FFA9F87917A +:105FF0007E92E3AC6F9C3E43339D231FD887DF74B2 +:10600000B993C3F358E3F0191594B76DF0F3A2A256 +:10601000FFDC706D39DACD8345BEE983B6C4F92E55 +:106020006ED14F16921CE135DC2427A717BEE7D5A9 +:10603000601E8FC0EAE5C47DDB2B3A8BB91D16F0DC +:10604000E339D4DCE82D0F62FBDC6C8DF25DE3C735 +:10605000CF9A136ACDC3F8679ACDEFA672B782EDD7 +:106060001D3F65AC1FB46FFE0F95E069DE3F89F2FE +:106070003F1CEE0686FBA9725E07D21E21FCA81DFE +:10608000C9B40E32B12F2EE3AD5F645774A2BDF1D7 +:10609000C5FD761AEF0B98A301FD7FD1A1D2BEEB0F +:1060A000E1B4A4A80DCA6AAB87D6EF5CB43DA1FDEC +:1060B000C20E4FC49717C38BB66E329D87710CE426 +:1060C000F36F4E7347DC7934EF749CB78453CE7B07 +:1060D000501F7E6689803BE7B29E731A0CF95835D3 +:1060E00034EA77412A3F8719699C28E8659D4F4B20 +:1060F000F675D7DE84E787DE5219A686F8BADA6825 +:10610000FE0B61FE115F6FFC9EF6E57D695309CEC3 +:106110001284535D574EF3A076F05DEDE30A7B24C5 +:106120000FF930349DE8DADF46E7027BD9074E2EBF +:106130005F339C3C2F57CF2E98B1B91F3E87925C9E +:106140007CC7D9E7BA1F74727D44CF6F70BF00ADB2 +:10615000FF521FA9019BB073B95EEAB19FF4D00F43 +:106160009C19B1B29AF2D322ECB76FFB6CFB3E1DC7 +:10617000ED333723FB59EACDBEEC33B4CB90DFA42B +:106180005DB6386E9E30BF1A31BF9A44F3EBA56FEF +:106190006F6E9076CD12E705ECCA0C3DB13E7A5297 +:1061A000D0A1DED019C59B688D02BDB3D846E78D5E +:1061B00099167199CF97AF774ABB6EF73E1DF10CD8 +:1061C000F3463C6783FF5C4E7AC79E302FFC62FE2D +:1061D00048FEEAC21D47B03FB07311FA736DBE941A +:1061E000B40BD817F665AFBBCC78BDCF29F2B96335 +:1061F000787C40E0F18184784C073CDA2CF6E1CEE3 +:10620000021FE1F117CE0BD887A7BFF77E31AE474B +:106210006704BEEA7AFC5CAE9FFBC32285F1AA5AF2 +:10622000CC5F76F232EE07E15E0CC6E18A6CC127E4 +:10623000B0FFFA5DD673873F73F2381973F373B307 +:10624000B2BF4CA1EFC1AFFED61F7DA4F7FF11E78F +:1062500013F3AFBB8AD1BF5AF1C26529689795ED98 +:10626000BCC9C0E7B9F4A1B49E9DDEE908209CA793 +:10627000D378BEDEE99D130E63FCE1B3C623F96655 +:106280007D7FFAD9A3C576E8E7F48EA3C51AE507A2 +:10629000472C7661EDD7BF29C6735832AFBA875FF6 +:1062A0009C7C9DB8DFC5E31A19997A0BE68B9F4F4A +:1062B0004A257C3D9069BB3751BC06D527EDDB7B79 +:1062C00074DAA75C32C2B7C28DF19A3C83F2705780 +:1062D00028819C05B8CF32CBE9C77D80F47C363C61 +:1062E0002F055118626EC0A7E3601B1D374DEA34BD +:1062F000F6A17924E3385A29D7B7DDD7EB9437963E +:10630000ACF91E9A03E5ECD91AAD7732AEE348E654 +:10631000E792655CA7079ED7ECB40E2DC90BB59527 +:10632000C0774B26A5D177DE59EF10BF9CF5D9C2B7 +:10633000769C8FD64DF19D9F370ECF180A78347218 +:106340006C33C8A6F90B60CB94FFEFD5583805EC39 +:106350009BD5C0FF4381FF3B1A9DD4BE05EC432370 +:106360008DEE4988DDF361929B1D8D06B5FB65635B +:10637000367D775FA38F9E3D7604E3DF5139817EC2 +:10638000FDCF7ADED3C8EF1391E57F1B07761AD0D5 +:106390003B7D025015F0922ECE9FCBFA471A5F1B21 +:1063A0005236542003F0D9BFC6D8B0EA02F0A63B5B +:1063B00022A978C4F872170B974DC43CBFEE7BCB73 +:1063C00053F17CC45D656523008FB8BF7D2590CAFD +:1063D000755F339E4FCDA9F13561DC2F6797D28E63 +:1063E000EB57CEAEB525B88F00EDE8DCA0EC37C397 +:1063F000C5F55CF2818795FC51B8B9C0F7E5D99E27 +:10640000E448A2F3A5E35C5CCFF95D7C7F70B5D86E +:1064100057EF9EE526BD987CC045FC92B3FB72DA2F +:10642000DF73F7B1AF1CDF4FF2813F531CD8ADB41F +:10643000EDC37D4AB680DB9F929FFAFA0EDBEB97A5 +:10644000D0FEAC5FA3B83098BD34BFD3B30612BE44 +:10645000B1BD598F9FD513DB650181A795F6C47136 +:106460007A8DF171C67576D37E26DEDB84F8CE791F +:10647000AB4D417FFDB4C2F331FA033E764039673C +:10648000721BDDEBF49C3354EE82EFFE641C2B5840 +:1064900009E0B80A7F9F8BDF497CA845BA13F5490C +:1064A000CEEE0FF8391F5B978EF96F8BEE7E9EE272 +:1064B0008FAA1ECCE3E5952B313E99E10D6E403E4F +:1064C00061E1E7CB0E029F3C20CE2DE31BD47BABDA +:1064D0005DA21C6E6F0E009FACB6F3F2A2BB9F23B1 +:1064E000BE596D0F2EC673CF586E86FE57A7B6677E +:1064F000DBA0EC6E7AA6F9C8202CCBF6CF34872728 +:10650000831DEA92FA39988378EF291B501E652A79 +:106510006BBCCC9CFC29E7577BE0CF870700BFD43E +:10652000EDE6F7DCF4E06DD75A05D7A35F361EF130 +:10653000356B424EA4FE8075FEB26C467E8A1E51BB +:1065400022F90ADEF7D19A69CE57F941B222E21652 +:10655000F0BD39FE1877AE8D8ECAE0FADCCCF3427E +:10656000E2E9FA7652495B52069E470DAD52510F51 +:106570003E633728AFBE4B23BD7D4AE6D537D8C929 +:106580001EAC11E75CEDCB43AB46A05CDCA2F9315D +:10659000BE509DD75682F650F58B79FE2616CBD38A +:1065A000AD4E6DCF1CE38EE5E9CAF20A1197CA4AD7 +:1065B0006D484D2DC4FD98B5B9B85F52C7DA6EFD70 +:1065C00009C2FB86CA90DF3FDD372905EF1DAA858A +:1065D00032C6C16A3B8EEA2168776512BFEFA6AE6C +:1065E00003F8C6CDEFA1091430B641339250CFFF66 +:1065F00032D030124DE24DAE5F97B9FE81B127F235 +:106600000306D2F995BB8F353BB1AC1B23D8682C60 +:10661000FF6B33F259F5681BE559B2F0BF1E0C0C45 +:1066200015FBBD506E750D9A6A8E7BE7887386F5F3 +:10663000EBDD741E0CD6E58DC8DF75EB6C61DC3FBD +:10664000B3393BE91CD02B2E26E8633D3F75BFC212 +:10665000F56178018FA72E9D91F66D3A3FB532DF37 +:10666000085F20AE5B793E89CE49C9F295493EEA82 +:10667000BF520BD33E52E5792F9DAFFAFB8DE7B4A5 +:106680009CD7EA3D9E9BE091E3D5C4C623BA1E1871 +:10669000F3FA8343816E4BB7DB6D0E13DF2DDD2ED6 +:1066A000F6E75D812CEC2743E77866E80F02AFD16F +:1066B0001D37BC1CD6B241FF4BF90E9F6B2E9B8C35 +:1066C000748BD533ABFC07D01FBF274996FFBDB9EC +:1066D0006C6082F64971EDF365FFEA4AEC3F1E9E5D +:1066E0008CA458D909EDB5BF3A7ACA08DF5A5B5C69 +:1066F0007F69B2EC5E89E34BBE6ABD3BFD5018F882 +:10670000EA9ED4B612D4FFDD0B980FEFD1427EF58E +:106710009BF46DAB8BCB75E5F97C0BBD63782FB02B +:10672000D0E5E3C66CCBBEE7A2394B697FB6D52571 +:10673000E8C5C2FC9CCDFA012C628A07FD7F38FEB9 +:106740005638AEEC038E6FFD17C3E1B38C1783632D +:10675000A805BEBF158E8D37147C3B0F9A3CA084D4 +:106760009DF9B82EFC8CE7C5A9A965BE26DC97F972 +:10677000994671FD618CE7BBE46BEC883606E5A7B2 +:106780002D807110B69CDB2BF0BED53E86D621F253 +:106790001786EC76CCC5BC8DFCCAC0627CB2818504 +:1067A000B4EF23F749998813CA7D9E61062BC17BFC +:1067B000FF8E27CDA5752A3F38A71AE3EAAA675CA2 +:1067C00012AE870FD822611C2F7C1F1F2FC31669A2 +:1067D00077A2BDE41D6AE07A97E1E5FA8FAD2AA4BD +:1067E000F56FA32D7FE46D00C74AA524E935C47376 +:1067F0006A3EC5C7F13DDEB3B351AC5B6AAADFC0E8 +:10680000756AA358B75608FD2EDF27A705E7A21D16 +:10681000F1F355D3A63A27A11E0AB4F683F5E6DEB6 +:1068200055D356664FC2F5C697EF84F5E5DEA469E9 +:106830002B9D30998D4DBEFE466AAC3CECAFB05AF4 +:10684000939E98B632007AA7D9BDA40AED1CA83F42 +:10685000847EE2136952EFF0FA7CA9A7502F811EC3 +:10686000539B7ACA61D44BF93D7A671AE99DCD8F63 +:10687000A9545E0AE3A11D03F308E3FD60DDC33400 +:10688000F28F5C004B12945D23F269FF0CE6CD920F +:10689000D0FF1FC1EBE57E873ECC46FB1DD81EF125 +:1068A000E8CAE1EDF559FCBCB4EE7193DF26F74F71 +:1068B00054B17F9724F254146316F9C1CE35639610 +:1068C000A01FE51C6ADD9FD6E3F259D4F8FC1677C9 +:1068D00094ECAEB62411BFEEC7B2E9DE04F11E2C73 +:1068E000E531F8CCBCA9B984EED3F33003F3A9B3F6 +:1068F000435166B697E4D301EBA8CF24370E370B8C +:1069000024CAA75898CCED61F7798DFB890AD8374E +:10691000B88E7A841D2EEC23BBBCE7286EDD95F67D +:10692000925DDCA7B774C6942C3C97A4BA034EB40E +:1069300073F61963689F4665FE6B4B4CF64E737495 +:1069400006C5273523C0D0CE795DD839AAE1676660 +:106950003BA7A5111C7058AB361517D0FD358FB865 +:10696000A2CE2148DF076C7ED41B07C65485158C48 +:106970004F2E6324A79B8A33A7E03EC3062D98724F +:106980000BCACB5B309E8FD38DEF73AF50309EFE22 +:1069900085339882FAE09E5466F1A3AE4DE6FEC8B8 +:1069A0009624AE7FA49FD002F044010EEDFC48BABD +:1069B000CF67B4B04BF53965142FC334208C7F3AC0 +:1069C0005803E587CAFBEA1CD9364BFEA376BE887E +:1069D000E2895B92F83872DCBBC47D83B2EC640D53 +:1069E0003C6E0C3C9EC87FAB15703AC01EF2917D88 +:1069F00012B7FFDFDB3E227B45D2A7C74E51F8B965 +:106A0000D0BEECA3FAF3368B9E8D9D67D7492F9F9E +:106A100011F705C83C10B7D0672DD9A1B6ABF2620B +:106A2000F70368221F648DB81780656BDDE673F885 +:106A3000C9188F81FA669117921C77AEDFE55E4A1E +:106A4000FE826BB8663907E66421FACEE1B3BED7A1 +:106A5000B2E3EF0B08F7E48151DEA2C61E56E872DE +:106A6000006EEF0E107958A793DFA77823D8BB07E5 +:106A70009CB42FC1CF89CA78D837B58F5F47BB8AFE +:106A8000FCC2E9A3B1DF45B81E613C9B0573F8A6C3 +:106A9000633BA3BCA1247F17E3778E91BDA54A3D3C +:106AA000177EBE19FDA80CB37D67B2D72E5FFD7CA3 +:106AB000737321F91D545E74771BE9C1952E595EDD +:106AC0004D6558AFA2E8F7B09D0E1FF2137C1F4032 +:106AD000B961371490BDACE6834B0B7097E1FD872D +:106AE000B83FB0D3B111ED59F06BE7B94C71B2D3E7 +:106AF0009E63B9AC30617F614B7FB9DFAC3F18BF9B +:106B000003F38C647D99775D54E5DFF9F03B36B093 +:106B1000F3FD30F4FFC00B0EBA9744DEB31CCFAFC9 +:106B20005392B9FF8E7AC39CCFA9CFA90820734A8C +:106B3000F974642759F2BFA5BC6AE787937CCAEF52 +:106B40005E4FE2FBC79A16A0B89A76BE90E47F8BA0 +:106B5000A06B4BA3719171D2FA18670CF5D3F7387B +:106B6000C5424F30B13FA619E67B64FA92D7F8FDD3 +:106B7000C078FD269F52BFED15FDCF4DB6C697AB31 +:106B8000D6B51F4616FA892D54913C1EF3BEDEF38E +:106B9000E2525C638B16A1BCDDDEFB7D1D4EEE4731 +:106BA000224E50B0F5B6FDC8AE0DC9A1F54950AEA4 +:106BB0004A16FB00D9B0AEA9B86EF1BCA587B11ECC +:106BC000F31B42BE87A6A29E9A554EF1EBE7928335 +:106BD000BFC1EFEEBEAE98620512EED58D3CDF4E22 +:106BE000EA4B37E20BDA3BB4061EF77407A2685F84 +:106BF000DC97FCF6540DF950E372B06CF5FE951875 +:106C000017716A7EE22BA7DBE6C3F5DD09FE1DAE38 +:106C10007B4D6E1BC59356E03DC0F0BE599969A0EF +:106C2000BC2EF1E467B10BE847ED7CA6D0BFD67B64 +:106C300075FEFEE3A4D3F7BDEEEF3930298AFD6976 +:106C40007E46F93388840F4D7A55AEEBF1DFC5F7F8 +:106C50002FF129F1EBD04284571DED8604703D9948 +:106C60006CDDB7CD92FA33F59D8228BCAD55BABC28 +:106C7000689F805E7C12F9A46E54F7AF151FE9D3AC +:106C80004C6ECF84E57D0596FB91645C5E7573BBAD +:106C900046C2BFE4B5079CE67DA77878E3D74B777B +:106CA000A1353FC3393029EEBEE0263E8E1624BE04 +:106CB000B14F0E38514E9A8C3106DA2BCD9AEFB780 +:106CC00001CA2BB193DD0C76B8657CF9BC47DC0FAB +:106CD0007C54D851F1F51E719F72FCFBCF85FD707D +:106CE000CFBE9B480FF7453F3C508DF4F5E433038E +:106CF000CFE7D805BCDE8BF4DB171FDDBB8FC77574 +:106D0000B589CE08BA58F1E3A9F66000CF93A9A3DC +:106D100019D9BBEA203E3ED0D2C0B8B0775C1A1B6E +:106D20006E5A67EF1E7A1DBFDF39C3A0F37DAAC775 +:106D3000164C64674A3C1D4C96F75470BEC9967C4D +:106D400033ECF7740FBA896FBA13F1CDC164AEAFEB +:106D5000100E333DEF1E9A9F95883E31BDC8F9EA6B +:106D6000627CD121EE4BAC45DC807F5323CEDB9F90 +:106D700012F704CD4B16F70519DC2E96F75F7468F1 +:106D80008164B4ABE6F5EC5307E85C4A8D2B903296 +:106D900009F9F228B77B3F2EE1F7967D6C0FA4200E +:106DA0009E3F3EAA2A4DB4CFCFF302659ED5C7764B +:106DB000DFEA91503FFF176AA089AAADF6DC2916D9 +:106DC00018FBCF68DFEE5269FF28EFBEB9EA2868EA +:106DD0005F01861EF2D1BC527718D7DF8EDF37BC39 +:106DE0008F7A68FE630EDF7218E7E0BAB15F62F96E +:106DF000C41A8FCF4171B27C05EF155FBA36CFA0B0 +:106E0000FDA3654CD81943CB4B8732F614FE53C60D +:106E10009D9D74CFB8A80FB694C1FC466674D8DCAB +:106E20000053C41D6CC1734E2B9B82D9E8FF5DBB20 +:106E3000A6A005E38F999981CEAB411FAF5833BC13 +:106E40001CFDC18E47447FE1112DE8EFBD6C0BE5C1 +:106E50002950FFD49A29E594973B44F67F03D5CF78 +:106E60007BFCB22F8F1988D3CA728C9915CF91F001 +:106E7000D49697826E5F30599697E8584E4F669633 +:106E800038983DE64F529CADA3C77FBCA31CE3607E +:106E9000F3A734946AD07F9EE7A72D85201A13DAD2 +:106EA0004A8C005E99EBB9AF3C39036FCD0B54E3CC +:106EB0007A32D2737F39CE27BD9FB5FF7455C45344 +:106EC000D9BA16ECAF07BEF0D6168CAFCAF66FDE95 +:106ED000F34E4B78608CEFBF1BBB5FE93BEE0CBA07 +:106EE000B7EE3086D8729775EB3C9F57E4DF0CEC19 +:106EF0002AE27945A23CBC8BE75DCB72362F772C1A +:106F00004FBCCEFFDCCBE5AD232971FDCFDC5C5F50 +:106F100000DCA4E7538EB1C0B6047254E17653BBD3 +:106F20004360E739D362F274AD83B18998DFE4E45A +:106F300070CA7EE2BFBF538CC3C2D7A6211FCF1435 +:106F40007C3EC4AFF03CA55DC911FC3D06F0B2B477 +:106F5000EFC17CB68A78C45617FBE12C183A338906 +:106F600085F0DE9C8C7E502EA4EF03DBDDB1FEDECF +:106F7000E022CCA60E096EC6FEA666E58C5E9117D1 +:106F8000EB07E06E768EB1C0AD4D4CC3FA707F8CCE +:106F900093F4E0B390CF03F884F005C33C8DBF1F9A +:106FA000D0D139321FF5EF484CBA31E9F9E2CEEBD6 +:106FB000E83CCD52AFD81FF1F1EF334A79DE4BF701 +:106FC0008BC9FCFE4C676781793FEB21B7C833B8AA +:106FD0006BE643740EBAD3CEE8FCC2F6920BE61D04 +:106FE000D6605CCE6437D66851F2C76A302E371649 +:106FF000FB7B83CE1F623F3E117FC6B85AC68AC450 +:10700000F497EB60CD798385FBF5D697B1FED35924 +:1070100078ECC5E715EBCFEA37F6EE4F17717C81B8 +:10702000774DE05D4F0CE75EC9A7806F9B89BF1667 +:10703000087E93FB8167768ED868DE7F95E7864071 +:107040003F3F8DBF8F10EE4C227FA5580B5C83ED28 +:107050008B3BD3687F40F287E40B49D78EB4068A16 +:10706000B7743FACD039AE78B80E49B8D6F17BFBD7 +:10707000B2E68454F33DE3521EA0FF0ED1FFB8895F +:10708000243F8F727900B9B905E517EF61C179F82E +:10709000BB8ACCBF4720E12F425E1C4F74E4F87FCF +:1070A000C125F25738DE7AE3BFFF45E8994BF42C4F +:1070B000EEDC4FF3ACE9436EABBC5E9EC7762CEAC8 +:1070C000F541BB3182FF3BDA3FA47BC53A76A94C40 +:1070D000F1F179A3DE2AEED1C7E35F9D02FA38AB66 +:1070E000A70CFAD28774E8D19F51A733D6FE07DEEA +:1070F000F1D39A515F8A7B7BD355586DC6C4E0F8B3 +:10710000939BDB57134389E3580D5E8F458F3DBC3E +:107110006C0AFB10E67FA59BE75F4DEC0AD3EFEA14 +:1071200048B98ED753FD3C9C8E86E7FF929E725DD8 +:10713000444FB9A49EE2EF0FA1CD3B06D7D7AE22B4 +:1071400005ECE60A5B2013FDAF8F8EFE84CEA72CE4 +:1071500012F939A3303F07D7CD63415A573EC54A8C +:107160009EA733D09381F9DAD63C1DB6999F6B8DDB +:10717000E7AB181F8585FD26E010EBC1B58EAE6725 +:10718000793CC32ACFB20C70D6D98698EADD7CDD73 +:107190009274007A37D33DC7428E8FEFCCDA80FAF3 +:1071A000F64D0FCFB3491F12188DF3977209EBAA52 +:1071B000E013DB0FAF7373BD715D02FE9DECE17AEE +:1071C00076C13ACE371DFFBBF41AC47BC79B69A9B1 +:1071D000CB4D7AA24CC8B1EC57EA21F99DAC9F2265 +:1071E000FA9BE6E17251E6E67C877024CA272833D1 +:1071F000ADAFC43FAD9C7F60BE61337FBF29FA8DC8 +:10720000E153ACAB02CFB53AE017F0B7D51EEE8F25 +:10721000F949C59D36EAAF629787F2322BDA391EFB +:107220002BDAF6D9AA4DF889EF6FA987CBD1067171 +:107230000FED211BF01BE2DDCDE13BB33387F4E71B +:10724000220FB71B2EBE6E5C9A9ED920F23180BEF3 +:1072500094BF58FBD2800D563DCDFB4BEF175A81A2 +:10726000E7F0D21F627ECC29033C451580FB4B8F93 +:10727000D03B7A40C7F3B6DD0F33DA8F1F362730A5 +:10728000DA07E5FAA07B8C02FD15B4713D5C7C3F0A +:10729000D83128774EB92EBCB6CD3CDE9D1E8FE589 +:1072A0001C61C53A8EBF6160FF3C8D4FE8E759B263 +:1072B000E3393CC71F6CBF0AE34EF2FB5641FF8B1C +:1072C000C1578CF08D8BC187FD53FE8A3BB81CFBE8 +:1072D000ADFBCD8E01E67E1FE8E977DE1417EAF9F3 +:1072E000B5B0EE9074860EE0B98B8ADDA906DE9308 +:1072F00000F26C437F478E5BA1C9DFCBE92AC67BD6 +:10730000C20B7AC69174FDDD33E6F96FF2B8FFAEB9 +:10731000F4EDD043349FEEED00AF2F86978EF6B993 +:10732000CB5DB84E1C637E5C2724BCC3E674793108 +:107330005FA45EAC1F305F1BFA2FE9BFF0B1158868 +:10734000B7CE29744F423C5F4B3A0D675C7EA49FD9 +:10735000361C03FC50DEED2912FA87919F7BFCA5B9 +:107360003D4FF37B2D385DEAE7703A7679425F7ADC +:1073700032627208FA9CEE2FAEB8BF471FB5F3F722 +:107380009DB973009FBFF64839B7D2253DD8EEA20C +:107390004B66055F9F7E71546415A7338DDFD1EE78 +:1073A00089280A9EA36D68427F5BEA0984C79CAF67 +:1073B00024E1E9A123033A8E8ABD1F3687F7570FD0 +:1073C000F28E7C54A33628390AE9018AAF66A11EE1 +:1073D0008072563B6FC776F3FB1B249E6A6E844E09 +:1073E000C1EFFC574F21CD43E22B6B4ED45653884F +:1073F000F9CAFB077F64A2F311B15F8078B98EFCF4 +:107400000DAEAF6BD4E040F45B599683CEA1C23A87 +:1074100044FAE5908B692EE8EF5578E2BA3455BD11 +:107420008DCE094D1DA2901C830690F11EFA3DAE33 +:107430006BAF4EE6795B7FF9D1509C674632E743EC +:10744000E8C729FA71D23A28D6837FC905BB4E898D +:10745000E9E5438A42FD1CFA87CB37AE50627C894E +:10746000FDA1FD7448993590D6CB8E0C911CD46546 +:10747000C927EBBD9E75E562BDD95F44FF2EE66F5F +:107480002A774D039E9A30BD3D8A574E3785D56980 +:10749000FF08E34E057FD385FAD3CBF9FA505E5847 +:1074A000F5225CC314BA5FF97052A890DFD3CBC742 +:1074B000C914719B4C91AF8CF6023E235EAEFF4720 +:1074C000A6F0E78FC533D39B38CEB356D4D78B7B8A +:1074D000AD579524CE671BE8552CF1966BC5BE05BC +:1074E000DEFFEBE57EA7C8B3E5FB1C60DF137E4B38 +:1074F000EF9A43FB765F745E9FC2EF6FE0FAE04362 +:1075000025F0EB1B157C06E9FEBCF0DB2AE5BF7F0E +:107510006404BC98DF549B94380FBB44CCAF56CC6A +:10752000FFE3467EDFC27CDC4F03FD31D6CBE7B103 +:10753000A86D6C39D27BD11A85F6D3E4BEBDA46F99 +:10754000E57AD5124F9F8FFB69FDFE163FCADF8794 +:107550001F35CEE247C971E3FDA9E38DD996B8FF87 +:10756000BCB621E29E0BDE7E3EF313DCF35B0758D4 +:10757000F6FF586BC6A5DD030AFE5338217C3AE9B5 +:107580005BF9FE78A39385CD707C3294F21E067A67 +:107590004337217D637024B3B0190E3699FFEE9501 +:1075A0008BC75DC10EE7FE0B3C37B8C94EA77B6A9F +:1075B0007BE260A03F8C14D4472573BDE3637E83D8 +:1075C00094AF9AC989FD8771C2CF1DE7E6FE71CAE3 +:1075D00031E94F27F9502F4A7B3CFEBB861EBEB5D2 +:1075E000DA93178B3F00FF86CDFE517CBF2DA2DFC3 +:1075F0006FCE2FF97DF04BC17F89DF5D3C3944F1BF +:107600003DD6A6502ECA8432AB1FF48897AFE78FC1 +:107610007893E97B695757CCB1B67B0CDB8DC76794 +:10762000F225C573CCF6BB3204F51FEF4FFEEE4ECC +:10763000DEC93729FFF377E827427F6FA404B6201D +:107640007FAC11F9F21BFE7A207B3EDA43FF6CA778 +:10765000FDFA924797AEC07C6677BB62D0F9A35D16 +:107660005679F8CEB2F6C115808F7641A71A3F9FA2 +:10767000478D3FAA0F75637E351F7F60FB3E453304 +:10768000F1DBC04ADEEE25AFDD129FD98B65E867DE +:10769000B7D7907ECBBE19E9D83EA0A11DD01F7FE1 +:1076A000EF06E0E9DFC0C88EEE3F4EA1FEBF336EAD +:1076B0008382BFBF25E7D96A9B5568C077AD99C95A +:1076C0007E5C6F328DD0419C67CD7BD1282E8F138D +:1076D000DEEBD4D0BF1A6E040EA1DCC979F954A335 +:1076E0003FDAEDC9EF71F8DA7AE24A7CBD616CB538 +:1076F000B04337727B4C654718B7C7695DCF5C3EB6 +:107700009CD63D399FCC34B16E64B210E61F43FB6A +:1077100056B2539C7CDDCF5CCE7F2F4FD233E667D1 +:107720008E18837EE69035516D1E7CF7D27A5BC24F +:10773000FB353E14788779BC6F9EC7C5F4956C679E +:10774000EF23CE28F93D797A62FF9DB17BA9BEE493 +:10775000D1F49B492E9B75BA0F51E27FB811FC1CE6 +:10776000E1E9DFBE4141DC1C177905C7573DADA0FB +:107770001DF9A3C5CC5013F0538FBC2EDB31B8C21A +:10778000A437A17FA2C786B83C71196F71A570FF9D +:10779000E71623C852C653DE2EF9CF8B37F3DFDD51 +:1077A000E8131F97882FA592DBE535B3F9EF8E9686 +:1077B0003CAA11BDAB9BF9EF0ED66CDB4EE7ECD8C3 +:1077C0004F991FE5BDA67DBB5201E3566FDBAE2C82 +:1077D00030E16F404D84F2AB2FF3C87D8728D9CDBF +:1077E000F17C8DF102B4530EBBB8BC9F2A71877136 +:1077F0001FE2943D5483ED4EE524FB719F52E2FB62 +:10780000D5EDD3E8BE03CF0E47149FADB68DD94E4C +:1078100068D73A52F7231F0D3742C3102F695AB069 +:1078200003BF4F4DF7F8711FC3E7606368BDBE44E7 +:107830003C4C88E387093FE57272638A57C805A309 +:10784000BCA7AB533CD27E22FD74D8CEE7B1837186 +:107850007823DEC0B814E4C323FC7713FAD74415A9 +:10786000CC17891F37C64F812B11FE4B87B35D475D +:10787000BD5E2DF44CC9A39B950F4D70CF40A30A5C +:10788000F973DB0605E364504F7A06DA33CC4BEA32 +:10789000BF8DFBA5D550BFC0A457E43C12E897208C +:1078A000C2E77EAFF320D72F51BE2F20E08DA7E790 +:1078B0009C141F8D5F0EE601BDD7C3C3D12F3E9C24 +:1078C0009F44FD49798F97CF3982CFFBAFDFACD88A +:1078D000DCB47F4276A4844FB67B23654A08E199E5 +:1078E00030BD93F050BB5EA3F94CD583436F33C9D1 +:1078F000435D0AB7E3F6DFF83EDDFF73FFAF8E129C +:107900003FD6823F4DFE44DB51FD7A5C57C24FAA01 +:10791000B8DF750D3749D883E25EAC6B3AB8FEAD7F +:10792000EDD8AEE13D92924FF34EEEA7FBB46ADB89 +:107930001D0CFD28E0BFA548EF783EBD547A821E9D +:10794000E27E525817F1BC501EFA39523F47843D2F +:10795000CADCFCFDBD024F31FE09B5A458F4AB8B67 +:10796000E422EFE498FD989759EB57E8BCA48427EC +:10797000BD34B17D2EF5A2D4D718370C9AF4FA5A3B +:10798000A4EB782A47B93FCAF2715D9670C6D3E975 +:10799000E514AEBF13F0D3232909D62BB97EE73DFA +:1079A000B643C37B91249F5C83F435F1C99329FCD2 +:1079B0007EDD275334EAFFC112BEBFF8A09DAF534E +:1079C0000F3639295FF2D59B78FE96E7663D8ACF60 +:1079D00043B67935587FA83F87A3D5B69CCED781CB +:1079E000FC3D95427CE2655C0F72BD77FFF35C6FF6 +:1079F000D584DDE4CFD684BE5F4179ADE92E3FDD8D +:107A0000F7193AA85FEF89E1359E8F7C3BF6D1EFFD +:107A10001D5FD3CEE50DF426F1510C7F1CCF524EE5 +:107A2000A43C44E4FE0DF001B77BB8BF5428CE3B24 +:107A3000563AFD745EB252C4550BC5B9C7E2630134 +:107A40005A0FE6093A14D982AFE2BC2AD6C4C5550A +:107A50002FD1EEAF5EF6FA08FC5DB0AAEC23F494E9 +:107A6000F2087EA9456EDF11FEDF1E41EF3F08F9E7 +:107A7000AF1ED74EF256FD5103C9A97B3AD757EE38 +:107A8000F7AC7A96B17BC47CD7D0775393DBCB71BC +:107A90005F78EAE30ADDABD9179C8BF01C18FA6F0C +:107AA000EB0F78E7A23C8BDF8792E765CE08393988 +:107AB000B55515BF97D9A05FC8AEBE587F2CFA96B2 +:107AC00042F795089FEFD4B6D2497F44BF736B0A43 +:107AD000FD7EC967DBBEF7E33FA6E3EF835CEDC73E +:107AE000F53F7D4590F8A53BC3E5DFC8E3ACD33156 +:107AF0000ED5D47EC08BE76B3E7DFA8A31A88FF11C +:107B0000DE2D9CFFC9E7D5658897E54F3CF72DAC86 +:107B1000AF8E28FDD02E3DB5F5F1FFC0DF81AADC88 +:107B20005C4FBFF3BCE2E957C8BEFF3F75A9C786EB +:107B300000800000000000001F8B08000000000013 +:107B4000000BD57D0B7854459A689D3EFD24DDA140 +:107B50003BE93CC9A393404025A1131208F2EA2453 +:107B600084872076408620AFE61D20241198591C7A +:107B7000DD9B8620221767E2EA28F8DA0E838A3333 +:107B8000CE18306A90A0CD43C4195D5B040767919D +:107B90006DD4419090F446671677B8C3ADFFAFAA95 +:107BA000749F930EA83BCE776FFCFC8A3A754E3DCE +:107BB000FE77FDFF5FD51A5FF3DF52ED8454EFE9E6 +:107BC0006F3510422EFEF2E1716428218D2D8DFA61 +:107BD000A099902F7FD98CF5C3CFBFF4C67FD3F780 +:107BE0006ADCB14E78EFCB970FE9E1798D47EB6A0C +:107BF000A125F11CD5CFB2D0D2FB824C1209994AF3 +:107C0000D8DF637B0FE91D79B4DE221142BF27550F +:107C10007ADFA02CFA5DCB5EED1233BCE123A49891 +:107C20008EFBFCC2511EA8B7251092127EBE554F86 +:107C3000BCC6385AF623C444CB4BA566AFD49F903C +:107C4000D565E6AD505EFA8DA9CA47BFABD50773BF +:107C50006D309FA1C405F578AB86900418E76E5D82 +:107C6000AD19BFC77E3ED21102651EF192F34308E3 +:107C7000A16FEDBE361CC6FB2DBE4FDF2B3115129A +:107C8000327BDE3909E61333B45EB71AE7F96BD6F7 +:107C90004E571DD93E623D1D8F8E7B0DFEC687CB94 +:107CA0003CAB19DFA700C132B5B532CD01EBB71B34 +:107CB0009CB07EB1BED46A4FA3853EBF6DBDC729BF +:107CC0003B0879FDC289890368FDF921D270195EEC +:107CD00097A5856EDA7FADD78CE3ACD950463EA32D +:107CE000F31D6F95F0FB442BB1DF4AD753A12576E6 +:107CF0003394849CD41542FFCF62BBC3405CA488FC +:107D0000966FCE7E7623FDE4319D27A518FAD91A09 +:107D1000D03BA0DCCDE64FBFB79A0BB13FEBADF047 +:107D2000BD91AC85EFBA364EB36F93B0DF802E2E87 +:107D30003C6F424219B3F2587F4500A7C9DE2A784A +:107D40009F38F4B8BE2FE115C4A3377F7E1E940F71 +:107D5000B1F96A8807E825514F4B84AB27AB92D223 +:107D6000CD7C6B6995B5385C26F663ED6AB83E0547 +:107D7000ED149E67AC2E2CC99E784246F57E4F943A +:107D800002FE876777EA8374DC470F9C43BAAD0530 +:107D9000BA85F13D9FEB611D826E9708BADD7F0EBB +:107DA000E976499B84F454DB56A0077ABDD4E022DF +:107DB0009F69699DD3DF63527039D0B577BFC9FA27 +:107DC0002C8553A7A0CFEDE7CECB141ED96D290E7D +:107DD000099EEF6774FA9646E30538BDB5EB96E663 +:107DE0004629729E1B113E5235413EA9AD273E03E6 +:107DF0006D2F7D7AFD8929B4BEA69A380D943E6A0E +:107E0000557494F5CCA75B805E6C35A4C8E480758E +:107E10009E9D3880F65F5B438A814F5327B8F643B7 +:107E20009DB4496410D4ABDD4B61FCDBEC2B9D327F +:107E3000EDDF36C1DD0AE3DD661FEB94697F8FA5B8 +:107E4000B76C31D2766F05B13EEB00FC36956969AF +:107E5000FDB10A87954292C26D7732B493217AE7D9 +:107E6000B340C79EA535D05F6DF25C27D0492FFE89 +:107E7000DFBF7108CCB7D6D1CF69A2EF4F6D939019 +:107E8000AE88D74C60FEB514BE509FEA1BED83F957 +:107E90005CE6F01370ECD40516C0FC3A5F31102F8D +:107EA0006D9F3A81D1AB6D420BCA8FB7F74F3A2E17 +:107EB000E587E9D2F2AAC10FF538AD5572825C228E +:107EC000330D91786DD291856EFA9D6D32EB2767F7 +:107ED0003BC3EF739C9F9E03B981A59EF36F13A3D1 +:107EE00077AB37DF4DE9E132C73FFC3968BFABF113 +:107EF0001F143F4BFDC84F352FB2FEEC0657C1BAD9 +:107F000008FAB59713E4E33D26B2B0923EDF63630F +:107F1000A59A5EDFE5F3C87A662DE27D09C53BE0F0 +:107F200035753B7D0E70A3740170A378443AB8CDCB +:107F3000BE02F1B664BB7417E2D13B82403D219E84 +:107F4000AD53DD7F80CBC53D26779144FB0B255893 +:107F50009CBB24988F4B63827A81CDB98BC0F7EE9E +:107F6000DD305E4292C9D91821AF08711769E8382F +:107F700017122D0CDFBEF7B533F2801F1DD86F82AC +:107F80004CFC04E50FC976E785BFABC861FD55F031 +:107F9000FEA63579F349368307C285C3C3B7B15FFF +:107FA00055A43CFD08E041FBF5DD44AA406EBCA5AC +:107FB000276623F46FA5E3D0FE12778DFEE5369C8D +:107FC0005F23BEF7A6D58A6545BCBBA81E44708E4C +:107FD0007B3DC045AC530D8FF91C1E87672F28D001 +:107FE000001DDF697602DF3D7A405A8C74ED355210 +:107FF000A604BA677C48283E802F88478BF8A8AD36 +:1080000077FBA2D37D25F259ADDDE4344948F72E44 +:10801000D47F5EB38FD13DD37F319399BE0239595E +:1080200099D75B1E083903FA0DE859F045EDB860A1 +:108030002EE0F7DBCA954E1DE3F34E0A07E023C19D +:108040003796D719BF6CDBE82885F66D94EF23F1DE +:108050007D4CEF45FE3D96DDCF09FDC23CDD96B07F +:108060007C4FB4BAFBD9609E1AFF166D56581ED7C6 +:10807000BEFE60AE270AFD09796CD4323967F4C5BB +:10808000F858BF6C3C2305B7A5104B2FE8A3980DFB +:108090000C3EEA7ED26D664E8F46EBE7548F4FA7BB +:1080A00048EA9F43C8648D27DD46FB5F630C1EA32F +:1080B0009825191B427A984722E82EE09F5D313EB1 +:1080C000905B8989C4B32F4ABFFD6D8CDE045E9A34 +:1080D000E2181F25C6B2F747D918BD0CB5313E2DA1 +:1080E000E3EF8BF90BFA77683CE788DCB71E13DF08 +:1080F000D17961BB980FFD7E2B61FA17E79BB829F8 +:1081000077D7B6087C84F9E8A642C053CE76BF760E +:10811000B1393C8ED0A76AFCC3FC817F603D95439A +:10812000FB7EAFE910E347353D4EE17C62B0112C98 +:108130009B74FE3F235FDD6D21BB607E3B882B9EE1 +:10814000CEABEE8DC18C1F5CA15CE8FF609C6737F5 +:10815000E063E4044EE7F4F90CFA7CB596780D146C +:1081600027ABF7E87C4123E3996BF4FF62C0139DD2 +:108170004797C5E895299DBF1FE7A982EFBD65C454 +:10818000E907BDF4532A3F80FF88BF18E44B1D095F +:10819000C6029C6BE5402EA1F8BF1AE3990FF4F8D4 +:1081A000A9269001CF090922BD9E31C5E613DA5FE9 +:1081B000ABDE9FFE4F30EF7764B28BF6D34D5C534E +:1081C000611DDD014D9C97AEE393B60F7F73807EFA +:1081D00035FFC0E5F9F70294B6C52C789296F38C7A +:1081E0001AA37678181E672CD1E5EB8F395D2434FD +:1081F00032BB2BB4D1E003F8A8DF1B1FC7F05F77B9 +:10820000259578E3239F33395AA70DE9C184ACBB88 +:108210009241BC74DC4F34A4BA258A9DF9A18DE942 +:10822000AB564AFAD1DA4F733ADBA323B93B603E2F +:10823000CD540E02FCB40E9417D58F6439B7D16AB1 +:108240006B76E818D811A15F4828FFCFE898DCA129 +:108250007F771A4784F5279827601F565BBD7E0DF0 +:10826000951BD5EB2D7E391F9F6BC700EEBC562D9D +:10827000C8C1C55C2F2EA97FFB1B2996B66B8971DF +:108280000CFDEE0BF3D258500BCB7FBC2E118CEFB4 +:10829000A4794DC89F844CB0823D2EB9A6C9D7623F +:1082A000AE67CF69D16E477AA1F82D8F733F09F879 +:1082B0009ED79FC17BDEBA189F3742FEDDC1E1A386 +:1082C000A6B33D40A374BE6725A657D4E3BC1057A0 +:1082D0003609FAFDABC5FD1CF6BFEE32CAB379070D +:1082E0004C19A0B7565FD1205EBA0A02B91BB28002 +:1082F0009E43197FA0F05BDD6EB07A1DD0AE57E0D3 +:10830000F5D3062AD072C3F5C517064E246680AB96 +:10831000730BE079C9D618E21D129E1F18D240B720 +:10832000B55708F6B3B8FDEDD320A76BB541A48BC4 +:10833000C54633C2BDF68A16E741B6EA3A82E27B09 +:108340003ABFF858573BCCDBFBC018DBF95BE8C3FE +:1083500024FA1CD7E5390CFCF4784C2C71313EF032 +:108360000DA6F3EF363AFAC75138D4E929DE876112 +:10837000376E6384DD44D22C4ABCB6BFF30DCC67A4 +:10838000A9D1A307782CABAAD703BFCDEBEF2FB6AB +:108390000E8DC4E718F9DA2DDF1E9FCF73F9F2892D +:1083A0009ED27B14FE3ACDE5EF782E273E49657CC0 +:1083B000F14906A9DE07E5CDB4A4DF7D92CDEB85BA +:1083C000ACAEEEE72AE78B4FF2991EF2AE657A412A +:1083D000FD5E271FAF3CCE751EE0269E0F8F63CF3C +:1083E0005F88735D043853397799D3A1DF46FB9BCF +:1083F000F7A601E9906C0EE5021E7BD695CBE79BB4 +:10840000187D5EB670BF5F437FF43D17DAE36F9867 +:108410007CB0BF20D3A8DC0539BB369D809CA5E38A +:108420005EC5F772E9B8F89E01D741B652F94B190B +:10843000ADABD88178D9564AE913F8FFA0C10AFC40 +:108440002FE849D0919A7E4C7142AF31FD7A07E80E +:108450005719F5AB298EE9573DF02FED51CFECBC04 +:1084600081886FA433F9DBE3FBA09170F8BAE3E3F2 +:10847000509FFBF3DC79BDE12CE4DF27FD9474E130 +:10848000E3781CC0DFEB81731C7BCF9EC3F499B0F3 +:10849000FB6FE1EBDACDE5B428857E1A3959696FB7 +:1084A000ECE6F263B72D164B8A97C1B07EA1D77A5E +:1084B000E1FB29866FFADE5058CF3C4368413CD53A +:1084C0004B3FA2F68EBE10BF7B1EBEEBE57F98C071 +:1084D000F469DD5A0B017D3F228ED9B1A4289401A5 +:1084E000FD9121B4CC03FEA3F246BA31FE60AF9FEA +:1084F0004279E4F65807DB57CA7440E09921C40179 +:10850000FD517897C62584E1AD1EEF0C3451FB6E0A +:108510006A9CA43D0F382A200580AF051F7C659911 +:108520004FBBBC6C357A35543FFC58E3B903FAE9CC +:10853000B8E71DB4E7CFE8FDB94DE628ED7AFF3383 +:108540008F4BE1F6852FC85E3D9533AD818E5FCCB4 +:10855000A674B938203B61C8C5F7FDF9BD91602705 +:1085600007744ED8AF523B61BB96CEFB8C86E1932D +:10857000D42BF7FBAB38DEA9BDA42523C2F249E812 +:10858000FB95C43F08EC8225C4A587F2D3BB574CAA +:1085900023145ECBCCEB516E5D5C3B05EDE0E5C496 +:1085A0008BED4BB6EA3E8DD413CB9A94F5153B94E4 +:1085B000F5953E65FDD24F18BDF5A67B665F259407 +:1085C00047B71B1EE17479491FBDBD318ED169F9D2 +:1085D00003D31E47FE0FE88881D2C9FA83A5492438 +:1085E000CAFBA2ACBB924D7C117A286C57E412DF17 +:1085F00070E8EF2AFAF9A01FD8BFAE37B992609F92 +:1086000071A92CFA3CFE778FDDD2AF8F7E63B1DF8C +:108610004BD9D75F67DD1523BED7FB7B33F64BED18 +:10862000A7A8DFEFE670B81417BDDDD7D37F32EA15 +:10863000C5F0778C0FC2E3A4A15EADBB6255E8E93B +:1086400070BB9DE955BEFFA778F5A2BDCBED39AA59 +:1086500010ADE763C2724CD78FCD47F0CD671231B2 +:10866000A6A0BFEC612E479DF960F77E067615F057 +:10867000ED24C71B413AD525F78ECAD56687F94A3E +:10868000BD1E4A8F5F0623EC82B6388B1DF5B99369 +:1086900038615CC10F0BEEA9E8EFA178FB8FFBCA34 +:1086A000933C4323E9CE8BE3D7EA853D6756E871D7 +:1086B000A2D2F34BDADE417B6DA9D19D0BC2E94F0B +:1086C00007EF413E594EDC89C01F5D07076778FE02 +:1086D00007FA5DCC67A677918ED9E714A8946F67E7 +:1086E000F0F9CC6C67F6A2C6E8D2E1382EE2B026EB +:1086F000E2169CCD970A592DAD8FED993F3813099D +:1087000019C3E72FC1F714BE637949167B9261DE66 +:108710000618978E6722BE64281B47391D508E9716 +:10872000DC5A360F1FE27922A94F83F735C6A0CC59 +:10873000D649679008DFF7C00BEB165EDF7C67F762 +:108740008265F0DC6C41F9A3E7F3F846C84D2331AC +:10875000C2BA0D66FF4558978597DE32667F7BB3B8 +:1087600089B391BED68FB41018D76CBEEC85C55AAC +:10877000895582BAC9DAED877DC865ABD9AB198650 +:10878000F2F4FFA03C95DE5D0E78A1F29BF9A5FA0C +:108790006AD7FA71FF23E4631C9F5F23978F2984B4 +:1087A000C1C14EDC875C94AEFFC5B27C1A89053529 +:1087B000EEC1F177C64E3E0EF305C0A39E9FACFD01 +:1087C0003452CF24B8B50AF99754A5ACA77894755C +:1087D00023396305FA95FCEEE46BF1B8AF1B027E1A +:1087E0001A1D973777F663F312F49316AF51D82119 +:1087F0006EBECFAF8DD313F40F261A8D6418DA2511 +:1088000069F1CC2E394B314DF7832194E705E35DB7 +:10881000837E41E1BCE503D9B989E2698BC5B151D9 +:108820000BF6DE1CC9F92C92678B1FFC3ECD0B6C3E +:10883000CE6DD06E72FDFCFF40FB0732017BAB0EAC +:10884000FCEDF1F0A2B514BE6BCEB0E27BF6F210F7 +:10885000FA49430F12B4A77AD1E9553A7F0AEF5F7C +:10886000429DC2B76EA975F58BF4FD14778C538ABF +:1088700068DF0DED749E12A70B783E7E04EC6BD979 +:108880005F4E7B41C0057E0B978CFAB0AEBDE08891 +:1088900099CE23C753E004B21DD8CEE32A76838F46 +:1088A000C51528D7D279CC32B279D4B597DE514CE0 +:1088B000DB07068613882FC41C77CCAD81260DDD1F +:1088C0004FC3776531E8CF3AC9FD4A84CB83912AFB +:1088D0007E1B1DA67F6C2F10756A36B84630770553 +:1088E000D6ED8C0F9C44FC31FEBC9584FFE0FBF27E +:1088F000707F288F26849BC3FC469756687436D6B3 +:10890000D0F7DEAA9C84745807FB2E8A8F915AFFF9 +:1089100021E0EFD1BC2CE02559DC84F0DCB6D17F1E +:108920005897052E14B70CF511D6071BA1BFB192AD +:108930001FCB8CAA871B81AC5E03E30CED4E4F0569 +:10894000F0E3960A6205FBABB1C4E9B4D2A6D955EF +:10895000CCEF3AABCAE8033FFE2C2D61F12EAD27D8 +:10896000EB4794AF7E348FF97BA13E2FC29F22E26A +:108970001B27E93E666F147BE0B578A6C7C4F77580 +:108980009BF58A38D2CBF1CCBFB5337EE24FE2D92A +:10899000FCB280FFEE8BE77265081902722582EF48 +:1089A000BDF05E47E9EFFB920BCA762E1766B91E43 +:1089B000D1A11DCFE58390C36EE043FA5D4072E91B +:1089C000007E1F9731F89F285D89F26136F1E073D0 +:1089D0004A203A77A41F6972843D44C799E556DA64 +:1089E00047B3AB947541AF62DC391E65FB0C61DFA8 +:1089F0004E56DAB7F3FEE9AA0DF56FD2736BAE658A +:108A000062DC04F7FF75144F2C6EA2657194CD7A69 +:108A10001FD849756D77BF95007C741FE17CB457F2 +:108A20005A3A14FDB0D2B2083B62408D4F02B93FB2 +:108A300098AE2980780D61BCE8A4CE7708E228279B +:108A400057D215D3791ED1B378E45113F1823F5A2E +:108A5000D0A76506F3A75232C6B8489A35C609F4BE +:108A6000B4555388FED7ADB11667A4BF73DB464A31 +:108A700077117E578781145A39DD44DBFFBEC9E583 +:108A8000E16312F37F7BE71871BF9790E356C41B35 +:108A90001264721AFC883F897788F7D1CF01F1BA46 +:108AA000E1B4F449CC9EE9F95E269BD1EFA8923F50 +:108AB00009F14EF4F727F4CF43BF7D557BC16E9487 +:108AC000376693739014EEBFCAD3AC5D06FE83F68F +:108AD00066ED527398EE4E00BD02DE62480CD06B1C +:108AE0008F1F6F9F01FD783FD6B83F02BAACD1FB14 +:108AF000F389929EF1795F7A6C05A7175D997BCE19 +:108B0000323A9FAEF7F4CCAF751F417E7D79BF0D31 +:108B1000FD90DA1904F5C9E65282F4D0D52CA1FDF6 +:108B2000F685AD1AF7019BA526D4139D7113117F0D +:108B3000ABCC47715F5BFD94EED348BB6BD56E65E4 +:108B40007D3509E0BEBAE6C55EF48CF24BC8C7DAE3 +:108B500056E57764A0523E1670B95FE876CEAC80D9 +:108B6000A9573973D8BE9AF80D741DC5EFEAB9FF3D +:108B7000771ED39BE43909ECAD2ECB0599F13993DF +:108B8000C7C5BC3FB51E2AE6F6D4382AB760FF2910 +:108B9000EC23FA3ED68F6ADAE5644D785E45FC3BFD +:108BA000619709B92DF0525A424809A5FB643B97D9 +:108BB00043D9241BF04AFB477EA0E37AF571D8BF66 +:108BC00017F66DA3F97814EF5ED0B35E8DD10774FC +:108BD000B445AA47396D245C5E4B1E94CBAF79BD7A +:108BE00032C07514A99F398DBE37C61888017850D8 +:108BF0007A48B32784E9A491F833F64A0A7AC1F691 +:108C00000EDBEFA3D28BD02FFE8F997D3195AE185E +:108C1000FAA980400E2D8F4A6C5F38C9FCA816BE99 +:108C2000FFBD660AD2C364E2D3C2FC2AAC4A3C4F01 +:108C30004A56D6A7387AD1810CE3BA383CA70E51F0 +:108C4000B6BB845C234AB99645AE229EC983C77ED3 +:108C50000C7E81980D6408D81DD442447E53CB838A +:108C60007176B3C23E8A88838CB317F78E83747192 +:108C7000BFEEAD24B8FC45A937BD74BEB5414E8EDC +:108C8000A02B41C7AFF3BC09E94D1E6F2D62FEC09A +:108C9000B09E67F43282D76E057AA3EF2F147492D8 +:108CA0004932814EC6B699FC32856B01EFE756A07A +:108CB0009BC2B03EF76BCC0E7D36D08773AB2CF7E2 +:108CC000B6DB13E31C4827C3352EA49362E28C075E +:108CD000FC94185B1AB530FFFD230778CC0ABA580C +:108CE00062473942E902F9AA975E54B6ABE846E01A +:108CF000EF38B7972711EF40188F8AB1A3602FFB89 +:108D0000B318DD541017D2C9DBD953783CDAA3C5A8 +:108D10007E88521F961B9574A0A62B3AA226725CE1 +:108D2000359DF54537994037421FC6DF986EEEEF07 +:108D30009B6EEEBF1EDDA8E945C893BD266B39D8F2 +:108D4000A575D512CAE1E1EF0D6C84FAE0355998AA +:108D5000D7B2D7E644BBB5AE9EB517055C32E4BDCD +:108D6000E4ACE7ED59EE72A8D76D60F187E2932C81 +:108D70002F66E07DACBD6053FD110BE8772FFBFE45 +:108D8000F58B5BE458DAEEDBC2BF2F6D2A877ADD04 +:108D900056F6FD17103FA2F81D71DAD708CF6FDA2B +:108DA0009EE564DB4F66CF8EE774BA57DA7704BF6F +:108DB0006B62DFAD3866EC47D00E6676EB38BECE20 +:108DC000F14FB175DA3FBB6DB283D2EFB29017EDC0 +:108DD000A6F39A9A11286FFAD867964A4D695052AD +:108DE000BA4139E33252BACE66F1C55D7488437632 +:108DF00066078AB81CE40944E6051CB233FFA37871 +:108E00002F318EB038F21316F4078BB8A1FF712200 +:108E1000019FC11AB9FE8F1A479C94538FF1C34921 +:108E200099227E18D42EA6E3165CFB6A62347FCAB0 +:108E3000713EEE059EF7209E57FBB23440177B81B2 +:108E400048520148AB7F0776D35EF0BF32A5E125DB +:108E500025805756FFC8BE62DBD6340A5F4DBDD6AB +:108E60000B4A2683EEBF68D7D303C4DF3FB6F7FCB7 +:108E70002769891FF413D1B2F92F6FA47A500ACB56 +:108E8000A55942EC8C19847C7A27C7D367766E6F1C +:108E90000C27C341DECCE278FB91B15EC7F4659349 +:108EA0004EC5FF5F20FFEFECD36E56B6ABE4433503 +:108EB0001F7739B797579210DA05E7251F9617766F +:108EC000327B79B5F924DA155D4F303BB18604D198 +:108ED000EE50FB0F57EF51D6D7B428EB756DCA7A19 +:108EE000579E17C7E9DAB96604F8EFAA77BC877E00 +:108EF000E16A21277C4A39410D2426271EBF19FD2E +:108F0000361A2395134500AE7E9847329CB8E2414D +:108F10001E8092BD46EB0FC22729B4AE711B1350C1 +:108F20005E4C8EFF5C8C2F639CF63D97238C979E46 +:108F30007DA14A4E14087FCCC038F45709B951C0FE +:108F4000ED123259BD6F7C14F96F38AFE52428F764 +:108F50003DC2CEA0DFA39D11D0987D1A4DA45DE146 +:108F6000437E2C34523D812CE434B2FD4A1351E14E +:108F70007730ACEB3AFB2665BB0AFF62DF3282E357 +:108F80007F0EF10C007CDC49DC6F817E38F171B51D +:108F900062BFF4F11F270A7F0AEE9BBEFB7EC9FF6A +:108FA000BDF64B3D783751FB9196E533A60CFA059B +:108FB000C4BD5B4D98CF5927313C27CE399911E973 +:108FC0003F3CD14012B4117CDF38C56084F860A307 +:108FD0008EED27664CFD64C4E208B9F192B1746A63 +:108FE0004231E021F0937F87FDC53B32C17C99F689 +:108FF00004C47B77137D4EE9ADFBA95B9C5EFAF858 +:10900000928EC51BBF90EA97438A9398C7F20DBF13 +:109010003369A91E5B21FBDE08427C55F2BD5A4331 +:10902000DB4EE93D73A0FFD51ABF9EF9ED0218276C +:1090300015FDF7ED87F4A2BED31F667A3124F573D0 +:10904000323FAE373732DE5495C8F657EFC7B9977F +:1090500001DE85DE13F18433774FEA0FAAE16BE27C +:10906000EA0F714E490BB1A7DEE341BEC0E608BF6F +:10907000F21953F4B8C0DA04265FF7016FD1FFED9F +:1090800036D73A18F702DFFF5DE0F1AE0BB12CFEE8 +:10909000F5BF7ADE67E5A309CCDF7D81C7C72EC4A3 +:1090A00029F78DE2BDC778F97983D1B839029F8E4F +:1090B000C70DF53ECC93E27921EB09DB27EDB735FF +:1090C0006F8B8887362794EE837925E4B8F42900DE +:1090D000BFFD4C0F433C1AE2C64556CF76C04BADA0 +:1090E00083B820EE4A1C41FD4C883FC2BE13ED07F9 +:1090F000462F5D26568A79352754EE83EFBAEE0E59 +:10910000223E7BEA954C3E3627B871DCAE59A29DD3 +:10911000D71F0A72FC33FF81F067F7150F53C7BFE3 +:10912000A8E26076B689C93175DC7BBE90633CEEFF +:109130003D8FCBA1F9EDCC3FBEC048B60CA0ED0BE6 +:10914000DB93D87E31D69BAB887B7B63BE531E837B +:10915000A0CFAEF4404FBCF6898878ED1A1EEF5BC5 +:1091600023D6D7AA5CDF9B097DC66BDF4C8812AF84 +:1091700055E705BC0AFA7D60189E6BAD6CFD157253 +:109180004DB91EE4C45282F9E16BDF59D268A4F5EF +:10919000B50F82E70FFE98BDBA86C3ABAFF925B80D +:1091A00035C4A1F013F7238E887D718A274E51476D +:1091B0000B3822BF724075AAE2FBF4FA6CC5FB992A +:1091C0001B6E56B467790B15F59CADB72ADE1FD41C +:1091D00054A6A80FDE719BE2FD0292D31FE3B1C734 +:1091E00065F095909B7C3314EDB7ECB94BF1FD170E +:1091F000A4FEB131F4BD5613D303C4EB0A0CA57021 +:1092000059CAE79FD7B258F17DA3D432C24FDF5F6E +:109210001A60FEF6616DAB14FD5D8A9DC8F6113CC7 +:10922000FE584FFF6372DC21A33DD4269127A4DEB4 +:10923000F1C8EAF687B70C20BDED0AFA877A7E15E9 +:10924000D5F36047A9ED0C39D16247FD904A52AF82 +:1092500045F055980ECC6887753F25A33FAD800C2F +:109260007E7C0CC247477C8EDEF8EA26CCCFD3FD4D +:10927000A2C509FEB215EF2C41FA33242BE9C0E454 +:1092800050D241CC10251D589C4ABCF72F51E25DAD +:109290000D679B4B4907028E02CEF193957421E036 +:1092A0005B42FF03F81692D031CC9FF6494E3F89BE +:1092B00012EF6D6BC675DCC86ECB53C173F8515796 +:1092C000A319E1C4F2A9849D64E0FE69B5DF5CD80E +:1092D0001F6313B9DDC3FB117EEE2D9217ED9C9E2B +:1092E0007856893FC39F05F64E3D61FE127769624D +:1092F0004254BF1A3EEFCBAF26E028EC99D560CFA1 +:10930000D07196110FCAA5CFB93DB3C2FC28C605CE +:109310002FFD91C1B79AF8505E7FD77839D889244C +:10932000C2DFA886A3D42EF92DC0075C6EA7927663 +:1093300021B73D983741C9CE3842115F50DAA1C4F8 +:109340002545CA2761978AF1043C85DC12E3194858 +:10935000BD9C0C7CA092636488DA4E55FA3D849FD4 +:1093600004078B88638CEC894FB07D62D8EFC5FC15 +:109370001C7266562301FBDB2AFC1A81B9F05CF8EB +:1093800035D4FBFB1BC545677AA5E09359BDE3A126 +:1093900022BE4A97F9D9BFD38FC7488E74186FC6BB +:1093A000EB831388269A5FCE79FA00ED47D684E2E4 +:1093B00023FD65C27FFDB614C479FF88B8EE27117E +:1093C000F6422D699938370BFC9F546FC542C9FC92 +:1093D0003EA44D6D97B278A286AE04E87B358988AD +:1093E000176685DBB12EF7AE8B3C971BE97747926A +:1093F000559C5BC965ED4CBE89FD5B5FFB2511CFBC +:109400007F4B4F615218CE6B793191EF33F3493E68 +:10941000F44FF9AA2511F7E7940FA548BEEBC983CD +:10942000C1F65E7CA75ABF88E7CB9622F4BB2C8995 +:109430005CEFB78087B023BEA26B83725BA203CBC5 +:1094400035FDCE7CE482E6A24046A4BD5BA76779E9 +:10945000C1A445693F9F4CD47078B9E46F03A7BE9F +:10946000F1C0F3C2381EBEAD3D24F2C204FCFE289A +:10947000E46018DE671572AC67DFD603EFB3D1E4A2 +:109480009C80C7E5E2C0738027D9723211E0FC5797 +:109490008BFB33C04FFAE9E0794903FAAEE3B92711 +:1094A000417FB5C9B83FAA1DCBF2836AF763B09C70 +:1094B00074B61B301E58DD7604EDB28E062A4007C6 +:1094C000F60D9F9E75AAE0DCD73E45ACE3BF557410 +:1094D00026F244E8FAFEA6A0A7DEEBFF5B347A137F +:1094E000F94915F2D0FEC188FD483BDFF798B46E0C +:1094F0006D12FDAEE8C3B458804B85DC7E2C15E0C0 +:10950000B05EC2F347E30DC40B7EFE147E0EAD24A5 +:1095100058EFB4527824A799F13CD1E01FCB6E8864 +:10952000637EB27E5DDC125A7ED94087A6FB8DC178 +:1095300092C68D7446F69DFD6911C4D7E661DEF1D1 +:109540007C038BFB67FD24C69F43E5C39B7A6204C3 +:109550003ED365D7E3798B904DC67D865D2613801B +:10956000AE049CED316C1DE279E9D3BB25C86312D2 +:10957000CFC7378686AFA5E539C07771789DE3CB35 +:1095800043C3EBCD61388BFC40A20D65CC88E08BEA +:1095900037393C6A13F45B400F761AF9FE8FEF03FC +:1095A00089558BF2633D8FB39F194477A2D88FDF23 +:1095B00002F958B52657FF91E0E7823C025A7C6DCC +:1095C00075F5B7E1FA1D682FAFE7765527CFDB5E5B +:1095D0003FA52C09F6517DE53D952631FBBE86C79A +:1095E000BFC5F31AAD1FF3956A20DF3822DFE9BB50 +:1095F000E61B8BFCF13EE160D3122D8543AD44DCCC +:10960000D77BEFC0DFE4A8FBDCEA24CD75F3DF16DF +:10961000F2F589FCB65AC86FA38FD6EF2F4D2251B1 +:10962000FAEBD133576E55E49189FCE8DA2BE3303D +:109630008FACFC810E3CF707FD38CCE1FCB6BEE0F8 +:10964000FC66229B472DE4850D8F7CCEE446B87FD7 +:109650003BE2E1570040F073B4C9E88FFDD571CD0E +:10966000E45D51E6FB501283CFCD095AE48F5BFCD9 +:10967000C4D51C657CF19E38170270AECCEB3DBFA3 +:10968000D6B2E002983FE4AD461BAF2189EDAFC5ED +:10969000BC5BE382CB399DE3B98C9EBA5589C77F09 +:1096A000E572BFF5B660069E2F9A123D3F5EE07BE5 +:1096B00084B65E0278042D9E03686FCEA6956190F5 +:1096C000D7EFD7B0FC29C6677DE13D0C6F8D229F97 +:1096D000B037BCF58867D19FD88F5CDC2163BCFFB5 +:1096E000E209CE97C46596287F2DE2FAEA226171DD +:1096F000838B4D12EE43167B08D940E5CBA2DDAB40 +:10970000316EB3FCD9E15B404DC1F3FBA81C599409 +:109710004CC8385A2EDEAC8CDB2EDDDE2B4E4322BD +:10972000F522353B715FBDFC51E577D564FB7F8247 +:10973000DD53ADB26B06733FD7BE249ECF37828C0C +:1097400000F9BEF6D9AFF490B2DB17BD7F49F97AC4 +:10975000A016E4A015CBA349AEFD49141E1F26791F +:10976000DA416E777DC0E0D05DD3CDE4FE5376D490 +:10977000370610CEF49F86B92CFEFA001517107725 +:109780003318985D23EC39595E27C7D2F6517F5ABA +:109790001F07F8B3FF7AD264B0F7137E1DE3027897 +:1097A0006D2B7515C0FE7F5BA519F3188C0616F797 +:1097B000F5FD6AD46108030C6C79B80CF69FD6F6F7 +:1097C000437EF08F6CD5FC279E2BD93A8EE5B98964 +:1097D00071EADA2BF7C27C32EE647A635B96ABC037 +:1097E0001AD12FE1F6592D8759D7C1C13F1F4DF12D +:1097F000F8E471348FE9FAB2D10F773361F814F9D4 +:10980000543076A41DDA41F50F24E589FACD2D9266 +:109810005F47D7B3A6752FC62F6A36F913E7829E26 +:1098200079418BF11F313FFB9B296510E711FA65E8 +:10983000AE6445FD2FECEC3944FCB1385115A783DB +:1098400039DCBE9E1BC3E0BB983833E0BBBB8C2425 +:1098500016FCD373CB5B8A51FFACD6D940AF8B7863 +:1098600047DFF640743F51ED7316763E560AE542E7 +:10987000275FD27D0761FEA2A8E78D4CC99CCF72FD +:10988000B9BD3790B820BE56FBC6E066F00718FA9F +:10989000B1382C953BC69242B4778DB08F5979C0C0 +:1098A000E467FE6A1F3F07EB2A807C90BA1969853E +:1098B0009897709ACA0F0B9C2F0C66209F52B92262 +:1098C00051DD969D1C334D4BE9BB3695DA53B4EE12 +:1098D000DE91CCEAD9C1E51A5ADF905CC8EA3707B5 +:1098E000CF437D53F258562F0C2E9769FDE9E4A91A +:1098F000AC0E1B3B4A58BF4A9E31CD0BF6848DEB14 +:109900006B6710CF05D7BE3E5813E9A77C2C99C9C9 +:10991000A52FB9BFF5CB2CB27006C07B4810CF9DE8 +:1099200089F77E9A2CEC5B96DF2BD629BE23C9D112 +:10993000FB2FE0DFADE4E779C7C790AD2616A7F2AD +:10994000C652F81F6D1F8C71B6C4E438E68FB3D2CF +:109950007E8AC2FD08388AFEC4B8AB40AF82BCD54F +:10996000317FA9681F97CCE4381D67338E3394C1CB +:10997000BF76465A01E08DE24BCBF1A565FBCE6682 +:109980001C17FAB5E5A37C1F0EFEEEA357E9FB59A1 +:10999000E179ABE9632AA78F958D2CBE18B2E5203B +:1099A0001D8D8F61F61E2952AEE3690E87C7926D39 +:1099B0000C8E3DF84892709C460EC7340AF7BCEFF7 +:1099C000BEEEF93FD0BA23F0E592A1BDEDA65D91C0 +:1099D000EB11F9DAA29F2F37AABE2B617953B5712B +:1099E00039F8DD032662C4E76457CF7759F9CCCE46 +:1099F00004FB53DCD740BCE3D04950C3A546CFFDA0 +:109A00000B2D3C7F70A08B9D3F9E31AD88AFCFCAA0 +:109A1000D7673546DCBBD0C38F274319775A7AD333 +:109A20006F0FDC7BFA1B5AC8FB53F075B4FE803F06 +:109A3000FAC2C7CFFFDEF810F354C1B307CEAAF9BC +:109A40000978023FE3774395F428E6B92959E40BF6 +:109A5000ABF83AEB7B8E57CABE5B730FCF03762809 +:109A6000E9794D6B9606E2E7E2BBC9E0634F08FB7C +:109A7000DBF625F37D6B1A49EB23FFEDD5E4E87E99 +:109A80003A7CAEDEBF75D958DEB3DA6FD095E00C04 +:109A9000C0793EEF65763E7DB4CADE80F8CB3E737A +:109AA000F8BBB03E51D6E514C607BDFD40213C4F82 +:109AB0005B64287BD9E1A47B9DE4EA695A6A571468 +:109AC000F52F5B9745EBA79257A1BC2E1A50F65580 +:109AD0001695DF7F485ECDEAB7947D950DF51DABF9 +:109AE000D9FBE35D2F837C27DED5D326A484ED87C5 +:109AF000D3C90E849B5CAE21404706F96E27E84926 +:109B000001CFBECA2283A63E9A7D7AAE870E587CCC +:109B1000A284EBE712B13F0F6A15FBF3AE5876DE75 +:109B2000B80BF4295D6F47B2E77C32D829311D0BA1 +:109B3000B268579B62CEEAC11E925C5477819FC384 +:109B40006125F3209FAE639B1BEC23B2CA69D4222C +:109B50003CB9DF89AEED1AEDE7C01B2FDC3B800D71 +:109B6000E386798CE2FC5FF7C6377F81F868DD9782 +:109B70006627B8F546B5EF5C07F6D5A8F6DF7FC3D4 +:109B8000F42D3BA721E63D0AFC87F479499B01E7C8 +:109B90003FAAFDA665F0FEE80FDB73803EC69EF18E +:109BA000378238E83AF8DA00C5F90CF285F47DCE50 +:109BB00067F4C0E34FD478EA8FF030A624003CAEBF +:109BC000629E5467C2892D41B4D394E760A85D8E2C +:109BD000F1D56ED2CF097102718E5BEDAF3C5D495C +:109BE000D7479F8F0DD11944D8CBE3AFD0FD7D84EB +:109BF0009D5D4A6C8A7AB93145F17E85354BD13EFF +:109C000029F92645FB144781A23E75C828C5FBB734 +:109C10003B4B15F53B4AA628DEAF74552AEA05FEF4 +:109C200016C5FBC38FB729DB4F3A100FC3CFB8CB94 +:109C3000C18E77063C8D508EEC682AEFEF20BDFC7C +:109C4000B445415F233C1F7DB5BED84FA29C5F59F0 +:109C5000E541FF7EAFF32BA5EC7C7BA7869DDF1053 +:109C60007ED9AB319EB180A7B7250A760AEC71C6C2 +:109C7000503CE0AB62E143982FD51D22E8CF6AD576 +:109C8000077F361AF4FC7C19EDDE569E67D35A9591 +:109C9000E7035FDE6929F82AC4E9BDF3D9F980B189 +:109CA000D4C2C575434C53023C7914EB2E252B5579 +:109CB00078BA5B51AFB0DEA3787F52F24645FB1411 +:109CC000C7832A3C3DACA8DFEEDCA9C253B30A4FE0 +:109CD0002F28DAC77E1E6C04361ADFE1952D74FE3C +:109CE000B79E6E2A07BC8C3EE39D0FFC52E4F7340E +:109CF00082382C3E5A7F044A3FDD4F819FEA7043F1 +:109D00003296471B1CE8673AD63004CBE30D4E7CF5 +:109D1000FEBB86122CDF6D7061F96F0D93B10C34B0 +:109D2000B8B16C6968C1F7F735B4614921980EFA8A +:109D3000C21EDF73AF423AECE73B35C15A88A0AE92 +:109D4000DB7900E56467BF6027D43791D7A74D80E2 +:109D5000F35CB09902FB0A4A8ACFFB525D7F49A1AE +:109D6000F54D29AC2EF2125A34AE02B0AF1FD8799D +:109D700064BB369D90FB37BA93AD365637D23A2244 +:109D80001BFAF01ED9EE4A23E437A0326EC5FA342E +:109D9000A8779958FBA69D47A679513FB0F8F19D49 +:109DA000E1F8F10330AE3A7EFC9B0B0E0BF8534EFC +:109DB0005C1D6C81759DE0FE231729D02DA265A93D +:109DC000B640077AF1B4CA8E10659DA6B409FA6D43 +:109DD000D13867615EF06D3A0279E83324B61FED41 +:109DE000B10353991CEFBADD80FB9D931AD732CC97 +:109DF000779242CF00BCF6A49C44BDD265096500B1 +:109E00001C9E4BF990D51342CF48CE88BA8EADF345 +:109E10005F534EE03E22CA3A77A7448993BF90C26F +:109E2000E3067E573A9EEBE5F59395AE35A0274EB7 +:109E300096BA06C17C4EB80DC83F5EB7C507F99605 +:109E400044EB2A9E15E157C949D5E17777EA199F76 +:109E500091BBE4A8E7CD4B53999D857883FDDC9CAD +:109E600018B4C34F6AA29F179F93CAF4F5A57ED179 +:109E7000FD2B77F1F6B29916ECAF6BBD09E3B75D38 +:109E8000EEC1680775D5532851FEE8BA507FF91521 +:109E90006C3788D016C629E77239F59BF6757F3E78 +:109EA00045DF3FBB3EC68932DC7A33EAA7BBF8CB3D +:109EB000F3E38D68B7CC9F915E067A692E8F772D7C +:109EC000B0681331ECA5B5E9E18AA0A5E6822DA022 +:109ED000FE97DB2BF5365AAF4EBB7B0B94AB063EA1 +:109EE000AC87239A3543F76E01F3710D65AD62DCE3 +:109EF0002F05DF6BA0F35AB84176B0FD933877B8E1 +:109F0000FA3BE557083A3CC9F364287C715F38375F +:109F100095ED7BC4777339BD5D4CE1765B1EC9BBA3 +:109F2000A68CE35C063AE998FF5E6E1F7E77653B80 +:109F3000B7DB3ED2B371D5F7508871E771BC9FD4BF +:109F400013970476DC5D16A48FFCAAAF3615D3F503 +:109F5000E7B75B35188717723CC0EE032BFEDC8336 +:109F6000726E6447F0B95304E9BC0DF8E4467A6AAE +:109F7000A67723EA87515F53FD0372F1AAE7EC2924 +:109F80006CB5473D8FE96FA8E6F2B11EE5DAD186E0 +:109F90000D583FD6E0C5F278C3562E1F9BB0FDDDAD +:109FA000861D5C3EFAB87CDC83CFDB1BAAB07CA3A9 +:109FB000C183E55F2DEEB8D40420360FE667BEB549 +:109FC000D340E0DEB4EE7603D229E580679EB44349 +:109FD000FE8BC10AE7EED479306A79DB83FFD65E67 +:109FE000F76164A41647E4BD807D96D937FD9C20B7 +:109FF0000E0BC893114F24DD0EF2F984C36101BB2F +:10A0000075646A32ABBB1C161DAD973C41EB54BE68 +:10A010009CF0382C065A1F959AC2DABD0E8B89D651 +:10A020006F7D2285B5FB0806A9C73F91713BC89F8C +:10A0300052221D057E2837664D8094D90A6BE9515E +:10A04000E08349C98B26001FFC36C5817438C5B131 +:10A05000F128D4A70E69D6C2511B97B960337C573B +:10A0600066AFD4C27713D2EEDE0CDF4D1CF8B036EB +:10A07000F2BBC943F76E86FA3467B316ECC1DFA6AC +:10A08000B0F3FDA21F5117ED42BE8A3CAD61ED6EEB +:10A0900094E3F96D6E94E3022E657756DE0F7EBA77 +:10A0A000BA36C92AC13CEE947A82EF900B577B9561 +:10A0B000720B95B3D39FB8C9B291F2571DD46FC537 +:10A0C000FA431BA3CBDD99A951F4CB1F389F82DE45 +:10A0D000847CE83FE8D97D1E2FF3F5D5B52FB22C4F +:10A0E000427DE5B1807EDD9FC2F4E541AE1F2FF3D6 +:10A0F000B29B3FAFD3B8E6C3384B53FBE4EB6A687F +:10A10000A77CAB3A27D0473BE7EB55A95C3FF07BF8 +:10A1100013D610769EE846F95A2B23F76F5990977D +:10A12000D3720CF245D5F90F3570CE28A7771E30C3 +:10A13000958B2CEFB14D993FDAB3FFE8C7E41E1CB5 +:10A140005F844D4763DFEB7E2035E1BAEB56B6F313 +:10A1500075AF242CBF59BD0EE24940DE12F9CEBDC9 +:10A16000D7138CBE9E5EEBE0F7EEA9F2ACA91DF40E +:10A1700038CCA762A18580FF26524E9CBA8E9C5097 +:10A18000CB9DBF973CBB8EBC79319ABC11E79DD566 +:10A19000A5B0E7E09C14E4DBC17D2FE0A7FFA74456 +:10A1A000CF6BD04F5759E82F1AD89FD9834867767D +:10A1B0009BE775782EE959DC5DE4B15ED0787F0BC2 +:10A1C00076D1B12796A01CEA04E540F9F10D5A07B3 +:10A1D000B9536475FB017E6408A39FBEF233DFE6CA +:10A1E0007AB177C9F849E42976357F93817EAC1B33 +:10A1F000D07B5F70A890C704E13C4077490C9A3C43 +:10A200001D12F14B85906F9D88764447BA5E0BE531 +:10A21000DF7B9FD8919E8BFDABF78B1D29254636A2 +:10A22000EEC4C950B6E93D3B16C13E699401F749F9 +:10A23000EFF3FCBEE99F5EB583BE9A2EFB13F3A538 +:10A24000DEFBCC8E77E69539F27BEF37E9FA26C054 +:10A25000FA6EB4EF741B03710046F5FEB366C35F7C +:10A2600008E4458FDE7095C07D6437DE8F1219C417 +:10A2700044E169E711288B3F77611ACE880BF547D7 +:10A28000A01CF535DB9EDF289FE8D62B2D47D8F1A3 +:10A29000F0A1CAFB164A7ECFF6ABBCEC754FDB2AA9 +:10A2A000AF324FADD45F8C7914723016CACB5210D6 +:10A2B000FD5EB286DDC320EE5FA0FBD8C401C5B051 +:10A2C000EF65F952E321CF884EAEE2A71F2FB817F2 +:10A2D000F9DE84F64FCF3EF6150DE609B46A5DFD52 +:10A2E000C7C23E76C320E7465AFF8F40C22F0ED02A +:10A2F000B2CEFA1712797F5BCD866E45BD6363F8E7 +:10A300009E20C883AEF99B8C7AA78690AD80AF1A49 +:10A310007258BF36420F9296FFEC81FB302AE72A33 +:10A320000170B8AFD24C77D1F72AF97E83781B59E8 +:10A330009DEFB308F9EC7617EDB73281BF4F664F4A +:10A34000C77ABA68AF62F541A2BFD7D8FB29A2CEBF +:10A35000FBBB49D47FCEEA59E2FB16F67D9E18FF7F +:10A36000BDDBB1DDC2DE1F3F60FD74900342BE570E +:10A370000CE0F925FC7E1F2AEFA70C48B86E5E8919 +:10A38000B29DEB03719F4FC54FA7C4BC07FCDC22F5 +:10A3900061EE5BCD7D3AF46F5F8A6BC98F3C9F2C79 +:10A3A000F250DCE51617D87B6B5E1DBC4BE6F93826 +:10A3B000606F6CE3F1E50AD98CF188EEED4CCEF7D5 +:10A3C00065AF2DDFF0BA029FBDDAF93DCA18A8A328 +:10A3D000E35D7E2809F3DBC9C000C6C3570C90C4F7 +:10A3E000F92A3CDF2AF2BDEC39C405FB53FB6B268E +:10A3F000764FE5E70194BFCB5F63FEDE353B8FA070 +:10A400009E5B2C3B908E0F6779D600DD765AD87D07 +:10A4100084CB37BC81FCBA2193DB09D6D050053CF4 +:10A420007BC3FF9E1BC0FF9E7F24FCD57E66713ED2 +:10A430007AD577CC4BEBB4B038A893E3E9538D636E +:10A440000487D723B09ECBCB02B9361992860389F5 +:10A450002CEFE8DD62D80775D75BF09EA379EB3E61 +:10A46000C98F3C97224AB5FD7F0EF8A8380CAFE69D +:10A47000DEF07D16F0731DF82ADB7F60F826698315 +:10A480007A27C44D4FB37BC746043ED547E6BBBCD5 +:10A490003580E9DDFEFC1E6A75DED65B032C0C4FB1 +:10A4A0003C1EB366C6BB63201E23F8617C0C6901A9 +:10A4B000FF3AA56B27A76B27D0B5A0DF705C867E1F +:10A4C0001785BFC2F44B147969EF0E50DE0B46E1DD +:10A4D00016B801DD06FE9174DB4AED5F8C63BE6247 +:10A4E00042FF891ACE5F71B80A786BD3AE0F676DE1 +:10A4F000DA0F03676D9A43E17F10F0EE4B3FA9F14D +:10A5000023E61D854F8BBF0F9F36A67339A50D62BD +:10A510009EA81AEF3169BDF0DE3FEDFA7857B6FF1D +:10A52000C07857C34D5DD6F0F8A6FA795E9A88FFD9 +:10A53000FE3070FCFFCD7F3EBFFE90A27DE18677AE +:10A5400014ED8BBC1F28EA638281722073E10F1F18 +:10A55000772184F6E5F7F5ABF7E54F9FFEF20A0D9C +:10A56000C4DB4A02CC9FFF65BA67531A85F3FB1A16 +:10A570005FA385C275E49916766F57752EE60FAD09 +:10A58000E373FC6ACC7F9DBD97D2CD57C480FE4E4D +:10A59000FFA19BB48EBCDE74507A45435C11796890 +:10A5A000A5469BD685FE1AE28A46370F70BAC1FCD3 +:10A5B0001FCAEF5546A2B3533EAFAA9230DFA98A15 +:10A5C000B07C685AFA3DB47DBA96F8E1DEE34AB34E +:10A5D000D66FC0389FF23CB381DF8B4CECF18A73AD +:10A5E000CDB24BC6BCB459252C3E7897B905CF9354 +:10A5F000CE39BEE9F2BDB49D6CF616B37C6B71FE2C +:10A60000EC8F9AEF12F77B208DF17997C4E3C89213 +:10A610000EEFC7527F37378DF1D97479A30CF92E1D +:10A62000A10F08DADD82EFE8FA8E1B0AD9F90AF8E1 +:10A630005D8A4AA2F30FC6F3CE0F97C3FB35271DE1 +:10A640000897BA928DF980C7BA09D239437E785FEC +:10A6500053B7E16BECA7427EB111DEEF3ECD5CE17A +:10A66000233BE83EC511E9AF0C2E00BEBCD1FE472E +:10A67000CCFB4C831FE9E96CC3712CDF1FF7FB6235 +:10A68000B033820D81A87EC9EFEB1F107E01E12758 +:10A69000107240DCCBB7378DCB05A33400EF53D31A +:10A6A000B252C8CBD7D27AD92B076E205F0FFC23CA +:10A6B000E5EBB7A5F39A64A617D5F4ADA66B41CF29 +:10A6C000709F37FC1EC15DD4DE03BD3A9778F36AF4 +:10A6D000A89CAD5AD1A41B2D7D7FBA5E65FE3C833C +:10A6E000443967F2DDE5B983E54796CBB83F10F909 +:10A6F00009020F9DBDF1D69D767D3B53D9FE0FB764 +:10A70000E33F5FF0FDF41A51D80396F45EEBB6A573 +:10A710005F7FDDCAF61F78DD11E75F16C89AF07912 +:10A720000FC81F063BAECBC7CE33566735E13DF2AF +:10A73000A424140B76E3CA8332D221D1BAB42911EE +:10A74000F74D7510FF47408F2BC6ACC07370BDEE40 +:10A750008932B7E2B938F57D51225FB896F7A3BECA +:10A7600037AA96E709D7AAF27646A4F3FCE042524C +:10A77000C8F22B9476A9BAEC6C200ABF64E7D50620 +:10A78000F4038C4B6FF999372D8C8709E9BDECB830 +:10A79000C937C0DBE47F24DED4F42A5B76E379A8F2 +:10A7A000EF4AAF57335DF3D313C272781EE47015CE +:10A7B000C13DEE061FDCF72FEEC7EE92D87D345D6B +:10A7C000E708FA8D6E74BFF2A8931E3CCF39F25D94 +:10A7D00097CCF20858BE81B05384DD32BA2324B33B +:10A7E000FBEDF939289E17F46DE5973360453B473B +:10A7F000F8DFFE5E7E6BA1E70E1A995C13FEC1A224 +:10A80000A01BEDB84E9DBF18EEB3F7EE3745B5036C +:10A810007E96AEB9EE3DAE7FB5787E06F43293CB30 +:10A8200077719F6B85CCEE7BEE0EC8E8BF5BFFCFE8 +:10A830001FFEF649C78DF7F575D6EEA8FB2251D657 +:10A8400069D87989C27207E6EDC17E09FC77C29F9B +:10A85000A77EFFF5CC321FCCAF421E83F76B76EF9D +:10A8600060F3E90B2F751B42387E9FED7CFCBA83A9 +:10A87000C5D6C8FB30CEA5F7ECCFACE78D61BC7E6A +:10A880005BFC8F0D5529EC9BFFD7F70DD3656A3A1A +:10A8900052FD9827F9987D4A989D3A8F04B05C4004 +:10A8A00042587A08CBA75F4C9C582E256E2CA76582 +:10A8B0007A4EA5637E4B2811F3215FFDEB50A09BE0 +:10A8C000CBE3463741EEDC0F65A775153870FCAE5B +:10A8D00057FE9A01792D37E2FFF858D70598A73A25 +:10A8E000AEF16FA532C64F88712DCAFB4A7E4B026E +:10A8F00099C0E262DB12B390DFC2F22FA959C83FC0 +:10A9000088B7E69DD3B0FC909512DEE7DA16D42026 +:10A910006BE52DCBF2C1FD3C6DADAC3D6F8DCD2710 +:10A92000D17ADE28136BBFDBE683730FF34910F98E +:10A9300071219C7A90E11C0C936FE2FE736AB167FF +:10A94000839DB5ACDDC8F2F7497020C8F1FC3EF636 +:10A95000371332189F0FCB66727B5899D20FD18F65 +:10A96000B7AFCC2C5B960171D90C574C065DDFB0AC +:10A97000B8C0B6478AD02F8FBFB3F2C5A87B307E50 +:10A9800028BE6BCA2CB3C27B2F492CDFDC7B90FF27 +:10A990006E01092546DE273A2DB33C11DE4BCF2050 +:10A9A000DC6E8E0E57F83D3A7794FD9CC8671C0606 +:10A9B0007B2AF48FB37BA95E92583DFF19EB1D9B58 +:10A9C00087A20FDF0B766D53A66730AC63989E109D +:10A9D00033CCFF69836F17DA9FF519E08F5CF18C38 +:10A9E000410376C1C754ADC2B9927F6F3062F90995 +:10A9F000DDE742F91F749F0BE539BACF85F233BA10 +:10AA0000CF8572D91527251A42DEC970B9603D225B +:10AA1000DEA69EEF28016F31FE413D8EBF32D3830B +:10AA2000F0EDC1F77EE28378C84BB6506ADC75E87A +:10AA3000AD6F39E3E5FBBDE8F959C332D8BE36BF87 +:10AA4000558B7A3CBF2D18BB3CE2BDE9197A6CCF1F +:10AA50007BE5733C27DA69ED81AF4BA24B9EAE617B +:10AA6000F5E9CFE4227C5766BA96C1BA297FCF8038 +:10AA700075E4B77DF82F709E87F68F79045D52E8F4 +:10AA800031B4F355EB50C341ACEB255B601B7CFF4D +:10AA9000D22BD9B0122A6F08E31BA02329DA7A3708 +:10AAA000E27CEF30848AE09CCA1DD7E4A879C32BEE +:10AAB000334B11CE12D05B42049C38BEBE2F5FF7E1 +:10AAC000C4B3399D1271BF06C84E07E8A1ABB1608F +:10AAD000D755F2787D5BEBC0F7617DDEE33219E498 +:10AAE00040FA55F0DD0E8E1F51E61DD4BB014F2FED +:10AAF0001D3C3F10EE5FA5781908F7B16ECD18A484 +:10AB0000F02FE68DFAE68947ECF83EFCB21A95CFB5 +:10AB1000CD15904F32D778E82D58D27CEBB90AC8C2 +:10AB20002759982C1D837291236B22E491887CF71E +:10AB300025434A8F012B4D7356A23D560AC225422A +:10AB40001F941B63F865D042FFC42BEA9392072839 +:10AB5000DE9FE2C851B44F1D728BA25D8C3BCD3994 +:10AB60005CF1DEB0B85036ECBFE83AD8FDD7CFCABA +:10AB7000987797F7CAC9DB6EA1F5E9CFCDC2FBFE86 +:10AB80005EE2EDD3F795E3EF0B765178EAA92175F4 +:10AB9000A1E4C1C71E81CE54F67DCDC15F1E7339BD +:10ABA000AE63DFDFC0AE17F27575BBB118E4EBB76B +:10ABB000B5F3D578792583DF1FC2EDFEBEE8A58702 +:10ABC0001F2407A3177EDF969A5E20B394D11F2B14 +:10ABD000A79F60E7C0BEAB1CFB13C8B18873983D4C +:10ABE000A5CADF364CEF7C7F1DF8DFDF93099EABF3 +:10ABF000E3E7F396C3BFE5309D93A5CDF7C37D5240 +:10AC0000F4B917EC4F3807EAA2FD5FCEE07653CDDA +:10AC1000A1FB538AC2ED64FD39C5FBE43E698BA2FA +:10AC2000BE394B59DF5EBA25F2FBBEE4E1F21D8B63 +:10AC3000F41E3CBF2945FD3D57319F8AC326CCCF2A +:10AC4000BB1DF24EE8A3DAA20FB4106FBDBD0FFD1D +:10AC500029E4CE1C99D4476BBF92C1E28ED30E9BE0 +:10AC6000309FE5BBF6FB318525E60BBEC6F4E7C792 +:10AC7000FD03DA48BCCB99ACFFCBC50FFFF35F20D7 +:10AC8000EEB99F60FEE6651B93FBF9AD5F6834B4D7 +:10AC90001CD68FD14BBE35A8017DD2551DE385FC56 +:10ACA000FCBA9516CCEB1C961DFAC85840484CE6E9 +:10ACB000B69F1B29BDFD110E3346E8D32ED8E3D035 +:10ACC000BAFD5F1FBC6333FDF7D4C326BFE67BAC80 +:10ACD000C74E6D28D47F658CBF1700DD70BD02BEE6 +:10ACE000F3BAFB498F9E017900EB87FA6D990FBD8E +:10ACF000FF289D77DD3B8CBF21534EBD6F9F1BB15D +:10AD00006F274F31BE34D2FFC09E5B75B4490FFB35 +:10AD1000B91BF3770BE6CD7C5BBECECFBC211F9F6A +:10AD2000984AF152B79FDD33D1DD3E08CFB5F6A585 +:10AD3000BFEB766890FF44BDB35D9E0CF4AA3E273E +:10AD40002EE049ACB98A7B9CD68EFDAF19A027D7DF +:10AD50001ED4B2648FBEC6D9AA218E88715E7AC312 +:10AD600050CD7EA792CDBF4BE8E7837F8E2B1DCAC7 +:10AD7000CA8D51F41CD5CB3A3BE8E54AF67B0BA7CC +:10AD80000E269501FC4F49C4EFC073572CCF78268F +:10AD9000EB0E9E9BF1FE90E421DAC87B0EC53E725D +:10ADA000D6C15983C08EFCA875F1298A19B22833FF +:10ADB00007E96536F1A2DD7BCAE64E077FC3741E44 +:10ADC000EF3F650B75803C3E35364682F83DED7FA2 +:10ADD0003389B8AFEF94CE9DCEEE831079C5377F1F +:10ADE000AF7BDB2AE4FB4AA742BC7A1EB1C23EF22B +:10ADF0000E99D9B5E44DC69742DED549813898E71A +:10AE0000B4CC19EB3221FEBBE167B8AFEC819B9665 +:10AE1000FFDED3B7B46B7BF6AF7B24764F8993D933 +:10AE2000FBB5632EFD62369C73A3FB6C89CE677104 +:10AE3000DB21BC8747BDAFEED9DFFC0FFDA3BDF71B +:10AE400047EE87607DC2EFADDE27F5D8E5C2BE7B59 +:10AE500096E5B91F19FB78E76A5A5FFF6C0CC2F1DF +:10AE6000E233062FC8EF8BBB0CB8DFB918173AB323 +:10AE70000EEAFBF29C5E1C2D17CF7709FA5EA171DA +:10AE8000FC01F40EF99D0EEFDDF8E26903FEBEC78A +:10AE9000CA5FDEB40BF64F5FA43B7EFD22F8F77E5F +:10AEA0009D80F7019064F6FDED9C1F81BF1C141F6F +:10AEB000F2F316B41B56BE9C82F24BE0EFC2D326CF +:10AEC0003C077FF1F8CCFEE007EBD0EC65BF3329FF +:10AED0009BBD208757EF32A1DD47F49E9760FDE5CB +:10AEE000CFDF3E7B388CFF610281F574B5BF8CFEED +:10AEF000C7307EA3EBF5EEF61C26077AF42CCB9B2D +:10AF00005D18BEA7F915E87F0D11F720B2BCD94234 +:10AF10005962BF3BF950F473E0C73299BD5823FC26 +:10AF200025F1C4980C7CE821ECDEC78706E33DBB25 +:10AF30006733F9F96512E2E71D05BD9DA93D80FE65 +:10AF40001203CBD7EBE35ECB1399367C7FB9F16B61 +:10AF500085DFA476C315657D28FB1DE6C246C7F0D4 +:10AF6000BB69B98EC3F9BF92DCA7607DAB5A1E7E68 +:10AF7000F55D84CB533FF9238C7BDC8C7E1AF22E5B +:10AF8000839F7AFFB2DC18E271876685DD7B7EE7FE +:10AF90001F307FE4FC2BB7E0EF942D9603E7E17EB2 +:10AFA000AC4E4BE0ECBDB4DC77FC04E2453DDF5E2B +:10AFB000717889C9951A58C770C85F715FCA44BE55 +:10AFC00065FCFEE9B63C849FF0D3765D8CBEBF1273 +:10AFD000F314FD8BF989FEC57BDF707C5DD607F22B +:10AFE000412FFB200E11B1AECBB1817CF8295C5F03 +:10AFF0003ACBE7BE1C47EB117473A378CDFF055C19 +:10B00000F134E600800000001F8B08000000000003 +:10B01000000BAD580F6C13E7157F77679F1D623BE0 +:10B020008684FC217F383B10D2262447FE786902B3 +:10B03000E39A908822B69AC0B48CC138DA42293497 +:10B040008D97C086E8242EF5C43F819A69DD46A716 +:10B05000D2192618D2404D3340AC02E68256C8863B +:10B060005A77651ADD2274CB5A16AD2149195B85D2 +:10B07000D42D7BEFBB3B9C73025BABD98A5FBEFBDD +:10B08000BEEF7DEFFDDEDFEFDA00E26A15C0B3B997 +:10B090006F80A31AE8137667037C05CC4F56A6038E +:10B0A0004200ABE87F099FD7FDF62EE703580DBDA0 +:10B0B0004E2806B8CE776F130580E1DEEF3B550FC3 +:10B0C0002D5AE2BF590AC0697FE4C7CB00C6E9B375 +:10B0D0007832057000ADA3CFB840BF1AC04CFC6DEC +:10B0E00084D208F2B9E5F7687C25C02C8973DC743A +:10B0F000E3742114D23A9C97E33548FB5C7214E563 +:10B10000D9C6878B24DCF7AC18AF0021B96F1BAF11 +:10B11000B2E7C3DCD58D10A4E3E215612FC0E8745B +:10B1200011B80CA433E58492857CFE01F251E4331E +:10B13000EA84B63E3CB7A6898FF4313D1C833ACAF7 +:10B14000C703C7E4AB29C3E7E5008BE8B9DB943B51 +:10B1500080CF2BEDEB93FAD8C767249EE95793C9AC +:10B16000477ACB27E3F1B8391F85B840B8E2679535 +:10B170001B716F307107500440BB3C678E9F737B1F +:10B18000E24205CAED736B02EAD3700EED82E3066C +:10B1900047FC4DA29C02B07D06AE3DEB1CBE2707CE +:10B1A000E1905BE6203EF5A67939E4B506D7EDE2FD +:10B1B0002240E7BAA187D17D5C82C9F1451863546A +:10B1C00001BF8328C2CFE8120833DA021146974242 +:10B1D0000FA3CBA097D1E59060141E8E4721402786 +:10B1E0007DC77F331DC9634FF3E3486BBE0A915E91 +:10B1F000CF641CBE4938D43E08078D237FFCAC3891 +:10B20000B4809ACBF8A5E25150CAFC3B150F17F950 +:10B2100023DA2D0D62B94417812E105D4C8E8B7C84 +:10B220001E05C941E32650D8B8F97FC4A14E571D69 +:10B230006AF91478344DED173B4CBF1827DD6726AB +:10B24000ED745292D8D8B217A09CE1F993ED683D05 +:10B25000AF496FFCBBE407F841AC31ECC8C3717572 +:10B260006357318E8F49ADC6B8A1F117411C1F8FAE +:10B27000AD0C3B1E21BF6EAC76CA00DDDDABC24B10 +:10B28000705E4DF35500C615B495F0E43F5BFD06C6 +:10B29000FE6AF736D98F71A4167A64D2CFED42CC0C +:10B2A000103FA158803AA4454BE3179DB86E89A87A +:10B2B000F6503CB6BBE33E0971DFDADD9C03A8EF34 +:10B2C0006ED158EFC27DEEAAA45EF85C4BC3715FED +:10B2D0005F591717BCFFF9C8F790544B72CCD58053 +:10B2E000E438CDC986251B73DA304F0C279CB04F4C +:10B2F0004A9EF3A31CF508C901EE1220BBE7BB0D63 +:10B300003EC37D65656497930412CD6705AA09B7AE +:10B310000F73C22769FDA8D7F0AF936487DAFBD318 +:10B32000DF4BCACF697DEAF3D10F5100DC7F415278 +:10B330005F27793BD23F2DA1BC34B2E0BD5D7A20BE +:10B34000E9A71C9EBF06F58E2A1013591E59E8BFA7 +:10B35000897914D006E368CFD10DC80771A809AB6D +:10B3600051273EFEC29AB1102629E27B8ECEED1007 +:10B37000F5A205B8EFA5953744C3CF0A0C3F33F3C8 +:10B38000D0F90BFDCFE71BC3304C88AB8E0B77FF9A +:10B39000F927C4AFE3B647A6E5C9787AB90B7CB400 +:10B3A000C863CB1B569CD59F75C5051F8D1FDA4002 +:10B3B000EB16BD37504C7A2D1ED0A35EE273FE0F04 +:10B3C000F9861C665D503EE13E4F5D6816283903E4 +:10B3D000749E16622EC4AB938B5CF2D2F824276B5A +:10B3E00028FF5FDDE81F19B45EF1E4A15E9B4CBD50 +:10B3F000DAFB8FEEF222DDF4CA93CBA182C2C1C97F +:10B40000F2B7845F8AFF2DC79DC97CCE7ED110A87C +:10B410006707589FB8487ED0DE6B5FD701FB3FA619 +:10B42000BCD33131CFA35CC392378BD9CBAC57405F +:10B430002504F93D6DEE253D3C24F77931E6E29097 +:10B440001EEA92FD3436E3074EBCC0FCD25A0FAF61 +:10B450006432DB5BF1F4CC1E943D338957E53197C0 +:10B4600042B8571ECB5148BF4A11D68519DE31E686 +:10B470007795E81B1CFAD36BD3C7823C9EF3DAF9AD +:10B4800052193328BCB15381BFCC49CAD769C653BE +:10B49000B370A249443FB8FD14F83124A1B3FFA70B +:10B4A00051378E3BF702AD80DBF4837C6E0FF131B8 +:10B4B000E253DF5F9D4BF63E65C6A72B97076902F7 +:10B4C0004E69D234904A93630B5F97699FF4D21907 +:10B4D000B679AF3CCBB63FA32E68DFAF2989F21017 +:10B4E000E56363FF74E561DBFADDBE962BE4978BC1 +:10B4F000121B97132E994BAB6CF32170B3FEA1B6C0 +:10B50000C023C7703FDC31EA791D7E593D808840F9 +:10B51000FA35E8003F467BD40F3B6C764FD3D11F02 +:10B52000715DDAB50976C73F97641FCF0F987E50DB +:10B53000000513FD2089B3E71E8ECC0FFA7111E1CF +:10B54000EC1563D8724CC22904733268BEF68A00C7 +:10B5500031867B971CC7E733C376BC73DAEC78E798 +:10B56000A9767CF337D9F12D8CD8F19DBDDD8E679E +:10B5700040B3E357BCA7DEB67E6E4FA36D3CEFE051 +:10B5800032DBFA8762ADB671D9F1D5B6F5F37B9FA0 +:10B59000B0CD579EDD6C9BB7FC2AD5EE0BE29DB675 +:10B5A00075A976AFBEB2C3C6D7B2B386DFFFA79D7B +:10B5B00037A7D8F95B281BC5DDDBBEA1FD14865F6C +:10B5C0004E37F252B3B030A190BD173A65B2E93BA5 +:10B5D00052669397E2DDAC4361B30E417817B37BBB +:10B5E000D8F41339215FA23C5A753DDCE4C3718D58 +:10B5F0001EB944E93834D4D39421313791FCB89E34 +:10B60000337179BC8E03872D5E709C9DC46DA5D669 +:10B610002D64E0E2864F6351962EC9A9F0FC567363 +:10B620009EAB33F2FA0A250D1C13F058643E072A2C +:10B63000DAC86FA131052BCDFB00F6E520525FCEB5 +:10B64000BB63D1C054FDA47C50607D92CAFAA6CBE6 +:10B650009CEA24BACA9D28A2FA75285B7D298079C4 +:10B660007E849725D667717A94941A25C558D17926 +:10B6700027AC9453FF8EFFCEC2BCCB5F0D6B1E2652 +:10B68000BE5F47F955539EC301F55000F11FE4FC1E +:10B69000BBAA71EFDBF51F1551FD71098804E6C1E6 +:10B6A0004C9FF2133A47DBBD703AB35B0EEA8779E1 +:10B6B00054E725D63F683B38761FF888983D3221FD +:10B6C0004EF73859DD01F37EB4D6C4CBBA1FAD3185 +:10B6D000CF1F44169B304FAF3D7B99E1B2257718C1 +:10B6E0001C99CCDF589FF46481A76A1FE9A454CB4E +:10B6F000ADF3E9B9755FCA173E4B5D6C16CA33F4FA +:10B7000029FA458B6EC91D62F7B97BFB4F1875E4AA +:10B71000FEFC355667937A1BFC07F7A6B3FA32B8DE +:10B72000B7B0916892FF08E3BF36F2AECD4FD66D49 +:10B730007FDFE67FEBB53FDBE6F5AC31673EEAAF96 +:10B740009FC96BF93AE277EBB42B44F746B4DB358B +:10B75000B28BC55F3F306F099DF7DFF5FC1BC377E8 +:10B760006067021C73927ADED8799D8DF59D3AA3AD +:10B77000A97A5AF74C8B8A17A1D481F619E3A6C986 +:10B78000470293CFD91C34FAF08147B31BA9CE0EE0 +:10B79000148A0E839618E3BC3AB7316E594A74D4B2 +:10B7A000E9D943F7CC010E140EFD610DA7BCBA1EFA +:10B7B000F97E3B5BFD98FCB363F3588503E3A1A3DB +:10B7C00052FF0647A97FBA7A87F4E7B0BDCB9BC189 +:10B7D000E42CA1BE6388D72A38CC0515C19C15D4AA +:10B7E000970F4DD346A812971C99618C45233E4272 +:10B7F000C17FB178A8F1ABFF263E1F70429CFC567A +:10B80000FB25173BCAFC4D175BBD2C9EDAE8DE45D5 +:10B81000F75DBA6F8CA619D419E4987E620AA55E0A +:10B820009D682868E4B566617F0947FDC1411750EE +:10B830003CE0390AF515DA7957EC288EB35176EAEF +:10B84000537E2D1AFD7CD5AF5C71CA1B1BDD77982A +:10B850009DF28201C62FAB183317F2C97AD1158B2E +:10B86000927C7AA26805CAD7E3C4FE85E2FA1ACEB2 +:10B8700023DF5B07E61DD937C11E7941E37E084F00 +:10B880000118F3398769BEBD7FF006E5918B01B5DC +:10B890003088FC0779294479A4DDF7A648F9A73256 +:10B8A00028B17D282FD317F3C1773986B3DBFF0189 +:10B8B000FAEB3A4C3619747FE3D5B9C15ABAA7E806 +:10B8C00022F1438F60FDDFFDF4BFB521F1C372A407 +:10B8D000235EB988CEB1CE45392A898FA5B72547D1 +:10B8E00092CF83FD7AA37BCC16BF375FDE5D4271BA +:10B8F0005225700C9FD4F52D262E034EA3FF4B9D91 +:10B900005F4FF6AC9DC23EF3007291BAA661AD43A3 +:10B91000BA927042FC6E7D0DF5617D8BB280ECDBDE +:10B92000DEEA91296F59FC918FFAFA03CEF92427A8 +:10B93000FC25B2C3E6C8F7CE5C9592F3E87FCCAEA7 +:10B94000DA01C35FDA2FBC7FE3793CE5999FCDAF85 +:10B95000A63C6DED4FC579C42BB1F73B4F087186FE +:10B9600023E2BB9AF8F75DF95D36E162E1FC79719B +:10B970001D2D4C88C47FF4F0DD2209F7B79FBB7CF6 +:10B980009DFCB6DD7CBF00A7ECEF0D102F8DEE9374 +:10B99000F7EA08E5D6D96C9A9BD8B7B9ACFD050E85 +:10B9A000FB7E6CD0793CEF94796F394BF9628AFB5E +:10B9B000EDA904CF4AF4A95CEC0BA9FE60BDA77AFF +:10B9C00063D5FBADEFF22C0EB60680CD935C6457C9 +:10B9D0004E7F8BD51FEBFD4594C3BA8AB8758AEAB2 +:10B9E0000BE497A076B17A24CC46BBE2BEBEDF2C36 +:10B9F00033EF69467DAB35EB592DF121F9CB335847 +:10BA00009DAB31CF0DB9B17F0A52A9D0CCF734E646 +:10BA1000FB8CBD6FD9EE77FF01E91E35E2601400A3 +:10BA200000000000000000001F8B08000000000064 +:10BA3000000BFB51CFC0F0038AD5151818D6293159 +:10BA400030DC5266607055616038278F90A31556C0 +:10BA5000E5A04CFF0B4606865740FC0688DF319276 +:10BA6000AE5F4B18C15EC9CBC0A00DE4D7006955CD +:10BA70000106062E205B0788F701F9F780F81510FC +:10BA8000BB08313070F331309802B11810EB02E589 +:10BA90007D81F4373EECE6EB09E3B7FFB9002A5F9E +:10BAA000521095CF20805F7F97207E796921D2C385 +:10BAB000C44E9DFCF868A240EF40E09B0CA87C0BB4 +:10BAC0005906062F3906861E7908FF1A92FC3CA0FB +:10BAD00098A52C345CC5816907C8BFCC80DD5C1992 +:10BAE000A0BC36507E15D41C00DF43986568030067 +:10BAF00000000000000000001F8B08000000000094 +:10BB0000000BE57D097C54D5D5F87DF3DE9B2DB384 +:10BB1000852C842D4C58141070085B1094C9860134 +:10BB2000020C8B881675588410208980FD51B51F32 +:10BB3000139688967E0DA2965AB0030D82FDB00D25 +:10BB4000183560A0C366B1451B5C10BB7C1D16D9BF +:10BB50000C2404A5A3C5FADD73EE7D99F75E664853 +:10BB6000B4FEBF7F7FFF7F102FF7DDFDDCB3DD73F9 +:10BB7000CEBD910D76424613F235FCD07499400843 +:10BB80004989A6F4E79F5FA71232C94CFF2512929C +:10BB90002FDA081942C8441B099A689D89A3E8C78F +:10BBA0006442DEAD128222B4A1F502C3082926EC5C +:10BBB0006792446A85DB0969CE7AB562909B10C1B1 +:10BBC000EB25CB3369EA769199908E3AF085E020A7 +:10BBD000C4996520A40F6BF335FD9BE8B5625F4AFD +:10BBE0003EA9A083269FE2EBACA9DF71460F4D79F9 +:10BBF000277F3F4D7997A24C4DBE5BD91D9AFADD48 +:10BC000097E768F21981719AFA3DD74ED1E47B57D4 +:10BC1000DEAFA97FEBC6D99AF2BEC1624DF96D3B8A +:10BC20009668F203AA1FD3D4BFBD76A5A67C50E8C0 +:10BC3000694DF9E0A3CF68F243EB5FD0D41F7E7269 +:10BC4000ABA67C44F8579AF29117766BF27736EDF3 +:10BC5000D5D41F1D39A8C967933F68EAE79ADFD793 +:10BC6000E4F35D7FD6D4BF3BED8CA67CACFB534D9B +:10BC7000B98207E3FB5CD37C9FE0F987A69D447CF7 +:10BC800014D884184919A6665289A99554636A2361 +:10BC9000F5989E49F7DF8FF8F962A08250BC5B15DA +:10BCA00068FAEF249ABE9BD5D3E9EF0FBD7909A1BD +:10BCB000783B91754D269A6D2191E299C94C0216F7 +:10BCC0008A0A8E08C5B7248A771182A92B42F16DA2 +:10BCD00030C5BB8819D30E910EF83D29E2C2343924 +:10BCE000D219BFA744D2304D8DF4C0B463C48D695E +:10BCF0005AA41FA69D227D30ED1CC9C4765D221E6C +:10BD00004CBB46EEC0EFDD225998A64772F07BF798 +:10BD100088175377641CA61991024C7B44A660BD1A +:10BD20009E111FA6BD22F7E3F7DE911998DE129946 +:10BD30008DE9AD113FA67D22C598F68D1461DA2FED +:10BD4000B204DBDD1629C3B47FE431FC3E20B21C13 +:10BD5000D381919598DE1E0960EA893C8DF50645F0 +:10BD6000D6629A197906BF0F8E54623A24F2027E87 +:10BD70001F1AD988E9B0C8564C8747829866457E15 +:10BD800085E988C80E4CEF88ECC6762323D5988EBB +:10BD90008AECC5EF77466A31BD0BF02D09F02E8491 +:10BDA000A937F27BFC9E1D398A694EE43DFC9E1B3F +:10BDB000A9C7342FF227FC9E1F3989E998C8694C1E +:10BDC000EF8E84312D885CC2746CE402A6E322CD30 +:10BDD000D86E7CA409D3C2C897F87D422482A9C238 +:10BDE000EF4896DC1056F0AF07FC7FA6EBDC6D94B5 +:10BDF0002F11BFE16B9A121BC58311D1FAFA94720D +:10BE00003BE49332C5AB048ADF899417023F9C5808 +:10BE10002604EFCEA0F8911C3E0C7939CBE436D144 +:10BE2000FC03A44906FC25A4DEEE1B40C88111E7F3 +:10BE3000BB8629BEBE9B12EA46911B7E90DFCA30AC +:10BE4000A79EC06F1BA430FD3E31F9608ADF06ED6E +:10BE5000296D64027AD3F101BF293A025F7E402244 +:10BE600001079DEA71E86104D60B99687E6621F1AD +:10BE700066D2FA15234C3382749C8A4C5F918FA64C +:10BE80003FCEF0CD80F4F7403C74FE87787A9C1862 +:10BE900030FD32DD85E9CC477A337ACAA340ECD451 +:10BEA000361C1E4865ED88AD291DD6D7DE7612A159 +:10BEB000ED8646EBBF4C7C1FC2F7400EE953668B04 +:10BEC000D6A3DF4F42BD18DFFF1CEB7BAD813202F2 +:10BED0000AFF400763701BC827E2764E867999DD1A +:10BEE000CE29F6F8F37A7285ABBFD44B3DCF20CE86 +:10BEF000EF4981CCA866FC256DCA00EC1FE561C046 +:10BF00006AC1FE450E7FA5DD67004FDAEE3D8BAFBF +:10BF100091C9537757848BCDD52EB8D076D7112EB3 +:10BF2000126D676F7FBBF869258333F1BA711EFC10 +:10BF30007BA9890404BA8EA66DF6E0D60CC06137E1 +:10BF4000F2CF221767A0C9141854AE1725C21208E1 +:10BF500039BC3F2164A0F573B6D9B7821ED09813BF +:10BF600078DE0770DE2A936DB4CACAFD3F3AF173DA +:10BF70009ACFD9221313CD2F48786E18A170BB55D4 +:10BF800010D8F801EF815EB47F3F517EBC02F43FD0 +:10BF90009FB0FE1B054647816D4E84EB85BCAA8A87 +:10BFA00091340DEF5B5C48281F3F4FC1DA89E2F7FF +:10BFB000022B9120A51CDC88F009C867C38A7C414C +:10BFC0007A96A279B1757E3EE415FAA7EB5E1094DD +:10BFD000A379FA77E10E6D5E052FDCF7268B1CDC6A +:10BFE0008A78D585C1478197B70B831F87579E45B0 +:10BFF0000E1892115E41E0034EC18D7028B2C82127 +:10C0000091F65344E1082458B4EFA95480D3C21DDB +:10C0100016D759D5B88BAB1335F9D2DA4EAEB32A51 +:10C0200039DA7CF4970EA0D3256906D759CADF1AEE +:10C03000567893CED22DBBB2A20053053F16576758 +:10C04000B86C9A7EB4F9E64AA180E1B7DB396D405D +:10C050007C3C5B9266749DA5A47A690793B797565A +:10C06000985D304EC30A978B8D9B86A902AF45CB56 +:10C07000AD585F995FBC7EBFEBF9115243CE9881FA +:10C080009FD3B29EF1EBC7A527E93323D2499D7C0C +:10C090001DF0C64CFF7E6D403CC2BCD26F69B51826 +:10C0A00030DD0EDF776AC6A3EDDCE754F2253EDD16 +:10C0B0004AE49C0A2F97420748A766DC673FEDD108 +:10C0C00049FB6B946C6B418F9AC0F1A714EA517EC7 +:10C0D000B0D81C36FAE9A7CB356C3FE28D7369C541 +:10C0E0008E2EC0D78ACC9546605645D57DF3809E6E +:10C0F0002ED7AC4A05F9B2506CFEBE2F46FB1F2B63 +:10C10000741B949BB4F232C8E749FBD5D019B1B582 +:10C11000AC9BE61B0C74285BEB7E7F2A30B953B2D4 +:10C12000F3F8989174FE25B5578D308F0982FFA7DB +:10C13000424A74FD02AC9FF653BCE39411D677419A +:10C140000EDCF278C64DE0D96A9EB6B47309AAF93E +:10C1500005A82249E9757616A757E2BEF7CF943EA7 +:10C160002FFE41264FD379901BB4162D4FE7A573B0 +:10C1700089CF01F09A5DB310F9CF45E03F208749A0 +:10C18000E530C08FCBC45000EBBB4CDE730C56C106 +:10C19000EFA060E4F0A1AA2CE507261C0AE1D6096D +:10C1A000F895A9A8A25E1C08DFA500E74BC2D7C876 +:10C1B0004F8202F2B322F63D40CCE5B88EB58C1F1B +:10C1C00005E81FC83F5CA9E54FF3376AF3F3C8944D +:10C1D0005489F29779CFCAB447CADFD4FC8FC2EF33 +:10C1E0006581C9DDF9A4ACC245E7BFD948F789CE5E +:10C1F0007FB68B485DE8FA16BFB179D82C9A7F5B81 +:10C200006072ECD20A3AFD5B683F1DD8FA8B970743 +:10C210008DDEFEADD777A666F0F49104FB63F2B134 +:10C220005891BFC42D0D436E4995DCF8EBEF5223B6 +:10C230007A2D0EA847BFABF8F39CB5DAF5B5B57EFD +:10C24000FD7A097906F1AD78C7640278A6AC47D9C2 +:10C250002F653DF20EC11B8C4107618EAF0A5F6BEB +:10C26000E2F053F48ECF75F92F75F9AF757905BFEC +:10C27000654EDF14EF3F1786023D378D6178123629 +:10C28000B2F30CAB678CD6FBF266F54C9C5E68BDD6 +:10C29000AF6F56CF12ED4F32A4B4AEB7F88D575EE4 +:10C2A0000F50FC2EFECD730E42F1F1A25499EAA17B +:10C2B000DF176D5BE300385D90020EC09B8B41B1D0 +:10C2C0002016BC46180445DFB00974DF4B14FC1F70 +:10C2D000553E11E4FBF56DB2EB69BA2FA53B4C213D +:10C2E00013DDEF929A05856420E64FB1FC93570168 +:10C2F0003F4A6BE5D3EA7D2DDEFE5CAADB8EFBD0E8 +:10C30000C5003A30097521342DA9FA640CE8D1A58D +:10C31000A409F159DF0EC687A31DE5D7B38CCED68D +:10C32000E5CAB9B1947D22A5353FBA0AE7C65222C3 +:10C330009D56E35111E032D5F3FA19ECC9705E2035 +:10C34000C3C970E02B0A1C483005F9F2AA977F3A5E +:10C35000F0149D4743D51F1C820A3E544342B83413 +:10C3600057CFF95BD24DE4C2158A9FE41675BB2006 +:10C37000B673D7D20974A4D93A962E92438E9114EB +:10C380009E8BB6C81E8A9964D12BBF7CE9054A777B +:10C39000E46393A73785F7C2578E9CB883E617EE00 +:10C3A00092930BD9326C426A743F4AE95FB0CB2852 +:10C3B000F02F7EF588D13D807D7FA243741F16EE5D +:10C3C0003A6024035AC32DB7FA80316C8BB11FD564 +:10C3D000A7C6803EB3EAE5BF1B61BF2FEE1748C773 +:10C3E0008CD6ED8BB61C41FD05E084FBC7F7A76535 +:10C3F000BF5AED5368E2DE2158CF05FC3ADE3ED944 +:10C4000041560F453CFEF55E3A7ED19F4C1E587F4B +:10C41000D1AF973A601DE7A53286CF9BD7A47AE9C2 +:10C42000B8457220D58529FB5EF4E2A38867F38FB7 +:10C430003F8A7A19C58F4E069419814EB0BE873750 +:10C44000DD83EB9B47FC886F459B455F10F880447C +:10C450000A76C5A087DF707A38BF95724ABABEF3F4 +:10C46000C01F41CF7D4FE4FCF111D4231FE56BA524 +:10C470009A0CE63F37B37DAA301814BB9C5983A7AA +:10C48000554F221FBDD4CDDBD1D51FE1A0F04DE427 +:10C49000A7E2F1FC8E6C7F18FFC57614EF72E13BCA +:10C4A000D4AF97BD96819A769C5FB2F197F1F1E98E +:10C4B000BCADA07F9C4F657242BFBE3F1914FE48C1 +:10C4C000E5AB0ABF5474CDE8BCEA2946D70A9D07FC +:10C4D000271740F9671F30FA8176207FE8BC421D9C +:10C4E000B1FCC03401F980898462D17395CCE959DB +:10C4F0005B4E3934EA6F74DE92E054E309EDBF031A +:10C50000C21FF59279CFD2762A7DBA14C6C37AC6F5 +:10C51000E8F78C28DDCEE7F4FF2BA0FF8428FD93FD +:10C520004D29ED3A9F2D92832FBD00F44AE933E067 +:10C53000067A957DB0EE4F771E3A713FC5EB4FAB53 +:10C54000153AD5F24D3D9D16ED7E94007EEAE9F454 +:10C55000D3AE6524269DD2EF31E9B46BF87F856FA9 +:10C560002A703BAE831BE583BFD8EB8E0F3F3D1F88 +:10C570002C35B863F241FAF30119D61AEF147C5343 +:10C58000F0ACF8BF1677077ED3828F0ABEB5E0A362 +:10C59000826FFA756AE1A62FDF04FC46A51FC82B3F +:10C5A00049C04EF7B9699F88E7C4467793A3031D36 +:10C5B000778D853C047A76A38BE71359BE29C5583D +:10C5C000017C41F9DE642133003F1B7D4D8E449593 +:10C5D000FE7CAA4E74B8697938480A62E9D594E3BA +:10C5E000E2F86112AFBC1CE1972FDAD2970F81738A +:10C5F00095E801DD6D6EF9BD0E305934D6F59C34E9 +:10C60000837E7FF86D116D1A8D56C74098173DB720 +:10C610004B9D287CE7F07DBE4002CF8FA2EB9A5362 +:10C62000C7F4E2B9EBB4F098675B66043E43F5CF1C +:10C63000281EA8F045F113146DD296179375B85FB4 +:10C64000C53AFCF1F3F34E2791E3CF2032889F37B0 +:10C650000CD0DF12CEA7F2C5FE936650B8371E1578 +:10C660008989E69BEB445201EBDC290409D0712057 +:10C6700005F1B084F207A23A1736009E19E3D36F92 +:10C68000C36B7F1DF638ADB2E8F53F0FFC394D1B8B +:10C690005EFFF8963721FFC647E97F26ADEBE7EE50 +:10C6A000FFE241E0EF8DFB4D04ED24FB7F97FE3868 +:10C6B000E4F79A3C68E75869F2A27EBCDF1EEC0DF5 +:10C6C000E5DD987D69D5BEBF0F0CA3BC598DFB94E9 +:10C6D00027B2734473DD3FFE5B488694AE0AE4E8FC +:10C6E000FE04D4AF4BF75A8270E86CDCF7F7617E3A +:10C6F000DB77B79E1223F123FED9C98CDD80AF8989 +:10C70000CC9E56FAE6885F96D3F117D71C30CEA19F +:10C71000E5B9BFFD6A20F095C6DD4C3FB822875FC2 +:10C72000241E422689CF95CB74BFAE80AED699F237 +:10C7300025F14476C0160B2E0C0E8D140EB02E0A69 +:10C740009722E087F1E031EFDF161E571F84F117C3 +:10C75000D50D2762861A2E82977DB707CD02AE9F30 +:10C760007DDFFFF781C0773FAD2E47F9DDD6BAD721 +:10C77000C0BA53FE5F5AB7106ACFBAABFE6DD7CDC1 +:10C78000F0BF9FC8E4919E0E5AE3F91BDFC7FCAFD0 +:10C79000ED1E9C6F3BE9FFF0BFEDFABFE5BEEF1663 +:10C7A000D01FD7D6BE9FF9B75D775BFBFE36DF772C +:10C7B000BB0BECBD8DFBBE4A27AAF5B7B56E83F463 +:10C7C000EFCADF6EBE6E45EFA93794B986D0F97D0A +:10C7D0004C2AEFC9A0E91FBDD792E1384A69C017BA +:10C7E000EBDC9029B1738309EC4C50F11E41B11779 +:10C7F000D56BFCB85D8B50CF98E8FD31EA07442A31 +:10C80000ABCFA6F5EB73E6789EC61A9927FD909FED +:10C810007627CF6BCF531373C61F05BDEEDD723A7B +:10C820003F885BE826B9A8A644267945D403698ADF +:10C83000FADF87E963B0DEA42CED79E23EDD79E032 +:10C84000DE19DAF27B78FFD3C9332960779B3E97F4 +:10C85000D9DDEE25656B5CAA7DBA47D78F4322DC14 +:10C860004EF2EDE037B7057E4B101E245BF46C23CF +:10C87000ED801F61F0AE9F3628087618227918FCEB +:10C88000A62FF6A01D949F3365DE5EB6ADAD07BA48 +:10C890009589F67CA99C13DB8233E1E74FECAF4727 +:10C8A00014EEB257C4F3A7AA5F848BB21FDF741FC4 +:10C8B00094FDFBB6FB310CF62386FF6C81D97C0F0F +:10C8C000F82FCC7D043CB74F5A27621C8CB9BF802F +:10C8D00070F465C9E8DFF9C4E01B068A73E1E0E1A2 +:10C8E000258FB16E3D009F051C8EF34819EA9DE42B +:10C8F000C6D75F8F02BF114286967B099940CF2130 +:10C90000F34609212B5DF77C89049C9960D714C8F4 +:10C9100069B55D33A8CDC3CF5DA9D17EDAAA1F8FDB +:10C920003F7CD7E9DF283F3ADD8B9E572095707812 +:10C93000497D4E7CA88EC1B1749110EC817814921F +:10C940007D2ABFCEC71CAFFFF6C460E473D93F1980 +:10C95000E0C4F3ABB71FEAFBA55CDF6F0EB89D60C8 +:10C96000AF69AEEBE9047B4CF3D15C879A2F2AE9DF +:10C97000717E8E7C7F8519D3C63CA15284F31669E3 +:10C980009A887238CF4280EFE8DBED9114BB4B19E7 +:10C99000F333D21F7118EC23FB994F9B3A3BA8F657 +:10C9A0006DDD848BD2C0D6FB003FA7557E927F15EC +:10C9B000BE706E05B81EB784C7F862ACF70F1C7E58 +:10C9C0008507BF30829D604A5D860C709992276A08 +:10C9D000E26E0E49FC3C35980C8679151E1CEB184E +:10C9E00001FB7254F458287C4BEBAE1AFD31FC6D00 +:10C9F0007A7842FF60173E237BE6013CCFFCD842A9 +:10CA000002941EDEE1FE1F5AE405FE45BBF2827D64 +:10CA1000EC0389F915FACACC2E3EB5305B4EA1E382 +:10CA2000F6AF710D0211D399D7EF2BBBB1BC0B6FD1 +:10CA3000A7D4EBBC88D53B657495C45AFF04235B2F +:10CA4000FF7CE2F97E96F0EFB76FD93FB187724075 +:10CA5000BEE709C8475AE33541FA682E1082207FA5 +:10CA6000E11C8BF94201E5FF3B06561E98C2E4A586 +:10CA700082F77A380B3283B3327E86CCF0D92833F2 +:10CA8000F8287056E0AB9FAF529FF2ABD16AFBCA59 +:10CA9000A4DA41BF06FDA4A44E7081E9AF440A1B8D +:10CAA000810E4B6BD7CBE02FB8CFCDFA25926FA07C +:10CAB000DA5FDB5796703E873247A2FE786D1DD352 +:10CAC0008FBD73AF3A400F7AC7E0F9E348A0C7774C +:10CAD000458C278807C73FAFD8312D4F52F79B8130 +:10CAE000F39CBA285B0673D0F7161D903BAAF0A9F9 +:10CAF000AFDC01CB95EF9D17B933E13B1D0FE7117B +:10CB0000F84F13D946BBE85F5D9F9340CBBF579664 +:10CB1000C8F0B0A8FA8011F319585F194F19474FA0 +:10CB20004FD30A1334F939B9E1AE009742536899EB +:10CB300027069E1E96153FC93794135E8AB703FFDA +:10CB40007F901357C77863C06D83DC4A3E748C2591 +:10CB50001F9694BB3B02FC97ECEBD9118863C9DBB1 +:10CB6000F9A9B1E4C3872B983FF023CACF206D9C6D +:10CB700046E5C3ED2AF930CD82F8A16FF743B99DA0 +:10CB8000F241D9AFFF653EF321C88718745D296B68 +:10CB9000E5C3F4BA59281FA64F13895B658F7B52F2 +:10CBA000E67EAEB8F2213BF53ECCCB9E841878F3FE +:10CBB000213F97005C218571404EFC96F37DBDBC02 +:10CBC00088C7CFA71805EEAF6E839FFF5F82B3C201 +:10CBD000CF97D0F30BE881ADF19020BF5E721FE5D7 +:10CBE000E702E023E3E74B1EE076491D7FF5017F76 +:10CBF0001DA2E6AFAC7D899FC983D2DA8C9FCEA4FB +:10CC0000E5F757CA1E33AD7F7F94DF0E53F3DBDFAA +:10CC1000727E4BE19CEE8AB1BF33662610B7965FF9 +:10CC2000F5023E7566D0EFFABF0A78FF8E887EC4A3 +:10CC30004FB81C3F36E87743C07E9E6C94107F3E11 +:10CC4000E1FCEBCA8AE0B43C4AC7B973993EBC78B0 +:10CC5000A7887028A9617A5E492F6BD04DF36332A3 +:10CC6000BF407FE0C27DCC1F48015598ADDAC78533 +:10CC7000EF842BBA40F91601FD99F33C0BD18E4F8E +:10CC800036323BB199FE61711D5EB4232FE6F05A36 +:10CC900050B705EDCD0B825A3BF4E25EE32EC2396C +:10CCA00040E1BF0B77E8CA3D4FA1BF6231D89B5529 +:10CCB000E70F91EB0F0F8BA1FEAF426CE71FD9B9C5 +:10CCC0004ABFFF4ABD96F517FD8BEB3F4ED73FE4B9 +:10CCD000BB5F7F7BD72D1B39BD679221401F9F18FB +:10CCE000BC48EF81DFD3F5D371E6AEEFDD511D67B0 +:10CCF00094C4E9F21D83BFA213D42B11B0DEFC4D06 +:10CD0000BB8EA4D2FCCC6A3208CCF4F3376AE5625D +:10CD10008B1CAE71A39C9D59B64B98DD1FE04DCA8C +:10CD200000CFE6649AFCE04F3D6E6942FEA5E0DD6F +:10CD30009D4686CF23F9B8673A37E5E139A25670A8 +:10CD4000215D842CEC5C41E16FA1F94323FE3E861A +:10CD5000C31BED31A5B56C7F4AE97E005D8DA9E36B +:10CD6000F91D4C0FFB1E9537E80FAB3B2043BB2250 +:10CD70005A3F09F94D3F8D9F0BFC73D9A9AA7DDB62 +:10CD8000778AE1ED36C14362EC5B1FFA27E6BE7D90 +:10CD900047F8AAC0E34E23D7E7F9FE1DB7D4170E14 +:10CDA000463F94E0D90A95EB12D18F72B6B227EEC6 +:10CDB000E3788EBF7ABC06FDDEADB2274D8689438F +:10CDC000BC658105E3DC70DC1E4CFF51F313FDB93B +:10CDD000B994D4A31E3341F0FF5552C5B54DE7F1C8 +:10CDE000278A9F5655EFA7F24DEA91349701F8E450 +:10CDF0005225DE12E28753316E097F0E751BF6D184 +:10CE00004CBADE6B6B450FF87FEE35B84F8C02FAEB +:10CE10007D5A268097D78EC95EA6772620DF9DF59E +:10CE2000CE19194C21B3284C60BF67FD90F1D73360 +:10CE3000D019FDF6272AB7BCE0AB27D543217E7871 +:10CE40009AE740BE9BEECB3D438EAF013FDCD45C06 +:10CE5000D7891300DFA74402F03DBD3617CF274B1B +:10CE60001F1110AF4F523842FB7BA6659C3841C75B +:10CE70007D606D0AFAD5667A8FE4039ECD9964B71A +:10CE8000817F6D7C1F91F855707C80D4A39D626674 +:10CE9000D923F7C07C8BA81C003B6B51DDF1FC8EC5 +:10CEA00090DF2478DCB4FFD280DFD8916E61FDC6BC +:10CEB000AB46B0B7CCA3F5607B4A37B17AA55582B3 +:10CEC000C702F858B71EF9CEBC2A81B8A03ED5F7E4 +:10CED000CCACDFA099F65BBF89B6A7F9F9D01EFAF2 +:10CEE000AD4A9C0E7EB4D263226B9F55FE16F0A510 +:10CEF00079B41D2D26F5558F607F0B3609248DF6EC +:10CF0000579495F19F59D0DF31D903E51F1DF8994A +:10CF100011E6FD201DAF13ED7F8E18CE87FAE47168 +:10CF2000C1B50DED4D2C4EB691D301F9A013A32F31 +:10CF300081E7B91EA8C8C3F78D3D109FE62D2FAF1E +:10CF400080758503291970042AADBD6A04BDEE2CD5 +:10CF500085B39FEA6D67781CDBA1C0196358C5A72C +:10CF60009A8C3DB1FDDCDA6CA4EF87890FFDDDFE04 +:10CF70007226874FADB10405D03F6417CAC9436B11 +:10CF80006E7D1ED67FE51519FDA357BA85D11E7B90 +:10CF90007E934C02748EAB3689C837CEEF64762010 +:10CFA00071B38CF9F98F1A317F68D3D431C00FCFA8 +:10CFB00053F8031EE66ECE37427E3EE5EBA618FC24 +:10CFC000639EBB98F10B1D7F98BF514BFFADF8C519 +:10CFD000B2318CBFEBF8C1E2AE1568E7D3F38952EA +:10CFE0006253F84326E4EB439D107F4B8EC904F453 +:10CFF000B912C9F5E046C09B9916F01453BA081D42 +:10D0000001BE762D28B803B4FC7B0FED190AF03B66 +:10D0100007F006BA589784FED479C1590857259E5F +:10D0200070FE462D3E2BF14BF7F945E255CB81A220 +:10D0300004E255D5FBE887142FE9780FD50A418B18 +:10D0400000F9536F3D3A04F32EC0C392E55C9EAEE7 +:10D05000B323DE7EF483AB6B002F1F7C42C0F993B9 +:10D0600080BF02E44AC946C10D76CCF94FB0F6F351 +:10D07000697BC0978F7EC6F087E2B11BF0BC64D39A +:10D08000FAB7B07E95E086FE3FDA320BE56F51408D +:10D0900024585E750AF5632A07300EE850404C05A7 +:10D0A0003C2F596D72C13E2AF8A2E0DF2999F9EDB3 +:10D0B00089D933702A6DB7C5E8C675EBF14E9C91DE +:10D0C00081F855BA5346FC280D307C3AF58A8878A9 +:10D0D0007868CDBD883F57B60971F02FD7D809F0D1 +:10D0E0002FC8CA5BF0EF6581E31FC3EBF3CB183E9B +:10D0F000E64239E0DF6B5C3F25C4A6D63B14FC5307 +:10D10000F0A92DBC6B2597E2E01BD58DA7C3BC967B +:10D11000AEB1E0BC732BF64C5F8E7423A37F3EB799 +:10D12000E207A940A7F3241687A1C071B1C4E27435 +:10D130005ACDE3D97263A7F6CC47378F0351B9981C +:10D14000097211E24A42749CDFEDFC25C6AF5DFE18 +:10D15000D5298C4B5CF826DD775AFFCA4E3B09A1D6 +:10D160003E1D44FE525C23625C289142C3A6AAEE97 +:10D170008F28F1160B7F6347F816EF36050B69FB16 +:10D18000E2D7CF0C447FF8CAA6B7807E02BF1298C0 +:10D190005D3E101E3815E22A2516F7A197BB234CD9 +:10D1A000CC5ED3B0276106E83FC28E03E84F2AAEBB +:10D1B000BE5736A9EC931E938CE3D27AEC9E0BDD1E +:10D1C00077F023C2FC260F50CFAF9CF5F732A39B1C +:10D1D000E25A19F5A2E21D5BD0AE57BAE32AC6BDEA +:10D1E000E6FEE61507C0A1B456D4C643ED104326AB +:10D1F0008CD7124F99187FD2C42595D4B07B1925AE +:10D20000D53CEE471717B3F037FB5E0F50D02C7CA0 +:10D2100075BB03E8E852FD3607C093F687F14493E7 +:10D22000B2E2C41BB5156754FD54CC38A34BF00FC4 +:10D230008A200F9AB4F1996407E35374D787F9628F +:10D24000D833157D65E12B9FBF0871AF0DBB3F7DC6 +:10D2500011E6BDE89FD75E84B80DB2DFE202FDA102 +:10D26000F4571F62FCA0D26EB9899F7F5EDE8E717B +:10D2700097573E36A1FE7765DFF974D00FAEECFA12 +:10D280002215E22997EDCB47FBC3B2D7723B921828 +:10D29000E75B2505BC0CB623EE53BF0F876AC4902D +:10D2A0008DCEF3F24913D2774BBC58F562167FE767 +:10D2B000E671623B63C7D52AF14D25355327DD0959 +:10D2C000FCAD86C9F19678A7B6E2C33EA0FB797B98 +:10D2D0003BF66D278FFFD3EDDB65F807DD9FE74C4D +:10D2E000DAF8B0CF6B1EFEC50B505613FB3E9942C9 +:10D2F000C76DC14B89DB9D63F2064D4037BBFF0B09 +:10D30000E3F060BF0ADD20E73F4F07BBE505B90941 +:10D31000ED814DFB4C2E88DB2ADEF711D2C795D765 +:10D320008E635C2CE1F1B35748CB0F8B77E43689E1 +:10D33000D22A3B8B2BE37087B833B703BFF3F832A5 +:10D3400086B74ADC59BC78B30F4D3DF8BD0B1617B4 +:10D35000B7D85D6F04F8ABE3D0842CD8A7539AF804 +:10D360003D65DDFAFE5C0087E1EAB8C978F17C5CD6 +:10D370001F6FD927C687AF6CE171942DF19184742A +:10D38000CD84781F26EF4A83C24724063D2A719335 +:10D39000F57A7A0CB62F5EB2EDF97E3B781C32310D +:10D3A000FB930297861BB1F9F1A79CBEE9B9E49201 +:10D3B00049752FE5217E2E51E2C894F9565433B9B0 +:10D3C000DBB083E9857A7A2EE1F676FD385FF0717D +:10D3D0004A6A0F0C04BED370700FC73786CF253B47 +:10D3E0004F19039C3F07D5FC19FA8BC14F4433EB0F +:10D3F0008F9E6363F657BAF36ACCFE2E49DE7B61DB +:10D40000FE97EA999E71A95A2C08C6E8FF32973F09 +:10D410002DEBB61BF15C253AACC87F96D9B34E3ADA +:10D4200093213562FCC2AA721EEFF0434F1AC079F5 +:10D43000957D1C81F9AC01F8A8CE99B2CB4F40CFB5 +:10D4400091D37C43E0FCA4CC572937261B4850BD20 +:10D45000FF5200EF474EECF17709E44BFD0AEDBDBA +:10D460008E7AC9752489F6579F2778409F6D8D67FE +:10D47000DAFE277B458D3D0C6CCFB0AE668F01F791 +:10D48000D36E08B9681562B7D4A7E141CE4DDC521E +:10D490002A8674A35FFBE9153BBAC13D2B07F1084F +:10D4A000506EF7B4DC6FC1FE9C4417671D201FC08F +:10D4B0007D481B67264EE23A0076096B1FD207FCB7 +:10D4C000D62E62F5C0FB0A1BF8BDC775763FCADBD6 +:10D4D000B874E361F75E143B91334BD2DC8B49F4B3 +:10D4E0006AF349BA7B900ABFC62B7414FE63F8BB7B +:10D4F0000F89F96CFD60AFEAAD9A6F620AF184A002 +:10D500007C820DE3996D36363F65BE743EC80F28A8 +:10D5100098D87CFA8703A087D379E9E898E0BD27FB +:10D520003ABFD3BAF969F4B8FBCC5C3E4844023E3A +:10D530006233D7130EE7666D9C698040BC81B305EA +:10D54000AEB49CF693214C3241DC820B4EC13D714E +:10D550003C5DBBAE2EF57DB15AF8C708F4171D36F9 +:10D56000829FDF2CC0F19974045C032048F54600CB +:10D57000C64F6D4A3E84FAA2AFE6389E3F17571F4A +:10D58000C77203E4699A94E0CEEB328890A7D6E69E +:10D59000E5A5F5857AB3D20C1ECC1F96808E26FBAE +:10D5A000D30C8360FA79AB0F8F22643B29EB07160B +:10D5B00025F36AEFE1A3DD00AF083AED48C07B1820 +:10D5C0007073BB92A70C10DE57D86E6DC97BCD94DB +:10D5D0002F6EEFD1920F40BE0A807F078CE73DBCD3 +:10D5E0001AE27CCCBED5663AEEE4CD06A4BBD111DE +:10D5F0001B9E3F48B803F26742CAACBE18F7A55B52 +:10D60000EC3CBC5E5B7C7C3B8F479EECF77BE0AAEE +:10D61000F7702E8F892B3C18EE63379A673F6F5651 +:10D62000D3E1E666B1079DDFF3B0F7B4BDB3C03513 +:10D63000AE0F9D9F739381C5CF9AFD3F87FABD9F23 +:10D64000F01BA0CA68125E2A001FFE4B32CE47199B +:10D65000A7621F3B5755AC31045722FEBA05906FA5 +:10D66000D1FD0BEBF6AF89ED5FED29DCBF92BA532C +:10D670006CFF6AB71C30727B3C9C5BB613CF2E30BC +:10D680003DED5A3B234FA2FB92646AAA807D95C967 +:10D69000F4BCC2BE08D7DFC4842B9F5F5B70DD7E05 +:10D6A00061EB8F06825EDF60F0F426517829F54E3B +:10D6B00098599CD864ABBF0EC6297D365C01E7DF64 +:10D6C000BD17DE433F70EF86E6D0403ADFDEA3B8F9 +:10D6D00039858FBBBD612BFA33B7031EBBC175EF14 +:10D6E0005F0972323E3C187EB7C0A3E614C2C70081 +:10D6F00079FA7D37BF4791532B78414E2499A81C66 +:10D70000A5E91FCDEC1C73C62CF294D9199D0D3DD3 +:10D7100024D08B73A619F03CE5E46974FD3CFECF80 +:10D720002C69E48BB29F0A1E11529900E79C02A754 +:10D73000FF2F5ABC7926A1072D1F7DF6F452B0EBBE +:10D7400029EDB6AD209EB9AAFBD0147FF668DAE5C4 +:10D750003F6A057BA8521FF032D63981B6BB04ED73 +:10D76000601C58C79EB3CD22C0BBBDFBAAFF5EBFE5 +:10D77000828ED72B3EFDF8B2D9BD22FDF77F9A15D8 +:10D78000BF23D347BCD17B7FFF047C586C0E3BA6E4 +:10D79000D1FD2DC9BE660438AC4CB8323296DF33A9 +:10D7A000DE3CEA6FDC6A03397D30628A798FA0AF94 +:10D7B00085E917EFAE98E1013FFC532DF704983C43 +:10D7C000CBE37C37AF577121635AAAB83130587018 +:10D7D000B9990F5FE8FC0AB27649203FF3894A5EA7 +:10D7E000323BC504D0479ECA1109C6A9B9648D7CD5 +:10D7F0001B0FF67207BC0B52761886BF3B4D7B0F92 +:10D8000074D2A85312BC5730368B8A6301DEA7D17D +:10D81000968FD7DD139DEC9DE5C9E3E5D7F0FF4179 +:10D820005CE7A4ACFB3C796A392155F6817D3EFE6C +:10D830009518536F7CB4053E3E84EB1B160A9FDBA4 +:10D84000619DB3563399747378E8E1A8874BDE5F26 +:10D85000E6317BA10E1E77DFA83C9C14030EADD7EA +:10D860005DD907E4A6023F3D1CEAA12EEA4DA620A1 +:10D87000E881F55218E1584FE118E07EAB7CF53EA7 +:10D880002BF3E1FAC378FE5D0F4F3D1CA97E81FAB0 +:10D89000C3D80176B4831D0378611C40E50726FADE +:10D8A000FDED5E32791A785F6834C619DE45105690 +:10D8B000E40DA12C0FFD322EE65FA1F29CE1C35FC7 +:10D8C00098FDAA30C2E63FC6CDE265283C4EEBE0AB +:10D8D000715A87079A738B7E9E6FC03F46C4C00FF4 +:10D8E0008E078B2CFC7C934EDC70FF7FD8C7439C4B +:10D8F0008C2FC4968FA323BE967E98DEC1DEE710E0 +:10D9000088BFE5BB8BF613F2CA18FF996B76217DB1 +:10D91000E4126F12BC07014186304F655E8305DF5C +:10D920000F2D29F07ED3D824F5FB10CAF8CABEE427 +:10D9300072F8E592C0013887E612E933F5BA95FE30 +:10D940002A2C5CCFEA4EBAA39F1C8CA143A3FD29CD +:10D95000EB4B4A22217C3F4430E33D27FA5FC0D89D +:10D96000213A9E123F9A689F526941BF4E196171D8 +:10D970001221DCCF1C5E9EC3DF6922E6B8EFF29075 +:10D98000AF13A2F37BD12248F86E029FDFE5A3E636 +:10D9900000C46B3C26F8B7021C1A846303015E5472 +:10D9A0001FBB05EFE9EBCAAF9D3C5C02E5B4DE3C72 +:10D9B000ACC7D7B5506476327AFEC7F7505AF371C8 +:10D9C000664FA3E426C1FC15FCCFB132FA1E4FDC32 +:10D9D0005DF1BD34E297203D6C61F7D0EE3EF90C6D +:10D9E000EEDF1FAC771F057A2B204109DFF9716943 +:10D9F000F1B04D3CEDA33FFFF2775DA4A67480EB40 +:10DA000041CBADBD408E29FAC27B16DF6F61BD07E9 +:10DA10002D8C3F9FF60E7D17E4C2ECECC12786D01B +:10DA2000D460F6E1BB0B0F035E517866015ED1B6A0 +:10DA300007A1EB4E88574761DFE6ACD5E19599D950 +:10DA4000D36653B605EBC8592B7FA99E570BBCB8BC +:10DA50005C6C4B3F2487A9429F0AEF2D30FC3C6849 +:10DA60003105406FCB798AC547CC21FE172B057C49 +:10DA70000740A3AFCFB530BBF7DC9F5990CE69E329 +:10DA80004D65E0E7B2F0F71CFAB077775AC6AB54B1 +:10DA9000B5877D37A7221ECEE5FEC3B3023BB7CCC8 +:10DAA000B5E4B37BBF1BE566353EEAC78FDBAFAE9F +:10DAB000DD4181D9490ECA6E8C0753DA5DB1303928 +:10DAC000DE6CEEBDC97093FBE0F3CC1DFA4B49D17F +:10DAD000FC398B65462CBD40E9AFE55CDE729E30BB +:10DAE000AE39DC357A9E3094CB47B4E709F9C8BF2C +:10DAF000729EB03F2D1F594DDBBF6DF3A55A617C5F +:10DB0000C9D717E0FE1CD70FA926D3576D974EB57E +:10DB100032FD3075790E393338FA3E9B20D199E0C9 +:10DB2000FB1AFE729037D20C82FC9FF2998762C575 +:10DB30000525DA733A5B8746E9EF2983BBAA92C5CC +:10DB40002BA0BFD7B77C36EA7353971761DA78FA00 +:10DB5000C62D4087391C9EB75A995E5A9AC0E84331 +:10DB600010FCB7427FF55ED10EFED485B522F7D703 +:10DB7000B177ADA64E1053E0FB19B38CE7C08376A6 +:10DB8000B6AF67087B9F26E7B8C95743D31B247BF2 +:10DB90009C55A5EFDD2079982769A9E8BF56EE2BA3 +:10DBA0009E21196CBE6B997FA0796D06C6311F94BA +:10DBB000B5F6A85156A60F8FB2B2FD9DCDDFB103C9 +:10DBC0007C82F724664B6EB40FCE8E18D93B6A74F4 +:10DBD0001E886F166D3FF956163F91CFE13F1BE44B +:10DBE000E460A8A7EF4762FD73BCD5C3FD4D4BEEC3 +:10DBF0005880D30DE21D6745BEEE96003E39430EB8 +:10DC00009F04FED6363F0F08C0CF4B6F08A1EE60D1 +:10DC10002FAB91F17CD6C0F5FBCB35875267D3741F +:10DC2000F1AEF71D700EFC9E95E95397A57A7C77AF +:10DC300062D16B22DE9BA6689AFA3D6C3F6718BBE7 +:10DC4000F7C1EE2D2872EE8EAF7A76F5613D76FF44 +:10DC500040D1AF72CD8120CCEF60B98876292A07F8 +:10DC600035EF90E4D7B07B097ABDEB11ABCCE3354F +:10DC7000D93E2E73B171E2D16D4EC44A822ABACD1B +:10DC800091DC12CC3F27E220410AF7CB17B66E9801 +:10DC900048F13C9026E3398F1E7F0EA3DEA7F8C122 +:10DCA00003344FC739CCD773A466EA34785FE52DC7 +:10DCB00052B67A00AD9317F6273322A6A7B4615166 +:10DCC000BD2BDFA5D5F7F4FA6041DDFAD5F0164B90 +:10DCD000037C80F1CD268C236EA5279AEF8EA91F99 +:10DCE00012B21EF1F08ED77E391EDE9FB8E3A2C1BC +:10DCF00005F39B6C7533FB62CD357C1FA18484A634 +:10DD00004379498DE80AD1564748CD6D201715391A +:10DD1000AEC02574E390D903FCDE22BA56C23ACDD8 +:10DD2000F7D820CE626463FF64906707CD32DA21B2 +:10DD3000732CBD6D7354F87C3099BD1B7024B9A74A +:10DD4000F6BB79C36D20D7F6F0B8B5C3E7EEB7855B +:10DD5000B1DED464D4CB1439AED357157BD7D8DE1B +:10DD6000628BBD4BADE71271D3B3165A3EFE561906 +:10DD7000EFBDE58599DFB4951CBFE15FCDCF239A58 +:10DD8000EF055C3F6825D7A370D6E8A16F58B95E50 +:10DD9000E9260340AF0CDDD8B010EFCBD625B8563E +:10DDA000A23D81E92D8D678B374C80EFC744661FFC +:10DDB000B921221D1DDCBFB07B5845BF5422E0BEF7 +:10DDC0005D1F74F5CA9B745FAE7F62F504E0B354C7 +:10DDD0007D5B6CBF5890C329D499D9D9039DD93B99 +:10DDE00018ECDC7957F4DCF90EF001784706C443EF +:10DDF000DAA65346381F5FA6AA38E2175D34E0D78B +:10DE00005DDEB0A8BE7F738AF3DFC956EFFBC01F8B +:10DE10000324A70B55424891D59B0D71E04D938982 +:10DE20006B2B5DCFBE0B39824CF3A3B66578049A99 +:10DE3000DF0D8A25F0CDD7C420C493EC867B6BB46C +:10DE4000DF05F595C60C3A6EA04644BBFE026E1F78 +:10DE5000BF2007D21355F85199C0F8C905D9FF0B57 +:10DE6000E8E7C2C726B4775FF8C41A53AECE48605D +:10DE70007CF74D2ECF3213DC980F35EC7DAB339D04 +:10DE80005728E21A04702FDE7155847793EEE4FA76 +:10DE900057E1B3F5ABC12E33715393047CC71774AC +:10DEA000E583489DB2C323831C9AB6D327839A3D4A +:10DEB000BDA60CE39066D4561E81FCFDA16ACCF78A +:10DEC0004FF047002E77AD6D3A04E8D2AB9248F898 +:10DED0008ECF674CAF4AE5F3E811F11C7422366728 +:10DEE0001B00BF5BC67FA25E02D57DE26A363EEDB7 +:10DEF000CF9040D77D5759532EC8B5F4E5ACBF74C9 +:10DF000072A0DCE98EF63BFA46BDA0B617BCF898C5 +:10DF1000AD88F15B06F7F4C73B6FC173197159F116 +:10DF20005D454E4F398FDBD00F70FD07CC0F707DF4 +:10DF300010D3A7AFFFC0160CC4D0A7A378163231F8 +:10DF4000FC52F08D9859DE6B067CFBFEF36556A003 +:10DF50009B649FDBA88E3FCCD950D8EF6DE8DF6281 +:10DF600042BB5CCB78EBD97810880B78ADC8B1D9BF +:10DF70003AFF4B940F30BAA05D04615C2525C24A7C +:10DF80001751E749280DE6939EC0F85C95D13D13E3 +:10DF9000C6ABB29A5C30DE6C736F23F0AD16FB2615 +:10DFA0008F4F1BC9F5CB7D170E26C1BE5F1F549E38 +:10DFB0000E7A73C8F073E4536DE1DD4FACDEE10916 +:10DFC00038CF00EAF94AFD3DE7ACFD414EBE69603D +:10DFD000714FC433AB3BAC5769378DA7BBB99F4E6C +:10DFE000A193E47AE2DDD21F41E5DDAD82C7A4044E +:10DFF000468F4ABA5B7607189DB1B8CEDDF690B968 +:10E0000027D0F39E9E984FF6119B07E2586A7B7BC0 +:10E01000C05F43F9C0A404955DEA4ECE1F92EB9B0E +:10E02000902EDB7B1E18C6E11B92AA397D11E453AA +:10E03000405F8C7F87BAF0F778D0FF077C83EF4F83 +:10E0400027210DE3C1719F95752773BEB08CD33D19 +:10E05000C001CA4B795E295FCCE1952FF677AAE320 +:10E06000C75AC9F5E56904F4C7FCE59D312DE5F310 +:10E070005D605E8FF6D205C9EBD14E9AECADC474EB +:10E08000415E257E4FDB340BF163C1C6D8EF8C1D9A +:10E09000E57AD9E50B06F69E94C1DA19F04F297F8F +:10E0A000C72A737EE97F1CF0E162CD86E707BAA339 +:10E0B00076DFEB96CA89F703FE6F135DE5B03F5537 +:10E0C000F9823B065EA9E107F02AADFA1CFDA62500 +:10E0D00024CCFCA6DC2FAAF84F83558C9F5EE4FA73 +:10E0E000599155AB57562618383FAD1F7F3B1D3F02 +:10E0F000D4DC2B13FC4121292C4A6CFFD06E047C0C +:10E10000D885F8FE74FA638047821DF51EE0ABBB2C +:10E1100054F8B170E7968ACEF49F77DD60F77742C6 +:10E1200012B1A9F9B782270A3FD6AF6F2BC75F0597 +:10E130000F4746E5D4D6046E1FED49FB2D59DF8C01 +:10E14000F6D137147A067C037A5EABE0DB20037BE2 +:10E15000374D4BC7C3BF23FEBEE79917D2D1FE9000 +:10E1600045E916DE5903BA8E8117BF6DE103FEBD86 +:10E170000931E4C145C1FF8BA49ED1F67BCE8DEB66 +:10E18000375BD5CFCF389E5F97FDDD5D31E01585DC +:10E190002BE90CF850447706E04036092E75DC7BFD +:10E1A000F22666E7AFE7F055BED7EBE03D3AFABEA0 +:10E1B0005C3D8377931144765A90E905C430AE33C1 +:10E1C000C8F90556EF38B4B7AC37107C4F55C84185 +:10E1D0007C4FAE7AEEDC574320B5F440BF09711B8B +:10E1E000008F163CE5C6F3E0CA972C8897E71258D3 +:10E1F0009CC4CA2A99E1A75C89F875F193E2EEE024 +:10E20000770950B9DE3B86DCF9AD4E9EBFCAE5A862 +:10E2100082773DD631BCAB92BCD644155E6E27DE0C +:10E220004CE6EF6772251E3E46F1C83548C1A3593A +:10E23000F47B8FB56111F68BEEE335A0DF9EEB9A90 +:10E24000909FC5DB47C5BFA6ECA7C2E787DBB4F745 +:10E25000FA641B5B4F729C7880A89CD3F26578FFB0 +:10E26000CF36544B0F70E552594F23874B3CBA9829 +:10E270006363EF3E57FC75C38340CF15EBAD9E95AE +:10E2800024EAA751FCA7CA3C3ADA048D3F47EF675E +:10E290006934FB536D2ABC023FA01BF93DF3AB2848 +:10E2A000BF8760C93616E7B4078A808F9CB506D54C +:10E2B000F7776F958857CAA470B565E0BA6F0516F1 +:10E2C00042F3C9CB8DA4173D775D1F71E0B083D6B3 +:10E2D0009FD0142EBC9D2E718F313C6D12D87D893C +:10E2E000B718F40CB4D103FE37B07E89AB5A33CFE4 +:10E2F000811CDECAFE54FC754E5A2C3F8002C77842 +:10E30000FB3287C3C3C9CBF5F46FE1E59FB69B7EB3 +:10E31000034EA0DFBB48A01CE22FE8011DE3D65A44 +:10E32000E8971ED8A1FF029B967E957C0CFA2DB033 +:10E33000A9E9371266F4CBE9D459257B63E92DD3DB +:10E340006DEC9CECACCACF0679E4F461D839D00D01 +:10E35000D2FB024AEF40C701A0DB8E004F86673D2B +:10E36000BC9518EFD8A38AE9E3D713D97A17DCE96B +:10E370003D00EF252FA0E7018156ADE4F41E1FEE0E +:10E3800021A7C0E49B13F8CC5DA3C2B92087DD6050 +:10E39000EFE888BFFA023765F428120CD17D77DFE9 +:10E3A000208C7F7CF2C2838F01DF586FC37B4F8A42 +:10E3B0005C4A4DF017DB86C6A76B8A975EB0572D77 +:10E3C000F9C2C6CE8D71FCE2A3971B48AF24C4F3FB +:10E3D000A56A3C1FED6B1201AE4909FE34399190DC +:10E3E000D5B69C31E66E747D1954EFA5F9729A5F2B +:10E3F00007F6B70E61C2F315B64EDFDE5EB77A9D43 +:10E40000F72DB0D7BD94E05D09EB82380048EFEA04 +:10E41000D224227F6BA75FBF14EC77743DA7EFE98E +:10E42000F7D22CFA75F67DBE0A2855ECC9C3B93D62 +:10E43000B9B46E10DA995576E50DB0FE7876E5B68A +:10E44000C67570BAA7F88DE73F47569308FC51E1AF +:10E450002B5B6C1D383E8709BCD7AED017F025D09A +:10E460007795F802B03BDAD15F11447C85BC333339 +:10E47000CA6FD6551A62C63F55DB6C1A7A51F82915 +:10E48000A9FBC7EB8F29EF2C32FE5AADE6AF5595AD +:10E49000A75399FECADE2D5BCA6D001B567AFED8C3 +:10E4A0002B397AEF7984C91880F716E981CEED52BD +:10E4B000C54F0A7542C80E71795FD222C0A32F0DD5 +:10E4C000986EF80F5F4106D8594E1A90FF96F07B70 +:10E4D0004D59DD09BEC353CBEDA3D9676C5EF0FF88 +:10E4E000370A66E49F8DA7AC0190AB8D7603DACF37 +:10E4F0000FEF33215D5CEB65E5F68FA0C64EA2F809 +:10E5000073AE1D9B9304FCFF79EED77CFEBE5BD0FF +:10E510006EA9D8732589C2BC0384E9B07B9939CB35 +:10E520003BA3BD55B1EFA69A67092C8888F52F99B2 +:10E53000D9BA5225BF00F6F12D6DC43F9CB1191513 +:10E540003DF82F00DFD227C24638E72A7AB022AF43 +:10E55000BB37F438007110DD0B98396D4B83C10067 +:10E56000EBDB42D12831A3355EB5E04FEB38838B2E +:10E570001AB9B486C519B4E479BB5FF03883D167A2 +:10E580004FBF8AEFE999FD1F6BDAE5A75863BDD34A +:10E590003D7DF963D83E1EDE4F37B0F779F4DF13C7 +:10E5A000EC9C6F4B655DF07ED4DFBE9FE08E61C753 +:10E5B00099FED7D9F87B24F476B7E8F8FFE1C9A330 +:10E5C000FB26DBB9DF2F9DA4835FAD2D3FA67EDE4A +:10E5D00027647FB758F2491F67A78CD7BA3D3B978E +:10E5E000B5D43312FF2E1BEB3753D5EF283BD37F27 +:10E5F000A60B04E3DFC95704E5B4822714EEDDED72 +:10E60000B47CD83B67065BD1CFD324021FB876B267 +:10E610005757F4AFC739872AF321C4DF3B561CC7CD +:10E6200074788727C6FA46D8997C9E2E333F85702A +:10E630005F6FB40B4CB7980475DC7E6F65BF74FEDA +:10E64000D88396E178BF11ECF9B1E0A7F7D3F606CD +:10E650001FEA5006174F0C7C52FC820A9C2BB2BD5D +:10E66000D912B3A7E13DB5642FE39FC90504FD6B43 +:10E67000C3052FC263BC3D03E7B785C7C75D3BC673 +:10E68000E2598765BBF1F73C51393116E03A9A847B +:10E690005F35A8E2AD143CA97885CA638DBD31A071 +:10E6A000394F27723EEC82F72654F5DC4F000F8875 +:10E6B000CA81AEABCD9A7CFA321791547222D19BAB +:10E6C000A6C977F5B9AC708EEA5AE0D6B453F04ECD +:10E6D00089F7C39F6458B70BDF3DEAC0E7335CF0AE +:10E6E00023DE005F033BF202BE9F74BDF371BD05E4 +:10E6F000E16B6ABC51D6DBD6BA4EAF70232F3CBB60 +:10E7000082CE97F28539EB32CAD310EE2E02E78B18 +:10E71000732BCCF8FD61DE3EF1D959788F3671B597 +:10E720001BEDB889DEB2B7E09E4F62991BEF15CCA6 +:10E73000AD1404B0F7503E83ED36AF7061AAECB76C +:10E740008B960BB6E83BE3F1E4D75A7BBBE5D75A8F +:10E750007B0CF965307BDE06BFFFE23AD10D78B164 +:10E76000AAB003DAFD3654B3FB6E87EA58DCDD86C7 +:10E77000E94C8E28E35E79CD89F2E28AF2FB54BC43 +:10E780005FA64EC178802F5381CF6EB3F99FB7AB90 +:10E79000F8E586BAA116FEFEB246FED01F17DC7F52 +:10E7A00040DF9C007AD2A0B5524FA4FB1761BE6433 +:10E7B0005E78B0A527E0A9FF7D78A7F4DAC9CFD2AB +:10E7C00061FF143F9FE20754C651FC8482E0DF6E74 +:10E7D00057F1A9D67E40ADFF4A7498314E374B644D +:10E7E00071BA2A394B601F57813E48F16CD5292BED +:10E7F000C263D5578CDEE83C5F85710EDB8721FE56 +:10E8000028F294CE73E0BB243ACF524353BAFA9D18 +:10E8100052D53CEB6E3E4F5D1C2B9F97689770BEA8 +:10E820008DC4EA8179D51A3D27FD2067AF58D19E66 +:10E83000D7E8BDC302EFCD36923B2CF00E6DB5CDBF +:10E840007F14F643ECD6E4003DFB50DDE0BE30DF44 +:10E8500078FED8265BCE31A84FD7F7474847BBC2D2 +:10E86000D77EED8EAEEF267EDCF7A1FE3758FF5F38 +:10E87000BEC9FA4BE1F767300339EA5302E7BB7AC6 +:10E88000BC12EA0E7C01F143947E306E33904E82CE +:10E89000AB289C2A0630FC227309FFFD395A3CD86C +:10E8A00066F335C07C14BABB097C9A609D1B6DBEB3 +:10E8B0006648611E700F84F299CFB8BC7AD568881B +:10E8C000EA5149498C5F3525128CAFD1FBC913ED54 +:10E8D00053FE01ED52FBF80557FF6F84E792E3A664 +:10E8E000F00B615C84720F7531F87321BEAB466E1C +:10E8F000D0FE9E1D2D1CAA6D3E8703FC3839EC3DD1 +:10E9000039C02B78FFED26F0E8E04078F85320B5C9 +:10E91000CB145F002859B3D200CE8D666F2AF895CC +:10E920007697333834BEC3E0B0E7AC01F1F839D2A2 +:10E930000FE92ED3D0FC20F44FF9477758D7A8A67B +:10E940006A01CEBF1D8BDC06E0B35D9A3CA2E1E616 +:10E9500078DBD381FCDE7F8B83EDC352D887C1C7C0 +:10E96000987DE62678DBCF91F28DE03ED891D27E7D +:10E97000FE42F16AB8438557ED8D9B12F8FD497D43 +:10E980007FF43C84FE83037B4CC88F4A76B3FBA2A2 +:10E9900025FBCFE3B9BB64AF0991326FAF85DD7B57 +:10E9A000A861E557B263C70178E1978F817CA87EA3 +:10E9B000C4A395BB0166AFF436BB7A8951BF6AD256 +:10E9C00004768F60158F4752FCAB0E8E6749DD7C55 +:10E9D0005E902B49F904EF13386C2CAEB0F57D0135 +:10E9E00046B729BC9DCBE51600DEFAFB0329F09E55 +:10E9F00034F38F23BE8806AB07E47E5281AE9EAD12 +:10EA000000FDAF29BAFB06F31DDCFF6A2469C0478D +:10EA1000AA2DB1EF097DE650F43A2B9EEB243EAFD0 +:10EA2000C376237BE7C56EC6752F49244985989721 +:10EA3000509EEBFB69C12BAF41730F25A9C0AA798A +:10EA40006721C5D74193EF38A3B3A67E277F0F4D2B +:10EA50007997A27E9AF26E65999A7CF7E57768EAD3 +:10EA600067508453E77BAE1DA7A9DFBB728A267F60 +:10EA7000EBC6FB35F5FB06676BCA6FDB51AC291F94 +:10EA800050BD4493BFBDF6314D7D318E9EBD87C3D1 +:10EA90005954F46CFB103FDE3BB29B0593EA3CF704 +:10EAA0002CAF97ED284803FFF76AFB9834386F1EA8 +:10EAB0004E1CE60CC7E85749BFED396CB743D0D8B8 +:10EAC0005773B8FDECCA41CA45E0F7591CA27880DB +:10EAD000BFBFC9BFDBC1F5A9596EA8CFDFB5903C58 +:10EAE000B88EE90E33DAC5F4FD3FEB706BEC758A36 +:10EAF0005E2F1A3CAE42213EBC3E6B27BCF67E47E1 +:10EB0000F03AA18B1752CE6FFA76571DCC7E4AF998 +:10EB1000ED07C00F5BCE69A449F4E139EDB32B01D9 +:10EB200002FC94A0DE124F0F50C61704DF5FA11F36 +:10EB30003D3FF52D9FC7CE99062FDED78A777EBB46 +:10EB4000CAD71F3DBFE5CFC0FD48346AE0F4B71611 +:10EB50003AF76ACE6FAB1387E1F96DB5EC4D6BCF29 +:10EB6000F9ED6FC0938602DCD9BEB6ECA7D1E3669F +:10EB7000F73CB5FA4B6B7D9BCA3FBACE0DA0C709D7 +:10EB8000A0972531FD7B377B0F4019B71DFAB6E4FE +:10EB90006C87BE6D229EB59288FB657532FD7AA9A1 +:10EBA00045FC56FA7592F31BC8BFF7640FC6FFBF4A +:10EBB000374124F02ECBB582E1788F3A1E3E7EC0DD +:10EBC000ED2FEF39197CDBB25FBCB7A2E8A6F72FB7 +:10EBD000DE1BCBE22CA7E8DEDF1DE164783095A7D1 +:10EBE00014406887B8FCBA1DE3E52F8FFB107F6FD8 +:10EBF000D2E59AC14302F87BC23CCB20DE2660B34B +:10EC0000A37D6FCAD8A143CAED2A3CE2BF8F2CF77F +:10EC10008D771C60BF99B2AB674AC0161F7FA6F202 +:10EC2000F511297C0BC653BF79117F5FCD943DBD93 +:10EC300053987D511B9FA6B7FB4C595E82F8A6E402 +:10EC4000174708C6A3B5E42576DF787144C2F8B546 +:10EC50006ECE96F8F6F49BBD9BD65E78EABF2BF09D +:10EC60007C6FEC45766FDE125BDF58E1143476245E +:10EC7000FDBD9578F731E6F1FEAF158CC0FBF7537B +:10EC80008CEEDEEDB1532970AABF713E01F8C27E51 +:10EC9000B80F13A3FF879C8C9FEDF77E920466E963 +:10ECA0006C73532EE07F36B783C788D75F0A7434FE +:10ECB0003A52F09DC4EB3FE1D4C6EB1738195FD14F +:10ECC000C7EBB775DF68B231B67C9BC1E14EE1F7A7 +:10ECD00021D0EBD2CD32C6FBCDA7730880FD6D8B62 +:10ECE0008CF6B7F76F9808F841CE6F927F09F169FB +:10ECF000459B7B6E7E96E68BC69AD06F337F0B7BEF +:10ED000087848CB504C12F5BB4E5D1547857FC538C +:10ED10004AB78BA8D2347FF373180FF3FED9A7310B +:10ED2000FEFA22D033FD5EF4D593D301FE7B8C95A1 +:10ED3000B70DA2E9A29D82E6FE447195459357E284 +:10ED4000FE94FD2342F45E859BCA91979CDAFB53A7 +:10ED500083A3FEAE979CE8EF0A639C7CC904767F90 +:10ED6000EAD039767E3FD28BC50586C6DE5B388811 +:10ED7000AE636C0A7BBF451F4748C03906EFABF056 +:10ED800038DFB11F4B2DF75C58B9D796AFBA3FF0BB +:10ED9000D68A32DC97B13F637693B1192CEE3D6E83 +:10EDA0007C615AAB7B007D406EB68A2B8CDEEF39DE +:10EDB0001D0B6F0EE9E8FAD039164738EF187B3F84 +:10EDC000AB2DBEF9019FF7FB67FB3DF06B0A8FF798 +:10EDD0000B18177FFFC6DD6BF07D1A9F40209EF356 +:10EDE000FC8DD8F7C8529C8ADEE46FB96F03FB3301 +:10EDF000B560414B1EC8F21EDF239AFB38EDE737A2 +:10EE000037E7274F3AD93D4A3D7FD7E3FDFF29FE3B +:10EE10003E65EC9174B89F4FD397F09EFE2EC61FAF +:10EE2000F574AEE7E733747C30CAC70D9A78E319FE +:10EE3000C00786AAF9B911F9FCFF00D1E7EDCB00B4 +:10EE4000800000001F8B080000000000000BDD7D2B +:10EE5000797C54D5F5F87DF3DE2C496692C96412AD +:10EE6000B2336189A088C3BE457D098B51080EB8B5 +:10EE7000A1824E02216C21816A456BBF1948C08076 +:10EE800060635D8A8A76A041D1A20D8835D6A01331 +:10EE9000A5086A357EC5AFD62A0D82088812412D95 +:10EEA0006DA5FCCE39F7DECCBCC984A5B5FFFCE26C +:10EEB000A7BDDC77F7B39F73970914319DB9190B80 +:10EEC0000CD782B50A631BED7EB33395B1A1F66012 +:10EED0004A2163ACCEB921C13F80B1941476ABCF47 +:10EEE000CED869FCBB3C9C76D88BE2B0FEAFE2FC8E +:10EEF00076E730A8F75666114B646CC8DB4D8A1F65 +:10EF0000EA1F53D8B4A618ED4EC5991883FA5BCD05 +:10EF1000BC7C2BD61B102ECF74169E8A837EB7D94D +:10EF200020857A8CD99C07FAC1BC988925A98C9533 +:10EF300028FE4C1CB7D2D67E5F29942EDCFDBD0581 +:10EF40008AD843167FBA3614D69369F16ECCEB3A61 +:10EF50006E1F271F376D4911DB3F8431AB8D05E2F2 +:10EF60000633A6682C601E8CE3F8979AA0BD368DF8 +:10EF7000B155008F3D3037ACCFFAA59B581A633F8F +:10EF8000B131FA0B14319C0C0B7C161FAC85714E01 +:10EF900031FD425CFFBF987E11CEEB13A60FC0BCC3 +:10EFA0001CB74EAC533331FF9618F028772A7C1CDF +:10EFB000E6CBF739205FC4FC91F090A9CFA951BDF1 +:10EFC000C2876FCC6D87F2CFF7DD94CB20DDF1D017 +:10EFD00088A4F618F565FA8B9A6AEF38687A6F8D0F +:10EFE0009FD224C6749CCF9A9A39DE717D187342E1 +:10EFF0001EE7556EF1E52747F433C499CC18AC27CA +:10F0000071D4D6B65E40270756AB4EC503293315DB +:10F0100063FBFDC1A4E26D03783BB7A11D9FA70A66 +:10F02000E4C57AC3BAEDDA3FDA05EC4E335C2FA3C0 +:10F030007EBB5B67B9C09385796DD8DEF2D9553652 +:10F04000D60BFA537427E6253D8C8211901EEEC133 +:10F050004FA3605CC57FAB93DAE929B2FC741E8EC6 +:10F060005F4C79393ECB763196D13DBC98A2CFC268 +:10F070007E0E31BD1CD3664BE02227ACB7399ECD46 +:10F080008945CFF3117FB09EFE4E412FCCEE3C78E8 +:10F0900091180FE6F76482BE10FB3966F355637A68 +:10F0A000595647AD8A7413E714F5DB19E21DCA6F90 +:10F0B000C77296DECEAE06785F06935D05D9970FD0 +:10F0C0007DC63C00A7C48E03CC03E32722FE62C0AA +:10F0D0002D2199C3ED0F8C15C7E63B4E670131CF4B +:10F0E00046E017933BCC2F4F41BB2D0390EFFC82A2 +:10F0F000EFF4AB503E34FED2A5AC82F25EBAC784C8 +:10F10000F4E16E637A10E121E02EFBFFC469A17E79 +:10F11000910F9533F0E143E7C9878DBF9C648AC3A3 +:10F1200079DEC5BC7D3D58EE596683FC138B9DDEB0 +:10F130005590EFBD1A080DEAE72C89DFA042FDA02B +:10F14000E0A79E0FB26571503B6F5D8786F261D27A +:10F15000DD6D9A0DEAE7D5B56B289F5EBAEBD15C01 +:10F16000A4ABC39F5FA53AB0FF6F64FF0020E0F738 +:10F17000314E8E4336B2B427E2A709E79D1AC15734 +:10F18000F1FEDF22BF5F56DD31D60AD57297300D12 +:10F19000E5E561C5FFEB94DED86FFCB4E000442FD9 +:10F1A000A7B7970E1EE95F06F9ED92DF95A24C9680 +:10F1B000CE5841A399E059D0F8D02D08EF82C62B44 +:10F1C0003405AA3CA185140DD759AD6B01C8BFEB1E +:10F1D00034D3F8873F9FD753C1F9FED9CAFAC68006 +:10F1E000EF9BA2FF2681E7972DB1E97667A7DCE1C7 +:10F1F000FC34862952BEEE443A04F99AD81BE0B199 +:10F20000F0CEE3245F9F727A68FC27B4A69D993400 +:10F210002FE60DC0A7799BDE23792FC791F5E66F06 +:10F220005EBF02EB65DFE61CA47AB05D7B1CD2CF2B +:10F23000F7711C5FDFDF191F5CAA10FD0FF25D1C68 +:10F24000830F59C86A4A270CD878AADB4C2301AF30 +:10F250001D1D8528F7A0CB65C89757257B681DB273 +:10F26000DDFA0E673CF2CBD9F4C14181CF73A5C35F +:10F270003792B9DC0A74D59B47115EE7A1373B840E +:10F28000DE3CF16FE94DA12FA5FE94E54A32C7E7B8 +:10F290003DCE6EF5A6923CACABDE74B3E0BD03612F +:10F2A0003DECA8C9BB91751D3720E4DBD178DD9A10 +:10F2B0000C6981C27C386EE2D1CF98122187160B7F +:10F2C000BEDE2AE9C0C56E9D12631D95A23FD3F430 +:10F2D0000E4B3BF6D3A210FD775DAF85EA815CEC67 +:10F2E00081F3BEAC27C84DA5ABDC8C818F5CAC9F95 +:10F2F000F5B6FE3A12C9E8E4C60440FF99F0D10B16 +:10F30000EBFF2A4EEF8DEB93F01F7C5ABDD537A053 +:10F310002BFC2F1470BECCA1F7C7767F137CD61DB3 +:10F320005E4625737BE6AA648E97AD0E512FCE58AC +:10F330006F6632874B45B2912F23F0372A3986DD2D +:10F3400023E5F0D1785F0196FFE1D0D604A42389AC +:10F3500027297FA2F115E6B3A5341EC0793CB68FEC +:10F36000D63FB27DB41E0AB70FD0BCD7231D21BF34 +:10F37000211D79B89E583F203C3F49E77EB1CE1F02 +:10F38000E2F52908BFE8793A8F9A9433CD33B9C3AF +:10F39000AD20FF27EB4E4A5F3E6452705ECE0E4DAD +:10F3A000C17939857E8CD683202E045C793F6F0825 +:10F3B000B9B1E2AB99E988E71585FEF46AA83FD9AF +:10F3C000A1CF4238DCE3D4CB717EA50E7D36E64F6B +:10F3D000C571FE1F95ACCFC1EFC9C28E8A9E67B5BD +:10F3E000C01FC0B30AEB258E6301D487979FB40773 +:10F3F00041C4020860DEA01F12756711EAB1C4752E +:10F40000CC8B749A92D0D16A857CC743CCBB01F275 +:10F41000F9018FC98AFAED367D19A62BBE52C9EEC5 +:10F420005C51C882CBA81F6E87B2BA5E41D2DFC0E2 +:10F430006F91F4BA4CC079593297736087D42473B2 +:10F440007E5A9A1C6187483EEACEAE88E0C3FAF342 +:10F45000E4C35FE078E7C1870F083E7CF05CF8F01A +:10F46000B1301F3E8AF5CFC687CF083E7CE32C7CA7 +:10F47000B85BC0ED5D513F061F3E138B0FDD821E52 +:10F4800024BD231FA2BE0F2577CACFDFC5A2F77305 +:10F49000E0CBE6E473B00B3BFB3B47FAEFCEFE1B41 +:10F4A000E33AB3FDB7C7EEA4F5487E067E793399FB +:10F4B000F48EFE16C205F8E56DCE2FB1F9AB53DF21 +:10F4C000747039C1584302D28F9CE7E702AF00AF96 +:10F4D0000FB01FC967D24F91F0EBA40761F71E155B +:10F4E0006962C7670CE502C06D6F24BD3E25F82533 +:10F4F000309211BF8047558476E54B47C18E44ABAF +:10F50000CFC5E75BB0B6ED756475A635244C757450 +:10F510000FA72217B773BA83138C7F2C963C6D41CB +:10F52000BCD9BBDAF3D1F8FA44ACC7E952CE88AF04 +:10F53000B3CD43C20FE77109CDC3635A15A1E7CD1F +:10F540002E45F2B7E682F4F2711D2AA3798512C026 +:10F5500085EA94A72C1BDA0FEDDADE1E6E6F77C1F9 +:10F560003C2FD7A1FD80707B189FE45DEFDB409EB0 +:10F57000919DAC9B503FADC8E3F4104DF78D683FB3 +:10F580000C88C0574326E1EB3E9B3F13FB6FD43CF6 +:10F5900026B4EB1AEB9D4A80F0581D8FF463B7EB4D +:10F5A00044B731E490C7757E72A88F8BCBA1BEAEF5 +:10F5B000739043035C9D72E822ACEF3C8B1C1A23D2 +:10F5C000EA17B8B87CE94E0E5D26EA1509F8C69030 +:10F5D00043635C31ECB96D369DFA8DC1A79763FD2D +:10F5E0004CA7AEBBB85E2B7445E835683716F3F709 +:10F5F00089F6AB1B4CFDC87E66F1DE587E86CF6572 +:10F6000037D829970AFF81B5FCF3F7770D67AC0A65 +:10F610008BF83C7DAED4B03FD1D8F0591AE21FFE32 +:10F620000C7195079679DFED83787B476568873E97 +:10F63000F03FED168477737CE240764978DCAA7F50 +:10F640000041A6005EFE61A254E27161CBD2210CA2 +:10F65000FC88C2FD3FE4A25D796CDF3F283ED261A9 +:10F660002FF3E3F83BB6F338C989B767A6A07D2E20 +:10F67000C75F8CF882798D5707348560BDC777598D +:10F68000BCA86F55E6F95501CCA76A979905494E74 +:10F69000311BD637F3E932F3AE156D6A22E6B58039 +:10F6A000886F28A7C99FF12421DD9A77A90CF990CA +:10F6B000B9797980D9969E067F3369A4897922E247 +:10F6C00021C97A3CF344C427528A5D867CAA2FD391 +:10F6D00050BFC7B45E86F20CFF8586F2AC39830D4D +:10F6E000F99CEAD186FA3DC1DF89CCE705AE32D478 +:10F6F000EF5D3FD590EFDB7093A1FE056BCB0CE582 +:10F70000FD83F30CE515BB9FB7A05F7DD1A6C58631 +:10F71000EF1737DD6568070069EB0374328B71F80A +:10F720005FD2BCCC507F56FBBC4948B78342AB8C00 +:10F73000ED1ACC07383C030CE1F905F35B90CE34AD +:10F74000D6B1330BE0BE30A87843506D6E735E6F58 +:10F75000E4872FDF2CDEA50C8479ADE5ED643F73E3 +:10F7600083C6FC7C7533F14F349EAB58AF24CF5029 +:10F77000A40395059530DEE76F32B66718EF827601 +:10F78000F3C57AA2E9E20B56FD7001D247406FEB58 +:10F7900093165EB799350D0FE17741274E412772D9 +:10F7A000FD72FE72DD4EF80FCB41E15B90CE663705 +:10F7B0002BEC51A5EBFAE6B4DCBF222BC63A190BB1 +:10F7C0005AD0DF8E9EFF0E97C37D3001FE91CB7223 +:10F7D000316EC5BAF0879DE4F1F1756AD00A74AD57 +:10F7E00006FA45F18771FDD1703C5F7EF10838580B +:10F7F000D38DFC12E7898FA6B7E121D615AE09FD9E +:10F800008C7C24E128E1EAF066C6A42B0FFCC7E15A +:10F81000ABB31F13BE1D08DF8BC2F03D66F39F40E4 +:10F82000397CE2A36F55A23B7FFB10D463DDE9A5D1 +:10F830006447D1DF44FD5CAC5F9500723109FAF991 +:10F84000EC877CE4B74EB9BCA4CC3B0EE4A2A2F892 +:10F85000594A6AF87B9BAE3A8602BEE637AB5ED465 +:10F86000C3C7347BBD72092DD3E34C43252DF1C6AC +:10F87000F128F1A6B4BCFE7705E0056DFC168CBF3F +:10F88000167B6D384FC6A6539C5301F7E67402E908 +:10F89000D9C414D2BF3AA3F8DF71E6AD85FE6A1D64 +:10F8A000BFBFE82CF110570AD90FFEB478B43F3A25 +:10F8B000DA4F3C87DD6B6D4E1C678ADF4FEB198199 +:10F8C0001304BB9A39014E11F12268978DE34E79EA +:10F8D000FC9709680FBF74E0B84AFAE51337D9C33B +:10F8E0004F315F7F940F5DEDEB00E93D69AF837FA2 +:10F8F000D43B85DBDB7D5322FDA34EBBFACCFD80E0 +:10F90000DDD10FED99EE52E53595F4698712EFDD03 +:10F9100010439F8E4C31EAF94BC3F1B8912911FA8B +:10F9200073E1ED2776E23C00DE63709E0E07D8356A +:10F93000CA39D93597633FBF4A4824BAEED8AD06D5 +:10F940002F8006C76D9E2417DA9142CF2A1AE8103D +:10F9500057843F6B730DD0866079FF2416C34F9197 +:10F960006911D64B09E75F8B33FAA32B06F3794D68 +:10F9700011EB5C29ECA7F2146EE754611C2E251CD8 +:10F9800087AB9AC6E3CC0F45C52FCB531C547FA53C +:10F99000BDA81CD7BF224F21BB6985A218F6915282 +:10F9A000530ACB71BDB78AFECBA16F1CF7A95E7C51 +:10F9B0005EEE28FF3D0FEB0FC394F70B9CD41FE9BD +:10F9C000CFA2AA31E1392F45C4B1E399B4BF896F01 +:10F9D000260ABE9920E4E5957D415E1273E993C63F +:10F9E00043F93851CED4757BAC503EF10233433AE3 +:10F9F0001B877209E5BCD3FC597BBFB09C9FD0AF7D +:10FA00007A078A872BD2E17B843C2966BE2CA483AB +:10FA10002B3DC6EF13F74C388CFC3A9169D40F7D1F +:10FA2000CFE3704D7085E97D594AA7BCF79C06BEAF +:10FA30000EC5FB1F28C1F8C39F54EF066AD53624B4 +:10FA4000D22FFB85C0DB6AE1A7E03E12FA1F2E91A0 +:10FA500046C3E717293CEEB0DBEEFB05C2F3214BB2 +:10FA6000DB4F70BE214B7B6D128EF301A37132E729 +:10FA7000E8AD981FE6F3308C13AFC863762FD2E75A +:10FA80002013C541DC7EE7380BE4DDEB14B4849928 +:10FA9000596301C7E0B05C684EC913F3AA6D4D828B +:10FAA000FA49EBBE61BDC87F708E73A21C9AC56215 +:10FAB000C6359F167431E5F15E1AFA614936450F75 +:10FAC000C658C7D302CF201736E13A2EB7ED1BA296 +:10FAD000907EE07E07BAB2F47F074CC18D4AD7F61C +:10FAE00076FBD8E7900E251D5FAAB2EA2D764E5F11 +:10FAF0005322E458B3A4A7738C470F9BC362C64D2F +:10FB0000DF17782AB7F95EC1F90EDBE3A1FD8E0A93 +:10FB100029EF679998067478A320C31BD7B5FE9D7B +:10FB2000EC8B1F4E9F56A5DDCEA87F86FB0F150BD5 +:10FB30001C41DC8FA868C90B50BC698E42FB245560 +:10FB40002DEFF9305F3174A893E46482A21CEC4776 +:10FB5000263FE37251630725FDA90248D0FF34A177 +:10FB600067409FAC4E807555AC5BDF9A01457F01C5 +:10FB7000C301F1FF9089FB7FD1EB4A8BE7F059314C +:10FB800005FCE04128764FACDC918D78AEBE50F19B +:10FB900082B1B2F4F8EE5D978AB85826961FDFADB1 +:10FBA0004B3F3293A61162309FA7E23BF3BA2D9DE3 +:10FBB000E481CC0730DF88CC361AECB5078EEFAE87 +:10FBC0001B40F44B7A8969200F2E0EF3FB47AAFFE6 +:10FBD000A39FC1BAAF0365BC6430A61A9B4E784A96 +:10FBE000A7755E2BD619F807530EDAC270B9AE6549 +:10FBF00037C1FB23338C07CC632EE2A031DF954461 +:10FC0000FBC9603FD03AAFB7358C47BD7ECCD2310F +:10FC1000D08BF184ED1FE60460FC4F7F7EC2C18073 +:10FC2000EEFEAA7538F0FBA1BBDF77E880DF4FEF6F +:10FC3000568B917E6F117A52C22DCECDE9E166B717 +:10FC40008FB9511ED69C1AEE8F8C0B2D4925FD368F +:10FC50003708338CB097E66F4A400BAE335FD994C8 +:10FC600062C84BBD576965D5B1E2A097BA39BEE607 +:10FC70006E5E6FC9F2E0F87E178E7F08F40BD2CD6E +:10FC8000A16D8E20FAEF723E659B0759D09EFA6BEC +:10FC90008B9585D03FD3DACCCCCEE5A602F4EA171B +:10FCA00074193DCF9DAF24507FE50F71395B0A6316 +:10FCB0002D01B8FA5BE6923C8D5E47F9A79E093D9F +:10FCC00000DEE52BC172F1F0FA7703DEFC4BEEF9B2 +:10FCD00006EDD3E87596068CF27566BD312FE57E8C +:10FCE00085C037889B7AB4F3CB1B8CF52A5AEEA5D6 +:10FCF000FE2B502ECBEFB0FE216E61170E67235006 +:10FD00000ED7DA7B25F9CFA0678FD680419ECFD85A +:10FD1000911A1BA5876A18A5CCED217C2C6879EF78 +:10FD2000A748370B9BB758B09FBAE078279033B3FA +:10FD3000B600C7A33D8DFBE3D07406EE8FC33C6BCA +:10FD4000712219B87FEE1BEF067C999D51FBE5628D +:10FD50007DD305FC99DD45F4351DD73310BF6BDF2E +:10FD600046AEE7F8AE21361C77B25CD70858977AD2 +:10FD7000EEEB92EB91EB93E595203763C90549DFF4 +:10FD8000CCCDF5CDACC6292B320114B5DBBFA038E4 +:10FD900000137E8826F0A3D957911FA231F033F8C3 +:10FDA0003AB91F12607B58049D45D35105C2019991 +:10FDB000D8C9DBD9847FD2493F2D6B081E12CFD022 +:10FDC000613ADFB70CA5E3BE25D0D181283A32E4F1 +:10FDD000CB1B8CF9AFCDEDB9C8DF402F0722E1FB7B +:10FDE00075D4791999CE70F7E2EBF7E8139C505E61 +:10FDF000CE7C2B9CB4FE06E2C3435AC3CE9F21DFC8 +:10FE00003572BAFFABC0FBC76E5F2DE29D69FA4049 +:10FE1000946F45CB325437D42B5DAD38919F66D665 +:10FE20000D9A807C3898E9D4DF8C6EECCB8D02FE85 +:10FE300065D5666601E3A0CCC348AE956D53833C9F +:10FE40004EA7DB4B00BE73041E2A576EB164403AC6 +:10FE5000A7BA82DB3D41CE2F0057B27BE6AD6EA53F +:10FE60003802F85131F94DEAA9CA266379155B4D7C +:10FE700078A88AB27F82921EBDCC8BF4E8FFA9C31A +:10FE8000A6249D7DBDAC6B9C88E248C777F5257B99 +:10FE9000F8B8C7D303EBF901E76D68E76BFE11F81B +:10FEA0001DE044FAB263694210EDFD7D27C18F4524 +:10FEB0001BD4E91F6101B8B47F9C437A5CD2A75C74 +:10FEC0004F956D35D1671533FAC9A5E09061FCB740 +:10FED00074634A10CF0340FF039BD18EDA68263B40 +:10FEE00029C016A733A033DF7233C9C3B2E664F268 +:10FEF000D3CBEAF8BE51D9E6E4A0CAE30F7B30EEDB +:10FF000022F1B0AF6EAC2583F094E745FDCB9ACDDE +:10FF100006FA96F889F673E7D5B7EE4CF7741F0723 +:10FF200089C0CF816EF07320123F7BA2F0C3EE4EEA +:10FF3000E17266D11FFBE23ED9F1EA38AF1AC36F16 +:10FF4000927A886503010E0FC7138B33393E98E60A +:10FF50004D437C9E583D8CF0158DA7E27FCD247CCF +:10FF6000B08F1D0CE3CC337AB35BA7C2F75B15CE21 +:10FF70001F336AAF2C467DFD959033EF827CD22DE6 +:10FF80008CBD07F24907F9F43EC82DCC7F50934E43 +:10FF9000F90F6B3C94FEB9A61FA50784DD27F9066F +:10FFA00008C08276E309C12F27A4FC62B7A5A3E9A4 +:10FFB00050FCAFF7879930741BB8EBAAF160CF5CA7 +:10FFC000AD1BF5DDB46B8DFAACDDEC9C908E76EE5E +:10FFD0004A85F653CA7C630CF599E6B14C417FBD66 +:10FFE000DF90F077B25F3D96A9C0EF374E4A31D42B +:10FFF000BFBE3ECB904F48F5D0FCA614F7367CBF71 +:020000021000EC +:1000000069FA45867CE94900C210A46617E1E13629 +:100010001B13F104178FF38AF334DF568FE871074F +:10002000CCF7DBB7CD541E8D0F89D7596B4DCC0F54 +:10003000539BB916D606FD1E68003C41BB2F3F728C +:1000400030A4E3159B87BC3312F2FB369B295EBBC1 +:10005000AF2EE53EB48FF66D4E4DC438B07F852A85 +:10006000EC08A78545C8ABB1754BE99C4D69D0EA52 +:10007000257B6147E00999F728C8F78CF3CB1E353B +:10008000887139C01F8F673C63A57D884360B7398D +:10009000412F1C52581DA6A85892A0FCBBB6D420D4 +:1000A000F273F1BF543D1DE9E99938B1CFA4507FF7 +:1000B00047DEEBBB6115D197A729447C6B25FF6711 +:1000C000663B5F1F53066721FE0F25333D192651FE +:1000D000B9F8C3BD1AE0696E7EDBC010B49B9E17F1 +:1000E0004ABD01DA1D6D34D3B91BECD709F9CADF5B +:1000F0005AD77339A2F7407F220CCFE0405CF70C4F +:1001000093EFF254C0DF91D9C18124CFEE4E25BECA +:100110008A86FB018B9FE01B403E50C2F231CC67C8 +:100120007CFF10845A06CA9999666F1AEAA703AB36 +:10013000CD647782FE48C4F119DB4A747C40F34CED +:10014000C0751FA8CF6328AFE4B865AB55F2B39074 +:10015000FEA8FEFDAA1F6C0426F554A05EF1B31E96 +:100160005DE9E6278B46F4C0F544DBB732FD1A782B +:10017000D51F612FCCDBAEFAD03F6243DBB56B2FCE +:100180008E5C471DDFB748E7FDDF26E4FA825E6F2D +:10019000ECB59B50AEF74E42BFE7F01E95E8EC7011 +:1001A000AF86E1E9BDF178CC6BC3EF80FC97258188 +:1001B000831AE49FB0FA17205CE79B563FA140BB2F +:1001C000632DFBEF1B03ED8E3C6BF6E2B0F39E99C3 +:1001D000DB93F619847DDD556EE9D23E4853D2D1CA +:1001E0008E7092DEF6D4C120B4FE20CDF366D6B474 +:1001F0001CF1E65CC0BFEF1FE65885719A99C01EDE +:100200009176F77E33B70BFE2795FBB552BFB7A4A7 +:1002100072F932D3C4E99ABDA2909F8AF64E9F0824 +:100220007D2CE5F29A546E4774EA65D644F26A363C +:100230009EDB81F52DD8640D06F3A88D13F97C2E75 +:10024000470FDB8D7202C69D6779F661E4A10AD67D +:1002500046FAF3883938BB2D0FDBAFAF73517BB350 +:1002600097E2C5429FD88081501E5508BEAB6C50A6 +:100270008221E21BAE17CB45FF0CF54C84FCEAAAA9 +:10028000578CFAA45CE8D17216156F6E30EA375FAE +:100290000277E2E7C1B8A82FC3F302FB186036DB90 +:1002A0001FDC3999E6AD788331E651C13A422ACE56 +:1002B0007B33DF77889E57F43ACE759EB3BD53C625 +:1002C000250F8D18376ADE12DE14B08EC08384FBD2 +:1002D000EC0087E7EC1685F0F5B9B0CBE4BE8BC433 +:1002E0007B05F34DC6F384150F82BCCC0BD341A71D +:1002F000DEDF12A4FD952F5943A21DE87EC1DA2D41 +:10030000D78FC276EBDE23FF62BA2BD4D794CC58BA +:100310004AE0F355C53931F655A2EC831F0B3E3840 +:100320007B6DB86807F0286F54F5B881867AD45E83 +:10033000DA077302010BC661E788F8E6D9E659854A +:10034000F5069FCB7C63DB33FFE9BCBF4F15F1B9EA +:100350002EF650DF987E54A71D7416FDFB89399444 +:1003600083FAB7234723FDF3ADE6FDB0D08DFAB88D +:100370002FF905DDC9D7D9420F97A35E86F4E0DADD +:10038000E713D16FFFFCC1E7693FD7F26C7922DA3E +:10039000C507D7CEBC2F002C7570F34CD2C3158F78 +:1003A0004A3DECB744EAF7B16B4B7FFD73A4CF4DE8 +:1003B00071B41F317B875FD8DDE0B7A01C5CAB3028 +:1003C000D20B0F72B95781FA6A00E9AB0BB0DE4F5E +:1003D00067FB2F403A8FF84E7AECA733FD23A83DF8 +:1003E0007386D0EF02C919427D25F5A9D4B39AC905 +:1003F000DF270DE1A5BEFDC19DB0FEAFB6AAE4DECC +:1004000055AAEB739DB8CFD18DDCFEF7E16DEA8480 +:1004100077DE39C0BB0CE14DF60F87F767F51CCED0 +:10042000FB5773B8AFD8DC3B11FDDBCFEA7B93DD24 +:10043000F3D9E6BE04EF59AB00DE64F77A8C764F51 +:100440003DC01BED7C84378C5BB6C323E0EDE5F04B +:10045000AE177A67354F6775816BE01694273FFDBD +:100460008DD58BFAFC505C2815FD91435B5486E7D3 +:100470002C3AED2261BF48387FC71A9E403BAA8BB9 +:100480003D73BF95617C76EE0B8E2083FC11A5B089 +:100490000722E068C31B89385E78FC4E3B665ADA57 +:1004A000B0083BE61CF1B390F9E81EC2C296373E95 +:1004B000423B5ED1B95FBFD0660F21DF82BF73348C +:1004C000529E2B1E94691827F1DA6C4807D9CCE3A9 +:1004D00023BB46EE77F919EE777DDFF79B5B1613AA +:1004E0003F77E447C6C9ABE243668C2F756C510871 +:1004F000DF95B715261632DC4FABA679DC9EC6F524 +:10050000B1A2EB1437B402DDC4C3784BD23C24CF84 +:10051000158F93C711D7C1B88EF07CA3BF4F46D2B9 +:10052000437D6E8F1D77DE98C6ED804AD5447EC729 +:10053000020BF73FE47996E5621ECBD3B81F726FCA +:100540001A3FCF770CCF8340BFC72EB58AF3D9E3CC +:10055000289ED9193F9170736A5F77CA2BE42BAD3F +:10056000231BE1B477F47B66946B7BB12D19D380A8 +:1005700080E168C7F0F6EF98EDF56857DE3CF20DC4 +:100580008A83EE8DF379D0DEDA9B6AF3221D05B6FD +:100590005B89FEEE89E7F16FE64ED2909F6E12F214 +:1005A00076468155C720EFCD05F7F830857102B842 +:1005B00009B1A2F0F5E54847B7A6EFBFDD064B5AF3 +:1005C0006AE2F6CA5217A373409780B98E71583CFD +:1005D00022733AE54C74638C5B2FC0F8EC68C60953 +:1005E0006A24C1D39007B852FEE587AF9BF8603606 +:1005F00063FFCB3C17239E17204C900E4A93C8FFF5 +:10060000BF1AE3C42E4C35A2AFA91A0B98785A8FA3 +:10061000213519379E2CD679DD48164A82F5857624 +:1006200033435CFD8690297401C0ED6A2DD48AF0B5 +:1006300033D93C66F4037CC5CA60F48F172C3BB7F2 +:10064000F9BEF3B07FE283059037F1C38B1D772AA3 +:10065000C10D00A79B81B9912E6FD1D80E7530C7FF +:100660001BD25D95CB13A07A8B14B13FC4E3F91272 +:100670002F83A0FB48F8DE2CE607FDD427627B4BD6 +:10068000ECB8D1C769D2FFE576E67CC1A7F3259D1A +:100690006D36F2E73F249FA03D0B70BB59A4DDD11E +:1006A000F9DF44FF7F1374FEF9798E576965215A8B +:1006B000F7762BE1518E7BB548BF4BE3F6B29C87B2 +:1006C000A45F26E24F2690184847071A6AC95E9A27 +:1006D0001315FF6591712A3556BE53EE984E636A25 +:1006E000E99885F3512E8B237EB9D9D2D4B7DADEBF +:1006F000B51ED8D184A24ABB8DECBF85AC9DC7B3D3 +:1007000084DD2FEDC5B968E761BCB291DBB59AB065 +:10071000C74BC13F43A22BAD8FB077E17F939BB70F +:100720008CC7783E18267EDAB7B0DBE8DCC6E40575 +:10073000463BC92CEC2273945DC4A2CF85083B29AB +:10074000FA5C882AF817EA727F459C0BD184FDDB9E +:100750004947696681CF80611F7E3A6B33F3FB6244 +:10076000227E27F4F378D5DE0FE5CD7425DE8BF6F7 +:10077000FEB14247C09484F125338D371DF800E562 +:10078000C82771FC7CC58CA49F4E463B787AA24555 +:10079000C3F45367AFA41B18CA1B55EC1B0527E213 +:1007A0003E532DCA4D9EBF57CFA62898C86F7C0BCD +:1007B000F767AEFD01E64BF92727EAE0BF1DFBA373 +:1007C000280F401EE975B9E4DBDFF2FC43B2FC7789 +:1007D0003CBF52966FA3F18EAD91FD8BFCFD51E5B0 +:1007E0004BA3CA1FE1F9F13DB64D0C207CC4BED32A +:1007F000F4D10AED3BCD41BE02F84D5F16227A9A44 +:100800006E7A8DA7452C84FB8E67ABB7A8876F0ED9 +:10081000EA67D571C081F6C99D19FA1CB4AFAE4D17 +:10082000F5FB7AA05F3845095870FF714F305FE8DB +:10083000AF98E7E7E7083E5D98EEA3F6D2DE857E47 +:100840006EFC77FA39D5A34B3F653D52CFBF9FDD94 +:10085000E97C7D11FDCCFF77FA1998619C8FB4FF7C +:10086000DEC8D457E0FAD801B7E15CE4FCFFF1261A +:10087000A1FDC8F05C24807EFEB2A6DC21D0FFFC86 +:10088000E75ECA9D1D115F5878D2C474B013AB4E99 +:10089000324ABF6CFDB3C503F359B8ADD53201EA96 +:1008A00055413A36625E0BE4B960D6AE4D8DB05F0D +:1008B000EEED6112FC743FBFC7F5DC61DA3F9E6F5D +:1008C0006A3AF828F2E3681E678C5EDF4F7AF0FD23 +:1008D000BEBD783E20867F727F0F6E8F6CCFD61B99 +:1008E000709D8B5146423AB636F6F98A8F457FD3D2 +:1008F000E3B93C9F39DC61F35C82FBD9FE5ABCAFA3 +:10090000377B5DDE608C57DF915AF4688F33C67F8A +:100910003B78FCB785C77FA7BBDA6E0365C53EF899 +:10092000D5FBF7DAC05F9DF82BD6B91F8C71D56265 +:10093000ABE4BB2313C715503C8FF2CD3D0EDC1B3F +:1009400080F6BBE2F9F99119232E8E4779D09E9754 +:100950006072829C08B84B3FC079CC1871E904FCE6 +:100960005E6875E497F2FD03A28B80DBD784EBC64B +:10097000FA18BFF15B783CCFFFA64AF13CFFC004F8 +:100980007FACF307CF09387CD083DB67BB00CD6831 +:1009900057C979C8F1C120BBAD0DFA3BB02C63102B +:1009A000DE8BFCD85DB887E022C6FFD8ED6F8D1CCA +:1009B0001F963B10BF9FEB3C5E1174B147E0CD57D3 +:1009C000A0323D42DE4F1D9760C85F3B2985E9910B +:1009D00071E56BB30CF969D37B1BEADF34EB22437F +:1009E0007989B56D68F579D8F9550E473C9E6FF851 +:1009F000B4E5BBFFBB19EDD746D5ABC07AE66EDFD9 +:100A0000F87F63A0D6713C364CF6A887E27B47F0AE +:100A1000BC21F29EA66B91FB525FB1363AA719B189 +:100A2000EF61D85F9AEFDC41E7447FAC7DA9133DCD +:100A3000C4BEC7603C628E7AE8835C3C5FB2D0CEB5 +:100A4000D7F3D54BFB2C74BF03F507D0F715D8505F +:100A5000453E0F50BC7D6CF33EBA47F7500F2E97C2 +:100A600017662FD2C002655590A2DC9F00F22909BB +:100A7000E8A3AD955DBC0DCF57E739E83C4CE5C91F +:100A8000A98CA5201D05062C827AF3EB8B29BFF0DB +:100A9000643CF5FBAEDA3681CED1BFA8D0BE484962 +:100AA000D68C65682760FD9FC07825BFBBA218E182 +:100AB000B3701B3F3753A2FEEF50EC67414331B593 +:100AC0002F51D92E05ECA18963B97E2D415B06F229 +:100AD000EA70C72AD4ABAA2594FF18CA138B83E403 +:100AE00049D2C99B68FCAA93366A9F95CEED3473B0 +:100AF0003B9FD7F8933EFA2EF19E97DECB70EFD353 +:100B00009CDAA895D9B13EA3FA579DBC9052B9CEB4 +:100B100037FBFDC68D72CC9CFAED043C27FCA65B2E +:100B200071927915256F4F548F486231E4914CAD25 +:100B300042CEDE7C929F43EF95A98F4887794EBEC7 +:100B4000BB5DC37D2A66B739115E93470EF2CC8E2A +:100B5000E023F5B51BD1336056778719F5F9CD90B1 +:100B600046CAE35BBB91C797A69B0CF776A47E6150 +:100B7000C11BC9FEBE45DE53167C72A1A82FDBB790 +:100B800091ED04787CC14A76D4984CBF2F1DCADB06 +:100B90000AD9B4AD241FDB72717FE8C79A3FE0D950 +:100BA000A6903FD34EF730268FF498D03EBC2EDD72 +:100BB00064B0D3CEB68E2251FF5D952D417DF2EE0D +:100BC000E597B7E9D05FEBCF860C41B92FC79D9D64 +:100BD000CEEF9D3367C70FE8B756BD92E041BE2EFA +:100BE000C1BDD6A161BB1DBE338C7356BD62DD8015 +:100BF000E799AA12C16F87F1C7BE1A17423A6E7DF4 +:100C0000354E43FDF075B67F36E273ECAB178CC3FF +:100C100073747A8B556364DFE81508B7EEE67B36AC +:100C2000F9144D67922FFDF59C5F4A059D9609FECC +:100C3000F30B3E3A51DD83F8F0C4DD30695847D9F3 +:100C4000DDCAC5DBD01EF038E81C96E4CB12F4F305 +:100C5000E07BC945C9E4EF46F01DF1E182934EEA1D +:100C6000AFF2A447F0B98BF292DFCA04BF48FAF69C +:100C7000093BE26799FE87111E25B5C0EF787F73A7 +:100C800059C650E4A330BD589C4857402FE9B323C0 +:100C9000E8A1B615E8C541F44272C8076924BD5CF5 +:100CA0002DEF1531E7843498F7E4BA3CC3BDA2C7F1 +:100CB000CE93EEEB05BD94D9437DD15E3557C77910 +:100CC000F19EE47137DF875ABC92C36FB1D93716F2 +:100CD000ED87C58F285EC00CD915288F867F546D8F +:100CE000898CABDE787220F3C0FAAF39D987D23B5A +:100CF00052FD4F231C4A4F5E2FE035F0DFDAEF1C28 +:100D0000A6F3389A3968F5AEC7FDC438BF8AF83DF6 +:100D100094C39C0F44C4D130EE87F13FB90F2AE34E +:100D20006A56DC378ED093DF690DB9E8E77489AF76 +:100D3000151AF70B17B4FEEF7013941FC9D329CE01 +:100D400036C3E47F1DE979DED4E07366C8CF5FF374 +:100D50007C22C6F5253C9BB4505FD4934D00478C54 +:100D6000F735AD568B83DC9E49E0FB7C9CAE251DA0 +:100D700047D3F7BC93BD889E4E545B49EF9C007AE5 +:100D800065117A275ADF483AAED498F05B93E8DCD5 +:100D90008894FF617DB3FEBED148774735A2FFB08E +:100DA000BE99EA2BE4F44FE7CEA3E9FFC59A743A63 +:100DB0004F24F548B4BE8996EB525F7D92E1FF1E49 +:100DC000E154F4DB7F3EFF317CBA4AE37AEB2ACD73 +:100DD00041F4F3DF92FBFF3C4FFA3F2CEA83FD4ADC +:100DE0007621CAF5C8FEC66416256640794A06D73C +:100DF000ABFF6D799F92717EF29E65F0F99F4DDE9B +:100E0000E76770791F2DDFF1A222CAF763DBFBD3FE +:100E10003EFC5E06FA00F55E4B8267A390FFA41FBE +:100E2000E293826792FFDBB367E667C496FF1764BD +:100E3000FC07F2FF7CF944D26F77FC32F15E6E9FC3 +:100E400031B4CF9448FB8CC365D7855C0F44D86917 +:100E50003C9E027CD55789E49B0DF78D46BE39E652 +:100E6000F6E25940C927926F24BFDC2CF8E356A163 +:100E700017247FBC9AE1BF11E125F963C1D668FD53 +:100E80007066FABAD95DCD503FDC0A69247D593BC2 +:100E9000F583912F6EE9A4AB73E38B4919E766479D +:100EA0002CCAE0F7DCFF8B74B508E927065D2DFE40 +:100EB0004FE8AAABFDFAE150BCAF766228D0515E94 +:100EC000988E26BEC5B8DDD09BDBFF9D7462C9A19C +:100ED000B8CEC4D3FC1CAFA45389DF68B9F85CA6B4 +:100EE000EF61C4B7F41BFE5BF2EFB1F3C4F3CA7356 +:100EF000C4F36681E71FD15E7C31165E99D36588A5 +:100F000047007F5F43765C48A32341DDE1D5BC9673 +:100F1000F397CC2F0F6952EFA6A0DE057A69FE4F3A +:100F2000E8A5642C13F18D4393304E39F11722CF8D +:100F30008E4E423EBC7EA42C3FBC5AEF837286C9C3 +:100F4000FD038A8FBCAB8A7CE0C8DBE3605E131FC5 +:100F500060E1FD05281F5F90D4194F41D743D6FFAC +:100F6000F0912FDE5E4DFCCCCFF9307FBBC6F7D5BC +:100F7000447E28E41D11F99151F975BC7EA2D6CEAC +:100F8000F8B9CC20D7032A6E3572FAF145D82580FE +:100F9000C909787E62F236C589F1909B0A8ED1FE2E +:100FA0007378FDC727E905B82FA888FCF76FE37AA7 +:100FB0006FDAC6F3A71EF9C7EA8026FA4BA37819A1 +:100FC000FD599B145DC5F320239560AFBCAE703E08 +:100FD00015A5F7F04F33B66778CEEA7CDA239EA9E1 +:100FE0007D2F6A1FB29EC7F83714C4BE27E2C8140B +:100FF000F5445C81FA07585ED314FB1E4CAAA8DFA7 +:1010000086FB4504AFA43508BF368B8467E21AA47B +:10101000A7F18CE77B3E9A581218C0A7AF47ADFFE7 +:101020004CF35732BBAEDF636C1F3A13FCAC5DDA96 +:101030000BFA9963A4A724CDB7E304CC23C9AD3838 +:10104000D13E5EE88B5B8D7E40983E324A703D6DAE +:101050009D71FD68FACF2C41FA5FC864FDEC35E460 +:10106000E7983AEB737E90F405EDFBF1F7F7A8FDF6 +:10107000A847B3D6207C003F544E79ED0CFCD01429 +:10108000952F88E21F41FFC4BF28E7013E7D63C85A +:101090009969023E5F8973E46D45DC5E6C13F7E28B +:1010A0009664F238AD3F93DB637324DE23EECDB05C +:1010B000083C3371AF2662DD04A71BDD72DD052518 +:1010C00093605D6D2E5EBE3873E49A4076381FDD06 +:1010D000DF6D990525B83F11EE7FF49F506FDC2836 +:1010E000E0B62473CC9F025C1E2AC89795442080EA +:1010F000F76D4A80CE61215DC458B7DE95AE0251CE +:10110000ED75F319DA4FE8DA5E8F6ACFCCEEF3694A +:101110002FF036290AAFC551781D17959F2EF34140 +:1011200083FC9372B1ACF9FEE5696E8C4F2A74A70B +:10113000374CCF57113DCF774AFA9DF827A4D730C7 +:101140003D4F22384F6D92F2B0640DCAC329280F6B +:101150004787F3D7A0BCA0FCE4123D29525F5CBDD9 +:1011600046073CDF502FEBFBA8FE4D75B2BF29545C +:101170002EF1C802534B70FC1B870A7D11B8E64F55 +:10118000583EAF85B7FFEDA3D7FE29D0E70CFCD0C2 +:101190001005977551F94054FD07CFA25FEAA2DA16 +:1011A000DF1D55BE3A2ABF362A5F6F6C5F3A4B216E +:1011B0003E2C057A40449C8D2F5FCEECF47F3AF5AF +:1011C000A96227BBCDC057136B79FE8F8F9696D43B +:1011D0000F88C867CE2C89E40BB9BF0AB23680FAF3 +:1011E000CADC8DBC7CBE3BBAEC17AD6F79F95FF100 +:1011F0009F19B4CF63B00B5E578DF95655CE7BD196 +:101200009F6E1B10B91F5A5D8271966EF75DD8C232 +:101210009271917649A092E844AE53D69F70EAB499 +:101220008AE3FD25B3B2A411F7758AC47EA48BA707 +:10123000A0D754D49B55222E3301CF0363BDF85061 +:10124000DFC59176086BCAC775B6FE8CDF9308D4EC +:10125000027E30CEC6BC168CABB426252D7912EAA0 +:10126000BFFE337509EAD1BD4B52E81CD66559DC87 +:101270008E7C3DA9675A39E45B136EB5E0FDF3D669 +:101280007BC653FA9AAAAFE8005EFBFBA37797D818 +:10129000FB637912C1E7BBCC25254B81CE4FE225FC +:1012A0002568EF7739D3F01E075B6566FC3D24EFB8 +:1012B0001344376BAC83D08F2E5D7A11ED5F953D73 +:1012C000346502DDD3586EA67D0DF8A3FB3AFE55BA +:1012D000E3E99CD7AC3A9106AEA0F4D57FFDA636E3 +:1012E00011CF2D3CAED0FD904BBF6D7A0BDF5DAAC8 +:1012F000A8EFED45D4BC02763D9EBFFA6CED0574B7 +:101300002F647F5C359D7385FA0CEB57FCE07967A1 +:10131000F250ACAF3AF148C941F88EF6F0C195EA07 +:101320000605E795E888C7733C074F79DE41BB1691 +:10133000CA9DCBE0FBC1E573D3D0CE3AA878121595 +:10134000BCC7F0D8AA92F40C7C3FC12AF0B9CA51AC +:101350000A7C5D6AEAA417D21FB393793E356B55B8 +:10136000C94698FFC1472EA0736EBFCCD2D3B2003E +:101370004EB766EB3DB286E13CB99E7AF55F7CDF05 +:10138000F0E5A36569484F79599C8E5F39599656A7 +:101390001661EFCCFE4A23BCBF6AF1DC86F37C35D4 +:1013A0003E47A1F3E8AC2905E3DEB3849F09F4BB13 +:1013B000E4F91876CF0F992AF57BC0BA84ED8779C6 +:1013C000B7DE7BDD5807C0A5F54585F0308BF96B9E +:1013D00031CF9A63EF8BFE90563410E71FA6FF754E +:1013E0002467C9DF80FCC8AC47D604D00610E73BB1 +:1013F00019BE3E85FCBA392E1807F09CE5D6276049 +:101400007D96DE943FD511C1A7A2FEA7017E7EF98D +:1014100053A88FFEDEA781BF3822F72F64FD8A44D0 +:1014200047008D8F2F1C0E0DF1B657AB3988E71E84 +:10143000673F6E263D31FBF1D4BB3B701D405F7DA5 +:1014400059D775D46599895FBADF2F7DDAC8B7ECB3 +:10145000E933F2EDD4C7369534DABBE7DB0AE1D7DE +:101460004C78DC4CE7F82B863934DCB72C7AFC8FCF +:101470001BE9DEF1A2B8C1787FA3E2712BE1B7DDF1 +:10148000E10838715F35D1A125632AE8616916E763 +:10149000B3B12AD36C8329A57B1B723FF0F092076E +:1014A0001EC663A64758F0FA1100BFE3882880CB18 +:1014B00071796F2D6A7FB072F7F396427686FDC11F +:1014C000B3EC0BE20D78E4DB73DD1FBC232B7A7FDA +:1014D000D09C8FFB8F15627F70EC3A1ED7A958C243 +:1014E000DF65199BC2E3C4076A02F81832AE37E021 +:1014F000C47BD60F727D54C194A00DFE79C5BA4548 +:10150000F45EED1121874AF15DB501C85FDE5CF440 +:10151000EB673F1E4770AD7862EEFF3D02EDDA9754 +:1015200096B823FDE835821EA07F86F798653F5F59 +:101530002CFD792ECABFB1BF067F18EF4326B3E753 +:101540006ECC433C65E4E23EA6AC57B1EC67F9BC17 +:101550001EF8D3E03797AE54797CEA052BE9479023 +:1015600009E92CE23EFAACBADD16CB80F0FDB8CF2B +:10157000208F4F2C44DC93B320BCE4BD2DFC4B1FCB +:101580002EEC730FC91B7A6F7ABA49A1FB5D20E973 +:10159000E85ED4CB593C1EDA94C5EDDED25C2FDD7B +:1015A0000FAABCCFEA5DC6CF2BB1CE7BF1781ECCA3 +:1015B000D4369BF62D7F6FA5384A555D9C1E97C883 +:1015C000CF536C1D40E7C6350BEEB778B85C795940 +:1015D000D05F9567CA15482F50FE9186E7D51C5CF1 +:1015E0007E56268BF700A1BD09C63986FFEACDFBE2 +:1015F000CD181831BE22BE433F9EC470BFBB4CAC59 +:101600001EE33458BFFF408463CAF5D3707ECFAA6F +:10161000C4C7B0F8FB46A23DF8AC3A04FDE0D29551 +:10162000AF4F588BF92D83F046072B7DEE7DD22FDF +:10163000F305FEDBC5B9B932C8E33B057B041FF9EE +:10164000551E1FDA23E025E9409657AEE4E7A72AA6 +:10165000975BC9DEA95CFA21F55BE9684B43395D0C +:10166000F98299EE797F28E65DB634A7E023A0AB36 +:10167000327312BD2BBE205062C1FC820685F2E19E +:1016800076A9B948A75FD6BD9888F4B33F2ED41782 +:10169000F556C7A2382F9E5794F1B92FEBFA6EC0BA +:1016A00038CE2C679B03EF6BCDBAADB70BE5FC5E74 +:1016B00067C882E57B9BF24C98D79DCE02CCEBDAD3 +:1016C0002594FF529C57A13FA41785E379C1E6D723 +:1016D0002DBD60BC1FC47ABF7AF6FD7CD46B95B972 +:1016E0006DF9A87F800EF2B310CECF28A4B7176E85 +:1016F000E6E7F8251D2C443A00BE9B27E860E1B6DA +:1017000017EF407E5888F81FDC958E804E77D0F713 +:10171000ADEB2730DE7E07D289D47790AF33BB3074 +:101720005E27F2300EE64F213C8751F9385E1E18D5 +:10173000C0CF03B6D3F9C62A719FB3533E7583E772 +:10174000CC6CB17FB6D44AF236339BAFBB7DE50B90 +:101750008988C7AF9E7D7D27C6892BB78256F7C47F +:10176000E00B01972A844322AD83EC902A5C7762D8 +:10177000180E9DF42FF8B18AF175CA755769020EDB +:10178000B25CB4CFCAE6EB5CC004DCB65DC0F94F16 +:10179000F01BF233BDBB24D6E77719DF97D7C5FA24 +:1017A000FA8B7401D005DE5F63787D53CA0928FA8D +:1017B0006ACB7A8A13497CC9794FCDF6483DA22776 +:1017C000BBC2786C37C57E5F7B54369727FB96F794 +:1017D000C86D06B87D09FE189D37007AD522C693DC +:1017E0007423C71BFBDB2957E17AA1FF10F62FC733 +:1017F000DD1B48D0B09FBD8CF307D227CA4FC997D5 +:10180000636B675C3508CF4307BE72F4467B5BE0D1 +:101810006F6A367F0750473B01DAEBCD0AC5A9F75F +:1018200009FF7FDFF21713CB22E0E413F3967486EF +:101830007F18BF92F3DDE5E271DFE8794B3924E7E9 +:101840003DF69E1BAEC2EF72FE925E257D4A384A7F +:101850003A95F703A3E995684DEA4FD520EF493F44 +:101860005E91FD8DC56FEFFA3D3ADF6937D5A5EF83 +:1018700088BCF7B65F9C77EF48653CDECF806A2373 +:10188000F48ED4F3117A65B516A157AADC3ABDB728 +:101890003367E8A27CD4632F64F37329475893A578 +:1018A00010FA5B70A86D42A2276CAF5EFA6D48C556 +:1018B000F76E166CE3E7D724DC171CDD41F45F29D3 +:1018C000EE6F95AE7CBF6404D2F9D366DAE72C5D87 +:1018D0003E9EEE69CFDD387338D211DEFB40B97E13 +:1018E000B871D810FE5C9B33ED7ABCFFD1F8C0F51F +:1018F00037C1F759CDAA97E43BF4837C5B7AFB10A0 +:10190000A6D07ADB4B70FFB4E34ED58976FE988D76 +:10191000C3EEC6FA631C3D93713D7A630AE5752DEB +:1019200089F483B48FE5B9BE5A33A78B5F67737FA1 +:10193000F5E1CE5411E7F96AF371FFBD637D1CBD7B +:101940007335DD22EEBB6EEF417E489505AF5ED26A +:10195000FD59B2C7E658982D839F0FB765C0F7DDD4 +:10196000E6B6DB518FECBEDD3188EE1FA83F0C2FB1 +:10197000E3FE23CDA324C5F8AE949CC71382DEA357 +:10198000FB93ED7789F3D9FBC5FC0FD73D7D3DEA8D +:10199000C1C39BFABA70DD5F6C8FA3F771BE887A02 +:1019A000AFF37CEFB301FD46DD175B46F36BCAB6C0 +:1019B000F3FB5CC28E93F47ED6FB5C9FB8A3F6115A +:1019C000CE7C3EE9680DA37BE7B7812D8EEDC72560 +:1019D0009C7A1ECF05CE6EB03AF1DECF01A477DC43 +:1019E000BF7A41E5F7936D9CFE0F6C1914447F7329 +:1019F000F627FC1ED68EFBEFA17309E5605FE2D1EE +:101A0000CD4E7BF9C1FBAF473638EEF5AFC88076D7 +:101A1000C737F173145DDE77D8FDFCCEC8F71DCE55 +:101A2000D74E3E57FB58C6233EC936BE1F20E12A7B +:101A3000FDA45701FF230787E1F475CD1CB28F8FFA +:101A4000D6F8293DA6ECBB6F0CD2AD2389EE37BC8E +:101A5000DCFC808AEFD1546E1BF403FAC5A3ED4978 +:101A60004EE4D7AF6B96D0FEE8D19A6AFEEE4AE715 +:101A7000BBCA414A2FDDD64AEDBE6E1ED282F78127 +:101A80005FB12709B91FBD1FC4F1D8DD3D67B9AEED +:101A90002377727CCA791FD9343311D7D5FA584AC3 +:101AA000CB28C463429213EDBC0A714EE4E05A6E37 +:101AB000471FB2253D3909E07368DD3569F85E508E +:101AC00079EBB5D7E3F7D9DB1527DAFFDEED531253 +:101AD000D13FFB5C6B4FC4FB5F9FAF95F7C682F4B1 +:101AE0007EEFE86246FB55A3431AF3E4D1D633D127 +:101AF000C9A8A31ADDCFFD12F7B1305EF2433CC591 +:101B00004B98D89F2A7F89C7593AFD59E1CF8D114B +:101B1000EB1E91E392FB0EF47DEC48FEFD8B75CF3E +:101B20004FC6FE0E379A9D38EFAF1BF93B16F3C038 +:101B30000FC3AB008736713F675E93427EF1E14D84 +:101B4000A0A7615D958BCC3ADD6B8DA2BFB1508EA5 +:101B5000E72225FDCDD38344D7D1EF8C24B326BA19 +:101B6000FFF663D1E3C539467FAD930EBBC3BF809B +:101B700013F22DD2A1C4F3BCB5FC7D5B57D3A042B8 +:101B8000A42789F7E87B0EB51646F71902A6787ADE +:101B9000177A8ADD635660FDD7B8DBC7A1F87C24CD +:101BA00087CB4575AC49C7FB7AAC96BF63D0253E61 +:101BB0009DC3E5E89B398CD2B21C7EDE58DE5B9378 +:101BC000292C2487DE654C707DE7812AD7E46C9A46 +:101BD000ACC1FCA78C71DDDEDBCBD8CD39CF4DD6C7 +:101BE000806EA70C71BDD00BF2331EDFCCF397B81B +:101BF000869921BF54F9DDE47190BF2B479F9293E2 +:101C00001A1E47F60BDFAFC5EF8752FC37E40C43D3 +:101C100039CEDF2D3BA6740C5C9217AEFF9EC2F648 +:101C2000BEAC84F3ED6646EFE594E1FC53BB4F3761 +:101C3000E4E8FE9C6131CA19A3FB6365017E1F08BD +:101C4000FE7CB6343AA746F45426EF07D51BEF07BF +:101C5000312FBF9F26EF6DC97B59FDC3F7CDD69DB0 +:101C6000CF7DB363E27E5CF4BD3FA585DF97AB0D0E +:101C7000B0F638C243D47D9F04FE7EE3E217BEDA9D +:101C800081643557DA2BA86C8787DF3960E9FCBCA3 +:101C9000C0ED820EBFA8617DFA002B5FDDD696E80D +:101CA00081C91E9D1CCA47FEF658FDF508A72FD610 +:101CB000D5662F76E3FD58AB7712D43F14E4F74F87 +:101CC0001708BB9335A60A3E57439743BD5D79FD80 +:101CD000E99D8B5F0A7A3A9A17CAC577870279DC41 +:101CE000CF817A74FEAD78D915A958EFE8967BFAC2 +:101CF0009403DEACF8AE9F8B5286F7C5AE84BE4728 +:101D0000BAE8BD3FA6D2FE6E90FAC37A89A8D73D45 +:101D100033D379FC9DDF2F947892F0EF82179802ED +:101D2000DAA5261B33E3FCFBB3754ED4C7123FF292 +:101D30007DDBC52FF038CA62A5BD2E05F3CF2A740E +:101D40007EEE0B1BBF0FD455CF6DB420A8E7AC9B24 +:101D50006978C748BE23FB63C7835ECA11F7C20711 +:101D6000B14191EFF45688B6E3D5E91E7C677471F2 +:101D7000AA8DDE3759FC786FD2272C703BD181AC0D +:101D8000C7D6A5107DACC85309CE739B19BD4F545F +:101D9000D29C49E71D2735BB284D3C994EDF0F3FAC +:101DA000F9D6502E7F381E4A9EEA41EF8A973C753D +:101DB00041117F74AFCB3B49FC3D6DBB8DEE1B2FBA +:101DC000DECDF5D2E2EB548A5332710FCC27A6E375 +:101DD000B3D7535CC7C762BF0FEC93EF03EBE63397 +:101DE000BE0F2CE16B15F8897E2FF8BADD43D2D1F6 +:101DF0005F95EF05CBF708DBC47DAFE87783EF494C +:101E00009C40EF064FD3B91E897E37580BC479D159 +:101E1000BE3567DBF9BB16FEE87784DB355CF7F58A +:101E200005FC1DE1EBA619EFD3990BBE21396D2EF0 +:101E3000E8F28E9219E9DBEA33D6FFBBD42FFD59C5 +:101E4000FF33BED39C6DA1F7F0347CC71CF2D78B57 +:101E5000779AD18E43FBFCB8CEDFDFB3C6F375B7FC +:101E6000B1A1E9C8F7FFBFBF4F7EB677C9A3DF2195 +:101E70008F7E7F7CC8AE5F1AF2C3DA1E35D41FF1A5 +:101E8000D10643F9A8F6670CE5630E6D35E42FED36 +:101E9000F883A1FEE5275F33E40BD95B86FA636D17 +:101EA000EF1BF2E39D7F31D4BF227DBFA1FC4ACF5F +:101EB0009786F289FD4E18D7A3F927E4223F7BFFCE +:101EC00069683799797E81EF7BDFE036D1BB26C523 +:101ED000B946BA1B97C3E30AAC0FCB45F9355E9DF3 +:101EE00044EF241D6F52F8FBD2DDE8B124B0F7B403 +:101EF000887192751B3882E17C4AB1D3904FF5A569 +:101F00001BEAF798E6319467F8FB19CAB3E6780D37 +:101F1000F99CEA9186FA3D97E8867C5EA0D850BF8E +:101F200077BDCF90EFDB30CD50FF82B57E4379FF98 +:101F3000E01C43F9459BAA0DF98B9B9618EA5FD2EA +:101F40001C30940F0AD51BCA87EC6A30E487B5AD04 +:101F500035D41FF151D0503EAA7D93A17CCCA1264F +:101F600043FED28E6643FDCB4F860CF942B6DB5062 +:101F70007FACED3D437EBCF3CF86FA57A4EF33949C +:101F80005FE9396C285FF0A597EE4BB397F97ED8DF +:101F9000C47EDF18CACD6E46EF6057B2782FEE3B95 +:101FA0004ABBA6C4FB7743BF4FE6F2380AD0527B48 +:101FB0001CBE1F19F051FCC7850702514EE13D754B +:101FC000173F4F339DE2486ED26FA48A3C78BE071C +:101FD000EC8044F4AEF2F2D04E4E08DB63D9A72376 +:101FE000CED79DCD1EDB96CB681EFB73FD4FE7A6BB +:101FF000A2FFB16502BDFBCE022B701EF23DC07781 +:10200000A2DEBB96E995B6432CF25DECDD710DD9ED +:1020100083CFE0BF5F693BCAF0BDEDCE7E45BC42D9 +:1020200081F52D8EE8FF3EF017B43E8C35D400FFCD +:10203000808DF4CB1A27E51FAC49A7FCC3351E4A97 +:10204000D7D6F4A3F4D11A2F95AFAB1949F9276A63 +:1020500074CA076B8A29DD50E3A3EF8D35D328FFBF +:1020600024F8C5986E023F19D367C0DFC5F2CDE0F2 +:10207000FF62FEB99A00A54D35F5F47D6B4D03E581 +:10208000B7D5ACA5FCEF6B829436D76CA2F40F35B4 +:102090004D54DE52D34CF9576A42940FD5ECA2FC52 +:1020A0006B356D94DF51F311E577D6B453BAABE6D7 +:1020B00010A56FD67450F9DB3527297F54C45DF71E +:1020C000E51AF723645EBE5B21EDBFC968BF2371CB +:1020D0008C347F6DB0DFA3ECE8687C1C11E3E03B3F +:1020E000BD43816ECD99F91B6A23FCA7AFC478F27A +:1020F000BD8AE8772798B04FE5FBB0F23D8BD962F7 +:102100005E1582FE87217DF623FA7CFB7CFC05E9C7 +:102110000F5E9BEA3F45F499630A903F6CE7F791A5 +:10212000EF48F5B39EC370DFB07C278DE7F4D2FE95 +:10213000618935947AC3507A079EE272DD8D572506 +:10214000CE89775BFECAE16CB4A78BFFA5D27B6416 +:10215000EF981DF4BB97293D395C527A9A0CE93F00 +:1021600053FDAE9E907EEFA8BEC504F3FFFEB245C0 +:102170004FFE242FEC275F8DAE26F8375398C74CBF +:10218000E71199FEC73CB49BC0B0C2FC0D2C40695E +:10219000C0EDCFC275DD080637E6FDA3ADB9B1D6F7 +:1021A000153DAF7C31AF7C311F99F64FF3F7C5FE7B +:1021B000BE77E834AF77465D918FEB92F39A27DED6 +:1021C0009D98CC3A9EC0F97DBFFD9B834AEF30FCC1 +:1021D000A53F4EEF02A0BFB34811EFFF75797F8096 +:1021E000CAA7DFAE907D3603FC19DC2792EF0D1CE9 +:1021F000AF36937CC4F709701FED78F5E776246756 +:10220000A8C7709FA3160FF64079EDCF15A2AFE9CE +:10221000F88E08B49F9196C7EF4B339B8E7A787AED +:102220008B753DD2E974B0F7D07F02FA2844B8CF5D +:102230001BA5D27DF5774CC17C85F693CB2D0ACCBE +:10224000ABC2ED35FC8E4434FE178AFB07F23BD05F +:10225000D54484D7D72F8DE847F1F7574679104EEC +:10226000B5267EEF28F0A62A7EDF8B8B6675CCC55F +:10227000145F649AD78B71A212714FA555654B629A +:10228000BD1F5F29F0F44E3A7F5FB0366A9FA5BC50 +:1022900027F72FCB7BF2B873C96BBBE99DA585BB34 +:1022A000F87B906C68FB80C877793AD7B3E4CDFEB1 +:1022B0007D22D651D5BC8F9FAF60ED0322CF9FAF5B +:1022C00010E34BFA512D0EFF7A7BE4FC3AE97901D9 +:1022D000D17332D0736FA2E783B8AF38D9EA49BA65 +:1022E00041C15FC7635FE3FB47FE5F3BE93C913C55 +:1022F00057348BF928AD00F423FDFA02F7D37BB7EE +:10230000F358137D5F387226FD3E6D15EB18970E5E +:1023100070BBAE7EE91FF1B9C06B1AEE1F8F71D58D +:10232000A9C1D23F623AA5513988FE29F0C3CF1125 +:102330001FED4AF5723CC279D3E6C2E5B83538598B +:10234000E5F8606F717C00BDE8AAABEB3A81FE97BF +:1023500013FD27EBB40E35B1D840FFD397315D7133 +:1023600087CFC777F2C3C8F97FC52D60A675D0BEE9 +:1023700079D52B5617E2791EE3FA3A6CFF493DCD29 +:10238000F5FF7CD0FF58EF88A0E723398CEE211CA5 +:102390005118DD6F97F623CBF5A70FEE1DD6B74783 +:1023A0004CC1E189BD491FAFC3F9EE4CBF86DE0FBA +:1023B0009AEFB6D1FBB0479283B951EFA1D07B4DD4 +:1023C000327E759F99C793A2E7A58CDCC97FE7C4CD +:1023D000C202B82F81BFF33D1CF938D3427C568B23 +:1023E000A0C5385891CF13ABFF3AD1EFAE53DCCF35 +:1023F0000DE4F0774BBA8CE314E3C4F371A4DEE888 +:10240000FC5DF13466186F7BCF3CCE070E9DE6BFB6 +:10241000D4944C7226C3E66FC1F5CB788EF4FF7668 +:10242000E57DD187FCF41F6AE93D267ABF00CFF530 +:102430005CC6E5D13B660FBD4BFC4E611EC5EDA5EC +:102440009CBD7A248F7B5D2DE35C055171AEA8386D +:102450000B2B881DF762CC6BC671FBB34F247C2815 +:10246000BEF25A8166F83DB1D784DF79BCD83D947D +:102470007E2FCAC3CF5925A6F0F7463A1C2AD1D9D8 +:10248000EB01AF1D7F9F6495888FAE8E7A177CD548 +:10249000D0C54E3C176075F0F73ED714C5CF893CC8 +:1024A000BFEECEE7EFC33C995F98E18174803D5861 +:1024B000446A59D73C387F45ACE72227C0DB84F615 +:1024C000A64FC439E5EFDC8C23BD2CF17CAE7AF944 +:1024D000192DB82C1ED7EB66C4778EB536929F6A3D +:1024E000931EC2A3D4B3F2A71E47B9C1345F3F1CE9 +:1024F000A775783CB343FDEF5B2D147F7AC554F686 +:102500006B7C97B8E3CF5686E71C9A1C591A1AB70A +:102510004DA72E1C47A963CC04FE3E274BC0774431 +:102520000739D96F7E874812F7C92CE9CFF80E809A +:10253000DC6E52D82EFE0E979E80EFE13599D88939 +:10254000CB617EFF0FA64C086300800000000000F6 +:102550001F8B080000000000000BED7D0B7854D5A8 +:10256000B5F03E33674E66269370327930E40167EA +:1025700092C98B4CE290F054AA93106840D0E15578 +:1025800083243A58F446854C8AB445AF5F339000B3 +:1025900001F42FA2B548BD7640A568B50D4A6D6C13 +:1025A00023770242B197EA606D8BBDB57FF0F6F7F5 +:1025B0006AAD12C47AB1A5E5AEB5F63E9939930974 +:1025C000A2BD7FFFEFBFDF8D1FEEECB3F7D98FB554 +:1025D000D77BAD7DF28CA3F6FECB18639359C0CCAC +:1025E0004A18D34A838A96CBD854D641F57B954076 +:1025F000DBEE1C289D565F18FAD58E33F919D4D915 +:10260000C78E48A9C458E0986C313B18EBF3041D01 +:10261000F8DE05FCB90A9EBB4C16C5CBD84685B57D +:10262000F54299E1B3336665F47301FE05CE953149 +:1026300056C7D858CDC4D814C6BA5DFE985F8ABFB5 +:102640009F5C32551E1AD4DF2FC6FF17AA6FA58BC9 +:10265000BA9931AF23D22061C52F6BEA54C6E8770F +:102660008DB12A95052D30451A0B30DC0F9BEEB34A +:1026700006AAB1B1517DAB02FBF9A50BE9179997F9 +:10268000C90CFBE9F3FC6102A3F51EB267D6B031B9 +:102690008C851BB4FB1A2743F953B3AF8B7AA993EC +:1026A00071FCCC6C1635C1F3A10C73648F9BB1C364 +:1026B00061EDA95EA81F96AB088EF774C266000490 +:1026C0005B3BA1A2C4E7DB3A798DAA013CD332CCB3 +:1026D0005F3A8C702E32A9A5B08FCDF3ED4D1180ED +:1026E000E3BD0DF6362C73CA2C8C01BC97165B68C3 +:1026F0003D7BCBEABF5D0CF5564760B6A47138B0A0 +:10270000BC381CE001E3FB0D32DC6F8BCA06A5442C +:10271000B830804B06DF00BE770DDF32BB4666E186 +:10272000314EC65E9EF1F663BD304EC64E587736CA +:10273000BCDF71460EC23AD8F90B57D901DE01BD94 +:10274000FF4C89BD9978CEF0EFCD0AB13F37C15328 +:102750007D4B6F375F3ADC2D4BD6573058EFA64E86 +:1027600017C1AB47F2F9C7C27872C7A93BF0F94667 +:10277000193A02BCC25E25F238CE23072A703FFA0E +:10278000782BCB1A6ED0004E19D3FE907E0BF4FB43 +:1027900028CFA42170366A377DDF8EE777329DE13E +:1027A0007B99D9B1B647A17DE8F572B60786F9E8FD +:1027B000D6E00415CE630B9CD39B1E5C4D64AC69C4 +:1027C0003A9683634D2E02AE8B9741177FCE447BA2 +:1027D00084EA6FB98BE99C00FEA2FF20F5DFA26CB2 +:1027E000B7DA711EB755DD9380F7579959472FCC4B +:1027F000F775A40B7CEF7C97B63003EB12D5EFEFA7 +:10280000DC19F89D07D713A1327B7E840501DFEC2C +:1028100015612D0CFDAC1B5810DF4F86E7DB6E9960 +:10282000DEB71E7A8869D02FDBE39382D02F673E14 +:102830008CA7C399D1B987C7D442BF3D80309311CB +:102840003EF64838055D5E93DB704CCE1CFDFC9275 +:10285000F180093CD0CFD3FA577310F902632E13DD +:10286000E2DB5A2BC7D3C6622BA379D729BBD3602F +:10287000DE27B42C5AF787390D639877F4F91E8157 +:10288000F309033D4580AEB0DCD3A9B230E0C963A3 +:10289000802F58DFDBA951B9AFB382CA273B7DD463 +:1028A000FE54E774AA7FAFD34FF5DECE26AA3FD3FE +:1028B00019A0FA81CE66AA3FD719A4B2AFB38DCAC8 +:1028C0001F7576507B7FE73AAA5F9506E786FBA9DE +:1028D00008BB16C179F4DCA9F83580CFA038C7C38E +:1028E000FEE26C1F9CB7ADC2043407E5F11D0CF786 +:1028F000637399FC1138874DAE1DEC8B505AA66658 +:10290000F448C057363EEDE8918031DBE4FB19F224 +:102910008347A4701BF331F693483020CF60CCE39B +:10292000FA528313EA3F8BDCB2DD0A785BA62D6C8A +:102930005E9F50D7326A6FDBAFC6EB13BCBB653B03 +:10294000B4BFAADDBA3D47E2EB60F98CFD26727B8D +:10295000603DE051B4988511EE436E2582F8B812BF +:10296000CF4BC6F5ABB4FEAB5997CB04EB9FA02978 +:10297000B54837D03FCA722EBDFFA0A6D1F3E4F709 +:102980002ED6CF34F992FA31F345C6C376E922E365 +:1029900058A5C5D618AC7D9B45F08F5C07F18F1EFE +:1029A0000BBB310070EFB1F1F2CA6289F8ACB3B879 +:1029B00061B71BE6DDEDE672ABC716561B70FE6A0B +:1029C000930FF9055BE7FE7931CCF7959FCA6CABA5 +:1029D00016C7CFFF1078503A2183CBCF7FB4464A39 +:1029E000619ECF4F78BADB09F5D2477D3E33F4DFE5 +:1029F000C67C76C493F03D26F638D4BF3BB9C4B943 +:102A000010BA574DF98113F9ED5237E70311C69A01 +:102A100010DFD66FBC65C220941F9DE07C4A71F325 +:102A200079765B621D749E531C6C0F0981EDE9C8B9 +:102A300077D6BBE090A631661AC74BC5A25E8FFD64 +:102A40001410D461588FF29769D6008CD7752EADCB +:102A500009F90863B174E4638A2DA866C1F3ED61D6 +:102A600013F1852ECD119160DC6D8EDA631AF24F71 +:102A7000D5E42B45387A4D04C76EC7172266E4CFDC +:102A8000D2FA36942F11F519AB1B9E47BC2615E9D7 +:102A90003CE25FD484F57050F6956A8241607BD049 +:102AA00019D98AE3B2A17FB90CDB5B980FE1B03191 +:102AB000EF4F87D2A1DEB554F599796F4D06B93342 +:102AC0000E7F8329BB2C831BD2711DCB787FF8CD61 +:102AD000B710E5701A3FBFAF0FCC558B49EECB61F5 +:102AE000A14748178010658BCFEA83F61A476D938C +:102AF0001F4A39A3D6AAC13EBBD55AEB0ADA3F73A7 +:102B0000803284228FF853976A22398CED5F447AA1 +:102B1000EF662F7AF28894A8BDDBB16300E121DF74 +:102B2000CC985BC3F5C17C3ADF0378584B661ED363 +:102B3000601F3DB738691FB2E4A33ABB59A675E7D9 +:102B40006BF628AB013EAF2C38C6807FE45B6F9FED +:102B50008FF5716DF2EF0613F8F4D8A0B19EDB6C1F +:102B6000AC6733A85BE3F32E7273FC4D865B323C9B +:102B7000C6A9DD2770FDE382323D4C5EFF43EA03C8 +:102B800059F50CD7E9A075E6396EAA070801CA0500 +:102B9000D623FEFDADEBAC511759DD307F4D8E894C +:102BA000D496CBD8D0061C779BC0F71E373FCF38C2 +:102BB0005D9975BADC8A7439619D898513E48E3B11 +:102BC0006C67E184F94A7A9C867AE9F67C43FFF2E5 +:102BD0009DC586F6CAC844437BD5BE5A43BDBAF7E5 +:102BE0007243FFCBFA1A0CF549D17986FE75C716E8 +:102BF00019EA5362D71BFA4F3B7993A17DC6E06D6A +:102C000086F62BDE5E63A87F6EE82E437F5DDF4E87 +:102C1000968FDD822F7C5A3D3BCD05989D305FB26B +:102C20001E9FAC875BFFDAA56D407CCE54089F6584 +:102C300094E7505F73A7124943FCBFD2A7217FB925 +:102C40004BE0A3B7DC7F1F9E5B7DA695E482ECE0A2 +:102C5000FD64C71CD253C6EF04BE54875A231B6EB3 +:102C60004F47FEDC190E783CF175DBD4ED0CE9B76B +:102C70003EB3890D3AE2EFCBAA9F0533703E8DE655 +:102C8000B3AA61EA67D3E0FD847D1D34999803F906 +:102C9000F88042FA7A6F46818CF4D7FB97898D547D +:102CA000665C3107F17D92CA1EFD3EF4EF95D83186 +:102CB000067A52AF899D059D8D3D936447E9F6D311 +:102CC0007813B363B95B1ABC83A19DD271A2612C46 +:102CD000233BEB59DCF7BDA043E0BEEEADE17AD675 +:102CE000C6BC791AEA653DEEDE63C5B89E5C902BE2 +:102CF000480872C0877A85BEDF37C479CAC53D836C +:102D000028FFD6645935D49764EBF6C0EF005E8F88 +:102D100058069FE8827AB7A4AE42BB237CA7C3F7CC +:102D20003843FD91C34DCB30D56D80717BD7FBE52A +:102D30002C68EFDDC27CDD481F39F51BB2E07969F4 +:102D4000E10A9313E9C1B37E0396AFA01E0BF0AB6B +:102D5000F4EE3665437BD5E4FA6686B25785F9B260 +:102D600047C72773E64E86FB611EF92DC42BD4BAE4 +:102D70002FC0D2EB9D70DE30AF0DCF5BA292E06032 +:102D80003BE788D8B0EEE170B1F9A5483AD4733C7E +:102D90007EC9EFC5F776D2F9DAA2463D16ECCF37F9 +:102DA000DC53509F359EAB6C7D80D6B7CDC4E9A275 +:102DB000274B3B8EF2B9C7ED717669F175EA7CE578 +:102DC0006D618FEACF75BE723DDA1453E2FA0DE001 +:102DD000F94E5309EA67DB19F227DBDDDB19E2B5AF +:102DE0004D0D6B0CF5F0AF8509CF75FDF60E413337 +:102DF0008DC5CD5694D767736A499FB5ADDB4BE758 +:102E0000950C37DBA089F92F02D7CCB25D24DF8186 +:102E1000016B68871FCA73B4ED4EA1F76FD0389D60 +:102E20006D01328E79098FACC8AF2DC2CE004C3007 +:102E3000A17C3BAB326E27F6BAA97E4716AFEBE317 +:102E4000DC915B3BF662FAB70DECC260C23EB6C0E5 +:102E50003C08978DE71736215C994CC4C1B6FDC577 +:102E6000BB7B2BC252D8351B04BCBFAE71F88E574A +:102E700018D905BE9CF94D24FF5C4FD2F905CE153B +:102E800093109E56EC24F883116DEEA0F55B74F957 +:102E900064BA7019AD595360FD05F8A4184B2EDFC4 +:102EA000A0CBC00509F97F823CE305C9F702FE3BD0 +:102EB000C803637BF94E63BD3292F47E98BD86F2FF +:102EC0007F25E3F0AADA676CFF16CA71E01B2B8539 +:102ED0001C67DB2D24EFACB0A20B5CFEC6E521F035 +:102EE000876B7A63F5E9304ED1748B414E1624F628 +:102EF00003F8D5DE6A0AA0DDA0FB5F74B807DA4CE0 +:102F00001685E84123380D3F17FE9664FE3D3E8D41 +:102F10009FCB212523B2C1CDFD12C1326E6707813F +:102F200024EF957DBF6A417BEC98D907983D7C9E44 +:102F3000C9E7BF6F583F0ECC2F267B77B00EED6FE1 +:102F40009C2F98309FEE37292C0F2E2A86FE1F3497 +:102F5000E54CC6734A2B6416A463DD2FA2DBF9BBD4 +:102F6000115760BC6DBE573B0EC33A369F4C239F32 +:102F7000C66CF3F1639D505F532413DF53A7ADFA82 +:102F800036DAD30DFF0AEDF0CE664D1B4BFAFC315D +:102F90000BD9F50D02DF1B849DA6FB4F6E2BE6FAC5 +:102FA000F42DA28437ECDC4E8FDA51EFADDA073C1A +:102FB000DB882FE9BCDD4F7A71756F72BB9F21BD35 +:102FC0004F14F80075473DD427897A2F93B25538AE +:102FD000E7CB9A070FA1C9E17DE9881DF5B0FD3661 +:102FE0008E1F4F0ABD2F8F49BE28AC3F6F9FC3175E +:102FF000817E1966B63F06FBF0BD28BF399800CF29 +:103000009A7E63DDCB12EA6E5C87B17E8FD621217A +:103010005CEE690154842D6F28CEC879AB8A21CC2F +:10302000CB10FF669B1D93D0EE5A53EF6008D7B4C8 +:1030300053E5DF8C219F396166283FD474EDBE468D +:10304000785FFD976CDF7A2D7EFE4F76228B67ECE2 +:10305000C10B3ED6ED89FBA99E82F34479F33DB0C6 +:10306000C7B1BD17CE15EBCF803D8EE501B0C7F1DE +:10307000F973608F63BD0FEC712C7F04F6383EEF5F +:10308000077B1CEB7BCBEA1F4CF66F25FAF9E2FEBF +:10309000AD4149F76FA5015C1BD04E9C92E0E70A59 +:1030A000723FD7278FE3D7C721FFE1887186FD885C +:1030B0005615FD27C5F0C61878FEDE9DBFDE8B7263 +:1030C000658114DC87F8BD7ACA9B0AD7B38714ECF4 +:1030D000FFB00DF01FF854E128FEC32B679DBA2303 +:1030E00017ECF41F15B72E443BFFCADB4FD58D8775 +:1030F0003A2B39C6EBDF39F56C01F0EA5B4AB6F0E2 +:10310000FAFDA7CE1642FB18F6ECC2C619E47724E6 +:1031100039F6B0C49A13F5C09F08FA0CADDB41FC38 +:1031200014E400433874E505488E9ECE19CA5C014C +:10313000FD43B94379375D84CF87D63D48F2AA2B4A +:10314000F3F7A4A7740DCB151FC9157D5E5DAE7C8A +:1031500020704F972B6B6CBC3ADC2F5842CFEF1787 +:10316000FE1F1629A57AB68DD7FF5783F60ADA47D0 +:10317000001FB2870F674EFCFA4CB43F9B645F1A86 +:10318000D4EF77D4DA502E9D15F40BE386D1DE0F01 +:10319000CFB6461EC743CDD1881E9DFAF8391E54BE +:1031A000CE9853ACE3C5CBED51F40774355AF7A074 +:1031B000DEB9C3514CE3754D57C2E887D1EB1B2EE6 +:1031C000BFDC8A7A4756A6D38D759D3FE9FE5BF832 +:1031D00031E3B80D62BB0D5647D49C89E861F943D1 +:1031E000A23EED6031C21F9F090C17A0B7AF9570CA +:1031F000BCAA63BE667CAE481D6144C68771EDB84B +:103200008F0CE1CF44093535611FFE02BE2F7D1FB3 +:10321000194A58EC83F4A91D0E5314F5C21DB02FA2 +:103220001CEFDF8B35824FF2BE18BA6861DC59D3D0 +:10323000C5BAD59907701DB34DFE6E7CEFC8C72D7A +:1032400039887E7358878CCF4BC0F245FF2DA07410 +:10325000F7858BE827C9FEDB2BFF4DA2FDB0DB1500 +:103260003A17A58CEF7B97127133328423E31665EE +:103270008C8EBF2525FC7CE3F8EB67484F5D4E3F05 +:10328000C75F7528733DE26FD650DE06DA5734E526 +:103290007924E371F2F9D4206D73396046F87ED257 +:1032A00079EAE7A8E341B2FCFA5A89AA9FAF8BF604 +:1032B000E9AFE074A0EB5B0CECA18C91F0DB04E3D4 +:1032C0006965F1BAE20A901E6DC9F155A09FB7EB8E +:1032D000AFE6B6547EDE1B049CD667DA49BFEECA61 +:1032E000E4FAF540E63C835DD408769204F861CEBA +:1032F00066BD4847E631D7939FCC3C1635285C57CE +:1033000092DE3A663ED75B55D05B53CCAB9732EA40 +:10331000AD29F4D961BDD5398FEBAD990AE9AD0F6F +:103320006728CDBB53F09BA9255C2F1CC07DA4B0A2 +:103330000BC11E247FA56E0F2A6A90EC3A7D9F5325 +:10334000055DE9FDD3D40E86FE33B3E2D3502F35AD +:10335000DBB99E9906DBAC4890DFFAFC934A785CB7 +:1033600025AB9CEBFB262BD74FAE7C45EA4805F7F7 +:103370005089EE5F498D777F03DE105FA875287E48 +:10338000D40F6A1DAE06D40F467B0F4CD2F0DBCEB5 +:10339000385FF1FD75AA99E48FEC73219EF55A060A +:1033A0009F7D05EDBD230E9237BD1985349EAE5F1E +:1033B000835D1BAE8041F6FF1928D134D29E053BB8 +:1033C0006B4B09C6BFD6E44DE6E3829E573D52AF34 +:1033D0004CF61B0CD37BE65E377F2F320EDF93D685 +:1033E0004C1F8B78954CEF7A59E4FA69D14A5857BB +:1033F000D1B86354EACFFF8999C90F97DC3F327C7B +:103400000E5C2E57C26463CC248F23B8EEF7D6BE71 +:103410009AE783A5B4CB67482E7FD0317DCC668DEB +:10342000F3DB7D2867BE2413BF2DBC7520CB9970BC +:10343000CEBB3AFB8A640FC61762458D1EF2F7F9C0 +:1034400053ADF7B83E7F7402F1678BC0032D27366A +:10345000B71CE0AE394C3E542540F81AF840BD9CEC +:10346000D5A8C2FC459DCCE780BA9BA9E4F72ABA4F +:1034700060267C2B3ABC8CF07842CE9014F626CC99 +:1034800083AC38217EF2614723D167D1D8617B8F2D +:10349000E20C1FE64417227D7FF8005F51D1A3C6DE +:1034A0007690B1E497BE65AD3D8226E384BB5513AB +:1034B000D68BBE2DB14237AEE3B07B33FA757E9822 +:1034C0004E7E1DF34E0FF965BE2D050F105C23DAFD +:1034D000574C2562B3D06FF557ED7BB6921C8BCD60 +:1034E0002539F665137B3C85DFE9E725DC8FF19A0A +:1034F000C0F722D7CB452BEBB03C4EE77DA9F4C4F7 +:1035000004DFDE3C663BC5C5C20DAC02EDC31E0B3D +:10351000E0550A7AF57B387F19E6C7027E36B45645 +:10352000602CB324F4BC7D4F3EF9641ECA6D46F690 +:103530006472BC36BDA2971AD37D7E86FE0949F51A +:10354000733EAB865D618C03FDC59C12AFC77804EA +:103550009F766F7261FF468FCF857430E09EEABA26 +:1035600009E0E770282C2D810FEB78F262C654D267 +:1035700043F471D664145FD42E57801F6B1791D318 +:103580000AFAC7519F3934C3AAC17A37396A63A886 +:103590006F6D72E4D4929FDD017C23C1EFE4701C57 +:1035A000253C74F8B83FCE81FC17FD4E62FF03EE58 +:1035B000A3B47FBDDFBB820F397C511EA7046B060D +:1035C000FBD9E44018ED0C5B0E23BBD266E5F49406 +:1035D0000EC7614DE023FABCBF2BE1F6DAA6C2DAD2 +:1035E000583DAD4F46CF01DBE4AA75913C4438A36A +:1035F0003E3A6E581F25FF4AB180B33E4ED700DFDA +:1036000067609DCBDF988D7668C0E5C1711D375925 +:10361000C3281732265F743CAF4732F887E2E3AD28 +:103620009B25C62BC6F1CC19B52A8E67413E910267 +:10363000FF6688757D56FF19405425BB8D71FD0AC4 +:1036400030DE954A8FD04BABF0838D7C8FF349B73A +:10365000B05F804FCEF6A0DD52F8E6D17AEAC5ED34 +:1036600016E75CB94286F3FA004ED02CC5EDF8643B +:103670007DA6DE3C44724D9747BA7CDA85FA8C12FF +:10368000A7A77CCEB958415B80E4B6941320BC0157 +:10369000FD4643BA31637C3805DCB608F84B99D354 +:1036A00035A497C6F38305F8DEC18CB70B5882BFEB +:1036B0004DE7872F7EBCD786ED1FB6355C546FD1A2 +:1036C000E3C7A3C58D33EFFAFD9712F596D1E2C893 +:1036D0009F143F3E94A9909FEE11C9C897BA043F2A +:1036E000FA9AC00B6771F02B88478F48011FE98D4C +:1036F000C29FE22D0FDE89E733BE47616138CF8379 +:103700001F4F75217E5C2A7C753F7BBED0A7F21DC2 +:103710007B25A4D3FCB688847EF282B65EC97F91F5 +:103720007E8B3C9C9EF5FE1631FE55F29019E5D538 +:1037300055828E0BCEC9AC22410F5CE0E1FA944574 +:10374000E8EF99879EB0E178874C819E32940F997B +:1037500026EDF1047AB7DC5A6B6D48840FC67F52B0 +:103760009CDF773DC37A17D947BABCB5E8722247C8 +:1037700036C889503AC75B5DDF095DCEED21490A45 +:103780003E86F03E7DF9EFAF4196755AEA55304ED0 +:10379000FE49F18F61BDC61459A1DB31482F3E5956 +:1037A000FDF120BC3FE93BF5440F535890CA698CAA +:1037B000EB7DA0473DE321FD0E969C70BE0C5D0F96 +:1037C000799FBC8F473C5CDEDD2BC7C8CF7AEF7991 +:1037D00089F878327CFEE8D1FD5AC371BE8BFA4974 +:1037E00035F493BA316E65F463D61D33D6A7C48C15 +:1037F000F5692793FDA2FE5F24FA451F06BA427EB3 +:10380000A0FB410BC3917A15D65BC47A296E58D0C0 +:10381000E634C0F54AB3C8A7607E29D13F5B202FAC +:103820007807DFFFFDF0B98749CFBA45B4FF43E31E +:10383000CAAF74A3ED3CEC67D5085EFF3077D16C5E +:103840003CD7647F6B514742FC918DF4B3DEF2B0FC +:10385000C5D01EF04F223B60F112A37F96D691CBCC +:10386000F75B503B72FE4F9E17FE3947CEAF8FBBC2 +:103870000BF80DF251761ECE752AC28DA1C78115A7 +:10388000C95109E3D7F91DCC8FFA70C15AE64F151B +:1038900007282CE578900C6716BE8AE0374B3CCBA6 +:1038A0007798C94ECF5F6B223D301FF801F2816BD4 +:1038B0005601B940BD6095467AE4B56D26867280A2 +:1038C0009DEF34BC0FCB257FA77EEEBB703CD4238D +:1038D00057B38809F7D33191E889D6556CF08BBF7F +:1038E000C9E16525785D3BDD62F06B16A11F3301F0 +:1038F0002E3A1E14243D7FC1A31AE802E45961291F +:10390000E13F9773A528E76049EFCD38B917F3D9A0 +:10391000AEDCC068BF4359F608CF93188E27982FA6 +:1039200094037FB2CEAA40BFCA36D56EC27C8683CE +:103930005983DF62598CD594B270E34CC6FED93EF0 +:10394000542541FDF2D24777F4C0A11CB40D7D1778 +:103950009DBD0EC7938B9A3E17AF67661EA43A9B18 +:10396000CE3419E063C719609F7675DE3E33CC6FA5 +:10397000F73AC8096967C3744AFBE9BE5CBB07F341 +:1039800041BA4B4DA427B1C476D8C7774A553DBF3D +:103990008CF2DD58138FEF278E2FE75C64FC7930B3 +:1039A000FEE44F31BE95AF3F0F1F817CC9C3F5A325 +:1039B0009F1AC7C7F3456751E2FC623C998577635C +:1039C000FC05E673487C3E15F34DF29831BF6078F4 +:1039D0003E15E6ABFE3BECA779E479582E761ED770 +:1039E0007FBAF3E836F969BDE11A07D93F0C9A4D61 +:1039F00053D1CEE0F3D964F6A25CCBE1DA3D350ECB +:103A000057D0F7685CE8BEFE8280B305E1AC2A04BB +:103A1000E7D1E07648E5F94E5B547B64BDFBFFC11E +:103A200079B9F87925CE877AE325CF773DCC97739E +:103A3000E9F3217C917E86E10B67B221EFD2E10BA5 +:103A4000AB0A5F0A7C0FC1B8A604B8C6F38A1E523F +:103A500051FFB75902561FF0DF03A53C5FD19BB35E +:103A6000C84A7906B98BAC98BFB7D1EB68C278DD8C +:103A700046CF12AB25414E6FF4B6503BF4A77C28DD +:103A80006FD48EEE0956CD6264FF6F99D9E85A81E2 +:103A9000F8D3C1F3ABF47C235D1E3211BFA47DC10A +:103AA0008B633E7760E810F4DFD23199F2C9C664C7 +:103AB000FD89F2A8B6B5F97CD8FE2D8C33813EF194 +:103AC000A0883321A2921FADE6F247312E5B5BBA8C +:103AD00046C2748EC25546F9949F94A7537B26D64E +:103AE00080F9586C05CFB772B5C849F2D048B7DB3A +:103AF00010AE3C2F2A2271F81AC6FB3D32E95CD485 +:103B0000EFF730B4EF9E85B1CC46FA32617E523287 +:103B10003DCA8A5FAD47BD7C8D89D65180217F101B +:103B200071B5D5F35D2BE079E1CDB24F82E763BD8E +:103B300077539E1268F5A46F78BDC71BB03E629F95 +:103B40002B8DFB48DE57F2BA4170911EA29F57EDB4 +:103B5000195F3ADA51B5A58B288F8C7E747A372796 +:103B6000ED271BED5F93DF0672CCEE49D81733F4D7 +:103B70001376DA7F6DFD242213D25172FCEB6B01B8 +:103B80005A671AF359157AAF85EC453DAE968FB456 +:103B900083E73E9EF1B844F2FB53F9FBCCC5E36CDE +:103BA0006976303D81FEA4DBECE4BF4C4B833A9C4C +:103BB0008FA430EB3878BE4BF8FDD64B4CC67A7CE0 +:103BC000BE28E5A9774981ED3E3796DC5EB26405F3 +:103BD000280F11C3B48976E721CCEF80F635B7BA48 +:103BE000C7A2DF6E0C10440CED661197D2FD24992C +:103BF0002583CB517E1797952CB6A27C46C7D2E57C +:103C00008C5DB6B7E8FEF0CC385DA69DCB675A82D6 +:103C1000FD922677509E47DAB9F1067F4A54D85D67 +:103C20007ADD9F2337E27C73D02EC0BC26A676E3D4 +:103C30007BF500142DD13F7ACE6518273E7EA16119 +:103C4000DE28D8CF897180D1C74F675A45E2F8C5C1 +:103C5000A38C5F9634BE9A72FCF8B8D9867137CAC5 +:103C60009C5F8473EC9154FEBC95650D5797E58E6F +:103C70009E87F6C532E177B302CBC7B893C09BCD20 +:103C8000AE0ECA4B33DB797CD422E2258733DA8847 +:103C90005FB142635E5A0353656CDF9839E798045D +:103CA000ED0D0EA39E7ED5F937CDC877AE928D7AF5 +:103CB000BA9F75107E5EC98CCF2D85463E40BA36C0 +:103CC000FAFD3326C7287F2DD7417906A3F90F7E49 +:103CD000D3C928AFCA921EE840197777D9B4EC8DC2 +:103CE000D3A13E86E3D7D6B2F98BD11FF41B81C78F +:103CF0001B81EE118E2D6BC6EE36278CDBA2444B5A +:103D0000518EB498781E3FFDC0FCBFC9CD277F6A95 +:103D1000F2BC94099CE08F6AED90029E847DFC4683 +:103D2000D0C5F07C7714EC463D7678BEB4E8149AA2 +:103D30006F381F48CC97F7D9E67B43D0B33E5FEB93 +:103D4000578CFB6B5562B4BF561313F9FF7CBE371B +:103D5000707FEECF309FC8EB1A9EEFABC6FDB5A6C5 +:103D6000C5687FADC3F6A4982FEFB3CD97A6745066 +:103D70003CE63E899FEBA1BD4BEE477FFCD9F96B3A +:103D800034C437DD3EA3FB3366BA3F4372EFDA42F9 +:103D900085F4067DDC7D9DD3995FE17E1B2C2B662F +:103DA0004A740FA072BAE4C778D8C340F7FE32F461 +:103DB0004BA9D41EE97451B9A753A3F231B007FD42 +:103DC000E49FF251FD6C19B787EF1BA72E5B89FAB0 +:103DD00042BD9DE741CFBC0234D1B8BD0506D82114 +:103DE0001BE61B7E814DDA8A68BE93C323A7312F61 +:103DF00082E7649FF462AC13EA6933CC1AE677A7D2 +:103E0000B9592095DFE57D913FB359CF9BFF9CC405 +:103E1000E3EDA08FD4C3FE6F14A066E6F912EA5555 +:103E2000D77E358BF491962583192AACE30669D2A7 +:103E30002F3C008FFF2DF4911BC7733A4EB62773AA +:103E400050B24CC6BC3E732402BF2ECE584CF6E88E +:103E5000E2A58C39E1FD6BF13D902BAF087DE6E5E5 +:103E6000C13486F65AB891C7996FB8DB6847DE67E8 +:103E70008BAAA8C7DD372987E179B4AC35B66F16B0 +:103E8000F182C54976E5B5497934A065F27C10DC4C +:103E9000F30CC6DE2DCBC8A13C589147F384F00B40 +:103EA000B1C21C4AB676CEF58CC1F8639A92FA7EFE +:103EB0008E3E5E8EE03B2CC74F70D0F3CA99F9A9B5 +:103EC00049F4BE984F7F6F97F4D4B88BF935416FA2 +:103ED0007B6BB082CB67D4AF59B931DFE7ECFCE242 +:103EE000AF37B254783B24A35F415FFFFF2D7CFDC9 +:103EF00011EE17CA57667D3899DF432B6489F7CFD7 +:103F0000F47CAAC5C37599A15EB954AFBA86BC78D2 +:103F1000DEAF7D2EDDB795F04FE80FD1D74D17D22C +:103F20003FFD78C3EB70F98BB83F4EDC1314E38D83 +:103F300006E7E47C07DD6F433F53E3FED8AEDD3C8C +:103F40002F323FA7E11DBC3F85CFDF34E095F19EC6 +:103F500054D7C01312DA17DFC27B5F727C3EF4D3F2 +:103F600086497F35DEDF1A218F19BF97A3AFA74B94 +:103F70006115648F9A803FC07C0B1C83B2A4A1DFC3 +:103F80007D88EEF3DD59CECF057387F97D18AEE756 +:103F9000990B4C3C7F6382C6F53ECFD0F8C4B8D0B5 +:103FA0000DE55CAE2F487F75AD06F26F49F9938B36 +:103FB000313F69C19857D7BAA17E5DF97717CB8099 +:103FC000470B0A5EFDD00D3ADBB2F2A778BDEAD509 +:103FD0000F8BA1BEBCFC695EBF8211505ACBBFB72C +:103FE00018F9EA0DE5AAF0F3C50A71BE0512A78F0C +:103FF000CF5A9AD34C29E3F7FF50AEFB139905E74C +:1040000009F4FFE424F2A380EE7FF527C51BB12954 +:104010000FEF13899F9C4CD267E6E1EF00CFABE531 +:10402000E800BE6FB24609AEE59837534128F0C0AC +:10403000858BE44724E39104E8BA0EF5654D652DC0 +:10404000A01F77AD63415B49029E33BFC0739EC71B +:10405000A3AF479F7FC4BAE0486567E2BA1EA67166 +:10406000F4759D9E9416C67B677AFC545FD7696988 +:10407000E811744644AB0697E2B99ECE181A2F4158 +:104080005DAB5097503D77E811C99750B7F073BCBE +:10409000B7FC27A4F7AC95FCF79623BF541C74BF5C +:1040A000AD47E879DB728361C6F57BCA770C17F1FF +:1040B0007B038D93257F627CFF9B02BFF22A7839B8 +:1040C0003B6D7BC709C0C7D00189AD87FEA1F367EF +:1040D00015B4C717F49F52D0EE6E3F704A41BBBA79 +:1040E0001DEB304EFBC30AF1AB64781754980D7189 +:1040F00074DD9E385254B63107D6D3BE52F2618A6F +:10410000EC9AE7B366637DCD0ADC2563D7CFDC3F4D +:104110001BC9BB3530B011CB1BD9E0118C172C0B50 +:104120001AF5FCE56D46BDBCB5C3A84FDFB81D4E02 +:1041300007E4D78DEB0A0CEF31D490613DCBC47905 +:104140002E73DD1333D7603DE1BE8E44644DFE9D7A +:10415000E57C07501AFD160BFA25A2E3F6662BF94B +:104160005F8F14F13CFBD02A33E50585101DB0DECE +:1041700021097F969FF8A32EBF67F79D395A80EFDC +:10418000AFB2101C58D81F43FF43B3C0A71B9B9B63 +:10419000DE413C6BD66EE3727CC25E0BF957825CEB +:1041A0001FD784FFBBA5EFBE4627EA9F6B25F26FA2 +:1041B0002C6F33EAEBADF80BEA6FEBA448D48D70AB +:1041C00032B6DFB8CE587FBD5CC8DB2A568574F2A4 +:1041D000DB7249A67BC5A2FE87A25FBE1C8589EE65 +:1041E0009202A710EF5629D11A946B774941AAEB96 +:1041F000EDF0BC9DCB1D2EEF4D4051C4772DDCAFB3 +:10420000105E2D113E2E1F21FF13F403F3C87A4ECA +:1042100005F7B777D9026BC95E7A4152511F69948D +:10422000FDB2D31BB76793F13157E0F7CB6CD08B5E +:10423000EB2A43A003FCCB168F89A03FACEC9F5721 +:10424000507E63599DE433113D9BD8BA5A2C65E2E8 +:104250000FA86FDAA02C33F73613BFBE4C5179FE8E +:10426000A08B25F201FF134C4278E1D271DEAB0B3B +:104270008F7D8CE778CDCE7BCE20BFF394F86BEFAB +:1042800083F56DB3F1F9B73D2F91FEDAEE3D4A7C2F +:10429000712CA009CEDBEE12FCB10FF8A3BEFF62B9 +:1042A000BCD70FFC0A2F8ECCF7D2BCE3F4F8809E6B +:1042B0005F1B6D305D00BE3356CC5B50A311BCF26A +:1042C0006EEB9570DF452CBC1EFD44328E991B2F82 +:1042D000753FFED278BCFA9B789EAB5D830AE9DF1E +:1042E000225E9DA2DFEE94FDFCCCE047986D3E9FE0 +:1042F0008971E5352F945C34AFC26C3519E8D5A2CD +:10430000DA0D747D758591CE17F88CF47DEDF4127D +:1043100043FB427F95A17D71539DA1BE347085A161 +:10432000FF75CDB38CF6BE6B9EA1BF4D5B64A8A795 +:10433000575C6FE89FE1BBC9C86F727A297F40B1B3 +:104340008607831ADEAF676CBA33CEAFAB32AD9857 +:1043500064CCEC753607963D93D2A2786E3DF93C5D +:104360009E9AF6D2975D5184FA98A7ACF5507E5785 +:104370008A3460BCC82AECBC897733033FFFA72A84 +:104380008EE77AB9A42278632594DE7D5A01CF970F +:104390008E4DC4F3B1A20311F1F8392BE91D972515 +:1043A000E9BF4535F5CB2AF0BDBBFD73C92FD5C795 +:1043B00054BC57BB47E1F94CE1E778FEACB76FD08E +:1043C000E44FA0B7FF53C1E5FD37020D949FD4DE43 +:1043D0000FD20CF17BE79B0AFAEDDAFB0732516E44 +:1043E000D404DE5450BF8E3F17F2441EB263FCF279 +:1043F000FBBDA9F3D0BE51A1D0F84705BF6DFD327A +:10440000E7B78070F3D13ED2F967EB7EBEBFD6A589 +:104410000AD1B7CE47817F1AE261C97C79F9CCC84D +:1044200046A45DE0A306FBE5C62573DE417B0824B8 +:1044300035E931C0478DED859B88BE6F4CB26FBAB0 +:104440002A86F9A9F702D0CBC98029E5BEF654C95E +:10445000B4AF93C15904EF6F00DCD06EFCC60838CE +:1044600071F87D127C9E16FE44FD9C92FB7DA78A0E +:104470009FD3D3A3F0CB77059FDD23C56A919985A0 +:104480000276C2D3E556EB52CC33385AF4D1268C9F +:1044900027B4FE40425B96FDEBC04B799877A0ECC9 +:1044A0003F9287F910A1DE23790CE0B4CAA2AD4790 +:1044B000BD18F0C0B71ECEA5BD2F4AEB5FDD5B3740 +:1044C00080CF57F7493E6485A10367E6D03ED9E027 +:1044D00026D4E3F78CB2AEFD153CAFADBF42E37915 +:1044E000F7419813E5EC8134B2635BF7031FC275A3 +:1044F0003D2FD13D8C3D5BACCDA9F493A7AAF877B5 +:104500001B5EDCA2308CA3AC82F7711F478B8E2A16 +:1045100056C49BFD12D984A1DE134BD11F1F5A6BC9 +:104520006118B7D5D7F75E51ECB7B8FFD7575A180F +:10453000DE2FEC5AC9E3B1AFAF35D338E69B2D542B +:104540005F762BCF133EBCF2DF3615C0B8AFAF920B +:1045500028BF7ED6CD7F3C8AF565B7723D28197F8E +:1045600087F135093F97058D7837024FDB3E1B9E5B +:104570009EAC10F66B15AB41390BE73E7B2CE2CFBE +:104580009D8CEE37369F3F6C190BEB2DDEA4FA3075 +:10459000B45B6D8E6CCC43BE7098B74F5AB55BE27E +:1045A000FC45A37BEF053D0A43BBF15D715EEFE285 +:1045B00079E5E2D68624CC6B6372AC18D7E716791E +:1045C0005CCF5858F37EF423C99CBF54FFD0B53B51 +:1045D000D18FB44BE0A3CEF7AAC0DEDF4F7EE8DE7A +:1045E0007CBC8FFEB485FBC7C68BF14A4B86E62C9C +:1045F0008432BD92CFFF47B10EBDFE9CC07FF687CF +:104600004709BE0BAC1CEEF3D6455B701FB7C8C1A3 +:104610003F23FF9B3FFE97AB50AEF514FFD44BDF1B +:1046200065611349AE85C4791C9EF1EF0FDF81F9F6 +:104630007695763AC785871E8AE1B9B67B64CA3318 +:10464000B4954E1E1BBC881F21744E33DCEF6BEFFC +:104650003F33C79F82AEF757F1FD578B7B7CAC9FF2 +:10466000FB0F801FCBD36BE3FDF4FDEB7E0F5BE90B +:1046700063744E777C894DE2F7FBEFA37196AF3AF6 +:1046800021E1BD94EB2C7E8B03E0FCCB316C29DA6D +:10469000C13FED64744FED38DE570356F272A74AFE +:1046A000F598B8B7F66AA746E5754A603CCA95A57D +:1046B0002F769422BC0E173D18C0EF359C3E2EF489 +:1046C00059A6F2FB8E02F7CEF69B9915DACF1E9013 +:1046D00022E43411EBBFE15C3E0B023FF9B5B81F99 +:1046E000B77ADDCF89CFF9DACECC413B63D2AA537A +:1046F0009BB01E5AF7C739A837FC16E404E257A846 +:104700004F622E18A7E59C93DE5FDD7742417BFE6A +:1047100069D3D01C847FF8A044F7AA421D67887F24 +:104720003E2CFC2B37546671BED13FC944E7E99F4C +:10473000C8ED1371FE0313FF9489FCCBBA4E7BE5E1 +:104740000A3CC763663AC7AD0D43996A8A73390953 +:10475000E3A24FFBD7221F2FB9BD5909935FB6596A +:10476000E06D72FBF59526DD0EB7883C2526C17AF3 +:104770005A047EB532FE9DA0963E296A07BA6DEDB9 +:104780009F45FE8DD68E8B7F0766347CBBD4B29D51 +:1047900071FF865E47FB2B315F0BED2FE37DF5301C +:1047A000E1555A91676CF022FA5D68309FE227ED7F +:1047B0003D8CE225ABCF4DA4F2FDE737D3BD27AB4F +:1047C0007DE841940BACCC447AFDEAB051BF992D01 +:1047D000E876B6D06FD654827D52C186ED13B043D1 +:1047E000BE5CC9ED90CC43CC609F243F27FBC42A1C +:1047F000FC86305CF09914EB9E57D57057652ED22D +:10480000D576C26F06F88D7895BCCF8D959C3E7598 +:104810007A5E76E81D05F5DD505F6A7A5E5A55BF0F +:1048200011D7B36594FCBBAB05BDAFDEC9085EA173 +:104830009D4E82D37B6C67A001F0F23D5807DE5F8E +:104840003F1D08A467C1FBA78381748CCFE9F4DF07 +:10485000BED34EEF6DF12CCAC6EF6DECAAE4F1F3B6 +:10486000F7FB665911CE37ECE474A7CFF7DBE8B25B +:104870006CA49F29962105FD9385FDA73251AF9B1E +:10488000F2FCE26CA4BFD1D6B975A258E7BAFCA578 +:1048900074EF077ECC40F7B70B3916DA105510FECF +:1048A000B7AF6384BF03CFFD6B3BD2EFFBFDE92ABB +:1048B000CAC9F75E480F23BF3F7D302D6282A156E3 +:1048C00089EF24BD6719BC86F4C7E7CD94AF103AD1 +:1048D000F8EE83488FA1E7D2E81ECDEDFD9BCFA077 +:1048E0009C5BD53FF71D19CBA7FEBEF4B07ADDF86F +:1048F000A589F9C5EF76EECB47FEF9BECCF9C4ED3C +:104900007DCF923E7BFBF9B335983FF8DE0B7F9E5F +:104910008AFC2CF4CF67A7221F0BFDF8EC546C0F18 +:10492000FD30BD23957EF2E32AEE3FD1E5A3FB35B2 +:10493000D9E067B959E087BB7B7B137ECF60CA891A +:10494000251407D0DBA794F27BCC537ED1987D73DE +:10495000C27BDD3199F225269F684C5F998097D7FD +:104960005759747FCDA5F947441E82EE1FD9129383 +:10497000F9BDBA36337DBF6E798CC7DF93FD268CC7 +:1049800005AEAEC6F3BE35D787DFF1C1FBEB181716 +:10499000397D676984EEAF87AD473C097AD0B2981C +:1049A000299A867E90FEB428EA43CB62F2A9B40429 +:1049B000BFC86FD56736A21ABF2C68F46324FB41C9 +:1049C000E027434E889FB4AE8D5A7439B500E6FF98 +:1049D000E546A662DC66847FA4F9F3E48749F69392 +:1049E00068B107ACF89EE6E1DFDDD1F54C3CAF03E2 +:1049F00029E87DC344CEB7743AEA8E99E81CBA63BD +:104A00000D560F94FF28DA0F80D80C635E50FFE23A +:104A1000C7D14EEF3E7F5D3AC2ABFBB5450CBF2B15 +:104A2000715A6DB096E27BE73F6F5DEA8DE3C70890 +:104A3000FE3191F3C7617D6014393753CCFBF79297 +:104A400077D3279A84BFE1FF6F790776F55513B9BD +:104A50005DBD9CFB3DB85D9D2C2774FEAB8F1B128A +:104A6000F01EC97FDF21FD05EC5FE2BFA1891AF5C9 +:104A70002BEC5F984D76F16B4BB235C7C8F14B64A8 +:104A80009FC9E91D39BEAEAF85C2FE2356B463FC93 +:104A90003CFF34B444A2EF4B850212E9D9A1164B76 +:104AA00004DBF5F5C496F0B8E0529F44DF0BD1F576 +:104AB0003F5D3F1C6E9F0CEDEEB8BEA8EB85B100CC +:104AC000F78B2EF15BA8FD3A25780BC2E9B7511B95 +:104AD0003D9F32838F0B7CE008FA3FAFFB8244DFBF +:104AE000F3D2F5451D3F93F5C90FFA4B2EFA9DBA47 +:104AF00087055EEAF4353E892E7439B5AB92C3A7BB +:104B00001DE57436CAE98F9541C7E87A37C8E9BB15 +:104B100070FDBB2A19BD3FF917722095DD9D21C696 +:104B2000DF8AE7066561ECC57A5C6F118B515ED454 +:104B300068F2F3B62A4E0FA3B5EFAABC343AFE8151 +:104B400098FFEF45C7FB27FEF7D05B87F53F25F5BC +:104B50003EE755D5FF6822C0D56EEEA0FB51EC5F55 +:104B60002CE4B74EEE1712F218E499018F8F142936 +:104B700026B47B426DDCEEEFC9D25E21FBE4257EDC +:104B8000EFFE7691AF74DB3995CA1EFC8018B67FB4 +:104B9000D94D7E9BDBF69DB0F8E1FDE56BA549E8BC +:104BA0000F5ADE66DC4F4FAE7F6EA21FBC675C2FD4 +:104BB000C515C28F9768387E2B6E16FD213DF91101 +:104BC0008C3DB6A31FE7327C9E70DF02E6592D9E16 +:104BD0005F21FC3B2C490FF8F1C0EBE4EFC1B810AA +:104BE000D2AFD22F515E48E818F777B4F773BEF012 +:104BF000769B44FCE46D919F115A6723FFB6AE4744 +:104C0000BC23FADD7AA744FADE08BDC26F8CBBACC8 +:104C10007EEC17C41793F508E7013E0EC65BD02F54 +:104C200073A468AA84F5D56017E2F74B439A766DB2 +:104C3000015F1F8B107FF11BFC281F1CFB37B22369 +:104C4000973F2FB16CD23B92E22F3DF392E22F4778 +:104C50008F14E03842CF50E13FF41F26EB19ED7D71 +:104C6000272C68177C529C45A91AF6B7905F708272 +:104C7000CCFDAC13FA2515FD4913049CA66DB113A8 +:104C80009CE6BCB1321BE95C3F9FF717F2F37AFF59 +:104C9000F50FEBF1BDA96FC82AF2DB1FBFBEF6E727 +:104CA00005BCAE59357C6F6D3ADA21EFBFB1261DD8 +:104CB000E1F86328F13B4A3F3C29A7F41FAE15FCFD +:104CC00008E45B4115E6DBDE2DFCC632C8B78CB8C4 +:104CD000FF25F9BD1DC21EEBC1EF1B21FE3DCFE339 +:104CE000DB3DE382F3A8FE5031CF239639BE3EDB95 +:104CF0009FA5A2BE57059BC538ECF7ECAC1BE32B78 +:104D00003DB9C19F127D3C6422FC85F7F97727F6F7 +:104D10006B24EF106418FFA8015963A5BCC61C8A58 +:104D200083E8DF85190776A8F88EC2128CBB5689F6 +:104D300038488D9DC938FE364B706B25C65D0664BC +:104D4000DF7A7C47F665E3F79292E3317A7C588FFD +:104D5000CBE871E2D1E23212CE53C3F12CF13B2702 +:104D60007AFC857D81E76F764DEFA0FBAF63B12FB5 +:104D7000F1CF11F194D5686F26C753EEAAD4FB1B6F +:104D8000E3695B2B9E217CFBB471B41F4C1C6D7ED0 +:104D90008D9E27CF3F39EB833CB25FFEF21F9924F3 +:104DA000CFFACF92DC393D9426EE710E723F75BF7B +:104DB00085ECF5D36007E526C8B35F55F2710FF5B2 +:104DC000CF227C3C106B4CC7FE7FADE4F0D9F2DA09 +:104DD00092C5A84F876332CFC766DCAE391093A760 +:104DE00070FD60049C364D4C0127AB3D751ED054C0 +:104DF00081D753ABF8BE67BDCEED95D05A1E3F505C +:104E000005BD859A14E227478BF224DD8F3C365589 +:104E10007CE1F921E2B3ADB7F2F8EE25C717FA0647 +:104E20002CAC3885DFB6690EF19B4BF5D732B482D6 +:104E3000A7C6F9F3769D9F5473FFADAB8AE7F33BAA +:104E40003B26D5E377F1F47DA78023F35E5A9C2FB0 +:104E5000B3FAD2FA2DACB8B47E9B2B529C5F8A7EFB +:104E6000DFB8C47E3FB8C479D353D1578A7E7FBCA4 +:104E7000C4795FAAFC9FF8E7703D39BE991C0F4DBD +:104E80008E73A6BD747318DB364BF70C4511BA99B7 +:104E9000CF35E3F7D3E5ACC7ACC8D7E6CFE0F180B8 +:104EA0002D8DD6C86E291E17D5E1F55135D7BB54C7 +:104EB000EF99307E3F71BC3FD6980D747C7A062303 +:104EC000BBE1B44D7C0F4956C72DA4F353E97B38A1 +:104ED0003DB6D4F1A527C578A3F191A29AFAF3556E +:104EE00053E8FE50CAEF54DC2FF440B58F91BF86D3 +:104EF000C9DAB84534AF360EE5CC9817F9F3CC28AB +:104F0000A3FC3E68772F22FD5973E3FA7688B897A1 +:104F1000735E991BFD744E90B71817B90FE323E425 +:104F2000D757A99F3E5F9797CFB7C3C2248C63859D +:104F30002B795E056BE935C4358E5BA2BF5B2151D1 +:104F40005C632CD2FBCF4C51EF1E373F1784AFF779 +:104F5000804AF19697677CA782EEC58B38C71D2AD9 +:104F6000EF7218ED0C58C71D2FD411FE2E3F34E3FD +:104F7000572DA80F7A6482F3083D5CD85727857DAA +:104F8000A8DB5783682726D81B555ED3687CA92ADF +:104F9000155FDA2171FB37FC336EFFD629BE92C450 +:104FA0007CAA69021E2BA2DC0FABDBB535FE88297B +:104FB0000FE05077A7399A06B2B76E53B582FCBAA4 +:104FC0006E53919DFC4A2BF79B7478A73AF77AB100 +:104FD000CE2DC786282EF16CF23D732F8FBB0E09A4 +:104FE000FCE9C2B385FA1DA572178ADF3133557308 +:104FF0002ABF782BE8FDB8BE153D7CBD7A1CA435D0 +:10500000AACDC2794E1D19DA84656D9B7B16F90D08 +:10501000579DD984723374FEECD1ABC80FA068A938 +:10502000EE0B586BCCB48E6751114178CD95296F3A +:10503000B76EAE4CE7ED6CB5911DEEB430337E9F8C +:10504000D5B990CBB1DAA69C5958674BB2480ED768 +:105050001ED3B26EF6C6ED7CE7DCB5B908A74F8A61 +:105060000FE9FE82EB14FF4D788E9F363EB4FAF8BE +:105070006B946776C3A0313EA4C77B468B0FE9F1E2 +:10508000D950D387867872481E9A837E95BA174E78 +:10509000517C38D427A92E773C6E143A704621F8FB +:1050A0008A7811F457F0BD3A38F6714EFCDE008F65 +:1050B0001F3D87F9B80A7E4F4FA5BCDB1F613E6ECE +:1050C000197E4F8FE7E31EC47C5C05EF7FF07CDC2C +:1050D0004322BF37D47F86E24D3D5E63BC428F479B +:1050E000DC2505B679730DF10AAA27C72BCC766E9D +:1050F00087868E59E8BBE8A1E356E2B3F5FD2B267F +:10510000A03EA67FAFBC1DE30509FEA5F7FD3E1B33 +:10511000DEEF793FE0B3619CA06EE01D4523BE1336 +:105120002DC014A67639A6A0BD8F70A03CBFFE7A14 +:105130001BC2F513FDFA7DFFE3D7FF347EFD8C38EB +:105140005D12FFA80D98E85E79ED31BFEDE604FE33 +:10515000B025C0FDC35B3CC5447F0F048AB356260F +:10516000FAF19BB8FDE69CEBB1253E5F54C3EF0F0F +:1051700038A5D4F70B5EF7EAFED711FCF6756F4A37 +:105180007D27753C604B13E723BABF7F647CC0F773 +:105190009227C1CFFFFECFACF47717069E4F23793D +:1051A000FED10B697B50EFAE6D5A392103EAB5276A +:1051B000D3989BCB23435C617993C96FCB4C154744 +:1051C000F017D0F74293E3054D26E2EFC3F18226B4 +:1051D000F914D5857E7EC3997FCFC04F643F2B45A0 +:1051E0007AD0BE7876B5E41B6023E3073070019B6C +:1051F0000EBB68E27682AFD94A76C127C5155A0E32 +:105200009CD8887E82496C7B0F7E7F7292C7A48275 +:10521000284A1157E0F99DB5428F48F60F207EA02D +:10522000DC4FF60B665673399459CDFD983B51AF60 +:10523000CF8D8FA3BF977CEE5F147269343FE3621A +:10524000D1DEDD54BB05CF2D3CDFC490FF77373571 +:10525000583D09E3B9AB79DECC0E8C53E424C62962 +:10526000783C22393EA1F3A7BA818FE7E0B93FD05D +:10527000CFFD472117F767D61DACA77B26F17572C6 +:10528000FC7CC0357CCF308BF17D312BF773915F87 +:10529000A176FE8787F0EF12B04016FD9D83D07196 +:1052A0004F9703F9C87C798AA4917F7BD8DF8DFE64 +:1052B000A8C5AFB4CDC37CE0BAA5934EE0B92C6DC0 +:1052C000B150DED1E2579AE9FBE3BABCAA5BBA7BE4 +:1052D00003FEDD9AA51592CFA6617B5303B65FFD51 +:1052E00054143D7B6C01AE0EE825761C7A17937F33 +:1052F000BBBE1AD65BB750F8BD5BB85C5DDABFD0F9 +:10530000C23F6E659473878B3E22BBF96C7F1DF99B +:10531000B3B331DEEA8DCB99BA1740FE64C4E5CF52 +:10532000DF2A77BE58CDEDC0CB40FEE07A9C0B79EA +:105330005C30F9FCDDE2FC479327A3F14F941FFC9E +:10534000EFF2840B24575CEE6A684F4F8BCB5FB54E +:105350000FEA6347C7BF87847E95358AFEF580C014 +:10536000F751F335FAFE3E7EEFEDD5FF3DE257BA39 +:105370007DA3FBBF757BE8F702CE7AF9AEC08BBF89 +:10538000395F198562CA7C6567EA7CE51B7A25FA74 +:105390000E8BC8573EA2B0FAFD3998A727EE2544D8 +:1053A00002A4DF1CD9F5EB4D4FE4E0BD044945B143 +:1053B000B3BAF704C9E7D5A0CF901ED4FF2EF74BA0 +:1053C000F5F2FCD2D57DC6FB0F7AE9ACE1F1F646E9 +:1053D000D80FF991451EDF9C039CAE437E25A2B9F0 +:1053E000D12FF41539D12F14D262B97A7E6084CBD3 +:1053F000A594797CED6C88F2FDDADB241FCA83CF9B +:10540000EC27F2F3FCBE4BF513FDBCDA987F7AAEC5 +:105410008ADFFB690E4A12EAA356536015E5F71EB0 +:1054200094D45479A2EF087973B5F0D3EE55381EB1 +:10543000ECBD5CA2BC5ABC1783E7BBF720CF9FDF53 +:105440005BCBF3E775BFAC9E175F19F7CBD27D1826 +:105450003D9F5ECF8FD7EF872EDC698FA27EB1CDC7 +:10546000D2EB423A1CFE4E0FEA22D06E17DF194FE4 +:105470005EE72FAAEB775553BF51F59B3F56A7D058 +:105480006FFCC24EFB73F5A87AF95FAB8D7A39D504 +:1054900093F5F2FF2ABFEC37C43E53F9D552EB67C0 +:1054A00023FABD7889FD7E980A1E5DB6D4DF0B6DA8 +:1054B000AD11FC37E9EF92B011F77BB87CEB91B4FA +:1054C0005F5D41712E0BC5B974FED293C1C7F78AD7 +:1054D000F1F4F2F3359CCF8CF65DC945A2DF5AC9D1 +:1054E0005F553305BF1F6FF49355F71AFD6497F5A9 +:1054F000390DF549D17C43FFBA63C586F629B189D8 +:1055000086F669276B0DF51983971BFA5FF1768391 +:10551000A1FEB921A39FECAA738B92EE1D71FCAE84 +:10552000078C487C6F96F58B867E056DC67D15755C +:1055300018F735619D715FFAB8EEB0717F253DC6F1 +:10554000FD39D17FEFFDECFEFB9857E3DFC1E92F7A +:10555000A1EFFEED68F2D077AEF5FB7FFF09FEEF1D +:10556000D922F072000000000000000000000000DE +:105570001F8B080000000000000B53E16760F8512A +:105580000FC15BF918182EF021F8F4C01CCC0C0CDC +:105590009C40ACC8C8C02001C4FC40CC06C49E0CD2 +:1055A0000C0CFF81F81B10BF05E22740EC0CC40770 +:1055B00058B09BE3C6CAC0E001C4DC40B378988908 +:1055C000B7DF8917C17ECCC3C0700E889FF1D0377A +:1055D0000C061B5E27403FBB7E43ED3A2932F0FEAE +:1055E00006612131609A1447F0A78AA3CA0B8B2168 +:1055F000D8C9D294D9950FD40F00F19321F080032C +:1056000000000000000000001F8B080000000000E8 +:10561000000BED7D0B7C94C5B5F87CBBDFBE92DD45 +:10562000CD26E44900370960501E4B80C84BDDF0A1 +:105630003252C40411828A2CAF10027914A9A5FF3A +:10564000DABB0B2804AADE5851A37F6A17041B2D6E +:10565000DA80D11B6DE02EA208D56A684551AB0DEA +:10566000888808498C8F6AB57ACF3933DF66E7CBF3 +:105670002E89B6FE6FFFBF7BC3AF1DE79B993367D3 +:10568000CE3973E6CC9999B3268383192E60EC1B2F +:10569000FCBB9C319B893136A62B6D573A86AB39C2 +:1056A0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D45 +:1056B0007907C3779FA1306867EC5EBF8BF2BFF0BC +:1056C00017525AEB2FA27A77FA4B287FBBDF47E9B4 +:1056D000667F197DAFF157537E837F0DA59BD4451F +:1056E000692C05FA66458559C98C553D9393B719C0 +:1056F000725B668D4F504743FE15233366017C9FD6 +:105700004AFD31D5BD69E0E8AE7A1A9E9BD449FDC9 +:10571000104EED128E17B3325B8C7A5938CE3B9710 +:105720000878F6D69A9CE4A8F50623BCDB4B00DE8D +:1057300050287085AC39D1E15D8CF03697A8BC5EFD +:1057400072B0263B3A3C0FD6ABB941C04B0F586301 +:10575000D41B83F536DC20F0EBE7ABC98ADEEF78AB +:10576000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4E04 +:105770005D2CF246CC263136AEAB9D3E652CC0701A +:105780009C2AF315121FDC995F7F93CFD84D081325 +:10579000DA0726B19011FA0F24B1E0FA2CA9FE4CD9 +:1057A000AADFDAF7EB6F52A5FA014394FA26D6A0E6 +:1057B00060F9CF518E80EFF7F97329DD28E4E7BE59 +:1057C000A106C6B05DBA393808DADDE3F790BCDC73 +:1057D000ED1F4BE5770939FC7721674121670FA25F +:1057E0009C41BA15E5CC8CFDF95A4B014EFBDE7895 +:1057F000B6D94DF2B598F05419C1DFB077C8F6CDDF +:1058000000FFBE1B569DDE06F46F6B1EE63142BDE7 +:105810007B866AF2C5BC2CB9ABDE3DB34F38170DA1 +:10582000257A97219CBB3D827F2A0C2CA2DEDD339A +:10583000C2F52AB0DE5D9E30BC5064BF774D09D7FB +:105840005B457C56584983BD3B5F763085E623082F +:105850000AD1D784F48579F9EC80EB9456689F924D +:105860009C97C6A0DDFD381FCD38EFDC4417AD3D59 +:10587000D2D907DF332CAC1AE10365F71B015FD3E4 +:105880006C7722D2E5F66B8B98328CB1BEA23C3598 +:1058900050A464015CFB9C2205BF9B6643397C7766 +:1058A00089F2E435BCFC762C7774952762397C4FFD +:1058B000AA8672C8DBE7F2F23BFCC089C15DF5360F +:1058C000019F7DC4EF74FE1DD88AF4318DE6A98650 +:1058D000F713282440BF83988EE9C27FD3A07B337F +:1058E00016DABBF0B50DAEA7BC86DFA6C17194D7A2 +:1058F000F0B15DD82F6321A47D97F465DE5C311F84 +:1059000058773A277AB3A5F24CD593A0029D325F1F +:1059100032B200B02013C413E1E9DB153103E1D941 +:10592000E3FC4BEEDDFC330D95E9A0A547053D34C6 +:105930003A6CEC2FD3C13240A6C3C601321D2C17DE +:105940009C9F0E3B989BE81C8B1E5ABF9B87C8FDF3 +:10595000C65D24F7BBF922B9DFB88BFF39FDD664E9 +:10596000C9FD5AB3E57E6BB2E57EAD39FF58BF4C39 +:10597000F5C064407DA5FD5D28E9B7AB99EF2CB675 +:10598000473D87F349D373A6641FF3D9BBF809EBEE +:105990001463F99170064B7A15E07C8AF5008EF756 +:1059A000FC705C3A3883F470BE16F8B0483DDD0DEB +:1059B0000E1BA81F8749E1ED428688FE99EA6345E0 +:1059C0008EC8761E5DFF39FAFE9D8A1887E1BCFD00 +:1059D000BB7574CDD6E39326F06186F3D183B97499 +:1059E00070B2F470DC029F90725E386EFD382E1437 +:1059F000FD071469FD027A0CEB6AD70EF8D13A95CF +:105A00006709EE04FD10DAF7E5295C07CE355EEB99 +:105A1000B640FDFD232DA1CBA1FC5CB0206881F236 +:105A2000C94F1E75A21D53F1A451C572C33E1BADD3 +:105A30002F6D3B142AAFB2B4DC3901CA3B9E34B29D +:105A4000EDD45DA601C7774AE81416E2F9521BCFE0 +:105A5000566CDB7F23B62F6BB2301BC0AB787AD984 +:105A6000CC09905F76C8C4B04AC5CEB5E6BE905F9B +:105A70001E541A300FF8D23A15C8B3057742FD7597 +:105A8000FBBE6C43FCCF359A06213E67609D70C318 +:105A90003AF192A3257536D0A73CB87B1AB62FDF12 +:105AA000A57840C301FE3B0F6620FE8F281E0BB079 +:105AB00070457D3C7347CC97538D461AEFAA6D4ACB +:105AC0009001BC65AC761AD2B302898378782C41F8 +:105AD0009BD235DFCEF8EBA83F2D5FF108F407ED40 +:105AE0002B1F573C38E44A03F3E13C6E7BDA56F255 +:105AF000901DC7BBD63CD881E3DC68C67ACB820B4D +:105B00009FB2B911CF6DE66988EFD66DE6D2A14894 +:105B100047B6A06828E2F77F65FCEA8C5E1CEFAA16 +:105B20009196ED46C083D943036739BAEBD933B0B8 +:105B30005EB923D6CF72067A9FD6EFA0B97858D730 +:105B4000F72F0D89A43F56D41B99DBDAD58F261F7A +:105B50008123423EF63A88DE1A3F57B9F814D0F84E +:105B6000B92A51F057EDC89F35AC3B3E77225FC84C +:105B70009E7651FA0B583731DD02EB3CD2EF5EB026 +:105B80009FDC64977BE8FB03602761BA15EC244C2B +:105B90001F043BC92DEC24ACB71DEC244C77809D31 +:105BA00084DF1F067B1CD37AB0C7F1FBA3608F6331 +:105BB000BACB1FA0EF8FFB6B286DF0D752BA07F955 +:105BC0000669A33F48F59EF2D753DAE46FA0EFCF02 +:105BD000F89B28BD5DD0D1399115E03AEAF432172F +:105BE000923D6986B7C004F9A4229E4FBD21506042 +:105BF000867CAA0FF24097BE2B430516C8F7ADE688 +:105C0000E5036E6193AC901F10E0E5D9B77B27D90F +:105C1000209F5DCBCB076F0D4C8A83FCE0202FBF0C +:105C2000685768523CE42F6AE0E5C39BD9643BE4C3 +:105C30008787783EEF25EF6407E4F35A783EFFCF7D +:105C400081C94EC8E7B7F2F6E3CF068DEE28EBEF39 +:105C50001E937B31AA9C03CADB5E3503F266F74DC7 +:105C6000A8128F2AA728DF68F252F9FB4ABB578592 +:105C700075BED1ECA5F22F94CF29FF94C947E5F169 +:105C800006A580F2661F95F737C451BEC914A0F26D +:105C900011863E3C6F0E507981A15F01C27FC61410 +:105CA000A4F26B0C8378DE1CA4F25FA8C30BA640A1 +:105CB000FDC70DBEBDA8EFD62BBE32B40F99DA904A +:105CC0008EFA4AB32B77E2E0D0CECC30D33CD8F377 +:105CD00087FC87681EE05F32E64B1F46BB14E01C62 +:105CE0002438268063EC194EDECB632538792F9754 +:105CF00069705E2138B6DEC1D9F3F278199F97CB6F +:105D00003538C7088EA377E3CA7B65A28CCF2B2BCF +:105D10003538C7094E62EFF0693C2AD3A7F168987D +:105D20003E67707D589FD23B7C46BF26D367F46B9D +:105D300061FA7C4CF864F40E4EE36B327D1A5F0B13 +:105D4000D3E72B82D3BF77E31AFDBA4C9FD1AF873D +:105D5000E96332209CACDEC179EA6D993E4FBD1DEE +:105D6000A68FD380F419D4BB71E5BF23D327FF9D41 +:105D7000307DD2089F21BD83F3D43B327D9E7A27AC +:105D80004C1F37E133AC77E3CAFF8B4C9FFCBF84D9 +:105D9000E93384E08CEC1D3E4DEFC9F4697A2F4C59 +:105DA0009F3C8233A677F88C3D25D367ECA9307DE4 +:105DB00026109C71BD83D3744AA64FD3A9307DA60B +:105DC000109D2FEDDDB8C6BE2FD367ECFB61FA5CEA +:105DD00045700A7CF5840F03388ED8709E3927D31E +:105DE000E7997361FACC213853014E4ECF70C6B794 +:105DF000C9F419DF16A6CF02827365EFE03CD32603 +:105E0000D3E799B6307DCA88CE57F56E5CE3DB6583 +:105E1000FA8C6FE7F4A9B278263BD0BE4B649EEDB6 +:105E2000D0E492930D079C9037D99907C1BEA48402 +:105E300076207C582BC92E543D9A9DE2616887CE0E +:105E400070BA3DE8F7316AF6086BA1FD827D57A272 +:105E5000E40FFAD230E916C4D701565BA45D923044 +:105E6000364EB28712BD4952BE4F615FA97E4A517C +:105E7000B6549E567291549EE1CB93F29965E3A578 +:105E8000FAFDAB2749F90BD64C97EA67056649F945 +:105E90009C9AEBA4FA836A1749E517D6954BE5431C +:105EA00082ABA4FCC5F5FF47AA3FAC619D543EA25E +:105EB00069B3543E32F40B293FEAD00352FD312D31 +:105EC000DBA5F24B8E3D2A958F6BDD23E5279C7E6B +:105ED000466707CAFBFFF5058CDB831966B20743EB +:105EE0000E33E5CDFB6C64FFEFC73CF0D3DC7706E7 +:105EF000E5CDCF2E7627E37E1A01C07A5FD0B7ECCE +:105F000042F4F7DC3CDE77A10BBEDF6CF68D70450A +:105F1000F1477854DF3E03F98B5A14968EA9DB8043 +:105F2000699C51ECD72D5CBE3666E53F148890D352 +:105F30009AFE30FF207FD86026FB5593EF8DFD4BF6 +:105F4000D31746F4B3A1BFB964FB50FE7DB11DFB6E +:105F50002B7A11E75995B96330E2A5EFC7923D5608 +:105F6000EAC73AA08CFA790DFB89F07B590694E9CF +:105F7000FAB1966C17DF453FC7705CB1FAD9983D0E +:105F80005E1ECF8072EAE75D5D3F1B0794EBFA89E6 +:105F9000E3E381EFA29FF7CE3B9E9C89F2782E58D7 +:105FA00049FD74E8E866B960A5AE1F3BF583DF17CD +:105FB000933F17760169C0674B4729C9C17FDA58FB +:105FC00000E4C29C59FE6BCCB3B76C6C10F6E38650 +:105FD0007EA11ECBE5FEA3A70D49349ECFE280FF34 +:105FE00011766AD77E3640FBE2A5024516048C6026 +:105FF0007F5B296473C9AEE20137B9216D3A30F095 +:106000006EEC678BC33308F26D4D93CD8BA3C8D371 +:10601000D25AD3A9D648BF88B6BF99C472ABA1FFE4 +:106020005D369794D7D2958A8B097F04E54FC0BE21 +:1060300085C17EE0CFB02F6040AA774D7C9FF60EE1 +:10604000EC6F30DF0AFB1B2C676C2DB53B21FCB4D9 +:10605000276E578248EFCF7EF24313E9F1007B357C +:106060003D15FD6EFC6FC19A78F4F187F15B18E87D +:1060700023E5415D661AD2695F48FBDF8EA72DC11B +:10608000ED48D79A4CA0A9A897CDD8EBB0C9CD4878 +:10609000A26CA6612C63B3AB8BA7A6D12C52FAAF2E +:1060A000023C67358E34410BD6666ABDD163EF8200 +:1060B000CBBCA613481F2BFC4338D714423EA2FF8B +:1060C0006B8BE4FC5CA676E581DF838DD9826FA2C1 +:1060D0005FB7D7847C2D4AE5F8CCC5340F8BB9BFA8 +:1060E000A3C4C5DB6AF8542D36B110ED4F03290C5B +:1060F000FDD18164AA779DB6CFD4E15762B27A8B85 +:1061000080AE250B8D44573DBE6FEE8BF71A86434C +:106110005A73B7095D9B3DE13FCF2797B332DE9FAE +:1061200046574D5E4E09FE9E40FE43FA3EF21FF07A +:106130003E29F8DF25C79CFF5516DF4CE47FC7FDDD +:106140004646FC127C9F23F8BEB456E6FB1CF49333 +:1061500043FD39ABB382EBB17E5D1F89BF307099CF +:106160000EB5774D05B5DA0DFFB7851C5C57B3FB4F +:106170007964EFF565BAF1093EDC28F8305F478FA6 +:1061800039826FF305DF96B1C06D19E43F0A9AD0EA +:106190002F36AF4C61A82FAA7EAAF1AD55E29B4FD6 +:1061A000E39B0EDF1B05DF6EFC09E79B1EEF56C16C +:1061B000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2BBA +:1061C000A0E75BAD38777099D1DE29F616F439195E +:1061D00051FF9AC22BFB9C8CD00BD716154BF9B9EB +:1061E00025F3A4FAF37C0BA5F2EBCB964BE5F3ABCE +:1061F0007F28E517ACF989547F6160AD54BEB8665D +:106200009354BEB4F62E29BFACEE7EA9FEF2E03662 +:10621000A97C45FD23527945C36E295FD5F4B4545A +:10622000DFB06FC8D5285F2F1D3532F4977DEA792E +:106230009FFC759F7A4C1EAC538932370EE5D94DC1 +:10624000F27CCA9F4BE969BF87E4FD8C7F2CA56D6A +:106250004D07ECE87FAC8A03BD9F0876B8F1CDB559 +:1062600035FD70BD81F6E3196B36B6AE0D40FE000C +:106270001E46C1BC99516766A1510CA4BB6F589EC4 +:106280003B8C11E5AD3D94D7A92CD4A77BF98CD6D6 +:10629000E8DFDB958EC119E8277CC3C27646F8EBB0 +:1062A000BA9F57B04CB42B62959F35B0B2C8F3ACCF +:1062B00093467E4EE2344E3A698474A599CFFF9599 +:1062C0007B32263127E64383ABA3F85DC2FD350060 +:1062D0003269C8E71C69DE2FABBBB86B9E33EC2775 +:1062E0009BE476797094F47D45FD04A95DAEE27B74 +:1062F000D708F5CEEE37D27ACD4207065C330CF1E3 +:10630000F39EC4EFAC2985ECAE16BFB7CFC9818C24 +:10631000FDD15F48E9ABFE224A5FF397507ACCEF9C +:10632000A3F44D7F19A57FF65753FA8E7F0DA5ADC7 +:10633000FE00A527FC35949EF4D7527ACA5F47E940 +:10634000697F90D233FE7A4ACFFA1B286DF337511A +:10635000AAE9CF9EE4EFB4585FCFA0FC459133F398 +:10636000AD6C5DCDC42E398B532DEB50CE34FACEAF +:10637000A8B308794895E42111D76192B31ECAEBFE +:106380004C420E63B58F5E8EF2D6F77B9037C6D641 +:10639000911CCC1472F75DE58DA1373E05E52953BC +:1063A000274FB21C6A72A4E9815CA568B83AA64B73 +:1063B000AE661AB99DA4C9D5CFD14E8C626FDDA04F +:1063C0002A62FDE3F611F36518D07E5B25FCFECC56 +:1063D0009D4EF94ED1F77A00D782F5D4602EAE23C8 +:1063E0009DB97F1B8CFEF1CE6316867EF858E3D3F1 +:1063F000CB4B6CBA7B69FF501A84456D54F7725BC6 +:106400001CA7ABCDC00A591E9ECFE61FF3013FE388 +:10641000FEF3E23CDCD7C27795915D15F41447F1A9 +:10642000B73394F1B49EE9ABD53FF5C097F9786ED8 +:106430003E53CCF3B803467EAE1D7AC8734DC4F903 +:106440000CECB7D3D1EFDC31C8EC22FB21D457A63A +:1064500063B0AF44C703833E1B8CE71B9B400E71A8 +:106460007E750E1C9CC0CE231F3DE9F99EE8B9281D +:10647000D8B797F434333C37027A6EC7FB2FBDA5EB +:10648000674F7AB227FD786233A7B353D8A7B1E834 +:10649000DC3E09E65D1439BE475565396603F97976 +:1064A00087467FDC9746D0FF52BB9BEA3FB7EFADF4 +:1064B00001ADD04F67E385098C9FE7905DD7F1A4CC +:1064C000B0DBDD99321F5BFB125C0DCE734FBE3E1D +:1064D00000F7C9B76106E6D993F145BF5253BAE058 +:1064E000F5F61C3ED6B8767FCBF9D99EAACDCF96CD +:1064F00001284F9F093D10737C3DC9298E0FE05C38 +:10650000A5F0F16D3016FD0EF54C787CA3537A356D +:10651000BEAA04335346007E0EB3992530B643F528 +:106520001D54691FE7690DA09F625FBC673DB0A461 +:10653000CA79E6E5901BDBC9FE8C15F536976C3FF2 +:1065400025BA64FB29C315693F751E7AC8E903FCA7 +:1065500056A51B5C2747E13AE715EB1C5F5735FC56 +:106560002A1AB25C76098E9CEFAC550A1B489EDC59 +:1065700009B3A39C9769E9AA74B3EB24AC5767EA03 +:106580007312B0DF337EAB8BAFAF2E17EF37DD1555 +:10659000B9BEAE5C1347F535FC62C1FD67E3C75871 +:1065A000237BD78AEB2294E5C4AE1F939FEA27662C +:1065B0003A976E367D86F6BB2D57B3DF55CA6B70A2 +:1065C000AB1A8C01CB08FCBE4BEA0FDAB9B53366C7 +:1065D0006C175B6E54764AE327F0DF8A07EFB46FDF +:1065E000B5129F7D003101E0B5ABF61A94AB132ACA +:1065F0009FCF55424E2BACAD669F9BC8DD82F2BC4F +:10660000682CD326CCDCB7404F7FF0A289EE69B16D +:10661000AF007A7ED7558125ACC8894ECF458D2BEA +:1066200066E0BAFD8141DB0FD7E6E3B8CF31432105 +:10663000EAA573EC8FCE5111F3758889FB63580D71 +:10664000DFE704E01F8E6F69ADBCEF595627E74BBB +:10665000D9AC54D4B7A55B4C2C08B82FC77D933662 +:106660006ED0BF1926EED758C6AA37E03EFD5E139E +:10667000F7F72C72313513F0AAF88F5FE6A3DFC766 +:1066800063E27687769EBC3C89E35D3E3B68F642DA +:10669000FD771B47CD018D0BED831BC8FE29669E40 +:1066A0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA61 +:1066B00076AE2DF048AE57BCC1287AEE329322F662 +:1066C0007F7C7ECC36C9FE9C7926D9EFA3C981494F +:1066D000C8C109D577B5690CE73BF251513BCCBE37 +:1066E000887AE6AE7AB3CF57CF82F58C546F9E2965 +:1066F00005EB754CA3FD3103791ADA55CFD605EFBA +:10670000460E4FAE57F11F8F3D15007929FFED3D25 +:106710004E06EBE6076A6DAA07BEAFDC799BD30B8A +:10672000E96935E0447E7E10341646A3C796303DB5 +:10673000BC7605FD69423E594D80FC149FED34B98D +:10674000C8CF5F6F0959404E2B1B97CF60C3297F7D +:106750009CE7377E64C47C93CCAFF25FDF93EAE6BC +:10676000F76CB83F8985C8CEADDCF1DE345C2FAA6A +:106770005807C999BE1DF6FF7912CDEB85E684EE68 +:10678000E58027F913AAC42CAB6AFCF9474627E633 +:1067900065F92813F62AD209F7F9B7991CC9A7E2B7 +:1067A000217B09BB04E7B9460F16E476EBFA47EE06 +:1067B0001B7E1CF039BBE345A73234523F7039EBE6 +:1067C0006C58FC2BAB21B61E6903398CB48F00309A +:1067D000B57337097BBB99A72B4D2127DE6759B9C4 +:1067E000CDE40109642B1F3332BC07C0DEB004D1F5 +:1067F0002FBAE2B1E75F1B0F745FB1DB943C830FEC +:10680000C7AEA476F1A50AFEB726AF8B0FE54F3CC5 +:106810006F760FE3DF6F49EAE2C78ADDFBCD6C5884 +:1068200077FA4D6ED86F6EB547E14BC3F169B8CEBC +:10683000AE7FE4AF66F4277EB04F616959DDDB9728 +:106840006D7B9ED63BA413F151F029CCB76EFC0AA8 +:10685000CD7C6634D573A11E8CC5AF6542EF823CFA +:106860003FFE0CDEFF79D3E2C1F1973D7E9313C763 +:10687000F1BE5ACDE5FA97B7A5E2FC2E3305525D7D +:1068800094F2EF650FFE88E46DD9911FA592BDC00B +:10689000BC1906D2C5810C1CDFD2ADD7D2F84A99FB +:1068A0008FE4AEEC97C622BC8FF8A9CA0A77479945 +:1068B00017716685F0797F3B183230BEF7717F899A +:1068C000FAEC8F46BA17C5D80FE9DED88FC45861E5 +:1068D000E5A3FCA756CEA7E3424FE24496E475C772 +:1068E000C616E4CF99FEDE343CE7003A0404BD94BA +:1068F0006F00AEF1C8D434CE1FE656F3453BD0EF5F +:1069000093F13BD66F31796DC3A576421FF2FE57E6 +:106910008BFE01EF385CAFDE4F8D6EEF8D11E383A0 +:10692000BF1616215F11F39BCFF71D9BF8FCD6E62F +:106930007BB0B810CB3F7995CF1F6C87EB03E01588 +:106940004AA3F2FDB315D207B0AF8E36AF7798C425 +:10695000BC96CBC152A4F51EF0569584483901F877 +:1069600049447FDA07976E817611F65715F647F599 +:10697000CC5DDF23D68765420F98CC30FF2FEE9A8F +:10698000FF6C2B9FF73DD9932B4DC1871FC0F9FAA0 +:1069900086C51370E37C3515E1B83FDC75E0B5EBD7 +:1069A00040AE3F6CD0E6A9AC3FF5F3B46CCF1816FF +:1069B0006D9E7E6887FD55B4790ADFA3CE537B2B8D +:1069C000C9F1F7AD3F35BA0D35CB7A13F5E033EEAB +:1069D000D8F4D3EBC1DF9BDC4447BD1E84BF5759BD +:1069E0007E77B9D3E44D93B3F2DF545C80FA262C62 +:1069F0008F9ABC85E5519337FD3865BAE9CBFF2AFC +:106A0000F4CDF5D6C26BD02EB67630DAAF14CC36D4 +:106A100006719F6CFD84D17C9F74433CE5E71A5B53 +:106A20009F409BEFAD8AB9C3701DBF9E054CFCDC37 +:106A3000BCD64476EA57DF7C3311C6739DA0EBF5D4 +:106A400040E6AB800F25AA128A033CE7A92C909060 +:106A500084FE62859D88C0E3FA32398F7F97A576E0 +:106A6000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8488 +:106A700029ED2FC0708E90A3E2667E4E51355A09E3 +:106A800066D3FC6B558B22F6098F99B99D7164CA48 +:106A90003563907E05738725907CD70EA17D609528 +:106AA000D05B9D017702EAF3CEE61CDAF7751E5A39 +:106AB000ECF045D15F07849C3D2FCE59DAED4AAD0D +:106AC00011E4BD9D7590DD12B0DBA2FADDEACC06C3 +:106AD00061EF08BEC19F11FA2F1172380F9A26E498 +:106AE00045F06DF6551FA8CEEE7CC0BF1311FB8696 +:106AF0007F94BE28D748DF03B6D6694551FC338F53 +:106B00000A7D7DD9B35F98719D9BD25CA0221DA7A1 +:106B1000D88D92BF63BB365F87B2A188D765CF2E71 +:106B2000BF630CC871D521A3C706E3AB6AFEC8ECEE +:106B30008BB27FD3D313E1A3FDD86AE6F6F15153AC +:106B4000D152A4EBD16BF979EE9FCC9E8A6878CEB6 +:106B5000B6723CE7B1A24F472BFF7AF42D98EB08B1 +:106B60004D027A74DAF9FDE4EEF2C7E77DA74B092E +:106B7000AE55500E8D3C9FCCEFFF4E63BE3B262A98 +:106B800034DF2F8FD45F054DC58FE17D96CA66C572 +:106B90006580F24AB5D58C725CD5B45B45BBFC0709 +:106BA0006EFECE82A9D5C36647F8B75ACDDC9F7476 +:106BB000E06FD7CD47FA7E3CDBC2102FEFD08F9C21 +:106BC000B8DE7FDC3C8AE641AC71FDC1EFB9660AF4 +:106BD000FAE3CD5C9FE9E5615A72BC94BF7632EB73 +:106BE00087E7BC97595A6FF244E1DF3A0B9FA7BD84 +:106BF000D66FD6FF61FA6D22E8372ED7A648FD364C +:106C0000DDC2E53E42BFA545D36FABD6BAD3502E09 +:106C100056EDCD4943BEAE3ABC34259A7E7B41EC5D +:106C20006B0F8B7BD2EDFD40BF8D88D06FFD40BFD9 +:106C300045F1838FB66876670FFACDFADF33FF5ED2 +:106C400040FD1665BC5708B9D3F45B61F35AD26FA7 +:106C500085FD8CD27DA4CB2CC28E8BA9DF16DE7372 +:106C60002DE54D9EF828F2837445FD7658E839EC01 +:106C700007F5DCCF2CDF4ECFCDB3727C7BD473FF16 +:106C80004D74D6F4DCAAFE0AD92FDDE590EBB95598 +:106C9000595CCFADDACBF5DCAA415CCFE9F5DBA4DA +:106CA0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF39 +:106CB0005762F258A1FE0CB7F6BEA07A4CA4BEFBF8 +:106CC000992586BEF380BEB3F7ACEF5E417DA792F7 +:106CD0001E1B88F3482F1FD307C64BF7D58E7E7136 +:106CE000EA37BFC5F9F20723DD077ADDC0F743FBBA +:106CF000BE38350AE7DDCB880FCC979D42FEDAFC23 +:106D000063499F4E1ECAE77BC5A1385A272A1B1527 +:106D10003EDE5B94A01BD781BF7D4EFBE4F97BF97F +:106D20003E79AE85D383FDD8C8DF4500091646C835 +:106D300043C9E7E5E4E72B519915EDD70587A67F11 +:106D40008076EB82CF6BC8DE5D80DFF17EC5EED64C +:106D50000D99D0EFFCE50AED3798B80FA1DD97B893 +:106D6000BE793FDD5FD1DF83D0F4F9FC6AF9FB0225 +:106D70009D5D7F408C13EC59A20B7BC518D53F77E6 +:106D8000404F0F0F1F7FC56A6E1F87E901F4712BFB +:106D9000DDE9011C9DB130B56BFCF39F8471257753 +:106DA0008D4BA3877E7CDAFE6481981BB1C6ABD184 +:106DB000AFDB78357AEAC6FDBC45D84517B36138F4 +:106DC000CF5E37F8EE188372F17B183FE03367DE51 +:106DD000A0B4483DFCA2D0E757F98E4F497523BDBA +:106DE000F8FBBBEBCA763F9F0AE3B8DA9B9587575F +:106DF00011AEFD9BD9877E8403B60ED26B9A5C5D83 +:106E000068E572FE7701E7685FD7145A3F9A141756 +:106E1000CD97904E6F897B6155404F9C8F554D6249 +:106E2000BD0179C3F9364D5B7F90FEF09F573573F6 +:106E3000FA57552B44FF99ACE320D2B73259F1846D +:106E400000D4B4A6DDB7E13DAA176CF01DE76D993B +:106E5000E2D9CEC961CF488D2A976A34B964D54347 +:106E6000C8AFA0AD830BB05E12BE17793D05ED1320 +:106E7000BDBD7199A5E528E271D98F4D6C1BEB6EF4 +:106E80007F68FCCE857FDF44BBCFD383FC0E12F638 +:106E9000E50B486F3BD2B5C38C725F15E2EB8656AB +:106EA0005EA5BAA7107D347A37C1BA309AD31BDFFA +:106EB0007DE9E979B5964779C6FACD8A09DB5F099C +:106EC0007CE80345930D5F1CD4E417DF89E9E98270 +:106ED000FBFF8C88F98E7A29F2DCB1B2E908D16522 +:106EE000FA6A30AB22E88EFAEA7CF4E9361F9AF6A9 +:106EF00047BD07F56DE7C38556793EECB375BC38E1 +:106F000002FD5B7B15D207AC3951DADF5F61E5FB2F +:106F1000A603361FC96DC76113DDF7D6EB8DB182AD +:106F2000FEB89F887C0737190782E7BB2E1B7B576B +:106F3000C3239BCB4FA4BE7EC1E6233EC5823F4DFB +:106F4000C08F652F85F1C5FEF03CC52DF7A75F2FDB +:106F5000343F4F4FE3BA46ACF7DF755CE1F349D6F7 +:106F60006266DC9FBFDB1C71CE3447F8F9353F58B1 +:106F700044BD999631B1EBA1BF2504E37E61D743AF +:106F8000E4D73DF7E8F19928B72B7E676456E073A4 +:106F9000DB2E070BF17B14665C57CB1B8D51CF4565 +:106FA000185B4FF8ADF8AD83F44AF91E4B7006B488 +:106FB0002F7FEADDE1E89F6A5BC7F54BE051211FB7 +:106FC00081D6E1785E5EAEF2F3623DBC1F0B79398B +:106FD000FB747C09EA47A59EBFEB2C6F986BB2440B +:106FE000ECCB2BF1C08DD7A37BC8814714F28377FC +:106FF000C76F2DAFF708D77BE54DA620BE0F2DAF8D +:10700000DF46FBD9AAFA8FCC68C74DFEED63644713 +:10701000543519653F61BD3164213FA6F138A67A28 +:107020007F5D656305CDC7CA06E10FD3F98B56FCBA +:1070300076EF530120CD8A277EED443D73A665A7E8 +:1070400093FC70F5DCCFA6DAD5E87EB89EFC6F0D18 +:107050009BA2FADFCEE07FC0FCDB6A95FD6FACBE81 +:107060004FAFCEC1573CF6E983782E7476CF870FA9 +:1070700022DE2BBFFEF8C19FA27DB2CFE6C2F5AEE5 +:10708000EAD1A3E457D7DA3D25E655DB23BF7EF8E6 +:1070900001987F6D6F58E8FE55DBDEF707B8619CFD +:1070A0006DBBBF4845FFE5EABD5369DFB2FAC9C908 +:1070B00069E7BB47827219ECC579889E0F071A8D64 +:1070C0000CDF419E3B66213B23EC476DA8E07E69C7 +:1070D000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52F3 +:1070E0005CF71A4D1E377D177EC09EFCA6AF023F8F +:1070F00047F4826FBB845F5CC7B773F81FC09F3FC4 +:1071000059657FF3A78D4B7FF5009635F689E937F2 +:107110000DF5825EDAB9D636ABF71D2BCE873DBFB3 +:1071200021FF34F20B6C6ED6F6D8A703D0DF70DAED +:10713000D47123DDBFD86BA17B42E57B5FA7F9D17A +:10714000F6E4113A2F62E25CA98D85FFF83980D808 +:10715000CB54ED70707FABA03BFA63DD4EFA2EFC92 +:10716000AE5C6E357F6C2C3F6C1F9BB8072ECED962 +:107170002A76BC65663ABFB63216F9745C3A17D403 +:10718000C6AD87E7423A5C12799E10CBCF2DF468EA +:10719000984FFC1CA16D9B385F089F1B30D62F0FAA +:1071A000EFBFF3F3EEAAA0F23A8B321FB5F304A7B8 +:1071B0004D371F83BD3B47E819DFEF460FC5C6F7C4 +:1071C000AD1A5DCE7E155D1F0FB129E2FD812FD76F +:1071D00016B1EE2C10EB4925D08BBF27E3F89E1596 +:1071E000FBBBB38F1A83B80FDED07080F4AA7E5E2B +:1071F00057B2E8F143C6DBB83EA96CDA3F1CF5CFC5 +:10720000D9679F26B9ABDC75DC1C003807EB9F30D3 +:10721000B70EED9273D4D7C1087D7DF6F1FDC3F9A9 +:107220003907DF47EAE15F21E05735CBF0AB767DE8 +:1072300024C15F116830BBEC3DF77346F5CEC5F154 +:107240009E6931515C94330DC6C268F14A86622052 +:10725000A9942E3A6D70F0F771C62433D991AB1D05 +:10726000638F2524636A76E33E7AFD5A7E1F72FDA2 +:10727000CF3CE9C897F58973E81CA856474757B231 +:10728000AB00F7D7AE2945A351ACF47A20D16B906F +:10729000F05EED284CC3F7DCB70A7B84A91E7ABFE9 +:1072A00067744E2BC471185D06972DEA3ACAE199AE +:1072B000EC45142FC2E492DFD37DEFF11FDCFDE437 +:1072C000F80F817EFF68FC07467130FEDFC77F083C +:1072D000603FFF02F11F42E4B7D1E23F247FCFF1CC +:1072E0001FD63239FE83E06738FE83E0E7FFC67FB2 +:1072F000F8FF2BFE8331EEEF53303E8316FF21253E +:10730000CE3C3532FEC38571095323E33F8C8B4B52 +:107310009F1A19FFE10771595323E33FCC8FBB68D4 +:107320006A64FC87AAB8515323E33FAC8D9B48792C +:107330002DFEC3DD7153A7CAF11F664E9D02F9B63B +:1073400038DFDF71BD8A15FFE13D9C2C637A8EFF2B +:107350000070CC716362C77FD0C38915FF01E02440 +:10736000109C18F11FBAE11323FE03C049273831DE +:10737000E23F74C32746FC078093457062C47FD008 +:10738000C38915FF01E05C1497123BFE831E4EACCF +:10739000F80F006714E11323FE43377C62C47F00BB +:1073A0003813094E8CF80FDDF08911FF01E04CA570 +:1073B00071C588FFA087132BFE03C09949F8C488C4 +:1073C000FFA087132BFE03C0994BF8C488FFD00D94 +:1073D0009F18F11F008E8FF08911FFA11B3E31E233 +:1073E0003F009CE5042746FC073D9C58F11F00CE5A +:1073F0002A821323FE831E4EACF80F00E7A7042752 +:1074000046FC876EF8C488FF00706E253831E23F75 +:1074100074C32746FC07807307C18911FF410F27FA +:1074200056FC0780732FC18911FF410F2756FC07B7 +:1074300080F32B821323FE43377C62C47F0038F530 +:10744000248731E23F74C3E7BBC67FB085062A3983 +:1074500014FF81E24486E33F247FEBF80FCD88EFF1 +:10746000FFC67FF89F19FFE166BBEFEB38F2837E22 +:10747000B7F80FB6F86F17FFE1667B517C3CEE2F33 +:10748000BF65FC87D4F86F17FF01FA498F1F13BB44 +:107490009F58F11F7274FDF414FF01FA1974DEF1A4 +:1074A000C488FFE0D1D1EDFB8AFFF045DCF9E33F72 +:1074B000FCCBC559806D0A9EFF149328B27F99B802 +:1074C0000BD7C6FF93E32E90B1F0AF1477417BBF8B +:1074D000DF60C2F5EA4DC1F7D7845CBC25E22F1C02 +:1074E0008B197F217815F94597CBF117A60B3ECE66 +:1074F000F3C9F2309DF1F386E953B278BCCC325D2A +:10750000FC855CF9FC7A86EFC81400C7AEF2C8E3CC +:107510003822E46166C947CF217BAE1E1B3DFEC207 +:107520002CC18F621D5DA60BBE158BF47A7C920276 +:10753000F23CA3EC888A749DE96E55C9AFFD038DBA +:107540007F6E897FB3055C3DBEB304FF665DC9F9FC +:10755000A7C7FB55E49F13D2B251C43F3DDE7A3C2E +:10756000F5FC6791FC8E889B51C0E4B80B93AD721B +:10757000DC85A92E39EEC215E972DC852BDD72DCC3 +:10758000851FE4CA7117AEF2C87117AE1E2BC75D16 +:1075900028F6AED5C57DD8A48BFB70972EEEC3FD23 +:1075A000BAB80FDB74711F1ED1C57DD8AD8BFBF04F +:1075B000B42EEEC37E29BFB8E6B0547F69ED112921 +:1075C000BFACEE0DA9FEF2E071A97C45FD07527932 +:1075D00045C34752BEAAE90BA97E6FE33EBC2ADE33 +:1075E00003BF26DE031F13EF81DF8C11F7E1AF3FEE +:1075F000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC86 +:10760000838D15F7215C1E23EE4357FB6F1FF72177 +:1076100025F99FFF0E3FC7CECF3727C44FCAB1A76A +:107620007CF777F8D716C9EF99E796C8EF9973EC0E +:107630005C9FCFF3C9EF9AAF2F93DF3597D97CD9F1 +:1076400088873EEEC384786F8E1DF5A5789F1FC294 +:10765000F7A9B0363E8BEF53217D0EE33E407A1002 +:10766000E33E407A08E33E40FA7B8CFB00E94B188E +:10767000F701D29731EE838A712302226E448D88FE +:107680001B512BE246D489B811411137A25EC48D3B +:10769000681071239A44DC8810C139E13F44E949FC +:1076A0007F0BA5A7FCC7283DED6FA5F48CFF34A583 +:1076B00067FD1D94B6F93FA7B4B7712334B9FC3305 +:1076C000DA0D66EC9FCBB126A733EC033744CA69C9 +:1076D00091FDA20D28A7B1E245CC459AA6C48E170C +:1076E000112E8F112FA2AB7DEC781169A3BFBF784B +:1076F00011FF16CFE5F51F8D1731BF5A8E67B060A9 +:10770000CDF9E34594D98A56A35C6AF2F86FF1FC8F +:10771000BCAAA77811DBEC8A58AF812E6877015D8F +:1077200068BDEEE1BDFD738E8773713FD1997BD14A +:1077300079E31CE8E52236BD795C83EBBEE73811BE +:107740003DD155ABFF66398F5FF06FF1E78F5FD0AA +:107750002D4E444FF105067D467AB2B771227A5A12 +:10776000177AA2E7ACEF394E444F7AB5277DFAC7B6 +:10777000E99CCE13E2CF1F8F231C17CEDA72901A2A +:10778000BBBC34B555F10EBC60B68BFC27EDBBC459 +:10779000BD312F73BB52F93B75B437DBF7240C674F +:1077A000F47EDDC5BCC09F78F15DD9B57F3F9EA753 +:1077B000DFEA64DEC4248A07EF36E6E03E6CA415F7 +:1077C000FD29158D1FBDFC3B806B6B36D27DB276DB +:1077D000C0A185EC3E6F22F22D9EDD4EFB743CE392 +:1077E000FAA64FE47B66DDEF37609588F39BA946E8 +:1077F0003BED9B3AB7F27B9E4676F17D1347D37DF6 +:107800006A167413FFC84E5D21F0ECC414EBFBAC98 +:10781000643F2E3BFC447E88F1F3CA48BF419F423F +:10782000D94F5367730EC777952CE06D41FB7B8969 +:1078300080975224FB6F3E5C547808CFE997F84A52 +:10784000E91E425A89ECCF61E2DD386EC7C2F7E526 +:10785000009FD226853DA0747F475ED67CD706DC8C +:10786000E72C0FEAED6F968B7256CEE23CB8EF5DD7 +:10787000512F973B1CE23E879DD97B45B7D60BEF36 +:107880009B987C5EBA7942587F9783EEC32E3BBCAF +:10789000D88CCCB2A4CB74B3B965BAC5E7CAF4D15D +:1078A000D3CFE191E9A3A75FC258D9FFA5D14FBBC0 +:1078B0006FA832715F34C8EF91767B87DFB48DF0AB +:1078C000D4D34F4FAF510E714FA28B5E45D6545259 +:1078D000F98467861A22F9D6CF874C7B48C1FFEE20 +:1078E0009F1C5C4BAD3C0E15F5563A07CD9425BC5C +:1078F0005D3CCE078C2BCB3C341F70478FFEDD7870 +:10790000F66721F7EFB26F20BDA9F8B9E38BA07439 +:107910002BCADB08FEFB0BE4AFD27E3781795CB863 +:107920008F6AF05BDD4B543C1764EE2503F13CD0CD +:1079300045E99DE2DD6FFB5046FBFE86D027A97826 +:107940008E76675EC74CF43F542D6545B87EFDC802 +:10795000C9DF5D6C12E90827F7CF6C2E3230EF6873 +:10796000FC1D1E635041BFABCB7BF872B4479B4DEF +:107970006E7A47ECEA78F97A2A1F45EFA3330CB503 +:1079800023111FA84FEF6BDB9BDF752E8ED0C36DCD +:107990004D770FC1FBC5F71BA2BFEB2D7568EFDB61 +:1079A000F8FD8E115D71064A1D63281EC19DD9D058 +:1079B0004F657127F15193CB0982FECF954E27FC7D +:1079C0009E6C56DCE8AF9B66BCE107C300BF714705 +:1079D00055AEBFC4BDEED1A2FED3CC938EF88EBB04 +:1079E0009429387FC6BDC13C0124717529DDA7FBF0 +:1079F0009D73DA21E4D7946690279C0F67ED1EBC37 +:107A00002A3FA645BE2F9738C57700EF175E728CC8 +:107A1000913EBBE498AABF1F63C4FDFEB856F9FBB4 +:107A200004DDFE739D26774E968A72B7E52B23E11F +:107A3000D5DEC13CEB006EFB92BE746EDBFE09230B +:107A40003BB1FD2B6361B4FB25773BB8DFEB7E33A5 +:107A500023FD7D7FA99DDE393C5B5A7E01DA179FAD +:107A6000FDC47741343F65849D96C0DF9F7B13D86A +:107A70005894C35B154EEFDA8CA228EB9626779AC2 +:107A80001C6AF297511AE78B765F33D9C9EDA34987 +:107A9000A5B98A19E5679FC290AE6DEB00AFF3AC54 +:107AA000DB01B62E13F1A96AFA98EE61599B95A8ED +:107AB000BFCBF384C3C9EF03AE0BACC5FB1737C311 +:107AC00024423D9561AECD8A063FC0B6905DFA80F6 +:107AD000C3CDDF0D58451C21B53603EF23B4354D1A +:107AE000BE7203E0F900CC07E4EFFD260FE11DA80C +:107AF000608CEE930A7F5DBF996CDBE608FB77AF85 +:107B0000A3E030CAED6107B71BFBF83C0AE2EDF9D0 +:107B1000FB5F9D08BFFD730BF1AFAFB037B57627A4 +:107B20001D9C3E254EEF016CCFCA9249F9787C4EE0 +:107B3000F7923EE837077A47B1AFB4753DC9C7E859 +:107B40007C22C96E089272F27ADD2EE9BE7780E659 +:107B50008D360F584861F85E5FD36F4AB31272805A +:107B6000DC8FB6DA4378FF2CA90CC69D8CF13CACB7 +:107B70001C5E8B7A56F66B813CE6A371CFE8BD3F65 +:107B80003A5211BEA6F7347D796B22D747B7DEA5EE +:107B9000523CD0AD6AAB0DFDA9595EF7240C4D9354 +:107BA000A4BAE95E4AFF323E0FE3737E9918B6032A +:107BB00060928FFCDAB820DA7BA60C94A714A49705 +:107BC000EF4307A4C30F753C8BE682C7C6FAF0FBF0 +:107BD00053424F08BB669A58EFC6BD67E0EF284393 +:107BE00097B3C8F7457A3D0172FF27FCFD9EFBDF86 +:107BF00053294E68583F944EA3F58919871E403982 +:107C00009BF022E3C751423FB8E01FD2E792977C36 +:107C1000EB118DEFAA17F4FC66216B388F3FCD3640 +:107C2000EA10CCB7C875D629D67BA1476E2A1EB8F4 +:107C30001EE797264717DCE231FA22E8A86F1FF605 +:107C4000532AD6F077770EEA91978C783FACBD0037 +:107C5000F80D747912E70BD03BF193E095C8F72D3E +:107C6000CD57D850BE6F0D4D72CD803689D6226269 +:107C70005E22F3923F270FA8837122D69350C07ED5 +:107C80005D2DCA72A6E03DAE42C9DFA3FD2E1E0CDB +:107C900094F812E603C871E43D564D3EF5F2A8C9CA +:107CA000EF7ADC60E1F91D7ACC21352A0DC4200B76 +:107CB000DBEA423DABD997EBC3F65C22ED33560BC2 +:107CC000BB68BD7D9A95D4C0FE645ACF57E3FA04D1 +:107CD000E35F9DC2681E68E3D0CB63D5E706168CD0 +:107CE000D81F54A91D748FAFEA73330BF6C171FB13 +:107CF00026E1B835BA8C1474D1D321DB29F69B82E6 +:107D00001EB1F1CC77E1FDD944AB976D243C27D16E +:107D10003DE786509E15D7DBDB7478F602BF39D17C +:107D2000F053ED31F013F1DB2630DFEF5A415EF313 +:107D30006FAACBE0EB057B353D827FFA7933B6A99C +:107D4000FA803962BE687E5DFD3C19D1CCAE41BA85 +:107D50008F0BA90CCF5F7B9A2F9F88F156C5737A42 +:107D6000B5CFE9188CF2B943F5553BC9BE6835600B +:107D7000DCDFF6A719CD67CFFE934E8A6FD4D2BB56 +:107D8000FBE99A1DA5D94FFA7A9AFDA4E95DED7E2B +:107D9000F876A7CF8FFD2B4D209F30FEF52EBE2FFE +:107DA000DAEBF0ADC3EFF130063C4A62B9A12CFE2C +:107DB000FE5596FF58F21EAF93E706A013FD4E1630 +:107DC000E8FF414A773CB4FEA73813F9790BCC663B +:107DD000D443FDF219EFAC92D1FDC97EC3990FD700 +:107DE000A77E79FCDE5F50ACDBDB84BED5D2BD8ED6 +:107DF000A2FB117F93CA0296BCEF8E37A28AF7B11D +:107E0000B73BBDF7A1FC590BBD348E4C17F3A0FD59 +:107E100099A93628F86E3269A55BE1F7B059D73BCE +:107E200026809739C35D80729289FB68ACDF1C3D68 +:107E30008ED6134E9364677A58384ED513D82FD800 +:107E40009907CD80779F195ADC2BEDDCC6A3209DC6 +:107E5000DA1C7308E9B64F156E8F27727AE9F703BB +:107E60004878C44F15F9DBCC4CB525B1AEDFE13411 +:107E700058C98E8F679E06D44B2F3BB3C5B9A8A7B0 +:107E800006F3FFAE7658138776C9F19D13677954D0 +:107E9000A8E2BCB47338EE99409E0F23BE6D133B2D +:107EA00007DF4AC4E818C0E5C66B94E2E268F46FE5 +:107EB0003249F4B7E13E3B520F3ACCB48F6C53E2F7 +:107EC0003C38CFDA962B1C4FC52AE206A9F2FE5F9A +:107ED000E8234DBF763AB308FF7816A07D00B37A49 +:107EE000AC748F5DE08F7115C9AFB3373EB81DCF4D +:107EF000A3747114F57116272FB6D3BD8B2D7B6D2E +:107F0000B42FED2CE2E7F39DCD16D2BFB1E6691A8E +:107F10002A83F3C40B04BA7520DDD24CD589A8F7A7 +:107F2000D2E6F3F9AFA7473B0E14F73B7F3005A32A +:107F3000BD57D7D2F4F4BEC56897A567A453AA7DF0 +:107F4000AFB3AB51EF611B1314294EDF10E851ECB6 +:107F5000738C09F0FD9CEF8FAF7959D7BDF6BA3815 +:107F60004EBF4EDFF8848751AE40E0E8F704B473AB +:107F70004DB19FD7E22769FD6CF15B8B31E467DD82 +:107F8000A2E9365C075298F7CA793829B798D84ED3 +:107F90006A972BDD77BDD73FB218DF276726F07BC6 +:107FA000B49F6C994AEF9953D93ADB60A043699129 +:107FB000C183FE80738BDE741A407E1665B6E4A31F +:107FC0009C26987C990963C87545FB8D6525E660FC +:107FD00008E8955C070A81E818B892E8B8D010D58F +:107FE0003F9C9DC0F79D6F89F5243D7D40F19251E6 +:107FF00091F97E44574D8E60FE642C19DD150F13E8 +:10800000F87951429479D06E624DF85E42D347C9F7 +:1080100042CC347DA8C97132CE0FB4E38A403F49C7 +:10802000E77D5035B5EBF70C95E617BE403BD679AA +:10803000E924D237306F6B48CE73B9FEB4A13E8BC2 +:10804000F05BB5EF7DBD3FBE637AFB671F3BF05D24 +:10805000CB5FD40E07EAAFD3B7FCC98171C0DEBED7 +:1080600085EF936FD4D9FF5709F90826144D41BA0B +:108070002EF0FF3D3FD25E636BB8FF7979507EBF33 +:108080008AF7BF23FD80150DFAFB00011EA74CFCEB +:108090003EA79E0FEB041F96EFDA66CE7463FFBE19 +:1080A00039D8FF69B1BF39DDE8A0F7141A3E8B76E5 +:1080B0008D34A3CDFF97668B78A7D762E27AD93B40 +:1080C00003DFE7F804DDF4781EDC174FF096DEC31B +:1080D000DFAF2E84BED6805EF435F3384AFA712CB9 +:1080E0007DDB3D0DFDE84B3729B48FC3FAB7C03AAD +:1080F000E15BB391DEF1E8C7B93020FB73F4F11A0C +:10810000B5FDC032C1FF25F86BBC3951E23836F3FA +:10811000F774CB74F645E7A19C781CFF9A0461675D +:10812000E7B34B306EE79E43D909D1E26168E95964 +:1081300071DE8FF7FA313DED67944E4970F3785D4B +:10814000CD476E46B9AA6CDA4DF111F705DFEB3376 +:108150001EAA14347F6144A12A10F6D87C618FEDE9 +:10816000615C6EC08EDE8CF27FF9E73A3B5A8CF38D +:10817000064DEE0F2591DCDC80E31A8EDFD54FA291 +:108180008DEBEE04F9FD576FC7A58D471B9F565E1B +:1081900021DE9FEBDB69723E45C8DD921DC51BFAEF +:1081A0000229D6EF7D7F8088234771B63439D2CB40 +:1081B000C932C1B7B03C34DF41E3D2F806F29E2E9B +:1081C000DE25A5A33FA327B9D0F3BFCDD43A00E75E +:1081D000AB9EFF6D31CE7DB627F0738D256EEF34EB +:1081E000F4AF8079B8C115613F9C566B0FFE14E760 +:1081F000D10E2EC791EB22194B2F9A689D5DE57029 +:10820000A725DA05DFC6E1FB454B00EB69FD9CF2D3 +:10821000D7CC1A48E78DB5B3060EA4771B946AE550 +:10822000A5F77FEC44FBB43D97917FA1CD21E37B83 +:1082300004179B319872FAAF545BBE7E0B75D08EDB +:10824000168ADF7AEA2BE19FF8CA52186D9C6713F1 +:10825000B81DA8DD3FB951CCA31B9BF97BBB455B87 +:108260008BCDE4075823DFD77849714DCB84A6BE68 +:10827000869166E4B39E1F4B3D57D03BF06E7C6108 +:10828000B7135F97EADFB5897B4C0B847CCC74B95C +:10829000859DE6A377C44BEA8C64DF2F7357D3FE2A +:1082A00066851AFD3DD61897E1BCE3D18F6361A3C3 +:1082B000427A4F8FFFB21D6B37F465387E3EBEEEBB +:1082C000E308F5233D23C6C95A2FE7EF32C5BAFDAF +:1082D0005F995EED8C008000000000001F8B08009D +:1082E00000000000000BB57C0D7854D5B5E83E7356 +:1082F000CEFC24334926FF21413C21111212E29089 +:1083000084000171F24BC4080301826075405184FE +:1083100090207A5BEFABB79990682DFA7AA358CB8F +:108320006DEDFD062BAD0A4880A08126E9041403FB +:10833000040D820A96D68014B1053280B5587D8F1F +:10834000B7D6DAFB64664E92426F5F87D69D7DCECC +:108350003EFBACBDFED7DA6B9F65ECD94B720E636A +:108360000FB7CB8CE53356FBACEC65A98C2D63CAFB +:10837000E9BE0C46BF6BA9F85F67E59204C6EEC57F +:108380003F5568DB57553278AE5CAE9985CFF56FB7 +:1083900090995982EB1EEF53C971D036498E461819 +:1083A000C71E379EEEB33066817FD746D33C8C25FF +:1083B000E0FCFCD723B1A75260FEB38AFFBD08786A +:1083C000EE2CC0E181799678F873F47EF8FF32C71D +:1083D0008C2F2478DFFDEDF229730E5E5D6D32C0C7 +:1083E000F8A52F496C1D8CBFFF69DD78B12EFD3AD1 +:1083F0001EDAF0A3B9E91981710F7B9F0BE9C3DA8B +:108400005456C0D87D023EF6EA7F05EE73F84DAEB5 +:1084100008C632ED117167B3A05BC0265D4B63AC3B +:10842000CE1A99C3A2A03533C2233B64F46E02B8BE +:10843000D644C08201CE355BA3BD1EC4E3EA68C644 +:1084400046C0B8F68D26B70DE6C4DFED8C9DAB6F48 +:108450009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB1AD +:1084600089408FB6E7685CB7E29A6487FE2A4BDFE3 +:108470008FEF5683F03899D363995C696286C07C2C +:10848000FA7659B3F1CBBEA0751621FC56F86312EB +:10849000C02FFF3DF8D5C4685B006EFDBC7FAADF2E +:1084A0001002F74A85395B6C81F568E326DA0DB472 +:1084B0001EFDF37A7A30E6A5717ABAAC443A04D15B +:1084C00017E15400AF3D1D56EF5A89F888E0F67465 +:1084D0008411DC1793D6CD3D93C7D8617C00E0AE04 +:1084E0001DF132F55F515C6E7B3C5EF48F728DC77F +:1084F0006762199B323CDE6046C6607C2ECE0FE37D +:10850000768539F3988CD75DB1C807D31BFAAA2CAE +:1085100040AA3AFBA40A05DE33FDB9BEAA30E83F03 +:10852000629FCCFB9BFA8E5A1C8C35B02915A5F0A6 +:10853000FC63700FE7BB5E9B6F762D66C05735807E +:10854000534B0CB4C7C6BC8DF256D35B5921454280 +:10855000CB984FCA057E7046FAAC39D4678530AEE9 +:1085600033CAFD1FB8BE55579B2EC938EE98C2E5D9 +:10857000A53B8EF0A000EC61F05C53B853B503BE90 +:108580009A622C8EC654BAEE098BC1BE535583AE87 +:108590006BF4C0E7108E2603734643DB75604C54C2 +:1085A0005FF6F078EBAA57AB14A0FFBEFA0C6AF5A1 +:1085B000F78B4CF674073C5F6460EE16DBE0FBAFB4 +:1085C00022BF109DD414A4736DB789E41C7F12F0F0 +:1085D000FD2AA1876A81405100CFAA63CC171E896A +:1085E000E3CABF50B06D95D8E910BE6281BE3C3C75 +:1085F000DC37DAD6E27C4A309F703C152BA9554A0D +:10860000D07B4B6D99217D39D19081EB6172B8633C +:1086100013E0574E31ACDE01EB976F8616F0A1D810 +:108620001DF212689B4BA6CB4BA16D34B2852DD8A1 +:108630001AD8F2603C750879D2DA4B76D76F90EE93 +:1086400017DEEF2DB0929E1A6927F916EB6D941C78 +:108650003ED4439E2EE6D804D79A6417E37CDCC24E +:10866000908F7F2FE671980D3B55E0D7F7EC0F12F6 +:10867000FF3AA20C8FA642FFA3E615150AF0AF231E +:10868000C570251578F478F34ADECF325C190DFDFC +:108690004F9A6B787F2A4C99CCD8C9E655159E6CB9 +:1086A0009C97EB31B6C59985EF510C12C9A9B2D789 +:1086B000E46D843F9B22393F3519812F6370BC4A9A +:1086C000E39F6A28DE6C05FE578A9DEA6A1BC73560 +:1086D000F2C3FFB4D5F0285B0DAB118FD822BECF0B +:1086E00088756B7460ADCEAC39A8175A9C5973234A +:1086F00010AFEECF11AF793DBDD3510FB77EF0492A +:10870000813B9BD30BE7C9EB612C12D673E1AD9B88 +:1087100036CA52803E97EC45E7515F4BA0A61F87B3 +:108720007549AA9DDD0372D7E864AA09D695C85E8B +:10873000B2A3FD30207D4005B532AE5F3AA35C5F49 +:10874000E2736CA48FEC4CB5DDF515BE5FD3CFACF6 +:108750003766483DACD757A69CC765067C1093D2B8 +:10876000767C29EAF3DF9A1DB7A8088F933D0E7037 +:108770006C333085C5107B642870DFCAC21DEB5096 +:10878000DE1D2CC903F2856823E0E01707F6D02828 +:1087900064485B073C5FCAA09D8470DD4AEB929100 +:1087A0009F2630978C7AAB8079ADD8F677BC9584CC +:1087B000F87A3E8CDDE782D6F22A737A83F4467E1D +:1087C000B444F89F1563A436DCD83217F934FC1290 +:1087D000B3A31FD0FF0B9382F38360DC89D71DFB0B +:1087E0000D0CE1FCB5D16B8F82BE3F53515F6681AA +:1087F000F9FA059DB5799F37A999D1D0AF8A91082B +:108800002FBF2EE2F6D8FF85C9FB722AE2C7B2DA83 +:108810001B2457E3A3F9B8BAB8E2B1D1F07C4B47B7 +:1088200038C3F74FEA0C3720FE376FC90D433ED8E7 +:1088300086B881F5C798ED8FE07C315700DE54BAD9 +:10884000EE24BC2AEA8428C06BE14C9BBA0EF0FEF1 +:10885000EBB09699C8F7FEAD06F632BC629BC93103 +:1088600007FBDB2EAB76D4B3BF4E6D09A7F56C3595 +:10887000D07AB685FBC7AD01B8D7652815089F62C9 +:10888000650AEA5FC550AC3E02D7A74573FDA8E96B +:10889000E39A6895FACF4BF0FE5C1C57447253265E +:1088A000DB48DEFAFDCC6B86F7C4CFEB95911EE179 +:1088B00073809590DF159FCC703E17121A5A9BD18A +:1088C000AB929E75DA9600DDA70B3D3BFD644D250E +:1088D0008BC48EE3D854986F9FCDC8705DB7B13EFE +:1088E000D902FDDBAE32870FF9E7AA427E981DFE62 +:1088F00005FB7B65629E5F494C898271455FAA0AD0 +:10890000F257110BF5DBCA36947F81F6ADC4A2BBDA +:108910008EFE5C24B64AE03ACCB3285AF861A3D85C +:10892000A86BA4CF60D6046147555C7FF67FE1BA9F +:10893000FA2B4C0E5CFF769BF3E3A9A8077B8D6CAA +:10894000131B5E8E7E550F1A7D0C08C7D570E68D01 +:10895000253EB421FDC76D68F684C17AC7A5F3F939 +:1089600091DF506F8CFD455C2CEAED8868AE4FB40A +:1089700056E32FE4237B14E723FBAD01F9FB5E7480 +:108980002A8DD3E409F90BE7D963F42E760D61172C +:10899000812FBF877CB9DDC62A90CF9F1961598886 +:1089A000F2A4BD67B7E07B7DFB54C39A2E23AEFBD8 +:1089B0002FA0FF01EED2E4ABA660FBDD15C7E12DD1 +:1089C00093BF25BFFA62BB44FE7C423BD7D7C17C34 +:1089D000316268BE7801F17A3DBED0C7011A5FEC02 +:1089E000B81E5F74FF637CF18B68E1DF0ECB17DF8D +:1089F00046E2FA1FEB2849647FC78F69137C30DC9D +:108A0000FD2956AED7F4D7DB053E779B9AEFCC41D4 +:108A1000B9BFCBE040B906AAA7CC05FBB23B9C3F4F +:108A2000C794D569D8DFAE703DB2BDDD4C7A64BB6A +:108A3000CDED267B9D6461E82730C5DDF77DD47FD1 +:108A4000C916755D10DF3E2EF4408BD137E573F407 +:108A50007F0F70FA4EBE2B5736C1B8110F70B9CECA +:108A60003F67DA28C33CD53145BE6818DF17CDED26 +:108A700062DD1918057C597BC644FAEDADCE23E5BD +:108A80004E1BF9374EE4AF497B8E941767E378CEDF +:108A900047DDA2D5FA53704D3164768E25017E5D97 +:108AA000C24E4C615C0FB9903F72027DE634523C7D +:108AB000A6F1413563596827E6F639CA908DAA2A8E +:108AC00042E95BED9B4971DFFCE3CEB20858D77CED +:108AD00097EEBEA07FB58EFEE007FF01E564D5E608 +:108AE000DE4E1BF2ADCAED698B697516F77B56A792 +:108AF000A1FFAFC911FD004F2DBFCF78795D901D4B +:108B00005763F83A9F752874DFD367F2DE0297FE49 +:108B100037E3CFB5087BF3AD90E3DCC7DE588CFCC0 +:108B20009BB7DCB90FF1BF284EA6EBFFC97C96348A +:108B3000A48F4321FFABC5A8967C2E05C631C595F1 +:108B40006183FB7BE2C3F3F0FDD531EE6B4827A6D2 +:108B5000F8BBF1B94985B9792857B6094DB1687F95 +:108B600034B801AE8A4DB6001C1A5CE785FEA98EAA +:108B700059720DF180CFA15E693B75D682CF6B74BF +:108B80006FE9B8C4E91D447FA47780FED27DD8D7B1 +:108B9000F06011ADD6FFE7E9EF1B89F41896FE18D7 +:108BA000F747FE8FE83F2A6608FA833F958ED73550 +:108BB0007FAAC5047E7576A0AFD1BDDA5E44E31C02 +:108BC000265819FA4F9D1057A21CBAA3D1B9613B80 +:108BD000EDFC5DFDBF3F3B0A5C4036292686CB930A +:108BE000C93F06FD8D093E89FCBE0920F0F7909F24 +:108BF0003592F49D43E0879D95A4B319DC05BF969B +:108C000082FE9F2F16E56082B9D287FCBEC33A3D33 +:108C100005FDB75CEBB434E4A737331E3B8426E78D +:108C2000CDE4E53B5F51037E8EA6D7F68969B5F7A3 +:108C300097C770FADF0E6A16FD3D740D83E1D0F41C +:108C4000379205E1907CD5866B56D2C7ED7D80AF1B +:108C5000DB110EC06B97C45A517F17199C7125E820 +:108C60008FC5FB14EED77D3D4A05BEA96C7FF73852 +:108C7000C25B69B1F930DFC21CC6F37D41F912BD98 +:108C80009FABF9259ADFAFF92D5A7C89FE0DDECF17 +:108C9000C7EB00BFDD0C00A2FDF159BC0DF0FEE7F3 +:108CA0002FAB994E21AF0AACA352AC6336EB25B87B +:108CB000D8B7D7AE4D03FACC12F8A8EC86B8300777 +:108CC000EF337617E0E12E85C78B7739203E0CE233 +:108CD000A3D99343FBF89B9E1098E77AE3F5FA7FBC +:108CE000AAC817FCB371A6D676831D3A0D0C70B0D6 +:108CF0009EC73485A3658F82F1803BD380FC5827C3 +:108D0000EC1A84C943DB2321AF8586BE1C07E0B77C +:108D10006BCF3764FFF6EEF9E623F4E7A67CA130CB +:108D2000333C5FF8457E14EA07E60A9DB7EE8FAD47 +:108D300056C6AF13FFD48AB5EFAFC78C18C267A170 +:108D4000F637E79F5F8FF37D7946E1BC2DDE5F6EDE +:108D500072A7DB6DD8F2787FBFC4FD1DEDFE7E23C8 +:108D6000C00DD737C568717FAF42F919F89983E80C +:108D70007C17C6FBB901BADE75AEE20B2567307D04 +:108D8000F0F7FF23DED7E2FCB744FCC0F69D30A924 +:108D900000D78CD64714F4A36724C9CC19F4DE3B62 +:108DA000542B7306C5FB6FC4E8FC907DAFAD9F05E7 +:108DB00076A4AE477684A1BCB66F3F9483FD5ED99E +:108DC000611D828FF4F89DD1FE8882FC9F10CBE557 +:108DD000E67AEF2F1C077C722BD29D911F77B14052 +:108DE0002239D2D377EF9E9FC7F6650F8FEFE1E868 +:108DF000AFA7C36FCE1747215EAE470F3DDF76C2E8 +:108E00003A3DB03E1FACD303FED6DE7A3BF5DFAE73 +:108E10004FA2BEC6AF751DBF8C457F4DE3D3B25880 +:108E2000CE375376AF8F65B600BD347C5D1474AB1E +:108E3000668EF9B3E0CF5D922382F48487F5261520 +:108E400004EC55F5B172F233347B552D671B51FF9D +:108E50006AF60AD3C2A8CFF4F6697E7A9111D5AA30 +:108E6000DE2EC1028DC8BFD50B43AF57F4342B1192 +:108E7000D433109D2449E043F8D51A3C1F3217C162 +:108E8000ABA7A7069F1E2ECD9FAE1674837596E1E5 +:108E9000D2E7AA45B48E417655ACF746EDA93936EE +:108EA00034CEBA72AEF4FD9C21F87538BED5DFD74A +:108EB000F44039BE20975A0FFA1109B10944AFF2B4 +:108EC000AB26E6047BC14686B1CF82F3EFAF649256 +:108ED000BD7B54D8DFE1F8A6F6AA81B96303FC6331 +:108EE0006C7BCE8AFCB35B69B662DEF136DB9CC676 +:108EF00028C053E91F8BE7A15F57D76760989A2A6C +:108F00006BBFB40FE3F6BAE3CC81FAB0B8BDAB04E3 +:108F1000F9ED6DA557A638FA4BC69E0BF20FDBDABA +:108F20001BADE83FB5C5C914A7EF8FE6FCA8DD6F00 +:108F300089E5FCD776E6F22CE710F73F13F74B4FA5 +:108F4000E51AD148F6C74750BEA1FC6903ADBF542E +:108F5000B25755A2FF718791FC7A885BFEF07DCCF9 +:108F600037B599B763AABEACED878FD881102DFFB6 +:108F7000E7B30633E60FE6488E97615CB9EAEFC2C5 +:108F80007EF9BC54DA8799F47F65F25FFD774B94E4 +:108F9000F7280776C17EF93DA95ECC3FEC9178DFDA +:108FA000D3C1F3FECCEE899D05EFF9A03276C23A2B +:108FB000E229AD7F4BEE3A261838289E7A6C17DFEF +:108FC0003F7AAC4CA2FDA3327B0AF304F155F9D3EE +:108FD00040CF3CE0C7F6C462E4DFAA0A997983F87F +:108FE0007ABECBCABC41E3F7877178FC92D98BF982 +:108FF000124D5E670AFEAE5E181B327E0EE37EE205 +:1090000042D66C44F9AE13F0D415013CF0FC4C117F +:10901000A7DEED4E09796F256641606856DC68B2BF +:109020008FB3BFEC23B33A473E796C31BC87657090 +:10903000F9D0E4AC4CAE69223E48921C181FCF9781 +:10904000C0AB9451DF85CAD1ECC9A1FD394EBD7EBC +:10905000089577BD1ED7E47C7E876CC4387A7E91F4 +:10906000E46043E803BD3FADD703930C8E7730AE89 +:109070009E7BD549FC35480F9CACF887F4C05B203B +:109080005B93415E7FA4E9839BD84DA80FCAE42D72 +:10909000EB913FFAC1AE9987E00FCD2E68F176399A +:1090A000C827F2033BCFF725CAAE829CC606E2ED85 +:1090B00001FD007E8363087FE657B16921FB490308 +:1090C000FA22C86F3016FCF37E4319F88BA65C8435 +:1090D0006F24F3E4919EA2FC1EB43ECAB3255DA2A8 +:1090E0003C4A1DC4F114CFB35F125CA8D7A498000A +:1090F000DFEBFD092D4F3B42E409F4FC3090B79BB8 +:1091000067F4229F69FC506EE772513E4FA6FCB98E +:109110009E3FB4F75D8F2F7C12F085F477F842C83C +:10912000D38DF2C5218D1FD259FA8DF083C6071A4F +:109130005FE8EDC5415DDE65387B71F23AF6E29D90 +:109140000C23E965BD9DD0ECC28138AE7FC7C7F264 +:109150007D8A9999F36DE8578C407D80FE9EB037EB +:109160000379A30D9C0FDEE95BAA486837500FA472 +:1091700006E15DE44D35BEAB7D9A51FEB052E89FED +:109180008B1D3C9F56572A7B2DF06749FB73EB796B +:10919000DF48F9B622A54BB1C0BCB31D9203F3352D +:1091A0004E917F9B75D5E455293F3FF47E7A95E03B +:1091B0001B8C7370FC6CA7E4851074901EAABACA4D +:1091C000EDBE5E1F5589FDF22ADD7EB9294ED0F530 +:1091D0006676F3BFD2EEC7C72570B919868EDAF36B +:1091E0001A1D35FA4DC0B1283FFBBE36A911DC3F30 +:1091F00046FACDB8AAD03CA3E242FD962FCFE7FEB7 +:1092000027C574627C5DFB25937BFCF0F05FCF2F5C +:10921000BD59F3C3855FAEBD7726C8780A3A863A52 +:10922000FBA1BDE7BAF6423CAFA7D3E4B8D0784281 +:10923000A387A64707E15BE8D9E1E8753D3DABE9C7 +:10924000B37FB59ED5E6D7EC80F65EBDFE1D2E3E03 +:10925000D3F4E9531B0D9417B94DC4C1B7893CEB46 +:109260008342CE970B7DDBFF178B01FDAC6D9DDC40 +:109270001F7198ED87D06F08E4F3385D9F8C601EF6 +:10928000DC2F674AAF85F62F8B81A4B87F99CCF786 +:109290002FB7283E17E96987C21A405EFE2AF216E8 +:1092A0004FEEF52C463DFDE4E93106DA47577CBD2B +:1092B00018174FCA55683F28DAAC52BEF76287D9F3 +:1092C0008ECFF5EFFE5E9711E7F90B7360A8F67687 +:1092D0008779603F06F54299DC23635EBEDF0FBEEF +:1092E000388C9FB6D05782F1CE6DACB711E3EA420D +:1092F000A4E310F47B55675FF479FB920EEE27959B +:1093000044F0BA9FE980467CEFF43613F985D7CB59 +:10931000DB177DC9C85F1A94AF6FE37A0606119F09 +:10932000DC68DEBE107D3DE0E39FE8F40E1B267F87 +:10933000BFCDC4F773FC478C0CFD5E762E6EC8BCA7 +:10934000CBF5F2F8BB3BC39D6A24EEBB71FF7C7783 +:1093500067B253CD197E7C4E9FBF18F395DBB6CC18 +:1093600055284E14F9CF41FB223AFCED9058931545 +:10937000F369ED8E528C3F86DBE728F63B69DE1BF6 +:10938000C51B63CD9CCEA27EE9762163DBCE863BF6 +:1093900091BFB79D4D76223CBB057F6AFCBEFBCCDE +:1093A000E570DACF343955DC07F6475B1C2F13BF65 +:1093B000723E6F1931C68BFBADDB853C6C0BF71F22 +:1093C000CC8A0BDECFE0FB179DF59EAA33E9B4DF14 +:1093D0002D61BE51DB27F680BC505D4E0C237E32E2 +:1093E000B21686EF6D74B29F633B7D9A1A85F8BE04 +:1093F0001CA7ED47AA519467F8F64A816BFC60BC44 +:10940000EFA877513D496BFDC22A05607CB3DE4D64 +:109410006D5BFD726AF7D4AFA6FB6B0F453E8E768F +:10942000BFCEB9A04A09D21B9FC5F3FC526ED6E944 +:1094300012E473F60D6318EF4C7FA24F463D71FBAB +:1094400055584748DD887219F14CF9CBB4403F5567 +:109450005A12867C79FB55E8078D97E2A3391D9A4D +:1094600094A65B0A485A881FC2E29D17E3E0FA0FF0 +:10947000ED2E7F5C3CF241F5BE0B8CFA97F1FA0EB3 +:10948000E96EF9028CCBF31551DE380FF3C6B9340F +:10949000ED62C4DFC42E13ED7B6BF9DB5C31AFF3FF +:1094A000ABD03C729EC8DBBEC9FA289F9C6F81C0BE +:1094B000CA807071FA39A5F94912E6FBE24D0EAC8B +:1094C000579898E6CAC37C6B573CA3FC695757C2B0 +:1094D0004815F0E054785ED7A9E575D9DFCFEB7673 +:1094E0007F1AE9217D057E0AEAA7EEA3910E1FED02 +:1094F000FF59C8FFDB810F627D4338AF1760F3E689 +:10950000511EFD760B5F07D89FF878CAFBF9F61D50 +:1095100086E77E7B99F17DC4DE93B43F5D62C84CE3 +:10952000EC0338F74963A3B07DF1D3C86C6A8F466A +:109530009E47FC741AAC2ABEF7C37A56857567CE6F +:10954000F76DB49F31FD7D9B82EDE1FA3EAA477B2A +:10955000BFFE1CB547EAFDD41EADBF4AED3B701DF2 +:10956000F9E7103C8F6DEEE2087A6EC7A20813C2CD +:10957000DB19C9B668EFC17A335FB8AF1593F9EF5D +:10958000C57FBECE7213D83BB37BBC3481B113F11F +:109590009FCF54A07F68C6A87FFF0BDCFFDD4F2E56 +:1095A000ACB3005CF38EDA5A7BA0FFE94F2EAEB36A +:1095B000A19E3D140ECA0EF546FF41907496873663 +:1095C0003D9971053B19FAB1A2EFE99F590A245F51 +:1095D00050D297C580B5A6FCC43FD302785C6075B5 +:1095E000FF1BF64D9E976696DE847DE6C17A2EBF00 +:1095F00064A4F89E8D94E2B07E6599DD7D2C3EC812 +:109600007E3BA53FD2FE51815362D1714457DACFE0 +:1096100062F653B1C1F2B6CC5E760CE971473CDF1D +:10962000BF9A384D7206D749E8C74D3CA396229D94 +:109630000ACE9537613BBB229AFAAE85939A509E2B +:109640004B6DC33D5F42CF2F8837127F162B524898 +:109650007D887E5C1E3013FAC7FE03E1941798786C +:10966000CCDD8875A36549A9B9B2D0798CFAD11B34 +:10967000711F6D62E587A5B1283F36C981E6A180DB +:10968000F535C5C661FD231644E1BA9E2BC1FA9D8E +:1096900089AAE440B41539BB5AF1F9224784A308DA +:1096A000FDF1636A299A9CA3CA84C3F9306E46BA55 +:1096B000ECB0C044477D774CBD00FDA28C28CAE3C6 +:1096C0001629ABAF1CA67E84A341C5756CFC792D11 +:1096D000CD63267BBE6356C97F20FF14BBA228E75B +:1096E000576A3B3537B82E0CD64D7017D9656F9831 +:1096F00084FCFD83523BF4778C9218CACF515FE60D +:109700009FE97E77B81A0680EE30D94B71BE1D26D0 +:10971000C9BE96FAAE121CEF196354314F541EF7AE +:1097200045C8FC334AA5296710FEECA80978AD624C +:10973000E4A590FB3D8BAC64272ADFCF267FA8678A +:10974000510AD98BCAF7A71563DB63E07E7AE5FB84 +:10975000951574DFC0E3DFCAC5DF718A3EC5BB95CE +:109760008B5751BF4B4AFC777CDF95ECA85CCCA3B0 +:10977000CD4CFF7AAE12ECFFADCE24F9CF1579BCFB +:109780002243E6FA6900FFA307F83E4465B6145287 +:1097900037372BFF54483DA86BDA1721FDB9A59741 +:1097A00042EA43E7557E1DD25F304FAA0A1E5F7A18 +:1097B000209FEC6BBEA85FD2F24B458285DEA9CF1D +:1097C000A82A05B93C00ED03A01F8A7A45DE55E1C1 +:1097D000717506FC433D586AD3E577994AFBD91564 +:1097E000DD7CDFBA3CCE783AD83E54C84F707F411A +:1097F000B7FEDC0346B293B9D132E5AB34F82A4662 +:10980000863EAFF95F1502CE1D0677530CE5C79C67 +:10981000BDE87F68F06BEFD7E0AE90EF29A5EDBF14 +:10982000EBC0AF87170025FF4D0FC78178118780E8 +:10983000BF41FE5937AF4B835FDC50765BF3CF2BD4 +:10984000414F4507EB299B1487F576C3E9296DDE67 +:10985000E1FC306DDE6576173DEFDCFAD9D1423997 +:10986000A89F7A2A3626B8FFDA67EB43EEC79FAA8D +:109870008A0EEE6FFAAC0AEF4F57D4461BF0E34165 +:1098800026393CC89F3DAA82FBCF25C79C4DD89660 +:109890009D746399299B71C6D384EDD4F3DE1E3386 +:1098A000ACEB8E0C59C5B85DF33FF4F09A13781CFD +:1098B00072F0AA6AC5FDD31D1ED58AFEFB8E275401 +:1098C0002BFA1F3B9CAC02E331679A6135FAF3CE69 +:1098D0002C5E677855E8E16FE2F9F35A7B5A717FA5 +:1098E000837A11EBC2D127A8FDDA4F75E007D1AF1B +:1098F000CA1EEC571D54BC367CDFC127BCB6E07DC8 +:10990000C21BF5ABFE8C363A1EF96C4E887C96581D +:10991000EEAE0A96EF32FB9290FB9FC6A904FF8C35 +:10992000A48743C6DDA13E12D2077F3103FD9146D5 +:1099300013A33A598F81D7C9EAF1F8A8C0A3C36627 +:1099400047378619E354AA6BD38F739470FCE9AF41 +:10995000A727F0B86823C80CB6F72470F8F475B1DF +:10996000FA3EC47C0B713E983909F9DC61355C0123 +:109970005797391392EEA47AD93CC3A369D0AF4E5E +:10998000C8E2FDA9869D581F7B774236EFDF6AC883 +:1099900033821FF02B36FE4EAC07AF0D13759D0FB3 +:1099A00024D27E9816DF2886532F2EC638738F91C7 +:1099B00061FEFE1913D8BDDCC0BEB9D5CCE352ABF5 +:1099C00089D76D3F957AF429D41B6A987B7A02F97E +:1099D00051C52AE2EFBCDD42759D8FED2E4B44FA56 +:1099E000DF93C0F35C593BA726A17EF917BC7F56D5 +:1099F000C2C4E1DF8F75BE38CFF91D59E47F67DD42 +:109A00000CE89502F887F098AE87419840E72598D2 +:109A10003309F36C8DD1269AE79E04CE7F37DA0E98 +:109A2000AAFB8D32ACDE0EEDFD82FE0FE07B095FFE +:109A3000FE51737063CEEE1F35773CEF237D6539A1 +:109A4000D78F7EACFF3B11B4AFC246FA69FFE5E3A6 +:109A50007BB21CE89F7E12CEF1B7D03BBAB14FC5A6 +:109A6000FA0DEF4D582F9191E8AE453C2C327B6FAB +:109A700021FEB1AD8EC0F96FB41E78F07B21800459 +:109A8000FA544FE1F4D1DE0B38B5A03DF8589C03F1 +:109A9000D1E080F7FF00F9408367000E5D5DB89666 +:109AA00067AEFBA381F20C7512E83DE8EF3CC91CE0 +:109AB0001E98E7A2E6AF8BBC266E45E17BA61C5E36 +:109AC0005A628336BF6D258F737B95903CD7A4E394 +:109AD0008A7EBF83ECD654ED795D9E71AA886BA710 +:109AE000EAE2DA1713849D4966C9C1798035226E8E +:109AF000B8DC333A0AFD4CD45132E0D5A4CA6C72BA +:109B00004C40CE5B21EE674171BFC667E38FD9EF52 +:109B100047B8C71F63F7915DD7E61DC82F70BC5CBF +:109B20003ECEF132A12FE3A7D3A06FEC3632AF1AAD +:109B3000584F2107955DC6FFE078BBC98B75CB05F3 +:109B4000077E99E7834BE624035383F010A6863300 +:109B500035482F5A336242FAB2866F61CFF3C4FCA4 +:109B6000118EE49079F6C49477A37DCFB32D27FBB3 +:109B70001E357974C83CAC4709B1F3B028DABF9CF4 +:109B80000840FD0CF05A704C09B1E793E23CB86212 +:109B900036F9A4A2B3FFCD32CA41E199D0EB0786D2 +:109BA000A3CB70F863393F45FFEE1FC55FB4331494 +:109BB0007FB115A1F88B7785E22F7161289E46B899 +:109BC00043F192B27C5CC8FD9B56E786F46F7EBC85 +:109BD00030647C2A18A4E07EDAD33343C6DFD23C5B +:109BE00037A43F76C3A290F199DEA521F7B35E5D5D +:109BF0007143F41EDFB226649C9EDEB7B6FDAF90C3 +:109C000079357A7BE0DFBF82DEE6C4507AA70AFDB1 +:109C10001AEDE4F565FD46DBD312E8234C13A15E93 +:109C20008B6E7FF76BCC43788A55AA9FF3CC64B4D4 +:109C30000FFD82EC92500FA5C0148634AA5FA7FADC +:109C4000BB1F1B0C21FBE28989DCBE2726F27CCDE1 +:109C5000CF4DFCDC520AF88F64870C2C102F031EAA +:109C600022315EA678FAC7CF60BCDC14DD97A14232 +:109C70007C6CC6FE4D017DB9C8AC36F6013E26C8E7 +:109C80005C1F829E4C4B84F93F919E30723FC263B1 +:109C9000443F22C5C23C91B9643F287F1CCDE224D9 +:109CA000ACC78F0AE869F51A106BDF8A2C3A07F502 +:109CB0001E4282FEAF2586ECE8DD9A7E5A9E49FA66 +:109CC000E9B22DD40FBBFC401A5D3F71AF99F6FB92 +:109CD0004F883A446DFDE784DEFA53BD85DAF3F52B +:109CE000F6103DB67CE3FA08F41F4F64707F51BB59 +:109CF0005E82789B88AD2CEC9AC58EF9AC7BC0381F +:109D00004701BE5775F7452E62E43716E3BA6B3745 +:109D10005EB9F74DE8D719FC09DC3E7878BDCCC7B1 +:109D20008CFCCFEA6F5888FF343791C7E973C5FCC4 +:109D30000BA0B1039E1600FEA3B17D775A39F2271E +:109D40005CA7F369B3BB19D59FCC71A7D23EE35191 +:109D5000E6F8701780F89D4495E09CC75CB45FFFFF +:109D6000D1BDAB2270DCC07CDA3CC028E86F7C1C23 +:109D7000ED312660DC7F1BAF6F80F759F0BAEB9EA8 +:109D80009427D10E69EFFB88B92F7C88FBDDCC418D +:109D9000F36AF3331613A29F762C5FF9692CBC6F1C +:109DA000CD0103E513D6749829EEEA5FF1D7AD2F04 +:109DB000C2FDFB52FA6E42BBFCC98A6FC6203FDC73 +:109DC000BD01F410ACB130CAFD7062509C72E281EA +:109DD0002B11781FECEBA617D1386E36537DEF2789 +:109DE0002B368F09F6471F4D2CAAC5E7D8E41B3B3D +:109DF0006F58F27A6622D563097E7A58F0D39AD7E3 +:109E0000C6921FB52662809F787F13AFEFD0D6F140 +:109E1000A1E0C715AF7F5D107CCE7407F0913A8644 +:109E2000EF6BA920533B7B2EE7E0FD57147713C25D +:109E3000D779F57424F677BEF737829FCDBB31789A +:109E400051063D0581FD65EDDCE5C2F6D83CA43B3D +:109E5000C85933CEBFE837AF5DF81DE2A763F3A65C +:109E6000EFE3981B3C7FC9847D71083C807DA1F89D +:109E7000A09F85F3731D428F2AB8839E86E7991CA5 +:109E80002AF1B3931DC27D97C62E03C3BA9548DC51 +:109E9000B409CAB345CA06CD08392D49A09F855ECD +:109EA0007925F1E49D4DE4E787FA3DF96FAF08F1BC +:109EB000775CF08FFC9D97DC8D9807BAAEDFE333BB +:109EC0002C3145DDB8FF0381B0532A105B38F06BAD +:109ED0004B14FB22420F77A21C61FD3FCE85F97A1D +:109EE0005F383F670CA602F5F80F604DF8B02945C2 +:109EF000B4D2C50C0BE8C5BD897F78E669D09396CE +:109F000074BE5EEC37E2DFDD9CDF06FCABB7C791C9 +:109F10009E62DFC2DB100F225FA1A7533EC8078BF2 +:109F20000D9233F1BC6FFFDF22314FBB35467D1FF1 +:109F3000E9E03F20D33E4D98D2678A1E222E7B1344 +:109F4000F59E89FB4D546FDEC6F38116D5C9300EE0 +:109F500008B3DB27049FB36B17FA6ED5FE4F469903 +:109F6000800E170C3D91D9307FCDAE1D91E8C6DF34 +:109F70006B747F8A7CB7F2C40705763ACFB671144A +:109F80009D03F08DA6BA83F10AF328B983E1A8DB1B +:109F9000904BC6B8760325E3D9F8F6BC87501FD599 +:109FA000F9F83A716E2CFCCB6C63D4BFD8D6188309 +:109FB000F3D5FDB62319E567733C8F135FBF3A8E67 +:109FC0003FAF3005C77F99182DF8D96BC03863B300 +:109FD000884F2E5E35D038EDFDE3DB8A643BF043DD +:109FE000B6AF792FC543ED6615E91AF60AE378682E +:109FF0000F2339AFEB9CC1309FDF1FCD1C12DCDF7C +:10A000001AEEFF039D33EB30AB981F0DB337B31837 +:10A01000987FABD80FCD048EC2F34ADA75ED7D611F +:10A02000ED3FC55802F981F2B4614A33BBCD168CBD +:10A03000E708C2733CF2533CBEC767C0FC88FF16FA +:10A04000C65E26B80270327AAF066726F9735B4D9A +:10A05000FEB3787E05E0B223FD33198793B58F55A3 +:10A0600031BE0FB33B691D6176D5E19106C35597AB +:10A07000C3BC68BF7FBC960DC82BCA6F5D78A06F4C +:10A080000119D83A9A09F9B63F5B3A2DB80F8A649C +:10A0900072E0F9711B629E6D1A49718347C63816CA +:10A0A000DA88185CA7CACF3B636A2897E301F7C533 +:10A0B000AD167E7F603CF0B70DFB363ECE1165B726 +:10A0C000CE94484E28AF572BE4FD31C977F67690F1 +:10A0D000D3BFF8F6E6A8004BCDBB7B884F571ADA02 +:10A0E0005F1C0FF7375ADCF94980CFB74E1AE81CCE +:10A0F000E99F5E0BF35662FCB87B63827308F9D06C +:10A10000CFFFC3E36B9F4F41FAEF9654CC9BF61BF6 +:10A11000FDA310DEDAF6CF4D548FD0768AEA938E07 +:10A1200024B99DF89EC96D0DB46F3C8535D3BE71C1 +:10A1300096387FDD92C4F5C7E563635E6E08C2FFA3 +:10A140008349DC0F637EF7CD2837ED423E3BD12FAC +:10A15000817697F08F7675DD9DA606E5FD1AD8DE2F +:10A1600014C4F75AF636B5DAF57E2F3FCF98F5913D +:10A17000E53E6710FFB993B89FE716EFF327B917CD +:10A1800024A1DC769D3645AA785EA56514DA911681 +:10A19000F09FEC43E065406E757254A7F84D38BEF1 +:10A1A000EE1C3F770A746EC2FAFFCD1FB58D5B02BD +:10A1B000D77701AEB1DED373C24C758FBB8CAE14B2 +:10A1C0001CDFF0E15739A8B72A1069F0BFAF3A5643 +:10A1D000DE8C7803BE2F0E47F9DACE488F69F299EC +:10A1E0008DF209CF6723DFE7633F93F4F056532FD7 +:10A1F0003FF7B98B9FFB04BE273900BEB7A39F90E2 +:10A200006D0739A0E7C7927C6FED35D0F9540FE8A0 +:10A21000F15BA85F5C85FDADBDA576926FCCC3E711 +:10A22000A29CFAF6D23C2D108320E924E60AF61F00 +:10A23000DB1323898F35FD783091EBFF960C350ABF +:10A24000EBFFADB21C2217417690F7859DECDD50F7 +:10A25000FCEC0BD3D0DE09BB20FC27769CEBF94746 +:10A2600085AD5AF34EE1EC2DB0CE3587E5817A6E9F +:10A27000F4577D824FF60AFF15ED849AC7EB67F01D +:10A28000FAC40DBCCEB5C0B9BA04CB38265734EFEA +:10A29000C3B6D0D55282678EA72DECDDC7CF1EF393 +:10A2A000F3E3AD7BEFC8C27DEAFE136686FB24AD07 +:10A2B0007FF3FFE175C0C3773B01FF43D825580EFC +:10A2C000F11F58EA149634F87EBFA4E98FF9952857 +:10A2D0006F175BE5401FEC612D3038F67F9D54F51C +:10A2E000AC07004B1BE17C1D59A230D94D6DFF918D +:10A2F000BF25A02DD8758CFB4DAD266716F24FEB10 +:10A30000E8D0F3FA5AFB62123FE79C6F6643E625FA +:10A310000F09BB37C6C39E413EAA6D95ED5EA0FBFB +:10A320008556D96902FFE6ACD39D806765CE31CFF3 +:10A3300082A968E745DCA87D4F6519FA2760A71E4A +:10A340007C61501EDF807CF450BBC47E066B5EFED9 +:10A35000D2D0FB0A35629E87DB36EE4F013AAE78EB +:10A3600025745C8DA813ABD1F92F8792447C98C6D5 +:10A37000D2D02F01FE21BD605458B719F8F5C16441 +:10A380007707C61B9BC5770C407F921C7608BEDC06 +:10A390002AEA04FC5B25DAD7CB7CD52B1BE0F942FB +:10A3A000C52BA39D62D0E23EC164A7BB1CF10BEBA1 +:10A3B0003E86FB35CB851E5CAEF9655EBE9F01E631 +:10A3C00096FCB229CCDB1889EB7E5572F854FC8ED2 +:10A3D000C8A03A5C5A779D5877CD8623FB318C5BB9 +:10A3E000D5123AAE4EACBB4EB76E6D5FFBCF49BADD +:10A3F00073C837B86FF16723F7133E10F368F7CDD2 +:10A4000023B83EAC05F0906E355ED9EBE57E9D0D30 +:10A41000BFC373BF80F77E41EF3AE633A5C0B8559E +:10A420002FF075B26743EB3F1F6C7DC484F1959E9E +:10A430002F966F31923F0A8833A1BFA8E78B156230 +:10A44000DD2B74EBAE754B3AB8B89F3C18AE960551 +:10A4500048D7555B8C0CEB11F5702D6B59528E7CE7 +:10A4600036985F395D5688F90270AEA6737C370A5C +:10A47000E7A811822FC7B17144978AD81BA28BDE3F +:10A480008FDDBE7F9C15E5FB72F7688ADF35BAEB7E +:10A490009F2F177EF08C0D8CDA0B6D25D6F118A747 +:10A4A000F4181C924AF156E478C0475E87CC2AA182 +:10A4B000DFDF9EB6DE0378CF3D9C5F85F17CDE61F9 +:10A4C000039D77DBD99D4FFBC07907D263D3281F4B +:10A4D000EDA0EFCDC03C643FFB7B72D7E3B980FEBB +:10A4E0009ED27C9C57827168E773851D68E8C9B568 +:10A4F000069FEF2E18C1E3F5A7923EFB31FAE13338 +:10A50000B61BE97CC30CA3FF3DAC9FDAD9ADD0BE2E +:10A5100075CDE1A56BC390AEAF49B46FBDBF774DAC +:10A52000DC62E4AB76A31DF7A1FBDBFF6D2FDEF74A +:10A530006C91E87B12751D65595BA19FBB31CF11F2 +:10A540007CDE2B375A25F8D8082BC5C3336E3292E0 +:10A550005D3C9F6CFD25FA372B9C1B498ECFEFD9B4 +:10A5600069A2FAB9AD1243D3BF3F69DF1B888FF3ED +:10A570006F1E31A1935DD27AC4D4F777ECFD052F1D +:10A5800004FE1407379B304E59B551EBF799904EA6 +:10A590002EE1FFD4BE728AFA2BDA24D2332B5E92DC +:10A5A000E93CFBBE8EB74CC8C7B55B2496981A74BD +:10A5B0007F8314F21D84A58CF3C152A1675632EF3C +:10A5C00053C9306E6533AF23604F87D6E5AEDC32BA +:10A5D00087BEDBB4AC79687DF3B0E0EB87301EBC9E +:10A5E00015BF83143AEE61EDBB5C3A7E7E5CE3E717 +:10A5F0004C9689FCFC55911A950DD7BF3AB2E2E60C +:10A60000A1CEB1F7083BACD9C1CB3E03D911FDB8FF +:10A610008B6D5708DEBA9ECB26B483E5ED9708EF25 +:10A6200095ED5D54C7711773D7209EEE6AB7DA5166 +:10A630008E2BFBB85E9AD96EF67A25BCDFD284F4F5 +:10A64000ECEFE4758B9E3D12F92F9ABE7A48E0EF4D +:10A650002181BF874041A7E4A21FCBE3DE873336C9 +:10A66000EE8F81FBB5E27ACD817D91E8EFCD6497E5 +:10A67000EE457AC07B18BE87BD148AE73B1987E395 +:10A68000CE2DBCDE596FAFFA4764CDA6FC23C49D26 +:10A69000084FCD96503CD7EAE2ED7523B87DDEA495 +:10A6A000C373A59F59B3110E5576786974AF82EFC5 +:10A6B000EDCE9128BFDAADA6450DB5FFA8B5EF09DF +:10A6C000BF59EBCF16E7AB5BECCDB6E038D894CCF6 +:10A6D000EDFF8A29B207E934103FA4EFCB510D8179 +:10A6E000F801E286DF8C88E771041674BC3B526681 +:10A6F000717181F8E18749EB2B73A15FB785CBF9C5 +:10A70000C5C9301F7EDF4B61E45FD66D31D339C0E0 +:10A710003AA03BC509EDFC1C83AB5D2A437A83FF5D +:10A72000FDEE888978AE8619E360DD73DA389FCF55 +:10A7300029BD447C72209DAFF7B2A2260EE58F6B37 +:10A740007E389EC35283CF3F805CE2F8DA765E0F9C +:10A75000D4BAF7EB51A9A8D73AFE3A6A09B45746DA +:10A76000F0F56B7E9E1FFCBCD1DCCF3986FEE78303 +:10A770009ADCD8F93EDA83C2CE30A989F8BBD6D8A4 +:10A78000F2760CFA4D5BF9BE3DDB6DC46F9CB18671 +:10A790000F5E6F8A81755F7C5DA27A347CFE09E072 +:10A7A000B38B4B5B4EA31FFDD5560BF98F0F828FDA +:10A7B000383D77B03C6A72AB7D77AA81AD257F7258 +:10A7C0002D6BA27695E0E38B6D8D26CA9B79839ED7 +:10A7D0001F3DD8EF58A5E33B537228BF357C104E80 +:10A7E000FE5FFF01D98EFB2780A7FF4E0EC687F0C4 +:10A7F0002F5AF786113DFB8FD8C85EFC49F0D979F6 +:10A8000091376E982CD3FA0D53789BD5F9D668A45E +:10A810001FE21BEBDE3777BE358E9FA7F612DE57A1 +:10A82000BE8A49F120385BAC94DBD3FA0D1F2CA211 +:10A83000EFF0D4ED19806B8C292E00D770FC2F49D6 +:10A840003C1E3448A1F160DD6ED9155CEF05EBB913 +:10A850000FF54F929003A6F813D02F1999AC92FDE3 +:10A860006A68E7F43474F016DEBF80E73B8CF4FED0 +:10A8700041F78B3D3578FFAB542BDF4FBEEAA9C4BF +:10A88000FE7747CB544FF9DD0F568C0DD69B0CE16C +:10A89000047AD619FD0914371E31107C75472E270E +:10A8A000A4DB501F6D2CB567A3DEE1FA6EFF68EBE9 +:10A8B00072E4630FBE373130CF6BC2DE325C6F1291 +:10A8C0007A152FF079C57AD7B2B9223EE67C942D5D +:10A8D000FC3D882B26264F1C1C57DCA83F09F6E0C0 +:10A8E000E86209EB89140FC6B53B8F737DD0D0F1B8 +:10A8F000D0A7C8E7759F98A9BEEABB9D0F8DA53A62 +:10A900005BB7FB56F42BBEEA7CF856CAF3496B09D9 +:10A910002E0FC29784FECB8709580FBAAAE3C3044F +:10A92000B2AFBB26AEF744A09F927B275E07BF81E4 +:10A93000F80FFC17E2BF9D3DF99ABF62C579571D1C +:10A94000505C889F5507F20F55A21F71B8381FD56C +:10A95000B874389FFC953CF4576C01FF455B4F651C +:10A9600032AF77E9EF0AA33C81C44673FE61E92167 +:10A97000FC53D3FA0ED9F59A3639A46E507BCE9D8E +:10A98000ACF07D7E8D7F5A2427F1C776DED6B4EDFC +:10A99000A4F5AD34B610BD1BB618F9FDADBCD5EAB3 +:10A9A000AA3D2CC683F8388497800E334D5EFA6E2C +:10A9B000C5C154EEBFEBE9F15932CF631C3CE1BE97 +:10A9C00019F9E560917BAC7D08FBE061C53C3E95E3 +:10A9D00004BE5BF97925FDB853C93C8E8F8C0D3DC3 +:10A9E0003F3A605F9239FFCC340DFD3DBD9F69F267 +:10A9F000C4D83306E08BA39546FB3AE1B78F08FA3B +:10AA00005E42D55D46F20F8E32FB3B5867384BD322 +:10AA1000AF93B95DD5F2DDAE0D2ADFD7197CAE91CB +:10AA2000F4E47C6D3EFD7969E1D7CCD7F935EB359F +:10AA3000FD37868D41FDD722CEB9ADC90CF306E7AF +:10AA4000A3F4ED7EB18F81E775B06DC8FC98F23646 +:10AA500007BB4EBC41756627C2D8689E97A3FCF51C +:10AA6000AA61F2D70D03F2382F84BF347A5C10DF6D +:10AA700055D1D3E30D81776D9F2D5CECB39D56DCF2 +:10AA80006F24535DD67913FF8E9A9FE2AB864CEE0E +:10AA90001F5D2893685F1CE01C650ED2EB1746F023 +:10AAA000B8EABB0B24CA9B76E1788C9F5A24AAABE8 +:10AAB0005EE5EB35211F8D695DF224C9AB871D630F +:10AAC00041DFA9986DE17671806EDABA07EC568C99 +:10AAD00087EBE1386A713CDAC159C2EEE9CF218DCA +:10AAE00065BDE51857563B2507EEDBEBE93D77E101 +:10AAF0008477E2FF013A9F4B761F21FDD67B7901D7 +:10AB0000E63F0F667E3E0AED65ED307CFB3BC1B74C +:10AB1000DAF7591C63D546FC3EC98F12DD9F207EB3 +:10AB2000FB0DDF468E63F87CDF7FAF91902E8CE8C3 +:10AB3000319C9C9C12F39D4A16DF258CE3FB24CBB1 +:10AB4000B18FF26AF48EA4FC42F68DED4B35EC7EAB +:10AB50003707F5D6C5AE0339A6203A9E5F03F28EBD +:10AB6000F6A3635F826A0BE63303F1972469FCA6C0 +:10AB700008BB18CA77E791EFB2B1FD30321DF5EE90 +:10AB8000F6A391B7E07CBB783BC09FED328D837814 +:10AB900067CCFC8860F89E24F82EB4F07918EB1B83 +:10ABA00053353EF87EE3707C6B4CE1F584217CAB41 +:10ABB000ADB705BF8783FE7DA799BE8783F9E6E819 +:10ABC00020B9484DE1F230497CFF660AF3D0F70026 +:10ABD0002789EFE04C51984F89C17D2E9FCCF765B6 +:10ABE000F9798602C1BF93145F17D6394C11FB3235 +:10ABF00085AC97C64D677E6A9DCC4EE7148A9983D3 +:10AC0000DAC916DF9D9876C96E69A1FA3F5F821294 +:10AC10007DD622CE430C41B7C0FA15FAEE0DF1A550 +:10AC20008CE76186FE6E4A650A9773FA3807D2F799 +:10AC300002A3FC147EDF0C5F325561155877749BBC +:10AC4000C22CE100EFF6B70D24BF9D7DAA17EB40A3 +:10AC50001DB1E2B92F18D5BB4E7272F944D382757B +:10AC600012DA7AF5782884F9303F364981C892F0B3 +:10AC7000E8A3F7DDCEF8398D22A6D207566EC78F2E +:10AC800027935EF7539C54027112EA7583C543F80B +:10AC900028C3E4CA44BEBF1109F314364BEC38EEA6 +:10ACA00057A4F1F56AF3170223E0B9BD32B15E4C47 +:10ACB000811E8FE1FB1E9154385C6AE7DF094AA0D0 +:10ACC000EF04DD285EFB13F8772123EFF75FFC7EAE +:10ACD0007E60FFC781DF0D8A0C7C8FD281E74C300C +:10ACE0007FE753CE07FBCD77A72CAD4E9918A897D9 +:10ACF000636EA6A25FA1AF9743F49D0B3ADFACD57C +:10AD00007BBCEA9DABE2B9B98571163A4F9B6B19D2 +:10AD10009587762B23D15D9D42751F5B6EA14914EB +:10AD2000EF44574480CFADCC3919F11CA8D7E3DFED +:10AD30004F1A38CF94C0E8FC9FD5CCEB199F01B9CE +:10AD4000C0EF178154A958D7C29E28A1FAC7A7A25D +:10AD50002D0E3C87604678AD01781B2DA2EE47573B +:10AD600077D96833D0F7381B59389DE79E15E6FE32 +:10AD70001EAEFFB188623A2F9DB56D5A12F983B0AD +:10AD8000DE69DA7A0D83EB10B1FE0F9FD3D7FF692E +:10AD9000EBC2E3EBF85EBBC097B64EBB76DEC7A94D +:10ADA000849CF7D1D6FF4C385FA71177E2D3E859DE +:10ADB00015F5837E7D1A3FFC3FDDFB356D605C0041 +:10ADC00000000000000000001F8B080000000000D1 +:10ADD000000B7B2ACBC0F0A31E818565181826F1D5 +:10ADE000A18AD112CFE066607804C42C3C0C0C859B +:10ADF000407B23807424101F01E2A340ACC2CBC06F +:10AE0000100BC471403C07C89F0BC4A5409C05753E +:10AE1000632B0B03433B107702713710EB30333059 +:10AE2000E832136F7FBE0803C31309045F51126831 +:10AE3000A734FDFC3FD8F00A7DFADA276DC0C0B018 +:10AE4000D502C15703B2B759A0AAD96E81DF8C1DB4 +:10AE500068F23BD1F8BBF0E83FAB87CAB7D540E515 +:10AE60004B693130782285899D067EB7A0E30AA020 +:10AE7000DE4A200600FB72DB43680300000000008E +:10AE800000000000000000001F8B08000000000010 +:10AE9000000BE57D0B7854D5B5F03E731EF3C8CC9E +:10AEA0006412420818C2092FA30D382121058AED2A +:10AEB000400091A206B50A1575C22309794DC0C795 +:10AEC0008FB56D0682111034582C51A39D2028781F +:10AED000830E3448908003581A7A5183D7FA687BDE +:10AEE000BD4129200412F185DEB6FE7BADBD4FE6E3 +:10AEF0009C9319E0DEDBFFBFFDEF1FBFF6B0CFD99B +:10AF00008FB5D76BAFB5F6DA7B648B8B484308F906 +:10AF100016FE7E40C8748910D23FFA74BE4E549219 +:10AF200048485D0E2DA710923E9C848840C8E46A74 +:10AF30005ACE23E4D13B49C89A49C8FE2316FCBE29 +:10AF4000CACFCAB45DD8720DFD3E82BD7F328BB6CA +:10AF5000A3EF9FBC2062BBE04C12DA4CCB4984F6D5 +:10AF6000368CD021FCF89CECADB78FA2F51BEFB46A +:10AF700010AB4AC8137418329E1017F1D9096DBA74 +:10AF80006A38EBEFF19996E745013E46D2E6D3F2F7 +:10AF9000EA29C5F9AB69698DCCE06A9853FC7C90CD +:10AFA000F6EFB10CC379D07A4F3A69BDC7DE2F21D5 +:10AFB000AB69BB0D732D427136ADD7A4CC0E65477E +:10AFC000E7AF3DE71289B70B5A2DE3E0E9E3CF88FD +:10AFD00002CF5F4CB4E0386BAB193E683DC592467A +:10AFE000484BC7019B9FF6B7B6A2E5E834FAFD913E +:10AFF000E1162FC52079A4E380FD4A3A7E30CFE2E6 +:10B000001D416BA74B11C1E38C8E379E50C0C7D238 +:10B010007ADE1D36D5D9B73EED7712CC7B0DC5BB98 +:10B0200098196D3706E0A4EDD6529285E9B8BF9421 +:10B03000BD8761DC5FDE902C0449B4DEF50024D4CA +:10B040009B6B21115A8F483D3642C7593DF16DDB4C +:10B05000085A7F75A1052641D67AB5EF5E3B81FE81 +:10B06000A68E3C3C1CE87A3DFD0EF3C87E7C36CCB7 +:10B07000FBB1290A01FCFF52A0F5288A1B8A941F04 +:10B08000027CAE6AE281F7F4E98B85D756C18670FF +:10B0900090351B08C9270002FEADF685560E05FE49 +:10B0A000CA235E28A77B697B67DFF69D8215E9D2FC +:10B0B00020070702FEE2D16F38C7E7EAAC2576A089 +:10B0C0000721F56985A308590F78824125BF3ACB3E +:10B0D00015ADBF5260F85927139F40E79790A7849A +:10B0E00096513C5BB23D7360BE4EBF42AEA3E55588 +:10B0F0004270A0087419A590CD2AF2857D042DAF69 +:10B10000BD2AD90BFC572784D324F87E03FD4EBB00 +:10B110003C5038660EF067A357417EA6FC7318F0CA +:10B12000BDD69F4C56ABF8BD03DB3B877BAC880993 +:10B130000A0FC54B3FCA4B80D79C9BEAAE1F06F453 +:10B14000196BF10085560B93D4F9203F49360F8CCB +:10B150002F8FBD19E927F74F16888EDE3F077A53E8 +:10B160003C3DAA16FE1C9E4FE77D943482D65F9329 +:10B17000F34A03D0E999FB6D48BF67C6762C06B940 +:10B180007AF242EEFB7E944BC5BB99F6F36CCE8906 +:10B190004C42077C7CFA474980BFC1C3EBEF216E6C +:10B1A000FA9CD953434653F8487DE1824CE413E1BD +:10B1B000168AD7C14B15A2DA182DBF25F09DF8C20B +:10B1C000D9ACECA4F319CCE9DCD2F1B6AD08FA9B0A +:10B1D0004B2223DDF8DE969A1CD53383F348249561 +:10B1E000F6FFE4C24328E7CF5C9DEA65729E86FCC9 +:10B1F00092C1FB4987FA54BFA4D94830813E07B7B2 +:10B20000F7DC0C700DCE3A3117E0DCFFC62101E807 +:10B21000F6ECE85415F45192BF837452BA0FCE7E07 +:10B22000F741A8E77286D20AB3B1FE5FB19D09FE6D +:10B2300066D5B709F0B64DA83E0CF409E658BC8CAB +:10B24000DE4C0FAEB93735047A64B0E34FB3C4A116 +:10B25000C80784A452F83C04E5A44E88D88641BBB4 +:10B260000758BB212424009E076705178B6EA8EFA3 +:10B27000170A5D7DC76D018D08F241391DF875BB58 +:10B2800042CA0A63C8C16B5C9EEB04321BF9994841 +:10B290007F03BE1992C4F8462B3F0BF0D071B7BFA5 +:10B2A0009EFCC36C0ACFAF960ECD11293C8F42BBDA +:10B2B0001872B396CB81A39D04058AD7FDBFFB9D71 +:10B2C0001DF0B6DD424AA1FEA4ACB0AD93D315E8A3 +:10B2D000B190B0FE1BB337DA505F0859C8770BC77F +:10B2E000293EFB6890BFE5829FB64FF330BDECF27C +:10B2F0002A21D0CBAEB4A060A1F0A8D9C4B33193B9 +:10B300007517A4F89B07FF00469758FD356B9342CD +:10B31000ABE9F779D954D0006F1457163AEE02C250 +:10B32000E639CF5BB718E84748A105F0B9DAC3E8BA +:10B33000D308E3D0A934A6B37ED6DE4742CB818FB3 +:10B340003CACFD706842E9363CEF95FF25D07ED3DA +:10B35000793B907B68979016B259683BB5DA4210FA +:10B360003E29725800BA8F4A55019EC634EFBFCCB1 +:10B3700004F8674BDE8DF4F3708083F6D3586DF1DB +:10B38000A1BEC8539A404FAFF6313DAFE12B938F2A +:10B390009BEE8D0874EE2493EA49C4932F62F74024 +:10B3A000399BC19399C7E6D50BFF2825B49C364E2F +:10B3B000B74508D4D3F050CCFB2BE6F370A68556E6 +:10B3C0004A00771E839BAECB084F7AB6D2047290A8 +:10B3D0009EC6FA53297E34BC035C0E0DAE3C5A1F48 +:10B3E000F4B0576902567070F88AB3193CFB8FBCF1 +:10B3F000DD2EB0FE50AE1C1C5E079F3F017853B996 +:10B400005EA7FD35CB1141A4F5436389BA918DA6A2 +:10B410004AF9D1EF8F57533CD082938F43D65B517B +:10B420001EE8ABE0B7940FE6D7D37256543E46AC55 +:10B43000B41AE4C5C9E74DEA991C51B68940BB4C22 +:10B44000C2CA1628D379146719E58C7875650A87FE +:10B450000BF89DEA9F65E315C63F57313B86105DAB +:10B460003DE0F3B1EA736BF0BB82EB7AC64F150394 +:10B470007C83AB53278BA04FDA9FBAD9027C752F00 +:10B48000B18889C8CF42AFFEA2E3ED5812B1C32400 +:10B490001DED85C980B78CEAE4C90AE0B1DD8F658E +:10B4A000477BB50F9FB0348D216410D18D9309FA7D +:10B4B000D553DE4CF14AAA9530E8EBB17A38E9F77A +:10B4C0008CD7EB6701BD1E5E7C6820C86FAAA9FD02 +:10B4D00068CB5094D3C1AFD35A38FE899F41FD55F4 +:10B4E0005C9F3800E231F87C1D9E839D54CF523D15 +:10B4F0009D4111AC8C89EA8BD557BD9BE37772FED9 +:10B5000049C667049E66BDA2AB7F15AF1F142E5AB5 +:10B51000EF04D6D3E0317F3F2758504FB9C0CEA4B7 +:10B52000F87D8C78E6E0BAECB5E0BA98C0DF87BD6C +:10B530000726233DC3C42B6482BEFD9B55CF073F26 +:10B540008197A06FA530CA8992E140FB90CA710231 +:10B55000AC7B8D527529BC0FA73B08E88503530FC0 +:10B560000980CFF456FF109043CDCE9DEC0DA7C1BE +:10B57000FB470EFBAF44F98C63376A76A2793E57DE +:10B580005CBB1CF5C1107F4F3BACF7CE0AC97B1DDD +:10B59000F0979FC2E5443DA992EF52F8BDC165A066 +:10B5A00067553F2D0FA0CF0AFE2C65DF57D594E6D7 +:10B5B0001E97A2FDAE1A4EED51AA17D777ACB7DD94 +:10B5C000007646B54505BE5DEB7DDBE673427972DC +:10B5D0003FC0734BA166F74504182FFD1D1FDA7994 +:10B5E000633D8A0794D6286B64A047B75E344E7DCE +:10B5F000770CC0416EA5441C189F8E74BEC867F1BD +:10B60000D61380C5A25B47F667EDC0F5E50D721550 +:10B61000D2455B57B475047BA4FA653E97A347D423 +:10B62000B04D407D456597D2673ED7234EAE37A9D2 +:10B630001E667A8EAF276B17A7E27AA2E94FB0ADEC +:10B640004149CCE7FA766DCEF3493750989CA06714 +:10B65000412FA591C9B0FE8E003D03FA490A0A3078 +:10B660005EE3580F598DEB98519F8EA8667AF09142 +:10B670003482FC44D7A12658EF1AD3C369D04F6354 +:10B68000F501C1AF5B3FB5F5CE55DD41400FCECBE7 +:10B6900063EBDCBC6C36DE1F00416319BCA057CDE8 +:10B6A000EBDE2F26EE406599C0ED2D33FE050BB382 +:10B6B000031F9BF936E271ED82C7F149EA37607FDB +:10B6C00069364683555907F0FD1ABF653AD8DDEB58 +:10B6D000A58E95C329FCEBA7CF5382F4FB1A2FF359 +:10B6E000BB564F9CF73CAC6B568BC2E0AA2E457BF9 +:10B6F0003581C3B501FA463F5141BFE8BE3B37AE85 +:10B700001C4AFB49A37E8CA042A590CD4ABF3B8139 +:10B71000A6A0BFFD1106BF974C2631E0FF57C1C15F +:10B72000FC507F47FB08A4A7C503F026787B6CE09C +:10B7300027AAD40F53558057B58F42782D9E656A3E +:10B74000B4FDEFB9BF70172CFC60DFCF79773AC832 +:10B75000D7BA3B995F6686FFBE49A1760B8E43D070 +:10B76000AD73C5C1EB5CD060A07FBC2184CB95C517 +:10B77000E03A2E307A3DD631F97AF4930AE97BDA51 +:10B78000D1E31D43ED20DF667BEF99840F73D0DE9C +:10B7900031AD33972A0F36E9FB51D6F00CE4B76D83 +:10B7A00016D45384303D27108BFAED305844185C82 +:10B7B000C87A547FAF90237316D0FA2B763A09E0FB +:10B7C0004BE38774DEE7EA6ACA0731E6DD2E88F1CB +:10B7D000E8CEEC0C4EF70E18AFFFA5E94FA5D90E39 +:10B7E000765B385437A80CFC8F6AE6EF8623075047 +:10B7F000FFA44FB90DFD942D4DA97316005F65F997 +:10B80000BC800E0D1EB04F62F989332CB68BFAEF57 +:10B81000F1F47043C50AF47B1B3A62CF7FA285F92D +:10B82000DB61AA27BDD9F1C7CFB7303B3AC9C2F90E +:10B830006EEAA134FD7AA6ADABDA3A3B582241510B +:10B84000B71EDECAF1675E3789546F1BC9F81CFD4D +:10B85000C786052C0EB161A205E32B1A9FD37A6926 +:10B8600080573A0FB4E7281F86C09E7B8CD4A3DC98 +:10B870000469FBCDA42FDC7712CB65CD6F029F5FEF +:10B88000EF78DCBFBE8BEBAB7539F7DBA12B3A5EF3 +:10B890001AF047C0CDF464A58BD9B1053BE5C80FBC +:10B8A000281C954D02DA59967D7684F3DC265AA63B +:10B8B0005D475C0AD63FEBB1613960ED78F47BB44B +:10B8C000DCB35324684766392CC0AF2738BF923C9D +:10B8D0005A067BD8CE8A954DFBEF82FE4A5BADC4FB +:10B8E0004EFBAFDC5D72E3F768B9A45D2650A5722C +:10B8F000F33265102D2F0A096128774FA60B15E04A +:10B9000025590981DFDEEDEE48FD119DF7E91A1B8F +:10B91000512928B5AE8ED45B293ECA42DBA741BB74 +:10B92000B2660134229DC7E64303615E5B052FF8D2 +:10B93000F7E55B120CF6E0093A951FD0EF4BE83CB7 +:10B94000412E4B48FD3458E72A37AF53545DFCE194 +:10B95000748D07C7D1CA955BE938B45DD54B8217A2 +:10B96000A65865217ED043E776DB673FE784F92D53 +:10B970005346BA605E0F2B50AF2454F48A5D05F82D +:10B980009A9469F47B59639302F1AD8095DC0D7E46 +:10B990006EF9967E46B81A4494D72549B68DA0CF45 +:10B9A00089D39776F3A8BE743E5D4375ECC868B939 +:10B9B0000CF421F2614899A5AB3F444C427E2DDF47 +:10B9C000221AED6CBEFE078F32FA07F7BA30EEA7E7 +:10B9D000D16F09F79735FA2D49E2F4947AF263C1F1 +:10B9E000F328D083C2530FF8A2CF351C3EF7443260 +:10B9F00009E22E6E1FF10831F8DAFCAC974911B05C +:10BA0000EE3F2D9F35491A88EEC362883C7956CCAB +:10BA1000993485967F6F29DC6C41FDE155418E3468 +:10BA20003FFB590B93CBBA810AE2AF7E6AFE732CBF +:10BA30003E4170DDAB9F5AFC3CD805B4FD360BCAC5 +:10BA4000216D3F2A7E7BCFB47186F69E69A55AFB95 +:10BA50009DD8DE76F1F6F5D32618C79F56A6B5DF3A +:10BA60008BF03B2F0EBFE7BA89C6F1AFABC0F60132 +:10BA70002BA3574F920DED9A1576AF4F6276540473 +:10BA8000DE4BC92337423D51E307D2E103FBDBD94B +:10BA90009C346635D1F3C5E437000E1795163D5F2B +:10BAA000248E7318F831C9976C28D39E3C27BEC3E7 +:10BAB000CB3088DB86F0288314D4179306D910DEA8 +:10BAC000FBF7D9B17CFF0406EFFD839C2867B8B66D +:10BAD000503ADEAFF8AFD1DBADB0324128E94DD1FD +:10BAE000FF11E037FA5EB5C07B8748AA513F5B097A +:10BAF000EAA38733F39F0BEAF0B37230A52F2D9F93 +:10BB000005FBA77F14AF0F0F2E4E2BD28D53375846 +:10BB100099BD319BBD9FEF84F10ABB010F01A56761 +:10BB200024D895E671AC43C719C6B16594E238DFF5 +:10BB300098C6B166949AC6B1CDDEC8DFF371FE0235 +:10BB4000F38A37CEC3432718E7935186E35845D38A +:10BB50007C32CA4CE338D87CE87B3E8E5DBCD87C16 +:10BB6000864D34CE6748058E93222A86B89575484F +:10BB700085691C278E03EF611C92CEFC1BC5DA532E +:10BB80008CF47FCD4EC09E56ACFE17A05FF2473BB3 +:10BB9000417DA2D27107805E49C6FD827FB524E354 +:10BBA0007CBE7450FA3BF5740E6A7601DA3B0B39B1 +:10BBB00088245487FE7915E7D105CDB33296C1B3F9 +:10BBC000B520AD08FCECF52E2FC44FCFB51628F3E9 +:10BBD00063D8050BEBE5139D06FEE57A6F32C9AA23 +:10BBE000063F8BDB015AF904D55F84EAAD8FA8FECE +:10BBF00082E74999EA69FAFE38D56F44D1C3BB0C94 +:10BC0000DB9D90181E4F34B275E4CB7547658CF3FD +:10BC100005C93B59741EB7F1692CAC4F60BE028751 +:10BC200023C0E9D1B3DB1ADA88F4F05D01760F693D +:10BC3000E84771C5EB0D057C517149C6E215601FDF +:10BC4000FD78E5F6DF40B57785A2C14BE87C67B7A4 +:10BC5000AC93AFA0E57372E75D5EA7AE9FD9F247E4 +:10BC6000306F1BFD0FFA99E3A765DDF877941ACBC7 +:10BC70007712295AA6749B2A0EE5F4E0E3AA21194B +:10BC8000E8755B2A83E74E788E81CF1EA4D75D1EB0 +:10BC9000D6568327F0A04C22B81E75F667C66D7F76 +:10BCA000ACE7D7D615137C77C9365F21A5E75D0FC2 +:10BCB00088884733BC9DFB127C16EA5775367C2674 +:10BCC000837F7929F8EF5E6AFC4E826C3C0DAF1AD7 +:10BCD0001FDC3E7B52BFE3BA7A73FCD7F73BAEE37F +:10BCE000973B4A6719CA7756CF31D4BF7B6991E138 +:10BCF0007B517091E1FBFC958B0DE585F50F18EA02 +:10BD000097342C337C5F145A65F85EBE659DA15C48 +:10BD1000197ED2503FD0DA64F86ED977D54D208F96 +:10BD2000B5BF1709D8675F384F3C0AF6D5174E09DB +:10BD3000FDAA2AE0352A87A76AD290BF4FD7A8F874 +:10BD40003CD79A8BFB6301079567BAD66FA83DBCB9 +:10BD50006CE544D023B43ED5E14FD7BEB52C487D29 +:10BD6000F78D10A4A67C2F362824D20FFC98E45E11 +:10BD7000BEEE1175DF3B2FF1BD812E58B97DBF8B13 +:10BD80009DB1DF770B3D23C1BE0B7E60C5FD9B7867 +:10BD9000F603FDBB82C4F01FB46717C437747AE79B +:10BDA0003591D9D5D788935F13E9B34261F25EB17B +:10BDB00063E064881754289191D531ECECDEF1C230 +:10BDC000149801D00F939745A12BA2F28BF41B6618 +:10BDD00090FB1B2CFE7DA09FBBF68B6C7F207230EE +:10BDE00003F669AE117DAFC17BD2DA1FD7C7776B7F +:10BDF0007CFD8E0F27E4FD9AE9F8FC434D613F88F6 +:10BE00001FFDA96636963FACF1E3B3B3A6149F1F9E +:10BE1000D554E3F7E3354BB17CA22688CF53352BBD +:10BE2000F179BAA61EBF77D53460F95C4D089F9AA8 +:10BE30001C68F62849E1F61FB7D7E9CA81E5F37C0B +:10BE40000E22FD7707CAB5370DE4FABCF3CB91603B +:10BE5000E79E7FDF8A41F4787832F35B7CFAF970F1 +:10BE6000BD2F0E51FAE7F6FD6E7730FAD82D643A01 +:10BE7000F867AB462804E2EA8ED7BE83F6327D2F00 +:10BE800011D49721AF7E1FB1B77F98F3804BD34970 +:10BE9000AB7FE2A97FCF9F970DF461F4751C14ABC3 +:10BEA00019DD9EF302DD74F86376D94EAECF4D787E +:10BEB00094B8DC99F179B6BF86CF8E0C88B7548AD6 +:10BEC000851689BE3BDF62C5799D6F4B60FBD89EAE +:10BED00094CB8AE7956FB17BF4FAA1329CE431EA06 +:10BEE0008B811EBDBE38DFFE9C1BE47E499AC57364 +:10BEF0003C17F8C3C7F983F19DD67F6538D3E33487 +:10BF0000F4632C9FAF17A6B37D4535F1D618FE819B +:10BF1000F65C92A6788E53BD707ACBB0441897FA2F +:10BF2000711E18A7ABC6E361E3A679F47C59B1D4BE +:10BF300081F535F8E2F5FBF7860F76FC3EB6B15891 +:10BF400013C469E2D58F4B0FE97305FC03D2267F3A +:10BF500009EB8E234B5B77242C6BFD06C262D07AF3 +:10BF60000DBC6F368C47DBA99A0F0DEDE2D35D2235 +:10BF700027347A523D791DCF0FA1CC8C74F6D31E95 +:10BF800013697FDD927325C479332515F55D0006AD +:10BF9000A2FC5469EB54FC2AA2BB03E39EE334B930 +:10BFA000576FFF2365B94FFE59C67806F90BED9D13 +:10BFB0007E97F9D705A4D00D4EC6BC96F299A0275E +:10BFC0003FB168F6407D3ECCFB2CB1E07EFE59F2DD +:10BFD000B63B576797954A3C3EB992ADCF41FA1FA1 +:10BFE000CC8FDA6986F5BAA4C1582E2637A7823CD1 +:10BFF00014AF9761C7962C82F55EB76F325BF2E0A3 +:10C00000BC4B48751DD829AB65B68F3ACF43A42BDE +:10C01000285C95BB9EC9077B3620317DAFF9CF8B5D +:10C020009219DC652921C547BF7FDC927BDBF708CD +:10C03000B40FD5815E0BBA8837563C66FE4A237C26 +:10C040009782DF0C2F21CB0D7068FD6A70885B84AE +:10C0500098791A3F93041ED761F2B15632DAAF8F46 +:10C06000733C68E50DA672A3A9BEC62732E7934CC0 +:10C07000C9FF38E89F4A5BCF34B4D308E58FEC683A +:10C080003D255A6FC3C5EA59A19E88F51AA5B1F19D +:10C09000EBD9A3FD35C5EAAF72D7B65782949FCAD4 +:10C0A0005E7EC20D41DF4FA4FA54887F556C7EC876 +:10C0B0000D783A2505DD40EF4F4262CCB8E07BBDFC +:10C0C000F8F23905F02390B529DE5F7CE446D0D73D +:10C0D0005F6E96312F26B0C51AB1523EAE6A593402 +:10C0E00013E2F7B47C8C951FFE14F60D03AD467A6F +:10C0F00096BDF0442AC489282699BD4D22687754FC +:10C100006DFAF334D0E301D2837C686E07E35F48B5 +:10C1100046B92F5212FB7ED7F215025CCE022D8F4C +:10C120007C0A79090113FF94F6AE279D0AC411DA3F +:10C1300025570AFAE5DF25DF053DA0E18384983D18 +:10C1400051BB75C3E863149EAE4DFFEC160C7E37F1 +:10C15000E3C3F3E1F9BF7A558DAF67CE717F28DA7B +:10C160002E84EDD45666FF9036F6AC90236EB03731 +:10C170002B9A642FE55052B1EDB9E79F023FED03D2 +:10C180002BFA69E5DB7EF3EE045A2EDF2EA7CC6492 +:10C19000D3710AA951BA04E8FF968E89D2A1ECD7CF +:10C1A000BF51D451ECFD4F93A3F428DFBE5F21A310 +:10C1B000FAE2AF20BC5FE974C6A04BF8D834B057A0 +:10C1C0006AB77EA580DFF5C93E810CC8ECDBBEB442 +:10C1D000E937B81E029E908E9C4EBD74EB43AFC8EB +:10C1E0008DAFE6613D0FE8C978F47A91EBE5CA5D61 +:10C1F0002E9204F1CF3F584333818E2FDDE38679B1 +:10C200009C94AA195F3FF3502AECFF95CAC1540FC2 +:10C210003ED9FBD267EF437E2B11AA53D93EA66FBE +:10C22000208F970F84F92D6CFC11CEAF98F891EF09 +:10C230004A9F110B213EFC8544A66F8F211737C8FA +:10C240006CFFE9E4462B24F9919360E7837DFDB60A +:10C250008871564216E33ED87D5A1C972CC1F217BE +:10C260007C5F6AB86CD1FC439B815F373DDC01F495 +:10C27000393DD83700E0A47808727C09B0DF2F1E62 +:10C280009D3A80D187E51B603BAAFF0BE03DD4EFD0 +:10C2900090719F50D78EEB4B36FEBD7C7C0AB70366 +:10C2A000D6B393A96CBFD23CBFA57C7EF4AF83E824 +:10C2B000F84B27DF4CDE37AD62F2ADC97B68D67430 +:10C2C000F8FEF93B4C7EA01DAC1F14AEC800FCBEAE +:10C2D000FF5601F581954462C9F52699CBB5F17BEE +:10C2E00080CA29C40528DC12E43344F984F69F8C03 +:10C2F000F847BFA4783D6DA7B3CF02301ED653A236 +:10C30000EF75EB4709D703D365A3FC93C6FE97658A +:10C310002F56C82408A665C50756F4BB2BB6C98599 +:10C3200030EF33CD07DFFD31E5EB33614D4E8DFA54 +:10C33000D32CA7A53B360BC09F66393D534A57EB1C +:10C3400058724ADFC794D3D2CEFF2BFA53C35BC0D7 +:10C350008437AA07872459E2E3CFAC075DB21A53AA +:10C360000FD2BF77487E5FBED3F84DE3336AA10D8D +:10C3700001FDDDCB8F1ABFF5F2A3C66FE6791AF186 +:10C3800066FE3E010C350A57E16E19FD928A36B6FB +:10C390007F43DB1DBA220FF1E3C3E58BD41FBA2222 +:10C3A000455F0E99CA61537D9FA95C68AAEF3795D6 +:10C3B000AB0DF52B5A0F2A2CC92862A8675DFA1419 +:10C3C000F938867DAFAD3381964F9520F0437A8F53 +:10C3D000027A4E5E4E4D33889FED15D1DFEA567BD3 +:10C3E000DCC9F4FD4376E6C7767B783989957BFA1C +:10C3F0002B75A0E7B4F73D7616E7EC2EEC7127E934 +:10C40000FCFB636DA21BF6833B432C1FB52F3CB591 +:10C4100028379D24DE7716179C2A3A339682FF56DA +:10C420002F7AC1355CB0EC7637ECBB75B70DBB69C4 +:10C43000367DBFF0B008E633E976B847035C24E800 +:10C440009306E6F3FC09FA778A047F3911F226DABB +:10C45000987DBD608DC91E76DEAB607ED97A5D5C4D +:10C460004BC7FF65BC9FD246E3F732B206F9AFCCAB +:10C47000240F7EEE0F1CD5E42187E4B0FD6DC2FCD5 +:10C4800058AE77A78AD937CDA678EF6E17316FF6F9 +:10C490007C9B48EA609ECD02EE7392607F94AB2A4B +:10C4A000D283FA4EC34B17C88D125F1F75EDFCD7B0 +:10C4B000FC07813F5EF9E3E8A7E9B3EB950F46EE91 +:10C4C00081F2AEF732FE48FAD62FD8F735EE237652 +:10C4D000EFB3629CAB7BDF6F331E84F2AB568C7381 +:10C4E000752FB7E23E4A709F2B3402BE0F66FE40A6 +:10C4F000EDDEAF46B33CC91548A7BFC8CC1F39DF36 +:10C50000F6EF1F42FEC8F9363A2BB00BF625A0DC39 +:10C51000045EB5A3FFDDBDF7AB7CBFF3EF379F2A09 +:10C5200085F891FF5C64F60EE0D724160F0EEC1927 +:10C53000FF1CE43757B6EC5720CE5EF0DA5F478336 +:10C540009EECDEC1EC9D7372E7B3B01F66553E5D95 +:10C550002E533C9F03E11944C873CA988260762C1D +:10C56000BC303C74533CC0BC285E4A41BFC7C34783 +:10C5700086F28F8A8F4FEF627AECBB98671FC58B6C +:10C58000E063EF5D219B80F367EFF77D351AF4CC14 +:10C5900099F032B4472E35EF6B15B6CFF23F67DE18 +:10C5A00042E472E63DF71F96DE8CFF3F82F5B57FD1 +:10C5B0005F39E8CBE7BBEEC7F24B2E2FC27B99F277 +:10C5C000FFD3FF6974DF41E9EEBE34DD9FFE879D36 +:10C5D000F7A5E87E98D3DDE581FDE5EEBD7FC5B822 +:10C5E000A936FF4BCDFBD5FF47E7ADD9EB332CD5B3 +:10C5F0004766D1FA4748647D2185F3F5F4A9EFCC6D +:10C60000A25F7F1BC71E39ADB0F8C76F09CB130CF3 +:10C61000A6092CCF83FB450584ADEB05592568673A +:10C6200014643D82F60191AA8FE4507CCCC858E88E +:10C6300065F96063F01CCA7503AFF5623CD0E41F76 +:10C64000165C7D7D3BF829079751F8E83807078B82 +:10C650001E6A299129E972C43A1A9FC7E079C83D38 +:10C660001DEB4D711AFDA399E0DFE8FCBDEB55E32E +:10C67000F769BCFFE9E4400AE4934CF7CA2404F5E7 +:10C6800048FD0AFD3EF234533F87C0AFD5C5CBFE0F +:10C69000A3F84BB7323FF2B764C9911CC05FBA8CA4 +:10C6A000F1C04BE28FB0FCAFEB06E6E079142279E3 +:10C6B000117F330655727C32BF59E2ED25675D0765 +:10C6C000C8AD44A8DFCBEC32F49735BFF7527826DB +:10C6D000DC9F96F8D01ADEA57419F35675FD225E1C +:10C6E000347AFC47E9A0D1EF3F4B8F73267AA47FC1 +:10C6F000EE91403E0BB8FD3FE5F30E11CBE95E092C +:10C70000F7A3B8FD3FC9992481FD7FAD745404B9E6 +:10C710002CB1B5CE8038BDCD2B205F5FD96541FFF0 +:10C72000C6962720DEB31A242C1FB578C682A17DB9 +:10C73000E3F7769D7980407CD8A7A0E14D0A597C2B +:10C74000FE2FDF7E3B513BAF81DF09B981FA5F0BE2 +:10C750001A49C441E7B75022C1C46488EF0AE423F0 +:10C76000437CD75886BFEFA746FBB954FD787AE4DF +:10C77000EFFDDC45F5D647942976C313F755282BF2 +:10C78000E8FCE3EFB6317C058E90D050D40B3EB17F +:10C7900050B76FF68895E98F5D7FDA910B71B149DB +:10C7A000DDD9894C9F0E47BF20C0FD82F3444D84E4 +:10C7B000FC83F36DC312715FB05D74F963C465B639 +:10C7C00072FFF99F209F823EBB37917A3887D14D07 +:10C7D0007A301E1BDC648BB9BF7BBF558B3771BAB7 +:10C7E000D13F513B6FA462BE4830514FB7AE999FC5 +:10C7F00048A3FBD201FE3ED2ED97FC57F10BFE3A67 +:10C80000E077ABBD735AACF3602B39FE6E3CF0356C +:10C81000C631AF6E6BB200FF5EBDC962D86F0C5AF5 +:10C82000B9DF35868C01B86E3C6077E5015DDA458D +:10C830002FE40F06DA3E55FC31F6ADCCF884FE212C +:10C840002EBECFCAE2FC7BE4F07CC0EB9EB336CCBC +:10C85000CFD9ADD497C782F34A3BD3730B49F89E27 +:10C86000D199FF78F89DD4ED8C4C063F7313E1719C +:10C870000C33FF11E4E3F35B089E0F05BF14F4C211 +:10C88000F966760E98A2642DF8D354DE7FA08FCB84 +:10C890005CD9BAFD9FC00EA86A133C903A5B25751F +:10C8A0002A106F0DB42689B0EEE6A85A5EA567D4AB +:10C8B000AD3AB9D86765F9C60727ECB903C6FDAC30 +:10C8C0004B21608FF85EEF71C3BAFD595B6E62ACAD +:10C8D000BC79EDF9EB1A32638A04FD10C4BB991FD1 +:10C8E000B29B1D86F2F744FF2090AF1BAD9DF77AF7 +:10C8F00063D0CF6F637C76D9FA2DF4FF997E7B47A6 +:10C90000D36F7EB150274759B63EFA6D402CFDB625 +:10C9100044500700DE97EC1D3600E8BAE4B0DC3F77 +:10C92000967EDB56C3F6F35EE6F9B0DD2D54BF5DAF +:10C93000A3D36F2D36CC8B33B74BB659F8BA7809E1 +:10C94000FD16FAEF91BF6DA0DF62CC77848DE90D03 +:10C950004DBF8D6E3B86FA6D748BC590379A6EBB5A +:10C96000947E13FADF0AF670BBEC4D88C13FDBB84A +:10C97000FDFD32CFC3837140CFDD6163FB9B97AB7D +:10C98000E7B2ED8CDE97D473FF4D78D6F4DC929D40 +:10C99000DA3947331F323DB76437D57302F023D3FA +:10C9A000734BF6B27B1CCCFA2DAB8F7E2358BF2A7B +:10C9B000C2DA075A3337CCA5FD8DF1C95E1BAD3FF6 +:10C9C00026AAEFC6EAF5DD1D3676EF421F7DD77E3B +:10C9D00079FA6E27D777548F0D05FD6AE60F6F9BA6 +:10C9E00031EF78CFF893CDBF06797943C47DC3A3E7 +:10C9F000FC5CDA9BE34FE6017F35DB98FEADE5FC9E +:10CA000077AE2688FD17BCCEE657E964F9C8552DE8 +:10CA1000CC3EAC6A16422AFDE7B4095F2B00FFA2A8 +:10CA2000BD021940CBB3ACAC3E7941DBF722337386 +:10CA300074FCB0605C39C6ED1748C40671F972E742 +:10CA4000B44F201E5F3E8EC5F1CBF9FB45873BEB13 +:10CA5000209EBDE84901F73D09CF07D0F21B4BDA14 +:10CA60009661BCD69C17A0E9F34521E3FB72533EC7 +:10CA700063139FE72CB113F142DE1263E62534996C +:10CA8000F1D1CEF1B149C475B3171F143F6A665F87 +:10CA90007C508ACECC498DCE7FD11B745E79D17902 +:10CAA00069F830CF4F8B3B97F376F1E6ABE1AFCF30 +:10CAB0007C357C9AE6FD1CE80D5008392417F2629B +:10CAC000281FA0DE08FE4EC4F3FB8593460CD0EB76 +:10CAD000E1AD5C9FE7D64F2A1848005FA41AF8A67C +:10CAE000B861F1A18174DE63DF57C7C0F2F8BD09F8 +:10CAF000563FEC8F6EB5F7A05ED3F8EA1BCE57EF2A +:10CB0000723CEE19548DE75403AD8207EC8A40C4A1 +:10CB10008EF80B50FCC1F995003FBF18A0FC05F240 +:10CB200074F0C92F19BEF60A2AC4C7A769EB0FE033 +:10CB30009FD6CF6D63F80F8404C47F1EE9C1FD91B9 +:10CB4000AA06C11BA1F5AB5A1763DE83A66FE99F46 +:10CB5000534F0F1D3F4AB1F8112BE9D6BF725EEF5C +:10CB6000466BFDBBC09F37BE2093261D7F66D1FF5D +:10CB7000BE8D41270D9F97E2CB0B1C4FDB008F4EE4 +:10CB8000C0570FB39F225FE3391AED7B400A1AF0BA +:10CB900058F0D4858BE269AC8627E053D0536D45BD +:10CBA00022948B5B05D22FB3EF3C617F522FB78B62 +:10CBB000F61E63FD3F23E0BD2566BED5E6DD876F2B +:10CBC000E3F02B9C4B03BFE872F9F61B13DFBE6941 +:10CBD000EF39920B7CBB5760F183B624C3FEE22091 +:10CBE0003B5BFFB7DA297FC3BED661D9BB51ED2BC2 +:10CBF000DF097CFD02BB5F7F2EE92A9808E43D6EC9 +:10CC0000B1611E19C23194D9957ABDBACD4EFADF01 +:10CC10009A17BFFF81BCFF78768D561E05E341BE93 +:10CC2000572B1D2F2B3A9E59AF6B7EFEA5E635F292 +:10CC3000BF38AFDE3C4CD281FB4E9992FF31AB2E18 +:10CC40000FEE369E67442140FB4A572FDB76917AE0 +:10CC500024CD83E79FEEF1687CC6F2DD0B791EFBE5 +:10CC60005471E27BB07E7EE663FB7C7916F2FB8931 +:10CC7000A09F27CB788EEFB32332C66B3F9BC2F2C7 +:10CC8000386F7AE3A004F1999B4039517CDC34562B +:10CC9000407F058E61C1BED92E6ADFF846E27C7204 +:10CCA000E11C57CEA6FA02387F3C664BA8169EDEE2 +:10CCB000829E9437018F93440278ECF0F52B80FB31 +:10CCC00093EEF933C1FB43E83A8BEDC7B493FE50C2 +:10CCD0006F82AF3FBA03E35BD617407C74D641A79F +:10CCE00013EE67C96AB4509F218ABF0924540B719F +:10CCF0009BF1C77DB700BCA5D45E80B873695B5358 +:10CD0000AD1BCA8D8257A5FD0782FE696E3A8F6DF5 +:10CD10000D9F4EFB0EC823AD07DD041A59BDC0267A +:10CD2000B87808DEAFC33C9BE24D021EFCDA161257 +:10CD3000888DF51BB2D17EB735D2F679B04ED0F6DC +:10CD4000D0EFA64FDFB905E4FD88C8DA37B37DEA36 +:10CD500062DA4E05BEDDB418FB5BD4289034DA5F8E +:10CD600069335B074A8FC85EF8DEB2FF495CC7666D +:10CD7000D2F1066682DE8F4C8132C9153C18EFACC9 +:10CD8000188974EBE6724E268E60FA43E065EE3742 +:10CD90006876D3BB7696EF5BEC5DA6F4A3FDBC3959 +:10CDA000AE7F26A405045A3FC5FDE7E314CF7EDA23 +:10CDB000E5519EB77170DCC74AA76E1DFACCCEEE66 +:10CDC000B75AD03A09F319169242CC67B8713CB3FE +:10CDD000D7DEBAD61E822B0EDE927BD2E1FDC16B6E +:10CDE000AD68FF9EDB26231F9D1BDC89F1E9938D37 +:10CDF000329E1BAE6D64F7739D6C66EBB8F80CDB6E +:10CE0000D72F7129583ED878CB3458DF4E6E62E761 +:10CE10001D0B9E99AA40B9A449F0B2FB8B987ED411 +:10CE2000FCB7620FCB47D0F45F259F779FBC45933B +:10CE3000BEABD4D61B93BEAB847D65373C8DEF0370 +:10CE4000C4C9F420D8FD40F7C8D7C8BF554764020D +:10CE500076BFF071D734CCC7DA2B603C7F7C9BE087 +:10CE6000837DFDD2F7AD21B457434577FF04F4F835 +:10CE7000075622A890D74EF14EF5C3386BCF9F7E50 +:10CE800041DF7F72D4069930944F8A10CF5AFE67E3 +:10CE9000DE6696C79277747D2A9CB72453FAA1BEAA +:10CEA0002D6910895FA7373E117CB7FC98E965BCF6 +:10CEB0009F42A35F9E525F0CEBD83007D34BEA66CC +:10CEC000197244C8611E27A1F6349EBF5DB47B5D14 +:10CED000AA42EBD5F1FC8F457BD7A58AF47D2DAC1A +:10CEE0005FB4FE2285F5BF689FE069D2F5AFB5D784 +:10CEF000FAD3FA51761BFB19B697972FB31F0D0E75 +:10CF00006DFC78F6F8B87FB9B01EEE8B19F79688ED +:10CF100049C7E33E9E394CBFDFA13DB5F86BFE3BF0 +:10CF200016E2D3E16DDC9F1CC4A7E38B96B154BE1F +:10CF300029DD6E681542004ACBD8634A651E963DCE +:10CF400020CF553C4E5B3585ED5BB5E41C5D01F2B1 +:10CF50003D334F403E2041BFD22F05ED2015F6173F +:10CF60004AF258FB12DA1EE4AEE5492687541FA8A0 +:10CF7000A02FAA1AD74DC3FA9B0415FA6F692AC2CB +:10CF8000F5BE749C48F0FBA663687F94B61E4B0107 +:10CF900079A5F2B91ED6DFAA8956BCCF4B933B4D7B +:10CFA0008EDF92F97D4D36CF28C8EB7F10808A2125 +:10CFB000BFE211C2FCD46619E52C308EC9E55BDBFB +:10CFC0004494E783D7DE8E72786EB310478E0B14CD +:10CFD00038977C32C4BEF7CAF15681CB31D30F27C4 +:10CFE0009D4CAE0BE03BC8F14E81FB83CC1E34CB95 +:10CFF000B126979792DFF22D26798E23B71D52E73F +:10D00000AD30EE3DD7DA11EE82EFEF7EF71ED43F62 +:10D0100032E67D147CFF8154D077C512CB57D2F015 +:10D020005829B17CB63E70AC5FA60CBC2C788C70D5 +:10D030003C6D7745F587087CCEEEE10A6E9291CF84 +:10D04000CD72F85F959FBF973C1FE6FCA3C123EE0E +:10D0500065ED217F2C42F1F4DBE6E7304FF5EC8BF8 +:10D06000C76E043C97EFA17C4BE77BAED9C5EF7B45 +:10D0700009E13A53D622621E389122F9B7B8F47208 +:10D08000C9F290CA5F76217F94ED60F9A465AF7C08 +:10D090003C1AF34496F7607E55F0456E6F063B47A9 +:10D0A000035F97492C1FCA2CE7B73A98FDD9B53BC7 +:10D0B0006136CC43D8C2CEE997856F97810FB57A98 +:10D0C0003F74C85A3DDCBF0C52BE85FD75804F7F52 +:10D0D000EE5CCB83EADACAE4BEAC55467FA96C4B62 +:10D0E00013C6B1035B3EC53CF78297B761FC20D005 +:10D0F0002A1AF31EB788B87F459FB84F65CE3FAC5C +:10D100006AA9C4FDB6AA30CFEF33E5BF95BFBCF71F +:10D110009520454DF9AF5F70831E38DDB1D90DF80C +:10D12000A4FD61DEE0F73F970C7951F1F37B7DC6FA +:10D130007CC2F0AA98F984A7E11F94C11F70707E89 +:10D14000D5F230B7F4E379DA91FCC218F1FBDE7363 +:10D150003BDBBE7816F2DCBB769C7916E0AEF8DBE2 +:10D1600067CF423E13D967C77529F0E2EF314F58B8 +:10D170006BF70B07F7F3B7BE80F9D5E73EB0A29F78 +:10D18000736EEFC90CC85F3BB7FDEB5488C7DDBBBE +:10D19000772AC62BEFDD593080C4D0EFDA13F8328E +:10D1A0007419F9DD663A1C6C3988795767DFB7A2C4 +:10D1B0003EEBCD0B0D57B23C5B95E78336C7CEA354 +:10D1C000D7F218AB5A6EB9E95AD0CF2DCC9EEBCD21 +:10D1D0006BBC541EE83B949ED75C06DD9A799EAFEB +:10D1E000896E67E11F943E6113DDBE6859F8ABA7F5 +:10D1F000E05B4BBFB879A091CBC09796A7FF738730 +:10D200006F8F03CEFDED4808A6317A85660A60EF80 +:10D210007D9101E71A4EC93D98EFD1B3D7EA817CE1 +:10D22000C6B2BDEFA17C9CDB7914E3AA84E7C99F59 +:10D2300023BD7F2CAF59E0F3DBE462F9A31CEF9030 +:10D240005FAABAF13DCF23657CABE597C6CB2BED4A +:10D25000710C6571687E6EA092FA49FCDEACDE7CD2 +:10D2600053611CD0E998214F579BB7B93F0FD79B0B +:10D27000D1FCE8D879BB5ABE60944E6C1DD1F29FA8 +:10D28000CF35F1BC69FA3E7D0CE4C1B1F53A10121C +:10D29000DE2331E451CB8F3EE330E545872E2F2F3F +:10D2A000FA52F0FE67F1F1A183C5AB35BC74FD25E0 +:10D2B000B63E561298DD49FD533901F705987F7A3D +:10D2C00037F74F357C69F0D68599DDD0B585F907FC +:10D2D0006679AE8A735F520A1FA7AA75FF68D03BB2 +:10D2E0005D0776737E63FC5CD57C8CE5DD52FD1CAE +:10D2F000D2EB677EBF84B9BF0CDE5FA02D767F8145 +:10D30000E64F63F6775AF2DD0EF09FEE6076D2E9D3 +:10D31000B0383DD6FD36B604D9903F50E762F76588 +:10D32000886E07DA47F7BAC6BD9F98024F05F37AB1 +:10D330006A97F13CA09F79F15ED15AD70C02F03C7C +:10D3400004F8D1C519648F9F809D26A715E6896AC8 +:10D3500014DE5E7AA45848484F7F29920EFAFCC327 +:10D360009C9332F4F76FA6F8C8BF49A46E0085EB12 +:10D37000DF828277991ADFAED6CAFE9F8A86784608 +:10D3800095B5E743B0CFC96B76DC0F17F7D9831893 +:10D390001F7B96DDAB7170E757CFE3BD3CBFB21288 +:10D3A0006E170AA00F4A789CE2E4CEAF9EFD77B0DC +:10D3B00023A1311DBFE4595A1FECE7E604B4F7BBC3 +:10D3C00077248E863840C96B0FDE08FAA204741FDA +:10D3D000D8992F0F08D5D2FE4EF467E513DB06E38C +:10D3E000B980F21D2ECC273CB8735715E8FB732F7C +:10D3F0002710D0F767E5CEBF4139B0279134A9682F +:10D40000F7A9FA7575119154BD3D570E65437E0B12 +:10D41000C1FC168CBF517E2E6F4DC4F31FBA7A5CCF +:10D420009E8383F83D518340EEA8DDA81AF39ED970 +:10D43000F705094C7F05AC3DF7B3FB1058FD80D2D2 +:10D4400053CCCAF58398DC7660FDC51ABFF2EF7D38 +:10D45000FB65F503092C1E10ED87B5AFB2B2FB35A5 +:10D46000CCF4FD6982C0CFE3FEF5CA58F74FC48003 +:10D470009FDDCB259020DCBF4AB6DB314FAB428924 +:10D480008C847CF55714B6FF51E18E8C847CF53D7D +:10D490005CFF55386899BE1FC4E180FA5026B6CEAD +:10D4A00097F05EA75D76BC0FAFF235970FFD8457FE +:10D4B000BE3AF1741EE4AB25609E74E56BFF0BE988 +:10D4C0005F698DDC05FCDFB3DD8AF793766D3F9CE9 +:10D4D000017643971CC948BEC8BE4E65D86AD8A716 +:10D4E000D6E671BA66E90438C7AB9D332C8BA32FFF +:10D4F000DE4860791D4D09BE5F313D67BC5FE67453 +:10D50000CD6CC3BD8965B6D87AAC19F4822E8E274E +:10D5100046CF153643BF674967DD204A924AA107C7 +:10D52000F7C7CBB664A683BF7BC07E25EE5B1D909C +:10D5300055F407E1A9D7C7A76ABCB9129EA7CFCAFD +:10D5400095281CDD4D9F160F22901F689F1D4B3F95 +:10D55000ED4D48407E2AB359639EDFFC1DE7B76D51 +:10D56000206F63D978DEECE8B807E49002704C7461 +:10D57000AA389F32EA07B07BA2E6E4EACF6D2F9289 +:10D58000EAB11E952FC4C722B25EC973F6D52B8BA4 +:10D5900096E6E54AB9A8B0BEE9E537314A27124C0C +:10D5A000413B49E23424EB071AF2FD25B9D006F8D5 +:10D5B0005248A1471281D4F528A70E12C6A7939A04 +:10D5C000216C1DAA26101F3FC5F767AD92FA18DE21 +:10D5D00037D32EA23EBF14DEDE4B7023DC56A99A51 +:10D5E00078D1DE98E9017B4C08FAC9B7941F6A6BC1 +:10D5F000A6E7B273E1C407796E6EC2E0737B0E7D5D +:10D600000DF601E533768FD5F749A8968E07C78CBE +:10D6100031FE3799DD676F1EEF2F9C0E24B8DF7047 +:10D62000DF39FCF568F7E781BF9EF8B771B01FE3FB +:10D63000F49008D84B094E1249180DF7E449A7F5A4 +:10D64000F2EB26AC3C94B233E835CF44E377335F5A +:10D6500013AFF479AF5E14B1FDE7A6F69F5FACBDE2 +:10D66000868F806DA3F7786E142F0E3E87E064EFEF +:10D67000854EC0C768B7B716E8A8F47CF820E06309 +:10D68000B493F983290D44EFAFE53A99BE5AC1EF3F +:10D690009FA67F854E5D7FC463C3F8E82A8EF7DEC0 +:10D6A000FA5ADCA44F7DBB0478ED53DF1EAFBE23D6 +:10D6B000767D573C781262C39314A7FF60ECFA554D +:10D6C000AFBDF7664485974C6F40709E9F5BCE75EB +:10D6D000827F95F8616A11E30AB61F60A29B03F886 +:10D6E0008FF28363B8EE3DFC5FB68E7E4363D09FBE +:10D6F0004490EF8A383CB4EC1C48E1FB310777CA10 +:10D7000026B65F39F75E1627FAB18DE5971EE3F767 +:10D7100001CD6D607EF5DCA56C1F9194B2733E1E49 +:10D72000FA1F8C77277442E97D67BD108A64C2BDF9 +:10D730003526FBB5F77E9C450AD42F32C55D347E75 +:10D74000D2CE23CDE7F67526E7CF85A4C705726F45 +:10D750003EF7FE3AD76B9ADE0FAE2359706E5FB478 +:10D7600038BCB03F2AF273A6C4CDEEF323BEC1ECA1 +:10D770007E392D8F2B4B4D84F58D84F97BBECFB236 +:10D78000E47A7580FE9C9674C181F783D4CADE3436 +:10D79000D083F2056AD751574DB93094A8BA736453 +:10D7A000D49E43E1963DECBE44C953484AC00EE4C2 +:10D7B000F703909419BD76D75B140F4BD6A9786EFA +:10D7C00075A193D999BF7015DEE31C0BF6E5382FD0 +:10D7D000BBE7D648C7E04E36BF5A985F665FB86B66 +:10D7E00015AF17EDCE19D462C0388E177FDF41B464 +:10D7F000AAEFA9208FFF2CB3DF2BE8830746BFF3E6 +:10D8000029C9782FFB02F7EA0F814FD7F0FB0857A1 +:10D81000D664E173754D1ADA9D75355E7C6A78B110 +:10D8200079EBF1DE37DB70D69FCDE3677605B56522 +:10D83000209F42F25447A06C4BAF2660EFDA7BF199 +:10D84000538FF8517ACB7E2C5B3DEC7723E486999D +:10D850008867DA9E94D0EF4B5CFEA7404EECEAD589 +:10D86000867BE4AC69634CF70D9AF0A6F1C7368667 +:10D87000BFB502E30F33FED6CA1D2AEC2BAFBDBEE7 +:10D88000F7DE19C41F35EF19FE7EC7F6D9E2E2CFE5 +:10D89000938CF6EB82FCBABB204FFA11BEBFF87036 +:10D8A000CD38C4D72A7E8FE443353E7C8A803F3A08 +:10D8B0003F6B7690C0FDE8ECB721E8D359E883FBD5 +:10D8C000678177017FA293E1D39A568DFB6B362750 +:10D8D000C397E80C225E6427C397E864FCA6F0B205 +:10D8E00004F8CBC5F6F89EE2EF00F0972D7D82019B +:10D8F0005F4ACAE4CBC3DF93147F148E142E5F6695 +:10D900003CA428EC7E4A4DAEE2D9714FD0F9C3BA9F +:10D91000BDA186E0B37F1C7F71A88BAD9B2996EAE1 +:10D92000FD32E02399F0F52448D2F3094B3D84BF42 +:10D93000B42051A12C303848FD60C3BD92A24732BB +:10D94000DDCBA66E003E587F58B640BEBCB874868C +:10D95000E13CA838DB97A4223EFD784FF323352A1B +:10D96000D26F1DD011EE01E5FED7439C9E0FF37BD5 +:10D97000285771F958CBE5E5312E27B5FCDEE435A3 +:10D98000D3599E554A8E85DF571621FA3CA6246F3F +:10D990009828142EB4A9557CE23D8BE47D6B680475 +:10D9A0006D97904D7CC02749EF3F1062F735160EFA +:10D9B000043B2849BB7F71A29A34070FC24624E674 +:10D9C000775055887E4C8725D63D55B5DE03368881 +:10D9D00087C68327C1EBCB7C888E97D0E042FBBD06 +:10D9E0009FBF70CE425A76362460FC2F81FF3E8B5B +:10D9F00093C25DA2A377BC7BA837BAAE4F74517AAD +:10DA00007A0046FA7CBC6118FE2ECB137221FE8E82 +:10DA1000CB137C3DD5EE39D7DA7DC3F5A33BEF6A56 +:10DA200083DFBA5EF6613BCF44A3FCAFE7FA3679F9 +:10DA30008A91CF357D7BBC57DFFA87023CA917A6B8 +:10DA4000A01E4BB939B6DEAD9515BCB7BC761493A4 +:10DA5000F36091C2CEB5F4D50318A73EEF1FB911FC +:10DA6000F4A8C657CB09D33B41E2F0E23AC4EFB782 +:10DA7000D1ECE095700F20D7AFF01487B3DF1F48CB +:10DA80009DCBEEF35DC3EFB17A94F215C17B4FBD30 +:10DA9000F89CE162FB13CB6D63F03EB55AA705F528 +:10DAA00084F48135042687B47FBC07E20592ECED4F +:10DAB000F041BCCF2585E1DEDC5A671EDEFB2E245B +:10DAC000E57980FE5FBA160CB9583E1D9D28DE9799 +:10DAD000E94929241F65E36E009E5F913D37138855 +:10DAE0001B6E48A9B603DEC6BB585CBFA1281FF158 +:10DAF00048F17B93AB7FB49F01B367F4DE8305DD10 +:10DB00006E88730EE60E17B397487A900CD7C979D2 +:10DB100083F63B276A9064E9E47DF9886904F68717 +:10DB2000FACA791C3DB699E9B115426C3DA6D9995E +:10DB30009A1E934DFA417BD60D996E38A7A5A4780D +:10DB40008177E119B478C1BE7BA5EE8E24C443353C +:10DB5000E081A4CDE8F55F7F3014ECC7FC98FC664B +:10DB6000D65F0B7AD7735F2AD0E994AC0E9803FC8A +:10DB70007438F67A3EE9F1AB1E033E58F03B51D0C3 +:10DB8000EFA7945C5889EB69F18571F82C6D988E3C +:10DB90007C4F200AAEF3C34E36DEE706B84E36F0B1 +:10DBA0003C80463904F919271BEEC3FB4A20CF5BA2 +:10DBB000D4EDEF933C15ED4BED9EB193A17BDCFAD8 +:10DBC000FDDDE25FD87D60B7C6E3AFE2C6D87E3D3B +:10DBD0009E35828D3CE2CD027B98DA373D11B07FD5 +:10DBE000365ABD41122D071FB7C7CC4F5CE29AFAD7 +:10DBF00004E07D89CBF70CC83971B27B41E3F3397E +:10DC00001BF7046C02C37ED3533C4F53F2BBF5F7B2 +:10DC1000BBF5DEC7C9E324C416E7BB43FB7D8338ED +:10DC2000DFDD2C9F8378627FD7FC8484A89FD00A95 +:10DC3000F3A86C3853F701E289FB091CEE533283D9 +:10DC4000FBD4F356F63B3726BE38C5F34716090C0E +:10DC5000AF1A7F9FEAB577FC780F8D99FF848D57B7 +:10DC60006D184FFBFDAC5DC6385C05E51FE01B6120 +:10DC7000E378CC5F171E1FFF18E4257D7E44C4EFB8 +:10DC800065176CF8BDEB67DE0D7321CEF3868CF75C +:10DC9000757FDE3E3591C5798C71E8856EB6CE9F75 +:10DCA000E6725F7C6135F2672F7FD42F5440AE8AD5 +:10DCB0002F3C8AF64CF11601EF8924C19E43932430 +:10DCC000CE8713A0FDD969CB01DF13EB717FA3646D +:10DCD000B3D5BB5AE84BE7D32ED570AF7A49E71AD4 +:10DCE000EC97507B2A45B7DF7D8AE701975C60F7A8 +:10DCF00003124F90A401DF73BD13E55FE3BDAF5D79 +:10DD0000F6D871F66FB83D537C6182C16F88CEEF53 +:10DD1000FB4C3EF97A5ED2398EC1D53B9F0DE36351 +:10DD2000CD273A8F89D8BE2B29F6F8991CCF276AC0 +:10DD30004AE1E406295558BDE2FAFB14D027C58D07 +:10DD400049C9826E5E250DE5863C8C92C622659E91 +:10DD5000AEDF281D1CBF9D343C4A87CC47E5EB96BF +:10DD60003B61BD2F74B961BC8D8BF27FA2427F4CA9 +:10DD7000FF7C22D76754A37EB9C71DEB5C43A65B2B +:10DD800035C4954A1A387DA89D9CA7A38F46177362 +:10DD9000FB134D25F93F8178F293EC5690F87AC742 +:10DDA00044B7CCD8789BD08BB72CCC07BA34DEBE26 +:10DDB00063C8FBE983374E5F0D2FDA7B6A1FE502EC +:10DDC000BE2640C0A93FF4C3E87F297C45C7E5F4DF +:10DDD0009F147B1EFEDE792C25416A3F2CB8E43C63 +:10DDE0001E2441DB45E6A1D19F5C6DA0BFFFD11190 +:10DDF000D7811C6AF45E70E049E4DF05541E615F60 +:10DE0000FE64FD7D86F5210A5F1CBA0F0F92ECFCC3 +:10DE1000FF7374FF440E6640DE57701D5B474E6D06 +:10DE20007C24438FE725AE490B812E6453FFCB5AE8 +:10DE30003F8293BDED2AAE4B32C6C376BBFC0137A1 +:10DE40007D5FCAFDEA1549D346C65AF7A95F381166 +:10DE5000E2CFB535D32742BC4DE67623FCB216D8C7 +:10DE60009B70057AACFBB5EA395D1FAAA9C6F835E7 +:10DE7000B10589477FDE9730BBE81BC2E22D5A3BD4 +:10DE800045F67B20FEA908A410ED39C9BF32330F37 +:10DE9000E2182939411DFE1E7533BB6E4DDA010FA4 +:10DEA000E4935A69FF108FB1A54BE78DFB94AC9CAE +:10DEB000238C97613E724A98603C339BBED7E15BEE +:10DEC00049A1705EC4DF946C6EDC2F9208B3D3B4AA +:10DED000F9D337B89E3DCCD7A5E510C74D013BCC53 +:10DEE00082FED07A1EA7FC654D21C78384EB98354E +:10DEF00089D5571219DC76885B8BB0AE46B0EC82C0 +:10DF00001B7644BC9A0C7F7F3489A8F83B7DFD4882 +:10DF1000A40EEF3199D4793FBCF725F8B7001F7CE8 +:10DF200039B0E34301E2D085FE2B61FD6D108339EA +:10DF30002AADFF2BB12707EAC1EF7BBD9FCC9E43E3 +:10DF4000206FD9AFDB9762F772AAFAB89EB93C642A +:10DF5000A964DAAFF9CB95FAEF4D09BE5D0047CA67 +:10DF6000C702EEC3D4DAD9BD3EB5AEDB1261FD3EC9 +:10DF7000CAE985F407FE696776CC79494D4CC6F845 +:10DF80006656EEEB86F1BD86B2C4FDB74D941F25F3 +:10DF9000DDBDACC3259F05F865443D7DAFA75F8C13 +:10DFA000B85AB213AFBF8DB90FA3C147C725803F81 +:10DFB000F1C234B6BE9AF8608FC0E00FBAB8BF4560 +:10DFC0008222D0738E765FB0B48295B5DF8B002A43 +:10DFD00052383ED0F617C80A56E6FB9481796C1F7A +:10DFE000D20CCF9CB6873B20AE3FA76DE07CD89F7C +:10DFF0009AE31CF96778EE917B0E24801D789F8050 +:10E00000E73F7EFCFBD7E504FADCF9CE463C6F7CAB +:10E0100096CBDD5DA407EF61F7130FDF270FE1FB60 +:10E0200079F00373580ECBE0A7CF8D847E74032D57 +:10E03000DDF97AE80630DBEE6AEFF90DA8017FD84A +:10E04000330DF700B476ADDE43ACCCDA45F160E3D6 +:10E05000F6A80DE7159DB70DF1F0416FDE7810E9D8 +:10E06000D18B277EAF928697DE7927DE3603E2BC1E +:10E07000F1F4D91C67D69FD9E60783CB8CA7CFE1F3 +:10E0800013B5233F77FBEC8954BF7DECF639E0599B +:10E0900061EBC99086A2BCB8A15C25FA87A4523C6A +:10E0A0009C1DECBFB23FE0A3A3DF65E9D10FED4CAF +:10E0B0000F90BC0C9C8F76EFFBC1074EBAC0EEAC44 +:10E0C000DBF95E063C2BC5CEB5B7637C53447FE8D5 +:10E0D0007CCB95173D1FF621C49DE8FA372251E30A +:10E0E0004336BFBBF9F99ABB5B12F07CCDDD4B45E3 +:10E0F000C3BDCD772F65797744EA187DABC15E5FEC +:10E1000011B71F880398FB99BF7432F9B81FECB39D +:10E110007A26615CE059C65FF3A7F844C8479EB011 +:10E1200052C078CBF8E36A6B272DCF0F25E1EF1DA6 +:10E13000CD7F60492EDC4350D5C1E27B03C4C53995 +:10E140003F83F8C901B68E437931C8B7D3A73A7572 +:10E15000F1FE2EB93A07EEDD0BDEE9F401FF14DD26 +:10E16000EAFB007F2F91C721B47575574311E6B1C3 +:10E1700016CD55C701DD8BC276FCFDC1221B911C5B +:10E18000548F1549C406CF010A91ECF074101B3C62 +:10E19000F397B37BB28B1B66A17DE01E57A8C0FD31 +:10E1A000B7456D2F7C01ED4BA4C87E76AE85E1A707 +:10E1B000A8EDF0D7C03F0B7D859877F89D2D8AC1DB +:10E1C000FF1B153696AF6935967322C6726EBBB1CA +:10E1D000BC15EE38D3D91107F65A719D283FC3CE2E +:10E1E000E9BD2AC0DA04F1602BCA5341795B3EECE9 +:10E1F000479F79C96581EF7BFECAFCDE9EAD76BC88 +:10E20000EF6DFF1F1CC40179852FDB37C2F7338EFA +:10E21000703EC4E1687DF63B5B85E191E0BFBD7275 +:10E22000B5E6A78746C3BC5EF91BCB93E9D96AC59F +:10E23000DF4F39B3FB8597605FECCCD62BD0CE7A1D +:10E2400055085AA0DFE02A467F339F966F31FAC502 +:10E25000F727327DD32D307C5FD9609CF755216341 +:10E26000F9E789CC9F9A4774EF3361FF5EAD4B832A +:10E2700075F5B9D8F70D3FC4E5E2C517158D6F45A3 +:10E280007E3F1B5175E797F644F7EFEEBD02F22A89 +:10E29000001743A3EFCB4DE36AFD1726B27DF814B8 +:10E2A000BE3FD3F38688F8396DFADDC25EBBAEA6F9 +:10E2B0007AE014DD3A54DCB03FB508FCA3C6FDA9F2 +:10E2C000F374EB4BC5D683A977605E9284BFCB54C1 +:10E2D00031E7F94727A4C07B310CF0C277887B7502 +:10E2E000857FE3867AD4DE1D23EAF05ED270DFC03C +:10E2F000293A39FD8FF2A5264F15DC3ED935AE639C +:10E300001AE4899737B0DF6F2A0FFFE816F8FD454A +:10E31000D2C8CE99E64BA450A4F253B1FD473F8436 +:10E32000DFE30A3C33D60BF0D02E6E85F7E5CD9FA8 +:10E33000E27982D5A6DF11D09EFB387D69FD888504 +:10E34000D65F7D9BB314F413EDF775281FC8DA88E8 +:10E35000F79BB84FB1382D7DFF3EFC24CAA9C9C137 +:10E3600037EFA04DCF90F0BB3764C2BC8D7C46F92F +:10E370005600BBAB67B380BF6B4B2DADFC9BC1A4FC +:10E38000F62DC3BC5BFAFDEE58E79D17858CFD9812 +:10E39000E9FF07CEBFF42F4BCF47E67AFD6606F1C3 +:10E3A0005C62C552AAEF74767EC5F17ABCCFD13CCF +:10E3B0000E06E174F906B05EAA28DF76EDFE21C1F3 +:10E3C00096CFF36687B132DE5B08FC4A19A5FC6A7A +:10E3D0003245057CDF4CA6C3F35521F2A828323D17 +:10E3E0008171A06D09A827BA3C9DCF3F0DFCD53C9B +:10E3F0000AE34F83F879CF2E3582F73C76F3F86441 +:10E40000978795CBDAEC980773E6AC827A7459F863 +:10E41000A01BE8D1F592DD02BF4B7A667BBFC990A5 +:10E4200027D91566F7FF9E0EF7C3DF7F8DB76E996C +:10E43000F581B64E1E837FC27A9AE8FB06D65BB2A0 +:10E4400082E5910EE8579D13EBF724B476294A75BF +:10E450000EF829FF1B63EBB5D4008000000000001C +:10E460001F8B080000000000000BDD7D0B7854D5E9 +:10E47000B5F03E73CEBC92996466324926218F096D +:10E48000841020E024860814EB24040C187542D173 +:10E49000A2B638804080BC44DB46A55F26244242B9 +:10E4A00051428D08087140B1F48A6DB0A8C106EFE1 +:10E4B00080F86AB537DADE5EB5FDB92370295A1ED9 +:10E4C00023F452DBDBD67FADB5F799993349AABD6A +:10E4D000F7B6FFF7FDE9478FFBECC7597BADB5D722 +:10E4E0005A7BADB5F744BE6EF1EC2D60F0172850A5 +:10E4F0009C8C5DF2BB3C9BA0BC4482573318333AE2 +:10E500007C465B3A63D672C6BCF0CFF186BC5786B8 +:10E51000FA53B2E79BB6718CDDC57C0686CF72BF1D +:10E52000818D853E9DD0388BB1650A0B290E782EE2 +:10E53000F4BE2F4DA53263D07FD92E29D801FDEF2F +:10E54000DA6C64CCC4E8EF33F8B7A217CAC5B1F2ED +:10E550002A16343019FE63575C3B187F95123A2A0D +:10E56000A530B6DAC442C930EEEAA7B4FDD6B01081 +:10E57000C1D370E03363FCF8303FC600B4FF64EAF7 +:10E58000BCBC6EDB34C69C0628C3BC236FEB8388FF +:10E5900087FF907D34AF35CC4FE3DCDE5AC54EA506 +:10E5A00031D67C5F6BD65DF0BCD87A7FD65D5743A1 +:10E5B0003DC201DFB730DE9FC1BCF601CED654B3F9 +:10E5C000502EC0B71CE69B5406E541293405CB26E6 +:10E5D000164829E3EF53CBF87CBD71F0D5B31EFA92 +:10E5E0005EFD2EED7BF68B34C267031BA27AF654D8 +:10E5F0005C3DE0A341E0A1E100BC8FC3C3CC03526A +:10E60000C07A1596821D19005FD359C63641A9E913 +:10E61000D06746CDF8AC8731C04366126366A0D799 +:10E62000A3125BD45F42FD26D64D8136F8771D9646 +:10E63000DBA9DD0981BF476F5991E587765BEC5017 +:10E64000CE16089E0EDFD0E1C7A91C32C17792AE6C +:10E650008E96A9BE623D2FD7D98A6BB6E730B64DEC +:10E66000EFCFB2011297C9BED77480BF271DFE5BE2 +:10E6700090DF96E9BC790ACE97798B7C00076BE531 +:10E680007878ACAC65624B490CAE187C9CBEDBA4C0 +:10E69000FE900EF82C7058F2EC7323DF46F47E4B9C +:10E6A000AC5DB34DA279A41E0BBF3606E9FEBCC417 +:10E6B000F642BB1DD287AF8D817E3BE6B9590794E8 +:10E6C0005D4027B90CDFB34E09F0527EA8EEEE573D +:10E6D00091CEE5499EF1F0683C5429375A68FE779F +:10E6E000FA009ECCE4963D3AA8CFBCB3B80CF91B17 +:10E6F000E67DE702787FAFCD4DDFCBB270BABBD6F7 +:10E70000070AD696E0F77D77BF0ADF8B4C49F2E027 +:10E71000F733015756073DBBCCD88EB54BD8EED159 +:10E72000143E7EBA4EBEB30ECB65BCEC582779F7CB +:10E7300012F36DA579671A590DC289EF8325B46468 +:10E74000BC07A93EC8E93BBBA514C7CB1CC79F4E5D +:10E75000432807C7794BA5F760968E6520BCF0DF8C +:10E7600000CFBD072B331DD0FFAD732645970A4F51 +:10E77000176343D84E0959183E0B8B797B93685F1A +:10E780003A3B131783334FDBEEA2DE9B7A35E0254D +:10E79000F08ECC901EBFB37853EDD0EE4B063E8F7B +:10E7A000443AF6217D603ECD9F02E46971745B744A +:10E7B000C580E3357FAAB0E0D5B1F7E7DA4C2C5835 +:10E7C000142B37D41F9B8BED1AD9D006E4ABC6FEB1 +:10E7D00064168CE3F72F258DFC5D95BF9B3FD5B16B +:10E7E000401AB16F8ECF8AF8896C588EF01F91D87D +:10E7F0003E86F5061688FB7EF3A70E6D390A67067E +:10E800008D136BC7B4ED067E4FEDD8F4700A7EE72A +:10E81000822D9CE210F3C37ED9326B41BA5C0CEAC4 +:10E82000027A58C717DCBCFE226335FD96587B750B +:10E83000BC0B8B0C2C44788FD0B8889700C8B69D41 +:10E84000839F18DC506E183C4A7851F9211E3F8195 +:10E8500038B991D13114D2C19AFE856D55578919B5 +:10E8600048714C5DBF6BBABCB3A05ED669D67372FB +:10E8700079747D93587954270B79D0D0553D2BBEB0 +:10E88000CCDBC7FA37D654C3FA2F2FE1FD4FD89A05 +:10E89000DE58AFC4E411CC230FF1122D9B12CA161F +:10E8A000284F892BDB12EA9D09F5AE84720E6F7F2B +:10E8B000CE1ACA933D8C7D645B5BA3807C3997152F +:10E8C0005A2C417973C7BD35D520E71ACB87BC32A6 +:10E8D000CACF41C923B118FE9A3CCC1B04FC593C59 +:10E8E00061C3B212C4C3D06BB8FE1B06249B047C68 +:10E8F0006EE93F18A232F673C7F5EB97A85F43FFA6 +:10E9000087D46FD4F18B75B48E37159FA4768000B1 +:10E91000DB69A0D35799C45201A5058AFF8FA8BF10 +:10E920001AFB7FC3F52E8B18F8FCB81CBC90E57D54 +:10E9300085E4E011C986EB2ECA7738AE25C6EF6AAA +:10E94000FB5F4D19FC571C26F9DE4FDA1568FF7F77 +:10E950001A7F338D01A97E854D66A05C0D4E447DE6 +:10E96000BC93F927A21EFA7AE3F8A33A6877421F0C +:10E97000DECD005FC5F64D350AB43B610DE74A2098 +:10E9800043266DEDE5E5F4F06EC46760EBA384DF2C +:10E9900013B9E15C1D94A7DA43BC3C3EBC1BCBB76A +:10E9A0006E7D8697A7847365E83F3670A0A61ACA65 +:10E9B000FB6C23AFD77C3B97E32A7C97C779B3EDF9 +:10E9C000E9C8765C4FECD603C6401E2E5EFDF1B35F +:10E9D000FB000F8BEF4F2639B5EFDC57E6FB68FEE7 +:10E9E000019F5201F290B33ED763248F15B203B258 +:10E9F00050773962F4B0E60DB949CE4F6A3988FADA +:10EA00003E737109C9F94F53BDEDF669B1E7271996 +:10EA1000F00438DAED362E97659D97DA3F6025BB16 +:10EA2000678B99CF07D60DD1D722E8512EE6536ECA +:10EA3000D7D133CF3687C6FB40F2EE30C9F8640138 +:10EA400033D2735512D91977EC01B90072B957C096 +:10EA5000DDBB75623000E3DF21311FCA8D5EBB373D +:10EA60000BE5C30B7F91EFC4F9F69642199E3F1652 +:10EA7000F2BEB7CE9B658FD38BBD7B78BD2A777AEC +:10EA80000B787F55DF6476F0EF646E99B817E791E5 +:10EA9000AC302F96972F2ADADB4E7A7B01CD9B790B +:10EAA000BD5912CCF7F4AAB13AB42355FAA4157A99 +:10EAB0006FC2F9DC8EE35B627452BFDF8EF346BD3A +:10EAC0002F83DE87F93EE0F0D3FCC10E984A76A092 +:10EAD000B003DA71BED362F8654A781ABEFFFF0848 +:10EAE0004FF760FDFF144F23C88B00B66B6C0579A0 +:10EAF000A18B9317027FDBA4903E93CB0B0FEA39D7 +:10EB00007CBF00E4E3ED36FF468447FDFEE2071AD2 +:10EB1000C9EE53E14AFED68B355F65C3D759A25D76 +:10EB200076E203D366067AEC84A19FE4E289F9CC0D +:10EB3000D38EF243C7EA118FAA5D5971FF9AB718B5 +:10EB4000D8B397ED32D1B95BF266E1BCBA81AE269B +:10EB5000D4C37586E0BE82985EECB50777AC40BA48 +:10EB6000DE52E209B8493FD27A0BB42653BB5E7B32 +:10EB70009829583FC36D034890CE448FC86D86E0F6 +:10EB80005E09E9CDF9A577D5A4604022BA07A8FFB0 +:10EB90006D9C7F7AEB18D9F7BDB7B9886FCC2C681C +:10EBA000467846E3838C0E467CC414EFD43A6B0C53 +:10EBB0000F3F13EB3AB93CFCFCBFA11DB9D94C7611 +:10EBC00024EA4CDC77B19E4C8217E8F902F187BA4F +:10EBD0005F7A242BB889F6679E0AA4C746AB7709EB +:10EBE000C1FFED6437C2BFCBCCBA4C65B8FD609DA8 +:10EBF00024EF043CACE73186F6D99DC23EFBF7FA20 +:10EC00004B56B4035EB573FB0A19C504F26F29E3D2 +:10EC1000F54BD7257F88FB99A5EBE49011F62BAC3B +:10EC20006B8E371CB7CF208E82F1FC425EB2ED11A5 +:10EC30002BF28D1FFBA5E0F87FB4BA2D5886FE534A +:10EC400091ECD0BF38D6FF3DB16E17CB1C7ED69667 +:10EC5000EC46FC26CAF5F754F87A1EF3C67F4FFD42 +:10EC60004EE2B8B08F7B1FF105780FA5A23DFF6D76 +:10EC700099E89A08AFD31079C80CF58BDB64FB7A5E +:10EC8000C0A7BFD54AF355E1BD3333722DEDAF12A6 +:10EC9000C63F93DC54A1E0FCC5FE83ADD3EEBF18A4 +:10ECA00033C4CAC017CB5984F631C3DE8B7D6BE207 +:10ECB000BE8FB1BF18E3DBA9EB85B9A504F8055FEA +:10ECC000B92505E9E69738DDA2F44E805BC5A7ECCF +:10ECD00018199F4E433817E595BFD5487848ECAFD3 +:10ECE000EABDC7CCB03E80AFB64B12F1E3F6FB9263 +:10ECF000498F3113A763F3EA2437F2E74E43E469FF +:10ED00005A372F1919D2F5A239F202C9A342EE37A8 +:10ED1000B8F833790FB6BB90CEF9FAC2613DAD2792 +:10ED20000E0CD83B3F93F752BDC4C7BDD09EECC676 +:10ED3000F5D88C9884EF3707FEAB8D01FE4EE9F8CD +:10ED40003EB87940BBDFBD00FFEACB6272E122E34F +:10ED5000DF090C703900335D45DFB923896D82719D +:10ED60009B749217EDA3A6D593821D9C5F4CB85E51 +:10ED70001A04484D3AD8F795C5D67793EE6411EE4C +:10ED80009B1A4C9B87E414AA3F8EFB2D86FB25E83B +:10ED9000B71A3B150CE7E7A6CDBFFD33C2DD7448BB +:10EDA0004BF786187F489F49D83F8E5F0A627C40A8 +:10EDB000F635CA876A161C2F713F0C96936B8682B4 +:10EDC000E8876916FE89F463E1B9C81FD6F27EB6FA +:10EDD000149ECD67B97D317370CF2BB8CFB5D70CEA +:10EDE000E5E2349B5BD75E7DFAEA187D5538670C07 +:10EDF0006E9571FFA6DA2571FBC7890BA6C43FD7B4 +:10EE0000533FDC8FE2F7C2F80AD785C2F5D936A1A5 +:10EE1000CF40EF91DC5DDE3381F41EEA25945FEA9A +:10EE20007E16E519CA8F271D558B1C30CF92B4AAC8 +:10EE3000AF38A6F1EF901D8F9BA019C3F199A85789 +:10EE4000D476B8AF6DB18CDE2EEAE7D991CAE583EE +:10EE5000225179C54FF57B36117C0AF1CBDADD05FD +:10EE6000246F557F4C83F043AD10FE9B15C27FB3DA +:10EE700072BB91B9E3FD55416DB941ACF74616E659 +:10EE80007EACFD501FEFB7A966212BD6A3FF069FCE +:10EE9000FDDAFECD2C385B41FA0E7C668C7FCF7A92 +:10EEA000F97CEF1474DF61E67E9B99EBF6C8DC1900 +:10EEB000C5E79B5AE62D7810F5C49B7AF22FFC87A4 +:10EEC000A0938A17A3A3EAEB88EF24DC8F61BB072A +:10EED0008D8497D3A08F0F0ABFC602DC67B6F9B343 +:10EEE0000A0B113DB6BC05D6E1F8DDF492B91EF966 +:10EEF00065B343A7E1A72A879ECAE4EF41BCB727C1 +:10EF0000935D0D689E8A7C543156D5936C2AFA998C +:10EF10003ED483BD05E5A65B2D7E1C2F8C76019427 +:10EF20007708F9B5C361A0F1D472741F27F805BE44 +:10EF300043E3A1DFC517C707C168FBADC25EE4723A +:10EF400061DBAA24924731BED531E2DB129F01FD7D +:10EF5000452F0939F2122094F651FD662E47142EE2 +:10EF60009F5E3A3B89E4DE1B1FAF26B972695112DE +:10EF7000334AD4DE2B61FDF3C6E07A28DF25FCA8F6 +:10EF80002F49DC0E0C1CB1D2380D06FF0EF42B34C9 +:10EF90003C37DE0314632F1882DF7F1AEB5F369352 +:10EFA000DFAA2185C3D9F0D21892933FD6079FF9E3 +:10EFB00001F9218C649F3524B953A9FE27690CEB14 +:10EFC000BB92FD8348CF6C23B71B1B0CA1223BE0F7 +:10EFD000F16490DBBF2751D0E0F88356B26B00CCD0 +:10EFE0002CFCFEA9EE4CCF26770C2FA71E9A4CFCCA +:10EFF000BF4DCFE91638CCFD9A27F5BEB959503E22 +:10F00000F97CA907768EECA2CF1032008CCD5BB8CC +:10F01000BDB64CE7EE6B45D9F472B247B3DF7C78EE +:10F02000652DD637AF5E7713CAC1D1D633CAF37810 +:10F030007FED0516C9A3FD66FDD8FE107CF7C2E082 +:10F04000440FA947E60262039FD878DBD37AC03722 +:10F05000F2D7113DF1EF171D1FE78BFB3FD42FF8BF +:10F060009D6690BF513F32C9DFB8B23C5299D3B3CD +:10F07000F9A54C619F69EBEF48F55F40B9D6F4DD27 +:10F08000DF9F6825FC4648FEB11EEE1F3FADF72E00 +:10F09000463EB557870C4BE3F6B78634BE8E9619BD +:10F0A000855E672143FCBA53EB2BAAB47CAE3EF5D8 +:10F0B000697C1F691DE2727C78BD4EAC9BAF185114 +:10F0C0006F71D70DECA7CF727F8621CD4DF533CF71 +:10F0D000860CCBA09CBF2E6458219EB82E00DF2149 +:10F0E00013CCFBF40E2B5FCF80061C67C57446F66D +:10F0F000C80A19ECD0327CEF1E08035DCE3C6FE7E6 +:10F10000FCF527C00AE07B0913ED8C60B782DC7A3E +:10F11000B1530AA15DBF64BB71AFB900D7B157B697 +:10F12000223D774B24B796745616ED80F2EA43538E +:10F1300088FE29D3395FAE0EDA49FFCD147270997B +:10F140003168203BFA19EEA783F1C91E6E804E5933 +:10F1500065C3F180F25BC30F416D9C6166BF90A7F0 +:10F16000FBE3E20B63E3E47A7F427FB0E3B4FC119C +:10F1700050F50E9773CC9D89724E95C34687AF3478 +:10F180008DE4526126D217E8C9E5E44189F0DAC876 +:10F190005AB8DE10F23EFA5DA12FCEC801AE978CB0 +:10F1A0005BE93937AD80E8B61AF50DF9CDF9FE6E99 +:10F1B000343E989BA6137271643EB85EF041C35909 +:10F1C00016BA16BED7B08E851AA7F2A7752AE941DE +:10F1D000AE0F4D229E61E2F18ECFD38B897A70986B +:10F1E000DE4BD0779906A1DF049DE3FDD9A8EF6738 +:10F1F000AE0BCAE8D7CCB379AFCD4C8FD92FCDEFBA +:10F20000994CEEABB0EC63632DE89FA97CC685FEFC +:10F210005DD88FE3BA4A06BCEC81F7BB55FBD6C577 +:10F22000E7EB3270FED52B3E566A41BA0CD17E35E3 +:10F2300092CE6CC88F2A3E775BA15F19F6E3EB2D67 +:10F24000DADFC43A93E2FA57BD6426B97AE5B035FD +:10F250006824BBC39F6F87F1327E65243BF4C24BA9 +:10F2600056D29F1784FE73AAFB7EB681E8D38A74B8 +:10F270004D476EAA1A83FE5326CD1F832250B5C375 +:10F280001AEDA3F9B3457DC1D0AD9CAF8CB45FBC82 +:10F29000620F7F13CB000F43FBBA05E98CFEF643E8 +:10F2A000B34B1F80F7CD3E8B8763DF5F8AFC6A9488 +:10F2B000EFBD15FD2A73E57591FB601E8DB9169B98 +:10F2C00011BA54E7FFFA97B741F9A3437A66443A73 +:10F2D000EF9BBD888D1D5DFEAE0AEA4F86E3D6CB5F +:10F2E0009AFDDA7263BFB6DCCC9493E13879FC58AE +:10F2F0009AD5796632C90ECF67C0DF4663CBD93D58 +:10F3000000AFF1C746D2470D69FE5D69E837D545C4 +:10F310005E433C1BF3CF4D453F4555FE9F28AE73E2 +:10F32000E5DBCC83705F315792FEBEB2C3EC0EC4F6 +:10F33000C9AF66C1FFBD79B554DFBBD3E896787D10 +:10F34000EDB40AB407E9DBF867D201FE9BB7CFFB47 +:10F3500088F64D68B543B917ED4BECF79C146C4734 +:10F36000FB713BD77BE7C17E34A1FE14EBA9591E8C +:10F370009C6B82FFEC75D44C44F9A2FC59F121FD41 +:10F3800037E25071F6EEE1E8FAE47E9C1BD08F3351 +:10F390008EFC3887516E349AC2864A18E7BA3FFF0E +:10F3A0008EE4F2CAD6A564D7C7EC5C23C99195F761 +:10F3B000F9E9FD2B3BAEA7799D8179237ECEECE662 +:10F3C000FBB995399620C2779D9DDBBF2BA19F2469 +:10F3D0000DC74B221E7EB3EB7A17D2FB378C7F2FE3 +:10F3E000D0CFED84DFD8865248FEB85B52D0CE6BCA +:10F3F000DE7EFD4728B756EE963DA8C7D9112BF9FA +:10F400003D56EE9E3371B905C7B99C568978EB9B82 +:10F410006393E9BDEC0B72FFC9D075F05EE9BBC622 +:10F420008DEBE4F86E2387CF6E7A1AE1BFEECF3210 +:10F43000F1BDA2637EB4577B0DDE89B8DEDCBBF67E +:10F44000CD45BCFEA62E5B47ED9F95980DF1606FF4 +:10F45000CDC0F72B25C587EBAB7EFBAADA787BA462 +:10F46000334D267C57E6AFCB085B88DF6F453DD731 +:10F47000B85B4F76DDF1051FFCF236678CDF57CAAB +:10F480003DB7CE8CB3379A77DD28F8013436E06982 +:10F49000A5C093317F5D117EF7F3F87FE5FA9622E0 +:10F4A0001E8FF9EBEB20BABE77F1F5F007D0F7B479 +:10F4B0005FCF7168ECFBD1F641AABFD9E461DE7D74 +:10F4C000168A1B7A719F9BE754A83ECFC9ED6CE565 +:10F4D0000F6BF7BF0DF0F7A7F98D4E789FCFBCA546 +:10F4E000485777C45605E6244E89EC1FB6CBC8EDC5 +:10F4F0004985FBDDB6A5B3A737C5C1998DE3A5D373 +:10F50000FAB43961DC0BEFFFE935C45F53DEB9A90A +:10F510003C9EF63B8A4F590679DCD2E2F131E48B0E +:10F52000E6C13A7657494C1E367BB8BC4E9CD77222 +:10F5300027DF67343B23344E753A5F67AABF77678E +:10F540006B12F9F5763A8366BEBF0D3094E73795B6 +:10F55000CB3CDE22EC129FF09399BCAF308CC730CD +:10F560008FEC190FE521EFA9CE3428BF5D3EC723EC +:10F5700043D9E27DB26B2CCEDBA317F5E3C85FF86D +:10F58000D6AC4AB24F6EF2CAF45D569F42FBF521EB +:10F59000EFCF9D77C1776F66DEB4D3F08D1A50D66A +:10F5A00048C721FC36DA018ABFDC19E75FBDD133D9 +:10F5B0002FED74BCBEF472FD8FFBF17E113718097C +:10F5C0000F2569953311BFD77D99D3E1E367F9FE24 +:10F5D000E36333F763ABED3EB6723D53EB94841DAA +:10F5E000D89F87723E5AFE5AB1260EEC34F4E7E1FA +:10F5F0003AFBADA41D6775978EE2B3ABBA18C5632D +:10F600003FFEFE8B79286F3FDAF762DED238F812C0 +:10F61000FBA9CF5B9D5ABF94EA87748AB8F4528FD6 +:10F6200091FBFB46F143AAEDD976BE1FBB08D21D64 +:10F63000F94EED77B13EC98B76E545662279B67411 +:10F6400050F835BDDE4227EE1FD4FE09E36F41FEC0 +:10F6500001B8A40189F6E7C9251192AFAB4CBED71A +:10F66000C6B8312FC54BF499877494905FBD069C42 +:10F67000B722F67946C5D788F45CDEA3A56396D396 +:10F6800026E2944EA2BBA1C9A2A07EC8E810F2FA5D +:10F690001B3ADABF18B25D16944BD715257562DC9C +:10F6A000DD99943215FDE6B9D9C5D43E50C5F93A75 +:10F6B00090C1C86F95C55A2492B736EEE7CE99CE61 +:10F6C0006C98E7F1A293DB832EE6D92E933DD82FD9 +:10F6D00091BF5FCC5F95EBC82F28E73E964CC42FB7 +:10F6E000D2A044F69DACEB5F8CE38EC63FBD09FC17 +:10F6F000D3FB0FE69F3EF57BC3F8C74F71BAA52E2B +:10F70000D3C8FC23FCAA5FB8FD6871C26F98543F50 +:10F71000B384F3AD15E3D59A2C21792AC98773F107 +:10F72000FED45D6067E27E448D2B8EE958E2E6767A +:10F73000FA5018F7E5C9D79848CF7D47375480F677 +:10F740007C629C11286B47798F3286FC8AAD55BE4E +:10F75000D36971FAFE08DF3734DDE7A5F7B307B9DF +:10F760007E6F2E3490DDD93C200590CE4D3E43D0A7 +:10F770005440719525A4B71F32BB799CC4DD4E71EE +:10F78000926FBB791C25EA470DF73D80FC566F212F +:10F79000BF4362BCE585BFC8FCFBE3197DBFB794DE +:10F7A000C7777AE7B9C9AF911847635DDAF5ABC699 +:10F7B000512E5A0131F0BDA59BCD44876C99E39938 +:10F7C000A59AB87E192E07C85F9B315D1046C43BD1 +:10F7D000A2EB1A240396B345BD1A9FB196F80AD03E +:10F7E000C2BD3DEDB93793D2FF967C86D6EFFCD5EE +:10F7F0007C8680B116F3194C683D8B7A041BF4ADFE +:10F800005AF69ADD18BF89D52B60379A0624F1BDC8 +:10F81000E76F9853087890D4EFAFDFE4B550BC5849 +:10F82000F3BD78F89484F1F530BEC52DDA070ECC1F +:10F830009BA3505C52D47FD68DF91B5BF4DAF108A0 +:10F84000A5A23F16D4EF1DCF9CFB9DCD3931BD0F36 +:10F850007680297D5A4CFF6FFCA0B6E72AF856B295 +:10F86000EDB201F5AAAAC79B9D3CBF2171BD3AD25A +:10F87000F97A05FBD5914E7283DBB5B5223E09F6C8 +:10F88000EC5C5C5ACDEB7C0CE393602F64A4631EAC +:10F89000C3FBE7CE1C45FA2DF898ECF9E64F15EEC0 +:10F8A0007701BB03ED7393E07336A0277DABF2C104 +:10F8B0006A217F7AEDA0EF915F8F48D302C4172DA4 +:10F8C00079B7000DEE4FF7BA697CB1EF4A847746FD +:10F8D0003AF793341757ED28C2F19F9218EAFB4D7F +:10F8E000C52733D02E691EFC3063795CBF55038F6A +:10F8F000121E56EDD78F38FF19E9DCBE6C3AFC3C7E +:10F90000F9073F0E4AB496EB9560F74C28D7D7EB32 +:10F91000D04263E5C125B791BF7F91818D87F9E51D +:10F920000B7DD4BCFF2B8199B83F837F12BCDAE9F1 +:10F930005B417A6FE7229305E30ECDC54BEF263C82 +:10F94000D892BC88874DC55559F89DA6BAB9368A54 +:10F9500013807D85F54DF7DD4E7E1315AE4D03FA10 +:10F960001AB4BB2AC0CEFA11C09DEB985FE381F5B3 +:10F9700037463E587A8F05E3C223CBDF7FC9E0F4D8 +:10F98000EC947C819BCBC94FC8E2FD7EF903DC9EE1 +:10F99000AB4B3768FCC275E9DCCE9C15189A8DBC60 +:10F9A000F7B2124E46BBB799793FC1FD25F359DC3A +:10F9B000FB884E5C8E38DBDCE43F3239C3DFB90AAA +:10F9C000EB6729B47F604AF811FCEE856EA76713D8 +:10F9D00013FC8BE5FB4A822847FF39DDBF18F9ACE1 +:10F9E00042D88F170E5F5F8A7E36D53EEADE630E01 +:10F9F000621CB0DBEAFE6E0DCAC13F283CEE6D8A88 +:10FA00000CCD467AFCD141E3769B83DD48FFC0569E +:10FA10003DD51FB6FA5721DF9CADAB29A2BC1B4BCD +:10FA2000A008E3BC7A670F433B01B60BE44F3039C3 +:10FA30007D0CE3A1B3034B1409E57C82DD315BE46B +:10FA40008F92F084F755428C8D072E3863A225D013 +:10FA5000F9595ACC0E79E34F0B157CA9DA273A13E2 +:10FA60008F67552F4A6232F2FD86C86B3AF45F3BCE +:10FA700087C87E6DEC97E83B8DC5CF513ED81A9173 +:10FA80007714CDFF51C2940FB53E3D59E8F14ECEEB +:10FA9000EF6C88F6CBEC00A7276361CA938AED234D +:10FAA000DAA99D3A9E41F8DD1B85DF053418D53F64 +:10FAB00094AEDA07EBC553CDEBE2DFDD260D7965B9 +:10FAC000C46BA9A4F117ABCFA7D2B97D987A2C3219 +:10FAD00017D76FE4B09AA7C9F330774C9BE441D3B2 +:10FAE00069589EE6C02773916FC0D0A6F5DA34F04E +:10FAF000C5F234BF2FF60DFFEB799A1EC9BB179ED6 +:10FB00003F4AB773BF959AA7E9E1F853E36C89F9C7 +:10FB10009917B2420ACFB70AF7ED43FE1C30521EC6 +:10FB200057EDC0EBEFA17EAC35B17E8C4326DA19E0 +:10FB30006DB6AF0C22DF5F3C7FA6EF418679BA2F0E +:10FB400078285F23C17E48DC27ECC52659A3DB7BE0 +:10FB5000EF46E9C9EDBD68F97FDDDEE3F67C601FA5 +:10FB6000CF0F50E579B3D89F5DACBF94827AE6445D +:10FB7000149E843C86A7441EC3E0C8790C8AC8073B +:10FB8000027B3D407C7290C775DE783A99E4C725C8 +:10FB90009BB217EDA5F3D6C83711598AB0933A8FA7 +:10FBA00018DD282F40DE91FC0E1CD4F3380DC66DF5 +:10FBB000308EF3F24411C711F1A29792C96E6948D1 +:10FBC00071A7627F354EF363A16F1A92787CA62BE2 +:10FBD000D97F397D84B8CD1E617FED81A16C38DE7F +:10FBE0007B4611C7060181FB9D877279DC41C46D9C +:10FBF0002E8AB8CDA9625DC8C0FD10E4A77277292E +:10FC00002C0BEADDEF99836EEECF32E940EF2F53F4 +:10FC1000E3362F733FD532119F39B5602EE5072D9E +:10FC2000C7FC7719FD18DCCF1CCDC767361DCE6722 +:10FC30000D888B9D28620280F56BE0B5A493D09E61 +:10FC4000707742998C656F4F0D7C7769A78EF6238C +:10FC5000CBBAB4FEF22B9BEEAE41FDBDB193C71FF4 +:10FC6000035D12E9EF65CCEB427B43E587828C3480 +:10FC7000A273A053E7C5EFCCC8E0FE04407D90E638 +:10FC8000279E9D7AE1671770B4335D089F3A893FDC +:10FC900037DA949A11F5B218AF53DF62AA443B36B3 +:10FCA00057477EDE2B06EF22F2933A8A886E9DD666 +:10FCB00096AE1A5E4F6BE58A39E2A3FA6B156EE8D1 +:10FCC00031B703E564668688DF24CC77798FB69CEC +:10FCD000187F5815D4969731FF842C3C87B05FFB72 +:10FCE0003E3383CBA92B9B0A849FDF437EFE4EBD10 +:10FCF000FBDD029453DD0AC9C9F61C8E2F5D2E7FF1 +:10FD00008EB5572F22FBC00E7605C1CBE11F7BAD10 +:10FD100053427DD969E77CF93F853B11DECA8C22CD +:10FD20006E27A07187EBA85B0A727C71B8BFA8BF71 +:10FD3000626986F01708F9132DFFEFEF37393F7628 +:10FD4000CB62BDD948FE2C15F1C65392E7E910BE2F +:10FD5000B7805D00702FEB96CBD03E99FD150BCD93 +:10FD6000A3E96573D008F58DEBC279B88E9AAAC263 +:10FD7000452D23E015A15554B905ED963A617F80D4 +:10FD8000EBB64B1B871A1E57F47E2B231DF721A7BA +:10FD90000EBE8EF43E6826BD04FF75D488FE8EC369 +:10FDA00005642F4D4DF5B765A03E4F0AF57DAF00B8 +:10FDB000ED136E1F350E1AF7A0FDB7B4537B6E8698 +:10FDC0006DD6C6B9589783FC19AC57FB1ECFA768F0 +:10FDD000FA0D8B7B713DBFCDE09F8876DD755FE6C8 +:10FDE000F1F5F3AB740CE9BB4CF6AC403972DEAC08 +:10FDF000B5BBCF5B39BDFAA274F614219DFB46A5B5 +:10FE0000B3A708E9BC4CC7FCF1E334229DAFC6ECB4 +:10FE1000734EE7F3CF5F5384743E77F09A22A4F3D6 +:10FE2000367D8F17D7CD930EFF5EC4CFE9393EB232 +:10FE30009BD4BCC92FCA8F8732B4FA305AFE3BF923 +:10FE40003F46D383A1281C5A3DE834B873501E2E78 +:10FE50003519FFAA3EC4BF11FD692623F9235EFEB2 +:10FE6000D3E58751BF050665B23FD4F15E56FCE38A +:10FE7000D05FF0F27B2E4F401A7DFC066157B94CE3 +:10FE80002C807E0FD5DE57EDC64479FC0B319FD315 +:10FE900019DE1AB4B355FF6CBD18D314BCCCEDD326 +:10FEA000A724F2BF9ADCFD3C7FFEC8121BFA67CF85 +:10FEB00006B93FB6E9F952F2D7AE0ABE12C2FC2724 +:10FEC0003628D970DFB0EAA90F53309E0DFBD0530E +:10FED0001971F19539621F7A36782A05E3DEF0FD53 +:10FEE0006AFC7EB2336240FE6D82FD1934614D4A78 +:10FEF00084CE0D353919E9FBF201ED7E4D8D4FEEC3 +:10FF0000F41948DEED1C9482B83FCB30F80B7250E8 +:10FF10003FB11CDB99E4D87AF924C36BCB9C161F44 +:10FF200017F65ECE88CB570AEF48253E0CEB999723 +:10FF3000EC801D56219778BCE63F77D9833C7F89BA +:10FF4000B7FFCF600195557DBD429CC35B21CEE1DB +:10FF5000A1FC0E25C8EFF87234DEAC9E3703791E83 +:10FF60001A29FE1D97B714DFBF8945447EDE674618 +:10FF7000CDB8D17C9D965237C0BDE66B163A67D896 +:10FF80000C7CDD5A16E3C3063115950F9B845FB7D1 +:10FF9000B9FE24ED039AF17C05DA551ECE870DB02B +:10FFA0003FC2FCCDC475CBFAB5F98CA3ADE329995A +:10FFB0005ABD122DFF83FC98D333B5EB579DBFEA92 +:10FFC000078FCE7350E2EB2B615E89FBCA44FFB50D +:10FFD000BA2FFCA272EDE64CAD5C8B96FFC172EDC0 +:10FFE0008ECCD1E49A363EF037CBB5C4384121F7F8 +:10FFF0007F639C00E3B6FFD338C147EE9E0C1DCF54 +:020000022000DC +:10000000C3D7C44FBBA4969B4CE330AEC8E3CB8DA3 +:100010005623C56113E3AACDEEB9228E38F4CB196D +:10002000A8370FE919EAF37ACB4A8A5736CB070C7F +:1000300078A470583C51394A76FBDF1A575F9F19F4 +:100040008DAB17605CFD15CBE5347F1C3DAB4AC022 +:10005000C02F193DDF68B3A053B2C88B30290166A9 +:100060008FEB3F5ABFDE4C6E27BF22F2635C069EC9 +:10007000C7BEC50AFB3098BF4BC7F377EE4FF76D8D +:1000800043F9687273FC3E71F8AB0CCF1D3DA1EFD4 +:1000900027391268B478501EAA7E17757C45F80F70 +:1000A000BE28DFFF2081EF7FF077E6FB447C0CA8C1 +:1000B00072E76F8D876D07DC68D607A3B8D75B182A +:1000C000CF2918CEC7A38D331A3FFF34D3F75A2652 +:1000D000C947EF54CACBFD82F226B93C720AFD3BF8 +:1000E000EC90D18DFB0D933897C13667893C4A4F10 +:1000F000451DE513F3730DEAF98FD1ECC20FA3721E +:100100009ADB851F8E2AA7FF7B76E1030EDF299CF1 +:10011000E7E94A6F11EACD8D56801FF77BDF378EF6 +:1001200078CE423D0F00FCC4CF9B3CCBE3E0897C02 +:10013000F58704FDF287BFB37E194D9EEA5D2A1C48 +:100140007F67795AFFC714F47B8E3E4E80E0A8A8E3 +:100150001AF28AB815C3B8913A8FE6219E7F96218C +:10016000F2AAD4F7116117DEE9F266BAA0FFB9F777 +:100170004D26960A2610F218DA633E0BC5039AFA4A +:10018000799E48D33A46715FF51C65D3401D43BB49 +:10019000AF3FCD5F8079601B3FB004E454F4932FF0 +:1001A0006068EF5D789F971BD2FCE3294F6C5D5828 +:1001B0001377A8F8ECF206F46700BCE41F708AFC21 +:1001C0004C15BE3A179767EAF32681EFE8BC9C1CF2 +:1001D0004ED62F07D14E4C760F911FA9E91037DE6E +:1001E0002A642FF9EBD91A079D9F683A54594AE7B8 +:1001F000CDFBCDA568E756FCAAD686FE8973D73A13 +:1002000029CF204F0EAF423BEB9FD3FDB3105E6B67 +:1002100079701EDAA9F960A7A2DD7BEEE0BC527FFF +:100220009CBF7B1BFABB61DC6D56AD3F9B99789EF2 +:1002300078FD5E9E077CD8EA9F8BF8DD66E6F006C7 +:10024000B68ABC67E1E74E5CFFEABA8F9E73BCC317 +:10025000447169552E6CD3333FEA3D559E94883CDA +:1002600039C007CFD31BACE3F91EA26C716AF3153A +:100270004F67CC2941784AD0D13B0DEF518848E8EF +:10028000775F2EE2F0D78B7C0A357FCAA8F8BE8E46 +:10029000EDD9BA9A58FC7D2CF617F177912793FC8B +:1002A00029B79FC7DA0CC43756585FE41F01BE4117 +:1002B000FACC8A0CCDC6F34485BDA15988CF973FAF +:1002C000D5113E94BAB7287E928A648371C66D0EAA +:1002D000774F403F8AED17D7225DDC3DB62A445D5B +:1002E0007F9AAF91E0505A8A715F59F5AF7A9E07B5 +:1002F000782499FC03BD790D940778E103E388E73E +:1003000046D46780ADA7BCBFB1033F273FBEF59081 +:1003100034623E6797CBC2CF0D078628BF8CCD7263 +:10032000123E9423BFA2B8AFD2AD9007A353EFD52E +:10033000E139A8403B23FFE5F85E9B0EE9922FF2DE +:100340004B2EBEFC5F53FDB44F51FDF6419E0FA4F2 +:100350000F6FC07D97D21EFE32AC60D678C8AE6BF0 +:100360002AC1F1224D3CAF3D99219FE40F8C5BFFE8 +:100370002528E777D99884F2E7A535F9E42F857920 +:100380008E1F619E77BB78FE8E722459877A4BD977 +:10039000CA28FF50B1675411DC8F4219C65923F89F +:1003A000468D4702B82ED44777BAFCBB11CFD17324 +:1003B00032AD49FC9C8C3877696DFDE0593C7FD2A9 +:1003C00067E0E70C8FBD3C7901F9EDBA1509E970DA +:1003D000C5BE24DF06EFF78B756B558698CD128F5F +:1003E000FF63946F39F608CF4B53F49C4F946EE73C +:1003F0001EF40B7E9AEAA7BCD26B3B4332C5B36CAA +:10040000A71FA971C7ED6BB6733DD2B49FEFA713B9 +:10041000F7319FA73F8EBAB47649B4FC0FB24BDEDA +:100420004AD01B7FF3FE8469F77589F649E23E6E78 +:1004300098DD9D30DE68768A9AD75115FB0EF1C3A0 +:100440002B56D50E0A68F25EAA2CE2DC9B493BFED5 +:1004500053224F47CD83C9E870B7635E79E4DB8CE4 +:10046000FC6C6A3E4EA08AEF1B023A139D8773B163 +:100470001ECAC319C3429244F67F98CE7566623E87 +:100480000EF47BDF3596E0DECD3C5D32C943B784A8 +:10049000709B318F83F236833B56E0776EB1D07715 +:1004A000CC98C7713586E2BD3B507ECEAEE77188F1 +:1004B0006CD0B7C8B7D9859C0FCD8B783E879AAFE3 +:1004C000A1E657A878A812F8CD9EB0A200F707DDE4 +:1004D00092FFFBEA79DAF873D2D1F3D1ABC6D279C5 +:1004E00093E8F9B94226EABFD839E9447CAAF91D54 +:1004F0005536BF2D2B7DF87959953FE2E84670EDD2 +:100500003CC2EDF5AA7A03C17F71D57CF2235E5C13 +:10051000A563B86EAA068D9CDF12BEB7337A0F466C +:10052000D04CF75D08BA7F9EBD0AF42C463FEDB172 +:10053000B69AAB4F036E8FB7F9E879D12CF5CB574C +:10054000D179C6C528992E67EDACC57B0A2E5A23F2 +:100550007978CFC1E5EC076FA4727AE404965376FC +:100560001EBA11EF3DB8383ED287F71E14EEACE448 +:10057000F5C883D98C5D9555716380E6CDFD4EB38A +:1005800063E7B3CB113F8D2CBC6188FC3B3C7F1FE4 +:10059000F3FD900E2E8B81EC1997C8B364D522EF32 +:1005A00012233050EEC82AA578B585B90F0D617DAC +:1005B0000E3F2704F5C4BF1DE3B95FD824E8CA7213 +:1005C000543F523880F2A9A3C04EFDA372F490317B +:1005D000C8FD59FCFBEF3C3F85E24B6AFE2863B641 +:1005E000DC855328DF445356EF37608A2D17ED859D +:1005F0000EBDB04B45392DD55F97156717BD33E755 +:100600005B25B80ECEBFF04021CAA5EB0D60B78FB9 +:1006100020877E9DCDE5D045BDA54B023BEDE7296A +:10062000FEDB719CF79217CFB5C3BC16A5551AEC2B +:10063000086FE0FB32CAC574416FFB420E9FBDDA02 +:10064000272D87713BCCB07EA17FBA5FF1529EBD52 +:100650007FA1740BC0DD2171790B9D52695F52EC53 +:100660004EC5FCE506715E5216EB7E46FF5619ED4F +:10067000E977DB06662A8531F87E2EE2CB3F2F60D4 +:1006800077D68DB0DF6DCDE2727B81EC9E827CB43B +:10069000411A78AB360BDFBBE9FD9C94D672CC3B9C +:1006A000BE3EB9A51CF5CFB0F7A9F0BE24AE6CE4F0 +:1006B000ED1A4C913C3C9FEC4DF6AFCBC2B8D092BA +:1006C0000F296EF9CDEC774E60DEC13BFA9ED92939 +:1006D000A85F0AC4B97EE1377C6D82EA3734F1F253 +:1006E00064EE378CE6734DE1F964B50BF939C55A00 +:1006F00091AF30D7C6CFF5CC2D2FF074008837B12D +:100700008882726FEE7BBE14DCB7B385FE72DF9415 +:10071000D1ED19E6D2BBE3D7EB3C775C19FEDD5097 +:10072000AC2DDFE8D1966F9EFEE709F1E53DC9DE0D +:100730001D38EF1F4B3CFF313083D9689E4E298016 +:1007400076C7E417B3C5F94E9EA7F74F625FF4E290 +:100750007446F519FB4D7B31FF5DF533CBA27EB2BC +:100760008B99F21DFCBE00D4571149E4FB39299640 +:10077000C25EB8DBC6F1076D0D30CE0B4BDCB43E6C +:10078000322C3AF6655C43E526B2432AC69892902D +:100790006F8E09BE53CFEBAA7C58A1301FE62FC045 +:1007A000A717E2F31DBDED28FA97031F31C6E955DF +:1007B000A950FEA1F81663ED547E4CF0F7310153B9 +:1007C000E0DB0AADE757AD06A2A7FC13790FEA09F3 +:1007D0008CCDA0DFF8D2E649049FBA7E6055173A67 +:1007E00033C8A52DC655740844B1B02754FE460B36 +:1007F00008DB8DC1FF2C203E27791399C6EF4FF8F7 +:100800007901972791AD0E711E8CC7CB724DD171B6 +:10081000BD386E56F43BFCBC51862843554807F35F +:10082000FE4D560197CB83AFFF81F4B2C5E3C7EF0E +:1008300018524C744E465D37B6CEDFBE553B03E7CB +:1008400059F40D9AE77CAB0DE7590C6CBDC8414FCC +:100850006F1A8DC7D78F9CE471E33AF94ACDE199BD +:100860004A1CDF40FF46DE3F59DBDF05FD1D71FD01 +:1008700053A07FC9F0FE4F594D21DD541CA7C21D66 +:1008800026791EA2C9CC17F3923378BFF9221FB480 +:100890003005DAA3BE29D6E66BB0E91E13BFAF431D +:1008A0009B9F71BDB42E0BD7D53C53E36018C67B1C +:1008B0005DD0ED7A9DFF77783FDDEB8B8B8EE37A11 +:1008C000AB310515DC0FDDC0421B9098172BFD4F97 +:1008D000D8C7913CF80BAE8B26D93FC101E5F3FA9E +:1008E0009EC2BB0B68BD7C96356D38BC2A5FA8F0F4 +:1008F000227F209F45F92301EE289D6EEAA744B68A +:10090000DD60F7E053B583186BE1F9C6EEDCD8BCC7 +:100910008089E69A5A0AD10E79BD3D4072E37AFB8E +:100920002394D7F4E7317E6736C0B5E8AA4FE85E76 +:1009300013E65A3201ED7B80373D3BFDFF1DBCAA1B +:10094000BD372CDFF6238326DF76B475A57EB799F5 +:10095000F1FB69660FEEA1FCD9E685160F9E836850 +:10096000C6FCCF728A2F911D87E784E99E13C924A4 +:10097000ECAE2F9A97CBD7616FA39BECB7A81C174F +:1009800079E5BDA51CEEDEBBDDEA3D27DCBE5BC222 +:10099000F83D29EA3D27CB6D54AFE69FF7EEE17EA7 +:1009A000BCDEE727D07929B0DFC85E60A93A0E5FC8 +:1009B00081F67E15FC933262F9D2DBF4DCDEDCA931 +:1009C000F354209E77621CE8AFC47FBF9AADF59BBD +:1009D000A8E544BFDE930EFFEDC817CB4BBC7912E0 +:1009E000F0CF3203F7DB017FEDC2B31535ACE5295B +:1009F000BC3F701E6BF9856E1CF1979FF86BF22758 +:100A0000FC5EC1187F2DE1FC1520A1A4F25794AF24 +:100A10008A13F3ABFCABB17DAFBDFF574D68A70E9A +:100A20001A892E6A9E5CE23A8E83E7B49EC3E394F1 +:100A3000658267ED48F07C113E8FE7AF4CC6F979CF +:100A4000347ECF5458C05A16E3F73DC9FE76843F32 +:100A5000CAF71BF87E6418DCB285F8E3D6DB649E27 +:100A60003F9ECCF515C62BB2E0FB75E2FBB7767363 +:100A70003EBAD56A20BEAB1B6CA47C2256CDE30ED9 +:100A80001EF81FDF077A09BF8B44BF85CE523DB2E7 +:100A9000ECC25A6D7C6291458D7FF8F4B81E6F5D93 +:100AA000A83F19AFEF17B1CD9F60DEDB228C63A8A2 +:100AB000FDE0BB8F6747E31813308E715CECD32FDA +:100AC000027F23FFBF9ABE72D7DDC0B7131E2F2946 +:100AD000437FCE9C8C554F6D85F2F7764EA2F2ABDC +:100AE0001977DCFB0ED6F71551B91A2F71C1FD46E7 +:100AF00023EF5F5C71DBFC02F8EE71B31817D715BA +:100B0000EEFB92FCBD75D0CE35756C19E623560B05 +:100B1000F970F16E9E0F7FC355569EE2B9D24D7E9D +:100B2000A3EA2451FF753EEE5BA5FF568679A9D551 +:100B300063238BE93EC6B21F4FC2F271E993C5230E +:100B4000C54D26174BA189809F6A076F5F5BF6FD35 +:100B50006CDCC75757F1F2644F65F738ACD75D5A74 +:100B60003CD2B9D09F8AF5143DF724D6E98BDE0F2D +:100B7000E99C93CF2479708ABEE91FF27B892C927D +:100B80000DFD8F3E6F81827ED2D95E9EB758656A19 +:100B9000CFC2FDEF4D7E4339E69FDA4CA5C7D1CEDB +:100BA000489D5E390DE93BDBC4F4A89780CFFF85F3 +:100BB000F8FC9A4FF25290B92C5A3E57F9A84EE5DC +:100BC000EF6A2D1FC3FAFCD7ECF4CF97AFA3F13136 +:100BD0007CFFDFB1FFA22F69F54A74BC84F596381B +:100BE000FE687200FFE2E55C0C8E7E5A573998155C +:100BF000360ED75D8FBAEE220887413744E73EF2C2 +:100C000025CF243AF0388AFE57E1CB05D9C6CA86EB +:100C1000C3857F8A6A9771086CB60CFC2EAF877EFD +:100C20005EE688C105DF676350EF6FE0F0EC965A2F +:100C3000B8DC1076B1BA3F6E52E73BA09D6F45120B +:100C40003FEFEC42FF05F673964EFA6B70370BBD23 +:100C5000B9D0E47BC80873B8C5BE8CF8E1AB2CF002 +:100C60003CDA27C654BF634C3AEEBB0247C205E4E8 +:100C7000CFA5BC01A077DA9838FB44852B111F4D16 +:100C8000A3C8C344B813F110A3CF10D957EAF9A9E8 +:100C9000E8BC12E6D361E5EB3532CDA8DE5F528CBD +:100CA000EBE26D699227DE9E7E3B416F27C2A5DA9B +:100CB00011AA5E55E1417F11FF7EA41DCF90DD3862 +:100CC000662CD99D2ADF640AB80C3A69C438EA8DCB +:100CD0006374AA7F4E43C7C4734E2ABED4BCA044DB +:100CE0003CA9793DC3E23509F1C8D1DA49603F8FAB +:100CF000710CC79F1AEF7144FD5C029FA512C93F9A +:100D000087F073CDF6F0F309B5ADFC9C7C6D0D4C0E +:100D10000070FFB6F01FA8787EC8EEBF8DF347784D +:100D20001AEED3BF3BEF698A73A8F7C825E267F9CB +:100D300028F8198DCF47833F2DD5B712BF7B5E1A98 +:100D4000AAC0CA2DE9E2FE41E62FC07560B715546E +:100D5000A21F02E4EA679FE1660EAB80AEE50E7F5C +:100D600033F2F957996F0ED2D751E3D773FF3A2375 +:100D7000FFED5AB1DF9A23F4EDA55D32C507AABD98 +:100D8000131F9B8576E21B7A16A4F5EE25FDB94666 +:100D9000C07F099FD8DEC2F5EECA377F54012B868B +:100DA0004DD8AE8BDDAF00FF26069334F72B4CDE1B +:100DB000EFD094A7F4676BDA5F353056535F1A9A19 +:100DC000A4A9BFFA8D324D79DAD04C4DFB6BDEAB66 +:100DD000D2946784E76BDA7FE9EC024DF9DAC8ED6B +:100DE0009AF6A7C4BE9805BC43C51978BF389FEFD3 +:100DF000759F2ED5F4FB6DCADC37900FEFDACCF37C +:100E0000972B01339A7B267AB85DD102FFE374F504 +:100E10002988AF15606F63DEF2CAED5ABBA37E70FE +:100E2000EB0694A5897915AB594B155E49979857F0 +:100E3000516D5BA243BEFBA731C2EEB8865D23EEC7 +:100E400085F9AB742D62E3FF5B7435BAB47435BBBE +:100E5000B5744D2ED6D2D5EAD1D23575BA96AE76C6 +:100E6000AF96AE69355ABAA6FBB474CD5CA4A56B37 +:100E7000965F4BD731F55ABAE6B668E99ADFAAA56C +:100E80005F4160B5965E09F456E5E5B8AEB59A7671 +:100E900051BAFBEA291F667CCFFD9A7155BA07E06B +:100EA0007F9CEE2D94AFFEB7D29DB120F95F13E980 +:100EB0007E3681DEA0AF3E42B90076C6397C2E9ADE +:100EC00020EC79DFC876862A7FE2F57AFCBE75349D +:100ED000B9344C8F897DECA87A2C611FFB3E66F1FA +:100EE000907DB499FC3CB709FEBC8CAF66A01FF5A1 +:100EF00007A49FDF0740A6035CEF23DCF09DF79378 +:100F000026939FE10E16D2D3BDBF98890883DE8950 +:100F100089C932DEE7E3A6E732A1BF970B3F8437EA +:100F2000D99F92C3FD0FF919F8DD9C217EFFF25B7A +:100F3000695FE89E8293E887079D721AFDF0F0BC16 +:100F400060E6FC7046950F5EE676C6E16DE96C8959 +:100F5000F4323A7C703FBBF4AB12C51996FE9E3F4B +:100F6000C7E770BB37F1D9D1AAE28DEF876EC871A0 +:100F700093FECD61FDC27E637ECB381A87FBCD9F89 +:100F8000E4F78F3E2B3165BA838E49111D334D1C1A +:100F9000AE67F5CC84F87B86F9DD8897EF28209A38 +:100FA000789EFE24E487A5BF7F672CFAB164D975CB +:100FB00013DE2F3D1DBF0770CCF95A8B847EDD4CAC +:100FC000578B847EA361EF0FDD2FE1F9C26899F1A1 +:100FD00076F8877850FD73C53A1EA78EDCCDF717DB +:100FE0004F7D9D91DFA9A3355019C0F8940C0607D9 +:100FF000E6B1E8F979E41B72B8DF2D8B0DD1BDA6FF +:10100000EC3561178AFBE04B44DEFB0511E759B173 +:10101000C7C4304FA2E4E05107C67556002D875073 +:101020009F297EBA5FA364C7AB0E7ECFB8DE8EE782 +:10103000D8543D3A3ABD1576262E7F1CE8D8329218 +:101040001E5F93CBE3B31D6D35B3302EA3C2F360A7 +:101050009B7716F287AC7818C693F0DE9DF8FC33C8 +:101060008313EAE3D6AF62A9D194F5161F5D66B18A +:10107000A1AD85F84C2FEE07DA98B3D616FFBB0169 +:10108000AB7374E21EF200433B9B8B7A7C2A675061 +:101090003EFC91F17DA8D105E3C4CBB57BF358BCF0 +:1010A0005FB9ABCD47F06E90FC7E1CC458C842E6D9 +:1010B00014CC5BC0B397F07EC7F56F601E8DC1BACC +:1010C000D613728F8E37A34BB9122F971EC801B952 +:1010D000941C934BDF6D3B4B78EA685B44DF037CE9 +:1010E000318C9F05B2B87DDAD1B684DEEBC0CE423A +:1010F0007E7A65C784A36EA83F01FFF09E1CA39370 +:10110000C3C5CAF3483F2D167C803EAB5CE09F13FD +:10111000AD7AE2B37B722D415C84F7BC3DFE28DEE4 +:10112000F369005E92FF06B8A3DF11783208B904B4 +:10113000FCE4C3F566C856C8FFEBB02D203AFD7736 +:10114000C753F16B3033BA87C6906B21BFCD17857B +:10115000F37B39097ABE3C8FE4E83D022FAFECE027 +:10116000794727EE6564BFDE731FF7BFDDD3C8285C +:10117000FF9BB5C25F458C6F54799D8E3781C0CB84 +:101180009E361034458C3DDC66C293572C19FD64A5 +:10119000E36274ECF12A7674C76FAD76D6E1F3E1C1 +:1011A000E9A77B50AC6C99F5BB217CA28F1BBF6F6C +:1011B0006B6141B43329160BDFB7D74319BE9F22A9 +:1011C000EA53FCBC9C2AEA5317F172AEF739A91A0C +:1011D000014B8883E45A1CF30A51EEDDC5F8B95B74 +:1011E00071EE7EB790BB632C8EBA6AACFF1AA37CFB +:1011F0007CB5FE71519F6539D9350EE5F2426DFF20 +:101200001D020F9996933DB3295EA2AD57E31BE9EA +:10121000964B6F50FF126DFDA3A2BFD57269683661 +:10122000D6176ABFFF90A84FB67079C87CFCFE54F1 +:10123000B5FE3BA2DE8CF5F87D8FB6BE5B7CBF436E +:101240000A127DE88E585C3FE9DC5FDAD7C6AEC58E +:10125000F5D3D316A175F470DBA7442709992C3D6B +:10126000B6AE6CAD6CC4F3E092906729EEB0D73B9C +:1012700082BC53EB1D367EDE5D7619888F8C16217D +:101280002FC43A8CCA0BA9C5C3998BFBB13F8F9F62 +:1012900061815D41FB220FFE909F73EED5317F9CF3 +:1012A000DCCA6E4862FEB8F6AEBB1C9A72C6D7B2F4 +:1012B00035ED9D0BC76AEA2DE59334F5CC9B4BEBDE +:1012C00065ADE0ABA492324DBD7A0E9FF5E46AECB9 +:1012D000677DE14C4DBB4BC56EFAFD9033F3D4DF17 +:1012E00019F198502EACB58ECD44BDF34CDB74345F +:1012F000B2D9B3B09EF0E8D4013BCF2F3E807159F4 +:10130000B4D7DBBCF47E1FD483E5C29E84F5E686A9 +:10131000F67BDA6C547EA2CD45CFDD6D6E7A3EDE73 +:10132000564CF53BDA3C547E0CC6C7E7A3300EBEE4 +:101330007FA4AD86CA5BDB7C54DED2B688CA0FB50B +:10134000F9E9F99DB67A7ADFDDD642E58D6DADF427 +:101350007CB02D40CF8EB62EAABF46D0FB8038C7BA +:1013600078A0929F4B4EA4E3AC5C49732F983596BE +:101370003F302B17F307FAC39AFBDD71DE349E99D9 +:10138000CF3F71BC3A1C0FBE3B890DB527F3754C9E +:1013900071C7F1039EF5C9C0EF635A381D0A0622D2 +:1013A000549F55CF695127E065CE00CBA9E0C750C7 +:1013B000B1DD0569A82A99C76129BF8CB9609E155E +:1013C000E27E1C62BBA00EE152A673BDA9D2353AE3 +:1013D0006F3B8713E73F12BC5F13F397CBFBF9FD1D +:1013E00017353D2164FB246F0BDD7F615AE40BE16F +:1013F000EF57387D7E3A8F3FE9D3B9B0B90139F361 +:10140000E997991B9E390DDA7D4FF65D659AFD854A +:10141000FCE9C3CC7D358C5BA2DD9F2415AED5F4F1 +:1014200033E5DCAFA93738D76BEA97AE29D8E0426D +:101430007C8E61149F316E6E6718525CDEBB95E046 +:10144000DA24F07E4172D379DEC041353ECFEDF330 +:10145000EF09BDC24C9B693D4CB0F362516A4087B5 +:101460007AE1DC8F52491E3DFD842E88FED7892CFF +:10147000A8C3F53F19CC3DAC9F8237E8CA74A58A52 +:101480008CE552E696B17C358BD0FE04ECF3F5B9D1 +:10149000DC3E7FC28CF1C15CFFF778DE5288F466D7 +:1014A00091A06791BA1FD9AE24FA65BB72890FB5B6 +:1014B000E7993A859DDE6EAFC8C4B8E88551F2CA97 +:1014C000ACAE9933F177B4AC59D3E9A9BE7FC8ADBE +:1014D0001BF19CEEE3025F2ADF4F0426177CFF38E6 +:1014E000CEE37CF9BB19B8DD6B2A8C10FF5F90BC92 +:1014F000AE2588D73765CE878359342F45E05539D7 +:1015000058E95A02F853DE1EE709B0D8779E6EF309 +:10151000CE549458B948E445EE6FAB9B591DF7FE85 +:1015200075014F311BAA41FD545CA2F30469649715 +:10153000467E990B7BBC78CE5C29631E146F1359D1 +:10154000CF7AD4D5CA5F64CA73518ECD606ED81776 +:10155000582C21867941AF47E7C934BFAFF43B5BD4 +:10156000752ADD17981D957BA813F1F79486907F57 +:101570007ED7ABE7F33AA6AD2FB6F0FC9D15C58636 +:10158000A05BC2B07A0FDD8BA7F4490C4D7FE52F2D +:10159000B3090FEC8564E2BFE4ED53E94AED9B1417 +:1015A000FF0F91BEE743EE1774E3042F42BBC6C999 +:1015B00086BD688F4D40BCE0840A8B09AFCBC57CEB +:1015C000F7B72D213CFD5ACCA33337011EE6F1E2DB +:1015D000BD912B7A55FF87769E0F9557DD8CF7ECE2 +:1015E000750CC9C256D2E273937E682AFE36DDF9C5 +:1015F00030C025139CBF46FACBDB2BE8F795408122 +:10160000D0FC1A9F80FD7E01C9A31AD2DBD374944B +:101610009F9AC857A7841C6BC9E5797F56D79767EF +:10162000E2EFBCC5CAB3883F9FD1B162CA2FD1F1E6 +:10163000FDA59ABF0186831BF775A579BAE83D1A07 +:10164000F3515FDB7594F727EF49A2F389B25DA1EF +:101650003CE34E4BB56D358E635328AE32579E3505 +:101660008476B3D1AEBB1AEDEEE37BEF1FC2FC1262 +:10167000395761E82FEAB429DCEEC8D1513E9662B1 +:10168000AF36611CA6C872BA12F17974CF37C9BFE0 +:10169000217F43E488087F925E90AC93B5D0F881B7 +:1016A0001C45DCE7E1AD2DCD10210437EE7F6A3E0D +:1016B000423FCA71DB2533DA2B6ECB0AF2A715E65F +:1016C00015D07CF4186F83F213EB2ED9516EBDB98F +:1016D0006783A300EDE7A0423648F19F3BB2E9DC07 +:1016E000F91E039D8B57F19A1F503471BBDC566D68 +:1016F000D99810BFD3279C4BCACA2B107A6E110BF6 +:10170000C5CD47EFE2FB35E6B4D07EA7304F629FF0 +:10171000E962E531A2BC5F1FC8F6007E8EED5991EB +:101720008FF3BA72D84F79BEA3D9FB1FE7BAD5DFC2 +:101730004332EBE87ED59019F37E9F6A63E968DF58 +:1017400099820AE55DEF13F2ACD0C2F9DF90CFF9D0 +:101750003CF159D8C3D79D722029988C74B3F59762 +:1017600005804F26BF328FB941FF15DABCE43F2C0C +:101770006C35A463FEC0DC1F5A884F2E5992C84FA7 +:10178000A8B42679F07DC7DE8A62771CDCC1365B9F +:101790003AE6E5EC6D33A5A39C0A8E225FC7D975A6 +:1017A00094AFECD6F17CBAF9791CAEF979FCBE970E +:1017B00079A2FCA4125880703E09F4C43CE9A39BB2 +:1017C000B93DBCB6DD4470AC7D731CD955A3E1EDC9 +:1017D000E936573ADE0FBF77B32E1BFD4795DD85FF +:1017E0009BF09E84B5567E4FAC9C3AE9314C4567E0 +:1017F0003FD533B4DF3B52667A96C5C97739755603 +:1018000031F2952C07B2D12F7267DEFC9B315F124B +:10181000E8B713CB2BFB4A79D91AC8C6FCCAE6BE77 +:1018200069BC9C1ED889F995DFEA9BC1CBB9816C54 +:10183000FC1DA9B6BE6B79797C60279637F655F208 +:1018400032FA9E40766EE99B7333CAD90E83A71E87 +:1018500005F20F00FE1280BF5F3CB70ABCA8F5CFAF +:10186000E17BC0F321F14CAC7F41F41B18A5FE25B0 +:10187000513F38CAF82F8B7EA151FA1F13FD8E8F6E +:10188000D2FF35D1EF8D51EA7F22EADF1A65FC9F46 +:10189000897E43A3F47F57F4FBC528FD7F29FABD59 +:1018A000374AFD07A2FED709E39F10EDC3E2FD58BA +:1018B000EBE60F42C07763418EA05C2AB66E76E0FD +:1018C0003ADFDB554EFCDF51C1E33B2ABF8FC5DF5A +:1018D0006F827A5D3EBF4F4A97CFE33CCF88F1815C +:1018E0000FB720DFAD7D5BA63C9B0E9DE76C10E53E +:1018F000E8261DD9036BDFE4FBF3B5DD4A30FEFCBF +:10190000C53309F06F10F0750A789FCCE3F139A365 +:10191000CB955E1BEF47B269CB9896857217E4377B +:10192000E5ED167757751597638C4C471688D26886 +:101930000AE17D0D8A55E8055B794F31C26751E8B0 +:101940009CBA625742FBB1BFAB9CEC3B15BE4E8BC1 +:1019500042F775C956AE07E6FE70960DEDAC4EE641 +:101960001FF2627F9742F6FBD1AE321BCA3D83F570 +:101970002E1BAEDF76379F5775537112CA6BF92154 +:101980001DC9EFE336BEDEFB5C3AF25B805EA1F37D +:101990002C20AF3DA82326B0503B9D8F78F885259D +:1019A000DCAFC7ACA515745E448D434B4A9CFD7FEC +:1019B00059E0275FE81105F50B3C9F2C17E71C0247 +:1019C000DCFF0464738D893BAF79394FE6E740D47F +:1019D00038A25C4BF716E5AD5334FEF79C7BB5653A +:1019E0004382DE5012F4CAB82E9093717AA7206019 +:1019F000D3944FE609BF8E8779D07E9DFBC3CD245B +:101A00000F2FA17E9346977B51F92BE4F193E21EB1 +:101A10009E2703FC1CF1D1CD653F417AAFEDD6D1B5 +:101A2000BDD35F548E3E93C7B87FDA0F7A07ED19A6 +:101A30008565E37EE9F3F0305EEF73D0BD0A9F83E6 +:101A40008FF18F963B50DE8EF72BA47786E98DCFF2 +:101A5000C1D7B392E73D3FD2D19EC4ED6A1B9F77B9 +:101A6000678693DF4724CE1FCAC25E7B50F8C195BC +:101A7000D4B96EFC89904E7B0B9537489ECC1BA049 +:101A8000FD46C96FC3F21B8E24AE777293880FF7A1 +:101A9000A32D43F71C16F8D03FD21F34A8F71486A5 +:101AA000F0FF0E627E8E7A0FA28BEC33710F63EF24 +:101AB000CDD5D85EB14D469373DA138F6DD1830DBA +:101AC0007AD0C0A2EDF13CD533C775E29EC4DD5B90 +:101AD000D05E3D98C434F7401E443F3A8D17DC82F7 +:101AE000F73EC2F76E90610F767DFEF7B658B26290 +:101AF000F054B90F6C69A73C59BE2FB1337E4FF734 +:101B000079773805970BEC4FAECAC77DF99ED3198C +:101B10009ADF5D13ED5345FBA6C148D30137B59F4E +:101B2000960FEBA07120925242EB2B5211DF3E45F3 +:101B3000ECF7E3DA7F89C61FA57DB10ACF81776F05 +:101B40002DE1ED2B71FC0BEE7006E5BC24C0933645 +:101B50007CFCEBFF1A3C9344FBF3A177A9FD05162F +:101B6000CE985240FD6EC27E17DF7AB742CC3B035F +:101B7000ED64908A37E37B34B7F8EFB1B490FDDCC5 +:101B80006FEAB1A1BD66D6F7F850EE16E2BD4ED3AE +:101B900063CF05F985DCAE4A78DF6F6269B5C88F1F +:101BA000AD3ADABFF49B86CA4AD09E7ED102320F8C +:101BB000F5C23A0FCAC181F05A4F09B4EBCB99452F +:101BC000FB8A8386967E3ADFBBC442E74FFB6C3DBF +:101BD000365C3F667B8F0DE308F27DDC7E52965AC1 +:101BE000FC4F213F85D6162F8F5BBF556E3DC1DF61 +:101BF000FDAA6533EE03BAF59E9E0968675B15CAB8 +:101C00003F57960ECEA7F3823FD03192EF30AF2AE6 +:101C1000287736EAE8BEFA87DD4BEF413C30C5E76E +:101C2000AB827E79E98A84E72F1E547C268C5F186C +:101C300085DDD6E7E1BFF7AA7E7787B02F77E4F39B +:101C40007BABBA971C287E0DFAF5B5AEEDC7EF99C0 +:101C5000279A18E699F5E59CE9C6F3A28FBB60C701 +:101C60000B78B034E8E8F75A1EAF8536A9E8CF30D4 +:101C700068FC15CF4AFDD43ED0A8A37D82A5C4A0A0 +:101C8000F16FA435E8BCE8773CE0F66F427EBBFA22 +:101C90006DE506FC9E6BBC6243FDF490EB17261DC0 +:101CA000C09952AE1DD7364B3B8EA35A5BEFACD5D5 +:101CB000D6672CD4D6BBBE6648F0D768CB29C847B8 +:101CC0008847900116D04349BC8A2559AED0EF858C +:101CD00075FB77F54C8036C6E440E96B006FD2A403 +:101CE00024DAEF6F7C3509171FC81F467267E314AB +:101CF0004679AFC772BFE9427D9A889FBE1C03CD6B +:101D0000D75208F82CC0FDFA59FA5D2F0B8B6B5790 +:101D100080F8F13E93CFF7EFCC5581FE394672F053 +:101D200059D57F7C0B3F4FD5D7CAFDD20F2DE27915 +:101D30008134830A5CDFBC7D0AFECED854F4DB77A5 +:101D4000DD8DF98E8978CDC4FC3239C61F1BD4F3E2 +:101D50002B787AB2828B655C7797DCFCFECD970599 +:101D6000DF1C14F72D44DB23FE3218DFCAC2786F64 +:101D7000E6ABFE077E1E609B1A8F1165BCC610CBBA +:101D8000078F3B6EC0F5B46DA1A30CD7D346619706 +:101D9000A5E618BC1301DE47DE3004A4ABA0ACB04E +:101DA000E37AD0E7071DFCBB86379302789EEA11E1 +:101DB00057399DCFFA389FFBF39EABF4FCBC96D607 +:101DC000A342E7DF1E717ACC65DCDEC0BBAE19A58D +:101DD00016816971B4B68CF6A98F783D665CAF8FB9 +:101DE000E478CC989F6CCE526CB88E1D2E85EED1C7 +:101DF0007AC4E4B7A1DDE2000588BF1F67C8ED998A +:101E000047E7920087BA0A1E1260228F0FF3E8D2CA +:101E100004BEFA5C77D9F0FCBAB3F0D0B7D0AF9E6D +:101E200086E3A5F07E8827BBC0D3A57C37CF4B16B1 +:101E3000E3A7DDF51CB5C7BFCE8AB8F13C9CBF0C4B +:101E4000F358907E074D7C5F1D273A3EF392DF7E6C +:101E5000C34F38DEDA73F9FD4186358CF661CF5514 +:101E6000FAF71F45FC6425D13E3BDB955D85FC916F +:101E7000FDC6CE05780E61C34FB8FE342CE7F1A63F +:101E80006C8599BE8CF34EF7DB108F89EB30EB78C5 +:101E90004F1D32DBFF054658D4C60080000000000D +:101EA0001F8B080000000000000BD57D0B7CD4C503 +:101EB000B5FFFCF6954DB249360F424248D8CD8B5E +:101EC000401E6CC24344D4E5114445BA913722FE0A +:101ED000420204482080F6A6D69AC50445C51A2AAF +:101EE0002A5AD48D02C58ABA5440ACE85D1E5AAA5B +:101EF00056D3AAB7542B4D842AC82B86F65EDA7ABD +:101F0000ED7FBE676692FD2D89D2DEDBCFE7FEE373 +:101F1000A71DE637AF33E79C3973E69C33B33B9399 +:101F2000D82D3E076349136DCC6567F4F777FEBF84 +:101F3000740B5B674E622C650AFF5E10F63D2D65E3 +:101F40007C7E0963A9D38DF5D35858DECDEB1DEE09 +:101F5000BC8DC53336A0DA58EF89D8A3A5CC845CF4 +:101F6000D877F3B7E79BB5F67B078F60CC9F6EF110 +:101F70006C75319619311E635F4721AF3193EBEFDA +:101F8000398C8D772532D60FDFEB5DBE62C676DAEF +:101F90009C131C298C75AE649EA779FBF12FAF9F13 +:101FA000FB36CFFF67A6C319C56B651C6E692BE2B4 +:101FB000DFD95E7D30EA6FB6E84FC5F2F2CD47FA61 +:101FC00033BFC658542CAB0F723CD94C4C47FA77F0 +:101FD000FC5D8D71AC34CE78179FD448C67817015C +:101FE00053DA3F9F06070E2C747AD09FBBCDCEFBF1 +:101FF0000D5A9C85169E1FF9D4A30F5A33310F0E2C +:10200000E3189AB6978D66ECB9437CDC013CE77F18 +:10201000E2C189165E1ED35DEE47F94E9349E4FD99 +:102020008107278E656CE0A1E01A8793B18AA7B675 +:102030003F68E7788BFE9528F7F1BCDF02BCD40E31 +:102040006AE7F33B90B594E6DFF4BB2816C5EB15C1 +:102050009B3D9B90671F47B3AD3CBF7DF7D8D92E02 +:102060005EAF296E944B2F626C9A4BA3F95720ED0B +:1020700077F1BCCC368FEE715CFCFD7A8937C63CBB +:10208000475A397D8B9FB1B1FB786101E006BD5A9B +:10209000A3034F83BE2D8F72A663ACDA29685EBDA1 +:1020A000E7BEACFD3C7D25AEA2CAC5DB57C74D4C93 +:1020B000053C191718D39339DD1AED4CE7B8CA4817 +:1020C000F999C6387C03530E8D630EF04DDB1A2749 +:1020D000D2FA18A687F165C6050BD387A33F2FF563 +:1020E000873F7B2AB850FC3527E96C0D87C7CF7135 +:1020F000BD15DCE98CE9D04AC0F813BDED6A7D64FA +:10210000834FD9EC6011B84EE0C1C6716A2DE3A9C6 +:10211000C3128AEAA5FE6DB29ED9EE089987F1D462 +:10212000F9E611EAD76139DD6EEFA9670F58081F8C +:10213000AC9605F234C2933F0AF98424CA33AFD770 +:1021400095920AFE6784DC0C0B3B14C5C725EEE5AF +:10215000EB279D85287D82A3C791834A99899FC5D6 +:10216000327C62E0E3A7199B1CCED72A350D3211D1 +:102170007CB90DA67EC7397E0A0F46131C96752CB6 +:1021800010CD07CB053D38DD72D7B380C58D7AB64B +:102190007EC793D1CE25F9C06962345E7028D6D54A +:1021A000A6371DEB5902D197E4CEA61856037CA999 +:1021B000F1185B43FC10907CB1B9D1497454E5032C +:1021C0006B0F44D031C94047552FE3C200A2674F7F +:1021D000BF01EA2FA36117F143C6852CC927AE6F53 +:1021E000E93FBB8FFED3A87DDFFD0FA4F19F087DE3 +:1021F000903895A3E2C79DBB127D3C8DB6B6F83CE6 +:10220000BDE039E356A39C1CB6D72877155EA2AD76 +:10221000DE940A8EFFE8DB4C9E56DEDF65478CF5C8 +:1022200026BB3F4CC47AECA91F4A9986FA75A2FED8 +:1022300015278CF57DE37647D417F05D7DC1582FC7 +:10224000923E91F072B8FACD08836B823DCAD07E7F +:1022500076E54570F59B1506D73569C6FAFA9ADE1C +:10226000E1BABE20EA1BE152F5BE33FAD2EA45CE0E +:1022700063DAE4A83EF02EEACF9A7D69FDDE54F3DE +:10228000CDF56E69881CC72FF72BBEB6F83A4EC63F +:102290003FF812486E3079A3F93EEA649D0CEBA832 +:1022A0004BAEAB24E6A4F5CC17BE8675F53EFE9981 +:1022B000CED810B7EF2BC8AF0976EFBC8779D58998 +:1022C00072BF6253788F97A3735FF18DC517F31FA9 +:1022D0006377115CAF6ABACE689FB57BB6F2F55DE5 +:1022E00098C1ECE95C0F606981EC1BE3188B752BDE +:1022F00079CD450D8773A8C4DDF30382AB12699DC8 +:10230000079200CF3F3A6E7FB737C9DDAFA77E6433 +:10231000BD9EFA024F365B7025E0ECAC7378B03F9F +:102320007C8022DEEE9999512133C7D739AB639D6A +:10233000C6E5CC91D8F96FF6E378783F5E77A1FFD8 +:10234000D9B3AEBD1B79ED40B26B1587EF5C65FB71 +:1023500028E0D51BABE7BA391CB5767D502A9FE241 +:10236000994C7D7002F0EB4B26BCF27F14FB7A8512 +:102370005FC0335113F84F4ED08B31CE4453DB93B3 +:102380003E7CB3B48D423BE6EC47F09DB17179D70A +:10239000CBFA5778182FFBD96FF57CD5C9E7B77FF3 +:1023A0004382A789C35B9D3C6BFE0A5EB4D0E44BBD +:1023B0000D990D705F81F16A1D9583D201B755C2E9 +:1023C0006DEF27F1EECDFD26B89B301EF6B51F68E8 +:1023D00081AD6E414BE45FF62706EEE3F928D3F9B1 +:1023E0000F203F3A8B4D1EBE47B0CD5CBFB0F37D92 +:1023F000E53D89EF27B8FA634FA2EFEBF03D2D469C +:10240000B44F7BC41468E2ED7DE35F213A3DB3DC59 +:10241000E131F3B12A99CB06BEAD625E1BE0FFE36A +:10242000B8BFBDD6CEE737C7AD4FC73C6E4936659E +:102430007D4070E885159CDFD85881FF6FE307C6A3 +:10244000D69BD828C66E94FAC14289C769CC6BC5A1 +:102450003833986EC5B8BF396BF3422FFD0D7450F9 +:102460000EEF2CE6A7EF735880D29B5888EADFCC9A +:10247000DA29FFEBD892CC060E5FC5A383F3B01E1A +:10248000C3F0BE54F2CB2D29825F3EEF0FBC6FEC40 +:102490007749FC5BA109FC0D71EBABDDB45E5D29F6 +:1024A0001EC0E49C30D01717B67E26F613FC677169 +:1024B000E67DD3FA69EB8A2F61C3481E38D2391EF4 +:1024C000AE91A4BCC6BB6C0AE60B0982F5FA1DB935 +:1024D0005ECBCD0E96C2E9D2E63207A2382C93C766 +:1024E000AD4CC37C7FB186FD6A38A7DF2FC69959F2 +:1024F00013D5F452BBA9B2BFA903279D847EF20E67 +:102500000BA58CE0EDCA2FE88712387EA69A7734A7 +:10251000738D9B4D1E68FDB43D4CAE5D9BB2D3C226 +:10252000B8FE725DAEF1FB94229E0F93BB5399A54A +:10253000A79CD37F3FF003B9C35ACCE0DF47DD71DE +:1025400029D057D85036549C0F3835C2E6D365FF92 +:10255000DA768EB77BCBAD3F093E5A9578763EE969 +:102560001D16319FE5EF9A49AFFCB49181F3D87104 +:10257000AE1F7AF319FB8CEB17C89F684CA3F40BC2 +:10258000AE0F203DDD5840E5671B3D94FFD2EDFBCB +:1025900009E8B460DD9716EC4BF7442B7C0B3856FA +:1025A0004BBEBB2773D4A37FE578BDE71DBE303893 +:1025B0003C35C19649007B75E6A777417F5EFDAC4F +:1025C000E641BD65FBBC36078767E121FD6E90796A +:1025D000F13BED532126EAA0BF72BDE15EAB6F3740 +:1025E000C61BF9E1F1549D57F0EEEB783399D7FF14 +:1025F000BC7134C175B2D14B709D6A9C4C694CB6AC +:10260000EF55D4F7B22F6DA87FC38E0E4B06AF5F88 +:10261000EED5BC588F57795920C0E1D96415F27DA9 +:102620001397EF589FE38A6F7CE25606F9ABBF81A0 +:10263000F63392AACA93F9F7A9A32B2DA837EB2B4F +:102640002ED3DC3D7CF8EDEB50E0A34ED2E5CCEB95 +:102650001AE1E9CC9EC2EF5CC1FB7BFDB0999939D0 +:102660005C5D174C0457D79198009456556FD56E02 +:1026700033E993AB326D01E06FD5EEC2FED0A74EC9 +:1026800071BAB1FC9EF14E3DFF6F2E3D4C8E9E4ABD +:102690000AFEE74790539F0839C5F5CDCF1E871C2A +:1026A0001B38C003BA9FB572BD1C8866F5B1D8C788 +:1026B00096DBE4FAE27206F95331E21C3CEA858CBF +:1026C000F1582F18CF65EB9143F92F3C9AFD7D57B8 +:1026D000CF78DB830B3F7A9CE7CF044C7E2BDF6700 +:1026E000CEB0E0D99F438E6E7178703EB847E3F06C +:1026F000601FDD3A80F2059A25A681F83940EBB5D6 +:102700004073591AB8FCA9FDD96303C04FAF721CBE +:102710008CE6E5AF6E8825F9F4AAD573B401FD3DCA +:1027200021FAFBC90FBFF7E95EA40FD4957D0F48CE +:10273000CE4E227C57FF68C950B4E7FB344BE7FD0F +:102740003DF7B2168AE6EBB378E3FEBBD2397CC321 +:1027500036779806F0B4748BD684B430F3BAC36677 +:102760005E6ECF76111CC377B8CD19585603021F81 +:102770005D4DFBB7715F2FDAF8E5781C2FD5FE3E73 +:10278000540B7ED18AF370D691329DF0D742FDEC86 +:10279000DE37EDFD9B18E6C13507C05D69F3D07EDD +:1027A00012F0B782CE67F402CF7D58D33EFF63A00C +:1027B000EF193DD583FD658FC91F3F06F58F5A6818 +:1027C0009E2F6FF975BC95E713765959342FAF2BAF +:1027D000ED9C84FA75992E3A87673E79CD64E0675F +:1027E000F9AEDDADD44FADDDA3619DED3EFF6606D4 +:1027F000CE43D7324F1EF86E97C8DF3FD1EB01BFF3 +:10280000D5B4FE59E4DB7C94F799FD6E0BEA5709C9 +:102810003DE751B98FB1F6129277C4CAAE1E7ADD88 +:10282000CF8B51BEC9ED4FAF77F4EC7F7CDF2ACC64 +:10283000E6E5E936D9DE392DCBF70FEC5B36B90F7B +:10284000A9FE1EB5317F34EF27937FD7B0AFDAC42E +:102850007EBB95CB17F08BDA6FF9B857648BF65EB9 +:10286000C8C90CBEB996F2F9643C1A15A03DFD1218 +:10287000C7577AD28A1821CF94FE313BB9E9B57691 +:102880008ED73FC5EBD7607E0BE57ECD2C9E34CC3A +:10289000EF58BC7732C6AFB57766610E7C3F9C823D +:1028A000FC7233D79F72C2F427FBA5ED875109DE76 +:1028B0001BD1FE52EB8F8DE95DFE8EED1A4DF2F7C6 +:1028C00035297F57FFD9C44A797EF5C351244F6813 +:1028D0004FEB052FAFF1F5AE73F9F2EFB01BF0F44B +:1028E000CA3FB59BE9FC71C854FB26DF4F69E86C11 +:1028F000FC5F6753C208CA7B41E6ABFE64EAF57C25 +:10290000A8524EA77ACCCBFB95D1DE70F5574E1B63 +:10291000F5EF48BAA4F99AFB98AF395ECC771FE679 +:10292000CB69B7FACB329297FB2E719E9951DE3567 +:10293000A06FE43C38DCF7E07B24DCDDFCDD79696A +:1029400070DFA631BF09EBEC4B5B00EB6C1F07138C +:10295000EB76DF92A200D6F31E9BC8FBE36DA47F4B +:10296000EE8B637EC88F7D15A901BF1B729009FD98 +:10297000B41F13E5D1B2FD9C546A3F208AF33FCFC8 +:10298000B39B6264FFF56F17A37C4D868743C0F548 +:10299000DBC0BA6CD26FCD64373C22E5F5C6C4D03B +:1029A0004D66FE7DE397F90CE31C61A18C15A857D9 +:1029B0001343726863A2373D89E371CFD766DA1794 +:1029C0003696F2BC83E434D977365678D313797EC1 +:1029D000AEA4CBC6D6C0D647D05F4581C7CFC719F6 +:1029E0006066F554CF2DFAF9C82ADAFD4ED285AFCC +:1029F000635AE7EF672F0801CFFAD4580BEC221C7B +:102A0000E3E91A87FFF1EA3C46F252DABD664B1A57 +:102A1000CCEDE103AF7D14F45AF13767E1D668C815 +:102A2000E31935D164973A5273579C8B8F374337EC +:102A300087A2A0FF4D2F37D89DDECFF6D2B8FC601D +:102A400021CF09A12AE0F1F54E3B835CEE8B9E7508 +:102A5000C171C9C7C3F8A1C626E4C709A90FBD1231 +:102A6000A7BF0B7E5FB1F7DAE4E361FA5EF5C2F26D +:102A70007CB2FB565FDAF9AE09741A46EBD56F02E9 +:102A80007F04A389FE936FB413BDBB1CA6A76197F7 +:102A9000BC45CAAB261C84F9F7A6DD5181BBF8B74B +:102AA0001551A19990579CFECF6E035D5F8B26FA5E +:102AB000D7DA043FD5FEBC90F86B8FCDEB5E8BFE72 +:102AC0005F8F22BAD7C6BB12A8FCAD6426F98FF47B +:102AD00086DA98507E22C7E7BA58FD24F0C6F98EF0 +:102AE000ECC1B536F1FDA8E4ABA3BC0FC0E1AF8FDC +:102AF000237E6432AF7F3F99CE535C1F25FED51FE6 +:102B00002CA4BC6EF3A62FC4FA58154BF01D95F6F5 +:102B1000B4A3B589C4DFF31E5CF60EE3F43CEADB34 +:102B2000766F3EAF77749FD5837DE9F70DE6908D84 +:102B3000D3F5EC1DC7466DE2F9F6BB3ECED2C3EC31 +:102B400068F3EEAA9B8276F396DE3115FB655FF89B +:102B50009E571BC5656E0F9D5272BCE61C8E7F4F43 +:102B60008E6ECBE1F35C51D4BE0872EFACADED4993 +:102B70009C0F3E4AD0A3F1FDDC2B9F6F237968E9BF +:102B8000CC877EBEDCC2F9007C29F7CF15922F5F7F +:102B9000CCD113509FE38FF4F1D8A23621F7EEB8D1 +:102BA0003439FFC5BEAD7B343ECEB2987DCB2935DE +:102BB000074AD0CF292D14AFE5007F5C8FE3FD9D40 +:102BC0007686E241075D9E9B966D37CE0B7FB0AB5C +:102BD0002CC33F78BB654133D955F8FE6E03FCCB5F +:102BE00060E935F813845CE1FD3C4DEBD0F1FBF975 +:102BF000DFE7F85FFAEC9032E893CB12F7FEF00AC9 +:102C0000AAC7DB293E375F9C57F3B9181E31BFD3E3 +:102C100092CF4F33290767DBBACFE1D083CE3EDFB7 +:102C2000DFC037679F1D42F92FB44E2D86C37556FE +:102C3000CA23E6098EAAC001C21B1C057DF611F944 +:102C40007D59727014E48F9247CC1E2CA17375418C +:102C5000B004E74925CF982F984FDF03C17CB4DF3C +:102C60006312760AFAC3BC9FCB68253CD8C57A5C50 +:102C7000FA5C21E1458D1349BFC8F94ECD11FE0123 +:102C80000EEF2D3E5E7FF0269BA17C48C0989F29C9 +:102C9000EB0F8AA0CB0073E7FE28C8FB6718ADD7FF +:102CA000C8716FCE11F6F49FFEB49B0E66795E6418 +:102CB0002E457F97D0B7ADC0F7EFBAF17D6B069781 +:102CC000A7CB30C7EC9EF9EF29D53320F7CF9A84F4 +:102CD0009D7A4F22CF1741CF11F8547985C7483ECE +:102CE000BAEB778B32E04F5997D3EDE7E80F7E6B65 +:102CF00082BCE4F2A2C92AF0F14563CDF0E3169C50 +:102D000047EBD3AB2D3DF359B4A9D48EF5B278730C +:102D1000A97D41D879A769FBF0C32E4E97D3DB2D4F +:102D2000643668B2047E083DBA69BB39E867546E00 +:102D3000F7F2FAA71D07DE45BD459B13CBA0F7AA06 +:102D4000F68B37DD965E1D86EFC2ED46FC17078DCC +:102D500079D8A3C3F33F822E38F21F6F571A32E699 +:102D6000871F36E63FFFE0D69960E397470B7E3F2B +:102D700011880BC04F55F3F1A4C3D8D74EEC793965 +:102D80001EF459F649F59B38B72CDE64E4334E3710 +:102D90000D7ABD7F9B46FCB12410B9EEE47ABF6882 +:102DA0003DAE5176CD82703E89A4E729169CE9E5B7 +:102DB000FC54DBB06A38FC21355338E372782E0FAF +:102DC0006EB0C16F10395E5FEB9E39BC2ED8AB2A56 +:102DD000478BB2310DE3D931187DD7FF7A12D65B1C +:102DE000E5FD1AEDFF952F0D3E04F9DDB173CE75AB +:102DF00094CE9C4C7850F6B3C5FBB4501CCF3B47E7 +:102E0000BBF6B6F3760B031AED0F0B9AA37AE41018 +:102E1000FF5FF5FA083836869573F817EFDDFF1770 +:102E20008DF75FB3D9D86E09C717E4FED22D7F8F17 +:102E30000AFFAECE7D63F6B59A31EF850A7EFF5567 +:102E40000CF3122E482E3AA4BE721C192EEFA39238 +:102E50007C6DD85FC66C14EDB8C0AAC47CEB1C3680 +:102E600017E65B6767A1580EC7E1389BD7C9BF9FBC +:102E7000DF1447F6A945515C2F2CA3944597A19DDB +:102E800087F6E9CFDE3393BE5287B1D1CF531A9D77 +:102E90007FEA606C44FE19915FC242340FF08B37B9 +:102EA0007C7E01639EB5887353AD25B41FF858CA64 +:102EB000DAC5B987D3D11BE68FABE5F33C92047D2D +:102EC000C8D87E050B52FD157BFF1E15FE3DCC4E6E +:102ED0004AE73975AE34DB9817FAB1F9CE18DAEF54 +:102EE000B9208E017FAED5BC8FD9CD48C5BCFC1BA7 +:102EF00084FE33B755EC175C3FCD077E366E18E283 +:102F0000819E3297EBD9D1D02396C450BD8D898C48 +:102F1000EC2B1BE7E40B3DFBEB974218A7F3618D0D +:102F2000EC231B4B45BF1B1F1842E590871A8D13DE +:102F3000457ACBC60A559E497AD247002D1D7AAEF6 +:102F4000FCDECF45DF0798BDF9D0D7D943D174DE79 +:102F5000577AED33497A7C6EBF9EF92A3D98D55C4D +:102F60009AFEB755EE779D1B84FFF7B8E67BD31426 +:102F7000A6970ECA15FBC3A8F1DE6DB21EF901AA11 +:102F80004D15F75DCDE1A97EC4E46A72F7E09D7945 +:102F9000BDF998FFF10DD165E0B351E385BDE76858 +:102FA000A990DBB1239837C0D3825CB17F14E49A37 +:102FB0000C695A0CE73FDECFF172611F8E1BE123D3 +:102FC0003B1BD7D9487E47CE638484AFDAE67BEBE0 +:102FD000CA5EE0E9E6838942CF38BE527B5AC0C55B +:102FE000E9CAF3A37E144DF6B9E3725F51F8E77CAA +:102FF0003392F66929AF36483ED900FA633F5B2227 +:10300000CE413D7C62E483B99AC02B7B40E8A71B8C +:1030100013455EF1013FEFB0BF824FCA19E1BDAF6A +:10302000738F9AE7C65651CEE93D05F48E3CF728DA +:103030007A334B6024CE8D7DD17BC1E8C4519A890F +:10304000FCD67EF8ADB1D7115EEEB504EEE2700CA1 +:10305000B408FC675A047F71A9EC8F29A3FA5E1BA0 +:10306000CF573EB4987979FDCA0C46F6205E9F256D +:10307000A03EEF06712CD82BD0AE3241F45BD99F25 +:10308000D13981FEB8BCCA459A4DFD7A4D49A27D21 +:103090007C19B5F79B447BAF85A78372843EDFB96B +:1030A000362AF034E4F33D99F9E08329E38D7CF08E +:1030B000EFB962BF57E9D03C97342A79D2B0BE1736 +:1030C000340FA1FDA229DA57B71B747B5EE8FF9588 +:1030D00077DF7CC348C0F742B207E07D317527F93E +:1030E0001B1634CFB9ED439C1BB647D3F76BF2F4F4 +:1030F000DB7347420F74CDDFCD3F2C9871D096C65D +:10310000DBEBC18A333FE7E954FFCE77A10F4C9D3B +:103110006EA6FA5399B08FB26631CE0DFE2F2D698F +:10312000BCBF1BC66A1433D011EDCC5AC9E1AF94B1 +:10313000F4BB5BF26F53349BFD3307E0CACCCFE6A0 +:10314000DF6F8086D98BFFEA90AA3F4EDB0CBD660D +:10315000D004B1BE547DF4837EDF92EB6983C48BCF +:10316000CA73BC52FDEA75511D39F148ADA1C13C8D +:10317000EDCC1FFF30F86A4A369BB40978FF9E19E0 +:10318000B10A1CDECE4A5AF771F92EF0A9CE588842 +:10319000E223024388AF3BC67576DCC3F31DAD83E3 +:1031A0003D64F391E7E885385FB9502EE498922F9B +:1031B000479DED71C4AFF25C5D2559E38F0D131E81 +:1031C000B98CD7AF72D83AB01F2C7C785A3CE24CFD +:1031D000AA369A453CC77AE3B99A9F7F5F045D227D +:1031E000CFC991E761F00CF8A87ABD467C38A8C930 +:1031F000634B2739A63931BF6A472817F2BDDA1366 +:10320000ED41F9E9466FF2F15CF8232653CABEE2BC +:10321000781F057B2CA3208E0379FA3EE0A9B2A586 +:1032200092CE8BB1453AC9A7BFE5BA08CF53604FDC +:1032300084BCB1B4A7631DD6A9EF49CE7C07F17356 +:1032400034031E3AACCE7CC0D5B136DA847D73CA65 +:103250005D82AFF93AB35B78FB7B2D2C06EBFD3E2C +:10326000D97EDE1A8BAF95E707DA99252E097C55B2 +:103270004A7C5D3658DF003C9CF8011B8DFDBF6A1F +:10328000FD068247F105B3B44D4C867EB7D55D7619 +:103290001FEBE1A3B2C1E3DF47BB6E7E98AE111F07 +:1032A000F0747F0EF1C38D47503E657C2877551131 +:1032B000FC58B5CC0B3F421AF3C01ED0C53A499F0B +:1032C000E8E2FA04E49992274A6E703EF022AE4793 +:1032D000D157C98F6D8D1C248ED7ED8D764A7FDA3C +:1032E000E864162E037634A651FE854617A5C1C69E +:1032F00002FAFEB3460FE577358EA6FC9E462FE513 +:10330000F7364EA6F4E78D3EFACEF1427248C91563 +:10331000258F143F29B914C947F3397AAF2AA3F688 +:1033200024F794BCC33C4C653DF248D1375BF3F9BC +:10333000D3DC9063ED73202FCACDA79F7F197692BF +:103340001A8727CA05BC08B9D7E5B0939CCFB2B19C +:10335000BD38AF37ADF476DC13B6AFDE54A3314BD6 +:10336000189FDE5C1FCD2C617C7C4B43A2213FAFBC +:10337000E1FD37FAF3FEB544DD91C7E1387AE7673E +:103380004FFC967F7FEACE2FF2406F0EC7D64731B3 +:10339000EE1D31DD702421DF6C25FD61508C380776 +:1033A000E10F7459C0C4FA7CEACEBFD2FAEE688845 +:1033B000729979BD050D5184AF8F40278ED7DF4BB1 +:1033C0003A55AE3DF6FCCB58E777D848CE2D6896F7 +:1033D000EB721DC76798BEF6693A23BD4CF33206FF +:1033E0003FCCA73FB085F89ECF3ED5EC010DBA0F7C +:1033F0003F24CDE3DFF575BFA0F82BADE130E9C385 +:103400003AE2B26027F05B0DF1585A838CD36A1F01 +:103410006888A38A1DE1B5413E80A741B70505072D +:1034200018D6356BD19CD802AAE5F7EA751AE91BC4 +:10343000DDFA429E99E8589F6BA1F45DAC71DA2FDA +:103440005A687F52FCCAE585378075D1526A5B1491 +:10345000268717C8EF5505264AD5F7FA5C1BF5F302 +:103460002E8403EFF7BE826CDB4292732E1BE48046 +:10347000AABFA0A0ECEEEC11E8675C0A0B5B8FDE44 +:103480003C0BB5AF47A017CE477661FFAFED631F8A +:10349000507AC909FCF372829FCE5B4B5F78EE05D0 +:1034A000F8C7967E1C45745A3A4CDA238A02A3A6C2 +:1034B000913EE375687C9ECB25FD273EF7497C3B1A +:1034C0002F5FB14BD82F79DA8174F91D3564D75A43 +:1034D000EEE1EB230972D5E8473EF4C2C7F1ED7483 +:1034E000AEF06720BE906F0B192C0DFEA2639360A7 +:1034F000175FC13AEF465C5764BB15DA57F1C2BE9D +:103500002FFCE4CA7F59FEDA9F53098EDDE7532171 +:10351000D756BCB63655EF65DE2B22FCD7CA6FAE48 +:10352000EC602BD8FA2FE1778BACB72A4FFAB52F86 +:103530006397919DC2C2288E61955DE0A12B909703 +:10354000C07A19AF7BDC4D5CB0F3736897C595E02A +:10355000E1709EEB238EEFE53CB13F9F917ED473EB +:103560003BCCA4179EDB1147FCBF7CC7436F5EC1F9 +:10357000F3CBB7681896D5B136C2D3F25D66660F45 +:103580003FDFC06E93DC379CCB9E8BAB073F2D0992 +:103590006ADEAD45F0CBBB12FA85EB8B929F964568 +:1035A0000547111D24FCF749FD48D55BB2EF211BEF +:1035B000E8C5EB9D25BDE5C558E8DAFCAFF35DC075 +:1035C000796AF370F2EB2E09EE5C4EFBFE8E582703 +:1035D000A6F885D5688F0AE489F514C813FAC629B8 +:1035E00069FF3DF58299E40FE0C43AFC4213765E30 +:1035F000D56E9B6CB74DE2ED863CB11E55FD25C1E5 +:103600008EF85C5EFFF3BDEF531A94F35AE2682B19 +:10361000C17EF9F9AED8C9014A7F3CE9553EDE9931 +:10362000E0B8142D6C5DBD9627E286CF6C364F0650 +:10363000BE5840C51905693EA776646874AE05BEDC +:10364000397E4EED7A29DE44EBD62FDA493A9AECF0 +:10365000C29EEAB6B8A4FDC2EE849E31976B75098E +:103660005CDED5ED12F10091DF557D5A6FE9E0F790 +:103670004E9BE07FE9BF97FE25C489903F3ECE1662 +:10368000C0FE3A7F986BD64D90676F5B053D06BADA +:103690001EC5B96AFE7BC964AF586575F547FE4F14 +:1036A000EF58C97E3E7FB85CE769ED23619FEC70FF +:1036B0008B7DBD761D5F217CCA0338FDFD7C7EB508 +:1036C0000113C5531ECBCB26B81EAF31796DE4E78D +:1036D00008E5C34E79D4C6FC66E8C93F8B26FDAE2B +:1036E000365BD8DD1F07BFF3B43629949F0C7B9758 +:1036F000A463ED8DBC3C8C9EB54F87F2A1B79CB600 +:10370000093B1ECA9D48CB44BD26C937E807FD7654 +:10371000B89D6749BFDC1DC7A0E79B5E8E13F6848A +:103720009F4493DF41F57B5EF25593F473F9B70A3A +:10373000F80017F4E625B6967CE8956ADC25F12DAD +:1037400034DE6939DE929816E13F907161A84FE34B +:103750005B9917E7F1CE67A3483FFD22BD6D0FC609 +:10376000FFE2D921E407EF700716EDA572AEB7713D +:103770003A2CFD695408F09E7C368EFC9C27AD42A5 +:103780000F3A19974A7AD0E1B847E6A3BFAE2D5158 +:103790001AEC292735664B43F9D67EE4AF5ADAD8BE +:1037A000407E82A57CB9C31FCDD3C9F02B9FDC3AE4 +:1037B00084EC2C277F6926FF22FFBE0EDF75D632F0 +:1037C000FF76ACBBEDB16467FBE2A77F1B12EE7F17 +:1037D00050E9D22D467B92A2BF2A4FC917EB2B2569 +:1037E0005FE0312D5FEC3375B1C147B2699E62BDB8 +:1037F000723AD0798BAF8F54D8A78F065F49D51C0A +:10380000C07328FFC7C0FB7671AEF9628795FC22B2 +:103810004B5F8EF392FDE69ECB4CD82F969A85FE99 +:10382000BB94B39B48857D68697C3ED98738BEE9E7 +:10383000FCD8B9D52CC711E39EDC9629ECEF219971 +:10384000DF531C009F4F4962B7DC48FACDE612E017 +:10385000F5FC965813F8828FE385DF7EE9EDDF17DC +:10386000F84C5844FA38431CF428F8CB85BCACBB60 +:10387000E78A04C4C3B0F7CC0CA2EFBCC5D31FF2D7 +:1038800030125F8BF3A5BCDCF3840DFEB35ABE5E31 +:10389000101FB44CFA4D97FD54237D6ED9DD573C73 +:1038A0004A72F05D2BCBE3709C0E3E141F4E8F0AC4 +:1038B000D94F4F7B0FD55FC6EB8BF66FC7133CDB41 +:1038C000AC1EC01349C74B6EFF53F325B5EFE68F0F +:1038D00020DFD74B2E9EF779D6F6DD8F2147764431 +:1038E0007BFCF435487EE753D6E022CCFBD4F3D101 +:1038F000245F4E258AF5FE3997877E1BE0B8FE418E +:10390000B26FFC661A83E85E1C30F6ABC69D992F39 +:10391000E46F5DB22701FE8C3A4E07F4C7E9F21D51 +:103920006AFF9E95DA47CE63A46CD7BD3E9F8F2574 +:103930007E393540D0E3D40B83695FE948147CCEEF +:10394000E1CDC239E554A2487153067CB0549E4380 +:103950004F8D0BD2B9FB94B693D20EAB68B7B4417E +:10396000FA6D39DFA5816FC093F05BD9D7B7418F6E +:10397000807D7A5419A5A1A8A48BEDCCE04FEC432F +:103980002FE40B7B16D41AC875F26F907E12B441E7 +:103990001EEB528FABDD71B1BF8CFCA03B34F2FB50 +:1039A0003C20D729A04E51F671CE8FCBFC9A17F14F +:1039B00046CB9A572E01BF2FABDF7013F85DCD6356 +:1039C00099854DC6F9AA4333133C1DD17CDD000F08 +:1039D000E1E365F7E07793821720A7929E49CAF545 +:1039E000E67CB15F21DFC2FBAB6DD6D6D3386E75F6 +:1039F0009E14F35378E268B1C14EC6CFF9A2BC8FD2 +:103A0000F92B3823E7AFE009E60BFB4487DBF5E051 +:103A100058D0FB5766B29F9EFF6A7842D237E8655E +:103A200038B175DB8B39FCAFF1BD1AFDF821DFB081 +:103A30009E618FE670E66F36FA3F0AB618F3437759 +:103A400018F345BB8CF9927DC6BCE79031BF558E0B +:103A5000ABF084732EE2DA70CE458A73AE2B5F9C96 +:103A60007391C7391729CEB9F88E732EF238E72231 +:103A70008F732EF238E722C53917DFCF4AF95D2B55 +:103A8000ED8EA003C557BD12ADFCE0B45ECECD49AE +:103A900025F9A9FC99E7961451BEDB9E5361277B5B +:103AA0008E8AD3B929413F924F7EC3B6BBD34137EB +:103AB0004B3BD97157FC5CD8716BCBA21DB02FB4B6 +:103AC000AFFDFC6EA84F2509FA27F914D7D4B94DDC +:103AD000C42B85486EB4AF71BD77B5A01FD93954DA +:103AE000DC4D25F6BBA4BEE918E94761EB8D7E935A +:103AF000483F4AA4FF24920F94DFE4296B673AE41D +:103B0000FDB167EDEB01FF31691F63B39DA47F2910 +:103B1000BDBA5BFF7A407B1AFBF6D7F949D4BEEBFE +:103B200030D7B77BD96F555A75A18CF4C6EEFC7AA5 +:103B3000CD44712369F1B40FAD963065699D1DF7D1 +:103B400040DEC599681F3FEF30D1B9E0FC0766D26F +:103B50002306433F0F9BCF90408C81BF0AB7274578 +:103B6000F8FF0618EA0FDB9B1DE1FF1B6AF44B4DC3 +:103B70005FB31FE7EB69EB871BEA55FBAE88C0A379 +:103B8000845BEAA54D776CCA82FC591DD745F0AF1E +:103B9000DE1D4D71B5D51C5E2FFC72C87014D4D8D3 +:103BA000BD5381BF9AA03511FB7C95DC7F58837192 +:103BB0003FAEB130BF33A987EF6A9CCC9BC8DB9F77 +:103BC000296DD966E2743B63DAFCC85817FC4AAD2C +:103BD000594ECE57B76AC1D4CB797F7FB3E84583BE +:103BE00039BF6559433F9C0779B93387ADE1F58EFD +:103BF000AD7F299EF46EC9675956670CE8DDDA621D +:103C0000A67301EC52E6A41E7E686D498EC975F458 +:103C1000CCB387FE5FD1FC385D3CB8A7D8E538301F +:103C20007035F4B8A0986FCD38CD4F7AB29CCF2ABA +:103C3000B9AFB05CD1CFAD327F5C9E17D4FC4E0FD4 +:103C4000D95FE2821FB3716F961972DCB4631BEE09 +:103C50000FDC19A35F337824E225F37E3B968FBBFC +:103C6000F44311AFFBC78D13E22F87FEF9BCD533A8 +:103C700085E7EF6979C68673F1524BC0867367CDCD +:103C8000B3AD362F4FAFD9DE4ADF176DAFA4F3F6D1 +:103C900062564FE7C8132AFE56E2A366BCB6D9C9DE +:103CA000E17E61B0901B3531226EA3DC3CF60DC481 +:103CB000A59FDFAE9562BED37D3B6D95B03FCB7ABD +:103CC00091EBA3EB9D69E5FD604F0A0ABF675FEBCF +:103CD0006146A880D6C3B40B2E4AA75F184AE7D81E +:103CE0000F99AF98E44451C479F61D1187DCB54FA4 +:103CF000AC831A5B28651AD6C9EB565A27755C7EC9 +:103D00008D2EC33999B1313CF58D351BF875C5C47D +:103D100058033FCF6649063FF24C5CDA0CCB4F9F0D +:103D20009263A83F6B7A6104FF97F594931C196323 +:103D30008833A9BBC3EFD2289E65BCF13B4FEF206F +:103D40003EBBCED0BE8EDDD8530FE7E02DBF263C64 +:103D500033D666C379ABC624E26A66EB1DF27B3BC1 +:103D60007DE71331ACC341399EDF8A7DD14A767934 +:103D700065979E8D7FE7F4B62F7242CB71111F0AB3 +:103D8000FB8221BE900340E74F26E85027ED3D75AA +:103D900005C2DE53E76FB321FE96E3DF92C151B255 +:103DA000BC45237B1EAF6FCF4812F93BF07D97F1E6 +:103DB000BE01FABB80F2C3E64AAC97C8F2E57CDEEE +:103DC000D03396C34E033B93EA5FF6ABF873F1260C +:103DD000A3DD6839EC396174FC72B08BF874E9F6D4 +:103DE0009D6F0EE07899E64B2CC5FAA90D56582B1D +:103DF0008B2EE63325DFCFD798C8CFDDF5CE41E255 +:103E0000B3AE1A0BF1F3B7E163B957D83323F96FA7 +:103E1000119F0FFCB28B76699E8026EA012F03C0AA +:103E2000971178C9E8055F0A4FDD788B285F8C7F92 +:103E30008C40DC801608B97BC38BC4A3EA3F024FD9 +:103E40006CB4110F8B74D77B90378B0E9B59E0129B +:103E5000E6BD18F3C3F87C7E18FFC60BC24EA2FC69 +:103E600006332F5828DFCD273E113F3D7D8A715DF7 +:103E700076F38D4FAC93191752A9DDFF36FF7C1BEB +:103E8000DF28B823E393D5FD9EFF1A2CED8423D9B8 +:103E9000485AFF971837ACF67B85E741778EA678AE +:103EA000A22E4736E90FDDFB8DD358BE2A2E9BE2AA +:103EB0008875699F53725797F5D43895BCDC351CCB +:103EC0007C3C301576D7BB9B73B2DAC3F4127DAD60 +:103ED00095ECA6596B9229AD8C76A662BFA85C635F +:103EE000F6611FFCF4DEFEA9A361875F6B4D99C2EA +:103EF000BBFEF47B23B25831F2E5941EDB10353B58 +:103F0000DC9EAD525781D80FEAEE3C42FBD719D365 +:103F10003BF1B3B1CED6EE8E4748CDB2B5EF8F723E +:103F200072D5A3D5A20F2A401CA1D6BACD09BC399F +:103F30005B4B608F1E06DAF5EBD11396AE2DEF0FBB +:103F4000FB57EDD7079FC4FEAEAFB1A642CF3CF9F9 +:103F500001DFFF34DABF483F3881F8E314F8AD627F +:103F6000E97EDB098D79E1BF5962DE5FE234ECA7BF +:103F7000FB66028E5762F46105E4A70D6C4BC3F833 +:103F80001E3FC54BEA6BF2127AB397A874C526A1FF +:103F9000BF6D53F65A69D785DE8E3CF4763885A01E +:103FA000B7230FBD1D29F4767CAF90F6FA414D9DE5 +:103FB000A53877FAC7B3827ADA5F1D05D0CB576B85 +:103FC000311EC89BD59AA73FEC606C4BBAD85723DB +:103FD000E8ABD22B3BB96E15C6EF575FB0B3F0F824 +:103FE000B1712CD1909F604F37D42F77BA0DE5D7A0 +:103FF000A40D31945FEB2A35E4AF2FB8DC50FF06F7 +:10400000CF3843FE3BA3AF35D4AFF05618F2D326DA +:10401000CF31D49FE1AB3494CF9ABDC4503E475FBB +:1040200069C8DF54F33D43FD9BEBD718CABDCC698B +:10403000C1FEB60FE7298EF7D7719EE2E9EA5FE588 +:1040400039C2E93A7682A9BE377BFC7725FF6E1A22 +:10405000E25D09FECC94F74032E57D8EE60217F171 +:104060006706EEEDD379B62D1D7C13592FB27C6C0B +:10407000EC81F32E4EC33F6C9F39DDC2E5C3D8CB34 +:104080000E0CCFE1F9A421F74FB770B932F68A03CD +:104090002F65F3FC80216F88F26107CEA3FCFE211F +:1040A0000F8AFC3446AA45F690F1D3FD7C1E63AF1F +:1040B000CE5EEF11F6905EE32D550A3C206E11782E +:1040C000401AE2FC89F400E74FA487387F56E732B4 +:1040D000F626E74FA487F9B912DFDFE2E74AA4EF3B +:1040E000F07325D277F9B912691B3F5722FD4DE3D2 +:1040F0006C4A3F68D4A9DD7F34D6507AA4B19EBE05 +:104100007FD4D840E9EF1BFDF43D50A0EC0721B26D +:10411000B3287FD272F8F16087DB6B3D1DEE6755E7 +:10412000FE40E5FF6BAA67EDB158A7ED96C4CFEC52 +:104130003D7EBDBEE5AC857D16A66FB5C67A9F2BCC +:10414000203BC94027C96BF97DBC362DB38CA77FB6 +:1041500071E93B41EF1965556B13DCB807526F05E8 +:10416000BF7C68EAFD5E707381B03FAC1AE2DD434C +:104170007C22FDD8CA8FDC1D9F12E6E73685C5C5B7 +:10418000D05F587C8BF237AB789AABEC223E4FF97C +:104190009355DC8CEAAFFC02237977E53A0BE927EB +:1041A00071161642FF2A3EE64A7BB014F10257D63A +:1041B0003A280EAD3FFF6E2BA37A5E334FB7FC99C2 +:1041C000D72FE9F15FF797F0F37282BFFC824E764A +:1041D000D72BA5FF1EEDEDA2DC8FF6889D829EC138 +:1041E00053B2AB3D8138A7B21E7F3AEAC78AFA21A3 +:1041F000F497FB9F7CBCF89EF59399142C453C5595 +:10420000E67207C5536D1E17A2FB5B2BDCFAA7A055 +:10421000932FCAF9492CAD9F9C4CD8092AA4DEFBE8 +:104220000D74F81CED147E149E155D147EC3E28E91 +:1042300008AF7DD129923E917451F428BFD0836795 +:10424000E0E9623AF4D009F6D8FF2B74186109D27C +:10425000FDBFA85ABB07707D1B5D6EE96493709F1C +:104260007870B6DE0C3C575E70BD897C151B370933 +:104270005B932AF77C4BF92C94F7EBBBFCB63ECA58 +:10428000DF8E56F1085E4729A7CB04293F56970BCE +:10429000FC4E769B09BF138A16933ECA1C42AF732D +:1042A000F1FF204F267DE56B467F93528CFAA1F2F9 +:1042B000075F27FB9B1CE107BE4EEA8DD745E885CB +:1042C000A38648BDCFCDDCE2DC27EEB94F94FB746A +:1042D00086A4730E3FCC8F051D996E81D03A847BE6 +:1042E000EE25B807EEA7FCB52C40E9F52C44FBD62B +:1042F0000D5CC021FF1DC6289EF160ECD4792B789F +:104300007F13864FC8C5F7B07B7DD70CE947F7FA16 +:10431000FEE00CBBD77760A28BF48603F61CD26359 +:10432000B00EAC6176B45F72B98F5086837C5F400B +:10433000FA06DF17723993FF82EF0BC85F57B0861A +:10434000A1DD249731DE44B5BFDE399E5986F72DB5 +:1043500077AF2F796520EC2B6F270E9E08BBF3DB20 +:1043600089974DC47CDF4EEC6F1269948DD2E29731 +:10437000737BD3B3141FF68C378959922FC6AFC203 +:1043800067241E157EFF097CAEEC0D9FCDC001ECAD +:104390007AF6F7E3D3B2E1FF12EBBFEEE5E2FE807F +:1043A000FF2440435CB25DE025D2BEF379231B08B5 +:1043B000FCB22D09F4FD36C94357368CA1FA5735A6 +:1043C0008CA6F95D11A3DF35848F73BA2C94CF3599 +:1043D00007F6F9E626BA7F7BE605B307FA77ADD98B +:1043E000B5DE83B5FEB6B82FC7BE3A98057F1BDB96 +:1043F000D27BDC6EAD5DE1CD4FF8F4667B9BC5FEF4 +:1044000027EE11ABFD776094887755F759FBDA8F6B +:1044100047C508B932304AC8414527DE8EF219BC7B +:104420009F515C6E643C1843FAF78824EF63C0A781 +:104430003A4723BE09FBD455A1C204E427E33CC993 +:10444000F36FC9FB696F0DAD4FC9E6F83E68D39FA6 +:10445000413B66FECA8C75DD94A7D13DF7AEC339EA +:1044600029C0F756B5EE4A5849F87B034A3FEE1E7D +:104470002FC54C7EF155F08FA6E0DC64277BD1552B +:104480002C9FFCA613E5F8E5BFACA27710D4BD8F36 +:10449000A83493F1FD1C578CE13D98D88224433E0B +:1044A000CE33C0503F6174B6A13CD13BD4509E3C4A +:1044B000B9CC90EFE71B63A8DF7FF678E3BB6EFA19 +:1044C0007586FA1935371AF24A7E65884F2CB37E05 +:1044D000AEA1FDA0860586FA6EFF52E3FB367E6F25 +:1044E0005B412AE49EF8CB59B7CA50FEE37871AF1E +:1044F00061B26311BD5791D772BB717C49A78C041F +:104500004127E612F2D5CFFF03DF94A719E5ED04AA +:10451000A7F1BCCDF5410DFB7B46BDC5F0FDD3FF3A +:10452000219D23F1D2C5B7A610EA431FE2F9ABF4EF +:10453000A10FC2AE3131C5EA0930614F0F9F17ECB0 +:10454000E9E178803D3D3C0F7BBAF15D2823DD61D8 +:104550004F0F2F1F7ED848F7916D46BA5F76C4483B +:1045600077C58F91F4B9BCDDC80F91F4B9E244046A +:104570007F487ACCE6FFFD5DDC93267A4D7268ECCD +:1045800071F73F4F9FD4A19C3E853DF4F9EF0C3D60 +:104590007D683FDC4F3F9F6503BD3AC57B7D2BA502 +:1045A000FC54F184FCBC2BEED3DD6E26FFFE515390 +:1045B0000BBD9774C0A9BBD1FE96A27A0DFE8334C1 +:1045C000E6DBB988C337FFDFA3C89F307F90B8D739 +:1045D000C98ADA29CE5EC9B9F919228E65C850791F +:1045E000BEF0887896A2A1422F8CF33829EEB5B29E +:1045F00048DC23E0C782ACF9C5E09F77A2F16E6189 +:10460000D74661BF6FB78AFBA57ECE47F08B414F7F +:10461000841E9729F5A8A6DFD9ED807FF02666D8FD +:10462000178704EC86B8CBC2ED4E43BE389866A817 +:104630003F6CAFCB505E1A2A30940F3FEC31E44709 +:10464000B68D36D4BFEC88D790BFBC7DB2A1FE1525 +:10465000277C867C06EB7C0CF81DA489F368F5505A +:1046600011C7C3D710F993E6DF9328EE0FCA73AAD8 +:10467000D283553CAE2EF92E529F1E64D329BEB76D +:10468000299D79E81E805D9E4F9851CFD6653CAD3F +:10469000D24799DF184FABE268BBF571A97F2B7D3C +:1046A000382C8ED61B1E473B5FDEF38DDCF7EA25E8 +:1046B000DD23E11F6413F36DFA9E8DEE2D28B822E1 +:1046C000E1F99B8CEFDC6AEFFDFEC89D4385BFFDE1 +:1046D0009739BEEF825F9F84F8C8E96D3C4FBB9F5E +:1046E000F357D30F6C9EBB5CDF3EDEFC61623EF392 +:1046F0004CA65B2A8A286E69F6CFC2C6FFA11C773A +:104700007591D6EBFCE62788B822966073817FFB13 +:104710001E4FE033CDC69AE99E8B8C3BBF797DF06E +:104720000198C8E7D95AACE2FDB28015FC30653C6F +:10473000D79F4A61B7FAFA2107D7339E6CB0901D14 +:10474000E2E1A137CCF0E7F6DC2318C4CF17E00F85 +:10475000E82A3897D88B44DCEC9EA162FD979BBF7A +:10476000EA8EFF267B3A63527E8B734B2FFC467C8E +:10477000A8E6F1AF8E038FC4933A1732B9EFE44A3B +:10478000B814FEBACFF1127F2A1EDFB5D2EA7BDA67 +:104790004171FD9311CFA4E837B048F0E589A182BB +:1047A000DEA80779D457BD72735102ECB55DCC9584 +:1047B000E0FC067BE4BF0A2F0AFF7DDDEFE94B3EFC +:1047C0005C2417FAB8EFD3177FD2DF3F70EF274C86 +:1047D0003E88F812498F40AE89FCB9F7C419D771E9 +:1047E000FF4281DF7D6ABFF0F3F3A4514E30D897CA +:1047F0009BD69AA59C10FB2AF40D7C5FB8D64AFA8A +:10480000066B10F1C835521633E64B1D3302FE58C5 +:104810002BBD67759597913EB2C0610BB4F2FA95C6 +:10482000FEC87DD54BEDC95FE3C2BB259EBB617F52 +:10483000AF5A67ACB7D821DEF55A18712E5D2CCF70 +:10484000A58B23CEA5D185725FF6300FE94DD2FF3F +:10485000ACE0ECE6AB400EC505E39C6A16F6128AA6 +:1048600057EAB6E3C3BF10F68E26C7674C01F6EDD4 +:10487000664BAF7164DDF8ECC34F7E1A7E7217D6BB +:104880007F17DDFFE9DA152DFC68CA7F21EB9FF663 +:104890009FA772D4476F674ADB4AE047EAF677443E +:1048A000F84DBA1CA6F8D1E86F87787F41C5012C76 +:1048B000FD6BA0C419E6E7D4DB4D86B88BC8545F06 +:1048C000B39BE2025A2D7A59219FC7298BC78EF7D5 +:1048D00022EF751C48C57DED29D25E13096FB71E06 +:1048E0003A56137E42BFD043BB266BA48772B9C829 +:1048F000B08E943FBB828552902AFF81BE6E34E118 +:1049000059F90F2A43A309CE194D8BAD78B2AFFDEB +:10491000B13BCA635C3D7E85F64C118FD2977F61B7 +:10492000DA050FF537FDC218EAA7A2D02DEE7135D2 +:104930003FB0127C34743BB3629EED11F1D82ADD96 +:104940005F28ECDF470B95DC96712E6B34A1676B0B +:104950004CC5BD90DC56F9F32D325F2EF2ABD78AF1 +:104960007CBB7CC7689BB437609E48311F9C8B77AB +:10497000487B04E68114F3C077C829E421A7908717 +:104980009C421E720A29E414BE2F60BEAC52B3F0E2 +:10499000834C0C5B37F0834C0CD383E00709CFC307 +:1049A0000F125E1F7E90F072F841C2CBE10709CF73 +:1049B000C30F125E1F7E90F03C1B7D6D4F1E72CDAB +:1049C0005B61C84FE3FAF8C4B0750B3F4878FFF05D +:1049D0008318FAD3571ADADFC41A0CEDE10709AFCE +:1049E0007F4B8366F093DC22EFA5576D4A22FE9839 +:1049F000E3F6FDB090D3F70FB15FDF66C539CDBCEC +:104A00006F099D9FEA623C82CE2D9305DD4D4CD00F +:104A1000B9730ED1F90E9BC8978BB8D8DEFC0D1375 +:104A20007385BF0129FC0D48E16F400A7F03DEC397 +:104A300086BF0129FC0DF80E7F0352F81B90C2DFE0 +:104A40008014FE06A4F0372085BF01EDE06F400A18 +:104A50007F03BEC3DF8014FE067C3F0ABF476E0F94 +:104A60005CD0DB730DE73BCE8786F39DD39087DE6A +:104A70001E5E1F7A7B7839F4F6F072E8EDE179E892 +:104A8000EDE1F5A1B787E7DB86BA685D427F0F6F7E +:104A900007FD3D3C5FDCE27F0336A61B369F3D846D +:104AA000B43D4E7B52E3A2E0BDE78ECD80DFA83D52 +:104AB0005ACB4AE44BDEAA9D9C3191EB67BA8C2F0E +:104AC0002B619DF4BEB32EDFADD1438CE2618BFF31 +:104AD0009226E482BA37843F4EF7D25D8CCE011520 +:104AE000723F55ED3DCC6926B925EBF7E47BAF1756 +:104AF00039BEAA47F2320C0E7E402C451C44E91DFB +:104B00008E32C4716F3369220EF22E11871AC95783 +:104B1000E6222197B699761E88415C4BA546EFC5E3 +:104B2000E75BD861BCE35DDC525F067DE15461A2C6 +:104B30009C57FD18C4C528B8951D90CB09BA5735A8 +:104B4000B693D9AA8BF09E18B32D847CB7093D018A +:104B5000ED707E2CF46BDEA7C3F8FBCF85627FD3AC +:104B6000FD2BC754F3EF853BEAC7E0BED69418D1BE +:104B7000EE274FC5131EA7366B4FE35EDCD81DCC66 +:104B80008BFB975F4B795AB8C369ABA6719D74CF05 +:104B90004BF55BB9398BEEA555B2F6896964CBD775 +:104BA000E81D7385373EBF43981F17F187ADA48F6B +:104BB0008AFB2231F2BE88BA27E2B6F8424347F6B2 +:104BC000DC17B972446239E2B5D83EF1EEDE0D234E +:104BD0002AD7F6E3FDEB01F1EEDE957FAA7F83F2A3 +:104BE0005BC4BB7BC406A3681CDAD706FB357AEF2F +:104BF00061AABFD594E2C2FDD135D654D4DFC13C01 +:104C0000507F0633710F52C157C4DA4C78779C6FCE +:104C1000310793C3F8884B80E9A07BA9C74AEF41CD +:104C200054589C56C88DC87DFCE278BA083D2122B4 +:104C30001EA2E98E2359E66CD87B4C9E10E4D6EE7A +:104C400058D21794BE5329E3A0CE37BF41EF59572E +:104C5000EE14FA81CEE500E49F8A8FA8CB0964990F +:104C6000A02F0C682D49328BFDBF08F791FC2FCD8A +:104C70001CEDC23DC637285EBF72EDC804715F47A8 +:104C8000F81FAA259EAA65FC0B2B72A642EF54EFD3 +:104C900098969BC726D07DB716A1CF29FB4BE5AFD1 +:104CA00086BF093A573E21DF03595749F78022E36F +:104CB00050947EA8DE3B59D26CA5F89625117AE077 +:104CC00032A9072E8BD003AF2B8AD003D5FB74B249 +:104CD0004EE5AF0ECE203DA55EBCC7376F8DD05BD5 +:104CE000D84EF18EFDBC35134C78B762DE6EAF47FF +:104CF000EB853FDE93FACB140C9A8C389F0194CE4F +:104D0000BC9046E9AC0B052407701703F46F7F8550 +:104D1000913EFDBED4576620CE0FF7E3FC51329E84 +:104D20008F91BE54CA9CE5901B43BDDA4198AFA752 +:104D300058F5B588239CD2CAE83ECC0DD06B78C11B +:104D40006CE839C3C1E7EE72BA173059A3FB1537C7 +:104D50008C5829F99AF339039FFB25DFFA28DFBD28 +:104D60001F48FED6FD1D167A97D5AFD9F02E9B2E83 +:104D7000CFB38A7F23F97CBEFCBD09E61076A66E10 +:104D80003B1480A5C755AE9A097D713E6C7703240C +:104D900021398AE28A447973D155339B71B8F91F5E +:104DA000DA27E6A9DF61E07A16E4E9CDB796DA16EC +:104DB00084C9958A92F1CF14F7EBA1FB82EE7B6355 +:104DC00045FDA1FFAFBA37AFFF37DD5FACE278C674 +:104DD000FA989FD07E1B5EC6DD52C4BC1347E33DEC +:104DE00066354F1642BCDA5C99FF75D1E2FF585721 +:104DF00044F8A17C60C794997E5A2F425EDD047905 +:104E000065869CD29F2CC2FD0E7BFB24D023B6A8C6 +:104E100053DE8797FB51843DE2D745820E91768918 +:104E2000AA2221C799C5957513DD5375915D4FC1B0 +:104E3000FFA9D5786F50A5BF54FB48E3BF26DEFE1F +:104E4000CB54FDE7901F8F98C4FDED01E61626EDCB +:104E500043E27732E4FA61F23D831EFA73A901FA64 +:104E6000DFAB39C3E9AFAFD3C4BDE93EEC38ACA08A +:104E7000F3B1ADB0E3358ADFE7782A5FF0D153B7FD +:104E8000DB48FF9E676B7B03EF34293C7EDCF0231D +:104E9000ABF89D97501EDE9F9A5B1F4DEFBD569459 +:104EA000F8DA4097D8220FD1E319C494F2FAED4E04 +:104EB000DFFB984FDDFAFD4FE2FEF88A7D6EBAD730 +:104EC00058B9B7F46EBC6B5151A21F4179A5C369A3 +:104ED000C3FEBDBC3991F6B3F9FDE5FD42D6497E6E +:104EE0002A85FFCE2261C7DA5622FA3F27CF21104A +:104EF0009415867A32AE38629D28FB60A49D21F21B +:104F00003D81BED68FB227C07E600BB32F2AFB84B3 +:104F1000B5E0D339D83FE7D98CF7E154EA2E96E7CC +:104F20005C790E5CD8BD7F154DEA0F7D798346BF55 +:104F30005B53ED70CDBA9CE7AB0F5B1129C8A6247B +:104F4000B9C43B12F78A772416F0F50A79334FC6B5 +:104F50000D556F1A4DEBAD3AC0D3E4BED7E54D1BEE +:104F60000E66BE02FE0979E99E78B5D36B4B0A5BEB +:104F7000F7552D9AE19EB9CA27160B7BDC3C3C61A4 +:104F80005E0679E1B6E12D97795CAD401C9ABBD8FD +:104F900065F0BBF27A14C730259BBD29DEF1E170C4 +:104FA000BBC5786561FD2F6831DE97E7F5C5BB1499 +:104FB000C571D45FA593CF1BF60FA793E0E47820CB +:104FC0003C753EC0FB73D138448FAA50C08AF3F6BB +:104FD0003CC44FF0FC5C67C08A7116348B772BF4AD +:104FE000F5621C7D5DA2AD18FA92C569CB04FEE4A2 +:104FF000BBF61C3E9283D51C2FB8FFA3EE0146E200 +:10500000A752C25BDD9268D4C35A3658418F397DAE +:10501000DC9FBF41D27D41F338BAFF5C6DF1527C19 +:10502000BD2EF1FBC795D1F7C13F3067E3A35637DB +:10503000CF5F592CF8F70689D729D9A13C7A9F660A +:1050400065B40770CE71B6D0FCBAF1FB30C7878665 +:1050500077507C845FCE177EC491556F34D2B307EE +:105060001E81DFEA8D95B4DE1659749B331C8E4D7C +:10507000FBF370AF670E5FDF7877873975BA6FF330 +:10508000D9C3B3B2689E1C4EE035CEE39A84F7666E +:10509000389F101F2B7E51F783D5780B8BC53DC1F0 +:1050A00085C5BDDBD77BD6A597F49B264E5FD8BDC3 +:1050B000FB5A97365C34E2E3DAAAC53B6091EB54C5 +:1050C000AD4FB52ED53A55EBF749AB2F94A6F5C8A1 +:1050D00019BEDFD6FFAC173C3D23E19D2BE9CAF199 +:1050E0007A28FC5ED1FA62218FE6651BD73BFA4332 +:1050F000BFB7ABF2F1A13CDC0354F5D5B8F3E4EF54 +:105100007481EFC16FB74BBAA3FE2AAA6FBC1F51BF +:10511000D52D2F76AC4D85BCD8A991BEBBEA818335 +:1051200099FF063DF679A1C79EAADDBA3C1D76031C +:105130004B202BFC7DA6EA90900F0BB9FE0379B1B2 +:1051400048EED3D7E4E9F7168F0CABF7D0F3F9BAF2 +:10515000902F21C897DF3FFFEA87635C3DFBA78262 +:105160007FC1BA5F5B2B1DE1F8127C7E5F4117DDCA +:10517000FBAA72D85C88B3AD6AAE2479CBD2F87939 +:10518000420B8B938AE083CA668DDECDAA6A18151E +:1051900030FF2FCAE5AAF515F4368FA2937A7F4324 +:1051A000EDA70AFE1D12FEB9928F5F94EB6F6E8D14 +:1051B000DBB688D6BDDB5605FE97E573AA8DDFBB4F +:1051C000E9D4ED672EBA3B4DDE63A173C97AABB06B +:1051D000EFED88237DF5D4AA97DF9DC9EB7DF148DB +:1051E0006B16F41305C76269C75B28ED718BA4DEEB +:1051F000CAE9F47A71989C5DFC94A053D50BBFFA70 +:1052000004EF43CDCB96F2EC0171BF7C417027D106 +:105210006DCEBA0D5637AFF76EB1DB20A7ABEA4BB8 +:105220009DB04FCF5DD76A851C78B758E02D92DFCF +:10523000E7C9B8548557EC3B5A98FF42D587FCDB49 +:10524000C9C7B97565743CE232D438FF25F9B8AAEC +:105250003E3109E355D557FE10E71E25EF23D7DD74 +:10526000B168B11E16F0FEB02E8F8DF3D03DDB7904 +:10527000F2F7A522EB9F9574FBB155BC2398111B47 +:105280007C96E20A56C478201F7273DB031817FC61 +:105290000CB86D26F1EE606E6DFB978083ABC51484 +:1052A0009F8214EF1D414D4EE5F9A74DE23E10627D +:1052B0004B90A694087E80690AE52CA59DDE3F0BE5 +:1052C0008BCF34F0AB8D6D5987F7576C298C7EEFFF +:1052D00045F1A7EA47F1A7E2DFBEE6E728B9B4F94E +:1052E0001D734B3B4481270BF728E63F3898DEE7D8 +:1052F000FFB679DAE43B78DDF38D12BF5B70D17CC9 +:1053000073C5B9A5EFF96E2C4FED65BE91F354EB63 +:1053100044C55E77FB155A845FE198C6F72FDEEE31 +:10532000D8CA688AFB52F35276EF4B8D97F79424D4 +:10533000493B427B1CF4C879F2F7205848E4F1BDA0 +:1053400022ECBBDAF7D5BB614A3E1FAF97FB226B5D +:105350007F00EB9935E4D03B19475B8EC5E1FD8EAC +:1053600063E3047CAADDAD5671EF95C5D95C783F47 +:10537000919FAFE8771F1636F7A773E4CD0D392458 +:10538000176EF6270ABB83D4EF174939187B6BE5F4 +:10539000DD97A1FE26B753E3E32C74783EDB44EDA2 +:1053A0000B3DD007633756D8B249EF15E700E50744 +:1053B000BA55633EBACF043989F565DA9F8B7D67AC +:1053C000F126710E986262EBE02F1CD4E49B940EE0 +:1053D00039F1987837926D36BEAB7420CF777D095E +:1053E000F016F11ED9ADD6A0B73FE438D7376067C5 +:1053F0005AE8F091DEFE969493473776D0FBE40AA4 +:10540000AF17DD53B1897BA99D7126B2BF5DEA7DDF +:10541000956AE94F527CA3FC518FE3FF2E079E4C07 +:10542000B4AF959BE7D1BB3E776F9C4069F586F2A0 +:1054300047FCC5B80FEB4B1D43705BC93E565D374B +:1054400041DC1F7D3A2A11E79B2CAB3F2B5C2FAD33 +:105450006EBD87EEA99C688DA67B2A139D1513133C +:1054600053E8BD5DBAF7A5EA7D5FAECBA575130C19 +:10547000F74C16F23E1107FBE7602CC595AAFB23FB +:1054800077C6E8DF2DE927EE915CEE12F747D2A947 +:10549000BEAB577BB84A3F6B14F711C2EEC54C9DAB +:1054A000C3DBD7D6BD148F7E963DFCFE288E19D85F +:1054B0009FEE02DDBAEFC56C12F7629A705E821E33 +:1054C00099E49B3907F8FFA599F0DFD77835F851B3 +:1054D00092B073C4CD8104D25BF510B3C19FAC3BD5 +:1054E00019E9C527CCAC017A80D25FD4F747245E96 +:1054F0004E24B464813F966C7B340BFBCBC938914E +:105500009FB76DD65B9057FA9628A19F5B18E9C3A9 +:10551000557EA15FB39A24F52E66F47CF8634B6246 +:10552000C53B3CF2FE8C824BBDB77AD222DE8BC1EA +:10553000BD18F0FBC796D042D0F763AEBFE21CFBAC +:105540007D29C73E6E31D3EF8EF8F942811EF2718C +:10555000CB4B71B89FABF4B572F3EFBD788F66D5C6 +:105560006E714F15EF9AD39B95D20EB25CDA41560D +:10557000BD629D84DF1DE1FA177DA9B5846CBDD1A4 +:105580006FA9D4AFBAF3BB76D2B9AD7687D01F6A14 +:10559000831DA43F287D44DD8B5BB6A383F409D52E +:1055A0006EF92E8197BA5DE27B25E2D6E5EF856A3A +:1055B000B9384F6B94FFA468C1AC3596F07C25E5F3 +:1055C0003F2952F6914ED207EF2BF80D9DC3EB9A6F +:1055D00065BF3C6F0D1BEF0D30693FF13DC781F694 +:1055E00062DF57E575BB12A97DA82E661DF679EF1F +:1055F00072870569539D83F6FDCDF5A602CB0800A1 +:1056000017E3811EB74FC66FF55BF61FD1B01FA41D +:10561000B3CE8378F7F580533F027E55BF67A9EE7E +:10562000BD9C7BEDF3E1E8FFAA41EDE7F1C6837590 +:105630004DDD2CF827DA4BE43C8ADA8783AFFB1D7B +:1056400010F2F9092B5B47EF075B7C0C76FB90F4BB +:105650002BFAFF6212BF2FA1859E09D7AF52860990 +:105660003DDC1725FC8B5EB77E12707C47B3169726 +:10567000E24CED32E7A17FF53B2A4A4F1D2FE5733F +:10568000A63C5FD906A439C0C79AD74BF710EF2ABA +:105690003A50857DF9FE4E3BFDBEAA8AC31BDF1939 +:1056A000437A6BE680C9B49FA97B29078A4C7EBCEC +:1056B0007B7E3FB38BB8007B845E6B8AA678646D7B +:1056C000DF2FFE02799E61FEF2207EA724E3DF3405 +:1056D0007AFF727ED7674FE03766E6B14029BD8317 +:1056E00097A89B86410E774DEED039C9EE7706ED2F +:1056F0001EB14FB070F8F77DEF2FF149A61EB8CE5E +:10570000757E46EF0A9EEBB493BD76FC3EF9DE5EF5 +:10571000043CE7D25C1417CDEB85F0BECA3987890B +:10572000DE191BBFEF20BD9B375EBDAB6737BEAB3D +:10573000C7DA3213614F261B2A570A529B04DDAE8B +:105740004A309E13F38689F356DE30213F14FEBAA9 +:10575000EC67DFD6B59E75B842F9EFD5EF4DD5446D +:10576000D1EF4D75EDCBF9C6F713DE87FEC0F5829C +:10577000F5D9DEE261FD7AF6CF19122F6A1F36CB1A +:10578000FE6748FCCC7098043E227E6F43F187A2EE +:10579000BF8257D157D18DDDDEF606EE05717A1541 +:1057A0003FC8884E97119DFEF2CE5A5CF31F60F6FB +:1057B00076E8EEFF8B740A450F869EF0B0F8FDADDB +:1057C000C8B84656C0689DCF37C7901D5097EF8226 +:1057D000F3F5FD06D6B75AD78326B717637F3CCAC1 +:1057E0008FDE80ABDD14A4EFDF1D26E20907B2B621 +:1057F00074197F33127A59937CFFB8FB770C973872 +:10580000E8BD917301F5FE71E0B1457CDC8D338A12 +:10581000C8AE7F8EC9F55ED3FD4EB678FFB8FB9D4E +:105820006CB39FEC247362C8CED3FD4E769E78EFA6 +:10583000FA558DE5E31D5A7F859DE2E323DFC9E636 +:10584000FBCCB3F0673C5E13437E28F53EF278A7AD +:105850005E0F3A46BE8FFC88E69BB310FD153BA851 +:10586000BFF639312F6C13680EC18E73B4218EDEF2 +:1058700085567CA9ECD783FC1D8F014FEA5EE71F9C +:10588000247F29BCAB7B6D0AFF8ACFFC5646F73FCD +:105890004107BC2BABDE67D7EE907243DD277CDD82 +:1058A000E342FA40A2BE0E7037ADE47283ECE2ED43 +:1058B000B761BE4F7C2FCE0BB88E9A8CBFDFABD2B8 +:1058C0008786990CBF133A5FEE57F355DC7F83311F +:1058D000EE3FF21DCDE404DFC3C378FB33DAFBA354 +:1058E000F0F19DFF36F71A47F2A45CFF2362F5271B +:1058F000505FDD7F50FAE13BA59F67D2EF8D7C754D +:10590000907E5771AED31740BDE85CE10FF8437A43 +:105910003BDDD7F8C39CBF66923DF90EF1FEE7A5CB +:10592000C279F17D5AC10FAB178A78C30C564FFC70 +:105930009BD6734F331A70FCFF769FB6E7BEEBE43D +:10594000E1C729EEC247BF5711498FB151075E72B7 +:10595000F193CA6F877D318BEE93261C58EDE6F9E3 +:10596000A32F9E15F98C03E7DD9C36ED2F9E13F9CE +:10597000C203E7711FF5D3173B45FE0A46FEACE3B1 +:105980002F7E390BF74FFBBBF53F825E332FD4BF21 +:1059900081EDF5C335372E74D37DCA8ACC02719F51 +:1059A000F26394CF485DB03641EBB94F69F2F8FE2F +:1059B00008BE3DF7A5E06F3787157CF2CFA6EA3E1B +:1059C000A992B77DC945B5EEFE55F761D53A66DBBC +:1059D0003CEBAC6042FF3F7D4F9579F8BCFE1F9BCE +:1059E0004A017000800000001F8B080000000000CA +:1059F000000BB57C0B7854D5B5F03E73E6994C920C +:105A000049C80B02E104420C18D299BCC05BEA1DE4 +:105A10002089015A1B6CB52018068D90D76442A8C6 +:105A20002DB5D80C0611A8DE0B5754B068274000DE +:105A300035E8A0012718EA00922252BF98FB37F2FE +:105A4000FD5FE10B3E90979310B557EF55B96BADE5 +:105A5000BD4FE64122DAFE7FF8DAEDDAEFBDD77B03 +:105A6000AD7D86B1B196F3D18CFEAEC98C1D3FFCE5 +:105A70009EA249646C4681D16A90A034772BC602FD +:105A80000EBB01DE7595F935B1BC9F36B45FA2D768 +:105A900066C17E7566EA973908FD72B1DF9F476B74 +:105AA000B1BE416F356430F6B48EB94D098CC5680E +:105AB0008EC8B84ECC2063CDD07FAC8131631E63DD +:105AC000297AC6B01DFA312394BB06F97AE3121A7B +:105AD000563098675C85D9DA9C81BBF53056C8583A +:105AE000DA28FF68DC5FDA4A3DD5C7687A94063366 +:105AF000638126FFDC0F33192B8E8ACD653F8052E0 +:105B0000CFB2711F4C13656D85F54AE4AFBAD20070 +:105B10006EEC906CB0342B36946F671319ABD702D0 +:105B20009088FF33795A711D6D77F51EE8D7939CE5 +:105B300066DD08E0D8D4832C331FC6BBCA72D804F4 +:105B4000C68E5A1C39D62468679B241C1F9DC3C768 +:105B5000FFAC2C7A870CE3FB0FDF54E880BA3B0CD8 +:105B6000CA0166652CDF3B7A81F61680E39442C950 +:105B700002B075EC02ED688053940312B41BDDA3F0 +:105B80001714DF82E7335A3ECC66EC174C62718003 +:105B9000970CAD63BA15CEEB2CFB44CF34D83EA0A6 +:105BA0002F9F0AF76A854960FDA4A3704FB0CF818B +:105BB00039319E1D703E96A314627BBA6E20D602C8 +:105BC000F7D1FF95B6CC63A671B13F87FA6BF8F7B2 +:105BD000AF8C3DD72953BD0AABE5375689EED79533 +:105BE000697E0CEFAF3ED568A4B2F36A29C379B4DD +:105BF000E59977C03C763D5B529E73FDF801AB861C +:105C0000F695B10E103A86C8CBCE14F8BF28A6C2BE +:105C10006E369DB1965F41C5BFF0763809D34FD23D +:105C200008F896ADC5DAB0FE76EC1F6C6776230BEC +:105C30008E775AA76E5D9B29D6433C2F639E497091 +:105C40008434D62031B8BF54E627FCBC644BA07323 +:105C5000D11FE0E9D94453CB46A45719E8328F4A03 +:105C60006681322D1AD683F6B4374C1EA4AB5D265E +:105C70004EB7991A5EEED2F0FEFA28E6463A1D07B4 +:105C80003083F26D9BE377B6249AC74FF3C8FB6D60 +:105C9000488FA39997D64F616EDA8FDA6F2CEB3667 +:105CA00021CCB40359844F5933EC7D26D9666E4616 +:105CB0003A0B34D9D947DA607D203A765528FEEA86 +:105CC00071BC3974DC2C1AA78E77AED2B08F46E146 +:105CD000E1FD443FCE4C8DDD9383E3D89B521ED62D +:105CE00077EBCB6382E37A9B8CEC23B8D7FFD3C4EA +:105CF000A83CDD64A1F5FF6F532A957F6B52A8FE87 +:105D00006C5336957D4D56AA7FBF693A95772D8A9B +:105D10002940FA77F966B28F8C42CEC0FF9C5E9D17 +:105D2000A32F04EE9D393C1DBD26E8A83763F8F685 +:105D30006E6C077CF6DECAF1D97F3FF3ECC820BA5F +:105D40005C6B49B81EFF30C284E7EB8F610BBC70FF +:105D50004F6F1748347FFF680EEFB7EA683EBB8687 +:105D60006DC5F16F17E8F9FC133455D86E4FE0F3A9 +:105D7000F666010CFB59307DE6CBC897F664A8CFD8 +:105D80000BC2BD5378BB7D0CAF57F7ABB6FFCE66E9 +:105D9000E17428F0DEAF83F57388DE697EB5FFD746 +:105DA000459C0F23FB7B3235659E61EE23C1C6FB0C +:105DB000135FC07DB8910F3242F8A25E21BE50E958 +:105DC00050A5BF976CFC9E330D82CE4127D0FDA11C +:105DD0006E40F99A027C20D1BDD8199C679724F8AF +:105DE00025921FA04439AEF283CA072ABDA7019F9E +:105DF0004909C173FC28825ED5F2B495E3A53B390D +:105E0000E601C26BA7CE02A210FA03221310BEB3A2 +:105E1000C00EE34A1E35370C27BFE2FED97B50E5A2 +:105E2000C108F770DDF9F5BCFCBEE727F986721BE7 +:105E3000E9761879F5B53581F6A3D26D92CDFE5F7E +:105E4000483FFD92492BC54169E2741379FEB70BB7 +:105E5000F83954FA79C9C6B8BEC4734EBC5EDEA91F +:105E6000E7193AE77246722F338AD747E2573D5710 +:105E700088DC8BB11506EF93316E0F8C057B606368 +:105E800046907E03495F2E43FDB5CDAAD0FEFEA00D +:105E90009109FFAA3E19AA97E425F373C2F40CB343 +:105EA000001E070E1B88BFFD1A56F50A8C6B255580 +:105EB000113CF76D362E0F06174CD2AC827D05FED5 +:105EC0006E76A3DE0A8C19382BC1F8C0563040C854 +:105ED0007EB0FF584A66EC7ED029A897AE809C63BE +:105EE000598CC9DB3E3F2BC1BE976D9319DA350142 +:105EF00010DB328C733D19E331F2718CC1B83A3149 +:105F0000AE79EBA777217D9D07FA44FBE62353FD8D +:105F1000040676CFEC6D3ABAC765317A0FD61FDB2F +:105F2000FAC48945009F6F9714B4374A6533B5D7D3 +:105F30003C2F7B709D3A73E94509EC9C407BCB5329 +:105F40005150EFDCAB63261857DA2E59FD30FF7243 +:105F50006F0CDE0C5BB645F77E5F76506EDE26F486 +:105F600058D52EC90314C3AAB687B7D7EC0A87EB56 +:105F7000983608C3FCB36C318964FF4D6636B4FFB4 +:105F8000D89604545643723B92AE506D237EEC8DEE +:105F90005C1E33F659F21D4097F2E1CFD3DF377321 +:105FA00078BE80CF01FCC9E7FCFED57BAB1732FF82 +:105FB00093D1ACC00BE7AC3F6CB2B8E160F51D32D9 +:105FC0009D23E08DA37B7645F5DD4E7C7A48B6A017 +:105FD0001DB6C127BBB1DDD969DAA98173D61F907F +:105FE00018DA9F4E9FC1C3EFE9EA326C5FEE335976 +:105FF000146C3F6460328C0F00DE4C88C7717D8466 +:106000007FC42BDAA7F0F763A928887F19F19518C8 +:10601000C457F356BE9FF37B397E4AE5D55AC25723 +:106020008BC45242F0FC67CD8B43F8C27EB3B7FD00 +:10603000B50BF1BC0CF6675010EF32E1F93CE0070C +:10604000E7D51FFE28BDCF1CC4B70CF8FEAD3A1E25 +:10605000FA2FBF01BEAB987B1DDA73DF17CF69C87B +:10606000FF4964F79EFF03DABD31608F23E908FB27 +:1060700038A9B6F778222C589170D9B902EA27A529 +:10608000BEC232C14E90E21D8F225F9F9DF39747A3 +:10609000101D3D735FB4215D34EBFA5A9F860A7779 +:1060A0007CB41579B03F63FEF6D7609DE2842FD3B0 +:1060B000F723BFFCC96041727A42F023FE1901FF49 +:1060C0004EC6EF1BF0780ECFEFEC34F80D708FACAE +:1060D000BDC43E640F4C407DECD5A39C2AD10F5427 +:1060E000AC407B1CE6C375242023E4EBDACE3F9F53 +:1060F00096609CA424B2C5081BCD7E19E769D35DC8 +:10610000193A37CC2359FE42FDDA6C13E8FC1353DD +:106110007EA4A0FC695EC81C5113BF4DCE3392F320 +:10612000CF0A7F6544FB6F0479AFDA7DCC3D361E24 +:10613000F90BEF82F30F973BCBA733F127F842C05F +:10614000556BDCB146E8BCFC666B2A9EFF63A4B3CA +:1061500058A4BF53DA51B0AFBA5689F0568FF483C2 +:10616000FE15EA37A8EFF70A39F27C77F1A8442C3C +:10617000252B702AABEE94AD7E68AFF6717ABA8E9D +:106180006E84FCA869E3F2E33A3A6A0338C44EAB82 +:1061900047BA5261C0F7C9A0FC987A0DF6FBF234F9 +:1061A00026F4955BD05B4E5C1FD0CB2053E22C399C +:1061B000217A4BE2F6962A576EDA0AA23E64DDC9CE +:1061C0001E23D386AC7BF35E4B183CD59B1AD6FFBF +:1061D000073E25ACDDE6CF0E6BCF3F610D830BBBD9 +:1061E000A787F59F76DA1E06DFD25716D6FF8717E8 +:1061F000CAC3E0C11C38CF3076C7901E4A95C2FA98 +:10620000CF514C61F3CFCB8E0F8307CDE27E841D3F +:10621000A8DAA75FD8B81D1459AAF7FB136BF83A90 +:10622000AA5FFCD3E9E1EBCDB787AFF75DF1B21B15 +:10623000EC7E2DD8F57B413F62F902D8FF5AB0EBD6 +:10624000DBC0FE47F825B0FFB1F482FD8FF5AF80CB +:10625000FD8F703BD8FF081F047F05615F531995C0 +:10626000879ACAA9FE46F7D725D63D21D63D29D61D +:10627000FD47EF492D9D6593345F009FCE4CB8A834 +:1062800047396C6FEC2BC538C0C05B32DB810CE248 +:10629000F09C684A447D348AA1DDC2CA07DEC63854 +:1062A00045FD8189968D0AEAA1FF7C07DB03EDB2EB +:1062B00082F2FCA8EF83589CE7CA17C087F938EE32 +:1062C0008358F48FEBBE64046F847605E039FB419C +:1062D00030903D03720DFB67AAB047CFA02C6FDB57 +:1062E000AF477CD4EEDD4FED6F7975E1ED7B5BC29E +:1062F000DA2DD81FCA5AAD87FCFB4B3E753E3FF5E1 +:10630000AFCB94EC68175FDAFB9FC9CBB05FDBBB08 +:10631000C9F77DCB7D7F72F0C51C94EB4ED0C37E58 +:1063200073701E67874EC07CDF7599FB4B1350114D +:10633000B4496C121457D826B60AE45DADAFB50E59 +:10634000E5506DF6221DCB207924E20D206DD15E43 +:1063500042E71EEEEF8AF7D3D8FB60DE37BCC76F8B +:10636000B723FE3A8FC5E2BAFDED72983F73771EF0 +:10637000B75BEFCED313DEAEB41F8B55A07D83F792 +:1063800018BF6FAD9FCE7D54C0FD50D23DFB643A27 +:1063900077F5171ABA7F75BEFBF3649A678E6F5252 +:1063A0000C9EABC7CBD773E529B4CE9CCCA595B8D2 +:1063B000FF93A90B0B65B2F34030A35C9D32AF1580 +:1063C000E303B55ED93E9CBFB546CCDBA5E374F8CC +:1063D00056E6AB5D63803E4E968DB291CC17FD7E46 +:1063E00093C7EDF152BD2313F5428F5989413A7E8F +:1063F000B86C620CE2F52896585FB653EF80B2A6EF +:106400009DAFD763E98E457AEB69CF97D16E51E79F +:106410005B89EB1686D0F510DEDC84A72A4F8B193A +:10642000E709E28FD7BBF2B81D7ED2F3EE5D68A715 +:10643000F464475B112F5D7A46FE6D2DE015F54142 +:106440004F675A0BDE83BA9E4BE0A33F5B43780D48 +:10645000F874A2DFA25616D64FC7F1B52B7C3F16B3 +:10646000CFB97F5B847AE959B0ABA1BA4ED7908C93 +:10647000E7FF787BF8FEAAC43DD7E9FCC9C921F43F +:106480005AD731C42F66A2EF0E953F14C2A78AC710 +:106490009E6C6EB7F5A41A3CE82FD6ED6F25BABEF8 +:1064A0003EBED39D81767EDAAF8D1437BC913FAB73 +:1064B000DA01217E0F433F4E5736B1503321A8EF0A +:1064C000AFD9EC2FE615A23F544EFE5E0F1B588647 +:1064D000CADF8976701CCADDBF3D85EB0EB683BD71 +:1064E00007EB3A8DBEB91F829D35680546817D0F49 +:1064F0006ED779847F6246FB7499B04F3F561C4536 +:1065000032E857E71A0D9DAF2E278ADBB5424E7E43 +:10651000B23FE3A748AF7527648B11ED50F05B08DD +:106520006EE37641BD37E3DF67A0BDDDA6233B40C8 +:10653000B53B9CC2EE382FECD9F36B06F464AF1E6A +:1065400096D813B08F2ADFE6AE346877E6CC257B89 +:10655000D529B751FC71F9D670BBA0DA130ED7EE6E +:106560000D879D117683EAB7F5E40DD90F93D1FF1E +:10657000289167A4201F7C2CF0A9FA232BA75A533B +:1065800090DF376895B96A3C00EFC975F8D56ADCC9 +:10659000AFA72ECA4A7EC1AA43749FFD9F71BFA3B5 +:1065A0003F9571FB88F17BEDF771FA76E924EE6790 +:1065B00000B9D27C46C9B3069AFADD83B124971894 +:1065C0002B437E685CC8FD483BC65CA1DC9727E294 +:1065D0004511FAF2566D9F1C1F221F3ECB9B40FBBC +:1065E0002FD63307EAA9953156D25BE38DDCDE2E38 +:1065F00059EDB5211D8C07FFD81012CF1E6F1E90CC +:10660000B0DFAE8778FC5CF5EFE76B2DBAF810BD14 +:106610000792276C7E90247CFC8DE6B7C0FCE6E0F8 +:10662000FC70DF7178DF9F1658491FA7CF67AC9BBE +:10663000F8B181F8513DCF15A0B362A0338C9920F9 +:10664000DEEAB61FA138B09375933F521ACBF751CB +:106650008AFB41388A97967C2E37CAF3F9BD350BF1 +:1066600058955B6FE5DBE3F3A1DC9BEF48CAA77AA3 +:106670000BD1E54A412B60A7A4F40D23771BFFC281 +:10668000FDAA4F810F90CFEF699094CC303B88D317 +:10669000B78B57B1CBCCDB3B03EFC16DEFCE4E4692 +:1066A0003F8AF3D59255262533844E5D48E7702FF7 +:1066B0005596EA1FA3DDED5895AC60BCDF85743FAD +:1066C00001AF91D37522FC43FFE23A3AF786C3F05B +:1066D000B71DE9AB9E19ACA8475CBEC876AB16E304 +:1066E0003AF9F9C0073707F9205DD0658B43F2A06E +:1066F000DC6FF94ACBE3588B258A5BDD0995489717 +:10670000F487FDAA667A70FE3B01447F886D4924B8 +:10671000BEA14690233F17E7BD53EB3F827C7C5CD4 +:10672000E7CDC078CA7127CFEB2C646070807C59AC +:10673000CCBAA9EC8DAE3FE0A7C9DDE3D06F7ECF28 +:1067400061A0384ECBDA1D31284F73D95ACBF96C82 +:1067500054EE6CEFB5FC91ED0A2024765EC50BC5B6 +:10676000853611FE55BCEECDB7CF47FC8F34BEF653 +:10677000AF076E4797A2F681567D0A279BEEECA2E3 +:1067800020FE5CCC9B8DFB55F135843FD8F358B887 +:1067900087056CA008FD1A156F46F8371CDED4FB80 +:1067A0004CD70DFC0CAF0CF412C997487CAAF75BD0 +:1067B000CF1A743CCED5F0CE42E87FF75A8D82F6E0 +:1067C000E175F8BD011EFC26DEE48F91C8DF1C09CF +:1067D0002F2A3E54FC9C8EE7E34EDF23539CEEFFB2 +:1067E000355EDECA773CFA6DFC18C97F23F1DB9277 +:1067F00055117C19C17F2ABE1CAB6289CF543CD68F +:10680000298CFCD6BACE18AB8705F167867F883F06 +:10681000CC53503CA65D62CF48DF850FFB28AF11FB +:10682000891FA00D3BCAF59D11FCA7E26D24F9A3B9 +:10683000CAAF33CC7FDC22517E80F3E7AF0C1ECC95 +:106840002FAAF901350F704CC8BFC8F20CD81D989B +:1068500077D998DD9384F65AAF5E9D87E71FCFAC5A +:10686000E91EB702C69F99C9CB5EB4D342607B14C0 +:106870008FC39D196D70E3BD9D9126CF423D7E462D +:10688000FAF5ED1C4ED12B082F4C996501B857A78E +:10689000C6ED1E1672D843E59985D38AA99FC4DE3A +:1068A000C4FB5024564EEB48524219ECE7CC0393FC +:1068B000F29A59F0FCAFE4737BD62BE4F9501CFB41 +:1068C0003712C5B197800AB060BC7DD6D36513A0DE +:1068D000FEEC83136D94FF6B0C5F1FF56806C50714 +:1068E00037D37CB77E31A05B9A13DCD790FE2BBEEA +:1068F000CAEB2B27913F512570684F98CCFD58CF9C +:10690000C438D447AA7E1A3CF1AA39347E7911F4EE +:1069100017D387C0931F4F0FD56F4776FF3E0BE706 +:10692000A9D2BB73AD507FA1E50FE9680754ED7E96 +:10693000348BECD2DD1BB2D0BFA8DAF1FB2C3BC10B +:10694000D10EF26FB4FCDC97F7DDB27363881DFCE7 +:106950006021F70B161B8F94A07D3AF7E64F1EC1FE +:1069600078F8A407258A8BDDC3BA1F41BD5991CDA4 +:10697000F9886D31925C87F928EFD83AF927BB5036 +:106980009E9FCCFE405709FD4C055ABA8F0AE67906 +:106990002C05E361EB258A8705FB8FA33CE6D2B586 +:1069A000923E3511F561BC4D56705C3CEDE3DEF571 +:1069B000B62EACAF58CDEBE71A3CED3D38CFD37ACD +:1069C0006BAB8213954F280FC90B9B0AB8DFB5E458 +:1069D0003189EC71759D494F25B7849ED35420F4BD +:1069E000F98C6EE2FF9F0ABCFC78F5BB6FA62A9873 +:1069F0004F72C41540FB3B4F9ECF44F9559C7031FC +:106A000007E97C92DEF14C359E7B8781E28705B9F0 +:106A100069720AF4CFFBE5CC27B05CB27AE933D5D2 +:106A20001807DD6A243F4ADD5FA3A468D0DF3CD6A7 +:106A3000F28B7BF1DE2E3C69243BBAB1E5A614361D +:106A40000C9FAAE51EC0BF92C5D8F34D462A5F6CC5 +:106A5000B230058EB8AF2995E0979B142AD9024E23 +:106A60005F8DC25F1D69BE7CF0F715905705EB6125 +:106A70003EB0376D26FB143CE7A429CE1D1BC4B9DC +:106A800026C1789B3B6336DE43C186155D688A2646 +:106A900017F0FCE2DB3DEBD3C98E5E7DEEB96A6890 +:106AA0005F5A509E5F00F76DDC7E95FCFC631D8F86 +:106AB00056505C7F87819F4F9CFBC2935929CF60C2 +:106AC000DCF52D1DF9DFAEEDE79EDB00E57D8FAD3A +:106AD000D087D2FB773DAF4DECE7467C35D23D7C8D +:106AE0007FBEFA7D3AF1CF0EE0AB9C7F9CAF5CABF2 +:106AF000D7D0FD3D5A507E37DEFB059D3B1DF9E9A1 +:106B0000C2E41F119DBB0F4B74FFAA1C57C72F1067 +:106B1000E7ADD5781F237B50C8F1CFC1F3C3FB3D50 +:106B2000D2F17116DAC39FFB167EEBB90F36610600 +:106B30001DE35A462A23DB8BF48E8956385F9186F3 +:106B4000DBC191ED0F17A871719E6FC73F8C0BD7FA +:106B500009FDE9848DC525A0FE93FC51B998E7B8DD +:106B6000EDA216FD2FF0EBDE0FB72FD9FB217A7CBB +:106B7000A4FDDEA8ACC779B441B93BEDB486F943B6 +:106B8000F4F62D7D51CC1FB2EE90DF01757ACCB3B7 +:106B9000748C26B98078C3BC4CA063F20E842FEAB3 +:106BA000391E0307C1BFE27115261705CF79B1E37E +:106BB000722ECAD9C8F3D61FBA4CF451E77BF4AA97 +:106BC00044E79F73519B7BE3F31FD97D3917F1771E +:106BD00051D757847E5440DF978B78A87F9DCBF3A5 +:106BE000EF7B0F6A7DF57A3D8FEF4916F2074BE494 +:106BF0002BE4C7074E703FBEBE6327C9D3C14E1EEC +:106C00004F7169BA4B5330FED070AE0BE5D9602A94 +:106C1000F7AF607E3BDEDB8C89420F6A07D2E783E9 +:106C20005C3B2AF2B5AA5F7701F9578FF378EBE85E +:106C30003D526E3443BBE212F233D457ACCA58878C +:106C4000747EC193849120F676EEFFD453FCED8DD3 +:106C5000688B4C762BD486E06FE81C1E993F9C61B4 +:106C6000AA9F1ECDEC21FD5C7AE5A7E41F9FE47985 +:106C700032D714CE4FEC10E727E7DA23FAD490F995 +:106C80005E52E587B01FE7BEF13FC497A76CF6538D +:106C900028CFA25116E27CA9711E4912FD8A827981 +:106CA0004073A7F0C7CB646A77F964361AC7A4C6E5 +:106CB00050BEBE8C6DD2A2BD3B977967F077327D16 +:106CC000FFF643689FF7869C8FEFB1C07EA6FC71EC +:106CD000699423B311ED238D24EED55B303F549F8F +:106CE00015727B6B862C911E1B181D4D76CA9C0558 +:106CF000CEC5B85FB55F9996EB339887EC2CE61953 +:106D0000C8C57C26F30FE4629E53ED77D71BD10DE7 +:106D1000A41799B7E0AE9075C61472BDF929E69F25 +:106D2000419EB844FEB344FEEA29F4A31A0FF33C93 +:106D300061AF26E33D7CAFE5867B46BC5E06BCDAF0 +:106D400051FF3898DD8EFC3335C983FCE3DA2731F7 +:106D50007CB756DF61D881719D7A5D5F32D2F306D0 +:106D6000DF5FF548CFAE03EFEA95A9389EC781C033 +:106D70005ED7E0FDBA84FE72FA6E7A0FE36ECE1330 +:106D80005C8B3AB5EF925F5FDBBE9FFCF73AE6277C +:106D9000FFBDAE2D9C5E0653799C3D923FC6142AE2 +:106DA000617C31672BE78BBB64D680728E89B8E932 +:106DB0009CD414B24782E3849D285F7E04ED97FE45 +:106DC00009925582A9FAA3DC6BD12E7267717BA65A +:106DD000FF4F2F162C23B9E229F819BE8B11F6EEBE +:106DE0009CF59BB572C87EE674F238617F14AB3AAD +:106DF00048F8768C453CA4E7958F2DE4EF6472E962 +:106E00009D8F86C73523CFF1AC88E39CC4384F4EA5 +:106E100070DFF3D2D2B81C631EA29F2E0D5F5F7D80 +:106E2000F7A28E5F21E869C81F92787C6A24B98234 +:106E300079944A9147A91479944A9147A91479946D +:106E40004A9147A91479944A9147A91479944A918F +:106E500047A9147914AC3F895BA5F7703B9F417A31 +:106E6000E8421E1B13847B1322E031E1FD7B13A457 +:106E700070788C44FD8B0B773EE3CEC138A645C8B5 +:106E8000252506EDAF0B261E5FEA8871CC2D84FA0E +:106E9000CA39CDBBF97B443BBD67294E58B818F9B8 +:106EA0006B30D1C0500EB90B1DF3111F274ECCCE45 +:106EB000DC4CF2D164C53C77EFDD37C7515CEE2D79 +:106EC00099C9B0E4CCECFCB50500CF344B44B720F5 +:106ED000277E50AEFA9330CFEC4E9ECF2891EB2A0E +:106EE00071FEC6D1A67C8A6BE53B161586C40F4A97 +:106EF000C72CCF443BA84BA7BC87F154F75F740C59 +:106F0000FD2835FEA6F6EBCD9B598DFB9A933D717E +:106F10006D1ECA1B602E946F763D6BC37DD935D133 +:106F20005233C92B458BFC5F2DF03D4BE1F6B05F32 +:106F3000AF6813D06F8F9A99E85678BEAA52E4AB27 +:106F40002A45BE0AF1730AE36650BE03F55876433C +:106F50003D9691EFB9761794AF24BA6503E9A1EF96 +:106F6000C1E6225F7139938EF4FC8288C367178A69 +:106F70007769F9E50FF2715E9AA756C4DF2EEBC26E +:106F8000F378EAB8E07846E51D3FE0F299C5E9F903 +:106F90007BD7B1CC8DEF69EF786D34C593021E8D30 +:106FA0005B170730F038CA2FF61AF76F592AE797A0 +:106FB0003B5E4DA17ECD220EEA4CE8CE4A40BD2B71 +:106FC000F84A850F7EC3DFF938F30086F275899F92 +:106FD000CF794777563CC001C9A4C1F8B873076F91 +:106FE000EF117CE79C20E613E761466F3AE2A3FFCE +:106FF000F06BE9F702BCD1EC5FC6E5BD3F8BE43432 +:10700000F367E17BA1CB92F72CBEB7FDF5C17F59A9 +:1070100084EF6B2FEBBCCF21FCDB8333382CED3FAF +:107020006B096D4FF2A6E37BDC5F1FFCE1227C9FC6 +:107030007B3969FF73F1D61058F7CA596CD73F3CBA +:10704000635131F49F67F09C6842BA7999D397698C +:10705000DF81F3783FB51DDC5E9FB5EFC0955750DB +:107060001F1F88A17CBDAF3083EEBBB963CF6348DF +:107070006F81FD3AE2838D6D7F7DEEB7D4CF4061A5 +:107080009479066F01865CDC457FBB1BF7352FDAF0 +:10709000FB19C29B8B6EA37DCE1BC5F9F9A9A2B9C2 +:1070A0008B903F0307F6FD0AF96F5E1C18B2B89F7C +:1070B000174D849F9A572717631C2010D35D81F3C7 +:1070C000D7BF60B0229DD6BC9A320BE302C70B79C2 +:1070D0007CBA7ACAA674D4AF9A43CFEFFE2DC629E4 +:1070E0005F30517EC695C0EDBB1AB9A56805E16F4A +:1070F000E76E7C371278DE4479D26A9803D7ABDE2C +:107100003D89E2EAAF7FFD4105E2A144DEBE1BEB13 +:107110003FDB65D2E03DF4E8ED713F423EECD191BA +:107120009F592DE0EADE517C3FD17DA584BFC44D3F +:10713000E9A85F6B46FDE676DCF73C79D373E8E7B8 +:10714000B03D06CA155C7C1EEE0DC65D6CD5D12B1C +:10715000D5C0F3315AA497CBD2A68A6770FE56DE0B +:10716000EFB26913DDA7BBF52686EB413F86F2EA55 +:10717000B2B439ACFE62EB9E5CF4432FBD308FFCA1 +:107180005195CE557EA9D96508D387240992C57B30 +:107190000952B36E66063D5B2DC04B07B7059E6175 +:1071A000C1F197DA747E3DDC51B581ADC5F7C12AD6 +:1071B0003FD4A4DD5686E7ABD1B464A1BD529DDFB8 +:1071C00057817C71D1C48CA9F88E4EE8AB9AF63504 +:1071D000F3D1EE1D693FB1E25DDFE7820F3FF79922 +:1071E0003CA1F9C1C8F26F4D4C3915F26EF89E06FC +:1071F00003D9EEEA7C6FEBBD75E89FD52770F97176 +:1072000016FAB7811C331771B9B76455787FA9880E +:10721000BF4BACD7F765A1DE53E7FFA650956B7D5A +:107220005928AF22C7CD9385BC7951227953D32EEB +:107230009D93E19E6A8C6E0FBEDFA94167929F53BA +:107240007B4DE2E3528BC4BDC3D8A78B3268DD9A75 +:107250003693DD04E36AA3FA62D11EAA8BE98B455B +:107260003B277048663B04BA1293057E2608948536 +:10727000C41DABBD3ABB2977183CA3DD84EF73F086 +:10728000BF61FDB622CE2755BE685A8F59FA8A9043 +:107290004EABB6878FC3735942F82FE0DB991CEAD7 +:1072A0008FDBC4BEFBA573C427FD5FBF9F8E78AF85 +:1072B000D1B0B59847BC24F1EF1E00A6EF1E2E8971 +:1072C0007C64CDDFCD51482F973EAF23BE0D487D66 +:1072D00024D7CE1C5C407229A0EB23B9D65354416D +:1072E000F22110DF578172EACCC17ADE3EBAAF429A +:1072F00081F64E84B17D1C237D7FB9E801921FF396 +:1073000064FEBE81EDD459781C687D6F13F9153A7F +:1073100025D4EFBE52A4E66DF4C173CB41BE093053 +:10732000655F3BF2619599E239603FB5BD8276DEDB +:10733000C2642BC6C5AB701CA7037D68FE2F31E16C +:10734000CB65889F45718E3B8B308F9DD347FE0365 +:107350005035D9E9F57F32901FD9AF1BD88D722AED +:1073600037CEB1B008F651A7EF5E87A1A72BBABE02 +:107370002ECCFBCD95B93C627B385D057276F2EF81 +:107380002444FEB0BA88CB5FD05BAC05E942E2F89A +:107390003DE67BF514CA9540F74492C7917C73D1C2 +:1073A000F7442CCA87D3A0C7DD217EFEE9A57B2840 +:1073B0004FBF00DF654079EFDA707A18FCEA67E4C6 +:1073C000EFB1C742EA910EB784C3917484F4E80F19 +:1073D000933B6EA29B3D82AF6A6775D7E33D0CC1BC +:1073E00077002C87C04723E088FEAC9CDB097BF04C +:1073F000BF61DEBA71FE5EF2CFF7F177B1CDA0BF0B +:10740000083E104D7963CD3ED04F895C3FA15EA808 +:107410008DEDA6B854E08081F2230F777C4CEF19F4 +:10742000810E29FE52DBF15A32FAED3EF4139248F6 +:107430000F26D33B95031DC9E86FA8F5751A6F9603 +:10744000788F4F76BA5AEF94FD59B8FF5AA93B1777 +:10745000DB7D8516D11F60196146E7A89338BFB35D +:107460000E99E47924DEF60A7A05B9904BEF2C0EDA +:10747000F1B8802A07AA853C398AF5399CEF2D6A34 +:107480005E49C2F772D1C3CA879B8A547BB881E236 +:1074900036BB8A147EAF623CCDCBE34AD45EFFFAA2 +:1074A000E5DC0939384E11E342E4D0C4A05C41FE6A +:1074B0004F25FE7F58970CE7AA794EB236A39C5A07 +:1074C000BCA614BAB3E5DA15A5142F13EF3F23F7C2 +:1074D000154947F6228EDF1A4D7C4962C87C97C059 +:1074E0005D4FCD233943EFE8EF4F7CBC14E313BF6E +:1074F00058BC99E87948DF84F2399E673B97E3C826 +:1075000036D734D7D3F1F286967529C3EC23729F10 +:10751000D58E96D264E5FA7A75BF974CEAFE66E995 +:107520009242EF61C19AD22428971BFFD17BE0E7FA +:10753000BDD461F0A35EAD5EBC625DDC3074739D52 +:107540003ED81EA2BF26207E3D94D71869FF9165C4 +:107550009DE4EFC5381103BE6A25FE027E09D10BFA +:107560006542BF0EC51BAA968E47BF9339968E47BC +:107570003D037C55611DC6AFC42F4B34F476C34D1B +:1075800065E47E3E2BE271D2B222CE2FA76CF66F5D +:1075900050BE8EF4BD85619AF4ADDF5BA46906DF51 +:1075A000417E4B4B8E51300F54323B9AF73B6CB2BD +:1075B00060DCA6FFF09714D7ED7FC4BC80E70BCC4E +:1075C0006C34B477A54EDD11AA473CD3385F46171B +:1075D00070BBC595ADFBF6B8504ECC505C88EC86C0 +:1075E0009C68CA93047C9F92DEEAEF2CB4603E2331 +:1075F000D00DDE21F093EBEBFF4A46FD1AE8FC8844 +:10760000DE8305BEFA98DE896D10EFF48EFAC43B76 +:10761000AB6E2586BE8B2BFBA014FB6D1465303E34 +:10762000C0E35A6AA9FAFF21FEEF946985C3FABF45 +:10763000090E73685C4049192E8E121A17C8D4F2CD +:10764000B800961817C8CCE4710184312E8025C685 +:1076500005B01EE30208635C00618C0B208C710195 +:107660002C312E80F59F89EF1FFA4130F178A599D2 +:10767000E4FA4A7CDF0EF7B7F230CF3BAD6C9529C8 +:107680007F8BDF3FA07EBBEEDD4CBB7837E3DD4C6C +:10769000793CD701D98A2872E9068E631CC7B55F89 +:1076A000B2AE41B9D2B480D6DFD059F8DE62AC6F49 +:1076B000D559350AD111C7638B44EFF46B3A5B2976 +:1076C000EE549C72584FF56D12C338E95D06EEE733 +:1076D0003A65A8CDA33C28D9C14E4337F91FB57BE5 +:1076E00025A532F49DC6F4AB2407D47CF232DEC467 +:1076F0009C5E935239CC3B90A177E7E2DDF432CC2B +:1077000033E37B71F92B7AD7EF04877414D2E156F7 +:10771000FEFED902FF88DF23DE35D574EE5F87EFEA +:10772000A122F3CD43DFD345E49DEBA789BCB28D05 +:107730007F5F51F664E5BE03B0DEE02603D91BEEA1 +:1077400042C703D39230EF6FA7F8C8F1C326F28B7C +:107750003EDC7C53587C84E53B1E9C46F9F9B11411 +:10776000AF68D449A48F67974D4CC17B9C7D42473D +:107770007AA737AF7C35F66B9CAA503CAAC4C01ED2 +:10778000A079C47B29151F25CD924703F05266A529 +:1077900077F64BE09A305ED9AF33AFC7774D4B18D1 +:1077A0007FE7A0D24DE36689E8060304789F15E2DF +:1077B0003E9774FEF94B7CC7709F81DBAD691A9EC2 +:1077C000BF4EDBC8DF33DCCF1C7AD4B3CB91BA64B5 +:1077D000D28F7FEA837A47F4D8746E972B2938FFCB +:1077E000D2933A7A6F5B92F2932C07E9E9627AC7F7 +:1077F00020F917C9D76E1E997F22DF311CD771B9C6 +:1078000002F748FE5017D225C5651C549E6CAAA2EB +:10781000F277E27B88EBDFFF0F9C453F312D25C6D9 +:107820008A726EC4EFDDA2BEFD7BAF17C4FBB53418 +:107830004D4FBE82F7F177B315EF437D2778CA56D7 +:10784000BE1FF1648F656E0B7D0F061210EEB5142E +:107850000F22615CDB6BC7EF8E060E4B167A977CAE +:107860009D7CDCFC08BE1371654A1649C1F8F7A679 +:107870009264D877E9840CDAB7CBC7E3A37443C921 +:10788000183FE7F84ACF731C9B5618AC9F27F82681 +:1078900000FD399DFCD083F4F61DE2A6BBB0BF9B72 +:1078A00099E87B6AFA83FDCCBB791CC54F55BA19A0 +:1078B0006C4BD98174F39E90FB8B17BFAB43FDDFFC +:1078C0009BEFE8C17D54545E7D2499CE377CFC4A01 +:1078D0007DA71E19BF0A959FFF3FDEA79F6A6AA07A +:1078E000F29DA655547637B9A93D44FE5F1A41FE74 +:1078F00047C63FAF227F47C63F99518923FD09FC08 +:10790000CDE3CD11F1CEB251F7AE87FB9BBD456FF4 +:10791000C52A35FE89EF87579A491EFCF7B461E303 +:107920009EEABD99294E3AC84C7978FFB3B2276ACE +:1079300035D0AE9DCEF1A7C61D913FF07CC81F5833 +:10794000227F68B541FE78560F2C5CC0F5BC9BF4D5 +:10795000BC89F0BA6E0DC80F80EF639630F97125BF +:10796000427E80C371377D57D56960182754DF5137 +:10797000CE82E28BBC61E48997CB937151DEE7E95B +:107980007BFFFA287A9F7B5CBC873BBE81BF87ABBD +:1079900064E5B4EE30722516F171DFA881B37F8003 +:1079A000FEF7FDDE4CF6CABAD1CB8AFE19B9724D8C +:1079B0007CD7F234FEAE80F6DB7E57E03109F3A1CE +:1079C0008DF7301BE259FD5D811491CFFE1EBF2B58 +:1079D000306D7AE177FF5D815BA78F5F1CFABB0298 +:1079E000B7FA3238ACFEAE001BBF7884DF15983D85 +:1079F0003DE9FADF15B86D3AF71747FA5D01B02790 +:107A0000CB705C92CD3E07CB34B1CFC8EF694F8AC3 +:107A1000FC5D97C6B118CBD258B796EA359E02FAEC +:107A20000E5EE3FD25F981F98E9FE3794B9FB04D02 +:107A3000C90638CDE02539D99B67BF13EBAFD9EC28 +:107A400077E13A917173C42DFAF7B09FBBB13DF263 +:107A5000DD958ACF15D3B9DC6814E58CE6E1BF2744 +:107A60006F9CCEF3F237DA37ECB706D71BDAFFA6F6 +:107A7000A505B81FD86F2DD6C37EEBB064E684B0E1 +:107A8000EF53AFA73337D155E3744E5F20CFE67D78 +:107A9000C8ED412AB3B49E78B41FC73CE489C7FD42 +:107AA0008E691930E177107F740F9850BFFF71F520 +:107AB0008009EBFF68E7EF9523E77F793AF703B298 +:107AC000660CD0F8F168E3937D3E108FF65356D5DF +:107AD00087EB28DFB27732E997F142BF8C7F68826B +:107AE000AF0FE86DFCB638CA67B3E2446AAF3172D3 +:107AF0003EAD79A8F2E00185BEDB9AF76188BD331F +:107B0000D903FB0EB3BFB483FCDD25C0784F7B7572 +:107B10000423CDA27DE564FCDDE5182137D04E5B62 +:107B20000C72C159F5E69794F7C7F1381FE66891D2 +:107B3000FE7CBA41F17D9A05FDD0E50BD674915FCC +:107B4000B875A85EF899FBD7A1DF0CF65B587D4DA0 +:107B5000E5912ED437B57BC3EB9D0D57C97F05FB4F +:107B60002DACFE9E5F9ED3F3DF2F08AF07FCEE45E2 +:107B7000BA54F17B5CE79D8C7EDE71679495BFDF24 +:107B8000F7D2EF95EC10DF3FEFFC8F599C6E04BEEF +:107B900061BC3774FCC8F4D14CFDDDB35836F2C378 +:107BA0008D4A552E0DFDFE899EB929BE373786E4D4 +:107BB0008E4BF855F59516D2F369F546925F25720E +:107BC0009415E1A1DF3F2993859CF212FFF7DC1E9B +:107BD0004F713C3A00C2095329EF93DCCCE1812478 +:107BE00003C987124D79DD1E28DFD4847FC7FE2CA0 +:107BF000CA0719F9977F87E9D27BF977E25AA5106E +:107C0000FDDC66C9BE0DBF7B6C96441CB1DA4CF935 +:107C1000827E8C2FC279B6C47BB62D8375B6DC9973 +:107C200043F6713FE3F2D4BD80E7ADB6C4972F5E53 +:107C300081ED0BA750FBC16F263E5E80F653759415 +:107C400015EDA72D366E5F6F999F4DEDAF4BCA1A9C +:107C50003CB7FB2146EB6C99CFCFBDE5F171E2FB60 +:107C60000B8F09F9794B8B7D34E6A366591C1710ED +:107C70005F63443E6E4B06D443F99454BEF07E9C41 +:107C8000672ADFEFEF6C0AC98FE30BA73CBE5B21CD +:107C900035E2C7BC906B6E0CF9C1FF0BB81F749432 +:107CA000704700000000000000000000000000001D +:087CB00005020D0000000000B8 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex new file mode 100644 index 000000000000..ea3e254335b1 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex @@ -0,0 +1,12849 @@ +:1000000000003BE8000000600000068800003C5053 +:1000100000001968000042E0000000AC00005C50E5 +:1000200000008DF800005D00000000E80000EB001B +:100030000000E3140000EBF0000000940001CF0882 +:10004000000058E80001CFA0000000C40002289082 +:100050000000F9640002295800000004000322C0D7 +:10006000020400480000000F020400540000004594 +:1000700002040058000000840204005C0000000636 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040004000000FF02040008000000FF79 +:100170000204000C000000FF02040010000000FF59 +:1001800002040014000000FF02040018000000FF39 +:100190000204001C000000FF02040020000000FF19 +:1001A000020400240000003E0204002800000000B9 +:1001B0000204002C0000003F020400300000003F59 +:1001C000020400340000003F020400380000003F39 +:1001D0000204003C0000003F020400400000003F19 +:1001E000020400440000003F020404CC00000001AF +:1001F00002042008000002110204200C000002008A +:10020000020420100000020402042014000002195D +:100210000204201C0000FFFF020420200000FFFF5A +:10022000020420240000FFFF020420280000FFFF3A +:1002300002042038000000200204203C00000000DE +:100240000204204000000034020420440000003575 +:10025000060420480000001C020420B80000000131 +:10026000060420BC0000005F0204223807FFFFFFE5 +:100270000204223C0000003F0204224007FFFFFF6F +:10028000020422440000000F010422480000000084 +:100290000104224C00000000010422500000000074 +:1002A0000104225400000000010422580000000054 +:1002B0000104225C00000000010422600000000034 +:1002C0000104226400000000010422680000000014 +:1002D0000104226C000000000104227000000000F4 +:1002E00001042274000000000104227800000000D4 +:1002F0000104227C000000000C042000000003E840 +:100300000A042000000000010B0420000000000A85 +:1003100002050044000000200205004800000032F1 +:10032000020500900215002002050094021500202D +:1003300002050098000000300205009C0810000033 +:10034000020500A000000033020500A400000030F8 +:10035000020500A800000031020500AC0000000208 +:10036000020500B000000005020500B40000000610 +:10037000020500B800000002020500BC00000002F7 +:10038000020500C000000000020500C400000005D6 +:10039000020500C800000002020500CC00000002B7 +:1003A000020500D000000002020500D40000000198 +:1003B00002050114000000010205011C00000001FB +:1003C00002050120000000020205020400000001F5 +:1003D0000205020C0000004002050210000000406F +:1003E0000205021C0000002002050220000000138C +:1003F0000205022400000020060502400000000A59 +:1004000004050280002000000205005000000007E3 +:100410000205005400000007020500580000000813 +:100420000205005C000000080205006000000001F9 +:100430000605006400000003020500D80000000665 +:100440000205000400000001020500080000000190 +:100450000205000C00000001020500100000000170 +:100460000205001400000001020500180000000150 +:100470000205001C00000001020500200000000130 +:100480000205002400000001020500280000000110 +:100490000205002C000000010205003000000001F0 +:1004A00002050034000000010205003800000001D0 +:1004B0000205003C000000010205004000000001B0 +:1004C000020500E00000000D020500E80000000742 +:1004D000020500F000000007020500F80000000718 +:1004E000020500E40000002D020500EC00000027DA +:1004F000020500F400000027020500FC00000027B0 +:10050000020500E00000001D020500E800000017E1 +:10051000020500F000000017020500F800000017B7 +:10052000020500E40000003D020500EC0000003779 +:10053000020500F400000037020500FC000000374F +:10054000020500E00000004D020500E80000004741 +:10055000020500F000000047020500F80000004717 +:10056000020500E40000006D020500EC00000067D9 +:10057000020500F400000067020500FC00000067AF +:10058000020500E00000005D020500E800000057E1 +:10059000020500F000000057020500F800000057B7 +:1005A000020500E40000007D020500EC0000007779 +:1005B000020500F400000077020500FC000000774F +:1005C0000406100002000020020600DC000000010A +:1005D000010600D80000000004060200000302200B +:1005E000020600DC00000000010600B80000000068 +:1005F000010600C800000000010600BC0000000069 +:10060000010600CC000000000718040000A900004B +:10061000081807C800070223071C00002C2C000044 +:10062000071C800038930B0C071D0000293119317D +:10063000081D686052F40225011800000000000047 +:10064000011800040000000001180008000000006C +:100650000118000C0000000001180010000000004C +:100660000118001400000000021800200000000122 +:1006700002180024000000020218002800000003F5 +:100680000218002C000000000218003000000004D6 +:1006900002180034000000010218003800000000B9 +:1006A0000218003C00000001021800400000000495 +:1006B0000218004400000000021800480000000179 +:1006C0000218004C00000003021800500000000057 +:1006D0000218005400000001021800580000000435 +:1006E0000218005C00000000021800600000000119 +:1006F00002180064000000030218006800000000F7 +:100700000218006C000000010218007000000004D4 +:1007100002180074000000000218007800000004B5 +:100720000218007C00000003061800800000000290 +:10073000021800A400003FFF021800A8000003FFF9 +:100740000218022400000000021802340000000019 +:100750000218024C00000000021802E4000000FF32 +:100760000618100000000400021B8BC000000001EE +:10077000021B800000000034021B804000000018B3 +:10078000021B80800000000C021B80C000000020C3 +:100790000C1B83000007A1200A1B83000000013806 +:1007A0000B1B830000001388021B83C0000001F4B0 +:1007B000021B1480000000010A1B148000000000CE +:1007C000061A1000000003B3041A1ECC0001022711 +:1007D000061AA020000000C8061AA00000000002AF +:1007E000021A1ED000000000061A1ED800000006E3 +:1007F000061A36E800000004061A36E0000000027F +:10080000061A500000000002061A500800000004FA +:10081000061A501800000004061A502800000004B0 +:10082000061A503800000004061A50480000000460 +:10083000061A505800000004061A50680000000410 +:10084000061A507800000002041A404000020228F4 +:10085000061A400000000002061A400800000002CC +:10086000041A62C00020022A061AD1000000000209 +:10087000061A200000000124061AB000000000281B +:10088000061AB1400000000C061A330000000014E4 +:10089000061A33A000000068061A81080000000252 +:1008A000061AD1C800000002061AD1D800000020A4 +:1008B000061A249000000124061AB0A000000028A7 +:1008C000061AB1700000000C061A33500000001424 +:1008D000061A354000000068061A81100000000268 +:1008E000061AD1D000000002061AD25800000020DB +:1008F000021A292000000000061A30000000000241 +:10090000041A30080005024A061A301C00000009CB +:10091000061A320000000008061A5000000000020B +:10092000061A508000000012061A40000000000263 +:10093000061AD0C000000002021A2924000000009C +:10094000061A304000000002041A30480005024F29 +:10095000061A305C00000009061A32200000000868 +:10096000061A501000000002061A50C800000012BB +:10097000061A400800000002061AD0C80000000253 +:10098000021A292800000000061A30800000000228 +:10099000041A308800050254061A309C0000000931 +:1009A000061A324000000008061A5020000000021B +:1009B000061A511000000012041A401000020259D9 +:1009C000061AD0D000000002021A292C00000000F4 +:1009D000061A30C000000002041A30C80005025B8D +:1009E000061A30DC00000009061A32600000000818 +:1009F000061A503000000002061A5158000000127A +:100A0000041A401800020260061AD0D80000000242 +:100A1000021A293000000000061A3100000000020E +:100A2000041A310800050262061A311C0000000990 +:100A3000061A328000000008061A5040000000022A +:100A4000061A51A000000012041A4020000202679A +:100A5000061AD0E000000002021A2934000000004B +:100A6000061A314000000002041A314800050269EC +:100A7000061A315C00000009061A32A000000008C6 +:100A8000061A505000000002061A51E80000001239 +:100A9000041A40280002026E061AD0E80000000284 +:100AA000021A293800000000061A318000000002F6 +:100AB000041A318800050270061A319C00000009F2 +:100AC000061A32C000000008061A5060000000023A +:100AD000061A523000000012041A4030000202755B +:100AE000061AD0F000000002021A293C00000000A3 +:100AF000061A31C000000002041A31C8000502774E +:100B0000061A31DC00000009061A32E00000000875 +:100B1000061A507000000002061A527800000012F7 +:100B2000041A40380002027C061AD0F800000002C5 +:100B30000200A294071D29110200A29800000000E3 +:100B40000200A29C009C04240200A2A0000000005D +:100B50000200A2A4000002090200A270000000002E +:100B60000200A274000000000200A2700000000059 +:100B70000200A274000000000200A2700000000049 +:100B80000200A274000000000200A2700000000039 +:100B90000200A27400000000020100B40000000185 +:100BA000020100B800000001020100DC00000001A9 +:100BB0000201010000000001020101040000000127 +:100BC0000201007C003000000201008400000028C7 +:100BD0000201008C0000000002010130000000044E +:100BE0000201025C00000001020103280000000075 +:100BF0000201607000000007020160800000000137 +:100C00000201055400000030020100C40000000190 +:100C1000020100CC00000001020100F80000000108 +:100C2000020100F00000000102010080003000001D +:100C3000020100880000002802010090000000006E +:100C40000201013400000004020102DC0000000186 +:100C50000201032C00000000020160740000000784 +:100C60000201608400000001020105640000003000 +:100C7000020100C800000001020100D000000001D4 +:100C8000020100FC00000001020100F4000000016C +:100C9000020C100000000020020C200800000211CD +:100CA000020C200C00000200020C201000000204C4 +:100CB000020C201C0000FFFF020C20200000FFFFA0 +:100CC000020C20240000FFFF020C20280000FFFF80 +:100CD000060C203800000002020C20400000003406 +:100CE000020C204400000035020C204800000020C7 +:100CF000020C204C00000021020C205000000022B9 +:100D0000020C205400000023020C20580000002494 +:100D1000020C205C00000025020C20600000002670 +:100D2000020C206400000027020C2068000000284C +:100D3000020C206C00000029020C20700000002A28 +:100D4000020C20740000002B060C207800000056D6 +:100D5000020C21D000000001020C21D4000000018F +:100D6000020C21D800000001020C21DC000000016F +:100D7000020C21E000000001020C21E4000000014F +:100D8000020C21E800000001020C21EC000000012F +:100D9000020C21F000000001020C21F4000000010F +:100DA000060C21F800000010020C223807FFFFFF9C +:100DB000020C223C0000003F020C224007FFFFFF14 +:100DC000020C22440000000F010C22480000000029 +:100DD000010C224C00000000010C22500000000019 +:100DE000010C225400000000010C225800000000F9 +:100DF000010C225C00000000010C226000000000D9 +:100E0000010C226400000000010C226800000000B8 +:100E1000010C226C00000000010C22700000000098 +:100E2000010C227400000000010C22780000000078 +:100E3000010C227C000000000C0C2000000003E8E4 +:100E40000A0C2000000000010B0C20000000000A2A +:100E5000020C400800000411020C400C00000400C9 +:100E6000020C401000000404020C40140000042195 +:100E7000020C401C0000FFFF020C40200000FFFF9E +:100E8000020C40240000FFFF020C40280000FFFF7E +:100E9000020C403800000046020C403C00000005F7 +:100EA000060C404000000002020C40480000000A0E +:100EB000020C404C000000F0060C40500000001FE7 +:100EC000020C40CC00000001060C40D00000003AAB +:100ED000020C41B800000001060C41BC00000003F8 +:100EE000020C41C800000001020C41CC00000001CE +:100EF000060C41D00000001A020C423807FFFFFF29 +:100F0000020C423C0000003F020C424007FFFFFF82 +:100F1000020C42440000000F010C42480000000097 +:100F2000010C424C00000000010C42500000000087 +:100F3000010C425400000000010C42580000000067 +:100F4000010C425C00000000010C42600000000047 +:100F5000010C426400000000010C42680000000027 +:100F6000010C426C00000000010C42700000000007 +:100F7000010C427400000000010C427800000000E7 +:100F8000010C427C00000000010C428000000000C7 +:100F90000C0C4000000003E80A0C400000000001B7 +:100FA0000B0C40000000000A020D0044000000325B +:100FB000020D008C02150020020D00900215002089 +:100FC000020D009408100000020D0098000000338C +:100FD000020D009C00000002020D00A000000000B5 +:100FE000020D00A400000005020D00A8000000058D +:100FF000060D00AC00000002020D00B4000000026B +:10100000020D00B800000003020D00BC0000000249 +:10101000020D00C000000001020D00C80000000227 +:10102000020D00CC00000002020D010800000001CA +:10103000020D015C00000001020D016400000001CE +:10104000020D016800000002020D02040000000110 +:10105000020D020C00000020020D021000000040F2 +:10106000020D021400000040020D022000000003E7 +:10107000020D022400000018060D0280000000127C +:10108000040D03000024027E020D004C000000014C +:10109000020D005000000002020D00540000000884 +:1010A000020D005800000008060D005C000000045E +:1010B000020D00C400000004020D00040000000145 +:1010C000020D000800000001020D000C00000001EC +:1010D000020D001000000001020D001400000001CC +:1010E000020D001800000001020D001C00000001AC +:1010F000020D002000000001020D0024000000018C +:10110000020D002800000001020D002C000000016B +:10111000020D003000000001020D0034000000014B +:10112000020D003800000001020D003C000000012B +:10113000020D011400000009020D011C0000000A4C +:10114000020D012400000007020D012C0000000721 +:10115000020D01340000000C020D013C0000000BE8 +:10116000020D014400000007020D011800000029D3 +:10117000020D01200000002A020D012800000027B6 +:10118000020D013000000027020D01380000002C84 +:10119000020D01400000002B020D01480000002755 +:1011A000020D011400000019020D011C0000001ABC +:1011B000020D012400000017020D012C0000001791 +:1011C000020D01340000001C020D013C0000001B58 +:1011D000020D014400000017020D01180000003943 +:1011E000020D01200000003A020D01280000003726 +:1011F000020D013000000037020D01380000003CF4 +:10120000020D01400000003B020D014800000037C4 +:10121000020D011400000049020D011C0000004AEB +:10122000020D012400000047020D012C00000047C0 +:10123000020D01340000004C020D013C0000004B87 +:10124000020D014400000047020D01180000006972 +:10125000020D01200000006A020D01280000006755 +:10126000020D013000000067020D01380000006C23 +:10127000020D01400000006B020D014800000067F4 +:10128000020D011400000059020D011C0000005A5B +:10129000020D012400000057020D012C0000005730 +:1012A000020D01340000005C020D013C0000005BF7 +:1012B000020D014400000057020D011800000079E2 +:1012C000020D01200000007A020D012800000077C5 +:1012D000020D013000000077020D01380000007C93 +:1012E000020D01400000007B020D01480000007764 +:1012F000020E004C00000032020E00940215002085 +:10130000020E009802150020020E009C0000003022 +:10131000020E00A008100000020E00A4000000331E +:10132000020E00A800000030020E00AC00000031E8 +:10133000020E00B000000002020E00B40000000423 +:10134000020E00B800000000020E00BC0000000207 +:10135000020E00C000000002020E00C400000000E7 +:10136000020E00C800000002020E00CC00000007C0 +:10137000020E00D000000002020E00D400000002A5 +:10138000020E00D800000001020E00E4000000017F +:10139000020E014400000001020E014C0000000199 +:1013A000020E015000000002020E020400000001C3 +:1013B000020E020C00000040020E0210000000406D +:1013C000020E021C00000004020E02200000002099 +:1013D000020E02240000000E020E02280000001B74 +:1013E000060E030000000012040E0280001B02A281 +:1013F000020E00540000000C020E0058000000090C +:10140000020E005C0000000F020E006000000010E1 +:10141000020E00640000000B060E006800000003CE +:10142000020E00DC00000003020E000400000001B8 +:10143000020E000800000001020E000C0000000176 +:10144000020E001000000001020E00140000000156 +:10145000020E001800000001020E001C0000000136 +:10146000020E002000000001020E00240000000116 +:10147000020E002800000001020E002C00000001F6 +:10148000020E003000000001020E003400000001D6 +:10149000020E003800000001020E003C00000001B6 +:1014A000020E004000000001020E00440000000196 +:1014B000020E01100000000F020E01180000000EC5 +:1014C000020E012000000000020E012800000000B2 +:1014D000020E01140000002F020E011C0000002E5D +:1014E000020E012400000000020E012C000000008A +:1014F000020E01100000001F020E01180000001E65 +:10150000020E012000000000020E01280000000071 +:10151000020E01140000003F020E011C0000003EFC +:10152000020E012400000000020E012C0000000049 +:10153000020E01100000004F020E01180000004EC4 +:10154000020E012000000000020E01280000000031 +:10155000020E01140000006F020E011C0000006E5C +:10156000020E012400000000020E012C0000000009 +:10157000020E01100000005F020E01180000005E64 +:10158000020E012000000000020E012800000000F1 +:10159000020E01140000007F020E011C0000007EFC +:1015A000020E012400000000020E012C00000000C9 +:1015B0000730040000E50000083007D8000502BD30 +:1015C000073400002EF7000007348000311A0BBEEC +:1015D00007350000356F18050735800038C42561D0 +:1015E0000736000014C5339308363400398002BF33 +:1015F0000130000000000000013000040000000085 +:1016000001300008000000000130000C0000000064 +:101610000130001000000000013000140000000044 +:10162000023000200000000102300024000000020F +:1016300002300028000000030230002C00000000EF +:1016400002300030000000040230003400000001CD +:1016500002300038000000000230003C00000001B1 +:10166000023000400000000402300044000000008E +:1016700002300048000000010230004C000000036E +:101680000230005000000000023000540000000151 +:1016900002300058000000040230005C000000002E +:1016A000023000600000000102300064000000030E +:1016B00002300068000000000230006C00000001F1 +:1016C00002300070000000040230007400000000CE +:1016D00002300078000000040230007C00000003AB +:1016E0000630008000000002023000A400003FFF2E +:1016F000023000A8000003FF0230022400000000B6 +:1017000002300234000000000230024C00000000F1 +:10171000023002E40000FFFF063020000000080055 +:1017200002338BC000000001023380000000001A69 +:10173000023380400000004E023380800000001021 +:10174000023380C0000000200C3383000007A1207A +:101750000A338300000001380B3383000000138834 +:10176000023383C0000001F40C3383801DCD65007B +:101770000A3383800004C4B40B338380004C4B4095 +:101780000A331480000000000233148000000001BE +:10179000063220000000010206328020000000C84E +:1017A000063280000000000206323DA8000000045E +:1017B00006323D800000000904323DA4000102C150 +:1017C00006323D00000000200632500000000400F8 +:1017D0000632400000000004063240D00000000243 +:1017E00006326B680000000204326B70000202C215 +:1017F00006326B1000000002043274C0000202C402 +:101800000632DA40000000020632E0000000080064 +:10181000023308000100000004330C00001002C66F +:10182000023308000000000004330C40001002D610 +:1018300006322450000000B406322AD00000000214 +:1018400006321000000001A002323DB80000000086 +:101850000632500000000020063251000000002037 +:101860000632520000000020063253000000002023 +:10187000063254000000002006325500000000200F +:1018800006325600000000200632570000000020FB +:1018900006325800000000200632590000000020E7 +:1018A00006325A000000002006325B0000000020D3 +:1018B00006325C000000002006325D0000000020BF +:1018C00006325E000000002006325F0000000020AB +:1018D00006326B780000005206326E080000000CE1 +:1018E0000632DA880000000206322720000000B429 +:1018F00006322AD80000000206321680000001A03D +:1019000002323DBC00000000063250800000002082 +:101910000632518000000020063252800000002074 +:101920000632538000000020063254800000002060 +:10193000063255800000002006325680000000204C +:101940000632578000000020063258800000002038 +:10195000063259800000002006325A800000002024 +:1019600006325B800000002006325C800000002010 +:1019700006325D800000002006325E8000000020FC +:1019800006325F800000002006326CC0000000526A +:1019900006326E380000000C0632DA9000000002B9 +:1019A00002322A300000000006324010000000021F +:1019B0000632D0000000000602322A340000000087 +:1019C00006324020000000020632D0180000000657 +:1019D00002322A38000000000632403000000002C7 +:1019E0000632D0300000000602322A3C000000001F +:1019F00006324040000000020632D04800000006D7 +:101A000002322A400000000006324050000000026E +:101A10000632D0600000000602322A4400000000B6 +:101A200006324060000000020632D0780000000656 +:101A300002322A4800000000063240700000000216 +:101A40000632D0900000000602322A4C000000004E +:101A500006324080000000020632D0A800000006D6 +:101A6000072004000093000008200780001002E611 +:101A7000072400002ADE0000072480002E050AB893 +:101A80000824E4A061D202E8012000000000000068 +:101A900001200004000000000120000800000000F8 +:101AA0000120000C000000000120001000000000D8 +:101AB00001200014000000000220002000000001AE +:101AC0000220002400000002022000280000000381 +:101AD0000220002C00000000022000300000000462 +:101AE0000220003400000001022000380000000045 +:101AF0000220003C00000001022000400000000421 +:101B00000220004400000000022000480000000104 +:101B10000220004C000000030220005000000000E2 +:101B200002200054000000010220005800000004C0 +:101B30000220005C000000000220006000000001A4 +:101B40000220006400000003022000680000000082 +:101B50000220006C00000001022000700000000460 +:101B60000220007400000000022000780000000441 +:101B70000220007C0000000306200080000000021C +:101B8000022000A400003FFF022000A8000003FF85 +:101B900002200224000000000220023400000000A5 +:101BA0000220024C00000000022002E40000FFFFBF +:101BB000062020000000080002238BC00000000166 +:101BC0000223800000000010022380400000001269 +:101BD0000223808000000030022380C00000000E3D +:101BE000022383C0000001F40223148000000001DE +:101BF0000A231480000000000622100000000042AA +:101C000006227020000000C80622700000000002BA +:101C1000022211E80000000006223000000000C08F +:101C2000062240700000008006225280000000045E +:101C30000622670000000100062290000000040058 +:101C400004226B08002002EA02230800013FFFFF84 +:101C500004230C000010030A022308000000000007 +:101C600004230C400010031A06228100000000A08B +:101C7000062286000000004006228C000000003C86 +:101C80000622B0000000020006228800000000804A +:101C900006228DE00000003C0622404000000006C5 +:101CA00006228380000000A006228700000000407A +:101CB00006228CF00000003C0622B8000000020062 +:101CC00006228A000000008006228ED00000003C20 +:101CD000062240580000000606228000000000088E +:101CE000022211480000000006223300000000021A +:101CF000062260400000003006228020000000081C +:101D00000222114C000000000622330800000002ED +:101D1000062261000000003006228040000000081A +:101D200002221150000000000622331000000002C1 +:101D3000062261C00000003006228060000000081A +:101D40000222115400000000062233180000000295 +:101D50000622628000000030062280800000000819 +:101D60000222115800000000062233200000000269 +:101D70000622634000000030062280A00000000818 +:101D80000222115C0000000006223328000000023D +:101D90000622640000000030062280C00000000817 +:101DA0000222116000000000062233300000000211 +:101DB000062264C000000030062280E00000000817 +:101DC00002221164000000000622333800000002E5 +:101DD0000622658000000030021610000000002876 +:101DE00002170008000000020217002C0000000388 +:101DF0000217003C00000004021700440000000825 +:101E000002170048000000020217004C000000907A +:101E1000021700500000009002170054008000904C +:101E20000217005808140000021700600000008A22 +:101E300002170064000000800217006800000081A3 +:101E40000217006C000000800217007000000006FE +:101E500002170078000007D00217007C0000076C12 +:101E600002170038007C1004021700040000000F65 +:101E70000616402400000002021640700000001CFC +:101E80000216420800000001021642100000000184 +:101E90000216422000000001021642280000000144 +:101EA0000216423000000001021642380000000114 +:101EB00002164260000000020C16401C0003D09085 +:101EC0000A16401C0000009C0B16401C000009C4B0 +:101ED0000216403000000008021640340000000CDA +:101EE0000216403800000010021640440000002096 +:101EF0000216400000000001021640D80000000158 +:101F000002164008000000010216400C000000010B +:101F100002164010000000010216424000000000BE +:101F2000021642480000000006164270000000023F +:101F30000216425000000000021642580000000045 +:101F40000616428000000002021660080000042409 +:101F50000216600C00000410021660100000041449 +:101F60000216601C0000FFFF021660200000FFFF49 +:101F7000021660240000FFFF021660280000FFFF29 +:101F800002166038000000200216603C00000020AD +:101F90000216604000000034021660440000003564 +:101FA00002166048000000230216604C0000002466 +:101FB0000216605000000025021660540000002642 +:101FC00002166058000000270216605C000000291D +:101FD000021660600000002A021660640000002BF8 +:101FE000021660680000002C0216606C0000002DD4 +:101FF0000616607000000052021661B80000000171 +:10200000061661BC0000001F0216623807FFFFFFC2 +:102010000216623C0000003F0216624007FFFFFF0D +:10202000021662440000000F011662480000000022 +:102030000116624C00000000011662500000000012 +:1020400001166254000000000116625800000000F2 +:102050000116625C000000000116626000000000D2 +:1020600001166264000000000116626800000000B2 +:102070000116626C00000000011662700000000092 +:102080000116627400000000011662780000000072 +:102090000116627C000000000C166000000003E8DE +:1020A0000A166000000000010B1660000000000A24 +:1020B0000216804000000006021680440000000561 +:1020C000021680480000000A0216804C000000053D +:1020D0000216805400000002021680CC00000004AA +:1020E000021680D000000004021680D40000000414 +:1020F000021680D800000004021680DC00000004F4 +:10210000021680E000000004021680E400000004D3 +:10211000021680E800000004021688040000000493 +:10212000021680300000007C021680340000003D62 +:10213000021680380000003F0216803C0000009C20 +:10214000021680F000000007061680F4000000056B +:102150000216880C0101010102168108000000002E +:102160000216810C00000004021681100000000419 +:1021700002168114000000020216881008012004D3 +:1021800002168118000000050216811C00000005DF +:1021900002168120000000050216812400000005BF +:1021A0000216882C20081001021681280000000861 +:1021B0000216812C00000006021681300000000784 +:1021C000021681340000000002168830010101204F +:1021D000061681380000000402168834010101014E +:1021E00002168148000000000216814C0000000425 +:1021F0000216815000000004021681540000000203 +:1022000002168838080120040216815800000005D3 +:102210000216815C000000050216816000000005C6 +:1022200002168164000000050216883C2008100197 +:1022300002168168000000080216816C000000068A +:102240000216817000000007021681740000000170 +:102250000216884001010120021681780000000169 +:102260000216817C0000000102168180000000013E +:102270000216818400000001021688440101010158 +:1022800002168188000000010216818C0000000403 +:1022900002168190000000040216819400000002E2 +:1022A00002168848080120040216819800000005E3 +:1022B0000216819C00000005021681A000000005A6 +:1022C000021681A4000000050216881420081001DF +:1022D000021681A800000008021681AC000000066A +:1022E000021681B000000007021681B40000000150 +:1022F0000216881801010120021681B800000001B1 +:10230000021681BC00000001021681C0000000011D +:10231000021681C4000000010216881C010101019F +:10232000021681C800000001021681CC00000004E2 +:10233000021681D000000004021681D400000002C1 +:102340000216882008012004021681D8000000052A +:10235000021681DC00000005021681E00000000585 +:10236000021681E4000000050216882420081001EE +:10237000021681E800000008021681EC0000000649 +:10238000021681F0000000070216E40C00000000B5 +:1023900002168828010101200616E410000000043E +:1023A0000216E000010101010216E4200000000015 +:1023B0000216E424000000040216E42800000004D1 +:1023C0000216E42C000000020216E00408012004BA +:1023D0000216E430000000050216E4340000000597 +:1023E0000216E438000000050216E43C0000000577 +:1023F0000216E008200810010216E4400000000860 +:102400000216E444000000060216E448000000073B +:102410000216E44C000000000216E00C010101204D +:102420000616E450000000040216E010010101014C +:102430000216E460000000000216E46400000004DC +:102440000216E468000000040216E46C00000002BA +:102450000216E014080120040216E47000000005D2 +:102460000216E474000000050216E478000000057E +:102470000216E47C000000050216E0182008100196 +:102480000216E480000000080216E4840000000642 +:102490000216E488000000070216E48C0000000128 +:1024A0000216E01C010101200216E4900000000168 +:1024B0000216E494000000010216E49800000001F6 +:1024C0000216E49C000000010216E0200101010157 +:1024D0000216E4A0000000010216E4A400000004BB +:1024E0000216E4A8000000040216E4AC000000029A +:1024F0000216E024080120040216E4B000000005E2 +:102500000216E4B4000000050216E4B8000000055D +:102510000216E4BC000000050216E02820081001A5 +:102520000216E4C0000000080216E4C40000000621 +:102530000216E4C8000000070216E4CC0000000107 +:102540000216E02C010101200216E4D00000000177 +:102550000216E4D4000000010216E4D800000001D5 +:102560000216E4DC000000010216E0300101010166 +:102570000216E4E0000000010216E4E4000000049A +:102580000216E4E8000000040216E4EC0000000279 +:102590000216E034080120040216E4F000000005F1 +:1025A0000216E4F4000000050216E4F8000000053D +:1025B0000216E4FC000000050216E03820081001B5 +:1025C0000216E500000000080216E50400000006FF +:1025D0000216E508000000070216E03C0101012098 +:1025E00002168240003F003F0216824400000000B5 +:1025F0000216E524003F003F0216E5280000000017 +:1026000002168248000000000216824C003F003F84 +:102610000216E52C000000000216E530003F003FE6 +:1026200002168250010001000216825401000100CE +:102630000216E534010001000216E5380100010030 +:1026400006168258000000020216E53C0000000059 +:102650000216E540000000000216826000C000C0C3 +:102660000216826400C000C00216E54400C000C02B +:102670000216E54800C000C0021682681E001E0057 +:102680000216826C1E001E000216E54C1E001E0083 +:102690000216E5501E001E00021682704000400027 +:1026A00002168274400040000216E55440004000CB +:1026B0000216E55840004000021682788000800033 +:1026C0000216827C800080000216E55C800080009B +:1026D0000216E56080008000021682802000200043 +:1026E00002168284200020000216E56420002000EB +:1026F0000216E5682000200006168288000000020D +:102700000216E56C000000000216E57000000000F3 +:102710000216829000000000021682940000000061 +:102720000216E574000000000216E57800000000C3 +:1027300002168298000000000216829C0000000031 +:102740000216E57C000000000216E5800000000093 +:10275000021682A000000000021682A40000000100 +:10276000061682A80000000A021681F400000C0878 +:10277000021681F800000040021681FC00000100F2 +:1027800002168200000000200216820400000017DA +:1027900002168208000000800216820C000002006F +:1027A00002168210000000000216821801FF01FFCD +:1027B0000216821401FF01FF0216E51001FF01FF5E +:1027C0000216E50C01FF01FF0216823C0000001317 +:1027D000021680900000013F021680600000014058 +:1027E00002168064000001400616806800000002A6 +:1027F00002168070000000C00616807400000007FA +:102800000216809C00000048021680A000000048CC +:10281000061680A400000002021680AC00000048EA +:10282000061680B000000007021682380000800003 +:1028300002168234000025E40216809400007FFF17 +:1028400002168220000F000F0216821C000F000FDC +:102850000216E518000F000F0216E514000F000F16 +:10286000021682280000000002168224FFFFFFFFEC +:102870000216E520000000000216E51CFFFFFFFF26 +:102880000216E6BC000000000216E6C000000002CE +:102890000216E6C4000000010216E6C800000003AC +:1028A0000216E6CC000000040216E6D00000000686 +:1028B0000216E6D4000000050216E6D80000000764 +:1028C000021680EC000000FF02140000000000016E +:1028D0000214000C0000000102140040000000017E +:1028E0000214004400007FFF0214000C00000000EE +:1028F00002140000000000000214006C0000000040 +:102900000214000400000001021400300000000165 +:1029100002140004000000000214005C000000002B +:10292000021400080000000102140034000000013D +:102930000214000800000000021400600000000003 +:102940000202005800000032020200A0031500201D +:10295000020200A403150020020200A801000030BA +:10296000020200AC08100000020200B000000033B8 +:10297000020200B400000030020200B80000003182 +:10298000020200BC00000003020200C000000006BA +:10299000020200C400000003020200C8000000039D +:1029A000020200CC00000002020200D00000000081 +:1029B000020200D400000002020200DC000000005D +:1029C000020200E000000006020200E40000000431 +:1029D000020200E800000002020200EC0000000217 +:1029E000020200F000000001020200FC00000006EC +:1029F0000202012000000000020201340000000277 +:102A0000020201B0000000010202020C00000001FD +:102A1000020202140000000102020218000000027B +:102A200002020404000000010202040C0000004045 +:102A300002020410000000400202041C0000000416 +:102A40000202042000000020020204240000000210 +:102A50000202042800000020060205000000001207 +:102A600004020480001F032A020200600000000F1D +:102A70000202006400000007020200680000000B70 +:102A80000202006C0000000E020200700000000E46 +:102A90000602007400000003020200F400000004BB +:102AA0000202000400000001020200080000000110 +:102AB0000202000C000000010202001000000001F0 +:102AC00002020014000000010202001800000001D0 +:102AD0000202001C000000010202002000000001B0 +:102AE0000202002400000001020200280000000190 +:102AF0000202002C00000001020200300000000170 +:102B0000020200340000000102020038000000014F +:102B10000202003C0000000102020040000000012F +:102B2000020200440000000102020048000000010F +:102B30000202004C000000010202005000000001EF +:102B400002020108000000C8020201180000000291 +:102B5000020201C400000000020201CC00000000DB +:102B6000020201D400000002020201DC00000002A7 +:102B7000020201E4000000FF020201EC000000FF7D +:102B800002020100000000000202010C000000C867 +:102B90000202011C00000002020201C80000000045 +:102BA000020201D000000000020201D80000000271 +:102BB000020201E000000002020201E8000000FF42 +:102BC000020201F0000000FF020201040000000008 +:102BD00002020108000000C8020201180000000201 +:102BE000020201C400000000020201CC000000004B +:102BF000020201D400000002020201DC0000000217 +:102C0000020201E4000000FF020201EC000000FFEC +:102C100002020100000000000202010C000000C8D6 +:102C20000202011C00000002020201C800000000B4 +:102C3000020201D000000000020201D800000002E0 +:102C4000020201E000000002020201E8000000FFB1 +:102C5000020201F0000000FF020201040000000077 +:102C600002020108000000C8020201180000000270 +:102C7000020201C400000000020201CC00000000BA +:102C8000020201D400000002020201DC0000000286 +:102C9000020201E4000000FF020201EC000000FF5C +:102CA00002020100000000000202010C000000C846 +:102CB0000202011C00000002020201C80000000024 +:102CC000020201D000000000020201D80000000250 +:102CD000020201E000000002020201E8000000FF21 +:102CE000020201F0000000FF0202010400000000E7 +:102CF00002020108000000C80202011800000002E0 +:102D0000020201C400000000020201CC0000000029 +:102D1000020201D400000002020201DC00000002F5 +:102D2000020201E4000000FF020201EC000000FFCB +:102D300002020100000000000202010C000000C8B5 +:102D40000202011C00000002020201C80000000093 +:102D5000020201D000000000020201D800000002BF +:102D6000020201E000000002020201E8000000FF90 +:102D7000020201F0000000FF020201040000000056 +:102D80000728040000C00000082807A8000B03491A +:102D9000072C000032FC0000072C800035780CC0A6 +:102DA000072D00003AC11A1F072D800039E228D0F4 +:102DB000072E00001C3E3749082E3710391E034BE2 +:102DC00001280000000000000128000400000000AD +:102DD00001280008000000000128000C000000008D +:102DE000012800100000000001280014000000006D +:102DF0000228002000000001022800240000000238 +:102E000002280028000000030228002C0000000017 +:102E100002280030000000040228003400000001F5 +:102E200002280038000000000228003C00000001D9 +:102E300002280040000000040228004400000000B6 +:102E400002280048000000010228004C0000000396 +:102E50000228005000000000022800540000000179 +:102E600002280058000000040228005C0000000056 +:102E70000228006000000001022800640000000336 +:102E800002280068000000000228006C0000000119 +:102E900002280070000000040228007400000000F6 +:102EA00002280078000000040228007C00000003D3 +:102EB0000628008000000002022800A400003FFF56 +:102EC000022800A8000003FF0228022400000000DE +:102ED00002280234000000000228024C000000001A +:102EE000022802E40000FFFF06282000000008007E +:102EF000022B8BC000000001022B800000000000AC +:102F0000022B804000000018022B80800000000C83 +:102F1000022B80C0000000660C2B83000007A1205C +:102F20000A2B8300000001380B2B8300000013885C +:102F3000022B83C0000001F40C2B8340000001F43D +:102F40000A2B8340000000000B2B8340000000058B +:102F50000A2B83800004C4B40C2B83801DCD650034 +:102F60000A2B1480000000000B2B8380004C4B4088 +:102F7000022B148000000001062A29C8000000046A +:102F8000042A29D80002034D062A208000000048A8 +:102F9000062A9020000000C8062A900000000002C7 +:102FA000062A21A800000086062A20000000002032 +:102FB000022A23C800000000042A23D00002034F85 +:102FC000042A249800040351022A2C500000000017 +:102FD000022A2C1000000000042A2C0800020355CD +:102FE000042A300000020357062A300800000100BE +:102FF000062A404000000010042A40000010035937 +:10300000062A6AC000000002062A6B0000000004C5 +:10301000042A840800020369022B08000000000053 +:10302000042B0C000010036B022B080001000000B1 +:10303000042B0C400008037B022B08000200000058 +:10304000042B0C6000080383062AC000000000D88F +:10305000062A24A800000014062A254800000022A1 +:10306000042A25D00002038B062A266800000022CD +:10307000042A26F00002038D062A27880000002279 +:10308000042A28100002038F062A28A80000002224 +:10309000042A293000020391062AA000000000281B +:1030A000062AA1400000000C042A29E00002039334 +:1030B000062A502000000002062A503000000002BC +:1030C000062A500000000002062A501000000002EC +:1030D000022A520800000001042A6AC8000203956F +:1030E000062A6B1000000042062A6D200000000432 +:1030F000062ABCD000000002062AC360000000D8E7 +:10310000062A24F800000014062A25D80000002210 +:10311000042A266000020397062A26F800000022EF +:10312000042A278000020399062A2818000000229A +:10313000042A28A00002039B062A29380000002246 +:10314000042A29C00002039D062AA0A0000000282E +:10315000062AA1700000000C042A29E80002039F3F +:10316000062A502800000002062A503800000002FB +:10317000062A500800000002062A5018000000022B +:10318000022A520C00000001042A6AD0000203A1A6 +:10319000062A6C1800000042062A6D300000000468 +:1031A000062ABCD800000002022AC6C000000000A7 +:1031B000042A29F0001003A3062A50480000000E3C +:1031C000062AB00000000006022AC6C40000000063 +:1031D000042A2A30001003B3062A50800000000E93 +:1031E000062AB01800000006022AC6C80000000027 +:1031F000042A2A70001003C3062A50B80000000EEB +:10320000062AB03000000006022AC6CC00000000EA +:10321000042A2AB0001003D3062A50F00000000E42 +:10322000062AB04800000006022AC6D000000000AE +:10323000042A2AF0001003E3062A51280000000E99 +:10324000062AB06000000006022AC6D40000000072 +:10325000042A2B30001003F3062A51600000000EF0 +:10326000062AB07800000006022AC6D80000000036 +:10327000042A2B7000100403062A51980000000E47 +:10328000062AB09000000006022AC6DC00000000FA +:10329000042A2BB000100413062A51D00000000E9F +:1032A000062AB0A800000006021010080000000165 +:1032B0000210105000000001021010000003D000A6 +:1032C000021010040000003D091018000200042341 +:1032D0000910110000280623061011A00000001894 +:1032E00006102400000000E00210201C0000000076 +:1032F0000210202000000001021020C00000000287 +:10330000021020040000000102102008000000014B +:1033100009103C000005064B091038000005065056 +:10332000091038200005065506104C000000010069 +:1033300002104028000000100210404400003FFF2F +:103340000210405800280000021040840084924A75 +:1033500002104058000000000210800000001080A1 +:10336000021080AC00000000021080380000001045 +:103370000210810000000000061081200000000201 +:1033800002108008000002B502108010000000004A +:10339000061082000000004A021081080001FFFFB1 +:1033A00006108140000000020210800000001A8018 +:1033B0000610900000000024061091200000004A32 +:1033C000061093700000004A061095C00000004AE5 +:1033D0000210800400001080021080B00000000184 +:1033E0000210803C00000010021081040000000068 +:1033F00006108128000000020210800C000002B5B7 +:103400000210801400000000061084000000004A32 +:103410000210810C0001FFFF06108148000000022D +:103420000210800400001A80061090900000002412 +:10343000061092480000004A061094980000004AC6 +:10344000061096E80000004A02108000000010807C +:10345000021080AC00000002021080380000001052 +:103460000210810000000000061081200000000210 +:1034700002108008000002B5021080100000000059 +:10348000061082000000004A021081080001FFFFC0 +:1034900006108140000000020210800000001A8027 +:1034A0000610900000000024061091200000004A41 +:1034B000061093700000004A061095C00000004AF4 +:1034C0000210800400001080021080B00000000391 +:1034D0000210803C00000010021081040000000077 +:1034E00006108128000000020210800C000002B5C6 +:1034F0000210801400000000061084000000004A42 +:103500000210810C0001FFFF06108148000000023C +:103510000210800400001A80061090900000002421 +:10352000061092480000004A061094980000004AD5 +:10353000061096E80000004A02108000000010808B +:10354000021080AC0000000402108038000000105F +:10355000021081000000000006108120000000021F +:1035600002108008000002B5021080100000000068 +:10357000061082000000004A021081080001FFFFCF +:1035800006108140000000020210800000001A8036 +:103590000610900000000024061091200000004A50 +:1035A000061093700000004A061095C00000004A03 +:1035B0000210800400001080021080B0000000059E +:1035C0000210803C00000010021081040000000086 +:1035D00006108128000000020210800C000002B5D5 +:1035E0000210801400000000061084000000004A51 +:1035F0000210810C0001FFFF06108148000000024C +:103600000210800400001A80061090900000002430 +:10361000061092480000004A061094980000004AE4 +:10362000061096E80000004A02108000000010809A +:10363000021080AC0000000602108038000000106C +:10364000021081000000000006108120000000022E +:1036500002108008000002B5021080100000000077 +:10366000061082000000004A021081080001FFFFDE +:1036700006108140000000020210800000001A8045 +:103680000610900000000024061091200000004A5F +:10369000061093700000004A061095C00000004A12 +:1036A0000210800400001080021080B000000007AB +:1036B0000210803C00000010021081040000000095 +:1036C00006108128000000020210800C000002B5E4 +:1036D0000210801400000000061084000000004A60 +:1036E0000210810C0001FFFF06108148000000025B +:1036F0000210800400001A80061090900000002440 +:10370000061092480000004A061094980000004AF3 +:10371000061096E80000004A021205B00000000101 +:103720000212049000E383400212051400003C10D2 +:103730000212066C00000001021206700000000078 +:1037400002120494FFFFFFFF02120498FFFFFFFF25 +:103750000212049CFFFFFFFF021204A0FFFFFFFF05 +:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5 +:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5 +:10378000021204BCFFFFFFFF021204C0FFFFFFFF95 +:10379000021204C4FFFFFFFF021204C8FFFFFFFF75 +:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55 +:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D +:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D +:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED +:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD +:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD +:1038000002120500FFFFFFFF02120504FFFFFFFF8A +:1038100002120508FFFFFFFF0212050CFFFFFFFF6A +:1038200002120510FFFFFFFF021204D4FF802000E8 +:10383000021204B4F0005000021204B8F0001000AC +:1038400002120390000000080212039C000000080E +:10385000021203A000000008021203A400000002EC +:10386000021203BC00000004021203C000000005A5 +:10387000021203C400000004021203D00000000082 +:103880000212036C00000001021203680000003FF6 +:10389000021201BC00000040021201C00000180822 +:1038A000021201C400000803021201C8000008034C +:1038B000021201CC00000040021201D000000003FF +:1038C000021201D400000803021201D8000008030C +:1038D000021201DC00000803021201E000010003F3 +:1038E000021201E400000803021201E800000803CC +:1038F000021201EC00000003021201F000000003BC +:10390000021201F400000003021201F8000000039B +:10391000021201FC0000000302120200000000037A +:103920000212020400000003021202080000000359 +:103930000212020C00000003021202100000000339 +:103940000212021400000003021202180000000319 +:103950000212021C000000030212022000000003F9 +:1039600002120224000000030212022800002403B5 +:103970000212022C0000002F021202300000000987 +:103980000212023400000019021202380000018401 +:103990000212023C000001830212024000000306F2 +:1039A0000212024400000019021202480000000640 +:1039B0000212024C0000030602120250000003062D +:1039C00002120254000003060212025800000C8684 +:1039D0000212025C000003060212026000000306ED +:1039E00002120264000000060212026800000006D3 +:1039F0000212026C000000060212027000000006B3 +:103A00000212027400000006021202780000000692 +:103A10000212027C00000006021202800000000672 +:103A20000212028400000006021202880000000652 +:103A30000212028C00000006021202900000000632 +:103A40000212029400000006021202980000000612 +:103A50000212029C00000006021202A000000306EF +:103A6000021202A400000013021202A800000006C5 +:103A7000021202B000001004021202B4000010048E +:103A80000212032400106440021203280010644054 +:103A9000021205B400000001021201B00000000192 +:103AA0000600A000000000160200A0EC5554000023 +:103AB0000200A0F0555555550200A0F400005555E0 +:103AC0000200A0F8F00000000200A0FC5554000025 +:103AD0000200A100555555550200A104000055559E +:103AE0000200A108F00000000200A18C5554000063 +:103AF0000200A190555555550200A194000055555E +:103B00000200A198F00000000200A19C000000004B +:103B10000200A1A0000100000200A1A400005014B6 +:103B20000200A1A8000000000200A45C00000C003C +:103B30000200A61C000000030200A06CFF5C000055 +:103B40000200A070FFF55FFF0200A0740000FFFFFD +:103B50000200A078F00003E00200A07C000000005A +:103B60000200A0800000A0000600A0840000000564 +:103B70000200A0980FE000000600A09C00000007D3 +:103B80000200A0B8000004000600A0BC0000000372 +:103B90000200A0C8000010000600A0CC0000000336 +:103BA0000200A0D8000040000600A0DC00000003D6 +:103BB0000200A0E8000100000600A22C00000004A2 +:103BC0000200A10CFF5C00000200A110FFF55FFFE6 +:103BD0000200A1140000FFFF0200A118F00003E0A2 +:103BE0000200A11C000000000200A1200000A000B3 +:103BF0000600A124000000050200A1380FE000002B +:103C00000600A13C000000070200A15800000800C7 +:103C10000600A15C000000030200A1680000200073 +:103C20000600A16C000000030200A17800008000E3 +:103C30000600A17C000000030200A1880002000031 +:103C40000600A23C0000000400000000000000008C +:103C50000000003100000000000000000000000033 +:103C60000000000000000000000000000000000054 +:103C700000000000000000000000000000310032E1 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA000000000000000000000320056000000008C +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD000000000000056008C000000000000000002 +:103CE000008C009000900094009400980098009C34 +:103CF000009C00A000A000A400A400A800A800ACA4 +:103D000000AC00B100B100B300B300B5000000008A +:103D100000000000000000000000000000000000A3 +:103D200000000000000000000000000000B50102DB +:103D30000102010A010A01120112011B011B0124E7 +:103D40000124012D012D01360136013F013F0148BB +:103D5000014801510151015A00000000000000001B +:103D60000000000000000000000000000000000053 +:103D70000000000000000000000000000000000043 +:103D80000000000000000000000000000000000033 +:103D90000000000000000000000000000000000023 +:103DA0000000000000000000000000000000000013 +:103DB0000000000000000000000000000000000003 +:103DC00000000000000000000000000000000000F3 +:103DD00000000000000000000000000000000000E3 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E00000000000000000000015A015F00000000F7 +:103E100000000000015F0160016001610161016259 +:103E2000016201630163016401640165016501666A +:103E300001660167000000000000000000000000B3 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E60000167016C016C0179017901860000000095 +:103E70000000000000000000000000000000000042 +:103E80000000000000000000000000000000000032 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB00000000000000000000186018700000000F3 +:103EC00000000000000000000000000000000000F2 +:103ED00000000000000000000000000000000000E2 +:103EE00000000000018701BE00000000000000008B +:103EF00000000000000000000000000000000000C2 +:103F000000000000000000000000000000000000B1 +:103F100001BE01E9000000000000000000000000F8 +:103F20000000000000000000000000000000000091 +:103F300000000000000000000000000001E9021A7B +:103F40000000000000000000021A022102210228E5 +:103F50000228022F022F02360236023D023D0244A1 +:103F60000244024B024B02520252028A000000003D +:103F700000000000028A028E028E029202920296D5 +:103F80000296029A029A029E029E02A202A202A631 +:103F900002A602AA02AA02FA02FA031103110328D6 +:103FA0000328032B032B032E032E03310331033489 +:103FB000033403370337033A033A033D033D034019 +:103FC00003400381038103880388038F038F0393D6 +:103FD000039303970397039B039B039F039F03A3F1 +:103FE00003A303A703A703AB03AB03AF03AF03B064 +:103FF00000000000000000000000000000000000C1 +:1040000000000000000000000000000000000000B0 +:10401000000000000000000003B003C20000000028 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:104040000000000003C203D703D703DA03DA03DD5D +:104050000000000000000000000000000000000060 +:104060000000000000000000000000000000000050 +:1040700003DD040A00000000000000000000000052 +:104080000000000000000000000000000000000030 +:10409000000000000000000000000000040A050D00 +:1040A0000000000000000000000000000000000010 +:1040B0000000000000000000000000000000000000 +:1040C0000000000000000000050D0514051405188F +:1040D0000518051C000000000000000000000000A2 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000051C055C00000000000000003E +:10410000055C05650565056E056E05770577058017 +:1041100005800589058905920592059B059B05A4E7 +:1041200005A405FD05FD0613061306290629062D1F +:10413000062D063106310635063506390639063DA7 +:10414000063D064106410645064506490649065014 +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:10417000000000000000000006500656000000008D +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A0000000000006560659000000000000000054 +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000000000000EF +:1041D0000659065F0000000000000000000000001B +:1041E00000000000000000000000000000000000CF +:1041F00000000000000000000000000000000000BF +:104200000000000000000000065F066E066E067DDE +:10421000067D068C068C069B069B06AA06AA06B996 +:1042200006B906C806C806D706D70748000000002A +:10423000000000000000000000000000000000007E +:10424000000000000000000000000000000000006E +:10425000000000000748075B075B076C076C077DE1 +:10426000000000000000000000000000000000004E +:10427000000000000000000000000000000000003E +:10428000000000000000000000000000000000002E +:10429000000000000000000000000000000000001E +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000010000000204C00003098000040E4029 +:1042F00000051300000617C000071C8000082140BD +:1043000000092600000A2AC0000B2F80000C344050 +:10431000000D3900000E3DC0000F428000104740E4 +:1043200000114C00001250C00013558000145A4078 +:1043300000155F00001663C00017688000186D400C +:1043400000197200001A76C0001B7B80001C8040A0 +:10435000001D8500001E89C0001F8E800020934034 +:10436000000020000000400000006000000080000D +:104370000000A0000000C0000000E00000010000FC +:1043800000012000000140000001600000018000E9 +:104390000001A0000001C0000001E00000020000D8 +:1043A00000022000000240000002600000028000C5 +:1043B0000002A0000002C0000002E00000030000B4 +:1043C00000032000000340000003600000038000A1 +:1043D0000003A0000003C0000003E0000004000090 +:1043E000000420000004400000046000000480007D +:1043F0000004A0000004C0000004E000000500006C +:104400000005200000054000000560000005800058 +:104410000005A0000005C0000005E0000006000047 +:104420000006200000064000000660000006800034 +:104430000006A0000006C0000006E0000007000023 +:104440000007200000074000000760000007800010 +:104450000007A0000007C0000007E00000080000FF +:1044600000082000000840000008600000088000EC +:104470000008A0000008C0000008E00000090000DB +:1044800000092000000940000009600000098000C8 +:104490000009A0000009C0000009E000000A0000B7 +:1044A000000A2000000A4000000A6000000A8000A4 +:1044B000000AA000000AC000000AE000000B000093 +:1044C000000B2000000B4000000B6000000B800080 +:1044D000000BA000000BC000000BE000000C00006F +:1044E000000C2000000C4000000C6000000C80005C +:1044F000000CA000000CC000000CE000000D00004B +:10450000000D2000000D4000000D6000000D800037 +:10451000000DA000000DC000000DE000000E000026 +:10452000000E2000000E4000000E6000000E800013 +:10453000000EA000000EC000000EE000000F000002 +:10454000000F2000000F4000000F6000000F8000EF +:10455000000FA000000FC000000FE00000100000DE +:1045600000102000001040000010600000108000CB +:104570000010A0000010C0000010E00000110000BA +:1045800000112000001140000011600000118000A7 +:104590000011A0000011C0000011E0000012000096 +:1045A0000012200000124000001260000012800083 +:1045B0000012A0000012C0000012E0000013000072 +:1045C000001320000013400000136000001380005F +:1045D0000013A0000013C0000013E000001400004E +:1045E000001420000014400000146000001480003B +:1045F0000014A0000014C0000014E000001500002A +:104600000015200000154000001560000015800016 +:104610000015A0000015C0000015E0000016000005 +:1046200000162000001640000016600000168000F2 +:104630000016A0000016C0000016E00000170000E1 +:1046400000172000001740000017600000178000CE +:104650000017A0000017C0000017E00000180000BD +:1046600000182000001840000018600000188000AA +:104670000018A0000018C0000018E0000019000099 +:104680000019200000194000001960000019800086 +:104690000019A0000019C0000019E000001A000075 +:1046A000001A2000001A4000001A6000001A800062 +:1046B000001AA000001AC000001AE000001B000051 +:1046C000001B2000001B4000001B6000001B80003E +:1046D000001BA000001BC000001BE000001C00002D +:1046E000001C2000001C4000001C6000001C80001A +:1046F000001CA000001CC000001CE000001D000009 +:10470000001D2000001D4000001D6000001D8000F5 +:10471000001DA000001DC000001DE000001E0000E4 +:10472000001E2000001E4000001E6000001E8000D1 +:10473000001EA000001EC000001EE000001F0000C0 +:10474000001F2000001F4000001F6000001F8000AD +:10475000001FA000001FC000001FE000002000009C +:104760000020200000204000002060000020800089 +:104770000020A0000020C0000020E0000021000078 +:104780000021200000214000002160000021800065 +:104790000021A0000021C0000021E0000022000054 +:1047A0000022200000224000002260000022800041 +:1047B0000022A0000022C0000022E0000023000030 +:1047C000002320000023400000236000002380001D +:1047D0000023A0000023C0000023E000002400000C +:1047E00000242000002440000024600000248000F9 +:1047F0000024A0000024C0000024E00000250000E8 +:1048000000252000002540000025600000258000D4 +:104810000025A0000025C0000025E00000260000C3 +:1048200000262000002640000026600000268000B0 +:104830000026A0000026C0000026E000002700009F +:10484000002720000027400000276000002780008C +:104850000027A0000027C0000027E000002800007B +:104860000028200000284000002860000028800068 +:104870000028A0000028C0000028E0000029000057 +:104880000029200000294000002960000029800044 +:104890000029A0000029C0000029E000002A000033 +:1048A000002A2000002A4000002A6000002A800020 +:1048B000002AA000002AC000002AE000002B00000F +:1048C000002B2000002B4000002B6000002B8000FC +:1048D000002BA000002BC000002BE000002C0000EB +:1048E000002C2000002C4000002C6000002C8000D8 +:1048F000002CA000002CC000002CE000002D0000C7 +:10490000002D2000002D4000002D6000002D8000B3 +:10491000002DA000002DC000002DE000002E0000A2 +:10492000002E2000002E4000002E6000002E80008F +:10493000002EA000002EC000002EE000002F00007E +:10494000002F2000002F4000002F6000002F80006B +:10495000002FA000002FC000002FE000003000005A +:104960000030200000304000003060000030800047 +:104970000030A0000030C0000030E0000031000036 +:104980000031200000314000003160000031800023 +:104990000031A0000031C0000031E0000032000012 +:1049A00000322000003240000032600000328000FF +:1049B0000032A0000032C0000032E00000330000EE +:1049C00000332000003340000033600000338000DB +:1049D0000033A0000033C0000033E00000340000CA +:1049E00000342000003440000034600000348000B7 +:1049F0000034A0000034C0000034E00000350000A6 +:104A00000035200000354000003560000035800092 +:104A10000035A0000035C0000035E0000036000081 +:104A2000003620000036400000366000003680006E +:104A30000036A0000036C0000036E000003700005D +:104A4000003720000037400000376000003780004A +:104A50000037A0000037C0000037E0000038000039 +:104A60000038200000384000003860000038800026 +:104A70000038A0000038C0000038E0000039000015 +:104A80000039200000394000003960000039800002 +:104A90000039A0000039C0000039E000003A0000F1 +:104AA000003A2000003A4000003A6000003A8000DE +:104AB000003AA000003AC000003AE000003B0000CD +:104AC000003B2000003B4000003B6000003B8000BA +:104AD000003BA000003BC000003BE000003C0000A9 +:104AE000003C2000003C4000003C6000003C800096 +:104AF000003CA000003CC000003CE000003D000085 +:104B0000003D2000003D4000003D6000003D800071 +:104B1000003DA000003DC000003DE000003E000060 +:104B2000003E2000003E4000003E6000003E80004D +:104B3000003EA000003EC000003EE000003F00003C +:104B4000003F2000003F4000003F6000003F800029 +:104B5000003FA000003FC000003FE000003FE00138 +:104B600000000000000001FF0000020000007FF8CC +:104B700000007FF800000CDF0000150000000001BD +:104B80000000000100000001FFFFFFFFFFFFFFFF2B +:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 +:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 +:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 +:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 +:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 +:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0 +:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0 +:104C200000000000FFFFFFFF00000000FFFFFFFF8C +:104C3000FFFFFFFF00000000FFFFFFFF000000007C +:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF +:104C500000000000FFFFFFFF00000000FFFFFFFF5C +:104C60000000000300BEBC20FFFFFFFF00000000AB +:104C7000FFFFFFFF00000000FFFFFFFF0000000339 +:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92 +:104C900000000000FFFFFFFF0000000300BEBC207B +:104CA000FFFFFFFF00000000FFFFFFFF000000000C +:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F +:104CC00000000000FFFFFFFF00000000FFFFFFFFEC +:104CD0000000000300BEBC2000002000000040C017 +:104CE00000006180000082400000A3000000C3C0FB +:104CF0000000E4800001054000012600000146C0DC +:104D000000016780000188400001A9000001C9C0BE +:104D10000001EA8000020B4000022C0000024CC09F +:104D200000026D8000028E400002AF000002CFC082 +:104D30000002F0800003114000033200000352C063 +:104D400000037380000394400003B5000003D5C046 +:104D50000003F6800004174000043800000458C027 +:104D60000004798000049A40000080000001038064 +:104D70000001870000020A8000028E0000031180FB +:104D8000000395000004188000049C0000051F80AB +:104D90000005A300000626800006AA0000072D805B +:104DA0000007B100000834800008B80000093B800B +:104DB0000009BF00000A4280000AC600000B4980BB +:104DC000000BCD00000C5080000CD400000D57806B +:104DD000000DDB0000007FF800007FF80000192ABA +:104DE0000000350000001900001000000000000065 +:104DF00000000000FFFFFFFF400000004000000037 +:104E000040000000400000004000000040000000A2 +:104E10004000000040000000400000004000000092 +:104E20004000000040000000400000004000000082 +:104E30004000000040000000400000004000000072 +:104E40004000000040000000400000004000000062 +:104E50004000000040000000400000004000000052 +:104E60004000000040000000400000004000000042 +:104E7000400000004000000000007FF800007FF8C4 +:104E8000000005C700001500FFFFFFFFFFFFFFFF49 +:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 +:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 +:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 +:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 +:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 +:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 +:104F0000FFFFFFFFFFFFFFFF400000004000000029 +:104F10004000000040000000400000004000000091 +:104F20004000000040000000400000004000000081 +:104F30004000000040000000400000004000000071 +:104F40004000000040000000400000004000000061 +:104F50004000000040000000400000004000000051 +:104F60004000000040000000400000004000000041 +:104F70004000000040000000400000004000000031 +:104F800040000000400000000000100000002080F1 +:104F900000003100000041800000520000006280EB +:104FA0000000730000008380000094000000A480D3 +:104FB0000000B5000000C5800000D6000000E680BB +:104FC0000000F700000107800001180000012880A0 +:104FD000000139000001498000015A0000016A8087 +:104FE00000017B0000018B8000019C000001AC806F +:104FF0000001BD000001CD800001DE000001EE8057 +:105000000001FF0000007FF800007FF80000112E73 +:105010000000350010000000000028AD0000000076 +:1050200000010001000D0205CCCCCCC5FFFFFFFF45 +:10503000FFFFFFFF7058103C000000000000000060 +:1050400000000001CCCC0201CCCCCCCCCCCC0201F9 +:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA +:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA +:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A +:10508000CCCCCCCC00000000FFFFFFFF40000000B4 +:105090004000000040000000400000004000000010 +:1050A0004000000040000000400000004000000000 +:1050B00040000000400000004000000040000000F0 +:1050C00040000000400000004000000040000000E0 +:1050D00040000000400000004000000040000000D0 +:1050E00040000000400000004000000040000000C0 +:1050F00040000000400000004000000040000000B0 +:10510000400000004000000040000000002625A0F4 +:1051100000000000002625A000000000002625A0B9 +:1051200000000000002625A000000000000E023252 +:10513000011600D60010000000000000002625A087 +:1051400000000000002625A000000000002625A089 +:1051500000000000002625A00000000000720236BA +:10516000012300F300100000000000000000FFFF1A +:10517000000000000000FFFF000000000000FFFF33 +:10518000000000000000FFFF000000000000FFFF23 +:10519000000000000000FFFF000000000000FFFF13 +:1051A000000000000000FFFF000000000000FFFF03 +:1051B000000000000000FFFF000000000000FFFFF3 +:1051C000000000000000FFFF000000000000FFFFE3 +:1051D000000000000000FFFF000000000000FFFFD3 +:1051E000000000000000FFFF000000000000FFFFC3 +:1051F000000000000000FFFF000000000000FFFFB3 +:10520000000000000000FFFF000000000000FFFFA2 +:10521000000000000000FFFF000000000000FFFF92 +:10522000000000000000FFFF000000000000FFFF82 +:10523000000000000000FFFF000000000000FFFF72 +:10524000000000000000FFFF000000000000FFFF62 +:10525000000000000000FFFF000000000000FFFF52 +:10526000000000000000FFFF000000000000FFFF42 +:10527000000000000000FFFF000000000000FFFF32 +:10528000000000000000FFFF000000000000FFFF22 +:10529000000000000000FFFF000000000000FFFF12 +:1052A000000000000000FFFF000000000000FFFF02 +:1052B000000000000000FFFF000000000000FFFFF2 +:1052C000000000000000FFFF000000000000FFFFE2 +:1052D000000000000000FFFF000000000000FFFFD2 +:1052E000000000000000FFFF000000000000FFFFC2 +:1052F000000000000000FFFF000000000000FFFFB2 +:10530000000000000000FFFF000000000000FFFFA1 +:10531000000000000000FFFF000000000000FFFF91 +:10532000000000000000FFFF000000000000FFFF81 +:10533000000000000000FFFF000000000000FFFF71 +:10534000000000000000FFFF000000000000FFFF61 +:10535000000000000000FFFF000000000000FFFF51 +:10536000000000000000FFFF00000000FFFFFFF34F +:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4 +:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF +:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025 +:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9 +:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095 +:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3 +:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B +:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A +:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065 +:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D +:10541000302FFFFF0C30C30CC30C30C3CF3CF30064 +:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748 +:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083 +:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A +:10545000302FFFFF0C30C30CC30C30C3CF3CF30024 +:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC +:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3 +:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE +:10549000310FFFFF0C30C30CC30C30C3CF3CF30003 +:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8 +:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094 +:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2 +:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A +:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299 +:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064 +:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C +:10551000302FFFFF0C30C30CC30C30C3CF3CF30063 +:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747 +:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083 +:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519 +:10555000304FFFFF0C30C30CC30C30C3CF3CF30003 +:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB +:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042 +:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD +:10559000310FFFFF0C30C30CC30C30C3CF3CF30002 +:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7 +:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093 +:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1 +:1055D0001CBFFFFF0C30C305C30C30C3CF30001419 +:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298 +:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063 +:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B +:10561000302FFFFF0C30C30CC30C30C3CF3CF30062 +:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6 +:10563000056FFFFF0C30C30CC30C30C3CF3CC00060 +:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518 +:10565000310FFFFF0C30C30CC30C30C3CF3CF30041 +:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA +:10567000320FFFFF0C30C30CC30C30C3CF3CF30020 +:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC +:10569000310FFFFF0C30C30CC30C30C3CF3CF30001 +:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6 +:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092 +:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0 +:1056D0001CBFFFFF0C30C305C30C30C3CF30001418 +:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297 +:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062 +:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA +:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0 +:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5 +:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF +:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517 +:10575000310FFFFF0C30C30CC30C30C3CF3CF30040 +:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9 +:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0 +:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB +:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1 +:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5 +:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091 +:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4 +:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD +:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296 +:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061 +:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69 +:10581000302FFFFF0C30C30CC30C30C3CF3CF30060 +:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744 +:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F +:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B +:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0 +:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC +:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94 +:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC +:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74 +:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB +:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54 +:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA +:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34 +:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88 +:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14 +:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63 +:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3 +:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B +:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3 +:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B +:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3 +:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB +:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93 +:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB +:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73 +:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA +:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53 +:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9 +:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33 +:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87 +:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13 +:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62 +:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2 +:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A +:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2 +:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A +:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2 +:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA +:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92 +:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA +:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72 +:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9 +:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52 +:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8 +:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32 +:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86 +:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12 +:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61 +:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1 +:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39 +:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1 +:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09 +:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1 +:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9 +:105B7000000700C000028130000B815800020210B3 +:105B800000010230000F024000010330000C000051 +:105B9000000800C000028140000B81680002022062 +:105BA0000001024000070250000202C0000F000086 +:105BB000000800F000028170000B81980002025082 +:105BC00000010270000B8280000803380010000002 +:105BD0000008010000028180000B81A80002026021 +:105BE00000018280000E829800080380000B0000F4 +:105BF000000100B0000280C0000580E80002014002 +:105C000000010160000E017000038250CCCCCCCCAE +:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4 +:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4 +:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4 +:105C4000CCCCCCCC04002000000000000000000000 +:105C50001F8B080000000000000BFB51CFC0F003B9 +:105C60008A59051918AC84117C7A607E4ECAF43BBF +:105C7000F232303803B12B103700F1616E06862303 +:105C8000DCC4EB3F298F607BCB32309403F1766923 +:105C90000606133984B8AE0203C33C203F012AF63E +:105CA000144867CB53E6EEC182155431C564951193 +:105CB0006C452CF2C858094DBE461995AF4C40FFB3 +:105CC00040E3781D547E8F16847EAD0DA113D0E481 +:105CD0007BA1F28E507F25EA6037D789487FA7B233 +:105CE000A0B9078DDFCA88CA37E340E52741D5034D +:105CF000000749300AC8030000000000000000004F +:105D00001F8B080000000000000BED7D0D7854D5BE +:105D1000B5E83E73CE9C9949CE4C26BF4C20C04975 +:105D2000082168A4C70069B0584F2060A8D40E1499 +:105D300069AC8A032244082452EBC3ABFD328100D4 +:105D4000010204B13414A44300A5B7B43752B4D44B +:105D5000523AE0A7C5D6F7BDE0B356AFB66FB4145C +:105D60007F8A12F3AED6BE6BEBDB6BEDBD93734E49 +:105D7000664810BDED7DEFC6CFEFB0CFD93F6BAF1A +:105D8000BFBDD6DA6BEF71BBFC246F34211FC3DFBC +:105D90007584FC2F8D1092DBFF747B4934FD738476 +:105DA00064E698D1441921C372CC389944DF075571 +:105DB000DD23F5B713CF9399334350AF25D70C119B +:105DC000DA474BE67C1281BE227584E411A2780981 +:105DD000FE89FAEEE05C2F29C3577FFB587C9709B8 +:105DE00059172CCA8076CEFE09891132D95A7611FC +:105DF00022FAA4EDBC006F068557A72F289C699353 +:105E00005CB1EB0B29DC7A0CE14E2FA070D3F2C908 +:105E100091CF78C7D0F2A66B5D86075BDF4D480552 +:105E200021ABA02FDA76D35571FE5D31A03C433E05 +:105E3000DCAC427B9D181E5AF65FD51857B19DA960 +:105E4000E5D37641C2DA054B97CC261308C930D585 +:105E50007EB8583D9C7F3AAFE7D1E9F7D2FEEFE933 +:105E6000A4ED3D3900A50409FB69FF958EEFA5332C +:105E7000DF807ED389A55F3A8FEDF08F7C42BE40F4 +:105E8000FC39E7A0F3CF93CF031E487516215306C4 +:105E9000E2AF1F6F51A42F217536B8041D3418636B +:105EA0000C21D7B7265E72E550784C17013CCD9493 +:105EB00035DF185ADE765A463C6CABEDF106359C60 +:105EC000DFEC7CDA6E34EF677425C5039DCF9E2628 +:105ED0005AF60CC46FC1A46E13F8C33FA95B22B479 +:105EE000BF0283906C3A9F60232D17D176247E6683 +:105EF0000CE52FF2009B6F94FEF771513F1E331992 +:105F00000A88E6C07326E091E2A9E01EC7FB4A8634 +:105F1000BF4C62C16B217213E2E90EC0DF95C8F37A +:105F200063117FD12CC4EB50F127E011F80B723EC6 +:105F3000BEBE2651AB00DF4CA5F8037C513CA6D376 +:105F4000F9F6BEE489C985D08DD91D027C8BF95440 +:105F500032FED9C2E1DA08F81B879F5CAE1021BE81 +:105F6000B22E93C94B5C82727A199D01EDCF6732D4 +:105F7000FCCD903509C6DB5CCAF8940E20B92A071F +:105F8000C245FFB0FD660A8F668167B3B7CB2BD1E0 +:105F9000F2760A6F14F04F8E04811FC5BC3DBACB58 +:105FA00086572594E6E07306A7806FBBC9E4D80244 +:105FB00007BE27DD5DAD1285F383192EB2491ABCE9 +:105FC000DF6D7DFDD8FB77F63B287C89A0AF98CEAE +:105FD000EF8367656313C5CF66BDABD545E1D85682 +:105FE000CDE63B90CE97395E4F8FB77892653C8374 +:105FF000C9CBA73E0EC9B4CFAB32E80B965DFE38D5 +:1060000024B87034D03F153D3E35F8750ABF054FB2 +:10601000BEE2A004FDFBAE7AD04B50EE8F78010EAD +:10602000E73803E0758CEB1C47298D9A0A96ECFA49 +:10603000C8138C1162D12F58478727D3CBE9865DCF +:106040009FF84AEDFAD9A9CF15D03701686FD7D795 +:106050003D42CF083D3D69887AC6AC43788B48DF26 +:106060001FCAF3182ECFD30F253ABC147FC57B84EB +:106070009E7EE057A5941F0E829EA6E5831D04D741 +:10608000C38347498CC935D3D713786713B8DEF972 +:10609000419FBEB1E3E7CA76731AE89D3262BA7CCB +:1060A000B49F31878911A7EF0F93F8DCF1A0C78E59 +:1060B000B1F97BE97F563D7D05C7E395871B5D40C0 +:1060C000CF317BEC78BC82E3B7ECA8E33DC7DF15AA +:1060D0000EFC6D837F507CE54B1C8F634909E27198 +:1060E000EA10D73B8E47A7BEEEC3E31EAAAF29DE58 +:1060F000B2830C8F2D6D2E02FAA137E642FD585A5D +:10610000D8E842FDC9F5F6783EBFF17CBD3BC0F151 +:1061100027E02C9E6D5401DEC612E324E8E5CC7620 +:106120008A37027ABAA00ACA3B1E22489FB10FE9F9 +:106130002EAEDF109E4CBEFEEEA82E7F16E4A2F718 +:1061400021C590E9380789B1C62BF5E3379B8F9FAE +:10615000CDF1F86543B6F1A1938ED91CAF4EFC94F6 +:106160001EB0E37FAC834E63DAEDE56C075D6E90A5 +:106170001CF6C710E9E15148D49305E518DA755EBD +:106180008AFB5C5A967FFC940978D63AD8BBCC3609 +:1061900057AC908EE36F6165A54D8955513CDC0687 +:1061A00086172D8F6B2531B047E56A9324281EC7CB +:1061B00005E344A678CBAE268837E2B02F05FD8AEA +:1061C00039131473FECFF872B90FE8B52348F10EF6 +:1061D000EBE26C85B7377CE1ABFAF1EED40F5FAB45 +:1061E000B5E3FDA670BA0D5FB3F46C5B79E2E9E14B +:1061F00017A593D01F828F04DE06D0A1D55EF65777 +:10620000DBCB4EFD13951CFA678874524F91529068 +:106210008B71AE34A3B37060BDED928BDB43DED8DF +:10622000593ADE4222910CDAFF0A921805F83EA68E +:10623000E9F87DA52B9107E50BA467E7C831FDFDC3 +:106240008F52C83189DAED1245EF6A0AD2702F8970 +:10625000A7A33D4CC2DE3C4401E245A2FFDF8AFC1D +:10626000A2B8005F2382EC3D896628500E11F1A789 +:10627000239D3CFC9FF9AB9FF98B44E92BF1A70CC4 +:1062800074A4E3BB4904F9C14BDAB19C46BAF0A946 +:10629000916E7C06A8C68667900425786611039FD8 +:1062A000E48AD8637194C30782C8F7BE3F908FD346 +:1062B000FBE7B38ED36D3809FF48CA053AC4895746 +:1062C000EEE7433FE7436AAFA15ED64A19FF6A9300 +:1062D000E8BA5A86F28F7E17F988E2B702C665F5EA +:1062E00005BEB772BB7A4B9317F5CDE6A6203ED517 +:1062F000A98D61002FB33AD17107A55786AE1AD781 +:10630000D3F90FABEE89839CF85B99DF966630FC7E +:106310009EDCF8C44B8BE8FBB6428DF9412DCC9E38 +:10632000CDE0586C9B9C88ADA5F06D2DF41A56FFFE +:1063300040E8A7ADD7260EEDA7DF3B75DA23FDEBCE +:10634000AC3E9258037253A08226229B27FC930EE8 +:106350007A2DADB8A7C9AA77B40F65A6BC0AA25119 +:10636000E02B3ABF282CEF4EBE6A2BBF02F562DB52 +:10637000A967894E2B14D5C44DC0977F2A3565E98E +:106380003CFC35BA2BAA8154465E053C67B4062511 +:1063900093E22FAB5A9F0632AA119DE96BA53B04ED +:1063A000F23BA0FF91F1D01DB4BFE8B5AA7110D99E +:1063B0004A77CDF7A796872D1BEFFDBA99C4AE0A91 +:1063C000BA24A4FBA96BF3F2C1FFF591607EFA2415 +:1063D000902F951C8475EBDA25A32349DAF5CB5968 +:1063E0005CD835499FA9DAA5CBA4B1CBD26F898BF4 +:1063F000C9A1CBE5C5676619E3A3A252EE17B71290 +:106400003396040E93C3AF2971C2FC39DDF559E20E +:10641000EB6DAE2FB648A4B62BC9F74E0ECF0C7954 +:106420008F09EB6FC646B64EFA28A85D14BE2285CA +:106430003E2DED66F1FA87F8F312F450DE4320307A +:106440003943D3833EC7B8E259FE09C6DD46C79536 +:106450005D415CF704DE9DF4144F97CB87F53EB8A1 +:10646000F6C5101881A9E0D4414687D167017F861F +:1064700050D713BD943D9DE35D6A7F5F74B1793859 +:10648000FB2507985D95C1D7AF93534A9AD1EF9DED +:106490002DFC50BBDE007F18F451E701BAF01782E3 +:1064A000DE60E5CD318276566F1965E42288277467 +:1064B000A3BE2D20119463FA09CBAD5CFFAD07FD9F +:1064C000479FEF93F02DAEC9A04762A7145A69F613 +:1064D000A4BBA7258B1FDD09F231F9D2D6A92FD293 +:1064E000E7426F7829F4AF19674C505B99F3249415 +:1064F00027A75C51F60CCDB5C80D91055F30796AC0 +:10650000E1FC0E723387966B8A93C3D9B9B1223FEF +:1065100082FDE9C3D1EE50F4E1D67E3BBFCCE46A04 +:1065200087437E3AB8FCAF017EBCB479E6D5D0672C +:10653000D08899A02EE7471B9F06BACD93221B5CFB +:10654000B4DEBC7BC26E903FED40375D23F1FD268B +:10655000C0478DDE0E94239AD91D85E7E6B245A883 +:106560009F7B436CEAA9F82ACD74D9FD27A73F3851 +:1065700044791C6F44A701BC7AED7B277375A05347 +:10658000E461806B64F86415A05DD3CF9859167AE6 +:106590006597327DB882F371E66C4A37D0778A19F5 +:1065A0009AE387688EB91FE63BD4F153F13DD89D3D +:1065B00080AF6CCEE72D06E3732107195C0E5AE01D +:1065C0003BE06B12E3FB96607930D93AB187AFF3C9 +:1065D000DFE37C5F4092EBA193AE4BB7C3C6D367BA +:1065E000095DC1009EF749E469987F1697B3CCEA2C +:1065F000980BE011F234DB38539D9D03768A5E0ED2 +:1066000076B118F71DCE6F0BBDE6AFA17D4D71B30E +:106610009245E735AE8C18A05E6715674A563EFF77 +:106620006D5FFDF0F3505F2BEB46BF7CB076DD7CF9 +:106630007EF3A4F0CBC87F0FB42B5EA47BF815ECDF +:10664000E7816EE2B5E89B228E6779E3A92AA04331 +:106650006F2309025FCED71B9F9680BF43E1752E43 +:10666000CB3C66E9763B9EF2F99BD0EFC8463B7F78 +:10667000D69076855CC2BA314A8AF400BCB31FE872 +:10668000467833AB993F4CE1EE45BDF2E9C3FDF1ED +:10669000C5E07E13843517E47D1FEA330A9F225339 +:1066A00038C6CD8E2B5988F7330AC047F1ACCA16CD +:1066B000391FAA7CEF00E0260F2EE72DF08F29600E +:1066C00027477264E03B61F7264E12E66FD9E396E6 +:1066D000C25E0E84A8BD4CE525B32641C03FCE3E28 +:1066E0002D1BD7D32AC36A8804FE9FB063B3B85C5E +:1066F0000AB8B6723B794B5308E5285BEB390D714C +:10670000FEADF92E630D01F9AD40FB6D4755220436 +:106710007E60B0B262E31DB47D5B938EF5373619AF +:10672000D87E4353253EDB6B5E47FB776B88D9BF32 +:106730009B9B4AB9D3C1E0CE1276728D885FDAE1B5 +:10674000A2ED6DFB1FA23E0959E25A4596F63AD3D7 +:106750003783B54F9F648F8BF5B53787D6DE67D803 +:10676000DB57998956F087833CEE2FF45E80D7097A +:1067700056BAD06F1678F694DAE9DE5E937C3F471E +:106780003C9DE3113DCD367F12AD43F85671F85272 +:10679000F5B38EC75F44D9CDED4567BD15325F1F98 +:1067A000F9BE54908FB5C3A4F8B0C461B239DF6D9F +:1067B0009DCDFC321264F13AE197B909B1F9656EE9 +:1067C000BE1F8565D4F751A68F1DF08BF62A6F9FEB +:1067D0000A0ED5D9DF59DA4F85A51F079CA9E073AA +:1067E000EE939137EDFDA4D65F8E76E7874687015D +:1067F000EDC06A28B596B31CE5E18EFA458EEF57D9 +:1068000038BE973BCAD738EA4F7394BFE4A83FD746 +:1068100051FEBAA3FE22C7F7658EEFAB1CE57FB22F +:10682000D72FBBEB93E1F7FF333C09B91A88979850 +:106830006D9FD7295745243E2A0E7E43E6734BE0D1 +:106840005342969473CC1761712D129F60F55FFFD0 +:10685000A845FE00EB58E747665A98CAD581F6E787 +:1068600003A08FC4FBF3D2AB81F13A21F56A7C25FA +:106870008B03B5A3DCA411E5F544295049C2F8996E +:10688000575B8C28F716D3F7567DD5CEE4AD18FCB0 +:1068900022DA2EBA5D45BB2F3A92C4C6D2766A81FF +:1068A000BDBE9BF74F7258FFF89EF65BAE307F215E +:1068B000146EAF02D91D5EDB75129E4EFC84A64796 +:1068C000AF7E06E20B3B981F7E6006F5032C7AEE46 +:1068D0006685E9B7DB944BF64B5F9C28F7F77FE0C2 +:1068E0005B9AD14CAB1C0020C0EFFF963706F18CB1 +:1068F00051109F639B07189F1B49F81F8FC381BBD3 +:1069000008EBCB48ED34C6DBF4BAE029D0757395BB +:10691000121CEF7B52CF7818CF957EFE6AB62EFE02 +:10692000ED63B47B38FE429B2B12518A3FB24D354A +:10693000C61258520D94238F425A3CE5C01E0CDFFC +:106940006B61D565EF157F16C4D9C2585641EFC2A9 +:106950003A067C24C3FE761CCB7E92C07206B76FCB +:10696000C781B3087E00D125A6270D09F6994237C5 +:10697000503F3CC9BA1196AAC62993FBE39492CE24 +:10698000E29152DB337F91205E594A74B64FC5E3E2 +:10699000821B65E96388B70687B6CF13BAC54E5721 +:1069A000A2B49339163EBEA58F9E0C5F63426CFE67 +:1069B000A16D6A23F8310766D9F940D497954BF653 +:1069C00007774E18F3D9F141A63206E119C807B787 +:1069D00006213E2D4529DED2878EB7A06C7E5DC193 +:1069E00079122CFF40326F053A89B242CC05D6F2BB +:1069F0006FE5F0422847A791D246ADBF1FFA7E71DE +:106A00008AF74B93BD1F27ECD5B36CFD2EE1323EC8 +:106A10006C4FD005766461C7AA34AB7D55C2D7E907 +:106A2000473B8EF860BEBBEB93EB3FF1DCC2FDBD94 +:106A300054F502527718E841262BE460127BFC499A +:106A4000E06F8B1E0D38ECC2EA966815B4CFAA75BC +:106A500011880BD3F51DEDBA426E1FEE9C1A9554AA +:106A60002A873B7611B48FB35A16F9ACF3C9E7F312 +:106A7000D9393B2F0DEC957D8B177D09FD156AF7F4 +:106A8000CB181F8F6C82FEF36BD83EBF13BECD7C3C +:106A90007EED8B199E9CDFD355124926874F2ADC49 +:106AA000CF55A212C9EBDF37D97CF2BE5F8DA7E3C9 +:106AB0009554BA0C9FDE0FE7B83E7B2981F84ABF98 +:106AC00046096E027BAA43B5D999FBF63CB86B31F7 +:106AD000F837F43DA88347AE6D1C1EA6703DFAE55D +:106AE00025CFDE057CBFCE45401F0938B432BB9DA3 +:106AF0007BB24F3EEDE3D27E991F47970F39C9FE17 +:106B0000C9E5E2A3838F9B8A4F9CEBA9930F2E6567 +:106B10007DB851BEFCF9FD18E490C293C7F3B58669 +:106B2000D5EACC6FE37294ED158A848D93C7F92C66 +:106B30006BF6833EE0B35DB5E5283FBDB31749A0D2 +:106B40004F441E54AAF152C193EE6EF7411C74D704 +:106B5000E207A56478CB8FB0F890F3BDE966FAB48C +:106B60004D6997A07DAA7AA3DC9C1FB85CE5F379F8 +:106B700085A6C6C380AF3C43216B28BE76CC5E544D +:106B800055027C47E510E22AD53504ED877C93ED6C +:106B90000B0529BE9EA4EBDECEC5C488D37A3B4D3F +:106BA000D5B61F23E4D0C98F3B175F5CBF10AB7F06 +:106BB0004EF95F716B6C7FB09814831DB523857D92 +:106BC00076A9F80D2D76B1F86875F920FABCF9525E +:106BD000D7A9F9D7023F0E35DFCDA12FC853BB6629 +:106BE00095805F6B507D4192E1C7AE1F06C387134E +:106BF000FF13009FE99F1D3E9DDFB3DD3CBE3D447A +:106C00007CB4D516FD0FDC034F51DF391FD14EE4A4 +:106C1000A77D91F4C820FF2670E818F0260C7C565A +:106C200093303EBB95C857DCB4FE4CD28865117FCB +:106C3000AA53828C1E3CFF45EC732BD319DF8F9B2C +:106C400048629DB07E4C9DCB377F15F39C178C36E8 +:106C50000A47127F8A903538EF118EF558C427867F +:106C6000D5B7CF2EA7FD8E98EDC2F8C588CA23B63A +:106C7000752CC0E547F4B7BB7268EBF3238EF5F9CA +:106C8000112581F95D8F54AE6986E546C97A339442 +:106C9000ACFDB80E3B5EB77ED4E50B278167F7E20B +:106CA0006398C7B5BBF2E2F1934706E19B7172723C +:106CB0007BF68B1EB6AFB43BD37B334B2E5A6DCBDA +:106CC0004320B256681D77F74724337C517D629785 +:106CD00097AD6E9E6FE0277EE0FF54F810CFCF1A7D +:106CE0000F8F4E6B5C164ED2BEC4C3EC89759924CF +:106CF0002A533E79F4652506790E84EBE18A9BF5EB +:106D000018D80BEB404950FDFB6815C1EF1599FCF5 +:106D1000FBC33AE6558DE8205195AE67235E5ABC19 +:106D20002393D66B5B4C3DC7C2FEF76DC6A956D800 +:106D3000177EE20517C6732B7C71AF41E755C9D7A3 +:106D4000C1DD8B4F61DE71748F628C45FD2E11A900 +:106D500002BD785B1CF3845B61EBBDF1A04FA7ED36 +:106D600077E909ECE79B534E7975D82F2FE8F6C2E7 +:106D70003CB754B2F5F2C8E2A2AF96205AED79269C +:106D800033E5A9DD261D6FCB62B65F9199E8F67AEF +:106D9000E87C02B50AB99EC217D0D87CDBD6911820 +:106DA000AC53E53C9F442273D01FCE77E409E5390C +:106DB000F24D82C6CCB760DF3F08FBFB3009B97EDD +:106DC000C755A06F1B5C3C0DD54439F5F3F9F90D9F +:106DD00013EBCF948FFB60DF77578B12C4F5CFD1C5 +:106DE000AF731E411239694AD80F8EB3EB21B64EEC +:106DF00006276B06D558B429873B48E1CEA643B693 +:106E0000D8E11678758EE37794DF14FC3C828C050C +:106E10003D24E2CC027E27DFE654C48E3E4FE7BB22 +:106E2000FB050DD7EBDD95CFDFD200EB7CA907F397 +:106E300023BEF4C1A1FA7FA1CF5FBF77AC189E3704 +:106E4000E41F98D4007880FC8889A42F8E97073D92 +:106E5000A3FDCAF59A18AF6C5F8B3B075F45FDB485 +:106E6000BCE5D4CB75108FCEAF2768FFE62B8C3FE7 +:106E7000FD2DAE5833853FE79A76E48711B571044E +:106E80005AABED92A29678A7C8FBF6D747308FE2AF +:106E9000FADA76CCF7F6F3B8AF7F523BDA4933E44F +:106EA00057BD68AF71FA89FC77217F4EFA942CEEBA +:106EB000AE817E46B42806803DA2BED105709554B1 +:106EC000D2358BD2ADA4A34B62FE1FCBA76729CFCF +:106ED000F419AEC3BC2CB287E5178A3CF040BD9DC7 +:106EE0007EC1BEFCF9880BFCEFC20EC7F770CD1B4C +:106EF0008C0FEDF42C52393D4B781E21C7C3088E00 +:106F0000872DF57C7F4EF3C62E66D7BEC0F7E75EB1 +:106F100084F98F1BF8FDA614FAF746D0BFE0B7BA84 +:106F2000BA5B011FE41A17FA714E38B6D633BD7733 +:106F30004075D9ECF8CB1DFF36AEFF6557E2EF3256 +:106F40007E7DDFFCFF3EE3DFFF771E7FD3DF19FF8F +:106F5000BBFECEF33FF41F3CFFF9A592CD4FEB549F +:106F6000BDD8DF4F3C223E66D7DFB22BB9BFFDBA9A +:106F7000EAB2E5138BFCC4E9B5E6428897F80D76D2 +:106F8000DEC3D9DF0CF9B956D083BB785E36D5A302 +:106F900026E4A9664C1179324CFFD570FD57C3F534 +:106FA000DF91147AB5BC92E9776A5FC4F442583233 +:106FB000DAD19F099C56303FFB08A1CB0CE835DDA8 +:106FC00093343F3B8FC3EDD4A7795C9F963FE7781E +:106FD000CFF5A8739D2FEC8B9F128C9FFE7795E7C2 +:106FE000033BF4AAC0C3AE4A662FE7CC4D6E0FB682 +:106FF00039E8A84D6AC4FC03273D5E57997F2DE808 +:10700000B1D06BBEA2E6A6A67782D3FB3A4EEFDFE5 +:10701000A83C1F8AE789A4A277A5878DF379FFD9B9 +:107020005033CC265C857490399D64D2D68DF15F47 +:10703000F24D62F52FB77E44ED1058FF35CD584321 +:10704000CB9FCF212E9174FF91D89FA37FEE6E1618 +:107050004795735487BFE5B483BD513837B3DB74AC +:10706000C5A285604F74EE5E09EBD30B6998A7BC8F +:107070003BB3E339F4E7DA272A0087B01B098FCF47 +:107080008249C1F2509CFB4E76BB7FF7475D71B0E1 +:10709000BF828512C6FD5AF50773929EC773D8FB4F +:1070A0009AC76FF377C9F543B3DBD7727A537F3151 +:1070B000D76391EFB5FE9913591E547510F67724D6 +:1070C00073A60BE2E9A9FA8148EF39CB7E539D62A2 +:1070D0008E84FE24F01F4BFBFD47420A587C5ECC99 +:1070E0007FA8E707EAEF62FBDE1CAF39D7747D2A81 +:1070F0007EA4F0FB453D919FE7ACE7F4C7AF779BDB +:1071000053607E43857F2F301CC4B3CBE49A64F177 +:107110008304D7AF5AF8B1676FA25527CD93587C37 +:107120009F9A6DD6FDB4B61CA52659BCEB975C4E54 +:107130007EA3EA5CAFC7499684F92404E625E4D12E +:1071400039FED57CDCAB2F73FC17B85C5FCDE59ABC +:107150001003F763528D5BC5F586787ED271137C80 +:10716000DE552A8F6B0C32EE1C3ECF399739DFF398 +:107170007CDC39439CEF423EDEC2CB1CF7433EEE43 +:10718000C2218E7B37C7EFDD978967C52BF17E86DD +:1071900086E7663E5EF3658E1BE4E3360F71DCED39 +:1071A0001CBFDB2F13CF057CDCED0E3CA792DFCE9E +:1071B000CB1CAFD4CBE4E700975FA75E13E36BF97A +:1071C000AE30B4DF1DB2F77383878D2F9E24FE315E +:1071D000FAAF23F8BEEE9495F72E32938C2BEA3B50 +:1071E000D7E354E3DCC2E335E229C609F0FDD02938 +:1071F000D7D07192E047D4BF5A657A3055FFCB386B +:107200003CCB2E711EA27E15F43F3975FFF7713805 +:10721000EE73C03F58FFA2FE9C41E06FE570B45E84 +:1072200022FCA2FEC241FAFF0E87E33B9708BFA8EB +:107230007FF720F87984C3F1C825C22FEA370FD22F +:10724000FFE31C8EC72F117E517FFB20F8798AC384 +:10725000F1D425C22FEA1FE89377BBFC69E23E0612 +:107260008394429EF1289266E0FD0646E224F801EE +:10727000DA6A76BF01E9729E87B29CA3A2227EF2EF +:10728000BE9228D4DF7B178BFBEDBD9AA01FB137D0 +:1072900097E729F3B896C6EDC1BD57B338C8DE10DD +:1072A000FD6EF1CF44BC68AFC1F29C7B0B581EB39E +:1072B00056D68E26260E97C74D441DF269D8B92A98 +:1072C00061EF89F3556B799C6AAF49304EB5B78C45 +:1072D0009577579398ABD072EEAA348EF9A760D801 +:1072E000423CB6FFDC984956975BF23156C731DF16 +:1072F00040E179231421C49697E138AF25F60F6F4A +:1073000032CC19A0E60A27B1FDBCC2B0DD7FA88748 +:10731000435CB4FEEFB99E0C4E4A7E9EE6B05761C8 +:10732000F4E3F99AF3F8FC05DECA393DB7CE79AF3C +:107330007B3A9DE7B353DD983FFAEC698EC7A9729B +:107340008CED9F1377B27338A9E26C5A47E3293862 +:107350009F7BD373C40032FAF798EB748CAB7D84B7 +:10736000FC8771353AEE4D7BDA15E0BF591DFA7492 +:107370008807CE7B4E5FAB41DE7507314C40EF474F +:10738000DFC07EB25A881163A46A0EA29DEB88CF3B +:10739000F17393223E07E16AAB7F398BCFBBBC25EB +:1073A000B80EB6EECAAB3D36FB7516F733BF627A40 +:1073B000ECE725F9F9C7590E3FB3C36B8FD7691DA9 +:1073C000E11910FF96E79D31E1FCF3B8B0141C46BB +:1073D0003FDF16DEAE407C72D69E46CC5F4FB5BF17 +:1073E00095F1F05CBFD57E17FBD9BFD973717B5D7A +:1073F000C41944DCE134E4157BC04F0F71BA30BED0 +:1074000012FC91354FB2F1498797E9910E2F8BE32A +:10741000FF179F7CBA7CF23BAF3DFED001DFA83C5A +:107420009618C9F7E9EBBCEA7FC9EB674087802F64 +:10743000391D487D862D8F58E45539F1B681E34DCD +:1074400094BD29CEBD14F8F83AEBF4EB5F8D54C12E +:10745000BC449C8690FB1DFB9B538D8BC5256471A2 +:107460005F8CEB5519E653EAE3FA47210AF6EF98E9 +:1074700007CA7D1E9E53643038FA5BC7CFAB89794B +:10748000B98BC326DCB742C7C0FD3EC8573F520682 +:10749000EB63D0366FD3C7D69B4DA58CDF36952ACC +:1074A000B174965F65BFB7A8B8D39BCCAE104F62DE +:1074B000BDB7A26820BC6A71246A8547E5F038FB35 +:1074C000999B129E3A5BFCEB52E1F18C27A41BF8CE +:1074D000568911A697BF61EBCF551AC3F3FDA9FAE0 +:1074E00051743E2F075D528DEF2DB0E741A93969E8 +:1074F000367E57B42C479E9483BFFAE242431BCF9B +:10750000796EB1859F4771B6F729EDC44882779FA0 +:10751000EECCC788211D9CE76ADC4107DC8EFEDBD0 +:10752000E05D923C1C71DFD006BEAE6D5462686FA8 +:1075300045299890EFB98EF3A5128CE1BD5EDFF678 +:107540004949E74F8CE4EBAD529C1C7E6F811DEFE7 +:107550006A4E969D0E4AF2731C1B85DC070F98F647 +:107560007BAC9C727EDCB8D87ADE77AF96F43BF9C0 +:10757000633AA5833EC73D0943A4AFF261369E6BD3 +:10758000EF2B53BD0AF15A2A2398CFEBAC7F46E08C +:10759000EFD54E845FE8E9F43D22AFF693CD4392F8 +:1075A00008DF27B7B74F29875CCFC99CAF9F1E6400 +:1075B000FEA9E89B56ECCC2B1C1A7D7D20F7B0EE83 +:1075C0002926BF0CCB2EF7A9C6234136DF4B95FBEE +:1075D0004F0A67764D84803E53431112A1EB7C7EA7 +:1075E000A81DF7C935A9270AFE1895291DE8BC3B37 +:1075F0005B67F76658EA4DA3EDDC85AEA81BF24049 +:10760000F87D30D110E982FA108FE92CEBAFA74951 +:10761000240CFCAEE52A61782FFACB986AEF8F9A9A +:1076200009B2F51C96C817405787CEDF3D85FAA7EB +:10763000B4BD4AEDD07DC9F4491AB343D39FF29942 +:10764000982710D662C092F9936298CF995F470C41 +:10765000F0E74A3ABA498476FA6D8063327CA7F340 +:10766000D620FFA31DF7ED733CECDC7A7E7DBBB426 +:10767000D0324E691AE3EF6973BDB84E7CA38A9D80 +:10768000DBEB0E2D6AAF82F12AF97D7A390A194EA9 +:10769000F1E17FC9C3FCCF490902F809F2BC863782 +:1076A0009B48F9E2B184BCDDE4C5E7F9A6203E833E +:1076B0001FFDCF10E4B9AC9B5CA143BEF507FEBA39 +:1076C000D1B06EBCDB14C2EF5BBE65E8904F249F67 +:1076D0007A19EF8FE8E7F7A84C2A210F366102FDEF +:1076E0002CF3EFF459F6F9FBE645E7BB908EB3595E +:1076F00072DD0EE3417911F2A957562DF91F2AF7D1 +:107700001BDDEB48F8B132B8C72426DD5D6679EFA2 +:10771000A3761BACAF938348F77E7CC69A39BEAF85 +:10772000067F37FF398ED7B99517DD37696B8A77B2 +:10773000578FED2F6B29CEBBCD714FBB2E0DE2467F +:1077400070D8938E377D6EE930C0D743EEE4F72FC3 +:10775000C8C1894631D48DE6BB500EF93D2BABC66E +:10776000EBC3322DFDCFE17C299FFA29E237BD8C96 +:10777000E587D0BFD9F996FCFF82481DDE8F441AF9 +:10778000D93918B10F39FAD644336C498C5E6D3F44 +:107790001F33939FF32C5CE7C2FCD7C229A843494F +:1077A0006133BBBF6ABF6C94037F3F4C5EC88403E8 +:1077B000EB0514BE9154540BA3F67EF62F99FD0CE5 +:1077C000C401C4B9D1B52DACBF51BA715A87F849BB +:1077D000990BEDE5D1C4F042FFA3351781734563E2 +:1077E00088A59F4238476BEFD7096FA1DFE5827804 +:1077F0008780671439EA3573B07F12A3ED0BA89B1D +:107800003722097CCE71C6887A579597C7499271FD +:10781000494F33EC0B0D187F907E9BD2B81DEE279D +:1078200001D0E77B2436FFE8B3B27110E87AF72184 +:107830008CD714ACEAC075BD238DD977EBA93DA0D8 +:10784000B9C14EA1CFB1A9F9500E52C465E0FA9169 +:1078500094FF1E4DABDA9606F1B0B469DB800FD30E +:1078600014FD6B783FE76937817DCC34B31DE50F9C +:107870002E64023B6373595106C85B5AA39AD45FC6 +:107880006B4973237C7BD22405F242296FE1BC94BF +:107890007AFD3B3369B13BD7FC1E8CF397DC083E85 +:1078A000C5FBD0A25A1DF873FAD2328C7FF5764808 +:1078B00018FF7A438AA990AABD7C5EE304B82F67BB +:1078C0004E66E41168B7548EAF77537856DCDA58B9 +:1078D00002F8990DF97EB9305C94F98305AF1B0A63 +:1078E0009C072B50E26ECADFDEE0A997D8335A0519 +:1078F000FCEE859330949E8162F32DF09BFCFC1C82 +:10790000924C7AA2901718984AC8EB16BA814F6722 +:107910002DC39EAEB59C0AFF833D17D3B6AF8F85AE +:1079200055DE3025B40B62883F35684C0038E5D011 +:10793000E9BC62CB3AE7E1F3F34C5FC4EF4932B9FB +:107940007F6310AB7FEBE1F3021DFEBAA5BD3B6484 +:107950002FCBC14F771EC2EE967EF1D77340C7B5CD +:107960008FBB31EE39FD7177FC3A5A5EB14FC2756B +:10797000C67582E9F5770F4828F771BF8A7AE09DCE +:10798000A017CB0D9EEEAD5FA0E59EC765D28968BE +:10799000A9C57BA5CE89F5F4182B2FE10ED28A7DDF +:1079A0002717407F75C73C04D689153F5D7AE317DA +:1079B000687929E563A8B2E260B33A9C96EF8A49F8 +:1079C0005D50BE308D209F45B3D418E4B55C08747B +:1079D000E7DDA4E13A46F471B0BFDD9D378FF2E3F5 +:1079E000B2D86333A1DDB2C3124452E93C0E3E93D8 +:1079F0004FE15AF17D09D7C7E587D2D95D2B1C7FAE +:107A0000E7E854AEA3DF57D179823E5C4ADA6702D9 +:107A1000BD561CDCAE5AD7B9B79B4A31F5439457D3 +:107A20007C9F8E43DBADFC9164C0145742BE03AC17 +:107A3000973FF5D5EED7607ECD6A891FE6B54185C3 +:107A40007A4B630B9FF0E900DF3E7526FDBE6CCFDD +:107A50003E754919E08DDC0EEBEAF2435712DD4228 +:107A6000D7731D32FA0BAB32BD9D78BFA966BF0F2D +:107A7000A51F2E62836B19D71BD4EF53ADE7DD9E94 +:107A800048CF443E5D7E48B68D23E81F3D43D879FC +:107A9000B49FFBF13C9AA09F58AF04FD56890BFFA1 +:107AA000949E8A64F06C057AC0B91BEADFC0F3C10A +:107AB000A6103E1F6AD2914E3B018FE3585E0ABC6E +:107AC000A7725B05F756054CB8180CCEA5985590D3 +:107AD00087991566E5BC5B23927E113B5D3C77BAC6 +:107AE000230BC1C8999AFEDD190AF5C776AA91BB86 +:107AF00021641D543A6754D335AF3E3D5C916ED935 +:107B0000F75B2FB1F37D9F4BD771FEEBF355C4F7B5 +:107B1000CEDB2AF6F3F813AE933B6F5BF208C4C7D3 +:107B200069FB2FA6837FC1F7FF52B5CF5B50696B0E +:107B30009FB7A04EB49F89EDBD176FBF73C135F6D7 +:107B4000F1172C13ED6F44F8B58BC39F77FB54FBF3 +:107B5000F8B7D763FB060FA36F4FA617F3AD5B7C97 +:107B6000461CF4315EA83609F2C94B3AA19E5877FB +:107B7000A8E637217F5B3B9C59BE8958F968DA0239 +:107B80008003F2B2AC7C9451996693AB4C33CB56E4 +:107B9000CEAE196EAB9F1B2EB27D1F567B85832FF9 +:107BA000353CBF8865000A0C730AA73A5C457D54D2 +:107BB000359CD9C1F79EF061F9DE6BD8FCEE1DAEA5 +:107BC000A11C03CCE097DFAB463E67BDBF95C03D2F +:107BD0004854A7DEA945EE8379F4BFD75DF03E8D0A +:107BE000E73BA57908EABB0D8515FBA3167CB68E8D +:107BF000A4FC40CB2DE92AC33BA7C386914B425638 +:107C00007B7DFD48B516FC0D787F8706E385D7C3DD +:107C1000780D6A4F09D81DCE713C4595B671BCA34D +:107C2000EA709CEDE92C9E2AC6F18CAA738CE3AD18 +:107C3000EDE4EFF9383B80CF528DB3A1E81AFB7C1D +:107C4000462DC371F63AC6D9306A99639C34361F03 +:107C5000FA9E8F13BBD8389E3153EDF3195D8FE335 +:107C6000FCC0399FD1F58E71341C07DEC338D4F0C7 +:107C7000D5E1BE2CD5D3B304E9FF0B1FDA39AA270F +:107C8000F228DA39AFF8D0CEA1B54CA8474A997F8F +:107C90007B4F7A16D2E783344A7FCD4AE728CF3B21 +:107CA00088A25F7C270791C4284454BFADE43CB848 +:107CB000F8F09C51CDF03C363DB410FCD187FC1857 +:107CC000C77BF7D874F58E24FAE8CE76F7B98485A9 +:107CD0009FFBF42A8FC786D2D93EA4289FE3F19F49 +:107CE000D7214E449F6FB809FA436779BCA81FDEBD +:107CF000666C778EEFEB9DDBC3D6A90FB69F71A3A1 +:107D00001D11252F9451B8E7F369DCD96EBF2FB34D +:107D100081D3A3E7A71E760E889823F03EBC8E6C15 +:107D20005BBCF07727BEFC0CCBBB2323E0DEDFAFD0 +:107D3000B73EF634547B515A3872159D6FEDD1ED34 +:107D4000EE11B4FCAE3BB1C0D02CFDD4BAF1DCBD19 +:107D5000F0436E8EB86DF6F32D75F6F26D0E7BFA6C +:107D6000D5F422B13FCBC6D5636EA0D77CD863A52E +:107D700024BC0D9E987C17447A2D08B2B6029E86CC +:107D8000FBDD248EEB5D2217E39CD15C8CD344C4D5 +:107D9000BAE5806F81DB6B86293D17DC27231E9DAA +:107DA000F0264EA49B2EEAE7243AFEB71BCEF10C38 +:107DB00006FFEDABEDDF49D46DBB8740F0C1D76A5C +:107DC000ABF69FB5F0C7CD9159FBCFDAF034C7566B +:107DD000BEADF1665BFDDB572FB47D5F18BDCBF602 +:107DE000FD8ED6BB6DE53BDBEFB3D55FDAD16CFB27 +:107DF0007E576CA3EDFBF243DB6DE5155DBB6CF5C7 +:107E00001B8EEDB37D779D18FF15F4037F23E37977 +:107E1000E7F7B5735BC17E7B3FA8E07ECE9B7CFF1E +:107E2000EE6D7EDFCF4AE0BD29203F13BDE0373441 +:107E3000A45179A6B6C4042D777DEB54D02304AFAA +:107E4000D428D746AC8F5267770A3F9F2877A8245B +:107E50009E0DDB2BFD71D81EB9FFBB92A0DF27A6BC +:107E6000FE2E772849BF2B092569BF17A49E12B0A3 +:107E70001FA32F7B929E03EF974B32825CE43EC997 +:107E8000F32E5267F5DFE66B2C3EF44CFAB4F95A48 +:107E90002EDC8FC1E4BDFE48FE34F01BEAD57849E4 +:107EA000B27D9BBEF1BA24BC3770BEC6E4E5AED845 +:107EB000085B3C6DF9A13136B97F292D729346EBF1 +:107EC0009D3F29A39E25F1A7467DF52A18DF9C0F2B +:107ED000EFC9B15C5C1F5F6C32F79FA57EC04B4D54 +:107EE00035F8FCD7A6F0FEB3D4257CB5A916CBBFD8 +:107EF0006F8AE033D15487CFD79B1AF1FBD9A6D52F +:107F0000583ED714C5E79B4DADF87CBBA91DBF9F5C +:107F10006FEAC0F2BB4D317C0A3910F62E09737B33 +:107F2000526C981056EEE57390F3441CD3C0FBA33B +:107F30007AB50F4AC08EEE7DC98379B7A9F0E4E423 +:107F4000BBD4F43371BD5F12B3C799C5D397C6E8EC +:107F5000E373911AC891D83856C5385ADA2FAE440F +:107F60007B9CBE57D865B231634E927B3BF142E4B5 +:107F70006183D349D43FF7DD7FAF585406F42942DB +:107F80003CA53D253732BAED37BE7AD5E0F8439BA4 +:107F90002F7F201EA55FFC6E14C4A7DEC915F8EC68 +:107FA0001E05C12D450BEF023EEC3DEAC179F51EE1 +:107FB0004F67F92810541B42FEEBF243BE98553F21 +:107FC000ACE8CA8CD9F5457ECCAA2F7A4FEF0F804A +:107FD000DCAF0AC9B1B313813F4CCE1F8CEF44FF15 +:107FE0002BBA0A639AAD1F7BB9B75DAAC17B1F8903 +:107FF0009E312F89FF219EAB422A8EF3F6A1319844 +:108000007F40FDC4D85916EF8CB17143312B5FD638 +:10801000AF4E8F9DCDEE872F55BF9F367C841C259C +:108020007FF0A63E8F3BD89328FFA6E2FD6EC7DD0A +:108030001FC0BAE3A1FF7F8CF9420A9645BF0D5DD0 +:1080400072D403E779C961DB78B49D2E7C7458AF94 +:1080500052D3DD9E0FFE7BE0255CB7D9F9F2089C78 +:108060002FA7FD5D50B456E973FDE7CB1B385FAE1B +:10807000F026D4087DF5CED13117CD0779BBE97450 +:1080800050190B7904ED7871445DD7F86AD08FEF01 +:108090001C5D9B07F1B4E572EFBDC9CECD7EA8B1E2 +:1080A000381B89B97B1296F988F80C21B45F6F3FB1 +:1080B000FCC0E9E72C65A7BE164F979FC5DD571E8C +:1080C0003E33F30B14FE95C7DE53018E635AC4E5AD +:1080D000B7CC5FE2E7EB971D7A4D85F9BDE98E9647 +:1080E000DC7F113D35104E2D64DB0F8D926E90E3D9 +:1080F00045EC3718809FBEF60A15CDB77EED26F009 +:10810000BB0E62BF429C7B584CC201C0D7A2A3CB1E +:10811000313EFCD61337707BAEBD02F8E31DE2AAF8 +:1081200081F9BD439E0F4CB4E0AFD8CFFC18D2CA42 +:10813000EC18712E90DAB336BB666987BDBC84CC6F +:10814000CD03BDB1E42137895114DD452CF72FD182 +:1081500079E7F899BDBB9434AE077B4EF130FF60F0 +:1081600051902823A83E5DF193872BC0EEBFD2CF5C +:10817000F61D451CE3AE2C66EF2DCB89A9B09FF010 +:1081800087A313E77F01B8CF135B0FEB32C948BE5B +:10819000FF7747AB1DBEC1E077C22BCEBD0F88A7CE +:1081A0007038E44352D2FCB4297ECE775C8FACF1B8 +:1081B000DBEDFC0D8EF26C3F8FB3CA44063ABF1361 +:1081C000F4465D19F81DCFD9468F788CB53ADCA7F7 +:1081D000150E037F51BB6002B1D4FBA316C1F7E7B4 +:1081E000A5E796E03973253E01F3F1BC04F314557D +:1081F000CE0F725A6002F91CC4491BD1A95FEB0B68 +:10820000744279BD9F9D836A0039A5FD6D09CC3C00 +:108210000D717D2F698F9B85B0FF6D8F7FFB747B08 +:10822000391DE409F409BC007A1804E345E9A5F610 +:108230007A7EC35E5ED687A7B86C3DF711F06A718F +:10824000F89D2152A99CB7DACD2BBD0C7EB8111C2C +:10825000EADFC3EDF995448F62DE6288F1C13DB378 +:1082600058DEC43D7EDD88D2EF9262E2F9880DD0FF +:10827000D4B28E357C28919845AF37283D2AF065D9 +:10828000C3870ABEDFAB45BE057855898976AE97B0 +:10829000220DF6AF15ADC666F792027E2FA0237FA2 +:1082A000A1CD1FB4F97B422FB8B95EA4FA62833F17 +:1082B00017F460CF4CB6AF9E50D9FE0EABA7F6D7E1 +:1082C0006B033852D5F3F5D7DB9EACDE8A9FFCF00A +:1082D000892895F765FFF2ED006CA6BDA5B4E741CE +:1082E000FE43FDC17501E0E337956800E6FD562CBD +:1082F00079DEFB2FB9BE837C27382FBF92D3E9EDFF +:108300007FDE7C23E0FD83836E3C6FDF70C813F754 +:108310005022AE3C7A17E3A7439ED7587903FE6EEE +:1083200054C331BBBC2D7BF4DB793A6EEE4547F08C +:10833000FBD8D17E5E79E08F33C11E69203DA8272E +:108340009CED60FC0FB370FD5A08E7FE9DDF45BE53 +:108350005503E7FB86A39B31AFAAE1E82CCCA36AC7 +:1083600070C8791DF7438EF9EDBFB321F04162CC9F +:108370002E5EFBFDEF4C788DC273FEC0AF03922DD5 +:108380007EC4F4446FD71DDF7B524FADDFDFE57E47 +:108390007D7FBB18B6D38F313B9E1C67CF7A773C6D +:1083A000007E53FD3EB7413508A9FFE1FE47BE0BF5 +:1083B000FCFDB207E30DCB7FF8F48BD7D0F2F2C708 +:1083C000DC39B3D93434C80316748133EE90AF2B43 +:1083D000E8B0ECC74FABFA55ECFD0359FDF458FE7D +:1083E000D849955C35107FD3BB4EAAECFCB9832EDF +:1083F0005DAFCD04BB7BEDF7FFAC827CBD75422247 +:10840000C30A07B6AFDBF734DA758027A423A75376 +:108410001FDD06D02B7EE39393B05E10D6B1C1E88A +:10842000F55DE0995CE4EB1F3D09FB05FFEA3100D7 +:108430000F753FFA4600E6F386D2C8F8FBE175797E +:10844000B08F5EE78EE605F1C9DED7EDFD26F2DDE1 +:10845000D233DFCC637950663EFB5DA3683EC60134 +:10846000F7DC84F35C4222C87F750FCB9887FEBE91 +:10847000426A1E4B221FD705981E7BA3D38397DF2A +:10848000BD010A17FCC5E7E5183B6FCBF212BF2907 +:10849000F63DE0DE465A7EDFCBE8951B70897BAD6A +:1084A000BC36BE3DB0A11BE8F4F6487318C42B29B6 +:1084B0001EA21C6F12E821F9CC8C618C4E44572A05 +:1084C000783BAA27A7C37BA8DFED367D136CEDF8B8 +:1084D000BAC6C6BF878F4FE14E03FBEC8D3C6AEFF7 +:1084E0002499DFF280907F6A7F58F8CC22E74CEE27 +:1084F0000F6C64722EE43E36A706BEFFDB0B4C8E7B +:10850000A01DACF314AEF830FC7E729E847AC14399 +:10851000E2C9E4FB809BCBB7FD3BF5CAD1BE157C1D +:1085200042E15760DDEAE717B6CF4BE980F6DB9210 +:1085300087687BAB7D0EE3623DB5FFBD65BD5FCA5D +:10854000F5C13501C7EFEEECC91DD27D79F5EED846 +:1085500023DF05F9A5F20AEB4FFD0FDD9827F2A7FF +:10856000C34FBDF875CAE77FEA12726BD7A74EB941 +:10857000AD3B32992493DB3F6906492AB7F47D521B +:10858000B9D512C8CFFF51FA54E06F51C09EE7240D +:10859000F4632A3C3AF5E3DFFC3AE2D3A91FE9DFB2 +:1085A0000BA462201F0AFE137CB7EC072BF0774167 +:1085B000FAF853F05F1F7F0AFE73CED78E3FE7F7BE +:1085C0002BC15011F162FA74AF21513FC4537F2E79 +:1085D000633CF50285693DA5F385C385788E789D5A +:1085E0008FF9E717823D81AC32BC0707CB3DB9EA72 +:1085F0007AD017E27D8F8FC5BF2F847B02D63C9047 +:10860000D78ECB01D8EF4AC4484D327F846A648448 +:108610002341527D67F1E20B60FFC17869A362409C +:10862000B719B2366A35F8F9EDECBCFCE2E6AF05F5 +:10863000601FFEC2F131DB407FDDF9AC4CF8EF2862 +:108640002A906F7207A7FF9B24BA732A9DE71DC764 +:10865000995FB1B82D39BF2CE3F59768F7A8A097BB +:10866000A85FF0BA351EBE8CFF9E64DD1EC7FBE31B +:1086700037205F2D73F05584FB8D3F147C7535B921 +:108680009AFB6D2E6B3EDB0CB96C1BD825174EB3D5 +:108690003864EF7119E9D17B5862F94F100F9E02CF +:1086A000FCD0A35AF3D8CE03FF25B9DFA0EFFBE33C +:1086B000BFABB89F56A97FE29509BBE9F3FC132F26 +:1086C00097FC0CCA3FF9EDA857C8C0FAD34FFC0578 +:1086D000F7B32F9CF0201C174EFC72D4FD507ED2B5 +:1086E00083F7D55C58E361F99F27FCB1B1F07D2495 +:1086F000CB175AFBF33F4F48E0BAD482747B29C0B2 +:10870000FCB1DEE3FFFE7BC81FEE3DEED1611E0D26 +:1087100027D2717FABE1491FC6692EFCFCCF15D66D +:108720007CA6CB9DCF4A7E1FE2053FA9853CE50B89 +:10873000996CDFA0E16753F6C339A215474FAAB081 +:108740001F33FD177F9D007AE7C211664FBCEB4EC9 +:10875000EC857DD63F046EDFE086F82EACD7C309EA +:1087600069CA885D0FF7E10CC40BC3C3058A07987B +:1087700017C54B1DE8CB54F8F83FFFB0F8786F01F0 +:108780008C5F7FFCF32837FD78914CF6DE1F83A3C6 +:108790004D74FEECFD893F4F00FBE84F5DCDB8CE38 +:1087A0000F36EFFC8CFFD7E62DC58732EFCA7FD896 +:1087B0007933FE3F11D059DE9F430E06F2F94FEE9A +:1087C000C5F28FFC06C23B44F9AFFD879DFF27A48D +:1087D000FB114AF7C0E074FF6F196C5FF81F6FDE82 +:1087E00083D1FD594E777F10F2102EFCFCAF185F3D +:1087F00017F31F6CDE3BFF93CE5BD8439B5C467B3D +:108800005121E461C7BB750AE7BAD2B9ED1096925F +:1088100079DEB513AE6732987F214B2C6E4346B29A +:10882000F811E1FE46DFEF416AEC7C95A2AD67F7F7 +:10883000912906DEAFB7E98A4506E67690F29722DF +:10884000502E988ABF73EBF4BB942BBE741AECFEC7 +:1088500096660A1F1DA7C5AF04A9E544DCA5AEB8FE +:1088600067023E5F83E7061EFF7207559BDFA13953 +:10887000FC059F6EFFEEE1FD7BC9A920E42F790D79 +:1088800005F3537DA43D6ACD37F0104B3BFABD1381 +:108890007E10D0624F5E2AFEFE9CC1FC4F592AEF2B +:1088A00086BC5832DEC5EE3727EC5CF1A60223B653 +:1088B00089E55D78EDF85CDF0D785408F50FD9BCDB +:1088C000D0AF24DC9F5478174AA9CBF4D9EB717F41 +:1088D0006950FA307A8CAAE7F45965A387C0FB4542 +:1088E000E862A387C0EFA5D2C5490F27FE7F95C1D7 +:1088F000E274824EB67C905CE697C4A981FCCBC33F +:10890000FB312EF2CE3FBF7623F0E9F29FC9C44B74 +:10891000DBBF7BD84FE220BF4A4C053F6BD95119D2 +:10892000E3C2FF174BEE49A70080000000000000E3 +:108930001F8B080000000000000BED7D7B7C54D5F0 +:10894000B5F03E33672633999964F29ACCE4C52496 +:10895000811834E0248480823A218020F43AA008EF +:108960007AA38E10209827485BDAEA8F09411A1EF5 +:10897000B641E5A1453A2028ADD8061AB9A0A8838A +:108980003CC4566FA3E5DEA2450D8A82C823A51715 +:108990003FDACF5BBEB5D6DE3B73CE6402DAAFBF43 +:1089A000FBFDF3E59F937D1E7BAFBDDE6BEDB5F761 +:1089B0005CBE0C7FB73076595C196B652C83B1BAFD +:1089C0005F3B184B67ECC19D09E1C9F970DDF5E922 +:1089D000503684B1734B7A0E65C3FDD02F15DF5628 +:1089E0007C3DD43DF40EB8FFA0CAEE0F9444FB9139 +:1089F000D754A781B1E18C9DD9639B11B633A66C86 +:108A0000DB771FF5DB31DD94A044DFB33A4D342E24 +:108A1000BCE7C7E7A15F28E1414ADFFE186BE1FD33 +:108A2000FD42E1F0ED3685AD08DFB64DE620C0D160 +:108A3000B4EDCF663FC051F5EB1793BA61BCA6DD2C +:108A400046162966F47799E173632461285D8FE304 +:108A50009531BF5DA960AC11FFF5C2B5B361324B72 +:108A6000826BC7CA3F1B93F07BD327DD96E8F7756F +:108A7000BF7E7557085053F79BE793BC703DDDB53B +:108A8000358995507F0F98931953EDAAEE7DECF739 +:108A9000526ADF7E605CC65C709FDF624D1DCBF961 +:108AA000789DDF39C9103E06FD48B8617EA7F11FE9 +:108AB0000F63239D8EF4CFAF83FF47B011978D7066 +:108AC000DD96C6D80D7DF114C55788D3F3C58B1B31 +:108AD00043809F333BBFDC88F0D7FFFD2F1B7F0413 +:108AE000F863AF599D5B61DE4DBFFC8F24A4AFFCE2 +:108AF0006EAA53A1EFCEE5B29007DE3BF77E423877 +:108B000004B7CEBD7A32CF0BF33DB7E3AF2E2FBC07 +:108B1000BFF0D5719938FF852F5565327BFF709C6A +:108B20005BCC5838410B5798E8E8DD0D9D664273E1 +:108B3000AFB8C6D0637FE7FE3C84F3ECD1045F029C +:108B4000E209EE2D2A43FA009D86F2F6C380DFC6C5 +:108B5000ED3FFEB371683C3C87B20D6EA4EBA7E31A +:108B6000114EC622D9CC8DF8ED59E6B4F77DBF97EA +:108B70005E47809ED77F03BA6D5FCEC7ED00BA25F2 +:108B8000F5A5DB59FC07E8D38474B345E976910574 +:108B90007FEE298476671AD1351EBE22DF005FB5CD +:108BA0000AEFFF26A7FF874E949F9DB65E7A4D463B +:108BB0007ABD78318F01BD4F997AEE63E58CF5BCB3 +:108BC0009AE0DC0CF71F7CF58F2427E75E7AD78CC0 +:108BD00074843FBB02F33AC77AFFBA709E8D8A98BD +:108BE000E716472421298AF7C6F09409DE24BA7FC4 +:108BF0009CEE8739FF22FEB2913EE17D772A71E833 +:108C0000D1E12CA079B07006CDBB61CB9FCCC83729 +:108C1000924E481F6524D2EBF878BC2FE924E71D5B +:108C2000DB9F13F1304243B72D5C0EFBD2B5C7CCAE +:108C30000AE3D10BE0C5EF105E689FDB94A02AC960 +:108C4000FC7E0ECCE39C89CDE84038C2CA1FE3D13C +:108C500097B125349F1762E552CCEF6A727935B827 +:108C6000FF51BC3CE37452FF123F67BE8EAF9F0FB3 +:108C7000A19C03FCBBEDC183C83F8C59C227A09FB8 +:108C8000FB99C2920BA37893F09E5119E9DD33BF93 +:108C900034864330FF651DFB49CFC6CA37CCCBDFD6 +:108CA0001167BC3F8AF11A77EF1B8A7AE8CC1B7BED +:108CB00088FF1AB71F3787A09F43DB7E63EE2E899C +:108CC000F23BEAEFB0467F9FF9D5BEA1A46FB1FF9A +:108CD00038FAE684E8BF69AFBEFFA6ED7FD6F55F40 +:108CE00017EA303BED571FE7B4EA9F8EF33DDD6591 +:108CF00062A8FF4E77182784E38CFB96B05F124F73 +:108D0000CBDE35931D2B7F2F319C00785AF8EE84F3 +:108D10003F25A7E3D5EC05D4B2CE16CE579D8FF8EC +:108D2000B3912E9DEFDE63447BB20BF1784DB4DF3F +:108D30008A23CD550E90DB8A63817264AB587D30F7 +:108D4000E2A84107378C9389FA7929F4E3857E9864 +:108D5000EA7307A05F63D2F809088FD169705AE3FC +:108D6000DA55DE9FC91E604180CB0476DBABE1277C +:108D7000F7D4A4A12C19A7E731A05E5800EC85FA1E +:108D8000D96D66C52AC0C70C89BEADD0EF82C1FEC1 +:108D9000D283D05E30DBED0BC173CF1DFCBBB34E75 +:108DA0007BC8703DB6F3C22847B64B46E605D5777B +:108DB00046797B0E039560137C95DD61233B6353FD +:108DC000BDEBAAA16DAB557D8051F6993D989B9264 +:108DD00081DF99E93B4F8AA27E8EF34E6249286F6C +:108DE000B27FF99EEC97A991A1387F66612A03BBF7 +:108DF00092C338DC46319F42D6A5207FB74E49DA70 +:108E00008CED0D8E5AB2FF79AC679F1FE8F66CD2DD +:108E1000F8C3A8C7E05F03BE97DBACB7EF0316E962 +:108E2000DBF92135467EBD8600F05F619BFE7E7AD0 +:108E300055E5FC013EC6EE4BE99CA082FE4E9F5ECE +:108E4000B9231B703A69C57BBCFD7C65A907DAFFB5 +:108E5000B1BA61A20A7A24FDF795A579D0BE90FA3D +:108E60008389F4BC0E907423A8FED54327864AA2BA +:108E7000729B0160261B499E6F463C9C0D9C598647 +:108E80004F1BA67D658647F817403CE48EE478C802 +:108E9000B11FDBC1E0FD0186EE16E4CB9FBFFABF38 +:108EA00052F03D2F73D27C9D6CA9F3730B4E9E8DB7 +:108EB000BC3CEC4AFA4C659F4B3E3446E520D91544 +:108EC000BC3D05F86AD9CCE275E351D7D6FB88BF23 +:108ED000606427D943F9BE339DE85323E883705A71 +:108EE00080CF66F357582D6B177A68AC13C7514281 +:108EF000F5C6CBD77D7B78664ABE713007DE57EB6F +:108F0000BD045757867F36E2EBAF1941BACAFBEE74 +:108F10009933BC41C0EFCD2981B9380FCF9C4B7933 +:108F200008FFE41446FD55CDB5FBD1AE5ED80BEA83 +:108F30002F8E5CC9EBE6C5CCA70EEAFFF9D4D4E0CE +:108F400077B1FF82D7BD3B0F437FD7D7987D5618A7 +:108F5000E2FA45E53E358DF109A1DF21E8E6465A02 +:108F6000A2DC7D8F8551EECE27287E3FB4CF3FE433 +:108F700024BD9C5333F930DAB3F3B6FC8E08DEFF20 +:108F80009197E4113C0005E521776F72C49A44FC87 +:108F9000FC550C3F7FA5E75FFDB8E72F7B77775344 +:108FA0007F4ED11F3844F03C57D0E9BC91FBE5E738 +:108FB000177B090E701FF7A1BDFDA6E33D9922FCAA +:108FC00024419F47ACFE35480FC0FF3A2DFE7FD6A7 +:108FD0003F1D37E27B4047BAC6D2718EA5390FF5E7 +:108FE000C283818EF1A0B1D9C939DFAB40E69E9230 +:108FF00012DC82EFD7CFE83A6422689A8B506EFB7E +:10900000D259217DEEDAFB408B09DA4D48276F5F9C +:109010007A5EBFA894E8A6A16F07F67FFDDE3F1B2E +:10902000107E49D7750AB703B1DFBF92A28871EBF2 +:109030005B4C80CF0BBBCDE4FFC6BE7730C54BEF9A +:10904000C9F6504B854F0539CD34B060BC7E0FF664 +:10905000E9D7E24B88037F6F7F4EDE1FE0FF4D2D87 +:10906000FE7FD73FFEFF5DE0FFDFBF25FE8F209D27 +:10907000FBC3BFF4BBEB847EA863ABC8DFFCCC3F73 +:10908000D53510C61F6FB4933CCCDB6A243984F706 +:10909000277B5C517D32EF86E67D38DF79CF28C4AF +:1090A000B73541AEE7BF9C33F910EAF7D9ED7AFF47 +:1090B00069CE8C9019E19CBB5E7F7F5E38261E6472 +:1090C0001ABD0E7C7126CABF03B8DE7193BD340A87 +:1090D000F9A89A5B928CFED26B26EFEFC91F7FCB6B +:1090E000C836C7C17F5E6A3ED963D9CE6D06246992 +:1090F000EC3CABB11A505FCA7EC7CE2DC944BF66E7 +:1091000081C37BC5386CC022BD5DCF0F2532AFA6B1 +:10911000DFC2B6545D7B507B96EEFD6BD617E89EA2 +:109120000F0E5FAB7B7EDDB6325D7B48C78DBAF735 +:10913000AFDF3D46D72E8DDCA67B7FD8E1A9BAF6FE +:10914000F0AE7B74EF8F383A53F7FC86EE0775CF9D +:10915000479D5AA06BDFD4F343BD1F6360A427591A +:10916000A2427AF3C0E253152790E1CA95B188CFA5 +:10917000AA91FCDD03F3CD0667125E8B0C4EE08FE7 +:1091800037664F263FE0C07C97DF4BD70A3FC63F8C +:10919000CC38BA3C18C7CF1DE7FCA2E28466DC2AB3 +:1091A0008B49A7E7C639F5ED61A9227E18C0F9669B +:1091B00064AA5EBE8CCD9323666866CD1B9889E356 +:1091C000819C8D4AE57246D7ABCA59527305B641A8 +:1091D000CE2A53E3C81913F6B652F0135CFDE632FB +:1091E000642C07D9653FDEF4D2FD900AF1CA188BD2 +:1091F0002FE720CECBE04B47261C3B237080F72780 +:10920000EC332B367C1BFB2CE5DC6DF086C8AEA561 +:1092100032CA2F3D35BB289969F07B4FAA41E883BC +:10922000761E473AB70D53251E0BB4F7270C578B04 +:10923000A3F795B9933351EEDCFDE845B3BB70F06D +:1092400016D0C7664F3E5DE5FD65330C13C271E86D +:10925000DB90CAE30CE9770D8EFA5D0D88DFB3EE83 +:10926000F7D60E027C3556F790DFE536B4CF3F8453 +:10927000F3FAAD91E7CDC0B342BD305BF8D1B3276F +:109280003E3EFF10E8A7D9EF0C22FD24C7D9B03825 +:109290003258EB37E4F413576D13F06C5CEC1F5C41 +:1092A0003388E022FD20FDF4BC50C3788C7706B0F3 +:1092B000668A1BD71A586DBC7E968B7E3291E40865 +:1092C000AFD34E727276CEB12415E691E8082E47E0 +:1092D0007E9B797D5705F7C7FCBEA9C03F79917B7E +:1092E000D7E2FB796E958595BEE3675607DBF261A1 +:1092F0007E4B530D3E3BB57B147C3FE161C6D2E013 +:10930000FDA57F37123C4BDFB88161BC96606F666C +:10931000E8D7CA79ED4F7D9AF063ECB4911D64E80B +:109320009202FEBE2B687FD15DD3857EC7C5274DD7 +:1093300034DE4598A313FABFD8690CA3F37E283511 +:10934000316280B6B1CD41F63B0F7D50787F4EA79C +:1093500023ECCD8FE2455D3F9A45C0DE25E4F0F970 +:109360002F4DB587EDF934EFD5386F09A79C776E8F +:109370003F71682495DB59E62FD6D1D903315917AF +:109380008EAD82F30FFD189F34519C383BC54E7053 +:1093900086178706D798FACE6F997BEAED77033C5C +:1093A000AD478CCC08FD78BBDB091F73001F616FD4 +:1093B0005F7C9FF5E67F653012DC11E447E3FAF14C +:1093C000342F867E3D7CD7F073853D9D8F7C199C24 +:1093D0004074CE32B0ADF97DE7F1662ACFDF1E4E84 +:1093E00075D2D5EC2EE272E21E38780BF4F736EA2D +:1093F000290B8BE707FC3E95FBD3748DD54F600797 +:109400004308C785F50AD1F3A412369B006575772A +:1094100036933F20F593D16F24FF43EA290917E8DB +:10942000B10F5235F6D198FCF050ECB77F7F6DC785 +:109430003E33FA6B4E46FE9AD4A3FDF96BE8A721A2 +:10944000FF493FED54CC3C617E5F8AF97D196F7E08 +:109450007DF4EF3DCDD2CFF973EA15FCCC0C737CD3 +:10946000FD744D1AA74393D3CC283F85F132FA0FF0 +:10947000F30CE1CD988752C3D6291AFC64A5493F65 +:109480008FFB1BFDE9BDABC525052B4B48FF5EE8F7 +:10949000F226A7C235FD53A5395E3FC6452F0C43C2 +:1094A0003ACDB356DAD2004E679A1E5F4F2DEF6366 +:1094B000BFD2D238FEE8DA077F76C09F41E727EEB9 +:1094C0002AF212FE3C6957F013CFDEF15105DAA5FE +:1094D00073024F8DBD712FD7D35960AC30AFD5C05B +:1094E000FCCF9E28E6EDCB0AAD7A50BE6EA33D3090 +:1094F00008FB6FDA3DF159ADFDFE3A95E7D3983D93 +:1095000095F2ADB23F97D0FB1067DFFC9997F4FF5F +:109510005748DF68BCDD5D81F156EB4BD724A37F54 +:109520003676D7DD4EBC5E481F48783DBB2BC18FD9 +:10953000709E4D057D6CC7F688439887F872F1E1FF +:10954000542D5DCEFEEADD0A13F47376E7BB152ACF +:10955000E63344BEA6D71E5DFE434500BE0F8D61B7 +:10956000C5CD760D9F58B8BD78D2CAF31D192EF31C +:1095700032763DC4231929F4FD1A97E12778DF6874 +:10958000F943DE0994B398FCCE93266FAB1DF80C1B +:1095900062391FAE132C18ECF7CCC6FCCE1437E59D +:1095A000655A15AE4743B3791C9A5EC08AF3A13F52 +:1095B00093C168C4EF7A3CCCB7195E4938D01E41DC +:1095C000B597D8D5E147F0CB1353099FA3CE3815F3 +:1095D0008C27643E48ADE2FDF54C3387376BF24093 +:1095E000EE192AD9459BDAC1504F3F90914AF0CBF2 +:1095F0007C50D5D419814A84EB5103C533A078152A +:10960000D487D9621EF99E9DCBA56FA3BA902D1960 +:10961000267FD84AE0FF8180E724AFC18FF9D7A425 +:109620009CC85113F877D94B19FB44E347DACC4275 +:10963000DEDE3192BC39BEBEC53203FC235B22CFD5 +:10964000AB260596CDC7BC38DEFFD732A40BFF9EF4 +:10965000E863C434150B2503C88E91FA7E25FD3AC4 +:10966000175B7C0381A1772E76D2F5B9C56E82EBAC +:10967000F1C55EBAFE747131DDEF4F4EAF767D6C91 +:10968000318CABE1A7F4118015986FBA91913C3FF2 +:1096900036BC2279661C7F405E9F5E7CD835769012 +:1096A0004020D023ABDEB969453ED119850866F765 +:1096B000CE72FF68C61E35F9E73360ADD5695F8F9E +:1096C000C5BCD54AC54079AAC7D3DE5C1ECAC1ABAA +:1096D00097E86EDBFF3EC37CA7A7BC5D4179F7D45A +:1096E000B7131F947775B1A0B8EF87B6E708BFFF2F +:1096F000A895E379156313105EBBC202783D67E558 +:10970000FEE0E756AE1FBF10D72169C18D28C7FF05 +:10971000E53C5AF42880672DF9200FD73B6CFBFFFE +:109720004AF960E350B305E5C3B3F738AD83180DCC +:10973000DD660626F9F5273EA6FC9AD11CC8E7EDA2 +:109740009756603B2329B0095D3616FA78E2013757 +:10975000C80DF2C38D848D10CAF14AAB68878E1193 +:109760001E569A78FBF527FE44F35E690ACC43BC8B +:10977000607B29F4B732A5C36D80B6BDE5FDE587F2 +:109780006FC2B67CFFFDE521F8FEE534A96F021E2D +:10979000D41FBD6D27B48768DA2A6F330BBFCAF9AF +:1097A00035ECFFEBA16CE0D7C6BD4A0782E6D9BB1A +:1097B0005AC1797A76AF267CD31FC8074E83F2A4AC +:1097C000969019BF7F6EF161E752A0B39ADAE64234 +:1097D000BC5FE30EFAFDF1F21319D2FF85F7B579FC +:1097E000B6B0A9A75BE38F7B18971BB614F4431C94 +:1097F000FF626846E517E9D0CF934A708511F5CC32 +:109800008B2627EA11D6C5F5D019D1170B67917FA2 +:10981000536FE54DD392E08AC1A827EE557D183FDE +:10982000D7E5B757A27DAFDB93EF6B61517EA94BB4 +:10983000E9709521FFA4E8DBAD22EF9299D29C92CA +:109840005282EB11ABF370BDA091B5DFF74384F703 +:109850006D23433FFD8B7D37248F827603B4D16F18 +:1098600068E87CD78CFCF9443AD79F8D9DC03FD0E7 +:10987000CF2A902F3F38329B546722EAA7E7FCCDCE +:10988000D7A28BF7F5137F9B6805FA3E5FE077223E +:10989000BDDDE9A61516701A9F373B07B3526CDB86 +:1098A00089BFEA4A0D5C8E98FDB77E55AC7F42FBBE +:1098B000F813136FD3E6773DB82E03786EDA600F96 +:1098C0001992C9DEFC6FB4B78DEB0D21D45F064B46 +:1098D0009719E9EBC6B55DA28F93F0B650EAF3187D +:1098E0007DBD7062EA6DD85EF86881337485FC6571 +:1098F000ED251B0B6BFCA327D2B91CD7AA215A4715 +:10990000A9BD9444CFFF79E3595978D895C6B3D30C +:1099100073395E7D743CA2EBFEB2DFAE1D08745B52 +:10992000B8C36448D0F0DDC21D62BDDAEACFC47EA0 +:1099300032CC4CE01DFC7DC0AF9ADFDB0EA920E7E6 +:109940008FF5CAF98015634723DDA2CFD9489D1E44 +:10995000F063BCF958A2D403D7C47F3F31E6FD02BF +:10996000D9F6AD189BD3179E8CC468DB02EFABFF12 +:109970009DD0DB46F8561B62FA4B95E38FA4FE247C +:109980005F1D4FABFC6D68203C4F69AFC4FA8D9EE4 +:10999000D9CC8B7619F9D5A7D1FBC7D3B85CD75EE4 +:1099A0002AD4D13B8AF722DDFD938BDDBA75BFB98E +:1099B000D50B697DF238EA79EC878528AEAADD906F +:1099C000CDC21A7FEAFFC3F18FC231AA1F386EFEE3 +:1099D0001F86235F279F513806EAEEFFA3706CBEF7 +:1099E000ABE8B67C78658D12B214A05D78C440797E +:1099F0001363CA586F0BAE3F3CA2929F872E09D6C5 +:109A00007F14A8ECB05A86F2D3EEC7389F2DE1F947 +:109A100023B8DF662A233B447E70E1DE8407D04F03 +:109A20002BA8F5CFC32BCB29A1F50DB92EC8441E09 +:109A30004CAE670C72B24A159CB751190F909D2A13 +:109A40000854D7A13367749427A27D5C630887709C +:109A5000BCD0E37CBC0C43B8C382BA3769A013ED19 +:109A60005D4612D77F6C4509D9BFCD86826BE7036F +:109A70001C8F2A95896F219E530A28FF8BF717C0E8 +:109A8000FDCDC26E19537C4EB4539B85DD6A15FA29 +:109A90005DDEB7A5061E407FE254FAC2DB2C37A07C +:109AA0001EF2B7A581BD3999BE7085DB83F6C65B12 +:109AB0006001FB72F2C987C8DE6C6EF1663953A291 +:109AC000ED41FF0DD69AF4C4432BD05F596A5FF085 +:109AD00020FA3BF0FCB716D0B3CFA70ABD239E17E0 +:109AE000F4EA29D04BA0C78C2DBDED10EAA5825E0B +:109AF000BDF310E99D2D1B8DD47E07C643FF07E6FD +:109B00001132E27C07A9E4D75B019644685B071732 +:109B1000D03A11CC9B25A27F3D983F97F97CF3204A +:109B200003E5F3F17DC4A3D5C3DF374F613E5CD7B6 +:109B3000323BEC1487C8F501A358A74A14751A8A5A +:109B4000730AC5779655650B301EB30CD4AFC39A14 +:109B500063EA398CB1F51DF608F95F5FA48BBC7E12 +:109B60001A735F2E8CDE07BD5D8657D7DD4B2B1138 +:109B7000DE050EE634625E2518A175CE58BB66017F +:109B80003BEAD5C887C5CEFCF1EA090E65703FD621 +:109B90007E49A5F8E64905FC1BB4A30ECE67D23F6B +:109BA000323925DFEAEDAEF4974C297C2E0B278E57 +:109BB000C9C4F8DD68F75BD0CFD9E72CA3BC80918E +:109BC000F96EAFD4F83B4B231329FFA63AFDE48787 +:109BD000178A38D1E8F431AD9FB36C310496D73091 +:109BE000F66C45D1189487A7AD114B21D2778D81A2 +:109BF000E2BDFD650F8614CCBF2D6224A7CF56B8F9 +:109C0000C6601E7D931A48BE17E5E5088CE7E5742B +:109C1000E3EBB9AD0AE68B2F5A02C9A80F1E43BE6B +:109C2000D7E0E5D7021F7F4FE7FAE75113978B651F +:109C3000004F04E0502F5D47F9ADD5193CEF61AE00 +:109C40001E4BF91F33E003F37B09AC39E4A4F9F2AE +:109C50007C5D82DBA0AB0B542F0DA5EFFF9E6ED079 +:109C6000C5D56D304FAF467F595988F27588E3AD41 +:109C700071FC977732783C62017FC84BFE49CC3A41 +:109C8000775FFF88FC15499F5E3F4501FFE40AF1BD +:109C90005813C4CB5A7DDFA4F690FE6D827818EF7E +:109CA0009F735AC83F94750F76A1CF96B983EDA3E1 +:109CB00090CF139386621E40651D84945558F7809B +:109CC000FAD0ADF6F4F23FC87CAB356933BEB75479 +:109CD000D441D87C7AF94964ED113FCA67B1466E28 +:109CE00018E23B44FD2678F5F7190B328C33547794 +:109CF0006C9D44A8B71E8AEAF954F614AE5F4BBFB8 +:109D0000375BD4239DB57D447934F07B2BD3681D1C +:109D1000A087E21699EFF9B67E7221F68179844523 +:109D20007FA938817236657C3EDEB7A99C4FC0158D +:109D30005713CA30BC1A3F2F05E67FB7B07FE9C67C +:109D400076AA1B795DC4B3FFE59CE1A1380AF0490E +:109D5000F53689BE6E8A17859F66ECD58F1F2FF763 +:109D6000EBFDCE90D6CF5BB9E6E3E54B79BC42ED97 +:109D7000D79F8890FE7CD42ADBAF501BEC5C04E3B9 +:109D800025B62BC18B7C08DFFB51DED85D45E4672F +:109D90001B0B5816E2636C9285F4A67157C266F4E9 +:109DA00083212E7E394DB35E7CD671340FFDE138B0 +:109DB000FD8574FDE57DBBFE60FC4EACC791CFC751 +:109DC00026AD8F18F9775EFC8EE5747D1482FED780 +:109DD000BC94C056000A9F36E9E55D5E370B7946B4 +:109DE0007DA3AD873457D7F891A9A55C27B813593F +:109DF00044C34F52CED54B835944232785197C5DEC +:109E00005555FD9447522F95D0F3BFA34CD338CE70 +:109E1000AB8C93DACF38C3487FF43F4E85D02F4CBC +:109E2000AC5FA9545723F5427F721EBB4E16AB1789 +:109E3000E555EAC5CC0CDEFFBE0C7DFEF5C1F51D77 +:109E40008790854EDB830732A83EEA58129AF07A53 +:109E5000436428F2F1677DEF37E2E4DE4EE379FFF9 +:109E6000A26DF3DF4076EDCA085E443FE8B71962A1 +:109E70007DD20DF6D088F60EEC4509E5732FA6636A +:109E80003E37E85D378EA13CDD45F9DC6457A00420 +:109E9000FB5F36B582720E12EE958B799D9AD4B324 +:109EA000763548F8B2A8217E7506C186337621C37F +:109EB000344955109F5C8E8EAEB940726055FDC41A +:109EC0005756A7C18B7E8115E242D4BB2D4E035F4E +:109ED000BF715B28FFBF4C810811F4C68294822BAE +:109EE000AE8F9B2FB9C8DE02246EADDEFEE78F93E6 +:109EF0002EEC837E1CD5C9FD06B69FDB6144C2A74C +:109F00001A7D2CFD81D8EF62FB97F894F8B5205E9E +:109F10004BC81EC6F537AC2EFD7A66A6D4B71947D6 +:109F20008B2270B741E94E42BF06F4A8D5857A7AF4 +:109F3000484F92C14BFAD7C5FDA090E06B66D7F2AF +:109F4000B5CC53CB7949F817BC35DBA25D7F898549 +:109F500037D6CEDA4BF4750B56AFBE6E41EE0B30F2 +:109F6000AA01E21BD368BF05E5A4C559E6443F67D3 +:109F7000A9EAFDA39FEA2D4CE46F83FFAE1B5F5E51 +:109F80001F03F947384A5D065D5D8DBC3A701D259B +:109F9000CE77535C5C4F3DB6EF6ED2C3AA8FAF3322 +:109FA000C5D28FB176E21747117352FE54C09B742D +:109FB000957EFBE3A39FECB3929FAC8EB484B1AECD +:109FC00033763CA329E05750EF9632F2938DB97C5B +:109FD0007CE3204675E049E5A9AC5883C765EEA946 +:109FE000F47C41869321BD8D0E43201EBF483C0D5D +:109FF0007419747CE3967CE3F9A008E540C33781CB +:10A00000787C33D0C5F515C2A1A5EF327741663C07 +:10A01000FA44F522E7ABABF1C54C1BF7733ACD5CC4 +:10A020006F36208E205EAACF302FC3FCF7190B7F2E +:10A03000CEFCC5DC2FB3709E9B69CB0BA33FD4A98C +:10A04000FA6DE897CDEC5DB7F5D37E8F7AAB3FF92B +:10A0500006B48FEF72BFF964A5BD4D817E4E9AFCA8 +:10A06000C988EF93EF1A95165A07E7F573B20EE910 +:10A07000A4C9BBF25A783EEB67467F0B3DD6FB8303 +:10A0800067987FD83BE81FEF36D27A4BFEE30F1874 +:10A0900087C0FB35E028223FCDACB287D00E777E5B +:10A0A000D0FC11EAA3591B13BC4BB08E65FDB0AFB9 +:10A0B000B0FDF92A873781F26C058A07F35FABF3AD +:10A0C0009DB46EB2888978EECE4955A0437F89430E +:10A0D000CBFC35CCF973269F87568E85795E9BD154 +:10A0E00069B0034CCABAD04A0BD0EFD196801BE3BB +:10A0F000C70ED7F495183FBA5CFEAE5B205E3CE11C +:10A10000BA7B12B63B9F96FDDDB3D20F7AF91543A9 +:10A11000305F81E7B6CC872651FD6AA1EC7F193DFF +:10A120009FF9F36BBE3A0AFD97AE5B3F09736E155C +:10A13000D5E2FBD03304DFECD1B2BDD9563510BE29 +:10A14000B7315D1ECD148D47294FD7D9EB5F3D3711 +:10A1500009E3CF59639AAB54E87FC9BAED2B4B4062 +:10A160004446B4573AFDD0FEF1BA3726D980DF3ADB +:10A1700099BF0EE3DD95EB0E4CB2DC04FDA7E9FBC5 +:10A180004F378A7C6CE8F04ACCE3F5C2C7DE5FE962 +:10A190001F187D7F983B61552827CAFFFF22F81FB3 +:10A1A000F8FD572E5C07B4741FC2145DDEA21E3387 +:10A1B000AF7B15F52939DD4379DD8D681777F33AE3 +:10A1C00065D976F376E792F8F6FECF6E2E779D8905 +:10A1D000F19F7F24F439C0EDC7FA95E4A3CCBF3DCD +:10A1E0008E3C1D74D949FE0E82BF67498DCAD5EDDC +:10A1F00020DB23B1FEC7C2E194FDC47E7F4CE8277B +:10A2000016BA3D15F978B2E0F3429FC2EB7876DBDF +:10A21000C283D0DF6311F50E98CF3691CFD8666533 +:10A22000F74F81A15D892CB803FDCF346897D0F733 +:10A23000FE1DF6687F6F735166E30A035BB0BF7162 +:10A24000999ED2D6FC683F00F7524B990E6E75640A +:10A250002A3E0F65CD2FD1E0B384CF03F884F005FB +:10A26000C3BC700BC84B67D7B5052B600A2B5D5E6E +:10A270005DDC57D13595F6A5FCA79BFB3FCCCBBF4A +:10A28000CFA8E275213D7B6C94A76096AE22A49383 +:10A29000FCEE92C047D58F27AFC3F7EABB4C8CEAE0 +:10A2A000FF77545ED11FA8C7BC9EC67FAC5723144E +:10A2B000CFD5635E6F18F6F7B619ED18F6E315F90A +:10A2C0006BCCCB65B4C6A7BFB487F5975258685816 +:10A2D0005FBD19ED3F9D9E5F6D5ED1FEF47167DF3E +:10A2E000FECC621D40E05D157837C7877340A6E05D +:10A2F00053C0B741C35FB305BF81F6243FE0DCAE76 +:10A30000C19B57E46BC7E5FB6E403FBF700BEACBC8 +:10A31000AE448A5B2A54FF247CBFA22B95D6172417 +:10A320007F48BE9074ED4C6DA67C4DCF530AD9C1C9 +:10A3300058B88A245CEB158223B33A687C40039FAB +:10A340009407E8BF53F45F3E92E4E7192E0F2037DD +:10A35000F7A2FCE27A25CEC3D73D74EA90BEF0FFA7 +:10A3600014EDDF70A223C7FF4B5651CFC1F1D617B2 +:10A37000FFD957A1671E3DAFE87A83E659DF8FDC2E +:10A38000BEED4E2238338F4692BCF0DE1382FF3B87 +:10A390003B3E4D1A8572B1DBC8142F9F37EAAD0AD8 +:10A3A000A98FD99CB7C780FECBEC6D83BEF4221D6C +:10A3B0007AF567C46289BEFFAA7BCEE4A5F02C3D86 +:10A3C00081CB6BBA11AC4D59148E6999DCCF1A1937 +:10A3D0008CEF97BEE776D07389EFA71655B14F6122 +:10A3E0007E3F73F1F5CF91DD2105E922E53A564F25 +:10A3F0002DCCE4F2383FF3FF919EB25E454F59A554 +:10A400009EE2F70F427084EFB95CDD4315F09F6B5D +:10A410000C7E17C66127DEFD21EDE3982BEA5686F8 +:10A4200060DD0ADACDA301B22B5FE0435EBFF20824 +:10A43000C680B3DBF5F52B6C0BDF271ACB57513EEB +:10A440000A09FF5DC021ECC1ED09DDBFE245C67A16 +:10A4500079966D80B3D150A8796EE7764BD201E83A +:10A46000BD94A546E5F8935D999B50DF0E73F3BC50 +:10A47000627AA1BF14E72FE512ECAAE013C3FD53E3 +:10A48000ED5C6F4C8DC3BFCF08F99CBD9EF34DE7CB +:10A49000DFAA2621DE3BDF4B4D59A2D1135B851D80 +:10A4A00094FD4A3D24BF93CF9F15FCB12D3389DA2B +:10A4B0005B5D0E91E731C4DD37B755635F897FDAA5 +:10A4C00038FFC07C435AFE1EE65674F6B5D7AE0A76 +:10A4D0003C379801BF80BF6DA65016D6ED54741955 +:10A4E000A8BF9ADD0EAA07ACE9E078AC69DF67A8DF +:10A4F000D3E027B6BFFFC8E4FEC02603AF233A6807 +:10A50000007E43BCDB397CE77679487F1E16EF5D21 +:10A51000DD6E7C333DB3C9CCEB4881BE54CFD7F060 +:10A5200072F626BD9E6E11F80FB6E23EB6F475CCFB +:10A5300087B55680A78802704F770BBD63F69B7175 +:10A54000DF6ACF538CD6F30755FB4BBDD06E0AD8CC +:10A55000CB14E8AFA89DEBE18A27C18F41B9B3487E +:10A56000BBF0D676ED78C7321D221EE1FC5CB39EAF +:10A57000E36F10F83F2FE015FAF915F9F11C9E4F23 +:10A58000D6768CC2FC93FCFE0B41FFABC15781F029 +:10A590009547E1C3FE919F983DB004FB6DFCC3CE8F +:10A5A0006C6DBF5F65727D9B6E9C39C68A7A7E3505 +:10A5B000D81D92CEE07EDC9750B337C5B982913C6E +:10A5C0001B30EE91E3D6883C24C85DC514985A51DF +:10A5D000EF3892AEEFBFA89DBFEAE6FEDC3F8BBE30 +:10A5E0009DE620CDA76707C0EB8DE2A5B3E38125EB +:10A5F00056B41347990FED84847750757712D69D22 +:10A600003409FB01F33560FC92FE332F6B45BC75BA +:10A610008D3163FC14CBD7924EC58CCB8F8CD38AF3 +:10A62000718100DAB9EEA142FF308A773F79F9D51E +:10A630001756507CC5E9D254CDE958E90E4E7767DC +:10A6400044E510F47905EAAB9A277BF55107BFDFA3 +:10A6500095570DF8BCDE2DE55C4F97F4408715D774 +:10A6600035245F9FDD3324BC82D399C6EFEC708420 +:10A670001505F7A136B760DC2DF504C2A3ADC39470 +:10A68000F0F4D291011D8744EF0FAAE6FD3581BC9D +:10A69000231FD51B9B158F427A80F2AC99A807A087 +:10A6A0009DD9C1DF637BF9B908124FF5D3A1538857 +:10A6B0003BFDEE129A87C4576675C4500FB72658F3 +:10A6C000AAFC2734FEDA61B1DE8078994AF106D718 +:10A6D000D7F5C6400EC6AD2C3381F671821D22FD22 +:10A6E00072D0CA542BF4F7265CD12E8D33CEA77DC1 +:10A6F00034E30A159263D00032EF13417FFAF65B20 +:10A700006C24FFECEB8706E23C336C9C0FA11F8BA3 +:10A71000E8C7427650D883DFE7815FA744F5F2416E +:10A7200045A17E0EDE74DD66AA2D147C89FDA1FF95 +:10A730007450999243F6B23343141771F8FBB7671C +:10A74000DD79F85C1B2F627C178D374B57DD0A3C97 +:10A7500035624247C4E044E9289FFC7D807F1CC4E9 +:10A760009B5698FF0382AF0FE6878C4908D7209845 +:10A7700037DC3A94182C69B647C77189FC8D4BD4E5 +:10A78000EFA2BF80578387EBFF9F78B8BDF8505C7E +:10A790005D49F1F33D17C5F38FED5C4FAFA88CBF5A +:10A7A0006FFB11615764DC79BB58EF80B8F3113748 +:10A7B0008F3B45FD295F1F01FF9EF05BF5E36A5A61 +:10A7C000F7BBD8352D999F87C0F5C12C51FF79FF74 +:10A7D00023D37E8A7C7602EBCC010F9F0A7E39E17F +:10A7E000F427619D544362FC3AE267053C0D020F79 +:10A7F0002717F3F30B66E1BA1CF0DF1A37F7F3E61D +:10A80000B60F1B8F749FBB4AA17539B9FE2FE95C47 +:10A81000BBC1A8CBAFCFC275B9B47F249E2AED27A8 +:10A820009E2AD7C55372DCD8B8EA93C56EDD3AC00C +:10A83000CCF642717E047F7F16F311DCB3DAB27579 +:10A84000EB88AC2DE31BEDFBC7382A14173EB3EEA3 +:10A85000FE278B2D2CA485E3D440AA9F78C41D7CB1 +:10A86000C5AD83C3C642BA7CE86827ED27B2F23C87 +:10A870002CF8E33C8E81EB263BF9EB13D09FEDCD1A +:10A8800087811E7126A35EAADCEF1E1E8D1FA49C6D +:10A89000D58F8E1F47AC117ED01A178F93938FCA16 +:10A8A000B83AD18BFA51FAE5B1DFBDD7CBBF7ABF49 +:10A8B000F26A7908E0E390364E8AEDF794FB1F8D3B +:10A8C000BF0BFBE197A2FF91F8BB627490F27CACE6 +:10A8D0005DA19A961163F5F1D0D768D787E3D5A625 +:10A8E0008B876AAAF5EF310FB7FFCC63D3F9F1FD7F +:10A8F000E153EBC72B85A807797F8D822FF24FBFDD +:10A9000047F5A4A33DDC2FF265F9133C705D25EA01 +:10A91000C95759F97EFE4DFFBDDF3D0BFDA3774CB6 +:10A92000B4FECF7673BEA97C66612B9E0F60EF509C +:10A930009CDAFDABDF59A4F86B40AED3847EACF754 +:10A94000F1F9D4FB22E68176AC2FE670E474EC5387 +:10A95000540DDFE5D4F2F7723D265D5E3C5FB4072F +:10A96000789C328ED937311DDFF7ABE81764752834 +:10A97000643FB39A19F9D559E50AF5FF9DF24DCA1E +:10A98000AC92E87CDB0C534A9CF05D9BCBE643FB2E +:10A99000F3C3ACE0351E84EF582482E672C4B12EB6 +:10A9A00015E3AD5559FE62C4839CA7D7E8CC423F5E +:10A9B000DE768CC3D7DE9B67E2F687B195C22FDDCA +:10A9C000CCFD33233BCCB87F4E76DEB5A498ECA00B +:10A9D0009C8F2B55D811170BEEB4D3FB6DE4B758F1 +:10A9E000B81FE05A5244FEBCA46B34EE1C5C867166 +:10A9F00067E1AA883A13BE7B798321EE7915E305D6 +:10AA0000DE611E95DA795C4D6FC9F74CFDE41D25BA +:10AA1000DFDB26C48FE7C112D2F3CA67D2EF21F978 +:10AA20005C6A6698AF96F85F9515B813E1C9EAD8E5 +:10AA3000A4206E3E11750A9F24F27CFC272B5E50E9 +:10AA4000D0BF7C681E731A59FF70D72F32FA6BB4CF +:10AA5000F2BCD44C7491F14A141E9E8769F070FBCD +:10AA6000B42F2B5083E337EE5E4D71F5BC2DC7CD6F +:10AA7000575C87F88678536AB9BF5E3FC342F54C8E +:10AA800095CFA844F7BAA5665A37ACDFBE83F6A7C0 +:10AA9000B187990FE5BFBE63875203E3D66DDFA18F +:10AAA000CCD6E031BB3E4CF5DBD738E47A4484FCAD +:10AAB000E958FEC63C02FA2F87AC5CFECF54DA435D +:10AAC000B83E71C614ACC7F7CE786C3E5CC79478BC +:10AAD0007F73C7AD745E8063674204AF6D86CD6ED1 +:10AAE0000BBCD776ADD987FCB42A2BB81CF192AA3F +:10AAF000063AF1FB9474870FD737BC09AC8CECF79E +:10AB000037C4C38818BE18F130979757847E813FA9 +:10AB1000AAA77AD6C3FD725C5E427D75C8C4E7B150 +:10AB20009371780D1EFF7A944B763895C6CDAA8F17 +:10AB300028587F113B6E94AFFC1B3D19DF06CE0EEB +:10AB400033EAF93AA16F2A9FD9A27CAA81FB458FEB +:10AB500091E0CBDABE49C1FC193C277D03EF33AC51 +:10AB600077CADACEE3D53A783E5BA35FE43CE2E80D +:10AB7000994E84CF7EACEB00D73311BE5E20E08DC2 +:10AB8000A567C4E3A5F1C783BB40F7CDA1628C974D +:10AB90000F1524527F52EE63E534E2E17E65D686DE +:10ABA0002D8AC14EEB2AE45F4AF8E47BBEAC310744 +:10ABB0003C84872EC243C30695E633CE1C18385F0B +:10ABC000230FEF89FEDE98FE119DABF3E4BFBD4B72 +:10ABD000FCD8007136C519EDEF9AA7A19D09FDC2F9 +:10ABE00088EB6093B88BC2D68A73A72675723DDC5A +:10ABF000D0B9439D658FF269FEE937E8BCAA868E1D +:10AC00000486F115F0DF518427964FBF293D411F7F +:10AC1000F1F829641679BE603EC63F524F1B84FC92 +:10AC2000333BBF7F41B4A3FC133CEDD1E9592BC9A1 +:10AC300045FEE9B237B0DEB3C1A7D0791D129EF44C +:10AC4000AAF87EBBD48F526F633E31A0D1EF1705B7 +:10AC50005DA11DE1712A2B403B2DE18CA5D3802CF9 +:10AC6000AEC7E3F0D3DF11DE58BB25ED79FEC69DFC +:10AC70002AEEBF917C3209E9ABE113479699E07067 +:10AC800064A9D4FFDA4ABEEEB8D6C4EDD5DA160B05 +:10AC9000D561BE7937AF0B73DC638EE0F5A06166DA +:10ACA0003D3E3F98C5E168332CA1FD68207F49599E +:10ACB00019C827498CEB41AEF79EFC0DD75BF521F7 +:10ACC0003BC5B9F5C13B6B68DD3FDDEAC37A591678 +:10ACD0003C609EE688E235968FBC3BF799711E93E7 +:10ACE0003AB8BC81DE243E8AE22FAC9313290F864A +:10ACF0005E3F2198CFFD201E479588FD81B5161F28 +:10AD0000ED2FAC15F9D612B14FB0E2A89FECC14CB3 +:10AD100041878DF6C0755998A75915936FFD8671B7 +:10AD200040DDA2DF51DCF5A0FB2DBA4A79847855CD +:10AD300027B73766713F3B5F5C2BB3389FD495775D +:10AD400090BCD59D682639B54FE0FACA7E2CC62F37 +:10AD5000648F09BE5B45E38EB3758CC7F5E2713F26 +:10AD6000579CADAC7F38E7E23E2B8CE736EC4F7A50 +:10AD700000E5F96B882634FB70A666713939B30D8E +:10AD8000104EF6A8D97C253FFB6AFDB1C81185CECF +:10AD9000F910B83CB3BDEA86CF707D675BB20FF7A0 +:10ADA000D37FB9FD8E1F7C06709FD9728B0FED7F0C +:10ADB0007A6B80F8A527C3EADBCCF3AF13303FD51D +:10ADC000D2B13F09F7ED7CF1C2F565A88FE7657157 +:10ADD0003D75FA37C645889725CFFFFA667C5E1722 +:10ADE00056D2D02F3DB3EDE77FCF827E6AB734E1F4 +:10ADF0000962ACF585D7C9DF378437F1FBDB92C92F +:10AE00007FFDE2D9D53723BE5B3B5AE9F9E96737C5 +:10AE100051FB8DE77FFDDADFE0BDFA4012ED673EC2 +:10AE2000FD9B7D4497FAA04A75E7BD7C1CAB077774 +:10AE3000ECE37A10ED37F2FD0CAE9F241F4BFEFDC4 +:10AE4000E2F9FB6FD0DA0379BF4DE469DA12B97D1C +:10AE5000F852C869DD187B1B5EBF7CD14AE76E36AD +:10AE60009ABB8B307EAF2FE17CF17D818FFA8EF91A +:10AE7000A6463B7D4FFDFC27303D5E87007F627D0F +:10AE800017BCB5E532D529FD8AEB99443612F33863 +:10AE9000D3AB8FF37D9B25CDA63A82F305FE1C66CE +:10AEA000AD7D5EB1307EDCB83ACBAECBD366754EAD +:10AEB000C9F192DC27F80669FCDAACDA60AB03EE84 +:10AEC000DFB630E8C37DEF2F9F7A6F3CEE4F78BE40 +:10AED000581946F4372ADC7E85EC344E03AE0F4118 +:10AEE0005CF1AC9013084BD36F84F98C53593A6ED4 +:10AEF000DD1DC7D81113E985ADF41CFC17F2CBBCDE +:10AF0000AF4FDF8AFECC5A53D0331CFB6913766FE8 +:10AF10000B871FBE77DACBA83FE78DDC0F5F80DFA2 +:10AF20009D6F999C8E7E3BF4DB65D2C459C09179AC +:10AF300068F7B0BF72C4D384D00CB23F5E33CD4F3C +:10AF40009EE709F31F7AEF90A87CC6E691503F6117 +:10AF5000DE775F56E55ED433F2EAEA270FC3B2F933 +:10AF6000737FB69FAEDFF47CD037A69FE3F6FB95E8 +:10AF7000E3C4B78DC8B7387EF084CE7ECF927CBB59 +:10AF8000E738F1EDACDDDC7E37EE2E3523BF7EB940 +:10AF9000D8CF3E0507B651F0DF5AA57B0EEDFFDA9C +:10AFA00063A57D7DE7247FAE3AFE39D69B16ECF68D +:10AFB000509EE0DC1ECEA7070D068AEF0F6EBE6E18 +:10AFC00053ABD2D76E821F4D72D2D8CC841FBDF046 +:10AFD0003DF4BB1A6A799D79630C1FE56FFC641917 +:10AFE000F24B0A78BD583F037ECA78DA1759CF86EC +:10AFF000A39C668DF5EFC9A6F53F1E7767D5823E07 +:10B0000081F66DE9F37C789455CA58F07791FFD2B8 +:10B010006FF2613E6C6D6EC732F48B43E3189D9BFB +:10B02000BAD6D43E06E3DBB5E3BC4EC024E06D0BDC +:10B03000F9CDACD82CEC570DF9DB8DEE7FF551BE78 +:10B040003A56FEF7B490DFD6E84DF4E139B6937680 +:10B050002B0BB89F6267087F23E017DB93C2A3C264 +:10B0600008CF59813F89C773A62E3A4FF7DC4B09A9 +:10B07000743EE1A4B19C5F53C67690FE7873CFAD69 +:10B08000649F255F3A7625909D4E559D0AE62F18C0 +:10B09000BB23414BD77651879B22EC48E12A4EDFF8 +:10B0A000C46CEE6724661BC4D52CF85C9EB712A254 +:10B0B0007CC259417FFCF36ACE6B6AA889903CD56B +:10B0C0006FE7FDA527F84B1FD2F0AFF497E47A2B7A +:10B0D000AEBF4E89C3DF3E0147FEC60544F759B5F2 +:10B0E000E23C8755DC8F60C0178837A023F1C16D23 +:10B0F000E973896EB35629F7101D431594D7947ED2 +:10B10000576CFFE5D95C2F6EB306CAB18EAF27C36B +:10B11000E1C3FA806D297E03AD0F94A6507E2323F0 +:10B120008DFB8119C20F8CCA7DA0DC00E39C7239B3 +:10B1300038BDC3BF57316FEDCFF6C6F5EBFAC6EF9A +:10B14000BCBFC9EDA1A118CFC8F563898F704BE2D0 +:10B150000CAD3EBD51E0233C98CD40BD0171829DB8 +:10B16000F2EB4E1807F3049B473DCBF304FC5CE77E +:10B17000C26C9EA71B97162847BF2CA330B090DB4C +:10B180004F3ECF587CEC13F6FD8DE9F795627CDAE3 +:10B1900078A7DD8772F7E42BCA4CE2EB90050FFB32 +:10B1A00001BEE772080E13D5ADB1A04AF4686C0E6B +:10B1B00084E3F3FD1492B346F0F3D0BF9F847C9EEA +:10B1C0004E7C1FE67CCFED9FCC23A09ED4AEAB4837 +:10B1D0007D20F50CDA37E46729178D377717217D45 +:10B1E000BFA95E3967E2727E0EF0807224E5C6F177 +:10B1F000329797152DDE4A7CBE02E45E4BEFD8B83D +:10B200000BE1C4F855EAF71F66051AB3318E3044D6 +:10B2100096D1DE52A18F1B5F5E5E146F7F90D4C704 +:10B2200016711EA6256C0B6BD741B0B6C25146D71E +:10B2300010DA23DBA2F87996966C695FFBD4A5B58A +:10B24000640FEF5B97E642DB85F2B3D946FBD4642B +:10B25000DE29B6DF87B2155D7E47C625B89E81EF31 +:10B260003F23E4A75DF0E573D932CF1BD6F1BFD7FA +:10B27000103C8E7505FDD931F9DD3F2B0F26C791A6 +:10B28000F63496FE723D06E733A5A4FFF7DAF731F0 +:10B29000B1CEA7E7C717859CD46533BAB69B2217F2 +:10B2A00049AEE63B18D5F3AC67FE345CE77BED1A9C +:10B2B0002E0FFE9E22EC7F606ED09A9311CDF7E2A6 +:10B2C0007D8C3FEB54164A009AD46D3385B5FB64F0 +:10B2D0007E86B58600C779872564043EAFC80DEE2B +:10B2E00045FE0A8DE1FBE1423FB4D2FA1438D2C3E5 +:10B2F00051BF34B1EE24C473A3B1AB08F393D5AE00 +:10B30000E03EA4FF2786AE3C5ED7C1D7CF8E897CB6 +:10B31000EE3191CFED344772BF9F1E3D9FEE02E3A9 +:10B32000755517BA0CA918F77DB8FB0F2FBE025F31 +:10B33000DFFBCAD97B7F84D85A61BBEF6770ADB69B +:10B340001803AA26EF76CC115FCF7E20F8A8B7EEBF +:10B35000A925216E3E7F6B0E7FAF2966BD7A6B0EED +:10B36000D7A7D17D4F7CBDFAC37ECEB5BA2147D4D5 +:10B370004B8A7AACD8E737E7707EDB666245EB1123 +:10B380009E4D0E5AE7672A3F8FACF6897C1FAECFE1 +:10B390007716F0F3EF7BD62864078E99B8FE81BF4D +:10B3A0003B2D15513B8A6E0AFA89B5CE50C400FA7E +:10B3B000A376A12382E760C27D7534CA5AC8497555 +:10B3C000C133857D9CD5FCE65F319F51AB32CB68A4 +:10B3D000F8EEA4BD2609CDC39CEF3E8447CCB0CC8B +:10B3E000EA76513F2ACE57F34F365EB65DC9AFD3EA +:10B3F000EF1BF9454E80E5C0FCAB9339BEAB1FE2B5 +:10B40000E7ECCAF77F23E43696DFB621AF02BC1F14 +:10B4100029DCBEC48EE3CC1DF302F253B53B60A31E +:10B42000FE1F3A4B7AADFA152B9D7F5487EB5CA03B +:10B43000F2CE9776152DCA47BEEEC9FB23E6C9F6B4 +:10B4400026505D721DAE7769D6A7FB5BEFEA7F9D44 +:10B45000CB6B46FE6DBCA410FD67EE7DF328EAEBD6 +:10B4600046B59BF862A6C54E786FBCA4D273D6666B +:10B470003AA3DDDFB6D0EDCF47B8433F1E9D42EB88 +:10B480006599709FF0574CE7632C10F5E0CEDC60B7 +:10B4900031BEB7CE96743FC67D172CFC3CA4263334 +:10B4A000AFFB6662DFB0A43FCB71E8E9BBF7ADBF8D +:10B4B000225C3596209D2B397B06C4C946A447647F +:10B4C000B8B3444BD7D1DFEA5C5B7B0ED7371F9A0A +:10B4D00079DD4F5FBEE67A69AB7C2F8BCBC787796E +:10B4E000AC76275EAF852B7CF761816897F1766C2F +:10B4F0003F33857C7C3894DBA5D0025BDCF33CEEEB +:10B5000014E3FD22C73F19F125EF3F25E4CF99EB66 +:10B51000BF1DEF83DEBB03F51EF0632405FAAB7E8F +:10B520009DFFBE005BDA4375A7BDF32A12F0BAE2B5 +:10B53000C3F5FD68BFF7607FF09E9FFCF3D7ACB406 +:10B540006F8D4D063D8C7A77412E43BD0BE3CEC403 +:10B55000F1A1DF480ABD9740F3606DA08F41E0CEB6 +:10B560000FF7125D5654029F968BF3F2BD51BE92B7 +:10B57000FC14CB474D424FC5598F6F42B862D7E399 +:10B580000112A237F1DBB7D8FF352A8DEB7F90E7A8 +:10B590001FE4905D8D0CD1D6F3493C4B3DF861A280 +:10B5A0009E2F4C02CE16F15E2F9EC5F953E985DC25 +:10B5B000BEC93860B5A0BB557C27AFD25EC5E6F3E7 +:10B5C000ADA25F6B4E92A4CB6308A7B4737DE8BDB8 +:10B5D00081D31BDE7B9CF44742CF7D6960A7EE02DE +:10B5E000FF07CF9F84EFECF85D9F7CC4586E5F9B94 +:10B5F000163818DAFF0D39A24EBBBC87AFB715C39A +:10B600007508CA1FE81DE5EAF4C3D8DF037AEED750 +:10B6100058EF01E329583F944A6AC08BFD01BE9F51 +:10B62000D7E23B76BC63F808FCBD1D39625F5C293C +:10B630002B457ADDF7EE5F1CF77AF17C72BE1FF7BF +:10B64000337BF025ECE7CC0FDE22FFFE983952D495 +:10B650006E8FF3DC1CD9B84E893EBFFF17C610FEB3 +:10B660001E4567D79935D3812F6776197D38E4CC8D +:10B67000872FBE3302FDE62E13AD1B81DFB00ACF4C +:10B68000E73C26EA0059B33EFE7F57D047EE0B96C3 +:10B69000FA49DAFF79CCC7F552223F0FFD93F973CF +:10B6A000695F700D0B1CC2F3D0BF583091FCE2B93A +:10B6B0002C48E771CF6AD39F871B7B8E6EECF9B95C +:10B6C0009880477CC59EA3FBE5F7AE9C2F97F52B92 +:10B6D000B1CFFF26F8F1CB7EEACB4F0BFE95F500FC +:10B6E0004DB21EE0D52BD70334C5D40344FD0C590D +:10B6F0000FF035AF0778555F0FF0E598F8705C10E4 +:10B700007034E1393A71FB4DA2FB5F165C799E4DB6 +:10B71000782E4EDC7DDF76BADF5F3D822D57E0A9C3 +:10B720009F7A8C845CD9BF47678F6DB9DE183F2B39 +:10B73000879E37C5D435449FF37A06991700BA52CD +:10B74000FD9CF4EF62F7C3CB7CBC949F4F1566F170 +:10B75000501E6DB5881B7C43D11FFE14FD2C94DF59 +:10B760005BBDAF7503A8B37E7443915A1095AFD8F3 +:10B77000F9005F9ED6EE3B1F902BCE6FF0311FED90 +:10B780004B147271DF0FC625633EFFE387AB74FB7A +:10B79000CD7AF7A39BA57F67D7D9731663EF67EDC3 +:10B7A0007E8BFCB71A4B80F6BD7DF6EA0FC8CECF74 +:10B7B000610117CAC9F957AFC90BFE5FD87909CF24 +:10B7C0001DA1074CDC6F4F27FF64AA80E78EBDDC0C +:10B7D0007F3458FC261AC7CFBC4E1785E61C5E5036 +:10B7E000B678EEDD4DBDF097D07919A305FC0A7E41 +:10B7F0000FF8BD495CD9CCA01BE196FBF881EBDCCE +:10B80000786DBDC1E7C5EB2D4A40659AFD9DE359B2 +:10B81000730EBE6FB0741BC5F962742E7C42145F48 +:10B82000D47688F6D23B2FDC371BEFDBF9F9C26602 +:10B8300001473057EC5BB6300BCE3BC11EF982D6C8 +:10B84000FBC4353486FBE3A1025E479C88E717C042 +:10B85000B876FBD9104ED6C99CB42FDFEABC10C114 +:10B86000B844F3BB1035B9C335BF0BC1223C5FD51B +:10B87000DFF398DF8D4815F0B50A3DE9C1F3050BFC +:10B88000E91C05D2938F3BE6D079E219F685B40E18 +:10B89000FD54D2045AA77421E2B13E7E82E61C0414 +:10B8A000789E11D09F7F903943DFF604F56D0B3BF6 +:10B8B00046F55C4A24E0BE9C163DE7D124F4CD9DBC +:10B8C000891CAE3B1379FCD69AABDF971990BFE782 +:10B8D00092CACF4938E7B258B0AE02FC93D65CEEBC +:10B8E0009F7C0494863891FFDE4BE92DFE416BCAA4 +:10B8F000F1774C8CBE2540A7650E6F8B8A7EDFDD0D +:10B90000E277BFD40EAA57D8745F8A0FEB6B9659B3 +:10B910009D9598070DE5F2FC4F93D8A70114A9DB7C +:10B920000EDF6D9A9A4DEFA557F550FEB467392397 +:10B93000BFAA0F9F7E0DFC0FF87E16DB787E438D2D +:10B94000AF0BF7ED7AFC46AA3396CFB7E07380537E +:10B95000117C81F76FA988FE2E53E1DED2FD78FEBF +:10B96000240B2A3E9E8EF412BF4F13FE7CD3DECAF8 +:10B97000DB87035C855DC3888D07EE15EB2FE90936 +:10B98000627D989FBF1BFBFE407C1FDAB6C3DE7F43 +:10B99000ADC7470688BBF1BB31369AF711917F627C +:10B9A000423F8C8891BF515179A0E7A5A2DD24EADE +:10B9B00001F1CC087F054F6FD07BE95C3E7C4CFEEB +:10B9C00071B9BD9145FFB09FAA68BFA4A7C6461F25 +:10B9D00047E510A65866F1B5D6C37B07A7F075F406 +:10B9E000116A641FCAFB28712D155736B39DF0BB31 +:10B9F000A225F286291F532D0123B62B9CCB5BB1C8 +:10BA00009F9B94085DF366AC6E4535EDCD2B14FC21 +:10BA1000161C87F2B96C1CDFDFDC3AD2E773C2A3D5 +:10BA2000E933787E76DA0C0BD54D4F53F9794C4CCF +:10BA30000DE6DF0572765735CF0B63BB5A937791CE +:10BA4000EB204720BED911C73FF0E671BB25BF6F81 +:10BA500012753EF2790E1EF40C001AF2C67F9C4B52 +:10BA6000F684AFF77E962BFCB462561CF3FB315F75 +:10BA7000901EA8FC5D7F7A42FF5CE88969FE274C36 +:10BA8000E4DF0B7D21F57240D42F75897354DE1FDE +:10BA9000C3F1FE5EE53CD21777B266D2E777B1908C +:10BAA00009F1DBABFF2768FC2318675A40EF2F4DE5 +:10BAB0009F11EB57717E95E3DE1DD43F9F2AFDDE7B +:10BAC000097ABFB7FAFB5FA7905DCC7CAEE1F2804C +:10BAD000689D52534C9D52A3A8536ADA3DFF60867D +:10BAE000A64EA9692FAF536ADC7DB53AA51E5A57F9 +:10BAF0003A620AEFC3F59623F3402400CEFDA2AECE +:10BB0000E500D6B59445F9D23195E75D817D69FDB3 +:10BB100024C769F3213FB519CA284FDB96E4F069C1 +:10BB2000F3A22B5A80EF34F959599774A49FB8B8EF +:10BB3000388FC7A96B159E270FDD6DA13830A33054 +:10BB4000A05B97C830B2A3986FFC58F8416B451EB4 +:10BB500004D7F586C135AC70FFA6F77BDCEF84F91E +:10BB6000C9187D9491E6A375818CE42194DF9FB17F +:10BB7000B7740BE91BBBD587F5FCB2FF19C14D2A81 +:10BB8000D60B35EDDDA4D6D8A37C372A4FF0AB8D8C +:10BB9000D9905F7BF37D3B1328DFF7993D704B1EF7 +:10BBA000CCA7DE1C19CAF4FC4CF7FBB36B7305BFC2 +:10BBB00098C604EE9E0DF09C7FC7CCF35E0F3392C7 +:10BBC000D7DFEC49A17CA53A95917D595AC9F8EF88 +:10BBD000BB6C52C89F3B99C2CF0D5A3A85911D3C10 +:10BBE000973A9EE8378F850FE1B940B51B4CBAF301 +:10BBF0007F1EDCA26FD7B30EB237F5DBFBF033E963 +:10BC00002DA91F1B98D7887AA8B153FF3D1BA8D731 +:10BC10008FA5C21E0C9B36B6D504DF0D3370BDC593 +:10BC20001EF6654FA5B8BB9ADB51F61C9D3775DE35 +:10BC300071CAC8E59CEBE3E151ADA9B34BC3857F65 +:10BC400075B3CA7F1741FA4BC3C5EF241C30EC35DE +:10BC5000D26FF20878CAC577D24F93FA5AD2A5723A +:10BC600024FEC603443779C2DF2960054857E89FA0 +:10BC7000E441C140891F714CBFB7304A8C0774E75B +:10BC8000E7CD192C61E4A3654A33E9690B13FA5A2D +:10BC900009925EFEB750C8887C70036BBE037FBFFD +:10BCA00073B4A5CB467EA93DF868DEF0289FB4B2F8 +:10BCB00048DE0E45C72FF4FC4CCAEFE2F28BB42BE2 +:10BCC00091F7B9BF3189811F08E3FA3FE07ED001C7 +:10BCD00085C78BE00F1EC078F1778689C40F13618A +:10BCE0001AF8DE38A79ECEB7BAF5ED89DE3E7C6045 +:10BCF000D4FEFE04489C8AF04C2AD6BFE797FA8D02 +:10BD0000E9F55B3EFB9AD7C12F3FF45DCC1BD816FB +:10BD1000B162F463C073F4C5FB7DD16DC25EC459DA +:10BD200037D99697D177DDE4BCC8FFDEC8BAE76C97 +:10BD300057FAF2CDB9838B8C6E0D7F497E7E59D434 +:10BD40005928AF8BF5D9729E2F8CDA79CE3715A290 +:10BD50007523F21DBCFF96E417F13B2137EDB64683 +:10BD6000F077704A453F3722FF9445ED7AC460F77B +:10BD70009A0B904F7C6D46635F7FDE95EA257E19B6 +:10BD800066F013BF0C67BE34A4D3484B47AB8AF0B0 +:10BD9000EF19911DB4EBF8E31DE20F05F883F2599A +:10BDA0007DECA3FE790CFF483A1E167EF4ADCC4B19 +:10BDB00071C404E14747F239FF54D9EF54F1FB371E +:10BDC0000B78BE612C2E28D23E53BD5DACB2E8F993 +:10BDD0002096BF60448376DC587EEB8F6F0620DFB1 +:10BDE00048BB987675BE39DF3FDF9CBF12DFC4F2D7 +:10BDF0008BD42B3BACCE2A3BE6B76A15D2C7C3DE49 +:10BE000019D88AED6B1AF2A90E66478A6F3F3D6F0B +:10BE1000E6CFCBBBFC46AC93295C289EE707AAB0D3 +:10BE2000DDB488AF530C3FC2EB68063ECC9F972E23 +:10BE300069DE8FFBFA9A42FCFB97BF5846FB9BC218 +:10BE4000CBC4F795ED55D86E6AE3DF9FC4F5A6EB3A +:10BE5000B1FE2DDC8AF707AFCAF7F1B094FBB5B796 +:10BE6000083EDDA1ECDC4FDFB5F3EFE61EB224D2D5 +:10BE7000EF060ABFF56631CF5B36F079A67F7A1BF5 +:10BE8000FD8EE8EC9E10F94F9F1BEAE9776AFA8B6A +:10BE90003F2B95F61CBCDE8AFA040FDFB2005F1759 +:10BEA000F0F5C8CD30C47503B83F28D7F1B0AE4027 +:10BEB0005B4770DD001E17C9F75CA97C1F1A7BDA8F +:10BEC00041F962B9CE1859C71494339CA3F003E228 +:10BED000AE3BDE5AD84CEB8DB70E90EB8DDD2A9E33 +:10BEE000A35E7AF92FE3E3E559CA06F03CD0295165 +:10BEF0002721EFD786F3E977C1762093D03EFAF079 +:10BF0000EFA92DCE056762DFDA8E7CDEF60FD8F062 +:10BF1000D3B61CC0AFA159C573D4589E42FBF6FEE0 +:10BF2000A58B459293FAC27FABCA2266BEEF8EE024 +:10BF30009FD36ADECCF74F72BD344DAA9DD18348A2 +:10BF40004EEF1474FACE00E1770C63C350DF4C134C +:10BF500074BBCB027E2BE9B576538CFC4F1980FE67 +:10BF6000C653FDFACFFAE731FAA1568C3B47F8CD1C +:10BF7000F3F0F7478D78BE3BF79F4F3DC5FDE607D1 +:10BF80005907E523CF3FCDFDC506981EF24B9FDF35 +:10BF9000E7DAA66F3774C4FE2E6C88FAEFF3BBABFA +:10BFA000253CAF7BFEA9860ACCEFD5AE7F87F2C7D2 +:10BFB000B5525F84F5FA021C0CAE2FD65D4B791D8D +:10BFC0008385FF2EE630D017586F320CEB48A1FF67 +:10BFD000A162DFFE72FC84EFD77F6800E98D09540F +:10BFE000674AFD19697DF71DBF374A1F693762F53A +:10BFF00045A9CCD70C4CA57C96D41FA5C24F611384 +:10C0000062E3C727490E8789D64F06E8E320E97720 +:10C01000C0F7E4777419EC618341EB6784492ECB58 +:10C020002C602F48947C1626F6FFC7D0F971A273B6 +:10C03000FF7194FE790C1FC838A642F0C1DDCC4FC9 +:10C04000F1D12EC107EFBDCF7FBF6D9A7D21F1E108 +:10C05000FB1F70BF53C651DF3E7E8AFC43F1532F56 +:10C06000DDADE04FDAF07728260E5A83EBE49D56DB +:10C07000FE7BD50AA7B3EBEE2379DAFCE27BF8BBB3 +:10C080002B9ADF73689D9860C175C456138F2FA6D5 +:10C090004EFAB062A6467F0C49ABDC85F85AA6740E +:10C0A0007DEF4F186FBC25CE4FDD9B4174BFD0C5CF +:10C0B000EF5FD8709D2F04B7BF3489F3A894E63999 +:10C0C000581A25E198237EA765AE31FC5A37AEC7D2 +:10C0D0002AE15DF50AFDAECA01ECBFCE1031F3BC1A +:10C0E0005E17E5E965FFFDE72943A4CFCC6F70FB40 +:10C0F000D8A324FA789E37A4FBBD9E035E1E6F551D +:10C10000E406BA060C8FDABFD8BA8363F36FA57D55 +:10C11000A9FFC5FCC9B82EAAA8FCF79963C7C53A00 +:10C1200083A59A3CF5316BFCF5838F849ECF435CED +:10C13000C1F88BB2FD1FE33C4F89B8F094581F3B08 +:10C1400095C4D7CB4E0BFD9CE715EB79E27A4AAC50 +:10C15000A79D4AD5C793F23D83977F7762B125B0FB +:10C16000544357EFBA8466CC4B64148ABA92858CD8 +:10C17000C74F7B5274E72438BC9579DE0C7C4F9C0A +:10C1800033B087DB655CC7C675E6F559C14B88B728 +:10C19000462FF3E33A2DF3769BEFC0F54AB13FF714 +:10C1A000BCE09BF3567E957039BC53F2BC88EFF926 +:10C1B000DD44D7DEF6946ED297FF072EE42C97006D +:10C1C000800000001F8B080000000000000BD57DE0 +:10C1D000097C54D5F9E8B973670B9909939040101D +:10C1E00088938D246461B261D86492808A22262C5F +:10C1F00015651B50C2964DA0FDA5D5BE0C06117944 +:10C20000DA426B5BFCBBBC01C16AB52562B0B126EA +:10C2100076544AA1D53A22286A6A4754D69044A057 +:10C22000567FF2FBFBBEEF3BE764E6DE4CD89EFA9E +:10C23000DE4BFC7972EEB9F72CDFF9F6F37D07BB24 +:10C24000B322C999C058F7ECA099A98CD965FD21F2 +:10C250005E871F031BCCD862FCCB09A5D5E657F33C +:10C26000E0EF0DA6CE6026B5B36F52185354E665C5 +:10C270007150C964CE0A3B3E9DE0389A0D4514B416 +:10C28000433F7566DB066534BD5E6185FEE68BFE69 +:10C29000D870BB11FB9FC7BB62F3DBF67FA5C43030 +:10C2A000B6C0CAD60F83F6856D43CC3003B62CC614 +:10C2B0003BD291836F4C761C8571156FB4FA4D3467 +:10C2C000F48D3F93FA968C19D951393F5A8797319B +:10C2D0005CD78800AD6B63694FD27F1531D6D36EC2 +:10C2E000716C83716ADAFE7A588175D5C8F5B568C4 +:10C2F000D797ED54182BC69AD5F7A995B15B98C27C +:10C3000006423FAD364F36C2ABC61AA479428FE61D +:10C310008A5C18EDFE09B1B4FE21F03DCCE7C546BC +:10C3200037FBC41482E72A075FFF14B5BADC1CCFC1 +:10C33000D8993B99C3028F56EDBFA3C90AF5550F93 +:10C3400030071FDD6D6063A07F01AFFEE69750618F +:10C35000604EABA8E3B07306306766A83ED413A75F +:10C36000A943BF0CE7B152F43B6CD9559AEF47D4BF +:10C37000A768DEBFBA6194A63DD95BA0A9A76E18D5 +:10C38000A7793F7D5399A69EB1E546CDFBF92C7563 +:10C39000208375D6ED53990F409BE59BA169CF7E15 +:10C3A000FA76CDF7C758FDAF27C07B2D5131790CF8 +:10C3B000F0A8292A661B96CCEB0EE4007CEE14EB69 +:10C3C000C86D5EACE9E754CC75FB705FEF0C544D63 +:10C3D000638057A35B5768FA5DA956F37DDB643A27 +:10C3E0001284EFEAE117E159C07AF60E03FCA8F5D2 +:10C3F000292E3F342FDDC2DBE577CB5BB7D277CB7D +:10C400007DDAE72B9FD6D6BD652CB3DE06EB74DA5A +:10C41000E38F02BEB2ABD855DF84D155080FE025BB +:10C4200018EFCC63AACF928CF0C9F8CD04828F8923 +:10C43000F99C7DF7EB0C632E3FBEFF9CDDE585FA92 +:10C44000D2FD77D07C2C895A3C88726AF1203A530D +:10C450008B07769776DF079668F75D0FDF58F7A8AA +:10C460000BC277D00D5ABC90702D81DF6F13AE8F49 +:10C47000E8E059B8C7DD642338B159D631083F3EEA +:10C480005F0BAB50592AFC1D0F7C069EBB7817EC46 +:10C49000B4C3E63500FE3CE3548CC427443FF94660 +:10C4A000FFABB89EF58A97E17751CC9788FCA2A99B +:10C4B000C49FE4877D29B0D6E3CEB1CF6C15BF47CA +:10C4C000BAAF36FBF3B05DF6F799CD43CF3B953766 +:10C4D000AA18AC9719FD79C40FAD8CC697701C33A0 +:10C4E00080E3F14A5661C6715E14F8FCE9FBCB08A3 +:10C4F0008E55AC7EAF1BC63BF50187EF72E6A5F704 +:10C50000966CD2C2A10FFC747003B471E2B875626C +:10C51000DD2B18F31952FBC2536953FCF63C04435C +:10C520009BE4DB9E6F0A39DA213CC7B1DE1FE2DFF4 +:10C5300012BEF08212CE9F703CC7E0D078129E925D +:10C540006FC9712CAC5E4D443AD0F13196A9DD270C +:10C55000864C620CFD473F7F021E6A8D13830DC619 +:10C560007E70F28C5D23C6618B3D8908272BDB44EE +:10C57000FBB751716D50611CF5EAE42606F02C748E +:10C58000B855DCAF6216988BCF4BACCD4D46E8EA80 +:10C590006A76DE41F834E4A99A6F0685D6A1C8759B +:10C5A00079156684FA44519FE955828F26E37AFE15 +:10C5B000FA158E3B519433B184FD83657EF2217C64 +:10C5C0003C41718EC0F166FC292301F166BD52CF5A +:10C5D00074F33BFC32F4A31A7A06E17B5398C7C884 +:10C5E000E5AE8FE4CD5F9520CDFB07CC7D1F965245 +:10C5F000BED5B2E6EBE642BDB605E4560C96517EDA +:10C60000154AD6AA8327331EC1BA015682F8BD1235 +:10C61000EB72DF9343ED5457FBD6D7C21A86C65D43 +:10C620005CBE3F98EC10F2B167246FE7FC6D998017 +:10C63000D73229B77CDAF975E01F4319FB8B1960F3 +:10C6400052807464F51A063296980C7489F3CC63A0 +:10C6500079D83FD0D5F064E87F701CD0A1124E7716 +:10C66000FC7DD9DE87EE74EB67F5B0B96301DEF6C9 +:10C6700022B30758EE1DE1EBBD0478483D6221BEB0 +:10C680000BE37DE174525933A0E35D373617059211 +:10C6900050FECB7DAA33334F33EA2DCD0934AE7C27 +:10C6A000EE4E360878013E5E029CFADF8734D28770 +:10C6B000E43E5CAA3E347E109FBF84DF75C9820FC2 +:10C6C00086E07DA3069E0CE099AB81F78D91E02D6D +:10C6D000E171BA38F014EE936A3F3818E13C2FB19B +:10C6E000E2966400C188C3C1A38A01E55DE7538F68 +:10C6F000A2FC6A555D48C3B513397FAB7D492592CD +:10C70000EF6AB3F814F87E59EBEBA4977536020381 +:10C7100035F50F9FDE75EAE0DC170E7CFFE43AAAE0 +:10C720007478B6E0EDB3F6F94E5ADF8AE4840BAEC6 +:10C730005FDB2ED67FEA476C61450EAE2F67603017 +:10C7400027346E26EE37BCFFD3988A7A845BD13BC0 +:10C75000C363102E53D4B6BD57211CD6282E0B8C84 +:10C760003BC9C2BC51B0BF431BCAD927B04725C182 +:10C770007A9703E09138DCE652011E193F542B7C76 +:10C78000D0EF3FD7AC8EBB03CA938D30743A3C5781 +:10C790000C1584676CD7473F81FE32ECF35C1BA11C +:10C7A00036DF02F38171927F14ED4F05FEF067339F +:10C7B000B3229D9952EA0F4C857E7B625517EABFE2 +:10C7C000F12A9B8C7825E11C1FCDD7219F973EBE77 +:10C7D0005D09DA42CF2735F514AE82F2E66427AD63 +:10C7E0004BAE7352794F21EA3B12CEF1A9FC7D6624 +:10C7F000EC499A114617D9021E1DA8CF013C6B13B4 +:10C80000CCEB51FE7559799DB93349EF5D63E57401 +:10C81000D11195E443B9D8016B0D507F7E3BB385B0 +:10C82000F1C328F7C06B60DDEC6D95ED80E29CC331 +:10C830003D3096E0E1E0FD083DAB8BB11B104E6B47 +:10C84000A6960D898332A189C3478F273B93159AFA +:10C850005FF597407085A1E7D546BFD961C3E7660C +:10C86000CDF3230037AF25545F7C3CED3A46FCC541 +:10C87000B51EDFBF634334F386E9552D621EFDC14B +:10C88000A536D6C88C008F5A85555CE8BD97FF5BEE +:10C8900025F8EAE7FFAEE02F09E591D7F76632B752 +:10C8A00067CAEF9FF61BD43B6B03266681476B5E1E +:10C8B0002A1DC222F4D70BE72FC733DFA0B0BA314D +:10C8C00048F0A8FDF25A7A5E7E7FA719F11EFB712F +:10C8D000C2F33551EE21AE0BC0395BC0B9F6CB586F +:10C8E000E61D14FE9CE355A8FF786AFF1D0210F0B8 +:10C8F000D6DBAAFA76C0A7BFDB67B8615B84F97E96 +:10C900002DD63F2AC148F492ED67EEAD11C697EFE0 +:10C910000D8E033E6DE370AECCED3BBF96B2E002F0 +:10C920009CFF3593993BD278A7C57B72DE2D71C1F0 +:10C930002A81F7232BED617587761FA3C5F82D3764 +:10C940000693B0FFAEA96C4E7384FEE57E8F31D6A0 +:10C950002B088FD2444F06F291EA5BA10278326431 +:10C960009EDFE0C909D15D7FFB1E8237D85D851748 +:10C9700082B799DA657F270E08BA646E9B02F4B419 +:10C9800048C8AB45DB574E03DED96BBF9CD802F6D7 +:10C990000B0C7182D5BF6EC7FA2685EC93C51EC6F7 +:10C9A0001A80EF54ED285C8F626B512263D7C6F179 +:10C9B000E7F760B9CE1492B3F47F370B978B72FC14 +:10C9C0003B1FD4EAADCBD8839FA3DE73E200E70F11 +:10C9D000A09E92FD5DF5B0B6BF65DB6F3A86F35C55 +:10C9E000A6D37F3250C103FD233545D81363D81831 +:10C9F0009403AB769C35C738FBA7839340EF69E976 +:10CA0000C82F1D548E49718F4A81FDE87E9BCF73DC +:10CA10004A8A272F05FD0D6FF3799DA93EC3E5C412 +:10CA200063F1249F2CC8CCE14FCB5CABAF09E6711E +:10CA30003FB09328808FC5C2F520A9FFA9EA6A35C7 +:10CA400006DAC77EB6260EF737FED9EB6FC0FE12A8 +:10CA50009E8D76E37A3696BAF3D15FB0B1D2E66AAC +:10CA6000822EADF03DCA0FDFEFC6BE76156A07CD48 +:10CA70009BCB8621DAB5BDEA477FCA06C3E77B8731 +:10CA8000C1FB1BAE65AE26161AA7AEADF2799C4F60 +:10CA9000D22C2E673626BBF31D61FD32A1CFD50AFD +:10CAA000D875B767FC7C3CECEFA3FB489D86F5A5E9 +:10CAB0000C44BE318AF17D66E7014E80273876B896 +:10CAC000DEDA09F28A6584EAA39A15BF09D653D340 +:10CAD000F2BC01E561F5BDFEC173512E3D63746D7D +:10CAE0000B9B5FFC9F8796396342F268AEE2207D24 +:10CAF00041EAE5B731F99343783347E0CD6D421F02 +:10CB00009F1BCDE1BB98B992F0BBDBAD2CC60024D6 +:10CB100035B7BCB998E4D54A532CEA3FB89648FBE0 +:10CB20002DCBFEFC4AB54FD9BD0AEC7B97D2331210 +:10CB30003B3989BE1EEE5FF26D4BEEDBCFDD298205 +:10CB40000E470AFD308DB9EDB0EEDA5732B66E847D +:10CB500026CB00D8C702E24BD69202D28FAD68F73F +:10CB60002C7F39CAAFC484E0C21CEE7C03FA09668C +:10CB70000C2FD8883AE961E02F40605DA66012D1A1 +:10CB800031F01D0564DFC329932B8D80E7B55781F4 +:10CB9000FE05F5D7B655F27A4AB0CA00F593292BAF +:10CBA0002B8D8097B5A38247B17E2EE547BC5E10E2 +:10CBB000AC52A13E30751D7F1F0D4140ACE1A9FF75 +:10CBC000B3D20BFD9F8C15F2DD155C80F853FBA7EB +:10CBD0000CC3C6B0F55A5339DF3A19C5DF3B99CCBF +:10CBE00016CE4078670647E23C7BF12245EAC39BBC +:10CBF000A894EB94DFB1C4C8FD3F99C2FB5F5E2EE1 +:10CC0000F49268B601E106DBE48D01F8EF69CBD858 +:10CC100086EF6F488913F0827E8A42FD4838CAFE4B +:10CC2000E4B82B50EE223F36013F0EE3A3CD295C42 +:10CC30006EC238EB689C1C0EFFDA19C3F371DF601B +:10CC4000BF8C62BF8CDC4EDDCAE707FDC6E611FF74 +:10CC50002F34C2FB7BCEC3FBC9A179EBF1A35DE00E +:10CC6000C7F2266084A4A7A5121E4D8AE6FA212BDE +:10CC7000D2AE63602A879F353596AFB3773F86285B +:10CC8000344E9380E370807BEEE5AFFB2D319F6FD8 +:10CC90007BDD61FBE556B1BD356B5BF87A18DBAC2B +:10CCA000E9E7E45ADD77254080388FB854FAEEFE84 +:10CCB0002866A5E76C5BEF77C9795C2F457DB546A3 +:10CCC000E8D5CC7B2D3915AA05D7A8D910303BB1B2 +:10CCD000BD5971FB103FD3607D08DF19D38AC4FAB8 +:10CCE0001C627D0EBE3E9F064FD9C19EA459F6BE62 +:10CCF000F8DB0BF7DEFE720A447F1ABA8ED41FD21D +:10CD0000477FFBA1A47ECBFB21E7A983672F9C75FE +:10CD1000F393F0447AA6EF72B4F828E779AE3FBAFD +:10CD20004EBEC2F14AF977353F867D44FDC4A9C5A0 +:10CD3000E79A9664C3E29CD077ADB897C521FF5CB3 +:10CD40005AAAB07387B3E1C8BFBD65DC8FEADD6561 +:10CD5000713539C9AF97995A1CD1AF47CFF5F65EF7 +:10CD600077AC9929A41769FD0CDD09AE801BF5D4B9 +:10CD7000D3CCB503FA1DAFD33BBA613F77D942DFBD +:10CD800085E489B6FE43C13FFBFA8D7A92707E45F9 +:10CD900096B2179C2EC6CA52B712BF2E1A58B63A70 +:10CDA00019EAD7A73E49FCBA6858D95974CD4C4DF9 +:10CDB000DDCEEBD9656753B0FEE476FEFE24F70BBB +:10CDC000C8DF99777BE5E4A121FDE1C654278DAB4F +:10CDD000961B18E29145BDCB857252C2B3BFB2C853 +:10CDE00062A88FA4BFCEECA5677E9E5122E4738912 +:10CDF000B4E783468D3DDF1D63F5AA00D76E94A787 +:10CE0000B0DE05A99E3908FFBAE8CE05A80ADF1BE7 +:10CE1000FD9119F521C50DFA06FA459C0E360FE66F +:10CE2000A9746EAC203D7085CB6A24780A3F15AC9E +:10CE3000ED1BE8E7E5579EB97B181FA602E73156C0 +:10CE4000D07FDD2B5F7DF121CAD1933617AA816394 +:10CE5000DB1E598DFAD5D8B6BF7FC5E5AD8DCEA9FD +:10CE6000E4BCC7A2BF119E97B45A68FE63DBB296BA +:10CE7000E0FBE3DF694B45FC98D8E16F4276D0DDFB +:10CE8000FEC7619EF0732B764CF926FBF2F58B5EA4 +:10CE9000787C6666A85F023C7EC2E171BE0AFD8AAC +:10CEA0005D0907D607494F1BCEFD98E27BD0CB33F7 +:10CEB00091CECFB0012E3C57E8B6F37EF4FECDC341 +:10CEC00095B03E783EB1076610A6374FFAD20A0CED +:10CED00024542F65B19A7AB975A8E6FD298E644D60 +:10CEE000FBF589599AF6A9CE7C4DFDA6CCB19AF7EF +:10CEF0006F76956AEAB7944CD5BC5FE9AED4D4F3AB +:10CF0000FDCD9AF70BF7B56ADB0F3A691F0A3B2A8A +:10CF1000CA519F77053C4D585ED3B9A97CA093F5C3 +:10CF2000F1EB16057D4DF87CFCF9FA623FEBEBDF87 +:10CF3000652B3C741E60C17D51C3CE074A03448FEC +:10CF40005D069733DC8F3B6FB067672AF97101ECA0 +:10CF500000EC6BAD3D8370BFA62C7C488DC17DE994 +:10CF600061E4FF6A31077F361EE5FC7C95F4DE162E +:10CF70002323FDB1654EAE0F7D7F8795E08B1F2289 +:10CF80009F9A1F4DFC642268B8B46E3C0355709F95 +:10CF90003C9A7597B2E5BA7DBA4B539FE2F8B1E679 +:10CFA000FDEB13D76ADAA73A1FD0EDD3664DFD66C5 +:10CFB000D723BA7DDAAADBA76734ED133F0D3621FC +:10CFC000194DEAF4AA7698FFB8C39BCA715FC67779 +:10CFD00078E723BD14F93D4DC442F6D4BF8EA51F9A +:10CFE000EC2AF46BBDD69848E59E4627F9A5F6369F +:10CFF0006652B9AFD145CFFFD65842E51B8D6E2A98 +:10D00000FFD178039581C60A2A9B1B9BE9FD5D8DA4 +:10D01000AD54020447A0BC881F24E40FD4D1DEEF36 +:10D0200032046BF1C4F5B327CF115FEC1A10ECC2D8 +:10D03000FABDEC2CF1C5401A233AB4A633E2635D85 +:10D0400069EE6569509E4BE5F56E936D03CA816686 +:10D05000833B1FF5EBAF9E3CBFD93882B1FBD65660 +:10D06000243A6279DD0A75DA6C34CCBCE737BB87C9 +:10D0700033F67B1419E3A85E89F5EE28DE7EEEC94F +:10D08000F3955E9A1F3F6F9E153A6FFE2A35C2795F +:10D09000F3EF8F3BEDE86F39703EC38EEB3A20FC27 +:10D0A0004B6E966F5A0465A931DF8472F1B04E8FD2 +:10D0B00090E5BF6CA5065C4FB3C1351BF514EF8D31 +:10D0C00026B603F8C50C85DBA3BD7A601A9747DD49 +:10D0D000375BC8DE3968702F413C073EFD04C2EB68 +:10D0E000AA34FB0C845FB7BD2709E1909866E3F58D +:10D0F000849E27145758DDC4D7199B163DA39F75EE +:10D100000E4E8BB0CE61690E1A9FF9DD2350FECA18 +:10D11000FAC14A770DCA8983A5EE749CCF810A0BA8 +:10D12000D18FB7C2EE4B4726677417CF0EF3BBFC07 +:10D130002ACD44FB36CBCCE98CDDAEFA7644B0D3B5 +:10D140005E48E3FA3EED1BDA73B745931E7ED0C00E +:10D1500096ED8A00C7BFA77139776A4064FFCB1B81 +:10D16000027E6533EDD45FF79A283AEFEDAEC82022 +:10D170003DA8BB1EA004F4D17DBCFEF46E6AB7C806 +:10D18000A3303AD79C2BF8D4EFDB56FFFB10BCFF43 +:10D19000D19A6817F170C728924FB78B97E70FB2F3 +:10D1A00092DE327FC68832944B73C5F9D802BB71C8 +:10D1B000301D931963CD0EE8E74E5BFE7A14FF55E0 +:10D1C000F195E658A82F1B7ED77A2C57A46D36C749 +:10D1D00041599DF3FC7A541F6B80B48AC95E0ABE24 +:10D1E000D908F35AD8A03AB9FD24E49A7BE565C57D +:10D1F00063483C4438229E027CC92E7C53C05B7E2F +:10D20000F7A680E7DC34A1B7E5B2DC6FB4E73E0BEC +:10D21000114F3AE7BF39B21F3FBDB65DE86DEF9AD7 +:10D22000F9B82B9F36F9C2FD4972DC7F88791C342E +:10D2300033B7827ADCED76C28FBC3967EF2D86F585 +:10D24000E7B5390C746E2FF9788091FFBEF8530F53 +:10D25000F1B96B3A834F1D6284E7AD4827179353AA +:10D2600033BD6B493E8C3D07F207F9E279CF478722 +:10D27000880F2E137CB09EF8D79EC606AAEF6DF4D9 +:10D2800052B9AF7183E0839BA8FD8DC62D820FFA42 +:10D29000041F7C9A9EB735CEA1F295468FE083FCA1 +:10D2A0005C7586C0A779899E7548FFF2FC7296D599 +:10D2B000634278FDE5110B53F17CA2CD42780A144C +:10D2C000F0C4A3F1182F63716C74F68D9BD1F3DB5E +:10D2D000DEFDD79DF3AE49746FC27DE98D9341FDAC +:10D2E000ECEAFEF1E70073DA919F3CBDBD82F8C71E +:10D2F00001A7D38E7AEB3369953350AF3DE076DAF0 +:10D300004D50FFDDF64ADEEE71DA2D507F366D06A8 +:10D31000AF7B9DF628A83FB75DD47D8C0EB59FDF0F +:10D320007EEB0CF4639432650FD243B9357932B099 +:10D330006B908FA57B900EAE4F5C3419E9C099E6D7 +:10D34000247C98EA5CBB07EB37656E350E72A2371A +:10D35000347F1D7E57165F69C4EF260FBF6B1D7E9D +:10D36000775DDA6663F87737E43CBF0EEBD35C5B3E +:10D370008DA80F3AD3F879A9EC47D665BBE4AF681E +:10D3800027209E8E6EAB203E9ED75A417C5CC2A564 +:10D390006C56E57DE8A7AB6B551C0ACE6396D27B35 +:10D3A00058AF800E517B1EA805F8AC7FFBE2B8B5E4 +:10D3B000188782F57154FFC5DAC87CF72F88077A81 +:10D3C000BEFB9EA053949B95D0CF7B403FBBA09EBD +:10D3D0002ED657D7B6C8BE88EC198F1DE56B761AC6 +:10D3E000978BA385DC5C28EA778AFABF6CEEB7706E +:10D3F0009C77FBA7EB0FB01DE8B68ACFA30F5D6B40 +:10D40000DB055D770838B2A29E24ACD7B04DE42787 +:10D41000BC587CD7F270FB2D19E3249A29FE421FD9 +:10D420002751CD02BCBF665D9C050B9AE93CB63521 +:10D43000EC39F123617F0CE07C6F0E326BC0BF7F53 +:10D44000A78973C7BEEBFE4AF0ABFED6AD6D17EBF6 +:10D450005ECE7C14D7A65F07F324106DADB41DA477 +:10D46000FDECBB9E60E4F5F45907B7DF651C8BF457 +:10D47000CB831E14955E8C7CD0CED07F13CE270E2E +:10D480005D804FE8F9D1B7C5E72EC06F92709E7AE4 +:10D490007E23E3B3F4A5D4E7A0EEC5F83CEF2B510F +:10D4A000E4A7FFC4E9C9C27EBACB7ABE30A07D161C +:10D4B0001F243C6B002B0F9F2B667E4E0F5F8CC48E +:10D4C0007D3B6EF0FE01F5A2921D8F119FEA42E1B5 +:10D4D00000F4E8823AF29D2D575514E0772C93E33F +:10D4E0004FB7C2E5A2A47BD007A91C9BCEE551DFB4 +:10D4F0009269E21ABBB77E95447EAC8BE07B7F706D +:10D5000098A24E087A91DF974493CAD3A930BF02FC +:10D51000FA5F67E960D2233A47988D587EDB7662DE +:10D52000E78891D4BFDE5EEC1C5A62E5E35E7703C8 +:10D5300096AD66CF964568278DB5909DF496880781 +:10D540009C1ECDE3A7DEC27362786FFA91F3F128D7 +:10D55000BFF4F666E7FE7965CEBCBE7627AC7332C3 +:10D56000AEB3FA63C37DF8EC72EDD0EA862F987102 +:10D5700010C8ED86F3CC587829762953915D141C98 +:10D5800076BD8E65F1A781B83C27DA9F527F10F6F1 +:10D59000E945E2904A7AB8BE30E93CCB3416A19F07 +:10D5A00069009DDF28257FE776AB28E5B9C8043EF2 +:10D5B00005B6C060F39953347148894628E7A9C17C +:10D5C0003158EF62013A27D1DBB37F157E28B06B6B +:10D5D00037A6935F8AC727C18E0C42FC9DF293F752 +:10D5E00017DC4D7C208AF4A15EBB76B781E20C5A31 +:10D5F0008CEE8113D1AE6D4877AD85FABF0209BFBD +:10D600007A19CA3AC717043749BFD50D67099EBDB5 +:10D61000E703C2EFBBC904F207CAEAFF56490E5539 +:10D6200033B681F68DBD665E15261759F3E7BDF05A +:10D630001F0D7CAF12014876D684996EF8AE52D891 +:10D640001FCCDBCEEBC2EE626CC44C37F453992096 +:10D65000DE679B79FB08D9FE0B5E4F97FD7D3E830D +:10D66000EA43655DF49725EBFB793D598E7792F798 +:10D670009F2BEB165EB7F3F75F48FFC34CE40B92AA +:10D68000DFBF942EE4443ECB177139EDE9C5178C0A +:10D690004BD1B60BF9B0F019D56B1E8DFB3335FAB3 +:10D6A0004DA4EF668562E7AAEF3191BFFB545C732E +:10D6B000DEEA307B45C6B15494DBDDA8FFD5BC98CB +:10D6C000B14D15F13CA87F7CE1E47AF914D546E729 +:10D6D00013671EE47CBF3FFDADAAE165CD7EF66910 +:10D6E00057156E8FE3C11D8C77FAA1215BC9BE4827 +:10D6F0000BD0F9F98782DF0D06DE5A12178A178BD5 +:10D700004F656EB457E3FF08FC19F7F8D300F1E357 +:10D71000AA3F72FF6FCD23AF93DC5BAC3AC99F5B2E +:10D7200096E3F918E1D3650F905FB1AAE1159AD796 +:10D73000992C61573A7A72C2E179A22FFC4F5F04AB +:10D74000FEA7BF4FF8EBFDCE2B6C7B68BD2B2E33B5 +:10D75000AEADCBCECF455D629F8E189C6304BC2CD2 +:10D7600023012EA7970446C6AA18741C18CCE3966A +:10D77000DE2846BBE84CBD9DE1BECF5BFDCF3C4FF4 +:10D7800004BFAFDE1EB80DC72C0EC12B61641FF89D +:10D790000EC5F12E005F6DFB770CDF21C6A0D98589 +:10D7A000E7A88719F5332670C41C1E1F337624C7DB +:10D7B000CB81ADFCDC481FF73576A49DEF93389FF5 +:10D7C000A999F1C6043C9F91F430299A35A3BF1D55 +:10D7D000F0DA25F0DA85782DF137744E03DF45A0B5 +:10D7E000AF10FE6AE1EAEE0BD7C9232F8CB7DAF649 +:10D7F000EF18AE2DA00FD3B9E6EE28F2A7E8E1BCF2 +:10D8000074243FDF92F06EB8089C1BBE2338378C1F +:10D81000746AFC1112DEFDC927FDFEC87947A0D34A +:10D82000E22BA1D3AF33847D630C529CA97EDF1B16 +:10D83000FBEE7BD345E8A9E9FBA4273DDCF465B505 +:10D8400038EFD43FDF3A92FBCDBE2B38FEFFE64FD8 +:10D850009F5FFFAAA67D61C37E4DFB22EFDB9AFA94 +:10D860008460A01CD15CFAC7AF3DDEF33AD6AFD4DA +:10D87000CFDE9F7F7DFA0B4B0D78FE5612E0FEFD4A +:10D88000C5999E2F90AFBC65F035D901AED77434E1 +:10D89000AB741EE6CBA773C0D5628E6727FCE7A3E7 +:10D8A000BB016FCE320BF93FFDAF66199DB97DF11B +:10D8B000A0F44B95B9C3F4C4526BAC11F5A75260F8 +:10D8C0007991F0E66B8137140F04F43EC7CA4CF12E +:10D8D00040E773E62814FF3487F1786A28FD1E6854 +:10D8E0009F6E647E0BD42B6D46BF85CEFD78BEC384 +:10D8F0006C3E4D663182C686F65DFC20B28367E1E0 +:10D900004398AFEA56299E6D76093F2FBCDDD66C51 +:10D9100042797ADBBE7B4FDF0DED6C9DB798C76B0C +:10D92000CBFCB50F0C97730EF8F5484EE7DD8A383F +:10D9300057564C2E8C73D57FF7D6484E67D3D5B546 +:10D940002AC6BFF4BCCD48EF967407EBDB6729E02D +:10D95000F919E3709DCCE4CF8841FD797339BE5F3E +:10D960007DD04970A92B599B87FB583759F9D8921C +:10D9700017B26FEA1ACE919E3E457DAE09DF3F7326 +:10D9800098BBC6AFE9F4AA68AF84FC97C105489775 +:10D9900017B383E4BC3B1AFD844F1F35EEA3F2ADF1 +:10D9A0006BFF5E8C7A46B03110D17F79A5FE02E91B +:10D9B00027907E03C907FE754FF910C4CB74C917B1 +:10D9C000ACCA30E40BCCC84BC92FB333FAF0D7D173 +:10D9D000191796ABDAF6EF98BF5E2A9E572772B9F1 +:10D9E000A8C76F3D5E4B7C86CF8A1518F776D0F7B7 +:10D9F00050AECE65DEDC6AE0B373966E328D57AE04 +:10DA00001CAF57D83E4D6211F2542E9F9F3B79BCFC +:10DA100064B94AF6818C5790FBB03843F81943FB40 +:10DA200056957161B9A86DFFDEF5F84F175C995CEA +:10DA3000639AFC86B57DF1F5BE8BE0EB7DDF27BEFA +:10DA400086E5CF2C500DA17C118C27463DAEDBC75F +:10DA5000F32197256F8AA1E0CC929E18D41B97B72B +:10DA6000AB8487CCE8360E057C5D2AF0B593F9DFF0 +:10DA7000457C5C3A6129E5D12D7B2C725C71AD78D7 +:10DA80007F85ADC58CEB5CB15DFB5EAD882BAE7E5A +:10DA90004EEB17AD9D70FD31ECB75617CFF36C868A +:10DAA000881F2E60053CEE42AB9FEACBAE46A6F146 +:10DAB00057769D6F247FC00BBF3DF94BEF8430FB41 +:10DAC000BF2FDEB65F046FDBFF6FE2AD6ADF4E791A +:10DAD00055978BB73F1AE53E80F396FC781EF226E9 +:10DAE0001877DECB169F17CF478B9DDCBFA9F89A1E +:10DAF000F0BCADFB2B46FEA3C5C2CFD95F5EBA8C8E +:10DB000037187BD0D7C4E30DDC2AE6898ED957516C +:10DB10008EC715856FD4933ED2EFB995CCAF12F175 +:10DB20004397CAD7A45F6FCCF17AD2B35C0107E9FF +:10DB300043E3BE6C7E1DE5E3B7E5EF96F270FC2093 +:10DB4000EEBF280A56909ED765F217BF877AC24B60 +:10DB50005111F5047326D78B667A179978BE619FA9 +:10DB6000F34073269E070AFE6FB0BA4D08A7296AD4 +:10DB7000E7AF6E45FC09A8E4DF5BF3D377FEF0A8BE +:10DB8000F3E2767F9DE32CE90DFDE9FF75069E7FAC +:10DB90005150EEA4383FB4A7D0BF27FD7DFAF78BD4 +:10DBA0004695256692FF6942C08DF3D9C2E7D3DF5F +:10DBB000FED4357CAEF12FF6377E5D7BB1637118F4 +:10DBC0001DDC96A948BBC371D41ADADF4BC5838923 +:10DBD0003D7334FACFFFEB76C57415544B909FB963 +:10DBE0008A8FEBAF8CEBB1F35880CA05AC874A0F34 +:10DBF000E3F1F78B998BCA3B451EF3DE2CCFCD9911 +:10DC0000781E61EA194CF1932F7E9D837873FADABE +:10DC1000F19B30D6EEBBD2E3BAF39D347EF7EEAF84 +:10DC200093300EE6627C614DA2DB9319E1FCF91F93 +:10DC3000A52A9DB7B0C38F929CA814B730B0C9FC79 +:10DC40001CED0B6732E143882F0ED92AF9229ECFB3 +:10DC5000E67E6CE0F124CB155F3ABCDA1A34106929 +:10DC6000E52E49F6A9586FE1EDB935B13E05EAB99F +:10DC700063A378FB5DB13EF4A3CF6741A2C78540A3 +:10DC8000A2582E629CEFDDC1DC3CDF81F5A4A01E12 +:10DC9000B6A4CDCAE3FD59300DF97B5E3FF64F5B6C +:10DCA00026E7D3A353383F1F5DA6F553DC2BF8C0FE +:10DCB000275965FF447A3A96E96EC272745C60E354 +:10DCC0002F8BC86FCFD07E3836F6C774DE28BF1BC7 +:10DCD00030AA6C03C26FA7C2E3D3BDED168A8F8052 +:10DCE0002F065784C5F5EFCD2AFF19F6F72BE1F77C +:10DCF000EB0FAEF09D266F36444F5E9ADF68B4B9E5 +:10DD0000C8FF0E0F4A685CAA3FF5F4B459EB72C81D +:10DD1000C7EF45BD77C028CFFFC2798D363366C3C4 +:10DD2000F93F6EF16D23FDB43E09FD954B9FB01890 +:10DD3000506F781FC42DE6A17CD868A5F29F6007BC +:10DD400063F92FB083B1FC18EC602C3F013B18CB7A +:10DD5000255FE683B060AC2CCBDD9A591C3A9FD38B +:10DD6000CFF77901CFDEF1DBCD34FE27591E826F6C +:10DD7000EF7EBFC47C78A8B333B6E7AAB80BE05BEC +:10DD8000FF7C86C3459E17EADB7F2BF63DAFC54877 +:10DD9000F23DAF35185315F6DEDE4C33B5E7EEFE37 +:10DDA00094F250BB1CBDF0752BB0E4E9065EDFFBBE +:10DDB000F46282EF2759EE7F225C81BEFF86655EAA +:10DDC000EB3BBFC0FC1FE89FE20EBA959E5F931D20 +:10DDD000A05B871E0E725D3B63031BF1FB9DBB5373 +:10DDE0007025C06F18A71BC42325D27AD7D27C6FA9 +:10DDF000B1F414615ECB2DDFA811E38C3FC92A2555 +:10DE000038FF18F12D210C4E62BFAE94AE7BCFBF10 +:10DE1000059E32797F07F24E27CAA1F331A8EF554C +:10DE20008AF3FDD696B4B7707DDE7D2A4B7712FE5D +:10DE30006AE8CE91C5F14496B9EDE60ADCA79DEDFE +:10DE400047D3EEB4D1BEA42DC171B3D235FEC7DC29 +:10DE5000B15FFDD72FE3E97D070E751BDB3A05E3C4 +:10DE60004FE65A5FFD0B2E69BEE3E329187FB230FF +:10DE700051D98BE52267F275187722E3E3EFC82CBE +:10DE8000DD8BA434CD55497A5A2932973079506EBA +:10DE90008DC643C1DEFA14C7204DFDFAC4619AF75E +:10DEA000A73A5335ED3765666BDAE5B8D35C859AEA +:10DEB000F746C7F5A4A07D06EB207A603B548AD3D1 +:10DEC000CBDD7DF0C66CA84F7F6AB60BD5929DA2C4 +:10DED0007DFAAE721FEE4737C0D30C0AD4F1920719 +:10DEE0007EFD4BEC4CA7FF57B73FB9D7EDBC0CFDFF +:10DEF000BF1FBD5FF2D9956DD662E4B3976A07E89C +:10DF0000F7272F4B6B17F48737BD74A13839DEEC38 +:10DF100057D98E08788311A91C0F7939FD00CF1FBE +:10DF2000BB5C7EF619F2B34121FAE82D757EB9D1BA +:10DF300066D75BABD14FFFA6CA281F4FE4F555E16A +:10DF4000DF6A08DFD99D5BEF1B1A4FCFBDA8E762E0 +:10DF50007EA91BFAAFCA12FEEFEA57EF1B5A146AEA +:10DF6000676B3ED6BCCFEE51D66BEAEB92B5F507A8 +:10DF70004BD7877FDF1F5FACDAB2C8ECA1FC4FC57F +:10DF8000ED8BC01FE47CA6BC1645717D3763BC0ACF +:10DF90003CAA2D7ADB88E7B437F7234725FFB94D34 +:10DFA00065F591DAEF12FD4E7B2D8AE2602EB7DF28 +:10DFB000F701961467F8472E47DF1F183086EFFBEE +:10DFC0003D595C0F3D5DBCF9A75FE0F9E84B8CE281 +:10DFD0003E4FC772FE9FD772CC608072F4008E2FC6 +:10DFE000798EA001E54AF7B2682FC6F5D72DB75351 +:10DFF0003CE8E8949E77ADB0F5EB9ED9FBB015F602 +:10E00000ED034C820C93ABDD681441FDA1ACBDB3B4 +:10E01000D6C1DF37BD16E5375CC17A1EC2730994DD +:10E0200083659CCE1720DE08F9823EF6BAFB58AF16 +:10E03000BC41BE80EBC7FA9E67F61F7C18F5F0FD69 +:10E040009CCE31C24E6FDFCF0DB3EFD9639C2EADA6 +:10E05000F0CBE39474F4BD6793D976413A6FA6B8D8 +:10E060009B4BA5EFA7919EB32F48CF076E82FDA9CA +:10E070007B89DF6B71A62D9DF262FB93E7755B5484 +:10E08000A24359EF6A536F40BCD5E7A14BB832B7F2 +:10E090008BE853DE1BB56AE27F66A0DC5CD56EE4DC +:10E0A0004122FD8DB34165CEB07176BE625946798D +:10E0B0006E62FEDD525EB7FF3BAE3487976B23C8BE +:10E0C0003D90D3A67894D3950AD99587DA87942181 +:10E0D0009C0E29CCEFA4BC2D1EA73C937787CF6D57 +:10E0E000745F496226C5274BFB52DA95B3DB67A7FD +:10E0F000A35EF96ECBE243B073ECC3AC541AEF5697 +:10E10000E6253DF8506CC508F44B4C17F1018762C9 +:10E110007B3A912F1F9A18ADE0793FF4BF0EFB9721 +:10E12000EB3A64AA18C1EF9F9071C9A3AEE89EB8FC +:10E1300029EA3DA537E1F9F63CE640BBF21695EB3E +:10E14000B9ECCF9C3E25DFAB53027138CFBD5933BC +:10E150004E67C177431A7E26FCAA026E461E877858 +:10E16000A97A6EAF3DFBB4C2EF457171FDBF76C2B7 +:10E17000A95FDD8A797260772B309FC5ADAFD2BDC4 +:10E180003F7A3BBBD7DEF93FF4A7F6B5972A2CA31D +:10E19000C2FCE47ABBA9574F97FADE0E1E27FFFA9E +:10E1A000C4DF74AD84FA9A1DD104C7134F58BCC89C +:10E1B000C74F6CB390FD7322AEA76335D677E5BA2F +:10E1C000BC349A4B732FDA5283F33D943FEC6F26A5 +:10E1D000BAD7E3D8E3163FC67B2C7F326B1BDA53EA +:10E1E000C746389F7D0EFD81CF26D03D03CCC3BFEF +:10E1F000BF59D023D29713540FF5B776D22396BFC9 +:10E200003094F898DCBFE38F47511EFD897D3307BA +:10E21000A2BFACD3F03CE5F130D5E6457EBC725BE5 +:10E2200014E9810D0E4FD628585FF96F6FBEB510F7 +:10E23000C77F2781E17ABADB5E207F65687F23CBC9 +:10E24000F7336DA99C0FF4CA5B1E77BB10E36E53C6 +:10E2500029EE7634C2B786C97B1779DC6D81AAB8FE +:10E2600029EFE0A1C879E4EE515C7FAC96FE9341C2 +:10E27000CC9A8874E861B4DEEE8732B6A1BD33670C +:10E28000545CEFFD4C3C5F52E25B47EDCBE43FB1A9 +:10E29000F078BFA8C8E7D8D346F1BCE22AEB398DA5 +:10E2A000FFA6B6E12B8D5FA5368791DC2D6872162F +:10E2B000DE05E56A01E7E52915B7E0FA56346F7E19 +:10E2C000F10D82CB633FFA00C7DD6723BF0D7B836F +:10E2D000C34F6FCF54593F17F4B45573CFCCD147C8 +:10E2E000DEA37893A3BBB3F370DF16AB81A3781FD3 +:10E2F00057973DF0D1DD50EEDA7780F6453FDF3EAF +:10E30000E7F60AE72BD5B88E4118EF52B16414D165 +:10E310002DA7F7231B73097ED29FDB7D22B2BD257B +:10E32000E729FB97F393FDCBF7568BFD3A6D0EE48F +:10E33000A17C4ECC746AD6753A2690176BC3E7DC85 +:10E340009F773A0EEA6178F35D9DEFDC2EFC3C8707 +:10E350000D6B7F6806FCEB6CFEA5C913CE472FF34F +:10E360005C47CE57C695CA3CDA874789F388116C5B +:10E37000443FF9B75B90CEAAFBE6DFD2F3FEF26F23 +:10E380007BF36DFFCDF36D657E6D51B9A13E3CCF42 +:10E3900056F2C3A26C789E83E7FE5AF95E345AFBAC +:10E3A0007E7FFCB1209BDBD7458322E7BBEE1FC5F8 +:10E3B000DB9B989FDF3F28E4E278017779EF97D4E1 +:10E3C000536A05DF96799EE3DB78DCE67891B70344 +:10E3D0005C80F25CFBDCEF96984D7255DECFA74077 +:10E3E0005FF3E222E50B07681ED7B21E2ADDCC617F +:10E3F000C412C04FE5645641E575AC9ECA1BD826D1 +:10E400002A6F64CD544E63012AD928BF88F7BC8790 +:10E41000E7994E5D6A40F95A746B64BDF8D445E1E2 +:10E42000E0A5FB032F170ED7317ECF5F1F780CCFEF +:10E4300024FCD6C3439FAF399105E9E2924988B8DD +:10E44000A968073B29BEB59CB9A93EE512E1501267 +:10E45000F418797EAF0E1EE591F1E29CA0FF9FA219 +:10E46000EC2C0EED5356B693DFDF20F60B0CB144C7 +:10E47000E4FFFA7D94CF8BA2CBCE3A8145389E6DD6 +:10E480009C4D79DC8565AB53A19E92BD6936E579DB +:10E490008F2F7B01F3BCD39EDDCCEBA3CB0A4D2E9B +:10E4A000D022D7FE6236E6337A44DCB447C44B331D +:10E4B0004FBEE69E2CCFDA1FD2BD639E113617AE3B +:10E4C00053E685ABA9FC7C35E906FF6B2678AFDD0A +:10E4D000E189CE46B965F5C738514F583B85EE8F77 +:10E4E000BADFCCDF97F7D9C8F5C97B6E76EDCA5E87 +:10E4F000ADA45C7C1ED0FF50ECDFB3369DF2E33C54 +:10E50000BB15910F5736640EF08DCE8089617E81E8 +:10E510001CCF94E249C2F71926C5035D0C1372B8EB +:10E5200073577636EE5356B638DF8F4F2E4438DEAB +:10E530009A529185EFCBBCE82CDC9784FECBCA6C59 +:10E540007706BEAF7F2EF3B2C7657B72B1BD2EFAE0 +:10E550003CE59B75E5BFB33E98DC374FBDC9CD7C2C +:10E5600066E22BDAFCF4EE2566BACFA9A8C2D38402 +:10E5700021CAD7CCEB1983FA31F45B929D80F7095D +:10E580000693F2E1BB8767F2FC777DBE77FB2BFB3E +:10E5900035F9ED92CE7AF3DBCFF0FCF6107D3DB28B +:10E5A0009A85E5B74BBA9174370EF3DB63B09EB52D +:10E5B00004DF9BF84E07E5B74FEA088AFCF6F7B48C +:10E5C000F9EDEEFF5C517EFB3171EFDB312BBF2F9C +:10E5D00049DE27B56A373FFF5DA5F0FBA456FD9ED7 +:10E5E000DF2725EDC265627D35FB77ACC773BE655D +:10E5F0008FDD41F75131710FAA137EC3ED42792FA0 +:10E60000A93E0FA60EED41D29BFDA477E9F361EA86 +:10E610001E2B277BB04EA747AFC816F6A090674CBD +:10E62000E87F4BC5B7B80E1BD96766D23B573DBED6 +:10E63000DAE5C0BAA02BF6D87374EE26DF678F0D2B +:10E64000225C9074B67C8342FAAB84DFE8A72C6E20 +:10E65000BAC7F8A921A4B782BE2DF2987DDCCF0FEE +:10E66000B882F1F03B637B52504FDED99EE9020E37 +:10E67000CBFED4EFFDD3CFE9EE9F7E5273FFF419AA +:10E68000FC1FEA69C70D3EEC670CCBFCF904A81728 +:10E690001F37BA7CCED07DCC17BB7758C2DF22F6AD +:10E6A000EB72EF21D6DFF72CF31FF4F711DF2FEE1B +:10E6B000239ED8CF7DC416B54D25FDE19C51732F07 +:10E6C000F135629D254EE6C37B7EC7751A35FB5F2B +:10E6D00012DCC4501F8A3A68D4F8112C4E6DFD39F3 +:10E6E000890FE27E91BEF0B6F5C2D342F04CFB0D2D +:10E6F000C15377CFB38453EF3DCFC36D84F7E3F6B7 +:10E70000BFA0223FB8DCFBBEBFEFFBBD2F769FB79B +:10E71000FE9E6EFDBDDCFDDDF32DF73DDFBF4AF350 +:10E72000BE7EDF0BF7FD447B0FB5D86F2FFC7E9BC1 +:10E73000FB7D325BF877C57EF7E00568C0CFFE1140 +:10E7400073FC4124CBE9D1E23E3869D74F30919D2B +:10E75000F5967350B91DE95FC8A90A21A75845333A +:10E76000AF0B7C7105781C41C1617E7F455190C71C +:10E77000138C391E393FE896124573BEDBF7DE6213 +:10E780009E673CFE3C8FD3D39FFBCBBCA14A7794C2 +:10E79000F6FE867EF288A41F07F47866463DDEC04A +:10E7A000EFB38B70CFF11635353C8FC843FE9D59C2 +:10E7B000D64012E27354B2273E2721946F3409F3F6 +:10E7C0008A14B20785501AF8038CF3ECC624DBAB2D +:10E7D000307FD4F603CC9381E93B8263B8B98B3F99 +:10E7E000C9399E1139C0078F288EF585F0ED3FC6D7 +:10E7F0009D4A42F964C173ED023AF7BD3A27FCDC49 +:10E8000057DCCF1F343849BFF0FE4421FBE11476BA +:10E8100036368C5E3798445EA3EEDF2F10F694FCFC +:10E82000F70B8E4017CB806FCF6FE579D42B133B5E +:10E83000851DC6EF71BD63B88DEE7F62EE4217B7DE +:10E84000C3A57D354CBD1CB979B1F8A29589273493 +:10E85000762E7B6ED0259D2786D6CDFB3FF24034A9 +:10E86000C99B230F8C203F5FA8FF2EB2FBE7D76B1D +:10E87000E38C1736BCAFC1BF45DE8F35EDC1F81E46 +:10E88000D330587FF0C5A1D7CD05F89DDE6D198333 +:10E890007406FB362B27CC0E0E3E943199EB0117F4 +:10E8A0005BE7299A4787881395EBFCA8F130D5835D +:10E8B0008D415D3C8F576397CAD2FC1AA37B727A55 +:10E8C0009401AE487E9693395C6FEF1079901D22CB +:10E8D0000FB243E42D76883CC50E91A728F3473B41 +:10E8E00014E6C6788A798AFB8945C9943F7A17AEBF +:10E8F000B36E454F1EE6DBD58D0E2E5054CA1F5DFC +:10E9000083CF23E48FE661DEFB1F726EFD01EAF91F +:10E91000C70778E95E92A79E9BC1EB664E1F2FE664 +:10E920004CFC01CF27F5FC0FECE75345F5D3FD1761 +:10E930002F29749ECADC41F38C0BE497DE97C3CF7A +:10E9400017D6EB4AF2452760FF4CE47B3D3892F244 +:10E950007EB65828EF07C6A1FC2B79FEAFCFCF2A91 +:10E96000F8B3C58F7C43FA611EC94996F702937FBD +:10E9700025FEE7169EB7150C24619E17C6FBE0BD69 +:10E9800019EC2073F33C307E7F9FDC87477244DCB8 +:10E99000195EA45F14CA13ABD97FE423E42365395D +:10E9A0009EC771FD327FA926E6558A9BD899E3A4BC +:10E9B000EF60BEB45EE007EB1482731F3FDC0EFC19 +:10E9C0005E9FFFDEDFFA4F2F09FC3A2739943F158F +:10E9D0009637B53327CC5F26E711EAE7C2782DFDDD +:10E9E00049217FD7FD23914E0AD00F1EC1CEDE2BC9 +:10E9F000E0D2618AECBFFB384789983F5790C11835 +:10EA0000FA0BE57D93EF209CD0EF749B8BFB4119B3 +:10EA1000BFB7AE6686CD857C4BF68FF7E53E7F812E +:10EA20007196A754BC89EB5F51CFFD7DB2BD5BE110 +:10EA3000FBEA7D88E34BCD2BEF7F74378CB2FCB7BC +:10EA4000B985C8A7E5F77A3877D979FEDE62D54F60 +:10EA50007004F87E80FBA4F7F35D295C2F377F1AE2 +:10EA6000E045F730F6F583032285E96F16F9FD706E +:10EA7000EDFD6616FC771860BC1661F7B408BBA7FD +:10EA8000D524FE9D1C9D1DDC12E071442D89668AF3 +:10EA90001362E2DF7590727FCDDB3CAE684D32A32E +:10EAA000769C1FEEAF12DC4B72A8F79E2A05E42B72 +:10EAB000C0EF94C3A3E6A21FDAB39AE4927A35ECCE +:10EAC0002FFA4DFF76A3B0E7B89C2B1672AD18FB5A +:10EAD000C175E40C24795724C61D63AD277D7A2CBB +:10EAE000F30AFF8EF0833CB097ECC0FF0D9F4D61A1 +:10EAF00077606800000000000000000000000000D7 +:10EB00001F8B080000000000000BFB51CFC0F0037A +:10EB10008AF92C181856593130DCB0666070B4612F +:10EB200060D86C8E90BB218E6053133F97A74CFF2B +:10EB30003C4906860540BC0888974892AEFFB71648 +:10EB4000825DACCAC0F007C87701D25FD519186ED4 +:10EB500003D97F81B803C85F03C43B805804C8BF92 +:10EB600009A499D518189E00E97F40BE34907D44D1 +:10EB70000DBBF9FFB5F0DBBF5D0395FF128D7F4143 +:10EB80001DBFFE284DFCF2AF09C863C35EF6E4C7A3 +:10EB9000471F057A0702AF474BD7E2A60C0C7A66EF +:10EBA0000C0C85D0B4BF0649BE192826610A617FC6 +:10EBB000D103E617207F258E7CF11528CF0F94EF27 +:10EBC00037C76FBF38335A7AE1C154F39609C1AEE3 +:10EBD000174295DB248CA9FEA708030300E92850FF +:10EBE00078D80300000000000000000000000000D2 +:10EBF0001F8B080000000000000BE57D0F7454D54A +:10EC0000B5F7B973EFDC9924772693106042024E72 +:10EC100012D458038C18302613B821098424E0003C +:10EC20007E34565A07E421B640A3B5ADEDF395E125 +:10EC30008F315AACD0F2FAD4767DDF40D5D5F6B913 +:10EC4000DE0A8A4A43422790502488112DD66AFB57 +:10EC5000A276D9F81AED80C1C6EFA38FEFEC7DCE76 +:10EC6000C9CC3D994942F5AD7E7F64B537F7DE7377 +:10EC7000CFD9679FBDF7F9ED7DF63963B7B988E75E +:10EC80000A422EC17F0B09F95C2E21645EFC2A9E8C +:10EC90002F729270C61C42B29C077A67E710B2D8F6 +:10ECA00050FD4B7C844C75AEED26A5840488C3E7EB +:10ECB0005008E9525EE89D4DEF8FBBEC7E0781FF67 +:10ECC000EE22643E21773BE99FB4FCF173F40AEF36 +:10ECD0003FB145082D5FAB361205BE772A7E870F00 +:10ECE000CA9BC6B22984D410F6DF8273A446A1CF92 +:10ECF0006BBC773492D984547B68AD4EF6EE12FE2D +:10ED0000BF49082D5F4158FDA6D3FABE82EC3AA751 +:10ED1000BAE12EA60667D1FA2EEAD6F7DE257F24C1 +:10ED20006E2897F0BC80F603FEA03CB88AB872DE6D +:10ED3000CBA07FDF406EB8A4D2AB3689901BE37CBA +:10ED400091AF848409994C483BFF5E23C1D9704F31 +:10ED5000C833D87EB6E0635D3FF1D27EE79411FF01 +:10ED600012CA87A9756617A17CADA8D1191F6BE7D8 +:10ED7000E7F61B84FCE083B63C52423F8F6C423E78 +:10ED8000E6703E767DF0FC9B5B806F7504F976D86B +:10ED9000EECF0D968CA62750979D46683D7B824707 +:10EDA00033B01E42FEF3D2145E4F11211DC1C2CCFE +:10EDB0005092EFC4F591AD1E421CF1FBDD26A96B0C +:10EDC0003346977B1E06731E54BF06E9ACE0BCFCBD +:10EDD00081429ADAB0DD261CA7C39CFE6EF368461A +:10EDE0007F09BC8F66D8683FC2E76CE4495A45C7C3 +:10EDF000E0A274A077BB698BC2F38E413D02FC2078 +:10EE0000DEB6BC15B346D37FF8DCBAB9D8AFD0268E +:10EE10004BBBDF1FA4FD35A07FCF642CA6F59C1F44 +:10EE2000B479543AAE7BF8F3C3A1B60C0F7C37909B +:10EE30008DE3F9C856FAF7D5A9F9F1C8822F1786DC +:10EE40000C28E7B4F263F0FC89223A6E1D7B353F53 +:10EE5000F46B3C7E7E9FB723EEB3FDD16A0FAD37D6 +:10EE600010F32BA017D983844C2A00BDE838E6861E +:10EE7000F16D24A84781E0A2B42B593FFCAA0FDE14 +:10EE80009F52413E029E28F663841EA0EF6AA0D3E3 +:10EE90008BD747797B3F8471C4FE6D4FBB8AD27B91 +:10EEA000BE4CC37AF69BDBAB34ACEF62540579DC25 +:10EEB000C4E429C717DA6607FEAF27FEB00FEA25BC +:10EEC000D8EFFFCEFBFF635E9F68A76330BB4A03AA +:10EED000FA9A881FD4A456BDAF0BBE0F6C64F4CF52 +:10EEE000B8B75901FE5D715F3F5E239CCEDDF03DFA +:10EEF0002D90DF1C53806FD3EF89E275EFB6B7BA60 +:10EF000080BECC9D240D6CC19E1A5B167CB767F148 +:10EF1000B43478EF0E52C5A7F620E0F7DCD54DFBF0 +:10EF2000B3B746433AF70E52FED372EEB0C70F7A2C +:10EF3000ED0EFBF8D5EF87F2BFE4FC38CCDBEDE457 +:10EF400074B8C3262FD75C02E5DCE1305E23BC9F9A +:10EF5000C4B719E5EE6E2E77BFB4873E077CCF1994 +:10EF6000245E42F5F9F087F5B9D0AEA85F2EFFD444 +:10EF7000E3FFF37A783F7990BC6D9F0DD7E85A682C +:10EF8000EF6AE8871BEEFBD62A68A722A847E6456A +:10EF90001B21C5713B95331C5C7A13DAC75AD42305 +:10EFA00061072A06759B9299A86735A8077BB91E49 +:10EFB000D40C46514EA89E1DB3513E853FA07A46C3 +:10EFC000E5EB70D086E3FD444C473B4C8AA3792B9C +:10EFD0005CA3F5A8E3DC86B9C06FA14FA3EDC7FF22 +:10EFE0001BFAB597F62394C4AE89F684BEC9EFC761 +:10EFF000D5374F18F5AD83EA5B18F819B4A5CD04E1 +:10F00000FD6BB5A19E786BDABA98BE6C427DCB5988 +:10F01000CFE899BA26827A309EDEEDF579AA34A837 +:10F02000BF89E969C7E03BDB1C301E6B08B71317CB +:10F03000BBE03E702FD36B59CF643DCC0CF4A17E66 +:10F0400016EC8C11B8FA7634A25CD356D250FF522B +:10F05000E86107E861E9FF3F7A5823E671CA982C16 +:10F06000CAFFFA186178C8B30FF150AD8FE3A182DF +:10F07000D76FFD2A7DFFA23D03C7F5C5C9F421DE88 +:10F08000AB110238E3CA7F5973372D5F9F23F0CF4E +:10F0900046D4EF3AAEDFC7E011D59FAA7E85CCCF2C +:10F0A0008672EFEEAEA6E54F0E103FBC3AE9531163 +:10F0B0004F750F12AC4FE8671DEF6F37BC07791B18 +:10F0C0002611D04F81236AB97E9FCC61EFBB2F12EE +:10F0D000B403A2FC49A244547A7F9CCBDFF9E2DB63 +:10F0E000FF87BB90903F6F8BCD8ED2E7FF6E8B7DFD +:10F0F000DD468BFE7E99EF69B81FE0E5FE83CBE924 +:10F1000020C70D27AE0DDDA450FC5349621BEE86CF +:10F11000EFBC458FCC2550DF47330865ED57AFFE78 +:10F12000CB7BA4102869D383AEB85E89FA443D2F07 +:10F1300078434D0A1D8F81C8BB6E18BF0F0E7E34F9 +:10F140001BAEC49884386B3C3C1610E315EBDB0116 +:10F15000B883D450B9981F978BA9B1BE63886387D1 +:10F1600018FE22759B711C2A3D8C4F5D17CEE6C19F +:10F170007747385D9DE7FAF2D01ED659EBE9B4F730 +:10F18000AF09B2FAF1FB80878DA3A0A75DD8074530 +:10F19000E025365E01FE7DB9D637690EE57FF909B7 +:10F1A000D5BF8D7E573EDC5F4392D89D889285FD0A +:10F1B000AA18B0CA67E785E32AF085D2AB02BD95ED +:10F1C000B13E95D96D2657012E5795B133167B2E3A +:10F1D000DAEF8C9D699803F66380D9A7547CEDE63D +:10F1E000FD38CAC7FB88D04F12C900FA7B28FD0F33 +:10F1F0008DF17DAD47B5D02DF4ADDA9961C1E70B46 +:10F2000087B325BC6FA5778116457E2D007E91D4EE +:10F21000FCFAB6928DF52F1CFEDBF825DB11516F41 +:10F2200027F0B164345D04845BD0ADFE9FCFD74E30 +:10F230006E67A8BFD20DFA4AFA0FA8A08FB5AA81AF +:10F24000F6A5E26625E248B02FA29F0BB95E4DBD40 +:10F2500048D06E980304CB1D8E31FB9F8ACEA35BF2 +:10F260004DEC5FD645DF4E98571719C17CD09BAE49 +:10F27000C97F647AA69C43FD322FBED7FB55CAFFD7 +:10F28000535CEF0E6FADC3EBCB5B9B912F014371D2 +:10F290005D0F54CD64FA562DEC1A9F4F4E70FB71E2 +:10F2A0009CCF33AF6E0DE1F357B66EE47C65FD592C +:10F2B000C4FB1335AA0D18CF6E6711CEFB0B355367 +:10F2C0004BE65755C4AC7274CC47F18E0178EBA86D +:10F2D000713DCCC7D43F46BCC2EB19F92E5F6953D0 +:10F2E000E6C4EFCF0A5CC4CBFDCAFF2CF3EB6ECEB5 +:10F2F000C0F9A02216AA05BED63629C4097C9D3EB7 +:10F30000AB318B3EFF7C93759C457D3D39EF4E02C2 +:10F31000BE5704825A905E6BA3B7683E57EA71E805 +:10F32000D1828DD7E1F832FDA988F5D798948E2542 +:10F330009E8246F44787351BD8C3463ACFF5A35E75 +:10F340007890CF62FE3895A3D64500EF0DEECF0042 +:10F35000FABB3DEA64B86E87C981CA51ED458A4F50 +:10F36000E78CD1FEB046794E2BD2A2CC5FA3F5C07C +:10F37000B5C750F9F3208E470FAD179E77FDF5877F +:10F380008D737300F7ABC89F00F9DAA9EB60FEF24A +:10F39000DB91DF426F851C741B6C7EEC8959E7475B +:10F3A000C4B7F455CFE0F76F5E09F323B1235E12C3 +:10F3B000F8577C7FC4B87DEF0AD03BA2FA0919FD4B +:10F3C0007DF066D5A247E57EAB9ED5974EB2DCF7C1 +:10F3D0000CAEFBF15DD05E2C9DB517DE64A1F78805 +:10F3E000C1E6DF9E08C30762BE16EF0344D66FB9BD +:10F3F0003F8B4EF9C1CE50F9043B53FD49A951430F +:10F40000EBABC9513DA097C73CDBCE82BE7C10F868 +:10F41000F53760DEAD2BB1D2DF3138977DEF5591F6 +:10F42000BEF69CEBF1FEB0D72EFA6F2C037AE02FDC +:10F43000FAFE08E97F7536AD7755C44AD78A6086EB +:10F44000E57E73DD24896E6B5CA8FAE2068CEF2CF6 +:10F450002AEDDA914DEFCBC11415419CC961F92E0B +:10F46000E0B4DE97437C877EB78048CF2F2EC6B8A6 +:10F470004E39C475C473E0A764C7E93DD221E6796B +:10F48000593EC57C9D4A7EDB6D6423C443C8D0CA07 +:10F4900071E242DB93CEF744DBABC0F897739CD0AC +:10F4A0006E6FCB80E795E798FD2443D949F18D3CF9 +:10F4B000EF13F2359423C14FE209939CF9C8C7A416 +:10F4C000FD127C69A5C37209F00EC749F87112FDDF +:10F4D00096BF9F02FA4DFBB3B8E9408687CA5775BD +:10F4E000CC86F2D561EC41FD6CF7AB5C1FFB2F25A0 +:10F4F000CA674353D529880FD2F204F4B7C3B80BB7 +:10F50000F537781DD35FAADFA88F01AA8F897858B5 +:10F51000C8BF2CEF03247CF67A68977CF4DA2AC003 +:10F52000C10759BBB2DE53BD433D3E4FD4547A8E22 +:10F530007AD943F532593B97AFE73613DA3F7FD09C +:10F54000C570F7283D7FB56612B4E754587B9FB16C +:10F550009E1FE1FA23CBF7687D5F6480FD3F6FC893 +:10F56000FACEECDD62D7BBAFCE66C52D7AFF59E986 +:10F570007BA0789F0A5049E8F178FAFEB7EA794A09 +:10F58000FD9DA07ECBCFB7D814A62F29F433AEF7BC +:10F59000612CB7C3458A213ED6AEA4FBB717809E27 +:10F5A000B3788D5C3E5DE5F51267F80FB43F6BA94B +:10F5B00053964959BD99F4CF808156737DA8775BE6 +:10F5C0006CFD53E0FECF2436E55A15FC067208E2C6 +:10F5D000408A49C8BD9424C5E7216BA8A3D5A2865B +:10F5E0002ED968796520FA890203790FF101AEBB43 +:10F5F0005A09D954FADC41F963D0F2443B83788F3D +:10F6000022201CA7E55C09963B8D28C6CFCBEC8356 +:10F61000FD426ED05F5BE379EF5A5A2F892A97AE8D +:10F620008DF7F3297B24CF6F403F233FDA02F1A609 +:10F63000C774FF93BED1FDFCC426FC9FCBEBE7272C +:10F640005456909F36C6CFB02DDD0FF12CB97E53A6 +:10F65000BDECFACFA6D36B05F071CE683E2A839439 +:10F660007FC007ED3F2F81BF57E16572A5FE593777 +:10F6700021BE425467E4CA2474ACE774B4A8E66CB3 +:10F68000E0B75ADD86FC390CE36F00FF72C8371211 +:10F69000E4AB52D5B17F6A0369C67985446D6037A2 +:10F6A000C61B0FBB463415C6B1EF12DADB164E9FF0 +:10F6B000833E37E6A61E2FB5C11F8BD271227F660F +:10F6C000E37478A9552EBFC6E9FF32D0358F992152 +:10F6D000A8BFDCCBEC90FA27BD3992448E7708FEA8 +:10F6E000737EC9E50FDFC2FA2FCA7F87CBFD372FA4 +:10F6F0005FFE574F2D4A3D6E42DE95C1E3A9C6AF6E +:10F7000039D9FC364BB5713AC2CA44F4A15265727C +:10F71000A956D37183FED55AF9F86DCE8F55BCDE4C +:10F720002F2A6633C8C3D54AF06E15DAA9E943FD1E +:10F730002B847AE8F36B89790F3CA7EFBF01E5488A +:10F740009DF53D7DFE2D7CDED487EB4AE279976204 +:10F75000FE23FFEE9FB05ED3FA9ECAE156784EE5D7 +:10F7600085A873E1B90FE9A172429C602FF6DDFE16 +:10F7700005E02BFDFE7EAC9F9CB17C6F070391CD15 +:10F78000AECA5C767D1CE48EFB993B9A4CE4AB4E92 +:10F790009AB91FCCE6AD057CDE728202C33CECD187 +:10F7A000715ED4D2CC48945EB33D5113E278934855 +:10F7B0005F18FCA8D5D27CDBB4C63ABF7C61BD75AE +:10F7C0007E59B329CF72FFA57B8A2CF7A1FBAEB57A +:10F7D000D4B76EE7F596FBF5BB2A2CF71BF6565B04 +:10F7E000BEDFF8E306CBFB2F3FB1CA72BFE9E95B8E +:10F7F00093AE4B8AF9EE41DBDB9BC01FDB01AF12FE +:10F80000E60B2DBEEE686338CCFA1D153F9F361F00 +:10F81000CA110C29C872AA49EB96AF8FE8CFDD96C2 +:10F82000F9F668B820C74B596A166806C6DBC26687 +:10F83000DFCC29F1F9BCDA47E76337F8E1C9D757DC +:10F84000355EAE8AF457C3B8999AB59CC6D7590DA0 +:10F850007F0CE329F23AABE663F3B44CEF19D5958C +:10F86000037689D6EDC3F555237B42EBABE3F68FE8 +:10F870005AC209F58FB75705FD2C4ADDAF05A531F2 +:10F8800015C89B68BFE2745A718F58DF5EC68A92B2 +:10F89000F282273280DE653E86874829C3374EFADA +:10F8A0008FCDB38CFF0DBC7CF01E8F1DE2C8C11A3A +:10F8B0002B9D0D1C3F513DD4C04E94174BEF81CE74 +:10F8C000D950CE8A93BAB93CAA1A5FE79E4FE6E3B5 +:10F8D0003870BD5D21F4B696C5278827F9FA77FD03 +:10F8E000302D84819888256FE06471513A7CB7ACE3 +:10F8F00095F81C149F3C386F9B6711D5FF46D3EEDB +:10F90000AFA3A5ABFD2C1E5E6FAAB8CE7B4531BB65 +:10F910006FAC51224B287DF5A13E8CE735AE8F6C44 +:10F9200083EBB48D510DE990F8FAB82F926553E34B +:10F93000FCCDE3FCCA137CE57C14767CDA26EB383C +:10F9400036965AF9B59CF353E6F372CEC7E5121F0B +:10F9500045FCAC44E3F22CF17119C7A1CE794563A3 +:10F96000FA758FF33897901F4D9AD784FD1899DF59 +:10F97000B8FCB6801D079CE7E13885CF7B55331571 +:10F98000F4836ABD0AF2B776E63E4B7C73C9885CA5 +:10F99000323A6BF97897E7BF8A71CDCE1C3EEE9470 +:10F9A000AFB5F3E372D83093E563ECE4FDEEE038F5 +:10F9B000BA9DC72D5BBC67D4C4B857C78CBE7C3F0B +:10F9C000BD7FE942DF9AAF517A1AF3157F1DB41B50 +:10F9D000E271565EEFE1EBB6E5037D27CEF561DC23 +:10F9E000E7A59CA231E38802BFCBF250EE0FD6C050 +:10F9F0007CB224FA0B15FA5F1EA36C53002747351F +:10FA0000C05F8DDEBB358C73E5DFA541BCB1367FB1 +:10FA10005F35B41B20A1DD5510F7CAB1FBA33E88AA +:10FA2000FB8477BA419F4B985E6EA4FF12F552D0CB +:10FA30005D31D8AC019D4B7C92FFC2E5A8D62B3D31 +:10FA40009FB904E52820C9D13D420FAF245726CAEB +:10FA50008F8817E8E70AB91E26971F310EFFCEC719 +:10FA6000E1773C7EFC268F7FBEB1D587D75F6D2DB9 +:10FA7000C6E73D5BFD78FFFAD632BCFF358FCBBEC3 +:10FA80000A71568C930679BCB509EF7B79FC54C892 +:10FA9000E7037CBDA356EDC0F860833FE4F424ACDB +:10FAA0002B3470BA51A4015F9414255DBF75CC3816 +:10FAB00084FC3B3322FF04EDC0CAC682FD0F51BE59 +:10FAC00038BE434280171D477FA15D45E5BAA1AE10 +:10FAD000C0BE01DA0BB769D7D3FA1AA2BFD08AE049 +:10FAE00079E375F6DB93B42FDA49D5BE6CB756D5FA +:10FAF000A9921F2AD68F4261E8E7D458280AF40554 +:10FB0000BCBACF9104F777E56EF0825CB59C0B79B7 +:10FB100041AE5A72D93A032059901B9DCBA9281F98 +:10FB2000F05AD7D7754E77077D0EF476C4C65EF7C8 +:10FB3000167A20CA55686DAAC748DD3F397EB4538E +:10FB400049EE8F5ED46CF89D1BFA4FED37B5851AE0 +:10FB5000E8198828D03F958A0DE8976110B42F19CD +:10FB6000FE10B7B7D6F939AB2C18AC827239C4BFC6 +:10FB700004CC96D1EF05B951CB16BF0FF327294915 +:10FB8000B0C7E0CFC8FE7CE2BD8A262AECCA86ABAD +:10FB90005C8EF1D7E022D47A1DA3EF7B03D6F8AFB9 +:10FBA000C1F95BEE3BF11BB097DFF3DB58B91CB634 +:10FBB0004E7ABE6C1DE2AD728EF71D6437964F27EC +:10FBC0006D78DDC1F97DBEEC0C81F95BD5281ECEC8 +:10FBD000017A9C9130FDDE2DD96DCDB0F25BA13C58 +:10FBE0005903B87940B3F8114A19B3DF4EF0C3C1D5 +:10FBF0003FE1B824EEBF85C82560FE0471D24EBB3C +:10FC0000D5CF12D7DF6ACC0FB1D9A5FCB6FFEBF97F +:10FC100077FC33E59FF0FF46F0DBB13B09ACA788EA +:10FC2000FC3E51FE57521C49CF7FBBC64CC2F72A3F +:10FC30003BE3FB7576096F05E476D2C2C04F9DFAAF +:10FC40004969CAE87A52B54706E68E138FDAC6FCD0 +:10FC500044CDC3FAC7F373A8BBAD58FC0EA7E905A2 +:10FC6000BF6FD4F75E9B454F47D3CDF8F359D3BB55 +:10FC7000903A9A705D2EEC7019C3892B7C1427D2B0 +:10FC80003F57184C4E4F572991ED28A7A6C58FAA6C +:10FC90002B5BF23EDA25EA67E8F339FEA6F4B742B9 +:10FCA000BDB49E5772C57723F6C47669CEE87A82D2 +:10FCB000350CF790F0CF9726C60582545C8AE74250 +:10FCC000BDEC7B5AB4EB52323AB8DD0A96DDB5DCB6 +:10FCD00070C3BDA93C0A38AE24011F005F673AAC6F +:10FCE0007C96EC5FCD28BB67B5B78BA9FC1EA2ED57 +:10FCF000D4A9CD8D35B4FC923DEB0EBE88E408FF4F +:10FD0000C297B4DE53F0C78D80F6AC7885F8599E63 +:10FD10004575D887EB822B7214122900FAAD742C2A +:10FD2000CE97FCAB1CB91FBB711C8F6A741EA1E37C +:10FD300075948EE36EF47B93FB49C27F5B583084ED +:10FD40007E92F0E308F7E33CF45F221EABE4E5AB00 +:10FD5000EEF169B07E5025C58F2B47F28109FA4933 +:10FD60000B8995DE4AEECF554AFE9CD0F79F0ABD1F +:10FD700015FE2AB78737093FA93239BE10D70E2999 +:10FD8000BF8DE247B3ED32F4800055B4BD4632C2B8 +:10FD9000278B7C75155CD516A57CBDC99FC6F2AFB7 +:10FDA000299D9AB0E7C82786B797F3F237F974947C +:10FDB000FF804741FBDE384E3C2250C6D6555E36AA +:10FDC0001496371826AFE17A11A7A786FEEFDEB9A1 +:10FDD000D09E552EF27D7DD59939306F28FE0819B9 +:10FDE0002DAFB57C5CE1FBFBB2C14FA1BE7636AC5A +:10FDF00067C8F1883E0899527F9CFA4A05A3FDF92D +:10FE0000057C7CABFC04C47E943FBF808FEF8251A5 +:10FE1000FEBA1567BF1C7B07F3ACCE9728B82ED26D +:10FE200055F031FA09629D26CEBFE3E84F05CA3E80 +:10FE300062790323FE08AB6FB9A8AFEC18E617DEB2 +:10FE4000EF3986791CA74FB0F5EBD35ACC007F640D +:10FE5000A9C05794A35191FF5E007912ACBE28CF80 +:10FE60006778D9F96A06D84D9117D21948BE3EB7BE +:10FE70005065F16371CDD7198E2BD6D9FC23EEC511 +:10FE8000F88EC8937AAA94F97BDFB68CBB5C3F945A +:10FE90006FC2B85FB42438467E41A3C4678F6EC575 +:10FEA0001BE3E15AD14F990F723F47E98BCEE260D5 +:10FEB000ABEDE6747D72BC1D31DFC9E5573893E7C1 +:10FEC000CD549559E38E72DECC6A7BA804EAAFD696 +:10FED000949D993EB46BA84F472F1A8863CEC78E66 +:10FEE000EE8461ED196271CF4AA2F23C1AB311D6C9 +:10FEF000D3C43E871A1EA790E918AFFDCAA17EF4AD +:10FF0000B3AB866335207F3705BAD0AE2EA37675A6 +:10FF10005212BBBA581DDC3909F4D7AFA07D78F96D +:10FF2000ADBE9A494C9F313FD5AC2CD226811C786E +:10FF300092C7A116703949A577F4430D70C344F5F3 +:10FF40006EA53E82836EB85434FE38A59287F3B115 +:10FF5000F35F4B161F15D7EA14E3BB8548FCEDB0E1 +:10FF6000C695E57A449C87A81DF9A0CFC2FF95CB22 +:10FF70007D5B67F1FE9E597790FE04BF4ED803BDAE +:10FF8000ACCD80F8446FD9D8F3859CAF5645ACEB27 +:10FF9000CED54EEBBA73AB66FEA36EC1496B99BF6B +:10FFA0005AB616FDD5E5250EF457BB66DD81FEA9D0 +:10FFB000F0AB5B6E3C807117914725FC5399EEDEE8 +:10FFC000DC670C28371EDDC28FEF74B03C20F0DBFD +:10FFD0007DE8B7BF8DF94572F9430EC6AF2735F3FB +:10FFE0000740FF4EBBE95D0BEB87B31CFE27938CEC +:10FFF000C31B0EA6DFBD29D6514FC382C664EC07D2 +:020000021000EC +:10000000F2419E6F841F2BF60D4DF532BD6DE07EE3 +:100010006C45C95AD4C72C2FF55B816F7EE6B79229 +:1000200041AB9FBADCE8CB83F197E73B7588FBB522 +:1000300013F45B1F48637214F210A797BE4FD328C6 +:1000400034A5F3E82E75D173C08F07B208FA03A761 +:10005000B3F4C8FE24F18617B9BDAB553759E4ADEA +:1000600092E312BDA6DF8078C0E9A1B1F3F21E923F +:10007000707A6131A972B8E11AAB027ED07BD3816C +:10008000D718E64B7F77D686C264F5ED6FD592CE52 +:100090004B6FF1715BC9E7BBAC3A169FDC52A263B0 +:1000A000BC776ADDDBC7514E1BB99C2E7360BF7BEA +:1000B0006769382EBD3716B4C17A65EF2C27E6275D +:1000C00074CD7AE1ADBBC1AE96297CBFD9468BFC1D +:1000D00056525C9D0EF57B55C42B5BA8FF920EDF3C +:1000E0007BED0CBFF03C90CD7C4C4F1F64F8E64399 +:1000F000816F381F5709F96F14F1502B8EA2E6C497 +:10010000B24E43F8FAC312562DB5534C1F3E6C64E1 +:10011000F1CC2DA2FF870EEC043D6CE072D475612A +:100120008317F5F5D0018CA7B5CC5A8BF1A3AEDCC3 +:10013000B33ADC6FF6BEA7C3BD8C33C4386F297BDE +:100140001671482F1FE7CD1077A7F2BFC4CBF0552B +:1001500074CAB5769F11CF6396F1DDCA681AF67F2F +:10016000D5451BFA9D2BF9F747A6FC4987EFB64406 +:10017000A91E53FBDEA0F5CF00DC9221E1C50F9F45 +:100180003B900FFADD33FB8F58EE8AB2B75B80EEFF +:10019000696507308E9F77E8407736AD7F7931F11A +:1001A0009BBED1EDD7F2F9694B0EDB07B1C51F0934 +:1001B000C33EB00F8608CE4F0B9F3B56ADF892ADB5 +:1001C000B79804708858AFD1BC7CBD83AF3B908B8F +:1001D0009794C4F16AD0424EB0BF2D65AFBA81DEAC +:1001E000C283EA5A90EB9AE7AEFF22C81FB9D1E169 +:1001F000B992F6E703CFAFDD5719ECFD1DACBE0594 +:1002000021CA8F869203F91B668DB62B237A53F28F +:1002100097AD214AC7E9A52FE4035E7B95DA5B1F02 +:10022000B4C7ED95EC272D94E6D3C090B4CE24F559 +:10023000D7A5ADB8D1310FC6F347DE820479A2FA53 +:10024000BF0EE8DFFCA8D303FA9275E8155D05BB85 +:100250004671FB920479DECCE5A5C16076AF6516E8 +:10026000896C5740CEDE6BAC007D7B5165FB500E38 +:10027000BDCDF23EA579A197CF1742AE7B73DF715A +:1002800083DC7D7890EB47D8A624C6918CB2D8CD7C +:10029000301E823F1D929D0990E4F3C22907C3A935 +:1002A000951A7B6F50BB0DEBD4F27B13FC28C04139 +:1002B000DC9F12EFD73B18DE15D7CBC82BF8E177C0 +:1002C000A8BE77ED3AEABD1DED9381787DF3A103D9 +:1002D000C5B00633E5E0811A9EF78DFE98CAFB395A +:1002E00095F8D03E2D379CB87E20CBB7BD6C5F14FF +:1002F00060B3989FC111D7A6C4ED869A187F48E2D3 +:100300007F91B0F9DACC843C2C3AAF13B01FD55EA4 +:10031000167795E524ABECC04E361F50294C58C7D4 +:1003200095E5B6C10879617D9AEACDFB6C3D93CE27 +:10033000531097501BFD389E5C3E6DF41FCC7B190B +:100340007EAB7CDA8B750B4E91E978C4C1D7C5388A +:10035000EE17F37296B71FE95B6EB4E543FB53BD2E +:10036000FDE86751BB9E0F572167C24E8FC8DFACB7 +:100370001BEAC14E815CC392F7E9B2EBD3C1DE3513 +:1003800078193E21521CBDD73BB69FD12DC9E369D8 +:100390000FF3AB1ACA48BA2713F49DC59B7A1FCE38 +:1003A000DE9791108FDB630FFDAB6372FCDE5DF2B5 +:1003B000F97A8F1BEC0BCBC72AA766CB5E148F6331 +:1003C0008A78A958BF13F1D15171CC922ECCD7B2F3 +:1003D0008B3C0ABE9E372A8F6782F9678EED6D9A35 +:1003E0009FAF93200E6BE4F1B7A1B9E3C441B70905 +:1003F0005C76DC31797C5CF628F72BDF00E341AFDB +:10040000B7383C783520BF8492DA9B961CAF1DE04C +:10041000F8E572F4F3840ADFB176DE7458FD4AF130 +:100420003C8E83991E4C2D3BD09D88832B5B296F7E +:10043000E838E9AD6406C94C2D77CB47ECDEB3163E +:10044000F91AC1C5E3E061215F83AAF967C7BCD48B +:10045000E51A381DA9DEB7CC723441FE142D47A62B +:1004600066B2EBD5F4DA3DFB40BE8D3E3F09B82BBA +:10047000818EDEC70E613F5ED6D9FE97DE0B1B0A6A +:10048000611EEFD24CE29C3771F991F5C939CFF476 +:100490006DA3FAD799EFC4FD7E9D5E86375E81928B +:1004A00009F2B45E0F799C93718A304936377242F3 +:1004B000CEC168D64C6CFFD66D19FDF70413ECFA6B +:1004C0002E78958BE70660BF1ED4FB31BFE6365A07 +:1004D000BB83B673CC50A7ACA3F7454E66F78F85A8 +:1004E000ED16BE886B9193C9DD7A3D58047492B6BF +:1004F00066D4B3B58A1A04FD27FE89C5E576B4270C +:10050000CF132D8DD73F07EB3F48EB07DCE0E771BA +:1005100077E2999234CECEFB1D25A40EF4E57B59EB +:10052000563F739693E9D99C78FD1589F5CF7132C2 +:10053000F9A7CF17E0F3A7D9F35CFEBCAA88E5A919 +:10054000093E8A7A6BE3F5D5E27787D877939D7C6D +:10055000BD80D32DF0BD9CCF74431A1B8F2AA17789 +:100560009A8278BB9CE26FC4F7DABE6318BF73F25D +:10057000FD91690E7CDF916B477CDFF10941FCD96D +:10058000E962F1C8AE0B676FFD2ABDD78689251FCA +:10059000DCC165481B7A0AE36FE5F97C3F1BD7573E +:1005A000B16FEB486CBF655D55ECF3E974F23C0C40 +:1005B0005EDF025E1F9170BBE897C039ED7C9F4EF5 +:1005C000B9E8DF407407DA958128F6ABD2C3D68349 +:1005D000BBB2BE81FEF503179ABD8971C1AEE9C7F2 +:1005E000D9BEFD7C4A77499C2E8DE3B1F261DBA632 +:1005F00003C00F4DC18CEDAAE88B1905B4FF8B4EDB +:10060000A8FE34E8BFE4672CC9E779D41CE7A6C28A +:10061000F5BF54623F80FA6D19178B80FE2353FE9D +:1006200055053C5A1E7D43059C5EA9B1BCDD851273 +:10063000FE6887F33A809EBFDA2236DAAF9EF3EF88 +:10064000A9307F5C311CC17E4F1BEEC3BC89BC014D +:1006500016DF5D30534985EB7764421E868FED735C +:100660002DF7EFAEC9867A87F8BEE5D8F94940D7AD +:10067000685C6FC529015F15F67B04E7E7B3B8D264 +:10068000E5E2E94AEED708BF408C3FE503EEE36AB6 +:100690001FBEDB09F36315E76B61BE8DF907D30B52 +:1006A000D7A07FF089EE817CDF073C5F77A27F4097 +:1006B000DF837F5009FE4126C4E5FAF236B846F7DB +:1006C00047C853E1D0C75B43B4FC11FBEB79806BA7 +:1006D0008F5E782A0FECB2C80B17B85E9477695515 +:1006E000CF83BD16790802E73B04CE8F3513D8CFF0 +:1006F0005F396CB3E07C0797AB4A83E955FB5F0930 +:10070000AE7375BDFF5E6F01FDBEF34516879E1A81 +:10071000EB5713717E39E777E7277D78FE8890FFE6 +:10072000CEF7D939221DF97C7F0AC7F98B092BBF77 +:100730001870BEFBF271FEEC3466774C8EE317F353 +:100740007C54F1BE9FDB7119DFCBEF2F17DF138EC7 +:10075000DFE3B8D82AB75DBB0A713DA5DCE364FBD3 +:10076000CD0662CFDE45AF5362A127F600BF2FA6AC +:10077000FBE13307F7BFC6CDE794F0FE5412D79BD9 +:10078000287D9495DF8F7A5249F504F6938FD2072E +:1007900019FFE7C78E41F90584E955F57088AD8FDB +:1007A0008D83F72B8DFE3CC4FBC38BDF677EC3D8E4 +:1007B00078DF94F297EA663AC6F64FD3AC786C814C +:1007C00088770C37B378E47033C623170C717B79C4 +:1007D00081D94B319E0F70B913F65CE867E785B39A +:1007E0006A28C16E8EC8F730DB872BBEEFCC6778E6 +:1007F000FF275A1FEA73E7D0DCF4C438958CF73B27 +:1008000001EF97401C89E2FD39A0BF04ED5E27E0AF +:10081000FD04BDA578FF9AB404FCE61E5A5DEF8185 +:10082000F5E009E613083F7631F8B1D909F152A78E +:10083000D58F4D25DF67F9FC1DE7671F9B7F86FB82 +:100840008E25F253E3B8D60178724E7CFF7A672A80 +:10085000BE7E62DDC72CF2B53B8727E637515C5B75 +:100860009F363975B94A4E47AAF70F5CD011D702A7 +:100870001E9F3A875DAFA6D7EE8FFBF212712D3126 +:10088000181EEB7CEC37B83FB8338BE2D992443E6C +:100890006F1B077FB0FB055E3B5F87B1E20922CD8E +:1008A000FFED2E260747291EC1F848DAAF908F1DAD +:1008B0009F9CC5F6657C22F0888C4388843F04BDEC +:1008C000EDF98CEF476267BEEB877D7327C43E531B +:1008D0002B2E91F9353E1EE9437B2ECB7987CBC475 +:1008E000BCAB383ED1116F3C60677843E0138A3B64 +:1008F0008EAD05DC3140481A89D32F708AC01D6245 +:100900007E6C1FE6E72D79F8BC20E19411FBFF29EE +:10091000718AA847C629723D9D3CAFA39DE2966DA2 +:1009200088638EE33C3B51FC22E395F17049E54C32 +:10093000864BDAFDEC3C268167645C52E7EBC23CF7 +:1009400040815F268A5304CE91F18A4C5727E09765 +:1009500092387E91F18A2C4785F9642DC4F7058E73 +:1009600049A59F50EE0E771CDFA42A47ED33E29E87 +:1009700094F50CC52E17F7FC1AEC4A6ADCC3C6B90D +:10098000F222C13CA05478E4017F3F3B8F489A3764 +:100990008EE49F7913F7690EE83E157111B5934601 +:1009A0006A3C24F46EA4BF60074AE2F3524ABE0CCC +:1009B00070FDC81F7BFD65A27849CC17B3D3D87CE6 +:1009C000906A1D323D9DE1AA070B997F2CBF8FE7EE +:1009D00095587113C99985F2FD55BE2F39158E2290 +:1009E00024E66671A930B683F9E480C34037E7F3A3 +:1009F000BC024A6A70269909718D20BC8775AC7952 +:100A00004A244C495B01CFE9B856D5B075A033B341 +:100A1000D83913A7AB1C38AEA73E6479875D2E1674 +:100A2000573D7D5D9A7F3F25E143A897CEB767D2BA +:100A3000FA4A615CA78B7E66B37E2ECB886EC27548 +:100A4000F0EBAFB5850B46DB8707D3391DD906AE72 +:100A5000A735F0F814AC07E6CD1DBD1FA035BD00CD +:100A6000FB0DF9EF79B4DC4E5BDF770BE9A3341BA8 +:100A70005B3F95F9FADB7445E4EB841D097C689CC7 +:100A8000E934D3A83CA67D8EE50374D638709D2941 +:100A90000D96CC69BD0F1517BA92C987E897FCFC73 +:100AA00061DEEF33D363787EC6CB3C8F77B3A68409 +:100AB00081DF6880617E9A346DDF43B4E8D274765A +:100AC0006ECCCBCFBD8271A197B2381F4C05F31508 +:100AD0004EFB983E853D4604F655D2EFEDABC7D0B0 +:100AE000E7BEAA25C51C8F1105D6C9E08FC2D1FC6F +:100AF0005E55A762BF577976DD05F3C699BA5733BD +:100B0000E0DCC7E54336027AB7CA537E073CEF7292 +:100B10003139063E03FE5F55F3F9AFC0F3C646EB2D +:100B2000781C4C2F44FE56686C3C60FCF2E68E6EDE +:100B3000977848489F92C0FFC00BDF5412D62144DB +:100B40007E8A3345BE5EAA7E2B8976578DC719A74C +:100B500096EDDB0DFB5B82A5ECFCCB061F09C37A8F +:100B60006E839F440BB87C61DE4CF74CB6AF87EBCD +:100B70005756D9BED642884B0E696C9D599A5F2A4A +:100B8000E858E567439C9C8DCFE9792AE2910AC831 +:100B90006BC4F32B197E6F30D722FE6F7CB87B5766 +:100BA00021BC57F36BAB7C6C1DD492477588C5DDB7 +:100BB000564872EE92E2FA157E290F90E7EF75160D +:100BC0003FE101F979309BCBCF5C05F5E815C5F71E +:100BD0007061C23C7363BAF0CB88CF9E201F23F2B2 +:100BE000C0C757E67B2A7ECA7C92E542E6F7699742 +:100BF000C4AF14FC4FC5EF8AB2AABF2B7F3FB03BF6 +:100C0000EC20B75DF63FE6B37815B5C109F644E6CA +:100C1000DB0786CF0576E2CC108B87BD34DDF74548 +:100C20003C8F8AEA319E9FC9F5213E0E541FDC8914 +:100C3000FAFCFA0CD0672A6776A8A7D154CC34D036 +:100C4000BF830FDC85FD063D75C7F548E6FF28FD2F +:100C5000A3FFD304BD45A3F548CE0FFB5BF5EF4ED4 +:100C6000B0E7946F73D37D7815F6B49178BE98B8D9 +:100C70000F55AC937715B40461FF78C3808DC07CA9 +:100C8000D33EF48CB60EF6A5D62938AD19A40FE9DB +:100C9000355A59FEC3558FDF4B203FFDE1E9C40FA4 +:100CA000F6CA6865F910F43DE64308BC2ECE4DA4A3 +:100CB000EF4DE687B376EB79BB2EBF359F67E5E056 +:100CC000225C4FE82EE6F148EE37883C5622ED6371 +:100CD000698127B9F1FD1EAD1722E83FB4A7D8D727 +:100CE00022AEB21F205F7B8EFEEC2BE00754CED4E9 +:100CF0003D00292A87A24EA8EFBB2547EB105FD500 +:100D0000291E5867EBF9B86D07A172B4B2E49DA42F +:100D1000B8E4F0073FF4433F0EDB77FBB3C13E6C12 +:100D200067F356DAD525D3D78D817B427555750586 +:100D3000B353E78DDC9AC1E7F7AE3BF73F08EBD939 +:100D4000833AC643EB393E6ED07637ADA3E3D9BDC7 +:100D500054F16FA3CFBBAFD9D37C14E2C8EFEBC083 +:100D600071D27BE1A97CF0234E3EE66C82FA7B3E99 +:100D70007EEAC7983732A8CF87FE8ED07FA5C1DE26 +:100D80007FF8FC09B0332B8B5796423B691AD90D7B +:100D9000F274C550DB9B70AE41C3803E0FECCFCAEE +:100DA000BA7DCE7F003ED53DEBBC925EA70DF96AC1 +:100DB000613C33D243733228BD792505F7E7403BC8 +:100DC0007EE23791AF7D04F8BA528A3F5672B96914 +:100DD0005F5AE04A8C639C192A74617E421DCF4F92 +:100DE00058AA06C10F3EE3B9D28571C73A9697203B +:100DF000F36B25C7E92BEB0AA627C3E385757F4173 +:100E00001CDE7E8DA32919BF6FE2FC4EFBD386FD4D +:100E1000D0DFB41F393D00AFD352E45B6667F07C8E +:100E200052EFC4E22002CF50BE3AED0971108AF7AA +:100E30006FCE4888AF5C6EFBF519CC0E0CAAA12FC3 +:100E400001FF2B781C64BCF843F938EB6E548E908C +:100E50004F2B797C62A5884FD4174CB7C42788E9FB +:100E6000053B7B06D6DDC0CFD6566C013A7A3F6093 +:100E7000EB6EA9E477E5CCA76E3D9A60EF7AED269C +:100E8000EE97ECBE86F949FF55F23B226775CFB667 +:100E900096D2E70F95AC9C0CF62F418E5B613C2EF1 +:100EA000578E65FEB52F2D7211232ECF428E47CB64 +:100EB000A582FEA890EF54E301E5C01F5D398E3F87 +:100EC0007A66E9D549E53F5ECFB931F5A086CBD545 +:100ED0004D5CAE2A89E9C173A9F2DE44BFF557DC47 +:100EE0001E8FC889AB0FE341E1279DB83EDE7941F3 +:100EF000C7F3CD3B9FD8F8139837BA871679DEC36E +:100F000079BCCAB38AD2750DF80F25383EDD5A4236 +:100F1000BCFB8D0CB11E6ECDDFFD37CF1FB2ABD841 +:100F20003C6B54517ECFE1F3C4E70A9E4887F97CBD +:100F30000ECFA39FDDA1279D973984202539AFD8F7 +:100F400000FA971CB4963346F691B7D960DDEF737B +:100F50004F4BEFF9FE6739DFB13723F9BE6731DF59 +:100F60003A2F8C1D47FC39F7AB9FE6F9BCFFC6CF83 +:100F7000ED6BE3E7DC3E03FB56E9F520EC5BA5CF28 +:100F80009F877DABF4FE10DFB74AF227762EBB3881 +:100F90008749E77C68CD8D58D607C53EEDF652955A +:100FA0009D53E1D5F11C548A9B6C987FC2F1A22D10 +:100FB00023E0D4E9B8EAFF4130FFE4EBEFF7A13CCE +:100FC000ECE2F3AC8C633A243911573DCE470DE285 +:100FD000589DD3434DC1123E602037F3A6EE7B28C7 +:100FE000014FFF2F2E172DDC6F0B5F209127957877 +:100FF000F9972E90A71E421C45C22AE00EF88B8A54 +:1010000070FD00411C575FFA00FA5F80030197E111 +:10101000F96085101F7D1EF15CFDD0FC3BF8FAC124 +:10102000281C37C23715F9C4F079E92B1827A91FF6 +:10103000482E6FF1BCA5A6EE9909FB0C1A87C43A9D +:1010400005A5644A7C5FB92EC9955C4F56A982E319 +:10105000B2AC98EDFB12EB1C623C7734F7617E4733 +:101060006FA9C307F1051927CA385F2F65FBC2B402 +:101070001BD9FED4FA0B2CCF1005664AFCFC349D1C +:10108000E7EDB67B427E38AFA4C12FE1DE189BF7B7 +:101090002A8BAD785EC6FBFA802EE1FD309B0FB740 +:1010A000B3F13CFD21413FEAC9BD2C3E70D8EB6352 +:1010B000F24722E8F72CF4DAAE7BC807EB526CBF9C +:1010C00065F9103B6FB37CC087FBA7170E92E855FC +:1010D000B3213E4A5AF13C20897F0B095B7758E8DF +:1010E000F5754F86F8A34676C23930539C6B4DD0C8 +:1010F00003DDDB8CFB6BAA9D0A9E934DF8FA98E00A +:10110000AF9E7E6A07A8C0429ECF277E1762AAF3D1 +:1011100000CA813E4E5C56AC7FE95CEEC47A56153F +:10112000AFBF6A90E5B1C97290E53CF7269CA3BCBD +:1011300068C8C0753179DCE5715D64C4DE7D04E2A8 +:10114000F617D2FDDB619C9D6C9CC538EA6A870A64 +:10115000FB3588C6C64BAC7355CABF0F21ED8393D0 +:10116000E912E71F7CC590F685711CBF8853D79A9A +:1011700076C0B2BE22AF031CE6F9083FD1D839A22F +:101180008707C75EAF3ACCD7AB886782E70EF2F32A +:10119000022ACA483AE09C8A41C2E4EB615B2471AE +:1011A0007D4BDE27EE1E5C5D8FE7AB793C789E427F +:1011B00005A1D7523CE715F31B4D72C0B21E6772F2 +:1011C0007BAFF3B898AEB07E093EC9F4DD3664F566 +:1011D00087BE18B6EE6FB8F55EEB7E8C5B9AF32C8B +:1011E000EF976C2CB2BCAFF55D6BB9FFBCD77ACE74 +:1011F000CF7F0B59CFF959D5542D9D63673DE7E754 +:10120000A63AEB393F0DE6AD92FE9AD67507A58F4B +:10121000AF5FBC5534569C37617FE198E7FEA01F55 +:1012200098645F8BBC3FF1AC21E28D563DE80E57D0 +:10123000B17371067C7BABE8FD51E2D7D0C1E5E725 +:10124000FF887D7BB55EB69E337ABF1DA34BD84128 +:1012500079DF8F38B7AF62B00FE5A0523E9FCF9BCA +:10126000FC7CBE570C8E17C4391729CEB318357FB6 +:101270004FB47F7C1D6FDCFEF176CB49DF3138E760 +:101280002355FF26DAAF91BC2D383790F2A30F1EFD +:10129000E5B2F706D5B79D59C5789E85DDB92866B4 +:1012A0004C8EC73B8979FDC4F66DF3383E31578DBE +:1012B000539EE9BDDDE9637261327CB45331237022 +:1012C000CE5DFC3C0B827640E7F3A97CAE45DA4E5E +:1012D0006296501685179128E28D42676407AC83A9 +:1012E000E6B27DA32DD7D870FE693967EE86FC93F0 +:1012F000D66B34DCB758AB1A585ECF67F35300D6C1 +:10130000A0203FE2A4D964398FC3BBDD037AA2FFDA +:1013100098BD4FD59F8E5CB63E2C3F2F72313CD48A +:10132000A505F35C281FA697AD4744F0DC32916F0A +:101330009B2ACF9602470FDA6D22F0011BBFFB619B +:101340003D2589FEFA5D4CCF02254AC40E79A337AC +:1013500093887D0CBFB2C36B4B1ACFC875F1B8E848 +:10136000C54B781E9D2ECEC7CB63E7E37549E74E8C +:10137000E6F27E1E7039991C143CC5F6A34AE79428 +:10138000D7FB3690443C5BCEE7193DF60EC6994E2E +:101390000F8C8DC3C5FAD32EBE4FB9FA822D988C0F +:1013A000FEDFBB3496176CD893F66F3DA7B7638604 +:1013B000FFB5209583967FB6E1F9D2016FCB34DC7F +:1013C000C7EDFA07C2E25D8CFE7AAEA7016F640733 +:1013D000A1E31788BEF128FC3E875EE6C0F5E7D39F +:1013E000D7507C426568578CE2C58278FF5C7CBE32 +:1013F00009EC3D5A5754CACECD8778CF9201964713 +:10140000BEBC6C1F3F77A51FF725CABF0F525E17E2 +:1014100032615E5EDE18DD81F8C7EFABC2DF0B2103 +:10142000FE6D6CBD50DE3F6920EEEA186272DFF19E +:10143000537F17FEFE8657E046B3B1764AFC7CAF79 +:10144000CA734777C2128C7CBE977C8E90F0CB74A7 +:1014500009570A7FAC81448E69CAE838732A7FEC49 +:101460009F5C1C8F5C43FD313AFEB73958FE6CE03F +:101470003EA50C9CC6B4FB945CB05F2D7C9C5EAB1F +:101480000C615E404B8AFD747FE472FF5A6514F76D +:1014900029751484BCFE31CAE7BA542CAF5F64E7E7 +:1014A00078E84E96D73272E5795C42AE0BDD0E7667 +:1014B000AEA19BF9DB0B2F3D9D37D6FC591E0811C1 +:1014C000E80FB52F49F365F689F6A3EC3C0ABDF5A4 +:1014D0009D9A64FA2CF470BD1EFC890BF61D2ACD72 +:1014E0009134B403133F7F728EFAE9EDCD9F0CF374 +:1014F0001968FFA4FD5F7CA01F3B42D6DF7512D7A1 +:101500009346C889FCF71ECD007FF377E9A1C3603D +:10151000F720DE0DFB053B62CF38D19E4A7C97EB6E +:10152000B9CDCDC653F7B1F7E437A66F65429CE459 +:1015300006371B17BBD3EC81FA67DACDE340DF83B4 +:101540008B92AF43BAB44527A1DC7546F01494EBF7 +:1015500088EDC7F8F12769E64BF0BC54334FC375EB +:101560008FDD7C99D9E91ACF7BC5F17D0CA9C6190D +:10157000162EDE2B4EE4D7A7E3B3DD19EC87F6E990 +:101580003C18322E739CDDF45A07730BFDBEBF323C +:10159000F97A7B0B9727AA67989F25F6B904BCC4F4 +:1015A0004C367F89F274FCCF035D0FEAE120ECD763 +:1015B0003A3DCD46F627D839712E414B8CF985E757 +:1015C000EF51F633BF90E0FD4FEF2CD80FEBBB3758 +:1015D000CFE07ACCF759DC7E8F75DFB368F7CA4C61 +:1015E0006542FAF9CD4C260777673AF0BA2D93D1C8 +:1015F0003B61FDCC61F5083DD535765DEE61ED9F33 +:10160000E1F57FCCEFA91EE6B8991EF6BB2E6F7CE4 +:101610007EB8AAE8D3CB87D007DD6FCD33FD16D7D0 +:101620000761AF289DD7B8518E9A43E99747E79451 +:10163000F2CF408EC57E033543B1C4C303DC7EDEEA +:10164000E416B8C8AC7433FD5D00D731F477919BD4 +:10165000E96F8DDBAABFB56EA6BF8BDD4C7F97B857 +:101660003F85FE9E05FD81FC3C1EC727A7AC768703 +:10167000E2E255D07EBDA6F07DDBE40F4A82FF5149 +:101680003F1022269B2C9F48C40D14BF9AB85FE3DD +:10169000356B7D3D7CDEA276EC4B506F0FD7DF1DA6 +:1016A000BF65FC033E3E93442F051F55C75A2FE4E8 +:1016B000C5A79AE7026EB6BFBDCAC1F6539013B470 +:1016C000FD5996FE6C067E8DF4274C3DBBE4FD096A +:1016D00027ED4F9FB5BE84FEDC0BF58AFE2CBC7453 +:1016E0006A4C7D0C087DF4445598B7035AF279A1F1 +:1016F000DDCDE6CDDF67983BA17E59BEC475179757 +:10170000AF54FB5EBAB445BB80DFE51AB383C4882F +:10171000F6AB09FD2B2F5E2BFA1DB225C6D906921A +:10172000DBC947DD237AF728CADF5EB64F87CAF5E3 +:1017300063D0CE6D933CAB715FD747CC6E9EFDEB13 +:101740007D76F89D94A69C3DF7C3F5A49BE5BDACC2 +:101750003D57E88661E8AF64FB1D5B72D9F9682DDF +:101760008AF59CB4937C7ECCCD147EF5C4CF11C792 +:10177000B392FF4EF31BE54F07B74BFD69459767E3 +:1017800097E67D06EDDF3C83203E6ED9A7E33E035E +:10179000A137B7C1D8B2730D4CC8A3F812BDB7D1E9 +:1017A000FB7E70BA291DA17C42BC73B15C58C77323 +:1017B0000FCCD7983D327F0DE34BEDD0596E875E4D +:1017C000877B6A877EF369ECD0336EA637AD54868B +:1017D000FA400EB508DF8FC3FD11DED7F2E2639643 +:1017E000B89DF0A73A06F61B61C81B2C66FB4F5349 +:1017F000B52BF205C7FB3D82AA7F5EE70427600791 +:10180000C575104715BF5FD701ED1BD09EAD11F810 +:101810007A92A8B80E2FD7D7329DCFFB2E2ECFB9F4 +:101820001BD0BF927FBFAEDA1BD93597D613387164 +:101830003B3B2FE1E2ED64F52CC0272102E76AEA89 +:10184000F40AFBDA05DDAECCAB2CF1409D28DAE2E0 +:1018500092B81DA98E91E8C252C437B87F0BEAF145 +:10186000F17A42B360BECFC273564F1627CF4FD81E +:10187000A58672322727F041FADD0B3AFE93E13D4F +:101880001DFF2999F370FCA766B279C80BF7BFE179 +:10189000E3B84B0DE6C1F3500E5B82A6E5F379F990 +:1018A000E9999F819CEC20EC776F417E13D7ABF7D1 +:1018B00070FBF0B3C9A11268AFE6A72BBAA7D14F4E +:1018C00036B5ADC5738A175E11FBE865CA1F92A7CE +:1018D000E37A60CBC3D679E4071CFFFC3C53ACF73A +:1018E0005D1E8EA0F6EFC64CA48FD9BFB097FDBE8B +:1018F000E7DADCC2EF31F8481DCC29F1736A6B3CA2 +:101900002B6AE0F70ABFFC74C15C38D74AE7F67966 +:10191000B1B74B5F07E30ABFFF94C49E378ED8412F +:101920006ABD2DF354F2FCD42F65B2F993EAF1B2FB +:101930004CA6BFCB81CE7D93CD9B32E7FDFDECA3C2 +:10194000B043218DD91BEA3785C16F5A3DDCDC03DA +:10195000D35413D9530BEB1B542E3700BD5F701EAD +:10196000E8613F9D129E06ED5279BC83CBE3462E83 +:101970005F777279FCF2A7E9D76A687C5E6AFC2916 +:1019800070B8C0DFD4CE7F2B93E1649FFBB399374F +:1019900076F0FA42EECB9C376EF90CDAA778E3FBCF +:1019A000C0C7924C3226BE7D94CBD5639923F8F6FE +:1019B00031F86EA1D37C3C33116F949CF803E4C9D9 +:1019C000C5F14697CAF1869618CF0E50FCC5F3EACA +:1019D000D6DBE6C7F5448F25C7216599237ECACF9C +:1019E000D0AEEC6238A46C846EFF4004F4701AD759 +:1019F000F737983D5EABF7AF07FB7C3E8B7D1FCB87 +:101A000062E3F81CAFEF6DC59534BEF942E608EE0F +:101A10007901DBBB8FB5A7665CC77EB743D815BB22 +:101A200082ED88F87059B6B59D79D9360B4E95DBA5 +:101A3000E98EF7AB1BE5F81EB1EFD7EC81760371A9 +:101A4000BE4613F90AF6C5363F819F1CD7A5C27161 +:101A500009FC7B05FBD3CADA19E15F28B99DC5DF14 +:101A60003564B8F475A02F957CBCC5E5E37771F9B2 +:101A7000F81D978FDFC37737CF60E370DB24EB7EF1 +:101A8000F277F977F7723E89F192E9FF7A362B37D0 +:101A9000C20FDF892712716DA0386B7513C42D5BDF +:101AA00055BFCD375ADEE87F336D09F6581F88E001 +:101AB0003C510FF296C4EEFE25CEAFBFE0B8D43055 +:101AC0007E75A5F0E3EECC66FDBE257F5FCD646834 +:101AD0003F7CC9F27B2D5FD8D8A526FA09FF1BBE33 +:101AE0005F0B5400800000001F8B08000000000006 +:101AF000000BE57D0B6014D5D5F09D9DD9D94DB275 +:101B00009B4CDE1B48C224040D1A708110A304995B +:101B1000BC780688BC4445591E86F04A22624BAB0D +:101B2000FE2C2684A76DB43EB045BB2054AC682380 +:101B3000A64A31D00D08E2B3A1ADA2B58F2008A806 +:101B400008216A5DAB7EFCF79C7B273BB3D905D4AB +:101B5000B65FFBFFF1EB77B977EEDCC7799F73CF08 +:101B60009DBDFEC3E373350721E7E06F44B0AC4A87 +:101B7000B010924C48FD0CF741359F10AFCBE2DE20 +:101B80004A7AF65B1E2F63BF51D93E298EF67BE35E +:101B90002C5136D37E374C11345F1E21233B89E60E +:101BA000A3E37F192F103294104591B0FF1509ACB3 +:101BB0003E4AEE985B1966FEBEFCF9689568CD74E6 +:101BC0009CD10AD17684E977295FE7A8E8F0E38C15 +:101BD0008271E8F331848D13FA7C1C7F3EAA24FCC9 +:101BE000FB97C1F8741DD35DCF94271058CF26AB57 +:101BF00087F6CBB16AB90A6D5F53D2B128DC7B4E50 +:101C0000A9240F9E4751D059071372337DD742073D +:101C100098494B9996EB45CF6085CEEBA1E070D10A +:101C2000E7B45BAFCA01840C726843A0FD8B282D1A +:101C30001FCA7C491B0AE3DC6BD50AA04E889F9023 +:101C400002422610F637C1EEF08BB1F41F85D65351 +:101C50001D76D6762E1BFEFF0CE5F8E58408C42F12 +:101C60009CBB1CEA3E11C6BF5A3DF8B640FB5FADB7 +:101C7000BF77520A792F5D391EC3EB22AE0BE1B359 +:101C8000CBFA90EAB0F4DCA75EEE7278EC0087BF86 +:101C9000447BC6C33AEB5D9B1D2A85F72B9E66BB32 +:101CA0009BB61F8E2308C7BFC66813613FF5BB48AC +:101CB00075336D176384BA6603FCA6280C9F531511 +:101CC00086FF36499B0AFD47D8B56930EE944C8AA9 +:101CD000273AEECCC48EA546B8CFE474309DE3EB32 +:101CE0006699F50B5DE754DEAF4812BC31B026C7EC +:101CF000C163620A8507E9FECBB1D0FA58F8974A6A +:101D0000FB9D54A64D4FA2385B2DBA2DB42EE70A89 +:101D100048CFA1E32EE2EB9D2B572E82F512B54E54 +:101D2000AD7452FA90C3D3C731DEBF3C025D66F199 +:101D30007596C1F330EFA771FE284B6A13097DBF7A +:101D400088F35B68BF490922E36337191D6E9C7AEB +:101D500085D13F5D773DD297C2D69D63AD5C09FBCF +:101D600098A11C2A8FA7CDC5F7244D2349000F0B3E +:101D7000B165219CEC84C249E270A2CB24505F6221 +:101D80006775297A1189A365A6CBB76E20C0AFC14C +:101D9000EA5669FDBD93EF8984D2D9D6FBBB0442D4 +:101DA000E5C5AE4E4212B3601C1946843FCB39A143 +:101DB000E778F4992AE9F351D05C739268364ABF08 +:101DC000D714764E22B1A6F7C9393A9EA3B3DD2BBC +:101DD00000FEECC41B730592F11F735270541C2F4C +:101DE00095CE0BFB913F253ED88FE6F2549081842F +:101DF000C47776FCAC16DB1DEE51B82FE2007E0BEB +:101E0000EE7309F29FBE2ED9D1F1D88F69FFD6CFDC +:101E1000A2DD77C3BE3B477EC0D643BC4EE06BB16C +:101E2000C2EDC983F76CB83E0BFD0FF86C7880AE3D +:101E30003797AF1726C937AC9FF4DCCF7AB1F27968 +:101E4000C0C74C3BD16207A37CD809F5BE56DA81E6 +:101E5000C2B151117C5EDAAFF1FEB9ABB3405EAFF7 +:101E600097DCFD08D039D929503A1F46E75D46E591 +:101E70008E5C481C0AADCB2EB6FFC67B9236C508D9 +:101E8000F05C2233E8F3619DFE2F040A8758575512 +:101E90008542F721F3F7050A38785F501532633031 +:101EA000D06DBB48503EB8101E3AFF689712E1381B +:101EB0005D373C02FA2A9388D74EFB0B2E36EE355F +:101EC000A453247D010F5411D0B284B8B16C143DD9 +:101ED0006F02FDD9658A57BA7EBBC5EE5B2100FE55 +:101EE0002A5F1B8D702F538EE706E5592439049025 +:101EF0003BAEC355FCEE72AF7C6978BEFA30C83792 +:101F00001F32B94CF986CE33259BC99DFDCE8E1963 +:101F100046BE5FAA30B9B494F33D91189FCD95B5F4 +:101F2000B380C7487CBE8CBF9706CA07F89884E781 +:101F3000E39FC7B3F54CB9DBD7D88BC26F4282E0C1 +:101F4000063D5CBE7D96D45B0DF693B9BE3B97AC67 +:101F5000917894C3EE93BE24D03E32EAF7C677C898 +:101F600074187F16979F27F8B8EFC7B375C4703DF4 +:101F70007E44704E0F0717677CB71C74C2F8C4C349 +:101F8000E022C60CEAF4D379486F3E8F55C079DA67 +:101F9000B2997C8C4F30CF13CBE53895FBC9F12833 +:101FA000F77DE9D0EF152B5B5FE8BCE9C179D37110 +:101FB000DE456CDEB120E781FFD5832F829C2FE2C6 +:101FC000743AB6D343C0EE011EB61404E5BDACFAB4 +:101FD000C53ADA5E1441CEF70FCED31FE7A9637876 +:101FE000DC9EA25D06EBA476C1E550B6652B282FDA +:101FF000DFE865219B295FCE4ACBFE11884D7D9C91 +:102000004D7C9F6D598DAED9145F722771DB90CED8 +:10201000AB51EE1571F952BFCB43E0B9B7179599A3 +:1020200086F7E5CED976E2C0ADFCCF39BD3FF051A1 +:1020300067769C270C5EF472DD72268A88BA18DFF8 +:102040005BC2DF0BEDE778606F0C8CBF16FA5F4A5E +:10205000F996EB1BBA615CDF58CE3BF59D9B633A6A +:1020600068BF5DB9734CEBC1E7948F1A731F8B0186 +:102070007BA93583EA0190532F8B28271B9D0C8F5A +:102080008D6955C4638073A9CB2F1E8771BE9A4397 +:10209000A651FC15B93CE4126770DD45B9555E21C7 +:1020A00009DB9F8BA2E3CC89BF04E946CEF3909174 +:1020B0000E804B33A9A2FB9715BFE8A6656927F1EF +:1020C0008FC887FE54CE0B6C3CD5691C8734C3384F +:1020D000B29BD203BCD7E9C7F5EC3A797E383AF225 +:1020E0002C26F9ADF325B5EB6A802ECA946BCBE2B2 +:1020F000E9F80BB6670D16E9F8235D6DF2EC3C9438 +:10210000DBB5401F9B92B53AA49FFF257B6E3AF149 +:102110005901EFA332991E985023F83653F83486AC +:10212000D8098D9C4E2F0DDA37AB61FDA450B71343 +:10213000B435F1E7B783EF893FBF1DFC93F8F07624 +:10214000F0FDF1CC0E7E209ED9C10F4249EDE08713 +:10215000E2BF831D3C5C21BA1DEA43F8C7B37AFD98 +:102160009F983D1ABAFEF9F1CC0E5B4DF7DA0E746A +:1021700029F92446E78C4FAFE67C3AF624E597BC74 +:102180009EF4DF4AE9DF4BE9AF8BDA4D6256647AA1 +:10219000F25F245F163FC0F8BEDEB517F9EEB79CBC +:1021A0003F5BF9FCADB96205E0F315222AA2D073BA +:1021B000BCC60C8F0BE47A28FF695F99E9B9D4E5B6 +:1021C0005B3F18F8E6E01C372C2B941F655A560D20 +:1021D00008AEFBF79C0FBBE51311A49117C1873024 +:1021E0008E6700D819F112F05F3D61F37A0F8AA86B +:1021F0002722F111A59B77E30DF31503B00DEBA793 +:1022000074F367C02FE5B3BF7C177AF93EA70FEAD6 +:10221000871C87F192787D5604FFE2E3F86EBBE0FD +:10222000639C7706D343CE7895BD479264D02F9AAE +:10223000989109F2858E7B16C6DD1377FE710341F6 +:10224000BD1340BA5DC6C67D1E8CECE49EE38E4A8B +:10225000A0F6479871EC5C8EDF10C15F50B85D430B +:10226000F2BAED136B02FAED6C7D4F246BB684E489 +:1022700020DF1471BBE525C1AC9753B93E57B83F79 +:102280002726B0FE646EF7B80A8CA3C353B7036663 +:1022900071F9A08F93C4F92F2E4161EBAA66EF1359 +:1022A0005E1FC9FD270A97DEB82E3B7B7E21BFE863 +:1022B0002E85C52D2671BBAA1336C8F41BC27574B2 +:1022C00024BF2B68F7F507B81037EB9FC6E143DB57 +:1022D000F3B0BD82ADE352450D1B3F88841F1DFE48 +:1022E00052025F4F2E1B9F78BBE17625EC53A797D8 +:1022F0004870DB13C7E056A0C3AD818F13220FD601 +:1023000049CD7625CC3E47727AD5EB31B966F910C6 +:10231000299E9215D413E3111FF96CDD91E22BFD78 +:10232000F87E2FE378A0EF4D41F839D87AEF52BA12 +:10233000DBAFC3F67436DECC60FB0D388F8BF58FC8 +:10234000E4F7CFE4EB9A9AD08DA759385E127B2F31 +:10235000349EA09737F2F54D0FAEAF1ADFCB61EF89 +:102360004941BC2FC4F6D1ACFDFAF44D65C92AE051 +:102370008D8E037AC2C5F4C10DD56DA2D1DEB93EF2 +:1023800042FC4DE2F35605D7FB7DDCA7C6F67F2263 +:10239000AEBBFD87386F119B3792FC3811C7C6BBA7 +:1023A0009DEFE31AF08BE918F101922B2581D714E8 +:1023B000ED1E45BBA406343FE88F924F6515E474CB +:1023C000B9E8F00A541E4BAA1DFDE4288968E0D73D +:1023D000B67DF63D57471ED6FDA0D7574515DBC144 +:1023E000EF5C9D25B9411F16DF2B31FFFA9405E5FF +:1023F000FD4871118EB357D1EDDC5B4D7EB4AAA8B8 +:102400001551B00EBB4854E6FF578CA7CF477079E3 +:10241000BDD79E6881F18665B078C108B50AFD75A3 +:10242000F215F3A335FA1F93DF1AEA6599BF27A5C2 +:10243000D711014BB3BF2D93F567C581A817D08E77 +:102440001AD669F6BF6575E409185F2686F7E8BCF9 +:10245000DB129C49684FE5907EE728FFD872056241 +:10246000BB02FC6CCF76C0CF18B54A29A1FBB1A541 +:102470007BEC208773ACFEDE104F684897DD5E6012 +:10248000C3FBCBEC59E06F3551FF1CE1A0255C3B51 +:102490002088275B9146800E294E90BFBA4B072BB0 +:1024A000854486C7B7136C580EE275FD7928DEB3F4 +:1024B00013A319FF13BBF7582EC80981C4513A5C06 +:1024C0004C3A32811EC534C6E735968E14A89F213A +:1024D0009D2949B4AC6F924687F37FD6F1B8D41AE0 +:1024E0004B787BE95EEB9857010E12C40DAEC0B875 +:1024F00080C7D637183FD0ED553D8E10C96E6D148C +:102500002BDF04BA1614FF17D0BFA7FDEB65FB4EF7 +:1025100067725A2FF5758C4F64FC6E4BB463BF3DE8 +:10252000779692D92AE2E908C7D3C12B012A5973B9 +:1025300015C0D3CB590FE6405CCA9E757F12F0E7F9 +:1025400068C2ECD372FA8E8B962B1D9E9309067B84 +:10255000634CCE2CB49B8A32EBD09E5A15C12FBD52 +:1025600085AF43E27432C8E1390BFBDA7AFF123BE4 +:10257000BC2F2995D150EE094CC292DABD9FC0F311 +:1025800055E9AC7E213CBCC4F939D2FA47815E8062 +:10259000784D7AF73E84C4647CEE950707F761585E +:1025A0009F3531CCFA3EE5FA485F9794C3E932D7BC +:1025B0004C77457CBFA989BABF78D174F7D6C5D00E +:1025C0005DE87EC7642D1DDD9F04D7AFEF57DF3F69 +:1025D000DD6F1FD86FB9C4F6BF55F168300485B3FD +:1025E0000AFBECB12F7B78BDEF48B47CD3FD3C985F +:1025F000D0F7E2F7F30DC69D96F80DE0B47FB8E68C +:102600000279D2904CE993E2A94160A5DEFF0B6EFE +:10261000A7FDFC9BE32BA5DF37D85FB14B7811F406 +:10262000E108CF9152D86E59D120503BC08F930111 +:102630000F2579F74AB369BDF1CE39283FF70FAFBF +:10264000C375AF729AD7AB9742228FE3676AC87F90 +:102650000D9CFFCA09F323F57E4F72F918CA1FA11A +:10266000E385F2F54A873617D62524323D1BF4FF61 +:10267000DA45A3FF57C2F5D770FB6DA6F8C770EE19 +:10268000FFADFA34DBE1A51BEDA27AED9FE2FF7D01 +:10269000419F809F945E6237FA7F0DF6526C5F9582 +:1026A000A18DBE2209F4B1E8BE9B20FCD01FF40A24 +:1026B000A2B2358C3FB82A43F68FA0CF6D0AF90538 +:1026C000ACAF94EA4B88BFD8148D5C32A0A75FB83A +:1026D000D75E4A206ED2A590E7C01FBBD07E1E48B1 +:1026E000BCC464474AE017F2F1D12F54EA4807C648 +:1026F0007B4A09D835D0AEA25DA5118F13F408F539 +:102700000B0DF2A9CB7E1BF27BE87C546E3D027C64 +:10271000DEA0303E0EF507BB389FEB7236941ECA22 +:102720005D8C6EA2E8D2AD4C6EFC2271684FBAF897 +:10273000E6F2696E19B800D79115FBC1559B1AE8EE +:1027400094C0E59993C8F8A9D2F14C033CD7C70FC0 +:10275000C50FDDB906F174B06758FC86DA6BD48E0C +:10276000B2527B6DAD109C7F0DA78348F888A4AF53 +:10277000F775CBB5D038D16DE6F317C54B920A5833 +:102780005C9F8481BFC8EDA4D5945FE0FC668DD5C5 +:10279000ED02BFA2BE5FD1DB1EA0BF7E32B377A425 +:1027A00026D7B561FC90B511E2DAEF2526203CA3CF +:1027B000732C26FB8C7A0626FB31D2BE095F9795D7 +:1027C000EF4B0078E61AE119B2EF3205F70D663DDE +:1027D0008C1B6B71133FE58BD84CE24681156BC1A6 +:1027E00038ACCEE70AE7735D1E3814F6DEB0A4BE3F +:1027F000EC7C4F74748A145FEB92A83D4DC7A9D747 +:10280000F6A25ED5DF8FE3FB770C67F14687D3AF87 +:102810002861E4DD8F2F80DF264D8A2FA3EBFBB1EB +:10282000C2EC6F69B8A5D287F12816AF5538ECC451 +:10283000E27C3BD8ED05E0780F85F5EC508C712BF0 +:1028400091AF27C649D7731E39B98AF3B75EB7A9C6 +:102850001D65B07E294B53E20DEB1F94A4EB9576DA +:10286000E4EF48E3DDC3E5BC2DDD4DAAE8BC768787 +:10287000DB0FE75A36ADAA00FC05BBEA26730CED68 +:1028800076AD6088CD80F7A67EF2F4707CB92089A1 +:10289000C97FA7A455C27B4E4522704EE6E4F6726E +:1028A000A47123ADE342F38D8A349F1ADEAE884DC6 +:1028B00062FC270DDF5109729A0C9048BF307A42B2 +:1028C000E0FD62E50E15F88AD2A327DC7867126571 +:1028D0000EEF7F117FE8767771CBC16CBADE7A8715 +:1028E000E416407E159E6C570D7281EAF509490683 +:1028F0007B59747850BE892A3B771F6D63FEF6FEC4 +:10290000E1E673B2299C5E5EE56524B97079928533 +:10291000DB4DFF9A7D7E53FC0D4A2226B834015CC4 +:1029200008F0D77D0DF561E42585CF926F039F6593 +:102930009CBE1EB9007C32FECDF0B9105F07F9CC09 +:102940004B8E86916FF54E396D8E89FFA91D12A1B0 +:102950005F95A13D121FEAF4310AF002FCD0A49960 +:10296000E2027292B79DF995B79BF59CB8C8CDE588 +:1029700033F9AA808539E12FDE41FC31B1C1F1E59F +:1029800032733CE1C9241E17882251009F2EF72480 +:1029900001F214A22C3306410834853409A02752D1 +:1029A000609C81D44FE6F23C540F266BCC4FEE4D29 +:1029B000EA04A657D2717D497C1DA17A308DFA3583 +:1029C000108F0154833FDD5B82182F3CD5F01C5CD7 +:1029D000F05AD05F76119F00E3A7930E2CFB402A9C +:1029E000021D3F8BB40B39147FF796570D02F9FD8A +:1029F00062C83E2E648FEAA56E7F2CFB37C1FB9D1B +:102A0000FF5E78AF2835C0BBEB3BC27B0A973BA18A +:102A1000F1BC31DDF1BCA617310EF715B33FDABEBC +:102A20009631BED790C5E279E562C506B0E7C7A882 +:102A30003201FD26E576AC833C27DDEE049704E207 +:102A40005C7ADCCFDE6F4EE560782E9D4438E1D9AC +:102A5000908AF2CC998CF286D91123F8FAC7A8553E +:102A6000F62CD5E83F3599CECF644E07635C25E858 +:102A70003F357C757EBBE362FDA43DD2030EB06B97 +:102A800074FFA83E670EDA3DA1EFF9A5A63F435CAF +:102A9000D29F6353575078BCCCE5D5CBFD1E928CAA +:102AA000E7BFA17E906E578DE0EB2FCD997510FC9E +:102AB000AE31CA6C06130E0799CFD3E0EAC273F0A9 +:102AC000DF7E65417FAB8BFB5B63B89F05FE4E9558 +:102AD000B3E73E87279BCFD574FF694CB7FFD4245B +:102AE00019FDA73111FCA7D1B6CE57AF80BC9057C6 +:102AF00045CC0B8904DF50BF2954FF8C4E667A67A2 +:102B000076323F270A81A71EEF0B3D976ED4F94F0F +:102B1000F20A46FE0F9D5FDE3B06CF05896288C73D +:102B20006607E38982E625CB0607E38761E2863301 +:102B3000920D71435D8FE9746CA37DED78CE1C3EE0 +:102B40009ED89A75A02FF30B5F4C04FC972B2C6E2C +:102B5000A4AF8FFA85F3930D7E615127D3DBB6FFC7 +:102B600053D7B182C297241037F30FEA547B3EBA91 +:102B700013896B591C1DF3B4C638048C874BFE288F +:102B8000AC979D72FBA268DDB6F76109FC84524ADE +:102B90003F5142907EC670FFA221E7E83AA0AFAE57 +:102BA0005392FB7C7E7799430CA1D3E8601DE55BD3 +:102BB00082A9BE5AF2AC647CDB2B086F11F2C1B261 +:102BC0004DF9675B25AD11F63DCAAEAD4AFECFC4E7 +:102BD000FBCF605D8272E05BE13D380FD30760B3ED +:102BE0009134C37C0EDA7815CCA322FD77C7A59764 +:102BF000123C8FD90638033FF763E28338CB0BD6FC +:102C00009744D0478D7C9CAB49932AF765EB857E32 +:102C10004F6C756D5A0BF238390BC77BC1E1590FF8 +:102C200036E4C12DD22088DBD4ABCFDA217F76EF1A +:102C3000D6C6F40E03FF1D7CC2D3279C7FA897F451 +:102C40002FCE5288FB8A65A5265A5CD82E42BD87B6 +:102C50007DB6A54581799ED86A0F6B4775713EBFD9 +:102C60007A0BB36B47E75ADC1402A48878A50438C2 +:102C70008F7113B79F36C40CD8D15E02BA284B446B +:102C80003F9FD6F7C5D27ACC500DFD83FE0376E088 +:102C9000FBFD3F2E71B33C4AAF6330ADAFCB2D1976 +:102CA000BA16FA477BDE04FC513DD324A13E6D8E5B +:102CB000813C8098019392A98D4B620452192E0E8B +:102CC000F84132B3F39EB0EA7095300F72EF5619A7 +:102CD000F9EB609A88FC46E1B608EA7F4F8B2194B5 +:102CE000124999E62D03389693E67AF0A7CAD46B79 +:102CF0005F8C25DF027EF93B14E0FF756087875902 +:102D00005F1B5F1F0A114A3F07B634DC40C2E45123 +:102D1000EB74F88B18ED1380C31A7EAE4B5C939066 +:102D20007E22E3FB6EA41F67B3BF3E9AC2F1EAEDB9 +:102D30004DBD8CE3EF4F564DF1371DDF90FF4CAE8C +:102D400080FC5B0FE6D3D69FB420FC5EC9137C02E7 +:102D500085CF815C91DA6C745539765F3F5A5FCFCD +:102D6000E9B862FBA1865E00A494245CEF2BB98FC6 +:102D7000D9597EEBC5C7AF87503E5800E7C9141F2D +:102D8000A394689F4AF1B51086C887FC1CBBCF4F3F +:102D9000E76B73B697C6D1295E4816DC9B815E72DD +:102DA0008902F2035D100B439442EB2032909E9215 +:102DB00008E673AD2BC8DB0CF2766DBADA0CF98637 +:102DC000BB07D831DF2C349F78B750F7623CE499C9 +:102DD000C40B28AF0FE4FE1ECFE90EA4DB08D02BF6 +:102DE00026FCD2E70D098C4F63F2CDF6677E4A16BA +:102DF000F7B389D756105C574C8E5D8BA284F45282 +:102E00003C7BFF608EE0037A3BA872F940F7BB156C +:102E10001201A91D346D4064BCBEDC6F94AADBC5F1 +:102E200082BE4F4BCF7DBC20F85667C33EFAD37DA0 +:102E3000D0BA3357C0F99DCADA5B099685F3E01C16 +:102E40003374FD35298C2E654A76B920DF9A578F69 +:102E500031E6C7C885B74E70C4621E13DA95A9B9AA +:102E600002D35F27D9796E8FFC6C857864137EA8B6 +:102E7000D591121C2FE6D3E7BE0FF9BFE30A057FF9 +:102E800014AC87E737D3FF6B03FD22E7CC62F9D799 +:102E9000B99B703F630BAD6E38CB19EBF03595D015 +:102EA000FACB1F4818CF1E97330AF3AB43E75FAB4B +:102EB00010FF680ADF97F3248477D4258FE1386FF9 +:102EC000E45950DE8C837C6CC85F36E655A33E34F3 +:102ED000E7738F13FFAC1543B39BF12B91BCBD403F +:102EE000BE4F7099E1E73C693E2FAEC8B799EAE35F +:102EF000F2E49078A597C58733185DBCD45FF06D78 +:102F0000CE0AD2D9D893093EA033F8130B4C7034B3 +:102F1000ED33A653D6007E07FB3FFE1338278951B9 +:102F200057DD8AE7E01CFE3A9DC470BC3BD39FFF8F +:102F30003EE8291DFEA17470F1F8BFB6B218F09FEB +:102F4000AF9FDF87E03F04DF1883D4F7D1B727DED8 +:102F500071FEAC9EF8D6E9A0C7BEEF69599D4DF150 +:102F6000FA8A933E003C6F927D770B413C5D10AF37 +:102F700039C548376B952607C8FDA84B8E3AC0DF88 +:102F8000D0E98288ADF946BFE39F85EF92F50273E1 +:102F900026DD820FE27ABF83475705E77936A53BE6 +:102FA0009FE8D914D013952C8FA35E1BCCEE5DE562 +:102FB000337DDA433EA4B07B1D6DD697D2CF97A761 +:102FC0005AE1F010381FAB877C3BBA3F79FD2CB833 +:102FD000D140E429B3505E92F5028BCB17FD01E599 +:102FE000FB5C976FA510663EB464709D2A937B4589 +:102FF00089D89F4CD7F3922A5FC5F54F61F58B5D59 +:10300000D7EBFFA4751DA0B4420CFEE7446E37EB6E +:1030100076F70407CB3B9C5024223EDED822F830C2 +:103020003F92F6F3523A59C0C97622B703BB0A9FC2 +:103030006D1CA4823DA899EC4EA1A80DEDBEB8422E +:10304000B33F18AF459BF09F383AC1544FAEEC6583 +:10305000EA9F3A3DDB1C57F05C667ADEBB7AB0A98A +:103060009E5177B5A97F9F6525A67A9677ACA97FF3 +:10307000DFD5934CF57E4D3798FA5FBA61B6E979A2 +:103080007FDF02D3F3CBB72D31D50734FFD0D4FF88 +:103090008A9D779B9E0FF2AF353D1F72F03E537DA8 +:1030A00068FB4F4DFDAF7C7BB3E9F9551DBF343D47 +:1030B0001F767287A93EBC7397A9FF88C05E53BD77 +:1030C00098BC6AEA5F6AFF83A95EAEBC6BEA3FCA3E +:1030D00075D4F47C8CFA91E9B94E07E3723F31B5AF +:1030E0008F777F19724FA712E59B0CF180BEF0A875 +:1030F00009CB68D2CCCE75483B962F1578DCA94019 +:103100009F8F7A1B2121A9DEDBF957389A7EA3B065 +:103110006F1CB39F3462949F7A7E2AF55BBC5194F6 +:10312000146203946E8750BA0B08582A012A591367 +:1031300021DE138565422011DB1303F15826057A41 +:10314000637B72200DCB94405F2C53035958BA0215 +:1031500097639916E88F65AFC0107CAF77601096C3 +:10316000E98161D89E11B80ACBCC4029B6F7091481 +:1031700063A906C6619915188365766032F6EB1B64 +:10318000B816CB9CC08DD8DE2F703D969704E660B4 +:103190007969601696B9818558F60FCCC7F2B2C02E +:1031A0006DF8DEE5815BB1CC0BDC81ED03023FC045 +:1031B0007260A01ECB2B022BB07407D661BF418179 +:1031C00035580E0EFC04DB8704EEC5323FF0336C3D +:1031D0001F1A7818CB82C063585E19D8846561E0E5 +:1031E000492CAF0A3C81E5D58167F1BD618167B0AB +:1031F0002C0ABC80EDC303BFC1F29AC03E6C1F1104 +:1032000068C3520BBC8AEDC58197B12C09FC01DB68 +:103210004B0387B02C0BBC8BEDE58177B01C1938C4 +:103220008AE5A8C0112C47073EC2724CE0032CC7A8 +:10323000063EC1F7C605CE625911F812DBC707BEBC +:10324000C0B25BDE45CC57F658D09FE57E6A647FFE +:10325000C18B72D2CAEFC5416E35E6FFD709BE51A8 +:10326000943452933A305E682DB461BCF026D26932 +:1032700065E7D0ED4ED04B6D579D488738DA1BC9B6 +:10328000FE0C63BE8395C701CAC553188F9A90B4CC +:103290003719F4E94DB419F28C88760EF32027F033 +:1032A0003CC89B24EA60D1A51E8211AEC27E7E1B63 +:1032B000ADCFA820DA60DABFF12A1BDE2F6A1C4CE2 +:1032C000FD205ADE93C5F2657DA94C5F3ECCCBC78D +:1032D00053D9F9CB5F0B589EEB8C5BFB317E2A4BAD +:1032E000BC80DFC4E0307420CF8F757466627EECE2 +:1032F00045BEF7A714FE1EEFBF3CB5F2C954BA0E87 +:103300006F09C9AD7304FBD1F6A723B43F03F220C4 +:10331000B47DAF85E1C3FB96C8FD84CAB849E7F127 +:1033200013DE58DE7ED98BFD82F5DF45F043095967 +:10333000C1CE0FF77E50711DD587130B4537951CF5 +:10334000E4CFCB770E3FD68FCD0B71506F8988F1CC +:103350008B194587F627D2FA8CA5F19877DFBDAE99 +:10336000122B3E9FE07AEBB217E9D66FAAFBCDF0A5 +:1033700063A6789307EDAEDB388D12CDFA8F0EFD84 +:1033800039D22B8BFBDE0693AB20FFAC386EBB66CD +:10339000F59D2F3F866836A299E89EC16B1DAC1F34 +:1033A0007C7F62B7C0BCB1BC0F852BEA7D6FACECF3 +:1033B000AB17C07957E380EE62F23AC9F9E2CB006D +:1033C0004F092E4E920E07D83191E029B8581C347F +:1033D000AE487379297E1ABE16316EBC2FBE4001ED +:1033E000FAFF91232715F843E2FD1ADADEC1F856F9 +:1033F0005C7E27F13A58FC5EB5C139BA1DCB95CB3E +:10340000DD58362C2FC4726DFA7D76889788C9985E +:10341000094CA232E6623C489FDF1A3FDB5EEC2695 +:10342000E4CB87BE1E07212411E20CD444F89AD6BF +:1034300057509FE2642AA3CF375CC71CC00F2753A5 +:103440005596876F61E7C631F97E0DE28D316EA525 +:10345000445283EDF89784ED9BC11F798374AC9F30 +:103460000C70D4D87D8C7A7EDFB4BEB81F87ABFEDB +:103470005E08DE43F02CCA6E3CB716A369FFBCC8D9 +:103480007875B9585E02D09744E9EB6FB06EB037EB +:10349000B5180B8CA7E3B74BEAC47CAA7A217CDE73 +:1034A00065B68BC987064553CE778E4214E91F4611 +:1034B00079EAC8DB1942CF0E94AF58877C2E2EAF25 +:1034C00076A46AB92E3A7EF3355C0EA427A01CA020 +:1034D000EDF75D4DD7BBD3C2FC146F828CFC4281EB +:1034E0001087792F76356ED279F220562D5734C950 +:1034F0000AE7036A1CC06B15CFD7831BCA4639F095 +:10350000AFEA1794173E961719D27FA785F3557423 +:1035100014EE4BE4F0D0DF9BEE62F2F8C1ACCAF1DE +:103520002E8C8FA8E92057697D22C08BEE3F1DF8B5 +:103530008AD6AFC5BAD25D9F8CFD5DAC3F26D25C0A +:10354000841CA6EFDD80EF49DDE3CCC0BAA37BDEAF +:103550009B719EA4EEBA079FA7B3FE173B8F5E76C2 +:10356000EFFFF74C4E7E2A697109143E95CBE65465 +:103570009651BD3D79D97C2CDF5BDEAE815C3D4E42 +:10358000E54903856B6571DF24F073268FEFEB50FF +:103590000DF43A8FC735F7AEB68E067D57B246ACFE +:1035A000DC82FCB4C214B7FBBECBCAE34D6C1D5524 +:1035B00094C7EFA424376FC3A1CB1A0CF6E86CE2D2 +:1035C0009681DEE7ACB606E99A18F853616D3B2D9B +:1035D0009E1F5D0FFB582BF2F30ACEAFF184FBF375 +:1035E0006A4AE579F40E596D239E30F2B8277C08BB +:1035F000F907E5834F1D391897A5969A3DDCB83A2F +:103600009C22CD372F42FC5787930E6FBDFDE8FA01 +:10361000210AB3AB7D2638CEB96728C62BE7F178EF +:103620003D89B773FE64FDAAE83C3BE03D49538108 +:10363000DEA11E4EBEE8F356D17FDD39381C7C3941 +:103640001CD65A991E0F81EFF10DFD62410F85E2E4 +:10365000EF62E15C6B23789FA273AB93C59192A656 +:10366000E3F8D57C7E923403D753CDE77B714F8C42 +:10367000DF42FB976C756E063FF84C89F7C14A90A4 +:103680004F9BAD98CF76F79E756FFD0CEE7D6CB2BB +:10369000E299C9FC98070AE0FCF42F5C8E5205D031 +:1036A00006DF4FF010FD4F1360FC79848D7F463F9D +:1036B000FFD81A87F03C59B6A571182D3B762FAE6E +:1036C00080B8CB893DE30F80DF3C3F9A4878979DD7 +:1036D0002832F29FD77ACC6C1F48C1BAD8B33E0FBC +:1036E000EA86F8D17C9FF59891CE176E33D78DF08E +:1036F000B218E1A59699E1A5969BE025FCD6E917BD +:103700000DF02A8BEA97047A7DBF4BC5F1AAA35628 +:10371000A6007CAA77AFC172E1B628EF31C3BC8B9B +:103720009BE34DF5DA9D695EA35EE93AF8582CD02B +:10373000E11297E83D46F5DCA9E55A3DD831A79757 +:103740008FC652C7FFE2E62CAFC3348EB9DED52454 +:103750008C66F2598D9B721E7E5DE292719E0FB750 +:10376000317FF3C3E5762FCC736AB9E265F3BABC57 +:10377000CC8E62F05AB42CC67B6C48707D91C6FD2D +:1037800067AF8F901672D44EF0CECEB9F3E8ED88C5 +:103790007249FA5446FDD16AFD3BD08D9DFEEF1C67 +:1037A000C65125ACEBE3D6368B5EC8272664BB69D1 +:1037B0003EFA9E7ADCC06F91F582F93B13FD21162B +:1037C00086F2999D8378E01C848E774672AC8638A9 +:1037D000827E0E520B13D1BE8BED1DB287367DDC7F +:1037E000D2F7BCF7CC299EB2402F57DB9B6450B672 +:1037F000D5CDFDCB809F3E6EA94F01F9B150ECFABB +:103800005EB8FB5EA5699C6F7DD64EB3BFE8D3D78B +:10381000992599F88C38BAF74DEBA722E40B8F4F16 +:1038200063F66CCDF6432387D1F5D7EC3C2B63DEF2 +:103830005A9A677C9A61FF023F075AB0ED888CF66E +:10384000A7D57BC91DE7B3EF7BACD3E132E51D7A89 +:10385000493BF0E7EC42A233EC75EF5279F3C1AB90 +:103860005602E787E42BDA8B3ECFE44FE792CA5843 +:1038700080D7EC9685287F3E786EDC01967FD45405 +:1038800000F4F131B160DEDCC7E4F7B1430CF05B6A +:103890009626EB7144BB31BF852E300DF3D3AB1BA5 +:1038A000DBE1DE988D485E2E9704F6BD1A9F80F20C +:1038B000AC9AB57B897D05EE633593475EFA1FD4DC +:1038C0006F6932CBA7791BCCF52A322905F2BBAB45 +:1038D000EEB7420611996F947F147E33D3581EFBC6 +:1038E0003C52D708F6DC2332C5135DFF6C8548BD1A +:1038F000A91E5AFCFC2305B3687D791A3BDFF990B9 +:10390000FB19F3C13CA5CF172CF3C95A5ECFFD1D9F +:103910006D19326D18C1F198DE5AA0DBAD448538BF +:103920007E6FF85776E4FDF76E11F1DCA937B41B12 +:10393000E4F39CD5E6FD5D68FFA1FB25E43EDCC712 +:10394000826DD7A2DFA6EF47C797BE1FEBB6F0F791 +:103950007C1FE4F4DA7DBECAE1A7FBDD4FA631FB94 +:103960005DAF3787D47F1D52D7E9DBCAF99BD2FD03 +:103970009369C9C0CF9D23199D74C8C6F35039D827 +:10398000AFF97CFD6C9C5F68BF5F9FAF5F5470BCFC +:103990005DE1FA2D7EFEA9E7C01F5DF0AB0762E195 +:1039A00030E803A92905F284166D5D190B703A29D8 +:1039B0007963816E3EF089A3C3C1ABB31B5E9A43AA +:1039C000A078AFD1E9BF68C504D0EF7FDF6A55C0EA +:1039D0002FACDD66F3C3F7976A5AE6E3790DAD1FA6 +:1039E00061F55578AFB276A7F53D235E173CFE40F2 +:1039F0000AE677106F6F769EEEEF0D9F0EAAD9F252 +:103A0000FE48F0936B4927D273E87B307F2001E5B5 +:103A1000F52C39AEE7733D6E5ACB9A486DCBBAB3ED +:103A20001037AD6D197302F8BE9648EF19E9A91A5F +:103A3000689AFA2B47D278DEDD95E44A902F3A3C1B +:103A4000882F19E573FD130F0D3C42D7736ACBAB7A +:103A5000B182D15FE5E7ED5DCD73FE96781EFD7016 +:103A60009AD2A9313F5E97BBEA4EBA80545A6D652F +:103A7000E522AB3F761885EBA24D56BC1FBAE8A9EC +:103A8000C77EF153C8237AC786E71F0B9FDAFFD69C +:103A9000D5B4BEF0196B5205DB8603CE8375BCD45A +:103AA000D2FFC1F9848E8705CFEE9721FF0BDAC1D3 +:103AB0003FD0F1B1F09936990CE809BFD2E636B99A +:103AC000C311062FCD4746E23DA3273E9701EF1FC6 +:103AD000EC11486A56CFF7AB37ED473B06E08478E8 +:103AE000E478EAC65B0F7CF927ECCAC77E0AC8ED0A +:103AF0000BE16B1FE8D564A4EBA777D17554FFC920 +:103B0000E60638543F7D5B2CECE78454C7E8FB9114 +:103B1000952990E7566DF5A62858B2F6EA476F4703 +:103B2000BA9B77E8F61476CF414BE3F91D69B0CF25 +:103B30005B364EC57D56110FD25FF5236225E4C179 +:103B40007C2691D1CF84E18FEA5E4CAF9ED84C9118 +:103B50004BF77902E46552D0DFD1EF35DFDE1D0788 +:103B600061E7909FF173C86B7A594CFAA59B6EB7C9 +:103B7000AC42B9FA6186960AE793140EBA1C45F96D +:103B80002A1E2A4F657862F218DFA3F4570AEDD097 +:103B9000BFDD8AE7C286F7B8FC64F32FE5F3D3757F +:103BA00047833D722285E98DD0FDDDCFF747E0C226 +:103BB0008681CE0C7CCEF87ECB1AC6E73ADFFBAE10 +:103BC0001D0DCF3FFD23E323780FF4115D973F15C3 +:103BD0009FB74D11502ED8883F1C7F6FB172FE36B3 +:103BE0003FA71209ED399D4EE8FA25F81E59905E5F +:103BF000E83C098807B457AAEEA7EF1BECEC5A98EB +:103C000017FBC9C1F6AC201FCFE3F2604E2FB33CC7 +:103C1000201B932F2A2EB0C8EAFBC54F817F29BFF6 +:103C20007A55E05F2BDEBBF968FBBEB76EA074FE71 +:103C300051B3CEB766791ACAB7D53B6EC7F86028BC +:103C4000DF7E945E47C2F26D3ABF3717CAB7E91DEF +:103C5000FF5679AAC36F5D08FCA87CFCF92E3532AB +:103C60001C43E5E3A5BDD4B0F291FEFD9114F4A48C +:103C7000439DFE74BA5BF0E4E23E2087BAE953A7A5 +:103C8000BF6EFAD4E92F74BF66F8853E9F02C94E15 +:103C900006FBC17A37F13A29BE3B778BF8BDA433D6 +:103CA0006A672CC47F5646919960879F51783D9EE4 +:103CB000D53B93E54690137A7B67148B579EA9EC0E +:103CC0008C8D37D8D7475AC55888EF76F8C2DFE7CA +:103CD000C08C443A7F4784FB1E7A3CE24C74EC4033 +:103CE0009C2F3AD307F82A171D99CBF2C10F13F175 +:103CF0003B3E73575C170BF921675AFB4E9C4EDB1A +:103D00006F79997FC6CFAB496914CE7338DE4F12F5 +:103D1000EF8345747F735A99FD3C777D783AD1CF14 +:103D2000CDAB1C4B659047D46E0DD20781E7EC3BC1 +:103D30000BD51B43DA5BC7213D2D08A1270FF78F59 +:103D4000DE047A82B8EB203288FB2716633E48B93E +:103D5000983711BECB79E6A08879EB5DAD226984F6 +:103D60007D6E177C04F8DB9B8C745943E58731FE2C +:103D70007B0AE8EE3CF7E84EFDFA2F0577D02E8B54 +:103D80009E7B77E0CF6879EAB9772E7901EACF1F79 +:103D9000CE7C9784F1B3F67C7133C8FF337B6C041F +:103DA000E32A7B5ECABC03EABB6C987774E66E9B21 +:103DB00086F6F41E27E6D19DC960F1D4FADD9F0F87 +:103DC000C47C74D2C0E8AB37BBB7D5D5FAE55FF198 +:103DD0007E6D2BDD15E8DB3D31688FD7EE8AF281F1 +:103DE000937A66F7E705C6F38BEFBA9F1A99C5EF8A +:103DF000CF38C974887B9D896771EBDA17AE7A0C6E +:103E0000F2E117B7B4C9706FA7F4B75F0F04797305 +:103E10006607B3234E5B3B1E256E42627ADF768FC8 +:103E200095C2F934D87694571EEFDD321ECE377A1C +:103E3000C285C1E10C8503EC8BC2A51AE464247829 +:103E400064FFC7C2E3ECCD30FFA2D62BF1FC210802 +:103E5000174163ED4E9F5DC0FDB3F63D9F0F0479A2 +:103E6000FC51F30AD4EF17DA77F1FF73FB16FC1756 +:103E7000B36FCF7FECBE19FD1F07FD94DC930F7A63 +:103E8000D2F9F3DFC3FAD34E37AEF722F9DFDB9B6B +:103E9000C51DFEF3F6FF2DF1BE43C0FC950BE1FD01 +:103EA000E7FFB5787F99E3DDA9409EC499DD5F67A0 +:103EB00012C3FE2FB4EF3DFFA5FBD6EDA0764B9DC0 +:103EC000924FD7F70E699A9A45CBDF699F2481DB21 +:103ED0006A8B704E73BA37F32B6C02CBFB265305FB +:103EE0003DBED46ECA7B4AAF467B6382760FFB3EF3 +:103EF0009354D70E79A7ED2573DC6BB1C7E0B73DBE +:103F0000509F329CD7CDFED684927107C1CE7B6381 +:103F1000055D1FE4F965480ADCE598A8896817D2B1 +:103F200012EDC137334762BF8985667FE3FA103FE0 +:103F3000E1BAE9E6E753F9F8D3C87DC910A79B3683 +:103F400097C5E9AE23752B8DDF519B1A32CE2B100E +:103F50004033D891DF147E6ABA0EBF25080F52ACE9 +:103F60009FDB5D007E84C1BB7DCA20965F2CB919A2 +:103F7000FCA62D7663DC94FBA156FEBED5B1BA1D1E +:103F8000F8D64ACCFEA7EE475E08CE84FBA7385E83 +:103F90007610EE564D44FFD4302EC245C7C737C504 +:103FA000838EBF6F8B8F2EC087E15C572FE7DB6757 +:103FB0002D8473083BE4BBD37D4D5CCFEE8FD8F3EB +:103FC00004846365A115EF4DBE6FA92C00C3B962CF +:103FD000C895353F64C3BA013EF3391CAB481DDABE +:103FE0009DE4AB73E78A0AF0F40FEDD6F91A21E3EA +:103FF000A95F525524F8A3E9BEE749C41B3718E26C +:10400000A00279CF1807F599EBF0774D4A709C0B19 +:10401000F58F241FFED9E5DFA83C7A8F22FB089498 +:1040200098374324A3FF38B395C1B17691E0CB46CE +:104030003AF25B8DE7BF0FA4B378E3DFEE1C827228 +:10404000AEF8C703E2985F9B8FF93CB5DCDEEFF278 +:10405000AA7110CFE96AED1B07F19AAE83A5B1E111 +:10406000F2780E71BFF20FCBED589E29139AC43827 +:10407000BC773201F570591401B913FADEEDE97A13 +:104080005CA68E9D4B1296875FC5F7318FBE1A973F +:1040900060C0DBFAF11F48037BE201FEDE339CAB1C +:1040A0007C57F8821F0B703D14D53132DCF709576D +:1040B00071F855ECFD4286F8C1A4D62CFCBEE4A4F0 +:1040C00032D194A7BA3C9DFB5343C8105857C5DE64 +:1040D00031B157015E0E8AEE280ADFDAD6B3B22775 +:1040E000CCF95C283C617C88231FB5BAAB009E47A5 +:1040F000EF89C2FBFFAFF3F3A23CFE5D48F87410FA +:10410000C4CF9AD2593EC8FBE92C8E3EB9A2D89AA8 +:104110004CE7CD6B5106415E592FDEFFFD74159FB4 +:10412000F7E6EFE9FD7A2D62FD8EC84A4DB8FDC76E +:10413000640AFC3CC4FDBD42E13F0F6FC53F76FA07 +:10414000E15E5C5799C0EFCD84D23541FEE81A2D6F +:10415000F840FF821F8BF50A01F5FFEB7ADEDD24C4 +:10416000A62F75BA0F85F36E0E677DFEBFF0FA5E5F +:10417000AE377438EBF00D5DAFDE9FCAAB11C67879 +:10418000CBC49D839E06FBA4A655502C74A81AA9E7 +:1041900043063EACDD79AF15CE17AEE7BFCF42A4E4 +:1041A000CA81C6F3DDF7D3D9EFBCEC1B3C0CEDC7DD +:1041B0004FD633FB589B7B3616ECA0D72DEEDF0D88 +:1041C000037E7C43347DD73CB47C77B9B2A0CC6A03 +:1041D0001C370BD7397951B115C243372E6AB3A6B4 +:1041E0001AE8E97DC8C31A1A6CEFB548C5FC453A10 +:1041F0001FAEC3FB231B817C8CBCE6F69218FAFC35 +:10420000C6BA784687D5CD6D32D6D97786F5F9F41A +:104210007942F9694A458CA93EA7B4231DE0526151 +:10422000F32F7587A1536F867EAEF20DF58446E9B4 +:1042300076E0FF0F7AE2ECC870DF419D98D1433FF2 +:10424000A486D30F4B56A8A900FF25BBFBA602737B +:104250002C79B93C259C7E7873393B3F3CCCF32EBE +:10426000CF4CA1FAE10A837E981285F411FADE554B +:104270001917A91F747CFD9BE5CC9BA01FC2F0758C +:104280004586593F4C6B9D85FA61DA1491A8867872 +:104290005C69068FDF46D40FC529D763DDEA8E0936 +:1042A00043376F72BF04E00A25CC037AE28E0C26F6 +:1042B000F743F5452479AE5CAC3CFF5F82B32ECF6B +:1042C0009750FF85FD0E4E281D1294D74BAE17F068 +:1042D000F74B96EC66F27CC94D3C2E19225F2B41C0 +:1042E000BEE61BE52B7BBFC6C3F441EDCEAC8766B3 +:1042F000D0E7373459DD76DAFF86A0BC2D30CADB33 +:104300003B32241DCE994A18FC4E9F114354B3BC36 +:10431000CA01397574D04B79CF02DDBFCEEE99BD9D +:10432000CFF5F86B835ECA8778FAEFF9B89B391D31 +:104330009D5E4E1694513894CE65F6F0E2ED22C2A1 +:10434000A1A685D97935DB04BCCF3B72F017786E16 +:10435000B870373B3784EFF9161BF0B8F0F58EC60E +:10436000DEF07C9380E79E55EE85ECDEDF061627B7 +:10437000B6D3FF205F624D74EC6682793A1AC69B11 +:104380001773B855D83A0FC0FB158F0BEE4D28D7D1 +:10439000CCF1E9C539633F00BF60E1B69076F71A0A +:1043A0003CCF580C7167831FD2C6F7778BE8CF7B61 +:1043B00016F2027F2786FDBDB3B65038547F4738CA +:1043C0001CA270C8FFF670A86DBD17F36FBEEBFEA0 +:1043D000F76570FB7030C9077E79DFA221FF7B5F34 +:1043E00011F15EF1DC7BFBA51AF3940E6530BBE2A4 +:1043F000758BA7310DFAD5B0FBC7F3363EB31FAEB0 +:1044000086CF682683206C3F6F83594F76EBE51685 +:1044100015F5EE8CBA6704F89EFF2D22C1DF019BD3 +:1044200033D8E681F3D743519D28CF743AFC12E884 +:1044300090C2FD0B3EEFD15E9D65E857EC1414E48D +:1044400013F89E06D4291EA2603F577D3E92C31DDD +:10445000E333B53B199E6A295E80CF46527B17F441 +:10446000C88D54EFE079596B9B15FA57D37E892894 +:1044700077DCE8EFEAFA09CEEF8A530C78DB7D842B +:10448000D1EF56C14DC2E02D97FE773EBC45C29795 +:104490006E3F5C2CDE74787CA9CB6F8EBF4351EDF0 +:1044A0001543F09C8AFD0E10698DC77395634D7D91 +:1044B000118F519982E9BB32DD7805FD68882F5D47 +:1044C0000B0BC70FD747619E1CCE9BCDEC21A37C65 +:1044D00009F5A36B493BDA35629AE7E174435ED88C +:1044E000349EBFD27DAE1BEC37392339723FE22AAE +:1044F000C1F31F3DBF167E390AF3C1787D5F46C107 +:10450000E11974BF9FAC16F17EF27516F5AD22E08D +:10451000E3B5560274F9C96B568DD9A13128876766 +:10452000BD7ED40AA19159905F40FBCDBA8BC9DB07 +:10453000A330186DFB13D5631A7CB784340F85BC88 +:10454000FD29EEB672C8DB9E9A7F68259CD34D2E5E +:1045500055DE7A0BE0BB462400DFF75697A2BF7208 +:10456000DBAD02D2F5DBCBF1B7B0C8D429596FBDB2 +:1045700045E7BD6975329EB3CDD0F69703BDCD99A1 +:10458000E874C039DDB85C91780C70BC89B463DC28 +:104590006246DDAD5361BDD5542F40DCB5BAF55050 +:1045A000792AD4370AF83B6AB55E8F0C57A0DA3700 +:1045B0009C9521FE5245FB017A6A37B27EB55B04B9 +:1045C000BCDF5345E503ECAF6A8B40E022493BB5C5 +:1045D000FFEC6C5C9F9D8EDBBE91BE4FEBF3E07DEC +:1045E00018774B3CFEDE5DED6BEC7E5055E18A03A7 +:1045F000209FAAE87BF43169DF722B8E377FA340BE +:104600002035B8BA30EB478530DE6B56FC2EC8E15A +:10461000B6876558F7CD74BE343AFE1CB1A31CF3BF +:10462000ACEF1014CC83FEEA07C80767381F90D799 +:1046300096313E13789DDB85BA7EBC37339BE5BB54 +:104640002F5BD108FBEAF02667814B54BBF3AC0C1F +:1046500076DEB1E5F0E1198A379E07B7CF7B54EEDD +:1046600030C8A9A733FBB2EFE4EF2C463EBF855418 +:10467000E2B9B86705D3CB475646F904B047AC0A50 +:10468000EACD7D2B2F7D10F67FFA292B9E979ECEAB +:10469000E8C0F8EC898D56FC6E48FD4611E5C889E6 +:1046A000ED2C2E243E3275641AC08FCA01A0BB7D4A +:1046B0001B4B659087277C02BE5FFAC8ED292CEE64 +:1046C0006B961F55EA0294178F4431F9306F43F807 +:1046D000F3D588F262E94826DF43E4C1E2F4468C70 +:1046E000FB85CA895AE2D0E5C360A8B7FBD3907EA8 +:1046F0006B5EB312B0EF6A24E5E60D403733A2E0FB +:104700002499F2857F3FC8B74F7C82EAA5CF6F9C82 +:10471000F99BA100BFE3006FE08BF58978BE5AE5F5 +:104720009B8570D5F311E76D30D3B39EF774BD4709 +:104730000CDEF3A1FFBBB13A8668867E87EFA274D8 +:1047400049E79BB953C0EF211DBEEBC881DBF3B134 +:10475000AE001DD62CE37A75BD13E9F6F00FCEAE90 +:1047600004BABCF94E01D74FBC9E46D02B351B0472 +:1047700015E29AF3EE64EFCFA3EF03BD1C7E98D150 +:104780000FA56315E8BC66E3BD07B0FF164185F1D0 +:104790000F6F9A857AB8DA2B127CBEE508DACB5413 +:1047A0001F60DED03EAF9802745ED3605300AF3A14 +:1047B000BDE8F477847F7F9AD8DD0327C3EF536485 +:1047C000AAECBE7C08DD89D3B390BE6AB75B915E6C +:1047D0006ABD8C9E8E3C25221DEE5B79DD48A09F34 +:1047E000D35B8508F447E92B3F485FE223567C7F83 +:1047F000DE132CBEB06F23A3EB132DCC3E2D7DA476 +:104800001FFA35F35EB712167F200EA3FD71213A11 +:104810000CA5BB1E7A89D36124BAF3589BA741FE2D +:10482000C1ACA7E9FAD520BC4A1B7F807180D2C6F3 +:10483000EB71BF3AFFC0BD16C8DB98DBB482E5332D +:104840004A2CBFE71BAF2B641DCB339D41FA175990 +:10485000FE899FAEE3A5ED8FA11DF0F12F8F607E45 +:10486000E3C21728FE69FFD3DB9DC48F76B60FE540 +:10487000CC821611F34B89E42F986CB8BFA5E7657D +:104880002CFC9513E1BE6087CD5741DF5FF0DCD192 +:1048900081784E7E37B353BDBF64DF9921DE8E81B0 +:1048A00093213F5362F921A1FA3790C9E230A77EE4 +:1048B0001383DF6312B6B5E139D382E6EBAC36433E +:1048C000DCF24CA615E7A5FDD83D338A7F385F841E +:1048D000F5197F4F42CF0B39F504E39F053BAD68D7 +:1048E0001F2DD8B609E37DB5DBCE62FE6CE9AF9E25 +:1048F0008A0538D4EE14CDF953DB44BF0DF3BCC4A4 +:104900002336F65D0E531E534D0BBBDF51D3CCF354 +:104910008442F26716FE6AF7735E0A9A85CF3E1EDE +:104920000BFCF461FBD65880271D0FF38F2616462B +:10493000C84FBA505E52F31A9E97341E7FA7233495 +:104940002FE943F807D5E3997D42F2BAB631B9456C +:10495000B15F10EE1E926EBF2C7CEAB347218FF63A +:10496000D48E8F1E85F52FFA9F4F1E85BC0EB22761 +:104970004A017BA2F6976F62FEA1FE5E611F664F41 +:104980009D7EE271CCDF3CFD8E0DEDC2D3BB4F644A +:1049900082BD70FA992F52202F73E9EE728C4F2C42 +:1049A000FD7529DE0F8DE46F027DFA2E227F34140F +:1049B0001FFB5A44BF83AEF3E3B76DC8FFDD7966D2 +:1049C000CD8B59FE9ECAF3CBB687CFD3D5F3A16A60 +:1049D0005A264F1C0EF2AE85E9F5EEFCA80BE595C4 +:1049E000FD91E2F58A8BC0DF769E3FD83C3E6C5E3F +:1049F000D9C7F00F8AA76921F8FBACE5969FFF1491 +:104A00009EB584BFA7ADF3F585E0A6E701F7EDA35A +:104A1000CDEA037CB4E349CCE303BC55A8A0FF3F37 +:104A2000CB84F8E6496B27C60D3B77DB14C8F75AF1 +:104A3000B0FB30F2CBE95F1FC23C5BC2F3714F9316 +:104A4000EE3F9637C96317B55B9C2C1F8DC31FF2D1 +:104A5000D5D4586CE779698C8EF57CB548796A0FA6 +:104A6000F5C966F1439E9FBC586D971547105F804E +:104A70001FA110F075C494FFA7EF3B743C05E070D4 +:104A8000A531FF32523E20B7D37BE08BC9E5D39BE3 +:104A9000783E66779E2521E983213F88E9C35A9FA6 +:104AA00070381C7EF5FCCBFBFA70BF53E74FDFC5B7 +:104AB000E55D5E78DDDF0E2E0D7DD8FD001D3EA785 +:104AC000BE0A2FA79FE2FC4EFD96ED7D0CFECD4C5D +:104AD000EEB7E87967FA7A1B9B995E3EB58DD98D62 +:104AE000A1FC5D13E1F7B45EE8C3E20D353BDB06E4 +:104AF000821C3AB5F7379CEE7CFC1ECE11D9CBE573 +:104B0000B6CF28B723FC7ED97E3E1EF577C38E57DD +:104B1000BBFD6CD8F13E94B4EB60FD1FB6333BE4B3 +:104B2000C36631ECEF20FCAA8FD5E407363A65F472 +:104B3000BBC4D86894474B9D856FC377DD963A65B3 +:104B4000CC77A85FC1F323EE72E3EF78D43BC7E2E2 +:104B5000F74B57027C0C7EA855F1E0EF4E585D955F +:104B6000F9E05F85DEEB94932CC467C4BFE4C5FB1A +:104B7000BD13B23F9740EFB42F37DF1B699794FD09 +:104B80008974BCF632C10DF66E4F3A338F7FAD2675 +:104B90009AE26710AB867D75B9D9F7D09C16BF42F3 +:104BA000BB106754BB0B1D3D95FD5E35FC4C179C3F +:104BB00083AF5D6ECF817B5CB1C48DDF1976BABBEC +:104BC000EFCFE0787124246F9BFF5EB5830B95389F +:104BD000A2B441DC223A97FDFE8342A2DDF0FDA2A1 +:104BE0009FC46A78AF69BDD3837A3822DFB8D9BD54 +:104BF0001A3D9E1457C8EE51FE5FBBEBC4160080F1 +:104C0000000000001F8B080000000000000BB57DB5 +:104C10000B7854C5F5F8DCBD77379B6437D9900421 +:104C2000C2FB6EDE0921591E09A82837E16110D0A8 +:104C30000511505137E1FD4AE2A396AA9505621A83 +:104C4000296D8380528BBAD050FD5AB480B4828DC6 +:104C50007603D162AB36A0566DD52E101194C70ADB +:104C6000948FFAC3F29F7366267BEFCDE681ED3F0A +:104C7000FDEA30F7CE9DC779CF3967660921E40A8E +:104C8000FD7F92A6B485EC04FFA09E4C747537FCA2 +:104C90005723A4373CA77F2A211365072123E977EF +:104CA000132C811809DF4FC9A2EF1DEC1392944A0F +:104CB0003C41783FD5E1F1D3F60E876F0A49206475 +:104CC0004382F6A6444BE2518E8672A12B955C4935 +:104CD0002724B120E4B7D0C789A3E973DD3CE89F5E +:104CE000E475E2FC8E9AE677543FBFFEAA33E5787E +:104CF0003CAD2844B922D3F1ECAD84D0D2E951CEF9 +:104D0000C13891FEFC4429A1E3F0792612FA9EF6FF +:104D1000E396362A57E83A5CC425910C1CCFF4DDA3 +:104D20000017F60F75DAEF5EF8C73584F45BA6B6A8 +:104D3000D8E83ABD76C90560E843E7DA0A40505A38 +:104D40006D008CA71CA21EB49102DA6ECF215B8885 +:104D500096CB771EC2F716A8D332395E1DDF7F18B7 +:104D600021930359DEB43C68579166F160BD554903 +:104D700025A46E9A2FCD320CA69FD5D0328090E715 +:104D8000494DBE44DFDB6BDDAD07AF27005A3A1952 +:104D900078EF6ED50AE03DAF131224741DCFC7B56E +:104DA000D7357B1AADA7B7D7FD506F04E05F0BE393 +:104DB000B95B6BE9F7BB54EF44958E3BED190B9152 +:104DC0005208197BC91190800E42BD08E90B9FD58E +:104DD000C4015EAEC0DFD84809F025A99176E6F798 +:104DE000E676749EE53BE9FAA7F92ABCE347103260 +:104DF0004A627025AED088E94E9847E56CB538F226 +:104E0000DDB467CEC9E9747EB3294D11FA3CB1DC3B +:104E100075532E9D5FE2160A2D15DAFBEE82796737 +:104E20003DE2B300798C25A1FB258A4FF2490ACED9 +:104E3000478C53F79A8CF45BF79825B01AE957958D +:104E4000BC43F5F80B99F01766F8DB7B04F157D5F6 +:104E50007484E16FEFD666C07F5593E48A51613D5B +:104E60009E5D9488C8FD816BBCCA408AD798701D2E +:104E7000E0D54A4679A7C4225CEF85F574802B9F64 +:104E80005F77707DFEC4B61F17D2A6FE53164F166D +:104E900089C04BB4DBACDA102E7DD27D8F021CAA08 +:104EA0003786EA62E9BC5E3D7138C147E79B75EA27 +:104EB0005CB090CE376B0CB271FBB8CF9FDAD66C7A +:104EC000A3FF7C1EE898BEC826BED52E4757F060CB +:104ED000F4DD0E8F3D47103E16A8D3E7BB6D64117D +:104EE000E0B56CAFA40580BE63C83D5E5AAE572DD9 +:104EF000B88EEDAACC4B89E1F154BAA2D2EFCB66C1 +:104F000058B4002D137919597F2DB6DBAE2A580AF3 +:104F100078087C0A3A22A4217E1AC5635A8EEF597A +:104F200023DD3C119F4EDF8F6D3B7A3FB144BEDBEA +:104F3000BE9278E75923ED28FD3C6CF86EC2F7E28B +:104F40007C0591F64097402766FCD0EF7630BC3E5A +:104F5000110FEBD8D7764E0678F714AFE6E7AD2BF6 +:104F60007DDEF1D6CEF9C75B2A7B01AEE6E7418054 +:104F70002FC2C7EE6FCB05A92D91440A6AB9AF2F96 +:104F800008F35B6E0F25CCA0F8AD2A3D6F0338AC5B +:104F90008E3F739D2F4A3F9DCDA3F5728EC34BD795 +:104FA000B7FF520CC2DBDCFE2B8ECF7757CEF68ECE +:104FB000A704FA785C42210A5B3F793F93EA87F1C4 +:104FC0005CEE8ECF5C3285092DC5CFE5B8742586A1 +:104FD000A0425068BB09F084CEAF7CF42E85A44378 +:104FE0009DB613F2D88DFD6E2345800F6B1B3CB729 +:104FF000D3FF811E999C79D349D02FAD4A684D22A9 +:10500000057D6B9A84FAE7C6CB0D2DA0BB6E4CB321 +:105010001AF4DC24D5589F0C7A4F37CE348DE29D9C +:10502000BF3F8FFF0DE0FA6E56296869FF3767C6EC +:1050300005FC74C9B78CBEDD3B5EA72F0E7D2BDF50 +:10504000E32DE8089FD16E011F2FC2F595580A9FE6 +:10505000225867452DD3495DC3C30C47335CC67FD7 +:10506000B2600A29EC08979EAEBF1DAE84FC04D640 +:10507000375993C95A7704AE66F8D0BFA9D0EE501D +:10508000296D27815D704AB1D0FAA46B2422EC828D +:10509000097ABCF3F999E16A869FB03726F3EFDE0F +:1050A0000678517A9A2C6F71003D4CFA61EBF864E6 +:1050B0002AC7260D64F825410A5CAAD76F20083359 +:1050C00080EB36A43B9715ED0CAAD7197D7C32F105 +:1050D000A444C79F7289BEA3F39CA84A01CA2200B8 +:1050E00097A326B81C35D1C551FDBACDF37D05FE79 +:1050F000714D147A511A7281EF8BDCDC3E1944D465 +:105100002B541F957C3C3291C987E87A72EC256F4D +:105110007B3F0C1E0D483712F1B53F77D17E829A46 +:10512000358582818CB3BB904FC6116D4D9B1D4060 +:1051300021E33CC5BC4EA6793537FDBE944C5AD30D +:10514000A687F327429F33788FE3F01B47FCCD728D +:105150000294CA05FDBA457F93C47A0693C1600FD5 +:1051600035AB2AD3FBBC3FB1BEE4641294E804C360 +:10517000923DB04D82F913BFAD57643C2BC7EFC7CA +:1051800099D36F75A3DCAA21002F305B009F65FCCB +:105190007D99DD1184F910BBF5543B5EC086217307 +:1051A0005CC787205CC895F8C8FC2ADC92723C3743 +:1051B00032BFD307ED7E99D2B5A7AF6FBE9BCEF3BA +:1051C00094F47621C08BDA65D920CFCDEFCF7FD490 +:1051D0005205EF69BB05D88EAF6BA92C21DD845F2A +:1051E0008B096C734793E7AB98FCB5534BB42442DF +:1051F000F765718CCF2713AF02F6E5FE58C6672D11 +:10520000B18B911F26929ADAA1B4BFBFC4DD78108A +:10521000F86C12F163BB092E231D7647A73791F076 +:10522000DD60F74ECEB59AEC683FE2677F6C4E26A4 +:10523000E8B3FDB14C2E0BFBE149B7778D1BDF0FB7 +:105240000A805C3EAA15BF0B7AA2B274C4DF46D2B4 +:10525000D262F7DA009FF381BE285C47037DD16FED +:10526000F743D77D91BED601FEE6D69BE8CB9E8C58 +:10527000FD7BA91883799569D66FF476753BDCB808 +:105280009EECCE5E242D0AC9A5709DC7E9747F6C83 +:105290008C1FECB8B2C7291F53F8CD25BE671B245D +:1052A0009887D560BFCF8BB5A2BD37EFE7B1C8EF08 +:1052B000F4E32D3574C805F4F95ADA0FC95507E837 +:1052C000F53A69D07D0FF8B7AB488FF35CEC591B0A +:1052D000EDA36F2FE8974A370A4FB2D97A4E4F970E +:1052E000E6F13BEDD7F4DD7E89CC06BDBADFAA0E30 +:1052F000F0E8F4C76E37B39BCED9B3B658D23B872C +:10530000D3027BB2A68C88D48FC7C6CE8E66278880 +:10531000FE045C23FB8B130D2D6322FB0BCBAA2F0A +:105320004CFB8B2FFEABFDC5A1AD5FB4D6D2F934DB +:10533000647AFF0EF446146F1EC07D13B71729A5BB +:10534000E44DD3E1E1EF6E66CFF45E318E1CA3A491 +:10535000146327FED8E194DF15E2B70E87F6BE5539 +:10536000168A57653641FD43E50DDA99E6F57E9CD0 +:1053700059F6198C27F8B02C8ED239E5BBC72D6AA7 +:105380006303D8D37F96A96D49475F3117EDBC5BA6 +:10539000572CC6F2ECD1CBD9C0FF651CAEA7417F1C +:1053A000835D1DCFF8A73A9EF1CB2B69BED340FF9A +:1053B000AD9AEC1C49FB5BBA57F6C4E0F2C38360BC +:1053C0007DB74E9553E1F931BB15F789FB9D0CCFA5 +:1053D000C78854BE13ECDE4331DE3DB45C9056EA20 +:1053E0004AD7D9830BD2C6639D9453C38ED2DF7D37 +:1053F0007646F7C7889BCDBB5EF26CA78FCED5BB38 +:1054000013810EF75B89C1EEB0A4337BD992CEE055 +:1054100058798932E108465F3574FC4A45B5819D6B +:105420005F79C986CF611E487FB1C67EE2793FF1C0 +:10543000EDFD48E80CD81F6BEE4761CF391D9BF19D +:10544000F0A87B5C22AC67419AE64A4779AF2A0014 +:105450009FB2912D1F81DCEB5ECEFB2590F3D5979B +:10546000A5E060BAFE537BACB87F3BC5EDFFD37BB4 +:105470000EF4AEA4E5F25DEF25C03ED19DCEF075F1 +:105480005A694D80F92DFB1DB59B0B906C7BDF8914 +:10549000DFCF2D59CB86B1EBF5DFB5DF660CF062BF +:1054A0003B3AC19288FD35CEEE0FC0FCF6AF926755 +:1054B00003DEA87E14F69704F270C21E598B2DEC01 +:1054C00068978D4AB7727E63787CC0C5C6E98C8FB9 +:1054D000CB2EC593808E8FCB145581F9975D4AC032 +:1054E000E7A74F6CDB7033A57B7F9A15F781747B40 +:1054F000D48276A1C4FAA56CDD9249C769E1EB7943 +:1055000063CFAD33AEA3FF7C13F40C6D333EE44B9D +:10551000614C4D777125113B6B82CB680F9AED453D +:10552000A1B7CA9BD6D7F62700F7C0ADD7011D9EFD +:105530005008D061077BDA7E632776E37A84C7ABB5 +:105540007B7E89FBA53EE92AE3AB3DE727021D5799 +:1055500091E04CE8B76A8FEC0AD2D66F903D434099 +:105560007F08FDDEBEDFB97CC0EE01F91F2BBB5604 +:10557000C33AEDB739540AA7EBCE16A4A09EB35B8D +:10558000CB41FE95C56639E6EAE8797F8A5C0E7400 +:10559000F0464A86F1B97DC310D073FB2C4C1EB582 +:1055A0001CBFC311C276B7A6A0BD26F4BBC93E1569 +:1055B000FEB0495972209ADD4BE42D1B63E9FBC90B +:1055C000395622839D1E5A827ABF837EBFECC37DEB +:1055D0008059CF0BB8534823BF74B04F237036D8CF +:1055E000A98FA6533B6D08D2C050B03B8397372C90 +:1055F00085799E6D8A77AD46BF03B36BCEB62DD944 +:1056000030159EBF2DA31FE5EC6519F969FFEB4B23 +:105610000787747C4C3505E2E9E2B0AFCFFC81E24C +:10562000E7E2E7711E3F3C56760E89B62F16FB2542 +:105630003A723F4B1ACEBF9F6534B21BEE4F6F8854 +:10564000EC4F37A6E3FE343C11D446DA962336A05D +:105650008BD3D45487F9FA29F2B753B8DEA0856406 +:10566000976E3E2FA44BDCDFA13D0D72C54FCAFAE9 +:1056700053E3842C8AD34AAF03BB731A716DA3EB37 +:1056800079ED449964A5F531DBDD1E89D67783E198 +:105690000974FB3B39B09DC2613795C7BB69BF8BAD +:1056A0005B1B6C6E3AAE7F0F9DD4285AA7880438D6 +:1056B0009CB0FA0725E9E8645606932B27ACBEE7B1 +:1056C000A09F131FC710D8079EF83C2EAABE1D9C92 +:1056D000C1F4ED1FB89EFB37A7F7E0A957DFEC47F1 +:1056E000E715BCE41A06705FF2C2D772051DE77AAF +:1056F0006E974DD9D85A0BFE9B9BB78415903FDE11 +:10570000806B02A8DAE92F78ACA09766ECF05AC15A +:105710000C9FB9A7C60AEF67EF6D7803EA770477A5 +:1057200062FD7CBAEF8F00971BEAC307805C321BD7 +:1057300088027C412E307BEB533E8FF44B9EFD89DB +:1057400048D5A516A0F3F6F11F6955C0F4B9B9966E +:105750008D4FFB7B0BF074434D781CE8B7412B5801 +:105760007F8348F3AA4435D2EFD8CBAD92DEAFF0B9 +:10577000EC438E454CEE32B80F7AB8DFD6B5C82769 +:10578000AE38D0F782AFCA1E766880EF8B3F880BA9 +:10579000C4B881CE98BD7DF1078E803F8ABD1DA122 +:1057A000B3600CA32F416FC4CEEA9A1DE8EDC12768 +:1057B0006BE2407EA478559B4F87C7B20D53F2DF52 +:1057C00082FE6363D07FD73EDE7A361EFD3E1FE841 +:1057D0005AE8B34AA007835F4AC803C617B48B00D0 +:1057E0008C2B4A22AD76117D9D04D3603E9F03DC55 +:1057F000E9778D36750E8CD71817E382F12AED59AB +:1058000036905FED7E5070265239721DB73B5F3B7C +:10581000B13F19F07E71D8AA41B03F085A7E81F29B +:10582000AA3BBABB2D5DFB0FD3B7FE41B0BF12ED53 +:10583000F71D8F2B007DF9079077801F4FC56058AB +:10584000AFF8AE7F06D3F7945F70FD824F525A894E +:10585000B6B50041A5EDD6C1A337E70B51EEB6AA08 +:105860007EC667D44E01BE7306ED19C0CFFB32B0C1 +:105870009EE2250E0F7D5FBD37CB23AB28077A67ED +:10588000A446E4C3F55C3EA4B486912F7BBA4FF8DE +:1058900096C337A8ECE4FC45504E017F31391EEC2D +:1058A000CFE490BF3FE005E406C74F5F89960B3910 +:1058B0009EC5BA53B85CB84EAC0BEC375A2FC960D2 +:1058C000F247BC1FC9E136412E480C45F1FFB4D365 +:1058D000DD8ABE04ECC9092BFA635992C1E6BBD834 +:1058E000BE1EFDAA8B53D6A33F35456BC072F1F89F +:1058F000067C9EB6A502E963F166C9E01F15E5CFF7 +:10590000B87D76FA8405F51BB1C4F503FA13EF37B9 +:10591000723BA44FBAAF0CE07C72CF86270BD588C0 +:105920007FF8626CC3CD7700FD6F975DAB003F8D54 +:105930001324350A5DE9E107F0AA6EFCD744985FAD +:105940001509D5817C569B24949FEA5E5AF6A1C422 +:10595000DFC8E4E9496EA72D8A33DA97B338DC4E05 +:10596000585B2717D1F183E73287835F27A88464C8 +:1059700085E18F007F801C7621BDAF1DF410D09192 +:10598000E444FB07E4EA2E1D7D2CDDB1B5AE1FFD1E +:10599000E70D975DC364EC8738F4F25BD08990C75C +:1059A000E6F52DE6781574785D444F2DCEE07E54F3 +:1059B0004059D5FA73E8477D94E3AF11E80DF8B983 +:1059C0005ED0DB300BCA5B131F8FFA1FC9F77D4F08 +:1059D0003C3D08FD13A329DF52BE3E097C1D852EE8 +:1059E000EADAE5806F5546147D7052F23D979C11BE +:1059F000F97EDFF19BF22B75FDF8383C2E5A7D8342 +:105A00005D51E015812BE907F4B0886206E040B6ED +:105A1000482EB00BC5FB942D2C1EF014E723F15C2F +:105A2000D405BCC702BC3310DE4FC17CA95D600346 +:105A3000959D16607601B1DCD40FF4FCE238ED26BA +:105A4000F4C7ACB710F02F11A90CE93DA571D3F143 +:105A50006F4742199B8EF1156A77031D2D7E5CC539 +:105A60007DE2EA5FC5225DBE98918EEB5ADD6865E6 +:105A7000F4696D40FA3AF9F992C1109FF153BD9E55 +:105A80001545EFD499F4F943194C8F0ABA4B5FC707 +:105A9000E8AE51D1E2927474F93CD18683DC167A77 +:105AA000A5337A8CD0916B98A0A30AFA3CBD3E2412 +:105AB00003BE281E5F053ACC58174679D6191E45F5 +:105AC0001C4EE053C8F9FFF0F98BF1DFE6723E851A +:105AD000DB3B1DF1BACAC00FD747F8E12F0C3F11CD +:105AE0007EB0AA91F5FC9EC3A533BEC8CF7461BF3A +:105AF000759F6EB81BF8B96E7D9C673589C4734479 +:105B00009C55CCE3334E879DC56376A9BE4F334C7D +:105B1000F14215E53D8BBF4CE076FA7DDB63D0BEEC +:105B2000D807AF408EB4C505C0BE14DFE528445386 +:105B30008613F255861BE79F032284D65356D84816 +:105B4000261DF7E235CD2D09B4FDD470684A115DEC +:105B5000E23E5B68C62DE01726DA12B033D0970F0D +:105B6000F47F8AF54B5C3B0DF3FC1787B7C04FDD24 +:105B7000A773D3A2C50B041C3BC34B7E268F9FF19A +:105B8000F766FE6F15FAAAC7FCEB4F04FEBD81F85D +:105B90005741FC845C262ED0D3EDFC7B99B0F85C99 +:105BA000A6917F453D0AFF2666EAF9F75288F12F54 +:105BB000E7D3C446AB16CD6E19986965EB6A9C5065 +:105BC0000AFA28D14BD06F429789FCBE98F23BF07D +:105BD000B11FF8B60FC093C9DF74ADE16E789FDED8 +:105BE000C8ECF18B496CBD8BAFD79A65E07FBA1FCB +:105BF0009068D306CEEF9DC33D982831FD9608727C +:105C0000E68631A171A08755881BF481F531FC8EA1 +:105C10001D4302418A77F53261F2E3F3A7EF7E0874 +:105C2000E4C67A87274B8DE8A54FD37DC332533B1B +:105C3000E76B4A971AF8B1EEFBB783ED1F3B899FDC +:105C40008F5D2123FD513ABF365307FFB1DEB00C03 +:105C5000704D8EF7A55993E83EB0316BBA7D205D4B +:105C60009F9BDABDB45E4EEBEBC02FD72B4478FD83 +:105C70000947DFFF224F2033F330F8F1966768932E +:105C8000328B31AE3D19E67343FFB08CF2AD87F134 +:105C9000FF6AF0EBD1F51CBD2DFF5715F469E5ED5A +:105CA000DE3A782BFCCCA3B89FB9BA6918FA9F7575 +:105CB000FEE63B60BCCEFCCDDD8D9BC0F99ED237AD +:105CC000EEFF12468765908F42AE2CCAECC5E939CB +:105CD00044A60F8DF017C825B077451E02F8239D06 +:105CE00018CF0820FD413D717844DEAC6BB094477D +:105CF000A3EFEF673AA2CA53D2F47FBF7FA884AE66 +:105D0000175E31F9FAFD4C9D7C6D6C38DA9BD9AF8A +:105D100054FB537BE27EEE03D8B0DAF3D74CA0BB42 +:105D20007765F4C35C1363F34BE02FD088EAEACDC8 +:105D3000FB03B66B9282CE425AFF46221AF837BF57 +:105D400091B1DCF0A8B7DC0DFE968F2C287FABC09C +:105D50007EA3F0193D9804ECF49F7BB9DFB4F4986E +:105D600043833C81B3921DE5E7D923717ED0AB67B5 +:105D70009D16F4ABB7BC16837C713E338EFB41029B +:105D8000067F8988F79C7F7B6E32C8FF2779FCF3FA +:105D9000C958E68F7DF2F66CF4630A7FAFA250D843 +:105DA000F782B41E0AD75E6037F7473FACF0FFF6C4 +:105DB000B657482CE9888DA3D8D9FA7A2B3E09FC2E +:105DC000E75BBBC997F84DA64DD8C38D00E7EA47FE +:105DD0004236D8EF0A7B58E8EDC1A7D29B216F620B +:105DE000703973AF6D3D65B1C03AB752724A727780 +:105DF000A42F41475B3BE625ECCAD4EBA7C7585E0E +:105E0000427B9D7FF71CCF4B18DB76F465B0F328FF +:105E1000BF6F357C372135CE17456ECD5CF1307EB6 +:105E2000DF19FDCFB4105F343DF21ED72344A9E93A +:105E30000F7A8AFCF3C178358A3F67E6A795A900F7 +:105E400017B31F2E32FEA338FE3B99EDF1CE411061 +:105E50007FEB2EDE699EF7DFACBE81D1F494C0B338 +:105E600079BC8EDFB3FD597B3B1BF1ED72B07E87B1 +:105E7000EBFA55B2981D345362F17CF22D417D2D21 +:105E8000E884C2FD0BA08B92778E8D88C338505862 +:105E9000067970FEA3CC01188FEF643F2AE6432DEC +:105EA000E7AC68791F743C6F343C48594C8FCEB4D2 +:105EB000B23886747B16FA0766C6C648313AFBE4E8 +:105EC00074BBBED50C71DBFDB1A346A2DFD3AA0E15 +:105ED00088063F733CF774264178025C3C51E849E0 +:105EE000C49D059CEB4AB55285F9D5C83650811A38 +:105EF00093A329E504E36FA3240DE1910C467331CC +:105F0000D03FCBA73BFFB68C72A1A4540D4008959F +:105F1000EA8BA4AC62CCCF7AD9A2CBCF127452F761 +:105F200022D5CB06BFA3DFB0AF4EE2F2985A8FDA8C +:105F30002E5D3BF5119001117D30A0D66EA80F7A31 +:105F4000C045149DBE48D2D20CF5015E571CECA78B +:105F50000694AB86EF04DD89FC40FC4B8175BB02E7 +:105F6000901FD18BCF6794E443BA01F9067EE561B7 +:105F70001C9F74BD4559B41C5B1E3AAFA71BB1DE14 +:105F8000EED67574259D0F15606D2BE97CA95C9884 +:105F9000BBCEBD2A0DE1EE22B0CF38BED28ECFE708 +:105FA000F3EF933656D4F5A54324D5AAE8CF4DD2C6 +:105FB0006ADEEC0BF99835B44EFFE6354812F87DF1 +:105FC000A89CC1EF9E59E9C252E0DB45DF4BF4BD0E +:105FD000BF8CE4427CA7333DE6CD7218ECBE2EF4B4 +:105FE0009837ABB8A31EB3D83D6F417EC0F2265997 +:105FF00005BA5833A517FAFF36EC943CE08F3BD036 +:10600000C4F2F436CC64FA448C7BE67789A837CEA8 +:10601000488CCF494B12F2417512C74D6D12C66BB9 +:10602000CFF2FDF6B24C9F2F4B672F6D682A8EC5BD +:10603000B8AD492FD13F9744BFC3D89D04F6D3B024 +:106040007A2503E5C022F89E2C088D88CD00BAF58C +:10605000BD37460239706110E0D31C0F1471431133 +:106060004F7C25CD77AF7EFC8E7142637C4B4EB06A +:10607000E7029F8D96E33CB251FF12C0EB1AB013BA +:1060800029DDAD391287F059F32DE33F3ACF1F02D6 +:106090009C5B9C25484F42CFD27916BE4B3ACEB37B +:1060A000DA12463FA26E9E7559C55DCDD39407CBDB +:1060B000E7D50E7F1ED7929D0ACEFF2C89F3C03CF8 +:1060C000F7DA3C1FF9400F9F8943BF9FC04F15E788 +:1060D000B1B3141F129DE7D9BD23622D0EB08F7C82 +:1060E0004F02BCE481E104B0CF0F348DC883F57456 +:1060F00016DFDD9B59F67416F299EF19E43357E871 +:10610000FC4B6A64FD5DC485B742FBAB80CFAFBB7F +:10611000C6A3113ED58AA35E628E75B4C3242EA792 +:10612000CD74273535FF1BF29228BF615EA87F1022 +:1061300009ACA170AB1BCAE88FCC232AEA65139D7A +:106140002CCBF4BE0AF8127CDA057C5E8779DF93EB +:10615000E90D4209F3E83F1CE5D2FE2CA6DF5EB64E +:1061600059F07B96DF9244305FC71C77FF38B3F25B +:106170002DFC5ED85FB93EC95570557C70B86BF880 +:1061800005912E9673382D877830E4B3EDB19E32A9 +:10619000E44D98E0F0FD4CEF270C0E94CE46323AD9 +:1061A0005B43BA844708DADF93E93B06A5D34AE9A3 +:1061B000058032BA220DE0BC4BD5303F61F72A068C +:1061C0008FB3EF3078EC6BB3205D6F22F9C897C3C3 +:1061D0002DE7EE86FEA97C390DEB1A13DE29C1BE30 +:1061E000B9CF22D50272B97FD8235BBAA6DBAFB391 +:1061F00070FFE4BBC0F1703FE061C4DBCCAFD305FE +:10620000DD5EE274DB53B84BD95DF27507BAB26656 +:10621000A746E8AAA7F958942E48FF5E1DFBA3FBEA +:10622000288C3B34EF8B417955B55B42795EF5FAAA +:1062300017B85FAF7A35068972FCABB1F8FEDC1E89 +:10624000F6FE4C69F43C8284EC5EA8A796EFBCD7BE +:106250006BD4D37ED4473FD3CEB932E5485C367990 +:106260002A3BA7B086E73D89F86C02A7B3E4815EBC +:106270000DF450F20482F984090E96A7D8F13C027D +:10628000E3DB54FE9DCBA54A0067F3F904398EE5A4 +:106290001FA692755F039C92CB8DEF531DE518AF3F +:1062A0004D359D6310F02ECEE6F6B38DA4811CD93A +:1062B00069CAC710E5FE6C6E07D626E17E50E1F391 +:1062C0006A71DA906EEF73DA71DDF72591E429587F +:1062D0005750FF9BFB1165926621AAFE9C45791CD5 +:1062E0005175F651AAB797A1DE67763F43FBBEBE54 +:1062F00074C3FBFE8BF20DEF07D60C37D407AFB893 +:10630000D6D0DE4D01A0AF67D4DF64689FD530DD05 +:1063100050CFD97C87A17D5EA0D2F07EC80B4B0CFC +:10632000EF87EEBCCF502FDAFB90A1BDDC895DFE7C +:10633000A36CB63F92855DEE1CE903BA929D762967 +:1063400046B7FFABE4F8284D284F83B879AD7362A8 +:106350001AEC4F5B92A83EEEC2EFF65DF76D7E81C0 +:106360007F6E7F9571BFDB99FD548A50FAAB3A403E +:10637000E9A008ED2F7F36F72354A8D03E6C437D6B +:10638000A278701D3313ECE84F33F75F99AD1AFC18 +:106390007C621F205B3CAE2952E7F01274D91DBC11 +:1063A000EA395CFF5B78FDCD946F24F67BE6EFFE67 +:1063B000986DE1F6B86F5BB67E5F47C2B217F775AE +:1063C00017CEF809C85182764D75BC0BFD12663B9D +:1063D000408CFF4A9AF7372057CDF2D4BB62016B4D +:1063E00067A11B0CB9F3FDDE1FB3CDFBBD09B311D3 +:1063F0001F4936039C5E6CC7B366D8EFD52695E07F +:106400007EAFD6AAA5F564BFF762364178D7035EA2 +:1064100075FB3AD9E6515D28E78DF64B47FB9CEAC0 +:106420003FBACE0D60D749609725337B7DB784EBAB +:1064300016E37E07FBFCFDEC1ED8E731C453AFC862 +:1064400088BFBF67337BFCFE58F93BD9E3C7AE4634 +:106450001F1EB67A30CFFDF05499ACA2703C5F3E5F +:10646000AA0F89228F45F93EF7DF6CCB2188B7EE62 +:10647000FC1F87572EEAF2BCC7E1492C8F733AD034 +:10648000916EDCD81C46171939DC7F13C3FC18A7A2 +:106490007FEFC47309A76FFA208138212F6EC4489B +:1064A0003FE43913CF0390B7E37738D14F387D52AB +:1064B000F1C8554E1D5D8D66701EF7CA3B09E0FFA1 +:1064C00099BE2B23D5EFE89C9E32F8FA8812CAC6F3 +:1064D000BCED3F9CECADD272FABEAC54E6A734E6FC +:1064E000BB99FD46D3575419F878F925890492755C +:1064F00075A515F30A975F52F0F9E96CA35FA953EC +:1065000078F5109EE6E7029E87279D1C04FEF43373 +:10651000B1D1ED8F5B38BCDBE9C7744EA6B3F31F76 +:1065200025BCFFF3E5D7F4013937DDA666F5C4CF06 +:1065300025E0D47AF98B789013AFC3F99B28FD1727 +:10654000E5B0B8D2EBDAE7703C8294DAC3E380EED0 +:106550004BB93F3DCAB9807139E087B954FE3F3924 +:10656000173025C7782E202D478D7A2EA0BBF34DEE +:10657000D36CD1F55D6E047E1F00BFDEFF8CD505A8 +:10658000F35A08B613F8EFB65AD17FF7DEE51802D2 +:10659000F1942FB6587F09796E8B9EC9786623AD2A +:1065A0002F9A1483F19F855BAD2C3E37293600AEC0 +:1065B000AA455BBFD77B2E1DEF2BCAB7CBB2E8FB3A +:1065C0006736615ECD7B6D6B31BFFB24F0337DBEE2 +:1065D000E8DB1FCD04F8EFB3350C190676FF0EC9C2 +:1065E000704E634963ACA12EF20805FE881439BFD2 +:1065F000A1527DF2608EF1BCD68848DCECC11CE66D +:106600002FC13CFCAAA9ECBCD681E36CBFFF462697 +:10661000CB330C4E9A3565185DC7A4542BFA4BCC7E +:1066200079898420D2C9029E373CE96305CFE54EC3 +:106630001AEA443BF0CD95358807FA9D6382EEBC9B +:10664000C2A49F33BFCB2437CBABEF345FD194A729 +:1066500028CE0F75C84F8C9C1F3A1A8D6E36E4F009 +:106660003C45CED7078EB37CC4056FCB6C5DDDC8CF +:10667000CDF7F93ADE6BCBBFEB250A8FF7CA991439 +:106680007FEFF28D8F81DFEB0BAF44203FF48BCB9C +:10669000D1CFAD7DDEAE5F7DEDE77A003FB7962FBF +:1066A0006EAF035BDEE6BDD770EEA7E7F2A66B79AF +:1066B000322B87C521CCF2DD4CF7FFBFE4FBF44958 +:1066C0006F0CF23BB1FC1594A77631F968E673B311 +:1066D0003C17F332CF77F925D990BF9CCBE54044E6 +:1066E0009EDBF03D35F7713DFE1225B046423BE0A2 +:1066F000831CDA6EA423905C4A87A8756D8BEFCA61 +:106700007F43F7CF1F43FB3BDCBE4FA04CFE4BBF8C +:1067100032D0F723DEDE89F987673BC9436F769B6A +:10672000F2DA2463BCE0CB9CD266C8E77F50A5A513 +:10673000CEBE1E499990E73D7CC9F9F3A710B7ACCE +:106740007AEB22F2E7269B2F0DFC03FE7E36CFF676 +:106750002879231772AEEE3CC316EE9F27B9B9868F +:10676000781FF889306FE1681CFA89D6A669DFC006 +:106770007C9E4BD3FE0FCA2169DAE51C1D5E6AF9C7 +:106780003A154B74BBB83857D0BF17F5F8FC322A0E +:106790007FA3D0A19ACBCE01943E79FB20F0C77D98 +:1067A0007EE48E41201F5B368DEA32DFED67C09FAD +:1067B000547EFE18E47E56249EFA13CE37C2DF3D87 +:1067C000DFE6CDD6E769C9B949385EC235BB5BD3D0 +:1067D000299DB4AD93517EB739587EDB318752DEA7 +:1067E00058C0BE4B317CA7B0FD07D03DE563C5A1C5 +:1067F0007CA39747C5B90CAE9DADB33897ED136C2C +:10680000C46387EF6D476FB2831E9525CDC5FCFF2E +:106810008C1EAEA123003DFC88CBB19369BEA2DCE7 +:1068200062F88EE9DB6BB8BE551C26FD3AA0EBF88A +:1068300078639A3632978E3F314D2B86FEF6DAFC1E +:1068400043806FF6C645CF57BB2E97D923FFCEE1C5 +:10685000F4421C68BFE27832C6E96FC865717A0DF0 +:10686000CA1BFA87D7401E7AB3DBC5DB87F0DC1D75 +:106870007D3F01DE93B410B905F2E7E864E17CC422 +:106880001F4E1C2520BF12C26D04F269124C79B054 +:10689000A2FC0787DBAB3CEED991EFD83CBD1CFED8 +:1068A0008D945FE0BCA8E01788AF43BEC483AA8F75 +:1068B000F31DCBF7687CA297047196744DB5007DEB +:1068C00040FE29C827737ED08E5C76FE1DF850EA04 +:1068D000820FE7F379F6940F1B9F98628985793EC2 +:1068E0004430AF8372C26A3BAD3F7B9FCB03E7C7A7 +:1068F00032D611DC070D5C11B70DF649351C1F832C +:106900003792D5B1B4B59BE7F7897C6A776D48C1FA +:1069100073060FB1FCBD939FDF243BA1FFAF45FF82 +:10692000C67C4191DFE7CFB518ECC2DBD27D0F23E7 +:106930003E4DF9D89DE7817D9907790E3F11FCCE38 +:10694000F370C6F03C9C318D9BD01F37A6F14645B5 +:10695000A24D9E558212ECF79EADD114D037CFE5F3 +:10696000B2BC9CEEF2E39EE6FDFB01CFA99DE75988 +:106970003ED92E773AE4593E999BAACB2BFB01CB0B +:10698000B3FC7E2ED323CFF23C9A676B98BF6EC9BF +:106990000B8750DE8B71443B918F37E001968FF768 +:1069A000AC128A05FAB9184BDAF3CC57A1533E342E +:1069B0002CFAF90591576ECC271F1C0E97623E10DA +:1069C00021784F42BF3CD5A007B7865D71C02FDD4F +:1069D000E983DFE75E9D3E782A8FF14D14BDD9949F +:1069E0007B757A33087443F5E60128AF5A6F727DE0 +:1069F00029F4A7787F88E373562ED39F51F4E621BC +:106A00008E5783DE4C2101CCD320A72C1E7DBEA83F +:106A100028BDBCDF97D3B50F61BE63B83F25E1D475 +:106A20005122E9E45019E76B71FFC4F3BDC83DD3AF +:106A3000A2ACE37ACE9F963961BCAF22A1498A9A73 +:106A400087D6ECB689F8ED1730EF1B0653B92975D8 +:106A5000949B51F07106E6D9FF6DED0010C9B54960 +:106A60008DF1603E75818F73B968C768E7A114F036 +:106A70001F7EC5B88F14F0FF86C3C396A5FD1BC645 +:106A8000F913E7B3CEF0129BC7F0D12F8FD9332281 +:106A90007F7DB7C91E1D91C7E0322ACFC8973AFC47 +:106AA000C5E645B17B841C7E39DDEB80F7AF9ED80F +:106AB0001D0F7424F024E48F195F113E5B85E352AF +:106AC00038A7E6A576D43FE27BB31E8A7CEFC7F9F0 +:106AD0006E053A1AC9F27DF07C013FA720E627E84F +:106AE000DCC3D779205D73E715779CA7EB9445EA63 +:106AF0006A9E49E11409F83F497361F98713160941 +:106B0000E6E50A2B982FEFE2FAD1AC07A9B8E074BA +:106B1000C3FA798ACB8DBAD32C0FB1AED49706FEC7 +:106B2000FFDE59DAC83CE423AD18CABC2CAD04E63C +:106B3000D9EC66788ECDD346435DE40B98E7A9E5A2 +:106B4000B5E71D8C857609E3891FF421DC370371D5 +:106B500096049EC790A0B9CA408F256C21982790B3 +:106B60001C1F6E8E81F8DF26E2817353D97ED50219 +:106B7000FBAF8C07B4D550D69DE6F7E694123C7770 +:106B8000D99E47579B8E7974C06F7A7A9DCEE73134 +:106B90003D8FF125B5436EC963F39A06A5B0430452 +:106BA0001F756657E8F87076DED5F1E13DD0FE2A14 +:106BB000F8706E1EE3C379793DE0C3A579ED7CB82A +:106BC00004DA77C7870F71FE7BAA1B3EFC39A7CF7B +:106BD000E7F23A95A30FE54595A38C1E04BD031F6C +:106BE00082BE6FE0FD51F9B9321ABDF7802FEBF389 +:106BF0007A6017B6F7D743FAEFCCFE8BCFEFDAFE09 +:106C0000DB0279E3BAFD1EE597A7617E945F7E0102 +:106C100025E5972D8C5F54965F6EE2AF767D136607 +:106C20007202F2F3F4795ABFCB6BD737DB01CEE6B1 +:106C3000BC9C31267FFE3B9CBE9B7899103E4A400F +:106C40002E50B8BDA4A7D7E739BFF847B3BC53AAA5 +:106C5000D9CAC0AEDC778ADA91003E2E0FC66C6EC0 +:106C60003D007623511AE2E11EACCEE0D42B5F1535 +:106C7000F99551E144C7FF633479DA04787374B449 +:106C8000E7CDF8DA91C7E83CC4E1F15DE721E00720 +:106C9000F328C279A896B53A3DFF41445EBD0F780E +:106CA0001B3B3E2C139C57301EE227429E9201F460 +:106CB000FB911DBFFF24F2FD27B0DEB11AFDBE20FF +:106CC000F27D12B8F233408E51798676B286E71C97 +:106CD000EBDC8C1ECC74DF6863E724DAF1D5D00FCF +:106CE000F1E5557D5F42FF8D0A3B4FD258EF92D8B8 +:106CF000394196EFFB5E8686FC1A450E85AF520E33 +:106D00005DC843FB4CFB1794DDC9A1CB9CBFA91CFC +:106D1000FA3F681FCAE95A0EC5E7337839F2997C01 +:106D2000E94C0E25F076BDF225839F522787E2F3CA +:106D3000A3C8A107550687287C9A985F0CFE15CD3D +:106D400095CFF834295FA7D7E877C9D09F17BE4FF2 +:106D5000C5BC33CCB7F093384FB47D869AEFE86961 +:106D60001EB59A9FDA31FF8C749347BDE1D1900D27 +:106D7000E02DF29CC4B8E6FC6981C7AAA65523C8D9 +:106D800050C8D3BA3C08ECCAB347BE41FFC8DECCFA +:106D90004A0FACB3E5B55186BC2C31FE7DDC9F3685 +:106DA000412ED809FED973076DE8F79489FAD418F3 +:106DB0003A9FEA8356124039C5EE2910F130EBC1F3 +:106DC000BA56F0C75B89EEDE28DCCFA88940B7D67B +:106DD00083ECFE2692C2DEFB897D15DEB738DA1819 +:106DE000E74FD28C71FEE4F25EA6B8BF31CEDF670A +:106DF000B631CEDFD7678CF3F75F34DC14F737C6D4 +:106E0000F907AF2833C5FD8D71FE8CFAE9A6B8BF2E +:106E100031CE9FB3D918E7CF0B18E3FC0BDF7AD93B +:106E200006FBEA212FDC678AFF1BE3FD1420AD99E6 +:106E3000BAFB648AF6AE36B49F1762F7940D0BAEB8 +:106E4000357ED7C0EE39F0D3FF013CBF203E1BD0CA +:106E50009942C26FF687FC9680E409D2668BF7EE02 +:106E60002A817238F78B2FDC6CBC1F6171C058FF10 +:106E7000EACFE507210FAC1A9888F653FD82140873 +:106E8000B83BC7FBD2178CDF0B3FEF52BE9E73DCC3 +:106E90002838B745C6F3CC663A59F8D6ADFC5E3112 +:106EA000AD15EE8F107010F4E2E2F422E625E0B1A9 +:106EB000545E867C2EE020EED7AA32ADBFC37AF7AF +:106EC0006EC5EFCCEB36AF6353BE31CE473AF08997 +:106ED00083E509D175419C5CF6E79AF8C40887CE32 +:106EE000E0D753BE51391C62D28C7C13ABC699E9F2 +:106EF0000EF16D86677CAE919FCCF0747AFA45A551 +:106F00002F713F2AAE07E2217B25F2B4D411AE8B5C +:106F10009AD6D7F58F424F840430CFC30CDFE67C7E +:106F200063BC6597EA6B01F978FEA30B32E2D517D3 +:106F30001A01FAAC8BFCB383BC7D4FE3ED87F2758D +:106F4000FE1173BCFD2CE449EACEAB48ED78D34C7E +:106F5000799207FE0D7124FA8DCF067ED8728F9D2F +:106F6000DD1766CE5FF3FD331FF5B046D00F788E88 +:106F700078D6D0FED6387F3FA41BBFC8B1FC62963E +:106F80005F00FA6B6C3874FE25E85E6975C138D114 +:106F9000EE29359D3F3C0DDF77760FE4F3C49B4728 +:106FA000A2C4ADC5FE55D8ED749F74219FD9331787 +:106FB000A1BFF67D52BB7DDD753F228FACB352DAA7 +:106FC0002FA35E0D4B719E68F798C50E31EEFF75CD +:106FD000E73D6387E8F468D5F7CEBF09F3A0F07604 +:106FE0000CA1F3743AA97D23F5C8BE71413F4FC58A +:106FF00027205D87DF9203396EB8DF4A4DEC55D00C +:10700000F19E2691575803F73025C3F3BCC4AEF266 +:107010002FCA4CF76099EF33AA1BCEE695CED7392D +:1070200085DB5125BC2ECEA5097F5CF56CE66FDEB5 +:1070300064F263960C71627B6F665909ACBFCE2D0A +:10704000A1FD5427498678D2F1FC527CEFE1FD97EF +:1070500000EF15E3F93A9C578A691F7F8EB73F9777 +:10706000CFFA857BB180FE6CB21C159ED70D61F303 +:10707000FF3BB7A3BEC3FD34EFC78CEC783F8DF95F +:10708000FEC489B9352D201ECC71DFDF75773FCD69 +:10709000FB13A3C67F01BEF1BD22743F6388F19E3E +:1070A000C4609C6FC354F047BC237BB6E157AD234B +:1070B000F4FBB48A21CC2E5DC7F72D1057C2FD0812 +:1070C0002FCD70AAE0706AC8F45600FD6DB2B5DE2F +:1070D0000FF41BB4B1FB42C31F101CA7DF22AD1974 +:1070E000EAC55E15CF57D4B98903EE190A0FB3A0CC +:1070F0005F24C5E71A0FF7FEA66C917A0138855C0C +:10710000B02AC4EFA4F4B276881BF1B08EAC6986C5 +:107110007B5112B77C4DD2713FE11AEF0279348F67 +:1071200044F5733ECCE963DA33E90AECCB12EDD1D6 +:10713000EF79787888C863F33E04F431D67E6484AE +:10714000847A82ED43606B8BFF69B318CE358BF286 +:10715000BD8C717EF84ED0F3F532A9D9E56074A6E6 +:10716000BF7F6DED90ABF34F172F2251FDA8DBF9D8 +:10717000BA72546F03C0BDF87D15E31F0B85DC9F09 +:10718000672170CFE9ED9C1C6FDFC2F2E1C9E52BEE +:10719000576461C713EC9F403C62E1326700E21321 +:1071A0000B9BDC78FF1F592461DCA4BAE99017EA35 +:1071B0000B478E74A1BC8C9724B807124C08261F6D +:1071C00015725CD09FCC8144FB9FCDF50DD52BEB88 +:1071D000E2E9BA166ED9DA0CE72CFE410D08C0FFC1 +:1071E000267E6EDEBC2E713F5DE4FEBC4F36E9EFBD +:1071F000E7B6ACFAC707C6FBF3FEF1C17F737FDECB +:10720000BEDFFCE303B89FDB7C7F9EE0FB8F64DF87 +:10721000470FD37FDF4695F28AE1502A640EE229B8 +:107220000DD73983AFD3FF0D918EDB2370B9ADE954 +:107230002D84F747563A1E651E6B19038DF5A14440 +:107240008C2F8B7CA499F68609A0D7CFDAC28570E3 +:107250005EECEC6B1F0E84BC834F7F78DE097908EF +:10726000FF54C24E787EE291F79C1AC5EFA78FB00B +:107270007BB6EEE6FA52C0ED1F9C1E0A0BBC87815E +:107280001EEE59F96D89FEBE20B22215F5DCE280B2 +:107290008C292C428E2C7D211E2CB9F6FAF29DC928 +:1072A00086BAD07FCB63484D34BFA8AB80F1CDE226 +:1072B0001D5B6DFD5518DFD706E39F80C4694A3713 +:1072C00027F638D14E16F3A9DC31CC0676D53F9B94 +:1072D000624810F66B4AAB959D37D5A648945E7D03 +:1072E0009C2ECDF37CF3F578EC6FFE26266F2BE811 +:1072F000582B285C7D4DECBE4FF33AE67FAA4EEC4E +:1073000043E13DFF716AC1A8ACFD23146FBE153F78 +:10731000C2FC71F33A2BFCE6FB3D3594F70B397E4A +:10732000E7D61BDF2F6CFA31F6338FA8EB204F72B4 +:107330007E83F9FDA42F8048179AF2D16D055C1E5B +:10734000979051208FF7DB3312A39D3B15E5A9954C +:107350002E64A22F57DAB13CB192607978888A7096 +:107360005FD674E841A09FAABDBBF01EA696C0845C +:10737000144AD6E4C6A6DBF1FEDA1B79DCFCAE8E3D +:10738000F78BA6151443FE91E9BC375FF71C8E07F7 +:1073900071FE7B0EACB7109E2B17F4EB397730C320 +:1073A00001E3BAC5BA46D175C93D5F97588F589F5A +:1073B00078BF9CCACFA8F1704EE787B9BC9ED7387A +:1073C000ADAE1F05C59AD7BE40FF00E1FB92F6FBAC +:1073D00091ED3F6E85798F27A67D899FBC4F74F410 +:1073E000B69068783FAC99AE049EA9DEC6EFED7CFE +:1073F000DFD24E4F4D3F41B8087CC30D82FA7BA9C6 +:10740000285D19F609948E0CF5F90DC6FA196B680A +:1074100010F0FB42D3EF459C31E5D388D25390CE98 +:10742000E0A06A13E1DCD07CE2AD6379C7ECDCE17B +:1074300009A5E1CD87810F1B191FFC93E37F6781AD +:107440007716E09F285A21DE17B9BAAF0C171F57DD +:10745000AC935CC05F736B87E1FD43C38986FDDD40 +:10746000D589DDF910E7FFCA1A2BB15163A1928EBD +:107470000172AE728F2CEEFB724CED0DF7D7303EE1 +:107480005AFEF82E5B5F5A2EAA59C8ECA100E31BE6 +:1074900071AFB6A03FA19F96AC6B46BF03DD6F19DD +:1074A000F8AB1ACE8114021F9B9ED7DC8878A836D1 +:1074B000D945DF2BE0FB330FF1007DFA1E74DAE1D2 +:1074C0001C5977EB261DFD49E86F3A77300BEDE547 +:1074D00073AADA07DAF912D83DFE92E21B05CF292A +:1074E000BC508F8657C5E3BDC6472EC944C5FB5562 +:1074F0007CA3E0BC7FE8EF0309BBAF8DD1AB586F35 +:10750000B57D1DEEA3AB4DF45A41376CE027AED8E4 +:107510009E8C796AB4FFC2BD605F6DB7A2FDE4279F +:10752000F7A5C1BD1ADEC7D8BDBC957B93701F5FA0 +:1075300059CBE24B953B92F09C30DD47BF0FFE19D3 +:10754000818F23B5E36C7D115F6EBC2F8CECB5FA97 +:10755000F93DE748E7024F1DF7C1263CD537BF99F3 +:10756000A676DC17EBF0D4D6099E0CF758FE5AC865 +:10757000118E27F208973FF7BE910571B57335B1AB +:107580001E39CAFEAAFD3EE379D7623E9DF03F96C2 +:10759000F713BFAFE0E90D783DBFAE18F166C657EF +:1075A000F97FE6225EC8DF9D04FCD27765907BA65A +:1075B000D3E7F7488C5FEE5A33A91CF4F9810266D1 +:1075C0001FFF95CA2D2D879043546E69546EBD4799 +:1075D000E519D43F589986F50F57AA587EBC321743 +:1075E000CB366E170A3EA2846003BBF2AD0266EF93 +:1075F000BC5520FCC10FA4816951FE9FF78A2DE084 +:10760000EAF5CF9F3981DA3BB768467D387B8651F2 +:10761000DF85ACAE89707ED9FF38BB17AED27B9DBB +:10762000A13D5154DB34D8D7E78E883C477E536D5B +:1076300070FEFEF629C986F633EBFB1BEA470A54B7 +:10764000764F507986E1F91D738618EA15FCDE5BEA +:10765000A28E46BE7980E7C912329AE185E7DF5CE7 +:10766000A819D5E7FB74BE17DEB6E27B333E045E95 +:10767000E76D96898FF6377733955F748A6D0D14B1 +:107680004FF4BBAF3E72C2591952B763C4BBA36972 +:10769000FDC80E96AF7BA436F9A7603F1DD9919A1D +:1076A000007E635F9DCCED0C17DEF726FA1D57BBFD +:1076B0000AF3722A023178EEA2A2C5FFACA8C34F2A +:1076C0002EA089077CF3BE1C084A883FE6F7F875B0 +:1076D0000CC62D4E50BBCE45F5C40989D4420907CE +:1076E000C512E9FB7FB5A60680AFCBFF236B6940CF +:1076F0004FBF8EE5712909FBFBF250D6B6B5485F46 +:10770000EACE20F26F0CEE8FE686D8FA8834BC3FC2 +:10771000E0FF4412D192E82496DFF7E1670AC5D36F +:10772000E2ECD642B817678E3B983A8B7E77AAD1A7 +:10773000CAEEE9A7FDBA687DF96F62F8FD8F5A1F9E +:10774000D86F44E019288475A7F6F3A60EA5FCF1BE +:10775000E5824021CAB5475291AFCC706FB3F910A2 +:10776000BE7EE003292227237CC6E28D54B8F505AE +:107770007933D7EAE90DFAAA6D9D95DD8FA76809DF +:10778000ECFEC9DD48C76D8A3A11D6DD56EFC6FB5F +:1077900083C4B895EB648DDD5F49E912DAAF977D5C +:1077A00070DF8FD05BFE7AC907F70299E9E6FE7BAE +:1077B00047619EBFD9FE15E519CAAB3E9D1DB1E4D8 +:1077C00035197FD7838C0C29330CF783B1DF3F2128 +:1077D000BED186FCDB65E97FFACC6141BB2611F6A0 +:1077E0004527DF9791CE4EA63794A465403ACDFE4B +:1077F00092EFD3FA5753FDC7E11CF13D837D65003D +:10780000D7A59675CF4A1638777DECA770CFEE973F +:107810002F5A3D30EC925F2F1E8C71096E7F77944A +:107820005B9AB0177AC33D5115AA0BF5B85A2B11C4 +:10783000B6FE00CEF34EB2F331C09B6B197B7EAC2B +:10784000D8B916FC03734DE7D88EF17B3A660C6508 +:10785000F244E8FB0D4399DD34D7C2E89ABC2EB15F +:107860007BB4F8EF5F087D20E4B590FBF38632FB34 +:1078700042C86B6A39A0DC5A00B747D1752E7B210C +:1078800086F9D355E202382E6668225B873279B1D9 +:10789000C4F6E293C04B0B492BEAD32FAD8105AD63 +:1078A0006EF87E6B6D2FFCDEEA41FF32D72F70CD74 +:1078B0003FC8A5859CFF963748781F14E17A723E31 +:1078C000EF9FBC608DE88DF428FAC5A457E673BD20 +:1078D0003A9F98ECC006A3BEF3C6B3CDFE123A2E73 +:1078E000E8CFC8BCA8FD4C61B7C01778F3669CB759 +:1078F000E4094499C742120EC2BD58CB77307FBD10 +:10790000795EE675F4749E0B3CD3C6278DD48D6BDF +:107910009AB780373AB8757810705FE067F05CD03E +:10792000C4E21F9F737B4DC46BCCF85F48BC3743E8 +:107930003EE2C28D547EBA23F420E860F1AE00C668 +:1079400067BE220D090ECA07CB36EF9A798D0AFB66 +:10795000FC43B80F99D32B9865492224D97FE8C9F5 +:10796000F281DDC727FE577022FC7E71FC8EC26556 +:107970007E23BB3F5CD78EE7DDFB91AE17F9FD366A +:10798000F0DF2EE2FED0EEE659ADB073FEDDCF970C +:10799000C1F17F3DEF778776661F6545DD6FB5DB0B +:1079A00045DDE8E34FACC181A08FC30315D4471771 +:1079B00014CF87A529A09FB370DFD099BC5DC0F517 +:1079C000F27CD0D3B43CBEF965BCE7E9F38D2F63FC +:1079D0003CD8F6E2FC04B0978F6F9EFB53380771DA +:1079E0007CC75CD4CB0B9F167AD967D3EBFB719B1A +:1079F0002B9EFB21D0E90BB118C758D0E2E3F63833 +:107A0000DDD7805CA4E3A19ED8C8E4E042D05F0546 +:107A1000A8BF72A0DD830B7C3940EFBAE7A8D71E60 +:107A20009CEB1B85DF135790DDB3EA0A82FE12FA46 +:107A300055E8DD57FBFA2E0F053E92DFFEE0077496 +:107A4000FDA777CBE8D3592E6F1D04BF0FD3991C28 +:107A5000FFEEF0B6B4C3DBDD03785702BCD11E6283 +:107A6000F03E5ACFE07C6C1D837BDD8E8C04D80702 +:107A70001FADCF403BE8E88E2C84F7BCB514DE6820 +:107A800007AB463BA89EC21BEC7F80371DB7B245B3 +:107A9000E5F0F63078D7733DB48E95F33AC0D57FD4 +:107AA00037C895077F19E3C1FBBA6383A9B04F3983 +:107AB000B14B2690A7D16E27717B46C0F95FA4E138 +:107AC00059B0AB3AD837EB6308F87317FFCE89E7A4 +:107AD000A4BE944AFB00024E35FC2901C68B8CDF04 +:107AE0006ED7780A8B75764D0FF15345BC788EA111 +:107AF000AAE94F1F815D0FD72CC1BEBF4ADC8FB1F1 +:107B0000D7783F86A4824CC3F3B2763BD0C100F352 +:107B1000FD213EFCBD9C8B595FDF7D1FF273385BFE +:107B2000EF57AF8E0B5AC11F15DE2521BE973F5070 +:107B30009A504A200E5783F3985AC8F4B3A469E8C0 +:107B4000678CA1741347C7F3C265C2F05C7531BF7F +:107B5000E3163AAE33325FF3F39B4110817E7744F4 +:107B6000F753FF908FB35CB6E03E64998DED4744C8 +:107B70003ECC5D85CC6EB8AB90ED4BE616B27C93F7 +:107B8000B3903C45FB3D7B7D0CCFEF1E8FFE4F71CC +:107B90003F8222E0E652CE187E674209E3EFC07CC6 +:107BA00076ED21BC7FF733F8168D6B8A8012B06BAF +:107BB000D8F7EF5AD9BD2E778EFE13FA4D3F8BF5CD +:107BC000AA607F7D966AF7001DF9E11E3C4A7F3F5F +:107BD0008A63FE729292A8007FDDC1E5ED5D63626B +:107BE00034D04B778EF991174A3A8E1F821675A5BD +:107BF000071E033ABA27EDD8F7EC7449AB2CCC6ECC +:107C000059D58B601E511135DFC16F4B5FEDB992B5 +:107C1000DC15DD18FDDCCBC09F7B2D6104351AE13E +:107C200069A853B8627DC34BA5B3360E20E430512A +:107C300087029E97014C800E2A12D12F700BF89567 +:107C40007B41A9207D4D5788DFC2CA7A07DEFBC180 +:107C5000FCCC37F375DE369A0413E9FA826F118390 +:107C60001F7E56D012CCA170BB45093603FC2C7682 +:107C7000D50AFB026FB9341CF6CBCB56F76CBEBFEE +:107C80007A69CAAC8D6368DDC2F21CC23F90F09E77 +:107C9000963B2973035DDEAD90167938C31BD05D2A +:107CA000752F761F79F85E89C79398FF5FE0651896 +:107CB000ED5E0FDF3BF9FC683FF509F0BD2DBA5FC3 +:107CC0006937A753616F2EE57CBA54D0D90E237F54 +:107CD0001E167C02F62D85DB9DBCEC8CCEFFCAFB0C +:107CE000FF6B21F35FBD7695E32D8F2141FDEF56AC +:107CF00089716FE1E53B85CC6E16F310F44BB85FEC +:107D0000CA422506D0515BC31AB4971699FCC444E5 +:107D1000EFBF92A3D5DBE58EE50A94B6F03C988FD1 +:107D200074432CF2CB9DB69D59EC9E1963BBE50DB7 +:107D30008CFE973BEC68078AFBC5C53E40D88D8B0F +:107D4000C1DE037BBF91D9B70AB7CB2BE87E0D8884 +:107D5000CE4A42B5FD61DF5CAFB37F519E717FCFEC +:107D60009E613E18E74E871DE39F372F33DA4B564F +:107D70006E475A3BFEFE9D31AF84DB4BE6BC129949 +:107D8000F3316DCBF6313CAF44E1F6B0A0A30F0B5D +:107D9000ADDCAFE237C4F1E790562BBF778EF9F731 +:107DA000B89E9E203BF03E863912BB67EB6CA9D390 +:107DB0006FA172E9137ECFCDB91A76CE79CE0FD8E6 +:107DC00039DEBB121FBC19ECE239093605CA4FF87F +:107DD000EF7D7DEA4A4F9C4540FEC83CEEF4935946 +:107DE00010BF59037294D59FD2C6A0178DD79FF8A4 +:107DF00010DECFB84CE78DF50DB3343ADED937F845 +:107E00007B3FAD437CE831C1C79B597D9378BF85EB +:107E1000D51F17EFB7B2FA4F44FFBCBEDEF47E9514 +:107E2000E9FDCF597D70D1D6597EB0E379DC6ACEB9 +:107E3000B512C6AD34E0330ACF39AB83485F732C3B +:107E4000FB5959468210B7ECAEDDE422AF06FA5A70 +:107E500076B639C15E99314CC37AFE505F7E11C54A +:107E6000CF926992DF06F1CBF703D95C9F45CFC76C +:107E7000E7FA699287F527EC5FDACF88A2E2ABEFE9 +:107E8000E7A3A20EFD8CF92EFD34769CCF84EFB2D1 +:107E9000AED861C67E843DB86DB8E6837991F1D7DE +:107EA00019FC9C4B1FF524823D49DE65BFBBB574B0 +:107EB000F5CE412368FF4B5FDA376881CEFF5075FE +:107EC00049261A95C3D597242CBF6AFED806F74BCE +:107ED00054ED69B64D2C80DF0B6AB68DD3CD6B990E +:107EE000C833262165BACE9E995F64E17CC57E7752 +:107EF00068E94B2731FEBCD4B2F3F8D3C097D73230 +:107F00003FA4797D53F9779F417E4194FDCAD222E7 +:107F100026879F1EA92D01B84D0198D1F6E3D644BE +:107F2000CFD3D8C3FB9B13C7E4FBDC12A75D2D8224 +:107F300078B86F0D9CFF5BB0C53D1CFCDA5387968B +:107F40003D50D4A57F38CCFCC34DCC3F3CA757EB6C +:107F500003547991DFFE36F814DCFB3CF929D21E7C +:107F60004F06BF2B1E8747BEFB70D6F831E8EFC324 +:107F7000FA1345879E82F3DF07F9EF31DC356A6833 +:107F80001CC885903BDEE2A2FC3CA3A0E2B780BF08 +:107F9000BB465D3F119E97C638B32B589C01E962E2 +:107FA0004681772DBC87F6E0DFF1D998BFCFF76720 +:107FB00019FD7DBEC2785FB4FC857A0E87DF16B1ED +:107FC000F31B072D749EC323F310E35303ED815677 +:107FD000DA5FDBEABEC3E09CE5CE82D297909EF8E2 +:107FE000F83B0B7CBFD08F0F1409CF7B3A8FCD4568 +:107FF0004C9FBEC4F1E61D43E94D27F7A78F8F378D +:10800000D4674C49269ADEEF3CA3BFA13E7B4E8647 +:10801000A1FD1DF38618DE4F8D691D597315767FFE +:10802000B5D31907F9119F36FDEB6F77823DDB2839 +:10803000E3EF172D7E6DFBDFE0F7BCCED10527A364 +:108040007DAAA2FFEFCB83EC775889A229FA38D614 +:1080500069D2FA24C47D75F191A8F163111F59EA20 +:108060006AC13CCDFF368EF56E118F630D87D475D6 +:10807000D0471F0C823C952A075BD7E97D47F0F774 +:108080004C20CFE34A09C47F091A89D59756E1EFFE +:10809000C88DE3BF275D5DC4E473D5807B15B8B799 +:1080A000A09A9620FF2752399548E9A4B5990CDD8E +:1080B0000379DB6E27E6D52CBF742BFAF50FC6F9D2 +:1080C0000BEEA5ED96D64FC27AD5A578ECF7AF7238 +:1080D000EB44CCCF7F45C2F8C9D4FE77AD86F943D7 +:1080E000FBFBE978537F7B6339C0A96A0FCBBF994B +:1080F0002A1F1E09FD2C6B9884DF4F95C94189DA30 +:10810000498997EEC47EA7828D43EB7289732DE86F +:108110005DD916CCFE05C8159B13E54AF5A558FC9C +:108120006EF238A69F2F16B17D8B35C4E635E1D2AD +:10813000347C2FF07FB928DD709ED49ADAA8C07DF8 +:10814000ADD69084ED6FBA34044BB1CE3FE7FE124A +:108150007F9FCC9A7A6122E4DFFE394572A1D9650E +:1081600092BBE76B4625EAF7D3FF0F762BD097003B +:10817000800000001F8B080000000000000BCD7D78 +:108180000B7854D5B5F03E73CEBC9299C9E4C9843E +:108190002470024908106032791042209310109127 +:1081A000C000550906199047401E21BEE295FB67A5 +:1081B0004212088216B5BF45453A205AB4B6372256 +:1081C00056DA224E006DACFE366A1F786B6D502F6A +:1081D00082458DE0B5F416E5AEB5F6D999394382FE +:1081E000D0DEFEFF1F3EBE9D75F63EFBB1D6DAEB3C +:1081F000B5D73EB978117ECA19BBA895E6F332F31C +:10820000263276D37989790B18FB3ADF9BE04E66EC +:108210006CD6861EC592C418B3599C4F66025C92F8 +:10822000AF2ECF0BBF271FA961EA18783FA9D7E867 +:10823000B5C1FB504EB185EB1731E6ED0098B11E8C +:1082400065AE3DFCDCE53630968CCF9B192B827EEB +:10825000FBDAFD8CB114C66E7632FED3088D52194E +:10826000336AEDC5FBDD12D4C1BC022F98834FC227 +:10827000EF291EFF6837F4D35DC1E6EFC77E94EEA9 +:108280002173ECFF73F3AF9699454AA0757871DCC2 +:108290005925AAE15EE8CFDDB78E0095DFB68E0CDA +:1082A000ADFDAF65D6D801F3F8757979B717FAEB5C +:1082B000BCA7A04056C3E356B84D8417E6ECBDC03A +:1082C0000A195B773856BD17D6590D3442B8F725D1 +:1082D00073704F263D67521296E63D12D4AF73F489 +:1082E000E6F860FC292F5B436C2CF4FBB25561303F +:1082F000CE1B85FE0AA4E794974754490E98E421C3 +:10830000B3C2A0DD75E3BC9588B781E67B318A4FA7 +:108310004429D6CBAA261A583163B759F86BD3E64D +:108320004881B838C6FCEDD73206735D7C7E1E638B +:10833000C04F4BCEC712ECDFCE9F9FAB1F340DF169 +:10834000786E034C1AD6B1648334E600AC8BA97600 +:108350007736E0A13A6DE146E640BC1B68BDD5A387 +:10836000E3832DD0F4BA29F680218EE8D185F45824 +:108370007D3E9EFA5B733E93C6597B3E91E075E766 +:10838000AD542E393F9A9E0BFEF6217F437983C769 +:10839000BF1EF151DD72CD741CC7BF31B5D06F8BDC +:1083A000E4179313F90AF8C5B53C821F5A3A815F66 +:1083B000ECC42F8A17F0EA8332925F6623FDF31034 +:1083C00013CE692930EF59AD99867B59B8FE4EA47A +:1083D0007FD195F3FD2D1ABF2CB185B20DD09FB181 +:1083E000DEEADE08F33A9BA44E43BC346CE1F86B42 +:1083F00030FAA6D861DE0D8F486EA00CBBA5D86EF2 +:108400006180A7E2E3F5267F04BFD79C1FCB54C051 +:10841000C7BCF35954568FF1B722FD179FBF41A334 +:10842000D3582A995A62C0F9DC8E74557142259C42 +:10843000CEDAFCBEAC1F3FE82E18FFCB378C545F62 +:10844000E40DDC8CF33106CDEEDD309F5356BF8C4E +:10845000F43D95C19C0FC1144F1959C009F4BA6578 +:1084600087CC02D0FF5228FD509E8A67DE780FE24B +:1084700013D699CBFBBE08FFFF53D93E840D07BA34 +:1084800036FCFE7D6518632B73BAC786A0DFDA8AD7 +:1084900050F28DD0EF99BD467700C65DDDF976B11B +:1084A00001EA3FC9F40E6232A06AB07F17D275D5D7 +:1084B000DCE04F8C00DF7ADFF38E096A189F1D4ADB +:1084C000285B81F73B008F019857C736797A90F087 +:1084D000CF62E78C09F3B5E0E368FE5E757E38E1B4 +:1084E000E75CBD79CC01E45FE0577CBE46E3F35B1B +:1084F00091EF890F39BF0B3E5EA37079B5C6161791 +:108500000CC03A8C3DBC5DF5BF01FF01CAD71ED837 +:108510007D7F29F2DD1985F87FB5B64FAAE5B9BE92 +:108520000ACEFFEE1678FE62930B9015E6FFA9E7E0 +:10853000E750BBB8F337517F82EFA3E579C4BE6142 +:108540000CDE7B31DFFF16E2A9F2477F7BFEDFE125 +:10855000D10C2594F358129676E29F7F96DCFFDDCE +:1085600055F2FF31ADFD74335BE4CBE3723DB2BF36 +:10857000144FE5695CC7676E89CBDF7FB2BCFFEC47 +:108580002AE5FD1FAE50DE4BF95CDE47CB7706FDDA +:10859000A17CFFFCA5914194FFEF33D007A8F70E13 +:1085A000C5AA4F6AF29FF4434C5CF072F2FFD1C24D +:1085B0005BA4FCFEE5BF21FF1F90FF7FEF3E11FC97 +:1085C00018BD5FAEDBDA4D7A81BD283194BF62FF02 +:1085D00074C570BC748DE27A20BC6F24DA570CF637 +:1085E00055B614B96FF6DC5F8AFBE6F324770B1BF4 +:1085F00078DFDCA4ED93459A5E10FBE3D17C7F61CC +:108600007EC4FE58BD3F5A3F5C9EBF6E4AAA67A813 +:108610001F164119C95FE63EFDA0DF1713F2AF6ECA +:108620005F8CD0DA7F1B5FCDFCE7F3D5CC01F8AAD5 +:108630003A3FF9EFE7AB687E3A57FFFB4215E67326 +:10864000AE10F82833CC3FD7BDCEB8DD30DCEE7E9F +:108650009245F0892923D882ED2EB27AC463B43CC6 +:10866000147CBB05EC009CA7A07B574C206F7DDEE3 +:108670003F4FFEDD997F7576EFD2FC2B931F9B91C8 +:10868000CED8EFFF9CBDF8607F74655E6E1784E9FD +:10869000629E47765C08149C34305D8D3BF8FE1278 +:1086A000705B48117A3711F52EF0CB43FF08BF54A9 +:1086B0004F815F0723FCBBF9DE74E8EFBB1A1C781F +:1086C000773ED2E7861251FFFB1DDE2C9433F06B10 +:1086D000298DE06516C2AF061F3F5E85FCFB505F2B +:1086E0007D00EBA796C569EF332FBA1EA2FDFEFCF5 +:1086F000DF1EDF46FB793BDFBFFE1EC53726022E9D +:1087000004D81E019744C13B797B87D2C39C848FD8 +:1087100020DFAFD0BFE4E1FCE38BB04B8092D3E22B +:10872000D1AE3C2039EF05FA2F28FBDC84F40AAFE8 +:10873000BF87D6BFF690A4C11F1DF70269161CE0C3 +:10874000F0F1FC533B028AD61FE079B58666738749 +:10875000E495818EAB4BA4E0B0CC4BF17CBC4F3E9A +:108760008979802AD6BFCF4C8557F73EEE6F7A7F46 +:1087700018BD1F325FC5F83796316FD07669BB538D +:10878000A2DD058045FF80CB79B0BE60DEA5ED7B24 +:10879000B5F6DD068386AFAF7720FEBA4D029F1790 +:1087A0007678CB80FE8CC3FF957F617E208F4FDF74 +:1087B0001BB5FECBCDFFBD7CBDDD803FAAFEFDD04D +:1087C000E5F0F7C125F8D3F8A74ECF4F718AEFD85F +:1087D0003998475C92E444FB78ADCFBA0DFD803008 +:1087E0007F986B703DDD56D6C7CF7AFEB7D454C1A3 +:1087F000FAD632511FF308F93986BEF67C3FF4F100 +:1088000017F3E6023FA10980EF2779AC8F046C448F +:108810001FAA2738EB32FBA1230A2E8BDA3F1AFF5F +:10882000D3FE45390FF8C9EE47CE1478387E3E9511 +:10883000D87C9493DD95DC5EEC1EC6CB791E89EA6C +:10884000277A381DA66865774C041ED2C374869FAC +:1088500010FA2311EB263CD52469EB0E8CAC990958 +:10886000EBEE4EE0F5D5FBB31F099485E1E8FE661B +:10887000EF1F59837CD3D77F60C4BB88D71A0D6F95 +:10888000F3F6E7BE1BE0F250C27DB9861804A87566 +:10889000400AC8B0EE35C817FDAC3BCD73C9BE0A5F +:1088A00044BDEF355EE6FDCC4BDFF746BDCF8C49CE +:1088B00057F3BE46B79951749D1E45D7AA28B8569E +:1088C000C0419DFC137271C9C107DA52601EB7EE38 +:1088D0009350CD44F07309F1F3AD4EC1BF13DE45A3 +:1088E000791FE6E75282E776087E9DF808CAFF39CD +:1088F000280F4BC3F03C94170497D578C745EA8BF3 +:1089000049547F63BB683F99E005ADA2BFF2475071 +:10891000BE0A3A02FA6A70BC9A42A12F2ADEC5F654 +:10892000AB0EF1F737792ADFBDEC7ED81E85979D17 +:10893000517020AAFDF7BE45BFB446BDBF21AA7E37 +:108940005B14BC230A6ED7BFBF78A944FB7031F01B +:108950000312E2DBF6E5C39E3E3BB54F9F4A36B2BB +:10896000DB74FBEABA160E073DB36BDA6D11F07ECD +:108970005F8D266F695F1819FF01591B407D651CCB +:10898000405EDE3F105FE646EB5B5EFF27FC351581 +:10899000ED60A6B30B8ECA7AB853D6E61DB8F9DDE2 +:1089A000DBF3F0A18017D6A07F70DDF7F5EB02BFF7 +:1089B00055ABBFA9A6AA2CC22E6137119F88758A14 +:1089C000F6D3BEBE28E3783FDDBFA0662FD4D756CE +:1089D00086B2EBB14CE025E83519F5E63A2D2E3399 +:1089E000ED25D9877AAD362694DD106987B08E1CC7 +:1089F0005C67E73D32D127D002F4C1381B739B304E +:108A0000AED21917D7F814B43F7A8FDC887AF4FD08 +:108A1000C6C4149C7F6A01B7238FC60D4D590670DA +:108A200067EC22930AED3A374FA5F288ECDDD40BC0 +:108A30007BED379E5535B691581F47F8E9DEBFAC40 +:108A4000A619F6C13B1E95DEF72738530EA2FD7C12 +:108A5000AF913DA9E27CDCBB886FEE33E7A31FBD7D +:108A6000B879740ADA934BFEF79C69A9D06E499BDA +:108A7000D12D513B3616E7EDBF77AA09EB97B66AC1 +:108A800065E01A2A5FFEE6891607B4EF7D5C72EF97 +:108A900081F693BEEC787D2CC02BDA87BB913487AE +:108AA000CF1B9813C6F960C788A00CFCF8A1B5FECF +:108AB000D559BC3DC3F62B2EA86FCE2AC4F6B2738F +:108AC00023B43F09CFD11E3EB945DE23E1BC1CF6DD +:108AD00018099674F26BF54DB46BA1DEB9119E9F27 +:108AE0006C5B998276D649497548B0FE5E4F638DBE +:108AF0000BF865C50EB346BFC6D4C5B0AF171BFA99 +:108B0000F885F4C7F2780EF7EEBFABE64998FFC9D7 +:108B100047463810CF6B0BBC5F78501F157ACF7A61 +:108B200092719E5C4FBDFC8DBC08EDF15F9C59922B +:108B30008271BB0B1A1F1F3EBF24654984BDB3FC65 +:108B40005385E8FEB249BD1DE7F9724C8684F12CCD +:108B5000A07B22C6BD976A7E26F06FE3F3FDD83D69 +:108B6000BFF7C844A78FCC8DEC43D8549D5BAF9F13 +:108B70006207BC74BE28111D96327F0BC2ECA0E4C4 +:108B800046FA45BFFF9BB195D682A248FEDF4272EE +:108B900096FC0D80139FDF44FA906D800713A03C74 +:108BA0006A253FDDF8AC3568057C2E4DF24EC3F6E4 +:108BB000CCD59133D71EB14FB5F67F0CD8A9FD1F88 +:108BC000A13DFA7B7F0CFCC1CE6C97DAFD2B1CF625 +:108BD000001A1F1FDBED0AD2ED7DA5E9E4DDF0DE12 +:108BE000F2C78DA427963F9EBCA117D701FC95CD57 +:108BF0002E5D87BFC048F81D70DFB2EFD754E9FC87 +:108C000089872FBB6FC7143C5CB3376FE07DBB42D5 +:108C1000F36BA63D6EF4E1BE5B51645718E89BCA46 +:108C2000C75F7912F7C78AF5568F1926BEE27133EE +:108C3000D1B7C76E0F38A1DEEFB02BF1504E2CE04C +:108C4000FCB0B040A5728ACC148B87CA568CAF9EFC +:108C500085F924027CBAF1A187C7C3389FB0E00D23 +:108C6000E3017F6791508097B307648A3F32C5ABB9 +:108C700054833CAD635C8EAC79ED795305FC5A5757 +:108C8000BF6226FA812B83C60F7A341FEFA2B64C3F +:108C900094BFEBF823D0C3FAFA756CDB17F2586275 +:108CA0007B13EEDF351D51F5F5D77C8C719C754C2F +:108CB000F9A047C479611EF30AEC49274703E06134 +:108CC0001EC0103B5B6FCC61B0C41536D887B0DED8 +:108CD000293B797C6745A31C3443FB29893C5EFC16 +:108CE0005113D07F04AD3BE00478C5F7B85E5AC19C +:108CF000A4A0057EBD66E77A05F7CF2B1E8EA7C51B +:108D000012F3E17EF8D0EA1E82FEFDF2C7AD84DFE9 +:108D100015BB56FEEE1178AFA7B93A29D29F5EA9CE +:108D2000F105F4CF2C09E17E3E6EFED7212807A77E +:108D3000FC00FC6258EF8A78F6939A4CA457EA102C +:108D4000D5166EB762E33D39BC1DF8D5B0EEC55BF4 +:108D5000641EA77AC14C7A1264838BE4B886CFA5CF +:108D6000ADAF994C7928D7B775CBD0FE0380651B82 +:108D7000E12BA0E1D184F85A84EFA6F2775CC59A82 +:108D80009DAE92DCF1E3FA6A0DD2A2B9A4077A4D46 +:108D90002807BE5FC0EDDE6D5AB97888FB668A434E +:108DA000DF6F76A35CC31F59CC03FCB03586EEE5BC +:108DB0001807663F35533C655DABD56B75909FE2F8 +:108DC000DD8FF3539862C2731795CB97EF6B7CB826 +:108DD0004E9D730DF20DD41F57A07E8D9DCBD135C6 +:108DE000F180776ED77A0D30CEE7F8DB70DE6FEA70 +:108DF000D888F125ED39F4A33AC2FD7619583BC65F +:108E000065B0FDC8B188C7C41BE6E3FC7E2CD37EE9 +:108E100086C5DF5F8276E18FE502F487176F393A06 +:108E20006D07C2CFE53BB1CBC53F7987F4CCAD1A16 +:108E3000FD7BD03F40BD03F073507668FBC92FF334 +:108E40003851878627C107A27ECD16238FDFB799B9 +:108E5000C9EE59D3FC7BEA778DBD3B05E5F59A1742 +:108E60008CC528D79FD7E6BDA439A3EC38F0D5121E +:108E7000639C538247AB03D52684576F97080EBF78 +:108E8000973C04F9F4CFAD2F3A907F3EB486B251AF +:108E90007FF5AEB7BAF7E002B438DD9F5BB3F76099 +:108EA0003C67A9B3DB2E41FDD2DB8727A0BC7FDF67 +:108EB000193261FDFB1D990684BD4E6719C25E65BE +:108EC0001CC17F0651D6A1F9ABC86F6B254EE7D503 +:108ED000CF1E350D83F18E17F0B8F9A73F7E270717 +:108EE000F5DB9A21DD39A887800F72D210CFCF48E9 +:108EF000A4BFD73E2B7BAD63C37CB016F900F6DD73 +:108F00002A8D0FD61E78F12EDC0F6B91FE9E4BF949 +:108F100008F8F4183DDFBF7B1AE3EF1F433E117AD8 +:108F20000FE05623C6DF4C1A0CE320FCAE864FA898 +:108F3000AFE2F581BC7A1E5733A19DBAEEA031D0C5 +:108F400013716E34109DBF2AD0CED19ACD2477BF35 +:108F5000D2D6DDB3E50507D2F1D31F1F7D15E3C5DA +:108F60006BF6837657FBD9171A5ED6211E1CB40EFA +:108F7000B247D6E1BA1D613CF4F1BFB61FD731BE8E +:108F80004EB1EE758A860751AFBDFF176D9DAB9947 +:108F900086B70323F8FED3F61BEE6794AB627DFE23 +:108FA00004FEBEE0D3F442BE3E6321E7D7D5C0172E +:108FB000EE3CE21FAF49C809A8FAF4B9DD142F123C +:108FC000F412F31E5BA80A79E78D4F08D3B1C7C02E +:108FD000EA3AFA89B3241772FC9D681B34E420E056 +:108FE000EDCFE097A1FD85FCAA448C27F8468C378D +:108FF000E5477366E07AA1FF10F62FC67D3F10AB00 +:10900000603FEF33BE3F903F517E8A7D39A565E1D9 +:109010008C7C07B6FBD43E3C0FD7CBC71F5BE8A4C4 +:10902000F7BD682FC0FBDE8312C5AB4F687180139C +:109030006D2F3A9644E0294F7B4FF019FE601C4B90 +:10904000CCB72B81C77FA3E72DE49098F794CD3759 +:10905000CEC0E762FE825F057F0A3C0A3E651B9236 +:10906000C9AE89E657E235A157659DBC27FD784D0D +:10907000FA1726BFEDD2E7D1709FFDD4EA3A9615D4 +:10908000A1D73FC4380FCA93A7E520C913065C1BBC +:10909000A17784BE6F5E7F8D13CF198DCF4A6E345A +:1090A0007D22F4CC362542CFD415AECF417DF6607B +:1090B000E1302EF793BCA7919EAB4F754F73A8611B +:1090C000FB75D29721390EE36107323D917A75F530 +:1090D0009963B40FD6B0EE4DE87F2DDEF24EF578F1 +:1090E000E4F7A78D74EEB9B86DAA09FD81954FDE3E +:1090F000528CFCF441FB7092EFA7F71615107F31EC +:1091000067CA0DB00F96EE7DE88605F07CE941D97F +:109110004D721EFAC1FDBBF88E0226D1BA7BAAF1B0 +:109120003CB5F76ED98976FFC4278B3660FB89F68C +:10913000A1F1B80EEFDE4482BD4A1CE909612FBFE0 +:10914000AFC9CB1623E78F0DDABEBAADAFE4FC335F +:10915000A5A52507CFE37B77839CC6736993DA11B6 +:10916000C2F15E1A447EC93A70A35C40FF5312B745 +:10917000CFEA4CCC92EAA1E7965478FE9AB1FB0E66 +:10918000D427AFDD61CF6FC609C8178A97707F9269 +:10919000E60176348D2FF026E6714F21D74FD1FDB1 +:1091A00089F7BBD0FF40B9AACDFF74EBD337A03EFF +:1091B0003CBD2F3B01D7FDF14BD676B4AB3E3672AA +:1091C000F9D867EF048D1F45DA6B60DFE960B0E71F +:1091D0007430F0F1477AFB7023CDEBBE429BCE9EFC +:1091E000137C5FBB3E3B2E320F21DA8E6759D1E7ED +:1091F0003DE3E3583F724794679A0051C0A873D08B +:10920000B68771AB62BF7EBE1BEDFEED66A719D6B9 +:10921000F911F23D9E67BD2007F1FC066D74DC0775 +:109220001F3D971F44FF73F97BFE69D8FFB10736D6 +:10923000539EC232B033074911F6F3F71EB801D975 +:10924000FFACDBBF2915DE3BBB8FE75540B52DCA10 +:109250006E7E3555FDC7EDE62BB597459CE2E7855B +:109260009ADDEC666EC4B3C0AFF09F5E063E28F197 +:1092700084F1F559531DD9CB679AFC547E2E9DB8C5 +:109280007F22F2AF3DCEBD075EFBC5C187E434A4AB +:10929000F381FC0BE82F97DAE29CB86F3F6B6AA46E +:1092A00043CB334DF5540A3A8B38DDA4039DF4DEED +:1092B00067070B0E4D84F70EDBE2B81EB8E49C88FE +:1092C000D3333A8FE4B6F5E307E173B1AE4FEEE680 +:1092D0007415F3FE64DF2D0E5C57E7638987262043 +:1092E0003D63E39C68F7ADD0F2474EEEE076F5299A +:1092F0004BDC533331EF64E7BC1406F27659E77761 +:109300006EC0E7CB5F929CE80FB85F9AE3C078EB42 +:109310007F283D0E2796F05E08E7A304659447A5D5 +:10932000D3199D63958614A666D2D130F1CB8433D0 +:109330004A10F34EFE8CE75B1847B910437114A630 +:109340009D5B2DFB198FBFF4F9B99A9F37515B775D +:109350004A5102E76FEDF99412FEFCE39DCFCFC2B4 +:10936000FE4EEF353A71DE9FED3552FFABC03F3315 +:10937000C07C4FEDE37ECFAA0E89FCE5D3FB406FA6 +:10938000C3BAD6AC377A4D7197F2E114A8EFB18524 +:10939000F970953748FCCD347EB4C0BF8BC32EE541 +:1093A000C778D6B109F1F18FF2A5AD48EFC7F5F155 +:1093B000E3407CA0E10BF731F2A3A0F72AA00B9EBB +:1093C000CF2674E457205F09FA0B3911A864B9A8B5 +:1093D0005F5B4C2C17F37802861837EEEF3936D5E1 +:1093E00028011EE625F554A138BDBB88CB49798AF2 +:1093F000C16B40FDD2622639102D47B28BB8BDF447 +:109400002CF234FCAF2872723B8AD5933F224AD0AB +:109410003B19A8C7E7C426FCA70A4D3C2F7C7F81D7 +:1094200002F39F3331E18EE16EE09B171E5FA000D7 +:10943000FFCE2948786118C065453B393C2EA1C84C +:10944000087073F3AE055500D71479DD45C9E17195 +:1094500044BFF0BC009FFF7CB4BF18CB75261BC96E +:10946000E9CFA5DEB18D99E1F66F49ECFD5F48616A +:10947000B8C7C886A09D57D137FFFECB8D45DE7299 +:109480003EAEFEF912C6DA28FF2EF0CBE312F7C784 +:109490007C9614CA6323BE5A62B185C8AF6F379EEB +:1094A000E9A337F2913B4E41BACED2F868B612EA40 +:1094B000C4F747B256E7490B99523B2F260E2CBFF3 +:1094C00061E3B193A23FE097CF8DB05EE06B09D826 +:1094D000B311B68C0448AE05F9251DFAE55FB1DF7E +:1094E0009600EBB1121D6A9DC86712F31B2E42B99C +:1094F00026D63116E3276B62870491EF1B5EF8F4E2 +:1095000018B2D74A61BFF84B88DF6F77F2F5307F2A +:1095100029F1E31D1A3F7EDCC4EAB360EBCDEEEE29 +:1095200076A830E933B34239B8DFFF34C45F5784DB +:10953000FEFECE96F406E09F4FF79BDD33A1FDA91A +:10954000E0F314BF5BADD9A56C6FB2B6EFE550394F +:10955000B4EBCA1CB907F54B4311D7D76732434365 +:10956000EE41B991C9FD2068477972D3375E938C7B +:10957000EDCE3CB7396B19D0CFACB0803D814AE617 +:1095800080755F0B7D97006C0458A673E020D10BAB +:10959000DB3950DFABB7B8789C9EF950AE087A093A +:1095A0003A5C421F9802DAAD060B33E2FC47B29DEB +:1095B000CE93B1613A7D6C013C621CCD027884FD92 +:1095C0003D15830F85884F1E7769907A5A1311FED7 +:1095D000B144797797EAC1274D88F2BA9DB790FCDC +:1095E000117247857FFDC99DAB8E1FED9CD2AFDC0C +:1095F000790CE50EAC83E5B3FC8BDC4024FAAED0ED +:10960000DE9D2AD7AA0ACE3BD9E2C6B85AC3E3C325 +:1096100049DFB00BBF217F58B4633B13895F3665C8 +:10962000CA84F79507259E1F79308DA95035F360C0 +:1096300022958EF3A9F4FCF453AF1772B9C4E95222 +:10964000FDC3419594AFFAC311548A7934687C37CD +:1096500055CEEB08A11D61837900DCF01AD75B0DB4 +:10966000D7CB14DF6428A2539098FCC7676BA73848 +:10967000908FF5D9F9D245B2DFD538A48BAF4B66C0 +:10968000C83FE07504389E2DCD8867B3CBC0D47E2B +:10969000EC0FB34627AB1AC3D408FF43098CFC6E0A +:1096A00019C665BF637407A1BEC5EAD883FB8905E7 +:1096B000BCDDE847CCD7DEEBB672FE88CD4DD0BD21 +:1096C000BFD931AD0BF96DBE97EB1DBB7BB06E7C86 +:1096D000B3BCDA884CC6FCDC5E14FC407C09E3CEEB +:1096E000F649A45FAF9F0FF511FD1ACBBE20396E6E +:1096F0002CD3DB99669FBEDD1F84DE19C94646D296 +:109700003F8C779B17EDF4B35E3BF13168F7EF9731 +:10971000017C439791E17ACD317C5D671153181F2D +:10972000F5CA418C9B6C463CC0F3B8123D3EE3BD8C +:109730007AFC254ED7E323D9A75FFFA0F9C374F5C0 +:10974000A9FE51BAFAB43A8F0ECEA82FD5B51FDABA +:1097500058A98333033374ED87B7CFD5C1D9DB174D +:10976000E8DA8FD8B144573F32B84A573F7A5F831F +:109770000E1ED3F12FBAF6E30E6ED4D5E787EED5E1 +:10978000D517743DA8838BBA1FD5B51F7F7C8FAECC +:109790007E42CF33BAFA89A7F6EBE049BD3FD7B591 +:1097A0002F3F7F440757B0D775EDA758DED1C1537F +:1097B0009D7FD0B5BFC6F5A1AEFE5AF5CFBAFAEB84 +:1097C00072CFE9F93586CBBF6AF7DF74EF7D9EE68D +:1097D0001F558C3A533EA320DFB62C945822C6D591 +:1097E000BBE659500EE4156B7248E3C3E1453C2ECD +:1097F000C1B2D810946753E5990CE376673BB87F04 +:109800003D90BE8B0375A5448C1BEFB58003198674 +:1098100013A73B7570B2CFA56B3F68BEAAAB4FF5DF +:10982000E7EAEAD3EADC3A38A3BE44D77E68A35716 +:10983000076706A6EBDA0F6FF7E9E0ECEDF375EDDD +:1098400047ECF0EBEA4706EB74F5A3F7D5EBE03114 +:109850001D8DBAF6E30E0674F5F9A1765D7D41D74C +:10986000761D5CD4BD43D77EFCF1A0AE7E42CF3ED8 +:109870005DFDC4531D3A7852EF415DFBF2F3211DAB +:109880005CC15ED3B59F62794B074F75BEAB6B7FF2 +:109890008DEB84AEFE5AF5B4AE7EF59FDD213A071E +:1098A000F8053F57BB2EF70B5DBD3109EC5A8C43D1 +:1098B000B218379E5F0AFBA7DAFD575DBFF7160F98 +:1098C00023FB0278A9C72AA37DE4A3F85102261638 +:1098D000025FC6811043BE4257A196E25049A4EFF1 +:1098E0004835A99827047602000986CC4CB4A763B2 +:1098F000C3765BFAC5822BB7DB76409F388F5F1645 +:10990000FBEF2B4E467FE5B96968B7AF64814D38F0 +:109910000FD07B713DB03FDEB4EAE319A2BCD602A2 +:10992000F88918EF35EBF674CF65FCFE6B2D67A850 +:109930007D5FBF5A9C4382F53544F47F3FF8150A9A +:10994000D875DB9B60FF80C3F8609393E0EF35B977 +:10995000087EB849A57247532E958F36B9A97E6700 +:109960005309C1BB9ABC04079BA653B9A7C947CFEB +:10997000F736CD27F829F0A3B1DC077E3596CF80E6 +:109980007F8CF5CF82BF8CF04F9A02547634B5D3DA +:10999000F3FD4DDB093ED0B483E09F3605A93CD8EA +:1099A000B48FCA9F377550FDA1A683041F6E0A119C +:1099B0001C6AEA22F8485337C1C79A8E13FC6A53CF +:1099C0000F955D4DA7A8FC55532FD5BFD1749EE0D0 +:1099D000335ADCF6956249776F4AC08C55113F08BF +:1099E000FB7016DAF9C81C25C6CF74767E94BD1DAF +:1099F0004D8F4FB4718C95602E62FC7070CE9E9628 +:109A0000083FEB2D6DBCCD312C6005F9D66CE07EA6 +:109A10006D7302A33C6EA6D9AF2B34BE6449DC6ED5 +:109A20005DAECD6B85C6FF45C89FB9C49F6F5C8D89 +:109A30005F21FCC65163FC27883F330C01F29F6D08 +:109A4000C11CB49FABC7F83F42B97EB67ED9AB34D8 +:109A50009ED34DE78FD5E650F28D181F794DA6782D +:109A6000DE40E3ADD3F2CD07AC3F7C3A1DEDEDE92E +:109A7000DFC87EC4D39B46FB7C8C17FCA598FBA754 +:109A80007F2936E8CA77C6F8BFC2797E65AFBFD9ED +:109A900000F3FF6AF2FAA76ECB0CFBD3B3D1250516 +:109AA0003F680E538D94D7C8BCAF644257D78381AB +:109AB00085F08D2C40E577F2FC17715D35608823C9 +:109AC000EC2F350FE96F5DD1F38A19CFE71533DE3F +:109AD000A02BA5B17EEBF8229C9797E6F5E6846B68 +:109AE00072705D625E956355ED3E44EF2E9CDF57CC +:109AF0002F7D71521A1EC6BFF0DB375568F928EB6F +:109B0000251E9713F69A96CF22FC8EDA3BA420DA14 +:109B1000EB0BC1DFC173A6F734FBF33D2BD7CF6747 +:109B2000EB8D24276BA518379EC79DADFF0F1BB289 +:109B300035B467785ED282894250DFF2AF12F159B4 +:109B40002DF463807E8AC666D27A6A99C58BFAB88C +:109B5000F6907937F26B2D987FE867019FE48C4788 +:109B60003E9920074C6007BF6908E648742EBDCCBB +:109B700024C1FC5624017F0C1B980FD66AF719C428 +:109B800073E02F37F6F7D9CFC6E7521CFFF0041564 +:109B9000F1D562E0F79802BF92DD3C3F868B687991 +:109BA000E2188A4F32C5EDC6F852B576EFA5536676 +:109BB0008DCFF5233FE78EE7FBEB4D97717A90FA57 +:109BC000D59FD7CC18CFFDD0195ABBEA23AF65E09B +:109BD000BDADB55D46F24358614F9ECFDECF7A1AD8 +:109BE000B7DE9915C1D7EB0E9EE0F91AAC272F32DC +:109BF0009FFD56AD5FC147B2C9EEDF6D8B9C1F1F45 +:109C00001FF87A0EE2E1AB78E0EBE1C4D727D1CEC2 +:109C10009E6556E36E84B207501482D2FF0327E597 +:109C200027893CA5A5CC47E50A6003E4635FE00112 +:109C300013E27F15EBA0E76B4B6E1982F03AD65B0F +:109C4000E5423FA2BDF91517CC72DEF607A6625CAD +:109C5000766E70F12B58CED92B9D44BF15F6C512E8 +:109C6000E4E31EA9BE6D308CB7E0D98AB634783EE5 +:109C70004BE6F460AF737A00BF78E5844BD709FBFD +:109C80006015ED83782FAD43764CD7ED83DA8DCC1C +:109C90002B2585F3EDFBF645C9AD7F4A433F48E9E7 +:109CA000A5F3F77587CD0948E7558CEBEDB01D2876 +:109CB000F435B7036E053B00DB7DA2F1F327198C69 +:109CC000EE357C228163E709DB916C88DFE5191EA4 +:109CD000D6BB9F1882C58EE1A4979B71BEAFBAE632 +:109CE000A9182FBB35C9E296B13E3E38849FA3F632 +:109CF000C9777631361CEFBADFC8E34FD1F3924A09 +:109D00005EFD2BDA0D66130BE0B906EC6B568CFB8F +:109D100079B089F6590BA216E366953EB5BFFE5B96 +:109D2000B57EBBBEE6FE6F00D683F77C2E19C7A9B1 +:109D30008D13C3C711FA03C723F991C274E3ED1958 +:109D4000CFF7F59B762FCDBFD9104FF2E60F43FD2D +:109D5000BB91EF44DC47F8855D991F6791FF7EA1B9 +:109D6000251DED73E05F9EC73899CBA5378D6A003E +:109D7000E1372B3229EE2FE4EDEC121E279B2DE26A +:109D800062655171B1A8780C2BEB3F4EC698DB8809 +:109D9000E38E64EF09FC501CE6489942740F00DD25 +:109DA00031CE7C44F34F2B62B95F9E509248EB4C0E +:109DB000B8368BF8CD91C842740E659789DF8EB2A4 +:109DC0007C5B42849CB8578BAF6E033B8845C4D5FF +:109DD000EF2D6CB060BEC1661BBFFF785F654C5D48 +:109DE000647E7CE2649EFFF2C3C915AC04F0976701 +:109DF0000B5692BAF62A2AAE47D2D637DA09F83786 +:109E000060D73E2D4EEAB6F0B85415E96B41F72BFA +:109E1000D5D7CF28C18D31B8FE2446FBD0BEC34A6A +:109E2000F254EEF08630557BD9E4B9EF223F33C5CA +:109E3000978BE37416C7301BB4FFAAD344FEFD61B1 +:109E4000C3921F9870FFBD6B6678DED9614F535087 +:109E50005F747C3DAA8A4AFBC4698CC739630D20B4 +:109E600028F29DEC897F43A269F7D54CAEA3933EBF +:109E700002147748AC8B51DCCD1B6B009FACC3C088 +:109E8000CE95C3FCF6DB3C0F8D2316F4C9B8DEA1DA +:109E900093FC9F227F15B37A82EF33F9EA76C3F8F9 +:109EA000F72558886F3CA906BA3FC8FE6AA3BC1FB5 +:109EB0005F97624415F76299FFDCF808BBCCE73284 +:109EC0001831FFA7CD04F23B0FE32831FCCC8A7197 +:109ED0007BDF773E87E6F78D264F5B5DDE6EBC88C5 +:109EE00032205E9D4A6F5FDC84F8329DE27D02CFB6 +:109EF00091F47416EBE8E93746D2B304E8392692B8 +:109F00009E5EE96AE8F90E26A1155DCAC7814AF589 +:109F100081AA42AEFF30952E9A8F2BCC936C980776 +:109F2000D3E9900D48D7CE98B43C8CDB093E167C23 +:109F3000DD0F3FAF3F8A72255D71E279B2B93A8693 +:109F4000CE67047F0BBE9E5EDAC7DF8F95023E1799 +:109F5000DA7C5351F644F337C6CF22F9B876407E07 +:109F600067CEC87D3E0BEC8DB804B4934EEDED8802 +:109F7000E0E3DAFA2F142E772E96C71487E37DB329 +:109F8000CA24F64124BDE1FF07B9DAFAC84E52C827 +:109F90003F1378BD52FC1BBFD39C8B76DF26BCFFE2 +:109FA00008F86A97DCDE411807AB3F711B3E6FD3A0 +:109FB000EE2507F24CDC1ED3F695E86FD9E4CA69AA +:109FC000B8FFEDE3CFC42E87765FA51854444E9BAF +:109FD000BAE4DF689F1E8F65F89E23B1BBEE09DAF5 +:109FE0007723189E277EB5D23F14CFF7B7009D3E4A +:109FF000A0A4EDE020039D7DF50CC27D07C875F19E +:10A00000D2EFE2CF99561F24F80F138669E78C5ED2 +:10A01000AD7D0FB5DF62DA6E89C171322DCE3D1193 +:10A02000FC5FAEC5E35B4BC4FD9F1615F3DF5A4BD7 +:10A03000B83DFB50D3BE491F65E37C3A267D04F34F +:10A04000499C19647EE0EB98DC808AA923966FA670 +:10A050004878CF818D621D18A7C7E7CD63C2FDAFD9 +:10A06000D4FAB5A09D03F4B36C0CA89172D662909B +:10A07000FCFDE5C9FC718242FBD5B29151BDE5C83A +:10A0800023F4FD80C42CB784F9D5968DDB199EDFAF +:10A090005843FC795296575A1AD16FD24C9877048C +:10A0A0005F007F05E2402E59F6006316221D6228EC +:10A0B0005E193DEEACE4CA2EC531309F44F31BD38C +:10A0C000F84DF08D5827DD8089F80E40D5300BE92A +:10A0D000C9B646D36EB4CF7795C4135EBE4CAA8C76 +:10A0E00063FDD8A7A2DC057C1030A33F6DA1720FE1 +:10A0F000F8E38111E84FBB087E0AFC712CF7813F21 +:10A100008EE533E08F63FDB3E08F23FC13F0C711BE +:10A11000EE007F1CE1FDE08F237C00FC71847F0A50 +:10A12000FE389607C11FC7F2E7E08F63FD21F0C735 +:10A13000112E37037FE07A7203AEB940D7F6BB4DDC +:10A140005ECC33FC6D0997A747BDC312DD407F6B22 +:10A15000AE8162E5D6371E64B81EABCB40F7CC3675 +:10A16000B91E64B7A09F5B6C277BABEDC7DC8EB1DB +:10A170002A0F31943BBBA4401D73C3782537D5E229 +:10A18000B960966B7D6502C0474A16EFB4C0FEC841 +:10A1900051E7CC6F8E8055BB67D573CE303C346FA2 +:10A1A000B7029E0CFBE5C15B76E215239C07E61720 +:10A1B000BF55B2BC16F3EA43C318D923BD9926CACA +:10A1C000E3598AF4CAC6F9F373C0EB588B0BCF3945 +:10A1D00087AAE02D49D49EE24C57DAFEB7252A3DE6 +:10A1E0008F7EEF72ED0C8557D48EC997E90FEBA5E2 +:10A1F000CBF46391E659BA61EE5B8D9A9C4AB691B5 +:10A200009C6AC7B80FE0BDDDCACBFC52BECF8DA59E +:10A21000950F4F80F2E1099CAEEDD680B312C71FB7 +:10A2200063A03C07D698F9CE3018EFCE5F290CF327 +:10A2300045057F9ED1F8207BA89DEBEB7B2C74CE4F +:10A240007FCDD01FB726009CFD84DB8DF9105B9974 +:10A250003B06F924B0CD4079913F2A1C9E30079AE5 +:10A260008F2E7A2101E5FA8C097C1E412D8FA8B929 +:10A270006DF9508C537DF51697877FD3C6D96DEC59 +:10A28000AE277A16D918CFCBDA4EF648B30B880D25 +:10A290003AD390CA4B93D1B900DB99C030C0BC6DA2 +:10A2A000D3D7E32DE80FB69C374FE779B5DD649F30 +:10A2B00098AC7E673C3CDF1E30905C68516D940723 +:10A2C000B7D5E6E9C27BD301A781F265B7E61908E5 +:10A2D0008FADB61B82E8072852731DEAB1A073BF89 +:10A2E00025139E07F30C94FF18F4CE9D8E70C0CFFB +:10A2F000BF47413F58EF4FA0FBE25B59EFEBE3B0A4 +:10A30000BE96DB696D29FF752416E3E2D73BDDFCC1 +:10A310001886A9983746296406F4C77B36C6E23CFE +:10A320006A98E6EF06C8BF759839FDBEDB79AD7354 +:10A3300018D91911E75D668CE1B92D6EA81F6BF372 +:10A340004C47FF53B17B2C9817D8EAF45816D3FA30 +:10A35000793E1BE56B40BF2D4E03F9C1587F0BEED4 +:10A36000F75646F97083B5FA56DB839D880F651959 +:10A3700063992ACE4F09449E275A869775A9B08EB5 +:10A38000F6E509B40E457213CC962934EFC16A0C78 +:10A39000DD937EC854DD85F6E460CBAD74EE955A4E +:10A3A000A7E8CEA506F9F570F27C3D9CC894F0B9FB +:10A3B00016F2D9041197D3E32D1A1FA9CED6B77080 +:10A3C000FEA97EBAC47BC9FC1F717E2FBE82E13C10 +:10A3D0006D34CF14DB920AB49B9299AF19F9EF1F39 +:10A3E0009DE758E75C4B268C3F36C940E6D138D60E +:10A3F000BB11FBDDAAF17B7B26A767785FC9625F93 +:10A40000364D48C6F305033874E1FE3303E0D8E95E +:10A41000CE17127470F6F6C1BAF623760CD3D58F28 +:10A420000C8ED2D58FDEE7D1C1633A4A75EDC71DD8 +:10A43000ACD4C1F9A119BAF6055D73757051F70274 +:10A440005DFBF1C797E8EA27F4ACD2D54F3CD5A025 +:10A450008327F5FE8BAEBDB0EFA3F5E3DD13B87D2A +:10A4600071B576BDD93558F7DD9C68BF21DAEEB7F6 +:10A470007CD3A26E447E7698889F15D4E7780E7DB3 +:10A4800037F79F2C93DD2AE5396BFC5854EEDD84B9 +:10A49000F2B4C26121BDA0D8783BC5368DEC9521C0 +:10A4A0003B4CF43D1FC5C9FAEA63513E37052665AA +:10A4B0006587E76D756E67B87F2B1CD319E6298910 +:10A4C000F715A797F9318F1B3FD28376923340ED72 +:10A4D000AC2ABC1FB18EC30603B3A11C073F0FFDFE +:10A4E0008381FC3AE1CF09FF6D20BF4DF86B430C2F +:10A4F0002C06CBDD52CF6DE8DFE7D5BF553988910B +:10A500005FB70FF9F53EBC078EFEDC586E67B5A548 +:10A51000CC5031DED39ED9D1350CE7936CA0382ACC +:10A52000D8CDEEB911F6E2DB9AFE5186B5F7A0FE62 +:10A530006B88B7A8682F2996DD933E027CED32F632 +:10A540003C8DF18B56C9B9BA03E5E2DD36CA0F7905 +:10A5500048C39B6A37146C847E3B9ABD0ADEF7EFD2 +:10A56000D8C2DCADB83F922A36C6C3F3ECF4C506B8 +:10A570000C138DC86ADE88E5B109FC3C6864DE6EA8 +:10A580004322D48F2EAC988F7131D9B99BFCD981DD +:10A59000F84976EC60B81E96A59C44BE42EBFE22BC +:10A5A0004CBD2201E80DE35A91DE12958407EB7948 +:10A5B0005BD08A7016C78BD52B0563256EB7627E7C +:10A5C0005D45C20EA2AFB067D1CEF5737FF76DE4E3 +:10A5D000A3A4997ABA2A96BD848FAD06BE2FDAE37A +:10A5E000D537503FB7676625B4A8E1790AB9F24775 +:10A5F000CD0E17CF855C998D3938C961FB06F87C83 +:10A6000007C6E7ACCA76BAE769DDB09D215F5BF1AA +:10A61000563CD9FB01D547FAC3A7CB4FAB1A36DF5F +:10A6200082FAFA5C9287EC596BE34F697ED178B37A +:10A63000F6F03CB581F0EAC87994F43B086015FD6A +:10A64000FE2329B6BAC8B8A828EFD2FC13A3C8279E +:10A65000024F02F5D93991AFE48DE5F38BE7F0D1E4 +:10A660009C0534BFDB923D832E676F5BC1DFF447EF +:10A67000D07D8BE2B3201EDA2ECC994EEB56683398 +:10A68000B0AD5FE7EDA678B3E62FDDA5E1B7B58401 +:10A69000E3738889DF337027CDA4EFA40DC6F84893 +:10A6A00041385E32AA94E737BA034CE6F1BEBEFCED +:10A6B00076C3C571346715EF1FE09920F2631AE382 +:10A6C000FA0C9A74623ECBF076459F0FAFE9F334F3 +:10A6D000FE3BC87F7DFD881D7A786430EAFD00FB73 +:10A6E0000DEA7BB477299EB14F5FFF18EA6D901396 +:10A6F0004B35BDCDB6F3FC120BCCE822D7B761FDCC +:10A7000007F260564777452CF49351A2CF3B498B13 +:10A710006C07F8F3AC34D0BD1211DF1178F7D519FE +:10A720008C26E27F55770E27E239D1F25ABAE7CC70 +:10A730007ADC5715B1B12ACA598C77F8CDDC7FF78E +:10A74000833F739FE2FE7D2DFA5F5D32E561097AFA +:10A7500046D37F6F9F3DEC2B2F253FBAA700FD7A94 +:10A760001CCF1F319E88CB6497FBA7623B119F399A +:10A770003B5D794552C3F116113F7818F719B4DBE8 +:10A78000EA7EBBFE28CCE3E87133C54AA6CA6F74E3 +:10A7900035619E55864272CE397EF50FD04FAFFCA3 +:10A7A00003D4635C52550791FDDE65A47841A5C6CC +:10A7B000EF959A5F26E2320BB579D7940A7B281081 +:10A7C000C3FDFF500CDAB9A3F7818CD6F34B2CAF45 +:10A7D000E771BA311DD1F55ECA7F1AA5F103E6AD66 +:10A7E00055A460BA18873B9894E8043A8F9BDF73AE +:10A7F000045D8CBCD75E8941BBEB392BE78F673496 +:10A800003B2F85496ECCEF4FD9677307A19D5D66DD +:10A81000CF75C33ADCC7145D9EDAD8437A388F45CA +:10A82000C099380F3DBC4DADC7A36BB6AD165811DE +:10A83000967C47A9964792C37290FFA6CAB67CF44D +:10A84000B31A2A6C0CF16A3E31E2FBDD2857DE9226 +:10A8500019EA0B67ACFA4015BCEF7C3DD1DDAC8644 +:10A86000E9FF0CF8DBA8471EBEE866ADC670FCEB3E +:10A8700059A067169D4F3BA9BE03E88AF07EF0BF42 +:10A88000B3E87C3A979EFF14FC6F840F82FF8DE53E +:10A89000CFC1FFC6E787C0FF46F887932B1EC4B819 +:10A8A000D97BD00EF92226FF806538C6CB6D32DD0C +:10A8B000DF89E6C7CDF51FDA6E049936CA953C33B9 +:10A8C00019F9E17699EE45432733D1BF8D8CBF4509 +:10A8D000C623C3F1B71E49C4DFCC409F519A7FD92C +:10A8E0001787F3F338DCB7F7E315FD509CF3927E3E +:10A8F000FAE29D96C047B928B2241607CF3FBDFBA8 +:10A90000DF9F427D24A7FAF7E23E5953F48189DBA9 +:10A91000E7FC5E56BAB68F765A793E6ABA96471405 +:10A920001DE79C3CE5C46DC980B2177F7ED3428C85 +:10A93000134CBEF544C11080BF29FD25877F78E206 +:10A94000F934C0D3D289ED1C7EE8C4B97437E671FE +:10A95000EC5F88F9C38E44AE07776AF79B047E8F5D +:10A9600069FB665DE313A4EFC11E61888F96141F17 +:10A97000E9E1CF937A1D8BD1AE4BEE4D597219BDE3 +:10A98000B1AEF1297A7FA7E43E15C4794FB0F0BC8F +:10A99000554D2F9DD57857E8A5062B07C57C187314 +:10A9A000D1F387B47811F3A6D17B89560E1F759425 +:10A9B00092FEBABF52FDB5CACF3FC98F3EEA18F525 +:10A9C0005DCCCB6B99AED0B9E443368F15F5DBE7A0 +:10A9D000DABAA0FF00C60902532D745EC492E6D312 +:10A9E000BE4E10E324D5523E4382369F63A53121EB +:10A9F0008C23B45459F6A01C7DD0368CFA6B2931C7 +:10AA000005307E23E08DA5301FC067BC2321136174 +:10AA100021E7447C99E1E91CF45BA92DBB52E44990 +:10AA2000588C6722ED701BEB26FE711B5419EDC884 +:10AA30000D13395F1530F77C7C6E92EA03C88CB831 +:10AA40000E43E43AD42AFD3AD4A9BA75480D9610BB +:10AA5000DA8F2D53611DD0FE98BD98E61B4D37B19E +:10AA60009E0F4B55C257F43A99762E25EE1F543A55 +:10AA7000CB0EE0BCA61ABCAD38AF57FE5A9B841F64 +:10AA8000E89BC6EA157C3E3C9C0FD47A35F91693B8 +:10AA90003F94F839DAAD265A9F71329FCFA3A66052 +:10AAA000265D0C5182A9787E3C101F674E8CE663B0 +:10AAB0002FC3FDD592E0E57CECEC7534231FC7F77E +:10AAC000A66CA47585FAA54F343F47D32B6F22138C +:10AAD000DF079111FFDF465F41D7E8F334C12F1B39 +:10AAE000263A05BD5DB4CED010DD7923F4A0F6770B +:10AAF000CEBE09FA5323CEE54C2E1FD9E3C62477E8 +:10AB00002EC6A55BBE91FBBD7F59ABE1A9D9114310 +:10AB1000767A8B83DBE99D8E193AFFAA0AFC2D3CDD +:10AB20008F96135907EE2B396E01C5DBE441689906 +:10AB3000115BE8EDDFB899DCFE757A2E7BFF4AE900 +:10AB40009175DF73BBC4FE4D98C1ED5F8789ECDF63 +:10AB50009D76D3FCDDFDC89DC289DC4FEAC475F447 +:10AB6000E35F825F49714FE1579A9C7EF20FC53ACD +:10AB70000BB57D26DA9B9DF50CE370B2C9ADA2BD85 +:10AB80002B6BF764312F3A37C22E10E38F9BC8ED41 +:10AB90008EC1E53C5F53E4C74FFEB554DF1FDED7DF +:10ABA0004C147649FF7CF70FF00DC9098FCDE445B1 +:10ABB000BBC36373511EF940EFE151F8A984B09C07 +:10ABC000717F532C933E52DC742FA0C3D8F3FCAF9B +:10ABD000D16F7CC5467AA7C39E4EFD09BBBD2296A8 +:10ABE000517E33F8C9815CE8ECB9BFC18E3484FD75 +:10ABF00063F0D7364F8C38D73CD27092CE8BA2ED13 +:10AC0000D5E8F843DF7E773C95C9E7134CC5FD2BAB +:10AC100035940C42BE8ADEEFA2CC70158C5A0AF332 +:10AC2000CA48CDA7523C7F9CC9D3FBFB6EDBAE3E2E +:10AC30003A703D3D12068B93493FEFC2797F7AFB14 +:10AC4000DB296E15EFEB7E417AFA6C7D49DC66E418 +:10AC5000F7DC0492AFE9DAFD33319FF4959DF109F9 +:10AC600036CC03EC1D89F973C126DFA82A23C50D54 +:10AC7000BDFDCDF757DAFE63A1A12CF2BB446A52A9 +:10AC8000F7B52300EFAACDE056697F3949FF0939AE +:10AC900050A1C4573981CF339A98DBA6E2A79B9D78 +:10ACA000143FCBB82813BF651CE5DF971E9AD42B41 +:10ACB000E1778FFAC6D1F2A4C439CC97F555B43FE9 +:10ACC000330631D68D7210F43DCAF92F934273705A +:10ACD0007F7FF93D3EA38C27F4F5A07329BEBDFC10 +:10ACE000F698A00A5D0FDD00F3C3F9FC4062E99914 +:10ACF000388FA3999B313EF4622CC587E41D59140B +:10AD0000DFB93ED5BF7F22CCE3D3A07AA761B8B626 +:10AD10005868B7E6AE18FA2EC14EA9FB5ACACBB88E +:10AD2000C340DF6D8DC6D75B13B95FF9F644BECF64 +:10AD3000325CC59CDEAEC2514B13AF7C3F7D83DFDE +:10AD4000D601FA6E8D0BD2799EC82BDB66EC9FAFD5 +:10AD5000CACAB87CE993C71AFE2CE80521BF489AF5 +:10AD6000DDB7EF99679E4961FC8AE2307E6E197902 +:10AD7000BE1C9315A4CA18B797E48FE4F47239EB9C +:10AD8000AC770580BF377F2DF73BBEBD4C93D31901 +:10AD900077BAB07D95EAA6B233A3F8F862C09FCD2A +:10ADA0006662E608392CF8245ACF37D8875DD6DF9B +:10ADB00037813C562F138F306979649B8E4CB0E0FD +:10ADC000774B37D93CDD687F6DB22579285E6F03FC +:10ADD000B91111BFB2D95E253EB4B9795CCF86F204 +:10ADE00017E357B8FE3C9CFFABB47ED1EEB4268788 +:10ADF0006CEE109DAB5ADDDBA99D45F1D1FD3B4BBF +:10AE000012A37C088B937FEF3426CBC02CFDC8E3C4 +:10AE10000F501E433F9BF23CDD95343F05AF65B1BB +:10AE20004D2E8F8BF421E219DE3F6A2F8E8BC4CF1B +:10AE3000500DCF2D9D7C7DBEC654675501FAB5BE21 +:10AE400094B222EC678905BFAF27DB0B2FDB4F6E77 +:10AE500019972BE17E1E49A94AA47E86623FB2DD86 +:10AE6000E3C47E8CDA775BA3F15CA4BDFFF7C6DD9B +:10AE70000083940F447821C2847474892E6D183F26 +:10AE80004BECEF3D2E173335FF05E4624519CC6BD3 +:10AE90004DDE07AFF23DC6FD96846B79BED1592DCC +:10AEA000DF3C3A4F23DA8E11FA47E823E847C67EA3 +:10AEB0001E453B6644781F0DE6128BA5D5F9F87E3A +:10AEC00049F211BF805DA3E27E91B57CC1E8F56CCB +:10AED000D6F027394A54D41755177AD2F0BDC3F6A5 +:10AEE0005369DC8ED59F471FFBEB5356ACFFB2AEC8 +:10AEF000F2B2F68A387F1EE8DCD9F12F9FAC8FB40E +:10AF000057063A87FEB6F3E7230E13C5F97649FADA +:10AF1000FBF5CD9A1CDA5026E232FEDB901EBB24F4 +:10AF20009F9B5F98E6F199A272FF9DF87C48BB89D0 +:10AF30000580AE87FF5AECF247F473A57816F1FA54 +:10AF4000C19A3D35D8F69484FB74705D50C2787B0D +:10AF50005A5D87E4BD4CBBD9655C8F8BF646ADFF6F +:10AF600072A557467D55EEE47A31EDBCC27223E4FA +:10AF7000CE8C32BE7F8D9AFDEE38F2B415FB3B626B +:10AF8000F0B5E7A07E7018D42723F6BB71A5C75291 +:10AF900019B1BE163C47EA878ECF94F5D95DA4BFA0 +:10AFA00085BE350A3D91A4E8F4C4BA58CEC7C2DEC6 +:10AFB0005957CAFDA175B1DC2F7FD1E57F02F7F3A8 +:10AFC000E7A59FCC1AAEE23DDB0E139EBB7FDB797B +:10AFD0004A9F7D63082E16FE0CF2BF5B71FEA2072E +:10AFE000DECFFF6105D97B45F8E512198F70B9FDF9 +:10AFF00007F6D473385E014E3D82DE2CEABB860331 +:10B00000AD67277E4BAD08E37FDD14C7BDEF82D46B +:10B01000EF7D8A2FCB84BDD0776E78D938AC8A711A +:10B02000D84C3C07D3C7490BBAF47051B71E1E7FEA +:10B030003C3AEEEAFD6D64DC7527EC33941322CEC6 +:10B040009A1E0856E03DF30CD641E7906975093A1F +:10B05000BC4E96B5FC0CFCBC7244FC374DA93E8D31 +:10B06000EF9FEE5B5780E9EE07542DBD133FC519E6 +:10B070008EE3AA84AF15D7CE9D8A748D8EE766D4F1 +:10B080002BBAFB84D171DCE53BF5F70D7DDE7CF25C +:10B0900007E67D471FFF1579EDB8DE34CFA5E37FC6 +:10B0A000FBB8F03FE1D2F145BF8F82FC21F9AA7DC8 +:10B0B000C73803ABB01F2524E179F8E07A46DF33C7 +:10B0C0004EBB9D79FB3B57489BC4F1158D671628F5 +:10B0D00027FC4DD19E0DB6F1BCD7C1B71BC81E1CB5 +:10B0E0000C7281FEDEC16AC612014E5BAD923D3923 +:10B0F000BBCEC0503FB00B4DBAF761BA144F1574B8 +:10B100007FD4C6F37A33D6B0A001D7533F8AF61363 +:10B11000CD6B982EEEAEFB2EC1EC12FD7DDF8CA820 +:10B120007BBE820FD2A29E1F2A73EAF605E8B9B44D +:10B1300049C4275CFF65A3FE83297D3AE1F8539853 +:10B1400087377923E3DFC3898FD1BE87D3775E2129 +:10B150005F047E3D6299928BF6CA56678C01F32399 +:10B160000EC7F73CC6E2191B338905F0FB9D2FC7BC +:10B17000F48E96009EF0D29E5DED4094C3D6DE1F05 +:10B180006130D9B6EDE99BA747C08EFB5F22989549 +:10B190003015BF2F84B9ABB8EF629C33F6E1F77C72 +:10B1A00063F26C149C8C61FAEFF8B496AADB30BFA2 +:10B1B000A435DBA0DDB38EA887753C35C929F2E242 +:10B1C000284F8F4DE7F90291FD639EF780FDCF80F8 +:10B1D000FE0BAFA27F0B9F7F0A3E023D9382F3C717 +:10B1E0003838F68FF4C5A051E4F85A7F0A0BECC644 +:10B1F000F31D18CF26F1F19C98BF92C2F4F90A7D95 +:10B20000E33961BC31FF17D633FF527A182F478FCD +:10B210000557478F568397E61B186B233F08BF8758 +:10B2200085DFBDB36AE359B5EF7F215E5B8BC378E1 +:10B23000053B90FA85E6CD17353C633E628AD344E0 +:10B24000781E086F479C3C7F6A8B3326D89CF9FF99 +:10B25000805E2E4EAFC8F1D09EBCE2F116C0784998 +:10B26000573E1EE217F74F1F7E81261B53AE1CBFB1 +:10B2700030ABC095E0F708F46B88C06B384FE9112C +:10B2800027FA0556A3CF82799BCF4FE2F98F7949F0 +:10B29000732D94B7903C97F290DBF26C9457DF9645 +:10B2A000F51D8B31424FB7E5D5523DB4A7FCAABC82 +:10B2B000500C8629D818D64D71802D65552EF40B6B +:10B2C00003F53C5F4BE42F097DC8B4F3515A17BC1A +:10B2D0001837E940EF1168BFA5BE90F2D3E2E2FF54 +:10B2E0008BF2B2B6D6B9DD58FF189E63813DF1B03E +:10B2F000768E858C4AF1B4B1A54FE0B9AF27BB413A +:10B30000C2E3A6F4D57AFD34382AEFC7F345772592 +:10B31000E677B1C53C7FCB55AB44E943FDBEDD8A42 +:10B3200078E579564189E357D7DFE949C9A4E7B6FB +:10B3300064ED6115D0EFF3D097ACDF5F06CC778A70 +:10B34000DE8F8AC94BDF29630D069A471AA6108043 +:10B350008AF38C99E95A0CCFD39729F4FDDA417915 +:10B360001B28EF09AC7CB237F2F2DEA844F89275E4 +:10B370002ED5AF237A5DD1F316DF5716F4F27CE1B8 +:10B380008E45FFCA933D97F2D2E847EC77396A3D84 +:10B39000600F5B930CF45DB998AC8875315D3BCD63 +:10B3A0007FFB9F857F3F8971FB39FA5CEC7FF1FB66 +:10B3B0004766E6B698E83D715F879FB70DC6BD83C7 +:10B3C000741FC2787E78F4FBC5FC7DE6E2E76FE689 +:10B3D0001866C1FB3AD2AA188A639ACD00E37D1E93 +:10B3E000ED7B658F6AF1B6668929A99EC8F1429402 +:10B3F0005F2F5BAECB42BFE188659E93EEC9697E4D +:10B400009431DE47F98D2C3741E78F1ED1EEBB35E5 +:10B41000ACCC1C84F1BB38A8EB46BF5A715B90DE04 +:10B42000226EE218DE7313EAF16193872FB2002EC9 +:10B430000EA3135CCAD8B8C3193FC0EF148BFD69C3 +:10B440003ECFBFF7D1072BF5943F623E3F44F73C18 +:10B45000A4F96102F626295538DE34F40F92F1DEA4 +:10B46000B8B315DFAB00E4E8BE2FA07D3FE4D2FE09 +:10B47000D375CF43E05F479E0B0CDC7FACEE3B0502 +:10B4800066F077FAEF3F27AA7F67BFFD87FB4DD4B1 +:10B49000F5DBA670B911488A09F617DF5B36B9F2F9 +:10B4A000BAC94503E7B72D9DACC5E12C20FAF11CC4 +:10B4B0004AE39FCDAE7ACA779363F8B9A911C4085D +:10B4C000F2D3517B1DC92D96AECF7713DF2769C309 +:10B4D000EF8E407DA54D6FAF57B0DEA3E324F4534C +:10B4E000F5F6FA645439783EC5A2EDF87A3A273574 +:10B4F000A6EBE5C2456DBF18EC85DD941F976CA3E4 +:10B50000BC8681E20BEF3531CADB32C6FAEA51E77D +:10B51000FDEBE1F143DB4A008EE37CB6F5F0CC4570 +:10B5200018377A4FE3E736900374CFB561D06E39A0 +:10B53000A2DF5A53281BF54AAD81DF17A01F18FF61 +:10B54000BDE4C114678D1E577C7F46C00BEBA54937 +:10B550005911EB7B4FDB1F7DE3DD96B61BEDDABEA9 +:10B56000F1CCA1221AAF2FFF481B2FE5EF1BEF8F65 +:10B57000DAFE16E32DBC53BFBE85A66E5ADF42ED40 +:10B58000FBA762BC3FE2FA32FF8EF1B4BCB1BEF160 +:10B59000EED2AF6FA1B99BD6B7B0CFBFD4C64BF92F +:10B5A000FBC613F90E66737D1DF2D340790F22DFBF +:10B5B00021C795A8CB77C09B2715598C3D2071BE1C +:10B5C000787D72CD0F30CE7F6E66839BEC14CDDF1D +:10B5D000A37B4432DD23223D3A3B9DDB21A2FF7D4C +:10B5E0004D25CC3B82C783B0CC2D93E89EC2C812B8 +:10B5F000C98BE76C3B417EE077F476C13EC7FA60C9 +:10B60000938BCA3D4D2A957BC1BFF452FCCB4DF0C4 +:10B6100085C9DC5F7C20D559B314ED8F8A189EA7AD +:10B620005D36112CDBB0FF06FBE58815F3216F605A +:10B63000F9F8772D7376707C2655A5D0F7F663F26E +:10B640008F753701BCB9445631FF7CB3DA7F3CE7D4 +:10B650002F5ABECF662DBF3280F72E49A9803F59A1 +:10B660004C7F3F8BFFC833E95ECEECBBE2C9BEA97D +:10B67000FD4E8FDD09F3B859CAFF6D16E0E34F9A0E +:10B680007DB368C80C9207D1FE69126AAA42CC3B0E +:10B69000948341F8759E7D1EF9B7F3AE672C01DEE9 +:10B6A0009F8DEF819EFAB5661FBDD96366E8FF05E1 +:10B6B000AAF8F9F5CD1BF47EE903D69013EDC20785 +:10B6C000F29318D2A3F6767DFD6613DF6FF3A2FC2A +:10B6D000D4D951793FE23B8A9BF1D7098C7D395906 +:10B6E000FB8E9196F7B35F8B33B1F4044A0617F7DC +:10B6F0003DCD66D6EFB9A4E82F11041DBD97E42512 +:10B700003C88BC77263F9B8FEF8BF1C47B8F4ACF61 +:10B71000A65E2E6E0A76E0C99E5CAEEFD15EB7964D +:10B72000EBE7796EE6B0EF56B1FEF8B657C1388553 +:10B7300098FF3F8B5F8FE27A414EFF7ACA9785FC74 +:10B740003E5E3A8BBC8727F2BFE6F5C10A7D9FF8C3 +:10B750007A01BA7AF390DEBF9914EBBE97F84FB333 +:10B760004742EF1A2EC65E7D7F7DF370793374F702 +:10B7700060B5FE06C2F340DFADA09FE2709CB7A5A6 +:10B78000D9EDA27B77C9FC9C6D7052E569BCE78559 +:10B79000F51FE8F84B7F9FABA5F36909FD96C7F04D +:10B7A0001E9C31224E54D721B5D9B0DF208F2B8576 +:10B7B0009EA6F86F7A5D486ACD0BDF1B8A968BE9EF +:10B7C000ABF5F7D2A2BFC7586DEB512415E3FDBD11 +:10B7D00074DFB1AD5C3B9F411C63BB646E4FCA69B3 +:10B7E000069E2F3254E5F66556EF90C8F38E55E568 +:10B7F000DC6EA88E7DFB761544AFBFBC6311E645B9 +:10B8000055C7BD7D7B26C0B7943FB708BFB3589DD1 +:10B81000F6F69799206F9795EFE7F0E8B7BF1C060B +:10B82000F08AF2E7398CF91E80A495E50716A1BCD1 +:10B830005D552EBEBFD84DF7BFE554CE477F776923 +:10B8400036F4BB2F6F2B17714B46F7BD7D877E7982 +:10B850001CE5944FC479BDFAF34DA67D7FF13AC142 +:10B860005E490EB29766E0EF80CFEBB4EFF6182C8E +:10B8700021C2EB88F07751BE7735DFED09DFB7E7FE +:10B88000DF9D6A69647EFDF715BD1AFFF3BC2131A7 +:10B890001F31FE25F3C2EF0B2644CE6B27F523E6BE +:10B8A000F579BE39208D0B9FD78A797D2EF5EEC2B2 +:10B8B000A047CF94DEC548D7CFEDBD43F0EFAB94A2 +:10B8C0008786FA094EEEDD25B9236023A7E323E539 +:10B8D000FF87ECA951A9DE47CA317FCFC4BF83D00F +:10B8E000AED9915B93FD01F4EB81DF286F3390C1FA +:10B8F000EF3B5415EAFF0EDC131A7F1579F9F9F4C2 +:10B9000054F3F6FAB70AF1BBEC126B86F6EB2E9CF9 +:10B9100033A1DF5F7DE88409FDFBB5074E98D07F3A +:10B920005F8B30F4B376A7A9DFBF4357EA95C5FE16 +:10B93000D5F92BAF64E4B425C17CD62EE5DF016BCD +:10B94000F859FC54841B16E32AF1EFF93D37155FD3 +:10B950005BE8EB6CC37211EB7905CF256AFC7A3F8B +:10B96000E2A63ABDDDBFB05E6FAF2FDA0ED401BDE7 +:10B97000B6A8312DEA7B80FC3B83351A3D6B5CDB3E +:10B98000BAF13B06352CEA3B83011E47BA89AF006A +:10B990004A7D7CA41AFF9E15AE63B54C71DE57320A +:10B9A0003629784F6E5DBD44F97B530F7E61A27AD4 +:10B9B0006887E74A2983F9F7F484FC14FAFDA6970F +:10B9C000761B315E10FDBDC145F3A7D377C5E7AB4C +:10B9D000ABB87E1FFABBA909F03CFA3B82B507B9A8 +:10B9E0007EAF6D9482F8DDDE9BEAF4FEC042D6DDC8 +:10B9F00086FECCC27AFDF3458D7AF823A1D746B3F3 +:10BA0000D1B83F4E974B0AED170D3E93F1BB37432C +:10BA100030BE3BD5C7BCC027AB4DA1B1A8E7DCA960 +:10BA20007E82453D3C5F8BF27FA07DF8FF4BF9DFC6 +:10BA30005818855400800000000000001F8B08008B +:10BA400000000000000BED5A7D70545596BFB7FB07 +:10BA500075A7BBF341E73B31045EBE58244D68D265 +:10BA60000441778AD7DD494FF8723A40866008343E +:10BA7000B350152549478953B1CADD341063072DEA +:10BA80004B59B4C0F28F06C5D51ADD0D92C1CED286 +:10BA9000301D302C3A387676D08171B582CB3A524F +:10BAA0008E9088A3B8CB167BCEBDEFD1FD3A2F8AFE +:10BAB000B353FEE16E527073DFFD3EF77CFCCE396E +:10BAC0009710E1A3B1D984E8082537F484EC344811 +:10BAD00056E7024202EDD47E5024A419DB4D84FDCA +:10BAE000DC28C1FF797F56D74FAE3B244A480DCCA6 +:10BAF00063F676119CE718B51E844FB5822464D98D +:10BB0000E03B254D0369D0177F96C4CB05928E90FC +:10BB10005C427E43C66CA48C90592930610E94AB74 +:10BB2000A78502B0EEAC5F6D0A50986F9683DA7508 +:10BB3000B0AFE5B0E3EE6A2C05B21ECABB0542CC3D +:10BB400050CED20F34E1BA649ED17A90EDB7809096 +:10BB500085842CC33F619CF432A11FC37970EBB87C +:10BB6000EEF2E9A7BFA619307EEFE3137A28CBCB1C +:10BB7000A4EAA7607F8F99F9FA8F0DD1D07698A7A4 +:10BB8000C376EA1CF6CB97085BB7A3202D8AFD4944 +:10BB9000D8F0C79BE72F8576D14AD6674165858D5A +:10BBA000AD5B28D30E56261F433F1A75E96E5442EB +:10BBB0003F79DD1F794476EEBCFB06289EBB9804D6 +:10BBC000B65358AF0CD6413A2A2521A6C04518DFF6 +:10BBD00008F7340DFAE90B7DCF2F8171ED0563462F +:10BBE000528AEDE346EF5CCD7EAF2EA9D1E8270166 +:10BBF00001617F0F58395DEAF4D73380F2E4816345 +:10BC000065F9C436F97E94526FD21151E107F86795 +:10BC1000B05A88383B5E5F3E3B5B555F692F52F5FB +:10BC2000FFC9A232557B8354A96A5F5DEF50D51BD3 +:10BC3000BD77A9FAAF6D72ABEA2905CB54FDCDE211 +:10BC40002A553D75F63DAAFEE9F69FA9DA49CE4090 +:10BC500081379D10A32930E6033A04815717C1FDAF +:10BC6000A518D382741A219519D0194A8BC39C86C2 +:10BC700065707E4A14EF2D785B4615D653DE7CB096 +:10BC8000208A549FF68AC909E52F68C8950D73006C +:10BC9000997C0340C7390F13299440CF636E1DBBB5 +:10BCA0004FA5DC26F9FECE09A5ED25B1086E047E70 +:10BCB0006273F07E4C16F813F9F88829847C3C0FE7 +:10BCC000E6248BE3F32CF138BB251CF7B0B414F950 +:10BCD000948489B502FA1D30C2CD423D70C4C8C6F5 +:10BCE000D9C2633A2941DE042797CFA7BDAEA53854 +:10BCF0007F47845A09F2F7DE8F8CA20DEBC319122D +:10BD00009455DE8F8C242DF1FB05237EEF10C62D7C +:10BD10005628FF69405F1FD2E09341C9C8F8F95423 +:10BD2000B191C94FCB83FA500A65FCBFC209FCD65A +:10BD300024CB61CBA1F1A81ED66F013D13804F4DDE +:10BD4000E27D2B08CA93CFC0F48D097E519E9E2EB2 +:10BD5000CC3840E671F92179846C94A5E99E45516F +:10BD600003D2ABB9D510D74FF06FE31ACF255A05E0 +:10BD7000F376267D9FDEC7E47B63A2BE427A49E963 +:10BD8000391F833C924A62BB01F272CEABD33CD7DF +:10BD900009B7C0CE75CEE766F47E1AE8A6A748C7F5 +:10BDA000643A71FA7D1B7D5EC5BB4EB8A7E47EFF89 +:10BDB000E2A6BCDF14FAD2E2E4ED0768AC1A95996A +:10BDC000DF6B617CDA6CDAB4F5A203E9FF651F452D +:10BDD000FAFF92921498FFFDE137F344E4F3432312 +:10BDE0007963309F7F60248F009FB519C4ED420EA8 +:10BDF000E303FB76B8978E7094EDBF7DC0318CDF86 +:10BE0000DBC3D48EAAD03F38E161E724637DD6340A +:10BE10005C577B5F31598FBF2F898CCFFC3E5833E5 +:10BE200007C7A7844214EF1DF410EE6B889227A178 +:10BE30007EA0DFD414D298E70CD21BC6BFD16F24EA +:10BE400002F0491B8CC7739C2A3E653421DF1C829B +:10BE500073513CC768632ACEDF6520228DEFEFB3B4 +:10BE6000E2D88778FEF39B0D2400DF776ED6337A15 +:10BE70009FEFD2B379F45BFEA3AF08EAEB80FF52E9 +:10BE800060AB27375F3D5504F39E6F853A9CD7BD65 +:10BE9000C5C0E46FDDFD94F54FE65F855F9F95F9C2 +:10BEA000739D4FCD6FC9FC3A894F5BBF1B9F7E15B9 +:10BEB000E7D32AB4B370EF75F9C83F0F11FB419473 +:10BEC0009FEB270DF9B0DFD23EAB7D07D4E7EA4305 +:10BED0008FE4A15E38C9DBE7B7EDA75CBF88F7E068 +:10BEE000B98A8246B28B221FF1FBB23845568A646A +:10BEF0009CA6A2BC0AB152D443B0B484F7FC9A8188 +:10BF0000341DB2E177AE5FE6BE5EB07F5702DF0E52 +:10BF1000499C1F15BD576924BE4369D87FE0B6060A +:10BF200098E755188FDF67C8F355948D7B1AA09C4E +:10BF3000E3E47A3047DE87527F4FE67FD22A50A46F +:10BF4000E34A13A7FBB2EEE87A3C47E974DF6DA839 +:10BF50003757CC78AF0DED5AB0F42D9B0FF747EC67 +:10BF60003AECEF97E97E72F11F9EDB06E735DF6E54 +:10BF700061F7DA70625F0CEFB9A35C2078EFE68AB4 +:10BF800005F93E0DFE534AFFB512E2CB8ED73B2298 +:10BF9000131E4943AE47DD5CAFCE35F2F393081074 +:10BFA000A990E963615175BC9F727E4276B0FEE64E +:10BFB0008A17D83D6DBB9FCC67708A3CC5CEDDDC4F +:10BFC000364A37C13C6B0D92210DE8FCDEB4A6ADBC +:10BFD000172B0879AB0754241CE44C8F89F8FE0A10 +:10BFE000F0528F95D5633D05ACFEAF3D222B7367B4 +:10BFF000787F84F4697CA3B302E975B2F819AF0BBA +:10C00000D6B972C6C0E840888BD1699BCC7B5723D8 +:10C010007A6282F6AB833444687CFF1BAE15111F35 +:10C02000E893DFE37A30B0BDFBB74CCFD95B273C58 +:10C03000621AF2D5853EACFBBBFFE441DCF021D8AF +:10C0400009E42F7F9892029867FDB56C36BE3D3C9F +:10C050006A14910F74E31EA47FE03825C897FECEC2 +:10C0600009A63F9F837349B0EFBF756672BD1199F2 +:10C07000AFE3F7B980E314F9FE87E7FC6706EA2F20 +:10C0800053B7F8CE5D788FA7F5EC1E77B9C633AC01 +:10C090001AF7720EE625297CFF5826B737190315C3 +:10C0A0007618D724F36D72FB43323F02850D881357 +:10C0B000F08702DDD6CBFCD50247990678617D98E2 +:10C0C000462D20B72D11F72501CB4E4A3E52E903EC +:10C0D000423E4AC0C953F1DBAD961D385F45BCBE38 +:10C0E000CE079326E09CE6D65434A209EB07185FEE +:10C0F000A51497E7FBBE01DFF9C700AFC17D75004E +:10C10000101281EFDBAF55B2F2F2D0A322CA89C977 +:10C1100032FE0CDA05324BC7707D7B408D6F36CB1B +:10C1200072BBD9CDE5F929271510F782DEAAC473B1 +:10C13000DB0B7D7B902FFF58FC5EC609F8DC668C1C +:10C140005611EDEF1D88874D284FB06E25DCCF6B63 +:10C150001AFBBED7EDDAE7CC45B97A92F13701FE8A +:10C1600046BE4A3EE70B32EE51E479DD894B46C4C8 +:10C17000BBFEB0B63C77B99D2FE07EFA09A9D7B2D5 +:10C1800073F7C9F2DEBE97327AF9F766333A7D4625 +:10C19000F67A5DC0979FC13E0E005F5EF17A533321 +:10C1A00061FC159F37352B2D2EFF1D7B53D9B8FE13 +:10C1B000F255D99BA03E847C0FE7B81C769B90CEAD +:10C1C0001BF672B953D6FB30BA2E1BE5A7C6306EEC +:10C1D000B443FBF4C8850CC4753543ABB351FEA61C +:10C1E000DAE7CB2E7E1FEDDDDBB65ECCE6FCA007EA +:10C1F00079DA2ADB31FF8EA811E9BFB59B30FE1D2D +:10C200003EF27E07CAEFE548AA15EDDE67C7520386 +:10C21000A8EFAF1C4F09E960AA36E477D0679F19F1 +:10C22000C6EE66F871486F45FFCC7FFCD367501EA1 +:10C23000FD47401A61DEAD914727D0BEB545965EF9 +:10C2400012B07CE5FB9587F6EE9FB3F32AF54F7BA2 +:10C250004C22EACFCB02D7135BC387199EDD7AFD50 +:10C260006A95D786E7FCAF85A8CFFCBFBABA10F5B0 +:10C2700098FFE8D585D8EE7F3DB5530B9FBCEFD630 +:10C2800033BA2AF6B1E4AC2025F6EB95F9A3A4F76E +:10C29000C9FA52A05FCDE81ABB5E8CB7D754E8BC90 +:10C2A000D8BFE6DDDAEC2D89E362423D7E5F305A8D +:10C2B0009BBA39812F1F721B643D04520DFA679D92 +:10C2C0004CC375058FC7F455581702328EA0371826 +:10C2D000DE26A2B010FD7782CE3DE98F090CCF0497 +:10C2E0005AF5A10A686F8EE9247315F3EF038938B4 +:10C2F0008310EFF2B978DFF7E6DA7789CCDE931EA8 +:10C30000AC3F5411427B4F02A691F2041CB42EA6FE +:10C310008BA600DF344552A28887D6C5840BAC2E8D +:10C32000E3A30FADAF3D826E27E0A38B893807F002 +:10C33000D045355E22E9B85F052FBD87B80AF06C9D +:10C340004B57D480F60A7092AAFFC6A61F5F423FE1 +:10C350006C63B7FA7B494CD0AD84739680BA433294 +:10C36000F4C7F698503E149C89F735A821EFFB5D81 +:10C37000FCBE1439EA8DE9D83DF4C65CA672289F4C +:10C3800095E568D0AA230198BF37B2FA20FAE9BD33 +:10C39000D7D7A622BD7ACFAE223B50DEAD2E5305B5 +:10C3A0008EBBFE6353A32DCE1F93F4878BEBC73850 +:10C3B0001ED0B673CDF2BEBE2F7BB7D6F5C3B07715 +:10C3C000E0576F70E532BFBA99C73DB85F9D6C27E3 +:10C3D00014FDABCCFB847CCF93F5EF25865FC0FFCB +:10C3E00065FAF70997C8FA4D8F346433BFF8EC9AB1 +:10C3F0006C316DF2FC65825D97659B3CBF82D7FC1A +:10C400000169C4847E8CA467F2E95F434314EB5E48 +:10C41000CA70B67FBD2184EDCA7E626B28EBD768F7 +:10C42000A721338DE33F051FDE6C5F00ED2571BC56 +:10C43000A8E0C29897323F688D6460EDB9337C8F75 +:10C44000B86AF07C66F6BD66319F17F4C008FA47FB +:10C450006B7F4A09D303325E54F833194F7E1E298D +:10C460009BF64D71A3E764BE54E46B46925C28765C +:10C470006A48B6D31D68A71D68A7BF36A21C4C85A5 +:10C48000BBC14EEF73B171848D5FF0AEE0D5F2BBEE +:10C490006DB21CBDACDC5BEC0D27EEB798C4B6A347 +:10C4A000BF3895FDEC9771CC54ED43323EFC3639E4 +:10C4B0003E2B9FEFFB92E3D80F448E6FE23FA3F633 +:10C4C00039EF753BCF23FF5AF49D3127CADDAF0DFD +:10C4D0002C6E9DDCEF09D91E833D53DDCF48B15151 +:10C4E000877E8FBF95C7018299E23BCC3F79534F3E +:10C4F000709EADD70A194EBBEF5A262B838584DB7D +:10C50000D1074B58DCE6BE97460D128C6FEEA2F3B6 +:10C51000311ED4DCAA3E4F30575A9A18070F160E18 +:10C520009C42B90A1C2C1371FE163C2CC6435A338C +:10C53000433B317E81719C79F8DD12A703ACD32E89 +:10C540007FBF4B8EEF90241C7074F83C8BF7F8077C +:10C550002941F93546407FA03E39CDE31D1D11AE7E +:10C56000173EE936337DF289C0CFE1EFA6A1ED3465 +:10C570008E232E459ECA43399B842724C01379718C +:10C580003CD1FEC2BB4C1F26E387AC41BE8EBF4DE3 +:10C590001FC278CC48F1428AF576F007F311278A5A +:10C5A000E24F8AF8BE4888E91549152739701BB74C +:10C5B000FB9F9FFE77E647360F5192CD7087142B75 +:10C5C000CF8BE38E8DC165CCFE2B3863E3CC532338 +:10C5D00045389F8C33ACF08BF1C3649CD1111E3570 +:10C5E000A05F30094F24E1880AB73A2E3853E07132 +:10C5F000D699116AC578D24C999E77F45B182EF6BD +:10C600007CB0391BE55CB99FCB0DFCBE2E9FFFC2F1 +:10C6100089E3167E205851DF1E3DDFF5DB225E17D1 +:10C620004D228EEB4A453FE4F2070FA4223D8F4294 +:10C6300049405E5F3F2768C60FFF3E1E37BED38D61 +:10C64000F6ED61396E2C807D4B8FC75F92C7BD269A +:10C650008F0B829BC1E28E4384F16FB0D0B78CD533 +:10C66000F79592832CEEC3F9F57024D38A78AF1234 +:10C670000EDB0D7AE21F2DA417F32BC15CDF5B4CA0 +:10C680003EF6E918FFC2789697091C1299BD4392AD +:10C6900061FEA3CA087BA9267C3190B739F2BD158B +:10C6A000821F8AF917D8CD9A1B40A74A390F5265C5 +:10C6B0002102CEFF98C1B7EB76CCBB0C0BF6ED3860 +:10C6C00046B06737A44FCEC70077B37D2979198A62 +:10C6D00079976FC8CB505CA78AF31BCBC31089DE58 +:10C6E000488DE75FC84FBD2C29B473512741BF73F4 +:10C6F000B187F0EF93F3298F3B35F229FBD0FE3061 +:10C700007DABCEA7ED9AFD1AE3B7EF9A473BEB520C +:10C71000E64B5E5FE47E67D2FA0B323FCF63FECB1F +:10C720007F7F95C1EC59E42AB33B57C653488CC56B +:10C73000EDC6789C3A6260FEFA15F0837213ECD96C +:10C74000974E4E87131137E3C7C1586D2AF62F96BF +:10C75000ED65FFD935AB57229FC4047B05DB25F778 +:10C760006B0663420DC70793E874D0A5919F3259B9 +:10C77000B83E4FE6CF46993F1BDD9CEEEEF3DC5F03 +:10C78000F177F1FC815596377F27657AE554711E64 +:10C7900055E2C8F95AF985A171A6675BEEA5F68046 +:10C7A00038757E61B7EC6724EBA18EF0217E6FC9EE +:10C7B00071DB7A0FD33BB71AB725E80D2F8CEBE965 +:10C7C0000145AFCCE571DC3BDC5676DEACCEF9CE74 +:10C7D0007C123FBF063DC55AAD3CDEE47EF3EA6EF7 +:10C7E0002D2FD829DD5ABF17A55B5B77F016FB9D6F +:10C7F000BDC57E73B4E44CA35F8EF3D6CEF18966DB +:10C80000BFFFA379D0E43C67725E3439DF99F2E66A +:10C810009600B63D4A1F1F8F2275338E3451105932 +:10C8200021F30513CAC98AC53C2FD05F6B0AEDA757 +:10C83000F1FCA842AF020FC75F56DB44201BE83C67 +:10C84000438AD566833C5F594C98FF70C5CCF3038F +:10C8500044B01636B0FBB316AE02BD1F346BE79979 +:10C860007E5D27E3E929F4C9128F733ACA8B1571EB +:10C87000B9C63D1E96E394D63061711B228885AB04 +:10C88000D8BA6221DA9B696FF0EF195122ED67FB8C +:10C89000124B56311C2D96E0FE76CBF9AFAC65B34A +:10C8A0004A305E97057617F3234F619E84F901564F +:10C8B000D64F59EFF95ABEDE6E03A198CF0ADCCEEF +:10C8C000DF57907FB3AAF21B670CD18B9B28CB6FED +:10C8D000DC81FB7F5B17B51D28E1F782F4B50D5AAB +:10C8E00059DEE5378BFF61B68FADC3F31DDBACBC02 +:10C8F000CB49F437601FDB8E3918FF369F58FCBBDD +:10C90000F5880BCB0546E749785CF6B3CEC97EA225 +:10C91000E2678DA1BF98E0772CAFD54DA59796D74C +:10C920006AC8D56ECAFDE0C0DBDC0F7618ED659DE8 +:10C9300009F7B4B696F3C3A6288FC72AFE6D9514DF +:10C94000D2E5011D1C0FE9A32960AF1D7D738DA8E1 +:10C95000B71D7DC516165FDA7C48A7D05BEBDE37C6 +:10C96000D5723BD27F7A9CE5270E27E5299FAF350C +:10C97000B2F62C991F9FAF251C4F55083BD10C4F89 +:10C98000FB6BAB5E2B3EDE02F81FF7B729C8F7AB97 +:10C99000E4435AA2A21BD7B93032DE8765756B8992 +:10C9A0009BC50FDB26FAD07EFAAF5F3DB584C50389 +:10C9B0008C22E2ABE479E778F46CFDC30848905E22 +:10C9C0004B8510F6732C15D87D67B598993F9E65F9 +:10C9D00020FA34AC37707B565D9FE3C63A5993C951 +:10C9E000EC71F56931738B2DEEEF672DEDCA453A89 +:10C9F0007D5B9E48891BE4CE907620BF7DD73C515D +:10CA0000FB99B3463CF78631759E48C9FB4C952788 +:10CA100052F2B4FEFA2F547965BF30EEC1F88AE3C2 +:10CA2000D8059627F687A9B5A0249E3FF20F4E1889 +:10CA3000197DE5BC11F437E2B8C11E9E3F3A02EB06 +:10CA4000631986F34AB08F7F86F3621981F3E2F7A8 +:10CA5000E33DB35919EDB1B3F244CF22563A806D9C +:10CA60000AB330EF34C1F24E2FD5AAF3164A5EC294 +:10CA70005EE8FD05D229216FC1EAC9790BBD85FBAE +:10CA8000A3FED306FB01F8EE3F63627AD619D934D0 +:10CA90001371D997A3BE99569607C8667EA5C20F93 +:10CAA0009725BB3913FD01AFDD8CF902C7F025A333 +:10CAB000C8F44EB4089F3275083123FAFD4807893F +:10CAC000E139A719E9FAADF1FDF0FFC7F7BF4B7CDB +:10CAD0007F5E5C2E99FEA8F6EAA4FD589E96CC5B7C +:10CAE00012F443BF97C789FBCB4B99FCEDF19666D7 +:10CAF0006E4E8CE7D7733F2E6B69B939F17B97C7C0 +:10CB0000C0711F255E2D3DF6F5D4FAF66B2D7D4BD9 +:10CB1000A6C80BF4D7733DA2C4FD27E709EC6F96B6 +:10CB200027C4FB2FBF0D7C0A7EEBF0500AB3E75FF2 +:10CB30001E4B3980F8BBBA7EF3CC74A8579F4B21AB +:10CB400025DC1EA9F20BCDF53AC99CA1954F908A20 +:10CB500074C0B793F206F53AA6DF6FE60DEA850BCF +:10CB6000AC2EE3F40D137F482FA148FF5010FD8C2D +:10CB7000C3EDD43E4C26E71160E222B2084E517F4D +:10CB800096E595ED9DD42E8ADF9E5FC893E30C1D3C +:10CB9000E14C3DF279CB1B84E0BBADC979867A8646 +:10CBA000F7ABC993C15A7C8F55AEB3A23D4B8E17DC +:10CBB000209FA0FD4F8E13CEABE3F7384FC62B61FD +:10CBC00019DF57CBB84419977CFFBD75EA7C4472D6 +:10CBD0007B97DCDE5B5FDD8FF71758A12368077A50 +:10CBE000EB5DA6F284F95C75FC1DCD6ECC5BE42494 +:10CBF000E62D787E22395FA1E829C7F0D71EBCFF59 +:10CC00003D111E4FF217F0F8A6E3B8F334CA7D7C4D +:10CC10009FDCDEEE813B8E311C65CF24FC5CC4C4FE +:10CC2000E35E2CCE50BDE28B13A9483F2FD82BD406 +:10CC30004B67CA77A6A13E5921D45091C5BB6FC698 +:10CC4000BF313EB5FA9DD66504ED7FE3FC51A47B70 +:10CC5000E37A037B87A4D8ABD5EF347978FBFE1D4C +:10CC6000166C9F4DED6611BFD7BBF0FBF257A218B3 +:10CC7000E9232B91DA2037B13317059497DC19BEDD +:10CC80009FA17FE46890E3E0EBB97D6D8C34184898 +:10CC9000DA647B77B2F84BE6475F8D38587C3B1BF4 +:10CCA000F3AFB6B8BD701C033B94FE97B343BD759C +:10CCB0005646CF796087703F590D3C4F987CFF2EC8 +:10CCC000F9FEA7B22B53E951B423BA455C6E684113 +:10CCD000DCFE8AE85FDF11B7C3D630D4F3BF21EEA4 +:10CCE0002DE3ACCC2970D82F657E9FF2FD46F8FB72 +:10CCF00089831FAAFB81C4C1653F4789872B7E5169 +:10CD00009A8C639532DDC3E9FEBF7EBF8CC651F3BA +:10CD1000FD7296F6FBE50D03147186F27E79C44828 +:10CD20009C8772F0DD1E25DB51BE430D0CE78C3C69 +:10CD3000FBFBBE97E17BC720B5A2F9691F1865769A +:10CD4000BA1D700DC343914F799C6A80BF376D0F38 +:10CD500053492B0EBA40B6CFB512617AA35D7ED788 +:10CD6000E719E4721D8F13FD5C488C13F9C558AEAA +:10CD7000F25E30C4ED93E6BBBE0E32CEDE0376B477 +:10CD8000527B14BE27C78D92E3454FCAEF00A78C94 +:10CD90001B49DFEDBDDF9FEAD2733E061650E2CF9E +:10CDA00005B53C4ED4E4A314E737E9BC6DECDDEFE8 +:10CDB000716AD57A3F9AEAE17667B91CBF7DD1C81E +:10CDC000F9E1C53B297B4FBF9CF038ED8BC7F9BB20 +:10CDD000FA17ABF9BB7A255EABBC97BF3D1EAFDD42 +:10CDE00083F15AE59DBDF26E9E9010BB8786BD967D +:10CDF00028E28DC70C0305288FCA7BA3A375DCDE50 +:10CE0000595248A7967C7E55E73C5AC7FAE9A6884E +:10CE100077FAF23D1A71209FECB7157BA6C4E9A200 +:10CE2000275785D3593D19A7FFA5E2B547EAC8544E +:10CE3000FBBF5F1BAF4DEA77F116FB9DABD3A0C7DD +:10CE40004E397E924CDF1E8FA287A75B193FDDDC37 +:10CE50003FE1F95C39EE3522DBB920157F7717CB3E +:10CE60007F1958FE4BD133C1743EFFDDB29E51CACB +:10CE70007BE53268D08ED374C9ED730AA595788F9F +:10CE8000952FA9E3667307D471B379E12C557D7EA4 +:10CE9000F436557FC7E952557B4D6C8EAAFD8E73D3 +:10CEA000D5AAFAE2B13B55FDEFFAC4A5AAFF685C2A +:10CEB0001D375B724D1D3753F8DB091C9138CE6D61 +:10CEC000FA1B55BFA256F5B98A3BD5E79AD9AD3EB4 +:10CED00097326F49407DBEB2A0FA7C5918D7B7FD92 +:10CEE000F971FDF15A518EEB979971DCEEFA7233BC +:10CEF000E2183DE631E1FBFF001DADB367003400F1 +:10CF000000000000000000001F8B0800000000006F +:10CF1000000BE3146060F8510FC1D3F9191836F310 +:10CF200023F8F4C0C79819188E83302303C33E201A +:10CF3000DE0AC46B80F83D0303C352203D078827F7 +:10CF400003711710BF048AD5B1623787858D81813F +:10CF50000D884F02CD3AC54CBCFD8A7C08F6215E97 +:10CF60000686B5407C9497BE6130D8F00C41FAD962 +:10CF7000F50C6AD76ED181F73708B38A3330304A5F +:10CF800020F8FD12A8F26CE20876960C6576950101 +:10CF9000F50300295128158003000000000000005F +:10CFA0001F8B080000000000000BED7D0978544540 +:10CFB000B670DDEE7B7B49BA3B9D90952574802051 +:10CFC0002A4BCB1201113B2189010306440928D2C7 +:10CFD0006C2184249D01661E3EFDFF6E0842C4D173 +:10CFE000898A1AFC195F83E004079DE0A0139DC0A5 +:10CFF000348B8833E804C70597795F401E204212BE +:10D00000A338E8F3C9AB73AA6EBAEB763769B7FFFA +:10D01000F97FFF840F8ABA55F7D4A9B3D5A9537500 +:10D020004F149D9524DD40C825F8A1E5AB0A2124C5 +:10D03000255876489DC3E581C1F6B55E177119097B +:10D0400079C06BC272BD379DB8AEA0CF47EB8AFCEA +:10D050001642EEF7DAF1F9E3DE122C1FF59662F9CB +:10D0600088D78DFD1EF29663F92B6F0D96F77A8B9C +:10D07000B0BDCEBB0AEB372A0BD2605C425CA6ACDB +:10D0800064423C2F0F1CB981D6D6678E4F9047D390 +:10D09000FA5FF5449F45DF1B2D17F987D206B9A427 +:10D0A000286B74B09F8AE78D4A5E5F80F3F8581D45 +:10D0B000EB67AA792D3B72BF2C3286E2395646FCCB +:10D0C00089A564727672C47E8301DE2343D93C89CC +:10D0D000DDF9DAA0C8F0AE06780F0DE5F825DB27FC +:10D0E0000F8A0CCF09FD7EE5E4F0D23B0F0F8CDCFC +:10D0F0006F0CF4AB7372787D7DA60191C71D0FFD97 +:10D1000062E013C589105F8BD19F9DF5FDF9455CE9 +:10D11000F42FC5A763AF79EB0609F9370DE8B4D64C +:10D12000BEFCCC163A4E7BCB30A7DE41C8672E67DB +:10D1300082DD1213DF6E8179C4C0B752182706BE94 +:10D14000CD8D916F0BA05F0C7C5B02FD62E05B6597 +:10D150008C7CFBD94F846FF7021EDF836F1B62D478 +:10D16000B75FC5C8B78D31F26D538CFAF6648C7C0D +:10D170007B2A946FEA73B5DC4124B48B372A253BB4 +:10D18000A09F27B3CD3620EB27C1BF3DDF53EFF67D +:10D19000C7C8BF5763E4DF11A04F0CFC3B1A23FF45 +:10D1A000DE89917F1FC4A8776DB8CE58E4AFDA86C8 +:10D1B00010FCB93400FEB5D84F5DCDEB7AC03B8989 +:10D1C000908C7039504BCA51940799B8DBD9BA5535 +:10D1D000F0CDA51C425698E87FE9FBBE3C12D0D3A7 +:10D1E000F17D36E2AF9584FE9F039E84E47F732930 +:10D1F00055E8EFD345EC4F74D0FE30C815E5FF6617 +:10D20000EF102CEBB91C6D2ED2A13CF8920D285FCB +:10D210004F789DD8DEE01D8BE5635C2E3772397A3E +:10D2200000E4EE0A90C3522E574CEE082971945335 +:10D23000BA76EC89271B1C28576609F09499BCDD47 +:10D24000BBE7CAAD1B28FCCD35BA2BB785C8D913AF +:10D2500045AA7C51C94C0EF67BA2FC846DC150A43A +:10D26000B70DE03414EBD47EBED07E0DEEEE7EBD65 +:10D27000A0DF63C55CBE6412081DF7B1D2EE7EE983 +:10D2800012A5CBBD12296DB284F3658AC4F4942A29 +:10D290000AF243E6F4DD9F7796B4D1F76DF6916913 +:10D2A00084964F827EA2FE39B054DFAFA7747653C6 +:10D2B0007A641A494D13E04B5A2585E22B8F752469 +:10D2C000821C3D34CE45242B21FDA19D8EDF677449 +:10D2D0001BC9A265E2F836220D837EB49DD6537831 +:10D2E0007BC650DA4EE13C04EDD6607B2A6F4F736B +:10D2F000F0F7AF63ED0F7B098EAFF6BB8FF2D94D20 +:10D30000F15B47F1C5E7C5C4057494293BFD21F3E2 +:10D310009F2DE971DE95BC54F1BF2FFB54C6FCA1D3 +:10D32000417CCD832F66CC0FC1EFBEC173B0AEE29E +:10D3300063BEA212EBFD57F5A69E18D707124EE763 +:10D34000D49903847687EC443FCD71444F7C945F3D +:10D350000E2A9E91F8F30515E71F54FF5C8C1EDA28 +:10D36000F6BB3574589721D2C1D05BA4C3BADE2274 +:10D370001D0C7D2E4F87299203E147A3873AEE8645 +:10D380002BC571E3AE12C7DD7095386EDCD53FCC8E +:10D39000B8EBFB89E31A33C571D7678AE31AFB7FC1 +:10D3A000BF7189ECA40F99B9200EF8679E60DF2E3B +:10D3B00010F7C3A0DF60E7F4C9413B27DB4B88DBF4 +:10D3C00012E42791E9CB39A170EE14EC2A85F37FA2 +:10D3D000381CD7E5E1D83570E66AE16CE37048A8FF +:10D3E0009D0E8343EED0CEE3B7FCBD802E647CBAA5 +:10D3F000BE92126BE87B4ECDF8B76BC7DF0D760C93 +:10D40000E6A1BBECF80E0D5DE768F1D9C3E110DDD4 +:10D41000E5E841EC1A38B3B5700E713801E9B27025 +:10D420004AB5F3785DE5AB24AC5F941EC382EF751B +:10D43000E4759E423FE845C5B19DB64B7FB2066E8E +:10D44000A0FD8F6C91FC465A0FEC8DC7F5E3FCB63E +:10D45000E958DF778D11D789F3CEC97E23B527939D +:10D460005E78DB06F6A5EA05BD0C75DDDE8F6D6D19 +:10D47000142F8FB1F5C1EBE8F3CE17F4642B4A6398 +:10D48000A10EE87E8ACB2659C5EA656656ADDAB2AA +:10D49000EF4E805BDE6C24660AA7EAA525D3AEA317 +:10D4A000F5258715025DAAB6AF36F4A6F5A57EA9C7 +:10D4B00009EA1D79A41CF469CDDEFF6C87F5E8FC50 +:10D4C0006E251BC63F4BD70907B5C747ACADA9337F +:10D4D000291E15FE5D85F05EC54EC9492D1CC57718 +:10D4E000FBA10CC07787E434527A2F6B8C270ED5C2 +:10D4F000DED1BFA776EB71FECBE9FC0985B784D4FA +:10D5000017023DAB803830BED3E8374B417D3BEB53 +:10D510003D8CE3A9F5AA1D743CFA7EF5739213A61F +:10D520005AAD236EC0B3FD2573E9531698E76AC35D +:10D53000602BCC6FBD01FA2DF1CF7FD1EC003CB751 +:10D54000180A01DFCD5B0C6543817E645EC950C063 +:10D55000EF2F227E0D7A17CC77F935C6AD7AE0A78A +:10D560002530688635DCCE9EA5EB952364FDAC2086 +:10D57000CCEE13D96F983E2CF8FC257D22CAC1B29F +:10D58000463D7184DA0D2E1FBEA384F9317BACFEBB +:10D59000ED59413E2EB77379E57C5C9EC8F92A7738 +:10D5A000E6CC18168ECF83C01723F38FA07C98AEDD +:10D5B0009B0EF47F1C48BFC7A8FFE440FFC889CF7B +:10D5C0009FA07E12949BA99F04E593D44F82D24FD3 +:10D5D000FD24E8B795FA49506EA37E123C7F9AFA73 +:10D5E000E7503652FF1C9E3F43FD7228777A7DF844 +:10D5F000FC396F1D964DDE7A2C9FF73660B9DBEB58 +:10D60000C77E2F7A1BB16CF636E1F397BDCD58B6C5 +:10D61000780358EE053ED332E06DC572BFF7189619 +:10D6200007BD6DF8DE21EF192C7FC9E96E9B4072B2 +:10D63000652A2F3617B1039B928A5DB9E0AF249516 +:10D64000B07AEA1DBE5C03ADA7BA699DD2B1776519 +:10D6500020D748EBBD6B587BE63D24CF44EB993E89 +:10D66000D63EE097AE3C33AD0FA867ED8337FBF2B3 +:10D67000E2687DB09FB55FB53390174FEB5735B17A +:10D68000F6E12D649285D68707587DE411D7242BC7 +:10D69000AD8F6C65F59C0F7D936CB49ED3C6DE1F79 +:10D6A0007F2E302981D6C777B2F6895F937C3BAD58 +:10D6B0004F2412D6F32CB9F989B49E6767F5C2BE20 +:10D6C000F3654784F57DAFD2B6104CDACF7539B922 +:10D6D00032F513F61ADA5680C95DAFBB21571E47E3 +:10D6E000E9A79045D0BE4957C4EA06B212DA7FAB2B +:10D6F0009B8EF5FD8A03DBF7E8E6B0BAC181ED7FCA +:10D70000D52DC4FA41C585EDC77595AC6E7061FB2A +:10D7100067BA9FE378871437B62BFAFFCDEA06374E +:10D72000B63F2CAFCFCDA7FD2BF56E8F8ECA75AD52 +:10D73000E42E2703415E9BD2C11EAEE37EEB2C9DFF +:10D7400003E57E5D8601F56CEF7FE53C857A063F5B +:10D75000C9502F7B1AFC5E0A6715C251281C7DCF69 +:10D7600070267E33568033F19B7215CE6A84638EA9 +:10D770000DCEDE6FC68BF87C53A1C2D9A0A3F6BE36 +:10D78000D61ADBBC265E9A20E273A95285F308E222 +:10D7900093181B3E01E55A014E4059A2C2D98C7024 +:10D7A0005262C3C7651827C0711996AA70B6239C28 +:10D7B0008CD8E0040CD789F81896A9709E43FAF427 +:10D7C0008B6D5E2EE3F5223EC62A15CE1F109FAC50 +:10D7D000D8E0ECB78AF4D96FEDA64F00E164C73604 +:10D7E000AF3C9B489F3C5B377D5E433857C606671E +:10D7F000BF4DA4CF7E5B377DDE4438C3629B575E4E +:10D8000082489FBC846EFA7C8070AE890D9F83290C +:10D81000227D0EA674D3E724C219131B3EF9A92258 +:10D820007DF253BBE9731EE18C8B0DCEC154913E4A +:10D830000753BBE9F305C2B93EB679E5A789F4C938 +:10D840004FEBA6CF258493EB6E447C0885638D0E49 +:10D85000E7503F913E87FA75D3C7A407380514CE29 +:10D86000C09EE114668AF429CCECA64FA21EF46295 +:10D87000726C700E658AF43994D94D9FDE88CFD4CE +:10D88000D8E655D85FA44F617F461F8FB173921DB4 +:10D89000FCC644E2DC4A5F9994FCB383B0EE2816E0 +:10D8A000E204B047A4C036804FD756F44B65A7EAD0 +:10D8B000073909F8B9C5368713E2017AD5DF21ADFA +:10D8C000B81FB1EC4C14E24D2FE9F38603BE56EAC3 +:10D8D0001586FA3D0963E3047F2BD19524D47B158B +:10D8E000F516FAA7940C10DAD34AAF12DA33DC2318 +:10D8F000857A9FF2F142FF7E357942BDFFAA294227 +:10D90000FF2CDF0CA13EB06E8ED03FBB7E81D07E5F +:10D91000454385D07EA57FB950BFBAF15F85FEC370 +:10D920009AD608ED239A3708EDD7041E16EAA30EFF +:10D930003F21F41FD3BA5568BFF6D83342FBB8B6BF +:10D94000E785FA75675E16FA5FDFB95FA8DF70F1E9 +:10D95000CF42FF5CF237A13EC9F481D0BFC0FE9137 +:10D96000D07E63FA271A3F568C5FD4E612E6CF6664 +:10D9700018D09F0D580D5837EC35B3FD0DD49321B9 +:10D980000E518C75C3FE858E6488070000EA4FE453 +:10D99000F62EBF02E255BF18EFBE02E2B8BF30B8A4 +:10D9A00047D823F841EDB2FB1E3DC6135B25920E0E +:10D9B000A54307659C9EC7138C4C7ED767E53CE565 +:10D9C0000BD183BA7ED4BFA0F5F57A8AC798A0FEA2 +:10D9D000ACEF57963E3F649C75FD0CA55B87B2E7A4 +:10D9E0000B2D305EC97D309EC7D03918F0D28E63C2 +:10D9F0001C305618C794598EE36C84715282E31818 +:10DA000033CB35E3984AB7F2E77C9CC7406FA28DD1 +:10DA1000B37EC078713E991538CE16CD38EB332BD6 +:10DA200034E3C4B1F9D0E77C9CA72E378E71E004B3 +:10DA3000713EFD2B719CE7B4F3E95FA919C782E33E +:10DA4000C0731887F4A5BB9834CA67636719CAC145 +:10DA50009FCC182733F4A9F80DD4C90766920DE3BB +:10DA600038E8B8B41F199244859A907FD127217F56 +:10DA7000BE88A3FC0F89A705F7E33EDCD72FE62875 +:10DA8000123FC588EE93AAB96C2EDA393D738583AF +:10DA900096CD07063D02E36CB43AB369BDBD7992F9 +:10DAA000616104795A5CAF9C6A0B91F3EEFD591EDB +:10DAB000195243C75F1167477CD4BA5A26E9C4E7B5 +:10DAC00027E8BE8BD0FDC987749F42E87EE5238599 +:10DAD000ED33FF9DEECFA0DE46F767D04EC86A7CDF +:10DAE000EF048F339FF8A5E4077A7F71D7CF145CDA +:10DAF000277CE4ADF4548826B09F79ABE2291382E9 +:10DB0000F8CDF7F512EAD41CF7D1A5E3BE16E3076A +:10DB10009D2F19FD5B81AE757D284D79BF0184BCB9 +:10DB2000BB77EA21C986D53EBAB184CCAC995E9068 +:10DB3000865A24F55B4EF19CB1FB1A85BE41DA95FD +:10DB4000B63B9D96205CE2524E007D4CF40FC0B96E +:10DB5000A588D643C6BFB544ACCF2272B04EF97D7E +:10DB6000523F80B0F83F1FD7E15280AF25748E1925 +:10DB700094D5B3A01C09CD2C5E536A67EFAAF87840 +:10DB8000162A2480FB6B5F0AC4B1892F19FBCD5183 +:10DB9000F7C91AFC4A1593AB84D2B574BE1EE9AA24 +:10DBA000C5F7FDBDF12EDD705AD63DA24068B627FF +:10DBB000FC67BBC57652CEC653E9AACACB29CEDFD5 +:10DBC00013C07F5A9E06FE53BC4F72FE07E598F1C4 +:10DBD000DF63744F03FE776ED213E417E7FB6D9C8F +:10DBE000EF8BEB45BEDF06E771B4FF6D2BB358BC7E +:10DBF000A9A197C05F3A71910EF50F1550B31A861F +:10DC0000FFDFB91CCCA9DBF50AB0F7F672CDFC3802 +:10DC10001FEEE47C98ABA1C76D9C6F7339DF961043 +:10DC2000DFBD1918BFF02B10D79B5D2E11B0179ECA +:10DC3000BB55BEB5097C73AB7CD3E07B27E7DB9D8E +:10DC40007731BE69F16EE37C6B6BF84C2103C2F156 +:10DC5000D6E2396F95665E3E2DDFEAB95CDA0DE0FB +:10DC60004F4D77E5AE3819D2FF96A2C92B4E86D814 +:10DC7000855B4BA60BF559A5B385FEB3DDF385F6A1 +:10DC8000DBCB970AED736B7E26D4E7ADBA4BE83F4A +:10DC9000DFB75A685F58779FD0BEB8FE21A1BEA4F7 +:10DCA0006193D07FA97F8BD0BEAC7187D05ED5B495 +:10DCB0004BA87B9A5F12FAEBF65E7933C8D791B71F +:10DCC000F504E27D179CA731CE78C1A938A1CF49D0 +:10DCD000AF03E5F89477089667BC4E94F3B3DEB1D2 +:10DCE0005856834C8E033B7BC002F1534F1CB5FB4F +:10DCF00089741D97C7ADA99B00EB0D6D1F4FC8BF61 +:10DD0000CA37ACF1F5A55A00716F4AFFE206030964 +:10DD10008C2254BA7B77CB73A73EA4BDAD87F606A1 +:10DD200099047A85B717B7457EDE21750ECE80B887 +:10DD3000EC7B46B23D24DE187EDE42FA805F11ADF8 +:10DD4000FD9C8E94879EF76C95D939CF117DDE5658 +:10DD500099E2556960FA5FF97C461EB1413D30B8E1 +:10DD6000C67299F19A283269C0E78182DE2F69B8BC +:10DD70003AA8E704C661F674A97F94F07C59E3756C +:10DD8000C27B6F48EE2D80C7B97D7A5CAF49E04019 +:10DD9000E62DC3003FD75619D6D1E614F4BB5ABDC1 +:10DDA000AE15271542DEF41661F996B704CB77BCA1 +:10DDB000A5581EF3BAB17CDF5B8EE587DE1A2CFF17 +:10DDC000DDBB0ACB36AF0FCB13DE3A2C4F7AEBB16B +:10DDD0003CE56DC0F28CD78FE5596F2396E7BC4DBB +:10DDE00058B67B9BB154ED674FF27786AFAF674172 +:10DDF0000E8DE1727670EDBC35757D837276582E8E +:10DE0000433953E95BDC60E4F2902AC8C35F611DCB +:10DE10004E0179E9A1BD41E17218EDFDC8ED206F19 +:10DE2000BD7F047923640DCA8105E4EE7BC81B81A4 +:10DE300053841490A73E1A7912E550952355CFDFED +:10DE4000904ACE817CA9726591993FA4CAD5FDE024 +:10DE50002746F0B77A2B125FFF987F4402B93A2029 +:10DE6000D9727E5E417C2EAC77F1B16B29B856E851 +:10DE700027FB87C03AD235E4ABC110DFEF3A4685C5 +:10DE8000202BFAFCB4F2129DEE2EDC3F94F929F31C +:10DE90007B85B79BE3185DCD3A524446C2F972CEFA +:10DEA0003137E567DC9FAE1E09FB66FA5C26490048 +:10DEB000C7EF9C1EE1BC800C2248E79EE8ABF63F12 +:10DEC000F5C47FE6C0B9BF05F49CCE3DEE80BE86AA +:10DED000E9EF53CE5B42CE973C46673AC4C13BB3B1 +:10DEE0000D76E63F4C12E94826E1F9814AC703D98D +:10DEF0005F0C86F399FBA81C827E750D1A9C402E40 +:10DF0000231F3DD9FB9EE8B900E61B133D0D04CE4F +:10DF1000B9283DB7C27DC758E9D9939DECC93E9E4B +:10DF2000D8C0E87C84FBA7D1E8AC9E8769F1B845EE +:10DF300091391FB81C933B34F42F15E8DFD7EAC0A2 +:10DF4000FE07F77E9009E7785DBBAF48204343DFCB +:10DF50002F60E73DDDEFE70B7A20FDE9EF99B03F59 +:10DF60003EF8C2BB58AE254C0F375A4AE62A6382A8 +:10DF7000F062BD47106D5E1E4512E7D5837E76A424 +:10DF8000AAFAD99A09F2B49BDB81B0F9F5209FEA8D +:10DF9000FC0EC0FC289CA920D3741EF972C95DC276 +:10DFA000FC46A7E0BC7B9A9F27C140A411143FAB5D +:10DFB000C14012A83C2AEEB50AEEEB9C6D3E885398 +:10DFC000EC8D77D65296786C67DF0838E03D319E4D +:10DFD000B1ACD15C23FA4F8935A2FF945113EA3FCB +:10DFE000751D7ECAE6A6F82D4FD7D79CEC05EB9C95 +:10DFF0008BAF736C5D55F1AB6ACAAAB10870C47A75 +:10E0000057BD54C4EEE13812664638EF53CBE5E90C +:10E01000061CE76CE3C00418F7ACD754C3D6577B93 +:10E020000D1B37BD26747DAD5C155F73725410BF38 +:10E0300068707F68FCA844908F4CB02ED2B681D116 +:10E04000FB47E5A7FCB901CFD55B942FC07F370F05 +:10E0500051FD7719EB2A5C4F93DE671C01CF770ADD +:10E06000E3D1F71CEAD938BC175D6E64724AE5A7A4 +:10E070001ECEBB08DF1F9890CF6E0A3181C2EB9095 +:10E080002D7520577E85E9B387CB6995A9CDE076BC +:10E0900020B95B41AE178C55E5DC31EB036AA73F35 +:10E0A000FE8B82F7CCC8D7147A4EF0AAC3225262F4 +:10E0B00083A0EA82DDCB8A61DDFEF8C59BF83EBD18 +:10E0C0003E07E67D9EE88AC02E9D276FDA4685E8EA +:10E0D000EB6985C5B1481DDBE7F8E81F98DFE27AF8 +:10E0E00071DFB3A441AC979119A9606FCB362AC4F4 +:10E0F0004F715F0AFB2675DED4FEBEABD811B92581 +:10E10000A4661DECD31F5358BC67819DC87DA8BD74 +:10E11000AEFAC3AF7320EED3AE307F573D0F5F9A98 +:10E12000C4F6831533FD0617EDFFD1EE51B7518BC1 +:10E130004BDFF7AF43FF673A716E27E1745F5827F3 +:10E14000E2D713FE5A7C553F28EC5C9EE391DC2815 +:10E1500045BC2FF535B773AA7E2419EC42DC274D58 +:10E160005357E540E172E057DC56430AE33BF05178 +:10E17000923B0DEE907E8660BF24C398E8FD8CD064 +:10E180004F8FFDD258BFCE42DC1F132A4F4383FD71 +:10E19000CC41787DD9B862BFAA3F3CFBA28FCA4B65 +:10E1A000C5EF1EB511BA6E7E2CD7A73AE9F3CAEDBA +:10E1B000F7DA5CB43C23FB6CC0CF8FFDFA88F77DA7 +:10E1C0006F31A8F470592488A771F924753E8C53D7 +:10E1D0007CB15DB1E33942A33160A4F259BD7B69E2 +:10E1E00031198EF5E3ACBEFE533DD49B457E55FC04 +:10E1F000E6D15407BB27C4E24924807E6EF5B6FF02 +:10E200002884F5C2433A51CEB4EFC1F8179350AF0A +:10E21000E71B12C2DBF162702ABCCF7E3CBBEFFF72 +:10E22000546F8372F269D0238F464ECAB9DF0AF465 +:10E2300082FD7EBEC19A8CF6FE5A722DE8BB4A174B +:10E24000E267FE6BED8EC7871FA7789DDBF6179BF5 +:10E250003434D44E3079EB6A5AF86F265D747BD231 +:10E260004EE531D44FA280F13D4733F7BB5B58599F +:10E27000A9046C701FA7728BE2A492482A9FD51341 +:10E28000B89F40DE33FA213EBAECD957DE194FE988 +:10E29000BF6C97925CCCA663915283FCF1D0BFAB6C +:10E2A0004606F951F1FB570C8E61ECF93D4941BE30 +:10E2B0002CDBB5CF408685D37152D33E439B2502DC +:10E2C0007F9A8E17C27A5BBBE31F06882B7EBC57F2 +:10E2D000226959E1EF976F7905D73DA013F293F3C7 +:10E2E000AB9B7F617C0B4C7B7934F6B3833DEC892F +:10E2F0006FD9B09F4B41F97EEE65B8C7F4BED10926 +:10E3000074287F6E850DE6735AAE6172FEEB7B5307 +:10E3100041DFCB155FAA1D4BF6BCFCC99FA3FC2DAA +:10E3200039FAF354F41F882B4387B6D99701F35C6D +:10E33000BCF9569C671971A31C96FF5A5F02F74CF3 +:10E340002FC8A46857043DF98B81ED5F4E6FA5CCB3 +:10E35000A5F33C0DF8817D7B53EFDF8E71F39FE1D8 +:10E360003DB89FF339D39510EB174C8C5F5B0C3A9B +:10E37000351E6A12E477DBFA56E0D3D97EAE343824 +:10E38000F7A074F071BA4997285CFDD18234C62792 +:10E39000E29073F87BD4DE4F82E7D0BF5571998746 +:10E3A0000BEF71FBC8C65FC9C7A778C7C1FA753A3A +:10E3B00035B2FFF70F3E3FFAD34A42E42C44DF99CF +:10E3C000FE6FBB8FE9BBAAFFFEE945D0FEF95B4CAF +:10E3D0008FE03D582F285E81346CDF375342FB407D +:10E3E000F7D991F47C9BC2F55C6CA73B1C5CFF5594 +:10E3F00039A1F8CB5242A8BCD07192900FB83F2EF1 +:10E40000DB48DF0FF1CB3C302EF633049F87AC1B8B +:10E410004BB85D38A4B10764734A4C7E74A5E27FA3 +:10E42000FA09D0DFF78C4E9F03F4572981F97FB2A8 +:10E43000F3C03B73A89C7FD2A4EAAD6857B57A5B62 +:10E44000FEFC1812496F3FB1D07D5724BDA5CF23E4 +:10E45000EAADA50DE5F9FF965D55E9D7AEA11FD848 +:10E46000C7971DD1E9A8B58F1B0C8E88F691FEBC0D +:10E470004572C2E550953F55EE2A7E5BD51FEC50A4 +:10E48000B77CAAF2D72D9FAAFC69E72BD24FDBFEFF +:10E4900007D06F8AD7EDA64DD3C07F3675128CC3D7 +:10E4A000E7CED4E33D4DD3E784DDD3B8231EEBB3F1 +:10E4B000F46DBF079FF083AA59C3609DBF9DF814F8 +:10E4C000766E5FAFA01FFBF5A54B13E87CE670FAF4 +:10E4D000DE4EC93D95F2A35496027114CFD932F1A4 +:10E4E0002524413C59222742F0B8BD5CACC3CFC4BF +:10E4F000D4209C9EFA7F5BBFFBBB9647295F4F648D +:10E5000013F2372871FF411DEB10799ADEC2CE312C +:10E510003CA325FF00D4C336B924641FE13132FB8C +:10E520007334FF963140BFDC59C312989C0FC6FD6F +:10E53000A287DBB12E9F2301EC7B57CB40DC177603 +:10E540001D5E687547B06707B89CBDC2CF613A2CA5 +:10E5500052BD9ECA7D07E944BFC66731478CCBCD0B +:10E5600031AA769AF38DFEE8E9F8A55C0E67D357D9 +:10E57000134686F06DE6D48F655B381FE0E744C82C +:10E58000BEE2FBD217E41AE87BC0DC565812217EAB +:10E5900053C9E93771FF970658F7F25B7265A063BC +:10E5A000BE452FC4431619B9BE0E254301AF89FBE2 +:10E5B000973E3086CAB1E7B0DE69A6F3F3B47C6A51 +:10E5C0007047D8DF69E909F0C1BFDC6A64FEF2DB9D +:10E5D0004AC962A0EBDBB7B2F3DEBF199C5591F0DC +:10E5E0004C37337F733629B9305AFAE9D1377796E9 +:10E5F000359047E9D16561F7B5C3E58FE97D975D52 +:10E60000F2AF96400EF5AC9ECCEE371712F703131F +:10E6100024D4F71B42ED576EF3F467E13E4D758B42 +:10E6200064D7D1F66AB9CD0072EC69DE2583DF7E4E +:10E630009383B8707F2DD70C9B1912FFA2CB1ED2EB +:10E64000EBC05773E6027D3F9B692480976BE8A778 +:10E650003658FF3F6B19857A106D5EAF7BC9B47C6D +:10E6600005E0307BA69587C2E478A17EEB24D21723 +:10E67000CE81271ADB563823F02FDFC4E42C66FB4B +:10E6800066FAFFCCBE4DA0F68DC9B5126ADF2CA686 +:10E6900030FB9616C9BE2D5FED4803B958BE672002 +:10E6A0007EBFB5FCB5C52991ECDBAB7CDFFB1ABFA7 +:10E6B00007DED197DAB71121F6AD2FB56F11E2E47D +:10E6C0005FC46ADF4CFF33FAF72AD8B708F3359BEB +:10E6D00044FB56D4B21AED5B515FBD705F8998A8B8 +:10E6E0007D8BBF9C7D9BFFE8AD58579CF111E407E3 +:10E6F000E80AF6ED356EE7601CB0733798587C3346 +:10E70000563BD72F563BF73F4467D5CE2DEF27A179 +:10E71000FF122E87CCCE2DCF62766EF91E66E7965D +:10E7200067333BA7B56F7961F68DBD5F3D84BE8FC2 +:10E73000FBC7ACC7EF80FB84A58AD344FB173BD44F +:10E74000EF276AC684DABB1B4C32D239CCDE393FA4 +:10E75000C5EF607AB2777F057B978D766C10E89174 +:10E76000563EA60C8A17EEB3BDFDE5A9DFFE0EF4FA +:10E77000E5753DDE177A57C7F6477BBF3C350AF48F +:10E78000EE2113B3BF4B4C8C9FED5E1FDAD3494390 +:10E7900099BE57DDC3E857BD5B62F35DA9F73B60E7 +:10E7A0001DF8EA22EE9FE7EE61FBE759C6D69478A2 +:10E7B000B897F42F0A61DF7D90E2F921F2507AB127 +:10E7C00002E380CFC7D9B6C2FEB2542626F063E773 +:10E7D0001D9EF231F8AFF32ED6A1DF3B0F9EC33959 +:10E7E00009BF27A1DEA398D3BCEB953E24FC7EC4D1 +:10E7F0004423E3C3C415927F4B16DC4710DBE76963 +:10E80000FCFA757C9ED49F45BA90BFEA23C6EFD62A +:10E8100069E9E164F3AF5AA917E9512345A407E573 +:10E8200068F1FCD4E0FCE7BED0B6AE0FB42F957013 +:10E830003FA5D2433B4F953EEA7E651ED7114FCB95 +:10E840002E05F8A59DBF4ABFB079ABF4D4CCBF4E1E +:10E85000B51F579361A06FEFEADC0F8C01F9F83315 +:10E86000A503C5EBB6D9D969A1F6F8416E97A6BA4A +:10E870008FE7A73A806EECBBC439E5BB5E49A5F3D0 +:10E88000B9D9953512BE1FBEF52B831BE20B07CC01 +:10E890009D68DF54F9FA84CB7B80C379BBB73D1FF9 +:10E8A000D79166C98E7A13D0D82F7E7FCC730FD3C1 +:10E8B000AB03D23FD6F5198D7485658014AAEB1091 +:10E8C000F081FE776A0BE38307F840FF3B8D741EEF +:10E8D000023A57274BCE00F46FDE752FC8CDAB66DA +:10E8E000FA1CF4B75C72B2EFCB882523F5B2F2299B +:10E8F00047924F0C4EE404D7C579D02F29DCEF980E +:10E90000686C7D1BF09848F5610B09F74354BE0F06 +:10E91000A17F2E45BAF7D3831C7FCCE5F355A0B772 +:10E9200005E8DA69007FC61360EB87DAEE911DF91E +:10E93000481F95DECD747D18CDE8AD8B40CF9BD5BB +:10E940003AA7A7A74552E0FDC974FFDA4B82D3ADC1 +:10E950002F0FA9720CDFC369E901F1808C10BD078C +:10E96000FB147A3E59DD7C14E932652575AF42E827 +:10E970000E76EB72F489A617D5CD3F8C5E7CA2D1C2 +:10E980008BBDE6CEBF8C80F8D71E09ED0369491414 +:10E99000F6FBF166E6671C30BB517E3B5F53F0FE31 +:10E9A000B9D68E7CCDE51EF617A1DFFD4D8289809C +:10E9B0009DB39BC9472A1E03981C85DAEF57CD6E7D +:10E9C000E45734F8717C1D8EE63FA9F51B613CB815 +:10E9D0008FE810C70BF32F78FCA7A779A5F171BFBB +:10E9E000EBBCBACF3349AB81B0F8FF0A63C8B9D4E6 +:10E9F0006DFC5CA03B4E16EC67375DA61FC45F0242 +:10EA000074DEAFEE7C0AE3BFE79F393E0DE477D9B1 +:10EA10001FF5C444F9DCBED34A02ECDE8501D6D929 +:10EA20008ADDFA88E72884D4B2EF1C7F6745FB5261 +:10EA3000F1BCD15F4CDFAF78F1A3E110B76A5FC3DF +:10EA4000EC8CEF192E1FBEB6E170BE5E21B3736170 +:10EA50002DBCEBB8BC9C7B29BE14ECA4D4C8BE5F13 +:10EA6000AD689AA51843F6E923CD0A8E4BFBE1BDAC +:10EA700065DF0E09E3E5E1F8AD66F07630FB57D1CE +:10EA8000ACF8E13BD88AC62DB8BFF5347E6A00BF2A +:10EA90006ED2EF9E65DFD736EBC5F861A33E60C44A +:10EAA00038A7FEB87138D35B49884755A15E563701 +:10EAB000F13899267EB4EC777B5EF451D22CFBFDC5 +:10EAC0006F6C606FCEB66EB7617CAE91C5DF648B44 +:10EAD0001C393ED7535CAEE93E1E979B7A9A0C0FC9 +:10EAE0008FCB9D85FF503D9C6FE6FAAAC6351B7BF8 +:10EAF000C5747EBEECD90B4FC279D2B9E73F79120B +:10EB0000F0AFFCE6B327EF867389BD663BAC7F9E12 +:10EB100067DEC6F8BBFADEDD5CCEDB77FCE6E92714 +:10EB2000A81EB6BF67C47B5BED7B4E67C2F78CED5A +:10EB3000BBBE4C85F8E6CA3D05B89F59F9C2A4B4DE +:10EB4000CBDD3F01F9F4C7707EA2E5C781DD7A0213 +:10EB5000DF739E3F6644FFA33BCEDA54C5E2D70E77 +:10EB60001E5FDD19F9BC4A8D0756EFBEE5E6EB6185 +:10EB70001DDCAD381DF89CC7077B8AABBE45F93A52 +:10EB80002206FEEDE4F1F3A6A911E3AAE7E13F9422 +:10EB90004F9BCC625CF5C2EEC5FFF604B4EDEE15FA +:10EBA00035AE1A88816EEA795899D9B5CD0CFAF14B +:10EBB000FC6F318E0D7CA33E39697FF64226C4235B +:10EBC000CE289D77E23DE53D46BC6754B1E75DD474 +:10EBD00097F6178EE23913E1E751EDA4FB879D1BF1 +:10EBE000F0BD8E679B95C56339FD215EEBB0E17387 +:10EBF0001E976572ACC66BA3C569DF37B3FB50EADD +:10EC0000F95CD5B60F0C4413FF96C602BF8E0BE716 +:10EC10008AEABCB5F0EC40876B43CF1FA2C5C3B9ED +:10EC20005D0DE3173B7768DFC2CF23BACF1908E940 +:10EC30003B12CEC7D9B9B9C72FBD1B89BFEAF9C3EB +:10EC4000DB5AFDF4C776EED033DEDF8D2EAF9AD9D6 +:10EC5000FE56A5CFB9AF23DBE94EAEEF749DE93088 +:10EC6000E3B9315B67E6F175A69AD28D7DF7C6F000 +:10EC70003DC7F781E79ED1FB61BFBCAEE900DA5B1F +:10EC8000AD9E571316FFD28E27C531FFA0BA79DF8C +:10EC900070B047E7F6BF84F257BDF3B8C147E11C37 +:10ECA0006AFCBDA16D6850DEC18EFB43ECF8B9E78C +:10ECB000F60D67E72291F3B4D8387C4F8B08DFB3A9 +:10ECC000F35301FE325F93C16EE9799CB3B26B16C8 +:10ECD000CCF76CAB42E03EFBD9267D913FC2B89F9A +:10ECE000C13A362648A77556F61D9F3EC9807EE676 +:10ECF0004AEBD863F0FDF84AABC101FBEDDAD5EC85 +:10ED00005E65EDFF72A6035F6A136FC373A37A0D8E +:10ED10001DEDC9F65CD887DBF34B46835869ED419E +:10ED2000A24B27E0BDD25A94E6B0405E2FE6A71072 +:10ED3000D989DF19EA6D8545300FBD5D6737475CBE +:10ED40005F193CC5C2F2662876F1BBBFEF9007831E +:10ED5000403E8E6F9D07A3539307A3FCC6FFD7F2D7 +:10ED600060F8609C9F401E8C00C677D43C18C93F59 +:10ED7000721E0C882F8D0EC983D1A9C983C1F9F8E1 +:10ED8000CF3C18FFCC8301A59A07E39D0D65059044 +:10ED9000A742CD83716683A700F252A87930BEDA0C +:10EDA000B08AD5791E0CCBFDAB0B42F36064DEBF9D +:10EDB00001DBD53C18CEFB1F2908CD839177FFE6F8 +:10EDC00082D03C1833EFDF5E109A07A3ECFEE70A0F +:10EDD000843C186BFF500079305E8F77B7C6A5442E +:10EDE000CF83D11CE788290F0685F31EC2899207BD +:10EDF000430B275A1E0C0AE744DC98E87930C2F02E +:10EE000089920783C2F904E144C98311864F943C77 +:10EE10001814CEE738AF287930B470A2E5C1A070DD +:10EE2000FE0BE144C983A185132D0F068563884F2E +:10EE3000899E07230C9F287930289C048413250F72 +:10EE400046183E51F2605038E908274A1E0C2D9CA6 +:10EE5000687930289C2C8413250F86164EB43C18F4 +:10EE600014CE55F163A2E7C108C3274A1E0C0A67F6 +:10EE700014E213250F46183E51F260503813104E1D +:10EE8000943C185A38D1F26050380538AF287930A0 +:10EE9000B470A2E5C1A070A6213E51F26084E113D6 +:10EEA000250F0685330BF1899207230C9F287930B3 +:10EEB000281C37E213250F86164EB43C1814CE5288 +:10EEC0008413250F86164EB43C1814CE7284132575 +:10EED0000F46183E51F260503877239C287930C293 +:10EEE000F0F9AE7930CC8141D240CC8381F938BB86 +:10EEF000F360247FEB3C18BF027CFF9907E39F7906 +:10EF0000307E8C3C18B75ADD7F8FC77DE377CB838B +:10EF100071265E9337A2873C18B75A4BCE823C7F4E +:10EF2000DB3C1817E2BF5D1E0C3ACE3F2E374EB4C5 +:10EF30003C183ACBB7CB8341C7912D632E339F2822 +:10EF40007930122C62FE901F2B0FC6B1F8249C4F13 +:10EF5000B43C183FB97C13749B05FBB4E9288AE4E0 +:10EF600027937F62B485C70D7FA8FC1330E99C9F6F +:10EF700052FE09358F419302EBE1FB9CEFEF70B934 +:10EF8000F880E7A13816350F857F2AC677978A79EA +:10EF900028A6703ECE768BF23085B0739429F9594D +:10EFA000FE5AD8AF976BF2500C11CFE98BDD47F3C7 +:10EFB000293832D529CEE328978769A59F1E04F604 +:10EFC000DC3C36721E8A199C1FD3357499C2F936FF +:10EFD0009D97B7C3A739549E8BCB8FCA40D7698EF4 +:10EFE0003619E3F437A9FC7308FC9BC9E16AF19D6B +:10EFF000C1F9376332E39F16EFB7807F14EFB7CACA +:10F000004721FFB4786BF1D4F29F84F23B247F4810 +:10F010002E11F34F4C3289F9270AEC62FE891BD37B +:10F02000C5FC13931D62FE899B8688F927A63AC505 +:10F03000FC13378F15F34F4C77ADD6E4BFB84F9321 +:10F04000FFE2214DFE8B4D9AFC175B34F92F766859 +:10F05000F25FECD2E4BF784993FF629F505F58F7AC +:10F060009AD07F71FD51A1BEA4E13DA1FF52FF7175 +:10F07000A17D59E3C7427B55D3A742DDD3FCA5D080 +:10F08000BFA7FC036FF1EFA1DFE1DF431FE3DF4325 +:10F09000BFDF43FE8B772C4BD785E6BF78DFE25985 +:10F0A0000779098E5B1C3CAF40E4FC16DDED51F2A4 +:10F0B0005F04DFFFF6F92F52927FF87C043A2BFBB6 +:10F0C0001EB0B7254F674DF9EEF9086E2D11BFEB55 +:10F0D0009E552A7ED7ADB3B2EFB567BBC5EFBB6F08 +:10F0E0002F17BFEF1E11E796000F6DFE8BDE1697F0 +:10F0F000CE0AF692E72908C077BAD9106F2BC2F270 +:10F1000020E4BFC886785B29968721FF052DFF0C78 +:10F11000F92F687904F25FD0F20DC87F910DF933B1 +:10F120007C3C7F461DCF9F51CFF36734F0FC197EA6 +:10F130009E3FA391E7CF68E2F9339A79FE8C00C233 +:10F1400039E13D8CE5496F2B96A7BCC7B03CE36D18 +:10F15000C3F2ACF70C96E7BC9D58B67B2F62196BD7 +:10F16000FE0C552E3F04BFE10A189FC9B32AA757CA +:10F170003FF0C8BAD0FC19231ED884721A2D6F46EE +:10F180000E7CD397123D6F46777B94BC19C1F7A3D1 +:10F19000E7CD481BFDE3E5CD986BF961F266CCAD98 +:10F1A00011F33ACC5B75F9BC1923E24A6E41F9E3DD +:10F1B000F238D7125BDE0C9F55E2DFE553BA80DFF1 +:10F1C00045E982EB750F79070E5A9F1E02FB89AE47 +:10F1D00021575D36DF83562EA2D39BE57798F32324 +:10F1E000E7CBE889AE6AFFF72B581E87B9966F996F +:10F1F0002FA3877C0B07B3BF403B196BBE8C9ED6F9 +:10F20000879EE839E347CE97D1935DEDC99EBE391D +:10F2100085D1B9770F7456BF97AE34B51EC297ED3E +:10F220002E546D997F0F9F3BD38EF1998E9DFC5E7E +:10F230009C8B38ECA9EC7B7DF0373B9E4F184EF051 +:10F240003B7E3B7151FEC4F3E7D2CE7DFBE05EC056 +:10F250005A1B71252681B3471CFA81B00FBBC60427 +:10F26000F19AAADD9FBEF1470AD7DCA2C7FB721D47 +:10F27000148756F4FB5C89C0B778F24BDCA7C3193E +:10F28000DDA55EA1DF756B7E0F0774490D9E3F15EE +:10F29000E82DB86FEADACCEEB3EAC9D58F4F188DF6 +:10F2A000F7C689DF81FC433F7519C7B38B10670030 +:10F2B000FAEFB4E2FDD525AF2D34C0A070DE1A1AE6 +:10F2C00037E85524C6811ACCB6E1706F2F5DBDBFFB +:10F2D000E773B5821FBE88C34D2911E3449F2C28D4 +:10F2E0003A0CFEF3227719DEAB482B15E346847FF8 +:10F2F000470FDB32F03365C2EF75FAD97DCFB0EF3F +:10F30000EA9BB7209E4BFD9AFB4B8D625DA5DB39D6 +:10F310002BBF9762219698E8D676C5E31392BF3D3E +:10F32000DD8CE922DDCC0E916EF14344BA68E966CA +:10F33000758A74D1D22D61AC185F53E9A6DEA7FCA3 +:10F34000A1E89664E3F73C82F42A31A5A2C9473CC0 +:10F3500033E400CAB7561FFA5802F01B7E48BF6458 +:10F36000FF6A7CCB6995C16EA533D0445AC4DE8B4D +:10F37000077D80FCBDC489FAA0FE3E8A78F2219701 +:10F38000FB8FC8255AAE987EF0F802DABA19E46D00 +:10F3900004FB3D1A18AF4A22B89F5388D30EFBA82E +:10F3A00026AFC9B94881734DE25C940DE799762C7C +:10F3B0001FE4DF3B770C25B8EF6F0A7C9E0AF70647 +:10F3C0001E1CD9390DE20F9EC5A404D6AF59096C95 +:10F3D0007D5DC64B5B028BCF6C28D111D768F87D61 +:10F3E0004A7ABF44C76BB7BB5EBB01FCD116763F00 +:10F3F00080D83BDFB81DDB47E1F7E119BAFA6B00B3 +:10F400001FDA1FBF2BEE68F9C8B630C40EB7373FFE +:10F410007225DC6BDDA48BFC3D73818DFFFE1D7EB0 +:10F420003F654430DF42816D0CE6657870001DA7B2 +:10F430007A7A17F25195CBEB38FD0F964D41FC5E71 +:10F4400068911C10AF2BD4DF71D3308ADFB8B76559 +:10F450007EAF97DD5F1FCDFBD79AA9FEA2FDAAFF65 +:10F460001BFC9E95974ECA980F71744D19DE13FCC4 +:10F47000A3ADF030F02BC7D5340AE429BF2511CF56 +:10F48000713D1F12277E9AD52ADE07CCE1F7B673AD +:10F49000DA881F84E2DA6362FBB836B17E9D66FFCC +:10F4A00039DFC6F5D4465241EE367EAD9760FDE8B1 +:10F4B000E824CE3514DF8E45BD71FC8ECF09FA8964 +:10F4C0001D5FEB8B22DD8F596E63FCDB642068BF10 +:10F4D000379559F0DEF9FEB28AFEE05F7C7197BB8A +:10F4E0007FA43865889F96C0BEBB772590B12087E2 +:10F4F0006B2546EFFA8C9208EB962A77AA1CAAF2A3 +:10F50000975116E78E740FF5339B847296573644E5 +:10F510003280FCEC9530FCD5BE86E2759975DB47F0 +:10F52000D6F4017C3CCD9FE17D32538BE48A744F4D +:10F53000E7619B8DDD6F5CE35B0DF7467E419508CF +:10F54000EC5486A13E2B127C1FD9887EE95D3607DC +:10F550007BCFC4F320C9F519709FA2BD79D2E475A1 +:10F5600014CF27A83EC07AB5497122DEBE2A42F0E8 +:10F570009E2C8FD7F59D46B66C08F17F37DB721B4A +:10F580006D145EA38D7D6FD9CBED94006FE77FFD89 +:10F59000C306F03B2E1A917FBDB9BFA9BE7780D3B9 +:10F5A000675C826B2BBC4FE0979F51E3E374DB9C5D +:10F5B0008B46415C9ED23BC40E06F9E663F951DCF2 +:10F5C00004CF3F922C3A9443E27239ECC27D761F0D +:10F5D000EA8DAA07242011C853A0DA37A9450A5892 +:10F5E000A9DC8F365902708F2EA99CCE3B19F29A56 +:10F5F0009818BC56F99C18D7A2F29803CE3DC1AB1F +:10F60000F3104805F8AADD53EDE5DA44668FD63EDF +:10F6100024635ED4CD729B19E2A9592E471EA4889B +:10F620004C921D78AFA65F3971520C49FCC05F2720 +:10F6300076FB0154C9AFF9463F2FD2775B176DCCEB +:10F64000DF1E97E0FE33D06BF8E1CEFDE02E38CD23 +:10F65000A417BBFFC5ED04F76B0AF97A37EE3F74C8 +:10F66000EC7BD1C00D24F43B2AAD9DD86466EBFC45 +:10F67000B8EBD9BA37EEBC05D7BD6E3B515688EB17 +:10F68000D4C8965107E09EC5C80F997E126E1FEC34 +:10F69000F40FD029E7B04F0FF4F9B67641CB6F12D3 +:10F6A0003075D787EAE01C86EA5BC8FB673576646D +:10F6B000C5F441B5185EE672D4FF1EA7DE1D4247B1 +:10F6C000EDFBDD714AC9D4FDDC3110ECC8113DDC25 +:10F6D0000BE9C8A5F3A3F3DFC8F525F173FF649820 +:10F6E000D7C6961BCD20DF6B0379F662FA4EA2A92E +:10F6F000049997485C18CF19493D32C88F518B4205 +:10F7000041FD41A58424A4C03DB42221DE432C49FF +:10F710003CFF4B00F9D22DA7548E43EFE5AAF2A986 +:10F720009547557E6BE1A005CE0721624E4BBDD4B7 +:10F7300084878146B2D90EEBBBEA5FD6727FAED624 +:10F740009CE9C7EF977C19E81FADE4FE51ADA5D049 +:10F7500084E6605F32AEEB2B217E42E9B03285D980 +:10F7600079753E5AB9F45CD4137FC83EC12377E261 +:10F770007D44CF45033E5FA7B807C0FC55FA5CC384 +:10F78000E9A3A58794C0F79D9C2E3DE39B63877BEF +:10F79000C1892617598FF8E6E13DEEA6C04813ACA3 +:10F7A000BFF76AF08D01CF6B13C684E3295BA2E03B +:10F7B00099CCF0BC8EB8FFD846E53767455D6D3C07 +:10F7C000EA15792B3D275CAFB47AA4EA8D1AE7BD20 +:10F7D000B6B2FE005EBBED416F3CF18C2E4EA5042F +:10F7E000EF5739F7C4A31DD1EAD3E77CFE9E7846D4 +:10F7F000BF058A7B06CCCFA3EBCC043919EE20BD24 +:10F800008A2992C39BF5A8E7A435B67BF8AA7FA501 +:10F81000FA55DA7EAA5FA5DA63F51EFCDA04F77CF6 +:10F820009003A999CA2DC5A7D6CEF64B9B6DEE4580 +:10F8300080573CC53D0EF68D430259ECFB5F512FBE +:10F84000A2E941BC46CE9B0232AE0B3EBA2E644BBF +:10F85000E178A8E30F4A48647CA45A0EEB7DDF1CD4 +:10F86000C206AB269837A7EF70E28675ABEF4876F5 +:10F870009F714D02B3BFB5096CDD52CBCDB692BBC3 +:10F8800051BF65E2338EFCEE7803AA70DF7C6D8297 +:10F89000EB2EA087A9C885F3E863274EF04BFBC881 +:10F8A0004D127C379A54E990D83D7312FC7E8BC27E +:10F8B000EB53ECC8057DED03FB6BE8DF1239CFD8C5 +:10F8C000A309EAFD5EE67F3A49771EAF471398FF2A +:10F8D0007908529FF42A56F382A9E7394E09E8D4F1 +:10F8E0006EBD0D916EBF20313F3D91D14BBB4F009E +:10F8F000C287FEFEBD7B0D44362791E0EF59D599B6 +:10F90000D0BF8F27CE26B057BB1206F0734C671DB1 +:10F91000D47F25779A128706E55D95E30727CC709B +:10F92000422A52DBF55DC3614F45E57A27D0BF7DA2 +:10F9300042D760CC41493A3399FCB8F442BE209595 +:10F940000FCD8AC00733ECC343EDA4D53004FCD1FE +:10F950007629CE09F72CDA974A0C5FC9C4F329C976 +:10F96000C23CD3E3997FDDC1EDD53B09592827AAD5 +:10F970003DA6F3AB83523B0F8F11EF7490CE3DF158 +:10F98000FEAD706EA5C93FA9CD4F3969A105EF7FC6 +:10F990006CDC63C6FD6B57093BC7EF6A31A27D8EF5 +:10F9A000A6B7696DE688711CB5A4F47B0BE897A631 +:10F9B000D424823D4C9B7BD2067CD7D2A543F25DFA +:10F9C0007308F645AF2B11BFBB55CBF4F49B121750 +:10F9D000D1FEE91993B1549F3758E488F7CD4F739E +:10F9E000BD52E5F14A3A22DF0F9D06793CEF7EF3E6 +:10F9F0001D1709DEDF6F8863746C886374EC728F87 +:10FA00004F781AE4CD9781FAB0583D07E5FB7F3572 +:10FA1000CF943ADE46AF2951A62AD0B0608A19D6D3 +:10FA20008914E29A3C1B9475A342E03BA2C7BC3BFD +:10FA300012F3318E6D12EFF9DAD9BDE1CF3716E04E +:10FA400077DEA9648D7930A5475989CE09F183F312 +:10FA50000BDEB7E9A83C2DE8D39A03F2FBBAE22605 +:10FA6000F63118EAC2FDC99252833F40F996DC4054 +:10FA70000D05A5CB7F03D85B39A8008000000000EE +:10FA80001F8B080000000000000BB57D0B7854D5DB +:10FA9000B5F03E73CE3C92992433794E1EC009E1F5 +:10FAA0009D108724BC1F4E9E448830BC0485EA808C +:10FAB00028CF2488D6DFB6DECBC444F4A2B745E90C +:10FAC000AFF4D6DB7FB0A2A8200182069AA413402F +:10FAD000E4113408A8A8AD5129620BC908EAC5D6BB +:10FAE0007BFDD75A7B9FCCCC4922D8DE4E3EBFED62 +:10FAF0003E8FBDD75EEFB5F6DA872EC977134B641C +:10FB0000CCB7D8C0B64A8C7D87BF1B43ADD96E60D9 +:10FB10002C89B196383BB54EE70CC7D284F07E8570 +:10FB200063693E63D5D6D85C16876D7F3F8B85F1C0 +:10FB30008A58EAD202685BACAE5A95B12546AFDD71 +:10FB40000ECF774EBA3CA48EE12FD8DF3392B12E80 +:10FB5000236B94E2B01F606C0C4350F8CFED56ED70 +:10FB6000D097F0FFE1FD448B2D20C3B8CCA35CEC13 +:10FB7000B0F047BE1B281E4D66CC285E939ADEF877 +:10FB800046CA652C7672116370DFCA5C8FB22CB8DE +:10FB9000318CA99E18C6A2D833F6F3D98C19F07D02 +:10FBA000584757F3BBFD7C00C71FFEE54A0C83FB9B +:10FBB0001F29C118570E63171E3C15E3B6C1F50780 +:10FBC000E5723FF46F4740C687F0926F870BA31929 +:10FBD0007BC4EE1981EBBA63DD7F8FF1DA42F7D98E +:10FBE00003703195B1157E19E7E6F0C27FABB659C7 +:10FBF00019B384FA95F509117DC018E1B5D2CCD6B8 +:10FC0000D4DB7AD26305D203E65DB17D8B295DC575 +:10FC1000F9BD93ECD0BFA0C0AB80EF0B0D317E5F80 +:10FC200066089E25DB4799D2E1D6474D661680755A +:10FC300030A5DDC86C84B50A09F0E61578D3C37920 +:10FC4000B8C54AE3DDF57F65BF1996BA18E67A2094 +:10FC50001E9E6F5A51C1727BAEE3AE3FA86529402C +:10FC6000BCBBFE4D623E953FFF601E3CFFC0235F64 +:10FC700020DDF4EB5CEC337ED211B16E376300CF44 +:10FC80003241EF3B1F8DBCBFACE9311A6729F39AB3 +:10FC9000909E776DD4DFBFE933E4BB654C095D0707 +:10FCA0003C5C3E9265453CDC618F493C0F20038FF4 +:10FCB0008DFD0EDEDF7D64609C37A7277EB5F6E202 +:10FCC0003AE06F33637F5E67A1F6C23A46ED08BB48 +:10FCD0004AF459DD74F27EE4AFAAC65D261CA7C5BE +:10FCE000FFA78409F04861D3373232572173DF7B95 +:10FCF0000EF0F92326B3EF007FBB19E79FF546CF3F +:10FD00003D48AF1BAF96D37DFDFA1769FC7F249E5B +:10FD1000F86711AE3B17AF2B5FF6B6AE9FE2BA8025 +:10FD20009FD95858977CFDEBD2D6A3AD4FBB5F2926 +:10FD300003DFF5F2BEC6EF23843E58FADCACF5696A +:10FD4000808ADAE6CFFA77103FB1D328BF1A3F2D69 +:10FD50001374D2F38D46C76EFE68FA775A9F463FFA +:10FD6000E07FA7C1896DC06918D7934FF47CA1E7E4 +:10FD7000834E63477F945F3D1F744A6C416FEBFA7B +:10FD800037FB405AD752D55D6687FB7731CF7A3B38 +:10FD9000AD67235DBFA06C3CFC3394ABE7385F7765 +:10FDA000EB3933973776DCE847BDB936464D71D825 +:10FDB00004FD80CE9DBBCC3E7C4E9BE7FC3AB77BDE +:10FDC0009011F15E4EED9FD779DC830687EEDFFD63 +:10FDD000AB2BB12ABCDF358C95A3DC77C644C2BB04 +:10FDE000CF2E133CFB900EC87F4AFBFF7C803AE984 +:10FDF000B9F631A847CF7FFB5FB11E78BEEB5B73CE +:10FE0000796FEB3C2DE807EAE5B413F8EC7621674F +:10FE1000B73755125D963C33CB84FCCC1EE0F8B46A +:10FE2000C01FEAD7B6A8D867711D8B1B24D2237ACE +:10FE30007ADCE59AFA39EADB3BFD85F47E0FFAB00D +:10FE4000C789BE77213D8685E831D6A1727854F8FE +:10FE500003BEB943F0CD79658DC9007AE4FC3380E7 +:10FE60006F007995C2DCBDE9C1FE0ECE877DAD473E +:10FE7000BF8EBEE05FF65CCDFA3486EB1F654AEBC1 +:10FE800045EF68EBBF8BB96249EF88F5B28E1B492D +:10FE90005EAB2D7C5E6D9D2B9AEE9C817C51B519DD +:10FEA000E895D973DDA87717F7026F997CD168813F +:10FEB000F7BA1E905CA86FFBA283A627EE12F85A31 +:10FEC000B96DF10C349A8B613E3913F5D1176FC6B9 +:10FED00024A25C415FFA1E7A35C91F9B711D8CE319 +:10FEE0007B09E07B8374FDF45BB6B9D03D28ECB9A7 +:10FEF00015FE9BDC83C2F5998EAE6CDBACD0F3644F +:10FF0000B7DD26B4C7F10EA1BF845EEE5BBE60E133 +:10FF100000E7DA1D0EB26F6C8D83F46375D3165350 +:10FF2000B8DDD5E44B93B7B10E3BF15955E313F46B +:10FF30001CE85FD501FD4A4BC7CF6F55C3F0394E62 +:10FF4000D051AE30A1FEEE4B7F82BEF9B2236C9D44 +:10FF5000231CC2AE08FD7B2DFDA0C1AD1F57D307EA +:10FF60001ADC1ADF6BEBD1F37D5FF0E9E9C2989FF1 +:10FF7000FB0B3AFAAC427A84F5115E05F0DBD66CE5 +:10FF8000F53F04F0B6491C7E5F7314C1DFE92C769F +:10FF90009F033FAF2A7521B527F0C554F4EB3CD33E +:10FFA000109F9A3FC70A1222FC247DABF93779C211 +:10FFB0009FDA1BE5CE0713093F4F02F2C3949A8ED6 +:10FFC000391620D9AD8EEDE50A8C3FE5898E395181 +:10FFD000D05FE8D8C1FB5B3B4E595C8CD5B057CAAB +:10FFE0004BA07F3BA013C7BB565B60F62C44F95D6A +:10FFF0000D7E9205ECD1EAD3430EA1DCAD6EAF28A5 +:020000022000DC +:1000000097C0EEAC068323813DAA74C706ACB9D471 +:100010006713E0B9E7EDDE65C42F57EBC86EAD3E60 +:10002000AD70B9399248EB5700F62878AF2E1AFC1C +:1000300055C0575DBCC5559B49D77D51F1D877ABAD +:100040006AD8758D1EF81EC25167606E07B4AD4741 +:1000500087C4757C8FDD6E5DC72A14E08383EB2C2B +:10006000D4EAEF179AEC83D0EE151A98B7377DF9DA +:10007000A483FB8DC0E4E948E7AA23269277FCA17C +:100080001F5829F4511510280EE0A93CCD02D1B11A +:10009000F85CD9E70AB60D12FB24C25F61A1BEDC91 +:1000A00037DCD7DB56E17883C3F984E3A948912A8A +:1000B00094B0794B6C51117D39C5300CD7C3E468CD +:1000C000D756C0AF9C6E58B31BD62F0F8016F0A129 +:1000D000D85DF2626837164F9197405B6BE476B556 +:1000E000D6C09687E3E905811FADFDC0E1D98A74CA +:1000F000BFF456FB182BE9AB0C3BC9B9586FADE404 +:100100000A50DCD4CA5C5BE15A9DEC619C8FEB1910 +:10011000F2F11B621C97D9B047057E6D747C40FCE0 +:10012000EB8A33DC9B09FDC0131FF17EBAE14A263E +:10013000F0F781273ACA15900757B6E1CA40E81F81 +:100140007AE2637E7F220C0906EAF0139F94FB6C2F +:10015000382ED7676CBB3B1BE7510C12C9A972C084 +:10016000E4AF85FFAD8BE5FC54073C82FCF786B01D +:10017000B3EB6B8A5EB602FF2B456E750D8CE3C741 +:100180008069F4DFDF6A7894AD068A53B0457CBF9E +:1001900029D6ADD18135B8B367A15EA87767CF8E78 +:1001A00041BC7A4F225EF3DBDAA7A03E6E78FBFDFE +:1001B00031E8AF22BD709CFC3688DD603D975EEB78 +:1001C000B7450E8B473F7014BEE3003996DCDC9FC9 +:1001D00094543B5B047257EB66AA09D695A28BEB4D +:1001E0001A18D72FCFDB3D7FC4F7584680EC4DA1BE +:1001F000C3FB31CEAF8F57597B7CAF7A59AFB74C29 +:10020000B90FC8E8E7C4A737BEB704F5FBEFCDAE1A +:10021000C12AC2E5660F003C3B0D4C61F1C426C308 +:1002200094028C3FA35D1B50EE5DCCE90339C330D3 +:100230008D80845FE298B0B855AC07DE2F61D08E18 +:1002400045F86EA0F5C9C857A3984746FD3586F90D +:10025000ADD87635BFE644BC3D19C5EE40BFCFB240 +:100260008DB9FD61FA63403CF7F726251809EE6861 +:1002700063FD6CE4D7E82F981DFDAAAEFF34293842 +:100280003E08C874BCEE3A6C6008E70B46BF3D0EF2 +:10029000FAC1E18AFA2C0B8DD725E8AD8DFBA44974 +:1002A0001DEE407D93C0FB2F1472FB1CFCDCE47F31 +:1002B0003613F16359E30F932F673CF75BBD494554 +:1002C000F1F1D0D63747339C7F6C4BB401E9F0F2A3 +:1002D000F6BC28E4879D881B587FBCD97E0F8E17FB +:1002E0007F05E0CDA4EB6EC2ABA28E8A03BC4E9814 +:1002F00066533700DE5F88AA9F86FC1FDC6160CFF3 +:10030000C2143B4DAE59D8DF7959B5A3BE7D21B398 +:100310003E9AD6B3C340EBD9191D1CB116E0DE30AE +:100320004C2947F8142B53500F2B8622F51EB83E4C +:10033000349EDB574D2F2F88E7F2F3A404F3E7E157 +:100340007385243FA5B28DE4AE2BC8FC669827695F +:100350006EBB8CF4889E05AC847CAF046406FD49BA +:100360001E46498D4936A35F257DEBB62D06BA4F53 +:1003700011FA76CA87AB2B78DCE33A3D11C63B68AD +:1003800033325CD764D621A33F38F92A7305907FB6 +:10039000AEF278C60E7FE83F3DAFF3074BC578EE6F +:1003A000A0BD042F17B2483FAE7473D9E712CDA396 +:1003B0002A68A78B2DBAFBE8E7C5621B193795C5DC +:1003C0000BFFA63FEBFF1DE937E05E98EF3E3B9F3A +:1003D000AF54CEF915AEAFABDCE4423CECB2B9DFC2 +:1003E0009D887AB1DDC8B6B2BEE5E979883FFDE007 +:1003F000730CBB6A65FE7CE2471BAE67C4E68DBE2C +:100400002858F788417C7CE43BD42343FF333101F7 +:10041000F5F855A15FB456E333E4277B1CE727FBCF +:100420000D2139BC333E939ED3E40AF90CC7D96F32 +:10043000F42FF4F46227813FEF44FEDC6563144738 +:100440003D966A598072A5CDF3BCE0637DBBBE6664 +:100450006DAB11D7FD15D80380BB24EDAA29DC9E16 +:10046000EF49E27C552A7F4BFE766793C4D0CF4F8D +:100470006EE2FA3B9C3F527BE78F5F225EAFC51F67 +:100480005ABCB0FB87F2C791BF8F3F365C933FBE2B +:100490008D453CDCD75C9CC2BEC7BF6914FCD0D77D +:1004A000FDF156AEE7F4D75F1178DD67DA383D1716 +:1004B000F5C0CD0617CA39503F7D36AC635F347F37 +:1004C0008F296BB2B0BF4BE17A65579399F4CA2E6E +:1004D0009BD74B76DC6961E83F30C5DBF133D487CD +:1004E0006916754318FF2E8DE7FC566F0C8CFF0CB8 +:1004F000FDE2A39CCEE36ECE934DF05CEA522EE774 +:1005000005174C5B300E2B4D28DC817C7402751670 +:10051000B4D5E7E029407CD53913E9BBD75A4E96CC +:10052000617E11FC1E37F2D9D8FD27CB8A72F07993 +:10053000AE4FF78A56EB8FC735C5B3EE78D723ECAD +:10054000C678C6F59207F92437D4676E23C56B1AAF +:100550003FD447033F805CCC67AA3116869C73CE9C +:10056000F330984336A73C92CEF303D3283E9C7BCE +:10057000BAFD55D0CC6C9E47775FF0C17C1D1F80C3 +:100580009D3D1E8FFED2F180C980F399D664737FA2 +:10059000684D16F293264FF4033CD5FF61D8B31B88 +:1005A000C2EC7B6C0297A3C75D0ADDF77598FC83EC +:1005B000E1D2BF33FE5EBDB03F9FA33C63FC70DF62 +:1005C0002B0BD18EE62F771F44FC4F4F92E9FA2F69 +:1005D00058C09285F47129E497D51BD5E2CFA4D0F9 +:1005E000734CF10CB3C1FDFD49D1F9387F6982F735 +:1005F00022D28929C123F8DED80979F9285FB651BA +:100600007509688F34B801AEF2ADB6101C1A5C677C +:10061000055F94262CBE88EBC7F750BF347E7CDE86 +:1006200082EF6B74AF6FFE82D33B8CFE48EF10FD00 +:10063000A53BB0AFE1E12BA157B4FE3F4A7F2D7F30 +:10064000704DFA637E20F6EFA2BF352129447FF07A +:10065000B3E2B1AFF7B3EA4DE077E7F4BC5EE82868 +:10066000A4E75D265821FA552D1077A23C7A1DB4D7 +:100670002FB0C7CEE7EAFAC3F9FEE022B2C109F112 +:1006800084F76A537008FA21A30212F985A340F097 +:100690001791FF95417ACF25F0C4CE4BD2F961DC9A +:1006A00045FF2E1DFDC34002FA51A3CC1501E4F70E +:1006B000DDD629E9E8D7E5592765215FBD3AECBECB +:1006C000E368825E4D5BBEE73935E4FF68FAEDA072 +:1006D00018569BBF2081EBA11B41DDA21F882E6312 +:1006E000381C9A3E47F2201C5260BEE13B2BE9E5E4 +:1006F000A60EA0C78D0807E0A155620DA8CF0B0D6F +:10070000EEC462F4D392020AF7F7BEE98FF9C18A08 +:10071000A637DE43782B703F04E35097F162773EB3 +:1007200062604F3F58F357B4B840F367B4F813FD15 +:100730001EBC3F405CB79B0140B447018BBF06E63F +:100740007FF2B23ADC2DE4568175548875CC64EDA5 +:100750000417FBF6BBEF26017D66087C541C81B8AC +:100760003117EF337633E0E16685C79337BB207EE0 +:100770000CE3A399E322FBF89B921C1AE75ACFEBF8 +:10078000EDC044DDFECC3FDA1E017BF409B8CEC7D4 +:10079000D6F1B874C240D9A7A0E11C9769407EACDD +:1007A00016F60DC2E85EEDD24BC22F9E60E8C8750A +:1007B000017E5BF7FF8DECE081FD7F7B07FDBCF1E7 +:1007C0009F2BCC0CEF4FF8BC200EF5041BA7125F3B +:1007D00069E356FFA9C1CAF875E2FF2AB1F6C30062 +:1007E0008F7B28C267A1F677179FDC84E37D794E63 +:1007F000E1BC2DE62F337907611EBBCCC4F3018722 +:1008000025EEFF68F70F1B016EB8BE2941CB0BB474 +:1008100093DDC79F398CCE37633E202F44D79B2F63 +:10082000947FAEE4F6A40FFEFE37F2015A1E60ABD1 +:10083000C01F3B78D6A4025C531BEE51D0BF9EEA8A +:1008400094993B6CDE9B542B7387E5039E49D0F94A +:1008500023075FDC3403EC49759BEC8A42796DDA3F +:10086000753C17FBEDB2CBDA0B1FE9F13BB5E91E86 +:1008700005F9DF98A8927C5F6BFE0923804F6E40DC +:10088000BA33F2EB3AC74824477AFA1ED8FFEB8412 +:100890008E9CBEF1DD17FDF574F8DDC522DAEFB9E7 +:1008A000163DF47CDB02EBF4C1FA02B04E1FF85D9A +:1008B00007D6D9A97F689D93FA1ABF5637FF36012C +:1008C000FD368D4F4B1338DF8CDFB72981D942F4C9 +:1008D000D2F0F5A1B0577BA3347FC3356F065C3AE5 +:1008E00005768718D4C7DA9D6342F66BFEE932F2CB +:1008F0003734FB355F5E544A6A53D82F4C23A35ECE +:10090000D3DBA9B9EA6223EBCD3E2D88EC97B76D16 +:100910005462A867203A4992C087F0B33538CE3088 +:100920000FC1A9A7A706971E1E6D7D9A7F3D5FD0B8 +:100930006FCEA04C23C2DFC3AE8A75E2409887B861 +:100940005EBBFAB58E9FAF5C28792BB717BEED8BD7 +:100950007FF5F7357D508613E451EB43BFC298987D +:100960004C742BBB6A626EB01B2C238A7D1A6657AF +:1009700058C550E29F7B851DEE8B7FAAAECACC9BEB +:100980001FE22363E31356E4A37DCA462BE6272721 +:10099000DB66D5C6019E4AFE543417FDBCEA0E0341 +:1009A000C3145669D3170731AEAF7E8FB9502F16D7 +:1009B00035B51623DF1D52DA658AB3BF64EC893082 +:1009C0007FB1B1A9D68AFE5463A24C71FC6107E7DE +:1009D0004BEDFE9644AE3F1ACF5D9EE1EEE5FE196B +:1009E00071BFE4E33CE2A3B24741AE310E4D8AA1B0 +:1009F000BC4489649F53817EC84D46F2F3218EF931 +:100A000023EE035E6A34EFC2D47E69E323F7D88114 +:100A100010F5FFFD698D19F30BB324D7B3F05C9982 +:100A20001A6CC57ED9DC4CAA7B18FB3F32F9B3C1E6 +:100A30005B25CA8B9401BB60BF6C51A61FF313FBEF +:100A400025DEF735F37D0266F725CC8079DEAE48EA +:100A500018B581784AEB0FCEDBC0042387C557F762 +:100A6000ED9549CFDC572AF971BFA9D49ECE7C61A0 +:100A70007C55F6A889D635BB29A508F9784EB9CC9E +:100A8000FC61FC1D107EE13C0FC4E161EF1D8EE2B4 +:100A900070051703DC52486EA7093E9FC5B89F3802 +:100AA0007F4142C47BF0C62D688F6E6D8238157A07 +:100AB000D344FC7AAB373D625E0FE37ECD09162C42 +:100AC0008983F1FB250D24FE9B11B48F0EA8A87716 +:100AD000CE24A25E63C3B89C6872572AAFAE237E51 +:100AE00070F27DB2791248938CFA2F529E668E8BEB +:100AF000ECCF72F7A83788907FBD5ED7E47E5EB3F7 +:100B00004CFB72F30A2517EB453FE8FDECB1D17DB4 +:100B1000E8856FD587E37AD30B1F96FF5D7AE135C1 +:100B2000082BC681FCFE3451E8877EAC1FEA875251 +:100B300079FB26E4972EB077E65EF845B3175A3C6A +:100B40005E06F24AF27E91EF67945E4D65BEFC5000 +:100B50003CDEAD2FC09F70F5E2E73C9D984572D416 +:100B6000AD5F34FD11E64F18C7FCE3FE4429F89150 +:100B7000A63C842F83E02B633C1F588685439897BF +:100B8000737E41F9966A88F329DE67BF25B850CF96 +:100B900049F12139D0FB195A5ED72AF2087ABEE80A +:100BA000CEF3CD35521D8CC61765762E1F65736545 +:100BB000CABBEBF9449B4FCF1F015D5EE69AFC2157 +:100BC000E4EC87F24773A2D8571DC4065D0F5F6837 +:100BD000FCA0F187DE8E1CD3E567FAB2236FA21D5D +:100BE00019DDB71D797D9891F4B5DE7E68F6E27760 +:100BF000495C2F6724F27D8E69C3E7D9D0EFB02618 +:100C0000F13A0DCD0E75E79736737E78BD63892274 +:100C1000A13D41BD9019867F916FD5F8AFEA51890A +:100C2000F28D15422F7536F3FC5B7589ECB7C0FF6A +:100C300016373DB189F78D949F2B545A150B8C3B79 +:100C4000D325B930AFE316F9BA196E89E7EB5C9199 +:100C5000FBF42D3AFACE117C349305EBD01FD7EB81 +:100C6000A53957B95FA0D74F73C4BEFB1CDDBEFBCF +:100C7000554DDE07B001FF4C7FC09CF4FDFE80F6B1 +:100C8000BE46478D7E2AEEC5A11C1DFCC6A4C670BB +:100C9000FF19E937F5AA42E3D893045F0A7FE6CB50 +:100CA0008B79BFA0984F3C5FDDF485C93BB26FF8EC +:100CB000AFE5B7C6A29F3E3AE4B76BF34E53184B6D +:100CC00047C74C674F6689EB3FD47E0CD7AD43A333 +:100CD00083A6477BE059E8D9BEE8742D3DABE9B364 +:100CE0007FB69ED5C6D7EC8036AF5EFFF615B769E6 +:100CF000FA74FD1603E54B268BF878B2C8C3CE4FC5 +:100D0000E2F1C1AD493CEEECFACA62407BB9B38571 +:100D1000FB272EB3FD38FA05A17C1FA7E7C331CC12 +:100D200087FBEC4C69B7D0BE67119012F73DD3F842 +:100D3000BEE77625E0213DED52580DC8C9397C0F3C +:100D4000E679F8806F21EAE9873F1962A0FD7725EF +:100D5000D08EFEC9D83C85F68F1C6695F2C19DCD1C +:100D6000663BBED7B5EFFFB41A719CAF980B43B882 +:100D700043CDE6EEFD1BD407A5729B8CF9FBAE209C +:100D8000C8083C3F6941A018E3A0C9ACBD16E57B8B +:100D900002D2B117FAFD2A498BB37BCFEF17377315 +:100DA0003FAE3846263F6E8AAFBD18F7ADA62892F3 +:100DB000AB169FD5E5F75FD1C51FA1FCBEAAF0FA1F +:100DC000435DFEBE91EB99EBCDEB4F40DD067CBC65 +:100DD0005EE373A16F581FF9FD9D26BEEF133C69BA +:100DE00064E807B30B89BDE663AE95E7DFD712ED84 +:100DF0005663719F8EFBEBFB5AD2DC6A6EDFCFE746 +:100E000076048BD03CEEDC3E5BA1FA35911FEDB150 +:100E10007FD2C7FE88BBD17E08D5695FFB21C55F45 +:100E2000AA94F6B95EBC69750B4CD43FDDC8B49F7B +:100E30009BE474E7F96837F2F9CEF3696E84EB79D5 +:100E4000C1A71ADFEF3B77399AF6414D6E15F78F40 +:100E5000830E8BEB59E25BCEEFF5A943FCB84FFB59 +:100E60001B21173BA383C7B213C3F73DF83E47CB03 +:100E7000BA47679F33D27EB984F9486D7FD907722C +:100E800043753DF18CE20F23AB67386FAD9BFD1AC4 +:100E9000DB2993D438C4FBE5446D1F538DA33CC4B8 +:100EA000B757A8CE508FFFDDEB9807EB511AD659F4 +:100EB0003C0AC8FFABEBECD46F5CE7A476FF3A9535 +:100EC000DA878EC73E8076BFDA6DF22861FAE39D3D +:100ED00064EE77E5657F524CC5DF7F6354873EE55E +:100EE000C10E19F5C58D57611D117527CA65C43727 +:100EF000E537B342FD4C69710CF66FBC0AFDB0E7F3 +:100F0000AF2439B83DAA53EA462793B4105FFC2DAD +:100F1000C9DD9104D7EF71783EC176B734FFE02583 +:100F200046FD73BC7FAB7C099ECB0F14525E391F0C +:100F3000F3CA7934EC42C4DFE85613ED976BF9DD60 +:100F40003C4DFEBE8ECC33E78BBCEEABAC83F2CD1A +:100F5000051608B40C0817A79F5B9AE794301F98F2 +:100F6000647261BDC3E82C4F3EE6635B9318C547CE +:100F7000ADADC9196A0E720FCFFBBAB5BC2FFBFE1F +:100F8000BCEF918F627DA4B7AE9A687FFAC8A9586A +:100F90005780F60B2DE4FF69F5C82DD1BCCE8065D6 +:100FA0002CA03CD38DA29ED162F69A93495F050E88 +:100FB0009E80F77E7F99F17DC7F60F695FBBD830C1 +:100FC0003C05EB7E0F4A43E3B07DEAA3D81C6A4F91 +:100FD000C55E44FCB418AC2ACE7B669D5A82756D02 +:100FE00027D6B112AC637B6B9D85DA93EBECD49E74 +:100FF0005AE7A4F675B88EFC731C9E477E71BF65D8 +:10100000A37D92296FD9146CF316C650BBFBB6189A +:1010100013C2DB12CBB66BF360BD5A203AD080C945 +:10102000FED6A7BC8F59FA81DD337B474AA3186BE4 +:101030007BCA3B5D990CE34EEDFF93AFE0FE9BC98D +:10104000CB1EB3005C734FD91ADAA0FF76F2F2C759 +:101050006CA86F8F4783D2C3F5AE38EE1E0474437D +:10106000A590C605978D837E82D65F31BD641263DD +:10107000B71477643360ADECE495D32D80C75BACD7 +:10108000DE1F63DFE44B9A5ED20FFBCC87F5604135 +:10109000C948713FCB9012B1FE65A6C3FB4672589A +:1010A000FD9E5BFA13ED338D714BCC41871F8CB4E1 +:1010B000EFC5EC1F2784CBDB4C47E91B488F89C960 +:1010C000BC0E78F424C91D5E5FA17F6EF439B504AF +:1010D000E934E642591DB633CB1DD4F72C185B8793 +:1010E000F25C62EBEBFD627ABF3C99D78D1429521A +:1010F000445D89FEB97C6026F48F8347A3294F3075 +:10110000FAB4B716EB4F4B9D9979B2A6FAA8EFD86F +:1011100082FB6DA32BCE9424A0FCD824179A89318E +:10112000ACA32E01EE17DAB1A00AD7F54431D6FFF1 +:101130008C562517A2ADD0DDDA80EF17BA625C8538 +:10114000E88F9F564BD0F49C52469D2880E7A60E10 +:10115000925D1618E854E0A68997A05F382C8EF2AD +:10116000BC85CA9A2B27A81FE3AA51711D5B7E5D1F +:1011700045E398C9AEEF9E51FC2FC83F459E38CA43 +:1011800009023E4AC2EBCA60DD0477A15DF6474919 +:10119000C8DFFF5A6287FEEEFE1296CBC37CC3FF08 +:1011A00042F78F44AB5100E86E93BD04C7DB6D92EC +:1011B000EC0F51DF538CCFFB861855CC1F9525467D +:1011C000458C3FB5441A7F0EE1CF891B85D7CA33C2 +:1011D0001C11F7DB6EB3929DA8782B87FCA2B6DBBF +:1011E000D2C95E54BC35A908DB3603F7D32BDEAA7F +:1011F00028A7FB061E07572CFC915BF429EEAD587F +:101200005849FD5629E52738DF959CB83CCCAF4DB1 +:101210001B945AA244F8810349FEF3447EAFD030B8 +:101220007CD32480FFDEA37C9FA2222733E2F9191E +:1012300005524978FDA8675254447F7689A324BC9F +:101240000E756E456A44FF96B99911FD92A3056427 +:10125000BF410F5494801E380AED5260C1025107FD +:10126000A5E59F0A054B15B68BBCACC2E3EB61F05C +:10127000877AB0C41669A77747733B5FCED6D0068E +:1012800049F911BEBF5D9668FC24DC4E94CB15363F +:101290005E97158987BCA346B2977931921FE3FA0E +:1012A00092A34BEBD0F4966744BEAFF961E5023EE2 +:1012B0006D5EE673B7A33FA2C1ADCDAFC15F2E2F68 +:1012C0002AA17CF735D6A18797C17A503FE8E1681B +:1012D0004A16FE1AF81FE4AF897324F04BECCD7E5A +:1012E0006BFE7A05E82B47B8BEB2498958B7D79745 +:1012F000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9F2D +:101300009E9A2087F5333F4E880FEFBFF8E9A688F5 +:10131000FB491FCF7184F7B77E3A07EF4F51D45A7C +:101320001BF0E53126B97CC8076DAA1203F4283EEC +:10133000EDAEC3B6F4432F96ABB2A9E77C75D84E99 +:10134000BCE86F33C3BA6E1A26AB18BF6B7E881E1B +:10135000DEBF26F3BCC3B1ABAA15F75977FB542BFC +:10136000FAF3BB1F54ADE887EC76F37319EE2C0348 +:101370009D8F7167F37AC5BF24F3BA834EF1BED651 +:10138000FA8DDE4E841BEBCCD137A8FA264875E5E2 +:10139000C7D0BFCAE9E95F1D53FC369CEFD8837EF6 +:1013A0005BF87EE2F5FA577F041E43380A99E40998 +:1013B000D723C596284FB8DC96DA1D11FD93C20FCE +:1013C00099EA4C8D78EF263533E239F01B87A15F1F +:1013D000526B62546FEB33F07A5B3D1E57A4F0F80A +:1013E000CE65B3A33B83FB66726FE7915CC5865EF7 +:1013F000CFB7A5A4707FF03F5218C1352B85C3A786 +:10140000AFAFD5F76BF17C0FE293B99CC8E72EAB79 +:10141000E10AB8BCACE0E927A6535D6DBEE1DE2C65 +:10142000E8573CBD753AAFAB35ECC13ADB194F3FDD +:10143000CFEFDF60C837823FB0CDF7C274AC2BAFBF +:101440008AE2F5095551A23EB46E7444DCA3183EFD +:101450007E6A21C69FFB8D0CF3FC8F99C00EE6853A +:10146000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A837 +:101470003F3E8BF2E6A5509EB148453C5EB45BA86A +:101480003EF4BE7DA529C807B35278DE2B7BCF443E +:10149000279D2FFBE7C151FC7D7060FD308E73717D +:1014A0007736F9E5D903189D27D1E801E1335D8F3F +:1014B00082F081CE6330B713F36FB50E138D332BEB +:1014C00085F3E3F5B63DEA89E30C6B7641BB2085F5 +:1014D000C7CDB7E2BC046FB0FF2CDCD0B307FBCFA5 +:1014E0001EC9FB486F59CE0BA27F1BFC510CEDC3EC +:1014F000BC1FCDF1C63282B46FF3EEA26CD706BA30 +:10150000CEF1B8C03FB0B643C5FA0F7F3FACB718B5 +:10151000E8F42E457CDC66F60F26BEB2AD89C179B3 +:10152000AEB7DEB8EFF921E0047B327F3CA79736F7 +:101530003FE0D882747C579C3BD1E001387E8C70B0 +:10154000687075C3A3AB3FEF147E7B278E971BCAD1 +:101550005357FFC940798A6A09F424F4F77CC85CC0 +:101560003E95E8437950DCD2C2F9C69F58526C834D +:10157000B6A071158F8FDB9588BC9866CF268AE759 +:10158000C7BEA744D8A38922FE1DAFCB4F4E6C9C8B +:101590004EE7F826EAE2E25FA488BC651A4B0BCF5F +:1015A00023AC15F1C6E5B68171E89F2A10E7CA8021 +:1015B0006F932AB371F121BDD0B08E459C53D4F8FE +:1015C00070E469FB9D38DFC8D3EC0EF207B471BB41 +:1015D000F3131C2F97DFE37819D531ECE949D037A5 +:1015E0001E3132BF1A5AE7040E2A833087E2A4CB99 +:1015F000176C645FC61C9D43F5DE66A781A961EB8D +:101600008F52A3991AA62FADC3E223FAB2A04F5D61 +:1016100054A41F902FE68971A5458CB73FBEEC08F6 +:10162000FA05F9B6E5E417C48D1B18311E6B532279 +:10163000FC833CE67163DCE802FAE27ED998D34A87 +:10164000841F302EB091CEA18EFB30F2FA847391BC +:10165000FD037DD1A52FFCB1DCA7D12FFCA1F87330 +:10166000B823F197501E89BF244F24FE521644E23E +:1016700027D51B898FF4E52322EEF75B9317D11F43 +:10168000F0C08488E733C18085F7B31E9D16F1FC56 +:10169000E08DB323FA4337DF16F1FC70FF9288FB2D +:1016A000D9DB56FE207A8FAC5F1BF1BC9EDE37344F +:1016B000FE34627C8DDE3EF8FBDFA437730AFF50F8 +:1016C000D03B51D859879BD7AD75196D8FE2797C86 +:1016D0003C3682FACE81E7E963D1FEAB5497E79BB3 +:1016E000C6685FFB97B24742BD940EA8356451BDF2 +:1016F0003CD5F5FDDC6088D867B73BB93F647772AD +:101700003DFE6B133F2F950EFE26D929030BC5D93D +:1017100016AC77648299AC8F639C5DE7E818A63AB3 +:10172000306F07FDC921BDAAE9D1DBCC6A6D07E89E +:10173000975132D793A03FFB39619EF7A5078DDC07 +:10174000FFF019D1FF48B7305F6C1ED919CA433B6F +:1017500058A284E700E2427A5CFD0E887570653617 +:101760009DC37A134140BF5975D17ED3AD9A9E5A1D +:101770003E9CF4D4655BA4FF767969165D3F7BBB24 +:1017800099EA07CE8A3A470D0FFAF3D6DA396CEDAB +:10179000FEF22D9B62D0EF3C2BCEFF6AD7270BFCCD +:1017A0004D76CAC2FE59D6603E6C1118F138C07B26 +:1017B000E5918ED8DB18F99B9370DD555BAEDCFEAE +:1017C0002AF4AB0DC1646E377CF4DEFC77F9B9EE18 +:1017D000F97F8BFCAE408593C7F91562FC5BA0B125 +:1017E000039E6E013A38B07D635219F2275CA7F36D +:1017F00071338F3023CAF32C6F26D54D9C62AE33E4 +:101800007B01C4F94E95E09CCB3C46CC5BBD737B21 +:10181000650C3ED73D9E360E300CFA25EF3A7CC65D +:1018200064CC1B4CE67513309F05AF7B16A53F8C2F +:1018300076499BEF1DE6BD7406E83B9BB9685C6D7D +:101840007C86E9F9303DB57BF9AA8F1260BEB547B9 +:101850000D948F58DB6CA678AD6BE57FED780AEEC2 +:10186000DF91DED10FEDF6FB2BFF3604F9E1D6CD8B +:10187000325381DEAADD7BA7336C5FE5ECD22B31DE +:10188000781FECEED6A7D058BE6CA63AE2F757BE4A +:101890003C24DC8FAD74162EC7F7D8B8EB3BEF585D +:1018A000FCD2F014AAF712FCB442F0D3DA178792F4 +:1018B000BFB536A69B9F787F2BAF1BD1D67146F064 +:1018C000E3CA97BE89F8CEC46EE023D5CCF7C5D461 +:1018D000A160EFDB2EE7D2771F8CDE7F75C2BC2DB7 +:1018E000573F89C5FE9E37FF4AF0B3B9D7072FCAC5 +:1018F000A26F4C687F5A3BEFB9A029211FE90E72F5 +:10190000B601C7BFED772F5EFA00F1D3FCF2D69F88 +:10191000E133D779FE7397967714F6C625F001F672 +:1019200086E28B2E16CDCF9308FF46C11DF92CFA07 +:101930009E874A7CED66C7711FA7B6D5407526B154 +:10194000B8091496AF8B950D9A51725B9CA0AF8528 +:101950009EF97FCEDB2AEAA83E20D21F2A38B43275 +:10196000C20FF2C05FAF7ED033DE5ACC2FE9FDA1AB +:10197000F101C36253DCF7F84587A6F5EA17414049 +:10198000ED96C688AD21F835E8F4F37E2157F53899 +:1019900016E6FF03D1FCFC33980EF47B7F9ACAF560 +:1019A000B72D83F1F36952E7300BE8CB16E7A2C7F6 +:1019B0001F856B96417CDDD8AFA53335F9C47FDD3B +:1019C0007ED7A111A4B7D8B7301BE243E43DF4742D +:1019D0002BC0F3ECF9617227DE0F1CFE6B2CE67D49 +:1019E00077C4AB6F213D824765DAFF89523A4C8E4E +:1019F0005EE2BB57510F029FCAA9DC1E581A797EBE +:101A0000D1A2BA19C60F5176FBA8F0737F8D4E1E76 +:101A10004F561E7EBFBF09E871C9D0169B03E3AFC6 +:101A2000DEBB3B16DDFF0C93F703E4C35567DF1EF7 +:101A300063A7FCCD96FE180FD607F87730462ACC60 +:101A4000A7E4F584A37A332C2601CFE927503BB2D3 +:101A5000297F19F2597580AF13C7C642BEE18D12B6 +:101A6000F53B1B6BE371BCEADF37A7A13CBD9CC40F +:101A7000E3CD97AE66F3F715A6E0F341A74310D385 +:101A80006FC0F8E46511D7745E95E9396DFE918DEC +:101A900085B21DF82127B0F100C5514D6615E91A30 +:101AA000F51CE378688A22B9AF6E99CAD0EE77390F +:101AB000984B82FB3BA2837FA4F36ECD6615F3ADFA +:101AC00051F68D2C1EC6DF21F659870347E179298F +:101AD000EDBA365F54D3D31873203F50DE374AD95E +:101AE000C826DBC2F11C437876A4723EDA111D30A1 +:101AF000609E253898B16709AE109C8CE6D5E01C35 +:101B0000EEC7F3843B4CC1F3786E06E0B223FD8749 +:101B1000330E276B1AAA629E20CAEEA67544D955C9 +:101B2000974FEA0957752EF3A35DFFF943AC5B6E3F +:101B3000518EABA3437D0BC8C08E814CC8F9CF1F1B +:101B40002FC908EF836219177A7FC8AF363E5E3718 +:101B500089E2099F8CF12FB431F1B84E95D6A76078 +:101B60008A298FE301F7DBAD167EBFFB79E06F1B9F +:101B7000F66DFC39579CDD3A4D2239E1F5B8421F2C +:101B8000DC2705CEDF08A4FD2A702057055856BF74 +:101B9000B19FF87495A1E9A99170FFEE28AF2B15BC +:101BA000E67BED43039D6BFDF38B51FE0AC0C7B08E +:101BB0007D5B92DDBDC8877EFC47DE7BE8C974A4EF +:101BC000FF3E49C53C6C973148DF37A96AFACC44DF +:101BD000F50D8D1F53DDD39BA9DE4938CFB8C61A4A +:101BE000DA8F1ECF36D27E74B6380F5EEFE4FAE39A +:101BF000F2E921CFD684E17F492A972F16F40E40CF +:101C0000B96912F2D9827E0AB47B85BFB4B7F5D622 +:101C10002C352C7F58C30EA423BE1F6287A8D5AED7 +:101C200077F9F9B9CAEC772C77B8C3F86F9190F7C8 +:101C300045A9224F96EA9D8DF0AE6AFDC414ABE231 +:101C40003999FAFE6857EAC19FB2F782976EB9D503 +:101C5000C951B51234E1F3D517F8F957A0731D9E99 +:101C60003778F99DC6118BE1FA5EC035D695FACE6C +:101C70009AA9BE72AFD1938ECFD79CF93A17F55679 +:101C8000090201F07CDDBC6A00E20DF8BE281AE50D +:101C90006B17233DA6C9670ECA27BC9F837C5F8054 +:101CA000FDE1A4877798DAF9F9D3BDFCFC29F03D72 +:101CB000C901F0BD1DFD861C3BC801BD3F94E47BFE +:101CC00047BB81CEC9FA408F0FA67ED11CECEF68CE +:101CD0002FB1937C635E3F0FE5347080C6A987D82F +:101CE000044927314FB83FD9E88C25BA69FAF1B0D9 +:101CF00093093BA1C6E17903AB2C47C845983DE465 +:101D00007D612F4FFC2AF0F82FD176B8855D10FE4B +:101D100014F3E6939EBF57D8AAB5AF4F98B91DD616 +:101D2000B9F684DC5D3F8EFE6B40F0C901E1CFA2C5 +:101D30009D5013783D0E5E1FBD99D7D58E71AF298A +:101D4000C6B3CFE3CA371EC47682A7BE18CF3E4FB4 +:101D50005AD07E909F81E6E7D91B0EDC948DFBDE86 +:101D60005D67CD0CF75D1AFE1AFCE34B8087FB5BC9 +:101D700000FFBDD825580EF11F58EC74E6EC79BF72 +:101D80004BD2F4C7A90AE4C7CE0639D40740AA80CB +:101D9000C1B1FFDBD4938FFBA09F95E67E3E15FD7E +:101DA000ED742FB55D27FF9A8CB660EF69EE47356D +:101DB00098DCD9C83F0D0323BF1FA0B54FA61A89D1 +:101DC0000E057D7CBFEB482ACF6F0EF1B1C7908F17 +:101DD000AA1A64BB1FE87EA941769BC01F3AEFF6A2 +:101DE00026E3D99C0BCC77CB44B4F3228ED4BEF738 +:101DF0007217FA2960A7EEFE65EFFB0FAB99F65B51 +:101E00006340BE5AD624B1FF001C2C7F26F2F9D5C0 +:101E1000DAF76A1AB71CC6EF88AD7C4E771FFD153E +:101E2000FA0E46A41F732455F827592C0BFD13E016 +:101E300023D20F46851D3103DFAE48F7EE437BFC0E +:101E4000B2F8BE02E85192C77D4E615744FD417021 +:101E500007AF2B1EBECD2F1BE0FD098A5F467BC559 +:101E6000A0C57D87716E6F197D87C9E73E8DFB3EEA +:101E7000CB853E5CAEF9697EBE3F026637C24FAB92 +:101E800016AB1FCFFCB5B1B8FE6D12C5CBABB645D6 +:101E9000EEA7548BF5AFDE7CF2309ABCCA7ADD7DBA +:101EA000B1FE6ADDFAB57DF3CF5323EBBFAE773FCA +:101EB000E42F46EE37BC2DC6D1EE9BD2B87EAC8265 +:101EC0006520DD56FB65BF9FFB7936FC5ED09D62C9 +:101ED0005D770AFAD33AE1B9CA6D923F803CFE7849 +:101EE000649DE95DF58BCB90AE7A3E5929D6BD7CD9 +:101EF000BB91FC55FCFE0FCA9D9E3F568AF5AFD4A0 +:101F0000ADBFCA2BE9E0E37E744FF8EA6F413A5760 +:101F10006E37B2DEE0D3E8B552E3EB3EE0D5E0D475 +:101F2000E0FEA1F0F64F13F9AD116C04D1A93CE12C +:101F3000BAE8A4F773771D1E41DF5BBB7C6420C544 +:101F4000FB1A1FE8DF2F137EF2D4CDDC6FBCD45810 +:101F50006C1D89F14C9BC125A9149FC58E04BCE45E +:101F600037CBAC02FA5D4D599BF0FB8379270AE62B +:101F700060FC9F7FC240E7EFF61C29A07DE7FCA331 +:101F80008312B228CFEDA2EFE3C038645FBBDAF270 +:101F900036E1F984AEB692021C5782E7D00FC8131F +:101FA00076A2A62DCF1A7EFE7C4C1A8FEFD73B3F30 +:101FB000FD39FAE9537719E99CC55463F04DACDB60 +:101FC000DA7344A17DF2D527963C1485F47D51A2A5 +:101FD0007DF2C3ED6B1317229F3519EDB8EFDDD5F8 +:101FE000F4E30378DFB75DA2EF5E54379766EF80C6 +:101FF0007EDE967C57F8F9B33C874AF0B1542BC586 +:10200000CF53FB19C96E5E4CB3FE16FD9F95EE2DA6 +:1020100024DF17F7EF3151DDDE0E89A1293BEC3CBF +:10202000F80AE2E3E2AB274DE88417379C34757C6D +:102030008F3F70C92FB300C5CD1B4D18C7546ED14B +:10204000FA1D26A49347F84755CF7D4CFD95E8CF60 +:10205000C37C2B9F91A97EF760F36B26E4E7AAED82 +:10206000124BC90CBBBF598AF85EC312C6F960890E +:10207000D03FAB987F7D1A3CB76A23AF5B608F4639 +:10208000D6016BFCBD42F0F7AAEDB3E8FB533DBEB1 +:102090005B8871E30DF81CE7EF659B23EFAF107CC5 +:1020A000BD42C7D73F4913FA67381B8E7CFD75A127 +:1020B0001A9703D7BF3EB972406FE7ECDB84BDD6F9 +:1020C000ECE5E58081EC8DFEB9CEC62B046775DBAF +:1020D0006513FAA7654D5F10FE2B9A5AA97EE46638 +:1020E000E65D8DF8BAB9C96A47B9AEE8E07A685AD0 +:1020F00093D9EF97F07E3DD53977B5F0BA49DF7EB9 +:1021000089FC1C4D8F69DF775C26F0B80C14787A57 +:102110001EFABB3C6EAE1271F28A615B0EE33E7B2F +:1021200095B8BFFAE8C158F40FA7B12F6E47FAC0AF +:102130007C0CE763CF44E27DBAD08BD3B773BDA8E4 +:10214000B76B5DA9D933298F09712AC2B57A7B246F +:10215000BEAB74F1F963693C3FF6820EDF15416650 +:10216000CD413854D9E5A7A7DB159CF7482ED85B9D +:10217000B4936AD6F77E87F14DE1676BFD99E21C57 +:1021800078BD7DA32D3C6E8E4AE7FEC2CAF1B20F28 +:10219000E9D51D6F0C3A98AB1A42F106C419CD6906 +:1021A000493CEEC082923732649698188A371E7185 +:1021B0006EAAC8837EF5762EF79DE3603C3C7FAD2A +:1021C00030F247ABB79BE99C6235D09FE28A267E0E +:1021D0009EC2D3249522DDC15F3F9A86FBB19852FF +:1021E0008575CF6AE47C3FABE40BE297A383F87A72 +:1021F0002F2B6A4A6FFEBBE6B7E3F93035CC7FAFD1 +:102200000239C5E7AB9A783D52C3816FFA67A29E47 +:102210006BFEAFFE8BA1FD5AD845CD2F0C825F38E7 +:1022200090FB45F4BDC9BB857C2DB3F37DBABB855E +:10223000FD61521DF17995B1FE503CFA593B78BDD4 +:1022400000DB871F8503FDF8F64B75F1B0EECE97E6 +:1022500024AA87C3F7F17B949D4BEA3F41BFFBEB78 +:102260001D16F237EF06BF654A5E4FB9D4E45BFB3B +:102270006E560D7B88FCCF87581DB595829F3B1B02 +:102280006BE9FBA09ABF42EF0FECE98F540ABEAF97 +:10229000D4F15F547A24DFD5BC1D4D7E63D751D96C +:1022A0008EFB3180AFDFA485E345F8210D07A288BE +:1022B000AE5D276D6447FE2CF8EDA2C83FD78C9326 +:1022C000090F86F1BCCD6E796D20D211F18EF5F734 +:1022D0002FB7BC36829FFBF613FE576D9323BE0FBC +:1022E0005B591FF9FDD79AB76FA3EF0855EFEF863B +:1022F0006B88293104575F7220493C8E34489171B4 +:1023000064F53ED9135E7706EBB903F551BA900731 +:10231000A6049331FF35009D0680AFA689D3D5D0A2 +:10232000CC5B98FF169E2731D2FC3DEE17F956E3A1 +:10233000FDAF33AD7CFFFAAAAF02FBF70F94A9AE55 +:10234000F3FEB7570E0DD7A30CE104BA561B83C991 +:10235000146F9E34107CD5272F270FB2A15EDA525E +:1023600082DF0F9D2EF4DFE181D6E5C8CF3E9C379A +:102370002534CECB69BC7E8FE17A9DE86DFC928FCF +:102380002BD6FB109B2DE26ACE4F39697CBD108F96 +:102390008C4BEF251EB95EBF13ECC3A98512D63353 +:1023A000293E8C87F7BCC7F5424DF3B28F90DFAB67 +:1023B000DF37539DD7FD2DCB8652BDAFD77B03FAB8 +:1023C0001B5FB7ACB881F283D24304970FE173A2CD +:1023D0005F732619EB522B9BCF2493DDDD3B7A9361 +:1023E0002F06FD97BCE9781DFC09E23FF06B88FFE2 +:1023F000F6B415687E8C15C7AD3CAA78103F95479A +:102400000B8E57A07F71A2A800D5B974A280FC984A +:102410007CF4636C21BFA65B4FA6733FA6AB358AE5 +:10242000F20B121BC8F9870D8AE09FD50DAF93BD43 +:102430005FDD2847D42F6AEFDD99AED038CB34FE6C +:10244000A997DCC41FBB78BBBA710FAD6F95B19E65 +:10245000E85DB3DDC8EFEFE0ADF67D581F8BF721E7 +:102460003E8EE325A0C334933F03F3D3C732B99F15 +:10247000AFA7C7E7E93CFF71ECAC7700F2CBB14204 +:10248000EF507B2F76C2C78A785C2B097C37F073BC +:1024900053FAE73E4B97C4774222CFB76AEDA9744F +:1024A000AE3FA7997AFF2EE06FD2B57309EC3143A6 +:1024B0000146C546FB06E1D7A7867DD761CECD464E +:1024C000F2174E31FBEB58EF3843D3B3E3B87DD569 +:1024D000E7CBE789F73C9B55BE5FA43B3F334F3BBF +:1024E000DFA43BEF364FF83BF374FECED3E9C28F47 +:1024F0001FC286A01EAC17E7EFD60E8FF287E7B398 +:10250000F4ED61B12F82E787B0AD19FE2EE57D8E27 +:10251000B59E7D85EADDCE46B1813CAF47F9EFCA75 +:102520003EF2DF35DD72393782CF34BA5C12DF8399 +:10253000D1D365B7A6AFC4BE5DB4D8B7F31BBDBBDE +:10254000519E2B2D174DBCEE3068427D56339CFBBF +:102550004D974A25DA6F0738FB9BC3F4FBA5541E41 +:102560007FDD7F8B4479D7567C1EE3AC7A89EABC49 +:102570002B03ED26E4A7210D8B1F26B9F5B1D32C33 +:10258000ECBB1A332DDC4E76D34F5B77B71D8BF740 +:10259000717D9C482D3E8F767186B083FA735143CE +:1025A000597B593AC033DF2DB9B01EA02F3ACF5E08 +:1025B00030EA7544C3F5D2BB33DDFB4E3ACA79FB32 +:1025C000E55B308F7A6CF867FDD18E56F5C1C71F79 +:1025D0000B3CEBBF2BE31AAAD6E2F7556A9DDE0E41 +:1025E000D29F866F6347301CA7E3376B25A4132364 +:1025F000FEEF4B7E3E13E37E96CEBF770FB8A77DEE +:102600009755E9BC4EEB98D19F41798A9CEBDBF75B +:10261000AAD9F7462EEAB3CED6A3B9A630BA5E5CE5 +:102620000B7A00ED4AF3C164D516CE7706E237493E +:10263000D2F84F11F632920F2F221FE6607B2676DA +:1026400010EAE35DA76207E3787B79DBCDAF4DFC51 +:102650007BF6101F0D9917130EDFC304DFA57A3E1A +:102660000E631D43E68C0CBF5FDB171F5B33888F47 +:102670003B22F8585B6F3D7ECF07E38016337DCF5A +:1026800007F3D78E3039199AC1F5CF58F1FD9EF175 +:10269000CC47DF391C2BBEE3335E6101251EF7CD2D +:1026A0000232DFF7E5E72DC6087E1EAB045AB18E75 +:1026B00062BCD8E799C0DAE9B9292C48AD9BD9E9C1 +:1026C0001C451173513BCE12988EEE544E7D3DD574 +:1026D00025069215C7798B38AFD10BDD42EB57E851 +:1026E000BB3DC49F329ED7E9FDBB2FB333B8DCD3CB +:1026F000C74590BE9718E5B9F07B6D38C9448595FC +:10270000637DD3648559A201DE5D870C24CF2D1D26 +:10271000AA1FEB535D09E2BDCF19D5E18E75737920 +:10272000459383F518DA7AF5789800E3619E6DACED +:10273000029128E13140F3DDC8F8399242A652FDFA +:10274000736946A6D0F7418AA38A218E427D6FB075 +:10275000F8081FD33354BA8FFB25B130CE848D12C5 +:102760007B0FF73FB2F87AB5F1270023E0F9C2E911 +:1027700019DC9E614AF5BD78BE8F124B05CD2576DA +:10278000FE9DA364FACED1F5E2B52B997FEF32F628 +:10279000CE60E7CF0A42FB492EFCEE516CE83B9B32 +:1027A0002EEDDF830844FE7B1077642CF911F2A331 +:1027B00056AFC7BCFCDF7DD0D7EB85D5E7B10B6149 +:1027C000E7B0B5BA926DFED92A9EF35B9068A1730B +:1027D000BF7996FEF968C7063ABD34FEFBD2F6C152 +:1027E0003498E21FED8909F1BB95B9C721BE437545 +:1027F00083FC3B50DDE7AE92199D57B49A797DE595 +:1028000063201FF81D26902E15EB68D883C5548FC2 +:10281000B9DE6171E1790933C26D0DC15D6B11DF04 +:1028200005B5F07D717D3D68ADCD40DF1DAD65D155 +:10283000740E3D29DABB2E03E0BA2FA688CE776747 +:10284000EF9CE444BF317CFD93B4F51B7AD647C2BC +:102850007A1FC9E8A51E515BA7F6EF76D805FEB42E +:1028600075DBB5734A6E25E29C92868FC7A2F9BAD2 +:102870008DB8F39F45EFAAA837F4EBFDFFDC29BC28 +:1028800016A064000000000000000000000000002E +:102890001F8B080000000000000BB3D36660F851E6 +:1028A0008FC0C19A0C0C5DD2A862B4C41D120C0C6E +:1028B0009780F80B106702EDF5926460F006E26D08 +:1028C00040BC1D88C5A518180280381088FB80FC04 +:1028D0007E204E07E224A81BB30519187281381F09 +:1028E000880B815848808141588078FB8B151918D6 +:1028F0005EAB22F85A6A0C0CC91AF4F3FF60C3816C +:10290000B6F4B5EF16D0BEE56E08BE0490BDC20D9C +:1029100055CD4A37FC66AC42935F8DC65F83477FD7 +:10292000810D2A7FAB292A7FAF3903C3072435DB0A +:102930004CF1BB051D2B00FDA788274C9730A2F258 +:102940002732A1F2F9A17C00BE1E313CA803000091 +:1029500000000000000000001F8B080000000000C5 +:10296000000BED7D0D7854D599F0B93F736726992A +:1029700099DC24433260126E7ED0A001879860B04B +:10298000586E20E147A30E082CB440262888166D07 +:10299000C49FC6DD500609BF0921E14F70D11D104B +:1029A0005DEA63FBC5565B75BB7682D646AB356880 +:1029B000D787767765A015BFBA761BD96D976EBBA2 +:1029C000F57BDFF79CCBCCBD9900FEECB7BBDFF30A +:1029D000C5C7E770EE3D3FEF79CFFB7FDE73C725BC +:1029E000FB59701A631FE31F9413731963B5A9B2DF +:1029F000C5C362D9398CE576488CD530B6B25D89CD +:102A0000CF827F1676B4BC82F5E56D6EC35DCA5881 +:102A1000FF036E7F0DD44F6F57C26EE8DAA8F8A897 +:102A2000BEACCB15761BF07CEB472FE7E3FB8D525A +:102A300098419DB1BB199BCCD81A0FFC13EACB2A45 +:102A4000921DF8FEDD2D523886AF99E99B04EF6F99 +:102A500065FC7DF3038AC664A8EFBBAD894D64ECC9 +:102A6000961E98C5430DD9C7BC3D63058C45F82318 +:102A7000D6B205DE57A6DE4758D7470AF46B8E3923 +:102A80009EEF9BF53E0BE07B2DF51CD6730CFF31C2 +:102A900085B14B993F783A1BFE1D66E18F15281BC7 +:102AA000F2191B9DC297B3640CA01FC5D85CC65C0D +:102AB000AC1CC6A9BDCCC5CA607D161EDB381E97EE +:102AC000354984C7653E46F577E74AF1074BA91FAC +:102AD0009B5E0D253C2FC88332C8CC4228231E960E +:102AE000C806F8E7B65DF61EAE7F034E359ADA27C4 +:102AF00002F07E018BBA18C0F7672C46E56216A774 +:102B0000F2CB2C41702C6543252AD4EF52129B182E +:102B1000CC130E45A7E3FEFEAEFED8BB12BCBFBF72 +:102B20005AAA9D0225F3E5D1BA2FB43E6B7E954596 +:102B3000AEC37118935D113F63E3AD751E66B18A34 +:102B400020637A8F8FD3CB61D6CFA03EBE41D04BCE +:102B5000E3FB7208D6DDF33C0B633D049B3905EAC9 +:102B6000A1AEACF806A8F73C1EAB47BC1C6B01CC71 +:102B700043FF638D6E295A05A54B7745A00CA98CA0 +:102B80002980A7FA86F59202EDE646F938E34D4D25 +:102B9000665742FD704C52C573ECAFEB314987FA72 +:102BA00078A83F28E17BDDC5609C86865C57B20A29 +:102BB000F1DD334687B2E2B0969001BFF5A64ECF65 +:102BC000195B4474355ED0DA5C93F79B7B38CFCFCA +:102BD000E83DFBD3C7D67BC0EF25457CDF8E1D2E9D +:102BE000CB417859D4DEBF4865314F5E0ACF3BD721 +:102BF000C10B770ABFBB0E976D45BC1DEB53C3825B +:102C0000946DE3C3B8BD0DF0FE4C951C560CE4B3B7 +:102C1000220E7F85EED77DA97176AE83F697A5E06B +:102C20006854A6F6133E4C46FC38B706DA57A5DAC8 +:102C30003F81ED018E3D080FF55B73D48BF3441893 +:102C4000CD33123DBCB04EA77E83621DD7FCEF3062 +:102C5000EDD3DC861689CF2BE06BB0C36795167C6D +:102C6000238D7F4CC0658D6FCDF7C4BA10958D4A0A +:102C7000D523F7E2BA8E687C5DF38DC77723FE8E8D +:102C800078C231A83F79DDDF8CB91786B862FAF3D4 +:102C9000973FC370BEE50FDF8EEB7A2E8BD6F5D44F +:102CA00087675EBB910D9FF72D81879F9E9B3F4459 +:102CB000756BFEB9A63446023AAB34A5840BE8E541 +:102CC00058FD571EBED7C07ABF89F2A4D23C664ACF +:102CD000504E846168BF99FAA78F419E554277E4B0 +:102CE000C7490D520BB67BE2C687BE741F3CFAA9DA +:102CF0008BC37DC55F72B82FBB7EED9308EF653740 +:102D0000AEFDF93350BF028520F0DDA537ED5FF34E +:102D100077F0CF6F2CFCCBE57B18C9855836C09176 +:102D20006B4A0CF777D9F7DD36B972EC793FC99564 +:102D300042B33486FCB7AC4F22F9DCDFE866417C55 +:102D4000FF3377DC8DFCF5806452FB67DD71940FF7 +:102D5000C75C8CA13C5E76DC1B477E61AB9691BC68 +:102D60008E58F2DACC5F7A2F8CF76E8325CF399D9F +:102D7000D27B58DFBBE62FB65F0DFDCF98AE308A11 +:102D80004D4B5E38F1FCAEC06FA4BE9CE860999AD2 +:102D9000748533D043739B6293DBF50D2789AE9620 +:102DA00041C9D2F874AEE0B3650DBF10FCA9935CC5 +:102DB00072C2F3466D617126BA3B25E0490A7A7BFF +:102DC00017F7FB32840F7A21DD742971254D4EC32C +:102DD0009F2B3281EA3164E95BB6D8E1B4E4764BEB +:102DE0002CDBA6AF40FEFE0BCACDE6B67CDBF3B90A +:102DF00039AC76EAA793C37F20399C94081ED0BFD4 +:102E0000B4FF91B81447B968EDCF1D627F22158CCD +:102E1000D6F3AB03523C06FBFBAB23627DFBA4B8AD +:102E20002211BD9AA73D382ECC599EDAFFDBC5FE94 +:102E3000A7F68FE3C7C2574ACFE56E4A02082DBEF8 +:102E40004809CA6B8B7F2CFCF6EFF95109EE5F61E4 +:102E50005B69771DC2794021FEFDB0FE6431EEDB77 +:102E6000BB2EC02BF48F1C7E2CC07C29F85B841CED +:102E7000FCA003E8059E4B0867651A9C026E17D6F6 +:102E8000A1DDED0D521FF2E92FC5BC56BF1F6D9994 +:102E90003113F173478FC4103FB71FE95DF6E7B0F8 +:102EA000FED5F1EC304EF1ABC6E2C02500CF8A1E54 +:102EB000FB7E9EDA727300E9E6C3BEFC021CE7F6F5 +:102EC000A9090DE15C9D78553380CE6699BD5A32D3 +:102ED000035D7DD8B72180ED3F547B6EBC06E7D9FA +:102EE000A784D7C3F8AB8F94CE34399D12FDAE16AC +:102EF000F83DA9F6CC1C03F0B57CA39CE4C17B7D16 +:102F0000CAEC7806F9F97549213A58DDE696719DC3 +:102F100023D1CB871D2E96C079D404E173A4761FEC +:102F2000F4B5D0FBFE070A6F40FBEDF67617C98BB0 +:102F3000DBDBDC444FAB1BA4389352FCB642C0BB76 +:102F40007AB742EF4F9A12C90F6BBF6E17F476F241 +:102F5000F055AFA0BE3F03F207E5EE8C8D3FD42EB7 +:102F6000013CACD8C2E5D1C9DDB94BEF413922F4FF +:102F7000E51D62DCDBE28A8D3F56B667DBF623DABD +:102F8000956FAB9F3E927F631DD2759742FAF39681 +:102F90008D8F6921924F767B13396C5241CABE3CAA +:102FA000C186165C23A5E8C9A29F5BDBC0DE0C0CC2 +:102FB000B7375B8E48648F5EB49DD90676E6C4E170 +:102FC00076A6254722689F95A7E4882537EE52A26A +:102FD000638300C7AF5DD1CBF2CB496E3C20D522D5 +:102FE0009DE8BF45BB92C5945A946F172B2F68B1CB +:102FF000161FC1DF7B1D405719E87506D215CC336B +:10300000B3A73F233DCF900C1A2F4537B704886FE5 +:10301000715080A3D96376219C97C0C4DE6A2A9937 +:1030200092C74B15EA9B1166A087536BA5F8A15276 +:10303000DECE87F214E0BA069E37775D1EDF26A14A +:103040005D087FA83FDBB8DD0DED4C7F1E3D3725C9 +:10305000288BDA4B5FC6FDB904048056CDDBE33C18 +:103060006067114AA07DC25D4D5D6301288BA19F01 +:10307000CCFBD37B6C1720391EA7F5E2F8384E85C0 +:10308000125F8372C6A2E36542EE805CAD5481BEDE +:103090009A595618F566735BF979ED971BC276F964 +:1030A00071539D5D0FCC35EDF2FFE6D997D8DA2F3D +:1030B0008894DBDEFFD9A22B6CEF1747AFB2D5BFE8 +:1030C000BCEA0BB6F64B5B67D8FDA49FE6D27AD676 +:1030D00008BE1C09EED785BCFC89C33EB5CAA6EB69 +:1030E00013356FC33EB175EEF0E3509C98C316F5EF +:1030F000A5C9159F2C113E7F036CC2FD833F7D4CFB +:10310000780CF1799BFEC2DD9A89EE34D10FCD2582 +:10311000B4979CED4F2C8679D2FAFD9B24111D9E0D +:10312000EBC73C3DBF04905B80937300F577B264BE +:1031300009EE9B3BD7A0F777C9C902ACFF860DED1E +:10314000CDC7FDF5258B917F9A55F69C9483FDC2E2 +:103150001E37CC07D6106B03FA6869FBD171B4E354 +:103160002423C89660DDE34B207FB30ED787490B3D +:10317000EFC087BDA1E88712C021B5F7FF5EC2F797 +:10318000DF6706EA61962CCA45FF11A74AE7C3A686 +:1031900019AC15F175A2D18E37AF58C7CF2599DA82 +:1031A0003DC7CCDF221F9D9474BE3E01EF36C93C63 +:1031B0008BF35970BF9BAB6BECD3C1ADC8B508F7AF +:1031C0008F08EE0DAD2C99AD8C0CF715CC74CBA3FC +:1031D00086C373969959999ECF0276CDF4FC7237C7 +:1031E000AB447BF58494155E5F8AE5D03F7E0DF895 +:1031F0002AF60D5FF87163385D4C957369FE666160 +:10320000EF16B64B896CB44F9987EC57D6F390E91B +:1032100041B926445C4B9B7412D7CF3A1ACDA427F0 +:10322000B55E66482CBDDDB97D6F73537B4BDE58B0 +:1032300072CBC2A725572CF965E1D539FE48720635 +:10324000C753F310FEE824399D4E74C0C70484C7E9 +:10325000ACC6FDB3F60DDCC898A77AE47DB3E414E0 +:10326000B463E8FF8FB45F8027B2EB5C6146787A85 +:103270003738B4F42958F7401BD7D7EF1631B20FBF +:10328000CFB45D359083F8F1782A103F857C2A56BB +:10329000181C5A87F2D5A726FA11AE42A1BFBC8CE2 +:1032A000EBAF4266ECB81AFDFBF6934BB09DB53F11 +:1032B000B9627F9A617FD01F69F60D15A39DE44620 +:1032C000BD06EDDC2077512E17B6BFFF1FA8170BE8 +:1032D0001D7A112161E9706455EDB8DA481FFFA32A +:1032E0008D685F5AE35287F4FD0F6A2711BF85EDA1 +:1032F0009BEF5602B6F1A58F110F426EA3D9756EE2 +:103300009E52B457E5843B90A20B275C56BF91E8D0 +:1033100084A5CF536EAB933DE1ACBBC39A4D3EBF8A +:10332000FBC7F29C56DF79E8CD399E93BE9D7C2089 +:10333000F0F029E87413A7532E172CBEFDCFA2D3AB +:10334000A8B5AFB1DC3B8EA07EEDD2C2B30CB413F6 +:10335000867EC8ED04B77108E92C266555C2FB6866 +:10336000874A76A36557F4AFFDEB2D65F0FC44ADBD +:103370004C7EC489F59CEEF73CC0ED514B6F478500 +:10338000DE46BB00F10A76C3809B971E1CC7BFFEBA +:10339000E65209E0F61843FD6E6CDF6690BD9A5365 +:1033A00017D71BA18C571CF28C3352722919CBCF23 +:1033B0005B0EFBF5AD5C635984ECEBE8E8B9FED439 +:1033C000FB1FCB5C3F4D2B6179B361BCE45639FCEC +:1033D00020F44FBAEC7ACC2AD7285C5F26BDAC0427 +:1033E000FDE091DA0D29965ED535DA97F903C771BC +:1033F0009F46DA07D8019DE298E7E890E31DE6A131 +:10340000F1937EBB1E3A29F49005FF27D0AB0B8BBE +:10341000813EF64A99E1FE488C177D0E0080FD8EB4 +:10342000AACCCCD4CEB9EE7F10FD12B24AF3EDA8EF +:10343000D8391BF73B1653C2E9FB61957FA170FD9C +:103440009933B721B711DAB1F599DBE589768FDDCC +:1034500097B508FD2B409D8AF19A504C9F371BE38E +:103460009153F326A18FFD63D43F30EFEEC819BD11 +:10347000C5F789F051105246C6C79BB2CCF7D1C1EF +:10348000B77BC05D43F999943C147F6989B933F2E5 +:10349000B125A79CF2C8A9E724D3646DD5C3E58AFA +:1034A00035EE27D567201FB2945129BBFD9C3EBB4A +:1034B000587A1C410E94C82CDA97C13FBD5AE17866 +:1034C000EA8FF138856ACAA4B7662A4D4C023C6D72 +:1034D0000832920779B8D7C8B70D2C0E2860F92C9E +:1034E0003CE0437912945982FC56A71F6836A11F0D +:1034F00018E4A0317D54597F213C0FCE5F49E70C81 +:103500002CC2E5AD0EFF713E32495FB8055EA3B136 +:103510004914E7CC6BB2CB7137FA81201FF506C78F +:10352000F3F933E9BCC1CDD29EC33AAE52FCC1D34C +:1035300060DAB36A5683FC59BDFFAA5D8B61FC9AC1 +:10354000476E7E1BCBC907EFC9FF1294758FEFBA88 +:1035500019CB92D7A26333C553AD123885C9750014 +:103560009F8F19EE9C91DB19EB9508DAD5B08F1D72 +:10357000480FC9587916D2F72A85F37FFF022D80AC +:10358000F119750B97ABEA7C401ED13FF7D39B53E3 +:10359000FE34F915AAF093947685E20849BD8CE2D1 +:1035A0002D87B6C81A96206763388F357FAF88534A +:1035B000778A78AB13BEDE92A162948327D67F44CC +:1035C000F6A1A2678567C37C5D7E5642708878410C +:1035D000B3D8BFE4DA7A4F7ABC48117E4EC7D139EE +:1035E0000306D2C18012F61AC4371A8E1BDD329D33 +:1035F00061FC65961E66684F740ABF47F1990CF727 +:10360000355B6733D1AF85575A08FB57B17002FB62 +:10361000B7F7236E61BDE6EDC8073FB896DB2127FB +:103620004AED721B48A80BF694CD2A5AAF226D368C +:1036300005275D8534FF7BA540C8554EAF6FD44E3E +:10364000796C1BD0C1736EF31E65D427E023875CB1 +:10365000FF01B009EEDBA3925D9E5BE541271FB53C +:10366000496417AA265FE74CE5C346D4931BC16E95 +:103670002C3486F3CBC6D719D98D1B81FF62A5994F +:10368000F8A75A421971B1FC93D79E2B611CE3B382 +:10369000F2CF5F2AE29C4EF00FD05902ED984725F9 +:1036A000A3730AACEF3BFB1A7F3C055E3F7B604592 +:1036B000F635507E2FBEF1FA6B60FEDB1FDF938D77 +:1036C000FBFCE8ABC04FE7F1E32D7E6A461BF63CFE +:1036D000713663AD9D9F8CF515C44F6F295C7FF5E6 +:1036E0002FF8DD1B57FF7F7E3A1F3FBDAD007D4E9B +:1036F000FBD3D9E2E879E45B7311D3D0DE823626BE +:10370000D27934682F7D6A16E17B9D8BCB31BFCB9C +:10371000CBED8E107FEF1CEF6FD44F1E3F5850FE45 +:10372000D9F9749DCFFCE8F3E077903B246F4E8C81 +:10373000B3F37DA78BD3DDAF5C9F787DEF7CE17326 +:10374000581FD8F564DF5DA73203FD80892F7848C4 +:1037500058BC3A6EE311648969F03C94C7DFBBF34F +:10376000485EC6D18E19522AA9BFC9B81DDF54B30D +:10377000F9083F9718AC5804FEF21CF817DA23D763 +:10378000F9B85F01E3B0108CBFDA1B2D5647D17832 +:10379000E45FBEFAFCBE20CA97D73D66093E674982 +:1037A0003517CF072CBB63647E57D9E9343FEB69EB +:1037B0008D111CA72ED5285E89622C00F5ADA5972A +:1037C000529C928563C725AC8FD219CA71251859AE +:1037D0004C76489BDB9805F5AD6040C58244B72424 +:1037E0003795F6DE5000E500D825F85E8DCDF568FA +:1037F000E8BF8C923108CDDC6D1F91DF7DA298CBA4 +:10380000DB8E298CCE69061EF8B7A532DA3BED6E49 +:103810003AB700BB91F8352AE44632383DD4827E6F +:1038200046911696A0BE29F68BE35FE3F2C4F44CF2 +:103830004E8F8FF078474B88FBBB4EBB6FF3D72F73 +:103840007BD3C0F17EF85AD7E550BEFEE4CF5FBF10 +:103850001CDEBDF1ADD76A30EEEDAED36C714737EB +:1038600033DE447B0B7CA68486F2397672096E6661 +:10387000CAAF9362889F688D3F8EEB45DE46FC247D +:10388000A728FC7C11FE42005F40C0D71D3C554577 +:10389000F3C4DEFF8F4CF29EFE260B3D02ED36E7B1 +:1038A000DD1F4739929A6F12C9A728C827F423A3AE +:1038B000BE9E256B683E7FF841ECF347D8D5C9A979 +:1038C000F3C2435BE6B5209EE72EF0E84867EED8EA +:1038D000E6BB91CE9DEB3CE37BF0520CCDD9E607E5 +:1038E0003E715768A697EC5F7698F64334B1E0D600 +:1038F000418160DC01FA2F5BC132F437A03FAE1387 +:10390000E419DADB563F206313D77BC637FD528AB2 +:10391000F78B7885D5EFA69844E7043795031B9479 +:103920000FC7D3069FFC93AFE1B94B4CD1154E079F +:10393000A18A34BCE19F3D6EC6E9E2B27D76BD0B43 +:10394000F32F2CC5F73185E8C5C92FE3E3F6F61B45 +:103950007CE73FD71FBE9F1CCF1305BF59FD2DF835 +:10396000085E29537CDD7E2E73539DBD3E77183E45 +:10397000CE0FD774D57E6ED3E0B38F3733687F3FD9 +:10398000BBC85EDF80F19B4FB26E07DF3D3DC6FCDA +:103990008EFA19FC7A4BEEBEEF89FC2D8DA38619A9 +:1039A0008ED3BF60EFFC794007853AB73B0AE72F1B +:1039B0006CC8AD4139C5449E4966FBA350E87BA560 +:1039C000FD252507FD5193B74F2E796B460E9E17A7 +:1039D000D7313A4F8FAAF7C4728C943DD2AF966715 +:1039E000219E3F7F7BE46E6F7ADE4DCA1E79E055E3 +:1039F000A326833DA2DE239930CEAC25608F54A54B +:103A0000DB23AD12CAA0EC25608F90DD117D0FF194 +:103A100035925DF263CBBEF767B6ABFFA0723D0B8C +:103A20007AE69F3E8B9E19E735FF45FD1CEC8169C8 +:103A300025C6CA48063AFC40E5F10E4B7F36061310 +:103A40000A9E9D83DE545DF0FCDABAE44B288E3B7F +:103A5000F49D415C37ACC7E5AAFDF4EB39A372785D +:103A600026AA3C0F66A47EDF1AC15FF16A5E61B7C9 +:103A7000D8F7BB7FC13BBA8CFE0BF831E8BF247D81 +:103A800065DB302E7826A652BC4E9DBF72F75CA433 +:103A900027B0B3393D9FDFBEBE7648B6F1F1B4B36F +:103AA0005936BEAF67F673BA191EFB395DA36E3F78 +:103AB000A79B15B29FD3CD31ECE774D757DACFE986 +:103AC0009CF6FDCCD1AEFF9EF67DA891113F5DC066 +:103AD000BE077EBA09E969247EBA2EDFB83F92613B +:103AE000BFAB356EA7AEF6461620DD4D33B85D1779 +:103AF0008DADA77CC0BC28C89B528A1B52DCCB8AE8 +:103B00006B59712F2B2FD08A6739E35756DCCB8A3C +:103B10006349311EB76AF6445720BCCDED27659442 +:103B200023FA73300F3282758E372C3EC7E5414B36 +:103B30007BE6B89C33FE3662BB4FC9579F837E58E5 +:103B40008FEBB5F403F0F9839F85CF416E6DC3F120 +:103B5000FE05F97D14C9936EDABF0AC035DAE9B003 +:103B60000F1AC6E9179CDE8FF138F5B89BF8F6629C +:103B7000FD5F4C749061D3A2E083633C2B1A2B252C +:103B8000FD62F18DC5274EFF78187FFC57F3CF45B6 +:103B9000FAC7C03FDF739D471F017F3C8FF89E56D9 +:103BA000C9F1EBE4078BFE8124125235EE773481A4 +:103BB000ED2D7A672F864D8473A2F06B4E8CD6C89C +:103BC000BF38F1FCBFF373D8E73DE171628DF87E39 +:103BD0006277417C5B698ACF2C7E6AF7447FEC4A2E +:103BE000CB03B1F21D0F7BCCD7F17948ED4BA0BFD1 +:103BF000129ACDC21B0CE2B363FC39E7535F9851B4 +:103C0000FCF433FB657B5D713C1F6A91869632F252 +:103C10005B99867CAB0A79F26256F424E2B3797A36 +:103C2000A484D3D3D0381FC0F58B0E85FCB5CFCA82 +:103C30004FCD23E1FF1C3EA243AEDAE1F901E97268 +:103C40000BE55B28A4C5374819E495C0579C85C788 +:103C5000E0FA603FFF1DF19857C5245A8EE0E366F5 +:103C60008FF907D767B33F14AD36C5C780378F8646 +:103C700072B11AF0563E1C6F275D7CFD4EFA0BA9FF +:103C80004919E93F0472748394764E2AF062AD6755 +:103C900024F96CD169DA7943484B5FEFFFA372D9FD +:103CA0009297977BA293711FDC6644C83F93F6D727 +:103CB000296786DB41329D339E01BB07BB5DAC7C2F +:103CC0009D76D68B87256CEA5985CA6BCFD2E109E0 +:103CD000FBE2D96C2ACDB3F954D69FCDA572FAD99F +:103CE0004BA89C717634950D67011830711ACF96E8 +:103CF0005239F3EC1554CE3A3B9ECAD967AFA2763F +:103D000073CE4EA2F2BAB35FA0F2FAB353A874DA3C +:103D10003FC67A95E4B725BF2CF9EE94DF96FCFBFD +:103D2000BF26BF630D1765FF80FEFBAA761EF93D17 +:103D300092BC00BEBE4F4B971329FD7CBFF619F80D +:103D4000FAB8E053E0DFF7300EE3012F8EE2546162 +:103D50001EA70A189A81791AFBB0096CA9BF3472A0 +:103D600012E306CD0B3C7A0CE01E28D5483E6D0BC5 +:103D70006A74EEB659D2477379904C20FDED0C6908 +:103D800034DEB63F2A5ECC5F7869544100E7E9F63D +:103D9000CB3AB6FF566E72DF2D788E3F85850FC108 +:103DA000782BF6ECF1A4FBE1FBD13800F802B1A7C7 +:103DB0001903BEDE38EA774B713EDF5446F118280E +:103DC000CD4CF962DF748BF36975288478DAEA9355 +:103DD000491F74EB1E91879A1C68413FB74E66DB02 +:103DE00060DE0DA3DFD98260ABE3CA7694417D67C4 +:103DF0005D991737E9E9573E08913D01EF10142806 +:103E000013A23473607F3ABD61E37CE76D8A31B4FD +:103E10000E8915FBBBAB476EB7C93F1042FAE89855 +:103E200034B9F21698BF7752C1689C7F7BCD511B85 +:103E30003E14DD1E4F5130E0887E785D92E26A1BB1 +:103E400064634719AC2F20F2AD01CCCA485ADE8119 +:103E5000058712867570B8120A5F0F2B80E7B97557 +:103E6000895892AFD7C4B8ABCF970CA1BFA8D49D47 +:103E7000A6785BA73FB988EA0E38ACF17FAB5979D9 +:103E8000019C6F7C826F9A277D7B11E5915769B405 +:103E90006FDDAEA105588FAD75B1C733C46F36085D +:103EA0007EDE5679FEB88CEAB3C3D1EDB5FB8B1636 +:103EB0003CEF8BD20947B36B6854A6FDFBB4F35FAC +:103EC00068DD9FF77C9D23E40F5CEEB6EF4340C8AE +:103ED000F3E629DF0EE1B9B8054FA704FB50F3F96B +:103EE000EF43F3142EAF3FEFF5FE4F1BF7F71A8F9A +:103EF000AB009FCE2EC738E398C9218CD7FAAC7897 +:103F000074384EF949018C47532F83F490AAF3314A +:103F1000149525900FE5EC0F13B84F4AB566282489 +:103F20006733EFBB12DE44796D4EFEB4E0A6BFC925 +:103F3000C274A0F343AF159F36D4C9FCBE04C67F3C +:103F400015669DCFF2F8B4D55FAD90291E4D81EC7A +:103F5000B47154D0C3788EA3609C3A6FF8FCDF4DE7 +:103F6000D1A37DFE221E1F5754EE07BE27717CC4CD +:103F70005E5528DFB3EB792EDFD87146F2BBABD6A6 +:103F8000A073951DF03FFA0FB15A5F1CE95671E41A +:103F9000E39DA99C1E42396AC5C5693E7E3E4071BB +:103FA0006ECC53A4B8B9C12AF07DB700CD1A47B57D +:103FB000E2F2956B26613BBFC13CCFC1FAFC752C88 +:103FC0007109C01B74B76EBDBC34433CBC72CD37A5 +:103FD0009E8479773F35FD574F427D971C7EB50E05 +:103FE000DAE57FB98EF0EA8C876FAB944D1DE583DF +:103FF000CF7708F7156C68A28B5B7BA4183ECFF6D1 +:10400000F90EF2FD6E0D298817D0938817AF332F64 +:10401000321DDF6508C7CE8179F06FEFD679CB709E +:104020005E841BF32B57F4D66BA867824BECE71723 +:10403000FE267BDD5B658773ABD8BF0BD1BF330F2B +:10404000B1C79CB708E9F64C5063286F36AEBDFA8D +:104050004692FBDB1536AE3403FD3AD6D5A9B948F6 +:10406000FF771BF57B2B506F346894D7D31DF7C6B1 +:1040700031C57B7B5DEADCC466BF1B1A3FC7AA91D2 +:1040800013EE4C76BC381F0B8867CC710ED63D5BA7 +:1040900026BBA6BB87CF638DD75DF79607E5C448DF +:1040A000E33E3DC63CE2467B2A9A7751F72EEEDB93 +:1040B000E8E2743D458B4BA5688FEA0B17417DF311 +:1040C0003899EC2126FCBFEE6BF979E2C39A61BB0B +:1040D0005FB169CA4AB21B6E72EB82BFC02E9C9060 +:1040E000BA6F71C06BBEE086E7EA733012D803EF97 +:1040F000E5866F44BA680C7E4476D4AD45B28EF442 +:10410000B5624F23AD6BB32EB304DABD6A2B19A988 +:104110004DACD5C4F3004CD444BA9B036F64BA17BA +:10412000913CD40970CE195738691BD4DC45AD9445 +:10413000C7D26848E4875D07984179D0521C51A5E1 +:104140002AEC37FF1DB4FBE6044B65F4F7AF535977 +:104150008396669F835D7CCC9DB6AE13E3F604E543 +:104160002A9C1FE6C1F91779E83E811BEDE32B532A +:10417000F6F14444649A9DFC6B342A319E5194F8C4 +:104180003DE5797F3F29E3BCEC0556BD4DFAE47E61 +:1041900035F897BFC4FD8C33A31F530D3F6B5CE212 +:1041A000EB9AD827716FE5B027F21B1CDF8A074C0A +:1041B000D4F8FDE6CD2D2C1C4B8BAB6C7EFECF8F47 +:1041C000A3BD6AC55FCEE5DD09382DB837492C8B14 +:1041D000F4BC27FA0777BA5FCC926573277C7E70B0 +:1041E00067C897F3D5023F8D15FC93575BE145B93E +:1041F0003916F37D701FDAB93C31E1BFF47C1F45FD +:10420000305F30DCDA2F1BC3E59222EE4D015D4BAF +:1042100068C73AF38114CCFB99385C6E1C10F47FAC +:104220008947E4FF4C6693B91F6E3FBFF22FE57AD2 +:104230009FB5E665BC87FA7DA1F75F147E6542DC19 +:104240006B3C2AEE2DBEBCCE203FEF957595540EEB +:10425000AC0BD3F3D7D6D55199BA5FC5E7CD177656 +:10426000988A41353CE7F7B1B801F0FA47AD192813 +:10427000453EAFE3F7BBBB9B4E6D2927BB919F5BD0 +:104280006C2EAA4E14A2FF02B0E643DDE5EBF3F07C +:104290007B5EE6606501577388F7FFEAF30A275DE6 +:1042A000E8D6FE3BF6DBC75A19CABB8069DFEFECE4 +:1042B000B0D3BFE1FBEF2ABAB87DEFC57FC03E7E29 +:1042C000C9DAF7ABD9D5FCFB0C17278F918F2A855C +:1042D0001C1803FC7400FC79B7C2F3D5F3799EABCC +:1042E00019E2FC66AABC1E1B2FDABB3809B1813C5F +:1042F0009ED75ECCCF13A81FE695E37B0C4BBEC0C8 +:10430000E35B2C47E4BF8F15E3AC16E34EACA67B12 +:10431000BBFCFC9FF5E958FA5892EAB9C007580669 +:1043200059AB84C81CC306C9DF2E9686A86E487A8E +:1043300016D6CBA47019F7C3E3A43FCB15F3DB1556 +:1043400084FC88CCE345C9C5644F825E46B91857E2 +:10435000238B50BE6C68D3C28089737972787F0ECC +:10436000CB0D7D350378FE118BC9247F94E75896D9 +:104370007E25D97BA4BF36ACCF3B984DF91A49CAEC +:1043800073DFEF29B5E9A989BE85D7E9B05F1B4581 +:104390003E9D0BFAB30CF9A7563E1D8C5B92E9BD0E +:1043A000556EF46B8B32F9FD0F7B2411CF488EA62E +:1043B00038A0D8D7F85439E37DC67D1E6ED73C5A55 +:1043C0009AD99E66EC411A6FBF47778C9B6CA1FB14 +:1043D000333A8F6F64B94CCAAFD9D8C6EFE95BF8EE +:1043E0001B0D762DDAC31BFBE6CF46FE8E55AA9435 +:1043F0006F0EEBF721FE5C222F79E3F8E0C16C1E13 +:1044000097284539DD8FF8AB4DC35F706513E2AF78 +:10441000E3559EDF0BFADCC732E41B5AF873F9D878 +:104420001733BDB7CA8E51DAA24CF7868F7A2C3B70 +:104430003D59CAE984E32FEB5A3592A97D42E0BB8E +:10444000A48C45CF87BF7E8F6E1BD73AF755468821 +:104450007749BE04C5B9266ADCCED8B098E375C3E7 +:10446000F3D71C8FA69D43FC12879C928A075B7131 +:10447000634B6FB67BA2FFE81995D297ECFB8CE4F7 +:104480002E7BC17310F72DC339C4294F6D867388F5 +:104490009E8BFBBECB58C1B787B61C9D87F3FC55DE +:1044A0001D23FB2AF00C9F37576771B914BF536067 +:1044B0004A1867B926A2D7A3FDE66A6726E6CF8C1D +:1044C00015719BC2F63E05E922087B5928E1BDA67D +:1044D000640CBF67327637233F512D9CB96ABD21EA +:1044E00044695A7E94C286FA697DED9AF1782981F1 +:1044F000F553D40F63C4FB40FBCC5FA1DC1C1389D4 +:10450000521E2EF48BF9D1BE10782CF072BE5DDEF7 +:10451000109624681F0C26293EE994EB63003F9710 +:10452000A4D96F015167ABB89C96E13FD4F3F91160 +:10453000BBDC1EE7B8171D70E4BDE47A45BEBB25A1 +:10454000B78BF8A64E5007E54C7E794ABF3AE04358 +:1045500019569DEA1FB0EA9F113E2004A2670B1E68 +:10456000BC4A8972778F4BFFCA53A89FEB359E4791 +:1045700026EECB650BBCFBD061867603535E3171B2 +:104580005F7784F97769CE4C9D477E68769D759FED +:104590008EDF5786328671BA6C31BF75AF2E9B198C +:1045A0006F96033D649B49BA57A75BDF55305902AC +:1045B000F370749F4C7974BA2F42F2A9678147C790 +:1045C000EF7C68E29E9E4BDC1FCF364FD3FDBAECEA +:1045D00061EBE3F7EB2CB8B3B3AADE2C376CF3AC8A +:1045E000C7F836AC7D74C6FB7575DC4FCA36791CCE +:1045F000226D7CBA5FB7636A99ED7E1DCD837E9C88 +:10460000A03FEB9E9D13AE73FD6A32DB6913C27649 +:104610003BE242F7EB5C217BFB1D17C8CFFAC4F7E6 +:10462000EB041E86B573D8832ECB0E1D2533DCBF5D +:10463000330D327D4724F7A3646486447109D2F7B1 +:10464000969D97C787FA6F67E7E55979FD0E3BCFCF +:10465000B2DF7267DBF1EDB4FBDC5511EA73B176C2 +:10466000DE2EFC07D0CB435E879DD794993E9CF20B +:10467000229F0DEEBE12C6395AFB2305F3D576E50F +:10468000F2EF1FB161FEC15B33685F7CFC7B47BB0F +:10469000A6F4ABF8FD9BDF2D656427597104B78044 +:1046A000795791BC9EC2EE5D0F117E82020F4DF8CC +:1046B00001B21AC2557C1CF199E9C5BC85FC26469D +:1046C0008D0A2BC2B4EFF85902992E6DC554D4E36C +:1046D000F58895343CCDF0D8BF13D0A8E73BF6D190 +:1046E000BECFE7CEC11FE4DF539863D8F7DDF29366 +:1046F000D09CC5F9AEAFB4D3C1092932A84097A761 +:10470000B34A85FD33A8A3BEEC5EEB22BBF1A12525 +:10471000655BAF447F3528EBFC3872681CDA47CD07 +:10472000474D2FDA79DB23D3BDE3E0FD431D4A1863 +:10473000CDC3A796AC7915EBB1DD2EB2839EEA9B73 +:1047400057B0228DEF36EF5EB07031BEEF70917EC4 +:104750005FB1E7BE81D220F677D5A67F6FAA65E369 +:104760007D3AFA6D6FD47A33DA31576771BB64A33F +:1047700096A4F8D3C6791A43976B6349FDE8156888 +:104780003F5CA365BC4F7E57969BDFE773B54A2815 +:10479000DF0BA399EF0558EDC6D6FC96CE3182B358 +:1047A00065867E9CEBFA7932D61F827DD5A5143DB5 +:1047B000E5097ADA5874EFD60A5CDF40E67B875663 +:1047C000B9366B1CA7D3889DCF5D854DA371DD2EB7 +:1047D0007764A01E89AB50D6312EE272B7466E4682 +:1047E0007BF46A175238DBDCF1C38645B82F614988 +:1047F00097609EA01A59457416CC62A80F1A964469 +:104800005A112F85A0FF30B45758F44B3AA728AC63 +:10481000D39817EA9E253D0917BCF75444AF42BC14 +:10482000BFB4967FE7A530E8A37B4185117E0E5784 +:10483000D8EE6668326C0417D845FE814471222791 +:104840001F59EB6A5ECAE5F8EEB5BF1D95E97B33EB +:104850001559658457AF615FB707F52E8C33D51CAA +:104860005C42F8AE71B338F1AF9BE87B57AD8BE09B +:10487000DA35E5E45710AEDFFD3E8BF6FB5A664AAB +:104880000857FE103F67B5E6C96F1A54783C9CF391 +:10489000A193EF2C7E70C2B773F63C3A8FDBCC0647 +:1048A000E723BE636765A2A3CD456BBCE971D15612 +:1048B000417FB00F245F623AA3FD56FE95ADC77CE1 +:1048C000D88D5F8C54227FBCEDE5F756EF5BAAD103 +:1048D0003A1E9AAB51BCF1217F2BD1FDA98DAEF0D0 +:1048E000210447D517E27EEE2EAE0863BCEDEFF053 +:1048F000F039CD3FD83DEA4B9588CF2FFE218B8FE5 +:104900003345B5C6F919D17BAD97E09CA1B4FF6CD6 +:1049100005DAA14BE4C9943BBD6A09C92F9790E31E +:104920002F2FC9AB473F2570C372C6E5218F5304B3 +:10493000D656F3FB0C0EB99FA85377CFA05DE2F1DA +:104940009F7A21EFC6DE30BD1ED7592FF482A966AB +:10495000FE2E63AE685F381441936C58FC2757E80D +:104960008FB1BB1DCF855EC81D16071FACB819E4FB +:10497000CF97B2841D3942DC67D79279C40F678024 +:104980001F282E5D7292E83F067202EDE637A4649E +:104990006845DA7998F59DB99F887850C42CA53C74 +:1049A000E1B7443CE8A7E2BB73EF8878D071110F00 +:1049B000FAB98807FD03C683F0FB61DECB69DFC669 +:1049C000D57DD48F719C9D350B3C068C33551F7C57 +:1049D0000981FCA239E813F9F7046FD0D24373CFF1 +:1049E0001FA74A205C6E8C4B71385F16DFA37B4596 +:1049F000C03520E07A4DC065E941941B48676CAC36 +:104A0000AA67928741B555C2F35E9417FD4192178C +:104A10003C4F3CB84632260C971330DEE8743BDD41 +:104A2000A2BF53A37C44C7CEF11FCDE2F70E5F5A5D +:104A30003B6B3F0BA6C9A3C8C2554877F9B03F28C6 +:104A40008FA24D5C8E47F1DE459A5CB5E269B023DA +:104A500061D23B37703C8D245F2E24570A1D72654E +:104A600037CA15A8EF46B9124C972BADFDB8EE200A +:104A7000CA1596D243C1C827932B3FF396D9E22497 +:104A8000967CB91AD898ECC430E853FFA7D7A76F23 +:104A90000B397121BD6AE57F044C467A7D0FE685AE +:104AA000A03F339ED13D1CC51CA47CA2DC7617C35D +:104AB0007C90ADD86534FA330B291F64C77C8F8E88 +:104AC00074F1B09408213EF7493D5EBE2F7A3FDA7B +:104AD0000BDB26F038C98E3FDEE3453BFBA5DB0B45 +:104AE00002788ED39B6BE581E88B6F85FAA94646E9 +:104AF00074B262CF0A5BDEC3CFB3F2081FB9319044 +:104B00003F808F876FE7FA4737781E089419F34084 +:104B1000DC3E110F526321A48F6D52D4437198462D +:104B200099F4546F98E7AFF4825F8EE783BD0D3B35 +:104B3000E7A07EDE70ABCC285FBCB2E71E94331DCD +:104B400013161AC897AED1656FA239BEC1277BD3A1 +:104B5000F348F13841ABE6E786A2347300E4CD5E5A +:104B6000D338DFFD5155F87DD8DF7D9E3CF8CEDC93 +:104B7000D0688C13F4362E0CE1BCBDA322A13CCA34 +:104B80004F1943F6C0C6519B1663FCA963B9C6D240 +:104B9000EDA461F305EDF6B51567541B78FE488763 +:104BA000CCFDCB5C713E0D7C5589784B5F27C2A94B +:104BB0009A3C7F04D7ABF0F5D2F74D731BC03FACE6 +:104BC000E2EB47FF55F7E9A3517EA80D3C7F64B3A4 +:104BD0005F5F8C7EA3130E6BFC6BB3259B7FA45B86 +:104BE000790BF56BF8396211CF5BE8759D3F6FA1CA +:104BF00043C843CB6F1C091F2EC73975AFD71E079B +:104C0000B4E0B952944E3846CA17F8B4F35F68DD81 +:104C10009FF77C23E511ACC9966CF72B72AD7C969F +:104C2000C635219413163C9B2F903FF269E16A6EC2 +:104C3000E4ED3FEFF5FE4F1BB73E9BEB47E0D301A2 +:104C4000BC47D931716608E5502A1E3334508EF6C0 +:104C50009CB8CF68E58FB874FE4F55E5DFB993B3C4 +:104C60008BE83BCBEA749E3F427F19F240363136E7 +:104C70001BFD1D55C46F9C7C7A21F89D792337FB61 +:104C800084DF1875CC27F2449823EF440DF1FC1211 +:104C90002B9FA44B82F50553F92023CEEBC0DB7884 +:104CA00021F7DF73F41FB6EE30BF5F69E59F0CCBD1 +:104CB00023992AEFC72D18964722F2517A728D3820 +:104CC000CF13E77925A836319E372C8F64EAF4108C +:104CD0007E53725A89E87703A3EFEFF67879BD77B0 +:104CE0000E8BE3F7CE7AB18EFC54CB28AF65587E9D +:104CF000C9D43584278D4596F1F31D7EDE6FE1C161 +:104D0000995F72417ABB401E49D0677D8F2242F382 +:104D1000F4F8C33FA923F8643A8F2FF8D2F170FA60 +:104D2000F897F8B89CEC1179783DB9F67CBCFBC4D7 +:104D3000BE548876CEFDD58B385D77D5EB1477776A +:104D400037F078E5B0EF40D4D8FD01673CEF8490B0 +:104D5000D7175ABF33AEB76D84FB660B7C3C8FEB25 +:104D6000A12587282FF6CC2AD0B380AF87319FA505 +:104D7000E6E2F3595ECFE2F92CBD46FDC24B518FFE +:104D8000453586F2B417F359E0FD868611F2594491 +:104D90003CD18A8F8E94CF927BEE3CDE9ECFD27B2D +:104DA0002BCF67E9EDE1F358E3F53654939D35D207 +:104DB000B84F8F31651FEE7FC5C59D9F4E2B89FC77 +:104DC00019E6AFF4946AFA8306D20BA7E7AE468DD4 +:104DD000E8BBCBC5FDD8D868EE3733351E5A086D11 +:104DE000B6F8138B289E2CF2327AC5FDF9BFCF326C +:104DF0006CF67167E3774368D7031DBEAC733EA1C1 +:104E000071F2D5D2F5600332B7DE62A24F3990CD90 +:104E1000E308AED0B181BA343ADD22F41DE2470690 +:104E2000FCE44AE7F015950B28BA4F7F6B047DBE72 +:104E300091CDE7B7E890A993C2FCFC8F55A01CB1B7 +:104E4000FCD761ED3CBCDD30F9E390233D98DF8673 +:104E5000154B9EDC60C9133B5D5AF28339E4CC39B3 +:104E6000793287DBE9E7E409C80FFCD499530EF5E2 +:104E70007AB9BEB0E071A3600639F29E2B6C8BD379 +:104E800038E5CE85F8E8F3963B2F65E70BFB83CB3F +:104E90009D20D206F24DB6758EC8EF3D9C99FA2042 +:104EA000C9438FCAD7ED8930FA9D00ACA33CF7E027 +:104EB000394A46B95E2D51BC419C8BE48BEF0F3EC5 +:104EC000EC0A537EDAC3C0CFE8E74D309CF6D9F93F +:104ED000CF159CE7490FAFFD1AF7CF00DFE8775DEC +:104EE000AC1CB2E4C487D97CDDE7E8CBE4705AF4AB +:104EF0009546CFF47D018B7EAD712D3A66C8A00535 +:104F0000E7A15741D7188EA638754C8A631CC4CACE +:104F100023B3C67BC3C7ED9191EE5759EDBE63F93C +:104F20005DE7E2C17A40A77CB21EBA6FCEBA38FD07 +:104F3000CD61BBD53555944FA032CA278894A03F88 +:104F400073D867F78BAD7CB06925E110CA890DC2B3 +:104F50004EB7F2C8ACBCB4C3BE5CEB9CD9969FB64E +:104F60006184FBD96F9EC3CFC57FFF04BFDBB6DA78 +:104F70006B3E8E7211F0658AEF39511E9A35EE77CD +:104F8000059E5EF7984FFA3EC3FDC917B3EC7957FB +:104F90009D3EC31117E0789DA8C7EAE93E5E94DF05 +:104FA000AB729EAB8F74FFD5796FEFDCFD5771FE4E +:104FB000DEEC89BE4CF0BFC8F3DFF470F46027FB71 +:104FC000FCD673C06BFE04C7EF14FC3D2DC8EFED9B +:104FD000BCEF89BE8DCFAF63DCAFB6EC9CC3D80EFF +:104FE000FAFB5F06A90DF4B2A996D36B5125A3EF86 +:104FF0008F4F6FE5F51D4BF9774DFB5FE7F73EB639 +:1050000045F9F74CA15F9F0C78D9319EEBC3FD5554 +:10501000BCDF7EBCDF847C5AC1EDAE3C8CDE2B282D +:10502000AEA3544EAFE9F14E80F70796CA1417DDD0 +:1050300023F822C04C8A736CABE4F3ECAA909F1067 +:10504000DFA359740BD43B67AF9C8CF74BB68B78BE +:10505000CABEC52B9FC0BCBE0F02E582EE1274EF24 +:10506000B5E7F86D141F7968499EB412D6B8EF60A1 +:10507000E6FC962ABF2AFAC5DC229E24CA8486E56D +:105080005653E4ADB632F13DF69886F1A76706793E +:10509000DE6AF7EA678ECD447D5C29539E59D7E0DE +:1050A00051EF65B8EE3A9ED753A426A474FFC5EB22 +:1050B00077713BADE6A8C7A81ADEFE99C1A3447775 +:1050C000DB01EF4A9AFF270B38BBD19F807E7B5DC7 +:1050D0003D0333A1DDDE717952CC48B51BEDE7FC11 +:1050E000D7BD4416DFA167F41D874EF39407E5662C +:1050F000279E7F40FBEE1A2B2FB587EE65ED9D3383 +:10510000790EE6896FBB81074BBBC287C84FEE990A +:10511000CDEDB2BD12B4837DD9D7A25D4FF7985AB9 +:10512000799C08CA8C71A25E4C0446BC8A733B4AC7 +:105130007D81793B1BFA06709EA23AFE7D8BA29A76 +:10514000CCFD5F08B8A9FF3E578CE29F23EDDFBF7F +:10515000FA383E3BABF8790163718A4BED167E1746 +:1051600053A346FA77425B021C3F3B5DCCC478995F +:10517000AF4E23BD2E870DB243FD603F623C6E9B58 +:10518000145B8CF921B1491A7B9C30627AC761FCAF +:105190006E425E18E96F939408E1779563E3787C3B +:1051A000FB686427DDBB3A00763485835982F4546A +:1051B00077348FEE431D8D540F527F5F85EEB634EA +:1051C0000AE6CDD38722199B74D9A6AD68D7744E51 +:1051D0009175CCDBEC94EAA3385E2CD7437164D78D +:1051E0009479B47FAE517952BA3EBAD1CFF5C2D0DC +:1051F00084C88D7E585768CAA95C8C5B6EAF7D658C +:105200001FEEDF23F77B888E1EA91DBC1BE7D97F0D +:10521000F6AAE351E24B7E5EF768EDE952B47B7685 +:10522000359DCA45FC15637C0EF46171058FA3A101 +:105230000624FB4CED6137031E8BDB3466A4E96367 +:105240002FE3E779F8E79B4C728FFE9E193CE569E6 +:10525000C1F196B0C4A5017AEEC1789625678AEBB4 +:1052600058A200E4E1FE15EFC4304FEE91890574B9 +:105270008FB248BC27C909E39588F1FADF78653D0C +:10528000B67BB4BAC04079513C30340F954471D5E7 +:10529000698AB385ACFB1F5163FFAD449F327DA784 +:1052A000B238FCCE5FE03A02BE3ED273D09EE266D8 +:1052B000CE7504269AF7F9018FDF945A5F1D174CBB +:1052C000F963F487FC782FBF975D9CF50F7395B455 +:1052D0007CDB121117D8240DCE26BBF4016E878F0C +:1052E00065719273C555B1BB79BE6D94F26D9DF336 +:1052F0006EF79FD3AF12DDA3CE6F12F74AF8EFD847 +:105300009488DFB171D27D28945FD57155AABE2FE4 +:105310007A8AE8FF69CDB82BD3F71EF609B9B049F0 +:10532000F863D6F86373F9F856FD519DD3E3D32F94 +:10533000E75D5F05EBF9ABB6B24918FFDC31821FC0 +:10534000B732C0E92F7B002C1CD003FDAFBDE6C5F2 +:105350007C96A765B60AE5547D55C293AC12788455 +:10536000F1C91783F10F84BFED41B9F4D54025C1D0 +:10537000B5622A8F1B74563D48E740219DEB1DE422 +:105380004F94EFBE504CC2B8F7F21AA61F12F19616 +:1053900018E09FEECECB2C95D7BF3D97FC1CE015B7 +:1053A0007EAF067393268BDF9F28C773A24D778B42 +:1053B000FC5919F1DD29E601BEA5790E148971EEBB +:1053C000E3F63FFA17D8BF5CCC535EF7DDAFA11E02 +:1053D0002FD2395DA4E0EBF3107CAD3223F8D4C4B6 +:1053E000ABE8876E9F546020DD1C0885DF6E82FA73 +:1053F000F2452AC5E3CB6B381C075A65FA3D207F7E +:105400009D7690EE8F99A02FD2F06588798B6A12E5 +:10541000129E6B19AD7C5DD0CE8B72D108033C50CF +:1054200037C4BACEC13F4923F88B3C83985B740ED6 +:105430000F2B713CA0DF9575BC9F3FD4B705E5D815 +:10544000F23A0E37E87782A728AC1D447D5F14E25C +:10545000E32D07FC1C925270655B70D5C9947F5593 +:1054600054A31D443F385BC0B732CCE1E97FFDD483 +:1054700080C4C73370BC6C016FB6583F25EC16086A +:10548000FD00E33DE54AD4E3BD9C5353987188CFBA +:1054900046F12CEBFDAE56C003E0C72FE661BBDD45 +:1054A000C44FB0C4D8C732FFFD10232D6E51B15B7D +:1054B000B3D5FD62FF58177F4E7E1CA9445E9785C9 +:1054C0005FB7B2CADE8FD5A4D5CBF07E19A7F7F5AA +:1054D000D7F2F38E0313B87D847EC739FE463A9F18 +:1054E000623CD615C4F71AE9BB9276FBB8C5AD0588 +:1054F000D3513E140F3C3C4F86F514DDCB64258719 +:10550000E8593A27FF60BE6FAF49D0FDD9EC81481A +:105510001ECABB92D6BCE9F8FDB7EC8128D5B3070B +:105520005A4D9E7F062E4C1EE6EBA5CD538A729AED +:10553000E7D3B156AD0FE55A6D3A9CF0BEE4E59E57 +:10554000B9D87FF3DDAF8C46FE2D70F4F7E470FF21 +:10555000A1F8656815C0F94FAFC5F6567C271B2129 +:10556000CEA3F2652C8B7D208FA12C11F97796BCF0 +:10557000E89CF0CEA4A84FD00FE5E3B144BA9DEF6C +:105580002CA1FD78D13E269DB7DD696A3752BC69F2 +:1055900020C0E34D0161AFF630633FE9F71A9EEF9B +:1055A000E1C3E7A03FFA6A8E4EA7FDEC6361A4E772 +:1055B000E2B63FB9D3E5F5CD8152710F3A4174AFF0 +:1055C0009564D1F91EF0317DDFF480DA4AE7AC7DD5 +:1055D00045FC5CF3E89C5724C467D1733C4FDBB2B5 +:1055E00097A7D72442F8BCEBD5E865C49F23D89F82 +:1055F00096BDE95CCF25F50F923C181B655E3C5FBC +:10560000F3AF56298FB5240A7055A15C00922E0481 +:10561000F86B62EB916E8C28AF1BAB45B90ACAAB35 +:10562000C1BE5D3750FE4B576ADCAD1560D7A2FD99 +:1056300034B8DB7303DA2BAD608D18682F9EF2E06F +:10564000F754BA5BA7E7239E9F8958F66542C2F1DB +:105650008B7E6A92BD58AB6B3AC66126B813A3D352 +:10566000CFE90ECC79A79ABE2736FFE2F2C946D21F +:1056700027088B9CA647FAAB8E927E79C23F9EF498 +:1056800090A5572C3D4223827CB945F0519791F06B +:105690004824AF807701CE5B508E001DFB8BB83C59 +:1056A0000739CCE59CA54FEEE67ADF929F15629C08 +:1056B0005B50DE42BFEEDA27726F40B922E4AC3FA6 +:1056C00064CCC4F3B90A215F991A9370BE0353F8EE +:1056D000F72A030E795AD1CAC7E90A31A227D04363 +:1056E00007916E0E1425E89EF881D6A352FA3D5319 +:1056F0004BDF055A930CF77F5C1D9783E3845CFDB9 +:105700008EDFE0F4E9E172F59CDE13F276AB79947A +:1057100089EFC266CCC3FA7BA1CF7B2A0E915FB022 +:10572000EDD653844F2B1E1A12F1D0EEAAB7E8FD26 +:10573000F628BF07B0CB9C3E87E08F2CD728FFB45C +:10574000E6E89C32F4379A966B68D79D0C1458E7BC +:105750005FDE85684FB6AE22FBD727F6F1A1301386 +:105760007EA7467ED67D4BBF3D80FD43E0174906B0 +:1057700036EAF3B891CEF17B0A88EFE82075F6D5CA +:1057800018F41D08E73ABE17E0DFA5F5479303E3D9 +:10579000685F65BAD2E3AB61E4772E07BF0E87DDA1 +:1057A000AD86BD13E0FDEE26595FCF52FDFF578059 +:1057B000E7A34DF4F37B0A3B179FDE8271BE9D4B3E +:1057C000C577CE1CF0DFD7D8E751681E8C09501E74 +:1057D00073C6EFED57F9B3F8F7176AFA06D09E0FC4 +:1057E0005471B85E0C181CEF831C8F3D1199F8683A +:1057F000D760B517F59DD36E7C24FBDD493CAFC562 +:10580000AE6F2E542F76C8FD09EEBEEB48DE7D53F9 +:105810002679C518977712930DFC5D8D9600A7A782 +:105820002A21AF3B5C89FD9857D0F1AC8FAD375240 +:10583000745124C6EC6C9533FE7EDAA180C2F77FEA +:10584000F8BE73FB41ECFB93020F17DA7F0CB3A099 +:105850003DDD17DF34E60E94E3ADDC7FEE4BBC4557 +:10586000794745B31792DF73E4E0A5E40F14559927 +:10587000B6DFD7CC1EC16FADC8F19C371E30923C4D +:10588000DEB7BA83FCEC7D8399EFC514E4F0BCB4B9 +:105890003E9097F87D9391E6D77338FFFD5340D043 +:1058A000DD9C77E87B19697AF665A16749DF16AB5D +:1058B0002CA6A4E5394C10F873EA4FA6C63D97D63E +:1058C000109D13FEF689F38B874C99F06ED1399EAB +:1058D0001F205E611DA6A0433ADFE861710FF24D03 +:1058E000AC89E77938E19EE0972F6A7DC11CEE878D +:1058F0009C9B4FF8EB13FD1CEE9DB5F7D33D4798ED +:105900002F84F421FDE03F4ED37DA8675DF47BB684 +:10591000339E752530A675E741FE7B8BF28B5E8248 +:10592000F39F0FF3EFAB27FCDC1EFBB5CE7FAFE898 +:10593000ABEEC1EE2F407DE85985913D1907C505B5 +:10594000F47A5AD02B7B8ED7577A79F5CE83FDCB5C +:1059500070BC55CFF13CCC3B9FBFEDC62F40FDB690 +:105960000117DD19B8F3F1F5DA18A8DF1E97FAB0C0 +:10597000FE9BE98C7EEF3396A7519CEB3781C18269 +:105980000580EF0FD679987119C649070BE6031EFB +:10599000EE883F3D13FBDDF1941446B69DF1ECE338 +:1059A000AF8C06B8EEFC8644F95F5F39926DB30B9D +:1059B0004FC352A6C1FB3507F9EF46DEC67A662211 +:1059C0003EEE7CBC977EFFD0C2E707EB2A9991F6AA +:1059D000BB61777EE369FA3DC3BBBE25D1EF2BDE09 +:1059E00025F37B44FFFCBC77D1633E5CDF7AED524C +:1059F0003FAE6BB386ED6E8BB77C17539AEE881F64 +:105A0000D466C2FB3B0E1CD456A25FE666CDA87FCF +:105A1000BE72E40A9BDC39BD4F21FF604DAE87EEBC +:105A2000D7339F199A3761F83E7FB08ED9E0BAC359 +:105A30008A13A8716D6E5A7B97CEFDDFAF1C516C37 +:105A4000F3587640EC18D70BB1BFF553FCDCDABF46 +:105A500035C2EFB6F66F8D15885787266782A71B6C +:105A6000F703E0E959A753B9735D88CADDEB0CDA97 +:105A7000A7BD884728BB04DC81A9AC1EBFCF1F305F +:105A800079DA715E93598F77CBF222BC5EB0244AEB +:105A90007EC848768C55EE75455BD087ECDCD13FEF +:105AA0004B05BB67AF16BD1B235F7AC7ABB31AA00C +:105AB000FE3739918D39246FC206F29DE59F7F3DF7 +:105AC00087CBDD4DA335C2F7DEA5931F532CFF0B0B +:105AD000E37E4B573E81F604F4DF9E437C1BA6EF2A +:105AE000748DD4BF60599DAD7FC1B25556FF3DD472 +:105AF000DF73FEFE7B975D639F7FD91D56FF4708CE +:105B00007EDFF9E12F689E6A9FBF7935F5FFAA9B7A +:105B1000EFEF50AE87F2E93BBCE1848BFC6746DFD8 +:105B2000E750F32E3D44DF4F3A17671A3451CFFA4E +:105B30009ECAAD463996A2A3E9DFC475F881BBD2EF +:105B4000E928A72ECBC657B9669EAD9E3F7B8CAD8C +:105B5000FDA84899ED7DE1A2CB1D74E9D3290F96EC +:105B6000717D6A629C13E0D4C6F0EF35D58FF1D019 +:105B7000FAEE7FD14BF5FBAFE1EBBB7F8C8FF89852 +:105B80007417ECFBFD5AF4CA74FB18D62561C8EBF8 +:105B9000193D3A90539BFEDC90F17996C27FC72E57 +:105BA000CBCDF5E5E6D2C98FC5D2F0B9A518E8018D +:105BB000EA6FE768B638CFE6E295A196B479361574 +:105BC0006B8B0E55F1E7B7A01DAF47FE0EE7FBAAA2 +:105BD000367429DAAFCE79DC6575B6793C25AB68C9 +:105BE0009EA4631E77C92AC73C9E4587C47331CFE4 +:105BF00029A49391E6D95C768D7D3D2577D03CBF75 +:105C0000C6796AD3D6537287639E2CBE1E782EE661 +:105C1000F9CD79D7533ED5BE9EB1AB699E7F77CC87 +:105C2000E31EBBDA318F8FE6C1E7380F2BE27E949B +:105C3000E61E5A49FBFF032FC33890E68EFE355D02 +:105C400052F97B2FC585A19589EDFE0FF9438DD2C1 +:105C500000800000000000001F8B08000000000012 +:105C6000000BE57D09785445B670DDBEF7F69274F9 +:105C7000773AFB420837801034C40E840CE0320DB2 +:105C8000411E3A80C1155CA0C3923DE988380F4798 +:105C90009D34041111B551D4A0C034080EF840034E +:105CA000132040C006D4C119D438CF7199059B4543 +:105CB0008210930651F1CDE25FE754DDF4BD9D0EF5 +:105CC00030CBFFBF79EF8FDF4C51B7F6B3D539A793 +:105CD0004E55939C0442461172308EA62308F92635 +:105CE000C67DB5C34AC8F7F0F74342FFBC8424F32E +:105CF0003485903984FFF9170BA490905A33CBCE9A +:105D0000DE3C256B01A42D45692505F41F2B6CCEC7 +:105D10002B14423A5B8A8CB372C3FDA9E91C9F7CA9 +:105D20003298C3DA7E4FC2E378C7929C3A3A7E59E2 +:105D30009C03E7A3E64FD6D3BC899063F504D376E2 +:105D400099CC28A6DF4FD4D3090CD6CE7701B63B29 +:105D500029D17F26D17495E0F70A745DCB3F90C9B5 +:105D6000001CE6C31CBA8E3BF832E6F862093187A4 +:105D7000E7E1311117B40BED32F9D709F0D5D5C7EA +:105D8000904693C64442D4F9F627E48FFB26BD2DF6 +:105D9000D831DBC7309290BB966C7D0BAA7D2494E2 +:105DA000F49D4BD73BB579B9DC87E63BE5E074A7BA +:105DB00055D3CF54F918ACDB4CFF837EA6B9695E8E +:105DC00033FEDDE5FAFCBD440AE7B309B9CAD19F49 +:105DD000E3838FABF865C0D71D744DE91485F74296 +:105DE0003A0C8A1D88AFE90ED6569D8FE72199049B +:105DF000603E523099E4424932D673433DA5E7FCF8 +:105E0000A6CB665731C5E7F407458463E47C83FB82 +:105E1000625D863C9A367E2593FE979EFF8CF9FA4A +:105E200072E265E3A97055E9E0CEA9639E3DA1A1A8 +:105E30008F69EE1B9F3DA183D3145DFEDEBA69BA64 +:105E4000FA33E697E8CA4BBC15BAF2594BEED3E5E4 +:105E5000E7F81ED4D52F6B5CA02BAFF03FAE2BAF75 +:105E6000DAB85C97AF695AA9ABEF6959AB2B37EC3D +:105E70001B7233A1706CF8AD484C148E5F5B4F3EC3 +:105E8000754D12A49213E07EAA3E0DE9FA74BD820C +:105E9000692DD0DE28E09FE16637C5932726544A56 +:105EA000E20979C477ED9225D7D2BC91968FA6D41A +:105EB000EE1BBBC49B49C8128782742F361A4980D7 +:105EC00092AA4012BAE93A246ACA8397286F944882 +:105ED0006078CF723118FD7B97101A9441D7E1FD9D +:105EE000D44436083DF93CCC97A40F49EBBDBCC364 +:105EF00040CA9B34726783C380F349768CDDE0A08F +:105F0000F4506D64FC5EBD2D7D2CB1433E30A8CEB7 +:105F10007A91F19AE86452A11FC62F15FE3E61FEE8 +:105F200045FC0DD0F1FDE038F77A071DAF63BF38AF +:105F300015E6410207B36E1D0AE3BB36C077D242B5 +:105F40003B49A7FC5DEF7AF6C415847C523F01D330 +:105F5000DFD5173F7B4226E40FF553317FA4DE8D5A +:105F600069B0BE1CD363F575587EA27E3EE64FD65F +:105F70007B313D55BF04D3D3F53E2CEFA86FC47CD5 +:105F800067BD1F53950FA83C9A510C7C5A5C6C005E +:105F90003E9D6B21FC8FE5CFF13588F4DF6DC8D7CE +:105FA000CE34E0EB73D66F0665507A3BF70925A631 +:105FB000ECDEE1144977BDE3CF6500FC95FA29F1E9 +:105FC00024F62CB7C430FC580C6402A1F2E7F12B84 +:105FD0008C44A2E3C7BC71D53A311BBF4B403A7425 +:105FE000E3704EB145E97F20417C5D0A4F6AFD9325 +:105FF0002FFEA970662EE0A73FD249CC41B18EE1B9 +:10600000ED6527E0ED52F093387F45C25178E38F7C +:1060100059415AFFCB64159E6D5984A6B73A8A4FF1 +:10602000011D9C6B36E1BACEB5C6FA09F4E14842CF +:10603000BAE81D6E6C1E551B2D3EAD7CA8698AF713 +:10604000E9E545BA4F2B2FCE1D7AD90E7C3F374D4F +:10605000F49D180EF4E1E2F4C1E84EEDBFA629DB91 +:1060600067D5F5A3CF9FF309139A50CE2B71B70DC7 +:10607000ED7D9E73D38C38CEE98D03E260DCD3F5E1 +:10608000661F8CD351EFF0B171D37C5ABAAC9E1F0E +:10609000EB3B91189E5F6FFDFEB3E7474833396EC7 +:1060A0002608FAEF07F45EBF577C48E78DC5401F0E +:1060B000ADF237B0EFC4E4A8FB8E8479B55F4F939F +:1060C000E8355D0DDF37EBC6A3ED94932A9EFA5FAA +:1060D0000CEF1239A9AE93CAC9A15476039D52623E +:1060E000463CBB698F71B4BF2EC9BA44A0E398E2A5 +:1060F000152CF7C040949E6ACC41A35B4170B781D8 +:106100009E3573A4CAF7CA9DBFA724F7C5AF65B271 +:1061100014CAFF4C7BA7E5322F9D4D8AED848E3744 +:10612000B3B96A22C8C92F76FC88EB29BE4258F75A +:1061300097C43001F8E44BF21BFB708D5E3639DEFC +:10614000C8E6B784EDCF5EFA1FAC8FEA69BAFDBA34 +:10615000AC519F2F25B7A4003F94AE90899FCEBD30 +:1061600002F67B75DD94EFAF8F677A5C19A95B0C43 +:106170007ACA52994C057CCF7410A90F9513353B00 +:10618000571796D0FCEDF106A4ABD354BF53A81C0F +:10619000AA48607A4C6592DFE8A2E5C79B87DF7169 +:1061A0000D81F6FEC520D7BC36E2DC407AC27DD632 +:1061B00012FDFC2E35FFC8F912B210E7ABCE43ED4D +:1061C000579D87B85170F9A3E8B3B3E285B09E4CF0 +:1061D000D3FBE3F5FAEB7CC86BF4DB4722F20B232D +:1061E000F22A9DC89C4E4CF1EEF9F1C94017A1F17D +:1061F000A8A7114A1FB9E17AC670BD472E56CF0431 +:10620000F544ACB7F062F52CE1FE1E8B56AF66E7A5 +:10621000961D5E4A4F95AF3F6727549E7F21F952E6 +:106220009CF47BF58647ED00A75392D70EF8FEC28B +:106230002F4E8806AF7DDDF0725905B02390B4294A +:10624000DC5F7D6232E849DF6C901D22ADE2D968E7 +:106250000A9828FDD636574C2479983FCAF28F9D6C +:106260001521DFA2C767E5CF9F4B516C8807A66F4A +:106270009300EA1DB5EB3F1F0F72DC434248879144 +:10628000ED60FC0B09C8F725C6B89EE5749EA827EB +:106290007B389F799A9F382BDA21BDB11DF8CC133A +:1062A0004147E5DDFB4BD0584CE7F37ABC2DE9E4E0 +:1062B0005534FB03F20390072A5C889FE9150D9B78 +:1062C0005EC83B4AE7D5B1FED77621572B47183D2C +:1062D0009E6B9AF5B3DD4AEFF2A693DB45E1767E3D +:1062E0006CA7B4303D88B4B2B45A0ED841EFAC5E5E +:1062F0002B3B29A592EA2D2FBFF222D86B9F9AD073 +:106300005EABDAF2D647A369BE6AAB9C34912DC767 +:106310002AA484F1E3A1FF9B3F2C8C8FCA5FBC654C +:106320005486B2EF0F2784F152B575BF910CED0979 +:10633000C7A2A6FDC6A0350A7E9A8E8E07BDA561AE +:10634000D3B746B0BFBED82790D4EC9EEDCBD7BE16 +:1063500085FB22C009F1C9F1D58DBF1E780B4CDE3B +:106360005D80F51C202F2F85371F97D3353B6D247B +:106370009ECEA3FC7726FF44C0E76BF7DB613DEDC3 +:10638000521DA3F3D58FA6B8E8F8E5B237C5812929 +:10639000FB5EBEE601A4BF32A12EC581FCE44A37F4 +:1063A000A0ECF6A6C33AE7ACBA1DD7594ADC488739 +:1063B000E5ABC5623F4DBF96C884AD51F8A43081AE +:1063C000F149FB3A8A5CBACE76D0FB41DFFE8DE81C +:1063D000DF80F6E97D04E4FF037CCD74A7C4FCD71D +:1063E00066862F6B8241B517CD3AFA5DFF581BE0E8 +:1063F000E9745F572ACC93C2C1CBE1267C4FFB15D1 +:106400003FB82195E1892852216F47F78322F80E82 +:10641000F5DB6497254FD78ECB4F36FE3C3E3E9D35 +:10642000770CEC6FED2954BF8FB2BE99B03EDC17EC +:10643000E93EA7A1330DBF33FE5FFF38E37795FF39 +:10644000FD532640F9F90F191F413BD84FE8BC0214 +:10645000A958BEFF3601E5838904A2F1F97A99F3C0 +:10646000B9BEDC43F915FC042A9DD0F94B429C9639 +:106470005EE838098807B4574A57D0F65AFD06C671 +:10648000C57AC6F077CDBE52C6E5427E029507B109 +:1064900061794056255F961E592D132FA89CD59FD4 +:1064A0009AD01EAFDE2217C3FACF6C3EF8D15D94AE +:1064B000CECF34A97CAB97AB917C5BBE6D8300746F +:1064C0001AC9B767CAE92E1E8D6FE9F7A87C5B1E53 +:1064D000FC7F2A5755F84D4BD0CB532A1FFB810A1E +:1064E000D11B1C23E5E3D7A06F25F7948FF4EF436E +:1064F00052D8930E55FA53E98E6A70FD40AE77D3A9 +:10650000A74A7FDDF4A9D25FE47AF5F08B2CEF0F78 +:106510003612A593E25D54A3A3F8AC6E15FC26E4F5 +:1065200073EFDB7D0A104E2EDCDE88EFED3E49DA9C +:10653000BC3F22DF1451DF15912F8EA8EF8EC8D7F4 +:10654000E9EA57B71C3412C47F4057CF34FF257295 +:106550003C8A3DA8EE3F9EE6B3462FD04566C8086C +:10656000724F5E485537F0AFED15D1BFD6A584EC1C +:1065700009F4FBA31666A77539783E9EE543C9C6A4 +:10658000C520F7D4EF210B41FBBCAB38648FD7D8C3 +:10659000FF475B45BB42CB837E3241EB4708CFA729 +:1065A00001F11D24BD9533BF61578C3D0FC78BC9C9 +:1065B000F203FDDD205AB3E683BDE7139D947CC84A +:1065C000EC0577DA09A5B3AED601374FA5DFE7BCF6 +:1065D0002382BA4DD1E392D229DDCCE2747C8A7851 +:1065E0009FBF96AE6F562BD3C3672F8B4EF795BCCC +:1065F0007EA9759E11E42BD5A38F69FDA295641920 +:10660000D25DF9AA88EFAD3F42FEA88CE00F37B704 +:106610001FF6AAFC914FF251BE10C2EC5F2E976F8D +:1066200010736F9E4AF1D07548242605EC59912CC1 +:1066300086756E16FCE02F20DE64E4B35A124279B0 +:10664000A8C2A903F86870EF72AA63FB1F0B1F02B0 +:106650007AD9F1FBBC9768DAB1E3D3417B20BFF371 +:10666000E3ACDF939EF58BF67D371DF6B3AE7D264A +:10667000F48B75EDFB65D64390DF6D42BF58D74272 +:10668000930BF8C0BBCFE6BF02CAFB32FBA161EFA0 +:10669000B77941DC5F1721DE4E2530FBE55CEB9FCF +:1066A0008E084990D25581FEB02F16F9C8B3DB820F +:1066B000F67AD7DE6F0BDDD67FDE7A6A8DC48DF475 +:1066C000682353B701FDC633FFB167CFA89717D032 +:1066D000F16B9AF71B67D1F2A237FE9207F2B36B08 +:1066E0001BD38B3AE5E01AE224E4AB84B2C765F031 +:1066F000F301336510F274E2C61BBDB9D1E0C2E00C +:10670000D045E100EBA2702907B9DF1B3C62128D76 +:1067100048EFFF7AF0383B9DC9B51F10F00B85E1BB +:1067200022B8D8779BDF2CE0FAD9F77DDFE681DC51 +:1067300039D3B400F5954BAD7B48E2BF2A1DFCBDB3 +:10674000EB160297B3EE09FFB2F866F4FF5E8282A1 +:10675000F38CE4839E74BEF3C7987FCDE6C4F95EE4 +:1067600026FF97FF6FC3FB368A77FBA5F1FED8FFA4 +:1067700058BCBFC3F16E7398409EEDFD0BFA59D51E +:10678000F55F6ADDAFFC0F5DB7AAC7DF64A83B3CCD +:1067900085D63F4C022B8AE93CDFCCBCE1C329B44F +:1067A000F497BDE8271F25323BF097A07C80FD972A +:1067B00026F837A05DC1ECA622C2F6F5A29C32D421 +:1067C000378A729E40BD81487587F3293C6ECA9A0C +:1067D000E35C8AD5877DE2A6F97F4BBFCE89FEC3F5 +:1067E00008FBB1E8CA1B0F81FD7270019D1F1DE7F8 +:1067F000605FD1413527322E530E98F2303D0AE9C1 +:10680000DBF609586F9C556F3F4D04BB47630FDEA5 +:10681000A8E8CBC7F3FE2790034912ED7F825326E9 +:106820007EA8477C8BB4E7CEE323FAD946754CADFE +:106830007FED6F859F3989D999BF24730FE703FCDA +:106840003265F41F5E127E006F8457BE7F29E856C2 +:106850009213E17753460D8727B3AB25DE5EB22E48 +:106860006E03BE9508B58B995E86F6B46A175F0A0B +:10687000CE84DBDB121F5A85BB9449ED6D7DBF08CA +:1068800017151F7F2B1E54FCFDBDF8F81DE0634457 +:10689000181F99E71D12F06711B707C69D6F1331D6 +:1068A0009FE994F0FC85DB0363ACF112D803D74970 +:1068B0001F88C09765E65D95708E60760A48D7831D +:1068C0003B0C68EF980B04847B4EA384F90F0C8E6D +:1068D00011A0684FBE66E7990709F8935D46A67850 +:1068E00017337FFE9FBFFFFEDA42F0ABB0BF32FA34 +:1068F000BF49D41E9BBD8A0462E8FAE648C40B2156 +:106900000E737C0239A6F307EBF3F0777D4AB89F4C +:106910004BD5EF4D8EFCB3D39D546E1DBB82905D65 +:10692000903267BFA4B59B7FD0CAE0E5394CFCFD2F +:10693000512EB8C462CD39DBBF2731F9B1F30FDB7B +:106940008683FF6C4C576E1C93A70506A04B0FB7B0 +:106950000BCE11250EE215CEB50E88C373C443A22B +:10696000CD1DC56FB389DBD3FF518F4E65D2B59E68 +:10697000F844B09B4808FDB7DEF5E6A8E7C13393BD +:106980000C9C6E38DEE89F5808E7166CFC39B46939 +:106990009C166F1D13BF90F27AE201FE8E69CE57EE +:1069A000FE51F882FD0EF0DD64098E2F8E223FE647 +:1069B00071F84D3EF01DFA3BAF6C5D6B00FABD7295 +:1069C000BD41773E599DC4EDAE616418CC6BF201B8 +:1069D0008BAD00F07248745AE8FA3CAD678DEE2832 +:1069E000E75C91F084FEC18FFE6A123B17D8233713 +:1069F000CD02B8EEF9D24CBC14BFBB8CBEAA68F372 +:106A00004C4A61726E0E69BA3F2FFB5F0FBE63BACC +:106A1000AC81B16067AE27DCAF11497F04E9F8DCD7 +:106A200046E287FD14EC52900BE73613DCCF294881 +:106A30009E04BB9AF2FB0FB57E9AC12D5BFF03F457 +:106A400080DA56C161A0E5B552D008FE584F4BBC64 +:106A500008FB6EBE425C783E2C3986DEA6E18B5781 +:106A6000932484EFC1D17BEE8671BFEA3012D04708 +:106A70005C6F86ECB06F7FD53A1CF9A0B775FDA2AC +:106A80009E548E93A11F260F23E92177738C2E7FAE +:106A90008DE8CE00FE9A6C0ACE7346C1DFC4644610 +:106AA00067972DDFFCFF9FC9B70F55F9E6168B35A9 +:106AB0007C9494CCE85E23DF52A3C9B7B982920AD2 +:106AC000709FBB77402AE075EE3B727234F9B6A531 +:106AD0009E9DFFBD4EF911D2AE662ADFAED6C8B775 +:106AE000662ADFB27BB6FBEBE5CA37FF7F0FFF6D8F +:106AF00001F91665BDF11C7EAA7CCB6B3D8AF22D97 +:106B0000AFD940148DDFC99C7C29F92624DF06FA11 +:106B1000F021D9191B857EB670FDFB751EB707E302 +:106B2000809CFBB764765E7AB9722E3D85F1C925EB +:106B3000E5DC7F139C553937773B9573D9D1E890C5 +:106B4000C9B9B9BBA89C13801E999C9BBB9730FF09 +:106B50005B847CCBE921DF08D6AF0DB0F69E96ECC6 +:106B600017EEA1FD0D73C94E33AD3F2C2CEF4668D7 +:106B7000E5DDBF254B08E71EF2EED0E5C9BBED5CB5 +:106B8000DE5139D61FE46B247D385B6374F93DA375 +:106B9000DA37FF02F8E55D11CF173F30B073A0F789 +:106BA00046B517007DADE4F3F170FAEBACF762FF88 +:106BB000456FB2F5D56C66FEEFDA66A61FD6AE1746 +:106BC000FD0AFDE7F8D1DF1961FE157B05924AF356 +:106BD000534CBEE7AD20837F2E13762E4626E66B00 +:106BE000E861F6C82AF4E33758ECEB08E5E3D9127C +:106BF0003183BFBECA3AFE0BF0D3578D64FEFD2A27 +:106C0000FE9DF0B801350EB2B4E5BEB7FB909EF123 +:106C100003934D0C8F935F16FC6BB3217E495F5E2F +:106C20001511FFF8145FE71431887021EF8B51E3E1 +:106C3000189E8A84C7210E0FBA7E1D3CFC425478F0 +:106C4000508C4ECC4F09AFBFE2DDE062F0E757ACAD +:106C500014F0DC578547E43A55F8A8FEE92ADEDE51 +:106C6000D37A1F9EFB47AE5F855F8F75ABF08C5864 +:106C7000BF2F999F7BE593E1104F43E901E587F72B +:106C800057140E749CE23157A46AE5F1F31C0EC34D +:106C90007D638AD209C08DD401FD9436DEF7763A41 +:106CA0005DFF884F9461B04D5E33DAE48673D44D56 +:106CB0009610CA3795BEDA557AE7FDECC9A81B8B4A +:106CC000F67A8BE000FDC213B0201C3D94CE2CB4AC +:106CD000CAC195DF8CE770749890AFF8BE43E16E3F +:106CE000A0F5C7ABFB10853BF0CDF0D6B3789E5B2B +:106CF0004042785E52DB283803741DB52D0C5EAA25 +:106D0000BCA57F562D3EA2D0A3148D1E0938890B39 +:106D1000C3FB6015AF37D9E4FB08CE6126537A5F19 +:106D20004BC278CCA1FF011E23F1A4C2F352F4F9A7 +:106D300039D73FB6001CAD00AF10D3A302745FB0CB +:106D400085CB3D925707C7A2172F30FADA2B287050 +:106D50009ED00D27A0575A3EA295D12BC04D01B809 +:106D6000B79688902FA5F04DCCEEB94E38BFD4F22F +:106D70006FC5DEA3ACFFD5829344A15F75DDBDD1A5 +:106D8000EF3F4AB7ED1174FB9E25747838D0ED5E65 +:106D900081F9115AE375E78EA61476EEBEC942E971 +:106DA0001BCEBBDE919DEB949E7C7E81C313F47F52 +:106DB00045E3971A020B80B3C08D668C3FC379F40C +:106DC00067FAA556BE6EB190E4DB0A7AEFDFC8ED34 +:106DD00081DEF41B353F14C603B9D742C7CB098FF8 +:106DE0001729DF557BFF52EB4A4CF9C7D6D51DBF9B +:106DF00049DAF0FCC914EF7E2809FD3F2C3EE90E6C +:106E00001E9F4467807A96A65E5AF288DEEB913424 +:106E100033EEC3F7F3B8F81B442BF1D2757CE5923F +:106E2000914EE92EFDDB6B412E8FA5FB084DBE3A3E +:106E30003CE2E37BB05CC4F3A89BDF4DAC8173BA4A +:106E40009B4118D1EF37E70BB8FF7E009D8D023DC7 +:106E5000D64C5C264EC2B47CE40FE2D16F94BFDE08 +:106E600057A4507E1AB6D1DF00A9B32894F41EC0EF +:106E70006F8C48007E6DAEC422D8BFEEFF9CE48BC1 +:106E80000AEEB3D8CFB0432419EA8D7625A3393062 +:106E9000AA794511F847A71CB45A81CE73561988B0 +:106EA0005B43BFA389BF01FC36A34EB86E05FE2B22 +:106EB000A7FA02F89DCB5BD736D821BF4A702AB417 +:106EC0007F8FD73DDE4EE7B5A5F1ECF8AB800F69BB +:106ED0003DE8C6B38AD5F3AC179C102A5BDABA1C1E +:106EE000E3714AD70BC401F5FD0231B37EFD66DACA +:106EF000EF9655B43DCD97417BE877FDD90F6F05EF +:106F00003E3F2CB2F69BD9B975296DA700BDAEBF27 +:106F10000FFBAB58259034DA5FF96626FFCB0FCB19 +:106F20004E286FDEBF12F7B18974BCF46C90F78104 +:106F3000719027C30507FA3B33EF42BEEEE27C4D6A +:106F40003AA632B921F03CB71B54BDE9400A8B0F79 +:106F50002E752E3026D27EDE1B999C0D61029E96E8 +:106F6000B3781E7D82C2D94DE1FC018FE73838F23B +:106F7000B831A8D97F3E4B19807438BB650CC6392F +:106F8000CC21C518E7307914D3D7DEBFCEE217E89D +:106F9000BCDE974399F0FDE07526D47F3BB7C878F7 +:106FA0005EDCD93788FEE9F6553281788D86552228 +:106FB000CAC5F6CD6C1F1757DF3E3E1DE0B74170C6 +:106FC00082DC3CB8AAC808FB5ABB5FC0F645AB1FC1 +:106FD0004861760C9387AADD56EAA8D0ED1F91F29E +:106FE0004D957F351C0E9172AE46DD6722E45C0D37 +:106FF0009C37DB21D57FF7102B937FA0F703DE03AF +:10700000DF21FDD61E9609E8FDC2F18EF118B70505 +:10701000FB262D1FD52AB8E09CBFFC13931FF55506 +:107020007FC98C9F80FCFED4440405E2E029DCA9E2 +:107030005C18690AFDE159FAFD8B0FCC102143E978 +:10704000A404E1ACC68B166C60F12D051FAC482979 +:1070500005388C4B44395BD62812B7465E7C21B884 +:107060006EBD8BC963C7068D3C2A30FA4A61FF7238 +:10707000A43239A86C902166846CE7F289EAD32E99 +:10708000D01B2A762D4F31D27A8B793C48C5DEE56C +:107090002954349006D8B768FD0A23EBBF629FE0FD +:1070A00058ABE95F6DAFF6A7F663DCA5EF67C05E8E +:1070B0009EBFCC7ED479A8E3F7A68F8FFCCF0B2B95 +:1070C00004DADFC8F7450C521E797CE200ED7987BF +:1070D0009AAAFED7C20F0DC4A581DBC83FC4109782 +:1070E000862E9A4750FEA6789BD4C2F4A1E611479B +:1070F0008D35059877003FD7723F6DED38766ED5A8 +:107100009CFFC122E0EF890502D201F1BA8D8949C5 +:10711000A8072970BE5056C0DA97D1F6C077CD2B9C +:10712000191F5279A080BCA85DB57C3CD65F2F2882 +:10713000D07FF3DA12DCE7CB478A04CBD71F45BDFB +:10714000A3BCE56812F02BE5CF15B0EFD65E6B72ED +:10715000007FA87CA7F2F1FB328B0F2166C750B8E5 +:10716000075096A244E55FF1306176EA6619F9CEE0 +:107170003392F1E5FB5B44E4E783D7DD391EF8B0D9 +:107180007383D00B1F533E2D08F3A9B89AC5EB9417 +:107190006D62F6CAC1554C3EB437333DB168B53C5B +:1071A00009F265EFCA84F9BD983E78B9FCDC434F1B +:1071B000D9189D9F7BE3DFC972D347F7D3F9DDFC74 +:1071C0001A9DBF128657D1F50FDAD14F7FFD345C7F +:1071D000AF2A874A2516CF34DBB780C5FB4A2CEE91 +:1071E000ED6F9E57C43C1E4BB185E58808F41ECF59 +:1071F000E2A4D7CB48EF91FCF88FF2D13F8BAFB729 +:10720000733A52E723EE65ED21AE2C40E1F8CBCD89 +:107210002F635CEB97AF1E9D0C78AEDA43E997AE17 +:10722000B773B38D04406E497EDC6F2A9B458C1F7B +:107230002752A0F0569B963F597C52D5EB36A49B23 +:10724000CA6D2CEEB472C7F13C8C175918C2B82B1A +:10725000EFAB5CDFF406F380BE2B25162715C9EFD4 +:10726000635299FED9B12B762AAC43D8B81FCF5BB5 +:107270002B9BEE9481FEBAE547AAACD6C3734C2F84 +:10728000A55F386787F94D19AA9DDF02C453C72649 +:10729000C6FF952DB2DF02F3DBB816FDD99E8D67D0 +:1072A000313EBEE8F52DE847F0B488FAB8C88D2223 +:1072B0009E63D114CFAB22E3136B9B6BF0DCADB6B6 +:1072C00089C7FF45C4C555BDBE77879782A6EA1713 +:1072D0003FB7833C38DDB6C10EF0A4FD615CE1F53B +:1072E000E7255D7C54EFF1C02E7DBC61D3E33CDE2D +:1072F00070523BC9EB196F781AFE01FB4D6A44BC12 +:10730000E6C6441EDF1D282C8EE2CFEFBEF7B3E5A4 +:10731000EB351027DFB1EDCC1A987FF55FBF5A032C +:10732000F14D649F05F729CFABBFC5B862B5DD82CB +:1073300054466F9D9B7E8E71D99D9F9AD0DEE9DC6D +:10734000DB9E05F16D9D5BBF4B01FFDCBCBD37A033 +:10735000FF72DEF6A2541245DEAB29D0A7FF32E25F +:10736000C223F171B0F920C6617DF98909E55B7727 +:10737000FC68530D8BCB5578DCE8E6E871F86A9C25 +:10738000636DF3AD375F07F2BA99E977DD718F97D7 +:107390008A17FD90E2F5EACBC0DF661E17DC3429C0 +:1073A0006ABCE897F00F8AA79FA5EAE345BF6E9EE7 +:1073B000F3B317A1AC39B1D778D1C065C04D8DF307 +:1073C000AF4E75BD9A0A7CB42DD69BC6F0E69F28B9 +:1073D000801EF87516DC8F382587300E24B4D7E46C +:1073E00080B8C7CABD1F23BF746EFF00FDAD84C740 +:1073F000D97792EE3F160F2DF075AEB7B138530E18 +:107400007F884355ECF89DC79B323A56E3507B8BFF +:107410003F0DA6F2FBC3FCDE410DB59B589C7A38AC +:107420002E551809F83AAA8BEB55D71DD99F83CB57 +:10743000D1705C75F4385F358EB027BED8BEA2C659 +:107440004D77AEE5F1D6F47BE630889363FBB9C7A0 +:107450002F7C1C0DBF6A5CF5EF23F0ABAEAF37BEDF +:1074600050F9F352F3FE7BE1F26E2AF367ABF0E9D9 +:10747000F8737439FD0DE7776AB77E9DAAB16F671F +:1074800070BB55859B3ADFC54D4CAFE8D8C8EC873B +:1074900048FEA6EB71458BB397D298FE5BDBB23FFB +:1074A0000FE450C7815D9CEE185DD76E3ECAE27452 +:1074B000A9DCF66BE536617EE4C8FEECBC3F4F6BA1 +:1074C000F4FE3C9BCF46EDEFB4E4BA13E67FBA8DF1 +:1074D000E951A79BC409FE28FD5FE0FB52F7BA6D96 +:1074E000468C9712ED31A84FCDB38DFC242E095256 +:1074F00023C6FD342CE071428F38D300CE0DB69BED +:1075000008CCE751808FC6FF203BDC04F43839AD4E +:10751000B84054C2F355CB8D4906E2D7E25F0A6406 +:10752000827C3F92DF2E437F9F45F84D3E93C8E219 +:10753000543AAFCFBC827381D2BBDEADE6DD0F8B98 +:107540003A3F47AD297404F477F28605FDD6E23E52 +:107550008B17FD666B2CB8CE83DBBF7D05E0D5F9BC +:10756000331361E7089430A85C28E3FE8BF6EDDF67 +:10757000AEF913E899D0988E5FB686D607FD7A7378 +:107580002CDA035DDBE2F2509F7CE3A1C92037CA0D +:10759000600F033DEFF5547F03EDEF6432CB9FDCCA +:1075A000D217EF13546DB361BCE1C1ED3B6B41FEEB +:1075B00077BE1E0BC7D1E44B39F857C87BF6C49190 +:1075C000B50AEA818A76BFAD2092A2D5F3AA20AF90 +:1075D0008B7F2168A7A33F8ED273554B1CDE1FD132 +:1075E000D4E3FCECCD60F7650219C077549FD48DCD +:1075F000A396DF96D69FDFEF0DFD98BDAFC0EA7B67 +:107600008CA15296F76530BE6DC3FA252ABDF2F201 +:107610009EFDB2FA33D2FAEBEAA9ED6B4DA42E1A15 +:107620001F54A709FC7EEF5F06477BCF22CAFCF1FF +:10763000FB0302F11A400FD86AC138AE6A636010CA +:10764000C4B7EF30B2F3916A7B6010C4B7EFE1F2D8 +:10765000AF3A86E6E9F70C3E0FA80F79620EBE0638 +:10766000F8AED969214BC17E7FC3E6023CD7ECF866 +:10767000F6E44B0510CF168B7EAB9A37FE1DF15FFB +:10768000630A4C07FA0F6D359175B47EC7D677B291 +:10769000408FE8900359091739F7A96932E9CEB14B +:1076A000D5759CAEF70F84FBEBEABDC5CA5EE4C599 +:1076B000DE34A68F2E4F733D9D867C6D75A0BC86F3 +:1076C000FE44E8A76580F65E73A5125D8EAD4A9311 +:1076D00075F768C5F03DC555D0EF9724B83883A23B +:1076E000A44608E1F979E5C6B343C11EFEECA757ED +:1076F000E1B9D667C6D05090DB9F6585866AE5F113 +:10770000A97AB322C9E897C0B46BEDD9D20C02F1C3 +:107710008396A9D1E4D396B4589C47E5C3B151EF01 +:1077200083EEE6F4B61A6830998D0B7E0875DCCFCF +:107730008C7E23CC23375DC1F2CA4CBF11BE576D7E +:10774000DC3540F7EE84E4C37A94BF101E156485DF +:10775000B1C0DA53AE54CCB72A12DE8F96FEAB9B83 +:10776000DEC4309ED0C909716A1C877467423FA885 +:107770007A1F40928BCD002F2329764822A0DA87EA +:107780007C1A439A30B5527584ED437504E28A4EF3 +:10779000F1F35B93A43C0DF2C3744844797E29B89D +:1077A000FD32CD8EF3364975C4897AC74407E8D5D2 +:1077B00082D74DBEA7F4D050BF71C00976FEEF82CC +:1077C00038383B61F3B33BDEFE0EF4034A6768676B +:1077D0007BAF27FE063A9E6464793296F8A39DC774 +:1077E00077703C10EF7E943F5612FE0BD17C2C4AF2 +:1077F000283A6EDC5F47829D6B759000E84DB1566C +:107800001288A5A935573AADE55F3B61F9FE949C16 +:1078100041AE39AED59747D235714AE7BBE5A2886C +:10782000EDCF47B43F7FB1F62A3C3CE601D9ECFEF0 +:107830003B834B0C5F8377ACF34210E09167773664 +:10784000001E8DA1230F013CF2ACCC4E4C6A245A91 +:107850003B6E403A93578B04B65FD2BF62ABA63FF4 +:10786000E230A3FFF4710EF7EEFAAA5FA5477D8B15 +:107870000470ED51DFD25BFD98E8F56DBDCD273684 +:10788000FA7CE27BE9DF1BBD7EED1B1FBF1750E0DA +:1078900023931B1231A8F7A007A483BD157724A555 +:1078A0008451053B2788C05B0CD01FA58798819A1F +:1078B000EFF07FB91AFCF58F827F1240BA2BE1F30B +:1078C000A1796B3A9DDF5D7CBAE3D6B373CC7BE6DE +:1078D000313FD25D0FB3FB42477FCAEEEDDFD3C825 +:1078E000ECED7BE6B3733352CEEE0139E87F30DE48 +:1078F000BDD009C5F7BD3EC11FC886777022F4D739 +:10790000EEF7761E90A07E49843F46A527F5DED28D +:107910002CAE5F6773FA9C434236E0FBC87BF4CD24 +:10792000692C2E8D9A632E58DFDD7C7DEA3EE05D6A +:107930004E72E05D00D110E384F31191DF5B257698 +:1079400023BBB77A5B824EFE9CCB51E260BF236FB4 +:10795000F2EFFC3DA2B9372AA9DA7B5ED285587CCA +:107960007FA44176A6815C942FFC8828942F8C17E5 +:10797000061045730F8DEA77C8ECB283A01F4772DB +:10798000149332D00BE3399D25DDD4AD87BD4FE193 +:107990003277B982F760EF4C67FBCBD28CE239408B +:1079A00017A27DA4D36DED8957EF76B6BE06585F5A +:1079B00076CF7937189D4ED4436FA21A04FA7B9C78 +:1079C00066988F68523E56803F7F2D13B0FF7BC272 +:1079D00081E1F35C52821FE25F66DB971E01BA5DB4 +:1079E00056EFC073B425F539982EAD4F433D7471F1 +:1079F000BD1353152E66A7CF2552389B07B2FECC78 +:107A00000E37D333E83E04F11792A32E0079736644 +:107A10001D01FDD7D20D1F1FC2C7D89D7763DE049D +:107A2000799ACA8D1311BEB43D29033F6A867B192A +:107A3000C0C7A25C49140D5D98D286E9F23DE0A66C +:107A4000D2C71606BF2705461F91F07B526E53E042 +:107A5000FCF9C91BBBDFB541F851759FC1EF57EC6D +:107A60007CAE57F83912509F9D5DB8783AC4553FA7 +:107A7000C1CF211FAB1F89F07A1CE2BA06837DE0DB +:107A8000C25404F8513A32E57A8948DB9B143667D0 +:107A900093B5D8652860B40BF013AD0C9EA6B43A2C +:107AA0003C8F335B19BC44AB17E1225B19BC442B00 +:107AB000A33723CF4B00BFE1D81EBF53F835A78FA4 +:107AC000003C8CD6C1CB9834F6F2E0B792C28FCE90 +:107AD0002389F357241C92E09E426E98AF7AD3EB31 +:107AE0009EA3EB877DFC050A1F48937BB11F933350 +:107AF000981C4D32D4ED97011E0984EF2F5E9259E8 +:107B00004858A822FCA57989027981CD83ACD7E3B6 +:107B100055744811EFBE292F001DAC784736C03987 +:107B2000A938FF47BAFBA4E25457BC82F0740BB0EB +:107B30003F3F51AF20FE96031E07C3FEC8ECB1477E +:107B4000393E1F033E41FC32FE7892F3CBD39C4F6B +:107B50001A9CECFEC4B2092C2E2B29DFC0DF430B8C +:107B6000106DDC53BCB38918E9BC50C756300DA06A +:107B70009EF189C97F056D179B4B5C4027F19F3CA7 +:107B8000E8C7B592E274D08BE2B9FE4BAE55E2A7DE +:107B9000E145DA80C4EC102A0AD1AE6933447B0790 +:107BA000ABC179C00C7ED3DEE6B37FCA0EA4CBD2C4 +:107BB000AB313C9824BA8BA7CDA1796B632CFA0723 +:107BC000639DEEC24781CF1B6D48A7563AFF320D29 +:107BD000DE637BC1EB8B19371A32281D8AA0B451A2 +:107BE000FC3ED338C002707E4E2E4E07F9FA1CDFE1 +:107BF00067290E14ED3954079793F6822B75F6EC2E +:107C00000AD985ED1CD7EAE5C00A2E7713C6E9E943 +:107C10005D95BB1F75CB5D7732CC27E5C238E4C7D5 +:107C2000A45BA2CBDF06D9E88577051A86327EF7FA +:107C30009618D97D989EF200FDDAE7DC83D6813C68 +:107C400055E96B2161F2C74B629CB81FF177745400 +:107C5000FD7809BC37C8E52CA4E24023D24DCA3DCB +:107C6000068CCF5BC6DFCB7A8AD217A43E4A5F90E0 +:107C70005E97C1CE33169A87E1BB6D0D5603CA0BD2 +:107C8000E95393DF0AFAEAFE510EF02348B2B3CD6E +:107C900005FE409BD4B48E40BD0233BC2721C417DF +:107CA00038800EBEB1CDEE77B1383C8A4E01E8C8BF +:107CB00091544C8EE5E2E901DE7B911DB710F02B6B +:107CC000BE90546701B8E56630BBABB1A410E14883 +:107CD000E13B362339DC4FEAD49BBADFDB826E5FAF +:107CE000E8E5FECCE40CAE47677AC9400DBF370A21 +:107CF0005C0F53BC2447C3F70BAF184FE05CA927B8 +:107D0000BFF722CF363079B648882ECF54FD539531 +:107D10006772849C50D3C5FD26E8EE7719939C408A +:107D2000BB907A0D144592F7EA27EF8E4738CC02C4 +:107D30003890B49BBAEDDA1FF607BDB2302ABD45C4 +:107D4000CAB1D9DDFBBA2B05F0744A5652A7013DE2 +:107D5000BDD3DBBEEE2A453AF4F551605FDAFFCCC5 +:107D60008FD0AF73E2199B0272A8ECC2E3B83F94C4 +:107D70005E18856979E38DB89F0BCF4E2A047A6827 +:107D80005F7543DEA7E0E7F1D970DF6E6F2C1A84D0 +:107D9000E791BE5805E23BDA1B697941B81CE2C5A0 +:107DA000454DBC0001EFBBE6FE372950502F55DF93 +:107DB0003DA3769D7D34F885568B782FACF4599B86 +:107DC0000BF4CFDEE8AF7455747F00DE614AC70163 +:107DD00073408FDE6F1F1D0AD07E67AF63E7080D0B +:107DE00046D7C900E84DCF58F01CB22121FABB207C +:107DF00073326E580672604E86EB39C49395BD534C +:107E0000DA3B3FB0F14FC221339C63BDC8DF4791DD +:107E1000DCF629BA7336768E7592FB5988B997F2DB +:107E2000185EAEF4526E67F122C411BD5CB53362C8 +:107E3000C3764613ACA3A6F1CCE24F115EDCCEE0D4 +:107E4000F33E25B3799F7AC5E45F1885FE4FF1F8BC +:107E5000940A81C157E58353DDFA911BDFC389A4DE +:107E60005361DD901746D17EBF3A24E3BE514DE900 +:107E70000BE96ADD288C8F179E19F534C40D9F3FDE +:107E80002C6279E5050B96773CE27C01E29E42EF9D +:107E9000CA04E4D3F94337C4313F91DE8F7D6F1FAD +:107EA00026178E71F9507AE109A4DF6E3AF1CD31CF +:107EB00002FF955E788AD1F74601DFAD24DEEA77CE +:107EC000C70CE4F4391ADA574C5A08F0BED687E7E3 +:107ED00024651B4C4ED00722F17C2C43D1F93DCABE +:107EE00082CBB05F42F5AF24CD79FA291E675C766C +:107EF00081BD57481C5E9206FCC0E553988EF5EF95 +:107F0000D07658A2FBE9CF71FDA7F4C2353A3B23E6 +:107F1000BCBEEBF17B29DFFFCB82A3301F5ECF0B12 +:107F2000A3A2AD27BC8E6BB17E477CF4F1D3399C04 +:107F30004FD6971317956FE54656AFD4F78011E4E7 +:107F40004EE9AAF80441B3AEB2C62A5D9C47D9AA4D +:107F500012E34C4DBF613C2C7E778C14C643FA4B28 +:107F60000B262DB4825E502CF7017E5A5751F81320 +:107F700005FA63F2E90BD99705F2BABDF17E7BB43D +:107F80007B13E97D22F0D3C8F143F5EA020D7E545C +:107F9000BC44B63FB9B6ACF027E08F5EC95E21E9BC +:107FA0005DFE44E02D3B3ADC8675C32D07E38D2E44 +:107FB0000DB7AB7471453DE0C6F1ABC245FD4EF562 +:107FC000A8ABFA8C80F108BBBFD3C8F07F297885B5 +:107FD000C7E5F81F137D1D53BBD7319F7829A3CE6A +:107FE000BEE43A1E225EF345D6A1E29FBCA2C3FFC7 +:107FF000D497D6221FAAF89E7D6025D2EF6CCA8F37 +:1080000070DEDFEE7BC01E2DBE686A6F781FE8252C +:10801000B985FFF7F0FE85ECCD82B832EF720BDA4E +:1080200023A7D63D91A585F39C8C31F7025EC8FA53 +:10803000E4CBDA3FBC639D87C0BEF43E23A33F6D13 +:108040006B86BB0CDA97733B7C51FCF841D1F4830F +:1080500047EB0F0D013F5D437D1BA632D72F09E88B +:1080600097D9A82FB9A2BDEFB5A40F932B8FD6B780 +:1080700031BFA7D94B1CDAFBC484E94FFF4598BF39 +:10808000466D6794DD0EF09F1A05528C7A9FE45E70 +:10809000925D007E8FA47CAF067E8BFBB0FB48CB4D +:1080A000D20E38E03EB189F60FFE1C73A6744E7FE7 +:1080B000CEC9F2F9C2A722C437CB494D04FDA1B9FC +:1080C000F4BB06DEC6A4369D7F3A120E92D98EE727 +:1080D0004D1261FA9CBA7EFA05F7A5C7F8BEB482C4 +:1080E000FB359FAF6F42BFFFC2583BEE7F8BFB1942 +:1080F000983D6596F0BD1A533CAB6F8C63F3B68028 +:10810000DF5B847D3580791BBCE823E2D36802E421 +:10811000E38922403E910416E33B2963823F86EFC8 +:10812000CE34B71FF0F84D7ADB1101FCD8C5EEC193 +:10813000B0FF368ADE7C85D6FF9918CA877A59B493 +:10814000E8930496F6837868B7E65C8BBD13AA685B +:10815000FD8291F97EF3A588F39E3F0FD6962F4FAF +:1081600073BD0EF368B0B07786928E0B789ED360A5 +:1081700061EF0D35D8EE88837DFC577D98DE8E74D7 +:1081800000747488E933E724252E81F94995377501 +:108190007E7EB3F2A6661C89DB7BEB295D4A9A736F +:1081A000958192CB007473858F7ED7CE338A3F2E14 +:1081B000C18ACFF2463DCF51E70771FB0047F1C2BC +:1081C00078B4D722E9614FB79FD92B023EA7A9EF18 +:1081D000174B8B583E9EA87F687F7DDAAD8F2E624D +:1081E000797ECEE999C9CE311B4AE2303E4E9DC719 +:1081F000B4D6C7DA404F9DD69A3E0BCEB7A65907E4 +:108200007D0EE91E39742016F4C00704BC5772D7DE +:108210006FDF946369BAFDC375789FF9732E4FA71A +:108220009310BE0BEF260E7ECEEEC7EF338993E799 +:108230009B64B0EBEF09F86F9F4473F7BEE99F04AE +:108240006ADBF443A1B7400CB89B1CE3F10C416D11 +:10825000D7E27C9BE559BBEEF54B665C4F78BD667B +:108260005CBFBA3E3A53847F377CF87B4D2A3CC4CE +:108270009974DD945EA6C5DD7113B9885E3ECD9A12 +:10828000F3393B3461F38984CF7928A2FA63471F1D +:1082900017C9A4F8FB7D1F970069B5399425F547E8 +:1082A0003E91215F2BBAFB41E8F3977DDD8393017B +:1082B0000E6D8997253F8F5818FF1F017A8638AFBA +:1082C0000B49B82EF51DFA830FB6DB40EF5CBCFD01 +:1082D000637C67B9460C3E7927FA4345B49BCE359B +:1082E0000FBEE8FDB323E0A7A2FB5FDF4CF59E25A0 +:1082F0005BE70C89F1C98CE6588CC79F315FD4BD10 +:10830000233D633E8BE723525BDE6D3A7D7D51AFAB +:10831000FD80BF20B29F59F38BC8F1E1704EEB187E +:1083200083FE83358CBE668D738910EF3C7A89801D +:10833000E7ADA34E282D419A9FE58F77027BCE7A39 +:10834000F03F07C03B07B56DCC1F982ADE97FF08AA +:10835000F8590EB07D1CF2F7019D585D8A55735E89 +:10836000D021D7E5C37B7FDE7BAD2EE0FF92DB5CC7 +:108370009FE27BBEDC5FA1EEAB3B1B4B304EB6E415 +:108380001E6524E0BFA4C9E2C2D44CA4182AC74A7F +:1083900024628634D548240BA431C40C69E142F62A +:1083A0006E7769E314D40FEC238B8DF01E6F49EBCD +:1083B000CFBF86F6655260BF9017864F49EB3BDF13 +:1083C000015EE7B88A319EF1AA8D469D1D38B449F9 +:1083D0009FBFBA459FCF0FE8F3C30FE9F31B3209E4 +:1083E000D2D14CF3ADB900AF037B4D742F82F83F6F +:1083F00013C6BB1C13187EBC9B2C280F8BAA5A0BD0 +:10840000C10E3EF39ACD0076F49EBFFC02CFC3436B +:108410005B6209C459EDFF5D0C898178C5D72DEBEE +:10842000A0BC8AE20EFC9755AF5BD6821DBEE34A24 +:10843000D58EF7E7C17A76FC95C5D7843699FC705E +:108440003E7E66D7CF5F83F3B4339BFAA07E754C34 +:10845000F01A6260FC2F98FF33C8DF8B0BF2F7E253 +:10846000AA36EAEDE2B9994CCE04175E13174D6FA8 +:1084700052D39CB4C4DC71746E5D8F9B66801F68A0 +:1084800070A31E2E6ABD217EFDF78778FFA3893178 +:108490004CA7D91027E06FB0C3FEFB72F477921798 +:1084A00072FE79F5D5EE76227F278E289A7B53616E +:1084B000F94DE6F581F80D807FFFF0F72AA2998F3C +:1084C000463F99C0FBFFCACCE29993F8FBFDA7EBAE +:1084D0000FE1BEDFADF7D5BB5CE334F9D2C6FD29B1 +:1084E00025603FADDA9F325303AFEA4D0753EEC626 +:1084F000B827093CB8A47ADA2B4F81BFA27A93D867 +:1085000004F38472805B47D35B76A847F5E161E0B2 +:108510000709EBA337B8C669F8F86FA55B95DFAA22 +:10852000B9FEB27364DB788853AF6A149C50ADAA6D +:10853000E9F65B2701BC57B17BAE85122916297F6E +:10854000556FBDFD4743216E66F50827CC877671D0 +:108550001B7CAFDA7C16EF332C8DF8DD0335DD9D07 +:10856000C9F4425A3F60A0F597DE612D07F945FB3B +:108570007D13F20772D6E1FB2AF653ECFC817EFFF5 +:10858000C440F5965363BDEFDD4D9B9E214D1F4DBD +:1085900002BF52A39E1E297D0BA097853608CE757B +:1085A000F87561E12DA072BB1660BC2F2D9F11EDF7 +:1085B000BE75855FDF4F24DE3FE2F3A57F395AFAAF +:1085C00089AC9738D18BF1E4D5F3A93CD4F809AA4A +:1085D0004FF8F07DC9C8718896AE993E41149087D6 +:1085E0005B2CEAFB4782B990C7E90E60797C571192 +:1085F000E894124AD595649C02F0BE854C80743490 +:10860000C815784F7F64531ED4DF2D045F7909FBB2 +:10861000B3A11CEF7004F09DC90C7ECFB44361F987 +:108620002EEEE754CB2B5B2D186773E64B23CAD98C +:10863000054D07318EBEE3358BC140E5C199AD894B +:1086400063211EB3A389BD537CBA2971ACF122FB0F +:1086500076A4DC50F7D3A3F04FBAEFFE29D3F54D43 +:1086600026EC538B58BC6A6A625D7EB4DFBF50DB78 +:108670002519EBF2C18E09DD6B75AE433879B32550 +:10868000F483A739214EA84460FD1AFB158B7D6940 +:108690007D1BAD0BFEE8844322FE5EC371D1F963FE +:1086A000C7007C4F1EF5A0D9056E7C9F922C62718D +:1086B00095B324129028BDCD82FD280FF32897672B +:1086C000AD1230AE6CF632FD7AE09D5CED3E5A4163 +:1086D000FCEC7D0BAD1FB13FC4BBD0FD06DEB53455 +:1086E000B3F88BCAF5FA76552480F3A9DEFCBD29D0 +:1086F0001ABCBE26EABA5C99B02EE11633CEEBFE68 +:10870000E7E2D8798F91B8603F0D3D6743F95E4548 +:10871000DCD8DF5D7C5FF73C58E29A0D7278FE2C66 +:10872000D7EC44B86FCBF63F34F990BF05DC77AA9D +:10873000C691405FF6EE06817DB5AA55080C85BC52 +:108740009978EDC3D877787F00D6ADBD5F534E7C66 +:10875000385EF92AFD77F221C36B35BFC748D66B67 +:10876000CAFB837EC6E051BDD9A4F3EB8CDE2C7826 +:108770006D78DFD5DF9042E7577B8ACA0A0271AA7B +:10878000DF9B74FD433CCF08DCF78985E2EDB96ED1 +:10879000B9EE1F122DCEFF0887E373B797A603BF6C +:1087A0003E0D7A6B0607F448945BDC7F4002663A24 +:1087B0004ECCF0EE3C96172E64F9C9AB5F99DC788D +:1087C0002DB5F364379E0BCD128BDF86FB602FF740 +:1087D00073DFD2978E33CBE0CA92906F5D83D01F48 +:1087E0003A9FC1E185617543EAA2E8812A9E9F17FD +:1087F0009A02702EEBDDC5F42F5B4148D6EEAFD563 +:108800007D993C8A3B10C47B13A1ED02DEB35C2949 +:108810001CC5FB882B6F5408D8F769144F208F575D +:108820000A649140E152D03CE5BEB700CF05314E1D +:10883000F8B98B9AE631628D15D7CFF4B4D8BAB5B2 +:10884000709E933A236718D0395DF78C5BE8F7FB8D +:10885000FA2A385EBA95E13D6DA1371B7E072AEEF4 +:1088600040F17D6F011F0E8DC17BB2A91456B60475 +:108870004C9780FE9546160850EF393BEB3FD920C8 +:10888000CE9802F9612C9FF0B0E05A87C4B71CFB68 +:108890004F359109304FF80E7AA419FC0A58EE674B +:1088A000F82DAACB87FE5207B034C918C8847E0EB3 +:1088B00077E3DB8D76C53CBE8FCDDB3A2615ECBC6D +:1088C000C31DD4E0A672EB709AAA0F05ACF8FB505A +:1088D0000373587D6E17CECB67F70D92B2F4F5BADD +:1088E0006457DC7090A31F303DFEBCD585FEE96B5C +:1088F0008CD1FD592FF5657A8BE78240FC9A7DC0BB +:1089000033F51BD42B3D1724DDF78E7AB32ECEB969 +:10891000BAFC00DEBBAF216D18875DD314AB8BDBD7 +:10892000BD2626FAB82A7D7B2E88C41B755CA3FE63 +:10893000FB8544E24D8C562F45FF9DAE43976FF962 +:10894000B67B1DF09D8C0CDAC11E9CC8F5DA2EBFDB +:10895000C12B5F1DC64BA723A8DB773A1596EFE224 +:10896000E7716AB9DA7FE75423BF57C4DE5506F8CA +:10897000780713F262EB59F44757B7EE1FCF7EDF4B +:108980008BD185164E5E8DFC4869680B18286FFFE9 +:10899000A6EFA9A7728750123BA0F2F1E9A75C9459 +:1089A0006F5344838EAF630BBAF91CC5CB7306912A +:1089B000CB85334F8DBB569B67F5C3ED3B268FA30D +:1089C000BA7D412E6BFF87BE5FBEB77060582ED157 +:1089D000756415DB34797344DE4AF34335794744D3 +:1089E000795244795A443E93D5EFB005B2442721D9 +:1089F000ED7DCF4E9646C13976603ABC28B0ACE1E9 +:108A0000ABC9E368BEA6A00DE3676A5B05271EEB52 +:108A1000ABF1F14EA667599D41FC3DBBD882B6B77C +:108A2000410E54B7080E81D2BBB5692BC6D554434D +:108A30003B45D3AE89D99DD54D47B15DAFFDE71814 +:108A4000909F97E61CC37AEAF9D19DA4FBF73A2ED2 +:108A500080BCAC696A67FB70C4F95167BAEB20CA85 +:108A6000C388FBAF1EE8D71AA67BB5FEEF87B6FE1C +:108A700016BA899D77768144EBFFB1A67D04E84B59 +:108A8000F0C625C8FDE705FF10D89F5F24EE21B092 +:108A90001FDD5B73C57E03AD77440EAE86A71A0655 +:108AA00065596E96A89C3E620BF615A82CC9599381 +:108AB0007833C0F34872105F68F8E99A2456DE37BD +:108AC000D817CE5D73B37EC8F257045743FEB63550 +:108AD00057B2FCD0605F91B6EFEFBDEA6680FF064B +:108AE0004774BEED9BC5E4B93ABFB27C575A16E84D +:108AF0009BD56CBF80EB97662A17A7579EDEB28185 +:108B0000C261FA4F62515E6DE8B8F5A6625CBFB70C +:108B100018E2DCD813EF7C3F43B92CA11E900E7BEA +:108B20005842181FB6AC3605E5FD95755B61DF4F01 +:108B30009D9E8BF2FE7CA6AB3E6B4438FD76004BCF +:108B4000EBB3D87D8F54D180F106A90FD9500F7A9D +:108B50009A9F2751BE41FC5A393E866531F9372C20 +:108B60008BD949197D6FA887F5DCC5F5D3158FFB27 +:108B7000375928FC7F07449284FE6DD477EF5E4B13 +:108B8000E5461CC453B8D2411EDC0DFEDFDC705E2E +:108B9000D5DF57E4D3BC356CA7AD98E24AD7C60100 +:108BA000AD58CBCA5579B3229BB557F79DD406066D +:108BB0009FD4A787AC8375C44A04EF5FCC993A6809 +:108BC000DD02DCBF6FC1F912972B1DECEF1315FD11 +:108BD0000DA057AAF8792CDF3511D723B278751577 +:108BE0004FEAF8F57CDDB344BAFFD3753ED4CF8DA0 +:108BF00070A4FA401E0B2E60FA403D386293C3F019 +:108C0000255270047CFF5F04A7FB60DDFF289CA257 +:108C1000C88B9FC2B835F3A9BC3068E40587DFF381 +:108C200042404E2DD0BC5F42BF831D78675FF7A3E3 +:108C3000599A739CE90FD5A0FEA7CE2BF6DF774E8D +:108C4000B893F4E4B348FDECC8EFCCCBD00F686C1C +:108C500042B978E426E25C00F2839FCBAAFA65E190 +:108C60004FAA0E831D752E4BC4761615AF42F1D652 +:108C7000520AA7C7E9B60AF7D1BD53587C8FBA6F1D +:108C8000AEE0EFEEAE78F02A8CF3EB2241FC5D36DD +:108C9000EF4882F2AFBB7CDA202CA7F8F65A80DFCF +:108CA0002B62F0770756E413BC67B362DA9558BEBF +:108CB00047F52B4D33E3382BA6307A5A51C1E230B9 +:108CC000611F01B8F5460F290DCCBF4124579E36D0 +:108CD0001EE05D8EBFD882E0F68F41AF5C6641BD7D +:108CE00012F64E3C1FF1A5E27814AFDBB390BED96B +:108CF0003C663D9BEE5F8AE33AD13E7FCCE62A415B +:108D000079F548AC02F35F65214BCCC3C01C218BC5 +:108D100050EEF1F910DF0B18E73183EB6B9F959F55 +:108D2000B3813EF02697374030602FCF24AC7CE6ED +:108D3000C3B147C1BE99F9B088F70BC9921B5CFA61 +:108D4000F30E3AD714F08FF3BFC6900DE0E08676AD +:108D500076E8FFBF6CF09E89FB6176BF9778697BF0 +:108D60004D3CF4C7C0BFE06717D9FC497DAC12ED9C +:108D70005DD08FB97CA7F37769C753C789EC97DAC1 +:108D8000779F00BC28DC03700F2CF488C87FAF5598 +:108D90003FDF2463E8490B2D9F5E2FC62FA4F0749C +:108DA000CFB7E17AD5F9CE480D5DC77E1756DFFF04 +:108DB000C9D8DA42F087ABF60879586F8F815FA285 +:108DC0003B2F629C34DA353DBE737B36D20E24E4F1 +:108DD000AF266DBDEE7B1A8A10317F4E578A200177 +:108DE000DEDC3C7EA11BDF11F356E169E8171D9E16 +:108DF00049C6605F905BEEF9268443647B75FF7B18 +:108E0000C142BC6027360A02D263E383B1B89F1126 +:108E100033C3A3A7324601FA7CD118C23826EF6EBD +:108E2000F6FB9F5D96D00E944B03993FA1EB3D71ED +:108E30002DD4EB4C6674DDB94BE6FC44D83B12EF05 +:108E400089EBB05C60FD762E88C5F828B8FF698490 +:108E50007B99DE3FD5837F45B5E38FEF60EF29C077 +:108E6000EFF668ED60B8375B3E2C2C1FF07D18E004 +:108E7000E79658EE277257E07877C71088C3A83571 +:108E80000818D75B5B7925DE2321FC1DE76A3EB518 +:108E90005A03B5078785F9BCD6706C10D853D5E650 +:108EA00065F8BE332D7F13EC30F899DDEEDFF1C8A5 +:108EB000EE49D7B5CBCEFC05EFB537EBF15F1DA67C +:108EC00013BC1F57A9A59BEC303DA0BE0D72621CC0 +:108ED000C17BF9369E8F9DD0E6073F8D87FB2D9293 +:108EE0000FB0776B6D054D04FCA69E534CDF18DD6B +:108EF000BAF620D8BFF113DAC0E2A2F599DF2DF25D +:108F0000FED0A8D6E522D875AA9EA2B12B87DC3266 +:108F1000549BB2FBB660A7C27841F804FC21B1FDB6 +:108F2000ED79BEBFD17D10E5F11CDF60DC07619FEC +:108F30000239A6DAB920D7408EBCDC6FECD47E743F +:108F40009D79CAD85BFBB1739821A8D77B2FEFBC62 +:108F500049AD07F6EEC5FD610C6EA195714C4EC092 +:108F60000F80829FF8D7F25A7CD71B042F9DEFDC2D +:108F7000D5D92877553F4D35F7539572BF4E29F710 +:108F8000EB805F551BF70A7E4B6DBE9AF37D0DFC9F +:108F90009E14BE17600AC7BD823F671C09D8A01C7B +:108FA000FC3A7676BF4EDBDE43FC4512D2F9F7265B +:108FB000DDBB582BD87A6770BCAFB4307FCEE88762 +:108FC000D78ACC49C5D61B37CC95FD6841F87DAE14 +:108FD000CF399E54B818FB8DBD17E01E23B2F7CDD4 +:108FE000438FB2DFBB3E41F7E7ADDCDF718B15EF9E +:108FF00017BB06425C82E4C8BA25CAEFB62EDD6D07 +:10900000C177FA97F563E7C1EAF7B1FDD8FD5DF4E2 +:109010000301DC17C4A29E4DC19C077454D85FDDC8 +:109020002F491EF89F8EF2F8CEDA3BAC6EE82FC8BF +:10903000FDE22BFBB17D6B653FF6DEBF9AEFB6EB31 +:1090400038BDA8E758E08FD1FAAFFDDDF599FF44B0 +:10905000DD5F9FAF8841B914A65B03DE9F8CCD2DE9 +:1090600036821F6937972325DC5EDF0D07B4204F5A +:109070009AB8DF59724C87DF05DA7D2A17E325930A +:109080008C4CBEECBE2B8640FCDEA1D3AF3EF11E65 +:109090002D3F77CA88EFE1CDE6FED6DD0271C178BB +:1090A000DEED26F423561B99BE58BD6F28D3538C92 +:1090B000EE9510D7EDDD26A35FABDAEEDFF40A966E +:1090C000A73B2966E13E28D37377C5B2F631FEFF90 +:1090D000780DECCE7DA94E2FAD3F3FCDBD0FF09A60 +:1090E0006152E2887AAE2A84EF8B1EF333BDF81802 +:1090F000081E18A7D5C67F47CE953E87F673FCF1AC +:10910000545C0F95B7A83F1D7FCA84E766CF778F61 +:10911000CBFC9FC7E4627C2FE6D8F67C27B52C49B0 +:1091200057B13100FE6DCFD34C9F9B6550D6007C6C +:10913000C8BE58A7CE1E7DAA8CBD1F51F9F0E48B86 +:109140009D63837CD7FA773B49280BEDD1F2FE4D26 +:10915000104FDAD93AC4C98EABD2F090A4969F2FA3 +:109160009F90197C437B65A4E7CBED1FE8A2FB77BA +:10917000EE4482BFDFA63D4F8B3C87E8996778F4C9 +:10918000EC4EE57A9BBEFCD64C7708E45BED33DF12 +:109190001E99AFC078219487C4C7FCE92764D774AF +:1091A000A0DBF871015D9C9659617C35CBC4F77BDF +:1091B00012306AF9502D2F1C4BA29EDB9814A60783 +:1091C000D8F8B97364F9FF014BC990C00080000062 +:1091D000000000001F8B080000000000000BC57D90 +:1091E0000B7854D5B5F03E73CEBC92996426992481 +:1091F00093F7C93BE4014308112DEA24040C98D2EB +:1092000009A062B538BC41C943B0BDB1C5662011E3 +:1092100002A2861A1128E0848762D5367801A34617 +:10922000EF8048B1D5FBC7475BB4F7F78B4A2952AB +:109230008188964BEFB5F55F6BED7D92394322D86F +:10924000DBDB3F7CB0D967BFD65E6BEDB5D65E7B0E +:10925000ED1DB36A602C81C1CF4C334B64EC1AC650 +:109260007F324F316FD0C6984555A9FC9A5321D310 +:109270007CC867AE0C991689D40FE909230B59CA2B +:1092800021DD620FEECCC2965E86FD2C9A00FF8532 +:10929000A68B64D66629C3EF6A4FBF8BB193079C38 +:1092A0009EF5F09D7DF995CC2A189BCB443D336B00 +:1092B000B7C431F67C9B14B240BDB99BCD3BADD059 +:1092C0005FC56AAF6C87FCC076C9B313EACD6DABDE +:1092D000CCDF02F93BF7977A64681A83E3603EE8D3 +:1092E0000CCA50FF9AE649ECE3718CCD37074D0A62 +:1092F0007C674F4B6C0FA3FEDBB0FF65D02819E0F5 +:10930000F90A7FAE1F4A176F36C364F9DCBFC27F0C +:109310008261F96CE8B7BB4B66305FB617BE170EBB +:109320007D5FA6840E49318CD57747B4677F330FB4 +:10933000D643405980F0E832B13B7C369A74525D96 +:1093400029637FC0FF263366CAF48D53C76326376F +:1093500069861DE65DC5E735B04F22BCD6B326133E +:10936000C37E3AE319BB3A6C5C0B0B45437A520E51 +:1093700050F922F3464A6BD42C1AEF4ED66F62395D +:10938000D8EF80C907E3D9FB80AE2597CEBF06F999 +:1093900060FCC87C3055F0C1B2532C742D8CB76C76 +:1093A000250BD58FE6A91DD2450A0BC4005E170117 +:1093B0000E62451A55C6F1AA160EE16569509F471F +:1093C0007CAA6178463C869737F67C650ECF279954 +:1093D00018B3C60DD119084570274D6A1ADB047001 +:1093E0005EB3322833985F4ABA77522EC01B5DCEE7 +:1093F000E7DB78DC6251C760DEC7B2A1DE17699592 +:10940000CFE54179A3C2BCDD501E0D78E982EFDBC8 +:10941000AD2C80FD3F9EA752BF6E13E75FA3E263B2 +:10942000636D4897BE9001E992C01CC88F1A3EB781 +:10943000DBA15D19B693A8DD607B0B6B8B0A6B5FBC +:10944000F5A29531582F175EB007CD509529FE4CE7 +:1094500027F497F87B335B0FF9B32FDA97607F67B8 +:109460008D6C7637D477C9ACA99BF8650DE1FF8781 +:1094700048D7F1C84D55A90C795F9A96CADC58BEF9 +:109480009ABED73B81BF86A1EF607956DFCD9CAFF6 +:10949000CCEA4E18EF82B3FF079807785800F2CB5A +:1094A000550E77E3FE49637F04DF1B7D360FC7BE91 +:1094B0007F2CF2AB59BEE7660BF0D71479E5C0BD3F +:1094C000308FFA749BC30C4DAA33FFE3B7B742FE4B +:1094D00093FD4666463AEF99349B655F0A87962E60 +:1094E0000D1A3FEA0F5B2F77EDD5E7EBBBF5F94699 +:1094F000A67CD4AFF101A0608B6A779D8C26D9E160 +:10950000F90AF8DB6C6E3AD505F09A5F327B56C1EA +:10951000E706D5BF03D7538361E028E2D99CF9E978 +:10952000683FE0A52AF3CBA3A988FFFB9807E1BE1B +:1095300060AD9C4BF4D862550361F2AB51F07F678C +:10954000462D95776E35AB122FAF1D0F726B092D1F +:1095500061AA623100FE1B374FFD441A4DE516A487 +:109560004727F029B57B4E0AAE82764B362FAE6583 +:10957000507E86054D1680E70F623D35CABD532CDF +:10958000F0DFCEB89A51285F94BF2A3EA4FF5AEC70 +:10959000EAEA217CBD34B83E2D1D27002F373289E1 +:1095A000C5E2BC9DFE97709EF5967E5325F473FD33 +:1095B0005FBF20B9BCB8F9D59C13E350DE78E71241 +:1095C000BD617E284716DF7B88BE4B332C04DFC984 +:1095D000745BD00CDF5FDD62E679A789F227B74BB9 +:1095E000945FDC2D052D5958FF627C25CAEFED46AE +:1095F00087995D8AA748BCFC71DBEF621880FC4745 +:10960000102DB8BE98A329C667C7B2A69819A58819 +:10961000AF1B3E41F9B578BBEC09A19C7ED9EEC9E0 +:1096200063989F3C6AA10DDB7F1E5F89F8DB31D90F +:1096300021D377D987728829DEBEEBE1BBB2E32A5A +:1096400015D7CB91ED1CEEC54ECB1348E7EBFF2AA7 +:1096500013FF2B06E6DF67433A7847E1BA53B7EDCD +:109660009982F8FD635D8A81EA3F2B3107E2C3D915 +:109670009C88DF174B8A0FD7D992CD4B6B59CC10F2 +:10968000DED7A832E1BD32736562BF8DF8FE66D4C5 +:1096900077F5DB81CF71FC19EFFFF656D710DF4B62 +:1096A00033364FBF06FB7FD248FCA5F5D3B8EDDBC0 +:1096B000823F180B019E160B3C993357E6E3F8974F +:1096C0005B0F8B5737E53B6C975F1783EB7D1BACCC +:1096D0008F62C6FEAA4AEC2BA0034B8B233D33D2EC +:1096E0007AD4F493ADD0C0F5BE8779F7409A64661A +:1096F0005E09E457769642E5D95926C287F297E586 +:109700007BDF04F89F53FDD15990CF64DEB1A86789 +:10971000D40147552CF4664306294738CCC13D2473 +:10972000E7200F78DA94C09E581F066786E80FD6A8 +:10973000AB0BFB39FBDE9747118F0D199F8E46BD92 +:10974000DD78F10B930AF4B4F54A24676D1E1F43CC +:10975000FE68ECAD630B4A86E463A387CBEF4BE472 +:109760004C9691CB33D700F533359BCBB74E275F63 +:109770009F5B9BA38228F7B6BA8256043ABA3CC0D4 +:1097800050BE4F2F973D08B666A7F82C9C5E16EF8B +:10979000AB4C467EF5C81E14F17DDE8FDBE221FF67 +:1097A00066F9648F0C799B77577B36CEDB6314E5C3 +:1097B00039019CF71B132BC95E99EE95695CB624A1 +:1097C0002688AAA2CFFB8E6B018CFB1DE67DE404EC +:1097D000D0B1069437D2B10FC7067A9D71F8272011 +:1097E0005EB4F97CDB33F59113E1768697DB03F009 +:1097F00089EBB1F2E1F1305AADBC0EFBB9FE3A4E45 +:1098000087D3CF9A83AB61FCD356D03361FAE2B4ED +:109810009DEB1D5F9624ECC2EE0C94FB837965945E +:1098200001D7FD3D0E8E0F97A93B03D7DB9F247D0B +:109830003F77B6CB2C08726669BBC48200E2E9A709 +:109840009ECF40F9FBC99EE733E685C117D94E4B41 +:10985000BFAB8DD7F198D702E3CD63DA78A1341C82 +:109860006F9EC7FC21CA0FD63ED9DB1F663F90848E +:109870000CABCF367B497E9F83D5887CA7B53BB7A1 +:1098800024CA8B76E63966094A30D4BC5E3964C690 +:10989000FEBCDE5C17D0BB416B1FD17FA7E01FA9C8 +:1098A000470AD9A17E74C900C9DBA516DFD15428A7 +:1098B0005A8A7484FA53918E12F2ABD784F35624E9 +:1098C0002ECFCF387C7767C1BC1676E8E9989EE545 +:1098D000E0F375B8B83DD86053505F24B6326E07D8 +:1098E0007EDF10447DED8A8A19CDC08E31A5B86D1A +:1098F00028A7AECF8F6A33C4E2F78C20D64F4F290A +:10990000A476812ACEDF8144166C95B0CB2689ECF3 +:1099100040473F53E07BDA04E6580FD9DE2C6E2730 +:10992000BA9967B34C7662B78476A286074DBE2398 +:10993000DFA0DC3B2D59886FA45E89EC3ED9D03D79 +:1099400007FB1D898FB644F0D1967F321FED1A9127 +:109950008FFC2AF191DB323C1F81DCFC46F559C0BB +:10996000A700BE9204BE1E16F265E0FB16A21BFC09 +:109970004838DF5AD15FADC5169247939CF87450B2 +:109980007E433FDBC0FEC47D4A32DACF90A6B6CE1E +:1099900055B9FDDED72F417FD1575948EF3D60E8DB +:1099A000CB423B3FA9A8691FF247D29C92B256B264 +:1099B0004FD29C28F751D6E0FC1B9A27F9B81D001E +:1099C000FD221FD599683FD1706FA58FDB0135B49B +:1099D0003E1A375855D467937AB356217F34AE0474 +:1099E000FB08E56F4FD79645906F9865F3A09D6291 +:1099F000B5CC2CC176AC5DBFCED649DD641707A6C9 +:109A0000320FCAED734143C03806E56CFF8E1FA1CB +:109A10001E5F5AE209A8B8DE045FE632D20B9D4E03 +:109A20006F721CE0F5E0DF64DA17758E853CA42FB9 +:109A3000097A76D679939D909FB7C14A78EFECE288 +:109A4000E5E7EC8020E83F45E6FDB1580BD73397BA +:109A5000CA030BE23D7102D37E36633E45CB773CB1 +:109A600046768CB6DE3BB3383CF6125F165ABEB76C +:109A7000ABE3FAA260BD27CA066D531440BB3B1A84 +:109A8000C7E4792F0EF7A8010049C1EC7F6FAC9EA7 +:109A9000189EE7F587DA3F30A33A8DF4EB60398200 +:109AA0000D7A57CB7BAD00C75AFB50B902F6A4A57F +:109AB0004712ED27CC980CAAF89C24C60F281BBD92 +:109AC000808F87AD4C375E387C4A44FF46E8DFA67E +:109AD0008AFA8152DFE45C80B74C6BBFAAC30BF0FB +:109AE0003D6CD4F7472815ED31A38DF7EBDCD73764 +:109AF0006E481BD2FF600FD8B3C70FD9016BDFAF21 +:109B0000ED180363453B3E37A17ED5F479A34B2284 +:109B10003B2372BD2665F3F50A766D5236C90D6E8C +:109B2000EFD6A2BD2B939D3B059756E34A1F43FBFF +:109B300012EC86D46CB21B3E3D7908BE77CE384D10 +:109B4000767EE34585EC8F46B03FD06EB7F4727BEE +:109B500096F51849EF6A74BF53C89F4E27E87DE415 +:109B6000D397A5F1C8A78C3565DC043468C9F6E63F +:109B7000211CDA7E2C12DEEBB2B95DDE5858B52519 +:109B80001FFBDF2D31D4FBEB0B3F4A44FBA4B1F7A5 +:109B9000C3C48561ED96F63C4A7858BAD738ECFCD8 +:109BA000AFCB9669FE0D2F1CF0E27A3F1D94682D15 +:109BB0002F5182EBD0AE5CB2C480961A2B0FCEBD73 +:109BC00015D73D9B6D627930BF5CD44BB89FD83BB5 +:109BD00033700DEEDBE0AF049FB6FA16D1FADE3A31 +:109BE000DB62635908E7BCBB090F8E282FE2617D59 +:109BF0006155328ED35037C581FE9346B0B3B0BCA9 +:109C0000E1DEEF923F45836B7D8FB106EDAF0AB089 +:109C1000B7FE15E04E8F9B56E381F5982AEF1BBBEC +:109C200002F29B4690BFBFC9E1F46C937C81EFE0E8 +:109C3000BA7F41627BD4A1F2CC1E6ED7DD9CCDED04 +:109C400040EDFBCDD9DCDE9C18E89B84BCF78AD2C2 +:109C50001F8DF66F23F37E86FB4EE6B3A97B884EFD +:109C60005CEEB85A54F22B595CFD0F8CC1F2890A94 +:109C7000ED2798D2FF088E7B769DCBB39E09FEC55B +:109C8000FCBD2541DA3F64FBE7237D2B841D79F67B +:109C9000851BC6CE2B19B293D6755983AB010FEB3A +:109CA000ECEA4F6A50BEFD4521F9C62C037D939026 +:109CB0001EFF1547FDAEB306D721FD031B8D54BE15 +:109CC0002FC5DF807C79AAAE261FF7C1CC16C8AF9E +:109CD000037E32BA3A18DA0BB07D203F83C5E563C4 +:109CE0002AE42705E62A12CAF908FB6312FA796802 +:109CF000DF0083C3F72A21B6F2800B4E5A6809B4FD +:109D00007D153F648F1CFB7296821F353BC560F149 +:109D10002FC5A6D5B3A3988C7CBF66E0A801E61337 +:109D2000EDEA233BB6BE5BA271EA0B9F33A1DFE4F1 +:109D3000AE6EBE2E1BC53E00F09781F6C0DAEC6811 +:109D4000A1C7DB38BFB33EDA47B367383D19837A22 +:109D5000F6F0FDC42AAAA7F5675ACDFD5EF5C21F2D +:109D6000037290CA7F922D897DED6A9176F0548CB2 +:109D7000BB49EAF3CA88D7B192279C6FB4F4292172 +:109D80002F620F0F4CC1F53B00FC857E992D52DDF3 +:109D9000DDAFC1FCB68C2FF2A009E5067692CBF0C0 +:109DA0003BB022E0BDBCE7B329C8376070D37A6D01 +:109DB000E8A994EB6DA4B769FF9814DDD485E54953 +:109DC0007714925E8D1AC7EE9801DF7F2EF09A6CA1 +:109DD000E37E2EF7EA40D6F2121CDF77F76B387E6F +:109DE0006914F929938036F6384ADBD12FE466AB43 +:109DF00024ACF7680CEF3FC120DF5157427297F255 +:109E0000711EC9BB13D29E6C27F76799590DC28981 +:109E1000DF693F069C81FB59F473613F49393C3D42 +:109E20009B1C5250406C65FD3BF6207FF6981D88C8 +:109E3000A7DA9E5F1E477D596B61DD32DA2B117602 +:109E4000C6CAF49987903FCF9D39B9E37EF8F6E80A +:109E50004D073D7EA28BDE7E88DC2FECC42AC92311 +:109E6000DB7BBFCBD6DB7B83F97FB8BDC7EDFAC008 +:109E70009E68754F983C6F14FBB4734BCEC7A09E81 +:109E8000F97890BF404F570CD92BF376477F88EB7A +:109E90006AD0EE8FB01B8E3D111D40FA9FEFB69237 +:109EA0009F4E41BB07E039631FF80122C765F27975 +:109EB00025DC3FEC337A56437F8D779EFEB901D681 +:109EC0009DD205764F2CDAFB6A2CC9D9D765B60727 +:109ED000ED32C5EB40BF8706BFE29CE2F696A05C80 +:109EE000E4F35F660AE5931D64624B281F13CA47BB +:109EF000BBE725A1779645411EBE37BBFD7F41BA22 +:109F0000A598B9BCC276F8BD4BD85B5D801207E25C +:109F1000E538ECBBB384FEC6FDCF83E9C1F5E4C7E9 +:109F2000B1103D3F7EC5BC13FD3C1F171A4226EE03 +:109F300097203F96DAAEB064A8AF1EB70655EEEF95 +:109F4000B21840FFCF7FF8AE37705F31FF15EEC714 +:109F50009A7FE7CAE9B8FFF878C61413CA9B85CC84 +:109F60004F7EE7C58CFBA197B220F757338701C717 +:109F7000BB0BC4C656143501C0FE55F059324868B3 +:109F800057A86D9027A3D9DB5103E3CE6B33D0BE26 +:109F9000647EBBDE9F7E61FDDD35A8C7D7B619B8EC +:109FA000FDD82E911E9FCFBC6EB43B34BC16E4C4CA +:109FB00073FF689BC18BE35C9F6322FE03120569FC +:109FC0007E226D330A3FBC80631533843035483CB4 +:109FD0005DEB506A86D3CF5A7F6DC6260BFAC30657 +:109FE000D20DE407BE60F2CE263F6A5C3E433F627C +:109FF0009BBDA9BD8697D39AB9601DF051F9B50AEA +:10A0000037F8981A87F2323D87DB0F91F35DD8A1BC +:10A01000CF479E4F2C0DEAF3F399BF203907FD4639 +:10A02000FAEFE9395C5E5D589F25CE013C740ED095 +:10A030006654DFCE4279B54E2179B92A8DE3CB90B3 +:10A04000CED36C67F56CE25F27D817042F873FFBF0 +:10A050005A97847AB3CDC9F9F27F0A7724BC37E4E2 +:10A06000E413BC6D68E4C1786DEBA420C71787FBCF +:10A070004AFD174B72F4726830FF8FDF77727E5C97 +:10A08000278BF5E6203934CFC1E7F4B1E479228497 +:10A09000DF6D601F00DCF3D7C96568A74C9A69A320 +:10A0A0007934BC62257F6BFDCAFE0CB267ABFAF354 +:10A0B0009B86C12B42AB68F20BEACD73C13E01D740 +:10A0C0006DBBFE9C0A342D0B3F779A99E6BD2F2776 +:10A0D00001F7231FEFFB25D27B9F95F413FCEF9034 +:10A0E00019E5D70B596437E5A7F9EFCF41BD1E1528 +:10A0F000DAF16416DA29DC4EAAEF3577A11D38AF04 +:10A100002DECDC0BFFD9A03F0763ED71E4DF609D10 +:10A11000FAEF4BB645B4BBE45C8CEBFB4D26FF2855 +:10A12000B4EFAEBFCE9B8C72F5CC520343FACE9700 +:10A130003D8B508E9CB1EAEDEF33764EAFDD8374EC +:10A14000F6E4239D778F48674F3ED279BE81F9C3ED +:10A15000FBA9473A037D97093A9F3970553ED2F9DA +:10A16000D37D57E5239D37193BBCB86E7665FAF76A +:10A17000221E4F4CF691FD04F22AFF9BF0E38B1157 +:10A18000FCF8E2FF1E3F52BB91F4E1D19CE1F5A146 +:10A19000CBA4A6A13C9C67317FAD5EC49F61FD6BE3 +:10A1A0001633F9255EF9F2F3879E403BA457263B10 +:10A1B00044EBEF15C59F837E85578EBB3D0169E457 +:10A1C000FEEF16FB18B78505D0FFA1D9FD9AFD1843 +:10A1D000298FDF17783C9DE3FD36ED1785BF768923 +:10A1E000E8D312FC9CDBA9BB25F2C75AD46E2FDA48 +:10A1F000BD0D2FCF75A0BFF65490FB671B0E8C25AD +:10A20000FFEDD2E0ABA154B40B7B2507EE1F96EE19 +:10A21000FE3006CFBB613FFA494ED87E74B2D88F6C +:10A220009E0A7E1C83E7E230FE54D4CBD1AE0113EC +:10A23000F26F03ECD3A00A6B50068E627F0D2EE600 +:10A2400009A0A8E8D1EFDBB4F3CBAD3E13C9BBAD99 +:10A25000BD5210F76989267F561AEA2796E6A07341 +:10A260002EB15EFE33C79B983B3EFCDCD8FB971CAF +:10A270007EAE4CEDFBB7C4121FF61B9997EC802DF8 +:10A280007621971492537FDEE6A47D0FFD40FD3FBB +:10A2900007B328AFE9EB450A0B2980F745B3BCEFBC +:10A2A00021DD507E8722E477787EF03C9AF571FDBF +:10A2B00002F23C34DCF9B838A7C6F3DDF0F60D6CD9 +:10A2C00080DAE139AFAE5F6D1FC09AC6AA00F75DB4 +:10A2D000B7DB3C68BF34025F37970DF1E1323115CF +:10A2E0008D0F1B849FB771C947B41F68EC911CE8A0 +:10A2F000DF5DE6E17CB80CF649E6D197AE5BD60DA2 +:10A300007C1806F748EB785CAE7E1D0FE6FF49FE31 +:10A31000CCEB72F5EB579BBFE6171F9C67AFC4D71A +:10A3200057C4BC22F79791FE6C6D7F78A572EDA69D +:10A33000087CDCF4BF8C8F91E4DADCDC91E49AFEDB +:10A34000BCE01BCBB5C873835CEE07C773033CD777 +:10A35000FD9F9E1B7CA276241A480F7A75E7A96898 +:10A36000A7E338EDDB65B20FA6C8FC1CBADE6E268B +:10A370003F6DE4796BA33A459C2FF6FDF66AD49FB6 +:10A38000FB8D0CF5FA12DB623ACF6C949F3139D415 +:10A3900061CE19954364BF7FD3F3F775B983E7EFB7 +:10A3A0005978FEFEAAEDF3787F185DAB4AC0D02F36 +:10A3B000A1389661E5F623824FA245FC8445093019 +:10A3C0006758FB91DAFD3497DBCBAF8A381AB7892F +:10A3D000B5637CC6C3F6682FEE4BDC061EE7D3924E +:10A3E000EDDB8E72D2A2723C3FFEC22DCC00F37F19 +:10A3F000DCD84DF224506FF3A05CD4FC305AFF56E9 +:10A40000B15FBD52FE3F30C8779CFF07F3FF247950 +:10A41000F06FDA78DFF49C6C33E046B74E189D8716 +:10A42000BD81E73B5997F2F348FD8CC4D76FE7FA3B +:10A43000DECC25B9E01D4DE7FE572877A2CB073EBD +:10A44000467F0FDB6F5671DF817E0FD2971B92B96B +:10A450001E533C158867B0F72A304EEA03FCEFD54F +:10A4600023DB87A706E513B70F4F8D289FFE3EFB22 +:10A47000F04799BED3C867272ABDF9A83FD7DA01AC +:10A480007EDCF73DC5E36BB659397F6E93385FB21A +:10A49000E678CD7F42F30A3CCBCFC723F98AE5E9C2 +:10A4A000F96A30FF4F96ABB64138FE97E5EA92FF66 +:10A4B0008A413FE8C8FD04886E15557D84B78197B1 +:10A4C00025B633CC3FDDD8C7E3D4D205BCDAF70BD1 +:10A4D000C2DE5D94E7CDC078AF4FDFB358582C98FB +:10A4E00042C8636897F96C743ED0D0CDE3481A56E1 +:10A4F000323A0F6E40FF6709FA05EB18DA7FCFA9F1 +:10A50000FEC2BCF1789E610BC8B1E8379FC1D0EEA6 +:10A510003BFB1ECF37A8FE122C6F5CD9AF3B87A840 +:10A52000F8EAF335E8D70078C94FE042BF4D189DEF +:10A5300066E7F1F84B2DBD29027EF4E313FF77CBDC +:10A5400041B417A3D53E3A1768D8CF8DB80AD94B76 +:10A55000FE7B76571C433E6AD85F39F635AA6F1DDD +:10A560008BF66EC5EF6B1DE8A7F8F45A17C51F648C +:10A57000C8FD4BD1DE3A92ED9F84F8B09707A7A2B1 +:10A58000BD9A09F62ADABF9FEE9B3A16E1D6E4DFC0 +:10A5900026F47F43BF9BEC7AFF36B378B3EE47FFD8 +:10A5A000F7CE24DA3FEE4BF17F1BE7BFC9CAE10DBE +:10A5B0006CB4F2F52AFCDE91EB5F5BF749B281C621 +:10A5C00049BACD42E7D49A5CD864647E4BCE903CC5 +:10A5D0001927E2E9001F3C9EAFB78EC78188BCCD2A +:10A5E000A58F6B3C9D33791CC2332E4FA1760B2D6A +:10A5F0000312FAE1178AF3F91B449C85166775C6A6 +:10A60000E15B80F8602B6B86CEE5B3B1BD83F3BF11 +:10A61000889F89BEC8EDE86C8789F8C6DECEF8B998 +:10A6200012F00DD267E240DFA458984F6E6768229F +:10A63000E2F3958B06C28752F7069DA7C422D9A0E4 +:10A640009F9C0DFDEB0AD09FE278F75AA48BDAE1CC +:10A65000A842D43DA7FAEEC9A375DE5488FBCBAA65 +:10A66000DF1879BCE0CBD1640774662CA378C1B342 +:10A67000EF03BF665DAA0FB434C056537C6076CF3B +:10A680003BE4D7B7EF97868DFB7C38CFC6E36F02EC +:10A690007D1487C626BA081FCACBBF0FA0FDA1AC88 +:10A6A00053C893D166F41AAC48D7558CFCF0799D09 +:10A6B0000E03D22553C49D9C7BE5BF47FB69BFA217 +:10A6C000F9F1833C4EC8D8BF06F75FCAAAFEEB601B +:10A6D00005B3FAFD4E4303FA3D8D030DE437793996 +:10A6E0009AFCA3993D39ABBF05F9CC76079350FE90 +:10A6F000BC785726F27500E69937CC3C9BF38CB4B6 +:10A700005E9497A30DA8B7948D8CE214156762151B +:10A71000C1FD28E4A19FE5826FB4F34900D78DFA0B +:10A7200068519E7F37D23B5AC801D61C45FE44BBB8 +:10A73000C2FD1EF6E6F79F5D05F91DC21F7BF89569 +:10A74000E219E4BF5BA74848870BCEB9990EF8FE23 +:10A750008B3C6E8FD8953EE6B085E3FF30C56566CD +:10A76000BFCCE3D61423E713659DAB0BFD835FA439 +:10A77000F929FEF4DAB6904CE75B8E138FD4A8610A +:10A78000FB9BCD5C8F34ECE5FBEAC8FDCCE5F4C760 +:10A79000B13CBD5D3E98FF27D925EF0C8EFF77EECB +:10A7A00053987E7F17699F44EEE72EB1BF23FA1BB3 +:10A7B000C94ED1E23CAA86C6217E78D5AED94101E8 +:10A7C0005D1C4C958D8FCB2CFAFE9F12F13B5A5C91 +:10A7D0004C62ABBA0AE3CF07EE63E46FD3E276B420 +:10A7E000389D4015DF47040C20F7B2F07CA883E2C7 +:10A7F0007352594892683FD0CFB07D12C6E940FBF2 +:10A80000FEBC6C827F3BF3B4CB24175509E1B762E1 +:10A810007C473CC21DDCB208C7BBC946E35931BE08 +:10A82000239EF611B48E537C3CAE73D2121E0F9A47 +:10A8300002FA17F329B99C2FADB34D14E7A9C56DE2 +:10A8400068F11D1A5EAA04BE530A1665E17E418BAB +:10A8500003D914157CCA2A63FC8790FB4B0D24F79F +:10A86000B5F8BACE3C3588FC7E0EE3406D571EEF3E +:10A8700011895F2DEEE3FA747F72FE788AFB203D2A +:10A88000AAC56B68FC1246C78015C6DFFA32B7DF6F +:10A89000AB969808FE734BA7917FF1DC5203C3750A +:10A8A00054D56BE6FC1731DED6D92616C27E95A0AC +:10A8B00015E5A7C60797B35F81AE85E8BF3DDCB25B +:10A8C00037E704ACF9232DDD949EB34ADDF2184C32 +:10A8D00007E6A0A41AFD64C64CE56A8C6319C8900B +:10A8E0008075CAF6E6CEA27CC2C007989FF6E4AC9B +:10A8F000590AE8897379033B24A8EF2FF87026E5FD +:10A90000912753189BF0C46F660668DEDC1F35493B +:10A91000F8A3CC4EFFB5F909785FA07F4D1FF97DF4 +:10A9200078DC3FC605223DDC3613D9376E118FC95E +:10A93000AA457C269ECC40BE35792C9D67DB98BA13 +:10A94000BF0FCBD3CC5CDF33CECFAD79DC5F4C2AED +:10A950001265679AE65FEA0FA0BC6ACD7252FB41AE +:10A96000B9BADF1CE47E2E3EFE5B074AE91C4A8B27 +:10A970003365CC913EAB94E25174F987ADFC5C94A5 +:10A98000298E74B41F5A8DC24E15F9A834FF77F37F +:10A99000C3ECA4B726FF4B09AE8733077F948B72B5 +:10A9A000EA0613D8F1C3C8A5D4422E97CE196DED8F +:10A9B00012D86D6FA4FAE723BE8E47CF99E284794F +:10A9C000CD8EAF343911DEC05332CAC904416FE7AE +:10A9D0002C0E9FB3DA272D847E5BADB09EA17D82C5 +:10A9E0005FF192BDEE9F25DD0470B74AC27E676AB3 +:10A9F0002CD9ED856A2C9EFB2D6B7E87E2AE6521FE +:10AA000007642107DE6EE9CF55F240E5766F94D1F9 +:10AA1000DE7E479C3FBF93C5EEA81B66FFBB299F08 +:10AA2000DB873364B514F9C875FFC4776A812F6476 +:10AA3000932748F44BB7ABC8EF87EC15EE7EE84799 +:10AA4000CABCAF1CE3965BD3EF2BC7B81339CEE378 +:10AA5000F685E537E5733EAEC67A88B7E8A672D4C8 +:10AA600063FFB0FE62A1BF92BFBFBFC17ECC1CAE70 +:10AA70006596810C05D6A7C7EDDF8A74BB30F74316 +:10AA80003A8FFD41CA5B1F60FCC45BC68E4931280A +:10AA900087B224C1B7DC5E3B5AA0F93D79DCFBD11B +:10AAA00062EEF70439C4E32B4BF93D9BDA598CD69F +:10AAB00073AD88BB98E2E0F796A69467795A616A0D +:10AAC000D3D98082727ACA715F0CD28FCDF297FB94 +:10AAD0004A47B6C398DBA886CB95A96A581EFEDE06 +:10AAE00058A8CF7FDBA3CF7F67C25F0BC2F31BDD0C +:10AAF000DEE771DE2F493C8E33703573D03C5D52FA +:10AB000000EDA5E2E753BA847F97E20D7F26F67346 +:10AB1000CF4F60549EB8D7B213EF1F687E7259941E +:10AB200017BB9925338EF0417A764012718B2E3AFD +:10AB30000B6207EF7670FC415D13F47370AE4AEB65 +:10AB400038D16660D7E15A2FB790FDA4AD8B562B54 +:10AB5000F037E0B122D51285FCDE6AF46CC6BEE4A3 +:10AB600028B38A7AB532C6427DCB3F56482FADB264 +:10AB70009A29F4F5F0835194AF50980FE33500C44F +:10AB80005998BE65F4049B70BE500FE7DBEA64245D +:10AB9000AFE40A13E969E897E87A78A321C868FE68 +:10ABA000950AC5630A98B5750723D1F7C7C4BA9645 +:10ABB0000D2C44722CC54272EC08F48FFD1E7E5D94 +:10ABC000EE223F5BA17A3B969FB714D0FD9CC6C195 +:10ABD0007B478A01812B147694B397DF0FD3D6B3CA +:10ABE000265F22D73348C15C5722E320AAF80F4CD6 +:10ABF0002311F53E237B5E3B3F4CB768E58A17C7C0 +:10AC0000491EACCFEF67258A7C6A4116AD37A81282 +:10AC10003294A1FDF1CBBF20DF6AF261C7DA1F9346 +:10AC20007CB814FF85DFA7FC34BB83E3BF200DD7BE +:10AC3000A11C559086FAAED5E9517D61F94258467E +:10AC4000B3E3103F500FF2336B3ECC55C2FC83A9E7 +:10AC5000052A094BA8E78D07380E5BD5345CAFC3D6 +:10AC60008C5BCFC78DFEC78EEB8671A1DE613B8CFE +:10AC70000BF5765BCD2143CC70E34F5071BCCB8D8F +:10AC80000BE824A44E137806BE08A05FEAB0DD40AE +:10AC9000FC394DC4EF1E4EE0E3B1427D7C4D6E1495 +:10ACA0008C4FFE587D3CCD0DD2B636D4CB8F596338 +:10ACB00076223FFE52F0C9D1E81FE7A25DF5CB39FD +:10ACC000F94750AE4C895DD5864C328D7593BCD119 +:10ACD000E4DE85E40F2B300FF2EF9A02A0FB0FB2F7 +:10ACE000DF9A839D1F713E968BFA0FE4C3B70A1259 +:10ACF0002E855FE3470D6EE4435C07837C1801BF3C +:10AD0000C6476C7A3705206E07BB1453CD4E65AC31 +:10AD100089C789ABE943F303269E6269E2F35815BC +:10AD200020B86F703E42F168D78EF2FB10DED96317 +:10AD30003ECB50B0B27B6E01EEC300DEBAFF9FF097 +:10AD400046DAE5978B97D6E08A5CC7DAF8D28CBDF5 +:10AD5000142FDD38CB46F1D39344DC69E31203C5ED +:10AD600011C1FE8DECFE066609A21CBE46D8D15A62 +:10AD70001CFF8B12F77F060E98D53D61F6F8A57182 +:10AD8000D42AC5690756F278EB417BBB9EDBDB8397 +:10AD90007A4DDC1BE81CCB6579E7DD2AC553BC2462 +:10ADA000F1FA81B98CDBEB75A27CA143C45BC05C7A +:10ADB0001287E2D93BBB18F17FA73D9BCA5364AE13 +:10ADC0007FD8B7B8FEE9CCE2F664E7ADF9540EFBE4 +:10ADD000825188F7F932D8CFFCFC9EEF0FF2F87859 +:10ADE000917EDA4D05DC2E1BB473443ED22FBB2B73 +:10ADF000D3BF05F9656189374302BE9A6FE27E577A +:10AE0000E0BB6D7867A68635ED5672F0FE45D3BB84 +:10AE1000861CE2BBC789EF8A81EF72747C172C18FD +:10AE2000CFE52F0A538DEF06F9AD30325ECEFF1419 +:10AE30008EDBE9ECFE7D03EE2B7ACD44072DEE315F +:10AE4000729D87C173C2C8E171C932C1B36F3878CE +:10AE5000AE84FFC3F92D89713E1F691D24292C6022 +:10AE60002F1B5A071BDDFE10C23FB81ED6F07DE433 +:10AE70002570CB36E28B9B6F9539BF46737D8EE78D +:10AE80004DC9307E9D18FFE675BE6A27D6AB930884 +:10AE90000F75BDF51417C6AAF9B99107FE203CAD90 +:10AEA00042CE69E75BB345FB998E3A23FAE366D558 +:10AEB000EACF9966DBF839D6CDB38C1F85DB3DB37D +:10AEC000D986CF308E71369E4369F5818FDE2F187B +:10AED0003C872AC073A823C2CF720EF81AF9FEB5B8 +:10AEE00084C5DBEE06BE2BF8694919FAE326272E46 +:10AEF000DDBD11F24F6E2DA2FC6B89B7DDF3169606 +:10AF0000EFC8A77CB541223E3D57CFDB1756DC3A50 +:10AF10002D2B06E5BFE817D713EED7A3FC9D755080 +:10AF2000CF3D3ABB0CE34BAB85DFE0DCDD8CCA6F79 +:10AF30001C63E721BB8B55F2FB554789F2EFF17E8D +:10AF4000DF18FBBB328C33AECE1E9883FCFD46D996 +:10AF50004B45983F227D3667B873AFE24229340AE9 +:10AF6000F0521DC7EBD7963D95827E98EA2A9E2F18 +:10AF7000F654AECBC172C3F939C3DDFF8D12FB9E0F +:10AF8000C1FB6C625D3FEFFD90EEAFF92C9207A71D +:10AF9000E89BF021F91D984D72A0EBCCE7CD52D083 +:10AFA000CF3DC9CBE350AB2CAB92517E4DF79BCA42 +:10AFB000319ED861197B04E30C6227548E47BA4E48 +:10AFC000B230A22BF0794C21FAB5AFFA2C230699B6 +:10AFD000CBA6E7738D8FEA34FEAED6F331AC4F5774 +:10AFE000E1F8CBCBDB91F818C6CFC0F6B3BFA5D73D +:10AFF0003783FD45ACB7C8FE479203F8132E178779 +:10B00000E0E8A6759586D17D39B8EE3AB475370675 +:10B01000E13019FAE81E4FA6E429A20BAD133C1645 +:10B02000D24711706BF0A5836C636597C2853F8A28 +:10B03000662F72081C8E441C9797433B2F8B1B82F4 +:10B040000BC6BF1EE9C0D67078B64B4D5C6E88FD4E +:10B0500081E6CF68D0E6DBA39F6F4514BFD7EE46ED +:10B06000BF13B6738D2DFA3AB81B853E9D65F13D31 +:10B07000688639DCE49C4FFC700B683427CCFF6F8A +:10B08000A9FE3AC447AB1478B93F8BFCF114FF0119 +:10B09000F49E51186607687045E2A36104791809A7 +:10B0A00077241E86E8D3978CA9761F6E705E11F305 +:10B0B00069B5F3F53A30DECCDFB550C01485FC9BA2 +:10B0C0005211C5A16870BD2971BF6440E2F78F3489 +:10B0D0007B2212BEC87B7A1A5CE8EFE3700CACC22C +:10B0E0003B820F166A7E3E4EAF24019FC9200D7B26 +:10B0F0001EFE60A141F3B3EAE819797F4DC39B16A8 +:10B10000E715892F2D4EEB9273B78873E591EA49C5 +:10B1100060A7A7C65D8A47EDDC2E6ED04FC9FD4003 +:10B1200003F7DA490EC60DFA298F2968DF4FF21CA2 +:10B1300052D02EAFAD8109000DDE147E1F0DDF0F42 +:10B1400064F8B71492DEEE1F8FFE959F4C7D82CE81 +:10B15000AB3E30703F7D247EF68C809F91F87D243D +:10B16000F8A3D27C4FE2B867A4BE0A2CECCC16E759 +:10B1700042CC9F85EBC1E9C8AA44FF11C8D7AFBE36 +:10B18000C24D2B16015DCB33FDBFC076B730DF64F7 +:10B19000A46F5C8DDFC8CF4918F9E1978BFDE3649C +:10B1A000A177CF6FE3F11ED5DE518F4D44BBF198EF +:10B1B000910569DD7B497FDE25E03F0F2A3684F566 +:10B1C0009FB193FE5DFCFA7C8AE328D86C187A4F15 +:10B1D00003FE8E0A46E9DED328DE1BA7CB9776A7AF +:10B1E000E8EA8FE9C9D6958F0D15E9CAC71D2BD39B +:10B1F000E5C7F75DA3AB7FD5F12A5DFEEAFE69BA2C +:10B20000FADF3A354397BF76E0BBBAFA1F0FFA0F61 +:10B2100084DD10F0F615C2BC1788795F7F719EAE91 +:10B22000FD9F62A61C437E5CB081C7A55702867451 +:10B23000EF8B7470FBA209FE207D27B3018A076C97 +:10B24000084A9E10C3F836BDFDB1B4A78BF078B99B +:10B25000FBF805AEB90634B94F170AFBE32A761599 +:10B260008F67FD7ABAE6B3BCBF8BAE66B79EAE56AB +:10B27000554FD7E8423D5DED1E3D5D6327E8E9EAA5 +:10B28000F4EAE91A5FA3A76B824F4FD7A4D97ABA21 +:10B2900026FBF5744D5DA2A76B7A939EAE99CD7A8D +:10B2A000BA6505EED4958F446F4D9EE6B42FD7D581 +:10B2B0001FA4BB6F09C537E575FC50D7BF46F70023 +:10B2C000FC41BA17301187F93FA47BE1283DBD410D +:10B2D0006F8D1A359EEC8D124C671708BBDE37BC9C +:10B2E000BDA1C99F70FD1EBEAF1D492E5DA2CFC47A +:10B2F0003E77447D16B1CF7D8F81BEA5413690DF6C +:10B30000EA56C19F87A338DE3FC7A2ABA11ED499DE +:10B310000070BD8770C338EF4515933FE2BBACDBCF +:10B3200088FDDFCEFA289DC30628F53307E9EF79BB +:10B33000CC43E902E63309FFC4F45109E8B7E8AFAA +:10B3400040FD7F61EE5B1FD0B9D61BF157F40EC5EF +:10B3500047787E92C7D849210F4EE0390AE4CF5A88 +:10B3600007F5ABEA0AC3DB49E16F9C3749223DCDC3 +:10B37000E4288AEF9A778B44E744F3FE93A78B4641 +:10B38000493C1E24226D6DD6F0C7F7473B47A90400 +:10B39000471AEB16F61CF3DB72A81F7EEEB1CB4406 +:10B3A000FB58B785C3F7ACC4940971741D8EE8EAE5 +:10B3B000B670789E35320BE2F369E65791180F2884 +:10B3C00020A2F83D8C22E48F79FFF95636FAE9A2E3 +:10B3D000A25E98557D359ECB0456919FFC7B4CEF29 +:10B3E00027BFBD49223FF9F7004E48DD0E8F1BED08 +:10B3F0007C2DFFB080B71AEBC1F7247793847EA928 +:10B400007F587FFB7FC8EBFD9DFD0DF6C3385CF8D0 +:10B4100083F4D3FC9E85061E27317037DF1FEDFEB7 +:10B420001EE3FEBBE6406500CF45653094308ECA12 +:10B43000C8EFC7EF1CC5FD9EC9AC8FFC0BECA8661E +:10B44000D7FA49FE9688FB1767C5B9E2A22E0BC34F +:10B45000389D927D87E2F01C7111F0601FEA61C592 +:10B460004FEFBF946C792D8EFBFD8C4EBC57A9E934 +:10B47000FF91F9546127C3EE3100DF350D677FBCC2 +:10B480005AC4E3035A5BFA46E139A006CFFD2DC743 +:10B49000282F2B1E86E797F83E5478FCA3C905E5B4 +:10B4A00061F24EB141FB303964B4F9E89195352D24 +:10B4B0007D74BE6814EF58AD4D5BEEF087D9898777 +:10B4C0004609FBC71260B84FE02A0A53E524CAB503 +:10B4D000FF627C1F6D76433FE1F2F362020B3F1F78 +:10B4E000686F394EF0AE91FC7EECC49CCB4256A006 +:10B4F0008F59C1BBC0F07DCB0DC7308ECB645FEEE2 +:10B5000009A923E3CDEC562E84CBD3B723E4E94F2E +:10B510005A068A719CD6967E0D5F0CCF6B03C9DCF0 +:10B52000BE6E6DF984BE1BC03E447E7B754BC1214F +:10B5300015CA3F80BFF8DE8ED9C5E162175DA457FA +:10B54000E7083E405F5C3AF0CF07CD46E2B315E92D +:10B55000363A2758F166DE212FAC67134C57FE06AA +:10B56000700F8DC3F16412F214F8C987F2C194A26E +:10B57000D079419C6306D1E9EFED4FC3AFC9CAE86A +:10B580009D2453BA8DEC822B85F36FA3F83B408347 +:10B59000F6C94517C9FF15022FDABB4F1FDCC3C818 +:10B5A000DFB3E25EEE375C51CFE81E026B869F8A06 +:10B5B00021BED1F44C02BE50031F3B5A60C5411757 +:10B5C0000FB55898BF00EC108CDBCF19A2638757DA +:10B5D000716288C1C66A571DA60F4D38D181E2EF4E +:10B5E000E1895FF4618A670438BEA38905D13EA66C +:10B5F000B37F18DFB904F2307E8C288FF1F37CAC76 +:10B60000288F9DCDF3E9DEE7A46A042CE23C2BDD14 +:10B6100016373517E5F402C6EF818B7720B60B7D20 +:10B62000916A8BABABC6F2DB19DD0BD1CA7F2ACA9C +:10B63000936D1FB5E7A01E99A56FBF45E021C9F620 +:10B6400051C7243AF7D2976BE74A09B6F3C7A87DEA +:10B6500089BEFC51D1DE6E3BDF3709CB73F5E33F8A +:10B6600028CAA36D5C1E321FE3EF1588F20744B9A8 +:10B6700015CB717C0F2F97B5773944BD75020E8CB1 +:10B68000A923BFEB28EE77DDD1622921BAB45C246F +:10B69000FA3CD4C2287F6B511CC909430DC7779C63 +:10B6A0008BF383A3990DFB4EC1AD42AEC5A8FD5EE1 +:10B6B000EF30724F2B8F73F0771864B789F8C96C2D +:10B6C000137243ACC741B92135793893713FFDE519 +:10B6D000F81A16DA05B48F32E007F93AED1E03F3D3 +:10B6E00087C9CB946551CC1F56DFBD204E974FBC08 +:10B6F0003D4557DF352B5B576E2B2FD295B35971D4 +:10B70000B46E960BFE8A2A29D3956BEF43B0DDA267 +:10B710009E58BFC6DC6B74F5CE17AAB1C8E327A745 +:10B7200082FEA178068F05E5C3727B7612EA9FA799 +:10B730005B2610729E857505462B7BC6C9E3DC9F90 +:10B74000C1F34328FF598B97BEEF817215D25DB0CC +:10B75000EE54A8DFD5E2A0FCE32D6E4AB7B7A8945B +:10B76000FEB4A590CAB7B47828FF18F48FE9A3D027 +:10B770000F7E7FA4A586F21B5B7C947FB86536E5BF +:10B780001F6CF153FA40CB12FABEAEA589F26B5B87 +:10B790009A29BDBF2540696B4B3B6F57C4F5CC332D +:10B7A000E25EED3395FCBE7C241D3B8B841F52C4AE +:10B7B000ADD887E2563A8B306EA5BB9FEC702D6EEC +:10B7C00005E74DFD59F9FC23FB7BAA88DB6F45ACEF +:10B7D0006F55345FCF743E9CD7E3591D0D7C9FDAC3 +:10B7E000C4E990D53340E5C94B382D9E12FCC95CA5 +:10B7F00001965641510254EFACD45715CDCFD529FF +:10B80000CE91B9619E15E2FD2662BBA001E15226F0 +:10B8100070FDA9D17570DE4E0E27CE7F3878F70BFC +:10B8200078E5F26EFE2E4B4D4708D93ECADB44EF59 +:10B83000B25866FB420AA42E9F9FDE8928BA3805BB +:10B840003667206F2E5EC75448D396E9F76D290BF3 +:10B85000CA74FB22F9E2434C0539602BD1EFAFA249 +:10B860007297EBDA59D27EA82B37B956EBCAE7DDCF +:10B8700095B5C68DF84CE5E74BE60DAB5832C0B533 +:10B88000B07323C1F59198C75949A5FBE5817D5A4D +:10B89000BC05DF5F3C29F40BB36C207BACC0C9B3A3 +:10B8A000F9B10103EA874FFF3596E4D2138F1B826B +:10B8B000E84706F164C0F55F0C661F9697B27ECA32 +:10B8C00063A80CE6C73255C6FC383640FB2BD85F60 +:10B8D000BC5F8471ABB2FF712BE4CFA4FB9FE4711A +:10B8E0007321D29FF9829EF9DA7E6AB312E95FEE84 +:10B8F0002F22FF8DFE7E5D9BD85FB459B99F6E9558 +:10B90000B32209EDD6B323C439DADDAF1E5D00F8EA +:10B91000B6271FA274D02FA71A86BD3FFE4504FF8D +:10B920008F026617FCFF05F2FF99F2B713D10DD510 +:10B93000903B40EBE0ACE475CF45FCBE2E737E84BB +:10B940001D17CE4F11F855F655BAE7021E953773FD +:10B950003C013634CE132DC773300E41CBE78B3804 +:10B96000DDBD2DC9B9D561DFD5624EC742D657833B +:10B97000FAAAB0C4E00962C75E87CE8F61CDEDF050 +:10B98000E27B084A19F3A0981BC53A56A3EE56FE6F +:10B9900026539C9572F86AA6C27EC6660B318C4B04 +:10B9A000D3FA65C21F728F909B5F38AA63E99DCB63 +:10B9B0009441F9873A927D61F3F6211F7DD169E4C4 +:10B9C000F33AAC2F2FB471BFE1A242535095F05D12 +:10B9D000B50E7AC751D921B1B42C846312E1811D0F +:10B9E0008C263E8CDE3C9A0560BD943BFD9662F44D +:10B9F000DB85D483861CC19350AFBED8B413EDB39E +:10BA000002C48B0DF1726B6E350E9D5B48F85D289C +:10BA1000E63DBE98D3AB2D3D021EE6F1E27BA78B3F +:10BA20003A353F8E7E9E0F96577D07DF856CED93EE +:10BA3000B95A8BC0E77A63DFE8B9D0F5997E804BBD +:10BA40002638C717A30DBAB98205488FF3F9D53F39 +:10BA50002EB1AD5924976A488F8F37B0F0F3532D2C +:10BA60009D58CCE5EFB1221E876A771F257E1CCA40 +:10BA70001F39BA00F0F1B48115D2B9B181EF8FB599 +:10BA8000781D19FD0078AFA158C845D6C6A6A1DE1D +:10BA9000761A28FE54EE8AA27BB3B253A1B8F736C9 +:10BAA0005BB5E34EECC7A1D039D11479621FDAD16E +:10BAB00066A7611CDAE14776FEB00FE386E4748581 +:10BAC000A1DFABCDA1703B24CD40F1808AB3DA82F7 +:10BAD000E74AF9B6139588CF435D3FA07722E4EF9C +:10BAE0008B981DE117330A92B5B126EA3F90A688DC +:10BAF000F766BCB56313C591888AFBA19A4F70BFE6 +:10BB00007DC471DE8AFB02D5B688FC81F715F37D12 +:10BB1000A211CF0F21FFF8CAF34E945FAF77AD8922 +:10BB2000CB427B3AA8902D52F8D7D6147A0FA1CBEE +:10BB300044EF356878CD0C28BA73C8F4667DDE1CF6 +:10BB4000711E698CB827B75C8C8F2797A1B0F91844 +:10BB5000DD7CFFC65C36DAFFDC572CDEE914F97BAE +:10BB6000447EAF3190E201FC1CEE5A9489F3BAF0A6 +:10BB7000829FE2CE47B2FF2715AB62BC80D540EF73 +:10BB80000287AC1887BEBB8579D0CEB30415BA073F +:10BB9000B047C8B35C1BE7FF3B4AF87A8D4C733B58 +:10BBA000F8BA539E890A4623DD1CDD650158E7C5B6 +:10BBB000AF4E652AE8C15C87D780FEF7DC66930745 +:10BBC000EDCF29BFB0119F9CB7F1382EA5F9011513 +:10BBD000BFB7EEAC2854C3E00EB6383C289F76B60B +:10BBE000583C181B1F1C41BEE6380D143FAF1A7895 +:10BBF0003CE72EB11E7715F3F788760A39B34B0967 +:10BC0000CC403877013D316EFFD0066E1F2F5F6547 +:10BC1000213896BF9E43F6D548787BA2C5EDC9452D +:10BC200078361852D05F55B92E773DBEDFB1DCCEE5 +:10BC3000DF3796638B1EC3AB11ECD74686F67C6B61 +:10BC4000CC359EF961F25D8E9D58887C25CB8114A0 +:10BC5000F4E7F43C7DE1268CE705FA6DC57CA8F895 +:10BC6000839B307E77AF3D9082F1BDC78A3FE2E58E +:10BC70000981AD18DFDB577C9297A707520C903FE4 +:10BC80005E7C9A97E705B662BEBFF82CCFE3D91B5E +:10BC9000C8CE53C5E76F0AA0BFC5E4598202F9E7D1 +:10BCA000007F092CB16E919E1678D1CA9FC3EFB068 +:10BCB00001DB2FD2C8F283A25DCF08E52F8AF2DE26 +:10BCC00011FA7F45B40B8DD0FEB068776484F647D7 +:10BCD00045BB632394FF4A94BF3142FFFF2EDAF540 +:10BCE0008DD0FE6DD1EEDD11DAFF56B43B3E42F948 +:10BCF000FBA2FC3F22FAFF40D4EF17DFB3ED1BDEBF +:10BD000047FF7D36C811944B85F60D71B8CE77B6D6 +:10BD10009713FFB756F0732A8DDFB32546EF0EDF7A +:10BD200056C2DF3BBBAD84CB71A584F339F0E1C3D0 +:10BD3000C877CBDF94299EA8D5E039154439BADEFF +:10BD400040F6C0F2D7F97E7DF93A25187E1F486B80 +:10BD5000AFC1BF06E103C66DC314D6DB97C5FC9C1B +:10BD6000D1EC767B6AC3E499D1A1CF83BC602877FC +:10BD7000417E53DC78E1BAAAF6C2723CEB339005FF +:10BD8000A2D45B42F88E8862177AC151DE5188F0E6 +:10BD9000D9147A3F4193F3CCE6D6F935DA6C0ABD73 +:10BDA0002727DB79F9945F4C74A09DD5C6FC7D5E96 +:10BDB0006CEF56C88E3FD45EE640B967B22F70E094 +:10BDC000FAFDB894E3BDBAA1300AE5B5FCA081E460 +:10BDD000F711075FEF3BDC3CCE0AF40ADDAF0279D6 +:10BDE000ED411D51C042AB506EEE7DE8E05CEEE7E8 +:10BDF00063F6B115747F493B579794B07D406D0948 +:10BE0000C74FA6D0230AEA174877958B7B3701EEF8 +:10BE10008FCA54983B35ECFE706D89CCEF3D69E7D5 +:10BE2000A1722DBDAB95B152D19D23A4DDA3CF9BB3 +:10BE300022F48612A15772DA414EEACE4F1CBAFCA8 +:10BE4000B74A849FC7C33C68C74EF9C5069287E7C7 +:10BE500051BF4923CBBD41F92BE4F12E4400CAD197 +:10BE600000BFDF7E6843D9AF90DECBD719E83DEB4A +:10BE70002B95A30AE218F090E797482FC0845270E0 +:10BE8000DF74393CE4197D71F4DEC765F091F76821 +:10BE9000791CCADB3CBF42FD5FA2372E83AF67250A +:10BEA000CF713FD2D11925EC6A6000F4DBC545752E +:10BEB000E1F9BE49F853B438652549E1EFF58B7BCC +:10BEC000B2B2E0E3FB99578DCBC1F78A9AC8BFBFE6 +:10BED00062DF3D6EB4DBD71AFC0ECC1F8B9B368025 +:10BEE000E32C874D3FE26F2FF641EF72BE7D33FAB0 +:10BEF0004DBA8326ED5DCD10FEB30FE38FB4773BD3 +:10BF0000DD64AF897CD5CDD530DF6EC5518C266818 +:10BF100047C9E44D46B049F799D8607DBCEFF7F4C6 +:10BF20001183E8EFC64DD52097F64531DDBBA5FB63 +:10BF3000D0CF4EF9E99BF09D5218EF4619F6663BBB +:10BF40009F99B5C976F5103CBB9FFDEEA655E8B0AC +:10BF500013FB1427E3EFCD9F51FB6390B4B05F59FF +:10BF60005F82FBF5AE1389E1FB75AD7EACA8DFD037 +:10BF70003BD0F08C4AF53B4A801FEA7B06624A08B8 +:10BF8000DF0315E1F563841F20ACFEA6AFAB5FA80D +:10BF9000C1F3CCDB3797F0FADBB0FE59B53F9162C5 +:10BFA0007A22E089BFB4FF9D04FF08FD1789FA6774 +:10BFB000426F53FDB3AC3FB1348BDA3D85E39C7BDC +:10BFC000E3ED0A31EF443CC779D7E6FD197E6FC136 +:10BFD0003E707FA734A9F8BDDBD2E140FBCD6AEC0F +:10BFE000F0A11CCEC5F7C7260CA5CFA2F2187FE999 +:10BFF000F7487EEEB6B0F85AE4D76603ED6F7AFAEA +:10C000000D0F205FEE489BE8C0FDF33E535F5909DA +:10C01000DAAF076C64BF1A323FB5A2DFDC5CC0D771 +:10C02000BFD5D9E42981BC35BD84DE0F95EF5DDE37 +:10C030004DEF98DFC7DFF7527E6CF2EF46FE0A2D18 +:10C040002F5C18B6BE7797F27B96EB5EB36DC0FDA2 +:10C05000C13AA3A7A300ED70BB42719FCA8F0F4ED8 +:10C0600023FBF0E70646F21FE65905FDB6CD55E87D +:10C07000F7300C94CEEB2B217CF87C55502F2341CC +:10C0800091F07ED0FD8ACF82E71D6661D7EDF0F09A +:10C09000FB61DAB81784FD79A184BFB7B623EDC27E +:10C0A0007B8B5DF8FE8389EE75DA961942A618BC83 +:10C0B000E7B6F3D462A46774FF3ABCE71C95A238D4 +:10C0C000707E3FAD85323A97EBA6EF817A03ED1B88 +:10C0D000E29719BCE87F8CCA35E9FC1D361827DCCD +:10C0E0001F1233DAFF47A4E7B837951B11CFEEBB19 +:10C0F0000DF43EEA83EE772D068033A65CDFDE3159 +:10C1000051DF3EAE5A5FEEAAD59727CED297BB6FCE +:10C110003745F875F4F9268DAF4026D8404F45F1E4 +:10C12000221665BBD082FB9EB5AF4531A2CFCA4D6A +:10C130001D05B83EA307085F514551E417589B6C95 +:10C1400022B9BEB694FBF50FA79B6EA43CCC0BF9AD +:10C150006347DA51DA8F5C8217DBA9BF62FF3616BC +:10C16000F61DFDF2A3BD96521E57C3DC15E8C7634A +:10C17000240F9F95BC9E4388EFB7B8BF624733F743 +:10C18000633F388BC741D20C2A70BDF3FA31960D4C +:10C190007DB82F8BB1B5DF8DF19D91784D14E70DF2 +:10C1A0003BF0762FF29D9FBF1BBD46BB6785DF2B03 +:10C1B000E8D604BD8B366BB478EF4FD809B1EEF8F2 +:10C1C00092B6B0FB1A89C26FF2F0C47956D41FFB45 +:10C1D000C43B2283FDA934280F79457F54A9E6AFDB +:10C1E000E1ED3769E73C229FE0E4F97D47E26EC468 +:10C1F000F5B569565C19EEF7D70AFB2E36CDE41D6E +:10C2000005F37AE49829208D81BCC28E18C12ED8FE +:10C2100017C7C735BD1E15C07B818FB8CBE99E619E +:10C22000AD80FBB94ACF3BB8DE07601DED84FE1F31 +:10C230007179AC65E2DC3400F051A8159828876A62 +:10C24000CB68BFFB88D76345BDF9489AC78A71DAC6 +:10C25000D664C581716B716E85DE897BC4E277A07F +:10C26000FD13078AD484E749E91D53E97E1DE0DA0E +:10C2700050C18F1A98886FC4F8C27881CF1DEE051F +:10C280000E7C97C195BBFF5FD04F1F8FFDC5F07629 +:10C290008827A7C0D3AC5295E07689FEE3173C47C8 +:10C2A000F5F1A7AD22AC3F4147D35416C47D9A3671 +:10C2B000BED6CF60FFCC4BE7006B7EC5F1B62A9DA2 +:10C2C000BF8F65BA8BD17EEEB94AFF5EE4B381E4DD +:10C2D00028927729EE942AE4A394635B67E0BD8BF0 +:10C2E00035BF8AE2E32CE4FC9EA230CB7538EF0424 +:10C2F000BF03F118B95E938F74D421536A74895CBB +:10C30000BFC90A6B97E32E5DC7C96E5755FEE8613A +:10C31000D673C47A493E36F07DEC3F725D6F8FFE76 +:10C32000602CD72361DFE5CBE7DBA4FE7524879380 +:10C33000155A67E911E3E13B7B98979841C5B8E846 +:10C34000DDA54EC1C7A0974A91EF1D936CFCBC9D23 +:10C35000F8ABEAF90DDFFD35E42FE0EFF3815AA9E0 +:10C36000C73AFA482FF6F80BB0FE36C5FF38FAD3B5 +:10C37000B71D4FA2F72BCDD1FCFD5153C47B299A99 +:10C38000BED85DCAFD486AC4BB9BDF34ED4E4B2B63 +:10C390007678B0BFB77F6B49F8C7DB3F6947BA57BC +:10C3A000D9604D3F5372F326BCFF6C7D93973F0DD0 +:10C3B000F980827859467E97C31977D2FC5BDF33C8 +:10C3C000933FAB54F66CC63CFBBD95FC717B0F4CA8 +:10C3D0009C8DEBA4D55EA1A2BD7F40ACE37F156927 +:10C3E000E4BC6493C78FF640E4F7674B35FF9BE7E7 +:10C3F0007817D0B7749789DE711A8C8FE8B2F2780B +:10C400005461872E10F26CC1C1F5198718BEC35153 +:10C41000F75A29B45F60AF4E4478522F4ACC0FF2DE +:10C420006F9B389F4D753D27A19C49731DA9447989 +:10C430009FCEFA56A1DC486FD29F97A55E54A8DD27 +:10C44000BE142FF5873F18076A62624DC7F9D92AD3 +:10C4500094F329FCBCC5E488E271A1EE6ADD3D6A73 +:10C46000ED7DDBB7851C35014E8D6590DA147E6F4E +:10C470003FA2FEEF443D19FDF6E8FC771C3D4EFD62 +:10C48000DA944FC3E34D715F4A426B193FFF043C9E +:10C4900005701FCA62E3F879A9D7AB86C7DFA68209 +:10C4A000DC359761FC4980E24492C5BD082DAE079A +:10C4B00030E044BF9B16F7B193E9ED112DD5F6E7B7 +:10C4C000B9CD32ED3B8A5FB5F2FD413B0B5A25F405 +:10C4D0008731923BB91BF8F9B4E617BB0D1713EA85 +:10C4E000257C0F97C6EBA6386ACDAE02FA92DC59CE +:10C4F00017F1CE94F68EB66134E78B6D2D0EA2A3A4 +:10C50000569EE68FA4A3FE9C53AB977A3195F9E330 +:10C51000C3FB0D527FA9CDFB891F522F6650F9B680 +:10C5200016F532FD678FD07F32F1CBC8FDA751F9E8 +:10C53000F6D0BBCEE9808A9F0EEC77FA54942BA1FB +:10C54000A99E61F09C7A8F5E4E8EE9D1CB5D0D2F56 +:10C55000DB14AFAB0EF0BDED1E83A78B61FCA9BE53 +:10C560005E4DD66F9CFC5D6BAD7EC83513EB2FE343 +:10C57000F5BF754A5FDF577920B23EC177FD457D33 +:10C58000BD48FA44C20B7025DC1406D7248BFEF795 +:10C59000DACD9E7B095C09B784C175835B5FDFBF21 +:10C5A0006A78B86E2C347F2D5C5ABDEF4CB8B27AE5 +:10C5B00091F39859631E01EFBCFE2DB3AFACDFDBE6 +:10C5C000967C7DBD3B9A23C7096871DB3A7B24BE0C +:10C5D00099DBEF0E364071269ADD11C71C22FE8BC7 +:10C5E000DB0DEFE07F93197B60B46FCEE804C4BF2E +:10C5F000F7F64755BC1FC3F515ABE5EF56C2BEA411 +:10C6000034FC5DEE21B85653BF2F61BC13E9598B42 +:10C6100007EDCEE254664946E3CB1DCCC6F7C7EA28 +:10C62000476BF29AC7971709DC3D9BD2BDDC49EBFB +:10C630003C1887F07CD371EF1DEDBD67F4F8A1FACB +:10C6400023F95B343C994CDDF47B1D06EA6D1ED466 +:10C650000FEF6211B4DB75B3398476B516877A3C77 +:10C660007ACED10495DE3D588DFDCFBE65EA1ACC59 +:10C670004B87E3D5E536BC37D5AFDD2F5D83785BDF +:10C6800066F167261AE87CB500F7C3CC172F2E2376 +:10C69000FB4A878BD3D0E0A99638FEA3D2FC0FE3E8 +:10C6A00038D586BE1D3EFCA6F4F17DB62381BFBB06 +:10C6B00084EFEB0CB3FE353C54897E0E193D5F0EC2 +:10C6C000C0FC0E6D8CA57BF80BE26F99836FB22CCA +:10C6D00034F812F1003D0CEEED04B76D6E6632C217 +:10C6E0006D14705B1204DEBDB95F07F760BCCC7DD2 +:10C6F00092F67E3AE59F0F38E9BEBBD9F0F9BB331D +:10C70000510F971A3C68776E03FB02DF77FB3F02FD +:10C71000DFDBF18C258EBED3BB6F6E71EFCBBDC955 +:10C7200040EFBCF8AA5E203AED6AB07970DF3E9720 +:10C73000A9F4EEEA7C710FE60F95FFFD723FCCEF96 +:10C74000A5D1FE83388F3BE20D19EF121CFE627AF1 +:10C75000476BE295C5CF6AE7F033847DB050E07156 +:10C7600026F352DCEE4DCC6FC471DF3E6BF2A25D5E +:10C77000FAB68847BE8505E8FBAD2C48E96D2C4428 +:10C78000F5BF872FCA42FEADE8D1E9CD005FDD637A +:10C790000579B81EC3F0FE06D219F8E50E17E79723 +:10C7A0003F2621DE3B13AE887FEB248EBF0746FB7E +:10C7B0007FC3D7ABEAF2204C8E4969E847195C3F4A +:10C7C000D5099CFF1447DED7AD9FBEF3DA7D7FAF5E +:10C7D0002DB902DFFBE23F3778EFA278718CCB777F +:10C7E000011DFA547ECF11C4863D0074AAA9942974 +:10C7F0006E6FED67E27E363A31A0DE2FC7CAF43E97 +:10C8000099762E395DF4373D8DDF57ACAD9CD91646 +:10C810000B7899F2657F7908D29A34FDFDC5A9AEEF +:10C820002E7AD27C5AAEFEFB8DAC830E886B4BF415 +:10C8300071E6D323FC9F87706CE0AB8BA345BC648F +:10C84000112B0ABF6FF01DD1F67CEDE7A673307E89 +:10C85000C918FF57488FE5DFFEC31CDAD729ECCD96 +:10C860007130BF867F97C99EFCA80566528071D53E +:10C8700016E60583FF24D815983FD5E2A6F434D8F0 +:10C8800001987EDA5248E5675B3C949F35C667198C +:10C8900003FDCE6BFF4C417DB4568BC7167068719B +:10C8A000856B45FCC40AFBF2E318BFB08202DE19B7 +:10C8B0002CF68E2908FE9D3DDD473185EF32EE4393 +:10C8C000566C94C8AFB3F0887F0D9279F11BFDD3FD +:10C8D000514C8CFFCD8944DCA7D7A31D0BACBF22E4 +:10C8E000CE9B340658C0DBFBE1D178A8FFC7960980 +:10C8F00004DF272D5E82EF4F2D3594D68FF1A5539F +:10C900003DF619BDF3F4ED673E54F0F7B34DF64A2A +:10C91000E4BFBFCECB8241C0EB662397EF9B41BE05 +:10C92000E3FAAC2C9DB1FD1E86F2D75F80F3BC29E3 +:10C930006EFEE478F83E7DC25C05EBDDF225E8A0F2 +:10C94000AC213EBC1C5F9F794522FC9C79C549F80F +:10C95000D0F0542FE875E660F177F0DDB3578EC95B +:10C96000147F7AFEA281E03B7F3C8AE25323DB2FD7 +:10C970003F909384F6D89F807E78F0B1FC4031F9E7 +:10C98000E3FFF4ECBFA8E171BF7F8AEBBEF03ECAC3 +:10C99000A9FFCBE514D89B27B7A21C4B4BA1F77B73 +:10C9A00006E3D5585334EAB10693585F206730FF49 +:10C9B000A728BE0FAEF8796A15AE171C0FE3BDCCE1 +:10C9C000E2F760407F1FFC10FA3BB8D54DEFFD7CCD +:10C9D000BAEFB16C1C7F6FF7C2F7B742FF6782FCFA +:10C9E000F7609C61DD675F4479BADB467ECBB512A8 +:10C9F000C085FA744F0AE50B2525AA999C19411E9A +:10CA00008722A90ABE7FB6ECB92D29C85F784F1DD1 +:10CA1000E3EA5FDA184D72EA25A3E78366EC6F3B21 +:10CA2000EFEFC987EEFDA807D307EBCBEE4539370B +:10CA300086C7312EF8C9D2226C0FFA9A7EDFF3D363 +:10CA4000CF4B21F48394761E5A8D714C63B67D686A +:10CA5000488174EC6EA915D3E2F469C7D07F70D712 +:10CA60001895DA8F7B264BC6D8F4A294E0FBD7F357 +:10CA7000B8119D7E2FE9FCAC0AB7999A9E2F92BA05 +:10CA80004F77E1BE38E37819BFDFC5DFAF3ED03B5B +:10CA9000F39DDB18CE032C08847BAE89E22E583040 +:10CAA000D085743EE32FF4D0BB2ABEC016E4AF336A +:10CAB000FE44BA5F78D01088C1DFE314F880FFBE6F +:10CAC000A1E777BF1583F114B1FB8D0C7F2F76FDA5 +:10CAD000D88129141F92AED27E3C7DC70D35889F28 +:10CAE00086FD07BAA89F65160FFA63971CF89CEE9F +:10CAF000BDB0A93C0EF5CC7E9E7FA0DA4BEF9D2FFA +:10CB0000E9FA33CFF7F928EF930359747F623EB700 +:10CB1000771E13FA8CF58F66E1EF2169F47A008AAB +:10CB2000B17C73562019DFBDD2F420E8AF8770FDC9 +:10CB3000A1DB91DA3B66F27BF257A8BF4C421F693A +:10CB4000FD3D66E2EFF4A218C1DF8BB3CDC4F5EE74 +:10CB50001E9037C82F9ADE857177E0BA3589FB328F +:10CB6000A9A064C7C27C521F3373F97D85E347DEF9 +:10CB700067D5EC90D9F1AD746FF5D354FFCF701C2D +:10CB8000EDFE2A533CF4AEE0EF53BD4F8F49E0EF8A +:10CB900075E01C402FFE02F30D32D85139617694B6 +:10CBA000E5CAF4E2DF52BD07709C2BAD1F29872731 +:10CBB0000AF857D80D8487158F9AC91F3651DC4360 +:10CBC0009D78FE7834CA93157F2E23B9D2CAD8B087 +:10CBD000F879B985C779FF1BFA1120BDF68B7E99CC +:10CBE000F623470CCB8E827E2510C87F38D01A5B87 +:10CBF0004E792F92FBBA2F0CC3EE17B514E8F52E21 +:10CC0000C9E92FF5FE87EBBF74D0EFCD64B6B82B22 +:10CC10009AF7D0FB3EFAF96BEF6CC1FCFA51BFAF4B +:10CC2000F8CC40FCBBE2B332929BBD57385FABCB34 +:10CC30007B12E18C9C0FC0FF29D22712FE417E1F80 +:10CC4000B832F8BF2F31FA7D43A0AEC8BFDD2BDE6E +:10CC500031E85D5A42EF691CC4F748506ECEE0F7E8 +:10CC60008E7AC5FDE4DE0407BDF7F19291E703B7C4 +:10CC70008AF6E27DC8DE5B53F87B1DE6A65F97620D +:10CC8000FFAD3C3EAED718A4DF53FBFF00D94A30BE +:10CC900097008000000000001F8B080000000000CB +:10CCA000000BE57D0B78D4D5B5EFFECF2B33C9242F +:10CCB000998490072161F220040D3879F10C3040FD +:10CCC0008268D10610058C71420284BC088FF6C4BC +:10CCD000969AC100A2C51A8E886851070A14156D6C +:10CCE000A888A8C13382505A5F69B51E5B2D4D04D8 +:10CCF0009F3C1282F6620FB7BDFBB7F6DE99F90FC3 +:10CD000089DADED3EFBBE7BBF1D3EDFEEFF75A6B69 +:10CD1000AFB5F65A7BED69FFD12097D7C998D13AC4 +:10CD200037E7743E63EFF90C5E7334632D9AFF5658 +:10CD3000630163DE0B16B63B8DB12D31FEE4E53C9D +:10CD4000BF65D95554FF3DC666B6E5E0BB3B2996A5 +:10CD5000A707FF66BCBDD4CEF3B93CCFD39734361A +:10CD60009FCA67BB9362787E6178D468760DCFEFF7 +:10CD7000F0EDDE1A87EFD9D4CF10236BA47A69A225 +:10CD80009F3F9A45BB3F30FE97C4D8A366E6B5C522 +:10CD90003236DEB568B8AB9031CF8D1126168D4294 +:10CDA0007792C6E7F348D57076AFC6B3AD0F3116AC +:10CDB000CFD87C2BA33F351E2A5AC730364F7C660E +:10CDC0000B16EFB679F87CE655DBBAB4D17C1DD5ED +:10CDD00077453AF978F33C467F5814AF705389BBD6 +:10CDE000335BD4FD7B3AC675D3B8AC6A10CFF0D4B0 +:10CDF000E4AF647CDC977BACEC5E0E97BFE36F4ADC +:10CE000020E510636C30639FDAC4F8F56D531F386A +:10CE1000ADFAE3FF565BEC1BB56894A7FA181F7FC9 +:10CE2000FF104F01FA5F7EE8BA074E5B03F5AA16C2 +:10CE30009764314360DCD07142C76B01DEF878C380 +:10CE40008047DEA485171880BF369B0FF863A69E27 +:10CE50003F2CE5F996F957B9EEE5D99973AC6E8D8B +:10CE6000E3A1F740982F4CC3F77037D6D57238D26C +:10CE700067E0F9DB3501FF168DD177EF7EB36F37B1 +:10CE8000FF5667F13DB187B7AB7B79A48B8FCC0E92 +:10CE90005AF87F50FE6284288F72A7AD2F40790226 +:10CEA000E1F725B3339ACA7F6D64541EEECF8AE151 +:10CEB000F06E4AF4CC71F1790F09E3F8B7A35FF192 +:10CEC000FDA4A4BF93BC5BE0D7DB1849FD3299F702 +:10CED000FC7090EF5E5A8F3B6931F2ABAEA6F578ED +:10CEE000300F3E2FD6A0D17A4F3A7CF764F1F293FF +:10CEF000ED83691E71921E4E96FEE58DB1BCDEC9B2 +:10CF0000434617FAFCA0C9E8B744A15CE0439B6321 +:10CF1000CDDAC6DB9D7A31D215C6CBCBEEAF7D1D07 +:10CF2000DFCBEEAA9F4569CD9A1B19AFDF79D7FBFE +:10CF3000A99E9C2BF15156C75B05E1F14E97BB1E94 +:10CF4000F87DC4E569C47A97E7742E619CAECE5B28 +:10CF50003A1E6346C6DE1DEA5985EFDD2F7CB20717 +:10CF6000DF399EB24A47F16598389D807E3B471372 +:10CF70005D2F97F49B9EEBB903FD713896B30CC6F9 +:10CF800022723A2C98075B33F85BD1C9E7EDBB0FEF +:10CF90006A7C9CDAF0F6064A8DBED1E8E78CE68F13 +:10CFA000D232088E1EECBFB30E7F14F0E131F03C9C +:10CFB000C74FED5EFDBAF067E2F3AAC5FFF076B5A4 +:10CFC0006D46B70DFB87F92C987F2DB304EAA7892E +:10CFD0007D083AE0FDECA4FD6AFFA0FC871C0F353C +:10CFE0004F8CCCBB97E3A736E6D04F26523DDE4EA2 +:10CFF000ED17E39579B59E2BE723D67756EE83B3ED +:10D00000FC8B19F4B32F4CD03F13F471FE892449E3 +:10D010003F826ECF3F31C287F9C4CB7D735EF31A76 +:10D02000C2D1EE47CCB59BCF8BB9DAC6CC1E85D921 +:10D03000B78D9913C9D856C9D76A07B58D01BF52A4 +:10D04000FC8B59DB46CFE6E52CBB6DF49C5101FE11 +:10D05000C74ADBB2E8BBAF2D0BED0F1A5835E0A97C +:10D06000E653F354F20E828755ECD79AA7AE26F812 +:10D07000A8715AC047C08FC12FA2AE5CF7CB2E4D0E +:10D08000ECFFC83109E06B03E13F3B71500E58C91A +:10D09000F90596DBDDBCDF11DB2CBA7E54BD913E79 +:10D0A000FDF75FA17F4E6FC342F039C4D8F34A1831 +:10D0B0009F2FFB198713BB72BC3765BB279FECC33F +:10D0C0009F51E09331A7A21B27C149E0E90F1685C4 +:10D0D000A7D5C99C5FD70226E901781DCCF524436A +:10D0E000AE9C471EF22686E779DA20E1AFF20AEE1F +:10D0F000A1F477D71F962477F2F6FFE532D0BC4231 +:10D10000E1BA96C30FE52D66767B296FFF79F38927 +:10D110008CD3E6C07A3E6E76BBB9A8E9CB2FD99600 +:10D120006BC5BE5BBA3DD7BA2808EE2D7BF34F38EE +:10D13000395ECFEE356124D662F2FD64421CBE1B1F +:10D14000DBBC8CCAAD6E5EFFACFDC89BA8B7647B30 +:10D150004C9ED11968BF745B89BB2A08FE57EFD576 +:10D16000E363549B3E7FCD217DDE9CCB881EFED1A8 +:10D1700076B97E7D3EFF843EFFC93BAB6FC63678F5 +:10D180007E9CD8379FFA227D560ED7EAF7679C809F +:10D190001CFDF4E0F351C057ED9FAA8E2733AC433A +:10D1A0004FA71C8F9A89AFD7BB47237A59E60BDD6F +:10D1B000BF926F5CB1AFD712BEB0B382E92614BF85 +:10D1C0006758DBCD6E4E5F754D6F67408FA99EC56A +:10D1D0000919F2BB6DB385D9AF1C6F20FEC1EC6E8F +:10D1E00027E3F457314E944D689ACE4EF1FED8A6FF +:10D1F000DFCEC07EADF8B146FA46C5B3235E05DD8D +:10D2000074ED5F703DA537CF24385432B705FC70FC +:10D2100069BBE68FE479C738E7A14EDE6EB14F7384 +:10D2200061DE8BD68505F819FFB76A53C83CB60492 +:10D2300095F3F92F3DF4CA571AEFBF7ABBBEDD3222 +:10D240000E2FC88F9A5D7F0F0BFECE152182D784DB +:10D25000F61D46AC7BB19CBF927FCC3B99617D13A0 +:10D260004413761AFFE172C332CC539C5B1890834F +:10D2700013B688F69CF15560DDF5768B13EBAEB7EF +:10D28000327F049FCF89488BDBC1BF5FDC1649FA30 +:10D29000C39230E6B5E651CA6C7968E78A46BB8F1F +:10D2A000DF32929E54CF790FF5F3B8E66B413F46DB +:10D2B0004DE47F26F2CB989FD603BA7107AFD3A770 +:10D2C000CFB3D641A497D499FCAF002E35AC93E0F0 +:10D2D000CD383EDD0A8E1C6E757C9DEFC542FFD2B7 +:10D2E000B75FCEDAA8FEF2437F0F0BFECEF54C6699 +:10D2F000E5F5B787F394E6EF23381A2DCC6DE0F30C +:10D3000034DE19EEF3921E521A0E3A354B7D79CB6C +:10D310003DEE2CCC7BBDE6CE72808F6DB6B9C0C71A +:10D3200016EE1072684B0CD75FE3486FA6F60BA1A0 +:10D330004F414F5920F8DD9698363FF8FE9607D3B7 +:10D34000843EF53723C1A5E73E9B6FA7067D5AE8CB +:10D350003D5B368FA0F6E097A44FDD1729DACF1694 +:10D3600070DD32D8E1F3F2FC1F31C524E8D9EE2C90 +:10D370002BB5E37A5A5A404E297DFA67C33C7701B0 +:10D38000DF6ABD4AFF66D5DF4EDFDC2DE567CF667D +:10D390003E4FDEFF69ADF4B821481F7E2057F0FFF5 +:10D3A00031D3DC7B643D17EA551966DF3B85CFB787 +:10D3B0006AABC1D99216803B73BBB300E7D39B6DB8 +:10D3C00079A0B331D3189D274EE60A7E1E51C0DCEA +:10D3D0003E9E6E97FD6ECF35E8D2C4704E7FBC9FE7 +:10D3E000D3257E33F01B59506A813CE4329CF87996 +:10D3F000E83AF6E60AB9596529FDCDA47EE6D34799 +:10D4000007C5426F39BD42DB29E625F03CE6DF6DFA +:10D41000AE165AB7989F823BA79B4292F7926FC570 +:10D42000F4D189EF091B47ED66A54F03FF9A8E4E95 +:10D43000089E5BEE1B45785C28F1CCEEB3493A615F +:10D44000ECAF282F7152F9379DB7D43A391D5039B6 +:10D45000C7B71FF80E3D6F297C3393AFB0347260AD +:10D460007C2F1A173346E3A04E36316F18870B64B2 +:10D470001EC1E51E93EF2E3E9FA12601FF1493A02F +:10D480002FCE9DBDE17954DF6DE1F98A07963237E1 +:10D49000AF5F91CC5C9AA8CFA2519F7763E42964D7 +:10D4A00006DA55448B7E2B1298EF2EA9F7835F6521 +:10D4B000224DA77EDD8658D13E2A8FDA7B0DA2BD94 +:10D4C000DBC4D3611962BFF4AC0FA3FD5371774A7B +:10D4D00016E860D6343D1DE4E709BA51E9E3794E18 +:10D4E00029675C89D8DF8BD68D24B9D1622BAD7FBB +:10D4F0000EF87A3A82F4C18A0DB7DD5088F93D33CF +:10D50000081A0EFBFCC6FD63406F8BD62DF8DEEFCC +:10D51000711ED96BA3EFED799EF3B9D0B73567F9DA +:10D5200073FCC3A279472D89BCBDA76DF6B91779E5 +:10D530007AA377FF9BD00B6EBCC948F56F646D7FF3 +:10D54000F923F8C23A31CE0DDE0BA644DEDF0D45DD +:10D550001A437997CD91BA82CFBF42E2EFAF721FE3 +:10D56000B4D8D8FC5FDA31AF94AC74FEFD0668AA7B +:10D57000FDE881E3F2A49E3855DB0EBD67D874B197 +:10D58000BF547DF4837E27031EBC9E59C245E539F6 +:10D590005CA97ED5C6B0AE8C28A466FF089E2E2E50 +:10D5A0009866CBE3F566A5B3193837F5DC61643BC3 +:10D5B00069BE3D15B4EF23B39CD8F71EC6FCC4F773 +:10D5C0007C2389EEBBA6F674DDCDF35D3B46B85AED +:10D5D00088AF8BF3FB620723F9DE3555F035C55F65 +:10D5E0004E3A3A23895EE579BE5292C6474DD3B78B +:10D5F0008EE5F52BED962EC883C50FCE8D72F27990 +:10D60000566EE1E7792EC7D826FD799E9FB733F293 +:10D61000065F792E0F3D7F83664047559B34A2C33A +:10D62000612D2E4B12F131CD81F555D9FD99907FA9 +:10D63000552E9B0BE5679BDD0F9CE6FAE1F9E69919 +:10D6400094B2CB1CEE7C9E5701797CDF8FCDF7B86E +:10D6500000A78AD60A3A4F46E478883F2D97743758 +:10D660008B835903BF317526611F76E5CAEFB18EF2 +:10D670002C3BD1B38D010E5D664716E6D5B5DE664F +:10D6800080DC9C7597A06BBECFAC26DEFE1E130B14 +:10D69000C77EFF1BDAF37596AD3595EEE0F9A1561E +:10D6A000668A8C055DE5125DFFBCC063061C3EFD0D +:10D6B000111B07BDA072D3669A8FA20B66EA281EC3 +:10D6C000043D6F775A1ECED78A8E7E5E30EDDABC6F +:10D6D000607AB849233AE0E92B19440F7366113D8B +:10D6E0004CF367AEE4F32A31D63137EC0C89CC1514 +:10D6F000C6E7DFCB7A489FE8E5FA04E499E2278A97 +:10D700006F703A705BE303F8DDD3CCA7C279F2DE29 +:10D71000662BA54F363B9889C3775F7322E59F69D7 +:10D720007652DAD69C4DDF7FD9ECA2FC81E671946B +:10D730003FD8ECA6FCA1E69994BED85C4ADF155F01 +:10D74000E270213EA4F88AE2478A9E145F0AA5A3EC +:10D750007227F606B527BEA7F81DD661C80BF023C1 +:10D7600085DF74ADD49B98063ED6B900FCA2C47880 +:10D77000F6E9E7397C7BABEDAE3027E022F85EAF0F +:10D78000DD4A723ED5C20EE1FCDFB2C2DD75779094 +:10D790005CBDB55A63A620BABDADD1C64C41747B01 +:10D7A0007B538C2E5FD6F4F6B104DEFFDF533C5E74 +:10D7B000E0E5E49D1F3FFA9FFCFBE3777E3E1CF80B +:10D7C000E6F3D8FD10C65D13DE378F58E4D79949CC +:10D7D000CE0C0B17E7A461E1E29C843FE0671113D4 +:10D7E000FBF4F13BFF4AFBBCAB29CC6984FE017C16 +:10D7F00071F87E20F1B5A8298CE058B1FED4D3CFC2 +:10D8000063BFAFB110BF5BB44EEECF8D1CAE417A9B +:10D81000DB87498CF433CDCD581387DF873FB2F8CF +:10D82000B9EC671F6A569FC61B6AFCD054C6BF7B03 +:10D8300036FEEA3DE8DB5AD309D28F3D56BBDF887E +:10D84000F979CD6783FBD39A8E533DD63934E6E31D +:10D8500008DA8A0C708C28705BC02740DBC0DFA21E +:10D86000EC230CFB9BB56A8EE17C5D55F27BD546C3 +:10D870008DF40E05FF27F28CB4AF4EE79A08AFD3B4 +:10D88000B0670713032339A5E896F30DB70FFBA381 +:10D8900035D7B224881F2F92DF2BB30D94AAEFA7A0 +:10D8A000F9B6443FD3B0B978BFF766A75B1613BF8C +:10D8B000735AC00F54FD45D9791BD20BD0CFD43841 +:10D8C00016B42F9FCB33C97939841CB37239C6DBA8 +:10D8D000D50D200F947EF229FE773CCD9FCE5F358B +:10D8E000CF3CF5CC8BB04BBC1F4678AAB946DA3793 +:10D8F000727C63E6925EE3B66B7C9D0D12FFC54FB2 +:10D90000FD29AA93972F3F20ECA73CED42DAB0A661 +:10D910009AEC650D2EBE4FB00F0E993FEC0CA2CBCA +:10D92000579F793FAA93CE17DE644322527F32E39A +:10D9300069C381533318FA633D1B1CF62BDB2DD7CB +:10D940002ED33953ADA3E4F097F134BE76299EEA85 +:10D950001F5E1FDF9F1D6439337DD8B77FC9CEE0BE +:10D96000D6D9D596B34D178C7CBECBD7CCFC0474DE +:10D970001E5AFF93BCC838D00F1BCBC6921DC3C420 +:10D980000CC0F74AAB8043AF6F7834FB1AFBCBF285 +:10D990006DBC1157B57A4DCE68179F6F37ECE7FD18 +:10D9A000D4CFC91772FD1CDF478C9FA5BAF719E9C0 +:10D9B000BCD0BD2F92E8BF61DF03C727F27CC32E26 +:10D9C0000DC3B27AD641706A386064D6607906FBBE +:10D9D000CEA081E759FB546423E869599BE6DECD6C +:10D9E000E7D36B75460F0E9A8F2D5FD0536D58DBC2 +:10D9F0001882AB9CFFDF253F53F596B53F6001BE13 +:10DA000078BDF3A4BFFC228291DD8CF5BC89799EA0 +:10DA1000D99EEF827D6F59DBFE0692FFFB221CC36D +:10DA2000F93A3E97767ED5CFE07CB19F06E70BBDF5 +:10DA3000E38CB4E79E79C6487C08F3C43EFC1C7AAC +:10DA40006ED03C93E53C93F3857E7304FBB130507C +:10DA50007F595B575426AFFFC9A1B7291D2EC7595F +:10DA600066EF180DB9F9C98188993E4A7F3AE325D6 +:10DA70003EDEB9B6A9715AD0BECACB3753BFE7B69E +:10DA80001B67025ECC3748EAF96DB49E33FB9235D2 +:10DA90003ADF02DE5CCF3F73E0D92803ED5BAF686D +:10DAA00027F168B00A3B6D588C53EA99D656E81BAB +:10DAB0000BB97617CDF95DFD810B247F43BFABFA1F +:10DAC000B4DF9270FEEE21BB06FF33807EEB1D02B9 +:10DAD000E725C69C04EC83F26B9CB7DC0A3EF69A01 +:10DAE00059E061A8F3219CABCADF1A44768B956696 +:10DAF0006702F25FBCCE0F827CDEE5F9727F27768B +:10DB000016C2CED99526E47ADD467E50E1EB19C2E5 +:10DB1000F1EEE54BAEF31999273FE0279A9F9F4E10 +:10DB2000EB7BA4DAE0B6909FC59F05BBE7490BF3FA +:10DB300092DFE89736E10F481776FD47A4BFA82E7D +:10DB4000D69F3508F62F89C7BA39BC3C089F753B6C +:10DB5000FD59D05FCE5A849D0FE50EA479A25E8B4D +:10DB6000A41BF4837EBBD21CE749CF7C2E9241DFFD +:10DB7000373C1F29EC0A3FB7ED0C0B929BD592AEB8 +:10DB8000B8CEE4C5FABDBBC5FC302FE8CFCB2CAD79 +:10DB900059D02FD5B8CBA25A69BCB372BC65E1ADE0 +:10DBA000C23F6111F648D4A7F1CD8CFC283D4F84CB +:10DBB000919EFA7952C7418CFFF9132319E47857E3 +:10DBC0009A6FC9212AE7FA1BC747CD93617ECCF72C +:10DBD000B327227D8CD7FFCC2CF4A1CF22E3491FA1 +:10DBE0003A11B9B59CFC32BBC234D8553ED3982506 +:10DBF00011E5BB851FA3A6B989FC0F357CBBB33CDF +:10DC00004A67B258948F247BCB67BFE6FB54A3EFDF +:10DC10001BF1DDC35ACB7F807DB73782EC6E9F3F0F +:10DC2000F95F23FBF35BD4ECD2DB97141DA8F27BE6 +:10DC3000245FBA47C2F1BE7C07E1BF3EA26D6B3ADA +:10DC4000AD53EC578E073A77F1FD110F7BF7C9B64C +:10DC500017E2353BE0ECCFFA29E0BE579C6F3EDF80 +:10DC60006726BF4BCDF3916EB2E3DC3DD600795110 +:10DC700063147A708D81838FA7DA9D7BB3A067B719 +:10DC80003C61CB033C38BCE91CD9B3DB28C711E3AA +:10DC90007EB62745D8F5FD327F7014D9F567C5B239 +:10DCA000DBE7909EB37D34E07A7157840174C1C77D +:10DCB000716B1C3E353FF8A18067F412D2CBF9FEA0 +:10DCC000237E5927F965FDDD13A327623FBD6564F7 +:10DCD000D00B2E9A5C09E087A1F0FA40F295DA8326 +:10DCE0008F5AE0B7ABE3FBC6C3F74DADF48FD53E1B +:10DCF000A9915E57BB61E243C407DF34B3E17C1EE8 +:10DD000067DB1E880AC6C771C9CF02ED5D54BF9696 +:10DD1000D717ED5F8BA2F9EC31BB309F503C7EEB07 +:10DD2000F64F1ABF55FB3EFA68E3727DF495EBBEE1 +:10DD3000C83ABEFF3EF8C93E1BD9AF38DE53A177C3 +:10DD40009C31B72DC1BACF3C6D233E732646ECF70C +:10DD50004F383FF48EC03CBE733FD9377E37974172 +:10DD60001E2CF5E9FB55E3BE26F96FFD205734EC78 +:10DD700064F51C0FE88FE3E5BBD4FE2D33B50F5DD2 +:10DD8000C793685718B43F9F8E207A393344E0E335 +:10DD9000CC332348AE74C5083AE7F34DC579E54C5A +:10DDA0008C481994114E0735F23C7A666A1B9DBF68 +:10DDB000CF68FB29ED328B76354DD26FCCE92E1131 +:10DDC00074039A843FCCBAA903FA04ECD563F22811 +:10DDD000F587C55E6977067D420E651408F9C53082 +:10DDE0005EBCF47F909ED266015FF6483DAE6EDF6A +:10DDF000957E38E0B76E9F467E2483EA87CF3A4E01 +:10DE0000D9CB393DD67A35B70DF359B76219F991A7 +:10DE10001A37DF0A7A57EBA835B199380F7569467A +:10DE20009A4F978DEF1BC02178BC20BD2B32300E4E +:10DE300073C4939E49CA754C819057C8B7F2FEEAE5 +:10DE4000D6699B689C3475AE14EB5370E260B1C028 +:10DE50005EC6CFFBA27C80F5AB7986AE5FCD6778DE +:10DE600081B05374A539EF2F02BEDF30BA704EBFB8 +:10DE700078393F3AF66BF4329CDCFAECC67CFE79DA +:10DE8000A0293EFF2F257FAB855D9ACF336BBBDE8C +:10DE90001F92BD4B9FBF6A9F3E9F73409F1FDDAE89 +:10DEA000CFBB5ED5E787C871159C70EE758E10E705 +:10DEB0005EA438F73AC3C4B917799C7B91E2DC8B36 +:10DEC000EF38F7228F732FF238F7228F732F529C7F +:10DED0007BF1BDB240F0EF3A6977041EE097612F05 +:10DEE000D8949F9DF64BF78278E29FCA4FDABD2CFB +:10DEF00087F27D769DD956B2EB90ED86EB25738740 +:10DF00007A6E282884FFB4634312F066EA247BEE1D +:10DF1000F217853DB72ECF66879DA173FD271BA005 +:10DF20003E650DF5CC41FD6E73CF1EA203939FF8A5 +:10DF300046E75AE75B5304FEC8DEC1ECB1743EA964 +:10DF400080BC8B1D188FA17E15B649EF4709F5AB34 +:10DF500084FA5342E940F9511E37F72481DF9F7A52 +:10DF6000C2BA09F33F25ED646CBE95F42FA557970F +:10DF700018ED04A795F7693B21A75615C452FBDE9F +:10DF8000135CDFEE47DEAAB4F252BED0AB557E93EF +:10DF900066203F8DC74D7268959C53AAD6D37537BE +:10DFA0006824D24072FCA2DD40E7828BEF18498FD3 +:10DFB00018B1CDA05BCF485FB88EBEAEDE1B1BE2B2 +:10DFC0000F1CA2AB7FCDA1F4107FE0557A3FD54D59 +:10DFD0006B5FC1F97AEEA67C5DBDAAD289217094EF +:10DFE000F3967A69CB9A6DA9E03FAB227B69FEABD1 +:10DFF0009EB3D1BD8B2A2E5FDC7CDDD5C870FE5868 +:10E000006D75DF08F855B7996360D7AA94F2873524 +:10E01000E9E571B589791DB101BAAB7630770C6F3E +:10E020007F2EB7758F81E3ED9C61FBD62227FC4BD9 +:10E030003B521D9CAE566B6DF1E3797FA7623C3B72 +:10E040000AF87E4E35FB7F52067EB93F83ADE5F57B +:10E050004E6D7A368AF46E4967A9664738F0BDA3DB +:10E06000D548E702D8A7600F52F4B0A3755078A640 +:10E070003DB0CE00FE2FD3FA385EE8DE48AFFDC8D3 +:10E08000D055D0E3DAC47AABA76A5ED293E57A566C +:10E090004AB9C2D6897E56CBFC69795E50EB3B3BD0 +:10E0A000F295D14EF8359B0FA51AC1C70DFBF6248A +:10E0B00041BF48F0B463FF54EF18FE9F457CDC9AE3 +:10E0C000DF1B19FCC81F6D991E351EFAE7D366D7F2 +:10E0D0002C9EBFBBF567169C0B6A4C3E0BCE9DD5A4 +:10E0E0004FECB0C0FF7FEDDE1DF47DC9DE0A3A6F54 +:10E0F0002F658D748EFCD42CE4B48247F5346DBB4F +:10E1000083CF3BB350F0D7EA70711FA4C458742C6E +:10E110000EEBDDABE562BD3795EEB754F0EFEF4A9D +:10E120003E1CBA3F7A5F9F5B321876A536E1071D29 +:10E13000683FCCF38FA4FD30F7521AA5375DBA9A29 +:10E14000CE55BF67A5A3884FE4849C675F370ABBA1 +:10E1500059BBD807D5167FDC5CEC9397CDB44FEA5A +:10E160004DB07DE39CCCD8049E96161975F4BABCCC +:10E17000384247CFF359ACCEAF7C331BA2CBDF3450 +:10E180002B4357FF969BAE0EA1FFBC4039F191097E +:10E19000BAFB2BF56BBC4E8DEC68D3F4DF79BA86F5 +:10E1A000E8EC7A5DFB7A3627500FE7E05DBF253853 +:10E1B00033D661C179ABDA20EEEBCCF774C9EF9DB1 +:10E1C000F49D2F44B70F8765B8FE53C84533D9E790 +:10E1D000957D7A3EFE3FA33FB9C8112DC78D360A03 +:10E1E000FB8247AF7774D0F993093CD44B7B4F7DCA +:10E1F000B6B0F7D47B3B2C8D7682BF299983A4A13E +:10E2000055237B1EAF6F4D8E15F935F87EC01CB0BF +:10E21000B330D1DF25949F305660BF849637F075B8 +:10E2200043CF6880BD86EC4C333F213B931A47F6C1 +:10E23000AFE874E936BDFDA801769D207C2E2B74D5 +:10E2400012BDD6ECDD7F7C0887CFDCD2985CECA3D6 +:10E25000BAB6D9E68A9C2BE94DF1F98BD506F27B4B +:10E26000F7BE7E94E8ADB7DA4474FD4D7069700B6B +:10E27000BB66281D2EE1EBB2F2F1971CD05C3E4D3F +:10E28000D4037C86803E43E093DC0FDC14BCFAE0D0 +:10E290001752BE14FF5380FB049ACF9FD61F5C42D7 +:10E2A000E0A9C60981171BA787C7128FF32DF09F1E +:10E2B00025278CCCF72DD6BF14EBC43CF83A318F10 +:10E2C000399784DD44F9136EBE64A27C1FDD94721D +:10E2D00078E561DFE9F7691F1D958A7D33EF523CD0 +:10E2E000B5FB57D1D337D1919ABFE2DB817D74174B +:10E2F000C98DE58591711F7356C1FFBF90F882E407 +:10E30000AF03EBA55EC1473D7A3933ECCE7174EFB4 +:10E31000A8D79E4E7A459F1C72E8CB5746A627A0E9 +:10E32000DC23ED768A1F7B643D354E052F770E0288 +:10E330005D0F8D873D76C3BA8CD4CE207DC5B3DE0C +:10E340001C0F7B61EADA419456D81CF19023156BBF +:10E350008DA5908F1FDE93103F0EF6F9F5E6B859A4 +:10E36000BCEB0FEF284865A3902FA1F4D4E6B0F9D9 +:10E37000C1766E956E2B147A68FD9DEF915C3B67BC +:10E38000783D6A3EF6DDFAE7A270F5A676FDDB631E +:10E390001C5C25B93BC6F35021F95177EC71006E36 +:10E3A0008E1DA361A7FE396C688303FA43CDFA92F0 +:10E3B00004D8C5EAFE76F431C87DCF5A733CF4CF59 +:10E3C000CFDEE1725123B9467AC3A73646E7A54F9F +:10E3D0007747F8E0BFFF54636EF87796195F19ED41 +:10E3E000D0C9D9F69B318FBD099E9F1716627CDF7D +:10E3F0009E448CEFF2D2FD4CCFDAE1D1FDD95154DD +:10E40000BA7C9BD0EBF6283BAEB4F7429F471EFA8E +:10E410003C1B21F479E4A1CF23853E8FEFC7A41DD7 +:10E420007F584B4F2ECEA3DE692CBB91E4AE3D1B33 +:10E43000FAFA2A2DDC457AA6E64A807D8CBD1323A4 +:10E44000E46D087E553AA987EB5C41743FE59295EF +:10E4500005DF339BCA6274F9E9D6245DFD12479A41 +:10E46000AEFCDAC491BAF2EB9CB9BAFC77B2C7EB56 +:10E47000EADFE09AAACB7F77DC75BAFAB3DDB37531 +:10E48000F9B93317E8EACF2BADD095DF327F99AEDB +:10E490007C8167852E7F6BF51DBAFAB735AED595B1 +:10E4A000BB99C304B9D78E731687FBCB3867F17459 +:10E4B000D51BC3EDC1782D9A6E68ECCF4E7F5EEA16 +:10E4C0004313C7BA3F037DA418041DF2D40D15E20F +:10E4D000B2942BC9CCAF89736E4712E826B45E683C +:10E4E0007951C4918B4E8EC32507636F35713E52AF +:10E4F00034F6487E06CF3F336681C84F3CF26C3A13 +:10E50000CF1F3CB8F55613E71F45D71CB988F2D189 +:10E5100063CB457E2E2395E3C898BF2DF4F2751486 +:10E520004D49DFE41276927EEF69AA1470C0FD4671 +:10E53000C001A99FD327D2239C3E91BECAE9B3CA8A +:10E54000CCD8714E9F484FF0F326BEFF869F37917F +:10E55000BECECF9B48DFE4E74DA41DFCBC89F47719 +:10E56000CDF3297DA7D943EDDE6DAEA6F4BDE64619 +:10E57000FAFEC7E6264A3F68F6D2F7C431CAAEE0D3 +:10E5800027FB8BF23335C0BF07FBDC21F3D9603F9B +:10E59000ACF2132ABF604B23EB8CC03EED34C57C3C +:10E5A0006C0DF8FB06E6B326F671901EB639D19DC8 +:10E5B0003186C61FEA207F8FFC3E4D9B9B02D7DF32 +:10E5C000ADA33D23C7707CCFCBAB5C1FCDF9C79407 +:10E5D000CB8D66D0CBEFE53DD5D0FE2F4B3A891BD6 +:10E5E000EB1E8D7693ADE21EDE64ABB86737D9D4EF +:10E5F000D9027ED4F22573E21ECD2B9116E24F2D67 +:10E60000F7987CB0536A5F30CA4F8A63946FF9B24F +:10E6100083EEE54D76B81249DEC87C9FFF1C7F4132 +:10E62000F765943F5BDD9329FEA2733AF480497647 +:10E630008B332CC4FF0EBFF52B91EFAAF9308CA7BA +:10E64000FCE4BBBE647EC3E8803F7CB2B5230D769C +:10E650008249ABADAEE0FB3FCAEFAD7DD161843CFA +:10E6600051F77CD4386ABE9126DE5F5EE01ECF642F +:10E67000475B2EEE35B4D4DBA9BF04FEDD9247F52F +:10E68000DC466AD7960B3BF0A43ABB0BF66DE56F00 +:10E690004F90EBE6F5689DC55F78E8BEC12479DF51 +:10E6A00000FD5845B917FD4C8AF32799B0FE468BFB +:10E6B0000BF6D04735DE3E2FE0FF47FD88A0FD8BEF +:10E6C00079A2DFCCBFF0F9426F77BB09BE73D5F9F1 +:10E6D000CD29F3523E33EB34B25F1965FEB7A33D4B +:10E6E000CB81F7D230C79F22689F67A4C0CE315B31 +:10E6F000EAED5F432FABFF7BE8C52DF03D94913DE4 +:10E700002D946E145E149E07A22385F7A0FB5A84F5 +:10E71000E7BEFB57B29F50FA1A88AE143D4DB60AB9 +:10E72000BC03AFB847A3E848FBA26D07ADA3CE4A30 +:10E73000724ED151281D5C4947822E5BBE67A5FEF3 +:10E74000AEA4A300FE018F7F9E8E3A8C90BBFF2863 +:10E75000FDDCDEC36644F3A27BAFF15C86DCA8B8C7 +:10E76000E43C8E7C259B3A0324A5CA1F40F9E02B8C +:10E77000CB43E94BD57F7180FE3C5FF498A383E8DF +:10E78000729294817F18A0FE6BF25EFC6B3675DF8F +:10E79000C36DCFE574305DF2E1552582BE66A619E2 +:10E7A000C99F313D6729E9F7CC2EF46327FF87EC39 +:10E7B0006DD2BF7EBD6C37E372E93A8C33234EAF26 +:10E7C0007F5F2FF5EE9921FEF6EB73AE253DFCFA47 +:10E7D000103DFBBD31528F4E6369E27CBD89F4DF91 +:10E7E00062B91F9325BE339C4656C4E15EC23C26E7 +:10E7F000088157CF5BDCE8EF5AE6A5FC75CC47E90A +:10E8000077989FF4801BB8C040FEBB8CD1FDD1A38C +:10E810001137962DE7FD4DCF9F9E89EF75D69E54FB +:10E820008B01B7033D9F413E34183D7F869E792E74 +:10E83000C53302E7E323C54ED2C38E5833482FC4F5 +:10E840007E3207D92B7FCDE56826977347B99C4563 +:10E850007A8CCBD94C2EEF7EC5E52CF2D767AF650D +:10E860006837C3A9BFDFA3DA7FC7319D99060D2C96 +:10E87000C7BE33FA85A1B063BD1633A218787B2DCD +:10E88000666C31D6FB5A4C8241A461164A473D9FC3 +:10E89000D99FDEAAE83530DE0C1A2F14BE0A9EA1DD +:10E8A0007054F0FD27E039686CE195F0BC0CFD1E5A +:10E8B000F653EBDB5189E9F033CA78BA08C107EBAC +:10E8C0009F1F958075D459055C26354DA47472D36D +:10E8D0007866CA273F9317F0FD0C4B80C139C4CE30 +:10E8E000C64CD328FF3D495BD9099EE198C7D93C66 +:10E8F0007F16D7C8D827DB5BA2703FF3DC334617FF +:10E90000CE357546E72617ECE4AF19455CD0E5A394 +:10E91000A9F06FB25DFDDF97AEB32AF87909AE3F7B +:10E92000BBC64DFB8DC13B1B1FD06B8686897BC64A +:10E93000E45EC81B58CF19132EF8CCD030C11F1578 +:10E94000BE783B2177793F63385F4BBE3F9CCE3525 +:10E9500005C3DC45580F3F2F505C516F7604D92B0F +:10E960007E23E31227FBAFA6B8BC9938B7F3EFC6F6 +:10E97000F0A89DD8F7BF917189BF18E4B916EDAF23 +:10E980004DCB4B043CA630E157B9CE6A76F9F99CE1 +:10E99000AE1B2BF7E168365AC6F5E8CE1FCA4ED239 +:10E9A0001B6724393499653D043B41F10933D9098A +:10E9B000FAEEBB250ABF68EF898B46F09592488D29 +:10E9C0000D4A0BC4E784251A9833486FB739C399A9 +:10E9D00033687F4464C7EAF291AE21BAFAD1E3D238 +:10E9E00075E531EEAB74E58366E6E9F2834B27E823 +:10E9F000EA27CC9FA6CB2779AED7D54FAE9EA3CB27 +:10EA00002BBE972C3EB194C685BAF6C39A16E9EA96 +:10EA1000A7796B74E50A0FCCEBEEC88E075F147F05 +:10EA2000191B57EAEAFD344AC49BCCB42F9985FDE3 +:10EA30003EBCF507FA79195FD7287ED429F8AD973F +:10EA4000FF033A2A49D4F3DFE90EBD5D23B9D1A40F +:10EA5000CB6FF847F1ECB94A87E7507870BCBBFC44 +:10EA6000A8CFE5B797E74B7E5D69827E01FF45F051 +:10EA7000FCE1BF085E2FFC17C179F82F82EBC37F42 +:10EA8000115C0EFF457079FE093D9E0B3BF4781E2C +:10EA9000FB9E1ECF8AFE06C2C7F84E3D1D84E26370 +:10EAA000E2A7217421F1309FFFD31F1EE828C2E99D +:10EAB0007F7A2323FBDC37E1E58510BC4C1AE9693A +:10EAC000C77E9D3FE862AA0578EAF18CC079F233EF +:10EAD000692709BDC7E9E5EA00C521FCC048F1374F +:10EAE000270DAD1AF8B23FC5736C2CAF7F7B4E2358 +:10EAF000D14F222BDDBF84CFA7FC3FC2C88F533E2E +:10EB00004CC4EBB29C4E8A7350FCAE3C59DC237A69 +:10EB100063AC3CBFB9C47DA28EB1429F8D7439E80D +:10EB2000DE71458E88E3E0C7AED4F251A09FD76D69 +:10EB300023400F5B84DFA413F1C271817861E89BED +:10EB4000D0EF52A47ED5F207AB15EB18B18DE9E4F6 +:10EB5000E4489F5577EFF5EABD0E5D7E545BA2AEAB +:10EB6000FE35879CBAF25C7FB6AE3CFF844B972F94 +:10EB7000EC18A7AB3FF63DB72E3FBE73A6AEFEC462 +:10EB80004F4B75F964D6F330E03B4C13E77D2BE730 +:10EB90004B740FCC29E281CAEF8E1171A0D20EA066 +:10EBA000F469751FDA23E92E544F1F66117A6A4BF8 +:10EBB0001213E730AB3C6F31BDBEEE91F799959ED5 +:10EBC000CABCFAFBCCEA1E739F5E2FF576A51F0721 +:10EBD000DD637607DF632E97F1DBA1F22F6E9CB029 +:10EBE000EF85CE7F9845ACB7E50E0BC58DA879852E +:10EBF000CE67799EA0DBDDD6FEE377D2C769D47FEE +:10EC0000516EE99071BCDE6366978FEC28578CE7F4 +:10EC1000EAF4E25CF9238BEB2EE7378F577E8D58B1 +:10EC20004F99C170FBEC1CBA2F36FF9741E3E78D7B +:10EC300013F41D3F41EB777DE5D1E23E178BB638EB +:10EC400041BF038F27E0996861EB28CE48DEFBBF08 +:10EC50006D53DB7D23785199A5D54CC60BE63383E4 +:10EC60001E664DE3FA542EEC822F3E62E7FAC6632D +:10EC70004D26B2F38C1F37AC8C6B627D711CC3F8D0 +:10EC80007903F4019D05E79427C71B699C85E3C4BC +:10EC9000FA4A8C97FBEEDF93FF8231C9BF19DD87FB +:10ECA000E987DE880ED53AFE55F7F115DD86C249B3 +:10ECB0009D2F99943B99725E0A7E6A3F28F8A97845 +:10ECC00008E70A73E94E3BC555CCC43D3285BF9772 +:10ECD000C70B7EB409F02814F5C08F06AA5762CC82 +:10ECE00089863DBC9739A31D5F63EFFD17C62910C8 +:10ECF000FC078AAF1A883F5CC1170688B71A883E9E +:10ED0000E9EF1F88BB0AE20FE25E8FC4872FD34072 +:10ED10007EF4BB23F5FBF8857102BE1EB98FB97C6A +:10ED2000B5E7EAF90483FDBE65BD51F2092157A19B +:10ED30006FE0FBE2F566D237182BDD8A38A28FB67A +:10ED400098E97EEB64B773864BF8E749EF20BF176D +:10ED50009F5A85572F4FB97CDF093D780A736D8024 +:10ED60003FA372A3BE7CA97DC66790E78B43CEA567 +:10ED70004BE5797569C8B9F4A971521EBB988BF43B +:10ED800024E9E7AF9675FAE8C897112DED2EB43F48 +:10ED9000794AF7C2145C9CF0D7E407F21C7EE1D9F3 +:10EDA00090D3EB4CFDDED7EB83DF00F711CEE23ED4 +:10EDB0008213FBBD97E2AD7A0FD8849F52F983642A +:10EDC000FDB3DE8B548EFAE8ED5C6EC768E8217DFA +:10EDD000FEA3103F54AFDD10350EFDED33537FEA37 +:10EDE000BE45CD5F7DA31D41FE644FA75177BFE5B2 +:10EDF0008AF9AF7D8EEE5FDC1DE379077CFC8CC960 +:10EE00006505FEEEB11F89479CFC2C69B7099D6F13 +:10EE10009FDE59A4093FAC57C4CDF6CED4E81E00FE +:10EE2000E7830CFB46DD1B98CDFC7148953FC6B3CC +:10EE3000713CC159F9632AFCE3699EF35A969AC35F +:10EE40007995CE87D794843B037E9ACE1471EF6771 +:10EE5000207FCDDC4BB9D4DF4D9726523F17C7A595 +:10EE600009BD6BDD7D2B404757ED6566ACB333E4E0 +:10EE7000DEBB4A2B25BFF18E577C5ADE275AAB11D9 +:10EE80009DAFD498BA5F447C5AE52FB6CA7C89C836 +:10EE9000AF5A2FF29D66F1CECC1E696FC03A9162D7 +:10EEA0003D3817EF93F608AC0329D681EFE04BC845 +:10EEB000832F210FBE843CF81252F0257C5FC44A98 +:10EEC00053738DC2AF541CB46FE0572A0ED27BE04F +:10EED000570ACEC3AF145C1F7EA5E072F89582CBB3 +:10EEE000E1570ACEC3AF145C1F7EA5E03C1B775DE3 +:10EEF000200F3EE69EADCBCFE5FA7771D0BE855FA1 +:10EF000029B87FF89574FD7956E8DADFCA9A74ED6E +:10EF1000E1570AAE7F7B93A6F33BDD2EDF03A8DC2F +:10EF20003688E8E3A5D1A5AEF17CBFFE39E26FDFFC +:10EF300033E31C606C5F06BA5D591FEE12786E9D5C +:10EF400029F06E6002CF3D0B08CF6B2C225F22EEC2 +:10EF50001FF7E7BF29360BFF0D52F86F90C27F8372 +:10EF600014FE9BE2E1C27F8314FE1B7C87FF06290F +:10EF7000FC3748E1BF410AFF0D52F86F90C27F8312 +:10EF800076F0DF2085FF06DFE1BF410AFF0DBE9F5F +:10EF9000841F29E8DD0CE8E999BA731DA743DDB9A0 +:10EFA000CEA1CB434F0FAE0F3D3DB81C7A7A7039DE +:10EFB000F4F4E03CF4F4E0FAD0D383F3ABC739893E +:10EFC0005F425F0F6E077D3D383FAAD57B0CB6A32D +:10EFD0001BB69F7F156967A4F698C659C18A170E9C +:10EFE00094C1CFD669D3526338A7346B2F9615F3EB +:10EFF000BC47DEE31BCD7A0CC037F9D939DE3C7E45 +:10F0000046F78E477D9544E5CAAF4B7F1CEFB907A5 +:10F0100018E9FDC764BCA76AEF620E2352553F9002 +:10F02000EFBF5EE8F8AA1EF1CBA079F083612EEE67 +:10F0300099E4AEB1E7E1BEFC1E8326EE9BDE25EE31 +:10F04000FB86D2D56EC997F618F61F09C7FDA10A2F +:10F05000CD8538862C133B61CE039C1AF3A01FDCB0 +:10F06000373E46AEAB7102EE1FA9792B3B20E7136A +:10F0700014BF56D4C32C557C9C495F30CB62F077CB +:10F080008BD00BD00EE7C5ABBD9A7B67107D3F34AC +:10F090005EC8378F77C5842AFEFDEA7D8D13101771 +:10F0A000372B5CB4FBF9E35104C71BD7693B117FD5 +:10F0B00058B48FB911EFEA93F3BE7A9FC35245E378 +:10F0C0003A289E4EF55BB13D95E2FF2A586731E242 +:10F0D0002B5881C6E01F5570E3EB7B15EBCBE25B51 +:10F0E000C54CFAA788CB099771392A1E272CA6B4DC +:10F0F0000A724BC5E54C2A8829C1BD38D6CE5C08BA +:10F1000003BEA1A062FD60DEBFC7E776E15ED1A4C9 +:10F110002F1A8F517E5729E5890CC6D03824D7463F +:10F1200078357A5FE346EF0E439C13F1BA6BCDF16D +:10F13000A8BF8FB9A0EE70514371A76A7E39ACC3E6 +:10F1400060D38077767450101D710E7013F09EEBB3 +:10F1500032D3FB1BB34D0E33F846A81CBFF2DE6260 +:10F16000889E1072BFA465CD7BA9C674DC2F31B810 +:10F17000FCE05BCF4590BEA0F49D0A79DFECE2BADB +:10F1800063836FE1E515FB857EE0D9A611FF53F798 +:10F190004DEA337CA906E80B43768C8E350AF90FCD +:10F1A000BE78C6FBECCDD8A215EB8F515C44C5FAF6 +:10F1B000C268111725FC1055124E55F25E11CB7125 +:10F1C000C443CFFC90F31DF708BA97184D7185AD75 +:10F1D000429F53F616A50FAAF7632ADEC83F0EBC5E +:10F1E000573C2ADF65D95841F157A1F77C6AA5BE83 +:10F1F000B76C9D99EE0F2D0BD1076BE57DA1DA1051 +:10F200007DF0DCF8107D509E5FD47DDE8A378ECE97 +:10F21000237DA5D14C7EB9B2B5427F61FB990FF138 +:10F220000C656BA71BF06E48D9736E97D60F9DBC0B +:10F2300025F598599D3682EB9C4BC994DE7C298933 +:10F24000D25B2E897B94887D011D74BEC0488F7E61 +:10F250005BEA2DF370AF12F188DE30797F9291DE98 +:10F2600094CB1C25E01F57B9B5A350FB66993DEB25 +:10F27000716F73D60E46F1473740BF41FC17F41D3E +:10F28000D8DD0BD24A280E63A646F12C3714AC9079 +:10F29000F4CDE99D81DEBD927E4B29DF2717249DA9 +:10F2A0007BBC5D26C0FD06AF66C13B7C1E798E55DA +:10F2B000741C4AEFE511D2FE6417F6A53EFB132637 +:10F2C0008B476DBCD1B7E17E6B396C764398403C7F +:10F2D0008779648E281FF162F46DEB70A8F9BFB4D2 +:10F2E0004B94190C22DE89EB5BE0ABB7ADCEB52CAD +:10F2F0000AE22F5F4C9C3663626100EF8B42E2F4BE +:10F3000056DE333CE1EBE2452B399CB14FCAA33BBF +:10F31000BFC729945D3B81B98BF999750163EAF107 +:10F320001E3FEE052E94F9D52F8EFBD3463BC187A9 +:10F33000F2D327A4DEE625BE2AF8D6ADE05B46F080 +:10F340002BCFD409C4AF3A67001F11393DF21D021B +:10F35000299742EC10AB2738C57A43EC11953982D6 +:10F360009F339333F5568A0B76923D4FCDFF43B3CF +:10F370003E4EB3CF2F3241CA93E67F4D7CC3FFCAC6 +:10F38000F0DC86F56D3588B8F921C65626ED42B415 +:10F39000FF15FF60F21D8900FEB99E467E74CD11F7 +:10F3A0008C7FCF464DC4A90F60BF61D93D0FEF865A +:10F3B000FDAED9C210E7FA7896A0A3C77F60213DC1 +:10F3C000BCCCD2710CEF642938BEDFF4EF66B2CB4F +:10F3D00033FF70BCFFB5B0D1E6027FFE6262E92A5E +:10F3E000CC3B22C745F898C1B719FA3F9952FA7D2C +:10F3F000C2D7A6571E43DCFEF2F6348A23AD3894FA +:10F40000BB01EF897C31D1F3C309F0E3DA1D16C8E3 +:10F41000F186753124D7CA13645C27EB213F9582AE +:10F42000FF031384FDEABA2241C7DDF23C028639AC +:10F430005B574FDEE30ED927CA2E186A5F087DC7D7 +:10F4400061A0FDA3EC08B01B5882EC8ACA2E61CEE5 +:10F45000FE7001E46899451F7FA8D25795DD4D9E47 +:10F460000717F7C9B19C1909D09B376B0EC8B12A91 +:10F47000BBF396F13C5F75C28C1B986C56AC53BCC9 +:10F48000DF718F78BF6311DFAFE03765F23E56D58D +:10F49000B6F1B4DFAA7C3CCD1F785FDEBAF968CA4A +:10F4A0000BA01FBF9BE2F2AB1C6E4B6CD0BEAF6CCF +:10F4B000D57471FD2A7F6082B0C39571351DF0BB94 +:10F4C0006D759A056FE89471F502F7FB5E9DE0D4C7 +:10F4D000C555F37A74AF61563A3B2EDE4FE2F34ED8 +:10F4E00013E3E505F5BFA855FF3E01AF4F7AD1CB39 +:10F4F0001322097F150EBEEE34A40E9A278703C18E +:10F50000A9E73EDE9F93C6217C54FA7D669CBBCB67 +:10F51000709F82E7173A7C668CB3689D782FC4B3DE +:10F52000498CE3D918631905BDC9E4B0A4007E383D +:10F530002CC7D1FC880F5671B820DE4AC55D86C243 +:10F54000A742CEB7AA3546AF8FB56E36031F0B065E +:10F5500078AFA047D2EDA2755329DEBCCAE4A678E5 +:10F56000068F84EF472B6CF7C22FB060CB43E63495 +:10F570009CB32708FB738FDC77B3D2FDC3E95DA092 +:10F58000153617E6B9C0D14AEBEB83EF831C1E1A80 +:10F59000DE9F2925F872BAF0E27E5ED5163D3E0365 +:10F5A000F311F0ADDA5241FB6D89C9637104CF6389 +:10F5B000DB2BC3710F6501DFDF78EF88393C14DF87 +:10F5C000F4F183B7A4D23AF93CE91E94CB3903EFA6 +:10F5D000FC703A213A56F4A2E2B2D578D689222EAE +:10F5E000D33AF19BF6A59BF49A168E5FD8BB07DA47 +:10F5F00097160476F1712D55E2FDB5D07DAAF6A7D8 +:10F60000DA976A9FAAFDFB98B9D49FA805F80C97D2 +:10F61000B78DBFEC074E33E47C174ABC72B8BE1AF4 +:10F620001CC775CD4481D7B274FD7E477FE837652E +:10F63000A2D8EF65D3FCC31177A9EAAB71CB6245C1 +:10F640003BD03DE82D65A2A1AFFE4AAAAF8F47A9E6 +:10F65000ECE317FBD6C7835FECD748EF5D79DFD1CA +:10F66000947F833EFBB4D067CFD4ED6E4882DE68D2 +:10F67000F2A506BF8B55E517FC6131D77FC02F96E9 +:10F680004839DD9EE7C99918B47FAB1E783ACB2381 +:10F69000F88B1FFCE583A75FFAFD0467407EAAF99B +:10F6A0002FDAF85B73853D185E627DF766F7529C32 +:10F6B0005DA5DDE2C4FDE5CA7515C46F59223F574B +:10F6C00068017C87D241C53A8DDE17AB6C1AE333F3 +:10F6D000FE37F2E5CA4DB3E94D248527F5DE899260 +:10F6E000A76AFEDF95F35F28E978CE44B1FF16568E +:10F6F000A75996D0BE4FB35482FE65F9822AFDF712 +:10F700003E3CF5F9977336607F206E88CE279BCC00 +:10F71000C2CEB72F92F4D5332B9F7FF3665EEFF303 +:10F72000AD3B52A19FA8792C95F6BCC5D22EB7440B +:10F73000EAAD1C4F15C1785AFAB8C053E5336FFCD7 +:10F7400009EF7295A54B7E769F88E75FD4B69FF050 +:10F75000B660E366731AAFB762629AEE9E4C652399 +:10F760003FE872782EDCB8C30C3EB062A2805B2802 +:10F77000BD97C9FBBE0AAE903B5A90DF42D507FF4A +:10F78000DBCFC759BDC21605FBB41AE71149D7959F +:10F790008D31B118AFB2B1E2273877287E1FBAEFAA +:10F7A0004ED9C47E58C4FBC3BE3C35D54571CDF09F +:10F7B0006BF52757374BBCFDD42CDE6F4C8E687B26 +:10F7C0000270485E1EEE027FC8CCEC24BF31E819FF +:10F7D000F3B618C47B8F99759D17300FAE52D3FDC9 +:10F7E00014A478670A2A763CCFEF3488F8AB74A368 +:10F7F000489F97F0E1E57E94B3B84E7A77AEEFDD9F +:10F80000A4107AB5B05D1BF1DE8D258EB95A9C012E +:10F81000FA54FD28FA54F43BD0FA7E21F9C837ADEA +:10F82000EF549AB44764BB5211A7527EFF0817ECFD +:10F8300033DFB44E8B7C7FB06FBD9C58C7C5F6B329 +:10F84000DE4C716E1978BD5B4AE2FB596FE83AD520 +:10F850003E5177DAFBFC0BADC2BF704AE3F28BB7C7 +:10F860003BB5C246F7BFD4BA94FDFBDBC621BC3D15 +:10F870003156DA133A23A1479685CBFDEF17797CF1 +:10F880009F1DF45DC97DF55E9BE2CFA71BA55C645F +:10F890009DF7613FB3A60C7A9FE464EBA948BC973F +:10F8A000726AAA989F6AB7DA2CE28C59A4C589F7C4 +:10F8B0000FF9F9EA6413FC3EEB12E81C795B53067E +:10F8C000F185DBBC31C2FE20F5FB25920F46ACAEC4 +:10F8D000D88077BE176F4B73687C9CC576D7C7DB23 +:10F8E000A8FDD52EE883115B665BD249EF15E700D2 +:10F8F000E5275AADB1528A1B039FC4FE32BC920960 +:10F90000B9B3749B3807CC32B08DF0130E6B299DC0 +:10F9100091043EF1B04671E66CBBFE1DABB1F9A59A +:10F92000E7E9FC17F20EDC6A739B3B017C9CEB1B46 +:10F93000B0372DB69792DE5E2FF9E4C92D5DF41E27 +:10F94000BD82EB15F13F161107DC1369203BDCB7D4 +:10F950008D03AA927E254537CA2FF508FE331E7007 +:10F9600032925C2B3196D17B4A1BB64CA7B46A739A +:10F97000C956EF28C41F97C64FA0799BC94E56554C +:10F980003F5DC4EBEE0C8BC1F926D5EC4D0DD64B8B +:10F99000AB76DC4DF13F9FEEB051FC4FB163767119 +:10F9A0004C1CBD774CF175AA5E6A91E03B35F5D3EE +:10F9B00075F13B8B799F7867F3CBB608BA1FA6E247 +:10F9C00072EA123C494583457CCE78A788CB49A290 +:10F9D000FACE7EEDE22AFDB859C47904C51BDDB824 +:10F9E00080B7AFAB7F360AFDD43EF8F6188781ECBE +:10F9F00050C3D17F5FBCD136116F9425CF4BB3621A +:10FA00004B6F5E00F8FFDA48F01F68BCEA439ACEFD +:10FA10008F779B2F9AF4568F9F59E047F63818E955 +:10FA2000C59F1A5913F400A5BFA8EFE3255C3E8DCE +:10FA30006E4D057D2CDBF3502AE4CB6791225FB637 +:10FA4000E796DF805F79768509FDDCC4481FAEF458 +:10FA50000AFD9A55C7AAF7486DE59C8EA6174588FA +:10FA6000778FB6E9E3CDD53BB79F99C4FB3C883788 +:10FA700002BDBF6FF22F067EDFE7FA2BCEB1A9459C +:10FA8000823EDF6F35CEA07B437CA3400F79BFF56C +:10FA9000D948C4432B7DADC4F8811BEFFFAC7C4E2D +:10FAA000C405E37D7A7A2B54DA411AA41D64E50B70 +:10FAB000E619C971A47FD1973A93DFD21FFE6AA4D9 +:10FAC0007ED5973FB09FCE6D75FB84FE50D7D6454F +:10FAD000FA83D24754DC61EDBE2ED22754BB860395 +:10FAE000022EF507C4F78A6C83B2A3B8B54C9CA765 +:10FAF00035CA7B5FCC2F5F6B0ACEE795AF05B39F0E +:10FB0000A0EC233DA40FDE9BFD3B3A87D7AF93FDCE +:10FB1000F2BC3968BC6A1051A1F89E61477BA7EE20 +:10FB20007C577F2086DAFBEBC33742CEBB1BEC262B +:10FB3000A42DF57692FBDB1B0DD9B8A7EED6C25DDE +:10FB4000D0E3DAE5FDADC1B5EFDA603F48623D478D +:10FB5000F1DEAE3FC5F3C322DE6F025E773106E20F +:10FB600089BA0F7F928FFE270FEBBC883735CCDA2E +:10FB70009472F8295A8AE43A723AF341D7838F088B +:10FB8000FEFCA8996DA4779B4DA50CF67BBFF42FC6 +:10FB90007ABF32D0FBB3ED9AFF67C1FAD521499FF6 +:10FBA000A561C2CFB873B46713E6F15DCD3C2A9767 +:10FBB000EE1D1A87A3FF6EE987547AEA34C99F5372 +:10FBC000E4F9CA3224D10E3A56F7ED34B79BE23D40 +:10FBD000EFCA395209F9FCE31E2BC50B4CEB092780 +:10FBE000BD3565C84C9267EADD7615F77324C7E02A +:10FBF000C57BF43F6656712FC01AA2DF1A6C743FA2 +:10FC0000596BFFD557E0EBC9C60B47A3715FF6DF11 +:10FC1000347A7FB4BCF7E347DF62380FFB72291EEA +:10FC20003AC5B307EB39D93BB3CBC351F763479B15 +:10FC3000D525E4050B5E47FB1D5F45C51A02F3EBB6 +:10FC4000EEF998DE75ECEEB192DD765ABB7CE730CA +:10FC5000643EDD894EBA27CDEBD1FBCFDD7603BD07 +:10FC6000EF36ADFD28BD57384DBD6768D5BF67C8B5 +:10FC70003A52626057265B2A570EE25B04FE264723 +:10FC8000EBCF8BAF15097DF1B522ADDFF7EE55DC7B +:10FC90008A922B2FDBF7DC26EC52629F2E577EFEDA +:10FCA0004BE9A44FF4B6677CED3B166F43AFE0FA27 +:10FCB000C2856BDC6F171506E4EA3C0927259F55C2 +:10FCC000DCC23C09AF797683804FC8EFAE28BA0911 +:10FCD000A58B50BC2B7CB21F741C433C16C7E3A8F9 +:10FCE000FB19E1EF24E1EFABD7D7E3D985214677C4 +:10FCF0009727EDFF45FCF96D23A0473C68203D4266 +:10FD0000DD77F4C8F7DAD5BD4796CD881F941BC3BD +:10FD1000C95EE891EFB4733E700C7C40EDFF613337 +:10FD20003B47418E9EE44774CCAFD3D046DF532788 +:10FD3000A5D37E1DCA3A92E4FD9C42E86FC6C0FB83 +:10FD4000D444F72D9AEFE125B87F39CF4EF7DCBBCD +:10FD50007D21EF53CB77CCBB99E40FF3D53BE67C09 +:10FD60003FF3765B1688F2BE77CC87333A476DC98E +:10FD70006559D0BFD4EFFE0CF88EF9B258B29B3E55 +:10FD8000F2886F24E4817ABF7A4A8A2771D2E02B05 +:10FD9000DFAFDEAA952EC0EFC0784789F9762E082E +:10FDA0007F668F00B71FF69E934D91F46EB7A253F6 +:10FDB00065E71EE6ED7A18705271B57F96F4A6E0FD +:10FDC000AFE20AE342F0A0E8CE6B6614870B7C201A +:10FDD000CEA8EFF763D648FEA2E23A5F763991FEED +:10FDE00038D5933B09FB70058733D9D13BBF87F5E5 +:10FDF0003E7A47A41BF33B297FD722745F154D320F +:10FE0000287F31C50D944BF956AEE2049AF4710285 +:10FE1000A1EF9C860F2D9D0CB89DD3DE1E838FAF66 +:10FE2000FF6F63BFF74FAE9D24F84466A267C624F8 +:10FE30009273D374FAE4EBB99FA4D0EFCC5C3E3A52 +:10FE400014F2EF9694D2EBD0AF2D53F80FFE9CD462 +:10FE500049711E7F5EF0D714B23FAF11EFB37EDB66 +:10FE6000795E19D72CE861D562712F319935121D51 +:10FE70002706E2656D98C7FFB4B8E640DCF15EFA8C +:10FE80007D91979BDB324E0FEF07EF61479E75F236 +:10FE9000938DF7F0CBE514F71B7D64551ACF6F3CBB +:10FEA0007CB49CE27C938F5C4CE3B8B9F7F0AB2256 +:10FEB0007FF5918B880BDE74F898A80FFFC110C6F0 +:10FEC0007E72F878B997E3E38ED19EFB81AF9B2FCA +:10FED000351E8338FEFDDA398BD328AE75764AB6E7 +:10FEE000886B5D07BCCF8B5FB43E5A0BC4B5EE9BED +:10FEF00024DA755F10FBA0FB82A0F330F083C1FF12 +:10FF00007CAAE27B151F1E885FAA7DF8AF8A4F5638 +:10FF1000FB99ED716D348318BDFF74DCF093936829 +:10FF20005DFAB8E16E73CF63E457BAC09CE013AFDB +:10FF300044BEEB84BC682914718D5A4F8713F73186 +:10FF40008A0A44BEE54287137C1E79D8B7BA634457 +:10FF5000BCA38A8B6DB9E04FC23E2942FC22AF5F41 +:10FF6000DCD3530E3E5A84FBBC69E8FFF851391EBE +:10FF7000437FBB2E88B8C36E5B87D321C7413F7CCC +:10FF8000DC34F0C7A2D556BA77D472A17105F55307 +:10FF900066EF1B570B19D7FAF5E34ED782C6CDECA7 +:10FFA00015F19D18D7A91BD74F71C1BC3F8A3FEDF2 +:10FFB0008E7125E2DCAFF2C528E7F987E4EF54142F +:10FFC00039FD46C8011527956091EF71CB730BAFD2 +:10FFD000477199BB7AC53ACF37FB6BB09F8A25DF53 +:10FFE0002EB608B9C90CE12EDCC72E315E3E9E8CC0 +:10FFF000F3C90BE27C521C56BA1DFBB1C124F80DAB +:020000023000CC +:100000008B53BF97D6B1ECE7BCDEEFE293E9F7C5BF +:1000100086261E6499381F2F9F9903B9C1F5EE33C8 +:10002000C0F7EF58AB267E874BB49F3B3382EEA1DF +:10003000741F1E5188FD3327CCF91CE3FBB677D221 +:1000400057B44FE7443B0B71E2E93DFC5F229FE070 +:100050007C0EFE5D2BFB8AF473E5AFBD25E0AFFDA2 +:100060005F18A77EE6398BD0CF7AE89DE6FF9A2409 +:10007000DEA7E3FA3BE91F3DD7C97737739C852894 +:100080004F35F744016EDD974DE2DD5AD6137553B7 +:10009000907FF6B176F19E6D285D1F9E2CE4C0F234 +:1000A0004C3BBD77D69068B552DA7E6106FD1E8C5A +:1000B000A93413E703B7A57FBBE32F260B7995B6C9 +:1000C000C112F0BF73F9E10E672AEF65E318DBF1A7 +:1000D000FDF0BEF317448C65B83C8F79131F2F36A3 +:1000E000E9EABB51BFAF9C8967DA54FB9C97ED8F5F +:1000F000AF33C9F180E725E2FE44A8BC689812DB63 +:10010000F75E21C9DD381BDDBBCA344A7B1EAFEB6D +:1001100020BBA0F0DF26FF878DE2E876D9041D66BC +:100120001A44BACB20E37DA5BD4F9D637E3CC53309 +:1001300069CA60EAC74FFD18F7E742AF48626D34FD +:10014000BED2CF543DAE87D988C9C8DF7B2B321AC7 +:10015000FA85E73B93A7964E2E045D7BD947417203 +:10016000E27C44545330FE1A8C7ABBE73B93A75190 +:100170003BD5BEBE693AFB88E211FD443FF59906C6 +:100180003AB73618D9ABF4BB03AC83FC99AADDBBF4 +:100190009C4F7E44EF36B8297D8FF3CB8FE8BEDFCE +:1001A0007C4A3F68F6D0F793CDD594763637D2F7B0 +:1001B0000F9B9B28BDF9D6C802D0FFF2436BD947ED +:1001C00041F2B1BECDEC09BE5FF3EED4FEE9E8FB2F +:1001D0009385DFE6DDB4FECBEF57E593053EBB1715 +:1001E0000B3D93D3E53A47ECC0FA4277A4B897F0B9 +:1001F000D234717EED4E12F9C6C9E2BD50B7816DA1 +:1002000043FB97A65928FF6EBA81DE7570C78A7EB8 +:10021000DFCD32909E76FD8CA90D80933B9E7FCFE3 +:100220000BE4DFBD4A94BB8788EF6ABEAA7CD294F8 +:100230003E3B4296381F0BFF3BA777EABF0FBFC577 +:10024000627EA1F5D57DFA5078FC56EE5BDA17D0C8 +:10025000DFB10FD282F6458393F685A243457F0D29 +:1002600053C47ECD0C9374CE6517C10F320CE7E3F7 +:10027000041BF907DDF05FF0F5EC92F1EE57EC07A7 +:10028000E90F50FB41ED0345EFC97C9F097F87587B +:10029000C72463FF76FA87268B7577C447927EDC86 +:1002A000DD6E7640DE4C320ABF4377FBBC02DC0BCE +:1002B0002FB9DBDED81FFF7A53B6FFA7E1A0F8C144 +:1002C0000070B862FD1669B7FF07D74FFC0D7C7B45 +:1002D000B1B897194AAFED9395DD5DD0ED3B93DD55 +:1002E00007413FDD9ACD84734AB7ADFF7BE42F4DC4 +:1002F00013FB42D14FC31426DFA1E1EBCCB892DF50 +:10030000A9F5F4AD732923BE9729E38D43F1ABD64C +:1003100015C4F75E9F3C38004FC6B8BEC2FB195AE1 +:1003200067A773AAA2DFF383BF5A02F9357FB253DE +:10033000F8990C46F91EAC90277DDF3523C55D0585 +:10034000C91906BDA5E7B0F0C7F9F93909FE2CD8DF +:10035000A083E3AE2D53C4BA7BE7171A602738FF9A +:1003600017BB1772EBFC909E93D04BCE6F13EF9D93 +:10037000F31E6769B83782F81F277EB745F8418CAE +:100380000F7F7912FAD092878DA4BF9CC7B199B71D +:100390005BFEA0F89D3B757FB04EB66BD976F166DB +:1003A000FA7D334E9FD07F3EB235A4432F9EFEF0A0 +:1003B0008327F0FEFA92E734989BD951D8DD79FE75 +:1003C000E3BD46F13BAB32EE6486BCDF5FB35BDC82 +:1003D000EFAF43BC09F497033BB6E2F727EBF79A7C +:1003E000998D7F9F8177D2F8384BDB22F94192F7C4 +:1003F000BB451F377A2DF36E803DB97ABBFE7BCDAE +:100400002E7DBE2EE4DEA23645FE9EC148964BF7F9 +:1004100013B7087BB1E2DB57EABB5E82AF7BA5BABC +:10042000AFFB05BDEF6D3CFC65EA8776919F2DF330 +:100430005D3C7FEE4B017F05B706C9F3CF25B18246 +:1004400036BEBE86C33607EC000D2F083BC1F9B699 +:100450006882F3F2F04EF22BB0178D0EE861F71CB4 +:1004600032925DA1BEDDF633FC2E6DC3731ABD570B +:100470005B7F28CC27E0736109CA971EB2399C289C +:100480007F318CC1FE7C9EE30DF762CFA77412FE14 +:100490008157D825F8DF2CFC7E85C2BFF161E14F82 +:1004A0005EF284C4CFB65526C2AB4F63096957E2EA +:1004B00049E1F95786A7FAF08476D31FFEFD7189CA +:1004C0007786789BA3DB2AE9773114BE2D873F4AD4 +:1004D00085DEABF06CE478FEA16AEF94EFE17D0D70 +:1004E0009EAB8167FB3F8EE73F423E1692DEFBF1FB +:1004F0004FA1F7465AC88FAEEC1ACA6E31B8F6DD76 +:1005000063717CE0E189CF929E5B1E7BA67E052312 +:100510003BDAB5536047BBEE0DFCAC2FFBDDF54F6E +:10052000E5823E5ACC9DF4BB31DE18F1AE7C77DA21 +:10053000ECEDCFF3F18A63BF4ADD8F7DF37218B91A +:100540004FE6CA7D893F6BF0BB80ED36B2B7D5B7B9 +:100550008709FBDA01BDFFAC3B49FC4E5F89A5A7CB +:100560007C05F472DE1FC651E7C1DA76F9FB2FF283 +:10057000FC56ABEC0CFB42DE8772BC41F5EAA68868 +:1005800078DB8C84494EF0A19605CC139EF175FC66 +:100590009E11BF57BF9737A01E3800DF57FA1FF3D1 +:1005A000EAED1C8AFF2C95BF2FD9B73F64BE7AAD08 +:1005B00037CA6A24BAA3771BEA1E15BFAFF809E849 +:1005C0002E2A404F0D323EEDD8F77F63C2EF3475CF +:1005D000EF12F7233887DC8A7BFA67DB443C5C4DFB +:1005E00041D718BF13BFD321F8D0B27D9ACF99D687 +:1005F0000F1D31DF06F1AE7D083DEDFBFA770FEF01 +:100600000DF091517FE7F0DC51C2A4DCF2F61B3F04 +:10061000D927BF427EC7E37F5A3C776F0E5FCFD7A3 +:10062000F81BAF4DD4BFE3729D53FF3B4DDFC9D6DE +:10063000FF4E53AF5DC247EA834A4F3D3445C8F190 +:10064000D054C1F706977E1C752EFEEE38FD78B3A8 +:10065000DDFAF1BE2D5EFE5571ADDF04BFE372DC45 +:100660001372DCDFC871FF5938A974A0F1FE7F4D09 +:10067000FF0F822563C60080000000001F8B08006A +:1006800000000000000BB55B0B7C94D595BFDF7CB0 +:10069000F3CC7308210904C2242421608803245464 +:1006A0002B94C9D300D6065C2D68840152C83B80C8 +:1006B000B5D2D6FE3208222F5BA8D1A2224E82E10B +:1006C000A1613B118289863A286411AD1B698BFDBB +:1006D000FD56DCF828F23213A374E5575DF6FCCF23 +:1006E000FD3E321942B5DDDDE4A737E7BEBE73CF6C +:1006F000FB9C7BA929CE317C394588DC9873E69E2A +:1007000008215CAB7A8A12B385E87B43154D0E2134 +:1007100084DB7BBC3E5688DA8EE1625332C1257D94 +:100720006F1A00B78DB36FA2F18DED7F781BE3BD1B +:1007300007558785C65F6BFF280AFB5CFC325C8827 +:10074000E158F7519420B8FAB2C2F0261A77103C5B +:10075000AB5515FE4CDACFE83363FC62AA0E7BCDB5 +:1007600082DA929656730FB5557B5B79FC0D9F69C3 +:10077000F0F8DEC641E376CCA7B6CAE88DB2537B6B +:10078000BE5DDFCFCFF3AB53159717FD7BFF10B7DF +:100790000CF35ADE895B4AED15FCCCBCB6FDF4D0F7 +:1007A0000B996E5A57D341FB440CEC53D361D26082 +:1007B0008977756A6B510CD14BB428228D9A8B6264 +:1007C000AB584DF4AC6A6FAE16D45F95718F49107B +:1007D0005D023EB518DFA71F8388A37576FA8BE804 +:1007E00077D1F779D452DAF755DFB1DB5DD4063A29 +:1007F0005F8FC2770307697EE6003ED35D44BF1C6E +:10080000B4662146D0BA83AF4739687CA3EF7549F7 +:100810006FA39FCFFD9A0607A8653AB7AB7CEE8A17 +:100820002F55A6BFBEDFAD2E95F799D59E168973BD +:100830009DF4C9EFCD7539647FEAE232E07F226131 +:10084000418E9ACC78BB000726CE69DE44A854F9C5 +:1008500068DFCC6BE9B654DBB7CB24E6FBC0B7D47A +:10086000035DA3483E4E140F9F4C2357E7DDE33250 +:10087000F0BC22B33B7505CD3B19E188B4D37E0FA4 +:10088000158F8B045F5F438BFEE25D6637B595077E +:10089000E5F74EDABBA3206F270F4E553DCAC07E49 +:1008A000776ADF15C2C3ED00DF3CCCA7726F63042B +:1008B000F619E09FEC9FEBB2F3FC13DE77EEBA87FC +:1008C000CE773223DC09BE749945B98FE5843E8228 +:1008D000EF752636820EFAF7E6821FB42E9061601D +:1008E000BEF6B69BB479F7348B41F34CCCB78BCFC3 +:1008F0000DC6C7EEFDE097F7D0FCEA675461A1EEA4 +:100900006AD38A389CFF931D83F12BD7E85C6DF284 +:10091000C7C505C96B75C7557D8960F9EED0F5C3AC +:10092000C1FCD4F978324395782558BC8250AE6E1C +:100930006D66B92675F3D8A6702BECD4268677277A +:100940002B74FEC407ACCEB584FF738A366EA03616 +:1009500086608384CDD45AA97DC624FBA1B6583FB6 +:1009600086D8A9106C2A1E976348A17DD4D6C9E009 +:10097000EBAB335D8FBA088FCD334B66CC043EA210 +:100980006F99A06FD65C8AF08868210AD5F79EC05F +:1009900077FB0F9A04EC478DB5A3F26392D37E27C1 +:1009A000290AE1DDBFC3E4F5B0FCB9229469422C09 +:1009B000BB49EACD270EF734751CCD5F63E0F355D4 +:1009C000B7A85E1BCDEBAD271210C93F6D4DFE01E0 +:1009D000E4B5FAB86AB7D2B9F37DC9BF9A0EB8C503 +:1009E000E4B4D0FA5A1F75125CBB57F13AE4FE0228 +:1009F0007A597313CBBA3863AB4D1159D4AEE9337E +:100A000063DE99C38A788CE66D0E8B6A02DE3599B7 +:100A1000B3CF2951D4AA5BD627D27ECBB79B3EEC6D +:100A2000B1CAB557E8BFBACE6D2CB715DEC1FD55BA +:100A30007B07C335C23800D3FECDF8E36621DA5C0C +:100A400091B1676EA0BF2788095754D0697A3CF4EA +:100A5000E104F84AF2241A88D82385B86F92331E2D +:100A60007ABFD1E8980D3A043A4D76D0ABEEF081DA +:100A70000AE0EDAD0E731AE8A8B5AB5F61BA06BE29 +:100A800020BADF486D82E0F30784A46FA05DCA79C5 +:100A90009D49F15AB19E68C8FB5915EF1A1A0A7898 +:100AA000FAA3D83E09510CBD58B520C7003B073505 +:100AB0001684CAAF747D506C46251AADD4FFEF1969 +:100AC0007BD4614176E23F5D298C7F8159B87DD42A +:100AD0007F5FA4331A723FD61A9505BCC65A93BCE1 +:100AE000A0FB5863DF1A7C7FF328C5F1106D7D24CD +:100AF000EBE5C90AE0DA0827E44449586C043D36BE +:100B00008F5A6C84BC8FB5FB324A3207E0028C43AB +:100B10001F8497BF5714E136E23BCF8D54FC06DAB1 +:100B20003F6023FCA02746BB09F8054C121662CD96 +:100B300020FCC82231FCFF8E9F9DF08B18C08FF8DF +:100B40001D8DF59F67137DA84D9A2B4437DB8515C6 +:100B50006C17747A5E24792F205EA529526EAA77CD +:100B60001C29C2788DE85E8F754551F21C45380FFF +:100B7000E030D9AAB9925FB95A7B7FAEF42FBAFDA3 +:100B8000ECC8751973A9DD9E5B62465BA866C6F763 +:100B90000C61EF5729569693CF49FF608FEF5DA107 +:100BA000D8533306E45BD7AB3AD975557FAA7EBFDD +:100BB000CB2C52F0395777068D970BA9D78B56DB84 +:100BC000ECA9C17A043D237A94DB2B6E13A46FEE5B +:100BD000D571F6D4A9D4AF5E340BC89EA65FB1F42C +:100BE0007B256508FDF285E865FB60D86F9372EEA2 +:100BF0008F54BC6B09FFD4DCC17A97A4E941A35B95 +:100C0000E1F3357E6564D853AA7841F33BA9737547 +:100C10008C7638CC2BCFF5C23FDE496029FA1B62B7 +:100C2000594F7990ECD7BF68E7BCD3E83F02FB711E +:100C3000CCE44BB6D3D0B11AAB13FB2F1014E89011 +:100C40005D2B15DDDC9E0AAF6DF3F3E69E3190AFB0 +:100C500077DD1627E2B0C6754D91B0E359629DFD70 +:100C60004C06820AB1F7CAD4EBC7332438E28CCEE3 +:100C70001738628A53C06F9DAFDB735D79B939D77E +:100C80005F5FF5A7B6DBBF03FB757FB3395E8A49AB +:100C900077C6B401BEE97CAD131EC65BE7D755FE2F +:100CA00011EEA3410FF5E25CB633CFAA82E30A8DC1 +:100CB0007F56FA1D8A7F3A7D676A7C58DE21ED51A6 +:100CC000285F757AFF9036C4F7C98FEE607E080BF7 +:100CD000DBBF50BE7F135F28C22CC5507EAC458061 +:100CE0009F8906691F1397919C10DEF708F7E11E94 +:100CF0006AEF0A7FCBC472A8F1E75EF087A6BE2B2D +:100D0000BCDFCF48FEBFE34F476EC903C17A18AAC4 +:100D100077D7D3B36A87F3DF75BF479686F42B4442 +:100D20003F43F44FE7977B7514EBD9553EAA2D52FC +:100D30005F357E45D0EF90FA863FE87B35ED8AD768 +:100D40009FFC2DF44F21C4896F8F85E89DCE9FEBCA +:100D5000D91DDD4E9D16FE63763AFFA9141907785A +:100D60007E62F136034E3794C3EE9D9A28DB039AD8 +:100D70007D0B6D4F539CA3901FDB94717204FCF5A7 +:100D800029B3BE8FCDDB4CF89F5ED33D6625AD3FCA +:100D90009D2BDB53880B836057985804BB7E7AA445 +:100DA000C5033A9D5626E4C13F9C561EB85DC2F16C +:100DB0006607E005F17976824F99E47CDDAFE8F6CD +:100DC000FFF482EF14F03C451C053D1C8A28E1EF3E +:100DD000284A4C31E173FAFEB4296BC5C0F99B7205 +:100DE0000DBCCEABD96FC283E9DEF753C5DB445DE2 +:100DF0008BE05208FFE4BCDF14A750FFFB3F1B371A +:100E000019FC75AD1AFC7DF8EBE41B016FE37DBEA8 +:100E1000F7659F6971905FBAEA270B3E93FD6539CC +:100E200006E84BB9C64357CC8468F0A7DF3B2E1ABF +:100E30007E47F743FDC70F44B883F8768EFC9418BD +:100E40001F044F783429D88F1DD9BD391DFB949BC1 +:100E50003D594EEA3FDBF87412E28DF2DD8FA47348 +:100E60001CBC7B633AF299F2A6CDE92E86C3DD9CC9 +:100E70004F19E5B92FECBF79D7A6A0B8BB2A5F659B +:100E8000FC4BAD470AE16F67DFF0E9C3769A97F64E +:100E900033C50EF1BA57743F0CFFB810F131F2B7F9 +:100EA000062BDB73DACF05FE374FF8FE73D0E31362 +:100EB000191F99CA68DEE55C23D367A1F06E89A784 +:100EC00071B141B1378BE0F9631A317FF13AC59CBA +:100ED000003BB062D864D58175C3188F251B267777 +:100EE000A17FE183B27FB6C57BF024F6F98DD9D915 +:100EF000EC607B9352326900FFCBB9665EB7688BBA +:100F0000C2F1BFFE9DB427E21A83CF7959E3BFF83F +:100F1000CAA2802F3FD0F872DB83EF1C4DA07DED7D +:100F2000B1EE2BB01B6F3F7E26D54FFD0531E7326A +:100F300021E76966F75315387793C5897364672588 +:100F4000AAF1347FCA8F731F43BBE8C1C54F55C098 +:100F5000DE6EB772DEA6E3B74A711A608F5F6FFC70 +:100F6000E112D0EDECE3568EDB57358E8F1743E858 +:100F7000A9DEEE21FE3B28D1D9576FE5F6857ABB75 +:100F800070903CECAF4F60F8B7F50E6EC57C295FF2 +:100F9000ABB4FCF87AFB4DFD325C38289ECDDE60A8 +:100FA000130EB2534971AE517974CEB489354D1BCD +:100FB000B573A5D1FAC99EE47CD0217BE3CA2E8407 +:100FC000BCE63C998FBD797243128CF2F2073FD890 +:100FD0005941E373F34AC6E551BF75C7675C57785B +:100FE000BDE39185A0777993459E4F3BF7D9C7D351 +:100FF000E39FA2FD3D6F9838DFAFDBF1C1CE8DD40A +:101000002EDDB2D21C2CEFDFF6BCC91A3EDFA4578E +:10101000D7A3C33FAE579B93587F9A48AF32FF790F +:10102000BDAA7B700DD3EF81BC92D9A0FB59932749 +:1010300009FA7476C20C9673CF6185E9AFDB717DD6 +:101040007DB176DE2A836FCBF4E4013B7E496433C5 +:101050007D8F747C928EB8F752FB82BF7BEE437417 +:101060006E3F9DBB9DE8EB1F7FEDF834B37B9C93F7 +:10107000CE37CD20E3DD6BE2D63C83562FE83697A2 +:10108000444A9A2BA8CB68FE93FC98279AF0A9EEC5 +:1010900054FC6159F067B79E3322DFA3BCF1C3E073 +:1010A00038827E3E0CF2DBD7C3F79BDA5AEC9336DC +:1010B0006077BFF36783F007F9E99B7BC2843FE861 +:1010C000BB57F313EA33139F7A3B46B25D00DF8CC4 +:1010D000A8C7754C68027CCE2CF9D87B88E22659CB +:1010E000C711EAB481739EEBB890053B1B7ADEDA38 +:1010F000972FB07C54B73FF299C2E79F75CE98F511 +:10110000CDE73FB2FB4216F877CED4330DF956AF98 +:10111000B9270B7CA87D45DAF37F940E7A7FC5064C +:101120003A08E979AD62653929542F72DDA0F7B824 +:10113000AC1BD476EC627BDADF29EB377586EEA246 +:1011400078D43B567CD0057BD69F20F328DADF0588 +:10115000BA4D1FA7F941635FD25CB26B2F5E950752 +:1011600099FF9D85FE8EC73EBE6AD80191152E104F +:10117000579C873E53FFC2D5C9EB21E767BD23A625 +:10118000C03EBE99F5B75AAEF7BD1A6E5739EEA1FB +:10119000DE20FE5D3D875715AE41F58070E10A9A6D +:1011A000576776FC80E3E313AA405C573751EA9314 +:1011B0007859EA53CDBA23E684A0FD76429F186F92 +:1011C000192FCE7EF56FAC975B66BA3AA197E1B066 +:1011D00085D82F21DAAB28DA3CE27FAD864344A7DD +:1011E00096F717AB3C5ED7AE8A91589310E94DA3A2 +:1011F00073148BAD46C4D3B3856F3AEA36C2D8F3C5 +:10120000CB5B687CCEABEAD44D82F3A745259C57D7 +:10121000BA5357213E32281A5D7DD97383FD599EFA +:10122000F453D35585FD58DFC8708E5366CDAF2972 +:1012300005BEFABCAC61721EEDC37196F0F665CDC9 +:10124000857EFAFBB2E6450ECCBBEBD5F015EC176C +:10125000852FFBAEA0EF84E5CBFAE8E7E447202733 +:10126000759764BDA350FDEA09C4E7AB0E93BC209B +:101270003E3424BF6B801D273A83AF1788AF2EF80A +:101280001FB770B9A03F934678A13F75FB15614425 +:101290009DA8C3D2843A52ADA9270EF2BCB1FD4F2E +:1012A00066C8735DDB3B66C724AC9775275248B6AA +:1012B000E3759AFFAA691FFF2EEA7C35C7A517AD13 +:1012C00031BEC3F97BD5C156CED3AB859FF3F4EACB +:1012D00096C1F2D29FE0E0BA48A87E84E53B06E9D9 +:1012E000C5ACED522FEE52C50AD839A1D569672594 +:1012F000C4733C32B04EC6BB2EF5C2C3885F022910 +:101300008A53A1AD02619E75888B3CE9329E09FC2F +:10131000EE85EC656C57BCD977D0B9025ABC3B6BF3 +:10132000C336A31A84CFAC4E59970C8489F243CCB0 +:101330006FF768F041B84A22F27358AFB2605703B2 +:101340000659470D3D47BD562F3A817A52E600DED9 +:10135000731213A51D135E969F2E83FCBECB40E334 +:101360005306D62FC997EB07F2215907BB9E5DD9CB +:101370004DFC2923FEEC253EA37D9EFC7119D999D5 +:1013800016F2C780FF95FC315A5F7D06F7BF58EF14 +:1013900064F860FD4D0C1FAA7731DC5E5FCCEDCBAD +:1013A000F525DC7F02A87E17FF7BBA11F2D0051D60 +:1013B0001B35009F8A0981470D9E7F2A46190C8F95 +:1013C00052787E76FED38D1ED48B66DA35FD764458 +:1013D00022FE3A6B9375A8B33659876A1DE5BE2580 +:1013E0009FC6CB66ADDD2DF350573AE615C42CE011 +:1013F000FCB59FF257D8A395F9EE3CF0E5F8F1FC67 +:10140000D46D6C276D5C073D75F70DD15C077C834F +:10141000F271FA746EC6D475D904E746282CBF64FD +:101420002F6E2CD1F34ADA27BF53DEA314AAD56559 +:10143000D87FD548DB54D8DFCF5DEEDB80874EEF19 +:10144000A251CB53110F75991CEFA28EEBF9BD4938 +:10145000209FD2EB7DFABC0E57EEDD58372B63DCB4 +:10146000BA29B03BA464B0732EB368015E2E43B8B2 +:10147000B296ED96C3083B70B726C7790E1917FBD5 +:10148000CD0E630CEA3761B9B11E5AD7A5F1F9B890 +:10149000C6E7131A9FDF429D8CDAB7A91F6D37F597 +:1014A000A39D01FA4A7965BA3D915752C6F22BFACB +:1014B0009200EB75C1D9D02F696F9220D75B34F9B8 +:1014C0004DD0EC4D576E49955CE7E37DAAB47ADBCD +:1014D00005ED1E443FAFBE6E60BDE076DE8DC2639B +:1014E000859D7F49E69D6234C52304CF7B299EED0F +:1014F000906ABD23F363D2F37953651E200E58E43E +:10150000BC04470EF464AD566FEDF51A3C26D4A723 +:1015100063BAD363E07F35FDD2E143FFADB2BDAE28 +:10152000994230B5AF28F27C35F3BAD38761BD62FA +:1015300033707DBB498E9FD4F4AF2645DB4F3B8F84 +:10154000B0FA92C08FC0E197929610BC29C2BF4CEE +:10155000DA7D7F3ADB6BE14F9F07BBA8F8DE174EC1 +:101560008A2B0BA62E318E043D7C3B015717E42CB1 +:1015700031DE8CF1D6F7EDC1E3237C498A1D70B6CC +:101580001C1FD1BA7398330836BDF83EC6CD869C71 +:10159000250504CFB1788FD7436E7E2BE5CBB6BF40 +:1015A000ED0CE856D521E3F6BCFD6D175F845F6E48 +:1015B0008B74C2BCEFCB4F667AAFEDD8B305F2D6D1 +:1015C000DB2AEF0336B5FC69E7CF799E05D724B453 +:1015D000AF2F5BD077561EFDE362E03527DCF705C1 +:1015E000E0878ECE643CE70C977AFDC8D1BC25D04D +:1015F000D3DEB6FD3F81FECD89A68016F8BC60E340 +:101600003A44E5810905D0D3DEC8EE85D8BFF67926 +:101610008B13725A79203E0FF58143F9B21E5E3169 +:10162000716B12FCACE1E57DBB7F8EFBD5E76D7C79 +:101630002F541723E3BC4AB571DA4AE6DFAEDD4F1B +:1016400003EF7D36BE9FAD40AD8AE08ADD695CC7A1 +:101650007FE5EB8F16820F85EA8EDDE8FFE2399B8E +:10166000017438697645CF801E9E3471BE59A1C180 +:1016700015A7864B7CC27B8A987FB15B93E0672B72 +:1016800087FFF476E03D47DDBA13F98ED863E1BBFE +:101690008973FB886EB4EE5CB3690AB8DCBB2FD2E9 +:1016A0000879B9A06C5DF814F66F96F32ED8B632AF +:1016B0003D3DCDE305BE47F304ECD60565DBA0FE5A +:1016C00073CD7BB2908F9E7F7E0EE7A5BAFCEAFABF +:1016D00052F99C65905F644B40F6A852FB5BD83D85 +:1016E0002282FC6D85069E3FF464EF536260FDF933 +:1016F0001693DF4C34AAB08875D698017DA84CBCEF +:10170000B518E7AB3434A6236EA998DAB3107A7112 +:10171000CE26AC0934EF4DCD6F551E5C3317F1EF7B +:10172000F5F0B9A2D9A34B09D27F5D6AB77983EFEF +:101730002543DBF7EA85FDADB401F8DE15168EE131 +:10174000F5FDDE34FBAA91A7D5C648FBF13ECD6F6F +:10175000213BF6B5E6EF16AD1E3CBF3F3F86BF5FAF +:101760006BEE4987FFD3F70FE46B7EC3D8930E7BF4 +:1017700015BA6E0EC211D8911714B6239507950F9E +:1017800054A253A5D5E355411761D6CF69BCA2C871 +:101790007509D334BAD3DA0D05C9FCDDCA169BCB63 +:1017A00046EBAAC27AA210175547F64421DEE97D1E +:1017B00059154D1ABB62E334FEA4682C0BAA3756A8 +:1017C000F84C2E5BD6107C46FC44F396E36FFAFE91 +:1017D0003305297C9EF2F670FE9EB0F74C839C96F2 +:1017E000EF18BC0EE7B207E95F6FFBAEB8E0BC3C98 +:1017F00045C33BA07CC07A12F8FAC324F0BDD220C6 +:10180000D6E1FEF23CADC1BD26C1C22A61BEF7AC35 +:10181000FC6B4418E4E5FCA56AD6DB5EA587EDDA2F +:10182000DB0573D92EF59A7AD8AEBD7EF42EB60FAD +:10183000BDC37A16C24EBD5DB05C8E8FEC59E8A078 +:10184000F1FD3A3C46B0DF7FEF680DDB8F39AA7CB3 +:1018500057217699ECB21EB4E1543DE71726477044 +:10186000FE7DBA40ABF70CF087F32E5D6F7A85638F +:10187000FF41E8617904D775288E6A7911F1DE821B +:101880003827DE6B94639D940373F07D636CCCE525 +:1018900065E0CF1DA3DD450539B8DFECE13C82A44E +:1018A0009AFD4DEDEF2C9C4F064C7DBB61A7D247B6 +:1018B000BB6717101ED5E6EEF5D984D245534F17F6 +:1018C0004AE4B355698FC41E2957BD99BBE43D8DC9 +:1018D000765F79B7467F41494C23E44291FC7DBD58 +:1018E000FDC05BB02BBDDDE3D81E87EACDB9F6C7DE +:1018F000A2601FFE4C7EDC1394EFFF79F11EBE67E1 +:101900009D8FF720D42E5937581EFABFBA83F33E65 +:10191000B125A81F72D830180E9523C8A37F90DD7B +:10192000F130DDB76B7A5595D75D0B3A5C85E711E1 +:10193000AC06C1AF85C021F345898C13B6C3FF1334 +:101940003DAAC7F84F719EBEDF2460C7D792FF62E1 +:10195000B82DDC8B7CC5B09FFC53ACF44FF00B551D +:1019600051DD5C9FEA6DB3F07DEF431D9F24E1FCE8 +:1019700024875C87A9EA78290EF9FB3E2D5F203F7A +:1019800018C7EF63DA3AE29077E8FDD5065F3AF0E0 +:10199000A28888E375BDBF46F5A703FF2AA53B0BC8 +:1019A000E3FBF2EDDA7C8255C082CF51AD487D1762 +:1019B0001D2ADBF350BE3DA9C92BD9852C7EDFF152 +:1019C000B2AC0FE876A042B327AFA13F53EABD5DAA +:1019D000BF57A2A515D0F721EC4342811E17AFE0F7 +:1019E000FACDE3050E096BEB795F595FE2F1DA5747 +:1019F0002E64A564629D362FD80E8D1BB02BD0FFB0 +:101A000004D6FF874C7174AECA9D8A732DEC54E9DD +:101A10009A229A2E961B571671DD4C78386F0BC59B +:101A20002B548E2617483A551A8615C606ED779E12 +:101A30006C7AC214B6337ED89D1FC53E5A843AC50F +:101A40000F4BE5BB81ABFE2658CF719E1DD28E4356 +:101A50006DAE18AE95E3E52B1AD7C70F8147289EC8 +:101A600015EEC6A238C7B5FD3ABEE76D3A7E79A637 +:101A700011C17498BFA66804B5CBADFF2C1DE479E5 +:101A8000CF7758FCF0AB15A52BD7470F2137D7F8E8 +:101A9000831D41FE2B05FCF5F2FDC6F5F00F6DAB85 +:101AA00015FF29D48B04E95533EB17E94B905FB848 +:101AB000B920A4EE50BE782CE26AE15E3C167E8628 +:101AC000F46AA17388FC920CE42803BF19F1701B1F +:101AD0008ACF5F0AE4BBA49B0BA49E6F99E90AC05E +:101AE0006ECE500D1C8787EEF765818C27BAE322F6 +:101AF000EFD7DF7380D9335449B74443FFDBD0B706 +:101B0000C4B84807EE830AF3C3E5BCC3363BEA37E3 +:101B100081C397B9BE1B783862BEBC378810236971 +:101B2000BC2B615253B01FF975A13C6F78B68C5B2A +:101B3000EA324C7FBF3E941979B53EC47143663892 +:101B4000DF97F4B67FCE7E2BD09963C7BD466F3743 +:101B50006587A44F755FFF571CFC6B6FE75FF81D2F +:101B60005AEF579FF0FBB48DDAFBC0D7DAB5F75DBB +:101B7000DD8E48F4078A3F2AC2BC4D5A3B5027905D +:101B8000F562BDD5F35FBD1E1094078F2E1C3A0F72 +:101B90008E714704D7091CF143D55582EB04A9691E +:101BA000B24E801675825493AC1300469D002DEA08 +:101BB00004E8479D0030EA04805127008C3A015A1E +:101BC000D409D0FFC57CF95E2640422CEB97116CFE +:101BD000DFEF6B56BD88CFEF3B2CEFA1EE6B54F8D7 +:101BE0009DD645FA3EFCDC35EF750E6AEF757CDB61 +:101BF000F85EAFAE4D75825575A6BE63A8EBD4B541 +:101C00002ACE35B02FF5F3F9FB1B3B73DE2D457F54 +:101C1000B3C96970804F97E250AFAAEC6CE6FA53F3 +:101C200041FC6133F3B74511A897DE6591796E8D5C +:101C30004ABD53F83E94E3E01A4B37E71F557B1536 +:101C40007B59F07DEE4D9FB11D586B8B6A029E351E +:101C50003E9BBD6C88F71F7C2FEC1057EF9B97C9FC +:101C600029A226A288EF9B97E19E995AA17E65E45E +:101C7000FB634A4C87431EF1AE2A0366DD2EF53E18 +:101C8000E43D556567EBFA4471ED3D342A03E07F8E +:101C9000E8FDB3BB3032F64C380C85988CB8A9F807 +:101CA000F1B2FD6DF4BDFEAD168E3B56E6BB97431B +:101CB0008E8E995C5C273976D8C6F9D1C7DBC60F02 +:101CC000AA937CEE725717F2FDFC68AE5BAC32292A +:101CD000EC97F38BC7C5F3BB81E326F63F1DAE92AD +:101CE0005ACC5B35C9C1F5A9428BB89FF7D1DE69E3 +:101CF00051CBFA54B856F11A085E2C9C66E8CF22F4 +:101D0000221BCB8B296203DE532D12F27D832E37EB +:101D1000ABB6291C1770A1200EF79292BE8B3AFF2A +:101D2000ED32DE2F2CB5C8F835D120EFB31337C90B +:101D3000F72D3F126E33FCED72F28B68C94FFEAE89 +:101D400087FADDE1A393647CEE88C7FE8B4F98F899 +:101D5000BD6F61FCF7D3DDECAF0BF81D83E2BF472D +:101D6000BD72C3F5F527F41DC33193B42F4447CE9C +:101D70008BBA20975C9F71737BA2BE9CDB1933A545 +:101D80009DBEFA2E91786407FEE17DEF235F4C8CB7 +:101D90008F74C2DEE97A7FCDFBC430D9EAEF13C776 +:101DA000502B82DE276E713978FF44C3C9A90ED04B +:101DB000E3AF114ED0437FA7B86566C92EF0C915B1 +:101DC000253CF82EEE51B6125D8B701005756E9F96 +:101DD0004B45DDFAB062E777D1D7D8C96D0FE31D67 +:101DE0004F5DAA62571CA8876F2D8C23BC8B529223 +:101DF00019EFBA76592F650AC5A19EAEE983CBDDEE +:101E0000563862A07F8EA617BD345FCAC92D5EC842 +:101E1000DBB7A8A33E87F91E6173366BF91AF83E4B +:101E2000E786315C4FD5E5A6BF25BE0972F346A112 +:101E3000F433A5A5EF98100774E5BA8FE2FC0BCB3D +:101E40003E7B388ECF37741D8BEC28DF4B86D6B1A6 +:101E500074BBBC5BAB83C37E1AB53AAB51ABB31A50 +:101E6000B53AAB51ABB31AB53AAB51ABB31AB53ABD +:101E7000AB51ABB31AB53AAB91EB772BB87DBB7EC8 +:101E800035B7DDF51E1E0FB2FFEF5DC7FE87D641E9 +:101E90003FC2BCD03AA8B03AA2D98F927ECBFA7397 +:101EA00048DDB378F8920D44BFFC06B3135D7A1D8C +:101EB00014EF97EF8B607B70B170C8FAA74EB7082C +:101EC000AE97F60BDB14D03F2F639CD140E37FD558 +:101ED000F8A0D71FA11F381FF4032DF4C39836A014 +:101EE0001FCF984985B3A5BFF7B0BFB7315FD7AF54 +:101EF00021FB41F052611F643F2E86D80F4A3CEE11 +:101F0000061ECB3AE5BB26FDFD661E355F4E19C2A7 +:101F10009EF8A43D1913E6DB87EF8CA90DE3F7C10A +:101F2000C7B4F758C736CA777165A284BF3B845DD2 +:101F300089023F960EEF7BFF699ABF747304C72D29 +:101F4000EB472E9BF6BFB12B9F150AA6DB6FEAFD70 +:101F5000951F132E056152FE0ACC2203F735C210DD +:101F6000C67A50A86E51703FBAEA5E31197C2EB025 +:101F700094EC009EF1DAFDB688D5EAADC6EE8A3D56 +:101F8000049F8C4B74E25E6B74C22181F74F8575A0 +:101F9000C599B08BFE31EE09453978BFBC55C1FA01 +:101FA000F04C79FE3B8AC39B205781C3E373C0EF9B +:101FB0007916471BEA00CEA284A5C8F3E7453B7219 +:101FC000500770768D9270BCA34D7122944D585A73 +:101FD000C0EFCFAC5B3FB6E2DD9A22A2E95C96612E +:101FE000EE1C7CA7A6F85399378B3EF6633717C9CA +:101FF000FC6BC46BC28F7BABBE59917C7F26321DBC +:102000003918A7B8F2BB45241F7FFC9EEB16AC4FD6 +:10201000D4F08CC72DA20AAE76DBD09ED0EEF3BAF8 +:102020000CEE52B445511E23F71BBCD968DF34F8BF +:102030007E8C7E92E722EC57F4D8E4891904275A63 +:102040007C6C273B5CAE5BB1FFAB335DC5180FAD5D +:102050009F83B7C8F3099FDB302FF41D96CECFA521 +:102060004552EECB8AA4FD98BE56DEC786F2BDACC3 +:10207000C8A0D9B7BF8F37E15B8AEFE9F88BAD8B8A +:10208000B3810FE17B2FF0247C17625C44C470BDE8 +:10209000E3FA72E6E1EF951549F9227B56F5B1B402 +:1020A00067DCA61BBDC3103F8EFA857718F01DD5DF +:1020B000D867C3BFC378D6D367837F7FF6C13E1B83 +:1020C000FA9F75C977D2A1FB3716C9F713E9D3FB7D +:1020D00078FD58FA5637C7E97DC31047A5977FBCEE +:1020E0005EDEBB64B07F19ABF997B1BF4869EF21E1 +:1020F000791BFB6434DF6F8B82581EAFB44A3DAD51 +:10210000FC45D9A1366AC76F277C83E2AF095EC25E +:102110007B505C64EC97EF2D09069DF69A1886CCEF +:1021200022BEAA11F2BDE528CD6E206E2B25BB5034 +:10213000537EF432BF03C07AEC8F3B5BC85FBB4970 +:10214000C2E4AE918F2E9FBFA68BF3C3ED57FBB5B4 +:102150007CB3753DF2678ADF06F557961DE982BFAD +:10216000A9DA3BB8BF66C5679CC752FC36A8FFDE3C +:102170001F7FC0EF6CEADA07F7137F9F029F75FE9F +:102180001E33F92620DF3B5613E694FF7EC0B712BC +:10219000FADE541DC1EF6777FD3A8FE546E737ADAC +:1021A0006FFA76F2B196E77BF24406F4E19BDA5ED1 +:1021B000D8A7B441F6C9C375BED9916C77EAB4FC0F +:1021C000AAB6CCCE7E3EB1D6CAF6AB500D7302AEE7 +:1021D000354A3B238A55CD4EF958FF4FDE3E8CEBF6 +:1021E000797C00C03193F8DD71DC5A09F78DB0B00D +:1021F0007D28349454EFA1F6A86105DB8104BCB8B6 +:1022000024BE3F03FBA0427F655DB5CEEC53E4FDE9 +:10221000BE2307F9AE7EDFD4B0D1DB7A10F9B2E28B +:102220007D7219EA8A7746F0FD4100F5463A4FC3C0 +:102230003069471B16A4B31F088892D2958843E6DD +:102240008771FDB16198E351DC2736544CE438FACC +:10225000D07F4BBFDB37D7EA441CD530D9B106EF6E +:10226000551A7EE1E0F15714B99FE751499F86B9AD +:10227000F2FC0D15319CF7E87C6868748DC4FDD4C0 +:10228000CC31EEFF00DF4769F7730DC9D44FED1372 +:102290004AC9821F619F4912DF19331DAC77C716E7 +:1022A0004C7C74B783DD891FF74475B32307E5C5FC +:1022B000FF033C759D8B10370000000000000000FC +:0822C00005020D000000000002 +:00000001FF -- cgit v1.2.3 From 0c5b77152e736d23a23eb2546eab323e27a37f52 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 14:10:08 -0700 Subject: bnx2x: add 6.0.34 fw files New firmware files for all bnx2x devices Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex | 9476 +++++++++++++++++ firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex | 13178 ++++++++++++++++++++++++ firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex | 15442 ++++++++++++++++++++++++++++ 3 files changed, 38096 insertions(+) create mode 100644 firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex diff --git a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex new file mode 100644 index 000000000000..33b584c7c1ab --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex @@ -0,0 +1,9476 @@ +:1000000000003BB0000000680000070C00003C202E +:1000100000001AF8000043300000007C00005E3051 +:10002000000079E800005EB0000000B40000D8A035 +:100030000000800C0000D9580000008800015968B9 +:10004000000039C4000159F800000090000193C07D +:100050000000ABA80001945800000FFC000240080B +:100060000000000400025008020400480000000FD5 +:100070000204005400000045020400580000000083 +:100080000204005C0000000602040070000000048E +:1000900002040078000000000204007C1217000037 +:1000A00002040080221700000204008432170000BE +:1000B00006040088000000050204009C12150000E0 +:1000C000020400A022150000020400A43215000062 +:1000D000060400A800000004020400B8021000009A +:1000E000020400BC00100000020400C01010000058 +:1000F000020400C420100000020400C830100000F8 +:10010000060400CC00000004020400DC0010000023 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000060400EC00000004A1 +:100130000104012400000000010401280000000067 +:100140000104012C00000000010401300000000047 +:1001500002040004000000FF02040008000000FF89 +:100160000204000C000000FF02040010000000FF69 +:1001700002040014000000FF02040018000000FF49 +:100180000204001C000000FF02040020000000FF29 +:10019000020400240000003E0204002800000000C9 +:1001A0000204002C0000003F020400300000003F69 +:1001B000020400340000003F020400380000000088 +:1001C0000204003C0000003F020400400000003F29 +:1001D000020400440000003F020420080000021155 +:1001E0000204200C0000020002042010000002049F +:1001F00002042014000002190204201C0000FFFF6A +:10020000020420200000FFFF020420240000FFFF62 +:10021000020420280000FFFF0604203800000080B0 +:100220000204223807FFFFFF0204223C0000003FC7 +:100230000204224007FFFFFF020422440000000FD7 +:1002400001042248000000000104224C00000000CC +:1002500001042250000000000104225400000000AC +:1002600001042258000000000104225C000000008C +:10027000010422600000000001042264000000006C +:1002800001042268000000000104226C000000004C +:10029000010422700000000001042274000000002C +:1002A00001042278000000000104227C000000000C +:1002B000020424BC000000010C042000000003E83C +:1002C0000A042000000000010B0420000000000AC6 +:1002D0000605400000000D0002050044000000205B +:1002E00002050048000000320205009002150020BF +:1002F000020500940215002002050098000000305D +:100300000205009C08100000020500A00000003358 +:10031000020500A400000030020500A80000003122 +:10032000020500AC00000002020500B0000000055C +:10033000020500B400000006020500B8000000023B +:10034000020500BC00000002020500C00000000021 +:10035000020500C400000005020500C800000002FC +:10036000020500CC00000002020500D000000002DF +:10037000020500D400000001020501140000000184 +:100380000205011C0000000102050120000000021E +:1003900002050204000000010205020C00000040FA +:1003A00002050210000000400205021C00000020AF +:1003B00002050220000000130205022400000020B4 +:1003C000060502400000000A04050280002000002B +:1003D000020500500000000702050054000000075D +:1003E00002050058000000000205005C0000000843 +:1003F0000605006000000004020500D800000006A9 +:10040000020500E00000000D020500E40000002DE0 +:10041000020500E800000000020500EC00000020DA +:10042000020500F000000000020500F400000020BA +:10043000020500F800000000020500FC000000209A +:100440000205000400000001020500080000000190 +:100450000205000C00000001020500100000000170 +:100460000205001400000001020500180000000150 +:100470000205001C00000001020500200000000130 +:100480000205002400000001020500280000000110 +:100490000205002C000000010205003000000001F0 +:1004A00002050034000000010205003800000001D0 +:1004B0000205003C000000010205004000000001B0 +:1004C0000406100002000020020600DC000000010B +:1004D000010600D80000000004060200000302200C +:1004E000020600DC0000000002060068000000B800 +:1004F0000206007800000114010600B800000000A8 +:10050000010600C8000000000206006C000000B8F0 +:100510000206007C00000114010600BC000000007F +:10052000010600CC0000000007180400007B00005A +:100530000818076000140223071C00002A1E000090 +:10054000071C800031E60A88071D00001DDD170228 +:10055000081D4470577202250118000000000000B9 +:10056000011800040000000001180008000000004D +:100570000118000C0000000001180010000000002D +:100580000118001400000000021800200000000103 +:1005900002180024000000020218002800000003D6 +:1005A0000218002C000000000218003000000004B7 +:1005B000021800340000000102180038000000009A +:1005C0000218003C00000001021800400000000476 +:1005D000021800440000000002180048000000015A +:1005E0000218004C00000003021800500000000038 +:1005F0000218005400000001021800580000000416 +:100600000218005C000000000218006000000001F9 +:1006100002180064000000030218006800000000D7 +:100620000218006C000000010218007000000004B5 +:100630000218007400000000021800780000000496 +:100640000218007C00000003061800800000000271 +:10065000021800A400003FFF021800A8000003FFDA +:1006600002180224000000000218023400000000FA +:100670000218024C00000000021802E4000000FF13 +:100680000618100000000400021B8BC000000001CF +:10069000021B800000000034021B80400000001894 +:1006A000021B80800000000C021B80C000000020A4 +:1006B0000C1B83000007A1200A1B830000000138E7 +:1006C0000B1B8300000013880A1B834000000000FE +:1006D0000C1B8340000001F40B1B8340000000054D +:1006E000021B83800007A120021B83C0000001F4CD +:1006F000061A100000000273041A19CC0001022728 +:10070000061A2008000000C8061A20000000000297 +:10071000041A499800040228061A2E280000000234 +:10072000061A2E2000000002061A0800000000022F +:10073000061A080800000004061A08180000000243 +:10074000041A08B00002022C061A2FD0000000067E +:10075000041A2FE80002022E041A2FC000040230EF +:10076000041A300000010234061A300400000003AD +:10077000041A301000010235061A3014000000037C +:10078000041A302000010236061A3024000000034B +:10079000041A303000010237061A3034000000031A +:1007A000041A304000010238061A304400000003E9 +:1007B000041A305000010239061A305400000003B8 +:1007C000041A30600001023A061A30640000000387 +:1007D000041A30700001023B061A30740000000356 +:1007E000041A30800001023C061A30840000000325 +:1007F000041A30900001023D061A309400000003F4 +:10080000041A30A00001023E061A30A400000003C2 +:10081000041A30B00001023F061A30B40000000391 +:10082000041A30C000010240061A30C40000000360 +:10083000041A30D000010241061A30D4000000032F +:10084000041A30E000010242061A30E400000003FE +:10085000041A30F000010243061A30F400000003CD +:10086000041A310000010244061A3104000000039A +:10087000041A311000010245061A31140000000369 +:10088000041A312000010246061A31240000000338 +:10089000041A313000010247061A31340000000307 +:1008A000041A314000010248061A314400000003D6 +:1008B000041A315000010249061A315400000003A5 +:1008C000041A31600001024A061A31640000000374 +:1008D000041A31700001024B061A31740000000343 +:1008E000041A31800001024C061A31840000000312 +:1008F000041A31900001024D061A319400000003E1 +:10090000041A31A00001024E061A31A400000003AF +:10091000041A31B00001024F061A31B4000000037E +:10092000041A31C000010250061A31C4000000034D +:10093000041A31D000010251061A31D4000000031C +:10094000041A31E000010252061A31E400000003EB +:10095000041A31F000010253061A31F400000003BA +:10096000041A320000010254061A32040000000387 +:10097000041A321000010255061A32140000000356 +:10098000041A322000010256061A32240000000325 +:10099000041A323000010257061A323400000003F4 +:1009A000041A324000010258061A324400000003C3 +:1009B000041A325000010259061A32540000000392 +:1009C000041A32600001025A061A32640000000361 +:1009D000041A32700001025B061A32740000000330 +:1009E000041A32800001025C061A328400000003FF +:1009F000041A32900001025D061A329400000003CE +:100A0000041A32A00001025E061A32A4000000039C +:100A1000041A32B00001025F061A32B4000000036B +:100A2000041A32C000010260061A32C4000000033A +:100A3000041A32D000010261061A32D40000000309 +:100A4000041A32E000010262061A32E400000003D8 +:100A5000041A32F000010263061A32F400000003A7 +:100A6000041A330000010264061A33040000000374 +:100A7000041A331000010265061A33140000000343 +:100A8000041A332000010266061A33240000000312 +:100A9000041A333000010267061A333400000003E1 +:100AA000041A334000010268061A334400000003B0 +:100AB000041A335000010269061A3354000000037F +:100AC000041A33600001026A061A3364000000034E +:100AD000041A33700001026B061A3374000000031D +:100AE000041A33800001026C061A338400000003EC +:100AF000041A33900001026D061A339400000003BB +:100B0000041A33A00001026E061A33A40000000389 +:100B1000041A33B00001026F061A33B40000000358 +:100B2000041A33C000010270061A33C40000000327 +:100B3000041A33D000010271061A33D400000003F6 +:100B4000041A33E000010272061A33E400000003C5 +:100B5000041A33F000010273061A33F40000000394 +:100B6000041A340000010274061A34040000000361 +:100B7000041A341000010275061A34140000000330 +:100B8000041A342000010276061A342400000003FF +:100B9000041A343000010277061A343400000003CE +:100BA000041A344000010278061A3444000000039D +:100BB000041A345000010279061A3454000000036C +:100BC000041A34600001027A061A3464000000033B +:100BD000041A34700001027B061A3474000000030A +:100BE000041A34800001027C061A348400000003D9 +:100BF000041A34900001027D061A349400000003A8 +:100C0000041A34A00001027E061A34A40000000376 +:100C1000041A34B00001027F061A34B40000000345 +:100C2000041A34C000010280061A34C40000000314 +:100C3000041A34D000010281061A34D400000003E3 +:100C4000041A34E000010282061A34E400000003B2 +:100C5000041A34F000010283061A34F40000000381 +:100C6000041A350000010284061A3504000000034E +:100C7000041A351000010285061A3514000000031D +:100C8000041A352000010286061A352400000003EC +:100C9000041A353000010287061A353400000003BB +:100CA000041A354000010288061A3544000000038A +:100CB000041A355000010289061A35540000000359 +:100CC000041A35600001028A061A35640000000328 +:100CD000041A35700001028B061A357400000003F7 +:100CE000041A35800001028C061A358400000003C6 +:100CF000041A35900001028D061A35940000000395 +:100D0000041A35A00001028E061A35A40000000363 +:100D1000041A35B00001028F061A35B40000000332 +:100D2000041A35C000010290061A35C40000000301 +:100D3000041A35D000010291061A35D400000003D0 +:100D4000041A35E000010292061A35E4000000039F +:100D5000041A35F000010293061A35F4000000036E +:100D6000041A360000010294061A3604000000033B +:100D7000041A361000010295061A3614000000030A +:100D8000041A362000010296061A362400000003D9 +:100D9000041A363000010297061A363400000003A8 +:100DA000041A364000010298061A36440000000377 +:100DB000041A365000010299061A36540000000346 +:100DC000041A36600001029A061A36640000000315 +:100DD000041A36700001029B061A367400000003E4 +:100DE000041A36800001029C061A368400000003B3 +:100DF000041A36900001029D061A36940000000382 +:100E0000041A36A00001029E061A36A40000000350 +:100E1000041A36B00001029F061A36B4000000031F +:100E2000041A36C0000102A0061A36C400000003EE +:100E3000041A36D0000102A1061A36D400000003BD +:100E4000041A36E0000102A2061A36E4000000038C +:100E5000041A36F0000102A3061A36F4000000035B +:100E6000041A3700000102A4061A37040000000328 +:100E7000041A3710000102A5061A371400000003F7 +:100E8000041A3720000102A6061A372400000003C6 +:100E9000041A3730000102A7061A37340000000395 +:100EA000041A3740000102A8061A37440000000364 +:100EB000041A3750000102A9061A37540000000333 +:100EC000041A3760000102AA061A37640000000302 +:100ED000041A3770000102AB061A377400000003D1 +:100EE000041A3780000102AC061A378400000003A0 +:100EF000041A3790000102AD061A3794000000036F +:100F0000041A37A0000102AE061A37A4000000033D +:100F1000041A37B0000102AF061A37B4000000030C +:100F2000041A37C0000102B0061A37C400000003DB +:100F3000041A37D0000102B1061A37D400000003AA +:100F4000041A37E0000102B2061A37E40000000379 +:100F5000041A37F0000102B3061A37F40000000348 +:100F6000041A3800000102B4061A38040000000315 +:100F7000041A3810000102B5061A381400000003E4 +:100F8000041A3820000102B6061A382400000003B3 +:100F9000041A3830000102B7061A38340000000382 +:100FA000041A3840000102B8061A38440000000351 +:100FB000041A3850000102B9061A38540000000320 +:100FC000041A3860000102BA061A386400000003EF +:100FD000041A3870000102BB061A387400000003BE +:100FE000041A3880000102BC061A3884000000038D +:100FF000041A3890000102BD061A3894000000035C +:10100000041A38A0000102BE061A38A4000000032A +:10101000041A38B0000102BF061A38B400000003F9 +:10102000041A38C0000102C0061A38C400000003C8 +:10103000041A38D0000102C1061A38D40000000397 +:10104000041A38E0000102C2061A38E40000000366 +:10105000041A38F0000102C3061A38F40000000335 +:10106000041A3900000102C4061A39040000000302 +:10107000041A3910000102C5061A391400000003D1 +:10108000041A3920000102C6061A392400000003A0 +:10109000041A3930000102C7061A3934000000036F +:1010A000041A3940000102C8061A3944000000033E +:1010B000041A3950000102C9061A3954000000030D +:1010C000041A3960000102CA061A396400000003DC +:1010D000041A3970000102CB061A397400000003AB +:1010E000041A3980000102CC061A3984000000037A +:1010F000041A3990000102CD061A39940000000349 +:10110000041A39A0000102CE061A39A40000000317 +:10111000041A39B0000102CF061A39B400000003E6 +:10112000041A39C0000102D0061A39C400000003B5 +:10113000041A39D0000102D1061A39D40000000384 +:10114000041A39E0000102D2061A39E40000000353 +:10115000041A39F0000102D3061A39F40000000322 +:10116000041A3A00000102D4061A3A0400000003EF +:10117000041A3A10000102D5061A3A1400000003BE +:10118000041A3A20000102D6061A3A24000000038D +:10119000041A3A30000102D7061A3A34000000035C +:1011A000041A3A40000102D8061A3A44000000032B +:1011B000041A3A50000102D9061A3A5400000003FA +:1011C000041A3A60000102DA061A3A6400000003C9 +:1011D000041A3A70000102DB061A3A740000000398 +:1011E000041A3A80000102DC061A3A840000000367 +:1011F000041A3A90000102DD061A3A940000000336 +:10120000041A3AA0000102DE061A3AA40000000304 +:10121000041A3AB0000102DF061A3AB400000003D3 +:10122000041A3AC0000102E0061A3AC400000003A2 +:10123000041A3AD0000102E1061A3AD40000000371 +:10124000041A3AE0000102E2061A3AE40000000340 +:10125000041A3AF0000102E3061A3AF4000000030F +:10126000041A3B00000102E4061A3B0400000003DC +:10127000041A3B10000102E5061A3B1400000003AB +:10128000041A3B20000102E6061A3B24000000037A +:10129000041A3B30000102E7061A3B340000000349 +:1012A000041A3B40000102E8061A3B440000000318 +:1012B000041A3B50000102E9061A3B5400000003E7 +:1012C000041A3B60000102EA061A3B6400000003B6 +:1012D000041A3B70000102EB061A3B740000000385 +:1012E000041A3B80000102EC061A3B840000000354 +:1012F000041A3B90000102ED061A3B940000000323 +:10130000041A3BA0000102EE061A3BA400000003F1 +:10131000041A3BB0000102EF061A3BB400000003C0 +:10132000041A3BC0000102F0061A3BC4000000038F +:10133000041A3BD0000102F1061A3BD4000000035E +:10134000041A3BE0000102F2061A3BE4000000032D +:10135000041A3BF0000102F3061A3BF400000003FC +:10136000041A3C00000102F4061A3C0400000003C9 +:10137000041A3C10000102F5061A3C140000000398 +:10138000041A3C20000102F6061A3C240000000367 +:10139000041A3C30000102F7061A3C340000000336 +:1013A000041A3C40000102F8061A3C440000000305 +:1013B000041A3C50000102F9061A3C5400000003D4 +:1013C000041A3C60000102FA061A3C6400000003A3 +:1013D000041A3C70000102FB061A3C740000000372 +:1013E000041A3C80000102FC061A3C840000000341 +:1013F000041A3C90000102FD061A3C940000000310 +:10140000041A3CA0000102FE061A3CA400000003DE +:10141000041A3CB0000102FF061A3CB400000003AD +:10142000041A3CC000010300061A3CC4000000037B +:10143000041A3CD000010301061A3CD4000000034A +:10144000041A3CE000010302061A3CE40000000319 +:10145000041A3CF000010303061A3CF400000003E8 +:10146000041A3D0000010304061A3D0400000003B5 +:10147000041A3D1000010305061A3D140000000384 +:10148000041A3D2000010306061A3D240000000353 +:10149000041A3D3000010307061A3D340000000322 +:1014A000041A3D4000010308061A3D4400000003F1 +:1014B000041A3D5000010309061A3D5400000003C0 +:1014C000041A3D600001030A061A3D64000000038F +:1014D000041A3D700001030B061A3D74000000035E +:1014E000041A3D800001030C061A3D84000000032D +:1014F000041A3D900001030D061A3D9400000003FC +:10150000041A3DA00001030E061A3DA400000003CA +:10151000041A3DB00001030F061A3DB40000000399 +:10152000041A3DC000010310061A3DC40000000368 +:10153000041A3DD000010311061A3DD40000000337 +:10154000041A3DE000010312061A3DE40000000306 +:10155000041A3DF000010313061A3DF400000003D5 +:10156000041A3E0000010314061A3E0400000003A2 +:10157000041A3E1000010315061A3E140000000371 +:10158000041A3E2000010316061A3E240000000340 +:10159000041A3E3000010317061A3E34000000030F +:1015A000041A3E4000010318061A3E4400000003DE +:1015B000041A3E5000010319061A3E5400000003AD +:1015C000041A3E600001031A061A3E64000000037C +:1015D000041A3E700001031B061A3E74000000034B +:1015E000041A3E800001031C061A3E84000000031A +:1015F000041A3E900001031D061A3E9400000003E9 +:10160000041A3EA00001031E061A3EA400000003B7 +:10161000041A3EB00001031F061A3EB40000000386 +:10162000041A3EC000010320061A3EC40000000355 +:10163000041A3ED000010321061A3ED40000000324 +:10164000041A3EE000010322061A3EE400000003F3 +:10165000041A3EF000010323061A3EF400000003C2 +:10166000041A3F0000010324061A3F04000000038F +:10167000041A3F1000010325061A3F14000000035E +:10168000041A3F2000010326061A3F24000000032D +:10169000041A3F3000010327061A3F3400000003FC +:1016A000041A3F4000010328061A3F4400000003CB +:1016B000041A3F5000010329061A3F54000000039A +:1016C000041A3F600001032A061A3F640000000369 +:1016D000041A3F700001032B061A3F740000000338 +:1016E000041A3F800001032C061A3F840000000307 +:1016F000041A3F900001032D061A3F9400000003D6 +:10170000041A3FA00001032E061A3FA400000003A4 +:10171000041A3FB00001032F061A3FB40000000373 +:10172000041A3FC000010330061A3FC40000000342 +:10173000041A3FD000010331061A3FD40000000311 +:10174000041A3FE000010332061A3FE400000007DC +:10175000041A4CB000080333061A400000000124AC +:10176000021A492000000000061A2500000000109F +:10177000061A258000000012061A09C00000004861 +:10178000061A080000000002061A082000000012D5 +:10179000041A2FB00002033B041A4CF00002033D70 +:1017A000061A500000000004061A449000000124AC +:1017B000021A492400000000061A2540000000100B +:1017C000061A25C800000012061A0AE000000048A8 +:1017D000061A081000000002061A0868000000122D +:1017E000041A2FB80002033F041A4CF80002034108 +:1017F000061A5010000000040200A468000AFFDC72 +:101800000200A280000000010200A294071D29111D +:101810000200A298000000000200A29C009C042488 +:101820000200A2A0000000000200A2A40000020921 +:101830000200A4FCFF000000020100B4000000014F +:10184000020100B800000001020100DC00000001FC +:10185000020101000000000102010104000000017A +:101860000201007C0030000002010084000000281A +:101870000201008C000000000201013000000004A1 +:101880000201025C000000010201032800000000C8 +:101890000201055400000030020100C400000001F4 +:1018A000020100CC00000001020100F8000000016C +:1018B000020100F000000001020100800030000081 +:1018C00002010088000000280201009000000000D2 +:1018D0000201013400000004020102DC00000001EA +:1018E0000201032C0000000002010564000000302A +:1018F000020100C800000001020100D00000000148 +:10190000020100FC00000001020100F400000001DF +:10191000020C100000000028020C200800000A1130 +:10192000020C200C00000A00020C201000000A0427 +:10193000020C201C0000FFFF020C20200000FFFF13 +:10194000020C20240000FFFF020C20280000FFFFF3 +:10195000020C203800000020020C203C0000002176 +:10196000020C204000000022020C20440000002352 +:10197000020C204800000024020C204C000000252E +:10198000020C205000000026020C2054000000270A +:10199000020C205800000028020C205C00000029E6 +:1019A000020C20600000002A020C20640000002BC2 +:1019B000020C20680000002C020C206C0000002D9E +:1019C000020C20700000002E020C20740000002F7A +:1019D000020C207800000010060C207C0000004F54 +:1019E000020C21B800000001020C21BC0000000123 +:1019F000020C21C000000001020C21C40000000103 +:101A0000020C21C800000001020C21CC00000001E2 +:101A1000020C21D000000001020C21D400000001C2 +:101A2000020C21D800000001020C21DC00000001A2 +:101A3000020C21E000000001020C21E40000000182 +:101A4000020C21E800000001020C21EC0000000162 +:101A5000020C21F000000001020C21F40000000142 +:101A6000020C21F800000001060C21FC0000000F10 +:101A7000020C223807FFFFFF020C223C0000003F4F +:101A8000020C224007FFFFFF020C22440000000F5F +:101A9000010C224800000000010C224C0000000054 +:101AA000010C225000000000010C22540000000034 +:101AB000010C225800000000010C225C0000000014 +:101AC000010C226000000000010C226400000000F4 +:101AD000010C226800000000010C226C00000000D4 +:101AE000010C227000000000010C227400000000B4 +:101AF000010C227800000000010C227C0000000094 +:101B0000020C24BC000000010C0C2000000003E8C3 +:101B10000A0C2000000000010B0C20000000000A4D +:101B2000020C400800000562020C400C0000055148 +:101B3000020C401000000555020C40140000057214 +:101B4000020C401C0000FFFF020C40200000FFFFC1 +:101B5000020C40240000FFFF020C40280000FFFFA1 +:101B6000020C403800000046020C403C0000000C13 +:101B7000060C40400000005E020C41B8000000016D +:101B8000060C41BC0000001F020C423807FFFFFF9B +:101B9000020C423C0000003F020C424007FFFFFFE6 +:101BA000020C42440000000F010C424800000000FB +:101BB000010C424C00000000010C425000000000EB +:101BC000010C425400000000010C425800000000CB +:101BD000010C425C00000000010C426000000000AB +:101BE000010C426400000000010C4268000000008B +:101BF000010C426C00000000010C4270000000006B +:101C0000010C427400000000010C4278000000004A +:101C1000010C427C00000000010C4280000000002A +:101C2000020C44C0000000010C0C4000000003E85E +:101C30000A0C4000000000010B0C40000000000AEC +:101C4000060D400000000A00020D004400000032B2 +:101C5000020D008C02150020020D009002150020DC +:101C6000020D009408100000020D009800000033DF +:101C7000020D009C00000002020D00A00000000008 +:101C8000020D00A400000005020D00A800000005E0 +:101C9000060D00AC00000002020D00B400000002BE +:101CA000020D00B800000003020D00BC000000029D +:101CB000020D00C000000001020D00C8000000027B +:101CC000020D00CC00000002020D015C00000001CA +:101CD000020D016400000001020D01680000000215 +:101CE000020D020400000001020D020C00000020A1 +:101CF000020D021000000040020D0214000000401E +:101D0000020D022000000003020D02240000001852 +:101D1000060D028000000012040D030000180343AA +:101D2000060D03600000000C020D004C00000001D5 +:101D3000020D005000000002020D005400000000DF +:101D4000020D005800000008060D005C00000004B1 +:101D5000020D00C400000004020D0114000000097F +:101D6000020D011800000029020D011C0000000AEC +:101D7000020D01200000002A020D012400000000D5 +:101D8000020D012800000020020D012C00000000BF +:101D9000020D013000000020020D0134000000009F +:101DA000020D013800000020020D013C000000007F +:101DB000020D014000000020020D0144000000005F +:101DC000020D014800000020020D00040000000187 +:101DD000020D000800000001020D000C00000001CF +:101DE000020D001000000001020D001400000001AF +:101DF000020D001800000001020D001C000000018F +:101E0000020D002000000001020D0024000000016E +:101E1000020D002800000001020D002C000000014E +:101E2000020D003000000001020D0034000000012E +:101E3000020D003800000001020D003C000000010E +:101E4000060E200000000800020E004C00000032C8 +:101E5000020E009402150020020E009802150020C8 +:101E6000020E009C00000030020E00A008100000CE +:101E7000020E00A400000033020E00A80000003093 +:101E8000020E00AC00000031020E00B000000002A3 +:101E9000020E00B400000004020E00B800000000B2 +:101EA000020E00BC00000002020E00C00000000292 +:101EB000020E00C400000000020E00C80000000274 +:101EC000020E00CC00000007020E00D0000000024D +:101ED000020E00D400000002020E00D80000000133 +:101EE000020E014400000001020E014C000000013E +:101EF000020E015000000002020E02040000000168 +:101F0000020E020C00000040020E02100000004011 +:101F1000020E021C00000004020E0220000000203D +:101F2000020E02240000000E020E02280000001B18 +:101F3000060E030000000012040E0280001B035B6B +:101F4000060E02EC00000005020E00540000000C1A +:101F5000020E00580000000C020E005C00000000A1 +:101F6000020E006000000010060E00640000000475 +:101F7000020E00DC00000003020E01100000000F42 +:101F8000020E01140000002F020E011800000000D4 +:101F9000020E011C00000020020E000400000001DF +:101FA000020E000800000001020E000C00000001FB +:101FB000020E001000000001020E001400000001DB +:101FC000020E001800000001020E001C00000001BB +:101FD000020E002000000001020E0024000000019B +:101FE000020E002800000001020E002C000000017B +:101FF000020E003000000001020E0034000000015B +:10200000020E003800000001020E003C000000013A +:10201000020E004000000001020E0044000000011A +:102020000730040000B00000083007680013037692 +:1020300007340000332700000734800032520CCAF6 +:10204000073500001A8C195F083539A058CC037881 +:10205000013000000000000001300004000000001A +:1020600001300008000000000130000C00000000FA +:1020700001300010000000000130001400000000DA +:1020800002300020000000010230002400000002A5 +:1020900002300028000000030230002C0000000085 +:1020A0000230003000000004023000340000000163 +:1020B00002300038000000000230003C0000000147 +:1020C0000230004000000004023000440000000024 +:1020D00002300048000000010230004C0000000304 +:1020E00002300050000000000230005400000001E7 +:1020F00002300058000000040230005C00000000C4 +:1021000002300060000000010230006400000003A3 +:1021100002300068000000000230006C0000000186 +:102120000230007000000004023000740000000063 +:1021300002300078000000040230007C0000000340 +:102140000630008000000002023000A400003FFFC3 +:10215000023000A8000003FF02300224000000004B +:1021600002300234000000000230024C0000000087 +:10217000023002E40000FFFF0630200000000800EB +:1021800002338BC000000001023380000000001AFF +:10219000023380400000004E0233808000000010B7 +:1021A000023380C0000000200C3383000007A12010 +:1021B0000A338300000001380B33830000001388CA +:1021C0000A338340000000000C338340000001F418 +:1021D0000B33834000000005023383800007A120F9 +:1021E000023383C0000001F406322A88000000C2D6 +:1021F00006322008000000C806322000000000025D +:10220000063223E80000004004322E580004037A0E +:10221000063250A000000004063250B80000000250 +:102220000632508000000006043250980002037EFF +:10223000063250000000002006323000000004008A +:1022400006321C0000000004043218300002038033 +:10225000063224E8000000B402322DB00000000075 +:1022600006324000000000B40632300000000020BA +:10227000063231000000002006323200000000204B +:102280000632330000000020063234000000002037 +:102290000632350000000020063236000000002023 +:1022A000063237000000002006323800000000200F +:1022B000063239000000002006323A0000000020FB +:1022C00006323B000000002006323C0000000020E7 +:1022D00006323D000000002006323E0000000020D3 +:1022E00006323F000000002006321C1000000002F1 +:1022F000063245A000000024063227B8000000B4D2 +:1023000002322DB400000000063242D0000000B4BA +:1023100006323080000000200632318000000020AC +:102320000632328000000020063233800000002098 +:102330000632348000000020063235800000002084 +:102340000632368000000020063237800000002070 +:10235000063238800000002006323980000000205C +:1023600006323A800000002006323B800000002048 +:1023700006323C800000002006323D800000002034 +:1023800006323E800000002006323F800000002020 +:1023900006321C20000000020632463000000024F5 +:1023A0000720040000870000082007800010038237 +:1023B0000724000031A500000724800008190C6ADA +:1023C00008248EB06C9003840120000000000000FF +:1023D00001200004000000000120000800000000AF +:1023E0000120000C0000000001200010000000008F +:1023F0000120001400000000022000200000000165 +:102400000220002400000002022000280000000337 +:102410000220002C00000000022000300000000418 +:1024200002200034000000010220003800000000FB +:102430000220003C000000010220004000000004D7 +:1024400002200044000000000220004800000001BB +:102450000220004C00000003022000500000000099 +:102460000220005400000001022000580000000477 +:102470000220005C0000000002200060000000015B +:102480000220006400000003022000680000000039 +:102490000220006C00000001022000700000000417 +:1024A00002200074000000000220007800000004F8 +:1024B0000220007C000000030620008000000002D3 +:1024C000022000A400003FFF022000A8000003FF3C +:1024D000022002240000000002200234000000005C +:1024E0000220024C00000000022002E40000FFFF76 +:1024F000062020000000080002238BC0000000011D +:10250000022380000000001002238040000000121F +:102510000223808000000030022380C00000000EF3 +:102520000C2383000007A1200A2383000000013848 +:102530000B238300000013880A238340000000005F +:102540000C238340000001F40B23834000000005AE +:10255000022383800007A120022383C0000001F42E +:10256000062250000000004206222008000000C899 +:10257000062220000000000206224000000000C6E3 +:1025800004224318000503860622432C0000000B9A +:10259000042243580005038B0622436C0000000B05 +:1025A0000422439800050390062243AC0000000B70 +:1025B000042243D800050395062243EC0000000BDB +:1025C000042244180005039A0622442C0000000B44 +:1025D000042244580005039F0622446C0000000BAF +:1025E00004224498000503A4062244AC0000000B1A +:1025F000042244D8000503A9062244EC0000000B85 +:1026000004224518000503AE0622452C0000000BED +:1026100004224558000503B30622456C0000000B58 +:1026200004224598000503B8062245AC0000000BC3 +:10263000042245D8000503BD062245EC0000000B2E +:1026400004224618000503C20622462C0000000B97 +:1026500004224658000503C70622466C0000000B02 +:1026600004224698000503CC062246AC0000000B6D +:10267000042246D8000503D1062246EC0000000BD8 +:1026800004224718000503D60622472C0000000B41 +:1026900004224758000503DB0622476C0000000BAC +:1026A00004224798000503E0062247AC0000000B17 +:1026B000042247D8000503E5062247EC0000000B82 +:1026C00004224818000503EA0622482C0000000BEB +:1026D00004224858000503EF0622486C0000000B56 +:1026E00004224898000503F4062248AC0000000BC1 +:1026F000042248D8000503F9062248EC0000000B2C +:1027000004224918000503FE0622492C0000000B94 +:1027100004224958000504030622496C0000000BFE +:102720000422499800050408062249AC0000000B69 +:10273000042249D80005040D062249EC0000000BD4 +:1027400004224A180005041206224A2C0000000B3D +:1027500004224A580005041706224A6C0000000BA8 +:1027600004224A980005041C06224AAC0000000B13 +:1027700004224AD80005042106224AEC0000000584 +:1027800006224B000000001704224B5C00010426C7 +:1027900006224B600000000304224B6C000104275A +:1027A000062238000000004006223000000002002F +:1027B000042251C00004042806221000000000C0BA +:1027C000062215C00000024004221EC80008042C86 +:1027D0000622390000000008022251180000000003 +:1027E000062251D00000000606221300000000025D +:1027F00006221410000000300622392000000008D4 +:102800000222511C00000000062251E800000006D0 +:102810000622130800000002062214D00000003037 +:102820000216100000000028021700080000000235 +:102830000217002C000000030217003C00000004F7 +:1028400002170044000000000217004800000002C8 +:102850000217004C0000009002170050000000908A +:102860000217005400800090021700580810000062 +:10287000021700600000008A021700640000008058 +:1028800002170068000000810217006C0000008041 +:10289000021700700000000602170078000007D041 +:1028A0000217007C0000076C02170038007C10043F +:1028B000021700040000000F06164024000000026A +:1028C000021640700000001C0216420800000001C1 +:1028D0000216421000000001021642200000000112 +:1028E00002164228000000010216423000000001DA +:1028F000021642380000000102164260000000018A +:102900000C16401C0003D0900A16401C0000009CCE +:102910000B16401C000009C40216403000000008DD +:10292000021640340000000C02164038000000106F +:102930000216404400000020021640000000000182 +:10294000021640D8000000010216400800000001F5 +:102950000216400C000000010216401000000001A9 +:10296000021642400000000002164248000000002B +:1029700006164270000000020216425000000000DD +:1029800002164258000000000616428000000002B5 +:1029900002166008000006140216600C0000060013 +:1029A00002166010000006040216601C0000FFFF03 +:1029B000021660200000FFFF021660240000FFFFE7 +:1029C000021660280000FFFF021660380000002099 +:1029D0000216603C00000020061660400000000265 +:1029E00002166048000000230216604C000000241C +:1029F00002166050000000250216605400000026F8 +:102A000002166058000000270216605C00000029D2 +:102A1000021660600000002A021660640000002BAD +:102A2000021660680000002C0216606C0000002D89 +:102A30000616607000000012021660B80000000167 +:102A4000021660BC00000001061660C00000003ED7 +:102A5000021661B800000001061661BC0000001FEC +:102A60000216623807FFFFFF0216623C0000003FBB +:102A70000216624007FFFFFF021662440000000FCB +:102A800001166248000000000116624C00000000C0 +:102A900001166250000000000116625400000000A0 +:102AA00001166258000000000116625C0000000080 +:102AB0000116626000000000011662640000000060 +:102AC00001166268000000000116626C0000000040 +:102AD0000116627000000000011662740000000020 +:102AE00001166278000000000116627C0000000000 +:102AF000021664BC000000010C166000000003E830 +:102B00000A166000000000010B1660000000000AB9 +:102B100002168040000000060216804400000005F6 +:102B2000021680480000000A0216804C00000005D2 +:102B30000216805400000002021680CC000000043F +:102B4000021680D000000004021680D400000004A9 +:102B5000021680D800000004021680DC0000000489 +:102B6000021680E000000004021680E40000000469 +:102B7000021680E800000004021688040000000429 +:102B8000021680300000007C021680340000003DF8 +:102B9000021680380000003F0216803C0000009CB6 +:102BA000021680F000000007061680F40000000501 +:102BB0000216880C010101010216810800000000C4 +:102BC0000216810C000000040216811000000004AF +:102BD0000216811400000002021688100801200469 +:102BE00002168118000000050216811C0000000575 +:102BF0000216812000000005021681240000000555 +:102C00000216882C200810010216812800000008F6 +:102C10000216812C00000006021681300000000719 +:102C200002168134000000000216883001010120E4 +:102C300006168138000000040216883401010101E3 +:102C400006168148000000040216883801010101BF +:102C500006168158000000040216883C010101019B +:102C6000061681680000000302168174000000014E +:102C7000021688400101010102168178000000015E +:102C80000216817C00000001021681800000000114 +:102C9000021681840000000102168844010101012E +:102CA00002168188000000010216818C00000004D9 +:102CB00002168190000000040216819400000002B8 +:102CC00002168848080120040216819800000005B9 +:102CD0000216819C00000005021681A0000000057C +:102CE000021681A4000000050216881420081001B5 +:102CF000021681A800000008021681AC0000000640 +:102D0000021681B000000007021681B40000000125 +:102D10000216881801010120021681B80000000186 +:102D2000021681BC00000001021681C000000001F3 +:102D3000021681C4000000010216881C0101010175 +:102D4000021681C800000001021681CC00000001BB +:102D5000021681D000000001021681D4000000019B +:102D60000216882001010101021681D8000000012D +:102D7000021681DC00000001021681E00000000163 +:102D8000021681E4000000010216882401010101FD +:102D9000021681E800000001021681EC000000012B +:102DA000021681F0000000010216882801010101CD +:102DB00002168240FFFF003F061682440000000218 +:102DC0000216824CFFFF003F0216825000000100F5 +:102DD000021682540000010006168258000000020C +:102DE00002168260000000C002168264000000C06B +:102DF0000216826800001E000216826C00001E008F +:102E0000021682700000400002168274000040002A +:102E100002168278000080000216827C000080008A +:102E2000021682800000200002168284000020002A +:102E30000616828800000007021682A40000000126 +:102E4000061682A80000000A021681F400000C0891 +:102E5000021681F800000040021681FC000001000B +:102E600002168200000000200216820400000017F3 +:102E700002168208000000800216820C0000020088 +:102E8000021682100000000002168218FFFF01FFE8 +:102E900002168214FFFF01FF0216823C000000139D +:102EA000021680900000013F021680600000014081 +:102EB00002168064000001400616806800000002CF +:102EC00002168070000000C0061680740000000723 +:102ED0000216809C00000048021680A000000048F6 +:102EE000061680A400000002021680AC0000004814 +:102EF000061680B00000000702168238000080002D +:102F000002168234000025E40216809400007FFF40 +:102F100002168220000000070216821C0000000733 +:102F2000021682280000000002168224FFFFFFFF25 +:102F300002168230000000000216822CFFFFFFFF05 +:102F4000021680EC000000FF0214000000000001E7 +:102F50000214000C000000010214004000000001F7 +:102F60000214004400007FFF0214000C0000000067 +:102F700002140000000000000214006C00000000B9 +:102F800002140004000000010214003000000001DF +:102F900002140004000000000214005C00000000A5 +:102FA00002140008000000010214003400000001B7 +:102FB000021400080000000002140060000000007D +:102FC00006028000000020000202005800000032CB +:102FD000020200A003150020020200A40315002035 +:102FE000020200A801000030020200AC081000003C +:102FF000020200B000000033020200B40000003002 +:10300000020200B800000031020200BC0000000310 +:10301000020200C000000006020200C4000000031B +:10302000020200C800000003020200CC00000002FF +:10303000020200D000000000020200D400000002E2 +:10304000020200DC00000000020200E000000006B6 +:10305000020200E400000004020200E80000000296 +:10306000020200EC00000002020200F00000000179 +:10307000020200FC00000006020201200000000025 +:103080000202013400000002020201B0000000014F +:103090000202020C00000001020202140000000102 +:1030A00002020218000000020202040400000001F3 +:1030B0000202040C00000040020204100000004064 +:1030C0000202041C00000004020204200000002090 +:1030D0000202042400000002020204280000001F73 +:1030E00006020500000000120402048000200434DF +:1030F000020200600000000F0202006400000007EE +:1031000002020068000000000202006C0000000ED5 +:103110000602007000000004020200F40000000437 +:103120000202000400000001020200080000000189 +:103130000202000C00000001020200100000000169 +:103140000202001400000001020200180000000149 +:103150000202001C00000001020200200000000129 +:103160000202002400000001020200280000000109 +:103170000202002C000000010202003000000001E9 +:1031800002020034000000010202003800000001C9 +:103190000202003C000000010202004000000001A9 +:1031A0000202004400000001020200480000000189 +:1031B0000202004C00000001020200500000000169 +:1031C00002020108000000C802020118000000020B +:1031D000020201C400000000020201CC0000000055 +:1031E000020201D400000002020201DC0000000221 +:1031F000020201E4000000FF020201EC000000FFF7 +:103200000202010C000000C80202011C00000002C2 +:10321000020201C800000000020201D0000000000C +:10322000020201D800000002020201E000000002D8 +:10323000020201E8000000FF020201F0000000FFAE +:1032400007280400008D00000828076800130454B4 +:10325000072C000033FC0000072C800038B20D0062 +:10326000072D000039171B2D072D800005D9297364 +:10327000082D8A204EBC04560128000000000000E2 +:1032800001280004000000000128000800000000E0 +:103290000128000C000000000128001000000000C0 +:1032A0000128001400000000022800200000000196 +:1032B0000228002400000002022800280000000369 +:1032C0000228002C0000000002280030000000044A +:1032D000022800340000000102280038000000002D +:1032E0000228003C00000001022800400000000409 +:1032F00002280044000000000228004800000001ED +:103300000228004C000000030228005000000000CA +:1033100002280054000000010228005800000004A8 +:103320000228005C0000000002280060000000018C +:10333000022800640000000302280068000000006A +:103340000228006C00000001022800700000000448 +:103350000228007400000000022800780000000429 +:103360000228007C00000003062800800000000204 +:10337000022800A400003FFF022800A8000003FF6D +:10338000022802240000000002280234000000008D +:103390000228024C00000000022802E40000FFFFA7 +:1033A0000628200000000800022B8BC0000000014E +:1033B000022B800000000000022B8040000000185B +:1033C000022B80800000000C022B80C000000066F1 +:1033D0000C2B83000007A1200A2B8300000001387A +:1033E0000B2B8300000013880A2B83400000000091 +:1033F0000C2B8340000001F40B2B834000000005E0 +:10340000022B83800007A120022B83C0000001F45F +:10341000062A3D4800000004042A3D5800020458D2 +:10342000062A3D6000000006062A30000000004821 +:10343000062A2008000000C8062A2000000000021A +:10344000062A31280000008E062A33680000000397 +:10345000042A33740001045A062A3A780000000254 +:10346000042A3A800002045B042A3A700002045DD8 +:10347000042A3E280002045F042A3EB000040461CE +:10348000042A250000020465062A25080000010020 +:10349000062A297000000004042A29600004046739 +:1034A000042A2F480002046B062A3378000000D853 +:1034B000022A3A3800000000062A3A88000000324A +:1034C000042A3D880010046D062A502000000002E6 +:1034D000062A503000000002062A500000000002B8 +:1034E000062A501000000002022A50B80000000115 +:1034F000062A50480000000E042A3D780002047D90 +:10350000062A3C1800000026022A50400000000055 +:10351000062A36D8000000D8022A3A3C00000000F3 +:10352000062A3B5000000032042A3DC80010047FE8 +:10353000062A502800000002062A50380000000227 +:10354000062A500800000002062A50180000000257 +:10355000022A50BC00000001062A50800000000E24 +:10356000042A3D800002048F062A3CB00000002699 +:10357000022A504400000000021010080000000160 +:103580000210101000000264021010000003D000AE +:10359000021010040000003D091018000200049100 +:1035A00009101100001006910610114000000008DB +:1035B00009101160000806A1061011800000000229 +:1035C00009101188000606A9061011A000000018B5 +:1035D000021010100000000006102400000000E09F +:1035E0000210201C0000000002102020000000013A +:1035F000021020C0000000010210200400000001A1 +:10360000021020080000000109103C00000506AF70 +:1036100009103C20000506B409103800000506B961 +:1036200002104028000000100210404400003FFF3C +:103630000210405800280000021040840084924A82 +:1036400006104C000000010002104058000000006D +:103650000610806800000004021080000000108046 +:1036600006108028000000020210803800000010C0 +:10367000021080400000FFFF021080440000FFFFA6 +:1036800002108050000000000210810000000000C5 +:10369000061081200000000202108008000002B520 +:1036A0000210801000000000061082000000004A96 +:1036B000021081080001FFFF061081400000000297 +:1036C0000210800000001A80061090000000002404 +:1036D000061091200000004A061093700000004A76 +:1036E000061095C00000004A0210800400001080FF +:1036F00006108030000000020210803C0000001024 +:10370000021080480000FFFF0210804C0000FFFF05 +:10371000021080540000000002108104000000002C +:1037200006108128000000020210800C000002B583 +:103730000210801400000000061084000000004AFF +:103740000210810C0001FFFF0610814800000002FA +:103750000210800400001A800610909000000024DF +:10376000061092480000004A061094980000004A93 +:10377000061096E80000004A0212049000E383401D +:103780000212051400003C10021205200000000285 +:1037900002120494FFFFFFFF02120498FFFFFFFFD5 +:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5 +:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95 +:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75 +:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D +:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D +:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D +:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4 +:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC +:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C +:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C +:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C +:1038500002120500FFFFFFFF02120504FFFFFFFF3A +:1038600002120508FFFFFFFF0212050CFFFFFFFF1A +:1038700002120510FFFFFFFF021204D4FFFF3330D6 +:10388000021204D8FFFF3340021204B4F0003000EB +:1038900002120390000000080212039C00000008BE +:1038A000061203A000000002021203BC0000000484 +:1038B000021203C400000004021203D00000000042 +:1038C000021203DC000000000212036C0000000181 +:1038D000021203680000003F021201BC0000004019 +:1038E000021201C000001808021201C400000803FF +:1038F000021201C800000803021201CC00000040BF +:10390000021201D000000003021201D400000803DB +:10391000021201D800000803021201DC00000803B3 +:10392000021201E000010003021201E4000008039A +:10393000021201E800000803021201EC000000037B +:10394000021201F000000003021201F40000000363 +:10395000021201F800000003021201FC0000000343 +:103960000212020000000003021202040000000321 +:1039700002120208000000030212020C0000000301 +:1039800002120210000000030212021400000003E1 +:1039900002120218000000030212021C00000003C1 +:1039A00002120220000000030212022400000003A1 +:1039B00002120228000024030212022C0000002F31 +:1039C0000212023000000009021202340000001945 +:1039D00002120238000001840212023C000001833E +:1039E0000212024000000306021202440000001905 +:1039F00002120248000000060212024C00000306F8 +:103A000002120250000003060212025400000306D4 +:103A10000212025800000C860212025C000003062B +:103A20000212026000000306021202640000000697 +:103A300002120268000000060212026C000000067A +:103A4000021202700000000602120274000000065A +:103A500002120278000000060212027C000000063A +:103A6000021202800000000602120284000000061A +:103A700002120288000000060212028C00000006FA +:103A800002120290000000060212029400000006DA +:103A900002120298000000060212029C00000006BA +:103AA000021202A000000306021202A4000000138A +:103AB000021202A800000006021202B00000100468 +:103AC000021202B400001004021203240010644029 +:103AD0000212032800106440021201B0000000012D +:103AE0000600A000000000160200A06CBF5C0000F1 +:103AF0000200A070FFF51FEF0200A0740000FFFF9E +:103B00000200A078F00003E00200A07C00000000AA +:103B10000200A0800000A0000600A08400000005B4 +:103B20000200A0980FE000000600A09C0000001416 +:103B30000200A0EC555400000200A0F05555555568 +:103B40000200A0F4000055550200A0F8F0000000AB +:103B50000200A0FC555400000200A1005555555527 +:103B60000200A104000055550200A108F000000069 +:103B70000600A22C000000040200A0600000030761 +:103B80000200A10CBF5C00000200A110FFF51FEFB6 +:103B90000200A1140000FFFF0200A118F00003E0E2 +:103BA0000200A11C000000000200A1200000A000F3 +:103BB0000600A124000000050200A1380FE000006B +:103BC0000600A13C000000140200A18C5554000026 +:103BD0000200A190555555550200A194000055557D +:103BE0000200A198F00000000200A19C55540000C2 +:103BF0000200A1A0555555550200A1A4000055553D +:103C00000200A1A8F00000000600A23C0000000491 +:103C10000200A06400000307000000000000000094 +:103C20000000002E00000000000000000000000066 +:103C30000000000000000000000000000000000084 +:103C40000000000000000000000000000000000074 +:103C50000000000000000000000000000000000064 +:103C60000000000000000000000000000000000054 +:103C70000000000000000000002E004D00000000C9 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA00000000000004D008B00000000000000003C +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD000008B009000900094009400980000000079 +:103CE00000000000000000000000000000000000D4 +:103CF000000000000000000000000000009802DE4C +:103D000002DE02E802E802F200000000000000000B +:103D100000000000000000000000000000000000A3 +:103D20000000000000000000000000000000000093 +:103D30000000000000000000000000000000000083 +:103D40000000000000000000000000000000000073 +:103D50000000000000000000000000000000000063 +:103D60000000000000000000000000000000000053 +:103D70000000000000000000000000000000000043 +:103D80000000000000000000000000000000000033 +:103D90000000000000000000000000000000000023 +:103DA0000000000000000000000000000000000013 +:103DB0000000000000000000000000000000000003 +:103DC00000000000000000000000000000000000F3 +:103DD000000000000000000002F202FA00000000F3 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E000000000000000000000000000000000000B2 +:103E100000000000000000000000000000000000A2 +:103E20000000000000000000000000000000000092 +:103E300002FA02FF02FF030A030A03150000000052 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E60000000000000000000000000000000000052 +:103E70000000000000000000000000000000000042 +:103E80000000000000000000031503160000000001 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB000000000000316035700000000000000008F +:103EC00000000000000000000000000000000000F2 +:103ED00000000000000000000000000000000000E2 +:103EE0000357037B000000000000000000000000FA +:103EF00000000000000000000000000000000000C2 +:103F0000000000000000000000000000037B03BB75 +:103F100000000000000000000000000000000000A1 +:103F20000000000000000000000000000000000091 +:103F3000000000000000000003BB03F700000000C9 +:103F40000000000000000000000000000000000071 +:103F50000000000000000000000000000000000061 +:103F60000000000003F7043D043D045204520467BE +:103F70000000000000000000000000000000000041 +:103F80000000000000000000000000000000000031 +:103F9000046704ED04ED04F204F204F700000000ED +:103FA0000000000000000000000000000000000011 +:103FB00000000000000000000000000004F704F80A +:103FC00000000000000000000000000000000000F1 +:103FD00000000000000000000000000000000000E1 +:103FE000000000000000000004F8050A00000000C6 +:103FF00000000000000000000000000000000000C1 +:1040000000000000000000000000000000000000B0 +:1040100000000000050A051F051F052205220525D1 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:1040400005250555000000000000000000000000EC +:104050000000000000000000000000000000000060 +:10406000000000000000000000000000055505DC15 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:10409000000000000000000005DC05E305E305E783 +:1040A00005E705EB00000000000000000000000034 +:1040B0000000000000000000000000000000000000 +:1040C0000000000005EB062B062B06330633063BEB +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F000063B068806880695069506A20000000085 +:1041000000000000000000000000000000000000AF +:1041100000000000000000000000000006A206AE43 +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000006AE06B40000000001 +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:104170000000000006B406B70000000000000000C8 +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A00006B706BD0000000000000000000000008F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000006BD06BE68 +:1041D00006BE06D006D006E2000000000000000087 +:1041E00000000000000000000000000000000000CF +:1041F000000000000000000006E2074F0000000081 +:1042000000000000000000000000000000000000AE +:10421000000000000000000000000000000000009E +:1042200000000000074F0750075007630763077639 +:10423000000000000000000000000000000000007E +:10424000000000000000000000000000000000006E +:10425000000000000000000000000000000000005E +:10426000000000000000000000000000000000004E +:10427000000000000000000000000000000000003E +:10428000000000000000000000000000000000002E +:10429000000000000000000000000000000000001E +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:1043300000010000000204C00003098000040E40D8 +:1043400000051300000617C000071C80000821406C +:1043500000092600000A2AC0000B2F80000C344000 +:10436000000D3900000E3DC0000F42800010474094 +:1043700000114C00001250C00013558000145A4028 +:1043800000155F00001663C00017688000186D40BC +:1043900000197200001A76C0001B7B80001C804050 +:1043A000001D8500001E89C0001F8E800000934004 +:1043B00000002000000040000000600000008000BD +:1043C0000000A0000000C0000000E00000010000AC +:1043D0000001200000014000000160000001800099 +:1043E0000001A0000001C0000001E0000002000088 +:1043F0000002200000024000000260000002800075 +:104400000002A0000002C0000002E0000003000063 +:104410000003200000034000000360000003800050 +:104420000003A0000003C0000003E000000400003F +:10443000000420000004400000046000000480002C +:104440000004A0000004C0000004E000000500001B +:104450000005200000054000000560000005800008 +:104460000005A0000005C0000005E00000060000F7 +:1044700000062000000640000006600000068000E4 +:104480000006A0000006C0000006E00000070000D3 +:1044900000072000000740000007600000078000C0 +:1044A0000007A0000007C0000007E00000080000AF +:1044B000000820000008400000086000000880009C +:1044C0000008A0000008C0000008E000000900008B +:1044D0000009200000094000000960000009800078 +:1044E0000009A0000009C0000009E000000A000067 +:1044F000000A2000000A4000000A6000000A800054 +:10450000000AA000000AC000000AE000000B000042 +:10451000000B2000000B4000000B6000000B80002F +:10452000000BA000000BC000000BE000000C00001E +:10453000000C2000000C4000000C6000000C80000B +:10454000000CA000000CC000000CE000000D0000FA +:10455000000D2000000D4000000D6000000D8000E7 +:10456000000DA000000DC000000DE000000E0000D6 +:10457000000E2000000E4000000E6000000E8000C3 +:10458000000EA000000EC000000EE000000F0000B2 +:10459000000F2000000F4000000F6000000F80009F +:1045A000000FA000000FC000000FE000001000008E +:1045B000001020000010400000106000001080007B +:1045C0000010A0000010C0000010E000001100006A +:1045D0000011200000114000001160000011800057 +:1045E0000011A0000011C0000011E0000012000046 +:1045F0000012200000124000001260000012800033 +:104600000012A0000012C0000012E0000013000021 +:10461000001320000013400000136000001380000E +:104620000013A0000013C0000013E00000140000FD +:1046300000142000001440000014600000148000EA +:104640000014A0000014C0000014E00000150000D9 +:1046500000152000001540000015600000158000C6 +:104660000015A0000015C0000015E00000160000B5 +:1046700000162000001640000016600000168000A2 +:104680000016A0000016C0000016E0000017000091 +:10469000001720000017400000176000001780007E +:1046A0000017A0000017C0000017E000001800006D +:1046B000001820000018400000186000001880005A +:1046C0000018A0000018C0000018E0000019000049 +:1046D0000019200000194000001960000019800036 +:1046E0000019A0000019C0000019E000001A000025 +:1046F000001A2000001A4000001A6000001A800012 +:10470000001AA000001AC000001AE000001B000000 +:10471000001B2000001B4000001B6000001B8000ED +:10472000001BA000001BC000001BE000001C0000DC +:10473000001C2000001C4000001C6000001C8000C9 +:10474000001CA000001CC000001CE000001D0000B8 +:10475000001D2000001D4000001D6000001D8000A5 +:10476000001DA000001DC000001DE000001E000094 +:10477000001E2000001E4000001E6000001E800081 +:10478000001EA000001EC000001EE000001F000070 +:10479000001F2000001F4000001F6000001F80005D +:1047A000001FA000001FC000001FE000002000004C +:1047B0000020200000204000002060000020800039 +:1047C0000020A0000020C0000020E0000021000028 +:1047D0000021200000214000002160000021800015 +:1047E0000021A0000021C0000021E0000022000004 +:1047F00000222000002240000022600000228000F1 +:104800000022A0000022C0000022E00000230000DF +:1048100000232000002340000023600000238000CC +:104820000023A0000023C0000023E00000240000BB +:1048300000242000002440000024600000248000A8 +:104840000024A0000024C0000024E0000025000097 +:104850000025200000254000002560000025800084 +:104860000025A0000025C0000025E0000026000073 +:104870000026200000264000002660000026800060 +:104880000026A0000026C0000026E000002700004F +:10489000002720000027400000276000002780003C +:1048A0000027A0000027C0000027E000002800002B +:1048B0000028200000284000002860000028800018 +:1048C0000028A0000028C0000028E0000029000007 +:1048D00000292000002940000029600000298000F4 +:1048E0000029A0000029C0000029E000002A0000E3 +:1048F000002A2000002A4000002A6000002A8000D0 +:10490000002AA000002AC000002AE000002B0000BE +:10491000002B2000002B4000002B6000002B8000AB +:10492000002BA000002BC000002BE000002C00009A +:10493000002C2000002C4000002C6000002C800087 +:10494000002CA000002CC000002CE000002D000076 +:10495000002D2000002D4000002D6000002D800063 +:10496000002DA000002DC000002DE000002E000052 +:10497000002E2000002E4000002E6000002E80003F +:10498000002EA000002EC000002EE000002F00002E +:10499000002F2000002F4000002F6000002F80001B +:1049A000002FA000002FC000002FE000003000000A +:1049B00000302000003040000030600000308000F7 +:1049C0000030A0000030C0000030E00000310000E6 +:1049D00000312000003140000031600000318000D3 +:1049E0000031A0000031C0000031E00000320000C2 +:1049F00000322000003240000032600000328000AF +:104A00000032A0000032C0000032E000003300009D +:104A1000003320000033400000336000003380008A +:104A20000033A0000033C0000033E0000034000079 +:104A30000034200000344000003460000034800066 +:104A40000034A0000034C0000034E0000035000055 +:104A50000035200000354000003560000035800042 +:104A60000035A0000035C0000035E0000036000031 +:104A7000003620000036400000366000003680001E +:104A80000036A0000036C0000036E000003700000D +:104A900000372000003740000037600000378000FA +:104AA0000037A0000037C0000037E00000380000E9 +:104AB00000382000003840000038600000388000D6 +:104AC0000038A0000038C0000038E00000390000C5 +:104AD00000392000003940000039600000398000B2 +:104AE0000039A0000039C0000039E000003A0000A1 +:104AF000003A2000003A4000003A6000003A80008E +:104B0000003AA000003AC000003AE000003B00007C +:104B1000003B2000003B4000003B6000003B800069 +:104B2000003BA000003BC000003BE000003C000058 +:104B3000003C2000003C4000003C6000003C800045 +:104B4000003CA000003CC000003CE000003D000034 +:104B5000003D2000003D4000003D6000003D800021 +:104B6000003DA000003DC000003DE000003E000010 +:104B7000003E2000003E4000003E6000003E8000FD +:104B8000003EA000003EC000003EE000003F0000EC +:104B9000003F2000003F4000003F6000003F8000D9 +:104BA000003FA000003FC000003FE000003FE001E8 +:104BB00000000000000001FF0000020000007FF87C +:104BC00000007FF80000016A0000150000000001ED +:104BD0000000FF00000000000000FF0000000000D7 +:104BE00000000000140AFF000000000100000000A7 +:104BF00000201001000000000100860000000100FC +:104C00000000860200008604000086060000860878 +:104C10000000860A0000860C0000860E0000861048 +:104C20000000861200008614000086160000861818 +:104C30000000861A0000861C0000861E00008620E8 +:104C400000008622000086240000862600008628B8 +:104C50000000862A0000862C0000862E0000863088 +:104C60000000863200008634000086360000863858 +:104C70000000863A0000863C0000863E0000864028 +:104C800000008642000086440000864600008648F8 +:104C90000000864A0000864C0000864E00008650C8 +:104CA0000000865200008654000086560000865898 +:104CB0000000865A0000865C0000865E0000866068 +:104CC0000000866200008664000086660000866838 +:104CD0000000866A0000866C0000866E0000867008 +:104CE00000008672000086740000867600008678D8 +:104CF0000000867A0000867C0000867E00008680A8 +:104D00000000868200008684000086860000868877 +:104D10000000868A0000868C0000868E0000869047 +:104D20000000869200008694000086960000869817 +:104D30000000869A0000869C0000869E000086A0E7 +:104D4000000086A2000086A4000086A6000086A8B7 +:104D5000000086AA000086AC000086AE000086B087 +:104D6000000086B2000086B4000086B6000086B857 +:104D7000000086BA000086BC000086BE000086C027 +:104D8000000086C2000086C4000086C6000086C8F7 +:104D9000000086CA000086CC000086CE000086D0C7 +:104DA000000086D2000086D4000086D6000086D897 +:104DB000000086DA000086DC000086DE000086E067 +:104DC000000086E2000086E4000086E6000086E837 +:104DD000000086EA000086EC000086EE000086F007 +:104DE000000086F2000086F4000086F6000086F8D7 +:104DF000000086FA000086FC000086FE00008700A6 +:104E00000000870200008704000087060000870872 +:104E10000000870A0000870C0000870E0000871042 +:104E20000000871200008714000087160000871812 +:104E30000000871A0000871C0000871E00008720E2 +:104E400000008722000087240000872600008728B2 +:104E50000000872A0000872C0000872E0000873082 +:104E60000000873200008734000087360000873852 +:104E70000000873A0000873C0000873E0000874022 +:104E800000008742000087440000874600008748F2 +:104E90000000874A0000874C0000874E00008750C2 +:104EA0000000875200008754000087560000875892 +:104EB0000000875A0000875C0000875E0000876062 +:104EC0000000876200008764000087660000876832 +:104ED0000000876A0000876C0000876E0000877002 +:104EE00000008772000087740000877600008778D2 +:104EF0000000877A0000877C0000877E00008780A2 +:104F00000000878200008784000087860000878871 +:104F10000000878A0000878C0000878E0000879041 +:104F20000000879200008794000087960000879811 +:104F30000000879A0000879C0000879E000087A0E1 +:104F4000000087A2000087A4000087A6000087A8B1 +:104F5000000087AA000087AC000087AE000087B081 +:104F6000000087B2000087B4000087B6000087B851 +:104F7000000087BA000087BC000087BE000087C021 +:104F8000000087C2000087C4000087C6000087C8F1 +:104F9000000087CA000087CC000087CE000087D0C1 +:104FA000000087D2000087D4000087D6000087D891 +:104FB000000087DA000087DC000087DE000087E061 +:104FC000000087E2000087E4000087E6000087E831 +:104FD000000087EA000087EC000087EE000087F001 +:104FE000000087F2000087F4000087F6000087F8D1 +:104FF000000087FA000087FC000087FEFFFFFFFF2C +:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399 +:1050200000BEBC20000000000000000500000003DE +:1050300000BEBC20000000000000000500002000B1 +:10504000000040C000006180000082400000A3001A +:105050000000C3C00000E4800001054000012600FC +:10506000000146C000016780000188400001A900DE +:105070000001C9C00001EA8000020B4000022C00C0 +:1050800000024CC000026D8000028E400002AF00A2 +:105090000002CFC00002F08000001140000080003C +:1050A000000103800001870000020A8000028E00D8 +:1050B00000031180000395000004188000049C0088 +:1050C00000051F800005A300000626800006AA0038 +:1050D00000072D800007B100000834800008B800E8 +:1050E00000093B800009BF00000A4280000AC60098 +:1050F000000B4980000BCD00000C5080000CD40048 +:10510000000D578000005B0000007FF800007FF872 +:1051100000000166000015000000FF000000000014 +:105120000000FF0000000000000019000000000067 +:1051300000000000FFFFFFFF00007FF800007FF885 +:105140000000035F000035000000FF000FFFFFFFBD +:105150000000FF000FFFFFFF000000FF0000FF0046 +:105160000FFFFFFF0000FF000FFFFFFF000000FF29 +:105170000000FF000FFFFFFF0000FF000FFFFFFF19 +:10518000000000FF0000FF000FFFFFFF0000FF0016 +:105190000FFFFFFF000000FF0000FF000FFFFFFFF9 +:1051A0000000FF000FFFFFFF000000FF0000FF00F6 +:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9 +:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9 +:1051D000000000FF0000FF000FFFFFFF0000FF00C6 +:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9 +:1051F0000000FF000FFFFFFF000000FF0000FF00A6 +:105200000FFFFFFF0000FF000FFFFFFF000000FF88 +:105210000000FF000FFFFFFF0000FF000FFFFFFF78 +:10522000000000FF0000FF000FFFFFFF0000FF0075 +:105230000FFFFFFF000000FF0000FF000FFFFFFF58 +:105240000000FF000FFFFFFF000000FF0000FF0055 +:105250000FFFFFFF0000FF000FFFFFFF000000FF38 +:105260000000FF000FFFFFFF0000FF000FFFFFFF28 +:10527000000000FF0000FF000FFFFFFF0000FF0025 +:105280000FFFFFFF000000FF0000FF000FFFFFFF08 +:105290000000FF000FFFFFFF000000FF0000FF0005 +:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8 +:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8 +:1052C000000000FF0000FF000FFFFFFF0000FF00D5 +:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8 +:1052E0000000FF000FFFFFFF000000FF0000FF00B5 +:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98 +:105300000000FF000FFFFFFF0000FF000FFFFFFF87 +:10531000000000FF0000FF000FFFFFFF0000FF0084 +:105320000FFFFFFF000000FF0000FF000FFFFFFF67 +:105330000000FF000FFFFFFF000000FF0000FF0064 +:105340000FFFFFFF0000FF000FFFFFFF000000FF47 +:105350000000FF000FFFFFFF0000FF000FFFFFFF37 +:10536000000000FF0000FF000FFFFFFF0000FF0034 +:105370000FFFFFFF000000FF0000FF000FFFFFFF17 +:105380000000FF000FFFFFFF000000FF0000FF0014 +:105390000FFFFFFF0000FF000FFFFFFF000000FFF7 +:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7 +:1053B000000000FF0000FF000FFFFFFF0000FF00E4 +:1053C0000FFFFFFF000000FF000000FF000000FFD4 +:1053D0000000FF00000000000000FF0000000000CF +:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1054000000001000000020800000310000004180FA +:1054100000005200000062800000730000008380E2 +:10542000000094000000A4800000B5000000C580CA +:105430000000D6000000E6800000F70000010780B1 +:105440000001180000012880000139000001498096 +:1054500000015A0000016A8000017B0000018B807E +:1054600000019C000001AC800001BD000001CD8066 +:105470000001DE000001EE8000000F0000000000CF +:1054800000007FF800007FF80000021A00003500DD +:1054900010000000000028AD00010001FFFFFFFF29 +:1054A000FFFFFFFF00220006CCCCCCC17058103C9F +:1054B000000000000000FF00000000000000FF00EE +:1054C000000000000000000000000001CCCC020140 +:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1 +:1054E000FFFFFFFF0000FFFF000000000000FFFFC4 +:1054F000000000000000FFFF000000000000FFFFB0 +:10550000000000000000FFFF000000000000FFFF9F +:10551000000000000000FFFF000000000000FFFF8F +:1055200000000000000E0000011600D60000FFFF82 +:10553000000000000000FFFF000000000000FFFF6F +:10554000000000000000FFFF000000000000FFFF5F +:10555000000000000000FFFF000000000000FFFF4F +:10556000000000000000FFFF0000000000720000CB +:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B +:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F +:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1 +:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E +:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C +:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D +:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2 +:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6 +:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00 +:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6 +:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7 +:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE +:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19 +:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E +:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC +:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E +:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D +:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E +:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F +:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D +:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B +:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C +:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1 +:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5 +:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF +:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5 +:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6 +:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD +:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19 +:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D +:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B +:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D +:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1 +:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91 +:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1 +:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70 +:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1 +:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F +:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91 +:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D +:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71 +:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08 +:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50 +:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0 +:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30 +:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0 +:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10 +:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70 +:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA +:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C +:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D +:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B +:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29 +:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A +:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF +:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3 +:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD +:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3 +:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90 +:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE +:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2 +:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE +:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8 +:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B +:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB +:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B +:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D +:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A +:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28 +:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19 +:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE +:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2 +:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC +:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2 +:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3 +:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA +:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82 +:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD +:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8 +:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A +:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE +:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E +:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE +:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D +:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE +:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C +:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E +:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A +:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E +:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05 +:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D +:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD +:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D +:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD +:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D +:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D +:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED +:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D +:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD +:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C +:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD +:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B +:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D +:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29 +:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D +:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04 +:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C +:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC +:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C +:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC +:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C +:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C +:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC +:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C +:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC +:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B +:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC +:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A +:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C +:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28 +:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C +:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03 +:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B +:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB +:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B +:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB +:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B +:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B +:105D7000CDCDCDCD000C0000000700C00002813069 +:105D8000000B81580002021000010230000F024097 +:105D900000010330000C0000000800C00002814038 +:105DA000000B81680002022000010240000702503F +:105DB000000202C000100000000801000002818003 +:105DC000000B81A80002026000018280000E829810 +:105DD0000008038000028000000B8028000200E021 +:105DE000000101000000811000000118CCCCCCCCD7 +:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3 +:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E2000CCCCCCCC00002000000000000000000022 +:105E30001F8B080000000000000BFB51CFC0F003D7 +:105E40008A5B591918EC39107C7AE0A58C94E95FCB +:105E5000C3CCC0B019882F00F12E66D2F57F9642D0 +:105E6000B0CF483030BC03E29D620C0C2B2411E211 +:105E7000D1D20C0CFF81FCD350313BA09EDD52945B +:105E8000B97B140F0E7C471D957F5C15428740C57A +:105E9000EFA2C99F80CACF5780D0F7D4B19BBB0077 +:105EA0002A0F0001FE3753600300000000000000CD +:105EB0001F8B080000000000000BED7D0B7454D513 +:105EC000B9F037E735672633939390C704123C83C4 +:105ED00001820618303C54AA93F068E8A53A3C04C5 +:105EE000E447195034822411D39AB6FC7F4EC8E49B +:105EF0000102C617A52DDA81E2BDD185BDD1466B61 +:105F0000FB6B5710A5B9B5772DA4A8B4451BD06B72 +:105F1000C10237DA72A1FFB2977F7F7BEF939C7348 +:105F20003293876257EF6AC3D2937DCE7E7CFB7B30 +:105F3000EDEF754E141803CA8D0097F0875CD7B942 +:105F40000020BBEF6ADE073556095900154145DFD1 +:105F50004A9EAD17237A7D09B97F85107E0AF0FE2F +:105F6000B839300940C671790053F17FD300A4CC11 +:105F7000969C988FDC1357A6E3D59CCFBC5648005F +:105F8000DA547CBE6D5CB2E7BDEB27E49E6E15E88B +:105F9000CFA53100B5C76F9DFF9AD926FF8D027F2F +:105FA000D68757935F66C08C4B22C027F98BD23BB4 +:105FB000F5D4F37D54D7A54963012ED42D9FFFDA84 +:105FC000D8FECFD78B50DD5EDCFFFE75A052BC80C3 +:105FD0006A28D1897DFB5E0FD0E9CE0468CEDFCC84 +:105FE000F69B4590752DB9DFF66F9A54D407E77A82 +:105FF00089F49BDA7F3F00069DD79CA7777CA2CBD4 +:1060000036DE39AE773E3E1E24F26F3A00ED42F6A0 +:106010003FCD15BB11EFBBF3171923497BFDFE5292 +:106020008815A786BF975E9F117E735C4A3AF27E01 +:106030009FEC6B6822AC071F2AAD375D47F8E8F785 +:10604000CF89E1CDC847BBC7CF8100B90F8C8F4C3A +:106050003A9DDED790938C3F52D1E97F8387F29FA0 +:10606000C95F15C2CAF44EF8ECFC7537F2579A8531 +:10607000BFDA170F38DF67E5AFB893BF383ECEB44D +:10608000B3FDC3AE118C2E9C5E4EFAA4A4CB671D4B +:10609000D79F9FB6205EDDED8B8D9190849F38BC9D +:1060A00026BD3E2FBC83F111402BA5334054C4F5CF +:1060B000FBEEB3ABB7447381409B87711F23F83E5F +:1060C00046C49AEE13089C7E682D1F1722EDEED56C +:1060D0000B500EFCC7E79FC66B6371595719E997C0 +:1060E0001ED616CE23576F11B8709F5B70B2EB703F +:1060F000BE4AA3B418E905B4FD8C7147C4403C40C6 +:10610000042007E06B7C4F00822E91B682BF8E493F +:10611000B60F053A193E5C97DCFDC7A7DABFD23748 +:106120000E2E85F0FF1B01F737D8385840C6A988D6 +:106130000E83E23BC3314F7A843D37E9E3074B9B43 +:106140003C3F8ABF507CDFF757594F8347549DA887 +:1061500014A550D012D81FB40C89B4BD7388222264 +:10616000678D16EC31047D70BA340294B7FB28C3F6 +:10617000C1427F1F7CA7C145F7135C130F3591798E +:10618000CF97F8C2943F34F2DFD4FEFB79B00E19FA +:10619000D9D22EDE0BC8E771C24763C878A3989C9A +:1061A00087084FE1F39A555FA5B95C9C2F9DFC01D0 +:1061B000BA341DC50C59855C0B858827F0F9F94365 +:1061C00072E071A8FC91B6C0421F183EBD82DC6E21 +:1061D000182A7F7CDEF54CBAF697AB7A4ED71A15A3 +:1061E0007C782E2F4A6A7FA4A6EB2394AEDE4288E9 +:1061F0002492E8E902978BCB8161D337F44AE823F4 +:10620000F692F77E1BBDC4DCE9CBF70C800F31CBD7 +:106210008E0F735E4FADA87F80CA4BD2049C4FC1D6 +:10622000F990CF828F1840CECFF3C8DB041F62EB0A +:10623000944E6C432150BB8CFC74BA48DB138C2405 +:10624000B68618FF235D4CF8DCBA60C3AF94E5B5A1 +:10625000B561B9E1B2C2EFA955281C0AB511C83C15 +:106260001A9990A042F24127F2ADC9AFC80697AE85 +:10627000C4F6B76C7CD0A24F85647430F915D1CACE +:10628000F8F55B43D32FCEF596D8E11DF2389FA4E5 +:106290007F683987528F93E043933E048915388194 +:1062A000850F9A6578C93519A0217F29C4C8DD6694 +:1062B0007C44CEB126BCE6211F4ED5E879D9E692C2 +:1062C000104EF35C856026ED37CDA5D3F904B59A61 +:1062D0009EABA22FC2CE57FE3C355C6CFD1CBD357B +:1062E000A211FCE6426B4420F4914A20DC09A84745 +:1062F00023807C0061C61722B7D3CDF171CECF1EAB +:10630000384AC713ED6A68F43CB3CBF15C913C2486 +:10631000F36C2982849BD2A955C5B6542401FA0591 +:10632000443FF9F2A6A39EE63FE28230C29F8EE789 +:106330002BF2C72CCEDF2EA2CF089E7D2576F9F654 +:106340003AE45FE2E7713F7D96C29F30AF4EFBEDCE +:10635000FB2E6EBFA5818FD29B8F075F727BD5B45A +:10636000DB4CBC660B40F109BF90134F85F8DE484B +:106370007BE3BB1909DCB751165DDD48F0609C7406 +:10638000851B909E52A4279D3CFFF09F45EA2F65F8 +:106390002FADBD02D7DB5E678C2DB4D883DB25CD56 +:1063A0008B78DE139FAAC62C7AE66688BDE8B2F821 +:1063B0005FA160D3D8C26B28FF9DEC2EC2A3C2455B +:1063C000F9CFE38B075F47B9E4F77BF1636D8BFD92 +:1063D000DB59B9C0CE4BB8A93442D66D41DD3592F8 +:1063E0003E365C04CE963CD6FE797D4E299E9F2D8E +:1063F0007ED6FEA4FEFD483DE58B981A25F76A81FE +:10640000E3A58BE085D25FCF5D3831355D9CFBDF46 +:10641000211DF6E0FE9FF01D993F1ECFCF99421837 +:10642000D1FE44CD116DB5051F2DEEB2B7111FA3DE +:1064300020E102A45F3C8BCA4F107A7F22D8CEE3C2 +:10644000F2940F8769BFD1D19E52196F2DD75EC5C7 +:106450006B53F0F90C2A4F3047FB90CABFE8BA746F +:10646000F5D0E53DD57E032E8826B3E7378A9954CB +:10647000AE022564DF36BD9EAF517EE4F37E0D692A +:1064800044F6B72783C04484678FDCBA3C9A84BF44 +:106490007FEE1268BF787C5E742DE533761E8CE645 +:1064A000E741E3E2DBC3C80F50A8E7227D242D4675 +:1064B000F5AD84E707E11F398BE915498DB48C27C9 +:1064C000FC1A3A2A8241C6855A33CA54D40F1A504C +:1064D000FB05D1B96422DB2F9EAF6EC2712897995C +:1064E000E47AC9B26F087AFBE4750CAEA3D0752EBE +:1064F00003BDB3846983D37924B497E261968ADEBD +:10650000979BCEA9C63BE91B7031F9DAD87021629E +:1065100010FC351D7709222AC5D6424A2F95EBA6D5 +:106520000B724C45BB71CBD704D84BF130B09D12E8 +:1065300077D82992168DB8C8F89115DA5464A15409 +:10654000E3765608E58924F3960B4CEF6FA978A4FF +:1065500095AABBD7ECFE9EBC3242ED52E2F79523E2 +:106560003DCC719E42C647B08FEC87F49739FF5DF2 +:10657000C85E940E49E4C0BC7E0FE11FDFD71EC584 +:10658000F9CBD9AF5AE4F6D5636C7ED3DEB9903738 +:10659000F0FC267E2E960B7018E1937A3C40E53D88 +:1065A0009BDA61A3391349B5846FC8BA3274D7E353 +:1065B00079B753808AF662BE69D2CFCDE9F3FDFC8C +:1065C0004F3CD8EF3651A0F08C8AF46C41BD3F6A45 +:1065D0009300E88F548A3ABD9FBBB2FA804CEEB765 +:1065E0003442D8A7E33A6CDE96031E7A5E2A5990AD +:1065F000F090FE8742399B915EEE3844DCA49FFB0D +:106600005E2272D82E84844E9ECBB53103E19582F2 +:1066100051746FE060E82EB59BFA2D60E39BA64DA8 +:106620001B55ECD7AC6FEC0AA1DF522851BF45D106 +:10663000AA23945D3F25F830FD0A2217A138740A79 +:106640002554CF277CB483CAE8A67139DA350B3AD2 +:1066500089DCB6647CBD13E133A601954BB403D04D +:10666000340089D813647CFC4E2DBC15F922CB7004 +:1066700059F97437C4B659F943D2DA297FB4FC45C5 +:106680005C9E4C2FDE2B307C5673BD77414ECC4741 +:10669000BC6EA92772E0EADFFF7A8EFFEF1A8B6EDD +:1066A0001E4FF5133B7FCCE75D2EDD16AF1C7951F5 +:1066B000A1FB71DA2FF3B8FDD2944FEC178A07587B +:1066C00080F64A1A277D5318E8737706240C428F08 +:1066D000341E178062667FA8E41FEAB9DCE576BB4A +:1066E000C5EDB04F52D92DDF7445DBA95E232A09D1 +:1066F000E1DFE56A9D3F0EF19DC7FC46E7BEBBB8F2 +:10670000DF3857DC166A22703D992584DD7A1F3FF9 +:106710001470B978128C1397C83C7BF2059D58C051 +:10672000B0A746A0F6C9799DD9E7F08187F6BF8268 +:10673000C3D2B86911F58B7AF532979B6D75AA4D66 +:10674000BF38AF3EA53596EC5CF273FAA4CD8AD083 +:1067500038872F9CA0E70EEE33993DFE6071993A81 +:10676000909E938A94D5147FF965A725BCCE74FAC0 +:1067700045C9E7755EC16A4F8AA9FB0DF5BA85E088 +:10678000E9A46C9D3FAAE239E121E728CA85274C9C +:106790008EA4005EB51C84DF130EFBE8B5BBB49C71 +:1067A000DD8F6EC5AB3AABE7F06CEAA74994EE7BA0 +:1067B0005462075AF031490C517CF6E2B750B0ED03 +:1067C0005F95AACB914FD57C01904FD5D8D7BB2EE2 +:1067D000E17C84FE6343C9F848E2FEA99D6FF69010 +:1067E000F30606A0C3E7E58B5F08A69F6CA717FD1D +:1067F000B1C63D389D7BE9DF2F7EF1B7416F75163D +:10680000A137E299D09BF9D7DA569433292E50FF5D +:10681000C7EC77411863A39F74916852E237EF2A5F +:1068200085A4FAF082A0D0FE443F94882CEEEAC200 +:1068300078E65C71533930B906F4B754E22F50BA98 +:1068400093F550CE9B3FAD5311EF6A4CA1F679976B +:10685000ABAEB45E1A8E9E6470C16E66978C32CFFA +:10686000D90D433B672F9043829DB3D5F43C92BA38 +:10687000ABD55202EF15F7B2F3116DB04CD21E4DED +:10688000CEB7CE501FFF85F83A7271EBE17149CE59 +:10689000A3EFC53F39E046FD950FEC5CAB6D8FA0D3 +:1068A0005EF1E777E2B6F1BC5921127CE5151AA535 +:1068B000B8A591BBE6D17D7C57022A47177061824B +:1068C0008F9D9B9FA8376611B98B443B0511FD62D4 +:1068D000A07A91D8B9DCAEB3AFFBFD4D4204F1EB29 +:1068E000C910F6A008FAEFED34DC16BD4CD6BD0792 +:1068F000D735CFBFBCC276C0F59D76414A7BE02F2D +:1069000022F7B3A6D7A3DF950F0CCE873727EAD19E +:106910004E2C7547EEA7F477F807BDF1251EC75E2C +:1069200033D314227DD96FC93AF774C9B0159B9F30 +:1069300092DE96F8CE3D780E117DB3869F63774246 +:1069400034800FCF8240E36667E148E01A0B9D1F59 +:106950001215B64E8B7CB2DB12B75DDBCADAA6FE2F +:10696000B97B97BD7D172CCA9108DEEE7A4C460F95 +:106970000DEE71F8A375A246F9FB6EA86E423C3489 +:10698000CA4C0ED668208D202ED2861F3F311DEDB9 +:10699000FF9D22F36F3E22FCA55BF4CD3A5F42419E +:1069A0007CBDDF71CDD2EB01C7279A46A2BF9D0106 +:1069B00049CFCD3B5AECF00D06BF135E80CD14DEFF +:1069C0005470486DAE48327B7A9F69B7727AD5AA07 +:1069D0008149180CB9E06157A30CA87D61BCE74957 +:1069E0003490750E70FB9158429359FEA27A065E60 +:1069F000071B7748D4B93E1FDEB83752ACB741ED1C +:106A00005690FFAB24A3DC25F4C5A154B93A328AD1 +:106A10006C497EA9B493D8EAD67E2D43EC572E0C50 +:106A2000D0CF09EF694D3584C9FDE1BE1962C75069 +:106A30002E2E08B14AEAFF73B8DD886711AF12A5A0 +:106A4000278D8B84705D5F0BFAD11E5F07B5473CC5 +:106A5000BA64A37795A9078A80C673D28AECCF9DC2 +:106A6000F1923F8866FCBE93CA170D75922D0554AE +:106A70005FA788F6E14CE94C6F7FB25E25EE6B3282 +:106A8000ED44F54B0DD72F95A03F34AB84CA178D3D +:106A9000C3D5CC1F63201C35D97A18FD7009C211EB +:106AA0003A8783AFAA2EBA2061F1ABABA41E05E5ED +:106AB000A88AE86FEBFD8D4116274EA5B765507586 +:106AC0005F11DAB102C593A891B665DF9FB4BACA67 +:106AD000B91F94BE64007F776390C581D76C199B02 +:106AE000CEE229767D758E9F0F3FDFFF0305FD9770 +:106AF000B3CF9CB809F7B9FEFF8AA09275CFEDF726 +:106B000043273D37120A9E1BEB3AC4A471768006D8 +:106B10009617FF573FA5D7BAE7DD890564FCBA177A +:106B2000DF9F0404BE739B7B0E8D42FBF919178B0C +:106B3000771BDD931693FBEB2458154D325FA1C4F0 +:106B4000ECD4333F495B8EF2EB6A3B703B9DB77DE3 +:106B500099ECB69CDFA32499AE4BFA45F0B9F1B499 +:106B60002B3136895F62E619CE3CED62F0BD2453CD +:106B70003F6F5DDB1E2546E0A86AFB98EA8BD9FFD4 +:106B8000FA6C00F150F59268B3E3AADAC44EF72428 +:106B90007A3D81578C9FBAA6239F707EE9D840E347 +:106BA000A695ED0F7E2C0670BC5D6F11BC843B1169 +:106BB000AFEF88E105D8FED1BF047482AA8F0E3FE3 +:106BC0001540BC9279572BE9189FB7F337CE7F3128 +:106BD000B3FF7C003D348F5BD5BE85ADE7D08B1F06 +:106BE000E12F79FDE3ABFF24D9F3E3D036B4FCED1C +:106BF000FA67CF3F6990F5CE3CFF87270D02F7BDBE +:106C0000FFFDC727BF8572F9338F867ABDEA99B732 +:106C10000260E1C3B512D3AFE70A88CB44FA9DFB0B +:106C2000B53B8106C1B9577E3F5A27FB3DF7DC9F34 +:106C30007374D2BFE695B9B9B8FF9A1766E70E64C8 +:106C4000DF229F26DC56B812747EFD251733165EB0 +:106C5000E657075D0E761C1C8D709E3DE60E635A4E +:106C6000AE8ADCAB9D8A74DA40CF596C6F22F8ADE6 +:106C7000DCDFFC31EA87FE7836460934A845D4606B +:106C800010E9FCFE3C4A2FE8A1E7A3B37FD55142AF +:106C9000C7C9A9E9761E3E5550CF55EDDFC2D67360 +:106CA000D0ED2CFE726D7FBA6D76D0ED3CDCFBFD35 +:106CB0003CCC97778CB0E5077AEDD4DEB878343DDC +:106CC0003A807E30E57F30BCD2FC09812B2A451EFC +:106CD00091508E9E4FEBA5EB02A4EBB3E74703E187 +:106CE0008B5372CFED781EF4BCE2D6303EB0EE95F9 +:106CF00077A85C9D7BE14D45A7E718F85CC4AE3CE6 +:106D000007BD3F87D1CEAC643E3E54EDF377BA0366 +:106D10007DF4A94C2C2CD703F4FE097A3FC1F8BDB1 +:106D2000327160892B09BD7E298D61FA3F914DF149 +:106D3000B261DF6F15F0D9E9E89A89743C310FEF41 +:106D4000A7A2A3B97F0DF73FC342CF7D4C4E9DFD57 +:106D50002B893CE279D74BD784EB1D482297E7F685 +:106D6000B8253CEFCEA15D95341FCAEC99E1E64D04 +:106D70000E39E5DACC9B703CA4E60F26DF83ED6F7D +:106D8000B8F8EB90741B1F99783CF369727D7F9281 +:106D9000EB8B4A30CA475ED9DF0E91206A8C0AF528 +:106DA000C17B061D52C27F679E1169FCA7A9FD2009 +:106DB000D5DB4E3D518971CB24EBFDD15CEFA503B2 +:106DC00093509F9D79F527943F2BF79F50D0BE3F5E +:106DD000D4F623A5BBB84F1EF03C4858CE83333FB2 +:106DE0003C3089E981E471515A6047E0AC7AD93E80 +:106DF0007FD5FE8F6DF3AF37DAA97D30D83A1F49C2 +:106E00009165B8DF8F0ECBD49FFCA85D4C1A27FE8E +:106E10000F3C0F2D766DD39BF37E8BF9AD92235EE5 +:106E20001DCFCD8ECD91DCED68AF1D9181E60FA415 +:106E3000C81FDCA4DDF1A657C7BC73C791A5A26E1D +:106E4000F1437FECC0E78CA3C66C3F996F4637F1E6 +:106E50007FF5FE7A63E671E25759F8A0E6CDF25C61 +:106E6000D4F7E887EAE371BD7010FD5C3130AF9C68 +:106E7000E5A505CD93F4BC66F3C9BE288D4FC99A2C +:106E800000BA65DE5190A8C73C3AF87CCEBC4354AA +:106E9000B5E697961F3E802E66D6E297F3709E0069 +:106EA000C4B50FA9FD09E14B03D85FCE3C8389CF60 +:106EB0005EF94B917748D36E0F1E80FEF3F5CFAF8E +:106EC000C454CCAF34F9D6B4842CF995A660BFFC79 +:106ED0004A4426786871258F478C91CBE6E073E2AF +:106EE0001DC7923D5F2E333EBF11BAEF5F8D7046D6 +:106EF000599E6696035F5FE2F8FAD964B271A242C6 +:106F00004B41976482DFD94B227199DC9FBBB2E77A +:106F1000EA5769779EA731C60B97D2868EBFE1E606 +:106F2000E34ADD8B56CBD983E7E352E585FBE030BE +:106F3000B83F9E69CB4F1C7CF7011AAF97A1BA25C9 +:106F4000648913E5747A208271FE2C9DDA87399D5D +:106F5000F77C672DC699B3F2C31EE83F8F74F17AB0 +:106F60001ACF30F3F4527E84C6E5254D2F15E93A49 +:106F7000CB2298CF6FD681DA1FCDC181E33553E4A0 +:106F80009881F4942EDE40E715545E5730C47D7E20 +:106F90007B7180E23940F08CF24EFD1FDCDF71170F +:106FA000CF87771B22E6C34F64D0FC404082228CFF +:106FB000075C7079C39B43D02F1F9E8A7FB74B8697 +:106FC0004AE3247ABF7CF82ED9124F53311F4E8BDF +:106FD000F9ECF970D557137C5D47FFC662EF86FA6E +:106FE000FAF5C99D231F8E73615CC6689E8D764538 +:106FF0007306F0FC38CB8737F37CF8B38DD366A3E8 +:107000009E6DF698CF67B0FE66DBF8F5AB111FAD4D +:1070100003A1EDD372CF66EC9F350AAA69FD9914DE +:10702000855B2C7AF0B82CB13A5539F2BC6CAD279F +:10703000E2FC60E67B0EBEFB7BCA57781D8374279B +:107040007C8571A99CCED360D5ABE6D5E49F667DE7 +:10705000E0F8AE7C710ACD9398ED40562C1249C2EF +:107060004757BAD9B963F271200809D4AF8199B1F1 +:10707000EFAC45BE0EFAC26914CE07689DC90E0D6D +:10708000749AA770EC6387BE91F2EDF92CC2E516F5 +:1070900079E90FFF0D1C7EE61F9FD7781C306840F2 +:1070A0002C097CF2C512BA8F2972E4B7563C665D92 +:1070B00091BCCEF60E85EDA731BA92E5D12BEC79D5 +:1070C0004F4C335BE3A6D35CB153A837CCFCB9A0DB +:1070D00046797EC330E3EAC1DE78B68EF580F71AD2 +:1070E000A8DFE495ED860BAF592C1F22AAB18FAD16 +:1070F0007C2C69DD4C0E1DF9BDB9E2198A971D8300 +:10710000D06F5B1DCBA76EADD3A8BDBDA52E48DB50 +:10711000CD753ABD36D545E8FDFEFCF4F3E01DC85B +:10712000473E2FCD270DC6270FD585E97CF1BA99AB +:107130006C5E97C9EFEE06E4774530E5C74FDB3E5E +:10714000D1948F2CDADEEE62CFAF514653F931F98C +:1071500079B0FD8989E994AEC39D3FE57E67F986E4 +:10716000B4DFF44EB6EE50D7713BD6D9314BA57A89 +:107170007947FE20EBB4B27506879FE16BDB81D3C4 +:10718000B45EC04DE4DF43F6E1D62249E5C1949FE9 +:10719000FEF3B8A9DE6ECE62F94FB9D0174165DEB5 +:1071A000ACF37C21916BB47FE4A29C32BC2F87AFFF +:1071B000A2F5DC72B18FE6E3E4C29C3BB0BDEDC04A +:1071C00016AD8CEA01819E5FB5D00D58974BC486F1 +:1071D000C663E5C2A2B5D85F43B9247064BA99FF0B +:1071E00024175E77378E3F30E590DE9085E716E313 +:1071F0003FE8966CFCEF94FB94FA2B68AF5F04E9D0 +:107200004E40BF74DB94BB8AA87CAA967AC62475CC +:107210007DA63E217A638D62A9E354608E8179D385 +:107220009DB7DE154EE62F91F3749D92DD7F1E73A0 +:107230007C851CDDA0B0BA74B0D7A527CF4737072F +:10724000CD7C74B58AE7A814ECADA75B9047F0C27B +:1072500052A9D05B4FE733EBE9C22CDFD54AFE25BC +:10726000CB4B3BEBC42F573DDD16A5B79EAE00EBD5 +:10727000E97E2A43B813F3EA6F89E1BD7A7FBE73D2 +:10728000CEE77C2FC23C0752C965A762CF87E6C50F +:10729000ECF950B8D3635BEF359497E2C1F5CBA816 +:1072A0000AFB3C05D5F6FAD72B6A336DED9031D247 +:1072B000D6FFCA9631B6E7635BAFB23D1FBF6BAA7C +:1072C000AD3D21719DADFFD56D65B6F6C4F6AFD865 +:1072D000FA4F7E6991AD3DA57385ADFF355D6B6C51 +:1072E000CFA71D5E677B3EE3D8465BFBDAEE6FDA25 +:1072F000FAD712F34641B9CDE2F5C259B98235CF7A +:10730000DA924DCE25E2B7EFC8260C43E3D9ACFEA6 +:107310004A618F7BF380CE7192AE44349AB71F37A7 +:1073200007AF20D5D0F354D273CA747A7FFA3CBC2D +:107330004289BD0E56D1591D31FA65F67CBFBD1E7E +:107340005811B7D1B206F7F12F77B926F5A7AB924E +:107350006F9783A1D613CBBA63DC30E5E28C291793 +:1073600005442E683CED5311FD1E98E3A7F685C534 +:107370003FA27834FDA31B5488A3C968CA45E9CA53 +:107380009E51B48EAFD72F720BC3A95F33E52F6028 +:10739000D1FB91AC3E3DD33C7368FA554C5C63B372 +:1073A0000F9DD786C0BA54FA31E01E403F4E91A3DC +:1073B000196EF42FA5880196F80B54CB36B8870ABE +:1073C000E7673D07561386B3EA15134E85E86DCC83 +:1073D0002B352DBE893AF55003363ECD591EA5FEFC +:1073E00009B10BAF76DBC633FBF06FCD4EFE8D6C73 +:1073F000DFA7692F9B780F84C2B49E04F204407FFC +:10740000AE69562C88F1B416EC62F10F1F705F491B +:10741000E7690C2A02D6B93776B1387B835ACDE2B8 +:107420000E72358DBF34640B5AB23AAE3BDD2CBFC1 +:107430002BD63E3876DF007C252AC9E30E0D7C7CF6 +:10744000C3816F74B17352D1D19F06E234BE6FC94C +:10745000BF8970381A72E13A3BE83A010E57A040F2 +:1074600080FAD0E070DECCFD1DA976CB80704A0892 +:107470006712BA9870C611CE92D470FAB3CB687EF8 +:1074800052AADD46D731F1BACACDE8E584DBC4B7EC +:107490000C91F2D9D83EF1E5284D8712B223BFEF07 +:1074A00098C9FC66A2D86DFC6AFA2D845FEB915FE7 +:1074B000258DF92FE6FB055F716B0CAF9C8EA067E5 +:1074C000D2B8432016A775E7FE18F3B7FBF40DE317 +:1074D0001BBF1C01EC2FF9049ABF5378BCC2ECF718 +:1074E0009E9BC5891A667547711FCDD74AB019F59D +:1074F0000FD63763FC2E9FED378EFB22F0FCCC9D20 +:10750000C1F891AFEB8525E9B41052DC1F1C480F80 +:107510007B117F23FAEBE327DDFCBDE03CC863FA77 +:10752000B87819E6A353CDE3B44BCCFAE7E1D7B56D +:1075300057D33846B36F6317C681CC381C044B92BF +:10754000C6CDFBF0CAF2897DF45DA67712FA49D365 +:10755000A6523E69CEE7F4AD76D4E99A75DD9CAECD +:10756000669C1B822CBE63D2D9D38BCFDD03E2D3C2 +:10757000C3E5C689CFAEFFA1F8FC11DA28E4EAF72B +:10758000B3F7C2E1E03780E68DF2EDF2688E33F9B1 +:10759000DDB9FF536E7EBEFF0FDDBFC90FA9FB1B18 +:1075A00049FD1433FFE9E7FCA6E2DB4D44F1BC3EA4 +:1075B000F364CB955978FE32BFDA3F334EDFAB959B +:1075C000C1D0502FF8CDFAD912FB7BA0DE62BB9D53 +:1075D000A53AFC1185D72DF57BCF95DB63CEF797C8 +:1075E0007AF1EBA0D7683545FE6A88EFFDECE4F947 +:1075F000B4BC9AD67AF46FF3EE6475F6BB65588521 +:107600007577232B0CC19B85F995D0736964FF793D +:107610002F3F5C3F0A4972A71E42B3E17BAA6E8BE3 +:10762000EFE7DDDB5AEA65CFA7E03CBB54A677F372 +:10763000CA5B693D59C30BE3D3D16F79EDDD651AA0 +:107640009EF79F6415D2B8EED917DD11CCEF9DCD12 +:10765000840A5AB7F5E28C436897FFA1AE2B53B268 +:10766000F0C9D91FBE395D26443AFBFC9BD3254A9D +:10767000AC84EDDCDF70E957D3116EA30C8AAA311C +:10768000BFA629F47D932A95E5B3CC7A9C9D394A0F +:10769000135E7FE261FA382757D881ED5A0C70A14A +:1076A0009DC0E3EDD79FD197613D644697ECC27AC8 +:1076B000B9875D86E123D70B271EA6EF5D2B9DD5ED +:1076C000183621F7C30711E5C658E6675C08415133 +:1076D00088E87DEFE1EAF1D43E76D42399FC2FCD02 +:1076E000061A97E8B9554DEC0D617C58FFF64AB281 +:1076F0005EC34A89D6CB6C970EAB5A123DF68667AD +:107700008C0DEF7E1E2F3EF8EEDDADA564FCC62984 +:10771000AC8EDA77624A3A2491DFED7533E9FA816B +:10772000BC93E5A508D6A7E4EEF43EBFC727819138 +:107730004E8E4839241832C18B6F26C0490BDF3575 +:107740000910D1C8F317EB80CED351A7D26B5B9D44 +:1077500036B69018FADFAD0BD2EB63753ABD3E52E8 +:1077600057449F3F5417B6C93DAE77B288B743A977 +:10777000E5F6725FF17DD8931638764E24524FE8C5 +:10778000B593E78B1E2C9E9ABE66807CC3EEBAAE84 +:107790001173C6726411FAE5D7687BB60E00FFEE6E +:1077A0007AD7AA459837B94F8AEEA5FA3196B7C865 +:1077B000A21F1BE5581E1056BC5FC99C33278FCAF9 +:1077C00023959792C331C03A9BBC60AB0BE3D6794B +:1077D00047D97DF3FD074A2F22683FCE9AE39251A5 +:1077E0006F16433B82A514C7A08CF49F91BDA414CF +:1077F000EFC344FBFDE90A936F9CB78C5CA7AAD149 +:107800003615EDA6CC5DC6B3643F7FEA70EB988772 +:1078100079E8D53F2B187F8FFF5A51D18EC97BF95C +:1078200004AD4B88BBBA156292C11B2D6BE748446F +:10783000CFC4793E802A16C22771D4B1349EF9FB99 +:10784000F89C627CFF2476DADA7FA737761FB65180 +:10785000F1AA41C2471EB3FF9A78249FB4797DEB09 +:107860001B2DABE3066D93FE53583B4EC6BF9811DC +:107870001B25107CF9EA57C5BBBE846DB3FFAA383F +:10788000D6C31E52593D26F8622194B7DEB646DAB9 +:107890007E4B5B626D50D9D5DCEF86837F3E847A68 +:1078A000AEF265573B8246F41EC3FF4B0FD3EF2465 +:1078B000B4D575697199D3DFA40311C90941A07EBC +:1078C0008A927025C610FD31817F1722AF24A2D77E +:1078D000A37E4DC861D49B577899DD382141E6B12C +:1078E000C8D58414DF1FA17959A4E33656D7DB8F9E +:1078F000BF3CCC9EAF05632BFA0DB05FD668BE903F +:10790000C71DCF98E71CF73FEFF5B0A6BCD9F05ED6 +:1079100085FA67B544E35AEB43ADA50A5967FD4FB5 +:10792000426172B242A387D51DACCF68CF994AF8A5 +:10793000A431C3DE7E98D7B906338C8CCC62AC0BF5 +:10794000787834E6ED2BA1F5F66F22BCBF64F9C15F +:10795000D307AE4DBF9EB437FC92C5753774BCA932 +:10796000C4483FC1C3EB093AA67C05F757B94D009F +:1079700021C4E433329EE039D27A9544F864A27788 +:10798000C45C4F01C0D363229A40F860FED68246A1 +:1079900015DB8A3601E566FED6C246E4ABF513CDAB +:1079A000EF2414BE1E29E4F54C23719D07E21877DD +:1079B000DEB7A2FC2B78CCE6084C6E0923D2FC9EE5 +:1079C0009811A779A7FF6C14685C1B53EE9BA66205 +:1079D0003D1D7449E4BA5361F4339AD8FB0CE47E3C +:1079E0008B3C15E9C2DE1B228E24D5FB635F76D368 +:1079F00038726175E41E6A1768C592F5BD2CE0798E +:107A0000E32BF03732CF780D4AF1BD80A73D2CFE35 +:107A100057B87CE97A1C27FA977851CE73C4844111 +:107A2000E7FF1E8B3BEF1412EDF81EA31128A4F400 +:107A3000DD19607C613C524CF9629F5076D57D84A3 +:107A40000E8DAED55BFF0DE99A51084857BCBF912A +:107A5000DCDFC7E929668435A4DF3E4ECF784230AB +:107A6000B07EC5BCFFA26BCD3D286FB76ED93F4736 +:107A70002578CD71475A47103A2CDFB23F1EBC968D +:107A8000D2618C4AF0BEDCB33F8E74D8571F19A95F +:107A900059DAE3FF42AC115A07BE9FCAB394F1C84A +:107AA0003A9477F2FC3595F0E9D399A6BE60CF0BF6 +:107AB000C7F4EA8F0890B346ACEFD3272A391F0AE0 +:107AC0002DFDE710F9FEE727599DF997C87A28EFB1 +:107AD000641F343FDB33414AA0BFEB25B0A0DDE299 +:107AE0009D3886D6CF917D03DA253D13257ACE9A2F +:107AF0007169F70481BEE78DFD911FBC05AC3F1194 +:107B00009428EA4D295F02D4EB92B83B3241C7700A +:107B100030CBBBBAB485F43D514F9125CF0A7D756A +:107B2000BAB41DA29F97B1B5C7BABBF3046257663A +:107B30001D5FE81A4DE65BEAE1FE4616B1B7C9FDE6 +:107B4000151E662F3D1035BE8C210DD0BBF3A87ECF +:107B500082E854BCE6DE56989B2C1FD277AE3BEDF4 +:107B6000EA6E6A3FECF009E5C9EA4F0BBD3CDEE086 +:107B70003B42BFE7510B44FE512ECCF764B9FE30B7 +:107B8000DF1F70D6FB9AFA44CE607BAC995F968B70 +:107B90007A40E2F5439216D6B0FEB1D45F42EDBE14 +:107BA000C7B99E120F5C7B33BE47A1A03E00D45FD5 +:107BB0003103F3FF3D79D08EFC2A052360CDD39AA3 +:107BC000FAA0A94EA5D7A7A68E2B4339796A6A4E8B +:107BD000994664E0E0A49F7661DEE8FC6E26BFE78C +:107BE0000FAF35687CC960F122642B1A67EC7C9476 +:107BF000BE27FB0329FA10AD7BC5FA0502D2B60CED +:107C00007B7DD5082FABA3ADE2F036CAEC79731DAE +:107C10008B072B17AFA671A9F3FCB93B76277DAF75 +:107C2000C24DCE327CCF5105C360DF196078C0F7FA +:107C3000986C798B8B93E8F82A0FC3BF59CFE1ACCE +:107C4000DB30E119CBE1E9FFDE849D1EA6FF65D2A2 +:107C5000C11C5FE38AE46A03F04DD545111296F822 +:107C6000475FFDB542EF9FC3BAF574ACB389B55E0B +:107C70001F42394850FFC8E3AB01E0DF35A27C1A50 +:107C8000947AAC75E2698EBAF57EF2A2DBDBCEBAED +:107C90008515C81CD3981EA7F5A6127CC745E87D9C +:107CA00036EDBDE968D75611F5A062804832345CE4 +:107CB000FF1CB7F7A597EF8B8CD2FBF663C60BCCF6 +:107CC00076E54B0B691CA16A9F8FD6E357A2FE9BFA +:107CD0008C75FD4697DB56CF1FE9C4FA39F9253676 +:107CE000DFE31C9E3F691579B8EF37B8FF9323C4D3 +:107CF00044F652CA618A87B827720C34A6CF24C2D0 +:107D00001371B3DEC2581B478761A702367B69A790 +:107D100097B5FF73CBDA789C9DB3DC9EF984DA3F8C +:107D20008D1EB37D96EABB9D4A6B27EA3BE345B7C0 +:107D30008EE717194FDF93365614D173201E8291A8 +:107D40008887D73214AAE7E22FB8F7A29E9BAAC66B +:107D50000EA916BFE16CC6DBA3D1FF4A329F619B1F +:107D6000AF6078F391F53B10AFE6F3D73276768AC1 +:107D70006C9C4EBFAB917F78F46AD2CE79D14DDF47 +:107D8000EB31FD4D275F2A5E265F4D8EF7F314948D +:107D9000371FEADB6A2A67EEA03DAF65CA9D7271A4 +:107DA000822DBEFF383F67152986A14AF2BC983E56 +:107DB000AFE2746DE27506A9D7C94CB1CE35549EB9 +:107DC00053AF339DCB3B703996B4DEEFB10CF01E50 +:107DD0009F33EFE1D453BDF2CAF5D0169C1FE3BA2E +:107DE000101BE325D77589F6795E3A3A3609EDE03E +:107DF0005F737FBCA8EDE157F1786E7147EEF24CEE +:107E0000A3EF657D17AFC39587F95EE0F1947E7AA5 +:107E100088D95777327BB566FE546ADFD56C1FA3CD +:107E20001903F8491517D36C7A48F0E8FC3B77063C +:107E3000D547151703F4F9E55BCF637BBFA4FF7A41 +:107E40003EFADC5CEF5E879E3D38E9173B0BC9BA12 +:107E500035CFC982DBB24ECD73BC3EDF43F4AE5D9D +:107E6000DE2328EF52087ABF4782FA619BC2DBC645 +:107E70008CC639F968D75AF4C34CB4BFFAC6E3F7D5 +:107E8000E5B679CDF19146B487FAF54F73F41F63E7 +:107E9000CE5F4EFB3BE131F50FB6D1DE92FEE2360E +:107EA000E1A3FAEB61C1315FA6B9FE423A9F69775F +:107EB0009F6BB9F57543423E6D2D45FFA9672DE8CF +:107EC000F8DD871F48616FD8C2B7E75466F7575C83 +:107ED000BCD246EF3EBC8FB3DDFF7D5DD0564F7BFD +:107EE00077AC86D6519F5339BD88654EC7ED1E6568 +:107EF000ABA3FD071C9F158EEB53C071C35F198E9A +:107F0000904D3EFBE028B4DDFFAC704454A68FE7F3 +:107F1000F1EB5C8DBDD73A5777851BC8ADB9E4BE90 +:107F200087F0FA97C95525D7B912183EFA3DD20401 +:107F3000EB4FDAE8DFDFFC97FB3FB89126AA82B669 +:107F40003A0191D7613BF50EBE77CDEAD854DBF705 +:107F500042CCAB5764F594CEFBDD3C6EF0EDAB2B21 +:107F600001ED6962AB277DAFACD1C7FA811A146C01 +:107F7000716EDE36EB702F175C7FE4E7F4B7AFBEAF +:107F80000930AE2B215C49FAB573B89AD408CDC339 +:107F9000C5B581BF07F359E191D34C3CDD40F124D5 +:107FA000A6C0D32A1FB72FB418F5939A825F0C3C52 +:107FB000B9BDF00C8C9F6FA43178E0E215948F442A +:107FC0004EA7265FF2EFDB98F98F26F58B857F723F +:107FD000DAD0E8BB87F7FBA2E95B3A44FA8E30F9C6 +:107FE0004DFB62E1593C4478AE35F92D18A1F4FA05 +:107FF000A2E0593B44787E6ED24BFF62F1F3C01091 +:10800000E139CBFB29692C3EDB54C4DEF7F08AD181 +:1080100087B0DE6130B9F016DAFD6C35DF6BAFB3D7 +:10802000FAC05EC7956A9FBFE1FB4C254F2BE44425 +:1080300036D2EF581D8B07BCCDFD93DF5434F86961 +:108040007CDEB14E5370AF7FA0B8CDFFAAB0BF3772 +:108050003B981C17A4B1FCCFAD31FBB865CBD31C4A +:10806000756106FB4E30C75FAAF9FE5EF0361993C4 +:108070009843C01BC1577A6800BFE172E32B95DCBF +:108080000D175F716D78F81A4CDED722BEA60D1D54 +:108090005FA6BCFEBDE24B1926BEFEDEF9ABF41FA7 +:1080A000F81A16BE160F571EB95DFBF78AAFA1CAA4 +:1080B000A3D36F23FE5D78A0F7FF2F37FE9CEB7FE5 +:1080C0005E3C9AF3AD48E1E7A5C2E7607098D76ED1 +:1080D000EF10F1EAF43FFFDA7875ACFFB9F1CAE7C7 +:1080E0001B365E0781C3BCFE11F13A0CBBAE4D617D +:1080F000DFF574CE93ED67DF5B1BEFAA3E321FF313 +:10810000C75F15697EFAC8EE391BACF540D97E66AB +:10811000FF1F299FBD81D65747D368EDD95121FC58 +:10812000EF2598575EC4C639E73FC2F1F55FBE0C34 +:108130001ECFD6B391AE47A38B07944728B7EC8BDD +:10814000E68D2CF415FBE3FB08E8DB4B300FB12088 +:10815000391C269D53AD3B5CFA1E8DFE6058FA67B4 +:10816000B0FDFE876FA8767A82E2310B7AFFDECD12 +:108170005588CF3681D5C31DC75B79F8DD35A09D05 +:10818000962DCFDD83748AF9595EB043D13760FEF6 +:10819000C4BD78C1837E42B7A3B764B8DC167C5DEA +:1081A000E3677ED5F495C9FDAE08E783BEF12E18CE +:1081B0009F84BF27F37EB7AC64DF07032952B0C8A2 +:1081C000F21EE90ABE8EF9DC397EBE3F40C71F4D64 +:1081D000F15EFEF57CFE654B061E0FD5ECFB3B8485 +:1081E000EF0AACEFB1F6F219978FE3BED81C3F81CE +:1081F000E76D57EC89AF211F4DF0B1F7802408617E +:10820000FD95394F96049D0AC1FB07B25E8079CD7A +:1082100024F37C75A07952E1D5DC8FB90E8A227ED9 +:108220004767AECAE28825118059183F7487EF630B +:10823000F943C60799BC0E7146755AA21EFD5E89A8 +:10824000ECD3026FC7FF9BFD4FF8BCE388A0D1F7CA +:10825000CF1D78184C3F6CE47C9325C6367B306F7D +:10826000B2CA95F43B73EBFDECEF0C15F87BEBA574 +:10827000E83AE31E8BC9F87D8AA512CB7F114E2CFC +:10828000B0FEDD9102CE07CE715922AB37827798CE +:108290003CB7ED5D57904C7E7EC5E5B4C05F64ABE6 +:1082A000735C12BD4F46F95CB260A1ACFBF0B9CE75 +:1082B000F88DC3D1A6C40AA6F8FAF094520F71FC47 +:1082C000741C8B35E0773956D5BA689D40F126C6C7 +:1082D00077AB361D103690EB1E2E7F0B910696F96C +:1082E0009EE0746DDBEB1D8DF0B799F91B9C98C077 +:1082F00071FB2EA0F990C7FD1F34613EA4DB053C45 +:10830000FF1B2DC7FC6F37AF6F7B8E3CAF4778E705 +:108310006453F91EB7E9E31AD4CF1D0AD0BF7BF12D +:10832000BB2DEE04BE4F60F24BAF9ED874A10EEB96 +:10833000871F553A2722DF6437547F2D59FE743F3B +:10834000A7C39F7CD1F46476A07935F5B9D96F9134 +:10835000A4CBC9FA2F2E779C6B1CEE11EECEB390F6 +:10836000248FD9CB878981EDB4B7B81EFF9523CF71 +:10837000BBE458F23863975FE0F396ADA7E796E168 +:10838000D669CD3487C7C45796C1F0B4748968D311 +:10839000B7AB16A439EC1E86D79BDDFA93B88F478E +:1083A000F7FE62227D2FCA713E78C59882CFEF8694 +:1083B0004E19F5C42951A7D7B7EBECDFFD7E1B6240 +:1083C000DBA7E1F9592B2695ABF739FFBCBDFC8E35 +:1083D0005B28FC715143F84FAC1C71D34CD42FCBAC +:1083E000E5F05832EE44FC7EFF5ACBFE7BED1A07D7 +:1083F0005CBFA9B863C0736BD9723BDDDA14661732 +:10840000185F6172780FE1D15994BFBAB7CF20EBF2 +:108410001F49644ED9CABA03FE7DA7C5FCF7534273 +:108420006CC70CA26F4E0B2C4F627C9DE98D258F83 +:10843000451B31757ABAF69A57BA49BF8B7C7FEFE4 +:10844000D50E7C3E3AF969DC63767B6FFA31507069 +:108450007CAC26F979B0554BE37FC72B3C1AF5CBA2 +:108460006D9B92F7FB213233A1EFE9FF162B92C5EA +:108470002727680CDE55D1E4E327687EF61CCFA5DC +:108480002478FE2090C6F59C361AF5F4AA14F076EE +:1084900007D8F9F57EE303B7A11E3825D8F5F39187 +:1084A0000093D7F600E3EFD37B57C8D948A72697A8 +:1084B00086FC7032233C01F96D75FC047DDFE55FBD +:1084C000020CEE43DEA81E9886F2B2686E36A14B0F +:1084D000C74A08BBF4D4FABF2860EA7F16AF25E785 +:1084E000DF0778FE91A11F50FB438A8CBE75229D49 +:1084F0009AD6819F168C75B4CE70AF97D595427879 +:108500009AD58E9FCEE13EBD6F78F4BE25EAB0834A +:10851000FAD97FAD9574DD7D691AD6A51C29173B64 +:108520006F24407EB82F8D7EBFD62917A9D61FAEE7 +:108530001D787ADFF0ECC0C1F6BD32101A921D78BA +:10854000BEFCD11D2528474AEBA464FAD7D4D347F3 +:1085500079FCDDC93FE6B582F3C5A9C4C070DDBDB5 +:10856000CB0ECF6DD576784C79399568F0AE463C18 +:1085700041E744AB5D0A73A60D72CEB2FC542A38B3 +:108580003705EC7A02390FE9700FD737EFD53E1A6D +:10859000B0D2C1B9FFD302F70F9E6475B963A3AB24 +:1085A000CBB2F53EFEDCC2E7BFDC7C699E33CE7900 +:1085B000FED6F9D03CE706E3C3AC14799C027C718B +:1085C000998C5F2D690AE6EB0B023A6B83360F5FDD +:1085D000D58299E6DF57D147E3FB5FA7F77AE97BBE +:1085E000C0C6567702BFDB7E6AEFF513ACFBE9E24B +:1085F000F459B524837E9EE294109E9F4BEBCE44AB +:10860000FA9DB5B78F65CEC3F6A38705D4D0705B4E +:10861000CD6A11F7F77A80BDB7B36AD39BD41E1C1D +:108620002E9FAFAAB69FFF13701FD9163B4BEA29A6 +:1086300041FE49858717100FE8074517CE45FD7C99 +:10864000C72617D5B72FF279EE9022546F439C9D21 +:108650008FA0127C9023E4046E02F1F138FFAE94F7 +:108660001455ACEFC9ADDDF6C05CAC7B75CACB97D9 +:10867000D3199EA6A433BD7DC81B7B2F90DDA79F79 +:108680004FBAAA0FE4922EEB039AF91D5F2AA7E6D0 +:108690007ED673B8889DF62CFDBE30DF1FF438F807 +:1086A0004D68ADFC29E2BF4CA57681D74DF43ED68E +:1086B00045FFC04BEBA84CB932ED1DE7F8A552CCF5 +:1086C00066377ECAF59ED976DA21FF382F92F71FDA +:1086D000931E1A929C5EAEF36252FAE5392F04CED5 +:1086E00067CE73A357AE9BD8FB20278E7D32379978 +:1086F0005CDFF819E170CAF3A9BD5EF65DE31BFC0F +:1087000054EFF4F953B909F4979D7281FE147EC7B2 +:10871000E3D1BD6F4CC4BADE13DB1FB82D193DAFDA +:10872000D6781D7677AE2D9EB72600B4FE1BC87A8C +:108730004F59E637C7F5CACB20F1CBA52BAEA5FE26 +:10874000E4DB2BAE1FBDBAB8BF5FD1AFBF2BF6F8CD +:108750002DB86E3DF7A777B82BF626F303395EFBED +:10876000C789EDF6FD2D9B4A1BD1A5DE9C76C397EC +:108770006249D6EFF56B36258FC7FD9F74875F631F +:1087800010BF86E0A37BA5189859D2E7D7741B5F6A +:108790008C5FF33BE8F9F71954FE93C3F7643AB3DF +:1087A000534F29B11DD712F84E13FFC740F911C816 +:1087B00038E497EF26F7D71EE1E37EB76998FAEA27 +:1087C00098DD9F49257FBD707D4EF96B537A0A5025 +:1087D0000FFC6ECFA7EF3E80FBD9E3A5F876CE73F2 +:1087E000A32672FFC24BF9D63C9F3B14A6FF7FF72E +:1087F000D591F4EF553BE503A0F5A6EBC8F3E37B79 +:108800008529F81DC4B6BD6915C9FC9C159A8BFB5A +:1088100017F6780F70FBEE16CE6FDADE67AAADF1B1 +:10882000E877B8BE32E300AFA4B37376C982850A95 +:10883000C67BD6F6C69B803A2BDA55F97BF03B52C5 +:108840006FF1F7B98C35FEA4EFC7FD82F3E56071D7 +:1088500088E52BED7182250B063E6F3E4C24AFCB95 +:1088600032F939D57AC33D5FDA12C3CB8B0DB64FDF +:108870008F36347FE416A8FE12C63B964258C6EBEC +:1088800012A89EF85382CA0F772DA6F0BC65FEDDB4 +:10889000E14FEF9F68B563FE8BE3FBFC92FBBF8A61 +:1088A000EAF21DA57A62B2F3C919F7792B053ECF1A +:1088B00070BBE71DA433F2EB5231299DDDDC8F7FC5 +:1088C000672593A3FF0F425212950080000000001D +:1088D0001F8B080000000000000BDD7D0D7C54D5CF +:1088E00095F87DF3E62BC924992433934FC2840075 +:1088F0002206984008A80813422428950904080A6B +:108900003A7C88817CAAD8B25BB74C0860A46E1B05 +:10891000566A5DAB74A0C152C536D1D422A638A028 +:1089200028FEABFF06EBBAB845775017F9924456CC +:1089300017BBEB963DE7DC7B336F5E6620B6757741 +:108940007F1B7FEDE3BE773FCFF739F7DC3B972EF8 +:10895000C1DF0CC62EE99E8BAA5516B232FABB04B3 +:10896000FFAB9E9B145576D9ED8C3919FBC7A5AD8D +:1089700089FE22C64E19E065096381C7D4E06E0501 +:10898000CA41FE5EF6E7B22B54FF547041AADF36AF +:10899000783CF9BCEB5118774C649C65CDD1E386EB +:1089A00059602D73C038C144FBEE0286FF0C592676 +:1089B00046DA77DA0D340E3B9569602EC6EE936D7C +:1089C000E38CF7BB0DD0C15583EB571BBD26BB66AF +:1089D0009E2B52DD8C4D8E94ABE746CF3335C54E82 +:1089E000DF19B3E7FB92193BBD2BD14BF0989E1CCE +:1089F0001C05F3ACB0B2800DE6F9F093D7BCCF46BE +:108A0000305625E051EDFBD484F0386DE8DF9C8CC6 +:108A1000EB7ACB60DF0D43951EF39AB4F05B9BA21B +:108A200050FFA73B2E0FBFB5297C9E0B2AA3E7B7AB +:108A3000F058625459BFDE7FFE9B072662BFFFFCE1 +:108A400037174DDAFE177D91CB421991F21D358A09 +:108A500037583478DC8E54F390E0DEA183E31D5F59 +:108A6000E453FF0E953577C65897C76EA5FA0B7D70 +:108A7000652627C073E5FD8A47812E8AED6E1A6F41 +:108A8000A591793B613ECCE8CEAF02B83B5B9BEF52 +:108A9000F3C5E8678D9DC3EF339B2FD57E19F8BDD5 +:108AA00023E841D65B64F49B62D55F5C130DDF3035 +:108AB0006395B1E67FFF57A44739BEBEFE50E7512C +:108AC00097C2F932C312FA84A9F0E21CF453FA15E2 +:108AD000C6D5D5D78FFBD702EEF1C63FFD47B536D9 +:108AE000161CF60AF8FB7D403F31BF27D3F7B75875 +:108AF0007BE37EE2EF24CF6E0443C7CAEF01DAD9ED +:108B0000EA39F7BD0AAFD91F920B68FCA5BEA315C1 +:108B10000856F6E5C3E311EF9F573EFCBD1298DA05 +:108B200069B3BF35191A9CDEA87802EEC1E3BC8593 +:108B3000EBB430F6F6062BADF70FD096F0330BFE04 +:108B40002F9BB131AAB70E850AFBB6C5BD5BC3B773 +:108B50008EF51737B0F18CED31FB36E21446DFFFAE +:108B6000E93A86328F0569DE1F983C6B08DE8C116E +:108B7000DF1FDF65DBB915EAFD3199E3032839DF33 +:108B8000374E23278C762A0F153FBF8B839FAF2A42 +:108B9000A7E43AE38D0390A7F9CE9F696B5352196E +:108BA000EB36BBEFC4F5F4CF49B0EF0214CE377B00 +:108BB0006F46F8BC75D4606829A06E8D48A70BF885 +:108BC00010ACE09682EF8E2D41F963F226C054AAD4 +:108BD000A00DBB16E868A62D80FD95FC6EEED3882F +:108BE0009F876B2C6E15FB9BEE7E4F85F2FC9B2CBA +:108BF000EE8DD05F69EF88830EE87FE15CC5CEA083 +:108C0000FDAC39A39C61585FD27AE82707A7F79D8E +:108C1000CAF2918C3D85835DC7F8840116F3155126 +:108C20000E3CD5360BE4C15867B7C106A05EB8ED5F +:108C3000A9362BF4BBB9C597654F83C9A6B5B459FE +:108C400087813E72797B6778189B9AD65A69BD01F5 +:108C5000D6F998EC6F539B378FB1170DFE0205BE06 +:108C6000DF91F644A511E6EF2894E377D2F7453774 +:108C7000ADD9BD0EFADFBCED50A511E7BD548EFF96 +:108C80005A65B911C69D26CB6F58B1EC4812ED71EB +:108C9000BE5319338D88CCDF9805E3A7CBFABD9579 +:108CA000B3A0ED3B65CDE54618FFDD6DEFB41525AE +:108CB0003036656E99DD0BE5F7D3CE5726017EBAC7 +:108CC00019D029943F48EBA7F93B5483E8FFD336EA +:108CD000EF349C4F602C7E57029FB5551633D660FB +:108CE0000DBF8AE4DAB43E6075C13F262B9C4EACC2 +:108CF000A6666F2EC0CEB4AF2C944BD369E7F4991F +:108D0000171A877A6CA03C06CAE334E52C5EEEDEC7 +:108D1000C8EE88256F83E95CEE7527C6FE3E318D6F +:108D2000CB03801BE993D463CCBB37865EC94EB3BB +:108D3000513F871359C09A1EE1B779C0C353812FA1 +:108D40009995CF53F633487FA4713DCB02F3D2916E +:108D50006FE66217B0F4428F1240BA66CD49C15136 +:108D6000483B2C645C80FA4335D07C9DAA72471541 +:108D7000F4E74A64FE2E783A331895A1BDB7CB16B6 +:108D8000E9EF0D41F71585BE0EECAF2233BBB8B548 +:108D900020D20FCC7B937562D4BC8D53D3F1FBFCF6 +:108DA000E2BB8B34F02CE2EB003AA07630CCD3332C +:108DB000800FBA7BC78ED80AF3FB5027774B7BE72F +:108DC0009B18D4DB9C2EE4899BB7779673F9D37FED +:108DD00077527017F2A7D5538C7892EDE60AB897C0 +:108DE0003F30F78758AFBED7C42C506F5D57592618 +:108DF000BB8C5EACFFE27A169CA4291B4366943BB5 +:108E0000F55F4CA7F7E50FBC61463EC57EDCB0AE12 +:108E10007509DE4C0FC2AD3536FE196BA179D47FD2 +:108E200091C60293B4EF399C22FD3BE8FB95D61521 +:108E3000E94F65C18CCBF567A6EF0370370AB89B85 +:108E400063CFF35E49A7006F8386BE160A7A03E9F3 +:108E5000E7457978FC96A25D28EF23E36EA476DDE2 +:108E600046C023DA81BD896EB48B4B8D5C7E96F64D +:108E7000A6DB034A843E245D48BC76A73797D17AA7 +:108E8000AB14FBAE82C1F3FA6B392FA14F3397FAC3 +:108E9000D5E59AF9497E80FEBB45FF2553897F9E23 +:108EA000E0FC007CB30CF917ED165C8727346E7E6E +:108EB000F2E0F97F0CE485F5018F1CFEDFB005516F +:108EC0000F48B80D867FEE15F0994FDF4B7B0F9959 +:108ED000719DF571F8F6DBE929346EE6B1508A1B15 +:108EE000EA9DB57379D5DD3929E17AE48BB9068637 +:108EF000220CD78DF66AE980BCBDE1F599A01F323E +:108F00006519E5AD1BF130207F43566BA47EC3DFAE +:108F1000DD306713D4775800FF4564875A99C69FA0 +:108F2000F8591A976353FD2CA6DDD2929E4CDF258B +:108F3000BCFF7E7D39FB10D6F7AF76CE9753C301C9 +:108F400005F122F95A2FA78E083C1EFE1F9353CA23 +:108F500015E454959053FCFD6130F3B19ECB151A86 +:108F6000A7804E5CF1FAA451E8CFDC93A5BA3F028A +:108F7000BE5AA078863D03FD565BDD9B93DD113A1A +:108F8000A96656B70DE10E46D325D4FB7313A88C02 +:108F90007F68975C6857381D32776AF5B8F8724871 +:108FA000CEE39E2C338DB7E2C151A97EEDFC849EA9 +:108FB0009867093DC30A07F3B92CC3FC1B0CAAE64A +:108FC000BB8DEBB3AC64EF87698087B7145643F36E +:108FD000D1D94BFF21FC36BDBDB449D8914E342FB9 +:108FE000898F0DE49C66B659828C3709A09F9AD967 +:108FF000C904BF860CF51A3AB8989647F358BA18C0 +:109000003E4E00A6B4BE3CE1230D1F1DC1F9905E8B +:10901000084D463E05B119358FA5AA2F4F41BB35E6 +:10902000D3E24139037822381C4E60C60418F73564 +:109030007822DE2AD4BB0F9A1C48078AA795A0BFC6 +:1090400053D8A72C84FA66DE8C24B25BD997F78EAE +:10905000AC0278389338DD423F56D18F95E844C84A +:10906000BDDFE65FBD0BF593949F120FEC4B95FAB5 +:1090700093DF0F2B557976281F765E55DCAA44DBEB +:109080003F680F45ECA7C40767033F4EA9EC0C19D6 +:10909000EC285592E77C0BED70B09F12603D19E90A +:1090A0005C0E1C2E08A829D8DF285807BC7A35D1B9 +:1090B0005FD46C8BE0036C1C3FE2CF6586A78DF319 +:1090C000073EBBD23932AECFE0CFCDE2E94AE1F57F +:1090D000F5F4F6830CCE9F6B150EEFAD655C4EE894 +:1090E000EB8D17FD36580395AE115AFBCAC7900E8B +:1090F0008D8CDB5913D2059D947378953FB0341550 +:10910000F5E6E7BD0B535951448E6E56FC760FD4ED +:10911000DF6CF27D9FE21DFFA032F447CC697E7BBD +:109120003AD4CB488AED2F57A7F3F966A03F0DF547 +:10913000BE27FC1DD317D7909F7D23DA65F03D2510 +:10914000AB9AE439C2D00DFDA6B2FE805D83BFD4D8 +:10915000A98628BFC1F4C5786AFFD5ED86E23876C6 +:10916000434994DD20C7D5DB0FEF6DC8A2F9CBF6DC +:10917000CBB2DEAE609AFAB7B3F066ECEFF675B933 +:109180005171A27876C75A8127B4130231E7658EF0 +:109190007AFF1EF88901EDF8A7F8F891719380D154 +:1091A00022E34E48F7D6A5133F4DB39FBC061E6081 +:1091B000BB5F5249DF90DC07BDE4DD69237D548944 +:1091C000F25AFA47C8F7F654E4EBB27BD3276BF4B4 +:1091D000A368A797439F087FFA13A167528F497B23 +:1091E00031D1AD28117D33585F093DA3938B57B220 +:1091F000AF815E035AFDAFEFF787E97FAA5D59188B +:10920000873E46FFB7D895A5D3FCEA38949B950ACC +:109210001B058F29B3A2F5FCD3E9DCFF783A3D2981 +:10922000CA5F99BF34BADE2FB0DE647C260DC95FF9 +:10923000D1EA21454579C7FB6B14F45070E62DB394 +:109240001BE4EF19B483A0DED10CEFF348579B1257 +:1092500053C6A37ED8F99FE56376C2BCFBDF3479A1 +:10926000766177FB387D942D59D76A84F7A64EC571 +:109270006E6191F9D9D6774D5805EB3D28F054EF42 +:10928000E0EBA87784CC2361DC9C7A3E7E5EE741EC +:10929000C5A8916F79B5BCDE6FD24D51FAE6B758CB +:1092A000867EDE94FE070BB65494607DAF712B88EA +:1092B000BE9C4E85E2C139CD0000A0831C0FEFDFBC +:1092C000E6092A2B8B22EB6C335415A15E687325BB +:1092D00079502F6439FCFF80EBAC3F1E0A2198A621 +:1092E0001CEF35A27D37D1E17D87F84AACD3ADDAEA +:1092F0007350AE261DE7F36BD7D13B63DF15F3DA6E +:10930000C5E5ADCA8E30C407CA0E18CFB5710CE9D9 +:109310002559DF952EF4848BF99F25BB8AB531C280 +:1093200017A375B8368E26FB5EE23362475D3D11AA +:10933000EDA8C28742C615D06EFFE386CA5876E212 +:109340006702EEB08E3EED3AE2F185D463B29E291B +:109350008E1F2DE93DA932B67D0A1A80BE972D7168 +:10936000DC8AEBAEDF6466162502FF890E9F21C3FF +:1093700089F8DAA9206C247D6D4A7F4AC985F5DD1C +:10938000BB86D955167FBEF5EB9F9BB04AE36F4174 +:10939000FF848F9D6656ABD5A7D29FC8C9E0F6F46F +:1093A0006A872F0DC76DDCB7CD8CF85DD371C2AC69 +:1093B0008D770F5AC710E1A5D4723FA5BEC61AC457 +:1093C00075962D3112FEEA369983288FEAF7768555 +:1093D0000C684FDFCF3CC8EFF59D5DAFE6005C72D7 +:1093E000EBBD935577A4BFDCFAA082F3710111F6AF +:1093F000929F1732A37ED6D335DAC36897BC9AC042 +:10940000F9FD5C992DA000FCCE99FCF558EF5C7637 +:109410009227501081F76B5DB38F28C0D2C9CF5A05 +:1094200042F86C33ECCAB242BDB6B1660FD2D14439 +:1094300087BF3403E0946EF47563FB3447B2A7052D +:10944000DABA2D6C22E9E721C2618A8E1EA6DCCF32 +:10945000F9A4362345DA7B13510EF93278DC156313 +:1094600042289F5E35F1756C627CBE5DE9DE0AC400 +:1094700013B3A7D3B839F52105ED7DFDB8117AF204 +:10948000DE9CF115E81BEC3C33CAF53A2167CA961D +:1094900074281F6AE8E0563064B05ECEDE9D0AFA9A +:1094A00081F0BDA5C241F59905E5CC5EBE1F51070F +:1094B000DFEFD4C815B98E18F26539C2D776BCF77C +:1094C000152E5F42447F72BE7A7C3664B869FC1BFD +:1094D000C12CA0F7E6C01837F4F7EA8844EA4FF247 +:1094E000BB9E3F1B049DE7D474281837702471BBC2 +:1094F00051CE4FD63B9A31F36E9CCF94CA5E8243D5 +:10950000438D91F026E75361F68D44FF6B83E8EFBE +:10951000D0E2F7CD61286FFFD551A2C78676C54B43 +:109520007E41FB51F3428CCF057EA6623CF6666E0F +:1095300092B0477E7994F4C8CDDD3C4ED0D0DD6545 +:109540005C698BD069C19943B7239D35745A5882A1 +:1095500082F8E376AB9E4E41BE10DDB38099F6B340 +:10956000403E06489E327F01FA2352FE7689B81F9C +:10957000B3F1F77F27E62DFB8DC8CD04A2F7823328 +:10958000130F59019E0D1EC503A612D8DBBC1EF495 +:109590001F22F9CBD808F4CB64FF7AF81D10F679B6 +:1095A0000C3CEF40B8EAF588D4AB053B66327C4A08 +:1095B000FC1905DC65BFCF6498A9DF67328CDCBF7E +:1095C0002BE3F1EB4D26AE3F36B55883C8D7AFA598 +:1095D000DD7844190F704A3787F079D8B0A21EBFE2 +:1095E0001FCEE1F368336C1CD3CCF5D7CF713E8727 +:1095F00016A7302E9FB83CDAFE1C9727F5011BF901 +:1096000089F5FEEA55B4FFE048F0A0BDCFFCAF9865 +:10961000172647E8418F5FF7B307CD6EF87E7327B3 +:10962000E78308DCB89E92740B728EF0DE952EF7FD +:1096300023FC050857F0DF5B30CE20FDF794A5BE74 +:1096400040B27B30BF6608FF7DB2F0DF4D53AD7F87 +:1096500051FFBD6EFD6FB2B1BC36EB757A4A7E012B +:109660003F318AAF7E2FF01D12CF0F04BDD4957409 +:10967000123FD47DD44C7C64ABE4F2C4763C5A0EE9 +:1096800032F6B7C22E7888E05091D479A38AFEF0E2 +:109690008F157B2B8B3FEFBB94E6FF7F2DE2A54B15 +:1096A000A57D29F62558F5A500D704010351EF3310 +:1096B00041EFE7F60022902F8DCDE6CBD9BF57EAD8 +:1096C0009785DE5610DF7502D6E7F6965FFB2F18FA +:1096D0004FDC93EA19054B3FBB77C15FFD0BB43FED +:1096E000D731C3837ADAD1EA23FAE9772678306E64 +:1096F000E850C1B2057A68E97C39E57ADC177B7AF3 +:10970000C244949B490EEE079E794E5D8FF0D9F8C6 +:10971000D35F4CC7EF75412503EDC6737B7EFC47D5 +:10972000D48BB51D4DE869B0D6A75F223BDC10DCB9 +:10973000C9DFEF4925FBF2F44FB64D47B8B776B60F +:10974000D2F7333FD949E5433FFDC5817F477BC30E +:1097500097E2C17A679EDBF69D7F473AAF4EF1E014 +:109760003AEAFD46BE6F2BE95B2FB7BA0E129F4A4D +:109770007AB919F52EC2A986CB1F49CF1F887DA5BE +:1097800015E5B63694671F6C4DAE8D154F9C20D6EF +:109790008B31179263350AC5D3DA806A30AED19621 +:1097A000C8A6E233A92864CE8571162FED9A4E76AD +:1097B0004FE0C46AACBF605F02DB4AF1370CDE8267 +:1097C000FD4FA4CED838108327C14F86DE3B2E81B3 +:1097D0007DFD0EC807D23B3AFB7F41DBEB7F403972 +:1097E0005A6D0D1F74BA23EFDB449C06EA93DE2901 +:1097F0005D173B1E3AC561137CCBF5664E77559ECF +:109800009BE484C5334A63970E3BD6BC15C410CB8A +:10981000A9EDBD11D771D398E593882E30CE87FA84 +:109820002760A3FE1B304E097C56E910F10F3B73F5 +:109830005C07E3571899C3864FC6DE36911CD94D95 +:10984000FD82FD417695FBA5C5BBD11E79C4E4CF51 +:109850009E8CFDB409BDD5C1E70DEDEDB85F0AFDE5 +:10986000D9AF9B48FDF49AD2A97D80B79FDDD1A2E4 +:1098700044E60B949A8F7A0BFB2BB1A19E09D4106E +:109880007EDC665AD719AC924DEB1EBF6C5C847FB0 +:10989000F5F11D9467B80FBCDA51B6DCE18C3C657C +:1098A000DC470FCFDDE2FB470EEF7207CE634F467A +:1098B000945E8967AF1C5A7C9EEBDF174F90BC69A2 +:1098C000443AC6F1FD1F45E9DF95928E5F38417439 +:1098D000BC721FD7BF8DFB8ACD48B7673778D98751 +:1098E0006080368A7DD64794F06A8AF3BC9060C760 +:1098F000F8DD79A16FEA1E3A7112F74747ECCB26E3 +:10990000BFFEFC0B0935D8CF618381E07978D7356C +:109910003B5B15ED3CB93F007630916A23D8A9DC5A +:109920000E5EB50DFDB3865AE641FE6FD4D14FE30E +:10993000BEA3442FD20E2ED8317F15B73F133C095A +:10994000E8BFCDE2F628037B14EBA7CD0AB69889D1 +:10995000BE8A4B91BE0E2D3EB005F578E32C66C74E +:10996000FE1F19E67D2197D6A330CC6779C4D43E7B +:10997000D308ED1FA970DB019200B70EB27BD91896 +:10998000B3D073ABC85E6ECCBACD437CA697072F1D +:10999000B490DDD5E84EA4F9DCBC4FB987DB2336A3 +:1099A000C6E7AF107DDE1CBC3E88FBCA9F08F849A5 +:1099B000389E37F5DE8EF038FF4B2044F87EF32CCE +:1099C0004EAF69B33A498EBCF6C26CD2E3922E9385 +:1099D0009FB7903E4F37DA150FE9B505162D5EDBC0 +:1099E0004D5C2FA5093D53F810C7EF2F043FFDC272 +:1099F00061104FB3A073116FB107C6A3DEFD44E041 +:109A00009FC408CA77214F1A5685889FEAF7F2FE4D +:109A10001C166FF1BD1AFA759473BD28E3FEB80FDA +:109A20005015435EBC2DE651B063C536B4976F0246 +:109A3000BCA34AC91923E428D005C22DA7D6477470 +:109A40007093E32E8F5A40FB07E427F6B79859AC82 +:109A500038CF31B12E6786AF04E3CDCECC64B2737C +:109A60009C6A992101DB152B9E5D6EDADF243BAFEA +:109A7000DF99EDD915C5EFBE1203D43BE54AE67870 +:109A80000EFED6387F1CF2A15BFAE95176DF607FCB +:109A90009BDB8D73DB03E3D10F91FB17120EC19695 +:109AA000C41AADFC7C5FC02178358FE7837D6FA33E +:109AB000F8B51DC641BF7ED7F53FE17E7D2BD57B36 +:109AC000CDC1E31915B03EB4DB9C85BE755C9F2605 +:109AD0007B62C163B543DAE5B717A35FD9586DF36D +:109AE00020BF6D7F515941F48CC141F4B7FDAB08E3 +:109AF0000F0CF080FCC0FCDC2F6D6CF60563D37B93 +:109B000015F15F23F29F42F44EF176A0F720A7777C +:109B1000AEFFA4DF8FF2B12AC67EA8942F8DE6F0A7 +:109B200068A463C90F8DD3C3A3116E439527E74D76 +:109B3000C0FFC83F0007E41FC92FC9FB399F6C6DE8 +:109B40007197E1F7AD15CCDEAAD1477A7F09E78995 +:109B50007EA794EB590E5FBA13E30086D016CCA310 +:109B60009072B871FF83A363E5B949396C3572F916 +:109B7000660D26055B35F4857B7BC913E949793B86 +:109B800049EB63C745463979BC6EA879112ED4E5F7 +:109B9000286F762505515EC93891BEDF4CA7121596 +:109BA0008F917E0BEE2F60FD3227B7434A9C9C2E8F +:109BB0006F72CA786C30CAEF711BFC27309F289EE9 +:109BC000FE92EDFE52712B398ED4A37AFCCBFD119F +:109BD0005C4F5551FC7AED07B97CD2D3E37C617FB1 +:109BE000A5E25AE17F3F17FB5983F1CBFB6135C6F4 +:109BF000A8FCB73643576DACF8D7C10D222F6ABB0E +:109C00007148F9753F17F5BF27F2BFD85263543E2C +:109C100095CDE36EC1F8E9841E77B14AE3F2385678 +:109C2000F274F629EAE194A9ED63304FC9E98BDEBD +:109C30001FC9AC498CDA7FC8F6A74795736B73A22E +:109C4000EA0F6B1E11F57DF8FAB151DF0B0213A379 +:109C5000CA856DD745D51FD53E33AA7CD5A33745D8 +:109C6000D5BF3A383FAABCB5A5B306F172CD9E5B0D +:109C7000A3DA4D30860DC5F07E5CE78AE83C311DE5 +:109C80003C67FE518D49873F7016103E27EC8B864E +:109C900047EAD46878605A1CF697CA447F897FF0F7 +:109CA0005C2E8F3595193F0BCBF60583E98159ED75 +:109CB00025DAFC8308FD04A3F2DF661A55DD3C02B9 +:109CC0007F12FDC59BA7DC5F8BBB8E3870DB27E462 +:109CD00084848B492C2B757ACD65E162BA125C586D +:109CE000D83314B8E8F7F706E2CDBAFE3626355277 +:109CF0003EF0DB58D0D8C761C147B2BC2890CAF546 +:109D0000906FC115EC681E07F65BF8FEA4FEFB45DC +:109D100021D79C300782CF10F9FA7D8187E3C8D71D +:109D2000E870EAF97AFDA78733517E5732F29BED4E +:109D3000CD2D9FA2DEBAC31862C530EFED623D8F14 +:109D400008B9F0E8063BF5F398D87F7C7C839BDE6E +:109D5000EFD830869EC10D1E7ABF6BC3547A7680D1 +:109D60003D87CF273754D273CF061FD57B6A430D6B +:109D70003DF76EF0F3790DC2172B253BC7971133D2 +:109D80005EBA3CA00E094F4CCD8BA92FE3F6A32E53 +:109D9000BD6C1EF9FAE34BE6BCA2E11B8B2BD9414B +:109DA000FB9953D814DCCFBC52FB8B1B6AE6BC3248 +:109DB0006AE87C24E9897D9931DA17237EE417F972 +:109DC000936F3B2F6E0DD8E2C32B4267B1E1546D08 +:109DD0003D9F83CEFA78B41934ED8FE9F8B8DA9F55 +:109DE0001AD36E287771FAACB1F0FDF7253AFEEE82 +:109DF00010DF3B5CDC2E7C378E9CB9CE6510FC1FDF +:109E000030D17EE020BEFBDE0DB1E0DBED7247F12C +:109E1000F112BF0EAFBA7EDE35B50FF3C4E0B32B3F +:109E2000F523D7A76FB7C9C5E5D6AEFFA3FCF9EEFA +:109E30009DC9E43F20DC9C9AF5BF7B67524DACB8CE +:109E4000CC5E17DF1705EB9C15A493A91F30A3ADBB +:109E50003886B9F93EEF483BC687641E407C7A35A8 +:109E6000521C8960A80E862BE0C36D2E84FE8D03E4 +:109E7000E3848C388EC710D16F9853C334E73CD439 +:109E8000C1F400ED0366CADF09E750DEE357A427FB +:109E9000A63E3EEA72FB7483DA7F4539B3FD6B96CA +:109EA0003392CFD9970F8F8AA5276B50CE5C07646A +:109EB000E82AFE6EA0E8CAFD7E55F8D5A861DAB79B +:109EC0001E32FCF6398614975A6F4D198FC6D5C5C8 +:109ED00004FE0CCC64FC3CD6FB0941B4F343629E07 +:109EE000E0F84FE07E75F3147CF664F90EB9A0FD3E +:109EF0000A33F713F35CDE975D502F51EC039B336D +:109F0000CD5BF0C9EC7C1DE3311F14BADA6270E757 +:109F1000E33A3E523C57A39F6237043DF84C61A19F +:109F2000713CEF2EE847FF2CE39A4437FAB789A338 +:109F300019EBA578B82701E366E6A4F05B23D19F6F +:109F40007DD148F1A1F198CF06E5F17F9F1B0C90E0 +:109F50003FE726F99021E0B615ED70683F8FF9DFF5 +:109F6000C5F99EB65B030698D7C3951313301F2A15 +:109F7000B4470D98F1BC42EFB9BFBB19D63DA1570C +:109F8000A538F30436E9F59128577A4DB4DF5B67BD +:109F9000640F21DFC483E7D96FC6CEEF2ACAE4720B +:109FA0004FE66DE9BF2789EF67E3E411FF87D00B28 +:109FB000323FC624F3639CDECBE6C79874F93126A2 +:109FC000A38FE13EB069203F6629A3FC18E8479BB8 +:109FD0001F737666EC79A8997C1EA62F92E2F49BFB +:109FE00042EFCF8EB8FC3A4D5F2444E55947DADBA7 +:109FF000E87DBCFC9C3C09A738F9495903F3CB66C2 +:10A00000810C6D3B4EBF9171F2E8BB4997E713F9A4 +:10A01000CEF37B36A5713A399865772C87AE97B326 +:10A02000B009E9F40E9BC384F1231FF374D1B91D69 +:10A03000A3A93F2CF96E04D6337E8076B601242D79 +:10A04000DAD977AC377D10D6C8A92A6F7499617DAB +:10A050008DDC5D9FC568BE8963C7505EDF05E64E37 +:10A06000B55F466E2EB5AA56A366BDC7E3D80D7E72 +:10A07000019FE3D9B1E13727D31095A734B87D4AC2 +:10A08000D479B47BED979797085F7F86B67F3D1EA6 +:10A090001CF4FD4A7076B672FEEE2F5378FEFE5F1A +:10A0A0001CDE69229F8D9F0B30E9F2D0D767B9394A +:10A0B0005D0DCC9BE7A1BF6CF7ADC8A476EED1DAFD +:10A0C0007300DD466FD244781E1772470F973D022A +:10A0D000CEFA75778B7CFA4495357769E0AF5FEF00 +:10A0E000E3028FB2FE2613DFBF823F9F15F0B28CD2 +:10A0F0007139DB9A3942E485A719511E2EE55DB00E +:10A1000065F657693F49C27910FC04DCF570F431FB +:10A11000F7ED98B77D25782E3F9A6846B97FBBB595 +:10A12000FF30FAA6E15EC33B23E179C236F2640751 +:10A13000C37DB731CF1F62180FF1F0FC09368BECED +:10A140001C2590AB5EBA66E876CE9614FF18E48BB9 +:10A150008F44BEB5D4435B72CE8CC6BCF9D4F4B286 +:10A160009A2C27C5DBBD19483FBFB670FA79147A1F +:10A170008272D381AB77A27E69C9F22FCA9A1CC9B9 +:10A18000DF63DEFED1987FF055E1037F26A49F2B8D +:10A19000C1675B26E37C98129B3E8EC4A10F3D5F96 +:10A1A000D0B9B292AF8F2F243CE57E859CDFA22CE4 +:10A1B0004E7FF229E1A6CF1B5A946510F5B8DC68F2 +:10A1C000C9F2119CFB867D7A3201E67E5C97E73509 +:10A1D00020BF86B87E09EFAF4BFE1E4F8C3DBFFE01 +:10A1E0004CBEAEFFA9F92D91F31B1F7B7EA6ACA13F +:10A1F000CDCFC7FADF4FFB1AF417E07909E2996D6A +:10A20000EA27B9783C3DF63C470E799E7ED3D7A12C +:10A2100067257DB3C0F25ADAA7CF4A8CB94FBF0881 +:10A22000FC26F47BF4FBF5725F1EE407ADB7DADAC7 +:10A230007F7B06E27D9658B78B85D2701FF38085B1 +:10A24000E2FEFAF55F23D60FF02A4639C5E6F6534B +:10A25000FCE2F8E8D872A1388BF3C540FD363E4EDB +:10A26000BC7305D70AFEBCD2B90256E2A7B85F9903 +:10A27000D51652010FF7087C9873D77AD02E2CCBC5 +:10A280007AE318AE13E07F6E009E9A3CBE331B8EBD +:10A29000D8479AE2CBED3AF5D9D2E618EB99E7F434 +:10A2A000CFC5750CD4DBF3BA7DA4065FE358D8C0E4 +:10A2B000CF45F71BA2FCE14CF695FC61AF95F34B43 +:10A2C0006ABA8FF401EA07D43B5BF65F5B8CC84443 +:10A2D000FB02F378FA9313498EB6E65C37C6AD817C +:10A2E000676396B45BD538F6E29F97F71FB19794F2 +:10A2F00028BB35D2BF91DE4BFC94D9FE5F4C7CCCA1 +:10A30000737AEF453A1C9DEE5D874F3DFC020F4C82 +:10A310004B23FF18E13723D2DF00FEE3E0F9C74EFD +:10A32000EF77B0BFDBC4F91945E6EF0DC4298CF611 +:10A3300093D608BC878A97EFE13FC03FDD91E5DD0A +:10A340008A78315B043F321B9D0B97F60AD3D935CF +:10A350006C2ACF275D96F5C61F30CEB32585B3ECAA +:10A3600096EF24505EDD1D8ADD8CEB06FBE3BD1FFE +:10A37000417D3F0BBDF76DDAC7927646927A296927 +:10A38000E8F3947EF295F2A80FA11D06F39969B047 +:10A39000D1BEE621209B6C901B33CDFC59361BA807 +:10A3A0000AFA9BA9E6F584615E9FB373E93740EB37 +:10A3B00044114F5C77747202D2E54CA3E98C566E5F +:10A3C000E9E31C5D59D1718ECFD9DCEFD3DEEF18F4 +:10A3D000EEEF3F3C7766A636CE3210E710EB581012 +:10A3E00058CEE5A94ECE497966B0F2FB439897B9AD +:10A3F000ED2E8A1771B883736D84F20DB28CCE097D +:10A4000094A7092429D81ED67D8378B215FE2C94F2 +:10A410003398BE83E381D79785CFD66B3D6E7CCED4 +:10A42000507C463E8F20CF3764CD7958DF600DAB2E +:10A43000FC5C1ECCC085EDE578BC9C2CCA9BAA2F89 +:10A44000DC7EA77B70FC82D992C9DE358B799DB604 +:10A45000DB0206786FB1854E535EAA78EAE31C17DB +:10A460000D8100E6657F4B0DD27C935828D48B710B +:10A47000092B80C040F1831348A7E0D534E23C1398 +:10A48000EC1742DF6698DFE855B09CA1D3474EDB5E +:10A490003ACA7776FA8C3A3DE457906F326BF4EF14 +:10A4A000A3F593951DA773404AC8977529E3CA7110 +:10A4B0001A7D7CC63493A3B87F0DB77BDF49E4EDEA +:10A4C000245D28D95CFF34A69B19E5B9B8AC56B415 +:10A4D000DBCF279FC2A396A837DA506F584D5E8214 +:10A4E00087D41F0DDD7733C44FE3BE2A86F4FA4FBD +:10A4F0000ADFF70C2C53283F41DED75053C4DE84CB +:10A50000966C59F6086AB7F0887F593D94ABDF60C6 +:10A51000E34250AF7886AF02EF65691DC73C1BA1CF +:10A52000DC9AE07FE697B89EA32AF5D324CEC33207 +:10A5300066AFDB0BFDEFBC7598672B2EA9BC7F0BBC +:10A54000E6FFF43FC8EC982F32884EBF84F501FE39 +:10A550007F82659877D32AFF13F741FDEC37988700 +:10A56000EA88EFE88B20DE14410FF87E06BC6F12FC +:10A570007453D8A3F07D7B8785F226D8B14CE2973F +:10A5800085563E4E534FD9BCC930AFC2DE4944C692 +:10A5900023A13EE635616601CFAB63E427EBEB8F89 +:10A5A000C4FA6E8A52F17C9A1C33DD7BC4849C9B76 +:10A5B000A2E3B7EB23F44FDF8B45B949E8A3283E6C +:10A5C000C17EC02FF796F26D7C6AE7E0FCE061F295 +:10A5D0008FF3ED752CF287FD9647C621F93B4B7C36 +:10A5E0003BBC640EE5734F31860E225F5F2F9EC524 +:10A5F000E2897C6D05382E36361F76C27AD2D63384 +:10A600004F0B8EB2D4DD8AFD95309F8A702EB53FF8 +:10A61000D88AF3BB76E9D10CA4AFEDD985447FD3BA +:10A62000AC9EC2042091D6A91E8F1D5ED52C550864 +:10A630002E0B6BAC41CC5B5B38704F8FBF6011F061 +:10A64000CD62BF22CECFFB0B966AE2B0329F6F91F4 +:10A6500005FCE718727A7B36B78764FB2671DE4407 +:10A660007E6FCFB6D1F76F66DFB82C9BF22A789E4B +:10A6700033F0BD3F7B72448EC0B89487B280794D71 +:10A68000B8AE05826F25DF2FF4DE4B76EB425FB468 +:10A69000FDF94F0AC777608942F6E0E29ACBDBA763 +:10A6A0004DD9729F37CF7E3229F25ED29594DBF37B +:10A6B000518FA3BCAD04BDADB18F977EEBCB346A97 +:10A6C00097F964C3A5E191F32D4DBAF32D8DE27C8A +:10A6D0004BD3BE16930BE95D9C6F69EA39B1459B7C +:10A6E000D727E134F87C4B3FE5332E32070FE2B930 +:10A6F0009F456B618D50FF65711EE2153C0F313136 +:10A700004247C9B7268478BE9C97F2F6F2EC491E00 +:10A71000CC3369334CA43CA1B694648F362F676B5D +:10A720004B7305D693F941F23CCBA238FBC08F673F +:10A73000733BF91185E76905965809DE4E951DD3DF +:10A740009ECF7716FA283F6E59B69BF0FE88882375 +:10A75000603EE9247806C11CE3F8E2EDF5F201FA67 +:10A76000DB84FD95177A282FA63C95E79739337C33 +:10A77000C5F71445FAADEEE1F978D5BE4F5FE5793E +:10A78000B55525084FBD3C97F4A597EB407F9D48F4 +:10A790008F170D5CEF44E4BB6FC99DD05FDF9B66F4 +:10A7A000CA9B63F77B1513B47BEE75BB07CFD16DE6 +:10A7B0002AF35555D077239DF373D5B09005BE97F6 +:10A7C000BC61DE85F97AB5ACDD8CFDD5EAF4D65AEC +:10A7D000DB2B66E4CFB51DA6083D32CC33F414A2C2 +:10A7E000A0ABDF3B28EE41F247CA253D1DB391D116 +:10A7F000F2A758CA5B900B5C5F2DE57A8E3DA9608D +:10A80000FCA72FF9942AFC67927793A590D2C9F9F7 +:10A81000C93DAF91BD321DE403FA670A96C7537D67 +:10A820002A83FC1C8379A3D7B344A2AF41768298D4 +:10A8300057C9C0BCB93D24E562D9546E6A4ABCC050 +:10A840003844CF729F6E32DEBF03CFEBC5B8DF3224 +:10A85000788B420AE289050D856847F8C9DED1DBAD +:10A860003FA5D6E6242BAC6F2A6B27B938E5F02B31 +:10A87000242701CF9FA09CF9359378F65851CE54E8 +:10A8800060C29F8ACF683CCDB66D37229C6667E96F +:10A89000F11130225CE7B807E189CE0778E3E0C91F +:10A8A0002BE5088B962305EC4B7E1EF9C157EF4331 +:10A8B000BFF74A76C821A7DF9C43F233DA1E899797 +:10A8C0004F979A63137EEAD0F2E9FA4CDC4FB88EC8 +:10A8D0008557EF5506D3C5F9C3EBD52C0DFD48BA06 +:10A8E000DC2FF2EB959744BE6E4932E9B9885EE4FD +:10A8F000F82F15A5EB90AE34F8BF615F4248057A9A +:10A900002B16EDAF437A9818D18B2183CD6D8671CC +:10A91000B7289E363506DE5DE96ED27F930C5E95D4 +:10A92000EC29E6C9403C03DE8B105E53AD9DAD467D +:10A9300098E749B3E747E8AF943137E1BD4CA75FEB +:10A94000CA6DD546E4CF72AB1EBF5EC27B857DD09B +:10A950007BC39F82F7E18877A93F86607F02DE2B69 +:10A960007262EC13C6C3FB2D7F22DEF5F8967CDF06 +:10A9700095602FB7615CB796E7114F7A73642B9699 +:10A980005D0D0574BEA52BCDF3327D6FE6DF4B7AEE +:10A99000BD2ADE9B58B80EBE43B9ABC0578EE5A6A4 +:10A9A000F50AC9CBC96FFB5BB13CF27EFEBD786393 +:10A9B000F3CB78FF585380B7DF7F7A0BDD2311DCB0 +:10A9C00022DA97B59763B9A98DB7FF38D91A40FF36 +:10A9D000BAF458B015DF5FFD109F87B4EB66083AF4 +:10A9E000EB529E7D99DAB5F37677BD6A4DE4C96E78 +:10A9F000DC4E9B2ED639E371BE4EC7873755BA81E0 +:10AA00000EEFEC0F98900E4E1AEA4B495EC6F1B766 +:10AA1000CA94F63C7CCE06B9C008DF409F23789EDE +:10AA2000E92E18626B0EB78B647E26E6895769F0B3 +:10AA3000B53587FB09B29E2B9DF17CE2C792C96EAA +:10AA400095F9A3A11F3205E300B846D2AF71F249D0 +:10AA500067173693BE9C3D5CE691868D2B60DCE2E9 +:10AA60004BFF7A632CFF7A9B18F794C87B97EF6BA8 +:10AA7000830506F43FBA9078E87EB5796FA25DD27F +:10AA800085FBC19AFB41BA0A78F9C78FDDFCB76D27 +:10AA9000E0ACDE6568360650E8E72B74DFC92DBDF3 +:10AAA0002C949A3278FEB38D2CC4F31DF8FC57B762 +:10AAB0009A776DD5D8E90BA5D898368AF448B5C0F1 +:10AAC0009394170B05BE80BFF7207F2FB236935D9E +:10AAD000B844C8F7352C48718A353AFEAEB37DF6D6 +:10AAE000BEC180F1B0683E6E80E970BDD0BFE35D4D +:10AAF000807FEDA3C976D4F30D9DD1F56A1F7DF358 +:10AB000018B7AFA2F9BC56F279309ACFF1A649E254 +:10AB1000F31F8EA5FD17799E2FC1DAFF7E8045D6E3 +:10AB20003BA0DF75FC9780E7FBC6A0DF62E079857C +:10AB3000A22CC7BDD0CEF57000F4B0F07348D45E3F +:10AB4000383E2788F4502CF857F271B1D0E783F4DF +:10AB500075A5DE8FD94EFC31499424DCA57E867E16 +:10AB6000483FCBF382A097DFF4927F0FFE27CE738E +:10AB70006C34BF6C55403E1744FC15C0DB3F23DEF0 +:10AB8000401E5B799CA29DA13C8B6BF7DBD6C5B4C4 +:10AB9000FBC18FA07D80C1F67E28CA8ED7E32B9E95 +:10ABA0005D3F80AF04B09792D08F67242FF7E17399 +:10ABB00008F91C20A7FF3D967E361FE2F5FA77269E +:10ABC00050BC40C6C725BFF5E572BBFA57595E9623 +:10ABD0008BFB57A2FFE377CFA67DEACF9897F6A924 +:10ABE00031CF2837469E04EE536FD2C4498FA7C594 +:10ABF0008E5B27E772BFE71BB97C5D794E6F4A2EEB +:10AC00003C4F99795CFC54A278A6F07D85EC81FAE2 +:10AC10005C4E4C10E55322FFFA547A743C5DD62BFF +:10AC200016F53EDA60B56ED2C815F70F2DCDA8AF78 +:10AC30009C85225F7D1DA7D7BE17D2766AEF699BE0 +:10AC4000965BF60D9C97B3D06BCEC638CB0B5C2FC2 +:10AC5000341AC366CC2BB9C1E1BF0AE1D4E866DE81 +:10AC600067B11F77D8BC00E0DC27F6E7FB4CDCDFE0 +:10AC7000E84BE04F39AF69B955DFC0767D7787493A +:10AC80003E0C94ABC2C4FFD3727D346EDF42F95DDB +:10AC900094FF969799F00FCB045F509C37465C77F2 +:10ACA000701C37FADE992673EC7D6596971C159F0C +:10ACB0005DD6C3E386B75BD9965CF87E474F26F92D +:10ACC0000FB52981D1768AE3FD7971D7BE61BDB414 +:10ACD000AEAD65FDF98F95D03E2EC57D1A7A5E2307 +:10ACE00039D720F9A43B9A4F96E40E6DFF431F1706 +:10ACF0001F02FFACC88DC13FCFA37E3245E07F8FDE +:10AD0000C877AA50EBCB312E746115A373AFF7BC93 +:10AD1000AE123DDDF38C42F74048FBAC41C037DE5C +:10AD20007AF0DC805B233FF0DC805BE39FE1B901DC +:10AD30006D19CF0D68EBE3B901ED773C37A0FD8EBF +:10AD4000E706B4E562B6B215E36C4D6DCC1E74F344 +:10AD50007304DAF6788E405BC67304DAF6788E40B8 +:10AD60005BBEC0381C2F3CAE529C1ECF1368DBDF8D +:10AD7000F5FAA42CA49BEE049E3FC602DEDE2280E0 +:10AD8000CB2A01173C67A0EDEF6CCA8D4718D0DDC8 +:10AD9000AADED573F13961DFDAA8FEEAD47AA243DC +:10ADA000D6CEE56E33FC47F2532D52711E9FEF5302 +:10ADB000584601DE1BAED39F3DDBB6A0E859138C8D +:10ADC0007E5FC734F1DA82C171F98EDC64C7499EB7 +:10ADD0006B9CA38DD344E8C0E609E1FADF563DB190 +:10ADE000E8A0985D954AF199232AC61ED8C7ACF908 +:10ADF00091698A267EAF8387252B9A1E12DCD1F4B7 +:10AE00009034269A1E923DD1F4903A359A1ED2BCC7 +:10AE1000632F0BDF8CCA68FAD0C3772AFC87F09DBA +:10AE2000883742625C09D68971DEBF147C7B75F07D +:10AE3000FD9C4D2BB7B9E973B5B534629F941C697D +:10AE4000A64D5A7DDC53C251DA09327E3999713FE1 +:10AE5000DD8AE72C0BD10EE0FE1BEA7F94AB27CDF9 +:10AE6000DC6F430A42397927F3933CBA53A7FFEFCB +:10AE7000B26D37A3FE1FB45EB0B8F0BE40FD7AD10C +:10AE80008E629A78925EFF2B3D4A28793C2EB74716 +:10AE9000CA65FF253276BCCA50E4C5719BF7739C26 +:10AEA0003F3A7ED6D2A8786F4C7B4ECE43C2458EB9 +:10AEB0006F61CD6A16D2F318BDFD15ED2F4BFF9AC9 +:10AEC0003AD5C4A3A57F2CFD133D9CD5E10564773D +:10AED0004DB24BBFB8F7367C2FFD61BD1F7AA57D03 +:10AEE000A9050125FCA382883D7983782E10F122E3 +:10AEF00058D687BF87C6D314F7301C6FFEFEAB9CB5 +:10AF0000482F5B9466A69BDFB117A11FD5D09FC1C8 +:10AF1000E32FFEA8FDAAD79430CD7B11F36EC66750 +:10AF2000A388A73576BF46FBA88DDD3C5EC0F645FD +:10AF3000E3456FEFAF659DE60265B0BD5FCF7AA9CF +:10AF40003FBD7D3F884EAEA0C777E4C97B3B78BE4E +:10AF5000001372A956C02B9E5F6044005F1BB9B7F7 +:10AF600013F8A12C6F72247FD6950E7E8C8A7918E7 +:10AF70006E73AC3C298697AA804DBAD2564D726248 +:10AF800065DBA0B88499F8A9FDF2EB9376C05FE584 +:10AF90003182FB883C37DF874A9C7BC48B9F4B7A8E +:10AFA000F3B5E73E9ACCFCBC216B8E3E97BF3ACFFF +:10AFB00020CF4DA94359FF60B8FE69F9F832FF0070 +:10AFC000E0B7460B3FB98F20D7F3C9E4DE27317EC7 +:10AFD000A826CFB2A25F9B9AEE6FCA73E2BD0CE1C6 +:10AFE000930ACA339B9BF243CEEF3BFD0EFAEF72FE +:10AFF0007D8C851FC17B6D6BF7A9E40FD6EE7B9925 +:10B00000ECA2F8FE5EFBC0FD09627FE37E1C473FB9 +:10B010002F99CF5CA116A5863576FABC3C1E0F1879 +:10B0200035DCB711DB95FC2E2F05E76B1AD149F7FC +:10B0300061F5DFC7ED6087CA6621FC40EF71BD6F27 +:10B0400033D2BE832329A0A6A01DB79CF1FBE73C09 +:10B05000CD1E2415755811C5695DF7A93EB4BFDF33 +:10B060005BB7320DCF29BB9257A515C2738685DF1A +:10B0700047E3520C3E7EDE74451ADEFFB1CCC2F7C8 +:10B08000E50BBE99142A047E7BC9CCEF197524F90F +:10B09000E9DE82FE3495E67366032C6D14EE7B7C4C +:10B0A0003609EF1BC8F9D23611E7932DEEB3A8CFBE +:10B0B000E3E7B7CF3E737112FAABEA251B9D6B979E +:10B0C000F4E7288CEDAFCC17F06874F27CF7F3C28C +:10B0D0007E3C2EF65B65FEFB3AB10F787CF4C0BD7A +:10B0E000604ECC0B694CF0A62EC678C451156FCCBF +:10B0F000609FD9BDA9696437F33CF675C27E382FCD +:10B10000F23DD7CD999989FE45BC3CE997F2B8DD6F +:10B11000FB75DD5329F34EE3C221CDC88C13E8BE85 +:10B1200025DFE5EABDF84735263C4F8AEFF1F2E529 +:10B13000DFCBE37E9BCC876FC47C7878B5EE85B29D +:10B140004C76993CE946BC875C935F837E1AAEAF30 +:10B1500011EF21A7FB49CFD1FD1CD80FDE1776A533 +:10B16000FB22E70B3837621E7986F6BD9BBF1FE8CE +:10B17000DF41DF9F12707BEA88A172578C79260E1F +:10B18000E3EB1EEB34FA705FF29A10BFEF335E3DD3 +:10B19000797E3BDEBCBA67866FC779637E66ACF1A9 +:10B1A000BE147094F3ED4E0FAFF6F1FDBCD155C94E +:10B1B0009AB2BD3F7FBE46BE4E11F8E9BE299C4FF4 +:10B1C000F700CCE1FE6B3C3C971A9B1584C31769D2 +:10B1D000FE5B50FEC97B8AF11E639EE711B82CBE50 +:10B1E000237056A3CE1D0C86B399BECBFEA4DC39CA +:10B1F000FDA84A72E7F45B821F99D7A694A2BEE22B +:10B200007C759AF1B8EEE976FEBB1F2BFC607B8261 +:10B21000FC58DE5137177FB763F5EE495B50FCE30E +:10B22000FBFB41FE2CCF626C3A3C576C8ADE1FFB65 +:10B230009C3D447A6ED5437A7DE633A39C5DBD3D4B +:10B24000BA7E2D7BE853B40F6A7576AF4BE85DBDCF +:10B25000FDEB1926F27E4A59E95739DFF428F34EFF +:10B260001946FA9FEFB74D16FBE9FAFA4FB8399C29 +:10B27000EFD9FDAF66FC29A078FD9E01793112FA65 +:10B280003DB7C14ECF6F0CF3CEC4FE970DF3570CF4 +:10B29000C338C4510EE70BF51756535CBA86DB0171 +:10B2A00016BC5C05FE69B9CD4A7EF40378BF18C0B0 +:10B2B000D962E1F685B4AB54F55E3505BE5FFB2F70 +:10B2C000ABD2707D8EA76757A2FFE17C3AC98BF89D +:10B2D000D85AE62D46F9BDB5CA46FBC43B0DFCFE67 +:10B2E00041AB85EFCF059FBAF610868347766E9BFC +:10B2F000897E86BDE76008E3126D06BEFFDA369DE3 +:10B3000089FBABF9784D3D555D38AFFC6A90F7D0BD +:10B31000DFD6026FB15DD33F13F652A3C045DFAF56 +:10B32000AFFA3EDE77F5A32364AEC23A4750FC6B1A +:10B330002CE37423F34BE8373134F1A273A07F98E8 +:10B34000E6DCF3D84E25644AA17BF5288E5DBF313B +:10B35000E4BA0DF5E7CFF87EAD9C9FE3A5EC991814 +:10B36000EF97FAF436CC6FC338B0B07B9730F9C79B +:10B37000F70B6A045D2F11F6EE6D491CCE2B9887F2 +:10B38000CE5DDD6A6529185FBEADBC7332DD7B5DC5 +:10B39000674A437B45C6BDE3E13D5E7CA6F1C964D7 +:10B3A0007E4F8ED23F1A3B398331909248BEBDBE4C +:10B3B0009F8787097E1E2DECB491CC8BFB2C8D07CB +:10B3C000AEA27C7C4B22DF5703F96645BC1E467D4E +:10B3D0000EEB5EF3624288EF1B07C57D382C40FB05 +:10B3E000310732695FC151E8A57DF7F3A6703EC908 +:10B3F00003905F0AE8CEBDC37A6FC1DF6169CC01FB +:10B400003B0ACAEF3EF1DE2D46A0C7C611E1D57852 +:10B410004FB8B2E3DF78796CF82496937628F3A8D6 +:10B420003C31BC5A85F2E81DA9F3A83D3A5040587A +:10B430009376B8E6E139E233227EC93C61BA1FA8AF +:10B4400071FF55066D7C70783EB737CF24F07A6770 +:10B450000AD81DF311DE63C2A3B5BF97A0E61B98FF +:10B46000F65E65B94ED98E65C5EEFF45A107D68853 +:10B470007B7D6624B1B604BE5F1140FBEA959EABAE +:10B48000082EC161E9025E61BAAF51F6A33FD72F22 +:10B49000C75D8B7A1BE5BA29FA1CD191615C5FC04C +:10B4A000389B689C226F31DEC7D3383FAF18F10656 +:10B4B000F8320A7C19B91FB893CF0FFA4D1B4F7A97 +:10B4C0006412E689BDF225D42F88CC5B4F1F6F0B29 +:10B4D000FA58D3CAF799FAD30A898E662471FB8F7A +:10B4E0009500FC408E8D16F01D9E9FC6E13780872B +:10B4F0004C85FA6F15F0CBE3F5BFEA7A4F7E4DEB42 +:10B50000D5E0C98B79C7AFECBB9AF024D7C3D8B6C6 +:10B51000A87ECEB4E8DA4DE579298DE985D4EE012F +:10B5200071BFBEBCAF18DB1540BB19E5FD93901F82 +:10B53000E47D6D2C309D9CF57A212D06EE5FEBE4C9 +:10B54000F9296CA497DF43347F6E89589F5DACCF97 +:10B55000AEBD8F6E800FDFEECFAFD6DC472DDF0F95 +:10B56000C07DA0BFA289A2BF287E8ED51FF2453C18 +:10B570007C64E573BAF88BE143CE5307CF0138EB17 +:10B58000E627E1897C4CED8AA2F949CE3369008F28 +:10B590003A7E2EF813C713F9FD0D7F25F221DDD178 +:10B5A000F4DCD05D60C0FD53D9AEADB3C587725E2B +:10B5B000C6BB2DDD5501D47F4D3D6594B7D9F0ABA9 +:10B5C000679E0F40FBB5BFF8410A26D39E36B6BB37 +:10B5D000D0CEADDFBD39C58BFB25C6400ACACFD35F +:10B5E00041B532D639C0C67C45FAD16447350A7DAB +:10B5F00073E6A9EFDE82F0F8B7DD263BEAD1A63D7F +:10B60000969085E2206BC88E82F2095E7EE053F44C +:10B610004B9BF645DB496B7FFA03979BE829906BC0 +:10B62000C0332E2C94CBE0D9D861F2841C3C9E0808 +:10B63000C3B026D6BF05E7A76F8FF3F802F0DED4BC +:10B64000A92EC7F3BCFAEF2049C80E6BEAFE2ED92B +:10B650005D4DDA3803E0A1368EDD75477E74BEB5E8 +:10B66000840B0B3AC9AE69FDD90FC79FB0E13D9A73 +:10B67000BF49518AB4FA7223C1E942E7CA1FEF7782 +:10B68000C7D7ABE7D12EB068DB71BCBAF729B427B6 +:10B69000C17AF8B3DE144A413FBF7EA7C9039A9727 +:10B6A000D53FF39327713F84BD6BA17B0FEA9E3991 +:10B6B000FCCE7550AEEB3239E6F2E9DB1457043FAD +:10B6C0004D6E6E9F487CAC7DEE30DD2F88EFD1AEA5 +:10B6D0009578A9EB3A6866E306C3AFBCF3A0F8BD62 +:10B6E000051D7E3A4FDC48F778FEECA219E9FAF422 +:10B6F000018565160C6E5FBBF3700AD21FC209FD8F +:10B700004B89A701BC0DC257E896FD25548FE21A5C +:10B71000F1F0E6CD677C9FE757CFFC1C7FFFAFF6CB +:10B720009F2C1E5C7FEDCFEF4DC1757C6C6CE6F4F9 +:10B73000FDC4669717C6AD35055C767AF2F7B53B62 +:10B74000EE23BABBEBE87D2EFE3B1ADE6CC3545AE7 +:10B750006736AEEFCEC717D2FA56333FD15DED1341 +:10B760003C3EF1B9F81D063D3E4F0AFEF87897853C +:10B770002E2DFA1813D1318FF02D55E4F9DECDB40A +:10B78000F75780C54DE5CF457CE0C5017B805999D1 +:10B79000262EDBD4F1402FE2E7CC306F26EEAB0152 +:10B7A0001C02025E0ADEABAB1EADC8E4F8616EA3FC +:10B7B0008C2B83FD5D8EEFB17EAFC99B303EAA9D81 +:10B7C000D8AFE7E3CBF804CC3B11F7FD3E76C53E9E +:10B7D000B7E5182EF99FF5322D7DC5E3F78E078961 +:10B7E000AE3E7B9BF34D63B0AA92BEF79A4278A41B +:10B7F000B83178B05A21796089BA6F69802E3A4C95 +:10B80000829FA3BFC33C8D8A16BE07785EEDEAED2A +:10B8100096A87B102274638EBC2F88F0A7F4A3EE49 +:10B8200012FCAF5FAF5E1E9CD0C903F6B87348F739 +:10B83000C9D49B824F3E86FC0BFC8A7E66FD332674 +:10B84000F2F3CFEE7DF99D5B81CECF764ABE8D9629 +:10B85000AB7ABEAD7D76328BC5B7676D1E16936F22 +:10B86000E17D4CBEB545F669DCECEB93AB77C59159 +:10B87000AB89C3C57ECEC03996A254CC753FF35474 +:10B88000DD708A0BE8E02AFD59BDBCECC877C7948F +:10B89000970CAF9ED2C051C24FD2E3DAA71B689C6F +:10B8A00001BA957429E976802E07E55746C151FF04 +:10B8B000BD57C8A38173431BC14F413BF6D72AFD37 +:10B8C000FE491FCC650BC0BD6F6F01ED836E167610 +:10B8D0007E9FBD3F05E37A9B855FD18FF1C4D4C8BD +:10B8E000FBFE049137E0EB4F49D3D845277AD414B7 +:10B8F000B4E3C2C1D8BF232BEFA70CC7F99D597978 +:10B900007EA942B5E5AFC7386D3BDF9F5CD5B23845 +:10B9100005E3197D3D85F43B4277BE0EFE2ECCB784 +:10B920004FC635035E637669E45ED3532C40FB95C6 +:10B930002B7BEA68BF501F07596DAB4EC5FD407D9C +:10B940001CE42ECC83C23CE4C7A3DFAFC5F808E2F9 +:10B9500049474F7EA4A7ECC1F4543D5CF065312B00 +:10B960008EDA7F1572AD422DFA3EDA277DE0B7639D +:10B970003C88A945BF457DFA39FAF1C8000127D1B5 +:10B98000699DFF94CCB322BA9674A7F7DFF5CF7305 +:10B99000BF7CAF14CF03D53FFFFBF13F82E7B9E790 +:10B9A000DF1DFD22967FF58FF9BF6783EB971FF8A8 +:10B9B00003F92B7D072C349FBE03AFE57F1BCBFB28 +:10B9C0002D1E9C6FDF460BFF1DE803C974DF74DF7B +:10B9D000301E676BFDF5C5F161D2539B7812F27092 +:10B9E0007E4FEC859EFF781FEF55BDD0637163DC01 +:10B9F000A1E94012F9E14DFB13E87EF8BE5F5F2C30 +:10BA0000D5C68BFEDCF5348AF3167DC9AC06F35B34 +:10BA1000FAD2B8BFD6F4E2B53F692940BBF420DDC5 +:10BA2000575CFED27F8E47F9D3F72CB72BC03FDF90 +:10BA3000819B88DF1DFEDCF74DD978DE88915F7D24 +:10BA400095FB33F2AB07C385C3A10FE080EB02B8CF +:10BA5000D03DDDF1E0B1EB7F2D3C3E257FA1BE67FF +:10BA60000AF151042E0AFFDD919EE4A055A1F5F3E1 +:10BA7000F7072E8E473BE96C670BE9FD2BADFBE02A +:10BA8000FFB9752BA1A1AC3BFCBF76DD9CFE570F27 +:10BA9000E7FA49CF0783E9FC57DFA4F2CF933D349F +:10BAA000DF21F23F6EBFA27CFFEF5EFF7F01F65207 +:10BAB0009D150080000000001F8B080000000000A2 +:10BAC000000BD53C0B7454D5B5FBCEBDF3493249C0 +:10BAD000261F2008C19B2F51F2194802E1A7938429 +:10BAE0005050C409488B157000955F4822D89A566B +:10BAF000DFCBC4440CD4D547D5565BD135A0509E7E +:10BB0000CF3E530C96564207540AADD5D142054D4F +:10BB1000E948AD480D6404157CA5E5EDBDCFBD99A0 +:10BB2000B9378988ABAEF55EB2C8F1DCF3DB67FFED +:10BB3000F73EE7586F035F8713A03711E6EF28C47D +:10BB400032053C900ED0F0E2C4A75AB20056777E80 +:10BB5000B408CA00EA764F0019EBD5BFFE477198CA +:10BB6000FAEF903CE27B62C021E1F73D9F89EF7BD9 +:10BB7000CE1503961FEE90827212D6EFB32F0FD020 +:10BB8000BC9930BF03CBD6AE73C5612C01DA00CAB5 +:10BB900001AE546D5C9ED9FDF763523A95761570EF +:10BBA0009D863D0940F337FC2A2E00387F6FD7B9B8 +:10BBB000F13E9CF722FD5C0BD0D38C538C8ED6CDFE +:10BBC00065CFCE3F8DBF07BBD4BDF04EF1E358F635 +:10BBD000BC7034FF45AAFFE2AD51EF60597FC97DCB +:10BBE000EFB52DC5F63BAE5419BEE8BEF7DAA08816 +:10BBF000F67B7011F5EFDD93E8B267117CFF180555 +:10BC000031FBBFD4BEAFF97FBA6F003FC01000ABAD +:10BC1000EC7564237C0F4230A462793FC08C0E67C0 +:10BC20007F785651E3101A0721180A2083F891D320 +:10BC300057CE82242A377C2417D3F83933B2100E1A +:10BC4000BF6A716F55A98785F1D03ED21DD880702B +:10BC500081E25DBE19EBD62BEBDC1B78863B01C67F +:10BC6000037CCBA1CD3774D60C09E76B6D41B8705E +:10BC70009ED62116572BCEA3A896A0BD98CB77A908 +:10BC80007C60E87507685DC56983A036F622FE739F +:10BC900002D60BB43AAE179F1B53C77F71B0CFA526 +:10BCA000E0FA716E0502B8253BC48CC7FE33551708 +:10BCB000EF331E027E97F3F2F1F4F825F064C68F9D +:10BCC0008EB77E780270D07885FE8BF69FBE2144B9 +:10BCD00072A880E20F8BFD481725C2A73BC381F3F2 +:10BCE0005993EF706F90F8BBAA8CD7C659E8CF1A5A +:10BCF000037E117F9EB8E2289E63E6E3FD9BF17C04 +:10BD0000B9F8D5E912077398CE71239DEE00C27F72 +:10BD1000BF2AF07E3FE25D92A2F8D5F166A6433DD0 +:10BD2000F14E7914FFD1728AEBFD314C48B888C8C6 +:10BD3000F557414123CE53234F09FB71FE331509BB +:10BD40006E3BC98B0441691C969543AB00F7D193B8 +:10BD50006953A89C1AC13DC5C07BED79072831FB0A +:10BD6000AB841443BD27339FC7573B861BC6F50CD6 +:10BD7000AF70D0F71A5796A1FFEB7149C55042E357 +:10BD8000A6CFA0F6AF655C651837FB78CFA6C5587F +:10BD9000DE2885CB88397A0E2EA8227CCD54C71A8E +:10BDA000FAED42B542F21CA991035B101FB5527027 +:10BDB0006831E2EDFA828946F8249846FBACB3205C +:10BDC0006B61BF1BDC9586F61B2B661AE6ADF5D4BE +:10BDD0001AEA754D9F82920630B9E90228A50063E0 +:10BDE000831D86F1A5077619FA27BD0A722296638C +:10BDF0000FA9AD5496768752897D6D690EBF2519BE +:10BE00005938ECADC6EDC0F80F1A5FA2B2C981F87F +:10BE1000C0EFE7E24489F4623EF71F8B0BB422BC0B +:10BE2000E72C011FE1E16E39504065FC883B8A2117 +:10BE30001BE064C6837232C10FBE632AF2C1C48F95 +:10BE400003AD54BFF64287EC233DBC5DF6DB4A8868 +:10BE5000EEB3127E4F7AB74302A27B9DD3E20990E4 +:10BE6000DD4AED285E1BC35F1F7E1B6EF516F6973D +:10BE7000D74D7995119ABF2DC3B3712FE9CDAA3F44 +:10BE80002D92B3FBF703971209EB78C9A671DEEC8C +:10BE900091384E4E9CE620BD1E5F2DF3BEE06BD662 +:10BEA000C0569C679DC51DA7093FDB57D774EB663D +:10BEB00092EBF62CA11FE27F07AA84F0C7A7F9E452 +:10BEC000221AF71F126C85E87A4B2B80F791926546 +:10BED000117CAFB8862C2CA2F1895C1F5F21F00881 +:10BEE000B32C813C9C72EFD413FE44C443FC8D966A +:10BEF0004CB4409054E1F95D2ED6C787DECC94490E +:10BF000096A0C042FA640DAA37D227C31ECC7A7419 +:10BF10001F8D3F60853C2C962EF09CCDC5FAF767AF +:10BF20005940C2F6CE8AAA84A218FC259D97402DBE +:10BF30008DD6DBB3548623490903C971D27985DBD9 +:10BF4000A129DF42FA465F276981FAD6DA9875405F +:10BF5000F1AC22B8375CDDAD92BE4A3A22F6091048 +:10BF6000CEF0E2D6FE86765125422AE18C8589FD07 +:10BF7000E9F0B7EDE5292AD231ADD29DE2A6F2670C +:10BF800088E4498C673FA9BFEFD39F2BA8F6686868 +:10BF90001AB66F271D28DA83807CBCC1A6B5930A28 +:10BFA000C17A9AA4B5FB1FF54E233ACAC6FE25D91D +:10BFB0007DFD3D8E8CE8FC53363F1A6A2BEC8FD703 +:10BFC000BD53ED6C87E3910FECD877CD5585C360F9 +:10BFD000003B11C56BC225F09A24F07A01B53DAE45 +:10BFE000739743ACF39EA48E22FE7AD882529F03AD +:10BFF000F092CB579D554EF0078BE8FB9224CFB0C3 +:10C00000A9C86F9D36CFA8EF901EE98A736FC171E2 +:10C01000B5777EF85813C9F1ECBF15A007039D8AC8 +:10C0200027611CAED3E0FA94E5BF462E4C26FFA64E +:10C030000F8FC4BFB8E6F72DD13AE983A4285E3D3F +:10C04000B9D8BE2106CF0E07E92B51FFF7AC67BC6C +:10C050006D44DFDB1C8CA7B59A0CB5A5C0460BF26E +:10C06000FF59D7B6AF133F9CDD6E05F2933AA99105 +:10C07000EC638183E508D2C319B5C8F7456F58BC96 +:10C08000E48775237F78883F1AF30DF39D9DF25660 +:10C090006A118E3B9BAEA4127E56866D8CB7850AC4 +:10C0A00004EDA81F3BD36FABAEC4F6CE232AB777FF +:10C0B00068F33C9BE7599EC576659AEB7DDC97E477 +:10C0C00099245F1C3338BDC862BEAFEB43C4730311 +:10C0D0006D3375703E68AB7404C8AF6CA8682924D2 +:10C0E0007BB026257F18E03E1AA6496C5F1B9A3E5E +:10C0F00066BCEBF32BE76550D3A275778ECA7650FA +:10C10000513CCC0FCA791BB7D7359D65BD8DE06416 +:10C1100091DCF4B408FDB6D10AB7D66259F74FF9ED +:10C12000D65AEC5F872CC5F601F6D9D6C4E83FE8AD +:10C13000F8A84FCF9720ED1E9EF5663CE9D55AC969 +:10C14000350F700F87B36DB5CA70ACC7B9E64958E3 +:10C150000F6CE9F5723DD335CF82F58EACDA5A65B6 +:10C1600022D687BB7E687103FC69CB4AD13FCB7571 +:10C1700098EA07B31E10ED89820F7E98755BADBFFC +:10C1800090F8CBC97839D39EC0F231189E9735BD4F +:10C1900068C04BBF7659BAD54B7C355FE8C153EBCD +:10C1A000476C66FF2737944F6B6E273D8B781B8A51 +:10C1B000B4A9C07FAFA0DC3B100FE939E0B160FF4C +:10C1C000F45FA0FDA1FEEF854611FE96FD222E280C +:10C1D000213D563FF1928DECCF1259CD27B9FAF59A +:10C1E00068DF7F935C9D4E0C717D59D31E86EB1FDB +:10C1F000B92EE19FB822855EE4CFE5B0D146EDCB04 +:10C2000041394E7602B528FB312B9D2FDBC80F5BE1 +:10C21000F9B4F57838C68EAE82F03192D3BA67ADF4 +:10C22000C7C331F616687C0C7F1DB70838140D1F84 +:10C230004BE4D0229B806B2FC1B53A15FD7999CC88 +:10C240004368A88FFDA0BA028E4332E281F86EDD0A +:10C25000156F17FB06B07B1DCD68E751E47634EF10 +:10C26000E2B21DE724BD334C09DBDC384FBDA69795 +:10C27000C7878EDB2066FC31CD7E25EF92B85DD777 +:10C2800017D176619FA0D033D68270AC9EF3EA14AA +:10C29000A28B4ECF6B13A0232E95E9E2D6E8E226BF +:10C2A000BAE8F8477C962A38EEE50B382E6B20BEAC +:10C2B000D0F12FE0ED8C17FA22B2338EFD2433FC3F +:10C2C000E7343ED0F791902DEA83C19F909D28E8F6 +:10C2D000FA2F863F215BC8B1791FBA1CF7C57D2DA7 +:10C2E00003FB293ADC97CF6721DB17E1335DCFD41D +:10C2F00083AF80E6D7F58A8E671D4E1D5F9D14FFC4 +:10C300000C00A7D2F44BC37E945015050D50909DA0 +:10C310002DF458C74C203A284DBBB9DFE5EE47D77E +:10C32000B783ED4BD7B3E6FDE9FA56DFA7AE77F555 +:10C33000FD4E4545C2FA10C3768AABAE3DEF33F8E9 +:10C34000BD95B0C2E017573BEE34D46B5CDF31F4DF +:10C35000FF5A468BA17DA6BADED07E7DC10F0CF5BB +:10C360001BDC3F36F9ED9B4D7EFB7F1ADAA7844339 +:10C37000EC67BFD63C031474ACAEF920C2FE76B0B5 +:10C38000D9C5F57DCD195CBEDCACB27CEF6F2EE07B +:10C39000F240B39BBFFFB6B982CB579B3D5C869AF8 +:10C3A000BD5C9AF5C2ECE7BFA1507C5211DA584D42 +:10C3B000AA7C5B8EEFEE6CE487D72D81D644C4D384 +:10C3C000846EE18FC372B33D3E77EC1EB2EB2E9BC1 +:10C3D0009BEC61DBDE89923A803F9784F6CE13C3F3 +:10C3E0002F49B3C2E021BF07CDF340FC756FB6857E +:10C3F000E9476A1F50EEE63BC09A8EF2367FBEE4F4 +:10C400006E15E6C00FA95C067DD83E5B013FD9FFE3 +:10C410005AA712B42731685E07C2394F8009766A7D +:10C4200027FB9D9EA690DF7A137D4478658F0CD7FD +:10C43000E0F77915BFFB8CE2E46F3A3BACC42737D9 +:10C440001FB8EFD43DD80E6DFE72928F3EBFC1FF74 +:10C45000B6E572FC867BB3855CF54AEE9087FC9D61 +:10C4600014C51DEBFFEBA5375BF8FFB35BFD721244 +:10C47000E233F206B01FA7CB23EEAF9DE0D7E5A2D3 +:10C48000D6A504472791BDFF4135F5AF3BA4325EE9 +:10C4900074B9D0E5408FFB7439A8919F6DA5FE67F4 +:10C4A0008E00C7CF137A7C1F3C4FFB34F99D15914A +:10C4B0008DD514875D2A4E9C74BEE325EAB7A7D9B3 +:10C4C000C77CB4BB793E97C1E6E51A7F3672FDE5BD +:10C4D000E626AEEF6FF67379A0B95DE3CF8DDCFE93 +:10C4E0006AF3635C7FAD39A0F1E976FEEECE11F61A +:10C4F000F7E350F530E2BFA7B245DE061C951C47B6 +:10C500008022CA2FCA2775192F0A7FCAC41F66BE88 +:10C51000D0F901506F4888AF6FA29D25FB700BF8D2 +:10C520008B1663397FD946EB64E9CBF3C54A671BA9 +:10C53000FB1F667DB80282ACEFFAEB77E1FF5F4A42 +:10C54000BFCB189F92BDD2F5DF6A08F37C76F94E17 +:10C5500037E54FBE3ABBE2D2EC0A2CA6FE7D7176DF +:10C560007CF722D972E9383B7BA418AFC7D9E83FE2 +:10C5700002D9E5DE80CC7EF5F2AC8D491C675744CC +:10C5800092C80F58D125333D30CE548623DD9669AD +:10C5900074EB81E01F892ECBA62CE33CDCF24DC668 +:10C5A000FDAC74DE941C5407F4D306DC673D3CF804 +:10C5B00011E5E3EA357CF17784A7A9FBE6992FC75B +:10C5C000F4FB243B319DF355136002E103E177074F +:10C5D00049CE0EC92C6783F1C5698C4F88CFCF3502 +:10C5E000CF9FF932F2FDE90BCD1C7FFD33FB811F9C +:10C5F000F8477E75F45A97E74DC8E1BC5BD846F220 +:10C60000A3D36F1DE948847B5D95234081766FB984 +:10C610004BA1F57B258F4C7987DE77C1DD82F8ABA6 +:10C62000DCFD9B23241F950E279F1BE0267A62E9E1 +:10C6300039F190AFD589FD26BCEA91C97D2F7F39AC +:10C64000DC4ADD747BA3DB9FC93D11D9C779815CCE +:10C650009623C0D8E262CE17972373BCD94AF1263D +:10C660002AA4B3CEE90CEFD920B8E97B348F25F2A8 +:10C670004B932F78E424846F9D161F4E7CCFCB7094 +:10C68000781C2AEB17BB164FDA332CF82D8A479704 +:10C69000CDB79DF29DF0AB38CEEB9AE19B9023F4A1 +:10C6A0007872AA7702E3D7A9E653DC5023F76C7BB4 +:10C6B0009CF8A133C14D791BB3BED5F5DB607E7B01 +:10C6C00083EBEC807EA45E3658C439C1B86AB59459 +:10C6D000E23FF22F292ED4E34473FF9ABCAAEB0861 +:10C6E000BE1A794AC84370B92C9FCBA70D4D1F7D48 +:10C6F0006E9CA6AFDFD055EE5A12930769CF91B466 +:10C70000FCAEE27ADF11A5DB17A5EFD4C87C83FD70 +:10C71000F9BFEEAFCD46374742192A9202C28F00C9 +:10C72000E14F2C8010978B20C2A50F3989CA25E0D4 +:10C73000E6F236F07219CEF535E790BF608D0C2524 +:10C74000393EF5C2DF0B892F4E5D33D995A546EDF5 +:10C75000AB6E6F2FD7AEC6D379D200FCF090C6B7C0 +:10C76000BADE1E943E26BDDD3B16F5834C79A1C88A +:10C77000A21729DFBBC7EEDA1AA31FC06FF4170791 +:10C78000D317358A88DBB75BDCAF531ED1FF5A1A4B +:10C790000C245F7A399BFC49E4C7E40561251BF949 +:10C7A0002D3FD5F334F1B3FF812929AC87498F5C44 +:10C7B000897478579CB7C00A299087FBDAD529EA93 +:10C7C00045B7A70424B6E741A6C742085B691FB76F +:10C7D00002B0FE5C0C2A974BC1C374C199138A51F5 +:10C7E0009FDCDEA98CDB807095A446B249CE8A26F8 +:10C7F0001E4D9570FD62F2639D9C6369277F4387A0 +:10C80000F3448EF0632FE67876115D4B52431B1E86 +:10C8100026FF6EA705C8BF3B31F13B77408C7D1CDE +:10C820009157D545FB784E12E77CFE2EBBC88F4151 +:10C8300064A837C6AF0EE756BF44F3FD568BE7A199 +:10C840007B3D9FFFD4BA044E61DA10C6018E1B45B2 +:10C85000FAA7BF9CF9795C09E97B91EFF34305AF37 +:10C86000CBF577724ED4B689FDF8C9AF1A91E73B84 +:10C87000447095D850A511FC4FD8035BD8FF691CB4 +:10C88000457988654FDA2D648F8FA23EA5F3CE7768 +:10C890009A1D5CFE09E3142AFF8C710A95EF629CD5 +:10C8A00042E55F304EA1F2F6F3635129231D723D3C +:10C8B0007F617D39C83E06D7177ECDBF86F9039DBF +:10C8C000D3756B7C5DDCF9DE7D09C407BB64771E24 +:10C8D0008250B453E17CC2E9DD130272562C5E7DB6 +:10C8E0001182A378D71F1E9A5C46E3149784FD4FEC +:10C8F000EF3A3B94E31F137C7DF8E8B2097C68F0C3 +:10C900003E9712DA40E39FDB994D10A23E00C187AB +:10C9100044CF01F261002DCC27CFE708FFF6467B1C +:10C92000A42CF65C12C8F453DE51B31735F285A47B +:10C9300070A1967F9D487C9DFB3AADE73F20431E4A +:10C94000F3A731BF50902BF0A097455D362FE545FA +:10C950009EEBFAE39CEB110FB327CD2C9763E42DEC +:10C96000237788E837F1B39F3C9CCEFD5DB4D4CDEE +:10C97000B0B9C685FD6E71EC7D8550B0D0F56E4DB9 +:10C980000AD66FCD90F653B958CD9A9EAA12B80127 +:10C99000DECFD282CAFDC462B3DCB536B2AF952415 +:10C9A0005431FAB3DA914027A07DF51A579AA1FEC7 +:10C9B000B58C1186FE33D51C43FBF505630CEDFAEF +:10C9C000BAB3DCA5867E24AFE4FFE23E98EEB05514 +:10C9D000E6F394A29D1FBFBD8AF77F7319EDBF17C1 +:10C9E000F1674307E1838AF53F7A98D4C6CE7D4943 +:10C9F0007CBE6AF233EBBA9EDAEF5107F7333F8120 +:10CA0000DD03FA67F583F8675FD4CF44FDF110E9E1 +:10CA10008F92176EE2F3F2E7267E76854AFE722E3B +:10CA2000FA9F884AB3FFD9ABF99F66FEE9E3534901 +:10CA3000157C7350667DABFBA166FE01B84FB3E376 +:10CA4000A2BC5C399FFDA6B03B7F25794F8BE56B7F +:10CA5000AD34E5154A6C680728DFF77B19B6D08737 +:10CA60000B08878EFF9C28DFC36D9B5F195EC6DFB6 +:10CA7000FD89B864BD966768CED5FC8EBABDAF0C93 +:10CA80004F8FB6C35DEF1AFAC3BDD27E43BD2DCB27 +:10CA9000587FB0727FECF8C1F4D0B24D77DA7C9455 +:10CAA0005F7E44E41BCDED3A3C35FBE23CA42F9580 +:10CAB000DD768E6BEA5D1ECE832883E44174BD7003 +:10CAC000B30C8D03E9B70DDABCB3F6C581FC25E6DE +:10CAD0003D8ABC42F0F87F21ECCCD1640F7863D65C +:10CAE000F961AEC8039F4AD9F86F9F62BF53BF0474 +:10CAF00037A1FE548AD0B7C59D272C16B213F182F8 +:10CB00005F8A5D614B2ADD53599EE0A773E086156D +:10CB1000897E3AFF29C98EFCD181A47F2277EE431A +:10CB20000EE4BBB72D1683DDE9255D87F56D4FCF8C +:10CB30009943E76DD7EF8B0B5ABEC47EB6511E9357 +:10CB4000EC549590F745C437FAF916CA47C3FD600F +:10CB500038EFA2FD53FD58EED7DF7C84CE6B0E0A72 +:10CB6000F9C766A739AEBC2526AE844D427E1DF8B6 +:10CB70004BFECBCA9737DA28DEF9AAE47E6FAE33D4 +:10CB80001A5F8EEE2FCFBABC371C16F27E66F727DF +:10CB90006F925E3F83F62E56DE757CE972DEF0986A +:10CBA000CCF2A87F3FBD5B9E111800BFCF6A7C000E +:10CBB000AE7CC3F9D79AA9E7E6905D5BD3A5F0B93F +:10CBC000DE60F6BAA1DD78DEF5DC1EFB72711E2C8C +:10CBD000F6D1ABDBD3AE4F522B0B45D9C2E7AE1B20 +:10CBE00035BD23FC18B4A3D674B2A3B512E7D10E99 +:10CBF000770DE37B15872508AAE3788A9B1C48B745 +:10CC0000B9623AFAEE247F0C320A145A678E46CF84 +:10CC1000B95A7E675ED7BC3CA2D71F3B971CF66013 +:10CC2000D327B939BCCF6F809FFDC1C329DE4CBA71 +:10CC30005F30BB55F0F7E194480FE5830E4F4D9000 +:10CC4000E85C09E76F8BF5F70E5BBD998DBC2FFD96 +:10CC50009CF16AF962C265C4B39A3E447AFA25111E +:10CC60009731FF2BC31F64BE5A0181FD1E5CB7DEE6 +:10CC70001D64BF741588F8DCEC97D74FF9D0467661 +:10CC8000C11C4756EEDA7B84CE2FFAE5134CFC7AB2 +:10CC9000A9FC81397E1DCCAFCF4FF566E4C5E4EF2A +:10CCA000CCFE799F1FAAFB515B13F87CE7A5A98FE7 +:10CCB0009E5E85F5BBB626B8285E3EF9A4DD4F7AA8 +:10CCC000F9E4167B40C2F693A9916E8A134EEE28C2 +:10CCD00072E30CB0CCA2FED7B364D79FB1325FE051 +:10CCE000CA86FB096BA6DECDF7F6D66C4D94E8FE3E +:10CCF0000C6488763D76937F9AC87EC18AE787F375 +:10CD000079A56E5F483EE87CF98327E23CE4E49F26 +:10CD10003C303799F2763D969FF3B93CC8F71EA395 +:10CD200073F755DB12C7F1FD8B4260BA2DDF721528 +:10CD30009F536E547C9368FFD53FBD6118DD075B40 +:10CD4000F1872140FBE9DDFD3C9FE345FDF481FDDA +:10CD5000BB33BB7392A1308A273D9FD7FE748B975C +:10CD6000E85E2EA9E2BC051A3D23882F76D502CDB8 +:10CD70003B4E16F73D23EB13D82F35F35D6D9EF038 +:10CD800003EBF4BC411A3832487E7CC078E85D3F42 +:10CD9000660B9D6BADC84BD5EC74247F4ECC7DC229 +:10CDA0001AB9BB9EE2BD339BEC9CCFE8891BF83CD3 +:10CDB0006B615E0AC3B7CC613CFFAE6FFACC582FF3 +:10CDC000040FE99D71AD6AE99D58AED5F0DF92E997 +:10CDD000F5E5E17A2B3B7EF0C2AB8C974DDF7E9B75 +:10CDE000D63DE01479945705FECCFEFF3287C85734 +:10CDF000006C6678F5EF279E788BCF494FEC1C933B +:10CE00002FCE7F43EF3F9EC5E7BEC7EEC172C781FD +:10CE100037992E6678FB9DDF4912EFB78EF6914663 +:10CE2000E7B4DE6FE7F1FD1D11B72DD950C4F8D37B +:10CE3000CFD17A4F0E1C9FE870EAF3EBF0E9F3EBE9 +:10CE4000FD5A357A5DA7C507A76CA1D37C1EFEC22B +:10CE50001889F2747DDF5343C52931FCF255E5C5CD +:10CE6000BFA9E5358E585ABE65A3FB6D1D0F5B7DCE +:10CE7000B17AEF32F3E17D7EA00754D750614AD8F2 +:10CE80006EE1E694A1746EA7D54918B03E45034FF4 +:10CE90002278E8BE9F56C24A5F06E7BB693E99AE5C +:10CEA0000F06B8DE5AE956A9BC56F22AE2BE5680F1 +:10CEB000F9723A348EA47D581C613EDFD2EFABCCC0 +:10CEC0004B59774316AED73604D6911FD3661572E9 +:10CED000E15F9CC0F19B8E27DDCE80ABD0605FDA36 +:10CEE0005CA02A38CF7C05DAADA9A2DF9588E7C31C +:10CEF0000796BC427EC25B4AE3105AF7A8F3912220 +:10CF0000C942FE5D209162C4B7DF7CA6FCF7D8F76A +:10CF10001DF04C7522FFDCF41B07EB7D733EE276BF +:10CF2000F0717D1984AD1FE3B83F4FFC9FADFB202E +:10CF3000BAAF3F4FFA7427C507B7A4DC574EE3F5E5 +:10CF4000FB93E67B7A275D4EBECF67BEAF7723F8B3 +:10CF500042C4CFE72CBE7A91FF689C40F6B737C534 +:10CF60000612F6EF1DA2E1E314303E7AADDAF88F37 +:10CF700054AE97558FE3BC229C53591F4F36D99B13 +:10CF8000B2311611875D14FDA7461483BD292BD13C +:10CF9000F2367F57D92FBDF6BCF2B9F6A82E5FE462 +:10CFA00059CAD22C8D03F98756ADBD1582B2D88FE0 +:10CFB000F01326F7F1954726FAD56BF57AB267C8D4 +:10CFC0004FBD490E3F5D509CBC5BF0D76425B897C0 +:10CFD0004AD4AED0447EC52EB4773A1C74D697316D +:10CFE00086F96092CE9F38D702ECB74E6AE4B8C596 +:10CFF00041FE0C961BA410C3710D44B8F46876BCB6 +:10D000000ADC5C4E032F97C89F5CCE404B42E5750F +:10D01000D0C1E52C0809BB7F75B095ED19DCEBE2BA +:10D02000F86FE6320BF91B65DF18385E187D493C56 +:10D03000A0C08DBF7C3C4C0794BB9C01F031B280FA +:10D04000F587191F66F99C0A6199E59314430EE56B +:10D05000095496D36AF070BDE60BE2A122EC533876 +:10D060004F63C647F5C07CE1D6F0F1E77C10E71FBF +:10D070001A9D96E6AB5CD7E985729541FC6FA6A335 +:10D08000FEBD2CA1EA2C5D29BF7E5BE65CBA1F5574 +:10D09000565AB59654F282FCA2B9743FAA6C72D566 +:10D0A000F37474B9685BB1A89754955ADD68DF5A78 +:10D0B0004AE64EC3FE3EED3E31CC17FEF55D9ADFEB +:10D0C000E26BF996DB8572E2CB74BA697F0E74EE7F +:10D0D000E95E8A9C23CEF946CD08EEB362BFA38AEF +:10D0E0006F7A3E9DF73982492AE2FDAE961ABE7FDD +:10D0F000F6804DF4B7DB457E55DF177EF7C7617DBF +:10D10000C78E316BA5ECC1D7C779E7E60F2138F29E +:10D11000FC24AFBE9D925B50B26AD87C94CF9E90A7 +:10D1200015281FAAAF939EE99B4F7080239FF3643D +:10D1300023347FA667C798314497A5F9DA7DAAF40E +:10D14000AC52C25B43A67729CDDF9B28F86B29D16F +:10D1500061C8E0E5F7F23D8B697EF3F7DEBF2200A0 +:10D1600038FEAE7CDF329AAF21E102DBF7D363FFFA +:10D17000B02E9C15E5530989B400F7DDEA81808D56 +:10D18000ED8076CF5C3B77EABD1DE7413C94797D2D +:10D19000ADA4D2262C888C27FD89F3AEA1751B6C1B +:10D1A000E1516371DC23738FD9049F8D147CA6E950 +:10D1B000A1AE3D07EF1921AA5E8891AB863D9F7D08 +:10D1C000FA0EE2AFE18CD34DDDA3F2F4E3B51C4FD0 +:10D1D00082D3A03774399BB4CBCE7EF5E4DD57DD26 +:10D1E0004EFDA6FEA13B87F6756D7798CFB37ABB4F +:10D1F000DE1A21E0D0E38D73D297B1BB74DECA7121 +:10D20000DC4E71DEBA466A7C2991EA3F93DC7E846B +:10D21000FF846637F4B878B9B6AFD507B7AEA3BC0C +:10D22000C8F24D4B67F17D9C80881B54FC25F9FFAB +:10D23000045EE573EE55DBCDF144C446F45FDD6179 +:10D24000BAD743F130DD5F88D5EF03C4C34FE56B38 +:10D25000F9AE4CC8E47DC80B927D03E83B73BCFB80 +:10D2600018789EC9677FD62BD3FAE5CAC0F9842700 +:10D27000A2EF3B581E96696B139E9C1CEFDAC4BD4F +:10D28000DF27D6BA5D54D7E47333F24A05F9D16D7E +:10D290003F66FED7C7E9F2BAA25DDCAF864D69CC26 +:10D2A0007325DBEC1EA26BC9B6611C5F601CC47EDB +:10D2B000DFE66DF676AAB7DE1FEF974B289F1CB905 +:10D2C00082F22AAD71E27D129947BAEF59922DF29E +:10D2D0001CC774BDAED975FDDE6C5FFC9398CFF7AB +:10D2E00093FBDAC38A21DE68D5FCE732828FFCC06B +:10D2F00046AB889FE204FC7BDFF87A02F9B13B156C +:10D300006F02E5A5CF1CCA4E8601F0A697E5685EC0 +:10D31000E073CE0BCBDF9A95F379F42A7B4CBB6795 +:10D32000AEF1E7AF9A3DF0176B941EFABE6AE46760 +:10D33000AB6D94E7B80D5C94F75873F0A9567A2753 +:10D34000B3663D7046E10CFDA178E1030B9F674F8A +:10D350003A589A41FCD8A9E93B3ADF5563F86A3C50 +:10D360002585B07FF94808D0BBA138351ED498B8C0 +:10D3700038A120D5504F745F61189F5C916D68078C +:10D38000BF2754383EEABFA678AE36F47F20693A0C +:10D39000BFA3991ABA83F34A6933C619DAEDC8D71D +:10D3A000745F013E16FE4F05FEB25D854699E09C16 +:10D3B0001C06F809F2DDA41EA37F5411DEC87160BB +:10D3C000DC21C510D7DB2F91674A1AADC9D54818A3 +:10D3D00029F48319DFC67B0D6B0ECAECC7ADC944B7 +:10D3E000C7336B707CEBF2A7E37D88D788F761F3D6 +:10D3F0008D781EEE33E279C472239E331B8D78BE86 +:10D40000B2C988D72CBF118F39ED930CFDF3365676 +:10D4100019EAA31FBBCED0FFAAC01C437DCCF66F78 +:10D420001AFA17752C31B497EC5AF9B9741F1B5CB2 +:10D43000636837D3BDF4C0774D7CA8309ECBB577F9 +:10D44000553AFDFDF84BF49F0CDEE4A044E9407F23 +:10D450002BC9E3BF8AFEB3476BF75874FA7F41BD0F +:10D460005AA8F94FE6F759B31384BE79EDC0994332 +:10D470001EACBFAE965A33C86FD2FC03AF7E1E619E +:10D480008AFBF438E5C60AC974DE1E67386FBFD45C +:10D49000FDB4F250D0501F7B48BC6B1A77C4FD120C +:10D4A00095E5EF79E4D8774C133F66B3DC2FEED4E3 +:10D4B000EFB9E97113643CC971E8021D7E1282F173 +:10D4C000FDF38B7A7C6A8E5BF578B5FF3B29E1979B +:10D4D000DC2D0F16C78AF8558F5BBF0E1E7E0F56C8 +:10D4E0003ED2B76E34DD9FB244D2A85D8F6709B1DA +:10D4F000746EDC4B8865E7E2E05C4F21BF23E5BC3E +:10D50000F7CA9657E6D27D7D04DF151E2FD23FF471 +:10D51000F3E468DFC6D1A8778F4BAE75A538F6B5B2 +:10D52000491F8EA2F91E1E2DF20C76193184F66762 +:10D53000D8020FD0F7FC54CF23A387F4BF676D2E1A +:10D54000CDF77F3A9B835C2A2E37DFBF31E707C3D5 +:10D550001695FD4EFF7725BE6FF321013731EAAFF7 +:10D560009C69B7B2BF025A3CBE50C3BF9EB758A019 +:10D57000EDE7384EB11CEDEFC25DBF61BAACCAE851 +:10D58000D1F21D8DEC5F2F1DE91CC7F7C93CA56EBC +:10D5900091E7D2F318232EEB9DC8A5F6BF2AE3A48A +:10D5A000218F04CFA67DA1F3EDE8BEC5FCC7D78BC4 +:10D5B0007CE4F1F5999CFF8ECE7F9AF3490B1BDF3B +:10D5C00030C8C5AD4D470D72B0D8FFAEA13D9C1E11 +:10D5D000B152FE30FCC2F0E9B720FE4EEDB4F33B91 +:10D5E00066E4833746C7E4CFC2EBC74CE3F79097B6 +:10D5F000DCE7870C47777388E9ABEFF358F311AE9C +:10D60000879BC35C9AF7A9E729F4D2B60F0AE89E74 +:10D610007D448A77535ED89CBFB8DBA2BECFF72289 +:10D620000BB2B57382C6122FD34FE42BBAB577A1D4 +:10D63000DDDABBD06EED9D67B7F6AEB35B7BBFD9CD +:10D640006B75B6535EA35B12F77716489E2717E3F8 +:10D650007AC9237D1F915C35AC8C142BB84E43499D +:10D66000789184741E39C4F731E145C2706138BFC6 +:10D670000BF2F33DAF0F2CFE627A47E32EC8B88958 +:10D68000E2BC0FE2FDA7C91329D89E26EA362187FE +:10D690001505FF60B97B0F27A3FDF97F2989BC928F +:10D6A000336CA3775053D37D503044DCDFE2F72F47 +:10D6B000F89DF852CF73F65A851FD8ABF983F6025E +:10D6C000710EE83095D944F3725A0F343FFFC17C94 +:10D6D0007E37B2C90EE4BFE2FAFC4E46BF67627EF7 +:10D6E0004733EED7767EEFA0E743471464F17CF42E +:10D6F000BE86E432FD7B09ACB7201C1A45EF71FAF7 +:10D70000E03D24DE439EA23C724CFE794481F6CE7D +:10D71000F13630BCE7597DF0F8318AB37E3DDA77D7 +:10D720006501CEBFC4A28E27BAAE4EDACBF9AEB138 +:10D73000052AAF8BF08AFDCAD046745AED08737E75 +:10D74000EC52F9F0C1F67FEAF6D08F0A39FFAB163A +:10D75000F37B3A6D5D84636C414CDE5A87233ACF8C +:10D76000E7F3BF9ED7D5EB279E78205FCBCBDFEAD0 +:10D770001DC09ECED0F0D26D1D388FBEB440C423E4 +:10D78000FDE8331A4D11DD538C471B81E53CC21374 +:10D79000E5816FC6FD707EC23396E8BB7A8E93DF5B +:10D7A0008DEBF3E33CBE9F7FCE3A2D99DE1B89FFC4 +:10D7B00056368ABCBBDEDE2B09BAFAD78B3CE8EAC8 +:10D7C0003D478FD1FFBF60C54F8B4A39BED7C69B3F +:10D7D000F18CF8E5F74D4B64716E85F85D40F39B75 +:10D7E000F3ED5F16AFBD99E27CB577F367A3E8DD93 +:10D7F000E86ABA7F46EFBCB4FC15741AF352882F5E +:10D800003FE52BFA9F47019F6BD9353B62D7C78F06 +:10D81000540CE3BB9DDEB5C41F2F687A03FB072CB5 +:10D82000B87EA71E279BF2289D2191EFECCCB0B1CA +:10D830009F4CFE0ED927DDDFB9EB0D91EFBC2B4BD2 +:10D84000F8D1041FD1573AB29FFD843EFB2FB95542 +:10D85000C29FDDEABB9FD607DF5AB65FF295485FED +:10D860003ABFF8ED755A3E40D8C372CDFE95D33C11 +:10D87000E4E01426B35D2CD3D645FF91F36E13C1BB +:10D88000D72A80D1F266EBF7731EE17F01BC43AE6D +:10D89000E0704400000000000000000000000000F4 +:10D8A0001F8B080000000000000BFB51CFC0F003ED +:10D8B0000917B0A1F2AFA1F1933951F93F5951F9CC +:10D8C00017D0F884B02E1303C30A46D2F420E39D88 +:10D8D00040FD0780F838109F6322DF1C103E28CCE3 +:10D8E000C0F0458C816116906E01D26781F82B10D3 +:10D8F000DF06F245441818948178BE28034314903B +:10D900005E0AC40522107D8780748D287976AAF37B +:10D9100050E6E6514C195E298DCA2F55616058A614 +:10D92000CAC0F05A0DC25F8824CFA0CEC050A60254 +:10D9300061EBC931307400D5CC94C66EAE3E50BE9A +:10D9400013282FA00EE10300D191FB3B68030000D8 +:10D9500000000000000000001F8B08000000000015 +:10D96000000BCD7D0B7855D595F03A8FFB7EE424E6 +:10D97000B9819B90C049081834E0490C0F11F12679 +:10D98000441A6CC41B8C1A6768BD606B231588C869 +:10D99000687C4C7381248497066D2D83FEF462AD00 +:10D9A0004329ADD16287A98FB9202D689D1A2D56C4 +:10D9B000ED4FFF46C6B1D42A7F44F1552CB3D7DAD8 +:10D9C000FB24E79CDC04D0CE7C838FC33E673FD62C +:10D9D0005E7BBDF7DAFBBAA104E0128053F8873D05 +:10D9E0006F9000206FF0095EA3092200CD9A5B5F63 +:10D9F0005F0CF04DC538A857B1F7A365E3073ABEF1 +:10DA00009F580B610005EBE70318F83FD66E4D7089 +:10DA1000F5A84490BD531666E1D3ECDF7C36AB002D +:10DA20005A257EDF3831D377F30929577F9F17E8CE +:10DA3000CF29066AEBE1D727EF37CBECBF020845C9 +:10DA4000DE0AB0BF4C87E9A71480E3C10559691805 +:10DA5000BEBFB7DBBACF5327007CD4F6DAE4FD13A0 +:10DA6000867EFFA6022D3DE543DF4F0736E854C40E +:10DA700047D21D9F3C38EF81790619922E64ED0143 +:10DA8000D29E1CF6DCB1F93CB56C104EE73C00921E +:10DA90001CBF9FB39D2752932E60A50A29318BE0AE +:10DAA00052D93FD300A82A5B97253B1A80E072C069 +:10DAB000DB11F9DBC03BEC7A897AC783AB3B91B4CD +:10DAC000D6B838BDB4E7C9C66A184A2FE67A98783E +:10DAD0003CD3F5B81D7C348E4947CDF2C211D7FD39 +:10DAE0007474743DD2D179FFFD7494FCDF4B471DF3 +:10DAF000D4CFFF323A02E8E6F8823E15C71F7CCF4A +:10DB00009F91853D12D2192BF622DC457C28286A8C +:10DB1000EDBC599EC2C41418CF9DC3E45651DFA278 +:10DB20007A847BF4E1797FC26767634DDDA56C7E03 +:10DB3000F94D3D2F7D893D23F1949460EB751FC80D +:10DB40002854587F3725ABD9FCDAB1B399008F241C +:10DB500017C592385F88018C02F8073127005957A2 +:10DB60005939447FCD340F37A4393EA4539EA1EDDB +:10DB7000879B7F08DB99758AF1FF2B00E777BA76E0 +:10DB8000B0928F9764FF20BEC70C8E4FFDE4375BC9 +:10DB9000CA80F8B17FEFC5BF107E6FFE1F19AF00BE +:10DBA0002A7D281F42F5B296C2FAD093ADB272E434 +:10DBB0002615D24C461454754B2EFDF4EBD2095069 +:10DBC000D7C3D7476A080DC2F79F2011FD8CBDE36C +:10DBD000CDED6B19C99D581834883E3480DC9CA16A +:10DBE000F3F94E1B12B2A5DC582325683CE3B95269 +:10DBF000D63ED9C8F5DE7DF50BB2ADF2CA23490297 +:10DC00006F4EFA005D9D866CC5E943AD9763BE29F2 +:10DC10005F9C3ED4CF491F792B2DEDE0ECD72B62D2 +:10DC2000DA0567481F5F743C735D87F2D52AB1AE91 +:10DC3000A53E607C7B6FDD828C76C6F0EB5A49FC9A +:10DC40001EA987582A43BBFC81F54C0E7DB2F551C5 +:10DC50000696F716DB7A29A3A7356D1F011F4AC464 +:10DC60003E5FB35F5FABA2BF99CB8AAA26637F6E8C +:10DC7000EC8FD1D9BAE8BD4960FC7002699BE143E1 +:10DC8000E9AE4863194AC1F881804066655F349601 +:10DC90005A4F7490A27531E1F3E8B20DFF6AC46F78 +:10DCA0002B435352B2C2EF6B75131C6E1C8FD1BB4A +:10DCB000A2B10E192AD420A47D61ACC1E14732384B +:10DCC000351ECB77DAE8A04BAF844CEB60D22BA2A9 +:10DCD00095D3EB9D67265F9CE335DAE13DE3764122 +:10DCE000557FCBA287866FA7C25BE6FA30247E0DF4 +:10DCF0003B983AB84E6B5DB0473A9FE9EBC2AB2117 +:10DD0000C1DEAEC54F17129D923DB3B6B05243BAB5 +:10DD1000821D928A709A7A14A23954AF42D2A91FF6 +:10DD2000D9DB02584F09C6E8697E1F1E2E417FC904 +:10DD3000D8DE52D6EFE5627D2F177A0DAA5C6FF61A +:10DD40009970939E5507CB6C1EEFDECEFEC7E8247C +:10DD50005921A57E200DFD5E8F7A91C9A57A7C6F31 +:10DD6000912B5B06F8204AEB552FBE3DFBC4AB134D +:10DD70002F60F4D16B2880626BF5139E582DEBFF5A +:10DD8000A58BA5944712F03238E70B385F88E5166B +:10DD9000219DF6D67A888EE77FE9A30892F1B13DFE +:10DDA000BF5133D1CBFC59AE4138D87FCBADF363F3 +:10DDB000FFFDF3C0BA14D238265C4B2B1582A37733 +:10DDC0009694C271F6FFFE8F775FC4E07CA14A3261 +:10DDD0003C3AC11B02365E6FECFDC8887E8739BEB7 +:10DDE0000E1AE2D339BEB91EE1314078853F30BC0E +:10DDF000B2F19235FD7D6B10CF4724630D1B2F6B65 +:10DE000076EB381CA7589609DE75B3BCB2C2E8079A +:10DE10005E1B25233E8382CFB3DCDDDEF10CCECE4C +:10DE200009323CC45EAD2B1D599EB53BE499AAC591 +:10DE300063126BAF27B54A6504BE48C5E4BA4CF21D +:10DE4000EE7989EBC98EE402AD14A7B7DF6E07A2A5 +:10DE50005E8A5BF42AB3179F97D8FC5D114EC7D931 +:10DE6000B5716E27F68E22F91510EB9135654116C6 +:10DE700064B083879D071B2893DD9C2D73F8E030E9 +:10DE8000EF5F35FBCF19B9FFB5A2FF8F9B25E845A2 +:10DE9000F8D4B817D71F621544CF7E419FB03287A0 +:10DEA000CAA6DCF594C5BB8AD93A7AA232E83ACE42 +:10DEB0002F49EBBC81AD712103C55FCBBEB3AA1B5B +:10DEC0003E53C82EC9964F24930C8E0D7B6F049D34 +:10DED000D9A9FE680AA83CF9062FE26703530A7C19 +:10DEE000FC1EC0F1038C6C51BE06987CD551BEEA75 +:10DEF0003D699995D53A3062EC534833243F2399D4 +:10DF00007DD192552A7BDFBE10887E01AD080B7E45 +:10DF1000DBA32FC71406576713905DD319A9A1F986 +:10DF2000B597D7788BD1DEA957E93D9C64F830EDE1 +:10DF300010260FFD6510C3F136E4432A88BC549BBC +:10DF400047F4E8D6F8FCF52DA590BE807DCF9EB6AF +:10DF500017C74FFE231813F89024D754932ED44498 +:10DF60005242FFAE5533D667A0BB2D90C892A7DAB8 +:10DF7000E894F4AE136F596EB80CF1DB59C1E8BFE9 +:10DF800078683F85C83F8CDE52C6822B4A328C535C +:10DF90002CEB441F6659FFD84DF00F577FB01EB3CE +:10DFA0003373B1EB98847881DA08CD2F0706FEC46D +:10DFB000B09C2BE63B0A5AA85E7446F75EE4B38237 +:10DFC000584F35E2E23BA1AB5FA2758307358C4722 +:10DFD00030684B4FE50ECA895890CB89E3864CF2E6 +:10DFE0003124A7B518EB20E4EB8D92B2D681FC88E2 +:10DFF0002C6CC2005EDFD63D19FDCB3018127E0FAF +:10E00000196AD22A7FB280956DF61F1C2A9D46A4FC +:10E01000C5F902B4BDC8325A59CB39D8DF7D0C20BE +:10E020001FF393378612A42F3EF285A7E0601FC925 +:10E03000F1AC346F5F8676F76D8ADF588FF46070CD +:10E04000FDE065FFA0FCCB9AA1DAE47176CC5ECE50 +:10E0500075E88DB94A90E69B7D39087D10AB9F30FD +:10E060006A103E065903D2CDE65A1570BC6090C3C3 +:10E0700065C299AB9C4CCB40701C4138187A088E15 +:10E08000701990BFC7E039E280E788039E23567875 +:10E090005ABD7CBE4EBF7FB12CFC7EE6F7A21E3C73 +:10E0A00001EFC4EA90606245A457C21AAF1BF4F6B0 +:10E0B0009251A58146EBEFF4FBD9FA1CB7E9871919 +:10E0C000A2AC33BBBE84E0B37F8742A2132A2B30BD +:10E0D000E0BF2E9E61E247BFE6FF32BEBBF1A00B60 +:10E0E00090AF18FF2AF8DD25BEDE28FCD8C5A8FFB2 +:10E0F00099DEFE1AC4C308DFBB2093BDFC2EBC1CF6 +:10E10000BEC02217EF93DD428FB305B5F22F185131 +:10E11000F4ABD56067AF1226349874269DA2753390 +:10E1200080FCEE20A7B7247857917DD1C5F5A3E9EF +:10E13000F77DBDDBAEAFBFB1C55EBE01168C42FA46 +:10E14000BAE1DB2E48B17E6FB4DA1F6C7DEE9035FC +:10E1500082EF1BD0D2A905C9CE6AC2792CD6404520 +:10E160003F6DE9BFFC9F698BD87CB60A3DFA3693B8 +:10E17000EBBA456F2C89A4DCB1F2A1F35B2319F350 +:10E180002F92869FDF5A57EF7CB40F929B5CE4D7A7 +:10E1900081D35FDBAD90BF666947F05EDF659FDFCF +:10E1A000E9E6EF9C2FF35868BE4B762C22BD39DC94 +:10E1B0007CDC3BA4582A837E7BCCD48742BE98F477 +:10E1C0006DF275B206B8BDF7FF7CA9356CBC57502F +:10E1D0003ED2FAB79CCFE3282DD3F179BA76BFFBB4 +:10E1E0009CEDFEF039DBBD29E4B8B3DD526F9F1B17 +:10E1F000D773B99AAC93E4413BDAEB6A898D61A895 +:10E2000070EDA94EA32966A9D77586F50E4A256734 +:10E2100054AF4E1EA1BF63C2CE38B0EBFBEE3EE45E +:10E22000BF9D6FCC47FDFECD2715F0B2791DDB15E4 +:10E230008234D2A79A72A3BDB284D1558ACAE96941 +:10E24000575AEC2A46B1D4FF371F0D917DB0E471C7 +:10E250004FAA9EB55FF2B3FF98020C0FC756F7FFA7 +:10E26000720CD2EB4E89FB7FC9BE2957B2F74B54D3 +:10E27000B82E9E814E6485F3CB3BFF1A6842BB4F9C +:10E28000DAB1F7ABD46FCF352E94CB66BD4F6417A0 +:10E290008DCBEAC5F07BF287526A82C4E16B983C71 +:10E2A000D4EF7EE78712876F8F2BE543F8766C7784 +:10E2B0002758BDE53BDE23BA9DF3E88FC38887E589 +:10E2C0007B149BBFBB7C8792F64CA1E71BF844CD27 +:10E2D00028317E5B26F875D9EEA5A40796F56C78F3 +:10E2E0000FF975F91E974DAE33BC1869C4EBAB8AB4 +:10E2F000518FE59FFE735867A87A3BBA33AC9553AC +:10E30000BF8BDC8CAEAE98616F87FD7F9C33B43FD2 +:10E31000807E8A6B2EEF59C7C703AE6F4C3E7D1BC4 +:10E32000FF923F546F4C52ECFB0E27E08569148737 +:10E33000DC919BD18F33F585C9AFDFFCF1896D4945 +:10E3400036EE3B8FFF795B92C17FD35FDFDF7627AD +:10E350009B173CE3D3500E2DDFF94A182C78AF55AC +:10E36000B81F76EC87FFFCC856C62FC75EF7905DD6 +:10E3700077ECE93F8ED5D9BC8F3DF6C928B43B5721 +:10E380003E7DE968A4AF954FCC190D23F80F48AF37 +:10E39000298F755D53B4AEFA1E098330004F89A7EB +:10E3A000637D9EDDADA43174FBEE6B9E9487E167C7 +:10E3B000397BD75A89EBB594F41096EF62785EB644 +:10E3C0006BED7BCA944CF84E8E91A3F8646C13C528 +:10E3D000F5BEF28A8BABF0E93274A40FE827F9EFAF +:10E3E0006CB7FC105BD7F3875FC71370D28DF85FF3 +:10E3F000BE6B1D1FD7B18EEFE25F2ECCA0FF87ACA6 +:10E40000E34DDFDB8A1F77E7D2BA0FB78E4B9FB899 +:10E410006A44FFCC9407A7C36FB3C4E13A5F89ADE8 +:10E420005090AF1EFFD1235B237C7DEB19428EFD04 +:10E43000F8C4580C2E1F75F57F15E564FFD31EED4B +:10E4400021D666C9D3AF129F1D7BE225B74E72124B +:10E450008212D37BC760E04F2FEAC165122F2C7F59 +:10E460003894F68407D76959AAA14E0FD3FB37E831 +:10E470007D8AD3FFB2D4DE4629C3BAED544AB85CD4 +:10E480004EE5115E96EABD6E2D685F4F6906AEE3FC +:10E490001B7391EE865B4773FE1ACE7FBA653D1FF4 +:10E4A000E67C3B1C7F1EDBEE51A5ACC1F53D26ECA6 +:10E4B00083E529E955C8C0B700AB39BCC3EC3F9A26 +:10E4C0004F273D3CECA007B3BD39EFD3F1F5E9E7A9 +:10E4D0007376F8FAB6A2DBE8C6C4DB3B2733CBFB86 +:10E4E000B49013CB205957307EA8BE52219E1C53A6 +:10E4F0003C086F678F4272FC9D1D0AD9E94EB9B086 +:10E500006C187FFCD70AB73F96EDD93B05E5D73BA2 +:10E51000FBFE55D021A7F365BBDE702785FC4F5964 +:10E52000E53FF697613D5E13702F7F2A737FCB77AF +:10E53000BD97B1BFB7D5D83508FFDBBD2E48B22E89 +:10E54000DEEE5132C637F6292E5B1CB73334EDB5FB +:10E550002C8C6F86FD3ACE7BCDEAD8AB49B4435EB6 +:10E560007601D981AA71D4C3BEAF09F969DF7B4DA9 +:10E57000F806D02D7ABADD8127351A273F588DC489 +:10E58000AB78EC3565F3475D9A6C831BD46421C688 +:10E59000537E5DFC4715FB7D11EDBF7306EBBFA8F5 +:10E5A00042472EEBEFC59864AC820CF12947FFF18E +:10E5B000590AE8563A8B95C9D6F86A78DFED149770 +:10E5C00068859634C689A0107A7E60E9F7C1360D59 +:10E5D000D26C7CA82B93ADF1554F4B4BCCC3E028AC +:10E5E0005CA995A06936DCF8452DB23DAE2DC65F1D +:10E5F00021E209B063E7CE9DACDF3AFC56827E0C87 +:10E600008F5731778AEC9839420EFE9BB083F749D9 +:10E61000F1FDE867C5F4CD2ACA39A974B38AF6C4F6 +:10E62000BC93DDEA620B3DCE2B5D5588F472F0336E +:10E63000A529135D35AA9CAE5615AF2DC4F6077DEE +:10E64000B7157227344AF32C10F3DC5FF48D601F8A +:10E65000EB776FF137364E6470D54515C0784B5D5A +:10E6600064D1C60A36FF82438AE163E582E6A49A52 +:10E67000983C749C6D28EF19FE1E423C32F81F6EC8 +:10E680008B52F991369D9E3BDACAE8B9B3CDA0EF23 +:10E69000BBDA6650B9A7AD8E9E8FB7C5E97DF80E7F +:10E6A0007F02E977775B13BDFF595B829E352AE7CE +:10E6B000B779021F9679D33E58637B7835C6514CA3 +:10E6C000FC39F15DCB282E87F60D241DF13D5AE56E +:10E6D00072C589D7D6D620D9A5DB24B0E1739ACAF2 +:10E6E000EDC8B880E3696FE23215F7F9EB4ACBC9A0 +:10E6F000EE81B881727A9B14BFA782F1CB81A2E927 +:10E7000051ABDC0D051371D5422F63BB787C66BA23 +:10E71000CAE5531DACDA9FC5E08B9D041DE9CC9C76 +:10E72000E7BE6ABD10E5E2BE550C9E72FC2E439911 +:10E7300085CECCFE660AF82098594E0FD22DE7FF01 +:10E74000E8CCB2CD1827668EA7314127ABDBD66E59 +:10E75000B36AC6BD75A263934E18FF1C288A503752 +:10E76000DC5F6C2EE6DF7D9CCE5BFBDEA3F856748F +:10E7700014D8E28D1DCD32F9395B0FF3B8F489E678 +:10E7800092CD1359FD6A8637F4DB73E69566252C26 +:10E7900074BD51D0D3566F3C4B1B417F758A7A664E +:10E7A000F9902FF12D5C97EF8EFB493ED2F356572F +:10E7B000EA5A948FAD873DFA6A36A593817812BFE5 +:10E7C000C70BD97B06D289BA951E9A5A90EF3FB4EF +:10E7D000DEA56F3EC7C2E721C3CED7DB5A478E4BBB +:10E7E0009B706F43B84788CB9A709BEB71A2AEB118 +:10E7F000FF1B30140FCE7E73E6358E38FE83C8774C +:10E800001EC2C3362BBD15B668B4CF60B637E7EB72 +:10E810006CEF9CEF60BEC299EDCFF4B82017D7F330 +:10E82000B1BF8CFDE98B804B1E57508E5DA7267AB9 +:10E8300010EFD3A085CAA0F6E723BFFCD6CFF970AE +:10E840006BE723F9C4476AAA18F5C2998ED701F17C +:10E850007835EA2D4336ACF2DC7CFE4235E30469C0 +:10E860008A1FD116331B520EDC15CD84E781FE0BB7 +:10E87000D577ACFB491B01B89F9EF6D23E070644F4 +:10E8800034562E3E0895EB597F3B853CA956B95F1F +:10E8900078C1417DBBC2E3474A43C88247114F3527 +:10E8A000E3581D701768ACA95BADD88BD54D3EBC45 +:10E8B000C29DF82DE2CB1DD569FFDD1549105F81A2 +:10E8C000887FCF1271FA4B95C301945FADD01B388E +:10E8D0001FF9F99002E41727C6135F5E34CC3EE1BE +:10E8E0002E619FEF10F2FA1141370FA3BC66CFEAF9 +:10E8F0009EDE34B2F4AC875373F0F99090DF292197 +:10E90000BFC355FEB4C4ECCEBBA71D4DB43038BA5E +:10E910008F1E5770294D793153C067CA87993E0EB3 +:10E9200047B8BFF366B4BFB7A1FC473DE73A30FE36 +:10E930001E86AF8E84DBF0907C89D7B5E03C0A65FB +:10E940009AC7CF0B6B641F2B3F658081FD3DD816A6 +:10E9500023389EF2F6BFFF22C6F767B98D247B1FCE +:10E960003E79FF2DD86F58FDD13FE0135213F8FCCC +:10E97000855C32F9ED59D70109F5F9D38540E38576 +:10E980004FEEB90DEDE7F0C9E76FC77697A4A03653 +:10E99000C0EA072B767FF97CD67FD6E532A0091A2C +:10E9A000ECEE4F74B3FAA5AD2DD538B57F93D201F7 +:10E9B000FC9E9CA7921C1C0BB15518E7C8DB9890D5 +:10E9C000F07BE8418EB78BB6F4FEAA1A109FDA3EB0 +:10E9D0001C6FBCAB98CB5FF9B939B8F7E2297AD391 +:10E9E00087EBFAECD11580F2CAF3814CFBF14F7F33 +:10E9F000B002BE61CDAF38AA668C838D7779F8BE40 +:10EA0000D5070BBAA7E89CBC907F66FEA9D64B7CC5 +:10EA1000FE02D8F661CDFD2AB37D859418EFCAA316 +:10EA20007D09BE7F25DA5FA4A02DC78A7F96F97E77 +:10EA3000693C15B0C641827F92E399ECCC2A974A93 +:10EA4000F0B41BB5477FCDC653A75F4DFA17BAED9B +:10EA50007038DB3138AA381C1C3E138E2246EF3E3C +:10EA600036FE53C77F978FF07D5C67EA95DE00FA2C +:10EA7000F97B4FC8C46F9BFA81F4CABEAA7D5EC4FD +:10EA8000E3C6AA1A3FB773383DE6087A7CB88ED73A +:10EA90003F51C5F7F5E1E429DAF77289EF3979FBDF +:10EAA000BCB457918C05ABA7A17E32FF58F2081871 +:10EAB0006E8A93F63C02B935C7562E8202477E4ACB +:10EAC000C9A05C453FBB2EF2FC38064A48EC3B57D8 +:10EAD0009BFBD8CA6103E7FF80A9FFDABCF4DCDE48 +:10EAE000F25000E31CBF30E9A4B9670ECE6FD64DDB +:10EAF0003DCF86D97C2E3ECAF7CD9C792928F75088 +:10EB0000CE6ED4D2B9563D0AAA87E031F7372E3EF1 +:10EB10006ACF5399E5C84319928F75967EE572972F +:10EB20003DBFF0046C9C4474D15B625B9FED173277 +:10EB300037E6FCA1FEE540BFC27F8228976F3942CD +:10EB4000AEDC7D87D28CF651F8B2CA6CEB7E68BB26 +:10EB50008BEF9BEDFFBD0730FEBEB6D64B711B732E +:10EB6000DFDC5CF70D986485F90DED3F0B205E9FAF +:10EB70008C94F8F0F9ECCC9D245FCDFD7F8F98D379 +:10EB8000EA993BBFDC8C72294F269DD251B86F0C9D +:10EB9000EE27DE5BEBA5FDFD70A0AFE759560E7EBC +:10EBA000E436703FFBE9EA7493D55FFDB18BEBA5CA +:10EBB000FB5DC2CEDA68DF6F66FC70BF8B7DF70449 +:10EBC000E3B45F297B459E84C3AF31F111DE972FFB +:10EBD000174FE6CF92C983F6F883827EB60AFF66A6 +:10EBE000A3B0CB9DFD14376BFBDC68E7DFA4552A8F +:10EBF00019F8735CABDD2E286AB1D3FF98663BFD34 +:10EC0000878C02871D9126BD65EADFB5BEE078B42A +:10EC1000BF2A997EE4F680265BF7D79DFA77A71A7C +:10EC2000FB99EB2CEC907020DE82F876DAB5FB04D1 +:10EC3000DEFFA2C4D288DF801ADF47FDAA719237B7 +:10EC40004E3B61089CC0E09C3C229CBF3A1B384F65 +:10EC5000B71FF0911CDFF22203797616883C8B10E7 +:10EC6000D91F1D21EE9F74B8B85FD02FE8E80D972B +:10EC700042F33B26CAB303D092397F8CC7878EA359 +:10EC80002182F54667CED7450B85BE8FC9FCFDB8FE +:10EC90008BEFABCD1E37F2381F88717EADC6FEBF3D +:10ECA000CBB26FF3A42BF69EB5FCA18BEF830DAC1A +:10ECB00087C8C735EDA53D6AEC235786BCB49C795F +:10ECC0002AEDDF9E00BFA130FC3C930FBB81C991B0 +:10ECD000672481CFDFFB488F99F81EB0A7517EA033 +:10ECE0003E381C4861FCC45C0773DFC59C87693FE4 +:10ECF00094B9B93C6174E37313DC71BE3F08699247 +:10ED00000F05826EB6FA16DE53CB9E77CF7CFB35AD +:10ED1000CC4F78F7099F8E706DAA3A12B6CA4D682B +:10ED2000B6D38FF9DEF5F118DA97BF554A8C765BCA +:10ED3000E328917E37B67F46D2C97F4BBEA290DDD5 +:10ED4000FB8C949A44FBE82AD0FEC533374653EB3C +:10ED50002DFB1B4EBB3EC7D7F7C0729C7733B39FCA +:10ED600060E8BA9976B959C63C106BFBF96CD9B911 +:10ED70005DCDA6CBF8BA42CCDB50630A100926E879 +:10ED8000391D747A32FBDF7033BC5D00FDF9C84772 +:10ED9000AB03632FE2F6C67F1BDE66E378FFDBF092 +:10EDA0003648B74E3DCDF719F2041E42D042FBED76 +:10EDB000BF685ABC6E021BCF5D18247B35AFA9FD1E +:10EDC00066398CD97DBD1AFA977962FF1B1AB97E14 +:10EDD00036F7A373EAEDFADCA9BF3DC2EEF00CA34F +:10EDE000D79D727338BDBEC46DD7EB03F1E261E409 +:10EDF0009F335E7C7AF9A7DF535B8C7919B1576B2F +:10EE0000D9BAEC9BA5527C333C1EAE8B5BE8E1B0DB +:10EE10005BA1FE0EBB791C643DE3D7D4399CCFE1E6 +:10EE20001CD4074C01E1FE41919CC2FC9AB5C95427 +:10EE30001DE69BAD552768D675AC2E62762DC3EBCB +:10EE4000A61A7FB3D5DE7ED3EFE271D840F541E458 +:10EE5000C7F260AA86DCBB1873FC46F13C4B5CB77A +:10EE6000F334E8C37D570F70BDCD38C2CBF54AAD42 +:10EE7000F616E56326E0546024BD60CFBFDCA9A68A +:10EE800056FB111F111E6F096D91281947E989A5BD +:10EE9000D17F981C58B095E4901A2FC371F64E6339 +:10EEA000662FABFFE15E37D9393DA1312ADA95CF24 +:10EEB000C88BBFE766F3ED7FDD03B87FD2F3D9B926 +:10EEC000748EA12774D15CA4831E099827CBE6CF4A +:10EED000F88727FB4000E3F4E13931C03865FF2FA4 +:10EEE000C078888DEF8AFE344E79BA100BC833583B +:10EEF0003B1F7461BE8AF1A9FFFD4B18DD3D1EACBE +:10EF0000BCEF7C18F4FB4D7FFF627FE231E4C78EDB +:10EF100051BF6B463EEB62702A6487C5A2087765D5 +:10EF20009E4CFC0779C1D404F6BEFA60A416F3CF58 +:10EF3000AAD50A94340C0EBEDE877C892771BEB533 +:10EF40005A436D36AB5F7548277B656EF4E6FD5816 +:10EF50009E7698973BDC40F620F22F58F8AFFAE304 +:10EF6000B134BF5F0A39DE1E8DF5C6A411D64353F6 +:10EF70001DE737EC792B563AD0A6D9E820E1B2D27A +:10EF8000C10C460793AD741093CE860EBE8D5838D3 +:10EF9000237EE17C729BC2F96628DDB77873CA874D +:10EFA000F28739EEFAAA9C08FA19261F68D3EFD225 +:10EFB000B0EC59E4267FCFE40B931F4E7AF9BE02E2 +:10EFC000E38B3A1F7B3606F54B33F105FA7356FA9D +:10EFD000BF72183E990FFDFB31C77EBE0AC92C26B1 +:10EFE000427E7DE1D1D2B116BA77E269FE2C098E5C +:10EFF00058E4D1A953BC6CC1A33690F7AC9C39BE80 +:10F000005F56F58E8885EF3A99FD8C4661976C4086 +:10F010005E31F2DD62BF07FDD5FAC7A214CFF7C497 +:10F020009B294F6DFA3B811B181D7E384AD671F221 +:10F030001DFAE247897F5F0B00DA6D9BA62D1987C9 +:10F04000FEC9873726C6A13FB68EE1FF081937A94A +:10F05000D132E53EF58DE6FB637A943F1351FE1EF7 +:10F06000C4F79428C744BD3EAAC7D6D9260F377B1C +:10F07000397D6FF6723B709DBBDB8BFCD55FECA5D9 +:10F08000FD53B3DE250AB7DB6678787D38B946C70D +:10F0900078D50C0F6F775F5B2AFEE6048473073D1B +:10F0A00073EB5380F17F7F5952C7F8BB7735243219 +:10F0B000D97DF779791CC0BBEF9F68DF28B7D4A052 +:10F0C0003856A49EF56759AFF90C35594C7E30700F +:10F0D0006348C71DBA9FECB0F9919A3FA95386AE19 +:10F0E0002FFE39625927EF5F95440FC50BF87EC696 +:10F0F0004AE1CFD59678892F3A5ADDDB712A0B3C4D +:10F10000D9DC0E8DD48C982F8B7E53D283712E2F09 +:10F110003D713F23790EDFCF487AF87E46D2C3F7A0 +:10F1200033F089FB19F81DF733B0FC93B6189571CD +:10F130005F03CBB8AF8165DCCFC032EE67E0734FC1 +:10F140005B333D7FDED642DF9F6A6BA5F2251E6EE4 +:10F1500067435932BA80E1B9EB76770CF7A9D789C2 +:10F16000F5793656926BB075F445B8DFE97BE15E10 +:10F17000C0F9F8A23C6ED419BD17AE67CFAEA9A1F5 +:10F180002EDC2FF63E1AA4A74FBD0FF420EE4F241D +:10F190009B3153B6C5F3C41C95E9F7D2E8CD353998 +:10F1A000AC7CABE7C93518BF9AA8AF32166B836544 +:10F1B0003D54B9E4314B795CF976D5CFEADFB9F645 +:10F1C000E935C8A708071A6F1D9EF49C556CC9D372 +:10F1D0002540E735FA8BDD29A4B3AFE17A21FD782C +:10F1E000B85DFF655813453F799CEEAE44FE60F56F +:10F1F000D39C2ECFACFE3ADC94CA1BDA6EA47A7292 +:10F20000D519D5036584FEF0BB34423F1DB046C31B +:10F21000B3631B9097312EE80B909FD6E5E27CD923 +:10F22000E5E3CFA35E73FFA8669E978D3B4FF06921 +:10F23000972F5E87F9CAFD93658A17F4B858179817 +:10F2400084DB5AFC9B1236EEADCFAB8071E694871F +:10F25000DB3713C685B8BEBCD34BFAF24BE37EDC7A +:10F260009EC3CA13BE6F18A8FF3680E1473A496EA5 +:10F2700094693FF74755E3731A58F5F3A63E918317 +:10F280007184CF047FA7F07C112BAFEAB8611CC654 +:10F29000953E7C89CBA547C538DB5DBD2DB49E531B +:10F2A0008364370074935DB02AAAD23EBC9CCF9F82 +:10F2B0006E97F67758CFCD146F92C1E3FE6CBA9774 +:10F2C000FCEF8F3DE25C5A2FD90B6E5F42CB66EFAD +:10F2D000BB9332F1FB1ACD9FC2D4FB0DC14A3A2732 +:10F2E0009B2C5729CF7A43398FD3054257A7D04E4D +:10F2F000B867AF8FCB87A097F2AD52E5BB0FD6446E +:10F30000F0296BC8EFA9D8823AC2BB266B94B7C567 +:10F31000FE46DF9B239497BD01C4BA34F37866C7D9 +:10F32000A84F7F85F1DB355FD70C715688F21EC977 +:10F33000B491F1DC6EFFBE00C2F315F39C51DFEA1D +:10F3400000ABDFBE5833701DA66835751827ECD0AA +:10F350006ABCC85781C9B5DE45248706F292E93CEC +:10F360005B7B39B757F13BF225B4C37E3CBF3246D5 +:10F37000C8B24076A584764E473D858D306FD796CE +:10F3800067D99E7319E5B12BF37308CE0E8879B156 +:10F390007EB29EC79DC704BD69B4E3C698F1434CD5 +:10F3A00031B6F811B937D9F394F39B55DB398ED1C7 +:10F3B000097B394FF805798E7CE64F3DE63E8A1D84 +:10F3C0004FCEF9E6461ECA467873F160B23E743EEF +:10F3D000F7452A1B709E63343FC11DD55657A3FCC9 +:10F3E0001A0D2DAB90EECE1A5E079C53CADB7B71D3 +:10F3F000DDA7E82A9D5B381FFA5763BF1B049D7782 +:10F4000015DBF564CAC3FD06C68F95C88F18E74A99 +:10F410005AC6C7386FD232DEF8AE1C5B79427781AC +:10F42000ADFE395B4A6CDF27A5CEB57D3F6F47A5A2 +:10F43000AD3CB967A6ADFEF97B6A6CE58AF465B6AA +:10F44000FA171C5C602B4FEDFD3B5BFDE9AF2DB661 +:10F450007DBFB06F89EDFB454757D8CA17F7DF610D +:10F46000AB6FDACD4EBD58EEFD7CF6B207CF75D945 +:10F47000E282767BDC694F7BFFBA465F8D722DECB2 +:10F4800026FA56518FB3F28ADBB93FE39D6DE82827 +:10F49000574A841C0D056317E2BA5587BDA40FD4E3 +:10F4A00020AFA706E792DD31760B934717A015082A +:10F4B00003DF032897DB92F152D720DC3EAD9BCED1 +:10F4C000285487EB00E3BD667B558B412284E3E93A +:10F4D000DC9E61DE22D6F3E9ACBD651ECFC8321DCD +:10F4E000E9EE677ED74316BF6B383FCBE9579DA93E +:10F4F0001F3556063F3EB74BF1167C96B7BC54837A +:10F50000E974CCBFFA0AE261933BDEBC1DF7434AC3 +:10F51000FCB42F66FA575DC53DC417FDC52AE9172F +:10F5200050F5F20596F8569797CBFB80F701F2EF6E +:10F53000D492190775C4FB2A95E20E1B241E1F499D +:10F54000B27540BDB66DE6D1F7FE91BDF79678C7AE +:10F5500078993C329E75C770BFF33E81D712ADA239 +:10F5600086595CCCBE68D887CF893AB333D8B3AC60 +:10F570006CF33E7CDEE1E5F974E71A8FD5A02CF13F +:10F58000CEE6F69F32C59D5A8DEBA7713886A33320 +:10F5900035670BDFAF2A55DF427A436BFB943C485B +:10F5A000073EA403899E443FBE4890F4860F0F7720 +:10F5B0006159955201F63D521A9330CFA23ABC855B +:10F5C000F6557C69BBBDCAFCCD2EC46BA4DEBEDE85 +:10F5D00001EF3682AF5DE2F1D7AE6CFD851A067F92 +:10F5E000575E490EC64E303ED16091379B85FDD6A1 +:10F5F000E4934DFD4FF24646DE983A68EF30FADF6D +:10F60000228F47F8BA01E596EFAE6E407AF7696C43 +:10F6100035D1DEFE5692E8DFB4776F11BC555BD270 +:10F6200044FB5EEF472AC9BEF5B5FE2423FE7C7D70 +:10F630000AC42E181EAFE1895B49DF43895B47BBD3 +:10F64000A25577C7B667900786D007EB30CF03E1A6 +:10F6500011791E5D021FE6BEDBFB66FE93D807BE76 +:10F66000251B6CFB7FB7E4558E1EC91EF731BF2FDB +:10F670006181771D1B07F1D271B2A12E4EFB80C0B4 +:10F68000CFA57D56BE9DCEFF0AFFC510F6CB0C0F51 +:10F69000C7EF5837909F3007E31717A0B7F9E53A3F +:10F6A000E44B33DE71C49B43F83792A0B490BDE2C3 +:10F6B00032F5967CEA7C8259779B714A3279B95E41 +:10F6C00063FFEEC57314E3BBECE7932674DBCBE773 +:10F6D0006CB19727A5EC6566351F42BBA001387E4B +:10F6E000CEDB61FFDE60C6F96AF9B90A2F1BF91497 +:10F6F000D7BFB673AC20F4BF194F2DEA4957A37892 +:10F700002D5C69D7AB0542CF1738F4676548213FB8 +:10F71000BFFA60643FDA8F66FCE510267F59E2A9E4 +:10F72000661CC529CFFD873703FB42FE72C2C3E3C7 +:10F730000B09E6DFB4168AB845117FBA14FDC585FA +:10F7400064A7B59C83F2E9696FE2032F192DF67364 +:10F750000FC7EBD45F483A1F276119E7B6B2E497A9 +:10F76000F8F453944762C6314C3FFD642036CFCB4A +:10F77000D67D83F172CBB318477ADD03D8CFA5CA03 +:10F780000B07DB587945914A798FDAF49BBEE7C7BE +:10F7900038207E67E5EA627D34D1FF732EF2D7D739 +:10F7A0000A7A36CFE398718F6C1FB79F433ED32EF2 +:10F7B0004AFA455EAB1FEDDCF37630D96CD3733C6F +:10F7C0009E66C6CD26F7D8BFF78094ABB1F53BBF98 +:10F7D000292573BB2A16ACB6C4D5CF15EB356561A8 +:10F7E000FADE85ACBC0B5295783F4485A00B63BF15 +:10F7F000FDFCD72890E89CC0A8438A9162F5A73CFD +:10F8000065FF5EEE381F76AEF3BC9823CE1B52E048 +:10F81000BD456CBC8D7A8B84F273E34266C3B3F250 +:10F82000B93E912F3C112622FD5DAA048D34E2F7EA +:10F830001585F486E78D735E5D84FAFC259E97A29C +:10F840008DD737D7B2B2F62B85F49316808A8AE02B +:10F85000605CF8FE5306B4BB06E34C3BD9BA964E47 +:10F8600040FFDA0BA8577EC2D617CB3DCC1FC7F29C +:10F87000E3CC1FC7E76EE68FE3FB9F317F1CCB7B9A +:10F88000983F8ECF9F337F1CDF3FC5FC712C2F0F1D +:10F89000545FE28C5359E3768371AA3EC98C53A11D +:10F8A0002839EED6699D07E255091EAF3A7D3F31F2 +:10F8B000B31F8A070EE947C405DFBDFD778FE079E6 +:10F8C000E9A5535777E1B957AFCB8C8BF13C08339F +:10F8D0008FD9E4BFA5BB6FA6FD6077FEA1165C8F34 +:10F8E000DD5541BA53C8ED4A68281F9DFE97E97758 +:10F8F00039ED5FF3E9D4477EB4032E403BA99BE288 +:10F900003EEB5D5046E76025BF817CE18C439A7CED +:10F91000FCA2AF24E3F9A5817C58119FF140CA8B6A +:10F92000F132B724E629F2354984B12E36203F5B07 +:10F93000F28B83E5698A73048331B2BF24669791A1 +:10F940009DA625A21887EA1C26FFF541C1A7ABF2A8 +:10F95000DD746F44673EDFFFAF2D34A2D87E4DFECD +:10F96000B4A8351FD6CCD7DD1F9AE6EDB3F4B72285 +:10F970005432A29E52985ED547D0AB8A87E7ABAF90 +:10F98000D977A117F390D70717F7A27DB53E1AA133 +:10F99000F3EA7BF3A791FD31503F3A83F29595202E +:10F9A000B75B95A897EC5615E75F3E58DFACD72AB2 +:10F9B000E433633F8ACF05823D54CFA3C629FEE1DD +:10F9C0008900ED5779BC3C5F20C8FC6BAF2D6ECA37 +:10F9D000C7BDD9C7E5DB7A3D11C776EBA3AA8EE296 +:10F9E000687D5925E1798DC0F39A3C53EF1B646F14 +:10F9F000F4083968F6B346F8EB6B9ADD6477C55BBB +:10FA0000B363B5B9947FF903E4BFF5C187BC98CF60 +:10FA1000EECEAF1AB1DF27C5FA0DDFEF1B35B517F4 +:10FA200050BF3D3E36BE3BB458C37E5DC3E4D91FD4 +:10FA300014707E5EFB92614EA3FD2E30F56D2A6A36 +:10FA4000DD27763EFD68275E30B4DD52BD6F2EE6C1 +:10FA5000F9AA90ACF32B43CF292CDBC3EF9DDAA49A +:10FA6000F692BDB3E9A494F1BC43965F12CEFE803A +:10FA70001F6EB357C6087E1A23BEEB68AF14A35F90 +:10FA800069B72F2E38682F4FEDB597A7BFE6B4574B +:10FA900062AFA0BDD228E45D2F93CF3C69A25F4541 +:10FAA00039104FA6AA11EE06E85985FB942E11676E +:10FAB0006E14FAEA0AA1CF5C7E1E971DD3ECB7F94B +:10FAC00089E6FD1985A2FFA2DAFD37B7A3708D9BE9 +:10FAD000F68F4EFE65D1BCC7AB494C3AECA0869878 +:10FAE000FDFCE9150E3BC7690F55ABDB29BFB2C062 +:10FAF000117F30F729719E780ED739FED98E6BF6BB +:10FB0000B795E92DB457CC7B09E8DE2ED6BE484D1B +:10FB10004B06C353410B50BEDF989510DB9E818E80 +:10FB2000A789751F82B7E42584B739E25D4190DF6C +:10FB30007B5250ABA4F462CCDFEF21FDBDE0263652 +:10FB40001FB2974FD13EB4593F27BB672FEE136EBC +:10FB5000AD97B8FF9804B243CC75DE1AE4E7651A96 +:10FB60002E965232B66F29A1F109AE92C1F5657891 +:10FB70003AC2F1C4F3CBAEACB39FEB6970D81B268D +:10FB80003D5CE178FFBA4F23FA30F9E0DD0B5F9B73 +:10FB90003896C1B1544AD6059433D79316FE709D5A +:10FBA000423EC4BF8FA2A9107FECF3FE54A3FC8099 +:10FBB000ECBE078091E4657E48D6CE02F8377FFF21 +:10FBC00079122B37F8CB3BBA2EC6E389FD3F42A30F +:10FBD000CCE3A9B8B4AE68B0ECF75F4CE588188701 +:10FBE000B91649BEDE967B0A18BCDF15F9011B6207 +:10FBF000B059C11C4B59DB6C140FB6CBC176D2087F +:10FC0000EDE2B059CDD02E68B663E8EA34EFF528BE +:10FC1000C127FF2E0B78ACE3AB88374D0FD2B99DCF +:10FC2000B9AA86790F5F148E51A79B770236BBC69F +:10FC30000F6DC7C05E65C22F67863F85DFADE3BB32 +:10FC40004680FF6F8D8FD3F5E716DFCF1A3E567DC6 +:10FC5000F5A8E1E78B70B9E87E0C3D285BFAB9673F +:10FC6000EF2714BF56AF053A97A3BA629AC1E8BC12 +:10FC70005CFB36F9E16A76AD8676C03A56463B6063 +:10FC80005D4F37C5A9CB4BEFED42A22F4FFB01E5EE +:10FC9000C164D0B277B17E276B2A66E2807AF17EAA +:10FCA00019E3DE7039D0B990ACBD7E7E8F45F1CCC2 +:10FCB000EFA37F949DEDA53850207BDAF7B9B1CB47 +:10FCC000E3C126FC81EA43351827571BC040565430 +:10FCD000A5145423934D02DA87F0C776DF86E72B0D +:10FCE00099E223FD44773BA05E1571F1D19C64A09D +:10FCF000CBAD35A09F907C5EA5F8FB68BCF2861169 +:10FD0000657979CE6684A73CC13A90107E1ED79A59 +:10FD10009C908D34EBBFF23DDE0EFE9D9F0760BED2 +:10FD200044D313C141BC9A7265B488974717DAE38C +:10FD3000C9D0CFE6CCDA57FEFB821F603C61D410FD +:10FD4000F9CDFD6BF3DE9CACF720FE04ED6BDAF52C +:10FD5000865FDC4FE177DC7B302E683F8737C46FEE +:10FD6000F8569CF480070CAF9BEC8B85643798FEAB +:10FD7000C856AC88F1FF22E079D9CEF6D3787B88DB +:10FD800072FFC4E367665E25FBBEC41FA37C1F0F22 +:10FD90002B333C4A6EF0E6B3F705328F8BAC9240C2 +:10FDA000C5F2E07869DAA75F2B195D8634E8FFAE0B +:10FDB000D10CCA1F809539367BD9CC435D7163F174 +:10FDC000E81CF6CC1A3CFFA3213DAEC82B25FB391D +:10FDD0009CDBF7F7285F8FAF5F7FA917E529E62F38 +:10FDE000CC04F8ABBFA323C9E4ADE7E331A05BECDF +:10FDF000328FDA427130CFC7636DEFD36DF6F38285 +:10FE0000B1A05C8BE3E461F23EC683416BC776D55B +:10FE1000603F17E8F938DF66A70FF65F687B9F66DB +:10FE2000F68CF53E8AE1FB0F805E66ED7FFC30FDCF +:10FE30004F74F4AF65EC7FB0DF5C5BBF1D2A8F8F22 +:10FE400026237E5A77A73D3039505310C81B217E98 +:10FE50001FE0F1C7B5D1168ADFD700637846279730 +:10FE60009C3CA2F0F36B40761B14DAE3F735827EFC +:10FE700065461148BF97A8F67BC06683F35E30BB2A +:10FE80003DD48B8C827E65A8AA97E2F89F0475F416 +:10FE9000BF86B3977BDB80E2C7B3037DB7E03EF557 +:10FEA000A51B1E7075CC10F9AF05CC8ED8D0732968 +:10FEB0009EF3EB15E7F33A2232E1255E339ACEDB6F +:10FEC00098FDC4DD3001E5615CE6F909F4878DDF5A +:10FED0009B57F0D0FA0CF8739EE76C8849F1520BEF +:10FEE000DDF4CA0CAFD6F1E68CD9AE58E611F7C0F6 +:10FEF000541A4FD8B903E38DFA7CE3BD24E24EE6F1 +:10FF0000780D73EDF36B706B34BF06C1BFE6782FCD +:10FF1000E1FC32E0F7B4E3C99C6E06C6FB927D7E3D +:10FF20000D1E8DE6D720EEF51D186FD4E71B6FADC3 +:10FF3000AB258176DB6689F3FFDD817FED40BFED88 +:10FF4000FDFA1551D207C22EBE021BB07A57A87C0B +:10FF5000BCF985DED42ACB785B991C88893CF7985C +:10FF600007F337342AA7DAA2F47C88D9D931CADF5B +:10FF700028A3EF8FB41954DED136839E663F6533D4 +:10FF8000F83D3393664919EDED5F06B8DFB8395F88 +:10FF9000BBF66BA897AAFDFCFCE38C8B2066B17FB7 +:10FFA0009941BCCF87FB2F574305EAB6895B38DC04 +:10FFB00091DA51295C3F7FC5FEDE3656F6B85C3AD1 +:10FFC000EA53C60BF14C7EEADE00F7C33D6E2EEF1E +:10FFD0006126BFB770BED02BA0D44B2EC4C715D995 +:10FFE000B4DFBFA03116D218DE1A25E99552A1A7B9 +:10FFF000F0FCCA5562A99C767E043506EB37125395 +:020000021000EC +:1000000052781FD15585079B502FC74357927F10B9 +:10001000670D73583F57093D59FD860730DF012EA4 +:1000200075131C8D8D767B7EB32FADA17DB2B92269 +:1000300002B83E0BEAEDDF3D6ECE8771C73D05F39A +:100040004F736F01DD9D95218FD4199F7C32608F96 +:10005000439E80F27B6AF1636164C47B0B5604C0EB +:10006000BCD73263FCC884E74D94635391DEF650ED +:100070003CCC84AF404D4928AFC734EFB1E53531B2 +:10008000C492316CC6E141D955817E88733E5BA52F +:100090005DF923DD535200EA5B7D65E21E4F69E89E +:1000A000BC7F1710F9B703F39EF5622964E21F1EA7 +:1000B000779D7F503156E9837831F1F03FCD479DF0 +:1000C000018ECF17E77C50C5FDB742DB7D99E63D39 +:1000D000C0570E9455502DF47CC51237D93310EB10 +:1000E0002F47BA3B747180DFDB66DA2FE9D765B43E +:1000F0005FBE78FFB1225BDEA6E877B8F572E61145 +:100100005ACE7D0EE6B9637E89C4F7B10A30CF2D91 +:10011000CCDF1FB1DB99B63CB7357B7F28619CEF04 +:1001200001CCC7B3EC5B8F61FE3CCACDC29BEC79BE +:10013000754EB8CCBCAA8173B3B31AB55D3ADD93E2 +:10014000D88D17CF746D49C6C1921F699E1334FDB7 +:1001500069E7F94025C8EFCB8B8AF316CE78F06DAE +:1001600072522B96301F35E5AD66CFF29C848147E5 +:10017000D36F539275F85E193DB319F1B0B0F54ED7 +:1001800003E3775A6EE6B8F442A1BF2F0A72BA3978 +:10019000EC4A17611C3B91537351302F43FDD66FCE +:1001A000517FB387B97FBE51F4F380D0E7CEEF978C +:1001B00007795CE59AA532DD67E183504A2AC67D5E +:1001C000E3EE19742E6FD95623D3B9B783E144BD3A +:1001D000151E5F293F6F0DD07321E26BDD5F1EECB2 +:1001E0007994A132E72F4192A3390AEFD7D2BE31D9 +:1001F00053FB673EF92D9D537E06CFA9CCC4FEB6B6 +:10020000CEC5F8F7A6813224252C678B72F2B6B9D9 +:10021000E8EF0D962BE6566319699011D9ABC1DA58 +:100220004EA4974D120862BC94D777F1FABBC5F77C +:10023000D997BDF37D3C970BD3DCE4076E12F688AB +:1002400009DFEB419E37F3FA69F079ABF81E447C85 +:1002500046CE0A9FB766C2C7EB39B1DB8253B19F66 +:100260001EBA17D2F717EF4ACC23FEA73630BEC608 +:10027000E6F080B1FB87F700B5FF5670EAD0F6F3E1 +:1002800072626DD86F70E9119A5FA83488EE0DAC78 +:100290009B0ED44F0638D666EAC75CD774169763B0 +:1002A00027D076CEC375E5F69FE2E98DE2FEBF5614 +:1002B00075FF2D1A93239DC5DD4D99E8FB3B21BEAB +:1002C0004F9D3D4CBC7A97A0C757B5F877118E76F5 +:1002D000ED5EBA4FD52D71BB61DD8C3E902CED7E6D +:1002E00015E2F519DCDFC3FAEE0BF93DA72186779D +:1002F0004C300B5571F8D7E98700F3BA43D14394DA +:10030000171AAAEA237EA7A30A059CAED05FF30AB8 +:10031000FB6C57F0DAB94817398A49777FEE443ACF +:100320005406CB4497DB7378FB97427FEE4C3291B7 +:10033000BB8DD92F78EF46B280E78D38E7F72F21B4 +:100340004E1FF787638F23BC43F0E9E9FBFE3DAC0A +:10035000FDA609FCBCCD6CB9B7E97AA4CBCB82640D +:100360007FB1F74DD673C86F0A7CBD19E4F6D3A6EA +:100370004FBCF4DDB91EC3D1EB0BA2FDE7A0D7172C +:1003800032D109A3D77F477AB3D0EB0790995E0F9C +:100390000D43AFAF607B275E9C6505625B707F5647 +:1003A000FD74EE0EEC4FFDF2AC2D8FB2A7F2E95DBD +:1003B000495A4D43B29D2F35C7A99012FF11B4C8B9 +:1003C00077F33EEE1B83BCFF21FD4E9FB605E5D8BB +:1003D00019F47B2C387568BF4F0539BCB32F0B2639 +:1003E000329D1FDF1252E9FB43213EFE707C7330C9 +:1003F000C4FDD9E1F8E65141578C6FFE7A267CF3B3 +:100400008741BE7187F2CE846FBE4D4F5F29E71BD7 +:100410003A863C7328DF40F2D54E94AF9DC59C2FA1 +:10042000466F7AB313E31C037C943C41DF95C132E1 +:10043000C963938FFE73D309E22367FBF030F75251 +:100440008D15F33E188E17E13C62E769EDFC9C4D7B +:100450001FE9EDEDD0BFD74379B63CAFD59F4CC671 +:10046000B8D9D00B78BE7FA2C0C336F4C1D0CF9923 +:1004700026E24C6A2F2C080DE5E75055BACA7A9F40 +:10048000C0D362FC0F43F1C9A1A9385EDF24B4BF19 +:10049000865BA74A31DE3DD9B1CA5006FE3F9D1E9C +:1004A000BA26C4CFBB5E23FAC9F98BB705ED4F2737 +:1004B000BFCF5EF6F33F3D32423F8DA27D7DE873B4 +:1004C000F37F7D2833FF5F1EB2F37F15DEB799817E +:1004D000FF1B33B567FC7F55E86FCBEF8B4219F8F4 +:1004E00072E619E2FB6181EF87BF20BE570B3AB974 +:1004F000E3F3E3FB8E61F07DE719E27B7528837DF2 +:10050000C1F0BD2644F6CAE3047F480F521CBB6B02 +:100510003AEC964A32C2B1C1DA8F57E7FD30BC7F60 +:100520002031BA9FFD699791E99E19D6EE5E2BFCAA +:1005300066BBCA9066266FDF8CFEF9035F0E52BC65 +:100540009FE9C7FBFFC674F050263A982D7339F423 +:1005500041F0B14E8CB37D81FE7F92A9FF6621D719 +:100560004F6717EC1574C1E6FD4468EA50F9B75DB2 +:10057000FC2ECAFDE1C45321C257DF3C9457DBEE89 +:10058000C891301E55184B4BE8273C2EF4D87921E2 +:100590009D9F6710EDB6A96909F359B6B568129E1B +:1005A00037B2F4F74B1C6FB8FE9C7030F89EC3F165 +:1005B0003F0CC59EC767A598DFD9DA490DD9B19719 +:1005C00043A47FE287486E9F6397DBE63CE478377D +:1005D000E5BDF86664FEDD96C783AAD063F1DF5BF4 +:1005E000E5FF2B0374C5FB3B5BFDC3E07B2BC4F530 +:1005F000CAD14CF039F1723A38F34203701EC77E0B +:100600009D7ACAD99FE9B79AEBE4469D648DEB0CBD +:10061000E8BDC45F897F3B643A87345FC893F93390 +:10062000B285DDAEF9B1FF07449CFC819BEEADC6FF +:10063000FDEEED77691588828266AEF7F49BC652AF +:10064000FCD317966C714CF339D0DEDD3309EF190A +:1006500067E386C2ACDE25B3208D7E6316DA0D1407 +:100660008FD0E877BB723CDD518C9FAE93BA9B165E +:10067000A35E9D17E4E74AA28DA7B9AF6DB58D6E55 +:10068000215A759AFAABA8BE16E8A6FB2FCEB8BEC3 +:10069000A7BB29537EC994B06CE275527824BC463E +:1006A0002314D732F13B741CBE7ED5F11609F11D1F +:1006B000AA92343C7A15627482F6925CDA4BF94C59 +:1006C0009757717A01E6978C7C7F46A769AFCD0A70 +:1006D000E77D71B8CC7AC38F27EA39CE2BE0BE17FD +:1006E000C567835C8E5145563E7E303763DCDF7CC8 +:1006F000AE6DD30A5597B5FF14E179ED40FEB41104 +:10070000457BAB15383D42D44B7618DDCB6E59CFC7 +:1007100084589FEF66C5FF3E4CF019740F2168DACC +:1007200019CD87B55B4CED54D62E74E6ED867F9AD5 +:10073000BF5767E871CBBD6726BF8E4E2401EF9986 +:10074000F1978326B1F58F84CC7D424E07DF0E9A58 +:10075000E5246D92C74BBB795EBE6ED209972B5ACA +:10076000A0272657006CBEBBEE4BD149ACBFD2448C +:1007700014AFD067E5032AF9E1BC0CC9BA03FB0B3F +:10078000917FB4732583E9A9F6DA03072F067E5417 +:100790008A7E4FADF600C93BB38C175294B1B27F3D +:1007A000A01CF34659B964A09CC4F236A12737DFD8 +:1007B0005D7BA03D48726CA3953FAA051DFEADE987 +:1007C0006FBBDEAEE13983645425BB6A9D831EF6A0 +:1007D00084F97D2C93B5C4365CD7F977F5AB787482 +:1007E000C55B1C09213F8C8B7E90C4FBF2C6CD12E9 +:1007F00069AAA5FC9E86EDD195C497DB715D80A7A3 +:1008000025607C72707D5299D7A72C45EBE3D7F910 +:100810007719CBE46FF3F85BA08CF3B3E6E1F1BD9D +:10082000C704BDA6C33C7E9416F2352BDA4EFE9467 +:10083000B74EA6F871569D6CD31BF48B77D44EB58A +:10084000DDFBFF7A4EE2A9B0452FB01AF132360F28 +:10085000FFA4480EEEBF5497A92BD1DFFE9EB0FF38 +:10086000D83A3D40EB5411F127486EC79FB5CA8F67 +:100870008175137839DDBAFDB62D61D4BA865FB7BC +:10088000ABAF5532DE93F6DB30F75F8F35FDE7FD1A +:10089000389DA5DE7EBABFBBAB7415C561CDB8ABC4 +:1008A0006777757A8C3E980FB83A109E854FE7B8F7 +:1008B000BF3DF95D8DCE897CE2C9B89F7452E0F9E5 +:1008C000505B13B5630B4CBFB7721D4E85E7B1D9B2 +:1008D000CEF199E711BE0A9C181AE38B2E4739B462 +:1008E000B849A17B1BAE037B3EC557CDBCAF563389 +:1008F0003F8EE77D25207B2EB2E1A2A4E3F722C044 +:10090000988BE7E887FC8E84D8DFFABA236FE29AE7 +:10091000A64546ADA8F73EFD3F45F369D4B9FC6D49 +:1009200034F8FD3D57C5AF356A2DFBD1AF7EA664C7 +:10093000CC9B9C9765E2236ED44E188A8FC571C9F3 +:10094000ADE9A7C7CB99E261915A31374F1F8A07AA +:10095000E7FC19C636219EBFCEF08C76E770F860B2 +:10096000F5683D5EBD56A1DF8F99ABD4BB701FE427 +:10097000FA0689F698187EC3222FAEFE520BBC4EA3 +:100980003C3AF175FDD340E706AEFF4E88E26D2F8D +:100990009BF8495F42FB17E6FE89659E4778FE9605 +:1009A00046F35C30A3E217786F42A25DA2FB1AD92E +:1009B0007C6DFB808B219E85E716D8BC8F0CB3EE37 +:1009C000B6FD40277C4EF87D42AF38F7C5404D97C5 +:1009D000A31E9C9D25F605A78021F6C7B2281DB74A +:1009E00034B3BC75DE3767D2D975AD0D03E362FF52 +:1009F000122406CA1A9ED77A4ED97415FBFB8A2890 +:100A0000FF1DC3F8B5B91DF86D3E98BF2F14A3FDA7 +:100A1000A6EB04FE1A98C787BF7D7609134EB8AFC0 +:100A2000373FE6D38396791EEF96EAC439AAACC65F +:100A3000C9D82EB957993214DE1551FE7B858C0E1C +:100A40003FB0D2A16F02BF47D68917135F8B06F163 +:100A500032E56CF0F22A2ACE3CDAAF213BB75FF2E6 +:100A6000D27978731F87FD35E966A2F3D6AC62614F +:100A70000FF0799BF77701B4907DBF509CC73AEC9B +:100A800082A6C7827C5FA7D222B76ECBA9BE35CB28 +:100A9000E2579BFB3AE67D51263D7FD51B4C2B9CB4 +:100AA0000E6DF7410DE63125288F49C9BA49477CBB +:100AB00074E1A70BC9EE5985FD2B01BE5FE57BEE06 +:100AC000A75D57E983EBB7FE6B4F744F6565FFD7A2 +:100AD0007F93A44EF51CC25B48AC5BB55837133E00 +:100AE0007F397F6F593F1E3F2B13F133B18EC3E91E +:100AF00009731DCD75433B0AE9D757A67E9AE9775E +:100B0000F7607F553FF26922AA520E5D427AB383A5 +:100B1000EED9027D1BEEBF5FD7EAB2FDDE5202CFF7 +:100B2000E963FD753EE19718D47E713E6F0F65DC79 +:100B30006E1CA0FB246B6FC903026F7814AE5B1FA1 +:100B40006B8B7962ACBF51A8EFA1CB324EC9D0718B +:100B500087EDCFD14E19D837310CC322AF1FCBE26E +:100B60007AF278B4AA47CE107F319F8BBDB985AA9F +:100B7000253FEC48BEB729E3EF0689FE06EE8D1B44 +:100B8000B013DF39B07FD6A09DB8C1F5C703078B7E +:100B90002C7622FCF100F9ED03E5B3B3135FCFFA35 +:100BA00023D9891FFDDE43FAEA789D9FD621B775C8 +:100BB0000EFC079EB755F1B7FCC8BEA77B6FBCAD56 +:100BC00063683E92CA3087BF07A61B12E2FB4896B5 +:100BD000CEF7637548871870B9AA2121BEEE15FEBD +:100BE00028A3B349D6DFFF3D22E66B8EE3F1421224 +:100BF000CF199BFD323A584579A5F5407AC4DC8778 +:100C000035F9D9ECE7589664CBAB3E03FE3D9635FB +:100C10007528FFBE20B7FCE11FD17E7D5EA17CD090 +:100C2000AF446FA7F757B75E4FCF6B5B6FA4E7C7B3 +:100C3000423FDF2A253E463EED6DFACD576E63F406 +:100C4000BA7CB787CE952DBDF54F77237F7A5BD9D8 +:100C5000BA63BBAF5FFF9DA9ECBB7B824CF66B57C1 +:100C600011CFE770AF9278BC5F77D7ED66CFE670B3 +:100C7000F544CD02D77F01C39B58310080000000AE +:100C80001F8B080000000000000BE57D0B7814D5D9 +:100C9000F5F89D9DD94792DDCDEEE6B5900713C2DC +:100CA000230AC44D202128D60D011A2B81A0A8515A +:100CB000826C0884008104B4B2552C1B021830D613 +:100CC00068B562B57C8B85D6B6DA06A52D6D23DDB9 +:100CD000085AA81463B50A562020B5286A228FB294 +:100CE000B6B6FEEF39F74E7666B21B82EDEFFBF734 +:100CF000F7FDE2D71EEEDC3BF771DEF7DC7367EB46 +:100D0000EC5347390A09216EBB811411B2CA42FF64 +:100D10002D1372F1E8FDEE05C984C45BAD1EFA84A3 +:100D2000989AB21F32D0323920921D148809647EFD +:100D3000C5580ACD0CBA1D122185000D081D00539F +:100D400008B184054292A09DC7D368A56529401CBF +:100D500000C3123E370942453B7DFF0BF8BB2E0214 +:100D600095FE2C619190F1309EFE7D133EDF249B19 +:100D7000CAE07D3189CD43793F9BBF9FCDE76309B1 +:100D800027B07924E9FBB1B3E722696CB7F69FC7B6 +:100D90007D89A5231D741D7576EF288084741B2B17 +:100DA0006C84DC61FDFD61218F428B35245248FC4F +:100DB000C68FBA7309FE7D311CFEBFCAF1FE184210 +:100DC00004D22D7C41879EF9B9101A46F11757229B +:100DD00006D765532838CA274CA0CD4A8C1EC06759 +:100DE000D78864DB70D5F8C50E01F1F7BAE4B0C15D +:100DF0003C2BA68915C1B1D87DCA1CE8675A4DD1D4 +:100E000066369C85A412329FFD9BBC2E6F6F194ED7 +:100E1000EB0301A36724A5E37C4B2008F39B4FA4BD +:100E200040B7059B085F080865A988BF47E73B7F77 +:100E3000AAE88DB36BDA912FE83CC97AB26F04ED62 +:100E4000FF0E810F10A065FADE315E3C3EF5DCCD71 +:100E5000B08C6EE2300DA7EDEFE8AE9E41F2B0CA65 +:100E60000AFCB488B79BEF379EEAEB97FEAF3AA037 +:100E70002D2F28CE7F859281E225583601F8EC0A85 +:100E800003F2594D8BB6DDA277AFFF80D8A15FE9A1 +:100E9000541FBE619EE461C66FD39A1D32C5D3381C +:100EA000878C749F39F5BDA9849667117233F43B22 +:100EB0006BAAE808D1D6AD7E03F1D2891FF28A4130 +:100EC00081AEED506EF781EB006FC5467907AC350A +:100ED000973C785332D48F77009E2BE0D9106C4F1B +:100EE00008B4735B8223E9B32EEF7BD61A15DF1D9E +:100EF0002A7EEF0A1FA5D75603A98BC64F8434E17B +:100F0000BCF6DD138FFD1C7F54089AE9FCA7899F6E +:100F1000FF61229D4FCD7D468F59C6651980AE3346 +:100F20003C4C1E09F15AA7517CDE4158F93D525103 +:100F300014A2E3D7E41F2D31D37E6A360828A70A0E +:100F4000FE29BE4FAAF1E66BAC480CC98877CD7379 +:100F5000DA9909F899E2F9640C3C9F54E3D9FFEE61 +:100F60009171FB54ED363B6CC9C0E7A480147C4101 +:100F70005173814C4E1C4FFAAF5B8117D71E1EB7C1 +:100F80006F24218F12EFC3A87748B754318ED2490E +:100F900022DE687A60BA9DC9C134F123A4CFD96238 +:100FA00051067C1DF27F68A51C460E7D2E96019E83 +:100FB0008997369A1479EF870E13E279AB89780115 +:100FC000CF5B875A824DB4ABCE7BAE4CEB46FAC8B2 +:100FD0008F4F063AFEDE4876C8B1E76BF38B6404A8 +:100FE00065CC72BF8050A1DF307F1C91C647DA0DFF +:100FF00023D1E7BF1BE498B64F59430C321DD719D4 +:1010000020DE6014BE50DA2DB7F44E9708B60F39C3 +:10101000E9FC56C886A040D79B2FC88CBF8D8DDEBB +:1010200074DA54EA981D4827300F11E721D3F949A3 +:10103000747ED9FE042C0FF72721CCF13B118EF0E2 +:10104000A763FD487F0EC251FE6C7C3EDA3F06CBA3 +:10105000B9FEF108AFF0E723BCD27F0DC231FE52DA +:101060006C37D65F82709CFF067C9EE7BF09E15516 +:10107000FED9083DFEB9589FEFAF4158E0AFC6E733 +:10108000E3FDCBB03CC17F27960BFD2B1116F9EF8A +:101090004538D1DF8CB0D8DF84ED26F91FC0F2D5FA +:1010A000FE6F23BCC6FF30C2C9FE27B11E1410E07C +:1010B000219ECBE303F242079514E07019F83896AD +:1010C000DC5DE4F668BEC37B1CF84E696732109F96 +:1010D000BABDD2EE1CB71B4EA06B94FE3EE1F4FAF3 +:1010E000C473F23BA349846E2DEEA60A2246E8653E +:1010F000DE55124AA7FF5CB17B3601BD40729335C5 +:101100007CDA5F3FB0F51DE3FA6BABD4E515817F68 +:101110001B8927401F954F785D807EB6C952593094 +:101120000ABF8D761AF1BD710EDFBFC05E25649FC8 +:10113000DA07FA6456C0F18729C02F63937F3F8591 +:10114000F6376CBD0146A0AAC4D13985EA1D792ABB +:1011500041BDB88D1094A76DF15A7B3ACCC9F041CE +:1011600048FBFEE1284F230A98FDE9BE1EE4CB743C +:10117000CF70B2391BE42D2448B4BFC02A42762870 +:101180003603DA6F5CF003A88FF467C2750E6B212B +:101190002F59E844B2DBE4297114E66CF1BE144720 +:1011A0005F1919F44D89A7E5D1CF045E0278457B1C +:1011B000704A02856376875EA2E6948C0B754FB108 +:1011C000D2F255FBC95E406B7E975C6AA3E5F1875E +:1011D000BD7B291B90C26E5FA95D86F9049BED74EF +:1011E0003E5B8F114F132D177FD426261215FD4D10 +:1011F000C4B7534517DB84AEA949F49F197739F278 +:1012000045785FEA8E738EED4F9F6DB06E5827B5AF +:10121000233BE8BA32BC21C1A1E2931B9C4C6F5125 +:101220003A5CE5043BB4A65782756E5BEFB221FDD4 +:10123000E21D253064EF34E2785A063E96104FA640 +:101240000DC351DE15BEA3F8BD62B64D8D3741D139 +:101250006B75ED6363E3F70627D37FFF2DF87DC73A +:10126000C1E421167E2DC02B932E2DC755CE3E39BD +:10127000AE74A6C46ED7C4F1AFC7F33603D94F6DB1 +:10128000151D97F229932B12A04DD770FEBE145E48 +:10129000EFFE2FE3DB9B9C03E395C8C9A82729BF7A +:1012A0005E417262EB1BE82F9AFD7A80E351A5E75D +:1012B0004CE02FB638A89ECB89ADE76E755E427FB5 +:1012C000713D63E27A5C196F0BE7EFFDF68AEF8000 +:1012D000DC58371802206725C4867241DCC99C4F50 +:1012E0001CF1C02733444709E81B329AA01F9D30E8 +:1012F0003618807DCAB0805C20423350CA80C7A1B6 +:10130000B9C1CDB4EB6CEA674894FEB4AB10408B26 +:10131000EC302CA0EB4E54E4CD51ED56CB9B62EF5C +:1013200023F2A8F0856BDBE66CC6AFB3A9FFF236FB +:10133000C753A41F01DB6DFCC6D06D9B557A709B13 +:10134000DB8D65A57D2CFEBDA0F0EFFA75C407F21C +:101350003139BADFF0BA53E47CDBEB053E0F7C8514 +:1013600038C09F71AE3F89FAC949F59380FA898DDB +:101370009FE18FFF418096BB9CA95C9F3BE26FB1D0 +:10138000FDFFE3E71D4EC2F4D46447A748EB875145 +:101390003B24839C4EA6739F00F83221DD65C2E892 +:1013A000284F2641F07B29DE4206D0BF065B10ECB9 +:1013B0008CC9D4E60579262627AE7FBFDD77DC39D8 +:1013C000805C3812E47C206AAF335C66A5FCB731E0 +:1013D000DB110FE58F69B9D54DC77575135E6EB119 +:1013E000A2FCD0BFA148C510DD1B807D54CA5E0B96 +:1013F000B41FDE570E40792BF82457D3FE1FFEDBB7 +:10140000FEF51431B39DDE4F9C8CAF7B017A47D340 +:101410000D6A4E849F2FE50F28F219912747BE22AF +:101420004FD563511FFEDD5918E92F967FB38BEB23 +:10143000CF04D7C0FE8DC2F797EDDFF0F97EC6F579 +:10144000522CF98F3BF0C696EDB4BCCA2DCAA7A8A2 +:101450007F671BFA569744CB16EA6FBE47CB064B05 +:101460009704EDCAA9845A29BEBDD4C983FD8765F6 +:10147000022BC31FEC3FCEB609654C5FCB8973C608 +:101480000D84C720AE6795DB84E3C58D1C9108727F +:1014900065E77C4524210876DC5EEC9016607FDDF4 +:1014A000E446DA5FAECBA0916BD05BCF8F05BDE495 +:1014B0009260BF6EB69080CD15E91FCA890511FDF7 +:1014C00044F83EEE4EBE676A5BE7491C01727A88BB +:1014D000C551DABEC9E4B23C8304D7819EF012D96B +:1014E00041DBC711E58F0A2E2D1B7969C6DF05E2A6 +:1014F000A5F33FF87711A13082846C74BF57EE11C9 +:1015000042B00F34192C41B0A525432DC40465BB4E +:10151000216806F93829E03A4D050941507E538784 +:10152000162776D3759C3BB8D7EA8B42FF5B7DD5F7 +:101530009EA9E363E3B1AFDDBC971D80C727E5F546 +:101540000EF023036E09E30E9BA0A94AAFDFEA3237 +:1015500029FED06C17F8430B7BD79B80DED9C9E8F6 +:101560000F91112EE4DB21EE5D9B4AC064D533FF61 +:1015700074280936A9FD2A85BF8EB87C73A19F27E0 +:10158000B91DA162D9350AE2555724BBC02F2D6978 +:1015900018DA01FEEE136B8967A111F5C14C68EFF3 +:1015A0004D6ACF07FE7DD2B3EB470F013ECD745F8E +:1015B0000C7A7CFC51AB4CE95555B83705D6F3078E +:1015C000DDFCFBFC0FFF37112FFA7DF03217DD0732 +:1015D0008342CC2379B00F3EE7B9293184BC9514FE +:1015E00055BEABFCF7623FCA7EF85D6328D3115548 +:1015F0000EB5F856C6AF12D8BE961805A6FFB81D90 +:10160000A5FAE53E58277D0DEDA6D72C3C0DF6E654 +:101610009C67BC07EC762C7DA3CC87E27164852D9A +:101620004ABD402AA2E989C75DCC5E5719E97E818F +:10163000D60B2B0B1B615E5536AB007CA7B46BE65B +:10164000ED147E56E25562E2E785407F880F465BE7 +:10165000FF7C229D57C7A39A41D65218BE3C51FC2D +:101660009558F83A6C6C2B87791D5E249226DACF58 +:1016700039DFC43412E57D05BE037C43E9B21CF6B4 +:10168000FC852A7A8E888EBFC36BEB3C538D117A12 +:10169000F6ABAF8EAB04FB5D0978548DBB9FE3E5E1 +:1016A000848BD97B62F6C90E5A6F5AF098838C03EB +:1016B0003D75BE306083B858EFCF9B80DEF7D930E0 +:1016C0005E51597DA1B0699C0A9FC5048DE4FCBDA3 +:1016D0004F3864FABC72E4FA948035361E4FB8D89D +:1016E000BA1E800793301EB3D77519F11832D6850C +:1016F000FC46F6C67942108FFC93E801BF01C6F59F +:10170000A1FE64F1E4BB1C6C5E713A3FAFD2BF42F4 +:10171000A35F12C2020926A9CA523BC66713C212AE +:101720003ED7CBDB0E178F3B717953F01F8B9E0A90 +:10173000FEF5CF431CEF87AB97C8103734C547F78A +:1017400083D392040D5FBDB5D6A719EFED7F8A9ABA +:10175000FDB202CF73FA9EF34D4A837855A5293026 +:10176000723072AEE0E7ADCF1F7740BF719F99A393 +:10177000CADFC7DC3E517BDA72B3ACB2A7B789EBE4 +:1017800001EF0912D76F3AB9F3825DA5F8BC0EECF0 +:101790002A9D62C225ECEA7C12E88438B27E7CC5C0 +:1017A0009EEAF94BB1AF7ABA297CE04CD2EA4B25DC +:1017B0006E184BBE14B93AC2E55F8F7F3DBCD5A40D +:1017C000F57B14F87E1F3DE24880EAC73B4BC420FE +:1017D00011903FD03E1E7E4C407F33546D46BB5C23 +:1017E000531D87F1D99A7C11EB6B1E14D17E86A80C +:1017F0007EA8A7F3F903D713FAF86C09113C5355E7 +:10180000EB9E39214E53BE6DD1B7FFB016E2CBC56A +:101810004619C63B24B37873C02BA2FF4AFBF08461 +:10182000203EFDE8B51EB0670A3F1CF28A286F8192 +:1018300037450F0CDBC5E3D1875AF28322D059F02C +:10184000F58D23E740FF3532D0E1887B8B03F45DD3 +:10185000DC3F1FAFA8C0FDA34FCE47BB499D553A03 +:10186000EF382EA7A5438B6F013B7EBCD548206E79 +:10187000747CCD3994E7EEB58D9EA92323F16525BF +:101880003EAC8F33EBE3CBFDE2CABA78B2C20F7A3B +:101890003EB939067F28FA2A167F503D5695947234 +:1018A000F97A4CD11FEFF075960EDDF26013C54347 +:1018B000C24211F1A0F0E591CFEFFF1EE8E138CA76 +:1018C0001FEB809FFFF9C397611F42960851E3C841 +:1018D000DFEBB37B942EB911BADCE65BD25706F18D +:1018E0009F5BB7B2AF0CEBD7DB95D87A6D60BD3597 +:1018F0002C89C581F476472F0FFF69BB5359FD58DA +:101900002EBC5F59BD280870D3504B1DE85FBD9EAB +:10191000D0DB09653EFA79268445121CAF9EB78C50 +:10192000ED2276C284F57E8B3D0F9CF58B710C0603 +:10193000C00904BFF4585CB019C76BBCAA02E7DF4A +:101940003811A09F78BA03B03E773CC60FDA325800 +:101950007BF1FA78E68F4F70E13A45C5213FEFC43D +:1019600072335FC35897EFD9243A8F66AF210ECEFA +:10197000154A6DD20108B9B44D31103389E049F1EF +:10198000DF094406E87AB14E807D67BEC59483FEC8 +:10199000E92EE4DB6FD27D21E5F78307C55DDBE847 +:1019A000120F7AC62746F3CF1538CFFD0DD40BB7EB +:1019B000F86B101EFDFADB5920AF770BBEDFC2BCFF +:1019C000BA2A6B1E2CA4F369D82DE2B9D2BCBB8F06 +:1019D0008C62FB34EDF9A468B7E4421CA55988F782 +:1019E000801E51F0D86933A17E693ECAF460F309C4 +:1019F0008197D93E621FAF3FF7AE0DF7190ADEE9B6 +:101A00007A0EC1F8DE6F3B713DCA3EE3DF58CF91DD +:101A100081D793E1407D017C2546E62FDA245C578F +:101A20000F89F7C0FCFD3C1E44DE8D43BF59A16FFA +:101A300003E73F85BE2B387D7B3A2E7CEB1ADABE5E +:101A4000CDEBC253063193E07A7BDE4D40FE50D69B +:101A50004BF9E06398DFDE0E6627DA8ED918BE6C8C +:101A600045B9303FC5BF7624313F59BFEE2ABE4F3E +:101A70000F27097DFE2DC4297CAE29E1A428F2A000 +:101A8000F8B514CFFF80FA1207391F24113C2BE35D +:101A900028E32AEF9993B5F255C5E30AEF1A4925D1 +:101AA000C41361DC02D5FC56BB4ACCC929FDC7FD75 +:101AB00037E8E84ABE0C3A3648D6162191F4ED8B49 +:101AC000319426F79773BD9C091D9D9FC1F9BC5E9B +:101AD000FE2F1A1A8940FB5D2DFA0EBB286CF69179 +:101AE0006E734E7F79B8941EA1F4BE32B9B0BF3E7A +:101AF000192C9D0B93FBD1B93079003ACBAE8A8972 +:101B0000500FEB4F2FC07DDE2428839E300DC7F190 +:101B1000902F7B9D24F8346D94C4E328CA7C202E3A +:101B20001147DF2B4BCE46FA0B120918693929D71A +:101B30002380DE1F041F94A9E7F71FE0839B06E6BE +:101B40008310FA25CB39BD972B7916BB06CEB31877 +:101B500004DDAA61DC8B064FAF2FFBF2E956DF9F55 +:101B60006EF503D3CDD700F2D36C22E7D10F2FAEA1 +:101B700076C378FBEDDE9389F4F99E26AE4FB22949 +:101B8000DD68FDCBC922EAAB47C895A887BF6230A4 +:101B9000E0FC7BA8FE7D3A3B1ADF0724177DFFE2BD +:101BA0008D04CFE3E8FABE998CFE4F4080E7ABE7A7 +:101BB00013033C77CB4DC470197A6813D713AA75F9 +:101BC0006E52EB81287AA815EA293FDE05FC689160 +:101BD0001DD2407A68CBE5EBA12DFF613DF4FD817C +:101BE000F9EFB2F9EA598677AD3E50F858D917C4E3 +:101BF000CA17A2F248D25DFDC725C483E7612576E6 +:101C00000BB3BB3B05B4B3CD27F27D58B659502971 +:101C10002876F8EC2E562F4E89EE0FFE3CD985FC27 +:101C2000BBBC7DA547D2E48104F0F943DEB38E113D +:101C3000542F4E17ADB8BEA472163F54D64FF5ECD4 +:101C40008C69A93C6E4AD79394C9F09044FD013841 +:101C500047B3F3FD4162B1A4F1FB15BCAD162B04F3 +:101C6000887B3B9309A4DD50BF7ECD6838BF777A6F +:101C7000B5ED5348EBA7220E42501E5CD47E431CA8 +:101C80002BA94CD70EF62179D05EF53CBBFF7EE246 +:101C90007832DF4F98881BEC0A11AB06E41BD57E27 +:101CA000E2FDE441EC273E4A56CEC7B5F6AB3D8E89 +:101CB000448D0BDC93C2F71FE79DE8FF8ADC6E4D75 +:101CC000EDCEC6FC94553619E305A2E8B1CCC8EEBA +:101CD000FFBED36B20B26A7D4965F14456ED1F52B9 +:101CE0002A5C9A725AE5504DFB21BEE19AFAF4BA89 +:101CF0002B35F5998D059AF230FFD59AF6D9540017 +:101D0000D4E59C96AF69DA8F6CBB51531EBDE57666 +:101D10004DFB2B820B34F5639E59AAA91FD7BE4AEF +:101D200053BE6AF73D9AF6CD3CEEABC7CBB51CAFC0 +:101D3000CD12D33B4DD6028C47365BB5F1C8B414F7 +:101D4000A67F4A1227E7421CBCF9647E2EE07B9FE7 +:101D5000FD6A8C8BC7E20BBD1E8BA53FF5CF8BF8C0 +:101D6000789FBC6432801CACD84BE5F52A5AB6BECD +:101D7000B311D6D432969DA74A84E5F728E72BCA3B +:101D8000FB7DE72B9287C557ED56B2390A5FA4A5B4 +:101D9000C851E39F0A1FC5C2DB3D83C4DB5778BB34 +:101DA0007F176FEF0AA4523D8F2A7E9EAD7F6F751D +:101DB0008A819F07FB2A5398BF33211E3D7107CAB2 +:101DC000E3E5EA7F651E54FFD7A4A480FE7F63DEAF +:101DD0006AD0FFBBCC1ED8937D52F946EDE332B4F6 +:101DE000AF65ED0D9E5CA04BACF8F7EA947EF1EF89 +:101DF0003A16FF8ED7E06D514AF4F877B3FDEF182D +:101E0000FF6E3679720713FF5E043A2305E8C0F8C7 +:101E1000A38FBE3C7E1E6B1FE427E48000FB1EAB3D +:101E200024C339D7A5F6B5743F9B0BE7A96DB06FF6 +:101E300052ED73E8FE96EF6FE2D02E50BBD79A8238 +:101E4000FA911C90E9F38B74DFBB5986A262FFBC48 +:101E50001ABFDC4C3C169388F47C04E849BE49EE7A +:101E60008A13215E163A3839FBDFB2E7DF4BB90C33 +:101E70007B4E2E7D2E8776A79CAE7F5D14BF4B7F59 +:101E80000ED7E77F839F26E0791CE26903B58B704C +:101E90001ED799C2ECF386A36C9FBCE1C46C37CA11 +:101EA0004D4AD180E77083D537BF4DE9E797FE36BD +:101EB0006500BF5459FF2ABEEF9D268E6D8778E3DB +:101EC000D9B009F12612961FD9B0DF4882484F9643 +:101ED00067ACD0D118DED805F6D948F479C572229E +:101EE000ACDBB85F44FD4492597D80589AC0CF491D +:101EF0002CD6DA2DA7576BB792CA5C3A3BA6B55BD6 +:101F000069955ABB35C4A7B55BE975053A3BA6B5DB +:101F10005BC3FC5374764C6BB7725A6ED4D931AD37 +:101F2000DD1ABD456BB7AE086AEDD6986756E9EC89 +:101F300098D66E5DB57B9DA63E3FB459533F7EFF5C +:101F4000239A7261D77735ED171F7801F36F261E3C +:101F50007E5AD36E52F78F35ED28C2BB204F7B21BE +:101F60009284906B4E3FAFA95FC8FDB46B7B7FAD91 +:101F7000E987B4B17CEB00FD0FE8F557E2338173DC +:101F80002291DE57D2295D5704054F88365BB27B1C +:101F90006711CCE3CCB1EBF7433F8BB768F3B49751 +:101FA00004B5E506323C11F44303E58B20E5936567 +:101FB00090BFADD26BCB48A31DF32106C9678B0F31 +:101FC000DC4430EF33E0ED82FC74659D0ABF793963 +:101FD000BF29F353D6BB8CFA7D2139B24E2FFD8F2A +:101FE000ED23BB4DC0B7B5BB05F25DA1FF7AEA3A60 +:101FF0001EDE981E655DFA75E8FDCEBC546D1C7B37 +:102000009A68C5B8FED937450F8B0F6AE570D501C0 +:1020100016CF5FF59C80F1353D3E14BF34165EC48B +:1020200000DB273424936050257F32C787D9AD95D4 +:10203000BFB3F00F98CF536210F282E2E4783DBF55 +:102040001585487F3C27E46AE5548F679B67685491 +:10205000BE92E97F308F5AC2CEA5F47CA5C7FB8A19 +:10206000DD0F9B402F5E2EDEE7A56ACF0795F38339 +:1020700012BA5A53943C3805AF745F5E935A187B7A +:10208000DFDA907AD9FBD686D4FFECBEF59ED40178 +:10209000EC5C0FC4CBA85FA98F97F58F8FEDFD4C3B +:1020A000B0631C9AC5BF7C1E0BCB57D1D9C95CB796 +:1020B000C64EF6ED7B4F0AC166DAF912BB7713CC38 +:1020C00067A9DDBB196099DDFB807ABDCD142F783F +:1020D0003F87DAA99D51FCC3975315BFA802E3229D +:1020E0001B4A587B7DBB9FA5B2FB3C9D29456EF4E6 +:1020F0003B4FE433FB692B1AD0EF7C889FE73C0011 +:10210000E7852323793C0FF273152A765EA0DB0660 +:1021100063855B9DE7FB48AA13C7B34F7ABE0BF2FA +:102120009D9B1D06872083FF6CC073D1F55E6BD924 +:10213000AEB1ECBD64CD7B12DA6111F00DFEBC5581 +:10214000FABB9A6F5FA6B884FA58EB7C3995F9BB55 +:1021500046E2B580DE55CE738D27F32DA06F25C1E5 +:10216000E38896C769E4795253F879AEE860E7BB33 +:102170007D727E893CA97ABB6F9F9A6ECAB9EE1CAC +:10218000BBF765A0AB5F0A98C1BFF45BA2EF7F5FAE +:102190004D65FE470B5F1F7534918F707C7150F158 +:1021A000933753312E17C07CC5D5A2E734C4E70658 +:1021B0001BAF3A9EDACFFF399E3A70DCFC64229C5A +:1021C0004F240E95703B21797281FF5BE0DF9330E5 +:1021D000BEFA3EBCDF2FFF5476F17C5A79C07C5AA0 +:1021E000A59FD94EEFC78057DA5F4F2ACBFB5B2FF5 +:1021F000AAFAB15FA21F8AA7DC46EBA0F0F739C3A9 +:102200009FE7340B265C5E5CD39CD62FDE674E1BAB +:1022100020DE77F1E8E844384F56E256FA76167F2A +:102220005286FA7E4C8B533BFEC6025676A531BAD7 +:102230002D4E647C3F8ACF43C90354E2D69619C41D +:102240000BF71D1EE1F9D94A3FA3D26CD83ED13518 +:102250006514CC7763B680FBCA8D4E41B3BF3C9901 +:102260005A322A8DB69379FFA3D2189F6E1BCEE205 +:1022700033FA3CC833BCFD99D42908E99B57003E8A +:102280004DA218158F63D2581EC64988911546E293 +:1022900067358FB1FB5D4ADC4C890312E2792B81F3 +:1022A000EA95F75A8D04E25A8B44EB46E0C3BEFB35 +:1022B00073FC5CDD41FF037B593DB602F38FFEDD0D +:1022C000FB5B80CF04577F7B599AD6E7A7782EF324 +:1022D0001ED7D7D22EE3BCBD3B9EF16DAFCD8AF1A8 +:1022E0006C7DBB859C3EAD3C4E01FA1AEC864B24BE +:1022F0008DD1ECC7C234C637178F9ABDE8C794C5D5 +:10230000633E8772FE2149C01B98061E0068F1A734 +:1023100067C07DA2BEF30F99E07B49562BBE27C94B +:102320002464832BA1924780FCB26E53F7863498C5 +:10233000EFB58207EE0FA455393AD392E11EA18C76 +:1023400062B6319BD88BA13EDF80F5CE398E8D46AB +:10235000C8BB96099C6413231DC746C7694DCBC6ED +:10236000F5B7066EEA4CA3ED12E55E327C2CE8115F +:10237000C77437C87125CB5FD7AFEF3E2E1FD60D80 +:1023800074DF00F890A3E781DFC7F98FEA99354041 +:102390008F1299EC62F7A2581E2AA45963BEA08737 +:1023A000E54B2740BE510ED33350FF90B3741DF060 +:1023B000B9225F22C737F0BD3A1FBE95E33B4927DC +:1023C0009F0A3EE9004D900F21CD20C8D7B3AAA2A5 +:1023D000CFF7879CCECBED158FC07C674D6EC23C8E +:1023E00077F2F9175F8845E0F43239A1EF1388439B +:1023F000C42533FD1B27CBA88F8943C03C538BECEE +:10240000A983729CF56A870876CFCCCF0B171A8800 +:1024100044E5AD94F7E3AD24C2FBB92CCECAF4ABCE +:1024200044DE57E442E4C82902FBC9FEA85FD49AFF +:1024300040D7536A3D88E78871231A4BE05EC1CBD1 +:10244000F3591F8FC4C8DB3F99C8E8E0127D6E03C3 +:10245000F8F4E4E4ABFB26239DAF841B9A0F6C7861 +:10246000F7D5FD993C7E0EF9E281775FF55ABF7C86 +:102470007EF9BEC7DF7D15F2CBBF3CFF7B04D0E306 +:10248000272963C1BCF5FCAFE8B3C3A2EFF0BD14CC +:10249000FF3753A6F21700944815D29BE50FCDE104 +:1024A000780EFC9DE2D912C1F3CD1D07107F878DF8 +:1024B00074DE747CE314866AE33D893C1F2388FD47 +:1024C000DF62699B06FE4D8FA9370FC6ED79F1EDEE +:1024D000CC00D52747EF3B672394FF8E4BBD367862 +:1024E0007E7ACD1B36C0D7D13522DE7FC37BC9AA09 +:1024F0007CA0F7395F95BA2B8E025FCD5FFBCF22B0 +:10250000B59F4DFC296877970445B8E3DBA7FF9694 +:102510003D93C0998E9597B72769CA8A3D5E6E8EA6 +:102520007E4F3CDDCDE8BEE4D96D26C8872F75FB14 +:102530007A409E4EF37C83D3BB6CB8BF52E6B3E0C7 +:10254000D97C13EC278F77984908F85EEA32128C11 +:1025500053796708946F7D9C0FF5F37C654F02F605 +:10256000B7E83111E348D5742C3FC5ABAF6309DB45 +:10257000DFEAD6B1E8A83C1DF4D5A24D0209C8ACEB +:10258000FD1A4A379FFF7E3C5FD1AF536F5F2E909D +:102590003526D0237AFBB290785A2683DD6AD33E63 +:1025A0005FDCF100F6BBF812E7314E37DF9F159183 +:1025B000895FE4409C7938E60BC6B237A7D732A1D1 +:1025C000FC70AD05E1476B1D088FA631BE5DB6BB43 +:1025D000F3957414EBAE22B04371074A2DB793887C +:1025E000FF2C6DBB29F4A40C7CA9CD87ACE27856F6 +:1025F000FCE7C5FC9EC1A5FCE72A58E700F9905509 +:1026000083CC873CBB7FBC059E8F57F03191E203A2 +:10261000EDEFD8D7647269FB1B0B2FB1DE5B0EDFC9 +:1026200039888267456E8E723BB270FBEC8D43E950 +:10263000049A5FFC6B5637F2258B4328E754A27B44 +:102640006317AC5F24BAF85F80BC4954FCABE7CF9A +:10265000C5C4C3EC8E95BD67E171893EBEEC7810B0 +:10266000F1AAF011DC2830B80186DC86E2FEDF0D2D +:10267000E8F77D80366DF913637716E88DC5BA7873 +:10268000C12742F4FDD734F770B67ED93B1DF22244 +:1026900016918A8D2CAEDE86F8392DB5BD722FC805 +:1026A000F376264FCB7FF9DC2F404F2DFDD9637693 +:1026B000D0531F486DA9305EFD8E0D762FE82B2973 +:1026C0006087F73F088A51EFEB06DDFC1C9078AD80 +:1026D0009017B602590C042C3013F4E4DF76181D61 +:1026E00010476D78C61C32537CACD8C5F048CB2758 +:1026F00058F97EC457C36EAD1C2EFDE163A932EEBE +:10270000E703E91C7FE9A0AA576C3762FEE88A3725 +:10271000450F0CD3407A717DFAF7611E614AB78686 +:1027200076B1DA94D8BF9E7A3C2690B3865D8C4E03 +:102730000D3A3FB38EEB653DBFB7E9F89CE205E388 +:10274000614A3E2B0932FDDCFCA3C7F34ED0797DF4 +:10275000B4FD55BB3036C2EF04B22E291DCEB6D71C +:10276000CC873C83587CFE09978B3EBDCFED8CBC5B +:102770009B4E0C7CFF0E06EB8D21FB35141FF5DB09 +:102780008C9E007D5CFF9CE8B5829F74C48CDF77D3 +:1027900058F6DCCB6F5D4DE7B76CA73179065B86E9 +:1027A00015F4B342A706E0EF82085D96BEF0B209C9 +:1027B000F220E1F91A57843ECB76769A20AF528FF9 +:1027C000C7D2F64E13932F1D9DDA4F4C07BBDCFC8E +:1027D000A38B26E0830FF608045C48FDFB75DB5EE7 +:1027E000B683FE003C81FD50E8D547BF7E740BCD1B +:1027F000FCF5046CE780739A58F45B09732944FE76 +:10280000FEE9AFE9F875EF983DB0FEBA9FDE698743 +:1028100075FC556A647CFEBD0DA9608FEB8C8154FC +:102820000742F6BC6EEBD791FF16BFFEF554827AD5 +:10283000D33B04E497AE7308AC6FD15337E3FA6A25 +:10284000890FF9AFEE7B6205F88917245216CDCFB8 +:102850001F3284C9C95F9F36E3A6E0AF26C2BEC35C +:10286000F14791E5F19195E8877C9DAF956A622CDF +:102870005FB0303A7DCCED33E17AAC81B76AD87E77 +:102880003FEAB10F33BD6920EF140FDA78EAEBD3DA +:10289000D2B8FEC3EFA5E07B94EF4AE139B4EF3242 +:1028A0007AE3F234EFF1BC5636FE5D7C7C3AEF7889 +:1028B00088CBFD3555BB7F55E05787287130D24511 +:1028C000D4FC154BEEB76F42BE3AFF26D32B2B82BA +:1028D000B3CBB0BECB184A83FA60E71C01F502F512 +:1028E0002FA2C9F57623976B6D3D9DA724A8F1BB58 +:1028F00087DD8BAB7D94B653F92111BE31459E67C0 +:1029000047E453C9AF58ACF3CF14A8D70B4943B42D +:102910007A41799F3C9512F51E56441F0490AEF5FE +:10292000C6E00FBE0B727CC48CF70CEB9F33E2F752 +:1029300072CE3CBBF7ADDB29BF9F6957E457AB674D +:10294000F5F25BF7FCCD249AFC9E49AE2051E59749 +:102950003E8F2ABFC92C7FFF7F5ACF2E8EA167AF33 +:102960001DD2CF9F48BC86163FFCF1B261B8CFD2D2 +:10297000E155C1A75E6FBEE596A3EA4DFAF7265171 +:10298000E151C19FC2974B7FB21CC7E9E35F853F0E +:1029900015FEEDE34FFD7AB578D4D71BE0CE51613B +:1029A00084EEC675747F0DE7AE2F8A78EEDA23F7D2 +:1029B000DA5D1097E579373D0E5E76B2726F8A69FF +:1029C00023E80FE5796F1CCB43E8A9E8B53B557EBA +:1029D000FD890ED10E79F5DDC1E8F912984901F1B2 +:1029E0008C18F914CAFDD969A235CB0FFBB2367623 +:1029F000DEB3B0E9563BF8D33D1D39B32AC18F3F52 +:102A000020A24FD513CFF3AB025E6908C56B0D5BF7 +:102A100032394D02DF013FBBA663D90CD8342E6C8E +:102A2000D5E2A3D63A07CFB36A1F3546F88280BFF6 +:102A30001334819F55F794F6F952C8AB02FAE8F8BF +:102A4000C8077C14E51EC646858FF2493EDB27F396 +:102A5000F32AAED7A68963675542FEE27E764FE23F +:102A60006C874836C27A9FE5E7578114E4CF159406 +:102A70008FD571CE8F80CF46C7B6DF1FFDFC68D1E2 +:102A8000BDB449FD2FFE9CF724851FFDE2C8A8DFD9 +:102A900040F9976F67FD99F46F5FBAE7B33B308FEA +:102AA000728F99C0BEA867CFEFB2EE85F2AFCD1E90 +:102AB0009867CF3AB63F0EECB1A15DEFC964FE5FF7 +:102AC000F38B17F3BAD13EAD477AED1CC2EEA99E47 +:102AD000EDF8C73101F2E93AE8AAC0EEF27D57C33A +:102AE000AFE3707FDDF3E245CDBEF2DF5DCF0A7E5E +:102AF0005FA9C7462AE17E718F93DDEF6CF8CDA404 +:102B0000EFC37DC5E5BB3A4D35B4BEF4B7FFCC038A +:102B10007DD3F33CF327A87FBB155CEA8E275E6D5F +:102B20003552FA7D023EDF50BAEFFE6E4239DCC309 +:102B3000E88F1786871E8A075817C54B1DE8C958A6 +:102B4000F8786308BB3FF2DF878F4FEF80F1EB3BF4 +:102B5000261288A747F02278D9731BE65DD0F5B31B +:102B6000E77B2EE6817F74A9F57EFA7F6CBD8943F1 +:102B7000FFBBF9FDF12132CE4FCFF7FDF9FA977780 +:102B800063F9A7360FCE7790F27ED5D0FF5BF42E97 +:102B9000FF5F4BEF039CDE36079CA7F4BCF8CF2CFD +:102BA0007219EBAEFF5FBAEE3E3FC7E0B14CA0F347 +:102BB0007B87046F2E1162E7713E3154BB8F98C939 +:102BC000FD8899C9B5E83FCCF4B2F84A3329D80F4B +:102BD000F7D4025E11CF1D309986E2A16B4E7E10B4 +:102BE000F3B6A4C0C8EF401ED72DCB3DEC3B5FDA57 +:102BF000FDD5CCD4B232F0DF0E35D179D176876CE9 +:102C00000647335DC22CAF88FE1E85E8E7FD69CA22 +:102C10000D981732AB58BBCFB85DB76FB8B5525BE4 +:102C20007F0B793A05F2EF6EA93362BED0CDBAF6CA +:102C3000AB873A709DB792C60D2C3E7379783AC037 +:102C4000F1D41F0F03E3AD1F9EF87E127379E4FEEB +:102C50007833FBD8FED24C2BB8BFC5F3E4560D0A2F +:102C60009F84EF3BCD7C6805BF662FFB5EA7AA5F04 +:102C7000C48B82F7CBC5B742273DDE15FC2A78D33B +:102C8000D3E12938934889E03F02953C121F51E770 +:102C90005BCEECF31BAD88C7D7B6B3FB0AAF15D735 +:102CA000B4E643F95901FDB50B93C7130B5DEF2152 +:102CB00023D9CDEE7F79654751249F4528FE1D9E7F +:102CC0002B403EA17A5F0AF984EA75413EA1BA0C15 +:102CD000F984EAF6904FA8AE877C42753DE413AACA +:102CE000CB904FA86E0FF984EA32E413AADB433E7F +:102CF000A1BA0CF984EAF6904FA8AE877C42753DE4 +:102D0000E413AACB904FA86E0FF984EA7AC827542F +:102D1000D7433EA1BA0CF984EAF69047A8AE873CA7 +:102D200042753DE40DAACB902FA86E7F5DF8254D2E +:102D3000B984BCAA695F6A7943539EE6F8B3A6FDDD +:102D400057DDEF69EAAF97CF68EA15FADF907B4E5F +:102D5000F31CCE2C0245B08F617FE59E7F68FA910F +:102D60004805C6994DA411A105E2B714C69376840F +:102D7000562AE6004B47F972D2815FB706360273D6 +:102D80001D9A74310BF4FF6B936F62F1077E4E3026 +:102D90000BFE2953264EF83C03F6B5CAB9A73D2CC5 +:102DA00092D078CA876101A1239C404249940FC305 +:102DB00071085DE1247C9E1476224C0EA7E3F39407 +:102DC000F01084A9E11C8469E16C84EEF01884435E +:102DD000C257201C1A1E8FEFA587F3116684AFC15E +:102DE000E799E14908B3C2A5F87C58B804A11CBE14 +:102DF000016176F87A84C3C33761BB9CF06C84238D +:102E0000C273F1F9C8F06D0847856B108E0E572319 +:102E1000CC0D2F4378457809C22BC377E27B63C280 +:102E20002B118E0DDF8BCFC785BF81302FDC8CF04F +:102E3000AA7013424FF8016C971FDE84B020FC6D1E +:102E40007C3E3EFC30C209E127F17961F8098445F6 +:102E5000E1EF239C18DE86B038FC138493C23F4216 +:102E60007875F8057CEF9AF04E8493C3BFC1E7D71D +:102E7000867F85F02BE1BDF8FCBA7027426FF855CC +:102E80007C5E123E80704AF80D7C5E1A7E1DE1D495 +:102E9000F09FF1F9B4F01184D3C3EF21FC6AF80478 +:102EA000C2B2F01984D7873F40F8B5F0397CEF867D +:102EB000F0A7086784FF81CFCBC39F21ECDBEF4FE6 +:102EC0008E752FD167F802F6CF56D7A0BEF345C84E +:102ED00016CDB9D4E30976D493B3D6B03C928D2500 +:102EE000E7A6A25FBBD22CF3EF6BEAF4EAE756F059 +:102EF0001F3640CD10D607E401CEE3FCFB5AF1DECD +:102F000014F097361674D7433CE4C1ECEE2A84E9FA +:102F10002CBEBA9EC307D259BCF4F651CCCE56ADE6 +:102F20001C89E757247970EBF803D8E79448FBFA3B +:102F30004C5EB6F666E1BD8041F633D87697CA8F0F +:102F40005A95EE0BA6A35FA4BF9F37E8F79F413DBC +:102F5000F1E5DF6F1FE8FDE39C5EF68C8A5D384F7C +:102F6000C99B07F553D60D1193693FD5AD8203EC8C +:102F700064CDFAFCE940BF02E2C578E2BC18795D95 +:102F800047D2599EC682462381B8E20299603C77B7 +:102F9000C12E96E70B71D072CA17759C2F966FDA07 +:102FA000690217B4AE7131CB3F0AB2389385FE0780 +:102FB000FCBCB47536E61F2D7B461B7FAA87B88EF6 +:102FC00008E7C8DAE70D3CCEA48F57EAE34B7F4C05 +:102FD000E7F1250FCB3B226206AEF7025D2FE473CB +:102FE000F8EEB65940FF533CE03989B27E255EA920 +:102FF000E081F4BFCF8079A167F78FC43CB5B3B24D +:103000009C06ED7C549CBAAC90FFE09B08CF29FE57 +:10301000309FA4B72901F3914E507D2E43E293C314 +:103020003711BE9FD6FD4E26E1DF6FD49E1B585A46 +:1030300031FFBADA4807A6EDAA7724E1FD47DA5F47 +:10304000DE6E8847EE30623E5080AC7293E2FEE75F +:103050000A151B8CC81F0B763B597E58C0FB26E413 +:10306000EB2BF438B13E673AE4152D68C9CEC7B0F2 +:10307000DB6E23FA79CA79A942A7FE79D11589F0C6 +:103080007DC4A52DAF233D29BD34F5F5AD9FE2FDEF +:10309000014AAF5331E8756A207A5932B4F482B8E4 +:1030A000F2AD50B92609E5B46A5D6864A38A1FF5DC +:1030B000717A9261C5FB8E4A3E71D950460F2279D2 +:1030C0005281AEE75A0B915E7A3A95FDAB06E94123 +:1030D000DEB1E1F776E7E590F937D2E7F379DC7214 +:1030E0005EF3F5E83F676730BFFEB5B5906B49C842 +:1030F000EB6B2DC44B9DE737D63AB0FCA7B56E2CD1 +:10310000BFBD564678646D2EC2532696CFA3C81312 +:103110006500CCAB1B9DC1E4687486B2AFBACB0D21 +:1031200071E9B27FBD5108F93D2981E499D3AE45DB +:10313000BF5B93A75139479B87D16DE4795E9B04B0 +:103140000F7C476541C5359AF624777CA40CF6833D +:10315000E78D2C6871E2F7DB6E9B91A4697F4B4B86 +:10316000BAA67C5D868CF39B5D96A3797E7BD51891 +:103170004DB99AFF6E02B1C41BD4E753D4336279C0 +:10318000DE0ED6F67CE3C4B4D574FCF3078D58AFDD +:10319000A7C7295300F7E381A7CD1EB043A7E11EBF +:1031A000192D9FFE9388FAEEB491041C54759F1656 +:1031B000C87A804462F274E13093A7B27F8904F642 +:1031C000E1E4C7663CBFABD9229000DCA1EAA59838 +:1031D000A7E3DEF52333AE7BE11691F8F0BE92DC77 +:1031E0000EE7D677ED18ED8173CB7939A14CB8B7DE +:1031F000D7FBF338CFD3B4B6A69BBD7F9AEEAF9D75 +:1032000090972414E0F9C1C7E56DB506C837100FD3 +:10321000A6809C7EFCBC88F194252BFF54E400BD65 +:10322000F64AFB5BC5749C536D228E7BE619F33620 +:1032300011E5DD9B06DF758DAC3B8871867DEE8ADE +:10324000BA0CCAC71FD606F350EFAC61F1EDFEF819 +:10325000A1EB057A03BFAAF458C46EB17332AA7CFD +:1032600086807EA8317AF0DCF454AB11CFF3A8FE4F +:10327000C7F3FF536D4906A67F9E47BE5B20C92654 +:10328000F5B80B5A452FFB5D08D904F3250F8B3E8B +:103290003211CA2C5F21D022F8D8798D96BE77AE34 +:1032A0009C88F78BF5F9530AFC84CA944F750EB4C9 +:1032B000F445763E4B26744BEAFC7125BE42DCACED +:1032C0007FE53B3EF5C31FFFD6640ACF7AD92707B7 +:1032D0002F6CB7A17EFCC8F052D16A0ACF9407DEEA +:1032E00097285D1A45DFA380CF6586D6AD029E8BF9 +:1032F000BCF72D388FFFF039A307C590E76B2DFD84 +:10330000F1926103E507C10CD8F972285570C357D3 +:103310007909E66FCC25ED3C3E1064E75830098A08 +:103320001F473D3BC77AAFD0B619EEE1D6E8EEEDC8 +:10333000BEC7EF2DFC3043D0D8E7BFF0728D81C9F6 +:1033400027D9C3BEBF08792F2354F654D1A7BFC8CD +:10335000188EE3F6D955D28E7AA5967F1FB8FE193E +:1033600033BBA7231307C8E312461E7216E4998ED7 +:10337000B3D4F4DC77809D17932EB4731F1A83B5F2 +:103380005DD9F0FEB6F52E7CDFE80982FC723B6069 +:10339000A18A03F4C762C2E6B7BC4D088654710A1D +:1033A000E5F73808D80595BEE96F0FB4766011B718 +:1033B000778B882EDFA74D6B972A126CB8AEA56D60 +:1033C0003CEFB96F5E22F982E2ACD6177C6526CE5F +:1033D0005BF004A3CC6331E90DC17780973FCBEE5E +:1033E00003E9E7A55FC760E759EB993D15BE27DC08 +:1033F00037AE6EDE0ABE095C5052D141C17B6D8092 +:10340000E1B3B643407AFD85FB55CA3D3B85EE8B63 +:1034100049C54CD06B8B1FA5FBC2EC081FF4D9EB40 +:103420009D41F497CE9036BB95F27FFD969DB74CAB +:1034300082F79E7ADD04FC5DE50A8D3438E1276968 +:10344000EEF956596614FBAEB3E7FF29FC101E6770 +:10345000C2F7283E166D1731AF41D58E9FEF07108A +:103460004F7501827944756F8A9E66FAB40E7ECEDE +:10347000A7E0F2E7ABE0E77F7ADE7A3F263B7360B6 +:103480003F46AF5FFAF9313AFB09F726C05EF6A670 +:10349000B03CF0F39237D1857A59A777530AF0BB45 +:1034A000A38ADEADE5764F196711D83B5A7E7FCBF4 +:1034B0000B76883FFCE5D11752318F02ECCBD888D0 +:1034C0007DB9BB868D77F72FE3306FE9E3F2AE3C31 +:1034D000F0FBAABEF73BBBFABBA6756EDF75993051 +:1034E0005F6E0F978BDBB21C600FFDD1F32AFAEDF4 +:1034F000BF62ADD3768975DAB4EB5C00EB54DD07BF +:10350000A9E1EB3CD9C2D6F75E2B5BEFC27EEB0C98 +:10351000E039C8DDDF377B02E86784D08E9FDE2983 +:1035200012B87FD6E767E8ECFE05D2B615F0B17C9D +:10353000D5DBC724CA174B4651FC503EA87AD88C1D +:10354000767EC9CFD9F9E78742491A1EC0EF0BD959 +:10355000BF419F2FA5FE01F8179179F4D9FDC599B8 +:10356000852ABB3F48FCADE071A8151DBFC3DF8BAA +:1035700012BC2C1F7285F21D98DDBAEFC0C8A003E3 +:10358000D83D790BD02983C86C9FA88DA7FE6DE428 +:10359000A777AC42FEEF1DA5FE5E6F437CC808F91D +:1035A000BEBD3B05F48B96DF55622F2190DFCAE24A +:1035B00060EB3399FD12BC5ECC7B3153BAC6D3F1BC +:1035C000EECF94D973D9C1F2BA9F22F8DD1965BE46 +:1035D000FAE7101FB780FDB31AD0FEE9D7FF8B4C76 +:1035E000E62F2F170DE84FD79B985FDDC3BFFBF089 +:1035F00028AF7F3493F9D7DFE5F1811EF023E17C1A +:10360000FA5A33FE5E0F2153314E2E11C67F92823D +:103610003787F4499F7CA3BFDC9B0178BA83741978 +:10362000819E338B67CB706FE058AA05BFA344FF20 +:103630002AA09FB9BC9F4346764FE0188C41D735EE +:1036400097C7938FC16740E9F8C78698D08F0DBCA4 +:1036500068463FE1FE7816EF23C98912F0F9ED5C68 +:103660004FCD9B6CF6C2F9C0DCC9F75700A4FD052D +:1036700008C55795A577433E1DA7C9C0EC7C938B21 +:10368000E07D49B2BEBB10F07715758B214F9EAE21 +:103690007ED7174903F191F69E423DC415AE268CA4 +:1036A000C18A11BF9A72BD89D51FCC3C36F3D10CAB +:1036B000BABF866C26B0338023E08BEA44DCE7CEC9 +:1036C000823C7E174009F9ED4689040C0CB658F18E +:1036D0003B442CAF5F3907B9B9988412E9FA420725 +:1036E000B4F7286E0D1942A3E17C470A7502FE0C5F +:1036F00016D9E8A0E35494090580F7FA75839BEF87 +:10370000F1CC0F70BEF5F0BD2B98E73704CCE799EC +:103710004B851EF8F40E89EC130B18FD800F1B5C13 +:103720007200DBAD647CAEDCDF50E8924FBB57E348 +:10373000772E9F1FEDA7C50EEF9BA2C74DCE70F948 +:1037400050FCB4655C6E97297CF7AC565E6D5932BF +:10375000FB9E1AF883146F73398CC5F7F159ACFFCF +:10376000F82C165FFBDB658EB7DC4C42B8EE17CD4C +:10377000484765DC591C5AB258FEB2320F857F6B40 +:103780004923E6DFD4F2788C816A12CCD36DFB3EFC +:10379000E6F7EBF384A8838479674BB7EB9FABE242 +:1037A00039A2462F619C5330F52E84F9095F89F3C5 +:1037B00000BFCF35B5633C40DFCED826A09C1B5B55 +:1037C000A83F25F0F32D5A36B70AF8FB0E73337A6B +:1037D000C7E1F7CAB95F5DCBE94AB5F774B80754DA +:1037E0000BFE149E7FF1EF446D617EA4C4FDDF05E6 +:1037F000AD5A3F63EE7A959FC980E65EBD59971F2B +:103800006EE4FEC67153EF38D0F7FA7BF6C70D6C45 +:10381000FE815482F991CA3D7B89FB930A3F0DC911 +:10382000326ACEC594FB9C55A0A7D8F70E74F95404 +:1038300056FCEE4A95C0BF57C9E38A67A9BF89DF26 +:1038400095391A87764B8933F694D8028644F89CCA +:10385000252BCF4BBC7B26F89955769304F0A2A17B +:103860001BC7592D76D9B2B32371DC8D25E3B74040 +:10387000DED0ACADA3675932F19483DF471AFB1A4F +:10388000E4ADCFF99CCE1FCBE36679E9FEA8E7E56E +:10389000DE3B2C54452FCACA9B25517BDEF358EFE3 +:1038A0005628AFCE9A384BA276B0E7C1DE2CF88608 +:1038B000F0EAADD7B0FA26A5BF6B66417E70CF1394 +:1038C000AC3C87D607C0CFE5F780AAAE1650CFAE86 +:1038D000E6F647891F55195E62700AFB9D8F4BB54E +:1038E0000B6455AC063F47B49DC2DF13D82C7BB1A7 +:1038F0007C5F866F7E16ECA3660B0113DC8B7F3337 +:10390000388ADBAFA8BF7BB13A93C9E5BA61AC3F57 +:10391000055FB49FBAACC2CBEFC701FD146AFA5978 +:10392000F965E673B4FF7CEEF932F3F1CADAF928EF +:10393000FE99F29DB957B2BDDF81F92DFB26DB0F51 +:10394000935356CDFDFF738DBF1C0576FFDCB3E6A8 +:1039500024E0C3653FFD55562DF87FDC1F3AD3792F +:10396000C40479DF2BC2ECBB380D61F69D9C15BBFE +:103970003A4DD3C7421E6BA7A95435BFFAC8EF5CB6 +:103980004937AAFC9827B30C3CDEC67ED771D94FC5 +:103990003FC0EF092E33B4BF0F79BEE46A1647D398 +:1039A000AFB399BF770CCEFDA3C40BB66531BFE3AF +:1039B000628E3708EB5C9745B02CC6F86ED787BC93 +:1039C000BFAA78A6C76B8A6C1699E2BBF04D5F332D +:1039D000E49DD63E955D20D2790433A6FC386BC0B9 +:1039E000F8662F8B6F76B0F86695ABEB2E6AA4C89D +:1039F0005FB6CE7DC8722D21373C4EFAEEFB41DC1E +:103A0000B0CCACC8CFAA595327B3781994F767D56F +:103A10003F04F2B39FFF3EDBBC89E3E241CEBBB380 +:103A2000130C0E2AFF3BD3ABFF027C316FE2B5D300 +:103A3000E17989D936AA9AC5C7913F76A65784A05D +:103A40001EDA43DCC3670AA5DC4AD7E1FBBD8879EF +:103A5000D3BEBC045FB47B2A7BB8BDFA4B163B0FC8 +:103A6000DA6FA0F32C88CC43199F72FC5D5D10B710 +:103A70005A37241FFC687B46C9A9ACC2C8F8F60CAB +:103A8000DFEBEAF1E972F3E0F960E77188D3E31460 +:103A9000A75BC56411BE94D0A7D76F9C9AA029CF0D +:103AA000999144BCEAB8E99C744DB9B22A47D3FE57 +:103AB000F6856334F5E5E6AE098D97E1EF37D89EDC +:103AC000C1FCDEA31D17DE9A0B7EEC76D123D0F568 +:103AD0002C7971C75B907F7D167E82A480C5C5D886 +:103AE000F71AF9798CE49534E731075E3081DFAE5F +:103AF0008AF3EBEEE51DC438BEFE3C46C917FFB2A3 +:103B0000E731D230FDEF797EF40A5D1929DDDD89D8 +:103B1000F4693EC0F2989BA9DF02DF13FBEA2E7323 +:103B200010BEE1FEF1AF4E9864D5B94C43B8097FA1 +:103B300057B774F7093CB7D991C5F4F68A8E4F4D43 +:103B4000704FEAAB1D2B519EA753FD9548F9A6ABCC +:103B5000938CDB05F1E46C1BE6E12C6BB91EE3D41E +:103B600089E1B908EBDBAEC7FE96876FC2F20AFEA9 +:103B70007BBEFBE3BBA6831DDEFF0B27EE075F13B7 +:103B800043A39E847ECC36D40FE5E9F3D6819FB063 +:103B90003F3E30F64E3A5EF9CFBE8A79E82B760981 +:103BA00018372D17C97E01F2EFC371D85FB9F8C776 +:103BB000092BE9F31B4A995D2D071F87D68B45B664 +:103BC000CDF83DE918BF93E619C6F48AB19BCD7BC9 +:103BD0005A7836F6A7D4170D1BAEF99E9F3165BBF8 +:103BE000B4C01A598FB15B40F8B5F018840DBB66AC +:103BF0004B907FFEFBDCEF27039E687BFC3E587FEB +:103C00007D3C319144D15B0A34733D3C17F4309CC8 +:103C1000DB677B670C4B81DF23EC962CA047AD164E +:103C200007F82F338BF3E55AD5BAC4976EC37B10D0 +:103C3000E6E45E23D8EFB914AAF5F6FC1876E6C6DA +:103C400061CA3D9B26F6FBBB8A7E7FF7EBEC3BA867 +:103C50003C3EA0C8D375C30C9AEFE974094C2E0200 +:103C60003F67E702D3B37D0B61BE5D25A4F279D433 +:103C7000A35D59701FFD3F357F4A5F0BD0DF2E7566 +:103C80001388632C19A6D81D26CF979AFFAD7CBD4B +:103C9000AF89C40F7CF1DA75D77579E9BC3AEF1DAD +:103CA0003F1EEC8232DE3DC3589E2971F47E8EF9B0 +:103CB000867B126488EB97C399C784883F0FF98885 +:103CC000103F6CD8637E1A3E90DA60A7FB7B2BE432 +:103CD00005C685806F3B7F1B2781FD1833C277CFD8 +:103CE000B042783E7A2A7CC7C7DB619608FA41DE8B +:103CF0007B015FB1E67B29FDA5C8A39ECF7C2D4C3F +:103D0000FE7C5C0EAB39DF2EE072582D7912E13C5F +:103D100066FE4111EF452E58238CDB05F101D98653 +:103D2000F7F4153954E4CD087C391EF893F1657D1C +:103D3000D8C9E53B9BF7CBE4A05C64F976E5639CCE +:103D4000B87F5E114EC2768ABC2A72BA3EDBF76338 +:103D500058777933956F3A8E6FDD9009202F113E99 +:103D60003139809F289FB86B557CD0DCF999047C51 +:103D7000629C2C209F98292C55F151459F7FE298F9 +:103D80009E4AE731737D367E4F59A9FF591FBF0CFC +:103D90008EDF9FE2ED17584323C1AF3536C679E079 +:103DA0003BF2679365D463AB3609F8E384AB8C15BB +:103DB000A5E05FAC7A42C0F81EF81DA07F8A0E37DE +:103DC0009AD4E720B785F3F0BCFAA6F00884C10CBA +:103DD000DF8BC017D5E15B381EF3A29EF79D6FBC49 +:103DE0001FE36AE783660FFBCE98367E57E8F5E05F +:103DF000F99FF1A0916C9321EEE613F17C2F93389B +:103E0000BE2DB0F81DC4F394F89B724EA7C4E1CC4C +:103E1000F03D5C951DBD20B565C13EA45F3CAE8400 +:103E2000D9FD8FB61BD9BDADCE3F161968FD87D918 +:103E30005E8CCBED73FBDE86F52CBD31F853232D64 +:103E40002F7BF0053BC4CB157CB64BA191B05F6ACC +:103E5000A77884F8607BAB581664FE4EC26C557E22 +:103E6000452CBE5E1ACE41FC28F646D1DFBF5CEB86 +:103E7000C64DA9A2C72F658714FE5ECEE56039C87E +:103E80000151DB9BD915F0BB662457C07BAE117B7B +:103E9000C3E441D1D394DF516ECA733231AEAEE880 +:103EA0006DBD3DDA2BB67FFB6A3847937D7132C515 +:103EB000CF949FFCE385776855FDF33F9A0A742AF7 +:103EC00019231038C7BC949EFC7FD95BF3F900809E +:103ED000000000001F8B080000000000000BB55B15 +:103EE0000B7854D5B5DE67CE9C9949322FF28020ED +:103EF000249C993C0825E0F08884879F0702018470 +:103F0000E0046F1135CA2422CF840494CF28F4CE64 +:103F100009090894DAA0D6528B7642C1528B6D788B +:103F200058D38A303CA441AD1DAF7DD02A7450CA0D +:103F30004B9088F582B754EE5A6B9F939933495052 +:103F4000DBAFE3E7B7B3CE5E7BEFB5D7FAD7DA6B7B +:103F5000ED73100F7E2EC94318B3AE2C678A9DB146 +:103F60007BA12D81F63AFE6E634C624C69059AB1D5 +:103F7000A879A623F6DC299B18CBC0E70D8C153158 +:103F80003643E77B7F3963B73076BF9BF15F3D30C7 +:103F9000F565ECDA0013F14DB1B239FE42786E8E60 +:103FA00064C7CF57EA9920CBC09A270B34EF8C9582 +:103FB00051B32D1DF8EC36F7360FD0C5C3E4798523 +:103FC000317EF12BCA5D26329B900AF29AA32CB562 +:103FD00010E7D7E556F93A5F22779AC6FF3B91D5AD +:103FE000B7C2F8DFDD765B4401B90EAC18314294FC +:103FF00063EB15CB16DA5F591A8C1DC958C76BD6FF +:10400000D016909BC17C02F05F7A6D50683D6CEDDC +:1040100004EBB8C68056F7A6C8B8AFDA7D29C45FEE +:104020009BEC0A09D05FEBECC8F7833C25FB93C2FD +:104030006C28ACB33FC9CC60DD2B390F14CB45F8ED +:104040007CE044C10942EFB59A19F0A9D9CA68D4F5 +:104050005B4FF2EBF225B6FAFE4BCB05D5E5626C71 +:104060005A89433541BBE86A0E6323185BBC762A44 +:10407000B5AF043341C98C4DBA5A0ECA60ACE6EAFA +:104080009DF47CC9D514A2A77D3B528AFB61AF0881 +:104090006C1BC85FD6EFBE550CE46B4F6643F6C091 +:1040A000BEDABD59BE46E8AE6E9E4AFC65BF983C7E +:1040B00005F7B5640F30E3B8022194877A3A653783 +:1040C000B1DE8C3D64E3E27F5AF7A791328CFF7436 +:1040D000A4631803D64362EB536304B2673BDA73FD +:1040E000C2CFFEB1FB2FC0275D159902F258AF0A6F +:1040F000D446E4C022D407F031067CD5BBFA8E0C3E +:10410000D8BF0A9E7E25C98047A9FA1309F16485A4 +:10411000B624AE7F8E8693443DD6CA1CD75FD50F9A +:10412000EEFB8A785A8578CAF88FE26915EAA91BEE +:104130003C3522CEFE553CDDC08E3EE689E16CDA90 +:104140009B1C1F2CC7E1DBC6082F2477BB252BD473 +:10415000087CF7A25D115FD7591DEA730EDA372D7F +:1041600086D7973C819FC4DBB93D592D5C5AF855E1 +:10417000EC7C37C3B8716F7A1D53E0F91C68E3E338 +:104180008615ED57D8757F3BBEA69D9FD5F8BFCC51 +:10419000CEAF6976666EB0E348B29F8C764DB43B85 +:1041A000DA15ED5EBBCFBAE546761D9C1B68EF2E97 +:1041B0004E3077B209E58CD9C57A27E2E6D3B099BB +:1041C000A17FF564576913D7BB4EAF0E9BA784E858 +:1041D0003C6069E543082F47FF9DF85356D2FA77B4 +:1041E0005B2FC6CEC8757E33F0CF2A86AE9BB07FDC +:1041F00069B362C6F8027F8EA1191566237D6AF441 +:10420000B2C844D8EFB4A73AFB55EC9F34CEA58D85 +:10421000670A6CAB93FFB45C1BD9407237733B06E3 +:10422000A266FF90387A24D08E38BA3881DECCF975 +:10423000F11C71D33C211EEF617E6138D2FA7C9A69 +:104240001FB08ED25E60BF197B04F77AB0F73DE3F2 +:104250002E59D03E6525D123FD60BFFF273FEAB729 +:1042600027C1738C83206FB2A7A159356BE3C17F3F +:10427000AA35355A5B0545043B55170B21AFA7AB53 +:104280001E933DC6F30C7F66E3786619F9F5C6A365 +:104290001D69BC97C687AD5F63FDBBC63125D44D94 +:1042A0009CCCD4F9AE01ADCF0FBABB13F617EAC65A +:1042B000DF640FF79F88C954C3405F059EEF35DB6D +:1042C0006E05FB328E8F6F789EF6AB855C5C256148 +:1042D000BF3792D7E9D1FD38B65FD9383E7C237D10 +:1042E000A577D197868F0546BCB8CCFEC39F821CAC +:1042F000AE74C1AD82FD97F893363017DA5FC7F719 +:104300008FFC4A7FD85F12EBC4AB11DF21FF44D092 +:10431000E312A6F76F69C673C96FEAE4E778DF2B8B +:10432000748E2F00FCB8181F3FD1D3D2ACDAC91E4F +:10433000D44F74EE0DF0DE9A408F4BF00F0DDFE49A +:104340009F18B7413F79DDC48D4A4DBF1705361B15 +:10435000E35E6402CFF7225EDE3678787EB750D314 +:10436000E352AD8D24C7E9A17FCCCEF00BB302C3DD +:10437000BE494F77A76BFB56C3FEE9B0AF482A1B77 +:1043800022004E56B4EC6D6ECA8A8DFF564BD88F04 +:104390007AE89C4FDD17C1B87FB7A6A78696FD11B6 +:1043A00095C73301FDAE86000138D823A822ECB3AF +:1043B0000671D0CD3EA775F51B3561BC22DD607C52 +:1043C00079571C2A09E39994FE75C66B769A9E600C +:1043D000C72909769C984057E874C810CFF438571D +:1043E000D5B671756F9063F176018F098CD7166120 +:1043F0001863CF78DEF0DB47235E65A91FC4FC6736 +:104400003D6F456C80E5728C6784DFDF362B6097EB +:104410003BD1DF897EDBAFB8103F75AB33813FE422 +:10442000F95DB30D58EF69DA28614EB3D5F34EB399 +:1044300019EC77F7C85F1CC1F9CCC2BB91E9C20D7A +:10444000F0DA9CB08FCD09B49AC0FFF497C4F7A6F8 +:1044500084F12B13FA3724D09B12E8B5C6F195737B +:1044600005F2934AB01F2AEECBFCE6D79ECE7CA184 +:10447000F33C13EC942719703FAD91D3873D27FD92 +:104480006B0BE3E8960FF47848389618FFDD9BCE67 +:10449000543C3FA41EE2D9AE9EE25941E279C7FBEB +:1044A000FF8A7FF6C5BC9319CEE543A2913E20EA70 +:1044B000FED61179D88E0F75FA921FF3F169DF37A6 +:1044C000EE0BEA42ADFFA27F22F8FFB4EFEAFD1740 +:1044D000FD4ADC3E75FED27F5E1771BDBFB45CF055 +:1044E0006F85F92A2684F3EAB04DE52D9C33229E90 +:1044F00063B536EE4FA5AF897E3C672A92C379CB70 +:104500000AE3F6C95AF3719F075688641FB591D71D +:104510002355CC6761500A1D70B9EA5F00FE432B3A +:10452000C47A3CD74ED4A7F546F9077B79BD77C846 +:1045300035A0F783401F4899639181EFC0E393A8AA +:104540003D282A6B3A00C7573DD7FCF641D8EF22E9 +:10455000FDFCBDE58ABF01E2F4158F4CE303A9EE33 +:10456000DE6D98AFAE97D83619E5F13D4FB8F98EAC +:1045700075D87A90A3B261706FCCDFAABE575EDAAD +:1045800017F8AA564B3E81F8D850943BB07E92055E +:10459000FBE73669AD3A99DAFD5FEC7E7328F07778 +:1045A000AC137D5B8079DF55AFB30AE4FA3089C77D +:1045B000E10F2EE43A51CEEF7A03A217EC5AE974D8 +:1045C000240B7878B865E74C9877438E62F616C569 +:1045D000F8F77F21CEC17CF3D50B55BD03403BBD21 +:1045E0001CAFFBAE56F5AE8A3BEFE75D34939EF70A +:1045F0005BE48731BFDC9F9C25A8E4C7AD69E5E09B +:104600002F73B5FC1AF052BFBB9B73FF1F1E917036 +:1046100076CA5ACF3E04101FF876C63894531F57F7 +:10462000F4FB40A303F1DC5F1E1E9F47BBB227DCF7 +:1046300084FB88E12CF51D3C2F298F063ACFEBDA5D +:10464000A802AED821C8FF518E74A514FBD94A60C8 +:104650008038C6325BF3E3EF236279EA2A2D1E70BD +:10466000BEE3AA83EAD6E33B924258CF1C57DF73DE +:10467000307B3C3FF793F94E878A87F11987C38CCB +:104680007A3D610E9E7E14C6CD7B4EA2383AEFB9BC +:104690008C951D180FC09E79ACEBBAFFED9568DDC7 +:1046A0001EFD84C9E513C7C5F9893AA01CF7D39349 +:1046B0009FDCE61D50BEB5B0673F99AFE5EDA5CFD5 +:1046C000497EC4F9FC228799DD0C75F673AF6F4300 +:1046D0003CCE5F9A34DC0A82CF7FCE4AF68D3A1CFC +:1046E000AA1BFA034E87B917B4FFA5E121DA90445B +:1046F000758AD8DB42714F5C5324A37E4A4466B668 +:10470000C1B9223A7DB29FD34D6EA8DB563B8A6574 +:10471000B4EF0AAF4C7AEBEC77CDBE5D80BAE632EF +:10472000EC230DC69DAB7FEA995120DF79169A35AF +:104730000AF47E190D0DEB5CDE238654AC8BCD8A1A +:10474000B90CE2DE02C6FDBDE6E86ECB78F8734137 +:10475000DDFCE9581F2D0C491F44B5DAE73AFCFF90 +:10476000197BCB82F9EDE2EDC6E7E03116F4AB9AA6 +:1047700056E3F35AB6E1137128B6E60FA205DA73D1 +:1047800058B7FEFD3F0F391CC757ED75A49F1E0C8F +:104790007F0C67C341B3B04EA1EB2E845DBD48F2E0 +:1047A0008AAB9242A847319B9F0F9399104A42408F +:1047B000B861DFB0EE95E0B121870110E2632348D4 +:1047C0002FA78280A781A00FA78DF8C5C7C4901519 +:1047D000D62D49634A2FD4E733E58C39489FAA1B6D +:1047E000E8C9E975668C4FE7B4F85229307F2BF998 +:1047F000BD2F1BEBE379CF2591FDE63FBFF08F3F47 +:104800001889F62A4B8FF7A3C735DCC17CCC961AE2 +:104810009BE74CC3B7B2519E921F415D89F5A61824 +:1048200078E66E8A97293E8A5BEEE87746214E1A33 +:104830005286AD678893BED9DEC2D8F8F9AB56E48C +:10484000F3F150AF3A315E25D17EAAF7580927958A +:10485000EB4485CEC72C0B9D8F1F3425115DDDBF2A +:1048600098FCACD2C402B80FC8053329AE7395B317 +:104870006A3B5376DB31CE6F88884EB28FAAD9CD92 +:1048800082F6D9E24DA3F5E7A08EE1DC3AE8D5F453 +:1048900062E2F861FB84D0368A4F7532FA7F85492F +:1048A000A03897E88FBB3109C371D9BEFB715CCDCD +:1048B0001356DF2A0F9741D4E5013CD59822F37EA9 +:1048C00088F3FED24AF71AB5B08F2427D517CA2E1F +:1048D00090BFD6CCCC16BC9792793CD3E5A995CBAA +:1048E00027234EA1FF9819FA6B1C3C1ED7F4E2F760 +:1048F0003DCC610B6D8B5F0F65CEE1E36427FAD988 +:1049000068C20BFABD09FA2F31DE5FE22C96A3F0E4 +:10491000BCDDC4D6E23D09CA336868DCBA40F71D85 +:104920008A785C6AF63AD00E69B366E37A2F891406 +:1049300097C0999E28C6FCEF257104D6B195EB0E61 +:10494000956E427AE730378A50F9F377E97C5AACB2 +:10495000E12C8A793F9E5740EF84F63D2FCF2F02FE +:1049600022BFC779CFCBF37F5DAF7A7FCD3A89EC99 +:1049700051B39AE3A1A6E14F346F8D23D21BED51C1 +:10498000F3B2740BE2FA941627AA1AB2C61D037C7E +:1049900054492EB7008FAAD5320BD2D5CD02D1FA09 +:1049A0007A35EBFED0DB54C8E7C3D6AAE128366FD0 +:1049B00046369E671FED48CBAE8CB3FB474DAF38F4 +:1049C000653BFA4D38CF8DF7304B937C5BC84FB9C0 +:1049D0003D3E6ACADB82F73473DD118700FD731F29 +:1049E000CE49C573EE843B6CC1FE13AD1E13D28A53 +:1049F000DB3D0E69C57C33D11F41086FD5EA56C433 +:104A0000F11281E3A67AC7218B17D64BCAE138BBD6 +:104A1000F8D2BBF9785F50931DC9C7F3177095DFC3 +:104A20000FEDF2A24079C2921DA292343486AB25DA +:104A3000882BF0FF451AAE96EC79E511F4D3258862 +:104A4000A7E15D710975E5617ABEABA594F1F187C7 +:104A50001177FA790F749384F76A168D8675904EE4 +:104A6000CEE1B881FE89BC5F2DA47384452D980FDB +:104A7000D78A3C4F007FCAC43CA2B64D523BE325C7 +:104A8000AE8BFD85B1FE9E703338879F27550D563E +:104A90003A8F066B7A89AE7BD989B8B8F8D2A12350 +:104AA00063B0BEDA25B831DE77F1434D6FB5A82784 +:104AB00027ED93F2A25AD48B33A6A74E7FD3705121 +:104AC000CBB81E74BDD49A353DE9FDDAF8C21C8E10 +:104AD000C36AA6E975CF40EEEF9A7FEBE788BEBFC9 +:104AE000402A1FAFE3EBBE1C8EFB31DA3EAB013731 +:104AF000BE42C29762B945ABFBA1EBE2CE16BA3714 +:104B0000D2EDA9CBBD5C5B1FE2B4D22B3566E7A822 +:104B1000892DE8EE9EDAAFE94FB2F3B872B2A1DFA9 +:104B2000FDF5A0BF453B441F290F6BAEB875ADA680 +:104B3000A883F2D2C74437EEABE467E5B7E3BE75AE +:104B4000DC49DB0573DB48AC337A91FE75F94AFA30 +:104B5000F86FEFC57117467974394F0A61B297BA89 +:104B60005370F33C376AC1FB43DD4F13E5BD2F475C +:104B7000D0F201618C7033CAE393D1BF199C8324B6 +:104B80008FFDD80A5A4F3DBEC23334B6CE09D56127 +:104B900046BE138CC7011D9727B5FB8893AB5FA159 +:104BA0003C585FE7A1AEEB04EAD3BBAEA3F32FD62C +:104BB000F875BF684FE5F82F69FA13F1E971167FB0 +:104BC000780FA7EB53D75B9C5F1AF4A3FB97EE4FCC +:104BD000BA5DFF55BF622B33285F7D5CDB37F94838 +:104BE000EFD8B980F8C4F3CE6A015CDA0DE726E5A8 +:104BF0003593FB7F620974F35CD753E2F3583DE5CC +:104C0000CE46FD4FB6679A300F604D998773E3F239 +:104C1000B20FF1BE0BE36906E3EF33187865DC7978 +:104C2000AEE76BFA790DBF0D9DB884F1B5E9CA39CD +:104C3000EC5F3072693EE6119772BCB4EE79D66AC9 +:104C4000190FF3559F8D943AE558BD72EBDFC3A25F +:104C50000BEF03F7780CF542F585C3E4DF352CB292 +:104C600006EBDBCA75EF968D42BBFF14F271E09B39 +:104C7000DBECA173EFDCD6074660295BB93A8FE81D +:104C800085DB1EE4F43A9ECF55AE2E7A01EFE33F6A +:104C90004C524A11DF1D1B0537D65B63B715ADBCFF +:104CA00007FAC73A06F442B98F6FFDB06C0CD60D07 +:104CB000F522F98BB2F5A959D8AFB4893EDCEA5C8C +:104CC000E65E790FE2DBEC227F3BA19D138D12C7DC +:104CD000D91B5A9C38A8C58D831A0E4B1A1BF34D4D +:104CE000B86E0B9C4FB0FF0A8BDC1AC6BAEFB53E0C +:104CF000BE2DA82F285333014767059E7F2FB03064 +:104D00001BE2EAA814598EF21F5DEE18D6800288C5 +:104D1000D76E41BF50B43A0BEA265A57D797BEFE1A +:104D2000512D8EE8F3E8E3DA319FC2F34393F75C49 +:104D3000D34F67619E706E7B5E2A8BD3FB39DC1785 +:104D4000E87B21C4C55DDDD47F7FCCD1EF23427CDD +:104D50001DEDDEF0A8D4DC1FDFDF421E7F2A3E2FD0 +:104D60003FD39264433C421E6F7C2EF1F304F278F1 +:104D7000C373F09B53C67C5FABEFC40A57A09B384C +:104D8000A4B78979FEB91C7BFAE914D625CFD7FDE3 +:104D90002E71BC9ED777DEB3BC6F4F781F33CAC568 +:104DA0006EB0FE852018066ABF16F45D907762CA61 +:104DB0003F7747B09E6CB6BAADA0DF53E857F81EF8 +:104DC000F06591E78936E60B032E4EFD61840FFDF9 +:104DD00070DEFBDCEFE6B50A217CC57E78E3E322DA +:104DE000F23FB859607D84B83AEBE98DB3D0ED2E2F +:104DF000FB026BFA02FFE5ED824F2509157B427D30 +:104E000075A4AFDC737DF5EFD655FA3D53A2DE33C2 +:104E100073B5FACAC77C46BDF3FA7C3FC0A7787861 +:104E200057BD5F0806A88EFA38B880DAD1AD2D25B7 +:104E3000FD40FE4BC2C927C6A2FF385C744F7221E9 +:104E400058472F013F6E1B716D06E8E755BBCB8DB0 +:104E500071E3E3603D3DEFC48B86CF5BF71C10FB35 +:104E600031E2DF3B16F8F7D95DF85AA39BF76DDC0A +:104E7000BE9041F1F7A35ABDFDD0D2517DF0B9BE2D +:104E8000DFF38F723BEBF29FDFFE8013F3D3033F20 +:104E90004CDB3B1AED9BE272238CE66F12596004E7 +:104EA00063A737F13874D6E67A613AE8EDECE63B71 +:104EB0007B633DF8A0D461F1C1BCBED7CA9D787FA9 +:104EC000F63773D4E9C616F8C32887392462FC1B69 +:104ED0003385D17BC0316133933DF48A9E7032FAC1 +:104EE00082391406FA237C3F88E7F6B564FE9E5E9D +:104EF0007BEFF7E0AFF87D5AE7FD89768F3056DB20 +:104F0000EFC3B9A95C4FDAF39262FEFCCCE6DD3365 +:104F100070BE735B2537CAFBF15689E65F0475BC2A +:104F200009707816F086F16BD1EF451F42FADC76F6 +:104F30005E272F02DCE27D71CD5249B1B8BAE2B1F1 +:104F400044E7DB2B507DADE37291122A25BD6BF84F +:104F5000B4C17FD7E1C8E8C55AD7A03E1271FAAFF5 +:104F6000D6FD8B1197DDC583041CE8FAD2F110C37E +:104F700027235CEA764F6D1D36BE1F0D50295EA8B3 +:104F8000135801E6058D165660461C98927DE8E799 +:104F9000F536E750BC67BA92C4DB474CEED7B15E3A +:104FA000BE62922501DA13B91EB2C323A26F12D2D8 +:104FB000527A94EE07C4129362C2F3AED14AF12240 +:104FC00031DE3C9ECBE3703F041BB43FCE75532BC8 +:104FD000B13ACA1FF416369885F949794AEA673218 +:104FE000B03CBD75CA4C33ECAF7C6CEAF21CC82CEB +:104FF000376F9D3113DFEB968F487DD90BF4F3B9F2 +:10500000659CBE39B54802BAA1E18E991381FFD5DE +:105010005CE5C9DCA2D83AFABCF0FC7BB940BFDE43 +:1050200027B009DB5A8B7D2DC6FB4B42C712931864 +:10503000E37F4760275E1562745462D9984FFF186A +:10504000DF7915F5DC9EC9555A72BB795EC5D86A01 +:10505000D46395FA9B6398AFC1CF6F03BCDDA1E128 +:10506000ADCA660F232ED85AE942272EBC18975C8A +:1050700066F4EF199AB9EF30870FE0F841ACC97DBB +:10508000DA46A9E0E6EB693DC779704C765A9F0F86 +:10509000F6774982FD825D05056C0D2E2580922BE9 +:1050A00020BE097B7FF339CEDBA8B26812D9A1C23A +:1050B0008D71516001D375686B52000FA0A7652FE9 +:1050C0005F3C8CF05FA8E75399FCFB8CE51A1EEF60 +:1050D0008828DF6F01A1CE04597A2ED8FA223BF836 +:1050E000B119D63D670AFC06F55D6D7A2B7B998C6C +:1050F0007EDBE8C4FCE5E2CF45DF741857ADE5ED93 +:10510000EC9A18BE0D9EB77B066D591F87A3482EDB +:10511000CF172E78C2D92B307E7878DDC9AE1DCA64 +:105120005E01FC53BC538BF05C7A9A29FF931BF70A +:105130007E7186B9FBEF2FDEBC89E73B6C2B3F5FAE +:10514000AD66A63A52A9654ED0C75490A518680915 +:105150006891DEC787687DE473629E223F90C9DF55 +:10516000D7303FFAA36E47DD3E5DEC0622637E6ECC +:10517000B23109FD6510DBEC46FFD6ED3749B4537B +:10518000BC59F632BF8F5B26449BD2907E09CE4B32 +:10519000D497E6975DCFCD6D1634C582CD0F507C88 +:1051A000D2E3920CFF217EFE53F792D7F57373186A +:1051B0001B86B8FAB27C478F4B601F4B5EC6D7B0D8 +:1051C0000FAA08F63B5F5B7B9258219B512F193643 +:1051D0001FC6E565CFE5D079C79A9E64F17C6C73F4 +:1051E0001AE1738D47243B96B5F563323C5AD826B5 +:1051F0003019CEB9E96D69443BAFF625BAEC277D8D +:105200002660FEDFF9DEF22703893EF7C29B230307 +:10521000FC7EC586F3FB992E47612BE64397ED2074 +:1052200007D8C16F5F4BF7857ED659C708D705A44D +:105230000125E84F8AA472BBD81AC8AFB57D2D737B +:10524000733B2E3BCACFDD65E3F9FB3DB33AC8851E +:105250007890DA451602FA9B47C5A230B0366A71DB +:10526000D99A6962729C3D92E46426C7D56F4C5509 +:10527000225827CDD6709252906AE87F5C08482861 +:10528000D76CFB3CC28DC3779361BE4876693BE91E +:1052900023C0F35B1D4F4CBC6046393F1B27B03425 +:1052A000C0C53767437FDCBCD2B84F260AD41AF397 +:1052B00062D0CBA91BE1696A9E86A7416C10E129E7 +:1052C000413FE01F947F5E86731CD326C82EBE3FED +:1052D0000EE859ED120BC9946F92FF5C5652E8FE2E +:1052E0007EB5A6271D77FE81CCA1C0BCAE62A3DE31 +:1052F0007A2946BDA54D31EA29C36FD44B9FD95EAB +:10530000437FDFC0370CFDFD160C37D05975630C99 +:10531000FC03EA2718688F7ABB813F67ED4C039D39 +:10532000D77C8F817FE0A62A43FFA0D02243FFE0F5 +:10533000EDCB0CF490D6C70CFC37B7AD32F40F0BA5 +:10534000AF37F48F687FD24017459E35F08F3AB65D +:10535000C5D03F3AFAA2A17FECD95D06FAD68E5F9E +:105360001BF86FBB7AD0408F676F1AF84B6CEF1A3F +:10537000E849EEF70CFC93333F34F44F953F32F499 +:105380004F2BF8D44097F9FE61E07FF6A6C0268C3B +:105390003FB34D1B8EAB0CE3B3FCDD7180E7BBD29A +:1053A000CDBE30327DCDBA2D94A7E5691A6E3F632C +:1053B000F6FB4DDE2F8F83AB312FC8405C4F6778F3 +:1053C000DF7BB955205CF7743EBB20DF35C7EDA30A +:1053D000976283023C46A74D711BE80C7FA681BFF4 +:1053E000CF6CD9D0DF375060E8EFB7C067A0B3EA21 +:1053F0008A0DFC03EA1503ED51A718F873D6FA0DD0 +:10540000745EF36C03FFC04D0143FFA0D00243FF65 +:10541000E0ED75067A486BBD81FFE636D5D03F2CAE +:10542000BCD6D03FA2BDD94017453619F8471D0B51 +:1054300019FA4747B71BFAC79E6D35D0B776B4192E +:10544000F86FBB1A36D0E3D951037F89ED1D033DB8 +:10545000C9FD6703FFE4CC9386FEA9F239437FF5CB +:1054600047003FCC9F5F15E8FDD7B4824F0CFD523B +:105470003AE4E9783FCD927DA2D0354FD7F3B732E9 +:10548000DFE786751E31D5D17771574C3CAFB3E459 +:105490007B097790BFDB6C1467E1841A42572D0DAE +:1054A000989FBA54817087A94605DD17A6D37B055E +:1054B0003A1A65FC0E0DF21B20524D1E0FD60F2915 +:1054C000B13CB4FFF5115F3D0F4DCF67FCBE293FE6 +:1054D00090949F81F5D8CE52AC4F1632750DCA010B +:1054E000E7AB0BDF33BD9D64BC37D2DBA936D05FA1 +:1054F000DC7A47939AFB0FBF81DF4EB55D20FECE6D +:1055000079B57B2501F6B72C6EFE27A06E324309D4 +:10551000D91C04FF023F7D32E826FAE96026D1CF8C +:1055200004656A37050BA87D36E8A3FECDC162A2EB +:105530009F0F2A44878253A8DD12F4D3F3ADC1D95B +:1055400044BF100C50BB3DB880DA178375D4BF231D +:10555000584FF4CF832AB5ADC1B5F47C57B099E864 +:105560003DC14D44FF3218A2B62DB89DDA5F075BEE +:10557000A97F6FB08DE87DC130D1E1603BD1078359 +:1055800011A20F078F117D2418A5B63D7896DA3742 +:10559000821DD4FF56F02AD117B4FBFEF1F9FC5E50 +:1055A0004ED78B4E333691F0A0E7B533B06E4170D5 +:1055B000144B1F1BEA9684FA21D11EE7B575A40986 +:1055C000706C639E7353FE96C6B87CBF4C5BEFF164 +:1055D00064A62641FC6BC0621EA0D890CA428DF41E +:1055E0007E95E7DDF3355CB2749E6FCFD3E49AAF5E +:1055F000F94311E2B380F0F9D6D7A993F43AF95BF5 +:10560000FD03F7113EB34C2ADD13D843F998F78711 +:10561000FA0702F920DFE5BA078FD07A6E5F3E2ED7 +:1056200052660D67DC85F73F4745BA2FED69BD5AD5 +:10563000EDDF2FF4D8BFEF5C7F3C87A67C21D27DC5 +:10564000FADB926336DE8F2CD3F4B22CDF6468076A +:1056500066F997A29C67F2EA5E7808582A96E6B93E +:10566000306FBD034B6BF0FB72264BF47D2C535E09 +:10567000C74F26BF09891DD2773195DA9DFD028F6C +:10568000E17EEE860202E9C0186B7677FB4994A7AB +:105690004993A74993436F2766F91B71BE53798AD3 +:1056A000419E47B364ED7BF78EE751AEFF7DED93EE +:1056B000D3424E4CDFFABDC49AF1DAF7534B05FDE5 +:1056C0003D35CF076D4CCF07A9BF6239BF9FB90FDA +:1056D000EA327C5FF9BE160F2FD749142F2B846452 +:1056E0001FE6D397EB960FC4FD24C6CD0A18678238 +:1056F00071158C7F0F51F17E0AE10BE663F8DEAD88 +:10570000023277ACFFAAB3F47B8FA83D83CBA3E032 +:105710007BD8397BAD2D58A7024EB6104E468BAACA +:1057200005EAE4B74DA17C41247C580490777E3A89 +:10573000E0A39BBC40C7C112EDDFC7E8CF015F3BD0 +:10574000507F1FFF6A5401BD37D9375A46FD359A3D +:10575000C01E785FF386C8BF93C02B76FC8EC355FE +:10576000D842DFF9631281F61AEDA0F721074456FB +:10577000BFB39BF8F9DB7C5E5FBD9D294D09D1BCB1 +:10578000C6F77C47343B1ED1EC5B76F068D62330FD +:10579000EF927689EA1D36325AE8EFE6FBA6DAFA8E +:1057A00037FBE6C6EDA3B6ED24FF2E8A450BE3BF1B +:1057B00087FA9BB6BE8E27D1E208B4D8E3E5E3F7BB +:1057C0004580EBB7345C9FC6BC7E865576DD0543CD +:1057D000A3A09A30B4811FB9E9BB3AFDFBBAB9CC9A +:1057E0004FED7C8003E2D8AF6EA4FA77116BA5E78A +:1057F0004B8A1FC846BA96754CCCC4FA656DC3EB8C +:105800009920DD9DCD1B27E1FDF3CC50E5EBD8962B +:105810006F154E63DD0D7E711CD78F0A75ABB124F9 +:10582000BD67C7F8D578CF3B43E476606F723B0025 +:105830008E1431B5EBFEC00F4EE178F003925FF7A6 +:10584000838A551C3FFABFC7E8F48BE2C57FED871A +:10585000EF3ECC1DF45D48ED3E6B2AE26B11569E87 +:10586000627C5EA89FCF3C2F580C7901F29D97B8BF +:10587000FDCF1F4FA27FF7725E007C0CEF8A7B3D4D +:10588000CFBC62E2F76E8F88B04511EBE5A7484FB9 +:105890000B6CA1A1A827389FBF401C2EFAB075CD74 +:1058A00030BCEF9B10CAC67C557AD1EA6BF418E283 +:1058B0003CBB9E12BBC77B42E2F76A89F276C95BAA +:1058C0008A8F7C8EF984D5C2547C9F04FECFFDFE66 +:1058D0000497FF8A2990798BC8F315AAA3FBFBA92B +:1058E000FE67BD6DBEF542D7F59BB475DBFFC9EB16 +:1058F00069358BD1F7388972086EBE6EA23CD664CA +:105900002E877EEE749587DB4197277FA087DF5334 +:10591000642BB4EF06532F8A5F97C440DE403C2FC0 +:10592000B5FB31BD8E6DF79CA1B8CEAE35F6E7DF85 +:10593000F7867B3A4F2F74D6CFDED879A7DF33B105 +:1059400071DDDF0BFA6D6E09ED3693F928EE0F620B +:10595000EFEBFAA17BA6FF0732EFAAC6A039000041 +:1059600000000000000000001F8B08000000000085 +:10597000000B7BC8CEC0F0A31E82C539106C6271CB +:105980002D0B03C37B56D2F5C17005507F3110E754 +:1059900001712610A700713C104701712810BF0249 +:1059A0009AFD14881F00F16D20BE06C41781F80C03 +:1059B000101F47B277291B03C31A36D2EDFF8DE4BF +:1059C000E70940761910CF20231C46F1F0C0723C45 +:1059D0000C0C5ABC08FE5E5E5479791E047B99203B +:1059E00065766D05EA070050DE58A18003000000CF +:1059F00000000000000000001F8B080000000000F5 +:105A0000000BD57D0D7C54C5B5F8DCBD773FB3BB2D +:105A1000D97C10120870F3014608B8240141B05E29 +:105A20003E8CD1A206B4482DD505F908494822DAA2 +:105A3000CAABBC66490209883628225AD4054141BE +:105A4000898D7CD8D406FECB4731F6A98D1615ADCD +:105A5000B641FB14154844119FB57FDF3967E666F0 +:105A6000F7DE6C08D6DAF75EF8F19BCCBD7367CE33 +:105A70009C39E7CCF99A898D6532CB10C6BEC69F9A +:105A8000CB18BB59668C8D8994A3EFBCAEACA90032 +:105A90007EFF9BCDBF558DB4D3CB214CA2768CA578 +:105AA000323696B1CB1CF02BB49BF2FC893F5D944F +:105AB000CCD87E26333B3C0A2B5392AE867EF67FB3 +:105AC000C5FCF8DEF2BC3BBDC38DDF05194B61ECB4 +:105AD0007B8C7F17CE50D37DB95861167CAE39E8E8 +:105AE00077E8276B63157C7FE60B377D6F86432F46 +:105AF000D957161616DF7C9D89FD2A9F75E4887A92 +:105B00000683C19980379DC6D5E13DF4CE0704EFE9 +:105B10000105E055638CEF00F89323F0EF67D7C5DC +:105B2000B35C0EBF363602FF378587E6DF8FB1FAEA +:105B30006AF5FBD956C6EEAE66DFCF1ECAD85DD574 +:105B40000EAAAFA8F651BDB63A95EAF50A7C0278DE +:105B5000A8DFC64241F8DE5B00EDF5FEE0BF3BD7B3 +:105B600061A8DB92E17B47A4AEB8530D7547BA6AD2 +:105B7000A80338475261DE23F823181F7060C7F16D +:105B80001D4CBB00DF0F25BC3805DE6A3DC36EC867 +:105B900004BC34BC22332419ABAACD42F886BA6DBA +:105BA0006A08E01BE15E308D79615C6F8031685777 +:105BB000FB2063F7C2F3E1EEC20FF1F913D07F03CC +:105BC000F42B7B1B8EDAE1FDAA0C9B2A235E762840 +:105BD000EF229E1CF00FF196B391D723F332D687B4 +:105BE00033A8EBF380EF7F9FB0FEA80470D466DB90 +:105BF00054BB1419A77B5DFAE87FD8BA73F73F54FA +:105C00002D9E8C74AAF73B8C056A7CEEFFBDFD8E41 +:105C100000DC26E545FAD5C7E9B35F58FE62F876A1 +:105C2000D846160A4B3DC719AAFA8B82B8DE1B1557 +:105C300016CAE0CF93811F860A7EA84F9FE10AB85B +:105C40007BC2C3A2C7C98CACCB50D536C7320ACAF7 +:105C5000EC996512D0075B17F55D262750E4975F36 +:105C600054FB881EEFAECEA1726BB54F433EB9FB1D +:105C7000EFF2ACE6DC9E7CF8579453F0DD3D5646DF +:105C80007418DCCE425B25ECAFEAE81CA8AF199D86 +:105C900092B75A25A02D28C774FA5E23A944DF4184 +:105CA000A06F947F66FEB8DB5A7C15D2FBAAD11692 +:105CB000A906F19CCDE97DA835ECC882E76BD665D5 +:105CC0008E0688D91AFFAB1D38EED0A1C388BE87D7 +:105CD0006773FAFFFD98F50E9483DDF35F9AA26572 +:105CE0002731168FEBE38EAC97EF3CE9C037310AD2 +:105CF0005F31E8401FE79FCD0FDF1D7D359E93BECE +:105D0000D6F8333FB4C3FBADC0E7B2D413AEC42161 +:105D1000E1D4E2DC9EF436341BE80CD7C97F6E3A3E +:105D200033976BAB43EC3D187C7D752AD1DDBA6AA5 +:105D300095CAD54887202751D6B0F150473AC4F5C7 +:105D40004A2FA07AAFFB155B4EFB51C2D410433EE5 +:105D5000598FF479093E5FA169B045F5CFD1EB2C9D +:105D60006C01D9BF0EDF0FA0BA865BD85D925E7F53 +:105D700026A8C1F7FD7278BD507A26589B0DFD39D3 +:105D8000F9F745D2292D981EFDFD5D9A3631D21EB8 +:105D9000EAE1C9D9D1FD41FFB9D1F01CA4F67A7F5F +:105DA000F3A4635A10EAEB9CBC7D8374F45FD2FFCA +:105DB0006AA93115379A5552375EA89FD57A3DD8D2 +:105DC000A869B9917132963FAD05A3DFB3A70DEF76 +:105DD000C72E6F0C06016F0FB0E22C09D637715633 +:105DE000552AA844CC393BA459D568F838BE23F3CA +:105DF0005B4FF0BAB2F9FB5CE98F5A6DD4FA4C9262 +:105E00005E0E22FCBA7E63E5A4057A4FFA6D2F027E +:105E1000BD5BFBDBFCA467A443250DC69B1A642A6B +:105E2000C06151830CE5815555DE8FE6039DFE0070 +:105E3000CE71046771D5AC5EE00C46C3A9C3D1171F +:105E4000DC3A1CBDD3291FDF4C4F936F1CF78789A9 +:105E500040E2CE76AB1FF53C54995822FCF2D57D3A +:105E60009A025DA6DC04B85769DD66B1AC9EFDF60A +:105E70009F358085A2E6F9CF5ED72CAC8F21BCDDA3 +:105E80002C8D89AC2FD4E744E3719C6867A63F7DD5 +:105E90007E0E9C9F1A3DBF5A4D2988CC8F298DA913 +:105EA000C59EBEE7B7CE593CABD8DDB3DDEF25AE1E +:105EB000474F9E31EE5AC6C72359928CE3E545C63B +:105EC0004B9EA98F178A395EBFE2EF169F667ED47C +:105ED000E17522BC19D1F0F2F5D7E15D6D05BE8DFB +:105EE000B1FEDF35BCE7CB7F2E90BF2A7C6FC901A6 +:105EF000FECBED9DFFFED9FD25E3AF404F9F2A2C41 +:105F00007C19E0F1F6E98E50508AC8B97F35BE524F +:105F1000F015ACDFED2FDD72EC320B5680AE47464C +:105F2000C6AF905482BB37FAEE6D3E8C850CFDFCFB +:105F30004FCDA737BC7ED772E87CE56BCDEB2E6EDC +:105F4000DF65B310F27F7DDBE5F10CBEAF7F714AF8 +:105F50007F84C3DE308269F98CDD8F9F805E512F94 +:105F6000F45D767DDE79E919ABAB995607FACB1E65 +:105F70006F15E945F512A3EFD780DE16023DA6E0C6 +:105F8000952D8E396ED4ABEEA5B2DECA488F297836 +:105F9000E5906F0A4CC135347134DA79F54EFDF96C +:105FA00091A22C787E57363C07D2A8F7F0FEE07914 +:105FB00031B68F1BCA9FF706571CA84D75517877CD +:105FC000DA428158F2F17B160BE1E75ED4BBECA814 +:105FD000F7AB543A5D8D01243AD7609BBA39A3E7F9 +:105FE00077B32C5CEF5F3BF4D9306E73AB84FE76F5 +:105FF000E0F2C7892F5DD98D9A05BFF773D7C0BD71 +:1060000026FDCA9DABD753A529B067BA4CF5BBF5A1 +:106010007D37A84E427DCD2BF49D4935974EAA8DF4 +:106020007ECF2E9A84FBAEFEFEA69A31F43ED1516D +:106030007574228C9F08F2B316594751A52AA4976C +:10604000EB1363D2CBDA2B1DB342F07EEDE5C33206 +:10605000E6C7B0736015699DF57A529191AEEF1560 +:10606000FAEADD427F4D451E8F926B4EDEB45BAE89 +:10607000392FE072CD95A32E47BA4C2A627ED4B355 +:10608000D702FE0251EBE4CC01F9166577242AC64B +:10609000797D57F37980693FB4F4EBBD7F337F3D61 +:1060A000C00273B07DA2D8A75C397E2990DBF7FCD3 +:1060B000CDF3ED6DDEDF17F884712A628DF3AFC288 +:1060C0004BA21BC629F8E78FE3C271A2FD45E78901 +:1060D00077D84784DF8DC9B80F98ED2A57814F6272 +:1060E00016AAB6A3FD9D84AF00EF1ED658340CF857 +:1060F0003AA978E5AD68AF79DEBEF243360AEA1D0B +:1061000073A66159979BD73619DAC5FB7DD30B89E6 +:106110004E19E1791576467CB768F924981FE1009D +:10612000F8EE51CB4D9382B99CBD71BD7F22E682C2 +:106130009AB7A2EFEB99B1E66163618E5FE96B7B81 +:10614000CFEF7B9BBF35F29DF0F72D213F695FDFDD +:10615000B16936F21B06E11FDAA309A67EE2355BC0 +:10616000C4AFC8104F517578FF42375FDFFA2F195F +:10617000CFC7EE75A8A807655B7C68A7C7335F0229 +:10618000EA7FAEA9A00880BCF02577052D6ADFEB79 +:106190005207A605ED674077D3A3F4DB3F5BB87EDB +:1061A0009C3C636AC60AE8F74C01F70327F9B8DF9D +:1061B000C13C9FBB603F0BDBA3EAB99B897F6B812E +:1061C0009E32812F82B916F267AFCADEE98BE66B89 +:1061D000264B026F66FA60AA027894057DC8D9162C +:1061E000CD39EADBD387FC0FD247DCB4A8EFD83730 +:1061F0005F2F8FFCCDE8E3DB8EA7AF6B4FBE5A2E2F +:10620000D6759E03F59B95A933E263C9D9DED7F510 +:106210005E5A57B067B5508CFE13BBD733D8B34C1A +:1062200011EB493FB719D64BEE3F76D6A673AD5B5F +:10623000B2111F7ABFCEA5B2FA57145E8A8FFCE462 +:106240000ED1DF2AF5DE20EA2967706F077CC88D42 +:10625000A3C3B89FB26CE6DFCA9B901EE254B5D0D0 +:106260006AAE2FD3BAE8F0D9D22D86F194649701A3 +:10627000DF6C1668D951F03B97DA080E078E07E3FA +:10628000C83EE85042FF3F0B3BBDD423F587437D1A +:106290009D85F53B0D74509F9E1773BF53C4BAA2E2 +:1062A000B9CAE9F5CEF3932FE6F1AE37C27BDEDF54 +:1062B000B915F5FD283F5DEFDF29EC7D1D5F80C43A +:1062C0001F77D33B5FA79556D622C5833C489DC90F +:1062D000022AD4F115EC630D588E473ACCF3915E47 +:1062E000B04D52104E626915FFF3FD6E382AB5406D +:1062F000B7164780F024BB3546EDD5F3DB0FCF5AF8 +:10630000B99E9C2C3143FB65B28DDE2BAC98A1BDB0 +:106310007CF69D2B52A95F0D1E8D8DC061EE77B866 +:106320001C58268F41B2E3F0E007E81F601D39E4F6 +:10633000CF4E13383B3B7F06D913BDC1F7A089BFB1 +:106340001E14F6012B2EE8635E9C8FCFC298EDD809 +:106350005E515D380E3B9E437CA08AF1370733E9DE +:10636000F9E68673F3F92F110ED04F1FAD7650F971 +:1063700058B58F4AFDFD63C2EED922713B447FFEC2 +:10638000B9CCED845699EF179B1D8D4EF2431F7CBF +:10639000F0CA61C05F038EC87E27E02F6B913F314A +:1063A00010435EE865F61A23BF3179F639E15DFAEC +:1063B000F6A4E987A2F8B149F624BF1F07BF5CCC59 +:1063C0002E46FAEBEBFBB3D5DAF44343BF3D5EB6A2 +:1063D000083BF4F3DA9797939E13BE8CF87380A072 +:1063E0009B01E55C1EA8752CA422FF7EF5358BA6CB +:1063F0000FD8A92DE84F1F58C2D843D07EF33C8B4D +:1064000086726BE05A5BC842FCAEAEC67ADA11996E +:10641000ADA6BAE69E13E58F4F93DF5E0E14CC86D1 +:106420000AFD4CF7ABEBFEFF4141637C62208BF22F +:10643000CB437F6942BF4B33F9F1BFED7AFCE57F77 +:10644000683D1E53FC2E5FD4F759122B8EB50F9E5C +:1064500011FB54D6DD5BB83D52E266EF45C52BB665 +:1064600048FE44DC0C1E5DB373BF0DE35125CC3FE9 +:1064700014F09D5EE5B344C3A72871D48F9569E1FC +:106480000BA0CB15736676EC45B9359119E4580C21 +:10649000F9A128F85D32971F8FAD99C1CBAF647217 +:1064A000EAA4055908E35B53E755EDB7A22828672E +:1064B000E4EF4D2B094A08CF802AE65755A22BA2BC +:1064C000AFB4D92CA4F178CD9154A08FC182BA0673 +:1064D000235DE0FEB3D418171A5865A48BB4126379 +:1064E0001CA83FD2057CD7DF442FE67E06A87E8A13 +:1064F000C765042D3C5E34CB18D749635D1F3E81D0 +:10650000F01D72FBC3384E9D715C73FF0A0B5CA0DB +:10651000801CD9F3F3896002C3AE1C9C9C8478D99B +:10652000EC288E27B982C1AB187E971EF4AAEB1D0A +:10653000BDB48FC8D1A0C1BF662E1B86A6DC36179E +:106540005AADF204188D1FCC20F96E15F1CA8319CB +:106550003F75A05FA33E398FF213F6631DFD38EA45 +:10656000B0FED172DF8A7EA4A4487D85885799C782 +:106570002B54385DBECFB442C4C3687B3015E9D913 +:10658000AEA6E4231CF654D0BB627C374E71717BFF +:10659000CFA77C698CABB97DEF8BE029F16172E20A +:1065A00079E1235F09FC10C70F4E067302E93F91A2 +:1065B000856A717DAB1AF93E17697713D231B40B36 +:1065C00062FCBFBB5D00DA8D34B4BB45F4A719DAB9 +:1065D00015F7685722FA638671B51EE32E16ED484B +:1065E000AFEB6EE7EFD1DF12312EE983DDEDD41E84 +:1065F000FDDDA1C36768E7EBD16E990E9F615C6614 +:106600001CB7FBFD705BA896F4CB62F2C71EE8577F +:1066100048F472A85F6111C6C16F7BC1CA65C436F8 +:106620009EE7210BBADA2FDAD5B9395DD556B371A9 +:10663000E5201F1B44BE4AAD7BAE2310F55C5F3FD7 +:1066400078EE8BFD7C8983EC31F15C6970925F138D +:106650009E933D56F777596C5A3F9B8C71CD0674CB +:1066600054613D78758D960DFC9EA618EAABD2F963 +:10667000FBAFEBAEAE09A2A34F29A6F808D0E7F70F +:1066800073A3F8B07BFC7F19FCDC7F1C81FF4735CE +:106690009A120D3FAFEBF0EB75E720FE5EB6CE9E93 +:1066A0008CF35921F6F5CF946535E44FFE5F3BBF7F +:1066B00045A6F55964581FBDAECFCF6A2DFD3F36B4 +:1066C000BF3B4CF3BBC334BF3B0CF3B35B974E0EE5 +:1066D000669FFFFCCCED565B8B49DEAEE8F7782A6F +:1066E000C2B542F8A79D56AD6639C61DFA75EBDBFB +:1066F00024DF4733ED6F2837FAFA6EA3A2927C7637 +:106700007A2C3C68D3CF161A9AC1E19A0172A1453E +:10671000F171F92DE03C62AA7799EAF0CB97B86F56 +:10672000FA986E4F9AE47C1FFB5A7D06DF4F1A3CA5 +:106730009A44792E625FB3E9FBDAA099B48FAD4831 +:10674000CD23FB65FFA005248F56A60FEBCFF3F0FA +:1067500052495ED9C55EF34035CF5BBB5FE407AD00 +:1067600048CFA376F7EBF19250BA61DF3CF0830596 +:106770004519201F4F1FE1F98AABADDC7EA8AF663B +:106780001ACFC37350B90FFA0D408356D0F7B07CBF +:106790000EF43D2C5BAA53A97CB65AA572278C8BAC +:1067A000E5AFAAFD5436558FA352D7171F14FAE24E +:1067B000F7D22DB47F3E56CDC62BD0FFA66A0795E3 +:1067C0008F56FBC62B40970F57A752795A9A31CE56 +:1067D0004AFED38EDA7858AF3DAF6653BED2C4744A +:1067E00085FC1E4C09CBF10591E73A5E4F4B932F88 +:1067F000B502DE2F512DBC9D2354EB8DDD6E32F69C +:106800003F4E55081EE60ECADEE498EDAEC0766334 +:106810009339DCCC17A8F5C4EE6F1A8E9B972CE049 +:106820004B566BDDB1FB9B8EED2E4A15F0A5761D08 +:10683000888BDD6E268E3B3255C097DE3E392EF6B4 +:10684000B83FC2FEFA2736521CE932B477A03F7B2C +:10685000BABA897C16A2DDE64155CC0274DB3FA9A9 +:10686000B10ADB5D5A55CC32A1CC4C296616A07F0B +:106870007B32BC077852453F13E6F1F79BF1BD2709 +:10688000EABDF87E7C09BC877A667FE37B7D3C7B32 +:1068900023D3E54998813CB0AF61DD793D584FB1D4 +:1068A000F0FA9DD60393296E69E3ED1FC13AF463B4 +:1068B000AF337E9FE2E2F57BF4F65EFEFDD3A27D70 +:1068C000FF443E6FE78D8E10C6C51EFDF79FA6CD17 +:1068D000CD8DCC77C8CF975E38376A7E8FFE7C35FA +:1068E000BDD7E733A47A0DBDEF8D5F53675B981674 +:1068F00025B7521A73499F1C6DAF22B9337AC8CCA1 +:10690000F01C58176B31876BDF8A553535D9045722 +:1069100090F205045C0FFFC408D7A09F1AE17AF833 +:10692000A746B806DD716EB8565BB95CEB0D3E1834 +:106930005F8B1E3FB4DC38BE5A631C3F54631C5F40 +:10694000ADFDD6E387A3D7E5917F338E3FF867C6C9 +:10695000F11FF99971FCC1777EBBF1FF59FAB8D7E5 +:106960001AF80FABD0C7E568BDB32A68D03BA15D6C +:10697000BB681794A3F5D840D0A0C742BBD7443B0F +:10698000CDD0AEB847BBB7443B661857EB31EE5F8E +:1069900074F82CD1FDF97BF4F757ABB0172CD1FD6F +:1069A000A93DFAFB5087CFD0CED7A3DD29D11F3325 +:1069B0008CCB8CE3C24F0EE6F3DCC15C7EF4F72E89 +:1069C0009DDA40F1AFFE2C20A1DFCF97C4461FC255 +:1069D0007D398BE7DD27142E1D82FB784382D1DFC2 +:1069E000D5CFC6F729C52653BFBE38564579878E01 +:1069F00060DAF4A87C8B32D1AEFBBD3B98765DD4D7 +:106A0000FB14F17D83885727AD1C538B72C537105B +:106A1000DAC7A0B7541BB70BF5F72CD9DFAE01BC12 +:106A20001B7E3C63CC6A163DAE95B71B22C64D8FCC +:106A30000D5743061FB714C7CDC5E7BA7E114C23C7 +:106A4000BCF978A93F5FEFF9A9F457C04BFD548713 +:106A5000458E87F76BB89F53F7B727D8AA1C98B70E +:106A60005B3BC8C236AB94877C4E3F4E5DB5D1EFE1 +:106A7000A9F88A35B4F70694F8F264D6FB770F15B7 +:106A8000598A62C51D0AC4BCEA4A263766C3F8ECB7 +:106A900090D17F0B84CDA2F36186CB81025B2CFF6A +:106AA0006D1DF79FEA7A50C28073FB6F6B857ED1B4 +:106AB0003D0FE828D6FACD12F0B10D1C6F8A8EB7C3 +:106AC000C41964DF25D45CE9F0C5F86E95A97F2769 +:106AD0009BA161BBB8E446662179C2CF4DE87A55E7 +:106AE0009D6F33DF87D280A6300E94BC338CFC734D +:106AF000A6809FA35052434189EC513E4F542BF145 +:106B0000274E0907D1DF386083C2C220B7D65A02A8 +:106B1000B36C185FC96E24FF98E2D324C4D3596BB9 +:106B2000E84A3A5700EAE266A927BCB7D8B83FF866 +:106B30002175C61F3262AC63894D35C4B7077C61CD +:106B400063E1FCDEDB47DA71B8BAE93415E8732497 +:106B5000C90DA2D34A592BB7119FA7FBC8EFA8CBE9 +:106B6000579DFF459C7BEE38267ED41BFE04F358D0 +:106B7000D46665C83FEC2B681D15FF5924FC5F7374 +:106B8000855F751E2BF6E2CB93CC52847C7592BD4B +:106B9000EACD8F5AAF069B8DC3D56025FF961ED7D1 +:106BA0009DDF6835F8BB166E30D617B019292897C7 +:106BB00016ACB3B210E07391C91FB614E70BF02FF7 +:106BC00064552B7DDCAE207D7AAE8F2949B0752CC3 +:106BD000FEF5C363E740FD17887718FF23A017353C +:106BE0008AAF4ADD211BE647BDB73B7FE60486DF5F +:106BF00087560E40799AC0629E2FBAA5C1085F5F82 +:106C0000F09BE165ACE69C7028DBA498FEAB877531 +:106C1000FE10EBB5D4E11DC540CE9C75F2B2DB9FF2 +:106C2000F26727C9F7BD4847B4DE5517F1FDA0EA62 +:106C3000622CFBFAEE80A03FF3778B1D1D36E48FAC +:106C40004AA5AA48B244E24D766B401B08DF595B67 +:106C50002685073243BB86F36CD726659E57BB2239 +:106C6000CB39FA3B25E4E5F33B1EB3A15D76F2C9CF +:106C700063D7201F96FD56660E68776A878785C999 +:106C80002E09D9509E94EE9663C667290300F056EC +:106C9000F62B0FC989D29DF6D034F8BEF4D9F74649 +:106CA00031C0C3A99AAEC303711F7D52E271D26095 +:106CB000C728DCB74A157673718CFE3A04DD9DF85F +:106CC0004D1CE5B548DBF6DF44FD36DF60B547C94E +:106CD0008737705FE2EDB87F6DBB141A1A437EE808 +:106CE00071AD13DB250E5F8B35E444F8B66DB2054C +:106CF000008ECA6D9F101D4DF9559317F150D92282 +:106D00001BFCBE95DBE4B07D1495C7B0C478890444 +:106D10007C5DC1B87CACD8BD98FCE115CD777D22F7 +:106D20007BF17B233D035EFC61C4EB1BB27F1AD673 +:106D3000773DE15501551FB56FF5225EA1DF39B6EC +:106D4000788CEB1AFDD8D8FF17893DFB03CBDD8685 +:106D5000F455D9BC8A8F67E2978FF097B49EF113F0 +:106D6000BBDD934C7AA21E3FD996745E7A6259D3EA +:106D700099478230DE899D1F3F1204B8CBFFFFA7E1 +:106D80008FDC897ACD3EA70FF9BDF2C9D7BC2C6A3A +:106D90001FCCB073BE3BB5FD89C71F023E39F5A6B7 +:106DA0009DF2F24EEDFD6030E6D39E7AE6BF52547E +:106DB000687FFBDECBC99EBF7DCF94FEE7DA0F91E3 +:106DC0004E43F668B842D4BFDA22A1B20586BC2889 +:106DD0004DEB7270B7CC9C00E7C9A3F610E63557AF +:106DE000C2B3A579B84E8B49FE627D19E0B7624700 +:106DF000FD27F2A858780E0EB4A46209EC928AEB33 +:106E00007CDDB597166069F5AB4817AC8BE4A7F944 +:106E1000BBCA23B09E17F5BE7E67D85736CC3FA9B4 +:106E2000DCB18A8F6B5ABF93F8CBF89EEB7799DD74 +:106E300018FF3AC3CA1F7D085FEE4E8A19D7D5E303 +:106E40005F8BF7FCE09C7A932E07FAC26F89C4E14E +:106E500072DBB56BEDC84F3B9F7AFCA164BEBED31D +:106E60000021A79ACE0C66401FC7AD5D37A17CEC10 +:106E7000DA6BF7E17E5EBAF70DE2AF537B5EB1A944 +:106E8000241F995B023DE114EBFE6947BDA142E27C +:106E900095CA2D9EB0DD1B59A78AD0F422D54BCFC1 +:106EA0008FD1F310A7FB8AD0FEEBA518EBB6D29ECC +:106EB000C9E571A81FE165F1963FD9288E1DB59EE1 +:106EC000D2385CC76385F8BCB775D4E7EFC3F95F08 +:106ED0001CB59E5B38BFF6C697A736D915CC4BD0EC +:106EE000D7F794C8BFAD0C496FB018FCAAEF6FDF9D +:106EF000341EBADC440FFA7CFBE2E7BEE7F1CDF0CA +:106F0000742B26578EE989AF135FC596EF1B857CDE +:106F1000A860554503B27AEE4F0A188C033322F06D +:106F20009EC05800D0D98927653A2FBBB2F920C935 +:106F300069B35CA8E8454F6EB2733BA7A265FF2812 +:106F4000945F270EFC86E8B062C7311BDA4787B72B +:106F5000EDB275E446E81EE57F741EE689A7F78F5B +:106F600022398DFDC7589FE744FF95ADC6FE2B77AC +:106F70007C62E8BF2CD86C23BF681FE37CA4683711 +:106F8000E07C3F6AB732CCBBFFA8592E8AA5DF3C14 +:106F90006AB71AF3613C638FA25F514EB4A928EF20 +:106FA000EA966B6F04715F7CC5CACF3D2ADA51CC7B +:106FB0000BA84DB0A968AFD6796632354A6E379ABC +:106FC000F0E94BF64DC2B89A6F6A7141B4FDA4C3A3 +:106FD0009FA0590CF0DFEE29EA8FE79FD00E53F106 +:106FE0009CB1E227BFB2EC2D2CC2F9C83E8BCF1961 +:106FF000737FE6FD59DDC56437597D96EE5C13EC71 +:1070000077F4949923D075A630D5A0E7AF9DCAE355 +:10701000B8FAFCD70E621B19C8DDB552571BE6B390 +:1070200007AFE4F9814CD8E95EB4D3337AEA734C04 +:10703000D354943F247E787BA6459D0FB903C0B1FD +:10704000601E8FC54FCAFC1DB246793D361C370BFA +:10705000EDA7103D8F6361AA5B1C5CFE7858153D5F +:107060008F671D8DD9D0F9DBF6E2B32837EF2D4AB3 +:107070009438DC61CADB4810E358E2D2D3CEC5FFB6 +:107080006CAA7222DAEF63671BC92E41B7E3D749B6 +:10709000113CE879717ABF6B9D1325DC6F707E031C +:1070A000F15C8F3837EFEB9EAF46F57E7ADD340E1C +:1070B000B6F48D155B2CB162405264BC2DA091FCDE +:1070C0001C03583395E9AC9DCA44874F5208BEB79C +:1070D000C92F6561EFB2AFE34CF09D873E7ED6A22B +:1070E000BD1980B2D62A9EBFE3096D85FABA04663F +:1070F000381F9CE9E0F264ACC3A2E72707A2EDAE1B +:107100005A564E737726F3632CFA773F7004863B0A +:10711000A2E219B2BB9DE77F09FB57B7D72F97971C +:10712000F1F87B2AB7AB7B5B9F15D5C506BBDA5C54 +:1071300036F673CCD9C4087EEEA7921CFCFCB2C60E +:10714000545F34FD61AECDD8E8BC464D23FB5EBC38 +:10715000B7C2F4F0A51DF128F7A4BF62A4BF7E4812 +:107160007F1DA2932EF25354CA81229C6F6A76959A +:10717000C49F0724EECFD2649C6F8AE8DF12579E2B +:1071800076AEBC2A360BE8232AAF659DB01F158565 +:1071900029AE3C8467A35877335D1AF354757DCDCF +:1071A0002D6A76912FF7BB8257E93C8A92ECA6FCB8 +:1071B000147741DDAD789E5C61553E949F6E3DFF36 +:1071C000C4CFF30A75BBD89963CCE7B49BF257AD33 +:1071D000C2FEEE91CF2DF6DD7BF0410C7DD8BCEFE9 +:1071E00056394C7AB4F89E8D8B9D37A8EB61E74BEE +:1071F000F7663BB2DCD17E9806F769946FA9087FE9 +:10720000C3A4EB7DE407EFDC21F1736B263AEADCE3 +:10721000193F0AE521F22FDE6F11279E4B3BF6EF57 +:1072200047BDA9CECBB484449273AA0C785F298D54 +:107230007648502EDEFDC9CBBF45FF7AABCC706BD4 +:10724000EE84B9B5E3FC142D01172B8EAD31ACEFF4 +:10725000379D4FCFB822E7B7253E9DDFDCF4FDE92F +:107260001D129D9F92D98807F01C44659B9585E06F +:10727000FD69C6FB3FBD91EB030B5F805160FD379D +:1072800088F1715F8ADE3F928A5C4C8DCEE3096A99 +:10729000ED78FE7F9EC047BFE244C3FB8FE716B583 +:1072A000917F26B080F44F3C5716DD5F99BCEC020D +:1072B0001C8F093F860AFF90FEF4F99FB5046C7C91 +:1072C0009F288E0F933E03F62FDA0D2189F295CC7D +:1072D000FE8E8A1689F6A745B03FE1BD028B422695 +:1072E000FBD19447A7E3DB4C97071D421F7433770C +:1072F0002F78F587797C94F86AC90B3C2F6C4993F9 +:1073000014A27CE68E0BE219E15926BFD107AC6AC4 +:107310003DEC1C11FA35E1CD9E6AC4B35335E23918 +:107320002EC788578FDF8847339EE3C7651ADA97E1 +:10733000C9E536223281E71CF88778063948F3A878 +:10734000807984D59EF82C695DBB12FD1B7DE2D14E +:1073500084BF8F4DF83BC35AF7F3B720525388B51B +:10736000797EA41226FE31F39B8EA7745FFB247AEC +:10737000E6F790BF38557422CDE3DF0D703473E625 +:10738000C9F313BFE979C271DDFBE57BEC6B286FB4 +:107390009B7EE818C6D3CDFCB5114BE0EBE66A87BF +:1073A0006F1E8CF77435F3CDB362BCDA47658C7D04 +:1073B00094FA077AA4FDE01E8C4B26235F2BA1CD07 +:1073C000DCE68A9B86E7FC5AAD3EF45BDE93D7751C +:1073D0000DEAED95F3799EE38F5D7C5FBDD5C5FD2C +:1073E000B08A8BE737AF2EB6300DEDFB563924A1AE +:1073F000BFC8A7BD7019EA5DAD5695F6355FD7CB0E +:107400003FA2F7F93E8CEFA6591A47231CD09EFCE9 +:10741000ED9DADEF796F89D2774EB5DC7721EE3BEC +:107420000F5A58492C3D3EDBC9C73F95F36E0A926F +:10743000E3624717D9D1F51D55C5382FDD8EB0ED64 +:10744000E6FEAD8A96E9A44F1E5AC0CF63EE39C15D +:10745000CF6316CAB3BF3F12EAE35F53B8DC64DA06 +:10746000B43929D484D6711DE64B221FFCD512AA4B +:1074700021FC34FE11E354B5FFA950BE6C4115BF89 +:107480001FE4B7DEC2362CC76ACDF9C8D7535B13E9 +:1074900026E17999CAB7795EE59876A33F87C9E571 +:1074A00007D10F76E628DF962F3EAA98ED2E19F722 +:1074B000E3F11DC6E713FAA0DBC94EB11F7959CA23 +:1074C00037C98BBDDBA25DE9E4712C3ACFE5576289 +:1074D000DB4F0FBBB87E057891504E7576317F0D2E +:1074E000E0A973DE009A6FE767FCDC65E75772512D +:1074F0002CFBE82627A797076D3C6EFBE002776818 +:1075000039FA4D17940E41BBE8F37F0B0C8915A790 +:1075100088D8072CDE427B9E16CFC6215FD4F1733C +:1075200066AC312DD6F9799D1F74FED0F9226D819C +:107530002B10CB7FF9AE93DB6F9317E44836A4D7BB +:107540007D12C5784ED5005CE7C06390D50C4478B9 +:107550002A5B3E25FF82A335B61FFAE7785803E978 +:10756000B626B87C02E0EBA7C0D441E4075B6346D3 +:10757000ACFE836C1DF99BE663923B7EE7E07634BC +:10758000531AD36678904FA65CB912E07C08F80FC6 +:1075900049FE41AB9FE00E2E668CFCAB0AE7FFF480 +:1075A0006BD8A6D551F6568373D23A5CEF754E1E52 +:1075B000EF480AF82584DBFFF7B35EECBFF30B3B23 +:1075C000ADDF00E1E7D1BFFB958E1F97760FD14B62 +:1075D000493209437FC0EB9B07FBFF452D80EF2815 +:1075E0007A8CAC5B90BE4B0C80EC2BC0F38C163AC3 +:1075F000BF82F616DA13954CFF0992F2A9F31F1E0B +:1076000036C3735ABABC955AA5B007E46681C31D48 +:10761000467F4A6209CC1BE351CCC1FB6B37EAA31E +:10762000287951EEA20CA07D5AD83BBA1CD6E5773A +:107630005D029783756B15CAA7DCA87438D17F9C4F +:10764000A1A99331B52A515129CF615009469C41D6 +:107650003E663D9CD0ADF74C60EC99BFCB31FD1B35 +:107660001F74E32BF02CE26B545BD701549FFC4E4C +:107670009684EB5D28F49BF127B93CD2F3FB2B8574 +:10768000BD619647BF013A478131FE52BEEF8D3F43 +:10769000E9F623FD74CBA10585B48FE6B5E61FC4DA +:1076A000FC9CBCB7393F32217FC07A23BC8C6D0B68 +:1076B000CA880FB3DCE94BDEE8F2C4BCCEA05C772D +:1076C000D731752EBF0DF82C6AFF36CBA9374C7217 +:1076D000EA0C9BD8FF7235424F794BFD07ED51F410 +:1076E000A3CBA9083D85886ECDE348CCD15DF76575 +:1076F000A17C7951463F48E7241E9F0C221FA1BF61 +:10770000E2B3D09538FF75AD573891EE77B64D712D +:10771000205B2D49E5E7BD94FDD70799209FE8B888 +:10772000AE953954770EE2C542F8907D508F9AD7C6 +:10773000E946499C7754E3AF8F713F825E2E49E55D +:10774000E7B976B665C6733B334CEBDE4DF7C20F37 +:10775000A1F3854EEF66FAD6F9A19671BF84AE3FCC +:10776000C852B3B00B8D7E815ADDCF1174529CF894 +:1077700076A10FD6BA87DD85D7DBD48527FB302EDF +:1077800071BB2793F2996FEFC7F166C6835E567E91 +:1077900001FA6154DE79A5D2457EADCA2F6C86E729 +:1077A0003A5E7BC3878ED74B10AFD23F8ED7B36282 +:1077B0007DCDF8FD47E79DBE645CCC7373FF57E653 +:1077C0003D81057EDB4176173FB7A1D3972E2FC6AB +:1077D000DEB6218D88A3DD78AE479723E35AAA0E43 +:1077E000A28A68961317B5B2EB104FE3C30A1DB116 +:1077F000ED4B6E7C86BFA4D1F98B592E8073F4F3C8 +:10780000B3CA76C0A3512A4B9A06408D6A57488E58 +:10781000B1F6F38B4335873F4B41FFA2AE979ADB1E +:10782000E97AA9BEBFE871A0D5AEC0421C5F6A016B +:10783000BE81F9D7FAB8BDDBE00C94E2F33880D909 +:1078400085B97639E10C6E9F1AF9B2373E8C33F167 +:107850005933E085CE21C03E3754EA09873E7E96F3 +:107860002B81C309D486FA4BFA58C607ABE0F7D987 +:10787000A58F6201DC87F1F826CEB3C1C5F7935519 +:10788000420FD3CB0667F17284DFAAB0A03DEF1F91 +:10789000875BF70BAE7669D52E18C751A4D13C068D +:1078A000FA981FF5FA814AB3E4073812CB55A9DBE1 +:1078B00059A3EFDF78EE679A3A89CE9765333A1786 +:1078C0003B10F5A018EBF34B17F7572F76741CC637 +:1078D0009079E5B4AA22EF39E2D391FB06FCC24FBE +:1078E00065CCC3E8DCFBC6208C4BBEF3EF9F7A303F +:1078F000EEF417A5CB83701E5FF6470F9E377867AF +:1079000019B7336E32E9333B053E7D71C5DB117F1C +:107910003757FF7DACE1FCF8521E47591492D1E86D +:10792000ECA6EFB26D71E49BD3EB8B9B930C759D32 +:107930004E17DB799E9479FEC785FDB468C726DBB8 +:107940004015C70FFC16C73F2EF4B5E3BB3DE4CF8F +:10795000D0E199BB63B40DF1F09756BB88C3B75B18 +:1079600039FEB569183F0B88A530C379785F1CF5DF +:1079700037FF7E99F48B3930D652A0EF40EB22B21C +:10798000B3CDF398FF8E5AD81FD66FFE2A89F452D2 +:107990006CBF0CE821B0B49EE26CE679CE099AE3A4 +:1079A00099CBC84E37E779CC63EA5D133362E47B49 +:1079B000B4F238F9C23EEC9A775C425F18CB2EC61F +:1079C0007CF4332CF717B96ADF76CDF16A46495A51 +:1079D0001F553BA83C51EDA372BB4BE5F1EC96FD66 +:1079E0008789BE94F6B1C8EF3BDBDE8BBB518DC8F7 +:1079F000EDEF6DFAF4E02FA19ECFB8FF46F78FCFE1 +:107A000016F8BE4CC8EF85421FC8FFE2DCF27B3699 +:107A1000CE77544F7875B93D1BEF938DC2832EC737 +:107A2000CDF838DD9615477EC638731CF8DBE1A526 +:107A3000B7EF16CBB1F30675FED92EE879DE96E9DD +:107A40002B07C0F8B57B3F18CCEF036647503EE8E4 +:107A5000F469A63FC6AA6CC8CFDD74D67A37E14771 +:107A6000A70BE0A354117F4C45BBCF4C6F7DE513B2 +:107A70009DB2760C463960A6AF53128B79AF68621F +:107A80001CF797CF53B542B443617B59C9E3745C8B +:107A9000FE1C571A0FDF89FCB985F3C7E25F373D3B +:107AA0008B72A7F457F77B51EE7CA834A6E078E5FB +:107AB0005B577831CE7D5C097AF1FB0F4372CCBC09 +:107AC000C2057192906BC67C05D610BC06F9F6F320 +:107AD000AD561FFA192AB7D9791C7C37C71BD47940 +:107AE000FC7B77EC7C85D227EE4F51797EAA316FF3 +:107AF000618B95F24FD05F86C3F416C7ED8E0B37BE +:107B00009F3BBE5DB9FBAE9879277A7E80996E6700 +:107B10009AE815F042764C10E021B7B8885BD76E32 +:107B20007F60D43180EBC496FFF04AB9D17E731EDA +:107B30001F3FDD7CCBA318E2E98D5E4F09FA8EE88A +:107B40000DA198790CE5D6B017EDF0F24D56B2EBD9 +:107B5000CA9B64E6C07C9637EDB46F9735FDEEF5B1 +:107B60004B00BEB267ACC9D3F834285F415FA7EEC3 +:107B70003C12B12EA5BB7EC7E3BDAAC82711EB53AB +:107B8000F6CC7E1BE6C598F138A579BFADC3948FBE +:107B900040EBD47CAC90CEE56D3F6BC3FDF4C37D70 +:107BA00012EB9FD1F3FB924DBFF3A27C403C515CA2 +:107BB0005EAC57EFF942E16B9E2BA076E487EB6D4C +:107BC000FD2EC6351A43F4FDF473307EC95B76CAC8 +:107BD000572A79FA36CAEFF940A9E274FEF08A14FE +:107BE000DC5F4BACC1141F95FC79C9233F21FA5BC4 +:107BF000F8CA4F52F8791E2D8DFB6D8269E4CFD8FB +:107C0000F8039ADF021620FA2B79582E467FC919FD +:107C100085153D13834FFE2CF8E483CD760CA2B27C +:107C20000F84DF32F8AA2CEEFD35C793F8BD2B6721 +:107C3000841DBD2BCEA2E7693BA2EDAACA2DF5EDAE +:107C4000B83E1F0DD2FAFB28AEAF0405BE24D2C742 +:107C50005FB9BCBF9063745F8CAEE74CC1E7D8BE20 +:107C6000DD4AF7C6447D67B8F7E576313EC0ED9250 +:107C70002E823225B63FD3ED9674F878FE8B4E5F98 +:107C8000BDF1FD169E4FF2D9112E57302F86DEB76B +:107C90005BC3FD0DF93076C3BD22917C0FABE06B69 +:107CA000E37B8093F255BAF1BB4FA238EB82757635 +:107CB000631E5C37DD98EFBB31E6AF2C34E95B7AAD +:107CC00069960B6FC699E2681BCF2F7FA5DC1AA2BD +:107CD000BCA3F237ED643F9437598B111F1FEF3867 +:107CE000F8FA8D40E71F37EB7C6B94AF66BE2DD959 +:107CF0003986C5E2DB8FDD7E16936FE1794CBE7568 +:107D000047E2112AFBEEE4EBC25EE4ABC5DD431FA4 +:107D100088C7BCDC8F9E2C1B427E06135E75B96A39 +:107D200096971BE3D45EF2EAF87E1EC977E4F8D397 +:107D3000E9B1F4A9C5344E37DDEA74A9D36D2F79C2 +:107D40005A663C9ADFB7097964F6670427B31CBC0E +:107D50005FAFD6C672D0FF1CB4B8FC5B3362E4756B +:107D6000B0AA0B50CFA87167C4CCCFF5BB7D68C655 +:107D7000326BB22AC78A77FBA75862EAF1F96E71B3 +:107D80003F09D202EA936E8EB73A115F014B90F22F +:107D9000FEE98C36C297E0257EB2C27346E72AFD23 +:107DA000746EDB1F67F9540515ECDA35430A15F4D8 +:107DB000A7E65B6ECB82FA823579850AACB37F8207 +:107DC000655726D44BD6E4F3FA45967C2B90E6E330 +:107DD000C182C2A9D0BE429FE7BC78837F43B11C59 +:107DE0005B8F7117E5392BAB85FA5DC0D78EBC4828 +:107DF000BC37CECE824EA8C7D9A084FACA8C3FAE7B +:107E00004423F03E7BE06A37C9A3C92AE2F584CF58 +:107E100041F932B7FFE672CACF2C7373BFF1885DA8 +:107E200013E8FEDDEF60FC1FBBC7F43E7E9D95F7B7 +:107E30007362E7882988D71143F8555F3AFEF31437 +:107E4000959E3B9BF1E829F17F2A9EFFA84DB051FA +:107E50003F65DDEB757E65ADC86B90E3381DC8F1FD +:107E600096AA67A05C22D6FF36810FFC417BB973CE +:107E70006FFFCDFCDEA7AEC1B8BEB27CFACFA8378B +:107E800076FD38CE8FE757DE72717CDD10BFC63AC3 +:107E90001CEA798EC1B72151BF25EDF80996D77834 +:107EA00002FFCEF1CFC2D8DF8D37C9BC3F7795072F +:107EB000EF519334AE474B4034B3010FB51A536DB5 +:107EC00059C8A2C67C0B59CEEB0AD3B81EC3B82C36 +:107ED0001DF64158A71BC6F375029CD2BEF8C638E2 +:107EE0005E9F15CAACED50098EBB118ED1F6D02025 +:107EF000B47F6E04B588D3B5D1FED6E3F495FF699F +:107F0000213BB352526BDD50DFF53623B97CCAE515 +:107F100015F907FC7E19DD2F31FEA5B95370C90A8A +:107F20005ACA781E87F043E971F433AC55C6C9F4D8 +:107F3000F0539BE4E104B686E4645FF1B1C7DD620F +:107F40009F19C0067CC3F85893FB3CE263E96E5D61 +:107F50009F17F176B1FF9F7E3193F285140573F27E +:107F600018B3A932A588E8DFED36C95F9D8E471E9C +:107F7000F1DD8278197984DDCCEDA55EF2238E33B4 +:107F8000CA6B1EDD9143F91156737EC4510B253C1B +:107F90008D7D215F457CD689B8F1378DDBEB71FF94 +:107FA0007CFEA8471CFF396F11C541F37DB1E3F892 +:107FB00097C8B329EEC05EE4EBA7C7F1999C2B23C9 +:107FC0009C67C28C25219C478CF7C55C9C1C94291E +:107FD000ADE66DE3F34BCCE7594CEBFD57F37A9FDD +:107FE0006F1EC487FC7EB5D16C14E54158451EC494 +:107FF000B32C705F741E848EC7BEF24CCC7925E61C +:108000003C92B480114F034B861BDE0FAACA33D4B7 +:10801000872CBDC4D03E0336C2E87A56C35586F6D7 +:10802000431B6718EA176CB8D1D0FEC2D05CC3FB03 +:1080300011DB4ACFB9EE239B9718DECB96503EDE7C +:108040000BA9AFFB452D3F8B4917FABAEB795A982C +:108050006E84F81D03EBFE5006F98FA6486ACFF533 +:10806000F78783B42F7FD3F5CFF6087DE81BF2BBEB +:108070001F898DF25AB99ED8697537A05E9C00B0F1 +:10808000A1BC35EB1709ADCFFF17FEDD899EF916B0 +:10809000EA72A4A33B646D3CEEF7FD447E649D450B +:1080A0009C279DEC207DE01E8BE5E6E87B922FF57A +:1080B000707BE0520FDF5F7E09FB26EE9303E358EF +:1080C00090F64F0B8BDC6701F3F52631716FF1A64B +:1080D0009553D3319ED991A326007F637D5044EE02 +:1080E000DF68576B311E305AE6721CE4FB959E7EAA +:1080F000B8EF2CB372FD2768453C0F74B0A0378FE2 +:10810000F63D8A6B26B06469492E9A5EDDFB8BFAD8 +:108110003510C3C1D211F16807BD8C906090D6E1D3 +:10812000A2FDFF87BADC2BB990E4DE69B79E37A6C3 +:10813000D279C7D3F3B2E8F99B3701D701FFBC6905 +:1081400033DA457DF9A74A36DDE741FFFF9B39CC9D +:1081500090675026F056861762E2B993D07FA6202A +:108160005A3AE7FF6D18025D29B5AF44115DBFE1D2 +:10817000D662CADBDD3D3D88FE3FDDEFACF753D96B +:108180003A8975DF230CFDDDF006F77FDDF037A3BC +:108190003FF7671E7EEEE86762BC9950F8006F33C8 +:1081A000613D12B07C7E6221F2033C0F4B50BFB6A2 +:1081B0000D543FA0FBE9810C2BC2F347E67F6D0F06 +:1081C000C0B3C2A3D238D7B3622BC2F5FA4D8B3DF0 +:1081D000D8AEBB3FBD9F8178A613F6E984A03505D4 +:1081E000E8A7EB5289F67518CF81CF8B670F5C81BA +:1081F0005B873EDEEB2C70F23558EF19CC4FFDEA71 +:10820000FD33E632C8C19D25657F49CA44F967211F +:10821000FFC792BD76927F9DA5679BD6C3FB9B0748 +:10822000760C42FDE2ADD2BF0D43BCFC7083CC5452 +:1082300058FF475D81B59E28BCBD39EF530FBE077F +:108240003D61EB7ADCE49FB2D339AFB74A9F1A168F +:10825000AD57FFD233693DD21D1B777EF19E294F6A +:108260005E48F6B64E5F8B047D2DD97E01E9834BC7 +:108270003CDDF4C5EB5BB3E83CD15889C5B423F1D0 +:10828000DE0FCC4BDF097485E708F77DC1F3C777B4 +:10829000BD98984FE751596047F4BC76BD7CE30820 +:1082A000F2B71E4D3E2F78912783A85F310EE74B22 +:1082B000823F66B526E50BFDAE05FBBFF1B7DB4F90 +:1082C000FE09F1B3F7A9AD77629B82F3C30713FBF5 +:1082D000985FE001F631B27F3A99CB6F8F61FF3C36 +:1082E00023F4AF3B2C1AD925672DC5227F9DDB21B6 +:1082F000B2C59F8A79DCCDAD721CE2CD8B068B2E88 +:108300005F4027F4E23D8CE2FE7C07D8672384FCC3 +:10831000F9C3DD9F16D671FF8E41AF2B38546AD05A +:10832000E78AE11FCAFB8B37066AF14EEE5EF5BAAB +:10833000B085ECE17F54BF7BF71F94F7273D9CFF8E +:108340009B73B8FC6E0EBB42DC6E60F9A8EF35790A +:10835000F97E7025E68900FE6DD2A91C07FCFEC9D6 +:10836000DD6756364C84E5CEE6F8C03AFDFD95361D +:108370004EA7DDFADFA1E1FCEFCB8973C005E25C1B +:10838000B4199E02E02BBEC9BA0CFA63F8F09774D8 +:10839000CEA52951FDC304D4E7414F41BE772A1D24 +:1083A000B68418F37B16E527D0F7382FDF3F1C2D56 +:1083B0003C0EE75035BAF7CCE9F38D467B496FFFA9 +:1083C000B187EBAD8B0FBF35D806EB74D2F2A21795 +:1083D000E308E57B767AD14C1E1517F07A51AEBED4 +:1083E000F9EA581FE55B6D1A8C766D7398C72746BE +:1083F0002A2CA8C4B8B7B972433E5DFE5DB121898D +:10840000CA0BD19F008F2AC37C9EA75A6A63DEDB0A +:1084100059F9FFF60EC0757BAA1F3F2F35B2357F85 +:1084200021CA3F84C50A72EEC92F46507F43BDDC86 +:108430009E87F1157CCE58C882F71D3D25ECB553BB +:108440005FC8D44EEF7764CB24D9076B991B6E3C81 +:1084500040F661AB5DC575766EE1F7C1395B9D2471 +:10846000F72AF75DC1EDB8041EF76C7275FD599CD3 +:108470006353314FD2E96B6489D07F938DEF8F17AF +:108480000203EC74479EEBE3395B1FA0A4764736EA +:10849000BF57CFA934B24BDDD178F710FC8582BE2F +:1084A0009A5C610BE6ED74E15D950457044E46E37A +:1084B000EA705E48FA7C93ADEB7D3C7F49E7EB5474 +:1084C0008483C3C95A2F5051AF70FA78FCD6E95350 +:1084D000FD41A9275C95A340CF057EBBA78645FE3D +:1084E0003E06E6B1B9227507F044532613F761E55D +:1084F000D4A37ED15D4781342EF2FD8FBC23EAEBFD +:1085000026929D1394D1AE87D29388F3E4FC85F72D +:1085100017F4CBE378403F719C83BFEF6E0FF4EE0E +:108520004EA47B8DA99D3FDE177795C4BAEF35D554 +:10853000FD4EB74BE1F72F43FF56F8C028156029D1 +:108540007FFE39A2DB324BEBFA912A9E4B0CCCF723 +:10855000C278BF7EDB827F53917DB4DD49E79073A3 +:108560007EB389FCD5E6FEEA8FD6DC8B79D99DBF38 +:108570009154CC03EDB47651DCA8A2F5033AAF7860 +:1085800045CB313AB765890F5462BFE35A964F41E4 +:10859000FC8D678DB5E8DF03794871FAE6542E3F0C +:1085A0004E1F19B6797914BEEFF70ABBB02B300411 +:1085B000F9A655F0E73ED46FA0DC23F4AC3DFB7F79 +:1085C00098157D0E2BC80E903FAC861DA2FC42FD77 +:1085D000796748A17360235E77DCAC45D1DB2F045B +:1085E000BFFFC2CBF5A0ECF8C00A84B76CFFBB3666 +:1085F000AF8A79ACCD8351EE36831E76AE7CC64A07 +:1086000013DF74E7B71CE7F772C3BAD6C5C33A3DA8 +:10861000F57ACB70FCBB22003FA3FBAADEB493DC4F +:10862000DC93C1F96FF96B9F8F42B9F5F9DEB22186 +:1086300088AF3BBC3CEE0F743ED985FCF40C23396B +:10864000A6F3632EF223809EEBE37E945CA473E496 +:108650003F5B3BDD03DAB587DF0B01744E740F74AB +:10866000EE43FD22D707744FDF5F40FCDCD46EE1A0 +:10867000E7C0418E0FA5FA64CA57696A9FEA237E54 +:10868000B6006AF3902FC307A89F667EE76D81E965 +:108690003ED78F3149634C443EFE9787CBFFE61CA3 +:1086A000351E6D84385936F041D43EC9EB621F95B2 +:1086B000E26FAC5F878946ED625F107AD73EA1E733 +:1086C000B2A35CDEDF26F6B225BFBBE4DA1D30DFE5 +:1086D000252FC95CFE0B3A3920F4E043D5A954C7D5 +:1086E000FD4285751A0325DE773756AB9A82DBCFBC +:1086F000B8A2C683585E52DC3C058F4C4D9CD57E9B +:10870000909F61D34620FDED3E70E508CADF7DD322 +:10871000CE304571F7975D7F7E12F351F701FE630E +:10872000EC4BE89F6514BF29267AEC8D6E3AA58E36 +:108730006B26F8613ADEF22B14D8E82B9030001F3C +:10874000AF794BEB8300D00FE3B5A3488F77FA02E4 +:108750005476BEF2650ACAF43D47DEF5A2BCDF6D71 +:10876000D346209DEDCE047B20067DFE4ED04F41AA +:108770002F79155F7A797EFAB020BB0BE9A762B733 +:108780004C7FBFE0E46E59C373D8EF6B8114D47390 +:108790008EB3E0CC09B8BF0BBB763E473B9B8F7ACC +:1087A000CB28BA2FC3606732799985EE7B6F95C865 +:1087B0003F5162D243CA59E3CA81B86FB46EB2E185 +:1087C0003C4AB718BF2F47FD651496E7B657BFF46C +:1087D0000AFD258B65A1FE02F443FE89AED764FF36 +:1087E0006646F93D6D98DFF39485E307E425F1A132 +:1087F000AEC73CE1D34EA05E7DC223F613618F76F7 +:10880000354994DF7FE1369E777DC9717513E3F3B7 +:10881000A7BCB01221072F5178FCE2922359140F04 +:108820001DA731F2872C68954288C7125DAF13E708 +:108830002960DB25BD6E3C0BD5E2FD720BB7497498 +:108840000EA36C9BD17F5FBEE195C3681E2E6E3672 +:108850009D8F177831C73776E22F31E21B83E3858E +:108860003F67301B6C386FD5767EE7AD3E16E7AFBD +:108870005F15FDEBED26C473BAA910F32D0FC921C6 +:10888000F1F729DD987F7B8BA08F5B047D54B2B01C +:108890000DF3F717AFE3F3656BAC867B8B17ECBE7C +:1088A00095CE2398E9A864078FBB010229BE53B275 +:1088B000D1F8BE54E0A3D4848F8A8064828BEBDB32 +:1088C0003DE16A9E89EBBB788795FE4E8719AE33F2 +:1088D0006C36E511FDB3E133AFD375FA3A0D67C3DA +:1088E0000DEB5474EEFB0922F68D51FF7DE6F0701E +:1088F000CA7739DD9649FE039D3ECCFD140AFDF989 +:108900008A0D5CCF3CD932256E24DA452F2A7E09A8 +:10891000FAC97FE9332F9EF7C8DB2B338C0B76B671 +:10892000E6DF85E7B477B5655F87F751E4BDA4D08E +:10893000BE91FF521EDD0B92F7525E5C16E551A808 +:1089400049880FE887F6DDCE17B3FF988BF2B36D39 +:108950006A01A279F98B7971A81FEC62DC1F21BD35 +:108960005490D411B58F94C773FFC0CAD4F7EE41A9 +:10897000FDFD8A67F8DF1FBCC2DAF532E61FEC6A3C +:1089800053FCCBA15EFED2DC1ABCA7A27CBBE447A1 +:1089900035FB70FB92E41F219DB55A7D7682F72747 +:1089A00007F07D708744F78557EEBD7C4413E67968 +:1089B0006FCAF7479FCBCE4B50EFC3BC4A961647C2 +:1089C000F6F71583ACB49F9E1810F718DDC7A26D9B +:1089D0002A44397BE2B95D363A37D824B15498C875 +:1089E000E1D4834FD3FD1ECFBE42F90A5376BF4276 +:1089F000F909BDC9FB93219985C9EE6EA47B611667 +:108A00006FD2EB1D740EA258E84D155B8E51BD144C +:108A1000F57F18AF74A31C52E1D7837B7F4DF90D0E +:108A2000153B787E03BC27F9538AF1533542E7732F +:108A300019A783B942FE94317ECF5059233F47A7EF +:108A4000DF8BA4D3F9FC1D73280FAD47BE19DA974D +:108A500014876824FAEE79DF10A7EF1EF72499E84F +:108A6000FB573A7D5FC82E44FAFE7C12CF0FFBFC09 +:108A700015575C2ECCE7F31764CABB3F079DD37E26 +:108A8000FAA2D8FF4F872DB43FE9ED4EB57C4AFBE3 +:108A900048E58BA76DA8AF16B67E42EB30AD75FFEB +:108AA00054C4F3D52C508E78BBBA35CE877C3EADFE +:108AB00083CBADAB5AED21F4535FCD9AEB707D3B88 +:108AC000F73D519788F4F238A7175D9E2D14F85C96 +:108AD00028F0B950E1F73D95E6EE5F8F6ACA558CF4 +:108AE000CB9BAB9A85BCD968C46FA7B55921BA197D +:108AF00029B1C68C9EFB5D19EBA0738F9D6923E89D +:108B0000EF4906C15E453DAC7C87390ECEEDFA0AD1 +:108B1000D37E7A205EDC67F00DEFC178D7B42ED318 +:108B2000BAF87E7615D013C643DAC235B928F77481 +:108B3000FC98D7A54DCD8A3FD779E79785DEAED78C +:108B4000AF15F74C34FB1ADDD176F8153EBE9F9475 +:108B50008E9783B8AEDDF64AF6C151AA2562AF8082 +:108B60009DF2657C3F6EB78C86AE9F4F97597272AF +:108B7000C45EA94FBD6F5A5E32DE1FC1E5C5A97143 +:108B8000D01FE60B288CE454E50E7B08ED0C3C77F7 +:108B90008476C07F03EEF3D8290080000000000037 +:108BA0001F8B080000000000000B8D577F6C14D74E +:108BB000119E77BBF7C33EFBBC87CD116AE2AECFF7 +:108BC000BF3018B3312636A449D62E6928B8CE193D +:108BD0001A429BB45C4814D284B351845C242AB1F9 +:108BE000B6898A42AA466AFF88AA28DA448A94A8E3 +:108BF000343A84514C655BE7C424B6532408D0183A +:108C0000D4B427FEA069656383149C5691E8376F3E +:108C1000F7B833366ACE92E7DE7BF3E6CD7CF3CD50 +:108C2000BC778F0E5EF7A5EB886283E21182AC2CD5 +:108C30008AFBB4A5441D44DE9246C80161A40872B3 +:108C4000D3755FBC8068BCB2A2280EBD1BAABE4C07 +:108C5000C3F8167F1ECECAAEAF15A262A24E48BDA3 +:108C6000383BDFA9A67DACDF39284C1BB2FFC3FF20 +:108C700094951712CD0CCD953D0DD9A8798896F213 +:108C8000FC0F57AB3877F6929FA2E538D8322FD039 +:108C9000FD44CF91F3D9A3111D5882F1E80B6D5417 +:108CA0008F0971B8949A61D74B460AFB3A2F2A86EE +:108CB000A563FE9497A889A8E7B33F8F2E2921BA10 +:108CC000F6BE30FCBAB3FF570D18EFB60F2F81FE7A +:108CD000CDF7846141FDB97B881EC2FC9ED7BD578C +:108CE000D201E7AC5BF27FF2CA41E8258E05F4576A +:108CF00030EAA1DE52826E2F1D963241AF5E57429E +:108D0000B037D0E7635CC8CED91F257AF1DDF9F61C +:108D100012A466C788EFC0DF5A3A4673D61FD50A39 +:108D20004BAE06F1A5966A6F29EC7FFE5181F36781 +:108D3000C615CD2F246E6F7E27179F3180B19CE71B +:108D4000F34C429C33E70AEC3CE8FDFB10D66A8802 +:108D5000A60EC1B81F769A158987678323570F7FA0 +:108D600010E57C32FEF135447F1CFE6095C9FE9310 +:108D70004DB49EFD86DECA1CBF93702AC74FF865AE +:108D8000A4705ED75F1503E6D9AF6A5F49D6AF938B +:108D90006A3A64E4F063EE90D9315A8574890F65BC +:108DA000BE3C6254CADBBC39A5C4ECBAEC18F1EC89 +:108DB00032B1FF27CC0BF843EA6C24063F7FA6E9CB +:108DC00092273D834E7E3D438EC4F93B8871C19806 +:108DD000CF5FB0DE6AEDE5F59BE541B218B7AFAD08 +:108DE000361E7747157A05E3EECF5EA8A19CF3897E +:108DF000FD447EBBBCB311E66DD7398FF4AFEBDC1D +:108E00008D4825C65BE8AD4D1AC65B297998D73FDA +:108E10008E069F675E5B7CEEB2AC9D2F8B14C77F86 +:108E20008E17F62CFABD63D78DB797B6491C7A5DBD +:108E30005EED2E72E23DA8C5BBB90E67CEFD37824E +:108E4000B0E9E4852B21CE5726DF77D6DD6DBF71E3 +:108E500002E373B3453FFF2478D030AE5A4588F320 +:108E6000C4649EDDC6B80CEDF9C741CEDB653F7129 +:108E70003D740FEFA921B61B8FAF8DA10E6F0EFFB2 +:108E8000622DE340A257FA65B17FF06B7AE062444D +:108E9000C77C62E86284D71327D7FFCE82FEBA333D +:108EA0000D5B79FEC4982AF9D770A651F2EFC45F22 +:108EB0001A8B2BD87132826C3731AEC6189FC478AA +:108EC000E3A76DD04B9C696D147CCC99C662EE3FD4 +:108ED000EB04C5925817E395729C89E7379A22E311 +:108EE0009919011F302F28EAF0872AE7F1676FFFF1 +:108EF000691FC7B1774031737994D9F796A64A3B79 +:108F0000EF307F806F4F5298921FC71DB977E08472 +:108F10008CEF456F52E6BBE798D759FF9323895EE4 +:108F200093FB2C5A62311E9FF214F2B0C567AF203A +:108F3000B838514E3B938BF4C3AAB090FB262EC594 +:108F4000BFCB7C996889D768750BF52C6A95F19031 +:108F500070F1EEF76EB617B157E1DA0B15D3AED854 +:108F600022EB5AD8E1CF161FC517F3E78B4C3D1102 +:108F70001DF58017E7DBBC1AF39FC82C588E3EDB2B +:108F8000EEF6D9ED3FF29ABEB55827ED741ED6DB4A +:108F900033FDB619FD0C7D21863FEE6FB1D76345D9 +:108FA0002940DA61CEEF73DB28E6A50AD8D93C7FE9 +:108FB000FE71EE97F52C5569E76E7DF022F7C1D56D +:108FC000F8524DD5DC074929080AF0E6AB31AFA6C7 +:108FD000487FED4AEE0777C697E9331FA3FFE9E81C +:108FE0007F63E87F2C7B6A3FAF4F038F89914BEF04 +:108FF0008765FFCCA32813F01B5847DC09CD3DFB48 +:109000000E7B3DB7EBF3C7F3F896C9CF34D1E664D6 +:10901000DDC2FC5C77EFB34460CA07B25217ED3B88 +:10902000E2411CAB14877F7E6FDC2C451CDE8196F1 +:109030005429F7D35A7451C437FD88B0B9CFC3CF80 +:10904000327F4E9F9F5E2EE47AF70E615BF83A52B4 +:10905000FBB9BCB713A9B33EE65375FFD32FCBBA08 +:10906000B5E80245B2797C2CE0DC97B7F397899795 +:1090700017758E0F7C96FDB8444AD6E7FBB1DDBD6F +:109080000F1F6B9E9FBF1A3AFB8352F8F184290C85 +:109090007BB1BCEFBCEFF452FAF6795F158E1787FF +:1090A00081C7CCD91B3BD6C0DE44ED3FCBF81EEDCB +:1090B000BC0B7FEF0D3BB8760543F55484EE52A30D +:1090C000F7A581C7F1C2F80A69C7F34D6815F1FE2B +:1090D000F49B2F09CE0749FDBBD54B855B2F15614E +:1090E000CDA98B125AC7BC7A4F73C6135E7B05F7A6 +:1090F00003AAC36366C3FFEFBB3DA73EA9E7BC5C01 +:109100001B19AFF7E5E46FEA25D43DDF23431F4584 +:10911000F4825C7E795C7EA9520AB1CDBD1FE7F373 +:109120006D8AF9C6F93EFE51FB93CC93FEED2542C4 +:10913000CFB93F4F9E0F55E5D89D1E54A43EA9E9D7 +:10914000EAC70B73FD7C59FA399D74EC11A5ABB7D6 +:10915000AFC95DEF73799B96BCFDF5CA7D31AEE377 +:109160000C6F557278DB39D041F23E72E34EFAF063 +:10917000057E59C37EFB1DACCF7867CBC23975F134 +:10918000AC8B73534A483E6E204B61BB4DB0F81414 +:109190008F554AA9900F504ACE13AD20E6F1FD2E0F +:1091A0008F9BD4D488A8977A960A5E6EA4B352EFA8 +:1091B000219A95D2243478C85632A46C0EA4B67283 +:1091C000FBA84B2615E6532AA286AF828FDC4A16EF +:1091D000CB5F367E95AE66F809653C6E76C516E9BE +:1091E000D7BF75EBDCE0B71AE7799AECB731F52019 +:1091F000A5153EE40195362B88E7419502F9F0F775 +:10920000F8A847D6EF705AB7B97F19C5EEBE7F618F +:109210001FC64DA653A77CD53CD5908DF74E1C3666 +:10922000C25E11EBA974C42B714CC9F31E66C71141 +:10923000770BE92A8F7BC3E56E9F9FFD399FF3FD76 +:1092400041BF7CE7780296C4E3485897790B02CF78 +:1092500010EC6C7C4DD024CE352A9C7833F637E266 +:10926000D557D4C0FA42EA634C93980F069C7D44CC +:109270009B34C64BA4229E5BC16F8FEB4C84A4DF52 +:10928000A16766AF1D94EF36BFF6365C32063F9994 +:1092900014784F0BD3A403EC4FA020C5EF6BB06341 +:1092A0002AF75DFD4678F71FC2F047E89AC48BE2C3 +:1092B000A4F33B6319BDA1F1BDE161BD6207BE2FFF +:1092C00081DF136EBFBB9CEFF48D77ED6DBA07F9AC +:1092D000D8591230381F0D81B27504BBED85716904 +:1092E000F7B23856258DA8F67AB69BE17990CC6610 +:1092F000C659B8F93A1070ECCDE539926B92F91C69 +:10930000443B0FC0AFA3A88B00C656AB936FEBEFE7 +:1093100079761FCE9BF3C424197FA91801C9F76879 +:109320007CB209526D35F57D05FC64471CC16C1C8F +:109330007D7C0EEE637A160F449061BFE6C4D3576E +:10934000E059C9BF97FA28DFC0E388F6173A3CDB3B +:10935000FF459E4DE50BFD1BF1C74738BE398F31E8 +:109360003921EFD17D4DDCEF18A7EF6570F2647104 +:10937000DA6947FBD2BAC4658CFBEB7D7EFBDE1459 +:10938000F6FDD46F57B1FF193C90204952CDC53935 +:10939000838FC6F9631E9BC85F26FFD12C4E47F30F +:1093A0001D7CF0F3CDC141471ED72C8C3FC3A3FFDA +:1093B000010A95CE3EB00E00000000000000000043 +:1093C0001F8B080000000000000B7BC9C7C0F0A382 +:1093D0001E81BDD0F8E8B89917BF3CA9588601C1D5 +:1093E000CEE6626008E060600804E2DD40BC078809 +:1093F000A539191842803814882703F95380380793 +:109400008893816A1B981918B6B13130EC05E223B4 +:10941000407C9A8D74FB9F8A3330A4C920F85B800E +:10942000EC4D72D4F5E3281EBC38C600953F4713B7 +:1094300095BF449B81E12E929AB99AA4992F68C84E +:10944000C02004C4008B7A89656803000000000016 +:1094500000000000000000001F8B0800000000005A +:10946000000BED7D0B7854D5B9E8DA7BF6EC994921 +:1094700066263B0FC2248664E70501031D6288400F +:10948000D14E5244B4D48E685BF478740848781393 +:10949000F09556BCD9900709093058AC81224E107E +:1094A00011156AA4F8AAB40E88163DB64D5B5BD1BF +:1094B0005A1B11410139296A9D5AAD67FDFF5A3B7C +:1094C000B3F7CE4CC0F6DC73BFFBDD1BBF8FE5DA14 +:1094D000EBFDAFFFBDFEB5462645442A20E40BF860 +:1094E000FB1A21B9222164423C254452FB9C901274 +:1094F000ED8B62539E7C613B9FFC67A3CC798D9082 +:1095000061907E9F906C426EE365F42F00F9A93C58 +:10951000A3CF474F895F26D1B2783F5309CBABA287 +:1095200040BE10E0ABB95C1FA7C1E91D47D208F9E6 +:10953000C4C552AD861655D2F42D57A4A9901097E4 +:10954000102A66EBACFF4A702CA61743DA24905918 +:109550003DEE04F320AB195C76E788A42A3E7F6BCE +:109560003D3D6D6A24243A2A9EB749FE288C4FA6B9 +:1095700010FF8309DA4DA4EB40F8B88904F0903964 +:109580003CDE154213E1BB9D04A2365CAF9FC03C9C +:109590000F78AA8E84B208E99C22FB1DF079530E45 +:1095A00081797975B8CE2AC0BC0C799590AFC33F4C +:1095B000B8DE685B319D47AA5F246BE9A7A69C0AC9 +:1095C000271D93AC9FF4575F88A6A9520F512075B1 +:1095D00093404FF9E0790689C8F7F12E723E70B0DA +:1095E000EE8F1DD680ED6947D9F1F96EB0D379D1F0 +:1095F000F568134402F0595739332D94601FF47401 +:109600000DC0972EBCA5D18969D3C49969A41C7AD1 +:10961000EA9F05705E3F295B5C2BC4E1A2C3E1C0F9 +:10962000A4179D7DB45E3BDF9F4EDF4127B46BE7FF +:10963000FB6E85DB7A800F2DAF2102CEBB6558CA49 +:10964000AC4802B8D4102F96AF77D176B08E1C12EA +:1096500079B010E6D3D73587E6BD13950A80B715E4 +:109660007FA60E93B0BEDB4D220EDCDF803B8796DB +:10967000A71236BE3B8FF8A3743D2EB7DBAFD2BC2A +:10968000345124511DE6F8EF72D33E7849BD835022 +:109690007A4D9D326F061947F36AFF1118DFF9A65C +:1096A000C31F800AE532B657E87F5F14D1FDF8DBAF +:1096B00087584EDE16FC0FC2FC767078296C7C67EA +:1096C000896C1ACFFEF93541806F47F98A9455426B +:1096D0007CFDB2719FE9BA6D96BC7DECCC6F15AB89 +:1096E000C9F7D3DEE725D18B6865DB0D43EE7BC37D +:1096F0009BE32F3D54169FCF8F8827EB3800EB62FA +:109700007231D2FF39DA7FD2E8BFF4901DD7291A1F +:10971000F950B2FA6D1CCFF47C7B21C513C4B33E63 +:10972000DFD563E3DF5FE5F841B46AE46F12DFBFC2 +:10973000F64B48BF8DC2B769ACACAEA67090DC7278 +:109740005418C7C6ECAF02BAA67FF0BDBCB557F03F +:1097500042E636137F6C29BE8A328EE4F393B2CC94 +:10976000FBF365E1F73CC0EFC238FCEC249816052A +:10977000BC0DFA103E1E7D1E977C478DAA09E0782D +:1097800031A53B3A9E3D2B42128DABF341BF10F801 +:1097900035F01F9BEC47BE4526CB09F9A05D109123 +:1097A0004FC5E1EC94101F09FFDB1F42B8C30C9DAD +:1097B000D91C7E8097252FFE0DE027A9249AEAC5A3 +:1097C000EFCD5205A5039568A994FFCB129120FF18 +:1097D00029007B02964F9533804F4CF38780FEED36 +:1097E0007C3C65B6EF6A4F7C3E9FF27D8D97877C0F +:1097F000DF3695DBD97C3D9C7F28734C7831D03E99 +:109800009DB5B7AEF723C2D6FB29A547863F737C2B +:10981000410FF4434CEB6E516F08D6AA280F3E85DA +:10982000FACD5F09F4CC017AE5F2C02A5793F263CE +:109830008B3CB5FB0C79F84731E05311FC9BA7201A +:109840007D11AB1CE76960C43F270F69CB4472767A +:109850009C203039A565E1FA753A225C4FD0F79B20 +:10986000F27593FC90613E94EFB948043B4F25514B +:10987000CC7B483DE63F9E581115683F0EA9AF0DC1 +:10988000F89783F251AD70F0F81BB83C49B68E0DD5 +:109890009724E6FFF9807C80DFEE7A1242BCBD415E +:1098A00001BA12B410F902E88B84B9FCF5FB60BF71 +:1098B0005A1B1BC83BA584A41CBC8EA863611FEA6D +:1098C000038172D04B6815CA824949254B25BF6A6E +:1098D000C4C7817D24ABF87841A43B8A17970AD08E +:1098E000BFD38C3703F85142896E12E6D560C2FEB1 +:1098F000F87EF27A49F16760FFF5F5A832E2AB0530 +:109900002F5C958A00A84DB3BD309FE17C36C343E0 +:10991000ADCBC571B02FDAF49174ADC3FB66CF0047 +:10992000D1E979F38AF7415E3597571CAEA1FB94D4 +:10993000E657AE9E4653570911009E6DD0592EF43E +:10994000F7A2564DD7DB049DD1FCF5AB9E0D686E9A +:10995000861E66BD5254251D5F8A86D44B842F1CFB +:1099600083DB275BBFDD22D70859717E7AD00DAC2F +:109970009D46FF03BA4AB7F4931630F3710F31E4F2 +:109980006979F380DEB4FC7F643C85AC76AA14056B +:10999000EDAAA844E8D869444997286AB8A64A2499 +:1099A0004AF34A567F4054CFBD2FCD844C677C3C50 +:1099B0004C8C78BC99D3B9AFB6B9B095F6FB71A50C +:1099C000DB0F743E9CB2C1CC8CC1EBE9B0C8E18E18 +:1099D000F2BB11EF9B88E62C02BDBE5C44FDA54D99 +:1099E000DDAB18E5D0B33A3F19841F4495AA9035F2 +:1099F000207ED85431E0F2FEEBF861D57BCE173FE4 +:109A0000526F30EFC797DDAFC3801F13CE1F3FFEED +:109A1000D5F1F47D4DC6977CB5B7A25DB1266F68D0 +:109A20003D7EF0BEAE46FEE952492092A0DD2F05F4 +:109A3000C12C7F8C69B6515EDC62DA2FA960DA91A5 +:109A4000EE21E021A91639A8F3B1069B7A2C133A2E +:109A50005050DE38797FEDEADD1AE8ED1FE7018628 +:109A60005079125E1E1540AF2961F61D742002BDAB +:109A7000A88108DA212097E8BE38F8FCEC3EB31E36 +:109A80006F5352CC7ADC2C4D30CEDFD520E33C9C9A +:109A9000301EEDD741ED0518D79647A22E6F1C5FFB +:109AA000612866AFDF795E78A0E32B8095E1ABB9E2 +:109AB0005DABAF22A15E3768BC6BCDF34DCA97ACEE +:109AC000EDDC927ADCA06F246F2791E306BDC50719 +:109AD000B2C5B0FFAD76F2B440F5BC26DF77349C5A +:109AE00037FC9303FC89A03CB3E5D490900A7252F2 +:109AF00065EDD40C265F7709267B5BFF9E7C1E6C90 +:109B0000BCD8CD84F482DC9154D47F93D56F6AF4B1 +:109B10007D55A242C8DEF0C06489EE5FF3AAC0ACF6 +:109B200020ADBFB671D764F8AED7AB11454EBF5468 +:109B30006C56811EC3F196D07A4EFC4ABE00FB885B +:109B40007266D580472ED233592AC3AF7CFF883046 +:109B50004007B4CB25225BAF833C8DF5A023A847FB +:109B6000B938CBD386906FB10702414A776BA5888D +:109B700073054D5B5C3CAFF27C3ACF2B3C5FC8F386 +:109B8000643BE6ED32CDD375A5D8230AE65378BE03 +:109B900090E733783E9DE78B785ED88EF91699F57D +:109BA000D721F5B0FE53785EE5F90C9E5778BE8854 +:109BB000E7C95E36BE83E553ED3DACFF549E2FE40E +:109BC000F94C9E4FE7F9629E17F6623E299F2C637F +:109BD000F08FF305066F1D0F09C0D5E4E78A5AF22E +:109BE0000C5F32058687B16FEA78E347FE48DCF9FF +:109BF000486FC3B9BFA1E906E66F20DC3F62F87E7B +:109C000058057E334BF40F455F8F707EBA8BEBB1F6 +:109C10003B1B15D4BB7734FA30DDDEA8E2F748638E +:109C200019A6DB1AFDF87D6BE3444CB7340630ED22 +:109C30006A9C8EE9A6C620A61B1B6761FD0D8D21BF +:109C4000CCAF6B9C8F6947633DA6ED549F85744DE7 +:109C5000A386694B631BA64D8D614C7F7843C54B32 +:109C6000A0D27EEC1651CE279BFF85BB44131F1E4E +:109C70001D31F3C5515D19A67C6938D754BFB8AD05 +:109C8000C8545EA88D319517345498F223EA279B67 +:109C9000EA5F30BFC694CF095D69AA3F2C38D394E0 +:109CA000CF987ABD29AF4CA935E5BD950B4D797795 +:109CB000F90A53FF2925DF37E59D79AB4DF53B5C6C +:109CC000A19F8A942FC8596B4DF524F7DD6679352D +:109CD00023EBBCF816F948CB06BCD2F98795DFDB3D +:109CE000F2492080728BC99726C05BF0678D209166 +:109CF0000705F0235D7E18FC178E1226771C83E47F +:109D0000A6B93FD9BDF38846C7A9F61EF6F519E8EE +:109D10008C18ED4ECAF7FF2C32BFE2DABB989DDCFF +:109D20007957627B19393BADD7F979623FED9F4492 +:109D30009B452F60764AE75D02D6FF57FBD7CBAD38 +:109D4000FDC6C7A37B5C65B05341EE4F60FFA7190A +:109D5000F4137B5FFA1CB07B743BD6C6E9BCBACC6B +:109D6000FF763385778B42FC0E9A6F71D710D02B1C +:109D70003E5618DD931DF9686FEBF507CFCFA0575E +:109D800020FF4931D9FB927B26F29796ACA1F532A0 +:109D9000396623512AAF6C3101FD72B2149C5E48C2 +:109DA000E9577ED5E65F45505E26B4DF09B91BE171 +:109DB00060B3E837CD732D7C6FEA085CB75DE76F61 +:109DC0005935F8BD59197A5E0E9817CC87CFCB1E3E +:109DD0004BC5D41673E17C27C532313F31968EE9ED +:109DE000C5B10B30AD8AE5603A21568C6965AC107F +:109DF000D38B621762BB8AD8684CC7C72EC2EFFEEE +:109E0000D8784CBF12FB2A7E1F179B84E9D8D8D77D +:109E1000F17B79AC1AD30B63DFC0EF636257603A12 +:109E20003A760D7E2F8B5D8DE9A8D8BF613A3276E8 +:109E30001DA6A5B1399896C466635A1C5B84ED8A49 +:109E4000620B302D8CDD82DFD5D8724C0B627762CD +:109E50009A1FFB1EA623624D98E6C556617A41AC57 +:109E600003DBE5C6DA31CD89FD00BFFB621B31CDD6 +:109E70008E6DC6343DF600962BB16E4CD3628FE2E8 +:109E8000776FEC614C3DB19FE07777EC714C536399 +:109E9000CFE2F794D83398BA62CFE37767EC00A6A5 +:109EA000E7DA2739CFCCC76D5929A6FCC463663ED3 +:109EB0005EF5A6998F57BE6AE6E315AF98F9B8FF2D +:109EC00090998F8FDB6FE6E3E5FBCC7C7CCC6E3327 +:109ED0001F2FDB61E6E323B75E6FAA5FB2C9CCC771 +:109EE0008B3A179ACAD566331FCF5FF97D53FDBCF5 +:109EF0005B579BCA7317AF3595FBE69AF97736D94E +:109F000062B6BFA76E37CB91298F98FA7357EEB51B +:109F10009C034490CFA494FFD4D4CE597230A15D59 +:109F200063F57F0348244ADF779014FF5A61F07E7F +:109F300066707E90097447D32C4E77C380EE689A82 +:109F4000F18DC5787EF4C937DB7E416D4392710196 +:109F5000FD673274BBA12640BFB7E6E879A209903D +:109F60001F4198DF80BC5F8DE5852CDFD574AC5A2E +:109F70002B477D9EFB154E57835FACD5C5F20FD99D +:109F80005E59057E858CB440AE9FA63BEC89F9F8FE +:109F9000633619E1714A0C6CB3D1F5FE6775DFEDDC +:109FA000E00FFCD411DA6EA3DF173B4305E06AFE35 +:109FB000C01E7A4802BE48020FC0F73412D861436F +:109FC0007E6DF67B36828140FBF98B187C18CA3394 +:109FD000AFDA857691BEEE56CFD0F3B9CFC6E45254 +:109FE0006B3A41BB51BB4746798A7F55713FD5BD1E +:109FF000A9DE009477DE236F87F320BB3F9BC9095E +:10A0000062911F9B5A9783CBD101FB6933FA3D7B49 +:10A0100031F5927EF47F2A441120D5D73FB0EE115E +:10A020006CDD141E87603D32F84B697E75EA55136E +:10A03000613D141E2F7078BC681B961C1E044E0ACE +:10A04000AAB82A01FFEC164CFEC7778550AF8D9D4C +:10A050005FE27C54CD8F707BC4C6FCDD3AFCE8DF48 +:10A06000AD19BA3F86B53B82FB60E94FEFA7D7C673 +:10A07000C7E7F250C7E34C918412C1BFA591F99F85 +:10A08000C9AEFC2FE5AFFECC2E261CC72E05F19CD9 +:10A090007410DFCBB2D8F5592138D385F38784E724 +:10A0A000A99364EECF900ACEEB3C4AF79790DDF986 +:10A0B000E755FF217DDD70BE908DA063FB74281FE6 +:10A0C000F3A5BC7D31D7EB9EFFD353D125940F74FC +:10A0D0005230B3F348B33ED7B949C473F4E2114CDC +:10A0E0003F6CE07A80839A0DAE710639DD69D60B3C +:10A0F000DB7438EE37C3B19822F44F2BE8FFB80B6E +:10A10000D8FC14F37A9AF5F55AE6D152EE2746BBFD +:10A110005B1A1B1421EFD8C4E6611D9FF0F3035DA9 +:10A12000EF75B8B9DF4429C07EF571ADE310DB4AA5 +:10A130003C1F4AAA8F58C7F992E76F174989CF2F5A +:10A14000E9FE209C4AB87E441AE81FCD8FE4F3D77D +:10A15000FBD3CFE1F4FCF37FAAC3F3EDD6702DEA75 +:10A1600079AD3E26A7C967B477E88F24C617FD3CB2 +:10A170007C0DD88D60CF95D438B15D568169BF5CB8 +:10A18000A59B9C008F66E56E05D2B565AC5ECAE8FE +:10A190001DFCFB76FCEEEAAA3F0CFAA28BEAAD129C +:10A1A000C07BC4AD58AF595981FED9942EE6B74D46 +:10A1B000E1E5B925AB9D10A2911B0E38A11D5125DB +:10A1C0007F29B4EB0A4F2F027F571BF14B6C0A4ECD +:10A1D000D8C7ED1C0E7925520DB4CB0B6B9A0BDB57 +:10A1E0009100B4D3EB45F87AF3CBC45570AE901F11 +:10A1F0008E846BC04F574FFCA5F8FD60B4D0507FE4 +:10A200001BEF5709B3F993F9AC9E5EBE95F7E70EC5 +:10A21000D7F756433F9B58B92FAF12D837C9566B63 +:10A220004598CF3A8EB7CE424960E741ACFD161D46 +:10A23000CD2CF45E1A66FE4EBD5E179F870DBE974D +:10A24000C7E97E0DB7E7F57A3FE4DD8DB4B40FF3CF +:10A25000EF8E4AD6BE89DBFFFA7E97CACC2FAEE3DB +:10A2600047327C256D067E060BD452CCF9860C93C2 +:10A270001D47EA73CDF9F945E6FAA131E6FCAC0ACF +:10A2800073FDC06453F92703FE92880BFD22DC5F47 +:10A290003292D7D9D2C5F03CEE8FEB7319ED8B3CDF +:10A2A0005E6F5B3D8B7369729F5F5C4918FC16C8DB +:10A2B0002C981F46D1FB69ECC2EFAD81DA141877F8 +:10A2C00067D7D0FDFD84D3D5E39CAE1EE3FBB787F3 +:10A2D000EFC7A3DC1FF330F7C73CC4FD310F707F1D +:10A2E0004C37F863E8F7FBC11FE3003F4D10D32D57 +:10A2F000E08F413F0DF3C7FC90FB6336803FC60102 +:10A30000F8D780E9C6F1E1EBC0CFD6C1FD32EDDC74 +:10A310002FE3B5337FE3C6CB02B950BEE3B2C4F638 +:10A32000AED7CEF024171414CABFF389164D01BA64 +:10A33000E82404CE5B9CAF680137CD8FDEC589640D +:10A34000BF1648A5F9511196CFE3E3809CC0F8A74A +:10A35000061617E3C8D3C86CD8A73CAAED50F8AED0 +:10A36000E1F8FA9AC4C68372A41B95F88C7CFB0DA5 +:10A370002170449A00FDB2F9B8422101CA86DFDAA1 +:10A38000AFC9B45C59DC1B80ADF2B6F544C17E5652 +:10A39000B528EA1B1BABFD87E13C6BF3EF6D7EE458 +:10A3A0001D59C4841FB4EF8476757E6C1BEAB7AD6B +:10A3B000F53CBEA892D5CB4F627F8FD96196FF65E1 +:10A3C0005BCD764F6BC3CC21FDC5C36789167F92E9 +:10A3D000E55C608A191F5B036C5EC9FAF3569AE765 +:10A3E000E32E37F7D7EA1E7A3EAED855A8EF27C33B +:10A3F000F332B1D66D9F10CF17C72EC5FA56FD4E5A +:10A40000227E543EA4A97200CE79A5A94A00F45A2E +:10A4100069AACA533FFF1EE0F920CB2B03E7DBB943 +:10A42000F661087FCBF97680C0F9F3C6D184D917DD +:10A43000DA9CD5812934FF6D82F6C2EBD2B21A2D97 +:10A440008FD2CB0CA768FB0AE01B8B57D0E3BB3243 +:10A45000E5487B21E5E39B378A643BCDEF080F4D50 +:10A46000CF83E218DC01F4CF14772A1520BE93B510 +:10A47000DBD4294E4F14377031A72F728858F5E678 +:10A480008B61BD2D9D33159067D2B57EB40F88CA00 +:10A49000E6AFF3BFCC2D43EF5FBB65BEAE247E9B22 +:10A4A000EFE9F328637C53C7EFCCEF0F8D5FBA7EE3 +:10A4B00016EB114CFE9D61D706ABED142EAD9B89BA +:10A4C000DF4DFB69FDDCC6FC64FB597C998EBF4DFA +:10A4D00081A3C8AFF5F1739568B500F50F4C222A3A +:10A4E000DDD791EE9088F6E001CADF81FE24AA75DF +:10A4F000D2FACAFC6880FBC905D87FA5DEAF411E31 +:10A50000F603F806D89BBC3ECA8D7003550F29FD93 +:10A5100037815FB330CED7753C68F271FF3AD53BD7 +:10A52000B0F433BA3EDD1EA1FF8CEC62FBDC3A8C4A +:10A53000F8719965F5C486FDB0382989EB8FAD9E19 +:10A54000DBF11C509BC0F4026A350704A82769445C +:10A5500084F1E72AFEB5345BDC350EF98AA4680283 +:10A56000E0DB0C21741BEC771CAF7AD83A38DCACFA +:10A5700070BF96F3D59424FB9922337D3B53F65F4D +:10A5800009F6E4E67B287E2788779164D6CF039B83 +:10A5900066A68D56E3F4AA973F6253B19F387DCBF0 +:10A5A0002C4E2F6AB63FFE5FD7E377DBCD7174FF89 +:10A5B0005F8FFFBF5B8F5F3780AFE7D2DBD9FAC910 +:10A5C0002C73FF71FD5D53709E5DAC5CB7073A2C38 +:10A5D000FDEB7ABCAEDFEBFABCAEB793C17A3D9728 +:10A5E0007781D5010AD0516E961FD51A58AD419981 +:10A5F000C5CF61A36CCDE8AFF8C042D792DBAC7792 +:10A600009C3F3F9050DE13FF08133FCDCC1D5A6E88 +:10A61000E872F49311BADE1E427D9A949411A37EDF +:10A62000B5B3A18608743D5B7DC4CF978EE3E4F299 +:10A630007539FB029A884E0D331FDE3AFFA06B94EA +:10A64000819F3BDC3D01380F77FB7A217CC9C877BD +:10A650004BE409C08FAB90AF39D530EECF5DA05F32 +:10A660004E180C57E073BE0CE8D1C25F48B017E239 +:10A670003D8AC7138CAB77409414E5030E3FE34F3C +:10A6800049F9CC79C669E87113F9F40FF8CB2A209F +:10A6900022D0879E36C7931385E289213E80BCD79E +:10A6A000448CF17E3ADCADED9A951A2511BF7B43BF +:10A6B000085D210F8127563F14B1F067AAB08910B9 +:10A6C0007F583C633AFA9706FC5192995F3B227A95 +:10A6D0001CCBFF2CDF9E2327E6DBC9DA0FC43D7FAE +:10A6E000497F5D3B3F8FD7E97B80AE2DFD88E53DFF +:10A6F000A42FC1F8EE7233DC534ACC76C53F802ECE +:10A7000027C0F97186E9BBE4CE4DECFFE77199B53E +:10A7100013F56D53BFFB478ABF0B0EDB09E827BA61 +:10A720009CD1FDB10B203E93EE4F2DC46BD27D9C8E +:10A730004B825E28FC8088D341FFF880FCD67B9159 +:10A74000619F36CBCCFF4EDAEC47E11E901E877836 +:10A750007398E5F5F9D47599F3F3C8CC6C388798FC +:10A76000B7C94E20EE7001918EF6E9F3A7FA4B3B84 +:10A770005C4CA0FDD691FA56E0672DDCDF5EAB1095 +:10A7800009E206973C755FD56C9A8F70FDE72485CA +:10A79000BF6A882F5BE88EC8709EF0CEBE8BBEF37A +:10A7A0005502ED23ADB9103F984E307ED00AF739EF +:10A7B0006DE6F99D6BFED6F9EAF78692CD43DA2570 +:10A7C000248C73FBB1ACC72D6AE7759FE9B760FCB9 +:10A7D000A23FDE7C9FE95CED5EFB27DBBD29AB245D +:10A7E000D1FDA973B57B3BC9784B9C7D32F08B655D +:10A7F0005268BA50148FD392EDC1C0051414D2D34D +:10A80000E3A370A464A8D7769EF50EC379C779D464 +:10A810009B2E0ED1DF194EC7BFD8FD800CF4F9C1B5 +:10A82000236F5F057AF5A2676D54A6D3F2DD1E1281 +:10A83000457B2322831C5BB8CF867E372245ABAE97 +:10A8400031F05F8C90A5FD2F7ACC8371150BF73A10 +:10A85000223368FB854FBE338E50389C59DDFFE2B2 +:10A8600005603F3C22B03842AD6FDC35F4FB4289D5 +:10A87000DC144CC407399E9F7E267516E091B0EB20 +:10A88000C08DD86FCF77ED0EC339DE5F65764F810F +:10A89000D6C3F325ED6121522AB0F919EF2BE8F167 +:10A8A0009BA71F16D8FC9EB6475C30BF5DDD728843 +:10A8B000D65BB6EB2F88B75F7F6C8F17E0B0EC6983 +:10A8C0009B89BF2CDB658B3AC661FAB603EFB904EE +:10A8D000DC02E5234B91C5D074DF128CF75EDAD32E +:10A8E000F1179B17DA9BE987C2C51F05B8BE66F34F +:10A8F000CF80FC4F1EF2821D78B2F7412FC095F633 +:10A900003B5BA67875E947063A23ACFF58C6E0FEE4 +:10A9100008E99701BF96F5B4B3F12CF47912FE273C +:10A9200067B05C18E930CB858FC92B55A818EECAE3 +:10A930004C181F3F201738BD2EDAF3F1368D8E7B71 +:10A940007AEFA96D1A9DFFE27F7CB8ED4ED0037FB0 +:10A95000EE5280CF2C7BE4F75E62807BB583D1FB27 +:10A9600099871FDAB985D2CB99D71DA8B79CF9D999 +:10A97000897C95AEFBCCE37FCB867B02B7FEECB245 +:10A98000E100875B9FF8FAF0A1EC7EC0D788C3B8DE +:10A99000AF11EC5F7D5A60C1F8FB796AD99FE7F788 +:10A9A0003D9F0FF3FCE08803EF152EA3DF1A2A600A +:10A9B000BF9620DF87FC4A0AE7A5BBD7FCC5362E29 +:10A9C00011BCB50B441FA4946C7CB0DFD77CEB9218 +:10A9D0004A48ED7E15FA23FDC8B7ADED96BD4AF79E +:10A9E000F52BC9F7F163F2990CF05FB6BB9D8D6B47 +:10A9F000D9C70FE07F260DDEC79B1CE6F3958FC9F4 +:10AA0000E2FB5197DF9799305E4ADFC7254F7C7B89 +:10AA1000483D40E707E782EF7C1EF757EE082C73AE +:10AA2000005DED4DD57C6C7F233368D9993D1FE7E0 +:10AA3000138A1FEFD9FB6F043ED9FF3387B29D7E87 +:10AA40005FF8B3D790CECE3CF11B5965F79DDC0281 +:10AA5000D513CE9081BF5ED01B96F233E4653B3CAC +:10AA6000518737BE4F4B23574F57BDF8FD6DFC1E26 +:10AA700061F8BF3472E05A21C1BE3DEC28627C39D6 +:10AA8000320CE1B284F4CA4AB9793F8589B08F6F3C +:10AA90004F03BC4BB68FFAFA1558FFC586FDDCC1D3 +:10AAA000E8D65A7F29A54FF00B0EEC6B44788D2425 +:10AAB000A0D333DD0E09E27BCFD8CF713FF74BEA4D +:10AAC0007F0F38929CBF71389C8BCECFB5BE2F0BB9 +:10AAD000BF8DE0B41E36188EA73F4BCCFF9F730886 +:10AAE0007C1EA1E9B9B6C1F2CB4602DA0585F1F9BF +:10AAF000B6F6D890AF9FDE65C3FBA6563EB1942450 +:10AB00003EA7FEA53ECED307C6013F3B7DF0198E82 +:10AB1000970CEF97EE7E5BD6B83C8818E54112FFA4 +:10AB2000D46B9CDF2DDB9FB8BF65BBFF92B0BF939A +:10AB300052E0BB30FF93BD76A2D12E4EF6D8A627A9 +:10AB4000D29F0E38EC26FDA9D55375248DB6B37966 +:10AB5000535418BA6975E035B0E7B4DFDAF11C83F5 +:10AB600048FEF71C704FD393A2AEA5F06AF2CE4315 +:10AB7000FFA3DE5FB3054E922FA8815D2A65052BEA +:10AB8000998ECCE6AD97DB15D1346F2A67F3400E72 +:10AB9000BD35FE841DD6F9678B3EF86789B40EA7D4 +:10ABA000FDFD5913FCABD444F86DEE3FB4D24654CE +:10ABB000A3FC73F4BF05F321CFB908C495D87EEE8A +:10ABC000D2809F2CDBE68A38E87A9E7FE2939D0054 +:10ABD000B733F73B88C310275EC7EDAF134F7CB286 +:10ABE000EDEFB4FC0434A6E3D76DA3F5410FDF9D70 +:10ABF0008AC1FAFFB9376D1CA1FCB9EEB93BAF02AF +:10AC0000FE52073443EBD73D361CF5BAE3C358FE7A +:10AC1000F89E1111D897C53FF9D95290238B7E9C8D +:10AC20004AC03479FE89D76E84FC99E73C18D778FE +:10AC3000E6B91397021D50FD5935CAF105C67704D0 +:10AC400068BF8B20CFCA852F0CF1328B20A57C6387 +:10AC5000D1D36901F0131AEA61BB658EFEDBD151D5 +:10AC60004BB45C116D9C682ED0E1A25DE6F1F29CC4 +:10AC70004C7F5A26F7CF63F5C3B98C5E7BB1DD6894 +:10AC8000A7602AB7B6D7EB8F721659FA61ED973ADB +:10AC9000487D22FCAFE4FD2EDAF5F928737F1AFF18 +:10ACA0006E1D877DBF4D60F74AC8E32E3C475B2C85 +:10ACB000474766507A7D5226F3816E177BA323D3D4 +:10ACC000E978CF723EB93885E6E9F75C3E0FA80F08 +:10ACD00079E2ECFB31ECEF92A75C04F07DC9731EC6 +:10ACE0003C6F59F2E427C77F44BF9F7E2215E3B42F +:10ACF000973C7707EEF71247F446F06BF73FEE40CC +:10AD00003FF2E9C75FCA073DE4B43D9A9F31847DB5 +:10AD1000BEA4070EC107AF83DA0565F5743EDA46B7 +:10AD20001677D64052FCAB68BF0DE0D7003C7ED30F +:10AD3000C5E2A3F839EE0AEE0F3A3B574DC3F99737 +:10AD400033FFD60A7E4F7DC537D5E1E98679405C71 +:10AD500028B988903BE4FA51C0676DB16F1015FCBB +:10AD6000EDB1624CF57A3685AA59706E90C5CEC9A0 +:10AD7000ED597E52570EED581C11715F394067BF77 +:10AD8000A65BBC62B33A1CFAFB7727E32F1DAEC06B +:10AD90004227F21937DEF7C4755286A03DC1D6F5B9 +:10ADA00089C0D6659DEF2776CD01FC3C7EBECDCE19 +:10ADB0004D1A24F53538A72487395F1AB47E4667C3 +:10ADC00067950CA4337D1D1D8D0AF293F6461FA6D0 +:10ADD0006B1ACB888A71F87ECCDB383C1CE51AB143 +:10ADE000C1FD5795CDD5E10E06E05C02FA047FABBC +:10ADF000CD1D42FC72F8EAD1F677BA991FD2E6D699 +:10AE0000481D4DED6E0627B8770A7092795EEA9A72 +:10AE10008170A5EDF1FB025768A313FD11634C7C13 +:10AE20004ACEAA30E507C14DC78B3DFFD3F02308BA +:10AE30002FF0D3A8E83F9F88706B690C60FEFF007D +:10AE4000FC9E61F09B4C5403FDC85935A67C52F81A +:10AE50006DA6F0CB8AD395150E0D3C1E4DA7A764A9 +:10AE6000F4FBC34682CEBCBB1BBB30D5BF6724916D +:10AE7000EB392E819FF78756C1F91F51985F856482 +:10AE80006924CFE04F223E0DEF31E19B2650EE6664 +:10AE90007E447D7F6D8A74DCCCFFD4D7603D77BC67 +:10AEA0006C17815FD91A1E20EF641AE87846D0A586 +:10AEB000229CFDE8BF6DE2F2B565603FCDF4D1D1D3 +:10AEC000A862BA8ED3C9064E271B61DFC13FE717C0 +:10AED000714F3BA713949FF7D03CB3EFA3C4E8D7BF +:10AEE0004EF7F744ED74FF9127A998B2775E8E383C +:10AEF00022A5B45D6A390900BEA41FF95E84BDDFD6 +:10AF0000D283F7FBD339FCC8FEA2F4EBF0FE34B1D8 +:10AF10003339456C2C0DDBC17EB2C2B7C97FD00975 +:10AF20007677B2F964FB35473E1D2FFB4D07F2EFF4 +:10AF3000AC1B7A8ED4D275B83B53D19ECCF6337C01 +:10AF400074FB43429D61FFB293E87D9B5D57385C83 +:10AF50008087107F4BF9F6DD5DC52E3CBFB0F7F85A +:10AF6000800F76A43339A3CEA2A35D1C6F7796F32E +:10AF7000476FA599FE757EAC4CA930E1B1CE6F3319 +:10AF8000A69AF15DE7B76F0EF0DB608E0BCE3563EE +:10AF90005B911EADF8DF649735E12BF0DE06617E34 +:10AFA000A7B705F60ECB603E80F12867FB0AB7C352 +:10AFB0003B00AB79FCB346E905E50EF77FEA77B9CC +:10AFC000F690609B5A08EF81500485776328FE0055 +:10AFD0003DACA7F843305EC8CFE96422A63A7E565E +:10AFE00083F3C4A0B7D94A5E14D9FD0B11640E9146 +:10AFF000A81DE8063FD381494ED00B253B8B53E972 +:10B00000F7883D7036D6E29EE984F86821BD12F7D4 +:10B01000FDAF9EDA82A1CE5508C4F152BC51DC7E50 +:10B020007214C6817BBA40174A05017B728FBB3709 +:10B0300005EC1BBF4B349DE374B842D35C86FC58CF +:10B04000189DEFDBD770FDAC1FEB783339BD933C17 +:10B050008D9418E85B8F0B25AA46CA0C74BEBA748F +:10B060001A8173CDC1F49D848F3DF8DFC3C79A0A5E +:10B0700022B86F762BDFC8A2FCDD8DA9262A30FF0F +:10B08000BDCDFF361EF1AC0EE041DCDB07F497AF1F +:10B09000150D9EA7956FC5E5918AFE2A2A8FEE9D14 +:10B0A000087C30893C3AF0A751DF9269F93B2FD9EF +:10B0B00004A3BF6E7EAC1DE5415D6C1251E97C6B53 +:10B0C000BB7E80E9BCAE6EC4FBF7222D5ED8C7F70D +:10B0D000DA983DF75EC41EC17884CFBEF8C2067E02 +:10B0E0007DC2FA7F6F6B13D623E07D318CFBDE5679 +:10B0F000D69E54AAA84F9FE56BACDDE008405CF9F2 +:10B100007B5DB4DD10F0AC056328817E8AF7FF21FA +:10B11000D69FD48F023EA7D3FB1D32E54B0087B7E5 +:10B120001C09FDEC0B5C97AD03782F70053601BF51 +:10B1300021EE8CF37A87E21D91EABD08EF90F76A61 +:10B14000939F95F931DFE17A31712629F7F2F64ABA +:10B15000E2F2259DA75EBC8BE65ACB434162B0AFBD +:10B160006D84D9D74B9FAEE6EF7DB0F924C04FA6D2 +:10B17000CF763A900FCDE5FE201D5FE3F812F2F294 +:10B18000FBA0267C5A10DB88FB2D748CBD771285C2 +:10B19000DF87148FC02F27745C321CE868D5DAAFC4 +:10B1A0006EB881F6FFD12B36FC3E3FE6C2FAEFDFE8 +:10B1B000E5BFF706D0D77F69C733F68F0E5F86E706 +:10B1C000B1EFDBCD7E841B5318FDFED1C5EC917928 +:10B1D000B10E937E3CAF6D8E0CFEC779B1F5F87D54 +:10B1E0001E1CCAB07B1B87AA4BE0BC86E0F9E81F97 +:10B1F000DBDF9DBA1AE55905FAB1EAD63912DE232A +:10B20000F9A34B35F19DBABE4EEC9750FD282B9B10 +:10B21000F767E01F7531B87402FBA311B867308F70 +:10B22000F39181F96DB59BF8C8FBAEC47E925303D0 +:10B23000EBFB2AD2D1E0F55DCAE84B1FB78FD15D99 +:10B240007C3DF74E4AB49EF83AA660FDF7D3138FC3 +:10B250009F91C2C63FDE389F04281FAA75D07A6E20 +:10B2600018FF96D68960676F4DCF100CEBAAEB5A8A +:10B2700044028675D56D9D2DD71AFA8DEF83ED05A5 +:10B28000E33E64A4FC63EAEA7290DBC17F003DD533 +:10B29000765C322E847636E327EFD8FDF9C0574F1F +:10B2A00074DD9290BE33522CFBD3C5F787EABD956F +:10B2B00086FDD1F7C5DAFEF89FEAFE7A17F8013667 +:10B2C00033A52619BC06ED5B6162B89573FC3C4E54 +:10B2D000E56C08E1A63E7904F07A5D2AC6712687FE +:10B2E000DF85243414FC92E8AF54DF294D9900E344 +:10B2F0001284435D17C38373C12D3E2EC783EAC4F6 +:10B30000EBB97E000F1A884609F6A87C2E3CB8934C +:10B3100068CE21D6318007A34C7870FDDAFCCB8053 +:10B320001EDF033D65D4E0FD3F2A6BDEC9700EB41D +:10B33000D686E74C4753B4ECEB597E3CF0E7A3DEEE +:10B34000F055932BE3F9050F967A671BC63DD1762E +:10B350008B37919FF5FA64F853A291F2AAFF7DF81A +:10B36000F34E927B570B5CD537A6005F0E27F6E7AE +:10B37000EAA9CEBF6D69EE01BB13E4E95177D15F55 +:10B3800023B4F451576801F47387A88E9B2DC4ED44 +:10B39000CF41FA67E3F44B8E9582BF3078C9313BD9 +:10B3A000EA43D81F01BDB290DFDF42FF460ECA0359 +:10B3B000EB79E9FA94C284E7AA2D8DF5171DC30035 +:10B3C000228D28867B6012617AD4A784F9BDF4F5BA +:10B3D000C8F690E207FB522041C073BB146A833861 +:10B3E00028BB2F6BBC66806B670A8BFF731D3AD43A +:10B3F0005648DBBBDE7D45C1B8153A0EF8D79C79BF +:10B40000D259A37FDA9EC5E2124989E17B11C42794 +:10B41000D0BCC9CEA7F31DC24E7D566070D03C0E85 +:10B420007E0F4EB381DCBB4E7FF8024047F1E575DD +:10B430003D0E446A66E5E97A71332BE7FECB65B5CC +:10B44000CC3F69DDD7EBF6AFC177F5AEDB9F3307B5 +:10B45000FC58D7B947BD0BE70BCF820F1FF03D9DBE +:10B46000C9656BBBC7389DFE5BB7A8D9E9BE1CB2E6 +:10B47000F71F84B876ED36F64EE2F5BF3F644FA570 +:10B48000E91BAF1EB5435CD14D10A043D7359BA837 +:10B490003253822308D739A4C7C3F23DC3667A8CDE +:10B4A000FD515315FA5BCECE79AFFFFDAB9781F816 +:10B4B000A4FDB5407AD32B4486FE67EF535BD9B524 +:10B4C0003BDEDF7EDA9F18EF2F0E4799D9399213B2 +:10B4D000E112879313E1F6FA405CA4867E14039C84 +:10B4E00051DFD0E13C00B7B459579271C9E9E53A50 +:10B4F000F7C877C9B8F8BCAC70FE088A28BD3D9380 +:10B5000012F815D04D2425F06B48173BFBF3A5220C +:10B51000BC77F83BE0B34B6DA182EC62BC8F386A1C +:10B5200018C471F5263E5FB5D2E95B402F10CFCD30 +:10B53000E32B6FE4EB7BFE7B273C1837F9C46BF9F8 +:10B54000902EB1F5ADFB2ED0DB7FD850FF3EBB6F08 +:10B55000D49071696F717FC7C914FD3D16B6BE9B4B +:10B56000B81E77D3BED408BC7B795383CDA4FFDE4D +:10B57000D4C0E23888D43BEE5A931ED99CB41FB095 +:10B580003BADFDE8EB3B989F7B21D887F74F90556B +:10B59000F03F1C78E5ECEB75349F32C289E7B2EBE3 +:10B5A000D239FE568BB8EFF7A70752C782DF696D15 +:10B5B000865FA3EB5CFB02E911297C0E8EBE3D5237 +:10B5C00043C75B7F89883EAB0DB107306E522B6756 +:10B5D000EF14295C1FDDD07BB40BF0F1C41107FA26 +:10B5E000FBED1E765F75AD3D980FFAFBBBDD72C2B9 +:10B5F00077EFFEEE96705DDD421FC6BBCD21612761 +:10B60000F08D7DBD3387C37CBC7EA200FA9FD86AD3 +:10B6100013F93D28EEE7884ACCCFAE492C1FE0A9AC +:10B62000E232C6ABB54F9F8AF114733B7F8371C280 +:10B630005E7E9FC93A8F0B53D97C3DBD1957007C64 +:10B640003D53457CD3C8E3EFC778F182DE1A19DB9E +:10B65000878521DB17AC54AE00B8427BE0FF05E7DD +:10B66000D9BE3895C53B6DE47672B7DDDF3A95F605 +:10B67000D3BD2E5D80FDD0EB4D4965FACC89A9BACA +:10B68000FF268CFE9BFC12C505EFA3E40790B8894A +:10B69000A7328C71B8DBA11EF36F221CBA473F1989 +:10B6A00085F3E3B5201B609FED0C9FD6AE13D09FB2 +:10B6B00049E1970BF2E2DD7B1CDF807514B4090AC7 +:10B6C000D8DE344D38EF5BDD4E66B774DE8B762006 +:10B6D000B847A1DFFCADBFC3797992AC779B9BC122 +:10B6E000EBDD73E0475AAA9DDD1B6AE8E57652144C +:10B6F000DF3F0CEBEFC2052AD9BB84524035C6A10F +:10B70000C4E987D961749D0138DFAA9D2847C00F1D +:10B7100020B675E33BBF73C20E72395D5FA7D01BC5 +:10B72000007AD12688FCFDADC05B00A7F51B8763BE +:10B730003CDB1A31908FFE9DFF25E3F9D8C1C0D9BB +:10B74000CD73687EDB4419E9E26080DD6BBD7F6507 +:10B750005137D8E19E861A7CB737A2E04BB8A4A92E +:10B7600092BC0CF1A44D2B4545A0F5C341FD7E8153 +:10B7700092027831DEF6E11565707E9623822F897C +:10B780009C10D8BB202D2B6B14D8D716254B30DA44 +:10B790002DB7A432F9F2ABF4E02DA934F5DD75B77D +:10B7A0000231DD1B62991782BF506B9355F67E30D4 +:10B7B0007B4F2493EF4B66AF189DE7C5BC7B3E35AE +:10B7C00091374C617ECA1F5C1962FE453893AC42CA +:10B7D000FF22FFF3E1BE66F1DCDA312998D9B47AB1 +:10B7E0001ED6877EB2693F999562B48AF6BB3D3D0D +:10B7F000B00DE5C9654E841391FABA004E91CB7233 +:10B80000FD10D77AF7A491BF8127A5320FF7CF0497 +:10B81000391A1991F24637F0A91659053ACF5C79D1 +:10B82000FC06F89EEEFFE12D906636FFE14E900794 +:10B83000E97D7F69C4EFD365937F2FF3CDF73F8711 +:10B84000F2CCA06CF2139E4E0FFE3095EEFBB6F2DA +:10B850007018DE3DC51DCD8EAF63CFAADEE9F08E38 +:10B86000F589AB45FF765E8EEBDAA444D632B85547 +:10B87000825CD3E1B646547BE01D65ED2A27E247A2 +:10B8800009E9457E9503A7C8C5F17DC97CB37D391B +:10B89000C44958E7F308A75BF883772531FE9ECAB1 +:10B8A0003139676A0AE0F5E315BD3ED0E3D7A52735 +:10B8B0008E4F38E966ED1D49EEA71FE7E5C012BBC4 +:10B8C0002A300D8C85D44DB43448F39CF83EE1E326 +:10B8D000A2FA47C4F3BB6D2AEC0FD4B7D3FD3BF0FB +:10B8E000F249F40F1E08FF0ED317DC657A7FD16C86 +:10B8F000DA7E7DE551F6CEB7C270A4AE8DF18B3AFB +:10B900005F9F13CE2BEACA89B29DE39BA6C319FCA5 +:10B910005D5C5ED55ECBE09A554EF0BC157C62F066 +:10B920004E5936D4A3F0CB6A5BB51CF791F46AC5C7 +:10B93000B4DE7AE817F6A799DD3B21A4CF89F41B82 +:10B94000B6E17923A5F75FC179626DE7703C6F8737 +:10B95000EBE9D05F061F3783F7D74DFB01FFDF8987 +:10B96000361BD98EFCAD97405E5D497119F1B3BFAE +:10B97000BA8CF6AB562ACA5A1D0F743E4649632E3E +:10B98000951700B7B99AB61CF0EFA8537919E6914C +:10B99000BAC9A1C2FAE76E7AEA0ED05B527D7D6D1C +:10B9A000C01FEA26B2F96674D2EFA8DFA8BF82FAF8 +:10B9B000759D0E958DC7E157C9F18CC3E1663EEFC9 +:10B9C0009BB7B279A78C8884013FEB5652B8425995 +:10B9D00088E13DB834BF1091AE0EC3FA3D5A36F639 +:10B9E0003B6C96852E2CF8A7AFAB96AFAB76255B5C +:10B9F00017E1F444A715857E6B2BD93AE712D65E82 +:10BA000084EFB4FF9BF97A6AB52731BDB9CD61EAFD +:10BA10007F5BD98E5E984F61B9AC0A0867F63E66C7 +:10BA20003E5F577E331B2FBFFC4984176930CC170C +:10BA3000FDA2863CA5AB132F51C2A27AAE0081FCB9 +:10BA4000B4DFA3DF93F11CA56493795D27DA473D4A +:10BA5000D009FECF7B643CAF785CF4BF558076A8FC +:10BA6000AC32FEE3FFDD0CE0D33737E3BDA93DD5B3 +:10BA70000CFE27BE4922800FA587831900EFD2C391 +:10BA8000219ED6E33936DE13AB8AE331359DDA04E5 +:10BA9000E097B1E247E7031FA0FB0CFAE008E3BC24 +:10BAA000E9FC32DBB26B200E296B62468D8C4FFABB +:10BAB0005ACA0F6F9909EFD7661DDA720B8C934340 +:10BAC0000CEBA1E5459E62A4BBCC43B414EA351C43 +:10BAD000BF0BF6A393BF2F5F0A33CBC0F410A4991A +:10BAE00094BE3B32609E12995A11E7070FDE533520 +:10BAF0001EF80ADE29A9C0344A2A06F30D43FDD1F7 +:10BB0000BCBE2624A837DAA39AECF207EF99361ABE +:10BB1000ECF7F5A027D27D6A27CA87101FA3F94545 +:10BB200084FB7A7BD4594EF36BA8DE08FACB86B23D +:10BB30003F884077EBF7113FE04766F01F0EE33E8A +:10BB4000CE71A7E3BA25997400FD1F1C7D7C3AECE9 +:10BB500053E48088EF48D4FCC2BD2515F4A1D75921 +:10BB6000FC49F74BF528BF6FCF9713BEC34CCEA14E +:10BB7000275AEB6794CE443F5EC1A68DD3E13E4E7B +:10BB8000DD74C97F39AD9DB5A9BA1AF4183548B12D +:10BB90006B389DF7D6F1AB8008D519ECBC4A9DCE29 +:10BBA000BEAB5359DAD138FF22B0DBC3BB24173CFC +:10BBB000853CA69DBD57D7517ED619A27A6965F5F9 +:10BBC0005EE737E9F76395540AD2EFC7A69C75C1C3 +:10BBD000F9CCFD95359900CF7D6D66BD8EC0636A49 +:10BBE000D40E1AEB08073C745E9DBF27084F9B23B9 +:10BBF000DA554BF3B6A7DCA0E10CB26FDA3BBB67BA +:10BC0000019ECE2DC3F0E441EB3DCBE5C59C867E85 +:10BC1000BC5755A811768E1ABE1799F2CD9C6514A3 +:10BC20006ABDC8743C9B987D1296022F025F0E97E6 +:10BC3000876468A2F3B3CED2DA9DC0CFFE067A1D28 +:10BC4000C8B9FAF978FF11E9DF06FA507F7522BB0F +:10BC500029989A82F33DB1F59AD7C03F3DB781E963 +:10BC6000FB055B3F14703FA8DE9743FB2FA8C4275A +:10BC70002AC9DC9561E758D89F1291A82ACCA787DA +:10BC8000809D10A6F2C70807BDDF7FB6FD3AB70357 +:10BC9000DB07C1781E165F8F9BAF27DF4FD793401E +:10BCA0004E5FC5C7BDEDBE0F0F4C02F8AF64265204 +:10BCB00041F86DC169984781767EF3F816F447E143 +:10BCC000B9D3CDEE437B2AFBF0DE9195BF833A0FCB +:10BCD00074BB2DF5CC7866DF9BF9E9A03CC72BEB54 +:10BCE000F77C0BBF1AEBE8B912F7770F7BEF9C10CC +:10BCF0004AB74E7C065465EFC446F477C9EBA1DE23 +:10BD0000188F5B013CE81CFD870A80CF3AAE2FDC20 +:10BD10005C4ED05EBD39AF17F58539CD5C5F90FCC8 +:10BD2000ADC06453B7A693B506FD0143FCE188B1ED +:10BD300099EB0BBAFCE772BBCED7DB867215F40326 +:10BD4000835CADD5985C2DF031B95ED746C75139CB +:10BD5000325719F51226C7D54D5C7FE07238938FA4 +:10BD60009BD5C6E45526E8115E083FD0502EE35916 +:10BD70005E765C6F1956CEE46566E7E328D75E0110 +:10BD8000A7CB04E01B4C5E8EF8CDAB1A80C9473FB1 +:10BD900077513EFD142FF729543FCB88EB676B4456 +:10BDA0007ECE44987E88B1F5749E8FF1FAFAF71D25 +:10BDB0007C7E8F1FCAF806F0D707C345E36D06BA2D +:10BDC00045AF27CDE757B273FAFC06764EEDF1CFBB +:10BDD000DB69339C3F34BB99BDD9ACE35543D407F1 +:10BDE000FDE2FD40E4E3EC7DA976FE1E946E5F7DEE +:10BDF0002795FB3538FE2493273A1FF29080B79C95 +:10BE0000C2F7586427F26B8DDA4BB0B663E1A6DC5B +:10BE10008540EFE1AB2B61FEEB27FD15E32E0A9287 +:10BE2000D88B7F073B93C1E14BF175CFF457991D38 +:10BE3000DA2B26BC2733D123E13C7B24920AF07411 +:10BE400085D9FB84AE8972C2FA177A18DF943DEC6B +:10BE50001ED1FA493BF17E6352F92C11CD96409EDA +:10BE6000EAF2B613F6793221D5EE59AD1AF2FD4851 +:10BE7000D086FC95A0DD19E6BFFFA295C9E837EC96 +:10BE8000B4879DB01F1B2AF9BE2ACE6EB88FFEA5BF +:10BE9000F785C203F6B93D2046E07E793BB554C72D +:10BEA00032BF0EFE7ECE096ABF1BCF292EF3881C3F +:10BEB0004EAA08F189056D0CBFD64F92711E6BC753 +:10BEC0006777DB0A8DFC97C12998CAE0B476D28BDC +:10BED000885FE73BBF790D774E3E6638473CBEF939 +:10BEE000A1228073FC9D96C090F717E635FC66F2A0 +:10BEF0008E04E70303E56047B9C10E8C5C6F3C67B5 +:10BF0000F9770FB3AB431EB3FF0EF8AB1D8D8B4813 +:10BF10002EF897F65C12F1A2FF7E313BAF5DC0CFE9 +:10BF20006B4FEEB806DF53184BD1CA9E60DFDF6F50 +:10BF300034BFA7F0FE830FE532BF46C414E7B160FB +:10BF4000E73363D8BB661AFF9D0CA26655B177AF85 +:10BF5000514EBFE8D71CF8EE5C10F9900CBF5301AE +:10BF6000FE76A0E062B8D7DF83A91BE8B778F07B44 +:10BF70006E19540D43BB8B0431CD26F598FA481841 +:10BF8000D35CD283691ED8B9C52017FA31558922EE +:10BF90001203DF2F227ECC979020A612EC5B66FC6A +:10BFA0005C42DAE5C4F80B38BF00BAD7CF29F4F306 +:10BFB000FD199EDA4E0F327BF379C5524F609D0713 +:10BFC000E11F45BE3D87B3F0C33F1ED303F77B5649 +:10BFD000AC63F74B74BE8E760DEDFFD10C2607B423 +:10BFE000BB05E45FAB53AFBA14E1D8693F6D3C6F5A +:10BFF000204E6709FCFE8BDEEF1CEE5F98C3E51F49 +:10C00000B8B7D9FD3B3FDEFF99037E0643391928B7 +:10C0100067F7AAF57EC4D42923873ADF33B4C778FB +:10C02000E45A8BFE7F4EB96DC9CFB5B6FF8C4E2852 +:10C030003BEE877BF452359F9D3331B94D1149C595 +:10C04000766D8EB7D10E0B5F1630C2E510C77F5DDF +:10C050009ECCB5F8F5ADE95C89D385A51F2AF9D248 +:10C06000E15E04BE6962A06BFDDD5BFD77D2160464 +:10C0700042720E6BE6C3773DF8BCC3646B4D0E4D48 +:10C08000DF83BCC19F7FD81BFAADC7608728817A48 +:10C0900091BFFF8774388FD3E165B6CE6AE06F2712 +:10C0A00042C40FF6C30252BF1EF431F2AA0DF9DBEF +:10C0B0000574DE7205D86F44133330AFC1EFF97CDD +:10C0C000D0C8EEE51CE7EF56EFE4EF249DE2EF5415 +:10C0D0008FEDBAE32AC08393FCBD6A9DFEF571C75C +:10C0E000F6A4CE06B93FB6E7923AA8377697230A68 +:10C0F000702EDBD71E04BF10BCCF9242C7C9A3E38A +:10C100003933808F1094B7A73A5322ABE93C4F756F +:10C11000D9902F7F5C2EE23B23F0CCA58DCF2F2D25 +:10C1200003FAF9FB8DA0879CE47C447FEFF154B5C2 +:10C130008AF6F10B7BD608702FE1D46C15D77D2AD7 +:10C14000A7273F83C2C7E765F1E525BB1DD1223A8A +:10C150008F858FBC5E540BFCAF28BC30D13973BACD +:10C1600097F1BF534F108C873BE5E2BF4FE4ECF1F2 +:10C170001AFDACA95EC164179EF2F0DF39CA3B47D5 +:10C180003D1E5F4EDC3D5E46F73D5E388FBA37F5AB +:10C19000C7787FEDF813EC9CE285CD75F9E08F1A36 +:10C1A000EE55D939FE9E9F60DC38AC03EC683A3F0F +:10C1B00015E6776FEA5B27C1FF40DBE1FD0CBDDDD3 +:10C1C000F13D75AC7E17ADEF45B8136F05E0038305 +:10C1D0003BD9CDF884AE3F2E8A64E3EF2DC4CB4526 +:10C1E0002C8729BA28FCC7EEBE1ACFB5467B3398F8 +:10C1F0007C507AC6CCC4F987F3611D7B2E09E58398 +:10C200001FEFB8FE7B4E52381FE030C3131AED35D6 +:10C21000F0F7F7DF7E0AF97B9958FFE7BB002FF7AD +:10C22000B2DF1FB9E3CD8DA2917F4CF432FFFABD8E +:10C23000A94BBD701E757CE09D9C308BF7D9CFDE7D +:10C24000615DC469EF7837B59F283CDEDFFD032CC4 +:10C250003F3EF08E4D0FC693BDBFFBF90C486B7986 +:10C260003C3F895C83F445E1D2E64C20AF06EE45C5 +:10C2700045D87DB733027F7FF43E1D6EF5F24CD377 +:10C280007915A3EFBCAD8587505F8E24BE276795D7 +:10C29000F7D6F764CF750FF828A7D363FC9D92A556 +:10C2A0009ED0B7BD09E4486DC7927C80732DDCA990 +:10C2B000C33887AF5E0EF636DE3761EFC946114EE2 +:10C2C000FA7BB1643C2B4F67F9C5DE2BD7804E74E7 +:10C2D0005C7F7F56FB1A2B2F64E56DBCFC254F70ED +:10C2E0002E1B9FBD2744B9623AFC2E85CEFF92AF2C +:10C2F000DFFCBB143F029E3C01FB5B8AFD49B4BFDF +:10C30000B1FF7A7F3ABFF997FB71FEF7F6A3F361AD +:10C31000A04B08D9237EFF98FF0EF8FDB3EDC9AC02 +:10C3200002133FFF6473712B9C037DCCDF0F71748C +:10C33000AE2220976EDEB4D1F4BB26D677BD9A78B4 +:10C340003C895C4CE9CC40CFFBBD4C8FDECFF92162 +:10C35000FCB90DEFF9C05F673686DCA0FD378ABFF8 +:10C36000F35E46C2A85F8D213D9896935E4CC791BF +:10C370007E4CF198B4185C7D7E1B7FAFB70A16BF68 +:10C38000D819BA1F42753F75849E017C82777B0560 +:10C390001BE8454B27C3FC7FEE55F4DFF52496DF01 +:10C3A0004B8BFF0E880A7ACD0CDF507A0D51A4D347 +:10C3B00003F11B45F8EEEF0B5EEC37D9EFBF2DB75D +:10C3C000BC7FC2EE11EB7058427A300EE285AD2B85 +:10C3D0005E1E4DE1BF70B707E5C1C8ADCDF8FB5F8C +:10C3E0000B496F36DC2F1DC9DF93205DECF785F418 +:10C3F00077224677394CEFD42DB1FCFED022FE7B5C +:10C40000618B2CDFF5FB9B1DF021411C81F5FEE7C4 +:10C410003BDE24EF369527FE1D18EBFDCFDD3D22D8 +:10C42000C6F7AC80782121CEF746EFA87798F1AB1C +:10C43000E7D212C3FB4E4D829FD9D39E94C083C2D4 +:10C44000E071462A0CBFF60842C238B26FA6897C5A +:10C450001F9AC995B49FA6C59202F666532405CFCC +:10C46000419B1466175EE0A971829D4ED2457C47C0 +:10C470006E9A6D0AC697CB4BA48BE0DCF3D0F685A1 +:10C48000BD707FA1C927A19FF68274760E4A7244BF +:10C490007C1FA059D99B3E07F6C9CDCE1947282449 +:10C4A0000271F007BA6F1721DF44CD96E1308E108C +:10C4B000EAC57B373912E1E7AF33C653FC2BE0F80E +:10C4C00020914EBC7F3C75C93117C8F502BEEF13F1 +:10C4D000D20A99DF98EFE7B686A3E980A72F75B750 +:10C4E000FE761AEDCF1E9130AEB5ECF3A637A6D18D +:10C4F000F1FABB658C67D5E190BF5232DD9FCDBBB1 +:10C50000D59C972DF788256228A7F9517C7C78C0A7 +:10C51000296A8CABCA0A3067A1E246FCB8284D20D4 +:10C52000786EC3F3A3214FF174973D5C03EF61EE86 +:10C53000FA93807E8783DDF30A304EFF995001E045 +:10C54000B78E0FD6FDFB1BD7872806B8F8FD6017FE +:10C550001CD659F1A7B99194823FDA193994722106 +:10C56000ECE3613BBE23D5C2F56F89FF4EAF8E2F42 +:10C57000D6B4C582772D9F5F8378D74FF16EFB10BD +:10C580007827292AEA09F63CE207F2B767F5E62A96 +:10C59000B4DD854FC97E3705D9B4C7CAD3409FB92A +:10C5A000F0F9EBF09E2CC00BDF796C904BC1EE776D +:10C5B000346495C2EF1D4D7BCC8DF878D6CDCE7FFF +:10C5C000A486543F94377557F954035EB7362AA5AD +:10C5D0005229BC6FEA2C85DF456A4DF23BCC23D251 +:10C5E000C520F897646EFFCF4B63F39D97968AE959 +:10C5F000CD3C7F9FA4CD84F9DF47F107E2050EDC37 +:10C60000CAF077458E13EF3DAF78A978F8507140A6 +:10C610003B1B7DA500B7ADB7D6A2DFA37AF921D722 +:10C62000E540E71EA702F868F38EBC770AE0FBCB73 +:10C6300076BCF7D5E4A952E718FAB37927A25FC907 +:10C64000266AB96014DD9976E4722907F045DB02A9 +:10C6500092A869C373974B943FEDF268B9022DEF2E +:10C66000D8F03CCB0FD3B608B4FC071B7EC1EA8FD1 +:10C67000D072E1973F7EB4E13F5879A9B605F20F39 +:10C680006CF835CB836E41F5984737FCEE72B82FC6 +:10C69000DD64F7CF02FFCE8FE9FCCBE9FC7B78BAF3 +:10C6A000278DF973F4F2BDF09DC27B1F4FADE54FAE +:10C6B000F2764F2729FF292FDF9FA4FF9FF376D122 +:10C6C00024ED0FF2768792B47F91B73B9CA4FC6572 +:10C6D0005EFE4A92FE7FC5DBF52669FF5BDEEED586 +:10C6E00024EDFFC0DB1D4952FE062F7FD3D2FF5B36 +:10C6F000BC7E1FFF9EE7697B43A37897D7CD5EF68C +:10C700002CF3B4A1FEBEB5BE12F1BF6902D33374DF +:10C710007CCF83784D9A2F52585C5591C2ECB85F0C +:10C72000F0FEAB97976C00BC5BF14B1BCA532A47DA +:10C73000F0F774B5E52CEE65C54BEC3EC88AE51202 +:10C74000BECFAEE3E32F2CF3DFC6E7D7CCE7FB5C2D +:10C750005A113F6FF195CE30C67B2AE6BC93D213B7 +:10C7600084EC346731F952B6BCC6390AE407952F18 +:10C77000C0375BDC7214EED1B72812963767D52824 +:10C7800050AE2912CA9F96AC1AE71CF4E764A07F4A +:10C79000A280C7ED352B12DEE397D2A762F9B4C7AA +:10C7A0006628C0479B497F3ABCCFA7AD94F0BCF642 +:10C7B000407D0D7E2F48FF281DF8F38174B6AE43EF +:10C7C0009E175DF08EAB749B88F26224C08F8E5BE7 +:10C7D000B4528CA8B4CA21658508F9079A99BCA2FD +:10C7E0007F9EF186771477DD5EF532C4EF34AD932A +:10C7F000F077B6E14F32C88312FE3BA5994A8649CD +:10C800005EDDC7FDB89ACF8971782512F1197FBF17 +:10C810003253E1E769B619F88E5971D82C9F0ADBBB +:10C82000CCEFD81458E493555E8DA8A7FCD150DF07 +:10C83000E1534CF9CFD3F87B167EE2077D66C5E362 +:10C840002B2E8750769D5FEBF2E5BF005F71521291 +:10C8500000800000000000001F8B080000000000A6 +:10C86000000BDD7D0B7854D5B5F03E67CE3C3349E7 +:10C8700066263393C97B1220040838811023BE2614 +:10C88000216044B403A2E2A338E11920C9044A2B71 +:10C8900056BC4C48C440B186DB8840810E2A8AF5DC +:10C8A000D1A1458D18EC808878ABBDD1D25ED4D6AD +:10C8B0008EC855501EA3B648BDB5FC7BADBD7732C2 +:10C8C000E724516CFDEEFDBE3FFDEC619FBDCF7EC8 +:10C8D000ACBDDE6BED3DE7CFD3BF2B09695D19BD64 +:10C8E00062A89E902D2B4DC314FA6CFD72DC4C5245 +:10C8F0004E4822D5E27F482264F54ADB3065182194 +:10C90000E779FB621B7DE92264AB129E4E9CF41911 +:10C9100051484B2121FB96C904CA4BB34C11236DDE +:10C92000B2F4D5DF5D3D1CCA4B641FF1F67DAF7DCF +:10C930003EBAD2330CC67F259D60BFFAA034ECD836 +:10C9400038FA6F25E809A41232A443391A3711FCCA +:10C950003B4FFF2B6CA7E592BEB25E1FB0D9AC84F3 +:10C960001490A476743E8AA6AC771DB6074BA17FBF +:10C9700005FBD7CE23AF99AE3FA95FA3C7A62AAFC9 +:10C98000969A4BC810FAA47305F8845D7264075D2B +:10C9900067EEF2BB261CCB2024E7A0A58DC01A3A77 +:10C9A0001E24C44D880EC6A6EB5624BF97E808691E +:10C9B0002B2CF349F479E8690B83539E15E16490BD +:10C9C0007C99D7D0A7510ED8A07FFAE787FEEFCD8C +:10C9D000B36C5F5B08C5A009E090BB9376984D8B64 +:10C9E000E1DC35FEA1749F28B8C904A8EF69F7D32C +:10C9F000F5EF947ACBB5508E460CAC3D2131F8BFA3 +:10CA00005DB2C4EB895FF110F29424F1FA91B5356F +:10CA1000B9B4BD621BA5F80899DD31BA5D7F39D480 +:10CA2000CBE27B3FA9A4EB83F17819E0F2C4015E6D +:10CA30001FBEB4BD86CE6797418C4FC2D07E972C67 +:10CA4000B372B8BCBDE632DA5F35FF3E9CBFC69F0D +:10CA50008BF3B9466727A4D97665BBF592BEF9B6C4 +:10CA6000D827B5B728849CF2C6D3E87691C6EDC71F +:10CA7000DC8476B57A6630007024C44702A309F9D5 +:10CA80006FC98BF822F64FBFBB2A9C435F9D39F8D4 +:10CA9000455A297D8674F18329147E8D5D4193BEAC +:10CAA00088C259EF0FE714F67DD7B87B1A095238C0 +:10CAB00085BACBF039C0778714F99FFACE64B88075 +:10CAC000F14EC5DE6C7A925635EA82EDD621D89EBB +:10CAD000B0FD1F787DE2FB534FBE79238C77DA1BC4 +:10CAE000774F01BC8C51B80CF09D68DFD4554500E0 +:10CAF000EFFF62F1AFB48D27E4263BA333A234FBF2 +:10CB0000A07DD4D461F3D17AB3BE23E0A3EDE9567E +:10CB100046E4CABEE72ADB506CAF7DAFA59FA8896B +:10CB2000644CA5781D6E507C3B0894C329636879DA +:10CB30005DA332AE854E6955D91FC69642F9192BB1 +:10CB400031D2726BC3014F29D091CF40287B21EBAA +:10CB50002E8966011DB7351A663E42E7138D2DF505 +:10CB6000CC2BEDEBBFC54E098FCE7FCDCB94CE2E17 +:10CB7000A24F7DD42EC1F7C314027468B6D37DA62C +:10CB800065739683840BA19D751DD0E31A7DB0B6A5 +:10CB90001ADA65C964071DD73C6C466D359D87C799 +:10CBA000254B3A9C47CD91F9B4BED56600CE467E62 +:10CBB0006B9FBD13E0F484E26B063A7CC26AB585D4 +:10CBC0006905E58D7EA05B6598330265A38E3447C9 +:10CBD000E9FC72CA48206AED9BE76F397FFCADCD56 +:10CBE00080F35D678E4EABA2FD5896CAB6301D6FBE +:10CBF0004DE3869EC9749C9F363EFB460B7DBFD697 +:10CC0000AD109887D5A9C40C69148FAFA573A4F390 +:10CC10007EAA256003FE997029E4215A6F196A20C3 +:10CC2000DE243E682DA5E524FE94E154FC66FAFD61 +:10CC3000497BF0D7363AFEB8D70F9BE07BCF7859C7 +:10CC400006B2892A6C9FD3CAD5FDD82E53F7E3A824 +:10CC500051D73BA7AAEBDD33D4F59EDBD4E5ECB985 +:10CC6000EA722DE0DB786848E75C41D7C1AA8825E5 +:10CC7000FEC94A9286F0790BE06F29967D001F73FA +:10CC8000E323C7E7D3FA1CE02774FE640C89ECA009 +:10CC9000FBB93FFF87DE3885B3D1D1ECB597F68776 +:10CCA000474E9EE91AD82FEB50C546687BEB1F4FC5 +:10CCB0007C09FD5B4952BB42808F3F0EFB0B7F1E00 +:10CCC0003A9F54F88717E0DDFCE7BB41EEBDA1F3C6 +:10CCD00001BC731A151CFFBE19DE88AE903527B44F +:10CCE0007D1A6F9F665AD7A31B439F7F5CB34497FF +:10CCF000D61FAE6ED22C015D52FC407941EA08CAC3 +:10CD00008B7B65520F7843C995407F36F880F29946 +:10CD1000890E03E2CDE71C7F28A6C950EFB6B13ECD +:10CD20000D5973CD40CFF71C64F87F8F81F5D3DBAD +:10CD30009F17074511047C52679755FD6CB0F1367B +:10CD4000BCECB2B3F2AE038E6B802E37CC708C0588 +:10CD50003C31CA2408FDA5E79AFC23E8FACCAF1AB7 +:10CD6000C212ED345D2107F40EDADE426E0FD07987 +:10CD70006C3A6409EBE87BF3BC7FB711E01B7636B5 +:10CD8000EF5DAB7CBF033E90A853108E6657876D56 +:10CD90006C295B4398CECF01FFA0FCB16A58A70D68 +:10CDA000F6D35CD581F2DB5CD6D10170DA3455461E +:10CDB0007DC23157467C36E745DF184ADFEBE7C9CD +:10CDC00036E8CF4105BB8176F293DC8E4000FAA5B0 +:10CDD00030972B18AA40BFB8423A4E0687ABD3B95A +:10CDE000FB0E89F69301FD8D61ED014E760EA75283 +:10CDF000BB17F1D3C9FBCD184ADB8F61FDB455F4E5 +:10CE0000F523F671532D89C0FCC4B8A29FDEFE89BC +:10CE10005F02BEAAFF0D851BDD2729DF8493BB6758 +:10CE20001189180B013E81E6ED48D756F210D08BE0 +:10CE300033B71AF028FBD0E6E9F218F8CE82E3E81F +:10CE4000E79108E071B6424C5738407F09201CB585 +:10CE5000F49A75A0E37A4A23BDFBA2A5DF2C85B422 +:10CE6000EB1CFDE938CBE9AC2E1E33003D6BE82509 +:10CE7000EB50E2FB80F45ABADE9672BA0CE04292B2 +:10CE8000DBEBBEBEACD345DF980C9B9549E50405B2 +:10CE90007DBE663C42FE6184B24464EFF921C0F776 +:10CEA000ED8C7F102AAF28B1EE1A6B9B68053A5DB6 +:10CEB0004210BFAA9F5B77CB6F687F6787196C2092 +:10CEC00057F20E75F4807C245DC1E1B00F5B94E0F5 +:10CED000CF5268FD96239904F8F61A339909F8ADF4 +:10CEE000703CD7CA97164E375E90739E7FFE29F42A +:10CEF000C1E850F7281BA5BD96F5B14326D7FFA280 +:10CF00009E4586A19E957BA0A7C50AE377F8DB4DD9 +:10CF100014BEE6D759FB302D8715805F4301D0E161 +:10CF2000FEBCF90827E56D23013C1DADF347A04C7D +:10CF3000DE3113E0BF3B9FB9ADDE0BFCC73DC50B37 +:10CF40007CE8DF81DE29BC3A38DD6BD7AF18FC41C5 +:10CF5000D027B4EFD7027C713F03C7EBE83E8E7E4B +:10CF6000D840D6D2CA1279767B21D0C51ACA7F6939 +:10CF7000ED6C9DB7E94752DFFE3C61AE8AD8C1EE49 +:10CF800058692241235DD73989042971E639DFAC1C +:10CF900002FE934F6212C8D9FC66AAF0025E2DB35E +:10CFA000906012BEE79E53B0FD13667FC4CEF9BFFA +:10CFB00089F2013DFB2779C21120754EC6A3407F3F +:10CFC000D13F69790FF80671D6F87BED8D22C05FED +:10CFD0002AF7E9784FF1F5EB290CF563E97F56392B +:10CFE000661CD3BFFD2F397C14933506FC52B1BEAD +:10CFF0007604F98B4D3999DCCE1461F2863490C8F1 +:10D000003089C105CBDFB3613987F25FE358D4FBC8 +:10D01000C34698671AB33F88DFEF75BA815E08028E +:10D0200039D744DA4DB41D623BA5B72CD26346BD57 +:10D03000F900F1023D5088D93F4841964500AE5B6A +:10D04000A8884EA603F12CB2B17D5296EBD05E1AA1 +:10D05000F59219E7A36F261133E84330370A6F655D +:10D06000198928606F2D3760BB229B17BF339066EC +:10D07000D4679FFAF2DD6CE0D39683541FBB08F6A9 +:10D0800059463E65B1A8E98F62287E17E7F8B17569 +:10D09000A50DF7B9D73E0B1EE6FB1C6F017991BFBA +:10D0A000CCA1DA5FD12EF75C0E098E4BEE3782FDF4 +:10D0B000E50E3D209152A8CFC7FAAD2BBD5FD37FBF +:10D0C000D120FD67211E0DDE7F2ED66F8D1DB65F30 +:10D0D0004741B12571C01EF0F6E9D75A38E72E5303 +:10D0E000F3E58BBAD4650117B3DEEF9C46616EFEA3 +:10D0F000BEECDB4EFBBBF888BA5D6DE1EFD1BEED57 +:10D100006B1F735E0FEDA9FDBD9DBEBDF4B8BA7D6A +:10D11000A0EA653BD0715F7B36BF2BCFA9DB69F7F7 +:10D12000473B5F3A2FD70D49F39A6832AAEA67D690 +:10D13000F59B97EBA6A4795DE551B70FB60C3CAF14 +:10D140006B4A8C5F392FD1EE3B9517D64EBB8EEBD9 +:10D150006B8D83C09DB5BF69E685F57B6BFD57B7C9 +:10D16000BB7DB9769C30F2875AC93FCE41EB67C38D +:10D170002BD017AD16D47BB5F812E1F26902E87333 +:10D18000F43935D53FC1419F954077F46978FC0F5C +:10D19000B7007F39F4F4C84CE0EB3920E7109ECC9F +:10D1A000AFB0ABC1837E8500A7532A4FDA805FEC16 +:10D1B000DA49BF4B63F34AD69F321A985D6123095F +:10D1C000A467A12F39884D62F638D377061B47DB59 +:10D1D000FFDDDC1E98B37C22799FD2E1B3065B951C +:10D1E00002F6D93609F58139357E5D2AC58F09EDFC +:10D1F00012FA8DE6DCF9BD71C0572E39E6ED8AD3FF +:10D20000F77322761F0CDBD443FC118A5799BA2599 +:10D210006577D3E703FBA9FEC3CB4B00DFAC7E2FC2 +:10D22000D81B753023DACF497D73990DF8E677ADB9 +:10D230007EE09B7533FC6FE17AFF4EB512DA6E1E0D +:10D240005B3A79AE739AC14BF58CBADBBC95A0F70B +:10D25000D445CD7E7C9A8862A1EBA8A3FA183C3312 +:10D260000D4431C3D3424CF0AC58C5F4AFB4CA80BE +:10D27000A18E8E5FD7FDD85FE1BB054A6C1FD32717 +:10D2800023B8EEBAEE57FF06FADA3C7FC000FC6224 +:10D29000D44E03D349393E8C8EAACBC00F92CB65B6 +:10D2A000317579DC2175F92D07C38B3D526414EC7F +:10D2B000CF1E2AE0C02E0E3F654479B17FAF11F733 +:10D2C00067F1C796EDE07F9AB8D88A7CFDE39F9B13 +:10D2D000D11FB5478E3E0DE5F0D3296857EF7B7B14 +:10D2E0004F8544CB8B7E912A43FD0B5FEA10CEB075 +:10D2F0001C3D7DBFF8E911DBD7D2F78BC7452B6CFE +:10D30000F4FDB32309E9817A253206D6F7EC3F74A0 +:10D31000D87FE27163E4218A0F1F3FFFD8D377D112 +:10D32000F13F7E3CC721D17DB914E4016D37E16145 +:10D330009305EC8C091F3F3904F8C5E29D46D5BA28 +:10D34000B63A24AE3778D300DF06F3271E5DF31814 +:10D350007E5F72FC08E2DB1E7D58B6C0FAD730FC57 +:10D36000D2B67FC4C1E48D98077C5748F7E7CC0953 +:10D37000CBED7E5A1EBE510DDF111175F949079391 +:10D38000EFB349D2FB42E8AF68B507F4D4ED04F53A +:10D390009992E37FBCA510F46823D31FB4F3788679 +:10D3A000CFE3E73FA7FD30FEA063FA335D31A5C7A9 +:10D3B000C51C8F5F9098FE4AFF96E550BC5D0C82BD +:10D3C000BFA8EFFD62CD3C44FF4B1C8C6F38B95DAC +:10D3D0009D785D87FBF1D1CAFA71C786F59FCF07AB +:10D3E0002B9B47D4E8FBCAF3372E399845BF6BD83F +:10D3F000E5423B51BC6F78FC25F7ADF4FDC99D8A31 +:10D400000F54D7869B1FFDF10468F7B82E0AF385E9 +:10D410007AF0479E8CBE9C06EDE66FB18FD525ED68 +:10D42000C3828DDF1F5193C40FBF293D08FA6DE001 +:10D43000F6ED73953D937300BF374A3E68B6387A70 +:10D44000C3F5D782AEB245E71B46EB2B1412D08D45 +:10D4500045D37B063C1B763D73309BD687F68EAF5B +:10D460008075AD9503D78C06FCDFA6473F96162E38 +:10D47000A7F97ED3EF6332FD7EED8DD6FA8815FBDA +:10D480003D00E5FD250FE9E2E067394EF9137B7FAA +:10D4900044A63479BCFB9E31E04FDCA3B7B6039EB3 +:10D4A000EF4965FB107E4A877C9EC4D83A2670BF40 +:10D4B000F1E23F751A14FA3C7E7C555A15A323E419 +:10D4C0002FC0949D747DF50F8F46BA5BB0514D27E8 +:10D4D000A29D98EFC288BA5E8B1F6919C2DF404ACD +:10D4E00092F14CDB2E636AD80074D5B09CF2E32431 +:10D4F000FDA7E1588701F426ED38A00112B1AF3A3B +:10D50000C44FE2C5F59AD97AA9CA6AA2EBFD08FE12 +:10D51000C5FCDE12D8E58B245C22593C92D47829D4 +:10D520003C174F27B5F0DC23C57EACE3FC0CFDEFC8 +:10D530004FA5203F3B698B3FFA53C0BF27F37C6167 +:10D540005A95CDFD7227BDB134077D9E01BA00FC0E +:10D55000B3B1F2A26ECACF297D7F7CCA807CBD2583 +:10D56000FA521AECD7C9A7CDB24CF7E5E35D19D54D +:10D57000E0CF3919FD4D1AACEBA3684635F8E50646 +:10D58000E3375A3E25E4F97BF0CF4B287FCEF08F6E +:10D59000C900F8B66580324E32339ACB9A07A07F25 +:10D5A000F19DD3D05CE605BEF15DAB0FE8F3D20C84 +:10D5B0002FBEAF93587FF0E7A7F59F1ECA7808F6F5 +:10D5C000FFD0BEE27490F39F126F3AF0DF29AEC035 +:10D5D0001519948F78AA7BFC3AF0FF4D21BE56FABC +:10D5E000CDFB3ADF0F6C14CE7309953BF02C0F1A6C +:10D5F000D05FD2E6C279CD51484CA1783A07E4E237 +:10D60000182C239CE76C9122AD741E73D7A9D739CF +:10D61000BFD3D8B7BFF4BF8584324620A02D49EDD3 +:10D6200068FF0B41FE51F82D3291580AED77D12356 +:10D63000EAEF169318CEA7E1C9F3C681E0F8570EBA +:10D64000C7292EFF4D192AFEA547FEB59804AE80C6 +:10D65000711773393BCFB80FE711BAF3CE1173A925 +:10D66000DE7066F95D23E666801F907D47364A8846 +:10D670007F8B6B482C8FCE6B71B7141B0D7AC061FA +:10D68000B63FA27FB28DB5BB85EB29F3283C40EEB7 +:10D690004F78520AA7523B669E899A60C03FF8BAFB +:10D6A000A03E9D96EB4907AEA791C4711EDFE3FB38 +:10D6B00007112980E75F0FB37D9B50BF5D07933A49 +:10D6C000B4AF221DF0EF33E2C3FDA3FA04313BFAFD +:10D6D000E307C0DB9F049FFA2DEA327924A95C049A +:10D6E000F0A4E5243837ED3E6FF40F00DF077AE54C +:10D6F0004964C4B4D1A49FBEFA2E87FF0337CCCFB0 +:10D7000002FABF1FF4B76CDE4125F04B22FC113149 +:10D7100013EDDF328EA8FC13542FC272C74F5EB9CF +:10D720007A632E211BF441F4F3CFD1050E4248EA6F +:10D73000842BD809F83A47F6E72BC807FCC568A739 +:10D740002E67FBF1E0D8E611CD03D8A762FE1BA43B +:10D75000684C067EF03C93EFA9E5097D3089BE9EBA +:10D76000E6FC2D7D7FFC600EE0CD3312FAD3374905 +:10D77000A44DA270F6D06D0139B0497AEF20C88D62 +:10D780004D577B492BAD2FDF3D6DC9CB68E35A7CEC +:10D79000109F68DC5DA56BB4E2FA999E99D2BC5DDE +:10D7A000A6F599B7978C05FAA0EBBE7D3A7DFF2BC5 +:10D7B000BEDF5956860F9E55E1C2A5E04FDD1F58CA +:10D7C000F232D0F5680BFAAD3229AC521DF86C0775 +:10D7D000FDD1435A2468F7401AEBDF25EB6E9F0614 +:10D7E000E5B1ACEC5821F91F42245E8FFD671AA900 +:10D7F000C9E060EF410FA6DDF977617D04F72D7375 +:10D80000627319F49739843D9D86582EF4F39AD8A3 +:10D81000EFEE2C19F8ED322E3797EDAACA74D0EF3F +:10D820005F3B6952800FBEE6117A5CCC0A7A1C1904 +:10D830005AC2DA73F9B4AC6C6226E0AF335FDDEE46 +:10D840008CDE9F3E0EF8FC1B3A8CB7FCC5EA4FB746 +:10D85000D376971AD83AB4FBF8A70CA6D785CE4949 +:10D86000249264B787669E45FD38744E51BD3FB91A +:10D87000D2442249767B43FDFEC9D0AE91F4AC067A +:10D88000BC6A8CA69048129E5F6A19785C81DFA101 +:10D89000733A121E87E89B0BFEC5D7F489D5F300B7 +:10D8A0009FF64AE8070A517B389C3CAF7319249CC9 +:10D8B00031D03CDDEAF7743DAA72D7E7D88E54C662 +:10D8C000D3609CD3B6789A9DAF0FDA09B97526223A +:10D8D00087F517617C8FC92FF0CF58997E3A0DF6E6 +:10D8E0005749A44D4FEDEB57D4437F8EA4759E9EB0 +:10D8F000692031DC97048E0B700B0F276473F727B8 +:10D90000062FC8F1EE7D0837812FC9F00B27C77BA2 +:10D910005A7B6232A5F9CC4ECBDAD21114F5F673EC +:10D92000FA0E5BD7827FD1AD9355F49E52DE4BFF4A +:10D93000C86E1E80E813FA2F53D7429CB9B7CCDBD0 +:10D94000F77E1F4E9B02F5E5A5ECFBC2CEF4FF5817 +:10D950000532887430BD5F49E4075293CA264DD919 +:10D960004ACBA393CA364DBD5353EFD1947359FBA1 +:10D9700093A9B17C9D8FDAB99D195314CA7F4E6665 +:10D98000C566514B94ACD3B9A7D4D072633993AB6D +:10D990004DDD920F7D6E1C7E4D3EA6EF597D71C30D +:10D9A0009C528043CF41E00F0D5D924DA274608D7B +:10D9B000EE8A6119BEF3267D1795F0BB86E87BF8E9 +:10D9C000DDA0FD97C848E76B4B8EB276D10F517E34 +:10D9D000AF6EABC3B8B888FBEA48C09F23F5C57DDE +:10D9E000059F3C9DE57F4966786D4BB68342D06FBD +:10D9F00092BF45B47F6774F7EF413D4859F6490B34 +:10DA0000E8A17F6AFC703CE865EF7079B0418A8CD0 +:10DA100080713793E0089077DF6D1CB64FA6EDDE7E +:10DA2000D5C7B7426C6B71E7A8290A6DF76E6A3CDF +:10DA30004FA23CA6D15981F07CD715DF0AF07CC9F2 +:10DA400079312BE7C5F3645A5ED259C7DA0F8B6F71 +:10DA500085F226E7B5AC3C3A9EA7B38189731DC217 +:10DA60007F876D607A9EED647C44CCAFABC8FF5D70 +:10DA700027ACA781C991AD546F34517E396BD14722 +:10DA80004FEDA07098F5C314E4633B4E5E3F85E90B +:10DA9000D5E18052017E53F687720EF9B5827A463F +:10DAA00016C83647DF7EA4E6F778510E8C6CDE058B +:10DAB000FA42E6AC529403A519FE0330AE78CECB01 +:10DAC000A64F0ACF034E1BE3CB3A19E3C89977A5BB +:10DAD000A25E75BF99AD87D20DEEAF95EFC71D4E13 +:10DAE00026B7EE7032BBED868C49D8CFDB927F93A0 +:10DAF00089C2FD6D3D099B81CF2EB4A01E7CEB76C3 +:10DB0000CA3728DFEEE4F3EE5C9F158138F8AD12DA +:10DB100009005F11FCA3D3EECF7224D9139D65B425 +:10DB20006CEDB31F3BA7F9B32C4E78BA6588970804 +:10DB3000BED459C8BE13F228B3958D9379FF888758 +:10DB4000601D290AF3FBCC9B59FC500BCAF5E9B8C0 +:10DB50007EE2F76781FFE0D8C22219FC41627FDED6 +:10DB60002AF2AF87F5DCC2FDE9629FC47E1E7032E7 +:10DB70007B788E8EEA0574BDFB5C415C3FD513C695 +:10DB800070BF13EA0907404627C19728F1F1F0FE5C +:10DB9000FF23383DFB6DC0A97139E517F205F00B85 +:10DBA0000EBF0D524C9FC9F805DAC1F01EE4CEA697 +:10DBB0008CE07F3893F25266DDD5887AA19857CAF7 +:10DBC0001DCFD5DE44FAD399566F3B0CFBE5EAD363 +:10DBD0002F7DC27FC8C779F76D13C60BDE35449120 +:10DBE0006FBE4BED9816E02F3CDE5DF1C3C5AF81F3 +:10DBF0001D27FA9DE0D2617F6B247F16AC6F0DDD8F +:10DC00007713CC7F9A01F57821573BED914D906FBA +:10DC1000D079432EE61B9C212CAF23BC3C05DB5D59 +:10DC20002A1F25E08F4C5C62C37833C513ACEFBC70 +:10DC3000B918F33E283E84CD504FF109F2E33ACBB8 +:10DC4000E882A0BF9B47623DD8B9689FDE6CC2FEE8 +:10DC500006C013E6DF1DCEF21A3A0B391E2E2C42F7 +:10DC60003C74B7323F2251FC63A625C979B78BF1CA +:10DC70008194F2F833FF0538BFCE8C7A29C8588CCE +:10DC8000C57464627F74FFCF3B597C0BF16CEE8FDF +:10DC900053791E99AF02E07A6F2AC3CB2D661627FF +:10DCA000DA42F560E48B1C7F45FE5A90EB79F17AFD +:10DCB000390DF4855457AF9FC00F763BFAA969FD23 +:10DCC000ECB8F41ED85DB3C3BA9811ECA8F649FEBF +:10DCD00078921D027F1067BB9DF355B291A0FFEEB5 +:10DCE00076F82E0DFAB7A4415CF176F81EFCA42B51 +:10DCF00026A9E2670530E6F8BEF969F97E819857F2 +:10DD0000C783FEE47144FFDAFEA81DE975B910CEA1 +:10DD1000B174B0075A74B88FDA79C637327F737C22 +:10DD20006301E29DE86FB079FE5997F8BE44E5E0E3 +:10DD3000FC89CCBE16F6CB3C6EFF92156AFB0CFC40 +:10DD400023BD655DFFB2D6DE83B8B8BA3DD35B5262 +:10DD50004A13068C977825D5FC05BC0683C3E46F6F +:10DD6000083721F71E34537EEA00335A42BCDD786F +:10DD7000670ACA31A7213202F06A9ACB8BFD6E8600 +:10DD8000FC1494ABCCEEFDEC35E1AF50DBBB214B8A +:10DD9000621BC02B646174747A6F2AD201191A9FB6 +:10DDA00005F95D67F61809E06F93142F06BA3E2D4A +:10DDB000F9EBB05D4B8A17E8E97DB907E11D020870 +:10DDC000D27985C2FF837945A12EB5FD7B9AFE5796 +:10DDD0004FF1FDB41CAF807E043F00FA47BDA89E02 +:10DDE000C55B9A641206BBEA5279F64294FF376724 +:10DDF0009387F0FD7BC56047093E4FDB1D901C0CEF +:10DE00006D805E1A38FC9AE4A3D8AE01F283008ECE +:10DE1000605F815F0B2A93FCB14DEB3EC6FCA4A66C +:10DE2000DDEA7D6EE8C303E9BC04DF25E105D271BC +:10DE300098F301C2FC14352C5E9CCACB29B53D98E1 +:10DE4000AF14E27E0BD7FEF864E027A9E551329BC0 +:10DE50003E43C7999E31A17BFB4B600FDB6B7BF28E +:10DE600000FD43DCAF27F659CCF392EEF5E8A7109E +:10DE7000FA49929D3962BACA5FB00ABF03BB15C6A0 +:10DE80008BC3AB2CD87E26D73670B946E51FF2D7A8 +:10DE9000791DC351FE817C02BE24EC5EE053C01F9D +:10DEA0004EB8AAB7009DB6B8AB1F74B9D878A8CF42 +:10DEB00083B174C9E0FE38011FD10EECDFAFF2B7B9 +:10DEC0003DC6F1D569E07C9730FFDAD2575DC2BF1D +:10DED0008671B4A5923713F0F5035D10FD680B4809 +:10DEE00018FD3B0BC17F459F0D9CCEE773BFD07CD7 +:10DEF000EE0F02FF6C72BC0FFCA4C9E54584E12F54 +:10DF0000D969ECCB8301FF4D0D89A5D2FE1AC1BFA3 +:10DF100004CFA8FABB26926078DF75DEA88A277640 +:10DF2000B275DFCEF7DF5E13D1017FD864667E2540 +:10DF3000C13726AC60FEA7F4B1FEC27B00CF5FD52F +:10DF4000A35FE2BFF9BE09384D71556F77D1F61660 +:10DF5000B0D3A0DD3D46E497C7A81CDEC5FD21D3A4 +:10DF6000C1FE5C191C0179DC44B1E527DBA7E2B9ED +:10DF7000768FB91EF0E74D97ACC2AFD52E9677835A +:10DF80007E22E4C729A86F53B63106F0ABA248C879 +:10DF9000433206FC53EFE9993FB7E9466B10FA8B21 +:10DFA000CB8CCFFC99F3B33FBB58DEE59F7BE515E7 +:10DFB000B7EF38FE88381DF86B92FDE41FF4B65FAA +:10DFC000CFF36309AE77C3429E87DD8BC732F2A3DE +:10DFD00094D200F2DD4BE56AE4478913562FC0A5C1 +:10DFE000F6E38685B08E4F675A08C4CBE672BFED64 +:10DFF0005948B873F5F969BF2E8E55BB7604F249BE +:10E00000D1FE6F3027577F7FEF1ECEC7F61036DF69 +:10E01000709B91F9D7F9FCF71C1F19013CA67A6D8A +:10E0200018F85C629799C93BAA87027FDDB37B78B9 +:10E0300004D6F39E9EE90B61CA7FD9F7C14DE00774 +:10E04000D9F34B970FF273428B3E1A03FAE39EE328 +:10E050003FFFD56FE1FD5EA30FECBD3DDCBFDE6091 +:10E060008815A3BECCF3121BD262C5E0F77981EF0D +:10E07000578385964B4179083ADCAEBE38187C0749 +:10E08000EF8F46985E7E94303C08AF63F14A0ADF1A +:10E090002C9847624D26C6D1605DB00FEFEF1D8D05 +:10E0A000F3DEA0E7EDEF63FADB515E3EFA7C19E6A2 +:10E0B000E99D091830AF36743FD317E7C8DE6DCB42 +:10E0C0008157BE9882FEC2799D6F605C23F4E305A0 +:10E0D00053A13EB468C575E42BFCFD205792FDD4D6 +:10E0E000A749221FEDE0FAA2688C8E7BBA7B848F51 +:10E0F00085ED3C18246AE2F99BC7287C61DE89BD66 +:10E100007A84FF85F60FEB05BB14E41BFAB593E3A5 +:10E110002A280FD47196AF2B9FD6C78BEFA4E3AFFD +:10E1200070046BDC497A62E8C52CE477EFDFF7799D +:10E130003EEA131D2C2E704CEF9F057462AF8919B7 +:10E140006627E95FB7B9B9DD61E47A23E583C9746D +:10E150002FEA2BAAD574269EB7BA19BDA5F2387E30 +:10E16000FF7A91BF7ABD11E427732941BF5EECB7F6 +:10E1700080C7D7261C4FEC837CA8866819C6EF0A97 +:10E1800056C4902E29BC63A0FF1FDB94CAF8095D1A +:10E1900026F433BF92A0DE3A5FC7F212E61BA91E37 +:10E1A000CCE438B6FF605326C2A16215D3FF12CF6C +:10E1B00048C817459CB18EB0EF9F6B7B2FACA3ED89 +:10E1C000EB764A6594B592BAB62ACC5B58B4A510E2 +:10E1D000F77F02E7BF738CFEE24D806FCFA522BEB2 +:10E1E000D1F150DF6E80DCACB1C8970C200FEB771B +:10E1F0004A642D498E8B6AF020A28EAB4C8832FE89 +:10E200000D728324E969420E81BC201AFD518D17DD +:10E210006195DC6BE77015FC1F21F6157290EAD151 +:10E220006B808E2BAA19BD25764908E746D2CCE231 +:10E23000405C0EF5CE87CBB10F744C6ECE37AEC7B7 +:10E24000E73677218EBB08E225E8FF4F18802F0EB6 +:10E250008617DB06C10B810F3FE3EB68384E6297F0 +:10E26000D3F11A569058E318F64C1D837299C9677A +:10E270001393CFF0B45C809CD6CA67AD3CD6CAE19C +:10E280004C0393B7020F92FDF2A08F4C5811D1317D +:10E29000FF6BAE0DF2F1C4BEDC90E17F227B7C9F70 +:10E2A000BE153A6232792F8272801459C1AF54552B +:10E2B000914BD71FA2FC1BE82E85C2693B7DBF9501 +:10E2C000EBE54372BD081F0FCFBBD12B0152668512 +:10E2D0007DEA413B3AE12268D70AF86E4DA5DF8D11 +:10E2E00085EF183DF67E6F226D96A4EFABF798513F +:10E2F0009E9C7D3E15F344A87C28B0D3FEDCEF50F5 +:10E30000FD9C964FEF4945F97E9AF37BA7F0579015 +:10E31000D5D8DF9BB0CF2EC0BAEA1CF0FB12694AF9 +:10E320000EB048A13736DA07F3D3F3FAC29E1B19B1 +:10E330009E1951CE9EB5C77F00653A1FCCEBFD0FED +:10E34000BEEFA1DD13CBEE82787EC0EA63500D965E +:10E3500081DE60D42DBB11FC4193752B1277D275F1 +:10E3600034E659315FB8A6E08F7FB899964FECD666 +:10E370001323ECFB8EEBD363F099E2F70C249F1789 +:10E3800046F4AAF3688B77AACB8D5175394492CEA7 +:10E39000AB51102CFF63D9150792F0E43377AA1321 +:10E3A000F7DF4B7C90EF4C74B7A50707E097E2F9D5 +:10E3B000F94ADF1507F4982FF6851BE9C06B00BDFD +:10E3C0006636E0C300DFED7233BFA8D1D87C1CF203 +:10E3D000CE8D2F187D2DF4AB83EEA02ED305F64AFB +:10E3E000E220ECA7B1E0E4189083D5057FC738D8C8 +:10E3F000D9BB890FE073D65C85FACDD94D662FD88D +:10E40000659DF956E6AF78518A484C7F9F3ABE0227 +:10E41000E29EB80612DA78F5097648829864DC5FE5 +:10E420006ABD7880CFF8D19EFA609AC5B68A7E57C9 +:10E43000BF91C9DB06D293067CA03693E15D48F715 +:10E44000A4C144FF59D8E61FD142E7BB3860C1F3ED +:10E4500031CA974A00F0EB5EE83249FF2FC8647278 +:10E46000A6D1143754C1F87F9F5BEB2AEAF36F19EA +:10E47000F4CCBFA57495C572E8A70B96CF413BA716 +:10E48000378EBC89E5252DB8B30EDFBFB4C988EB44 +:10E49000FB60AF8478FEC156B6FE051BCD5EC89FFB +:10E4A000BED2CEECD905F4BB81D77FD50958D7872A +:10E4B0005BEEF0817FFE43C2C609DB981FEA431B77 +:10E4C0008B77435BE8E7C3DD43508FA9DFB8702A41 +:10E4D000E68B6DD5F9408F207B53D1BFB360EBF74E +:10E4E0007F7B09F88FA6DF520E70B8D2BECC0DFE2E +:10E4F00012DA2E10617A31CBC375543E0A7478E576 +:10E5000097137BAE047D692BA5934296E70E7AFAAA +:10E5100081AD57A15EBA609AC50EEBF26ED9311982 +:10E52000E4C787D3B2655CCF5312B1011CECCBDDDD +:10E53000F07E81A40406C2A777DDCCCF565560F5E6 +:10E54000C5E0BBDFEB104F285DDD08F2B371AB1EF9 +:10E55000F5DE03D3DFFEC3CDCE3EBA5AA0EBB871D1 +:10E560004292DE13DA72ADC01312AB007B8AC14453 +:10E570004B5FC68215C5301F2D9D2D58D55CCCE252 +:10E5800055DF8CDEC8164A6FA3A8BCCE94985FE313 +:10E59000C2E9AD3EF31BD01BC975A8ECA8FE7C2DCB +:10E5A0008C7014FE7E938FF8775831AEEB9728DF8E +:10E5B0005D9FA9603FEB33D9B920E56F4B77BE4E25 +:10E5C000E1E3CE0CFE3013F41FE22F033CF2266C85 +:10E5D000D570E6C7CAF538B285E9CDA0DFC37E6F36 +:10E5E000709147D726F91DEECB64F611A5FF56E8CA +:10E5F000E7F45B7F3F08FBD3947F720C8B77FE05BB +:10E60000E383D66E1657B6FA121837D73B03887FC6 +:10E6100082AF877C4CEE68D7753893D97321670237 +:10E62000FBF98587D1A1F0B76F5E6E413FE9666760 +:10E63000C4CCFC0A610272696AA58EC5C5B89E7514 +:10E640002DF73F9ACA5F22100F2397B1FCADD7CBAD +:10E650005F523268F9B795937C786EAEFCE1F62292 +:10E6600058F7657A5E3F240CEBFE4F7F15D62FF5E9 +:10E67000E8BC40D753CB591E22A94F437FC9EBE5D5 +:10E68000EF3BE726CD3F404C5E2BC593E9D4C8490C +:10E69000CE9BBBEE32B3D79A845F9F7648B54CDFF2 +:10E6A000F5A6CF18CDFC212887CBD5F058EA31E06C +:10E6B000B82DEEAAA701CE575EC1F6E3A3A78C1131 +:10E6C000E07F1FF173285AF8EDCDE476E86D25AAB6 +:10E6D000F8BCD310CD07F9F8B1A4FE6E51BB0EE320 +:10E6E000E30BDB2512A1E37DF4F873F9C0C74FEC0F +:10E6F000782E7F76D27CB4DF89E72B991C5FB91F17 +:10E7000050EBD71DCC9F2BDA9DD94882A6217DEDF9 +:10E71000CFD47F81FEDCD9DDDC1FECF70F75821DC5 +:10E72000C4DB6BFB4B70FC90BA24F477087FE6D116 +:10E73000430F43E4A477FFCCDD857272DEA1784EEF +:10E74000E0FB763DEC1B5D8AB99D9507DBAFC1E828 +:10E75000711DC89FF17DFB76B47D483AC0D1D0646D +:10E7600055083B0F56027AFA5662F1013D19B23D47 +:10E7700056E05FCB4D6963E09CCFE766F6745AE8DC +:10E7800093EA6B79D925F8DD1D7200F3DB3E973BE8 +:10E79000F03CE01DBA66CC9BFE8CCBBB5C5B60D7CB +:10E7A0007CB44FA298474DDAD5F075B732F991A8ED +:10E7B00033A09C1270BE74F60FD04E1D607F3602DF +:10E7C000DE6457B277A59E42AE2FC7314E60AE24AD +:10E7D00036B0E75B2F09E37CC4FE84587322754B87 +:10E7E000A827437E4A8A03E3A161FE245607E98DE8 +:10E7F0000FA470BB9668E201946D85A19D9827B027 +:10E8000031C873B9DF1EED282EC7782AEA9FD02FB2 +:10E81000BC9F5DAAA03F1DDA19C67E3DBEF5E2256C +:10E82000CF179C2ADED75B068C3F4C857337B47DAF +:10E830001E9583A0FF119F5E75EE660BD59BC11ED2 +:10E8400013F15D9D1C2DF3A01DD21307FF88A1C2FB +:10E85000E405B99AA28B96C0BE69E3BDB45D21CB35 +:10E8600033C8B5835C11E76A9A964F0C40DE7AAFE5 +:10E870009EB197D9474D7756E1FB89DDCC7F1E6A63 +:10E8800037E2B9C0509784F1AAA6802162423F8640 +:10E89000B705F62B4CF530B01B3BED2CCFA9F36A36 +:10E8A0009B2F4C92FDD7F16D77A1FFDA8A71BA7F69 +:10E8B000367E79269502E0A2A4F854BA89C911EEF1 +:10E8C000DF76737C12FB2FE859C43B534B0385A0C2 +:10E8D00071EF76DFFE1BCBF86F901742C6DEF7951F +:10E8E000792164EFB570AECD04DA3CAF876951B9D8 +:10E8F000D97B4ECEECC5B8566F3DDC6F60EA92F81E +:10E90000F78BAE9DA4601E282F57AE83BCEEFBCDC7 +:10E9100044355EF2FC144DFF7ADABFD5CBDB876F4E +:10E92000BE66D2508CEFF272D78FFC747EF7EBD5B7 +:10E93000FD210A8A737DA6BEF12A72E4FBD65DD65C +:10E9400027BFA93C5FE671F5C9F17BDF9EDA7191C3 +:10E9500017E8EB33CCAB15F238E46479225ABEB534 +:10E96000D22309FD773288D8D533EBF03E80DEF82C +:10E970006EF7343FDC8B20E2BBA11501CCAF05F96B +:10E98000EF41F97FF2837D04F4CB8F50FF0F9D534D +:10E99000983F88EA1112C543537715FA3D216D144B +:10E9A000E4A6D8FF455C2E81AE0EF81DDA72D30EB8 +:10E9B0001DAD7FC7E35F87FD723B503BDF1D1E66C9 +:10E9C000BF874AAA37013F208F4804E4F6DA924F06 +:10E9D00051CF687A7ED2F8E4FCF0855D0FB0FCE29E +:10E9E0009DFA01D7BFC3A363F931CF3F83FECC8F1C +:10E9F00022EC584ABD12593301FC2AF532685AA458 +:10EA00003C527733CAFF99741D745D3FE27227B49C +:10EA1000F3FA30E4AB87E87F00B2CD81F9A8EF6F5D +:10EA20009E69B242BC2654327B09D283CDE287F57F +:10EA30006BE7D91B1FBED382FEC6B55DFA5AD09BC9 +:10EA40002AA89EF42B3ADF3CC7945A1FE54B39BAEB +:10EA50005D65DFB3425C7D60395C9DCDF6B14D0AEA +:10EA600084BF538EF98C24394FA7A08BE963DD1E38 +:10EA700083EA5E886E0FD3132F0BF74C049C7B51F7 +:10EA800089A7805E1C22FE4FC0CE2501AB17FA81FC +:10EA90001B1540CF72AEF4A23FD7E48CFFE822D41E +:10EAA0009B14B433841D71FA79E6FF1A9E157C1508 +:10EAB000F0B24217FFC977006E3F62E77589C2F86E +:10EAC0004DFEF5D6B1E0AF323BE33FA9F5627E0DD6 +:10EAD000FA1FD22F6FC37D78D1496C009F89E13A2C +:10EAE000454A9233826F4CEC3D17E3443F693567EA +:10EAF0002FC3E86E7D6042146D3B9FD1A7171CFAAF +:10EB0000FB0C055E0A7D413605D19EA99949ED436E +:10EB1000C0CBD5898332F8E59D3DA82F3646251C0C +:10EB2000A7B1E49798FFB698E759F5E63B2971CC71 +:10EB3000FF7ADF93C2E3036D4C6F253D68FF922798 +:10EB400019FCA9DCC4BCB03EBDBD05DB89FE0C3C94 +:10EB50009ED0C8FD351450587FDA23E209AB78FF08 +:10EB6000228F8D8D4B146F45B27F61C3342A49705B +:10EB70005EDE3498EF13E6C0E7404747EB65E6CF2B +:10EB80006E4F89C021CF0D528F1FFC8EE1B281CF15 +:10EB9000B358B3181EA5EF4F4C467FFFF383E5BB78 +:10EBA000B2FCD64DE347627E7879D72793013F4880 +:10EBB0002D417AA4FCE282F25DED595E1CEF5BCF41 +:10EBC00077F549FE87E83327CBAECE77F531B88BA2 +:10EBD00038A436CFF574564C617969F16D3B407EAF +:10EBE000761931DF6D6AD72B47C00F39D544A2188B +:10EBF00097D5E8012F665C3F348BAEE3CCA90FB606 +:10EC0000DD4320DFF9591FCB9F53CBF5C1F4788C3E +:10EC10004D24D97B157C1FBE2D3D5EF0DD10B78BDA +:10EC20003E96123F2E86F5EDD5D9063AA732314BE6 +:10EC3000E0DF20F91ADD03E76B887350B5F1425528 +:10EC40009CE95AB19E6F18B70A802F7980B895C297 +:10EC5000F3B01489B100926750C5AD147BF16071B7 +:10EC6000AB18D63F331CEBEFED17B762F9016D7BA4 +:10EC700033BDA0A737B8128F3EEA85FE0CD84FDB14 +:10EC8000F32911C83B6FE3F06FB8F0B8D5C2AC01FF +:10EC9000E256DBB91EF67E891C3350B86E276CFE37 +:10ECA000E16E11BF92D11E4DDC9727E68FF567EE1E +:10ECB0001B857E9F39222EF522F387CDE1F1A7F740 +:10ECC000A71763BED660709ED3AEF6EFDFC5E17CBA +:10ECD000D65C857EF51FFCFB34F433CD077FFC90BA +:10ECE000BE730984FBE5BCEDECBCB977A714F1B2A7 +:10ECF000F88849461DCF26C3FBC5941D6E06161A1B +:10ED0000A65873317D2D51A8D17A6F1B2D53E55D27 +:10ED100059A3843DB4DDF62329E807BBD7E9C5F93B +:10ED2000DEDBC6E2C4E175526418EB17EFF10AB7F7 +:10ED3000C97EE8E7A7594C5EFF2A8BF921BC9AFBF4 +:10ED400001DAF43CDECBC76B21720C9EB2C49EF795 +:10ED5000DA94DA81F400D15F9BBED95405F0CE631A +:10ED6000F7859C35F867A29FD8518CF702B5A53678 +:10ED7000B7D7B27AA4D9B3E64400EB2F57986249CB +:10ED8000BC0E98EFFA2CA6A768E13CAF435DD6C64F +:10ED900069B4E7A0E690E0F0AC21FDCF09ADCF6209 +:10EDA00072ECECDA42BE2F3E8C7BB4E9BD6F1602EA +:10EDB000BEAF61F7FEB4E432B8C979EC5964AFC1B3 +:10EDC000FBD9889DEB6384CDBFE872A704F4D066BD +:10EDD0006778FBAFCE5B3BDF17B28A197CED8C5EA8 +:10EDE000DBD64811062F36EF0BF56FBC25F8D2B7EE +:10EDF000C417DF977C8FC60AF13BE40BE1FBF448B4 +:10EE00007747492487E53FDA906FCEE6F6EA512E40 +:10EE1000AF36D717A5413C73CEF1D5787FCFC4EB81 +:10EE2000AD38FFA617CD688F35AE88E7033E6BE19E +:10EE300008B355043F9521EF98B07B5FDAD5F139DF +:10EE40006DDC7585239000F9D2541D2F86F8CF0311 +:10EE5000F2FBBB5E617C0DE563D38AC4A3E02F0E99 +:10EE600038829F43BB9377BE3D59F2E2E7C8DFCEBD +:10EE7000EC1D8EE7FD66B7A9CF4F9175EAF81F69C3 +:10EE800077B073629DEAF7705E48F55DBF7820D376 +:10EE90004F36188223407FBCF20A96EF706AA14C6D +:10EEA000603F4F99098FB30B3EEB2B4E9603CEEC90 +:10EEB000C1E41D6D0770E6F99DA27D23EC2BDDCF2B +:10EEC00006BEAFA79EB9B818F6F5E4AE8B8B615FAE +:10EED00037E83BFC4017275C414F36C597639302E8 +:10EEE000A8DF897CD60BC5B7E183CEEB7F470E97B1 +:10EEF00067FF737218FE92FD1E2FFE9DE59D86BB77 +:10EF0000D979D13E7FDB4778EFD59973B2047C780D +:10EF1000B0FE5EF730BCF7984818FC1C15D571FCA4 +:10EF2000AEE20B99803E27F458EDFCAFE2F09B99DE +:10EF3000EDFF15E8A3C23F5BCFFB36453E63FAF217 +:10EF40002312FA5F4DDE70DA04B48FE68DD3215FB1 +:10EF5000F9159E6720DD920DEC8C858FB460FDE97C +:10EF6000AE39582F9B6231B0A71A693D94575FA6FE +:10EF7000CE4FD6EF2E8B25DBAF741EBF00BB24C552 +:10EF80009930007E36817E4CA7D8A4303F7593938C +:10EF9000A07FA4BC4B6DEF89F8EBE600BB5765730F +:10EFA000B784F72BB90DC1C25CD8574D1C765EB63D +:10EFB000BF0DF04EC4C3A7B8FC0BB259BC3C1FE058 +:10EFC000D494CDE617D78BF373EAF37D87F6DD880B +:10EFD0007AD05F49207DE0BCB1882A4E3E9F9FBF1A +:10EFE0009CCFCF5F027F8E69F87372B921296F2C95 +:10EFF0003650FC3F296F2CF9BBE4BCB1988AAF7541 +:10F00000F0F3094B313E1DA278BE7C6C1F1E3610FA +:10F01000FEB731F13E9E4FD96944BF5803CF170D5B +:10F02000D51F457B2304E75D183DB2BC6A7EEF40E7 +:10F0300003B5E3306F36AACE2BFD69F6B72B0F442C +:10F04000BBC1FCDD8F0A7EC0E951AC4BACA3A15B18 +:10F0500062F4A399A7D67ED5FAAD85FD79A17C6926 +:10F06000CFB7BCEE6FCA975EF996F8523FFFFFD05C +:10F07000449AEF5BF0FF9FF076B8C125D82E317C23 +:10F080009DACB3FA597C51C7F20FB47157EF648C41 +:10F09000270A7FABE9595D645521B6C7786AE3DE7C +:10F0A00054CC07A8F7D6A39EAD8D332E22BB26C322 +:10F0B00016FC95BC86E7AAFED5B8FEE9ECDEB87E64 +:10F0C000E1378CEBFF35FB1BC4195FB27E96114C08 +:10F0D000C293EA52AAB0970E9E77A5CB61FB9EC25F +:10F0E000F33F4C4A98D893BE1FECBB941C16677F25 +:10F0F00089E70BDD9F9A82E7E83D06768EC023B351 +:10F10000BCA677A8B69FE30239C0F6F167CFDF440B +:10F11000204FF067FA289E6B0F375A7D20BF84BFBF +:10F1200048F4DFCCFD98174A3F4539FFBB7CA33438 +:10F1300047FA6671B28D14064974A5A583C1BE1B3A +:10F140008CAF5C9E13A8CC41BEE51F83F1860BE417 +:10F150004729E5945F837CDE6DF482BD60E2E75D64 +:10F16000C8BA2C95BD3DE7FE3C945BA7CCCC7E1085 +:10F17000E772C4FA0383C2FB9FD3EFF6B902D3014F +:10F180004F8E55F931AFFFDE542657128FB3FC1E58 +:10F19000EDF914AD3C11E72BC47873C5FEFC1FF1EB +:10F1A000D325023EFF223FA5F215FD2B83C653FB5C +:10F1B0007D1F66F79154F7F8799C09CF2B887985E4 +:10F1C0007A585E5C0B9F5F2FBC38FF3F98E35F056A +:10F1D000FB70F22D9309E297E5E58C7F3605ACE8EC +:10F1E000FF6F8AB27C98A61504ED7C710ED59D192F +:10F1F0005C07F878EFDB56BC07B4A96B7B7B11E6A4 +:10F20000090451AF3BFD167B7FD01DEC80FE432BE4 +:10F21000E2AA3843C5F9CF56D796E37CD14E771A88 +:10F22000D5E77B7E99C3EC6FF1FC452F7CA95D424D +:10F23000BF3B59CFF2B0434EBFAD0AF303981F3B1B +:10F24000C5DB83FEE7A6DD282408268542FD5DB9DF +:10F2500088374DBBABCAF05C7FD45C86F7C1BC631A +:10F2600045FBEAE49DD9111DF37B3F06EB4A2D8F48 +:10F270005C0DFA65011D07FCD827775D5D86FE40B1 +:10F280000DDD097AEB3DD779AB29D22AF5D1E3061A +:10F290003D938F42AE3D08CA2CE647F0FCBEEE69B6 +:10F2A000649EB5AF6C75AAF31E67664F7A10E6F3DD +:10F2B000608EC2E3D32C1E5E68A2D667517F3C2CC1 +:10F2C000E4F1F0693C8F81844D7DF90B455F1F0FA0 +:10F2D00017F31365110F4F39C7F4DB229B01F1229D +:10F2E000B59DF10D42F102F4EBCB123D13E13CD59B +:10F2F000D0CED86500AF74003FE691C67F7411C4CC +:10F300001D3294CB20EEB06DF9D8FD2627F88F7A08 +:10F310002E87ADF176D8AAC1B47467060E039E108D +:10F32000A5B904F0BFFAF77A966FB82605E57D67B0 +:10F330007E03E61B9E7EDBA83A47A37D86C92A0F83 +:10F34000F8898ADA7F877EFFD4DDD28079A419A07C +:10F35000F48F67EDC1EF94DADE13AE043FCA7D127D +:10F36000BB4B91CE5EF280FDAFC8A077CCE962E7DF +:10F37000B1E774D8AB4DC84F251637B9CC897C524C +:10F3800059738D0CF699D242F0DE324B2EF35B0F9F +:10F39000EBB4C9B0EFBFFE5237603CEC6F1CBF212D +:10F3A0007F0DC0D5684C1C8490BD88E389BCB5C175 +:10F3B000EE0317F248ABC7F6D35FB93CEAD5E335A5 +:10F3C000783CD87702BF053EFF5A4F500FFBB5641B +:10F3D000C2735A02AFDB441EFE97CC8F5BC0F36250 +:10F3E0008EAEFD9F31EC3E3F110789B07B25F5F1D4 +:10F3F000D53908AFF8156158F76EBBDC548AFEAFFB +:10F4000026EC670DBB7FACA07DC8AACA7278DA086B +:10F4100080E0E89EC5054097618A07C306C0832344 +:10F42000392CFF48599382FBA6ACC79B968962771B +:10F43000E3BE290FB0FD793387AD47C461859FF2E4 +:10F44000604EB004F26B7BCF572DB7B0F355FCDCA8 +:10F450006EEAF2B79F82734BDBB8BF78FF8BA3F0E5 +:10F460007710CEAE5124F01B9DB5D71580BD372E39 +:10F4700097E94BA94A0FB15993F1733FE6BD16EDD9 +:10F4800065F97B0ABFCF4859E3DC0EF02CCD08624A +:10F490007EEFE56D31FC0981176DC730BE46F52260 +:10F4A0003CC7FCD1F392D08B54F250D86B5A3BEC52 +:10F4B000AADC6F572E7E9D9E343D572D072FD8BE58 +:10F4C000226A3BB3B7BDB01BB57684E6FBC1F41F1F +:10F4D000E20FABF25BE6E57A851E87F23D9BF346D1 +:10F4E00091F7D27B0E9944CC709E017209C4FD58ED +:10F4F00090FFB351B2F8404FD2E6FDF4E6E390E658 +:10F50000E12C1FA4F92276BF44F3C5F014794166BB +:10F51000C80B49CE3F4D65793D66C80BA1EF5B072F +:10F520003DB7EC6D81F13BEFB68973CBCCCF5E4B31 +:10F53000789CE1213CD79CB82117CFC94CAC65FE23 +:10F540003B47C020035E3EFB0F9D1FF86E82D22D0D +:10F55000E8578EA1FE2CD0B7CCB41EF24D7ACF2D39 +:10F56000D79101CF2D8BBC2411A7CD1EBE4102F92E +:10F57000D39B2F12EA3BCF0CE3762EF1A27FB83754 +:10F580007FE9BB04D7592DF88C49BD7F697ED62E03 +:10F590006DA601F50CB71C7C1CE3789B7BCC78BF77 +:10F5A000446E11EE5B6B6504EFB3759476A0FFB506 +:10F5B00025C3BF39D7D5873F627E64235BFF1938E7 +:10F5C000AF25F58D7B66E117F9A04F55771B191E06 +:10F5D0006AE6B1B9F7DE143A0E7DFE2297EDBF4F11 +:10F5E000A3DF8AE72F047D713E2CC61F6C9D021F8E +:10F5F000BF4E6FD7E257B89AEFCFBBE608CB3B526E +:10F60000E3D7FE95B5E38E515E726065009F67CCCF +:10F61000525407F941E6C42CE08077E6CDBF0EEEE8 +:10F62000D338939AC887FB385AF2A77E07EEDF38A3 +:10F63000E34ABC0BE5CEBC7F63E561896D703FC7D3 +:10F64000CFF3145686B1B2097965CBB9EBC2A57870 +:10F65000AFD5EA1E904FE59A3C13CD3D02900F893D +:10F66000F71E58D97E66F27C5452C3F577882CD1A8 +:10F67000726B56990FF208ACC4BBBB07EA738DECF2 +:10F68000BE01C2F29F5A8715B27C058EEF2497FB0C +:10F690009F493C0CF8DB5A68C7EF7BF9F56E238F66 +:10F6A0003BB1F1DF78869D131379B684D8F240EF31 +:10F6B000B17A89AA2CEEE1208A2D0FCEDDB70ABFE0 +:10F6C0001E2F1FB1044FE426E9456F4CBAA3147FE7 +:10F6D0008FE3D9BB86C27AAF32A8EF33EEE5A7F944 +:10F6E0008C1F9EE1F7FE7558829F423F4752664D40 +:10F6F00086AB5467665419ECA8A73DAE037EE4E2DE +:10F7000078619FC1E667AF0948F03B18E2DE3D57DC +:10F7100050417F000976EA407EBA8E05309FAFC126 +:10F7200094C857287E7D610CFE03E8E16CDD7B3FC9 +:10F73000C03860F61BEF42FEC51BFA8E8969202F88 +:10F740000AF97D0ED4F00B3B41DE15A0DDD77B4FCF +:10F75000E73009F9C3D419ECFCE9141255D0FF6263 +:10F7600063E7A1269717FA5AE9785379FEC6E4238E +:10F770008134F0034CBE29AEB0784B4249CE97108D +:10F780004FE2D17B93E9E06A6F5299C0FDBEEAF285 +:10F79000B53E75F93B955F0E4F2EA7533B206F3C4E +:10F7A000F0AD389E270E5F426C6C5D2C2FF0E7DCCD +:10F7B0006E1BE521A602C85B744A61B00B463D97FB +:10F7C0008D7194E72A0996DD3B4D0F9992D7BF5E64 +:10F7D00066715AEEE716BFE3037520579F7DCB8D08 +:10F7E000F0725B65E4A7E001077CABC8315980BFCC +:10F7F000EB389F17E7AF27A599F0FED5D625ECFE8D +:10F800007FEDFD93AD7ADB3ED8C7D613740D749CA3 +:10F8100047520D31390DF68B1083B38F1F0BFC81CE +:10F82000FEAE00BC1FCF7E678962F9D0E4FBBF5BF0 +:10F830005D6CAEAD772B3C3EC77EEFA1A4F7F71F02 +:10F8400028D9D1F6A05312A413161FCB13EB248A88 +:10F850001FDA67115166E7ACDCBC2CEEBD24A44A6C +:10F86000C1FB7224D1AE05CB0FF27652F72B7F038A +:10F87000FC189A46D7439F4BF2189F78587E632313 +:10F88000E28935E8053CF1A50C7CEEE7B63C46374D +:10F8900093D22A3D9037D09AE5F3805E25E023DEAF +:10F8A0008B7E45BD18CF973170BF4B78BF517E6EB0 +:10F8B000585BBF388FE96DBDE3EA69BFD6AF18D793 +:10F8C000A51EB7F7BBBC81BF13EF457BFC79A60A29 +:10F8D000A03306B7293C5F9594A8F35348A5CFC43D +:10F8E000F8BD3A1FE52A694516D0E7D5A6C6EE3819 +:10F8F000FDFE158E2757C9C1BF40BCE19559C5070C +:10F90000803E6BE18279DACF3524B61A90E54C550A +:10F91000F067F621C82FDAF2E83A9A74C1E10E5A7C +:10F920003EA5EF18BAA410E9EB9EBCF1FDE727F065 +:10F93000B0779E14FF60DF05FE69E72DF0805C174D +:10F94000C5C4BCAD24864F0F61F9D0547EB1BC67ED +:10F950006F5EDFBA28724E36350F05F9FE4A4B1836 +:10F96000F9CF55F69F60FED78305C1CD30AF99170B +:10F970007D82F7DD104F1DEA5B74BE3FFDBF9C2FFB +:10F98000A5AB2C782FF440A1EFF5CB033E6150E5F9 +:10F99000018BF969E958CC2344D83D4613BBB7A382 +:10F9A0007E179A61F5C1798D10E4B79663FC0BF36D +:10F9B00085F770BB2C2CB1BCDD7EFAE2E0F9C2EC1D +:10F9C0005C7FA38DDD6723EE45FA7E91B8EF86CD8F +:10F9D0009BF22F7EDF0D963BEBBC68FFF5EA8DF3C3 +:10F9E000981E7A65B1A50DEE0FEC7FEF0DF3EF9148 +:10F9F000E78C5EAE27A2FCEE4C65E39C32B3FCF4D0 +:10FA0000243E4E2477DF7D5C1BF44C1FFC635E219B +:10FA1000BB5F44F655C07E6C86B895AEBF1FF284BE +:10FA20002BF867C0EB79A5FE7CF8898D3906E6676F +:10FA3000A478B5A587409A5BF32370DFE4D5A4F9D9 +:10FA4000B03C04F1EABFA1FDCC519FB07B28FBF094 +:10FA5000EA0386576164825F47A72F6604CF40FBA5 +:10FA60004E7BF49DA67288331A11FE228F504BBF35 +:10FA700049F339A667F371C23DB7743E9F0F349FB7 +:10FA80000BC1EF643CCA240C8F07C373C8D74F1D4A +:10FA9000DB87E7E92468C81F9F84EFAB7DEDBA21BF +:10FAA00003CC5B67C57DBFF166168F09A5303D1598 +:10FAB000E232596EF03FB1F16F5CC3F0E346B3112F +:10FAC000F1655A7723C65F480D8BA7F8E8FF603EC3 +:10FAD00033897F12FC54C6F5B66978FE72C6547538 +:10FAE000BC65A6E92A8CEFDC40983FEDC6197AD5B3 +:10FAF000EF000A38CC24EB3E817C8E999ADFFFD34D +:10FB0000C2451BAF11F068ADFC6ABA1F91DF1BD76D +:10FB100019FE0DE33ABE7C963F7741719D03FA04CE +:10FB20009EBB7FD9B560CB124A17C37F5A8AF7664E +:10FB30004F722F7C643D2D3FB67924965F76DFBAF5 +:10FB4000EC0DA8DF568CE51AF99359788F79C5CD5D +:10FB500053E0BEF10366D68FC712EC84DF8FF08CC2 +:10FB6000291A0B26598D2181EDAEB9A8711CE4C16B +:10FB7000D45858F9B5B2FF1A8BE5225E1EFBC24875 +:10FB8000281F903E9935505C6854891483DF89AAF8 +:10FB900071B0F653C73E9E0D7E829A6A561EE5AB43 +:10FBA0005A3304EAE54F670D248F67E573FB89EB51 +:10FBB0005B014EEFCFF9DF6B83735E01ABE483FC37 +:10FBC000FE40E57BEC9E2B13CB2308F8CB14B80743 +:10FBD000B1DACFFC7B13AD2D59C0FFAE0B1ACAC1F1 +:10FBE0008F6BB316B6C17DFFE99555E361BF275210 +:10FBF000350CE41FA5ABD9F94057177F929F867A41 +:10FC0000889AAE04DE4E13F454A3A61BCA0FEAD999 +:10FC10003EAAE981F6DB88FD5EAA964BBDFC5D43FA +:10FC2000B75A7C1C54EE13351FEC954FABA3889745 +:10FC3000B9849DE3D90A78CAE8F7DF607E06B9C7C0 +:10FC40000BEF0B24DF484CAC18447F10F303B5874F +:10FC50008CED3F2FF85384BEC86660B3B9615C5623 +:10FC60004FBFF3C38F7A8979D1F17F8CF059CDE6FC +:10FC7000B3556AE6BF13C1F47261F73689F576A908 +:10FC8000D75B6161E7D13D84F21DF4DD978DFCAA5D +:10FC90007987B89C9D610ADC67A46BB8C13E07F701 +:10FCA000F926127E06F49BD72CC108CC472787F78C +:10FCB000C625F89D073FC693E93E6ECF4FD217C4C5 +:10FCC000BCB4F0681A84AF6AE7AD8543DFFEF4A0E8 +:10FCD0007E96C57F0FAE775D9AF5B4F2FBE01365B3 +:10FCE00046559EE86B752C0F56CCEB358994A09C3D +:10FCF000942C1847EDF53B69F9DB20E7D2847C169C +:10FD0000F3BC839F8BFA5C667CEF0E5D0CE7595069 +:10FD1000DB630638C6F38BD87DC67CFEAD95616C7F +:10FD20006790A501E3C4F17C59E457A8F65BDC4F6A +:10FD300026E25C02AE4E833717F33D35F09C6D3200 +:10FD40000E1C57D5C65F07692751F8E538FAC35925 +:10FD5000C4CBAED5FAE1AE66FEA96BB91F6E622DBB +:10FD600083BF63792ADA6D8EF2371432BAEFFE64FC +:10FD7000B11F3DCEE049C423253E1EFC04AF8F7F5A +:10FD80000CE344E29E422D7CCE0D029FC1E861B09F +:10FD9000F91FB104BE80714F493D789F59C263E39A +:10FDA000CE836021D08BDD565805FE05CA57CF9F04 +:10FDB000076313AAE8FE2D770565B853EF2612985E +:10FDC00004B9D78EDAA09EF9E709FA8797723B71DA +:10FDD0001297EF9F3EC9CEC1D7F8473C7819E89FEC +:10FDE00087F424E2853C6E069F4FB7E850AE2F782B +:10FDF000759C07F4F3F739BE0DDF28AB7E2F6E44F8 +:10FE0000C4A2BA2F63D44E87AA3C3A9AAD6A7F51F6 +:10FE10005791AABE2C3652553FEED05855797CCF1B +:10FE20000455FB8B8F54ABCA97C4A7A8DA5F7A7CC2 +:10FE3000BAAA7C79E216F57D1F617F4F891BEECB54 +:10FE400067F0B8F2DC6C55FB8FD3261F02BA9BBB60 +:10FE50008EE56D5791C5AAEF17EB1A301F9A7430D3 +:10FE60003DA699FE8F9F3757304F8CEAEF1900B7A8 +:10FE70008D6A3DA7BE7BFD6AE0B5FDEE99D0E83303 +:10FE80005AFD65B8B30EAE69269717B0F3EDE4627C +:10FE90007231FFFD10EDBEE2B9FD4F0FEBD08E5871 +:10FEA000FA2AD3EF973EC5F2E18AC9B0743CCF7508 +:10FEB00048472212DC5FD0BCE132A94F8FD1C2C5C6 +:10FEC000E851EFB3D9ABDEE79412F53EA7FAD4FBC5 +:10FED0009C5EA9DE67BB5FBDCF19B5EA7D7605D410 +:10FEE000FB9C3953BDCF5941F53EE7D4ABF739AF51 +:10FEF00059BDCF05CBD5FB5A185EA4AA177C734811 +:10FF0000FB52D5FB56295A413925991BA8C77B1BA3 +:10FF10008675FC7040FC10FB1FA6FF63F4DC8CF9B7 +:10FF2000F5F3E9FE437EFD5FC9BA83108AD2E24150 +:10FF300053D77A8CAB7D533CB8BB80EBA762FF2FC5 +:10FF4000503FA5F2B015F802D5635617807D3D9C51 +:10FF5000DB1D8181F518C1B792F58664BB7A307ECE +:10FF6000D64F4E723B7B5039A9B1B3DF82EC26D419 +:10FF7000C7D7A15FEB668ED79FC1AB4BC0AFFA343A +:10FF8000CAFFB7E8442AE9BCDE8279D371DEB28CBD +:10FF9000423FC8AD24A6C77802646EEAF0DE4BCCBF +:10FFA000C3ACA37A393CE770FD601EF7937C610C0B +:10FFB000EE2C60FE9102378C9BDBC3CE6FBD967139 +:10FFC00041F73BFC0EFE49DBFDA92010857E6A4C03 +:10FFD000DE650FD057FBB9FF894C65F99F44098C4A +:10FFE0004EBE4FB1AF1F16377D410A06D1CECE327D +:10FFF000F9C0CE1E95434C5920DF3C91228853FD19 +:020000022000DC +:10000000BA4016712A942B23398E3C951D5D6A47A0 +:1000100078451C1827F886E3FEA6C07F10F041B48F +:10002000FFBAF51A0CD125CC9FC07EBFE430DF9714 +:10003000876F34C6C02E1378742465D6419717FD98 +:10004000E187012E336FBA7A3594A5FD19DEA574C8 +:100050007E67EAE268DF53F81F81F11B4C14FE74DF +:1000600089A7F282C3D301190219DC4919183DD0BE +:100070007924319F8912C70B4BF03D1867BFDC9381 +:10008000EF0378283D78FE8E5851B921A70C03FB69 +:1000900003051CAA53F26EC3FB748D461FD817D5F7 +:1000A00012DBD76319B7CF82D8E23C39E08EE9542E +:1000B000F33E03E335D8EA0AB28AC0AFC6E70D3F84 +:1000C000028A70F7960EE827E7F3861C128CEFDEA3 +:1000D0002D89DFCBC1F273613BC6338CF26787E1B8 +:1000E000F7FD12A3658CF76DB1D0AE29BEFF27874F +:1000F000B7B8EF9CBE67F97916F6BD67838CF1A39C +:10010000FF07EF54F02D0080000000001F8B080057 +:1001100000000000000BE57D097C94D5B5F8FDE6F4 +:100120009B2DC924992C6421102609598010266121 +:10013000111471588251034E006531E24C12206453 +:100140008100DAC64ACD40D854A8A122A2A20E0846 +:10015000141568B008A8D1372C527CDA8AADB52EB8 +:100160009597002A3B3168A57DBEFA3FE7DC7B33DB +:10017000F37D244F7CCBEFD7F7FBC7D777B9DFDD13 +:10018000CF39F7DCB3DD3BEE31AF2E6043187B7E19 +:100190009ECDA92A8C7999C3CC54C6CA99CBCC32AE +:1001A00018FB7CF4BFBFD1EA602CD2E1B13A8632B1 +:1001B000764F9C21F58334067F9E012591908C8C8F +:1001C000632C99B1EFF1EFA6AB53C67C8CF5C074EC +:1001D000B5810D636C929DD1DF2C180BDB4D662E23 +:1001E000138E7307F39870DC3F5C34BB5814A4067D +:1001F000282F606C2AF3D1F7E9CC4FE95D2C40F54C +:10020000EF66AD947F3F22AF773DCCAFE489EC4CF5 +:10021000066D2E795B8761F9DF2D9E549C6F8DD51D +:10022000734F3C7CBFD0DBF36522D467EB60322395 +:100230007E78BE25383FA8F7591F779603F2E3ACC6 +:100240008E21F9E98C1D34B0CA661B948DEB41F305 +:1002500067467BE6A4815DF5B3943118FF58475497 +:100260001E1B8479972D19D67F335F3EBBD9555D10 +:100270008CEB2C546D2C1EE07FCCA1FA2D3066D176 +:10028000686F4F5C17FC45FAE2199BE852D9C3002E +:10029000EFDF2E812F50EFB7F9AABF11EA4DDC3006 +:1002A000FE0CB62F1E3D795934AC7FFC77AD43026E +:1002B0009016F5329D68CDE1637C0FFFFB866D1CC7 +:1002C0001703E9AD49BB8D0CE67F6B5F6D79712E2D +:1002D000E4ADC1FC44660C96C3B807100EB18CD5D2 +:1002E000FF257FD4E190768C35A96E58F7AD8EC886 +:1002F000F82F0640B63FEBFF3DCE5B2D8DF6D8BA0A +:1003000087EFB70DCE51874D304FC55582F861400C +:100310006F6EA0A33223733577D1EEE94C45D00F31 +:10032000603781B1DBC55C3B8A2F9B2FC17A57397F +:100330003CA5D8CFC2099FCFC4F53123FBDD608037 +:10034000DBBCDF03DCA0FC4403403E9BB1530D56F5 +:10035000E6B230F645839DF2A71B92283DDBE0A074 +:10036000F47C430E955F6C7052FED70EF72CECB701 +:100370006CD557464F2E632BC3241EF93C16093A01 +:100380005ED97BD89F9D30DECA774D94AF6C6E1AD4 +:100390001F01E9A2DE279646C0F7452F284EFC5ED6 +:1003A000DDE232DB603EB30E7B5620F9CC79B775C7 +:1003B00022808FD55E519807B690A5AF7B11D2D918 +:1003C000D03F9D4A40F87DD9309CE673A6C145F3E5 +:1003D00071B5B41D8983F6E71A8A287FD4E1BE1F60 +:1003E000E7E7625F99B1FE841D6DC614282F74295A +:1003F0002E06E38E7231BF1FF0B7C1E4F120DD6C31 +:1004000048B63A1B213F7AE0A467EE8571DFE9E345 +:1004100069C4F677C49617C6C1F789C3BD46AC3721 +:10042000F53BC6302FE9FB87F7358747ADC0CB8555 +:10043000371582D385BD036EBF01FA7BF3A8CA547A +:100440009857C71503CDABE3A3703F5382F516BE93 +:10045000A2125D2F1C68F6B334CC0F4864B9B84EB5 +:10046000E80CD69FA338583DD0DFB99D3F4D423CA4 +:10047000C8F1CFC536FFF513E8AFFD338373338D75 +:10048000DCFCC55390DFD72BC9F930E42E9AD83461 +:10049000DAA7AC2E6212D0D73C33F3F0BC6700E68B +:1004A000CF85B37BDC901FB62B650CEE231CCF9160 +:1004B0001DE46B59BB9E487FC0111C6F7BF3AC4F92 +:1004C0009E82FC05BFC1678A8694355F7C0DC6F3AA +:1004D0006DB139B7329CA7311CE7F98889CFCBB70A +:1004E00035DCB9D581FDF9890F40B919CB6B5E7E3A +:1004F000B227AEE37580C170C8BFBE3682F8DDEBAF +:1005000026E7F17A6CF70CEFEF57BFB8FFC47E4CCB +:10051000D7D416DC0F69C0114BF0AEF8E5DCFED87D +:100520007E400AA007F8E34BFB9440581E6303D7B4 +:100530001D589A0CE30DDAD866E80969FE16A51174 +:10054000D301BD8B8EAAD0FF118783E63178479AFD +:100550009A82DBB5A7FF939B3208700AE2AFBFC057 +:100560005FEEBAAFC6F4847467CFE6853150DE5FC4 +:10057000693EBB240DE9FCC3020FC1AF89FA79A51E +:1005800065F21FEF62B80E5FB215E7ED353BB7A617 +:10059000F1E59A207F614FC6A687618D7B0DBE4D28 +:1005A00088775F99D5B915F1EEF63D89F8AE85FAF1 +:1005B0003EC8D7E6FBA2AE87F2DACFFA3A81A2585C +:1005C000EF676F2E4278CCDBF3F8F89E50EFC2480D +:1005D000E604126095AF5C1E8FED586FC690255CE7 +:1005E000D8D3983003DA3D923B6628D2975B6DA64C +:1005F00071D87C3ECE13B01DAD0032D60AC0491072 +:10060000A40AF51E81CFF83DB625E6400A0BE26745 +:100610007ECB923423B41FE2B13A55DC3769BEE495 +:100620003A58EF7B5865049D7FA7717F269B45BF95 +:10063000F6C9A9EE1F71FE99C57926FB7BC2CC7C59 +:1006400061D04F6FF8AE40BA11FB85F2ADC057EAEA +:10065000217D46CC1FC6BD82FB14DABB900FA7C01C +:10066000219D0FF34C79C242E7C0B58E7FC9645B10 +:10067000A500DDCE0FE77C6C8C387FA7C535BED1D9 +:100680000AEB7D35DC634C83716689739F199D0E7F +:10069000E4EFFE709729AD079EA3EDA9B806385781 +:1006A000C3303F4FF5F449C8A073353B1AF9BEF586 +:1006B000DACED577C35DD1D8FE5AEBEBF9EDA26F58 +:1006C0000C2C1FE860D1E316E2178DC897615D8D91 +:1006D00091C3ACC837D86143CD1138676FE42D3B67 +:1006E000FB5B1459407CA591B12EE1F526EC7F0F00 +:1006F000F09B009C131EE003A3AEB4AB9CDE8F1DE9 +:100700008A1E827C96B922817E6EBA62609E907348 +:1007100050DF0FE02B0FE1389A45304FC8B9EA623D +:100720003166DCB7CC16FB5F5BB798FF4881BF91A1 +:100730001D1F45301BC203BEDBBA5FD71B625DFFC6 +:1007400082EB82745DA6DB85F0BFF16BBB11D777BE +:10075000A3B12415E51A98F778FC3EEA6B8376DEA0 +:10076000DF856BF2D73AFFFB14E633E07EFCCAEC80 +:10077000C7FDD882C723C0B1656EAE1FF7FD5E33DB +:10078000CFFBA2A01CF0D812C97CC8475A4A12FC61 +:10079000BE34E487508E7CA307E3E561A2FDF40438 +:1007A0006ADFD30220457E7057B8E8BFEE9D8158BE +:1007B000BE2485F848A3C9BF2A1DFBFFB94A7CF8AF +:1007C00023C1B7D7C504EE52A1DF755F25301CE702 +:1007D000231648998FE3548613DFBDC160B8A7C4C0 +:1007E00086F55CC9B100EFBDFF50E99C58970F79C1 +:1007F0001BF1ED69CDF07D5D892B391CFB2949305A +:10080000D07C545647DFD378BB4F4CBCDE0C81AF55 +:100810008F057E605FD3BEF74C8C3022DDAE492B56 +:10082000F3A5911CE44A5660BE4F556432E49B33F5 +:10083000AA6E49237A697A82F8D7348103D91F36A0 +:10084000B00E43B999FF4D9FB5350CF17947655806 +:100850001B9CACECA3CAA5910E687F87470D5880FE +:100860009FB22985AE4EB92E1DC775D1B8B5CDFD45 +:10087000324E85D0739905F804F4FF52986725ED40 +:10088000D3FDF954BE1F849AEF613F9DA8C8DC8553 +:10089000FB8A55C4111D3063A01CF1F066BB95E4C2 +:1008A000D4EEE8A111E13F48D029E26531C73BC849 +:1008B0006B946F9CD6DF8FED9F3371BAF1ED0E23F1 +:1008C000BC164DB2129E3BA6856FB240F93D826FB9 +:1008D000354E0B772950AFF1158BDF807C40E1F46A +:1008E000E07B2392FAAD31F37CCDCB99444F7BCDA5 +:1008F000FE17B661F99B61440F35517CDC9AD752E3 +:1009000004BDB9D296E3B86F58880E6AC21DD1549F +:10091000FEAF7144272EAB673BC203E8AE0EE588FD +:100920001A73202B06E07B5CD0D5716883F8F3D571 +:1009300045D2BC69CB43DED3D87B33E2D363E6E553 +:10094000EC672A951FB7F3F18FAFE6E3973E5AFDA8 +:100950002E03BC1D778F4F9E05F3385E174172E35F +:100960005FEAD580390AF59EF6F55950EFE2E29339 +:10097000C336C0FC5B977E9A8AF451BAB4B618DBD2 +:1009800095562D9E88E76677FBB2B406367FC83E43 +:100990007E3FCD15C0F55C48F31C423A989FDB3A88 +:1009A0001BE5E78BE663CFA2FE1115E73982DF2F47 +:1009B000BDFAE5362E57B767E17930CFC8E9439ED7 +:1009C000ABF305FDDD97EE7997CE89F0C04C3C3F47 +:1009D00022728F717EB7F8DAF8FCD996AD7B1518C4 +:1009E000A73ABC651EA5AA3F0FFB39A704A2940C29 +:1009F000829F07F7D3797B200AE1EE317079AE7AD6 +:100A0000BB765DF867847955E33FA05D75B3EA0A6C +:100A1000435C33BF19E75FCDCCC1FA69413C413F2C +:100A2000842766FBCBCC0700FE552FF42B40FDA19D +:100A30003A66FF2F6EA07AD04EEE13F5EABC5CCF7B +:100A4000D5F3E1EB3B2FE8FFBCA4FF6982FEC5F8BC +:100A5000175F4DA4F1CF95F8B310FE171551EF05B0 +:100A60000BAF07D460C479FE9AD3D37A93CF80FCBE +:100A7000C7F77346F45C1DD73C0CE122F910CCC1DA +:100A80006780FAE776A5507DC9B7989B316C57BD52 +:100A90002B793397CF843E8B1385FA552FF1FE3196 +:100AA0008FFBF0EC8B29623C2E4FEBF1A75F6F447C +:100AB000BA81E4A9F5927F47CA7DEE4C2A01F86716 +:100AC0006F306BEA5F8C34DFE3827EFBF9B5DF6564 +:100AD000FF89E95CFFEBA3C35B4FB5FD8005F7D34E +:100AE000F38CF6AB7E5EA9A2DD8B2F76E249E5782A +:100AF000033150D28783CBE12684F3C79DF8B83702 +:100B000005F86A35C2203D089FBDF99E14E4FF1721 +:100B1000318FE7420CE473510EE2F0967909673D9C +:100B20009D2DFD78764A2BB4BF45C007109A88F4F6 +:100B3000D829BF98401FC9457DB472F0A94CD45341 +:100B4000EBFAC151D0B99ED91BF2ADB89FE66CCC7F +:100B5000B79685E0A171FBE0A30E80F3F9ED46277F +:100B6000B2E546A3FF17284F376E579B7D8CCAAD61 +:100B700008DFF3B683BFC77AB337C614A0BC2CDB3B +:100B8000CFD9705FBF8A10B80FD8AEC5C3C0666D2D +:100B90007ED07E6D7E32F286A13FBE5D7E409B1F81 +:100BA0007C549B67ED802DC0836AE578DA37DC7969 +:100BB000D40178EAE3579DF8A98F6DD2E409285F44 +:100BC0006C549D9950DE67B1FBB681903FBD719624 +:100BD00013D15CA9FAE63D0038ACFC74FC513C0F23 +:100BE000CFB1E60F27001E66B7AC351B1DB86E2DC2 +:100BF000DDEE35087A7D51213A98EBD7965FBDAF8F +:100C000097083CB29C507AD2E31DC6BDD30513AA07 +:100C1000A95F34F8141C9995C540E800B311CD6B59 +:100C2000CD28B7FDF0383E2E0FDA5C0E848777387A +:100C30002FBBBE7E2C3B3918FEB1FAFDF1386FEFA9 +:100C4000230AC90DDEDF641FC673A06DF7F45B29AC +:100C5000BDB388D62FED79735A944024E4EDC31DBB +:100C6000FB5BA1DD2CBFE2C479972DB304F919FC1D +:100C7000AF62B56E1EEB42CA61FE73F61FF89B02AF +:100C8000FD576ED4B69B0B7C16F957D596EF2DA168 +:100C9000DFA5DE787DCB2615D73D4BCEDF378AE149 +:100CA000BAAEE75559BC906F4E6106CE8D5B7BB8EE +:100CB000D7A763BB75BC1DB04B2FAEB7D66676E029 +:100CC0007A6BAD2C1001F3381A6976D9E1FBE50D8A +:100CD0009164479B6D0179B28052165680ED9CD18C +:100CE000D8EE8BF7B83DAD368EE3BBF63985F4A868 +:100CF0005A347E62FE799E9FCB02B40EA41357E84D +:100D0000FAFCDA3C6BE2FA578D317000E151C55ABA +:100D1000B9FE04787449F801BC6A609D1FC5A2BC85 +:100D2000A56BCF9C1E1C77BE8DCB4FF3F77F6F0951 +:100D30002D977AA0D4533786733DF1B92C77388E2E +:100D4000B35C713D6985792E17F2B56F6D18D1EFDF +:100D50008C4DFCBC0139360BE1B26E6DB213E58CE3 +:100D600019209787E1BE991B4EF540DE25BB4C3B11 +:100D7000C8D59BD3B07E7300CF8D758FA7911C0D06 +:100D8000F22FC1A57D4D987FB38272309763D6ADA7 +:100D9000CD2639FC75794EADE1725717723195B396 +:100DA000442EC77F824B099183CFF4F07C901EB212 +:100DB000AE8AA5AE643C772A26990D68AF6295711C +:100DC000D7243F6C1572643BAC1FD7714A711F3139 +:100DD00084C8A39FE37900E30C1BE3DA26EA39B168 +:100DE0005E85A1E4E19B70BCF506078ED7096F977D +:100DF0002B0BE7716A6D5801D2D9B031DC5E743CBF +:100E00009FF3F78821CCE587F4A238672E225F0F85 +:100E10004993C281FEA09F5385DC5E1D39C44D7687 +:100E20003A38AB89CFEBD7F177D14F85D9FDAF37C2 +:100E300076311F091F368ECB0BA716289BF9BC00F5 +:100E4000BF901FF6CB30B2EF9D12E78F8433D0CD29 +:100E500050B2D30B7EB556D0CB5A13A703DF5CAE8E +:100E60003F05E985113DAC137AD60C815FB686CB80 +:100E7000B5402F1CCE6B9205BDC0DC911E0A1D5CD7 +:100E8000CEBE467D09F01E9BD1E36ABD49E29B19A7 +:100E9000FD43D1BED21DBE6BF7EDDCEB83F3B3EAAD +:100EA000D78F4731A877C6D894E084F6355B97474B +:100EB000B9203D6DF445D961FC337EB5C8DF05BC72 +:100EC0006FCF907665974D01FE330FFFE94079E7CC +:100ED0009189B8BEBF6E35D99125CCDF6E21FD69F1 +:100EE000DE9EB9246743BE8DE7577EA5627EBFD6DE +:100EF0007E5EF5ABC7131C046F5F8A2109D3400ADD +:100F00008374DE1693338076E90F54270C037273D3 +:100F1000FB0A9C9FBE3DCEE30AE07B7EB3EA3547E9 +:100F20005F5D3E5FF097F97B1EF90AED7AF375F687 +:100F3000FA4AE1B7D0DBEB6FCA888CFF020DD3D73A +:100F4000B1EB500E02B83803B86F613E994426DC0D +:100F5000DEDBF8C213796D282F6C79274AC90DDAC8 +:100F6000EBA53FA3A3B9FCB9D71CDDEFC78BC26EBD +:100F70001BC417E75B8EFD0AF20050D0795A630A52 +:100F800044DD00F0A8D964223E53B3F3F96D4F213C +:100F90009D7D6CA1F3BC7AE75B1F5E8FF2EE6E5312 +:100FA0007C315F864D4908E269BE83DBC9245EAAB5 +:100FB0007EF396D931907F5F1C1BC44FF5EE03661C +:100FC00036F06A388E6D3E606EB57581A7E6B6F173 +:100FD00064277AE15B33EE83336F2A2C31EDEAF636 +:100FE000959BDE8A42790CE184E792C45727FE7410 +:100FF000F5A1FF89AF0DA17A76D42BBAC39F03CF99 +:101000000ED4CBF745B21818BFF2138BBF18F1BA44 +:101010006B5114AEE34B631DA7F3679627A05C5793 +:1010200069F225D829E5DF2B9FBD8FE86F8E529797 +:1010300060CF25FA4E3690CCE04BC6F5CDDA780776 +:10104000AD6F36F310FD553EA3BAFD907E63644547 +:10105000BBBBD8276F6770BEF9E566402AACEF4B83 +:10106000B4DB20DFF8832AF4DC05747EDF27D6CAE0 +:10107000D842CA7F23E4B68D1952DE056922445F47 +:101080009CBF65E531C4CFD9DEAE449C27C0C127E3 +:10109000E0A57C0FFDAAEF172672FC3087719868D7 +:1010A00007E7E858FC8EF58F995C68F70E6927F41E +:1010B000393EFEBD627C987738EAAB5F2670B95D39 +:1010C000BFBE6F3BF9003BC642E9ABBB7DBFE5212C +:1010D000A2ABAF3FE07C659EBFA488CA8F9902890E +:1010E00058EE3F304521BE606181AEF6F51693D8CB +:1010F000D7DA7298A7510985EF9B5C0E9D0D725748 +:1011000020641F07E9C61CFC4EEBFEA558472BF9CF +:10111000D3A41F6E8EE007FA75EBF9C3211D7F90F3 +:10112000EDD9C6AEFD4041BEE0A3716BE03C413954 +:10113000A3E6630B9D1B353B4D6E84CFB91D873EE7 +:101140009C817A68B3DCC75A7EABDFC7952F0FED61 +:10115000721F9F5B9DDFF53E86EF5DEEE3D50AF1E2 +:10116000B7FF2EBF85938EEC06DDEDD739DDF0DBC2 +:101170000B3A787EC372A36FC042BBB70FE147073B +:1011800057094F3DFF5C9EE120F8EAF927FC7DC03E +:1011900042E028E127E993310F8DD349C7924E25CC +:1011A0001D77D2A97EBD5A38EACB77237F82F9B862 +:1011B0005F3571FB598B42F236B43B923284F6A90B +:1011C0008B8E3FD67424253E34EFD7E59B75F55DB5 +:1011D000BABC5B57DFA3CBD769EAD7EC3F64E6FA2A +:1011E000414053CF527F1BE91957CB117EEEF7D9FF +:1011F000F395D98774D1ABDD8C7CD1B494F92251AD +:10120000DE7D432579F792A33D0AE592E5615C6EA8 +:10121000BB6417F9189E6FEF615E817C517E6F0F82 +:10122000E376924BEEF6A898103DBDAD458D427B1E +:101230006CAB9F1575654721CB28C0B5957557CE0A +:10124000E5B742D5965A8FF6D026D50964C22A96BC +:101250004C8DA2B887968CDBA7C1F7596FAB143EB3 +:1012600070299CDB1598CF65C4B883728E42769A3C +:10127000F9D68F847595B7F0F8838AD55AFCCEB627 +:101280004D890E3890EF68E304E6A05E9781FA9EE0 +:10129000F67B155B4DF456A5DB171E61A7D5EF0B4A +:1012A000775F112F90CFF2853D86FC1C0B05BF2E7A +:1012B00054736F9F06F0BF74546516C877B4A86C5A +:1012C00005AE778742FE1E7408E07E9B07FB12E79F +:1012D00023E1731EF74D76F772C9F9573E1BF600EE +:1012E000D2C9DE4FF39E86F4FCDE8FB35EC7FCBE30 +:1012F0003FA77ECAAEAE3FF6CDBFCD443E7CE94DA2 +:101300000B43FABEF4E66F53D12E78E9350BE9CBE7 +:1013100097965AB8BDF9CD483FFA232FF5E6726E7D +:10132000E31BDFE6B5D2B9BB8CF0F5405F33979B8A +:101330005AFEFD38DAAB3B5A6055284FBC1941FBC9 +:1013400067FE6B61E40FBFF4C6B7C342E326FEBB82 +:10135000EB91FEEE4B916CDACB48B742AE9FFFFAB1 +:1013600088E7D19F5BBBE780B91CCAC7FECB7FE48F +:1013700021FFBCF43297932E9A5A9F455BE38A2D46 +:10138000CE5F9A92D13E079DF564ACCFD6BA49B8EC +:101390004FAE860B87C3258003AE0BE052897CBF1E +:1013A0003B783C83F0E8F1CF088FAF66727E761D04 +:1013B00043FF6F102E0AF723B444FAAD0AAD9F7FA6 +:1013C0007FF3DB3CE4373FB4DED7FF69F1FFBFB307 +:1013D000DE8FFF69F1CBE9DDDBD741F3D4D3FDD557 +:1013E00074BDEF2794DF15E9A4F95EE37EFFDBFF10 +:1013F00067F84ECCFCBF8AEFB705BE23EDE857BCBB +:10140000F4C67FA4B21FB1EE61FF47D72DE5F531D9 +:10141000AAF3683ED47F87357FE04C23E9A34BB91C +:10142000A33C5391FA1BE94763193FA7C75AAB493D +:10143000DE1CDB6B0DC9C58DAC80FC10BE5E2AF9CD +:101440006328F802E0F0DBA47C3FF9938C815E8B8B +:10145000203F26A596E2B3F47AE3D8F00945288F19 +:101460001E5A02F3827E0E451AECE82B1ED74B0D56 +:1014700058F2286DC3F448EA6D47516E1967D3EAF4 +:101480004FB7E9F4A15B1CDAF222F6723CFACF8A7C +:10149000724DCC0FF3198FF543F4C6D199765AE704 +:1014A0002DAC6999DDF6E3E1F49880D3D570F8CFDF +:1014B000E176159C849E6C14F5F57033DA1E3E8639 +:1014C000ED8C0CF45EBE5ED297A5DEFB43F0644269 +:1014D0009F368AA1257C8DBDB89F34A45F828B8402 +:1014E000FB8F85B7C4931EEE12BE126E7A3CCC46BB +:1014F00063548F20FC7B19F38DB8EF6E1472FC38A7 +:10150000630CCFF73AA6BA693FFA399D7FED34A252 +:101510007C32DA1643F19ACCD13B06E54C1431BF4C +:101520004F61AC6C78CC3005D69B62643E0BE89B77 +:10153000E843233BEA4346FFD2341C87DB6B7B1B2B +:10154000B95D1A76B72FBC80EABBCC90F73E3687E0 +:10155000B9A0BE378539155E9F45C752381A533139 +:101560002E0B526CE78DE6FD7A13997F29C727E190 +:10157000A52FA6E9D4AFCB10CBDB4715507B9F81BD +:10158000B7771921ED93C1EDEBEDCB2DA47F785703 +:10159000F6CE42FE513C466B378EC8E2766699FE27 +:1015A00024CB41A96A7026A15C5CB6AC1FE9436AF2 +:1015B000B8BBF615B4F7EF8A207AF4AEB87BC25008 +:1015C0009CDFAE38274EEFECC4DDC378FDE9F7FDB4 +:1015D00009BE7BB687D1F7A7B23C473201AE67158B +:1015E000C7CC57E043D91D87CC493084A7B9E40262 +:1015F000DAFF26FA76FF1EFD8C13A7A8547F22E39C +:10160000718F6C5904F9A327F8BE3226417F13402D +:10161000D9C0F2B6307BEA0298BF57D87BFF20F6DC +:101620008B1ACE3C2F23BF5AD13B2B1DBE4F605D82 +:10163000C701DBB3B89D461DA36C44FF509FB1DCCE +:101640001E2FEB633FD86F8280C76799DCEE24F3CF +:101650000057AA5FB1CAD296817ACF2A53201BE3E2 +:10166000A773C6B4E13A8BD3D9F80D08F7FB55B68A +:1016700099E6DBEE253B77648E03F1E00192A6F854 +:10168000C2A63407DABDDA463707D03FD0F6649AEF +:10169000B3D14158A6781CA967B58D0EF445BB7C23 +:1016A0007B3EF7331CB7B746A27E586EB3527C8E92 +:1016B0008CEB9965E7FBBC4F63EB9AEB50EF7C5CDE +:1016C000756E86FCACC7B9DFE5739BD5AFA0BEB61F +:1016D0008EEF53B65A1BC7C3EC4EB2F794378D3614 +:1016E000A37E59617399719DC9D99EEF715DEC3BE1 +:1016F00080DF308CE364B419BC4D5E8A3351A36043 +:10170000DFE13E313AA250EFD5C701CD17713F322C +:10171000FF5298C79A05702C8B76EC427A39519F0C +:101720004176CF9B91EE107E18C788FE09636B321D +:10173000CEE7D54C4E8FC5B1F62C1BD1731843386C +:10174000B4990093906F5B1E66403F5BF1524ED799 +:10175000B0CFAC4668FF909185A3DFE043D1BE7463 +:1017600089D1BD09F2BDACCC18198B74954F74FDAD +:10177000688EE7335CDFE99FB3E1480FE5ABD792B2 +:101780007F45D205331E1B1707E39CDE9A56807CEB +:1017900053D2D1A33963FA6485D2C31485E800D249 +:1017A0000319440F93FA6279F19840DF85B9A88F45 +:1017B000D630179EEF49CC897242076B27FF6387AB +:1017C000CDEC403B97E427926F005E5DD684201DF0 +:1017D0006C83F3DE68626C7B8395D2171BECCC08BC +:1017E0003C6E474312E5773538286D6EC8A1EF2F60 +:1017F000373829BFA76138E5F736B828BFBFA188B9 +:10180000D2D71ADCF45DF225800BF121C957243FB1 +:101810002AB799DBD01F29F9929E6E660278471588 +:10182000507BE27B92DFE13A0C05417E24F19BAED6 +:10183000B87D4969C8C75AA723FE0BD5F33BF7A16A +:101840005E5E6973929ECE38DFEB007A45B8A49A4B +:10185000D97EB4BB362E70B5AD4C0BC2FFAE4A85F7 +:101860001943E8EAEEBA30660C3937EEA98FD1E4B5 +:101870004BEBFFF85622F43F2EDE332D0BE671FCC6 +:10188000C12F9EF9337C7FEEC1B399886F98C7D67C +:101890002770DCC5E19DF388C5FC3213F9A3FA4833 +:1018A0003B08FC215ECA18DF6FCF3DF877DADF6DA9 +:1018B000F51607CAC39F209E00AE7F11782AABB7EA +:1018C00010FCBCCB4FEEDC87FB7CB199F85CD932C5 +:1018D000B10F57013C43FCBB279219D923409AA66C +:1018E00078F5133F370722A0FF130ADFBF0A080568 +:1018F000A518F7B7EAB71FE1FE57EA8F92FFDC633E +:10190000B505480EF099CE87F6A7D41FA17AACB5DD +:10191000570CDA11E91C43BE3FC46576C0BA91A6E4 +:10192000116F6539075932FA4D9A143B6E990AF1D5 +:10193000BD629542FE498CBB9902729F2F4B253C9C +:10194000B6641A695FF5CC6242AE6BA2F349D26B02 +:10195000C56A6887FBA229DF3C3B840F9789EFE5C6 +:1019600039064AE5F726EC17FB5B953F0DE5899EA6 +:10197000589E8B69C134846F4FDB78A31282FF8736 +:10198000B3F8F82D997CFC9EB8D9E0FF1ECE4937FC +:10199000CFCA45FCF0F34B8E539653B002E338CBDD +:1019A000568F46EECB1A4DCEA478A8F718F643EB27 +:1019B000B17379C1CAE3956BBA393FA4FDEC34FE2B +:1019C0007304AD9BECBA55BB5EDA8571FC559F5A2A +:1019D00008BF558344FC54AE7FD86432346AEDD5D9 +:1019E000E35EFA2C8AFC0F7B785C25A4DC9EBAB8F7 +:1019F00092DB5F9DB0AFBAF0FF1CDEF569549776BD +:101A0000EA3DEA35D9A9E72BDF45A1FC20D753F8F9 +:101A1000C63709340FE50AF97FE6BFB13CA1AB7BBD +:101A2000377A7B75A73D5BD8EDF4E57A7BDD912CA9 +:101A30009D5FC0C8E81E97B4D73135371AEDFBDF7C +:101A4000887B1EDDE935D2BE3D7F03741207FBD3D0 +:101A5000E888467FD5A56EE4E9A86C2E1F5C10F6D9 +:101A6000F04B3B54D2732EED88A4FD346FC763470F +:101A7000D07F386F8B42D3A865C7086E004F660DC4 +:101A80003DC730DE2CEEEA7977F833A3F11CA97E4E +:101A900029B20EE96C6EB3E2DA0AF3E9B03AA27B3E +:101AA00084CCE7ACA0D76A4BF33082B3987FAB907D +:101AB000B764BDB92D8F91FD18EA5D2439E8D711BF +:101AC0008CDFFF68FF3DCEF3DCC6C14EF4FBCD6D6D +:101AD000DE3D8FE4881D11761481CE8A3861D9CF1E +:101AE0005F055DFF358BCB2FE7843FE8DC2E95F853 +:101AF00019CE13F7D759451B8FF79D68F75D1687E9 +:101B00009B1FF7778F60FDB9CD6D517DA1FE97FBCF +:101B1000FF48A9399BAF6BAEED581E9EBF5FEE89A3 +:101B2000207FD6977B9E1EFF3A8C77A179743CEE7E +:101B300007D97F7CB689E363A35A84F0627E1EF7DF +:101B4000528BF01D1C3ACFB84DBEB4D07DC7E37E9A +:101B5000CEEDF94D94213788CF5AABC79A9C8EFBB6 +:101B6000C7EB46BEF1B9C2E169DA33DA87F798E626 +:101B7000B7E433A467DA77C9547F9521A49ED9E4EA +:101B800024A668DC5FE24A21388B7B48225E1EEF88 +:101B9000D5D1BDA2122BF927660E724CBD0BF9E40C +:101BA0003B268E975E8E27507E9BF95E1CC54D2D81 +:101BB0004C734CC5F92F7A5FA578DF9983051F48D0 +:101BC0006A1D8A718B35AB14E68275B6A571B9A111 +:101BD000C6AF320FE47B023DF8001423B3D3053FB8 +:101BE0000D64E17DC0A72A0D2E339C7FC7CDCCA705 +:101BF000A2DDE8651ECF5C93CEE3869F42BA87B430 +:101C00002636901507FD9D17F8AC9914C8C238897F +:101C10009A9793294EE2BC99FB2DF13BFA496B0A46 +:101C2000A03DD48B17F1B0D83E26847E6ACA9C0EA4 +:101C3000ACA7C63A1DF9369CAFFD22C9B1AF4432FC +:101C400094630DFB22799CD3AFC2365B42F0E4CEA5 +:101C5000E67272BCC0239BC1E321D78B78ECF55BA5 +:101C600093FDA8BFC9FAEB4D9EE908075C07CAEFD0 +:101C700073CD4D5928DFCAF9CE8D6AA2799E17F42B +:101C80003D37BC89C74B9B793C25D6C77C9B895186 +:101C90001C77FB0B168A27399B7C6C2F8E7FF68571 +:101CA0007E0CD7DF96E69FBD9FCA417E04BC55BD22 +:101CB0006809E07ACEBCC0EDCD674C5C1E3B539208 +:101CC000E440BC154DDA3093EC315B2C0AE2FD8C1C +:101CD000C2CC4958BEB587D387ED1BEA294EBA0A54 +:101CE000D804DEC781B408EFD59CD9DA8FE2C3CE21 +:101CF000BCADE28D28FCBE0ABF7B58D3CC9F213CF3 +:101D0000B673FDE9EC8BFFDE2FF41E9A4CABB66880 +:101D1000E3E0249DC8F205D95C7F5920E07C5F3662 +:101D2000B737D44634AF4FA77572B8039E48EF0358 +:101D30000E13F9F4108C83C854906F3C0574F5347D +:101D4000DA15B673FDEAEC0E13C58557ED8B7451A9 +:101D5000DCD9CAEB0C1407A17239BCCA00E0A35449 +:101D6000A17EAB26E5F81B49FE66A4C7B66F55C534 +:101D7000388CD970DDDB789C6F31CA8A543E90CAAA +:101D8000CF88FC99BD0349AE83FE5D785FA9EA6701 +:101D90000F70384EAE7C97911DC34AFCB5A6D38F09 +:101DA00033321ACFBBDA953744E33D40F69ECA5032 +:101DB0003ED1C3E9B2D199887CF57036E75FD57B17 +:101DC0009F31233FA816F743AA5F54B83F19F6196D +:101DD000DE93AC5E71C313449FBF37B14C58CFF94B +:101DE000E6C7A242F1B14BF4D359DFECA4FAD550C7 +:101DF0001FFBA95EF14E14CD679B89E24CF478BCC1 +:101E0000E6F62FAAD7D4BE933E9AB91DE5AAF5B33C +:101E1000633FF914FAFF7A4798D3475F9BE95ED98D +:101E20003953F36C5CFFB99D61C48FCEC570FEF071 +:101E300025F04F5F36CEE3B647292EEB0F93E93EF0 +:101E4000DC1CBFB65F39EE6F906F63BC549C331AD5 +:101E5000E3FA6ADFE3FC0DF0723BB57FCF44EDF5AA +:101E6000EBF8A568D7B93F7746103D9CEBC9F172F6 +:101E70006E57369D476D319CCE61BEA9787FEEDCF2 +:101E8000CEEC7CBA9786C20DD04395D06FCFC534C7 +:101E9000A7DA43CADB4C424F0B404DA41B6C0372C4 +:101EA0005F553D97ABAAADAB293E04E36A87155059 +:101EB0001AB0C45E1D1F0BF44AFA63780EDF5F0C84 +:101EC000C74B10F1DB24EF349B917F7B845C58B3CC +:101ED000431F5FCBCBCF6477DA391DF1329E17E910 +:101EE000D0A7509C49F5B2057391CEABEBD6DE85F9 +:101EF000FB4CCEBFDAC88A500F6B53549A475B181D +:101F0000BB67129E1BA1E384C86D5F07C761F6041F +:101F10009257E91CBB92EDE074832726DE135DA681 +:101F2000ACA671D2A43ECBD725E104E030635C5F60 +:101F3000DB6851DECDBAE53CF5EB96F3B1E5707E9A +:101F4000D496E6787424E2F9772ADDA7BDFCDDE0BB +:101F5000E8D82EE4B2E0B96E0EC6B7C2FC9391F693 +:101F6000D0EE92CDE5F16A8C9F8579666DD4C67509 +:101F7000E76CD1E6FBEFD0E673F768F3792DDABCB6 +:101F8000F3B036AF887151CFC6FBBBA867638A7ABE +:101F9000B6C3C2F56CCCA39E8D29EAD9F81DF56CA9 +:101FA000CCA39E8D79D4B3312FE18DFA36E651DF83 +:101FB000C6F25B73B83C5623E224110F48EFECD510 +:101FC00030CD7D9F4B6FF07B1C40077CDF4C37D3BF +:101FD000BE790A6B90DEC1ED4A3D275B1D18EFBB51 +:101FE00038D633246728DEF738B62219F1666CA597 +:101FF000B8D3F9AFF1B8D39A82301BDA375A977F4A +:10200000B902C339DDB19E1158FF92A97D1BC2B739 +:10201000B6FE10DD7B6F5DE278EF268E3FB2B3B087 +:10202000CA58929BBC78CEC5768F477DDC375BADB6 +:102030008DF3D6C77DEBE3BDF57420E5BDE74CED30 +:10204000C9C8D74FBE605D8DF33F1926EE9F4CB3D4 +:10205000EAFCFD424E5BA36CC6F37A464E2CF79F1A +:102060001D05F9BC8B7356A6E55706931CDE995FD8 +:10207000AD18E85E5C52029D438BC49C5295F6B647 +:1020800095C8E7E61AE8DCBC0C72198E77F903955F +:10209000E487EC0D06CD7AFAF9C335F435607BACF4 +:1020A000EE5E434F4DFD41FBD375F71AFA6BE3E843 +:1020B000A72C3980FAFDE4D58335F52ADC37E8E032 +:1020C00028E62DE4D70A383F5CB0BEA7166F484516 +:1020D000FC2E9ADBD1B612E5D357C2E85E5825FE36 +:1020E0003FE08B95D027DE67ACDC23EE03D76BCFC8 +:1020F000E172710E551A99CF1E1BA4C34A3B73C5DA +:1021000040FBB9FD8FE50550AF78FB8FC3ECE9A824 +:10211000578C4E447E946A72511C6CCDEECC98253F +:10212000D0EFA20CCF4339B0CF4E351DFA45299ED2 +:1021300087BBB9BE7772F56FA2284E4CD05BAAC997 +:102140001E8E78DFD4C4E3E3D03EA6C606E9625310 +:10215000535C785F5B70BD413AF88EF004F8E1762D +:102160009CCA83E4F7E86816EB1DADF8509E96EB29 +:102170005B28CE15D697F773AFC89F12FA855CE738 +:10218000F97E07F21C78FFA2617FAA8AFCDCB063AB +:102190005B32A4B916CF165C4FE5A6CC3F8F847195 +:1021A000AAFEC4D7F3F9BAB1512350FEDC69721606 +:1021B000437E65D3F366D4B3AB8C7E33C557BEB0D4 +:1021C000C98CF1C5376FDF44DF676FF7523CE51C00 +:1021D0005647FAE769F9EE808047E51865A31DE6E2 +:1021E0001DD68FF38FCA70EEBF03F9E82D7CF7E39D +:1021F000F276251FE378A6B8779BBDF0FD0DC18F61 +:10220000F5FBA4E3DDC9853D081EFCBEC69F18682A +:10221000F11957EF8BC957D2685F4CB93280F4B2CD +:102220003B02FDB8FE9BABD37FDFE5EF2E74B4F02D +:102230007D50690EC44FC67DF2A689E4DC5A386F22 +:102240008617A05ECDD8F590BA47AA1A7A9D3F2E80 +:102250004243CFD358C83E81FEEEC4A09190FC9477 +:10226000E20C4DFDA95306E8E8BF20584E7CE47A05 +:10227000CDFDBADAC53E874272E618ED77C6E304B3 +:1022800081436BDAD7B249C17A48DF5BB81C5CBBCB +:10229000276633DAFB2A0D5C7F9AE6E1DFE7EDE79C +:1022A000DFD934A6D9877D329C7FE6E7A289FC027C +:1022B000D29E3E0DFFDD05FC4112E9BC1F8EF7E208 +:1022C000D11EA1B93F2DFC81386FC443ADB01BD5E1 +:1022D000E670BB51ADEF9819DF1D00F81BE362A952 +:1022E0009E350EE3239B14B22B62BA98E225B5719A +:1022F00058D81FC631CE3BAA7A719FE8CB81EE78C1 +:102300001CFF6B3CAE74CE067D1CE46AF247CE43E4 +:102310007B5008DE6EE9E710FE38FF8A9E08BF6238 +:10232000259FEE45EE3860C638BB295362F271DF57 +:10233000E8E94BF275D8CFA47F77BC7B88E8ABA3E4 +:10234000D248F4FB437098E7E276543DDDCD66C792 +:10235000CC784F7CF61EC589FA28D64378F4447AA7 +:10236000D4C1232EF66A3848F874C26B8F3ECE8DE6 +:10237000C369CE7EC51FE8024EFA79770737B99E4A +:10238000D91ECF78E40B725D7370FED83FCC1FFB73 +:10239000977E08365CBF3F33C83E35CFCDE363F54B +:1023A000F430E90AB7BBDC79C548E99462ED7EC434 +:1023B00076B82FEEB89240E53F965EE6C13CF9FD57 +:1023C000A76BA313B90EC97783FB81DF1BF8A17735 +:1023D00081F476C73BFA09BBE3503654138F2CF8CF +:1023E000AABEBD3E1E59CA01FAF3C51B69A0B8C9F1 +:1023F0000E5B3AC91792CF7AC4F9E159FE0DD5F3B5 +:10240000403D3E9B04CD79E311F6BF8591E9F41E72 +:1024100043EA92B804C49337CC4EF1F7DE252AC5BF +:102420003D7BA19E23443E59B12C2315CF8B130F26 +:10243000653FEB03B9FDC4FDF109C3619C93CB4D2E +:10244000F15647B0DE89E585A918A77172AD659A86 +:10245000BF0B7835F4E3E743ED831FD17976C1F004 +:102460006ED434685FB3FC95280CF3AF5ECECFF129 +:10247000C40CCF83FDC87FBB699B1DE167DF9487D8 +:1024800076DF35701C607B293F542D2F4C44F9A218 +:10249000E61F879EB5E33DEB25A604943FCF7C0065 +:1024A000E7A142E719C90DA7C3A00BF2A745921DEA +:1024B000E1B4C25CE8573A6F38F0D795A817E63711 +:1024C000670520ADB578D6F443F97FF9F324B75406 +:1024D0003DBC244B55B1DFCCE8AEEC2632DD26CE38 +:1024E0006D94DF3145F91DE364507EC73CCAEF9817 +:1024F000A2FC8EDFE76FD0CA7FCF087FA1B427F799 +:10250000696CCF47FF9D6F0CCBA9A3F3D69683F2DE +:10251000FA2225DC89FC6811CA4A98FF2C8CF458F1 +:10252000B625999FB702CFF556EE37FA56DCCFBDE8 +:10253000B11D64B210FABCE98A9585DE9B1DCD629F +:1025400034F9B1D6644DFD427B9AA6FCE6A47E9A8E +:10255000F25B1CF99AFC6D392334F52738476BF28E +:10256000B70FBF4553BFC455A2C94F2E9AAEA97F1E +:1025700087DBAB299F3A6DAEA67CBA6781267F5771 +:10258000E5FD9AFA77D72DD1947F6B008D14E8A5DD +:1025900005F52E0BBE9F62A5F4A7AADD887C63D14A +:1025A000EF326D88EF91630D755DD9F73F14741CA0 +:1025B00037C0F53ED24B6FF13E4E6FF1CECD293C88 +:1025C0007786A21F12A88AF4DD63C948BFFA7AFA97 +:1025D000F29111072F3B0087A35E34DF61043E3484 +:1025E000F2BA83833320FFD3176FE4F91B0EFE2664 +:1025F0001DF20D2F2EE5F941072F63B9F9A5313CE6 +:102600003F9991E8F148FF8E29184F32F2A6F4D590 +:102610004E6E27E9F29EB94C110E785F1BE180697E +:1026200000E817D38340BF981E06FAAD00FE74047D +:10263000E817D3A3A07FE2F77F05FD13D37741FF0F +:10264000C4F4F7A077627A0CF44E4CFFD0308DD2F0 +:102650000F1A3CD4EEC3864A4A3F6AA8A3EF9F34C0 +:10266000D453FA97061F7D27473FB74333CDFD006C +:10267000F433A23F71BFE97CA81F58FA2BA57FB2A3 +:10268000B18EB54620BF6835C67C610DFA1DBBB75B +:102690000318D91721F258347345F42779A1979D6F +:1026A000F8B7F8BEB38FC7DE1FE6F5A7B4C99983A4 +:1026B000553CB7EADE42B7EC9FC4FD7A7DBFA784E4 +:1026C000BCFC657F570F6C27FDEBD2BFDD193713BC +:1026D000E27F3784C4EBD05F48DC8DF483CB389F36 +:1026E0001BADFC9EB1F473CB781ED95FE1D78CF89B +:1026F000C3A85546925F228D2C80FDCBB89D51D644 +:10270000E67C8C63185563A37BB589F0DD5C40F5EE +:102710005C2AA45BFE06F5F3827EF544317F28A790 +:10272000F9177EED213BEC28115780EDADBCDC871D +:10273000ED47A16D6108A5C49F9EC17BBB05413FCC +:102740003FD68FE0F503D85FDFBFC37851C17DD39B +:102750003BB6391FF975EF7936BA17BA717480DE56 +:10276000B322A313C065B2D49FAC222FFD79DB1333 +:10277000C98E3456ECF50C87E766C4A7DB62FF2CE4 +:1027800082F659466FB44F9608F9F93FC15B31E2C2 +:102790004DC253E245E251E223247E8AF0D01D5E11 +:1027A000F5F8D4E351E2AFF0EB205E10AE57E32D25 +:1027B0008857B4E7FEB3E06D8891BF5F66A9B1D2D8 +:1027C000BB683F84C77BDAD9F868A872CAE139854B +:1027D000E7BCF78AE308E6CBD9E8F1885A597EA12D +:1027E0009B72CFD7EDA6E8107CDF28F01D9F06F581 +:1027F0007B5C5D5FD693EF31C8FE077753FF9D305A +:102800001977E1B2E50F0BC63F2E2AE4F02F4A53A9 +:1028100009FE6373E7909CCC6C5CCE74C07FC89754 +:10282000C67FE7A6772DBF613BD073CBC6C76BE5EC +:10283000D3229DDFFA562197DEAA934BF572A5BFEE +:10284000BF902BD358DA8F7CAFF257FD89AF5EEB88 +:102850007B95FCBDD371629FA5083ACB70A86C2410 +:10286000D211F3D0397918DF3BCDC377417D94BFC6 +:1028700085F929BD8D05E87C9D008C18F3B733469A +:10288000F7C80F454C2CC5BB7163078FED8BDF4339 +:10289000DE656BC17D3A4FF5FC9B3DE45DB683E39D +:1028A0001C74BFF2A03583E42FDC87A6107BE0DB2D +:1028B000703EF585F3E3109C5F98BE05E7575F58BF +:1028C000EF6FE1FCC2FCAD394B18B61BEFD0C6ED83 +:1028D000C8F6B7D9C78262D23DFC6ECB7BB517C2B2 +:1028E000F79D98EC71683F7F27E6BA71B8DE776292 +:1028F000120D3CB598291DB8AF6F57F2A1DC07C186 +:10290000F1C6D3787AF84A78EAE128E1FB5F80E7FC +:10291000175DC1F394909F3BAC7F8C4A4A47FF5DA3 +:102920009478C7F277792AE4CFE0D492315EF50645 +:102930009AE7A8FA11CC3898FC36B908D71A2B8731 +:1029400097DE6EC5B6241A42E377BF307BBEC5F171 +:10295000BFDCA8D2BDF10B2F87913DEAB49FDBDB32 +:102960008A14CF77488F35AA6335BE3FCADEE1EFC0 +:102970009CB1EF0EA54E8AFC1174BA85DFB7AFB1DA +:102980008EEF128F529FFA0F878BF80813EF454A8C +:10299000B9A29785BF4B20DF2FEC4ECE1816CEF98B +:1029A000602F8B781741E015DA513E05FA19067C45 +:1029B0002EE5D170D22FEA7BB8E2070C0DDA113A7E +:1029C0007A45F891DF8E0A0CA077B98A8EAA144F47 +:1029D0007C50C477DD3CA0CE960E78BA29D3933ACA +:1029E00000D7A57EA7229F7917D61987F687A383DC +:1029F0006DA43FFE483D346B80E017792C4F735F28 +:102A00004DD29D6AA3F89D8E0FF87DBC856FF3B8FB +:102A1000CD853D548AFFD7C7C58D62598FA2BD7140 +:102A20006CBCC9E97704F98B7C07C89264608E108E +:102A3000393BCC11CE1C21F389C889D5E4239D3DB7 +:102A400035F5A387A76BCA635CFD35E57145059A2B +:102A50007C0FF7F59AFA89D3C668F2C99E5B35F503 +:102A6000532A2769F3B8EF00EEBDEB6668DAF5A9E3 +:102A70002FD3D44BF35569CA99CF752C2701F93858 +:102A8000FFCB58B55053FE7454118F1FB7CDA67BA2 +:102A90008A994D3FD3F427F19B12C7F1CB1CFC7CE4 +:102AA000F0C17FE4B710782E4CD29E1B63EDA30FCC +:102AB000DB29D5DA35527E200E6ACE7F950E6A99D3 +:102AC000960EE2791C4FE1DB831D28C7E8F18FFEEB +:102AD00088D075A23F22142EE88F08CDA33F22B4E0 +:102AE0003EFA2342CBD11F115A3EF8A816FF438F5E +:102AF00069F17FDD4763FE533C8D68D5D2831E4F5D +:102B0000379CD6D2C7284F38C1652CC86348EF120E +:102B10004FD3E03F3AE7993B1AED06373117DD0B0B +:102B2000F89FC2D7333A7C7DC3560FC5772E2F79D5 +:102B3000391FEFEE9C7FA28FEB79E41FEF0B3EAFC6 +:102B4000B703C87852DF188E4FDFF130E257DF1A33 +:102B50005A23F1FCF8A9DA4A76F964D6FE16BE3F8C +:102B6000638AF7FC1AF95822460F40F95373EFCCE9 +:102B7000C7736EE6BF585251AE99D987BF27C87246 +:102B80005BE99D16399F99293CFE68DF00C1A79D2E +:102B90003C0EE9B5015CBE8E74DA290EDA9BCB449B +:102BA0009C274B9D3910E9F0DDB06CA4B375DCCEE9 +:102BB000D56A72505C8B0FE811FD94286FA33CDC42 +:102BC0005BC8A38D1F5BAD9CEE98E67CEFE7B76A10 +:102BD000E270076CB76BF2039B9334F507ED7768EF +:102BE000CAF303399AF2C1479D9AFCD063C335F505 +:102BF000AFFBC8A5C98F682DD2D4BFE1B45B934F9A +:102C000061ED4F223CBF1A90CEE3FB156107707057 +:102C1000BCCCFC6902DDA7917A848CCBF6083AD64D +:102C2000EB237DCC1E8AF36E4C664EBA0F6215FA0A +:102C300020D3EA291E11572DE579E6D3C655CB7866 +:102C4000EA4E7D46E82F529F0889A776E1FC653C55 +:102C50007527DEC5FB927AFAFC87C0BB7E1D7DCC52 +:102C6000FCFE57E3FD66BAC722E7A79FD7CD221E19 +:102C700070ABB5EBF7876CB9DC6EF068BADB980B1C +:102C8000F59E85E389E079D578CE561FC0B7F1E788 +:102C900066E752C70F8F3773105F4F29BEAB9A4B51 +:102CA000EF74D2BD35396EAF5C4EDF863CA5CBF5F7 +:102CB000CD8CE6F15D2CDA4CF72EBA1F8FC335C9E7 +:102CC000CC96D13B49E21EC2DDAB9BD7606845A9DB +:102CD000B9C9C4DFD5F79BD04E543C06E4C07CE0B4 +:102CE000135B77AEB381BCF66CBD91EC3E19B9F1C4 +:102CF000778204D979AFA40FE8694827C5887FE8AF +:102D000077C3401EEF3C2E97AFAF50FDAEF33E8031 +:102D100045C3E7B9FED705DD113DCA75FC6FDD0F70 +:102D200090F4AB8793D4AF9938BFFA8A7949F87594 +:102D3000DA4F04FCE4FD0CC702937BB38DEE7914EB +:102D4000615C99C4DF4B03395DFE04E13194D743E4 +:102D50007ED45DBD4235371AEDE01DCC116DFF010B +:102D60007BF0FFD2BD09827F77F7BDBAE31357F13D +:102D7000876EEE7F75479FF4F723EE8185F0091E7D +:102D8000EF23F0E1EF6B20BFFACA48ED3EDE9ACBAD +:102D9000E17BABD84F706EDBF2B57C82A15DBF7179 +:102DA000B92AF8C4ECCEDF9FC0EFB3969B48BE664D +:102DB000CCBD1EE30C3E5F67A2B8D8512E46724CC4 +:102DC000D946C5BF49C173746412CEDFEBD39EC729 +:102DD0003731E70AF47F94AFD27E9F63E3BF53316C +:102DE0004BFF6E8AD0D7E7FC80BEBE3E579CE34EB9 +:102DF000E624B94BF8FF2B451BBDDCD5E1E77E335C +:102E0000D4B7556E77A2B83179BE3BD07F13F21E8E +:102E100008C0333C07CFF165C62EE3F93AE1D94D3E +:102E2000BCC2799B8857B0F1F88C8E3D61DCBF291C +:102E3000FD4AA2FE79DF652AC7FAD8DB857C1E77BA +:102E400021FD497A7F5587CD40FE968E3D91E49FC6 +:102E5000473F4E34D0C159C3EE84E169C1F9795A74 +:102E6000558D1F449F7A96BC42FA62628627908BEA +:102E700071D846A7D509F9876C07E9FDA86261F703 +:102E8000D2CFB753EF1AC9DF77E9F07179B6A388CB +:102E9000BFC3017C91E13E927108250CB45448BD3A +:102EA0008111349F1FEBCF997C259FFB31AFDC4014 +:102EB000ED3DAB4650BECFB2350BF01ECC1D8D7331 +:102EC0004CE8C26E7D72716138346DEDED5F1A8E23 +:102ED000781BAD7469976F13E759AB2EBE5EA625BC +:102EE000821FCD1B28F9B888435AA2D03E58A8307B +:102EF0001997447C5CE62F37897C21CF2F5ACEF37B +:102F0000ADE27DFD6DC28E82EBC614D78D7AFF0EC9 +:102F10006167C175638AEBC6EFC8B7308F7C0BF36E +:102F2000C8B7308F7C0B53E45BF8BD8CB953F355B5 +:102F3000EE871A17BAEFAE58D9B890FD827EA8D0A6 +:102F40003CFAA142EBA31F2AB41CFD50A1E5E8877F +:102F50000ACDA31F2AB43EFAA142F36CF82DC13C5E +:102F6000F2395789263F19E4FC7121FB1BFD50A162 +:102F7000FDA31F4AD39F6781A6FD5DAC5ED31EFDF6 +:102F800050A1F5EFA957347EAA7BC43BA7E51BE20D +:102F9000887E221DEED48180E77F8BF8C77DA674E2 +:102FA000C473CB5CAE97853B399E9B8A38DE0D8C13 +:102FB000E3B97D3AE179B199E70B797CB29E7ED095 +:102FC000DF33CEC4FD3D98A2BF0753F4F7608AFEFD +:102FD0009E7199DCDF8329FA7BF03BFA7B30457FD9 +:102FE0000FA6E8EFC114FD3D98A2BF0753F4F760A8 +:102FF0003BF4F7608AFE1EFC8EFE1E4CD1DF83DFA1 +:103000008FA3DFC9149C17CAF17D35FA23D0A146DE +:103010007FB46BF228C787D647393EB41CE5F8D099 +:103020007294E343F328C787D647393E343F33D7FA +:1030300041FB0BE5F9D07628CF87E60736F9DE426B +:10304000DBD9848D170F63DA1AA93CAB00CBB867C4 +:10305000E74B771A413E6B0D53526380739A94DDB0 +:10306000778E83BC47C4FFE5B17603E2DB23DE53F2 +:10307000F70418C55B0EFC5B32953F23EF87E11F19 +:10308000E03D7F0FA3DF2591FE62D9DEC9EC2AA6C1 +:10309000B27E30DF753DFDF8B21EF1CF9079E00DC4 +:1030A000608C57C95F6C2BC078CF6D0685E224B663 +:1030B0002DE571C27ABA7A6C20F78B6E33EC3E88BC +:1030C000F740DABD0ADD07CE32B2A3A60284535D13 +:1030D000019EBF0F0C8C117EBEBAEBF1BE899CB76E +:1030E000B46F029FA0FB7323DB8F8D8D867E3CBE69 +:1030F000D1F43B29C5662E37603BD42707F814D797 +:10310000E610FA5E3E90F34D8F8F8FFFABE726F20D +:1031100076E1BCDDAF9E8B22384E5CA650BCD4C895 +:103120001DCC85F7737F21E63D604740C5F1BCCBE0 +:10313000F878B25FEFC654BAB7E865ADE392C84716 +:10314000A230E4DB126EB0BEC3B83E501B8EA27D2F +:10315000FA5AEFFDDC3824A610E3E8580BA3772CCD +:10316000270C795FB35E42FB30EA97CEB56C9F4285 +:10317000EF054FF42D598A6431C1B7E0AD1E587F79 +:103180000B73A639E828A27BB1723EFD5DBB0D70C2 +:103190002CB25C76CC10A620BED9A1B810FA819DC5 +:1031A0003F05F19DEF34D1FBBD2546BB89DE8FE89D +:1031B00026FEE4B24DC69FE8E4055D9C49E3E28F3C +:1031C00052D19EBC30D240F6DF85AFF0DF03F06C09 +:1031D0005088AF4939C82BE2D42E2F7BABC754841B +:1031E000FB6E13F527E34F6A33FCA9068CABEFB9EE +:1031F000292F562539E000F2C373BEDFDC391CEB02 +:103200002DE7EF585E5E764774807AE2FE9A0A01F7 +:10321000AF0A11C7E4C507BDD5E0EF69C9FB1DAC16 +:1032200089CB7BD29EE3FDDDE023885FEF33E25D57 +:10323000E9555EBA97AD8F239ABBCC44714773753D +:103240007261B5900BAB7F402EFC78A04E2E94BFE0 +:103250009722DA30B5D78718B727EF25969AF8FE68 +:103260002FDDCDC80E5BBA64AC81DE417E85D34DC7 +:10327000E9122EDF94BEEAA2FB85525E7C4FC83174 +:1032800093AEA410DCFF28E4963B30BE12E05BDC7A +:103290001A26E2B092299D7A85C75B4EB2713ED064 +:1032A000FA067F07A2C367E1F2D461C6DF31D3D14A +:1032B0006589D16FC00B77CE914097909F80721037 +:1032C000F4370DE5A238A4F3B4428ADF2B52E8DECE +:1032D0008B9ECE8B4D756F617C68F156E6F4B150D4 +:1032E0003A07FAC5FE7C0ABD0FE0117AADA45F3D36 +:1032F000BDCF8C10F6281BB73775DA255046C54769 +:10330000BA7DA6A918FF3A137D7B3D39C160DC590F +:10331000642E2F8FDB659ABA0CEF2A7463A7507F57 +:1033200066267878E43B08DDD80DD05E807CF2EE2E +:103330007BF3CD65217CF2E4A0318307F508E2BB85 +:10334000ACF3BE5F2EBD0BBAF0A14CFA3D9CEEE48F +:10335000E172802BEE8B99D1ADF7E12FB315E431FB +:10336000D7B824FC7D41261F210F601CE10C91BFC2 +:10337000272FEFCFAB6C0417CAE7ED8A9B8A712128 +:10338000B5D6D6F14876F3733D45788F31C89FDCCA +:10339000AE1405F9537E0075C29BB3F83D2FBD3DB9 +:1033A000E29E3C5E5F6F9728CFE57C5BFE2ECA896C +:1033B00087F6EDC2F34ACEFF4437BFC330358FCB1B +:1033C000B3FF53F720F4F71F66F5F414E5C17CD77B +:1033D0001BF87DFE9E6A1313F621F20B4B7EC1C4CF +:1033E0003B1841BCBBE81DDDC687147BA87DCAB372 +:1033F0004AE1F7E8BBB1E3B09CF627B742BB990DB1 +:1034000066FA1DBFE7B238FD3C07F443BF97623E42 +:10341000F696352D08C74FEB7F69A2DFA561814C79 +:103420007C7F67465D9813F9F1C941EE9938EF88C2 +:103430005C27F1A1C183387D65C4BBBD7978FF6E7F +:10344000F58167F13D81F92D69F47B25DEFDF92BCE +:10345000F09D9393833CB3B1DC6BB3D37B1AF396AB +:10346000C5D0F9353351DC0B65EDE46793F07F305F +:103470008FEB89D73999F8BD2D71DF01186489A6C2 +:103480009E88EFD6ED0F6927D4DB19F4EF4B7467F4 +:103490005F90F604B41F9843EC8CD23E61CA393178 +:1034A0001DE58652B3F65EA24C7F2DE62FF5C0597E +:1034B0009DE756EEF844948FD72A767A6FD2E69835 +:1034C0003A02F215474D18D9C98A631D667C7FA060 +:1034D0001DF08BF1D165B05F91CF948A38AD8A0D24 +:1034E0002368BF55F821EDE21D4E99DEB5F650EF89 +:1034F00057917E022EF25B56D85DE6D8907D5FDE56 +:10350000A468DE1D90F9E7F2545A672988E308BFE2 +:10351000BBEF4D33E3DB3EA5204660FCDFAF057D0E +:10352000C876508FE2418AD3D911FE0E3CCC3B8D38 +:103530008F5710D27F5913BF372DF3509FE49F1739 +:10354000F222A93FAF1DD69D86A99DE609702038BD +:10355000B5AF81FE1C340EE1A33CE037A1BE5D8A0D +:103560007128909F61F79B709CB265FC1D13CF6A18 +:103570003E8E67558C7920CA4746BBB937C22F9C0F +:103580009F57303F92232B002E781F0BEFBBE1D9C2 +:10359000A2878F57CCB7A22986DE51087E5F6B4287 +:1035A0007C4CEFE65D844F05DECB968DA6FBEB15DC +:1035B0004617DD73F008F87EBE20EC61F40F4C5F17 +:1035C000F784290DFDF882CF7C2AE05A9C1EC8A4FE +:1035D000F78A168439719ED3ED4DB4BE4EF83E0E77 +:1035E000F050F09D1B37C117E8C287717B15EBB413 +:1035F000F80CCE87C3B7629D97F6DB6CA3C76C0F40 +:103600009DC786039978AF6A3AEC6F7C5782D93DA3 +:10361000745FF28BC7A7A6D23A619E08D748A7630A +:103620003CBE3F0474C2EFC188F5C87BDD72BCCBE1 +:1036300079FC1EFCE51FDC972E926B1A01BF68F720 +:10364000EE6E5F9A9171C3B8E60AFE3B12FA7D2ACC +:10365000F7A7DC97729FCAFDFBACC91D4852827C5C +:1036600006CED9BA97BB80D3E0411C0F33045E016C +:10367000AE8743EF79F51AC4F15A9AAEDDEFD81F41 +:10368000F66B95E5630299F82E93AC2FC72D8DE567 +:10369000ED90EE91DEAC830C9DF517527DED3D95DE +:1036A000F24E7EB1637902F28BDD0AF783AE39D434 +:1036B000FBA728BFEEE4F2EBB99AADF3F0BC644689 +:1036C0007F6AE8FBFEB340CE413E315B9CCF158163 +:1036D000AEF9C553599EE44121FBB9E2B19D591E93 +:1036E000CE6F02C86FFEB2F3F53F5DEF089EA77282 +:1036F0003D65ABDE37796DA1F0E37ACEC3391D7439 +:103700001FAFDC667660BC73F9322FF15F960472EE +:10371000A112127FA6A30BEF3285EE9195D70FF37E +:10372000ABFF837CBA7C7509BD7B20F126DF6791F6 +:10373000E7AB9CFF4831FF9B06F1F633047DCFA831 +:103740001C6D4E8E27B91BC32CD974F17D7A85F67A +:103750007B27DE3AFDD7B92B70BFE0FD22D24F5652 +:103760009BB8BD6F07B73F9E5BB8EFF77742BDB31D +:10377000EB37A532558B379453670B79758EB0FFB5 +:10378000758137F7A090389E39CF71BC95EFFADD7F +:1037900067F89E5869BAE0776BF83B0065CDBB09C6 +:1037A0008FD357AD35A5213F1A94A6E1E3E575F90E +:1037B00076B42BCF58B5C9847CC223E1A0DB0FA51A +:1037C000224E58C219CF2525C4BF21EB237FC4F751 +:1037D000EFEF5D101685F13C729C87049D97D7C56D +:1037E000C4E278E575DE5FA03E24CF03FD3A4F8644 +:1037F000F1FD5206FDE1BE3D39DA99BA303728CFE6 +:10380000EAEBFBC4BE7BDAC47FA72625A2F9058AB2 +:103810006B981FEE44FED1B76FAB1FC745FAC67950 +:103820009B0DFC776DFAD6B47E85F3E8CB785C0D02 +:10383000A6F83E16FA171220BFD9C0EF6FA5AB3C11 +:10384000DD26E003E5012C67F1ADF4FB1A2171B32D +:103850001AFA35B32DF4FB89E67846EF9B497A9541 +:10386000FD487A95F4DCDDFA9EBDC6F59D4CE3F08B +:10387000348BDF4DB9E6F559F8EFE8CA75C9F9811F +:103880000CEFA2F73D1E1848F69E934B9CA91837E3 +:10389000D9FD7AD7152674B15EFD3AE5BE91B1F037 +:1038A0009DFEAC26EE7738A9C0F906ED4E2E08A392 +:1038B000F836B9AE1F6B0F3F382856D8775A2351C8 +:1038C000CE2C0D0FDE9747F81DAFE7BFAF2BBF4BD8 +:1038D000B940BE3327F9F7A93A716EB2D635B8BFF1 +:1038E000597D06BD7F72BCE96424BEC77272349FE5 +:1038F0009F6C77AF89DF4F66916607DE138BB8F751 +:10390000FDC244F40FAD4BCB57A0DDDDF5838FE353 +:10391000FBE3772F4B24FD7E96CDB102CFC559BE78 +:1039200034F20747ACCBFF02DFD19BB56C00FD6ED4 +:10393000EFBD0A73933E29F484D9ACF38FF4843934 +:1039400082AFCD417E89F7A5EA0FD1BB79B39D61E6 +:10395000F978BECFD9C0F58462035B85FEC43E8D85 +:10396000EEF1C8C7DA9F54F8EF3E6FD4BEC3959C02 +:10397000EDFE0CF98CFEDDBB7B4DCD2E5C07037993 +:1039800004ED4EB36C6E92EB4B05BD1C5FD746BF8A +:103990009789F0A6DFCBD1D96FFA98F93DE2F648C6 +:1039A00003D9E300EFEFE1EF91E17BEB163A6FB45F +:1039B000F69B3E0F0EA7DF6B93F7842A84DF49D274 +:1039C0008FF45FCDDA3499EE0FCD427BCDE0E0FD90 +:1039D000A915EBC6D2FB4E156B0BD7E3EFDCA40A9F +:1039E000389E32B696207E4E6F4A8CC57BB915B58F +:1039F0008D59785FA862D34ABA37747A5318DD1BA1 +:103A00001A672F1987BF1F327B23BF9F27F7A3CDCC +:103A1000C9F76355ED58BAF7F3FF00B910AD8C0044 +:103A2000800000001F8B080000000000000BCD5636 +:103A30005B6C1465143EFF3F7BEFECA5ED527AA161 +:103A4000EDB6E5B2EAB69DA51403189834802412A9 +:103A50005D0805368176088114686B4593164364CA +:103A600061951088711F5AA104CC52A1BEA8D986B5 +:103A70004621AE66A541A236B18117129266FB526D +:103A80002E11BB564D69A2E039FFCC660997C44799 +:103A9000E7E5ECFFCFB97FDF39B3ED0F473EF1D457 +:103AA00000ECAA02F02C01F82B91178F3080F6431E +:103AB000972A240E10B06A56650EC03E9EDCBCCC20 +:103AC00007708FC5074B84BE6FAE47067844CFAAF8 +:103AD000A7E5E421009F15A0E3BD9BC2CF7D3EFA80 +:103AE0007A18EDDB3B2EBAC8CFBEBE1B4B3D783FEC +:103AF000B7462B541AC9EFB9418F0400A7CED5851C +:103B00006A01BC0AFEC6FBF505A1CD61CC2BF3A36F +:103B1000A40CF89E1FAFED1226DD903B6F8FBB2DDE +:103B20001000D05260F190F480A500E51D097A12D2 +:103B300028D75743EB463977BF48417BACF38E3BE0 +:103B40005611C2FB3D83272B7C28EF3AF5F3B6C113 +:103B50002D3F810BF5CF5B2D407626B02868B7331B +:103B6000C2D4384A682B0028C9C50F2A7922FF3DE4 +:103B7000A730A9C2DC3D405CDCDF35C13ACAA332C4 +:103B80009A09BE85F29629B50BB0CE5B5D7625828B +:103B900058C88A4FE4732B26ADA5FBC83B0C1630E2 +:103BA0003A5F74CEC7F82D6EE8227BE792448A7B99 +:103BB000B1CFC3F98BA97DF8702802E8F4E8873506 +:103BC00092BCB60CDFEF1F621E2BBADC7FF9EA5AFB +:103BD000D0CF00ECF9FDDCFB6005F81ECB7BEFF0ED +:103BE00090C587F1DA3FC77A317E7B62E88752F46D +:103BF000D3796947831E3706B014F3A09F18A773C3 +:103C000058EF4BC7F084656720E76787BFE0681906 +:103C100062BB29D1B8A50FF576106ECB910F752F29 +:103C20006C3D6C22E911FD0153A622E40438EEBF7D +:103C30006ED1C8CFFB863FFFF5A3D5A2DE0D85F080 +:103C4000181F9A15B3B0CBDA633F845DAAC3710C19 +:103C5000EA01D44ED94432DA21BB489EE9E27E1310 +:103C6000F655650E45C27EF7D85C75E00698B1EB57 +:103C700032E9D065370F0DEDC61467F8981D90F73F +:103C8000DD528C915C15E862D869307BB57D341FBC +:103C9000C59060201A916294F7D4B7B71B28FECA6A +:103CA000CAF41F802999D9CB5B57233FDE568CFA83 +:103CB00002E906E2F99C2BD04AFC3A6B8663F6C512 +:103CC00054770836D69217FC4DB8CFF2F805CC2FB2 +:103CD000C9529F92FF6CBD9F115FD14FC82A1F63CD +:103CE00098E79F95DA41CAE30D66AE0D72C2405A5D +:103CF00040FEA7CCFA7B889D546DC88B269D16503C +:103D0000CE210248594B69B14CBC66AA0A3D18FF46 +:103D100048E0CA4EE2C7898C0DAC18376AF4A32973 +:103D2000E39860A8575EBA8E431DEAFBBCB00DED68 +:103D3000AF0478C48A799E005B9CF4C1B6464DFB03 +:103D4000F5188FAAD13FB7AB423F796D96A12C935E +:103D50007E1F71A37E593753A2A8D3323D79F6173F +:103D600094DB201EA4BEAEF66A7DB40FC6A7D74D65 +:103D70006888EF094FC2467346CFE3F9270FCCBAE4 +:103D80000A782EAFA9CCE4175F2F21695318DA35D2 +:103D900025A594B5EEE97CA68A7D268A837A294EEC +:103DA000FA328F3346FA233729BF269B9C925C64F4 +:103DB00067FE356DCBD9C15879FEE44B20207E5487 +:103DC000065014D5715B69CC611697CB0A17B85CA5 +:103DD00036F0C9F64F248FF3B1DFA6CFC777F2E0F4 +:103DE00076E24F765EDF34EEA71F54BB69BF4C27E7 +:103DF0006BDC1078FE7CDEC0FD0A8B005EAB52BF30 +:103E0000A77EE1A3DAD07FB3D11FC41BC8AF64F88B +:103E10006D36FAD42C73BD2F9B9EE88BC1932C0F6B +:103E2000B2796771CEE207EF8E5D755709DC6A3FA4 +:103E30000281D7CFC4BBF1D9D10F70ACA0545227A7 +:103E4000B4AAFF235E29FB22E475A68F2B03C47F4F +:103E50006AFC6221558EF5811FC43E68911CCAF12F +:103E600067EC038DF6413DED839898F3199EB9CA2E +:103E700019ED832E712E86CC61139EC779DA49F92C +:103E8000A6EDC87A94EE60B5D8E36534D1353A4EE4 +:103E900034D7670F38078EA37E94A9FD36B48F9A66 +:103EA0008D79DF23C72FE0FD549C47CC18AF373FF7 +:103EB000DEBF1BEF7B9BE72911ECD314187A6D0E44 +:103EC000B11756702ECE9970517CA08AF471AEB1A4 +:103ED000CEDEF08BE23BFED543744E752F00FD7DA8 +:103EE00010169EA2F71BFCC2DF37D93DF3A153F891 +:103EF000EBDDA09638C4FB224EF6870B357BB091E4 +:103F000070D5F5F08F80D03B7D5A2D213C4E6FB49B +:103F100008BD8F5928BC8BFCD4CACA05F49B0E3B44 +:103F2000BE1CD4E14831BC1FEFD1EBCDF2F7D585F3 +:103F3000FA1EAC8C4CF403B628D204FE2EE4FD38F5 +:103F4000F1B03E870F53118B821C4E593E46CC88F0 +:103F50009757C7EB087B1A2FAF8117EB41DEBA08E2 +:103F6000B784E8FF0CD771E896209D8735495C2916 +:103F7000B6A21CF36AF3F53AC74AE87D8B35DD1823 +:103F80000B109ED09678C61CD6D3929D23EA63343C +:103F900067AD06CF5BB37C3CF8041FD3F3F227F385 +:103FA0000C3EA2FD4D472848F1EEB31B4BE972F4DD +:103FB0001F69EBB3E22C0FEA7BE437ABB68CF4E17C +:103FC000FC5C2EF688479FEBD1E0ED72FACEC0DFA5 +:103FD00023F3E8BBD35F187A85F4ECF333168DFA3C +:103FE000599231533DE3E17BE5F47FA6B5E79A981A +:103FF0009BFF9AE7BF3AB4AF4B200A0000000000D5 +:104000000000000000000000000000180000000098 +:104010000000000000000040000000000000000060 +:104020000000002800000000000000000000001058 +:104030000000000000000000000000200000000060 +:104040000000000000000010000000000000000060 +:104050000000000800000000000000000000000058 +:104060000000000000000000000000000000000050 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:104090000000000000000000000000000000000020 +:1040A0000000000000000000000000000000000010 +:1040B0000000000000000000000000000000000000 +:1040C00000000000000000000000000000000000F0 +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000000000000000000000000000C0 +:1041000000000000000000000000000000000000AF +:10411000000000000000000000000000000000009F +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000000000000000000006F +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:104170000000332800100000000000080000333069 +:1041800000100000000000020000332800100000B2 +:104190000000001000003A78000000000000000855 +:1041A000000000000000000000000000000000000F +:1041B00000000000000000000000000000000000FF +:1041C0000000000000003120000000000000000896 +:1041D00000003360000100040000000100003368AB +:1041E000000000000000000200003370000000002A +:1041F000000000080000337400000000000000020E +:1042000000003A70000000000000000800003A4082 +:10421000000800000000000800003D880040000089 +:104220000000004000003A500008000000000008B4 +:1042300000003A60000800000000000800003A8812 +:1042400000C800000000009800003C180098000022 +:104250000000002800003C580098000000000028E2 +:1042600000003378036000300000036000003EB0BF +:10427000000800000000000100003EB1000800003E +:1042800000000001000020080010000000000010E5 +:1042900000002000000000000000000800000000F6 +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:10433000000000000000000000000000000000007D +:10434000000000000000000000000000000000006D +:10435000000000000000000000000000000000005D +:10436000000000000000000000000000000000004D +:10437000000000000000000000000000000000003D +:10438000000000000000000000000000000000002D +:10439000000000000000000000000000000000001D +:1043A000000000000000000000000000000000000D +:1043B00000000000000000000000000000000000FD +:1043C00000000000000000000000000000000000ED +:1043D00000000000000000000000000000000000DD +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000012C892 +:10445000008000000000008000000001000000005B +:1044600000000000000040000490000000000490E4 +:10447000000019C8000000000000000800004948C2 +:1044800000080000000000080000492800080000A3 +:104490000000000800004938000800000000000883 +:1044A00000002008001000000000001000002000A4 +:1044B00000000000000000080000401004900040D0 +:1044C00000000040000049980008000000000001C2 +:1044D00000004999000800000000000100000000F1 +:1044E00000000000000000000000000000000000CC +:1044F00000000000000000000000000000000000BC +:1045000000000000000000000000000000000000AB +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:104600000000000000000000000040000018000052 +:1046100000000018000043000040000000000040BF +:1046200000004300004000020000000100004301C0 +:1046300000400002000000000000300000400000C8 +:10464000000000400000000000000000000000002A +:1046500000003000000800400000000400003004AA +:10466000000800400000000400004B00002800008B +:104670000000002800004B50001000000000001057 +:1046800000003800008000000000008000003800BA +:104690000008008000000002000039000020000037 +:1046A00000000020000020080010000000000010A2 +:1046B0000000200000000000000000080000510879 +:1046C0000008000000000008000051200008000061 +:1046D0000000000800005130000800000000000841 +:1046E000000051C00008000000000001000051C19E +:1046F0000008000000000001000039400010000424 +:1047000000000004000051D000300018000000102C +:10471000000051D800300018000000020000000026 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D000000000000000000000000000000023E8CE +:1047E00000800000000000800000000100000000C8 +:1047F0000000000000002008001000000000001071 +:1048000000002000000000000000000800002DA0B3 +:10481000000800000000000800002DB8000800009B +:1048200000000008000024E802D00028000002D0A8 +:1048300000002E58000800000000000100002E5962 +:10484000000800000000000100002D90000800009A +:104850000000000800000000000000000000000050 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000250062 +:1049300000400000000000080000250800400000C2 +:1049400000000028000009C001200010000000083D +:104950000000000000000000000000000000000057 +:1049600000000000000000000000402002D00028ED +:1049700000000008000030000000000000001000EF +:10498000000050990000000000000001000050B03D +:104990000000000000000002000045A00090000898 +:1049A00000000008000000000000000000000000FF +:1049B00000002960000800000000000100002961DB +:1049C0000008000000000001000029700008000439 +:1049D0000000000200002978000800040000000424 +:1049E00000002FB0000800000000000400002FB4F9 +:1049F000000800000000000400002FC000000000BC +:104A00000000000800002FC800000000000000089F +:104A100000003000000000000000001000005040C6 +:104A20000001000100000001000050000000000033 +:104A30000000002000000808001000000000000432 +:104A40000000080C0010000000000001000008B782 +:104A50000000000000000001000008B60000000097 +:104A600000000001000010000030001800000004E9 +:104A700000001004003000180000000400001008BE +:104A800000300018000000020000100A003000187A +:104A9000000000020000100C0030001800000001AF +:104AA0000000100D00300018000000010000100E82 +:104AB0000030001800000001000010100030001845 +:104AC0000000000400001014003000180000000472 +:104AD00000003000010000800008000400003004E5 +:104AE00001000080000800040000000A000000002F +:104AF000000000000000306801000080000000019C +:104B00000000306901000080000000010000306CEE +:104B100001000080000000020000306E01000080F3 +:104B2000000000020000307001000080000000045E +:104B300000003074010000800000000400003066B6 +:104B400001000080000000020000306401000080CD +:104B50000000000100003060010000800000000241 +:104B600000003062010000800000000200003050B0 +:104B700001000080000000040000305401000080AB +:104B80000000000400003058010000800000000414 +:104B90000000305C01000080000000040000307C58 +:104BA00001000080000000010000307D0100008055 +:104BB0000000000100001C180010000000000004AC +:104BC00000001C30001000000000000400001C3831 +:104BD00000100000000000040000000000000000C1 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C0000000000000000000000004C100008000040 +:104C10000000000200004C1200080000000000022A +:104C200000004C14000800000000000400004C20AC +:104C3000000800000000000800004C3000400008A0 +:104C40000000000800004C00000800000000000206 +:104C500000004C02000800000000000100004C04AD +:104C6000000800000000000200004CD00008000016 +:104C70000000000800004CE00008000000000004F4 +:104C800000004CE4000800000000000100004CF0AF +:104C9000000800000000000200004CF400080000C2 +:104CA0000000000200004D000008000000000004A9 +:104CB000000050000010000000000004000050043C +:104CC0000010000000000004000050080010000068 +:104CD00000000004000014000008000000000002B2 +:104CE000000014020008000000000001000014048D +:104CF000000800000000000200001410000800007E +:104D0000000000020000141400080000000000026F +:104D1000000014160008000000000002000019B88E +:104D20000008000000000008000014200008000037 +:104D3000000000020000142400080000000000022F +:104D4000000019C8000800000000000800002C1036 +:104D5000000800000000000100002C110008000005 +:104D60000000000100002C120008000000000001FB +:104D700000002C13000800000000000100002C00BF +:104D8000000800000000000200002C0200080000E3 +:104D90000000000100002C040008000000000002D8 +:104DA00000002C30000800000000000200002C323F +:104DB000000800000000000200002C340008000081 +:104DC0000000000200002C2000080000000000018C +:104DD00000002C21000800000000000100002C222F +:104DE000000800000000000100002C230008000063 +:104DF0000000000100002C24000800000000000159 +:104E000000002C25000800000000000100002C26F6 +:104E1000000800000000000100001400000800006D +:104E20000000000200001402000800000000000161 +:104E3000000014040008000000000002000014122A +:104E400000C00018000000020000141000C000188C +:104E5000000000020000141C00C000180000000840 +:104E60000000141400C000180000000800001427FF +:104E700000C00018000000010000142400C0001849 +:104E8000000000020000142600C00018000000010D +:104E9000000015900008000000000008000015A0A8 +:104EA0000008000000000008000015B00008000025 +:104EB00000000008000000000000000000000000EA +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:105000000000000000000000060022000000000078 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex new file mode 100644 index 000000000000..54f36f1d256d --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex @@ -0,0 +1,13178 @@ +:1000000000004F48000000680000070C00004FB8D7 +:1000100000001ED4000056C800000094000075A027 +:1000200000009EFC00007638000000CC000115386E +:100030000000DC6400011608000000940001F2706A +:10004000000040180001F308000000A4000233285B +:100050000000F378000233D000000FFC00032750AB +:100060000000000400033750020400480000000FA5 +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040004000000FF02040008000000FF79 +:100170000204000C000000FF02040010000000FF59 +:10018000020400140000007F02040018000000FFB9 +:100190000204001C000000FF02040020000000FF19 +:1001A000020400240000003E0204002800000000B9 +:1001B0000204002C0000003F020400300000003F59 +:1001C000020400340000003F020400380000003F39 +:1001D0000204003C0000003F020400400000003F19 +:1001E000020400440000003F020404CC00000001AF +:1001F00002042008000002110204200C000002008A +:10020000020420100000020402042014000002195D +:100210000204201C0000FFFF020420200000FFFF5A +:10022000020420240000FFFF020420280000FFFF3A +:1002300002042038000000200604203C0000001FBB +:10024000020420B800000001060420BC0000005F8A +:100250000204223807FFFFFF0204223C0000003F97 +:100260000204224007FFFFFF020422440000000FA7 +:1002700001042248000000000104224C000000009C +:10028000010422500000000001042254000000007C +:1002900001042258000000000104225C000000005C +:1002A000010422600000000001042264000000003C +:1002B00001042268000000000104226C000000001C +:1002C00001042270000000000104227400000000FC +:1002D00001042278000000000104227C00000000DC +:1002E0000C042000000003E80A04200000000001C4 +:1002F0000B0420000000000A0605400000000D006D +:100300000205004400000020020500480000003201 +:10031000020500900215002002050094021500203D +:1003200002050098000000300205009C0810000043 +:10033000020500A000000033020500A40000003008 +:10034000020500A800000031020500AC0000000218 +:10035000020500B000000005020500B40000000620 +:10036000020500B800000002020500BC0000000207 +:10037000020500C000000000020500C400000005E6 +:10038000020500C800000002020500CC00000002C7 +:10039000020500D000000002020500D400000001A8 +:1003A00002050114000000010205011C000000010B +:1003B0000205012000000002020502040000000105 +:1003C0000205020C0000004002050210000000407F +:1003D0000205021C0000002002050220000000139C +:1003E0000205022400000020060502400000000A69 +:1003F00004050280002000000205005000000007F4 +:10040000020500540000000702050058000000002B +:100410000205005C00000008020500600000000109 +:100420000605006400000003020500D80000000675 +:1004300002050004000000010205000800000001A0 +:100440000205000C00000001020500100000000180 +:100450000205001400000001020500180000000160 +:100460000205001C00000001020500200000000140 +:100470000205002400000001020500280000000120 +:100480000205002C00000001020500300000000100 +:1004900002050034000000010205003800000001E0 +:1004A0000205003C000000010205004000000001C0 +:1004B000020500E00000000D020500E80000000059 +:1004C000020500F000000000020500F80000000036 +:1004D000020500E40000002D020500EC00000020F1 +:1004E000020500F400000020020500FC00000020CE +:1004F000020500E00000001D020500E800000010F9 +:10050000020500F000000010020500F800000010D5 +:10051000020500E40000003D020500EC0000003090 +:10052000020500F400000030020500FC000000306D +:10053000020500E00000004D020500E80000004058 +:10054000020500F000000040020500F80000004035 +:10055000020500E40000006D020500EC00000060F0 +:10056000020500F400000060020500FC00000060CD +:10057000020500E00000005D020500E800000050F8 +:10058000020500F000000050020500F800000050D5 +:10059000020500E40000007D020500EC0000007090 +:1005A000020500F400000070020500FC000000706D +:1005B0000406100002000020020600DC000000011A +:1005C000010600D80000000004060200000302201B +:1005D000020600DC00000000010600B80000000078 +:1005E000010600C8000000000206016C00000000C7 +:1005F000010600BC00000000010600CC0000000065 +:1006000002060170000000000718040000910000BD +:10061000081807D800050223071C00002BDC000087 +:10062000071C80002DE90AF8071D00002F521673E1 +:10063000071D800015DB2248081DB0B049EA0225DD +:100640000118000000000000011800040000000074 +:1006500001180008000000000118000C0000000054 +:100660000118001000000000011800140000000034 +:1006700002180020000000010218002400000002FF +:1006800002180028000000030218002C00000000DF +:1006900002180030000000040218003400000001BD +:1006A00002180038000000000218003C00000001A1 +:1006B000021800400000000402180044000000007E +:1006C00002180048000000010218004C000000035E +:1006D0000218005000000000021800540000000141 +:1006E00002180058000000040218005C000000001E +:1006F00002180060000000010218006400000003FE +:1007000002180068000000000218006C00000001E0 +:1007100002180070000000040218007400000000BD +:1007200002180078000000040218007C000000039A +:100730000618008000000002021800A400003FFF1D +:10074000021800A8000003FF0218022400000000A5 +:1007500002180234000000000218024C00000000E1 +:10076000021802E4000000FF061810000000040058 +:10077000021B8BC000000001021B8000000000343F +:10078000021B804000000018021B80800000000C4B +:10079000021B80C0000000200C1B83000007A1206A +:1007A0000A1B8300000001380B1B83000000138824 +:1007B0000A1B8340000000000C1B8340000001F472 +:1007C0000B1B834000000005021B83800007A12053 +:1007D000021B83C0000001F4021B14800000000112 +:1007E0000A1B148000000000061A1000000003B36A +:1007F000041A1ECC00010227061A1ED000000008B1 +:10080000061A2008000000C8061A20000000000296 +:10081000041AAF4000100228061A3718000000041E +:10082000061A371000000002061A500000000002ED +:10083000061A500800000004061A501800000004B0 +:10084000061A502800000004061A50380000000460 +:10085000061A504800000004061A50580000000410 +:10086000061A506800000004061A507800000002C2 +:10087000041A52C000020238061A40500000000656 +:10088000041A40680002023A041A40400004023C84 +:10089000041A800000010240061A800400000003D0 +:1008A000041A801000010241061A8014000000039F +:1008B000041A802000010242061A8024000000036E +:1008C000041A803000010243061A8034000000033D +:1008D000041A804000010244061A8044000000030C +:1008E000041A805000010245061A805400000003DB +:1008F000041A806000010246061A806400000003AA +:10090000041A807000010247061A80740000000378 +:10091000041A808000010248061A80840000000347 +:10092000041A809000010249061A80940000000316 +:10093000041A80A00001024A061A80A400000003E5 +:10094000041A80B00001024B061A80B400000003B4 +:10095000041A80C00001024C061A80C40000000383 +:10096000041A80D00001024D061A80D40000000352 +:10097000041A80E00001024E061A80E40000000321 +:10098000041A80F00001024F061A80F400000003F0 +:10099000041A810000010250061A810400000003BD +:1009A000041A811000010251061A8114000000038C +:1009B000041A812000010252061A8124000000035B +:1009C000041A813000010253061A8134000000032A +:1009D000041A814000010254061A814400000003F9 +:1009E000041A815000010255061A815400000003C8 +:1009F000041A816000010256061A81640000000397 +:100A0000041A817000010257061A81740000000365 +:100A1000041A818000010258061A81840000000334 +:100A2000041A819000010259061A81940000000303 +:100A3000041A81A00001025A061A81A400000003D2 +:100A4000041A81B00001025B061A81B400000003A1 +:100A5000041A81C00001025C061A81C40000000370 +:100A6000041A81D00001025D061A81D4000000033F +:100A7000041A81E00001025E061A81E4000000030E +:100A8000041A81F00001025F061A81F400000003DD +:100A9000041A820000010260061A820400000003AA +:100AA000041A821000010261061A82140000000379 +:100AB000041A822000010262061A82240000000348 +:100AC000041A823000010263061A82340000000317 +:100AD000041A824000010264061A824400000003E6 +:100AE000041A825000010265061A825400000003B5 +:100AF000041A826000010266061A82640000000384 +:100B0000041A827000010267061A82740000000352 +:100B1000041A828000010268061A82840000000321 +:100B2000041A829000010269061A829400000003F0 +:100B3000041A82A00001026A061A82A400000003BF +:100B4000041A82B00001026B061A82B4000000038E +:100B5000041A82C00001026C061A82C4000000035D +:100B6000041A82D00001026D061A82D4000000032C +:100B7000041A82E00001026E061A82E400000003FB +:100B8000041A82F00001026F061A82F400000003CA +:100B9000041A830000010270061A83040000000397 +:100BA000041A831000010271061A83140000000366 +:100BB000041A832000010272061A83240000000335 +:100BC000041A833000010273061A83340000000304 +:100BD000041A834000010274061A834400000003D3 +:100BE000041A835000010275061A835400000003A2 +:100BF000041A836000010276061A83640000000371 +:100C0000041A837000010277061A8374000000033F +:100C1000041A838000010278061A8384000000030E +:100C2000041A839000010279061A839400000003DD +:100C3000041A83A00001027A061A83A400000003AC +:100C4000041A83B00001027B061A83B4000000037B +:100C5000041A83C00001027C061A83C4000000034A +:100C6000041A83D00001027D061A83D40000000319 +:100C7000041A83E00001027E061A83E400000003E8 +:100C8000041A83F00001027F061A83F400000003B7 +:100C9000041A840000010280061A84040000000384 +:100CA000041A841000010281061A84140000000353 +:100CB000041A842000010282061A84240000000322 +:100CC000041A843000010283061A843400000003F1 +:100CD000041A844000010284061A844400000003C0 +:100CE000041A845000010285061A8454000000038F +:100CF000041A846000010286061A8464000000035E +:100D0000041A847000010287061A8474000000032C +:100D1000041A848000010288061A848400000003FB +:100D2000041A849000010289061A849400000003CA +:100D3000041A84A00001028A061A84A40000000399 +:100D4000041A84B00001028B061A84B40000000368 +:100D5000041A84C00001028C061A84C40000000337 +:100D6000041A84D00001028D061A84D40000000306 +:100D7000041A84E00001028E061A84E400000003D5 +:100D8000041A84F00001028F061A84F400000003A4 +:100D9000041A850000010290061A85040000000371 +:100DA000041A851000010291061A85140000000340 +:100DB000041A852000010292061A8524000000030F +:100DC000041A853000010293061A853400000003DE +:100DD000041A854000010294061A854400000003AD +:100DE000041A855000010295061A8554000000037C +:100DF000041A856000010296061A8564000000034B +:100E0000041A857000010297061A85740000000319 +:100E1000041A858000010298061A858400000003E8 +:100E2000041A859000010299061A859400000003B7 +:100E3000041A85A00001029A061A85A40000000386 +:100E4000041A85B00001029B061A85B40000000355 +:100E5000041A85C00001029C061A85C40000000324 +:100E6000041A85D00001029D061A85D400000003F3 +:100E7000041A85E00001029E061A85E400000003C2 +:100E8000041A85F00001029F061A85F40000000391 +:100E9000041A8600000102A0061A8604000000035E +:100EA000041A8610000102A1061A8614000000032D +:100EB000041A8620000102A2061A862400000003FC +:100EC000041A8630000102A3061A863400000003CB +:100ED000041A8640000102A4061A8644000000039A +:100EE000041A8650000102A5061A86540000000369 +:100EF000041A8660000102A6061A86640000000338 +:100F0000041A8670000102A7061A86740000000306 +:100F1000041A8680000102A8061A868400000003D5 +:100F2000041A8690000102A9061A869400000003A4 +:100F3000041A86A0000102AA061A86A40000000373 +:100F4000041A86B0000102AB061A86B40000000342 +:100F5000041A86C0000102AC061A86C40000000311 +:100F6000041A86D0000102AD061A86D400000003E0 +:100F7000041A86E0000102AE061A86E400000003AF +:100F8000041A86F0000102AF061A86F4000000037E +:100F9000041A8700000102B0061A8704000000034B +:100FA000041A8710000102B1061A8714000000031A +:100FB000041A8720000102B2061A872400000003E9 +:100FC000041A8730000102B3061A873400000003B8 +:100FD000041A8740000102B4061A87440000000387 +:100FE000041A8750000102B5061A87540000000356 +:100FF000041A8760000102B6061A87640000000325 +:10100000041A8770000102B7061A877400000003F3 +:10101000041A8780000102B8061A878400000003C2 +:10102000041A8790000102B9061A87940000000391 +:10103000041A87A0000102BA061A87A40000000360 +:10104000041A87B0000102BB061A87B4000000032F +:10105000041A87C0000102BC061A87C400000003FE +:10106000041A87D0000102BD061A87D400000003CD +:10107000041A87E0000102BE061A87E4000000039C +:10108000041A87F0000102BF061A87F4000000036B +:10109000041A8800000102C0061A88040000000338 +:1010A000041A8810000102C1061A88140000000307 +:1010B000041A8820000102C2061A882400000003D6 +:1010C000041A8830000102C3061A883400000003A5 +:1010D000041A8840000102C4061A88440000000374 +:1010E000041A8850000102C5061A88540000000343 +:1010F000041A8860000102C6061A88640000000312 +:10110000041A8870000102C7061A887400000003E0 +:10111000041A8880000102C8061A888400000003AF +:10112000041A8890000102C9061A8894000000037E +:10113000041A88A0000102CA061A88A4000000034D +:10114000041A88B0000102CB061A88B4000000031C +:10115000041A88C0000102CC061A88C400000003EB +:10116000041A88D0000102CD061A88D400000003BA +:10117000041A88E0000102CE061A88E40000000389 +:10118000041A88F0000102CF061A88F40000000358 +:10119000041A8900000102D0061A89040000000325 +:1011A000041A8910000102D1061A891400000003F4 +:1011B000041A8920000102D2061A892400000003C3 +:1011C000041A8930000102D3061A89340000000392 +:1011D000041A8940000102D4061A89440000000361 +:1011E000041A8950000102D5061A89540000000330 +:1011F000041A8960000102D6061A896400000003FF +:10120000041A8970000102D7061A897400000003CD +:10121000041A8980000102D8061A8984000000039C +:10122000041A8990000102D9061A8994000000036B +:10123000041A89A0000102DA061A89A4000000033A +:10124000041A89B0000102DB061A89B40000000309 +:10125000041A89C0000102DC061A89C400000003D8 +:10126000041A89D0000102DD061A89D400000003A7 +:10127000041A89E0000102DE061A89E40000000376 +:10128000041A89F0000102DF061A89F40000000345 +:10129000041A8A00000102E0061A8A040000000312 +:1012A000041A8A10000102E1061A8A1400000003E1 +:1012B000041A8A20000102E2061A8A2400000003B0 +:1012C000041A8A30000102E3061A8A34000000037F +:1012D000041A8A40000102E4061A8A44000000034E +:1012E000041A8A50000102E5061A8A54000000031D +:1012F000041A8A60000102E6061A8A6400000003EC +:10130000041A8A70000102E7061A8A7400000003BA +:10131000041A8A80000102E8061A8A840000000389 +:10132000041A8A90000102E9061A8A940000000358 +:10133000041A8AA0000102EA061A8AA40000000327 +:10134000041A8AB0000102EB061A8AB400000003F6 +:10135000041A8AC0000102EC061A8AC400000003C5 +:10136000041A8AD0000102ED061A8AD40000000394 +:10137000041A8AE0000102EE061A8AE40000000363 +:10138000041A8AF0000102EF061A8AF40000000332 +:10139000041A8B00000102F0061A8B0400000003FF +:1013A000041A8B10000102F1061A8B1400000003CE +:1013B000041A8B20000102F2061A8B24000000039D +:1013C000041A8B30000102F3061A8B34000000036C +:1013D000041A8B40000102F4061A8B44000000033B +:1013E000041A8B50000102F5061A8B54000000030A +:1013F000041A8B60000102F6061A8B6400000003D9 +:10140000041A8B70000102F7061A8B7400000003A7 +:10141000041A8B80000102F8061A8B840000000376 +:10142000041A8B90000102F9061A8B940000000345 +:10143000041A8BA0000102FA061A8BA40000000314 +:10144000041A8BB0000102FB061A8BB400000003E3 +:10145000041A8BC0000102FC061A8BC400000003B2 +:10146000041A8BD0000102FD061A8BD40000000381 +:10147000041A8BE0000102FE061A8BE40000000350 +:10148000041A8BF0000102FF061A8BF4000000031F +:10149000041A8C0000010300061A8C0400000003EB +:1014A000041A8C1000010301061A8C1400000003BA +:1014B000041A8C2000010302061A8C240000000389 +:1014C000041A8C3000010303061A8C340000000358 +:1014D000041A8C4000010304061A8C440000000327 +:1014E000041A8C5000010305061A8C5400000003F6 +:1014F000041A8C6000010306061A8C6400000003C5 +:10150000041A8C7000010307061A8C740000000393 +:10151000041A8C8000010308061A8C840000000362 +:10152000041A8C9000010309061A8C940000000331 +:10153000041A8CA00001030A061A8CA40000000300 +:10154000041A8CB00001030B061A8CB400000003CF +:10155000041A8CC00001030C061A8CC4000000039E +:10156000041A8CD00001030D061A8CD4000000036D +:10157000041A8CE00001030E061A8CE4000000033C +:10158000041A8CF00001030F061A8CF4000000030B +:10159000041A8D0000010310061A8D0400000003D8 +:1015A000041A8D1000010311061A8D1400000003A7 +:1015B000041A8D2000010312061A8D240000000376 +:1015C000041A8D3000010313061A8D340000000345 +:1015D000041A8D4000010314061A8D440000000314 +:1015E000041A8D5000010315061A8D5400000003E3 +:1015F000041A8D6000010316061A8D6400000003B2 +:10160000041A8D7000010317061A8D740000000380 +:10161000041A8D8000010318061A8D84000000034F +:10162000041A8D9000010319061A8D94000000031E +:10163000041A8DA00001031A061A8DA400000003ED +:10164000041A8DB00001031B061A8DB400000003BC +:10165000041A8DC00001031C061A8DC4000000038B +:10166000041A8DD00001031D061A8DD4000000035A +:10167000041A8DE00001031E061A8DE40000000329 +:10168000041A8DF00001031F061A8DF400000003F8 +:10169000041A8E0000010320061A8E0400000003C5 +:1016A000041A8E1000010321061A8E140000000394 +:1016B000041A8E2000010322061A8E240000000363 +:1016C000041A8E3000010323061A8E340000000332 +:1016D000041A8E4000010324061A8E440000000301 +:1016E000041A8E5000010325061A8E5400000003D0 +:1016F000041A8E6000010326061A8E64000000039F +:10170000041A8E7000010327061A8E74000000036D +:10171000041A8E8000010328061A8E84000000033C +:10172000041A8E9000010329061A8E94000000030B +:10173000041A8EA00001032A061A8EA400000003DA +:10174000041A8EB00001032B061A8EB400000003A9 +:10175000041A8EC00001032C061A8EC40000000378 +:10176000041A8ED00001032D061A8ED40000000347 +:10177000041A8EE00001032E061A8EE40000000316 +:10178000041A8EF00001032F061A8EF400000003E5 +:10179000041A8F0000010330061A8F0400000003B2 +:1017A000041A8F1000010331061A8F140000000381 +:1017B000041A8F2000010332061A8F240000000350 +:1017C000041A8F3000010333061A8F34000000031F +:1017D000041A8F4000010334061A8F4400000003EE +:1017E000041A8F5000010335061A8F5400000003BD +:1017F000041A8F6000010336061A8F64000000038C +:10180000041A8F7000010337061A8F74000000035A +:10181000041A8F8000010338061A8F840000000329 +:10182000041A8F9000010339061A8F9400000003F8 +:10183000041A8FA00001033A061A8FA400000003C7 +:10184000041A8FB00001033B061A8FB40000000396 +:10185000041A8FC00001033C061A8FC40000000365 +:10186000041A8FD00001033D061A8FD40000000334 +:10187000041A8FE00001033E061A8FE400000007FF +:10188000041A62C00020033F061AD0000000007254 +:10189000061AD24800000010061AD6B00000002038 +:1018A000061AD47000000090061AD46800000002E6 +:1018B000061AA000000001C4061A30000000001043 +:1018C000061A308000000010061A310000000010D7 +:1018D000061A318000000010061A330000000012C2 +:1018E000061A339000000070061AD4580000000257 +:1018F000061AD34800000002061AD3580000002040 +:10190000061AA710000001C4061A3040000000109B +:10191000061A30C000000010061A31400000001006 +:10192000061A31C000000010061A334800000012E9 +:10193000061A355000000070061AD460000000023C +:10194000061AD35000000002061AD3D80000002067 +:10195000021AAE2000000000061A5000000000022B +:10196000061A508000000012041A40000002035FB3 +:10197000041A63C000020361061A7000000000042C +:10198000061A320000000008021AAE24000000000F +:10199000061A501000000002061A50C8000000127B +:1019A000041A400800020363041A63C800020365B6 +:1019B000061A701000000004061A32200000000809 +:1019C000021AAE2800000000061A50200000000293 +:1019D000061A511000000012041A4010000203679A +:1019E000041A63D000020369061A70200000000484 +:1019F000061A324000000008021AAE2C0000000057 +:101A0000061A503000000002061A51580000001259 +:101A1000041A40180002036B041A63D80002036D15 +:101A2000061A703000000004061A32600000000838 +:101A3000021AAE3000000000061A504000000002FA +:101A4000061A51A000000012041A40200002036F81 +:101A5000041A63E000020371061A704000000004DB +:101A6000061A328000000008021AAE34000000009E +:101A7000061A505000000002061A51E80000001239 +:101A8000041A402800020373041A63E80002037575 +:101A9000061A705000000004061A32A00000000868 +:101AA000021AAE3800000000061A50600000000262 +:101AB000061A523000000012041A40300002037768 +:101AC000041A63F000020379061A70600000000433 +:101AD000061A32C000000008021AAE3C00000000E6 +:101AE000061A507000000002061A52780000001218 +:101AF000041A40380002037B041A63F80002037DD5 +:101B0000061A707000000004061A32E00000000897 +:101B10000200A468000B01C80200A294071D29114D +:101B20000200A298000000000200A29C009C042475 +:101B30000200A2A0000000000200A2A4000002090E +:101B40000200A270000000000200A2740000000069 +:101B50000200A270000000000200A2740000000059 +:101B60000200A270000000000200A2740000000049 +:101B70000200A270000000000200A2740000000039 +:101B8000020160A000000001020160A400000262E6 +:101B9000020160A800000002020160AC0000001811 +:101BA0000201620400000001020100B40000000113 +:101BB000020100B800000001020100DC0000000189 +:101BC0000201010000000001020101040000000107 +:101BD0000201007C003000000201008400000028A7 +:101BE0000201008C0000000002010130000000042E +:101BF0000201025C00000001020103280000000055 +:101C0000020160580000FFFF020160700000000741 +:101C10000201608000000001020105540000003054 +:101C2000020100C400000001020100CC000000011C +:101C3000020100F800000001020100F000000001B4 +:101C4000020100800030000002010088000000282E +:101C500002010090000000000201013400000004B5 +:101C6000020102DC000000010201032C0000000060 +:101C70000201605C0000FFFF0201607400000007C9 +:101C800002016084000000010201056400000030D0 +:101C9000020100C800000001020100D000000001A4 +:101CA000020100FC00000001020100F4000000013C +:101CB000020C100000000028020C20080000021195 +:101CC000020C200C00000200020C20100000020494 +:101CD000020C201C0000FFFF020C20200000FFFF70 +:101CE000020C20240000FFFF020C20280000FFFF50 +:101CF000020C203800000020020C203C00000021D3 +:101D0000020C204000000022020C204400000023AE +:101D1000020C204800000024020C204C000000258A +:101D2000020C205000000026020C20540000002766 +:101D3000020C205800000028020C205C0000002942 +:101D4000020C20600000002A020C20640000002B1E +:101D5000020C20680000002C020C206C0000002DFA +:101D6000020C20700000002E020C20740000002FD6 +:101D7000020C207800000010060C207C00000007F8 +:101D8000020C209800000011020C209C00000012A0 +:101D9000020C20A000000013060C20A40000001D6F +:101DA000020C211800000001020C211C000000019F +:101DB000020C212000000001060C21240000001D5F +:101DC000020C219800000001060C219C0000000775 +:101DD000020C21B800000001020C21BC000000012F +:101DE000020C21C000000001020C21C4000000010F +:101DF000020C21C800000001020C21CC00000001EF +:101E0000020C21D000000001020C21D400000001CE +:101E1000020C21D800000001020C21DC00000001AE +:101E2000020C21E000000001020C21E4000000018E +:101E3000020C21E800000001020C21EC000000016E +:101E4000020C21F000000001020C21F4000000014E +:101E5000020C21F800000001060C21FC0000000724 +:101E6000020C221800000001060C221C00000007D2 +:101E7000020C223807FFFFFF020C223C0000003F4B +:101E8000020C224007FFFFFF020C22440000000F5B +:101E9000010C224800000000010C224C0000000050 +:101EA000010C225000000000010C22540000000030 +:101EB000010C225800000000010C225C0000000010 +:101EC000010C226000000000010C226400000000F0 +:101ED000010C226800000000010C226C00000000D0 +:101EE000010C227000000000010C227400000000B0 +:101EF000010C227800000000010C227C0000000090 +:101F00000C0C2000000003E80A0C20000000000177 +:101F10000B0C20000000000A020C40080000101109 +:101F2000020C400C00001000020C401000001004D5 +:101F3000020C401400001021020C401C0000FFFFA6 +:101F4000020C40200000FFFF020C40240000FFFFB5 +:101F5000020C40280000FFFF020C40380000004641 +:101F6000020C403C00000010060C40400000000243 +:101F7000020C404800000018020C404C000000F029 +:101F8000060C40500000001F020C40CC0000000175 +:101F9000060C40D00000003A020C41B800000001DD +:101FA000060C41BC00000003020C41C80000000107 +:101FB000020C41CC00000001060C41D00000001AC8 +:101FC000020C423807FFFFFF020C423C0000003FBA +:101FD000020C424007FFFFFF020C42440000000FCA +:101FE000010C424800000000010C424C00000000BF +:101FF000010C425000000000010C4254000000009F +:10200000010C425800000000010C425C000000007E +:10201000010C426000000000010C4264000000005E +:10202000010C426800000000010C426C000000003E +:10203000010C427000000000010C4274000000001E +:10204000010C427800000000010C427C00000000FE +:10205000010C4280000000000C0C4000000003E86E +:102060000A0C4000000000010B0C40000000000AB8 +:10207000060D400000000A00020D0044000000327E +:10208000020D008C02150020020D009002150020A8 +:10209000020D009408100000020D009800000033AB +:1020A000020D009C00000002020D00A000000000D4 +:1020B000020D00A400000005020D00A800000005AC +:1020C000060D00AC00000002020D00B4000000028A +:1020D000020D00B800000003020D00BC0000000269 +:1020E000020D00C000000001020D00C80000000247 +:1020F000020D00CC00000002020D015C0000000196 +:10210000020D016400000001020D016800000002E0 +:10211000020D020400000001020D020C000000206C +:10212000020D021000000040020D021400000040E9 +:10213000020D022000000003020D0224000000181E +:10214000060D028000000012040D03000018037F3A +:10215000060D03600000000C020D004C00000001A1 +:10216000020D005000000002020D005400000000AB +:10217000020D005800000008060D005C000000047D +:10218000020D00C400000004020D00040000000164 +:10219000020D000800000001020D000C000000010B +:1021A000020D001000000001020D001400000001EB +:1021B000020D001800000001020D001C00000001CB +:1021C000020D002000000001020D002400000001AB +:1021D000020D002800000001020D002C000000018B +:1021E000020D003000000001020D0034000000016B +:1021F000020D003800000001020D003C000000014B +:10220000020D011400000009020D011C0000000A6B +:10221000020D012400000000020D012C000000004E +:10222000020D013400000000020D013C0000000B13 +:10223000020D014400000000020D011800000029F9 +:10224000020D01200000002A020D012800000020DC +:10225000020D013000000020020D013800000020B6 +:10226000020D01400000002B020D0148000000207B +:10227000020D011400000019020D011C0000001ADB +:10228000020D012400000010020D012C00000010BE +:10229000020D013400000010020D013C0000001B83 +:1022A000020D014400000010020D01180000003969 +:1022B000020D01200000003A020D0128000000304C +:1022C000020D013000000030020D01380000003026 +:1022D000020D01400000003B020D014800000030EB +:1022E000020D011400000049020D011C0000004A0B +:1022F000020D012400000040020D012C00000040EE +:10230000020D013400000040020D013C0000004BB2 +:10231000020D014400000040020D01180000006998 +:10232000020D01200000006A020D0128000000607B +:10233000020D013000000060020D01380000006055 +:10234000020D01400000006B020D0148000000601A +:10235000020D011400000059020D011C0000005A7A +:10236000020D012400000050020D012C000000505D +:10237000020D013400000050020D013C0000005B22 +:10238000020D014400000050020D01180000007908 +:10239000020D01200000007A020D012800000070EB +:1023A000020D013000000070020D013800000070C5 +:1023B000020D01400000007B020D0148000000708A +:1023C000060E200000000800020E004C0000003243 +:1023D000020E009402150020020E00980215002043 +:1023E000020E009C00000030020E00A00810000049 +:1023F000020E00A400000033020E00A8000000300E +:10240000020E00AC00000031020E00B0000000021D +:10241000020E00B400000004020E00B8000000002C +:10242000020E00BC00000002020E00C0000000020C +:10243000020E00C400000000020E00C800000002EE +:10244000020E00CC00000007020E00D000000002C7 +:10245000020E00D400000002020E00D800000001AD +:10246000020E014400000001020E014C00000001B8 +:10247000020E015000000002020E020400000001E2 +:10248000020E020C00000040020E0210000000408C +:10249000020E021C00000004020E022000000020B8 +:1024A000020E02240000000E020E02280000001B93 +:1024B000060E030000000012040E0280001B0397AA +:1024C000060E02EC00000005020E00540000000C95 +:1024D000020E00580000000C020E005C000000001C +:1024E000020E006000000010020E006400000010E8 +:1024F000060E006800000003020E00DC000000036E +:10250000020E000400000001020E0008000000019D +:10251000020E000C00000001020E0010000000017D +:10252000020E001400000001020E0018000000015D +:10253000020E001C00000001020E0020000000013D +:10254000020E002400000001020E0028000000011D +:10255000020E002C00000001020E003000000001FD +:10256000020E003400000001020E003800000001DD +:10257000020E003C00000001020E004000000001BD +:10258000020E004400000001020E01100000000FC6 +:10259000020E011800000000020E012000000000E1 +:1025A000020E012800000000020E01140000002F9E +:1025B000020E011C00000020020E01240000000099 +:1025C000020E012C00000000020E01100000001F8E +:1025D000020E011800000010020E01200000000091 +:1025E000020E012800000000020E01140000003F4E +:1025F000020E011C00000030020E01240000000049 +:10260000020E012C00000000020E01100000004F1D +:10261000020E011800000040020E01200000000020 +:10262000020E012800000000020E01140000006FDD +:10263000020E011C00000060020E012400000000D8 +:10264000020E012C00000000020E01100000005FCD +:10265000020E011800000050020E012000000000D0 +:10266000020E012800000000020E01140000007F8D +:10267000020E011C00000070020E01240000000088 +:10268000020E012C000000000730040000C800000A +:10269000083007D8000503B207340000332C0000CF +:1026A0000734800030AC0CCC07350000353318F807 +:1026B000073580002A7126450736000018DA30E217 +:1026C00008364670373203B40130000000000000C5 +:1026D000013000040000000001300008000000008C +:1026E0000130000C0000000001300010000000006C +:1026F0000130001400000000023000200000000142 +:102700000230002400000002023000280000000314 +:102710000230002C000000000230003000000004F5 +:1027200002300034000000010230003800000000D8 +:102730000230003C000000010230004000000004B4 +:102740000230004400000000023000480000000198 +:102750000230004C00000003023000500000000076 +:102760000230005400000001023000580000000454 +:102770000230005C00000000023000600000000138 +:102780000230006400000003023000680000000016 +:102790000230006C000000010230007000000004F4 +:1027A00002300074000000000230007800000004D5 +:1027B0000230007C000000030630008000000002B0 +:1027C000023000A400003FFF023000A8000003FF19 +:1027D0000230022400000000023002340000000039 +:1027E0000230024C00000000023002E40000FFFF53 +:1027F000063020000000080002338BC000000001FA +:10280000023380000000001A023380400000004EB6 +:102810000233808000000010023380C000000020DE +:102820000C3383000007A1200A3383000000013825 +:102830000B338300000013880A338340000000003C +:102840000C338340000001F40B338340000000058B +:10285000023383800007A120023383C0000001F40B +:1028600002331480000000010A33148000000000CD +:10287000063280000000010206322008000000C875 +:10288000063220000000000204328EA0001003B6C1 +:1028900006323EB00000000606323ED800000002BC +:1028A00006323E800000000A04323EA8000203C641 +:1028B00006323E00000000200632500000000400F6 +:1028C0000632400000000004043274C0000203C855 +:1028D00006324110000000020632D0000000003035 +:1028E0000632DD40000000440632DA00000000D06D +:1028F0000632DEA0000000020632E0000000080000 +:1029000006328450000001180632100000000188D1 +:102910000632500000000020063251000000002066 +:102920000632520000000020063253000000002052 +:10293000063254000000002006325500000000203E +:10294000063256000000002006325700000000202A +:102950000632580000000020063259000000002016 +:1029600006325A000000002006325B000000002002 +:1029700006325C000000002006325D0000000020EE +:1029800006325E000000002006325F0000000020DA +:1029900006328DF00000000204328E00000203CAED +:1029A00006328E08000000020632DE9000000002AF +:1029B00006321C4000000038063288B000000118C2 +:1029C00006321620000001880632508000000020E8 +:1029D00006325180000000200632528000000020A4 +:1029E0000632538000000020063254800000002090 +:1029F000063255800000002006325680000000207C +:102A00000632578000000020063258800000002067 +:102A1000063259800000002006325A800000002053 +:102A200006325B800000002006325C80000000203F +:102A300006325D800000002006325E80000000202B +:102A400006325F800000002006328DF80000000290 +:102A500004328E10000203CC06328E1800000002F1 +:102A60000632DE980000000206321D200000003809 +:102A700002328D50000000000632401000000002BB +:102A800002328D5400000000063240200000000297 +:102A900002328D5800000000063240300000000273 +:102AA00002328D5C0000000006324040000000024F +:102AB00002328D600000000006324050000000022B +:102AC00002328D6400000000063240600000000207 +:102AD00002328D68000000000632407000000002E3 +:102AE00002328D6C000000000632408000000002BF +:102AF000072004000091000008200780001003CE8A +:102B0000072400002B0B00000724800015080AC3CF +:102B10000824AA10692403D001200000000000004E +:102B20000120000400000000012000080000000057 +:102B30000120000C00000000012000100000000037 +:102B4000012000140000000002200020000000010D +:102B500002200024000000020220002800000003E0 +:102B60000220002C000000000220003000000004C1 +:102B700002200034000000010220003800000000A4 +:102B80000220003C00000001022000400000000480 +:102B90000220004400000000022000480000000164 +:102BA0000220004C00000003022000500000000042 +:102BB0000220005400000001022000580000000420 +:102BC0000220005C00000000022000600000000104 +:102BD00002200064000000030220006800000000E2 +:102BE0000220006C000000010220007000000004C0 +:102BF00002200074000000000220007800000004A1 +:102C00000220007C0000000306200080000000027B +:102C1000022000A400003FFF022000A8000003FFE4 +:102C20000220022400000000022002340000000004 +:102C30000220024C00000000022002E40000FFFF1E +:102C4000062020000000080002238BC000000001C5 +:102C500002238000000000100223804000000012C8 +:102C60000223808000000030022380C00000000E9C +:102C70000C2383000007A1200A23830000000138F1 +:102C80000B238300000013880A2383400000000008 +:102C90000C238340000001F40B2383400000000557 +:102CA000022383800007A120022383C0000001F4D7 +:102CB00002231480000000010A2314800000000099 +:102CC000062210000000004206222008000000C872 +:102CD00006222000000000020622B000000000C60C +:102CE0000422B318000503D20622B32C0000000B07 +:102CF0000422B358000503D70622B36C0000000B72 +:102D00000422B398000503DC0622B3AC0000000BDC +:102D10000422B3D8000503E10622B3EC0000000B47 +:102D20000422B418000503E60622B42C0000000BB0 +:102D30000422B458000503EB0622B46C0000000B1B +:102D40000422B498000503F00622B4AC0000000B86 +:102D50000422B4D8000503F50622B4EC0000000BF1 +:102D60000422B518000503FA0622B52C0000000B5A +:102D70000422B558000503FF0622B56C0000000BC5 +:102D80000422B598000504040622B5AC0000000B2F +:102D90000422B5D8000504090622B5EC0000000B9A +:102DA0000422B6180005040E0622B62C0000000B03 +:102DB0000422B658000504130622B66C0000000B6E +:102DC0000422B698000504180622B6AC0000000BD9 +:102DD0000422B6D80005041D0622B6EC0000000B44 +:102DE0000422B718000504220622B72C0000000BAD +:102DF0000422B758000504270622B76C0000000B18 +:102E00000422B7980005042C0622B7AC0000000B82 +:102E10000422B7D8000504310622B7EC0000000BED +:102E20000422B818000504360622B82C0000000B56 +:102E30000422B8580005043B0622B86C0000000BC1 +:102E40000422B898000504400622B8AC0000000B2C +:102E50000422B8D8000504450622B8EC0000000B97 +:102E60000422B9180005044A0622B92C0000000B00 +:102E70000422B9580005044F0622B96C0000000B6B +:102E80000422B998000504540622B9AC0000000BD6 +:102E90000422B9D8000504590622B9EC0000000B41 +:102EA0000422BA180005045E0622BA2C0000000BAA +:102EB0000422BA58000504630622BA6C0000000B15 +:102EC0000422BA98000504680622BAAC0000000B80 +:102ED0000422BAD80005046D0622BAEC00000005F1 +:102EE0000622BB00000000530422BC4C0001047207 +:102EF0000622BC50000000030422BC5C00010473E5 +:102F00000622BC60000000030422BC6C00010474B3 +:102F10000622BC70000000030422BC7C0001047582 +:102F20000622BC80000000030422BC8C0001047651 +:102F30000622BC90000000030422BC9C0001047720 +:102F40000622BCA0000000030422BCAC00010478EF +:102F50000622BCB0000000030422BCBC00010479BE +:102F60000622880000000100062280000000020006 +:102F7000042212700010047A06223000000000C003 +:102F800006226700000001000622900000000400F5 +:102F900004226B080020048A022212C0FFFFFFFFF8 +:102FA000062211E800000002062212C800000009F3 +:102FB000062212EC0000000906228C000000000826 +:102FC0000222114800000000062213200000000623 +:102FD000062233000000000206226040000000309C +:102FE00006228C20000000080222114C0000000084 +:102FF00006221338000000060622330800000002F3 +:10300000062261000000003006228C40000000080B +:10301000022211500000000006221350000000069A +:103020000622331000000002062261C000000030BA +:1030300006228C60000000080222115400000000EB +:103040000622136800000006062233180000000262 +:10305000062262800000003006228C8000000008FA +:103060000222115800000000062213800000000612 +:1030700006223320000000020622634000000030D8 +:1030800006228CA0000000080222115C0000000053 +:1030900006221398000000060622332800000002D2 +:1030A000062264000000003006228CC000000008E8 +:1030B0000222116000000000062213B0000000068A +:1030C0000622333000000002062264C000000030F7 +:1030D00006228CE0000000080222116400000000BB +:1030E000062213C800000006062233380000000242 +:1030F0000622658000000030021610000000002843 +:1031000002170008000000020217002C0000000354 +:103110000217003C000000040217004800000002F3 +:103120000217004C000000900217005000000090B1 +:103130000217005400800090021700580810000089 +:10314000021700600000008A02170064000000807F +:1031500002170068000000810217006C0000008068 +:10316000021700700000000602170078000007D068 +:103170000217007C0000076C02170038007C100466 +:10318000021700040000000F061640240000000291 +:10319000021640700000001C0216420800000001E8 +:1031A0000216421000000001021642200000000139 +:1031B0000216422800000001021642300000000101 +:1031C00002164238000000010216426000000002B0 +:1031D0000C16401C0003D0900A16401C0000009CF6 +:1031E0000B16401C000009C4021640300000000805 +:1031F000021640340000000C021640380000001097 +:1032000002164044000000200216400000000001A9 +:10321000021640D80000000102164008000000011C +:103220000216400C000000010216401000000001D0 +:103230000216424000000000021642480000000052 +:103240000616427000000002021642500000000004 +:1032500002164258000000000616428000000002DC +:1032600002166008000012240216600C0000121002 +:1032700002166010000012140216601C0000FFFF0E +:10328000021660200000FFFF021660240000FFFF0E +:10329000021660280000FFFF0216603800000020C0 +:1032A0000216603C0000002006166040000000028C +:1032B00002166048000000230216604C0000002443 +:1032C000021660500000002502166054000000261F +:1032D00002166058000000270216605C00000029FA +:1032E000021660600000002A021660640000002BD5 +:1032F000021660680000002C0216606C0000002DB1 +:1033000002166070000000EC0216607400000011EC +:1033100002166078000000120616607C0000000FA4 +:10332000021660B800000001021660BC0000000137 +:10333000061660C00000000C021660F000000001DC +:10334000061660F400000031021661B800000001AA +:10335000061661BC0000000D021661F000000001BD +:10336000061661F4000000110216623807FFFFFF25 +:103370000216623C0000003F0216624007FFFFFF9A +:10338000021662440000000F0116624800000000AF +:103390000116624C0000000001166250000000009F +:1033A000011662540000000001166258000000007F +:1033B0000116625C0000000001166260000000005F +:1033C000011662640000000001166268000000003F +:1033D0000116626C0000000001166270000000001F +:1033E00001166274000000000116627800000000FF +:1033F0000116627C000000000C166000000003E86B +:103400000A166000000000010B1660000000000AB0 +:1034100002168040000000060216804400000005ED +:10342000021680480000000A0216804C00000005C9 +:103430000216805400000002021680CC0000000436 +:10344000021680D000000004021680D400000004A0 +:10345000021680D800000004021680DC0000000480 +:10346000021680E000000004021680E40000000460 +:10347000021680E800000004021688040000000420 +:10348000021680300000007C021680340000003DEF +:10349000021680380000003F0216803C0000009CAD +:1034A000021680F000000007061680F400000005F8 +:1034B0000216880C010101010216810800000000BB +:1034C0000216810C000000040216811000000004A6 +:1034D0000216811400000002021688100801200460 +:1034E00002168118000000050216811C000000056C +:1034F000021681200000000502168124000000054C +:103500000216882C200810010216812800000008ED +:103510000216812C00000006021681300000000710 +:1035200002168134000000000216883001010120DB +:1035300006168138000000040216883401010101DA +:1035400002168148000000000216814C00000004B1 +:10355000021681500000000402168154000000028F +:103560000216883808012004021681580000000560 +:103570000216815C00000005021681600000000553 +:1035800002168164000000050216883C2008100124 +:1035900002168168000000080216816C0000000617 +:1035A00002168170000000070216817400000001FD +:1035B00002168840010101200216817800000001F6 +:1035C0000216817C000000010216818000000001CB +:1035D00002168184000000010216884401010101E5 +:1035E00002168188000000010216818C0000000490 +:1035F000021681900000000402168194000000026F +:10360000021688480801200402168198000000056F +:103610000216819C00000005021681A00000000532 +:10362000021681A40000000502168814200810016B +:10363000021681A800000008021681AC00000006F6 +:10364000021681B000000007021681B400000001DC +:103650000216881801010120021681B8000000013D +:10366000021681BC00000001021681C000000001AA +:10367000021681C4000000010216881C010101012C +:10368000021681C800000001021681CC000000046F +:10369000021681D000000004021681D4000000024E +:1036A0000216882008012004021681D800000005B7 +:1036B000021681DC00000005021681E00000000512 +:1036C000021681E40000000502168824200810017B +:1036D000021681E800000008021681EC00000006D6 +:1036E000021681F0000000070216E40C0000000042 +:1036F00002168828010101200616E41000000004CB +:103700000216E000010101010216E42000000000A1 +:103710000216E424000000040216E428000000045D +:103720000216E42C000000020216E0040801200446 +:103730000216E430000000050216E4340000000523 +:103740000216E438000000050216E43C0000000503 +:103750000216E008200810010216E44000000008EC +:103760000216E444000000060216E44800000007C8 +:103770000216E44C000000000216E00C01010120DA +:103780000616E450000000040216E01001010101D9 +:103790000216E460000000000216E4640000000469 +:1037A0000216E468000000040216E46C0000000247 +:1037B0000216E014080120040216E470000000055F +:1037C0000216E474000000050216E478000000050B +:1037D0000216E47C000000050216E0182008100123 +:1037E0000216E480000000080216E48400000006CF +:1037F0000216E488000000070216E48C00000001B5 +:103800000216E01C010101200216E49000000001F4 +:103810000216E494000000010216E4980000000182 +:103820000216E49C000000010216E02001010101E3 +:103830000216E4A0000000010216E4A40000000447 +:103840000216E4A8000000040216E4AC0000000226 +:103850000216E024080120040216E4B0000000056E +:103860000216E4B4000000050216E4B800000005EA +:103870000216E4BC000000050216E0282008100132 +:103880000216E4C0000000080216E4C400000006AE +:103890000216E4C8000000070216E4CC0000000194 +:1038A0000216E02C010101200216E4D00000000104 +:1038B0000216E4D4000000010216E4D80000000162 +:1038C0000216E4DC000000010216E03001010101F3 +:1038D0000216E4E0000000010216E4E40000000427 +:1038E0000216E4E8000000040216E4EC0000000206 +:1038F0000216E034080120040216E4F0000000057E +:103900000216E4F4000000050216E4F800000005C9 +:103910000216E4FC000000050216E0382008100141 +:103920000216E500000000080216E504000000068B +:103930000216E508000000070216E03C0101012024 +:1039400002168240003F003F021682440000000041 +:103950000216E524003F003F0216E52800000000A3 +:1039600002168248000000000216824C003F003F11 +:103970000216E52C000000000216E530003F003F73 +:10398000021682500100010002168254010001005B +:103990000216E534010001000216E53801000100BD +:1039A00006168258000000020216E53C00000000E6 +:1039B0000216E540000000000216826000C000C050 +:1039C0000216826400C000C00216E54400C000C0B8 +:1039D0000216E54800C000C0021682681E001E00E4 +:1039E0000216826C1E001E000216E54C1E001E0010 +:1039F0000216E5501E001E000216827040004000B4 +:103A000002168274400040000216E5544000400057 +:103A10000216E558400040000216827880008000BF +:103A20000216827C800080000216E55C8000800027 +:103A30000216E560800080000216828020002000CF +:103A400002168284200020000216E5642000200077 +:103A50000216E56820002000061682880000000299 +:103A60000216E56C000000000216E5700000000080 +:103A700002168290000000000216829400000000EE +:103A80000216E574000000000216E5780000000050 +:103A900002168298000000000216829C00000000BE +:103AA0000216E57C000000000216E5800000000020 +:103AB000021682A000000000021682A4000000018D +:103AC000061682A80000000A021681F400000C0805 +:103AD000021681F800000040021681FC000001007F +:103AE0000216820000000020021682040000001767 +:103AF00002168208000000800216820C00000200FC +:103B000002168210000000000216821801FF01FF59 +:103B10000216821401FF01FF0216E51001FF01FFEA +:103B20000216E50C01FF01FF0216823C00000013A3 +:103B3000021680900000013F0216806000000140E4 +:103B40000216806400000140061680680000000232 +:103B500002168070000000C0061680740000000786 +:103B60000216809C00000048021680A00000004859 +:103B7000061680A400000002021680AC0000004877 +:103B8000061680B000000007021682380000800090 +:103B900002168234000025E40216809400007FFFA4 +:103BA00002168220000F000F0216821C000F000F69 +:103BB0000216E518000F000F0216E514000F000FA3 +:103BC000021682280000000002168224FFFFFFFF79 +:103BD0000216E520000000000216E51CFFFFFFFFB3 +:103BE0000216E6BC000000000216E6C0000000025B +:103BF0000216E6C4000000010216E6C80000000339 +:103C00000216E6CC000000040216E6D00000000612 +:103C10000216E6D4000000050216E6D800000007F0 +:103C2000021680EC000000FF0214000000000001FA +:103C30000214000C0000000102140040000000010A +:103C40000214004400007FFF0214000C000000007A +:103C500002140000000000000214006C00000000CC +:103C600002140004000000010214003000000001F2 +:103C700002140004000000000214005C00000000B8 +:103C800002140008000000010214003400000001CA +:103C90000214000800000000021400600000000090 +:103CA00006028000000020000202005800000032DE +:103CB000020200A003150020020200A40315002048 +:103CC000020200A801000030020200AC081000004F +:103CD000020200B000000033020200B40000003015 +:103CE000020200B800000031020200BC0000000324 +:103CF000020200C000000006020200C4000000032F +:103D0000020200C800000003020200CC0000000212 +:103D1000020200D000000000020200D400000002F5 +:103D2000020200DC00000000020200E000000006C9 +:103D3000020200E400000004020200E800000002A9 +:103D4000020200EC00000002020200F0000000018C +:103D5000020200FC00000006020201200000000038 +:103D60000202013400000002020201B00000000162 +:103D70000202020C00000001020202140000000115 +:103D80000202021800000002020204040000000106 +:103D90000202040C00000040020204100000004077 +:103DA0000202041C000000040202042000000020A3 +:103DB0000202042400000002020204280000002085 +:103DC000060205000000001204020480002004AA7C +:103DD000020200600000000F020200640000000701 +:103DE00002020068000000000202006C0000000EE9 +:103DF000020200700000000E0602007400000003C2 +:103E0000020200F4000000040202000400000001AD +:103E100002020008000000010202000C0000000184 +:103E20000202001000000001020200140000000164 +:103E300002020018000000010202001C0000000144 +:103E40000202002000000001020200240000000124 +:103E500002020028000000010202002C0000000104 +:103E600002020030000000010202003400000001E4 +:103E700002020038000000010202003C00000001C4 +:103E800002020040000000010202004400000001A4 +:103E900002020048000000010202004C0000000184 +:103EA000020200500000000102020108000000C8E8 +:103EB0000202011800000002020201C4000000001A +:103EC000020201CC00000000020201D40000000246 +:103ED000020201DC00000002020201E4000000FF17 +:103EE000020201EC000000FF0202010000000000DD +:103EF0000202010C000000C80202011C00000002C6 +:103F0000020201C800000000020201D0000000000F +:103F1000020201D800000002020201E000000002DB +:103F2000020201E8000000FF020201F0000000FFB1 +:103F3000020201040000000002020108000000C8A3 +:103F40000202011800000002020201C40000000089 +:103F5000020201CC00000000020201D400000002B5 +:103F6000020201DC00000002020201E4000000FF86 +:103F7000020201EC000000FF02020100000000004C +:103F80000202010C000000C80202011C0000000235 +:103F9000020201C800000000020201D0000000007F +:103FA000020201D800000002020201E0000000024B +:103FB000020201E8000000FF020201F0000000FF21 +:103FC000020201040000000002020108000000C813 +:103FD0000202011800000002020201C400000000F9 +:103FE000020201CC00000000020201D40000000225 +:103FF000020201DC00000002020201E4000000FFF6 +:10400000020201EC000000FF0202010000000000BB +:104010000202010C000000C80202011C00000002A4 +:10402000020201C800000000020201D000000000EE +:10403000020201D800000002020201E000000002BA +:10404000020201E8000000FF020201F0000000FF90 +:10405000020201040000000002020108000000C882 +:104060000202011800000002020201C40000000068 +:10407000020201CC00000000020201D40000000294 +:10408000020201DC00000002020201E4000000FF65 +:10409000020201EC000000FF02020100000000002B +:1040A0000202010C000000C80202011C0000000214 +:1040B000020201C800000000020201D0000000005E +:1040C000020201D800000002020201E0000000022A +:1040D000020201E8000000FF020201F0000000FF00 +:1040E00002020104000000000728040000A10000F3 +:1040F000082807B8000904CA072C000034F700009C +:10410000072C800039250D3E072D000037CD1B8878 +:10411000072D80003292297C072E00001AF33621E9 +:10412000082E4390378E04CC0128000000000000C8 +:104130000128000400000000012800080000000021 +:104140000128000C00000000012800100000000001 +:1041500001280014000000000228002000000001D7 +:1041600002280024000000020228002800000003AA +:104170000228002C0000000002280030000000048B +:10418000022800340000000102280038000000006E +:104190000228003C0000000102280040000000044A +:1041A000022800440000000002280048000000012E +:1041B0000228004C0000000302280050000000000C +:1041C00002280054000000010228005800000004EA +:1041D0000228005C000000000228006000000001CE +:1041E00002280064000000030228006800000000AC +:1041F0000228006C0000000102280070000000048A +:10420000022800740000000002280078000000046A +:104210000228007C00000003062800800000000245 +:10422000022800A400003FFF022800A8000003FFAE +:1042300002280224000000000228023400000000CE +:104240000228024C00000000022802E40000FFFFE8 +:104250000628200000000800022B8BC0000000018F +:10426000022B800000000000022B8040000000189C +:10427000022B80800000000C022B80C00000006632 +:104280000C2B83000007A1200A2B830000000138BB +:104290000B2B8300000013880A2B834000000000D2 +:1042A0000C2B8340000001F40B2B83400000000521 +:1042B000022B83800007A120022B83C0000001F4A1 +:1042C000022B1480000000010A2B14800000000063 +:1042D000062A9AF800000004042A9B08000204CE73 +:1042E000062A9B1000000006062A90800000004865 +:1042F000062A2008000000C8062A2000000000024C +:10430000062A91A800000086062A900000000020DE +:10431000062A93C800000003042A93D4000104D0A5 +:10432000062A9DA800000002042A9498000404D1E3 +:10433000042A9D58000104D5062A9D5C0000001146 +:10434000042ACB20001004D6042A3000000204E620 +:10435000062A300800000100062A40400000001034 +:10436000042A4000001004E8042A8408000204F82B +:10437000062A9DA000000002062AB000000000509E +:10438000062ABB7000000070062AB150000000022F +:10439000062ABB6000000004062AD00000000800C6 +:1043A000062AC00000000150062A94A8000000322E +:1043B000062A502000000002062A503000000002A9 +:1043C000062A500000000002062A501000000002D9 +:1043D000022A520800000001042A9B28000204FA65 +:1043E000062A963800000022042A96C0000104FC28 +:1043F000062A96C400000003062A976800000022DF +:10440000042A97F0000104FD062A97F40000000337 +:10441000062A989800000022042A9920000104FE30 +:10442000062A992400000003062A99C800000022E9 +:10443000042A9A50000104FF062A9A54000000033F +:10444000062AB14000000002062AC54000000150C3 +:10445000062A957000000032062A5028000000024B +:10446000062A503800000002062A50080000000208 +:10447000062A501800000002022A520C0000000117 +:10448000042A9B3000020500062A96D00000002274 +:10449000042A975800010502062A975C00000003D1 +:1044A000062A980000000022042A988800010503CB +:1044B000062A988C00000003062A9930000000228A +:1044C000042A99B800010504062A99BC00000003DB +:1044D000062A9A6000000022042A9AE800010505D5 +:1044E000062A9AEC00000003062AB14800000002E8 +:1044F000022ACA8000000000042A9B38001005062A +:10450000062A50480000000E022ACA84000000005B +:10451000042A9B7800100516062A50800000000E21 +:10452000022ACA8800000000042A9BB80010052651 +:10453000062A50B80000000E022ACA8C00000000B3 +:10454000042A9BF800100536062A50F00000000EE1 +:10455000022ACA9000000000042A9C380010054678 +:10456000062A51280000000E022ACA94000000000A +:10457000042A9C7800100556062A51600000000E9F +:10458000022ACA9800000000042A9CB800100566A0 +:10459000062A51980000000E022ACA9C0000000062 +:1045A000042A9CF800100576062A51D00000000E5F +:1045B000021010080000000102101050000000015D +:1045C000021010000003D000021010040000003D93 +:1045D0000910180002000586091011000010078656 +:1045E0000610114000000008091011600010079625 +:1045F000061011A00000001806102400000000E0C2 +:104600000210201C00000000021020200000000109 +:10461000021020C00000000202102004000000016F +:10462000021020080000000109103C00000507A648 +:1046300009103800000507AB09103820000507B045 +:1046400006104C000000010002104028000000107D +:104650000210404400003FFF0210405800280000B4 +:10466000021040840084924A02104058000000006A +:104670000210800000001080021080AC00000000DA +:1046800002108038000000100210810000000000BD +:10469000061081200000000202108008000002B510 +:1046A0000210801000000000061082000000004A86 +:1046B000021081080001FFFF061081400000000287 +:1046C0000210800000001A800610900000000024F4 +:1046D000061091200000004A061093700000004A66 +:1046E000061095C00000004A0210800400001080EF +:1046F000021080B0000000010210803C0000001099 +:104700000210810400000000061081280000000251 +:104710000210800C000002B502108014000000009E +:10472000061084000000004A0210810C0001FFFF07 +:1047300006108148000000020210800400001A8068 +:104740000610909000000024061092480000004AD5 +:10475000061094980000004A061096E80000004AEF +:104760000210800000001080021080AC00000002E7 +:1047700002108038000000100210810000000000CC +:10478000061081200000000202108008000002B51F +:104790000210801000000000061082000000004A95 +:1047A000021081080001FFFF061081400000000296 +:1047B0000210800000001A80061090000000002403 +:1047C000061091200000004A061093700000004A75 +:1047D000061095C00000004A0210800400001080FE +:1047E000021080B0000000030210803C00000010A6 +:1047F0000210810400000000061081280000000261 +:104800000210800C000002B50210801400000000AD +:10481000061084000000004A0210810C0001FFFF16 +:1048200006108148000000020210800400001A8077 +:104830000610909000000024061092480000004AE4 +:10484000061094980000004A061096E80000004AFE +:104850000210800000001080021080AC00000004F4 +:1048600002108038000000100210810000000000DB +:10487000061081200000000202108008000002B52E +:104880000210801000000000061082000000004AA4 +:10489000021081080001FFFF0610814000000002A5 +:1048A0000210800000001A80061090000000002412 +:1048B000061091200000004A061093700000004A84 +:1048C000061095C00000004A02108004000010800D +:1048D000021080B0000000050210803C00000010B3 +:1048E0000210810400000000061081280000000270 +:1048F0000210800C000002B50210801400000000BD +:10490000061084000000004A0210810C0001FFFF25 +:1049100006108148000000020210800400001A8086 +:104920000610909000000024061092480000004AF3 +:10493000061094980000004A061096E80000004A0D +:104940000210800000001080021080AC0000000601 +:1049500002108038000000100210810000000000EA +:10496000061081200000000202108008000002B53D +:104970000210801000000000061082000000004AB3 +:10498000021081080001FFFF0610814000000002B4 +:104990000210800000001A80061090000000002421 +:1049A000061091200000004A061093700000004A93 +:1049B000061095C00000004A02108004000010801C +:1049C000021080B0000000070210803C00000010C0 +:1049D000021081040000000006108128000000027F +:1049E0000210800C000002B50210801400000000CC +:1049F000061084000000004A0210810C0001FFFF35 +:104A000006108148000000020210800400001A8095 +:104A10000610909000000024061092480000004A02 +:104A2000061094980000004A061096E80000004A1C +:104A3000021205B0000000010212049000E383405E +:104A40000212051400003C100212066C0000000166 +:104A5000021206700000000002120494FFFFFFFF24 +:104A600002120498FFFFFFFF0212049CFFFFFFFFEA +:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA +:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA +:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82 +:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A +:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A +:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 +:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 +:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 +:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 +:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 +:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 +:104B200002120504FFFFFFFF02120508FFFFFFFF4F +:104B30000212050CFFFFFFFF02120510FFFFFFFF2F +:104B4000021204D4FF809000021204B4F00050005E +:104B5000021204B8F00010000212039000000008D6 +:104B60000212039C00000008021203A000000008CB +:104B7000021203A400000002021203BC00000004A1 +:104B8000021203C000000005021203C4000000046A +:104B9000021203D0000000000212036C00000001AA +:104BA000021203680000003F021201BC0000004036 +:104BB000021201C000001808021201C4000008031C +:104BC000021201C800000803021201CC00000040DC +:104BD000021201D000000003021201D400000803F9 +:104BE000021201D800000803021201DC00000803D1 +:104BF000021201E000010003021201E400000803B8 +:104C0000021201E800000803021201EC0000000398 +:104C1000021201F000000003021201F40000000380 +:104C2000021201F800000003021201FC0000000360 +:104C3000021202000000000302120204000000033E +:104C400002120208000000030212020C000000031E +:104C500002120210000000030212021400000003FE +:104C600002120218000000030212021C00000003DE +:104C700002120220000000030212022400000003BE +:104C800002120228000024030212022C0000002F4E +:104C90000212023000000009021202340000001962 +:104CA00002120238000001840212023C000001835B +:104CB0000212024000000306021202440000001922 +:104CC00002120248000000060212024C0000030615 +:104CD00002120250000003060212025400000306F2 +:104CE0000212025800000C860212025C0000030649 +:104CF00002120260000003060212026400000006B5 +:104D000002120268000000060212026C0000000697 +:104D10000212027000000006021202740000000677 +:104D200002120278000000060212027C0000000657 +:104D30000212028000000006021202840000000637 +:104D400002120288000000060212028C0000000617 +:104D500002120290000000060212029400000006F7 +:104D600002120298000000060212029C00000006D7 +:104D7000021202A000000306021202A400000013A7 +:104D8000021202A800000006021202B00000100485 +:104D9000021202B400001004021203240010644046 +:104DA0000212032800106440021205B40000000142 +:104DB000021201B0000000010600A0000000000C7B +:104DC0000200A050000000000200A05400000000FB +:104DD0000200A0EC555400000200A0F055555555B6 +:104DE0000200A0F4000055550200A0F8F0000000F9 +:104DF0000200A0FC555400000200A1005555555575 +:104E00000200A104000055550200A108F0000000B6 +:104E10000200A18C555400000200A1905555555533 +:104E20000200A194000055550200A198F000000076 +:104E30000200A19C000000000200A1A000010000EF +:104E40000200A1A4000050140200A1A8000000006C +:104E50000200A45C00000C000200A61C000000037D +:104E60000200A06CFF5C00000200A070FFF55FFF75 +:104E70000200A0740000FFFF0200A078F00003E031 +:104E80000200A07C000000000200A0800000A00042 +:104E90000600A084000000050200A0980FE00000BA +:104EA0000600A09C000000070200A0B8000004005B +:104EB0000600A0BC000000030200A0C80000100013 +:104EC0000600A0CC000000030200A0D800004000B3 +:104ED0000600A0DC000000030200A0E800010000C2 +:104EE0000600A22C000000040200A10CFF5C0000E0 +:104EF0000200A110FFF55FFF0200A1140000FFFFF8 +:104F00000200A118F00003E00200A11C0000000054 +:104F10000200A1200000A0000600A124000000055E +:104F20000200A1380FE000000600A13C00000007CD +:104F30000200A158000008000600A15C0000000368 +:104F40000200A168000020000600A16C0000000320 +:104F50000200A178000080000600A17C0000000390 +:104F60000200A188000200000600A23C000000042C +:104F70000200A030000000000200A0340000000089 +:104F80000200A038000000000200A03C0000000069 +:104F90000200A040000000000200A0440000000049 +:104FA0000200A048000000000200A04C0000000029 +:104FB00000000000000000000000003000000000C1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE0000000000000300031000000000000000060 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:10501000003100520000000000000000000000000D +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000052008995 +:1050400000000000000000000089008D008D00912C +:1050500000910095009500990099009D009D00A188 +:1050600000A100A500A500A900A900AE00AE00B1F6 +:1050700000B100B4000000000000000000000000CB +:105080000000000000000000000000000000000020 +:105090000000000000B40309030903130313031DF8 +:1050A000031D03240324032B032B03320332033990 +:1050B00003390340034003470347034E034E0355A0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:105170000355035B0000000000000000035B035CBC +:10518000035C035D035D035E035E035F035F036017 +:1051900003600361036103620362036300000000B4 +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000363036D036D037B1B +:1051D000037B0389000000000000000000000000C5 +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:105220000389038A00000000000000000000000065 +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000038A03D6F8 +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000003D604010000000050 +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000040104330000000000000000C2 +:1052B0000433043A043A0441044104480448044FC6 +:1052C000044F04560456045D045D04640464046BD6 +:1052D000046B04A4000000000000000004A404A863 +:1052E00004A804AC04AC04B004B004B404B404B81E +:1052F00004B804BC04BC04C004C004C404C4051342 +:105300000513052A052A05410541054305430545C1 +:1053100005450547054705490549054B054B054D1D +:10532000054D054F054F0551055105E805E805E90F +:1053300005E905EA05EA05EF05EF05F405F405F9C9 +:1053400005F905FE05FE0603060306080608060D18 +:10535000060D0612061206130000000000000000F1 +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:1053800006130624000000000000000000000000DA +:10539000000000000000000000000000000000000D +:1053A0000000000000000000000000000624063994 +:1053B0000639063C063C063F0000000000000000E5 +:1053C00000000000000000000000000000000000DD +:1053D0000000000000000000063F0675000000000D +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:1054000000000000067507780000000000000000A2 +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:105430000778077F077F078307830787000000003F +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000078707C8EF +:10546000000000000000000007C807D107D107DADC +:1054700007DA07E307E307EC07EC07F507F507FE94 +:1054800007FE080708070810081008670867087C67 +:10549000087C089108910894089408970897089A3E +:1054A000089A089D089D08A008A008A308A308A6BC +:1054B00008A608A908A908B2000000000000000022 +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00008B208B800000000000000000000000042 +:1054F00000000000000000000000000000000000AC +:1055000000000000000000000000000008B808BB18 +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000008BB08C100000000DF +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:1055700008C108D008D008DF08DF08EE08EE08FDF3 +:1055800008FD090C090C091B091B092A092A0939FC +:10559000093909AA00000000000000000000000016 +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000009AA09BF70 +:1055C00009BF09D009D009E109E109E209E209E3CB +:1055D00009E309E409E409E509E509E609E609E75B +:1055E00009E709E809E809E90000000000000000F7 +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C000000000000000000000010000000204C013 +:1056D0000003098000040E4000051300000617C0F7 +:1056E00000071C800008214000092600000A2AC08B +:1056F000000B2F80000C3440000D3900000E3DC01F +:10570000000F42800010474000114C00001250C0B2 +:105710000013558000145A4000155F00001663C046 +:105720000017688000186D4000197200001A76C0DA +:10573000001B7B80001C8040001D8500001E89C06E +:10574000001F8E80000093400000200000004000F9 +:1057500000006000000080000000A0000000C00009 +:105760000000E000000100000001200000014000F6 +:1057700000016000000180000001A0000001C000E5 +:105780000001E000000200000002200000024000D2 +:1057900000026000000280000002A0000002C000C1 +:1057A0000002E000000300000003200000034000AE +:1057B00000036000000380000003A0000003C0009D +:1057C0000003E0000004000000042000000440008A +:1057D00000046000000480000004A0000004C00079 +:1057E0000004E00000050000000520000005400066 +:1057F00000056000000580000005A0000005C00055 +:105800000005E00000060000000620000006400041 +:1058100000066000000680000006A0000006C00030 +:105820000006E0000007000000072000000740001D +:1058300000076000000780000007A0000007C0000C +:105840000007E000000800000008200000084000F9 +:1058500000086000000880000008A0000008C000E8 +:105860000008E000000900000009200000094000D5 +:1058700000096000000980000009A0000009C000C4 +:105880000009E000000A0000000A2000000A4000B1 +:10589000000A6000000A8000000AA000000AC000A0 +:1058A000000AE000000B0000000B2000000B40008D +:1058B000000B6000000B8000000BA000000BC0007C +:1058C000000BE000000C0000000C2000000C400069 +:1058D000000C6000000C8000000CA000000CC00058 +:1058E000000CE000000D0000000D2000000D400045 +:1058F000000D6000000D8000000DA000000DC00034 +:10590000000DE000000E0000000E2000000E400020 +:10591000000E6000000E8000000EA000000EC0000F +:10592000000EE000000F0000000F2000000F4000FC +:10593000000F6000000F8000000FA000000FC000EB +:10594000000FE000001000000010200000104000D8 +:1059500000106000001080000010A0000010C000C7 +:105960000010E000001100000011200000114000B4 +:1059700000116000001180000011A0000011C000A3 +:105980000011E00000120000001220000012400090 +:1059900000126000001280000012A0000012C0007F +:1059A0000012E0000013000000132000001340006C +:1059B00000136000001380000013A0000013C0005B +:1059C0000013E00000140000001420000014400048 +:1059D00000146000001480000014A0000014C00037 +:1059E0000014E00000150000001520000015400024 +:1059F00000156000001580000015A0000015C00013 +:105A00000015E000001600000016200000164000FF +:105A100000166000001680000016A0000016C000EE +:105A20000016E000001700000017200000174000DB +:105A300000176000001780000017A0000017C000CA +:105A40000017E000001800000018200000184000B7 +:105A500000186000001880000018A0000018C000A6 +:105A60000018E00000190000001920000019400093 +:105A700000196000001980000019A0000019C00082 +:105A80000019E000001A0000001A2000001A40006F +:105A9000001A6000001A8000001AA000001AC0005E +:105AA000001AE000001B0000001B2000001B40004B +:105AB000001B6000001B8000001BA000001BC0003A +:105AC000001BE000001C0000001C2000001C400027 +:105AD000001C6000001C8000001CA000001CC00016 +:105AE000001CE000001D0000001D2000001D400003 +:105AF000001D6000001D8000001DA000001DC000F2 +:105B0000001DE000001E0000001E2000001E4000DE +:105B1000001E6000001E8000001EA000001EC000CD +:105B2000001EE000001F0000001F2000001F4000BA +:105B3000001F6000001F8000001FA000001FC000A9 +:105B4000001FE00000200000002020000020400096 +:105B500000206000002080000020A0000020C00085 +:105B60000020E00000210000002120000021400072 +:105B700000216000002180000021A0000021C00061 +:105B80000021E0000022000000222000002240004E +:105B900000226000002280000022A0000022C0003D +:105BA0000022E0000023000000232000002340002A +:105BB00000236000002380000023A0000023C00019 +:105BC0000023E00000240000002420000024400006 +:105BD00000246000002480000024A0000024C000F5 +:105BE0000024E000002500000025200000254000E2 +:105BF00000256000002580000025A0000025C000D1 +:105C00000025E000002600000026200000264000BD +:105C100000266000002680000026A0000026C000AC +:105C20000026E00000270000002720000027400099 +:105C300000276000002780000027A0000027C00088 +:105C40000027E00000280000002820000028400075 +:105C500000286000002880000028A0000028C00064 +:105C60000028E00000290000002920000029400051 +:105C700000296000002980000029A0000029C00040 +:105C80000029E000002A0000002A2000002A40002D +:105C9000002A6000002A8000002AA000002AC0001C +:105CA000002AE000002B0000002B2000002B400009 +:105CB000002B6000002B8000002BA000002BC000F8 +:105CC000002BE000002C0000002C2000002C4000E5 +:105CD000002C6000002C8000002CA000002CC000D4 +:105CE000002CE000002D0000002D2000002D4000C1 +:105CF000002D6000002D8000002DA000002DC000B0 +:105D0000002DE000002E0000002E2000002E40009C +:105D1000002E6000002E8000002EA000002EC0008B +:105D2000002EE000002F0000002F2000002F400078 +:105D3000002F6000002F8000002FA000002FC00067 +:105D4000002FE00000300000003020000030400054 +:105D500000306000003080000030A0000030C00043 +:105D60000030E00000310000003120000031400030 +:105D700000316000003180000031A0000031C0001F +:105D80000031E0000032000000322000003240000C +:105D900000326000003280000032A0000032C000FB +:105DA0000032E000003300000033200000334000E8 +:105DB00000336000003380000033A0000033C000D7 +:105DC0000033E000003400000034200000344000C4 +:105DD00000346000003480000034A0000034C000B3 +:105DE0000034E000003500000035200000354000A0 +:105DF00000356000003580000035A0000035C0008F +:105E00000035E0000036000000362000003640007B +:105E100000366000003680000036A0000036C0006A +:105E20000036E00000370000003720000037400057 +:105E300000376000003780000037A0000037C00046 +:105E40000037E00000380000003820000038400033 +:105E500000386000003880000038A0000038C00022 +:105E60000038E0000039000000392000003940000F +:105E700000396000003980000039A0000039C000FE +:105E80000039E000003A0000003A2000003A4000EB +:105E9000003A6000003A8000003AA000003AC000DA +:105EA000003AE000003B0000003B2000003B4000C7 +:105EB000003B6000003B8000003BA000003BC000B6 +:105EC000003BE000003C0000003C2000003C4000A3 +:105ED000003C6000003C8000003CA000003CC00092 +:105EE000003CE000003D0000003D2000003D40007F +:105EF000003D6000003D8000003DA000003DC0006E +:105F0000003DE000003E0000003E2000003E40005A +:105F1000003E6000003E8000003EA000003EC00049 +:105F2000003EE000003F0000003F2000003F400036 +:105F3000003F6000003F8000003FA000003FC00025 +:105F4000003FE000003FE00100000000000001FF12 +:105F50000000020000007FF800007FF80000014010 +:105F600000003500000000010000FF0000000000FC +:105F70000000FF00000000000000FF000000000023 +:105F80000000FF00000000000000FF000000000013 +:105F90000000FF00000000000000FF000000000003 +:105FA0000000FF000000000000000000140AFF00D5 +:105FB00000000001000000000020100100000000AF +:105FC0000100900000000100000090020000900419 +:105FD00000009006000090080000900A0000900C5D +:105FE0000000900E0000901000009012000090142D +:105FF00000009016000090180000901A0000901CFD +:106000000000901E000090200000902200009024CC +:1060100000009026000090280000902A0000902C9C +:106020000000902E0000903000009032000090346C +:1060300000009036000090380000903A0000903C3C +:106040000000903E0000904000009042000090440C +:1060500000009046000090480000904A0000904CDC +:106060000000904E000090500000905200009054AC +:1060700000009056000090580000905A0000905C7C +:106080000000905E0000906000009062000090644C +:1060900000009066000090680000906A0000906C1C +:1060A0000000906E000090700000907200009074EC +:1060B00000009076000090780000907A0000907CBC +:1060C0000000907E0000908000009082000090848C +:1060D00000009086000090880000908A0000908C5C +:1060E0000000908E0000909000009092000090942C +:1060F00000009096000090980000909A0000909CFC +:106100000000909E000090A0000090A2000090A4CB +:10611000000090A6000090A8000090AA000090AC9B +:10612000000090AE000090B0000090B2000090B46B +:10613000000090B6000090B8000090BA000090BC3B +:10614000000090BE000090C0000090C2000090C40B +:10615000000090C6000090C8000090CA000090CCDB +:10616000000090CE000090D0000090D2000090D4AB +:10617000000090D6000090D8000090DA000090DC7B +:10618000000090DE000090E0000090E2000090E44B +:10619000000090E6000090E8000090EA000090EC1B +:1061A000000090EE000090F0000090F2000090F4EB +:1061B000000090F6000090F8000090FA000090FCBB +:1061C000000090FE00009100000091020000910488 +:1061D00000009106000091080000910A0000910C57 +:1061E0000000910E00009110000091120000911427 +:1061F00000009116000091180000911A0000911CF7 +:106200000000911E000091200000912200009124C6 +:1062100000009126000091280000912A0000912C96 +:106220000000912E00009130000091320000913466 +:1062300000009136000091380000913A0000913C36 +:106240000000913E00009140000091420000914406 +:1062500000009146000091480000914A0000914CD6 +:106260000000914E000091500000915200009154A6 +:1062700000009156000091580000915A0000915C76 +:106280000000915E00009160000091620000916446 +:1062900000009166000091680000916A0000916C16 +:1062A0000000916E000091700000917200009174E6 +:1062B00000009176000091780000917A0000917CB6 +:1062C0000000917E00009180000091820000918486 +:1062D00000009186000091880000918A0000918C56 +:1062E0000000918E00009190000091920000919426 +:1062F00000009196000091980000919A0000919CF6 +:106300000000919E000091A0000091A2000091A4C5 +:10631000000091A6000091A8000091AA000091AC95 +:10632000000091AE000091B0000091B2000091B465 +:10633000000091B6000091B8000091BA000091BC35 +:10634000000091BE000091C0000091C2000091C405 +:10635000000091C6000091C8000091CA000091CCD5 +:10636000000091CE000091D0000091D2000091D4A5 +:10637000000091D6000091D8000091DA000091DC75 +:10638000000091DE000091E0000091E2000091E445 +:10639000000091E6000091E8000091EA000091EC15 +:1063A000000091EE000091F0000091F2000091F4E5 +:1063B000000091F6000091F8000091FA000091FCB5 +:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A +:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:10644000FFFFFFFF0000000300BEBC2000000000B3 +:10645000000000050000000300BEBC20000000009A +:10646000000000050000000300BEBC20000000008A +:10647000000000050000000300BEBC20000000007A +:10648000000000050000000300BEBC20000000006A +:10649000000000050000000300BEBC20000000005A +:1064A000000000050000000300BEBC20000000004A +:1064B000000000050000000300BEBC20000000003A +:1064C0000000000500002000000040C000006180C6 +:1064D000000082400000A3000000C3C00000E48070 +:1064E0000001054000012600000146C00001678050 +:1064F000000188400001A9000001C9C00001EA8034 +:1065000000020B4000022C0000024CC000026D8013 +:1065100000028E400002AF000002CFC00002F080F7 +:10652000000011400000800000010380000187008E +:1065300000020A8000028E00000311800003950013 +:106540000004188000049C0000051F800005A300C3 +:10655000000626800006AA0000072D800007B10073 +:10656000000834800008B80000093B800009BF0023 +:10657000000A4280000AC600000B4980000BCD00D3 +:10658000000C5080000CD400000D578000005B0010 +:1065900000007FF800007FF8000000D50000150023 +:1065A0000000FF00000000000000FF0000000000ED +:1065B0000000FF00000000000000FF0000000000DD +:1065C0000000FF00000000000000FF0000000000CD +:1065D0000000FF00000000000000FF0000000000BD +:1065E000000019000000000000000000FFFFFFFF96 +:1065F0000000000003938700000000000393870061 +:1066000000007FF800007FF80000069200001500EF +:106610000000FF000FFFFFFF0000FF000FFFFFFF64 +:10662000000000FF0000FF000FFFFFFF0000FF0061 +:106630000FFFFFFF000000FF0000FF000FFFFFFF44 +:106640000000FF000FFFFFFF000000FF0000FF0041 +:106650000FFFFFFF0000FF000FFFFFFF000000FF24 +:106660000000FF000FFFFFFF0000FF000FFFFFFF14 +:10667000000000FF0000FF000FFFFFFF0000FF0011 +:106680000FFFFFFF000000FF0000FF000FFFFFFFF4 +:106690000000FF000FFFFFFF000000FF0000FF00F1 +:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4 +:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4 +:1066C000000000FF0000FF000FFFFFFF0000FF00C1 +:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4 +:1066E0000000FF000FFFFFFF000000FF0000FF00A1 +:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84 +:106700000000FF000FFFFFFF0000FF000FFFFFFF73 +:10671000000000FF0000FF000FFFFFFF0000FF0070 +:106720000FFFFFFF000000FF0000FF000FFFFFFF53 +:106730000000FF000FFFFFFF000000FF0000FF0050 +:106740000FFFFFFF0000FF000FFFFFFF000000FF33 +:106750000000FF000FFFFFFF0000FF000FFFFFFF23 +:10676000000000FF0000FF000FFFFFFF0000FF0020 +:106770000FFFFFFF000000FF0000FF000FFFFFFF03 +:106780000000FF000FFFFFFF000000FF0000FF0000 +:106790000FFFFFFF0000FF000FFFFFFF000000FFE3 +:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3 +:1067B000000000FF0000FF000FFFFFFF0000FF00D0 +:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3 +:1067D0000000FF000FFFFFFF000000FF0000FF00B0 +:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93 +:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83 +:10680000000000FF0000FF000FFFFFFF0000FF007F +:106810000FFFFFFF000000FF0000FF000FFFFFFF62 +:106820000000FF000FFFFFFF000000FF0000FF005F +:106830000FFFFFFF0000FF000FFFFFFF000000FF42 +:106840000000FF000FFFFFFF0000FF000FFFFFFF32 +:10685000000000FF0000FF000FFFFFFF0000FF002F +:106860000FFFFFFF000000FF0000FF000FFFFFFF12 +:106870000000FF000FFFFFFF000000FF0000FF000F +:106880000FFFFFFF0000FF000FFFFFFF000000FFF2 +:10689000000000FF000000FF000000FF000000FFFC +:1068A000000000FF000000FF000000FF000000FFEC +:1068B0000000FF00000000000000FF0000000000DA +:1068C0000000FF00000000000000FF0000000000CA +:1068D0000000FF00000000000000FF0000000000BA +:1068E0000000FF00000000000000FF0000000000AA +:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:106970000000100000002080000031000000418075 +:10698000000052000000628000007300000083805D +:10699000000094000000A4800000B5000000C58045 +:1069A0000000D6000000E6800000F700000107802C +:1069B0000001180000012880000139000001498011 +:1069C00000015A0000016A8000017B0000018B80F9 +:1069D00000019C000001AC800001BD000001CD80E1 +:1069E0000001DE000001EE800001FF0000000F80CA +:1069F00000007FF800007FF8000003400000150051 +:106A000010000000000028AD000100010022000677 +:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41 +:106A20000000FF00000000000000FF000000000068 +:106A30000000FF00000000000000FF000000000058 +:106A40000000FF00000000000000FF000000000048 +:106A50000000FF00000000000000FF000000000038 +:106A60000000000000000001CCCC0201CCCCCCCC5A +:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80 +:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70 +:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60 +:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F +:106AB000000E0000011600D6002625A0002625A005 +:106AC000002625A0002625A000720000012300F367 +:106AD000002625A0002625A0002625A0002625A00A +:106AE0000000FFFF000000000000FFFF00000000AA +:106AF0000000FFFF000000000000FFFF000000009A +:106B00000000FFFF000000000000FFFF0000000089 +:106B10000000FFFF000000000000FFFF0000000079 +:106B20000000FFFF000000000000FFFF0000000069 +:106B30000000FFFF000000000000FFFF0000000059 +:106B40000000FFFF000000000000FFFF0000000049 +:106B50000000FFFF000000000000FFFF0000000039 +:106B60000000FFFF000000000000FFFF0000000029 +:106B70000000FFFF000000000000FFFF0000000019 +:106B80000000FFFF000000000000FFFF0000000009 +:106B90000000FFFF000000000000FFFF00000000F9 +:106BA0000000FFFF000000000000FFFF00000000E9 +:106BB0000000FFFF000000000000FFFF00000000D9 +:106BC0000000FFFF000000000000FFFF00000000C9 +:106BD0000000FFFF000000000000FFFF00000000B9 +:106BE0000000FFFF000000000000FFFF00000000A9 +:106BF0000000FFFF000000000000FFFF0000000099 +:106C00000000FFFF000000000000FFFF0000000088 +:106C10000000FFFF000000000000FFFF0000000078 +:106C20000000FFFF000000000000FFFF0000000068 +:106C30000000FFFF000000000000FFFF0000000058 +:106C40000000FFFF000000000000FFFF0000000048 +:106C50000000FFFF000000000000FFFF0000000038 +:106C60000000FFFF000000000000FFFF0000000028 +:106C70000000FFFF000000000000FFFF0000000018 +:106C80000000FFFF000000000000FFFF0000000008 +:106C90000000FFFF000000000000FFFF00000000F8 +:106CA0000000FFFF000000000000FFFF00000000E8 +:106CB0000000FFFF000000000000FFFF00000000D8 +:106CC0000000FFFF000000000000FFFF00000000C8 +:106CD0000000FFFF000000000000FFFF00000000B8 +:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329 +:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66 +:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB +:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44 +:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316 +:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23 +:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC +:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC +:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA +:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD +:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2 +:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5 +:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304 +:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85 +:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7 +:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45 +:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328 +:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65 +:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389 +:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43 +:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315 +:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22 +:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB +:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB +:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9 +:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC +:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1 +:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4 +:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304 +:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84 +:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386 +:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44 +:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC +:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98 +:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB +:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76 +:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B +:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55 +:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B +:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33 +:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B +:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F +:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B +:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7 +:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B +:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7 +:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB +:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77 +:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5 +:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63 +:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387 +:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41 +:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313 +:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20 +:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9 +:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9 +:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7 +:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA +:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B +:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5 +:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD +:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5 +:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3 +:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42 +:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4 +:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62 +:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367 +:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40 +:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312 +:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F +:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396 +:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C +:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6 +:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9 +:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE +:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1 +:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320 +:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81 +:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9 +:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75 +:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9 +:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95 +:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8 +:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73 +:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398 +:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52 +:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378 +:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30 +:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358 +:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C +:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338 +:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4 +:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318 +:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4 +:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8 +:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74 +:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8 +:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94 +:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7 +:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72 +:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397 +:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51 +:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377 +:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F +:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357 +:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B +:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337 +:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3 +:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317 +:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3 +:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7 +:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73 +:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7 +:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93 +:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6 +:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71 +:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396 +:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50 +:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376 +:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E +:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356 +:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A +:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336 +:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2 +:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316 +:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2 +:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6 +:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72 +:1074E000000C0000000700C000028130000B815832 +:1074F0000002021000010230000F024000010330C0 +:10750000000C0000000800C000028140000B8168F0 +:10751000000202200001024000070250000202C0E7 +:10752000001000000008010000028180000B81A80B +:107530000002026000018280000E82980008038031 +:107540000010000000010100000281100009013854 +:10755000000201C8000101E8000E01F8000002D895 +:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B +:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B +:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B +:10759000CCCCCCCCCCCCCCCC040020000000000067 +:1075A0001F8B080000000000000BFB51CFC0F00350 +:1075B0008A37B231306CE344F0E98159181818F871 +:1075C00099C8D7BF0668C01620BE0CC47B5848D7E0 +:1075D0007F5E1AC15E20C9C0700488BBC51918EA55 +:1075E000A510E296320C0C3780FCC5503109A09EE4 +:1075F00069D2E4BB79140F1E9C648ACA773586D0A1 +:10760000374D2074329ABC1B545E500F42A79862CB +:107610003757488F38FB1354D0EC57C1AF3E5D034A +:10762000951F8EA6DE0FCA0700DCEC914ED8030032 +:1076300000000000000000001F8B08000000000098 +:10764000000BED7D0B7815D5B9E89AC79E3DFB99E7 +:1076500049086127049C8400C1F2D84280A0142705 +:107660001030B6D46E5E12BD081B1F95872411D34F +:10767000635A39CD401E2401243E4AE92DD50DC55B +:10768000367A6D1B6D6A698FF66C442D9EDBD303D1 +:10769000942AADE0096A2D58A0B1A71C68BFB6DCDA +:1076A000F5AF47F6CC64761E3EFAF57CB7F193C988 +:1076B0009A59CFFFBDFEFF5F2B0A2A443957217428 +:1076C000057EAE47C8101042D3534F744F86887260 +:1076D00010FABC8AC8CF255F7832CA40A84EA5CF21 +:1076E000FBFDE17DF06CAB4728391EBE8F4EA0300C +:1076F0004201848AE56C68E18F3E5100CF9A29B13E +:1077000049E439139E594844683894F3B57703B473 +:10771000EF2B12FEE764BC0CC693E82B24A3D268BF +:1077200092B47F00A119A979A09ACF6AB1506ADEFC +:10773000CEA7A42928C9EA5E817FA41519F160FAB1 +:10774000FA752785EFBE64A93F1685B2C9BC6424CB +:107750009379B1F60899C83A3F673F97EAD1775FC6 +:107760001ADB176EE9C6E5706BA957C9B3B95E435A +:10777000492F42B899D139113F83C8D837B16FBB6F +:10778000722430F8B1F9C0383AAE8FFF4718EE8D49 +:10779000D92811001CA2B80D6E8DC1C5AAE1D21F57 +:1077A0007FA26C0CB76236E7C2BEEBF5C1BC301CE1 +:1077B0007C302F17782E87794DEF3B2F5F91735ECA +:1077C0006B90153E439D977F024247001FB2811088 +:1077D000C1CB7DB6FE44CD30BB5DFA438C2E649D9B +:1077E000AD6F90780A148BA9F1010EBADF465FDE07 +:1077F00048969DDE9C740DF020F86A67F0894994E4 +:107800001FCC141EF13350AA0BA890148F00DE2257 +:107810000CEE913B9BEF15315F8551A2651CE6870D +:1078200048F7EA85C067E193379E459331FCA25340 +:10783000D579784D5A89FED002FC0C4CD404A0D7DF +:1078400036E0B36BA1BF5BCC325C6E80CEF270D100 +:10785000BCC93009DC0C1BDC30E47419973DF06BBB +:10786000A10BFC502F1E842BDEBEEDD3C1CF832C89 +:10787000F823FCBCD1469769F11EA7ED4CFC1FE034 +:107880002BCBD18F566EE7F330B294F1F7A7E01708 +:1078900002EF7BFF26E365A27DAA5E82D75B2C6A9E +:1078A00009A88FF44C1997031532023996998D0E59 +:1078B000628C0C889746842A80FF11EA448B26A5A7 +:1078C000E6F7AF8CBF723FF7E8EA66CC4F174B8301 +:1078D00051E0AF8886D0B0ACBEEBD9CEE44B6F3967 +:1078E000FA2C8A4F84F1122D85785E66548C3E0105 +:1078F000F3297E518B5BF8E574AF7C71D207D2E53A +:10790000194C1E60F848C5A2E19BFCE1E943FA80EE +:10791000F4118C2B36BE1C2ABE2E0C913E3EEC7808 +:107920001CAF7DF96A33C36BA30AF2AC455FDCAFD1 +:10793000BEEA8BD77D08EA078A91917069F75F5696 +:107940007DE17C5AE4BB538E4A236654EEED0F6F03 +:10795000D97678F07E7D7592FECE305C9435225FCC +:1079600015A6075A230F9B08D3DD45903D181E52DC +:10797000FB354928A32244E810FF24055CF6458C1A +:10798000441BA18304C10B9F9F57176DF095B3ED66 +:107990007218559A8275FEBE3A85CC4381F1B2C108 +:1079A0002EC01D6250C84194F485A1069D3FA8A435 +:1079B0002B63A06CB7335AF4A9C80D0F32C3AB20A8 +:1079C000707A7D6070F2C539DE52FB7C07DD2E28AF +:1079D000EBEFF2362E723AD54E46EF72FC6020CEB7 +:1079E000E1761DC3D3560F3A204CC1F220FF66B09A +:1079F00014D056F8340BDB21F0CCC5E5FCA9442E9D +:107A0000A00E4186799221311E11D677502F20E8A1 +:107A1000A41F51AD2172450A1AE4C9BFA79F171DC3 +:107A2000BFB7ACC6AB003F6B228ADE86E7B85E32DA +:107A3000F4CD4017D3B07CD2E1FDB872D0731E8173 +:107A4000CEEB4B422E59879CD59243ECB234F6DDF7 +:107A50001A19F3E454F8BE7D5C7FFC84129E9E6E7E +:107A60000B3C9DF6E0DD02B6073F817F99896602F7 +:107A70001C7F1F5D9C91EC075FEFD51FD6E4B129F9 +:107A80007BD0F97DBD846ADCE440B3A052BE544D86 +:107A900005EC03BEEEF5982FBC59C0E75BE87AB35E +:107AA000B3097CD777BCAAC916FE5B8FD58C776AE1 +:107AB000DFF57078F37E7ADB270EDBDA3BDBF5F659 +:107AC000C7E505B68781CE391D0484F83601BFF7B6 +:107AD00046179B7930FED36514FF69E6DF8BAF0F45 +:107AE000387FDE6E20BAFAFDFE8666D04FEF2AEDB3 +:107AF000375D8BE9E837CF48D12DF8EB9A3DE3CBE2 +:107B0000C16E7A97D137C7D3D9FD0D396EF4910E76 +:107B10004FAF0A3E320EA7AF35E28A7EE96120FA06 +:107B2000FA9E93BE3A977C2CF475C4495F0C1EE70D +:107B30003AE9FAD1EE61142F0C5F4EFCA4C5CB07D5 +:107B40006DD7979E7E2160BEF6762E71A727365F91 +:107B50008EAF0F3BDF81E82847370C0D8F3F02DBEC +:107B60003102E88F12144DEA60D745A9DE8A52BD72 +:107B7000C5E5126F7F41A0769A8C8E93F6124A9AD1 +:107B80001AB1B7ED76C67C09BFC4FD3416A384973D +:107B9000EC8B0C95E8A9621951FD67047371FD0C1B +:107BA000C47EA4D951587706B3FFD16CA67F056C6B +:107BB0006FE1F5054BECF687DF619F48B05F08BBCE +:107BC000D85B43DC1FFB44B63F0EA020D1477C7F2F +:107BD0009C863F7BF7C50CAEC315648878DDCA610F +:107BE0004F628B00DA0D11FD8C4E0A09EA2F40C559 +:107BF00060376F14F2A2A00FF03EAF27037F7FF72C +:107C00009B12D10F75919A554DB0EC9BEBC677E363 +:107C1000711FAE47D38A3CA9F11E96DB5580776B66 +:107C2000D146CDBAAEAF09F102D1A2777C11655A27 +:107C3000D134184E7EAB1BC343C48004FEF3071F30 +:107C40008DBCAC03FCE8FB5E3859CB52DF7236D8F2 +:107C50003C79A498043BAE3584A89D8F460A65986C +:107C60000E5A3DFCFBEB65B0DF6DF5D1F29E2DB3F6 +:107C7000369B501ECEEA9B95F47B2E2DDF273E517E +:107C800006DF139978CD5380AC13953117FEBE4FA4 +:107C9000A47E95067346EC2E323D6A7F5DC5F7D90A +:107CA0004B6E8ABE0CBF14E923C07F220563C4BE9D +:107CB0009198BD266B26D5E36AF4F0780CEF51C796 +:107CC000256462388C6A3F5AE6057A0F723B2D8A2A +:107CD00096E2F675CC1FA022BA3F06BFCE1542C76A +:107CE000FA08D8B720B0CF2CFB7689D963BD78725B +:107CF000E0ED11B986E06D6B7EEDE1023CBEB9505E +:107D00008C02D96CCD2FCC5C6DC1E3B7D4B9952270 +:107D1000D8318DD9C42EE1FB64601828E792290080 +:107D2000683BCBC078CCC7920F613A1D1DEB29038D +:107D300014E895DA8B648F8BCAB577895D2509576E +:107D40003E31783B0AD62D02BD62FA7DC2B2DE61B9 +:107D5000028AB9C9DD157216C1CBB00ABCDE7EFC41 +:107D6000049FC7FA84DA677135164A3F4EBA797EA6 +:107D700008786E01BE188912044E03C1351D3C9B64 +:107D800023CF661279FD11C3355D7B273C870994AB +:107D90005F56C8A5845F06EBDF6981FD14DEAF3650 +:107DA000811F0E3F1B981FCED9DE27B7A3A80B7EDD +:107DB0007DBADD3FA458E91EFF5F2BEA541F049DE6 +:107DC0007E228A67A75E58C0F4425304EB052A0F4F +:107DD00017821E0830F8374511F9AE8450C2C4DF4F +:107DE00003A00FB09D852652F9AFE2FF80DF465415 +:107DF000DAF58132487DF08E107B99F0174621CC60 +:107E00006FB7D07EE338A09F5C6A8F476E6F89584A +:107E1000FD05B522D5775C9F3D56D43B6F023F2FC1 +:107E20009BC36358A4023D26F2176710BFDD9D0176 +:107E30009B7C8A7C6931D9FF5AE899EC73DB997F86 +:107E4000341DFE342511779387BA249279858D9E4F +:107E500024F8FC0821E7309721236B0A7F64DB8735 +:107E600085A7F61C1E83D7FBF83522B11BE5D97216 +:107E7000D283E12B97BE5229E0E7E3B03680C72CCE +:107E800044E834A82F382B813E96BBD122DC5FB06A +:107E9000C2B92FB69425E8A76725D1DF563F753FB5 +:107EA000FBB8C13E1B30BCDEB2F03F42B10AD0B3DA +:107EB0003296E36D88B84BF3605CD9D072805E6413 +:107EC000231A24CFEEB20A5A8EB5C177DFECE8D17F +:107ED00072E0434D26F23EA152BCF17EE74805B662 +:107EE000FD5BA6E6F08FCA6625D0814F5710D0A75C +:107EF0002FAE180917FCD48A329377763AE1F4D181 +:107F00008F9CFB5074714AE47E6A3BDE6DF451989D +:107F1000C22B6F17ECE3A7B2E3D559FEA8F1E99B9A +:107F20004DF189303E99BFA40DE01C344504761113 +:107F3000AF17900A6DF8095EC61B2B6CE7EC2E4359 +:107F4000956EFA292029A43EE6FB7289DAE502D86B +:107F5000DBF3A53D06D079A208E306F7DFE2C126F0 +:107F6000112EB76C16395E89BCADDDD252B619D769 +:107F700069392988D214A09BE5049F3EE6F7B9E44D +:107F8000312B0A71BBB65122DAA783FEE9DFBFD5D8 +:107F9000506FF76F815F01ECEFFC1A6D2A80395D3D +:107FA000BB5D3562859BFFEB2E89FABF76D41C6BD7 +:107FB0002766E84BF67D876785011408FB8FBBA415 +:107FC000E9A976A112EAD74071BC1E5CDFC3D733A2 +:107FD0001CD3673FF18AFFCDF4092FE7B1788EB348 +:107FE000DE4F2446873A8597CAE8F05241FFF4CF26 +:107FF000E173B9456271901E1F227A7738F1DFE98B +:108000006C5D9279A40CFA9151F766D887EC12D185 +:108010001AEA578E117D1366E33D5EFA7B1FD4BBCF +:1080200041A6F27294D1D30A781EB54944E0C77EC6 +:108030004AD249D72356D41CF4E0F7AD9B5134887B +:108040005F8D867E71BB57C62A44EEABD954EEAB2A +:10805000B59804703D15EF6B745C6E3DD88A40AFE7 +:1080600087F1C6094C5EBD1489E0E7F6D4759B30F4 +:108070006EB8344AECD0436367907DD583D928EA43 +:10808000D5537281D3D1839B161B40072D781F06D1 +:10809000E596A22D2AF8B12F16CBA48CFE8CE1C355 +:1080A000FD85F81FDDA474D35A40E72B4FEC462220 +:1080B000E15B95E053D6E8FA5B43DF34617EE65A34 +:1080C00044EC23B06F497C468EAA20CFF377CF26AD +:1080D000FC236BED02D0C346147FCA4A27523049B5 +:1080E000E6DFFA1789D9EF2F6D06FB7D247485CB67 +:1080F000AF4AE7370FC51EE171416E8FB4C99D8449 +:108100000F4DCC63A06FB87DE22BEA24F4F9DF8C2D +:10811000BE07DBBFAFD8EE4775DA2B4E3BA556D472 +:108120006C76A9735D973CC91B617E6DB998BF0BD6 +:10813000FA8E775CA2FB923D91C5FF51A0A7FAE1B0 +:10814000DFB97DC4CBF9971502EFC1D7C7F20DF6A1 +:108150005E06E5A3D19C4FBFD03F9F723EBA84918B +:108160007E04F0239B2AE123A398F011E70FA9DBFB +:108170006C1983E94CAF13C1238DC04CCFC2E5AB62 +:10818000307D2785149D8E62E3CA1313EDE35DE80D +:10819000ECB15AD120FEEF28EE067F0F9B4788995D +:1081A000E92F4E70BABA0874C5E92C7FF702B2AE57 +:1081B0005781A0A7835E7597233F62760ED2F61B88 +:1081C000563FAD0F35BAC7CF6B1FEF377EAE167D6A +:1081D000B8F87948B6FBB3066A3FD4B8B9747918D1 +:1081E000A18FDE32DB873AEBC565265F4FEEB3C168 +:1081F000A50F3CA4EDD1783F74A27E487F3FD159B2 +:10820000838083138E3364E667F998E0E88C6BBF54 +:10821000CCE4FC40F2C06F1849710CF8C510F5DBD6 +:108220000411F3DBD8E9FDF14D94DEFD21712F88B7 +:10823000A870ED11D36B990FA6F725F2F014BDE7E6 +:10824000152793801FA7FE49A7770692B72B55E302 +:1082500036D925CF84EFB3537904988B5DF208D2D9 +:10826000E2B5E6A3C923182CBC7BFD962C2FE0F6C3 +:108270005246B7D8707803C365ED610FB1EFB1FE18 +:1082800093ACF1B2B56C7F773BDB1FDE896261F89E +:10829000781E8915C02FE7D1B1F0340BDDEF9415AE +:1082A000CA2F2D9EB7C06FCAE3E077B5D3329FCFF8 +:1082B000DDBBEDE5CFA1C539E0AFFBDCA31EF020AF +:1082C000A0B50EBF593D10049EFFDDA8A619F0D63B +:1082D000E4A176E8ED1A92216EBDE1075F9FB11A25 +:1082E000EC13667FBC87E5B26EB19FD605130AE03A +:1082F000F7EDAE69375F87A07DA2390FE2D7998885 +:10830000EC479D70BEA3C53EBF81E6EF9C2F425B4C +:10831000FA9D87DC21B8C659F7CBF6386BBA7C29B1 +:108320009E27F5924CF16FCE45C47E32DF0C241AA5 +:10833000883EA1795203B57F15DA4FFFE0ED7F3615 +:10834000C0F81BD49E05C4CECA3663E0EFE1F1BE8F +:108350002A54638CC4BFCACF2F3281E77AEB45061B +:1083600059AFA8FF7AE9E67D56534D714A6AFE5F20 +:1083700013E2276597F5DF2FC5ABA07F2FE0418281 +:10838000A74CF04DFCBB18BFD572B045C8803CA6C9 +:108390002EB2CFF3E9B28D1EAAE117906BC554AE91 +:1083A000058AEDDF9D7EDFDFF5E23D49F88F84969B +:1083B00075B01F824909FC32A5F2B9DEFA78BC2AF1 +:1083C0005817EC93508CC88D5A8DD6AF42FACED93F +:1083D0002584FFC8BEBBB6750C8997D70ED7A3E01E +:1083E000879551D4207D38E8AEFAB28012167D58B8 +:1083F0002DF728C067D5D82EB2BEDF18916CFE5776 +:10840000E7D383543D584CFDB9C43FA4E1B265DDC8 +:10841000BF6F17585E8A9EB1B41FBFDCC608F5F364 +:10842000DEDE3A3683FA03EDF2F702DB1FFDE4E904 +:108430006F28E0BF3FFFD4E99B00DEEBFF45422AF7 +:10844000E4653C1D4249628F2514B0C7D67549AE1C +:10845000FE0392390371CDEF8608BED63DEB4D2C5D +:10846000C4EDD73DF7F66484E777614BCF2B23C18A +:108470006E7E4AA07E6BB37BF212FC7E9D8C56B959 +:10848000F9058A3DD44E3DF7C34025F0B7D0717051 +:1084900025E9B773B9C76BD95F5FE5F1F07AD42EE0 +:1084A0007F52488C15DCE647F33ACE3D29D0F91DC2 +:1084B000F0247C30BF8EBD4A1CCFA3BAE37D224F8F +:1084C000E67DF7DB618043F501C9A607AA3BA4A4BA +:1084D0007732799E8627C483841940278C5EBA360A +:1084E00090385055E7B6F7C14F517DC02ED7305C5C +:1084F000A24980EBEB52742194BFF7ADB08E41F5E9 +:10850000DE9127C20057DCEF6A2503F48D9DBEA1E2 +:10851000FFCB597DFB43A887C4E1AA3B5BE9785DAB +:108520009FF90DE8956A87FC7C0F7EC9ED6BCFC47F +:108530003C0EBBB0637071B8F5DFBEF89889C73DDB +:10854000F7EC6F1F33F1FCEFF9EB7F3DF600F0E73E +:108550008F7D1AC8FFEAA77E1146167A5CE7A1FC58 +:10856000786114327371BD0BBFF4264CFCEAC20B68 +:10857000BF19ADE3755F78E68F393AAE5FFBC2FC99 +:10858000110087DAEFCF1BD1DF7E1BE835E1B5CED6 +:108590002B41F0AA1F10A811F43C7B3AF073A8EB12 +:1085A000D06898E7F913DE28D83DD5F85DDD54C0D2 +:1085B000D706A28FA1BC09C3B9EAE9ADEF839CE855 +:1085C0000B6F73A4489CF0C991E08CAFEA7A7B01F1 +:1085D000C11BEA217AD459BFFA38C6E794F4F8BB34 +:1085E00088FEAC80BCAB7EBA958ED789F117EE8B36 +:1085F000BFF3F0CBACBEF86B71E0EF22BAE7F15CF1 +:108600004868EB1A668B7FF2672AEE17CB88F52352 +:108610002FB83C1808BE6B043AAF651E63B707F865 +:10862000EAD9402F7E17027EBF7D7134C2F471C635 +:10863000D3B312E466CF0B5E6D1F7EBFEE85D70904 +:108640009F5DF8FE51452779972828E4B0FC2FFA62 +:108650007304E47015DDCBA1EAFDA1A4379CC253DD +:10866000556251851E26EF4F93F7094AFF558983BE +:108670004B0517BC1DF314523B2A319CC065C3FE49 +:1086800037146A5FA6F02994023E4F2F80F7E9F075 +:10869000C9D7AFC1FA675AF0BA9FF2ADB37E15E6FB +:1086A0004FD07B7DF09B105E87E785BD5E19F4DEC1 +:1086B00005B0BF827DF19E823FB57F86BA5FF9A982 +:1086C00093BF795C98C1213D7D98CC0EE87F7D43B6 +:1086D00085DF8F3CBA8D8E381CCFFDD95DFE9F6142 +:1086E00072A30A99157916FB44F560FB04F2C65093 +:1086F000CC1C59909AEF39D84760FA3BF79444E282 +:1087000030CD9D87881C77CA8BAA34FEBF3FF2F11B +:108710000E1C9C0C72EDDC8B3F24F459F5F46905BA +:10872000FC63AF747C4FE99E98E207D00F098B7E03 +:1087300038F79D8393A93C70DFFF2A0AEDBFFA79D1 +:108740007BFFD54FBF6FEB7FBDD9A9D0FC84FEC79F +:10875000794F3696C37ADF3BE241204FDFEB945CE2 +:10876000FDADBF05FD68C9336B3EBAE00D88DF97EC +:108770001CF3EBA047BBB618237680BD76CC8340B4 +:108780007E23D9F82DC497BB8EFA75C87BE83A765C +:10879000B3A45BFC133F70C073E671735E08F737D8 +:1087A000B33B56025B28A7DC283D2942CCA277FECA +:1087B000B5472B4680DC6F047B7E3C8C178D90F890 +:1087C00077784105CD0B14359FABFEA6FD79589CFB +:1087D000DCA38948B7D223DF6F31BF4F73D0DDFFF1 +:1087E0005CA670FB108F6B9183D856AD74C35B8908 +:1087F00042F741E9BE970EF07DB6C2F200D27CEF9F +:10880000E56F861F2524C6DCE63D99F5E3F4ABA6AB +:1088100093071ED6CF144567FDD3F502BC1759F256 +:10882000DD47A2C466F07FA160D019678EA9D63853 +:1088300073E591831057CE5EF27C2EC03F8C1AB543 +:1088400077891D8FA257FAB1639D716567BE61BAC2 +:1088500038B31AAC3A91447DFBEB1B5737485CBDEB +:1088600031BF5CB5C6D51BB53E71F50D0A1EB729E3 +:108870000D1E3EABCCBD17BE63B333EEF6BD49A1B2 +:10888000FEABEB51F7F756C33CA3342E3FDB01AFF1 +:108890004F3278FD780C5E38563D6548973D18BEDE +:1088A000F3961A8D2002E7AFE8597F10F88CC7E5E0 +:1088B000CDF1E295C0E0E137D47C8795EAE20795F7 +:1088C00041E43B202DCB552FA4E66132BE89907D3B +:1088D000128FBF1C3A75B70A724B46F18A024B3CA5 +:1088E0008CE4D1E3FE72923E64E0F92A9A4EECEDFC +:1088F0009CE4DAAFDE05F1722D9FC41FA4CBD71123 +:10890000FFA1B35F291235499E57502F932CE334B2 +:1089100067D3788CACC55CF381572AF1A761BDD2CF +:10892000E539A45F51A5F10C141C5C1EEC5796842C +:10893000097C550C5F908F0464B02E960FF5D09291 +:1089400030D133BEC39EBDF0DD17A4F951F78BFEC5 +:1089500028E44F39F3A3CADEA4F196E6D30289A333 +:1089600070FA6D2EA8B90AE4783FF9512F2B16BF83 +:108970007ABAFC285FF04E921FE5FBC0F951917264 +:10898000B0C79A337919AB133C8F6696EFF42BE599 +:10899000F03CD04FCD2C3F0A99AFCE23F57919D5B5 +:1089A0001C32E03BCBA7CAD9DADC00F5B347A29A68 +:1089B0004EE2CF33D0328B9CF579699CF9CB8AF1AA +:1089C0009F8A45EE71FCFB7AE96AAB0AFA1B3F49C4 +:1089D000BCB219D315D8ED39C95664D547FCC9E9DD +:1089E000A8B9A8FF789D7CF91AE2C7E765554B182E +:1089F000864B7D43A57A82D32FC4D3402FA97AFC1E +:108A0000AB77013D6707A3014A97244ED61224EEA7 +:108A1000A93EEB6829BA9DC4BD2E6AD4DBCDE9B866 +:108A2000EFFCE7B0F9179A405F1783288A5CE45F90 +:108A30006A1D25641D2B1543F55AE0987D957BBE74 +:108A4000E9762F5D4F536C45EC2E98C91A7BDC9567 +:108A5000E75FF0FA01213E1CFAF564D3B8ABA852E7 +:108A60007E4BE10BAB0A8B7FB301AD308104E41583 +:108A70009DE4C8A2AC2548FD31BEF868AF2D3ED7B5 +:108A80004DE3B88E78E27CE91ECADF03E06F07DBB6 +:108A90009F6C83B8DB7888CF45D8B93D9DC5E90C7C +:108AA0009A2F94869E5A8AFA8F43B5D74749FB9DE1 +:108AB000F5A5340F4940CCAFFDF506A013704B501F +:108AC000BADFDF007C1092385F3C45CA0F0AB41C45 +:108AD000DFDA45F8E6D0A9D72BEFC0F4D16CF8095E +:108AE000FF0FB43E2D3183E075A8E3F45D2F1DB771 +:108AF000C50892FDEE40EBD69274DCC18EC3E3E371 +:108B0000A9F5A9649C667D8071DAE93803CF9FF2EC +:108B1000C98E836B2B20AEAC62FEF7E1F7EAEC1E48 +:108B2000E4161FCA60FC73E89497C8EB966C9AC76A +:108B3000EB290E1AD40968EFDF3331672E39C7509D +:108B40007235C98BDF71B095C81905C6C1553CD1C6 +:108B5000E06ADA2E6EC0F9D970398A825FDF539CE1 +:108B60007307BCAF43EDB1B9A0874BE9B92D4F7185 +:108B7000F15DD04F26F0259EC73495E67D788AAF0B +:108B8000BD1BEA1F9CFE5ABC01E0544AE9001DCE01 +:108B9000B5C1B1592FE4E771FAE57B4FA93D6E816C +:108BA00054BF2D6F09C94B49BC1CCB856D5E8BFF33 +:108BB0001BEBC59D50F6A01213ECBD5DB7DC1CB5D8 +:108BC000F2F39795D8C3548EF03C2CCEE7EEF970B3 +:108BD000CDD93CAF2CAE4A2570FEA8374F7A61AE96 +:108BE00035AF8BE54907799E7494C6E1DAF17F6E63 +:108BF0007971CEF3891F559EF477BC6C3F1C40A35E +:108C0000204FFA471E144DE279B7FD428A421E8C6E +:108C1000933E9CFD39F3FB7BED9134FCFC6B008EA5 +:108C200045EEE5C61D78BBD347E2737CBC97403E5A +:108C30004D1C984F47AEB1F733AAC67EEEEAAA3A6A +:108C40007BBCAAC0CCB3D51FD35268FB3EB6FD6A2D +:108C5000DBF7F1BBA7DACA1312D7DAEA7FA263AE59 +:108C6000AD3CA9F353B6FA530E2CB695AF49DE6A64 +:108C7000AB3FEDF0EDB6EFD38FACB37D9F7962A340 +:108C8000AD3CABFB8BB6FA75D83C51483E1C8D37DA +:108C9000A1ED23452B7DB66662BD9281E1988909DD +:108CA0008626EB937833CD314EE51938DB49458A7A +:108CB000A161FE95F471E51AC91FBC93F09154941B +:108CC000335727EF672C00BF132AA1E7AF7CAC3FD7 +:108CD0004F114AC2B94B39E8C0AF232EED91B6937C +:108CE00078AA72F286C342B82F5E3D11679EE2E019 +:108CF000E2DAB2EE683744BEC854595C7B14E60B26 +:108D0000E247FCB344CE3D9787887D60D9DF1038B9 +:108D1000F2FDCD1C1535024C395F94ADE81949F2CE +:108D2000D97BF7355E7128F9C67DF58A97D85D5CE9 +:108D3000CE0CA457A4C4345B1E82F389E5DF14155E +:108D4000F6E1E15B893CEADD17F4CAC7D854F8EED6 +:108D500091A3443EF6CABF8E3C9B5C18AC7DE69462 +:108D6000D36D20F4C9791F77791D863C302C971E6E +:108D70005C72138983A15A643BE79753195341EFFF +:108D800061BBAC42B5EC9FC3A5D43EFB7BB353BDE6 +:108D90006CBDBD74CAEC550ED76105353112D70BC9 +:108DA0008908F6550DB3A311F003B64015CB3E6DFF +:108DB000973A86C8D1C6A02282BFB4F1F07C121FB8 +:108DC000F0FA622AE4D135786215B0AE864C517360 +:108DD000CB77DAA252FF8C521798B6BF1FFA501405 +:108DE000BCEF7759EF3E95FA5D1AB5C58741CF655F +:108DF00085141D526E9B0FCE5A04E3CA0B650DF607 +:108E0000B5086FE2DEB6C41521DF1711F88B442FC9 +:108E10002A756132FE40F3BD47A57E066F9DAFDF28 +:108E2000F97A15773F45BAF96E85F9660F3C5F6FA1 +:108E300036CD5FF5D605C9F8FF0C1759B8C0DF83EA +:108E40008C96725CAFE9F40DED458462689EDE237A +:108E50000BA7123AC582DA46BF7C1F81E937A10E03 +:108E60004FEDDFF939D5BB559A97C0F18A74EA8F77 +:108E7000181697C9BE372B4EF7BF29F941E928CB01 +:108E80001345E45C57BE4CE292E0A6B1FA31FECA4B +:108E9000F671DE4F4609BE5A3F23A32D406F457839 +:108EA0003D70DEF6308D3BB57AA295B1606A3CDE4E +:108EB000FE4D860F192DCD20F95BD2C2889BFDD9BE +:108EC0004BE70C6E4E39FB632E6773512E95B3132F +:108ED00097C311A174FD38ED0D7EBE67E8E74EDA49 +:108EE000093C5BF31F257634F78FA148C900FE1EAD +:108EF0001A2F4DE179B99EC478946F9C4A9C7EAD3F +:108F0000450CCF358EFC5D86678E5FEEB747916C62 +:108F1000C2D71CDF12C0137025CD8EF4A7AF24C6B4 +:108F2000374E789EF91F0ACF9FC31AF0336B145E39 +:108F30003FF0CDA11B11898339F891B7E374EF5C41 +:108F4000BFEAFB9FBD7E4E0FE9EB9BAEFB0F1ED72A +:108F50000D317A5399DE7CB9F4AD1638272267D3E8 +:108F6000FD6EA8B491DCD322235303FF5A889FCB14 +:108F700061E732793E957FA27DFFC1F30B4919F37A +:108F8000BB87ED3FFADC9BC2EC2C7E4EDF397F279E +:108F9000BEE6F8DCF30751BEBBDFD5198FE3F10D58 +:108FA0009E07CBE300040E78FD9E59628CC8BF1269 +:108FB00064EC75914FCB7C542F74BDE8237912A1DA +:108FC0004A85F863F34A926550CEAB4151D013D72E +:108FD0009E3982E2B8D3B17E2AF7F34A1202F83DF5 +:108FE000F2CED1BCD85D2C5E99579B10565BC679EA +:108FF000C047E5ECA553F713F9F8E2289A877E5F9E +:1090000019B5DF8E446E6F2F83714B693E7908EF7F +:1090100017216F2C74C24BF26F514937023F2AD689 +:109020000266087F3F538FA6DE3916F2BE54F23C2B +:1090300057AF91E7A151CAC1EB71BD8D057E1DFAF5 +:109040006D2AF4D373BB2195ECF7FF3BF373C4AFE8 +:109050007AA13E42EAB77CC9207645E3C1B3C46F2A +:109060001830A645A91FD5905029CCE788017E0E5F +:109070002447F5C5F0FDD02F493D4989FFD204FBB7 +:10908000E45685ECEF010E104F68F0D17CB9ADBE0F +:109090009A48263C0BD0AA452EF0BED5C7E34CAA71 +:1090A000A4E4A4F29094D2A49401FEE412D439165C +:1090B000E46553A20CF4345AABE9304EBE9A28034F +:1090C000FF71FE1A2D0A3E74A594DE23C2F1E1F170 +:1090D000A1D83341A89714EEC5E316FAA9DECC3B1C +:1090E0009120F70C5D3A35D3D5FEBFFF6419F9BE68 +:1090F000BDBEE258B9859F8369E2950F14CD7DD43A +:1091000087FBFD196C7486A7EF973F07DBEFCF7CD9 +:10911000549F1E3A357E04D8977569F2A8250DE351 +:109120006918954FE08FD838561F9119B4F643E16E +:1091300021BDF8438AD789943E1BBE3F3E03FA7D8A +:10914000E9D4720DFC7DBFCF2E22FB86F3CF790DC3 +:10915000B05FCE67A13524DFF2B999AFC0FEF0B79A +:10916000F587B3648B5C3CFF9DA3333CB8BFF3CF62 +:109170001E9D2113E64AD8F6F11BAEFC7C06D809E9 +:10918000E65C545C839FD59A82A0DF6A95AE83E744 +:10919000C9EDCA519AE1393F9049DAE78C101F8432 +:1091A000B2A4FE7CF43BD3C8BA695C81C571F0FA05 +:1091B0001A8284AE35BC018178A1E91D0DF1AC5352 +:1091C0005E427F970A5071C114F00B4AA45DCF5ADA +:1091D00094807C0A255903EC897C3F4D20E09BC09C +:1091E00071ED20A13576CF5BABAF90D121CD23DCE3 +:1091F0007CEAFEF1001F2ED7E57988C4337A6E51E0 +:1092000013608F3E2CEB5F590176E06D3299072E8B +:10921000FB34173C2E0F14DAE092C5E2131CAFE9C1 +:10922000E8645B3D8A166178FFB85E8DC2F8CFD7DF +:109230006BA4FCA3FA08291FA8D7C9F3B9FA62F2F4 +:10924000ECAA8F92EF1DF5A5E4C9F3FAC8D65E2209 +:10925000F674AC0CF4D032EA87D374D1807C850CE0 +:1092600019A9C3B0A9A29DFC4925ECB741AE64641D +:1092700011BE17A07D36CBF31B9E3BB7B54C4FC933 +:10928000572E4F1B3C48007964CEA27E8610F4878F +:10929000DB672F45E82D8B5CBF82FF79AB98AD0F64 +:1092A000CF27C3B07F77D60FCB7801597DDB61B96B +:1092B00048CAA97EDDE137D427F8CBDFB2D0F7AEBC +:1092C000E978D5988E7609548E3DC8BEEF983E2336 +:1092D000E37628CF9A9141F27F67215DC370DCA9C4 +:1092E0008BA62723557F4FFDE19CF2B14C07819C53 +:1092F000AAD5F6B659F631F9265A15B3D0CBCE1AFF +:10930000B9621FB133E2B98B27917C63E6D7DE5790 +:109310006ECC26FD927241DBA17293E915903373F6 +:109320002E533DD4AB7FFE4CDF73BDA730FC6F9F47 +:10933000BD450A039F803C057959124773F13C8370 +:109340009FA4F1EF59EF2411E4F72951FC1EEC51D1 +:1093500085E69BE4451202949FF4C5A6FA613F920C +:10936000B53BB90FE3FB0F5D5E1DE28D5D2FFE91F6 +:10937000E46748931515F83BEFF9D3246F4912BB06 +:1093800015D8F12E6BBB7ABE0CF62C4C84DC2B80EE +:109390001535C6B394C3D667763695031CC5F85900 +:1093A0006BFD5DFEF8BD74C78C0C3582F9C1C7DA60 +:1093B0009BE39B8C7C5CF6D0F2B2B6714DE66C28D8 +:1093C000E3FA99B4DC88ED846D999D111197839B24 +:1093D0008B9A0E8F8232AF5FD464E2F631A60F50C3 +:1093E000305E00FCDE5BD670396429CBB48C54FA55 +:1093F000E4EBDD70E88FAF8CC470A87A5EE82421BE +:10940000BEE7F70AB0EEBC037BE9B9800422FBFE9D +:10941000BC849080A39B1DF587B546EE5CE378C1C4 +:10942000A2614284DE1BA4243C51D85E4E60F782C8 +:1094300070BA782640F5C084046E6F8D4B3BEE0900 +:1094400099C0EEA1212403F2723B3DE7EBA4F3F1B6 +:10945000ACBF3A64B649A0B79FF668243ECEFCEC98 +:10946000E7B8DDC4FC39F730079E678BE9BF1AE423 +:10947000DF6A99F881D7172436631B0AADFF614173 +:10948000145BACA8C947E9657D6667CE544C2F4D87 +:1094900099F67203CB9F8F649A995913217FE8A1A3 +:1094A000D190DF5385DA577E11E6FB531A0F3F7BCD +:1094B0007056C675B8BCE1A7348EB1A1EBA802F412 +:1094C000BDC3CFF28EBAAEF914ACAF6ABB48CEC5FD +:1094D000015F1AE3F1748DF6AB654C2FFF1A383932 +:1094E000DF87F1FD64A1A189D720F4C6B6779BD4AC +:1094F0004FE2B2A24D00FA7863DBF926A0AFF5B3D4 +:10950000F87D76E75F368A58FE2306DE8EB6D94DA3 +:10951000700E63FFAD159F02732B47A4FC8B09925D +:10952000C4B5A5CC46727EEF774D22B19FC145BA36 +:1095300009C3BD48468765FCDCA5607C029F35CB2E +:10954000441EE2F72D1E829776727F086AA1F751BA +:109550008C7DDEBB1AECECA21A632DB1B7B589C4C1 +:109560000F301AF5FE903C89AB1095BFE3355426B9 +:10957000E37A2501EA2F2FAABC793DB493424BFD33 +:10958000C0EF3952C224FD7F8DCAE15D62A253054E +:10959000B91C2E24F8DD15A674613E3C91D0C57E21 +:1095A00071EED560173509ABDB5E05BC66169273AC +:1095B000AEF07E23AC9FE1B3418BAA80BFFD0C9F30 +:1095C000D25ED1847C4DFE7E9B70FB5A80EB3BFECD +:1095D0008DF3550CD71CAFD1320CE3E16DFFC6A65D +:1095E000C82C828742157F7FBBEDDE2615E365FF21 +:1095F00066234FB394C7FF054B752207EE257CDD2C +:10960000187C741D2821FCFD65F07F3C99C5F99EEE +:109610007E2F2AEC952306D8A50D664AAEA8582FB2 +:109620001459EA9763B9F0CDC72482D7C3783C9028 +:1096300013781D26D07DCF0499D8057E3C173F2E88 +:10964000FB2715927C5BBC6EE407BB61924CF43C3B +:109650008FE32813446237437DA0077F6E21C99FA3 +:10966000C3F23A06E77CA4088DEB48D21E03F33020 +:109670000AB0FC7D415B44EE17F1155BF20A40FE37 +:109680003AF210244779ACB73B17CE2B659F5C2488 +:109690008CC67839ED6771996CBC8FC5EF7FEDA7EB +:1096A000E71BEF8F993740BE0CD2BB73693C2A365B +:1096B000159E236E2B1AD19FFFA5EF7E354AEC979E +:1096C00047F265D77CB0E702745FE41D5544EECBEA +:1096D000A84398FF812FF8FD2A4C7E7898BDE03C86 +:1096E00027C0E5892793AEB1B675DE88AC60EA1C69 +:1096F0009C143454900707B5A919608FEA01CAEF8A +:109700008DC9599F05BB4566F2608F8F9E8FEDC94D +:10971000449DFB10D8BF5164CD4BE0F2607BBD4A45 +:109720009E4FCC1947E2974FCCC9990BF18A43D78A +:10973000BE47F6BF17F750FEBD78E465B823095D54 +:1097400034E9F95C202BE2974F3E42EE01F9861C8A +:10975000DB49F2E5215F074F6967A63D0FF38900FA +:10976000F59BFE89C927ACB7C9777E3F877CF91383 +:10977000C40FBC95C95D355E4EF695E0C6D3812E0B +:10978000503BB96789C3C1792F877C793269FF273C +:109790003F853FCF5F72E629F1F9FC80CDA7EF7DD1 +:1097A000AE767C70BF06C7036F5F2B1823B47EE8CC +:1097B000A6FAB2841296BC90D4B90D85BCBF00E75E +:1097C0005D32E05E9578FB7505C007096227FA8275 +:1097D0008DB6FB595144EEB19E2F0938CEBB38F9F6 +:1097E00005EE05063DADE8FD9F6BF935DEE6F2BC02 +:1097F0005C92A72EA3AF825D7B3EF0E60CF0C755CE +:10980000633101AE72249BE43CE905B62F919FBF02 +:10981000979CE7E1F3E3FE385EAE3AB088F8E9AA38 +:10982000F707C9799EAA0495831B54F3B057B4E691 +:10983000DD1A49C8B7F51CA0FDE980038C8F3F688D +:109840006B7261FD81BA3133E19C498E5873D568E2 +:10985000808F4CF100FBE56783E49CAE0C7A9C8F13 +:10986000FB4BB60F5CC6EC9100324580A7E48F76C7 +:10987000237A66D190B17D24F5CABDAB9B801F765B +:1098800039ECAD5D7E5ADEBCEDEAA646AA9F895C46 +:109890005CD6F62FC41E6AF2F1F273444EEE52DA31 +:1098A000932027CDE7BC3AE83DDC9E9C63376F2DC3 +:1098B00026FA432A447900B77270B480FC7BCEBB91 +:1098C0000FFC0C4FFAE231BF65BF733E746234EC9B +:1098D0002B5DFA336DFD8D1E5A7F78FC2EC003FF81 +:1098E0005E1EDE4DFAC7ED88BF03E51F7913DBBAB4 +:1098F00028E7392F3967B8C763B7B7F97337933398 +:109900002D8E7B39D478A3019B73CE9FCEFB9339E8 +:10991000BFCA9727D8F2A474A69F65D9005725FE21 +:109920003E917CFF939FD2410BCBC7493F4E569A45 +:1099300071EC71BBBEE3CC60720231FE97B5DEFB09 +:1099400036FBC97F75C6179DF28D3FB97CCB0E5093 +:10995000FE8A09F1AE001E675DA273819FF2E76483 +:10996000E0CF3B995E2AEE78E84550EBDF528DF769 +:10997000013F2B55636C60F8D0F9E70D369E8BFCE8 +:10998000A276D91A6AE7D6B64EFB14946B77146A9E +:10999000A64BBC883FD75C0ED8E4D70EBFCEEE45B1 +:1099A00034891C5B73394CBE7F74E3F96CE7D9FAD8 +:1099B0008E1724DFF978F738E4F3A16BFF6D572990 +:1099C000A6E3DA673CA2D7324EED33EC1C900FCB06 +:1099D0006B3BBF1BC0EF7201EACD5304F9B053617A +:1099E000651335835DF4A4553E9482DD966A0FF7C6 +:1099F00011EEF4F3F6BEE6F27C97FA0147FD42DE83 +:109A00007F26E9DF391F2E7FA00C769AFC172F9F47 +:109A10001F915F0F898EFEB2F8F879A43F6EAF7F79 +:109A2000A1ADF01553063A4D948DA4FE1D1DEC809A +:109A30006FC851BFF59EAB2FF8A9DC5C73798C0D14 +:109A4000DF29B88FB3BDFF4D7DC496AF7F77BC963D +:109A50009CD3F802F327AEC1163D69B767A42D4F1A +:109A6000FF1FF3F8A0F3B82ECD3CE6FC8DE7516064 +:109A7000E3CFD43C8A6CEF3FE83C7EE0A3F2F805EC +:109A8000F69CAFD17B01E6EB02F15BCFC7757D9809 +:109A9000D66FC04F153FE7CBC80C92FB6B13B43E9B +:109AA0002E833FE0B37FB9EF9DEBC97DCF06C9C7D9 +:109AB000E1F74EF1FB1007BA9FC8F9771B9CDF0353 +:109AC00069EE5FFD6290C2E9A129372192BF1E8C29 +:109AD0009338C1C1DC0511B0D3BF32A58A3C1B73DA +:109AE0006744401E35843E67CB37C77B04D773B0CD +:109AF000EFB17ED1E51B44EB7994AD701EC5A53E58 +:109B00008F8B6D55F9FD801FCF7A777F4CEB2D0D34 +:109B100051FDB9558D93B86073E4E399FFB3413AB1 +:109B2000CE4353E6203ADF39491AF75174EB796096 +:109B3000FE3C189A11817536642E88003D3766CE3A +:109B4000B0AD474AB39E957C3DDAC7BB9E7FEFC55B +:109B5000C7075DCF02D73C5839DBFDDEF9C6101DC3 +:109B60006F6B244EE8ECE35AD7990F8DA7A1AD2B6C +:109B70008BADEB8E20DD476CD5291F05A4D87F1453 +:109B80000803F3E1407F4F0415E9E260F2F07EC57F +:109B9000E0958E7F6FF52486C3BC4ED4D3FDF36B66 +:109BA000EC3EA95FAD690811BFB6639CADF9FB42FD +:109BB000FDF939FED71AFBF9F481E48619A471A0E6 +:109BC0005BE2F676CB2B03AEF79B60F8ED2C2848D2 +:109BD000C1B30FFE3F62B8A5A3C7A1C2AD393234ED +:109BE000B80DC40777C0253783801BA7B774FDFC69 +:109BF000FF4267BB83D46E1804BC087DFDADE0F561 +:109C0000F74A5FCF0E9EBEFE012FA23707475F5C6B +:109C10008E7528F49E45673FEF84E83D9BE3859A67 +:109C20006337427CE13312F1F71EDB53BE0189D664 +:109C30007A54BF1CAB98B781E4BBC60208EECF3A9A +:109C40002E46FFBD04E20E8B693B67FFC7187C5EA2 +:109C50000E65B27DBE3E1CFC08C7634BFA5D1FAAB1 +:109C6000B0AC8BE4655AEEA392FAC2F718D277949F +:109C700080BF69A1FB3C383ED38D3B547C1E8F7D59 +:109C80006348F81C68BD5DA1C1EAA504C14336EA7A +:109C9000FD3B1857033C3B449ACF710A5ECD82FBD3 +:109CA000C910A9B4BC7204B9E76C4A98E53D29FA19 +:109CB00006F09379972CDC16C2783BBE2C53B0DEAD +:109CC0007F2686A9DD326385BB5D9811A674906AF4 +:109CD0002FA0F17ADF7A7F65F6E3B215F45E2A24CD +:109CE0001BA3165BCED54D08DBBF3BDB47C2613201 +:109CF000CE71C1FD7E583F9BC7F2A5FDB747B5C3E6 +:109D0000D8E16D6D92DBFD829C3FFE4F283E2C8C8E +:109D1000EBBF26C4BFFE79A0A309411AF7905101F9 +:109D2000C4EB793FD9324A2A18EEEF78B449E0A75C +:109D300075E927BFBF7ED2C195AF878F03AC08F707 +:109D4000B2E0FD23D92F961808CD867DA2377A2F51 +:109D50003D6C48E9208BE5CFCCAC092436839D27A8 +:109D6000E3755AE6DBF5A7799F86EF5DC7446D4B37 +:109D7000415F380C241FCAC234DE902DC5B7F8C02D +:109D80003FB64A70BDDFECDA30FDFB23E742BD7120 +:109D9000F55130CEB847E31EB8E7E06696DF845051 +:109DA0007CD422CBF8E7189D38DB654B341E8D5EE2 +:109DB000A7FCDCB16FDD2837FEF939E3D373A1626C +:109DC0005B1ECED2D8BD1EE0CFA50B1779F4207C48 +:109DD000D729BDB1797428F151D70453704A2B8724 +:109DE000187CBA4EC41BE07E8755750289234DDC72 +:109DF00044E96ED5A683E206FCDCCBF86F91806C5B +:109E00007990F730BC76ECF38F86F977703F1D744C +:109E10008CE7B17237227EAF3B1FFCF456B84BB5CE +:109E20005B40CC4F76A002F20DBA599E8889BF6F75 +:109E300006F8950F27F31DB7E9FD5A90CF5D0A226A +:109E4000E7E5FEB3D54BFE6E05A7975E39B1E95243 +:109E50003D24DD3DA2242701DD0C6FA8F9BC9B9FAA +:109E6000FC0136CF3F0463196E762E7F7279CEEBFC +:109E70002D96758F5BFD25157639C6E73DCC9B3C4D +:109E8000EF765F432F1D26FAD77BBF60729CE3BD40 +:109E900017DF27DCF7455F6172AF2331773DD15B78 +:109EA000A6570779C8E7C3E1956D5238DDBC54B2B7 +:109EB000C9DB550B038EF34814AE9FF5EA8FC13A08 +:109EC0001ED9F76F93000F4EFDE097E20A7CBF1B8F +:109ED000253D2027CE483A79BE566FBF47FA351444 +:109EE000DF311DF4679DE4CA57CF32BCBC5679C739 +:109EF0003232FF464983F99F5E31ECA652902F958E +:109F00009E28E44F9E6EBC2F749765FD5CDF39E799 +:109F1000F5AB3577F4ABB79657DAF1D6A150BBC0A5 +:109F2000FC14E5C3B558DECC26F4D5BD63261EFF70 +:109F30005822EB9A365A1DC1DF695CC27E3F23C6A8 +:109F40001F9C89E5CD5991FAC3CC7FA27263E9A326 +:109F5000B12688F39EAD9BF64237AEF713A607DE17 +:109F6000ACEB5F3F3AE969DCA3F6FB29679C400A4A +:109F7000B48FD7BAEB835B32034CBE4447837CB9C2 +:109F80006D937BBD7F86E44A0CEFB37F95D6B8E531 +:109F90006D5ED6E87C57C5DCDB5FD642F43BE82536 +:109FA00017387F2F2340E5BCAC8D0639BD2ACD7C08 +:109FB000BF9B1126FDBCDD74FF6D10EF3B23DAE57E +:109FC000F3DE0C4A17F519543E9FDD77AB6738E096 +:109FD000A959D0801EDECA8C4E007A5BDD789AF8D3 +:109FE00011FE89D5AF0CC67E171E0EFCB278FE702E +:109FF0008C97AE15282AE8E9E5FF25C63FD912BDA2 +:10A00000C700EBBF7740FFE1A6EF10FB433646DF0A +:10A0100032895ED90879856745731DC943D9E7A799 +:10A020007947283ADD7ABF8C2783C2EFECFEA1E1A5 +:10A030007B592CD0AF1D7F0CB5579171F707348831 +:10A040003F1EAB9092D7E349BEBB3FB0572AE8CB47 +:10A0500017E9C61FAA1D7876FFD0ECC081D6FD890E +:10A060008C8241D9F5172B1E79B004F848699FEC12 +:10A07000267FB99C3ECEFC564EFAE1CF998C2ECE6F +:10A0800024FA9FD7DDBBEDF3B9ADC63E1FCE2F67D7 +:10A09000120D7EC80FC7A34FB2DAA5A87CFA00E75D +:10A0A0001CA8FF37DD3C3F9D6197134079104F5B43 +:10A0B000CBE4CD9B758F84AD7870AEFFACC8F6074E +:10A0C0008FD1BCADB1B1D57387EB29FAAC6470F810 +:10A0D000A8E992EB19673F7FEF74C8F5DC4074C8BC +:10A0E000E582B3FD3988F3E3A5AF963505E232E7A3 +:10A0F000C23A2D236D011C9141A5ECDC32D247C33D +:10A10000B99BB3FBFC08FECEA6D9E64D8CC52C70DE +:10A1100066DF7513ACEBF90AC3CFAAA59970AD0D34 +:10A12000A693E88D23487E8144EEEB7AED44D60277 +:10A13000283F724404098D6EAB5D2DC1FA1ECDA07F +:10A14000FBCE559B8E127B70A874BEAAC6AEFF2FA5 +:10A15000B375F4DA59724F09D04F3A383466503833 +:10A160002C8B2D9A0FF2F98E4D0291B74D193AF5BD +:10A17000D7CA0691DBA891EA47A462786015721AE3 +:10A180001601F0F832FBFB63724CB19E4FBA6BFBC9 +:10A19000FDF3C13E74F24B0ED34F481399BC8F7F31 +:10A1A0003B637A4A3EBF25D41C1C81AB5C9BA1F16A +:10A1B000FB61099FF2F55C9B41D787EDB46F93BFBC +:10A1C000BBC4D687A20E7A13DBAB7E04F09FAB1222 +:10A1D000BBC0EFC5721FF2E6BEE1D768DE1CE52BFF +:10A1E0006EEF38DBDF2CC76D76E3FF05B9373CBD7A +:10A1F0001DF20F7DE15EFF7D06B7BF95BEF8CB4730 +:10A20000A42F8E86759B9DC5F5C6FF03C8D629333E +:10A2100000800000000000001F8B0800000000000C +:10A22000000BDD7D0D7854D5B5E83E73664E669221 +:10A23000996492CCE41F9C49000324780221444095 +:10A2400098240482609D408060030E081A2584A82B +:10A250005879AFDCE684440C14BDF1E7AAB55EEF93 +:10A2600010D0F25ABC0D965A54DA8E54507BF53603 +:10A27000F88BFDA2466B292085E8AB57DB8F5BDEB0 +:10A280005AFB2773CEC94C08DAF6F2BDF0F19DEC0B +:10A29000B3F7D93FEB7FADBDF6CE098B3A3FD34341 +:10A2A00088B655264F10423E3CF65935961FE8B504 +:10A2B000B82528AFD8B84A0E390949C692979013E5 +:10A2C000E1C529583E8F3FB3873E6F7A44269142BD +:10A2D000427FCEC3FFEB5B920CE513DD890182E385 +:10A2E000CD7285C7FA09D9AF108D9412F2C1B6CCE0 +:10A2F000F0162857DB89E69C4CC8F4141F1DCFB319 +:10A30000F98B56F724984FF77F14937C98DF3D77AD +:10A31000AE08150D1DF72F6E0B215361009FCF4224 +:10A320003208B9C3CEC65C9D4C02D83F81F19ED0A5 +:10A33000F52FBE7BBB9590C8E5503F06BE2B8B7EAC +:10A3400067EE7FE975578EC675BF7DDD8CD1AB8A10 +:10A35000A2DFC583C35229F42F4B70DC365945B8B0 +:10A36000EEB937A1B13B06DCBE8D709D3A747CFC22 +:10A37000B1C23A16F3DF976CAEB8CB0520D9923450 +:10A38000EBAA508CF1DF26A17BA6C278DA66369E56 +:10A39000799C6BF8386FD7DFB004E1FFB926BB6555 +:10A3A00080477F839C5C8EDFD5DBD4B1D07FBF76C6 +:10A3B000BB6BAD6E9EBF8D039FDF36DEE08A8507E7 +:10A3C000F15C566FA4830FC8C06BD3709CDDB1E7FE +:10A3D000B75ED09712BAF74A98DFC9AB655583F9D3 +:10A3E0009CB4C077482F8FC277BEA1DFADE2DF7D7E +:10A3F000B07978BA5C5C639CCF92638946BAB490BA +:10A40000C69E18EB59FF15E97E05D2BD3D5ADEA365 +:10A410000C8C72C3F71FEC3CF7DE9DB89E9D89142F +:10A42000DEE67E9253653ADE49E41384D7F604CE25 +:10A43000275DCDCFC1771F5C93A36E2143F9839035 +:10A44000AE6F4C87FABE6E4BC976A8DAD39DD4188E +:10A450008E31DFF1A98C0E3CB2963801DA93771871 +:10A460003E90DC906F96707A7377FFB08558A2DFCC +:10A47000BD83749040C81BAD76FADCE1B6D3F1EB36 +:10A4800016D62A3E1867AD9504107EF407FA754F6C +:10A49000C8DBB91D867ACBC2CADA6AE03F69E87CBC +:10A4A000BEC7E9724F78D1B0F0AD6F900DF0AC5BE4 +:10A4B0006884AF993E8F872D35B1D62FE839DE7885 +:10A4C000D7D9C25EC4D331BEDEB7F97A7FDBD8EE0E +:10A4D000C2F6E671F684BB87E5836F361AE9E2427D +:10A4E000EB3CE6F653B82E0F19BF5B566F5CEF12CC +:10A4F000D272150152594A541B3EEB484BF173007E +:10A50000CAE38F2CA6F3798B909A1E9CEFB9DB8B54 +:10A510006B8BA3FD1FE6F0FEBCEEF66B50ECBCA30C +:10A52000B414BB63CCE72D0E2781EFB7E2C0F379FB +:10A530002E77DF413C23BD2E9563E2F96DCE47EFC8 +:10A54000340CCF474BEB86C7F3EFDD6EDE4F7B223B +:10A55000AEF38418F75136EE89307B2FFAFBFDDF1E +:10A56000887FFB89760BA5E370A21BF58807C9439A +:10A57000A7475A53B9FE291C5E8F88E71B42AE9A43 +:10A58000DAD75903363D3E4ADC8CCF45B96EA1710E +:10A590009EEF27BBD9B8C43D3AE8D2C90DAE5F855E +:10A5A000BE7BE0C989EFA3FEF471FEAF0B7E6A4368 +:10A5B00078807CBDCB85EB7ADDE246F95A762C605B +:10A5C000D3C3EFCA1406BF93BB8787DF955C1E5DBC +:10A5D00048CE9AD7FBC13FDD3D19FBFDE09FBEB0E1 +:10A5E000E9FB5FFA652E89A447CBD7D74B81700C66 +:10A5F0003EBBDDAD8C08EEB79BE078FD97A369FF0D +:10A600001E99B4F4C45A17CA37E87749B0C2E605B0 +:10A6100078DEB0595225E882A4B27E6E10F2CEEAFE +:10A620001B5D0B70F7B6B7DC118CD14F3987F79FE4 +:10A630009CC194587C36C81F9C1E44BBA5D6902D47 +:10A64000567BB35EEDE77C6E6EB700E9D13B727A64 +:10A650001CB4834CED473A8FE9298C2FD313227F0A +:10A660004479448A8C76D805C735B5378F3B1FE1CE +:10A670003E35FEF827FF2A37C682C3B75319FD8639 +:10A6800082403F31EB5DB4FE75C2F4AB164EA2FAC8 +:10A69000F0C4EE1BEE45F3EDC6F9771C4135F972B7 +:10A6A000B29F8EDF103C5A8D6025E71E988478FF9C +:10A6B000BCE6817B4B616A279550BB0B3E38B945A0 +:10A6C000A2768B799CD7B93E7913E5E9E5D81F616D +:10A6D000743B077ACB06B0CB81752854C8B7137C7E +:10A6E0007A3BD5B3E98B563209ED87E01617BC1FCC +:10A6F000B7F9D38DA8970909D3EF3FB2A93753789B +:10A700001366E7F6753B776E8776AF25337C10A22C +:10A710008E0E16EBE484D54DCB23C5CF1B71F073A1 +:10A72000B1724AAC33DE380079FA7D6D95B353BA15 +:10A7300002ED1DF71D088F816A97BB1BD6539B1036 +:10A740005880EB3BFABAC5D2E6A7DD527B6511FE15 +:10A750000643FBAFF67F17ED99450BE58003CA7DF5 +:10A76000F81EC65B52E9D4A41450116F2CFC11E200 +:10A77000E781BA049F0C24513BDBFD4719DAD7CEA1 +:10A780004BF26D8172596F7E9B07EAEB6A2437F6B4 +:10A79000F7E2C229AE7E585FD226E827073B3B5E30 +:10A7A000533586901FE2AFD3099B30C0E20D22EAF9 +:10A7B000D3B6CD017930C1BBDFE204508F494BDB0A +:10A7C000668779DED516CC72A742BBFB4E74DAAF32 +:10A7D00022242323D03B5B2524E1FE5335F651B0E0 +:10A7E000CE47797FDA279D8199A04F2D21BF04F5AF +:10A7F00093EEB7CEB75E09F82F10FD676DC3FA254B +:10A800007357ACDD0FF5756913E65BA1FFB2063136 +:10A810009F2BE65759E1FD4CD1BED481F3F5248935 +:10A8200032CCB79C105B7E74FED62C183F4D94CB77 +:10A83000E7CF816FDFAA68A9B242FF7BD2666D2B9A +:10A84000721032ADA6C21D80F53C75FF92F94940E9 +:10A850003FFB09D029D4EFBB7FD97C9CBF47B6B062 +:10A86000FEB57A3ABFB2066D02D64BA4615B0DAC61 +:10A870007BBDBDFF0892EB864D9A3D037E49921841 +:10A880009DD86D2D815C80BBED404524974EA78BF4 +:10A89000D1675EA418F5D860B910CAC5BA72162B74 +:10A8A000EFDF42AE8F256F5BD299DCDB9F18BB5E7A +:10A8B0004A63F218E046F549CA3112D81B43AF9CEF +:10A8C0004875D276871389664F8BF2DBB5C0C3E536 +:10A8D000C097C4CEE629FA1942D75CEE10EDDA34FF +:10A8E00094A70B399D16A812F577494B52782C3A4C +:10A8F000D824625D8C2248B6D0F97A65E9FA5AE824 +:10A900002F239184F6C1D39B4E6819BE0FEC73467A +:10A91000FB7B95B116A92E08EEC6FEAA33B34BDA1F +:10A92000FDD17E60DE1DF6C986795BCBD3B07E514A +:10A93000C9AD453A7816B175001DD0EF60981FCDAE +:10A9400006BED8DF3B211FEDF7A7538D7C5DD65B9C +:10A950006923F0FD92742E4F7CEC7B6F15933F03BF +:10A96000B72685915F895D2D09EAECCEDC34068F30 +:10A97000AABB173E8CED9A7A6D2401DA6DDC5791F3 +:10A980004986D18B4D5FCE20E129BAB235A2A0DC39 +:10A9900069FA72167D5F75F7AB0AF229F6E38379DF +:10A9A0006D74043255845B7B6CFC83434EE7DDF4AD +:10A9B000652AD1A6E8DF333845FBF7D0FA0BAD2B7B +:10A9C000DA9F4CC2E9C3F5A7D0FA41B85B39DC95F0 +:10A9D000D8F3ACE4F042785B74F575486F4E2AFD0D +:10A9E000681CA5EF1B45DD28EFA3E36EA1FDEFB7C3 +:10A9F000021ED10EEC4DF4A15D5C6605F9E9C1FEC5 +:10AA0000D2DC9A14A50F411702AFFBD35A2AE87A79 +:10AA1000AF91DCDD31ECF8F9827F16327B2CB3216B +:10AA200024AFD2D1BFE007E87F3FEFBFB49CF2CFA5 +:10AA3000BF327E00BE5981FC8B760BD2A11A295EF3 +:10AA4000E41A3AFF674076607BC02383FF35CE303F +:10AA5000CE47C06D28FC732F80CFD1B4BEACF79029 +:10AA600082F4D614876F17A427D3EF328F4592D183 +:10AA7000AF7D8EDB1DFB7BA63866205F2CB41014E7 +:10AA800061B86EB457CB660AF9FDC42B95207F33AD +:10AA90004519E5AD0FF130287F23767BB4FD550FC6 +:10AAA0003C31BF03E57302E0BF88DAA176A2F32749 +:10AAB00036A53139561E2231ED96DA7466B708781C +:10AAC0007F6F5315F91DACEF502AE3CBF27E4D5A40 +:10AAD0005514E56BB39C7A98E3F141FEFCC7CB2992 +:10AAE000E90272AA96CB29F6FE3098F9D82E2323D4 +:10AAF000522C814E5CFDCA94B1E8CFDC9625FB3E1A +:10AB000006BE5A2CA9A39E827EEBEC3E1A27137434 +:10AB10005247EC3E27C21D8CA6F312DA070E5AC626 +:10AB20001FB44B3EEB92181D125F4A5D717C3924B5 +:10AB3000E6715B9642C75BBD6D6C4A483F3FAE27EE +:10AB4000AE4D883C450A86F2B928C3FCD75B645DEC +:10AB5000BD93E9B33FB8024FA741F9288F43812243 +:10AB600003A72A3AFEAFB93E31DB4B8B93399FA046 +:10AB70007949F9D8429DD3CCCE8430619F68E8A74B +:10AB800066F6303ACA6C88589A747470242D8F36E1 +:10AB90006A5806956077D5D8AB021FEBE4D8CB1284 +:10ABA000A9A7710412998A7CFA521A31CCA3410EDA +:10ABB000E64968B76626A82867004F140E871DC4AB +:10ABC000EA80715F8227E2AD5ABEF5059B07E94036 +:10ABD00052DB29F47772FB944450DF5C3B3B89DA0B +:10ABE000ADE4DCED63305EE14D62740BFDD8793F7E +:10ABF000764A275CEEFD66F4F86ED44F427E0A3C3E +:10AC0000907332ED4FD41F966AF3DC503EECBDBC1E +:10AC1000A45D32DA3F680F45EDA7DBB6CDB3A2BD28 +:10AC2000D313B1000BB5691BE7DF897638D84F0E17 +:10AC300058CF47694C0F1EF66B7232F63716D601A5 +:10AC4000AF8E24868A5A9C517C808D1342FC6528E5 +:10AC5000F07432FEC0675B3AE33397873D97F16744 +:10AC600046326B6FA6B79B787D00790F9EDB2B98E1 +:10AC70009C30B7FB6FCEBFEBED5A4D46BEDEBE0A31 +:10AC800012A4432B6176D65F39DE409F517855DDA3 +:10AC9000DD90827AF3F3DE2529A4282A476DF63762 +:10ACA000467F0C72244216FF33F2ABF2964CD05E14 +:10ACB000BECB067400ED94D4903B0D9EE949B1FDE6 +:10ACC000E6317C9DE9E85743BB7BB9DF63FB722229 +:10ACD000F5B733B87D969C5547E53AC2D207704E1A +:10ACE00021039A5B87C794728BC17FB07D39897EBF +:10ACF0007FF1F643491CFBA1D4603F8871CD76C437 +:10AD00007BAD5974FEE2FB15596F56135DFB95A49C +:10AD1000FF2EEC6FE5C65C43BC289EFD319DC3074A +:10AD2000ED052DE6BC14C3FBF7C05FD4F4E39F60D0 +:10AD3000E347C74D02868B8EFBD7B4C08C741A0FC5 +:10AD40009AE93E3E111E60C39F97A9DE61FA1A9EE2 +:10AD50003B9D542FD5A0DC167E12F2BF3B05F9BBFC +:10AD6000A22ADDABD393FC3BB33C3AC8E31A07B944 +:10AD7000BE493926ECC6449F2445F5CE50BDC5EDED +:10AD800062937CBC909D0D74ABE9ED8021FC92FE3A +:10AD900055EDCB8238F431EE1F625F96CD0CC9C5FC +:10ADA000283F6B2432161ED3E618F5FDB7D39D74E9 +:10ADB0005DDF0686D3FB2D8B1A8CED5AD399BFD25B +:10ADC0008AEDBC1786A75E1F4932CA3DD65F33CADB +:10ADD0001BC0B3FFD4EB8A0FE4F0F3DC1EDAE50905 +:10ADE0006C45BAE8484C9E847AA223717418E31229 +:10ADF0003BFFBBAA7027FAE9AFD9D46EECF600F39B +:10AE0000F32B966F6CB7C27B5B8FE44E20D1793AFF +:10AE100037498135404AF7737C3579D87A9A3C11A5 +:10AE2000650C8C9FD3C4E691D7F38264D5C9BBBCB3 +:10AE300046D6EEB1749B41FF8479F9F17411EF08A5 +:10AE4000B7559762FB8015F741727A241A1FCE69B5 +:10AE50000140003DE4A8AC7FA71A966E288AAEB7E1 +:10AE6000D3525B847AA2332349453D71CA137A12C7 +:10AE7000F9A8A92F1241704DEBEBB5A2BD67F506FD +:10AE80007E807010EBF4C9EE1C94B3497D6C7E5D3E +:10AE900026BA27E4BB3C3EDBCDE4AF4C5E268817E8 +:10AEA0009421305EC69642AAA744FB8C34AE37325A +:10AEB00048E8696A67914E42F146E83A32B68CA397 +:10AEC000F6BEC06BD4AE1A3F19EDAA821D11EB6A13 +:10AED000B45B1F8B1DAF3FCCE50FAC2342E5C481B3 +:10AEE00091C565443B5B1CBF5AD07D524D6C7B15B0 +:10AEF0003401ADAF58EEB90ED7DDD4A19004290AC4 +:10AF00007FAB37F806CE27A767A784B031D3594760 +:10AF1000DA0FA55C58E7ED3713B74CE2CFBB699366 +:10AF20001C58A3E7E70E85E265A762DCDF137EC647 +:10AF300069AE8FCABDC1DFE1F8CD07EE5310CF3740 +:10AF4000EFFE50196E5F67A470931A99FFD2546F89 +:10AF50000FE37A2B965B291ED7752861944F4D7BA2 +:10AF6000F7452C68676F262AF27F53CFBE2339003E +:10AF70009FDCA6C054D9A7F39F9BC212CE2703889B +:10AF8000B1B788CA4D05F5B699BED14E467BE58866 +:10AF900083F1FFE90AA786F1B4D3B65013B63B9DFF +:10AFA0009DA46AFE28DC5FDA37EF650958DCF5748A +:10AFB00042049F9D96EE2C3BB4EB9CA0A8484F56B4 +:10AFC0006FC8EE8175A45983FBF1FB548F4B6D83E1 +:10AFD0006F7D096432D5D72384C334135D4CDBCC39 +:10AFE000F865BA2759D88193512EE57B5CC28EA2B1 +:10AFF000F2EA888DADA383B0F9B6A507323D48B714 +:10B00000EE343A6E4E5344423FC03C6E94AE02A3BF +:10B010003CDE8B99678F82727E1D973715CB774BFD +:10B02000BFD3D1419187EDCFE6ECDD29A17F08F5B3 +:10B030006DD51EDA9E24A0BCD9CBFCE27550BF565C +:10B04000275FC43A62C89929383F675FEF8B4CCEBF +:10B050004428FD89F99AF139DBC3ECBBB96026D0ED +:10B06000F78A56E883FE8EE427D2FE04DF9BF9744C +:10B07000B687D1794EFD6EC95244E382D49E14F353 +:10B0800013ED76792AAB3C140EBD140EEBEBAD2C10 +:10B09000DEC0E753AD04C7A05F56EB61FB5D87964A +:10B0A000BDAFF443F9C19F1DA5F4B8BE4B0A507F54 +:10B0B000A1EBA8B204E376DAFF91314EBB80992868 +:10B0C000E4A19F1EA57A65C17E168F5FBF7F9FF5A5 +:10B0D0000667944EFDA70EAD443A5BDF93401C1209 +:10B0E000E28FADD74CA7206728DD134DA1FB5C2074 +:10B0F00027352A5749C88F7E8A90C36DE97C5FCE79 +:10B10000C9DEAFE1F316FD46E5A783D2BBFFD4E469 +:10B11000437680E77A5552C174023BDC47DB43FF3C +:10B12000112A878144D15F13FD9BE1D7E5617A2D18 +:10B13000069E5B3C31F489D0B3FEC72B093E05FE69 +:10B14000AC1CEE83FADDA3D07E5B3D563A9F8E0A9F +:10B1500016D7EEB0313DD2D1660F235FBF943AF7D8 +:10B160006509E4A52B4D89E0F3B0657513D61FCEB4 +:10B1700061F3E8B46C296C617A4CF350FC2513261A +:10B180009F983C7AF0274C9E34694EEA3F3685EA18 +:10B19000D6D07D098F43C57D09127A5159E28AD2F2 +:10B1A0008319BFBEA75F507C50BFA087F141146ECA +:10B1B0004C5F09BA053947F1DE26E2888037842BD7 +:10B1C000F8F56D187F107E7D72435073F986F26B2F +:10B1D0003AF7EBA772BFDE566EFF9BFAF5EB36FD32 +:10B1E00007F5836EC97A853E05BF80FF68E0ABA78F +:10B1F000B89F763F7FEEE7FCB9AEB487F2C3BA8F53 +:10B200005B281F396B983C71F619E52021F7F0F5A2 +:10B21000EF60F498D43317F725AAFF4D72B793F86F +:10B22000F3BE496AF94FCC9321FB78FEC639B0F2E0 +:10B23000CB00AE0E0E03DEEE08E7FBD37B0011C899 +:10B2400097D61665387BF842FD92C89B12E27B1DAB +:10B2500087F5E9BD5557FE1EE38C7B52683ECB2730 +:10B260007B17FFAFDFC3F7A777CF56514F7BDA834A +:10B27000947E06BC0E15E3A7203E6B24A087B69EE5 +:10B280005F25CFC0FDB21F5D3119E5E67B7C9EA72F +:10B290007E226F42F86CF9C18F6761FDBAB0948E5F +:10B2A000F6E3E93DFFF657D48B8DBB37D0BCB4F63F +:10B2B0001FFD92DAE596F04EF67E4F0AB5334FEE5B +:10B2C000BA6F16C2BDBDA79DD69FDAB593960FFD86 +:10B2D000E0C7BFF80BDA1DC16415DB9DFAC97DDF3D +:10B2E000F90BD2795DB28AEB680A59D97EAEA06FAC +:10B2F000B3DCDAF702E553412F0B50EF229CEA99B9 +:10B30000FC11F4FC11DF6F5ACDF7B13EDAEE6A8C16 +:10B31000156794BC6CBD188BA172AC5EA271B64E61 +:10B32000A01A8C77742692727C261545945C186757 +:10B3300059C3BE59D4EED13EBC11DB2F3EE020DB19 +:10B34000695C0E83BAD17DB0621083C7C16F86DE9F +:10B35000779F07BA7D1BE403D53B267F6071E72BFF +:10B360007F46395A67EF7F0145A178DFC9E337D0BF +:10B370009EEA9DB28DB1E3A40EAF93EB6DA6377339 +:10B38000F6D7E6F9A89C4850C7EAECD351C75AB69D +:10B39000637A524E63EF5C5CC7D585ABA650BAC0EA +:10B3A000F81FEA1FCD49FB5F8FF14BE0BF1C2F93C5 +:10B3B0009F196EE2990EE3575B89C7894F42DEB44D +:10B3C0005139F204ED17EC0F6A57F97EB9EC09B464 +:10B3D000471EB285B2A7623F9D5C6FED66F386EFB4 +:10B3E000DDB88F0AFDB9A74FA6FDF4DAD2E8F71A47 +:10B3F000FB7EDEEE36293A5FA0D4D1A8B7B0BF52AB +:10B4000027EA19AD9EE2C7A7D0759DC226D974DD83 +:10B4100093561447F9D71CF7417986FBC3E5DE8ABA +:10B42000295E6FF429E2416678DE89F5D0CF33DEFC +:10B43000007D923D467F3B9EBD7268D919A67F9FD5 +:10B44000FF90CA9B66A4631C3FF4B141FFDE20E875 +:10B45000F8D90F291DDF7080E9DFE603250AD2ED58 +:10B4600027AD01F23B30409B2B816E817E1F92FA0B +:10B470006FA4F92ECF3ADC18D73BC3F5CDBA1D1F08 +:10B480001E97011EF907B2A99F7FE659473DF67343 +:10B49000D862A1F03CDC3D7167BBA49F27F30BC0D1 +:10B4A0000EA6A4DA0C762AB383D7DC877EDAFA46B6 +:10B4B000A222FF379BE8A7F9C0514A2FC20EF63FE0 +:10B4C000BE680DB33F1DAA03FDB839CC1E25608FA1 +:10B4D00062FBD439E13685D2574919D2D7A165BF6D +:10B4E000D88A7ABC790E7163FF0F8D0A3C9B4BD7CB +:10B4F0002311CC7379C8D6556985EF1FAAF6B90117 +:10B500009200B7DDD4EE25850AD7736BA8BDDC9C0D +:10B51000F54D95F299591E3CDB46EDAE665F229DD6 +:10B52000CF8203D26DCC1E7112367F89D2E782F0B2 +:10B530008C30C6CFFEC8E127E078C6D6BB12E171D9 +:10B54000E6A7408850BF600EA3D7D4393D548EBCC7 +:10B55000F4EC3CAAC7055DBA9E49A0FA3CCDEA9638 +:10B5600054AAD71627E8F1DA65637A2995EB998210 +:10B570001D0CBF6D5EA697DABC16FE548CF117B792 +:10B580003609F5EE1F39FEA91841F9CEE5C9FA359D +:10B5900011CA4F4D7B597F9E8440C9ED3AFAF5544C +:10B5A00031BD28F603707FA03686BC7892CFC3FFEA +:10B5B000F8EAFBD05EBE1AF08E2A25A790CB51A0E8 +:10B5C0000B845B4E6390D2C1D59E9B54CC4FF5A6A5 +:10B5D00013EA2F0EB4292456DCE7877C5DDEF46085 +:10B5E00029C6A1BD992E6AE778E50A8B03BF2B9186 +:10B5F000D46E1FDDF7A476DE80375BED36F07BB0CE +:10B60000D402ED4E64B8189EC3BFB12E2A463EF454 +:10B61000097FDD60F70DF5BB99DDB8B04B9B847EEB +:10B6200088D8D7107008B725D6EBE5670F976FE17C +:10B63000F12C9E0AF6BD93C6B5DD300EFAF7DD3368 +:10B640007631FFBE9DB6FB9E97D947D5B03EB4DBA1 +:10B65000BC05C18D4C9FBAD458F028E77AE5D0B22A +:10B660009525E85736D73955E4B7079F9756537A4B +:10B67000C66021FADDA135140F04F080FC4042CCF5 +:10B680002F6D6E098663D37B2DE5BF66E43F89D2BB +:10B690003B8DC303BD8719BD33FD27FC7F948FFA13 +:10B6A000BC432107847C6956FAC7211D0B7E689E26 +:10B6B000D53F0EE136527972C606FC8FFC0370400E +:10B6C000FE11FCE27A8EF1C9F6365F05D66FAF2621 +:10B6D000EE769D3E32FB4B384FF43B855C3FE509EF +:10B6E0007E8CF2B7D912D98AF915420E373FB76D61 +:10B6F0005CACFC372187ED5626DFECE1A470BB8EF5 +:10B70000BE70CFCF35993E693E4FD2A6D8F1912F6A +:10B71000BC4E1EC71F59BE4406EA729437DD493439 +:10B72000AF5DC48BCCFD9EE4F426F022FC16DC77E2 +:10B73000C0F6E9198C5E940CC69F7919223E1B361F +:10B74000F83D3E4BE843CC338AA7BFC4777FABF8C4 +:10B75000951847E85133FEC5BE09AEA7B6287EBB93 +:10B76000AE17987C32D3E3182E373EC4B5C2FF7FA4 +:10B77000E7FB5C43F1CBFA21A1F186BCB84ECBBE0E +:10B78000C65871B0175A79BED463E3479477F7EF80 +:10B79000BCFDBD3C2F8CAC196FC8B372AABE368CF1 +:10B7A000A35E71D05722D371591CCB358B7C8A7A1A +:10B7B00038B9BCAB10CF4D7883C6FD92CCFA44C3E8 +:10B7C0007E447628CD50CE6DCC31B41FD5926FA873 +:10B7D000BF6CD30443BD5F9B6C2817744E37B41FF6 +:10B7E000DB5569285FFEC8D586F6E3C38B0CE5ED13 +:10B7F0006D3DF58897897BAE337C7785B5DF520246 +:10B80000EF8B7B561BF3C74CF0ACFCAB1C930E6F5D +:10B81000CAF0537C5D71C0088F9472233C305D0E7A +:10B82000E19C42787F897F5687CB6F4D21D63FF5CB +:10B830008BEFFD43E981D8DDA5FABC8428FD840D9A +:10B84000798B9556D9340FED2BD15FBC798AFDB633 +:10B85000B8EB8803B7ED837CCFE062E3CB4A995520 +:10B860003F2C5C6C17820BE957470217F37EDF60B1 +:10B87000DCD9D4DF96A4669A27FC261674F6717F6D +:10B88000ABF13CCC522D85E9A1E0E20BD8D12C0ED6 +:10B890001C4A60FB95E6FA57B85CFC03C084CE678F +:10B8A000847CFD3EC7431FCF9F1FC2D79B3E3D9C5C +:10B8B00089F2BB8650BFD9DDD2F629EAADEBAD11D6 +:10B8C0005202F37E90AFE7212E171E6975D37E1EBC +:10B8D000E5FB918FB5FAE8FBC75B0BE933DCAAD235 +:10B8E000F7DDADE5F4B91BEC397C3ED95A439F7BBB +:10B8F0005A83B4DD0F5BEBE9736F6B88CD6B08BEC9 +:10B900004819B57382E931E3A5AB347944782272E2 +:10B910005E4C7D19B71FB961D8FCF24D7DD28F5FA7 +:10B92000D4F1CDBB192E0FDDDF9C46A6E1FEE685E6 +:10B93000BEFFA295FCF8C5B123E723414FE45CFAB2 +:10B94000B8608CF85188E7553E9911FAAEE68C0F35 +:10B95000AF289DC586539DFD4C0E3AEB93D066D023 +:10B960007D2FCE9F88725D2825A6DDE0CD64F45939 +:10B970009FC0F6E3979BF8FB5BBCFE5B994CDFBD79 +:10B980001B47CE38332DC29FB7D1FDC1217C77EF45 +:10B9900055B1E0BB35D367E063F3B915733FEFDA18 +:10B9A000BA46A931F8EC42FD88F599BF5B9AC9E423 +:10B9B000D6C64CC2E4E4FF67FCF9EE5A17F51F1037 +:10B9C0006E5EDDFADF5D9B541F2B2EF39D4C1BF347 +:10B9D000B703A0B3D3A8A9AF29682B16121FDBF7B2 +:10B9E0001DE3C6F890C80B884FAF561A47A2309493 +:10B9F00087C215F0E1530AA07FEBE038112B8EA32C +:10BA00005AA2FA0D736D88EEFC873C941EE07B4DC4 +:10BA1000A1793DFD3938BF8BA527223F3676B87D09 +:10BA2000BA21DF5FA49CB931F3EF2B67049F9373B6 +:10BA30000F8C8DA527EB51CE4C075193F9289333EA +:10BA400017E8F762E1572FF7D3FDEB11C3EF8067DB +:10BA50004471A92F1CC993D0B8DA6467CF3B139304 +:10BA6000BBF1F9856374982413F200CE13DA69955B +:10BA7000849DDF7A5FF84D2DD3E8FE4A76F05F3281 +:10BA8000A17EB5C2FCC53319818732615D897C5FB7 +:10BA90003891EF0B2B99CA562C9340215DD7247017 +:10BAA00097316EB1D5E21B8DEBFA5852C7A3DFE296 +:10BAB000B684557C26934831CBCF0B87D05F4B9F04 +:10BAC00098E8437F37711C21BD343EAE3A308EA6D4 +:10BAD00024F5BF3E06FDDBE7AD345E3409F351A12A +:10BAE0003CE97BB9618DCE3348E5453A87E376B4CE +:10BAF000CBE1FBEF4BA1A770DE27DD76CD02F37A19 +:10BB0000A0738A230DDE47F6C89A9282F931A7EF17 +:10BB10005F00EBBDA257A671E72BC89457C6A09C47 +:10BB2000E9B5D1FDDF7556B203F9281E7C3FF95601 +:10BB3000EC3C30922519F2BBCCF51F703DF0499CCE +:10BB40007CE3DF70392AF2676C227FC61B18367FD0 +:10BB5000C666CA9FB1598304F7856D83F9330D8496 +:10BB6000E6CF403FFAFC994F2A63CFE31D3E0FDB3F +:10BB7000974971FA4DA6EF3FC91F7E9DB62F1D86CE +:10BB80007CECE8F74EFA3E5EFECE001FFF9338F9DC +:10BB90004BA707FBCF265ABAFE3B46CFD171F268BE +:10BBA000BDCD940714AD67F93F1DA98C4E5EC872D8 +:10BBB0007B5641D7AB483F3DCF79BDD363C3785265 +:10BBC00090A8FBE8F91EAB6DA05FF0613EB6B37EB6 +:10BBD0008476B705242FDADDD76FB27DD4AF935BBF +:10BBE000B5016399607B9D1C5E88316CE4A7098573 +:10BBF00034FFEF33E24B710F23471BEC72D0AA5B8B +:10BC0000475F1C3BA2348BC1A72F3B36FC466559CE +:10BC10000C79CB43BF4FE6E73ED839B4DBDDC3CB6D +:10BC20004F846F285DDFBF190F1E5A7F21387BDBE1 +:10BC3000197F0F54482CCFFF6F0EEF549EEFC6CEE6 +:10BC40000FD84CF9EA0BB3CDF366F9EAF7A706CBA8 +:10BC5000B2D02EB3FAC6E9CF0BECB7069226C3B327 +:10BC60008FCB1D335C3667317BCFBCEEFD3CEF3EA6 +:10BC700051262DFB74F037AFB785E351B4EFB0B167 +:10BC8000FD2C147C76907B2B0893B3CBB2F2F93960 +:10BC900097542BE2AB81754156B88FD0FD2501E753 +:10BCA00021F0E37037C331487C2B31BFFB42F05C9D +:10BCB00075345141B9BFD23E70187DD5FE5ECBDBE5 +:10BCC00063E0F9A173CCF1DD04F7E10A9F39443058 +:10BCD0003EA2B27C0A3287DA3D92962B9F9F387241 +:10BCE000BB676B72A810F9E26389C56B853EDA9A6F +:10BCF000736A1CE6D7BF9F5651943D95C6DF03E992 +:10BD0000483F3F4F60F4F308F404E50DBF184FCFF0 +:10BD1000C12FC90E4DC8F646F3FB4860601CE623F0 +:10BD20005C2C7CE0C786F47321F8ACCD62FCDD9717 +:10BD30001C9B3E1EE37C7821BEA0E7CF4AFF7E7CA1 +:10BD400021E029F62FC4FC266433392C9E026EE6CE +:10BD50003CA209D916DE8EE5112DC90E52389F1D61 +:10BD6000F5E97107CCBD4F897DAF434F1CFE30AF65 +:10BD70005FC0FBEF257FFB1263CFEFC5FFE1F91535 +:10BD8000E3FC008E7D9362CFEFDD11CE2F4806DEFF +:10BD90004FFD3BE82FC07331F21DE918A072B12F9F +:10BDA0002DF63CBF1CF13C43B6BF879E15F44DB445 +:10BDB000558D74DF3E2B31E6BEFD52F0A3D00F321D +:10BDC000EFDF8B7D7A901F74BD75F68195E988F75A +:10BDD000397CDD1924928AFB9ABF48A0FB0043E41A +:10BDE0001AE77380978DC26BE1008D67F48D8B2D00 +:10BDF000176CD90C5E83ED3BD938F1CE1FB8387F74 +:10BE00005EE8FC01290DD1386085DD1991010FB77D +:10BE1000717C28B9B7A868175664BD7A0CD709F0A9 +:10BE20003F3D084F5D5EDFA9D697DD636CF1E5F617 +:10BE30003AF9E9B29618EBF167847C280F06DBED3E +:10BE400079C53D4687AF62D26F61E7A7072C06FF31 +:10BE500038935C947FFC3307E3E7F7D382541FA049 +:10BE60007E40BDB3F5B92B4B1099685F605ECF8003 +:10BE70002B91CAD1F69CE9853E1D3C2BB3855D29EB +:10BE8000C7B117BFDEB980A8BD2419ECD668FF562C +:10BE9000FA5EE0A7C2F9EB98F8F06704E6213C3FB0 +:10BEA0004F0BD4E03ACDF0D3EE9E994AFD6584DF86 +:10BEB000EC687F83F88F83E75B33028BB0BF89E93F +:10BEC0003E16BF10F97C83710BABFBB83D0AEF91B6 +:10BED000E2E55EFC05FCD5DBB2032BB17F2581F3E7 +:10BEE0002371D2F3E3C25E2126BB8694B3FCD21544 +:10BEF00059AFFE19E33E5B9319CB6EFD8E83E6D9F5 +:10BF00005D2FB9155C37D81FEF7D1FDA8748E4BD78 +:10BF10006FD37D2D616724C9E793463E4FE1375FBC +:10BF200028BFFA10DA61309F4A8B93EE731E02B27B +:10BF3000C906B951A9B067C53CA02AE8AF52CE3BAB +:10BF4000D80FF3FA9C9C4EBB0ABE4EE4F1C58D4758 +:10BF5000A73A902E2BADB6537AB9658E7BDC956DE2 +:10BF60008C7B7C4E16FE33DD0B2E64FEFF030B2B09 +:10BF700033F57197C1B8873897A6AD62F2D424E73C +:10BF8000843CB3D8D93D2324407CEE0C1A3F627028 +:10BF900007E71AEFBDBA4A94D13981F24C8E2409D1 +:10BFA000BF87755FC59F6475280BE50CA6F3E07825 +:10BFB000E0F565E1B3FD4AD587CFD952D0CAE61185 +:10BFC00066F987A4250FDB5BECFD328E2FE214743B +:10BFD0002619D88F1897955DBCDC51F7D9CAB5BE24 +:10BFE000A1F10CE27451BB57E1F33BE9766A165DAF +:10BFF0009C23C1193949F356F9D31CEFB853D634F1 +:10C00000CCDB4E243D545E3A9D7FD410186EE296F0 +:10C01000B0FC7D29F433E4B7E34A17F1C3FBB33F27 +:10C02000FF8220FED2F16458013E8DFAC9EBDC4854 +:10C03000F3A1BD41AB492F8524E4A3CC7AF37BA3C4 +:10C04000BEB2933E7A6E488A04B3CEA75F388E1391 +:10C050002F7E63AB64A81FB899D9C36F27B2EFDFF7 +:10C060004E64DF1DE37AA6394D212CBE63B7A33D94 +:10C070007FC675028F6AA23EE9447D62B705285EDD +:10C08000855E59BFFF5682786B3E504BE1F05B896D +:10C09000ED8F6A2B249AC7B094E7DFD51791D702AA +:10C0A00038B59C7CA6CF5E0EAD688272DDABA4383D +:10C0B00002ED4A6607ABF15E97F662A26E8172BB33 +:10C0C00023F4D44F711D47D93D631BF8795AC0C47E +:10C0D000BABDD0FFCEEB46A9DB714955035B314FAA +:10C0E00068601B71635EC910FA3D07FC00F4B00B79 +:10C0F000CB30EF0D6B42FF7A07B4CF7E95A8B40D1D +:10C10000AF471F05F12771BAC0F7B3E1FD064E47EF +:10C11000050725B6BFEF61F77FD1CEF17E2E3BFB41 +:10C1200075C3C18A6BA7C2BC0A7AA750F21E03ED81 +:10C1300031FF093310587B6289D57E0CB6F7E17E5A +:10C140003EC30FC951E8BD4984CBBF69263E9C114F +:10C15000E5075A5FC2CB1BB89E32F00DF603FE7A9C +:10C16000A08C6DF7D3EF3C8C3F54227E183F4F27B5 +:10C17000D11FECB72A3A0E95CB7378DDE1E5F36970 +:10C18000DEF7346BE405E4F719FC59C29FC8EF767B +:10C1900080E3326BCB612FAC27751351DB709406B3 +:10C1A0005F3BF6574A8232C2B9CCBDAD1DE7776519 +:10C1B000C3D174A4AF753905949E66DAD502079091 +:10C1C000487BB9AABA0BF09E3189C26549BD3D8C46 +:10C1D000F96D4B06EFF909F99702FF2C0BB1BC661C +:10C1E0002C37E8E2B522EF6F6902F8D531E4F7BAEF +:10C1F0001C662789EF37F07329A2FEA61C96FF71F3 +:10C200004DCEDCD21C9A97C4F2A181FFA76159C818 +:10C21000151897E6AB2C26011BAE6B31E75FC1FF0B +:10C220004B02B7537B7649D06897FE5662F8D69694 +:10C230004BD44E5C563FBCDD3A3747EC07E7B98F2D +:10C240002745DF0BBA12F27C11EA7794C335A0CFF1 +:10C25000757673C39DE752E977994FAE3F7F59F4E6 +:10C260001CCC06D33998667E0E66C381365B06D237 +:10C270003B3F07B3E1E0875BF5F97F024E43CFC157 +:10C280000CD0BCC7A54AF8053C1FB4F4165823B41B +:10C29000FF153F37F1229E9B981CA523D7758E086A +:10C2A000CBAB0BD0FCBE3C77928AF9289D96C93463 +:10C2B0009FA833D9A5EAF377B6B7B554633B914746 +:10C2C00024CEBD2C8DB35F7C7B0EB3B71F92583E3E +:10C2D00097B6DC4EE1ED95C931FDF97E6F4190E6F0 +:10C2E000D195E6F8447B1A5FC0BCD329F00C839942 +:10C2F000C6F0C5BE37CB07E8AF03FBAB2A5069FEDB +:10C300004C550ACB43F3A6074B6E2B8AF65B77900E +:10C31000E5EDD5053F3DC2F26F6B4B119EF1E4BADE +:10C32000597F01FD75E6C488D3DF29879A91FE6C99 +:10C3300095C1E56BA1DFB3AF2934CF8E6C0E4836C3 +:10C3400068F79357DC2A9EBFEBA808D656D37A2B02 +:10C350003D1F98514F2209505FFAAAD28DF97D8D69 +:10C36000A44BC17E1A4D7AEC16E78B0AF2E92DBB7D +:10C370006D51BA249897A816A0C06BDA3B242E42C0 +:10C38000E590904F667A26638C72A844C85D900F42 +:10C390002CAFAF81E93DF2A484F1A1B3AE1332F723 +:10C3A000AFA9DC9B2A849549DE4F3DF812B567049E +:10C3B0003C6781BC403F4EC2F793D8116EBABFA50F +:10C3C0004985986F3A8324527A1B6247F0F9950E9B +:10C3D000CE9FD94D424E56943393D48C1F188FD292 +:10C3E000B9D8E79B8AF7FAC073061FFF0B4BA0284A +:10C3F000E2477C91B005E0BC556AA17AC78EF99FEF +:10C40000F0DC2E85A85CFC99A6C908D72B49CBE2A5 +:10C41000857E8AF72339543EF626211E8E2BAA1DCF +:10C42000EBAB3151903E8DF89AE77CD08AF09A9729 +:10C4300065C68B6645F8CEF70DC1173D571088834A +:10C44000AF80902BC42857FCE41C3BD7BCEDC81D23 +:10C45000E81F5FC83E793023D48FF2339E9D122FA0 +:10C460001FEF2497C723CDC73B6B637EC574D27F74 +:10C47000E35E69289D9C39BC49CED2D193A0D3E715 +:10C48000787EBEF44B9EEF5BEAA2FA2FAA2F191D0D +:10C4900094F1D274A42F1D1D5C75C01191619D256E +:10C4A000FCFBE9480F93A3FA326271FA947CC4BB97 +:10C4B000DA29CB43EDE48C341FC5FF144B80E27FB7 +:10C4C0002A51D3B9DDA9E4C2FACBED3DED561FC523 +:10C4D000FFF7D1BFA9203E8AFF0A93DEA972D65981 +:10C4E000914EAAEC663C0728FEABDD43DE5BBE0A3C +:10C4F000FE2F43FC0BBD3202FB14F0EFCB1D669FF9 +:10C50000311EFEC7E73A795CE3E2F06FC6BB9003E9 +:10C51000FB1CEE2A27C6831B593EF294D7C6B46390 +:10C520003963BD9F9E93D997AAFE8AD6B7B0FAD237 +:10C53000DE808CF732166C847A28EFF307ABB0BC40 +:10C54000619344E5E8D43743ED581EB399D5976C11 +:10C5500069F915DE6FB64163DF3F77722BBDA72205 +:10C56000BC957F5FD15585E50D9DECFB3FB8EC1A7E +:10C57000FAE565C7C2EDF87EFC0E360F61F7CDE631 +:10C58000F4B64F7AFA57F4BB2EF6DD4D47EC89CC62 +:10C590005F6276DC2CBECED98FB1757A7E77758DD1 +:10C5A0000FE0BE7640B351B961692AA372348E9F01 +:10C5B000562175E5E1731EC80942F10E749ACFF257 +:10C5C00055BB6188B5B9CC0E11799E986F5EABC32F +:10C5D000D7DA5CA66F45BB8C34C2F2921F65F7CDEB +:10C5E0008A3CD4C8C344C2F801AE91EADF3879A9C5 +:10C5F000F30A5AA83E9D7799C847EDB7AE86714BAE +:10C60000CEFFDFB9B1FCF2263EEE099E3F2FDE37AA +:10C6100086FD16F44FF621F1D0FB7F7EFE1ADA2D4F +:10C62000FB701F5977FFC83E3F2BFFEFDC67EFE938 +:10C630000427F7264B8B554325305AA2F7A97CA334 +:10C640009744529287CE7F9E954458DE049BFF8D7F +:10C65000ED4AF7769D1DBF44888F9963A95EA9E3D3 +:10C660007812726309C717F0793BF2C7527B0BB59A +:10C670001B9713A6D76F26611ADFB8D9C4E7EB9CC6 +:10C680007F7ADF82F6F31E233FAF87E9B07DF58125 +:10C69000C7DF05F8373EE272A3FE5FDF636CD7F8B1 +:10C6A000C86BC798FD65E4F746C1EF6123BF8341BE +:10C6B000C1F8FDE10974DF469C0B74D807DED7484A +:10C6C00074BD837ADFC47F0E3C2758887E8D85E554 +:10C6D00027F2B218F7B32EA69735D0CBDC0FA222E3 +:10C6E000F7B3BE05340FBE44E8512E67043F977080 +:10C6F0003D3F448FD798FD9D07299F4CE125B3FE10 +:10C70000167A5B9C3F847EA9FE067DFD5A00E6DB1F +:10C710006B718611DE51BD1DA67C34D90EF2DA4252 +:10C72000F1F73CCAE9A91C6FED5CAFC7F50F9C1B84 +:10C7300063FA07E06FD07D84A17E41C460EF9BF176 +:10C7400016CFFE1FC49B03ECA924F4F709E3E31CF6 +:10C7500032A2FC1090DBEFE40EA3B79543ECFDC0D2 +:10C760004E078D2F8838BBE0BFDFE4B1F8C277B346 +:10C7700003EF613F7D7CBC3EDE7FDFADF3E8BEF7BB +:10C780009F4880EE7B631E536E8CBC0BDCF7EED0B3 +:10C79000C54BFB5263C7C13FE17260621E5BDF198C +:10C7A0006FE034F2D50985C5D94F24F26732DBA793 +:10C7B000F82297C57B27E6B1A72B8FCB119EDF7D93 +:10C7C00022CD189F17ED52F8F3E3567BB043170FB5 +:10C7D000F73D9CD0827ACC5BC0F3E137323A3EFB26 +:10C7E0006CEA4EFDFD7039791513F3304FA420A08B +:10C7F00064637CE659A62F9AADFD0ADEEB93E20D49 +:10C80000D9F2302EE32381A7B11F5FBFB218E07DBC +:10C8100096EFF79FE5F7009D75B0A798574E5EED30 +:10C8200044FCEEECADFD546E0C966BFBA95CC8C9E4 +:10C830000BD271CF2E11F5BC7C0F2B13EE57567017 +:10C840003EA171E31871E2A17161E33D371B94D8F9 +:10C85000FBD424CF6588F7AE38C8E2902BED646B2B +:10C860002ED45F7F3093FA1B8DC9DA38A487AF1BB3 +:10C87000C73D3BAA97AE6B7BC5C0E8474BE9BE30CE +:10C880008D17AD3FF812957FEB05DFEC37F2CDB495 +:10C89000BC91EDA798E3EC23E0A78ABC61ECA0670C +:10C8A000507FD9A278B88DE75155CB4D551857FA1E +:10C8B0006C0DA1E76B6F7B45A67475DB5312BD6FE2 +:10C8C00042D871EB399CE3AD0BCF27F8747205CFDA +:10C8D00027F8747E1D9E4FD097F17C82BE3D9E4FFF +:10C8E000D0D7E3F9047D3D9E4FD0974BC80DED188E +:10C8F000A7DBD049DC611F3BAFA0FF1ECF2BE8CBED +:10C90000785E41FF3D9E57D0973F230C6E9F3D269A +:10C91000D3F83F9E5BD07F7FD32B3F298BE0B21DA6 +:10C920002C3FADDD01F0473AD402BD45009F351CD8 +:10C930003E78AE41DFEF27C9735F46FCACE9BD71BD +:10C94000213EAF38708BA15FD2C5E4710BFC433838 +:10C95000DE488229E8CF4D26034730DED11C9654AD +:10C960001CF7A6478C727BF01E93B0F1FD3AA28BA8 +:10C97000FFFA87C6FD3BF25C9EE32CB739471FEFF9 +:10C9800089D283538D201CDE94D558F450422E4F0B +:10C99000A1719E97658C61903F909687664ABAFD1B +:10C9A00001133C12B28C74E1F019E922A9D04817A6 +:10C9B0002ED5481729E546BA480D4C1816BEE9355C +:10C9C000463A59273751BE17702E877F08E7C97836 +:10C9D0003325C217D689F162337C1B0FDEB715ED04 +:10C9E000FE8B856F4F1EDF57E1F0FD9CCCAC72FAD9 +:10C9F00068759DBD2C6AC794BEDC423781CDF1536A +:10CA000001476147883828E87F6A4F47FD7AE6EF9B +:10CA1000817DF04B94C3C715E6E72125A1DC5C4B73 +:10CA200042543EAD35D90737391F54D03E18B25E57 +:10CA3000B0CCF0DE42F37AD1DE22BAB894D93E907F +:10CA40000E4A11D7245CEE4121A743E7A931149087 +:10CA50004622377EE40ABC85720B1D457B99216E08 +:10CA60001CD3EE13F3107011E3279016390BE9B9BC +:10CA7000D06C9F19FD6BE18F8B78BB886B0B7F5A55 +:10CA8000F8316638CB97F9DB91FEA7B8851FDDFB3F +:10CA90004D7C2FFC67B3DF3A781E00218BE76D7861 +:10CAA0009CFE6EEF6A3BBB8F8FF19D78BFD5B3289C +:10CAB00065B83CCCBB5A8DE75F60198161CF13210B +:10CAC000C83270DF89605085ECB8E6483FDEB1B30C +:10CAD000E31BBF1E78119EDB8B9FECDF8275E7CED8 +:10CAE000CB08D7C1783E61E78315FE9D92B7F55616 +:10CAF000D4A389AA957CA4A30B3B68AA8F0AF9B892 +:10CB0000A827B206EB7FA3DFD7FF473DBF0BF0F9A5 +:10CB100068EC30F58ADA1833AFD6042F710D86A38E +:10CB200068EE49B44F1C44B76EAA0F7565390A2FD9 +:10CB3000AA5A657A5E4AD407F0DE92AFBB2EC4FBD8 +:10CB400047367D3972F4639B7EFE619657600D1205 +:10CB5000CCBB553C50AFD72F8374080C55A65BDF78 +:10CB600008D6854C83EE27B34B18BEFF56EBEA3050 +:10CB7000E10BFB0D665CD2F3D32EF1F9452E71FC6F +:10CB800092DA4B1B7E81DA4B1B7EDA253EBFC8252D +:10CB90008E5FB2E8D29E5F60D1A58D5FED129F5F80 +:10CBA000E412C72F597C69C32FB0F8D2869F7689CB +:10CBB000CF2F7269E357A376A0B33C42F05E095FC2 +:10CBC0000751FD3E3059E135FAF3052AA1791A845F +:10CBD000FB25F9DC2FB96F474B3DBA50BB34C54735 +:10CBE000E341E0DF6741FD78C2EA77752EA271D696 +:10CBF000B651E372F09E2A67E7DC93786E6FBCC68D +:10CC0000FC71F3DF0BAB0D18FFEEDAB5E5E986F248 +:10CC1000D45EE3BD15DF6C2C30D42F0F4D34FDDD19 +:10CC2000BC29C6BF47169C61BA7FE156A23F0F9947 +:10CC30004F222AC657F2EFB154E2BE99157DE62B7A +:10CC4000E1FF6E857E17807F7AFF251F3CA1C1FE24 +:10CC5000FD0837C5D0BFD3547FB1E74F9F19CDE34F +:10CC600031A6F3A7042F978C71DEDC9C8749AC3783 +:10CC7000D3F89CC0D7DDDB2CD4E5FD7C07A1F73BC6 +:10CC800056857D167AFF39C7DB444E7A62DDE15660 +:10CC9000E339F47C8D54223E0B3A8805E36BFEDDCC +:10CCA000440D101A17A274B24B8B4D27BB88BB12D0 +:10CCB000EFE3DA1526F4EF6309BAB8DBE6CBC17D02 +:10CCC000B5899D8C1E049DF8904E92312FC87CDF53 +:10CCD00080195F647204E6BA6B477E9A3E1F95EC3A +:10CCE0006570B7C3BFE1F055B8DB882F1FD195BF82 +:10CCF00002BE4E7F4D7C299E6024C583F14CE2C369 +:10CD00003CA9C3A3C659101EFE4E95FAFF35D00CA0 +:10CD1000E1ECEF64F7A8093C89FE76B492C81C9D4B +:10CD2000FFE75723018473B55C5489F9E73B4B69EE +:10CD3000C878087E76127722C6BD77765A12E9DD6A +:10CD4000D407002FC584FCD7B6A5298550DFED2771 +:10CD50008978BF56779B85DE57D6FDAC546FBC4FA4 +:10CD6000399260C9A2EB48B094D3A7953D03FC4922 +:10CD7000ACAC3E226379F4E621F77DC8589F5A6334 +:10CD8000FA7B812420617BEB652C8F332560BCC747 +:10CD9000C6566E940700C6DEAC328CB7707AE7F7E1 +:10CDA000A386AB4918FFCED7655CEE98E928F5AEAF +:10CDB000459498DA467D8BCAB3EE3685C2DFC6E568 +:10CDC00015D9CCE842837F484FA9263A72A9463A42 +:10CDD000B2C979340F57F095988F18BF6D5446A299 +:10CDE00095CECB4AEFC1B699E584697E4E0C06021A +:10CDF000EE9C1E120E43BD4D63FC41E43EFADE364E +:10CE00008D9074FF5798E7D7944F575F16FB7CFCC3 +:10CE1000C5CA2717EFF3EEA96C9D9FABEC3EEBAABA +:10CE20000E46EFAE1D8CDEF12437CBD70A2CCCD6C4 +:10CE3000EDABEEE772CA0C37576FA00AE979AEFC8A +:10CE40006A00F323EE7993D17FDBA8B75FC6F28E39 +:10CE50007B18FCFD2AC333D08B1A81A9DF7397930B +:10CE6000E6054F29057C21FE5F35CA93A9BD4638EA +:10CE70001698E4863F0E5CCDFC1A0FAE7708B89684 +:10CE8000015C0B2E1EAE8AC6E473EA4C76BFE2E16B +:10CE9000510AFBBBBC1A83636A40A5F277AE7C2EB5 +:10CEA0009202EDEE0B80BC8179D60418BCDD33858F +:10CEB0001C37C253C81701FF7C0E7FB7EA7E05FFFF +:10CEC000BE8B53B3129F84F0FDAF00DA115D538522 +:10CED000BC192088B79400A35B01E7AEAB189CF3A4 +:10CEE000031CCE9D1C6E129110CE667A35CBE79452 +:10CEF000AF09E76E01E70C52F655E07C5F12BB3FCD +:10CF0000D93686C1D5E61C88A09CEDF45BE9BA5EF3 +:10CF1000F02BB4BEB398D53F9CB4320BF56DA77718 +:10CF20006B16D2659BFFC62C94EF8E2C2E6748C0E3 +:10CF3000995D163D77502DEFA0F78F6EF529143FC0 +:10CF40002E5F6CF995323364A7E31459894CE1F0F4 +:10CF5000981A0B0EF652C5202F731B8DF04D32C15F +:10CF6000D7F135E5C37F7E4DF9803947D8EEEEB174 +:10CF7000E27E862E3BD54FE5B7D0B879011F6BDB3B +:10CF80008EFBD97BAED774EF6BF2519E38AD2AC2BF +:10CF900033DEBC859DF338BF0FE67E7E9F4B17BF07 +:10CFA000CFE55E7E9FCB0E7E9FCB76BCCF059E9D50 +:10CFB000789FCBE5684F07E853BE278DDE3BF839F5 +:10CFC00026B0FBF1DE9C3324D6FD247ECDA8FF2EB7 +:10CFD000DB64BC9F2CBDC6A8E75203463D87FB5EC1 +:10CFE000FA7A976ABCAF2DA9D0785F9BC367BCAFB4 +:10CFF0006DCF6521D907F0FD7FB1B1C61E0080005D +:10D00000000000001F8B080000000000000BDD7D09 +:10D0100009785445B670DDBEB73B9DA4BBD3095912 +:10D0200081849B950E84D040C0A0416F16302A8326 +:10D030009D088A8A1A013140481075CC3C9D97861C +:10D0400004081830A0A8332E34EBE0B845272A2A6C +:10D05000321D04069FBEA1595474D4BF757C0AC802 +:10D06000480417FC9ECBAB73AA6EF7BD371D088A28 +:10D07000FFE77BF1934ADDDACF56E79C3A55313B27 +:10D08000CB88DF4AF0E747F8C7DB4D3C76CC9A48BF +:10D090003221D9BC6CBCF8B0355840C8B2B6EA38B9 +:10D0A0005200F594402A2D8F85429990A566777F8E +:10D0B0000FFD1EDB366B227110B2B88910FF604283 +:10D0C0005A9BAC982E4CB7B8FD89846C7853744742 +:10D0D000D12616C5A33869FDAEF42584D0EFCB9CCC +:10D0E00084A464D2EFCEF984641122D101049A970A +:10D0F000DA261C2185B4C1D4B9848C09CF67599B29 +:10D10000C9ED2F22242ADEE686F14981F45190965A +:10D1100039E97F3FD2F63FC2CF45E1348AB0725C35 +:10D12000278C236BF204C6D39737BE273CBD5353DD +:10D130003E58B6277E028B3D8F9CF7A34853715A09 +:10D140005C8D8DA6AD09848CED39DE374DE4E99D0B +:10D15000B90850429220AD25004F89F7B934BEDAA4 +:10D160004A6C6138ABDF173B197CA30412B1DF16A0 +:10D17000806B54382F11A274003E061645ACAFA642 +:10D180001403848C26A4ADC9BFEF6373F8BBAD84D0 +:10D19000B6B7F5AC5F298B38EF29B28CED6C929F56 +:10D1A00038693DBB9BB6D7C0C5A69CDDF8F4A7285F +:10D1B00091AED7C1E9863C214880572BCFC70A35AD +:10D1C00053E424C09787229BD62B56484D011B4F12 +:10D1D00051DB09904AE42357185FF0E3A4E50CA45F +:10D1E00090D272ABBE5C4E467861BF52B8BDF2A31E +:10D1F000D0FBBC7FA914F0F851EE69CA2DEE5AE0BD +:10D2000027E3F77F974D2A1CBB1329DC44BEDE08B9 +:10D2100070FC772D1C451B83638B90B93548F9CD85 +:10D22000AC38DC1423A43451EE00BE6C516CC897AA +:10D230002D891D81329A3F5964724357F6DC32E4DE +:10D24000C796FEBB0FCD04B84EDA737823424D0962 +:10D2500054A8F0A5E5765765A042C50709E32B86DB +:10D26000FFBE7CD8E6E0229AF6BB7C1A715252B11E +:10D27000A5588848F1129D5B61ADB185F163815F6E +:10D28000E8F798C4094744CAF7316E0D1EE1FF1F45 +:10D29000591EE141176F19B8E41601882235546F01 +:10D2A0002FCC47923DE1F991738F2F329002298D57 +:10D2B000A6923B15E4654F7AF732BEE7F57AE70BA5 +:10D2C000566FBC3831F5460A97D637A87C04BE7035 +:10D2D00031B960B6327CB61225F546DA55EB40C955 +:10D2E000ED857CE274941F4B52AB5B417E7E95686A +:10D2F00022A200DF1759417EC0EFDA71933C26E28B +:10D30000D7E027656A8C4EEEB7CAD528CF7A9B67DF +:10D310005A8DBEFD805A7DFBF4F909BABCDA2E3A6B +:10D32000F5B20315FDC2F96592C70A726471E26A2B +:10D33000A14643DFF1F93507E5D1E1BC397512B6F5 +:10D340008B4A2F8A382FBF4B3904F5E9FA991CB65E +:10D350002546943FF7F17DE87EBE0F9D699D0FF253 +:10D36000FA7FE4F51F6E72621AC267CE6C1D5E967C +:10D370002651794DFBDB0C5534E33F23D71C07FEC8 +:10D380000BE3D914860F306DC11C13F0ABDA4F4B91 +:10D39000D274C49BBA9EDEE6D7CAE5BF5ACF2A79BB +:10D3A00089BB00F91EE57008EEB21E5F05995C6E40 +:10D3B0006C9CAD1B7767FC84A99994EE961C14496C +:10D3C00014CA11FDFA7AD2AB7E1D4B12D9FA7BA793 +:10D3D0006FC3BAA94408CD0BF309867C7F43FD2CAB +:10D3E00043F91043F94843FE7C43FD3243FE524368 +:10D3F000FD6A43FE1A43FDE986F23986F20586FC92 +:10D40000BFE9EB17313CDFAE7E3B8D7C01BC1AEBF4 +:10D410004B9282F8950CF8353BF5F82D4D2F3D3F9A +:10D4200013F7855A1D7E55FAEC2B7E96521917007C +:10D430007E926A987E523C8768E961496216EE1FC7 +:10D44000622971B3564C4E5978B998C6C6A3FA9A58 +:10D450008E8EBAD267A1FE481E4C6072F30C742106 +:10D4600090047DB9D23F5C9E05FF9E5BBA38331DA8 +:10D47000FBF8BE7BFA79AB7277CB20CFBC4C901710 +:10D480003EAA4F0F0BC3490EE9D37430CA77EB1392 +:10D49000892F8AEE77EBBD26CC7F954A07027DA5C2 +:10D4A00062B64EFF262428403F4639B00AE4144DA8 +:10D4B000EF013945D3BB9B52315DBAC2943613FAA2 +:10D4C0009B6841FDB8DFF0255E09D2B2E27CD8BF8F +:10D4D000EF1EB64531D1BCFD9448FCA3A8BE5078E0 +:10D4E0004D312C2776FCF4D49D30DC77749C31C010 +:10D4F0009D04958C7515C4671E4EC88A1D6997BA20 +:10D5000068BF728EE48E86B202F7422911EB79C1B0 +:10D510006C90A5EE3DD9343F28C784FA85B9B8BBD5 +:10D5200009F47775DE2B2EA5844B2B6656BA4D5E1B +:10D530000A823B07D5DC0B701AD4464C0ACDCB5E71 +:10D540005900B9F666A68CF0DEF02265C86C18A802 +:10D550003B0DF6D9AF575816C13C7BC713114DC5CB +:10D560003F3D55FB413DB33F7E57402ECB129210BD +:10D570005DE57FB52B346F1359FE95CC239E459AFC +:10D58000FCE399479C906F1B9561827564263A1461 +:10D590005F04BADA0FF298AE7BC38A5983B4FBA05A +:10D5A000319527D27E53685AC053A0B5F300FE3C94 +:10D5B00095F9F754967F0DE046FB951B7979224B40 +:10D5C000CFF538C6FE0F643A55BDB43FB71F0B6C9C +:10D5D000C9A7D54FF783BC32EAA754D0F5073A5F05 +:10D5E0004BED4913ED7BED0A0BF1529E5A9B4ED049 +:10D5F0004EF42EB3F836017F4872FF2B357A976FC1 +:10D6000059F23580179F40A66AE5E4FD1CCE2BB386 +:10D6100004AE671DF38A947ED7D26D13C4ED5AE22F +:10D620008C067D24846FEF098FA2C1F78559A5ABC5 +:10D63000BC30AF996CDFCC0AC9B3BC8512ED671D55 +:10D64000F443F3EB5A4D38BFB5DB28FFD2A1BEBA85 +:10D65000EB2313E8CDC388DF04EB1B4A7C98BAC8E0 +:10D660007C1300A583EB191B39FFE651FE467B07AF +:10D67000441F2DF70CAAF91AF8228EC89897BD4EB0 +:10D68000A4A7FA6DF16591F4039265E27626A99557 +:10D69000C6703B87C199648DEE097F33998F70BF47 +:10D6A000DDE53141B96DEB3EFF005AF4DCDB7ABABF +:10D6B00005A8546BE44E0A1F27CEED5144DACFB6CD +:10D6C0008C9A58685F5FFBC5EE64E8DAEBC5F6A399 +:10D6D000B29C58EF1A7FC778E866B83B5806B4305A +:10D6E000ACB26B0790CC50651D9819C4557CCB8E9D +:10D6F0007E32CCA326318BD6CF0B044B817C6CB50C +:10D70000FBFCC9389F0B4D4017D9301F4E1F5548A1 +:10D710005F32D2898A6FA0872A9ABFA68EC1875AA4 +:10D7200083584E24A76EFEEB17533AB1F5A4137B32 +:10D7300016D38F866485EC2B623EBD7D35242B820B +:10D740007DA5C2A5BAD36D067781E709E762B081EE +:10D7500026F9BA7746D3EF8B326A4640BBA2073D23 +:10D76000CD407FB66D012FD453E1642B092802D63A +:10D77000538A00AE6BEF2A2BC37DA19DA0BDD49B25 +:10D780009E6B2E31E9FD38A41DD791DBAED7D3298E +:10D790001DE37EDE838EEF0AD1718CD62FA1EE3F82 +:10D7A000BE36538C0BEC0C6A7F605FBDC891CD7C9C +:10D7B0005F52E95AFD9E4322FB19A686E19D2A9EEF +:10D7C0001EDE5323C1DB01FC918DFC320DCA9DA4EA +:10D7D0001BCB07DDA5E797FAAD5FEC1E40E76F2B8B +:10D7E0009247027ED4F167717AA6743C13E9F8C1BE +:10D7F000EEDDB0AF0DBA8BD1F13CD03592C2F478EA +:10D80000BB4BB919C651E9CCB89E9B787F8B323C93 +:10D81000F3B0DE831DBBA2B19DA701F2B60703FEE4 +:10D82000681286EF200EDFA8DF87F0EC04F9513D87 +:10D83000D1BD0BF6678FCB391ED24972770BA81674 +:10D84000D7D68A3ABDCF885F4A5FBF877514114F1C +:10D85000B9208036DB61C6FDB317BA09EF9B5E5570 +:10D860007EDC7506B9BD2C121EFADAFF890C4F3B1F +:10D87000B44FA8F490D3D96D3DE6D5C77AAADF2C72 +:10D88000ACC7FA747AAC4AF7CB5BABD1DE52F1A0ED +:10D890007E5FDC5A5D9909746E93DC91EC9FD07EBB +:10D8A000C3E9FC514EE7ABB9FED5CEF5AF954D328D +:10D8B000CAF7B62617A6CB9BDCDC1F5A8CE9E226FA +:10D8C00005EB89CB4E94A2FD7E1741BFD6A2D8426C +:10D8D00021125D657AF5FAFEA0463DDEFB55EAEDC4 +:10D8E000EF78ADBE4CFF8F2BCED295DBDD4374E5D8 +:10D8F000B1AE91BA7CB47CBEAEFE964135AF015D4F +:10D900005912CB74F548F00B9D7EABC271BC380D3B +:10D91000F57D0A4F660F707D562D27A48668ED149D +:10D92000759D6D063D7639C011E1CBE0D80E70448F +:10D93000F81673785632BB89DB3D31AADD93BF7A86 +:10D94000EAF444D4A7515E2D4CB7E0FEBC3C93E909 +:10D95000DB3DE82755233F29CF2F5DC6F673551FC2 +:10D96000DF95FE5625E8B5EB534D2827D727EE70F7 +:10D970006DC07C8C9BEDA7DE7617C59FD9C5FDD504 +:10D980009462D3E87AED9C6F969A09FABF9727D9EB +:10D99000DCE007B3BB664DC47A867109B98568EDD2 +:10D9A0003FF271AD4EEF20D26CDD3A43F32FB2B0AF +:10D9B0007E0422403F0905161DFEAC4493CF84F936 +:10D9C0005AC278CC84F5723C19F41CA39F421DCF37 +:10D9D0003951BFDF2CCD67EDBBD23723DE8DF0751B +:10D9E00054E8E97739A78B96A4F5C887C6FAC6FE2E +:10D9F00049498CCEFE5BEE3ABD9F44B5A7D57A600F +:10DA0000473B23D437DAD1E7C25E77E278FAFD2EBE +:10DA100082BDEECED6F893547887F0A0FA17B91DE0 +:10DA2000A6FAADD5FE24C2FAC33CFAB7BD28FF1E44 +:10DA30008875A01D9963B3F84016E6D079001DB72C +:10DA4000FC21D6B788E657C54EEA8EA3F99C8DA275 +:10DA50008CE5360F9EDB74AD99D03F48C77D48A852 +:10DA6000199FADF1C36D8CFF6D2AD307A48F822E51 +:10DA7000607201ED5CEFAA510105F4F17CE2DE4435 +:10DA8000C00A66E52A3D116D5EEC99FF3C9BEDFBFB +:10DA9000A9D792F91D11F0DF9CCDF6D1B01CF7C4C7 +:10DAA000A0BCE6723C87C36B537B758C568E6BBEF5 +:10DAB000C745A2AB7325BF5B407E0F8671F62BB8BE +:10DAC0006F17112EBF9F22BF46F93D27B36621D0A5 +:10DAD0009BD978DE2705517E0F939545501E07F69A +:10DAE0001EE0E5068A9708EB7881E3EDD78A177583 +:10DAF0005FDDD4FE2CC34B818A97952492FDFB2BCE +:10DB0000C04B27C0BDC7BE4A82780EDB3D50790EA0 +:10DB1000F8F11959791ED2107EAE8ACC379FFEC219 +:10DB2000F87994DBADAB397EDAB97F7C25C74F1B22 +:10DB3000DFAF9773FCB4F2FD7A09E027EAECF966EF +:10DB400050A31E3FFD2A630CF8D0E327AE588F1F69 +:10DB5000BB5B8F9F58D710033EF4F889CB91991E79 +:10DB600099AAC7530FBE3983BDE2807E22F83706DB +:10DB7000D6044AE18CABFFD48E2E3374E2692F8534 +:10DB8000545DEFC306BB544DE372983C4C2D8F8C13 +:10DB9000F7EF38DEFF98A5FCB78E8F2F8ECCC7A687 +:10DBA0001C56FF13591172B4747559E4FA565EFF8E +:10DBB000E020252A47D33FFDB94F3C8DBD605C7FF7 +:10DBC000ACA0C4E5E03AE4AD418AFB8D0BD939E461 +:10DBD000C668B903CEF3BD0B6DEE4D32F6E4B182EB +:10DBE0007DC4FB21DE38EC37830F33C8B6E75B38E2 +:10DBF000F7CB9C31B0FFCDB43C7341EAD11A9AE621 +:10DC0000E464239CB26ADD3B00CEA2636A7F767E29 +:10DC10003CCDF9C9504A6AFE7EC28F60703B13FA50 +:10DC2000742E47E520EA817422BE4D944EA324222F +:10DC3000D91360BD0AAECB0C7AAC08EB6DC77C0C77 +:10DC4000E9C0D44602ECFC9ADBA3A37332115E4E0A +:10DC5000E2447B3581B83155F9D89A48A4A491D8CB +:10DC60007F4BD448821BFE0560AFDA06AE5B0E36F2 +:10DC70008D42A130065905E121DCB71BD74F5C442A +:10DC800066FEB6BB9C189FF01A5DDFD0BEAFAFAF8B +:10DC9000F5BE8976149238421AAD2CBD23C6B11E4A +:10DCA000D26FA2337CE0B43A3FBBE63780576F199E +:10DCB00041FDC3FB41ACAF19273BFF3C661FF4B9E4 +:10DCC0009F2BCF513F379CA37E6A813FCED4CFDDBF +:10DCD000F0EB5838C7F4D4C1B82DF16350EF54536A +:10DCE000235CFD2E653EF42B590F647CDC2FACB712 +:10DCF000D9DE13506F6B11FC04FC94DE0F05D4AF1A +:10DD00004801C3934D26AECCE1E17E6CEEF98398D9 +:10DD1000BF8BF97B16BE7FC760D0BF1F889D148C58 +:10DD2000A3ED37ECA37A1EC4D194BBDFADA5F49468 +:10DD3000D4CFE25E4FE9A71FB793A3568CD95B4BB4 +:10DD40007FFD6C30932F5B9AF6385BA840B24BEEA8 +:10DD50004B46D276367E7E4BC48941D01BED632480 +:10DD600019CE38F2457F25CC97349808F0C5437515 +:10DD7000FAF3DC2579F9D89F9A1FC0CF734991D463 +:10DD80001D8AB3A17AFCEA1C1E57E3200ED00BA516 +:10DD90001F94B848710F6AAACEAF2891EE5B71E06C +:10DDA00017A49C42D3A2363F067F94B9FD56D06398 +:10DDB000D7F888D742E1F4D874CF6CE8AFADD81368 +:10DDC0000B7AF99A83D5970DA3F30E04253780E0DB +:10DDD000A5C10938CF8022AE88A5DFB7BE6772C261 +:10DDE000FA36F0F66D1E01F9FFA169C4E7A5F0D877 +:10DDF00050B7C32A82DE1B30915CD473A9C135862B +:10DE0000BB4E64F0D732BEBF6370127EEC0C2C8820 +:10DE100007B8AC8ABD30A0D0FEAB2A99DF79823832 +:10DE20007017F41B68B3207E9278FC9140AA507F53 +:10DE30004E98A6D197E9FF761E0715B88D60DC5382 +:10DE4000DC681BC6013C1764E7460F5532BFB3833D +:10DE5000F871FC09E2B66813FDDE592939819EE2AA +:10DE60000CFAB90DFAA324D7F920EBCF3182F5676C +:10DE700037C44159D57939E9BC28FE44BB8478764A +:10DE800056EAE3A71C867636C3787B01CF20970637 +:10DE9000923CC0F349CF6F471DC052B71C297EA2E8 +:10DEA000AD89042A34F116B65EFC875FE431BAB559 +:10DEB000A4EDB4C2BC4E7ADE4A0477D71BDFEFFE76 +:10DEC000F81E487FF88FCE06BAAEFFFCF6D0C6A784 +:10DED000018E8D77EF473AE476550A4C81CE67572D +:10DEE0009505E1385A61FE0152D4B5D35C84E578DA +:10DEF000AEB5624734960F2826BE680ACF019292CB +:10DF00007613F06B40742F94A113C5963686B0A398 +:10DF10002A9A5F713D251C2A1F92A629229C1F8CDC +:10DF200017DF20768AEF358A20B3F8376117F05370 +:10DF30007A85807658FA414F34D0C3C9C9268C7F80 +:10DF4000595875E525B9B4FF474A25F43754569416 +:10DF50005E0DE5030E327A71DCC6F047E1E4AFA056 +:10DF6000FC907D90F9138A48D0EDA7E503DCC49CB2 +:10DF700008FBC7340A60985F1BC70FF70F1415051D +:10DF8000BC0054BB5B8F47A7018F46BC5A73391E38 +:10DF9000F3493EB3EB98FE58C5EBACA91885F6EBF8 +:10DFA0004332F19A87F7C4D77EAA3F2A54FF0B5019 +:10DFB000FD11D2BF53FD11D24EAA3F426A574A2FDC +:10DFC0002BA2F30D24D17E81FF268E5E04E7038F02 +:10DFD0008CBBF9CE7FD174343F67A3949F5046E148 +:10DFE0005A0D5CCCF2AB15BA671E281275F915896B +:10DFF000927A8EE7853DD59E66E2E73CE5F7427969 +:10E000005BAAC4CFF5583EBB80E8F29D134DBAFC25 +:10E01000053B34FD0F04FC4461BE20F7B9D55E4DCD +:10E02000F9B23C9AA7E57BB93E5735CFE4591F8139 +:10E030007EE7E432BD4AFA8178058AAF2F7308DAA9 +:10E04000E9A24941F94DF224795384F83442A81CDD +:10E05000D4DAD73954AE6AFC23FBF3B85FDD53CA78 +:10E06000FC6C24FCF3DD181E6745E07B5B00F48844 +:10E07000256F5FEFF693DEE5AE39553AAAA5934BCF +:10E08000543AC825B930FE97A4646F29D059FB28AB +:10E0900009E8A188F301E17A1CAA8A947E5E3871AE +:10E0A000FFEB8A0C765AABB32517E37EAEC8D5F8E2 +:10E0B0001B1627CD1A05FB991AF7434885F313BAA7 +:10E0C0002EC17BA509F4B6DEF514897CA2814757E1 +:10E0D000D58438D8076C5C8E1BEB2F6EDAFA168C61 +:10E0E000BFB4A903535BA207858C55F2A2FFC6EF0C +:10E0F000AAA985795907D2728D1CB624D2763A3BEB +:10E100006020D3BB543C3889491BA7BAA66D644C28 +:10E110001405461BDD2F403EAF095447C3386DEE52 +:10E1200091A7F55F9D894F36541C2089148ECFBF6F +:10E130003DE9F5C934DD07FC46F7C1E738DFA41730 +:10E140003FF3CEAD3A7E399C5066D3F2CBE1D54A4F +:10E150008E965F58BE777E29B917CA3B53255D3E20 +:10E160001DF84593DF10E217960FF30BEDBF84CA3D +:10E1700085372D985F9D7B78B557537E67DE613D6F +:10E18000BF8C173DEB23E801815C26EFCF35BFDC68 +:10E19000C7F7913EF3CB3FCE8E5F9ECEE57ACECFD2 +:10E1A000E7971773937E397EF1F4915F3C3DF9E573 +:10E1B000EF3F855FDA9C7E8C076C9B6CAAF445C0B0 +:10E1C0007703978FAADF7B34F753944F53AE1E0625 +:10E1D000FA2C8F5B53E369DAA6B1FD7B61D504DCD1 +:10E1E0002F37EC63FBA5BA3FF3A35DCA4FCC8F3149 +:10E1F0003AC0F6CDA46201DB4F52049F4C7F6DA361 +:10E200002A413FD8AF4B04D22EC352E757E50A61EB +:10E21000BD898E877AD3236E16374B0E327DC74A5F +:10E22000FF037ABABCD8ACDB57538CFA9721AF9E68 +:10E2300063AAE7978F405C0285C7D72ADD18F65B93 +:10E24000150E6B0E96A11EF2D540CB69CFABDAF856 +:10E250007A43FA5491A734923F6C7A1E8B93B8DDBF +:10E26000A54879A3613FBE11F75D753F37EECB9DA1 +:10E270001507F472C65BD84F2767BC85F7EAE40C34 +:10E28000CFF72A6748119687F6659E0FEDCB3C1FA6 +:10E29000DA97793E2467A0FF92F0BE3C6873E1BD37 +:10E2A0005A393307F27DD897AFCBFB65E4CC5FCE0C +:10E2B00056CE9CE5BE5C9277CEE4CC84BC5F50CE5B +:10E2C00054819C893BB39CA9023953A09333D7E670 +:10E2D000FD043963AFEBF2C2F9FD35BDD0BDC8F521 +:10E2E000A5D939CA0CE89F4CEC5BDCB691AEBAAA52 +:10E2F000362F4E067A71333BAFB7F6F6C6BFBCD5A4 +:10E30000A2898BB64B0176BFA2F179FC7E6DDD3E12 +:10E31000F4979D69BED3F308A6C67DB4AB6AB71562 +:10E32000E9D66DC233F19F3A8FB6C98C2FDFDCF48A +:10E3300002EAB70F80DF2FA9A79EABE2B5AFFA8F35 +:10E3400071DC865C19D7611CFF4C744BE9F421A089 +:10E35000D393036F1B0A769E68BF2F16E0F52BD868 +:10E360000F3B7E0A9D0672193EFBB0EE977EC97583 +:10E37000FF0CFEDC0BF33ADB755F97D7E775BFF355 +:10E380004BAEFB67D80B9FFF9475CFC9256ADC0D98 +:10E39000DE9771C22F944F567F9FF721F82F56FFBB +:10E3A00030E4195867FBB7D675E0BF20DFFD283A87 +:10E3B000B5F7A708BB3763E7EDEC1E761FC659A972 +:10E3C000B91F45C2F7A5703DE8DF0895EF8D745F72 +:10E3D000EE974E411FF9C87C9A720BF3DB19BFBF51 +:10E3E0009323B07B6C425534C4C5774DDE81F10672 +:10E3F0006D9347E2B995514F51DB753629E84F6A65 +:10E400006BF260BAB2A932007E93E70F7C20403CE9 +:10E4100058D1813ADCDF568CB97400C6F18D2B8A55 +:10E4200081FC4A839EE2E07ACA90C16FEBF48A8E47 +:10E430003FD5ADF69684FD50F784F417DA4ED6D862 +:10E4400049340FE410B29320AFB393E6A15FA11358 +:10E45000F4175AFFBCC1F356471A678589D482FE68 +:10E46000B2A2CE5419497F793727B25F81E6F1DC39 +:10E470002DDA6EF52DCA047D86D468FD6A67D25FF9 +:10E48000FE34F82CFD0A6769274D1E7C6EF4971048 +:10E49000DF72BD253E5FB91E5CB2E74A4E0CE8A3B1 +:10E4A0009C18D0534EDC3AF827C8897773587CB54E +:10E4B0004A5F1B6437FA93DB2A09FA1FDB028BFAE7 +:10E4C00015D2FC73752622D0FCED6F32BFF09A6234 +:10E4D000E2837BB46B0612CC07DC8C0E2688B6DF99 +:10E4E000801FBCB382DA4F32F8EDAEA802D8AE8AF4 +:10E4F0009D747734A597AA628980DD34412CC1715F +:10E50000020A8B0FADB291DF44815D354E228BCE76 +:10E51000C26F6D170B04CA91943FE578E0DBDEFC17 +:10E52000D146FF3311DF70E33D27831FFA6CFDCF27 +:10E530006B07FF6CFF33F2DF179BEBAA311EFC0C5D +:10E54000F478DD601933C67DCAC8C72A3DF5467F19 +:10E5500036D0934669F2FC1EEEBBFC7CD9067AD21B +:10E56000A8305D74558D898B147FA5A6B18D2FBE03 +:10E57000A5BD8F172B75607FB18DDBF0FB7D10374C +:10E5800000EB93DC284F1F2BA37238C2FCB637CDAB +:10E590003F08F2735B5323A61749DD6202ADFF52B9 +:10E5A00093F720C06D6B532BA6CF37B5637967D334 +:10E5B0008398DED3E4C37445D3164CEF6EEAC0F4FF +:10E5C000B12C364E89E4C77E2E3A45FBD7D0D1B860 +:10E5D0006E3A8E06DF171CF6EACAC7065B75E5E7DA +:10E5E0001D6AD7E547071ED4D57796F874E5B3734F +:10E5F0006A3E01BE74146DD17DB71574E8DAF5D5A5 +:10E600002E38D7F532AC4FC1313989877B1770FF6F +:10E610000AEE0D513E4E69A4E295E61FB5733F47E1 +:10E62000073B274F25A11FA44BBC7245EB77D95957 +:10E630001C64731A6BDFFC3B967F349D9D1FA97190 +:10E640009AA23544D744480E9FE73F6AE7F7947291 +:10E65000585C6446810F3C12240302D4E03CA48839 +:10E660009D93A9E7DECDDCEFF0A8996C15A83ED903 +:10E670002CB1F9372BC4B790D66B2E60F9872A8856 +:10E68000CF04F357A8144FD69C7337EEFE56280CD0 +:10E690009F9793210A9ED788FC9C3D74EE1DFD4FE9 +:10E6A00082E7FA1C5E8B623FC738DAF8C66E01F863 +:10E6B0002BA5B1BB0BE6F7E8EF2D72247BA8EBF797 +:10E6C0005FA701DFACFDDDD769C0EC6B43F133DD43 +:10E6D000D1DAF8990C0E97B58D5918BFB0B6D6A1FE +:10E6E000BB07A729C77886AF6AF9FB044442BB6819 +:10E6F00080330C579F1A3F2242DC1D5D7F76F8FE67 +:10E70000E9CF8DAF59DBB880C5D70C243CBE66126B +:10E71000DA932A1ED6423ABCE7BDDE5F3ABEE68CEB +:10E7200071358638071DFD42DE6BA46F19F112C5E5 +:10E73000E95BB88BC545A419E8468DBB50E9528DFD +:10E74000CF50E335D4F80D0B8FEBA0C3F2B8E6C879 +:10E75000F465D9415C70EF4D34C5B8D7679E398EEA +:10E7600060812B8B6F0EF387B37E59FCC057839566 +:10E770005B5C49E17E07B8945B5DA3C37935DD003E +:10E78000BF8EA55DB88315A0AFE6172BCD709F2F68 +:10E79000A188E03D9DA26201D3FC832CBFD82562F5 +:10E7A000BB7F77317F939ABF5C515E85F671867629 +:10E7B0009787DA99B1DE932EA6E73DE992D8BC7926 +:10E7C0001CF2244EDF4BC78A2C3EBA426072030E05 +:10E7D00054C7F0FD90C2EF72E29C92A3F1BB5EC100 +:10E7E000B1B5B289C5F7A9F1D07F7F53C478685B12 +:10E7F000B1A71CEE9E8D0E04FC70BE5EB491381362 +:10E8000064985F50017E5C987EFF0E888778EE12D8 +:10E8100076667BF941A62F5C517C33BE37E2F84E19 +:10E82000447FACB3C4EEF6C14013CD6CFF57E3A1F7 +:10E830008BF5FA4295415FB8FC0CEF7F24906E2F68 +:10E84000EC935B5C067F2C7F07A437F91D7E078461 +:10E85000C98722DEA7ADD8190DFEEBFC8326BCEEDE +:10E86000296E5444BC1FDBC6E23C9E0B784E7B1FD6 +:10E87000753F876380CB89BFF338C94E2E27DEE50D +:10E8800072E210C8099ABEC5E3240FF23849E37D4D +:10E8900089B6A6CA035A7DC798DA05BF07E3A04622 +:10E8A0004804EFDFF5F2DE87DD4DFBD1C5312E44A4 +:10E8B000FAD9197F7F29EAA31E13EA95F7952869EB +:10E8C00091ECBBFBA6949D36FE7065D3D4032DA7B7 +:10E8D00099A7C3A2B767D4F45B977A3FAE1DEF5BED +:10E8E000A42826027155695619EFFFADEC52CFF7F7 +:10E8F000ADBE68585F9D8DFC5313A7D23E2DE081BD +:10E90000F2154512DECF51FB8D2BA6F3D1FAF92B70 +:10E910003FC278E995E382A9A0CFDC37F693A9B985 +:10E92000102FB24F2440063DE6ED62FE76755D295C +:10E93000D27C21529C7A6FEBFA90B757E3C58DF0E9 +:10E94000EF55EF808880D3DFB7B2E427F58CDFEB9B +:10E95000C33CD16EFD76CBFCC970BFB7AFEF5FC4CF +:10E96000723A4C9B49A2819FCE448F3673379E1BCF +:10E97000DD3333F2B951763EC3F73D25FBD9FB2297 +:10E980000591E7D1935ED97C5648B47FDA6F7B4915 +:10E99000E4FEAFC81754BA7E07E4557BA509F50A13 +:10E9A0003B159F10176F1F47F520F0E328EC9DA241 +:10E9B0002F4BD8F98C515EF418BF84C257636F1B7C +:10E9C000E55071BE4D671F9F1C3839CE1F89AE7848 +:10E9D000AAC25195433DE148F09CA91DE088708A88 +:10E9E000CCD7617C2D540FD16ACE705F6F5224FA60 +:10E9F000E90D0F467A5831D313E70778BDFA2D9108 +:10EA0000C1B955A2E7C7DEE06784D7F5BF30BC8C3B +:10EA1000E517E773FF481FD7D9E77A542F726AF4D6 +:10EA200062B8142DD1FC389EBFC22B041FA2724BBA +:10EA3000D8F637D47BC6F1F40A48E9FEB84DF0FFAA +:10EA4000F31FB4718920A703D2AA5F1A0C1E32B239 +:10EA50004498AFD37F960BEE432FA35FA8BB1FD480 +:10EA60001B4F6A2486641FAEEB6F42B01936AC2B85 +:10EA700089B218D27AD26E8176F59D7F3B04E3D4B9 +:10EA80007746FB45704E6E351FD3FA8D666BEF8F60 +:10EA900064C22B1A1D964C3A9FB95BF4E7A4752407 +:10EAA00080FDCDEBD07F37DE1F11440A18789C2003 +:10EAB00014FF5A82F1BD249A954B439C5CCE75E7B6 +:10EAC00069DF33ABE5F0AAB5DAFCF0BE10F1E9E797 +:10EAD000297139B48BCA31EB48BC0FF3A77CBAEE6D +:10EAE000234EABD744F5E5E4849A7A80C78D44B6CB +:10EAF000B094E90DEABA8893E173866DB205E03B04 +:10EB0000A3D5B80EC502F3B9A9FDF4EB53F1FEFF8E +:10EB1000F209C2BD355FC6745ECCC43D0A14170548 +:10EB200032B4EF4134C0FE00FC35BF9F8E7FDF5012 +:10EB3000E99128625FD6DF13AE39E82753E1DA3B6B +:10EB40009DEAFD642F44B37953F8ED0539A0C28FD7 +:10EB5000483585D0AFBA9E7F8D0E6CF6C3B9AA9D9D +:10EB6000BD03F54142CD9B00EFF443C14F043A751C +:10EB70006293F3609D9F6F3DF29698155E1F21C1D1 +:10EB8000FB213EBA76ABE85C0EEBD9FAEA21A0F79E +:10EB9000DED6A5C6C7527A40B8D1797D14695E9F8A +:10EBA000FD96DC007AC978B140E747798EEF276B94 +:10EBB0000A3C87617E4507063A60BEE6AC8EDDFD05 +:10EBC000E93CBA6F1730AE36512415003F351EE1CF +:10EBD000844D423B3B31D62B3A68BEFB46E25E0F8A +:10EBE000D370CF7703A988E905EEE5946E926F178D +:10EBF0003D204FDEBF6D46FC0C9A26DB67C667D30F +:10EC0000F4A228E28DA6FD250B264F073AA1A6C740 +:10EC10004FA1F3BC2E8ACE93E6337F1BEBCFA6FC2D +:10EC2000F6570BB102BD26C6D6AC1A0FE3C48B381B +:10EC30009FA3544F94A81C2BBDFACB51563A5EFFAC +:10EC4000EF6C23613E698DE5E49F1494FBF3995FBB +:10EC5000F1B327BF1905F7C0C51F6D6EBC67CEE9BC +:10EC60002F319BC1C388EFAD9CAEDE8B61F64E7D2C +:10EC7000926509F8DB3FE7F60F515C682FDCC6EDC3 +:10EC800085F762981DF45E9EEA5FF22769F5DBFA6C +:10EC90006825EE2A301EA89E04F1CE5F3A95B8781A +:10ECA000A8473CC8B7B771BBF973422A81CE6F5BE6 +:10ECB000569E9240DB2735333818E7377808DB9FBC +:10ECC000EB4E5182D6F8CFEA24BF05F486BA53162C +:10ECD000DDF7F7A91EEDD5DC57BFEEF0C1F130BF6F +:10ECE000EB497031D4BFFEB658E6B8E7FCDAC9E7A5 +:10ECF000D11B5CEAE325225178D40BC473BA7A2F76 +:10ED0000FF204684EFA421AC3CA93CF2FAC60F6177 +:10ED10007A5FF9D2890F009DD507CCA8CBDFF662C8 +:10ED200069CAE9F4E7FA5317109FC6FF572F051178 +:10ED30001EF5A72EC4EFE54B8F5980EEA11F997EDB +:10ED4000BF2D5A49017F6D6F70DECAF5A0FA53F1ED +:10ED5000C4DB4FFB9DF177B8FF442CFF3387DB9F6B +:10ED6000F7982A23C5772DE0EB1E92247940EF1AFD +:10ED7000EA27CABA08E3AAF5921322EBC5EABC3A1D +:10ED8000CB82D7C3BCCFAB204AA4F1667238AAF3BA +:10ED9000ED4C08CEF2207D76E7C13B13A1BCB33B1E +:10EDA00043FB8EC4235C1E745E1ACC80FE3FBF24DE +:10EDB000F2BD1D15CF63B8BEFCB7849A4E901FD329 +:10EDC000AEA2194A1F29D3FC26763F85F15B6FF866 +:10EDD0000EC35924BE51A783B305CBD5FE8EECE7F5 +:10EDE000FC48ED708853BF91CBFF1B37CEC5B827C9 +:10EDF000554E1D795044397504F7169AFA04D45FBC +:10EE0000A7D7509D8ACA95599BCA77C37670632A43 +:10EE1000211726B0EF7741DA62D6F9FBD5F1661CEF +:10EE2000F2A09E35B34DBFCFD592B62F403F38B23A +:10EE30009FC903CADF1690C7B3EED3F753BBF1B235 +:10EE40004F617EB506BB3C99EFCF463DEFA121DC7B +:10EE5000BF3F868C391BBBBC9E92C510DC173C2281 +:10EE6000CC63B4A47F674B4DE30A199D2CD874D2B0 +:10EE7000E2907BEFF728952339B4DF63D41E87F443 +:10EE8000C521CA934368BBE3FB185C5E1B52F30CBD +:10EE90008C777C1F5BFF89BA13B3E09D183295E92C +:10EEA0000D5170F980FE1A75ADD5D74CD7BB948A39 +:10EEB000A968B81714C5F411550F13C55B45072D84 +:10EEC0001FFB5F33E3619D898F5F5C09FD253D1E5C +:10EED000AB00DC96972A2340DE2FAFB2B9E1BECA61 +:10EEE0003A4A86C5B4BD95F603FB89EFCF6377C078 +:10EEF00071644EC7AA3278F7C5B9ADCB3F80AEABCF +:10EF0000D5C4DEC968BD90B89B4978BC866D55CF25 +:10EF1000C0BC3226D3FD41807BF4CA08A7A67FC2BD +:10EF2000F5AB7A8E93E3AF0CBEE702B897B04744D7 +:10EF3000F5F1445D16DAF54308A32735FE1EC60633 +:10EF40003D5285DF31BA5F114D9CDA900EC16FA63C +:10EF5000EB9AD7F90CBEC751B7C89F7C2DECB78F81 +:10EF6000496C1FE5F34BFC6B5A99EC08EFBFD70ACD +:10EF70004ED423553DF96AA2FE14A0BF702AE78340 +:10EF8000ABB97E7C6D2C83F374E2CE8076D7588942 +:10EF9000C34461766D79C7E8F9B0EFCE35C7837E9B +:10EFA000036B8984773535EA412A1FD66FB67BC15A +:10EFB000EFFAB9D09D079D1C35333EEB7E25CAB7CD +:10EFC0003E33427F7CFFAACFE37A5D0E51E0FE40E4 +:10EFD000FDF6C1781F2C2A86E27124CA3F2BE0750A +:10EFE00017ECFF74DDB35F8EF6E3BD30F5BD32275D +:10EFF000F1DAE9380DDB53D6839E9198AD8C5840F9 +:10F00000FBFBDC1CCC407941E59B40F7D6D4A14BFF +:10F01000A64894AFEAFB53BD8BE6C73F7EEF148949 +:10F02000D2637D56709689E6E73DFE04CB0F097EDC +:10F0300002F93B1E7F81D51F199C25D2FCEAC777B8 +:10F04000B17238C3A684B5F6F137A680FD7F349E31 +:10F05000E90FC41DBC1EE8A7FEA5C1A6E59AF5DE12 +:10F060003D94C9D1A3D1ACDED14C724335C0DB1580 +:10F07000CCABD69CCB350C0DF96F589C165FA7DA3C +:10F080008EA446EE7F306F37BB9CD5BB2896B44626 +:10F09000B3FB755ED0C7766E1B8C70B10D4DE0F082 +:10F0A000A2FD1485FB51E1A8F6A78E3B07F67590EB +:10F0B000FB662AF73572A66828C31B1DA705C7295A +:10F0C0005046C03B56F5D5034700DE28BE248E2FA0 +:10F0D000C98A8FABAD63F3A3FDC617E23E330AFCCA +:10F0E000CA3BBFA3F533C3F336D287C2C799DDCC81 +:10F0F000EEF777C767231D5D14CBF4455244E14713 +:10F10000E5D9EAA16CFFB97B683C5B5F080F290277 +:10F11000F6DFCCE13790D53FDBF556FF42EBD5E08B +:10F120004901FFCACEADF98827753D84ACD2F5738D +:10F1300074A1A15D31653C98474236B65B1A4DAC6F +:10F14000F89DAC0FB5CBA4ED2E2AEF1E05FC308F39 +:10F15000EBC3C47B21C635D4716931AF356001BFC3 +:10F16000F4BC0EE6272739747D401FD5138BF8FABF +:10F170009C7C7D4EB63E9F8E3EC9C1EE8CC9F69EEC +:10F18000741B827BA8BF8291BC3F1D3F47EA0FF8EA +:10F19000A2377CB40C65FBD439C3873A4F033C4398 +:10F1A0007036CC4F8527F031B62BD0F3933ACF3B56 +:10F1B0007AE3E7CC9F385E296B37EF77148FA0FF97 +:10F1C000C87A7A9ED799699A5E106ED7DAB1D00361 +:10F1D000723E5690991FBCB3CA0BFB5FC3B652F484 +:10F1E00053CD7BE1C9E7BDB4FD9CA7D73820B8EA71 +:10F1F00088D49E0C7A70DDA6C50E781FEEB0E4753B +:10F2000080FC3CE21323FA07FFC1F1A0EA5DF57C24 +:10F21000BF39FAE7BB27013CBEDE64C67B860D5BC7 +:10F22000A2FC51E837998DFA18CD7FC8F24BBF0088 +:10F230003BB661AB5E7F9AF3A735C9E80F23DE01C9 +:10F24000263C04F30F80C3B0FA8D663C4FA93F28DB +:10F25000BAE930A481742F81F919DBC33C4E51BC4B +:10F2600037748837427C9FB19C4A12D4C71A3AEF50 +:10F27000463DADA1F3924F41AF6830C453D4F6A2DE +:10F2800087BD3194EB61FC9D74153EC49784FA4DA3 +:10F29000F3630F147E48E7756CE3EB0EA140BB6F80 +:10F2A0002E423C9DE898B1F625B9F7FDF573D00FD5 +:10F2B000A2B4ED187EE5AD023B18DAC6D23AB3DF50 +:10F2C00001FE81BA756637DD8149DD931B36FF117A +:10F2D000ECCB77A2DC106A3AF7C95D6F9D4FF373F0 +:10F2E0009F31274E64D3B7C139B78A2788D9003DEB +:10F2F00045C5CB9CBFECB2C8C3D877D07B55FCCCFE +:10F300007DA6CB02F7FC8C702CEFE8B2603CAC1110 +:10F310004F1D1F4E0015A4F9B16F2C40DF47B60BEF +:10F32000F8EEBDB17DEDBA5D0EA0438013D8A12AE1 +:10F33000BE42F8EB8137FFA4978AB01EFA43CE8411 +:10F34000BF270047A391CE9F7A09FC28EF46B90159 +:10F350000EB54FDDEA80F57C2ACD67F4FEC8E26485 +:10F36000782FAFD6EC4D7662CABED73E7A3BD2E15B +:10F37000CDFB6E4F66EF482869EC1D4D6F1AACF35C +:10F38000A687A7E03A67911AA4C3DA47987FE32BD0 +:10F3900089543E13815FA614B07DE4D3F551101C4F +:10F3A000443E8573043837D92FE2BDFB1EEF22910E +:10F3B0000598FF8AFB17F20B42EF1F5A41BF6BE023 +:10F3C000B51A362E0D009E8EA62B29E0B7A570F03B +:10F3D00072B809F0EEBBB86F7C0AC31391E13C042C +:10F3E000DB517DBC1CBE43FD8059892ED4B5E3EFB3 +:10F3F000DBB0F155FF069D770C9CA77F9ACCE2F21B +:10F400008CEB6BE1EBA33F01A2A5B3DEF87FE33207 +:10F41000A4AF2F0F32FEA9F755556279C0EC4F818A +:10F42000725FD76401E54394EEFC3C441F1BCD9C06 +:10F43000BFF5E5749E92A085EF7601DFD354E965B0 +:10F44000D67D51BAF3FA30FDE8DF8B52F955B5B3EA +:10F450006EE6F2C0B86EA37CF01418FE8EC2C349EB +:10F460007DF27FD7997D9BFF08FC4CF9D72B033F9A +:10F470009BD13FF0D913AFBE750DA5FBCF3A543EDB +:10F48000D6CB5B231FD73E3B9A44E2E3CF6C6E1290 +:10F49000918FE9F7887C6C63F7A6FF7FC9DB9B7BC4 +:10F4A00091B7FF56A097B75F9182B80B08EC337302 +:10F4B000F1BD57237C55BBD72847130AE4887294C3 +:10F4C000FE1C241A78AA7054E973CEE3F3709C10E2 +:10F4D0001DAB74AAD271884E8DEBD6C3D3587E2152 +:10F4E000CC5D1307615E44ED18D0735F117DEBE9CD +:10F4F000D48ED3B92CA1F03FFE4426C61B2DE67650 +:10F50000C07167B703E2C71673BBA31BFC9271E11E +:10F51000EFDDD14C5F3AEEE976C46BF4A60FB78904 +:10F520000ED0F3823E5219C99F442536CE23487A25 +:10F530002B67E762C7B93FF438F7778E176D198DDF +:10F54000E0076E677FF764E6C2AB1C702E707C5BD1 +:10F55000F63DC07F37BD26B2773DBD8A04711233B8 +:10F560001808C861E2BDBF84AE73C6B6B918DF60C3 +:10F57000F4A3CCB26DC4F385AFC85D981AFD2773B0 +:10F58000C0CF02F4FEB0E1FBB6CB90BEE618E8AB0C +:10F5900006E82BAD277DED56F9750419A1BD7FB6A0 +:10F5A00080CBBDF162C13DA0CF1CA7763EC61288BC +:10F5B000057B61DFFD0AEC7E600C6F12D2EDDC9AF8 +:10F5C000C316FE8E33D2BB4A87467BDF981E7BEE86 +:10F5D000FD3177D22A75CFFFA3F0219A1E7BFE9DC5 +:10F5E000BC9721FFC2DB19FF203DEB976FFF16EDA3 +:10F5F0009BE3DBA3703EC7B7FF2DE34EC8BF148566 +:10F60000E7AFC71745615C9477BBDD07F7F98EA7B5 +:10F6100033BF5DF32BDF1462FC0569617A48818595 +:10F62000A5DBFEFB03889F3EB12D4A063F45C3F68E +:10F6300058B4DB1B5E8AC6B897E3AF7C3346EB67F2 +:10F64000FAB9EBA9E7E7FCC7ED64EAB340CFF1CC28 +:10F65000BE6B7879EC0688979BD7D96581F381F2E8 +:10F66000BF7E5F0872E9F8B34CFFA0F6FCA3F0D2AE +:10F67000E1F70575F79B29BC3F071D91DAE17F187B +:10F68000F6E4956087F7840B83C3710A07581785E2 +:10F690004B2DC8D3DEE09138ECD70A8F2FD0BEA80F +:10F6A000DB761EF251182E82C2BEDB7D5601D7CF0B +:10F6B000BE6FFFA610F4A9CF3A16A25E70A6758F92 +:10F6C000FA3FB76EC1DF977557C3BA937E8DEB666D +:10F6D000F47F88EF57463EE849E72FFC16F34FD9F1 +:10F6E000DD38DF3EF2FF82FF6B787F56C073F9335F +:10F6F000E17DD5FF5ABCBFC6F16E77427CD9F15788 +:10F70000BECF209AF59F69DD1DFF4BD71DD28F44D8 +:10F710008F159EB86F23FE00DC5F5FDC8B9EF2FED0 +:10F7200030D52FC1EC10357E474C9C837A8698B833 +:10F730001CF586C584BD83EC954DFC3D3616F7DD82 +:10F740003AD0ED43BFA8E4A95D47F3E64175EEE585 +:10F75000D883DE3E13932756829FA579219D17ED0E +:10F76000A739C9E46C96E19976933FAA10D30F218B +:10F770005D9A7CE91E1857B2E9DFABB519EC8D989C +:10F780001C8B3EAE98EC70C27975B45B82B7DCA975 +:10F790002AAB7FDFF6E5612CFE2386F8306EF36C32 +:10F7A000E1642FD4DB6B463819E1A3C2AD079CB8E6 +:10F7B0003DAABEC72F252E0F001F4A84DA936C3D49 +:10F7C0006887C2DF9182F31A73DC2CF772769E226F +:10F7D00087DEF18738086E6F86DE99954D6897AAA7 +:10F7E00070D6F487EB37C2F96CE1ABE2259A54236B +:10F7F0009EA307DADC3E3AFFC53283FB620A7778C4 +:10F800005F5C85AF0A37231E8240A34961F88753A6 +:10F810007DBC8EB78CB8E09C65BC5812F482BE5C8F +:10F820001C8BFAF23181F8056ABF1D2B4D2E03BBEC +:10F83000E258BA4582745C375D9366BE179DB28606 +:10F84000FE861EE44B49BC2E7F2C3D0FDB975BD31D +:10F8500074EDF642DC36B5DB8FA5155BF13CD4992F +:10F86000A96B3729D6B11ECAF7421C378E3F01ED6E +:10F870009B8B53F375FD4CFAE8D8C337D2742BB782 +:10F88000ABBBC799D11F7FECB5696500C74BE411CD +:10F89000BAFAFB883309888AAEAF02D677996BAC87 +:10F8A0006EDCBA0F77E4811FE237EE52DDF7CB8BC7 +:10F8B0002FD1F5E3B106FD40DE554A95EE7B5DE3C1 +:10F8C000D744EA47C8058DDF11691455DFFD1DBA1D +:10F8D0007E46EDD9AAABEF0E38CB41651C79C8FD49 +:10F8E0002AA46A3CBBA59FD56BA2E9B00FCB4438D4 +:10F8F000F71CFD714D33B8A12F38465C4007E791E6 +:10F90000183C0FEC2DEEFD1B93AF06D67987E873FC +:10F91000411A33605621ACEB486A9B08C7D20F09E5 +:10F92000355714523E1BFBA5AF19F2177DD7218224 +:10F930003DD9BC45C4FB75E3C589B1FF09F2B843A5 +:10F94000C018FF3A9B09FDF09F257414DEAAA13B65 +:10F95000356EC7C8C7FD4795DE5448E9AD255569E2 +:10F96000EF02795AF6FEF56284FBAEC4A97F97AE2A +:10F97000FF284F2B9CD3AB714931E5220B6EBFD8CA +:10F980008CFE9225267734170AB8EF3A2798D701CC +:10F99000BF7FCFE546CCEB44067F504CBF1A11EE3B +:10F9A000D9917B048C6B51C79B51CCE2ED9714AA83 +:10F9B000EF9B3893AE1B06EDED2C5E007C69D06E9C +:10F9C000A209F594AE719FA2FD1B73B9291DEEE14A +:10F9D000398A95D773687E4C607F3ADA59A418E368 +:10F9E0006D16F0389994B6CC077640FB3D668C3B9B +:10F9F0009E314D399943F32B27B2FB819DC565B1EB +:10FA0000C334F0739C1288AC892BF8BE50C6793889 +:10FA1000A420DE0F739C92B09C044730FB8F8FE3D1 +:10FA20009826BF7DAB661C22297361DECB87BC277D +:10FA3000831C731C22FCEF8804F1EFE4413C123E6E +:10FA400080260553AF8B70EFEEE896D1F16087F713 +:10FA50002B75E33DC17E4F8AA17BB2201657C23F72 +:10FA6000788FB6FAED0A5ABE0564232BF7134ACFF6 +:10FA7000CB2D6A39152D2EFECE2196575F55017874 +:10FA800014F5F5876785EA2BD6D470FFCF1456BFDF +:10FA9000DD52D013AE5DE3A2707F8EA17400FAE553 +:10FAA00082FC8294D3C5E93B4EC59E01AE0E06D7BB +:10FAB000EFE82E901CF6277E2CC819405FF7C2F5A0 +:10FAC000006A37AF8EAFD90A741C23FA87C1F7E9F1 +:10FAD0000E25651CA5B74E8B92F13BF48B4463BC9D +:10FAE00057D52D9F3D0857C41C938EBAA866433A3C +:10FAF00025257624F8A59C5FA31C50E3DAC270A4E8 +:10FB0000F44BC75C690AE7412E38C27055E06DE0DE +:10FB1000E51A385B69BE8AC3F5E45333AF4238CD8A +:10FB2000B4225DDCCA79A8259EB4435CDD49E7E6D2 +:10FB30002B811E4E6E3163F06A2714C2BEE9B2B249 +:10FB4000BFE393184C85BFDB326C9F09FD79EF5101 +:10FB5000FA50803EFC2310EE6A7F274BDE4E80FB7E +:10FB6000122713A50480CF9CA005E1769D44FCF0EC +:10FB70005E6A67E2CCF2525ADE7948C6F20EDECFF8 +:10FB80009051CAFB85B88FF3FBBECAF922BC8FDA4D +:10FB90001BBE8CE7F7E00F3E3FA1773A6829B5E23C +:10FBA0007B430DC50B0B605F58109F87F1570D15F8 +:10FBB00002EEBB0D8D5F22DCD5FEA553229135717F +:10FBC000524F80F73049F36EFC290B96D7359E448F +:10FBD000F94DA793097C738C9F6FB69BC90D553463 +:10FBE000ADFB41BCA1CA86E794ADB07FD4911D9610 +:10FBF000051AF9473ABE08C9FBE11477F74EDC1F36 +:10FC00000372B54A704E8147062EEDF05F05E7F7A7 +:10FC100055D1CE2970DE9FE4FEF355707E5F95EEE0 +:10FC20009C02E7FBB94FC74EC5F234E71AF84BA068 +:10FC3000D5EE5C96CF74BE09F90B8797B1BC9DD108 +:10FC400041CCD31953BDB87FDB102E275A637DA753 +:10FC50007B77E4E6C6977570E9512E0A180785810F +:10FC60001A947EFEB56C007B073727807159E9C373 +:10FC70000535FE8B142784E37513B38902E7A98940 +:10FC80002F44B3775A3F0E6400FC6E7E21DA0F7E5C +:10FC9000C8798FBC6A81FD67BA28E7015F8D1F5D57 +:10FCA000933D3C09FC2501CCDFDCB81DE775E74836 +:10FCB000FEF7AC9CDD05E0AFAAE571CEB58678DF36 +:10FCC00039B69DE87F9BB351EF679B4B821F009F26 +:10FCD000D63D71FA38DF8F4C6C1E1287C7743170B5 +:10FCE000BD85CD6BCC70389F49E8C23863C91948CF +:10FCF000AE41F8D6B9D03E498DC17B344BFABF5BDB +:10FD000018E97D988E26BADF53967BB6692BA6D26A +:10FD10000882EB4991821637EDA79ECBE531818FA2 +:10FD20002CDA78C12B385CE3B6B2F36E631CEC15A9 +:10FD3000C3ED3CBE9D9D2BCFAB7EA304F0A2E2F3AE +:10FD4000A258D281F1AA09C4CDF1E206BCA8F00FF5 +:10FD50009F2FD3769991E842853F61F175314C5ED2 +:10FD6000743F178DFA9471FE757CBEEA3ABCC39954 +:10FD70007DD3DBFCBD30FFA4733F7FEF7059F7DE0E +:10FD8000ADBA0E958F43F6E0C2C87A8A3AEFB3A7B0 +:10FD9000B380A52F74A6CA997A52E3423F2C972BC1 +:10FDA0002A9CD579AAF0EAEC25BE556A7C51B71E8B +:10FDB00029508697E31F19CEEE374A1D9760889524 +:10FDC000D4B80DEB9DED7A5479DBDBBA54396B5C1A +:10FDD0009F2A6FD575AA72575DEF382A48501EC208 +:10FDE0005B0F02D80B353AFDB7146E2868CF7DAC97 +:10FDF000B7E8F2E39DBFD3D5BF3875A1AEFC127949 +:10FE000099AEFC32D72A5DFE37EE3F18F4F875BA8A +:10FE1000F22AE5315D794930500E7AF6DF9B2A31BE +:10FE20007EFBC2C3DDAF42DEDFE4C4FC8EA6544CD1 +:10FE30007736C9C8DFBB9B5C98EE6972E3F7FF6851 +:10FE40002AC6F48D2605D340930753A35C98F497F4 +:10FE5000AB24D0D38B03EDA8FF678DA83906F270D1 +:10FE6000AFC9D76CA7703AEF3DA68F139F713FFEC5 +:10FE7000E6833B615F77B27B4D2D5D630539823E42 +:10FE8000E7A0FB9DA2A117C7C42081F36407891CCA +:10FE900067F9C570768E8BF1799436A75AD93BB63F +:10FEA00053A70A188F3895B0FB0934F5D7D0F2491B +:10FEB00012F1C2FE5F6593F0FC89F0FBC253D834A7 +:10FEC000E13D756F14ECDF89FDF07ED264F848E700 +:10FED0002B2A22C6B14E297E1DE3FFAEB1B1BF93DE +:10FEE00075F59E45FFBA93969316EF6876FF417DB0 +:10FEF00027E45DD3D9E80D5FC09D02380F12DCEC1A +:10FF0000EFA4C44B6EADFEAFA6BB8633FD7F52336C +:10FF1000BF1FB08FA01EA7F2235D5F2BCC5FE58BC8 +:10FF20002AA7E41FEC80FD7E5539D4AF3B28235C23 +:10FF300054BE50F940B5FF543E182F3ED10CF54F3A +:10FF40001C62EF929D77ACE6F05FE838FF03F207A2 +:10FF5000233E0080000000001F8B0800000000000E +:10FF6000000BB53A09705455B6E7F5EB2DA4937420 +:10FF7000428084CD0E110C64EB74D210B6E1911066 +:10FF8000DC101BD42F20420332614D62C02F8EFE45 +:10FF9000EAC63018F8D69F8C5A7EFDA2D53082CCA6 +:10FFA00068151948303343B0418D30E348545090C0 +:10FFB000882D322CDF848E2C223354F9CF39F73D33 +:10FFC000BA5F2761B1BE49A54EEEF2EE3DFBF61ECB +:10FFD0005CF95182BE002BAD00E00028EEAC2B4D49 +:10FFE000C27F0B82F560A439FCF911FF0AF7358155 +:10FFF000312B321EF343FDBBB46FB7CF0B4613C09A +:020000021000EC +:100000002EDF0C8641DF22300E05D8EBABE2F17B10 +:10001000BE553C6EF1F919EEF3D532FCABAF8ED77D +:100020003FF4BDC4E38F7C0186ADBEAD3CFF96D3EB +:100030000ED007E0426B693F6F0E409A3A06EBC460 +:10004000344F0242A38033082117422B9852531198 +:10005000CE909C35C0F37E486118F4E2FAB2B4BF8A +:1000600080B137A3EFB122BD0F80FA93DADB08230A +:1000700001EE0741FF03C57FBB2C25D2C09B251590 +:1000800001CC4AEB05EB258087C09F3B0FE18CF24A +:100090003AD35889D627D94F223F24FF17861FB35A +:1000A0009127F433A12B4444E1A4C6371960896D2C +:1000B0008D19860020978E8790BF0690E0C70C8030 +:1000C000C5103403ADBF6E3A1E8AE2F352800CC8ED +:1000D00044FCDF32F17E6D1EE8F9A873E552198AFF +:1000E00053886F0EE6D37208F17916F95167958D32 +:1000F000EEAB33D339B1F72EB1BD67C64137F7B692 +:10010000F2F3D7BB57935305C03CDABF264DA9DBAA +:1001100083E72EEFD536473674C30FBBB1F3EA79C8 +:10012000C887DAE1F8BC1BF14F9864F5229E65B2EE +:100130000D0C28C770400E58F09C45197589742E17 +:100140002A6622E0FCE26699E50146C5988E722B8C +:1001500057E5D60EC1CF482EE5E3CAA700CA6FD136 +:10016000063D3D4B6C2798EF176157B7F456C0B367 +:10017000DFC9895DE9AD1877FB293AAF42E51BCFAE +:10018000235EABDAA46DEF45ED5BEA4C483D198F79 +:10019000FF8C8251C417A4C31944FD397750765A95 +:1001A000A067FD38EB03D6F74B3ED8F61EEAFFD921 +:1001B0002B38D11FEDD159F2927FDCCF273763A1C5 +:1001C00067B593EC09F584EC4893E35AD42140BC1D +:1001D000D79658037EE467D86D37D2FD61295093D6 +:1001E0004872B90CCED5C8EF89BB3E384C7632D1B7 +:1001F0006A0B12DF9088F668B94E6817D3E34F0494 +:100200006A1270FFD836BF4C663BFAA0B7C686E3C9 +:10021000511F2A2869F433EF796492FB765F13F358 +:10022000A1DE57CF30623FB7B29D413ACE65DEB80E +:100230009DC1235603F9B5152A4E35C9506740872D +:1002400075DE36594E403ACE07C149F305071D35D4 +:100250008457619B2227225EEE13DE1AC27B2D8A11 +:100260004141C18D6AF7CB49386F3142D0827EC49B +:10027000926600258AAFA32F046AC80F6A7EEDED4F +:1002800038C1C70957EA65F25B76B377EB46E427D6 +:10029000FC39CEB9D9D115EF1D4E03EBFFB114CF08 +:1002A0000E9687CD31CC934BFAD3BEE515D29F86FF +:1002B00078A7059F83183FADF945ED1C8D6F1A1F78 +:1002C0002BEDE751C6A807ABCEB3DF8BBDB7D2008D +:1002D000DE7AE4BBABD451588DE7B4AF86B9D370A6 +:1002E0005C674298D375FFBBAE9216C2AF4C1ED767 +:1002F000AA105E76C335F5BA72D5777C7F8FEBEAAC +:10030000FD95CD6EFB7C5B64DE5820093F0F46FBFC +:10031000496B449E372AF7F19D3374716BC20F5EAF +:100320005DDC9A889E367ABDD4FAA86E5C667F4200 +:10033000B7FFF6B4D5BAF53B1DEB74EB7767FD5606 +:1003400037BEC7F9B26EFFBDC51B75EBD394DFEBAB +:10035000D6A7CAA0486873B952C044763613EA19C2 +:10036000CE86568673A093A1173589E07C70327CC7 +:10037000043C0CE7B8BCFF22B9844D9D7DC9EE3B1F +:1003800076FE2B87F4A2E31763ED198E485CD6E264 +:10039000F4CDC6E35E66945337FA905860603969CD +:1003A000FEBE47F9C4F8FB7001FA13C473BDA17314 +:1003B000CE5F508FFCBB2DF6CD51FE0435D240F1FF +:1003C00058B3DB9EFC4B99115301B4C7AD06E781CE +:1003D0001574CE47BDA13BFBD2E0D41F90D1A88FAE +:1003E00049B343C621A86F1753144701E2EF7F6654 +:1003F0005CF2C96CD5BFDC8272F8DAC0FE0F164B16 +:1004000081A14857538318E72E4C0E489C07045986 +:100410001E0F43C84474CC05607F3B0F1C0C178033 +:10042000C272C193E3F3D0CF2C6C30BAD6235EF9FD +:10043000299D43C8CE72471F4991F0FE3C742FA4FA +:10044000FFF906A8A53C45C3734181F0074F162864 +:1004500045056E7AAE75FDF3787F67A30136E13905 +:10046000A7463FF14B888AAB2FBB4A46D3BE6D12DD +:1004700028141FFDCD96C0E60CBABFB32FF9756DD9 +:10048000DF1C57E904DA37B900F87CA87F0788CF6A +:10049000D3EC82A730A90FF3009F1B4CFEA7AB9DA6 +:1004A000F959DEF9141FFA839828E67B79FC60C1BC +:1004B000E6196B72981E3FE5632FBBBC1EC6DF8C2E +:1004C0002E8DF07FD512D8C47953D56009F12C7FD9 +:1004D000CD62A0387E04FD2CDC0670D46765F8A5DB +:1004E000CFCEF02B5F1AC3AF7D0E86DFF8B2182E89 +:1004F000FC010940391E2E50E692FC7AA2A3677FC8 +:1005000021E8084B30A3DED6757D86AAD7790D2762 +:100510009E8E273D68929D431185DC465438C4FB6E +:10052000ECAE510139239AAFDE6584475ED3A7CF85 +:100530008D2DA2E78C7609F79F6D3ADF97EC301688 +:10054000BFABFC68360B7EA8F86E4B6E5D4FCF6F6D +:100550006B1C4218A23F00A187244FA93B3A56B317 +:100560001CF30B44BCB9D7D25964B745E8034A150C +:10057000305E54ABF1A24CBE9218427CA6D1B9A316 +:1005800049AF6F3D40F7F9F7C93094F513E67AA209 +:10059000ECFC75950F1ACC6D367B0278FEB6E6CF73 +:1005A000A6DF8D7C983AE64EB71C656F2F10136856 +:1005B000DFE8CBFFF37C2AEFB7D355336163991D96 +:1005C000F73D64DDF33EB1E061FBD765C9389E9B22 +:1005D00026B5109CE7C8989CE22074034CCF82ACEF +:1005E000892DA462539CD3CC94174C24A38AF29FE8 +:1005F000A5564CB274FEBAB76E7C7BDA00DDFE3BCA +:100600001D99BAF5BBB3B275EBDABD539C85BA7DC3 +:1006100064AF9437231D2C77D82C07864AA407177C +:10062000BE58CAF4CF2C22FAC3C83F332600A78B8A +:10063000D7BDF83CB98DC6BD89649FB1F9E9B2E672 +:10064000DFB5288E9EF3D30AF02405A59EF3D29E33 +:10065000F2BA1BCD4FD18F3C477E247FE7FDF61ABF +:10066000C463DBE8CBFD1D48DFDE02CC5BC9FFC500 +:10067000E4AD61356F8DD5A3ABFA2A3984FEEC97D2 +:10068000D9EF6AF96BAC1E013C2DFC8D0A6FD6DEEA +:10069000A77E22E2CF3FC8EE7B47EBB70A0305BA3D +:1006A00078916FC67880F2E9FCBB0C9B68E20AE2A5 +:1006B000A1C92133A2FFF0C8C6F7D38B78DE4FF96A +:1006C0006905C5073CFF0AE51F84EFB23DEFA7A708 +:1006D00046D661E5D7BAFDF094D4A21BAFC9D08F3E +:1006E0009F9DD812FD7C4FFEA87CC3A3662FFAE91C +:1006F000F2172425D08D3FD2F029DB1BA790DF34E1 +:10070000EEB2705D54615740B151F68371A49BF80D +:10071000ACF98799325475E7E72C2E91674DD91BB8 +:1007200007F24F38F708EA0AE1E37F5BC49B2349ED +:100730000A78A2EE497109BC3B92EBFEE37BDCD761 +:10074000F1277012EB3B9285DFCD6B38653050FCA2 +:10075000EB25F425CF1E32A4200C2F8AF703DA53A1 +:10076000E5E204BF211FD787747E6645D1F7DF9E7F +:10077000FCB215E5F685C1A08B3F61F27938CE74E5 +:1007800025CF5C83FFDFBD372E68F809F46462CCA7 +:10079000627F5A22EC7E0EE98DB84701743995BF0D +:1007A00006ED5E85FC04D14FE3D9DB538FBC407965 +:1007B000EC7EE10770D9165B973E145597C206612F +:1007C000BF56FCA53CA60202936D54FF07D1FEE183 +:1007D000E7B3FF092E5BC4CE6FEB6AD79ADD571ED5 +:1007E00012767F6ED7C54FC8CF9FC3F8176DF71A23 +:1007F000DF347BAF7C4966BBD4E6CFEE92EF087462 +:10080000C3E7E1AABE81E2647BADB68B7BABC75F79 +:100810009A4E71AEBA19252475BD478395B5323805 +:10082000A2EED9B6DBB228608BD011D6E26BF3C54D +:1008300094893902AEA6F80B75AAFF11790DC65539 +:10084000532AC5D5699273338243CDFD4A887F8789 +:1008500024083A5C7CC4FD56C4EF3E711CCDDB28F5 +:100860003F83B42C23DD335D95EB7D6A9FE881E601 +:10087000078692BFFFAC61FE21059756B83299CE2C +:1008800007C1CFF9E1A164CFA01588E7D41AA1E789 +:1008900087923BDBA9AF74687CBC5423F1F96BA24F +:1008A000F3BF4326CFA02AA64BED2F2923E41FE355 +:1008B0006FA2EE55FD22CAD32F893A8DEDC098FE66 +:1008C0002CF70B1643A045C17B2B9C41CE5397823E +:1008D000A8EF63F3F48A71DF9A293EC4D695139B7F +:1008E000F61C96F2BAE947C4E8EDF5FA0FB1F56CDB +:1008F0004F79FEC514CF8BAEA83E606CBE7E352FFF +:10090000D5F2AACDF1814D88CFBBE3FFFBEC521CA1 +:10091000AFDC1C6FA7FAF9CC6B163FF9E7339B2CC1 +:100920000109D7CFA474B651DD70667BAE134F803A +:100930007283E3CDB728CEFFC1C47A01E014F6710B +:10094000554F1F3F46FEAE7A738204945F7BC5BA53 +:1009500056CBC96F24709EB078477AC02245E20C0E +:10096000D98703538BD3AFC62994F49FD9775F12ED +:10097000F5A1DA0D7F1CCC7D2DF9A9634FE0734BF7 +:10098000B724B8289F801C60B92DDA347C23E5C7D2 +:100990002F9ABC4D447FE91BF7F4CBA0F33FED0346 +:1009A000444F78D78EBE941F45F2F6EEF3BD73BB6D +:1009B00032932027C227AD2F58FBFA6A0FC93D5E3C +:1009C00072F0BC11AA9401A4174DD380CE75C992C0 +:1009D0004276D9B92E9EF3D458BD3BE01275CA3287 +:1009E000AD8FD01BAC69643F5E603E84D7656F5AA3 +:1009F0008F7C3AE54A51E375E7B0E9B9D1FAD956A7 +:100A000041F5DFB90D16EE6FB4C7E9F3060D1E759B +:100A100025F3FE72EB055D3FA162D565FD38071435 +:100A2000F23BAE1A47E1A30857A8FCEF18E139E6FC +:100A3000423C97D4FF76E787CC970DFFFE05DDBBE0 +:100A4000CF26FA2A1F0AFEC5D603E556D1BF00D825 +:100A5000C8F76BF3A75EFD3C8FF4F05463F6309259 +:100A6000E37CB9F5E42B48E7D984D6634F22DCBE9A +:100A7000EF13964B2CBEB17D987649627A97111D83 +:100A8000385FE6F65C2039A320B88E9BBF3E97F90D +:100A90005726E724911CC367BAAF57343CB5F335EA +:100AA000FCB4F3B57D52A190578BDAE7EB30B79EDB +:100AB00025F976ECCC96A8CF77753EA5352F394A27 +:100AC0005F7EAEFEFA2CB5CF71D8B0FA3133EA634F +:100AD0007BFDF3266FB4DFBBC9BEFAD57C5001871E +:100AE000BDAF08251CB79038238EC76B6332061C38 +:100AF0008F53D193081FB4CBF12A8425DE34EE9BAB +:100B0000D37908E320C0E39A894E07C1099287FB95 +:100B1000175ADD3019AA06121D066B88FB7D6BA8DB +:100B2000CF8879CB03C96BEFC9C0FBD6F481B594EC +:100B3000CFAC3109BBF0CF8BE77A4EE3931667C099 +:100B40009EA38B2F6BECE030E239338C506B4A1153 +:100B5000FB6E413E1FDA37FF7DEA9F7E6EACEA43B3 +:100B6000F71EB1BD902B1928CF0B2450CDF8C52707 +:100B70007F70FF1DF71E05653CE515F77F6065BFBB +:100B80001FDB9F58085E1E9743C874019FFB6AF4E1 +:100B90003F37EF85085D5F8DF9BE91EA8487929FAC +:100BA00076D3F3FE12C8A2B874292E318FE85965A6 +:100BB00015F0F15E899B089EB1DBFCD45FBD143754 +:100BC0003840F1F415C97B6F611F7E8EEB58FFB181 +:100BD000F800C5BBC7656F05F79393CD20E1FE70A4 +:100BE0001F952F1DC07C099BD4FDDF39785C54EA2A +:100BF000E27E235C72B05F1E1B13778AB20DA23EA9 +:100C0000FB51EC1FDF69D4C59DA27CB59FF32F0774 +:100C1000E7A9137E305E332E75148A7AB7A8B7A180 +:100C2000AABB7C718DBA5E034159F47944BE30F69B +:100C3000AA7E2932C9B1421D57505C43BD0A275ACA +:100C4000FD32D23B7697D0B3B1C6E01E82E8656133 +:100C500015E5174D18F7343CD0AF405A36EBC318A2 +:100C60004D4FF1ACD9B86FAD54C5758C95F21A845F +:100C7000EBA556C6E317D0C95051E3790938194E90 +:100C8000020F43D4538677401DC3BBA09EE1146876 +:100C900015F17F44B086E31A3C65E7F71877961B99 +:100CA00028EF287AB0FBFA61CB75F9808637F2E637 +:100CB000F93019D0FE32BBE1C7C02CF623B1FC8855 +:100CC000B5D3F11092D94EC9416452FFC0C1F65A52 +:100CD0000A0A8FCB6E900FC521AF91FB37B1FC286C +:100CE000ED5E2FB6A9FC5840BAD62722A713850E71 +:100CF0001E6BF242FB4AA33C34568EDA7C517CC90F +:100D00007907BAE2BF157E39D388F1ABA8B0644544 +:100D1000268EBFDCD121C6634B760CC1F15785E12D +:100D200099C674D2EF92429313AB18A973E6241CB0 +:100D30007BC93EF309A21D923FF38AFA78A59AC7B0 +:100D400078573FE6B4A3BD7807D99C44A71593FD17 +:100D500038E4A39C29DE1F0EBE23B8D784FBBE3225 +:100D6000795BC87E975B83890EE4FFCAD565FDC8B1 +:100D7000753E6316FB2D16D17FD5E8C3797F1C8E97 +:100D8000B76FCF5E210DB93E1E78FE413ADFBB7AC8 +:100D9000A89FECD7DB283985644BFACD401EB6B747 +:100DA0009A80FAA6DA7D4F8DF01EA1FDE070B2FFA9 +:100DB0001EA0E639EDDBB3B3494E270AD5F7C3A928 +:100DC0001985C4C7A3233C27687F3841E8DB098A1B +:100DD000E5EE9EA1AD48395ED8CD7CF81F88003E77 +:100DE0007FB1D07B9AD62BE3AF70DC3F5BF0E9DAC2 +:100DF0005046446F2514DA6CA4BF46818099E3C342 +:100E000038FBD53C95FCDD423C07F951E4F1D69026 +:100E10008B1B35BB7324F9553CF73C9F6B0E0D2E95 +:100E2000C0E75EB8EF9859E8DD40A177AA5F6ADEB7 +:100E3000BDFFC90162E881283BABDC7DF9FBA3C89B +:100E4000BFCA7336276D8FD8D7CB2BB8DE049BCEA5 +:100E50008F687637A6C9C2F9F6D85DC317D2BEF13E +:100E60009FB665125D13DA42FC3E2CDCFCF9008172 +:100E70008756875C927E4A3C3EA5C6895356111719 +:100E8000E8FD2ED77B8DE2FD6EB5DAE7AC6E9602FB +:100E90007EF63FA27E5EA4D2B77C7F630BF54F1631 +:100EA0006D583085F52820EA0A07FE925F5872587F +:100EB000D4CD4BB7EAEB8D4AAA9B693F04CDA40F72 +:100EC000CBEB63D6379472DD5C19EDFFBBA99B8732 +:100ED00015A9FDB1413088E992672779BBF187B147 +:100EE00075710528B9459CF77A64BADF6DECBEFFD1 +:100EF000909427E9FAB5E5EADDC4271BF3C5CCF5E4 +:100F000044F5AB2B9C761AAB76BB1175A798F2ED26 +:100F1000DA03DC5FD69ED3EC7871ADC475076CE85C +:100F2000CD3A98BFC5A210BDF95BFA711D82F512CA +:100F3000E7871BB7586A695CF3EB5E7E399FFAD08E +:100F40009DFDA90F531387F9A6E8E783E4E23E0C61 +:100F5000F745E617A97E5FCD032058A0ABE76BD419 +:100F6000F85F9D30AC1F56CE917DFBD275F5498D53 +:100F70009A6F17119E94376EED2FD6E3041D7B3EBA +:100F8000FEB778CA7B1B8D9E78EA6B9F3B3884EB5B +:100F9000989EF8EEC63004D778DFE8FE7C4AE6B5C6 +:100FA000E456F49251F04BD5DB3FFB14F8C6149194 +:100FB0008B465F99FC56A999FA228F809DFA24D519 +:100FC000FB7F5763A5BA701D7007E21C087D3E7752 +:100FD000DAC0EFCF4742D66FC6E1D87DDAE80CE041 +:100FE000F30DAA5FA4F7C88E283DB3A8FDDF3847EC +:100FF0002F7044D5D1F15929BA7182B3BFEEB9A48B +:10100000E221BA75E4F7263A1FFC4A6BCEC848DEE7 +:101010009BAC8CD03DF74CE2E47D6CF7ADBFE4BEF9 +:1010200054EF3B5C7A7CE45D32F903B820F2A562B0 +:10103000FC257B1B05FE1A92C798767D1E551CAABF +:10104000E3BA31EEA051D707B05CA72FF59C665FDD +:101050000361A0F01BB1FCD67F4751BD5FE67CAFBA +:101060007A1026AA19DDF1FB561DBF357BD4F8DEB8 +:10107000C7A3E77BBF197A7EA77BF5FC1EB048CFDC +:10108000EF41557A7EDFB24ACFD70CBF9E8F99B51C +:101090006374FB87D695E8C6B7BD74976EFFF0C042 +:1010A00074DD387BEB2CDDFEDCFAF9BAF5FCA62505 +:1010B0003724FF8260B56E5FACFC0BF7FDEA9AF255 +:1010C000F7E3AF903FB03C8A511E41C7FF9F1E7CA3 +:1010D0001AAB0737E867DF249B15DF2584FCA407DC +:1010E000C5F1AC2753E385DFF968DFB9830A8E0FBA +:1010F000380A4D699467A9F98347F5435A3D135B54 +:1011000037DE5B2CC5BCB78FD3BDB7BFDEF771EE42 +:10111000D6A06E5C7010F8FB17D761E7BB04DD2723 +:10112000146E778D3C5DF52EC1D117386C77A957B9 +:10113000B5EFEC62EB2D701E64BF3F5B7B2F434627 +:1011400031B26B7F52ABC7B43A37B6FED5EADEAEEA +:10115000759AC863BAD61BCE3423E7D15ECEAB3FB7 +:1011600090BCDCE77C65B8D7E67653118075B28118 +:10117000EAE4508D60A602F41E3A4CFF7312F2ECC2 +:101180002CEAC7879381FBE7CAEADA597E1BA36F73 +:101190000F8D14ED23FAB9D5EDEDEB46B91E97ECA2 +:1011A0006B0BF1D98FC67C3B98F29174B7F85ECC8B +:1011B0002223A7302EF59BAD00CD5F4C51FAD3FD15 +:1011C0005ABFA427BD89FDCEA8C1176468B43BF9F6 +:1011D0003BA4D8FE62C8E0E0FCD4FF2B89BFDFF956 +:1011E00096901B1DC963CED59A388F01B59E7F5846 +:1011F000E5BFD6F798ADD2731C8F588471F9E1A67C +:101200000F582E4BD3DAD57E4915E7E30B06DA5C8F +:10121000FC5D9B52E8147D32AD0F3240BE99BCEBB1 +:101220007AF42F4D3BA3EB43C15BBD6FE87D79841E +:101230006E71FEF175A29F797CDD20EE9F47CE3F57 +:10124000CBFDA887AB3ED6D9C7DC554774F630CF67 +:10125000FFB56E3D94DA69A2FE636867FAE4879091 +:101260007F1D8D9691240FD48307DD51FDB7D0BA31 +:10127000EC4974EFF5E9FC96F168F3B5B27C353AC8 +:101280008FF90EF338E40BC57C6726E8D4FA1C1AF4 +:1012900034EF852C23BD4F947A39A9AFDC53FF433B +:1012A000B3B3F3EE21AC9F970C8E93A24F54358AC3 +:1012B000F2BFB6897D4B08EFB64166A380C3C43840 +:1012C000BDD82AC693EF201836D96AA92FD226890D +:1012D000EF82664BCA6BF3F0DEC7867B57917E5771 +:1012E0002EE9CC23FBABCC0FCD91F0FCB37DBC4FF2 +:1012F000127F242C2FD253980EFE7EECB4C19F2770 +:10130000A1A9BCDD787416D58DA77BF9CF5286B222 +:10131000CDFDF92CAA1B4F9B853DBED3189CE5A79C +:10132000FA090F233AFD7F92447FCA16324FC373E6 +:1013300092FA789FA1F3E9BB307ABF47F3A49F5A92 +:10134000BF346C12796258CD17FFCB2DF2D9DFB8BC +:10135000C5FB3F0DFE9EDEC1E0DF3B04D95F3F3B96 +:101360008CFAE9E7365880F25BBC5F311445BE5F0A +:10137000E98BB4501EFBBE59D499AE772C41F25381 +:101380005A5F75933B83CF49CD14FDD2D4FF44BF40 +:101390004576186A1D3C2D210ADF83C07DEC0EEADC +:1013A0004747F5B137B9453F141E117EAF63DD00E5 +:1013B000EEB72FDF7FFC18F9AF32B7770BD13DDFE7 +:1013C000E018497E6F79E21EEE9B35B91D7C2FE255 +:1013D000CBF4A21F5A43725A6E0D719FED7A7DF5C0 +:1013E0009EE8EF58D8FA620EF7911D79A437DABD5E +:1013F0008847933BAAFFADE11139E7DA76A0F5877C +:10140000B5F1A9579F19A6F6F7E77ABA89AF07DCB5 +:1014100022BF6F3375DF8FFF5F559E5DE4731B0046 +:10142000F5FF2DBD30F6236C233ED1FBDF99480F2D +:10143000F737940292EFF2E93627F1593B1FCFF1CB +:10144000FEF11AF7748CF07C467ABFA44AF4EFB52B +:10145000F5B024E4EA5F27FAA9CB771F39F624DE3A +:10146000B2F88DDC428A07DAF3B17C46FE0EE3EF78 +:10147000E864F1FE0BF9FB0D9D1FDBB7FFA97C0DA6 +:101480000F12EF69C31B2F0F76E0F3CBE9BBB63C1D +:10149000D20FD1FF82067D5F0BF9E5A7FE46D7F795 +:1014A0005AC0EFC72C6A3CB168CF0F34EA9E7F3335 +:1014B000C1F34FC27FA7EA37707FC080F737A8FE1D +:1014C000A941ADBB63FB2F0DADA26FDA9066E63C80 +:1014D0009AF21F5AD7F29F951F8BBEE9CA0C9167EB +:1014E000139E2467E9700BE70B57FBE212C67BE4FF +:1014F0006382D99B309274D2BB82E3997C0BCA99E8 +:10150000DE87FCF52EB58F20E2A35B8D876E3A87D0 +:10151000F0CA49E23859A4DE8BF505F7EF46835748 +:10152000CD1FD4FEDBBA16EE3FFC1F5946A94AB0C8 +:1015300030000000000000001F8B080000000000C9 +:10154000000BFB51CFC0F0030947B3A3F20FA3F187 +:10155000E7B0A1F233B9D0D4B3A0F283D0F4A3E3BF +:10156000762606064626FC6AF061116606061920F4 +:101570005601621D66F2CD0161235106866209069D +:10158000062E20FD5F9C81C10BC82E01625F20BF2B +:101590001D886700B11450FC029096156360782E88 +:1015A0000AD1670D647F1323CF4E4B5ECADC3C8AA1 +:1015B00029C3E6B2A87C013506064F750686891A4E +:1015C00010BE1E92FC0AA098A01A847D481E98DEC8 +:1015D000807C5559ECE61E06CAEB02E5776AE0B757 +:1015E0007FBB0E2ADFC10C959F8B26DFE882CAD70E +:1015F0007043E5EBB84368003560D6A4D80300001B +:1016000000000000000000001F8B08000000000028 +:10161000000BCD7D0B7C54D599F8B98F99B93399CE +:1016200099DC241398BCE02604881A6012121E8AE2 +:10163000781302461BC304D1E22EDB1D686B23CF57 +:1016400001ADC6C736139290204482765D162D1DDB +:101650007C15156B4AB14BBB6A27402B55B70E164C +:101660001FDDDA6E60FDB76A955F50A9F868F99FD3 +:10167000EF3BE74EEEBD998447BBFBDBF8B839F78B +:101680009EC777BEF3BDCF774E9CA484A8E30939EB +:10169000033F5710F21AA13FB9434F427A09A98676 +:1016A000E7801C9E02CF187FCF9E81A57D02ED02B0 +:1016B0008A4932839022C27E8A5A36AE13A71232EA +:1016C00096847E31B99896079635103F2DBF75D513 +:1016D000BBF0DCB8B8B67EBE4648DE92BE2357D219 +:1016E00067201C1722E584DC474442F2A1BFD25890 +:1016F0008D97900EE8EC5242C6C4F2F45839147437 +:101700005A20E49B0A1F88889A4CCB3EFC75681EC1 +:10171000C693102749946145E18C6B787B7B7DE310 +:10172000E98376469D62F8FF7A02F33B5B3B720BDE +:101730001B2F46FF3943F15230343EF693D76C2AC3 +:1017400013C08FF5BB9EC2FBBAFF95F1F249A55BB2 +:10175000ABA2F36D10D538D4277D59322D0756C969 +:101760002421D0EF55BD82433BFBBA6C24A4BECFED +:101770008BF8159A7C43F05D47049CCFB83BDEDEC6 +:10178000D51520E4D4526F08E9432524277BF87C43 +:10179000FEB9959084CB545E5C2B4470BCD02F4A2C +:1017A00069FBD86231F428C0D3B0280BDE1BF56E7C +:1017B000E3E30CA70FA2C9148F32A70FB941D4DD00 +:1017C00053FF7AFA902F903E726F31B523E7BF5ED8 +:1017D00088F7EA73A78FBF763C635D87F3551BC21A +:1017E00031EE8E5237A1EB7F6FFDA2CC489A7A235F +:1017F000AF6B25F27BA081E8F134ED36C17AE23C93 +:10180000631679834FBA3E526A796FB6AC973476D5 +:10181000C6925DA3E0430A58E76BF4EB6C91B4B752 +:101820007368515645E84FE6FD6D5497C708D02DB3 +:10183000D036C587D45B9120943F4890841EE51034 +:1018400088B4EC54F5F8DD0294E2B82E067C4AA97F +:101850006819CF51E8B1AC07591213CCF03B5B9C2F +:1018600008870C6CC2E55D18851B831B8638330125 +:10187000CA775AD65FF692849BCAD54DA595C4BC4B +:101880000E069D0A8241A7779E9B5CB18FB7D80A4E +:10189000E739B7F3CADAEF8D3625A3B593C9EF0D53 +:1018A0003C51E4FD0A7E31AD7B9783EC17A611D243 +:1018B0005EB831066FBBE07FB3913E416891AEC226 +:1018C0004A15E889EC166480D36D9047301BEBED28 +:1018D000221AD2534CB895403DC91B463C19DF47EC +:1018E000868BD35D4CEF2FA5FD5EC3BBBD86EB336E +:1018F00052E5787BC080BB04E73154A6F3F8E0766C +:10190000FA3F4A1FB10A21FEA830FC7B03E8432AB4 +:101910008F1AE0BD499EB804AB3C6BE0DF0E3EF38E +:10192000C6A4E9941E93218980B8DAF08C4BAFA34A +:10193000FD1FB95C88BB040E2FADDFC8E17C59CF19 +:101940002902FA4CD6B9907E1BAFFC2400E47B62DE +:10195000FFAFE474FCDA38C7310407FD6FAD797E60 +:10196000F4BF313006F2651DD29101D7EA4A09E190 +:1019700048CE11E230CEA1DFFEE19ECB289C2F574E +:1019800009219786F0FA081D2FA97F14184D4E10D3 +:10199000637C8DA8804FFBF8A9F550424B802F9BAC +:1019A00055A776371D6FA5143A0C7A8C8C65FAA171 +:1019B000599D5407EB23098C3EE60979D8AEDDBB6F +:1019C000610CAEBBB434ADBC6AA68A42AD84EF5B99 +:1019D000268D0A67DC313860A2EB96B78AEF39644E +:1019E00082738AE00BFC3E83FE3293CC8475FED07A +:1019F000BB28334146EEEFBD56A54D7610F249ABFC +:101A000076CF21C7F0EF2B2512ED2B1FFEFE6A418A +:101A1000E1F88839C13E33E69D9AA73780F4BD12BC +:101A2000C42F25F595BBDD6DB259FED8E691C2EF06 +:101A300005B65302EB63F91AF05B64A100FDC8F42C +:101A40009F1943FCB8724F13E33B1BBC9D81BF0D34 +:101A5000BC67E3E30FBD1B3682BDDAEE60F4D291C2 +:101A60002B863690E1F462AC8781C7735D8F2D823F +:101A70001BF9C3A0A36671E9A8EB7E363ABA15E854 +:101A8000E892FF793ABA0FE8A8FAFF241D6DFFBF6C +:101A9000484743E52BD15E58C8FBEA1FF8EF6F8338 +:101AA0007C7E5D9750EEBD3E87C9FFD7234C2E2626 +:101AB00049A4A71AF4C15109E554526FF721BCD4C7 +:101AC0002486791C81DFE8F847B9BDF46AAB42127D +:101AD0009371FE458BE8F757AFFAA410F4D7AB74B7 +:101AE0006DC1FE266450D769FB5752656A8043D9A1 +:101AF000CDCA836DA763609F270556FE69DB693DEC +:101B000086E36DD97825C5E742F895C271DD1C21C1 +:101B1000AD1DF6A2E06478A92316BD4AD7E545813C +:101B2000D28BB298DAA188BF3041FFB094DA09268F +:101B3000FBA2051418C8E57A17EA3F7BFFAFF079DE +:101B4000DAEDB8EBE6D438405FB8169F940728FC6E +:101B50000B170B0E660FC5886A825BD4051DF44017 +:101B6000788EEB21D07F619938D434F358A8BB2C00 +:101B700076D749AEC7285E9630BF452B6A9A325455 +:101B8000FFA4A17F6DF319892E8C7918E5C5734EDA +:101B90001ECAA1709106213451033AD58ABEE233A0 +:101BA000F79F61D8373EC0DBEB4BAECD647410417C +:101BB000BD6AD0D32F8E7DC33100EFEB72502E5D06 +:101BC00017962CF6E4B5F51996795D3FE7DA51EDF5 +:101BD000701231E1C144F7FE0282744AFE8BDA29A9 +:101BE000944E63B58311B45B8E0B5A3B2D67CE6D5B +:101BF000190FFDDE2966637D616ECBE401B4B71673 +:101C000020FD67F03E339DD13F94805C9D289287F4 +:101C100034B04747F70B3A016F9387CA8E402426AA +:101C200050BC6931B5521A05DF715DAC4F47AF1337 +:101C300044B66E9DB1456A290074C82A37B2EAA23B +:101C400068FF19F5291D4F107361DC18BE4FD17163 +:101C5000379D176DE761B608C9BC78512619651E16 +:101C60001DB6F5A7E25F4F27675772F8C87ED6BF4B +:101C7000219332B369FF69EA1BCF2EDEFFE990485A +:101C80009200A71C56001E52564BCCFD10BD02CB35 +:101C90004E5E7405C34A31C5A7AB5C846990CEF231 +:101CA000877459033CC470BD37D3B52D34F1E5E6D4 +:101CB0003F4BE8E7AF144BDA406E6CEEBF89681417 +:101CC0001F9E609C6079CA8D0AE0693375B29230BC +:101CD000BEDC47008E8C42FA3B1D274325718DF6F2 +:101CE000276B7D099196E57A12D2E9279F1A123C5B +:101CF000D4FF3E102C6993E9FB8EA504E52301AFC8 +:101D0000DC443F1DC1577509E867090901C01D8101 +:101D1000E538CF8DE5CBBB8BE9FB530D32C60FC841 +:101D200017145EC3AFA77E86A78CE830DEE63C12B0 +:101D3000F7A21DAC237E9D2A5B3F6D7B29494CA7F2 +:101D4000DFB366F4C3F8B17F22A1896C48946B328B +:101D5000972744A6F407E3B7A8A1BBD3D09F42229C +:101D60003789D5A67556C3E8C7DAF196E924570333 +:101D70007E3B2A281FA4917BB78A22D2413CB468BB +:101D800061499A71EE1435944F46593BED44F8473A +:101D9000AA3F544F26891CE85A17002F241CC0F96B +:101DA0006593D48F0EE51C3EDF31248AF582B37A29 +:101DB000FB81DFF2F5BE1AC0C53FFBAE3F82EB46AA +:101DC0001E54C18EA5D0969EC9199217A073607E2D +:101DD0001F8644F43B7C6242D569073E773288CE49 +:101DE000AF46302E97094D28C077B72A1D6097F867 +:101DF000494880EFBE901C33DBF59984962DF11491 +:101E000072B474069216E30FA2F603EBA865D169CB +:101E100000CC7D7EFDE7E0376DF145D00FFBC4EDD2 +:101E20009F0A83DDE6F13F04CF4FDCE3E2E89F85C4 +:101E300098BFA5D07F40DE65CE922DFE4D966E2DCB +:101E4000E7D8FCB0059217E799750DE1FE95DE30F5 +:101E500071CC105C14A226A0976D753201FFDFEBE8 +:101E600065F018F0E54877CD0478291CC7010E8A83 +:101E70001684E314F922014BEC2F23183FA5701DA3 +:101E8000B7C175DC06D771335C2D0A9BAFDD5E8C64 +:101E9000D592B22805EE3991FB1FD46E02BBF11426 +:101EA000795FAF07C2095F8D7AD6AFB2365E2589FA +:101EB000C10A95A8480776BB91AED38716FF6B166B +:101EC0002F6B4480795038ADDF4921D20B96259293 +:101ED0008A0B2F9F65E04BFBF26F28FFDD74D84122 +:101EE00080BF281F4BF0DDC1BFDEC4E3C3CBC1BF41 +:101EF000A6F8FB1A09FB01BE0F888871A80FC8ABB2 +:101F0000FEE926397942E4F6092CB1998F4928086F +:101F1000725CF66E4C4A7E4483416FC2195CC710F6 +:101F200093F35E467731A2B4A13EEC66FEA7114F53 +:101F3000FD7AAFD51FFEC6766BF946B2680CC44B6E +:101F40006FFCB683C469BF3799FD7BBA4EAF892A4F +:101F5000C2F70D12DD0876499783D91BCB55224372 +:101F6000FC73F5BF7D67C6323A9F53200FAAC17E2E +:101F7000A7E09BF4C88A40DCA9970F9F5FBB106A5B +:101F8000BC4C18797E5D8E6423F8DFB11E07DA99A8 +:101F9000C41E07DD27611CD4D40EE1FD6AB7757E2F +:101FA000679BBF7DBE84DC8BF35DB17B19DAE723D1 +:101FB000CDC7B99BDA9B69F49D57122C711F83AF73 +:101FC0000D7AB7F37795A4B1B80E558368AFFC2EA0 +:101FD00023DE8EEB1B9D09EB7BB6F6B3A17DEE8570 +:101FE000B79FFB578E3FEF2CED572B830B60BD3710 +:101FF000057AC3C09F461C6B0D89E905F457C7B32A +:10200000EB6260BAA5EA05CFB15E21AD279D43BD65 +:10201000D2D1FB3BC1ED9217F63CEC043BF5832794 +:102020008E35821DB0F2DF25A2507A38B1C7471233 +:1020300068AFC49D60DFACA07417C77262C6B526D6 +:102040007B985234AEC3CAA77D6847ACD8EB8A37B9 +:10205000D0F62B7EF4DF5309C5C3890D833F2F00D3 +:102060007A7E426071D7D8C0D46BE9FB1532F9C7CC +:10207000701A3A5A26317E7AFFC7194BC04E147631 +:10208000F77F05FBEDFBB2C365D2C74B24078E4B30 +:10209000EBA11F117B5C884F14187C667FC088778A +:1020A000BFFFB8C0E0DBEF88BB01BEDDBB9C115AAF +:1020B0006FEDEE9348D7F39E7ECA0F7858BBDF6A68 +:1020C000A7AFDD2D255C53F1790C9EA041851980C9 +:1020D0004FC6CF6BF6AD46BDB1A66FF349E0E7B58D +:1020E000FB1D16F94FF1124A005EDF90420D50FEC3 +:1020F000E1F7FC1A45D57BC947FD8057DAEF322757 +:10210000A5AB85B3ACEDA0FFD3D9C3FBA39E21FA49 +:10211000CD6BFB36B1F1F65DF30790B76B09D35386 +:10212000063FBF07BFE40DD7339B246B7CEB1479CC +:102130007906FA81BB73D2FACF865E31F87AE5531D +:10214000A776C6E8F8EFEFFDE3CE189DC7AABF7CDF +:10215000B4F34EF0979E77AB20AFD63EF19A9F989E +:10216000F0FF88C4F6034E3CFEBDC776503E39F101 +:102170006B17DA81279EFBC3388DCEFFC40F3E1D3F +:102180000376EA2DCFCD1F0BF8B8E599796347B3F5 +:10219000D7816EE32EF3FAC6B17F6DBF009B20841A +:1021A0003CCB9FB6753AB84F4A4088E083375D71A3 +:1021B00017C5CF5AFAAEA512D66D35EA2B28DF45E2 +:1021C000F1BD664FD749696A3ABCC70AC4203C13BF +:1021D000052408EB7EEDC2CBABE0E908694027643B +:1021E00010F584BDDDDAA3747DA78DBC9ED49E70EE +:1021F00002FED7EED9C4C6EDA3EBE91FBE9E1FC0F9 +:102200002FB387AFE741C91A673A45567D77077CF8 +:10221000DCC7FCCE91D673F533D78DEADF19F2E136 +:102220006C786E16185C5B25FD5712F0E3DE271FF5 +:10223000DB1160EBDC401173E2A953E36093F71DFF +:10224000C7E057404E0E3EE752C1AE5EF1DC1BC800 +:1022500077279E39E2D4707F9A7805AA274F90D4C9 +:102260004F12F4E61A8115D63EE24BB8FC43EBB5AB +:1022700026DE54AFF9F1FD317C1F67FCB026DEBFCE +:102280005848B37E5EB984E9A7782EE265B59674A6 +:10229000AA5EEBBA0AB3603D8F2D00FA1B693D8D33 +:1022A000F9AB30FF99A6757D84F1F148FC7A62970D +:1022B0004B163287AFF3096E57AC8D0B6FA45B776B +:1022C0004236B0F8DE08716FE369A70BA76CE573BF +:1022D000A3BD31FFB3F1F9D9E7757E783BC5F5B5FC +:1022E0001D7FEF7F915E0F94C802D75BBDF5F92685 +:1022F0007DE776503D560C76673456503C04EFC669 +:102300003E09E5FBFBBB25B4F7ED7262CD087E7D8F +:10231000C818677FFF549067EF1FF831A74746EF53 +:102320006BF61C73C6B85E889BF502F497663D2E6B +:10233000E5FDAD7D367D7F6BF79C4CDBDF7BB2FE30 +:102340006580FFBDA483C46817EFF54969E324A540 +:10235000B2C362676DF4CD783393B693FC1E0DE67D +:10236000DDBE417F2306F6C8AB0E82F6A31C7AC7FA +:1023700045BFB7FB3CB8DFD2EEBF916826FDDD61FB +:10238000C3931C0CA31F2D07C2556C2F346EF1672D +:102390001DAA68819BC8B142D8E7FC65F11F64E8BB +:1023A00017E2699A292EF48A4C3A73687FAFE842A3 +:1023B000A88DA4896BD9FA0FCF918866A6337DBC0E +:1023C000688E2FFA0FDC8E718D16124D40BC891469 +:1023D00092BE474DFD3ED8AAB1B86B78BC688EFF5F +:1023E000B9A251DD45E128BC452D01FF6DA4F18B5B +:1023F000A2D67D5F63FCF53C1E41763FF1C413B469 +:102400003C1EBE616A45BCCD09F13795D937F3B89A +:102410003CFC29B79F0F08E1436087E977C56490CA +:102420007782D626839D51FF454C5E6EA2C77AED1A +:10243000641EE8D5EFFE595A928E4EF773BA6AFBC6 +:10244000A71FE541FCEE01F76D85CC990D237C8536 +:102450007C9E878ABEE185EFFDAB6FF44EA6F8291E +:10246000084A04E2350581655B2A60FE47A5905B5A +:102470001BDEBFF1DCC9E37A0FB5AA28FF1F690D87 +:1024800062F9318ED7DDAD65F87CA23584DFF7B413 +:10249000CEC2725F6B3D3EF7B686F1BDFF8E17056B +:1024A000A03BF22DD207F19A7DAD4BF0FB8F5A2362 +:1024B000F87C94CFA71EF0E2B5CC1FE331FB3BAE16 +:1024C000D800F118038F76BCD7D1A962FF9AA0017A +:1024D0009DDF2E33F962C7EF38574208D3724B9411 +:1024E000E52BECE4716363BEFF2A337B731F87E740 +:1024F000C7EEC8F765D86FAA2F2DE7F1F110C8EF26 +:102500009D42786B05E59F178A6606CD72B8C8179D +:10251000D9279BE8675C378BF7EC9099BC1A4F4E34 +:10252000F66752BCEB5F100DE8CE98EF811AAD1044 +:10253000E4E40141C0F5D6BF10499989EE8CFEBE96 +:10254000238B7C7F23BDDC1EA263260FB2AF92CB10 +:10255000C0AF3D453C2189C2DB9947F681DFD209F6 +:10256000740976F26F33304E6CF8375BF87A67BBDC +:10257000D9F7536FF9E2207F46F27B36F2FA1F72E9 +:10258000B856CBE15FC9B8AF1C1758BE4302E398F9 +:10259000056C2A944E976EA56B45EEB9F4BD3721B4 +:1025A0003EF8C1336E0DE0EAA93AEE37E391AC9202 +:1025B000DF37EFEB18EFF34F17203EFF1F891C3377 +:1025C000E339BF79D009ED3B056D5B1DCCEB3509D7 +:1025D000F9AF53885F84F13399A05FD07953300EFF +:1025E00072CF68E70B59F93BDB1D5EB20CE6DDEC00 +:1025F0000CC5D2C8A7DF666816F9E00A5ADB0741A6 +:102600006756B3B246E9B382303911927509FCB40A +:102610006A12C1E74CA2E133CF11F90CE6319D8477 +:1026200035807343C6B8CBD8FEC1FF18DE14C7FF90 +:1026300041BC19F41ABCB46C1BE41F903B44DC6F22 +:1026400069874F263A5FE810387E1594E7053CAE5F +:102650004FE5FF0B4501EC86C549D40C9483057CFE +:10266000C3A065E024C67783E3088FBBC731DF6969 +:10267000C72A11FDF507DE12E290EC726A55C99186 +:1026800049B47D0DE573589FECAB4A33CDFB0C0686 +:102690007F3CA08433D551E2FC065F18E57F19FF2B +:1026A000BC007268DBF8E7FB413FE40F08211063D0 +:1026B000F9DEE864904735BF7B3C0FBEFFC6139937 +:1026C000635E9F1DABA3E3014EAF2F3C17DE870B6C +:1026D000E33780BC3B557F8B0B97D9CBF25E5AEE2C +:1026E000D2B64DD6465E9F9D2DA3EFDF18F3DA7963 +:1026F0008EF332D6EB54FDE228E8713B9EECFD668A +:102700005FB578D4F11F04BDE2C2F92F35CFBF30D9 +:10271000AA627E8BD1DE98AFBDBD7DBE43FBC0E714 +:102720009617D4E72039B0DE3FF87CDC0F5F2140FC +:10273000126109E89FF2E71A806706894A8C1FC276 +:102740001AC87F839E778C792C0FF5821C2F4679CF +:10275000778EE3759270B806ECB2901832DB2BC618 +:10276000B33D45E7098CABBAB81C1133EE0AA6C3DA +:1027700073AAFF42CAFFA63CA62D84B078544241FA +:10278000390F814295961D8749E5DDB4BF66079BE9 +:10279000478DCCE221D30F6BBB241657959A7C262C +:1027A0003CF2FD0623BEDB49EE22AA067E45453FEC +:1027B0005437F8F4E7CEC8B71D908717D430DFD36D +:1027C0001188086C3F8EED0F15717E9D2F2D55C021 +:1027D0002E6921E17AB04BC85189B03C3CC6D72E56 +:1027E000631F8CF3B1CB4D783C38C8F89AF77390DF +:1027F000FBA53FE5F6C9B3DC3EF909D827B45CF484 +:10280000F1E00180733FD8292EB03742F87D1FB721 +:1028100053FCB77812E01FEE6DD5B1FC706B333E00 +:10282000EFB9F5709B1FFA7FEE4707FD14BEEFB4BA +:1028300010E4D71692FCC54A80372A627C63576B36 +:1028400014FBCDDF923C007B24BD2D077485BEEFC9 +:102850008AD68A6E5A6F6715C1F8C64E85E21DE4A6 +:10286000631F41F908EE12CA2F2E9F32D79522FF1F +:10287000F654EDBD0AF051788D88DB2F06BFB9BA4A +:10288000070656D2F283CD7BDD4086D9B9C9F52F34 +:10289000815E9F43E5AD06EB92EC5E40D7B7A06842 +:1028A00091328F96FD7D1BD7817EF6EFBBFF66F0E0 +:1028B0008FFDCF3EF14D2817D8EC59FFBEFDB7B1C3 +:1028C0007A2FDE0EF50A0ED379D0F653D563FD309C +:1028D0007F8ABF81CDB49EA3CA9AEFF894613F74FA +:1028E00012A4ABED3FD82FC2FC0303E11AD8AE19F6 +:1028F000F366B41FC8A7F01D86FF5DAB3A76413F73 +:10290000EF3A8A919E1E6839001175F29D6FBE8E56 +:10291000F47C70D57A02F4E05A25635CB160F52D41 +:10292000E41B2679E16A91D3C699DF75B8907E3BA6 +:10293000572D4E4EE2640A7C38EEF63A05E5C5CBDB +:10294000D67C07637F781789BCEB40FE62FBC4B27C +:10295000CAF6932FA148077B89AC15599E5FB8CF63 +:102960006D8E1F16AE16C3E9E0F8D421E3BC3AA27F +:1029700075EFBC48E72BCFBC15ED52D26B1DDF18AD +:102980008F8EFFA9C3947F22AB0C2E8D84441F1D14 +:1029900077CF5E4F3E944F470D7D95C0FDD3A72B5B +:1029A000C4C4780ADFBDBD22E6A11CAC67FAABE760 +:1029B00016B6AFD5C3CB3BFAA801563CC44F863FF1 +:1029C000B023CAF6BFC91767D0BEF0723ECAAE7850 +:1029D00055C1FD8998EEADA1EFA71183DFC4A175A4 +:1029E00007FB658B950EC48E6C4B59A3C6BA39EFA5 +:1029F00018360D5365D4A74715F0274FF5C904ECD9 +:102A000097697C7FC88ECF1D9CAF7742DE0CF81D86 +:102A1000ABF6BA350AF7CF0C3A6989EAA0178BEE04 +:102A20000AC798DF63CDA3868C10C07311DF87229D +:102A3000D25B15480FCFB23C5A631FD15168CDAB62 +:102A40002EB7E58317D9F2A8CF37EE52EDB4C7E31E +:102A5000B65C84FA42F3A31CCBE7633D329BBAF920 +:102A6000D386C75F52FDF2F802E9F5E37AE673799F +:102A700078CF1D5233F80BFE159559E638E9D54E3F +:102A8000E6C71CFAAD0BE979679DC2F73D59BEA7B1 +:102A900083AF7B9353C37A3B7B6F55009F5D81125D +:102AA00037F473F0D29FB8315F85E7AD1AF278033F +:102AB0007D7F13EDEF3BB922EAA4CEC257F360BF8E +:102AC000FEDE3A05F352FD19037D0769D97BA73372 +:102AD0000479233B6B124BC226B86E7732BDB6D455 +:102AE000C9F787B658F33A285F2C7542DE98378AC3 +:102AF000FB99A2C2F37B6D7EBF810FFF81ABC4E265 +:102B000029EC593205FC54262FE33CDF6A27D70B0A +:102B1000867DB183FBAD5BB8DF6AEFB7B4593F8008 +:102B2000F6D92AB5124254F6F59DD06D959FC53160 +:102B30002B3F8C6FB1F2435134DF52BFA0B9C4F2C6 +:102B4000DD17BAD866B72498BE236C7DBADCDE09DF +:102B500020472AA93EE6F607CAB791F47DB343DFC2 +:102B6000E004B9768E76883F231C85789BDDCEBE47 +:102B700087AFCF3FC8FA16E88FFA75F760BF725C6F +:102B800060E787AC76C93038B99C1B05CE7F719E53 +:102B9000877D76B6FD37FBBEDB6D5278FB2BF439B3 +:102BA0003793E54976FA989FDF09F1555A7E8ECF23 +:102BB000EFFB4E099FFFCECB733368FD34FC6DC431 +:102BC0005D7F0A0939506F6CFAFC4BB08CF07B4189 +:102BD000FAEF3F75B27DEEB9E3471FA79F8FB3C5EC +:102BE000A13FEB34C5F7BA9CFAF3E6F24127DB9735 +:102BF00036E8C2C8AF34ECB45B1DFA2173FDA1A75F +:102C00005D5EB2FD915CBE9E3EC2F8EF674B966F73 +:102C10009A48F9D959E845FB277749C73AD10F793E +:102C2000494915FC845C2EBFC96226378DFDF6EC40 +:102C300006AB5CB59FC372F17C7997FDFC0D97AF35 +:102C4000767A1C49BE1EB3C9D7545C7B04BAB2C79E +:102C5000B55BE057667F72FB389CB968CAC8F4F868 +:102C6000CBD6C19E431387CAAFC0B99AB474C0F61D +:102C700019FD07DE6D585C05FB795208645CB235BE +:102C800031F7ED8943F22B3C27EB67100F0DD76529 +:102C9000A1BC690CFEA9E7500E95CB7AFFDCB74DBD +:102CA000F34CAA14DA09A3F089EEF8CCCC5FDF0369 +:102CB000590F76111F6F2BC7A7DDBEEE12632EE8EA +:102CC000F76332A00BC5A3CFBB03F136E0053A1B77 +:102CD00069DED35D4CBEFB67454310BF739D919089 +:102CE0000F5CE30D3B268476CC0C5716A3676F0967 +:102CF000EEEF51FF7DB01FD6C1CBF2FE0DFDF89176 +:102D00001167E57AEFE62C56DEDCCAE2CAAE83B381 +:102D1000DFD0683BDFCB0E0271CC4D54AE437CB0AC +:102D20009BDAF9F0DD5F354020BEDE4EEB474CFE0E +:102D3000787BA85685FDC68EF24A05EC0A694A15CD +:102D400096E5E24AB5968E39A5EBFE79B9101F2FAC +:102D50001531DF761A2DB79552BA76A938BF5F962E +:102D6000BDED05FB2C1B82A9D543EBE9A88AE8122F +:102D700085C711546B214723A5B7399DD1F70F4162 +:102D80007ED1F784C86C179DFF2FF9B9AC2E67B4BC +:102D90006C3DF84372CC0571C01685ED4F003D7453 +:102DA0004C1F82BB96E3D7CDC74DF9477C3D3F967C +:102DB000076290F2DA2592E674EBD3E06272AE43DA +:102DC000D5D551E949953FB3E455CF61FCE40C50AA +:102DD0007A32F1F548F25A728517BB7287F298E899 +:102DE000C2AAC8A784D981C6B99F3F38F52558CF54 +:102DF000CBF04A0AB3914EE9FBF99EEA0B91FBDA5C +:102E0000D63ABA6E07E6541DC17856D2817124FFB6 +:102E100004F28F663BE4251706E3E893C52DEFA681 +:102E2000F4119FCCE21504E826832A62D89F2C1265 +:102E3000E30F1503BCBBEA27D0FEBAE489D4521FC6 +:102E4000EAA7A688F9033DB59E66B35FF0C70CB646 +:102E50002F739BB7E619171DA7DC1BAF45F30BB209 +:102E600036C7B0735540C797A8644010410E860915 +:102E7000D39B2185C54DEB543847259008399331B4 +:102E80009A7EB49EB77A428E6FF0003E022C0EE618 +:102E9000DB2E6092A0D4A7273C2012BC8BBA5CA882 +:102EA000C7C365304EFF0C0FF1D2FA7FEA77E23EDE +:102EB000789FAF4006BC3E2F2EFFAE93CE77F0D763 +:102EC0002ECC7BECFBF3C59897DFE7BB6C01C8ED1C +:102ED0003E811CA6CA9ED49C2EE049882403F6FF9E +:102EE000FCF37402FB30833F2368FF39822FCD7DD2 +:102EF0007B3A4E3C439C45DBB949B79BB60B7DE61C +:102F0000F9E80A4A577BBD95F74D2343F11623CEC6 +:102F1000529711D90974D139E63F9B816FBA299C28 +:102F200012FA137A10E0AECC15312E4972BDF18938 +:102F3000F47DCDE1401DE495D6C8159832EB9FC7CE +:102F4000D6FB379EC86E986F9DDA549745EB571D98 +:102F5000D550CE2E08AE3B04E5196FB172A793F1A0 +:102F60000BC4918849EED69C1E87F3FB21A7938E54 +:102F7000A09ED48551F9C6761EC19A4767A603C89C +:102F80007F37D141C461A68359940EA698E94017B2 +:102F9000CE870EDA50595F08FFE86FD40943F1BCC1 +:102FA000E17CB04EC92E1FCE2F061C775765074017 +:102FB0008E1A7CA1CEBC0BE5AA6B99330CFB2D06B7 +:102FC0009F18FCF1A9DB817C48F9A411F87DB15769 +:102FD0009B9F8E4FC00F31F3C3B523F04D23193C97 +:102FE00014A08D1A6512CBA4A2E497B3DF291D6744 +:102FF000E2033BDE1AE708E4B8459EB1B209AF6AC6 +:10300000EADCA374EEF87F55D63A03263EDC48FD91 +:10301000103096BBC51001BD52ED5DFE29D0A5DC78 +:10302000F08320F8830E57B819F36967BE9F7123A8 +:10303000A5CB3F8D1135987CA7B6FC69E4E7373303 +:1030400008D8273D3356603CF84F3745C6839ED895 +:1030500044F17F1CF5727CAC88B9990363D93EBCFE +:103060001664CF4890BD27FC7B9C97755E6F00EB84 +:10307000D175B6C8C71E37A3F71E37D3179B9CBDA3 +:103080000AF0DB60B1A29AF3A0AF90981D5BA5F0A7 +:103090007DA92FDA35881B5629ACDD7DAD7D687F93 +:1030A0006C6ADD8FCF9C8638813C2B4F594C83FD59 +:1030B00070E52FF30407F0F1C56CDF16DEB799EC6D +:1030C000AF710AF36395BF4811E04F65434CCB36AF +:1030D000C959451422E9ECE8AD6E99B5DB40F0BB67 +:1030E00072E05F719F3BA734247C1DCA1B7A49881C +:1030F000F6E34EB0F781525DF89AA9DF40439F4551 +:10310000CF35D225C8AC44EB09CFC1746A1EDC1799 +:103110006B0CD4BE2B4F1D4E47F073DC440F06FCE6 +:10312000C6FEEC2DDCFFAE2B5190FF3A5B9CBB4002 +:1031300035372ACC2EFA38503BEA3902D897A59673 +:103140001BFAB9F084FDD9D864B63F0B65D89F85CA +:1031500027ECCFC213F667E13BECCF42F9FBAD3A67 +:1031600096619F16CAB04F1B9BCCF665632EB62F97 +:103170000BCFFDADCDF8FC496B14BF3FDBDA82E528 +:103180002B5CCCBF2165B120D8CBDDB73B75C8BF68 +:10319000E9E47470502FC909D1757507589CC0FDBA +:1031A000F2BD780EDA1D1471DF7563F05EF255FA28 +:1031B000ECAEF675431E8CF2B4179F6EF93EA2E199 +:1031C000BE6CAC1922A7AB94E97532B5134A83EBF8 +:1031D0006AB36979BD32BB03F21127696DA1E5EAD3 +:1031E0005059F355AEF881A93CBE7C97ECA1F56F20 +:1031F000EBBEAC03E401C001FBC86DCADC3AB0E32E +:103200001225D45001B956EC8C033D7F0DD66B22AC +:10321000C0CFFCA92F91F620C435C66BCE4AE0433F +:103220005A3FC1E8FFDCEA774210387778BBD1EA31 +:103230008955E7548F48A3F407DF85D1FA21ED6A59 +:1032400092C2BE196406D8476EB6FFDBED60FCDFA4 +:10325000ED66CFB739DFFFD85D3BDF4DF968BE9B28 +:10326000F161B73B5C0FE75006A788A18708EE9B8A +:10327000C4DC7028A1A5F857705EE8D6176502FB7C +:103280000A0F72BE9D38DEC7F4F49D0AEAE92BC727 +:103290003FD5914DCB131F0E8540EF6E26210FD0E9 +:1032A000496C8B88F9294F564DC86EA2D52FA97E3F +:1032B000261BF4CFA70AB377E3DCDF68EBBC713CD5 +:1032C000C4FFFE7484C9BF2739BDED7224A3B89E24 +:1032D000D55EB457A8C380F6485B50C6BC22318F78 +:1032E0003D9D0EF5EFA09E932AFC1885C7F9E7993E +:1032F0000AC63F4EBBF8BD1749B4539CEE889A45A9 +:10330000DFF7C644E4F776D51307BB7AB3B712CF1D +:103310009BC6CA653C77B2B95C64E7657CD7C7C118 +:103320003ED9DAEF66F2C1AB605E69BC7CDFE1DA00 +:10333000003C4515F83DAE2FAA47BCABA28AF9A9BF +:10334000F437FCDE1CC0732A1023C7EFCD2CFEDC43 +:1033500039E6B397A641BECED7D510BF8B00F3BFD9 +:10336000D1E412619F68F04006C0F30FC63D06032A +:103370001B3268FD8EE56A08D661AA5A5B0FF90513 +:103380009D6A2DFA391953EA9465288752E734F07B +:10339000BE8C8E7219F38BE03BF025E92087E09C10 +:1033A000BCB1FF9C915529807DD5D980613E38C73D +:1033B00060C937EFC8BE1ACF27498DD9086727D112 +:1033C00015A81F6B9051FF15789504EE3F18E7ED97 +:1033D000E1E88529DE90B3CA7A7E23AF59B69C17FF +:1033E0001F1BB1967379FC20D776CEE34F8AB16F5D +:1033F00066C5937DBE398187B200DE1C38E0AB0D17 +:103400009FCF7D81CA26986781EA41B883EA861AF0 +:10341000905F6349B40DE8EEBCE1B5C139B5BC239A +:1034200009EB3E559389A641BC7D7003F4BB99D34B +:103430007977B1551F3FA848063F4E75E7429C512A +:103440002431D3F810878C99C69BD09D6D294FEC01 +:10345000CDB7D49FBCBDC4F2FDA2F8C596EF97ECE2 +:10346000AEB494A7F45D6AA93F6D7FADA55C91B839 +:10347000DA527FFAE145967275F2EF2CF567BEB924 +:10348000DCF27DF6C00ACBF7CBDE596F295F3E78C0 +:1034900087A5BE61AFDBF56299FBC2EC7417DC1F38 +:1034A0006189CB5AFD00BB1DAFFCA55DDB0072CD71 +:1034B000EF44FA96418FD3F2FADB991FA5CC0D6940 +:1034C0002057C671395AE4D3AB418ED6F815D407CC +:1034D000B297D593BD0BD0FE18B79DCAA3E9606D16 +:1034E00092D4F70C90CBADB1B9A5A678935BEDC59E +:1034F000335B35FE7A02F179A3BDACEA2402FD40CC +:103500001004E2E7D44B857A6E8DB637CDEB795156 +:10351000C4A3D183D4DF7BC8E4EF8DE4DFD9FDB948 +:1035200073F5DFC689C483E70D8470149EE5D1234B +:10353000B590264CFDBA1B807E7B9CE1E65DB4DF36 +:103540009E120FEE5F1A7E5D77711FF2C560B18C1F +:10355000FA85C85AB9391ED7C1D737437912FD4AFF +:103560008A7794B706DE370B03F176903BB77B5032 +:103570001E8EFB2FD7ABC05F4A8952A0D0F7A18324 +:103580004E1DF6B7EFE3782D512B6A21A4541A6C27 +:103590003A00CF491AB533E8B3AC6CDB0178DEEA08 +:1035A0006679C217877E500BB24499CBEC3F79AA5B +:1035B00033BE81F623A9148E347E85F194FCDBD9C9 +:1035C000FE45A9FC7BA037B0EACFD029D4642B7884 +:1035D000FF8C1BE840C027D28F3BE045BDE186430E +:1035E000AF5096857886C0EC53D89FABC9DE8EEB82 +:1035F0006ED8AD60CF46989FDB01F41568B0AE770A +:1036000086F27DC45387C0E2DEDD59DACBB574DCC7 +:10361000EEDC926C88B1425CA4C9246F7AB8DEFEFD +:103620008A47E4F96F4CDEFC05FAAC1EB27728FD40 +:103630006F1727007CBD04E496FBAE5E02F4EE56E5 +:10364000E96AA25D1FD3C2A84F99BD7B3387A9AE9B +:103650006409EEFB7F14A844FBD6DDF27C5AFCB96A +:103660000724A24F1F19AFFE493B50DF9312A70654 +:1036700076458BE6D477A59107E5DC0FD934CE38B3 +:10368000E7CACEDB76737C18F1D0549C91C7D38CFB +:1036900038A3D1CFCDB9956347B3C7DDD4BF8C98DC +:1036A000E0DD44C701BC747ED1548F7890093BA7FC +:1036B000FBE7F25D904765F849E5DC7EA9E2F81D7D +:1036C000E724E827CC83B8490E78B55FAA07BE3453 +:1036D000E22CBF03638BD60BC588C4E26A0E436F2E +:1036E0008967A621CC9A7306BBE28BE5A332BD465F +:1036F000FFED87F36413BAADE73527F65ACB93B7DE +:103700005BCB17C5AD656A351F05BB006C348C5BA0 +:10371000ECB67E6F32F603EAD8F932858E7C86E904 +:103720005FCB7D3984EBFF7CDE4F515FA206C46B1B +:10373000E12D56BD9ACFF57CBE4D7F56FA248C27DD +:10374000D41C0E1C02FBD188FBFCC6A359EE7530BD +:10375000E2377679EE796B1BA15FD02F8FB8581CBA +:1037600003E2C39F14F17849218F978CE3F19222F1 +:10377000162F7148DA2B4B05CC0B3DE9463B233A1B +:103780008DC569D839AF0FEBE59F091A1B2F621A57 +:10379000EFB6B2D8950C0DF13CA867C44D8CB8803B +:1037A000D7A7CF073EDB1C7A357A90D249EDAF5DC3 +:1037B00004FA992FBD7CB815E45B918CF9DCEACC56 +:1037C00055DFF5401C12BED3726DB13616F9E01705 +:1037D0000E8C0F7471BA36CE271A7116BF87D94571 +:1037E0001E8F60EC037978BEBE07ECDD4B76535A32 +:1037F000B4E83B16CF33E27653FAACDFFB8890A3F4 +:10380000D2759CB6242E32FB4AF7D698F21D2FE6CD +:10381000EB367569E2DEA5B4BC87C42BE11EBA0A9B +:103820004E1FA143D673B1638880E7A2C61C9542A0 +:10383000715A7FEAB3D6EFE5B673B317DBCFD1DAAF +:10384000F6857C1239B98C8EB7458B0A2047B72C88 +:10385000A5B63C2D4FF6F0FDA2496412D0E17CC91B +:103860001B4A007E5F93707FCB756CF21B90C7483C +:103870008EB07C247502CB8B545F92504FA919A453 +:10388000A2C23BB48F74FF9910817D1123AEF50461 +:103890005D57D02B7BA85F5EEA003F5BC5721FF5CA +:1038A000CBA1BC97FAE5F0DC47FD72780FF94850E0 +:1038B000DE4FFD7278FE84FAE5F0FE59EA9743F98F +:1038C000366FCD7C4F2EEC1B9521BD782AF629133F +:1038D00028BC5D8A4305FAB0CBA19A9A9B95C59402 +:1038E000A4FECEF514EE5FD4CE67F9D3F33D4FCDF1 +:1038F0006B93ADF13573FC7128BE362018F1350895 +:10390000791EE3FB0CA9385B84C5D9CEDE8F6EF43B +:103910008371CD61FDF0F8E607B7FFE763EDF4D3FF +:10392000EAEA7BBB3D25709E234ACCFBC7C6390F14 +:10393000637EABF7B5619E8C33EF6814D6755F95E7 +:1039400017EFFA713A222AC85BBB3F67F871767BA2 +:10395000DA78DAF59B8FDB1546DCB4C741307F3A65 +:1039600026507B02EC8BD6F8DCB71D23C7535FF7DC +:10397000F0734536B9903A37C0E33E2EB066E93C65 +:103980009D02C707CF6747D158C2E27AE6B8AAA717 +:10399000348E87D53D5E1DED3A81DA7B68FFA991B3 +:1039A00020C4D136C2398134F37B98F37B5B9E13FC +:1039B000ED8D8D790ADA497585A120B46FCF9B1101 +:1039C000349F1B30CE351CF2CD50064CFDADF79523 +:1039D0008CAAFF24AAAFB551F4B5E462E77ADA0FF6 +:1039E000CC56E0BC46B7777912FCE8EE6000E3EF16 +:1039F000FD793330AF27553F380BCF75485E660FE2 +:103A00004B4105ED6119E65F3E54DFA8D7EA6174CA +:103A100042D919E38B6E6F2FD673C961BC4FC215A3 +:103A20006079772E95EDC7794A45A298E485316E85 +:103A30008B87C5A3BBCB232AC459BA8332E6E97767 +:103A40006B9588E7768EE7F622C39E08A11DF36F7B +:103A50001CCF463FED3C0ED0DEEC447B2EDC92A525 +:103A6000C2D52F5E5F780FF073B7778302FB92CEDB +:103A7000BCAA51FB3DC0E5F6C8FD568CA99B8EFD46 +:103A8000FE1BF4EBF42D57A15FC708E7915EE170D0 +:103A90005EA8DD6ADFC7A3D006CDF928F6A78FDBC5 +:103AA0009FF676ABCB079CB0EE9B1EB19E5F761067 +:103AB000769E6BCDFE75C8E73D7212EDA89E2F84F1 +:103AC000B4E7C2C66418FA2CE5DF5BECA002CE4F67 +:103AD00005FC3B901AE88B8A84D56E997ED85AAE45 +:103AE0004E5ACB33DFB4DB41FA6B60072DE6722F01 +:103AF00049E53D4B861994011FE158BC06E06E2252 +:103B00007D6D9027E1E071F2C55CFF2DE4FAD19B59 +:103B1000C1E2BD05CD1E8BFF49F8FD7F85BCFFA22C +:103B2000BA43EB3A40C8860DBB4A43BFB5E8AABDCD +:103B300035282E6DF655936E3DDFBFD0663FD9ED2B +:103B4000AC1A7917E6E9E6DBE21AC67E2ECC13EE54 +:103B500039B08F7FBEE31AFD411E16C837E3FE174A +:103B6000BC6F98B62F92134288E2291FCEE7507897 +:103B70000A6E21FAAE34747C395FF761788B5D810F +:103B8000789BC7DFE57BD9BD5DF975525C2B86F369 +:103B90000E7D680F2C5A45E78376F819CC8331EAFD +:103BA0006767F5F5C3BEE78E0681F9A53182768D8C +:103BB000B1CE3BBCEC5C61D3E5425C84F6D1121C17 +:103BC0001FE12A195A5F8AA7E30C4F2CCFF0DA7A4B +:103BD000EBF9C7269BFD62D0C342DBFB010FDB176D +:103BE00037F8E083D96F4E1A47E1582DF4D6674C69 +:103BF00038777D69E20FC719E043F87D0C4B7D01F2 +:103C0000FE38A0FC50057E7F3E6BE0014249B229A0 +:103C100083C4EA28F1FDD433788940CB4B363FDDAD +:103C2000D95D04C7BA079F0423CFD5B56F7EBDA960 +:103C3000ECB93B81E5001F07B616D97A9BEE83A14C +:103C4000A8DB0979F360E7EA649B04B9B6A2BA2D50 +:103C5000543CD42E1BDA09A3B40B936D729A765E92 +:103C6000A31D45D746B8EF89CFCBC3BF8B1C1EF32E +:103C7000F832E04DD5BC78BE7181AC425EC65F0BB8 +:103C8000C798B3CD3B42B639260C6F47C16E33E0BF +:103C900017D3C31F87EFE6F11DA3C0FFB7C6C7D96F +:103CA000FA73F2EFE70D1FADBE61CCC8F305B81C87 +:103CB000780F91E6154DFD6CEDFF14E3E2F20D0473 +:103CC000CF2FCA0E5D85FDBC72F5DBE8DFCB5975E1 +:103CD0002AD8019B6819EC804D7DBD18FF2E2FBDA1 +:103CE000B71B88BE3CE121200FA610356B0FED7786 +:103CF0008A2AC3892B225F7E4884783AB98660DE9F +:103D00004866BF87DD1B547CE9C3E06F656529B851 +:103D10009F919135E36166F4B238B3017F46CDD10E +:103D20005A88BFCB4D2424005C429CD400935D4450 +:103D3000707FC3A3EFBB0DCE1B1099E927BC3B07D7 +:103D4000F42A8FB78F652443BA9D6A13E6AFBC2867 +:103D5000631C6B2C5C0D4689B2BC3C7B1BC0531EA4 +:103D6000A11D08003F8B974D8988A104EDBFF22467 +:103D70006B47FE839D2BA1BEC99267BC437835E497 +:103D8000CA581E870F2EB5C6A9C9209D336D5FF98D +:103D90001F8B1E8538C59861F29BF9ED1E0E67E6F4 +:103DA000491286FE030D56BDE1E179D71EDBBD3217 +:103DB000953E87F53E68BBFFF0AD30EA0117092953 +:103DC0004EB42F96A2DD60F8253BA022D8E34584AF +:103DD000E5E7DBDBCF60ED4990F9292E0F51944ADE +:103DE000FA7D8547C77C43172D533C0A4EA2E4D188 +:103DF000F7F9228BB7B4094486F2D07809CC337036 +:103E0000295FEA00FBE580321DEF4B33FCEA763593 +:103E1000847910A4ACD662371BF95EEB2B4AC6C27C +:103E2000F7CC31A9B8930A74B93EB714ED687FCEC8 +:103E3000C0DF839CFD6CB37F81723995A39087713D +:103E400029E523AF7B636C0E1DF77401D14CF69905 +:103E50004B8E629CCD757A9CE57DA2D57ABE5AF7D1 +:103E60008A75304E9197F1610D513BA05D0DB19E69 +:103E7000A3769DCEB3D8EB43FD175ADE27A85D632A +:103E8000BEF767E4FE33885666EE7FC208FD4FB288 +:103E9000F5AFA6ED7FA8DF1C4BBF9D328BBFC602DE +:103EA0009EB4F750567B6B4BBCD523EF0F5479591A +:103EB0005CB32B18C5FD815A42199FD2CB155F1CEC +:103EC00097D8F95E82F61B29B4EE0FD4723A162900 +:103ED00065001D5F215BEF339E4BECF71B5BEDA292 +:103EE0003720B845F125FAAA92B84FF0A957033FF9 +:103EF0006C24BB39D94A303E3D3763E066D807BFF2 +:103F000066CB7867E72CCC67467FFEEFB7542DE091 +:103F1000F781B2BCE680887809D78EC5F35B463F4F +:103F20006127990872312CB23C08FCA1E32773F396 +:103F3000310FD13EAEFDFC7B932ECC2D35CD2B0920 +:103F40007985E6F1E615EC924CF308BB48358EC74F +:103F5000EDDDD478632E6CBC233C9E658CD7B4C059 +:103F60003ABF26A78AF36BE27C6C8C7704E697064F +:103F7000BF671D8FE74DA6C6BBD23ABF26978AF30F +:103F80006BE2F7EFA6C61B7361E319719D2E6734D0 +:103F90000A7438527CC788EB5CEF7AD212D721E4DE +:103FA000C97935A5846C1398FCD8E9ADD90874F1AA +:103FB00051C3FA32D42BDCBEC67B56A93E5E2833F1 +:103FC000781B0BBDF136131EE1BC8D3E19CE49287E +:103FD0004477B173133A9EA308E2F3216AAFEB98DA +:103FE0005F5286DF1F6B0D617977EB2C7C1AFD9495 +:103FF000CD62F7815D3447486BB7BFEE65FEECB626 +:104000003CF586AF817EABF1B07CDF599711DD6462 +:104010004753C3FA009C9FEBB99E54808E9CB49D7D +:10402000C11DA81B1387F5F7541C4AB6421C5476D1 +:104030006898EFAAA5FFFB0647BC4CDFB85CAC3D17 +:10404000B98CDD8BDA983A17D480F9478D0BB330F1 +:104050001F61D162DDA752BC2D1684D74AB9BE8339 +:10406000F350D7F1A5B6FB0B01D03C74BD02BA14D6 +:10407000877BE3AE2B7C798940FB0DFBAE453F236C +:104080004C1B66D37EAEE3FAB6E6988B403C82CCFE +:1040900077A2FC5ABCD8EA176C732754B073B65594 +:1040A00004481B6DB7A8C1FADDE5627C15B6DD0BCF +:1040B000D378967B628C7C5B3B7EEC71D397BCFCA7 +:1040C0009E181E1F3D45CAF1DCB991976B6F6FC4F6 +:1040D000413700AF835C7532F9309C0F183C7FE4A8 +:1040E000727047EB9B184733E0CB97E302C8FB8223 +:1040F000E6372D79EF14B168541BFB0444DA538181 +:104100007AD8369F1DC29EBCD1EE89CA27F2EF072E +:10411000CAF8DF331086CFFBBD61F39EF34A29490D +:10412000C73F2C1EDC78580AB569437831F0F0BFE0 +:10413000CD47F773BCBF32EFE32AE607165AFE6E8F +:1041400080717EEBDA545926B2899E17AE70EACCA4 +:104150005F1D2C07BA3C7A794688FDFD0B6E07255A +:104160007E2D821DF4D7F7AF1759F29A79BF23AD90 +:10417000973D9FD2740E99A4F68D20FFA52D14446F +:104180007B609D88FB1FF951968F07DF8F5BED5693 +:104190004B3E5E7BFFE302C40D1F80FC44D339BB62 +:1041A00082E63EA113ECBBB6388B4324683D0A7708 +:1041B000617342E8281FCAFBB2CBF5C255D67CC159 +:1041C000CE398BD53D1AE4D5D4F6C285609BB6B303 +:1041D0003897513F15EFE2E7511D244AE0FC85E492 +:1041E00065F1E620BFAFE36CF9BB9F8831B5B81825 +:1041F000F276E34A0D5DB7077322753E885F062AA3 +:10420000A3BB803EE510E6792F6DB9330C714235C2 +:10421000277D1C7C29B70F16FA585CE52D47A208AC +:10422000E2E6C99CDA85BEEA34F55BBE85FDCD1DAC +:10423000E11EFA66DECF03627A79B08C7FFFF26A04 +:1042400011EF1772131F9E577597F6CE027C3CB084 +:10425000664728DD39CB196A246286C75DCAEE0736 +:1042600020A46F36CC73D3E70FF63D4DE79DFDB923 +:1042700017E56CB6C4FA35B56FF6E50E6FFFFCA70F +:10428000EC1CF2F3FCBE75424AAF04BFB1275526C1 +:1042900031B88FBD278B976302FB9E2AFFFB02F884 +:1042A0007B4A3D40A394F8FEE8FBE54688C3F60848 +:1042B0008413EB2B0B206EDFC3EF773F0CDF69FB22 +:1042C000B957BFFFF056D007339CE86FF6707BC735 +:1042D00080EF031FCBFBF9C0C7F87D247CDECDF156 +:1042E000E9057C06CE0B9F77A7C3C755017D33BC7C +:1042F0007743260805C1FDB9720BE45BFF6B2B0900 +:104300007F8DCEE181D0BEC7E14C116D7F6FBAF6D3 +:104310003FCED1EF8375F2AE3E8EF3F3957A4380B4 +:104320008A4D3309F693068E07D2F563AC6B288B62 +:10433000C93977267B6673FB5272258390BFA056DE +:10434000DD7FB34AF97E63717249BA38F1E37E6664 +:10435000F7678D10174F70FC5E991D7E12E0EE50CE +:10436000EF457FCF299030D4DF346B8008A676FFED +:10437000E567F8A670FF10E076CE66F756FB28DEFC +:104380002141CE57C5E0DFA41D2590FFEE0B1EC5D1 +:10439000BC565FD500F23B8AC27C4657E00F2ADC50 +:1043A0007E4BF8FE7B01D04DB664D0DD37BB806E0E +:1043B000A4A1F29550DE95CDDAFF3FFF37BBC05F79 +:1043C000DCE9A46D400EE63BD1BEB1CFEF250EAFC8 +:1043D000ACEA3F87F90DC3A76BE0E1ADB47DCF44F4 +:1043E000767FCB5C31B9E4AB4097577BD13EA3EFEE +:1043F0009798EF1F3BCDE9ED34F7E77B3E55F0BBD7 +:104400007D3D46A2D7810BA7D78111E8F5988D5E37 +:104410003F26E9E9F59D74F283D2EBBBD0DE8E171F +:104420007B5922FA76D857963F5BB01BFA93BF347C +:1044300067FBD3F4297DB62586AB19122CE7998743 +:10444000E47DE4135FEED03D03C6DF2DFA27208420 +:10445000DC34FDCE9CB11DE4D839F42BFAD3F49BA7 +:10446000F43178E75EED8DA4BB376E8F9FE5C7FF13 +:10447000C8CFEA8DC4376FF9597ECA487C73D09F84 +:10448000E29B6C80E36C7CF311AF4FD721DF7F4E52 +:104490007CF36D7CBA4B19DFE0FC2F1DCE3724B6C0 +:1044A000AC0BE4F1C662C61797DCB306F922C54728 +:1044B000B156FC2E0D95517E1B7CF4E93DAD58DFC5 +:1044C000DEDE3FC23D819529FE0F57C03CF44BD440 +:1044D0000E763E6900CFE1EE2283FD2ECC13667985 +:1044E000B99E584C67E64192C07D1297723CEC042D +:1044F0001F0DFCA0193C9E2527C922DF707EF655B2 +:1045000025AACCF7BE1CE1ED3D99E11A187F1719D9 +:10451000C0FB9A465AA7051CDE33D9FA027F1A3A25 +:104520003F9B1E5AE967E7E556F27EB23F57A2600D +:104530009FDAF97DEE9A9FBCFBD828FD34F3F61183 +:104540000EFF05F07FC49F867F29FF2F83F726FE8D +:10455000AF124AD2F27FB33FBDBEBAC9FFB7E5F78B +:104560006FA6E3CB463FE3F7B3E17BBF9FE9FDFDD9 +:104570001C4F178AEFFB79FB7B2E1CDFF78C80EF3B +:10458000ADE788EFFBD3B5A7F8FE173FCAFFBD081C +:10459000BF4FF362BCBC7B26D92794A485E3BBE65E +:1045A0007E148DF54379EA6381D2FDDCCFBA43E90D +:1045B000EE45A2ED1E4BD76E815F3592CFD7E1FD60 +:1045C0005F5FF2E2BE02D58F4FFC8DE9E047E9E87C +:1045D00060AEC8E490E2BFAC0BF4FD5FD1FF817424 +:1045E000FDDFC5E5FAD9EC82D786EC825FF8AB87B0 +:1045F000CBBF5DFC7CB2AC46927E8CDB0F5C05F2DF +:104600006AE71DD902C4BB0AF584007EC2CFB91E79 +:10461000BB022E0DAA1E6AB7534E08F0773A7646B3 +:104620005501CE4B99FAFBCFD1FAB3C341E1FBADB3 +:104630001FE59DFE3B782EE0F33B5F3BA93F5BFF10 +:10464000BD1FF54FF81D78EA93AD72DB988718EE21 +:104650006579B6B3D2FF5DCB9FFB64AEC7C227CDF1 +:10466000F2FFDD145DB1FECE57FF50F83EF333BDCF +:10467000F2453AF8EC78391B9C17F965434F39330A +:10468000D3E8297B7F869F6DAC135C8B618EFBE446 +:1046900064A6F47736F4E7ED14F11C552397278DC3 +:1046A000B3B2B8DDAE7AA0FF07781CFE8155F7D60D +:1046B000C0BEFAAEBBD40A40417E33D37BDAAA71C6 +:1046C000185F2DCA142CF933C633D5DED97711FC07 +:1046D000BD083A6E318C7BC51C9200BF3113EC06CD +:1046E0008C57A8F8778DB35DBD4188CF6E127A974D +:1046F0002C07BD7A95979D8B092E3ECB7D991B2C5F +:10470000744B825567A9DF86F5D58C5EBC3FE59C6E +:10471000EBBB7AD3DA59B599A2E14F5C9E593D0AB9 +:104720005E83018C7B19F81D3E0E5BBF9A705400AE +:104730007CFBAA041552EF7C944EC05E124B9398FA +:1047400037754D15A31742FD92D1EF5FD968C0159B +:104750001E75BDCF112EA3DEC8E3F17AB6F316A9FC +:10476000BF3FE665720C2BD2F2878773D2EE2B180F +:10477000CFAE5655872B923F54B54CFCBB1DA9BC00 +:10478000EF507091EF7FBEDED0BCE22C3E6AAB9F53 +:10479000BA7F24A8A0FD877FD7C344479B3299DF07 +:1047A000EACC0A7F2B13E56508EF9FA5E518AC0757 +:1047B0005168D987E50DF85D4D953BB01C64F589CE +:1047C000AA9E13DE69BBCDD84E4EF5D383656F6AC2 +:1047D000DCAD386E2055DE86E54256FF5CC71976A3 +:1047E000FF4A52C2F97F2CEB99B06F7A7DCB5731DB +:1047F000BE7443CB4DF8EC6E556B204E67DC4372B4 +:10480000FD0D5F55C19FBEE1EBF7E1BEBED1FF429A +:10481000F03B80FF35B91EEC2567B1187EC43BC460 +:104820007F43707460B95166F7FC2F9C75B2A7C3C3 +:1048300014BF53E0EFA5437E8D66BA07830CC9C34E +:10484000EF09FAD399E741CFC3E749C8214ABF1F0F +:104850007B4BE331A4E75A351DDF18F31DA97F63B5 +:10486000BE23C91B036F297A2AE57F5FD716BF7461 +:104870004FACC3FC9F850287D3C7EF8BE4F51AE9E1 +:10488000387BCB912E34A0DB46EEDFD9F58331EEB9 +:10489000F784C8EB801F8813DF55391CBFE78A37C0 +:1048A000A3FFB19118817BB93CE504F7C5023E63D3 +:1048B0005F9DC9B56F7B8D720C934BC2A5BD28E778 +:1048C000DC9A21F7989E5433FA74B1828EB3F5CCFA +:1048D00095C18B200F3412848B0869F905B8E7392C +:1048E0005B6265123BF3C2A142D007EAC54288D29F +:1048F00043C7E72F1C2E22ECE822FEFDF4CF5F40D9 +:10490000FBC228C385BD65B4EC4995752548CB2508 +:10491000A9720CCA3BB9DD7766EBE72F74A03E0B9A +:104920007F6696AB355CAE9EAF3CFDFFDA45D4E9C1 +:1049300000800000000000001F8B08000000000045 +:10494000000BE57D0B7854D5B5F03E73E6956426F3 +:1049500099BC278190131E12157012480848DB0974 +:10496000AF862B8FC1074609304978846700AD4E6A +:104970009596810082628DAD0FBC2A0E16BDB6D50C +:10498000DE68E92D7F8BFC83A0424B3156AB684536 +:10499000A350A56A4D04B98E56CBBFD6DA7B67CE3D +:1049A000399909A1DAFFEFFF5DF874B3CFD9673FFA +:1049B000D67BAFB5F69EB367E1CFB7183B6B2A192C +:1049C0000B3396CBD80E6D8367FC28A879ADBE213A +:1049D0001A635BF05541BCDD051E3B63158C3D98A9 +:1049E000197479A09CBEA6CBEA8476CE921C77D0AF +:1049F000C558B1F79370357C5F3C8E310DBF1D9C5F +:104A0000C5D818E8D77BBD62CF817218F3288CDE39 +:104A1000ADF740FB1C3763ED50326B84B1618CDD28 +:104A2000E59275980F9481D208EB80E7A91A7F6F01 +:104A3000C13A3C571D6C651BD4D34A993F02758F10 +:104A400083CD0BE0F81E0BAD63844715A542F3CD73 +:104A5000F06E601AB477D658FC112833B074E9D7D9 +:104A6000BF81DA8DF058A994F0989213BCC8837076 +:104A700061ACA60DE7C5A281525847EA853959B7FE +:104A800042ADBAD47A3D83211F5ACB02F36D8C55C7 +:104A90007A0229081757594E6A7018D5CBF07BD780 +:104AA000464B98015CAA993BA294C4E102334F0D96 +:104AB000B893E3E395B5C1C0445BCFF7B29C758D65 +:104AC0001AD0AF439613110E308F8F6AFF7C0F2ED2 +:104AD00067B9B3CBCE06023E07DF19602AAE47A303 +:104AE000F7CE5D33A3FDE0FD8ADDAB18CE777D5AAE +:104AF000FA38C4A379DC57BEB8D71380F7299F3999 +:104B0000026D09C65B22E0FCF2DA5AFA0EBAD7ACA3 +:104B1000798CCDC3A50C6484D00E27964C39EBA0BC +:104B2000E5BD3C18DECF659C18AE0CD44F6300D7B2 +:104B3000865A95A925F85D777B7616EA733BEAA736 +:104B4000B2115009D94EE07327FC3D0BFD0659E622 +:104B5000640F3CAE0FF3E7D41EFE5BC07C9373E1A1 +:104B6000BBC6CDA6E76F4CF90B4BC7F7D6131DA5F7 +:104B7000F1FEAFAEAD0F4C14ED4ED3FF23B49E2B20 +:104B800035E647BC5DE94B8B8461895705AE094C1E +:104B90002C8DF7F7EA97EA3C848B191EBFEA86470B +:104BA000203071484F78340414BB473B375CFA0A15 +:104BB000877A6BD9E45CAD271CCCEB0788DD8E705F +:104BC0005E0070BEB524393CA01DE1E3D56BA01D8D +:104BD0002C65B23AD566013834CE54984321F8A6F4 +:104BE000B341D8CE3F75926EBE66389AE1D5F8349F +:104BF000F345A1DFC6BBDD3EA070F607099F280084 +:104C0000AD12E4096FAA5FE73B387F0FFCC5755E04 +:104C10005E55F66C0ECC23B841F131BEDE77F4EB75 +:104C20006B60818CA842EB7E2709DEDFD1AFD33CDD +:104C30003FF3FC53505881FC0BBD51F28303BA760D +:104C4000CC1A1D1618CED8E31E77CEBB69501FC1F3 +:104C50007C6781AFCEB0711923F1FDE01CE26F33A8 +:104C60005D7CBA56FBC1019B9ECF399DCD0BCDEC2F +:104C70001E17FB5758B0BBEE013807AE516FBF0A85 +:104C8000FEFDCAC1EC8DF86CB557D54E6423BC60EF +:104C9000BD842F3F6392BE1896E17D2AC06F2673B4 +:104CA0006A2EE8E75B20A4CEC25AA6FB5334976E67 +:104CB0001DA75A951A94A380BC8C2B87C7D76B9ECF +:104CC000F76AAF9DC6037AFC444F8F66B8BC523B6F +:104CD0002803E5C80B71B88C381FB84C42660678BB +:104CE00078B25954013C7729CEC8C330A7BAD0CD89 +:104CF000818923112E2C6C07D179C25342F251AE17 +:104D0000DBC6E49F950CE5699D9D05715D6FD858E4 +:104D1000ED932E2CA345E53AB9F55E76F50994D3CB +:104D2000B25E17FA3EF50F84487428E979AED315C0 +:104D300055391D7ED84D3724CFEA3CEF5E4C786262 +:104D400067619D6AC6320DD7ADA6A58F60198C6DBF +:104D5000C626B04E7B66A00BE5BF9A362082F4973C +:104D60007ACD8F37733CFEA866960E8F290B7E1185 +:104D7000A6CEB52C03FCD304FEAA05FE524A9D66BE +:104D8000FC31E4D370298B3CA2081040FDD4607F35 +:104D900004F93699DE90F84C29B57EDEA1A76BD6D2 +:104DA0004AF097786407467521BF06BD56762BBD3D +:104DB0002F25F8043D123E5D36D427F342B653FA50 +:104DC0007E8205F323EBF0BB2D0E1F3E6BB068799E +:104DD000D80EE0E4413DCE4A7D3EE41F1686EF2426 +:104DE0003D215CD198D0F5DF016B2828C7FE407AC1 +:104DF000E2779B75E30CEC396E375F99FB357DA745 +:104E0000AA603F901DE1F3F974F2BB2493DB0FA776 +:104E1000BCA3DA2C0393C3AFC199EDB766C7EBEF20 +:104E200014386B2309F480EC4FEAF32C35E8B5E035 +:104E3000DAC23B0F1E18877AD873114832769BED81 +:104E4000A183078B1892086385F8BF870EFA5D640B +:104E500077883A1026CC7F476A77DDEFF4427D6091 +:104E6000773D8CF5ED301C1B0B764BE6430737C0C6 +:104E7000F79F1E7390FE3A55931A41E6C90E4D6096 +:104E8000C761DE5630733280D4A00863E90CF5A305 +:104E9000F52856801CC03B5BF32908EFCB3335A2C5 +:104EA00007ABC6A26E985CB6D5A720BC7E68674DDE +:104EB000426E5C385367BF5C9EC9ED0E398EC3C924 +:104EC000C229E5F17E19F3AD433D629DCA48AF00AA +:104ED0009F93DD26F95BF6333793EBCF6EFE3C37BD +:104EE0003FCFCD4CC0CF872D2BDFFA1EDAB3BF5595 +:104EF000D923B09439DEEFD2F359A1462AAF092D58 +:104F0000A6B2498CF767166CC27EDA6B5F9A732380 +:104F1000D06FF32E870FD5F2F21BFEF2830A0DE15C +:104F20000478C7EF1634DE5D01EFED432C64CF6EDD +:104F30002E62B5484FF6750AD9475B347BCD2E28D3 +:104F4000EFCDA8BE2733373EAF7B3326529DD568C1 +:104F500016A4F3D54E4EE79F1EBBC5DB8076A5CBCE +:104F600045FC625F57728705EAEC10CC9BA1FC60A0 +:104F70006467A80E5E6ECEB4123D6D16F415167001 +:104F800077C610C99CAE57C2F84E6B98A19DED8CA8 +:104F900059E9B95D81F925A053D99F33064C3A12DE +:104FA000C7337F6FA7E7B82EFC5ECD6606BBE7CEA2 +:104FB0004C6E37DFD93D8F343E8F6C733FE9FCB9BF +:104FC000E03FF33C3EF04CB81BE17F6F86FF9E4C08 +:104FD000B2C33B6C28CFE7BA7E7B5419D11779DC7A +:104FE000A1A03C9EFE85122D06F8A554AB91F52597 +:104FF000A8D73CD346011DB06A9B0FE1D93E38C704 +:105000003D5037FE6302FF2F5A3D6E9C676012D8F9 +:10501000D544DF2CF74AEC67526325977F6070E92F +:10502000F4EC8BDACECD0351FE866DB45F9AE70CBB +:1050300047707E3ABB4D39CBE5B266AD8CDB7FF372 +:1050400026AAFE94F49EF61D6C430E90FD2765790A +:1050500018EAF0DD9BA2FAD6C4D357E1323A98C7DA +:105060003E506F0FE26EA912ED1BFE675EC868F737 +:1050700099EDC286AAB2E7000D009748CD28A4B3E7 +:105080000B2D44677DB59701D39C5E26B578705F84 +:10509000F5A09013D3271E9F887263069856D8EF09 +:1050A0008C89AA270AADB7862CCC0F133FE2572371 +:1050B0000AACED4869C7A16F21DCAA6C1AE9AD52B0 +:1050C00076FB1539F87EA407E11C107608B4E7FAE0 +:1050D000CDEB8C0C8167EDFEE3AE461DDD1DA93ADC +:1050E0007E21EE5740EE3525A227C6D6D1BC0EDC78 +:1050F000944AFDBC75971271C0FC27A95FFC7E34F1 +:10510000DAB3DFB3F91C1A2DCB82789DEA6362E330 +:10511000EA774DD2D901C759A092ECCAB263D50E35 +:10512000B45F372AC4A712FEF342467B33B812ECB1 +:1051300032ADA77D0A9DD9919EFB6A9F9AEDABCFB8 +:1051400033C1AE023A67E5AC5C6F5725D353D2AE9C +:10515000B232BF92457AA8C38A7A773A3C4824078C +:10516000AECD5008AF93D40F093FA7AA540DE175F7 +:1051700024F4BE0BF7E347BE50F93ED89F6BB0E373 +:10518000F2B3B85F60BB1D0C32F86E7BA133B20E78 +:10519000BADA77D345F91D841FEDDE7188C7DFDAEF +:1051A000480E279BAF3BA4B2C14098D3420A951248 +:1051B0007FC5A11466D5E987629678FEA5597CFE65 +:1051C000B96B9845837133C3CC9F687F2CDBC1BE1C +:1051D00078B29551FB6826CC6FC5600BD1A7DC1F58 +:1051E000A7D8C2FE7EB07EDB9E5561DC2717C3FCCC +:1051F000701E1ACC0FF56549288DEA0343D9540E69 +:105200000A65523938D48FDE0F090DA2F282500997 +:105210003D1F1ABA98EAA5A191545E182AA3F2A2DA +:10522000D0A5545E0C7A13DB0D0B5553393C741921 +:105230003D1F11BA82CA4B4233A9F48566D3FBB233 +:10524000502395E5A17A7A3E32B494EAA342D7512D +:10525000BD22B48ACACAD0CD548E0EB55059155A43 +:1052600047EDC6846EA3FAD8D08FA8BC34742795B6 +:10527000E342F7D37B69B7A40A7EBC4D9BEF417F25 +:105280000750B886749C8CEF1665713DF042A67F7E +:10529000465645BC9DDD027ADCD5B35D6316D76307 +:1052A0009988D704FDCDCDE2F2F923DF3BF70C65F9 +:1052B00071BC6DF1F6EECF60A589F71B71F9C0D70F +:1052C000373D4BA372BBB5DDAF22FDAE64BE303CB3 +:1052D0009A36EA4505E5CB0ECD5A93C8BEBB37CB0F +:1052E00046DF3D98195C81EB4C2B397100E5C98C88 +:1052F000B0E7F7E3915E86E5FC763CF457BCC1422B +:10530000DB7D8D79F6A17F4D9BC8482E4ABF12D810 +:1053100075067D7A87800B636D0707123F0D2EE7B8 +:10532000FAA7630AF297FDA681B47FDF6E8F2A5633 +:10533000B46F5633A6B7FFB76F6A7814DFC7FBB3F5 +:10534000D33C8B37B367D0C42E69D5C6A740396824 +:105350009BFF9914F8644824383E15EA431F0B3F1D +:1053600083E5856D91F169505EBC3BFA0C6EE38676 +:10537000473BC6BBA07EC941B61FD9BFAC5D9BE011 +:1053800086FAC8A3FEFD4006ACA22338215DC3F90E +:10539000445AD2613EDBDF04430FEA551FB6AAB080 +:1053A0001D8AE31FEC38B4DF245EDCA3DA2766C372 +:1053B0003FFB5FEF2953F17B6B474AE6B09EF8D97C +:1053C00081EBC675821E7904D6D5DF1F553C3A3A6B +:1053D000F98DE067C0C34328E7A45F72C7862CF24B +:1053E0004BEE48F554E3905D9398E7610DE9D84A98 +:1053F00070B26F1C48FE384977005F833D7B87A001 +:10540000BBEDDDF66E62F8FE46C8BF7F15F8FE5BA9 +:1054100016E78764F07522AD8C39371F1F167C099B +:105420007C7C50CFC7E6761F0B3899E1BCC3C20E17 +:1054300082AE8271814E395F31F4A37D28E8FB5C36 +:10544000707DF75F8C6EF70B39910CAE4CCB213928 +:1054500009F47A21FAC792C91BBBD8CF98DFFFADF8 +:10546000A79CE37E5B0FC8B941C9E5DCF302DF49C5 +:10547000E597903376937FC799CDF9A6D213B0679D +:105480005724F0537B730C7EEAA9AAA71AE50D1BDB +:10549000CAC88E4E1B1609E33EA538AC95ABD80C96 +:1054A0008532C2B1B094FC0F2560675801FFD0551A +:1054B000144BA7E6B134A0FF5DF29BA7DEABE73744 +:1054C000A9EFE3FC28E9226BC7ADDC2FA9CD04FBD3 +:1054D000E5DBD9C2AFDFDD0FF7836CFA6EE18E5BDF +:1054E00075727087D74B75D93E19FD2E10EF776C0A +:1054F000584FF0748E4B6C375467F3B8C2767B9775 +:105500001FE93CFC4DE6417B2673C33B249F32419F +:105510003E29249FF8F8FD43A98F86A1EECFCE1334 +:105520007E004FEA2CF7FF3B7ACE459B0AE5D43844 +:10553000CF3E15E334A08734E4D37130F751082F00 +:105540003BE15D631C8FDA381641BB17E016C57D61 +:105550007BD8E2263F93DDDEEA477E66F64C5A7F33 +:10556000A5273823BB17BEF0A4696588D46076DB15 +:105570001417D0DFA6124F2AD6E7407D6B158C9BFF +:10558000D5C1447D8B6BCC3FEEF708FEE8E787364C +:10559000C078FBB2FC73919E81AE8358FA877AACD7 +:1055A000E4AFF6F6CD1E90FC19E7274F99E4A7FA71 +:1055B00061240F9760BFB2BF64F6CDE06C2EE76E3A +:1055C000166532FB46D2FD79DB3762BE8BB37BE7D3 +:1055D000FF570EFE68DB4EA6F33716DED36ED5D02E +:1055E0009FC1FD3416673BF5E716FE463FFA1B8167 +:1055F0000E9C83791DFF24F21727876384E623FD21 +:105600008CD29F982EE88A599508EAF1F42A8FB532 +:1056100081FAEB6097437FDBB2B9BE917C8D72EB70 +:10562000A9612897B2ACB85F477F923B2BDE3FD68B +:1056300033CAE3F289897DDC7562CEADEB7D19E872 +:10564000720E1FE17E94D6EF73BE9CD69F45D6A303 +:105650009CF033CD03ED5398FCE337F893A77EAE6F +:1056600000EF821EFC5CA55219CCA26ED8EF4DF360 +:105670002951DC07DA2DCE08EAD2EA4227C3F8A680 +:105680003DDD12C1F888FD1D85D6692F4F8BA0F036 +:105690009B5858958171CCD387F7BB8209F07F75F1 +:1056A000B0DEE0FF32C3B1BBDD9C673D08C7FBCF76 +:1056B00011A77D3EBB3B4EBB0FF972FAFCAE0D76D7 +:1056C0002D1EA795F1C702EFAE2DD5A8B29671FB9E +:1056D000B49045D6E9ED2A5D1CF477D8CFFDF138BA +:1056E00068FB05FA386873E11EB477EFEB8E83062A +:1056F000F712DF65B79521FDDEEFDBF5933B109EDA +:105700000E11AF1879CCA5A19FBE627F2EAEE7F730 +:10571000A6F9CB52FAF1CCFBE03F651BE30BA77D6A +:1057200057644489B6B213F2B7F42FCAFD30FA0FAA +:105730003D09F9D0086F397E9DC2F7B5CCA670F946 +:1057400027F428C897BF921C8830D29B7E87F230FE +:10575000EA9BD3BE913E8A7B269137723E00C721D9 +:1057600089E2BF305EC238AB2387EBA93A1BF79BB7 +:105770002AAB2A56E2BCEADC2EC5A1F3F79F16FA43 +:10578000CC1C175233BEA8080ABF77A2F59BE33B97 +:10579000A7515FE47278E9FDE4E782D7515B2BC53E +:1057A0000F8F2E50D93AEC27383A9F25F85E96AFE6 +:1057B00023DD0C61EC18C2B84287CF24F1A2A36BA1 +:1057C0009B28CE6C8EA775BFAF4FA945FD5D8B7032 +:1057D000D48D5B25E0375394CC11D43CF0DEDE70E1 +:1057E000B78761FC6BC827156137FAC5BA7E89F1A6 +:1057F0000BF63D37F92B6AEBCF54AC1BAE83671524 +:10580000E3F1D9FDF77934785E3B64436ED8951C9B +:105810008E3373381C6FC30763C81F333287FB375F +:10582000FBE48F61C3785C88ED4FA1F869CA1F550E +:105830001FDA0D382ED703DC9F7CBD889B98E37858 +:10584000B5A11506F9921653584417BF48B3B6913F +:105850007F362D66A5E7667ECBCD31F29B847F3205 +:105860007C4AF89B9FFB72F87A8ED62FD6D06F6851 +:105870004F4D6C07DF22DAC9BA391F2159DC7DBED2 +:10588000C0EBE9E0987CF457D5DAC343FAC2E712DB +:105890003EE7CA739893C3F5B8FB9A97441C4FDD53 +:1058A00080BD49BD9A66ED3D1EEB37C563D346F515 +:1058B00088E7FD53E2B1EB7284DFF03CE3B15304BF +:1058C000DD9E2B0FE56ABBD1EE91E52C81C7D3C1DC +:1058D000141606F9785DB54A7128A00FD28F47EFEC +:1058E00056C8DE8CD63B482F37D6A7907FB6B14C32 +:1058F000A5F78DB7ABA43FA3201F96817CF8BD9080 +:105900001366FF6C35530CF1F3E9A3520CF56B16DB +:10591000FCE8F76BD1BF5C65D370BC231AF73787FF +:10592000FD2AD9AFD0872F8AFEE9BBBEE1437D2691 +:10593000E9E1885F257E0BBFACFA70D876E18F3E37 +:10594000B2B92C82792A4C89C7E9B541D87F23C5E1 +:10595000815FF36EA33867CA97F70602B47F0C6ABB +:1059600065A43779FC3445F0E984C2AA59A8C7DF99 +:10597000DA6A63E8377A6BCD69E2E78EB52B292FB7 +:1059800042FA97A57FD8EC6736FB977BF8954DFEDA +:10599000E464F90CCF26A10F29AF92D10788ADC3DB +:1059A000FF881C93F2E375B1CE0985DB6E5F07704B +:1059B000489BAF121C245DBEF6C52D0FA21C4E01E4 +:1059C000FA58CF109EFFF12CEE43D86225A11FD9C3 +:1059D0002DE53AE64F94C6F1724D7071771DD97F6F +:1059E00076D32A43DE8759AF24976BBDCBAD3B728C +:1059F000B8BFC2AC77CCFCF075EB9DDAFABB4BF1CB +:105A0000FBDAFA05112CB7143A9B50FE9AE583593C +:105A10004FCC32C9D9B87E505964A47EDE1AB58BFA +:105A2000EB093BBDFF3485E73B849CBCBC3135FDB5 +:105A3000612C3F4DE1F90E61340AD14E7D332DD2F8 +:105A400042FBF295A3914E42CCD711C6757A53C949 +:105A50008FD0DA9FB753A7A472BBFC4035AD5795E2 +:105A600086F9866AE29B16B19607B28345B980E74C +:105A700016BF2505E30B13DCD643E87A691D6F6179 +:105A80000E1687573C2F847914F89EDE29B8FF2C18 +:105A900073DA07919D3A2417F1F17DD81F02DD1FBB +:105AA0003EACEEDA014B3DEC1B9991C84EEFD603AC +:105AB000A638F2B1EFBC3A00F9F6CF2CE8CBA5F846 +:105AC00071E3ED181F6EDEAD527C69CE0DAF5D4007 +:105AD00076B7294EA9A63B4BD19FD2A2A4FA509EDD +:105AE0004838EE73DB49CEB41C4BA3FD44CBDB8AB4 +:105AF000A8BB491E4AB81F807605A33057C94D720E +:105B000053C21FD6E5C775493C54B3E8E171255F20 +:105B1000695D97F5BEAEFE1EB20F90CED4F83A5432 +:105B2000B795D6D7C9527D38BF90F00FB137D2683C +:105B3000FF27F1DC2CE851E27985C073E79E333F03 +:105B4000B814DAB7FAB328EAA016318243E71B6E1D +:105B5000A2130907B96EA08B20CE53AE7BFF9E9196 +:105B60004783F87D7A2AC5F1A5DD2DF30ECCEBAF86 +:105B700013FBF7A5B94AB7DD8BFE8BF6ECF14B733F +:105B80002B12B417F62EC07B05C2BBDAC33E89B018 +:105B9000F83E2F597EC34DB946BEEB437EC34DB987 +:105BA000B93DC7FD0AF8DC88FDF5159FCD56D766CF +:105BB00025230E6FB96F2696D67AF2BF99FF243E41 +:105BC000943DFB3EC338BE592EDCA8AE640A8CB3AC +:105BD0006938E74BB68669941F64E29773C91BC0A6 +:105BE0007F04F1944CEEF415FF3FEB89FF9FF5869F +:105BF000FFD6ECC013084F1CAA5F39ED0BFF13DB77 +:105C0000A33CB10FA4F1886EBB3219E5B3C9FC18EF +:105C1000391F9927B317935673757938A53E05F543 +:105C2000441FE863AF7E7E5F037D1CEA9DDFA3C453 +:105C3000A7CB05FE97CBBC8C5DBDE765F4017F4724 +:105C400013E1EF46D5D7152CE93BFE8EF7C4DFF103 +:105C5000DEF1177C17F1D762679F90FD5E55EF4527 +:105C60007AA9F4F82FC77C9DBDEB84DC2901FC9553 +:105C7000A0BDA4925CFB21BB88E4F6372D169A6F79 +:105C800027C8EB87953EADF3BF73C94E095BB3A040 +:105C9000DF1BAF6014DFF36AEB14ACE76BA0A7B5B2 +:105CA000BEAF57C9EBB15E25AF777965CDCB25FA8D +:105CB000BC1EE9D3A979ACBDC92B4FDE79CB2B4FE4 +:105CC000DED72BAFFAE59D875EED03FC87E0FC9203 +:105CD000C989BEE681029FB27E593DC7879D2EC508 +:105CE000D5AAD39D5C6F3FA9083D5E16A4BADB49D7 +:105CF000C2E280D0F3A776F1F7EAF8C476E588BC73 +:105D00002C9EAFD0B62A6035E49384E9F91DFE538A +:105D10009EC12AE669BB683DD9D3B81F52AE5FE683 +:105D200069A78BF56417F175671FE379ED125EE9DA +:105D300062BF91516535EC2324DC6E54030AFAD11D +:105D4000337318A649C03E6198827EAE4CBFB1BD88 +:105D500084772EDBFAB18A295F35C6F7B9B89F1967 +:105D600081EF75CF13EC5F013FA5983F764D9EF014 +:105D70003FD89917F51153EB7AA523DDFE249847F8 +:105D80007197DEF7270BF364BCDDA8F7DA525842AF +:105D90003FC327821FC05E217FB32AF4DCC48E126A +:105DA000CA7759EDD6C8FFA0AA3EE7D4929EDF6716 +:105DB000FA81BD75F0C8AE49659ADEDF12C832D4EB +:105DC000F36B0B0DED0B82030DEFFB355D64785F1C +:105DD000B4B2DC502F0E8D35B42F01C0EAEB833600 +:105DE000FF9BA1FD90D6CB0DF5A1DBAE35B4BF3046 +:105DF000D260787FF1634B0CEF87B7AD36D42FD9E3 +:105E00007D93A17D8BF0239BE1F2AB3CBE7F6BB118 +:105E10007239B4CE554EFECD1697D1BF79A7807F8B +:105E200075C6B852F4ABB7BC53568AF03E903E9656 +:105E3000FCECC9E8C22CD792C953F3F33631DE47E4 +:105E4000CFD82D48D72BF603DF5E0275D7EB9B70BA +:105E50004D5B86F1F8AC8DF17C2119AF91DF77C7EE +:105E60006BAC3EEEAF4D77B15B13D0C59D799A51C7 +:105E7000CE0AB929E92819DC243D9E0B6EBB057CAE +:105E8000BF2ADCDE5078BEAB5E1F3C99605E1FE728 +:105E900059447C39F8873C6E0F8D4A254BDE43FC14 +:105EA00078BEFA40CE03F4C131AE0F8C79BA1FD55B +:105EB000BEB4F05E0DDB2FE4ED2DBE52C44B327F3D +:105EC000FAC7026E3A7F7A13F7A7A71AE0F696E4AC +:105ED00077935FAF25FD73F2A7B7D87DA57DF1A7B6 +:105EE000BF05DF22FC77E771FAE8C6AFF0C727DB12 +:105EF0004785183B84E72198CBAAE9F74DC9F6C737 +:105F0000529EC3FEB814E3B4ADB8FF5212EA414743 +:105F10007E05ED9F491FB4821E74909F801DD2A004 +:105F20007EE3040BBB558BAF5BDAF30EE673DA55F9 +:105F3000C2AB1BBF67DF67D7A7A85FCB3ED39BDF92 +:105F4000EBBEC4AC67CF19EF233B6D1AAC7FBD6EBF +:105F50007F2DE1638EEF49F84CF3F1F8DD46D08FE9 +:105F600018DFDB97CBF5F446D87F231C3DD901EF32 +:105F700000B4E7E1F9C3888EDC4AE21F0957739C3D +:105F8000AFAF72676C7E0F3B6E6C7E2F769C5CFFB2 +:105F90006AB17F9EA40E6B433FE6A9989DE0A632AE +:105FA0009E77D97CD0C62284479EBF2CF1688B6D2A +:105FB0006A47FD6C63E67C652D03D76F3BC8CF89CC +:105FC000B11CFE3ECC9CEBD0EEC9A832EAAF4CBF70 +:105FD000517F65D76499F499517FE5D71AF55741F8 +:105FE000D0A8BFFA35959BF499517F1587C69BF4CD +:105FF00099517F0DDA7CB9499F19F5D7D06D46FDCF +:106000007561C4A8BF2E7E6CB5499F19F5D725BB15 +:10601000D71BDE97456F35BC1F79F087867A45FB25 +:10602000BF1BDA2F3AF40BCAEB197DF46143BB3185 +:106030001D3F35B40380B763FEF77C420963979E2A +:106040007CCAF07EBEB0D7BED1F56B433FAC95E7BE +:106050007187E12FE2EB3D16B4A39162655DCFF548 +:1060600003BCAE8828BE28345BBCFBC94A9CC7076A +:106070006F4E3988FD2CDA66CCFF5E1C31D69BD979 +:10608000C00C940BCD401711A093A59817AE936F39 +:106090004BD94A712EB06F74B6E8D0158CF249C353 +:1060A000FE76CC7B97EB94F4E617F426E727D7BB74 +:1060B00014ECBFA8165FA71FFEF2FD66871DE976E8 +:1060C000E16E85FDBBD2733D4D7BEEDCD42FC1BAB2 +:1060D000CCEB30DBA13FC937FAC727A92E8A179C22 +:1060E0007A59F5717FA3910F571FE27182D54F281E +:1060F000E4AF33C343DAA7C9E0A286F9BEA139876A +:1061000045223AFED3043C1C5E23FF9DC27FE07C07 +:106110001E5023986F94A2A59AE9AD32CA7AC2396B +:10612000ADD4C8A76638BB7D8509E94A83BF388FDF +:1061300085E2FCA199AECC705FB1FB4E3BCAC3F3C4 +:1061400085FBD1FCC47109D076A3EC09F2EB245C89 +:1061500061DFFE26CACD64FBD9F7F395F33D5FF40A +:10616000BE5E0E7F0DFBD933BDE9B94EF4B7817D1C +:1061700069F6B399F5B0B267FF674A3AF9B53B1CC7 +:10618000C877419F93E7C198F46469A9414F76EFBE +:106190007BDF5168DFBB2BC36FF5C2FA0E65F86D6C +:1061A0005EB48732FC76AFCE0E6D01B8D0B91FD089 +:1061B000534F26B013C77BA57D1420BFC9C66ADE26 +:1061C000DEDCEE222F3F27B42FB7D24BF6E7DB659C +:1061D0005EB23FDD95BDDA9F778838D16D18871C98 +:1061E00012CF0FBA5DC46B80EDFC88B78DB68057B7 +:1061F0009F3FECF666D2BCD2C73CD58E79D42D1E1B +:106200008B47D1B0E4F9DC1B5CD69A9DE2BB1CC382 +:10621000777C9E2AC21BE06A75593FD7D3ED782F51 +:10622000A3F7C9D639DECBED5E1B0BDE8EF6908C64 +:106230000FDBDEA976A2BC6B617E0F97933E8F3E8B +:10624000FFC3C6783C78BC880FCBE7AAE71FCBC357 +:106250003A9211AC463C9AF3B06ECCF08FC7E7216E +:106260006BD8817667C899785F5C23F0AA8AF5823B +:10627000014A7445F350CF3FFE03F6E61538EE8D24 +:106280006A98F2245BDC95A54157DFFD5C73BD9CE9 +:106290006F75F6D15C3D9D9AF913ECD3CBF11C9947 +:1062A0003FA3D04ADB0EABAF14E1BD19FF3D86FC26 +:1062B000B40BF0FB1E79AFE21C2EECE37ACDE39534 +:1062C000FDECCBF22FF3F27CC3155E9E6FB841D587 +:1062D000F5937E8E7EA49FA30F7EAB35DEC4FED1E8 +:1062E00093A8DFFB0AC75BBC3DECCC5BBCBDD89977 +:1062F0009F1E1B9A81F16CE9EF32B793E722657D0F +:1063000073A671FC4DE5BCFE4381BF3F8A7B3A1EFC +:1063100015F3709ACE8B3AA732BAA7439E3395FDF8 +:106320003CEA7553FBB5D9E31FC5F96E2A51681FC6 +:10633000BA295331EC47EBBDD58F225E23A2FF472C +:1063400005FDEE18C8FD39E63CCC25D8BE024BDE73 +:106350002F9E6B45396657D58470FC9997FB8B2E21 +:10636000878EB07FE9776BBC5B11FB27E3BD08C06C +:10637000E7AFA481FC39BED546E75E17A8AE4D480D +:106380008FC9EE39A81F16A0FCA7AF7A7E0CE19941 +:1063900096D553AFEEF776EB55DF799E23FBADF73D +:1063A0003CE2FD1DA99C4EBBDC2EF29B9BDB9D10AD +:1063B000F8D92AFC1A28D751BF64A96C65223D730D +:1063C00042C8D57FFC5C33BFCF23DBE5A2EFCCE72F +:1063D0009A3BEC1D1BF371BEDF507C787E21BFCE53 +:1063E000B32F3F07CF316AE4E3DB54C2D2ABF07D79 +:1063F0009985DE675EE9D964C3BC6F8D61E63EB303 +:10640000C1386E18C755C0E3385BC357ECCB8776ED +:10641000195A171B388CCE7B4FF622DFD6F2FC7947 +:10642000F3FABE14FCE1DA08FB0B848796380FFD03 +:106430004B417F206FBE403AAFD6D82E7E2E8BE7E1 +:10644000C1225952BEA28FE76BA761BED3202E6F27 +:1064500048DF644DB014E4C6F94B15F0369FE7767B +:10646000159CDF79EE197589E73BB480AFEB4F19C6 +:10647000812C1C77C6B875DC1FF6C5D9B36A251AFE +:10648000C79C4FE07B86FE8A941C2E8753348DE494 +:1064900032F32894E7EAD47C4D584F718DF5A86803 +:1064A000273B785C92CDB730BC5F6582E8C75FCB95 +:1064B00094774BB95F96CB592B7B57D2BF2A805329 +:1064C000897A96FF01FB696B1AAC6782EB30C527AE +:1064D0005306AFACC6730DCFCEE37DFC30C9B90116 +:1064E00079DEBDFB5C3F7BF8B0E15CFFC6070E1BAD +:1064F000CEF5871F38FC55CEF54FBCEF81C3FFCCDE +:1065000073FD529E1D5583476F06F85F0544152A9B +:10651000C7D2CAEA08DF5E82DB9502CEE1CF01CEA8 +:10652000CE389CAFDA7388E077D406F386F16DE35A +:1065300039A86D3765445A482E4668DC59CED6498D +:10654000B8EFECB4778DC0713B9F7EB5280CF2E4B8 +:10655000D8F74EBB19D0DF5BD62E373E3FB9E625C4 +:1065600037C2EBD81A95EC353A17ADCB475A28E825 +:10657000EAD982C01CA4AB796BBFACD4DBE32C940A +:106580004BFA777144A5D42B29FF963E9626888E28 +:10659000D797B7651BEA522F2F77243EA7FE6001DD +:1065A00097438B1FDF61EFA7E1F8C1E60298C74967 +:1065B00091DF7072979BF661723E0D8F97D971DFF4 +:1065C000F9D61E078B921FB8DDC6C89FE59FAAE4C7 +:1065D000E13D46FC8F799ECFED4DA3FE16DCAD92DA +:1065E000DFA91EC60A015C837B16F37DB0691D0B13 +:1065F0008E6993515E2DD8A2B0B0C6DBAFC1FB331C +:1066000042B7501CC6BC4EB37E5994E4FE9C457BF9 +:106610006EA3EFE733FF6D68CF2E6835BF9FF21E84 +:1066200012F9A273C4737E5820F44E251B7D761098 +:10663000C58F32866BE7D63B27D772267D7FAD9319 +:10664000CA0FD77AA89C53A0111E96EEDEF75C3FC6 +:1066500062F3F64AD44BAF1C6C4CBB568BDBDD951A +:106660003BAEDB7F3F91BC313FB34EC07DB4C8CB66 +:106670005C24CE3D541CED3D2FB30EE131A2E77CEE +:10668000A59D5D67F2FB4ABBDB0C8F530727A42156 +:106690007DFC52C26534C045FDEA7049F6DD729555 +:1066A000DF9B667E2EF9688EA0EBF93B676E2A842D +:1066B000F15B9E7E6F4007D129F75F54087855B88B +:1066C00036B5E3FA2B98C96F18662F331D3D033D8D +:1066D000A9A877CC742BE989BDCCBF770ABF463710 +:1066E000BDEEB99DE02BE90A4F3A58D0866351AF11 +:1066F000A5EADCF75C2D6835D63FB2750C4079B25F +:10670000C8E46FF84849BC7F7BBE60202D76BEE6AA +:106710009F8CF9170B586013F7CFF3FB714E5A5B40 +:106720009FBB19F97C27E7B3E5BF7AE2BF507E2D06 +:10673000F9CFBBD3517EFDC5DA9A87E32D7B646325 +:10674000BA1FE598359C8EDFFF25A2263C473CB852 +:106750005091F9FA2ECC535B41A406FFCD0F4F4761 +:10676000F9F9DF8FD83CE8876D7ECC1175003C5677 +:10677000ECE27084FADBBC7E0BC1AB79B7912F974A +:10678000FCC7DD791AF903C2FD04FCFAA1085FB168 +:10679000D34679AD2B5E567D384C33EBA2F599BFCD +:1067A000C779C4006FCD6D6ABD3DA3E77BB084ECB3 +:1067B000C86FCDBB383E9B77717C359BECD02621D2 +:1067C000B7CDF49F5328E2BA82EE013EE45793F925 +:1067D000B62CC2E577CB4FEE1DF136CCEFC39DBF93 +:1067E0004B5786C5E99F615628C0ED545BE33C7B5F +:1067F0002FF7F57C24F8A45B2F083DA4ED8689E5EE +:1068000043750F2F97D9A2E997025C96EDB0F9C2B4 +:10681000F078D913AADF8576D46B0EBA7F62E913BC +:10682000CFBE3216E6B7F4495BCE54BE0C17CA6F22 +:1068300089AF66A4F3F2387E96FCE2593BE669E242 +:10684000F33559713C2D7D729F1DF33ECDF09CD0E8 +:10685000B6CFCEF9CD84AFB6B727A3DE6EF9C9A700 +:1068600076A487BFEC55587E49CFEF9B763C9B8E34 +:106870007206E184FA45E2AD1B8F3DF0179DFEEBF9 +:1068800051D4CE83719E73E1F1133C835041F4FEE9 +:10689000F35FC33C9A5E77F8100E4D3FBF2E1DD7B5 +:1068A000F39E7525A7FB0737E6A1DE6EB285F33CA4 +:1068B00054F2E74DDBBF43F4B8E8C5EFF0FB9C981A +:1068C000BF00F919D65B80EB5CF0C055B4CE852CC7 +:1068D00048F4D8F420BFDFF08C95D524DA0F3C249F +:1068E000F8E6BD871DB47978CFCEF87D217F50C5FD +:1068F0007D58ABC85EF98E58334868AA9F71727C88 +:10690000AD2E94717F2EDF9A45ABE69DB7907C7BD0 +:10691000BFC89F8FFC0F7030FA675F9C942FE422F2 +:10692000DDEB42DF01FD4DC0E7D8BEDDE64F19616A +:10693000F84EE4DFF2F1AF17E3C3BC53D1CFF75EFB +:106940009E719F2BCB2385D2AFC6DA999ECE92C97A +:10695000819D5B88BE3E7999CB9915919935F4BE9E +:10696000DD16CDC7F7917D572A2427C00E49C4E70D +:106970003B6D82CF8DEF619E56450FDFBDFCFC9EC7 +:10698000A4978577417B1D5FC7E9C71E7F5E12E72D +:106990005799BFB1C864CFC9D22C27EE33C909F9C2 +:1069A0003D7B2037E1F988B87C0813FC96D9228F0B +:1069B000FE3BF2F56B0E3A17B9EC091BDDEFF3C1A4 +:1069C000E3FB5FB916E8FF8336C9CF46F96BE6E70C +:1069D000A6A7AE6289F8F9839C004BC8CFF03C2192 +:1069E0003FE7F0F306FFB7E4EFA224F2F740614F70 +:1069F000BBE352A8BEFFD3A5C5B43F33C157C2D530 +:106A00002C4F67A3B190DB539EC29F97990E9E12A5 +:106A10008E924E97FC6C398DD34DCF925E253D778B +:106A2000D3AB79DD46789ADFDF827BA7DC38FE6D59 +:106A3000EB615F8EF1DAA755CACFEBD4BAD2B3605F +:106A4000DC8D22BFA7D323EA99BCDE956BDF84F2ED +:106A5000443EEF4AE1F90E9D81AEF44CDD7EE0ED5F +:106A60003D6A3A9E07E88824CECBA08C0DF483249F +:106A7000C9DB90E77E3B53B9BFAF3395FBF926A93D +:106A8000AE0121DCDFB5F2F8D2FC7557A7E3FEBEFC +:106A900073CFA019B5B81F38A4F29CA3B0DF5A0079 +:106AA000F06DE44B672759F89E7168BFEF593A15AE +:106AB000FB99BFD5089785AE9D76ECE70C5B43E567 +:106AC000C2BB6C713A81FF9660BE16D2F903A6E78D +:106AD0007B2E23BA5A62A2AB20D25582F32419FD31 +:106AE000045D95B132BEDF16F13121F726A9C366E8 +:106AF000D4623EE5417EDEE3D41E956DC2F53E2EA6 +:106B0000E265E15CA2D71540DF7ABFE987487743A9 +:106B100093EBF90F7F79ACF26668B2ECBFFE34E21A +:106B20007E283FFCAFD72EF80DD67FF5EA803FB127 +:106B30009EED27ECFD6C2EE575EE75D0BDA69D7B18 +:106B40009F1F7033D67FEDA0FB453BD7F37D767852 +:106B5000AF9BF47F6711B7175B9EFE744407E92F64 +:106B60007E6FF0D87EFCBCEDA93D7F7B53C17CBE1F +:106B70003DB02A948F62FFD6FCEB14DAA7773EFD76 +:106B8000A9617FFA55D7B3429CBBEA74B35A3C273C +:106B9000DD99C9CFA936FF66CC8FF1DCE5F25DFB4C +:106BA000EC8DF07EC2FFFE7204CAA1CEA7B8DD0153 +:106BB000F6F076E6033CF46BBDDD06F8FB086D44A9 +:106BC000E09937FBB54FC3F3243DE1C2E1D0097032 +:106BD000C075015C9A507E268347DDBF2C3C3E9EEB +:106BE0008BE32FDB339AEE198EC345F1F3E76ECAC0 +:106BF000F780F5F3E77B3F1D8176D4B9D67B533F11 +:106C00007EEEE77FCA7AB7FDCBAE97D3BB864E99AF +:106C10008A9E74DF93AE7F7503D57FEEF6D17CFB41 +:106C2000C8EFBBFF87D1F72BFFDFE2FB90C0B7DBDC +:106C3000837199CEA7BF1CC0CE63DD67FE65F1DC12 +:106C4000FBBABBED1E8BCF390AE6F73A8B5C55AD2C +:106C500024CF1F1DD85FFA1FF83E43DEC33D3D67BA +:106C600021D911D3FDDC1FD3C2CA0FE239BBB05FFB +:106C7000A5F80525EF001CDAAF2C8B509E98353C0B +:106C8000E41ECC1B9BB5DCC7EF2B33EEBFA6E7D5CC +:106C9000D4A03D77641DCC0BDA1D715B3C2DB08414 +:106CA000197E95EC3F28C9EEFBE3F8CB280F65462B +:106CB00095711F72AD693F7175ADF1FD2CF6702EA7 +:106CC000E6FBCD6AB2517ED255E6FD477F0FADF3AC +:106CD0006AB67223F7E79C1F9C2EEFCFF7633DE166 +:106CE000D03BDC7AC049EC37297748EB093747902D +:106CF000EF3F1DF042D85B222F6F759FE0C9C4BEE5 +:106D0000D4218696F075F8F9BDA3BA7E092E12EE4D +:106D1000E70B6F892733DC257C25DCCC781882E7EC +:106D20003D2BE2F08F97C67BB599B01BA777DB8D23 +:106D30002E82E30B3BF9798917AA1AB79661FD7188 +:106D40007E1FFC9971239913D67BC4C676535CC809 +:106D5000EFD73C95F1FC19A5EA798A4F60FEA27E37 +:106D6000BF8AF98BFA7561FEA2BE8EF98BFAF6988E +:106D7000BFA87F8FF98BFAF798BFA8AF63FEA2BEBA +:106D80003DE62FEAEB98BFA86F8FF98BFA3AE62F12 +:106D9000EADB63FEA2FE3DE62FEADF63FEA2BE8EC3 +:106DA000F98BFAF698BFA87F8FF98BFAF798BFA8EE +:106DB000AF63FEA2BE3DE62DEADF63DEA2FE3DE646 +:106DC00029EAEB989FA86FFFADD833867A35FB9DF3 +:106DD000A1FD04E74B86FA24CF9F0CEDBFED3D6E7D +:106DE000783F45FBC0F05EE2FFB2D2D386E718FBE6 +:106DF0000857E23E86FF99E6FB9BA11F2B0B509C98 +:106E0000D4CE5652E9447F2F94A9AC8D4A17B0399D +:106E100096EF0D0D3EDE1FE9757B781312D7913189 +:106E20009F0E40F9FFC2B82BB85F42C41766E03F1F +:106E30003520E2B42FFAE33E57C64FD3632A8B8E38 +:106E4000043A8C29547A62692C9A0D74184BA13239 +:106E50002B964DCFB3639954E6C4FAD1F3DC5801B5 +:106E60009579B14154E6C74AA8F4C62EA6B2207659 +:106E7000219585B191F45DBF581995FD6397D2F3C3 +:106E8000A2D8182A07C426D0F3E25835955AEC3216 +:106E90002A4B6253A81C18BB82DA0D8ACDA47270EB +:106EA0006C363D1F12BB86CA0B628D540E8DD553B6 +:106EB000591A5B4AE585B1C5545E14BB8EBEBB381A +:106EC000B68ACA61B19BE9F9F0D877A91C116BA108 +:106ED000F292D83A2A7DB1DBA85D596C0B95E5B1E9 +:106EE0001FD1F391B13BA91C15BB9F9E57C4EEA3C4 +:106EF000B232F6632A47C776505915FB199563627B +:106F00003FA1726CEC17F4DDA5B127A91C17FB0D8E +:106F10003DFF46EC7F51F9CDD87E7AFEADD83E2AB2 +:106F2000FDB1DFD1F3EAD8212AC7C75EA2E7136219 +:106F30002F523931F6277A3E29F61A959363C7A95D +:106F4000FC76EC6D2A6B621F503925F6172AFF2D4F +:106F5000769ABEBB2CF6319553637FA3E7D3629F2D +:106F600051D9BDFF1F97F477052C6771FFECCAEA72 +:106F7000D37D6577A6A5935C9CBE86CBC57BD33EAF +:106F80003A4072728C437390F0DB668877D18F48F9 +:106F9000C0BE6FDF98F7FAA3BDB3A9FAF81BD7A15B +:106FA0003E5BE560429F99E4EE172EE1EF64988F17 +:106FB0003847D0F50B55FB73D18EDA54DEB10CFD9A +:106FC00026B79774D4615950C4ED098F28F38B7894 +:106FD0005CE9EF43B9FEAD5B3584FFBE404EDFD6C2 +:106FE000374BE8EDEEF6033C5C5FB8BA06D079BDEE +:106FF0003EF6D3D776E7CAC3FA5BFFE0F0A2047986 +:1070000058F1F3837DEEA7F26BEAE75B7DE9E72DAC +:1070100081F7878A02138A101E56FF087C3F7E7D07 +:10702000818ABFAB52BF55F120BD346E289B8C784E +:107030002D677EF24BCE49924FB658E0B561A58DD3 +:10704000A17FB24163E41F6ED8C5F390D19F3A0D82 +:10705000E8A549D0CBF22D1F93DFA969E5229EF761 +:1070600014E1FE29F93B364B5B773C876EBD33EC70 +:1070700030E5C72F7DCCE8BF6A16FEA9E56DA6E70F +:107080002BBF9DD0EF69F64B3514093FB28FE73D1A +:1070900031B53FADFB0CAC1BF3498237B89DA83727 +:1070A000001E14879170907E4F090FD6F3DC05E522 +:1070B000AF9E3A3884F2E44E695A3EB60BA6F3DF2F +:1070C000B352ACC1D1F81CE048F92C5DEBD2281FBB +:1070D000EA6DD0031A265E7982A3F1FEB88ED78BB3 +:1070E00098B8BFD2188F706EA53CF17A9803E6A5C8 +:1070F000D43F924DE736A1BF11BBD1AFF9888DF2D5 +:1071000091C26CB59755F58C570436DA882E1A76ED +:1071100067F2FCB4B0FF653C5720F1F2F68641936C +:1071200031AFA961734919B9EB76DBC83E94715947 +:1071300089AF9EF9DB3C5FA099453661EA12E0EB2E +:1071400044427CB5EE23BC02DE4E24C1DB89DEF076 +:10715000765F91F027FA64BEDAB08CABF1E59A6CF9 +:10716000E2E7BAF5D1212B75F469F6FFB3F963E9CB +:10717000DE1399FF5C53287F67CC9787F83DBDB538 +:1071800082F066C657CDDF1B092FEC7537DD3B3C1F +:1071900067109B77393C9F27FC9E735AA690FDFD94 +:1071A0005411DF17BCB016733F197B71AD93F9C151 +:1071B000F87E69AD87EA7F5CEBA5FAAB6B352A5F99 +:1071C0005B5B4AE5093BCF2B92FC058440F97DBB14 +:1071D000055FED2E92F19FEBBDE8E7AEF9FB4B1595 +:1071E00016127DC7A64F2A22BBDD902F527BA531F8 +:1071F0001FA4C326F2CDB6283EBC4FA62170A9A17C +:107200003D2B1D19AFA3FE11F92B0D9B33E91EBBBE +:107210006BA6661BDACFDADCCF506F2FD2F87D6A0F +:1072200035830CCFAFADBBD850AF17BF1FC1B42A49 +:10723000E21B19FF02CDCDF1E2E16D3F59393AFF72 +:107240004618FF93C3367A6FC6C7097B98F6F3E1F9 +:10725000871D3E8CEF9DC4F36F503FF94795F28B2D +:107260004EDA58D80322FEA4C23660C9AC9CAFCE19 +:107270001CE57C55F37795E13E9EFDD441F1C1C6F6 +:107280006D0A0BE3DD0C5D007918F7FA9F3868DDB5 +:10729000F3B7A92C48E7ABB4368C935FFFC8501FF7 +:1072A000C647E70C8A16E179C3AE5FA6F8F0DC5753 +:1072B0006307FFFE24ECCF33313F4A29A778C45F30 +:1072C000A7B52EB460BE9D7A3817F9F5AF4FF1DF40 +:1072D000355BBCEA8F951E80F392E7DA5EA9827176 +:1072E0004EB4AA34EE078F3976A8C4F7FE7CBCDF13 +:1072F00036BEEE08F929A614063E43F9FEFEC2C8C2 +:1073000008923F6BB87FBC277C60BD886FA4579DF7 +:107310003C8BEB371E7F0321548072A2D1E6A3B8C9 +:10732000EC89AD368A17823EA07C8313ADD9162E28 +:10733000879E22BA6BB06A76FDB80D5B553FFF7D24 +:107340000CCD8EF36577AA41361AEB3C3F22BC592F +:1073500009F2F88F11BFD7AD1A4DE7A2CD795CB213 +:10736000FC08782AA88B2B2D799AC77FD9A80EAB59 +:107370003ECF5DFA6758B0CA709FD1B281F7FE6008 +:107380001C94A7FCFCEAC5333BDD24273FB43C53E7 +:107390007923941F4C0BBF6B05BCBCA806870CC09F +:1073A000BC21CBD6ED0AC5558EFF00E3FEEF3F6151 +:1073B000F3111B8ABCB1253F5D4CF1A9E4F602F341 +:1073C000F2F875344FF1E2EDC48CF24566B336E164 +:1073D0005F88F03C039C04C0C7B38CC7C58E57B808 +:1073E0006FC5F3C38DA6F3C6C7C5398BAA01DC6E82 +:1073F00092FAFAC6015C0E345A387FB2BDFC1E4ABE +:10740000F97B71528E4B792BE575CD009EC722E535 +:107410002C636D245F168AFB92973DE6E0E78B3480 +:10742000E641382EE668621B0770BE5E627FE21E90 +:1074300024EB45AC9DF4DEFBB6C8C2F612FC7EC759 +:10744000862CFADEE68B201F47E4EFD159498E2CBB +:10745000627C9ECB5B954854E7EF90BF4FC2504F84 +:10746000E8E44E0FBD60D2070B84FE5BC04CF946CA +:10747000AD463D154873D3BA96B48A3CECEE79A973 +:10748000EC2CC6BB8291E7A6D3BC155F24C13C1689 +:10749000B1AE28DE8BBCFC717E8EC93C2FF33AFA6C +:1074A0003ACF85BE9913F17EE5EE714DF396F06605 +:1074B00078B04A870709F785610ECF857B14C2D75C +:1074C0009F85BD25CF079AF1BF8805A6A39C5B7455 +:1074D00017EC334BE2F420E960F193113A0FF80115 +:1074E0006B4D77013F2CDBF6E4AC31F0FDA2075E7B +:1074F000B423BDD7654587583261FF199E70474D4B +:107500005102BD6FD2F35F179C98F05BD177009763 +:10751000053B55CAA3D0B513790461E287A630FFB5 +:107520003DC1A697555F0B3C6DC29F392A3FFFF9BD +:107530004AB8FDB3E76DB66B760DE8DDAE31CB9B97 +:107540001E768D499FE2790ED49F5DB93C3FFD13B5 +:10755000AB3F238BE4B4490EE796D37DAC520E2F9C +:10756000147A508EB300F51FD4DFDDF68B74F46708 +:10757000FCF9AE5FE451BE06EA9B61717D73432363 +:107580001FEF865FA550BED45FA7B58F407BB0EEDE +:10759000C1E7D3F5F7BD7E5010FC03CA5BA91F9766 +:1075A000AB3B06E0EF1A4A397BCE7D5BB275BACFB2 +:1075B000B14EB7719D0DB84EDD399546B1CE7736D7 +:1075C000F3F51DDFCAD73BBFC73AC31457B9E1C7AC +:1075D0000E5F98EC8E28E9F5934FAA0CF759DD76EB +:1075E00087C90E38C35AB7233C96AF7EF54D2BD0D2 +:1075F000C5E20B003E400775773A48EF2FFE258F16 +:10760000A7BEAF54E75340FF4034FDBBF07C09D820 +:107610000B686FC4E7D16D077C3E406F07F4117EA5 +:107620002B845F6BC59EE7E977B4143FCFC75C211D +:10763000EFB5D96DBAD7464319C0CFF93B114FFD0D +:10764000CDF77171FFEC7F0FF978EE6AA2FFAE0BF8 +:10765000F4E7D89A53A336CC43EE7A52213B69F92A +:10766000F5D5E9D50CCFB771BF5A7E31D76F8ADF18 +:107670004FF9350EC06B2A8C5758ACF1FBAF340F65 +:10768000CF377F80D13D3A72BEE6E7E86F77A23E02 +:107690007459481F9AD73FA598EBCDE5AA85ECEB26 +:1076A00065766E67778AFB2B868A790C2DE6796082 +:1076B000C38BB99FA113ED4A8C777FC341BF63C4CD +:1076C000D844F2BB5B19A73FAB849BC7FA51377F05 +:1076D00093FDDCD51FE13497B5D3EF224EAF9AA9C5 +:1076E000E1798637F39C744F14FC09603FB3453F42 +:1076F000476CFCFCC29B3806AC6BB6F04FBF89D719 +:10770000A3C2F86F16D8C9AE0D3FED20BBE1965469 +:10771000EE3F64391956E4876B859C9A33CEE14776 +:10772000B93E7BDC2D012CA1BF300378D539BB36A7 +:1077300096C138EB2C5CDFAFCB62DC2FB0A1A3028B +:10774000E1770998C998BF0FABDF7536BB373A327E +:107750009E9F58867E86B18C135815C1D7505F66A0 +:10776000E7EFE73DF41F33EEEACFD81F306B0AF5A1 +:107770000CC208E9A23E83F6BF33F07C4116965650 +:10778000A2B7CBAD2C6CE1E56617DDABE435FC2E82 +:10779000EC55552C9A01EB8B1E329EEFB83A6A8954 +:1077A0000EC5789135BA0FE167716A360F8C13A850 +:1077B00051CA11EECBD6F76DBEAB1F7A6AC65DE338 +:1077C000A08EF779E13CBFAB50BED06C607AA4D3F9 +:1077D000B95676402DE7F8433A6CCED2C2D46E1536 +:1077E000A77379AE44E2A50CBAD7C377B6981FF455 +:1077F000B3391DBFB727F6AB7CBF58C6E3B8BDB6DB +:1078000054F0ED5249778F1BF935827C83FC84F666 +:1078100021C06DB62893D1FD83822F1E2CE6FBCCB0 +:107820002DC5729FD9B7F1963B5894D6FDB483F01D +:1078300028C79D21CAFB8BB9DD29E721E977215BA8 +:1078400049F93C0B859FC6029284F2835B7FCCFD95 +:1078500042A6BC23309428BF6DC94EF3739D9F4749 +:1078600035C825F29B2AF6AEF9383FE59B293EA4A0 +:10787000F7D9F636F20F98DBD9F0F75331EEB61997 +:10788000EC2A45C4CBA0EED8AAD0EF5ECCEEDF3513 +:107890001CF53948EBC9742E54D8DB0B057E1DE26C +:1078A0007EAB85685F615C0DED2B84D7366E575AD1 +:1078B000853DDCB0D5686FCCDEA0B33B7961B81FE5 +:1078C000C061CA53B709BBE32D7BD77094FBE6FBBD +:1078D00002DEB2F07584F318BF573387BFB70AFBD7 +:1078E00052D2D513C53643DC4D9E3BAD4379C5EF2F +:1078F0006D30E569B9E8FE983A85DFDF29FD906FC4 +:1079000088F214D8A1745FCEB1348A839BFD939D15 +:10791000D5EEB045E7A79C9371C374844F5DBADD83 +:107920008AE51BDDF78A75D0F8C73C03C9FED95438 +:107930003D721BE627FDF9A153339C45144D11E719 +:10794000A73E7D01F3E9AFFC02D643F5D80C3F8E8C +:10795000F36CD75C2788EEBF157F36C30A7ABEF377 +:10796000EEAEED58776B9600D56FEF1A80772EBB91 +:1079700023765E5F27FBB307304FB9F33E5E7FFF90 +:10798000217B00F39FEAC4B9A5BAB10AC9DF54C18B +:107990005FD2CF5467798697E3F9EFA29CAB5D9EE7 +:1079A00016482DCEC5FB504FD0EF2F940CF4A716E0 +:1079B00043BBF401C133582E99A984ED78DEFFE56D +:1079C000C80542AF25FC9D9054A1A70A4A02F4BD08 +:1079D000F4A3433F7FC7FECFD5CFFF016BCEE90AAB +:1079E00000800000000000001F8B08000000000065 +:1079F000000BD57D0D5C5455DAF8B973E70B6606BC +:107A0000464003F9700604B140470545A51A011127 +:107A10003FD041CD2CAD4634454341ABCDDDDC7785 +:107A20000651336B0BABB7DCB2763273ADD75A323B +:107A3000412C3F06B5D26C6B4C6AA9D4C532BFB29B +:107A400022D35DFAAFBBFECFF39C739939D7416D5A +:107A500077DFFDFD5EFCF93B3CF79C7BEE739EEF10 +:107A6000E739E75E2E5DA23F371312D94B43482E0C +:107A700021BFB7B9227B752764FAC2F46877162153 +:107A800051296E838DC2F3CA24AFBE3F21A4C5978E +:107A9000E1B210329E1067BD99904BFCFE4BAA7963 +:107AA000EEB35F368FF59F99E74FAA79EE94E8BD64 +:107AB00043E97FE2B0C1FD77A439B360DE7BFE8B82 +:107AC000B8611E52345C43061372AF91E0CF8FD57C +:107AD0005B338C39B4DD648825763AEEF56D29B3D5 +:107AE000E93C6431BD2981906F9A3FD3DBE83C0BC0 +:107AF0003A64E28C25A4AA43C276C196667D311D04 +:107B00005745DBC210FC2A39BE84B469275A82D794 +:107B100007D828BEDDE1FA6A6CEF79FDB4D64DC70F +:107B2000DDA3A93FF16C1CBD3C4C72BC6CBB7C9DC1 +:107B300009FCBEA38494D4675DDE3FC426617F5DEB +:107B4000BA7330AC339ECE01B0AC61EB558FF7F217 +:107B5000F9A64792BB5CB47FE6608BD146E99DDB1A +:107B6000E2AEB5503C66AFB50F94E91C03520A9CD7 +:107B7000301F99354CA057494F4202B03E6D7B0FE4 +:107B800042DB1FB7E746138AD7F498C07D64002113 +:107B90000FFA32EA8CC9848C7D868EE989B7380960 +:107BA000BDB7C4C061EF8DAEA27C0AFF4346F84E5C +:107BB000DB903A2F9D671FE043E7B963487624E9DD +:107BC00047A9673769ACD1F4E6E4190F021E770CB8 +:107BD000B9B118AE8F30583266207D09CA8733D9C3 +:107BE00035C596CBC613BA0EB7DEDFFD56BA0EF713 +:107BF000FBB2C34BD7E1EE6772FBC2D06D32A7C3B5 +:107C000083362BCAD13E0DC57360100FE5F9845839 +:107C1000EF0BD0F98E2F4D18B08ACEF7BBE411BF11 +:107C200082E729CFFF5DB27B4EE8F32946FDE0FAFB +:107C3000B5E2318BE3F12BE01B9DC7954FE58CD36B +:107C4000FA12FD3FB1C824C093C7C5126766109EE3 +:107C500032395180A74E4F13C6DF3EEB06A1BFD489 +:107C600010C8A93607E55B8D8FD25246215E559626 +:107C70008D5184A27864FB854FA7513DF97EBDEC00 +:107C80009028AE7377BCFCE9703AEA1C5D702CA5B5 +:107C9000DB392705E87ACF6D917D5E3BC887535B62 +:107CA000DA83900A988A8E9FBFFF4DFD08FA6B45D4 +:107CB000F59C71C0C7B93EDD976D21785E2017F540 +:107CC0002495EAC346F17A1579F407B91F407EBDC1 +:107CD0002B9BCE53AFEAAF1E759244C138ED976D22 +:107CE000CA3AE9F3171FB63FB63764DDCFD92C7116 +:107CF000276EA0BF0C24032FC9F0BCB3EFD215929E +:107D0000C2A666E453ED7ED901225A9B2C1189AE9E +:107D100073D416832F82AAD6B7DB8EE96D945E7F6B +:107D2000F5D81EDBAB03FDAF212416EE3BA66FA3F7 +:107D3000D787DB6C48A705DB7FD013CAF751DB1769 +:107D4000A25E17533B164DE527D04CB2B7D0F9BD14 +:107D5000768BE3653AFF3D2B4713328890E88E69B6 +:107D6000D856D68DC6F9E6774C4278418709E17D31 +:107D700091816242F1D8D7D88DD4523C3E92FD1900 +:107D8000CFC13C060BDA89D2C43B96C2BAF7457A1A +:107D9000B3EEA5CF2BFDC3A812A0EB822D9213E466 +:107DA000AC5426FBA418C03702E72B953FCE5948A8 +:107DB000AF8F2DB47835D1D84F08ED97075B5611AA +:107DC0000ACB7A6A2FC2C8E77BDCBEE8DA18DE236A +:107DD0003BCA703EA5FF8FB654945B05D6755FAF66 +:107DE0002D3707D7A36B93B01DD37103B6555BCA6C +:107DF000B436FA9CF7335F8A033AD1F1667758BB01 +:107E00003C249A84B15F4A6BE0F6781AD8633AEF63 +:107E1000DE54E757A087E397B4698D604FCD46EBFA +:107E2000CB540EC6E70DB0CD0E5997BCFB3662A3FE +:107E30007264886BD739E9FCD3681B6ABFEFEAC26A +:107E4000DF9CEEB4DF35B85EC52F91CC2584503968 +:107E5000BFD3CAF056F4EA533E5EB93F2031FDF07D +:107E600036187C2FD3DF8FA4BAFF06F8064690A9F8 +:107E70009BD19E0652CA2CFF3EFC297F8DC0FF2855 +:107E80006D1B89017F6657F0677A7D35FCBFB33182 +:107E9000FFFA914C16835C7C74F3CD0127C5ABF9D6 +:107EA000C14183C03F28CFEB66D7E338626DBF087E +:107EB000F25AB5D3645B45D7574A790370FB0E83FA +:107EC0006F9D1DAF13290E5AC33A89F65745B56702 +:107ED00080FF29DC15E107B96DDE15A1053FF24EE3 +:107EE000BABB9BBD3B5CEF532451F9766E376841BA +:107EF0000E7AD89C3170BD2B7CAF66C7147D54CBF5 +:107F0000997B25D33F37D7C3195C6ECBB91ECED032 +:107F10003AA21FA078DFF5814CC08E972F91B2B79F +:107F2000E4804DB338D243F450D1371DC8E52090DA +:107F30004F2697951DDDB87EDBF9BC4C0F4AA9830F +:107F400006FA94DED0CD07FABDA02316C729FAAAF7 +:107F5000E869629A7B04ACBBB496EA377D8E7B6994 +:107F6000420EE84B504EF45690272A27F1B343E4D3 +:107F7000A0B6F9272DC8892E5F423931D0B63044DA +:107F80008E5C9D718AB5B807C563FC32BB66150966 +:107F9000F617DB19FFAF55DE0771F92A37FBD3352A +:107FA000743E5D75846329C5EB5C9C0DEDD8A2879A +:107FB000294049B048E72A843863D16F2507D85F44 +:107FC000883FC0FE0C6EADD6BB43F0BBADA31FB166 +:107FD000513A4DEAE88DED8014F7647B2EF0670A84 +:107FE000A7633F6C892D4F03F8DC67647EE67CF560 +:107FF0004377C2F3CEFB0C0E781E21798CDF1CDF99 +:108000005CA7E3BA0700BF0F74E4453AFE54845BF3 +:1080100006BD3C954CAC4F521467AEA17CA6F39EB6 +:10802000D211AF95F2731685DD007723CE6E034132 +:10803000EFE83A43FCCA056D5D0A49A3FC5DF4A76D +:10804000A35A6A0AE76604FAF9E973A78F60FEFF8C +:10805000EC7A1DFAFFCAE68F076B68FF19BBF33A8B +:10806000426DEFE89EEE05C0D779137DAFEB287C1B +:10807000CF6FDE8C1A6A0BD2B35EEB4FD7D2FBEB1D +:10808000291DBD14AFFA47E5121F8B7B4C65D957EC +:1080900097EB791D69481FC5DF28F67BAB279E2E1D +:1080A0002268C7AFE68714F99ECFF5603EE8010964 +:1080B000F53765AE1120879992239D84FA1BA60F90 +:1080C0008A9DA6F28E7A539A96ECA82541BBADF60E +:1080D000477BE4FA2787D1F52E4D75FB80DF05FF3E +:1080E000F3B7373FA75D959B5F29023E8DB84122CC +:1080F000B2742D76F2271DDAC9256504ED246D438F +:10810000EDA4AE8B38FD65FBCFB3F34FF2F134BE77 +:10811000C5B811EC78E87C47520BB6C23AB6DB25FD +:1081200036DFBF096FB57DDFDEA9AFD766DF5FE55C +:10813000785FCDBE7FC4EDBBDA9E133A1FD8F3EF54 +:1081400077F4F581BD3F4AA8FD07FFB6DD647B9952 +:10815000DB7BF40791D1BE2BD9FBBAF4991F756173 +:10816000EF0340B77FD5DE2BF2A5D607B51EA8E5F5 +:108170007EEC2334FE023E6D9508D8D760BC455096 +:108180008EF7A5323956F42624FE423F4FF5C197AB +:108190006EBF5C2F7FACFE538E0DF2CD1CCB002248 +:1081A00005E55DD11745DED57E644EAA5B4ACD0D4F +:1081B000EA49E566B51FE84A9EB6E9207FD555FE37 +:1081C000C0FC006D43FD4057F18E3EF5E7E9C179F3 +:1081D000FBB5C50B09A97A9CF77F519E12804E61B1 +:1081E000E4A967EABF204F57E023FA1945CEC61E1F +:1081F00060F241D258BC4FE505F1DEA74FF6D5DA63 +:10820000C1EE317B38F612A9067ADEC5EB098ABCCD +:1082100016A5B96F0AE533C4F710B75F6B5C382D4C +:10822000AE9A38E9F5BB681B6A370CC0BF30F17DE8 +:1082300061EACFF3F30352AF8DCF93399FFF8D7176 +:10824000E15DA961EC047132FF1FE48B6112C8CDBE +:108250008F7E2D01FDEA8AAFBA358CEE0ABCDCAF09 +:1082600055FC6B2CF8572A2FEED47F21DE2C2DAC39 +:108270003F6FA4A1DF7FAD1B5EA61D4AF3F43CC295 +:10828000EB1FF9AB9D5AB02FF4F7613823D6473E68 +:108290009239ECBDF16011C563EC939DFD5EE81F62 +:1082A000991FDD594F81544219FFEB75C30E3E8A69 +:1082B00078D7313EBADBB4AEEC103887C2961038AE +:1082C0004F05AF65E3C18F58711E1FB3F7747E6908 +:1082D00020C0CA7C5C0F487B71378817B74856A806 +:1082E00087DC9EFFBD1EF8535AD8F66E225DEFEA7A +:1082F000754565E6BEF43AD8418AEF8BEBC6ADF61C +:108300006AF9FD3DB03E863F867AC929533E55E65F +:1083100049BE54FBE5747C3155F467F0A315EF2793 +:10832000FA9C9F773FE82FDE9F8AF7FB0D3FE3F92A +:10833000B7E613A72F8C9DFC8362272F5258999F75 +:10834000D26E523DCBC3D5E3B7F2F1018D663EA1AB +:10835000F4DAB5CEBD1AEA652309938FE6757795F1 +:1083600079991C12A76ABD57C2F7E55431BF831F24 +:108370009B78BFFF4AF4FA9FCBE8C5E5A3429497E8 +:1083800068AD6BEF8F148FE838C90A71ED0257C4DE +:10839000A310BF97162AF23DAFCC9944D71741845A +:1083A000FA5F50BEEF292BA274594094F1F3578322 +:1083B0005F72693AC73379DF2E75DE9F49E5074B57 +:1083C00071F4FE2FD655AEF666213FB01F61ED1554 +:1083D000E4BD5E05E7ABF483CB37EA27D86D4A9F4F +:1083E000F43076A383D3E75B894C05BB172860F193 +:1083F0005E2095B5F1692CBE23696C9C318DF339F3 +:1084000032840E49413ED31F3FE41121EB463ADD51 +:1084100016A7ACFBD1B271745D8118922D513989C8 +:10842000495BB97A59889CC4A53D8A72129C6FD564 +:1084300041A0E36D9C4EF1698F1CE4722481DECD76 +:108440004781A072B045F2CA749DF3410EC2ACF3ED +:10845000CBCBE5C8ABBADFA9BBC2FDA72EBFDFA956 +:10846000BA9FE8E27ECEFD9C4FE3547C2C51F1B1E3 +:1084700048054F57609F60CF143B57DEB47A798F21 +:1084800038A8374AE026C05EEBA5018464BFF4DF5C +:1084900065E60490579B2E91DAFC012F3D73D0487E +:1084A000ED5919D83394DF35AB9DBDA97E83BE232A +:1084B000FCDB32677F909FEAE5F174FC90979E5D4C +:1084C0006DA4436F5FB65A0731CDF097D6AED6D2C2 +:1084D000796FCBF9C3BB309FB6E68583E3A42BC885 +:1084E0006B9D6A1D6B55B05735FEA9ABD8F765AAD1 +:1084F000FB97A8FA1F55C16B54F04AF1FE19B3243B +:10850000D49319947F40B8ABE94D595A679ED1E98D +:10851000CF2433C64982DC8FAD65F0B4973695AD74 +:108520003487C069AF9781BE2B72AC23EC675A1CAD +:10853000F182FFD07561CF46A7752147996A7FC741 +:10854000FAFF0CBF26E03E8BE097F7C822DC2C2B0D +:10855000786F3F785F165C54E0B7CBA07ED1E5BE64 +:1085600007D95606FB1E631FE7B0B7A90CE23465B6 +:108570009DCAF8E2BF5F92E1790BD39ACAD6C3BE17 +:108580004A813F1DEAF5D363584BFD8C0C7EAC8AC3 +:10859000D73B8A77C82EF033D323FDE98BB242D67E +:1085A00049EA33609DCD0FCAC81F6F2DCB47CA89DA +:1085B000430FF58AE6E8E8C51BE8F83D0FCA8BC112 +:1085C000AF1D5D1CDB03F289DD692CDFDB13DDAB46 +:1085D000C7DD146E36DDA5877A6DF34323B1DD2D3B +:1085E0003B57B453397EFCA5F7D0CF379BA2913EC1 +:1085F0008FA4ED29ABA17AF1589A0DEF77C7587B7C +:108600003441BCBA4A47A05E4D88E305949BDF180D +:1086100006ACA278CCA8B901F78FCAFFBBAC3881F1 +:108620008E2B5FAEC37D05FAD30FF076AF1AA98704 +:10863000FE59CB78EB1D85EDAE7FBC79A01F1DDF09 +:10864000FEB0EC584707EFEC488D2AA7787D15C19E +:10865000ECF097677B47019E7D7ABB9F4DA37C9D85 +:1086600011658994C079586D5113E9BCBDD39DCF74 +:10867000A5E506C7EFFA878CFB606F9F2DEF01FC25 +:108680007B99DBEF9D1DE53DCA43FCFDEC6FB548D2 +:10869000E75D7ADB7D105FEE8A4C96BCA8C7F5B12A +:1086A00050B79DC5E36B2A2F8BDF0CE3F79F4893F0 +:1086B00071DEE386C5E42B2AC4CD8F74CF073C95C9 +:1086C000FB94FD375D926D60681CBDAE57C11BB059 +:1086D0008EA09C1D3D087283713485B7BFF4F96A82 +:1086E0002FF8C23D34FE073CE29CC5E007C8925813 +:1086F000B60F1A5F9F115A8F08C6A94BB93D60E3A8 +:108700008E782D98B71ED914E1837CE688F70B4B41 +:1087100068FD5DD1933951162F38E393168B16E817 +:108720007A54EB39F14BD8377C5E877674F6F3DDFB +:1087300097B4833DA0FC847A90FAB93D7AEB709EA1 +:10874000AEF707BF11F5847C53E63477AD279FBEA3 +:1087500074A66CBDB96B3D99C3E3F6E2E7752E9044 +:10876000F339B9162DECD3153CFFCECB208F731601 +:10877000460C3450C4E73C6F40FEB6592C5E2BECDF +:10878000234659B4DD68FB0D9787B69A08CC53E4AD +:108790001E7AB47BF28A5C1BD0A750265A23F52B95 +:1087A0007294C3E662F032A81B2EB7E4D980BFB141 +:1087B000BD993E74F6474F1D23F50BEE9B9D5EFC65 +:1087C000E4D343287E67886FCA10FBBFBE8F56452F +:1087D0005CD1507FFCDFDA47D3F6B6C49DA0A97800 +:1087E000701F2D2BFA5610BFC532E22D2F8DF001D0 +:1087F0003DE514E627461109F7D18895AE3F3BB811 +:108800008F26FF6A10D2E7B887CA551F4A972823D8 +:108810008E977F25FB0CF4B985B1ACDE2A3F5D460F +:10882000605F8DD2D56BA5F0A8B86ADC5FF3829D3E +:1088300001FD9688AB1EF5DF910279F2ECE72390FB +:108840008F735E98FBE96F73806FA571A1FAD48B6B +:10885000CB1F9D8F186382F39CACF9750AE053F827 +:108860003B9A5F42DE29BB9FBE0DEDA609F7DB8870 +:10887000B5ED3743405E6A4C03A04E3EE7F9849461 +:10888000D4ACE0FD73963E98C1EEA7796B14D8ADD9 +:10889000085C4FE51603CACB8C876527FAC9643D8F +:1088A000FAC92F9745205C999487FA3643C3F6DFBF +:1088B000684C188FF69D919C549A89F34D33D8FBE0 +:1088C000470332E38F97F34D0FFC19D63B169F7F7A +:1088D00017D098FAAFDB7B73BA68981C919D12EEA3 +:1088E0003711526D033B305D23A1BD53EBE5D8DE5C +:1088F0006C9F6F468AE34EB86FFE6306C7523BC358 +:108900004156F0A179D37C4D6036EC43924603D6B4 +:1089100037AAE83A22A2D8B987CD14FF2A2DD1EA86 +:10892000A13E6563764DC1A7CA56360AE495F6B7EF +:108930006A69FF7C0BB3CBF3BBB1BA0FB1187D2FC3 +:10894000873E0F704E63F7D9A240DF86A2BC80FE3F +:108950006B68FFF784F51746E5D9DAB270FF7E251C +:10896000D44B009FBEFD429E4BE1847E208F0BB511 +:10897000A916E043EC94A9F0BCD764B44F54A91EE7 +:10898000CB8338F0357910E4B3331EDE53BC06E0F8 +:10899000370658018519AF1F423F750F97B33688C8 +:1089A000FFC16F51F80DDADEDB9BD907B7CCEA398E +:1089B000F7F69684FD50A57FFEC33AE4C7FCE54C6C +:1089C0001EE6D7FC09E79D6F09F4007ECC6FD00D41 +:1089D00006B95EC2ED45794D727E2B958F725DB4FE +:1089E00055A2972ABDA57A802BEB248495E7CD7FED +:1089F000F8931E9A2C361FB4062E47C179BBA78068 +:108A00005FFB66536CCA8C10BE7FB36C6B14EC6B4F +:108A10007F15E14FB7423D666184631DEA29E3C7D4 +:108A200037CBD2D741BD6696356081FDF059F7A5A9 +:108A3000C580BF3B6AF5EBA1FF68BD5D03B0D36A9B +:108A4000CD07D8A9ED8FF037FC9C0AFE503E2D9043 +:108A500098DC546EDAA34FA5CF7B91D3E7DBD70E1A +:108A60006540DD607E4A2003FC3095AB8C44E0CB52 +:108A7000AB12C60B0B36C9CE887E41B95A0072457F +:108A8000F57F1E97AB055BB63E007ABA00E469E05D +:108A9000E57249F3CBBD787DF38BC584DDBF17E468 +:108AA0004EF1FB145EA683FA9A9EC3F43900AFE33D +:108AB000F4A7FD45ACDF9B85FE84B4E9212EAE9280 +:108AC00059BC40F5291EE289AA269DB72DC43E2E29 +:108AD00080FEAC607F5772B3A737DF2FAB31A05F4A +:108AE000DAC3F5AFEDE18628908B6F5FDBF3EE30F4 +:108AF000C8B3364B56B0FB97E921A75B15D0290ABE +:108B0000D789F15115D0252A48A74E7DE3725145EA +:108B1000181D14BA5469399D947E7EFF5E4E874AB3 +:108B2000C2E9BAA50FD377AEDF5462D08F28EB73BA +:108B3000C788E7072EF0F57DCCDB4A2A378E2C94C8 +:108B40002FA77E30CFFF69D7B76FBC88F523859FED +:108B50000ADE96749B62A79DDD62827C6ED3908A4A +:108B600070F5EA539C7E3A33B32BC76A12EF5C4C24 +:108B7000E9376F93EC40E241EE15F25C83A6CD82BB +:108B8000F1E9AF642BACABF07FCAC6C0BA15B9D35C +:108B90006D94B44DB04F48BA21FD15FC0AAF738DEA +:108BA000E9C6E4CE0FF828781E93FCC82FEF1B927D +:108BB00095C5BB6D7AA8232A7AAAC6F702C7578E35 +:108BC000928649FD011F870DF49B503F88F8985B02 +:108BD0001FC4E7798F3C68EF177CCE51AF450BE39C +:108BE0008E12660714B93CC6EB12C7966FC578584B +:108BF000798E29FDB2E7B817C75DFE1C65BC9CCE17 +:108C0000F453D18B7D314CFE0B97FD09C7297616A5 +:108C10007EA01EA7D053A15B885E0AF451F44BD10D +:108C20002785AFFFAC5E9125DD316E7D88AF1B756A +:108C3000A447D02F807C82BF33E8D939B810BF89D0 +:108C400071CDA8A41FF4EE30D7153AA9AF07F32AC7 +:108C50006B0AD07F94391EF7CBC9B2F8BDBD43E291 +:108C6000B3AFA0EE05F6F415D987F69450AD0CF12C +:108C7000E74ADC56B370947504C8D72609CF1D297E +:108C8000FE9BFE3CDA29A774BE8A9C8519104FAC66 +:108C90004C4F65FE2CCE791AEEAF3C15288EB205EE +:108CA000F3971BCFFBE568A80F6EB10BF943E5D92D +:108CB000BDA8E7F3496005E4BB331E3E543A04F80F +:108CC000FF8A0ECF2FCCAAB3A3FF3BBD7EE6204880 +:108CD0006D672C4F4778EECB7733F86116D7CD58B8 +:108CE0009EBB01EAF35F45388B41CEDB574B56C83C +:108CF000BF86BF9CBBE476DA3FDCD2AB1BE07B6473 +:108D0000FD57A5C3208F582CA3DE38D73F3905FA6D +:108D10009D4DB20396388B5897DC0E72AE8D46BDD2 +:108D200053CE35D6EA98BCCD4C67FE725A3AB31B87 +:108D3000D3B8FC16D6D666C0B982F617A99F82FDB5 +:108D400075BDADDE0F79E08EEB1CEBE873AA68DA37 +:108D50001A4FE5E994C4E2F10A3D31827CEDD70572 +:108D6000EE07FCF7DF6F19500308C8170797B3BC6D +:108D70001DED0CCDA3F0B90ABD94E797F3E72AF3F4 +:108D800028F7ED83B80AFC08C7F7F4B257A640BC31 +:108D9000707A637A0C09A1FB695817A5F75C6A1F02 +:108DA0003787C907ABD2957AAB0FDB0A5E47DCAFDA +:108DB000AB4B82FD5C1AD71F0F8DCF4FBE186104DD +:108DC000B9A471BD785DC7FC0A8DE785EB547F04BB +:108DD000B833DF93A747BBC3D823A555C7FB4BD3F5 +:108DE000CDAA73732CDE57F44F7DBF12DF77D65DAB +:108DF0007AFFBC735D673D9431542186417046EF24 +:108E00002F32FDFD4D387F39BBCE603550FA1E073D +:108E1000FD827DC10699C58B46A66FC7770CF041D0 +:108E20005D61F661E2F05378768BECB0D1F17B575F +:108E30003F84E73BEE5E2B91EBA490BCEBA9D553AE +:108E400040DDCE39DC2B12E8F8731BD97914DA6DCA +:108E500056E55BEF26D8BACEB7FE5D7996527F52C3 +:108E6000D37F733ACFB71CC421D29FE5EDBBA818BE +:108E7000E50DBC9CFE673D6ECCABBEF354603BB4CD +:108E8000FEC5C244BA8EEFA5638F0D073DB24463A1 +:108E9000FDE4ACA71A3707BF6B1A74713CA5D3DB8E +:108EA000E6682BD88FEF3C8BF17AA7DC7039BD7167 +:108EB0004BB39C4870FCF6E174FC4E73346C7784C1 +:108EC000D987637C569FBFB977E190EBE0BAB2DEF9 +:108ED00033BF64FC56F03FB3716614C4ABCDCFC54D +:108EE0006E1F0A7C36455B4114E6F0733827D63096 +:108EF0007B74CA18BD611CA5DBA9B5937A407E7846 +:108F0000B7AE5DEFA0F33A769445417DE46B6D5BBF +:108F100094155A3ADE0F78687D32D8C1612504F77E +:108F20000787F9B5C466C7AD7B949FA167B53EC8F6 +:108F30009BBF817D43F0E31723D9FE3DDF0FBC7B50 +:108F40001BABB375D655787D61385F6F74468CB2B4 +:108F50000F84D70BF3D8F5936BDF1C0FF39D5EAF37 +:108F6000B302BEDFADD7E1FCF3687EAFA1F2786A51 +:108F7000233B2F306F3BCD93ED60472494DF795432 +:108F80007E8D207F0B754E7DF4E57259B891E5D743 +:108F9000F3EA25CCB715F99CE7F41523DDB99C1A43 +:108FA000E9BF4BD4757423F52B801E5DC9EB3F5B85 +:108FB0000FD06784AF07A8E541A19B22174139254F +:108FC000289F0AFF63EA078C48C41BBC484F6F0107 +:108FD000C98478A1564F32E13C945713E900BDFF94 +:108FE0006B44543FA8432D36B2F681C8A875D0FE15 +:108FF0003522C50778FF55637D07F2AC5F67D871EE +:109000009E07649B4EA2BF4E8A6B2B423750A871BD +:109010006AC00FD61AD08EA8ED505A06F33FDB3344 +:1090200008CAFDCD19EC9CB88E54637CA1B4341EE3 +:109030004886F8A5CC1473018E923B36F49804FB55 +:10904000BD65C363EE4FA39167DE86A4495A2AE744 +:109050006583621A52293C2C2391F5F78FC9D551AB +:10906000B8A626795211856FCD70F6CB08798E326D +:109070002FBD3E2083E23132C19D03FD557AF34A74 +:10908000F003DF4BED0B347270FC41891C7D5B0AF1 +:10909000C26D3A9202F1F6CD807FF7AEDB1519CEA4 +:1090A0001B33C25C2F276439D425CABDEFB54A688B +:1090B000CF88CB48F93981CB5FB9D1EC473BB75268 +:1090C00077B6533E52C14E456B81EFE339DB2768DB +:1090D000FDCD707F5FB2CC7AC288A1E2DA4BB15D80 +:1090E000DB7FAAA8E484321F5DDFF73ABA5ECA5775 +:1090F000C949794D554CA2449E4EED9DB4FDBD9F8E +:1091000060DE5A2F698B403E4CB7829F92885B731A +:1091100089B6F34D542EFA434BE5818E5BD4F0EDC6 +:109120005E508BB94A9CE5CEC378F13E2B5B0F7144 +:109130000F4379BD9FCBEB490FA98652D1844020C4 +:109140000A8EC29E1DEFCF00FB5022BB6703BD4EAF +:10915000AEAD4D5A44E5E7DBCD06C7383AFE94EF95 +:10916000CD28F0AB953CDE271765FFCDB47F9FBDC2 +:10917000EFBA5521F25595C1FCFE59BB3FE541B010 +:10918000337696AF928B7B521EA4E34B5247E7AEE9 +:10919000422A381766E0BE05DBAF18AF0D7F7E634D +:1091A00072128B53C87AE68F0D5AE2B5C4604BA297 +:1091B000289D46535CF2E05C2A8565DCCFF7E1F33D +:1091C000615C14C435B699F16CBF87B8C06E29FCD8 +:1091D00055F876193F29CA10D76B8C4407EBED4B35 +:1091E000D65A41FF15BE9EE4FA78D2C8F470A46C3A +:1091F000463BB5A881D5F51649CCDE2EDA21B1FA69 +:10920000E665FEB66105D8E48AB533D19E2976CCF1 +:1092100046FF817CCDB3BAA2FDB67FC2EFAE2DBCB6 +:10922000267BE653ECD9003200E4EF6AF19262C784 +:10923000287B7E9F11B29F7C557E01C9E8BAE770FA +:109240001C47CAD36D5AA04B77A303ECF9A2E7D30E +:10925000D04F92F36BB08EA28C236B63517E57D8A4 +:1092600065E46B695322B1D14B739B243C273BAE21 +:109270002916E1A88E04844B7F7F5D01ACBB731F70 +:10928000F4F77D103EBDE1408E9BD5698C80878BC5 +:10929000287864D583FF3967A678503ABBCC2BB1C8 +:1092A000EEE8229DF990744902984A0DE89D53E733 +:1092B00065FC31D6A0FEF3752DE27AB5683FF3D791 +:1092C0008B46B0FD42ADB76F34F05FB74F263E0A14 +:1092D000DFB25FCEF5D3A1B5DC9E1BE235C416C26A +:1092E000B7085B24B185F087789D01C8B7A672796D +:1092F000792882D97D53668C306EAA7936CA4F2080 +:10930000A5781FACD7E2E829CC4BDC2C3E56E46AAA +:109310000AAF9B8F27EDCBC04FDE3295F687CCA7E7 +:10932000CBFF01FD862E5F8CAB295D8E5F499ECE03 +:1093300064F0F74EFA92BE284F2AFA50FD407F7F24 +:10934000AE85BD7F42A39267F2293C659F8EF86887 +:10935000FF724E17885B21FF39E7B4A0DE28721731 +:1093600000BF47ED5C749E48B76E4E916EB12522EA +:109370007DBABB447A5C373555E84F705F2FF427D0 +:10938000560C14E0E4EA61C2F85E8B0B04D8EE1DC3 +:10939000238C4F5B395180D3EB6E17C6F759532E90 +:1093A000F4F7F5CD13FA6FD8B84880B3EB7F258C6E +:1093B000EFDFB454E81FE05F25F40FDAF78400E72D +:1093C000069E15C60F695D27F40F6D7B55E81F7E5D +:1093D0006AB300DFD8FE9630FEE68EDD023C821CCA +:1093E00010C6171A0F09F048EB17C2F851F15F09C0 +:1093F000FDA36DDF08FD63337F14E0E53CCE2975E6 +:10940000FC4DB82F4096A5831CA725B987F7C1BA94 +:10941000CF292DE85FEB1D128985FC67DF242BEA3D +:10942000FDCFCC030BFB70BBC8E5F80231DF09E7C9 +:10943000D9AF6617ED3C9E18298FC3F7AACED5B3D6 +:109440007A87DAAF2BF15C3475CBDA90E776731A52 +:1094500069421F84634BAC02DCDD152F8CBF6EAA02 +:109460004DE84F70670AFD89150E014EAECE13C64A +:10947000F75AEC1460BBB744189FB6D225C0E97503 +:109480005385F17DD6B885FEBEBE0AA1FF868DD577 +:10949000029C5DBF5818DFBFC92BF40FF0AF14FA60 +:1094A00007EDAB13E0DCC01A61FC90569FD03FB4CF +:1094B0006DA3D03FFC54BD00DFD8DE248CBFB9C300 +:1094C0002FC023C87E617CA1F1A0008FB47E268CC2 +:1094D0001F157F4CE81F6D3B2DF4577EE3F0E3BE74 +:1094E000D4DBEC7D57259E1B9BF983304E1747E359 +:1094F0007DA87F9348079CF7EF2ACE57E2C052C75A +:109500004FC273FFAA61F1F9AB7DD8FB690FC82C7C +:109510004EACF5BAF07C5E0C1C78A57A12ED955035 +:10952000FE20C59A8EF5C838F4B7E8326D70DE8D2E +:10953000C6411488D1D8ED90879882716CD2A5412C +:10954000D71EC736F52188C7C93EEED7402FE7D5CD +:10955000BF510C79CE5CE25D017850BF1B0DFB580A +:109560001F4688F528A51D6DA4740C79DEFE88BA07 +:10957000A48157D0DFD1C6B338BE735E5EAF92E828 +:10958000FA1685CCFF18CDBFB4544FEB3C54CF68CE +:10959000A2FD84C78AF0539E78849FF6D8B05DE31D +:1095A000C9C4F6598F03FBD77AF2107EC1E344D8C1 +:1095B000E729C1769DC785D7D77BA622BCC1E3C664 +:1095C00076A3A702DB573DD5D8BFC9B318E1D73D75 +:1095D0005E6CEB3D2BF1FA664F1DC25B3C6B106E6F +:1095E000F4F8B06DF26CC4F62D4F3DF66FF73421F0 +:1095F000BCD3E347D8EFD987F06E4F00E1BD9E564C +:1096000084DFF5B461BBCF730ADBF73DEDD8FF8192 +:10961000A703E1B37C3FE1EB3EE2BE9D021352841F +:10962000F2A0C4BFE321EF01E1C8D37D27E43DAA46 +:10963000FC43CD8F33FC39BA021AFE42FCD33363AC +:109640005D6D485EF0037FDE4391C41B41F5A1468A +:10965000C3EA02353104DF0F233C3E9FC3E592C4C9 +:10966000B1B87C36C76B0ED7835C90CF4C94CF0FCC +:109670007E4E9EA5E4DB51296E2993E2312F59E3FA +:10968000C5BA8399BD873F20C5AD85EBE7AAEF7EBC +:10969000179F677564C0434A0DFEEEB7423D69BF30 +:1096A0008C75D8AE9E57C5DF93E8B27FE7E924F00A +:1096B0004725FF90B15EFFA1CE3215EA2D3D32194C +:1096C0005D7A646A84F6AD145777C0E7647AF586EC +:1096D0007BA5E0FBFF132035A77A5E466C3A3C87FA +:1096E0004B9CEFC0AB37B7D0800FE05B89175B674F +:1096F000B23B25B33B9C97F421EC1E664809B71E8C +:10970000353E99992C7ECFCCD408ED9F525C7D00DC +:109710009FE3E94E011F732F1B3F57DFFE02E0F569 +:10972000971D3F9C90D282F456EA1B2B46F0735A49 +:109730000B25651F9CC58946A2C489D83FFD7E566E +:10974000EF51FCE5E1CE96D9C373D53AB49BD3A5CE +:109750004807C4DBE7AAEFEF0FFB8577D07C0FF655 +:109760004F153B3A9DC21A0A4F27ECDCC5F4C316CD +:109770009433B57DA5F711D8EF9B4E4906F9E3A5C3 +:10978000143BAEE743D70F3A9897C4B5E37BAB548D +:109790006E4A809EF386CAF8FD860F35BE0C494698 +:1097A00079D14B14FF3971545EC2C40B8A5C2CE032 +:1097B000EFE528D7A9BC4D047A7EB76D4826EED3D5 +:1097C000EC1C6A037AD66AD87B75DEF765762E03C1 +:1097D0004AF9706E243AEB457CBF00820BE0DF5003 +:1097E0000BBE5FD02C93C56F84B1A7F772B9FA3066 +:1097F0005E57E2C379C57DC54ACED74ACEEFD2DDEA +:10980000FB93E1BDC105FB749817919CB62C57984A +:109810007355558B1FF945EF1039AF6A3AC6CE63C1 +:1098200091B6ACD073588FF07915F992F516F78B85 +:10983000E650FC3AE57C11D095CAF90988FBC71BB4 +:109840006CD1B7D25BDB2869FCB475FFCE8AE7F92F +:1098500094737DB3880BDB3994DD20D72EEF6A7CBF +:10986000AF7E1EA9C7EB0BF266A6005C45DA8BE261 +:10987000E97CB7ACAC79279E6237A96EF548A8732E +:109880004FF4CD7807DAB2F5D209AF0DF5A416F88A +:10989000D026552FEF499F77FBA611CBA18E3C5EBA +:1098A000667C2007181FA83C39E598CBD747F5629E +:1098B00015E04FF502F157F462FA52E294E282EFBA +:1098C0008174EA49DE3D7F4E843D166D3B9E43A97F +:1098D000DA698881FAC93CC2FC76B00EC4FCB5A234 +:1098E0000767748CEF675E93F03D9B3312C1EF39CD +:1098F00074153728F127D53FA677474D4CFE655E96 +:10990000D74B71C70F4C0BFAE7331ADFE0A834F4DA +:10991000DF1B801EBA02F7A303E0BCDEEB92A39626 +:10992000E272A69B2F859D13E8F403E49229582741 +:109930007C4CC7EA76EA7857594757781AF4C40B33 +:10994000FB5952DEBB3F411C7239BEEEF8C1942E6A +:10995000B5C022A84B16B86CE1F058C69FBFEFEF18 +:109960002C1FF726133C17A4A6A76465CFE9AABE4F +:109970006A8864F8287E4AC1F372BC18BF0E66324A +:109980007BA1E0478835D34A9FAFD5463A405FCBAD +:10999000B4EE00C887527F53F2E27DF693E80FC819 +:1099A000C5DA2476FED8DF951F3EDB998FA706FD2A +:1099B000A452C722F9E1EB912EA315EDD744E24062 +:1099C0007FD1971C56E885752C197608B1CEEBC669 +:1099D0007518C05ED33602EA28E82F7DB82E13E052 +:1099E00085EB0A404584AC3645211D86B512B4D3BB +:1099F000C3600D74BD3B8E111F9CA76ABE30A5D0FD +:109A000042FB777CABC53CE819D3EB89F01D891D7F +:109A1000A73F4D847A4FCD854684079F2D3ECDEAE2 +:109A20006787A7C17C6F9FD7DB0C18072C443A28A7 +:109A300075CAB70971C03E68DE67667CCF38B7A5C6 +:109A4000DE8474E375B57CBEEEFCF3AC1EB213800D +:109A5000A1340F68D7137F48BCACB38A701E09814C +:109A6000EDF0480A87D4397E6EFE68EACBEB2043DE +:109A7000C890D0BA1AE98809FB3E957A1F3147622F +:109A8000789FC874C5F5C5B86CA2CCE8FD0F19E87D +:109A900075B3D99700F16DF3DC0D0910EF3E63FA51 +:109AA00007D2F1D9BFEB1380AE7523FE827EA48E60 +:109AB000DE1B80FC57EB8B2058FF9A8F75E09BB91B +:109AC0009F7DF6E297249ED2B32E8FA0FF24DC0F59 +:109AD0002BFD7517CF55003F2FE41B6D60173278B3 +:109AE0003DB4E6A6FF17DF16428F1D34AEF65306CF +:109AF000BF4DE36A3F8DFDB7D1B81A6078EF14DA35 +:109B0000061A5743EBA37135B42FD0B81AC6415C7F +:109B10000DEDB334AE86760D8DABA17D9AC6D530F2 +:109B2000EE291A5743FB048DABE17ADDC5F242C43E +:109B3000A795E0FBF54B4D511AB0AF14FF48A80BA9 +:109B40007DE41C1809F4B8E9BC46E06FFED9480171 +:109B50001E763C26C85FE0FFE19E42FFE09654A1DE +:109B6000DFEEBD5E807B2D1E28C0501F0ABD3FB1B9 +:109B7000A2408013DC6384F1D74D9D28C0DD5DB722 +:109B80000BE3634BCA85FEC7A3547CF4556A443E7D +:109B9000B2EF2B5CC837E3F9CAAEE4F409CE17057F +:109BA0007EF297F2D47075DBB97D35423ED093E3F7 +:109BB000B6B0AF0DAFEF3D32E4958C1CE087866DFB +:109BC0009B3ADB4DBD295F329ED410385788270E53 +:109BD000287E567EDF9305E74C20977B4AF511C01F +:109BE0009F5DCE8248809796EA1342E5A8CEEE1E8E +:109BF00088EF29B8D9FA94FB1F2F9878C57DF427F0 +:109C000040FEFA5CA17FCCBC54D087CBE8482A70D8 +:109C1000BF3648C789F87D27E2AE10F057EB0581C3 +:109C20004DFA0478AE51A4A733F561A0C3B34F69D0 +:109C3000F11C56E77CFC7E65BE91F245535BD6E590 +:109C4000F8EF72B2F134FE8D00BAD06709F8C5386A +:109C50006C23803EBFE5FAF6DF5CDF9EE17C853C4D +:109C600016606265F7297CABAB78627406E84D1E1E +:109C7000C36BDDE427243037B1C451630DA1EB532E +:109C80001C8F17F8BAD6C2BC14EE3ED92901FD527A +:109C900016BB24D0B75E4BDA107E96EB7752753B3D +:109CA0005E4FBECF8F6DCF8A00F68F9437E13A3A80 +:109CB000E9E010E9A8E6938FAF47993778FFE6FD12 +:109CC000206F179C0CFF28AFD909FE22CA6B75B014 +:109CD000D6C65B8703EC7E94D7C9E1EA2C801BF8DB +:109CE000BAA2BC5E847D7C5D751571FB37D882CFCE +:109CF00023B62A4DA8BFE94A9E9A38FD1B399DD448 +:109D0000F735E8BC83AC61F44A69157F3AB44D235A +:109D1000E8F99056D14E7D04BF303FF0495F881B73 +:109D2000BC2E99EF5F211D2775E64BD3519E569BA4 +:109D3000EE3C00F9F6E41699307F3BFE1DB09787A4 +:109D4000461BD09F368F1E951C2A77CA3AB672BA28 +:109D50000FF53A8FDC47C797B90C8021755FCEE4C9 +:109D6000FBE97CAE71B203F6A15A3AFD89CBC4CEB1 +:109D70003B307F3291E3BC7BDCA447E0F9875AA8F3 +:109D80005DB005F154FA1B4A268DCD063E06181F1C +:109D9000BBA2CF7B9C5FEF70BCF6707E3573F9DEA3 +:109DA000C5FDC90EEE4FDE067F6200BF93C7D7C365 +:109DB000FC4903F7277F047F42DB03DC9FEC077F2E +:109DC00042DB9CD169456837E12536F4273441C12F +:109DD000F3040B847529789524C9027F8AE34C0229 +:109DE000FF8ACCB1427F813651809D175305F8A67A +:109DF000F3D7ABFC94E857861D1FA6F25305023C2F +:109E0000B8658C70FFF89C49023C2E6B9A008FE974 +:109E10003D538009DF0FCB65BF93DCC8B532E6B98F +:109E20007CDF4989A70E95C8B86F33F413D911AAFE +:109E3000B7B9A4739F4C03FB64347CB16995F952A4 +:109E4000857E8CA35A74AE4438BF575346E590B60E +:109E5000F92D344EC3E223956B1AF7E6BA46611C1E +:109E600048E3A541C88776B6DFA4EC5B0D55ED3F0E +:109E7000B98AC4FDA9DCABEC4FDD747D1771597E46 +:109E8000EC35C56554BF30FE7AC674E71E909B6DF5 +:109E90009FD13815E2DCCF7E81F1D7073094EAEB11 +:109EA000D6AF7F81F1EDD64E7D710BFA92CBF5B630 +:109EB000B125B5A98DEA5B4E37C9C1498DFA92C764 +:109EC000D794736CD1348C775A34187F91922AECE2 +:109ED0001FCCEF6F685D6A12DF5B0A897B306E8F83 +:109EE0000CCA0BE4932446ECB786C8672A635AE889 +:109EF0007842AE57CD3750050F538D2F50C1635464 +:109F0000E327AAE0DB55E3CB85FEA6B689578CBBD9 +:109F100015BBAE8CCBD5BA644718BB3BB8458C0794 +:109F200089AB4A38FFD07C6436DACFC6C32B389F62 +:109F30002A043EED569ED342E99D75F9FD055AAFC0 +:109F4000A91F95878216ADA3C616E4A3C22702797E +:109F500071C87C854659D0E3A656E61FBB5AE74E2A +:109F60006EA7B7737FF3962A8E93FF7EFED0042AE6 +:109F7000278D6D1ACCB31A5B0A62F1FDC18BB31049 +:109F8000DFA6560DBE4FB6F1D5F1B7D46883F829D8 +:109F9000F8E47CB2D404E7832E507F047296A37356 +:109FA000C65AC3D05D2D5F5DCDABC82F25542CD0D4 +:109FB0006517F547787E98DB55852EBB8F3C8D74F1 +:109FC000DFD6CAF0BDB943F48737B68BFE70F8A967 +:109FD0001801CE39C6E242EA7F71DE1C7EEEEE6ADF +:109FE00078ABF502764844B8A738FE1AE3826D5C78 +:109FF0004E1A389FB64538A6867BFFA8E1A8BE2238 +:10A00000F4FB0A27AF67F5B993D7B3B83BE79806D7 +:10A01000F35CAAF7686F875AEBE4EA30F30C3BAEC7 +:10A0200051E52D9102FD7E6EDEFAE5F57CDF53658C +:10A030001FBBBA5FB18F05CA77541C93C29E930DA4 +:10A04000F2819FAF54D19338C2DBDFCBF9A69C4B92 +:10A0500057F1AF8BFB83F378D579F5A5EB619EB60D +:10A0600032F43BAB4D0BB85D5F8076FD839FB85DEE +:10A07000FFA93109AE1F18B03509F4E840AEF23D32 +:10A0800058CABD907C5AD1A3F75B3E3685C6FB63A8 +:10A0900038EE3B320F8DED1FC2CFAEF0DCC7E5E7E7 +:10A0A0005D1EF7ECE57ABE9BC73D7E887BFA803D5E +:10A0B000C8E4F680E5D16FF1B8A789C73D8D3CEEC5 +:10A0C00039C8F3E88F20EEC13888E5D10D99F7E261 +:10A0D000F7C52E242971CF786D383E8FB689766A00 +:10A0E00054BC4990B7915631DE2934260AE3479093 +:10A0F00034A1FFE68EEB55FA2DC63BC34F8979F4A8 +:10A10000D036318F1ED22AE6D1138BC478C7952F53 +:10A11000C63BCA3EC22EAB84E7B1C6E788F1CF2E5C +:10A12000F885F63718D9F9AC86CC4957B4C37E6E9A +:10A1300087FFC8F5FB3DCE9F7778FEB093D37F07AE +:10A14000D01FE3521667E69E77EF89B6817DA8603F +:10A15000F9426615E6D537725CB67AAA597C7A411F +:10A16000637650BEEC32B3386B57E6CCF3F0DEFFCB +:10A1700005ABC906F599033A37C2BB32251B7C6F84 +:10A18000508D5F6EABCACFF1784191CF5D2D5FA24C +:10A190007FDBD9716D7E5519F71E998475979B5A8F +:10A1A000083184A92F5CCDBF5EED39EAF1E0C7C369 +:10A1B000F91FF573C674B86542F577476BE04948F7 +:10A1C0008BC6F8E7CAF05DA8C1ADEE42E0EBDE4C0D +:10A1D000C90AFBE9745C21EC4BBC77F1E3B1707DFB +:10A1E000E779ADC680FB4E56C11F7D7091D21FE44A +:10A1F00025939D4FF2B77EF9487FA8F31A657C7FBF +:10A2000064D7C58171A1747BFC0619ED4A43964160 +:10A2100003F5E686F35AE20F89F71A3B52CDD036A2 +:10A2200064CAFC7A00EDC37337B073AB3BE87CCCF7 +:10A230005ED8100F451EFCE73525E1BEBFF31C7F3D +:10A240005EEEC53F9B20BF7CF77CB909ECD3CE56B0 +:10A25000F69CDC256D26A0DB818E7566B8BE2B735F +:10A2600010CEDF9CFD907920C84DAB86EDE7F0F86D +:10A270004679DEAEAC398F0E8075B7B2BC6CD7F9BB +:10A28000CD7BA2402FD64B0E16BF307BA68C6F38ED +:10A29000CFEB4D3E76CE2D97783FCD06FDE9F17B95 +:10A2A0003DC839F1569250FB576815ED4841ABCA8D +:10A2B0004FB92B511F143E946A6385FE039F4D9C3A +:10A2C0005C067C33B3F7DB769E5F1A3711F4C2ACC1 +:10A2D0006371B38FDD3F2E58AFC1F7B594EFB0D4A3 +:10A2E000643F70A814EE6F607CCD358BF81CE85B82 +:10A2F0009BB880CED7B0C5E410D67798E0FA76390F +:10A30000DE9C8E75ED2C03EA61E185BDE6B6903AE0 +:10A3100051679CD8B2DB3C08E87C5623D04DA1C3E2 +:10A32000A83C317FDC91B907C75F38CBE89E4BAAC8 +:10A330000FF567755873E9E060FE95DBC1EAE373DA +:10A340007D22DE43378AF9E77C557CA4AE9FE76720 +:10A35000CD1927E4573C6ECAE37193BA4E5EAA3515 +:10A3600088F509559D3C575D27FF67E3249D7B1ABF +:10A37000BE0F17987C4DF1C3501A6BC6E3F95EEF20 +:10A380009320D76FF1F872A8BEEEDE04AA220DB2B8 +:10A390007B38EE5BF03A9D72FF55E325AB97C40D19 +:10A3A0000EC98789F604E4972B618F13F9E265E7FC +:10A3B0005955F376156F28FB23F945CCFF3C63FA1A +:10A3C00010E38BC6AF597C013F6D3D60BF9EA01F5F +:10A3D0006EFE5A8FFB276F8F66FBDE4ABC328938D0 +:10A3E00071DF667CDE79ED6F6CB09F7367F67CDAA7 +:10A3F000BEFD5923E6996F77E69975429E99CFE5A0 +:10A40000725BBBC61B0BF941ABC14742F6DB95FE45 +:10A41000C6F6F247B2410E031A94C3E66FF504BEC6 +:10A42000BFD7B8DD8078379ED5633CBA6DBB89C98C +:10A4300035AF3F2BFADACAFDE2A79C9F07B85FDC75 +:10A44000CFFDE27BBC5EF30E8F5BF6F07A4D338F6F +:10A450005B7681DFA4ED9676AE774B4C1C4F569F12 +:10A4600055F0BCAB4FDB112DE56BD57783D7403D65 +:10A47000EA36B7A80FB74E15E3937159627C32A63E +:10A48000B7588F29494A13EE2F8EBB41E82F320F60 +:10A4900012ED9676B8003B2F8AF1C984BCB1A23C7C +:10A4A0003943E213CCAFC57CF796D07CD70E7C62E3 +:10A4B000F9CCB6D627D04F6C3B9E1A1DFA9DE0AD65 +:10A4C0009CCEDB8E33BFBCF5F0394B68BFD29EE229 +:10A4D000E3CE707E9CE5FC9894E0BC238BCACA85D1 +:10A4E000E3E7F470FEA32B3956EE57EE3BE5FB2A6B +:10A4F0002AD4EF7D0DCC08393FF46DE31719684F6E +:10A50000AE512F6A2DECBC5B831489EFE15FEDFD4A +:10A51000962559A95C29ABFBB3FDD1EA21D06ED0B9 +:10A52000B912E13DA806C9356D3EECF3FE561FF6A3 +:10A53000EF4AD46649CA39F426F00B32D76FB249D4 +:10A54000D2827C4570F045E2AECDEA0E45B16A1C80 +:10A55000249B5D04D6B545479AC0BF1327B1597BEC +:10A5600010B655469FF3976CF7C3404F29C0F6913C +:10A57000A95BC5EF7EC0112DF8FE16B4B05F663042 +:10A58000B2F70F22B3DC8FC3FCF05DDBE881306FE4 +:10A59000411ADB4FF5A39D9EC6E7D598B627E3B9D0 +:10A5A00055759EC4EDB5A2779D74AD14DF4B51DB9C +:10A5B00059A5BEBBCDEE9A162E1F7D258BE59F4D6E +:10A5C0005F8D97E1B939C62827FB3EA45386F7C1B2 +:10A5D000B69D18639A1146CEF6F69BF10AAC4781F8 +:10A5E0007302F532FF7B151AB1CEA5F103BF2F9888 +:10A5F000F5A8D74361C13197CFA7B6CF798755F674 +:10A60000B9739FBF4E8273679DF2040C01FE1F64F5 +:10A61000DFD5B89A3CA9F7EFBFC84AE5EF4D557FA3 +:10A6200001E74CE468339EB3D972D0B84EB65F9E52 +:10A630001F36F0BA9F1AFFE6CF6627621DE993D94D +:10A64000ACFE07861DBF9B563D05DED3EB8461FD46 +:10A65000D00F1FB4C3EF002D60FDA315B86A0AC464 +:10A66000AB5B47B0F19F6F0A3C0DDF05DB7A07EF6C +:10A67000278FB1F10AEC5D386504C03A568FB9E511 +:10A680003536FEE2F5CE2F803F9159CEC320A7AFDD +:10A6900082EED0B6E87AE751B8FE05C8186D3FEEF5 +:10A6A000EB6C837E05EED6D7F965687F6367DE2B9A +:10A6B000D6FD8728F1E0E1727E5DCD77C5AF5CB94C +:10A6C000DEFF2197D30FB89CBECFEBFDFB78DEFBFE +:10A6D0002ECF7BF782FFE803F9B083E7C3793C1FF5 +:10A6E0006679D7769EF7BEC5EBFD4D3CEF6DE479FC +:10A6F0006FCE271359BD1FBE3B2841DEDB2F6CDE1A +:10A700003B214FF42BA50ED1AF8CCD14FDCA685B55 +:10A71000A22A4F4E53E5C93708FD85C641AA3C79A8 +:10A72000B82A4F16FDCA8DED635479B2B87FFC4547 +:10A73000968DEF27DDAECA97C57DE4201FBBAA47E3 +:10A740002F0ACBC7AD2D8B0E5CCBBECDBFBB7EF130 +:10A7500021E7E3079C8FEF2BFB369F7C8CF9DD858F +:10A76000F384F3F175F9FF62FD6242DEA4B07C2C44 +:10A77000754C53C9DBCC2EF8F84FEAA3F9CA75A87B +:10A78000FF943ED6B6C4307DD42A75A8EFE470F1AC +:10A79000CCFF357DA471C163D9D7A08F6AFFAEBC51 +:10A7A000B7A8C40D9D71028FC7947C690BA5157C59 +:10A7B00077A22141CFBEBBA175F784B843A1D7EFE3 +:10A7C000B259BCD3F8C502D48BC1E0CFC3D0F55584 +:10A7D0003EEED56C2BB6F09E64E440382DED65F16D +:10A7E0004FF4382B3B5F4502F01DAA2BC44DAF66DA +:10A7F000770FC64B5A6B35013ECA068D17BEC34B49 +:10A8000064239EBF6B80380ACE59ABE2A82FB3ED0C +:10A81000CAF7782598F70B3EAFD4F22E9EF3FE4B85 +:10A82000B6730BCE5FE868877DC8C6237ADC67699C +:10A830008C60DF4351C75B1F6667F0F79719FDE037 +:10A840003D805F803F850FC6A2FFFD52F49F1048F8 +:10A8500050784324EB0F647F35C59B14F4D79FBF1A +:10A8600076FE69F8BE6C86B9E74C383F20ADF1C67C +:10A87000B07D4B3FEA973A6EEB32FE55C5697FCE0D +:10A88000747E0472720EFC72773C5FE5D40EECFAB3 +:10A89000FE0D91AE7BD877619C323C57A153A7FD4A +:10A8A000CD6671DC877CBE4EBA287205DFA98909A6 +:10A8B000791F5685BF42AF1507F704E028E3CF5D47 +:10A8C0008FB28E30F2E3BA4ADC7D0EE8A0961F32DA +:10A8D000CEC1DFD70D1FF7E9781C19CAFF61B82E6A +:10A8E0009FC27F327220BC07A3BCBFCEECA1F2EEA8 +:10A8F0004C8CB5CE6AA77A74678B8CEF1F12BE1F83 +:10A90000AEEDE467BE04F6495B2C91D890784F5DBC +:10A910008754C7A9EAF365F9677B0AF04DE75355F9 +:10A9200079E4F5AA3C73902A0F15ED51715CA130C2 +:10A93000BE2469AC2ACFBDF239002DD12ADF1BE23B +:10A94000FBF6920DBEC3A365140AEDE7DF0362F4C4 +:10A950005ED6451EA49CA3FD4BB60DC775EAC75A2B +:10A960006263FCF30A7F1F4A1FCFF8FBF860C58FB4 +:10A9700039B0EE6EF0CF657FEFC921BE4FBCCE631C +:10A98000FCBC4807EFD990CF8BD2F1FC0EB62F78E4 +:10A99000E2B15DEBB161FBAC2713C7ADF138107EBE +:10A9A000DA9387ED531E275E7FC25382709DC78561 +:10A9B000F0A39EA9D8AEF2B8F17A6FADDB0B7F1F82 +:10A9C000B1F74A82E74BD3EBE8F342E89CB692E258 +:10A9D000114247BBD72AC0BD16C70BE393AB6D42EC +:10A9E0007F6245A6D09FE07608F07553F384F1DDD1 +:10A9F0005D4E018E2D2911C67773BA04D8E2982ACC +:10AA00008C3765BA85FEDD370D8B6EBB823E3FE12C +:10AA1000711E013A3CEA711D29C2F7A44A105EE595 +:10AA2000998AEDDC7EDD50AF62B401CC8F6272ACEE +:10AA300060B121BFC5FDBF58AD43EA16327F6C0936 +:10AA40009D4FC097CE27D4277D389FC5E13A22E29B +:10AA50003D55B88F3E0BFDE4043E66A49C64817CAA +:10AA6000EC607E2C7EB7F5119DB53487EAF1479FE7 +:10AA7000B0EFE4C21626096347BFE6718DA99F11A6 +:10AA8000F3C5094F4998DF11C2EE9FDD92E608FD3C +:10AA9000BB504AFBD1AFD977874CBBB7D9403E26D4 +:10AAA000E4CF888D08D97F99E0FFA92801E71B3002 +:10AAB0003882CACD843533F433B382EB53C6CD7EAE +:10AAC0004AACFF06E5DF67E4711CAED3C0C7AC4AF1 +:10AAD0005A87D757655E79BFE60C5FD7291EAF9DB1 +:10AAE000E071F7715E7FFB92C76B6D3C5E3BCAEB1A +:10AAF0006F8779DCFD39AFBFB5F27DAB4F79BCD63E +:10AB0000C2E3B58F79DCBD2A7333FE9D980B9BD8C9 +:10AB1000DF25EA0A9F7B368AF1DA5C9F18AFCD59B0 +:10AB200023C66B77D789F1DACC9562BC36C32BC6C6 +:10AB30006B772D16E3B53BAA45FB38ADA250806F6D +:10AB4000738B75B95BA78A71B7C2A75B5CA29D9C2A +:10AB50005422C6DD5DADF76DFF68DC7702667E15B9 +:10AB6000E20F43BE0B2F9C7BCCB13A0B61FF2697C3 +:10AB7000B86A61BFE6464DE010EC33914F65FC1EAC +:10AB80006413DC3194EAEB85C1E326D842FC8E578E +:10AB9000949FE987C5F311B7DF27D2B5AC52AC77E4 +:10ABA000EA4B44BA3A93C4F36793547E87707FA804 +:10ABB00067BF9322D795FD90C65489EF2DFD5C7F2A +:10ABC000A427EA7364CC1FE17353857EF447C6FE65 +:10ABD000EC7DA5C1FC7D859A88211FC0BEDDEECF2E +:10ABE000D87B0694EC81DEF4FE9B08A3B7DE380A1E +:10ABF000BF23B743C7DE1FD89560762CA55D375DB0 +:10AC000064EF09900E2D9E2373C3FB23A930AF7808 +:10AC10008E2C37A015CE99E955FD89E013AF880F2A +:10AC20003B4FF79FC3879FE3E84FFAE3F988B6F0FD +:10AC3000EF1D74C6712AFF1CBCCEE456B147397EA5 +:10AC4000EF213B5D578E2A5E32F075694CD3F1FBE4 +:10AC500063864F09BE7F9FA7F1C6C277B6C8390D7C +:10AC60007EF7650411EDC2E47157CEC747C58B76F8 +:10AC700061B42D4D95F7DDA0CA0B45BB6020AA3805 +:10AC8000A78D9D4F34B09585F623DD26F78F51DED5 +:10AC9000DF417AD51C5B81E7EFB625F3F751B85C4D +:10ACA0000DE7EB1D9EC4CE2FE6F17A71DE0F8B64AB +:10ACB0000BBD6E385ECCCF312E71601C7B96F12BB4 +:10ACC0008FFE037EE69110FE013F0F8BFC34A8FA45 +:10ACD000E7807CE586C387C9D57F1E1F7E8E529193 +:10ACE0002F73CC55F6EDC2CBD788805386F783DE21 +:10ACF000B14AB82FFD4EA03A00DF89FC319ED5271E +:10AD00001E4A9AA865DF6D719A4752BA17F375E625 +:10AD1000F17DB1460F09405CB2C563C496906A3CB0 +:10AD20001FBD227E512CF8CBC61477229C076CECF9 +:10AD3000DE6D199C1368D0754B0AF71E41B36E087F +:10AD4000FAD7C6E6042D7C577E84D6AA85FB462416 +:10AD500095CB90278E82F74DE20026B81FB6C5E34B +:10AD60000F14E1B950379E1FA2EB2884F8B5C83AFA +:10AD700003FFDE63F32754FE6D101777C37DE3BD39 +:10AD8000DDD9F96B83959D6F2D8E63FBB0390EF67F +:10AD9000FDBE9C24B3C307D3C5B3EFF854D07F974F +:10ADA0005283FE81EABBF07D9F212404B6237F04F9 +:10ADB000F839357F54E71157B4F273736DE1F76BCF +:10ADC000FECCE309E57CFB611E4F7CCEEB3F0779AF +:10ADD0003CB182C7137E1E4F1CE2F1C45E1E4FBC05 +:10ADE000CBE3897D3C9E789FC7131FF07842910B7F +:10ADF000C34A6233C07BB4C904EBF2F1CB245F09D0 +:10AE0000ECB3BB196C98C5F64F7B25D5B90AE2A007 +:10AE10005FE718057239D53B12D6113FBDBD02C69A +:10AE20002524E96D4E3BBC9FB40ADF2B51DE0B9B02 +:10AE3000C5E5E6367731DADD595C4F88BC3617F365 +:10AE4000D33AF1FB71096E5DF0BB49F4FF0C157D3F +:10AE50006F537D57492F317BF1BE6277079141A136 +:10AE6000748FE7748F98C1E90E2F5D85D197359C5B +:10AE7000EE0A5D9A6F1A6661EBA810E2C243F963AD +:10AE80002C206F2D497C3EFEBE8C8B3F6722D70F56 +:10AE9000655E657FF6F1822B9F6FFA888FEB848168 +:10AEA0002FD121F3143CA883EF92DFEAFF6532E84B +:10AEB00049F07D1A07C6E123E5FC3F423E1DE0EF65 +:10AEC0001F28F6720AE1B4523DEF90E7CAEFED1C7D +:10AED0002A18AB83EF764FF6FF12FFDE83415B1D2E +:10AEE0001F7ABEB785E3F750D9BDF877E00229EDA8 +:10AEF000F8BE9AC165B0417CDE2BC9B11CE8179F32 +:10AF0000D456C4EBA12A7FB5B6390EE4AB1FFB368D +:10AF1000E2FF072D97429600800000001F8B08007B +:10AF200000000000000BED7D097855D5B9E8DAE79F +:10AF3000EC3364E484C98326B813A658194E263826 +:10AF40000987B003C1460D7002018284709230C43B +:10AF50008A367632BD8F363B24246110F03EEB8377 +:10AF60004AF080436B3FEF355AEBEB40FB4544E53D +:10AF7000BE673128B4D8DB62982CB7AF03566BC7D5 +:10AF80007B7DFFFFAFB5CED97B7312A085567B0BBF +:10AF90009F2ED65E6BAFF5AF7F58EB9FD63E6DA56B +:10AFA000255903A98C2D0DAFAB645319FB00FFCCC1 +:10AFB00066CCC354632097E11FC7070AFC3FCA341D +:10AFC000753A3EC7279676F64136FEBF9985D3E09F +:10AFD00079E5C7FF83A533B6983507FAE0BDFEC211 +:10AFE000C0281F8CCF6A5C67B17F2EFCFD20273EF6 +:10AFF0008F2C1733F5AC79BC9420F4F78A3AA3F977 +:10B00000E27568EFEA669A671854FE04D08D86F7F9 +:10B01000B14D83E72A4BF34D86792B3FEDD5A1CC7B +:10B02000C974D47B605D0BB33EB5928D843EF33D15 +:10B03000BE09005757A8E8270550EFD2D769B83C9A +:10B04000ECB70EFAFDB0ECBE2C6D721CAEAECDAC02 +:10B050003402F374657DCEBF360DFBBDDF1AC17EB1 +:10B060002E56D30BEB3A31E7FF65669BFA3F3DADB9 +:10B07000ECE6C02818B002FE3786B189EE484E6073 +:10B08000F2C5EB65CC600CBAB495263356C8D8E946 +:10B090007A25EA01406ABA017F53B1FD42133E8F1F +:10B0A000747BB42D0820D353E7C33AD77014B0C8CB +:10B0B000848EA23E58EF9A6E4E37F6A0EB34E2CF64 +:10B0C0000B7F11BF59CDEA6933FE224C3D6DC66F2F +:10B0D0000D33B543DD8D7300BCE581B4916FDF0C9A +:10B0E000FF2E60051F3839FD11BF35A26F52FDE2FA +:10B0F000610CD6C3FC80BCE28BD7B5FC774ED6374B +:10B100008211C3B0A2F8F337578F4B8EE07BC8375C +:10B110005EC157D388669A1BF82A199FE460C9DB81 +:10B1200061692F105FB5B8E27C96836CE63262707D +:10B13000E758C66308EF52731DDF37F4E3E301FEFF +:10B14000958CF3C7CA505325F227FB0CE72F2F3CF1 +:10B1500014E3C4F90FC6A90ABBE27526E8355AC044 +:10B16000097F96943FD6FB6F30FE633BF3E7235F86 +:10B170002DF9829339A15E0DDDB05E5DA344A380FD +:10B18000D3A5A15B889E4B6DFC9D5C6D1DFFAD0D35 +:10B190000534CEAA4A180769B1C1D44EF0ED247C1B +:10B1A0005631DF26942789D7B7B3D97806787C61E2 +:10B1B000F7BABDC82FE71EF0300FAE1BDF05BCD6B7 +:10B1C000730AB2E3691CAE9F6E56A2FB61FCB3BB6F +:10B1D0003DC4776FAF51A20CE9CF7C4FA0BC76077E +:10B1E00032689E734991BD9F87F686AE9480017840 +:10B1F000EB1EDE7C4F18E63D9711A9C3711ABA6E9B +:10B200007618D83FD9F0E6E0B80DCEC07E9862B986 +:10B210000A381D0E25FCFB0628EBBB4DF482FF8E81 +:10B220000614E2FB050E16E94DBD987F92F2149AC2 +:10B230001F11EE31C1BF20C741F09E78D043F0A668 +:10B24000E469344E7D30494F4A473A325DCD077844 +:10B2500032F5B108E75905E413F8EDCC12C540FC0E +:10B2600030800BDF77DF70FD3E94A727C43ACFDE36 +:10B270003F632CF2F3990CDE7EDA9F1CC5759DD6D8 +:10B2800078DDF0A7461F477AA891DCA5697C1D0AE6 +:10B29000F0418380AB4173E84940DF860797DD8545 +:10B2A000746EF06FBB17CBE369469A02EFFF74B779 +:10B2B0009321BE111FDE7C6C2F5987ED76BCFC3AC2 +:10B2C0009043EB41FC8D00BCBDBDAB3D2D82FBA688 +:10B2D0008F45DCA3E378A8DFF9BFEF53F07DC6F715 +:10B2E0005FAF90138599F663E0DFE59ADBA8807184 +:10B2F000D8A1F1C4B7CB7D9CFFDDC59B46E5F06EC0 +:10B30000A931FED0A8BE0DF7F70651AF47BE05BC68 +:10B310002E4779998AF8183E1DF79B9AD5D67D79E4 +:10B32000D3C88DF72F8675AE09BA9813DAD7F855BA +:10B330000B5F57B558F91CD66DA9FBF218D1A17B4C +:10B34000B8E0CF4ECE9F8C85C786A7C4F9E2CB016B +:10B3500007E107A1730D817F3B5E3F6A78388DFC62 +:10B360000AE7CD992C6D6F318C77A61EF887C3C57F +:10B370009C2679A8EFF610DFC3CEEE463C017FBADB +:10B38000ABA6C4F945E2A77E571BF163BDE0BB86BF +:10B390006DC03FE9263EB2E10BD7ACCA79C6C5F90C +:10B3A0008CDA13F0D977021C6E297FF52C5CC79CD0 +:10B3B00017CBB52C89CE2548CFBB6A8C4C1CC52039 +:10B3C000BAEE282D1946FC2EE8A1C6E9E145BAA53A +:10B3D000CBBAC18EE17E9E26EA192DCA9BE505D027 +:10B3E0005FD0C9533E10ED83A6E12DCE37CB475039 +:10B3F0001F4D85FE23043ED881194F4F1C1D3F6F02 +:10B40000D2C479A03A33C7607B3AB3EA3D236CEBF0 +:10B410006785AA3837F839FB80CB3706F7E364B184 +:10B42000BFAF9B374EC17E0F280AED3F9E0AD5C2A3 +:10B4300027AA4D8FC9C97388FDCE90FC4DE7AD5B3F +:10B44000E83349631C2417BFC984035589E3C3CD7E +:10B450008760C3FBB4DE3E68AFF37B035186F0F236 +:10B46000F3A10C88D067E2AFEACA14D66782639E64 +:10B470006F84A5FE71FF0D96FEB76AE32CEDB7E76A +:10B48000DE6C699F1F28B0D4DDCC74AE239C031CF6 +:10B49000EF6E816753BB3C97FB918E8BC53A76B8B4 +:10B4A00023FE30E06BB17F2DD1A3ADF4137ED44BDE +:10B4B0003D7E4E57B7D0279326ACF6911E51C9E575 +:10B4C00027087F910EED38C898389FB96DE7AD5DBC +:10B4D000FEECFA64631EE83D2950F918FB18E93DBB +:10B4E000A9C313EA3776FD0DCE0807F26BB2A0D7D9 +:10B4F0003C672A9D1B5DD55C9FEBCA5DC4F5A5DC4E +:10B500004F125D17887ECC7090DEBA54AC5FEA5F54 +:10B51000AFB532D60747F38E12AE672D0D5EA83653 +:10B52000EBE5B2DC82FD26C5EBC9A17DBA9E40CF1A +:10B530006C13FC95A2F3F6A55EA6E23924DB378AEC +:10B54000F376A938B717821C23DF86B1349DCFDB91 +:10B55000C538DB63FCCAFAF361DD4E013F7B4A511B +:10B56000110F49A2BA8F45B6E715219E0DEAE44CAA +:10B570000D3392EF3F0176A1DF02D1AF2C6F75CF73 +:10B5800067817F3DD56901B42D3CC1FAC7BF54889E +:10B59000FA514AC0A1C5F99DEC0EA88FCCE5FC5E1E +:10B5A00093E90D50B3A11F1B0FE3558BF66A21CF12 +:10B5B000A35833C9C145768C97F3E5E0760CDF7F5D +:10B5C000E47C1EB1AF30E78600F15D98EFFB0EF82A +:10B5D0008B7CB7A4C6CA57CB2243F3596F9ED0AF1A +:10B5E00067B019C46791F5C4171ED167C7D88361C6 +:10B5F00092F7A09391BC0BFB46EA9D47822F12FF66 +:10B600001FC91D50F5D438BF487D7C41C8A947B13A +:10B61000BD9825FBE01C39E21AC87C00FAB954D663 +:10B62000A7E2DE2BF4F2F4E0B2DB7CB0AED78A5FA7 +:10B63000F19D4A6583EAF3767E9F08FFC07D7EF325 +:10B6400084B7FD08C76617345D8FCDBFAA4178B6B1 +:10B6500063BD04FB9FAF2983F6ED49B2FEEE2E6C6D +:10B660007F2299D77FF5CC1F771921A207F14D8A48 +:10B67000C0778AD4CF279BF00678F68ECCA77DC4FE +:10B680006BC3A75D6F770A7DDB69937FFBBC67A502 +:10B69000BC0B3A0CB6EE8BE005D6FBD8D07CFF8B0A +:10B6A0003C3A0F9B2D7C7FF1387DA49FAF10EB7649 +:10B6B000A41CC88A2490DF18FED7BB7E6EB6070094 +:10B6C000CFDF5450AFD5E1EDE99C55701C25F8F261 +:10B6D000EFF17C577619C3118F4EE880E7B80B2C39 +:10B6E000408447CA6312F28113F1DE47ED709E0E6B +:10B6F00028E370905A1FF2A702FD3F40FC5CEE3E2B +:10B700005861B513DDB87E18CFDDCDCA3CE9683786 +:10B7100036EEDF5C88E7983B40FA57F78532A41392 +:10B72000B4EB1E2A2FE8747EFB1D9673E585D23F8D +:10B730009C7F1458B3B3DF19F0C07B1DD800F074A0 +:10B7400086BECD50BF7E77320BE0E2EB22BE796E33 +:10B750000DE5A1EF44C784387C275A597FB92B5E89 +:10B76000EF3F98E4D660B111E35E2FD2E5AD0DED69 +:10B77000539E433B3BE8F1A1DED6BFB1DE40649C63 +:10B780001863F4224EBBD40843FBDDBDE17FCEC37A +:10B79000FDF384CB080C87B27BE3CEBBF1BCD2B502 +:10B7A000CA8A6C807B7FB75A114D60CF7C229FEF95 +:10B7B000AF475EB873FF66F4378C710792609E01E5 +:10B7C000F45F00FDBA5C46168E7FA2AD3D0BE5A38B +:10B7D000ABBE2B7010FBB5790234FF6E6F0D8EDBA4 +:10B7E00095B5D6BFD634BEF70677333EEFBFDEED54 +:10B7F0001E47EB7927CD0FEBE8DE50300279B373AB +:10B800008C7B6C23B637AC631AE8856EBFE142FED1 +:10B81000F2AA6C17EE0337FA2F7C7F06DA439A639D +:10B82000FAC7A1FF7D8148793ED0B1A6E5D43CD8C6 +:10B830000199BB3C63139E3F9D024EB90F49FA0E1E +:10B840008C69F062BFCE4823F7B3F81DF548E78551 +:10B85000631C61DC7F3A436BBC13C5F375E917E3E6 +:10B86000A513FD2AD3104E58D714ECF77E6B04FABB +:10B870000D64B96B12E13122F0E86D5F97D302706D +:10B8800077EEF6FA103F9D4A64573DE0CBC84E0D67 +:10B890003CAE5DFCDE53E23DC91F402792C34F3CE6 +:10B8A0003B7AB7311EF5514E47C08BD7653A179F8B +:10B8B0009E56B626DFE4BFB868DE319D741E742A3A +:10B8C0005CAE9F7A76EA6E03EA8140E46E7CAFABB1 +:10B8D0001B78791AAD732CEAF383C9CF8068EF6CBB +:10B8E000F3D44413C8FFC06A279B348C97D74139DF +:10B8F00071A373AC92003F03590D39D9781E40BB38 +:10B9000003C619D8EDE5253CCF81E76F0EC29F53E2 +:10B91000F2F9793E796AB81DE9CF2647C88FF772E8 +:10B920005E7813D5D94E3FDA171F01FEDDF321E112 +:10B930005F3A0F23F937137F31DF708B5E3AD8FE01 +:10B940001916FB715BE91F9AF0FCDF5AECD13C261B +:10B95000BF9FD4939327737D243CE1B100ECDC6C52 +:10B9600071701D3F2F2BB9FFCF077F13F9FFC23630 +:10B97000FF5FB2AD2EF5CF43F9423F117A70A6B604 +:10B98000333C07ED8B579D8128D03D0B5F1889FE16 +:10B990003125DA976D82F726B78097EB6B0BC57967 +:10B9A000F4A3562F2B9FC06276DB72B18E054DEF4C +:10B9B0003C8676F402A16732243ECC5F3D999FDF3E +:10B9C000D26E5B849D814597E772BB002C2B7EDE97 +:10B9D000382B8B901F1632AB7EB788D9F4B9D55C63 +:10B9E0001F93F6DA0A9BFE60B70BAA6DED3B60CEA3 +:10B9F0007ED4FB54B04600CEF782053B0A00EEBA77 +:10BA0000E0A14D0309F69BE378DEC07ADF68D5DF5D +:10BA1000EC80736753F5D7BD03F0FE56B5D78B7234 +:10BA2000B2B5F2D36928275B6B9D248F475B2BA8A7 +:10BA3000DF6BAD612AFF2B3F23E6FFEA93F601C0DF +:10BA4000B120A0BF8FFB8AD4D3AA2BCBDEEC30D1A0 +:10BA50007751F9AD967A3854F56687DD7F897CE6B3 +:10BA600064CD89FC6E530BA47F45B7F83999F3A9CF +:10BA70004024417F59021FBD67C6576A8155BF3DAB +:10BA8000129C3B6C28BD46AE5BE24BE243B60F0610 +:10BA9000EF6FF2A51DF297C19B7385F0DAE194F088 +:10BAA0000FD63F8C9B5909C2DBB6DC48453A46F2BB +:10BAB0000B00CFD515192FA14FE20D95CBD31B7AD3 +:10BAC0005AD400785E9ACCEDFD945C16453FAE9D4D +:10BAD000CE2915F5F3705FBB14BD93430AD9A14B72 +:10BAE0007425AAC33F6F1176E996C98CECD2B6D201 +:10BAF000AF1D4E2BC478878B897DA672BEC98E4A36 +:10BB0000A9E571881D6E16E8C3F7A6A40636C2F330 +:10BB10006A944394CFB0EBB4D90F0276D069B31CCA +:10BB2000D9F79B145BBCA1AA40E8DFD301EFE3E2A5 +:10BB3000781FCC0E198C4FC07A28C2F3CA8EA77B0F +:10BB40006CF8B1C723C207AAACED9769FFECEF2EE2 +:10BB50007C6924EA1BE54A6002E0E3756C82F79297 +:10BB6000F56728ECB1B940F0A5B0EBAAA55DB70820 +:10BB7000EC7920C111D40B86515C692CFAA5E3EB5A +:10BB8000E3765C20A07FBAA06870388E89F7BAAAE5 +:10BB900012EB0BC7505F98C6CBEBA09CB8686E56F3 +:10BBA000227DE1587123D717A01DF58463BB2B7844 +:10BBB00009CFCDFA02AB28B8045EDA68BD49130A92 +:10BBC000872592BBD7A7457622BFCB7A4A6E332B07 +:10BBD00037F149539EFE4001C535B8DF41CE07E736 +:10BBE000FC21B33E669FEF997C1FC773C5083A37A7 +:10BBF000647929FAA9BE66867CB6D5A5D7609CC0B3 +:10BC0000EE377AA680C727BA73F4266C67A9F9972E +:10BC100018B74DEED7B979A34D7E4B9B5D28EDA8A3 +:10BC20007DD868B20F551FB70F93332F1CF241D345 +:10BC3000DA82C8F388AF5917A286A310E3A90AE9EC +:10BC4000519E4CE622FFC9E5DA6397D9AF7B23DF2B +:10BC50007FBA1AB8DFBD2C4FA57A72C4B99FE248EB +:10BC6000C25F1316CB48D6DF217B6C01E803C23FCD +:10BC7000437AD509E1D70AB36617DA7DA9AEA8974A +:10BC8000E2BE36FF4C4DA6A36F22EC1F35C10BD58B +:10BC90001AC539ADFE9D1A2DE7D028D1EE83724129 +:10BCA00098FB7B96A2BF07C7AF8E76E7E0BE165023 +:10BCB000033AE3F61E9EB7CB1AEF9BF29076F5FCA3 +:10BCC0003DD28F24F546E9AF82F3A57B04D265AE61 +:10BCD000A2910FC0E60FB2FB7FC2C21F63F713D958 +:10BCE000FD42BF2DC8267A483D4CFA6BDE2FB0EAE4 +:10BCF00063FF09E281FDB614C35106F2BDC5C5B2AA +:10BD000076C2F8E9FAB2DB705F7EADEC151FEA1B74 +:10BD1000FF5960F3675EE6FEF663D887CEA0BEF6F5 +:10BD2000E21817EADD55CDF5E437B4CB89BF90EFC3 +:10BD300073C985A99678717F6B8B783FC9C0F3A6CC +:10BD40006ABC3B9A046BAAD2F938972B4F1979FA3F +:10BD5000C8C25164978CC69205C02E99827689908C +:10BD60007BC1DFAC7C143B638E937AC15E4933C3E5 +:10BD700021D67185F3238DCDF35C0A6F3B4A4BBC12 +:10BD80006EF447002C4ECE57BE989F3E07FD3BEB0E +:10BD900035B35E5187F18902D43F158A53C8E7262F +:10BDA0003FB98AFC9B9C19D1C309F6D5E5850E4B9A +:10BDB0009C34E667CF65141792E3A8CCDF46728007 +:10BDC000B22AE17126F0C70B781B259FB380D78379 +:10BDD00071DE6D4EC6F30FB89CC8B8835A1CAEC84E +:10BDE000C6F8F02625601014358750BF5F2DE4C8D3 +:10BDF0002DFC70F678D16A2957CEF5A4A735EEB49C +:10BE0000C6D1EC7131BB7E2EFDFA2A4C82707F5E6A +:10BE1000D2090E78E7D078D847EBFC3BC583E4C362 +:10BE2000CA82BBFC98BFD29914D9558FF1EB1E2F53 +:10BE3000F945BAB00BCA4B1FFC457F7B4FF0D12DA3 +:10BE4000F05E77A193DEEB54783ECBA1319FA3FD4A +:10BE500043F259B7E0B39B0A35EAE7C57D09448848 +:10BE60006572BB56E6AFBC3686EBABEE10CFFF7902 +:10BE70002AF3D0EB65042DCF63C90DC5F358CA0072 +:10BE80003F5304FE7227AC263B764A88E7B14C7ECE +:10BE9000CE6AB7DE9EEBB2D473ED76ABADBEA750E3 +:10BEA000EC7BB6FC95783C6D11E961127EBB5C7D44 +:10BEB000B595C755BE06762B964FB5FAA8FCD75652 +:10BEC0003F95BDAD1AE969CFB6E672BFBBC0FB5660 +:10BED000D7053A17CF65B9290F42FA29A5BFFC3B10 +:10BEE00085DC0FC5421C9E85624DF39C996918E75D +:10BEF0003A1AE2FAE160FBCCE20A6B3C6F49D81ACD +:10BF0000CF5B56638DE77D7AAA7EA010F5AAC9BFE4 +:10BF10007BF551E479117F5A23F0B0E3211E5F9243 +:10BF2000E31FFD02A7BFAC9F1378F83EF207C68F50 +:10BF30000E8A7DF4C1AA5B681FF5E55F965E785CAA +:10BF4000C867CA469F2B00E357F52D77E3386B7619 +:10BF5000C138A9973FCEE609A3B3ACF1864FDE8185 +:10BF6000EF1F8DC51BEEB903E30D4745BCE1FC7324 +:10BF7000CD5F467BEBA642FD27880747A17E12CB0B +:10BF8000F308CF28AA0FE0B922EBF0E770C6E8214A +:10BF9000FDFAE70B13F8F59D739584F6E93B85DC14 +:10BFA0009E86F3EB97F81EF3C6FC6A17789D9F53A5 +:10BFB0006A119FBFFD47AC09C769FF366B7A3681AE +:10BFC0005EFFC742458EF73B3A0FFDF23C0CFF2166 +:10BFD000D1784E4FD558C4F73917CF83B18FA716F4 +:10BFE000B9E5788E227C2733069F5A641A6F07E0E2 +:10BFF000A01FE9A4FAD2288EC9EEA678A7E4A394DC +:10C000003ADF7CCC53000393E13E93F2BC6F7E2178 +:10C01000E6D9FD605CE07136385D7F26F8EBBC90B8 +:10C02000B3B751CE409ECEA29C41791AE50C9E0F2B +:10C03000A09C4179B23540CF7FDC1AA4F247AD3ADB +:10C0400095275A2BA8FC416B98FA1D6BADA1F2F510 +:10C05000D6083D3F5AFEF55B289EF69442795583FB +:10C06000C173D757ADF27567D42A5FEB7659E56B8C +:10C07000CD4E6BBCBCB1DB1A2FAF37ACF1F2552DF6 +:10C08000D678F9CAE69996FE2B9AE65AEACB23B7F8 +:10C090005BFA2FAB596CA9EB455C5F5C125E617972 +:10C0A0006F7145A3A55FCA22164944FF8A22CE9F1D +:10C0B000074305C30686D877DC2DB7FF04F59458EF +:10C0C0005D8D30D4EBDD2D0BE8F9D6A4705D38C161 +:10C0D000F875457CBFEB2C5F1D9EC3D0FF7B8BD3D7 +:10C0E000ACFFAC9F16595464B273DD7E6E97BD3BB6 +:10C0F000FEBD17F1985854FECE4BD7E139D5CF028B +:10C100000AF0950E6A9F1FB6EC22A3CD791DD4AB21 +:10C1100033C18E34ADBBF833FBDA47C3F399EB5F21 +:10C12000983B12CAFCBC485D11DA5115A7DAF1FD43 +:10C130003995792A8ACDD60C467AE9B9096EB27753 +:10C14000EC707FAA48B1C4B3AE749FEE6CB5C6E57F +:10C1500073FC3CFE95E3E7F12EA853BCEBE9699133 +:10C160004F217CF09CE25E5D596B73703F192C8E01 +:10C17000F490A097F42B48B8769472788E8A78C39E +:10C18000107E852F168D1A1CEE73220ED1F5254FC9 +:10C19000C2F8CB3911873827E3100F2D4E18873896 +:10C1A000374FF815A01DFD09E776D7F0725EE390D2 +:10C1B0007108B93ED88F1EA4FD27168710FABEF06D +:10C1C000A3BF3E4DFF5FB88EA63C7D17F67B7F8AEE +:10C1D000BE1BEB474DF150DF68533CB4FC154B3CA4 +:10C1E000F499FCC83E7C6F226E693064BBC1069234 +:10C1F000C6617C367C4F223EFE9722A967F7FD453B +:10C20000F15A535CD5F1C1CDECB2E30297DD2FC8F2 +:10C21000F350EC7A4E0A620486E8C6AE70CE3E5900 +:10C22000183988EBEFC8785EE3F9568EF8FE8187FF +:10C230009F7679F3250B3B15CF2B3CB78E81C4E05D +:10C240003EB33DA399FC2AFD026FF6F28D22414FC9 +:10C25000E61B89F47DB230FC3AD28F3DD7AB511E3C +:10C260009B78CE722FCF5E7DC21DFE09EEEF9D73CF +:10C270009C1ACF1B64E4BF9894EB8BA27E2BF5B085 +:10C280005FE27E49F92803E3DDB0CE76FDC554CCEC +:10C29000FF7E6B8F8A1930EC2B69CC8570877361B8 +:10C2A0007F8375CCF1476E1C6A5FC4041E4790F80B +:10C2B0004271F8A91CC14B43C1E7F6FEAFED796F9F +:10C2C00014EAE55FE9E1F1B0493DABBD0DA6F173BC +:10C2D000A6F37DA73393C35FA72B512D1BE1B9F0C4 +:10C2E000FD19186FD11CE4EF786BC36F8E2F43FFDD +:10C2F00063C8199840F577A9DEAF390A307EFD96FC +:10C30000FFD7C7B1FFA42FAC194DB68EC0C7AA0D79 +:10C31000054F203EEE0B4494E9304F7FE8DDB471C9 +:10C32000A678DA2A858513E93163A673BADDA637C4 +:10C33000DF81FBE66DBA87615E737F9987F0FE95BA +:10C34000598A86F6EE42E475680FEF51C98F0DF8F1 +:10C35000588FEDAF065218CE3B477F46C5FAFB53C8 +:10C360001476DD10E7F015E335F4EE2894C3B790AA +:10C37000FF12C0FF4BB96F0A399AA882DCE723FE8F +:10C380000FA59AFD95929FFEA9501F37BD08FD7F0E +:10C3900091A630E9B98B2EC1871B093F0BBF1AA5A7 +:10C3A0001884E7B1E6EB5982FB0DAF09F9B03F2FD6 +:10C3B0009CCECFC95F0BB998D4F3DEABB7629C7942 +:10C3C000838BF2116E2A0C4F47786276D755DE3791 +:10C3D00064BE5A7F5021FB0DD4699AA71F245005D3 +:10C3E0007A2529C9014E4FEEA7F38AFD0FFAE9C35A +:10C3F000A0DF2AD6DB87FE3EA6EA3B9DD07F73B145 +:10C400008BE8BD6CA52B0DE9128F9F052CF686BD20 +:10C410001C1071B3CE562FE56BF47738B99E0F7FA1 +:10C42000401387461EB767C6948775F8E713228FB7 +:10C43000F493C15B1FC67C9AE30E5E6F08DE7AC37D +:10C44000468C7B8F6D3EBE04E3160F2881360DCBE4 +:10C450007DBB1A30CFA345095440BDAEEFF37E74C7 +:10C460008935747848C73FB56912E989EFFA990FA1 +:10C47000F5C46563B8DC34F6B3A8233B6EE79ECC05 +:10C48000E2F113B463E74DC76D97E3E39F5BFB08ED +:10C490007E4F0B8F9B0C0FF0B86972BF1A884297C2 +:10C4A0008F6F7B87ECE0B0DFAD219E47301E578950 +:10C4B00064A606300E1AF4F3B84AB27EEFF125F006 +:10C4C000DEF07295E7B70D707BB809FEE2391261B4 +:10C4D0008136DC9F465458EDE4425B7C459E6F1EDE +:10C4E000FB7315EC5178DE36DD7ACF6330FFBD2C5F +:10C4F0009F033D02D7F7BC88E77E13F475A4D3B73A +:10C50000415FC7F200E8EBF8FC7BA0AF63D907FA04 +:10C510003A9607415FC7F210E8EB58BE0CFA3A961C +:10C5200087415FC7F7FE0FE8EB58BE0AFA3A3E7F35 +:10C530006E16DF473AB3DCD18D8067EF9F808B01A9 +:10C540002F9D2EF663E42FA3CCA3F17C7CDEAF2BD2 +:10C550006322EDF3FD4AE4138CE781688F633DEDC0 +:10C56000C21F7F85F54DD964873055FBE600F4EF97 +:10C57000F87C76600B54BBDDFCBC1F38CA7CA83746 +:10C580009C5EA24C45BDE9CC7CA55701FDA67FBEB3 +:10C5900042FAC44414BDFCF83E5AF29EB61FE76B43 +:10C5A0004F63821FF7F5E8C07FA71126E2D7B43AA0 +:10C5B000B48F677B643DB90EDBEB5B1461A7A6EF1C +:10C5C00045FEED92FD8DEB7AB07F87AD7ECC21EB01 +:10C5D0004D7BB07E3C365FFD0A1CEF788E6C6FA8F9 +:10C5E000D5E1CC184892F3CD5C89FDFB15D93FAF5E +:10C5F00007EDE43359B2FFDA15D87E2666473FB619 +:10C6000092DA47F1FE93BE3BE211B49BAFF678EDB0 +:10C6100011BE3FC33EA69BE33A2D25DCBF10F39F1E +:10C62000EA8AC57F2AFDF68E94DAEB30EEE6D9C8A9 +:10C63000F3B406B20275785E0FE64735F9F9C98F93 +:10C640003ABB24767FC0EA2FD5159E47EF6311CB06 +:10C65000FD369127EFCE34F9ED84AC5F8EFF50C6E6 +:10C660004BA4FFB0461FDA7F5833CBEA3F947912D0 +:10C6700083F90FE57D04E93F0CAFB6FA071746AE24 +:10C68000CC7F58CBFA5C686F315D2179A9F5F5BE96 +:10C69000341AEDFAB31AF90F9976381ABB7FA0D184 +:10C6A000309A633ADE23E3F5D3772B7EB41FB6DCF2 +:10C6B000AD8CC6F2E4DDCAF5284767EF567C2857F3 +:10C6C000BF98C1EFB7149D0F1CD6705FF53B021CDD +:10C6D0001DE12FE03E1C5E9DA16D41BADEAD0CC791 +:10C6E000FE2B3F93E1C6F303F44B21371F3C8C7CB8 +:10C6F000E54C512CF5C2B1924FF73C8C72317B84E2 +:10C70000E4C3C57BB05EE696EF7F710FCAC9F288BD +:10C7100022FADFBB07E5F0F81CD97F782DF65F32EF +:10C720004E8EB7770F8E3F3B45D61FA4F6EED878D6 +:10C730005FA3F97E882721D5B7EDD1C7C37C55E229 +:10C74000DC323E46E377D6CAF7EFE92983F1568813 +:10C75000738A191F2739273F33BD0F7A3AD4FF5DFB +:10C76000EC030D337EBF02E5E68E58FBEF69BDB5E5 +:10C77000A2BE7AC6937B30DFECEF7E7D7FE5F9ECDD +:10C78000F595AC7FDE758571B9B09F8BCB8BF9BE0B +:10C79000126C7A068F2756DBBCCF89F2887E001197 +:10C7A0007FAA0E237F7B9D943717F687C9EF691FF9 +:10C7B000E7FD195CCFFECC0C6B3CADD3164F0B6381 +:10C7C0003C2D7BF071EA8AF938DD7312DBB34F4FF1 +:10C7D0009BD33A63545C3F4055D00D6529940E2895 +:10C7E000FF3425B26946115EE6E1FE16E9BF5E2020 +:10C7F000F288DB4ABF1C9E83F7928A5D01E1FEEE60 +:10C8000037C777D56DDCFFBF62CE05CA0B5BD3E9B6 +:10C81000D1F6631E4B87C85373A652FC41BDC1BD00 +:10C820008FF679113F8D60BE710ECE33F4BD0DFBD6 +:10C83000FD1943ACF7DDD01617EEDB35E56A9F5BDB +:10C84000C48F79BE9835BE2CE3C56579E329AEDC8B +:10C8500098E9A5BCE22ACC0F41D910F1EE3AD1BF3C +:10C86000B1E58530E2BD7EA793A11E78A5F1E5FA7A +:10C87000B091F539787F41791AD7E76CF1E69A865D +:10C88000277517B41F055C8FC00E225E2EEF85C47E +:10C89000EE1F883874443C5F1ADBFF2BD371FFF422 +:10C8A00074811D86EF8B38B38C4757D9CE81FAD06F +:10C8B000DC74F2D70654B21FD54BDCB3CE29E1F9B4 +:10C8C00068321E7D7886351EBDD5C5FD7FDD3956A3 +:10C8D0007E2B29E1F6EC2471EE1E2C4DEE4B42FD31 +:10C8E0009A79C9CED882FE9A61DCDE40FF84DD6F82 +:10C8F000A3B6AC20FF22B62BC07F4AEECBBFC7FB4E +:10C900006A582F81FE2ADE578175A8A90EBAAF2971 +:10C91000FD3BA886CCCB273FCF49E463B5A58EC6A7 +:10C9200091F7D307F3F3FC6C86D40F7A5DD86F854B +:10C93000FFE51338DF5FECE7117696EC1FD6789EA3 +:10C94000CBF0199A8C5BBAF8FD3DE65A3485FC2190 +:10C95000EFA17CB2C9BD1AC221F7A345C5CFAEC0B5 +:10C96000FD88E9A3D819D3BD08FBBE20F78BD87C7E +:10C970007EFE7EDDB7BEBBC2183978BC2227148B81 +:10C980002FA8419C7FA48C2FE82EACC7CF595850BC +:10C99000D072CED636FD37386763FABD31B616DBB6 +:10C9A0003F6AF0035FCD0E52BE14F7B37DD4E07F33 +:10C9B000A5485F8A7C78ADE7F956517835CEB359F2 +:10C9C000D16B52793030A00C1D17BC0BFBDBE3821E +:10C9D00097F257FCC33F31B47FE24B416B1CFFC35E +:10C9E000E29FF867C029EE93204F4F923C85B83CF8 +:10C9F000FDBDEF7FB0DE57B85CF44693C75D7DFFA9 +:10CA0000C09385916388CF895A6A3D9EE3308F86B3 +:10CA1000F217F37B20DC418BDF634FD335F07BC013 +:10CA20003ACF125DCB395DFF0EE8F65F749EEB5C8A +:10CA30009FF83BE4CBEB8B915EBD7C7D7F83F93F20 +:10CA400046F33FC5F9258E1FAE2799F053DBF4B7A7 +:10CA5000C14F29C1F74D0EDF47809ED5046F80C3BB +:10CA60007B29FBFBCE193C7E02EFADA0F70A391FF4 +:10CA7000DC85FA35B7CBE762BE80B4CB33F2F45530 +:10CA8000D80FF4DC7A3E4F4CCF6D281E35A4DDBCA8 +:10CA9000B67868BB797DF147C86EDE2DF0168FCF72 +:10CAA00044E93E1C9CE41447AE137DB7B42CBEEDA4 +:10CAB0002680FB37807FAC7B703D4ED37AB254B278 +:10CAC0009FEDF7D48E883C08B92ED5593B0CF5085C +:10CAD00089CF23E99A1BEF4335E84A272603CE3551 +:10CAE000DEA175BB750FE91F37FA7D9D187F5DAC20 +:10CAF000F3F5BB9B7C74EF45DE7393F74E1AFAC6D1 +:10CB0000BCEC86F7B680FD3206C65F586EBD876204 +:10CB1000D72F545BBDE5C7D9DB0F99FA3F566CCBD5 +:10CB20001F743E5541F94386427A1713F9840D620A +:10CB30008CB6D23B92FD5C8FD3100F73773ED08FB3 +:10CB40007133B7E1A4EF30FDB655DB7E08442A69A6 +:10CB5000F3BBB4BEDFC0FAC8C8ADE4F1FA4611AF0A +:10CB600067363F8527F9E72EF44F4B3C26DDCFF3A0 +:10CB70003CDCC153E574AFB1764D7F11EF4BFE073E +:10CB80009543C6E47735AAC438553ACFAB5CEA770B +:10CB900058F284EC7E0C95A9B6BCF881974620BF6C +:10CBA000015EBF8CEC91CBFD10C94CA7EF7024B790 +:10CBB0002D1ED687DDCA5D96EFA12C0CDDCBCCF601 +:10CBC00072B28D2F3D367F839D2FEDF4F8818D1E3F +:10CBD0008FAB5C2FED3CE6247F79E783ABBBD17F45 +:10CBE0006E3CE8207FC65999070240A23F7F198B0F +:10CBF000E197F4E5CEE68C28FAE1255D96EDE4F9BF +:10CC000021D4CBE477672C9399BFCFB14CF817EEC2 +:10CC100060BD74BF61251B70A11CAC4257BA13FDE7 +:10CC2000E21A958DCCD8C4087F91EE6C98EFF1E6AE +:10CC30001101F46BF75DEFCA783B97DB1189F4D7EC +:10CC4000785C56656F9BFCFCFFF06B5DAE5FCB695B +:10CC5000D0F7FDFCEE287EDFEF527EAD97453C42DB +:10CC6000FAB5CEEEE4DFD5E817F72AFA5DDAD89DFB +:10CC7000A9D84FE3DFCBE85E761BC2FBDAE6577C30 +:10CC800003B44FB20DA387FE0EC4D4920476E1F72D +:10CC900067309E17973D9085F999275DD6BC5B5903 +:10CCA000CE0FB9C5BDECC88C12935ECC7CB13CCD27 +:10CCB000E212F257F1FBD9D2CFB4B620528ACF6735 +:10CCC0005D60640F7A2A95A882F919A9CA4B8A1661 +:10CCD0009F9FD9F3E5FF1107E3DFB712F8E94FE2B1 +:10CCE00079B3FDD9ACE6D904F4C99EC5CFCFFEBC5B +:10CCF000C4F493EDA097DC83F443BB299D33CBCFE1 +:10CD0000DD43FB133E5B9220CF58D2F7C9D9FA7DA1 +:10CD10009CEEBC9E941FF902D6DB23E19FD0F7EB7B +:10CD2000B639B536C47F9F762488F2F945A70FE35C +:10CD3000DDD73ABE377C46F665C5F77E81F81D45DE +:10CD40007C2FF4C67FAA433D708BB4CB84DEB862DF +:10CD5000B8A90E5B71C931DEFF1B25D3F71AEAE0D3 +:10CD60007AE6FA0377F4A01E29F54CA8AFC4BA7C82 +:10CD70009FB1DBC796815EDBD824E388B7EF453DE2 +:10CD8000373EDF92BDA8079F7559C7977AEA2B25D2 +:10CD9000E57B71BC706CFEF2BD08FF800D7EFADE93 +:10CDA00024D4DF28D1F7A2DE5BCF64BB4EF901713A +:10CDB0007FE27AB25B8FBB65FB27285F607B361F03 +:10CDC000FFD503EB7BF03B691F3678AEF5F857DAF9 +:10CDD0007F307DFFA48BE7071AA09F615E4890F526 +:10CDE0003AB9F0E96E27F07F89AED07EF4EB109768 +:10CDF000D770AA43CCD3D2437C512AF11AA53C8FD9 +:10CE0000C1F8EECE03DF7818D71D87FB1B2B900EE1 +:10CE100031B88DF575E81792701FC5FE30DE8A7B3C +:10CE2000EEF4239C2B627E8DB61EECD79921EB93FA +:10CE3000F6627DB0795786B6F5E0BC2B62F8798052 +:10CE4000DE5F912CDFDF65CD4F317A565AE15A6DA6 +:10CE5000C1E7F70EF4F4205C615F74D368F2073227 +:10CE6000FAFEE71D4D6D94BF1D97A3AD592447FEF3 +:10CE700058BDC72A479F26B8AF365CB09FFA67E215 +:10CE8000F995CBEDC3ABBF6ED82771DDDB145AB774 +:10CE9000E4A35A9F89DFE19C6BD464FD9EBAA6C9C6 +:10CEA00057635E6EE7867FCEE8FC93F2C48C884DB4 +:10CEB0007E2E6FBCF6D41CCA9F00FB4A4F946F7D38 +:10CEC000D70C45FA31E7103E83D26E6652EFB86553 +:10CED000E62893DEA1C5F48E0AEA6FD33B3A451EDD +:10CEE00055A7B86FA2438BDF94E7337E168FD3B676 +:10CEF0008B3CCDC28DE1B5663BFB89D91C9EC766D4 +:10CF0000733994DFAB3DD3A4501E58FBB611E9989A +:10CF10003F7B2AD3B700CFB5FE6C4700AF2E9F14DE +:10CF2000DFCBECFFBC27EB33F0FC44762AD9A927F2 +:10CF30003276A6E13D855301A738679E7B8BFC5D69 +:10CF4000717FA281E78AF417AE9ED94EFEBF3735B6 +:10CF50005E0FCC7EFE2D8AB7E5DAEF7186488F71C1 +:10CF6000DF22BED32BBEB729F5A5AA4D8F7E896CD3 +:10CF700060A1BFC8F3D37EAF13FFB8CCFA57879335 +:10CF8000EB5F7EDECFCF06DA3E30E9DDDE41BEF379 +:10CF90005A23EF11DAF429BB7ECCC4774DA57E9ECF +:10CFA0003CB281FCFAC94DD67EA73A5EAC0CC2FAFF +:10CFB000BA024ECAB3BA3DD7AA474B3DECB68E472C +:10CFC000C90E05BDD0D22EF36B6F67BD1D74FF5B1C +:10CFD0003B7CC8393A6E77B4FBAA484F69C8851ABA +:10CFE000ACE7F8FF284B2B42FD609B13BFF0CA73E0 +:10CFF000EB4DEB807E2EC748DAA7038A62CE076A24 +:10D000007B04E5229E0FC4EB713FFC7D8FE07E1018 +:10D01000F317B37B5659FC9BC632EA1FF38719619D +:10D020006A3FA30AFF97B1EA11DCCFE2FEB11FF617 +:10D0300058FC6346E523C84F32BECA8CFB29AF6F4C +:10D04000A94FC2F3A31EACB7EBFC3CF9E6773C2733 +:10D05000F17B4057DA1FE4F379944316E6FB9DBD5C +:10D06000BDE458B43D5DE875F83D0ABB9C27857862 +:10D070007E5DB99ED7314AE37E2B0FD0475FE95CD6 +:10D0800089FC1ACF5329A6EFA2350E9257322FC42E +:10D09000E5F7F0CC548B3D6ECF4F691471E8C1C6F3 +:10D0A000A92FE571F67EC557CDCF6527C373B9ECBF +:10D0B0008171A9783D55F62B2DE5FBC19FA6E8C7E8 +:10D0C00071FD763FDA59F4A3A1AC0A7FC722C13BB8 +:10D0D000EA4EEB774BCE64F0EF962CDA26BE935EE9 +:10D0E000F197F9CDCECFB4DEAB1F2CFFA1B894EFF2 +:10D0F0006379A55727FFE189645D477C9D83BEE87E +:10D1000017BC281F42E439C83C08772887E76D30F0 +:10D110009E0FD16EF0EFF15DF57B2CD22E290CA77E +:10D1200084F05CA8E1E788E4B3BE991AE7BFF30195 +:10D13000E23FC977D03F23847C5DCDFB979CE7DF3E +:10D14000B790FA45D281933D6DE3E91CBA2E643E57 +:10D15000875263F71EC784129C4347E7EA37F0E71C +:10D1600086C86788DC182A4AF87E762881FD3C79D3 +:10D170006A783C3D8FDDD7D42784FE91FF00D3260B +:10D18000CE3B691C24EF44EA85F5DFFBE94A03FA4C +:10D190007D30475F1032D9AD31FD7280EB3B31BD40 +:10D1A000D2984AFBE235D01B57854C7935D760FCC5 +:10D1B000BB88EF265BF528B4FFCDCF3F6C761CC053 +:10D1C000B791F022E2267FC6FB5B42A678CD5F01D5 +:10D1D000DE5D2193FEFF21C4E75384CF0F2F7C7DBA +:10D1E000045F25A7F7CC99313E7D31311F5C36FFB6 +:10D1F000FFDF90296E6E1AF7083DAF1C3A2E07FD2F +:10D20000DEB0F68BBDFF03F3B843BCFFEF047FAC89 +:10D210005FECFD93F45CF0E75590F3F366FA5E8300 +:10D220007DE43D5AEF783EFEE992D83A7E6B7EFE71 +:10D230000F7FD925F93C6B16E2AB99F3D365E8D99A +:10D24000E366F1FC9608F7D31A52AF99289E0FE0D7 +:10D25000BDD105C8D7A3E85EDE4D38BECEB89D1B54 +:10D26000B34B8CDD7BAD76090C34D972DEEF35DB48 +:10D270001DFAAC7D7B115EE75CDEBFE8BBE9AB70FD +:10D28000FDF63AE825336659F3328338FFA5C6C563 +:10D29000F83FBD678BFF9BDAE7CCB2E42F703D16F9 +:10D2A0008E70AF0768FCC35AE7C806A857CEE27A6B +:10D2B0002CE82109EF6F57CE8AF9132A693E918F26 +:10D2C000712CECA47B80317D8579C9AE8AE953C687 +:10D2D000D7C84F14D7A7FE85F8A954D077D5777B48 +:10D2E000EB049CCBF8FAC53A2EDD7F25F5F7F3FE6B +:10D2F00009DAEBA93D93C3C9520F9F755AE2156C29 +:10D30000BC6374FC7740CA5C4B668D047DE56007A6 +:10D310008F47D5770BFA1ADFDA6BB513B9FC2D17E7 +:10D32000FCDEFADDBE3AE4FFE5EF49789D7CFD3195 +:10D330007F5F1FADFF4DE19748FB5E9F84EFB30415 +:10D340009FC6E1BB06E3B711DD19C74F0D335CA3E0 +:10D3500087C8B3D82CE80FEF75D37B5E0E574D44CA +:10D3600071F1B8CB2917F279DD3196D0DFB473961D +:10D370005BBEBF93DE4F15F66C20F1BDDD87E2F199 +:10D380009387A8BF8FCFE780F31FEBA1C8D1B94027 +:10D390001EFCDE1CD935E17255C7EF2C84831716AD +:10D3A00031D377E5641CBCECFEF1BD680F269727EE +:10D3B00071BBD16BFD7D0ACFDCFB721FD4485AE9EB +:10D3C0003BB54B041354316B5C34419CCBE27791F9 +:10D3D000FE9125B1B85426D9B9EEADFCF7A158B5E8 +:10D3E000358E99DCC2C8CFB5C050A21A8CEFD1AD32 +:10D3F000FE96C8066D3BFABB54D515D0B58BE39AA3 +:10D40000F6DFB998ED657A7A3EE5A37C6FD6A87809 +:10D410001ECAE9EE71A92887763BFAF4607674B7E4 +:10D42000D58EEE9776B47E75ECE8A3B3AC76F4DED9 +:10D4300082F01BC4EFAA4EFBDBC1D29245685FBCF1 +:10D440002BF228061E54D3110FC6367E6FE1948846 +:10D45000F3CB78FF40314BC5DF3B1868F3103E0734 +:10D46000D6644453E0BD74635D25FECE81B4A7113C +:10D47000F3E80793DF27B6DBDDC941A0E7341233B9 +:10D48000B2B7077C3EBACFBCB0437C4742E40B48FE +:10D490007B5BDE7B6F2CE7F7A7D17367FE7D8B8507 +:10D4A000C21E977679DFBF31C59C07B08805289FDB +:10D4B000A09A85A95C2ABE9F58E3639B10A8F7A792 +:10D4C000447E47FCBF87F309DBAED2EF570D6C7B80 +:10D4D000807E1F6AB0FB0C6AA9BCCF60509CF61A14 +:10D4E000D8FB49A5A6FDE332F69B61D45FE572DC6B +:10D4F00086F77C47C5BF1FD12FFCC2DB33B83F6521 +:10D500007C29F737D94BF97D882B3D3FE0FCBCB136 +:10D51000D46AD76BA597777E4EA4F7C4F7294663E4 +:10D520003C88EF4B379572BD404B27BF0A6CD14307 +:10D53000E703044A8788EBB24BE713044B13E41369 +:10D54000FC42E8236B0B22B370FC591718F1AD3D78 +:10D55000EE2FFB1D473F5582FDB659F8DBCA8045CB +:10D560001DF917DFDBFF61AB7E1275BCE3AD15540F +:10D570009E508D34CCDF3A22EEEDC30894CF24F3D5 +:10D58000A2E4B835B56527CF9AF6AB85F31EA33C68 +:10D59000B3F6DCFD871580F394C8F7EA4FF36D47C7 +:10D5A000BFB371947F476A69F5AD27CF9AF60F3BF9 +:10D5B000BC98176580A8DF59CABF5FF76299A76F4B +:10D5C00036C8E1EA6D5C0E576F3BE5427F665D4B06 +:10D5D0003D8B4CA1BC2915E97B6C26FFCEC2C2A0B5 +:10D5E000931926B832F2F486528A7B845713BDE32E +:10D5F00079816BB05EE6D2D331AF5DFA2965DCA0EC +:10D60000B4F467A43FF767309A3FEC67518CBFCF03 +:10D61000D5B3DD03187FF1FBC8AF5A57AAF1DFABD2 +:10D62000EBD847F02487DE2178CA54C0F7F08BF19D +:10D630002DE5A253E0DBB46EC2F760F2BB709E9A98 +:10D6400086F83D82F4827E9BC43EF09A7A21D5977B +:10D6500080EEB1F78265167C7BFC1516BAB5EBE35C +:10D66000D2713D92CEF5A2ED7487F3FB48C7F73037 +:10D67000AF8DE898381FE228D26B12B497727FB44E +:10D68000A4579DC1E9556794713C056F758FA178CA +:10D6900080D28BF7251BCBEB19DA0B6E3D83BEFFD7 +:10D6A0002FE9B7A81CE8678217E4F1E15293DEF98D +:10D6B00067F8D91F2D35E9C1D73A0E00F33D43F382 +:10D6C000D9F372FF4A71888BBFDBC3F7DD3705BF23 +:10D6D000D84BB9EF0E9ADF6C54AE6AFA33E0907211 +:10D6E0008372DBA660FEA4E2423E0BA3FC4E417DAA +:10D6F000EE3F36615CB4C1CF7A712F7C08E508F04B +:10D70000E6AEC870A3FCD47767135FA0FD4FF81492 +:10D71000FBF44BA54C9E5327E97913E78BBF75FCAF +:10D7200007E0B940F0D48AFB051FB2F854564558BB +:10D730009D8DFE597D1F9D2F7D33E5F79A5816F775 +:10D74000935F593CD4A3F3FC3119174D1007D594BE +:10D750003F230E6A8FAF0E16174D1007B5E8EB8307 +:10D76000C541992D5E6A8F83DED63182E2D0B765DE +:10D770003A28FF51EAFD32FEF96AC7D7E97B47AF85 +:10D780004E565846F6C571D26DC23FC650AB33AD4A +:10D79000FF4416FFDEF596315EFA8E28FE719AF28E +:10D7A000F1E07CF07A60DE8E794ED24BABB2F7DBE3 +:10D7B000F1EA1676C965E155C6D9DD1D3CCEEEF11C +:10D7C00033FA3D4D49C7F8F7749FA7DF8B642ACF22 +:10D7D000D3ABCFF5515EAB9D0E9E8EB67BE9779CA9 +:10D7E0007CD3D75129E8EFF15F9C3FA84AF812E4B7 +:10D7F0000FFED9F4BC041DDDCE0D5E14B98BE8A973 +:10D800001D4CC5EF8ADF1670FA342D4E4749D78B71 +:10D81000E9E7A3FD45C6B96F2A0CDF857223BFD3A4 +:10D8200024E97B228BE3F7CC4D2C2ABF4F66A62739 +:10D83000E05FA77B77B96C1FE11FF330A75ECC17C1 +:10D840009E5C837EC7D39D5CE927B992F8D50E1004 +:10D850005DDA9B7D0B507F3A5AEEA2BC9504FC40EA +:10D86000BF5B7B297EB888EEDBF8EF845E29FDEE96 +:10D87000287E5CCF4EC01FD790AE15C14474C57CC6 +:10D8800086BF80AE278AF4C791AE929E3715EA5FB5 +:10D89000995D64965F83DB312CF1F76D9E16792DCF +:10D8A00030CEBFE27BBD686391FF50EFC5FAE21B4B +:10D8B0005973A2EF823D5BC6CFDD5AD6FBD268B466 +:10D8C000FBCE3291B71938ACA19FA6655CC2BCCD26 +:10D8D000E3F86121E8BFD0CFF639C4FEEA30E16950 +:10D8E00040E46FBE89F99B60E7BE3C3B9BD6B10527 +:10D8F000F338E1F92991E7598B63E33CA0CF627CCF +:10D900009EA91186F7D3FB63DF6769A373379E8FE8 +:10D91000F1EB47ACDF67E1F58599B23D356A898364 +:10D92000327F04EDB6B8FD35356A39EF5830628D77 +:10D9300083F27C1D79BE6DD4E7440C731C9455D0E2 +:10D94000F8276B65FF1DD1B2C9E638E8E2A86E8EF4 +:10D95000731AF3A3E638279CAF54977EE8C7FBEE13 +:10D960008FA05E3F796AE43CD25FDE9B870348C7A5 +:10D97000DF9D73FB7DFBD10E07FB00AFE40FAA57C1 +:10D980007FD8CBFF0F02C2B069008000000000000A +:10D990001F8B080000000000000BE53C0D7454D5FF +:10D9A00099F7CD7BF393644226017480A02F01DCAC +:10D9B0005843187E020109BCF9C94F157480A0B103 +:10D9C000207D842CA55D5A83959676EDE6416248CC +:10D9D0008240E8D2EDCFE9CF88D03DAEEE69E87164 +:10D9E0002991D20E6229964A634B8EB14B75B0597C +:10D9F000165BDBA295DAEEF194FDBEEFDE3BF3663B +:10DA0000323128B4C7EE8EC77373DFBDF7BBDFF7C3 +:10DA1000DDEFFFDDC79DC58CB105F03FF3C60C8D72 +:10DA2000B18110FC3911FB7ED380B1955364BF22C4 +:10DA3000669433B6384FF6AB4C6321639D2EB99E86 +:10DA4000590CE6BFC09CD4DF66844C6B2A63C16569 +:10DA5000AA985F4FF05F5A2DE7EF8E0501DE2A8707 +:10DA6000E85B2B628697B10F31D95F4AFDD5C97E3D +:10DA700094FAF732BEFF81F84ED382F58FCD894EEE +:10DA800034C6C3B348AF1E9DFEB787FF3945E233A6 +:10DA9000C5C4F1F73BBEC0EF7AA312C1737EFF0D80 +:10DAA000E0BB86E4E330C7F77D88DFFDC4CF2738CD +:10DAB0007EEF037CDA099F5EC027FF2FBFDF0F2BAD +:10DAC0008D3DB8DF5F808EAFD1B997733AAE60FEFF +:10DAD000A34477809F43E6F8C4A08F311C9FC3E125 +:10DAE000BDE8147264359B28F709D9C77383FE8299 +:10DAF0003372BFCD7A50B3E3BF99F46455119FFFE1 +:10DB0000EBF8A74DAB38D5879F81E72ED7FF06C727 +:10DB1000D3D67F8AD67767ECE712E3CAB1AD846FBC +:10DB20008A5E8BE6F767CC6F14F4151CEB8C5936C4 +:10DB30007E306B3BF1276997AC9D6497065CB2BF62 +:10DB400083F4665709873FE1D8CE18E20FFC3B45C6 +:10DB5000FC9ECAF9F7FF9D1FBF3584BC94717E48B7 +:10DB6000397C6C8EF13B94B3F71BBE707E6A707C7F +:10DB70004AFEFF0AFB15D27E429FDEEDFAA43E0A62 +:10DB8000BFCF9624F93B2908CF2784741AAFDA70E7 +:10DB9000307C3DFCB9BAE511D544B830878D632C93 +:10DBA0009A60B16DB0E7AD2CA632F061D180C97C2E +:10DBB000E536BD665F243C5C5E87E87F83ECDFAAC8 +:10DBC00045E25CD8600CE38B14DEDEB5784E49BCD0 +:10DBD000D9D7D2F05E78CCFB88A03B10B4E9C9B5A8 +:10DBE00086EF0F015F6CF150B22FF8B3EA135F9E1E +:10DBF0008C7C58552AE17E3386705E2C94700FD24F +:10DC0000BEAB92FB7C8FF773E5FC1FD1FC145E0367 +:10DC1000661A5ED6CF28EE92783D766C80CECBE544 +:10DC20008B3D74DD1C689B958005E7F1A10D5B556C +:10DC3000D36E1758AF1E04FF760F4BF649AE5276DF +:10DC4000A097F6BDD6786D0A0AFE083D4DE29960B0 +:10DC5000018BD9F13BCCCFE71AEF6FB30BF7A3DC05 +:10DC60005E7BBEC79DD7DBF82EF560B52FA9DF061A +:10DC7000F300DF7509E707E606EFD5EF0B72BED3B9 +:10DC80006E4FAE9E8EFE1AA2E3357E2E29FBF31355 +:10DC900033DDFE5C317E8F046DFEFCDDAEFFB760D0 +:10DCA000BA9ED9ECCFE348779BD7E1423E9B7E6694 +:10DCB000C400DE65FC2D4EB513420AD9A7A47E56DA +:10DCC000F1F52B76B396DE2CF3AF0F39685EDB539C +:10DCD0006C432FC00DBA2E36476DF3E2413E7E34C1 +:10DCE000A8500BF41D25FE6FE1F89D0AEAB45F9081 +:10DCF00069CC009D6A5831B918F16BFB398707E987 +:10DD0000125B9E9F827741C093FB1C5B96DF18F3EA +:10DD1000A6C69F15FB9C0A723AD0FF133F1FE474FE +:10DD2000A8051BFD085FCD5384FEFC9AF8DAE114C8 +:10DD30007DEB0DF26B03493BF43B92F7956E29970F +:10DD40006F91FECB78FD8DE0FFC4AC85883F638E7C +:10DD500059F675BF253B38DABA84F417EDE2BCAC4E +:10DD6000E4799D43BC475BAF869516E29387C51562 +:10DD7000F01F2EBF6F5F3790525E61BC8A7C3E31D0 +:10DD8000D3F815B6A3C1013E5DA47379203D1FB140 +:10DD90008DBF194CCB072E6E8C221CD8D90DE7F6FF +:10DDA000C26A755C13F0EDCF783E95941FD4DBCF3B +:10DDB00045B67F4E9DCB9F8369F17C38BF12F488B6 +:10DDC0004D7004A6E9C3D779438A9433714EDA23A0 +:10DDD00048474752DF787F57211FCF79DAB956E895 +:10DDE000535E08F77952F097F9C6E17EACFC645CAB +:10DDF0009D0BFE95257F8603FA6BF12FD87F207C43 +:10DE0000CE8972B0A65DB9323DE914F01F4E9EDF97 +:10DE100084D078826BB2B9C27FC06FE0235B096E99 +:10DE20006333C0CDA22F53429C7F5342493E4D21C4 +:10DE3000FC0D0ED731273A0DE1C254E69E9582BF04 +:10DE400046E01D74468F5E0F72D061293ADA557331 +:10DE5000CBDACE12E4ABE60C4C83E626E414ACEB52 +:10DE6000F0977AD1CF3D27F643782E3847F425FE38 +:10DE7000229AC73468E7D66F3A0EE0D8DBD3CD4A92 +:10DE8000C4A32ABA278C642D683C781CDB3BC04CA9 +:10DE9000639CB275D157A221D8A77FBE3380A2065A +:10DEA000D159FF54C0AB41E0A51975AFB2319045CF +:10DEB000B958203E07FDBA37B00D9E37347F64094C +:10DEC000AB803951E750C283C498EC7229C2D58621 +:10DED00012659C6797C1C62DDBE24CF511371CF724 +:10DEE000A4C657DCC8EDD3AA10F0D32677DF17F409 +:10DEF0007D5FF07337E0D05F4E00F219EA0DDBE092 +:10DF000040FE991E8E67BFB5E2B69B81E04B652C43 +:10DF100080A36EA44F4DD19798AC05DC3A898B77DE +:10DF2000E975B0AF38D7D3AD60EBFE0EC05A9C4E4A +:10DF30004D5D5D10B7C9F1E931260B60DC56663DD9 +:10DF4000C4404EC2E61E6702F0B8B1F9F50D18F7ED +:10DF5000AD31DD7A1DA078CF065F0DC6B52B4CC163 +:10DF60009725CE57906E0FFC877C71C55FFD810BA6 +:10DF7000F9BC50611300FE9D113E2EF9E266DA2BCA +:10DF800076BE6819FD2D674B763D639B7F5F287FCA +:10DF9000DCF95BE08FD96CF665A093A9DEA588CF8C +:10DFA000A576C5A796D03407033A5D823F07DA37D6 +:10DFB0003D877ABAC6AF051CC887258CF8D728F6E6 +:10DFC00078AB55DFF50CC4AAE12D7B7A4A00CE3D33 +:10DFD000675486FCEA587D0021E1CF83F034211795 +:10DFE0008EBCAFF66B304FFBACCA703FC947E0B791 +:10DFF0006F2E3C3F3700EB61EA3D55C027D8F70E46 +:10E00000C3ADEB302F77E1EBEDC8A75CD6121F0B49 +:10E01000FDBBFC0E16F7A4E802BA2DC117C7658533 +:10E02000F6D235B9AF236D9CF892FB99306368BB8B +:10E030002DA37F2ACC5B26E5B61DCE13CE6199C1F8 +:10E04000CF439E2B8B707995E7929B21AFEE2A6789 +:10E050004A3EB3C86BE639C432CEE180C6F52471BE +:10E0600046A5B822B1571B53057D6BAF83F418F258 +:10E07000B4C34A01FC11579806FCBF5BE04B3FE07C +:10E08000DB8196C2587749EA3CEE2E3BF127A58208 +:10E09000F159D7A5EC11C32416FA7789DEDD5FB2FA +:10E0A0008A507E3FC47A9DA8D7F762C60CF87C9848 +:10E0B000F95CD86F62016AE1BC5DC8AF037B9FCE9B +:10E0C000473B129FE82C3C5F46AAC2EC7632B34530 +:10E0D0004E9C9774C3E4B8B49F1ED34F76D90B2DD2 +:10E0E000D9698361BFB026E231B3F891F86CF38748 +:10E0F0006807655FF3B530C4E3EBB3A3CF72BBCB66 +:10E10000D74FAD307E84FD83B38C53D87E13E33D6F +:10E11000F00F17430F525EF2F674E334DAB54C3B5E +:10E12000760EED989E9287E519F220EDD820DA312F +:10E13000185A8EFA0A7C63F55767C7CE4939F8003A +:10E14000FB00F207E8F925D97F0DE801BEBC84E7A2 +:10E150003E8361F52DCE8A884CDD07F829023F7C8D +:10E16000AE807D57B6FCF04FCA18DE5F00F3147125 +:10E17000AE9846D6A0DFF87AC0E39982F6C21C4476 +:10E18000BA33F9028ED9497999FFC420CA8D23EF99 +:10E19000BB93CD2C7E3079AE1B9DAF25E9423D82ED +:10E1A000481EE95098E9B88CF4F8008909EF241763 +:10E1B00016C941C75285E8EB28618D68CFDB7168CD +:10E1C0003E63DB972ABDF8FCF170118F97A6F2B879 +:10E1D000707B618B3F00F3B63B613EDAF33293AD67 +:10E1E000989E82FB7858A5F937CF31F2D07141DC87 +:10E1F00047F1928C57E53C5F98C79563C33CCE28A6 +:10E20000AF881685719F7126F11DE2A8B1D4F7C6BB +:10E21000638EEB445D84FF74872D8E1898D4C2D032 +:10E22000BFBB0DEEDF33E9BC219CF4EB3710BCBD66 +:10E23000D2AF1B37227E8BC7FA1AD0CEB900EF7D42 +:10E2400025297F7D68E9E754D896DD122E21FCAAA6 +:10E250009AF7B45D07E71D0C4EF1A27B8F57B7F814 +:10E26000D1EF6D9FC0F996B9EF9630F783736E10BA +:10E27000F304BFA4DFF740F8ED847D30CD77601C58 +:10E2800050CCE3807BC3A5B44EC60330DF72C1BC63 +:10E29000E04DA0A718374FE37032F7BB57F033E5D6 +:10E2A0006F030568AF196B217F1115FEE48556E3F6 +:10E2B000A52110CA81D67A6AC1FEF747C0C00D6A8F +:10E2C000567E200B1D77D63CE041386DC54D1EF4BF +:10E2D0009F1D4698E036AE0EBE3464B3B7DB8BD9D3 +:10E2E00064C4EFAE860FBE3464D3B7FE7C8E2FFAC3 +:10E2F00019CB9D82BB12E504F03D1E74C717034382 +:10E30000DD7E16739750EBD4314F0CEB341E35D6AF +:10E310003213F3F1AA731AD5BF0A5972FE5638DACE +:10E32000703123BF1EF5B7305CE7863ECE8F2E7C62 +:10E330009DE6DF59A532CB8627D89F35145065C49A +:10E340004BBB51C0006EC77C25B60DF068F0AF27FF +:10E35000FFB375512E3D877D09BF3BA63593DF92F4 +:10E36000F15547241220FF7495F1547C76F47EC455 +:10E37000CBE54FDAD507485E5376757398DBD54FFA +:10E38000E173693FF61D7F81ECC77685CBE176E0CE +:10E39000F7B7B3C8C756A107DB0BB3CBCF9785BC84 +:10E3A000BE3D3DDA86F00DF069FE59EF3DDEEC90A2 +:10E3B000F1A6E0E3D5F207F8F12F619B5D067E7CC4 +:10E3C000313C7E381FE0D78EF64295D6E2094543B0 +:10E3D000F9CF11DD47981943381ED64293546F94F4 +:10E3E000A1BF1B0E27CE70DD2A41DFBBB5C7DF8280 +:10E3F000F086DB35E38930E5853AB7A3C22E33D604 +:10E4000023FCEE7BB3DB671C604FB1DE8D8F6CF3BA +:10E410008F8A73EEAB348F229D37E9DEB5782E5D9F +:10E420008AE1F74EC1BAA7D9887ACACA668DB2CF37 +:10E43000568233506A6E88929D5F3ECAFC6D625F61 +:10E4400041675911F911D8F74BB96AAA3F1A5D878C +:10E45000C2C64F11EF3633FA0BD4BBED650EDD5259 +:10E46000A8253DECAECA8929D0CF9965BE887C0528 +:10E4700011319C00BABBEC0D8A8BDC4B148AD3DCC7 +:10E480001EC8E0B2C8F979E16F20D6A07176D6F047 +:10E49000DBEB1D8511477ADE0B2261D8EB171147A4 +:10E4A00013D6E5A53FC3BAC9B7B3C8C545A14FAA9E +:10E4B0007B539ABFCC9CF746D845F39488A84B0869 +:10E4C000FFB7D2CDF32BF663C0CFE65FFB2A437FC5 +:10E4D000203DB098A5D8FCA2F48334627BEEC6BA86 +:10E4E00013D279261D8EA4B328C2D2F605797544BD +:10E4F000781D438D54A6C657AA8CD73DFAD3F9058B +:10E50000F8782264A7D8D008F8ECCF8ACF603A3EDA +:10E5100045117E2E7D954611C203FF3C16DBCE10C1 +:10E52000C85F16FE7E6B46E87AC45363566769C9B6 +:10E530003BC6AD37201CD9B7C5AD7A24DDBE9644A5 +:10E54000B87D2D8D907DCDBE6F85E0DBD5DA87F768 +:10E55000AAF73BF0CF2C7AD49D7832AF02F070BB93 +:10E56000AD4F92BE96CF1A45DFB87E7FF886FE4942 +:10E5700048E751219F68DB31DE30741E8F7C22C258 +:10E58000E53878538CE63D3542FC919C078CC1BA46 +:10E59000DC4871C8FCF71887742F1CC8A338E4CD79 +:10E5A0007D79E8EF9F1A0A658D438E16F74CCA16DF +:10E5B00087F48D1087AC8FF078F5F87FB928AEA876 +:10E5C000BEC0FD7CF5851E15E3898D119DF83E7F4B +:10E5D000A85F35414EAA310E01387D220EC1F914D3 +:10E5E00087BCD9A3225EF32FF4D3BA6AE8631C3246 +:10E5F0007F843804B05051EE0E5777FF0CCF2D9327 +:10E60000DE5315E666BBDC5625FAE93D895CD75D2D +:10E61000B62DCFA4734E979BF86C8E6F6A1D97F73B +:10E62000CC7923C9578DEA2DC3FA4017CB0D201F93 +:10E63000DECA1953C10A785E837171174E05BABBE1 +:10E64000CEE6C52CCCAB3D7CFCD3B963F6612BED9B +:10E650008F47E8C55B3937C4441E6414C0FA4FAB1A +:10E66000467C31F8A1AEA99FF7717A36911E6D16DE +:10E67000BC09EDD1289FBE55C48332FE7A6EA51227 +:10E680007353D2652C590AF3E709F8AE393C3FAC15 +:10E6900055BD346F4719A379B75A17A97E313FE1A9 +:10E6A000D275E8CF4BACE7F9A2FADD937918EFDF2A +:10E6B000A231159EAF6C8FB6917C9E75513DC38083 +:10E6C000FF503F2BCFF412DFF2865C69758E5CB091 +:10E6D00064715BDCE2CAE833757541363B24DBCC00 +:10E6E0003AC4C188C83F2BD88CCBC0974BECC14EE5 +:10E6F000A4CD3D2D74FC51367CBDAC2F6C9C617C4F +:10E7000007E563AA33F1EFDF017EF5BDE6A2F73A34 +:10E710007D7BF7DE5E81758B1E8DEABA329F01CA62 +:10E720008A96613E8B3CA0BAF4E92694CB23F9B2D9 +:10E730000F060DF03E82092BF9BD8F3619B6FEA9E2 +:10E74000C843AFA0DF3B325ECE7F95AF977D2BD124 +:10E7500084F7358E4CE0FD4B11F5518BCE37A1512E +:10E760001EBDE597DE6CF6F1744DBABCDE51B5897D +:10E77000CBEB28EBC0AEBF18C9B22E67A9B9633A7C +:10E78000F0E3C89083EA389067C5313ED838C37C3F +:10E7900019F9B57D90F3F5C86BF7FBF09CDC6313BA +:10E7A0000F64B3F3BF11FE285E1DA3BCAB7BA6C8EC +:10E7B00077D990867E6BF7A2A74E55C03EA7E74F4C +:10E7C0009BA50209C00B0FC6CB72BDBB86E77129A2 +:10E7D000FC9E579BD0FEBCF64A43367DAF8C98BF5B +:10E7E0008FA4CDE7EF45DB7A34E27FD189BA7D781B +:10E7F000EF275EDDD3AFC1F9F6FDC6C1304FE99B0F +:10E80000CEE3FE11F10A005E455784D7DE7959E464 +:10E810000DF072D58C1F8ED74F6A187FEF53617839 +:10E820006A2A87E3C9441D7381B0F739AF7E9EEA37 +:10E830008E7D0907154F2E0DED5351F464FDBB7B02 +:10E84000B0142320B678C9391545CA7C504DD3BBC6 +:10E850007983B969FD7B5BC6A6F5576D9894D24361 +:10E86000F87F79644A5ADFEDFF405A3FC866A7F542 +:10E870001B96DC9A06AFC6174EEBD7F96F4F9BFF7E +:10E88000417D455AFFF6B25569F39706D6A58D57D7 +:10E89000FBF63C84E5A368F94C6D2C23799C897CBC +:10E8A000CD3B63903C6E1FBCDF877211AF8E521E52 +:10E8B0003D90DF5F8CF5EBE79CD9EB0B0FD6A8D230 +:10E8C0007F17A3BF3718CFD7E4FC606922AD2EBFF6 +:10E8D000AE86FBE735354AD63A41A63F967E58FAD2 +:10E8E000E5CCFD33FD6EA6BFBDF3E67D1E5EEFE712 +:10E8F0007E7FA59083B6B29F7A13485703AF2374E7 +:10E900001703BD5EBA8F41FA757CE5DD93F1BD5A00 +:10E910006E9939D65D92F2D7E1B218FB258CE7FAF1 +:10E92000626CCA741C8FB175D3A92EAD85CBF9F377 +:10E930009BC4F3F5D8829FAEB5F12DD3FF063D33CE +:10E940007F50C052F14AC31F8D4801E0775BF3410D +:10E950006D1CB461EF31CD6E874E57FF6ADC087EC7 +:10E96000FA633519FA84EBFA8696BFA31F78B99536 +:10E97000D7DD0FB57A581CE83BDBEAA3F6E7AD7E9E +:10E980007AFE7CAB4E6D476B19B5F1D6008DFFACAE +:10E99000B58ADA675A0D6A4FB4D6537BB2354AF35B +:10E9A0007ED4DA48ED8F5B4D7ABE4BE8E9FB051F5C +:10E9B000A34CD615A2C71D0AF1B501AFEA2EB86067 +:10E9C000A8763B0F7CFD4236BEBE577F12AFEE9D50 +:10E9D000847206FE2AAB3EF5D6C8B83E79DE84972F +:10E9E0008C87317F413991753AC0EF31C4CF8DF5B5 +:10E9F000B9A2ABC7EF88A8DF1C29648DDF1670961B +:10EA0000E5A33DFF4A3444F67CFC4CB2E77EA6A564 +:10EA1000DBF39261F67C2DE91D3B897552AC2FD258 +:10EA20007B8A8C3A4841AD4EEB641D64D11F791D41 +:10EA30006434FA81EE9368B7A4DDBE52BA879DC7ED +:10EA40006CE327C83FE99F87F90F7323F98F2AA149 +:10EA5000B34C7B93E2C43C41CFEE579617A07D7137 +:10EA600023823C4F3758159E3393F701F66D281ECD +:10EA70000EF7E5EA5EF2E73B9271CEEB14C70CF7B6 +:10EA80005FE97CC058C8EEDF810FAFA6FB45CE879B +:10EA90001AF5BB896DE09F8F2418AF93CDE1EFEBA2 +:10EAA000A41F3C7281D7312E694A8CC1D185584B45 +:10EAB000CF3C680F7F8E8D8BC2395B931D810330F5 +:10EAC00035EFE93EDD03F38209736C0E8C57C57395 +:10EAD000685D68C9CC18F61BA2AF937D0A69E97E10 +:10EAE0001223D4A4DFA1225851467F626ABE8AE76E +:10EAF0005B9AEA03DCF5B34DAD16CE65F9C516A6F3 +:10EB0000978B7AAA37AB7FDFA8D8EA6C1A0B7422EE +:10EB10001DDA6776F0F77A19F226F924EB6D320FD9 +:10EB20007F8419BEDA2CF143BB78EF92F9BEE50F72 +:10EB3000D34D7F2DF05DF19DA0F72D6C03E3F723FE +:10EB40001C909F20FFC6B862074A86CBDDC1591FC3 +:10EB50009C5C4BFA6D29D7266FEF51286F177913FC +:10EB6000D3EF73D8F318993765E6470F0B3BBB0B10 +:10EB7000ED2CB40F3B19E55B1D4A6E609F92CA975E +:10EB8000C06FCE40BA16D58AF72FAC651EAF177E80 +:10EB90002E2D5F1A116F91973893E75EEC3B9F978C +:10EBA0003A77AFABC78FF71CBB667EB5B109F936B4 +:10EBB000D343EF399916D7D1EE64D2C37C161B37F5 +:10EBC0003775DE2AD3CE637DB61382197CDFBB1383 +:10EBD000BF040078F901475ADC5350951EB7DD5D3C +:10EBE0002BEDECB5A1030580DE6F4B3C5954D45599 +:10EBF00079FCE911CFDB756E2F18DA3BDBFBF5767C +:10EC0000AFE1F1D9CE7F3B9E8F7B647CD492761F9F +:10EC1000D6C17BBC0ED2EF4E5DEBC2FB1E9D5E8D5E +:10EC2000C737BAA33EDBFD95DDB58AA09BE3E513AC +:10EC300078A9C1E514078DB45FB79017D9CF2D37E8 +:10EC40000DD2473D10C53CB9CD3B4EC1FAA81CFFC3 +:10EC500068AD22E485D797BB445C955BD61B77A053 +:10EC60009C4D583F1BD9E68138E93C3CF794F7525C +:10EC70005CE59DE832B3E1FDCF025E9733504F79FA +:10EC80007FBE8361DEDF5592DD8FFE632D8F33DB28 +:10EC9000F459519C6F015FA629C3E77D5CC8C1434D +:10ECA0004E9043D8BF6BDA5D744FAC6B3223FB5D83 +:10ECB0005A37FDD1ADDE2C72A8DF47E7E7F431F912 +:10ECC000FE3DEDBE449BDED0B816F6D59E6701B47E +:10ECD0001999FAE69CB0BC712DDEB7A8CA0DE0FC0C +:10ECE0001AF5C716F2B123C0A8DEA115367BA8EE2F +:10ECF0005CACD1FD08892FC4EB8FA19D1A4DBE33AA +:10ED0000F181FD48EE463ADF4CFC28949FF50EF366 +:10ED10000BCDC66816783F4FEA55BA7C394791AF9C +:10ED2000D1E849F3AFC529FFFA6CEDA675784F6DB0 +:10ED300027E3E3A76A4394EF67F6AF959EB7693D73 +:10ED40008D782E6D535D247F99EBBB4A385EDD27AD +:10ED5000AAC5BE3E05E57F5755510EDA772F1A6AD0 +:10ED60001B5F9FA930CFD5DAE2A6C2482F8FDB6B9D +:10ED700019C9AF578FFAA6825C78CFA82053C07705 +:10ED8000C7DB7F3CA7BF773EB21E83E4964C3B9720 +:10ED90005BF636F0A54088F518F6703FBF2FB299A4 +:10EDA000E6497EEDBEF1B781F83BF06DCCC2F4FAD6 +:10EDB000D4BBAD3F2975F9E388CF392C07F97C899D +:10EDC0003DA890FF8E18A477BEA45DE5F756C6C98E +:10EDD0002E90837D123925559762F8DE03F5CB64BA +:10EDE00014DFD0CCEBC42B2FA2DB47EB260930136A +:10EDF000F1428D8AF2CFEDEE25F61ADF1F96E1BDC6 +:10EE000015C572909FBD11E51AE69530F34FE7B234 +:10EE1000DCE799EC6B3EB80EDA4975A29E26E8193C +:10EE20008D1F12EFBF94DCCAF820B38E2AEBAC1D05 +:10EE3000A2CE3A5A1D956917896F32FECDACABD27E +:10EE40008D3AD08FB76ED25837F19DC70BA93CDFF2 +:10EE5000CAE375787EFF6E9EA0EBF0D9A45FA4E7AD +:10EE6000D26E65D2F9E4287EB1FB4C7B1EC2694BA1 +:10EE700034517DFE907FDB2905E3DC844B67367DD2 +:10EE80003D9C9FEE373A84FDDB5627EAF0E73EA52E +:10EE9000627D609EDF52F1DE5E5522407EA14DC94B +:10EEA000FEDEA1BB8EFB9B617E22E3FDCC7FE6787C +:10EEB00063AE5296F41FAAA053FA57E08F62D7BBF5 +:10EEC00043F2BE9761E8BEB9A9F8B3FBE98F321DE2 +:10EED000E323BFADEE5B9A65FF617163BA5F5006D5 +:10EEE000F9FD30C9D76E9177B7F9F979CC4102B203 +:10EEF000F801887F3F5B07F254D99F6E6FF2CAD248 +:10EF0000ED4D663CECF6302BD7060FE2E1D63A52D7 +:10EF1000DEF478B6B89E91BC1E2EB454ACFF8413B8 +:10EF200006C3F3D08A4D86E7E1F2BFF37934D6F118 +:10EF300078A1A3AC298A7993AC3FEF5E741BD957B3 +:10EF4000F0A33D75B6BC49DE7778B7F52829AF5AEE +:10EF5000867E66D6A5BA17FE3DD5A1DAFC4D27B14F +:10EF6000AE7408E411F5ED70BE9987F725ADE7554D +:10EF700076401F5EBFCAA44BD6A1C6D78B7B2BE7BA +:10EF80005CF1C5788F7290BFA7D0064DBA7F02F4AE +:10EF9000D07BA279E23D5166DDC9ED6EA1F773F138 +:10EFA000EA9655F6BAB3E45BA390E797AB4DBA3750 +:10EFB000D43142FD4FCE7333C31A87EFC7AB3F4BFB +:10EFC000FCC6CFCD302F97752D7D86F9BD3A98E7D9 +:10EFD000BA68AAE375CCE72C3A87BC7F6224642C1C +:10EFE00057891D80F54F2F7A8AF2CDDF27D8587CBC +:10EFF0007F92CC37359E6FCA3C56DA8D1AF589CE92 +:10F0000052183F7C46A33838EFE9AE5358770F9E2D +:10F010005947399FA1ACCCC37DE43D2689F7D5E69D +:10F02000AB9598AFDADEB748B8DF69ADFF05CAC562 +:10F0300093AD516AFB5A0D6ABB5B1BA9ADD28C30F4 +:10F04000FAA5AA7ECA00D9822118B7E1517516D651 +:10F05000DBCE7F5785F9DFC8B7CAFE68DABCBCB221 +:10F06000C6B479902FFF1AE7697ECE4FD71285EE8E +:10F0700027DC39C81E52F42C76E1FFAE5DCAAFBF63 +:10F080003676A9A89EF29791EC1223BDAB1A14EF25 +:10F090005DA57D12FAF7789D4E7A91D4437CFF4AA4 +:10F0A000FECDA2F59DF8E77CA067CCC7B81D4BDD6F +:10F0B000F3A0EF1B83E2BBEB9B4F2EDA8FF7803A76 +:10F0C0005E94E3CBF71BB67166D534E3F726C73001 +:10F0D0005986B873C7C9F1CDF45DB6F8AE26DC58D1 +:10F0E000583CC052F71F33F9B5AB9EC7EBF27E4DCB +:10F0F00090F1FA9A1CFF64BDC8E3801CACE3C9FB25 +:10F1000013B9237C47F4F17A6E0F3E23F8D4E9E279 +:10F11000F71716677C2F1212FB8EF4BDC836313EEE +:10F12000DAF721ABC47E4D62BFC7E6446FA3738B91 +:10F13000F2EF329AC5F30567626D633068F4B3ACE1 +:10F1400070960B7BFA6C3DBF97ECF21B1A9E0BC0BE +:10F150006B20788DFCBEA61C5F702139DE48E30D64 +:10F160007C7CC10593EA4AF23BBDE5F565FBB74EF1 +:10F170004DDDD3E9C0FA8417BF57E1F79FBE26F0F3 +:10F18000CF6CE5F72A77F9C47D1F3675BF81700C07 +:10F19000FE7DE6EDF5B70CE177C7B0FF06DA5F7CE0 +:10F1A0009FB300E9ADA4E7FF40CF33FE9D81F5F5A5 +:10F1B00093F78BEF7AEE433D612D1CEFE4BF9B602C +:10F1C000CDD96FFF4E6841FDEC66317F33C1DBC0A6 +:10F1D000E7679107218F73F7634DF60AE0B512BC1C +:10F1E000D51CBF5BEA757EDE19728BDFFF139EE2D2 +:10F1F0007BA133D1751EB4E7C97F07C09A4EFB5D72 +:10F20000019F76121C53EEC7C4BD28AE1752FEA54F +:10F210003C7C4BC8DFEC7A45CAD517687DF335A333 +:10F22000FF1B042FE3FBA4D1E828AF887E93D6F917 +:10F2300093F793FF95FA57898FFC9E2C532FBE2787 +:10F24000E8877DFF83CE0BE22FC413F63D742DF6C5 +:10F2500005B87182E349C23D762DE032FDCAEE99D0 +:10F26000FC2FBAA2684270460000000000000000B7 +:10F270001F8B080000000000000B93E16660F8514E +:10F280000FC121486C62F17A76068678160686B937 +:10F29000AC0C0C3540ACC8499AFE5540FD4B81780A +:10F2A0000110CF06E269403C11887B80B81D88655B +:10F2B00080E68903B11010F3023107103303F13FE8 +:10F2C0000E06869F1C08736E03C51E93683708DB05 +:10F2D000F220D8E781FEDF02C437C80887513C3CE2 +:10F2E00070163F03439D00822F2C882A9FCD8F608C +:10F2F000F38A5266971C503F008DFE9C5880030095 +:10F3000000000000000000001F8B0800000000004B +:10F31000000BE57D0B7854D5B5F03A73CE3C333312 +:10F320003909794C20E049483055C0214004A1F505 +:10F330001010432FD78ED42AF5A2774004E49554B9 +:10F34000B1D2AB6D46264050F4060B0A0A3A50A8DB +:10F35000D08246C4962A7A07454BFFB6365A6F7D4F +:10F36000D4F6C6DAEBAB18E28362FBEBEFDD6BEDB4 +:10F37000BD33E79CCC24A0C5DAFB874F77F6D9AF25 +:10F38000B5D76BAFBDF6DA3B1EA884C273013EC68B +:10F390001F96DEE60180E24C3AEAFAAF2EDA3386B7 +:10F3A000FDFE7F3DD11D46A69E4C4F0305602C2BD4 +:10F3B0000713A004E05C1FFB95D59BFCD323BF3D46 +:10F3C000AB08E020A8E0659FD2DAE401FFCCFA396F +:10F3D000F82144B1DCF5D360796710DB25A8DD970F +:10F3E00080B74B5718E5FA70CC800BBF9B3EFA9D57 +:10F3F000F5337473136B7FEC8320B577C22153F818 +:10F40000D00569D1E6E34AEC577BBFB346E42B80D5 +:10F410000D0E02DE29007519780FFDEE7582F77169 +:10F420008DC16B6419DFC7E02FCAC07F10BE9A0F71 +:10F43000C339FC665D06FE938587E6CFF09C6C368B +:10F440001EA9AA0658DB0C8F54B901D634FB28BF7D +:10F45000BA59A7FCCAE608A5498D356170247742E0 +:10F460002AC1501F8AB2FAB27FF65FA0CA67CBFBEF +:10F47000CA755BDE53C4FAA9C9E4B5A061CB278382 +:10F48000F5BE7810C76773F7E2F83E4A1998CF4582 +:10F49000183ECEE455C16F246602A34775D063A41D +:10F4A000D83CCE0CCE9B0E61AC7719E1CD23F07A1F +:10F4B00075D98A4E84F77D560F58BD338253DFC409 +:10F4C0007AFFA7E2FB7C1E1B014AD9F7D5DF6EEA63 +:10F4D00054587F2BCB3CC60A36AF7BD9F8ADA75B1F +:10F4E000F0B85BFB03E2CDC7FE211E6B36F37C66F2 +:10F4F000DEF6FC19C0F272DE15997E4EB6DF61EBC6 +:10F50000FBEEB7DA88D523BFCA7E87417C851EFC17 +:10F51000FCF67B26C3F980DA4CBF729C7EFB65EC5F +:10F5200010636D876D86545AE93D4EB5116D4820C4 +:10F530003F6CD62055C1BF1731B9A81672D1A2CFE2 +:10F5400008205F39E101EB389519BA54177966BB89 +:10F55000189F54472E5EA4205FADB7B4AB049072E1 +:10F56000F3EFCD3A986C1EB734D750BAA3596F4712 +:10F57000B9B9E5237566FBF0DEF2F8DF425FDDEA3C +:10F5800006E2BFC42E48ED50B0BFA61766B3FCDA42 +:10F590005125B53719989FE942FDE0177CBC5631DB +:10F5A0002EA9C4FACFA8807AD0290FB7B8635F46D6 +:10F5B000795833CAA5AC403C577179A876A77D43EA +:10F5C000D9F7B5EB2B473188616DF4599287EAEA98 +:10F5D00061868AF25025E461ECED3ED4873DF35F0D +:10F5E0005ED25E3500201FE913CCD04B3F413ED0A8 +:10F5F000275AF0F519CAC3A9E3AFB63EF96B6DB44B +:10F60000F24D2F2BDF51E53154A5375C85A7A5239B +:10F61000B1E1BDF9ADBA4AF059B46F3E73A62B9B68 +:10F6200053F02A1BFCF6E608F1DDFA6683D29B054F +:10F630001F7A91A7C6B3BCE043281F43F99CEB1681 +:10F64000DC487CE92E4A01CAC9EDC89FE7E0702B6F +:10F650004D7322D3913522CF9648175B03D663F9B9 +:10F6600040CA9B508EFC29CBF7264CD6BEB8869755 +:10F6700037287B13B866DCEEE7E55F56BACDC444A5 +:10F680004BFBC4CDA6599EA9CFF2E97ACDDA1FEB88 +:10F690007FB8051E3844F5657FF39457797F7EDE89 +:10F6A000FE26E52533517EEAFBBF49698B30D30244 +:10F6B000D638FAB9A927BFCE348767C6A9BCF17E70 +:10F6C0003311B496DF6F229E64F938655D22C1EA7A +:10F6D0006F845895C2E85038B329C24C23F0CF4A02 +:10F6E000996EC30A1FC777667EB713BC812A5E3E38 +:10F6F000E2C6E7CC6455A67CB2F2AB04C2EF2F8A17 +:10F700008321EC055C1FDD9CC5981D547ECD2F1810 +:10F71000DFBB4B3D51B23BCA59A68C7D8FC4C1AAF9 +:10F720000FDC11ED35AB3C4B3E64F09E43F0C69AC6 +:10F7300066E68037618557C2D31FFC128EDCFCCA97 +:10F74000C777F255FDA5E37E3591B1BABFC31D451C +:10F75000B3014D282864BF7CF85D53615D965CCE93 +:10F76000686010FD66C2D0DEFD96CE1C08298BDCD9 +:10F77000FFADE95B85798EB7D94A7186CE2C7F853E +:10F78000158FE7887A4E3E94F3F3F49ADF15B6F9B5 +:10F7900081D6168985FA9FDF7A7F7C662CD8BBDEFE +:10F7A000D38A42E3D7CF18F715E0E381B782962CCE +:10F7B000136A33E3155D2CC74B651DAF38766AF1CC +:10F7C000E9944B09AFBF17BCDFB5C17B939BC96FF1 +:10F7D00016FA9F6A78034CBF9E941CD69C981C9E78 +:10F7E000AA7E8BF057C65FEF69903E97E175D98589 +:10F7F0003EB2FBA5FEFBACF15782458C9ECB7E79D9 +:10F80000C52BE7BA30C3F87C4466FC26C520B87324 +:10F81000F17BAEF900A46CFDFCBDE6930BAFA75ADB +:10F820002F9DA8BE5DF19B00A07CADAE8214DA18BE +:10F83000AB0F9F970FACBFD5BF985C8A70785BCF3A +:10F84000047334C0066CC2EC8DD5D2FEB8A8F68421 +:10F85000EC8F9B9AA1BD85D9350F859BC85E5AADAB +:10F8600000B567FB524831BB66CC33DB7DB311FE7C +:10F87000E86D94AE76B3F2207E3FA44F66530854F1 +:10F88000178E62E883D57EF9FDB986A1ECFBCD55D4 +:10F89000EC3B638DD521DE1FFB1EC3FA79D5FC7BC3 +:10F8A0002EB8F26A183C16BCFB3DA978367D59EF9C +:10F8B0007211FCB7A13DE6C5FD8041A93FD01647B6 +:10F8C000A60B0CF118DB2A7AB79BE5E2FB8175D514 +:10F8D0003F4AE3D67A8DB0EB1E3FEFFBD089FAA208 +:10F8E000AACD7461FB28771DDCE6B0BB82C3657EC0 +:10F8F000A03299751070E46FE9B1E32A27A11D17B2 +:10F900001676D0792BCE9D84EB6C4F398CB295CF87 +:10F910005971F624B4DB0A7D4D2F4C64E317327D18 +:10F920009A44D1D10CA509EDFF8B0AB3F2CBBA6989 +:10F93000BE992956BEEEBC61155766D9FF302AD252 +:10F940007C657E40839DAF6F1376EC2DC2AE2D4754 +:10F95000191F2BF88F098B9F57EDD16BFED3B95E22 +:10F960000BD41837225F0E688028DADFEB18FEE22E +:10F97000163AF96BECFAAD50B3CFEB54CD67239840 +:10F9800097B9C6E6EEDF295F1B217E25D62F14EB43 +:10F9900056A026AAC487F73F7FE77C73CDFB2B02D6 +:10F9A0009F6C9CABB38DF359E1A530C8C619F3B772 +:10F9B0001F2780E358D7B113C43B2CDE6EE27E1BB9 +:10F9C0006510F7737E98124DD33EEF7AF2D35D2B1C +:10F9D000FA84F8261DED1C82394BBF5A9527E36F38 +:10F9E000C3FFA9B3F2B3D145A6CB5F7EA7E090A534 +:10F9F000FE7657A8E835DCD49F0D677FAC66DA83C6 +:10FA0000F0076A128E60A14D9F1E6FEE2E38C4F46F +:10FA1000C6CDFA0CD2C7B9C6FB21D3A3692657BB02 +:10FA20009A7D94DEDBAC43DA8B7E8B08A5DF63F234 +:10FA300087DFB7B27D24A6F73447E9FB96E67194D9 +:10FA4000DED56C52BAA9B981D23B9A63546F43F3A5 +:10FA50004C4A7BF0F9211BAF4EAC6FCCCE3A7366AB +:10FA60002AE1423FEE3E885633FCAEC6EF16F8D789 +:10FA7000B9263D4E7232D34F7E8F02E1F70840CA5D +:10FA8000ACC276CFA9B00372CF2B29E67581EAE22A +:10FA9000E36B35347840CACB6EA075AB640A5BB7B4 +:10FAA000185DB582ED85885796A7EF056C3D43FF3D +:10FAB000A07F0AA4FD23A98986ED8B44FBD6A08BE9 +:10FAC000EAADABD168DD73F2C508D0A75561E59802 +:10FAD0008FFCD4BE90C6EB4FE4E3159CCF143DB32E +:10FAE000EB5B751775BA6E0C5F3FFD358C5F2C7242 +:10FAF0005130F50F486928572B691EEBC2535E64DD +:10FB0000DD317ED4CB2A583F77B02D35AE6BBBB6F6 +:10FB1000BFABCFB6D039A8727B7DC4AC773B10BFEA +:10FB2000233426D76C1C757B2085EB0EA3878AF0C7 +:10FB3000E60B0532C2C7E7ADB6406A9B9229D70BE8 +:10FB400038DE47E85113D7B99EEF7EF1DDE84EABC2 +:10FB5000D82E05D16D46A63C24DB99F67621D92E08 +:10FB6000018A86EDD6B37690290FCB7630CAD62E91 +:10FB70002CDBC1B3268DB7D1DECE5F207026E61F09 +:10FB80001E1775C52DFAC15F65BAB8DCD8E9948B2C +:10FB90007F8A40D0E1F184F231E2630ACF2B8AAF51 +:10FBA000F56317FAB3EC721D1E63A71B5459F28C50 +:10FBB0007417A1EC16931DD480F6C6B6D6ECF4DA11 +:10FBC000A0C5A655E3FC266AB6F9493A6DF0093A94 +:10FBD000B606B2D269832EE8B8006C7496F4DA20C7 +:10FBE000E9B52C3BBD36E4A0D70649AFE5F67692E1 +:10FBF0005E1B72D06B83A4D7627B3B492F273DC22B +:10FC0000E3D28A9D6E6D943F55F470EA850E97415C +:10FC1000DF5DBB4D7D12EA871B34DA57438DAEE0C2 +:10FC20007E00CA4F70FD8026C075612DFE2AED331F +:10FC3000368F5D788EC5ECAB39C95727A11D1E5490 +:10FC400064F9A14968876FF3F0FC75C9E393D00E9E +:10FC50007FC4159BAB92BD93021ADF812F6F2C05D9 +:10FC60001B1948A76B4D3F43BE397DBB2B9A3032E1 +:10FC7000F07881E305B7EF1F6759BF72CF43E017F4 +:10FC8000EB0C3D2138BF45706A299A772F382F62D7 +:10FC90007032BBC240FE66FC6BB49E1A38612E5FA8 +:10FCA0002F7AD667C7FED7D9FE8CED2E1BDFD46C1A +:10FCB0000ED8F866D8FA425BBE6AED405BBEB2A5CC +:10FCC000D296376E38C3D6DF9065B5B67CF9E2734D +:10FCD0006CF98173EB6DED7BF10B707ED9A9BE7C65 +:10FCE00023E2B9870E899A7AA283A8BF3B59536F42 +:10FCF000E3A71CE55FF9B666FA18FEB5220FAD431F +:10FD000000D7107E24BEF275487850BF140553E723 +:10FD1000B3F2806E26D02FA0EA26A01DE1D2E39494 +:10FD20007747ECF275211A4A8CFE5FD9A5816F4C9A +:10FD30009FFD9B9FA4FFFEE6E5E417B9BEAB457CA3 +:10FD40005DBD836D97D0DF9360FA71071BD7CDCC73 +:10FD50001C7F18F942F00FE367D42B459A22F6175F +:10FD6000272767D529BBFE19BAD10E7F459B431FB4 +:10FD70009D207F7F56F2DB1FFE364034817ABC3FE8 +:10FD8000FC8DD114A1FF4E4EFE872CB3E3A77CB1AE +:10FD9000C721277F5FFCB5AA20F8A2A91EF112DABD +:10FDA0000C705305DA5DCFEAD9EC0AC92F77CCBACB +:10FDB0002D60B5F7618CC776FE2EC7A1BC9A2DFFCA +:10FDC00079E313A847FB2394E03EA46DAD39E62FF9 +:10FDD000E8BDE1A2CA80753DFFBCCF3F43E76F9FFE +:10FDE00054FB480FBCE5FA6B7916F81DFBB2DEED4B +:10FDF000135C5EE27E97554FB29F1AB4B7821088AB +:10FE0000229E8FFBC323219FED0F7D3C3DD5FBB68A +:10FE10005DB3F8FE26F1725EAA1AF189FA1DCF8D44 +:10FE20005F1E9122BA5FE482DBB17CB88BCAAF0B54 +:10FE300084B7215C5F57E3D76BC508EF9014C55FAB +:10FE400068697D46C8324F6117C9F9E7B28F56B568 +:10FE50005C5B6F5BEFE0E27AF4634A7EBCAB654DBE +:10FE6000BDB03B5AB5CF957D9413CE2D1AD99B9F2B +:10FE70004FFB4885ECFDFCA3D847BFD096AEB0DB66 +:10FE8000470F733A88FA1D2D0FD79F48B9B48F02D8 +:10FE9000418FD8D73BEC971A661FE1795250D82F83 +:10FEA0003529B257FC35296EBFD4487BC6BE7E5D6E +:10FEB0008B066871C63EEAA37FF393F4DFDFBC7262 +:10FEC000ADEFFEA0B48FDAB87DC4708DF1276A0D56 +:10FED000F77BA88EF57D9CFB7FBB7D945D7EFBC38D +:10FEE000DF0668E3F6513FF89B990B7FFFE0F6D100 +:10FEF0006E0DA47EFFFFC43ECAC527FFBBEDA30C59 +:10FF00009DFF36768ED3AE9176C4A9B66FA47DC21E +:10FF1000EC981A0DF51EB3B3D08E39EE6AF7DDCE2C +:10FF2000E6739DCAB03514E356F87EE6062DB6C1D9 +:10FF30004DFE8DB48E76C666D4E763859E45B90FB7 +:10FF40008AB83D2D0A334660FDF866B7E51C420DC0 +:10FF5000A6F59E739BCF111E989D679FBFC08BC453 +:10FF6000C37E7781DCF79C1DE3F3FA31E101D2DC3B +:10FF7000DED2D23E4CFF43AC6FB41E1759F1C1F133 +:10FF8000A3468D14EA03D6FE3FDCC536BCF86C7878 +:10FF900061EB101F0F546ECFC9EF3C0D8CD115F4DF +:10FFA00087B36C07F2EF002C3298BC415BC330D6AC +:10FFB000FF80D8AA6F60FC5CE8E5696F02D3BF03DD +:10FFC0003A674FC7B46578EDE17A562F3FAA5F389C +:10FFD000D5C07515C8AFB8063BA3F3505772D270A1 +:10FFE000718EC3E4F9D995C7853C9B60B7CB5D861C +:10FFF00026FD4995B9E585FD281F7B7BB7CF251FD9 +:020000022000DC +:100000006EAB5C937C5E7D62F2399DCB7582FD4365 +:100010007D51E0E827DFB4AF1321B0E459F98782BE +:100020008F01BEF1998CA7C36D3E03E34FAA5C3AE2 +:10003000C64DE6835E80FC1798A201C659EA45DDED +:100040000974C1F6479716E14747BBFF42CB7EA232 +:10005000C0C3E5B568C6948A95ACDF6363787CFE5F +:10006000009DC7813AE77333CA97D7921FBE8DCEE2 +:100070004D938C9F2AF9FE86CE6FD654EDD5ADEB0D +:10008000D4688FF47338F9832DE175C29E66F851F8 +:10009000AB5C26DA019F963FD44FC81F79D31DE78A +:1000A0004927492F53DCBB3851FEF8B4E349BAF66F +:1000B00096AB1B894F8B66CCF5A1DDBF2A32A3CF4F +:1000C00073D4DE74BD8DE81AA8023395A5FFF33C06 +:1000D0004A26AEC0195F6BD91F39ED75B5B46EE60F +:1000E000D6BEE856E4B4CB78BFFEE5AAF147545E2D +:1000F0009A4EEB804FF4B7C6B82D81FAF318DA0C9C +:100100000C1F6ADBA834EA4FA882E80E5E85E23F46 +:10011000FC8649FB703AEFAECBC0E72977D9C6D34E +:100120008A02F6F3E79909C50ABF7FB987E0F0E1D3 +:1001300078A8A775D6A182F730B87FAFD7FED16176 +:1001400037AC2EAFCD1A67A0FDADF6AB17D9E13DA8 +:10015000E17641CD78CD6247E56EA7C16B167BAAEB +:100160000DF9DDC207ABDCB05F61EB70327231C4F8 +:100170000D96C7A23280564CC7231FD6F2757DA7B5 +:1001800042E7C324D206FEC7CF892EF318D49FCBF3 +:1001900017273CA94113A8BE7162E748C707F3F8C7 +:1001A000A422056CF5EFF778A85F0D62749E7EFCC3 +:1001B00077E747A85F937DAACBC0E1ECF7324FFC0D +:1001C0007E4F31B21D87071B903F621CF70BD0DDBD +:1001D0001CD6EEF8BA19749F28177C9B1CF2B549FF +:1001E000C465416C4C3FF3E2727C9C8DD981F5B5BE +:1001F0005880EE2DB5717B68B0187FC7B219F47DB9 +:10020000C7FABEE57C8BB08FEE42FB88EC1C9DF2FA +:100210003D708978B33B057CF27B8D97C7671D15D0 +:1002200072BFC36706E85EC013D3025F60F255F980 +:100230009C1AC523CCB2356D057D8D3F70AEDD3F78 +:1002400072B2F11D9D9E5011D9D18EF88E5CED6574 +:100250005CC7A7C5CB9D621F53E35D90A4F393F4E5 +:10026000B9249F95428F542E03B2E3062F8694C182 +:10027000EA1ACBDA47A591AF3FFC18AC7C3218A242 +:100280002E20BD600667D7D1BD094EBF36179D53DE +:100290000FBECA93C290B661C20E838DFC3E83BC72 +:1002A00077B1C3175DE1457DD74A961F5426ECF719 +:1002B000440683E57E04D32383D0AE637A6990E35A +:1002C000FBA7A54381F7EF43874D5A9B5FB7B42F38 +:1002D0005320966DFD3BDDCBF9B4ECCAF779FCD722 +:1002E0000D417855CEBF12E9D9568074B86BEEB384 +:1002F00093F0DE49A215A2781765C8727B1C449D55 +:10030000378FDFEB00338DF6F2CAD917773E8A7448 +:100310009D0836FD95456FD479E93E08D71B9BE6CD +:10032000CEE0E9872AF149D53248E13DA3296D4D58 +:1003300007DD2C5FBE1CE8DCBCBC35A1A03FABF2E6 +:100340000688E23083D181C7F255B32065D2FA0521 +:10035000CF45EA68A9A39F0AE4135C775AECF773C8 +:1003600086DC60E78BAA56FB7D9C52C117A50EBEAA +:1003700070F65369B44D4378872E73F17B3B33EDB0 +:10038000F76BAAA0FDCDEFE37C0E05A3C8EF556B7C +:10039000EDE33AFBD720FE75C4CB434B374F3B9D73 +:1003A000D5DFB2AC7E00E265872F964FF7A2F01240 +:1003B00051967D712F7E95F6468EFA19FD99B0C53E +:1003C000333BD3D5D525D7CC61B5D6841240E327AE +:1003D000BE4E7ADD2DE4F589C1F3E85ED7AAA25AB4 +:1003E0008A0B3B8879B4A7CA87955AF5BD1BE3767B +:1003F0000764F22B518F66E1F3E5822F5F077339B3 +:10040000E26194B72982E37ACA4BDE9BCDC663CB07 +:100410009F99CAD26EA137C0E7AB6B7FB5DF6F0A79 +:10042000EAAF894B6C24874527E657B8D21BBF1922 +:10043000C74FD4B36D04EE3F0B219544FA36B5098E +:100440007F7B4FBD36512F81F73B7BEAC5DBC0BABE +:10045000DF64F536887AA6AD5EAC57BD3B453DB04E +:100460008D6BF61AF71E091F58FB8BF6EA6FBBB7A8 +:1004700098C307D6FE8C5EFDED92F0D9EAE9BDEA9D +:10048000DD27FA03DBB8601FB7A77CA44794C72811 +:10049000FEFDF1E2A9C41F878AA736E07DC46B7E0A +:1004A000E6163AE2725AAF55C1570745BD96602D20 +:1004B000D90DC966685DCCF696AD787FB81AEFF1B4 +:1004C000CEA17DBEFC2EE9C7BEEBD9BF5F4DF77E46 +:1004D000E577ADD54F71E4EC3BEDC35A3E52851F35 +:1004E0006EC0143CA76C8DB884FFFBB5A459C5E45D +:1004F000BD4CB3E5D794F3F251ADAF2513789F48C7 +:100500008BD1FD146F041E196ED1233DE37F66F07D +:10051000F3738C0CFCEF3BE07FDF06BFCCFB07F3F3 +:10052000F2B1BE639313ECD795A84BD97E7998AFFF +:10053000B885D6F3CFEDFC5C2DA6669D1FCF67E690 +:10054000C7F3727E67FBD429FF58F3D31DF3D31D85 +:10055000F3D36DF31BEF2B9882FC78A2F373D6BB19 +:10056000D91D8BA0DDBAB2F84764FFAF1C0CD4EFE5 +:1005700004DF8BC91BB19CC97607F56794A2BE1F27 +:1005800005E6085F71FFED9EC62072DCA786787CC9 +:100590002A147BC439702C82FECDB7BCBA889FE385 +:1005A000707A7C3ADF37897CA523CF7EF92BAE9B0E +:1005B000189EC8F7910E3DDFDFBA5651321AD7B5F3 +:1005C000D690A958D7354FCFBA7631AD6B2B23D9FA +:1005D000D735DC36D3BE48AC357734F3F7043688EC +:1005E000FBB12BCB6BA9DE06793F253195F49B5CE3 +:1005F000371FFFDABC860AA61FDF7D8EBF1F71C0C2 +:10060000C7FD3FAB9BA19DBF87E0A3F431D66F9C94 +:100610005538C0EC3D4C1F66F61EA6FB9B2394FE8E +:10062000A8D9A0742F1B17D3FB9BA394EE691E4778 +:10063000E95DC25EDC24FCBD5F2A77D1FAF9BD66B4 +:1006400058AB55A39FD747E93DCDFA5ACD8DF665F6 +:1006500084D23F2B3316FAC85FD199CC67F47AE87D +:10066000D92ABA373EB15C237F076869357F4CE6EB +:10067000BBC4EB9F95FA461FA3D339868BD7F3A54E +:1006800092E1ECF59661BD718646F04030A1868B13 +:10069000B2D6FB16C25157C4E1063D9E0C65EFEF82 +:1006A0003BD85F6D9180AFC84806B3F797C4FECEC4 +:1006B0008A08F822DD8FE765AFD78AFD8D8808F8B4 +:1006C000CA3BEAF3B28F7B0BD62B2D6CA37B3BE7A7 +:1006D0002E06E26F6FB9B1957C15A2DEB6C14DE072 +:1006E000627C5B3AA0AD09EB7DB12906952CAD2C5F +:1006F00089818BF1BFB78895337822A29F097379DE +:10070000F9362C0F59CA45FBF10B5839CB5796DAFD +:10071000CBE578DE3690FA24CD8C50F0AE859EFB8A +:10072000D5982F71F1FC1EDFBF4C41B92F11E74E58 +:100730001D22EF6DB1B72F09F07C1ACBD938256196 +:10074000DEBE53D42F2DE4F3F65FEAA338E17BBE7F +:10075000FDCDB239C333F33DED3BCBBF30C732BF24 +:100760007BBE731395CBF99CD6BC96CA73C96B64D8 +:10077000960B4C8BDE2A691B4EF6A4B40F479D7670 +:10078000717A36A38B3BC6E1EA6EAD6C5951457068 +:1007900025E85C55C0B5E55A3B5C83BF69876BCBE8 +:1007A00037ED700DBEAE6FB80EF8B85ECB051F1BEF +:1007B000DFB48E9FBAD13EBEB1C23E7E6A857D7CDB +:1007C00023F9A9C74F5BE972F7B7ECE30FF937FBE1 +:1007D000F877FF9B7DFC21D77FBAF1FF56F6B8E989 +:1007E0008B7FE413F6AE6AB53B9B1236BB93D57391 +:1007F000F985BDAB5AEDD878C266C7B27A5E51CFE3 +:10080000B4D58BF5AA17F40B7BDC36AED96BDC02C2 +:10081000512FEDB2F617EDD55F8984CF65EDCFE8A6 +:10082000D5DF20D19F69ABA7F7AA6788FEC0362E17 +:10083000D8C70511FF759D88FF2AF070795D1EE706 +:10084000FBEC52882BB8DFD707C0A843B83E0FE5B2 +:10085000EF21154C5D7E1ADA27CAD4E5A7E3FAD753 +:100860005A00B67DDB343FDFAF8DF3AB348E9E078D +:100870004D580EBE44D98596FBAE5B45BD9EF260D9 +:10088000A2ECAB96F22F8BF6ADE2BEE0F96B3A5AD2 +:1008900050CFE88358FD2CFC375DF627CAA128DA33 +:1008A0006132B8375E3663EC4D601DD7CDE13A4D0D +:1008B0008C5B9E1DAED60A3E6E4A8CBBD52FED8D4D +:1008C0004419E151E7A9FC7E7BE89BCA1F197E60B1 +:1008D000BBCFF61E5081A7E9DE0A064772B00BF0C7 +:1008E0007EC2EAF2BEFD392DCD76BFA7A6C7E81EAF +:1008F000F9C0057AAD0AB9DBDDD9E06AC876EE3019 +:100900005FCCA765417D5B15C277C8EEBF650C0E55 +:10091000D67BC89779E2F391CF7AF96F5B7CB67D8D +:100920007E4149DFF7BEE4FDA89E79B08EB2D1EDDD +:1009300056BF38E77A8EF72FEF9B1514BA68DF7928 +:100940006C383F2F80441958EDB18281F53EEBF8A9 +:100950006B1CE3F9618689F6272E53282F9E2A48BF +:10096000E1FDBA40519B5E81EB42A483CE0141DCA4 +:100970007393FDB64466D07EFC98B8FFAA45DA268C +:10098000B9487E047CBAD055629C811B354833BD82 +:1009900076C81DBFD55F6CA59BA920FE8EBB53E416 +:1009A0000F4A5630FA2BBDE7BFC9CFEF8FDD69CCB8 +:1009B000F8554516FADEED376CF70D077EE081F449 +:1009C000E8DCF533F5385C3D7C1B61FC3A82F40AC7 +:1009D000F1ED368FB9CD9F2DCE42EA0771FE3D670E +:1009E0001C881FE392DFB2795C75D80D284FF29E08 +:1009F0008D3C17BA4AF8C7E6083FEC5C8885B1F031 +:100A00006D70D1FDB1B7E1D9F0680BFD1FF3F3F3C1 +:100A10000526E0E4FF92E7BD57B6B96DFEB0F91BBD +:100A2000EDF97930A304F5D6BCF56E48317C5EE56E +:100A3000F097DD27E63B1F9A56A11DB0D2CDFDF2FF +:100A40007374D006B0A565C98FB7D4CD66F92705F4 +:100A5000DEDF627C6358E46D6130E5C1B89B57F717 +:100A60008DBE780260FBD4AA81A86F0B20EB7B704F +:100A700057B4DAE1EB0F7E27BC002B08DE5C706810 +:100A80003B95ACFEAD5FFBEDE789B9E23B64BCC5CD +:100A900031E423AB1FE6F779A924F94779DC457FD8 +:100AA000EDFFDA4FFB25BE4E0FCA4FA3D6D4A0B838 +:100AB00032E7525E77DC1CC4E6E9DE3F293D086C74 +:100AC000F55AFBAED73D15485F32C358CDD45B0A0B +:100AD000AC1ECAE5810B13B67A55ACDED0DCF5BA94 +:100AE000845EFDE9EEEF79701FF7F60F5EB900E561 +:100AF00072D1232AF8D8B85DBB4390A67D4CCA8337 +:100B0000FBB485FBD4ACE7B81429C0F0B0E8FE1004 +:100B1000AD970BF77A53D359FB853F7A7524303C58 +:100B200074ADE87E6A10AEBB3F50F8796AA27324B8 +:100B3000AE6B0B35F8D75896FE2201CE87477E92D2 +:100B400047F78E959D072FA77EDB2F717B2DFA220D +:100B50003FE0A679B17ADC1FB74B495567D127F240 +:100B6000FCEBC82E85C3B7DF9DF2237C3BB77AE24E +:100B70000C8EC69DEF105F4DBE7F4F18F1D0B85F51 +:100B8000B59DE736EE54D3DE9194BEE2A57BA9660F +:100B900050A9437C72FDB874DF12F29F2F6DBFF92C +:100BA0001D358CEDEDFCCDF0124D235E9F57A3D388 +:100BB00031FFE0BD6183A1EAAD8E1D61C42BEB77EF +:100BC000B6271FCF7FED7E6FECFF83C2DEFD31CBFA +:100BD000DD83FCD5D8BE868FB7EF9F5F47FDD2E897 +:100BE00090A3B7F097B2DEE72E66C071EEB273C085 +:100BF00009D9978BF61CBB3BC1C63DB2F74F77278F +:100C000018FC8BFFDF7B775F8F76D0637E1DF5400E +:100C1000E30FFE330C9675F3D2005FC7BA76DDFBA7 +:100C2000FD3B997C74BDE8A5F5A3EBD1D787E03BEC +:100C3000295D0FFCA5C460F5973D7A1EF901963D2C +:100C400034B9B4AFF513F935E5B5C29522BA1AFB3C +:100C50001534CE98A12D52077D9ED8A7829FC1F949 +:100C6000F60B5EBA1FD5C8BE2DAF457A2D21BD8CBF +:100C7000F91B189E97EE5EFD8E3A321BBE13835C05 +:100C800078D90098184690DE5FFDCA17C760EAA6BB +:100C9000F39546E826BDEA6CD7F81CA3EB59B9E9F1 +:100CA000780C3EF4E0E15FE3EE357CDC7646C7701D +:100CB0006F3ABE8DBF8CEF4DC76F39E8780C16DFE9 +:100CC000732716EE1B90F53C589E9F2D79E86B7D9F +:100CD000DA5B522FF487E7050A87EBBC80B92680E0 +:100CE000F2BAF787DFBFB388D3793A434CD79E6314 +:100CF0004380F1C91BEEEECB513F763FEAD571BD83 +:100D00005FF8E8F3246F5D0F3DE331C84E87A0C262 +:100D1000EC8D2EE8F9E940FB63293FAB82C6EDA1DB +:100D2000B4379CA1D7D2D4850D4698BEBF42DF53BD +:100D30005C0E96A60E5EA464A1DFC100BFC70DA91C +:100D400062C2CB92EDBFF540D04E57651CD2F395F1 +:100D5000A9F83D173DE5FC759CFFD916BA6EE7F280 +:100D60009B4B4EBBB67A358C6770D2B94BBC9BD2CD +:100D700098529ECF4677B90E9EECB9EA01A77C8BBC +:100D800079F727DFFDCFE7E4F0F5C38061E31B8946 +:100D9000B7231F66D7FBCF0B7DB1149A1A060EED51 +:100DA000BD0E6A6CE339A82203EF118C7364FC76E4 +:100DB000E4076A2AC1BEAF6A7F82F4B7534F2CCDD5 +:100DC0006167BF21C7DB7F7024EAB3238FFF84F8FC +:100DD00071E9EE573CE8AF796AE7839ECEE119FEF0 +:100DE000C775C1FA7EC691FB0E8E24FD8DFD67A1ED +:100DF000CF31D17FE3017BFF8DBBDFB1F5BF28D1C0 +:100E0000EE21FF6A3FE3BCA59997E07CDFEA70031F +:100E1000BE97F456BBDA90CD0E7A29E0B6C553AD35 +:100E20000AD5BD80FE49B5D063A0FE6BB9D17C3E2A +:100E300081EBE5336EFE8EA566BE80E7D7C9028FD3 +:100E400081FBDE96D0C56058F4789B039F7A913E73 +:100E500009F703FA94D818EBFE4BC25F60BA6CF046 +:100E60002F0B35941A41BE8F33F07D0A2D4AFE694F +:100E7000353CB581EED5EB2EDD9F75DDE6FDB98302 +:100E800031DA77B975171816FE1A35F9E233D1053C +:100E9000A78161DB0FAC9BC2CF83E5FCD70D86CD6C +:100EA000C0F4F03AA5FB30BE439498C6E30BA57D91 +:100EB0000762DF1FC67D7F456F7B0F4CD3407D44AB +:100EC000EAC8E0E39B96FBCD99F85D305C14C71C43 +:100ED000A54D8006718A13F26194C550DC77B55335 +:100EE0001A64EA0DD373F3B85EF24237E56F6BF81C +:100EF000039D7394E6C5C6E41563BE50E1F348D381 +:100F00003E4F5EDF77E59597F5A50F608A76C4EAD8 +:100F10004FF2C266DACFA03BF3E30119BCC8383BFD +:100F2000D9EF3AFF447A1F03E73908DF6BC3C78D57 +:100F30004AF8F9019FB749F96299778C8335F53AF8 +:100F4000B1049368C615F750BCA7D7467E9381D0ED +:100F50004E693974505AE8D3158DE07B99FC5D2EAB +:100F6000F8037C9CE780EF04EC78A7FD7D9D6ABECA +:100F70001867744C8A7DCEFA027B1C523C8FEF13AB +:100F800096E5B964DC73DCBA6F4BC262C281BF887C +:100F90003F4B26DB7D372FBE20CFB29F55831D3CB4 +:100FA000AECCB15F3E4FBD81CE455647FA8EE75A73 +:100FB00029E2C27395B715FB666F05829FFBC114CA +:100FC0001F8FEF36C1D0ADFC88B13D75D67849D3BF +:100FD000F68E8E1BF950453C2728F5A35CB1340FE3 +:100FE000F98AD1E156C18721E8149D7493FF639B70 +:100FF00027BE0AE71BA96A52F8F7B8C2FD65A68AA0 +:10100000F32D11FDBBF21697C5FB9827CC647C62CB +:10101000899B592FE8A269A0056A119ECD82FE4ED8 +:10102000FEB4C7BF4ABB2E28725E1187F7E49867EB +:10103000E97D31AD2848F12FC1312DDF708DC4F924 +:1010400037E9A8578332BE25CAE315E5BEDAF9EEC3 +:101050008BD71117EB16FBF75E71E2623DBE153FB1 +:1010600064B19B9DEBF17D7939DE131A973D1E51DA +:10107000DA699F94FFE5FE73B1AFE3290242372995 +:101080009E53137E8B4917E9E46F3FBA5BE1EF1182 +:101090003AF8E9E8DEFC91A82F519EF15DF33CF1AE +:1010A0005DD97DF020DA572D61300B0A49FF192AEE +:1010B000C3FF2A65944F61E9927DEF3CFD08FAF188 +:1010C0000FA880EFB91D0DCA7350B3008996076B46 +:1010D0006D74FEA4F3EA7D8EC9E5EF6A5DCA5F9088 +:1010E000DABDBB5BA17B622A9C7907BE73D578D839 +:1010F0000D2956FE2EF07EDFDDCCED86F93F7BB06C +:101100008E49026C14F0E0FA655D67063404C0B0E5 +:10111000F04944AE0B09B303DF7F9E2BF0531C2B29 +:10112000B4D593F3FBD39C86C3E4FF89CF23FB158F +:10113000DF11B4F60FC23F62B07FC8974E3C1C77F8 +:10114000C53D40EB4A2C3F4D7610DB4FE3FE23A517 +:1011500044116EA73F65E97E85D6B3ABD87A86EF9A +:101160004B5F9572EC471DEF224BFC3BF9D61D14EB +:101170007C1B84600E3C47D3FC7C96E4EEEA9FF136 +:10118000B8B4ABF728F48E93DA797A3E10DE55F2D4 +:101190004BBD0E4DB7B31526C3DF0EFC792376BCCD +:1011A000FB0D3BDEF36AECF80D45ED7874E2397F18 +:1011B0005CA5ADFE2275B187984FE0BB86FD437CF0 +:1011C000333D49F358CAE691367AE373C18175AB72 +:1011D000D05FD22F1E1DF81BE1C0DF313870909711 +:1011E00042CC5742A24FF32ED3D224574E39947893 +:1011F0002AD73B26D1B76888FCD411D1893297B75A +:101200001BE86BE742551B253994F1C9793DEBEAA0 +:10121000ABF0314BAFB9F0D02B7320B7DCB537FB57 +:10122000A2739950DFD70CD1B9D5785EAE53BA19F5 +:10123000EB9FD5E77A4BE3B921AAD37A22CE4D8E24 +:101240000EE7EF5AB5A7DF2F41FBEFD6DAEE0BD052 +:10125000EE6FBC92C75B7E2FC4D7DF1F8BF4FC9070 +:1012600087F4DD4D311798E82F38A0A614F443E930 +:10127000E6CFCE45BBED80DBA0F54FEF7EFA5FA851 +:101280007CB48EE7CC65AEB651382EAB4FFEFEA3D4 +:10129000075E0D5F61B18FBAF67FF70BB83E6D72D6 +:1012A000C1826CFB80F9413E7E57CD1F4A902D973D +:1012B000F8BA695FBEBAD3EE67F3ECE37EB8A5FB7C +:1012C0002F247BF4D03CFE0EE74347F87DD4A9EAF7 +:1012D000AC7F1AC1F2E3FF53E37A15CCE9B34BA814 +:1012E0000AD133E9677866785C8FF19B28177F74A1 +:1012F000A5F0EF1C8CFF227FE769FC8B7812C68A71 +:101300009AF8BBF18F84A71EC674CA0185FC478D6D +:1013100047F8FA36B6C3EE273A7B0AD30BACFFBACE +:1013200003DCBF55D7C9CF07CE7EC15E6F7CA73D1A +:101330003FA11FFE5D1914FBC830949C4C7C6EDAF3 +:101340006DAE0D72BB8AEE9345B5ECFBAF57437C97 +:101350007FC4F041F33FDA0DD1156C1E47E70E9CB8 +:1013600084F7938EBECFCF1B8E7EA83664DB5F6D75 +:101370000D727ED9E4E1E7C79BE6055337B2793CAD +:101380003E6FE169B8AFFAF3B7E2A7E97DD9254C22 +:1013900045B8684D34F3611CCA470BBFE7066D655D +:1013A000D9DE51967221E544CA47D9BC403C9B5FC7 +:1013B000B45ACCAF7E5E0DC5E3763DA6D01953D7A7 +:1013C0000A06571F784CC08A41084FE3FEF7C84F02 +:1013D000E13B90DDDF7D3018E67CBB2271E30486C3 +:1013E000AF6F32E14EA03C78DA2AB2F59F80F5E487 +:1013F000BFDA19E4FCDCE5E3FB70D0DACAF0BD88A3 +:10140000AEFD93A7AD6270DEC9E40FD7EF4DEE28B5 +:10141000C19D5802F4EE1F887B85E517C0D69B2C32 +:10142000FBB59F07273D1F64F37C3EC8E39306C4CA +:10143000A30AC21DFDE87818FB3FFA8197E83750F0 +:10144000F88B64BB7783DC0E5F1D329F217E595081 +:10145000444A311A0F47E78E06386B3FC3779638F8 +:1014600033691715C6990E1C83EF58BAF87918DB43 +:10147000A7E1FEA311E44F828C54297F78D90DEFA8 +:101480008949BDAB1C50D221A63FC7F88269F4CB75 +:10149000142E70E1DB3BCC1EF5F1FE3AEC762B6AA4 +:1014A00060D4BFA80378D03EDF1F497D2CF5784B70 +:1014B00001D77F2DEB34D28F9BB54E3FFAA52B4C35 +:1014C000A35E33E8FD568AB718BC80CB7BDED02DF7 +:1014D000053D76D10480073E52B3FA47CE10FCB4E6 +:1014E0003A14FF0BE27BE4E1EEC7D1BC8AFA61005B +:1014F000D27BAAB07BC6BFCDF591BC5FD028F625C4 +:101500004E7DB4C92FEC1868FB359EDBFFE48F1AC3 +:10151000DD9FEED13FF3A6D27A0AEAF02790BF26EC +:10152000FC5C6C0F84FE61BB3DC2CBD9BF88271128 +:101530000EA7BE19074C2F29FDEB1D279D9911DE23 +:1015400093C710BED187999C59DA3BF5D4C0905807 +:1015500067859E3A06134BCF3332FC54BB3CFA846A +:10156000D7C23F524F65F829457CE81C47015F4FC1 +:101570005E1F8AFAE5172AFA518E4EE27FFFE709CD +:101580009423468782F753D3901FD61F38DF8F7C72 +:10159000BFF7F0641F8AD5D5117EDF4C3B7851022E +:1015A00004FB58CF95DDE0338235880F17E141D534 +:1015B00059DE32FEBB6D8AB86F69E45F94E55D6CFD +:1015C000995E1DE1F7C9F61EAECCE7FBD134D1BD63 +:1015D00087EF85FF42CA85E477277F4B7948B2566B +:1015E0002E8B1DA12AED62FF68F72324851D91949F +:1015F000EFCE24CAC83E5C26ECC36470D8CD13D9A4 +:10160000AF2DE97A1DCF3D96852A29BE7A5931C77B +:101610009F131F326DFC80D98B9638F846AD9BFC2A +:10162000638D1F786CDF257E73E145E2F71CC4AF44 +:10163000F2C9F17B4EC820FE70E2F9D3CEBFFCEABE +:101640007159EFF1FDA3CC7F02C41FE9247F2CBFA9 +:101650004F22F94DEA8FBA6B5A937946465FC8FB21 +:101660002052EF48FD72F6E2B627F2B2E80FA7DE8D +:1016700088BAF52BD632FC459F0CD23B1D4E3DF26D +:101680003EFE52467EB7BB434C2E1F78EA2D17FA1A +:101690004D1E7A98CD9D95470F4EE17EC18E133B2E +:1016A000EF9276ABB4579DF5A4BD2AD71D79DED451 +:1016B000118AEF09317C29FB993C313C2475BE4FDE +:1016C000FE7930DE8E70E5319803180B5893AEE04A +:1016D000FB59BBBCE692CF3C87FCB5A7355AFF123D +:1016E0006CFDAB567AC321C79F1F12EF0930AE4382 +:1016F000BBA6BC0EF8604BF97B01E523218EEB33D2 +:101700005E2BC5793E2DD6995F85F8FA2CD39F07BD +:10171000633F45F8DD1A24BCB59F1C6EE95FEC08F9 +:10172000994F229E7C0D26CD63900E51B4F7076928 +:10173000ED4A94C151B8D8507A9C3D725D67FD0D59 +:101740009A6E4C42391A84770AB03EDA4759E8F368 +:101750004A88FBC197F83A9F4213BE717A5343B847 +:101760008FF3F5CC3B0851E1E7B2C7811C7DF4F95A +:10177000C178FEF9BB6FBF17C273ADFFD2BA430881 +:10178000E71B37FC3A84F7217E7703DF7F5CEEB0FE +:10179000733E10F8BC241C3B8AF3FDD7E68FEA6C3D +:1017A000EFAF2CE7E73357A554DC94F6F0FBA29D8E +:1017B00079E4DB93F925ED036C79C9A74BBC3C6E4A +:1017C000CB39FFB3C2FC1CFDAADD5B3D830C1C3F83 +:1017D000AE84D9F86F083BEE8D7D21F27F4878E624 +:1017E000EC1EE5413CFCD701AF38F7EF7073FC9B72 +:1017F000D3F17C2E2E48E184F3A9C7F2A8BF2B3782 +:10180000A86477CC66632D67FC1D3F7015EDC39D02 +:10181000F3B8F277C6D45246BF2BD72864AF62FD27 +:101820001B183FC497AFA6733CE73C67271CF12306 +:10183000C2AE70C699CC3FC0CFDFE78271F3C48AD5 +:101840002C712707A6D1B9DBFC7EF63D5561B1EFBF +:10185000A983B3316EFE180CFFF7E146FFFB9E37FC +:101860009A8182C8DE6AF6517AA459A7F428EA4F11 +:101870003C3FDF7FF029E233ADA30EE57EEFE15779 +:10188000F32E35327AFC4B5BDF7BE22E961F0DDCAC +:10189000CF23FDEDB304DECF15FA7CBEB017467F33 +:1018A000D0B73E9F85F818D91B5EA9C767E1DF2135 +:1018B000B4E041EA75273EDE3D3C340FF9E3FCB06D +:1018C000F3BCF9D3E12557BB256AF678462947478B +:1018D000439CAFE76EBF70D540367EF2D1D7877498 +:1018E000723DF11CEA09C9A7004D1E9463273F4AC7 +:1018F0003EE9E1BB03B7109E247F30B98A8873CEDE +:1019000008EE0F9DFCD75F7C5397BB7308EA052751 +:101910009F7539EE43CBF4EB61EE7F9F6B9853716B +:10192000BFCA969B55FC3C90EBA337B4B6A7AE4715 +:1019300079DDCEE565C98FF7FC08F5D0C2FB3784A9 +:10194000510FBDA9B595E0788B77AC0CE3B9FA1BC4 +:101950005A228CEDDF4CA959E31FEF0F2BF2EF75E4 +:10196000DAE224A0357101CAF19F77B8753C076BA4 +:10197000DCE9E5E7EEFB38DE589E9FB7EFCB1E278C +:10198000B1F0DE0D25068FA7B5C74B6C7793FF022C +:10199000FD6B384CAEF3E29EF3E7F6BECFD31BF7F8 +:1019A00089389B7DD3B2C64BC8B804271FDFE3E05C +:1019B0005F861FF2FB25185CE46E17E7E4C95D77CC +:1019C0008C7C85C17764FBCFC3CA70AB3F9E9FC739 +:1019D000BFDB7EC53D3E576EFEED12FC9EB1275229 +:1019E00059E32716BBD361DC572DDEEAA67DE0E282 +:1019F0003D2AE03B78F0A297D6F3457B9EFCCD399B +:101A00000CBE450FB88BA6F369509C84A4574F1C9D +:101A10008BA0CFC2079FE4E7CB86886711745AF486 +:101A2000C0410FC6E538F139B9FDA0A7D311074170 +:101A3000F46A7F652ADD27DC75DC83EBEC9B8F295C +:101A4000F4F7399DED176C7D328CFA02F144710088 +:101A5000826EB9E396D2173C3C86EA91DFAE3F3AFC +:101A600036A32C8E257EBFEF6106C78297BC143F3C +:101A7000B5E0BE6B28CEE875AD89F3FD969525B827 +:101A8000FE2E70274A744AF9F705775F4BFC38FF42 +:101A9000996B4BC47DA432EEEF4994E13CAFDCFC82 +:101AA000359AE73C88133F2ED8A2C6D0CF724C831C +:101AB0008607B2C8CD17F2B9DCBCBECD8B8FE8C0AB +:101AC000EBC2CF997856157F3FD2795EC5DF8B394F +:101AD00026F6DF1F89F5187075B3ECC71AB7AFEE9D +:101AE000403ABD35D82CD5299E404B08BCD1BBEB24 +:101AF000EA33E7950AFD46EFDC483B68327EC7FAD9 +:101B00001D6E7AEFC6D2CEF65ECD32313E833BA05B +:101B10009CC5D292EC7ED099F9522F88F81BC967E8 +:101B2000B9F4C0761ECFF2FE735CCF605C0E957781 +:101B3000B8D3A5B6781CAFEDDE7526CEC42DE4DC97 +:101B40005ECEE0A478991EFC3EA6A4F0FD63C92FEA +:101B5000F3D67BEDF1793DFCE37CAFC71E3F33DF6D +:101B60006197C9B4D7FA9FEF38AFDB7C62F1338B52 +:101B7000DD298A7F5AFCA297F6278BF7B8638897EE +:101B80003FED7EE2379732BEFF53BB9463BBDE75F9 +:101B9000CAF182BD63219B1CFF291885AC72CCBEA3 +:101BA0006795E360E65CC38053AF77E7E7D0BB1788 +:101BB00038F0C9EC867C8C237EEB078B4E237F8527 +:101BC00003BF52DF3AF5E86B6183F0DC3BDE8FAF99 +:101BD000FB99784C8E47C99F0B7FB884C6E9E163B7 +:101BE000C9A7928F73C48D39F1E92C2F44DFD9D85E +:101BF000DE7E91443DD4E0DF674A7A80BFF3E60A97 +:101C000044917FFB3BEF7C36BF42BEFB7616DF176D +:101C1000F2F3CE6850C7BF5401EE2243CD76CE1EFC +:101C20009DECCA6AFF27F2F9B9463EFA2318DE1E78 +:101C3000CE37F8BD0735261C79ED748F81CE56114D +:101C4000CE8230C9995BC4A9B09EE93E7A34CFF503 +:101C50009EC1FAD892FFD4F91AA36F74B4EB9AA17B +:101C60002CFF50FE4BE76BE8AF9DE07AB092E57F2A +:101C70009CFF5B9E3FCB35DACD587527BC7CFE14AC +:101C8000567FA998F752E92769196BF39368AE5705 +:101C90006EC7F31CED61372459FE6626F7BEDACC19 +:101CA00039739E17127E96CFF3B094E55755FC7AA0 +:101CB000156E229F0EC4EFCA277CD51B88E723BA76 +:101CC0008FE27796FDE43C8A237D389FC7BD9FF95C +:101CD000E004FAFB8EA7108EDDF9C5B9E16871F357 +:101CE0007E8EEC3D7332E2F9CCD3D0A796A147ADFE +:101CF00066D0773F437B82DBFD11BCDF922CF05036 +:101D00003F0FE74BFA9D582AE35ED43CCE176ABEDC +:101D1000ABE901961E14FCF0B8C00BFEE0BEFBE878 +:101D2000A3A5DBF8BB56DD4390DEAAFAEEEFD1DEC9 +:101D3000ECBE2C8FFE7EC84B018EB797021C6F97AE +:101D4000E4AF759FC1BED7FA865C834CFF92B2FBAD +:101D50005A4CB7EBF15F723C401AFBBDF47295F739 +:101D60001B6C0AE17B718AC9ED708531D32C868F9B +:101D7000A4098667288AB03DFE43556BBBD3347EE9 +:101D8000C8363E94B37593C9F925E339BD186E6919 +:101D90001D7D7E1CCF4BF866A62A939D06C1F37B62 +:101DA000E48F51DED460DC4F5DCACC2AC8F25E7885 +:101DB00057809F6F7661FB9199F881C6FF76D17E3F +:101DC000B611E7C0F20F1E01F1770AF9BB3BD2EF63 +:101DD00031FE975793FF7BCCFE453CCE44F8BBE4E5 +:101DE000797EDD217E3EE7F46F4D80B5A44FC73B81 +:101DF000F4E884FDFF44FAB5BFF3B9BF48BD3A101B +:101E0000069EE4F91CE896F3B9FF01DBE0C6DF00AB +:101E1000800000001F8B080000000000000BB55A76 +:101E20007B7054559AFF6EDF7E25DDE9F48B100838 +:101E3000869B0448421E36498010706CDE4C8C1222 +:101E400060406418695021E6D56CD6416A748B0EE7 +:101E500041459DB2326A29556BCD5E18DC45496615 +:101E60001B4934BA9D4C0710120437082830AE665F +:101E7000DC1D44973C645670D42AF6FBCE39977E1D +:101E80002428F3C790A24E9F7BCF3DF73BBFEFF7CF +:101E9000BDCEB91E3D7883F900D7E9DF9D91B62A02 +:101EA0005902980EF44F0729000D66FCA5005C3915 +:101EB00091990C385EAF07909D004645865267E4C5 +:101EC000B9B66D38CE14E9BF93ACB0790ACED81F3D +:101ED000001BB5B00E0AA3E6B5F37917CA568012F7 +:101EE0009CFF12A8A60C8069FD392FCFC1BEA1C7E7 +:101EF000002ABD979EA0FBE7746A00459BD1FBBBFF +:101F0000E2305EDA91602B84DBF195A93A50CC6C1B +:101F10005EB88EFF1394445072227D4B8E33A62FF1 +:101F200027DAF64032FE0878FB52518E627E0B9221 +:101F30003CE363E679C7B6A487E42EB66FAC20B95C +:101F4000934B3363E68113FACFFAB19F837FD73384 +:101F500069A995C96194BF082ABD12CAEBF9183C5A +:101F600061947FC6193E4E7BCE130EC83EC4B1F4B9 +:101F7000E3D8EB6510D5C779B67EFC95E348943C71 +:101F8000A5F624F7C53CFC311EC65F9747C5D113A3 +:101F9000269CCEC81E540334F4E22037B65F800A74 +:101FA00088DB34284C0686AB0C2AF6DF04DF0B7383 +:101FB000B0BDB66DD8716472044F8737164FD79293 +:101FC000583CC754C6E23976752C6EE37CB138A50F +:101FD000554D8DB97FDBE6A298FEC4AD6531E33384 +:101FE00002F362FA593BCB63C64F6E5E1ED3CFDE5F +:101FF000B526667CAEBA21E67EDEBEEA5BD27F41C4 +:10200000B021665CBCFE6FEFF855CCBC65F25A1986 +:1020100032233C08E01FF1A088544CFA473D84610C +:10202000A4FE67BA03C4F8BF59FF5B49FF9628FDB9 +:10203000CB6B937DD691F6ABB59A5EFF89D63A9D70 +:10204000F48A73A070D748CF786DC860DD2961EB42 +:1020500040EEACC5EB5BCDFCFAA3029F6B09E92A0D +:10206000ADDF113AF657095B540BB3C3C02716B561 +:102070000979F3A8AC3412AF5E942B254079D25085 +:1020800075BA2CE4910EAAC8AF3CA7D3ADAB8C9225 +:10209000EF793B0E1E43AD8EB5FF6C445BC5F7A6D2 +:1020A0005920602E62CFD1DAE89F1770DD36170312 +:1020B00005FF55EC5C3001EF3BFA731407E02DECA3 +:1020C000DF06702191CB7B2191CBB9C6A434F59367 +:1020D000FF90D5C924CF5EBBEF5FECF89E0BD2E337 +:1020E000067C3318DC0103D95D9A1902367C5F93B4 +:1020F00001D65562DF016EA901DB6478C54EF68515 +:102100006228D7911487ABF392FBF1FAFB24C23813 +:10211000B2318F0E6600DCA7F9C3AA5CE60FAFE010 +:102120001AFB48A17A2519B0BDF26016BB7EFE7E6F +:10213000B442B4A7F3468E8786C325E127BFDC6689 +:1021400066EDE56DF618BF59B5FB852405E7399FA7 +:10215000034B8251F8750BFCBAED32D3E7A0FAE7D6 +:10216000148267E8A1EFA690D07EA9EF492B0E79E3 +:102170006AD73F5402EAC1D8B62C803A815F18155D +:10218000365E9BC71F9A0B84033196E6BBF723D8B4 +:102190004CF2DDFB1DB651EFEBB31BD8737DE27D36 +:1021A000ABB0B1236EAB502F0E6A8FCD5944768100 +:1021B000D7C312F697F68081EC61992FC340F29C49 +:1021C00006CFD97694E78F76FEFE9F41A581E4FA8B +:1021D000F0FEBA241A77633E6D1E14D681F1E42313 +:1021E00047C090827E6BF80EC9B34761EF33D3F5D9 +:1021F000CAB5694F5895C8FB3E04DFC059D4F77281 +:10220000F0B079B5F9D1F262FCE21B55359FBA32D4 +:10221000C91FEAC04CFEB0D3C4FCE150F5B5D69757 +:10222000F0FEBAB4FEDB8CF8DC85EAEFA6102EF7E0 +:10223000ED924141FDFF39C9F739F147C3E3FC8312 +:102240007F49A2FB6B4CEAAB2FA11DC07E93E755E3 +:10225000A0E7F6B3E7B4715FD9E75EB653FC2C454F +:10226000A066DDDC3E35FCE7BF9E3B9678A6F1EB31 +:1022700061C1AF86D7B2C7129F1A926EF08BF75F1B +:10228000CD1A4BFC9A21715EC6CFDB85FC52B27130 +:10229000DDC82B0579D5F5CD3C17F98983279CC579 +:1022A00024A71E7C3A47141F0EBEBF268FEEC339EB +:1022B000F72DC94BB6194039EF052EE749611FAB21 +:1022C00043AE62D23BDA9DCD81E3D6FCC76B037F80 +:1022D000247C3AF7BFFA188D29B9353C34FF7420B5 +:1022E00091C7231071CE2370C13897A3475187201F +:1022F000D143F9C2CDFCD601F20BC8AB6B3A747C6A +:1023000059E4AF2A81FC82053C0AB5E865DE9B8D65 +:102310007A6CEAD6C133D8B59153D3FC4F29F66510 +:102320009DF03FE035A7621C11FE29E737EA921DB8 +:10233000CC7EBCD6F533984B6472951CA9AEA0F741 +:10234000421FFA7194B512FF281ECC86CD87135018 +:10235000CE19BB303FC07133CFF1FB9A5F9F15D6CA +:10236000AD3726D3B85F7F25DB08A2D83830FB48CD +:10237000F9E734EF6C887A6E94F830C711971FDC58 +:10238000627C584C0100710FE670FF1E0C27AA8179 +:102390000C366D716501BA26B43DBAFFEF6E1E476B +:1023A0008CD2608E19FDF05DBFD9B373E71CA4C356 +:1023B000248E0BF59BF4844531E3F18DBCF1C854B8 +:1023C000E60FE17B948AF0B20B99E3E42941BBE389 +:1023D000C1D8139377868F7E6BEBC775B43A95FFA0 +:1023E000247D0D635E437E2141DF6F748CB2BE3766 +:1023F000C9BF22FF9F77E898BCE60EC9ABE2FBCDD0 +:102400008A17245C4382DD3E4D9622E3173A78BE5C +:102410005B77F442BA11F535A03B61CBC7F96BDBB2 +:10242000DFB0E1F2618BCD57457CAE39FFC10C0ABC +:102430005D00BBD32B9308A7CC64B2A7023D04F484 +:102440004523E5F0EFC2C520E5EB77B9589BDB21CA +:10245000B1F5F9C37C9D831D4DCE68BF71E3B93FD3 +:10246000748E27BDED1F03ABC91F17848A37118FE8 +:10247000491603EAE2F56FF2D87CDB1C194C2FF801 +:102480007E3D5D075075CB71D07E033E87F30E7E97 +:1024900023B371DABC051D73653BF2283FDC7C88F1 +:1024A000F2C2849049213D27EC058E4B2881F945E5 +:1024B0007FD762A0FC75C8011E09EFB7260E7F42C8 +:1024C000BC18EE34297B24C2AF199C387FAB91C76E +:1024D000CF5C348437AC91EBDAFB12422F03F92B3B +:1024E000E48757A5FBFA66B8C31A8D7B12C35D75E6 +:1024F000705EB526867556F2FBC8C93D4CAE889C09 +:10250000C0DEABC999CBEA8056E3F0C5C7DC4C2EE0 +:102510003BF12117B89C10CA565EA5E7ED5EB68E5A +:1025200004BBE2094823E5F217625E8C76F7DC769D +:10253000B861E764F7FEC448DF8C36D19AC9F90D5B +:1025400081B33B17CC89EA93C32A8D3CDFEE38B7C1 +:1025500073C704561F0564E48305DB2427AD93C7C6 +:102560003F340DEF98228E830771B298F9FD1BE37B +:1025700091EF56EA5BF9384FB2DD522E31BB01B212 +:102580009B7AE1671E91C217EF44D57E1D3E54A889 +:10259000A02CB5C7DE61BCADD1855E2A20FF98E8CE +:1025A000FB03F9F7B73ED6810DD7FFE56B096A0546 +:1025B000E291F3F6EE14AF75E47C4F9DDBFE7C1ADE +:1025C000E9FB6D4941A4312F1C4E27F9EA439F1BBB +:1025D000BDD82EEEF89391E2D32F9CBE5EB283D28B +:1025E0008EC6F984DF2C686EB25B995FF4114F835D +:1025F000A9DC7F5C3933654F6314DE43C2BE60D80B +:102600003791EC2624ECB38BF21F6CDB451ED6DE33 +:102610007D5F965210792E0087D200E7DC0E47D2FC +:1026200008E71BF3A9FA25C4A7BC0FCDEBBC517C6E +:10263000FB42D8FB17E27D01A7EF53C2A1A6FB33F3 +:10264000A30DD7E5FF9F603AC5A720E669F61FF006 +:102650008BFE38BBF1EB878D34DE7F09981F41BDBF +:10266000EE48463DEDFFB063EA7A2B931F9271DD91 +:10267000EDE74DCC6FB66770FB6B3C7BB590FCD63D +:10268000D5CE9A8984D7298741E3F9BC44B2A70300 +:10269000C0FC98668FF9648F287A3EF1BC84FAB941 +:1026A0006CBE56635F39B3BF761D90FD21CF19EF25 +:1026B00091E776CA3FF2EDC87BF67C36B3E7D63EAB +:1026C0000C78D80FA01F9FCCFAF35650BFB56F817E +:1026D0009DD9B30EA12D22BB0C1F62F304B1A6221B +:1026E000D54950199DA72E74D898BC9A7F5C21ECCF +:1026F0003498A3247B703D16598EB183A878C9FB0A +:10270000229EAE759A9E7E71025993880B222FEB02 +:10271000127930F88A99BFFF4711CB1ADE2D5BDAA8 +:1027200082EB6D382973FF2F787248E4C947B6A54C +:10273000B23EC50B05F5341D5B2FFAD319DECDF380 +:1027400029FC942E693E4C6D596570BE81E2E2EA27 +:10275000BEC3066ECE79C4BFB6433FCDD313DFCF21 +:102760009B2001456CFB76F893D711872D5D88FF80 +:1027700028710997C3F887119DF1F166BC1992FA87 +:10278000EF99EDC1FACF39EEA7FA04B41F2206E2A1 +:1027900071BB73ECD30114A8C3E92D72227E9FB8DC +:1027A0007CAC1D3AF56D0AF9F4F6339FD9C8DFB752 +:1027B00019BD79C4B3B64CAC1746E1E744A781F91B +:1027C000FB12536C9EAEB52B9DBCAE9A12806789EE +:1027D0003FF56DB25D457D0FB4C95E23E65117BD6F +:1027E000BE143D427A0902AB66537C17F5EF431CD9 +:1027F000767888F2178C331B5F34C4D4A5B5625F3A +:10280000231BFA9F4C439CFC7B2556D756C5E523DA +:10281000B594BF14527DB1DB48EBA9DE1B370FE541 +:10282000318534EE87EBDC954E91C7644116E53176 +:10283000C823564F0F9F953D7B2806EAA1C784FC0D +:10284000DDAFE338A1DF64F6A8E533896EEF22B28D +:10285000FB450E9EB7B48ABA75B8555299FDEC4344 +:102860003F8FFDB24BCA6EE0389C499D41EBE1BC05 +:102870002CD3F3F165A10C667FA55EACE771DD1B7F +:10288000B19E5769DD5A9EA71AD8FA31FCB23C6F47 +:1028900016A84D361CB7699FC4F67D6AF61962F218 +:1028A0003CBFC0A776D7A9A3544ED605E3EE0B7C58 +:1028B000FC71F8BC413F668DC4E9574EB11F900EC4 +:1028C000E9D1F91EF43847AD0B347CB43CFB7F0DE5 +:1028D0003CBFF840CCAF8DDBE5E47EB4DE0B6CFF93 +:1028E000A856955595E783D6F5C89707045F1E103F +:1028F0007CF1031F57B74F52C314AF7ECDF56EC6A0 +:102900003FC2E5A1E0FA4569CA485E550B3CAA5AA8 +:102910000C2CFF05D86C24FBAC7A256E9CC0A53A24 +:102920000E977A9F14271FCFC7FF56F96A0C7CBFFA +:10293000A606F91550FE7EF2C6EBEF0D8DE753614A +:102940006A8CFE96B86E497FF179F281A3532DF41B +:10295000FC959E4CB60FA1F1267E9E4522CF5EBC13 +:102960008BE7A3031DF32D05544F9DD07B249CA71B +:10297000F8E4FFD90A108FA24E192A708AA150F1EB +:10298000B3015CE7C19E492B148C0F4527F52CBE83 +:10299000149F2C52A9AE293A5964C94A62C6E3A2CF +:1029A0007A01E761F179E8C4A4D3F9E4677B16946E +:1029B00010EC8D278A2C94471C04BEAF219D2C71EE +:1029C000F547C59BF79C325BD793A9FFFD1CE5F942 +:1029D0008B0F183C948F2C360CBF3FDB4DEFD77B11 +:1029E0001AB15F7B72C3F604D2FB6B9287D2F1A35C +:1029F0007D0DEE9F937E4306BB89C9FBCB43743F9D +:102A0000D0227926E3787FE7C2BC56EC17ED2EF68C +:102A100010CCDAFB8A1CCA0B15942F8EB3B03A7E09 +:102A2000F16D0616772F8FB7FC8EF2A56AEFEE4593 +:102A3000E48F2FBF73D048FE60A85582545CC8D184 +:102A4000D4C3BF0FE03A2FBF79CA4849F9FCB65347 +:102A5000C6FE1FC827065419C2AC7E6F36521D54DD +:102A6000B75BEBF71B494F9522BFAADFFB27D6AF19 +:102A7000A63A01DF57FD8AAC2AF8F370E75B46C23D +:102A8000BBBE4582B11951F7F74AECBEC6FB0DC07B +:102A900079B041F8A71AB10F5943FB90781D7672AF +:102AA0007FA3F1FEC17DCB8E52F87EA839D60F3DB3 +:102AB0002C78BE89EA52567FFB8CA4D74DBBE2C668 +:102AC000099E3FFC233C4F76093F950BB9C4F3ABFD +:102AD00073793CB97A2AD1928FEBBADA2B7B007EDC +:102AE00090EF2CFE9E10F9C295B08EC5336DDC6060 +:102AF000C75F58BCF19FB862A4FC7651E82BA68F43 +:102B00008A50F702C2FB6EF0D5127E77872C76B220 +:102B1000FF8A7EEE0FCA432695F6C1EF86E00ED2FD +:102B2000F350D7BFED70126FFE95F30684BFDB2420 +:102B300070DD2470DD840EDF852EB63ABFFB252CB8 +:102B400007A01CB81F2A0F0A3FF44A2CCE1879EEB2 +:102B5000277DD5874CF00CDEBF4BF8A3BB5AB83F9E +:102B60008A8F93F5621F60685CDE52B6DF8AF52EAD +:102B7000E571B52DB1F8D78B7D81FAB8389CE9E2C3 +:102B800079C28FD5FFF17A5A10A7A78A61CE9F72BA +:102B90008A7BB8FE9EF0F67CDAB7D3F08AD7538FE3 +:102BA00092953C5A3DABB5EF8BBC5FEB2F057EFE9B +:102BB00014B4375BA3EBF8D75D3CFE54CF9203A46B +:102BC000E71BF5CEA4C3858A2E52EF609DB3D635A0 +:102BD0009DD73DD370EA63136470BB23F5CE53A930 +:102BE0002F541451BED2C2FDC86029CE974CF93C77 +:102BF00030FFE56F31A954A7F8913FACCE21DE60DC +:102C00005B199216126FB07EA872218ECB68EB18FA +:102C10007158D6C1F39E650BBE627CEB9DC4D77B19 +:102C200045AF8C1DAD9ED0EA88FA6F789EAA5DAF45 +:102C300047BBA7F1F52189D5C56D87FE9A9E81FE18 +:102C400073A8F35AFA7A6C5F76F13C4ECB53873116 +:102C50004FCD14790AE5CF1BB9CA6013A6C35B91A7 +:102C6000871B459C036907B3937A4A76896FED12F7 +:102C7000DFC7791B2FCC44FFFB4122CB63063FE427 +:102C8000E743F4FCE398470D6E081E71E2F8ABAD24 +:102C9000128B7F1B31C7FD49D1487BAF13BC6C84BD +:102CA000EDA22EDBC1DAF29C039F3D46FEA8C5AC27 +:102CB000907F1DEC6832B2FD6535EAF9CC91F95090 +:102CC0009DE06FDD8FEC6BBD1EC74B5C07CB6F8744 +:102CD0007A65BB4962F8FD767C344E22FF693B94ED +:102CE000C0F43C74CAAA529EFFA5E0DF65B1EFDED6 +:102CF000582A335C74B3789BD7F55626E995F4E0EF +:102D0000A37D94AEB7A67AD93E9FCAF858B34FA612 +:102D1000C3BE88FC410BDB0BD5FA1ABE7E812FCADD +:102D200035C5E88EC8D5AEEFB77946B11B493AC470 +:102D3000F4A69362EB5CFFDB72A51A654FB89E7533 +:102D4000E4DF42821FA01F4E21BF1C76294CBEC665 +:102D500010D7B3AE93B7F8FE557CDFC6C0DE3FE2B6 +:102D6000FEBC402DDDBF9A6101C6936F0215D4DF12 +:102D70009229333FB5E583EA6C887A3F48BC1EF759 +:102D80001B8653583D7C4AC7E4F39FBA9232C94A26 +:102D90007E70F7027B3EF937EE1F8E665AAA88DFF7 +:102DA000017AEFD8C83CE52E7E9E00B4DE54CA6698 +:102DB0005EE4F38AF56E87E50C87ED8267DD221FFE +:102DC000C5BAE93CD9637CDD74B37C37AA7E6378ED +:102DD0005D9DAB9CFE39F2A0A8571FA07AFDE0399B +:102DE000EE271A3B377D4A75B0FF8209C84F6CE960 +:102DF000DA944D71187CBEDB29BFBBDAF5F0ED6CBF +:102E0000FF52DACEE40A907CA994379D4DA17CA8AC +:102E1000AEF36C0A8BEBEDD35FA03C09F3A2BBE8E9 +:102E20003AE62B8C7F45274B18FF0E9E2871659143 +:102E3000E0E0B1D0BC75BDFA4AC2A7AEB7E4BD0AA6 +:102E4000CA5F4ECE637992961715533D4E7952EF75 +:102E5000A4983C69D8C5F3A4A1EE04B6FF2141268D +:102E6000E70F4C8AE14F6DDBBB2C9FA8ED90BDD1E5 +:102E70003CD29ED3BBF57C7FD42DF81394BC8C1F21 +:102E800007785BDB7190ADAFC61064FA6E6C31F001 +:102E9000FBADBC0568E6FB2CE00C101EEFD125D481 +:102EA00043B9519D40FBEBC733787D11AF8F67DD90 +:102EB000FC1CEBF879DF44E2CBF1B9BE6CFB287166 +:102EC0002300F378DD2D09BCDB0C2CAF8C1FF7B48D +:102ED0009BEF4FD85C1073DEA8B5BF7473FE941BD4 +:102EE000F93E55FCFDB96E614F289A0E7971BAC250 +:102EF000607F46D413E3D0DFDE23FCED8ABB0D2CCC +:102F0000EF382DCE99EED1FC6E298FDFDA7EFFB23D +:102F100057E0092CFFE16BC867E760CBBCB17E6F5F +:102F2000A5C8AF562C89BB2EF2A9953F924FCD7202 +:102F30008BBA610A4CE17583D542FBA25FF718ECAE +:102F400032935B9D545930729D9ABF392ACE877A4D +:102F5000D00F52DB98FB11DBA73ADE7DFEF70EE6C1 +:102F600047132093EF3BB2FDFABA9BECD737DEB0A4 +:102F7000D39FC5F04ED3D300E5F9F923F5B452E061 +:102F80005D67BE6C64E796B079A74E8E9C539A0C31 +:102F90003E6F1AAEC3D031374CE7978DB926962FC6 +:102FA0000D2C9454F2F72867BA29CADF0F8CE3F985 +:102FB000D7965512DB17EECEFD88C5F1BA709F91FA +:102FC0007835A56DFD13CC7E037086EA254D9F4BA9 +:102FD000CD3C7EDED0A3B65EBAA9D0FA9C01EE97B6 +:102FE000DDACA5F1142FEF11F1716969ACFEB2A14E +:102FF0006F11ED8FDCEB9558BE7433BD2F5F3DED47 +:103000005DA2DBADEABFD9EDDBEAA6FDA2BE2BAB2C +:10301000687FF778EEE7E9145FEB6FC2E726C177C8 +:10302000BF859F8BF92DFC3CCC93AD34F5233E2618 +:10303000876FBB9BFC87EE7BDB54A079FA7FDB209C +:10304000917E80E9E56676F4B498F769B79DFB6FE9 +:10305000373F1FB2529FECD9A04E203F01F9B776FF +:10306000CED7F8F6B142D2D360776FA1314A9F979D +:103070001BD01F507CE93C9CA258A3F9A6137CD31B +:10308000B35692968BB819CBBFCBC43FD2FF81C346 +:10309000F7505D38D0B6C22D295171B5FDB46D72AF +:1030A000D4BC0321998DC77A6CCACAA468399F60C1 +:1030B000720E04F97C00FD53561444DF6F123CEE8F +:1030C000673C7E2A67333B77D778AC07CEE3FA8E2E +:1030D00065C0E2945877D0883FA8CEE832A9744EF4 +:1030E00041FBED8E283B392EEC63261607C4CF59E1 +:1030F000109069DE9938E35AEAEB21AC77D2796017 +:1031000058E6E7DD1380783D43F07AA63EDC2D15C6 +:10311000B271EC5CAA0CFAD8B89FC0306BBD60D716 +:10312000533B0F3CAC2D3587EF2277921F0CB2EF4B +:1031300092C2297AC745333B2A85D1F41759BF1E5D +:103140002E6A3CC5C198F4B07DFCF8715F0B7FEF2F +:10315000A11C8EF43C006C1FEE0EE897E925B3F538 +:10316000B084BE27BB430FE64494F7C0111DB3E7FC +:10317000AE7E45257FE67189E7BEC0E7B03FD3CB81 +:10318000ED9642107DB7A2AD371E87329C8FF605B3 +:1031900067EAB1F2653886D9FBEE24C171DD73416F +:1031A000D153FF923B437CEFC6EBB4F9A24ED399C7 +:1031B000030C8F418A8F63F8798E0DE7296B96E0B7 +:1031C0001C9DCF64F1F56AF39761284DA67C5AAC3B +:1031D00097B6C2CF39F9398F8D9DCF2DB0135E527E +:1031E000384577DD72EBB80EA50093DBF6C0F0E052 +:1031F000632591F32E4FE8D839FA2E47F27AD97722 +:103200003D1EB3354CF939B2E37274DEAD1BB30128 +:10321000C6E0FA24C5CEF0021F28947F8C8D7CEF87 +:1032200002D75D91EF6908C64B2991F37DEDFB9ABA +:103230007DEA7245877A59ED367B482F45E6F46280 +:10324000AA07F7DA7D30867D67D332994DA657A756 +:10325000572645F86E016F29E1AD9DEB4B427F3754 +:103260003BB7275B259E5BD0EDD37741CFA2BD98BE +:103270009DA37D7FC4CFF3D10A15FAEE081E9FAF40 +:10328000D077014F3ACC9E67C8CFD1FA2C91F53553 +:1032900099F9F7044D66FE5D00EC98CEF6CF1E114D +:1032A000E7114D565D0ED55B4D90E8A1925E93F708 +:1032B0009124CEC747FECBC2CE47E3E5FE3ED19771 +:1032C0004FF86AF23F2A7BCE61EE1383E71C0D4F65 +:1032D0005D04CFD56A6653BFC2F02BA1E7A799D48E +:1032E000DB685F648D897FBFA4E1860A65A4B60BA5 +:1032F0007D68F8D949DFB40E2FEA5BE34B6604BF63 +:103300006713396E06FA72228B3DABB0F3FC385C62 +:1033100034DEFD3FD45368B1102A000000000000E5 +:1033200000000000000000001F8B080000000000EB +:10333000000B7BCFCFC0F0A31E81FDD1F8E8389100 +:103340000F534C94118257B3E0D78B0D5B3122D8C9 +:103350009EDC0C0CB29C0C0C7240DC01C49D40FC49 +:103360001288B5B81818B4813801C84E04624B20D1 +:1033700076E086E8A96567606805E25E209ECA4E31 +:10338000BAFDBF2518181A6411FC0B4036AF02E9CC +:10339000E68CE2A1897F1BA2F245B451F9F6BAC0CE +:1033A000F46184E08B6A9366FE36A0DEED46B8E5F4 +:1033B00079CC51F9CC96A8FC6E3354BEAA3B840656 +:1033C000009B2185B9B80300000000000000000048 +:1033D0001F8B080000000000000BC57D0B7C54D53E +:1033E00099F8B977EEDC794F260FC20021B9794000 +:1033F00002267188E1A5A013040B886CC017B4AE37 +:103400000EE111DE44B49AAEB8B99010420861B42E +:10341000A8C18D3841405468830D4A57AB03524BC5 +:103420006DB71B1505772D0D688358A0298A4CFFB1 +:103430006BEBFF7CDF393773EF6426E0BAFFFDA743 +:10344000BF7A38F79C7BEE39DFF79DEF7DCEC8243D +:1034500087A4DD44C837F0474BBF891032205A9209 +:103460007255206308F9A195E09FD62FB6ACAB2129 +:10347000246C2124B290904E27ED28555949212DD6 +:10348000EF982E92744292E07D85907AA1EA686E60 +:103490002921EA5091ECA28F3664CC4E0A38138F62 +:1034A000BB978FFB931A2B96ED351E2C5FAEF16206 +:1034B000D951A390703E21AFD4146079B0C687CFA4 +:1034C000FFB5661C96AFD7F8B17CA3662A96E19A41 +:1034D000722C0FD7CCC1F2484D00DF7BBB66319612 +:1034E000476BAAF0F93B35D558FEB646C5E7BFABEA +:1034F00069C0B2B32688E57B352D581EAB0961BF84 +:103500000F6BF66079A2A61D9FFF47CD412C3FAE01 +:1035100009637937494678DE79E725EB3CBADEFC6A +:10352000671E7C6F5A1A215B468B3E0057FE339F05 +:103530007A0385D1756FF99B694E7B1CB8DC450415 +:103540001C678B8B60FB96431F11A58890E6D15DAD +:103550005E95D6A7F1EF8CD875CC3AAF30DA2F76DE +:103560009C3F12131BC74CDB69BFE1DB587FAD7D6D +:103570001A7C6774B47D77CB7BD6F94E7D3B7BFF9D +:10358000F9D6F7AC80BFCD11898411EF2A21B4B4EC +:103590002B3D2D03289E6D272CC4924DF1AFB49383 +:1035A0002E3A4EF3F827C36229AC9B7653609DEF09 +:1035B0001381C2417511A40705C6181BFDCE582200 +:1035C000E23CF29F39C6BE73C7252CDFF8AB4C082E +:1035D0007DAFF94E21E4A0E3374FBCE8F503BDA968 +:1035E0002F9880DE905C15F84F97B79C8EBD65E2F2 +:1035F000875E95C269F3DFDE9F331FE86F14F1C168 +:10360000F7361FFA3951A0BDA807E157CBD7BD79CE +:10361000EEBC2C4F6162BAA49444C47174B94EE2FA +:103620000FC581EF3F0210287C4C9E10AEC94EFBA7 +:10363000C5C3C33F1219FB6D76957F007051EF34FF +:10364000FB76D179DFEC0B936E6774DE50FF84D686 +:103650009D5F8689C905F33EEB35D1F53BC6C9D7D9 +:10366000D9E86C9C3D3D27E07DE784457E587BF39F +:10367000A82EEF22DADF5AD089EB253EE21B46C79F +:10368000B517A8647E21C0C184788D9DCF7C80F75A +:1036900000C0D3575EC08946871FDCF1BEB542D754 +:1036A000FF798D3E04465FA4296C9DE58AB63FA351 +:1036B000B5DB18FD10ABB17D5B0C1D938C04ED6682 +:1036C0000A68C49718DA2520DCADB38BFACEBB2983 +:1036D000FC6BDC074E5FD81A88B32EBA4FACC077AC +:1036E000924A451FC0AB7922DD2F85D1755E69DF17 +:1036F0003570B86C2E9DED82F1AFC4B78ADA4512F1 +:103700002EE03C93FEFFDA83763AF3687D5438C5A9 +:1037100050BFEEE86043FFD19D3986F6B127461AC7 +:10372000DAC7779518EA377C76BDA1FFC49E498633 +:10373000FA4D91E986FE65E47643FD66EB0F0CFDDC +:10374000A778E61BDABFE75D66689FA63C60A8DF46 +:103750005AF088A1FF6DBE5A43FB3F8CDB64689F23 +:10376000E5FFB1A17EFBD47F31F4BFB3FC3943FB4D +:10377000DD735E32B4CF0DFCCC50AFB4074E027E89 +:103780007EB0F835C37BFF58F596A1FE012153E3C7 +:10379000E197088CCF500AF2745FC3FB5316E70120 +:1037A0009A033A1EC0E8B4A02D019FE4ED2FEC7CF3 +:1037B000CFBAD0C027CD8C8E07B1F63DA1F7E2BFBE +:1037C0003F94EF13D2699DEDD2B7B3795DF357CA39 +:1037D0005FA15D52BF157F75797CD85FE3AB94BE66 +:1037E00009B99EC2571DA2AAF83D3A1EE59726B612 +:1037F00064524D189F22E4017CAEC97D9241C226DD +:103800003A6EAD2BA3AD116042C796D2A05EB8034D +:10381000EAA2E2275D71E06AF2C8063CC5C29738A9 +:10382000532831F7C76755849F3A851448F07DC106 +:10383000EE5B4BD72B91C060813EBF2C06BC30F9AC +:10384000874DEAAF02D9D1FE6B27D27F42FF5342A8 +:10385000681DF657108EB545C40F72431D24877638 +:1038600065233C2DC04FB4F7E803A58BCD57FD264B +:10387000D75067F3BD62FDEB7C635D1BF79F8CF057 +:10388000A47086FA7DBCD267DD3E394AB726E8C708 +:10389000EA8A28906F900F1ADBB5EF5CB6B98B49B6 +:1038A00012C5A395950FDBDD3BA0BC6CCB0C11378B +:1038B00021C562609240E1A04E62F0514F3A42B59C +:1038C000385ED5D8F222806F7C7D8190756C7F7CCC +:1038D0003C4DD4AF2311DE3682DE961FADDB32289D +:1038E0005DC5E1CB77094CFE511A95605C0B61B464 +:1038F000E53005EE8279CAA4DC2F225E7D04E677EE +:1039000068D893732A28FE9A26C83EEC1BA40A277F +:10391000D54FA55EB84EC5BA95D7E7090A8EBF3117 +:10392000F9B03587AE77B34FE47A4110C76BC8FE64 +:10393000CA0B7CDC26058907CABCF8727AA52072FE +:103940003C3E4AAE461F8EC5CF48FA3AE32F04E10B +:10395000A7CD6FCBD0B03507E8713CD3879BC7F5B7 +:103960002F57D673B8D6727D78B3323B8938A3EB24 +:103970009612CC6B03D7A309E99903786FC84E1749 +:1039800061DF6E1018DF3994FDB615F84793E7B084 +:1039900015C60B08D96CBD31F06D487E0FF5FA5A8B +:1039A000977D4E280E3E03821BD7D900388375259C +:1039B000132EB7552FE0CDAA784A1A95BE7434D984 +:1039C000F525CECB594A140BEDEF4C63EFDB3E16D9 +:1039D000420ABEEF770EA2F37070FAB02B46F9BA26 +:1039E00076E22D2AE8910FE71032109FDE6FC09328 +:1039F000A3343003E8DFF457138E4B06B17949A4A2 +:103A0000EA0FF361FC42C6A73CF47FDFD031AC790A +:103A1000317CEBD834DCBFB2877D9F982674DE44BE +:103A2000E72BE58B034D74AD2673A71FF4B18D5DB5 +:103A30006D3E55077F594F07C0873E9E769614C34B +:103A40007775E3C3FBC3666FC9ED879E4C5D6E124D +:103A5000BE0EBE7B4FBFF4E1FAB8ED9D233AB8BC71 +:103A600021B8D2BA016863C958E4135778FF724D80 +:103A7000E89D23C370BDE2D5D0797DCC3EDF90CDEB +:103A8000F5398AEF593A3DEDB2C0F439A296211CBE +:103A9000258EC70D13490FC895CDD9B2B20EF0517E +:103AA0002A8781849052E9F7CDF00F809B52DFC9BD +:103AB0009EFFD0C047D70F99E90B2B89E727A5C5F3 +:103AC000E0F10AEBAF06F8E9FA7703FCAE89C2CF62 +:103AD0004CCA93C240DBC1A948BF6E6D1E13EF52A2 +:103AE000F4F3E885E30D6C7F9AD354124F2FADE5C4 +:103AF000F0BB53F45F047E67927D2702409F39320A +:103B0000DA27B1FD478A8C0F45E16C95004F76C2EC +:103B1000FF668410EEF4AFDC9ACEE147FFCC196F5C +:103B2000FF5500BAA366B3A3189FD74925747F79C0 +:103B300089EAA0F2C12E1109EA59C06C4763FB64FF +:103B40003905F6F12D3ED477CDFC7B9E36AF5E4F26 +:103B5000CF12195EA3ED21EF9D8676338EB7C1C5D6 +:103B6000F51BCF7306BAE87D3F39BEDC192832FD5C +:103B7000274BF470FA790EED39F3D0BB1A0E517859 +:103B8000D7E5FB7D15B0400F413868F243931754D9 +:103B90008E64890300FE010278973CE558C6CAE3AB +:103BA000847C3C460E9B0B6403DF217AFD2607FED6 +:103BB0009BE1C1FD4662E53F2FCBA75FD5BEAA8D35 +:103BC000D95726125F2EDD2E32FD91A869B87E6D81 +:103BD0005F11AE5F68F8A7F2C140AF32CC87321CEC +:103BE0001B09E1E00E6A6641DD45AAB07E695C49C9 +:103BF00058A0E358A4AE06E0CB96712251B3E3D8A7 +:103C0000555C0E255AC79689F1E5C4CDA29BD9C74C +:103C1000CE2ADC1784DC837AA1A006C837A81F0649 +:103C2000B9BCF479018F1B6BAAC927743F590FCF18 +:103C3000457BDD9CA7FAC1DE075901FA23C9286537 +:103C4000A5E453F4F4D98B47B216C7333919FEE50E +:103C500034AA17E7207D2C00FA205623FDF4D24920 +:103C6000461AC80A9887521E775C8E57DE2F211D90 +:103C7000F5D281B62E4586F162E9C35E4A2D0E115A +:103C8000AB9D309F811C7B0303F5F78BC5809FE0C4 +:103C9000D4E1140F03BBE6A13C737179525F38FB8A +:103CA00028A874493ECFAC5B14B0F3890070DD08DE +:103CB000835D0FE3CD5D5B46EBEB61B0C1B4BA6EE3 +:103CC0006699EA646462D44B4545D2F430B15FBD75 +:103CD00046F8C6D2F7FD44EBB7C4C83B42565F9DD9 +:103CE0001E750FFB9E4AFF07FB2B39469E26F98D5A +:103CF000FCDD15F39D17019608DFFBFF57BEE7219A +:103D00008F5B154A0A963CD113A2B499443CC96012 +:103D100027D92753FB8DD63D193D2A4CE94A78A96E +:103D2000E7762AA1FB534FCF6F727EE9ADA8CBAEE9 +:103D3000A7E35E2A75FA805E0752F6989AD2773D1D +:103D40009BB8DED75B2FDC8174BD9ED211E8C36ABD +:103D5000A188FEA68D792F7BF472F194C657FAD014 +:103D60000751244D2EE7C03E14FDB6E2EF4E1FE68C +:103D700018385F2D7D38EE31E2E3DBE2EBC2B7A409 +:103D80008FEFFABDFA44FE07CE9F285E51FF6E50BA +:103D9000FAB703FAE2F571C4AB9DDA2FF1F8ED172B +:103DA000BDF8548DF288DBFF51B961B4FBA5AC5B63 +:103DB0004EB4F5030F29564FE6E3DAAA4DCAA7A978 +:103DC0003080C760EF6C541E5741FFBE047A34E860 +:103DD0007BC132F4FF923CE68F850144D0FB157F16 +:103DE00008FD0C209F74724DCE30EAFDA634BB5105 +:103DF0001ECF5105FDFC6DD532CEC30ADF4B437F8C +:103E00006D08BE6BF290B0CD1DA557F814B3F71F27 +:103E1000B92A3A3069EF091ABD1ADFDB905142E244 +:103E2000E1AFCFF7EE30CE37215F8A7DCF2929DD94 +:103E30003ABD23F17B12E9D6E92F376A711D8EA7AF +:103E40007A33392850FDAFD67B170928489F28C7F9 +:103E50001AA0A4F2B4DE5BE241F9BC4788B1CF15E9 +:103E6000464F4A0AF617AD4CBFD2EA89E7C3BE1BDC +:103E70008D1329A81F27EA5F5B33EE0989321B7374 +:103E8000F55B5B256AFFD4ADF5CF29A7FD1B6B8ED3 +:103E90006E958645FB2D3169F639159F6340AFE17C +:103EA000F44B683F849B48BE01FB8972684527E755 +:103EB0006DA473AB84769FC2F14884DEFD4087DC3D +:103EC000CAD7692127B01F0C84761CE9C271E1456D +:103ED000A8AF37FBFDE5144E8D52C8BA1AF8B98D5C +:103EE000D7155E4FE6750FAF67F33AD98175B34CBE +:103EF000EBB07FCD210FD6EDBC9ECDEB29BC9ECC87 +:103F0000EB39BC2EECC0FA7A998DB7496A67E3DBCE +:103F1000795DE1F5145EF7F07A0EAF9397D9F72D3E +:103F2000ACEE30B7B3F11DBC9ECDEBA9BC9ECCEB83 +:103F3000B9BC2EBC8CF584FCB280C13FCA1F18BC32 +:103F4000357A240057831FAB2BA69DD18B49205C6B +:103F50000FAB42FDFFD0D0BBBCE06F5C7FAAD20BA1 +:103F6000F4537F9B464F01E49F24E356E463662DA0 +:103F7000EE98B67A0EECFFFA0C19ED49C2FD305AF4 +:103F8000FB86E4C0D46CF0577C6022F1EC2EAD6C63 +:103F9000E57CF769D07BA97EDEC2E3914FF278E43D +:103FA000568847D23208F1485A36F37864138F475F +:103FB00036F27864038F47FE04E291F910E79C83A0 +:103FC000E58B108FA4CFF7403C9296BB211E499FF2 +:103FD000EF8478242D77403C923E0F413C9296DB53 +:103FE000793CB23EADE428E81D97AA45D40712CD2E +:103FF0007F6895917F0E596C8C4B0C0A18E3120365 +:10400000E718E31203CA8D718964BF312E9134CE53 +:10401000189770F98C71094781312E61538C718921 +:104020006B0FCE36D48BDABF6FE87FCD9E0A43FB91 +:1040300088D052437B7ECB6A437D58F09F0CFD7342 +:104040001BD619DA9F32E5207D65AB8D867E59D56A +:104050008F1BEA95767FB709FD946957E5AF265F18 +:10406000AAE97A7E192B1F4C99C4EF4739C7E4118E +:10407000FA6081FE8632BF94F5E3EF1D057BDD9289 +:10408000C7E4944589B13B63C6939DBB4FA8F43BFD +:1040900065EEA3DE2EDD7E245EDD7B60EF488C4F77 +:1040A000363ECAECF1265EF65D473DF66BFA5B7C68 +:1040B000BBDC269962F40866D7343D2A60FFEF3AEC +:1040C000BED61E3B6EF47B141563F4F66D48F3AF59 +:1040D000923A9DBE60EE4A9E4F50CE33FBD7C4F756 +:1040E0007B5981EF541D85F77A0FF159687DBD73B7 +:1040F000929FE925A2824276CD6D68A76BFDB579C6 +:10410000D5396733FE42D947D8C0A7EC063FC1FA7C +:10411000B4FEF53739622261AA97982202FAF56453 +:10412000A97C6A36D5C7E56326DF5AC067027B9F44 +:1041300090C7193FF48A063AAE5BA0F13F1F9B1F60 +:10414000CFBBD0F85B6DDA247C5EE7E97F5E169822 +:1041500017CC87CFCB1C7160698AD870BEE323A9C6 +:10416000581F1749C6726C640896632283B01C1DE1 +:10417000C9C5B234928DE575916BF0BD92C8082C1B +:104180004745AEC3E7BEC8282CAF8DDC80CF8B235C +:10419000E3B12C8ADC8CCF0B2365585E13B9159FD5 +:1041A0008F8C4CC37244E4767C5E109985657EE406 +:1041B00007580E8FCCC57258643E9679917958E6AF +:1041C0004696E17B3991255866471EC0E74AE47E52 +:1041D0002CB3228F609919F911964323B558664480 +:1041E000D6623924B209DF1B1CD988E5A0C88FF13B +:1041F000B937F21896E9916D5826479EC3764FA4B9 +:104200000DCBA4C84BF8DC1D79014B57E467F8DCF3 +:1042100019D98FA523F21A3EB7477E8EA52DF21627 +:104220003EB7460E6179253C5D490F1EF7A9918F77 +:104230008FF9D8C8C74B8F19F978C96F8D7CDC7797 +:10424000C4C8C78B5F37F2F1C20E231F1FB9D7C88E +:10425000C70B761AF9F8F056231FCFDB6AE4E3396F +:104260004D463EAED419F978E61A231FCF78D0C850 +:10427000C7072F37F26FEF0223FF4E274F1BEDF4D6 +:10428000C93B0CEDEE092F1AC67396BE1C63D7848A +:1042900090BFD80BFFD5F09E35EF700C5F56197F9D +:1042A0008AF19F0348207EF930B1FBC0AE89C56713 +:1042B0000AE707A9B0EF6899C6F7DD00D877B44CD4 +:1042C000B97502C6A952678E9B07FEB8CBA7040535 +:1042D00074226166753EE841294308F32790FC9BF0 +:1042E000FDB45E3B48AB135580FA5082FE0588FC56 +:1042F000617B36ABFFB2EE91491007AE35F376B570 +:104300007612F8D56A6DAC7EACAE621DF82352927F +:10431000FC83215169A7393E3FFF5892113E032586 +:10432000FF6F245AFEB9ACEB21F027FECA1AF877CA +:1043300089C263B935900521B4F3E6C0F3203A721F +:10434000047F27F42B12FCEF4AC8CF8D7ED35B404D +:1043500070D2F6A152F987D09E3A730FDA171A1C61 +:104360006A5DFDCFE79D5EF944504E6AFE8AA71C48 +:104370006EB43F1B9F904310373717A4A37CA84D02 +:10438000262C1E0A71218C0BB3FAAEA14AA891E922 +:104390008B46B9B2B5FE7E884758413EE5EAFDA797 +:1043A0005DE83F4D024B2117FC033D99122D575AF2 +:1043B000C2F52057BE4AEE3C2998102E1761FD0F1A +:1043C0004D0F61FF758E99E3605D142E5FC07A29F1 +:1043D0005CBE944627860BFD2BF78EE1AA05FC6791 +:1043E000AF60F05F3A4C81BFC3383229C7F115D5B1 +:1043F00087F03B2E79F07D0D8EF4EFC19431D1F82A +:104400003F7D4F360FE83B9E36CEDF25FE7D2E1FCB +:1044100035FAAE4E20AFB47825516FFB567EEFC310 +:10442000B218F73B66A91CE3B47DF8619A511E9A55 +:10443000D258DE83498A1F7746C7318CDF3AF3AA08 +:10444000E2D99ABF85D4DD7655FD1BB4FED44084F5 +:10445000FEB91A9E5A6F437A1CC6DFCFE57ADE5B3F +:10446000BF7F556D02BACC2398CF11ABDF356E15E7 +:10447000911E739399BEA8C15BE2FAA1F65DA9C92A +:10448000A827BE2673BB78EBD5C17F0F877F2EC5CB +:10449000F3BF96F49D07D93993ADC7C3AA0545C1AB +:1044A0007720DF64580BAB4B5BE97C8A13CF87F036 +:1044B000B884B68FA416D69FEC318EDBE7BBA61965 +:1044C000BE78F1B384DFF99671BEF966639C4F7BC9 +:1044D0009FE20BF19DC7F528524DFFE8BCF2891110 +:1044E0008E5ABC4FABBFF5FBB1184FAF0D96B078ED +:1044F000B993C973F2351D7D0CB8BBE2E3418BA7BC +:10450000D671FBB2DEBB03F3D9C85E239DCA831606 +:10451000E0F3C6820A0FCB4763FD2C431FC4FCC8DF +:10452000C682D5E8CF955BFD56B06BE502D107306A +:10453000979227F3F649D86E69657AA705DA15D000 +:104540005B77AE45D1100C35807F98A4493E086357 +:104550004AAD8106E82735101C8700EBA3F3D9C1CB +:10456000F198E195D695D17F6604CBC3367C8FF860 +:1045700087E9FA85F87A33331E0F43BFCC6055675D +:1045800019F8FDAA088E9F99B103CDF2C19ED96298 +:1045900099EEBDED7CFCCD7C3FD9827E0FBE1760CD +:1045A000F98CB1FB577BAF955786A75594C1B8F6E8 +:1045B000607939BED7CADFE3FD9EE6FD86417B29DF +:1045C0005227CEA777BFF37E2D7C1EF5DCDE1F1EA3 +:1045D00064799F75DCEED7FA3DC9C7B3589F7B0657 +:1045E000FC8EF941E68FD5DA83BC5DCBBB904B8D59 +:1045F000F9A31D66B65F3F97197FD2E826111D9378 +:10460000061DDF83F8A36A37D6AB530CF61FA91A31 +:104610006CAC2FCE31F60F8C34D6E79418FBFBAF81 +:1046200037B45FEEF5BB846C98EFCDFD2EF97CBFFF +:104630003CDD5A827647D4DFD765D3DB27197CACC3 +:10464000ED551576787F770BDF27DC3F63D3EC974A +:10465000BCD5D8AEAD7B3BDF271BC0FF6101BCB42E +:1046600030BFCAA8AA7746503CEEF9C0E4DBA124CB +:10467000865B223FCE46C027EE3F9657FE24F7E3E7 +:1046800004B91FA719FC38F9E0CFF1737FCE54AC01 +:104690001FE07E9C9FF1BCF2FDDC8FF3539E57BE62 +:1046A0008FE795BFC4FD382FF0BCF21D3CAFFC2650 +:1046B000CEA71BA6F807835F6DE794F876F14D321D +:1046C0008BFF4CA7EA1641F9DE23A0FF7C1CD555D1 +:1046D000E87AB3AA7AD6CAB49E7E0F835B56A0A7A7 +:1046E0000CFCE99EC9AC3E83CB55901F204F8897A8 +:1046F000EB3B1974C752786FE1749E59DD13867CC9 +:10470000165B866714B8406DFCBBB4CD8BF9FC9C7E +:104710008E6DD55561682726BF5D1E00E3B379E530 +:104720001CE99904E14DDF89CEC380CEE2CE76113B +:10473000FA159606D7510B9B380A4322F0AB86B286 +:1047400040E388B428BEE82C0C7441E788722B53F0 +:10475000E3BF138C742147B6A37E5C5B353B09E94C +:104760004F61FD8727907303E718EDA664BFD1FF63 +:10477000555B3DBB5F7FB4EF75E3FBC51D46BBAB2F +:1047800036AFFFF70BF71ADF1FB933E6FD16B68E0B +:1047900044EFE74466A27DF07C6B7CBEF00FA68AF6 +:1047A000898007ADEE8EDC88FD63F53E09F4B95CC7 +:1047B00070BFCB7ED07F25C5E3C7BC2445E1A58F64 +:1047C0003FF7F37A39D6A97E385D1E8D7831E887B8 +:1047D00026CA902116D23082703BE3EB75FE0C5A4C +:1047E000BF93A01DE290AD37AB13807F2C34F855FA +:1047F00052E5AA330AECD7C74494253B83FDF3BBAB +:104800003E79114E3FC68F729B3C25A638F8D6CA1A +:10481000AD4DE2D47871B1259CAED737CDF6A05C12 +:1048200038123F8F44EB4FD7BF44D6E5930CB88383 +:10483000E7099C63F96C83392DA52EED9F0EAE36EA +:10484000BF63AFB6EF9C2C6F44A3FBD4E1FDD389CB +:10485000A67F464222E9847D2155D9F148C21D3EFA +:10486000CC770701AADF27B57F7BA011F8A6FA2332 +:1048700011F9C8803BAA443D1EB4790C56C265B0FC +:104880007F6B0F2D1121DF3EBFA54AC4731387082C +:10489000FF0E9570B4B42D0EF9999F8CE559DAAAE4 +:1048A00002EBE0F9F016062FB04F797F940F1BABA7 +:1048B00067FB018FBB33888FE7AF18FC75BB9DA2E8 +:1048C0000A7AE625CAAF5051F89ACE4BB3EB28F0DE +:1048D000F25B996BB676180939A1DD3F15E1A5E5C4 +:1048E000EBD9B65D5471DE031E0AE37993514C0F88 +:1048F0003093CE30C616A4802AD0F1D7073C3EC8EC +:104900004FCC6D29667E99BC20E651AC16037B80A6 +:10491000EE357898D3DA316FA536C179810D9C9F39 +:104920004B24BEFDD1C9F970AAEC9B0EF6E89E2778 +:1049300028FDC7F10BBCC3C7796EEBECA4114A7418 +:10494000FF6AEDC74169D3CD2B3722B33CC1966FC7 +:10495000A7EFDF6C263CBFCAF89E49F219ECAD21E7 +:104960006605FB6975C969E467573F4F09F9122964 +:104970009C6EC073AABB7FBAD6F6CDE5A1317A474B +:104980005E01D27354EF10899BC2B5358FD30BA74C +:10499000274D8EC805414FBED0974E5AAB4BF0BC49 +:1049A000C9A509940EE99FC5D3EE07BF816B4218D4 +:1049B000D237800ECE021D0CCA53D70A4827631087 +:1049C000DEED5CEE593DCCBF123B6F4DAF03BBCA71 +:1049D0009B0223C7D83724F81ED077EE0888190227 +:1049E000DDD0CF51BA960AFAB7EFAE365EADC58FBD +:1049F00033E91FD8371D806FE0E39FC5F8A93C5409 +:104A00004F1DA393EF9F3D80FB2316FEB1EFD57999 +:104A10002679E2F16D620A782CA313D34BAC3D4D9D +:104A2000FAE4AD3D88FCC332632ADAC9BD7675EB82 +:104A30004C5CB785DB8BE63C6E47F6B11BEFF1F5BE +:104A4000274FCC19DF2D3F74A425BEDD98E8FDDE8D +:104A5000BCD06FE977D8C8F3EC34FBA3D7EE881944 +:104A6000472C6C8F7B0EC3596884BB3DCFA877144D +:104A70009AD9FEB4788D7E63B367707CFF26CF4FE2 +:104A8000AB18A7E149B9FB3FE97E5B72D44C1AA190 +:104A9000CAED5CCDAFB404F2D4281D5740DE1AC570 +:104AA000D30252EE86C6F344C47C98F3E43DF77516 +:104AB000BA7D1FB0F073010DE6D3709E42CBC75A8A +:104AC0001864756D3E952DC6FA22323B1DFCAC8BE9 +:104AD000B69A09E45F2D21D2E92E6DFE940F945B06 +:104AE000981E5449AAEA81AFADE7FEC30A0F912090 +:104AF0007F6AC5ABCF8C81F33995166E8751F82B41 +:104B0000BA3C9BA5CE900CFED14F3AAEBBEB060251 +:104B1000EF87EA0797629E3BE651C5C27D7E8371AF +:104B20007E579A7FEC7CB5731789E621ED11E29EE2 +:104B30003FFCA14530C4E7AE742EE41908820D484D +:104B40007C2EE44AEFEFF88EEF3FFF1DDFDF6B6155 +:104B5000F49BE8FD15D69E5B30CE9F56558EFE5ACF +:104B60009ED7B19204FCE03A37BD3E4B1DA2E8FA55 +:104B700079AFB25F06ED67BA8A7E79FD8F7781EFF4 +:104B8000F35FED7D4E86FD7BFEC55333412F58F616 +:104B90009A8958214F6DAF8B9FFF0AC920EF9676F7 +:104BA00098985F410A8FB95D971F082758018ECBEF +:104BB0007EEAC278F2D2972DA119F4FDA5AF7C52FE +:104BC0004C281C2EACEB797B08E83F2F0A2CDF4ADF +:104BD000ED2ABE9D3E5F2A91FBCAE3F9D12D4C4FD1 +:104BE00039F773C71CA03361CFA17B71DCF6BBCD55 +:104BF000169D5C3864316BFDD8F9AA1784D03081DA +:104C0000CD4F9FEFADE5B99D7B4160F33B680ED979 +:104C1000607E7BDAE400EDB76ACF5F90AE6FFEE9AD +:104C20003E37C061D5419381FFACDA630A5B8AB13C +:104C30003C65417EEF770A63009E04E5F7CA8E1556 +:104C40009817BBB27DD35F4C6E78DFB8BF285C7C11 +:104C50006180EB71936F06D47FF6BC1BF2893FEF46 +:104C6000DCE506B8D271E7C994AE6EFC52B70F0905 +:104C70001B3F92D2773C427A64A0AF55ED1BD9F727 +:104C80003A6E3B03FC6D55CC3EFE1CFE31A8AFFCDA +:104C9000B818233F2E91DF8E017D83EC498D9B67F1 +:104CA000D02B3FF8BE5EB6EFD276381F7CEEE53FE4 +:104CB0006D07BD7EF9DFBFD8FE08F803DEB079804E +:104CC0001FAD7AF10337D1C1DF65657CE1C20BCF3F +:104CD000EF7E9AEE930B1F5950CFB9F08B33990AA0 +:104CE0005DFF85FD7F4D07BDFEC15F4C1908F07863 +:104CF000F0C0CD03FBB363806E43163D7E43885FF7 +:104D0000E5A0C092975FE7650C9EDEEA782B13E67C +:104D100079FE8405CF71ADA2CFAA4B006F2B503E18 +:104D2000407D0D85F7CABD1BFE622A8E0777758808 +:104D3000E885323C847801EFB7FFC3C45228CD3EEA +:104D400005C6233DC8DF63DF5B758CE2F7DAC4F884 +:104D5000BC44BE9601FEABF66E64DF6DA7F874F737 +:104D6000C5E779F8C7F8BEF82CB4C6E273F9B3E822 +:104D700063EC488D9B17A7E173C5813BFBD51B34C2 +:104D8000FE7025382F16D8BC2216FF042BECB397E3 +:104D90001DAA97E1393483B65DD8772993503AF943 +:104DA000CCDC732FF0C99E5F583C60772CFDC57139 +:104DB000DC77170EBC2B2BECFC8853A07AC505D2F0 +:104DC000FBD7097AC64A815556ED74852DEE28BE6B +:104DD0005686664D55DCF8FC143E0FB1FDB03274BA +:104DE000E80E210EFE1EB2E630FD333400E1B28241 +:104DF0005A449E42235E857180CF53B700FD25C281 +:104E0000A7B67E0FAC7FAC0EAF3BD93E8EEDBF9206 +:104E1000EE57E0C37DF01B128E4379A1CD22413EB7 +:104E2000E4057E9E2516EF51F8F3F390DF525FAC58 +:104E3000B226883370385C69BF5F697DDF167EF704 +:104E40005A151C37168EE7BE8E2F0F9A38FF584919 +:104E5000AAA60ED6C9338B99CAB36CD0F7CAD5218E +:104E60004274BEF5EDECBCDDB93DA610C88B587E92 +:104E7000B132817DFCB495F9BF571E3C540C7CEDDA +:104E8000DCE19F73BA6474BF72EF2959E5F221A483 +:104E9000970F09FC283BF9BC57BD1E7FBC557BFF13 +:104EA0001277BCCF25FFDD30FFCF3BCD44A5437C3F +:104EB000DE6E9A1A4FDF6AB69A8D79B5AE312792B7 +:104EC000E87B26B71DCF33D6AEF31F57412F79CFDE +:104ED0008CFE1522F93EB3E0F969BB02F1E55AF701 +:104EE000223CD7A28D57170327C95B8EFE0929AD37 +:104EF000BC94E9D421833D6DF688867953B99B0132 +:104F000072E9E4A8336658E71F62F4C73F48A47EFD +:104F1000201DEF0FAAE05BABC4B3178DE307D69853 +:104F200088A29787969E93301FF2A68D40BE9AE97D +:104F30000D9B0AFC64D5761BC6D5DF3A707937C065 +:104F4000EDC2B3161ECF6479B595DC5E3B73E0F21B +:104F5000F6FFA2ED67E065FAFDCAEDB43FE8ED7B30 +:104F60001D98E4FCE797938A09E5D3956F3E3213C9 +:104F7000F84B25C4C069FFCA9F0E0C41EE42F700F2 +:104F800056EFDE3734047859FEB35FAC0479B2ECE7 +:104F9000270E0224F9D681E3F742FDC29B2ECCEF07 +:104FA000BAF0E6991B611F507D5BD1CBF525FAF372 +:104FB000DB74DC655067EDC2379CD7811DB30C4AAA +:104FC0004AEFCB0E26E179075D3F7C6F95A5E7217F +:104FD000BCC885A88345B489C283611F2EDB63FCEE +:104FE000DE592BB32B56C93D8B58FFE060B65F3BB3 +:104FF000F1BDAF38DD6BEDB1EF6BFDBFE4FC333AD3 +:105000000E7B7FA58554C5A37FC1C6C65DB6E76F7D +:10501000F9C6F118BDF6FD0E7BFE4381E5E393FD75 +:10502000368C132C97C3C353E87E7D45268B61DFF6 +:105030002E77878727D3EFBDC6F9E5723BADD3E75F +:1050400083F93CA03FD489B5EB2780DF15AFDA08A0 +:10505000D0FB8A375DE8575EF1CAE5EE7FA1CFCF7E +:105060001D70A0DF6FC59B0F23BE5758C2F7829FEC +:10507000AE67BF85ECA0FDCFEDFF7526E823E7CC3A +:10508000E1CC947EFC432BDA2DFCF217E33AA85DC9 +:10509000505045E7A33EC6F270AA09BB47A09AE765 +:1050A00079908F6DEC9C328F4BADE67EA28B0B948A +:1050B000249CFF845BD973EE275A7D9B323059378D +:1050C0000FC89323D751BB44AECA073E6B8ADC4A54 +:1050D000145A9722B9586AFD4C701F4321E427B037 +:1050E000B8A039CD472A69F9700A09E0F948E7F410 +:1050F000DE7DF6EF14C5ABB7290361BC9136C65F00 +:105100002AEDFEB136E433C67B14D4036C5D97F907 +:10511000FD08B1F3BD6C562DC0CFA3F13A962758C8 +:105120002D29C7C1FF4E8E72BED467FD6C9F5DF402 +:10513000A4E03ED3D6B1A9C683FC04E265506EA8B4 +:1051400029204A3EE47BF8B06EE2F0B014AA04CE07 +:10515000F7C21E843F8BB3DC2FB2F83001FFABC91E +:105160001940FAB278ABD05760E5F7E9989C2AA9C4 +:10517000A4A5D9C9E004E7F6004E32AF4B2D331099 +:10518000AEF47D7C7E933D702FC0C59A31D2C0A70E +:10519000E4B41243BD0FDC34BAD8F7BF0D3F82F040 +:1051A00002BF8E8271CC7108B7F5357EACFF7F806F +:1051B0005F3D83DFF544D1ED1F396D92A19E107ED6 +:1051C000DB28FCD2A2FB2A160ED53C0F47DB4F8909 +:1051D000F6EF933504832F8FD7B460A93D4F492054 +:1051E000D7CFD8985CAF2681B566E0531EE68721FD +:1051F000692AC9D0F99F8857C5731FE8EB87F68CD9 +:105200005BD17FA9E1D7E491BA8DFC4F390EEB79E0 +:10521000F81DB308FCCA54FD1CF92455B78F6794D8 +:10522000DB1484B30FE303B55CBEAEEFC5A7717F9B +:105230006CAA51B0DCCCF7C916BE4F1E03BCC37DAF +:105240000E702F05FD5ED35482F2F3095A67F67E85 +:1052500098E8FDE1C9BEF6B099E21F79928225FA7D +:10526000ABC9094B685836C455891FE825F9C48F66 +:1052700042B856D28EE72592B57B5D5ECF499E8BB4 +:10528000F11F6266728A98581934831D150BDF5A14 +:10529000DF612BD8E189E65376728900DFBB3C974A +:1052A000C5CCD2EE693F01F73C389B1C6857A6FB82 +:1052B000AAB23291BF5A905E9DBE8050A9C3637A54 +:1052C00002FDEF21FBB40F801E3F843C445A3EDEBA +:1052D000926B03386F32B77B811F6EE2E7C5953959 +:1052E000140ABAFBC2DEE47CD25D6AE4031A5FF6FC +:1052F0004C2831D0B3C67753261BE95EE3BB2FD8C9 +:10530000985FA3D25E7E06E6931A69C57D19BB0F2E +:105310006ACDB22A5C8BF7CB30FFD32981C5D5FB90 +:10532000F2038CBB5FECCADE01E7A9B5FD13BB7EBF +:10533000A9611A7EA7571F34C7CF07182230B9DEDC +:1053400040E98D605E82828868A6744678DE02DB62 +:105350004FE3B0D4E8781D613C44ED10D93CB9BFAF +:10536000563B7BB3CE5AE2073CAE6F677B68A09D8D +:10537000C749D344905D44A2F6A4933E920E8DB7E4 +:10538000827E29997D47810FF6B8C47688E3AE778F +:10539000CEB6421C44482E45FAF9CA5591D55F5CF9 +:1053A00007EE5303FAF3387DE474219E8745BFB0BE +:1053B000C95342C02EDDE7ECB4633E935D34C49F15 +:1053C0002AED810CBB4E4F2D82AF73BCC3B0FB12D4 +:1053D0009CB72CE0EB21192AC9D3F189DEFB8F148D +:1053E0009514E8F8C5BA61B7E0FD4A7DF944027E3C +:1053F000B8EB7F861FD6668510AFE658FE93E6C7EA +:105400003B9D68A9C2D508263274FD0F92914E27A4 +:10541000023C887347AF1E74534EDF79C6F2BFA8B3 +:105420005C53D00F46E5DA53E3809F26946B55F723 +:10543000211D370D51808E0F353FF22CD43F69B6B8 +:1054400028C0BF1645361285CEB732321ECBC52DC9 +:105450003FC6B2A2A58D6E2242D66EAE6C9E0BFDEB +:10546000B799D0FFD31DBAEE4235AD773759507F8B +:10547000EF6E7D200BF4BFEE268702F7AB74B78E7C +:1054800036B63798709F75B79843261E0F36413C45 +:105490008270FE0E5E20DD7C49A9827AFCC5987878 +:1054A0004BC5168B5F7027867F454B7C7DB216FE01 +:1054B000C9CEA3E5037F2D3BF9A32CA00F8DCF3CD4 +:1054C0009C42F91EC0EFA485C48B0BDC649FB2C460 +:1054D0003E004AFFFD768CEF5FDD3D589F8854EF1C +:1054E000463C05DCB30C7E5FE657FD84EBE5C49AD1 +:1054F000A0DDCDDFF7C46F5FD1F4A7B71FA5B50D51 +:105500008546BFB609FCD502D8E3B3F8FD196C3E59 +:1055100071E89AE9D34D16E42B0BB83F4AA3F32860 +:105520009D05DCFC9C9E810E97441E43BE276C2A81 +:105530007A6A3C85DF1794FE803E844D1307027C17 +:10554000D736DEB0E51E3AFE97BF35E1F3C5111B35 +:10555000F63FFBA8EFA97BC05EF83733E6917C7974 +:10556000740AC691CF9A8D7E8C1B1C6CDF1FE4FBE6 +:105570007F516493413F5FD4305F063FE8A24833D8 +:105580003E5F044124CC8BBFFB976579105F229866 +:10559000CF72D07EC79475284F4BD08F56B9D91291 +:1055A00037AFFFA05D31F2ABAE261C9750FD2C2D1E +:1055B0009D8FA7E33B959154DC1FC4A312C8EF5EF7 +:1055C000C4F94FEFFC5ACD06FE73D616DF4F73D4E5 +:1055D000CEE4C2A2C80DB8EFFAAEEF467CBE48FBDF +:1055E0006E17DBA7D1F53C353EDE7AA2EB9880FD45 +:1055F000CF26C7FFFE9FF9F7BB6B16133FE55F157C +:1056000016DACF09DF7FA07E1CD8F9ADC929826EDA +:105610005D952DCB885FB7AECAD679B2FEBEC928DC +:105620001EEEFF659914C5C39F1B974F595708FA83 +:1056300042F97FC23EAAD834B1388076FE4684F360 +:1056400027665F26F0E3332D0FB8E3E50FFFD9AEF1 +:1056500018FC1C952D1C3F54EF2ED5E147C34BEC95 +:10566000FBDDBFAFFCEA51E053DB5C06BE125BF62C +:10567000C15B767CB8D91C1ADC0A4800E1A6BC7272 +:1056800002E87AB3C307749D187ED790407FF04B31 +:10569000A03F533D4B748C86EF12665FB6303AB82C +:1056A00012DCA2DFE57450167F3D63F97EEBAEA9F4 +:1056B000262ADDB0A7E52BD1C12344B5F6B38E5E13 +:1056C0003A78C24007631D9B910E3E03FD27BF2F12 +:1056D000FE4FCBAAFB7AD0771A4D18F73A6D57D305 +:1056E000BFCFEAA3803F9F7607675E5F1AAD2FD9D1 +:1056F00035CCADBFA7F14C0385431CF88D75C4ECC8 +:105700006F8D7EF2545238E6FF1DFD7C92E0DCCBBB +:105710004DF6B21B009F2418DF9FAC95BDE7AA93FE +:105720009CBD762FC8D1D3CE9CAF42B4B5C11EF874 +:105730009E83B6D7253F8472FEF46901E5F0DADF77 +:105740003F9C0F7CB88FFE5B1379FAD361E8B7FCFE +:10575000974FCDA84FE1B884EA3F200730671CED92 +:105760008021E8674914CF5D0197F98E8EC675B523 +:10577000F8EDFA9ACE1FC3F8C4AA128FFEFC00619E +:10578000FAD8FF8179E8FCF3B239E0F181BD2B90C2 +:1057900072A07BB3C4F2D7CDDEB451AA0ECECB1C1F +:1057A0004C9FB41D39D2904DDFB72DFC770FF8F91F +:1057B0002CF43B505A33A48B7A7FB996F745F27498 +:1057C000CF7320BF82D60D7E073ADF7EECE6D7048A +:1057D000EDBE4F15EF2B9EAB5D5800A0A374F39167 +:1057E00096BF22D5B1F664ADB98EB5733FEAAA0A69 +:1057F000E6277D6B5E12C24F5BD7DCD737E07D6951 +:10580000735F1F341FFC69739DF97F0478BE06899E +:105810003540F7C94C3EC7D2C566CE7F7ED026AA9A +:10582000663ADE1173CF6107EC8B1F0A68577FFF62 +:1058300083236620F9FF3876DA0CF723DC078945E5 +:10584000743DF3882233253A84EFCF27ED2E566F2F +:105850001F00F79946C7A326338C773F8B3F7FFF06 +:10586000836353408CD2F1D64379DF6F890CE3CF49 +:10587000EB50EAD9B1273EDEEB743C313A5E2FFCA7 +:10588000242BC2230A1F2BC2EBA3DE73242AEA17A0 +:105890003AF8A2BEA2C1B716E046E1373769CE7426 +:1058A000529C78BFCC750EFF23298ECE2716BE5F83 +:1058B00042D320385FE67F09F6CD3F3BFC7BA15CFD +:1058C0006EEDC99472F0BC573BECCB95A640563AAE +:1058D000A5ABF34303F903E0505067FC386FEC3E8F +:1058E0003D09FBE55A28E9BE8079F07329F7F27586 +:1058F000BEF5A3332ED897F5078E6742B9C2D4B54B +:10590000F96ED86FBF31A1FE79B123BFDFBCBA9366 +:10591000DCEF72D4A1DDA3C1D6791FD7E7EEEB701F +:1059200084D652D2B8AFDAD46B5F015DDF57CDF2C7 +:105930004F88D4597C87419FACE3E7D4FA8E03F6B5 +:1059400042EC38DA3A0F670EBE06ECCB6747CB68FD +:10595000471CFAEDC58F2A69DD3ED48A76C2E6641B +:105960004EBF65CC6E7D36D9EF2802FF57638A4F54 +:10597000A5EB6CFC256917299C0E8F782834A91497 +:10598000EE7916D177B625F25C7012BC57C8EE9945 +:10599000F170BD744BE7E916A0C733272C1877F8D0 +:1059A000C465C2F9369ACB33418FFF639B1CF7FE67 +:1059B000B28F5C12CEB74DE8C23CBDF92468057EBB +:1059C000D1D1397B20CCC7ED231E20FF33AD2691EA +:1059D000DD6FA6F95BC212F3F7AB12ABFB79E9B14D +:1059E000E9EF17DB387532E6792C687A17CFB1B951 +:1059F0004BE3DFEB6373B2F9BA3A53A6017C5D93D4 +:105A000045CCC376F97A04782FAB73928CEF078577 +:105A10007EDFCF5AE399067085F781CF675DE5FB9E +:105A20008293E5693DC6EDEC36B3AF7E321DA76DBE +:105A300073B200F8D0FA0D7632BE7266B2E64762F3 +:105A400079C299791E5B1E9D77A61F37377195061F +:105A5000F11CD30EE8C7FCAC0887B611AF84218EC9 +:105A6000DD08FE15C0B399D153E36601FDAA147E8B +:105A700083414EFCF109CBADB08EAC06C103B63B01 +:105A80002DE3CE7BB6CBCAE8BCE929B40BC14D0BE4 +:105A9000E366B6BE8FF3722558EF1A4E1F7FBC0225 +:105AA0007D9C77303F54667527BFDF2E8CF7D80575 +:105AB000014E50F797F2FBEAFC8A3E3F26BA7FD6AA +:105AC000723A247E88B3558C9343E047101BDAF07A +:105AD0009ED4F9410BF91E5D5F93C0EE1D55478BB7 +:105AE000FCFE24FF498053F36303310F6F83E8CF3B +:105AF0000439ACFEB38C71BAC3FE8BDBE03EF8ED2B +:105B0000E364DC1787FDEC5CE1B36B72DA204EE9ED +:105B1000AA9ED4329F8E17F260462CA92D25EFE461 +:105B2000439C728DE81168FF60B996B7EDC17CF2B5 +:105B300051A62FA615401C6F90883EA53302BBA727 +:105B400061FD9A491EC0EB7A4F9AA0B75F66713A21 +:105B50003891523ECB49E1E37DF4710F9C85DB1215 +:105B600049BD06FC886A83ACEC62F142BCDF21953A +:105B7000E325B5530C2F7263DDB9989ACA5B2630C2 +:105B80007FE98FA707989F1362A363D0CFC9FFBC9B +:105B900088D7345E6B1C69C7CAD6758BB03F8C93AF +:105BA0004EC7492D15C363207F2DD9BF1DFD7653E8 +:105BB000AC08272275B5009C425306633EF8E3E328 +:105BC00087BF0BF9E3A9477B66831C0D0DB5FF4723 +:105BD0001BF0A9F5B202FB3C754DF73DF03CD9F73F +:105BE000E40350A6D67DF808F0E9E4AEBFD4E0F3B4 +:105BF000A9B2C1BF98FAF1D9BF417B6AB96CF05321 +:105C00007E9552FEA093C2677B613058A1B0E7FE3B +:105C1000F4E83AF6ADED9C0AF7D89F9925B2F33235 +:105C200084F1C3AD5B3DDA39E552900B1ADC36885E +:105C30004A7B18D635D38AF491473A915F0D826832 +:105C4000766E142FA91F6FBC1FF23562E7D3E014E4 +:105C50007ACF51C3BD80786E3107CE1F4EB6035D3B +:105C6000EF2FE9F4823EBF39C1FD9D475DEC7D8B8E +:105C7000C8FCACB1ED47783BB0C496122CFD455042 +:105C80003A899A046586D50FF9CFFB45E53F91CE59 +:105C90001F3729801FE86FA6F83BF4CEE7E85F3C8A +:105CA000147C1FCBE75C05DA78E174FA7E73E9694E +:105CB0008CD3347B188D5436307E51E9EDB242DC02 +:105CC000A4B2907876707A53353883BF8CCBAB8A88 +:105CD0003B185CD30A09C67DC11704F74BA5433FA7 +:105CE0000ABFB486B5F7231E49A79A4BFB35C3B844 +:105CF000809F3A91B071BBACB87F83268C7BD2FD7C +:105D0000FE3BF06B55340DC4B83F1C0F86F152F8C2 +:105D10007753F8786D741CF01F9E6930E1B9004824 +:105D2000BF81BAB286D232D2674F59011D5729F5C9 +:105D3000781A353AD0F818DD1A0BA8BC00B82D50E7 +:105D4000D5FB81FE4E5B3DEFC03C1C5B2D0AAC7F5A +:105D5000C1D6571F06FDC5E1ED6A00FE50398ECD54 +:105D600037A5893E473D47F91DF4AF6CB228EC7B5F +:105D70001C7EA59CCE381C16F2792F6C65F3B60FED +:105D80000D05813E2BD750B8425B80D13DB844BF52 +:105D900011715F1D85F5BBD4741C77C09C987D1173 +:105DA000437FDABA2AF8BA2AD6B07511BE9FE8B492 +:105DB000C2306E45295BE702C2DE17E1391D7F2143 +:105DC0005F4F85FA0A960B1B2C86F1B717ECEC8413 +:105DD000F96417CA8A807066F71B66F27565D6B1DA +:105DE000EF6516BE82F022D5BAF9A25F5557A7FB20 +:105DF000EACCAFE9C682C3FF70D0808E7BFA47EC55 +:105E00009E81BCADC6759DD998FF1C9CF7FEE40928 +:105E100019E3DEFB45DFC92CB4476585F11FDFFBC5 +:105E200033804F2FACF3011FDF57C6E07FE63612F9 +:105E3000027A1876B43C05E03DEC68809755184F1F +:105E4000A700117AF91E9D1F35991A04E09791DC7D +:105E50009716031F18C7CEF70CD5CF9BCE2FB521B1 +:105E60007D12E443A58D4B9924E315DE31ED479F68 +:105E70009E0DF78FA61D79FA01F8CE20A25B0FD0F8 +:105E8000833B979D6739425BA15F75F7A3808F269F +:105E90007E9FFC3098590A9647A04CA5FB7B530A7D +:105EA000CC5322934BA2FC60D7136346015FC1948D +:105EB000A7122CC3A4A42FDFD0F51FC1FBAB429CBB +:105EC0007E16B762B0CF773D71CB08B0E39B414FF0 +:105ED0004C827B383D5F409E8EEA1311EECDE6B0DA +:105EE000B5300DEEA51609E82F5B0A3E1461DF35CB +:105EF00077101FD0476AF9DF2D7A3C96B9D8EFEDBD +:105F00004832D904FBFFF088EEA980A7D02111AF59 +:105F10001898F42BE7D30ED0873E6279306DBFAE70 +:105F200042F9FD50A61CF73E5D72053D31B67FCAB1 +:105F3000B0D9E8CFCBDAFA18DEE7593955F27D8FC0 +:105F4000F64EDB5A56067A8C524EA96B209D77EBA3 +:105F5000A8B5F83B103358BC4C99CA9E2B9359B93D +:105F6000A9E6E88FC16E0FEE916C7974BE2337B24B +:105F70007BC436155EB406A85E5A5AF6B2F536FAF8 +:105F8000FCD3522A05E9F34F275CB4417CE7D9D210 +:105F900049A900CF8E06A35E47E0722B6A0F155900 +:105FA000827E179D57D30704E169B2845B2A68DDBE +:105FB000F4AA13349C3E76CEC6A6B63940A70B0A87 +:105FC0006474DBC7AEB793CB8BF9D53D53E1DEFCF0 +:105FD0006C9530FF7EF02964CA0B39CBC8563B91D3 +:105FE000E9B8B632FB2428F9DF06BE1C2C0CC8F039 +:105FF0008AC6CF9A8655EC067E76DCC5EF0BA95A89 +:106000008CE7CA70FF9B401FEA298B6737153BED71 +:106010004C9F6DBDFD38F8A91754337D3FABF50B90 +:1060200001F141F5BE4174FCAC52BC5A902C58139E +:10603000B416017EF244A228309F7602764290CABE +:106040001F3D1CB471FFBBEF2F7359701DC5A03BE2 +:106050008F8EAEC7C9D793E9A3EB8923A70BE1BB0A +:1060600090EFF3CC1787C603FCD73013292B784A5F +:10607000B0EAE691A55EDD3C8AF83AEA5CECBC85C4 +:10608000ABB44BC0FB6B62F83BA8F3B06FB73B2ED1 +:106090008C62F6BD919FF6A973BA8A7D9E19C3AF33 +:1060A0008A2CEDD311BFFBD8BDD584D07D6BC5EB59 +:1060B0001B1576CF6748BB5FBA0AFA8D74393D402D +:1060C000074D233E2C01F86CE6FAC2C24282F6EA82 +:1060D000C28C4ED417E6D7717D41F2D5039375B4C7 +:1060E0002613ED7E18D01F50550213BA8EEB0B9A73 +:1060F000FCE772BBD2DBD98072B58E9DF7EBD5334E +:10610000542657B3BC4CAE5736D0EF289C98C7E8FE +:10611000F51226C795AD5C7FE07238957F37AD816B +:10612000C9AB54D023DC9006A1A25CC618567A54A1 +:106130006F1950C8E4656AD37E946B2F3A199F4C4F +:10614000DBCAE4E5D0778FA900262F7DDC42F9F485 +:1061500013BCDDEBA1FA594A543FDB20F2781361FE +:10616000FA21E6FCD3796EE6FDB5E73BF9FCF61FB4 +:1061700049B915F8EBAE600E9E2BD7F62D7A3F6924 +:106180003D93DF879059CDE2E42EDFA2DDFAF3677D +:10619000152E76CF50858BDD07EFAA0E7B615CBC98 +:1061A0005701F9B88CFEC58D545F42FF13B7AF4A53 +:1061B0009DFC3E194E3F89E489C6875CC4EF2EA43E +:1061C000F0FD34B41BF9B54AED2558DBA7C1DAC19F +:1061D0004B61BF076795C2FC9BC77F85F91F5909B3 +:1061E000ECC58F343BF35BF275D7D463CC0EED1462 +:1061F000E39EEF497733FF43BB441C004F5B90DDC8 +:106200001B671B27C7ED6F7333BBEB53BE1F9BC7C9 +:10621000EFC6F39909E5B34454531C79AAC9DB26A8 +:10622000C0F3F574DDAE5FD5E3EF0849A17213F258 +:10623000578276679074A11DA916C8E8376C32079B +:10624000AD808F2DA51CAF1E6B1B9CCBFCD678A1FF +:10625000F0003C6FF48B21211BF01CF21431BF0EB7 +:10626000DEDB7986DAEFFA7845AE5BE47052F087D0 +:10627000F6B21A187D358F97711E8DA3D2DB4CD9DB +:106280007AFE2B70FEC9E8AB71FCDB485F573BBF61 +:1062900045D52F3DF3A92E9ED8BDEDF91C8073F492 +:1062A000FE0B7FBFE7291655FF65EBCE387182DE06 +:1062B00076B0A39C600786BE6F886BBAD9BC6F743A +:1062C0001BFD77C05FCD685C8406837F69DFC49067 +:1062D0001BDE236B58DC76098FDB7EBEF3763CAF8A +:1062E0005E44C9CA1C07EF676B8CE7D5CFEE7A7E98 +:1062F00030F36B840CF1B325BB7F3ED2101FF61335 +:10630000256D0CBBB718E5F4DB3ED5628ADE3F2075 +:10631000C3EF0DE446EFD1B293762C9DB07F69E9CF +:10632000263D587A401CE5829DE4C3328D946399E2 +:106330004EAAB0F492209683493B961960E7E68214 +:106340005CE8C152211E91E8F87E0EF1613D8F9408 +:10635000632901DE52A37109698F15F337207E018D +:10636000FB3ED1B9B391EE8A656E8477D5B5E598D9 +:106370004FCEE21533DCFEE56E942F61E4DFF33996 +:106380002B3FFA9391ED70FE68F56676EE45E3EFEC +:1063900068DFD0EFBC94C2E481FAB8807C6C9D6366 +:1063A000E68D08CF26F3397DBC8158AD79F0FB1E10 +:1063B000DAB8F3B99F613E9783E0EE66E7077D7830 +:1063C0003E693EF81B74EDA4B79DDD4BA38D233AC7 +:1063D000260CEF2FDEA77B1FF3A32B62ED802BC9CA +:1063E000EF98FA82D8F7BFA6134A8FFAE35EBA5144 +:1063F000C9447AE5F29B129482EF35584EA13D16BE +:106400009CE2D7C3E539CEE734B9B22026DF23B604 +:106410005C20F1FD11330E9580C970EF1ADE29A1C1 +:10642000DBDFDA7DA4DAEF642DF107E441EC352FF0 +:10643000E0D1C3E71D24AD9306D1F233A8EBFCFBFA +:10644000BF4B0AEC77EBF68BC7CFEE59203C2EB151 +:106450009CEFC729A6A632E0736702C40776C41270 +:1064600052E5BE01FCF9C7D8FDC443E8BCE512B053 +:10647000E3882AA6605D85DF6B395FC3CE0975F3BB +:10648000FB6876F37B85FFC4EF112E6A797826D0FE +:10649000C1E7FC1E9A828E8DE5E0F7296A77CC036E +:1064A000B95FD43EB112DA8BF658D8EFF0703EA146 +:1064B000CD0B8EB9DBE97732E8F7AC29C04F08CABB +:1064C000DDF34DF610FC7ECFF97613BB47B550C413 +:1064D00073F770EDA089CF2F2905BEF75FF7823ED5 +:1064E000F239E727DDEE64862F4915D434484B2175 +:1064F0003ED06B1E73ACC473908B9CA1DD4FA74143 +:106500007EB8D5B78E7EFFD0FE5733E1F9538E9516 +:1065100058FE69DBF14CE05BE70F1C97E3D1ED0A15 +:10652000292C837F6A59872042FCA4AC7D9E0CF104 +:1065300091457B0FA15F79852780EDCB5BF6637D6D +:10654000F2DE77317E323449417C9F1F14403F6F29 +:106550005E8B250C3F59B22F27B8346EDC3E89F193 +:10656000DDC71C6FE0F84F39DE781BE1B2CD82E762 +:106570003F0E6DFB158E7BEEC0AB7CBE04F305CFEA +:10658000DBDA4FFE13C8AFFDFC3CA6B5D3ADF70771 +:10659000FF9DF375AD7E5EFB1D9D8C2BF4D37E8F2E +:1065A000C7D9E9667CA9D30D71B345ED0C0E7F32D6 +:1065B0008765D02397B50B0AFC3E5ED9DE363C0FCB +:1065C000B8ACC38AE72596013C006E145E08979626 +:1065D0004338FF0C80CB6858C7FB988F9FD741E1A9 +:1065E000521C5DF7326700F7ABB65E0A07B6EE7D68 +:1065F00057C253C088A7967765F0CB2CEF10107E5A +:10660000CBF7B2792CEA60F39ABC771EE2FFDC018B +:10661000A280BFA57BFFF1CF613DE70F58F1FE5E81 +:106620006D5E944E89BB04F60FA353D2C1F8AAA69F +:1066300077AF08A5E3EF0CF4B6EF65BF330A20B3DC +:10664000517A2DEA988571C162205EA0534FFB48B4 +:10665000F67B81C14C80EBBE89E14C98F739ED7730 +:106660004CA56026E065A43B509CA4DBE7674FBDCA +:106670008A72B140ACFAC3A3B08F5F66BFBBF1F0C2 +:10668000C78F897A784C841F4A1E0D70FB9D1BE1D1 +:10669000D67B7F4B90E54B9100EEC7457C3F9E6FCC +:1066A000A376275DFFD9969F61FBF941C6FCAA3FFF +:1066B000B5BC950270ABE0E73148E876E447142EAC +:1066C0000DD63872BEF75C5B889D57BC2010BC2F7E +:1066D000537D46835B953CDB10E763FC30A335FBC1 +:1066E00008DA19A1F8E71C63F5A4D8FB5113E503F8 +:1066F0009CE6FCEC537E4F97267767B8033F481A19 +:1067000090F8BC77C5A6159900EF0A381B89F711D8 +:10671000BDF13DC823C57343EC5ED430C0A75BBB5D +:10672000F79474B0F664565F9DF46F1BE03C58B765 +:10673000768FAA7A98B567B3F666DEBEC75DBE34BB +:1067400009E53C11D8EFF99893E1771934B991181C +:106750000EC6DF6568830B3706E0780FE278121DFE +:10676000AFE8BB8FA7F1E9EF3C8EF57F761C4D7E3D +:10677000C1FE84D447E2F38DFC9F80DF7FF77D125A +:106780005C68D85797B7E5D6431CED9297DF03D3E3 +:10679000B496803C5FB8F531C3EF7AC4DEE354CBE6 +:1067A000F372E45CBADF74FBFA7012B3730E27095C +:1067B000BDF794437C6B3821FC9E29AAE2A5F37BAC +:1067C00025A9FE91CFEF2D2F2041D44F4792762C53 +:1067D0000B492796C5A4074B0C33E782ABD487E55A +:1067E0009FCBBAC6C0E2975B03CFDA44CC3B7813A9 +:1067F000F6C9F9A181E7E1DED9758E95D7C3FC8F83 +:106800002479F83CC286DF5721FADFBF50401F9C35 +:10681000E1ED4F1F241EE95C6FDE4B0EDE5BFB9B40 +:1068200024C443A2DF41BB3FE6DE1B762E5C83C35C +:106830000AB84987F6FF65EB6ABCC76FE95E17EADD +:10684000C9C35BEBF0F7AF9692CE7438273C9CDF60 +:1068500023425AD8FD2DDAFD20235A2C86FB4B56B5 +:10686000C4FCFECE32FE7B59CB627F8F8A9FC3DD94 +:10687000040FE2E463C49EE33D9B14FF7715496176 +:10688000FCDF3F893DC7BBB75DC4FCA8D59077A5A9 +:10689000B32F46ECACB218E94BF94D9E5957177C13 +:1068A000CC1FE1B2FB77097DBF5394CCF4807D828D +:1068B00010371FEF760FB7B7491D994EC7F9BFD4F0 +:1068C000AD220900800000001F8B080000000000BE +:1068D000000BDD7D0B7894C5D5F0BCBBEF5EB349F2 +:1068E0007693CD6673DF4080201737185244AC6F23 +:1068F00042C4886817A48ADAE2060402E406A58A7C +:106900002D2D1B122120D6F83522D0842E7829581F +:10691000F5DBB4A848835D3022DEFA87D6B654ADE5 +:10692000DF827C8A88B06A4BEDC5FA9F7366267B4E +:1069300021116CFDBFEF79FEF4B12FF3CEBC3367AC +:10694000CE9CDB9C7366B6B55EB56F608CB506AD4C +:106950009ADE094FBB2EA8143396975A655E0265DE +:10696000E6D0D94778189BA69F72C853CE98B141FC +:10697000BDC404E5BE1D4BFA0D506E75ABCCA440F2 +:106980007B878E3128B31C5D700494DBEC3F73CCA5 +:106990001FCBD8481BBC877E0AEC2CE8817EF76FA2 +:1069A000BF5D87E5D666C6B2711CC5DFEFA1EF54A7 +:1069B000F630C33F6D46998BB122FC278CA3B28D74 +:1069C0001FEAD318AB6E386E89D8E07DA476061B1B +:1069D000CFD86576F87822D4BF79F57B58DEB6F249 +:1069E00098C30FE3BDB87DEDAFA7417F8620C005FA +:1069F0005D947EDAFAFA34182FBADDC87640F9339E +:106A0000FCBB82B1C255EAB1889906649FC17FF987 +:106A10002B12CB4606E552512E4638E2EAA13C0E37 +:106A2000C7CFC2D21C167661BD80D7A9310670329D +:106A3000BBCDF9CE18C62EB52BECB361B1F2C5585B +:106A40000694EC3474545901CE9D7F54BC2D507D76 +:106A500060FBC2229CDFD967FC457698C74A73DA8F +:106A600078961E8377E099EE11E3062C3A373EC301 +:106A700016E68EB51FFD50B3C90FFDB4AD66DEE35B +:106A800023183307FBAC63701D0F19BC50647729C2 +:106A90006C4E08EA551BD34230CE388742FD253F65 +:106AA000EF5AED79B9C4101BF7AE4FAF9F83EB1BC4 +:106AB0004DB56A3B9473E192DFA9764F00D7D7902A +:106AC000CFBC29309EC1D99F6B87EFC63C6DF4DAED +:106AD0000065D3FE736C7A04C61DF3DC4DCC93CAFB +:106AE000F185F0AA2B8DDEE3998C99563ABDEA2503 +:106AF000D8CE46F4F891CD183421FE57DEDD81F56D +:106B0000ADDB2BDC9EB1B171D7AEB67B5580B36BDC +:106B1000B5D9ABC204D78AF925C357E0D0F982F0C2 +:106B20009D51C7FC585F0FEB80F4536F4FA1E752A4 +:106B30003B87BF5B0DCC42F8BB817E5A905E57709D +:106B4000FA5D9E630E229D2F7F7178361B3BC8BA7B +:106B500088E723ABDDDE1280A36BC53C37834F2B68 +:106B600097F559AE82F92F4F35DB911EF569231F3A +:106B70009882F4FE9281215FB5A65678E6C7F5A704 +:106B80004F9BE4467CE875815C6667ACC57E4B8DA7 +:106B90009A83F412D8CABC8CADEFA8AA512F857283 +:106BA0006A205781FAFB3AA6F1FAACC05605EAB75B +:106BB000744CE7F505815C1D94B7775CC7CB230265 +:106BC0005BB1BCAB63162F8F03187219EBE9B8A148 +:106BD0002600E3B71ABC73BC30EE1300FF58803FA9 +:106BE000249E3F177891F53FC3F780EFDDE2995C73 +:106BF000FF94F86ECF10F57B457DEF10FD3F2BBE67 +:106C00000B0FF1FD01F15DDF10DF1F14DF1D1AA274 +:106C1000FE2551FFCA10FDFF4A7CD73FC4F7BF16BF +:106C2000DFBD36C4F7BF13DF1D19A2FE7551FF6625 +:106C300052FF6F89F611F13E3FB5FDF500D05D3E84 +:106C4000C82DFC2B4D6DCF40BAEB6A2E27FA6F9DF5 +:106C500008743E3646EFF90AF361B9D4A1527FA514 +:106C6000288FE1F9AAE8BF7259C9BD4877CB5FD533 +:106C70007B910E5B15EF113FF41F58A6F3A2DC5D6C +:106C8000FEA29ED3F93235C8E2F8FBD524F8B70945 +:106C9000F8DA04BCCFDB87517DD14AB77786949769 +:106CA000C8F7F6C4B219F84983F1DB9C5CBF942E97 +:106CB000AB328F42FD01FA05E5E65D3663D804E3A9 +:106CC000DF6557A9BECD5965C7FA805D25FD73976D +:106CD000B3CA3C1FE5AA0D845D058C67E77DB7D973 +:106CE000D59A20CA0F4735D54FFBCF197694A36D9F +:106CF0002CEAA8C4F9AD02BD02DFEF6FAEA2F745E2 +:106D00008E3F39503EBF9CC1F9BF2FF5A0A518DAC0 +:106D1000A9DFD691BE186957498F0D5BA50B7AA0E4 +:106D2000499F7DB90ECB0FB6717D057FA965307E79 +:106D3000091F9EEDBCBDE2A552D467F7A85E8F8700 +:106D4000BF53E3F44109EA2BD05F398E0C2E1F8527 +:106D5000BEEA2E671AF61B709B830F43BF252A736A +:106D60006766C4F09EE3D07339AF9FE145BD36BC82 +:106D700023513F15B7C7E92786FA32513F25EBABC0 +:106D80008266908F71DF9BDCF684B2DE914AFA094D +:106D9000648CF733187A79CFF2ABAC2C26AF93F52D +:106DA00051ABD00F52EEB67E7A49827E907239593D +:106DB0003F9C5FBEFEE6EA51448720AD3CE797B3B7 +:106DC000AF221DC03A1AFC0AE90FA6FADDBED4F3C1 +:106DD000E3CB60F0D9EDB6F3E3CD90F51AD9150603 +:106DE000BF4AFD9FA357CE8357D9CE687EB0FB38EC +:106DF000E8B53FBD7947290396590BB8A1F5CFD225 +:106E0000051F8679E7AFFC6937F69F77D0DA867879 +:106E100036BAE777B7E17C3A1E600CE8496FE6F4D2 +:106E200064CCA9B2E3F7AA4E73670C87F2AEDFDD3C +:106E3000AC003DE9339BBD0CD6EDD0132F655C83D0 +:106E4000F87BD5407C6ED2F9EC6C388143F4B6AE59 +:106E5000C0BA7D03D1B1DF8C78CADF69263DC0029C +:106E6000DBD76B40D4ADB01C6C32D67F7DBD06F84D +:106E7000D9A90C94AFC6722868E4ED4144E3FFF54C +:106E8000E81451CF341558F3714511F5FF59533DAE +:106E900005DAABF6312AE89DFAFB7ED66EB81CEB1C +:106EA00075F27B8D4D82F9E278A2ACC2FAFCB44F48 +:106EB000D407C2EDD5C0443D46393E0B60FB1E9D54 +:106EC0008E9703CFB463FF8F5789EF030FAED7F2CE +:106ED000099E6BF40EC6BEE3E86BB75D1A83F7EE4E +:106EE0008C97DA5B607E1F782269B09CAC61FB7185 +:106EF00017EAE775739A7D8837247C1FE8C414BDB0 +:106F000087E86960DD76CF0CE441ED99837F4B1B08 +:106F10000B554DFAC8C114C05FC39E66B301BE379E +:106F2000197C81BCE2D8770DBB6BC99E69EA2DA3A1 +:106F3000E720DF1D5287FD4BDF998D1730DE07E11B +:106F40005F373E06550DFAE6769B9EDA33BEFE832A +:106F5000CF4F7EFFC163BFBE01C73BED89B8A643DB +:106F6000EB7561C0CB20DFC9F68D7B66D2F3D729E4 +:106F7000DA7A07F0752DC82E92576AB317DB87CCE3 +:106F80001D762F20DA62E8F0A1DE00D40775936247 +:106F9000CF8D8E126A9FFC3E99BF4266963903E5FB +:106FA00078BD4A7A2A640EA48C87F246D887B4004A +:106FB000486BCA7E37612C969FB431DC97B4D6F704 +:106FC000B9C7225F798D0CEDDD8D97867290CFDB8E +:106FD0001A8C731E027842E1E5EE0571F6D6DD19D2 +:106FE000069AD7FAE781EF2E86A721E450F0FB112D +:106FF000A03780942D0EBF19F739969C0C1628C621 +:1070000076B68DC89FEB0DFE9A2A6C97A323FD627E +:107010001931BBA60AE07067E9143DC1517D6421B6 +:10702000EA37BB1135283B9231EF6788A79FAADE6C +:1070300066E4C39FDA6CF60054808CD450FEA9231A +:107040009C412C9BF4AC19F5785E19E8F3383BF6BB +:1070500088909F471C468277A32534B312FAB12E3D +:10706000D7D90330DEFA864DFDD3609C1F353C75C1 +:10707000B805DE6F70A90CE1B039D5B011F48FE11D +:107080005A8011E07EBCC56747F91ACD52D90EA8C7 +:10709000B7961899274E5ED9C642394E4E663A5574 +:1070A000CD02DF9FCDF0BFE880712F79F535337EBB +:1070B000EF9EA8D321DB8454BECE69E589FDD8A715 +:1070C00024F693519D58EF9C9158EF9A9D58EFFEEE +:1070D000466239F7B6C4F22C496F20736CA08FADAD +:1070E000BC8A59231FAE467D0BF8F903E2DF3A5202 +:1070F000E745FC581A1E3AB110EAF3509EE07E684C +:107100003C23BD7BA0F03B1EB40B4C19CD1EC7D851 +:1071100073F1915760BE06D7CB56A2DA19B4B7BD4A +:10712000F9DEA7D8BF8DC5B52B46FC6827113FF8FF +:10713000E7067852F11F1EC477F37F7D0FF5E261F9 +:10714000BD17F19DD7A0D2F8F7CCF604F5DC9E7000 +:10715000A33D9326DAA79937F6EB419EA7BDB97EEA +:1071600019EE7B93F1EA62CD0AF225D007DF6FD7E3 +:1071700032D21FEB74AC0EE906F708D81F994720EE +:107180002FAECD34129E1461EFA0E6C07A97B09F67 +:107190008C39B759908FEF3AC8E9FF2E23EF67A0DB +:1071A0003F0F0D8A24CF504EA666E812FAD9641715 +:1071B0006D4439CBC1CB3D7D19D7205F6E9A9D318F +:1071C00001E9C484FB2EE82F3DDFAC8D86F9595EC2 +:1071D000340614E8345D657D0658CB1E2BBBD507FD +:1071E000706C39640DE8E1BD65C17FD8D14E1B9F3D +:1071F000C1E9BE678DF7372807A2B52AE1D192D53C +:10720000619F3096CF2100F02139A05EAC1CD1499E +:10721000769EA5B283F4BBA5ACA303F1B465868EBC +:10722000EC8D8CDB7444CF9682D0E112F4132CD019 +:10723000D9B1BF0C50FC46E8E487F91D3E1FF60BA0 +:1072400038D7557052C17E6986304EA6C0ABD3B9CF +:10725000FB0E05FAC9C4FEC6F3F6882787C053455E +:107260008687E0768A7E334BA0FD78DE4F5B45ACA7 +:107270001FB98E5B6A5810E193E3CA7E06FA679ADB +:107280008272D5F032E00DD64929341370772D6122 +:10729000B43FEE59E36BDE4E7C6D233F47AE33BF08 +:1072A0000AE928F7D0D659BAF1F89D95C6312C6075 +:1072B00041A4E35C9599BF9A81F68D8FF098CCAF8D +:1072C000397D1DD7A39D2AD725997F7354D6AECF7C +:1072D00038978F739CCEAA91E307E1E7247EC939E2 +:1072E00014FD36127D325F6F4B395D867861F1EDAA +:1072F000F5E72FEBF5A1C3E8E761D9A02700F585F5 +:1073000049E331F64F139615A6F37C361CE5BE43D0 +:10731000D031E82B60D69E09F6A936E4D3658CE817 +:10732000ABEAE98D37BF0CFD9D1D61B4A35E293822 +:10733000D4D18FFA91EDF18FC275E852FD3F4E81A5 +:10734000FAAE23D90CE5F67A0BDF8FA982CE93F53E +:10735000CBDD197C3FE6413DE7FED79FD23E0C9541 +:10736000B8C6D881F7EEFE8F2B5F3467FD0FDA5970 +:10737000ECD1F51A94F3FBFA5B6C38FE7DCFB79B2A +:1073800001BF965779FB0D500EA888BF7AF2671D92 +:1073900028584878525F3731A4D3717A2D8865F622 +:1073A0008685A1FCDDF9E437EA3C287F5CD33D28E3 +:1073B00087BA04BF6F15CFE4F9AB46CD8FF644F220 +:1073C000FBCE01B9E43B510BEB38EE4123DB0095DA +:1073D000A5BA79EDB8BF8BAE07F90BB5F3F49EC62D +:1073E000BBE3F6B7EDD6CA4733E0BBEED566E6079A +:1073F0008339FF1385F981390B9CBFAE44F953C81B +:10740000C20AEAD9C266307891AE5658993F8EDEEC +:10741000F33F51A97DBB557B34238BBF37831C3091 +:10742000F07FB29F66F858AD93CB28B45F0C8F59AC +:107430008FA2DC60CE6A6D603F320CE917F43E8C9F +:10744000F7B498B70170689800FFD97461D3F873E6 +:10745000DBF70A79AE9A6D619497AAED9523245FC4 +:10746000ECEAA9F876B8EF262156CFC82F8B78A181 +:10747000F2B7EC54CE03F96B9A40767F00F7DF81C8 +:1074800034BE1F619AE671BA905F182139DFCCDAF9 +:10749000CDD08EA81DF82D87F55BC86EEE631EE477 +:1074A00007F4B0BD9342228B215EBB18AB89E70382 +:1074B000F9947E0975A59EF653639EB3103C8666CB +:1074C00016B4A03D84B001BED5152CA816C7FC8209 +:1074D000A50E0F7D6764CD64CF3EFEE95BB928A79A +:1074E000AD07C11EBB18D7594772CA6A4DE43FC6E3 +:1074F0005A084F27057D74AFB6D33A0FECDFFCAFC7 +:1075000089758EB4A0BE285C9191B0BEB25DFE2795 +:1075100079CC7F497CBF41EA2FBFA44F41BF4CFECD +:10752000278554DFBDDA739EFE870DD17F0ED1D142 +:10753000D0FDE7537D77F835C775808AAE689FC365 +:10754000E789D9D7C978CE5F9128972FDE935896CF +:1075500078B11834E74CC0B9E5DB3AEF76E8EF2BA9 +:107560004712DBD514FF96F6BFB1F661E7F5D81EDA +:10757000F6E7DBE1ED652712DBFB2A9F77201FC7CB +:10758000DA73F8AEF824B15DF2FA24C30B70657DAE +:107590003D0EAEA9665342FD9CDA73E0CABA310EC5 +:1075A000AEABDC89EDFD2D83C3754DA9E973E19286 +:1075B000EDBE36E9C2DA25CFE3FA1AD31078E7ED4B +:1075C0006F9C7361FDDE52F7F9ED6E5D993C4E8064 +:1075D000F8A551A75D9E09CF79F80AED459B95EC7A +:1075E000DE647A7954E8A76A343CA0BF8BD2B4EA4F +:1075F0004C785649BE137E86434F5C948D723D4F46 +:10760000F8D199F02BF4D4BBC9AF70B3680FFAA4CA +:107610000DE545CF4EF82E8DC3156F3F65D6F37D32 +:10762000859D45899FA5BD94C1EC0ADF8F737B675B +:10763000A87192FB5F97C1E19EBF722A7B1BF8F095 +:1076400029A3BD52C5FDD93685EC81F9D59A3E15E1 +:10765000E86372BB427EA5F977FEE687E88FB9F44E +:10766000B8674F04DECF0F3ABC386C633FD3304E5F +:1076700090AD5F56F63D78DE7F00EC1F515E86F4DC +:1076800066D33CB8DFA84588A09F5386E6323BCA44 +:10769000CD6FDA34949BB5B3B53FD07CFF0156096A +:1076A000B45BC0A7CE9EEE9C69C47847ED373C938F +:1076B000D0EEA90D59347A9A996A8579D4823D869B +:1076C000CF6C23532DF8B432333E2BD670FB2B6D89 +:1076D00092CF580BE3D7F6FEE4CFF8DD2235BC9FFE +:1076E000DB93419A776DEF8B7F457B6D81E633A20B +:1076F000BC18B3D3C86D52410FE34289659407F1BA +:10770000E5B27062F9924389E5F771E1607D260B7D +:107710003FD6817D2692DB4BDFB792FDB917141E51 +:10772000EE93038F9B487F4C5D6AA3F57AFFA475A7 +:107730003BFAF5F6BF6EA5F64B7E6AE1ED75A12723 +:10774000B01C782285F6D94B3343151900F72F3E2C +:10775000D513BE715A06ECFF89D1DB3760FD25A138 +:107760000A8C8B3D751163FD58AF06C7E33C9FFA49 +:1077700027F75B477799823BA0DFF79FF9C913DFB3 +:10778000C57177E56528B03E97A15E8076931F347A +:107790005B71BF31F9FDC786A3DC58BAD39430BF03 +:1077A0009D998A88AB79D290EE86F23B1E5BFF13DF +:1077B000FABEF4C411A2BBBD86800EE37881F59CAD +:1077C000CEF65AB89F74AFA53088EBF47426D73B39 +:1077D00097E976FCA811EDCB57B91D3254FFA5EE01 +:1077E000F9DDD583F81907EA61DC6258E733EF5910 +:1077F0006FD5008E519B13D7697430B1FC4B31AFFC +:10780000792CEE7D31C2336CAD1BE1D9CE089ED20E +:10781000136FDE5C8CF6B889DB21C9E31ECAE4F283 +:10782000E1D147A11F2E67F4DC0E078C015F2F15F5 +:10783000FCF00B85DBC1F0B7220FE87F291A10C3DB +:1078400062EF9726C121FBFFAEC0D3C7E6B41DA8E7 +:10785000CF9D464EF727571FFA21C63165BB775695 +:107860006B5A759C5F79E1E665077360FDEB7BB24F +:10787000689F29DFD7EF7ACE750BBC3FB553F5A2D1 +:10788000E95B7FD3233F988CED76E9430827D6A3A5 +:107890003FF354E8F9346CB7B0CB3101FD25F2FB6E +:1078A000459BAFD4AAE3E4E917E527C9FFF5627F5A +:1078B000FCF4A4FE697980EFA59B152F365B1AFABC +:1078C000FAF5D7A2ADD3A5F7627CA342653EFD04CD +:1078D000DABACFC6677DCF930773A1BE69DFC40A4A +:1078E0009CD7069DEF9A71C82FDB0CE4074B5E1FF7 +:1078F000E6E4EB0CDF8775F0FD861B6C75181781CD +:107900007EFBB07CA074871EFDF8692740BEF1F7AE +:10791000477420334FF4DE351EF62C40C7B676E4AC +:107920008FBDE8B8C0711ED7939E60613E8FC9C2FB +:10793000FFBCF48F9D46159E274EAC49ABE4FC4737 +:10794000EB8442DD09F3AB7B701CF1EBA2CD89FC2B +:1079500025DB4978170713EB93E9C2E394FE0A5637 +:107960001A4F5FC9ED3267048CC88FF52B419EC753 +:10797000F14DFDF10E23DA5DC9E3A005C9E4BAEAD1 +:10798000892E612C9CAF85CF174C5E33CCF724FE3B +:107990008BFBCD15DCD72F51688A6CE945ACDA0337 +:1079A000F85C3A8BD5E053CAC3539342E3B1FD5E12 +:1079B00043E4911F911C4C257970CA1E4E43BF525F +:1079C000AEF0EB9DF284D350CE9D11713BACC7F26B +:1079D000925ED007C0D7EF7F6024BDD0127A2E0D03 +:1079E000D7EBD413169D0ED6E5FD9ECC2AF4079D49 +:1079F0000ABD9C86F33A19CAAC42BFDE50722259C6 +:107A0000BE497BE028FEF352C6AE746A9A13E51DA8 +:107A100006197240DF643697350FC2F7F23BA7B103 +:107A2000B90CF334A2DFB47951CE5EEBF4D0FB5A3B +:107A300085F7877F18DFFBE850E60E5CFF43FB47C6 +:107A4000A6A39DF011F3A4A3DC9EEBF2F99CB09EDB +:107A5000EEAA7E8AEBBBA7336F2B7CF3B6DE7BBB33 +:107A60001DF0761B03BD85CF72BF91FC2D6D5904AF +:107A7000D77C958555A0D3F9A857C75399EC98F9A9 +:107A80005D4AB015E0B86D63E23C17769A62EB0B85 +:107A9000FF2D6620109181BAE2DA41FF8B517F02FF +:107AA000FE9698593805FA5DF250E2774B5998E006 +:107AB000A97FEC33D36078FCB3C0E35C97B618F1D0 +:107AC000A8CC32135CDF7A5C21FDE6147EC6E8FDAB +:107AD000E9418C872D15FA7A81693FC1D37467AD6E +:107AE000761BD0CD9995F3B5DB3279CA08EDCB364C +:107AF0002B44874BAB59B800E05BDAAB84C7A13DA0 +:107B0000F11A5F27D92FDBC6DBDD2CEC9D05801732 +:107B1000B41F263FA60452417E2E30C3560EE58880 +:107B2000981FD6A743B98E75D0BC1A5884E0588BDD +:107B3000EBC8FD7904FF9F5FE3EB37B96EBB1E8195 +:107B40003AB4BF82E27F1F332FAD23D825CC927188 +:107B50002E9D20DEB5383CD5752596D94371E5615B +:107B6000885728C7E1BB71F767266D103CDF3FA03F +:107B70004F82A3678E63E7D8BD6F8975B8FFEB0BA3 +:107B800073500EDC8BF66BAEE86012CA4D26FD1A00 +:107B90006133F46FBD8425F839C0BEA2F283CE995B +:107BA000D337E733B6C9E0A778C17CBDEF2086B6EE +:107BB000FEE9F2FF04D777BE4E2B54491E682369B5 +:107BC000BFBB92AFC703139A47370FB2CF95F06F81 +:107BD0005242611DCA8367B87D905A1E35F8E3F89A +:107BE0006CBF9073E9072207F3905E9E54C82FBFC5 +:107BF00045616D0AE0D90DCB82FA608B72F420EA00 +:107C00008F2D577B582BD497EF9EB9EC79DA2B5BED +:107C100029AFA76177A5BEC146F3E7F66A4AF376B6 +:107C20001DD467DF5A3A01F904E67DEB2C787F50CA +:107C3000F06D8E8DD3837B4DA07839FA650FF89661 +:107C40003D8FFC3DCE4AFEAF6C33FA7AE9D98E7691 +:107C5000A89BB528D8EEFE34DE7F964E7FEB4C2CE9 +:107C60004FE0E58C558AB68388F83EEA3FDBC46A6C +:107C7000107E7C8FF63474A7F5507D90E69B3DB561 +:107C8000B90CFBCB1ECE9F4E63381FFB796560BDE0 +:107C9000FD3A94BB2B84FE5CB1BD2A1BE5E42BA707 +:107CA000CC2ACAC357DCD20E0CDBD00E6425A5BC8F +:107CB000BDD0532BCAA66623FD3A0B13DB9D31685A +:107CC000E997A0BC3FACA7B8CD9F6C5ABA03DA5D68 +:107CD00066E4F3485EC7A8D0AB4D9F282C18B7FFC9 +:107CE0006F9A7396ECECA64FD484F7A7569B593045 +:107CF0006EFF5F5F77601AB66B60FD6B91AE1A42E4 +:107D0000292C1847E79759071F57D277D3277A1698 +:107D100018745C63E2FB4F32592073B076AEC4F73F +:107D2000308F84F29EBF0CCC03DFB3499134F487CB +:107D3000CE40BD06E533415DC000F2E41503D757E0 +:107D4000A7ED91047D76DA13E1FA0CFD3D366E6FF6 +:107D5000CFC47556A369B35263E3C87AFC3E236E61 +:107D6000BEA7E7185998D6274A7020FE02A318DB51 +:107D7000DAFBA111F35CEA7BF713FE24DDC4E331E7 +:107D8000101F3F6AED0FEB80F7C7DCDFB961EC68CD +:107D900058B20382CF039B36605CD8A5D725F07D0F +:107DA0004AF9801C20B1733F46B3C81FFAC086EA67 +:107DB000FCB8B2683FF07D60F374AC2F1FCBBF9F5F +:107DC00078FF9697D65032480797A36AB4D0971A8F +:107DD000573627956D501E1757B627D53B93EADDCA +:107DE00049E57CDEFE546AB850EF05E0EFEF9E8E69 +:107DF000F95CA772C27331FF6BA33E38BD1ACA0D7E +:107E0000E55CCF36F62A5EF2E109FC357AB9FD670A +:107E1000F3468C98779652DE7F10E544FD1EC5AE82 +:107E2000003FD8423D612AE3779EB8EF420A7D5772 +:107E30001F3A4ADF0DD97FA98EF87D43E931DE2E46 +:107E4000F42EE9F3756DCB28CE2EE3C87AE6D7F28F +:107E500094581C59CACBD339DA73242FF72976E406 +:107E6000CF013AC57EE3FC37B2FD1BE37A7F8BE698 +:107E700042CA8A0F5BD02EFD63C3BB13D14E7B4336 +:107E8000E8854D4A70348EBB95F947A3DEFB66C387 +:107E900088FD3A68F79621D28DB1B2D5F73F49F8FF +:107EA0007B2B355280F9742D59E1E9984FF75656DE +:107EB000A41BF1F9FBACFDBCBE205280F97377DD49 +:107EC000FF3EAF1F11E9C6F2E359BFE7F5E3220514 +:107ED0007A3B6E758E4CAF86FA87ED83F3F5ED59DC +:107EE0005C9E48F8869768CBB2D00EABE7FAA41B2D +:107EF000F63666909B73979C7CFC61C0C3DCEFA454 +:107F0000903C7BF8D4F5D3B99D1DF0A915E887E521 +:107F10007FA4EF486EABB4FFCD411D97115B8FD4AA +:107F2000C27E0FE9838B9A7BD06EC89E3B96F4C1CC +:107F3000579DDA111C573EBF9F074F687F24CBCE59 +:107F4000E5B35E4771E9ECEFA6929D75AF85CF076B +:107F5000F886D6D726D6E3EE2CAEBFEECEE2FBB740 +:107F600045CE2BA9BF9B855DDCB93EB8CB02F87F1F +:107F70005DE6BBDCC7EDEC5BB6835C0139DEE9D0C6 +:107F800072509EDC22F2D7A4FCC0F71971FB8BCE95 +:107F90003228DB62FBC8CE995A8ED5894F970EE303 +:107FA0002F521E7516F3EFA45ECA6EE5E366DF3B43 +:107FB0007A07CE2345E57EA4057346EE6821FD3E93 +:107FC0008BE6CD342D4781FE8E2F1EA643FF925C9B +:107FD0009FEA12ED61ACBF59F8E7E53AC9F53C22DA +:107FE000E63D5F0FF601CCF3772E3FCD1FEC85F118 +:107FF000C28F45F6C2115CE3AC187E991A9988EFDE +:10800000FF3FC2D34B5F069E1A5682BCD05D80BC38 +:1080100010F8DBA4840DD95C5ED0BE18DFA3DE7936 +:10802000CCE97F0BFB97E3CFFD6E03D98712AE94AB +:108030003B9EAEB9919DCB67C9F6DB09B15ED2CE4E +:10804000F44A7FA418E7ADD7CD147F78CB1822B9B6 +:10805000F916EC6B5A50BE88F879C57796BE82FB4C +:108060003AD9EF752E9ED76791EBAEF87A16166364 +:108070003E090B98711E338DB4EE52EF763A787E3E +:1080800048E79D79941F72864518F9352731928FFC +:108090004007541FBDC945FC0FED03166CBFF82205 +:1080A0006A0F741120F9709395F6219D186FC6FA26 +:1080B0009B4A8398CF82FB5FA2B7C53A1A77107AA2 +:1080C000E17EE3513C5F42D28DAB95FB6798AA8D70 +:1080D0009F19A7E72F72713F514A79E4C9DFA37D49 +:1080E000BAD142F629EA588AED7464533FB0FE993A +:1080F0002EBEBF273ABBED07A9222FCD5B81785D4D +:1081000097CAE9B2CBC2E34E5D600F935C14F42BC7 +:10811000F3E2FCC2DE8BD4E9D2D05E28760DF80DF6 +:1081200034DCC793DF1BEAE74594A3B8FF9A17D066 +:10813000874DB89F6ABF528BC4ED47F00FE376B707 +:108140000AB9CA3633F203DE8ADFA561FFD6348C62 +:1081500053DE8ADFA3DF75D59509F1B84B5C9CBF70 +:10816000257CC972FF120957C7035AFC38B2FFE4D5 +:10817000FE605F59EECA223C87D3717D5BF4B47E0A +:10818000C970463673FF75647311D19DEC6F283842 +:10819000FF4B1FFDB6027A70E154BEDF96FB9805D7 +:1081A000623FCC5625EED3D05F3250D69F5B4EDE79 +:1081B000F7619C3DB13DB75B52C6468DC4B71E25E5 +:1081C000017E89AFA1F070F317C49BD47B0F588058 +:1081D0000F32703BAD10FD6EBE3385F498D3181C82 +:1081E0008D74B5C0E5A1765B31DF85F42ADFFF7EB3 +:1081F000FC8AF45F24EE7B9BACD16D88AF262B23E9 +:108200007E3ABD2F95F8879544E662BED899BD2683 +:1082100086F4DBA84446A2DC3AAD68B5D4AE25C5E9 +:10822000837C24FD036F3FC5FD034D884980AF2942 +:10823000F077CA576ADA93B81F3E0DFFD501DD9F6C +:10824000D6452AB03F290FC08ED6C83EAAE3719CFE +:10825000461D0BE03EEB32DDBCC59CCF73D90E7AD8 +:108260007F74E4F2383B1DDAF529199C7C906FEAA3 +:10827000051E1B75C7A85D3DE61D213E71BF85FE2D +:108280002EAC8CF3CF366E7C9FF29E1A7727AE779A +:108290007D8C1E94CF14FC2E8E3E889F03421E3090 +:1082A000EEB7A8E671E854514EA9E9A73CA826E12B +:1082B000C7C83A1099867225B53CC4E6C1B3E90433 +:1082C000B73726F76E7F0EF7C78E9AFE02648326B5 +:1082D000E1EF93EB2DE1BCB4F73EF25B483B256E3A +:1082E000DF397A5682FF600D7D87FB581C2F82AFE5 +:1082F00072900CB87EDB24F41BE84192B70B3A462F +:10830000911E443D85F249EE83515EA19CF8A7ABD6 +:10831000AA07F9755376D563AE2C3E1ED9F5B8A9D8 +:10832000BA74683F9DC48F6C87FBE1CFF3C3F5221D +:10833000DD66C5FCE3045139E64D6749BF1BC5E75F +:10834000962B9E6CA4DB77F47EF2AF2D6201F2F7E0 +:108350002C46BF163CEB05BF2F147EA285C23F847E +:108360007EDBF83822FA4FE3CB4B583F971B3B4D4F +:10837000B1FC1AF4E754B3702AF4D780FE267C8649 +:1083800012BF6B6451FAAE69CF67A6843865279F28 +:10839000F7AD62FD1DD5413DCA892D16EE6792F2FB +:1083A00063F22AEE8F4A9FA015DF8574FEA281FC3E +:1083B00014FF2DD66D40CFBBAA9E42BD62D5F3F30C +:1083C00068D1BB4C24378F833EEE11FE9159B80F14 +:1083D0005DCD34CC5F67AABD307E9F2A9F1BF65AC5 +:1083E000EA907EDE75E912E8EB472E9ECF437E23AE +:1083F00092CB29A477417C8C47FAAA1826F5221B38 +:108400008FFEAAA362DFDC7883CD8FFD45745CDE2E +:10841000FCC9C5F7017F72F17C4E591ED8E709FAF5 +:1084200091F13FF4DFC4FBCFFF3ED0FE3E9177CB0E +:1084300068BE9B168BFCEE013AD6915C4A19EB2381 +:10844000F97B99AE8AE452F43D9B07F152F37EFD2D +:10845000629CC74773AC748EEF36E1CF4DC976503E +:10846000BFD27F7BBEB858CD86D1242F65FB34DCCC +:10847000A0649DEB07DE2BE4D85EC6E10D9CB0F254 +:108480007C13950550AEED0D8D0E22BCB5C2FF805C +:10849000F60DCAD7E8937C1D99CAEDA1BDBDE38254 +:1084A00048EF470DFE2D0BD09FD36320FF1A538357 +:1084B000BB1EC17E9ECDF162FECF695D74DBAFA0B5 +:1084C000DDDE138FE661BC67AFF0BBD71BC323C9EA +:1084D0006E16F98EF569E191E807FA8558AF7A2BA7 +:1084E00094E17DAAC53F2A3B2B1617C3EFF0FDB1DF +:1084F00020B7CB8F314E07818D3CEE09F8CD5980E6 +:10850000F0AECFA6B81AAE0BAEC3DBFBC6D1BC36FD +:108510001944FB67146AAFCC2A9D4B7A61832913F7 +:10852000F17FC667A47CDDA67BB9DD385FE7D9B6ED +:108530001265E5B32934BF059D8729DED1F4834553 +:10854000740EB269C9AAEBD8E7C40150AFC4FBAF3F +:108550004FB36821ED87EB8685C200C7E9DED15EA7 +:108560001EC6E3E76A1A455EE87103D310EEE83EE3 +:108570004370B0F37E43F58FF3C5FD29EA37F273FC +:10858000C7C75B481F24C65FCE573E6D888CBC139F +:10859000C65F9BE9BF293BCE5E6C7A3687E4DDDBA4 +:1085A000F7FCA590EC8A0E1E2F386ED0E6229F387D +:1085B000AAC3C6797176D8B26C6E97CE3709FB1113 +:1085C000E4603CDFCBFA8AAA443E93CFE66C6E8728 +:1085D000A48AFC8073EB65FED9F526D49FDCB584B4 +:1085E000FD72795D24E26E934F44F7639E557DA83A +:1085F0008CE27A45ABC2C49780EF30DAFFC7B7A4EC +:10860000727902D3C47E164E6264BF2ED4F37C8787 +:108610008526B087B91EA7F6EF6CC9263C54ACE19D +:108620007660F44985E4A28C3FD632FEFDD36D47D7 +:10863000037A685FBB532903D1CA6ADB2A291F6208 +:10864000495731ADFF64217FE79BB4915B90DE9E7B +:10865000E6F12B188FECEE7ACCF99A4072C988FAC1 +:10866000B06EA7C2F0DCB09C7F72BC8F0513E32D07 +:1086700093435C7EA3DE6071F69AD443A82F589290 +:108680001D9948178104BDD78D789D1893FF84B13B +:10869000CFD183604F6F43FAA9A8E2FC17ED5108D0 +:1086A000CF0DAC99C787841E1A8047E8B177F45C78 +:1086B0006F2E34DD47CF9FE321B02CD48311AE075A +:1086C00041AFA15C1C8A2E7E3E045D487AD82DE81D +:1086D000A3FE040B5F0EE3D5AF62E186F1FC993A8D +:1086E0009EF432D7CF66AE9FF169BD003D9DAC9F31 +:1086F00093F571B21ECE36727D2BE920DE4F8FF6D8 +:10870000C8E455413DF7C3E6DB31CF4FAECB22A7DE +:10871000D6979715B3B79A8E98CD9E8BB1EC63C35D +:108720006CE85FAAF415A0FF5CE5E78D53004FDB12 +:1087300071FD847D7E79015F47B7C8E731A83E5659 +:1087400066C375EAA7FD74348B517EB6C46F772A71 +:108750007C3701BFE3FC38F0BD99B559E3BEAFDA11 +:108760006B21FD72F699543A57C6547F9103FA7300 +:10877000BD01763A944FEF4D25FD7E5AC87BA7F494 +:108780005BB0B5B41EEFE23A4F44AAABCA43FF2F29 +:1087900053A6E7313A6FCDEDC606C7507E7B515FD9 +:1087A000DC7F03A73313E9D9B38EC8ED58067828C8 +:1087B0005FF8BF04FD36ED9E5AF65D8CF3FB6C5EF0 +:1087C0008E557F19DA0D26FD8A1BCC7A3C77BF2A9D +:1087D0007A27CCA3A1C04679C8D5456FFEEE2628DE +:1087E000BFB7DB40E715173F7C7D7A183F5335F75D +:1087F00060FA7971D090700E6EE9CEC4724328B1E0 +:10880000DC9474EE7DE59BDB5FEA8BAB37BB539D5D +:10881000B4FE1EE6C53C6AA6FF46BA7F1079299FC2 +:108820007F591D7CA96F04E5A1A5BB797E8D11ED53 +:108830009A79480F837C77309BDB352653F309CC3C +:108840006737FDC244E7E3DFC8F6BBDDE85FD64526 +:108850000FE27A9A8A4E8D473D5855F40F8A8B9DC8 +:10886000FD1EF3227ECE5A2AC9BE39BBC5E2C1FD28 +:108870005967A18DE8A0F35925A870FB7DC6C40AED +:108880008C83D21C58D3E6ABDFE3872F98999FA740 +:1088900087DD8B1BE58C46FBA977665AED6BE0BB49 +:1088A000BACD5CDFD6B3FE349403DF748BF5D33FCF +:1088B0006634C33F8BDBB4D12D00EF529F95CEDDE4 +:1088C000A89FAA74DE7C1D761967FF97BBB93C6828 +:1088D00030478C9538FE3F56D4A06B4CFAB94C0605 +:1088E000BF86E7BB0C7BCAC279F06AD1CAE7689F32 +:1088F00033104FDEC7E5D6A23BF7D37B65560DCDCF +:10890000F71D982FE2E5B92D269AEF3B0536DA6779 +:10891000BED3CDF7BF8BECC6A099EC8D4F32F15C86 +:10892000EC3BDD063A8F7E2E3EAEA2F3A9EF76BD7C +:10893000407EB877191F37B05B4FF6CABBF6684563 +:1089400018F1E8694E437BB76EF3623ADFBAA85B71 +:10895000EF4379B6A8FBDBBFBA14FD47B36E2EC751 +:10896000295DE158E1F2D862F5D24E5533263D82B9 +:108970007C78C5A753FBAF407BA91BF8A498E7CF31 +:10898000A39DDED77D15D9A58B665A1D382F4FD7ED +:10899000C3D3507FBC3B3397CEE32E7A5C6178051E +:1089A000C322C74A17BE5FA4A8BEC1E8E9E36C3D75 +:1089B000E1B5B2C8E60DE377BFD5139D005FDD805A +:1089C000FAB3A1DB40766FDFACD77F779333C6571E +:1089D000CAACCDD74DC6F63F3150FB017BA7EB5A51 +:1089E000492F2C5C81FB2A8EB7643E3315AD1A8962 +:1089F0007025F3DBA235CD2379FCEA8BF11DEBE288 +:108A0000E773EF70F3FB23BE00DF7DFF8BF01DCB20 +:108A1000CF48D84F9D2BDF02D44EFAFFCD5EA63D46 +:108A20006CA378AFA680FCFD0906AC27E2939F3BC0 +:108A300052FFBA7CE7AB809F316E7F07F26F11D394 +:108A4000CA506F7AA2F62A3C536413F61CEB32C963 +:108A50007D00D9F79BB2D8231BE2FC0F0FBAF93E79 +:108A600009E4C016ECE7F41FFE7110D7A9B1F0D4E9 +:108A700078F4FB367DF2278A17DA7A79BCD9E68D4D +:108A8000523CDDE0F4111D4AF9DEE4E5FA27795E97 +:108A900027DD061EE77546A99F17723C54EE14F1B8 +:108AA00095AD2BADE44FDDEA0C5AB87F21C0503FA5 +:108AB000CD98A4E77132616F5D2BFC91E6F2E71867 +:108AC000C6C7D8149EDFF56AF9736A26947F35E924 +:108AD0004A2F9DCB2B7FB07D18CE7B8A41D40FA728 +:108AE0007B33FE8F5649F5CBDD7A0FF2F78C729E01 +:108AF000DFC8EAD2C86FF26AF9DBCEDBE2E0F73119 +:108B0000B3C70674330B98353E9FEEBA29168F2DE6 +:108B10008E7E3EEA506AB8DDEB499F3D8EFB4548AC +:108B20001F9727E263B9DB48E36ECAAEEC43BAB9DC +:108B3000E2AB7C3D4E3E6E0AA21C3C29CEB924E33A +:108B4000EF376EE1A7534727C4ED9DC65021EAC910 +:108B5000F795C4EF96B4EB296EBEB85D614118EF8E +:108B6000E4AEA70B519EBFF7F0D385F3E2E049FED8 +:108B70004E3EFFE816F42AFC82C97EDEA1FCBBB2A1 +:108B8000DD99CDCC6F1E1E6B7FA6EE6FE4DF9DD707 +:108B90002BFCC39A56E2C4FD90689FDC9F3997D3A3 +:108BA00087B24721BF87F46F1E3BF420465206D69A +:108BB000CFD25BAC8BCF4B94CFC962DDAEC7758390 +:108BC000A958DA7979A8F51A8A1F77083D24D7EDD4 +:108BD00058FBF074C4A3B1D1A6327EDEAC14EDF51F +:108BE0006E66F5223FFD45E4A73AADF0043BCD9813 +:108BF000EBB6A13C93E7FBEFB0A6EDC0E75F44FE08 +:108C0000AAD30A4FE8A720B794FAFB8BCE47FBBA4A +:108C10003BF41D740E3145F049360B2B0A8636960F +:108C20003EA550FE567B22BE5DAD5C8F446B8DA48D +:108C3000BF24DE2F9B773BED5F0759AFCD4847B987 +:108C400093F8BBEA9C62E1EF88501CC13289D9716C +:108C50007FDF7A6980E090EBD5C49B33A55721FB79 +:108C600019F3585232285E1A104F66CB6003F18315 +:108C700014B1DF6549F1826CB0BBB19D8413CA9415 +:108C80000F73AF23D43192C75BC92EC57EF1FDBCF3 +:108C9000B12AF9DBB19D71C2F9E96F804E457EE1E1 +:108CA0000CF9BECE3A687C62069EF3C17500FD8861 +:108CB0007621F31A12CEF974813D8DFB3419FFD55C +:108CC000EB42656EDA9FF447D07F62AC307B50DFB9 +:108CD000A6E843A5B87EC9F1606857CCF310F21D31 +:108CE000A867E4399EC695537D18A702FB2360C68A +:108CF000F59BC9D7AFF1CE4A7AAFCC2A6D41FA6A5B +:108D00005AC5E8BE81A9BD3D94EFD454C3EDB1A6C8 +:108D10003D478D0CE8779EF0E730E17F7689753D21 +:108D200026ECEF58BC2BB20DF3B73B17E7D3B9DDF8 +:108D3000E4BC922F1AEF3C930A08B9382E8E956E38 +:108D4000E67A46ACBFE46F19D74A1DEB2B464BFCC5 +:108D5000C507DE7BD99AF545F2469EBDE773F3461B +:108D6000D8F4EBB0DE8C56BEA84730408F0E9CCBBB +:108D7000B37828EE35508FF72998F72822EFE4ECE6 +:108D8000B5579650DEA8E8AF6F23E67FDF6B610929 +:108D9000E3C5C3A726F56F80FE6D1ED9FEF83557D3 +:108DA000AA14FF15F04FDD88E7FAEE3524F64724C4 +:108DB00028CF119A63E3F9BA7E70CFC6FC983E07BC +:108DC000FDBE3167624CAFAF7B7D46C7C51EE4AFC9 +:108DD0008F290F57EAE72627CF234996630FE470C0 +:108DE000790E76F13454B9EBE62CA3FB0706E2BF0B +:108DF000BDB51ADAC332FEDBB4CA47F9B8600FFC5E +:108E00002887EC8153EFEC6768779EA47D41D327D8 +:108E10002AF713815D81F7C9987B2BC91F8A69A640 +:108E200023E2D67F89D05368C3233F3475DDF8B081 +:108E30001EEA3FCED11EA27E0D83DF27B52F87DB32 +:108E4000F14DA5555B501EB08714BACF6943E94771 +:108E50006477343E73E5C4F87CF2C57BEEE7F9C86D +:108E60003B0D83CE7F5F0E8F0B373EF324F93B4FD4 +:108E700006F931983A35B81EEDD0BA3A1D5A5EACB3 +:108E80003C587B13D90373601E30AF0773387E9A4A +:108E9000765E1FC0FCF626F84F81575B7D0B695F3D +:108EA000B0758ED986719CA6D279CB88FEED560D11 +:108EB000E79F0C672CCE6CA573C81BF6186AD08E82 +:108EC000AA00BBE9E7006F41C6F41A2FC8A53C7D94 +:108ED0004FD9B76C18771F5C2FDF92C7ED8036C56E +:108EE00017F85A39F939597C1E4FD11E6E9FBD961D +:108EF000C3ED43F9FEB51C6E374E09F44F459A7B1E +:108F0000568DA4A09DDCC4B40F71FFCB7C360FF945 +:108F100077198FB33B577BC8BF6B7646EEBE98EC94 +:108F20002895E2CC727F71FA19EE17BB22D77F1415 +:108F3000D7B1421FF9E1D7106F77ABC24FCCE54CE8 +:108F4000E1F5B609E8C7B238233FACF150FE0DF9A0 +:108F500025D22F6FA37578D6C9EC889FA9815A5561 +:108F600089D333526E4C1D3887E324FF6915176B84 +:108F70006C04ACD63B6622D1B6CF326376C2A17FF9 +:108F8000CC56F1A5B41F74663FED73AAE7C0BE11BD +:108F9000E9726DF4A00EFDF5CE7EB21F1B420A8D64 +:108FA000D350FA33CA8F5B2AF2B006F2A1D408E597 +:108FB00087FD3D2745E8C7364E0FAC9FF6C5EC311F +:108FC0008E7FD09B943716B3E35BF8BD67A23FA3B7 +:108FD000883334083F0E208AEA8DB9C2AE137E8DE5 +:108FE000589E1B1F97A99E8A78BFC3A699A04908BF +:108FF0002E4F1AC2DB6EF5A5E7025CC7EA7484A2A5 +:1090000063ED2974BFD426A55F437F64A08CE7C5B8 +:1090100026D351891837FD40741AEA93E83343E5A3 +:10902000C5F23CD82D132FA27CF2F23D1F4E43FA1D +:1090300060358CF8B171CF85E5C58E16EBF1A5E7EB +:10904000C57A156D073C2FC97524E6C57A39DE65EA +:109050007C32391FF6744E58E5796B916D0FE3FE43 +:109060007B8F89F23D66EC79E108FA276798598889 +:10907000E2B54976C061E7F55310DF673E7867DBFC +:109080005D0CF3A29FF2F27392897A7D28BB9E62F7 +:109090001671FBBFEBE4FA7F4976BD94BB4D629F2E +:1090A000F4BE12FDC1489CDF3EBD7DB0732DB7E418 +:1090B000CA38D710F91CBD83E773C8735F3591E2D6 +:1090C00084F8D382017AFE62F1AC3AD48113CF8D59 +:1090D00067A9223F4B55B808600E9EBF23E3596A2B +:1090E000CF688A539962F1AC301B249EA58AF8D0D0 +:1090F0003A83564BFE967D260FDF0FFB480EB5F5E3 +:109100006479514E352D39F9041ECD571DD3DCA895 +:10911000FFDB04FEEB2F3C9ED5923BF1DC78D6764C +:10912000617FBD5DAA0B1B01AFDB1997A3815E199F +:10913000D7D2D1FE347A4F01C1ADCC3213DC6F3FB0 +:109140006BDA817EA6F9325EF52CF793CD1771A903 +:10915000B7678D243FD250789EDF9EE8F7FF21E26B +:10916000398BFC78E46FBFFD3F66929F7D21FAE961 +:1091700087C7CE2F30E1AFF3B4F3F3ED9E9D0ADD48 +:109180002F8A64A223DBD24EF78C2E0571B81545C9 +:109190006800A8E62BF05AD12968D778DAA00CC667 +:1091A000BBBA5E0DB8A1DDF62329E41F5CE7F488A5 +:1091B000FC331E3F0E6C54822378BF74AF58A04D11 +:1091C000A7613F3FCFE57EA59773B95FC293741F38 +:1091D000419B41C481C5782D0CD61D9E3A853FD751 +:1091E000897BEB92F121FB6B33349BD14F172DE040 +:1091F000F7939C356A73C87F9C3192EE216A4B6D60 +:109200006EAFE1F5C4B3672D511FD55FAE72C39247 +:10921000793210DE5DB922EF2E09CF0B3A12CBC99D +:10922000F19BE47353F3997F54CEF073CF15ED4265 +:10923000B909FD9FDD502CD6C54BF1903683E7D799 +:10924000C51407E5F70CB5E473BCE90AF87398A3F5 +:109250009AEE8B037EE1F618E3F00FBBDCA920BF8A +:10926000B43938DDFEBB7027C3FB9BDC91445F6DD6 +:109270000ECEAF6DEB9520C71787FB42FD1D1F4A31 +:10928000B9F425C9C5B715EF23E162FA8EE443E0CE +:109290001E03F1DD5E0B3F0F29E51525E8E03E5288 +:1092A000EC5BFF2EF4D6FC136BE9BEA0AD75C3D208 +:1092B00030EE39F57A1BCDA3F1597EDEB66155A4A7 +:1092C00010E9BAB12A32B27910BCE200AA94AFD048 +:1092D0006E9E93F17B67DA13E378C9F1D9B5999A59 +:1092E00005E33FF7EBDEEE7901D7BBC7427AB271F7 +:1092F00055F411F403DC9CE9B7E7017D9CBAF3F562 +:10930000698A873E23BBFCCCBE51744E705E5BE223 +:10931000B92BB631313EC8DA33F8F9B2CEC4F7789A +:10932000BE28E1BB73E285DC4ED964F48F463BF284 +:109330008AAFF27C880F16EB18AEEB0716BEFE81E3 +:109340007B5285BCF68E8CD707E3F2865A5F68376E +:1093500016E3F23C0F54B66FC0F58575AD17EBFB05 +:10936000C1935F1989EB7BAAE72B23717D37193AEB +:1093700034E48F7FBAFC6588AFE357FAC8CE93799F +:10938000AF174A775ADEFFAE3EBE56E2E50BEA6300 +:10939000FC8BF77F3CFB0F7DC042FA859F338DF934 +:1093A000E14ED27D5B673ED129288F87EAEFBF85EA +:1093B000DFC96D6601F477545445E8BB8ABFE918EC +:1093C000DA75D29E4D86DF2FE05F96A7BD9C83F3B2 +:1093D000107EDB3AD1B739F831B79B1F52C82F6BDB +:1093E000F604D226D33E69C1257A922F3FA7730F88 +:1093F000AC57B1E37E63F1432D547F7ACF7CAAD77B +:1094000099C361DC5735403D96D74D49CC6336EE64 +:10941000E6711DB98F05385E4038529C5123D267E2 +:1094200023DAC90062A3CAFDD78D4EE60D30B46BB6 +:1094300013F77D323EBBD5C7EF73D9DAABD0BD4E43 +:109440002EA3BF381FD735294EFBFD3CAD3B2F2E39 +:109450005E3ED7A505B0EC34B242C4D3BA3C8ECF41 +:1094600088419EBF4A3C0F7868FF0D640FFD99F953 +:10947000D207CF2B0B26C4D1178A739B0BC5B94DCE +:1094800094D3E124391D5FAE8FCB2B0B0F961F10A9 +:10949000975716FF5D7C5E5938419E7588730CCBDB +:1094A000297EDD0474BE72428C0EEB99F8DB1C7DC4 +:1094B0009BCEB1EC34917FAC5EE49536D51DA37D97 +:1094C00047139E8BE1FCA8F173D1DC1EAA87FD1C1B +:1094D000E5D78612F34F770F2937FEDFF8C17F29D2 +:1094E000E581E047392F398FFA5E85F34F129CC929 +:1094F000FBD8647FB6DC875EB0FFFF7F592E4592B4 +:10950000F0F0AFCAA573E20225D134EF97101778B7 +:10951000CFD3E142D7A0CC036EDFC7F380A7E96DBC +:109520001A8F43EA799E42723CD6338DE28D32FE29 +:109530006B7E4A1F5C534CEDBD98BFD5B02F95F2A2 +:1095400006EA3C75647727C72197B09E69B8147FF7 +:1095500066AFD039AC7F3BFE9F2FEE09F6B0E22F0D +:109560001AFFCFE7FBAE0B8A433E67FB38D31F479A +:109570002F5563C1801F3B747E56413E5FFF14919F +:1095800027625603CC11F7FD50DF8DC8E7795FCF16 +:1095900089BCA27B5353E81CBEDBC8CF1DB8753C09 +:1095A000FFE9E31CDF2884DFECE1EBF9E3676E649D +:1095B000788EECC786109D8B0F34D8BCA8C7A4FF4B +:1095C00048F6DF9EC3E1BA503E9A92FFE5F2D1F928 +:1095D000E4C7B47CE58BC5D136030EE2F82B991FA6 +:1095E00086FA6E28F97263BE6F16A70B6D3CC51F15 +:1095F0002E502EA59483DC463DBDDBE4C1FD03FA6D +:1096000051483F6ECC91FB6F7E4FC0BD05A4BF3E5D +:10961000B0F0FD843CC73380BF21F1FDAFD979BFE5 +:1096200073F9EAF3D1BEABD4E81CC0BA54AE5FA262 +:10963000BB781E50F2799664BD22CF63C8F1BEFF9D +:1096400025D3C31795AB77CBF1FF4DB90A7A96F6C0 +:109650002F43C65BCFF93E20F231FB3591F742E74D +:109660001A245C4DFD3C7FEE47827EE5FBEF09FD51 +:109670001BC9D7BA90AE4EFDC16CC67866793997D2 +:109680009F8D3E1BC5031A433C4FA67115A37DBF9A +:109690003CB73AC6ED7F04D76FDDEB36BA87B471BD +:1096A000CFF6F6619447E027FBEEF41FF8FB37B2E4 +:1096B000FD8F62BBA6559184B843C5671FAFAD2926 +:1096C000277869DFEE34259E077A259FEFC7E5F3FB +:1096D000C501FCC2FE04BE3B55C7F3B59B9C9ABDB9 +:1096E00092F207B85F3BC5D34F7EA0C6DDA4241815 +:1096F000258F62FD77F3896E1A775796D17D002109 +:109700004B19DD27F306BF7FE9D49DB9413DF783AF +:10971000EF477853CB8357A39D5904E3A0497AAA16 +:10972000E7EA32F20F26F19DE4B78173A0B7988380 +:10973000AD4A8C1F3719B89E94FAAD27DFC3FDCE12 +:109740004E9107D83B932DB0C5CA3667627EE4B20E +:10975000BC2B7B707D7AF25511BFE6F1F26233ECDF +:109760003E879D4B87C5225E3E53E439B0803996D3 +:10977000DF30ECFCF172099F2CCB7879CA27E2BE6E +:109780007FBB91E822B59DCB0D06748176F6946877 +:10979000FF543C7F55D2199E82F84A47F453BE6964 +:1097A000E4EE8B310E91A94EC138C4B695130E600C +:1097B0007C545DDF7F392E8DA7C35E855BCC316E17 +:1097C000DFE97CB2079B4B91FEAB7E6BE07989EBC6 +:1097D0005348DF7716D6535EE2E9D74D09E76D921D +:1097E0009F01B6C68D7EA361EDBFA13840EA6E65CC +:1097F000D07CD371053691B7B8C68D7EA8D4F6FE5D +:10980000C024F4ABDCA3F0BB1C017AC58DFB7F55F3 +:109810008776C7FC3DFCFCF6FC0E479599E4A9C28F +:10982000E328539C2427D5F5D7E8709FA6B630BA15 +:1098300037ADA480DF9B3AA2D3AEC375FFE5A7FA8C +:1098400041E3639905B13C37445783297AD05D1CC5 +:109850008BEBC9FCB6A1EE2397FA28D99E3DC78EA3 +:1098600015FA68C09E4FA2E3A1BE93F42DE9F997C3 +:10987000064676D82F15339DEB9274DD26F3F53F1F +:10988000E57EDD229137736CC3DFC7F373EB322EB5 +:1098900012E4F7711A226BF3085F91AF0670DEBB1A +:1098A0001DBAC6B1E40F6BA47ED6F3FBCE8ADA876D +:1098B000AF99548E4F3B530084637B9716215F060C +:1098C000800E460C42071FE5F37327EAFA145A3755 +:1098D000F53EBAE999A90E17AD9B7A3F5F9F53F900 +:1098E0007C3E322E2BFD96917C7F55C1C4B87358B7 +:1098F0002BADFC1C9638E79BBAF2F5C7F17CD3364A +:10990000E13F3EF0EC18FA9D86B3EB5505EDD4B37C +:109910008E5AFA5DA26B0BB8BD94AAF633BB2D9E8E +:109920003E0F507EECB07D3CCF4F15E798D5F5CE7D +:10993000ED88CFAF3AFD94077C795B987ECAE059F9 +:10994000FB718AB7815D44E7554F3EA348BB284170 +:109950001FCA7D5BF27EACB6E07FD64EAA2F48F4DC +:109960007B5CF03E8B25EE3707DACBFD63F27E227F +:10997000E9FBA1EC1FA60512F25D568B3C68A9DF3E +:1099800073856C94793003E79659D082E71EF29183 +:109990002927C6F28198C813DAAC58BD682F0D95F7 +:1099A0000F3490AFC39A2FE6FEC8E6AFE053E6133C +:1099B000C97C210BE68D649E9B3762C1BC914CFC37 +:1099C0003D0B7EFE59E67DB41A3C944712F81EA367 +:1099D00078A032AB86FC75193E23D1DF1916DC82E4 +:1099E000F7B90766DBE89C379E0B42BA8F2A6EEA0E +:1099F000776A8D26DBEBB0FDC0BD80B58CEA334ABB +:109A0000B41CB4C32C508FF7150F9C7B5EC0EF4F76 +:109A10004FCE1B91F94B329E9B3BEA2905FDA2E8F4 +:109A2000F6A73C826F89EF8A793F9DDFF490DC7066 +:109A3000B5F2FCA4E8A5CC8E7EF92A297FCC89EB6F +:109A4000BA49F117237F6EB2F273FFDDCCDBAE872C +:109A5000F21D05C3B85F8779F6EB486077D0EF2F2A +:109A6000743AB5A70AB262F424E1629BF9BCCFE074 +:109A7000392F2536DE99C57F2B44FBAAAAD7C4E926 +:109A80003269FCAD03F7AE042DA84F5E2E6044672B +:109A9000DE247B573E5F96FC26E4B21C7FA8F94982 +:109AA000FA3C9F1D2FE96F287A0B5489757A2B8514 +:109AB000EC0F496F0756EFA47B01FB5687E879C688 +:109AC000A284F4783ED6129D8B92B17FDB9FAEC309 +:109AD0007B39CEA4460BF15E8F377FFCD7AFE1BD5B +:109AE0001D67B2A26F61F954E1381FD58F886EC32C +:109AF0007B3E743FEEE1F5B89EB960BF173CF2B50E +:109B0000808DEEC95ADB8F7AAB3C291F25E93E8256 +:109B100014F17B3ED93623D993D922AEC7AA855DED +:109B2000CFF8EFA2B5E694511CCFC63CBBFBB13ECB +:109B3000DFC4EF2D6040FF583FA298E735303E6FFD +:109B4000962FFCD32C12A0DFE72B76D0F703727C84 +:109B5000B749C4A7F8F8879FE47144999FCB98BD93 +:109B600000ED219B872594E57D1E4CB517E0F9FD9E +:109B700056E9F713E52753FCC6C238BD7CF8CA3B4B +:109B8000C6D2EF843CF5DD12949B571913EF59961A +:109B9000CFE78B389D9C11F70936A5F8D30B61DD13 +:109BA0008FA4CC9D8657C3CEC9AC343AC87EDBA502 +:109BB00047399525E8C3319BC3E7A8F629F8FB1C74 +:109BC000F23EBF2CBF4A7E02E6EFD4A35ECD3AEE52 +:109BD000A3BCBF7A73B4107F47E505B33F0FE13CE8 +:109BE0005B7BF4768A17E61E7E0BF3340E1B3AA6D7 +:109BF000A6A11E2916F742604016CA07F38A683FDD +:109C000038201F462814CF9C319B9F5F9DCE422A4F +:109C1000AEF3343B3F4F35ADBCD8DB0AE3CD107912 +:109C20001ED38EF8D250BE4DBB31A2F27B2BA26A5E +:109C30007C5E857C32B7C113CF0F577BE2CA0CEF35 +:109C40001D4E2C5FEB4D2C7F6DD2A7A3E2CBE3140E +:109C5000AD02E7F90B45DCFF00F285CF8BE70F3E45 +:109C60002AF67363DCCC5C84F98D4E2580FB85314C +:109C70004FE7529CE5E9498CCAAE9DE61DE6F8F92E +:109C8000DFA7E37168E10797BF338475A86F9FFA78 +:109C9000838BF0E5B281BC7592F4217A3B20F8F613 +:109CA00080E0D38A3CB315E5FF0183A78BE83CD560 +:109CB000EC413FD5FE5423DDE3DABA8CFF4E8192AE +:109CC000666646E8573F8F97A11DD80650AE3053C1 +:109CD0005EC801916FDDFA3D95FC5C588FF7EBEAA9 +:109CE0007F6025FF76755AE937B05E9F66A4F30E54 +:109CF000FB532BFC623CBA5FFEA15473187FEF202C +:109D0000F93ECDC30817E20DE07A98C341FCA8AF35 +:109D100030921D2ECF9F433F147FD3E79A69BC0337 +:109D20000EFB7EA4BBD6F7C8D283FA491ECCE392C1 +:109D3000F45D9D36897E3F04B8AF24FEBE74BDCB72 +:109D4000EBE1E766F9EF62940EFC4E060C0BEDF0CA +:109D5000378518F12D8FE71548BC3355C3F6394CBC +:109D600096F9B931D740B952A5FB7F14596EA1F2CB +:109D700003A25EDEFF79A890CB29A5F785BF22DD7F +:109D800096A4015E609DBC29839F5B7AA090F3ED51 +:109D9000B9EB57E146BFBF82F31C1B9BFF0187D77E +:109DA000ED8B2B0FB22E41A4B7E4753960F17AD058 +:109DB000CF76FEFE385EE53CF4B91C9F03F3C81C69 +:109DC0007C1E87C43C42E29C7572FDEE426EBF7EF3 +:109DD00089F31C94FEFEE579BA12E7F925C2195100 +:109DE000BE0438F585009F2D061FFD0C5805CA4D91 +:109DF0004E7FD3459E322B4DCC4B6293BC666E2F6B +:109E000026E6215DA574B5A17E7D40C4B95F107CB6 +:109E10007530E5FB25686FBD3077641FC9DBF496AC +:109E200036642E299FA5FC3F9B73B402CBA007DEAE +:109E3000443D73FBB0C373B1F33EC70325A8AF40E5 +:109E40006EFEB170E2B9704AFE1D8017F817F9482E +:109E5000F26F32FC928FD875214ACCEC66617ABAE7 +:109E600019CF8307BB84EE2B679E82D8FC80C9A7DD +:109E7000999BF93C5A0204F7558E1F52FEDF598F09 +:109E8000FF23846BCEC51FD27D48CC5D3B0AF5080D +:109E9000C0FBF1FF26BC209F72F0BDB4F393EDFA36 +:109EA000F3E5834B3893E5A1844799B593ECF82605 +:109EB000B0E379BEB842F2BEA94EC7E5F01E85EC0C +:109EC000FA46D033A8A7E4FDBA578CB4B6E1BD8FEB +:109ED0007B0DDC9F1A78D2E449BC2729396F5CECF2 +:109EE000275631B95FE0F74134D8F93D4842CF7485 +:109EF0007E7B98BC2789EB43D05309F724D57A128F +:109F0000EF491A62BF00FB02B2CF58BA4EEC0BB851 +:109F10009EEEBCD4630F30F23FF3DF7BBCC928EC6C +:109F200041C0852B768F1BEC03E87EBAAF14158BEE +:109F30007BB282FCF73584FD9FEC8FFEA7CB3FB947 +:109F400008E87DC158AD107FEA65BE91FB9B81DEBC +:109F5000BAFA19A63F363F84F7955ECD9A5FD30DC6 +:109F6000277AD3B0FD9C311FF27B4C63F456599491 +:109F7000C5F5122A99F3F1F161A77F7AD144C45F44 +:109F8000E80DBCCF7C6BAF89F02DF34B93F93B0E02 +:109F90009EE3060E8F53AF2778660D06CF85D07DE2 +:109FA0003C5D65334EDF43D13F9EE3489D10A3FFE8 +:109FB000718ABF16C71DE083B57CDF750EDC7A1B86 +:109FC000ADF70D37F1B85C538ADC276B33725CE870 +:109FD00087E4E3DFB09ED3C50DB53C8F68666F03A1 +:109FE000C5E158358FAB79E17F08CF0121DF663BB2 +:109FF000CB0C487A7F66DF30A09F73F68CC4F8DB09 +:10A000001CF35514EFBB61B621E1F72A251EE68843 +:10A01000DFC39E93F43B95C978498EDB0DC80331AD +:10A02000DF3CFCFD1678E6337E7E2647FCAE585BAF +:10A03000D1C0F9DE515F30BE7777D11788EFF519BF +:10A04000A2744FC3F3598BBA9601DF8CFAD158BA78 +:10A050007FFD4AD7E287EE83F24FB65E44E5E75DC7 +:10A06000B7AC388CF5DB4652B95AF7E15CE483D2E1 +:10A070008A9BA6E37DF57D16DE8FDBEAEFC4DF3138 +:10A08000718F1F3601F380AB8D516A77CDC50D9767 +:10A09000603E54B595975F29FBFD042A0F13E5092F +:10A0A000BFB808CB7DCA8773078B0F8E2955C2F8BE +:10A0B0007B65D519BCFD8C09BB72D15F545DC5CBE6 +:10A0C00063BC95EB8763BDEEA3B983D923CF140995 +:10A0D000BF91B0AF7D82DF9FD68EB6E179409F4DB4 +:10A0E000F1E2B90FDFA4A3FC7E3433CF2BF1696515 +:10A0F0002ADE9F59A5713FEF545B4B0ECAC5EBFC9E +:10A10000C672F4E7DB6DC56D6817A74FAA9C88EB94 +:10A110003DD5CC889E80AFF6E13ACCF9CA878569F7 +:10A1200048CCB644BE92743B53F2537522DF803C58 +:10A13000788ECB83447E807E0F11BF5E96A8AF06DB +:10A14000E47D12DF26D3E39076014B9483313A0D00 +:10A1500029F1F4D98DFCCAF9F70F088751D7EFC15F +:10A16000F7458AF7224AB419C2BE90F0A1DB924D9E +:10A1700038172EFC53A53DCE21B0DB5D382EAF87BE +:10A18000EF34FC713909178CFF1EE1672D87A75B3F +:10A190006916BF57C2F761D2DFD128E7BB2771BE6E +:10A1A00015567E7F811BFD3D14C329BBE8F3E06E8D +:10A1B00012FA77B6D9778F09E6F075C77C5AE71B94 +:10A1C00041033A60FEBB52FC7F4778F4BAC0BE88B8 +:10A1D00082BF37A2513E0CACE33FF83AF275917062 +:10A1E00025E3E3FF02863CEC3E0080000000000017 +:10A1F0001F8B080000000000000BE57D097C54D592 +:10A20000D5F87DF3664B324926098484409824644E +:10A21000830426611164712004A3020E8B028AF864 +:10A22000C21AB20B5D624B9B81B0A9684345A5166B +:10A23000754040B0408302A2463A2C2A56ADA94B45 +:10A24000EBD2F22548658718AAE2576BFFE79C7BA3 +:10A250006F66DE4B52A45FBFDFAFDFEF0FB597FB3A +:10A26000EE7ECEB9E79EEDDEA9B43B02EA00C698C9 +:10A2700087F5ED16CF9802FF642EF8EF80E57C732A +:10A2800016A33FFF4865ACB7096AC44279E3EB5FA8 +:10A290002B587F5583C2D218EBC59A12314D64D525 +:10A2A000944F60EE35AA8AAD7AC57CD69F31FCE723 +:10A2B0003F6E60AC2E12FED18DB1D63C9B7F330E2B +:10A2C0006286FF0633F6567186FF7EC85FB238D6C7 +:10A2D00028D19057589619EAF99470F7D614C6BE4B +:10A2E0000A8B1AC0E07BB7704807323662CE0F2661 +:10A2F000B1A88EF3ADB1F37A3F0C8FDA8CE90D196A +:10A30000E12B4CD1D83ED98FF5BB85433A2038FF9D +:10A31000AF4C4CB3C37C7FA8C23A545C47EB32339A +:10A320008CF704ABA7FC68172C7A08633DDAD7E3F7 +:10A3300053BCB98C594DCADD5E07AC09FFDC104C2B +:10A3400047BB4C8C752770290CE65529E1E85298DB +:10A350001DF27344BE52C0BB9BD5D50BFB31C279F5 +:10A360008EDDD642F05D53E869B607BFB3FAC73C4D +:10A37000A1FD74554F01B826C576843FCC9FE637C2 +:10A38000B1A6C07B320EC717F8B83792F031F1DEB4 +:10A3900031F45D9992A534C3BC0A8A5C94C60EFE62 +:10A3A000BD99E5125E6634E404F174B2BB76B30B7A +:10A3B000D76B6E1E321970FBF69067F234283F6E31 +:10A3C000622558CF089FDB113E433AC247C2C308FB +:10A3D00087AEE6BF2FC23BC305FD5C509A8662A1E3 +:10A3E000BDA753C05D4B41FCC43853C6C420DCBF7D +:10A3F00081718732360D8B00CF0FC66B1AB69BCE9C +:10A40000BC8566586F6C9166D11C349C09E7B3D843 +:10A41000C9E753A83A882EDB762A7E1BD41BE7C9EE +:10A420007E6C24E4AB8E59981FCADB18A7DBB68D6F +:10A43000AADF07F4B2F08DE78706E0D3A7824E3398 +:10A440003798984BE203FECBF68733575630DF7FC1 +:10A450007BAC2E9FDBD053577FE081545D795EA0AB +:10A460009FAE7CD0B17C5D7E48D3F5BAFAD77D38FB +:10A4700056971FDE7CB3AEFE88D35374F951AD7787 +:10A48000E8EAD785C1FE1988E0F63465015CE60983 +:10A490003CDD70658EAEDDB9A8F1C7705FCD5BBBEA +:10A4A0007002EEAB31AC4CD70FABB79C40BAAC8668 +:10A4B000BF88CF05CC1B1D007815B2D6D792007E81 +:10A4C000957EC58D705BB881D793ED161DB8676C0E +:10A4D0000CA67EFDF732660EE6A19F9A3F6DFAED5F +:10A4E000D190F271CE6213D2DF465764B7CF2210FB +:10A4F00010ECBA7FA89DE2D71D40FCBDAFBA6DF04D +:10A5000069F11B2AED83C5BB143F837E33587A342F +:10A51000E6AB8EA9CC0FF83FC5AA1F1D09E957B5B8 +:10A52000FEDF1E4D0FC2C796A0C773984B8FE788FA +:10A530002C3D9E23DD7A3C470FD3E339C6A3C77376 +:10A540005C911ECFDDBD7A3CF798A1C773A2A6C768 +:10A550007352891ECFBDABF578EE53A3C7678AAFA0 +:10A56000548F3F03FE25FF4D5BB35857AF9D0EBC84 +:10A570002513304DAFFF91AEDF32B5DC0A1868A766 +:10A58000071FFC457AC864CC1D003857021E02AE76 +:10A590008E7450D2B86E55D2BF40077F42FCF70F81 +:10A5A000C1BF3A2B5AEB845FCB54E23557F19C4044 +:10A5B0007EF6A54BFB0BA633323F4F3603DF60DE42 +:10A5C000E24C6F6490EF3116606C68907FF5C6B511 +:10A5D000E5333A8FCC4383E751577CADC3393A49D1 +:10A5E0009E3F5D9CA3AEDE413E0800F988F95E699E +:10A5F000A641D69A701E33055D1F0EE77479198B3C +:10A6000086433DA8330CE6F511CE1BC6F928BCFFE6 +:10A6100051DCA777B0060BF63F8B35513A9BB5520C +:10A62000AA31A715D339CC4DE93CE6A5F475BB6634 +:10A630004B017894DB9B873298FF97C5BF3FAEE014 +:10A6400064DE8AC3C9760957C9AFDFC37F42BD91B3 +:10A6500029DEE814E0BFE3ECAEEF3D029F0EE339E4 +:10A6600081FC77421CCD9799BDB953723BEB67399A +:10A670009D1B2F2B9A867CD79768776F85B5F54FF2 +:10A6800062F6443CE712FCA953003FC929FAF3B72C +:10A690009FA0895D3D1B16C7201E993F16CF876B73 +:10A6A0001DB75F8A271DD72FEB5F6DBD566BC33D6E +:10A6B00038CFD60A877B33D0E7FB021F4FDF6E0B04 +:10A6C000A851413AFA3062F66BDD016F5511DA207C +:10A6D000EC7FC6F49B56615E391CE75A0CF3BB5401 +:10A6E0000CF0E6F0BF8EC35FEB130F4BBCD05BCB1F +:10A6F0008C46F87B39FCE11FB9DE4EE7CFE753A06B +:10A70000F0F1F745681EECE7B0A929D98DF0303794 +:10A710000DC576CCD19DFAB960E570E90A0E6323C8 +:10A720007ACFC275CDB3D9DC2AF43956E1783D1918 +:10A7300077F7EC2AF8E77C93373EA0EAE63D09F18B +:10A740005DEE2CEE93087473C122E66DEF2EE0EE01 +:10A75000CAC17DD5D5BCEBB07F94037FA2F8510E62 +:10A76000A43F907FC117E3BF1FF236D3E5F7A7A23E +:10A77000FC926B726F86A28DE1D035D0FB3B02DE7E +:10A780004F58201F4BDFD7E0F78470DE3EE1519336 +:10A79000BF0EDA7BC7BE48787ABAD241EB29662E63 +:10A7A0002B6EB2B9CC4374FF97317F7BA519F05162 +:10A7B0009EA22D44B8DD1D674A7E9FE6A1F547792C +:10A7C000878DFC6EF42FF7E914275FC27C01B7A9CF +:10A7D000CC43FBEE36A65970DC772F5A3DC83FDFDD +:10A7E00015FC643AF3D1F799CC4FE99D2C40F5EF75 +:10A7F00062CD94FF7DC480DE3530BFC98F65A6234E +:10A800007F0D81FB4F08EE76EDEE6E9C5E4EF540BF +:10A81000B8AFEFFE9DE877B2A017D8AF2B71DDB0CF +:10A820005F07E7A586EC9B719C5E98D999FECFF6F1 +:10A830004D531B3F2F80313A1261FD370A14DEE879 +:10A8400029A37302E5AC6E00FF26974A7256D19891 +:10A850001633CE7FDBE79C8FBDBE8C45FAA0FCF59E +:10A86000312A437C4DDA30FE0CB67B8B05BA0D865F +:10A87000FA8557B4A3D1B0FE49C0DF8123B3A25EED +:10A88000704E849C4B3727AC1B8772C4CD7DF5DF9F +:10A890006F61F52AC26F428EFE5C9984E78AAC072D +:10A8A000E31D4238C4763C5FB6A708F9A21FEB77D8 +:10A8B0002DE74BA5C9F36BE223406748F773CCCC77 +:10A8C000D3D97E73642A928F91DC72AB18BB6DC2B0 +:10A8D00065EB2558EFA914ED25EC67F1C4BFCC4614 +:10A8E0007E0C7AD4DB83F01CFD9DCAEE87F213B593 +:10A8F0000071385C4FD6DA9907049CCF6A9D943F6B +:10A900005D9B40E9D95A17A5E76BB3A8FC62AD9BE4 +:10A91000F251A9DE23D8EF9C359F9B518E5A1D26FC +:10A92000F1C7E7B144D0EFEA30AE472D895CF26160 +:10A93000318CBB840E4038AF1BEAC723584A0F3412 +:10A94000BC86297C571D58BE4E71E3F934FFA8B66A +:10A950000AC967E15BCD9390ED0CF9E0643CC2ADB0 +:10A96000E28AC234D84A3F48F7BC8BE39FAA1D460F +:10A97000F33A53EBA179791A5B5E8B83F6E76A8B26 +:10A98000289F99EAFD10E9DBC33EB762FB893B5B78 +:10A99000CC49505EE8513CB8BF477B98DF0FF8DBED +:10A9A00060E1E7C506382F907EC6E44E79E27B88E9 +:10A9B000B614ED048E735BECDCC238A4AB61C566E3 +:10A9C000AC37FD1B90B95282F47DB57D72E1A04297 +:10A9D000F0B9703086E021E15421F075617FFF5BB2 +:10A9E0004740BF07418E54617E6D574C34BFB60F50 +:10A9F000C3FD282418DB2FDE97D68339709DD0D86D +:10AA000086F9FE3D18E021C2FEF413A8979DDBF500 +:10AA1000C304C4CBB9D8862F3F46BEF767CEF7181C +:10AA20006BF8EC71E48BBD12DCF743EEA205F43455 +:10AA3000D26BAA23F05CACB4328DE7B5FE983F1719 +:10AA4000CE487F1DBA3B692CEE271CCF9519E46BCD +:10AA5000598A8BD500DD67EC7E2CF5C730EFED0D04 +:10AA6000F33F7E1CD20B7E93CF02E7D605D670F162 +:10AA700025E4CB5B1CEEAD0CEB9BC3B1FE03163E95 +:10AA80002FDF56D0DB5DD89F9FF800945BB1BCFCF4 +:10AA9000B95FF4C4F9BF8C7209E45F5E1741FCEE44 +:10AAA000658BFB780DB67B82F7F7CC43F79E388039 +:10AAB000E98315F9F742DA273596E03DEFE78BFA9F +:10AAC000617B38F75922F0C75FBDA004C2006EB9A0 +:10AAD000EB0F2D4F84F1066E6C31F584346F8B5281 +:10AAE0008769FFDE45C7F0BC4D4F75D13C06ED4C84 +:10AAF00051519EECD7D3FFF10D240FE8E5849CF56E +:10AB00009F8FEDC982F2423FA5E1EC32A087D5BD0F +:10AB1000FF90CFF5C47AEA675FE3D4F7EE64B80E2E +:10AB2000904470DEC556B253E0722D90BFB0376DC1 +:10AB300013DA33F69B7C9BE8FC9AC3E5950B5EDF4A +:10AB40002F90CE2AA0BE0FF21579BEA8EBA1BCE2D1 +:10AB5000CF7DDD4051ACF7933716213C2AF73E32CA +:10AB6000BE27D4BB3092B90115AC64DFE5F1D88EB5 +:10AB7000F586B5603F7BEBE2EF80760FE48C1D82BB +:10AB800074E5551B681C56C5C7794C9C7BAC198075 +:10AB9000132F5809D47B003EE3F7D8C69843492CBD +:10ABA000889FAAC66529686F19ACD9DD2AEE9B1467 +:10ABB0005F62B523788EC2F977632AD44BB48A7E5C +:10ABC0009D5393BDD770FE59C57926FB7BCCCA7CBB +:10ABD00061B15C6E56F07CB6F2737B2BF0979AFCF9 +:10ABE000E0B90DE34E4FE5ED495E4E82433A0FE684 +:10ABF00099F498CD4FB2C1771C5FCA5B55427F91E3 +:10AC000072CB8CB8BA579A61BD8F456873717DF36A +:10AC1000C5B9CFCC6E17CA453F8DF0CC4B25B9AB2B +:10AC20003519D700E76A09E62B5590C3D242E430C4 +:10AC3000FB773B577744782AB1FD77AD6FE4BB4B88 +:10AC4000BE30B13CA083258FD8484FAD13F6863A6D +:10AC500061DFAA8B1C6A477EC18E9ACA5F83F37636 +:10AC600014EFA1BDDF2591F9C44FEA18EB146E076C +:10AC7000810F68C07702706E68C00F465F695539F2 +:10AC8000DD371D891E8CFC9679225D680730312DD9 +:10AC9000E43C35F603787B08E1398645302DE4DC69 +:10ACA000F4B0182BEE5FE688FD97D63F52E04FAE2A +:10ACB00063A4B0E78D6CFB3002F9E6922FF2897F36 +:10ACC00076B5BE57C4FA7E83EB83D492E9DD84F86F +:10ACD00018F557A719D739CA3C3919E51C98FF331D +:10ACE000F87DF45F4DFAF97F13AECB7FD7757C5FAB +:10ACF000613E13EECFCFAD7EDC9F8D40DFB89F1B52 +:10AD000017E5F8910FEC87FD6047BD668A95E4DC96 +:10AD10004661276DECEE24FBD2CB169EF7CD14EDE9 +:10AD2000C3189D238D337B52FB9EB6EA3773B1FF68 +:10AD3000BA08E29F8D16FF9A54ECFF27716E1FE050 +:10AD40004BC5F36310E81B827FD7590277AAD8DF7F +:10AD5000E75686E3AD8F09245541FDF58B7A52FD08 +:10AD60000F419442FBDD0893E9EEC90E2CF724C68F +:10AD7000427EFFB72A9D1BEBF320EF203E4EF6C02C +:10AD8000F5933D89E1DD308D37D17C54564DDF534D +:10AD900078BB8F2DBCDE1D027F1F09FCC03E273E05 +:10ADA000A04D8A30231D5F4C9DD342FB8379121541 +:10ADB00098CFE3F3D219F2D13B4A6F4A21BAA97F67 +:10ADC0008CF8D90C8103D91F36B00F45399AFF99F9 +:10ADD000397F6B18E2F3B69230B28F7E58B23CD214 +:10ADE00005ED6FD3D4800DEDC6D30A3DA1FAF8C5A9 +:10ADF000540F8D5BD1909D763284AEE7D8806F4042 +:10AE0000FF6BC2B5D348CFEC401E951F00E1E61F93 +:10AE1000B0AF4ECC4BDF4D768D79528F0CCC45BC0C +:10AE20001E6CB533D44FBAA2873AC403F4DB479CF7 +:10AE3000EB44AF88FF19E15CCF3103BD40BEAE21CA +:10AE40009BF49CA72CCCA320BEF6D908FF4553EC5D +:10AE50001EB23FCE08DF6483F2BB053FAB9B114EB1 +:10AE6000DFEB5E89F49B14D29F28EFDB63A176E5CC +:10AE700056FF8E6DD04FF9C16C3A6FF65BC5B82F97 +:10AE800045F0F2284FCACAC158DE83E8E0658B2B33 +:10AE90009ACADF50199587073262008E91615A581D +:10AEA000DA10A43BC0B303FBE5DF8F0BFA3A0EDDEB +:10AEB00022FE7CD591D42F6D7DC86B75BD37233EA6 +:10AEC000352B2F673F52A9FCB8D393381FF2C7AB7D +:10AED00093685ED2CE74DC6B25BA3F5EAE90BCF454 +:10AEE000A71A35600DB5E34FD97E5F06B4FBF4A019 +:10AEF00085EC78B37E56F6167E9FB5BC82EC91B396 +:10AF00004A97929FE0E2D24F876E80F5342FFF245C +:10AF1000590BB14BCF2A8756A176D5344F6A1AE028 +:10AF2000E7D6342D1DD75795D3BC00E5EB8BD6A6BD +:10AF300027515F7075D3B2F0FBA5174F6DE37277A1 +:10AF40006B069E1395664E27F2BCAD1274F85F69CE +:10AF5000DA00EC0FE0361BCF95889C26CEFF967E5C +:10AF600037FE7FB671EB7E05C6290B6FACA454F596 +:10AF70000FC07ECE298128258DE0A8E1BE3AEF0CD6 +:10AF80004421FC351397F3CAB6EBD7857FCCF16823 +:10AF9000376364072F6B503D61B80F98DF8AF32F3A +:10AFA00063D660FD9420BEA01FC21773FC69F68FA4 +:10AFB000010FA53BB2F351BF288B39F0D008AA0787 +:10AFC000EDE47E513BE6E57A3ACE87AFEFBCD80799 +:10AFD000E7E18B05E965A74DEAF934FEC5177BD09B +:10AFE000F8F1629F5C5404BDEE08E374E58675E1F8 +:10AFF0003C7FCDE9EA51C92777F07ECAE27C26E49E +:10B000004B65B54EA22BC997602EB4BFCEED4EA2B4 +:10B0100076928F312F63547F77E2662EBF097D17BA +:10B02000270CF54B7FC5C7C13CF2F3B3CF26C971DE +:10B0300049DE369EC7C6752F49E3F62938A77BFC43 +:10B04000337D312B61EE13F30685AC27D22AF882CB +:10B050003B61722EFA17ACBA7E2F465AEFF638D003 +:10B06000CFA0FF2EFBAB4DE3FA641F039E7BAAAD7E +:10B07000876CB80F9F66746E18E7B14AB47BF6D937 +:10B0800076BCAAC29ECE5C929E5C5C9E27FC7D64D0 +:10B0900095F8FB5E12F0E33284556A108EFBF3B430 +:10B0A000243C372E0AFFD0FE18C8E7A03CC5F12289 +:10B0B000F3121F46BA5CFED18224F4473D2FE168AB +:10B0C00080F732802B96D75940BFC9413DF7D8C38E +:10B0D00027D383EBF9ACD6E39917925FB021CF8EDB +:10B0E000FB71E1C63CFB9C107CD46D1F74CC0570D9 +:10B0F0003FBFDDEC46F65E67F63F84727ADD76B5DB +:10B1000001E908CAED08EFF38EC3BFC37A0B36C658 +:10B11000E4A31C2EDB2FDC50E899178287FEDBF5B9 +:10B1200078C96DD0E7071ED0E75F4119B4FBB5B70A +:10B13000CB0BE8F3838EE9F3AC15B03714E5018E41 +:10B14000B71786B98FB9006F7DFCAA1B3FF5714C0C +:10B15000993A11E5888DAA3B1DCAFB2CF5DE827257 +:10B16000C5E98DF3DD88F612D557F963C069C927A3 +:10B17000E38FE1B97A8E35FC6122E06541E33AABB9 +:10B18000D985EBD6D3FB7E93A0DF67B9FD6E915FC7 +:10B190005FDE912F2C93FEC1AC50FA32D2018C7B32 +:10B1A000BB0726545EF3DEC3C8174A2600E1039DA1 +:10B1B0000D6F586745F9EFEAE3F8B87CE9F0B8108D +:10B1C0001EC5C378D9F53505EC53D8776CEDEFC7BC +:10B1D000E3BC8B1F5048FE287E3EF328D257CB9EFF +:10B1E0009937537A7B11AD5FDA0917362A8148C83F +:10B1F0003B87B90E3443BBF97E6EEF98B3C216E4B9 +:10B20000870CFD648679AC0F2987F92F3C70E86BB9 +:10B2100005FA2FD9A86FB708F8349E3FA55BFE61E9 +:10B220000BFD2EF5D1EB1B37A9B8EEF962FEF2FC4F +:10B2300064BED1E4A7B89E376127F1FFE0DC991D19 +:10B24000AF297DBB07CFD1EBD7F3F6C0768B71DD8D +:10B25000150EAB0BD75D6167810898CFB148ABC7BE +:10B2600009DF2F6F88243BDD021BC8ABF994B23095 +:10B27000F47B3037F9CB3E7B4725B9A7228EE3BD5F +:10B28000E22985F4B40A34AE62FE699E5FC402B45A +:10B290001EA4174FE83AFDFA3CABE7FA5DB93970E6 +:10B2A00008E152CA9AB97E06F8F484F8BBCB619DD6 +:10B2B0001FC6A2FC6668CFDC1AF9F11C5C1EAB3A13 +:10B2C000F00F5B68B9D433A51E2CEDC74F6578C36A +:10B2D000711C8B909BD7DFE7C9C0F9AEB4783210F0 +:10B2E0000EBE7561A4EFDFB1899F5FEB63408EED09 +:10B2F00046F233C9E377285C3E6733393F1C617AF5 +:10B300002E80E74DEB2331EECD2EAA4FE7D8FA077A +:10B31000B3B9FCFFAD4AF250EB3A1E17B13E8FC3F2 +:10B320006FFD83B95CFE97E75E7746FD7594B73D88 +:10B33000196887600FF3797D8C4B0A91AFBF8DD769 +:10B340006EE81BB23E2997B392EFE6CFD82AE234DB +:10B350005AD785F9D19F7152F1BE660A916FBD7DB2 +:10B36000F9393174AC679BA8477E8F79A6C9F7DF9E +:10B3700000F39AF7A8C985F6B776787B3C19787EF2 +:10B380009E5C17968F7436742CB7471DCFE37C3FB5 +:10B390006230F3F8219D29FA9DD9D7A44B13C281BD +:10B3A000FEA09F9385DC1E1E39D84B76C0AD2ECEF5 +:10B3B000F78DEB982FFA9967F5FE765427F3917085 +:10B3C00061E3B8DC71F21E65339F17E01BF2437F27 +:10B3D0001E46F6C393E25C92F005BAA1B807C9B75E +:10B3E00062DAE9C5BF230CE8659D85D381D4DB42D1 +:10B3F000E845E0BF37E1F70E815FF66098A01713CC +:10B40000FB6F8463A193D3C335EA5F80EF9F20BEB7 +:10B410008D7A98C43733FB87FC33BF4BC50BBBF623 +:10B42000FB40CE28FDF523510CEA9D31D7C7BBA1C7 +:10B430007DF9D695511E484F9B7D514E18FF8C5F6C +:10B440002DF27702EF97FB4AFBB5C7A184F849CFED +:10B450003EFBC0245CE7975B2D4E640955DB6DA471 +:10B460008F55EE5D44F23AE45B787EF5E7E837AD60 +:10B470003AA0B7CF973EF348BC8BE0ED4B32256046 +:10B480001A486290566EB1B4FB91611890BF5B5739 +:10B49000E1FC8CED711E5700DF550D6AB135BA63C2 +:10B4A0007995E02F557B1FF81CED86557B6F3A850B +:10B4B000FCBECAE0172811FE11A35FE0577DF571AD +:10B4C00007001F8A33F0C1BCD2895CB85DB96EC772 +:10B4D00063035A507ED8F266949213F40F48BF4922 +:10B4E0005BC3DCA75E7275BD2F2F0AFB70106F9CCB +:10B4F0007FB90E2818AC048A3F4FCB2D81A811A824 +:10B50000EF6DB290FC5BBEEBE96D8F239D7D64A374 +:10B51000F3BD6CD7AB7FB81EE5E73D966E13F832EE +:10B520001C4A485C4E958BDBE3247E4A9F7FD5EA1C +:10B53000CAE5DF97C606F154B6E79015E3838CF0B1 +:10B540002C6838646D767482AF8696F16487DAF180 +:10B550009515F7C799830AEB91D2B17DC9A657A378 +:10B56000503E4338E1F924F1D68E47437DE87FD23F +:10B570004B83A99E13F594ABE1F181BE8CE056F1AB +:10B5800042248B8179947C6CF34F40FCEE5E1285F3 +:10B59000EB3965AEE674FFC4CA7894F74A2CBE78DE +:10B5A00027A5FC7BC993DF277A5CA854C73B738827 +:10B5B000DE134D244BF812719DF337DE46EB5CC071 +:10B5C00034A2C7922754AF1FD22FCCAC684F27FBB1 +:10B5D000E6BA74BE6F4E6D06E4C23A4F89F82CDFAE +:10B5E000BBAAD0A3EFA1F3FCFB62CD8C2DA6FC1768 +:10B5F000429E0B4B6F8FAFB287EAA1555B56372146 +:10B600009ECEF6F6F4C079021C7C026ECA3FA05FA3 +:10B61000F5F7853D389E980BE317A81D9CAB05F800 +:10B620001DEB37593C68670F6927F4443EFEF7C4A9 +:10B63000F830EF70D4834FC5771EFFB500D7C7E74A +:10B64000D7141AFFD5251FD8721FD1D75FDFE77C2B +:10B65000A6D23FB988CA9B2C811E58EE3F344D219B +:10B660003E616381CEF6F9168BD8E7FA7298A75936 +:10B670000985EF412E9F4A7A5900725920444E089D +:10B68000D28F35F89DD6FF73C1E79AC99F27FD80F9 +:10B690000B057F30AEDFC82FF2D23B8F53611B3BCF +:10B6A000F73F05F9848FC62D87F31DE591F28F6C66 +:10B6B000244794EFB278114EE7761EF9C31DA8DF38 +:10B6C00036C87DADE7C3C67D5DF2DC904EF7F5B9B7 +:10B6D000B5799DEF6BF8DEE9BE5EAB10BFFB9FF264 +:10B6E0006138F9C82E71B5FDBBB00B3E3C2B5DCF68 +:10B6F00087BF6039D123B0D059DC87F06480AF8434 +:10B70000AB91AFB6F57575CA5719867484C053C22C +:10B7100051D22B631A8DD34ED7926E255DB7D3AD20 +:10B7200071DD7A781ACB9311F73075EF8B1692177B +:10B73000CA1B797C22B4A378BA2AB4CF53EDFAD7C6 +:10B7400092BA85E6FD867C83A1BEC790F71AEA6BA4 +:10B75000867CB5AE7EF9812356AE3F0474F56C3518 +:10B76000B7903ED251CEF073BFD3DECFAD3EA48FA3 +:10B770005EAD56E49396E5CC1709ED5B5F5149EE5B +:10B78000B9E46A8D42B965651897EB2E39453E8656 +:10B79000E75BBB5B57219F94DF5BC3B81DE692B7A5 +:10B7A000352A26449F6F6954A3D0FEDBEC67459D84 +:10B7B000C7B7D4115C9B5957E55CBEBB14CEED0DE9 +:10B7C00097C2B9BDA1507524D7A01DB69EC711CE92 +:10B7D0005B363D8AE2301AD36E9D01DFE7BF4161DF +:10B7E00006184767C6F887B91C95EC34F3513CE15D +:10B7F000DC461E07316FAD1ECF0B1C5B285EEE0BC7 +:10B80000B694D205EBF5F10BA56C2DD159C946C301 +:10B81000F7C65B689F941AF68926ECC3C67D72480A +:10B82000F29F3C96A78B9314FCBC50CDB97506E0F3 +:10B83000E3D23195D920DFD6A8B25583795C2CFAB2 +:10B840009F5021C1FD5709FB15E52609AFF3B88FBD +:10B8500032BB965FCEEFFBF3D01F23DDECFF64C05D +:10B860002F213DBFFFA38C9731FFC21F933F611D66 +:10B87000EB171CFC7A36F2E94B076D0CE9FDD2C1DF +:10B88000D793D11E79E9251BE9D99796DBB89DFBA3 +:10B8900060A41F8F984BBDB95C5CF7CA57039AE947 +:10B8A0005C5E41F83B9F6EE5F255E3DF8EA33DBD44 +:10B8B000AD1156857CFF6004EDA7AA97C2C8CE7C67 +:10B8C000E995AF8686DAE7FEA7EB91FEF74B916C20 +:10B8D000C67348C7315C2FA87A79F8D3E85FAED831 +:10B8E0007BC83A17CA0B7EF3F701C8572F3DC7E54F +:10B8F000A98B96E627D1C6F955FA999F5B86A39D39 +:10B900000F3AEB09BB3B237BAA2FA733B870385CF7 +:10B910000238E0BA002E25781E74058FA88CFF54DB +:10B92000787C3E9BF3B7EB18FAA38370513CFC7B09 +:10B93000A4DFAED0FAF9F7835F0D40FE73B5F5E6EC +:10B94000FC7FB6DE9BFF63D7CBE9FD5D5442867476 +:10B95000A4FB8E74FDC20F28BF3BD24DF3FD8EFBBE +:10B96000BD14D7DFFD3F71FDFF3BF85EF31FBBDE6B +:10B97000ABE1FB0D81EF4827FA332FBDF2F7647678 +:10B980000DEB7EE6FF289D4B397EACEA3E9607F52F +:10B99000DF640DEFBB53481AE9540E793F43AF3FC4 +:10B9A00015307E4E17D8CB48FE2CE8F520C9CB7554 +:10B9B0002C9FFC17BE5E2AF975280804E0F07A4235 +:10B9C0001EDDB362E640AF25901F9B5441F16246F5 +:10B9D000BDB2207C6211CAA74796C1BCA09F23912B +:10B9E0002627FAA8C7F55203B60194B660FA5AF2B0 +:10B9F0002D14F73FCEA1D7AF6E31E84937B9F4E542 +:10BA000045ECB96EE8B72BCAB1D0FD8AF1583F4476 +:10BA1000AF7C2EC349EBBC89D5AF703AAE1D4EE664 +:10BA20004C0EA78E70F8E770EB0027A1479B457D71 +:10BA300023DCCC8EFB9BB09D99815ECCD74BFAB4B6 +:10BA4000D48BAF064F26F46DB3185AC2D7DC8BFBEC +:10BA50006743FA25B848B85F2BBC259E8C7097F0D9 +:10BA6000957033E2E18F194CE8B71CFEBDCC7966C6 +:10BA7000DC77A3845C3FCE1CC3F3BD9A542FED4703 +:10BA80003FA7F3BFBACD28D78F71C4501CA9F1FED0 +:10BA9000C29C61314315586F9299F96CA087A2EF4F +:10BAA0008DECAEF799FDCB53701C6EDFED6DE6F6B5 +:10BAB0006BD8DDBEF07CAAEFB142BEF8E185CC03C5 +:10BAC000F58B93985BE1F559742C85C73115E3C468 +:10BAD00020C576C5D1BCDFE21ECCBF9CE393F082CB +:10BAE000661FB46F40BF1E532C6F1F954FED7D2610 +:10BAF000DEDE6386B44F1A8F53685DC9EDF2C5ABC5 +:10BB00007B6720FF9830566F675E9AC9ED2E323DF5 +:10BB10009DE92278A9267702DDA758914DFA911A5E +:10BB2000EEADD88776FADD3C4EA778D55D1387E079 +:10BB3000FC76C7B9717A6727ED19CAEBCFFCFE070F +:10BB4000F05DDB1E46DF1D59DA7599180FA0B86647 +:10BB5000EF830F736E3B624D8021B486C917D04EC0 +:10BB600038C9B7E777E89F9C344DA5FA93188FC37F +:10BB7000642B22280E73A2EF737302F43711940E14 +:10BB80002C6F097326DF03F32F16F6E102B15FD4A1 +:10BB900070A63DE7C079F5CE4885EF1359E7F1C9A6 +:10BBA000CB447CB23A56D9887EA63E05DC7E2FEB8C +:10BBB000633FD8EFEA4C6EAF9F24529907B852FD0D +:10BBC000796B6C2D69A8FFACB10432213D943D76B0 +:10BBD0000AAE73422A1BBF01E17EAFCA36D37C5B3B +:10BBE0008BC9AF1099E5423C6840D2E45FA94F7120 +:10BBF000A15DAC654C4300FD092DBF4871D7B90864 +:10BC0000CB140F24F5AD963181BE68C76FCDE37EAE +:10BC100089E3CEE648D417E73AECFCFEA4882B9AD9 +:10BC20002FEED1F4A96B7EF03AD4431F51C95F3394 +:10BC3000FF117E3FEC2F0EBB5F41BD6D3DDFA76C5A +:10BC4000AD3E8E8839DD64079A5B3FC68AFAE63CD2 +:10BC500087C78AEB5C9BA5556722DF16F711FB218E +:10BC600012A0CBE2FA628A5751A360DFE13E31BBFA +:10BC7000A2500F36C6215589B823995F13AEDD8BCC +:10BC8000709A13EDDA8DF472A2268DECA30704DD11 +:10BC90004DC0B84AF467989B13713EFDF03B8C3F52 +:10BCA00021D699E1207A0E630887168B3303E9BB0E +:10BCB00065659809FD72139673BA867D663743FBF6 +:10BCC000FBCC2C1CFD0C378A7E672D337B3741BEA5 +:10BCD000979D99236391AEF288AECDFDB449B8BE6D +:10BCE000D33F61C3901EE6AE5D47FE184917CCDC1A +:10BCF000342E0EC639BD35251FF9663B9FEE37B68B +:10BD00001EDBB5D3C33485E800D24369440F531E0C +:10BD1000217A181BE8BB3807F5D172E6C1F33D81E3 +:10BD2000B9514E6863ADE4AF6C73585D68FF92FC27 +:10BD300044F20D795F56D2C13638EFCD16C6B6D76C +:10BD4000DA297DB6D6C9CCE98CEDAC4DA0FCEE5A13 +:10BD500017A50DB559F4FDB95A37E5F7D60EA3FC72 +:10BD6000FE5A0FE50FD41651FA52AD97BE4BBE04E2 +:10BD700070213E24F98AE447731DD616F45F4ABE4B +:10BD800064A49BD900DED1F9D49EF89EE477B80E66 +:10BD9000537E901F49FCA62A5E5F420AF2B1E699E3 +:10BDA00088FF42F5FCAE17502F2F71B8494F679CA2 +:10BDB000EFB501BD225C92ADEC00DA65EBEEF1B4BB +:10BDC000AC4E09C2FFCE12859943E8EAAEEA30666E +:10BDD0000E3937EEAE89D1E567D5BCF76A0FE87F3B +:10BDE0004677ED0DC4DBF19F7EF6C41FE1FB533FA8 +:10BDF0003D9B8EF886796C7D0CC75D1ADE3E8F58B0 +:10BE0000CCAFB0909FAB8FB09FF411F613FC137AB8 +:10BE10009FF9A99FFE37EDF3961A9B0BE5E28F1170 +:10BE20005F00DF3F097CCDA9B1111C8B577EBAEBB7 +:10BE300005DCEF4BADC4EFE6AC10FBD1700FFA445C +:10BE40002223BB0448D514CF7EE227D64004F47FDA +:10BE500042E1FB5801E16016C61FAE79FD43E403E1 +:10BE60004ACD31F2BF6B786F0FE7E7B39CD7DDABFC +:10BE7000AE798DEAB1E65E31685F94F79223067B76 +:10BE8000AC2E583FD236E26F4ED66196887E967AB7 +:10BE9000C589A2DF3CF17DDE1A85FC9A18C7330DF7 +:10BEA000E4BFB64C95F0999B69A6F4018CC127F9C3 +:10BEB000AE9ECE2949B7F3D6423BDC1FF579D605B5 +:10BEC00021FC788EF83E37CB44A9FC6ECAE2FDF621 +:10BED0005C933703E58A9E589E8369FE0C846F4FFE +:10BEE000C778B3124207DF88F173C5F80FE0A68365 +:10BEF000FFDD9F956A9D9F43F701E91C93E3CCC941 +:10BF0000CA5F85F1A573D68E412ECCEA2CEE846EE5 +:10BF100068BFCB92FD88FBD8761E475DDEC539220F +:10BF2000ED6AA7F19FC369DD64F72DDDFDABDD7818 +:10BF3000BFA0F4131BE1B774A088DBCAF10F9D4AC0 +:10BF40000648BD3D7BDCAFFE1C457E8ABD3CBE1372 +:10BF5000526E675D5AC2EDB26ED85F9DF88B8EEE61 +:10BF6000FE24AA533BF65EF53BD9B1AB946FA250C9 +:10BF70008E90EB297CE58B789A877285FC4455AFCF +:10BF8000AC8CEF2CCECB68C76EB7770BBB5ED5D22F +:10BF9000A24EEDDD46FBDDF02C83FFC0CCE89E9980 +:10BFA000B4DF3135271AFD005F88FB275DE939D200 +:10BFB000FE5DB5013A8903BA34BBA2D1BF75A90BA6 +:10BFC000F97A59163FFF2F087BF9A59D2AE93D977D +:10BFD0007646D2BEAADCF9F06BE877ACDCA2D034AE +:10BFE0002A5813C10FE0CAECA1E71AC6B1C5759C67 +:10BFF000779B3F3D1ACF95B25F455623BD2D6A50C2 +:10C000003C5B613E6D765774F790F9DC85F406F47D +:10C0100053666B184AF016F39F9AC5F9A4ACB7A8FB +:10C02000F161B22F43BD8B2417FD3A82F1FB29AD9C +:10C03000BFC3799EDB38C88DFEC2450D7B2A49AE51 +:10C04000D819E144BBC25911B7DCDE8FA0EF4559C6 +:10C050005C8E3927FC47E776F37700709EB8CFCE29 +:10C060002ADC0EDD8E6FD1AE4AC02D368BEF3359F0 +:10C070007F51434B545FA87FEAC07B94DE2BD6B53B +:10C08000C8D13400CFE3537B23C8FF756AEF2FC7B5 +:10C09000BF0CE35D6818D30DF785EC7F759685EAD4 +:10C0A0005FD8A81621BC989FC7CD54207C0785CEA9 +:10C0B000336E932F2574FFF1F8A1737B9F8F32E5C8 +:10C0C00004F15961AFB6279A701FDDE345FA8E403F +:10C0D000E2817AD6BD937D78865535E631A46BDA58 +:10C0E0007F89547F8D29A49ECDE2A63853CB8162EF +:10C0F0000FBF6722EE458938FE423587FC8AB307B9 +:10C10000BAA6DF897CF24D0BE16371B66B3AF2A7F8 +:10C11000CB4D2AC3792E4E6101944F96DC1BB90991 +:10C12000CF3139EFD983383F285FA3300FACAFDC74 +:10C13000AF320DD29E807F1FD25342F3108C936C8E +:10C1400049E172858C1F7DBCC4E4B1C239B8272B8C +:10C1500056F059ED17F3D17F36258BF4B9E356E647 +:10C1600053D1AEF41C8F2F2D4FE571CD8F8B78F806 +:10C17000F2D840461CF4775EE0B77C4A2003E32EF9 +:10C18000CA9F4BA4B88BF356EEF7C4EFE8672DCFE8 +:10C1900087F60E7A674393ED6342E8A97C8EDB85D0 +:10C1A000F5D458B72BCF81F3755E2439775F2443DC +:10C1B00039D7F442248F9B7A266CB32D046FAF0AD3 +:10C1C000FA93EF77B03B789CD1A3161E97FAE8D686 +:10C1D00044BF3F045E8F5AB49908075C07CAF78BC7 +:10C1E000ACF51928FFCAF92E8AAAA7799E17F4BEC2 +:10C1F00028BC9EC7738BFBC0581FF32D220EBD7544 +:10C20000878DE280CE2636EDC7F1CFEEC866B8FE48 +:10C210009614FF8203540EF225E0B3F4595B00D765 +:10C22000736607B7479FB17079EDCCE40417E2B7A6 +:10C2300068CA86D964AFD96253D0CE774661D60436 +:10C240002CDFDA9DE2CF4B6B6B287EBB14D806DE69 +:10C250001F82B408EF019DD99A4DF16667F0DD06A3 +:10C2600085BEAFC1EF1AAB9FFD2384C776AE5F9D3D +:10C270007DF66FD9A1F1DE322DDDA28FAF9374224E +:10C28000CB3FCBE2FAD067595C9F3B9BC5ED1115C4 +:10C29000110D8FA6D23A39DC014FFC1D1BD61CF9BB +:10C2A000CBC1184F91AE201F799C05327E897687CD +:10C2B000ED5CFF3ABBD34271EBA52F447A288E6D1B +:10C2C000F575268AA750B99C5E6A02F041AAFC74F3 +:10C2D0003BC597757B362CDF46F239233DB775ABEE +:10C2E0002AC6015D10D7BD8DC71D4F405992CA7334 +:10C2F000A9FC8CC89FD99F4B721FF4EFC1FB55A5B9 +:10C300003FFA3187E3D492B7B8DC65277E5BDEEE77 +:10C31000E719198DE760C5EA11D1785F91BDA332A5 +:10C32000945B8C70BA6C76F7403E3B3C5BF0DDFD75 +:10C330004F907FAA4CDC23287B56E17E68D8877813 +:10C340009FB36CD588C7883E7F6761E9B09EF30DC7 +:10C350000F4785E2232D9BF3C5F6FA5637D52F8379 +:10C36000FAD84FD9AA37A3683EDB2C14AF62C4E3D6 +:10C37000776EFFACFA9DDAB7D34703B7B374583F73 +:10C380006BFAC127D0FF5F7786B97DF4B581EEC126 +:10C390009DB3342CC0F59FDB15467CEB5C0CE70F9E +:10C3A000A7809FFA32711EB7FC8CE2BBDE9D4AF774 +:10C3B000F716FAF5FDCA71B3B22D3CFE2ACE1D8DDB +:10C3C000F18215EF703E0878B995DABF63A1F6C621 +:10C3D00075D8B239FF6FDF9FBB22881ECEF5E47897 +:10C3E00039B73B93CEA796184EE730DF64BCEF77A2 +:10C3F0006E57661EDDA343A107E8A154E8BFE762BC +:10C400001A929D21E52D16A1C705A026D20DB601D1 +:10C41000FE5E5AC3E5AD32FB5A8A2FC178DDA1F921 +:10C4200094066CB11DE36E815E49BFACCDE6E7209A +:10C43000C3F1E2459C38C9410D56E4DB9A9017CB15 +:10C44000771AE37679F96CD91EAF64C83861A443D2 +:10C450009F42712A652BEE5944F1F7D5EBEEC47D6E +:10C4600026E75F666645A8A7B5282ACDA3258CDDFB +:10C470003D05E5CAD07142E4B945D9EDF656E68CE2 +:10C4800027399684FE8A6C17A71B3C41F19EE20A6D +:10C49000652D8D9322F55DBE2E0927008715E304D7 +:10C4A0005BC688F22ED62DE7695C77BBDC95CDF9AB +:10C4B000514B8AEB672311CF6FAB74FFF7F23783D1 +:10C4C000A2633B91D382E7BC35182F0BF37F289BE7 +:10C4D000D1FCA7647339BD0CE371619E191BF5F1A2 +:10C4E000E2595BF4F97E3BF5F99CBDFAFC80467D90 +:10C4F000DE7D549FFF018E3B84EBE178DF18F57001 +:10C500004C510F77D9B81E8E79D4C331453D1CBF2D +:10C51000A31E8E79D4C3318F7A38E625BC511FC74C +:10C520003CEAE358FE9B6C7E3E968B784BC403D26C +:10C530003B7B314C771FE9D22BFC7E09D001DF37E2 +:10C5400033ADB46F1EC71AA48F70BB53CFA9761733 +:10C55000C60FAF8AD3766477C77B284DAB12116FB5 +:10C56000E6668A63AD7A89C7B196E78739D0FED18E +:10C57000BCF2D42A0C0FBD234EDB8DF52F595AB7D0 +:10C58000217C2B6A8ED07DFDE665AE776EE0F823C8 +:10C590003B0C2B892539AA18CFB9D8AEF1688C2766 +:10C5A000676BF5F1E3C67872631CB9910EA4FCF7D2 +:10C5B00094A53511F9FAA73BEC6B71FE9F8689FBB8 +:10C5C0003033EC86780007F193C50F2A9BF1BC7ECF +:10C5D000279BDFCB6E3B06F27A27E7AC4CE75E1970 +:10C5E0004472797B7EAD62A2F874CD43E7D01231FC +:10C5F000A764A5B56535F2B945263A372F83BC4601 +:10C60000F2E0FB2AC90FF8AE56E87AF05DAD50FAB9 +:10C61000C277B5F4F7257AEAEAE3BB5AFAFB12FDD2 +:10C62000F4F1F9D3961D42BD7FEADA41BA7AF3BC40 +:10C63000230C7014F316F2EC3C383F3C285F2EDDDF +:10C64000908CF85DB2A8AD6535E077C9BE303796FD +:10C6500097E0FF015F2C813EF1DE65C95E717FB915 +:10C66000467F0ECF15E7508999F99CB1413A2C715C +:10C67000324F0CB45FD4AF6900BE9FB5E88DF7862A +:10C680003A5351CF18D303F951B2C54371B5E57B85 +:10C69000D2639641BFCD7DB56F91EE4ED61F7968BE +:10C6A000169E877BB8FEF7E9DAE7A328BE4CD05B7D +:10C6B000B2C5198E78DF54CFE3EBD07EA6C606E96B +:10C6C00062537D5C785F4770BD413AF886F004F8AC +:10C6D000E1769E92C3E417696B10EB1DA3F850CE70 +:10C6E00096EB93EF6EB115BC9FEF89FC49A16FC823 +:10C6F000759ECF3E34C085F73A6A0F24ABC8CF4D44 +:10C700003BB7A11E72C5A625F61B82F1A0E97FC426 +:10C7100077D84A3FE0EBF9CBFA82A8E1287FEEB266 +:10C72000B827407E75FDD356D42B4ACD7E2BC567E6 +:10C73000EED864C578E51BB76FA2EF0BB617533C74 +:10C74000E642564DFAE869F94E828047C95865A31A +:10C7500013E65DDB8FF38F9270EEDF03F9E8557C13 +:10C76000A7E4F276250FE37CA679F7588BE17BBE30 +:10C77000A867DC276D6F4D2DEC4EF0E0F7403E6072 +:10C78000A0DDA775DC1753AFA4D0BE9876A53FE90E +:10C7900069B705B2B93E9C63D087DF52B93DAF910E +:10C7A000EF83126BA0DB54DC27072D24E75698F9A2 +:10C7B0003B4F15F0EFEB21F58E5475F45A352E42B0 +:10C7C00047CF3358ACEE3ECDED185412929F362130 +:10C7D0004D577FFAB4FE06FACF0F96131FB95E7756 +:10C7E000EFAF62A9CFA5909C3956FF9DF1F842C6E4 +:10C7F0006ED6B5AF605382F590BEB7285CEFD91BFB +:10C80000B319ED802526AE3FCDD0F8F7CA03FC3B27 +:10C810009BC174FBB04F9AFB8FFC5CB490DF40DA95 +:10C82000DB67E0BF3B813F63E1EDF7D8F11E3FDA04 +:10C830002774F7BB85BF10E78D78A810F6A48A2C63 +:10C840006E4FAAF03559F19D0480BF392E96EAD972 +:10C85000E330AEB25E217B23A64B29CE521FA785C3 +:10C86000FD61FC63E531B518F789B1BC04DF2942ED +:10C87000FCBEC4E3522BD12E14D5F17DB44AB413BF +:10C88000A17DCBF01EDAA17E2E211FF957F5443889 +:10C890004E50F2E8DEE6CE43568CCF9B362D260F67 +:10C8A000F78F91CE247F877D4D71856D6F1D213A65 +:10C8B0006B2B31131D5F0D1E951E6E6735D2DF0287 +:10C8C000D664C5FB290BF62A6ED44BB11EC2A52730 +:10C8D000D2A5012E71B11DE121E1D40E3743F942F9 +:10C8E000C6E1B5F080E247FED8014E027EC6F97778 +:10C8F000053FB9AE059A361EF9845CDF425C078EAF +:10C9000003EBC071A4DF820D33EED734B25F557AEA +:10C91000799CAD913EA65CE17699DBAF98299D3676 +:10C9200041BF3FB11DEE93DBAEC453F9B5D24F25E5 +:10C93000CC13CF856BA51BB91EC98F83FB84DF4B3E +:10C94000B8DA3B4746FBE4DBFD847D72081BA28B13 +:10C950006F16FCD6D8DE18DF2CE503E3B9531C694B +:10C96000A278CB36472AC91D92FF6AE25CD1567E77 +:10C9700041F534A8C767E3D19D439AB0132E8E4C7E +:10C98000A577249297C5C523BE8AC39C14D75FBCE4 +:10C990004CA538EA62A8E70A915B56AD484BC673CE +:10C9A000E4C47D994FFA409E3F716FB7F86130CE75 +:10C9B000A72B2DDDECAE60BD132B0B9331BEE3D363 +:10C9C00075B619FE4EE0F59538372A7EFA219D732B +:10C9D000174C6F45CD80F6E52BF745E1F581B29513 +:10C9E000FC7C5FDE57FBB21FF97D376D7322FC9C28 +:10C9F0009B06A09DD8C261DA2E5794AE2CEC8172B2 +:10CA000047F9B7479E74E2BDF0659678944BCFBC6A +:10CA10000FE7A442E71CC913A7C3A00BF2C345D27A +:10CA2000FB67A715E6417FD479D3A12F57A3BE9802 +:10CA3000D7901180F47ABB66E98F7AC1CAA7499E64 +:10CA400029BD7F5906BE43A82D4B8FEECC9E22D325 +:10CA50006DE23C47B91E5394EB31BE06E57ACCA398 +:10CA60005C8F29CAF5F8BD6A835E2E8C127E4A69F6 +:10CA700077EE53D79A877E3FDF5896554DE7B083C0 +:10CA8000DE055EA284BB913F2D41190AF37F8E2003 +:10CA9000BB037BFF261D9EE5BBC1F25DE051AD20CF +:10CAA000AB85EC931BAED859E83DDD312C46972F72 +:10CAB000B027EAEA173A5374E5372664EBCA6F7277 +:10CAC000E5E9F2B7640DD7D59FE81EA3CBDF3AECBA +:10CAD000265DFDC99EC9BAFCD4A299BAFAB7798B72 +:10CAE00075E5D3672CD295CFD4EED1E5EF2CB957AD +:10CAF00057FFAEEA65BA72F94E7223EA63367CFFDD +:10CB0000C54EA97C2FF9872AA3F7D8461698B89D59 +:10CB1000D1C6CFA3256FA73B42E9E0D6FE5C2FDD4F +:10CB200095E3B9B9FF90E07B98F29DCBBBFA73BC5B +:10CB300026B180C2F5E1A644A463633D63F9C888C9 +:10CB4000C3975D80CBD7FA1FB9CD8CEF475E77785E +:10CB5000501AE4A372C26EA7FC88C3CFA7423E7EE0 +:10CB6000E7AD3C3FF0F0652CF7E744F1FC5446A2FA +:10CB700049EACEDDB7613CCAC81B52D7BAB91DA578 +:10CB8000D3FBEE324578E03D718407A601A0634CEB +:10CB90000F031D637A14E8789E05E605748CE9316D +:10CBA000D04FF1FB6F413FC5F42DD04F31FD1DE853 +:10CBB000A59836815E8AE9BBB533287DBF56A3763A +:10CBC0007FA82DA1F4C3DA6AFAFE716D0DA57FAAC4 +:10CBD000F5D1F77BFB4BFB4340F7DE6857EF8A4A02 +:10CBE0003FA7F46BD655B3E608E41BCDE698CFEC2F +:10CBF000417F65D7760233FB2C445ECB553C2BFA44 +:10CC0000D3F8BD9C749F427C77A468F7217FF820FD +:10CC1000656AFA2015CFB1EA5731D4E60353E7EF3E +:10CC200047DE25E8C397E37908DB8DB2F3FBC9A3A0 +:10CC3000ECFCFEF12873531DD257DDD7CC85F13FB4 +:10CC40008722F9BB1F75F799FD680755AEF07D3E49 +:10CC5000BA1BA37CDDD7CD745F7994D39D80E79513 +:10CC6000CCB7FBFDF14F489C8FF4C3CBF89E7157B6 +:10CC70009A0A505E18EDB0BA908F84C60DA0BFFD21 +:10CC800050E467723E0CC793FEFD2D5FB380694090 +:10CC9000D08F3FCADE94827683D1DFB3BB43E39665 +:10CCA000A4BF5EB9D2ACA25D55C627C971E47C238E +:10CCB000CDD05F7E30FE6894B3210FFD1D75150E3B +:10CCC000EAAF077CB7E6533D8F4AED1AF2D02E3714 +:10CCD000BADC4171B0324EA0875837D4A3758EBBF1 +:10CCE000A2519CC468112781FDD879B90FFB19DDC9 +:10CCF0002D90887160A3ABF93B644F28D03E3F185C +:10CD0000B780F52342F62DCE13FBEDFBDF305F94A9 +:10CD1000A33C1E82EF54A9D7B9445EFA1DED63C946 +:10CD2000BE552078CDF214ED1DA423AFCDF9E70850 +:10CD3000DADF69BDD16E3A59C8F5FF845EDEFFF7D0 +:10CD4000D08B87E3BB17237B9B916E245E249EBB15 +:10CD5000A22389F7903833C2737BDC98E8C7485F19 +:10CD60005DD195A4A751768E77C42BC6A9493A52B6 +:10CD7000AEF077DD4697DBE9BC937464A4838E74D0 +:10CD8000C4E9B2EEFB76EAAF231D05F18FF0F8D7C8 +:10CD9000E9A85945FFD5B5D2CFDDAD6C7C3414156B +:10CDA000A46A77215D145F71BD86F9B96CCC7824D3 +:10CDB00029593EA18B72EDAFAD96E8103A1B25E8DC +:10CDC0006C4917F5653DF9EE85ECFF61ACDFBD639D +:10CDD000FD3785DCF066988C53F138F28606E34621 +:10CDE000971472FA2A4A5149EE28C8E1EF9F330797 +:10CDF00097B35DF017F9F1CD4C3B1A9D82EF947A11 +:10CE0000E97DD2F1DD0CEF930AF9BCC8E0E7BF3948 +:10CE1000E74692CF6FBECA3BD7C373C43DB71496E3 +:10CE2000728DEF907A72483FFCAEEF90F2F76BC7CD +:10CE300089FD9E24E829CDA5B291B1F89EBB66C6B6 +:10CE4000C3E528BE5F3B00DF79F551FE26E6A7F477 +:10CE50001616203962221C4498BF154458CC1F89ED +:10CE600098340BEF1C160C2AE88BDF43DED9BB0D80 +:10CE7000E757A96AFFE50C7967EFF03817DD5F3DEA +:10CE80006C4F233914F7AB25C45EFA069CCF7D6145 +:10CE90007D47E0FCC6F45538BFFBC239FA3A9CDF47 +:10CEA00098BF396B19C376E35DFAB827D9FE1667C8 +:10CEB00001286A5DC3EF96012FF642F8BE19933937 +:10CEC0000EE9E2CD98EBC6E17ADF8CE961E2A9CD0B +:10CED0004A69EE0B7D3B9393E57E088E379EC63301 +:10CEE000C257C2D3084709DF7F019EB539433AC212 +:10CEF000F32ED423D07E6B7F2F2A2115FD9B9CCF50 +:10CF00005644248BF748DF1EA0A662BCEF089AE7C0 +:10CF1000E89AE1CC8CFE763B87D3A95AE643F89E8B +:10CF2000C125A0C1DB60DF63E6B1A6D038E83D369D +:10CF30006D1DE2F5D44695EEEB5F782E8CEC76A76E +:10CF4000FDDC2E5969D21EC5F272D5B5D68DF2E63A +:10CF50009B2A7F47F49B23C95322AF815EB7F077AA +:10CF60000ECAEDE33BC5A7D42F67A57AEEE2F20D1A +:10CF7000D3FD1E452F1B7F0F42BE4BD995BC3534C8 +:10CF80009CF3BD5E36CEAF257E375A851C00FD0C66 +:10CF9000053E9BF4B370D2B71E8CF7EC463C801E66 +:10CFA00043EF4FB5F58AA4F3E9B0888B1B1DE84F1A +:10CFB000EFAD1589DF1D785DBCE77E58C4CB3564C5 +:10CFC000682F62FBD75D877BA1FDE106C6FD403778 +:10CFD00039F8FBF9D7AA9F1FCA11FAF90036E09A6F +:10CFE0007E27A1BB4AF72946B30CF2C317E07C9118 +:10CFF000CFBD31D78CE764C8EF24D0BAFEAFFD4E69 +:10D000000263AD2AAE2BC9A9B0C753AEFD77135446 +:10D01000A157C9DF4F28E2451D7E37E19751453CB6 +:10D020002EDFB1A0D3DF4D4812EF5A33173F37E45C +:10D03000EF261426E8CF9102E798A34E4AF5769E94 +:10D04000A4ABC48F29B9E2FCB856FC5730C27F7B31 +:10D050009C69371EFF345AEBF733B4CF1774B3B85B +:10D06000FDAE8E74F09FF6BB285DE1C9F87B2946C2 +:10D070003C197F3F25492D37D33B90024F33E02F9A +:10D08000E2E906F1FB16E3F0F72DD8BF0F6FC30CF2 +:10D0900078FB82AD1D82EF965E2AE67CBDAB73FF06 +:10D0A0004B9767742EF0BD9B05DF97F61119976BB0 +:10D0B000FCFD24690790F1BABEB11CDFBEE311E4A8 +:10D0C000BFFAA1DA1C89E7CC7113FFBDA4C4EEDA64 +:10D0D00004ECFFEE9C6A05E191C0BC7B16C0FC67C6 +:10D0E000FFC6968CF9D97DF87B912C87FF5E909CCA +:10D0F000DFEC241ECF352D57E8BB6E1EBF353D97A4 +:10D10000EB01916E27C59917E730113FCB9267E786 +:10D11000227DBE159689F4B79EDB039BF1BDCA6ED6 +:10D12000C1F72A514E47B9B8B7904BEB3EB2DB3945 +:10D130001D32DDF99FEDB7EBE29CFB6F77EAF2B9A8 +:10D140000D09BAFA030FB874E579812C5DF9A06373 +:10D150006E5D7E48D3305DFDEB3EF4E8F2C39B8B01 +:10D1600074F5479CF6EAF249ACF51708DF8772536D +:10D17000091E7D14612771717CCCFE613CDD5792E4 +:10D18000FA878C7BD7043D1BF59A3E562ED7D725C0 +:10D1900032AEB7DA857ECAF4FA8D26E2D6A55CCF28 +:10D1A0007CFAB87519AFDEAE07093D47EA1321F1E5 +:10D1B000EA1E9CBF8C576FC7BB783FD448AFBF14E3 +:10D1C0007837AEA38F95DFAFABBBD74AF784E4FCCB +:10D1D0008CF33A20E298B7DA3B7F0F6A472E971319 +:10D1E000BE4EF36ECA857A4F02BB22787618CFDD29 +:10D1F0008CBF3F50F713AB7BB9EBEAE3CD1EC8D72A +:10D20000330BDFCDCDA1F757E95EA01CF74541DF19 +:10D210009B060A39C530DEEC681E1FC7A2AD74AF8D +:10D22000A5EBF1385C13AC6C05BD5B25EE79DCB584 +:10D23000B6E1412C9A65ADB7F08707FC16B4A34D53 +:10D24000180B72621EE886CF2C7AC40172D1933516 +:10D2500066B28B05769DB8DDD737786FA70FE86982 +:10D2600048271310FFD0EFD0813C8EBC2597AFAF7D +:10D2700050FDA6FDBE854DC7FF19F1FF4EE88EE8B3 +:10D2800051AEE37FEBFE85A45F239CA45ECEC4B9C0 +:10D29000D657CC4BC24FEE0B093F79FFC5758FC5F2 +:10D2A000BBD941F7688A302E4FE2EFA681DC6E1FB2 +:10D2B00087B260775E0FF95157F50AD59C68F4176D +:10D2C000B43157B4F32A76F3FFA57B2904FFAEEE01 +:10D2D000D375C5273AF0872EEED775459FF4E71A28 +:10D2E000EED985F0091E2F25F0E1EF6BA2B884D5A9 +:10D2F00091FA7D5C3080F38753621FC3F9EDC8D388 +:10D30000F30986FE8FBA95AAE0130BDA7F6F04BF8C +:10D31000CF5F6921B99B31EFA318A7F197F5167A72 +:10D32000E771B487917C3367A3E2DFA4047FE7ABA6 +:10D33000D86778A745FD86E4C32FD62A4EFCBD8862 +:10D34000B96BF4E50B1DFC774AE61BDFAB91FEB829 +:10D35000ABE8F5830788F3DDCDDC249789388A12A2 +:10D3600051C72897B5F9B9BF11F57295DBB128FE01 +:10D370004E9EFB2EF47785BCC302700DCFC2737C2A +:10D3800085B9D3B8C876B87611F771DE21E23E1CB4 +:10D390003CCEA56D6F18F70F4B3F9CA87FDE7799A9 +:10D3A000CAB13EF676218FC7AF48FF9BD1BFD7E603 +:10D3B00030917FAA6D6F24C539A0DF2B1AE8E1AC4C +:10D3C000694FFCB094E0FCB46655E73732A6DAB298 +:10D3D0007DA44F2EEFABCD1E8071FA66B7DD0DF93F +:10D3E000FB1C87E91DAF09C20E669C6FFBEFFE8D2B +:10D3F000E4EFEAB4F9B8BCDB56C4DF3B01FEC87009 +:10D400003FC9788EC90CA43B488B03C3693ED7EA59 +:10D41000FF9A7A258FFB7FAF8CA0F6DA9AE194EF22 +:10D42000B3E2C17BF09ED16D750B2D180AD0FC8B39 +:10D43000A585E1D0B4B9B77F7938E26D8CD2A9FF68 +:10D44000A276003F5F9A0DF716647A49EC1BC7403D +:10D4500026F89388E75AA6D07E58AC3019DF45FCF1 +:10D460005CE62FD78B7C21CF2F59C9F3CDE27715FE +:10D47000B6097B0BAE1B535C37DA05760A7B0CAE24 +:10D480001B535C377E47FE8579E45F9847FE8579BC +:10D49000E45F9822FFC2EF739837394FE57EBB7186 +:10D4A00021FB03FD76E342E423F4DB85E6D16F172D +:10D4B0005A1FFD76A1E5E8B70B2D47BF5D681EFD3D +:10D4C00076A1F5D16F179A67C36E0AE691DF7926C8 +:10D4D000EBF25341FE1F17B2BFD16F17DA3FFAEDDF +:10D4E00074FD69F7E8DADFC96A74EDD16F175AFF86 +:10D4F000EE1A45E7D7BB5BBC433B77431CD14F7962 +:10D500008AB711E9FEBF22BEFDBE05F545B5711112 +:10D51000D7DBC2DD1CCFF5451CEF267ECF42699DCF +:10D5200049785E6AE5F9421EE76DA41FF48B8DB35E +:10D5300070BF18A6E817C314FD6298A25F6C5C3A2E +:10D54000F78B618A7E31FC8E7E314CD12F8629FA91 +:10D55000C53045BF18A6E817C314FD62D80EFD629A +:10D5600098A25F0CBFA35F0C53F48BE1F7E3E89F35 +:10D57000B304E785F27C5F9D5E0974A8D32B9DBA46 +:10D580003CCAF3A1F5519E0F2D47793EB41CE5F935 +:10D59000D03CCAF3A1F5519E0FCDFF2DD745FB0C12 +:10D5A000E5FAD07628D787E673EB7DAFA2ED6CE283 +:10D5B000C68B47316D8E549E548065FC7DF78FA6D7 +:10D5C000A3FFB2394C498E01CE69517CD3C7415E6D +:10D5D0001371940358AB897EAF0F95478C73083055 +:10D5E0008A5BCDFD3A91CAA3329DED71CB88F7BC21 +:10D5F000BD8C7E8F46FAD7657B3773AA98CAFAC16D +:10D600007CE7F58CE3CB7AC43F43E68137AD31DE6E +:10D61000276FA9231FE366B789DFCBDDB69CC75B05 +:10D620001BE92A4FC84BDB4C7B0EE37D9AD6628503 +:10D63000EE5D6798D9314B3EC2A93A1FE588C48197 +:10D6400031625DD5D7E3EF8EC9794B3B28F009BA3B +:10D650009F38B2B5A9201AFAD17C63E8F771265831 +:10D66000B9FC80ED50AFECEF533C9B43E83B4DC819 +:10D67000E39A8F8FFFCC539378BB70DEEE99A7A20D +:10D68000088E9356281477367227F3E03DE81C3154 +:10D69000EFFE3B032A8E57BC828F27FB2DDE984C72 +:10D6A000F7428B59F338BCD7C2062B0CF9B6841B52 +:10D6B000ACEF28AE2F03B60ADAB1BFEB7DAA5183D7 +:10D6C000630A311E9135327A5774E2E0DFEBD64BB4 +:10D6D000681F4AFDD2B996E953E81DE749BE65CBFC +:10D6E000F1589FE8BBE7D5EE587F0B73A7B8E82841 +:10D6F000A2FBC7723EFD3C7B4C702CB21CD6640A68 +:10D700005310DFEC485C08FDC0CE9F86F8CE735BFB +:10D71000E85DE5C966A785DEE9E8225EE7B243C6B3 +:10D72000EB18E405435C4EDDD20F93D1DEBC38D25A +:10D73000447693C5FB22486ED03628C4D7A41C5427 +:10D740002CE2FD2EAF78B5FB7484FB1E0BF527E3AE +:10D75000752AD2FCC926BC9FD073D3805895E4802B +:10D76000BB07A21CE07BFEF661586F257F57F4F2E1 +:10D770008A7DFC7749857F47FECEE93C11FF559CA9 +:10D78000EB8DC67818F97B6AF29E8CFC1D5369E715 +:10D79000297E7BD06B88DFE227C4BBDF6B8AE9FE82 +:10D7A000BB31EEAA4CC87F8B5658286E6B91413E18 +:10D7B0002C13715957FB7DD39A8106F950FE4E8E7A +:10D7C000A8C3D45E7F40BBB0BCF739CBC2F9C0ACB4 +:10D7D0003D8CFC55B3961598F0BD6AB68FD3CFAC8F +:10D7E000655CCE99F5A287EE6F4AB9F11D21CF4C49 +:10D7F000B99244F07F4FC82FB761BC2AC0794273F9 +:10D800009888634BA474FA151EBF3AC5C1F941F359 +:10D810002BFCDD8D369F8DCB5547197F37CE409F32 +:10D8200093CD7E135E68748F04FA84FC449487A0C1 +:10D83000BF19281FC521BDA714523C649142F78827 +:10D840008CF43EC152FD2AC6DB4ED8CADC3E164AD5 +:10D85000EF40C7D89F4FA1F71834A1E74A3A36D214 +:10D86000FDEC08619F7270FB53BB9D0265557A44C5 +:10D87000FD83E9184F3C1B6D863D69191E8CDB8BBF +:10D88000CCE1E5CF0DFC60FA0ABCFBD185DD42FDA1 +:10D890009195E0A1C97727BAB023A0FD00F9E55D15 +:10D8A000DFCBB3CE09E197CBF3C6BEEBEE1EC4F7D8 +:10D8B0001CC37DCAC5F7A5D3EF1F752517CF05B8C3 +:10D8C000E2FE981DDDFC7DA054F6FB81CC332E01D9 +:10D8D0007F5F52AE8F05301EF30E91FFF6D77FFFAC +:10D8E000E31A07C185F26F0FFC743ABE3B57616FB4 +:10D8F0001E8F645795535D84F1D9413EA5799252AC +:10D90000904FE505F0F7F80EC87BE006FBC4B703BF +:10D910005DDCFF62B053CCCDE1FC9B89F7C64FDCE8 +:10D92000F7C26E3CB7E4FC4F58F4F76A65FAE5407D +:10D93000D3BFF55E89F13EC94F93B453C83F1E353E +:10D94000F1F7137AAAF54CD88BC8AF2CF90613EF70 +:10D950008E04F1EEB1F2B804C5196AAFD2D628FC34 +:10D96000BD822EEC3A2CABF5175BA1DDEC5A2BFDFA +:10D970009EE353199C7E9E02FA41F96C96B5E955D7 +:10D980007B4A108E9FD4FCDCC2F958201DDF3BBAC5 +:10D99000A33ACC8D7C79799EF7EF38EF881C37F16C +:10D9A000A377DD9CBEAEEBEE656EBCCFB8F6D09330 +:10D9B000F87EC3FF037EDA89FC00800000000000CF +:10D9C0001F8B080000000000000BED7D0B7454D588 +:10D9D000D5F0B973672693CC244C42200F489800A9 +:10D9E000911401270981800837C82358C081100588 +:10D9F0004DC28467B46023D51A2D2D03493020DA37 +:10DA000080C120F53150A5685163B56DA8D80EE2EC +:10DA1000BB682948F5FBDB86E18D8FD608B5DAFFB8 +:10DA2000E7ABDFDEFB9C93B9F7662680DAF5757508 +:10DA3000FDE3721DCE3DE79EC73EFBBDF7B9F9F68B +:10DA40009E1CBB7F1863D5EDF96BD33D8CADC9F738 +:10DA5000DBBC7DA0EE72DB7D2EC66E6948B67BA076 +:10DA6000AC4A63B56DD08FB1CEECD9898C7D81BFC6 +:10DA7000098C657915C6A0FF1FF2A1A988B18F6D29 +:10DA80006C2EEFD76C9B65E867A17EACB95573F43B +:10DA900065CCCFF82FCBCA029602C606D8FD4C4BF8 +:10DAA00065AC3E8379D7E430D60F9EC715F0F6F803 +:10DAB00014E8EFB21F5592E085C0642D9CC7DFFDCE +:10DAC00062206376C6340BB4F783D20EFDDB877811 +:10DAD000689E2C6857E1B92DEFD83C06FD2AEC6C06 +:10DAE0003EEE47AE479633C5FAD95C8785C1BA1674 +:10DAF0003BE0DF30C46475D894B4918CADD8A8B83D +:10DB0000E3E0D12297E7FA31505FF4BA8DAD81FAA4 +:10DB1000F4148F3D03EA9DEB14F776A82FB82DDFA0 +:10DB2000EE817D57C03619AC63D19631CCD31BCA78 +:10DB3000209485DDE795E58D1BF765ED86F958485E +:10DB4000B3FB005E8BDC9A3D6558A47D61B3A205F2 +:10DB50005DDDEBE3BD2AADBB82B14908BFCADB7214 +:10DB6000EC0B5C587FDDB66218EE8BC341BE07FD3F +:10DB700042D86FFA40F62AC375C3BEB6E7F0F90A79 +:10DB800074E32FC0F175F343FFF93EA8977A136948 +:10DB9000BC6A37EC3B074B37AD13E04070EABC176B +:10DBA000C6F3D03C741E0B43419B17D7638579A104 +:10DBB0007E833B68C3791634E4DB1994FE0D7C1E2A +:10DBC0007F53B27D38D4ABAD6E7B16C22F0160910E +:10DBD0004AEB0B6E87A35904704971E13C6CFE6CF3 +:10DBE0005777F8548BF52E6A4EB62F363CDF68C354 +:10DBF000F39807EB698B72EE77E1B917E17A4AEC9B +:10DC00000CDFB76A762FAE47C0F7E4ADF1EB592FC2 +:10DC100078BFA5D59603F59B05FEDE85702D42B82D +:10DC2000847215DCF7ADF15E5CE73C7733EDAF0B4A +:10DC3000BE9B011EF07CB1DB47F005BC083080C301 +:10DC4000A216E37946D69348E32E6AA9267A5B6248 +:10DC5000F5DBDDFA756CD99BAB005CE6D5C67B15B0 +:10DC6000803F73FBB3115F4E6DBE3E9BF609EB44E4 +:10DC7000B8267A3D53D247129E101E4B7CA92AE447 +:10DC8000F42BE7DBE4B5D27C9B705F453DD1A5F674 +:10DC90006A3AD2259CEF1A4F6CBAB433180FE6B526 +:10DCA0002F5282F54A773A95F429E952D2A9A4DF96 +:10DCB000476CBE50BA12E13355BD58EDCFA2C0E952 +:10DCC000A038871BC4B9025C5F46B8CAF617043D8A +:10DCD000570C34D23B8E87E3FE449C7BC5C450EE88 +:10DCE000ADC322FDE5BC1529FC3DC47BC4B79F082C +:10DCF000F860FF15D4DF62E0170BBBF8C5AEC6BEF7 +:10DD0000C82F9E55BCC82F56DCBB2FEB0E80DB8A7C +:10DD1000A79C5E84C187CB1EBF2503E0C0AC413AFF +:10DD200037B9AEC59FE7139F58F2F9959C5F84A25F +:10DD3000F30B579EBFDD5B14A92FBAFFA9CBFC9C48 +:10DD4000DF8490DFFCE9A9170E8F453EC28236DFE3 +:10DD5000F0C87E1634FDDE56EDD2C38FEF777DDE40 +:10DD6000D96A3CAF852EBB4785470B1BAA89FFB2FA +:10DD700074E6CD5522E76FC68BEA0645A3F7EA465F +:10DD800005D5AF914F2FDC300BDE8D9C1B4CCCD8D2 +:10DD900028D827E3F095EBFFA3587F87E06F37087B +:10DDA000FCBEA1A6C49E918AFBAD2E04CEC8E68916 +:10DDB000E7F316199F779D9BBB8BCFAF457A39DB75 +:10DDC000C6CFEDEC061BF19FB3BB12830CF6F7E157 +:10DDD0008A5FBE7D1DF4FBE0816DD94C359E1B2B07 +:10DDE000E4E786E5523837D63BEAB97DECD5F1E178 +:10DDF000A58FF2735BF8F45B7FFE9587F6CBF9DDB8 +:10DE0000BD7141E4C70BDA9EA5739CD7B4D196834C +:10DE1000F4EACD21FCEBE2FFB5F96E06F0BDA16995 +:10DE20009B0DF9C417120E267A8052633A3A43B911 +:10DE3000A4A420FE853310FF647FE48FCFC23CB7DB +:10DE4000DD1A9FC4AE88CC9397CFF17E616D720AC4 +:10DE5000CEB7B0B6FA3E3622220FCCFB3C1ECFE93D +:10DE600065018C87747BBCC49BBD82F0D31255EED8 +:10DE70000EC8E7E7F82300773CE0433F67DB130871 +:10DE8000877EDF4EF022FF183C381CC47911BF7129 +:10DE9000DD76E09F0EE8377859F8135CC760C03034 +:10DEA0007C0FCBC4142A595FA86F8765174339507C +:10DEB000E5E5E47CBE7F680F613B4B0D17E1FE2575 +:10DEC0007E9BF1D7CE1E6B1A887C2C9579EB3D1189 +:10DED0007C95E3487C95F81C6B7F575DE4FE8EE7EC +:10DEE0007078DA13607F2997B03F40D6E294C8BEBD +:10DEF000E4FA581EAC0BE6A9FADEF06DEB619EE386 +:10DF0000ABBDD9B5AE9EF6DB32B96F94FD9AF72959 +:10DF1000E9669183D334D04DAF30ACFB6CF3A05E97 +:10DF200028778E2B20DFE0BDE3B7C65B70FD725F04 +:10DF30003B56416758EBCE550E2A9F5C05843784CB +:10DF4000B15DABD2A9FEF42A0F956DABF2E87975FD +:10DF50007E0A97472C9C887A26E8039C1F84389D6C +:10DF600074D40DA27DC9E7522FE87087135374FC57 +:10DF7000FB44AD909B2C7C2FD237AB1BC41E87A9D2 +:10DF80003A9A8F275A86217EF2F5C9F76EB3751239 +:10DF90003F648976CFE34072CEDB7E3F390DE65B8E +:10DFA000DC9293AFC07B9575851D75D05ED990E6E8 +:10DFB00045BEB1D8E5598B72717120C78B72D1D92A +:10DFC000927F6A0BB42F6EB8DC8BFD6F53980FE90C +:10DFD0000BF82743B82D615D3FCD017C6DA9E06B47 +:10DFE0004B915F02BC96D4ED1BEC86F79778E3F378 +:10DFF00051BE2FDDA284E290DE2CAC4941395CEFAA +:10E000009B827CACF341C58BFA267B08F8AB23C21C +:10E010005F37E4F956E6E3F99F07FC83F187A20C2A +:10E0200056715F6D1AEE83813EF238C375FB48AFBF +:10E03000FF7F428FE968399AE819C6E18DFA3AF311 +:10E040006B16E4BB2B845C1B60EF3C7A37EA3389A8 +:10E0500016EF76CE2F7FE7C17DBEA1B2389237A2F0 +:10E06000BFE0A7037E50EC40FEB62271601AE9556E +:10E070005B54E28F127F6AC49A176F2BEB8B78B3D5 +:10E0800018DA51DE6DC587C042D7B65CDD17F16A7C +:10E09000D1C6C90F04408E650B389EB08667E1F982 +:10E0A0009CD99696B21AF5C2E5F59731685FB4ED42 +:10E0B000EE6C2CCF6C8B9F8BFC7E927BD6A464D8AD +:10E0C000EF928792F3559DDCF8A9A0C79B975F9DBF +:10E0D00086F6C0B27FEE7BC43D08E6075823DC3FDE +:10E0E0006D730603D065D9AAF66C1568ECF338FF9A +:10E0F0000E84E7B72C7BAE1B83FC5F09EEC8A0FE45 +:10E100009E3477147A97E529C0770FE0F3F21FBCAD +:10E1100047E3FCC5B27FE63C787FD9F2E792709C7A +:10E120006F6D3E34CA0DCFD70CF6FF0CC7FF40D938 +:10E13000B6C38D8269CBB61128B79F1376D4F41479 +:10E14000DF75F310EE6FA804F758F3D5B42B045F16 +:10E1500059AF0CF6227DD61F627637966E46FAF2DC +:10E160001995D5A13E20F51AF9FCD57CAE0F9DE995 +:10E17000D59C8D7871D38ED66C942BEF27F27AC50F +:10E180008EEBDF443EE57F2C8EEBED56467AF2C2F5 +:10E1900000D7BB590DD06B4664FE03F94E82F34D98 +:10E1A0005B0A0DF210F4129AE77D2B2BC5750CA8B3 +:10E1B000EFCC47FDEB8FD6D0623CD73F825E1BC8C9 +:10E1C000C173E27CEC8FCDEA147C1E0042427DE4F8 +:10E1D0008FCDCF250E7645F4B8C4916D21E473CB75 +:10E1E0009F4F2E50394A117EDDE296FCC935A55F5E +:10E1F0002AE9636EC4D315BB5F99C2781D04616CB4 +:10E2000078DE2CF4B0AEFAF3CF925DB76C17D72757 +:10E2100096B53DFB6A268C734BBBD027849EB25CBF +:10E22000D0F32DCF73B82C7FFEA87DA1DE1EC94B85 +:10E2300059DB0F34C173F9B6B99B518FC2731BCB35 +:10E240005842DBE7735783EA9CE07573FE6DED245B +:10E25000FD707DDE41B2CB973788F1F20EAE1D48DE +:10E26000FB9DD55BAF0FFD2DDF467095EF033CE8BE +:10E27000BDCFE2934620FF0B2D4F6842B9AEDDE2E1 +:10E28000B26259BFDC4572FEA15A4B9E15E0AB2924 +:10E29000095ED4E3EA1CBCFF1D0949DBB1DC93C075 +:10E2A000EB9FC567939CFACCE27B7609F4BB433DB8 +:10E2B00010CF06E19177EEB3403DA38FDF5900F315 +:10E2C000A731A01E15E54748C1F68F5F3C5D88EB7E +:10E2D000183F207C8EC1D26C4ADCBC49A82215882C +:10E2E0007D0E0B1722BEF77989F3EB876DAC09E53C +:10E2F0001DB3FAD86C781E42FE85E7FF0F4B10F96C +:10E30000F11E25F463BDFE555AC0F1D617E76A52D7 +:10E31000609D6539FEFEB88E6B15DB70545D9847C5 +:10E32000CDC5F13FB6F176A9C74E144C384BD86332 +:10E33000F6CC7417EEAF5EC04BD1345607EB5833B2 +:10E34000ECA585882FF7743A581CCC3FB13381F483 +:10E35000DAACCC52926FF5022E8A2715650E7B69D6 +:10E3600098251007EBBD873982D89F394CFAAF2525 +:10E370005EC3F7943DAFFD03F97D3FF5937DBDA0EE +:10E380007FBF3B146F3DF4A93A7BEAE1DF31B49FD4 +:10E3900083F908BFB97DFCA30A50CF3D5B7AD40F47 +:10E3A000E77D8FBBCDE11DC6C7D3EF63CF9DFF488F +:10E3B0004AB144D6F771E7A9A77E39124B07C9A124 +:10E3C000897B549223E6F57C9CEEB1D239753A42B2 +:10E3D00016ECEFB2041505FBEF7B0FD737D1E10A3E +:10E3E000A9A8C73B6C1FE9E50C3B90957CEA72122B +:10E3F0002DEC0B5016FAD6F3F31BDFCB685FDE581B +:10E40000C0EDA41B0B38DF95F09570631E8DE9E518 +:10E41000CCAF5D3B2A992542C7DF16CFCF7E3E9019 +:10E42000F48BB37B40CF88A277CAF210EA19A857C1 +:10E430000CD416161445E46CB994BA420EAB62DCE7 +:10E440007201AF729785C3678E093E026FCC786107 +:10E450003E77799EECAE03AFF4CAA1731CFE43462F +:10E46000E7770BAEA3E31FFB1B81DC58A6AA1DF5C3 +:10E47000E7FC3B9E5F287E08EA159B2DA457A0DE93 +:10E48000877AA2E41F7EE40357D073AE07E631E239 +:10E490001B556A82777D14BE21F9853F01CA11C8D8 +:10E4A000379A891FDCA176BE6251227C624069786E +:10E4B00038CAE10E30FDB13D6C69A3E7CF170C24DB +:10E4C0007CE9CF0E64E073B0578A500F541D3F7E35 +:10E4D000F804889496759C3EEA6DC10797207F28C2 +:10E4E000777951AFFB386809D8609D2DC99C6FB40E +:10E4F000DC9449F2FC6326F8C85C3BF1912B2D9625 +:10E5000000D95BF332C9DEEAEA9FEB09A2FCF9C548 +:10E510003FD5CBB660FB2C07C9DD1694C7506FB949 +:10E520007738B5BF20F9D24D9C2FB5CCD23212B07E +:10E530007D565F0BCED792EA7F1AE936530D3E1116 +:10E540008FFAE4B712D8E3F83C47CB4079FB80E27E +:10E550009BB718DF1FCED71D9E97F0F40E7E3C218F +:10E56000F42775D4256E5FAF934FED4338BF1C1071 +:10E5700038FA20C22B3091E5A13EDF81F87945E4DD +:10E58000BCC02A67752991734B359D9BC4D7800DFC +:10E59000CE2F959FDF1A25F6F9A58AF353EA00BF1F +:10E5A00089FFF3F3B943E5FC9DFD1A1448284FF4A5 +:10E5B000F1EF473CAFBF15CE850462F87684D7C330 +:10E5C00077266AB88F0E0BAB698B42B7EF1608BF80 +:10E5D000134A63A087F9821EE64BBC5D69C2DB70FB +:10E5E000FFE4534E81B7F0FECF9DBEFFC279FFA27C +:10E5F0001C1A850FF7FFB73A37DA3CC7849C78C1FD +:10E60000E13F4A7CC13AD1A0AFEECF3F9D85728AEF +:10E610009DDFD71FE5EEAE54DF093CBFF8C19D7604 +:10E62000F447746474DA709F1DF33EC842BD687E7F +:10E63000DD6B445F17BBCE35CE11361C3FB934DFDE +:10E640001686F7D34AF35F41FC393823CE131745BA +:10E650000FD93B637416EABF87A68DCE427E77083A +:10E660000EF000DA11566F22F241D65E497C6CB68C +:10E6700098F35069217F2EF866E479598FFCF243B4 +:10E68000E09721D053DF07BB0CCBD3609785807F09 +:10E690009E04BB0CCBE36097E1F3A36097617964C0 +:10E6A00095979E1F2A1DD41E467DB959213B68A10E +:10E6B000D56B8FA60F2FDBA5B290E457F0FFCD8F5F +:10E6C000390DF59A877A1BEA4B5A40737044EA8BEE +:10E6D000360C32D4A5FEB8A0E172C373FFCA424320 +:10E6E000FD3F16DE4D1CDEE827FF778237FE360041 +:10E6F0001CCAF01F80FF878AA6DA508E5B1D2CE0B3 +:10E70000047E928C7406EBB7CE51B85E04BF66A04F +:10E71000BFD9F80FA02BAB8BB737CC5382C88F5023 +:10E7200017427B02E01A72027D95B92F3B89FCE803 +:10E730007AE45C2ADAF3412A6F6421A2CB4A16A656 +:10E74000FA7CD6996D87F21635B416FD76AF39FC92 +:10E75000558540C77F9FF6FB0E0589D15B3D04E9D7 +:10E760009BB952C8CE8C754EC021B97E8A5D47894F +:10E770007DC16F0EF27D78EFA073C4EDB7C3397C15 +:10E780005C1D1E85F32F73F81F4DB5D07CCB0A910D +:10E790001FD9FC437AC3F3B78A466721FF60BE3EA8 +:10E7A00006FB28D67C1B71B30087EA52809382F166 +:10E7B000370E9713E51C2E7B37C6D9D18F71629D1A +:10E7C0008DFC94ADCEEC6CC4DB138D53B311EF56BE +:10E7D0006F1C928DF83EBB69EAFBC8B727ABD3AB81 +:10E7E000F0FD63CD1CEF19BB95F4ADDBC5D91DF36E +:10E7F000306F08DACBA7257A03B01F7F202789D690 +:10E80000CB34573EF45B28F6BDB079E9741C4FEE6B +:10E810007FC18638C3F95F5B6CAC97337B04CF72E2 +:10E82000F09CED91763C7FB5A297BF07FBB9EE4F08 +:10E83000DBDE7C5937DE038589A9A8AFB0D16CF443 +:10E84000176AE4FD5870FD6C55F0CD9773237095F1 +:10E85000F8746BA1EF513C1F784C7136A0259203E0 +:10E86000B774F9B3F62421FC363A7F7DDF9508971B +:10E8700077B87FA3D55945FCE3C369004758FFDE4D +:10E8800069D76785757C41BE1F46FA067A3DFCD480 +:10E89000F5C447F695A7511CE6E0F3DCAF7C44D005 +:10E8A000FDC139D757DE0EF2F1E02E95F4BB83EDB2 +:10E8B000E75E41FFCCC136C52B406ED18F7BB07D6A +:10E8C000D0BD23A1FD539F8DDAF7EE7A8ED669DE97 +:10E8D000F7FB62FED3380FF11537CD775CF097A3C5 +:10E8E000C85F86E03AF2A83C88FC05DAE7EC06FE51 +:10E8F00082E36FE1F32FB6FA88BF30FF5CC3FEBA44 +:10E90000ECE1C754C379D73CE434F115239F59B4E3 +:10E91000A19FA1BEA06190A1EE5F69E42F65A585CE +:10E9200086F6C3368EA7070FABE4676301ED405E42 +:10E930005F1D7E9672FC5C5D1E47F472781AE733A9 +:10E94000B3E7001DA07ECF3C45684B7ED85ED6075E +:10E95000CF856DB01D433DDA0DFFA1BC36C3B19C20 +:10E96000598F8575F8BBEC79E8AF5BDF6C6CD7E14C +:10E97000B3195F3F427C7546F0F553763EDB3E901F +:10E98000B71FE81BE17BF8D3F317C9B724FE02DFFA +:10E99000AA42BE067CE533E463DF2DC87931ACE8DA +:10E9A000F8CA45F2B18DCE7F921C6C75FE93F0F8DB +:10E9B00050B9C0E3F22184C707670CC92279169CBD +:10E9C0004BF4305FD847076DBE44F48F1E5ED93BD1 +:10E9D00009DB8F369411DD497A32CF7744E09FEC22 +:10E9E00037DFDA69F3469187FE9546FC613BE71213 +:10E9F000BEDF6EC2B358E39BFBCB79E69BE2BCE67D +:10EA000079868C14FA665BE545CD8764D8F53EE9D6 +:10EA1000B50911BC54910F7C9618267B9CD349B93B +:10EA200080DB91D2D189A447CC39472513F4DCD5BA +:10EA30003EE7DC5BA391DE4A6D82DE6BE8FD32D1FE +:10EA40006E5EC769A1379C14FCE3B8A06BD9AE6EAB +:10EA50006BEC7B03E2FD4AD58BFCEAF0F442C2F397 +:10EA600033C1729AFFC81C95FC4CD3460EB801FD09 +:10EA70004C723D72BEB219E712D18FF629C00BFD60 +:10EA80006265366F9F68FA85191EB1C695F8B3772F +:10EA9000DA90C3B8CF43C847B1D56F84D3217C1F68 +:10EAA000DA676F5329CE6686D3BE6943882F1DD996 +:10EAB00029F827C015F5EF9A878CE7BAA4C569E253 +:10EAC00037BD0DEDB3CBB95E26F9B55CDFA19583FB +:10EAD000FA30D7C59FB71CE762F1E566F13E8ACDF3 +:10EAE0002F48FEA618C6030BD134DF4053FB50530A +:10EAF0007B81B17E91787C54E08F943F47E3BD9554 +:10EB0000D1E27747AE89ABD1E7256C1AC9FD369BB8 +:10EB1000468A78F725CAED7B471AF9E085DE977CAF +:10EB20006F61A1AF6524D269A88CE2D817CBE774D6 +:10EB300072FEA191B8DEB062C7F7A55E5523F4CF8F +:10EB400056E77DAF22DEFD45D8037B67C4111EFE6C +:10EB5000F529AE77FDF5E7A7499FDAB7FB8EA4B09C +:10EB60000E6F9609BC39DD3E2409F1F0585B7D92A9 +:10EB70009EBE65FB19783E7664445EC75AF7979649 +:10EB8000D7CF0A7B602797D737599BA3DA03FF6A51 +:10EB9000393D595D497A88595E9FF67892DC041FA9 +:10EBA000417742AEC8B8CF5F6D9E24F4171E0B723A +:10EBB000B922F9FA41131C4E201CE222F224161C41 +:10EBC0008F8BF7651DEC511BCE5FE6F0BE928AFE7F +:10EBD000970D8A17E35E989E520CE77C604EFE8F7D +:10EBE000D16F25FBCF2F52492EC8793EDAACB4A1A4 +:10EBF000DFEFB595FBB2BF07FDAB773989AFCAFE32 +:10EC00008BA61BED2CB33CFAA8F193B746C3BC65A9 +:10EC1000CDAAD701EF954D2FE9C3F56AB7118F043F +:10EC20005D9ADF5F6AAD8D7A9E66BE57367D35E9A7 +:10EC3000EB87C47A0FED1D63F324767FAFCCCAE176 +:10EC4000B014F4CDD530EFD2864F48FE2C9DAE7A6D +:10EC5000512D79ADA97E26E2FF519FCD82F471A49A +:10EC6000ADF74C8453608EEACD85FEFB9B06111DEB +:10EC70001C6BBABA2FCED74BC0EB747B9C05FD4FF3 +:10EC8000A77D3616227B3944E7F9514319D9C7A726 +:10EC9000114E78FE5637D149BF22EEC73A0AE370CB +:10ECA000FBD9C3F4F1C02341B53418852FF513F314 +:10ECB0001D3FFF43C2AB5783FB08EF8EB6F1798E41 +:10ECC000AF7427619CEBB70D85248F8F4D87F1A121 +:10ECD000DCBB7BE97D98AF777A834AF2E374FBF57E +:10ECE00033B17E688394BB5C1E558BF957EF1E3D94 +:10ECF000A318DA3FFAB98C6B72BA5E20DAAF9E7550 +:10ED0000F8BE62BD3CDB35D7B0FEC3C1E3646F9D86 +:10ED10006E80B7018ED53306D9D11E5EB4CB786E26 +:10ED2000E51B8C74083F577EDF489ECBA206D06758 +:10ED300081651D9D5E4676F4EC406F93BD6DB4E336 +:10ED4000CADBB8BDB7E0E1B2A210D269E0131B9EE6 +:10ED50005375739C619ED92B8D76DA02935D66B6EE +:10ED6000DBCCF245C263B9ACB755D23ACC7A4B375B +:10ED70007963ABAD8A961F5155C4F5B16AA0CB74C7 +:10ED8000F42B33EF0CB4BB8E017CD7C378D576F768 +:10ED9000DF73414F3EA2B2F1E44CF30658B1F41BCD +:10EDA000E8E65BD0A09AFC1346F882BE7E0AF5F92D +:10EDB000A6DE420E0740AE24A29CD1FC4528272E99 +:10EDC000D61F70D1FA7695D0B7AB0CFAF641ECA20B +:10EDD0007B7F6FF9F5E4773A3CE37AD2BF0F77F99E +:10EDE0009D7C06BF9384EFE1E965067D52F7BC1771 +:10EDF000EB813FC6D21F8F0AFE7A44F89DD60A39AE +:10EE0000D320E4CCE1E9C22E4C65442F56ABC62E8C +:10EE1000862F5D481F5BD0D0CF745E4639E32CF15E +:10EE2000B716015EC4A50F353CB7B90B8C7463C22D +:10EE3000CF7E8CFBC1EF46DB1EE05E5FCEF347F179 +:10EE400039E6B148BC64D01FE573F986A1C1F5BCB1 +:10EE50003DA01660DA1B43158DFA5B795D53783D52 +:10EE6000E012EDAAC85FB341FD688E772EEA519893 +:10EE70009FE34CE1ED8822FD009F935222F88FFE24 +:10EE8000F9781E220F24C17BFDE7E4BC8CF48D7958 +:10EE90003B9741FD5745398437E9E89A2FA0F14364 +:10EEA000989F13AE9F40745CE648E2717690B33D44 +:10EEB000E3DF6A6EDF94F6A6C9FA5BF97A62E2B321 +:10EEC000E877097AD56B442FCC42FE938DCE11366C +:10EED000C4DFD92E5F16C201F0BDF276B4D35FB4A1 +:10EEE00093BCDC5BCEFDAA07A78D7EF836783EE2A8 +:10EEF000191791F1C1C580E724173A13F5787B649F +:10EF0000E5710BE6D3FCA19D79311FF1C8AE8A579C +:10EF1000DE8471F6AD5C786F11D2D17ECEC7CDFEA6 +:10EF2000D89267C6913CBB6E864A79DA874A55C645 +:10EF3000F97C82C1AE88F86955C28F4FF758A91D78 +:10EF4000F3AAF2308F0AFD95986F552ACE45E81541 +:10EF50006DE21C9F10FEDA1D826E5A04DD6C127485 +:10EF6000B3CEECAF7D88D3CDA1763004404EFE6E9B +:10EF7000FAC289E487DEC2289E9C334D5D3F12F6BB +:10EF800077799CD786F02B999ECFE13947B1601CE9 +:10EF9000A6AC34DF86F47E796F8FCD477AD62CAA63 +:10EFA0004F9A934376FBDE95658964BF277AB390C9 +:10EFB0002E074F8F0B5992D00E2C243E71E5198BE2 +:10EFC000815EF2430906BA1BFA588AA17DC8964CA5 +:10EFD00043BD8F6FA0A17FEF52233D260C2E30C979 +:10EFE00025AEE749384F56C791DFEA48445E52BB29 +:10EFF000B4EFA4FF4DF6076819F85A93D0074740BD +:10F000001DF3E2D6CDA97760FEC3A76D562F1FBFB3 +:10F0100082E4BD23E77907D2098648314FAA49CA5D +:10F020001FE18F671A33AD6B03C378E9915246F83D +:10F03000143F9829182F6811E77DBF9817F86A893F +:10F040008DFC6EFC1C7B4FF7513FE633DAA9E94893 +:10F0500067058827FCFD27C4FB3B04BE1C29FDF186 +:10F060009A04C487B98CFCF793D5656B302E78640D +:10F070003A233A690BBD9480EBC77130CFEF57B19B +:10F08000C699F3DC1F6FC1F5ECB4D338658F815C92 +:10F09000043C197AEDD10FDE46F06D71EF8B67DD20 +:10F0A000F5E9118F695E044EDE1916B25119D2903E +:10F0B000FFE49D39A0615C6FE85F777EF034C3792F +:10F0C000B95C6812F86DE6AF3F7DFC170BD663B9EB +:10F0D000636BC17B507E63CD839975503EB1E65B17 +:10F0E0005B6FF344FC9F3B662EDDDE02F521DFFC07 +:10F0F000FE93CF235ECDFCFEFF791ED73BF31F7F2F +:10F1000076C1FA2FAB4F6448DF727DE679D259930E +:10F1100082F14DE4A3C497AD01AA57078C7A7759C1 +:10F12000A9D3807FD8DF0AF02BABFB29C589D3C5D3 +:10F13000FB8766DCADA830EF7BD59CAF1C5CD5D9D6 +:10F1400032C946FD43D81FF824E55DF6EB0F6C0588 +:10F15000DFB707148C6F8382E4C5B86D06B4233F14 +:10F16000671E0FE93BD9127F055FC1EB0A8CFC7B60 +:10F1700056C2B33C115744FE8BFCBE6ED440E2CB6A +:10F18000FD5C4CC3F32D7D618382F966EFFA3D5E31 +:10F19000D20B56B1CD93C0EE1DAAF2FC89BCD2773A +:10F1A0006FC07381AD5AFD059171778ABCA6D217E5 +:10F1B0005C947FFDEE4ED736F2EB1F9869D1EB835E +:10F1C000137FFAD1CF7E8BF8551D4FF865D65B0EB5 +:10F1D0000AFAE8AADB3C0FDF86FAFE8B0E6E27697F +:10F1E0009E2CB2BBBD9E2CCCC3E9EAF77D191FF360 +:10F1F000FE19F9F9EC0A27C50D649C482DFDA411F0 +:10F20000E9717E716D11EAE399780EBD23F1E8F79B +:10F210006EB253DE404049A0FCF25871E79DA372E4 +:10F2200044FCA5F60A5A07AB1D8DE5B9B9F50FDB0D +:10F230003DB1E5558338D758ED363BF3478B0FEF9B +:10F240001CC5F5D07A3C079BEE1C5C7FB801E3BC83 +:10F25000B1CE81598305942FE9700CC67C8E34F1B0 +:10F26000B8D5F983B7505E751CE6F22AADEEB355FA +:10F27000487FD20F5195CEBAE2601ABC6713EFA552 +:10F2800009FD1B6918F5EF2A11FFE9A86414FF496D +:10F29000AB3BFDDF089F8D62FCAA77F8F8766B68C0 +:10F2A0002FE24B95CB4372A7A34F9217EF27B1F3F1 +:10F2B0003CCF2493717C4C33EBF7A809E9D69D969B +:10F2C00050F13B541FE68E672127E28FE2A079338D +:10F2D00057C6517EAAD4AFD2EAEEBE551D61184F73 +:10F2E00041BDFADD0A6E3FA399DB356E8E41AF2238 +:10F2F0003DCBBC0EF95E878DB5A33DA9D3B3480FB6 +:10F3000063FA790619EAC22F66ACDBD2ED063EF14C +:10F31000EEF9B25EB55C0E785247717F1CC243EACB +:10F3200063526FEB36AEA0779D7E19407E21F321AC +:10F33000BAF4A41A9D1D35B0FB7B32EF4C9E83843A +:10F3400067ACF79D25DAB951941711A271FC6218C8 +:10F350008BD3954DF035F14B605B3C2F5EE8A1A05F +:10F36000451AF211A45E29F97387E0BBE19C30F9DC +:10F370000165BE777F78271BDE8F1F9DDC952F8F61 +:10F380007AD091551F533CBD0AF550983FBCE643D7 +:10F39000C37D92A69292F8D1E46F33E63DE8E2A8ED +:10F3A000B45EBFE09B935517E59F74B0042FF2AF96 +:10F3B0008E80D0C7FEE4247D4CF20B337F98E1357C +:10F3C000F2FF6B8B8DFC7F96D6DB144732FAB3CA03 +:10F3D0007DA6F8F63BD30C7C53F29F3B542F6DC2B5 +:10F3E0000A821EE334FB05BF7C5BE88176564BCF77 +:10F3F0001D98F73908F97F1B952E7680CA24D649C7 +:10F40000A59BB9294F268579A94C653E2AFBB25A9E +:10F410002AD319CF8BCA646D54F66707A8CC669DB2 +:10F42000547A98DB82E540E6A57230F351E9636EC9 +:10F430008A7BBF9318CE3A04F09B7E3D233F3C630A +:10F440003FB9518373EA2897754020A4ABC94C207B +:10F45000DFE3376A589F26EB3B78BD84F72FFDE545 +:10F460004F7F141846FC46B43FC1DBBBEA3B6F2C10 +:10F47000213AB5507D0EF687FA8323B569A3015F63 +:10F480002B4733E2A3E70BB56FEAEB0F156A33F4B2 +:10F49000F5978BB46BF5F58F0AB459883FB29E5936 +:10F4A000A895E9EB371769E5BC3FF71FBD63D34863 +:10F4B000DFC50529A338BEE1CFA9FA2B090F7729AB +:10F4C000563CD738416F763C4715E9C8EB88C3D224 +:10F4D000C7F377C2F1AEB0D3D283FD63A2A330F2FB +:10F4E00027C0C3E18AFF665C8F999F280191079826 +:10F4F0006A8C8300BE93FF2CBC92DBE98C456F972E +:10F50000F35E08CF99A6F3DB0E8C8C1B6B1F66FC99 +:10F510003D20F4BC8342CF7B47F899BBF61DB6264D +:10F520009F7244E838B67D6865A7F4FCB2DBBE3F45 +:10F53000AAB4015D87EBE2DC28EF3AE2D9DB68A7E9 +:10F54000050EAB0CF58C4B5D6F69E1940708EEACD2 +:10F55000BF9BE20A725EC1673AF09FA0E75CDE4B98 +:10F56000DA975E078737B73B92C5BAEA27A55C935F +:10F5700047F137AED70FB31D983515D699B681FB35 +:10F58000479390BE3114F6CC9FDC18176B9E6C61CC +:10F59000C8A71A05FF34FBDF364E5AE1D6FBA71B7E +:10F5A00093820AC6233343F1DC0F91CA82F12847C4 +:10F5B0004BBDA594071350DDA558AF6033F3A0BE33 +:10F5C000A045F594C2BCFB5A9E5B817ED84515765A +:10F5D0008A4BD8B42914BF96F9182902CF1BD6C577 +:10F5E000794308C73E2EF2CF0E6B2C28457BB7DE41 +:10F5F000959282B89852B184FC87F52EEFEB784F44 +:10F6000023E0B6509E21736B8E32D057B6DD662D47 +:10F61000453E9EF5ECC82455B7EEE30D67E331CFC8 +:10F62000FD51B785DA1F5D39D1B1C485F711C15ECF +:10F6300080729FFB9886FAFB56E89306E3DD5773CA +:10F64000ACF9B21ECE31A9D46EC05BA7D7588F33A8 +:10F65000F91F6D26BDE0F06891F7318A8DC273BE47 +:10F66000E2C9F364FFCE7779C83F3EB149A17C97E8 +:10F67000F05E6F36EA9BC7EF1D42FEF0862655F816 +:10F68000A3BDE48F0E67B16CBCB753DDAC90BEAACE +:10F69000367CB21ADF1B90E7C9C07106783B33DCB9 +:10F6A0003AFA7BF4FBDF8D4779D78017CF088F18A4 +:10F6B0008D23ED55793FBCDA7DB692FCBBCDBFF70B +:10F6C00021FC93350BD1CC115B301DCF7F7DC96CF4 +:10F6D000A24BBC6F857A4C377DF47358A7EE9E41E0 +:10F6E00063EAC0049C3782BF1AF9CD4F3417927E6B +:10F6F000B4BD6922E5F59BC7B967156B43BDB5710C +:10F7000095A32D9AFE7B4FB62F1BEF619FDC58B25D +:10F7100096C1F99FDC7B533ADE5B5FDC1CC7E23DA0 +:10F72000DDFB9FD8389AE65B8CF7A171DEE659764F +:10F73000942B535B4AEC08B77B56CD7D563FCFC721 +:10F74000257E6731D09FB3F959C213170B0510AE50 +:10F75000BFB94ACB46FDE2442E8B9A97D9A798C7EA +:10F76000177F7B958FEE999CCC8ADE2FA398C71FBD +:10F77000EF2BF6487FF1DB4B53C91E7423BD1E6F80 +:10F780002A4C42BCB5611C1DE4A2ADFDFC2AC4FF9D +:10F7900073150BDF5B0AED8DD3AE3B83E515F65A8F +:10F7A000D29BD91F54A207D00BE9BED7DFE638DCC5 +:10F7B000F5BABC40D41F35835FC3C7D0FEB035A9AE +:10F7C000213BF077DB9E53A48723BE6A3AFCA5DF7A +:10F7D00028A1CF8B7C8FF451747F8E7E8DD75C17E0 +:10F7E0000C318CA32C74443BC7D8F3EBC645FD7693 +:10F7F00012D3E275F383540C915FDBCFE7EBEA277A +:10F80000DAC10CD5687D422F37B7CBF50FD962A48A +:10F81000CF6FE2F91445F4F358EBFD46D0F85E4D96 +:10F8200031137916330DF432546D5B3106CE8DBD34 +:10F83000CBF93FD875CC17255E15E1B3B0F6BE0203 +:10F840007E00CFB5A9B3C93E89B50E7BF080963353 +:10F850002262BF7D23DDB82ED9AF46E05D5C908586 +:10F860006C495886E85E461CBC8FF2FBD38AEFB821 +:10F87000AF894217B234F32DFC79F0BB11F2AC4CD6 +:10F880007C02D160B0D4472CFC7D4DC7E7123773A2 +:10F89000FDF7C41685F4DFF51B795EC4A741A89374 +:10F8A00072C1CF09558B2F84B2E3D2DD1F5CF242C7 +:10F8B000D37D433D06B82D62BA78D29927EF7A1BE3 +:10F8C000DB4F3F7D970F977B77EAA224CEB78E2E32 +:10F8D000C0794E5E6E277F0CFE1C123FA0E3D26003 +:10F8E0009C010FD7EF7E72CB02943BBB1D5E4CAFE9 +:10F8F0005BBCC5D81E97AEDB17E3F81530C0293CBA +:10F900007016D0D191EFFF84EE792720FF447A5C06 +:10F910001947F7BBCC70FE6074D7F742983E0EC70C +:10F92000C4BD0E4957C736D49F54619CB52BED1EFC +:10F93000FA2E82C9FE3AE299A5A5EBE2BDF695FC46 +:10F94000BE25D3DB890323FB97E31E092C74785C67 +:10F95000DDC7EB867731C65B58A2ED2A06845D567B +:10F96000E27B1ACBE31B16D2BEEBDA571E7913FAF1 +:10F970003425F87F867CF3D88641A314BCF762F562 +:10F98000D0FDBF86064B3CF2FDE6366BFC6084770B +:10F990008385E47C735B6AC260944B2E0BC549512E +:10F9A000AEA83AFFFE49C12723F2C397A4D77F121E +:10F9B000043E9ECC13FACF24AEFF28CFEC21BDA38A +:10F9C000A191C7A9A4BEE116F8E316F1C858FA0F31 +:10F9D000321E5C7762D12237F2B5C624FE1D8D45FA +:10F9E00093BC01BC9779B58B91DC1880972350CFDD +:10F9F00072B1E05498477573FDC6DFCC489F4971DA +:10FA0000B9BC08EAB4966080D6AD713A73C07F087D +:10FA1000CF843C8DE1F856935E6137E90DAAA9DEEB +:10FA2000512CF250841EC184FE2DBFDB90786FCF25 +:10FA3000793DD2AFDB2CFC13A03F05E8FE47310B2C +:10FA400022DE324DF3A4F68DD801E877C4F6F462D5 +:10FA5000B6AD5E177F52B457C96F20FD92D2FF201A +:10FA6000FD1C238AC15E4BD2F9237E0DA6A54AF167 +:10FA7000B0CF104F72801D903D398C29FC9AC597EC +:10FA8000D4D3EB2E2EEEF3A397F83D9F064B82774F +:10FA90007B4EF77E19E3B8DF2C611FEC0DF5DAEB36 +:10FAA0001D749F66B2BA8BEECFB78EB4F03C65760C +:10FAB000C08DFA40F218CE776F2FF1B9C7202377A7 +:10FAC000F972106F001E011BDEC3137EDBACDB0777 +:10FAD00026A03EFC5EC6A98DA897071A2DC46F24E8 +:10FAE0001C73565B36211AEAE273216B4124CEB6B1 +:10FAF000DE773680F77ECF5FC9EF1125CC3AB1179C +:10FB0000FDA0EB065BC8CF7E77A246713BA01F87A6 +:10FB1000CAE375AF63BCADC9939282DFCF793A99DE +:10FB2000B733718E0F24F6DDA6CF17E9BC92EFFB39 +:10FB30000125BABEB2F74ABECF8EDD00C85EE4D75B +:10FB4000E2F678607F85E6D2D591F6E0FD1F06B833 +:10FB50003D3D6AF7FE8AC060B29344FBF90AB2E702 +:10FB6000D1C708ED1B776FAE40FBFC919CE8F3DE3C +:10FB70003E8ECBEB47DEF00F407D36BC1BF0A75727 +:10FB8000B4F30D314B318D9B8D71A9F09D7173A331 +:10FB90007D8FE6CD719C9FB4425B5CAF881EDB5AC3 +:10FBA00061D65383C4AFCED51C7B85D2AE817F1482 +:10FBB000013D24B3E8FCF2C2FAAA371DF5CEFA3BA8 +:10FBC00095B5C83FEA415FC5B8609ADB4EFA6A4313 +:10FBD000F2774BF05CCED53037DE5BDD0E6A1FF27C +:10FBE0002FF4ABE27DD4A9759CCFF8DDDCCF0A768B +:10FBF0009CEF6AC4C70C2BE1A3D45FAD159CFF5CDE +:10FC00001EC7F38B3B925DE4374DAEE3F9C4CE00E3 +:10FC1000E8B3B8BF493C1F5883FF900F49FDD63564 +:10FC2000CC6AC80BB69BF286ADA63CE16F8F31DA89 +:10FC3000338945237BD4AB7E0DF62FAE730FF01FB7 +:10FC40002C43600763F912D8ED58BE0C763BC60D05 +:10FC50005E5D9547E5EBABBCF4FCCD55C5544EC895 +:10FC60000E535C91FCC8E4BF612185FC7812BF5E35 +:10FC7000EE3F11F1BD84B76FFFD5CC4703FDA13D29 +:10FC800055F40FE45422FE75D5D9B595D8BF2A9DF9 +:10FC9000D79D636754223E4E9AACAD1B0378D2C702 +:10FCA000E2AB6EC4BE77C579A3D9F77DC7CAFB5E48 +:10FCB000D1ED77869F3A30FA735A894FC4F0E73C0A +:10FCC000A0F075EC7D61F343E887EA35CBEA433C6D +:10FCD000CE1E68F4F37F3E86D3C5D4B19C2EB3DF2D +:10FCE00004FAE801EE923E62B5D7EF061488425757 +:10FCF000B26C4D64E3E99E75A57D6EB47CA66D8201 +:10FD00006FC61CDFC53C715744E8ADDE65A6B73051 +:10FD1000C577CFD57D672FCACBAF4E6F8CECC37044 +:10FD2000A546F23A0CF486FC5CADE1F4A65AF93D26 +:10FD3000CBAAFDDC3FB21DE90BCED98FF406FF9CA8 +:10FD40001AE0F53413BDD59BE9CD65A4B730D21BBD +:10FD50008C971CE0FA85B3A2ED6BA5B73F7F457A7F +:10FD6000FBCD5561CA6BE8C8A9CD40F8B48AEFDA7B +:10FD70005D2A1DDE35D6CEE5C1708DFC020D388EB4 +:10FD80008BF4F90DF8BD94A9FD575B53007ED35356 +:10FD9000F3E97B023963FB0A7A38E0427FCD024DFA +:10FDA000FB94E8EBBA33744FB18F85D36FDFB1AFFB +:10FDB000913CC86A3C386B2AD2DD9D2AC949F3BE02 +:10FDC0006E1A2FE25B0A9F174E2E431FD77308BA95 +:10FDD000F4DC59AF38501FAF66DEDC1CFA3E0C7DF8 +:10FDE000B7E6870D7F73E3B8378D4FA1757956BF9E +:10FDF00093ECE7FEB574B4DFE86A7241777A845F0A +:10FE00009BADAF819E93C7F6E09FBD10FFB84FE852 +:10FE10000F78F4A837F8C53D4C19178949CF263F0C +:10FE20006E4CFFE1700E1FF3FB67855CAD17FE5F44 +:10FE3000B3BE27F73FA4C43F0CF7A7B85EE57EE04A +:10FE40003DCC83EB9471B3AE3C23A91F0658B01E82 +:10FE5000F56D2BA8327DB9BA81E375E51F093DF137 +:10FE6000C512FF681C771BF3EC45F9E6F2F27C053E +:10FE70006789564CF0FC927AE086124D1BDB035EDC +:10FE8000BD38459B34B628763B3B0FA38C8AC4B55E +:10FE90004A6659395FA853041F70ADB543BD351983 +:10FEA000F89907F576BE6F37F00D0FD919463B620A +:10FEB0000A3A23916F201F21E06AD3312F32498CF7 +:10FEC0001F91D7E157502F0D036C3741535280CB10 +:10FED000EBFAFD9CAFD881AF505CBA98DB09F29E7B +:10FEE0008F739897EC2F55EBD97EB09AECFB256376 +:10FEF000051F296023116ED916CFFD63E079E183D8 +:10FF0000930F8D81C7450F2FEE8DE274F4B6C63284 +:10FF1000FC6ED74D8F9FDC867ED231FF15C7C4F7AC +:10FF2000D128CFE05F2867E85CB6ED79B72260455D +:10FF30007E151D8F0BAFE2782CE3AC3DE07123E121 +:10FF4000B188735E021EBB2E80C7CD884F51F078FA +:10FF5000E357C4E307715C0D0F01E34653B41FF58B +:10FF600084B75B276B8FF6D4AE8B1FF0FC21564312 +:10FF7000F6B38C5F9AD7D388F235B707BFD4BAED02 +:10FF8000F168CFD6D76C7F03BFDF585FC7EDEC8E2B +:10FF900044AF03F38D03BF57E9BB54B1DE47BB3B0E +:10FFA00000CC72E8553C0F7ADF9D71A109304EA656 +:10FFB0008BCBDB4C97C630EFDBEA0EDBFC89A8AFBE +:10FFC000F918DA19F6540B0BE8FC3157D80E905C8F +:10FFD000EE00398EF401F4C9E92D998F23E5F384FD +:10FFE0003BEFC7480EBBAA13E4A08E4EDED85D4C93 +:10FFF0007EB8C4A2E757E07B6AA5DD83F83DE173D4 +:020000023000CC +:10000000909BBA794A4013D1D7AF766418C699EC61 +:10001000CE31B44F4DFF86A1FD1AC0173BC5B1F9D3 +:100020003D3FA9D74CF3E41BFA258B38C737F3C6FD +:1000300018C6B3AAE7378D46FA177AC438F80FE91D +:100040005F35E90B667DC2AC3F9C1C6BBCBF32C206 +:100050002AF2D0AC3C3FA29539E8FB12C007E9FB7D +:100060000555913C01A29311F6F0F67BD0AF32CF4B +:10007000E10DC0B386DDD7A4578F8CF8CF5AEBB80B +:10008000DFAFBEDDB10DE961ABA04B495FC3128F9D +:10009000CD6324D7ED0CE5B1995E65BE93F41748A6 +:1000A0007F8252C3FD0CADE37378DE91E03FAD1566 +:1000B000DCFEFD91128A570671BAF4A444BE339750 +:1000C000CE94C0344EDF5A8A2855918F2AF35E7140 +:1000D0001CB4B3D3F97CEC759E37B9FA7BF8BE9BA0 +:1000E00005FA0B7F46564AC44F81F909CBF87B814C +:1000F00069E2BD0122DFB2175F7F68B2986F049496 +:100100006AAD26FCD37E2AE3301E0EE540C59B80F7 +:10011000FE8F41AA8F022D4922BE9E29E2E94E257B +:10012000C499C797E42357001BC5BC0496C2BF13EC +:1001300032F1A72EA6127DD8B7A33CBAFBA8F77759 +:1001400098AADB90F8DDB726C0F3A6DFAB5EF49388 +:10015000DE9D15780FE9DA0AC81020BF96AF1ACFD6 +:100160004D9DE3704F85F7D4C0B6D518DFBDC21ED4 +:10017000DC4BE7B9268EE83D0CEF213E6C4D043A8E +:10018000457C454FD7A8483E908C6384C7781D288E +:1001900047C3D88FFB9B0DFECF28F926E42FB58AE5 +:1001A0007A836B3BE9EF6B53EDF8E54CCCEFC9AECE +:1001B00043BCEC93C0EFD3321E371880FF18A4E382 +:1001C0005BEEE87E4DD0D7080EE1D54BD37BD2BB9A +:1001D00062C6515C96903DE9E2E3288D375F170CCB +:1001E000E9D629F7BDD6B55D59C02E657E668CA3CC +:1001F000D4302D7E4494384A38A8E03A07D4F038F9 +:10020000CB00E1AFFFB2711475FC978BA3C8FDCE94 +:1002100010FF9E0E882DEE0D533C81CECB12599FC0 +:100220000E7E8F113F22DC102802F56B45FDAD5D7F +:10023000073F7A12FEB97FE74BBBB0947ADC2CD132 +:100240003E73C8677B30776BD6BA15228E658C3FBC +:10025000CC00AB4EEFE7C7FBFFFAFA2CD37A265A55 +:100260008D7182492E63FF29A9C6F6D2FE71DDCEBB +:100270000DFDF2B45FA5FB7EEF76DEC7F877A374C1 +:10028000E7A05EB8EEC0BC398CFB78BAE3893E0EBD +:10029000E07BD1CA524622BE58482FDD1A58BAB95F +:1002A0001CE8672DC851CE8B3D06FA8BC43D4A35FC +:1002B000C427E9EF8F454FC75C03C9FF3FA06E6FAE +:1002C000DBA4DEAC2B0ED094E0FFC5958037035C39 +:1002D0006715D44306D4BD4CEDD7CD2BEA118F72F0 +:1002E000EBF6B54DD27D0F30D7EAB3A0FD9C5BF79E +:1002F0002A3D8FA9CF77E72394B7962BF042E605E6 +:100300006EC5BC40807B6E8DF8CE6F4BCFF96F52BF +:100310001E36E8F2FB2899C1A330FDF852EE75F3C2 +:10032000A733EEF795F375E5059AE6ED927F6E2E0D +:10033000FF9C25FE0E845FD7BD0C718F03F61D3523 +:100340000FF4E49522DE143B8F8DDB9D735E7F0FEF +:10035000C7BF64BB33C6B813B2C395D1EE47FD4DDA +:10036000F8AD3AE2C359E837E8B045D7EB3F9E34E1 +:10037000E51F57F660C761DE2CC232D63ABF6CDE8D +:100380006CF6180E2F196F95F9B3322FF642F9B3A8 +:100390005FD50F3F44F8033AAF64DCCF6F8A4398D0 +:1003A000D79B33AE2BFEE019D743FC41F67F2FC31A +:1003B0001ED52F5E3F5EE049F7FB47941F0AEB4DC9 +:1003C000D5DB41F23D99976F1E0FECA2C2713A7FC7 +:1003D000A07F752EF9FB74F696CC8725FA68157EFA +:1003E000882E3A30EB85221E62D60B657C44A9E04C +:1003F000FE09A08F89E3FA70BD0BF3D2A59D27F308 +:100400004965DE28E685523CEA4BEA555FBB3DB5BF +:100410007A32E575D5BB27BEFE55ECA9E5E38DF62E +:1004200094DFC5FD0E7EB4A78677B7A79A4AFC373E +:10043000E13999EDAA233FF890F263C10EBD99F01E +:10044000EAABF209937FCA3186E3B794D3D29FB661 +:1004500077B0C5E0779DA2AEDC4BF9E235DCDF92E8 +:10046000A9B5919D6677D93DE86FB14EE274641BE2 +:10047000C6821A8FF3927F45E695A5B8B83D65F61A +:10048000CB483B312CEDC400FFAE4AC77E1EB7758A +:10049000A2BF053B9672B926FD2DB654E16F31E53A +:1004A000633B4DFE15B3BFA5659CB0BB84BFE51192 +:1004B000C5730F92FA735B26FF1641F1F387163B63 +:1004C000D1D4FF65B0F19BC2DFF2A00BD6B7FB3DE4 +:1004D000A3BFC51CFF8A12F722E7D59BE3B653DC06 +:1004E0004DC257D2ADF46765D6F1EF024C51772972 +:1004F000C85F5A5D1CBE2AFAB35223FE2CE5998FC1 +:10050000BAFC52981FD73D4E5EFB06AED30A0C676D +:100510007D34FF9680AB391E9554C7FDE35F973F4E +:100520002B34CEE8CF2A78B0F07EFC3EF1C887CBE2 +:100530000E61396ADB777ADF0065F1E3F79761F9DD +:10054000F737C239A8779AFD58CFE0C78CFB74877C +:10055000AF198E124FFD35124F5D76A2DB0A0E47A2 +:10056000339CD2348EA7B980A7A02274E15F4732B2 +:10057000A7CFCC49DED7D1BF3660989545C3636B12 +:100580001DBF0F2DE1B855C031A56609F909CD7819 +:100590003AA0E5D2F0F38C097E3FDB52780FC2ED32 +:1005A000F987CA7E8BE52F82DF7122DCDA1FBBFF61 +:1005B0009B027E19F45D5C13FC26C580DF042FB717 +:1005C000AF274FF4FF1DF9F335C021D01FB2BDA9ED +:1005D000C0618C0319F969DAD7E49F0A77F153F601 +:1005E00076EE25F0D32D26FF545A80D34D5AE028BD +:1005F000D16726D0673CFAAB6AB81E09623FE8545F +:10060000D0E6E6FC55CA35643916103E5BDD3CEE9B +:100610001CC54F19A2EFF69AF8303A70F4780772B9 +:1006200035FBAA3E1179B7B586C7D15E9BE4F3E0EE +:1006300073195773966839577D35FFE337AED2F992 +:100640001F014F69FF2AE03B7EA7FC6A902768FFE5 +:100650005B6BC236942B5575B72A7E285F1CCBCFB7 +:100660003F2DDDCF30CEDADD5F174E44BD7DC2E0D9 +:100670002E7C28BE4A870F57DC79EE7EF473C5C204 +:1006800087CC18F94A17C6878906F9DADA850FB5D3 +:10069000EB2E4BBD787C68477CE8A3C30741FF691C +:1006A00035E107917EAD021FAC6EE063000F15F1DE +:1006B000605824EE29E9212CF20FCCF0090706C579 +:1006C000C84358A114F7B0BE8BCE3F10F1D07A11B9 +:1006D0000FF5D7F17CD98E3BE3A618F30FBCB4EE2F +:1006E000A9AE5A459FC71F254FB616CF4FC63965CD +:1006F0005C73F244DF0AC49F0979FC9CC3B1E34CEC +:1007000021BCDF0AE8E736E1F9F708CFE5FD03A1F0 +:10071000C7BD36495B89E38EB00729CF19F4BDD533 +:1007200058DFBAFB49FEDD5CE1879479795FD96FC8 +:1007300096640FE27D49E9376B4DB46FC7F3AE663F +:10074000E1C9F4BD5E8C53A0DFE9DE38CA6B5CA85A +:1007500080E10DEF7F7BA27F33D11FF3513EAE7F4F +:100760008EC38D7A7E43F29474E41B556B5592EBE5 +:10077000B1EC1B496F55C06F88DEEA38BF4903FCF6 +:10078000227C0B28C46F3281DF70FEA331D4EBAC26 +:100790004877AEEEFCA6B507F85F24DF790AE11CC6 +:1007A00085EF3C83CF757CA70DEB5F16EE7957196B +:1007B000F90DC60368FF485FFAFD9BF5D9AE7D1BB6 +:1007C000E94BD2DD7F009DFD19E11A85CE8E209E7A +:1007D0007D053A3B1383CEDE37D1D95FFF4DE9CC9F +:1007E00032BEE8C274B659E095CCDF967AC550B5F2 +:1007F000ED6C2ECEFFBF9CBFFD1D915F77A1FC6D00 +:10080000FC5D8CFFD49CCFFDFFFDA9FFB1FE54FF22 +:10081000F83E5FDD9FFAEB2B3DA4E79AFDAA0F8E11 +:10082000D66E1EDF831F4EF269ABE4D3C08F91F703 +:1008300056013F43FE9C56D1F9975F727BD3EBF490 +:1008400090BFE10E1C2F53F06B335F06BDB36EFCFF +:10085000D7E1978CE16FF857F90D8788BCD20BDD93 +:10086000B71F32CE23FCAED1EFDDD70BFBBE1EC6C9 +:10087000C07B7A5BEFB4071B60C1FF1CCBCF674422 +:10088000CD75D72091FDEE267B42B807BB49FE3DD2 +:1008900088E655FE174EE4EAF7C7A2CAADAEFD9949 +:1008A000F464BDDDE4B904BBE9FF8E37EAC9D61AAA +:1008B0006EE75A41DE515C5F2B0E21BFCE0C286DD6 +:1008C000981AEC4FAD55500EA6D5F8281FFE52E3EE +:1008D000FA663C8A15E7FFBAE3FAE6BC817F9738EF +:1008E000FFB1F1D1E3FCD2FF6A8ECB8FB037979284 +:1008F0007CADB4E05FB2600DBB3FD87E0F9EF73C8D +:1009000007DDD330E703C48ADB8F48B1879D0363DB +:10091000C7EFA5BFE0115BED1B68873FB2DA42E786 +:100920006BCE1B1896C8F3C75BC7AF7A98F27FA44B +:100930003E5C21F84C9D6247FCF7570489CFF8B51F +:100940009DAB319E9CE6626DA867B58FE7F4A2A6C9 +:100950006BC467AC157EC22B199FA8CAE6F7E6E206 +:10096000057EA9836BDFC2F1930FA85E8C6FDF8BCE +:100970005D816724A2AC443D628C85F2225A945A70 +:10098000F27B342B1EFA3B1EC9C3DCA41F3D9DEC39 +:10099000FDC35CCA0FE57F6F64DFB4EFA6E3FAEE38 +:1009A0005EBD3A1DF5C08C093C1F71D3B453950848 +:1009B000675B1EE87F0A9586BF4B2BCB8F26F038EE +:1009C00009F005CA4784756FA1F8FB603BF9D9545B +:1009D000ED81EF201F502F9B4278DDACB8E72DC092 +:1009E000F3CAB5931ED3903B6AEE22D8D7BA3EFE27 +:1009F000A61C3CD7E4C1B4CF86E4BE49A88FAECBD9 +:100A00001A48FA6793524BED812C0BBDA78AF8FC6C +:100A1000BADCEFBEBE18FD59D9FCFE674BEEA9D774 +:100A2000B15FCB18FEC76CCCEB55DDC67B52F8E14D +:100A300023E4DF6A7F0BDD2F54455C5C35C59537B9 +:100A4000C87D8AFB2BF1826F55E5AE994BDF4F488D +:100A5000B5BB11C91A13C3E5586FBCD3C6304EC716 +:100A6000ACCD063DAD7E95310E617519D7D3D475E9 +:100A70003FE1D5F9C8671A15510FFC82D7B19D9295 +:100A8000FEDAE623BE34C6F3FA35BF79723EC511ED +:100A9000C5FA6C727D7DF8DF5BF97430A3FB6D5590 +:100AA000B670D4EF0B5F685DDDC7DDA48971D9FF37 +:100AB000E6B84DB93C4E641E57F6339F9B6E1EA69A +:100AC0005CD23CA7CA09FF0EAB0CF98C793EF3FB54 +:100AD000F2BDAA3EB349DEFDABFAC782EBF2095D77 +:100AE0007FDF8575C52DC43D3B8F2E3E563F651477 +:100AF000DD8B6D556A896E02C996A8F9BFB1E947C9 +:100B0000373E0F8E10BFB5728833B52E9EF2382453 +:100B10003DC93C0F6BBA859E33311EF0E157491F2A +:100B2000D2BACE8BB9FB46C6552BECD4DF7C8FD81E +:100B30004CA7323F84DECB89B45BC5BCE6FC109782 +:100B4000C6BFB7D25AF900F9F32F354FE438D22790 +:100B5000C18D915DD8F05FCD942FC5DAF9F3867C15 +:100B6000377DE770BDEC97C828BF499E83539C032F +:100B7000137691CCBB89969783F65CBA84B9870DBE +:100B8000C67D36CAF73D3E0DF9E53D578CC8C7EF27 +:100B9000773EB873D313680F6DD9B5E67D2CE38724 +:100BA0008DA0EFA726782D5EBC9FE5BAB1BD1D399B +:100BB000E4DA618B9BE938F5E74AF75315CD0DFD73 +:100BC0001D2ED776E4BFCCA1D077AFD41FA605D118 +:100BD0006E4D5F64C48356C5DB17FF3E6660A3425B +:100BE0007A177E6F40DF6EF718EBC7262842BF34B6 +:100BF000DA31CD31EE750DD5B8DEAA9AEEB56EB20A +:100C000079E8FBB99BD6A9A40F6C1271A5F1DADDC6 +:100C1000F357036DDFDEC8FF9E706B893D88F75385 +:100C20005B13DDD7CDC5BA907F32BEDDFC8DCB82A4 +:100C3000FABFFB9439C14378B8B1A46F06E371F0F1 +:100C40000CDFF0D878F165CBFF0132DEFE59008071 +:100C5000000000001F8B080000000000000BC55BB7 +:100C60000F701CE5757F7BBBB777924EA7BDD3C9CC +:100C70009C8C6C56B6146490E5B56C9953B0A3BDCA +:100C8000D3BF9371E9C5FC3333B67BC6C6214D266D +:100C9000114E494C42AA333A59F21F84AC24953381 +:100CA0006D9AB30999CC8401259DB6860073024ADA +:100CB000288144492990690684096E483313A7C1E5 +:100CC00089D2A1A5EFBD6F5777BB3A59B6E34ECF96 +:100CD000237FF7ED7E7FDFBFEFF7DEFB6E8DDAFF60 +:100CE00072DB7A007855361ED6B104154C3FF0E71A +:100CF0000319FFD3F06F09007D857A2AC57B052093 +:100D0000FF810470F57115F2767BFCFB6E4718A02D +:100D10008D6A63905A8DC5E48D1ED800E0B7DA5C09 +:100D2000234FB6AEA0F95E93E1617ED20FA94AECE3 +:100D30004B9F8E42393480135C2DFA284B6855F84E +:100D400059017030B2F54734BCBBBD5DAAB969B377 +:100D5000BE85E681FEC966805551E7FAEC76A73A72 +:100D600070F13500BE1CE4BD412AF326B450396D44 +:100D70004A589EDBFE196DB3BEF03C3E281AB79E62 +:100D8000C603DEB75C4C3F7CEE853413EFFE8A96DB +:100D9000DB01F73D74830AB25482CE8BD455253FD4 +:100DA00025E13AC7EFBDFA468800640EC9D088E352 +:100DB00078A345EDF02FF5D47A9809887564F87911 +:100DC000D2243E053BBCBC5FFAF89730FF0088DFB9 +:100DD000FA8177641CEF4B49553F8CEBFD526AEF6B +:100DE000576EC17AF625D990F83DFE87FCBBC79AAD +:100DF00003C626581EAAFCA2FFFE53F7BDF922F136 +:100E000028A9BE457403AD882E2BB830FD1B0AF30C +:100E10003D183B3DB212E9901D293DFE1DD5FAA7B4 +:100E2000885E369D171AD77E2FEF9F9AEC5A57A8E7 +:100E30008F94A77798C887D180014074D8FF1CBFD2 +:100E400087F52897B50BF31329CAF47993BE62BBD3 +:100E5000AF759A7B4CACCBA770E96B00DEAED46F5C +:100E6000DC8AAFBA236FED20FAEF097834E2A3DD14 +:100E70007FF0A817F2012204CE8B72B70566766C5C +:100E8000C576D0E0653997236BF9F9EECA94E2C1D3 +:100E9000F2F3E60A9617BB7F1F7C59D987CFD77824 +:100EA000B557494EB211895684CF9180B8F4CD0A16 +:100EB00098412C7BF5B8BF1EC74D3E491301748481 +:100EC000C623E0016879E2785DBA99B6614E3721B0 +:100ED0007F4216BBAEF54DA73A71BCC19765E37E64 +:100EE000AC87027BB700CA91F4182E969E8720E744 +:100EF00043BE2B819E77E9F9A6B3005D45F2D4315C +:100F0000EB87AEA6423D8E2317D73BFDB58EF6DDAF +:100F10005ABDE3BD0CA691473AF5465739DA55B6A6 +:100F2000ADD768BD7DFA5AC7F31B9ADA1DFDA14BF8 +:100F3000393D83F58DF88FF82E83A8F37B5C77A07D +:100F400019EB45FD1528AAE3FBBF352B2367AEC57A +:100F5000CA75701DE911F2E5E411B23FDBFC06F140 +:100F600065D00BA7A42A20D5CF402B11DBD4234872 +:100F70003FC992D757CC7A960B29F0FC1F580E9F89 +:100F80009CF148C4D727A0F53036FA1B4D9FF2607C +:100F9000932B6948EC1F4541D7914F0D385E592B73 +:100FA0003F3757623D0A52A60FEBCBB05D54882203 +:100FB000BC40EDFC70E00BA21D2CA3761A64EAB0D5 +:100FC000AE19504E7CADC3713E19E67E993EABDF43 +:100FD00055A25FA62A2CC66FA179D15C76637902EF +:100FE0000CF0C9448714C04AB222FD5C5E45ABC216 +:100FF000E70F81D14AF5469861BB84EC97A87E053E +:101000004C6AC2C8E785DD9E514267FCC2EE97D2AA +:101010009782DE2870C6E607CDDB61FE80F4EFD64E +:10102000DBDBAAD28185FB29FB9F75E8AD1AD79936 +:10103000CECAFE5ED61365FFF3FCFEEA78EA551AC7 +:101040008F48EF6F9D4FEF16350F64BFB27130328E +:101050003844F6F1CDD15DC8DFCCE37EA3112E1F5D +:101060003F2E960F39D0CA89AE72FFA5F2013FB864 +:10107000AFC029FF89C32C8C269F937F045FFEE7B6 +:1010800052F8E2E607DC570DD0BEB81DFD6B295FB4 +:1010900026AD647A98D1D602FDB19E5965D12B6CEC +:1010A000F14316655EB69E2BE185F942E355870B49 +:1010B000FC598C2FD114BE6F2DF047EE379978F67E +:1010C000B9EC83B312952B2483F9B5524E79A85EFF +:1010D00021E52DD093633B1D048DF9B314FAB98C2F +:1010E000786776117FB2FB71229447781F4F59C2FF +:1010F00049D6B9980D24FCF5645F9B14C383F5E6CB +:101100004A4F2A8774BC52813CEDAF56810CD9738B +:1011100044063C7EF6713CADF09CC9E231EDA17E07 +:10112000F7FA7359A9307F8B65B77F54F94D6DA6D7 +:10113000B940E7D364BFD6087A78D8FE4CE6A97FD9 +:101140003409C6A03EDF9E61BB8C6CD9292A77D2B8 +:101150008B76A65B26887569E4FB7F209C41E3299A +:1011600058AF88A77BE3354C770884D92ECD5478C7 +:10117000A0142E300957ECB2E6D9F6117D790AD7C2 +:10118000B96BC4F7168D07599F1317B8FBEB1214F0 +:10119000F7B7FBCDC995BBFF25EA01ECAFB9201C21 +:1011A000107F6C6315D179419C497A525DDC4FF018 +:1011B000498DA41977A8A42FD58B8FE375E1177BF0 +:1011C0001C2F0A2E8DE3B5F08B7D4EED85B35E6549 +:1011D000A5B54EA4D76EB03F11A6E74E8B7E7F46D5 +:1011E000E75590E8A9AB44A43D9052496E3F861064 +:1011F0009A70FC8A437B828C17A04B23FA48F9EB48 +:10120000E50FAEBD083A5A74DA997FD7AB935DDA31 +:101210005F096FDBEF5714DEFF76FB4D8CDBD101EE +:101220006820FE5658EBAB38F5FE0019F5FB2BFE97 +:10123000F2E50E5CFAD0BFC8865C4FEF11CFE23802 +:101240006520CEEF0AD2535C77C59367FE9BDADB4D +:10125000EFC17A4F2343D1B89E8AA38C672B82AA11 +:10126000CE38DB2567368E86F7050E0E58D42B1A3E +:101270005722BC6CFB3D3CAE347FDED5163EC757D3 +:10128000F10F2E00CFBB713ACCE173F13E105085C7 +:101290009E1888738BE9B8809ED9EBB6FBD5A8A9B8 +:1012A0007AA3B9447F8B0FCD685708EF5D5107B91A +:1012B00003B8DE91917DF10AAC1FAB01DD87AF86EB +:1012C0007B3E2B11DE4844842885620217D21434F9 +:1012D000BFD79A2FF40BFD7013BEDF5B173070651C +:1012E00070C5AF4C2D8EE3DC59E7374C7C9005F18F +:1012F0003E13F3087F3203AF101EDD63F1C7FBA47A +:10130000C099CC1BD4C399B8C0577B4E7D720BF1EA +:1013100077347CB391C7767BD03E55131E1BF332D6 +:101320009E435CE7C0FDBE58110EC4BF3B8F7B1DC2 +:1013300075AF0B27BE19471C48CCB470E02FE320D3 +:10134000E6C582CE93CB350F04226C4F572BD31EAC +:10135000ADC4396BF3C3C6DF4FD5083A7BDF1374D6 +:101360004187791F3DF7BD27FC3134E081B62574F4 +:10137000FA0BFAF9DA903EF4F43D711E604F5EB755 +:1013800089FF68DD6E3CEC73E161F77A6D3EC80958 +:101390000B276F800D441FC4E78C13ECFDB8F7F1E9 +:1013A00024FAE75D28144F0FF8B9CC0F685C3E3380 +:1013B00010E5F2B9011DBA10803D3FD0C4E50B0322 +:1013C000063F7F7120C6A54D87F9F44129C4FD5E13 +:1013D00065AD59699E4ED139BAB4CBC3AA70EC3E03 +:1013E0000FD3ED1CCA27295F10BD2005977855D271 +:1013F0009333692F96FF738525AFD7FACE4EF9B098 +:10140000FD682D18F763FF2B627B59CE369DF514CE +:10141000F404C8CF2977C409E250EDA877FAAF7475 +:10142000B4EFD6563ADE87E3336CA77AA3D73ADA1D +:10143000D97CFE3AF959B8BE635DA735A26B9FBE51 +:10144000CED14EB90FF9DF42FECFF58E7141DE628B +:10145000909D0E6F77CA61D0C557F5AEF3FB41364C +:101460009FCD84530F16E2AF5B5E6DBA86E7E82A24 +:10147000FCCA2CF99548D7B026E86AEF77D4DAAFE2 +:101480003DAF1213FBBBDCFE6590FCCBFA52FEE5D0 +:10149000CF2D3A2FE25F269DFEA59BAE8BF9977F5D +:1014A0009E70FA97174ACF9DCB45DC2DFC92CC7EDF +:1014B0008B9CECE773B07A5A367AC9245AB8AC924E +:1014C0006C00B6DBD9A6E608671E8399289DE70F56 +:1014D0004A485594B7EA66A396ECCCA321E3D56DB0 +:1014E000841BFB3CC649ECF26CFCD628E18EA103C0 +:1014F00027A27858C103090FCF3B163FC3F10B4514 +:10150000078E5F6069E64AE013BBFD3D435E3E0F18 +:101510001EDCA1E6246CFF60A576EB36AA5BF32007 +:10152000414C7A3FD1F6A11CF929A309DD8A336524 +:10153000A2E4AF7C69C7865A3EAC14ACAFA6E606FF +:10154000EBC9E1322D487E74768747A37DC9EBFF56 +:10155000EA33241F0F48FD871AC87FABF1009D1F97 +:10156000D9D086DA5DD84EDE893086EA3B36BC4E6D +:10157000367BA2463FD440FD430D4CBFA18DB7FA48 +:10158000699ED1D0923E8A8F8C767B984732E18CCF +:10159000208FD3743EBF47D68ACE77E0B805AF53CD +:1015A0008E78F22A9D57843F82F3E37B87432A3962 +:1015B00005F08F895B4E641AF831DBAF2B2C3F604E +:1015C000E78E84C9F68AF004D267A777A6A6D4B9B5 +:1015D00070D08A77CE9D3B51E77A4ACCC3B8401190 +:1015E00033F247B7E3B4F8C9DED893A373741C523F +:1015F00049B29F998087E31D0BED5F0938E7B3C7B8 +:10160000E7F1648AA395996545FBD7ACF8EFCB0960 +:1016100089F1EA0F89EF6D62199125857529490FC6 +:10162000F7B3FD5794DB6D93240F16BDD1AF78BE91 +:10163000F8BC7D2D21E2B2AFCFC911365D52B48E18 +:101640008DAA359EC1718A35AEF8B59B3F171BBF79 +:10165000FEA5B59FD7B6DF745E3F7955CED9CFD7FB +:101660000962FF56BCDB6BF1FF1A79721FC9E3FFF9 +:1016700077BCDBD77979E3DD6F937D229C8776FE9B +:1016800061FC9EFD698EF5054E9D7D9BF57AD51218 +:101690000BBF40B4C1C68F2BA874E90F017DE4DFF6 +:1016A000F85AC4A5581FB7EA99D5625C28D6CB155D +:1016B000E4178838CAB2CE95C2DF227B42CC558C63 +:1016C000E544D780F29D8C86FB280F1C831096BEC4 +:1016D000C8AE0C951DCBF5D118AE6B7C9587CFAB02 +:1016E000F1CAF489215AFFAA4049BD68EE14F66F89 +:1016F00084E495FD24303DA46F92AD1C90F6209FAC +:101700002640F0D9EC0CF17A146D2C7607CA4DCC3A +:101710009207DC0FF7778FFF611ABFCD31FE374894 +:101720004EB3D6E034CE2E1C27DE29D97A95A1F708 +:101730007E6B3EBF3E16235C90E8D4C47B65AD4112 +:10174000FA301E2A3D5FC29A0F2814B3A1808FAED3 +:10175000D82EC601BFE8FFA07476DBE9F5CC57D6DA +:10176000275A07BDAF309CF6C13D7E5993D3BF5178 +:10177000EB9CED5373FB70FA450F48A5D77BB7D5AB +:10178000BE63B99033928FFB4BC8875BDF558A7B72 +:10179000E2B869E207DB0F617702CA7482FC9D4000 +:1017A0003318834CE029DE6FEAA9865333EBC9CEA8 +:1017B000070DF283143F9ACAD6829FE8DEF7627E55 +:1017C0009EA240C6DB3ADFDFC371CDAA5671CE645C +:1017D0008AC6FB8C252772B13F584FEE887E23EDD9 +:1017E00073EC90CCF1A5B17B7DDB4A9DD3F726CE7F +:1017F0009FD7399E423F829CD4C78E1EDA8DF5DF7B +:101800006A1ECDC76DF492791DCDAACFE57552172A +:1018100096D719EB0AF7355C4C5E678171E7CEE32A +:10182000F9799DE39D48A76301915F99CBEBDC1C9F +:10183000B9A0780E58E772D8B2CB957D961FB15FEC +:10184000623FE299B67F3FB286E4ACCDCB720047EF +:1018500027A0584FB66CD7BF5A4DE7CCEB3E681463 +:1018600076CDA4F16CBFD8A69F6A8D9FF8F64B0A7F +:10187000B51FAFF56CE0F120EFF344793DAA55CAEE +:1018800054AE51F372158D1B06439C0F79899EC788 +:101890009158C5FEC1E8EC4F3AAB284E1200834C7C +:1018A000D0685C3B50455F280B4478A75ECF91BD64 +:1018B000EDF45738ECFF689F2AEC6B23FA4BA43FFA +:1018C00053FA57F760FBE1FD658C9B1EA8F308FDFA +:1018D000CA4839A99EF0B5D3EF199F5C21F0D851C1 +:1018E000AFD188ED1F9914ED77C737E464C6DD4E9C +:1018F000BFA84F77FA45BB6B5B5F25BC08435E8E84 +:10190000C76B16AEBDA1C9E92755D6F7BF403865EC +:10191000E790C0C307A3E125BBD1FEADEDD21D7991 +:10192000B25D437772DE684805CEA78EEE50593F10 +:1019300046BD6F1DDFCDB8B19CE938B143AD4D1741 +:10194000E9CBC7BA7C3CCEC40E813F105EA6274BC4 +:10195000BCFF589765A714E073DC96973FF9B8A0D1 +:1019600073B00E723AE1B8BE7D79F22BC7EB704FBF +:10197000F87E28DAD03745F3BF2203EDD32D87F761 +:1019800090135CB40F5FCCE3A093D797EAA7F1E183 +:1019900006D0C9AE7525B14E7180ED2A507CC017B6 +:1019A000FD0BDE6F18EB6558F727C7320AD6FD0D21 +:1019B000E975848B9FBDF7B6917884CE3BA1DFBEDD +:1019C000ED7B533751FBF55E28A3F5812E45697DEC +:1019D0001909449EDFA90F07B3FFD4457C3A684834 +:1019E000CCA29D7D5BEFA2F59C8B94336E1AF3A67F +:1019F00076B13DBAC5AF65F80C9C613FC2FB051FCF +:101A000090DC4DDCFB4E0DE1EFABBA56B0BE95E974 +:101A10004EFFDA0F637C6E6F34A7B753BF8D3195DD +:101A2000321EF04CFB19E6DB449BCFF0E13A26DA9C +:101A300025A6F3EFDABC399AE769755AA6799FFEB5 +:101A40001DCE5D5F4ABF4BEB95AD47EEF6A3B1AD42 +:101A50007E928B83307D33D127332BE254EE76DFB9 +:101A6000B0E4E060F6962685E3592AE7DB95B38675 +:101A70005985A3876653DFA2D8EB2B9D0AB7BBA776 +:101A8000D6939170BCE13E95F568B8323D42F23C88 +:101A90008C72CF7E5204EBA467B511E370D17CE366 +:101AA000EDB736913D7BB9AD8CF1FD6BCFD6DE91B4 +:101AB000C12113F2AFFEEE31F2ABEA54E6E7B0B764 +:101AC000FF75F283326D65BCDEE796A9E0277B10D7 +:101AD000B9E321F2B3E191ED502CAF1349A1A71363 +:101AE0007542EFA5C7B6B31F302EC94C67B3E6A445 +:101AF0004478CC97B4E34E22CE14B7CCD9C4F6EFD9 +:101B0000721C6A699F88A3C69356BC490E64582EFE +:101B1000AF2B7B88F4DF54BC0EFF78D359A7BFBC32 +:101B2000D4E52FBBE3515BBBAC78841577B2E532CB +:101B300068B5998859767ABD2F27E4B0BF566B9E59 +:101B4000AFDF3FB4F0F3F4801F2502E027031AD77C +:101B500083E66F0E54139F06A2FCFC4F379E908ABB +:101B6000FB8DAEBFC5AFB33D9989D2B86E3BE2964F +:101B70008B373ACB1DE789BDCECAF60410EE3D7710 +:101B8000962D326C0ACC74F2D908D38162BC9FA71F +:101B900075FA284E26D6F91CADD3477132B1BE175F +:101BA00006742E5F1C68E2F23B5D20F201B67DB840 +:101BB0000AED03D2A1AB4ED4C91E10FFC3913B382E +:101BC0004EE68B2A1AE9BBBF6E2C2F15D98789CA1E +:101BD000FE9FDE4976BF26C0F2E8DED7B1AE397C83 +:101BE000E8D8D7CEF67D6C77CEE13C447FB433772E +:101BF000B11D42BBC0F36E576FE775986897D82E3A +:101C0000F47FF536B60B5E203977DB817046E877D6 +:101C10005A17F13BFB9ED09C5DC0797238CF336878 +:101C2000D7A93E8C7680E6196E7FEB1334EFEFFE7A +:101C3000500E34C4C48E57D92EBC7C0EA0FA32DAB2 +:101C4000055B0FD73DF71F27324A293E6FBDED9444 +:101C5000A0870682AEDB5225FCC48BE5339817863D +:101C60006372CACCED22EFA8321D16CC3B663C064F +:101C70008505062795A4957704CA3BDAF9C7A2BC67 +:101C800063B933EFA8E6B28C6F7256DEF1D6CD227F +:101C9000EFA896CF040AEBB0F38D43F4A8B6909F5B +:101CA000FF87AEF4CB5D6D853CA32E893CF8D571E2 +:101CB000F387F41C22613EFFDD794A3B1F89F04E19 +:101CC0004A17E5375BF0B93F5CC87FB9F399F6BDB9 +:101CD0008C1675E6E411A4CBE0ED7EC60FF6FA068D +:101CE0001FFFF0EBE948E13E809DEFB4F39976DE0B +:101CF00013D7FD4EF1BAE14960BB034FF84FD0F95D +:101D0000E65E6F453CFD4B6A3F6FDD17985FDC0276 +:101D1000D6F888BB489FDFB4E838D7BE4BF89F6B36 +:101D20005411DF86A0CAFE4EE2DB0190096757AA74 +:101D300027492F76C14C37D1773024705EF6012FBA +:101D4000DB49E8D6997F35AAC9F7216A3E5F661C50 +:101D5000C0C7D9292D48F1A7AF759AD0DD46EB1839 +:101D6000BB792BAD03713BD9BB371ABF12E17C3F66 +:101D7000DD7BAA22FFCF584E7110BDBBF47DA58E2E +:101D8000E567B7F2BC951E20FF2C5B66BCA013BDB7 +:101D90009F5278BC3E1CC26CE5FB4B5D6A98C61135 +:101DA0007EF260E034F3ABA3D1B796E37A95A5FD5C +:101DB000C0A5DD820E9B712C15C7792A9EAEA57534 +:101DC00053AC34CA722CFC3BBD1B6CFB759F674344 +:101DD000210E5621A7F56EB2D78F480A9D8F3E4B34 +:101DE0006E6C3FB13B61D6770B7E9834BF7D0FC8D8 +:101DF0009EFFEA6E61175FE9323F44EDDA681E929A +:101E00004B2D13273D6C49A33C48AC3FAE3CBC90E6 +:101E10000BB7BCDAF2369787B7E450D244BE16E56A +:101E2000AA8DF6074FEB531E89F2EDE91347A8EF91 +:101E300025E6BB3F9D3037D1BA77C7531D54BE71DD +:101E4000EF6DC0799D0BBCC7D1B1BC3F4A79FCE1B5 +:101E500032819B1F8D1B0E7B77B7459FBBBB055EF9 +:101E6000BA1665669AF44031AA80F5F82EC6D1B646 +:101E70007D1A1B487FEFE78D85FED90198A47CD0A1 +:101E800042EBF01EDAC771DDC1BA849FEC0FDAB7FE +:101E90002AAA0FD799D1E275642B859C679689B8D9 +:101EA00005C5D332BEC2FBBDDD32EFA7B30EF224AF +:101EB0003BBE80C8BBF95071753C7F7C662CCFB8A7 +:101EC0002600931462F814E90FDDFF8B186092BFAF +:101ED000599702D26F9F56E84F79D4CEBA7EBE6F23 +:101EE000B9D03872D4EE9FE6FEE3DD1A8FAB463CE4 +:101EF0008E38C0627473D36588E8D6B830DDD40BF1 +:101F0000A69BD03B37BD0E13BD909FCF863ECBFB2B +:101F100083F73B59CF7C1AEE13CB31CBBEC80113EC +:101F2000D29564A352882029CEDE0F9487B6E92C7F +:101F30006B82CEB2D6CFFD7C7506A457135DD24C12 +:101F400017371DD04E00D9897F7EFC7884F0690751 +:101F5000D6A3C27E800FCB5F5BFEA0ADA75BE0C7C0 +:101F60000111FF769E17F3ECA9553E6AC59FDDCFA0 +:101F70006FE92913B84E0707DD2B2BB7323F4E8E82 +:101F8000B4323EC0F33343F7627A6A1BCBA97EB901 +:101F9000F388EEFCA13B4FE8CE0F16E4C6F4D33A2B +:101FA0007FAB9DCE7CB484BCD8E5114BDF8606FCAC +:101FB00025F5EE08EA3BF16FB8DDCC50DEE860684D +:101FC00026CA7233F52EE362E525D9207CA9288242 +:101FD000CF3DCB66988FBD311328DF746460DB770B +:101FE0008AC7FD753CFD23B26715DAA449E30420D6 +:101FF0009FA1F36773B5D95F0A37FD9B6547BA1395 +:10200000A97F257BD5A10BFEC7E2E6AB6C172FD0CD +:102010006E2DA44F8A4DBB8BD6A7D3429F62FB582F +:102020009F46EBFA19678DFE58262455C091963EBF +:102030008DB69F617DB7F5EA3D4B9F3A63422F28ED +:102040008E40E777B0CE64BBF15F963E29A827A407 +:102050004F3E4B9F825AA13DC5C73B89CEF85CA934 +:102060009BE17EC198A57FA44F01BA3F0C8C0386EB +:1020700051EF282EE2D6AF8E06716E6A89B4A7871B +:10208000F0C5B2AD1C971FAEFBCF6AC62F96FC17EA +:10209000F06E2B9FE7E7463C06E9430B01E8D6824A +:1020A0001ED8FBDE382B431E59B36956E2F223B328 +:1020B000155C76CC967169CE5673199F0D719998FF +:1020C000BD92CBCED95A2EBB66510FD621DF67EB1E +:1020D000B9EC99BD96CBDED9555C2667D771BBBEEE +:1020E000D9B55C6E9EBD9ECB1B66DBC53C4D625F69 +:1020F00025F481D26097411F8C0C54921E7CFC7594 +:10210000B6EF9ACA7794B2A10D9C27F22933AC0F8F +:102110002763C2DEF706049FDCFAD09D48AF25BADC +:10212000BBF5610EDF2AA011FD55B03E2EFC80F8F4 +:10213000A7BDA7E83EB21A3559CE109F7CB887F4E8 +:10214000E31271C21CCE5CAE321EB571E6E832C439 +:1021500099F5059C39DC2EFCB2EC033EF6DF764B9C +:10216000E27ED9A713E91B7BD82F1671A2F4CD7E8E +:102170008D707336D4130D505CEFA00C142F401CDF +:1021800092E2764A4ADC67BD407D8EC5857ED8EDF9 +:102190005BE0B4A7FF2270CC1BF4B57D61BB10BE21 +:1021A000D473D6DB29EC8226EC42B6AE7F84F3D220 +:1021B0002EBB609FB3480F875DF85C8F854B2C3D2D +:1021C0000FD789F3324C7601E9F3C51EDB2E38CFE9 +:1021D00059C5C621491B8758762129FA216E779C5B +:1021E000B3C86E3F14E16294A3C19EB6F9F681CFE5 +:1021F000F3A2736EB0A1314EBF25089D8538896763 +:102200007056DF6C943877B25A2BEBC194D209C563 +:10221000F1958BD6B3907DEE987CEEB8DBD9FA368B +:102220003CD527F6699D4353B87FB348DF7A3571B3 +:102230001EE1F9F3F59E12E74FC772339D2AB1CE26 +:10224000477B84BFF1834D16EE455C690418DF9728 +:10225000C40D8FF608BB4EBFD37802ED4F77329393 +:102260005574D6F34749CE37764DCB1446F8486CB3 +:10227000EC154A89A09E3EF6C7E8E9D1B895EFDB98 +:102280005F2D2E3B5BE562F26FE3225B0FE6EDA371 +:10229000DEDC568A1E4B7B05BE1F1CF1F4D1853F48 +:1022A0005B2EA694958C7F4AD85BD3B82CF6F6C2E9 +:1022B000F0C7149E83C4F7F3E08F374BD9DB85F06A +:1022C000C7991E912747FCF10EF5EB6816F8636974 +:1022D0002FFCDFE08AF869A6DBA5E28A0F6CFBB170 +:1022E00000AEF0F6EAE27715DA0CDB8FE025E20AC1 +:1022F000B79D40FC50DE4BF431C4B96BFFDE842F38 +:1023000050169D5F6867AA7A055ECFD3E5B19381C9 +:102310004446623D4885E8F998B982E5E872E903E8 +:10232000E2C42B7B8BEA8BE9C505B79BDCC171400E +:102330003B9FF9FBB2600BC547F6FB45F9B9F2E0EC +:10234000492AC707441C7A94E27E588E7B81F307A2 +:102350004352B97152A27ECB7322DEDEBF86E29E6B +:10236000D7F786AD7872FF75FCBB1BF8A2236FBA56 +:10237000F0BAC43D5F1AEA03BE0F5EA7711CDDA26E +:102380004B981880F31E5EE5671C78B8EF91E377F1 +:10239000505CA64FC4C140D1EB3F4AE72FC29A58C8 +:1023A000D1B920837286E2F32374B79D41C7367199 +:1023B0000FDA5A4F7512FDF722FFA32A76D7F77E60 +:1023C000EEBC37E429CE231F31B75689CBCA77F14B +:1023D00038B69E1C094CFAB5227B7374C079FFC9CC +:1023E0005DCA6DAFF07DC3634D0AE72F1E581F29EC +:1023F000233D39D42082B4E58D9E54AE843E0FF443 +:102400004A8EB876C83AE7CBBAC5BA169A6F784002 +:10241000C46FEDBA4F4F9924A7E5F56329A26B79F4 +:102420006344A2F8ABFDFEF65E61370E4B46BE0379 +:102430008979B8529C17BEBA0C78080F84F6AE237F +:102440001AFBEBFAE14C80EE6F64E06D2CC3613552 +:102450005D6ADD83D6BA0F7B7329C2538757299CE7 +:10246000E7444C55324EF609CB4E97378EF3FAA01F +:1024700051E17C95BBDD0EBB9D3AC6F98E438DDFE5 +:10248000D4695F87E807374B914BC9871F3A40767D +:102490006600F9EA25794E73597ECDB798FEA32DD3 +:1024A0008A46FBE8969B0FD03CC79260105E71CBCA +:1024B000C531D0CA687CB77C54AC7E8FE34FE54110 +:1024C000CA8C901CCEF8851D157216B0F8336A8838 +:1024D000BCCF684AE4AF6CFE15DE8BFB06E7520A00 +:1024E000FB2576FE6A0940491C67EBE590158F9F36 +:1024F000F77E799ECF9DA39BF251BA2711D4FC465B +:1025000092C67DC4B9AE837876F2BAFA44FE62CE42 +:102510003EAF15FEE1FC758AF881F2CCBBC2AE5A23 +:102520007E42B0F93DB6ABF6BDAFDE8D425FABACDF +:102530007BF755919429E872B7C31E48D7FC224314 +:1025400079A6076BC5DD84F04671AFB65C05234FF5 +:10255000F700FA027CBF6949CCCAD76D13F72BECA0 +:10256000FBE16A4475C41322505427DCE9AA83BCFA +:10257000FDBCF7E0F6FFECC48BCF15F1FDA55EE7DF +:102580003DF2C5FAFF7E20F7E27368908E19E7D717 +:10259000479B6F5F1E887169CBA52DA761DA62EB3F +:1025A000C2FDC743A992799A6052E8C362762DE2D0 +:1025B00033DBDF41BE7BAB81F3675FD9E41CEF37D0 +:1025C00096BEFEC6D22F7539D4129E1A0B093B3027 +:1025D0005606DBBE5B426F972455B61B057D70E245 +:1025E0000A5B8EE6D363115CB1BA4BE00A2D5C4600 +:1025F000B8E898917881F281EF69AA5E2CB7EEB8BD +:10260000BB8D2BD2493BFEA74A840BB4C00CE3ED33 +:10261000395C60E108372E28F7E6B6917E94AF5218 +:102620006D7BC576E5F3DFFFFB8732BCBF8C547C46 +:102630008E8EE66FE771C3AEB83B449CBF63798B67 +:10264000F017AE27AC4F4E2728FFB84511BF6F1BC0 +:1026500033A1F81ECEB8E7FDD83BD6F7F76D1C5274 +:102660004FEF8F4EF3EF6BE01E289EFFE04D3BF9DE +:10267000F7148BF1DF5E17DDEB2AD69F8BD50F2386 +:1026800069E9471994917E9C83FB380F0F6349C712 +:10269000F9C41989256C12C407B7A96CB0A082547B +:1026A000D01BE8B5F2E3E9393BA9503FC3EA564BEA +:1026B000B72C64CA37E4F9778BB6BD39073FE379A5 +:1026C00033CF48D21CEEBA12DD7FFA3DE44A5A827B +:1026D000E6A1D2BDFE1560F0F3064871F921E8E7E6 +:1026E000B209C6B8BC0626B96C86692E5BE02C9789 +:1026F0006B419769927560CAC05737D35CBF0E3281 +:102700005CB643BA9DEE970FD5EC5D4BE7D12D2E0D +:102710003AD9742EA1F78C2B6D7AD8742F27E35DEC +:10272000B3385FB321618F3B6379F61F0201819B50 +:102730006D7FDB1E67211C7CB9F09A8D33FF17CFAC +:10274000A588169043000000000000000000000073 +:102750000000001800000000000000000000004021 +:102760000000000000000000000000280000000041 +:102770000000000000000010000000000000000049 +:102780000000002000000000000000000000001019 +:102790000000000000000000000000080000000031 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:102860000000000000000000000000000000000068 +:102870000000000000000000000000000000000058 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000090000010000078 +:1028C0000000000800009008001000000000000256 +:1028D00000009000001000000000001000009DA803 +:1028E00000000000000000080000000000000000E0 +:1028F00000000000000000000000000000000000D8 +:10290000000000000000000000000000000091A096 +:102910000000000000000008000093C00001000457 +:1029200000000001000093C8000000000000000249 +:10293000000093D00000000000000008000093D4C5 +:102940000000000000000002000094980000000059 +:1029500000000008000093D80008000000000008F4 +:1029600000009B3800400000000000400000941868 +:102970000008000000000008000094580008000053 +:1029800000000008000094A800C8000000000098A3 +:10299000000096380098000000000028000096789B +:1029A00000980000000000280000C0000540003032 +:1029B000000005400000CB200008000000000001DE +:1029C0000000CB21000800000000000100002008EA +:1029D00000100000000000100000200000000000B7 +:1029E0000000000800009D600008000000000002D8 +:1029F00000009DA000000000000000010000000099 +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A80000000000000000000000000000000000046 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD00000000000000000000000000000000000F6 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B200000000000000000000000000000000000A5 +:102B30000000000000000000000000000000000095 +:102B40000000000000000000000000000000000085 +:102B50000000000000000000000000000000000075 +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000000000000000000000000000000000045 +:102B900000000000000012C800800000000000805B +:102BA0000000000100000000000000000000A00084 +:102BB000071000000000071000001EC80000000001 +:102BC000000000080000AEC000080000000000087F +:102BD0000000AE4000080000000000080000AE80C9 +:102BE000000800000000000800002008001000009D +:102BF000000000100000200000000000000000089D +:102C00000000A01007100040000000400000AF408E +:102C100000080000000000010000AF4100080000B3 +:102C20000000000100001ED00000000000000001B4 +:102C300000001ED8000000000000000200001EDAA4 +:102C40000000000000000002000012B000080000B8 +:102C5000000000080000000000000000000000006C +:102C60000000000000000000000000000000000064 +:102C70000000000000000000000000000000000054 +:102C80000000000000000000000000000000000044 +:102C90000000000000000000000000000000000034 +:102CA0000000000000000000000000000000000024 +:102CB0000000000000000000000000000000000014 +:102CC0000000000000000000000000000000000004 +:102CD00000000000000000000000000000000000F4 +:102CE00000000000000000000000000000000000E4 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D100000000000000000000000000000000000B3 +:102D200000000000000000000000000000000000A3 +:102D30000000000000000000000000000000000093 +:102D40000000000000000000000000000000000083 +:102D50000000B00000180000000000180000B300E0 +:102D600000400000000000400000B30000400002EE +:102D7000000000010000B30100400002000000005C +:102D80000000800000400000000000400000000043 +:102D9000000000000000000000008000000800406B +:102DA000000000040000800400080040000000044F +:102DB0000000BB0000280000000000280000BC400C +:102DC00000100000000000100000880000800000DB +:102DD0000000008000008800000800800000000261 +:102DE00000008C00002000000000002000002008EF +:102DF0000010000000000010000020000000000093 +:102E00000000000800001108000800000000000891 +:102E1000000011680008000000000008000011A870 +:102E20000008000000000008000012700008000008 +:102E30000000000100001271000800000000000105 +:102E400000008D00001000040000000400001320AA +:102E50000030001800000010000013280030001897 +:102E60000000000200000000000000000000000060 +:102E7000000000000000000000000000000011E859 +:102E80000000000000000001000000000000000041 +:102E90000000000000000000000000000000000032 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000000000000000000000000000000F2 +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000000000000B1 +:102F20000000000000008308008000000000008016 +:102F30000000000100000000000000000000200868 +:102F40000010000000000010000020000000000041 +:102F50000000000800008D100008000000000008BC +:102F600000008D7000080000000000080000845080 +:102F7000046000280000046000008EA0000800002B +:102F80000000000100008EA1000800000000000108 +:102F900000008408000800000000000800008448C9 +:102FA000000000000000000100008DF40008000097 +:102FB0000000000200008DF6000800000000000282 +:102FC00000008E040010000000000004000000005B +:102FD00000000000000000000000000000000000F1 +:102FE00000000000000000000000000000000000E1 +:102FF00000000000000000000000000000000000D1 +:1030000000000000000000000000000000000000C0 +:1030100000000000000000000000000000000000B0 +:1030200000000000000000000000000000000000A0 +:103030000000000000000000000000000000000090 +:103040000000000000000000000000000000000080 +:103050000000000000000000000000000000000070 +:103060000000000000000000000000000000000060 +:1030700000000000000030000040000000000008D8 +:1030800000003008004000000000002800003390DD +:1030900001C0001000000008000032000020000005 +:1030A00000000020000037200000000000000008A1 +:1030B0000000102006200038000000080000A000DA +:1030C000000000000000200000003EA900000000F9 +:1030D0000000000100003EC80000000000000002E7 +:1030E00000001C4000E00008000000080000000094 +:1030F0000000000000000000000040000008000088 +:103100000000000100004001000800000000000174 +:103110000000404000080004000000020000406081 +:103120000008000400000004000040000008000047 +:10313000000000040000400400080000000000043B +:10314000000040400000000000000008000040486F +:1031500000000000000000080000800000000000E7 +:1031600000000010000050400001000400000001B9 +:103170000000500000000000000000200000500887 +:1031800000100000000000040000500C00100000BF +:1031900000000001000052C7000000000000000114 +:1031A000000052C6000000000000000100003000D6 +:1031B0000030001800000004000030040030001847 +:1031C0000000000400003008003000180000000279 +:1031D0000000300A00300018000000020000300C2F +:1031E00000300018000000010000300D0030001811 +:1031F000000000010000300E003000180000000147 +:1032000000003010003000180000000400003014EE +:103210000030001800000004000050000100008091 +:1032200000080004000050040100008000080004B1 +:103230000000000A000000000000000000005068CC +:1032400001000080000000010000506901000080C2 +:10325000000000010000506C01000080000000022E +:103260000000506E0100008000000002000050705D +:103270000100008000000004000050740100008084 +:103280000000000400005066010000800000000201 +:103290000000506401000080000000010000506048 +:1032A0000100008000000002000050620100008068 +:1032B00000000002000050500100008000000004E7 +:1032C000000050540100008000000004000050582D +:1032D00001000080000000040000505C010000803C +:1032E000000000040000507C01000080000000018C +:1032F0000000507D01000080000000010000401827 +:1033000000100000000000040000409000100000C9 +:1033100000000004000040980010000000000004BD +:1033200000004110000000000000000200004112F7 +:103330000000000000000002000041140000000036 +:103340000000000200004116000000000000000222 +:103350000000604000080000000000020000604221 +:1033600000080000000000020000604400080000A7 +:103370000000000400006080000800000000000859 +:10338000000060C00040000800000008000060006D +:1033900000080000000000020000600200080000B9 +:1033A00000000001000060040008000000000002AE +:1033B0000000634000080000000000080000638077 +:1033C0000008000000000004000063840008000002 +:1033D00000000001000063C00008000000000002BF +:1033E000000063C400080000000000020000640048 +:1033F0000008000000000004000070000010000041 +:103400000000000400007004001000000000000430 +:1034100000007008001000000000000400007000B0 +:103420000008000000000002000070020008000018 +:10343000000000010000700400080000000000020D +:10344000000070400008000000000002000070440E +:1034500000080000000000020000704600080000A4 +:10346000000000020000764800080000000000088C +:10347000000070800008000000000002000070845E +:10348000000800000000000200007688000800002C +:10349000000000080000804000080000000000015B +:1034A0000000804100080000000000010000804290 +:1034B0000008000000000001000080430008000038 +:1034C0000000000100008000000800000000000271 +:1034D00000008002000800000000000100008004DD +:1034E0000008000000000002000080C0000800008A +:1034F00000000002000080C200080000000000027E +:10350000000080C40008000000000002000080806D +:103510000008000000000001000080810008000099 +:10352000000000010000808200080000000000018F +:10353000000080830008000000000001000080847B +:103540000008000000000001000080850008000065 +:10355000000000010000808600080000000000015B +:10356000000060000008000000000002000060028F +:1035700000080000000000010000600400080000D6 +:10358000000000020000604200C0001800000002BD +:103590000000604000C00018000000020000604C05 +:1035A00000C00018000000080000604400C00018BF +:1035B000000000080000605700C000180000000173 +:1035C0000000605400C000180000000200006056B7 +:1035D00000C0001800000001000066400008000064 +:1035E00000000008000066800008000000000008DD +:1035F000000066C000080000000000080000D9427A +:1036000000180000000000020000DE400000000082 +:10361000000000000000E0000000000000000004C6 +:103620000000DD4000000000000000040000DD4458 +:1036300000000000000000040000DD480000000061 +:10364000000000040000DD4C000000000000000449 +:103650000000DD5000000000000000040000DD5408 +:1036600000000000000000040000DD580000000021 +:10367000000000040000DD40000000000000002009 +:103680000000DA0000000000000000040000DA0082 +:1036900000000000000000680000BB6000000000A7 +:1036A000000000000000D000000000000000000446 +:1036B0000000B0C000000000000000040000B0C422 +:1036C00000000000000000040000B0C8000000007E +:1036D000000000040000B0C0000000000000001066 +:1036E0000000D6B000000000000000040000D6B4C6 +:1036F00000000000000000040000D6B80000000038 +:10370000000000040000D6BC00000000000000041F +:103710000000D6B000000000000000100000D348F8 +:1037200000000000000000080000D3580000000066 +:1037300000000080000000100000000000000000F9 +:103740000000D35800000000000000080000000046 +:08375000060022000000000049 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex new file mode 100644 index 000000000000..78b41615e7d9 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex @@ -0,0 +1,15442 @@ +:10000000000052D8000000680000070C00005348B0 +:100010000000318000005A58000000B000008BE062 +:100020000000C14C00008C98000000D800014DE891 +:100030000000F16400014EC800000074000240306E +:1000400000005250000240A8000000B800029300D7 +:1000500000012110000293C000000FFC0003B4D87F +:10006000000000040003C4D8020400480000000F90 +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040258000000360204025C000000365F +:10017000020402600810000002040264081000007B +:1001800002040004000000FF02040008000000FF59 +:100190000204000C000000FF02040010000000FF39 +:1001A000020400140000007F02040018000000FF99 +:1001B0000204001C000000FF02040020000000FFF9 +:1001C000020400240000003E020400280000000099 +:1001D0000204002C0000003F020400300000003F39 +:1001E000020400340000003F020400380000003F19 +:1001F0000204003C0000003F020400400000003FF9 +:10020000020400440000003F020404CC000000018E +:1002100002042008000002110204200C0000020069 +:10022000020420100000020402042014000002193D +:100230000204201C0000FFFF020420200000FFFF3A +:10024000020420240000FFFF020420280000FFFF1A +:1002500002042038000000200604203C0000000FAB +:1002600002042078000000210604207C0000000F1A +:10027000020420B800000001060420BC0000000FAA +:10028000020420F800000001060420FC0000003FEA +:10029000020421F800000001060421FC0000000F08 +:1002A0000204223807FFFFFF0204223C0000007F07 +:1002B0000204224007FFFFFF020422440000003F27 +:1002C00001042248000000000104224C000000004C +:1002D000010422500000000001042254000000002C +:1002E00001042258000000000104225C000000000C +:1002F00001042260000000000104226400000000EC +:1003000001042268000000000104226C00000000CB +:1003100001042270000000000104227400000000AB +:1003200001042278000000000104227C000000008B +:10033000020422C00000FFFF020422C40000FFFFED +:10034000020422C80000FFFF020422CC0000FFFFCD +:100350000C042000000003E80A0420000000000153 +:100360000B042000000000030605400000000D0003 +:100370000205004400000020020500480000003291 +:1003800002050090021500200205009402150020CD +:1003900002050098000000300205009C08100000D3 +:1003A000020500A000000036020500A40000003095 +:1003B000020500A800000031020500B000000004A2 +:1003C000020500B400000005020500C000000000A6 +:1003D000020500C400000004020500D40000000172 +:1003E00002050114000000010205011C00000001CB +:1003F00002050120000000020205020400000001C5 +:100400000205020C0000004002050210000000403E +:100410000205021C00000020020502200000001C52 +:100420000205022400000020060502400000000A28 +:1004300004050280002000000205005000000007B3 +:1004400002050054000000070205005800000000EB +:100450000205005C000000080205006000000001C9 +:100460000605006400000003020500D80000000635 +:100470000205000400000001020500080000000160 +:100480000205000C00000001020500100000000140 +:100490000205001400000001020500180000000120 +:1004A0000205001C00000001020500200000000100 +:1004B00002050024000000010205002800000001E0 +:1004C0000205002C000000010205003000000001C0 +:1004D00002050034000000010205003800000001A0 +:1004E0000205003C00000001020500400000000180 +:1004F000020500E00000000D020500E80000000019 +:10050000020500F000000000020500F800000000F5 +:10051000020500E40000002D020500EC00000020B0 +:10052000020500F400000020020500FC000000208D +:10053000020500E00000001D020500E800000010B8 +:10054000020500F000000010020500F80000001095 +:10055000020500E40000003D020500EC0000003050 +:10056000020500F400000030020500FC000000302D +:10057000020500E00000004D020500E80000004018 +:10058000020500F000000040020500F800000040F5 +:10059000020500E40000006D020500EC00000060B0 +:1005A000020500F400000060020500FC000000608D +:1005B000020500E00000005D020500E800000050B8 +:1005C000020500F000000050020500F80000005095 +:1005D000020500E40000007D020500EC0000007050 +:1005E000020500F400000070020500FC000000702D +:1005F0000406100002000020020600DC00000001DA +:100600000406020000030220020600DC00000000D5 +:100610000718040000AC0000081807D800050223E2 +:10062000071C000029B30000071C8000312E0A6D52 +:10063000071D000034A816B9071D80002E6C23E4A6 +:10064000071E0000034B2F80081E07F03F02022503 +:100650000118000000000000011800040000000064 +:1006600001180008000000000118000C0000000044 +:100670000118001000000000011800140000000024 +:1006800002180020000000010218002400000002EF +:1006900002180028000000030218002C00000000CF +:1006A00002180030000000040218003400000001AD +:1006B00002180038000000000218003C0000000191 +:1006C000021800400000000402180044000000006E +:1006D00002180048000000010218004C000000034E +:1006E0000218005000000000021800540000000131 +:1006F00002180058000000040218005C000000000E +:1007000002180060000000010218006400000003ED +:1007100002180068000000000218006C00000001D0 +:1007200002180070000000040218007400000000AD +:1007300002180078000000040218007C000000038A +:100740000618008000000002021800A400007FFFCD +:10075000021800A8000003FF021802240000000095 +:1007600002180234000000000218024C00000000D1 +:10077000021802E4000000FF061810000000040048 +:10078000021B8BC000000001021B8000000000342F +:10079000021B804000000018021B80800000000C3B +:1007A000021B80C0000000200C1B83000008647046 +:1007B0000A1B8300000001570B1B83000000055F2C +:1007C0000A1B8340000000000C1B8340000002262F +:1007D0000B1B834000000001021B83800008647033 +:1007E000021B83C000000226021B148000000001CF +:1007F0000A1B148000000000021B9440000000014E +:10080000061B944800000002061A1000000002B304 +:10081000041A1ACC00010227061A1AD00000000898 +:10082000061A2008000000C8061A20000000000276 +:10083000041A1BF800900228061A3718000000045A +:10084000061A371000000002061A500000000002CD +:10085000061A500800000004061A50180000000490 +:10086000061A502800000004061A50380000000440 +:10087000061A504800000004061A505800000004F0 +:10088000061A506800000004061A507800000002A2 +:10089000041A52C0000202B8061A405000000006B6 +:1008A000041A4068000202BA041A4040000402BC64 +:1008B000041A8000000102C0061A80040000000330 +:1008C000041A8010000102C1061A801400000003FF +:1008D000041A8020000102C2061A802400000003CE +:1008E000041A8030000102C3061A8034000000039D +:1008F000041A8040000102C4061A8044000000036C +:10090000041A8050000102C5061A8054000000033A +:10091000041A8060000102C6061A80640000000309 +:10092000041A8070000102C7061A807400000003D8 +:10093000041A8080000102C8061A808400000003A7 +:10094000041A8090000102C9061A80940000000376 +:10095000041A80A0000102CA061A80A40000000345 +:10096000041A80B0000102CB061A80B40000000314 +:10097000041A80C0000102CC061A80C400000003E3 +:10098000041A80D0000102CD061A80D400000003B2 +:10099000041A80E0000102CE061A80E40000000381 +:1009A000041A80F0000102CF061A80F40000000350 +:1009B000041A8100000102D0061A8104000000031D +:1009C000041A8110000102D1061A811400000003EC +:1009D000041A8120000102D2061A812400000003BB +:1009E000041A8130000102D3061A8134000000038A +:1009F000041A8140000102D4061A81440000000359 +:100A0000041A8150000102D5061A81540000000327 +:100A1000041A8160000102D6061A816400000003F6 +:100A2000041A8170000102D7061A817400000003C5 +:100A3000041A8180000102D8061A81840000000394 +:100A4000041A8190000102D9061A81940000000363 +:100A5000041A81A0000102DA061A81A40000000332 +:100A6000041A81B0000102DB061A81B40000000301 +:100A7000041A81C0000102DC061A81C400000003D0 +:100A8000041A81D0000102DD061A81D4000000039F +:100A9000041A81E0000102DE061A81E4000000036E +:100AA000041A81F0000102DF061A81F4000000033D +:100AB000041A8200000102E0061A8204000000030A +:100AC000041A8210000102E1061A821400000003D9 +:100AD000041A8220000102E2061A822400000003A8 +:100AE000041A8230000102E3061A82340000000377 +:100AF000041A8240000102E4061A82440000000346 +:100B0000041A8250000102E5061A82540000000314 +:100B1000041A8260000102E6061A826400000003E3 +:100B2000041A8270000102E7061A827400000003B2 +:100B3000041A8280000102E8061A82840000000381 +:100B4000041A8290000102E9061A82940000000350 +:100B5000041A82A0000102EA061A82A4000000031F +:100B6000041A82B0000102EB061A82B400000003EE +:100B7000041A82C0000102EC061A82C400000003BD +:100B8000041A82D0000102ED061A82D4000000038C +:100B9000041A82E0000102EE061A82E4000000035B +:100BA000041A82F0000102EF061A82F4000000032A +:100BB000041A8300000102F0061A830400000003F7 +:100BC000041A8310000102F1061A831400000003C6 +:100BD000041A8320000102F2061A83240000000395 +:100BE000041A8330000102F3061A83340000000364 +:100BF000041A8340000102F4061A83440000000333 +:100C0000041A8350000102F5061A83540000000301 +:100C1000041A8360000102F6061A836400000003D0 +:100C2000041A8370000102F7061A8374000000039F +:100C3000041A8380000102F8061A8384000000036E +:100C4000041A8390000102F9061A8394000000033D +:100C5000041A83A0000102FA061A83A4000000030C +:100C6000041A83B0000102FB061A83B400000003DB +:100C7000041A83C0000102FC061A83C400000003AA +:100C8000041A83D0000102FD061A83D40000000379 +:100C9000041A83E0000102FE061A83E40000000348 +:100CA000041A83F0000102FF061A83F40000000317 +:100CB000041A840000010300061A840400000003E3 +:100CC000041A841000010301061A841400000003B2 +:100CD000041A842000010302061A84240000000381 +:100CE000041A843000010303061A84340000000350 +:100CF000041A844000010304061A8444000000031F +:100D0000041A845000010305061A845400000003ED +:100D1000041A846000010306061A846400000003BC +:100D2000041A847000010307061A8474000000038B +:100D3000041A848000010308061A8484000000035A +:100D4000041A849000010309061A84940000000329 +:100D5000041A84A00001030A061A84A400000003F8 +:100D6000041A84B00001030B061A84B400000003C7 +:100D7000041A84C00001030C061A84C40000000396 +:100D8000041A84D00001030D061A84D40000000365 +:100D9000041A84E00001030E061A84E40000000334 +:100DA000041A84F00001030F061A84F40000000303 +:100DB000041A850000010310061A850400000003D0 +:100DC000041A851000010311061A8514000000039F +:100DD000041A852000010312061A8524000000036E +:100DE000041A853000010313061A8534000000033D +:100DF000041A854000010314061A8544000000030C +:100E0000041A855000010315061A855400000003DA +:100E1000041A856000010316061A856400000003A9 +:100E2000041A857000010317061A85740000000378 +:100E3000041A858000010318061A85840000000347 +:100E4000041A859000010319061A85940000000316 +:100E5000041A85A00001031A061A85A400000003E5 +:100E6000041A85B00001031B061A85B400000003B4 +:100E7000041A85C00001031C061A85C40000000383 +:100E8000041A85D00001031D061A85D40000000352 +:100E9000041A85E00001031E061A85E40000000321 +:100EA000041A85F00001031F061A85F400000003F0 +:100EB000041A860000010320061A860400000003BD +:100EC000041A861000010321061A8614000000038C +:100ED000041A862000010322061A8624000000035B +:100EE000041A863000010323061A8634000000032A +:100EF000041A864000010324061A864400000003F9 +:100F0000041A865000010325061A865400000003C7 +:100F1000041A866000010326061A86640000000396 +:100F2000041A867000010327061A86740000000365 +:100F3000041A868000010328061A86840000000334 +:100F4000041A869000010329061A86940000000303 +:100F5000041A86A00001032A061A86A400000003D2 +:100F6000041A86B00001032B061A86B400000003A1 +:100F7000041A86C00001032C061A86C40000000370 +:100F8000041A86D00001032D061A86D4000000033F +:100F9000041A86E00001032E061A86E4000000030E +:100FA000041A86F00001032F061A86F400000003DD +:100FB000041A870000010330061A870400000003AA +:100FC000041A871000010331061A87140000000379 +:100FD000041A872000010332061A87240000000348 +:100FE000041A873000010333061A87340000000317 +:100FF000041A874000010334061A874400000003E6 +:10100000041A875000010335061A875400000003B4 +:10101000041A876000010336061A87640000000383 +:10102000041A877000010337061A87740000000352 +:10103000041A878000010338061A87840000000321 +:10104000041A879000010339061A879400000003F0 +:10105000041A87A00001033A061A87A400000003BF +:10106000041A87B00001033B061A87B4000000038E +:10107000041A87C00001033C061A87C4000000035D +:10108000041A87D00001033D061A87D4000000032C +:10109000041A87E00001033E061A87E400000003FB +:1010A000041A87F00001033F061A87F400000003CA +:1010B000041A880000010340061A88040000000397 +:1010C000041A881000010341061A88140000000366 +:1010D000041A882000010342061A88240000000335 +:1010E000041A883000010343061A88340000000304 +:1010F000041A884000010344061A884400000003D3 +:10110000041A885000010345061A885400000003A1 +:10111000041A886000010346061A88640000000370 +:10112000041A887000010347061A8874000000033F +:10113000041A888000010348061A8884000000030E +:10114000041A889000010349061A889400000003DD +:10115000041A88A00001034A061A88A400000003AC +:10116000041A88B00001034B061A88B4000000037B +:10117000041A88C00001034C061A88C4000000034A +:10118000041A88D00001034D061A88D40000000319 +:10119000041A88E00001034E061A88E400000003E8 +:1011A000041A88F00001034F061A88F400000003B7 +:1011B000041A890000010350061A89040000000384 +:1011C000041A891000010351061A89140000000353 +:1011D000041A892000010352061A89240000000322 +:1011E000041A893000010353061A893400000003F1 +:1011F000041A894000010354061A894400000003C0 +:10120000041A895000010355061A8954000000038E +:10121000041A896000010356061A8964000000035D +:10122000041A897000010357061A8974000000032C +:10123000041A898000010358061A898400000003FB +:10124000041A899000010359061A899400000003CA +:10125000041A89A00001035A061A89A40000000399 +:10126000041A89B00001035B061A89B40000000368 +:10127000041A89C00001035C061A89C40000000337 +:10128000041A89D00001035D061A89D40000000306 +:10129000041A89E00001035E061A89E400000003D5 +:1012A000041A89F00001035F061A89F400000003A4 +:1012B000041A8A0000010360061A8A040000000371 +:1012C000041A8A1000010361061A8A140000000340 +:1012D000041A8A2000010362061A8A24000000030F +:1012E000041A8A3000010363061A8A3400000003DE +:1012F000041A8A4000010364061A8A4400000003AD +:10130000041A8A5000010365061A8A54000000037B +:10131000041A8A6000010366061A8A64000000034A +:10132000041A8A7000010367061A8A740000000319 +:10133000041A8A8000010368061A8A8400000003E8 +:10134000041A8A9000010369061A8A9400000003B7 +:10135000041A8AA00001036A061A8AA40000000386 +:10136000041A8AB00001036B061A8AB40000000355 +:10137000041A8AC00001036C061A8AC40000000324 +:10138000041A8AD00001036D061A8AD400000003F3 +:10139000041A8AE00001036E061A8AE400000003C2 +:1013A000041A8AF00001036F061A8AF40000000391 +:1013B000041A8B0000010370061A8B04000000035E +:1013C000041A8B1000010371061A8B14000000032D +:1013D000041A8B2000010372061A8B2400000003FC +:1013E000041A8B3000010373061A8B3400000003CB +:1013F000041A8B4000010374061A8B44000000039A +:10140000041A8B5000010375061A8B540000000368 +:10141000041A8B6000010376061A8B640000000337 +:10142000041A8B7000010377061A8B740000000306 +:10143000041A8B8000010378061A8B8400000003D5 +:10144000041A8B9000010379061A8B9400000003A4 +:10145000041A8BA00001037A061A8BA40000000373 +:10146000041A8BB00001037B061A8BB40000000342 +:10147000041A8BC00001037C061A8BC40000000311 +:10148000041A8BD00001037D061A8BD400000003E0 +:10149000041A8BE00001037E061A8BE400000003AF +:1014A000041A8BF00001037F061A8BF4000000037E +:1014B000041A8C0000010380061A8C04000000034B +:1014C000041A8C1000010381061A8C14000000031A +:1014D000041A8C2000010382061A8C2400000003E9 +:1014E000041A8C3000010383061A8C3400000003B8 +:1014F000041A8C4000010384061A8C440000000387 +:10150000041A8C5000010385061A8C540000000355 +:10151000041A8C6000010386061A8C640000000324 +:10152000041A8C7000010387061A8C7400000003F3 +:10153000041A8C8000010388061A8C8400000003C2 +:10154000041A8C9000010389061A8C940000000391 +:10155000041A8CA00001038A061A8CA40000000360 +:10156000041A8CB00001038B061A8CB4000000032F +:10157000041A8CC00001038C061A8CC400000003FE +:10158000041A8CD00001038D061A8CD400000003CD +:10159000041A8CE00001038E061A8CE4000000039C +:1015A000041A8CF00001038F061A8CF4000000036B +:1015B000041A8D0000010390061A8D040000000338 +:1015C000041A8D1000010391061A8D140000000307 +:1015D000041A8D2000010392061A8D2400000003D6 +:1015E000041A8D3000010393061A8D3400000003A5 +:1015F000041A8D4000010394061A8D440000000374 +:10160000041A8D5000010395061A8D540000000342 +:10161000041A8D6000010396061A8D640000000311 +:10162000041A8D7000010397061A8D7400000003E0 +:10163000041A8D8000010398061A8D8400000003AF +:10164000041A8D9000010399061A8D94000000037E +:10165000041A8DA00001039A061A8DA4000000034D +:10166000041A8DB00001039B061A8DB4000000031C +:10167000041A8DC00001039C061A8DC400000003EB +:10168000041A8DD00001039D061A8DD400000003BA +:10169000041A8DE00001039E061A8DE40000000389 +:1016A000041A8DF00001039F061A8DF40000000358 +:1016B000041A8E00000103A0061A8E040000000325 +:1016C000041A8E10000103A1061A8E1400000003F4 +:1016D000041A8E20000103A2061A8E2400000003C3 +:1016E000041A8E30000103A3061A8E340000000392 +:1016F000041A8E40000103A4061A8E440000000361 +:10170000041A8E50000103A5061A8E54000000032F +:10171000041A8E60000103A6061A8E6400000003FE +:10172000041A8E70000103A7061A8E7400000003CD +:10173000041A8E80000103A8061A8E84000000039C +:10174000041A8E90000103A9061A8E94000000036B +:10175000041A8EA0000103AA061A8EA4000000033A +:10176000041A8EB0000103AB061A8EB40000000309 +:10177000041A8EC0000103AC061A8EC400000003D8 +:10178000041A8ED0000103AD061A8ED400000003A7 +:10179000041A8EE0000103AE061A8EE40000000376 +:1017A000041A8EF0000103AF061A8EF40000000345 +:1017B000041A8F00000103B0061A8F040000000312 +:1017C000041A8F10000103B1061A8F1400000003E1 +:1017D000041A8F20000103B2061A8F2400000003B0 +:1017E000041A8F30000103B3061A8F34000000037F +:1017F000041A8F40000103B4061A8F44000000034E +:10180000041A8F50000103B5061A8F54000000031C +:10181000041A8F60000103B6061A8F6400000003EB +:10182000041A8F70000103B7061A8F7400000003BA +:10183000041A8F80000103B8061A8F840000000389 +:10184000041A8F90000103B9061A8F940000000358 +:10185000041A8FA0000103BA061A8FA40000000327 +:10186000041A8FB0000103BB061A8FB400000003F6 +:10187000041A8FC0000103BC061A8FC400000003C5 +:10188000041A8FD0000103BD061A8FD40000000394 +:10189000041A8FE0000103BE061A8FE4000000075F +:1018A000041A62C0002003BF061A1AF000000042AA +:1018B000061AAF0000000008061AE000000005400C +:1018C000061AD00000000072061AD248000000106C +:1018D000061AD6B000000020061AD470000000904E +:1018E000061AD46800000002061AA000000001C415 +:1018F000061A300000000010061A308000000010A8 +:10190000061A310000000010061A31800000001095 +:10191000061A330000000012061A3390000000700F +:10192000061AD45800000002061AD348000000022C +:10193000061AD35800000020061AA710000001C4A0 +:10194000061A304000000010061A30C000000010D7 +:10195000061A314000000010061A31C000000010C5 +:10196000061A334800000012061A355000000070B5 +:10197000061AD46000000002061AD35000000002CC +:10198000061AD3D800000020021AAE200000000082 +:10199000061A500000000002061A508000000012D3 +:1019A000041A4000000203DF041A63C0000203E1CE +:1019B000061A700000000004061A32000000000839 +:1019C000021AAE2400000000061A501000000002A7 +:1019D000061A50C800000012041A4008000203E36F +:1019E000041A63C8000203E5061A70100000000420 +:1019F000061A322000000008021AAE28000000007B +:101A0000061A502000000002061A511000000012B1 +:101A1000041A4010000203E7041A63D0000203E92D +:101A2000061A702000000004061A32400000000868 +:101A3000021AAE2C00000000061A5030000000020E +:101A4000061A515800000012041A4018000203EB55 +:101A5000041A63D8000203ED061A70300000000477 +:101A6000061A326000000008021AAE3000000000C2 +:101A7000061A504000000002061A51A00000001291 +:101A8000041A4020000203EF041A63E0000203F18D +:101A9000061A704000000004061A32800000000898 +:101AA000021AAE3400000000061A50500000000276 +:101AB000061A51E800000012041A4028000203F33D +:101AC000041A63E8000203F5061A705000000004CF +:101AD000061A32A000000008021AAE38000000000A +:101AE000061A506000000002061A52300000001270 +:101AF000041A4030000203F7041A63F0000203F9ED +:101B0000061A706000000004061A32C000000008C7 +:101B1000021AAE3C00000000061A507000000002DD +:101B2000061A527800000012041A4038000203FB23 +:101B3000041A63F8000203FD061A70700000000426 +:101B4000061A32E0000000080200A2A40000020908 +:101B50000200A270000000000200A2740000000059 +:101B60000200A270000000000200A2740000000049 +:101B70000200A270000000000200A2740000000039 +:101B80000200A270000000000200A2740000000029 +:101B9000020100B400000001020100B800000001D1 +:101BA000020100CC00000001020100D00000000191 +:101BB000020100DC00000001020101000000000140 +:101BC00002010104000000010201007C003000005D +:101BD00002010084000000280201008C00000000C7 +:101BE00002010130000000040201025C000000015B +:101BF0000201032800000000020160580000FFFFFE +:101C0000020160700000000702010554000000306E +:101C1000020100C400000001020100F80000000100 +:101C2000020100F00000000102010080003000000D +:101C3000020100880000002802010090000000005E +:101C40000201013400000004020102DC0000000176 +:101C50000201032C000000000201605C0000FFFF95 +:101C600002016074000000070201056400000030FA +:101C7000020100C800000001020100FC0000000198 +:101C8000020100F400000001020C10000000002816 +:101C9000020C200800000211020C200C00000200BF +:101CA000020C201000000204020C201C0000FFFFA8 +:101CB000020C20200000FFFF020C20240000FFFF88 +:101CC000020C20280000FFFF020C2038000000005A +:101CD000020C203C00000037020C204000000021D4 +:101CE000020C204400000020060C20480000001DCB +:101CF000020C20BC00000001060C20C00000003FC8 +:101D0000020C21BC00000001020C21C000000001F7 +:101D1000020C21C400000001060C21C80000001CB8 +:101D2000020C223807FFFFFF020C223C0000007F5C +:101D3000020C224007FFFFFF020C22440000003F7C +:101D4000010C224800000000010C224C00000000A1 +:101D5000010C225000000000010C22540000000081 +:101D6000010C225800000000010C225C0000000061 +:101D7000010C226000000000010C22640000000041 +:101D8000010C226800000000010C226C0000000021 +:101D9000010C227000000000010C22740000000001 +:101DA000010C227800000000010C227C00000000E1 +:101DB000020C22D80000FFFF020C22DC0000FFFF13 +:101DC000020C22E00000FFFF020C22E40000FFFFF3 +:101DD0000C0C2000000003E80A0C200000000001A9 +:101DE0000B0C200000000003020C40080000101142 +:101DF000020C400C00001000020C40100000100407 +:101E0000020C401400001021020C401C0000FFFFD7 +:101E1000020C40200000FFFF020C40240000FFFFE6 +:101E2000020C40280000FFFF020C40380000004672 +:101E3000020C403C0000000C060C40400000000278 +:101E4000020C404800000018020C404C000000F05A +:101E5000060C40500000001F020C40CC00000001A6 +:101E6000060C40D00000003A020C41B8000000010E +:101E7000060C41BC00000003020C41C80000000138 +:101E8000020C41CC00000001060C41D00000001AF9 +:101E9000020C423807FFFFFF020C423C0000007FAB +:101EA000020C424007FFFFFF020C42440000003FCB +:101EB000010C424800000000010C424C00000000F0 +:101EC000010C425000000000010C425400000000D0 +:101ED000010C425800000000010C425C00000000B0 +:101EE000010C426000000000010C42640000000090 +:101EF000010C426800000000010C426C0000000070 +:101F0000010C427000000000010C4274000000004F +:101F1000010C427800000000010C427C000000002F +:101F2000010C428000000000020C42D80000FFFFBC +:101F3000020C42DC0000FFFF020C42E00000FFFF49 +:101F4000020C42E40000FFFF0C0C4000000003E81C +:101F50000A0C4000000000010B0C400000000003D0 +:101F6000060D400000000A00020D0044000000328F +:101F7000020D008C02150020020D009002150020B9 +:101F8000020D009408100000020D009800000036B9 +:101F9000020D00A000000000020D00A400000004DB +:101FA000020D00A800000004060D00AC00000002B5 +:101FB000020D00B800000002020D00C00000000188 +:101FC000020D00C800000002020D00CC000000025B +:101FD000020D015C00000001020D0164000000011F +:101FE000020D016800000002020D02040000000161 +:101FF000020D020C00000020020D02100000004043 +:10200000020D021400000040020D02200000000337 +:10201000020D022400000018060D028000000012CC +:10202000040D0300001803FF060D03600000000C00 +:10203000020D004C00000001020D005000000002E3 +:10204000020D005400000000020D005800000008BE +:10205000060D005C00000004020D00C40000000436 +:10206000020D000400000001020D00080000000144 +:10207000020D000C00000001020D00100000000124 +:10208000020D001400000001020D00180000000104 +:10209000020D001C00000001020D002000000001E4 +:1020A000020D002400000001020D002800000001C4 +:1020B000020D002C00000001020D003000000001A4 +:1020C000020D003400000001020D00380000000184 +:1020D000020D003C00000001020D01140000000987 +:1020E000020D011C0000000A020D01240000000086 +:1020F000020D012C00000000020D01340000000060 +:10210000020D013C0000000B020D01440000000024 +:10211000020D011800000029020D01200000002A14 +:10212000020D012800000020020D013000000020F7 +:10213000020D013800000020020D01400000002BBC +:10214000020D014800000020020D011400000019DA +:10215000020D011C0000001A020D012400000010F5 +:10216000020D012C00000010020D013400000010CF +:10217000020D013C0000001B020D01440000001094 +:10218000020D011800000039020D01200000003A84 +:10219000020D012800000030020D01300000003067 +:1021A000020D013800000030020D01400000003B2C +:1021B000020D014800000030020D0114000000492A +:1021C000020D011C0000004A020D01240000004025 +:1021D000020D012C00000040020D013400000040FF +:1021E000020D013C0000004B020D014400000040C4 +:1021F000020D011800000069020D01200000006AB4 +:10220000020D012800000060020D01300000006096 +:10221000020D013800000060020D01400000006B5B +:10222000020D014800000060020D01140000005979 +:10223000020D011C0000005A020D01240000005094 +:10224000020D012C00000050020D0134000000506E +:10225000020D013C0000005B020D01440000005033 +:10226000020D011800000079020D01200000007A23 +:10227000020D012800000070020D01300000007006 +:10228000020D013800000070020D01400000007BCB +:10229000020D014800000070060E2000000008003A +:1022A000020E004C00000032020E009402150020C5 +:1022B000020E009802150020020E009C0000003063 +:1022C000020E00A008100000020E00A4000000365C +:1022D000020E00A800000030020E00AC0000003129 +:1022E000020E00B400000003020E00B8000000005F +:1022F000020E00C400000000020E00CC0000000628 +:10230000020E00D800000001020E0144000000018E +:10231000020E014C00000001020E015000000002FC +:10232000020E020400000001020E020C0000004038 +:10233000020E021000000040020E021C0000000409 +:10234000020E022000000020020E02240000000EF7 +:10235000020E02280000001B060E030000000012FF +:10236000040E0280001B0417060E02EC000000059C +:10237000020E00540000000C020E00580000000C79 +:10238000020E005C00000000020E00600000001061 +:10239000020E006400000010060E0068000000033A +:1023A000020E00DC00000003020E00040000000129 +:1023B000020E000800000001020E000C00000001E7 +:1023C000020E001000000001020E001400000001C7 +:1023D000020E001800000001020E001C00000001A7 +:1023E000020E002000000001020E00240000000187 +:1023F000020E002800000001020E002C0000000167 +:10240000020E003000000001020E00340000000146 +:10241000020E003800000001020E003C0000000126 +:10242000020E004000000001020E00440000000106 +:10243000020E01100000000F020E01180000000043 +:10244000020E012000000000020E01280000000022 +:10245000020E01140000002F020E011C00000020DB +:10246000020E012400000020020E012C00000020BA +:10247000020E01100000001F020E011800000010E3 +:10248000020E012000000010020E012800000010C2 +:10249000020E01140000003F020E011C000000307B +:1024A000020E012400000030020E012C000000305A +:1024B000020E01100000004F020E01180000004043 +:1024C000020E012000000040020E01280000004022 +:1024D000020E01140000006F020E011C00000060DB +:1024E000020E012400000060020E012C00000060BA +:1024F000020E01100000005F020E011800000050E3 +:10250000020E012000000050020E012800000050C1 +:10251000020E01140000007F020E011C000000707A +:10252000020E012400000070020E012C0000007059 +:102530000730040000D60000083007D80005043238 +:10254000073400003222000007348000312C0C894F +:102550000735000038DD18D5073580002F16270D08 +:1025600007360000261532D30836711031DE0434E8 +:1025700001300000000000000130000400000000F5 +:1025800001300008000000000130000C00000000D5 +:1025900001300010000000000130001400000000B5 +:1025A0000230002000000001023000240000000280 +:1025B00002300028000000030230002C0000000060 +:1025C000023000300000000402300034000000013E +:1025D00002300038000000000230003C0000000122 +:1025E00002300040000000040230004400000000FF +:1025F00002300048000000010230004C00000003DF +:1026000002300050000000000230005400000001C1 +:1026100002300058000000040230005C000000009E +:10262000023000600000000102300064000000037E +:1026300002300068000000000230006C0000000161 +:10264000023000700000000402300074000000003E +:1026500002300078000000040230007C000000031B +:102660000630008000000002023000A400007FFF5E +:10267000023000A8000003FF023002240000000026 +:1026800002300234000000000230024C0000000062 +:10269000023002E40000FFFF0630200000000800C6 +:1026A00002338BC000000001023380000000001ADA +:1026B000023380400000004E023380800000001092 +:1026C000023380C0000000200C33830000086470D7 +:1026D0000A338300000001570B3383000000055FBD +:1026E0000A338340000000000C33834000000226C0 +:1026F0000B338340000000010233838000086470C4 +:10270000023383C00000022602331480000000015F +:102710000A3314800000000006328000000001022D +:1027200006322008000000C8063220000000000227 +:1027300004328520008F04360632875C00000009D1 +:1027400006323EB00000000606323ED00000000215 +:1027500006323E800000000A04323EA8000204C592 +:1027600006323E0000000020063250000000094002 +:102770000632400000000004043294C0000204C786 +:1027800006324110000000020632D0000000007046 +:102790000632DB00000000D40632DEA0000000029A +:1027A0000632E00000000800063324000000011893 +:1027B00006321000000001880632500000000020A0 +:1027C00006325100000000200632520000000020B6 +:1027D00006325300000000200632540000000020A2 +:1027E000063255000000002006325600000000208E +:1027F000063257000000002006325800000000207A +:10280000063259000000002006325A000000002065 +:1028100006325B000000002006325C000000002051 +:1028200006325D000000002006325E00000000203D +:1028300006325F0000000020063284F00000000233 +:1028400004328500000204C9063285080000000237 +:102850000632DE90000000020633286000000118F6 +:102860000632162000000188063250800000002049 +:102870000632518000000020063252800000002005 +:1028800006325380000000200632548000000020F1 +:1028900006325580000000200632568000000020DD +:1028A00006325780000000200632588000000020C9 +:1028B000063259800000002006325A8000000020B5 +:1028C00006325B800000002006325C8000000020A1 +:1028D00006325D800000002006325E80000000208D +:1028E00006325F8000000020063284F800000002FB +:1028F00004328510000204CB063285180000000265 +:102900000632DE980000000202328450000000000F +:102910000632401000000002023284540000000021 +:1029200006324020000000020232845800000000FD +:1029300006324030000000020232845C00000000D9 +:1029400006324040000000020232846000000000B5 +:102950000632405000000002023284640000000091 +:10296000063240600000000202328468000000006D +:1029700006324070000000020232846C0000000049 +:1029800006324080000000020720040000730000AF +:1029900008200780001004CD072400002AD500007D +:1029A0000724800027740AB60824D36063FA04CF92 +:1029B00001200000000000000120000400000000D1 +:1029C00001200008000000000120000C00000000B1 +:1029D0000120001000000000012000140000000091 +:1029E000022000200000000102200024000000025C +:1029F00002200028000000030220002C000000003C +:102A00000220003000000004022000340000000119 +:102A100002200038000000000220003C00000001FD +:102A200002200040000000040220004400000000DA +:102A300002200048000000010220004C00000003BA +:102A4000022000500000000002200054000000019D +:102A500002200058000000040220005C000000007A +:102A6000022000600000000102200064000000035A +:102A700002200068000000000220006C000000013D +:102A8000022000700000000402200074000000001A +:102A900002200078000000040220007C00000003F7 +:102AA0000620008000000002022000A400007FFF3A +:102AB000022000A8000003FF022002240000000002 +:102AC00002200234000000000220024C000000003E +:102AD000022002E40000FFFF0620200000000800A2 +:102AE00002238BC0000000010223800000000010C0 +:102AF000022380400000001202238080000000308A +:102B0000022380C00000000E0C23830000086470C4 +:102B10000A238300000001570B2383000000055F98 +:102B20000A238340000000000C238340000002269B +:102B30000B2383400000000102238380000864709F +:102B4000022383C00000022602231480000000013B +:102B50000A2314800000000006221000000000423A +:102B600006222008000000C8062220000000000203 +:102B70000622B000000003300622F40000000053DB +:102B80000422F54C000104D10622F5500000000398 +:102B90000422F55C000104D20622F5600000000367 +:102BA0000422F56C000104D30622F5700000000336 +:102BB0000422F57C000104D40622F5800000000305 +:102BC0000422F58C000104D50622F59000000003D4 +:102BD0000422F59C000104D60622F5A000000003A3 +:102BE0000422F5AC000104D70622F5B00000000372 +:102BF0000422F5BC000104D80622F5C000000046FE +:102C00000622E2000000044004221240009004D991 +:102C100006223000000000C006226700000001000C +:102C2000062290000000040004226B0800200569C1 +:102C3000062211F000000006042212080006058991 +:102C4000062212200000000206224000000005C0FB +:102C50000622C000000000060422C0180006058FEE +:102C60000622C0300000000A0422C0580006059564 +:102C70000622C0700000000A0422C0980006059BCE +:102C80000622C0B00000000A0422C0D8000605A138 +:102C90000622C0F00000000A0422C118000605A7A1 +:102CA0000622C1300000000A0422C158000605AD0A +:102CB0000622C1700000000A0422C198000605B374 +:102CC0000622C1B00000000A0422C1D8000605B9DE +:102CD0000622C1F00000000A0422C218000605BF47 +:102CE0000622C2300000000A0422C258000605C5B0 +:102CF0000622C2700000000A0422C298000605CB1A +:102D00000622C2B00000000A0422C2D8000605D183 +:102D10000622C2F00000000A0422C318000605D7EC +:102D20000622C3300000000A0422C358000605DD55 +:102D30000622C3700000000A0422C398000605E3BF +:102D40000622C3B00000000A0422C3D8000605E929 +:102D50000622C3F00000000A0422C418000605EF92 +:102D60000622C4300000000A0422C458000605F5FB +:102D70000622C4700000000A0422C498000605FB65 +:102D80000622C4B00000000A0422C4D800060601CE +:102D90000622C4F00000000A0422C5180006060737 +:102DA0000622C5300000000A0422C5580006060DA0 +:102DB0000622C5700000000A0422C598000606130A +:102DC0000622C5B00000000A0422C5D80006061974 +:102DD0000622C5F00000000A0422C6180006061FDD +:102DE0000622C6300000000A0422C6580006062546 +:102DF0000622C6700000000A0422C6980006062BB0 +:102E00000622C6B00000000A0422C6D80006063119 +:102E10000622C6F00000000A0422C7180006063782 +:102E20000622C7300000000A0422C7580006063DEB +:102E30000622C7700000000A0422C7980006064355 +:102E40000622C7B00000000A0422C7D800060649BF +:102E50000622C7F00000000A0422C8180006064F28 +:102E60000622C8300000000A0422C8580006065591 +:102E70000622C8700000000A0422C8980006065BFB +:102E80000622C8B00000000A0422C8D80006066165 +:102E90000622C8F00000000A0422C91800060667CE +:102EA0000622C9300000000A0422C9580006066D37 +:102EB0000622C9700000000A0422C99800060673A1 +:102EC0000622C9B00000000A0422C9D8000606790B +:102ED0000622C9F00000000A0422CA180006067F74 +:102EE0000622CA300000000A0422CA5800060685DD +:102EF0000622CA700000000A0422CA980006068B47 +:102F00000622CAB00000000A0422CAD800060691B0 +:102F10000622CAF00000000A0422CB180006069719 +:102F20000622CB300000000A0422CB580006069D82 +:102F30000622CB700000000A0422CB98000606A3EC +:102F40000622CBB00000000A0422CBD8000606A956 +:102F50000622CBF00000000A0422CC18000606AFBF +:102F60000622CC300000000A0422CC58000606B528 +:102F70000622CC700000000A0422CC98000606BB92 +:102F80000622CCB00000000A0422CCD8000606C1FC +:102F90000622CCF00000000A0422CD18000606C765 +:102FA0000622CD300000000A0422CD58000606CDCE +:102FB0000622CD700000000A0422CD98000606D338 +:102FC0000622CDB00000000A0422CDD8000606D9A2 +:102FD0000622CDF00000000A0422CE18000606DF0B +:102FE0000622CE300000000A0422CE58000606E574 +:102FF0000622CE700000000A0422CE98000606EBDE +:103000000622CEB00000000A0422CED8000606F147 +:103010000622CEF00000000A0422CF18000606F7B0 +:103020000622CF300000000A0422CF58000606FD19 +:103030000622CF700000000A0422CF980006070382 +:103040000622CFB00000000A0422CFD800060709EC +:103050000622CFF00000000A0422D0180006070F55 +:103060000622D0300000000A0422D05800060715BE +:103070000622D0700000000A0422D0980006071B28 +:103080000622D0B00000000A0422D0D80006072192 +:103090000622D0F00000000A0422D11800060727FB +:1030A0000622D1300000000A0422D1580006072D64 +:1030B0000622D1700000000A0422D19800060733CE +:1030C0000622D1B00000000A0422D1D80006073938 +:1030D0000622D1F00000000A0422D2180006073FA1 +:1030E0000622D2300000000A0422D258000607450A +:1030F0000622D2700000000A0422D2980006074B74 +:103100000622D2B00000000A0422D2D800060751DD +:103110000622D2F00000000A0422D3180006075746 +:103120000622D3300000000A0422D3580006075DAF +:103130000622D3700000000A0422D3980006076319 +:103140000622D3B00000000A0422D3D80006076983 +:103150000622D3F00000000A0422D4180006076FEC +:103160000622D4300000000A0422D4580006077555 +:103170000622D4700000000A0422D4980006077BBF +:103180000622D4B00000000A0422D4D80006078129 +:103190000622D4F00000000A0422D5180006078792 +:1031A0000622D5300000000A0422D5580006078DFB +:1031B0000622D5700000000A0422D5980006079365 +:1031C0000622D5B00000000A0422D5D800060799CF +:1031D0000622D5F00000000A0422D6180006079F38 +:1031E0000622D6300000000A0422D658000607A5A1 +:1031F0000622D6700000000A0422D698000607AB0B +:103200000622D6B00000000A0422D6D8000607B174 +:103210000622D6F00000000A0422D718000607B7DD +:103220000622D7300000000A0422D758000607BD46 +:103230000622D7700000000A0422D798000607C3B0 +:103240000622D7B00000000A0422D7D8000607C91A +:103250000622D7F00000000A0422D818000607CF83 +:103260000622D8300000000A0422D858000607D5EC +:103270000622D8700000000A0422D898000607DB56 +:103280000622D8B00000000A0422D8D8000607E1C0 +:103290000622D8F00000000A0422D918000607E729 +:1032A0000622D9300000000A0422D958000607ED92 +:1032B0000622D9700000000A0422D998000607F3FC +:1032C0000622D9B00000000A0422D9D8000607F966 +:1032D0000622D9F00000000A0422DA18000607FFCF +:1032E0000622DA300000000A0422DA580006080537 +:1032F0000622DA700000000A0422DA980006080BA1 +:103300000622DAB00000000A0422DAD8000608110A +:103310000622DAF00000000A0422DB180006081773 +:103320000622DB300000000A0422DB580006081DDC +:103330000622DB700000000A0422DB980006082346 +:103340000622DBB00000000A0422DBD800060829B0 +:103350000622DBF00000000A0422DC180006082F19 +:103360000622DC300000000A0422DC580006083582 +:103370000622DC700000000A0422DC980006083BEC +:103380000622DCB00000000A0422DCD80006084156 +:103390000622DCF00000000A0422DD1800060847BF +:1033A0000622DD300000000A0422DD580006084D28 +:1033B0000622DD700000000A0422DD980006085392 +:1033C0000622DDB00000000A0422DDD800060859FC +:1033D0000622DDF00000000A0422DE180006085F65 +:1033E0000622DE300000000A0422DE5800060865CE +:1033F0000622DE700000000A0422DE980006086B38 +:103400000622DEB00000000A0422DED800060871A1 +:103410000622DEF00000000A0422DF18000608770A +:103420000622DF300000000A0422DF580006087D73 +:103430000622DF700000000A0422DF9800060883DD +:103440000622DFB00000000A0422DFD80006088947 +:103450000622DFF00000000A0422E0180006088FB0 +:103460000622E0300000000A0422E0580006089519 +:103470000622E0700000000A0422E0980006089B83 +:103480000622E0B00000000A0422E0D8000608A1ED +:103490000622E0F00000000A0422E118000608A756 +:1034A0000622E1300000000A0422E158000608ADBF +:1034B0000622E1700000000A0422E198000608B329 +:1034C0000622E1B00000000A0422E1D8000608B993 +:1034D0000622E1F000000004062215380000000278 +:1034E000062211E8000000020622F3000000000896 +:1034F00002221148000000000622590000000006C8 +:103500000622330000000002062260400000003066 +:103510000622F320000000080222114C00000000E7 +:103520000622591800000006062233080000000297 +:1035300006226100000000300622F340000000086F +:10354000022211500000000006225930000000063F +:103550000622331000000002062261C00000003085 +:103560000622F3600000000802221154000000004F +:103570000622594800000006062233180000000207 +:1035800006226280000000300622F380000000085E +:1035900002221158000000000622596000000006B7 +:1035A00006223320000000020622634000000030A3 +:1035B0000622F3A0000000080222115C00000000B7 +:1035C0000622597800000006062233280000000277 +:1035D00006226400000000300622F3C0000000084C +:1035E000022211600000000006225990000000062F +:1035F0000622333000000002062264C000000030C2 +:103600000622F3E00000000802221164000000001E +:10361000062259A8000000060622333800000002E6 +:10362000062265800000003002161000000000280D +:1036300002170008000000020217002C000000031F +:103640000217003C000000040217004400000000C4 +:1036500002170048000000020217004C0000009012 +:1036600002170050000000900217005400800090E4 +:103670000217005808100000021700700000000632 +:1036800002170078000009FF0217007C0000076C99 +:10369000021701C4081000000217034400000001D3 +:1036A000021704000000008A0217040400000080D2 +:1036B00002170408000000810217040C00000080BB +:1036C000021704100000008A021704140000008092 +:1036D00002170418000000810217041C000000807B +:1036E000021704300000008A021704340000008032 +:1036F00002170438000000810217043C000000801B +:10370000021704400000008A0217044400000080F1 +:1037100002170448000000810217044C00000080DA +:10372000021704800000008A021704840000008051 +:1037300002170488000000810217048C000000803A +:1037400002170038007C1004021700040000000F6C +:10375000021701EC00000002021701F40000000251 +:10376000021701EC00000002021701F40000000241 +:10377000021701EC00000002021701F40000000231 +:10378000021701EC00000002021701F40000000221 +:10379000021701EC00000002021701F40000000211 +:1037A000021701EC00000002021701F40000000201 +:1037B000021701EC00000002021701F400000002F1 +:1037C000021701EC00000002021701F400000002E1 +:1037D0000616402400000002021640700000001C83 +:1037E000021642080000000102164210000000010B +:1037F00002164220000000010216422800000001CB +:10380000021642300000000102164238000000019A +:1038100002164260000000020C16401C0003D0900B +:103820000A16401C0000009C0B16401C0000027190 +:103830000216403000000028021640340000002C20 +:1038400002164038000000300216404400000020FC +:103850000216400000000001021640D800000001DE +:1038600002164008000000010216400C0000000192 +:103870000216401000000001021642400000000045 +:1038800002164248000000000616427000000002C6 +:1038900002164250000000000216425800000000CC +:1038A0000616428000000002021660080000121492 +:1038B0000216600C000012000216601000001204D4 +:1038C0000216601C0000FFFF021660200000FFFFD0 +:1038D000021660240000FFFF021660280000FFFFB0 +:1038E00002166038000000200216603C0000001044 +:1038F0000616604000000002021660480000002327 +:103900000216604C000000240216605000000025E2 +:1039100002166054000000260216605800000027BE +:103920000216605C000000110216606000000000DA +:10393000021660640000002B021660680000002C74 +:103940000216606C0000002D02166070000000EC92 +:103950000216607400000000021660780000002962 +:103960000216607C0000002A021660800000002F12 +:10397000061660840000000D021660B80000000109 +:10398000061660BC00000008021660DC00000001A2 +:10399000061660E000000004021660F0000000015E +:1039A000061660F40000000302166100000000012A +:1039B000061661040000002D021661B80000000127 +:1039C000061661BC00000008021661DC0000000160 +:1039D000061661E000000004021661F0000000011C +:1039E000061661F4000000030216620000000001E8 +:1039F000061662040000000D0216623807FFFFFF82 +:103A00000216623C0000007F0216624007FFFFFFC3 +:103A1000021662440000003F0116624800000000E8 +:103A20000116624C00000000011662500000000008 +:103A300001166254000000000116625800000000E8 +:103A40000116625C000000000116626000000000C8 +:103A500001166264000000000116626800000000A8 +:103A60000116626C00000000011662700000000088 +:103A70000116627400000000011662780000000068 +:103A80000116627C00000000011662D400000000F4 +:103A9000021662D80000FFFF021662DC0000FFFF82 +:103AA000021662E00000FFFF021662E40000FFFF62 +:103AB0000C166000000003E80A1660000000000118 +:103AC0000B16600000000003021680400000000694 +:103AD0000216804400000005021680480000000A1B +:103AE0000216804C000000050216805400000002FF +:103AF000021680CC00000004021680D000000004F2 +:103B0000021680D400000004021680D800000004D1 +:103B1000021680DC00000004021680E000000004B1 +:103B2000021680E400000004021680E80000000491 +:103B30000216880400000006021680300000007C97 +:103B4000021680340000003D021680380000003F5D +:103B50000216803C0000009C0216E6E800006000AF +:103B60000216E6EC000060000216E6F000006000BD +:103B70000216E6F40000600002168234000025E41C +:103B8000021682380000800002168094000025E3AF +:103B9000021681F400000C08021681F800000040B3 +:103BA000021681FC000001000216820000000020C5 +:103BB000021682040000001702168208000000802E +:103BC0000216820C000002000216821000000000A3 +:103BD0000216823C0000001302168220008F008F24 +:103BE0000216821C008F008F021680F00000000772 +:103BF0000216821801FF01FF0216821401FF01FF65 +:103C0000061680F4000000020216811C0000000568 +:103C10000216812000000005021681240000000524 +:103C200002168128000000080216812C0000000600 +:103C300002168130000000070616813400000004DF +:103C4000021680FC000000000616814400000002FD +:103C50000216814C00000004021681500000000191 +:103C6000021681540000000202168158000000056F +:103C70000216815C0000000502168160000000054C +:103C80000216816400000005021681680000000829 +:103C900002168100000000000216816C0000000680 +:103CA00002168170000000070616817400000006ED +:103CB0000216818C000000040216819000000001B1 +:103CC0000216810400000000021681940000000228 +:103CD00002168198000000050216819C0000000574 +:103CE000021681A000000005021681A40000000554 +:103CF000021681A800000008021681AC0000000630 +:103D0000021681B000000007061681B40000000210 +:103D10000216810800000000061681BC00000004A5 +:103D2000021681CC00000004021681D000000001C0 +:103D3000021681D400000002021681D8000000059E +:103D4000021681DC00000005021681E0000000057B +:103D50000216810C00000004021681E40000000538 +:103D6000021681E800000008021681EC000000063F +:103D7000021681F000000007021681100000000109 +:103D800002168114000000020216811800000005CE +:103D90000216809C0000004C021680A00000004C1F +:103DA000061680C400000002021680A40000000075 +:103DB000021680A800000000021680AC0000004C33 +:103DC000061680B0000000050216E6F800000204A6 +:103DD00002168240003F003F02168244003F003F2F +:103DE00006168290000000040216824800800080BF +:103DF0000216824C008000800216825001000100F1 +:103E000002168254010001000616825800000002CA +:103E100002168260004000400216826400400040AA +:103E2000021682681E001E000216826C1E001E0012 +:103E3000021682704000400002168274400040006A +:103E400002168278800080000216827C800080004A +:103E500002168280200020000216828420002000AA +:103E60000616828800000002021680900000004BB7 +:103E700002168060000001400216806400000140CC +:103E8000061680880000000202168068000000000C +:103E90000216806C0000000002168070000000C056 +:103EA00006168074000000050216880C010101014D +:103EB000021688100101200402168814200810013F +:103EC00002168818010101200216881C0101010157 +:103ED00002168820010120040216882420081001FF +:103EE00002168828010101200216882C20081001E2 +:103EF00002168830010101200216883401010101F7 +:103F000002168838010120040216883C200810019E +:103F100002168840010101200216884401010101B6 +:103F200002168848010120040216E6BC00000000C9 +:103F30000216E6C0000000020216E6C400000004FB +:103F40000216E6C8000000060216E7940000000111 +:103F5000021680EC000000FF0214000000000001C7 +:103F60000215C024000000000215C0EC0000000192 +:103F70000215C0F0000000010615C100000000029B +:103F800002140004000000010214000800000001F7 +:103F90000214000C000000010214003000000001B7 +:103FA000021400340000000102140040000000016F +:103FB000021400440000FFFF061400040000000388 +:103FC0000214000000000000060280000000200033 +:103FD0000202005800000032020200A00315002077 +:103FE000020200A403150020020200A80100003014 +:103FF000020200AC08100000020200B0000000360F +:10400000020200B400000030020200B800000031DB +:10401000020200BC00000002020200C00000000515 +:10402000020200C400000002020200C800000002F8 +:10403000020200D000000007020200DC00000000C5 +:10404000020200E000000005020200E4000000039C +:10405000020200F000000001020200FC0000000665 +:1040600002020120000000000202013400000002F0 +:10407000020201B0000000010202020C0000000177 +:1040800002020214000000010202021800000002F5 +:1040900002020404000000010202040C00000040BF +:1040A00002020410000000400202041C0000000490 +:1040B000020204200000002002020424000000028A +:1040C0000202042800000020060205000000001281 +:1040D00004020480002008BF020200600000000FFC +:1040E00002020064000000070202006800000000F5 +:1040F0000202006C0000000E020200700000000EC0 +:104100000602007400000003020200F40000000434 +:104110000202000400000001020200080000000189 +:104120000202000C00000001020200100000000169 +:104130000202001400000001020200180000000149 +:104140000202001C00000001020200200000000129 +:104150000202002400000001020200280000000109 +:104160000202002C000000010202003000000001E9 +:1041700002020034000000010202003800000001C9 +:104180000202003C000000010202004000000001A9 +:104190000202004400000001020200480000000189 +:1041A0000202004C00000001020200500000000169 +:1041B00002020108000000C802020118000000020B +:1041C000020201C400000000020201CC0000000055 +:1041D000020201D400000002020201DC0000000221 +:1041E000020201E4000000FF020201EC000000FFF7 +:1041F00002020100000000000202010C000000C8E1 +:104200000202011C00000002020201C800000000BE +:10421000020201D000000000020201D800000002EA +:10422000020201E000000002020201E8000000FFBB +:10423000020201F0000000FF020201040000002061 +:1042400002020108000000C802020118000000027A +:10425000020201C400000000020201CC00000000C4 +:10426000020201D400000002020201DC0000000290 +:10427000020201E4000000FF020201EC000000FF66 +:1042800002020100000000100202010C000000C840 +:104290000202011C00000002020201C8000000002E +:1042A000020201D000000000020201D8000000025A +:1042B000020201E000000002020201E8000000FF2B +:1042C000020201F0000000FF0202010400000030C1 +:1042D00002020108000000C80202011800000002EA +:1042E000020201C400000000020201CC0000000034 +:1042F000020201D400000002020201DC0000000200 +:10430000020201E4000000FF020201EC000000FFD5 +:1043100002020100000000400202010C000000C87F +:104320000202011C00000002020201C8000000009D +:10433000020201D000000000020201D800000002C9 +:10434000020201E000000002020201E8000000FF9A +:10435000020201F0000000FF020201040000006000 +:1043600002020108000000C8020201180000000259 +:10437000020201C400000000020201CC00000000A3 +:10438000020201D400000002020201DC000000026F +:10439000020201E4000000FF020201EC000000FF45 +:1043A00002020100000000500202010C000000C8DF +:1043B0000202011C00000002020201C8000000000D +:1043C000020201D000000000020201D80000000239 +:1043D000020201E000000002020201E8000000FF0A +:1043E000020201F0000000FF020201040000007060 +:1043F0000728040000B50000082807B8000908DFF6 +:10440000072C000028C30000072C800036720A31F8 +:10441000072D000035B617CE072D80003B00253C48 +:10442000072E0000366D33FD072E80001AA8419933 +:10443000082EBF20281C08E1012800000000000011 +:10444000012800040000000001280008000000000E +:104450000128000C000000000128001000000000EE +:1044600001280014000000000228002000000001C4 +:104470000228002400000002022800280000000397 +:104480000228002C00000000022800300000000478 +:10449000022800340000000102280038000000005B +:1044A0000228003C00000001022800400000000437 +:1044B000022800440000000002280048000000011B +:1044C0000228004C000000030228005000000000F9 +:1044D00002280054000000010228005800000004D7 +:1044E0000228005C000000000228006000000001BB +:1044F0000228006400000003022800680000000099 +:104500000228006C00000001022800700000000476 +:104510000228007400000000022800780000000457 +:104520000228007C00000003062800800000000232 +:10453000022800A400007FFF022800A8000003FF5B +:1045400002280224000000000228023400000000BB +:104550000228024C00000000022802E40000FFFFD5 +:104560000628200000000800022B8BC0000000017C +:10457000022B800000000000022B80400000001889 +:10458000022B80800000000C022B80C0000000661F +:104590000C2B8300000864700A2B83000000015775 +:1045A0000B2B83000000055F0A2B834000000000F6 +:1045B0000C2B8340000002260B2B834000000001DF +:1045C000022B838000086470022B83C00000022647 +:1045D000022B1480000000010A2B14800000000050 +:1045E000022B944000000001062B944800000002BA +:1045F000062A9A7000000004042A9A80000408E346 +:10460000062A9A9000000002042A9A98000208E7FD +:10461000062A900000000048062A2008000000C872 +:10462000062A200000000002062A912800000086C9 +:10463000062AC00000000120062A9348000000035B +:10464000042A9354000108E9062A9FB000000002E2 +:10465000042A9418000208EA042A9CD0000108ECFD +:10466000062A9CD400000011042A9D20008F08ED2A +:10467000062A9F5C00000005042A30000002097C25 +:10468000062A300800000100062A40400000001001 +:10469000042A40000010097E042A84080002098EC2 +:1046A000042ACF4000040990042ACF600002099434 +:1046B000062A9FA000000004062A600000000540B2 +:1046C000062A9D1800000002062AB00000000050D3 +:1046D000062ABB7000000070062ABB6800000002BA +:1046E000062AB94800000004062AD000000008008D +:1046F000062AC48000000150062A942000000032DF +:10470000062A502000000002062A50300000000255 +:10471000062A500000000002062A50100000000285 +:10472000022A520800000001042A9AA000020996F9 +:10473000062A95B000000022042A96380001099844 +:10474000062A963C00000003062A96E0000000229C +:10475000042A976800010999062A976C0000000353 +:10476000062A981000000022042A98980001099A4D +:10477000062A989C00000003062A994000000022A7 +:10478000042A99C80001099B062A99CC000000035D +:10479000062ABB5800000002062AC9C000000150CA +:1047A000062A94E800000032062A50280000000281 +:1047B000062A503800000002062A500800000002B5 +:1047C000062A501800000002022A520C00000001C4 +:1047D000042A9AA80002099C062A96480000002292 +:1047E000042A96D00001099E062A96D400000003F0 +:1047F000062A977800000022042A98000001099FE9 +:10480000062A980400000003062A98A80000002247 +:10481000042A9930000109A0062A993400000003F7 +:10482000062A99D800000022042A9A60000109A1F2 +:10483000062A9A6400000003062ABB6000000002FA +:10484000022ACF0000000000042A9AB0001009A23A +:10485000062A50480000000E022ACF040000000083 +:10486000042A9AF0001009B2062A50800000000EB7 +:10487000022ACF0800000000042A9B30001009C261 +:10488000062A50B80000000E022ACF0C00000000DB +:10489000042A9B70001009D2062A50F00000000E76 +:1048A000022ACF1000000000042A9BB0001009E289 +:1048B000062A51280000000E022ACF140000000032 +:1048C000042A9BF0001009F2062A51600000000E35 +:1048D000022ACF1800000000042A9C3000100A02AF +:1048E000062A51980000000E022ACF1C000000008A +:1048F000042A9C7000100A12062A51D00000000EF3 +:104900000210100800000001021010500000000109 +:10491000021010000003D000021010040000003D3F +:104920000910180002000A220910110000100C22C0 +:1049300006101140000000080910116000100C3230 +:10494000061011A00000001806102400000000E06E +:104950000210201C000000000210202000000001B6 +:10496000021020C00000000202102004000000011C +:104970000210200800000001021030D800000001E1 +:1049800009103C0000050C420910380000050C47D6 +:104990000910392000050C4C09103B0000050C5192 +:1049A00006104C000000010002104028000000101A +:1049B0000210404400003FFF021040580028000051 +:1049C000021040840084924A021040580000000007 +:1049D00002104138000000010210413800000001BF +:1049E00002104138000000010210413800000001AF +:1049F000021041380000000102104138000000019F +:104A0000021041380000000102104138000000018E +:104A10000212049001F680400212051400003C10BE +:104A200002120494FFFFFFFF02120498FFFFFFFF32 +:104A30000212049CFFFFFFFF021204A0FFFFFFFF12 +:104A4000021204A4FFFFFFFF021204A8FFFFFFFFF2 +:104A5000021204ACFFFFFFFF021204B0FFFFFFFFD2 +:104A6000021204B8FFFFFFFF021204BCFFFFFFFFAA +:104A7000021204C0FFFFFFFF021204C4FFFFFFFF8A +:104A8000021204C8FFFFFFFF021204CCFFFFFFFF6A +:104A9000021204D0FFFFFFFF021204D8FFFFFFFF46 +:104AA000021204DCFFFFFFFF021204E0FFFFFFFF22 +:104AB000021204E4FFFFFFFF021204E8FFFFFFFF02 +:104AC000021204ECFFFFFFFF021204F0FFFFFFFFE2 +:104AD000021204F4FFFFFFFF021204F8FFFFFFFFC2 +:104AE000021204FCFFFFFFFF02120500FFFFFFFFA1 +:104AF00002120504FFFFFFFF02120508FFFFFFFF80 +:104B00000212050CFFFFFFFF02120510FFFFFFFF5F +:104B1000021204D4F800C000021204B4F0005000E5 +:104B200002120390000000080212039C000000081B +:104B3000021203A000000008021203A400000002F9 +:104B4000021203BC00000004021203C000000005B2 +:104B5000021203C400000004021203D0000000008F +:104B60000212036C00000001021201BC00000040B0 +:104B7000021201C000001808021201C4000008035C +:104B8000021201C800000803021201CC000000401C +:104B9000021201D000000003021201D40000080339 +:104BA000021201D800000803021201DC0000080311 +:104BB000021201E000010003021201E400000803F8 +:104BC000021201E800000803021201EC00000003D9 +:104BD000021201F000000003021201F400000003C1 +:104BE000021201F800000003021201FC00000003A1 +:104BF000021202000000000302120204000000037F +:104C000002120208000000030212020C000000035E +:104C1000021202100000000302120214000000033E +:104C200002120218000000030212021C000000031E +:104C300002120220000000030212022400000003FE +:104C400002120228000024030212022C0000002F8E +:104C500002120230000000090212023400000019A2 +:104C600002120238000001840212023C000001839B +:104C70000212024000000306021202440000001962 +:104C800002120248000000060212024C0000030655 +:104C90000212025000000306021202540000030632 +:104CA0000212025800000C860212025C0000030689 +:104CB00002120260000003060212026400000006F5 +:104CC00002120268000000060212026C00000006D8 +:104CD00002120270000000060212027400000006B8 +:104CE00002120278000000060212027C0000000698 +:104CF0000212028000000006021202840000000678 +:104D000002120288000000060212028C0000000657 +:104D10000212029000000006021202940000000637 +:104D200002120298000000060212029C0000000617 +:104D3000021202A000000306021202A400000013E7 +:104D4000021202A800000006021202B000001004C5 +:104D5000021202B400001004021203240010644086 +:104D60000212032800106440021205B40000000182 +:104D7000021205F800000040021205FC00000019B4 +:104D800002120600000000010212066C0000000181 +:104D9000021201B000000001021207D80000000357 +:104DA000021207D800000003021207D80000000317 +:104DB000021207D800000003021207D80000000307 +:104DC000021207D800000003021207D800000003F7 +:104DD000021207D8000000030600A0000000000C2B +:104DE0000200A050000000000200A05400000000DB +:104DF0000200A0EC555400000200A0F05555555596 +:104E00000200A0F4000055550200A0F8F0000000D8 +:104E10000200A0FC555400000200A1005555555554 +:104E20000200A104000055550200A108F000000096 +:104E30000200A19C000000000200A1A000010000EF +:104E40000200A1A4000050140200A1A8000000006C +:104E50000200A6A8000000000200A6AC00000000AE +:104E60000200A6D0000000000200A45C00000C00BC +:104E70000200A61C000000030200A070FFF55FFF07 +:104E80000200A0740000FFFF0200A078F00003E021 +:104E90000200A07C000000000200A0800000A00032 +:104EA0000600A084000000050200A0980FE00000AA +:104EB0000600A09C000000070200A0B8000004004B +:104EC0000600A0BC000000030200A0C80000100003 +:104ED0000600A0CC000000030200A0D800004000A3 +:104EE0000600A0DC000000030200A0E800010000B2 +:104EF0000600A22C000000040200A688000000FCAE +:104F00000600A68C000000070200A6F400000000C6 +:104F10000200A10CFF5C00000200A110FFF55FFF82 +:104F20000200A1140000FFFF0200A118F00003E03E +:104F30000200A11C000000000200A1200000A0004F +:104F40000600A124000000050200A1380FE00000C7 +:104F50000600A13C000000070200A1580000080064 +:104F60000600A15C000000030200A1680000200010 +:104F70000600A16C000000030200A1780000800080 +:104F80000600A17C000000030200A18800020000CE +:104F90000600A23C000000040200A6B0000000FCD5 +:104FA0000600A6B4000000070200A6F800000000FA +:104FB0000200A030000000000200A0340000000049 +:104FC0000200A038000000000200A03C0000000029 +:104FD0000200A040000000000200A0440000000009 +:104FE0000200A048000000000200A04C00000000E9 +:104FF000020090C40000E000020090CC0000F3002A +:10500000020090D400000003020091A00000000103 +:105010000600917000000003020090EC00006000A8 +:10502000020090F400007300020090FC00000003F6 +:10503000020091A800000001060091880000000312 +:10504000020091000000400002009108000053009F +:105050000200911000000004020091AC0000000169 +:1050600006009194000000020200919C00000001E3 +:10507000020090D800006000020090E00000730081 +:10508000020090E800000003020091A4000000016B +:105090000200917C000000010200918000000001EC +:1050A000020091840000000002009128000003002B +:1050B0000200916C0003F0080200912C0000030034 +:1050C0000200913000000300020091340000030050 +:1050D00002009138000003000200913C0000030030 +:1050E00002009140000003000200942C0000000127 +:1050F000020094300000000102009434000000011E +:105100000200942C00000001020094300000000115 +:1051100002009434000000010200942C0000000101 +:1051200002009430000000010200943400000001ED +:105130000200942C000000010200943000000001E5 +:1051400002009434000000010200942C00000001D1 +:1051500002009430000000010200943400000001BD +:105160000200942C000000010200943000000001B5 +:1051700002009434000000010200942C00000001A1 +:10518000020094300000000102009434000000018D +:105190000200942C00000001020094300000000185 +:1051A00002009434000000010213003C000061A8DA +:1051B00006130108000000030213010400000000B0 +:1051C0000213013400000000061301080000000370 +:1051D000021301040000000002130134000000006B +:1051E0000613010800000003021301040000000080 +:1051F0000213013400000000061301080000000340 +:10520000021301040000000002130134000000003A +:10521000061301080000000302130104000000004F +:10522000021301340000000006130108000000030F +:10523000021301040000000002130134000000000A +:10524000061301080000000302130104000000001F +:1052500002130134000000000613010800000003DF +:1052600002130104000000000213013400000000DA +:10527000021100B8000000010216E6E8000020005C +:105280000216E6EC000020000216E6F0000065556C +:105290000216E6F400006555021681500000000079 +:1052A00002168174000000010216817800000001DE +:1052B0000216817C000000010216818000000001BE +:1052C000021681840000000102168188000000019E +:1052D000021681B400000001021681B8000000012E +:1052E000021681BC00000001021681C0000000010E +:1052F000021681C400000001021681C800000001EE +:1053000002168110000000000216824000BF00BF9C +:1053100006168244000000020216824C00BF00BF45 +:105320000216E6C4000000010216E6C800000003F1 +:105330000216E79400000000042ACF40000A0C5631 +:105340000000000000000000000000340000000029 +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:1053700000000000003400350000000000000000C4 +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A0000035006000000000000000000000000068 +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000600091EC +:1053D0000000000000000000009100950095009979 +:1053E0000099009D009D00A100A100A500A500A9B5 +:1053F00000A900AD00AD00B100B100B50000000093 +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:105420000000000000B503100310031A031A032440 +:105430000324032B032B03320332033903390340C4 +:10544000034003470347034E034E03550355035CD4 +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000035C035D0000000000000000035D035E1B +:10551000035E035F035F0360036003610361036273 +:105520000362036303630364036403650000000014 +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:1055500000000000000000000365036C036C03788A +:105560000378038400000000000000000000000039 +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00003840385000000000000000000000000DC +:1055C00000000000000000000000000000000000DB +:1055D000000000000000000000000000038503B090 +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000003B003DF0000000005 +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:105630000000000003DF040E000000000000000076 +:10564000040E04150415041C041C04230423042A5A +:10565000042A0431043104380438043F043F04466A +:105660000446047900000000000000000479047D75 +:10567000047D048104810485048504890489048DE2 +:10568000048D04910491049504950499049904E807 +:1056900004E804FE04FE0514051405160516051895 +:1056A0000518051A051A051C051C051E051E0520F2 +:1056B000052005220522052405240690000000008F +:1056C00000000000069006950695069A069A069F29 +:1056D000069F06A406A406A906A906AE06AE06B352 +:1056E00006B306B806B806B90000000000000000C6 +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:1057100006B906DD000000000000000006DD06DF1F +:1057200006DF06E106E106E306E306E506E506E731 +:1057300006E706E906E906EB06EB06ED06ED0702CD +:105740000702070507050708000000000000000029 +:105750000000000000000000000000000000000049 +:1057600000000000000000000708074C00000000D7 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:1057900000000000074C07DE0000000000000000D1 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00007DE07EC00000000000000000000000001 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000007EC082995 +:1057F0000000000000000000082908320832083BC1 +:10580000083B08440844084D084D08560856085FF0 +:10581000085F086808680871087108D108D108E6AF +:1058200008E608FB08FB08FE08FE09010901090457 +:10583000090409070907090A090A090D090D0910D0 +:10584000091009130913091C0000000000000000E2 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:10587000091C0922000000000000000000000000D8 +:105880000000000000000000000000000000000018 +:1058900000000000000000000000000009220927AD +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000927092D0000000072 +:1058D00000000000092D092E092E092F092F09307B +:1058E00009300931093109320932093309330934E0 +:1058F000093409350000000000000000000000002D +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:10592000093509A6000000000000000009A609A72B +:1059300009A709A809A809A909A909AA09AA09ABD7 +:1059400009AB09AC09AC09AD09AD09AE09AE09C294 +:1059500009C209D509D509E909E909EA09EA09EB02 +:1059600009EB09EC09EC09ED09ED09EE09EE09EF87 +:1059700009EF09F009F009F109F10A10000000002F +:10598000000000000A100A130A130A160A160A1960 +:105990000A190A1C0A1C0A1F0A1F0A220A220A25BF +:1059A0000A250A280A280A29000000000000000031 +:1059B0000A290A2C0A2C0A2F0A2F0A320A320A351F +:1059C0000A350A380A380A3B0A3B0A3E0A3E0A41AF +:1059D0000A410A4200000000000000000000000030 +:1059E00000000000000000000000000000000000B7 +:1059F0000000000000000000000000000A420A5AF7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A200000000000000000000A5A0A5B00000000AD +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A5000000000000000000000010000000207003C +:105A600000030E000004150000051C0000062300C2 +:105A700000072A000008310000093800000A3F0032 +:105A8000000B4600000C4D00000D5400000E5B00A2 +:105A9000000F620000106900001170000012770012 +:105AA00000137E000014850000158C000016930082 +:105AB00000179A000018A1000019A800001AAF00F2 +:105AC000001BB600001CBD00001DC400001ECB0062 +:105AD000001FD2000000D90000002000000040009C +:105AE00000006000000080000000A0000000C00076 +:105AF0000000E00000010000000120000001400063 +:105B000000016000000180000001A0000001C00051 +:105B10000001E0000002000000022000000240003E +:105B200000026000000280000002A0000002C0002D +:105B30000002E0000003000000032000000340001A +:105B400000036000000380000003A0000003C00009 +:105B50000003E000000400000004200000044000F6 +:105B600000046000000480000004A0000004C000E5 +:105B70000004E000000500000005200000054000D2 +:105B800000056000000580000005A0000005C000C1 +:105B90000005E000000600000006200000064000AE +:105BA00000066000000680000006A0000006C0009D +:105BB0000006E0000007000000072000000740008A +:105BC00000076000000780000007A0000007C00079 +:105BD0000007E00000080000000820000008400066 +:105BE00000086000000880000008A0000008C00055 +:105BF0000008E00000090000000920000009400042 +:105C000000096000000980000009A0000009C00030 +:105C10000009E000000A0000000A2000000A40001D +:105C2000000A6000000A8000000AA000000AC0000C +:105C3000000AE000000B0000000B2000000B4000F9 +:105C4000000B6000000B8000000BA000000BC000E8 +:105C5000000BE000000C0000000C2000000C4000D5 +:105C6000000C6000000C8000000CA000000CC000C4 +:105C7000000CE000000D0000000D2000000D4000B1 +:105C8000000D6000000D8000000DA000000DC000A0 +:105C9000000DE000000E0000000E2000000E40008D +:105CA000000E6000000E8000000EA000000EC0007C +:105CB000000EE000000F0000000F2000000F400069 +:105CC000000F6000000F8000000FA000000FC00058 +:105CD000000FE00000100000001020000010400045 +:105CE00000106000001080000010A0000010C00034 +:105CF0000010E00000110000001120000011400021 +:105D000000116000001180000011A0000011C0000F +:105D10000011E000001200000012200000124000FC +:105D200000126000001280000012A0000012C000EB +:105D30000012E000001300000013200000134000D8 +:105D400000136000001380000013A0000013C000C7 +:105D50000013E000001400000014200000144000B4 +:105D600000146000001480000014A0000014C000A3 +:105D70000014E00000150000001520000015400090 +:105D800000156000001580000015A0000015C0007F +:105D90000015E0000016000000162000001640006C +:105DA00000166000001680000016A0000016C0005B +:105DB0000016E00000170000001720000017400048 +:105DC00000176000001780000017A0000017C00037 +:105DD0000017E00000180000001820000018400024 +:105DE00000186000001880000018A0000018C00013 +:105DF0000018E00000190000001920000019400000 +:105E000000196000001980000019A0000019C000EE +:105E10000019E000001A0000001A2000001A4000DB +:105E2000001A6000001A8000001AA000001AC000CA +:105E3000001AE000001B0000001B2000001B4000B7 +:105E4000001B6000001B8000001BA000001BC000A6 +:105E5000001BE000001C0000001C2000001C400093 +:105E6000001C6000001C8000001CA000001CC00082 +:105E7000001CE000001D0000001D2000001D40006F +:105E8000001D6000001D8000001DA000001DC0005E +:105E9000001DE000001E0000001E2000001E40004B +:105EA000001E6000001E8000001EA000001EC0003A +:105EB000001EE000001F0000001F2000001F400027 +:105EC000001F6000001F8000001FA000001FC00016 +:105ED000001FE00000200000002020000020400003 +:105EE00000206000002080000020A0000020C000F2 +:105EF0000020E000002100000021200000214000DF +:105F000000216000002180000021A0000021C000CD +:105F10000021E000002200000022200000224000BA +:105F200000226000002280000022A0000022C000A9 +:105F30000022E00000230000002320000023400096 +:105F400000236000002380000023A0000023C00085 +:105F50000023E00000240000002420000024400072 +:105F600000246000002480000024A0000024C00061 +:105F70000024E0000025000000252000002540004E +:105F800000256000002580000025A0000025C0003D +:105F90000025E0000026000000262000002640002A +:105FA00000266000002680000026A0000026C00019 +:105FB0000026E00000270000002720000027400006 +:105FC00000276000002780000027A0000027C000F5 +:105FD0000027E000002800000028200000284000E2 +:105FE00000286000002880000028A0000028C000D1 +:105FF0000028E000002900000029200000294000BE +:1060000000296000002980000029A0000029C000AC +:106010000029E000002A0000002A2000002A400099 +:10602000002A6000002A8000002AA000002AC00088 +:10603000002AE000002B0000002B2000002B400075 +:10604000002B6000002B8000002BA000002BC00064 +:10605000002BE000002C0000002C2000002C400051 +:10606000002C6000002C8000002CA000002CC00040 +:10607000002CE000002D0000002D2000002D40002D +:10608000002D6000002D8000002DA000002DC0001C +:10609000002DE000002E0000002E2000002E400009 +:1060A000002E6000002E8000002EA000002EC000F8 +:1060B000002EE000002F0000002F2000002F4000E5 +:1060C000002F6000002F8000002FA000002FC000D4 +:1060D000002FE000003000000030200000304000C1 +:1060E00000306000003080000030A0000030C000B0 +:1060F0000030E0000031000000312000003140009D +:1061000000316000003180000031A0000031C0008B +:106110000031E00000320000003220000032400078 +:1061200000326000003280000032A0000032C00067 +:106130000032E00000330000003320000033400054 +:1061400000336000003380000033A0000033C00043 +:106150000033E00000340000003420000034400030 +:1061600000346000003480000034A0000034C0001F +:106170000034E0000035000000352000003540000C +:1061800000356000003580000035A0000035C000FB +:106190000035E000003600000036200000364000E8 +:1061A00000366000003680000036A0000036C000D7 +:1061B0000036E000003700000037200000374000C4 +:1061C00000376000003780000037A0000037C000B3 +:1061D0000037E000003800000038200000384000A0 +:1061E00000386000003880000038A0000038C0008F +:1061F0000038E0000039000000392000003940007C +:1062000000396000003980000039A0000039C0006A +:106210000039E000003A0000003A2000003A400057 +:10622000003A6000003A8000003AA000003AC00046 +:10623000003AE000003B0000003B2000003B400033 +:10624000003B6000003B8000003BA000003BC00022 +:10625000003BE000003C0000003C2000003C40000F +:10626000003C6000003C8000003CA000003CC000FE +:10627000003CE000003D0000003D2000003D4000EB +:10628000003D6000003D8000003DA000003DC000DA +:10629000003DE000003E0000003E2000003E4000C7 +:1062A000003E6000003E8000003EA000003EC000B6 +:1062B000003EE000003F0000003F2000003F4000A3 +:1062C000003F6000003F8000003FA000003FC00092 +:1062D000003FE000003FE00100000000000001FF7F +:1062E0000000020000007FF800007FF800000A9420 +:1062F00000001500000000010000FF000000000089 +:106300000000FF00000000000000FF00000000008F +:106310000000FF00000000000000FF00000000007F +:106320000000FF00000000000000FF00000000006F +:106330000000FF00000000000000FF00000000005F +:106340000000FF00000000000000FF00000000004F +:106350000000FF00000000000000FF00000000003F +:106360000000FF00000000000000FF00000000002F +:106370000000FF00000000000000FF00000000001F +:106380000000FF00000000000000FF00000000000F +:106390000000FF00000000000000FF0000000000FF +:1063A0000000FF00000000000000FF0000000000EF +:1063B0000000FF00000000000000FF0000000000DF +:1063C0000000FF00000000000000FF0000000000CF +:1063D0000000FF00000000000000FF0000000000BF +:1063E0000000FF00000000000000FF0000000000AF +:1063F0000000FF00000000000000FF00000000009F +:106400000000FF00000000000000FF00000000008E +:106410000000FF00000000000000FF00000000007E +:106420000000FF00000000000000FF00000000006E +:106430000000FF00000000000000FF00000000005E +:106440000000FF00000000000000FF00000000004E +:106450000000FF00000000000000FF00000000003E +:106460000000FF00000000000000FF00000000002E +:106470000000FF00000000000000FF00000000001E +:106480000000FF00000000000000FF00000000000E +:106490000000FF00000000000000FF0000000000FE +:1064A0000000FF00000000000000FF0000000000EE +:1064B0000000FF00000000000000FF0000000000DE +:1064C0000000FF00000000000000FF0000000000CE +:1064D0000000FF00000000000000FF0000000000BE +:1064E0000000FF00000000000000FF0000000000AE +:1064F0000000FF00000000000000FF00000000009E +:106500000000FF00000000000000FF00000000008D +:106510000000FF00000000000000FF00000000007D +:106520000000FF00000000000000FF00000000006D +:106530000000FF000000000000000000140AFF003F +:106540000000000100000000002010010000000019 +:106550000100900000000100000090020000900483 +:1065600000009006000090080000900A0000900CC7 +:106570000000900E00009010000090120000901497 +:1065800000009016000090180000901A0000901C67 +:106590000000901E00009020000090220000902437 +:1065A00000009026000090280000902A0000902C07 +:1065B0000000902E000090300000903200009034D7 +:1065C00000009036000090380000903A0000903CA7 +:1065D0000000903E00009040000090420000904477 +:1065E00000009046000090480000904A0000904C47 +:1065F0000000904E00009050000090520000905417 +:1066000000009056000090580000905A0000905CE6 +:106610000000905E000090600000906200009064B6 +:1066200000009066000090680000906A0000906C86 +:106630000000906E00009070000090720000907456 +:1066400000009076000090780000907A0000907C26 +:106650000000907E000090800000908200009084F6 +:1066600000009086000090880000908A0000908CC6 +:106670000000908E00009090000090920000909496 +:1066800000009096000090980000909A0000909C66 +:106690000000909E000090A0000090A2000090A436 +:1066A000000090A6000090A8000090AA000090AC06 +:1066B000000090AE000090B0000090B2000090B4D6 +:1066C000000090B6000090B8000090BA000090BCA6 +:1066D000000090BE000090C0000090C2000090C476 +:1066E000000090C6000090C8000090CA000090CC46 +:1066F000000090CE000090D0000090D2000090D416 +:10670000000090D6000090D8000090DA000090DCE5 +:10671000000090DE000090E0000090E2000090E4B5 +:10672000000090E6000090E8000090EA000090EC85 +:10673000000090EE000090F0000090F2000090F455 +:10674000000090F6000090F8000090FA000090FC25 +:10675000000090FE000091000000910200009104F2 +:1067600000009106000091080000910A0000910CC1 +:106770000000910E00009110000091120000911491 +:1067800000009116000091180000911A0000911C61 +:106790000000911E00009120000091220000912431 +:1067A00000009126000091280000912A0000912C01 +:1067B0000000912E000091300000913200009134D1 +:1067C00000009136000091380000913A0000913CA1 +:1067D0000000913E00009140000091420000914471 +:1067E00000009146000091480000914A0000914C41 +:1067F0000000914E00009150000091520000915411 +:1068000000009156000091580000915A0000915CE0 +:106810000000915E000091600000916200009164B0 +:1068200000009166000091680000916A0000916C80 +:106830000000916E00009170000091720000917450 +:1068400000009176000091780000917A0000917C20 +:106850000000917E000091800000918200009184F0 +:1068600000009186000091880000918A0000918CC0 +:106870000000918E00009190000091920000919490 +:1068800000009196000091980000919A0000919C60 +:106890000000919E000091A0000091A2000091A430 +:1068A000000091A6000091A8000091AA000091AC00 +:1068B000000091AE000091B0000091B2000091B4D0 +:1068C000000091B6000091B8000091BA000091BCA0 +:1068D000000091BE000091C0000091C2000091C470 +:1068E000000091C6000091C8000091CA000091CC40 +:1068F000000091CE000091D0000091D2000091D410 +:10690000000091D6000091D8000091DA000091DCDF +:10691000000091DE000091E0000091E2000091E4AF +:10692000000091E6000091E8000091EA000091EC7F +:10693000000091EE000091F0000091F2000091F44F +:10694000000091F6000091F8000091FA000091FC1F +:10695000000091FEFFFFFFFFFFFFFFFFFFFFFFFFB4 +:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:1069D000FFFFFFFF0000000300BEBC20000000001E +:1069E000000000050000000300BEBC200000000005 +:1069F000000000050000000300BEBC2000000000F5 +:106A0000000000050000000300BEBC2000000000E4 +:106A1000000000050000000300BEBC2000000000D4 +:106A2000000000050000000300BEBC2000000000C4 +:106A3000000000050000000300BEBC2000000000B4 +:106A4000000000050000000300BEBC2000000000A4 +:106A50000000000500002000000040C00000618030 +:106A6000000082400000A3000000C3C00000E480DA +:106A70000001054000012600000146C000016780BA +:106A8000000188400001A9000001C9C00001EA809E +:106A900000020B4000022C0000024CC000026D807E +:106AA00000028E400002AF000002CFC00002F08062 +:106AB00000001140000080000001038000018700F9 +:106AC00000020A8000028E0000031180000395007E +:106AD0000004188000049C0000051F800005A3002E +:106AE000000626800006AA0000072D800007B100DE +:106AF000000834800008B80000093B800009BF008E +:106B0000000A4280000AC600000B4980000BCD003D +:106B1000000C5080000CD400000D578000005B007A +:106B200000007FF800007FF80000022A0000350016 +:106B30000000FF00000000000000FF000000000057 +:106B40000000FF00000000000000FF000000000047 +:106B50000000FF00000000000000FF000000000037 +:106B60000000FF00000000000000FF000000000027 +:106B70000000FF00000000000000FF000000000017 +:106B80000000FF00000000000000FF000000000007 +:106B90000000FF00000000000000FF0000000000F7 +:106BA0000000FF00000000000000FF0000000000E7 +:106BB0000000FF00000000000000FF0000000000D7 +:106BC0000000FF00000000000000FF0000000000C7 +:106BD0000000FF00000000000000FF0000000000B7 +:106BE0000000FF00000000000000FF0000000000A7 +:106BF0000000FF00000000000000FF000000000097 +:106C00000000FF00000000000000FF000000000086 +:106C10000000FF00000000000000FF000000000076 +:106C20000000FF00000000000000FF000000000066 +:106C30000000FF00000000000000FF000000000056 +:106C40000000FF00000000000000FF000000000046 +:106C50000000FF00000000000000FF000000000036 +:106C60000000FF00000000000000FF000000000026 +:106C70000000FF00000000000000FF000000000016 +:106C80000000FF00000000000000FF000000000006 +:106C90000000FF00000000000000FF0000000000F6 +:106CA0000000FF00000000000000FF0000000000E6 +:106CB0000000FF00000000000000FF0000000000D6 +:106CC0000000FF00000000000000FF0000000000C6 +:106CD0000000FF00000000000000FF0000000000B6 +:106CE0000000FF00000000000000FF0000000000A6 +:106CF0000000FF00000000000000FF000000000096 +:106D00000000FF00000000000000FF000000000085 +:106D10000000FF00000000000000FF000000000075 +:106D20000000FF00000000000000FF000000000065 +:106D30000000FF00000000000000FF000000000055 +:106D40000000FF00000000000000FF000000000045 +:106D50000000FF00000000000000FF000000000035 +:106D60000000FF00000000000000FF00000019000C +:106D70000000000000000000FFFFFFFF0000000017 +:106D800003938700000000000393870000007FF852 +:106D900000007FF800000BA700003500000000FF96 +:106DA000000000FF000000FF000000FF000000FFE7 +:106DB000000000FF000000FF000000FF0000FF00D7 +:106DC000000000000000FF00000000000000FF00C5 +:106DD000000000000000FF00000000000000FF00B5 +:106DE000000000000000FF00000000000000FF00A5 +:106DF000000000000000FF00000000000000FF0095 +:106E0000000000000000FF00000000000000FF0084 +:106E1000000000000000FF00000000000000FF0074 +:106E2000000000000000FF00000000000000FF0064 +:106E3000000000000000FF00000000000000FF0054 +:106E4000000000000000FF00000000000000FF0044 +:106E5000000000000000FF00000000000000FF0034 +:106E6000000000000000FF00000000000000FF0024 +:106E7000000000000000FF00000000000000FF0014 +:106E8000000000000000FF00000000000000FF0004 +:106E9000000000000000FF00000000000000FF00F4 +:106EA000000000000000FF00000000000000FF00E4 +:106EB000000000000000FF00000000000000FF00D4 +:106EC000000000000000FF00000000000000FF00C4 +:106ED000000000000000FF00000000000000FF00B4 +:106EE000000000000000FF00000000000000FF00A4 +:106EF000000000000000FF00000000000000FF0094 +:106F0000000000000000FF00000000000000FF0083 +:106F1000000000000000FF00000000000000FF0073 +:106F2000000000000000FF00000000000000FF0063 +:106F3000000000000000FF00000000000000FF0053 +:106F4000000000000000FF00000000000000FF0043 +:106F5000000000000000FF00000000000000FF0033 +:106F6000000000000000FF00000000000000FF0023 +:106F7000000000000000FF00000000000000FF0013 +:106F8000000000000000FF00000000000000FF0003 +:106F9000000000000000FF00000000000000FF00F3 +:106FA000000000000000FF00000000000000FF00E3 +:106FB000000000000000FF00000000000000FF00D3 +:106FC000000000000000FF00000000000000FF00C3 +:106FD000000000000000FF00000000000000FF00B3 +:106FE000000000000000FF00000000000000FF00A3 +:106FF000000000000000FF0000000000FFFFFFFF96 +:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:10707000FFFFFFFFFFFFFFFFFFFFFFFF000000001C +:10708000000028AD000029180000291900000005A3 +:10709000000000070000FF000FFFFFFF0000FF00DF +:1070A0000FFFFFFF000000FF0000FF000000FF00D7 +:1070B0000FFFFFFF0000FF000FFFFFFF000000FFBA +:1070C0000000FF000000FF000FFFFFFF0000FF00B7 +:1070D0000FFFFFFF000000FF0000FF000000FF00A7 +:1070E0000FFFFFFF0000FF000FFFFFFF000000FF8A +:1070F0000000FF000000FF000FFFFFFF0000FF0087 +:107100000FFFFFFF000000FF0000FF000000FF0076 +:107110000FFFFFFF0000FF000FFFFFFF000000FF59 +:107120000000FF000000FF000FFFFFFF0000FF0056 +:107130000FFFFFFF000000FF0000FF000000FF0046 +:107140000FFFFFFF0000FF000FFFFFFF000000FF29 +:107150000000FF000000FF000FFFFFFF0000FF0026 +:107160000FFFFFFF000000FF0000FF000000FF0016 +:107170000FFFFFFF0000FF000FFFFFFF000000FFF9 +:107180000000FF000000FF000FFFFFFF0000FF00F6 +:107190000FFFFFFF000000FF0000FF000000FF00E6 +:1071A0000FFFFFFF0000FF000FFFFFFF000000FFC9 +:1071B0000000FF000000FF000FFFFFFF0000FF00C6 +:1071C0000FFFFFFF000000FF0000FF000000FF00B6 +:1071D0000FFFFFFF0000FF000FFFFFFF000000FF99 +:1071E0000000FF000000FF000FFFFFFF0000FF0096 +:1071F0000FFFFFFF000000FF0000FF000000FF0086 +:107200000FFFFFFF0000FF000FFFFFFF000000FF68 +:107210000000FF000000FF000FFFFFFF0000FF0065 +:107220000FFFFFFF000000FF0000FF000000FF0055 +:107230000FFFFFFF0000FF000FFFFFFF000000FF38 +:107240000000FF000000FF000FFFFFFF0000FF0035 +:107250000FFFFFFF000000FF0000FF000000FF0025 +:107260000FFFFFFF0000FF000FFFFFFF000000FF08 +:107270000000FF000000FF000FFFFFFF0000FF0005 +:107280000FFFFFFF000000FF0000FF000000FF00F5 +:107290000FFFFFFF0000FF000FFFFFFF000000FFD8 +:1072A0000000FF000000FF000FFFFFFF0000FF00D5 +:1072B0000FFFFFFF000000FF0000FF000000FF00C5 +:1072C0000FFFFFFF0000FF000FFFFFFF000000FFA8 +:1072D0000000FF000000FF000FFFFFFF0000FF00A5 +:1072E0000FFFFFFF000000FF0000FF000000FF0095 +:1072F0000FFFFFFF0000FF000FFFFFFF000000FF78 +:107300000000FF000000FF000FFFFFFF0000FF0074 +:107310000FFFFFFF000000FF0000FF000000FF0064 +:107320000FFFFFFF0000FF000FFFFFFF000000FF47 +:107330000000FF000000FF000FFFFFFF0000FF0044 +:107340000FFFFFFF000000FF0000FF000000FF0034 +:107350000FFFFFFF0000FF000FFFFFFF000000FF17 +:107360000000FF000000FF000FFFFFFF0000FF0014 +:107370000FFFFFFF000000FF0000FF000000FF0004 +:107380000FFFFFFF0000FF000FFFFFFF000000FFE7 +:107390000000FF000000FF000FFFFFFF0000FF00E4 +:1073A0000FFFFFFF000000FF0000FF000000FF00D4 +:1073B0000FFFFFFF0000FF000FFFFFFF000000FFB7 +:1073C0000000FF000000FF000FFFFFFF0000FF00B4 +:1073D0000FFFFFFF000000FF0000FF000000FF00A4 +:1073E0000FFFFFFF0000FF000FFFFFFF000000FF87 +:1073F0000000FF000000FF000FFFFFFF0000FF0084 +:107400000FFFFFFF000000FF0000FF000000FF0073 +:107410000FFFFFFF0000FF000FFFFFFF000000FF56 +:107420000000FF000000FF000FFFFFFF0000FF0053 +:107430000FFFFFFF000000FF0000FF000000FF0043 +:107440000FFFFFFF0000FF000FFFFFFF000000FF26 +:107450000000FF000000FF000FFFFFFF0000FF0023 +:107460000FFFFFFF000000FF0000FF000000FF0013 +:107470000FFFFFFF0000FF000FFFFFFF000000FFF6 +:107480000000FF000000FF000FFFFFFF0000FF00F3 +:107490000FFFFFFF000000FF0000FF000000FF00E3 +:1074A0000FFFFFFF0000FF000FFFFFFF000000FFC6 +:1074B0000000FF000000FF000FFFFFFF0000FF00C3 +:1074C0000FFFFFFF000000FF0000FF000000FF00B3 +:1074D0000FFFFFFF0000FF000FFFFFFF000000FF96 +:1074E0000000FF000000FF000FFFFFFF0000FF0093 +:1074F0000FFFFFFF000000FF0000FF000000FF0083 +:107500000FFFFFFF0000FF000FFFFFFF000000FF65 +:107510000000FF000000FF000FFFFFFF0000FF0062 +:107520000FFFFFFF000000FF0000FF000000FF0052 +:107530000FFFFFFF0000FF000FFFFFFF000000FF35 +:107540000000FF000000FF000FFFFFFF0000FF0032 +:107550000FFFFFFF000000FF0000FF000000FF0022 +:107560000FFFFFFF0000FF000FFFFFFF000000FF05 +:107570000000FF000000FF000FFFFFFF0000FF0002 +:107580000FFFFFFF000000FF0000FF000000FF00F2 +:107590000FFFFFFF0000FF000FFFFFFF000000FFD5 +:1075A0000000FF000000FF000FFFFFFF0000FF00D2 +:1075B0000FFFFFFF000000FF0000FF000000FF00C2 +:1075C0000FFFFFFF0000FF000FFFFFFF000000FFA5 +:1075D0000000FF000000FF000FFFFFFF0000FF00A2 +:1075E0000FFFFFFF000000FF0000FF000000FF0092 +:1075F0000FFFFFFF0000FF000FFFFFFF000000FF75 +:107600000000FF000000FF000FFFFFFF0000FF0071 +:107610000FFFFFFF000000FF0000FF000000FF0061 +:107620000FFFFFFF0000FF000FFFFFFF000000FF44 +:107630000000FF000000FF000FFFFFFF0000FF0041 +:107640000FFFFFFF000000FF0000FF000000FF0031 +:107650000FFFFFFF0000FF000FFFFFFF000000FF14 +:107660000000FF000000FF000FFFFFFF0000FF0011 +:107670000FFFFFFF000000FF0000FF000000FF0001 +:107680000FFFFFFF0000FF000FFFFFFF000000FFE4 +:107690000000FF000000FF000FFFFFFF0000FF00E1 +:1076A0000FFFFFFF000000FF0000FF000000FF00D1 +:1076B0000FFFFFFF0000FF000FFFFFFF000000FFB4 +:1076C0000000FF000000FF000FFFFFFF0000FF00B1 +:1076D0000FFFFFFF000000FF0000FF000000FF00A1 +:1076E0000FFFFFFF0000FF000FFFFFFF000000FF84 +:1076F0000000FF000000FF000FFFFFFF0000FF0081 +:107700000FFFFFFF000000FF0000FF000000FF0070 +:107710000FFFFFFF0000FF000FFFFFFF000000FF53 +:107720000000FF000000FF000FFFFFFF0000FF0050 +:107730000FFFFFFF000000FF0000FF000000FF0040 +:107740000FFFFFFF0000FF000FFFFFFF000000FF23 +:107750000000FF000000FF000FFFFFFF0000FF0020 +:107760000FFFFFFF000000FF0000FF000000FF0010 +:107770000FFFFFFF0000FF000FFFFFFF000000FFF3 +:107780000000FF000000FF000FFFFFFF0000FF00F0 +:107790000FFFFFFF000000FF0000FF000000FF00E0 +:1077A0000FFFFFFF0000FF000FFFFFFF000000FFC3 +:1077B0000000FF000000FF000FFFFFFF0000FF00C0 +:1077C0000FFFFFFF000000FF0000FF000000FF00B0 +:1077D0000FFFFFFF0000FF000FFFFFFF000000FF93 +:1077E0000000FF000000FF000FFFFFFF0000FF0090 +:1077F0000FFFFFFF000000FF0000FF000000FF0080 +:107800000FFFFFFF0000FF000FFFFFFF000000FF62 +:107810000000FF000000FF000FFFFFFF0000FF005F +:107820000FFFFFFF000000FF0000FF000000FF004F +:107830000FFFFFFF0000FF000FFFFFFF000000FF32 +:107840000000FF000000FF000FFFFFFF0000FF002F +:107850000FFFFFFF000000FF0000FF000000FF001F +:107860000FFFFFFF0000FF000FFFFFFF000000FF02 +:107870000000FF000000FF000FFFFFFF0000FF00FF +:107880000FFFFFFF000000FF0000FF000000FF00EF +:107890000FFFFFFF0000FF000FFFFFFF000000FFD2 +:1078A0000000FF000000FF000FFFFFFF0000FF00CF +:1078B0000FFFFFFF000000FF0000FF000000FF00BF +:1078C0000FFFFFFF0000FF000FFFFFFF000000FFA2 +:1078D0000000FF000000FF000FFFFFFF0000FF009F +:1078E0000FFFFFFF000000FF0000FF000000FF008F +:1078F0000FFFFFFF0000FF000FFFFFFF000000FF72 +:107900000000FF000000FF000FFFFFFF0000FF006E +:107910000FFFFFFF000000FF0000FF000000FF005E +:107920000FFFFFFF0000FF000FFFFFFF000000FF41 +:107930000000FF000000FF000FFFFFFF0000FF003E +:107940000FFFFFFF000000FF0000FF000000FF002E +:107950000FFFFFFF0000FF000FFFFFFF000000FF11 +:107960000000FF000000FF000FFFFFFF0000FF000E +:107970000FFFFFFF000000FF0000FF000000FF00FE +:107980000FFFFFFF0000FF000FFFFFFF000000FFE1 +:107990000000FF000000FF000FFFFFFF0000FF00DE +:1079A0000FFFFFFF000000FF0000FF000000FF00CE +:1079B0000FFFFFFF0000FF000FFFFFFF000000FFB1 +:1079C0000000FF000000FF000FFFFFFF0000FF00AE +:1079D0000FFFFFFF000000FF0000FF000000FF009E +:1079E0000FFFFFFF0000FF000FFFFFFF000000FF81 +:1079F0000000FF000000FF000FFFFFFF0000FF007E +:107A00000FFFFFFF000000FF0000FF000000FF006D +:107A10000FFFFFFF0000FF000FFFFFFF000000FF50 +:107A20000000FF000000FF000FFFFFFF0000FF004D +:107A30000FFFFFFF000000FF0000FF000000FF003D +:107A40000FFFFFFF0000FF000FFFFFFF000000FF20 +:107A50000000FF000000FF000FFFFFFF0000FF001D +:107A60000FFFFFFF000000FF0000FF000000FF000D +:107A70000FFFFFFF0000FF000FFFFFFF000000FFF0 +:107A80000000FF000000FF000FFFFFFF0000FF00ED +:107A90000FFFFFFF000000FF0000FF000000FF00DD +:107AA0000FFFFFFF0000FF000FFFFFFF000000FFC0 +:107AB0000000FF000000FF000FFFFFFF0000FF00BD +:107AC0000FFFFFFF000000FF0000FF000000FF00AD +:107AD0000FFFFFFF0000FF000FFFFFFF000000FF90 +:107AE0000000FF000000FF000FFFFFFF0000FF008D +:107AF0000FFFFFFF000000FF0000FF000000FF007D +:107B00000FFFFFFF0000FF000FFFFFFF000000FF5F +:107B10000000FF000000FF000FFFFFFF0000FF005C +:107B20000FFFFFFF000000FF0000FF000000FF004C +:107B30000FFFFFFF0000FF000FFFFFFF000000FF2F +:107B40000000FF000000FF000FFFFFFF0000FF002C +:107B50000FFFFFFF000000FF0000FF000000FF001C +:107B60000FFFFFFF0000FF000FFFFFFF000000FFFF +:107B70000000FF000000FF000FFFFFFF0000FF00FC +:107B80000FFFFFFF000000FF0000FF000000FF00EC +:107B90000FFFFFFF0000FF000FFFFFFF000000FFCF +:107BA0000000FF000000FF000FFFFFFF0000FF00CC +:107BB0000FFFFFFF000000FF0000FF000000FF00BC +:107BC0000FFFFFFF0000FF000FFFFFFF000000FF9F +:107BD0000000FF000000FF000FFFFFFF0000FF009C +:107BE0000FFFFFFF000000FF0000FF000000FF008C +:107BF0000FFFFFFF0000FF000FFFFFFF000000FF6F +:107C00000000FF000000FF000FFFFFFF0000FF006B +:107C10000FFFFFFF000000FF0000FF000000FF005B +:107C20000FFFFFFF0000FF000FFFFFFF000000FF3E +:107C30000000FF000000FF000FFFFFFF0000FF003B +:107C40000FFFFFFF000000FF0000FF000000FF002B +:107C50000FFFFFFF0000FF000FFFFFFF000000FF0E +:107C60000000FF000000FF000FFFFFFF0000FF000B +:107C70000FFFFFFF000000FF0000FF000000FF00FB +:107C80000FFFFFFF0000FF000FFFFFFF000000FFDE +:107C90000000FF000000FF000FFFFFFF0000FF00DB +:107CA0000FFFFFFF000000FF0000FF000000FF00CB +:107CB0000FFFFFFF0000FF000FFFFFFF000000FFAE +:107CC0000000FF000000FF000FFFFFFF0000FF00AB +:107CD0000FFFFFFF000000FF0000FF000000FF009B +:107CE0000FFFFFFF0000FF000FFFFFFF000000FF7E +:107CF0000000FF000000FF000FFFFFFF0000FF007B +:107D00000FFFFFFF000000FF0000FF000000FF006A +:107D10000FFFFFFF0000FF000FFFFFFF000000FF4D +:107D20000000FF000000FF000FFFFFFF0000FF004A +:107D30000FFFFFFF000000FF0000FF000000FF003A +:107D40000FFFFFFF0000FF000FFFFFFF000000FF1D +:107D50000000FF0000001000000020800000310043 +:107D600000004180000052000000628000007300AB +:107D700000008380000094000000A4800000B50093 +:107D80000000C5800000D6000000E6800000F7007B +:107D9000000107800001180000012880000139005F +:107DA0000001498000015A0000016A8000017B0047 +:107DB00000018B8000019C000001AC800001BD002F +:107DC0000001CD800001DE000001EE800001FF0017 +:107DD00000000F8000007FF800007FF8000005F928 +:107DE0000000350010000000000028AD0000291838 +:107DF0000000291900000005000000060001000134 +:107E000000220006CCCCCCC97058103C0000FF000A +:107E1000000000000000FF00000000000000FF0064 +:107E2000000000000000FF00000000000000FF0054 +:107E3000000000000000FF00000000000000FF0044 +:107E4000000000000000FF00000000000000FF0034 +:107E5000000000000000FF00000000000000FF0024 +:107E6000000000000000FF00000000000000FF0014 +:107E7000000000000000FF00000000000000FF0004 +:107E8000000000000000FF00000000000000FF00F4 +:107E9000000000000000FF00000000000000FF00E4 +:107EA000000000000000FF00000000000000FF00D4 +:107EB000000000000000FF00000000000000FF00C4 +:107EC000000000000000FF00000000000000FF00B4 +:107ED000000000000000FF00000000000000FF00A4 +:107EE000000000000000FF00000000000000FF0094 +:107EF000000000000000FF00000000000000FF0084 +:107F0000000000000000FF00000000000000FF0073 +:107F1000000000000000FF00000000000000FF0063 +:107F2000000000000000FF00000000000000FF0053 +:107F3000000000000000FF00000000000000FF0043 +:107F4000000000000000FF00000000000000FF0033 +:107F5000000000000000FF00000000000000FF0023 +:107F6000000000000000FF00000000000000FF0013 +:107F7000000000000000FF00000000000000FF0003 +:107F8000000000000000FF00000000000000FF00F3 +:107F9000000000000000FF00000000000000FF00E3 +:107FA000000000000000FF00000000000000FF00D3 +:107FB000000000000000FF00000000000000FF00C3 +:107FC000000000000000FF00000000000000FF00B3 +:107FD000000000000000FF00000000000000FF00A3 +:107FE000000000000000FF00000000000000FF0093 +:107FF000000000000000FF00000000000000FF0083 +:10800000000000000000FF00000000000000FF0072 +:10801000000000000000FF00000000000000FF0062 +:10802000000000000000FF00000000000000FF0052 +:10803000000000000000FF00000000000000FF0042 +:10804000000000000000FF00000000000000000130 +:10805000CCCC0201CCCCCCCCCCCC0201CCCCCCCC8A +:10806000CCCC0201CCCCCCCCCCCC0201CCCCCCCC7A +:10807000CCCC0201CCCCCCCCCCCC0201CCCCCCCC6A +:10808000CCCC0201CCCCCCCCCCCC0201CCCCCCCC5A +:1080900000000000FFFFFFFF03030303134202027F +:1080A0005050502070608050020002000604060408 +:1080B000000E0000011600D6002625A0002625A0EF +:1080C000002625A0002625A000720000012300F351 +:1080D000002625A0002625A0002625A0002625A0F4 +:1080E0000000FFFF000000000000FFFF0000000094 +:1080F0000000FFFF000000000000FFFF0000000084 +:108100000000FFFF000000000000FFFF0000000073 +:108110000000FFFF000000000000FFFF0000000063 +:108120000000FFFF000000000000FFFF0000000053 +:108130000000FFFF000000000000FFFF0000000043 +:108140000000FFFF000000000000FFFF0000000033 +:108150000000FFFF000000000000FFFF0000000023 +:108160000000FFFF000000000000FFFF0000000013 +:108170000000FFFF000000000000FFFF0000000003 +:108180000000FFFF000000000000FFFF00000000F3 +:108190000000FFFF000000000000FFFF00000000E3 +:1081A0000000FFFF000000000000FFFF00000000D3 +:1081B0000000FFFF000000000000FFFF00000000C3 +:1081C0000000FFFF000000000000FFFF00000000B3 +:1081D0000000FFFF000000000000FFFF00000000A3 +:1081E0000000FFFF000000000000FFFF0000000093 +:1081F0000000FFFF000000000000FFFF0000000083 +:108200000000FFFF000000000000FFFF0000000072 +:108210000000FFFF000000000000FFFF0000000062 +:108220000000FFFF000000000000FFFF0000000052 +:108230000000FFFF000000000000FFFF0000000042 +:108240000000FFFF000000000000FFFF0000000032 +:108250000000FFFF000000000000FFFF0000000022 +:108260000000FFFF000000000000FFFF0000000012 +:108270000000FFFF000000000000FFFF0000000002 +:108280000000FFFF000000000000FFFF00000000F2 +:108290000000FFFF000000000000FFFF00000000E2 +:1082A0000000FFFF000000000000FFFF00000000D2 +:1082B0000000FFFF000000000000FFFF00000000C2 +:1082C0000000FFFF000000000000FFFF00000000B2 +:1082D0000000FFFF000000000000FFFF00000000A2 +:1082E000FFFFFFF3318FFFFF0C30C30CC30C30C313 +:1082F000CF3CF300F3CF3CF30000CF3CCDCDCDCD50 +:10830000FFFFFFF130EFFFFF0C30C30CC30C30C395 +:10831000CF3CF300F3CF3CF30001CF3CCDCDCDCD2E +:10832000FFFFFFF6305FFFFF0C30C30CC30C30C300 +:10833000CF3CF300F3CF3CF30002CF3CCDCDCDCD0D +:10834000FFFFF4061CBFFFFF0C30C305C30C30C396 +:10835000CF300014F3CF3CF30004CF3CCDCDCDCDD6 +:10836000FFFFFFF2304FFFFF0C30C30CC30C30C3D4 +:10837000CF3CF300F3CF3CF30008CF3CCDCDCDCDC7 +:10838000FFFFFFFA302FFFFF0C30C30CC30C30C3CC +:10839000CF3CF300F3CF3CF30010CF3CCDCDCDCD9F +:1083A000FFFFFFF731EFFFFF0C30C30CC30C30C3EE +:1083B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6F +:1083C000FFFFFFF5302FFFFF0C30C30CC30C30C391 +:1083D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2F +:1083E000FFFFFFF3318FFFFF0C30C30CC30C30C312 +:1083F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4F +:10840000FFFFFFF1310FFFFF0C30C30CC30C30C373 +:10841000CF3CF300F3CF3CF30001CF3CCDCDCDCD2D +:10842000FFFFFFF6305FFFFF0C30C30CC30C30C3FF +:10843000CF3CF300F3CF3CF30002CF3CCDCDCDCD0C +:10844000FFFFF4061CBFFFFF0C30C305C30C30C395 +:10845000CF300014F3CF3CF30004CF3CCDCDCDCDD5 +:10846000FFFFFFF2304FFFFF0C30C30CC30C30C3D3 +:10847000CF3CF300F3CF3CF30008CF3CCDCDCDCDC6 +:10848000FFFFFFFA302FFFFF0C30C30CC30C30C3CB +:10849000CF3CF300F3CF3CF30010CF3CCDCDCDCD9E +:1084A000FFFFFFF730EFFFFF0C30C30CC30C30C3EE +:1084B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6E +:1084C000FFFFFFF5304FFFFF0C30C30CC30C30C370 +:1084D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2E +:1084E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C6 +:1084F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD82 +:10850000FFFFFFFF30CFFFFF0C30C30CC30C30C3A5 +:10851000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD60 +:10852000FFFFFFFF30CFFFFF0C30C30CC30C30C385 +:10853000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3F +:10854000FFFFFFFF30CFFFFF0C30C30CC30C30C365 +:10855000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1D +:10856000FFFFFFFF30CFFFFF0C30C30CC30C30C345 +:10857000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF9 +:10858000FFFFFFFF30CFFFFF0C30C30CC30C30C325 +:10859000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDD1 +:1085A000FFFFFFFF30CFFFFF0C30C30CC30C30C305 +:1085B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDA1 +:1085C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E5 +:1085D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD61 +:1085E000FFFFFFF3320FFFFF0C30C30CC30C30C38F +:1085F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4D +:10860000FFFFFFF1310FFFFF0C30C30CC30C30C371 +:10861000CF3CF300F3CF3CF30001CF3CCDCDCDCD2B +:10862000FFFFFFF6305FFFFF0C30C30CC30C30C3FD +:10863000CF3CF300F3CF3CF30002CF3CCDCDCDCD0A +:10864000FFFFF4061CBFFFFF0C30C305C30C30C393 +:10865000CF300014F3CF3CF30004CF3CCDCDCDCDD3 +:10866000FFFFFFF2304FFFFF0C30C30CC30C30C3D1 +:10867000CF3CF300F3CF3CF30008CF3CCDCDCDCDC4 +:10868000FFFFFF8A042FFFFF0C30C30CC30C30C365 +:10869000CF3CC000F3CF3CF30010CF3CCDCDCDCDCF +:1086A000FFFFFF9705CFFFFF0C30C30CC30C30C397 +:1086B000CF3CC000F3CF3CF30020CF3CCDCDCDCD9F +:1086C000FFFFFFF5310FFFFF0C30C30CC30C30C3AD +:1086D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2C +:1086E000FFFFFFF3320FFFFF0C30C30CC30C30C38E +:1086F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4C +:10870000FFFFFFF1302FFFFF0C30C30CC30C30C351 +:10871000CF3CF300F3CF3CF30001CF3CCDCDCDCD2A +:10872000FFFFFFF6305FFFFF0C30C30CC30C30C3FC +:10873000CF3CF300F3CF3CF30002CF3CCDCDCDCD09 +:10874000FFFFFF061CBFFFFF0C30C30CC30C30C380 +:10875000CF3CC014F3CF3CF30004CF3CCDCDCDCD06 +:10876000FFFFFFF2304FFFFF0C30C30CC30C30C3D0 +:10877000CF3CF300F3CF3CF30008CF3CCDCDCDCDC3 +:10878000FFFFFFFA302FFFFF0C30C30CC30C30C3C8 +:10879000CF3CF300F3CF3CF30010CF3CCDCDCDCD9B +:1087A000FFFFFFF731CFFFFF0C30C30CC30C30C30A +:1087B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6B +:1087C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E3 +:1087D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5F +:1087E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C3 +:1087F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7F +:10880000FFFFFFFF30CFFFFF0C30C30CC30C30C3A2 +:10881000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5D +:10882000FFFFFFFF30CFFFFF0C30C30CC30C30C382 +:10883000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3C +:10884000FFFFFFFF30CFFFFF0C30C30CC30C30C362 +:10885000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1A +:10886000FFFFFFFF30CFFFFF0C30C30CC30C30C342 +:10887000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF6 +:10888000FFFFFFFF30CFFFFF0C30C30CC30C30C322 +:10889000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCE +:1088A000FFFFFFFF30CFFFFF0C30C30CC30C30C302 +:1088B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9E +:1088C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E2 +:1088D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5E +:1088E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C2 +:1088F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7E +:10890000FFFFFFFF30CFFFFF0C30C30CC30C30C3A1 +:10891000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5C +:10892000FFFFFFFF30CFFFFF0C30C30CC30C30C381 +:10893000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3B +:10894000FFFFFFFF30CFFFFF0C30C30CC30C30C361 +:10895000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD19 +:10896000FFFFFFFF30CFFFFF0C30C30CC30C30C341 +:10897000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF5 +:10898000FFFFFFFF30CFFFFF0C30C30CC30C30C321 +:10899000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCD +:1089A000FFFFFFFF30CFFFFF0C30C30CC30C30C301 +:1089B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9D +:1089C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E1 +:1089D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5D +:1089E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C1 +:1089F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7D +:108A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3A0 +:108A1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5B +:108A2000FFFFFFFF30CFFFFF0C30C30CC30C30C380 +:108A3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3A +:108A4000FFFFFFFF30CFFFFF0C30C30CC30C30C360 +:108A5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD18 +:108A6000FFFFFFFF30CFFFFF0C30C30CC30C30C340 +:108A7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF4 +:108A8000FFFFFFFF30CFFFFF0C30C30CC30C30C320 +:108A9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCC +:108AA000FFFFFFFF30CFFFFF0C30C30CC30C30C300 +:108AB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9C +:108AC000FFFFFFFF30CFFFFF0C30C30CC30C30C3E0 +:108AD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5C +:108AE000000C0000000700C000028130000B81581C +:108AF0000002021000010230000F024000010330AA +:108B0000000C0000000800C000028140000B8168DA +:108B1000000202200001024000070250000202C0D1 +:108B2000001000000008010000028180000B81A8F5 +:108B30000002026000018280000E8298000803801B +:108B4000001000000001010000028110000901383E +:108B5000000201C8000101E8000E01F8000002D87F +:108B6000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45 +:108B700000002000CCCCCCCCCCCCCCCCCCCCCCCC45 +:108B8000CCCCCCCC00002000CCCCCCCCCCCCCCCC35 +:108B9000CCCCCCCCCCCCCCCC04002000CCCCCCCC21 +:108BA000CCCCCCCCCCCCCCCCCCCCCCCC41002000D4 +:108BB00003030303034202025050502070608050B0 +:108BC0001313131313421212505050207060805030 +:108BD000030102000000000000000000000000008F +:108BE0001F8B080000000000000BFB51CFC0F003FA +:108BF0008AF7093230288920F8C4E0427606864D8B +:108C00001C0C0C5BB849D307C32C0C0C0CDA4CE4DD +:108C1000E905E1DBBC0C0CCF8098810F555C80131B +:108C200042FF075A20C80AB4830DBBFEE56A08B6A6 +:108C3000A70A0343011033283130E8AB22C445D4DE +:108C400019182602F99150B1AB403A4C8D7C378F00 +:108C5000E2C1834F1AA3F2971A426807A8F8293491 +:108C6000F96550F9621D087DDA18BBB9253AC4D9F7 +:108C7000BFCB1A953FCD1ABFFA93F6A8FC7568EAE8 +:108C80001741F900B9FAD21DD80300000000000016 +:108C900000000000000000001F8B08000000000022 +:108CA000000BED7D7F7C14D5B5F8999DD9D9D9CD30 +:108CB000EE6608096C20E024861AFAA25D20609016 +:108CC000A843401ABF8FDA15A9A62DED77B5D4E2D7 +:108CD0000F60EBF3097DCF36931092101017B1D5CA +:108CE00056AB2B0F2DF56B25B5D4D2FAA38B581E9E +:108CF000B6EFF3BE4869EBD7621B7FE18F228D5A36 +:108D000084B658BFF79C7B273B33D94D36407FFC58 +:108D1000F1C207863B73EEBDE79E73EEB9E79C7B1D +:108D2000EE8D0A35F0A133003EC09F0B016E0F019E +:108D30004045EE695C7F7E4F7F03C05188A47BCBAA +:108D400001D62860022B5B072399FB25C09F3A853B +:108D50009557C91F8EF75603DC51F2957B117EB5EE +:108D6000A540803D7BDB00B267B1EFA1E816280586 +:108D70002881D476FCCE7E12F7B3F68E05276720C5 +:108D80009AEBBF027C0033F173957EA884E0E00388 +:108D900099FD73303917C601C860FFAC863ED68E88 +:108DA0007240CE60BFB2BC50FF554DAE1DEF53D6E2 +:108DB00055C86AA23DFC475E529A0C17865F7DB08B +:108DC0007AFBD37539F8B320527EE89FD87F1450D0 +:108DD000081F7903201D8E86212357176EE7589BA5 +:108DE000B1FD693FD2F133A589B30BC3D974EA69E8 +:108DF000D3E8D9D5A6433600C05036FBEAD9330CA8 +:108E0000E696FAA1F5E68144F4D20C8BF0E90CFB6E +:108E10003225D588751280D1D78FF491F0FD22CDFF +:108E2000CC53DF7E4239A38F3D5E46C720F0F680EB +:108E30008DEF7ED65E10FBCF43AFCBB07F2627C130 +:108E4000DAA1FD5B0D27DF7F682AC0BE30D2DB448C +:108E50001CC0A7A7202EF8FD51699876049F1583A2 +:108E6000B73312DD4BEA7CB97ED9DFA01172C94954 +:108E70002056E6961BAF5C229D2A905F86F4F29402 +:108E80005CBB2AF22D0FBDAE11F41A989B684D30D1 +:108E90007AAC6D03EB25473D390666260F9D568952 +:108EA0007A767F4A3983CBD33E40BB983F960BBE40 +:108EB00058FCBE7C92F8ADFF1BE1B749C83B409A15 +:108EC0009E03739384A7B7BD7CF38B4DE2C17248B8 +:108ED000C9583E94EF7288DFCF1E7E8DCF33FBFBE7 +:108EE000C3E0A77676A2C661FDAC11F80DCCE5FA19 +:108EF0006FED3435B345227DE4C2F321D45FAC9EDF +:108F000024097A687D80F257725C01188BF8999079 +:108F10008800ACAB6DD686D33FA02B7FEAB7E5AE19 +:108F200066A8DC7D9875837885C2F9E9F4F0A01E07 +:108F30005D62BDC4DAD182ECFD99D86E79AC6A1657 +:108F4000E0E8E8C72FBE83E4933FC0797B82C1CDC0 +:108F5000127A56A6F6498F401590BE97053CF5C388 +:108F6000E0036C58E674F6C4F775A21F6968BBDEAF +:108F70007AC7A08CD347E063EB75191EA77606F17C +:108F80005112442FEF7B3F7BAF874FFDFDA996FD2C +:108F90004681FED212C9D348F57F23E465887C164A +:108FA000E0EB7E31CF14E833E1CC9C1CD9F275B2F2 +:108FB0007274CA72C2BAA7F5A2809C5890A279C3F3 +:108FC000C0ACDE69A397973C729275C22F94C6F02D +:108FD0007128719217868F4272AB737C2AA69753C1 +:108FE0007B12CEF1B3B00551463AB0F15E65D7873A +:108FF00038CDD710DA398EFA6C7084AF244B42EF3B +:1090000073B89BC43C3FBFB98AE30FA27D0FBEACCF +:109010003DCDD99E0C551E39E7786F94B87E63F02C +:1090200059A2A7B77F45227C6548583E566F8BE80A +:10903000DFABBFECE70ED1DE06095AFBC27C3E2D4A +:1090400072AC87CD92D0131A9F675EFDE447B99A40 +:1090500071F27255AC5E5F28E55F77985514BB34AA +:109060005278DD29F5D9EB413626F8362ABE9F29FC +:1090700095B9F85E2CBE579D24BE1387E25B949C85 +:109080004D957CA35A276F3A49FC821EFC4E975C93 +:10909000CF1072562CFEF63C182DFEF250FA163503 +:1090A0008F668F12BF2D2749DF0A9F6D2709FC0AA3 +:1090B000CCDBF305BF2DE0F2A1303B1CFD9C62F13F +:1090C0007B7464FC00CE637FAD172D53217B0D6054 +:1090D00002C0D3ED2F5A9692C3CF04AED747DBFF21 +:1090E0009E91F927FA7FC3326B73FD1F687FC3D54A +:1090F000BFC2E40785ADD87E7F51ECB8E16DD7B82B +:109100005F96DE76F57BB2747FB5E8FEFFE81AF76E +:10911000BBD21FDDE30EB3719F597CBF7F38497905 +:10912000AC16F3A559D25DEB4021FB7D86E0EBDD6B +:1091300036BC8D6F01F8A902AFCE22E1278AF63F37 +:1091400055247C9F68BF0FE12B46863F53C0A78AFA +:1091500084977C7C1E165A3FE74A36FDC0E57FACFB +:10916000D1781CC45CA340F082A17113AB39F5AD7A +:109170007EC67BAB23A0AF29A7B809C545560324FB +:10918000306E7217241B7D187FD9F9E57B11EE1D17 +:1091900045D37B75E013927D0F1E8C6CE9ADCEF547 +:1091A000B74A4EB64A284B6BA2FAFD145F49B54A3E +:1091B000EC596185758CDB1CAB49B45F598EE3308B +:1091C000748BB5F3FCB2CB7661F9364DD265266A65 +:1091D0005FBD60EAA6CB0D06F7FEAEE7CE40B869EC +:1091E000E36A3A485FC6259487B171D594CF61CFC1 +:1091F000C58BB97E07E10FB738CACC0EF864EB27F0 +:109200005CDF3F9D74973FD1F289DC7AC2FE5E91AC +:10921000707FCF8D07B8DF3187EBED6335A9DF7243 +:10922000BC3E546DF1F8028DB7D48AD2F836BCFF3B +:10923000452A6F68AFD73BD8B83F75CD510BC717DC +:109240009680C6178DBF97C532B0F1AA8D00B75E64 +:10925000F04CCF2C28EC7F459B16BBF084B87B9C50 +:10926000ADD7E7C75BD5DF9DF00AB3978EED0A9ABD +:10927000884F74AF9C0956235F07B293B07FAB341D +:10928000C9F93300B5C8575307E463B399CCC8ECA8 +:109290007D3AA6C5032866D0AF21DD372168257B3E +:1092A000DFF88E96ACC7F6DFA3F675F1FDD6C69A49 +:1092B000F1181F79BC6DF54485CDF71FB55913150D +:1092C00066B4EF6CEBA1E7A36D697ABFA3ED4E7AAC +:1092D000DAE3434D62D8E393B11FB303E5ED989F02 +:1092E00099460CAF8DE7FBC8BFDD20F44897782A7C +:1092F0004A562EC5EF7198D60B88D7FE79584E374F +:10930000C0346459BAE929B9948DE3864A988E6DC0 +:10931000EF7AE157FC7B154C0F30F97ACA6CA679CD +:10932000706BA32F13A8A6E7C5D8DFADA60F98C909 +:10933000039138C3CB41D740CC5DD621B926D2406A +:10934000FDC77B0DAC7FC36E2CDF3093194A40ED17 +:10935000CB11A223C4B1BF99074CD2E381261FC50C +:10936000E9D24DBE20D271A47ED248D761E25573B6 +:109370005E77C3CFEE779799C6FBCDA07C70FA3E9F +:10938000EC637A62F70BE37D5639E141E3674F1EE8 +:10939000478CF9326894DE26E86CD3FD5884EB9D47 +:1093A0008DCC3FC47860217C369E776D6CB8788216 +:1093B000DAD8958073F0994E60BC556DCC88671FE4 +:1093C000BDF7C23F8F46D1CC5CB92B367DCC95F52D +:1093D000397CBCF0136495E4FF5805FFDE157B4A29 +:1093E000BF32EC6C4FF27ED73E5FEFFCEEA7FE8EF5 +:1093F00055DADFF76B57D6E7A93F897DCFC397A52D +:1094000032D7C34FBF1068FE1ACAA7A0EFEE175E8F +:10941000DB7B26D2FB800C280FE97DCD240F287F33 +:10942000A8479E62F2D0CFDA1BDBB2E137CEF91C3F +:1094300089BBCBE946864003E71B76F55F821F3F79 +:1094400015F1DABD225EBBA72D46CFA7DB0C7A3E15 +:10945000D55647DFB36D712A3FD9D648E5C7DB4CF7 +:109460002AFFA8AD85CA3BDB12547EB4AD959E3B66 +:10947000DA92F4BCAD6D193DD34D7C9E6F684B51B3 +:10948000B9AB6D35D5B3C7FF31A6359CF2F7CF75B3 +:10949000EEF2C5C659B9F9CEFE7E34E62E5FA47F42 +:1094A000D4559EA7B9CB73E10BAEF62E3C7EB5AB7F +:1094B0007CFE40970B7ECEEBEEF2ECFE075CF0E715 +:1094C0003EE72ECFDCB7C7551EDBE22E47E2875CB6 +:1094D000ED0562EEF256543E5C7F917C74C56AC61F +:1094E000E495BFC1EFD3839F737D978B949FAB7A35 +:1094F000AA517E5A7C71CB40F9E1F294467D260D4B +:1095000095139B6F23C9978DC7DF5AAEFE479E8682 +:1095100097A7A2E5A141895B30541EBC7CF7CAC75E +:10952000103D23E4E57FE4E01F430E607E19EBA4C9 +:10953000F0BA9AC7EE23BB35B015C8EEF3A30D5DA4 +:10954000E95887276793F9F6C1AEF5CD7D4466EDFE +:1095500004CAA10BF749034A01FF56AC73018D7F82 +:109560000FD6A67D284F1130A6CBD30096FFE096EC +:109570000957B1F6F709B8AEFBC1923E02306E82D0 +:109580009A44FF2652EBF673F6CA3CEE613FB77D74 +:109590003FD29AA1987F830BEFA1E3E6FB38F2C498 +:1095A00059ADBF66F340DE326BDB5AF60CD5264D63 +:1095B000D9C0FAE544B7A52183E0CCC68CE563AFFA +:1095C0008255CC6E639FE5B0096887CDF699CFCA06 +:1095D00033C93EDA8F4FDBEED9269E8F8B7978998F +:1095E000CFFC25D287C1FD6A3838BBDF11F90549A8 +:1095F0004BE271ABF8FD0C457F79DC653FD9E35355 +:10960000948499C8C3AF23B2D8E7D1E3AD3C3EA25E +:1096100002EA8742F0AFCBEEFD31FB59CAFC0219DA +:10962000F188F17D2838719971E9D943F150954459 +:1096300012FBC17DEC2DAC9FCE31971B49473F9269 +:1096400022F08999848FAA737C54256E26F2C8D1A2 +:109650009F043E763BF67E9A141B80FE700EBFB5CB +:10966000C144EB95E8B78E51894E9D11B7FD354B3E +:10967000E17276967876FAF3DB87001DDC4F1ED711 +:10968000A861FB6B1A9B35B4AF0D886BE87F7786BA +:1096900017950E676F6F68E3FBE3BDA80F03B84F24 +:1096A000AE8B7DF2183D3BC38FB4E0BC3B5ACFE894 +:1096B000505DB89D48DCBDDF5B5217F2ECEF6608E9 +:1096C000CFA051E6D9079EE0AAE71FA7F8ECFD6EF0 +:1096D0009046C6BF4BE06FC3752B294DCF4BA78C6F +:1096E000CBEE0EC4DCF8FEF5E8C7EB97F8FBF47C94 +:1096F000789D2EBA15DA9FB59FEA583595E1719697 +:1097000098731E2C11F2A58ED55218C702ADD0F752 +:1097100010AF1F4E50DC4B0B270CA8C9EDD36A3895 +:109720001F1C74BA51D47B41B1F74B5331F4AB25B4 +:1097300023D58AF2A455B179240DAD673F3F27EABE +:1097400077BFFF2FCFD13CA9D0689E48069B4779B1 +:10975000FA511473A5827151D94C29B86FF3173996 +:10976000996FBEAC10F3595B9830B41ADADAE3792A +:10977000201E3C36287C1EBF21E0C14A513CAB581C +:10978000FCFFBD48FCED7E18FEDD02FF1E7C16C20C +:10979000BF4BE05306463BC5380DAE67012E359CE6 +:1097A000F918AF89FECB849E02F822F1CDFEFE921D +:1097B000E04BB1E3F96A91E3792DC78FFB900F6C11 +:1097C0003C5B86E34746E0F19AC2D7192D9130629F +:1097D00035B4D4E795AB1F0B7ABD6BCB95F5C5516E +:1097E000C9D5C3A2FE48E3F8718E2F3F12E3786C0F +:1097F00038BEFC50F0252DC3EC5730FE78A65877C4 +:1098000060918B2FC745BBE980CD971B5C7C3932BB +:109810004ABEEC2D723CC773E33920E4EC17C3F168 +:10982000C501FFBC18FFAFC5F829AE7EBCF39A0E88 +:109830002B4CEBF26F9599B9FE185CBF6897E06E00 +:1098400054CEEDB0EA09EE157C2FB5F07590C1BD90 +:10985000EA84034874A0FDB616F74ACF03F896725F +:1098600073B368FF77546FE160FB879DF53628F38B +:109870006C3C06F07DFBBCBFD8706F3BE18E775E21 +:109880006FC31DA5F6128378BCE71CD78F3B9710DA +:10989000DC907CA45871F6AABF3C49797D651049DB +:1098A00063DCB14B49519C193721303EB92A10A7CE +:1098B000149691E2D4158B793D5DD128CE1A80148F +:1098C000DC89F1B97285F64D3EAE24753FDA11524E +:1098D000D2A24D57D097B463FB630DCA0BB3F1D935 +:1098E00054F2D91E6A87E183EDDE5112DD8572756F +:1098F000DB24D540B9DA35E9268AA76F6AE779858E +:109900009B2E56298EB8F98508ADBF6B95F82711A7 +:10991000DE325503E3C5AB427F796E292BF7B7974B +:10992000EAD205340EC2DBF241624D83234F91E14E +:109930001D88539E1DC5E136B5F0FD1EF65389F511 +:1099400057CD3328CE68A01E63DFBB1B55B25F37EF +:1099500055D5CCC5FE36376A646F6C5E58D34E71F0 +:10996000BCC610C531CBC28684F1F7E8B92A33C032 +:1099700059B9DC68477B33322B0418772AABE2FDF8 +:1099800045CE028A43F9219DA865CF688F0AD9B1D7 +:10999000D8DEA2ECE7D09E690CE832C6FD2D737FBD +:1099A000FD384A85E33FF27F01E2E39F2803D2DDE1 +:1099B000E66F343D587FD8FCC668A648B86C717015 +:1099C000911E05B2338A804B17099729122ECBE1DD +:1099D0000270E9B0797E10E7F9851AFBC3F31B1D0D +:1099E000F986D5DC7E77DA2D7ECFF7D1E68B2EF7A0 +:1099F00047CA695E9E0BE7F27CD1E1EBDB79A223DB +:109A00008D17C097C3531E197EADB0FB0A7DF78F2B +:109A1000BB2986FAACBBE2DFC4F366FEAC14EF2BC5 +:109A200057C7CC303EC5F7CA9B5BCD3CFD7DC3CF4D +:109A3000F5701D2486E54399C0FF10C31DF37EEA2F +:109A400014061F290CAF96FB86CDBFD414AB99E644 +:109A5000ED421FCDDB002A039C37557C1EFB219570 +:109A6000A8253D63462B1DF3C7DFB487E6CF7F579C +:109A7000CA2035127FE24847AF9C78E522008E72FB +:109A8000F5A9CBC9237E91577C9AE5C4DF2317350E +:109A90007FFCE922E13245C2658B83537BA4A2F4AB +:109AA0008A9A2E122E53245C96C3AD9DADF2F5DC3E +:109AB0003AD6817900FEF3345779ED7921F7F739F9 +:109AC0006157B96BA6BBBE3ACB5DBF6B96BBBE7A86 +:109AD0002EAF1F567DF3709FBFD879F2EA49CE931F +:109AE0003A6D78F848E308F34AD38358BF4C3120E5 +:109AF0005B4EEB5546AC5B79F7C96B543EFFA7F85C +:109B0000F9BEFD26450FA21FF98F3E4E45E5F8DA56 +:109B1000E31D095F5BFFBE260B7BAB403E38C4F8FC +:109B2000B9083F84E268E718F3B5E6DF303AFA9FF8 +:109B3000E1F9F0DE765F54930DAAC32F66F619247F +:109B40001D71988B2B149E87C3F880F6900A891696 +:109B50008C3BAFA9F2913DA284475837AA1C7A2BBF +:109B60004FBE5E2E2E05269EB3A04F06C0DCD779D1 +:109B7000BFA13810DE11E82767BA1453E8CE0418E5 +:109B80000386C493C1789E0040938EFAAC3C78BAA9 +:109B9000DB5D42ED4AE626F8A06414ED2AFD944709 +:109BA00073DADB1D01DF20DC4DED322FA9FC83B120 +:109BB000B976FDB114BDC4FC59D9914787E7252872 +:109BC0000FC517CF52DEC38428F9656BCB6F70E5E4 +:109BD000897F45AD71C58754BDEB8B12EEE3565DB1 +:109BE0006FF60F23E71D4C5D517CA46AA9D95F571E +:109BF000186E307F1FF340F3CC832E359941FBDD87 +:109C00009A1CE6FEBC92A27863B75436BDB7210712 +:109C1000A754314DCBF00AC74D0BFDBDEEB1BE3898 +:109C2000DAA90A6CD8279DC3EAC90BE3CEF8A5F7D9 +:109C3000A954296F3AC77387EAB6A7D68C20EF23B9 +:109C4000DA3D6A3C992F2EFAA0CAFD637F28FFF700 +:109C50005742CDDF522B86D2ED47485FF46FC740A5 +:109C60000FC6DBED3C5AA56ACF734887B5150B626A +:109C7000C38D9739508707F9C258BC2F64EE5067DF +:109C80000E8BC74E75661EFE858B8B7F03F3D374D8 +:109C9000062A8BF339681F494CDE4383F218874E3E +:109CA000D457CCFFE8657C0BD5C7612B2BC7E66981 +:109CB0000985D94BB7346C018C5BFB99FD44FE8957 +:109CC000DCC4EDA73A6E0F99EC0F8E23DA34BC5D3D +:109CD0002D7BCA0754B73DB4A66D2738F3DFBCE728 +:109CE0002DECE7D650F3F3F9E9519C3FBC99C90B31 +:109CF00033EE60539B46CF5BDB747ADED216A3E76C +:109D0000FA3683F2F33BDBEAA8FC55AC3A1BCF45AD +:109D1000A57AAA19FD7A625B9F5BCA5E6D46DA522C +:109D20009C20330FEDE45E2C53BE1F7303B13C89BE +:109D30007F7FAF2B3D0FE30DBD411B7EED3CD35527 +:109D4000BE73CD5C8417718648F77DF3D0DFDF3CAE +:109D5000C9CE4333B54F38D6BD9A003FAF42BE2B74 +:109D6000D5EF5883FD0715BBFC3D6A3F570613F13D +:109D7000096ABCFCD1C00EC2875400EBEFE381EF4F +:109D80005379F3141EEF87C58B46A0238FEFAF5195 +:109D90000D1EEF5A5C46FB472A939B1AF66AF3188E +:109DA000817791ED8092E4EB9D38DF5778DE8CB0BF +:109DB000AE093C469E0F26C5D1ED736BCA2FF2AF9C +:109DC000D3A7BBDFCDFED1D1456B4A9AD87CB4A5D1 +:109DD0002F8BACFEB19A9C13C07DA4F9FB6859513E +:109DE00063596E3714D9FFB8809D079924BFC9A65F +:109DF000B7A273FB6385879FFE72BE6F1714E7538C +:109E00008AC5FB73AAE847B4030F4DAF1CCECE2A18 +:109E10005FE843636C506F94CD0FB9CA7A539908C9 +:109E2000DAF072B46182AB1CAEAF7195FDFA875D5A +:109E3000F54F965FADC25EB4E13FE61957B3779C2C +:109E400045B6FB6269E25F0233314E05752946D79C +:109E50003B3EF300D13F34385F17749A4D942F2E58 +:109E6000FC8A0B7959B7BF9FD76956B1B2617F9F02 +:109E7000C9BF9BF6F7E9BC6CD9DF3FC2E1D15F6691 +:109E8000E58EEEA99D167E870E8ADF42550A1639A9 +:109E9000F44B787C7317E2377E492666B1F7BDEF45 +:109EA000CB5C6E211D73C2DDA5713FE02753BE164A +:109EB000C3B8E5BAA90FC480F49E94775FF0D900C7 +:109EC000CF1BAB0C256E4739667A6D00F3050F3D4D +:109ED000201B7C5D525EC275D167F17C7D15E2FB73 +:109EE0004CB48FEA78DC3A24BE131FAB73F0837C4A +:109EF000F5943FA2F1F5FDF79864C9C6F3ED52F36E +:109F00003EEA1732520B9BF755160CE0F92410F677 +:109F1000DF445E15CA13198AF74D62F4C47DF6C991 +:109F20008B07DAFD8CD6C612DD8753A46669DC0781 +:109F3000A4076C7B72ACF4017B7E17F9857AF9CBB0 +:109F400029C0757CEDD4075A912E81EC97C06074BE +:109F5000FBD749293018BDDF0E70BC024BD2407AC6 +:109F6000BB364D74F6D26BDD20DD332EBAFF4CD4F8 +:109F70008F2579BD413885C19D3D14AE37989EAB84 +:109F8000A21D3785D3D1DBCFD100DF1FF1E261B74E +:109F9000EB85DF1410FBDB5A86F6397E32F5A61806 +:109FA000C6B7BBA730FED717E6FFA600CFBB324E21 +:109FB0007C99F46FEFA4DB685F735DED16B22B8FB5 +:109FC000327B02F3367BABF3D7EF6EE3793217C205 +:109FD000DD2D358C3FDD07648AD77AE1BE1370DB57 +:109FE000CD5A95DB2F64F2F74A60E6C8F22747B6F0 +:109FF000F279394AB953698AE2BC1BDF89FCF58BD7 +:10A000003273E63A851D40EB6CE5D23438F31E8F8F +:10A01000097E3D2DF474B08ACB47AFDF929CFC8B58 +:10A02000B1F7731DF50AF1AD903CFC58CC877795DC +:10A03000782B19014A4ACFE7572BB17FFEF97CC72D +:10A0400079B04E25A3E9887FDD6D92D3BEFD869958 +:10A050008C6A0E7F3614BBE4E7F3D10F52E279FD30 +:10A06000F5FF659A65DA4CB4B360462D9E5B50AC43 +:10A0700000C2AD57B22DE45FD4FA286EBEAEEA86B8 +:10A08000BDD538EE7A5F1CC1D6543DD582F6C5BA2F +:10A09000DA4774A4DB2BFAA22A6C27105367D48EFC +:10A0A000A5FCEF048E3B5CCFDA75F0DBEE3723E4E2 +:10A0B000FC5EDDAC417C993E3853FB1BE883772185 +:10A0C0001EE3C616A3739E7570289D79BE4077D592 +:10A0D000103ACF71D23980749E81EDC6F3C6311823 +:10A0E0009D2F74D119189DCFCED1B9B78AD3B9BBE2 +:10A0F0006E4B4F8D93CE754FEDAD36B07F4EE7076B +:10A10000357E7E37847476E0E9A57358B2D79FBA5E +:10A110004EB43FBD72CFE87E29E263BFF769FBC84A +:10A12000EE0C8F4F7C82F8C0FC6594833BA482EBDD +:10A13000D227116EA475697D80EF57DEA57139674E +:10A14000ED5F89FD42B968DF5E6FC57A7899B66BBD +:10A150001EAE870CEE6AC2434F913F3C0867C1B008 +:10A16000EB28ABB79CDA0F7BDA376154EB316BE746 +:10A17000266A47F3F46FC029ADF3ACDD761A97E297 +:10A1800069F734DB13AC9F8D9AF0375D74F82BDBE5 +:10A1900031B1A4471E94B44BEFD9F250B9D40D5746 +:10A1A000785D4BF3756DA85D4372FB6CF7DEDDE8FF +:10A1B0009FBDA29BFF07F935DA7960DB8195A1E4A9 +:10A1C000A3482F6607521EA9F58D92CC1A5657F94F +:10A1D000201DE5FBF0EEF568BC6D0FD5F27520385B +:10A1E000CA75E98026F204C7301D55CA9EFE446B2D +:10A1F000BE78C33302CE6B37FF56CC2705121467E7 +:10A20000EB8C5DBEB39FF1CE6C49433E3DBF3494B1 +:10A210007C16E9A3EA29939657112729D46E79C2AF +:10A22000DAB5B781F4EE803C465418C74D6B8CCB41 +:10A230004519DD0E6914528B639CAD62B13517F57B +:10A2400058159317841FD7BA4F4AE6DB2717F41E19 +:10A250008B48E4F15FC67D6A5692F2E216368CE0D6 +:10A26000DFF0FC3C663FFC0EC775484D5F32C541D0 +:10A27000779B4F5F9312975E84FAF47CCEA7D251FE +:10A28000F2E9CFC2AE8685E534F80B4F5C48E77F34 +:10A2900082115F02E3F1417F5A2F73C8D1381F2426 +:10A2A000FB46817F130CECFE00FDBFB08FFCDEDEB1 +:10A2B000F055DFC6FB792C5D8D4F3172FDF6B2F59E +:10A2C000BECCB1FE78E35683FEB4802FDC2F879B93 +:10A2D000629D4BFBFEB9FB85DC79084CB0EA307F10 +:10A2E0006895CCE3E877947C85F211565B013D508C +:10A2F0004EEB18D97FEB445E5BB7C86B5B2BF2DA91 +:10A30000FCD6AAED08BF192081F1C9F6F353B4EFCA +:10A310001F5534BD834E0CA5CEC575225A6ECFCFC6 +:10A32000C7E7A37D3558B6EEEE6C66E38DC6ECF25A +:10A33000ED347F3BDBB9BEF94CF057F351DF18E247 +:10A340003CD6E6C645A5304C5C325CEFCEA30BD5BF +:10A35000865C65ADAACC5556CB270CBB7FB10FE30D +:10A360004515389E7E88239E05F286A70665829352 +:10A37000E5690359CC3B98A3C6B71878CEDA9DCFD0 +:10A38000D913E4F6E08F30303413DD2C21178D7CA7 +:10A390007FB564764D1FEE07C1182E17982FE894ED +:10A3A000874272F1F7A68FAFE4700CF32F6EE98845 +:10A3B00002E6BBDC32FB97F1AC817AB53F86791AB5 +:10A3C0006B9826E960DF37CEFEA5912FAEDCAF2576 +:10A3D0009705917EE104D95F9186243DFFDEE31A63 +:10A3E000899F7705F93A3755F053417E36E4F8B93D +:10A3F000AE91F1B32137CFD72969AD187E7E0CFB22 +:10A400009F897AE8F7E4B7AD6FF4B5A01E32A08F4C +:10A41000F27037D6FB7CD8FEDF8B2E365EE1D94C4E +:10A420003F129FB2095C1736C6151FEA917F383973 +:10A43000FC4B3FBD2F420E7F984F0E97D9F250B282 +:10A44000AF355FFEDDD4A0E4E2D706E417A74B0BDF +:10A45000A78BEFEF4297C1F5424BAE40B959165367 +:10A46000C9EF56CA7ABA68DF88AD7BB86F749D6C45 +:10A470001AB8EF04FFE1E7F735E1BAED585FDE0FF8 +:10A4800006793BF2860594FFC186867E192B7F688C +:10A49000D87DD18C7FC0798F89373FE350D0BDEF15 +:10A4A000F44ED5A252E457A1F6DE6CDBABE3395B88 +:10A4B0003B4FC3FBFD3A1952F9CE2FFAD120263A71 +:10A4C000F4A944879BD95A3B0DE9F1A1F9783EB331 +:10A4D000BBAA631CD931E27CC375DB9ED115079EF4 +:10A4E000D7296CF99B3E743C367DAFC365B2CC5125 +:10A4F0003FB3D755DF5B6FB03D519FD96DC1107B26 +:10A500009A4A6A2FEE3BDBE738D46D73B3B46C160E +:10A51000C09BF1F194F02EF63CC73B5BD774A1BF12 +:10A520008DF6D7794C4E5EFBAE1CEF605F97DD7DFC +:10A53000D67C3CE77A08B8BCD8FC7963EB9A71F911 +:10A54000E4A2107F2E0EFD75E46B7AC8235F7D9721 +:10A550009566E1F4CB57A2907C09FA1CEEE3F480F7 +:10A560003BC7E6E553A1F10CF2C9AE27E4CC5BBFD3 +:10A57000503D26578B433351AEB2D139C5C895C033 +:10A58000D7E6DFA9E23B925C69AB6503CF75552B3B +:10A5900009D29B3DE51D96B8F791F23EE5F4347E75 +:10A5A000BFCC607E3B64D19ED0CA4DB2A343E2FED5 +:10A5B0009E40AD5B6F2A31F7F989586B226BB78BE0 +:10A5C000F14B6DB54AFD0EEE2387211B8C6299EF8E +:10A5D00097A2FA43BF22007751DC93D5CB1BF7B487 +:10A5E0009F8AC85BC39C5EBAB70D3E3D429E8BBB43 +:10A5F0009FD8E2E1F36CBCF010568C430EBA17AE54 +:10A60000A7C021879F739BB877D4A6BFB9ED4ACA6C +:10A610002F0F822F4EFE41EC260BFDBE2E319F7B6D +:10A62000F0399BCEF3EAE4AF197CBFC592AEA638F1 +:10A63000837DFECCEECF3E7766C38DC4FF55389F39 +:10A64000F2CCEF3D21EE8F1DFB4AEAF7E887587FF9 +:10A650000203EFC97CACED38ED575F907D43C6F83F +:10A66000FE33A1710477C140BF3CCF312F2F10E7DB +:10A670003900FAE47CE7BDFC56E0299487270F7384 +:10A680007FECC9C3EF901DFEE41F7C1994BB278F9C +:10A690000F9FFFF098F08B6CB8C7FEC0EDB3C79466 +:10A6A000BE927CF65DAEFF0CF7070FBBE515943E3E +:10A6B00019E5E5D897F7C9181F78AC4D935E66FA8F +:10A6C000E77C31CE0B0EF7CBE8378D34AEEF79F85F +:10A6D0006B8F737B13B747B737BD13C2F8FFF6C74D +:10A6E000F9788F8A73B285F07DAA8DE7796C7F3C0B +:10A6F0003F3D9ACFE7FE71B3DF28CF6BD77ACE5BB1 +:10A70000CDD364F739AFD38CDFEE266E77ED56E20A +:10A71000E193C1C77E5FD2149770BD2B85CCDE0F4D +:10A72000551339F73BE322A507BFDE7E35E6B75E5A +:10A730001936A51896EF9226B3B23E41067F0CF368 +:10A7400037DEC9BEC0F05FDB5A42F91B9D0DE5ED57 +:10A75000786E73ECF2DA5DB88FDC8B1115CA5BB8DA +:10A760006B2DE62174E27F5939B03E7D119D930037 +:10A77000AE0F98456B28E3C4FE469E790EB9FC0ED9 +:10A78000E98340AE5E217AA99E7C90002C1A5E4F30 +:10A790002DE57ACD627F3EA07352EEFCDC312DAA0E +:10A7A0008B7EA59EF6CF2EE1F23862FEF829F65395 +:10A7B000065B3483D15FADF3E9198487F818CC0FB9 +:10A7C0002C59C80C203C1F10D377F98C91E9BE1688 +:10A7D000A085C7B7FBC039BF9A4BB87D3FE1DADB34 +:10A7E00025F4238EC699144CC3F2F178BE79714BCF +:10A7F0009BFB3E915B1A1E21BDD809991E5C4FAC94 +:10A80000061FAD67BD75FB7567FD2B4B24911F6659 +:10A81000F31F0C6516DDEB484138A5CE6706A3276C +:10A82000CF7FC543D791F81F59EAA6FB68F9B21C40 +:10A83000F93F7364FE9F6A3F36DF86CE8F76C1B7DD +:10A840001B35A0FD9DE1F5FA50BE6DA175AEA42E9D +:10A850007F5EEE0D2576DCD672E95D0D521077E451 +:10A860007FC9E367B5DE0785FB95CBDDE31B8C3342 +:10A870001A9689FB7FE35919CF7733998E6701CFF9 +:10A88000F198807610337FC85F933DFEDA6D428E7B +:10A89000343840F5D92CB0745A37785E9A9D877257 +:10A8A000911C8E637CA2470FD3BD48A81F799E0ED2 +:10A8B000CFE72FE528313B600026B37AA14A192C57 +:10A8C0008CEB35097C25267798C77FF08D83E88F40 +:10A8D000841BDCF968CAC192177DE7A09DE6390F99 +:10A8E0007270F972F25F3C7C1E6D7EFFC325229F61 +:10A8F000AD04C2641789FA85F2F46CBBDEA6AF71B1 +:10A90000224279395D0725A247C5E4C47DE87FC1AD +:10A910002F65E0F99760E23DC6AB7E3693BE0FDD52 +:10A92000374854235FDE3858A27754179317994855 +:10A93000B633F8EA8301F29FAA416FD6B0BF7E8991 +:10A94000F8288DD3282F6BD54FFDF70586C9CBB2DC +:10A95000F71707CB4A9AF689D7D54ED79CFB979520 +:10A96000A1E4CF4B1CFB9741B19F3874DFFD769279 +:10A97000F3D1EE6F945F76379DEB2F1F0F62FFFDD3 +:10A98000D30BD04E595701AEBCBC7595BCFCEAFA4E +:10A99000290B701F679DC8BBD337BC73513BE9DBE4 +:10A9A00004C5F95633C1437AC25EBFB84FD2187F8F +:10A9B000E9307AC34B870DCA3ECA8BFF6678FFC564 +:10A9C00067219FE23E8ABB7DF346BEAF6AC3BDA24C +:10A9D00037FFA184E6ABDE89FBD0139320F234DD90 +:10A9E000FB1F1370F560E39CC418E467F43863310F +:10A9F00074A0F8542FE9ABC4F5786DF92363F8F926 +:10AA0000FEF9FA21B2CF65DA872E84AFD71E2F3434 +:10AA10005E7B5FDD5BFFF608BF4FD5BBFFE58DFBBF +:10AA2000DC87F465703DB8EFF411F6F467F2C6AD5B +:10AA30005E2DE1F1E84E6341E2F3382EC59CFD2A1C +:10AA4000A347A63C4A7EA2FFB2FA2BF08A3E1BDE49 +:10AA5000CE5B5384DFE62F4FD1BAA668A656C7C691 +:10AA6000A11D90716681966E277D65DFFF80645D14 +:10AA70007C361F2F8E2B00DCFEC5F3091F38C60D58 +:10AA80003147BC0BF58AF0D34E03BFA787670EE5AD +:10AA9000EFDC1E9E771E5BC6CF334D54F2F37BFC7A +:10AAA00012DDC7F7B94E2F9F0BD52FB4BF79FB2D01 +:10AAB000EA02B453A6E8ABF64E62787759A549DCB2 +:10AAC0007739E64FD13D39BDFFEA832D80E31F7E04 +:10AAD0009DEBF4AC738A9EA0FBF4AA52FA749CE638 +:10AAE00085EA7D2DC5FD1CEFFBCF87F97AB329558B +:10AAF000B609F319CCA753BBFCE857C6B8DF6CFB0B +:10AB0000D94B43C9CF871DFA68CC7C2E3F5392574F +:10AB1000D0FC3F5631FC3D0BEB3D789740FEFB5D92 +:10AB20006F8B707CA618AB78BB93868FBBDAF4383A +:10AB3000DE238BDF8B00E487F8990027187DEF3543 +:10AB4000B87C2806FC14E56CB2E503C3C0EF03ED46 +:10AB5000A877BFE68365F9F0688BF0F935D964A66C +:10AB6000A7A887F6693A62D0FC1CBF84D3695D351B +:10AB7000C4C3ECD519D81EEB7FCF1495E492F9BE6F +:10AB8000742F526035D0BA1DA8838C81FB0ABBBEDE +:10AB900094457EA9F5100FB27ABBA774D17D2BDD49 +:10ABA0000698786F92FF6636B1F07BAD2F6362BE78 +:10ABB0008975157D5FABF37BFCD6D63603D9B131F1 +:10ABC0005ED60C7EDE65DD5485F0B0EF1F27BB93AB +:10ABD000AD0FFEFA812C5E5967C0326AC73F9BF306 +:10ABE000B5EACE263A8FB66ECC0374DFBFB51CF83B +:10ABF0007EA6BDEFAC30B962EF3B97E979E327EF72 +:10AC00008592DF72CA83A2EF2379289407D71DE6C5 +:10AC1000F4BC4DE8B763FE2CDD6FD8BBD647F7B662 +:10AC200078E13F2BE87F77E7A28FD3F5D4629DB11F +:10AC3000BF1F2A315CF765541D57693C0BE49B41EB +:10AC40006778DFC3EC24BAE7052F063D931AB8A452 +:10AC5000D2716EE59E781FD945AA6D17D5737BC654 +:10AC60003EDFC8E890FD26FBAE639E3FF303C7B707 +:10AC7000E6B78FBC7E5921FBA8A7C4FC19D2AB4B09 +:10AC8000E4ED7F7DE9227E6F6581BCFD3BC5F8EF79 +:10AC900094ACEA2ED48F93F83D335EB843C25E6421 +:10ACA000F620C9CD3A8BDFC7B58EB93E8FB272CFD1 +:10ACB0008DFC3EBF1ECBC7CF7FD602C54962375D34 +:10ACC000A5E59BAFB61DBD5EDCAF5568DE95A899C6 +:10ACD00064BE75E99F227C5F6D6CA3417E1B51723F +:10ACE0001C2E279CEEF4C4785E1D5FB7CF007D2E2E +:10ACF000E6316E5E58534DF77CB275036DE27BAA68 +:10AD000033D9F9289712F4DD8F95948CB59495CFAB +:10AD1000888F337A1DE7BAF5AA07B278EEFDF627D9 +:10AD200003106864E5F99EDF67E3E40F2AC83AF789 +:10AD3000EF532934BE629FB7327ABDE488370324CB +:10AD40005B703E85D87A8AF326D894C9D2EFD3B007 +:10AD50008280E3E8D15819F9D21902BC6F36541F2A +:10AD60000F63DC36D43FB7859EF5895E949FE8EC8F +:10AD7000AD7ABE73312D916A97DC87EBDCF99A418D +:10AD800071EE2858A552BE5A30A9E6BDDFF85089A9 +:10AD9000C2ED68D625CEAB1E6B783D7BAA72F1BAA8 +:10ADA0005867F49C7F4C72C14325EC59B5E00DD92E +:10ADB00071DF66C4EB5F78F9E8299F2A1F7B3D7C31 +:10ADC0000C36713E02E323BF07C4EAA17317860F56 +:10ADD0009CE72EC6476A5CFC508E2B748EF6CEB96B +:10ADE000F9EFE31C1FE179DD3D25894B2294570BD8 +:10ADF00012E5F70ABD7091BC81EE3162D2C1EF8FCE +:10AE000067FDDD9F473F8E8F70FF756BC8BC3C525E +:10AE100051785C8F4985F0E0F50F093FBF783DCB55 +:10AE2000C737C57C2D4871CF2F0DBFEEDBEBF3315B +:10AE300036B67D686F2B29D23B4ABF019D389F6390 +:10AE4000BE0CAEABDDB145A417EEB1988C4824978B +:10AE50005086FEADD01350DF1FC4F88B5FCCAB7BA8 +:10AE600056FBE8BED8508542F7D7066E4EB2B510F5 +:10AE7000CF350E6431965F75E702C293AD53372329 +:10AE80009DA3B1BE76D447FEF20CED0BDFADE821F9 +:10AE90005CFF8FA191C8ECB3EF86B777519EBF9945 +:10AEA000C8E29597E81639EFEFCF58EEFED800DAF2 +:10AEB00051EF7436E9646F9F71733F38E72BEB777E +:10AEC0003DF265625D66AE64E4D647AF3D51C88E23 +:10AED00060EBA8F0CBE675A15F46262C2B3F147ED5 +:10AEE000A40BFDB07B75F3AB11F283F2FB0F4C2E7C +:10AEF000BE7E3272F1AC98A7B65C0CC647441CF516 +:10AF0000AA46103FC615BF66785FB3D70F38FE0B51 +:10AF10004FDCBBE79B8C1EB23817C734F99E27D88D +:10AF2000F7A5A696C0F23507CF5631CEFACB093237 +:10AF30009E0146398BA29CBD053E8AFFBC05FBA342 +:10AF4000331CF83C21E60973805EEA77C4173F9F03 +:10AF5000E6655BDF7DE14E77F96A58340EE387578B +:10AF6000DFEE878C84BF57CAED177F27C2F3C5BFBA +:10AF700000A92EA4F35A71EFE9F21F9CADA27D74D3 +:10AF8000CD0CBD1AF72F6D3C7E22D6B337991C1B12 +:10AF90000EFBF5DA7046C57CA79777CCB87C0E60BF +:10AFA0003B99AE09B85E8D81BCEBF4E77ADC788E14 +:10AFB000340E2FDEF679A1427828DBA4BC71AE9F57 +:10AFC0000B7BDAE6E3A9DEBFFE7684EB03FBF7D367 +:10AFD000D97962A7DAEE7BC2AEF6B6BB5CC30BA42E +:10AFE00001562AE916A926B76F15F4A7CC8968DFA0 +:10AFF000ED9C9BC5DC73075C4F91702DBE61E046F4 +:10B000001ACFAAD03D518C07F5337F3FDF3D3A95EB +:10B01000A164245A31F43E1D10BF0FE8D06FEC7BC1 +:10B02000EA0716601C2F00CC6FA7A7427240F11DE3 +:10B0300009EDD17416FD80A0A1B8E4A304F74398EC +:10B040005DBB52D88F2575EEEFDE78CF19512E07F4 +:10B050004DD04FF67D540B6771BD854677FED21DEE +:10B06000259F253B72C53E3F1D015801C6AD4D0DC4 +:10B07000340F29CE75E3BA33699FF7C60A83EEF918 +:10B0800055206E525D8FDCAD3C2E41C6E1FFAF54C2 +:10B0900006549C6F2BD9FAE17C7F434C365EC9F392 +:10B0A000FB99ECA79F69F5701DD2C1C7CFC5EAAC6B +:10B0B000EC18E73B69A985EFAB19A58B87F1CB6F3E +:10B0C00088A9D4CF55EBA694F2B88F5B6F1E11EB15 +:10B0D000D47F3EF41F2AAEBF6F3DF8E2254887EBD0 +:10B0E0001E934163FD1E792802595ABF322AAE5F72 +:10B0F000D7EE90F3DA5598A9447925DB797CF2DA1A +:10B1000047029985ACFEB58FBE7C0E30FC8E740C68 +:10B11000EC9988F3E0411E3704ABFF9CCBD8FB6B66 +:10B1200015F8DFF9ECA62BA2DC0F38FCC312BA7FAE +:10B1300054DAB6EBB3D46EDF15FE80637FED92A8D0 +:10B14000DF86E371CE6F4B992979F6DFECB8FAE12F +:10B150006F4B1CBF9D7EBA8FF5DA6DF7A94986C784 +:10B16000CA6D6F933E99B7FD3B51A4C3CA9DEE7D56 +:10B17000B6EBB6BFDF857924D7C930B010E5593EAC +:10B1800041E5A3A6362093DEE7E7A557104B18DC70 +:10B19000F75E5BF06BF6FDCD980C41A67ADFDCF72D +:10B1A000AAFA189693E1147AB02B77BAF5DECA6D35 +:10B1B0002F535E83EE8381AA39B8BFEF966B2F3C85 +:10B1C0009B3F2ADA212BFBD6BD2D33BDB172C75B65 +:10B1D000CFA3FE58E9D19F6FE27F2A87C6A1DBA2E9 +:10B1E0009E7B66B61597FF70DD778EDE63B17E0FAE +:10B1F0003FF2BB7B304FFEFABFBC7BCFBFA3BDF09D +:10B20000645047FDBFF2C15F44C1218F5F8F727BE5 +:10B21000EBC824B02A19DC91FF17C8E0FD57479E00 +:10B22000786D329E733BF2DD3F8E3318FC8D4F5CA0 +:10B2300044F7EBDFF8FD79E387B3C7515E330127AD +:10B240005E197E5E6CA7C48D97C7C5D3C38FC3DF5D +:10B250003DA6A25DFB9E0403B8CEADE87B5F457FB3 +:10B26000648F0903489FDD3B5EDEF36FACFC16E3A1 +:10B270004F200F7FD8F827FA68FD666A923D57EC99 +:10B28000787901E2BB1206683D1DC2CF038C9F0D89 +:10B29000397E7ABF1F85132AC663573EC4F8770EDE +:10B2A000F291F1EF9CA1FC7B0BFF337B28FF7E101A +:10B2B00075E7091D85EBEFADC48DDA1D63F3E6314B +:10B2C000E4F61186BFCFC4D60723D17799C4F1EA3B +:10B2D0008C9AFF19C579F548C9207F17227FBF7363 +:10B2E00074323A39AFFB073E8B74187822A0E3EF33 +:10B2F0008FB8F6895FD13C3BF2FD675583F66D2030 +:10B300002ACD626518FCD90FACBC82C7B661F9D6EC +:10B310003F2F789ED55F8EBF204327BE51790F9B6C +:10B3200077C487CCA52D06AE9B990A1AF78A0C9F85 +:10B330000F2B32BB16E3BD125EBA4BA5F6BD9E398C +:10B340007EE27D4F2B76BCB800E5AE103FEDF1EB11 +:10B3500038FE73D9F7ADEEF9EA855FC1E627AD5344 +:10B360005EFE6676FD373E8FDC1750F07CC51171AE +:10B37000DEDBCBF71CFDC5F9F751EE33FDD93BBF42 +:10B38000ED7D2641A7C2F2C1E7F948E31B2DFDDEA2 +:10B39000881ADCEFF6D0F1F089FCFA7F7C295FB7E0 +:10B3A0005740BA054D67AFBDA240D29A589DC3F72A +:10B3B00030DA170CDFC30FCA14F7E9EADB4D7ADC89 +:10B3C000AB2F561488BFD6D9FDEDDC750EEAB5C398 +:10B3D0004FFD90E473C5432FAAE877ECD9F63DB54D +:10B3E000BF3E371F707DC838E87DF8E15DE7707DAE +:10B3F000903FAE3553B4BFF27177FB2B1F7ADBD58C +:10B40000FE75561FD90B23F5F3A6625E81E37D73AB +:10B410009F9FEE137CB34FCE1BE79E50EA77D9C1B6 +:10B420005DCF2EF8359E676DD81FA27B1477749878 +:10B43000E36F41FB6DBF5FEC1F9ABF43BB74C7B3A3 +:10B440002103EDB41DFB2FA77C1EBBBD1F78E8793F +:10B45000EE016B5E84B5776E7FA201F345BC7AA3E3 +:10B46000F120F3F71C7270E3B32DE351EFA37F6C6F +:10B47000A0E3ADC4E91C951C5D4079E2B2EED38334 +:10B4800079D76FDE9E3F9CA0FD1C3F134CE7BDECBF +:10B49000179EF8BFE4BF77C5F3C7FBEF2AB5F7BD2A +:10B4A000F9EF77B2DF6F90B8DC58CFF07D8E42F3C2 +:10B4B0006B5B5B2C5ECB4879575B631CF77396978D +:10B4C000F2F8C7D4572C1F9E0D99DD6F4CC7F14F72 +:10B4D000843EC0F3FA3BDA74821FE4FF4266519760 +:10B4E000E37DF3104738EC17FDB5D1F67B73A17EF1 +:10B4F000EBFB882EC5F4AB9D44BFEB4BF979E953C8 +:10B50000E9377C127406DC1D2A62BCDE3C296FFF21 +:10B51000EA349EF7E5ED6F4929B733EDFD039A7ADA +:10B52000C3C4D5FCA29DCF941A2E7902254BF74FA8 +:10B53000E7F22A32527703EECB0D9E174E688EF358 +:10B54000C2EC3B9D175E63F23C56568FE6418F88F6 +:10B550004FE03EE5550E7C9F15FA2350958AA1FDDC +:10B56000D58DFB0D79F4D8F342CEBB23CD943FB2F9 +:10B570004B9F5EDA3FCCBAA1ACBE6B86F35CB1A246 +:10B580006725D7FEB0F932DD8355A8BE77DFD0C678 +:10B59000BF7BD797A006F35CCB13D09107CF3E219A +:10B5A000C708578D70B124B43BE0D4181FA75DEED7 +:10B5B0007E9FDF73FBFCAD07BB515F16A2D30EC1AC +:10B5C000CF6731116426B96F1AE663F6447CA4276D +:10B5D0007B82F9EFA3FF45CE2EA0FA2A9E5FA478C6 +:10B5E000EB3EF21B8D132F9878BFD1ADF52AED0BF2 +:10B5F000459AF653F9A8E923EBBF107DECFB08064A +:10B60000CB05E24F8D3AE7EF6EF311CA6FBDE16CE7 +:10B61000D5182E9F22B47A5A1CCFB36BABE7C43136 +:10B620003F2254C77F9FC2C6F3793C6D6301F998EE +:10B63000A573F958FF453B2E992539D938CD17C444 +:10B64000E7FF075094EC5E00800000001F8B0800AD +:10B6500000000000000BED7D0B5C14D7B9F899DDFC +:10B66000D9D92730C002CBF21A10140D268B226ACA +:10B6700035664134F8885915A326185763521201CC +:10B6800037D636B4B5611010C447486349DADA7664 +:10B69000A5D892366D31A58D491F77D5E8B58FDBDA +:10B6A000A2318937571B34DE5C494D2F7DA4F5DE6E +:10B6B0006BEBFF7CDF996167965D3069DA5FEFFFC6 +:10B6C00077C92F999C39E77CE73BDFF9DEE7CCD9D6 +:10B6D000A3DE6909830E426EC0DF1DA39FE6862F9D +:10B6E0004EAF981E2EB7E5C473FE224276E63C4E5E +:10B6F00006E9D37CBD91F8687F334FBC7DF499E8AF +:10B700002547139CB4EC9D986BCEA54F0749379401 +:10B71000D07E6513B91DB9A3E11FCDFA84EB12EDFC +:10B7200097E625E9F06C2B13D20D1A7C3A3F1320D3 +:10B730003E3A4E6B99B016F034873E49A4384DBD61 +:10B74000682064067D5FDDE9F5D276F42FDD47EBF6 +:10B75000094FD25768DB71644D5FD1E8F1F78B1C5C +:10B76000212984EC56EAF7CD7EFB990728FEA257E3 +:10B770002A365230FB8E0E91BCA9B41C1AF27230DC +:10B780002F27996625A3E140BB5CDA2EDEE5271B57 +:10B7900000CFCC41E2A7E3C7170E1298BF4D22920B +:10B7A000414238887FC2AC6122D3760973075DF2CB +:10B7B000540D9C3F1BA3E27923C18078DA1A4A3CDE +:10B7C000F9C984581AE679F2E9BAC4F10344A470BD +:10B7D000E22446FFC87E6F2530FAA874E92C9B98B6 +:10B7E000E08F065F5DDFC653A9BC49532EEB5C03B7 +:10B7F000F43739FD32CC3F7E16A38B5A1F2F0D1222 +:10B800002F1D379EB0799212E23D441F712532817F +:10B8100071E8905EED7C362AF4DE28B2F9C09F37DD +:10B8200015DB11425FC579170E196F85324F2E1542 +:10B83000B2FA1BB90417F49245291B479763CD67E9 +:10B84000BCE7AE46422E69E66BC9A4F357E1D27F4E +:10B850003B4D241DE8FB41E926B806911FD4F701B2 +:10B8600065FE26E720D26714FD8A18FDEC458C7E24 +:10B87000F608FAED52FAEFFA07A3DF089D38C31A6B +:10B88000E0C3483AAAEDE78DE02DE393F623E423E5 +:10B89000505E5609F2DB6965E5FDE25D9572119334 +:10B8A000AB71E485103721A59D37DAA0BD5B14117B +:10B8B000AE7913D5070E4DD9AFEA0736AE23D7536D +:10B8C00049283F935C03394449DA3E5776C17A757B +:10B8D000A0A484E1BF2A4EC0F66D9260E06EA3CFB3 +:10B8E000530BD20885DB6CE9B4C07CDB4D9D08A707 +:10B8F00039CB207647D16FC794F91A1BECD37BA6BE +:10B90000C7A6A35120FE6872FFA6D2BFF9E8E74F91 +:10B9100019297FF092205929BE20F46FA9EB9B478B +:10B92000FB93BE81DC5C18271EC7712878390A0C8E +:10B93000A429777C3CBFA5F015DF601D134F1EF0D6 +:10B940008CA267543C5B004F676C3CED59E5C8A77F +:10B950007C8303C7F99128A17E729802968D747E2C +:10B960008EA604A9893E77F181F66A780E98884CF4 +:10B970009B9888F75439C59B9F3A8D100AA7F5E22A +:10B980004CCB04E0FD864EE2D3E8F94D36FF05913D +:10B99000C2E3453FF1533C7947C00B68F42A7CA0D1 +:10B9A000AE1B294C2264361DCFCF4F077D6AF70BA3 +:10B9B000F854E1A87C623779895804700CDE207D48 +:10B9C0005A00D8EC70BB8F2432BA35CF0DF908D8A5 +:10B9D000B9629E809D6B33794F6DA0E50E3A9F6EE4 +:10B9E000FA6C51F846EDE74E4C647CA88C6F2355F9 +:10B9F0000921806D7CCEE51FC31EDB806EB47DC344 +:10BA0000F9DCEFBCACD295FEFB3F629CF3ED5B90A2 +:10BA100077D3419EDF2345AB0D86D870FED4287DB9 +:10BA2000E7658DBE6A20CC7E1022A52D9F1ABBDF54 +:10BA3000EE46323DBF205CDEC3072C409F36C7D6A2 +:10BA400053B9749EB2C7E02990004C898E4E914F35 +:10BA5000429A70DD4DC403CC4B9A33CB4F954BB01B +:10BA6000BE2B5C8F43B5D1C1535B4B4C1349D008FF +:10BA700074919C3AB9DC64637C13B9CED6113A1E3A +:10BA800018938E56454E22E9989FF8BF938E2265F3 +:10BA900027E4D7B8150921E8779CFA49747C92A964 +:10BAA000973FB59FCAEF91F3AFF85F3EFF483E194D +:10BAB000DD5E56ED267F9436CDF093600787659F57 +:10BAC0002515BB5218543E2DA126304D59D57DE980 +:10BAD0002708D8E716F16D0BAA2ECF8DE4B1E0F35D +:10BAE000E46D959EC6F0785AFA18C0EE9C32050FA8 +:10BAF00071613AC589F7BB8E920F4EA7B6CCE7C5E8 +:10BB00000D1AFB71592CDF9E48E9B213FCDA28723A +:10BB1000B03EB15C4EA4780986E8FA7C3FE835F483 +:10BB20001B457E011DE78E613D9D6E57E8342FED6C +:10BB3000ED4FC334A996E40955C8E53E4F05D0AD95 +:10BB4000628D0FD8820819D76FF1233F54884017B0 +:10BB50004E9E64B861BF79FAC5A2978323BE687808 +:10BB60007F455CF1259897A388D24DE37F50411023 +:10BB7000DFB66BD6C5E11C87AFD8BA1DBF90669003 +:10BB800069D336972108F18C8904DA81EEE4AC910F +:10BB9000809F961A4AC77AB32B2F08F62E35642554 +:10BBA0005E8C13C4A095B6EF5A7B8F07F5D3B539D9 +:10BBB0002444F906751965323ED31B027F9A17A5F6 +:10BBC00032A304E33C6681F8A6CDB52281307F9B89 +:10BBD00044D35F7589FE17615DF96BF3109EC1E276 +:10BBE000453FF166E7F3F4CA78027E80F53C1734EE +:10BBF000535C9E5C39AF7D90CEC742E23ACDF4D91A +:10BC0000CCCB21B063F279AB04F4DE5A20DF69A01B +:10BC1000CFB25F590B79FABE9DB379800EED0574F2 +:10BC2000C9299C3F7DDE1E24B4BC73E5B2E10480CB +:10BC3000D36394A07EFF8DC06DE04F59AE3F81F17C +:10BC4000A145890F091F9809EB67FD807A6237DFEC +:10BC500089FCBF2B7F9A45EB8FA7DBFCE7812E6A1F +:10BC6000D9EAA2FA6D3AF2D3A541CA4F0699233711 +:10BC7000287F5A1CDB5C2724982F7DAFF2476EB8D3 +:10BC80005D586EF56527A535F89994C316815FD97F +:10BC900006FA06FD562273504E67F5BF7DF2EE455B +:10BCA000E087B659D5FAE58BBCDAB2FC3FA7B0BF46 +:10BCB000E2F7162525ED82F6CE0C1260F4F19155CF +:10BCC0001A7F464AE2510E7B12BD7F4C9C319A2F5F +:10BCD000DBF3195F1EBFD05699077C4AF9D22C01BD +:10BCE0001FEED2C5C9EA53E5C3B67CC667B1E86E9C +:10BCF000BA564C421A3FD0E4EC447EB4387DE84753 +:10BD000047B6BF2B99E90B95FF2D2E82F26091FC6F +:10BD10009F7F10E5C3E101F133E7070847F9C42429 +:10BD2000B27878BC79C4C24FE5FFB6FC3C19F8F58F +:10BD30003D913A1263B4375D2BC1F9D4257A7392E1 +:10BD400034F1873387D23DCA7CBE98C4E6D3EAABD0 +:10BD5000F63D48E17A6B2419E5C6453C1D609728FD +:10BD6000FB83DF49FDCD5B9252B4740A307954E015 +:10BD7000CB5CE0A809E4DC49FBD1B72DE487322C89 +:10BD8000BDC919D4C9F7BE647F4992867F7991C530 +:10BD9000870B8C0E03F900F47982C665A14984EC07 +:10BDA0006D14F1B9A7D185CFF646099F1D8D5E129E +:10BDB00032D3F0875C3BF700F8D90E1BE2371E5FE9 +:10BDC000B4367AB07F4BE32C068753F9BC7017F07A +:10BDD000B5CDA0CAC9AD584E30AAF525BB30BEE3DB +:10BDE00058FDD6A4DB514EE87C50EFB58F33AE3111 +:10BDF000588AEBF7FEE12BFA5BA1DF13B77FA23283 +:10BE00000FF8EF7523D1E63146F14B888D77B3F00B +:10BE1000DB330DA84F9FB87DE7A95CF05B5FA3F013 +:10BE2000C7E2C74E063F263C15DFA3BB105F335D5C +:10BE30006F2B85671699BE8F250F91F3A54F82F260 +:10BE4000E124A8A79F38BA961C07F9A4C35A4590C5 +:10BE5000539F17F25D420BA5B107ECAD2FF455B01F +:10BE6000B734D03944CB822237D4ECCBC7291CC19C +:10BE70006B211DB4DFD1DBEF21D0AFED650BC589A0 +:10BE8000DA87E43CE4776B411569A6ED76565A896A +:10BE900091BE4F98B78600BC9DBFB022FCDC539387 +:10BEA000515E77894C8EC6D5432E030969EDB8C51E +:10BEB000162EE781BEDC447C5351AEBF90A4D18FD7 +:10BEC000D44E7E19CA02A990090776F8210FF343D0 +:10BED000587D4FA2EF206BEFC3FE61BF304044900E +:10BEE000D7B3C66007C49BC65A74FA161A0F580611 +:10BEF00051AEBDCBD24B09713014C82E4F886403AC +:10BF00005DD28DD417A32F3C020951BBD149FF014B +:10BF1000FCF8F343E7C9AD84A4AD1174F3E0CFDBC3 +:10BF20002F1A6E05FC587BD50EF1E7EBEAA03D4FCA +:10BF300034EDC13E19AB13C68A6722FDF81F2529CF +:10BF40007EBC9D6481DD6B693C42DE3285E1F0118F +:10BF50007925F5A9FAF39B930D7AFF4762FCFD1250 +:10BF60008DD3811F5B5F3592EE28FCFD87A45C9D1D +:10BF7000BF9BEE3784E747FF7DF982B9BC4BC79F73 +:10BF800063AF7F468DBE7F56C0A6A3634E4392AE7D +:10BF90009C2BBB75ED27B4E7E9EA0B3AA7E8EA2743 +:10BFA0003D334D579E1CFC88AEFD2DBDE5BAF2D445 +:10BFB000BEC5BAF6B71D59A12B1787EED5B59F7E22 +:10BFC0006AA3AE7EC6C023BAFA99E7B6EACAB30737 +:10BFD0003FA56BEFF28BC78E807C527E34527AED98 +:10BFE0004A979F01FB39D84CFDB879CC3F067B4B73 +:10BFF0003289E21F53C3940A7CC5FE5AC00E809E4C +:10C00000DFF3E9D067D04E1A3C20BF7CFE42EF46FA +:10C01000E8D7221A884BA347A48504DE97EF49C4CA +:10C02000F7DE9226940F819A0D6B3CD86DFD7A1045 +:10C03000E376D207F8BDCEF0E34539AA7E1232F599 +:10C04000FC6F26F725F8C6F0FB4C92BEFDFBE5FF22 +:10C05000AC64CAFFE0706451FE378EDF5FE5FB47DA +:10C060000CDE09C92C5F5E71D6A98B7B90AE237163 +:10C070008F85B4803895550F679C60CD95F8C66C58 +:10C08000B871CBCDC73791F2459F94E6749D5C4C57 +:10C090005FABFEFD687B385DE79F453E9BE31F413C +:10C0A0007D47F5E2EDC93ABDE8F32643DCC77B5195 +:10C0B0002FAAEF737BA7A05E6E17999FD22651B966 +:10C0C0001C835E917AF9F34912D39F31F4B340F5A2 +:10C0D0002C18DC9D2BEF6F07BA79B711B44BD4063F +:10C0E000A19E8D844FFDAA7B006FC1C5FC29351E22 +:10C0F00052E32D0BD51F105F592482F432537AD9A5 +:10C10000D13F7A0CFD4B3A0F09FC23B393FA9F60A1 +:10C11000EFA9FFC9FCCD0FD7BFCC56E63D4217C5EE +:10C120005EF6D8BCB5C929B1E1FF20C67ED4CB49A3 +:10C130006ADCFDBF93FFE6264B887F241FAA7C663E +:10C1400006A6A3E3BD27B175A7D38AE7D4FD0B09E3 +:10C15000FEE3477E3931EB8C3C1FD6CDEFF09AA938 +:10C160005DDD376B05F61326F004F44CDCE086A5A4 +:10C1700060274909D31332FD07F8CD56A4D71B9683 +:10C18000083B2A803D8E1F6D7755FDA0C6E7E3E989 +:10C19000976755FD3293CCD4EA975871B8AA5F548B +:10C1A0003ADC71BD5144BFE33AAD57FD090AC7946B +:10C1B000C5FB20CF2C7888F76014F9FB27C52EEF3C +:10C1C0003D66C5F8DBB146C038CBED0995019FBA95 +:10C1D00003C403F4993518227E0AFF0527E34FB7FD +:10C1E00027C881FFEABE1CE400CF2E13CB0BB9B7E2 +:10C1F00005396DDEE8DF93593EFB4F171EF3C0BAD9 +:10C2000097E738504E3FF620417B3DE0DAD859069B +:10C21000E3CE221E334E97276E289F3307519F7817 +:10C2200006BD024BC1C97174E82B8D64DA261ABFB2 +:10C23000BFD368C1E7D546119FF3730E1CBD83C2FF +:10C24000DD9A6BC37C416B9E0DC769CB16900FFFC7 +:10C2500098F5480EF805BF697461FBF6C703859031 +:10C260004F683BC6F68332BCD3711F14A9E6027C2B +:10C27000426C7F870FB860DF37E3F84FB05D9BC932 +:10C28000FFAF1B283EF25AC17348627480F9B6585A +:10C29000D9FCCDF680279196CD13C8FAE5D1E451AB +:10C2A000A107E524A3900A7940C6A7C22CA909F2E8 +:10C2B00021542BF451F488A935C8C1BE077958948C +:10C2C000202F9469091EA5311FC9AC113DCD04DA98 +:10C2D000136FD0115E0F9395F80E3BA05D887B9491 +:10C2E0008EDBEF64FB13EE736C7D7E7FFECEA35975 +:10C2F00024B61CEF69AC3C53A1C9BB3A48F4FDDF3E +:10C300007373CAFF027A087D045CD79963DAC19B14 +:10C3100085EB75323D75FCC2A434F08B1BF8E8FE4A +:10C32000A45154D7494A8378796B819496E8D0C256 +:10C3300061FAC278EC455C2F7B5110CF17347FEF48 +:10C34000F5FA4F53FAFE8E7684BCD4CB173E8A7131 +:10C35000E2BB49D213105FC93F351258CF77BF3FB8 +:10C36000F32449183DEEAF1B4F25F19ABCD1BBDF3A +:10C370003E5D6AA2F0DF7DFE74298FCA26A8D353E2 +:10C3800075375E29853C95D0F07BF7658AAF5C4EAA +:10C390000A0350A68E32C69B72DD92D01874EB4A07 +:10C3A0007DE851C80B069B1D2247FDB2A7ED7F110A +:10C3B00080EF1A007FFADC6219DEC9D125FEEFAEEC +:10C3C000B71757D078722B27CB0E0EE8269B217E0D +:10C3D00020E7CD1EE09BAD05CC2E6E7D580CCAA08B +:10C3E000AF42012FA6852CAFB82F537D6BFD79107E +:10C3F000F6FA490BE79B1F0779BAA904F97ACED55B +:10C40000400EEC1F2712210FF8D06430229CE10B64 +:10C41000F66037EAD9C04CD0374D171E9B04EBF5B8 +:10C42000FB64762E40CDAFA51A024F56E7427ECD73 +:10C4300083F9B5DD7C1FEE93C59AAFDDC5F60FF825 +:10C44000F944898F7FDB119A1BE60755BE22FBED6D +:10C450006F249E7CCA5F2F355A3C30EE671B457CAB +:10C460001E6974E1F38946099FDF6F2CC4767B1B3C +:10C470003D58DEDD380BCBAD26B2DEA7E1B34F3839 +:10C48000D93C5627947DC2499FFD14EE65DAAE97DC +:10C49000F687E79CB341631CA5C79C2B542F4A50D9 +:10C4A000DFEEB94CE17D91C283E7E87A4B31BC2FD6 +:10C4B0000DF685044ABFD222F6BEB7B157E977041C +:10C4C000E1D27AA47FE955566FAF6570EC57D4F688 +:10C4D00085C5CA38C5D09E8E5BACF48B848BEF29A2 +:10C4E000DCE268F844B6A7DEBC91942AFB1410D7AE +:10C4F00099FA38F067648E840EC17EC6F9A7CBC066 +:10C500002EEC29267906DAC894D2CF41B9B78188B2 +:10C51000C644420AD3A7759401FF98BCF85EDECBEF +:10C52000070FE5A21D42B8AA1DCAA80D79817FE2B6 +:10C530003D24CF584CD741BA84F686D035B6CFA12A +:10C540004353F1B9A4B1B337E87FE0BC01AE0BEDC2 +:10C550009F5EABAF1FAF3DB52711F5D1F9EE833E1E +:10C56000BFD8A83FE7D15547B538D51B5D8A1F76A0 +:10C5700000EA61BDEA4A133642F9D187D2416E7FA3 +:10C580004F5C1CECBB8FF48BF0DB0E349E4AAD2865 +:10C590006078037D32B78907B5FE6CA64CF9552348 +:10C5A000077B037C6537E611FCE92B34F14FABC9FF +:10C5B0009F4E8597FCF6A9D717817E00BB0C7AFAAF +:10C5C0002357981D1FB1DF57997E54FD064159AF7F +:10C5D000CF95FC2E04722F833D02FBE4F19372DAB7 +:10C5E0003F658681033B448AF5EF9D02C3CBED0A8C +:10C5F00072504E76FA5E06F9E1939E21C0477FE8BD +:10C60000374BC06F7B8FAD2D04FF790B8997ACF44E +:10C61000BDFB871705C0A3D5302810AACF86F66FBB +:10C620005BCC537FA75550F4243838741D5B5315E9 +:10C63000BD20FFB1A302FC0D837F08B67AD5F65D5D +:10C6400036FFA350A67F5E0BB5DFFBADAA9E0D742F +:10C6500078298FED37B1F2D0FE2D1D329669FB623D +:10C66000566E4987FD296FBA81D22BBEA9AEE3541D +:10C670001694D5F6751D72265D4BC59E12873F1721 +:10C68000F4DE4859A4E5384D9967656261CFBDC7AE +:10C69000FE4B807DD3D6D4E1931940CF1F737DA08C +:10C6A0005FEB8E3F7B14CAF53544823C9CFBC8414E +:10C6B0005C87678D6543CE1490E353223AE4F0A77C +:10C6C000AE0BF54727BB08E68D852017CC033FADA1 +:10C6D000A8D3807EDA76EA5B1703BDDB53619DE762 +:10C6E000A4323F637290C2D1C8C1649E86EFD3C0AA +:10C6F0005C998607B57115F118005F2439FEE7DCF7 +:10C70000E210C5A777966C9B42C7DBBC81F7344922 +:10C71000607F824DE08F91231CDA89DC53E93BBEB8 +:10C7200041CB57FB92BB21AE30ED607CB039B72FC7 +:10C73000751A7DB65A997EDD9CA89413F5E516C549 +:10C740006F7425CA8949F47DFD9127B3658AC7D0E6 +:10C75000A199182FD6ABF8C87B1783BD1C3A3A3B7A +:10C76000610E9D6FDDCF59FEB2AEBF7831CCBF6E8A +:10C770008F8140BC56DF4FF9492B1F540EBD93E803 +:10C780003CBC9D5378CA1F8B52739758E9FA3E9B65 +:10C79000E715815E1BBAA6ECB6D020E859419C0C87 +:10C7A000F2B2A1CBB31BF869F38C4BC88F96CF794B +:10C7B0007E569944E3AF7B2B17835A4B3530B9A48F +:10C7C0000C877ACE98B80DE9FF9F6564D89C88E401 +:10C7D000C4FDCC1CF83F8ADF24D15B0EEDC5A53427 +:10C7E000F4013E157CC7C00F91CB2D980F2D1797E4 +:10C7F000627DF61A62E8A0F81C9492929A68576BD0 +:10C80000BED7007E4A9ECF86794E635CC50E909B54 +:10C8100043675939BC4EBFC275B21506FB2C14CE06 +:10C8200044072F42CC916AF45A60DDA82C0F1C2AD1 +:10C8300001792168BFE5CF16615EA72B9ED43C4FDE +:10C84000E9D463D8D8F113DAAE27C949C0AF6CE593 +:10C85000B8F52BF07DF994AD146E8FB27EC6448F7F +:10C8600008EBD593A82FEFE7363E0C72B4E5732F93 +:10C870002C86F9A59ABD9DC914BFFACFBDD0E19A07 +:10C880008D74CEB350BAD4A7BCD061A174EF69F255 +:10C89000BA454D79D29FA9B6C679BC8072CA277EA7 +:10C8A000F61190635AFF530BE5DF6793547F80D5F1 +:10C8B000E7E7A9651ABF521D6F6C1A29CB16AAFFAC +:10C8C000F335ED2BA8DC7EEDCB46A2C20FD1B26DC5 +:10C8D000769FC566C479101BF8335379F4676C8969 +:10C8E0006C5D6D93F3D04FEAB1327A0D6719B07E6B +:10C8F000A1F13911F200E6C9BCC18CF173C0672AFD +:10C90000817D579EB0BCEE01EF6409D2A36C1F90ED +:10C91000EB5C8E71A0B550B3EF47205ED5EF13F2FC +:10C9200011E502F360BA81DA61E7F9E55C36855713 +:10C930009BA2C4854E920E79D7400AD3338FF9E477 +:10C940003B4D12F0D8203B9F4A7CD3E099B62E3F56 +:10C950006DAC7385A3F7FF43E897ED711814BA49DE +:10C96000BB43D4476D763C2F821EA1667EC701F083 +:10C97000279D3CF24D01C83F2D6F4B64F9F6DCDE7C +:10C98000C54FCF02FFF0748101E49F173D229CA7A1 +:10C990002B8B2B4900BF8D1FE1D357507E8D4767EE +:10C9A000DF0DF19E00F24BDF1EB0B273A0C3E9A40D +:10C9B0000FF2BFBCCB4BB4FB81AAFCEE6CB4E073AE +:10C9C0006FC98A6FC03EC1D7DB09EE07082E1F96DC +:10C9D000A516C2815C1C2FBD17C7FD2AEF4B580757 +:10C9E000FAF62CF3EB815D309F117A8A837CC67B4B +:10C9F000165F02CC7B5FA2DE9EDE96CAE2613985BD +:10CA0000E9CF3625DF295CBB05F337AD26551F5925 +:10CA100096807F2AF07E3C2F6BF66FF382BEB210B9 +:10CA2000591635F9704BA63EAF255CBB15E1C829F8 +:10CA30006C9CC873050E4E854FD7610C7F597D469F +:10CA40009E4368203ED44764809D6FD8B66B7E5A63 +:10CA50009206CE36CE9B268EC11F5BAE194950730F +:10CA60001E650B3F2CC07CB65C13F03D710DC637C4 +:10CA7000C1FE0B65B80E58C717BF8B76C9463A433F +:10CA80007060CA0CF908CDF94FE2E28747F83F2FF2 +:10CA90002C1FB87FCE45910F495F8EDC370F808DFC +:10CAA000A57EC50EFB6F0498E7BBF3C930F89384ED +:10CAB0000C2E04F9AD9B6FC37CF416D269B1401EF5 +:10CAC00085EF14B579E1BAFE8BF1708E8E2EA90434 +:10CAD000FECD961F96E9F251EA3930B55C7F6403CA +:10CAE000E609B7F45C15A694201A03261A8FD559C7 +:10CAF0003A4F99F3C2EDAD26BF9C01FCFFC347BD81 +:10CB000019F4D5D7004F383FD5306126C47F7F1048 +:10CB10006BD2814E765EB11F6B2C683F5AAC345E8F +:10CB2000033EBD3009ED29ADE6C13EABE32F56E231 +:10CB3000E221F02F6640D73EF4D35B6DBE2B609FA1 +:10CB400080B179EAEFB426A97CB3AD03E4A74B0822 +:10CB5000EB45F09FBA6CAC6CEFDAD6D1C2EC30F397 +:10CB60006F9CDC6EF06F5A157F6968FF75F48FBAA1 +:10CB7000844EE6FF7DDF2C019E5D369F07E2417902 +:10CB8000C76409EC49459A03E7617AC1DC0DFA30C4 +:10CB9000D9E9BF047E0B7132FFE8DD94F3D9200F91 +:10CBA00051E00C733703C7A587639DCBC67F9733CE +:10CBB000FA769484DBD1FE21DCFFBFCF82791EB5EB +:10CBC000FD01935EAED5675E2AA327E813906BF54F +:10CBD000BDE0DF84F26B2601945FB34BBF2FA4CA84 +:10CBE000B3706DB22E4FF9B514B63FA5EA01E15A04 +:10CBF00011D6CB0A9FEE84FDF231C7498A31CE743B +:10CC0000D413B1C72955F40851F2BB3C9E2753E514 +:10CC100024B6BED0E76B23F59FFA54F5DF17143E18 +:10CC20003E6DF5CF4BA5E33C12EC5B68C3DEFE5BCB +:10CC3000617DFEA4F06561EF93C780FD2E8BDE4F12 +:10CC4000A5CC807353DE6FA4A4BC7FB9D990CAE68B +:10CC5000335A8FB1FCC3B68725B4CF5FE53D364F5D +:10CC6000143D5673CDAED35F19296C9C1A5E463DB8 +:10CC700056732D1EEB3F387C2B094E1F0BBE03EB6A +:10CC800047E0F731F8C74B7FDA350BE01F3619CC98 +:10CC90009A786EDBE105699097DC66A57AD9A19355 +:10CCA0005B2FC82D9F4B46E22090F37D23F5F37751 +:10CCB000837FF3AC56CE6781FF15EECFD375DEA729 +:10CCC000C83D9197446F6F8F683FE25F5561FB48A5 +:10CCD0007C543D0265F0B7F83F9B55FC500F3D6911 +:10CCE0008880A7FA637235C2DB3C83F919969407F2 +:10CCF0007F26E703FF05CB200E1A7E9848DD6434BB +:10CD0000DD2D0A1FD65C9BA05BD730BD27EADEFF76 +:10CD100047A38B0435F2F651FFB6856897619D00F5 +:10CD20000E917762BF031924A891BBFFC3E383E28E +:10CD30003127061EF3FECE78E4EAE4328C47BEEEDD +:10CD4000FD07C5C368B9E6BEAC299B4492A12D1767 +:10CD5000872C1997357ECBF453A2AE3C63C0A56BEC +:10CD60003FF39CA4AB9F3D58A8AB9F73C5A32BDF9B +:10CD70003E3C4BD7FE8E6B5E5DB98C2CD2B59F6F5F +:10CD800059AE2B2F10D7EADA4F54F2E477BA36E8CF +:10CD9000DA2D921ED6B5131A92BF03FECB1DD7EF24 +:10CDA000B0407CB1D361A8847D879DBCDF921445DF +:10CDB0003FDEA6C01DB177AE54ECBF400CB4803E40 +:10CDC0005C4043E166EAAFA555FB5AC0EE578A2C9A +:10CDD0008FA8E6CFC9F59515F0FEEE4544EC480C5A +:10CDE00097EFFC14215036677AF1FC9AB5C880E7BA +:10CDF000037617AD1873FF619FE2BFEF89B0F7EAC2 +:10CE000033C1C8CE4946BE2F48637EC29377EC2318 +:10CE1000B04F607104F17B9EA39377BAA0FCF41D20 +:10CE2000DF76419CD13EF9132EE09FB6ACAFE9CE40 +:10CE3000DFD9F2097EDF110977BF0237FFDA631607 +:10CE4000B09FBB33193D23DBA9E7D0775B58DEFCED +:10CE50006F35CFF234263F1FF63C2F2870775B8268 +:10CE600098FFEF28FCDBE05F3D82FFE384E1FB38C5 +:10CE70009E376ECF1224AD9D559FF07D28CCA72DF7 +:10CE800077A70BEC6E7BEE2774FEBF399FEDAB45A9 +:10CE9000F6E35C6CDD768B7FDBF93CF657CF67679A +:10CEA000D4FD754B8C7915A8F3720591CFFE56F31E +:10CEB000FAEC883CFD7DE6F5A2325E7C1AF34F77F2 +:10CEC0004B4C8E128CBE5FE6E5C696BF8459FAF3D2 +:10CED00048711E7D1C9097EF1BF39CD139853EB1A4 +:10CEE000E4758D494E013C5E6B64E769CF021DE934 +:10CEF000F39C7F42397C97F01A9CCBE2A0FF8EB85E +:10CF0000B1D661ADDFA8C3733CFD30258D9DA75C14 +:10CF1000BD46DF6F95CFAE3F17A59C27A0747A0260 +:10CF2000F2CB2ADD46ADF38744A758FC76B374EA0A +:10CF3000287C7F741A8FBFE3D398FD1A8F4E2A1F67 +:10CF4000C582F3FF2B1F95037D6E828F54FEF95B24 +:10CF5000D3E71F8D7FAAFF8F3E63D2E7B19BA48FDB +:10CF6000AA877A055213ED1C48934B40399DC4059E +:10CF7000CE2C8238FB2E239E773873A0A78EE469CF +:10CF8000DB317B7AA6F2AB7578EEAEC68EE7BDDEFE +:10CF90003078FEA504F2528F1831EF1609FF8C424B +:10CFA000BF4DAE44E5BC8E9402F47EA366E598F3D3 +:10CFB00023959A79E1BE9A2D5C3652B84442FACA5A +:10CFC00094BE90173853393D2E9A5D53D72FD6789B +:10CFD00037BB7E6FD434BFAFF51B6F7E2B5D7937C7 +:10CFE000A51FE1C43ACB4BB17301BD8F33FFBDD751 +:10CFF00040D793C2BF0FF2DCB3210E2098FF5BBD78 +:10D0000026ED20E0FB2F2E76FEA25F90EAF01E9028 +:10D01000954B77C3B988B3AB1239486DA8787C4576 +:10D0200059D7D2EAE8FEE7734A7DB83F472645590B +:10D03000E72F2AFECFAA6A0EFD08C27BB3B4F77CA5 +:10D04000FC73447D64FFEFBBE2B1FE6C8CF3975F31 +:10D0500057FAAFAE1ABB3FA94D510E618853B5DFE9 +:10D060009F8FF095220F8B5DFE3E176DFF1AE7FF35 +:10D07000D2C7818F263B90EF094F7261FF7F040E6C +:10D08000EFC5731B97EB18DD23E16AE0BD3416BCD6 +:10D0900058F455E7A58E57427C18DF914A223E315D +:10D0A0001BC737C279B6BBE793008ECF4B884FF2D0 +:10D0B0009B34AECB0DF3C7798358871FCE2870FA07 +:10D0C000FF7BFE1280D37FC620EEC88D8D772CBDEE +:10D0D000F0A6C23F4EA37F079C2F20EBB9A8F27D9C +:10D0E000CE65C576BB5CCC3F24BC3F0BC699B8DF90 +:10D0F0006F9228DC7B94F36784F8B3966BC6DFA548 +:10D10000CC3BB29FD3C8F6C9C9EB4C0FF5763F9222 +:10D11000154D8E5E51FCE65DAE42DD39DF2ADFA3A0 +:10D1200026D003554B979B2407D44B8CEF143C7AA5 +:10D13000057F56B1234CA798FA47A14FFF397F339B +:10D140009CFB59DFC0E139E3A2ED8CFFD66F3F6A4B +:10D15000A8A3CF838A1C2E57E450ED6F4F6772D37C +:10D16000DB6DCB06FC7BB5E730281EF73F43307FF5 +:10D170006748FFE21E99276490234ABEEFC65DB060 +:10D18000EF30A8EC8FE5D0FA26C0B782E1BB7EFB7A +:10D19000728CF72756B278BF5F20781EE8CDDBE3AC +:10D1A000823B0086C57BF4315ABEF4E704D2E10924 +:10D1B000F3C75342682AF0474AB3EFE3BE28EBEDCA +:10D1C00056F0FD8383EDE7C5A28BAACFD5762B78E9 +:10D1D000C914ADFDCA4ABD5E53F14F3687DE2551F5 +:10D1E000F2EA23FC181CDBEEBDAAE8E95722E2A60E +:10D1F000AA73D1E397D274C6C7BDC1F2CD78BE5928 +:10D20000364B789658C1C729AF467ADE5842442833 +:10D21000DF6D96BE0CF8DD53658CD0C34184B37EC0 +:10D22000A95D37AFA7BA7F3A15BE43CACB67FAF7F5 +:10D23000BD42079E0B7F880404D85FAA26F23C9467 +:10D240004B229980BFCF2AF453F13B4BBC71334042 +:10D250005F3444B79FBE742627677DF357A1DD6D09 +:10D2600031E2B9848B55C9CB200F2EFB4C1E38E61A +:10D2700074B16565DC839A7555ED9EEADF9CF3CF4A +:10D280001FD37EADF2E9D7AB57E8C47D40B99C040B +:10D290000E513E9BF4A5CB7B67D2F299A001EF190A +:10D2A000C23F2C67A8E7E0099F4AD75DA91A320C54 +:10D2B000627BF90B6C5EEBAA830B606BECBE673A8A +:10D2C000F7CDA4E587D2993FB0C33EEF7690D75F04 +:10D2D000358C632F23F869E27E9BAE5C7A8E08D092 +:10D2E000DFBF2DBA7DF88F0CBB72AEC8930DEBB0CB +:10D2F0006E7BF476F64C07DB27FC8BB1265AFCBD1F +:10D300003B83C9C9FA1A2EAA3EDF9D11C7EA6BA357 +:10D31000C3BFDBADE22166C3BAAC8F81EF1237B376 +:10D32000676FB5AE5E07FAE08A41AFA7E7BA195F4B +:10D33000B8DD6CFF7BA8FBA5D654E0879D9C08E771 +:10D34000C92E257A2603FF6D68B988F17EA2D2DE48 +:10D3500098E6DB974EDBDF7BEEF913D0BEBF9A7801 +:10D360003829B61DE84A57ED80FA1DB46A0F3BAD67 +:10D37000608FE07F619F15B6FA139260DDE547F09C +:10D380007C4CB74D64DF3D796668FDEB1E45CF0CE4 +:10D39000F5BCBFF5BEAF46EF1745FA7F4382B4B781 +:10D3A000848E3B44F9AD89CE875C7FEA56ADBD5192 +:10D3B000E521D6B837EB070EF5BC3F3F70BC799E30 +:10D3C0004ACFBD293FF0BDCAA7F6954830CFCE5B06 +:10D3D000A3E95B552FBFA1E8C5487E19D1378A3E26 +:10D3E000B9121C1BAF8F3EA3C7675D408F8F2A1FEA +:10D3F0005782CD36B8478B8E3E15D659F54B49C569 +:10D400008C9BBA1F24169E57143C7FD560E451EFC5 +:10D41000F57098A7FE55C353F1D1FCFCC8F90F195C +:10D42000283F007F7C9947FD5350B3E158AA14E68A +:10D43000C7F714F87F2D1FAAFA55B52791FDFF51A4 +:10D44000F94EB567E3F19D33461E7277BA05FB6F5F +:10D45000E04501F69176A74BAC4CC4852EF05F6792 +:10D46000B1F3EFD4EE65C33D1243DD36FCFE4BEE67 +:10D4700030070BE83A5EE99E3359BB8ED3DC8A5EF7 +:10D48000AD4DDC095BD7570C9E4569B07E2BD87D2E +:10D490001E67CF252D4CA3FD9F1A30C08D5864DD2B +:10D4A000B60D4698DF6DEE446697B79F46BFEFFD19 +:10D4B000F2F5FA80DE9E3F9DAE9E3F657EF8DDD49C +:10D4C0002F80F384B1E890E3B660FBFB6A0EA33EC5 +:10D4D0007D603B87FA54724BF8FE013E887A99B41E +:10D4E00030FF9958283DA85EBA0893007A7C8E6375 +:10D4F000E7BC799FA0BD6FE3C13DAB17C0F9CB4836 +:10D50000F9F88EA2C73FEF3628FADCBFC88DF1A12B +:10D510008F0378973EC9F05DBFFD513CA7FC7ABAF6 +:10D52000E25F2BF2F9BAB24EEAFC9295F99DB70D83 +:10D530006F037B41E5C680E74C5E33225E435FFBB1 +:10D540006600DA89531C18EFA31F4BCBBDCBE282D8 +:10D550004D9ABC9DEAD7E479983C54F15E9D5FF802 +:10D56000903B57E7A747FA1BFF670FD8B3C3FDF7F8 +:10D57000B5075DEE0FC71E04D219BF47DA85113912 +:10D58000DEC9E4F8E2B9DF2D8072A41C7F5D91FF53 +:10D59000BF567EAF74DF8B7C2D2F2662812E3ECA54 +:10D5A0000A421C3CC2FFE1388983736E4F75FF6CE1 +:10D5B0002AE4BB2EEE5DBD2EDAF87B33989FB531A1 +:10D5C0005E32E07D90AF313E8BD41391FD46E42274 +:10D5D000469EB16AC56C8C0FCFAE98930DDFBF45E8 +:10D5E000C607A3DA73DE9455101F3729F1F13E7395 +:10D5F0004D77147C93143F352F7FF804D0FBBD5A30 +:10D600000EBF1F863FAD9F7EEF39CF8F06A5D1F8A5 +:10D610008E94D5F8643B1B2F729CCBEE88F844A601 +:10D62000F109A5F36095311ECEB3AAF1C9A0FCE1C2 +:10D63000C6276F92E17F9909EBDC131D2F3E43E172 +:10D640006BC1BF6F36C56368B1D12383BC18683F17 +:10D650004D5C12D9EF9AC2876F6E7F9FFAE89C3EAD +:10D66000AF1C4BDE46F0FA2BE5AD5718CE02B97F62 +:10D67000F3E0F50B8FC17C0EDAF0BEB1483807330A +:10D680008C4A7C60433950ED6FBFD059FF12EDF7E3 +:10D69000E65D6ECF0EA2910B42E582BE3FFF172AD8 +:10D6A000171ED46F28C7BDDDF69A6871CA0F143EE5 +:10D6B0008BCCDB88DDDF08405CEC251E9336EFF475 +:10D6C000BAB2EEAF2A7A292F83D9CF7BAA960B90D4 +:10D6D0002F7A70245F4430B810A7641E84F8F215C6 +:10D6E000E57B0179631CCA5D241EB729741D2F7F59 +:10D6F000B0A65A1FD7DF53A5D71F6F07F346EC48D4 +:10D70000C118FB522AFFC61AEF66ED476FF0FDED18 +:10D710000B8C37BFBA8CDC9BDA17584502B7639E77 +:10D7200083AE0F3CAB4860EA4B149FB79F59897991 +:10D73000F45709A9443FFEFAC7A66AFD927B95F506 +:10D740007EAFEA637701BBBC2E04A646B33F917956 +:10D750009A5783D1CF67F814BDFABAFA5DC53DC6B2 +:10D76000A8EBBB5959DFD7ABC7969BC8BC4DD55268 +:10D77000FDBC3F95212A709A6D7E1657B371BFC0CC +:10D78000C605BBA5F54B3FF521C9EB20E4EF619C35 +:10D79000ED84403EA55790A768CF5FC565323AE457 +:10D7A000158EBD1FF58A4257B55DA49FF513B7A42A +:10D7B0003B3754B5548FD76746FC4111F320436083 +:10D7C0002F9D617B79B7D9F330F001714858FFBCC8 +:10D7D000B2DEF7D6FCD604F3A7FAB315F2A1F2191C +:10D7E0008308FAB3F45CD0A4A5CB6B3719DFBFA6CE +:10D7F000F80BE3E9D1BCC261D46FEF051DF89DC4FD +:10D800009B9FF993291ADCAA6B19BAF3C4EB7DD15B +:10D81000F32AB60CB6DF158BCEB60C49E7A7AEBF20 +:10D82000968DE78363F9FF9FCD6071D07D35075BEF +:10D83000B5FEFF530A9C07547DC633BF3F56FEF525 +:10D84000A71937977F55EDB3DA2E72FDD567A4BDC2 +:10D850001C54E439B2DDBF65DC1CDF8DF83131F8D2 +:10D860002ED6B86AFCA1E67DF38A68FF28FB32A3B6 +:10D87000C651DA458EF3AF197AFE1E1547C4C8DBD0 +:10D880005933991CFB63E4EDAC9971587F8630BB2A +:10D890002807ED68C7AEF43CB00FDCBD87167DFCF1 +:10D8A0002498B78F2AF99AEA9AD327204E55E38A0B +:10D8B000B03FEE6F867DB2A11D1CFA1B91E344FAC6 +:10D8C000E51F853D269047257F5068F4629E9A7C2F +:10D8D0009A9DF37736AC46FF52CD4FF70ABE1D71C5 +:10D8E000F4FDC4EDBFDD06F6558DE32F993C0FB373 +:10D8F0003C33F377CF773BF07BD7DA1179F760BE13 +:10D900007144FE95FCE378EB31A26F62ACC778FA04 +:10D9100026565E447D8EECB308E28C97E17C2A1794 +:10D92000EF817B99979B09E67D962FE130CE5C6E67 +:10D93000F6E27ED6E9330603947317E7EE067F63BB +:10D94000C552A3D74A51F83700359BAAF257AA0B04 +:10D9500000CE5374C210C7F6BF21BE07CF5717C4FD +:10D9600049E0FF9F9E27353969F9F4624EDC41FB9F +:10D97000BDBCF401E3545A7E8586CF70EF8CBD8127 +:10D9800028DF7FDCB26C7E3E21DF00B89AEF3F5E7D +:10D99000216AFD3DFB2A281F4D49E937382849BF38 +:10D9A00075E09E7D160ABFB5C9E782EFF2EECFBCE7 +:10D9B000751F7C0F999AEA1DB883FA519D999E654F +:10D9C000F09D5EFF175478C5FBE03BBC1F18FCB907 +:10D9D0001CAD7F2173D1321EF62326A8F0ABB17E99 +:10D9E000D5C2750FF6D3FA0B07EA97C119F6D26ABA +:10D9F000A5BFFCB165F3794AEFB96AFB8678283B8D +:10DA0000ED24BCCF348B1053F83B3F3CF7DE3F7224 +:10DA10008E7CFBB20ADAF7D5B2C07CF89ED3F3A5B0 +:10DA20001DFB8AAC84CCAC2C13BD743EA5595F5849 +:10DA300066877521941F69FD47B20E2C83F9388DD6 +:10DA40000605FE9710BFD26A790AD47372705F65BB +:10DA5000227C97307812D8724B43A72555F77D4228 +:10DA6000C00BAE8970A42C9481E828FBDA99A1A997 +:10DA7000ECBB3BA55CC8F2142365172BF7EF88FEBF +:10DA80007DC57F6531FDD56F8B5EDF91A9DFDF4EF0 +:10DA90003847BCCF4591FF8F29797F559E4E403E38 +:10DAA000C48957CC059A601FD6C2F08CB58FDBAE07 +:10DAB000E897FCA604BC976869C08EF7E84CF03084 +:10DAC0007D43A5885F09FADF68403C538C1CDE6B00 +:10DAD000926A23FEC3F49992CCEE39594AE517EEC7 +:10DAE0001F5930C1D783E77CD3D28B9BE19C5DD398 +:10DAF0002F79F0C3D4FEA3F1141F053C538C2B8A5D +:10DB00001F2DD2D0AF88E14DD75DE9E7FDE61D209E +:10DB1000170353F2C0AFBE3D536FEF4A07CA4DB073 +:10DB20003FF9AB2C250F26B1FE29F3995E197E54DF +:10DB3000B9B7C2E229D6E5F5153ACF6F5BFA34B42E +:10DB4000AB1D3011388FB8ED7099EE7EF5C8672D9A +:10DB50009C7BD7D8ED5A3E84E7CD6BE1DCFB74802B +:10DB6000F77301CE39021C880FE0FB0EF09B529A2E +:10DB7000A3AFB79A57AEBD9648E4E9DAF78C5E6179 +:10DB8000F84EAC1F6F5E6178FAEFF946C353BEEBF7 +:10DB900053E9CE2B7417A2E3F933952F29BDB5BFF6 +:10DBA000AB52554D94F313EC1EDFF3CB8ABAB5F7A5 +:10DBB0001610B2839DEBE0E93A823F3960C3FB80E7 +:10DBC0004B79AA1F9D002F4994B9D17CA1AE6B7FE0 +:10DBD0005200EF231ABE8B13BBA3F8D967143E2E55 +:10DBE0005DCAF836ADDA6FDCA0E17795FFC3F007C8 +:10DBF0003EA3CAC73A94DBBD0C3FF037800F3DA16E +:10DC0000A9DA73202AFE659904E74FD791D1FF2E38 +:10DC100047B09B0BD36D34FD33C659CF6CAC2F1D71 +:10DC2000382600BFD5C690D3B359F1386EDAB95053 +:10DC30003C9C0F58A0F07F7FDF74EB1C908BA506F7 +:10DC4000C2496CDEE06796CE55F5E73BBF28A7F6E4 +:10DC5000206DA44CF5AB04EB30A26F43164BB8FD1E +:10DC6000C9AC7796B5803E36B3EFBCA9FF68219A60 +:10DC7000EF11B92C96BF9DE58FBE6FFD4616F34799 +:10DC8000547A7FBE613E798BCEEFAE4C66BF670D96 +:10DC9000CA785F922AD7917A29278BAD634616E31B +:10DCA000B3BFBD5EE2C6D14BCB15BDC4EA89D35725 +:10DCB0000BF5A906E5FB0491ADFBC69F4C2F803CFC +:10DCC000DC56975182EF1D56729EAC6FD171AA2C13 +:10DCD000526B9C14E68F2A62911C406F3A027CFFC3 +:10DCE000BA62A915CBF0077EC7EF3A39C67F444A1E +:10DCF000A81AC3AF55F1D9EA1270BC8DBB0A12FC49 +:10DD00005A3C79DF7398DFB32B785A22EC15AF2F8A +:10DD1000A7A686EA0C464DBD83D9AF1697774E1657 +:10DD20002D9F56F242A43659E717AD52E42ED22F5A +:10DD3000FAAD8B287A6205C68F69347E847B02D265 +:10DD4000FA7C781E0C2E322AC0EF76D97DC6970E4B +:10DD500093B91027A9707C59453AFD5EBD1A364D1E +:10DD6000A8705AE67B2F6BF4D929E53E7ACA0F33A7 +:10DD7000405E9767117D3FA32F13BE2F2769660F63 +:10DD8000E89B1382EF00AEAF4812617D17181F3D6C +:10DD9000807C612489CD784EEA20F6AFAC1E2E41FE +:10DDA0003FF5BA310476E797D9E998CF49B133BE48 +:10DDB0003D610D603F9E4849A84714BDF7CBECC9B3 +:10DDC000780F86AA3FC3DFB5A87058FD096E792683 +:10DDD000DC0B7B2265527133A7F777C0FF09FB4B41 +:10DDE000DFDF77673EF8377D218A33D52A2F2E7BF8 +:10DDF0008CB6DF9C25317ECDF5F5C3B82712890896 +:10DE0000F8CF1AF43F07E5452E3BDEDBA6AE47AA66 +:10DE100081FD1E4CAAF27B2B2027F0B4653339EB31 +:10DE2000529E83D96C3D53E3A3FF7ECCB0D26EBF2C +:10DE30008DD1B9A34C7F7F92FADCA9C8719DA5B39F +:10DE4000123EA9D77CEF89DF87F384FA551C7C4FFB +:10DE500042F03DB56748AFF96DD5F8FB61EF0DAC09 +:10DE6000C27B5C477ED703EEABA2EB1E222B9F004A +:10DE7000BA0BAF1AF16EBD56133B772724FA45F85B +:10DE80001E29D91E3DDEFD96824FB291DDCFAD7EBB +:10DE9000C76052BEEBFF8AE28FC5BBAAD83D45944E +:10DEA0008612A55F0219C6EF74D5758C3C976B522C +:10DEB000BEE77FFFFE43710CFFA144E73FA8E346A6 +:10DEC000FA1117E0FE6D4DBE7B9DEBEC02A2697F5F +:10DED0003F196C0578F76FCBD0E52562F91FC715A0 +:10DEE0007D0BFE821C152F41F7FE028D0365EDF8B8 +:10DEF00057D8F8E171ED44D68CDB96E57D390BFD02 +:10DF0000D4B922DE234C7D76380F4BED0EB3D77398 +:10DF1000D9FD84D42E5582FE56E322907B3101E454 +:10DF2000BAECE759291A3BA9F48BD447772AFAE8C7 +:10DF30004EC5DE249C53FD469BC47161BB33DA6E33 +:10DF4000718A1F1DA91F23ED82DEAFA67C2B6BFDFE +:10DF50008051F292F541FDCB0931F863E2DFC5BF94 +:10DF60002C9DEBC7F892547204F6416656E8ED3DDD +:10DF70009FEDC079F1D9769DBD5F51AD6F6751DAE4 +:10DF8000599476E3D1536B8F3823E83D06AF9E63F7 +:10DF9000FC90FBCE19BC4FA9229BF943B7E4781340 +:10DFA000B269FB837F9EDF0BBF3B31DCC4936E27DE +:10DFB000F4F3F60E3A615E1611E2D4B2B515850798 +:10DFC00069BDE9E7260FC4CBE448F4F8DED1C07997 +:10DFD000375196CA54F460AD93CDABD61912F229DD +:10DFE0001EEE5A864F66DF518ED7E8BDCC1AD66E2C +:10DFF00062B649677FA628E5C26C252E21C126F8A6 +:10E00000FD93CC1A2F0FF6CEDDC711E59E4DBC1F38 +:10E01000D5ED61F01D9E20F7405178DEED86E54597 +:10E02000602FDA53ED1EB0175B72FC9E6C90D7F335 +:10E03000A110906DE6F9011EFCBE5D39DE62A0877D +:10E040003A3FC928BA617FDC7E9EE1D719C1FF84BF +:10E05000EC56D6A59BE1E7F015033EA9F112DE4789 +:10E0600044FFF2C0AEA62629762395F8E1DE2062B1 +:10E07000A1EDC00FB2D176DAEF3789AF04F609828D +:10E080002953A7819D5B60F31CB3807D9D963B0D5A +:10E09000EE177AE940F47CFA32C5AE50FC1769F10C +:10E0A0008F251F23F7AB2BED4C31E26895EFED95F3 +:10E0B000D1FD556A09985FBFD6792FCCA7B6452008 +:10E0C000708F844AF75D39BE6AC0C7DD77900379E7 +:10E0D00075F795215FB9659E805FD162CB0EC2BD99 +:10E0E000B12D491F4903FAC7C2BBB6C1E8DDA495EB +:10E0F000E71601D7E360C4F93535CEF87836F3B3C7 +:10E100004339BE5A58E7FA234FE239C1877B2E0ABA +:10E1100063DDEF73B374E36A58FC52BB86DD9B5139 +:10E12000B696473EDCDC22E0BDACB5CF1D0EE17EED +:10E13000F17682FBA0B57D874FC2BDAC19B5DE1963 +:10E14000DADF21C8A865F7C7A5521E192842BD29E4 +:10E1500080DD76F72DAF45BE168948908FFCE877B5 +:10E16000655A983FAAD2F7A410CA7E99B63B692097 +:10E170009E665A7FD52417C24F345DCDB579E01E17 +:10E18000867F3EFCBAF469A033E4C55CB01EFE276E +:10E19000811E1D4DEC3C79C702EAF7D0760BEC648A +:10E1A0002B9417343B08C8C7CDD26166045FCCDC22 +:10E1B000CEE4E4B8A25FE81FDEABF4CD6C16D7A4C2 +:10E1C0001AFCD5E8BFD279B4CD46BC701EB66C6FD0 +:10E1D00010F02262128EEBAE0D71DAEF50D4679818 +:10E1E000AFBC5FCB4E793F78F6E13EE36645CF9416 +:10E1F000ADEDE1DED2F0C1F7B2D97EA9FBB9831C47 +:10E20000C487B4BE698113DB637ED0FD1C8B9B3653 +:10E21000D3FA07757A6503CEA7DDC6FC47AA577EF9 +:10E2200008FC7EC2F0E871D82F39318DE07DB377DC +:10E230009D0F9D44F5ACE07B4260EBC9533A34D16D +:10E24000F2A96CE6DF9D14FC9B60DD4FBAD977DE46 +:10E25000ED861D78EFA92AF791727A4AE173F79A51 +:10E260001ECE50847940F42755FCD476B7E494FF51 +:10E270003C1BE9308074A85BC3B37C8382CF02C1AE +:10E28000970F71DA1B0ABC63ABBF6D7C86E25757F0 +:10E29000C4213FEF7FE134F2655D27C77E27A8F3F5 +:10E2A000B4B04A135F757DEF34DA9525FD6CFFA598 +:10E2B000AEFF30FF8003ECCD31E4CF3ACA7FD612F7 +:10E2C000583709E97CD514CA067B19C99FF64AA6B6 +:10E2D0001721E75AC0EE83C3FDDFE05A0BFAFDAA0F +:10E2E000FEB5652BBF5BE9F0E7827E7D5729ABF079 +:10E2F000C3F1AAD503FC9DFBCEB46370BF5B9D87C1 +:10E30000F3C079E4E1117BC2F4B544D915F4B50A40 +:10E310003F927EAE1C66CFA2D891FF8A6647543BDF +:10E320009BFBE572FCDD3775FD7885EE23F63D87B6 +:10E33000ED4B597278051FAF0BF2D81295E78E128C +:10E34000B8DFCF57043FA1D69262F7407EE79F1314 +:10E350005F933668E87552A0F24ECB27F36C880FB6 +:10E36000950B6B8E66FD6A8BD8EF4AEDFFEE72A4BB +:10E370006B2DAC1DA56BAD7FD326A4B38B888740D6 +:10E38000BFF899FEAA5D730FBB075CB57FCF7348DA +:10E39000FF5AD981F75A2FE95B8EFC499C564F01F1 +:10E3A000877A0DD7599533DB085DD9FD4334AE6FBD +:10E3B000827C891AD7C757FBE43869B49C262B7135 +:10E3C000FD0C25AE37CDB27CA871FDE6869F61FCC1 +:10E3D000F388EB27F854E584C68D3A799AA1ACB35B +:10E3E0003B87D9D3B9394C2E3797F421FF6FBE1C28 +:10E3F00040F97154323DE238AFD77F6A1E8C903DB0 +:10E400008C0FED7D0B611F62C1573811F4402CBC9D +:10E410003FCA057E01E755C861768EE28EEBBF8C60 +:10E42000D7DE47BA3487F1F7D55E230901BDF980FD +:10E430003096FF1B0B5E56A862F6BFD3F5FB756FD7 +:10E44000029E0BBAFADCCA4F4259EE49C0732459F6 +:10E45000A12AE48BABCED91EE0036733A3D3D5BE8C +:10E46000F9C83FEFA44906B82FACA9EFA979F0FB92 +:10E47000D01B15BCDEF9AEB101E8B0E3EBDF9907C4 +:10E48000F74B6E0E72C9F0BDD9D5DEAFFC05EC5E60 +:10E490004DCF163CF7D5FCCD7F42BFDB103CC8DE2C +:10E4A000F72688D06EE8AB4FCE03FA36F73563FD1A +:10E4B0003B5F3D88E5635FFF8EF19992301FBFF3AC +:10E4C000DD833FFE6F28FBE2F1BB9C5AFFFEC7A134 +:10E4D0004CAAE2D97757FE9705EDEF75751D3E8A78 +:10E4E00072A8F2C5923E4EB93F4CC0731E2AFF5E21 +:10E4F0002A2F2A05B9831B768DF368B923AE265AD5 +:10E500001E71A732DF5AE04518770D1704396817D6 +:10E51000E45ED4E7625F36E8737B5148807B5756F0 +:10E52000571F9EC77E76B009EB575AD879B1A954C8 +:10E530005EE01E290AADE706F56B56B63FBC0EE05D +:10E540001D3012D1981EC6B75E90303EAA5FC179C9 +:10E55000A884118E6C3B9102FB5F0D4439D7C5DA5C +:10E56000B5D3F0D29284768858E9B3745BF43CE872 +:10E57000BE1C87229F4C5EDDFDCB33417F10A7D9A7 +:10E5800053901B8697752ED001D7F9BB6B0616C228 +:10E590003C16176E980EF37042BE0FEC8BEC40F8F1 +:10E5A00075909FA4F21454E42655F4E17D2316AF30 +:10E5B0002F057E834D32FB703F4F5AEF3335819EDE +:10E5C000E187B357A1213CA4CB7B7599FCE93300CB +:10E5D0005EBB629F7A18FEB43FC293E67B9DD09FDC +:10E5E000C24778966A2F8FBFF16661EBF09F3FBA02 +:10E5F000F3903E5F1E1C05BFC401F6455E83EB260B +:10E600000938DF77A029D25BBE559BC78ECCF78037 +:10E610003E83FDDE504ED90F7266849F6A1E28929B +:10E62000CE7F817AD01F92179FA437F9A67E0F5014 +:10E63000D5DBF57B14BBFB838BA877EAFD3CB3BB32 +:10E64000FECB68777FDDE8256F51C7B2EBC58BC87D +:10E65000DF0F1C6176B7FE48B100FCACDE8B5C5F5F +:10E660007E15EDAF6C24C8D7F542DF4917C0EF2007 +:10E6700089D4B327F5F3062782FEFBCD8BD635D0A0 +:10E68000FF84C180FC76A2FB9683CD9C163F1607C3 +:10E6900070354194C77AC52F285BBBE94988C7EA22 +:10E6A0006A08C685F5FD8A7CD1780CE85B7FE43486 +:10E6B000F28FEAF7E67E7905F25B22E537FC9D846E +:10E6C0008A01C48FFE790AE833B182DD8FBBB8B00E +:10E6D000B814F8EDD8EA1FEF04BB5D5F414480DF5A +:10E6E00095E57D11EF017E91C37B29BB4C9DE5F043 +:10E6F0009D64D7024904F9A8F7578DD8273C5FEDF0 +:10E70000AFEA47F971AEF380FFD0D1E447BFBA2337 +:10E71000DD8E7E41D78B4D683FEB259B077EBF6426 +:10E72000C9116E2BF6971D84E1CFA19FBF24380736 +:10E73000CF6DA9F458523198CDF405C3FB37A681AB +:10E74000FB61DEBFF99E19EEFE1EE1BFC48AC00167 +:10E75000B8AF768938CD03F76B26F1037EF077A842 +:10E7600009F634C1FEB0C967F640DCBD97C37DA889 +:10E77000FF076B233BDE0080000000001F8B0800BA +:10E7800000000000000BDD7D0B7854D5D5E83E730A +:10E79000CE3C924C26274F1208F14C123040124EBC +:10E7A00020BC114F88416CA90ECA2354C4E11D201E +:10E7B000242362C55F6F33381023BFD71BAB156AA4 +:10E7C000A91DF0516A45A38D354AE01F10107BD575 +:10E7D000466B11FDD18E4A798964E451E957AA77D5 +:10E7E000ADB5CF49E64C263C5A7B3FBF1F3FD9EC25 +:10E7F000B3DF6BAFF75E7B4FEA64A6058B192B780E +:10E8000040D0824EC6EC8AC05826A6163DB5313699 +:10E8100082C19F669ECAFE524F09635F3468ECB3A3 +:10E82000018CFE28598C2DA37F30B67C41C8A640B0 +:10E830007FB5CFF2FE32EC5AD9ED907E837FAE8663 +:10E840007C25BBD503E599A270EB544A2D941AE5BB +:10E85000465AACCFC3FDF8BC87AA3218FB5E0D53F5 +:10E86000136088BE45F01DF2CCC78203DC90AFF187 +:10E87000E42A589EB15815219F99CE7E88E591D5FE +:10E8800036B659E8D9AF8AEB1A81F53CE502D4CB0C +:10E89000EC93AC067028B1C29280EDCA0475B382C5 +:10E8A000F91B9F64E590CFCC51B11FC6823A1C3C46 +:10E8B000E516A877342B595D87DF837F906E047847 +:10E8C0008C5764A3BC0CDB292EC6D69575B7AB2A32 +:10E8D000F0507F557D12D400CC734AB3BF94E573DA +:10E8E00038789CDD7008AE4EAC0E46C16324C20180 +:10E8F000DA0707B1EA966284BFA716FBC9B2A8E996 +:10E90000EB5221EFF497DE948CE304085E57E03C71 +:10E9100020AD82F5F9B0DF02CF4A824766B21A0F06 +:10E920001EA12B383C76CD7C4EDC00F5EA8A85A012 +:10E930001DE6F7C8B6A965B8CEBA694E9541BECEF8 +:10E940002BCDC37199DFC19E823CF32E78A80AF2C9 +:10E9500075351E759D42EB5E80E5B91909EA3A28C6 +:10E960007FF41541C37C9DDF194C80FCF7DB383EFA +:10E97000D4B5BD20CD873409F1CE89EDFCA5534B2C +:10E98000BAE7C3D86A9A4FDDC41379BBA1BD5F64EF +:10E99000AA3801F2B6F04015D65F37213C10E17578 +:10E9A000F295846A6CBFC762F1E3387B360FD914E5 +:10E9B000107AF673D2EA69C5F59F84F5FBA1FCF5E0 +:10E9C00057DE0FDE0DF935800A6236ECD16AA502FA +:10E9D000CBD7553119F7C5D8AFBD367F11E2D5DE9B +:10E9E000FC44C20F9CA707E07C1CFF99C358FD158F +:10E9F0009E250ACED3126A94B0DD9674C6C640FE38 +:10EA0000D5FB077A9D3DE10CED695F1C1223FC7577 +:10EA10000493828128BC7238184B1E46A9DF09690D +:10EA2000D22A0E9FD87EEE519C547FB923BC177614 +:10EA30008ED5AF6A7664011E2D4854E87B82D5A737 +:10EA4000F583F9D8DA2A42FDA03C2B0DFEC27DDB0E +:10EA50009C14C47DCBCA62DE17E3F45BA7D39BB1E1 +:10EA60002FCD698CF032CBC5EBFF4CA79B07F47A16 +:10EA70009BF5348A2ECC78EFF4BA914F6425326F2F +:10EA80004B9CF18CF6303F2A37E6C51CD04F06B6BA +:10EA9000532C84DF317417CC2C1986745795A8EE4B +:10EAA00072203D0D730F0BB0EE710031DD53937B7F +:10EAB000E201AE03E907D78574D65BBDE69D9C3FB6 +:10EAC000C5E2E5B33A9D2C425C87793F27003DC6FD +:10EAD000DD67DE4F93C56D7914E6FB9FFBC5E066ED +:10EAE00077CF7A46FA6003D0A09DB1FC8DB3523C3B +:10EAF00025BDD7DB89F5AE84711B1C54DFA92AAB79 +:10EB000025E87FA2C35D26321C4F9988E3F9613C5A +:10EB1000DCE7E409EC4B11E053DAD65C74AF1BF18F +:10EB2000BCA51AD7355192A532E40B1E0B0B1571FB +:10EB3000FEFD0DFCDFA73A91851CDDF91C6F9A29BB +:10EB4000DFAFA6AFA97E7F5FBEA9FC8A55834DE5E6 +:10EB50006EFF3053BEA069ACA9FE80E689A6FC9585 +:10EB60001BBE67AA3F2878A3293F64CB0F4DF54B06 +:10EB70005AE699CA53BE2ED8F533C4735C7F1C3E47 +:10EB800067A4C71537EDCF444934F537B4CDBC7E03 +:10EB900089852D48EF29138E0E8B47CF465ACAA47C +:10EBA0003361A31DF20187627914E6E17A5F0CAE4E +:10EBB0008BB3EF063E1BF994D1E67D30F8C4C5F067 +:10EBC0002BDF7B617C31F0AAB7F294AFC5B87499A2 +:10EBD000E8E67429310FE3EBAF562FB47E6BECFA05 +:10EBE000994278FFAFAE3FDF3BA82D0CFD9CAD16E0 +:10EBF00048BEBC8745637AF6F751CC3A67AC4C21E6 +:10EC00007D86796E8A5BBF7B1EF7D23C6EB1335F27 +:10EC10003C384C7273B93BCFCDE9FD62F4F9893EC3 +:10EC20008F3F1BF4B9C64DF4C8DE138303A0AB7944 +:10EC30004DC2CE3E8017695EA72AAA909742AC2C9F +:10EC40004ACE3FA2D3F7A3D81ED20D0D32F5F3580A +:10EC50004336A51B1B14FAFE784311A5C10695BEC9 +:10EC60006F6E184DE993A08F61FA74C3644AB7348C +:10EC700078A8DE330DD5943EDBE0A5EFC6FEDCA21E +:10EC8000EF0FF3A4933C8B5DCF9C9566FA30F6852D +:10EC900089C5D47E0ED0997801BED6A3BD383BE598 +:10ECA0004278B4EAA0FBF9DD517830DD9D9C7178A3 +:10ECB00008FC63141BF58D78F1F65F3528CFEFB6AD +:10ECC0005E9C2E0C7C61E73F1B10AFDE2D49503659 +:10ECD00016F893FB97CD7E67EFF0E9C6A3187CF595 +:10ECE00000BEC2D75294ED39581EEE1B3DCE9FF4A4 +:10ECF0007D36F2D3A6717C8DEDF7419D0EA7237E64 +:10ED000042F98C187AFD422FFFC2CDF5F4FDBDF01B +:10ED10008B46B745979F7CDFA7033EA2FCBC3769B3 +:10ED2000CE55DE38E3FEDDAD98E873C634F33EEE33 +:10ED3000B772FEB6FF4F6270759CFDBF587B633D96 +:10ED4000B1EDFEA0AFE773C4C911FF73E86DFFAC6E +:10ED500064D2E7F75BBDFD33A3F667FFACA4EA78A6 +:10ED6000FB7EC66DE57456243394EF2C8D69A8079D +:10ED7000C192FC36D4E558A17C18E9048C21A48BFF +:10ED8000DEF15262870D7A12119E09A48F9F9D9623 +:10ED90004CFBCFBCB2C6A2FA67924C7AE9733F0033 +:10EDA0005D01C793603CD043996AE9DEBF7CFC3BC0 +:10EDB000B19B5F8BBDD3DBC5F0C0E02333908F5C8C +:10EDC000405EF76C77797CE4E37F131F31E8989D10 +:10EDD0009F3FC093DCB37C3AF291BE8C3DECDE4F9A +:10EDE0007CE49F869341B7EF73BA8DE527BDB66B80 +:10EDF000CBB888FCD3F9B9E46B0A035EDC2926376B +:10EE0000AF8326F749BE5F62DEEF97D85390DA579B +:10EE10009DEE7B6838755B2451BDC164DFD925DF69 +:10EE2000AFC2640FDA65ACB73EE9C7CF637E157039 +:10EE30004C3BA45F25E40519D80243F2397F121D2B +:10EE4000E7FA1E8A9A9F5566FDA2F3652147BF43E4 +:10EE500051FB367C9F6CCA8FE8C836D51F75403190 +:10EE6000958F091799CAC71D554DF9AB22A34DF5CA +:10EE7000AF3EA799F215EC3A53FD4AC75453BE4A28 +:10EE80009E65AA7F6DF65C53F975CA1253F9D84294 +:10EE90004F493EEA0F36679390C2D812B7569A0F81 +:10EEA00070484CACF3CD453B69B54B6613B076303A +:10EEB00088706BB439E475C0A73E15B43C0678FA87 +:10EEC000B005ACEE02A82F8619A6072D6A19A6F97F +:10EED000DA162FD269E9A04405F1217120631D28BB +:10EEE000A7243581013FB12585DF2D44BADE06FB1D +:10EEF00007A8559A0A8A3EDA013F480BA2FD9B9368 +:10EF0000E8ADC479ADB334BB56E33E5B98E729ACBA +:10EF1000CFD4FB47437AF87A8B05F7B7B5C3F9C06E +:10EF200058C80F85EE19A59FFDE4FBB8DF1DA28A26 +:10EF30006E9F87A7BC3809BFAFBC8E896259EF7836 +:10EF4000F6F98FB83D15FB7D7D3ED7AF322BB99DCD +:10EF5000195B7E875EFEB92D7EF9C27C2E2F2AEFCB +:10EF60009BB21ED767EDB032F45BACCCD4FAB00BD9 +:10EF7000E9ABE70A587078545EF230D989DF07D2DE +:10EF8000F7CAFB66B3B093F7837EAC95095A1FF4BA +:10EF90003B7C3E31FE3C96EBF3B49E4BEAA55F17FB +:10EFA0007DFF3CFFC2EBB49E4B60C1F478ED9DF455 +:10EFB0003D3310BF7DA301A7B4F8E5F7EA70B29E18 +:10EFC000CB61FEF4E8769CEF748F934BE5D673A982 +:10EFD000CC1F771D19F49D656BD988373B81CE9185 +:10EFE0005F54A466D91890F81C16D9A301FCA7A2F7 +:10EFF000490078CA1C6A19F22926592361832E40D8 +:10F000007ECC65D2A7682F580019BF81A9DDBACA86 +:10F01000FA69388A8EA66AE63CC3FA51F2E630F6FF +:10F020000DF34E1C5C9482F87E8A2929721CFC32F6 +:10F03000D2D90ED12345ADE7602F7AD2EF75381DB6 +:10F04000CC890FC7DFE6733D6AE46C16575FFB7D22 +:10F05000BE8BEB81456A9F0BC90D84AF373DBADF8C +:10F06000D87DC8A0F24B8533E005C9F5C80F9C4197 +:10F07000F2537EEBF036F0A79F092F0E1728FC7B8A +:10F08000D7BCF3A83C2FD7F3663EC9156520CAC587 +:10F09000569D7E5B252D699813F918AB8907FF8C67 +:10F0A000025D4F8D59772BD3B2E7A25F43B2AA4FCF +:10F0B00031E487CCF7421CF8C7AEDBA1CF1BDA578F +:10F0C00087B03D73A99CCF318F230BF47CFC172CA8 +:10F0D000A1C2FF8E15FB9FED73A9EB40053AA9CBAA +:10F0E000ABB92C6C453EDC037ECE0C2BFA6D63E194 +:10F0F000E861CA1CA1E0E2F0B438E4ACADB0BE39BE +:10F100007E1743FFCCADB399AB04E6E1FD41DADBFA +:10F110001AD49977FDE0D235980E19DF2852AB6BDF +:10F1200048DF13FCFDC46F865CBABED7E8F2162137 +:10F130005D1C129445B47E01D68F72A6EFF18173E7 +:10F14000A3E0B7B87FC5DE02F47B5999968E7EE2C4 +:10F15000ED76F257B10D8CF4CFFA1D8336A19CE900 +:10F160002CF0EEC67AA3AED1FDB65A64E08DC997F5 +:10F170000F27F86345FAB8189CCEE7733A3FE88A40 +:10F180008F2FE5057C9F2E954E320A381C22008772 +:10F19000CDE5DF3E9D00FC4C7C63B78E7F466AC0A8 +:10F1A0006DD464B35F77B7BE8EDD059C7F7416782F +:10F1B00008CE9DFDBF3C9C8072DF06EB8F83EFD7AE +:10F1C0005DE6FA7BA3936F8B1F1F4C8C3FCF39DF1B +:10F1D0009179BE6ECCB334FE3C6FBFCC79C2FE2CAD +:10F1E00072147CFBF3EC2CD05E2F403994167F9E7A +:10F1F0003FB9CC7902935B14827A3380FF61BD6F93 +:10F200007BBECC3FB70AE5CF4D5EEEF72F014E8BAC +:10F210007C08A6F2E437C351AF55D76E40BEB3C2E7 +:10F22000A5FA65E223AF237E031F641ACC67DA6474 +:10F2300081FC489D23BE5C2421BE67B1502AF2ABFD +:10F240001D76F263C7AEFF67BA9C003AF925C28902 +:10F250004D890C447E7270607C3EF1CBD8FA4D1122 +:10F26000924BEB2AE2EBA5BFD2E975B9A37972966E +:10F2700025FA5C0516282297F569FD50CE96CB6BD2 +:10F28000909FD8401E215C6DFD06F7C1FD80BC47F4 +:10F2900080B422FBCD03828BE07DA20B7EF9DDE3FF +:10F2A0001C6FD827175A7BE7E7CBC41747FAE2ACA5 +:10F2B000E7578AF7D582287B71D99637E4C268BFB1 +:10F2C000380B5B18098E08F9AFBBFC057DD865F9D2 +:10F2D0000B0622AE64A27CF0907C40B9817673E389 +:10F2E000AB63CA707341EF6022F2D3E4449217819A +:10F2F000BE638B9428781EECD21BC45EF4499BE954 +:10F30000FB470D0E3025BBF3B71C7DAF0AF5F8396E +:10F310002CBC16EBCF599984478F5DEBECEAEF9C40 +:10F3200060D26BBBFB97E87B85C31912C188A970BB +:10F33000FE3EEE7EFC4AD13EC1F5FDB8BFF629A6E1 +:10F34000B1F0F3DF373E95FC0708BFAB7BEE7B6F78 +:10F35000FB7C5AD14E607FADFD65C39FA3D2395C63 +:10F36000A2712E2CC9871DDDF0BED47D7910FF015E +:10F37000767D52A1760EFBD758AD0FE733DBA0EFB9 +:10F3800018FD868D4E233F64A3AB63EDCE283ABCB7 +:10F39000D512C9E4723BBC169D4B7FDE9E40FCA398 +:10F3A00073FBEBFDBD748E66E81D49E23749973E5D +:10F3B0003FC3AF604D8CAF471BE717BBACC585A4FF +:10F3C00097E0F9EE68C80BCA02B4272599A90198FD +:10F3D0006FC5B5804DD0DF4431B73D0CEB38CB4E17 +:10F3E000A45D85E0D3FDAA2BDF199180F39C2859F9 +:10F3F0008F47F3A758FF4F5EA1D9FF738ACD4E09FF +:10F40000215C8AB87FA4F4956B52D00FFAF09489EE +:10F410007D30DDD9D0244BD66E3F50ECFC2B7AB139 +:10F42000478714727CEF48D48614C2FA2A7A59BFEF +:10F43000AAD73B94A8A98599DDFD61FD7871106F6D +:10F440005CA9F37B1DAE37F9E792BE6571005F459D +:10F45000FE097AAB28A37FB0D04AF4AE3145CE2264 +:10F460007F21DF7FE0EB12E4AFD2F342D307016CE0 +:10F47000B7F176179D7F33AFC2503E0060E83CA0E5 +:10F4800051F091BFC181F11E90AE13D40D22A4A200 +:10F490002592CEE922C8E3199857C2FCEB42388086 +:10F4A000F1016B1C3FFE25FABFB580C41226405EF9 +:10F4B00062E45FF41F4CA6F3389A19CCC36ECC4BB0 +:10F4C000CF27EBF9CEE993260F80F4CEC4C75D8831 +:10F4D000A76101F828F4F355E28F434437BE44D5C1 +:10F4E000DA17FD4A1F535E5891A80AD9E8777215BA +:10F4F000A19EBA8A25AA7618477396F8715C9BC2BA +:10F50000C80F9FC85A681D4EE7177E048ACC640155 +:10F51000F33989DEF98564A7303A1F3FFC71F26642 +:10F520005C7F827C2A74377C4A671AD54B8F918F17 +:10F5300099CE9502C56D78A418B9E81510FE7DAA7C +:10F5400063BF9BE5A5831D94111F859027FB1BE0DE +:10F550004F1D08B7F26EB87548DC9E33E0E69FE8B1 +:10F56000FB15C2D57FAF5D0E64F4EE6703008D42DC +:10F570007DBC435EB415EB83C1C42CD85F365F9F5E +:10F58000BFC6CEF741F26EC5F61F5AB365B4770C0D +:10F590003C6B1EA8FB217AF1733C58C8F1B02EEDEC +:10F5A000701DCA3906835AF2C05E4A3E3A12F90605 +:10F5B000C8CB26949709568DE06DC8CDE5ADB7311F +:10F5C000A4ABBAB6B90CE9F543C13B6037D9238C7B +:10F5D000ECB19993FD7B2C0AFAB0A6AD75427AB8CE +:10F5E000309F9F67EC99B487D890E82CC176655717 +:10F5F0007BAA3261DC400953EF857A8104EFD6970C +:10F60000705DEF882AFAB9EA5755B2CF86EBC80485 +:10F61000DF37CD48277F694665A411E30422F7331D +:10F6200019E37A7AD0C77958DF48C69EA0B1A09F67 +:10F63000057208F12707F04D90BBCB9FC4F2029EE4 +:10F64000BF1AF2F57C4B59417BC50D23B85F8CA1E5 +:10F650005FACBE5D207F5BC1B4E1A4D71462794684 +:10F660007479EAB267215F587D958AE4A458BCBFDB +:10F67000B803CBDF66B40EA6F3EF5131F43BAE9B7B +:10F680006EA8BCAC2BEFABC4F9EEB98D91FD5AAFAF +:10F69000CB5B13BDE162A14C1B89F8D7D50FC37EAC +:10F6A0002AF5FC3849A67E727D4CE70B9E8D3FA55E +:10F6B000F3018B8A7EC946A199E0C3FC3ED2F730A4 +:10F6C0005E06E9256FF6CE5D561C2C83D39DBA8F5E +:10F6D000D35D39F38808AF91F2FD011C7FE66C37EA +:10F6E000F199314719C185280FF257A50AB44FB9CE +:10F6F000030A68DFC73BD42611F04814CB0A126016 +:10F70000BCEAD9029D4B4CAF760405F8E774A00F14 +:10F710008A8392BCEE1980EF33BD023FEF85FCEC8B +:10F72000283F3C68C3745E36C3CE7C2FC4C1E7DC7F +:10F73000019C0F1BEDEBD7D84C7E9DEC014E2AFFB0 +:10F74000BA70D261E2138CC7B3E4247A8E217F674A +:10F750005233F1A9C316D0BF51FF651AE9DB37E96F +:10F76000F46EF08BE9DAED64074FF798F5E80F7166 +:10F770004F900E6609A4E7CEACBEB09E7DAE50D0D1 +:10F78000CFF172E5C349DDDF15A6903D7D23EA394F +:10F79000A5F07132E82151FAFDEC3BCFA752FD3EB6 +:10F7A0004F2FFFE60A40851ACE5FEA019EC82F2B35 +:10F7B0006649442F756B6C14F755DFB6DA9A85F8F5 +:10F7C0007C0F5339BE7ED2D80FE6D9AF561B212A03 +:10F7D000DDF0E9571B1490AEB390E710FC2336F42C +:10F7E000C7CDB0A9B5B8AE19694CF6A7025ECEBABE +:10F7F0006E23F6BFC6C16411E46DDFF677828857C9 +:10F80000C0CA55C449C01C8A67CB9593E85CA1C99E +:10F81000328CE2B59A5CC96A747CD4BAD5DD78873B +:10F82000715A8A9D0D93F5FD8D6727150CE0FCEA52 +:10F83000518191BCF0CF72109C330B789C52668A38 +:10F840006A0BA422BFE17CEA5181C7D73D6AF5E685 +:10F850000CC7383C502BF9FEF076B1749F99AEF787 +:10F8600093A4080120C669ED65E516849B3359C54C +:10F87000B844A3DFCA44CD8A7CAB72B0302240F0DA +:10F88000DC242D40FD34C1CCF7AD56BE2FEC23CE89 +:10F89000F763E520C801E2FBE8AF0F9493FC1A3F41 +:10F8A0006004C903EA6795E490ED2AEB21CF323C6E +:10F8B0002C19FD5BC30064A8AF77647BA662DC9E55 +:10F8C000FF4D89FC69E5D5EACD0BA3F6F5E7037595 +:10F8D000BD7D62640EC541DDA3F6C338A83515DDD4 +:10F8E000798C77AC61CD36C4F79A18F9B8D4B99B46 +:10F8F000F4C8A54F5ABBF197617CA85A80FCA3F6C7 +:10F90000D91EFE20E253DDFC2CC6BE64F26BB89E0D +:10F9100011C08F910F6985C922F995D96C2E47D9ED +:10F92000D302FAC544D7AA26947B9D4272B358DE0F +:10F93000CD2747E8FB759FE479ED6E5C37E84B4FC8 +:10F94000C9ACA71C603ED25F2680DC443D5A689F4C +:10F9500029E2B81B1743DF788E2F852B317FE762B2 +:10F960007E3ECAFCB7D1F9D738BF5D46FAFF2A31CF +:10F970006F8D3EAECF0ACCFA987C0FF5C7605F5012 +:10F980006F11901F4279DFC9D014E8605CFB11EA67 +:10F990006F633AA78B583D66B7C519B45890EFFA14 +:10F9A00049EE24B06036C24F2BE47CB6FC00E7B3CE +:10F9B0002FFB4183165195F5DD34C54D7A20958F87 +:10F9C0008D308A9BD9CEBC75BABEE31F908951A2F7 +:10F9D0003ECEC7757DC1D0E3AA62F6F15AE7231285 +:10F9E000F2AD6BB37BEC9788FD4F6602E98BD729AC +:10F9F00017E65B9AC19798992FB9D979DA3F76FFC4 +:10FA0000DE3BD04F1088D1830297A907A5BBBD1B51 +:10FA1000911E62F5A1DEE2289FD2F9FBA5C65182B4 +:10FA2000063107E5D758C3CE8AC19FBABDC7E73CA8 +:10FA3000C0BAF1AE0B9FFD9B6EC675803C97D1EEB0 +:10FA400013FE6B3DD1F51AA8278E47681E0CFC1CCF +:10FA5000F2210BF3619C02F3CAA7114F0DB90B9C65 +:10FA600088F0A47121C7BB5112CFE782228B78198D +:10FA7000181DABAF7BDDE887D6CA4B282ED690C7C2 +:10FA8000C32D1AE1C908A6A6633D034F46867939FE +:10FA9000E0C76EC48F7193015FF231BE76543FD4DC +:10FAA000BB2A9842F8511123D72A9DD324A4F34AA4 +:10FAB00047ECFE6B16ECF71A1D3FAAE47F0E3FAE33 +:10FAC00040FC30E416E8C9F7C5D817F7C5D8179732 +:10FAD000801F615CDFA5E2C7B101971767DB69BDD5 +:10FAE000E7637F39D9B33E31AF277E08ED772E7AB1 +:10FAF00000E93D90CC70DF5F48902B9D30CFFA1A23 +:10FB00001E6F3EFCADC200E6B396BB492F7C21556B +:10FB10007D8DCA7DBCBCBC431393215FB012CA214A +:10FB2000FF82DB5389F9FA55500EF547BCE70D60AB +:10FB3000BEF01E5E5E76AFEFB56494F37EDEFED55A +:10FB4000638DA20BCA838D7AFB8AE64ACCD737F144 +:10FB5000F6230F0403981FF4001FDFD03BAFD6F944 +:10FB6000E70BC2A9D7EEC2FE807F6E06FE39EE8497 +:10FB700056F61CE417C8160BE2EDC288DF8AF8704F +:10FB8000D8523B12F187CDF366239ED9D16E15BBB7 +:10FB9000F997059D3AD06E826425BDEF0DC12761AE +:10FBA000BDC94812286747AB0EE4EF1887BC19E4BB +:10FBB000CD005D1E1971BB787F606AD47E0D18C8B8 +:10FBC000E5BC512F2B8DE3057B8CE38511571C5A27 +:10FBD000CF04F4B7E0DAC80FD123CED847F23BD830 +:10FBE000BF6418E2EDB5185F0CE5D78EE5F1C56589 +:10FBF000DF9C9E14CF2E2AD6C73DAADF8730BED702 +:10FC000004DD16A49F171079FA62FFFDFF88FAD26F +:10FC10000B38D65802A99F8DC67DE4F9B103731E37 +:10FC20006E02BC586CF14988472C4F5071FED77753 +:10FC3000F8AEA1F5D43276434E9C75E8F27E51C001 +:10FC4000B699C78770FE335DDFB763F2EC3D7791FD +:10FC5000FDEC52AD30CEC4F10388EEA7550B06DDA6 +:10FC6000570E443D184F30C89FEDA538F7252C6836 +:10FC7000C34196C4D0FD32E7998F512E2DDB62A689 +:10FC8000EBE52C64E3FEE6C8E31F40FF351B9265FD +:10FC9000943FCB5BCCF56A36BC754028EDC9076A4A +:10FCA0000C3E1034F3015038381F583F98CEBF56E1 +:10FCB000648BCAA174F47FF848DE27302EEFEF93EF +:10FCC000D430D15FBB9DDB51BA7E7EA7C8F5F3046B +:10FCD000E6509C45C8872D7A9C2ACF1BE3B398F841 +:10FCE0009653CDB711BF31E260008024EF4FF9AFDA +:10FCF00095A3FD6C5D7C3E86DECBDAFB84F09E81B5 +:10FD0000E16701FD80EC2BB60038DD38E243B46FCB +:10FD1000C252F87F0CAECB46EB5A9F9447FC7D1540 +:10FD20001084BD0CED62A924847D0EE6F4E4403A13 +:10FD300042FE3ED96C6F2530AEC70FEFE07E9C11BE +:10FD4000DD72BF01F7D7CE540797FBCD0CE9AB5757 +:10FD50007BC5B932AEBD42120AFA9F3199F3F58BD9 +:10FD6000D92BBDD9235DFB99007A1BA4D3BC09CF45 +:10FD7000E3BAAF3E9F921C2F8E6A5A85E841BB6C56 +:10FD80009A55CB4C8B1727897A7666547DAF93FAB8 +:10FD900093BCE9CF63DC12F41B42FEDFF1A62D6EAB +:10FDA0003CB2A4F72F5935395EFFD7A2532ACADFD8 +:10FDB0002E79B3A8DF6F415F7971601C7DC5B62BCA +:10FDC000E69C92F90746C7133CA3FB0347166A6DEE +:10FDD000D8FE60421EF13BA50CECA97E94A7FE0E56 +:10FDE000DE762DC5479C61DA45E323D644F9CF0F73 +:10FDF000A6C63F17795DE773368C7983716F57B468 +:10FE00007D8857476DFCDCE568A29EBAF8B9D51F1E +:10FE1000BBEAF3F498C1272DBCFC689AF9BCC6A8CC +:10FE2000F7B9EE873AD4E0F0AC89F2BF2AEBED3EA9 +:10FE300094D39905FAFD8D958CECE7CE5752374552 +:10FE4000EFEBD98115B62B33B19E66CB4138BEC2DC +:10FE5000E55F9D14B6E1FE3E7285F7139C779DC267 +:10FE6000B417B11F256CBBA904ED061E17D269E5B6 +:10FE7000766067024F8D799D1D38D576259E23DDEE +:10FE80001626BED8959F1A26BE7776A087C6ED9C0B +:10FE90006E94EBF9FFCDF30A93559C6F8543B71F22 +:10FEA0008AE435E47705BD0FFD36B1E7078C8DE7B1 +:10FEB000FAB11EE7A9E5FE83CEF17AF3F35B1C1DD0 +:10FEC0007B7E0EDFE7E8FE606FDB977BEE56087FF8 +:10FED0000EE3B87383098CE2BDFF45BF7E67FF0E5A +:10FEE0005ACFBA8A48DE63E5142F407EB5E5EDAF00 +:10FEF000135F5F6ED07DAB99EED3AEBCB473B5D853 +:10FF0000F3966F81CEAEB8320E9DFD0EE535E0570B +:10FF1000953885F8DAA95681FC210AEB684438AF98 +:10FF200010F8BEAC78637EA50DF30B994C7CBE3502 +:10FF3000969F7903A8272C6B6224EFCA58410AC206 +:10FF4000BB7E9F883E04BA67A344F149BC67A344C3 +:10FF5000D9C578CF263A8FF76CA2EBE33D9BE872C8 +:10FF6000BC67135D8EF76CA2F378CF26BA3EDEB382 +:10FF700089CEE33D9BE8FA78CF263A8FF76CA2EB67 +:10FF80001F61BE47C70B08D7091B10AEADABED32E2 +:10FF9000C295F9B5778BB3489C11FEE17D9CE87E54 +:10FFA00096B926D996031CF6668B4C188DF76B967E +:10FFB0009AFA5D26D6929F00D40E92233EF88FE0E7 +:10FFC0002916939D7CB64D80BD037D68438CFED081 +:10FFD000FE5023EADB4B82E6EFCB5894DFDDDDF306 +:10FFE0001CE8D62BF573A0BEAC2FE27395E85471D4 +:10FFF0009F4FBD27AA76A6BB00709FB7727F64197A +:020000021000EC +:10000000BB72FD78DA472B0B2A783CC2CB4F6D14BC +:10001000837E77F7F9D0A97DBF3DEC857A8B734459 +:1000200019E9CE9E6DDEEF04C5BCDF4945E6FD4E05 +:1000300056CDFB9D32DABCDFB1704ED5CCFBCFC4C0 +:100040002904E765FDC0BC83F1D3279BF1C180EF94 +:1000500068F88FE3AB42F05D04F07D4CC073B507E8 +:10006000F6F6537AC2B9AEED211BEAAF970BE7075C +:1000700010CE49DD703ECBC6573A09B86C9A63641E +:10008000B7BE54BECF474102C7E4DC4AFD3E2F3F16 +:10009000DFD1E10AFA0BD90B51E7504DA248FACC57 +:1000A00063C857B58C64E203EA8624DAAF610EDEDA +:1000B000DF42E625FEB43046AF59EC7CC4867A4D6B +:1000C000EC3A7136E877A969E77A4DEC7A7BF8A3C8 +:1000D0008AE4503FCEB75B1E537199ED069FF6A29E +:1000E0001F238375D8508FE98D0F7E2F5B7B1EF900 +:1000F00011703186F0E0A600FD89AB4FD6771573FD +:10010000FFBCDDC7FDFCCC9F4AF318C5F83CA851E5 +:1001100094BF7F941424BF432EE3FE25C31E8B851A +:1001200027CB15D6BC0BFD8AAF311D8EAA2858BA35 +:10013000FDF760056AA85F8F3CC3F5A7D18E968056 +:10014000A4F4B4CF0F17E8E7DC921EF77991734857 +:100150009C3FFA396ED2E3EEAE6A1FB507F35DE756 +:10016000923BDEE887FB357EC75BE998BE2B284FC4 +:10017000DD0DE3DF2870BC88B52B03DBC729B8FF92 +:10018000570B1EF2574C62BE5C6E8F0449CE4C700A +:100190007849AFB538342B9D47E9FE4BC6C2935022 +:1001A0004F5FAADA681E6BE44F27A13F6619D3FDA3 +:1001B000316DE6FDEB610FC5D841B5B0FFD86FAC2E +:1001C000DD13078F62E201CCF2FE87453A3C198FBE +:1001D000575118BFF75DA3FB916A1C1B5DFC1C0EF9 +:1001E000E45C2EEB61374908F831745EF135E25B6F +:1001F000561AD80374DEAFD8E2C5EB313983CED5B9 +:10020000E73BA7115F9EDFD4C3AF4378BDB0F922AF +:10021000EBD2F58411F80DC6FDF3950AF7A3244E31 +:10022000D9A7617179475EB43E5B6FE3F772992F8E +:10023000DD745F21BF88EBB9E5BADE54E3D0E15449 +:10024000E46F44FDB84B6FEA612FFE73F7638C785F +:100250001780D78022FD7C677546F7F98EB18E2F07 +:1002600046743C1D027889C9D738903F2EEEEF1DA9 +:100270005204EDFA1F081F46BA614E85F4F5936DDE +:10028000C7F68BF9DDEB023C7B741CAEA34D94F9F1 +:100290007D797FE338E8B7B38CE35DEFF6AFDF98A5 +:1002A000D7E878F332E2EBABC4E2947094DEEED49C +:1002B000E17774B06702B62BFF63AE0BE76BCD6FCF +:1002C000D9DB17F5E23BB85E0CFB4A7E10D1CA04BD +:1002D000D44BABC4F3B763FE543693D1FECC48F293 +:1002E0008B2ED4F3E632F21331D5A722AA88FD8BE8 +:1002F000C94ECEBA03EC27E8F7A395F353F15E7F1E +:1003000056F282D40227C637C15407405EB078F84F +:10031000BDEC173FFE8F722C9F4D7EE95BECFC9C81 +:10032000D9FDA3BF2F233A604A9A7D0C8EE7A577AB +:100330000522A922CDAF62D699E1A85FF53DEF1C59 +:1003400086FA590E9EF302488B74FAB8BA3232DC40 +:10035000E7EC865346417CFB254587C7C1C49333F0 +:10036000F03CC4B87FB13EE96D3A0F3FA99F9FE4CE +:100370006B935310CF0F0E34CEB54299E8B2AA4B0F +:10038000D05266E23CDF11199E9B9C91B594542893 +:100390003FC9F8FD0A7F8795CE8956DE5FD927CD04 +:1003A000D97BBCFE7F1471FBA636262EAA560AD92D +:1003B000F03CABF65F8C8B6A058B3BDE7998B1FE27 +:1003C000BA54894943211598E742F5B67D2DC68573 +:1003D000E3A622CB05EF6D6CD0D767DCCBA8C37B3F +:1003E00019F069E52B157DD805ECD0BA73E34CF70D +:1003F0001FD05EC3F5D59D9B40DF2BEF3B6143FCD7 +:10040000C67EF00904E35E466F704E29E2F6461D93 +:10041000DE67488FFEAEF0EF5DFD6750F9333ADCE2 +:100420009ED96799BC39CE3CF7E870199C2991BFD9 +:10043000604888699BE28C6BD433DE35E86D5EAD35 +:1004400013C37370DE18171C6FBC97F57AC67C5BFC +:10045000D3C28B3CFC9C7520BE5BD095972379372B +:1004600046F1D3B3BA7FA0F57BE13C7A27E33A6E3D +:10047000C7F6B6CF53FB7B93903F8C944277ECC981 +:1004800020B38BA11FADCFEC9005E5A44157BDED86 +:1004900077379C45D3FD979E70B65179D7BD33A66B +:1004A000B9842C94438CF481F57F2CB5D960FC631E +:1004B000161641BE5325E64E7A15F3603F205D1EA9 +:1004C00023D901E90691EE311D7BB2C08676D9A20F +:1004D0000A1611816F1D7B37AF11E32E95B9A04924 +:1004E0008E0375678DF9FCB186697B93A1DDFC03F2 +:1004F0009E9410E4173C609663C7DE7DD086F6803C +:1005000030CFE9C3B82298E7A45721BFB0CD46F752 +:10051000B2163D12DB9F590FCED2E56DAC3E7CB2D8 +:1005200048B73B46B29128675E6D68E3EFE6E8F7AF +:100530001041FFD3E2E189A1073F9938F1AF4504AB +:10054000AF1611F9D238297EFD5B8B39DDAD78EA23 +:10055000B4CDA5F44E67C7819F14C2F8271A644A28 +:100560005D83346110F49F37C86B1B04ED45259201 +:10057000F705F939F93928E01BE5EBF17E1ACADBFA +:100580006AAE27D8C5DB6A481FEDC7E400E92F3EF5 +:100590001FF9D32DA09FA462FCC6EDA28BFC0DFC1D +:1005A000DDA0317F59908AEBCDF8CDCC1710AE7815 +:1005B000C781E1FB2B155A19F2F775539D74DEBF05 +:1005C000C9E2A77E3050EB3E8067F09931BBD07D09 +:1005D0005ED8F2D044B4FBE4F69D21B4579A2C5F68 +:1005E000EEC5B884A6094C0D10B483344E7DFBD4FF +:1005F00017B07DDE34A78AF74AD7B9B53239AA7F5A +:1006000085453E463DF364AD85FCA6A7DA9EA0F382 +:100610002AB0EF22A87C9FAACD27BF9911F7436784 +:100620007F71FC862740BEB1A87BDCCB5B3759507D +:100630001F1F821B15155765CCABF6DE50D6CD2893 +:10064000777F2D911CCDF8AFEB287EC02D2902C2FB +:10065000F36641E6FAA8AE27CF62C69FE63DA89FA3 +:10066000CE433D19F0F0332148F19A16D6FE12B66A +:10067000AFCEE6FA20535A46A0FF3A5CABBF4BB46C +:10068000CC9A8AFA8D714ED01B3EF4E6E7819E1615 +:100690007D08E39E1418F99BEA2D913C9CDF716B59 +:1006A0007CF93A7D10C7BFBA81BE20C9F334263F1A +:1006B00085F32AF4BA912EEB2CCA0AF27BBDE7A18E +:1006C000F8904E414E33BDEF2237FF0EF5EE7A8B98 +:1006D000CCED9B035A199EC7744E2DA6F75E4E5A59 +:1006E000C379C44780EF615C56DDA017A649F8DEE8 +:1006F0004E5FD0BB20FFF3413B783E3FBCC802F9C0 +:100700005DBF7E7F9A0470AD1B1C3E8CF937077D60 +:10071000CAF3C3C28B707F8E0C8AF03C1A60806073 +:1007200067067D35CD0FEB3AAEFB3F991A9E83F3FA +:10073000AC7BF54A4BB47F313C88F3CDE309BCDE9A +:100740007137BBF546D43F8AC2741FC6A8B77B90E9 +:1007500011B7C9F17FC9B68410C6091BED5876FCE4 +:10076000FEEFD1DB2DD1DFC902FAFB2DD6DB9DAD2B +:10077000A4D13E1F051E85707965109DF7CC1B9492 +:10078000A6BF7314CE4B2BEE39DE5294F32807AC80 +:10079000E67B6FF70FE27C9B15F3FEEBFACAA9B874 +:1007A0001F5969DCCE800D49BD8FDE2FD8A4EB55D3 +:1007B0007C7F3244B92C2093DC198E76F3EEF3B9AA +:1007C00065643757C6C78B4775BC5812E0E344725F +:1007D000147933DD37671AC6A3EC6E4BA07518F594 +:1007E0008F0CE2FA4578502AC78BAE7DE823D038CB +:1007F000011D2EB900EF926EFC31DA5F6CDD5BFEFD +:100800004DEBEEB14FE57C7EC67A187B88EF2BCCA2 +:100810002F15F4FCE3ABF576A38D7928440F4BB686 +:10082000DDB581F33F258DEC76F6133E5F87316EA3 +:10083000319D4F2ED7F560D1FFB60DED8DE54D1DE5 +:10084000F4EEDAF216FECE5637DD692BA3E92CA3BF +:1008500080AF3343D43202448FB03EA2474D8F372E +:1008600030E34F17BC63E9B8477F4A9AB93F85FA2E +:10087000EB6D1F3EF8B6F721101F9E5DFC25067E2E +:100880005DF4E8D6DB15039E95F7A4C737BBF62FBA +:10089000868EDDFFE478FABD93E577E9F1AA8A193F +:1008A0008F97B7BA2DF38ABBEBDFDFF290273A9E22 +:1008B000D6DE3AD78FF2AFBEBD82E26A97BFBCF5F3 +:1008C000777E68BFF4F99FBA3098FA98D49C857AFD +:1008D00071ED536B5D1A9EB3487E17F2CD63417183 +:1008E00072BC7BABEA60415F1FD7C7EAF09FD0FFC5 +:1008F000F167FEDEF81F30FFBF0AA05F21BF6DFD6C +:100900005B23DA6F7B354704E5F651293C09E5E8BE +:1009100092B94EDF6A15E306CDFAD4D25FFD344BAF +:10092000A1E06E7F3F0BE953A17ED8AEEE49AB8AC2 +:10093000F67BDD7BA20AC3B07A1669C4F9C5B6AFEF +:100940006FF9CC867095411FCC1DD7B31C3809E1D7 +:100950007D7DEB7F7E29BA303DF6212BC5FEA2FCC2 +:100960001100F79A5EF432F760DD4FA9DF0B30E03B +:10097000C38299A4DF047EBDBEF41398D78927FFF4 +:10098000AF4B288E9697F712BC4EB5CCFFE5AB4A1D +:10099000EF72F524EA07F69E7A80D2267025BB9D79 +:1009A000A7B5D6900BFD02B59BACAA1F3ED76E7DB6 +:1009B000E2693C57611FD8553C7AACDD7ADA86EFA4 +:1009C0009ED50A5A44203D8BB98491DDFBB46CEB73 +:1009D0005FB8BF2A476453609F96FEF62CAFAFB155 +:1009E0004802D45FF6C227E4DFAAF53A7D8E38FBD1 +:1009F00054D9B2D31676C6D9A7964F26A11E14F89D +:100A0000F557B40FC77608AC8FBB67FB9A4D7FB123 +:100A100021DD9C800D494FE5F042FBB4BE459C6B47 +:100A20004B89B76FA1EB51FF8372F2835C6CFF843B +:100A3000C18CD3C5CB5B9F437BA0E643BB3A05C7C4 +:100A40007DEE761743FE2AF938BEFF626D9606E307 +:100A5000D658FD5932A5FC7BCDE377101E2E7EE7DC +:100A60008E2CD2EB989663194DEBCDC1752EDC38E8 +:100A70009DD6B98879090F6B7EC1FD196725363976 +:100A8000DE3DE32D8339DFB2B3DB4A913ECE424FE8 +:100A9000E8873962633C9EF75DFEFE989DDD981203 +:100AA000FDBEDCDD83391FF1B3E0C7F8EE643DD84D +:100AB000C5C817C477CE4EC27E56BA259F5DA6F52F +:100AC000FB757809DFF0780E4532E24EF361BFDE48 +:100AD000A9EA8376B09D9DB2DD528EE7BB4C41FF03 +:100AE0006F543B82DB91CDF64401ECFC2359F1EFCE +:100AF00011BEDF45F7EC5D16854FF55B8E103E317C +:100B0000B0BB52B279FE31A443B08B52006E67DEA7 +:100B1000FBCCD617FD1D19163600E7DBF117CA33DB +:100B20003553C1FA46FFF56D76D37B24F54FFE258C +:100B3000869EED31EF9CF8089EF52C45417DF388AB +:100B40002D32691B8E03E362BCE6A247ECA677C296 +:100B5000BAF1C5D6FDDDDD4D9F867DB558A7FFD81E +:100B6000F5C7F2832762F801DB987949EF3ED55A41 +:100B7000834F237C6A815EFD44AF9CFE40478F0C0F +:100B8000007AF8FCD9D7F6FF10FD742DD68C2934E5 +:100B90009A99CFD6BC08F48BFE348077828A7CF693 +:100BA0002B1BEABDD9956007C3BC3F77AA7829AD56 +:100BB00027DDC2F7B874EB6474AEF5FF8BBF2EEE81 +:100BC00085BFBE35D87CEFEA2C2B4EC13B0CC79FAE +:100BD000597605F91562E06BD8BBB17C73F160857D +:100BE000E01CCB37E1CF7E1605C7A5BFF982F0F632 +:100BF000AF39FC1CACEEC9BF91FC02B046EC80B72B +:100C000075C12F29BF16E517E5774EC3F3EA9EEBB2 +:100C100036C333B6FC219D1F75DD73BB97F931EEEA +:100C20002EB25DA4F7173A612E8DA89F3FEBA673F5 +:100C3000C2B5BABEDF29475CA89FAF4D35F2EC566E +:100C40007C07A6D35F2AFBB17D821E7FE089B85264 +:100C5000A3F4A44FDA4517EA75E1209B1CFF3DC0C1 +:100C600000CD23CC7A2B5FCDEF6B89E79F0BEB7622 +:100C7000BD1DC60BAFFEEA393C373F2439E8DC72B4 +:100C8000C1EA992EBAFFD75EF07F102F16BE017011 +:100C9000447AF26BB61C80F37C0E02303FFC741E6B +:100CA0002C2697EFDD06F5160180F19C24D69FB225 +:100CB00094795242EE9E7E1390833694FF8B411EB0 +:100CC00091DF7BA3B97C69FBE784674B63F0CC8B36 +:100CD0007896D313CFFA0ED1E9B68C95E9E7BA64CA +:100CE000CF77EE13E93CFF948391BE81E7BCB063FC +:100CF000EC54BB48FB73EA592148F186FE4CFE6E6A +:100D00002BE03BEA59061EC6DAF7B1E989973E1A8D +:100D100089F7C46A7FF7DFA53F87F4C4EF3E18B8B0 +:100D20000DF32FBF9FF7DFAC67FDCA1D7F233BA6E6 +:100D300073879DFCA19D3B5ECF43B9DCF9AA5D455D +:100D4000FCEDBCD7CEE31A7624D3FB659DFDB9DF5D +:100D50002EB0FDABD230C9AD357C1F87D868BF4FF0 +:100D6000B5FF9DE4C8A976BB82EBA8DF9144FEB134 +:100D7000FA571382E81FE8DCFED5C8E877AEFED547 +:100D8000F5D4E9F7693A935935C6CD74A6F238CB54 +:100D9000FA6D639E588DF648EB4E1BFAFF2BFFEB66 +:100DA0001FA5C8973A5FDC6943BE0576E9E30CF0FE +:100DB000C3F39B9FFED49A83F7C518D9DB277EB374 +:100DC0007F3ABE8BD5132E1C0E9D00075C17C0A565 +:100DD00006F5B2DEE0B1F83B0B8F2FC99EA86D1F60 +:100DE0004574D40D1741E3DF93830E01D7FF8A0BBF +:100DF000FD469DF920FF555CF757A5A83F5D6CDDCA +:100E00008DFF53D66D6197B5EEA786F0F7C8BF7B0F +:100E1000EBE6F83F64089757B174D013CF5FFE112B +:100E2000E59F4B5669BE9748FF7BBEB3EBBFE47DA1 +:100E30002F45BFEDE5EEFBA1EFECBA2FB6EF6FE863 +:100E4000FB9E2CE3FDBACEEDFFC8A3F55EE2BAC56A +:100E5000E2EF2A9D5F78DD5DFA91E871E0D35A0FE9 +:100E6000B0508702E9DA5EF414B5D86C8F88BABE48 +:100E7000B1960DD336A15D057A06DA016B3378BEE3 +:100E800009F40791EE0F52B00A6BCA55F97BB6927E +:100E90008FC990B7BE3F9FE259D6667D8FE597E335 +:100EA0007905F7630456ABDE9DD03E906A51022A65 +:100EB0003E53B5C2BB09CAE5BEA28CF6CD5AE54683 +:100EC00047F43B1692D366B2539C31F64662A1CDED +:100ED000649724B05D32FAE1135489E2FFEC2CAA46 +:100EE0003DD47715F373EB4416F4CBCECB87D32DDB +:100EF000C5BADFECF2E1E4A07B95B20E27A669B893 +:100F00006EBB22911E2631B01FF93AB8DD0970542C +:100F1000A2E0C8743B54D2412E29C3088E604028F9 +:100F20001347235C7D04C7408E28135CBBFBA3756D +:100F3000C7EEC35A6522CBD7F57141FDF6E13CBC43 +:100F400098FF1E432C9C8DB4C05BB11AF5DF95ABA6 +:100F5000F939D78BBFFF1EE55BADA00FC37CC6A7D9 +:100F6000781715A3DFD1A30948A72BA7F27705CBE4 +:100F7000F11E58069AFA3C0E37C391CB24F25782E1 +:100F80009D41FE4A99A1FD274E642DE40FF448319E +:100F900071BD32C53D056EE3714FAC8829FC9D16CD +:100FA00073FC8F7F222BC2B8862AB1B619E7758AE7 +:100FB000253763DCA5CD1ACA23FF707F9085E86FC3 +:100FC000A9F8EB462C77835ECFF03E9914FA18E32C +:100FD0001BEE145318C55545E05314DCAE3EE760D4 +:100FE00052149C2B58AA297FA2FFE156B413F2FD9C +:100FF000761983C72A1D39A6F62772CED17801BB90 +:101000004346FBA84A769BDA8BAE7D1FA35DF37641 +:101010009A85EC826BB30799DA5FFFE9898D737566 +:101020009CC575DCF011BFA70AF6D6E36F42BB770B +:101030001E610CFDC6D72965A6766DBA7F2552655F +:10104000A5F766BE5F34C6346E5B7817C1A53693CC +:1010500009781E5C6B0192807A3F502B4CF56E181C +:101060007D9DA9DFA9DA5453BE76D55F9994CED879 +:10107000B855E719BE1B58166A31B51FBEAFCD541F +:10108000DFF52698429096BDA704301D7590DF23AA +:101090001D0EFB81E71B6DE1792AC6EB94E005D0BC +:1010A000723C16F0546218F2C8A3BED730BD58FC8B +:1010B00032D3DF634DD4CF5FD759822D73DD18FF54 +:1010C000D3FCE04E81E221B7158F40377473650A77 +:1010D000541F7BAEE5354C5B3BC6378D2DA76B436C +:1010E0001D247F9D163A17A812DB4B05B27F92860E +:1010F000DBA3CE5D7A7BA7F3EEB28AB7900ED664FF +:101100006BCD3B91EF4FFC688E98DFB31E93A548E3 +:10111000349EDF5DE6F933C69D197152899522FF31 +:101120001D8A6B799C4CA3454DD09917E907F22491 +:101130002BC5F1CF2DE1726064C7E6166739DA9DE1 +:101140000E05F73531DD7CCF7BFE687E6FEF8B625D +:10115000DD3F2FC999B79460FB64DE1E7D7C38DECD +:10116000140BE9533BAF3A42767AE20D96FE2041EA +:10117000996BB46A41BB7BE4BE3FD17B04AD53F2B3 +:10118000D7EF82FAADFBFEC40428EFF340D95E2B03 +:10119000D2D9688B8CC7F5ADA3279E2EC4F229EF58 +:1011A000524CA3310FD739812951710F734B141A47 +:1011B000DF2585E91D22D73989CA5DB3554B1EF657 +:1011C000B7CF4ABF5BB3E22AAEEFAD1894B815F1C2 +:1011D000D47540E37150454E6500D143389BF88289 +:1011E00014CEBE2599C753291778CFFFF89611A9B9 +:1011F00028B7D22BD454F47BA66F15BBEE99E17CB3 +:101200001FC4BFF020DDBF76FF3550BE0563D57823 +:10121000790878105B67D3CB9105413E5DD0CBFD5B +:101220006B675CE3A477174DF587E677D5D71CD9B4 +:10123000DDFDF7D9BA76FF9A6284F7280BC69124B0 +:10124000FE5F2BBD2BB0629093F4871540BF4CE836 +:101250007D1DAE73491781A78BCA0F094ACC3BB9D4 +:10126000A112CCE7E57AF34A005FAF389F42F7FE60 +:10127000CF342590BCBBE2FC0DF42E67AB4DCBBB4D +:101280008BFC3509145F36F5B6CF37AC423ABEFE5B +:101290007811C62418EF54D6CB7F25FA37E2EABA84 +:1012A000E087F80A78FEA0A53B8FFCC0D50D4F0D56 +:1012B000DFE35A17055FFC6D97A93A3C676E5D3F07 +:1012C00003E1A32C989C8D74789A39298EEFB4FC95 +:1012D000F40C9CEFE92D560A9A6DD5F9A3BF487F0F +:1012E0007F20239C8DF7F04BDEB150FCD141C0072D +:1012F0000DF0A120F44E5A09B6CB90D2309EE1F405 +:10130000F8F7E99D84D3F7300A265E1AB611BC5A65 +:1013100033165456A07C3BA0A4A1BFC1806F8BDEC6 +:10132000CFBA326D6209C947FD7E8836F6B2DE9BC0 +:10133000DC79D557740EB0C60D7A7D2A86189F6B5E +:10134000C4F72457B8AD248756A4FE755206E27B35 +:10135000852382EF3ED4AF3A43F0856EDCD1F7BEF1 +:10136000A4732253A2E2B5FA0CE5FB2F491AEDBF94 +:1013700074CE46E5B5AB4E139F36DA9FD0CF53F10E +:101380001D46BC1F54FBB548F74481FF3509C330E7 +:10139000DD655B117D8ED3F265175F1F6AC1F79F14 +:1013A000DE4D44BFE454419E8EF3FB6DE99919185C +:1013B0001F3035419E8EF105FFABF4239EEF2F4F7A +:1013C000C77882755BAF9E89F1065373E49F5A40DC +:1013D0005E6D7B6ED64C2A77CB7FC2FC132577F2ED +:1013E000F264BEEF752537CDC4F8822A91D3C1A926 +:1013F000A6A4A0FD0274B078D53616FD6E6D8F726E +:10140000FD77A35835E7735FDCDF8FDEE964851D68 +:10141000141FB6BA44D0E3D08CF35426E3796A465D +:1014200001D3D0BF9CF17202FFFDA1431D7908BF1B +:10143000231B6FFF11FA4F970B8CDECBAF65CA48A9 +:10144000A4AB7996F0C798FE66B8B789E34707C59D +:10145000B72E5EB583E6F789AAC729CB9162CF3F45 +:10146000F52E04F41FF75D08735CF1A7166520F6EE +:101470002BE970992776CCB1F179FDBC04CF87D2E6 +:1014800076525CB324776479B9DE5444F6527622FE +:10149000BD0BDDD8F7C3D278BF77D0D200F21D489C +:1014A000EEC586364AEB87325A4F1F296C53A19FEF +:1014B000BA035CCE8CECF8D4161DBFF88A2EA75266 +:1014C000F4DFB58A8DBF7D459743C6F9F6F2BEA11C +:1014D0005CD4078D7DEDDE9750AEBE2F0CE79B915F +:1014E000FEDAB3F8BE09C6B5DE83E7172F2784D02E +:1014F0004FDD3B9E18FBC068BCD644CE37222F255B +:10150000909E14BB8E3F76C957BE9E233A9EF4B67A +:101510008E23B88ECC7FDF3A8E207FCFECB91E832E +:10152000BE8DEF067DF76CCFE77FF978C7EFB15D31 +:101530000CEF0CFE53C7BC45FC7E34E73706BC8D70 +:10154000791A706BED25FE565AF58A693D52C744EB +:10155000347298AD349FF3B796EB18EE87B4AA9D1A +:10156000EAF5B61E31F90C9DDB2C55980FF5DCD849 +:1015700075D5B2166AD7735D11E2C7CB15CE8F7BD6 +:10158000C6ED47883FD7813D86FAB7B1EE2E3E0DB6 +:10159000EB47FABE0A180EF14DBC3B28A03DE135E1 +:1015A000E9C315784322FA9CCA719B295F25DF6540 +:1015B000AA7F6DF66A53F975CAFDA6F2EF173D646E +:1015C000CAFF40FD598C3EBF29469FFFB5A97C7CD0 +:1015D000B883F4EDB71B26533CFA84A311D2BB4366 +:1015E0000D32E577356453BABB4121FADFDB504455 +:1015F000E9BE0695BEFFBE6134A56F3668947634A9 +:1016000078288DE51BE51DE172F4E78FCE48A1F344 +:10161000A707867AA795E2D1C27B9162C4BFB107C2 +:101620005A5E43515010FCF263AC775AB651FCE15C +:101630009A9D63FE703BE4D3DF1459827221BD484A +:10164000645A14FEB8A684199E77BB187F0F2BB678 +:10165000FEAC521E4756CDC2FCFD805574E2CDAAA9 +:101660001DF21E2D83C44604EDF46AE6233DD4B278 +:101670008ABF4B53CD54568EF6AB97F91EA0F82374 +:10168000F37B021E6DEADADF42F90CBC670AED7FDC +:10169000E86CA17BE42FEE4BBBA60CBECFF208F4A6 +:1016A0007B1E0776DC778783EC5DE3BEE98796CB0C +:1016B000D127669572FAEA14D40E9CAF3F95BF57B6 +:1016C00014DBAE545FE7F58108E91F11D03F30BE4F +:1016D000CCA0CBA9F2217DFD8A25650CD2C76ABAC0 +:1016E000CF50DBA1A80180F798439C2E46005DE017 +:1016F000BE8D3DCAE96024D001C941DD1E34E80039 +:10170000ECA7D7B0FDA9834C453BA271C27F8A6884 +:101710006F8D39130C607AF5F9C8CE6FA07C5C0729 +:10172000FF7DA48BD98F865EDADE504D78B4A3C1DD +:101730004B69A8A146C74F1FE57737ACA2FCDE0670 +:101740003FA5FB1A9A74FC6CA6F2371B3650FEEDCF +:1017500086A08EA75BE87B1F5D9EF94B653D2EA999 +:1017600042B72B78EAD1565BE95E3F7C427E528DD0 +:101770007345FCA81182C8BF1BD3FC56CC3726E2A8 +:101780001EE0ACFD54FF66270BA11CA8CDDEC6F5FC +:10179000B0183CA9C8B889F0649A1EB77A20ADF198 +:1017A0000E1BE0C3899687ADE6F7452F0F2F963ABB +:1017B000D7D03DBE58BEB804DF9F107BF243C6545D +:1017C000B5BC9CDFE7C2B8BC4BE5F7B2A543BF1F71 +:1017D000C6EFBBD4E53A29AEF6DF2767645DCEB02D +:1017E000B958BFCBDE4E3C3807DFC3EB0197187BFF +:1017F000FBCF57F2F686BD0D7A26F9A13A8322D99E +:101800005F35EE6617D9DBA3232EDCCF25DB4546FB +:10181000FAA2C4CF771763470AC6F184F68F23393B +:10182000B3722FF2A5A5FAF96EEC396D1D9EEF0A81 +:10183000F1E01DA638FA65FAF96EECBAEBC61FA105 +:10184000F3DDBA8BDC23FD53A9391E23F6BE6E6F80 +:10185000F882F103D1EFB79E3CDF4076DAC7A57777 +:10186000AEF78FFFF7EDDFC232CFE7A53C6E9AEE01 +:10187000C919FBD9A8FFFE66E34407DD5BE81C211C +:10188000D37B379D027F6FA7F36F4C5DADE07B3A52 +:10189000F26E940B57AB36E2ABA3C3FC7D80F178BC +:1018A0000F31CEFB00571D0A0692B1DD413FF99F73 +:1018B000C6BCE70DE03DDB516F6A229257D96E8FAF +:1018C000887860C827435E75D3957E4F0E63300AD3 +:1018D0002E9DFE9405A3B351BFEBB25B9D93E85DD3 +:1018E000A2D32146D1A3861F6CF8414DC47B0823A7 +:1018F0000E7903286F1B753B73D409BF9802DFAFC5 +:101900003AE3233B680CD8A9F8FB31786F5A8B82F5 +:10191000AFE1C732F89CC1D78C7B7AB2CDBB05FD55 +:10192000CDECD5047AEF2576DE7943B95F68717F17 +:101930004FDE50E47BFABDBC2AF1FCCE6FD02EE81E +:10194000E0F101579CEF7C1AED9E952F25D1BDB497 +:101950008BDA07F2E9B8FAA991D65BF8B9C9B04AAF +:101960006538DA9BA8B7A21D6AD8A5B1F50BCB26BE +:10197000960DCDC4798DEFD010BF65CB05F1BB7E40 +:10198000D59717B40B8DF1EBB78F90E7459D1FD41A +:101990000F35CE57FEB977A7AF8A549BE4D8775D51 +:1019A000EF033A2C47FC429B15E5D40F7107601DED +:1019B00037B310E92BB7E8BF5B712BA8E0D1F76212 +:1019C000E7338DF8C31ED5BB08F765218BCCC17CEE +:1019D000BD10A9DD0620FC62C238D9ADF494D797BA +:1019E0002B9F13F57BAFB170BF6B28D7670CFEDF61 +:1019F000EBFEC4F0FFCE3299EE3D77BE34CE82E7E7 +:101A0000369D6F89F45EEA3A0BE72BFE6136F529C5 +:101A100015DF1F997D8DE10FC0F8B258BEB2C5A287 +:101A2000FEE17628F7BF9DCEE2D195915E8FFA2830 +:101A3000E061CAECB094EFA4F7D3D721BCBADEEFD3 +:101A400040BE7205C0FF137E3EC79608E4F76C6B7C +:101A5000E5F99285A934BF4BDD0FE839A914D6B159 +:101A6000B0551A86743A342D928FF45532E6833489 +:101A7000C189BFC3CAEF4501F89A585AF73CDFD273 +:101A8000E1F997A1DAE338BFA1691DEB1E463DF1EC +:101A9000250B43FFDF9131772D6251F2F56B75E233 +:101AA00013C82F9E17F4F7E5B6F3DF21801659D13E +:101AB0007EAA3D6AE5AFB15E0BEA5748579E57E8EC +:101AC000FEFD5499C3925D93A9FFFE63242FDEEFC0 +:101AD0000119E75043513E703F22BD07F6BCEE6747 +:101AE000DC39F4C3996B90918722F9388F2309FC74 +:101AF000FEF3D7AAF7555A07FA6B711DBFE076FEC1 +:101B000091541FDDFFF800F82C9EFBFE778383D2F3 +:101B10008FC0CEC1F4CF60E760FA09D839987E064D +:101B2000760EA60BCF41A7B08F15AAF6C6D00BAC88 +:101B3000A3773EC1D7D1D9CBEF2AEDD2E15FDA7AD4 +:101B4000E8DE24C4833691E29A4B5E9248CF3CD9BA +:101B50003ECAF43BA24077FB711EA56D7FFC09DEF7 +:101B60008F2E6D956441C1FBD4A7B3286E30667E7D +:101B700008073C27886CB7F1DF3FD2E7FB7C6AC7D8 +:101B80003A6CFFFC4BF938433C7FE178B8DD1EF737 +:101B9000F7818D38B99FE972FB067BA43CFADC30F3 +:101BA00036AE8CFCB963109F0BFF80E3F8F7896CAD +:101BB00000E1A5D94F91AC723964A425DB6D145FA7 +:101BC000FCFCF6FD377E1FFABB7EEC75A67775FF31 +:101BD000819B9B8978FDB7C71ECEA0FA320E358B4C +:101BE0006DAA92A1DECD8E9D7B70E9B7C89F54A5EA +:101BF00042FED66C612FA67315F7A43405E71BA42B +:101C000071E61755EC45D49AA24EB5F1771C453CC8 +:101C10006BECE28F958E247A0CFAFF01C9CDB6AA3F +:101C200000800000000000001F8B08000000000082 +:101C3000000BED7D7B7C54D5B5F09A39F34A329395 +:101C40004CC2041220709200060830249390902019 +:101C50002721D088944E225A54D4915A44E53122F7 +:101C6000AD694B9B13122084A04191624518285AFC +:101C7000EDF5ABA9052FF6AA77824AD55A1B149F1A +:101C8000A576A4D66AAB9282D87A6BCB5D6BED73E6 +:101C900032732693F010BE8F3FBEF0D39D7DF63E8B +:101CA000FBB1DE8F7D7600004EE27F33DD83001CCA +:101CB000C03F54FF4AD630808268FD1239DFD07EA3 +:101CC00069C178433B4008A004608EB7D8D06F52FA +:101CD000464F5ED00930E1A9CFEEA8F4E0031384AB +:101CE00047633961EFA76FDF82E5DCA957FA241952 +:101CF000E043E8B862BC09E083B2F55BEEA6972D3D +:101D00008A2D7B30C08DF43BB67F04E1D72BB05DCC +:101D100072AD3C701BBE77739604921760F136EB80 +:101D20009148CC3A96813F2D8CFD6EDE6D7C0E1075 +:101D3000B1857D00B7049CC13637C09247B0DD61E4 +:101D400068E77197EEB3B9A97D1958A2EDB9000DF6 +:101D500087731F7D3666BC4919DD77DD8DE34D7ACB +:101D60007C9EBB19D7F768F9E74365DC67A1D7E527 +:101D7000793F053B4C812927252C25A719B0DF8900 +:101D8000E7A59084EB9A297D911A29C4E73599003B +:101D9000D9F89E49FE6D05B6AB2F48F0008EF3F7DB +:101DA00046F9D167AD343E5CE7C77E27E9673ACD97 +:101DB000BA9AE1AB976F35E2AF1701FCAED1C1E53E +:101DC000EF1BDD5CFEA1318BCB771B652EFFD85856 +:101DD000C0E5DC5720D089E3FDE91F930106D13827 +:101DE0002A4066B49C64F39A87E23A7A7E23857629 +:101DF000E17E8F574E49035AE717387FA98607249B +:101E0000813ADC0394E37F37EC7C2EDBC7CF551798 +:101E10004EB5EC1F122838EE0D5E9358E792AEE7F0 +:101E2000B23DD17658F9AEA13FAC321D30D45B72D1 +:101E30008DF5F6AA03B1EFEB70882F6FDC76AB2D32 +:101E4000E0C272B3490939FBB6EBEB99B93F4931AE +:101E5000E1789627ED213BEE6F995B0105FB5B0076 +:101E600094CEC2BEEF0134F17B574A10EC4C30EEF9 +:101E7000721A17E136677F12486731EE5B481BB470 +:101E80001EF53FEDA107F0BDB7D214F0C7CCF35D4E +:101E90006DDD1FA7777CFF33ECF7F113404FB00ED9 +:101EA000F3693D13F7FCD96CC67252B2A09389EE68 +:101EB000883903CBA38BFFB9E5750F93A9DF743184 +:101EC000B6E7F5BCEE4094AFEE9CB9D581787BDBEC +:101ED0006C06180A02F165D81FC7A0FA06EFCCF904 +:101EE0002DF8FBA5FB93C2E6B3D8CF06E4452A271D +:101EF000550B7EBF96E846CCA300F2C3F235A0CFC7 +:101F0000AB907CA0FD53FD99CEDA3737D31AA0678A +:101F10000BC9878F00C26DBC7E253596FF973FF5B4 +:101F20002DE6CF25D9C8F748EAB04DF0AF03FF9DA5 +:101F3000CC237E0DCD72E27A6F0A23FFC3F9E7FF4F +:101F400087BDCE289F5F9490CF5FB914EBCB9F9055 +:101F5000BC766C3EF6E468C14F1ADFEB7CDE4B4F7B +:101F60005B25E64BBDFEC993526D2801BC376974F1 +:101F700091AFF4D4D37C2B9EB2401BAE6FC5B48B13 +:101F800086C48EDF875E5B259063C67FF469FB6243 +:101F9000E217197A06D721FF4C7AEA444655A12860 +:101FA0009B681CE8D0E44DCF08FF0494D726FFEFD0 +:101FB000BF87F301E2F101844F75D6FC1C9ABFDEA6 +:101FC000094ADB6406CB3C07CA89CB0488E0B2B27D +:101FD000AB7300E1B90DD12521DDCD53EA5EBB1A0B +:101FE000F178B939F05592F36F79F379FC2B5C2BCA +:101FF000AD606672CD31E178F3E7D98B693F739BB1 +:10200000055DBF96DEF3113D7F6D5A8AA919DF7B0E +:10201000CD042D9011DDC76B567F4E90E9A7C6FD0C +:102020003EE2C7A48C934EA6F42F2F8892DFD7F1FF +:102030002845E5DF4CC9A9D23CC7DC66A67B4B76B8 +:10204000BB8DD67513840E2838EF326FD846F2EF69 +:1020500016705BA8C4A2A7973E88FE2AFFD9751206 +:10206000DF5FD62D854CD8BFB3B1132C88DFC71ADC +:10207000F77139F28B912DC3101E2B27DBBC6DA499 +:10208000B734FA32AB263899405FF5A54F4BB41DF3 +:10209000D75DE57086A5547A6CFD28761D3FC85142 +:1020A000FEE945B8AAEB2AD3DF4715CDB43032BAE2 +:1020B000CF49360027C9F9075258CE7FF874A9993D +:1020C000F0F4E18BD69089EADB2F7AE3361FD781D3 +:1020D000E4CD87195EB38DDA33F2422AB6DF6806A3 +:1020E00095E432EC1272EB9969B7BF43726CE50369 +:1020F0002E93DD24E858461340FAC9C677EEC57121 +:102100006E4266B57BA37A63C9F49F6C7904E9607B +:1021100089B9E38E4A7C7602C213DD08CFBF9A3AB2 +:10212000C790DEFEF3FDF6B099DEFBF1D85D128EAE +:10213000FF5C6A207B32E9A92C65482E3E5FFC4A91 +:1021400026B4E1FB337EF2AF97496FDEF46826F3E5 +:10215000974EF733890F713D47910F693DC79ECC6C +:1021600067BE8BE25FC06129CA034038AEDFBDC9DC +:102170004FF8BC2159667AB440501946F8DE773DD5 +:102180000490AE8A24934274DEB31EE165EA4B4F9D +:10219000DEC9667E6F8919F52BD161402E26781C29 +:1021A00035C9451A5F00ADE7C8D36377B5E1FBB524 +:1021B0005AFF28DD1D5EF65F4477DBEC5E3B2EE1C7 +:1021C000A324A3DED7CBCAC9E9DCFF46C7A7602991 +:1021D0008E3E5FD6F0B9B15E080AC98DA266B9F825 +:1021E000562C6FD3E03E63AC7F3AC1F1E6CE4D8F03 +:1021F000BF24D3BCDBBEFD36CDFBBC93E785970483 +:10220000FC8E9A847EE9D5AF8EBFF1F8003B797ED3 +:10221000FDF99FEF7F636200C7FFF3DEF16300E922 +:102220006EA1D4FDFE7D88AF4F5CDDEF7C0FCBC788 +:102230009E7F6530C12F7EBD4B1A8E8325460E7D55 +:102240006432F17E97D03EF0F97F14FB2F9F5CC281 +:102250006CAA10DC16B64DD845F260A654984676A6 +:10226000D3D10F8DEB8B5FA73EBEBE3E7D7CBDDF25 +:1022700042823FEE63F22437971FDBBA3F21FC7E98 +:10228000FCF87813B262F47946F7C4F4C2289EFCD5 +:102290004A9395FA5D41A21E5131DF21F03A7FB198 +:1022A00029D49CCBFDB8FD6A7C4E78AFF234737DA7 +:1022B0009E13F519F65F92F55FBC2E12740ED46B67 +:1022C0009783FE53B7E617D8EFCD15A92C17E6DF95 +:1022D000D861253BB7579EA96F9B4F8E3F73798678 +:1022E000D093DD83817998F427E0E62C589FA6D51A +:1022F0004D65BF6BFE05C9E7DB52BD129A8CB05825 +:102300008630F1F5310811BCD79A826CEF39480F4D +:1023100060D966F26659B094CC3D8380E70909BB69 +:102320000A0216AAFFCA1469067C6F8DA73A8BE8C9 +:10233000FF4D70FAC92EBA3C7DED0492A3D5EE395B +:10234000F3E979BD9AEA6EC3FDB658E50D8564FFE1 +:102350005C2E79C9EED5E1A2EB8FF916AF95E03B83 +:1023600038287B55A4DFE297148789E1EF5069DCB8 +:10237000372CC14C5AD75BCECD134C66B2D342AE8C +:1023800009B8D9B75FF969C96FF0FDDF81328DEC0B +:102390008179BF72B01CBF1E64E6F76F80C272FC09 +:1023A0009B10E0FA8D10B17E8AEFFDA1FC7F1ED854 +:1023B0000FD17DFD61EA677BC9AE9F2F7566E6622E +:1023C000BB5A0D05A4677EE9F8C18E08AE4369B615 +:1023D0004012DA57BF243A25FBFDB02BF400F6BBC0 +:1023E0003D797B6A17D62326617FA9D5C147A9BF4E +:1023F0006A067F3396D9C9815F101FFE30458CD3A2 +:102400006071B8493E928145E3BCFF8E8BE99DF433 +:10241000EEF558AF406C11BC8E660A7A53FF062C5D +:10242000778F5ABDDD0A8D7B42F63E40AFCE30F34A +:10243000FB7052E67554C4E917DF7833BF0FFF9481 +:10244000F9FD693D16837EF14D32071FC3FD4DFF37 +:10245000876540BD737991905FBE41E660227BF055 +:102460002F1A7F2184245A4FF33E53A88D8950D8C8 +:1024700007153A3D42642DD15B254090E81EF6A138 +:102480001ED3E7C9E3FD7FA2FA880EB19DEDC1CE50 +:1024900067484EDA83824FB03E83F6E3088297ECBA +:1024A0003554C860C17A12BE28E4AE1BC88E6DAB2D +:1024B000824EAA4F838844F89E4E9046FC5781CCAA +:1024C000743B0314AEEB74FC1550B9BC04425C5E63 +:1024D0000A61A1EF416EF939CEFFD50F40EC675C80 +:1024E00098E91D1D1937DB8197DC6826BBC3F7F51A +:1024F000C4FE426A910E174488E7F4E1320B025998 +:10250000627E010F3B3DF745E1E188834712C1C37D +:102510001B8507CE21E0D107BE023ED314840FCA2B +:10252000A78BA147A27914CDBEA9062F9735E0E766 +:102530007200B83CDBE4E90B97B248C012284C00AB +:102540009F1989E966884657BF2E022E75F933BB5D +:102550004866B8E97208F9338BECD178F9A43FF7F3 +:10256000A5541F97911E7C45E9575A509FF98AAB95 +:102570006FCBC7FA8CC76451AFA8FE451ED667164D +:10258000E589FAA4EA622BC2ABC9947F650DCA99AA +:10259000FC80690BF1E5CA26B4AB715F81A43B8274 +:1025A00044C7A60C709BB07FA0A9C45B84F500D281 +:1025B0002520DCEC526E13C1D9FE3DF036E32A52E1 +:1025C000D302138B70FD850BBAD70A7C560F998FF7 +:1025D000FD3FEAB6B2DDB2CE160C129E90DDDD4DA7 +:1025E000E5D1FD7DF4D8F716D3F3C786829BF40BB3 +:1025F00078E462BFABEF7ACC0EE0FA52941B14FF82 +:10260000C0F92A69BE00AA2799D6F5732944F05F5C +:10261000D93493FD81DF16F8A717C58E8FFB90265E +:10262000D3BC42CF8127B798E03679AC7F368D7323 +:10263000D485F2358DDA051EFA2B571629B5346E7E +:10264000FC7373CA17D72EC37996238D909CBEA6B0 +:1026500028F0351A77B93932A2189FAD4E79C7C61E +:1026600074A1207D927C207EA5FD2E467A24BADEC0 +:102670002FF81539C0DD6BBF227E3DFE9E6B17F92A +:10268000848893F07FA5F383CFA0594DE35FCDE31A +:102690004B3D8B882E3F497FD5F627E6CBE182EE76 +:1026A00034B9B5FCE9CF997F9E324350D2FC6388A0 +:1026B000E1BBE54F2759C83F5CFE1708A5E0FB15B5 +:1026C0004F3EDC4CFE4E39FAFFE4272FDDF373E674 +:1026D000B727495F22E896FFF753CFDC477C7A693A +:1026E00012C7A1A6BD7A389FECA0E98723CD883612 +:1026F00038FAD41BC304FDEB7EC9DF4D67A3C7675F +:102700004AABEE207CAF40FCDB71BE15A6A0A85BF7 +:102710001D6E95E59EF093176BFBF818BAB72C6009 +:10272000B9A21E28A7FD6449C0F23124FC0919FF93 +:1027300011FFDF7238B496D609D21736923727D0F8 +:102740002FA67DDDF250BCDFD173A09CFC6EF28B16 +:10275000719F4B3B8DEDCB63F543023FF98E222DEC +:102760001E960339B4AF5FA23FF4C7D134EF823471 +:10277000B20FA7525C2181BCD4FDE3DDC9D55B8AD1 +:10278000D85EEE94881F2A2C89FB5F57A8C5793440 +:10279000FB7FC5FD12FB712BEE1F348EFD648D5F38 +:1027A00021EC65FE7D94F40AD199FC021A19643F6C +:1027B0008A35C3B6414C7337B59AD88FB14BB77AC7 +:1027C00049EF4F7A70C8CDDF65BA49754316D5A772 +:1027D000CC7FC8C3F655908435FA556C673E9ADEB7 +:1027E0009347F33F9A2E838AF33527F5E4919C555E +:1027F0009F727849EFC6AFFB454DEEE587276F8D99 +:1028000078049E89CF739F2FDF4A783E867C4EF8EE +:102810005BE11A33049C64375C9C15C1B259B3D395 +:10282000731F1A97568F70F1D17A63ECEAAE835713 +:10283000A490BDBCD7E24F7163BF6387F20C7E509A +:102840007C591246E4140FD0FEC69CFC4002B8EB43 +:10285000A56FAB85E1A5D3ED2F1B15F8A395F0511E +:1028600029F6A1DADD761FD15F6806F9932BBE0940 +:10287000EE36ECBDE2851F373BA8BE1E989A8FD17D +:10288000FFA8FF07E610D9E33F4C99786725D6F7F4 +:102890007C68117E8AAABC521863C7DAB3CC201BAD +:1028A000E8B55B5A4AF298E81EE935494E06398682 +:1028B0001E530A320C759777A8E1FDB4B23C437BF6 +:1028C000BA32CED05E0A0D9100AEA7244B7287704B +:1028D000C5836A8B0CED76A4EB30ADF3536147955D +:1028E000E13FA16F836C0F5544007E847430F52363 +:1028F000A39D5516E9607F33E990C51007B09F226C +:102900000EF53F3A7F0D87E1C45F48FF5E9263C7D3 +:102910000E89B893ACC173458ED0CF2B5E90D80E84 +:102920005CF1A199F5C431F0F6E287E4A3CE77F12A +:1029300070CFF41BE13C64BE11AED901235C872D3E +:1029400036C235276884EBC806235C7355231CF315 +:102950005BA71AFA8FEEA836D42FDA3ADBD07F6C59 +:10296000A8DE501FFFD05586FE133A171ADA27ED5E +:10297000BBD9D01E4F5793C32B0CEDF6D4D799AECD +:102980000E205D99501F143FFFDD38BAB030DC4B8C +:10299000863BBDA118FCABF88FF05FA1E525A680B2 +:1029A000DA4CFC78AEF03FB518F13F3E8A7F5DAE61 +:1029B000F6C7A73A7E0769FA1AF93342783F569666 +:1029C000C2F4F2F2F3C70E2940F84F8522DCEFDCA7 +:1029D000E9228E22C9C156A2936E707590FDB9CEC0 +:1029E0001264FF4545B3F00152CA71FEE6D7CAD062 +:1029F000DF8C59679D92049698FD4E0E771AEAC5B2 +:102A0000CFEF33F42FE90E1BEA930F8144FAAAE8C3 +:102A10004DEF335496BCA770F8ABF483E033549673 +:102A20007F1ABC9DF46FBC9F7B99DA24A5E1A2A616 +:102A3000FEA3F319346BD03F1BA192DF1BB935D530 +:102A40006B1A8AF0487EA799FC6F403BDA8ACA0865 +:102A5000BA7F43C884050EF1FEDF932E5E43FD4D21 +:102A6000E89F13DE112E0564EF3540B297E0427601 +:102A70000BF961305BD8F36B4D2ADBA349688F9269 +:102A80003DD25CE5677B79160487D3F32B4059432D +:102A90007C2799D17EC5E7C72F0AAC2C2E118B2538 +:102AA000FAB9FDB8CCFEF774F2A719980A90DE3B8C +:102AB0004ABFD3FA207CA5427110D265B8FECD6D15 +:102AC0004F5EA952DCC903EE08AE3B204006EDC5BF +:102AD000811F14A31C3E6272AF2DC6775F9EFAD78A +:102AE00011648F34150BBBCF2E21A49006862C5079 +:102AF000809EFF2047595D9C198DB3F4473F7A3C77 +:102B0000538F6FEE690C7369717B25A2BBF8B863B4 +:102B1000C4ECAE994CFA6F8589FDCEBFD2E2CA797A +:102B20009E5496F30EE8B6A7F392D9FFBF46C39B17 +:102B3000D9D1BDE67BF8DEB541616F2D3479D95F1F +:102B4000BF25EB238EA3D82513F8C81F4A2BDC25FD +:102B5000E22F7ABC6498742676D6A9F67B4BD6878A +:102B60008678153C3228617C3D3ABECAF08DD9E7A3 +:102B7000F6AD1EA1D7C8CF3FB23EA71A5213CDF370 +:102B800009C7AFAE091E34F0C5750D6F19F8E07AAC +:102B9000F55D437BC4D363A57865E4F1EC59145F1C +:102BA000FF78AFBD94F080F87FBA38265E17593FA2 +:102BB000BE06269ECE7EFFCAEB38DCD8CD78D5F790 +:102BC000FB4EE39B5C8F3446B88CDFAF1E1FD14BAE +:102BD0001487AD64CFDC2EA1BC207F97E485274607 +:102BE0005E001490FD7FBB34CE4BF46EDB1FFC09FE +:102BF000B5F734D9DDBB7C1C1FE1B84903D205D938 +:102C00000DE014EF2FB439D80EBDDE27FCE9C35513 +:102C10009F5D4BF66B2EA47A5106127FFC9EE22636 +:102C20000B4C69ACFFD7661FE0FA7BEB41E48D16D5 +:102C300087EF277F75796AAAB08B15EC8FF5A319FA +:102C400066AEFFFAA2C0FBCC8F8561CE6F2C1F222F +:102C5000E279E0898C203EBC4DF67F58CC7EBC3BAF +:102C600040ED8B33D0DF46FAFDC0AC4E34E1FBA320 +:102C7000F7645C6541BC7F90AC7E42164D8E2FF5AB +:102C80002AF2333FB009FE9DB0E7EFCCAFEF9924B5 +:102C9000F6CFD5274C1CAF0167C456877ED8E69186 +:102CA0008113347F8715ED49A7785E3F211A973D40 +:102CB0006AC592F83F49945F148B3CE4BF8A85FD56 +:102CC000AB97430866F87C8256CE94DAC750FCED89 +:102CD000D8363B90DCC2F915F2B7D4A7441C7F70FC +:102CE000867F0908BCB8D7E17A3DF9F271E23F8FDF +:102CF000847E2DEEC3EDCBE571F5782E39B0A9D8E1 +:102D00007EE471FB4EC25FEF7A0F8978D8C7EBC7BC +:102D100073BC5BA713B7862FB80140B40FDB49ED36 +:102D20004B5F38F20EC5E7FEA338E0F1E1F80BCDBA +:102D30007229C9C9A5A95D1CA71BE393F93D5C2FA6 +:102D4000EF17E5560BFAE2B0D411E1B8DEA9E2F7CD +:102D5000FDEDFFE36F766F29E478B53C91E48A3EA0 +:102D60002FAE638C2F26CEAEAF233ACEC0FCA3C7C6 +:102D7000A1F5FA9FEF5F3746CB235CE74FA097A7FB +:102D8000E9746C4D1CF79FEF13F88DC74FD145C107 +:102D900010C7F3DCE06EC6FA6C0D4E1F5F89FBE1D5 +:102DA00078883299F0BBB4DEE92538EBE30FCE80AA +:102DB000C0CF079867C6587F0DEDFFE6A0C813E89F +:102DC000ED487F22CEB93E85E975E9D36FBDF33D6D +:102DD0009CE5A69F4C2826FDA1BF1F0F6784EF1816 +:102DE0005ACF4249E4CF10BE75347E7C7EE06CE160 +:102DF0007A34A79BF5C2D19DDF09D1FA8E6683DBB9 +:102E000084FCB8F4C95FBD699A4874E20C4B58C29F +:102E10001E63FC2B5E4FB9217035C9113BCA11B23C +:102E20006FECFA7BC32D86F766672937FA585F2B5C +:102E30001B481ED955E1AFE507AAB8BED22AFCB59A +:102E40003DDD6699F87B8F0542A4C7571ECC50C95B +:102E50007E5C8976077B3A05415E2F24A31F949EF2 +:102E6000C06E307965AA57A6056E277849DF98713C +:102E7000DF23B9517F54D797259ABE570AAF6BA667 +:102E8000F17D5A3C10ED4C8E77964340B323B43815 +:102E9000DCFA031C87D0E5B60DE63B28FEB32E73A3 +:102EA000A183FC431987E5F89AA73E0D06B023D706 +:102EB00034A2A4BD285AB7F6E3C7EBE703788D83A5 +:102EC00069BB40C21ADABF7A20D24276CADC177BCD +:102ED0009EC5B26DC28391D5D4F6C54989EC4887A9 +:102EE0006607703198D629DEB30D5F7BAB09F567B5 +:102EF000B2D7024762F4A00339FF4881362FD903C5 +:102F000059BDEDBF25BCF5B78FF3556E40F81C19C0 +:102F10003D40BBCDBB3811BFC7C32B49C36F52E186 +:102F2000AC0FC9E04D82987DB3DD135397A2F02218 +:102F3000D54DF8B746DB959309F297675A12DE8FA5 +:102F40005863EBE183EF19EC8110AFDF6AF183176F +:102F5000F767F360BBE11C86AAC5C191804B357A47 +:102F6000603638F5BEC82EFFBFB52F1AD73FF8829E +:102F70005E9F7A81AF2F7C81E317EA2E6CF829756A +:102F80001736FCD40B7C7DE10B1CBF507F61AF4F2B +:102F9000A9BFB0F1AB5EE0EB0B5FE0F885CB2E6C28 +:102FA000F829975DD8F0532FF0F5852F6CFCAA6CAB +:102FB000073A2B81CFCDA6B7984374CE46AA0973A2 +:102FC000DE384F058E47A7AE07CE57ECF20A3F4AD0 +:102FD0008FD38FA52164F45BACEE6CF2AB77B5DCDC +:102FE000557D038E73220B174FF9FC9CD7151A677A +:102FF000E74CE0FC85B3E5FDC314FFCA85B0379C00 +:103000004B713509C23176E935C11408C7F813751B +:10301000CA2043BDA47BA8A1FF8D5BF30DEDDFECBF +:10302000186F68FF466BB1A17EBD5A61E86F87DCFF +:10303000B602CABBB658BC9407B3D0DECAFBC20DF9 +:1030400076DBF83D05FF911F938B9E50EFB8B88F4C +:1030500074D56618D719D77EAA7C407C3EA1A654A9 +:10306000CB27F47EBF20DE07B72761DC53CF27E8EC +:10307000F81C6349627C6D5245BE69DD4CE147CE68 +:1030800068719B286FA9E36F3CE83F6E33F99B0F93 +:10309000350A7F5287437A48AD667F74B7A08FB1F7 +:1030A00035E6109DC39D293993699C1092B41BDBB2 +:1030B0004335F59CD7D4E9607CCDA239145F6DCA45 +:1030C000199C4DF184DC1A81F7E5FB8CF8A6B42D30 +:1030D0006D29FD90C4EB4C6FCA28A2BC5D1FF83F60 +:1030E00022E0A99F334F8F83EFD89011FEF1F8397A +:1030F00053F8AFFC92F0B7D5CA5D69140F5541A6DD +:10310000F8CB733963CC0C87562FE3A116BB113C67 +:10311000735B81F33AF174D7DE08E19A183ECDF57E +:10312000861582EF4CA9B09AF909DF1D027C1A942A +:10313000F3EC3B5B459E16CB641A1FF6C943099F0F +:1031400021B59ED7BD6BBD2D99CEED7DD664063AD7 +:1031500017BF2B571E4AF9AF5D4F98E6C79E034233 +:10316000ECDBCD59BC0FBBB98C4B8B2815AD048B58 +:10317000680F4B541FB1CA1C874F55A2F6F4DAE40E +:10318000B8E78A89FA6F28CD63BF344DC930E0CBE8 +:103190005A66E46B04E32B85280747D2EF32D195BA +:1031A000A093D06B526835C7517A4C8B896EB4733B +:1031B00015E96BEA81F24E4D39DF9ECF72AAC9C67E +:1031C000708755822EF4FC9FB555D0613CFDB8BC8C +:1031D00046FAB14AC34D228F25F8445FC74E459B3E +:1031E000375B0295E59B6D28F181356E3C3B0949C3 +:1031F000922B1EC17F4EA8077ACF5966E77C3548CF +:103200008719FFD629008362CE23C4AFF794EBFC65 +:1032100092747EF01CC9999D35E2BCEABA35E27C15 +:10322000E389E7859E98D1EA36B3BC0199E50BD2D4 +:10323000C1DCEC52717E88E0D9AEC91B3BD4A551EC +:10324000BB4EE7B3A4E155B1748E72E44517C9B320 +:10325000172C1CCF5C6795AB6FA0F672BB7B35C398 +:10326000B3B088D6ED6B41B943F1C26E01275D5E04 +:10327000C4C3AD0862EAB9443A89E1D89F3EE893F5 +:10328000FFD7E1588A70CC3F7338DABC42DFA6978B +:10329000097DFB5CCEB7F955F721717E265D0106ED +:1032A000DA7155C07596F45198E4CB2605E50BB656 +:1032B000D76AEDEE32214F7438E78925F6CA934D6F +:1032C0000B2083F8DE4D7076125CDF67FDDC512247 +:1032D000E00C10E13C67AA22F8649D15BC148FED48 +:1032E00028777A292E98A768F06DD5E065025322D9 +:1032F000F8CA71F04D8DAB9F297CC74CD1E03B18CB +:103300004ACF06BE9B525205BF8D12F0B13A237CC4 +:103310007EB935D7E25D8D74D8958BF0C6F6D6D7D9 +:1033200004BC7FA8F55F3301B8DE9AB9368BE1950E +:10333000BB288BE478ABB543A57C552BD11F9FF3FD +:1033400014E7BF5C1A5DCF44FE5E88EFAF45F944D9 +:10335000F9C6D4B28083C66B2DB480C4FBDFE64DC2 +:10336000B47F87CF669083C3161BE19A1207C7A468 +:103370002FC9FF7553BE1CFFDF49BF62BF75A39104 +:10338000E538DF1872109C6C657F71101DB595EDE6 +:10339000E2BA0CA1D63CDCFF1D4E6167B595D50F96 +:1033A000780E6A972617428D0E2EB737BA51330121 +:1033B000DCD598C5F58E4699CBF6C6022EDB1ABD34 +:1033C0005CB6369671B9A651E1FE527951157F0F60 +:1033D00036876915DC8E4FC061EE3B5F7EAB518F47 +:1033E000E5AAC906B88F6C30EAAB41B5467D95AE0B +:1033F000E419DA5DDE7186F694822243BD704AA03C +:10340000794A099D8B9A6A78CFE6A936F4D3CFD151 +:10341000B59589EFA174B8E97AC9A9F1F73A6B2497 +:103420008BE2D8CE32C19FEB35F8B56AF04B5680AF +:10343000CFC5D80E49DE1010DFAF65FABE03713874 +:1034400004E1D295738542F6419B2CEC742B887372 +:10345000BDB62CBFFA0D7C9E847A8BF2B6B6F929E4 +:103460002C0FEEF038BD748EB6AD6C859BD7E3158E +:10347000E765DCF82F519C3FFEFC8C6394F1DC8DFA +:10348000F514E7171F9C12FF3DAF46A7951909E5F4 +:10349000471FF9DA9B5FD96FC8AFB46BF9157B3F53 +:1034A0007248D74F7ADDA9E55760B82F61FFA81D94 +:1034B00025F2071B292E1F937F705526FE7EF3B938 +:1034C0002912AFF3E01499DF7359BA81E474AACFDB +:1034D00018B7772967363FFEF83C8349FE02CBA533 +:1034E0001B92030789EE9447847D92345CE86D1B40 +:1034F000282ACB2510F90EEE6FA252E4737AE50B61 +:10350000898618BA73F6F16745DE833EA320FAB1C7 +:1035100044DF3F27FEEB99962D8D03E77F5AFAC9CA +:10352000FF7C3E45FF3E0C7A3CA500BA6B8EF0FB5B +:10353000BC1FF885095E2DA64DB57964E7F92C5EB0 +:10354000C4005479E57D948F5CA3A4B25E5FE395DB +:103550003B890F8F2B4E2FE16363610D59F090343F +:10356000FA59D63F2D74BC26060F7ADE0914A5BB86 +:10357000468733E9DB82DAEE9A18BA583F610BE7E7 +:10358000EDDABEFA20E7F3DAE6FE94F3796BB3677F +:1035900015505E38C93BEB43CEA3424C5E8AF447DC +:1035A00081317F77F2A4A8331C28FEA0E5F9C0631F +:1035B000CCE359647F743D70EEF104C385FE018B4A +:1035C000C2DF13F4A56FC1D77ABFFEF940D5BF2B78 +:1035D0005D4DE77F5B3D428EB682F7CD00D55F92B1 +:1035E000BCAA4CCF8BDEA4F3A46B875B182F6BB304 +:1035F000EA5B85FD2EFCA556CF6A961BF1FA9ACEA2 +:1036000063C6CA6B3A8F192BCF5BE5FA01F5717669 +:10361000C01CA7EF8DEFE7048D7A477F2F29EBD2EF +:10362000576B62CE43ADB7F81D242FD678EE320526 +:1036300062E8F9474A606E5949B46ECD9ACBEFD92A +:10364000737C09D7355B51EACB3279FF03DA019BF2 +:1036500035B9B845D32FA7DAE756ADFF8FB4FEDBF7 +:10366000489F5F14C5CF98516393583E5F22E43161 +:10367000C13C76DEC2B2C0E2D87D10D3F4C205E907 +:10368000744CE1B824B2379A2F294A223CDD3D67B9 +:10369000E0F5E87973BD9F9E278DCF9FDB3C6603E5 +:1036A000FC7795897322CFBA1655FF08417377AD21 +:1036B000A0A7E64B845E1EF388D8475F3A34AEF786 +:1036C000EEDA81ED9FF8FE1439ECA513AE67C4D590 +:1036D00087C6F5CF8B6B1F17D75E14579F1AD7BFBE +:1036E0003AAE3E3BAE7F7D5CFDAAB8FE0BE3DA6FDF +:1036F0008E6B5F1157FFAE119FBEABD212C1311E50 +:103700007F7ABFD3C5DF6F7D553F23FA1E03054C7B +:103710002F3ABD9D2E1EA276AE97E9CC56366E1F6F +:103720009D8FBB0BED2BB287EEAEAD760BFB22B0BF +:103730007AAF461FA41F2C5F15F374E59426B13FA2 +:10374000ECF418E4C8A9F06D820C63BB12637FE649 +:103750009D7B7C9F9A3E439A7E1C78DD3A1F174ED4 +:10376000F1BF43708790F02F75BB76A72AF867A743 +:10377000BAB07A33C9DB56B3882F6BF79D64D0405B +:103780001C070F684A3862227CB712FEEDE4070876 +:1037900079B25193271BC83FC0E749A3825B29AE8A +:1037A0009B7C888FDFC07A5FD1DF16127ECA4B7791 +:1037B000D2F7611B26943DFC63ACBBFE2141B818D7 +:1037C000EDF3896D0AD92C1D4A46129D174A3139ED +:1037D0003AC93F5C53DCE11F85FD36EEFFB0F319BB +:1037E000C4B39C65F326615DB6F49888DEA0D0CBA7 +:1037F000DF9DE13A55F2FDAC953D8D89CE956E9CED +:10380000ED369173985E2B9B557A6F4AC0548EF0BB +:103810001BD90A663A479CA186F9AC4D75B9CCF222 +:1038200065D713C850BCDF9E6C82D767EB6DFBA9D0 +:10383000DA3F3E40D2E2736755EAE3A409D2A01F03 +:103840008EC3C816ADAE6EDB46F78F3825511FFF0D +:10385000C48E05AB0BA3F5EC27760CA77A7BF10899 +:1038600013C9D3744F6AC27B60A6970BF9B96BFD7D +:10387000A2918101E84B267F6D0896855A4934351F +:1038800005CB515A296BCFB3447D0AC10DE12937CD +:1038900068ED1E519EEB79E2C757CADDBA9D38D458 +:1038A000CFCE3F143A071BECC5E9E599FDDB8B68E9 +:1038B0001E739C7687551E4AE70477ACB701DDEF8F +:1038C000B02307C477C66B6C7C2E142CEEA157B8BE +:1038D000A2EB0EAD19CCE7CF432630C46F2DE5C265 +:1038E0006E3D5E6ED2EC9E2FC2F49DDE0E2D8FB328 +:1038F00003226E8AD747F1FCF0022506CF0F957F91 +:10390000BA8DE8B32B6751F5167C6F538B99E3257D +:103910009B5AF298CE691CB28F4EAC7AC54CC1A5A9 +:1039200042E834939D3F8EBEACCEA72B8E025C76D0 +:103930006AF2F967C49F38F16850F8F908E861E065 +:10394000BC511AB89EE0924FA24D22FE91CD0E9C22 +:1039500067D993E95589F4F62DE5BDF6F8624BA9D0 +:10396000E65FC80CDF5BCA13D8E374029FE38D8A5D +:103970007F29B53BF71D0C0FC3EADE378CF449787D +:10398000AB8FD133AB35FA747BFD0AE1707669E019 +:10399000DBF4FEB2AD7F3B40E6A8ACBACDF4FEFD51 +:1039A0001ADE178583B3689809DE7035F51FDFB01E +:1039B000733FC5D10A82B7560FC1F58D51EAAA3DB2 +:1039C00044434AA091C619D51DA97261DDB9F560BD +:1039D000389BD73391C7CBD3D783F450C774E41641 +:1039E000F17B0DBF847F3A97BC689B800FB667F36D +:1039F000FE2CEEECD8F5EF9C8974E1EC4B170DDA58 +:103A0000BE3647E10856A35FB339111C753AD5E1BC +:103A100071ED233D6B2897B920D4FD1CC941FF5699 +:103A2000F74C2ADDA581FBE87D5F87BF99F37C7B9E +:103A3000BAE9BAA15EF838956E4A1B613F653BE171 +:103A40007DC7AA23D51C97D907C2DF89D3877A6996 +:103A500055E2F30BE23E9C49FB8C7632D2ABB2C509 +:103A6000134BAF66CE5785347D126A45FAA5F956D9 +:103A700009FA0DA92BDC89E8EC414DAFECD6E856EC +:103A80007F3EAA9F73954F97EBDF9343966484E73D +:103A9000D303F17D1A78991F900FF653BF0CE20300 +:103AA000AC8F5C25333DE87CB06CDFDF0E0C637FB0 +:103AB000522EA2FBD9F4795FD2E645FA7C91DE5F03 +:103AC000B6B5E700F98A235709FA7C95EE06CB8C48 +:103AD000D219FA8FBFA17E3AFDC4EFE3D71A5DB8C1 +:103AE0004BFDAF121E176D0DF278C83FAF31FF6C62 +:103AF000ED0E2731CB29D5B49F1D1DE0A6FDD8BF03 +:103B00005FD44572E1448389E17A5D61788D19CB98 +:103B10006B468195AE13AACB42B2C9A33CAD31EF3F +:103B200037BAC3883FA49F3FD23C259E804D04AD49 +:103B3000833696A7FDD04554EFA93AFC57C5C9DD99 +:103B40004F0694BBA739EE774B954F699CD35EC760 +:103B500069F6D3E34D7DE3A6E39289AFDB5AEBF53B +:103B600038552DDDB7B38BE2A608D735AD03DBABF7 +:103B7000218D7EB76BF47B971637EDD0ECA23B4ED0 +:103B8000376EBAFE5815FBBFAB80E340AB53269AA5 +:103B900012D14DAE6AE4CF910DC9717152A3FF9A53 +:103BA000AE18E3A6F49DE799C44DE3E3A58553025F +:103BB000E3A796F48D9B42E45D839DB9A655C805A5 +:103BC0001D7E636A6EE2F8E72E8F3914FB7D845EFA +:103BD000B66B70D3EDC936821BC3B3408B3F7B35C8 +:103BE000789669F0ABE5FA18B2E23C1C471579F714 +:103BF000B177CD5F4870CC02CE1234E53C9895E8A1 +:103C00007C3D64C5D8D148FFEBD66B79B42CE0EF8E +:103C1000439FCB79BD369FF29A59668ECFEEF2EC78 +:103C20002FF831D79399EFACA07614E07C63DE9B3C +:103C3000AFD27CBBCAEC6E711F07A4521E48CF4B9B +:103C4000E8F99CB64C91CF711568F99CB8F9ED7004 +:103C50007D7507CD5F20FC977EE9D9A7E523B43CAD +:103C60005046A1315FE188CB57C4E72BD7AD5FB891 +:103C70007F9788B3B09C1E73C3D864BFABEF3CEE94 +:103C800039463F6EDD58DD9F7AD091089EA93546B2 +:103C9000BA6CD3F0DE9C29F211A71A1F2A930DFEED +:103CA000555BC1E9C513F47EE48FBA13F48FF7476F +:103CB000CFC6CF75F3F8C63872023F77C354115799 +:103CC0006179B26EBDD87F6F5C4DF3AFF47346FA85 +:103CD0003856CD9FE37A6E545EE9F9B0516E1BFB06 +:103CE0006BA3B47BA19AEF4D09ADCEA5FCDADC1E27 +:103CF000CA478EDA2D71DE7D94D33F94E2AA5DF738 +:103D0000CCE2FC78767260C7D498EFE076BBBE9DBB +:103D1000C579032DEECFF7E3A0FE533715772B645B +:103D2000F78E05BE4F27392E2F107F0F4E9FFBD8E1 +:103D30002A841ECBBA1A12DE6FF2BBA9426F46E587 +:103D4000AE3F59F8F1B3194E0F74D4270BB9ABE855 +:103D5000F501FDE073256F1FE87885BFEB39E103BE +:103D60004DDEFE0C2E4479FBBBB2C05B09E5ADA570 +:103D700087E5ED235394B709CFD7D3851E8487EB0E +:103D800012DFC3E3AAB850F1F098C043A18E873B7D +:103D90002091FF7801E021B922111ED0BF2278A91D +:103DA0003E25A52293E2A68A93FAF5E2E3EB89F990 +:103DB000A2E23CE36393868F3BB5FCED460D1F1BEF +:103DC000081F76CA570A7CACEB838F23021F653A23 +:103DD0003E9E3E2B7C64D46418DADD95467CA4FAC2 +:103DE000F20C7567A1111FC9A38A0CE35D5F218BDB +:103DF000FB90864F35F4EB8B0FA35F10A0F706F016 +:103E0000B38607BAABE81BABA1F33BBB483667F9F7 +:103E10003BAAA8D4F7B92DCEAFD3CBEB35FC65CDFB +:103E2000488CDFAF69EDFF2E57E656C4F2E7571214 +:103E3000F3E7E59A1C0D9429F30CF47369E2FE573D +:103E40006BE37F7D8A72556C7FFCD92CC5D8E5FD6C +:103E5000EDFB8664E57A7A2F6B86CCF1D4DD4DA933 +:103E60009C3FDB9D24F2656A93D3703FDD48FA0DD9 +:103E7000EB59DFF8A24BA57376741F105A583B6FAD +:103E80001D9CB70E9B76668C594D70FC56453EAF17 +:103E90002B7F89FF6DCAF328EA51933887B480EFEE +:103EA0003532850799E83E2C70679C561E09E599C6 +:103EB000B8BF6D2488EF8521C87A50F2433A7D9FC0 +:103EC0006C01BFC89B537FF11D216F3E05C25C771B +:103ED0004184EB699ABFB7AE2297C74D07D92480BA +:103EE000E435911CD5F9D4E10932FD7B1ADCA6D565 +:103EF000E4D3599057C91F740EE7EF76A11A54CA3C +:103F00006B99C0C1F6A669F381CF395FA77F67F8C7 +:103F1000C220F19DE169EEEF74FBB5D0FD7B9EE818 +:103F2000FD7B2D9A3DA0DFBFA75607F93B7275B503 +:103F3000DDDDECE9FB1DF9E6A9819D44877F4F1A81 +:103F40001112C9E6E0947AD7391DFFFF9CE7F19F73 +:103F500038CFE33F47FCD0DFF81BE8D772CAEFF950 +:103F60005FA07ECDAE52B63BF5321E6FB3D1FFA738 +:103F7000F54A8E5787BE37286ACF390F9BD82F6AEC +:103F80003689F367EABB26B6BBA050D08153868240 +:103F9000DC49D1719CDEE048117F127198A6DFDF09 +:103FA0007E11D9DF3F4C991B49C3F15E3E28EC3F9F +:103FB000CB8CC836BAC779489ACDBB0BF9EE0E6DDB +:103FC000BDF6F22977DE86BFD64F376BE71CBC976C +:103FD00014F1B9A53911B21F5DA516997206CEB8B4 +:103FE000FC66BBA583CF19B7EFBEAB6A1CD039E521 +:103FF000E7DD2DD6BEFB746AF9CDB1526239F89770 +:104000006949422EF98CF7061FABD0CE41A5422A52 +:10401000D991967F2B6989CE05E8A53E7F892752E5 +:1040200043DF5947E8B236C47349595D52B287CF6E +:104030004774137CABBD6107D9BF0F2F0CDE14FB97 +:10404000DD797B19B8C88ECF9D2ECEC3DEA3482E56 +:10405000BA47E3BE8885EF17BF6FC963EB53B0BEA5 +:10406000EFB0D94DF068F7BFEB4CC6FAC3382EC994 +:10407000BB97778B7B26D505101A8DF06B27EF1237 +:10408000EB7B15E073C0EC90956A57F221FCDFB929 +:104090003853C01B8275743FE7A6948BF9DECA9C27 +:1040A00079222E3C4B3ADC45EFDF576667FCE56B27 +:1040B000E7754C6A1DDF5B99B9C0785EE7BE95DD98 +:1040C0002AE1D75D6E77D33958909CAE89F8BEEB64 +:1040D0002766905835F6F0E4B324A75897579CA369 +:1040E0007B580EAB74AF7126BED7E4E6DB110DE74B +:1040F00082F66E15FE69DA64A717291DD71B776E45 +:10410000485F5707AE8BEE37768DE2B844C63CE386 +:10411000FAD2E2FC06675CDD5BD97B5FCF18C2F7A1 +:1041200071FFB78B5FE556AF9CC8FF6C6F84EE9A4A +:1041300098F309CE7EE281975F2CE8DA96FDAC8396 +:10414000EC94E3FED73D848397FE75E03D3A2BF770 +:10415000D2BF5FDCB31CE1F39BCFDFDCFD28EDAF0A +:1041600061C32B44AFBA3FC66730713DCFD5D91874 +:104170006EFE5AED3CA7AFEB59AB8FDB39CFB47174 +:104180007F12B78FAD845012B68FB528D9DF24BA0D +:10419000EB96BC4D320D22CE23EAF8DF78ADDF047A +:1041A00013088F7E89EEBD9829BDA4B8F0FD7B96DB +:1041B000804CF8B72DE9E4F3EABE95E2BCBA4FA90A +:1041C0004BE2F3A6F3CC7C4EA4A9EE8A4B46637D6A +:1041D000CF25E21EAADA95CA953CBF22E825ADBBE1 +:1041E000D4BC92E8325BDCCBA49F372D811EFECE7F +:1041F00063ACB7B3CB46F266010298D6D7AEE14BBB +:104200008B1B94F8BA55B2275D5E231E33E2F0167D +:104210008FD79B743C8E85B18447193A92491FDE33 +:104220000FD049F707DCB3F2B12BE95CDB71358DB8 +:10423000E1D51F3FBF83F6AA7211DDB7E2E0B21BE2 +:10424000ED552AF7A0BD4AA52B5875F54A5CF7E352 +:104250006FBCFCFCD771BAB94ADDA57C544BCB7F4F +:10426000012C1A518D70BD96B857D4B72BA300FE00 +:10427000E0930CF58D1E4BF4DE7FFCD595ADFD1D56 +:1042800000F5C4764A40B66759B47C9BA8CF253F59 +:1042900024A67DEF1C63FF8AFD31E357E27A97DAAB +:1042A000B87D63E5A2EDEAA868FBC7D3B03E1CE089 +:1042B000A0663F5EF380D9BF2B817C7BA952D87169 +:1042C000967F834A72ED5319D8BF97CC0ACB77C833 +:1042D000B3C889EECF03407918EB97CB46F95AAAB9 +:1042E000F185C55F055A9E0CBED0E30FF8F3F8EFD9 +:1042F000E6F2BD4B6BF22D7CCF10EA03EF40793B29 +:104300008BC7F297D8FBB97EAAD3C168184DF37F4B +:104310000A95BFAD623E88B99F01D73DA3E399617D +:10432000CB711EDFE1648EA74AAECD29344F4B63BB +:104330002BCBF31F29813D9531718A96F445C52415 +:104340005FF4F332D1FB8DAE309FC9FDF65D75078A +:1043500080F4C2A7485AF601E8B0A571DFEBB48E2D +:10436000B58D9D5C3ADD0A0B1BBB25C8719FD94AF0 +:10437000E0C5CA12BA570FDB63F8C4EAC6F70C7E71 +:1043800087F1DE4DD91D7112DCEF29FBA393E66F97 +:104390003F24F8FA9E43F57C8EA1DDFB4A12F1CD55 +:1043A00071BAE0F14BF0894F39C8326CEF1BA9D7D5 +:1043B00010FD3CDE9CC676C5CB2BEFBE8AF8E7BA73 +:1043C000EF5FCEF0EEE51BF5DE11D585317CA3DE87 +:1043D000CB74DDCB375ABD7FBEF944F0452FDF8863 +:1043E000BAAF100CF597E718FBF7F20D8D8F7CF143 +:1043F00070959DDB3F7DF25E03DFFCE1A97B8D7C48 +:10440000F32DE49B0472BF789A46DFE7986FFE3184 +:104410004DE3C7F3C437E9D3B473B55F9E6F864DE0 +:104420002B391F7CF3B8E96CF866585FBE993CEDF8 +:104430002CF8A6DD1DE67375EDF3CC09FF0E487769 +:10444000A5C0FB8C0581EA0EB26B14714FDF4C697D +:104450004EB6CF437C26D15DD1A83F853E7FF99AE9 +:10446000DEEF33583FFB353C6E2684929DB454D02A +:10447000CDAB8D22EE3B5372CE5C4A7A97BE23A021 +:104480002BE3E698B8DF65A8F765B20BA1D3948952 +:10449000F3DC83EABD43A62D07EB46F3F861B6CF04 +:1044A000F2B53C80532A14DF3329E2EF5BE8DFC525 +:1044B000CC9B63BC4776C829EC261C2085FC18776A +:1044C00099F87B2757EAF4D3AB7FD10EC1F5750F6E +:1044D000B7319DDCA35C36609CA8CFF96A5F306180 +:1044E0007EF2C0349320464559342D93E4CBF664D4 +:1044F0003A2FF1B8047C4E6741F0E75712DFB95408 +:10450000216FDA57FD89D292B067E6D78D7A5A8D3E +:1045100018F5B41A31EA69ADDEAFBC81F78D7A5A6D +:10452000ABF7EA69ADDEABA7B57A54DE440C7A7A14 +:10453000F55391ED6A4CFBCB54AF3CB59EEE9A76A9 +:104540007EF4F490F3ACA7779C3B79F3F0F99137C4 +:10455000AF9F95BCC9E92B6FFEFB6CE48D6B5B973D +:104560004AE99945FDF0C137353D73A042F9158DF3 +:104570000F65A717AF89A7AFAEBA456BE9EFC77C48 +:10458000EA15FE5F7FEFBB1A7EF17A4B8C1FAE7F80 +:1045900097E06A789C9FDFB8ED20C7634FB95EBA99 +:1045A0000834B3AF5E45BBC8C1F4EB35734EFC6C49 +:1045B000D7D13E4FF05BD9B4C5CC4F7FD7E28FF156 +:1045C000F66F579DCDCCF3950939DD9F3DD4DFBC07 +:1045D000DD95B2E1FB0C7DFE78FA45FAFC37C9297E +:1045E000A4470BDDFF7DBC1BF8EF51FDE7B12DBFEC +:1045F00056E40B4A2F7A283470A6745AACE133C1C2 +:10460000BE732E2E399FFB3E67FC597C36FBEE9A1B +:10461000067A5C3B7EDF95E777DFE7CC7FA8BFF8C3 +:104620002CE4D24B95BDFBE6EF5232B47DDFF3AF05 +:104630002BDEA5B8C63DFFBEEAE714D7B8EBF38280 +:104640009D14D7D0EF8F4B83E88FAC7F1F8970719B +:10465000F9C5772519F362BE2F02F6EFA3DF9F900D +:10466000BDE1EB6DFF7F727F1CD9274712C4197B18 +:10467000DB6DC6B89E5E4EA53FAA85F4D56EDAC442 +:10468000F1887BD0AF6A42BC75CD13F18876B45304 +:1046900058EECC2B1AD03EDAD3A870DCA9BDD1CF0E +:1046A000E59D8DB55CEE79755905C95DDFAB4B585D +:1046B000EFF9BCFEAB7F8C407257BDE7A4E7777A79 +:1046C00074FB44D82F6964BF60BDE3E9B61DB1FE39 +:1046D000CD90E939AC0FF4785547568CDD23C7F8F7 +:1046E00051582772E9F5A3A83E2AD6AEC9613F6AA0 +:1046F0002FD93558BFFFE91C835DA3CFB3D10C8BF5 +:10470000C9AED9B8DB5C9BC8AEA9A84CEC47619D8B +:10471000F3200E9783BFFF97B4BFF315E59781EDA4 +:104720009AB4E9E7D78FFAE5C5E726FED0CBC79A5A +:104730003DF323457956932B5F527E6C3153FCF841 +:104740004CE5C758921F8506F9F1F6D9C88F8A4AF9 +:10475000B7212EFAB2AC0E9A4876FA6E3334C99A63 +:10476000FEF5907E05FEFB77DFAA92D8CFB9C70B86 +:10477000FC77FC66490B5E207AD8BBC4CCDFBBDF7C +:10478000A7887322F7CF13E7AA7EBCB2A89E3E2764 +:10479000DA9472ED86248A6B575A80FACD922A39C0 +:1047A000CE7D5FADB073729C9D97D0FE5FAEB200C0 +:1047B000D1D5A9E2DC146EE778B57E9E4ADAC67ED2 +:1047C00087EBEB16379D5B8D8F5F3BCBFECCDFCD50 +:1047D00083F4127FDF7DAAF8F599C6ADEDD37BFF98 +:1047E000CEC0D9C6AD991F2FBF38E75AFE0E218E15 +:1047F0003E9FB958E64A7F7A2C9E9FBBEA66A54544 +:10480000063817E524FB29E6BE58A725CC7454A129 +:10481000D9514EB29F8AA374D155573AE0FDB329BE +:104820000D4FBC1E9B174AB174F278290D4FF2F35D +:10483000CD747E81F665F1B25C7DB81AE57382F1C4 +:104840009E6C0C1E22B8FCB2B1E110C5A9A759BAE2 +:1048500025FABBADFB1A55AE3FDED8CAE59EC60EA3 +:10486000EEB7B9712B97773586F8F99D8D0F717D6D +:10487000436327D71FCE13F34CB584789C693D382A +:104880007E0C3F547C80F3C4E0B93CA21ADAA7BC8A +:10489000D96A682FE9EE30D433FD5B0DFD07D5866C +:1048A0000CED072A025F9D9E49E71A1E32F473162B +:1048B000761AEAA7EB2F9CEB7EAB53522DFF447E7A +:1048C0001D11407A423A4B6F9055CE9B2F167C3982 +:1048D000A4C11BA6FA76978DF95BA74B3EBB6C1261 +:1048E000EB37C5DC47DBE5B2B1BC68CE14F194E62A +:1048F000EF88FAF66C715E724C8DC88F340F17E733 +:1049000030F53CFC7697C89B9DF0897B3446144675 +:10491000F8928C11DADF7D73568AFC991BDC9C9F20 +:104920006F6E04ED3BC508E73B32C0EC15F7A82BD2 +:1049300032FFDD240B849A70BEE642B77A23C99910 +:1049400060AAD7ECE53F211B32531E91C4132761A7 +:104950003A35BDA3E5E593FE087CEEA0173E9F889F +:10496000EF121A7AF87EA6210D3D9C8FDBFE7D7139 +:104970008F4D3C5CBBBEFF19DFABB4E33B9F6513BF +:1049800053EFE83DB7D363F82E6DFBE254BE6F6181 +:1049900047431E9FA3D8B1587C772C83D8EFF625C8 +:1049A000363E87B1A3C16C263979628925A4C33B01 +:1049B000A49F5BA1FF158041BEE8DF73DEA59DEFDC +:1049C000E9D0BEBFBA433B6FD5AE9D976DD3CE5BEA +:1049D000B56AE765D7D2F91E3BE919859FEF68589C +:1049E00021CEF70C07ED7CCF270C670BC299E2387C +:1049F0003BACB0CF3409E80F1732FCE2BF971D542F +:104A00009B1C77CECA78EE2A2DEE5E2197D778EEE2 +:104A10002AA5605CDC392BE3B92B7B96F1DC95D5BC +:104A20005D6D3C271A4BA70854D3AA2D4D4407BDF2 +:104A30007FCF911E0EE6BF17C7FB53280F85FBCA19 +:104A4000AA15743948FBFE259DCE85E493FC0F33EF +:104A5000BC5D44AFF9746E44E57A92F6FD9B7EBE70 +:104A6000A43F3A3ADBFBFEA5D589EFFBD7CF1FBCAD +:104A7000A1D94F0BA62BAF4F2F89CEA74E57DE8C57 +:104A8000ADEB657FF2E0FF9789CBFF0532DED6778D +:104A900000800000000000001F8B080000000000E4 +:104AA000000BB555CF6B134114FE36BB69923669C6 +:104AB0001649B5211536C668031122A6A59588D3D7 +:104AC0001A24875AA2F4E0C1430E39F9E3EE6D537C +:104AD000158A92D218C173840A160AEDA17F40AAE2 +:104AE000C1736AAB281609B5F42CA87829C437B36A +:104AF000D9264D36B5170792973733EFCDFBBEF762 +:104B000023CF41CB0F4462EC9AAC0123895AC549AB +:104B10003214072B4581E92A4937ED2F1A526532A5 +:104B200029808BD98434F574AAA62864A7B6D9A5A0 +:104B30000FECECE2DE18B71BE05211F2DCAE13F022 +:104B4000016B49A9F42C08CC6DD0791CF83D269551 +:104B500010E4C1EDD7EBA3C21490F917EBF79F0453 +:104B600066F84F7AAF7FDC379021FF0B3A503ECF8B +:104B7000EFDCF172DD9D284C6A144764AB0A85FCBA +:104B80008D54A19E00C7F78381F6674F5F97157A12 +:104B900077691E3845FB73F65AF22EDD5B1B77A84A +:104BA0008F62DCCF94FD019D4F0764C85C4FDB77BB +:104BB0006A142A2448F533C44F4231745A75FADC1A +:104BC000448B4E714F737DB8A97BF743132AC5F50B +:104BD000703BB852196EDA852814BE7F89797C7BC8 +:104BE0007DB41141A42E3771D4F9BADA29FFE8DA7D +:104BF0004AC5CE71C2C6F98A6FD94A417AA7FF6306 +:104C0000B197E393AB69B946F64812EA71C2B99518 +:104C1000F6E2087FDF387F0E605B770A59D55521B1 +:104C2000D7F44121F7744DC85D7D58C81D3D2664F9 +:104C30004D1F1312C8897C3A2488F7DEE8A9CD6499 +:104C4000B8FB7B1129778BE71DAF14BCE6791E8A70 +:104C50000BBB8E7B25F2D3C217D1258AA1E279390D +:104C6000C1ED5FA46C70907D31A1F9D3D14EFBE210 +:104C70008D492F2CF64D99D76F6F3EB1773F77F75F +:104C800020B36A61FFB851C74041C41148D8C0EB96 +:104C9000D7EF844BA5FBF97597A8EB50CC597271EF +:104CA0007C7937BE9B38A87E16EE1704FEA54545D5 +:104CB000A59A3AF0EB89513C2D7515606F0779DEA6 +:104CC000F257CA836992C58BEF3F9F25BBDC868C68 +:104CD000303AE37ACA241197892BA0AC4AAA45DE60 +:104CE000BBE1BAD7B0C790CF980B6DFCB7DF37F3F5 +:104CF000CE112AA38D16A595EDCD2C30DA67CB9277 +:104D0000E0C13504D1DF3D60658EF718F101978968 +:104D1000E7F24826E76EC6D32D4F661C7D8DFAF369 +:104D200067355786E7E11F75E8B61BF92A646DA958 +:104D300092451CCB8D3957601F9CBC1F11B58EC38B +:104D4000136BAF53239E7985FCF3BC31F26FC1F72F +:104D500057CEB751CF5F646A81E2944DE33DE421C1 +:104D60006E183DE59940291714751E2BD3F92FD6DF +:104D70001313EEDBE643C7FBACA58ECE74CE9D7558 +:104D8000E636E64D18613E6F7E0ECD78CB16F96D96 +:104D9000F689C1A339773A79D40C9C590327A2D656 +:104DA000FDDCCCD76C63A823231FAE9B4F47D54DAA +:104DB00037FEDBEB603E9BF696E9FF01EF5C9276F7 +:104DC00081F371B8FFBAF1D6CED3DE7FE6A9FDBC80 +:104DD0006ACE9563E23CEE3D53FF0BC81D4E69F071 +:104DE00007000000000000001F8B0800000000000A +:104DF000000BFB51CFC0F0030977F3A0F2BFA3F182 +:104E000057F1A3F2CBB851F99E68FC2634FDE7D1E7 +:104E1000E4591820B4033BAA38B15888838141165D +:104E200088353850C5F3A1E656012DE805E265AC9A +:104E300084CD7A27C5C0F05F9681E12890AE06E266 +:104E40004B4036931C0303AF34038307104703F131 +:104E50003B190686A940FA25106F9086E8E3048A7C +:104E60009D9421CFFD6D42E4E91BC5D4C1B7955097 +:104E7000F993B51918AEE93030A8E941F8E791E4A3 +:104E80009D806253B421EC70550686BDBA0C0C8728 +:104E900095B09B1B0194DF07948FD0C36FBF831124 +:104EA0002A7F8B352AFF8B212AFF9A272ABFC11B15 +:104EB000955FE103A10157D509D0D8030000000098 +:104EC00000000000000000001F8B08000000000030 +:104ED000000BCD7D0B7815D5B5F09AC79933E799BE +:104EE0004972028710601283440D3884F0147512E1 +:104EF00082C6368503A2E6B7B61EA955449023D2D2 +:104F00009AF6573379125E6D406FE5F779A0DA5261 +:104F1000AB357AB1F5B66A9340BD784B21526B6DD3 +:104F20004BDBA05EB55EB5D18ADA5E947FAFB56724 +:104F30009299C34988B5FD6CBCBD9B3DB367EFB585 +:104F4000D75E6BEDF5DAFB285002FA2480E3F877A0 +:104F50002EC0E92200CC1C2AA373A04CAE04D8209A +:104F6000048D70312B3F94EABBC2EC1D58F1A55360 +:104F700087BEBB04046AFFB3E2F6783F7BDF31F9FA +:104F80005B712867ED2708D4DE69E79457820450E7 +:104F90000050DAB95C4DB07E368C6B56B17D87BE61 +:104FA000AD1ED878474B159070BCE2ECDFB73702E6 +:104FB000744F01381736AB2531567F4E323642B624 +:104FC000718A691CA7EE8F8BD05D06F4779CFD6F0C +:104FD000C3CD4948B071DB267FAB1EE156BAAF01A5 +:104FE0003D02F0957149D0D9F3E920D2BC9439162D +:104FF00098ACAEEA56DC9A7AE2381D889772ECB526 +:1050000033BE3432F47C898317868F0CBC00CC030A +:10501000D0A0A2DBC27A00E8FBCC7E4D7B7C2D3E8B +:10502000BAF14F9C3F1F7F1AE88407503BE389C8C1 +:10503000103C1B7C03DD12C3B7550CC6FDAC490EFA +:105040001BA7CAD54FE67883F3943B3DEB3F15E1B0 +:105050002CA07908B2ABBF4C7866D9ED66B19963E4 +:10506000E9CC2B673E1FE764FD7F06515C80ED3B7A +:10507000E356C4458FB2E5C17BD06EAF99DE76C3EF +:10508000E12784F89989F8B1E2488F0E1D4B61BD84 +:10509000A996CDA7C082012997C8C6843100F9F826 +:1050A0002FF689ACE95548AF634CD696BD1F1BB3AC +:1050B0009A24F67CDCFCB420B332027769AF84001A +:1050C000A1293D4E1F599CEEBB6674F433BA3D0ACC +:1050D00091CE8DAC6C9159BF88B7C391F4FD0CA4EF +:1050E000A6B353F7F6B37AC492A1B992C6253EBCD3 +:1050F000513ADDD8C8487AA34DFF1D8D2A95ED8D14 +:105100001A74FB015A1BE354DE1EBAE5BBD87F8339 +:10511000E5D7FCAC94BB6E7818EB2D00091C2F1260 +:10512000E3FD83AC6AF76B580713F11E29E5E5B37D +:10513000881706E7B71826112F3FB6F1A44337F1B9 +:105140006B8BB13407B2E0D32943655E3E0BE84177 +:10515000F6E550DD1FCFF3D47D5AA1A73D4011E104 +:105160008DEA4C54AC10B83C8AC87D60209C0C5F22 +:1051700059E5822D572469FA40379B5F78B662EC77 +:10518000649F6E11BCFC354EE0F4512EA854C660ED +:1051900060CF71C48B21A637B2B182D34BBABA6348 +:1051A00038A6624C66EB18F4A5B5BC2CFC0595F24C +:1051B0001BFD0EDC259F3E7E24A92795C832EEBB41 +:1051C000F6FA9D7BECA08AFCAF4E1713E97284D7E8 +:1051D0004AB0C9C3665D1671DE9F1EDC23AFD711CE +:1051E0009B9FDB41A5F632AE57E5D07A75186CBDB2 +:1051F000907F2AF97A75C8963A9AF57A00C0839713 +:10520000D0205EBA385ECA3F65BCB4F4D627B2CCB3 +:10521000A3DD5E4F190CA38CF0A0E808E7E6264E4C +:10522000B716A3DB6CF277383C483987E3C9F21331 +:10523000F17EB1C0C75960F38983A70D86589B0ED4 +:10524000239E3A6B516E6D2E1545944B9F169E1CF6 +:10525000B8360EC295E670957DBA7049A1EEFA6C2B +:10526000FCD89EC18F9B106E4E77B59CEEC44F95B7 +:10527000EE1CB802C80F7C9D137C9DE57F89756E7E +:105280001F5CE7245FE7F8A7B3CECE7E0EAA518F4E +:10529000EBB642637CC8E0B856B2942B707F0D0920 +:1052A00070BFC1E800E11FC7F4CC70F3F3BA0E7011 +:1052B0009B10E0FA8674594ED205EF0A99E92C1535 +:1052C000F87CF3A9C911E60169DF40BF0327E3DFDA +:1052D00086C34DEBF7BAE0BC5988C408CED9301B61 +:1052E000E17C27BC34A71B86EFEFF546B549F601F4 +:1052F000BCDF68ADDFEB3BF1FDB512A4B2E99777F7 +:10530000DA7201D42E85E67F13E3C1E98887536BF7 +:1053100020CAD623DC3C06E70161F6722EEB675704 +:10532000A04976E177B8F90CE2D5F98EA93BFEBC2D +:1053300013BF1FEEBBBF09C97B0586DFB698588334 +:1053400070A9A590C635F0EF5AD25D08C3C3DB162D +:10535000FBC7C03BECBAD9EDDE0937B733D30B5AE4 +:105360007CC63E9DD1496B816834C3101C0EBD388C +:10537000EBE2E071B4EBF2C741FADA7C1E909E09D1 +:10538000BA34FD93D3D53EA4AB33FEF974F5CABF4E +:105390002E5DBD2E14FCEBD295D220E92F333BA31A +:1053A0005836B99CD4965BB4FE3836934B52E7F42A +:1053B0006E94971067F6191F064456573493EBBD49 +:1053C0006000EAAF6AA9574EFA8ABC72325E6F7605 +:1053D0003BFD6ED4715C85C645F308C795C3D01DEF +:1053E00088625DA17E909C8F9FC2F00477D696F074 +:1053F000EF0CFC6EB8F9C8F81D1B0FD58FE3C5F88C +:10540000DDE7731259ECDEA1F97BC7892F4BE42449 +:1054100022A36F0F61597FC585F7E1BF93E115079F +:105420002F8CFECBD04F5230847F73D7F5E4BF086A +:105430008068905D57D46EE1DBF5F8FFE6E2BECF01 +:10544000F97A7D518586FA16B0FD069F5BC2570139 +:10545000EB7F1374E25B673C299C00A21BBBDDC998 +:10546000D6FF46E4A72CFC7D99C8F58DF76F49FD62 +:1054700019ED416BA3A0DFCFF07AA0F1037889F199 +:10548000E5F2EED314F47B5C2E8EA176CBE7172BDE +:105490000B5CFD2C076E1702F4CB4B22EE719BB810 +:1054A0001EDA25F5E2BC5F9C23A571FF7B71CE5F00 +:1054B000483F7FD194D288E4173B2ECC1949EE1C8B +:1054C00068E4F6ACD3EE8029D1FE7E40EE0F67D3C0 +:1054D000E387C64FD3F88BE748DE7D5AEE9771FD20 +:1054E000DFBF197CA83F1F685485972633E317E771 +:1054F000C9E868F99C6205FD0E279BD705B61FCC4D +:10550000C1AF33CFD6B048F36C0D5793DFAA557BAC +:1055100087ECC7A3EC39CA83E1E075FC56ADDAD25B +:10552000ACF850225CDF527CC9ECF6A63D5FA79E2A +:10553000E9CFFAA4F0B565C0D71EE67A56BB9CCC7D +:105540006E4F65C0A3C4448F9C885DD625E03E376E +:10555000168C67A614131A0FA1FF64822D7BC61E3A +:10556000FE4DD3D50CDE0357844D218EF5DF091394 +:10557000199C5AA1043E56FFB7656B7B7E8FFEBD1A +:10558000FA10481A836BD96D4D8C5C61FCCDF7091C +:1055900058DE8A76210A5EEBCB4DE8B76AC54EE746 +:1055A00001DC257EBE0AFD6A327039C0A49C2E8FB4 +:1055B000417F0C9033663879C0FE84E3FEA1EF860C +:1055C000C353C4964F344F924F4B47964FEB78FFDF +:1055D00016FB0FE5CBF8A1F1E8FB712B14CF3A8E47 +:1055E000CD78DF6BD3A11F96FC53C729848A00EACC +:1055F00023913A514B637BE8CA45BF536C950CDD50 +:105600008C6E0A2B3B059F7E72BC333957CBFDC491 +:10561000A6E0E6AB5FDB7268E2D79F1304F4F31AEF +:105620004C859F8EF586E9D9F8E1DF901EFDAEFA34 +:10563000B26A01DBB5327A2A4539B64C243BF7D63B +:10564000BAA5B9EEEFDF131DFBD8597FD0E5595845 +:10565000E7EB2FD7896660DADFBFFEF2C75CFF8217 +:10566000758A872F3EEEBA88686B149C7CFD3FE9F3 +:1056700038CEBA9DC81F4DF6BA9506509E6CABCD7C +:105680002EBF865FB70A01F7B7581D98E92CDFF9DE +:1056900025C123679D528514186C9DA5E724D24F20 +:1056A000A4B1B3EA77C0F0E34A3125C35EB3FBB3DC +:1056B000CC3DA56CFD3F07CE5F9F8C72A62E2EC100 +:1056C00046669F41A5EF65B73F84ADF0509DE1FE72 +:1056D000CDAFEDD97B37FA97E6FAC95F9AF9BE0EDE +:1056E000EB2E7AA891B8FFB4F7B15F9F2AB0710E84 +:1056F0001A7EDDCF1EED17FA5E213F6F9544FB2F1A +:10570000C2A7CEC2EF81949183A664D6B0F67D95F0 +:1057100002ED9B7E78F68BFF97BE0F517CA36FFE48 +:105720004BDF388B7DFFB9B37DC8391C13F83D932F +:1057300095807ACCB1FE6F9CC5DAEF3F3B7F44FD8C +:10574000AA0EE7EBA293C54F78EB9722BDB1F5E81F +:10575000FDFDAB7577B2F10E424EC28FE51C0EDF38 +:1057600041840FE9BEFFB7AFA01E78C014C8FF7414 +:1057700070CE2F63687F579902E9878BE60B697FAC +:1057800096792E9A7FFDA489ACBF8411D202ECFDDC +:10579000FEAAB7379FC5E05DFC1FD2162CDF7A5CEE +:1057A0002A48960F0FAFF37CB1E97D3EA80743D29C +:1057B00042BC83C6E310BE981177D3EBA0DE22274C +:1057C000CC6CFEB59512F7370A9A41FA9C1C56002C +:1057D000E7315CFB2B87A1DF1C18E896100E47DF32 +:1057E0003E76A1BE64EA897028722289E3489A0253 +:1057F0003B71DFCEBD5877CFFF66079EB849F028D2 +:105800001A8747910D339B7FE9AB363C4E3F009D95 +:105810005417E203D01F1E82AF2D90A8473F8595F5 +:10582000CBFD85AD11AFFFEF519B8EBF6D97AD3EA8 +:10583000C81A470168A6FEABC7CC51B1FF96395CC8 +:10584000EFD0C1207F782BB31361043D6EB3AD77E9 +:105850006CC478861FE31A9A1DD788737D24FC28B0 +:10586000F9C58E968B64C70CD74FC4F0EA43A132BA +:10587000AFDDE2E82B013D2FC3EFE3F5F3F8C6C837 +:10588000A2A34721BD9E0CFE41BDCE6EB75E4EA9C0 +:105890005A563CA547D4DFFE79F8E3DF877C5D5A92 +:1058A00036B8FE517873E82AB37F255F49A5294EA3 +:1058B0009788BBE9FFD7365D29F96A0AFD9FA00EDC +:1058C000F73EC8BF0FB3F718BF082774D42B25E0E5 +:1058D000712015F9C0859F3FDBF45F2F8B363FA603 +:1058E00028EE29E829F2D3A9458C7F8413BF73CA17 +:1058F0003FD8E3AEFFF08617883F0A54E20F4167B6 +:10590000FC93651C4B325F9758FB5592F93F58FA50 +:105910003E9292D9F8E44F128FE7AA75095D2DA146 +:105920003822D91F9970F8653EFE950EFC568AE222 +:1059300092A385FFBD51C2EF8CC3E017E59904BF68 +:1059400084E570F00B363C79A037C928D7742E5FF8 +:105950000196E86EBD64B9DD6F9E2D9F00AE8FBBD2 +:10596000F5C02FD8FD8C763E9A3CBAF92C1F9A4F81 +:10597000913D9F0923CD67BCCCD763B9CCF73BB52C +:1059800026A1C7D9BAE40E4357F364BEDED70DAEE5 +:10599000CBF51F8BAE4E1BE53C9C71D83C66CA9C78 +:1059A000AE668D348F4A1B9E4E09E6BE8C7AF12975 +:1059B0008E7F67A9675D6EB0C7EFF43BEBB2D6B3DD +:1059C0002ED7D8F818ED7C168C723E370CADCB6212 +:1059D0007B5D1223CDC7D5FE227BFE17DBEDC9EE22 +:1059E000B8419ED28C768625252E95670E8DC7DA16 +:1059F0007D5E2E186AF7E796779BAC30B5BB9CDAD4 +:105A0000D5F2FD8FB54BBAFB032BD28CFE8036B49A +:105A100015981D53D23AB7DAEEFF2AFAAE6EB0FFF0 +:105A2000ABDDFDFB5BA1D9EEFF5A7CDEB4E023A722 +:105A3000DD2A2FBCA73BED52D84EA81984E37A7714 +:105A4000BB797221CDEB8438C328FD3FBE58B20329 +:105A5000E3FA7910E9C4BC8E7639752FC6FD2D4B5B +:105A600086FB317FC06F08E8538BCE497D17DBE59D +:105A70005A7E8DF23FAA530F63DD1221D15249F9AC +:105A800003941FD020AB9ADFC07C0B03B6B3BA16C9 +:105A900093D39897D326242DDC177F2E2537CB243C +:105AA0005FB5CB9AB0FF7C9DEBE9D04FFB9603D757 +:105AB000D6D01729DF2197C185FEA7B60CB86E0F87 +:105AC0004DECC1FDF6D60285F464666095A17CB903 +:105AD000510A1AD85F4FC15709DE6D4D3C9F61DBFB +:105AE000E7BE4AF0DE2600C5696FF3F17C86AD3E65 +:105AF000556BD6B0BFE8B82F53FE438EE6AFB4E186 +:105B000040F83E5B42F0E5835675A540E2AB07EDF9 +:105B1000DBB6390AE9CBDB621555D4DF1C95F4D42A +:105B2000DB12154DA477CC09924F3E3F6C90DD1AE5 +:105B30009DAD8085F598D1847A66645610735E2099 +:105B4000BF083099002253208D751F747696B232AB +:105B5000DAC1EC927CEC6F295C8976EF1C8677B415 +:105B6000232CF310DA2561B0FFA4FD26CEDB375ECF +:105B700002C9185ADF68E7E0F723DA5DD1F428DBC1 +:105B8000758FAE5DA483D9FD3346D1AE7394EDD24B +:105B9000A36CD7CDDB9DD4DF61707B4F65FFA1DDAA +:105BA00016C8B067516FF7C4F332DE67C6DF32CB79 +:105BB000CCF8C76BB237AE76B2EF9DB8C7C9E68BEB +:105BC0004E894138A593B777F4CDE1DE2B8517C711 +:105BD0004DF67DDBB84BE324D7C65DC6CB09F6F3A3 +:105BE00009F576FD52BB7E59BD9945BE17F8F83EC2 +:105BF0005486FE9011D6211FB8FEF80A83FDB880A6 +:105C0000C94A23FB4F32F5DE4C79A7CA5635F2EB71 +:105C1000B604CFEFF02333221F1601F9357D90EA49 +:105C20002C4539016674E19821FEF1994F9BC8CF4C +:105C300007C64920CCA1F531C87F9E41279974E160 +:105C4000CFF0E77C523A99EAF3C6C9FE5174A274C8 +:105C500048A3E21FA57394EDD2A36CD73DBA76FE9C +:105C60000E6174ED3A47D92E3DCA76DDBC5DFB5C12 +:105C700085EFE7F058B359CAE09EA77AEAEDF382C0 +:105C8000DEF767853DF5F53315DAFF9DBA7F96EAB5 +:105C9000A9AF6772DEF37E7698EAEBDB7E5ACDB66B +:105CA000B251F3C97FFF9D7C52A69EC42F3D47CCC5 +:105CB000B0DB32F84AD503F87DBEAC03E64BE5C74E +:105CC000F83EC5CAAC7EB9BB6DFE4FCB1A95DB64FE +:105CD0003D80F6E3BFFA3C1B7D1C5E67BE2783D781 +:105CE00091BFAF4AB6BE355C9E470DCFC3942148E5 +:105CF0007998A53566B5C9E492FC0C8F7B65F67B77 +:105D000099927CD8E7B2F7652DC9E379767F1714AD +:105D1000C8A497C84CAEA1DEA340A2B698E28622E2 +:105D2000F9FBE4F049F68D2297DC2A19016E3B6FEE +:105D3000955EE90055AFF1718306907C8D403F1967 +:105D4000D339A8F59C827A9A2E007D6F08DC7F3EBD +:105D50005F4379160BFCA3FBBD8CFA15CCAD703CF0 +:105D6000F431FA95FBC9DFF90FEFF724F006309F05 +:105D7000F70C0A21C4DCF9BCBE788A1EC2B1E3C7A5 +:105D8000A559C03FA1BF24C5D365D1207F281446A3 +:105D9000C92E6B8BAD55DDEBFA575F89378EA6B5F3 +:105DA0005F2F445959B4CAEC1F81CE3FC42018FA62 +:105DB000478AAE34FB47D84F07E397189FCFC207F7 +:105DC000ED4A328DFABB3531CCED7939457EC6F5D9 +:105DD000425EC5C64A17FD1629DD0857D8302DB4D6 +:105DE000F7D6E78B06EAA9326CEE13A6B1EFA43A18 +:105DF0002399458F18FA5E7EDD3D9F3CC5BB4FB6AB +:105E00009C84DE9DF8E470EF7D8A91CCE60F9DAC1A +:105E100070BBD617CCFEFEEB62758932F344BCE151 +:105E20007680DFADCF850EE14C4E3E94DF50F4F42A +:105E30000B8887B682F3E223CD17346F9EE555A217 +:105E400079A65230221C33B2C131DAFC0F8014B370 +:105E5000D186E225A81F096330AFC3F933A015ED41 +:105E60000B667F60DC23586EC07DAC1E5FA026648D +:105E7000A62F6DA9DC09E8AFF631FD89EC13693E68 +:105E8000D79FCAB83E64B2FF701ED1F923EBD5523A +:105E9000467DB1E2D59B5B1A1F078CC73BF03B7E6A +:105EA000BCCC79CD13AB2F520AB2E16374F6F0ADDE +:105EB0008C5E9872075B1B552ABFD9A851B9A531D2 +:105EC0004EE5A64646ECE81F6D2CA3FABFE1A7738A +:105ED00091CF531DC50C7F1DF1FB5EB812D02E056E +:105EE000DB4FF08505A82F6FC43AE901CC0CC4FA4A +:105EF00004FEFE7A65D102B4F337069CF6D50B504A +:105F0000AF1EAA5FD45285EF6D3F43877239B5BF8C +:105F10007502D8E7184CF522D7BE77B7E2A379E02F +:105F2000DEC2BF3FB705FB0BC84E3D45F00CD63176 +:105F3000E08A7595D77BDBAFA7FE4904B0F1FEABD5 +:105F40007DED02F42FDC3A99FBF961D9D293E0910F +:105F5000FBF53FC2A02FD2E5B23CCA5F5118DD94D9 +:105F6000B047B7E6DA708FB21F90937CBF7B2EFBF1 +:105F70007E39C43727D9D76C384ECE0FA6ED874867 +:105F80008285E3FE8AF3C53F7BDC5B7D1F0F2FEA32 +:105F9000FCA489DD476BBBBA71A9E729C91F22DDC3 +:105FA000E7D4F4D1B6A2C4BBB9DE30CAF1B72A9A9D +:105FB0001D8F4A92DDE4E0DBD13FFE94B19EBE9896 +:105FC00049F9478130E7C3D1C2FD071F3FC7E3F45A +:105FD000030F568C1B49CF8AD589A88C0DCA8DBC5E +:105FE0009AA0A7AECDCF43236DB01EAD2CF4D4C381 +:105FF000E5259EBA4F3BDDF3FDDFBB5EBFB4F54543 +:10600000A7FDBE8CFA9399F31C65BF4EBDA77F8197 +:1060100058C6D6E1F9F912C5439F9FFFD26D3318D8 +:106020003D3E6FE2EEC9ECDAFA161FC633FA980A63 +:106030005289FB7052B2FDEA3001F1F92BFC171BBB +:10604000EF97F6FEF7AC7DEE876DBC13F09CD4B3F2 +:106050000BDF2FC2F57BD607B65CEA24B97070B0AF +:10606000CEE5C2C100AF9FE9DFDE8272A04FE075CE +:10607000D1BF7D01F73B6E6E3F9FE92F8BF19F6C87 +:10608000FC65F305339D657F0BFB15271F32EC671D +:1060900078326B4C5F01E6BDE9407AAB1F12A49FDA +:1060A00035805525A2DEC3E88FE2DDB236211B7DA7 +:1060B0001C6CE4F9027EB890F4FE65F3A7FBD0A84F +:1060C000F727DE96D14FBA3821F8C0D69B35177C1A +:1060D000A2299848DF89F9FE9DA83F2764461259F6 +:1060E000F691C5A6DFB35F196C2C84BF4FB0F914CD +:1060F000B409EEB893E1E7764FBC7464BBC181DBB1 +:10610000A95F38FFEDBDF9E86FAC158CC9D8ADAA11 +:106110004DF862C4DD6FC8891347B0DFE7EBBFC439 +:10612000FD1A8C2ED0AFFACC91AB7D149F5D96EF0B +:10613000E1BF6575DEFCB6A535214FFDE2F923E729 +:10614000D741D29F21D72CFBFCA548F278E361818F +:10615000E443CEC48134E667C2F312703DD0F1C38C +:10616000CE233F6C74FC808EF9A2F0C79076BF4BB3 +:106170008EB666E021B37CC2CFF55B39AF96E2DC28 +:10618000EF1F1174F4A70A790D5370BEB26236E3A3 +:10619000B8ADC5621AE3DF37966C5371BD37947E94 +:1061A0003C7DD017E3717FDDD22A90FD87FB2E6DF9 +:1061B000F2BCB6CCE7D7FA79DCA1CD5AAA9522D3A6 +:1061C000ECD5AA70FE8122C87ABE94D1FFB57EF2CA +:1061D000BB5BC0E3EC09D2AF4BD5E5947F2B178EA8 +:1061E0001CB7CDC49B6CC70333DB3D68D363E99C0C +:1061F0009DD4EFFBA78DDCAF83970F0C11FA102E07 +:10620000A657607B15D87C18FE3795F1FCDBD6F2DB +:106210004709CF9259457AAD4F4B99D86E53F972D1 +:10622000A2CB36D6269F0D9D5BD345E733377DC87D +:10623000E3140FFAF7B6A05EB1A9E71AC07CCA60F2 +:106240003C0D283F364DBD4A453C6CDAC1788BF495 +:10625000992E72CE856CBF78488334B3A840D6BBE4 +:10626000BA512EC8B56098EC556FBC1A70DD365522 +:1062700072D6CC4FA79A3004B4297EC8C4F8446BB8 +:106280003D50BE4BB0CCAC2D46F8C789240E7448A7 +:106290007660BDB54EA6F9B46B1C2F68871D77F2EA +:1062A000BD302FA694DB61A5E8EF67E32837F3F94B +:1062B000EBDB4BC96FB42957A9473967DAF611D31D +:1062C000532CF4F3B7366859D77DB3987CC0EF925E +:1062D000EFB296A0FCA64CFCBCEF83CFE0BC5BA762 +:1062E0008BB0338BDEF1233FB74BD2C6D2C52559D5 +:1062F000C679C2AF7BF611FD0385E01DAEFD503BB4 +:1063000099FCFB68805CC0E65150CBFDA690717E85 +:10631000350649B273C782D584FCE89C5B1D5F9348 +:10632000F84D9295526419E5D50D778ED5C9E75C85 +:106330003E07EC3FFD92DFB1F95EB3CF0788B7733C +:106340008FDDFB34E64D39F606DB979E7E92BDBFAE +:1063500092A96558BFE6F05405F3809E2F9430470C +:1063600006F9278A74F826889487F6261C8ACE7048 +:10637000D1F9FFD8FB0E4A5694232DB97C5E72B832 +:10638000BD4F8AE27ACB56BF93C747F60FCF6787D8 +:10639000307BAE52165213C9BF0E9E37E4E4497EDD +:1063A000B9D39B4774F5766FFD2A583A06F9E6AAE9 +:1063B000DB7C9066FD5EE3CEFF62E3FFD2CFF58328 +:1063C000AB21D58EFBCF7A5BFF5BFDA3A90AD2F58B +:1063D0003533B4623C7FE1CCE32FF6BABFCEF8543C +:1063E00077F1FFCA589AF29233E7F7E6EE05DD49F6 +:1063F000567F499753DCDEF6CE73BDAF6F11E67D55 +:10640000595B7C8EDEE0C9775CB9ABCAC4BC31860F +:106410003D3DDFFB3DC1FFA50EEF7C4F868FCCF9E4 +:106420003BFAE070F3517665D72382AA376FAA450D +:10643000E57147B34586C039279E8BB6AA5374AE23 +:10644000D96AF66B2D318A53521CB081110EC6F9F0 +:1064500066A83ACF730F4C4C039D3F48CDC673E1FD +:106460009FB4DF392AE7C37F74BF670FD3EF6AB5E4 +:106470005F41FE5C2377D60A2543E702023ECB1C30 +:10648000CFF0ED7F7C49F778F0B4EB1865BB7D78F1 +:10649000F47914ED6AC511FA7BCBDEB7FEF3C16F58 +:1064A0002BB87FBFF9C0914528E7AEFD89042A6B60 +:1064B000F7D68311E8A67D27ADA03C5EB95BA2F5B7 +:1064C00007B97BD6859E3CFB169AFFB50F47687FC0 +:1064D00058F9A83F5DC7BE5FF9C397A601E3DBB7D4 +:1064E0009A079E1E8FF87B40E0F90C56FFB40BD93B +:1064F000F395325C9E2D1F21A972BE7AE33F42F5CF +:10650000B8BF0BBB7ABE48FD765DE2F3BBE4EF2576 +:10651000AACF6947FAA3F53D213D59E0F065CBCFFD +:106520007BE37B3CFEB4F2715F1AF31557EEDAA100 +:106530002459BB35BBDE26FA5EF0F04351C4C39A42 +:10654000C7BD7ADAB50F7FD83EAF92CE390DD4A150 +:10655000FC938E51FDA8A90E70CD9FFB67AE238ED4 +:1065600065EDFEFDD5F37EC7DEBF1E9720C044CA91 +:10657000EB7DFFADFC04EBC9708A8932D6BFEF45D5 +:10658000371FAED9F5129D37D24418283A0BCF41A8 +:1065900064BCCF680F30A0A03C5CD3B5E16D94978C +:1065A0006B76BFF95BA4BB3520BFE8E6E7D7F11FE8 +:1065B000E34E8C6B75A85E3FCE51D83F0BED16D8DD +:1065C000959FD55E74E25A0E7F5FFBD0D17B508FD2 +:1065D00078E3D1FFB907EF6558F5D15FEEC1FC56FE +:1065E000782AA0A1DC5AF3C0AFA2E0C2FFB76DF9D0 +:1065F000F0D6F7BEFB9D3B181EDEFA8D9FB0F6D697 +:1066000093AF4EC4FB39DE7AE4AF6350FF58F7E432 +:10661000C2B14867EB1E5B3076A4F39F48B769BFF1 +:106620007B7DD3FC5E83C705DC04D9866B9719EBB1 +:1066300002FB0714D47BDF136060632E7BDEF5A1C1 +:1066400082FACBD3260C209EF6EC7EE9E9AFB3FAB2 +:106650009B6C9DFC59D689CD7FBC48FB1B631F56A4 +:106660005EB7FBC2C5675762E933B0FB353040FB0C +:10667000C609EBFB1C5BDFCAA1F5CD7C7F148E291C +:1066800088FF350FB2F59C86EBCAD673DA89EBF931 +:1066900026FE63EE89EBD9AB7AFDAF4761D5BD77B6 +:1066A000E0CBDDF959ED5B673D573F76D1887AB98C +:1066B000231F4E86673AD7CBE0FA866A1E520B90AC +:1066C0002EBEFF9D3B627C9DEB1862DE7AE8E844BB +:1066D0003CB4F19A6FE08B88878127FD1AEA512B31 +:1066E0009FFC35F1DD5B8F3D4BE779D85F5460FB54 +:1066F000DD5B30F8770858FD3A815756EB03E7FD2C +:1067000096F5BB9A756119B47EE7FDB612D74F1D99 +:10671000A0F5482FA9D551FEA60B68DED7A5397F75 +:106720005C97EE59867EED4CBC87034E5EE1D0BA95 +:1067300062BCF9BADD47CE43FA1B6E3D9DF96B385A +:10674000FFD9ECFD7D5EFE1D965FEDF57D6BC7FB11 +:106750000AEA57DD3F513491D9ED6FF9069442DCD6 +:106760006F1E91343C679CB9EE43F86FCE7ADE38E9 +:10677000B3CCA40F25903D8EEDE0E964FC7EF2F9E8 +:106780007D3CFCBD6BEF9799787CE358F6FDA02427 +:10679000C0EDB9EBA0B31655CCCCFDCC07296B7C72 +:1067A000F110BCED5D12C9F9377649148FCB9417FF +:1067B000D70D639F19CE388FF74C43B9F646EF7F5C +:1067C000D874C9E9FEBA078F2896BD3FA45DF85D6D +:1067D000339CDFDBEE6FCD13D9FB5BF3E0DB59FBC2 +:1067E0007B5D362F41F85FEFF3517ED2EB5D525661 +:1067F0003BB734E0F3E85DED91592FE460DC201AFB +:10680000A4FCAB9666F3D7E82FB50EF96C3F80F188 +:106810001AE65DB5448274BEBD257A15DD93E4F4B5 +:10682000D79A8127399E20FB498E252A792C2CED79 +:10683000896FF91841B8E106D92A42BDFF40F1AB92 +:1068400032F68B7E15DD65D71F94A10DFD2A074D0D +:10685000C168822CFE8D8CFE13F325D0DD7EC2EE46 +:1068600071E2BBEC7BFF73521A51DB00A96E3A1F39 +:1068700050045DF767E9EFAE469DECE7E2C4E5E45E +:10688000FFF1A75226EA6B45EBB412511F7EDC09DB +:10689000296F1CBB9051FEBB38CE3E1FE983B0EB85 +:1068A00081071E18C3B714D4CB9FC692C9BF7357B4 +:1068B000E84558BFCB9E37E3013ABF38C14AC828E4 +:1068C000E784D812F2832D4C25E4E5AEF55C18136D +:1068D0000A713F4D0F73FFD30F037CFF6C6ABA98A8 +:1068E000F2D9EFBC5924BABE33707E11F2D9DEDC86 +:1068F000D961CC57EC593D6BFF1406E7F8B004683A +:1069000072EE098FEC4FBAC7F62FECB4EF1DBACF79 +:10691000CE33FF8E8DB75D8D65543ED068D0FB07BA +:106920001BE750BDABB196CA471B13F43CFAF560A8 +:1069300012E97377633D3D1F0F6F0BB8FE3F6C4C40 +:1069400052FDDB815C827FD24D2026D9F385888F72 +:10695000F0D0BC1D78D2B6DDFDC30D4FB5A21F62CD +:10696000108F19F83E17FA0415FD573141C775BF4E +:1069700031C0E549267E27FA07048CCF35DCC4F305 +:1069800022EE11BCE71EBE65CBFF476D3E7D3B9AF4 +:106990007C30C0E07CA7765919E943A09523DDDC63 +:1069A00023240E1AC58467CFF9939579C947032E1E +:1069B000BA99D8C1EDFADB035C3EE9EB40447A9B1F +:1069C00090021DE9CD99776F955E8472B15710687A +:1069D000BD91DECA5CF4E6F4776780EBC110CFBEF0 +:1069E0008F0FD12FE7FFF8BCB2AD358897B522F9EC +:1069F0002D5BF095EBBBBFDAF364768B68213DAF7E +:106A000010C99F3BE9F0116122834FD7BE1F403F61 +:106A1000747C22D8FEA6AE00D2D79D2BB87FF1EEB3 +:106A2000C3FC3CD3D175254BA6B0F68B187E30281D +:106A3000957741698E3B7EEA9C63B85B4DE46823A1 +:106A4000F8B732F3DF6E9F74CB07396C9CF1874344 +:106A50003AFAD7B74E7AAA4761F5C27E81FC4985DA +:106A6000E1D4145CCFAA3F7C6F5CBF6B1DEE589DD8 +:106A70009A847A63FBA41F08C80785C77E2AE03E74 +:106A800032494BBE1228C0FC70FB7CB09C9A8D76BC +:106A9000C1A57989D770DD1245E9FF83F474B47616 +:106AA000DD7F62FF4E3CB2A141CF9DE2920F99E79C +:106AB0002AEE4A8DECCF74E67F17CE7F8476CEFC2B +:106AC0009DF53B5A1B5B857231139F99FDE65DB0C6 +:106AD0006CC4F1EFB2EF0F63F357822EFA2C4AF534 +:106AE000CBF89DF3FD70F1D7CCF90EFA894619AFBA +:106AF000EDF2413ED2C523FF3BF1DF0F02924E4241 +:106B000042FF544F20190F16E0BD7129AA33E948FE +:106B100079ED67E472FEBD63CC77C611DFC9E96227 +:106B2000CAFF18E5786D904854E13E678846B67D07 +:106B3000A03CC8E5E77C48917F540CDD3472BCBFB3 +:106B4000C81BEFDF0C3409B0BA553BFE01B286FE1C +:106B5000B07D5081FEC7BC2087BF4AE6F6E58C7D3C +:106B6000FA0E89FBADA4251117FE6CBF9D8F77CD62 +:106B7000E0BE09341DCF7F4DEF115CFCFA7E287911 +:106B800036E24989EB744ED6174B925F72A1141608 +:106B9000C99FDBC9E57F0324D4D3785C0670DE3A55 +:106BA000C445DCEFEF5AC7CF8DEB5A88E0BE2BA669 +:106BB00053BDC1D6531EB1F5FA876CB9FF7D5BEEAC +:106BC0007FCF96FBA55DA9056106D7776DF97FBFDD +:106BD0002DFF77A2FC67E569F7F5C3F72A491E1B6D +:106BE000985FF08D6DF16644C13D8D26BD7FA27129 +:106BF00005957B7EFF7C7588C177DF73DC1F7CDFAA +:106C0000E1319FC1F859DA140D81B5BFCBCA131F0A +:106C100067F51DEBC49D28577EDC98A2EF76A8DDB2 +:106C200012EA314799B56C2119BC66B68458FBC885 +:106C3000BB035A2D2B77B41E0AE0BCF33E2702DEBD +:106C4000D3E7F051F40F5FED8EA21C9B290691ADA6 +:106C5000F20ABAD553D04E5F27523FDFFCD565EA22 +:106C600002C07B1B5E84D5ECFB095784293FA2E858 +:106C7000FA97CDD5ACDD9697C394AF5DB1AFBFFBAE +:106C800021F67ED68A08D5CBBBFACD2DAC5EFA06AE +:106C9000AF4FB0BCFC71FAAE7EF321F67D712A4A8B +:106CA000EF67EEEE6BC2F9FA2ABDE7AF72FED031A4 +:106CB0006E0B836F22187B826C3D1E1352BD01F454 +:106CC0005B2CE1E73C0AD2C92ADC3AC66EEFEAA1A6 +:106CD000D07F0754235EE3BF7D217E0D2BB7E147B4 +:106CE0008C2E66EFE5F8B8BBF5C50BCE67EDF6ACBC +:106CF0005B4BE715FCEBD6717D88E10DE5FF84AFBA +:106D0000EC15AE76C989A25639ABFF6E5BD04FFC4D +:106D1000D1B66E59620A07776F18F5BE52EEB72CDE +:106D20006EABF1E439397192BF09C96D41D23F7937 +:106D3000BC44D652F47C06E37DF4B3C28D22D797CF +:106D4000127D01B73F46FF0ABF9F2D138E9D4199CB +:106D50009F77B46A5EDBCFE6B765A62207108E295F +:106D6000F6FD2C763CD269CFC6DFE9966FB2C6E15C +:106D70009AC00C2505E15ED537EE21D6CF072967ED +:106D80003F3383B89FFD68AB48FBDFE64A7E2E7039 +:106D90008FF14E37DE73E1F0559B21121F6FEB83AD +:106DA000349EB3D85659927B1AD2510C77719AAF50 +:106DB0008A782EED93C1CECFE945FFB81FFDE38C55 +:106DC0009E4A0F878E88E407F4E683175B5E7A108D +:106DD0001BBCE7F02630E5C79DBFCC2C9F213AA312 +:106DE0007DB6A617EF51388AF728A007C532A355FC +:106DF00063C874E2CA917493847EF8D28C73077767 +:106E0000D8FC7E8F7DAE108E5D0F28BFEEB0F38B69 +:106E1000EE5825067586979F598768FF9CD0D05DF0 +:106E2000458199C33C8FC2C9B7F6DFA435E33E5B09 +:106E30009CF2E60D5566E45D977EC2BCEBC341AFA4 +:106E40007FAAF7C74103EFC34B3F2719A8D77EE3BB +:106E5000EB33480E5A2BB9FE925E917707C697F234 +:106E60000530F0B9D3AF63C7BE13CC23BE49CF659D +:106E7000EF7398FC88745DB002D70B72B4E6189E6D +:106E80008FBE117E80FDAFE0EB5F550474BF4E51A5 +:106E90000C28CECFCA8DA7227FAF1331360EC76D17 +:106EA000790F6ADF33F83CF73322DD9F53DC6A9DAC +:106EB00086F3EC9D575888F4B139CCCFC1B4083C67 +:106EC0009FCB2AE0FCB023D24DF9A15B6A4568C68E +:106ED0007563B833B09FE5C19D94D782F0CE24BAD4 +:106EE00023FD0B6315C88FD61541BEFF1CB34E435F +:106EF000FF7234D4DFB587F5135EAF183B512E56C1 +:106F000079EFA99B1CE2FA5E20C4F73FC62F8110DF +:106F1000C6F93703E531B2B9107F33BEB280F60748 +:106F20008DEC2B27CE1FEDBD402C9ECACB1217FF38 +:106F3000EEB4E56DDACE5FB8C7DE471CBDE30E7B6D +:106F40001FD96CEF1FC5E6E26605E976054C473CA4 +:106F500095AEEA129667E1FF533ABC7235935F260D +:106F600065F24BCA7B6E75FC8A12CFFB8871BAE75B +:106F70003D856470DDD93E8E785E1F289750FF9B5B +:106F80000109D32D5786D303F282E634C4DF68F5B6 +:106F900092682891423D34530F3FCB5E972F0412E5 +:106FA00073B1BFE8BC7ACAE75915489C45FDCB6967 +:106FB00001E5E97CFC2E96155E4A061B05BC351FD3 +:106FC000075E900D3ADF75A3E4DC67EB3DDF051942 +:106FD000F7D766DE4F7BCEFFDE44F7D3B6094CE130 +:106FE000C37A8E7D3FAD9FDF4FDB16E1F6579B8F57 +:106FF000E7AD5D67E3E1F210BFEF75954DA7E7845C +:10700000B2DF7FE4F8BF52281BB0DDD8ECF78EA1C9 +:107010006685FD9D333EFBFB5448E1DF4F1A799CAA +:10702000B5380EEB6766D05C1D2A18C2D38C90B9B8 +:10703000C65DBF2164E715C909D22F4D99EF877A44 +:10704000D05CE76EE794791754D2F9BEA3F6F93E07 +:10705000F6DD7681F02A69A3C1BB6307B409FA564D +:107060009283BF62FA5F96F5783F18B5C49CA1B8C9 +:1070700094A327ED0A71BB97D1DB06A20F266110FE +:10708000EE30E85BF15E88F1780FB78EF6E7E17BD2 +:10709000BE8DF2F6ECBE5AD4A356FF58A2FBED4EBD +:1070A000C0D72A4677AEBC14E779E107E3C91E9E34 +:1070B00020256F0FB9F6E9C215030AD23BC25FC3A0 +:1070C000E1E7F9D442FA346E1700C573DAAE897B72 +:1070D000F20B33ED923CBCF780E48A42FA5D265C09 +:1070E0008E5DE1D433CF271CB0E908FFF431784F2F +:1070F0003870A5563625E4AF9990A47236E854321C +:10710000FBA50BD793F19F8E703687269E85F3F8EB +:1071100027E2EDA950C1BF1EDE1C3A2E4E9E3B4811 +:10712000C7D9EEBFBE3D142579DB7038B2D34FFB13 +:10713000C9D788AE2546D7A8F73A79330D60E7D589 +:1071400087A10BFD94C5C9463A277A94D131F62B15 +:1071500069FC5CAB0C5A02E337528CF3874F2ED399 +:10716000440DE3B3961FF51EAB040C94B5E8977479 +:10717000C35B194EBEEAA6BF1B0F6F2579FB854086 +:10718000F275C4EF8DA5961F353B971C7EC32D87E6 +:107190000508EBC87FE71CE3FB65555297911E1667 +:1071A000304E47BC2F8424D5CF078BCA0B204DE52A +:1071B00067F18A23D2E3EC730CDD9788EE730C83BE +:1071C000E7E12A9DBC0E1EAF2AB0E9106C7BF56783 +:1071D000F54B9B16B2F1D9E29B1897FA563DCFEBCF +:1071E000F1CF96E93C6B41FF1575182F82655C0F56 +:1071F00073F221F2EABC7ADA09F75D1DFED361FC75 +:107200002EF3DC9CA3AF65EE5B4E99A9AFE58587B5 +:10721000892F0CB3EF64C6171AF09FDC8EB5EDEB27 +:10722000448EFBDEF8CCF240E340EB5E57DEF941E2 +:10723000BCEF28EB3EC0E3BED1DE3FD52DABA4FBB7 +:10724000E50C4C9DEC6BEC3EE7E5C943F670627EC5 +:10725000EECFD02F9DA8C9AD407B7251FCBDD6BDED +:10726000F9004BCC9E735E76CDB34F63D066D113DD +:1072700006C7337D7F73EFBF6FE0B903F44FD8E3E8 +:1072800045EC38D97AD1F213BFDA7EB8778BB8BD26 +:10729000EED8F9D9E6DB4AF8EA0F233D0C37DF2FA9 +:1072A00085F97E3AA6DEA0FBF25BECFBF25B2638AA +:1072B000795C8686FAE45561EE8F5D1F2EA5386BEA +:1072C0004BCF5CF22B17ECF7915F7DCCB2A460B989 +:1072D000F645CCBF473FEC37997EA753BE7D19D505 +:1072E0007BAB66A9682FDC10A9A0B8EDC646C39396 +:1072F00037E2942DECFBA4CBCFD792A8D630EEDBAF +:107300005A57A1A2DD217DAE92EAF269159DD58C76 +:107310009FBFB079DA7905189F28E7F7935DCEEA29 +:107320004DA500D561BECF1E305E0E239EAAC3BA06 +:10733000433FB48EBE6549D3877221AE5563CE8C70 +:10734000F31C6CFA62CF49BF7E43495E13C67EECE4 +:107350007BB2D62BA9B2B5E5784E9E091CF417ABCB +:10736000DC5F8874D03A6308EEB5367EE7D9E33245 +:1073700081243EE25A3F25CED76FBD082BB2ADCF58 +:107380004D61AEDFB46AA636221D69F2DF3CF78795 +:1073900056C678BE7E8CD1918B9F4FA477CE4F95E9 +:1073A000E1442BCECFAA86B214CD3F4CF287BE93D8 +:1073B00086EEB18C87CD0E6CF78B5C3B4FBA88E7BD +:1073C00043B3E7ED3924FF5224DF1D7D70BDCCF5BA +:1073D000B9D1EA837917AC237DF01DC65A649F7D2D +:1073E0006E1DC9ED753E5543FBB477BE4C71ADE8DB +:1073F0002970B9DB6E91225C1F9422DCFF8DBF9354 +:10740000909EC2F51E3CE7110D4137EE0303137841 +:107410009EE97AD8517B0AC1375973EF675513B883 +:107420009F614B757085DBDF303797C7CDF6E65629 +:10743000FD29CCCAF270BA1A59F30C0DFA31AF0615 +:10744000AAF97932A1889F27F381A1727EADD1F08C +:10745000DE500192741E6DD8F503EFFDA20FC8E94E +:10746000E620E22DC6EF59896C1728794FEA32BB26 +:10747000F14C4F73EED21F8709DF0903F9BB675642 +:1074800090ECBDF77A14B23FDFBB067ED785755FFF +:107490000E586CA99E12C5DF3DCCE63BC0987527FF +:1074A000E68169FCFDF4CD02F9B39EFA5B703CD233 +:1074B000BB1105117FCF6211D32778B22084304EE3 +:1074C0001B5D00DDE7E2F73D61C29F2FFEF3735EB7 +:1074D0009E41FB4F489C83E7B7C43B71FE8FC6219A +:1074E0000FBF9FF1D76A094A86F4A1AD5AF210C2C4 +:1074F0003B1BAC153DECFB2D0AE7AF2D794A1AE397 +:1075000095150522E921E00BA527B3F78BF6BD5CA5 +:1075100083F99D8BE64CC796383EADF7242D79183C +:10752000E9AF465B5293CBDA573EA793FC3D2F7EE3 +:10753000FD5EACCF3ACCEB3E3FD7E3518F719F134A +:1075400058F4C1449AD7AB61AECFB6C6CD3E5318FE +:1075500091AF32EEE5F59E3370E8806DEB3AE6A729 +:10756000D3BF75A28BA44F1CF23FC11CC33E8FE258 +:10757000D083297C1C7AD88D3C89F217F3CE6243E4 +:107580007967EB6DFD6DB4796799FC9477814CEB6D +:10759000F00ED3B7300FFD443EB99EEEFFCCE4278A +:1075A00007CE8D95793194C30EDF68B36F22B9ECA5 +:1075B000BF42A1FB4C1D3E72F86756CE201F7D13C3 +:1075C000E5C5B2B0BE90A76A98E0E6930B4FC257EC +:1075D0008B60606F8CD517C960E530117460EE6BFD +:1075E000A5135D7C9289CF45F30578D1230779DD1A +:1075F000856F6DF01EE02C76F270EB7248D6DB6280 +:107600002E3E6DB7CF99758806E07ED49CBBDC8892 +:10761000CCC47B277357213F6C121229E487C8EC36 +:1076200037425731BCBF37866991E83FD4973F4C0A +:10763000FCFE4288ECB22DB356527CEABD6B9293AD +:10764000707FD9C0F0FE22EDE7E9B122E5DCF68FCC +:10765000E5F9137A9C97C9387F0EF6FBB45D37EDD8 +:1076600076FDD48EADAF476EEE8B723ED817E5FB3C +:10767000D406A553457A1828563577DEF2B9F6FDBB +:10768000C2D746ECFC97632D3AC629AE8D08F67931 +:10769000BB2ED25736343E4E657E5D1A304F2E5883 +:1076A00066E9A857A81F2D10709F85D379DC1D9F10 +:1076B00037B9F4B58B6CB9ADE2BD406CDE6AB3A5E9 +:1076C000BBEF9D554521EB7D41FF15E5FE5FB519EB +:1076D000E8BDDAFBFF283F21BFD410BE8CF5E64E93 +:1076E000FADD9840377F1E2B35852B5DFDC6EABA43 +:1076F0003CFBA32AF6CB640F358066A17127F7D730 +:10770000A0DFAD6369B013F39633E908FF5E74D16F +:1077100083FAD185A417C121AE97D694A844BF6D32 +:107720000DCA0EF4EBBD1BABA63CF5161B6F99F30F +:10773000C1F83AD3F4C84F66F9799CDD9AC2E3ECFC +:1077400058C7383B961867C712E3ECF81EE3EC58AD +:10775000FF41A349758CB7631DE3ED58C7383BD68D +:1077600031BE8EE5E38D2BA8C4F809BE7FA2B1819E +:10777000EAE7DA7213CAF8EF7C757C4D31313FEAE3 +:1077800027F6FAEC3197AEF825FA01216AE07E1D62 +:10779000D8DFFCC27FD975BAFF3A5E928F7E4988E6 +:1077A0008980F184F6F836A6630ECD2F20DF0A3AE1 +:1077B000C5D5AD1598D7B83372E03C99E90FA5F15E +:1077C000EBABF3587D57E4B976CC233D556FAADF78 +:1077D000E1AAEB918A958F6843F549E53BE4207B6C +:1077E000FFD096E7DB510E04625CEFFB51E437E714 +:1077F000353192E82E618A0DCAB162258D748C678D +:10780000395F9C8CF3E07ACB67A1258E797C9374E9 +:10781000A502F98FB5EFE6743FBAF63F89E8F43C6C +:10782000F3BB91DA8995A36A47E770876B87EF8589 +:1078300011FA698316AD8FC1BEC9C7F757AB80FB7C +:107840007F3B7C9CEF3B02BC9C98E3E42F54DF120F +:1078500065E52D51BEBE1D017E0FC1C054917E8FC6 +:10786000071A84CF633F5F2D040DF31F2BA696E408 +:10787000A3FE7FC8A687C993227CDFFEBF2AEDDB6B +:10788000E74F7AA8358FD5277FDB30701FDE04469F +:1078900010EF71B5368B944FF4FDCA53F296B0E6F3 +:1078A00067CC7C2C0FF5DE0A5BEEA46DFBA4A9ED82 +:1078B000AA49681FBCF72C977B47EC7176F8FA52FF +:1078C000B49E33C3749E02A093F492A6B84CC10C2C +:1078D000711C2F159F7629DD93D9A6D0BD4CCA8780 +:1078E000B355F2A77EE0B7EF25EE237D450924B519 +:1078F0005CF6BCD312C9FFD0A205296EB3295C4146 +:10790000BFCB6095CB140FDB54CEE33AA1C8C5744E +:107910004EEB9B3D016ADF1656291F385DBE7B5F2B +:10792000750C4B51C37D3F6D2EA5FB2A2D4DD428E0 +:10793000AF98FD8BDEAF8A919F6713D8EBB28AC7F1 +:10794000217C63F753BDE5228DFA073B7F9F542FBF +:10795000117F2722D1E3BD7F76E0E767A21F642570 +:107960003F9F324D5BDAF3247BDF6AAA8912C60F90 +:107970006DDA3BBD21AC5F06142F0D4D7DB919E3C7 +:10798000A9AD576A06CFC7E2E721C0BEEFB8B57C04 +:1079900059CFEFB1FFFA104C36B07D8D8AFC0AAD9D +:1079A000F034DE4F5564EB33A1DC0A01F5B1B63A91 +:1079B000BA8693C1E73D47D09AF71915E9465A941C +:1079C00047E3B481A9627BAB4EA67DB128AC76A318 +:1079D000DFA0C8F63B38F2203FE53A4FC0FE57B86B +:1079E0004AF69C37187BA5B75E9071DFEE9936FD9D +:1079F00064E22D739EF9B14773119EFC557432E217 +:107A000004F86F8D552CC1798DD37A851D9564D27C +:107A100068BA86A986A926773EC62785775A796BE4 +:107A20001FD2C3345D069DE1E54C1868C6FE37D908 +:107A3000F4DF51ECDD9F0FD9760DE3D3ABA3980FA4 +:107A4000D52082E5EA1FE31D960B9E533AF23CF5E2 +:107A5000C99D859EF653B69778DE9F963EDDF3FE70 +:107A60008C5D159EFAD4AE799EF6673E5EEDA94F09 +:107A7000EFFE8CA7FD8C7D4B3DF5997D977ADACF93 +:107A80007E61B9E7FDDCFE959EF767BDB6D6533F34 +:107A90007BE0EB9EF68E5E9FB96F5E11FDFBF47985 +:107AA000FCDD1FF7B9E24C7BE1847B743E6AD13187 +:107AB000FE07517E6FAE8CFB3BABAFFD1AB7BBD45C +:107AC000730C1DE5CD25365DAECC33AF43F95A15A9 +:107AD00055699F90C3BC9D1C3E8FF49189DB999C96 +:107AE0009A41F6D8E0FB10CAEB46EB9C5297BF2AAE +:107AF000A07502E68155456BE9FE40E77B593301ED +:107B0000F3E32EC12486023C766A51BB80CEBE7759 +:107B1000CD8BD97F7495C400B30F51AF1FB4FFE470 +:107B20001C8AFB32FB8FEC4323C8ED413826D17B06 +:107B3000E39B02607C9AD977641F3E1A66F6E17473 +:107B4000B4C7FA37A11C1AF8854C7144F647F65FA2 +:107B500025B3FF36E6BAFDE0FDC558A6412B247FCC +:107B6000B8D22D8E2D267BF036A4E72FAC7B760580 +:107B7000F63BB592DFB3D731A62E8E7A72477117D6 +:107B8000F1C940B1CCF7213951E6F6EFFDD45EEFF3 +:107B900090FA7DB243D93A905C76D66193D09FC675 +:107BA000FB0CADAF05C9DF3DF18FFE43C86F6A899D +:107BB0003A1EF3008D3D8A89E3DD6AE3B9449B5E9A +:107BC0008D3FF3581A5FD28BE5A93AD347585956DF +:107BD000B6B517CB47A22534DEE9C623D52863D432 +:107BE00073B8DF5A9EA6A49B05F4373338B2D81D6C +:107BF00083FE89E8767E8EBF547E05E90FB5FEE3ED +:107C00006C0A55792AC58D0348170295444F0139EE +:107C100044FB4B000FA3627D8E90C65017EAAF98CD +:107C2000175A95B79DE8C0D16B51DF4D72FBF8A78D +:107C300088D7589D77FD43EA0F084FADF6EFBC7526 +:107C4000E4EAFBABD9B81D052579E8B3457FCA1234 +:107C500097FCD963EFBBF7E6881EF9331B731466F4 +:107C60000EE9458C1FB68BA720BC098AAF07F64BDF +:107C700064CF076EEAA4DF570D68960EA4FF5B3A47 +:107C8000F65B53524FFEBFBFC42A480F0E343C95DB +:107C9000156F817E09CC19C3E3337AEA1DA40FC0A6 +:107CA00098A08EFB6C432C68EEC8621F7C29C2FD35 +:107CB000671B263AFECC049D7B6D437F5B18B7366D +:107CC000557C84F573C32F0A76BAEF87B8A180FB81 +:107CD00027871B3FC0ECCCA40BBE0DAC5F94E36DBB +:107CE000C796D4D2FDAAB8CD54E2B9D0F21DE4A70C +:107CF000B7EDA52FD978BD36C2F1385181053B507B +:107D00009EE431FD88A1B4CAF6AB38FE97780E8F99 +:107D1000EB1B1648DC2FE773F62DF138DE4BA383FF +:107D2000AECCB2AF00211598EF6BECFF7AF07CE09F +:107D3000291DAE7D0E703FF0D6A76CF7D64F4B7B5A +:107D4000EB4C8B7E1EF5806500DCAFB1CBFB3E0CAF +:107D5000A60FE32885CE7DFA097E5E506510207D52 +:107D60009777A57BEE66F34B38F75E66DC9F3F7531 +:107D7000779AF497C54C7FC1F799F7BA171E5EBD85 +:107D80001AF585C28C7DB4C22791BF01FD4486CB14 +:107D90004F3449D33D7695E3EFC994EBC1C35B8182 +:107DA000BD217B3DE9C7FB51B572F42BB417DDF261 +:107DB000C7239543FE957639F5EA11F25F32FD2B24 +:107DC000C6FD1FE897BEE1175FF9F311979FF2ED2B +:107DD00068721AFA336E9FC4BF77EE4F75CEF5BD49 +:107DE000532BFF4CD0391C49171C379659E7737534 +:107DF000254DF76738FE15C78F70699E790BF2DD48 +:107E000026E3506A0FEBB7FA377EC07E164AFBF7BF +:107E100035A2BC9B2053BE88367BD5BD41F467E2BA +:107E20007B56AF2ED6C7127F3CE3237FC27A9BEFEF +:107E30009DF3A98E3FE6B3B61D707E8EA3475941D0 +:107E4000FB5C4610F5E43376B135F4EC87DC1FE8D3 +:107E5000F8FDA67679DF9F8E47BDC9EFB983F29B07 +:107E60008CB93CBF694C7DBA17D7F94C7B9D316EFC +:107E700055356B287E3AF6B2742FEAA1D3EC3CA5B7 +:107E8000F2677E463FE50B5211E5279D3E9EDF4B94 +:107E900064EC953DE742C68040793E639E938C3406 +:107EA000EB67DA13DEF7E5E0AA17237CDE7A665C7F +:107EB0008AA95B6F5F21E0EFA2A60494679B2F6302 +:107EC0003602ABAFC8B1F38B4E8553916E174A6142 +:107ED00003EFD15BFB2B89F214FD47A6FC1AE3A349 +:107EE000F02CCFABD44EE1F156EDE792C1242068DF +:107EF00021983E3D3C14C7FAD67103EFD41FF48F8E +:107F00003DC0D61DF7A10799DD5FEA433B5EA37A2A +:107F100017B3FBB1FE28B3FBB1DCCDEC7E7CFE4396 +:107F200066F763FD7166F763F96366F7E3F3279815 +:107F3000DD8FF5BDB955E48FEFC3FB8DA6E0EFDA19 +:107F4000EEA6BCC6F5AA4F43FAC99467555537A8A3 +:107F5000CB187E378617521CA57A21CFAB6FCF592D +:107F600048F6F4A09F2EC3CF39E4B7EB171CBF1D12 +:107F70001E718EDBF6ECA0FF3369D0FD0527EFC73D +:107F800074FA21FFE909FDD87ED437BFF6DBEFB4E0 +:107F9000B057AB676EEB0896E0B99E147F6FE7159C +:107FA00066FE9ED6EADD4D94E7A78C7B2E85EBBA64 +:107FB000BB324CFA06FEDE12CAED4C3BD1B10F3398 +:107FC000F571A7CCDC0F33F36022B65E72B2BC8CC5 +:107FD0002DBE14C5ADAD26265F70BF684C9FF3B2B1 +:107FE000EF44BF6DA1969771BE99E75DF9F7F17CFB +:107FF000BC0E486AEEF93BE71FC8E62BE1FE43B72B +:10800000DF36589AA6FB19826193F44581E991A461 +:10801000576A498A03B60FF3BBD9AFDA72A269DC9B +:10802000C5B4DFB73FE3237DABC6CE7F6B19A75244 +:10803000BD65DCAC389D3389CC52FBB3F4B336520A +:1080400032E2FE2AB1FD5F1F61FF97FCFCDC574B5B +:10805000EF5C15CF47758497F7A1DDDE118F91FF97 +:10806000BF67DC2CCF3DE4527C0EDD572185B99EE5 +:108070002DC555D2B3659C7FF9507BA7DD9E1CBEF4 +:108080008F3036273F6620DC49EDFC72C2447F8B7F +:108090003FC6F38CFD1A8F17064B4550B39CC7782B +:1080A0002287DFE3D5519ED4D0AFD31197E95C4747 +:1080B000875E315CBC95F4A2FFCD113CF4DB62FB22 +:1080C0001D5A5628A417261A72B59A7C3A97308002 +:1080D0007CDE116E5631FEAA8CAB1CB15F45E3FD10 +:1080E000FE7FA3B2F95D0080000000001F8B080036 +:1080F00000000000000BCD7D0D6014D5B5F09D9DF6 +:10810000D99F24BBC924BB9BECE68F09241A34E019 +:1081100026240134E224048A167111D0D052D98069 +:10812000282A48405B57ABCD8604842035F853A9F4 +:1081300058BAB160ED57ADD1D296D7222F28F2FCB4 +:10814000414DD52A58D400D66A6B6D0469A9FA3E10 +:10815000BE73CE9D497626B34950FBBE872DC39D85 +:10816000B93FE79E7BFEEFB9774F9D823F1730D630 +:10817000BA27456595F05CEA88A71431168E966794 +:10818000D74F60EC1B59E1CF32FC8C393C8BE49823 +:108190009B313B636A173C4F69EDF4A75716188370 +:1081A0007AA2FCF329EF7A077FD79F62FA661681DD +:1081B000F6AC587AAFD7C5984D61C2291B94995B2C +:1081C0007EEF6C467F4E89F8774F20EC49DE8FC7F3 +:1081D000F58B29EF4E18DC6E7959AF4354185BBF0D +:1081E000AD23CCA0FCA900852A843BA6E6C1BCAE89 +:1081F000DFB99245CA18DB28F5B8648063E3E7C2AB +:10820000C270D9E0FE17E37CAAB057298670C21F5E +:10821000DBA973E06F85298E6AC6F2F0CD687CF227 +:10822000EF30CA9E53D07F7937944B3578E0FF13F7 +:108230009E3596AB7A8CE589078C65C642F6F03898 +:10824000C65E6B864ECF646CCEA10F0EB174C6E6CF +:10825000C642CF3CE9632C577585E33263F358E897 +:1082600099B7A09CD790C6BA4330B88D2DC57581FB +:1082700069BE510CF035308295E52D4D65CC35D079 +:10828000FF7C3993D6A9A1B771261BCFD8F76F69A8 +:10829000650CFA89D509F1ED00FFECFA6DB3C7C0A2 +:1082A000F3FE4A5BC143D828627F17E7E782CE4ED0 +:1082B000C17C336D2B478D86FAE1A969422BD4FB33 +:1082C000FEB967AD2F8672CFF49210E21DF0F56E05 +:1082D000FF7C00FFF3C2BCBD3EFECB95C7E68E819E +:1082E000E796CA2766E3734E627DE86FD6A4CE1682 +:1082F00007F477C932A502FB0BD71BDBE7D518CBF8 +:1083000000399F0FFCCB9B3518DEE1E0318FAFF7D2 +:10831000777FB342F8679F033D003EC3F809DA87D1 +:10832000A53E290478CEAD11D438D04D9E2AA89D03 +:1083300016FCD0AEF18319FF622C83219FD5CD139B +:10834000E3ED5025D76527FCE7CE14E20A8C9FBBEE +:10835000B4AFFB14942F73D9E3227CCFCAEC12F094 +:10836000FBFDCB18EB2822F0D26B13D6F77ED71A81 +:108370007B217C9F1714990DE880D58CA1F1088E84 +:10838000D1848F231C1F2EC247DEB2D0333F82F12F +:108390002F9FE49445A87F7903FFAEC3B751023AFB +:1083A00083EF1B81CE624467D29144FCCC39B47C0C +:1083B00039D2E31CD3FB62A88BF3FDDBE403671423 +:1083C000025CCB858E1969004A8ABD89315C68C020 +:1083D00020D2B5CE8F3A9E96EF68217E4CE033FBDB +:1083E00029E467FC7736A186F8EC29D72F65941B22 +:1083F000BB337BB73020E1AD328BD5E733F69FA995 +:108400007D670B50DE2E5FB66EDDF9F03DA5EFE720 +:10841000AC9C31A7F39B336624945353AFA6B24F61 +:108420001B07A610E3EBDD3F2ED1C75F650EDF060D +:10843000956D12A12CD9E44DA1A2817659D84E1880 +:10844000A25D986D922CDAB9F57680A7B5B07EA9B9 +:10845000DABC52B5EF360D9EC4F125C49BACB8050D +:10846000580F69BA2423BD7C5938B2879B77846D35 +:10847000B28F19DC0EC06ED1E1B759C31FC7EF89A7 +:10848000E3DB8780FFABC6C770FD39B4EFA70D1FD4 +:10849000545F9D9D7CBE08971DF595A2B86D09FDA2 +:1084A000DCB9E75F2F9C03C42BCD67A114E843B26E +:1084B000AB7208E8BC4CBEC7859D4B99F57204F8B9 +:1084C000613D945578BFBEABC3A5C0FBB2E2BBD63D +:1084D00021D19775A7329407E3989CF908F43B4E95 +:1084E000965837AEDAF97B6D69506617B35009F4C8 +:1084F0009BB12795E44966D1B93F1160DCCC4C971C +:108500008AEDD332AB7FC2883E982225E023ADF6B8 +:10851000B5BA34846B360B212B4A429CD522938DFD +:10852000051E8272E6B46DAC1ECA157FF32822F2D6 +:10853000B4C4F55D3BB6473DDDC6F6A17E096AF2DF +:10854000679D43DE44FAE35A89A1FE481B778F807A +:10855000F0DC0F5D89C097656559B3EBA15CB6DFB0 +:108560001652149C4F875088F30988A4B7747CEA8C +:1085700072A4E2E36ECEF463597C3BC0DF668F7772 +:10858000A3BC8A4DBE5CDE0EF0E45E9920AFF1AF75 +:108590003EC001C2FBE2A5DBDB8B90BEA57713FBDF +:1085A000CBF838DE8DF28CD53684B1BD6FA66490E1 +:1085B000FFA99A3C4B35E981E62C3BC9335D1F305E +:1085C00055526498B7A0CD9B7D2F4CFAC0C9422E5E +:1085D00007D92B0BC80E1158AF702A0DE68F151155 +:1085E000EE023E8F41EDAB797B1608B9D0CE71A675 +:1085F0003635617DF898D502C815AE4D55513F0B03 +:108600000EE60A56C0BC6D2CD20574D2223009CBBE +:1086100003E375331CCFE94A6B43BBEB2957AB0D22 +:10862000F1D7FA2CE80F98C7ED76D6807641AB1CCF +:10863000726541FBA866BFAD2A1F9D83E50CA0EDC6 +:108640001EB41BA4B08C74B9CA5F9CC3E07DBAB7DA +:10865000F79B2867BF96F9AB19AE0290A37550E758 +:108660005C90FB9B1E5B17AB81F14EE63125C1CEC2 +:10867000734A4D0CED29E7C942C3FBEE6698D199C8 +:108680000365D56DABC771AECD5408AFB54C6EC3A5 +:1086900076B5800C25615D9C27834C9960D57FBEA3 +:1086A000E17D37D8498A7324FDA731A534B1FF3164 +:1086B00049FA3FC3D4BF6CD9FF40BF5E43BF6B24B0 +:1086C000467674CCE7A67537DB05AB33EB5664A270 +:1086D0003DEA644D5D1676674BA68DE0BE3DD0D475 +:1086E000A342FB3A068C0F7472C1E7474446F60C6E +:1086F000AC14D00BCB97FAFAE97834D6E3F46B8B51 +:10870000090CE5D20592DDC0275398B16CB68B4AAF +:1087100060AD715C9BA7B207E967953F55715AC080 +:10872000AF3F7B9AD994E212986F6A7829033EBED4 +:108730003F739F6B4D00CAE99C4E1ECEFCE30CF4C8 +:10874000177A044E7F6B7C36C24BB82EA7534CE889 +:1087500037EC60252817C348DF6E0E0F8EDFE3CF9E +:108760007FB0DD627C10BB06FB61B62A4C294E98B7 +:10877000578F6607F78F3735AF13F9A07F3C27ABCC +:10878000A2F144C07FE278D95F6CBCDFE3FCCA068B +:10879000C69B3DDD38BFD90E99E6375BE35F7DBCF4 +:1087A000DFE3FC8ABEC07838BFC4F1BE669CDF6CD4 +:1087B000A74CF39B2D72FAEA1F2FFB8B8DD7D35C4E +:1087C0004A76F0ED0E904F4027A9E53B5C6360DCF4 +:1087D000DB5D76595006DAD5D6DEE09A8BBAD73D06 +:1087E00075BA1FC6A99B069573B197A9D36B8B1950 +:1087F000DB2470BAF8EBA63FAF43BA383E73552975 +:10880000E913CDBEBE04AB823EBE44E2F0CECA77D1 +:10881000C75B12F0783FC81115E07800F85D057E5F +:10882000DC0A7C89E57873809E0F82BD8ECF6D0057 +:108830002F7E7FA83944E5879B27D153EFA7741279 +:10884000B7DBC7D658DBED676471BF6F53509E7FAF +:1088500025EAB5DAD410EA4536E93CA626DAD5ACE5 +:10886000E9A914F8BEF132568EBAF18CCD1C6E5FB8 +:108870007D36D9EDA9E57B7B9AA17CBB6457502F4F +:10888000DFAEB019567E7311EA992AB457797B7618 +:108890001EF7C37CE1DEBDA8F7E6A09D0E78F5CFFC +:1088A000EDDD8BFEDFA56097935E6687F7BE05DF83 +:1088B0005F03FFAF1DCBA29BC9509E35C74FE3C3DB +:1088C0009FF4DA6CB4DFF99FBB671E23BF229CC202 +:1088D000F5828FCD7E660FC21B722871EA8FDD1B79 +:1088E000463E50ED4A3B8982B01DF5B41FF5347CFD +:1088F000AF3DEC6436846F9A83E4DADCB946BF613D +:10890000534AB78CF6CFA6721F6B81FE2F9D69FC70 +:10891000EE74727E0B9BFC8659A6324848EE778B2C +:108920000B32D0DEBF1D5F4D1E8CB7E8A196DBF782 +:1089300026D0695E96C747718033D81928CF4EB0CC +:10894000B23BEBF1637E16192BE6F6FF6C8EDDBEB3 +:108950001750FF32CABD2AA46F2E3706F307876768 +:10896000B256EFFEE69E29EF960CC0972BC505D4B4 +:1089700003794BE17DC27C255F5C407F87898F94C2 +:10898000A37F639EC7FDC2234166319EFECC65D2A4 +:108990007B88175C4A94E7E6F94E1E34DF9A978B82 +:1089A00099153F299BD09E9BF5AC186A5106F0A102 +:1089B000CFFF7F9AAF8E6A7A86A93ED60DF4F23247 +:1089C000D07B3BF76318DAA93ABD4205B29F2EB9B6 +:1089D00004BE235DA86A01E2F3E5D17DDBAEC27679 +:1089E000203B5AD1DFD5EDA0EE8336B483BE68BFFD +:1089F000975CEB207B8BB17AF9BDD281FE92AD0FF3 +:108A0000F6FB5E82FEECB713F14FB526FA10C69660 +:108A10005080EC819BC13E467F3F5AFF8194CEBF80 +:108A20001F49B053F1CF9184FE5AF7FC4C5000AE71 +:108A3000CEE6AE29EFDA13E4C552D9B606EDB99603 +:108A4000B84071886EA807F6C0E8A58AAD0DF07F22 +:108A500025F683F46992EBA3DBA09F443BA566AEA9 +:108A6000FC08D0435B595D47089EEB37F378995E6D +:108A7000BF3F6EE68B917F6E674D4C00381D29DF3E +:108A8000FB712FCC476D9558CA1428DBB9BDC3DEE6 +:108A9000F2905C10DD4D3FC5EF8118C82D9C775DCD +:108AA000D363588ED958B8159EF7A5F1F651C9254C +:108AB0003B431827699B81D3CF0C46EECD02FCAD1A +:108AC000C94E2539E878DBF320CA294766C552B478 +:108AD0007B1644BF1BC678A4EC650BC316F4B540E7 +:108AE000B31FE2593CEE72C8DE5D900970D706EB09 +:108AF000E2D8EFA0FAD1EF517F53446B3B6CA7D67D +:108B0000CF169BB55C785CFB7EF9F2273E7808E6D1 +:108B10009356EC0E21B9AD3F87ED106C83EBEFF26D +:108B200047BA12E1482996258A83B2AEC968CFAD0B +:108B3000FFEC81AEC700E5599FB949CE66899EB862 +:108B4000506468BF33AB6A70FBDDFF7A3D80EBB3E6 +:108B50003B85917E65EC850BD19FDCD85F6631014A +:108B6000E39C995A39F6F085AAA1BCF8C25A2C2385 +:108B7000ED02514EBEFBDBEB63D85EE06516FB0EEB +:108B8000AF6FE7F573B4EF532EFAF02777A23EA844 +:108B900076901FBA51B38374F8CEF38A443FE779D5 +:108BA00087C6E3414D2EB8468EC7835678DC1D54E8 +:108BB000DFC4F729AC4B403A4EF9CC7523B6FF61C0 +:108BC000330B5F09B06F5176FCEC4E85DA1FB6C2ED +:108BD000E35941F508B6772D3FF2933B010E8F0E16 +:108BE000C74476631238FE32D47AEEC8E6726E9EBF +:108BF0008FEB8D2CCDDE74387A02B3E12957FEE07D +:108C00000619E4CDDAA2AE06ABF8F309AF8DDA654A +:108C10002689B7677839DE76E5843F4538DAE42778 +:108C20005C387EAAC0C2587FC3A45E2624F47BB6FB +:108C30008FAF03C06DF342BBD4C94C453AF3304FFC +:108C40009C019D792A39FC1B02AF3105DA794AE192 +:108C5000E9C6F7BDC4FFE87270A106820ECA0E8D88 +:108C60003E32EE6EBF10E9214BD4E92DAF1DE9C5B0 +:108C700061D3EBE75D84E5CE2C5E2EF7E5B5C7F258 +:108C800041CF38A00DCA855C07D93BE6F9E568F00D +:108C9000B6FB55BFD76F814F672FADD3C6718E50CE +:108CA0000CD6758AADA761317EBBC84DF61ABC6F74 +:108CB0008827CC7FBA4687D3BDDCDEDAF82F57434E +:108CC000DC623D92D1E978EF69D3E978AF359D9EBA +:108CD00083F84FA0D34F98359D565BB5073A9D68F2 +:108CE000850F735964EAE6460050FA74FAC377A216 +:108CF000B6FA7ACDE6C7E039E533B7E4853AE2194A +:108D00008CEC449B8BCBF701B91F9986FD4B7213FA +:108D1000BD17DD61DAAF79318BF73FA8DF89D59BCD +:108D2000516E8DA0DF30CEDBDCEF282F8777CA4570 +:108D3000EE48DC02EF27BD12F74B7D7CFC64FC5251 +:108D4000EAE37E73527ED1E93F271C413886E397E0 +:108D50000B06F865E9C8F86507F14B5A19E797B4AF +:108D600024FCC2624EE28FB545BC7CF3DD3EE28757 +:108D70007EFE899518F9275662E09F69F794507D29 +:108D800073FB749CB7055E625E7D1EE1669C877A0C +:108D9000B6DC2692BDD1CB504E75B2BE3D4EE4C37B +:108DA0001A21B41DDECE8AF5D4BB14FCDEC3668363 +:108DB000FDB14EA3FBAD080FFA43D55A3C4BEA6117 +:108DC000977A06F3B1A7B2BB349280FF020D8F975A +:108DD000F9C277E2F89DAC772CDAA5C9D6E91E0D69 +:108DE000DE1B03EA3D56743E9CDED9897AC78F4F5D +:108DF0000E77D667AE269403663E9F72FD6F3F786E +:108E000068887E7EA5C1F1A8F63C0DBE7FD46BA517 +:108E1000A783EA2F4C7C5F298CB6E4FB5F59B5072A +:108E2000BEFFB5153EBE049F3F65C5E70F7879FFCD +:108E3000C3E159F2713C4BBE2F87E723DA3ABD7983 +:108E4000FA787E33099EFFE8F58F08CF4792C8D79E +:108E5000A35E82C316C37D01E477F4DFD74D8CF5A2 +:108E6000E17EA8051C7F4DECC7A5F07EC0B4FF4491 +:108E7000003A9FF2E9BA50C4822FA1DDB144F8F55F +:108E800076F77865CD8F5056A25DBDE5EB6EDA4F73 +:108E9000003DF80FEF572BE76D3E0B793CC5C6E55B +:108EA000D065771F5E8F719A2FD17FBA55FFCF693A +:108EB000F4359CFE2F4AD0FFD88F59DE75321E4FF5 +:108EC00069F747F27D84AFDE0B513E6DBD254B4007 +:108ED000BF2E5FED16D0FEF76BFA65A397FB337AD2 +:108EE000BBAD52B72061FD2659880986FECE18AA6F +:108EF0003F331C00DF5884EF329F7A163EEFF1F6C5 +:108F0000DB7BA7650F5507D40A6C0F72BA12C757DF +:108F1000CF34CA697D1EB67017EB45FD02EE77DCD3 +:108F200082AEFC9ABE847ECEA77E34795FE5D3E91B +:108F30008AF777BAFA06E09BAEC137039F66F8CC92 +:108F400078190ECE9B104EDEDFA5897026EB4FF709 +:108F5000AFF575227D9A10D75938A0AFAFC0FE5C2F +:108F60006B6C31E61BE05F5D5F83644AC5FEB7381A +:108F7000781C75CBB2BB6A31DFA0F356B91C519295 +:108F8000BB94EB39655921C555AFD1FA35C3DFDF45 +:108F9000DED1357642198DBB1CC7BDA08675A3DC1A +:108FA000C8403B81E20FB284F1852C674700E3B2F1 +:108FB000EB858E8645A8472F7493BE6581B996F1DF +:108FC00029FDA9C79FF479B340E530F55BA8BE9CA5 +:108FD000D6D18476D288EB3B3B2CEDAAEF6B76158D +:108FE000CC6FFD90780DF828BEA5E377F0387CFDB6 +:108FF0006AC34D02E23BB50C8604964C0D77D066F1 +:10900000ABAD38CE7AD17E2A057AA1FE5EB38CFB59 +:109010000DF4B75687EB01A4C72F0B975E2FF97895 +:10902000BC1EEE9F51BCC3CDE5167D80F2B167BD7D +:1090300096FB07FAF3F666599540FF1C93950C8C46 +:1090400017DEAEE941C642814B3DFFFE7A03F3884D +:10905000F378A7A97E9471BA670117D97718864F5C +:10906000A49B577DDC1F6DCF0E3FCBE56328847436 +:109070000DE5E711FFCC05650F95F75359EE2FBFAE +:1090800044F503BC3E93E511E119DAFD81DA49FDAF +:10909000FDBC41FDBAFBC73D48DF7DFDE53FD2F792 +:1090A0007C5E7FA4E324AC2B9F7F8F48F3FF445268 +:1090B00033707FF4B2E8628A13CD8F5E43CF75CDF3 +:1090C000722DC6E35E6AEE6B6B83E765F317CB68C0 +:1090D000F7CF5F7237EDDFEBFD5F827E05F2BB22DB +:1090E000CD20BBA8C816DEE61EE0B70138DAB43CD6 +:1090F000B3DE7AA42397CAFADACBA1FDA48FDBDA18 +:109100000C794E1D943F93A2489F26C6D57539F819 +:10911000A143FD94E63F723A36CD97B1BD30FE27AC +:10912000EEE2788CE8BA4EB6E2177DDEC9FAD7E7F0 +:109130009D4CCEE8F8D3DFAF2FAE9079FE4FDC80A8 +:109140009794927ACAF7B944D0E0F4B8347EE3F544 +:1091500066C1384F94117D2848BFB3343FCEAC1759 +:10916000F4713F74448AFCD80EDEDC5A6181DF1151 +:10917000E2ED40F3D270BD1DE571570AEDDF339982 +:10918000E2FC7ABD8624F33FDFCFF50873AA349F53 +:109190000DB765C4D1EED8D0F82B19832B69E33E07 +:1091A000A98AE153E83BB108E5CB6D1ECAC76868E0 +:1091B0003C51D592D0FFC2A7FFC385F1DE8671ABCB +:1091C000FD187759C8A44F12F31DCCE33644AF27DE +:1091D000BA8DB5080D56FED61BD99CAF17628A8C86 +:1091E00048FD1D49DC476E542A1C189F688C19F7EE +:1091F0007340433A903E16AF33BF4FD8CF11B17F83 +:1092000046F38EE1661EEABD3536A2B72D8037F4EF +:10921000030B415DE2F38DEC2C8D1F7B089FFF6EED +:1092200078DEC896F9BE9B8BC5D2B206E82627D257 +:10923000C1503F792A05DADFF479F4FC882ED25345 +:10924000F7B8F532E82DC07FB84CB3738AF9771BB5 +:1092500096D1FF49EBD96B033E5E73EF531705C6FA +:10926000427F6591804DA6F2F3921FED2F5E66B1AD +:10927000A79EDF4BF6AC7C961002FE6FDBFDFCB3C5 +:1092800005E4CF6BF6D8EEE7C91ED3CB8C753398C7 +:109290004F676A7F597505A03CBABF1CC3F256CD13 +:1092A0008E5F73EFEEE7DBC83E09C7FC097AB29622 +:1092B000F1F8F257AD1F3B035776603E51ACD846EC +:1092C000FE5EAA891F1FF13BA85E514EE42EE2C745 +:1092D0005BFB248C373882AFF9500E8C2A3EA68E69 +:1092E00006FA1F55C3D36458291FB7B37815D90D93 +:1092F0009DDABAC0FF56A3DE1B589F1ED3FAF0F5C5 +:109300000857F6D0FA78CA7A68BD6C58A6B81FDF3D +:109310008FBFB892DB1BB293EF2B6CF7737ED8E153 +:10932000E7FEED0E3FF74F338AEFA2F84ECA0C1B53 +:10933000D5CFD09E6639BEC32F69F29CE3637730E8 +:10934000D2E54FB05BE17DB8B412E59B2F0BF75926 +:109350006B8BA51B919E7FACF9A7B04E77D23A15C7 +:10936000F952237CDD7EE3F75BAC5BE9C8D6EDF513 +:10937000E608C9AB64EB76D97C316C15777B5EC3AC +:10938000C3470D7FFA014E67B9ABCF81FB30EB8B42 +:109390003719F2AA5D3B6677632EB49E57BD3A2D0E +:1093A000BD06E5B679DCD73FFF2F1FE277E6BF9C0D +:1093B00096F2F1634D3EBED6DC40ED608115299BEF +:1093C000E400E3792FFD7962C229274DEF75CC4384 +:1093D000BB82589FB1B9E1C3B45FBD282032DC1F06 +:1093E0005FC88C79652CAAE705F33CD8D725704D6A +:1093F0000185AFC78410608A354AB375B962C80F5A +:109400009B3777F63EDC875FACEDC3837C317C5FB6 +:1094100062CA1BBBBCA1315CAF7D3F4E7FC7094F09 +:1094200073156E37CE75BB49BFCE0BCF0FD727EC68 +:10943000C7BDF1DFA2651EFAF9D93A5EC2E1FA9220 +:10944000C1785914161CB2323C7ECCF8A89538BEAF +:109450001A357C99F163C6C3E2B9B369FDCDF37FD8 +:10946000DD1526FCBC0EF8C17C61333E188B5C8C8C +:1094700074FBC67C91A17D3C5D9C69C73C81C5B3F2 +:109480000586F9454B58289DE707ABB3A625C06B69 +:10949000C6A3195F8B9F64A16EE877F1BD1E5ABF0A +:1094A0005734FC88DD7FA77985615EED7C5E477867 +:1094B000FEAA4CF3BA542D7FC607DF236D206D152D +:1094C0002B3DC2E7B308E6D32E0FD62727584D13FE +:1094D000D2C91253DE82193E33FC33510E4E1EBCEC +:1094E0008F5F91ADEDE38F67216D1F3F838E3584D4 +:1094F000FC43E62D0CF039A7AF85D1D9FDE361BF60 +:10950000028BF49765C0EFCCE7BC1BE7C1BF5705E2 +:109510004405F30467CF1FB306E71F66E18CEE2214 +:10952000B4F7FBEC28472E6560C642BB0B6092A8DF +:109530006FC3F52954D6FB3DD6F1B19DF47884353F +:109540006DA7FD772563EEB8E4F26555C041E39958 +:10955000ED9499E52519282FCCF8D0F1340FF1922C +:109560004678197F3A7879017515FAB318478375EB +:10957000ECBB86B107CB07F68F59BECAEDC96C4666 +:10958000FBFFD764676A764713C51D16687AE190BA +:109590009D353CEEE6FBC81509F2F11BC1DA6BB252 +:1095A00013EC547D1FD9CD7A097F57B8DCDDE27802 +:1095B000A2BB0FFBE983E4979EAF19A17C4D3163F9 +:1095C000994271B1B4F4F12C03EC62C6E70D7ECC84 +:1095D0008DD97E7C5F18472360E6733F59374F195A +:1095E00058B7F5576EEF40799CB2E49731EA5CE1E9 +:1095F000F91C69DABAD56AEBD66F4797C2FB04FC4F +:109600001EEBD0ECB0522D8E8F7FA07CAC588D0F0E +:10961000E5BFEAEB98520AFE87218FB083F0ADAF29 +:109620002738117DC89791804439C336E622FF3828 +:109630007233CFC758C894AD981FB4306A3F96D8DC +:109640004F2428111C91F5295ADC2444FD2C0AF2E0 +:109650007E5829F7F3FAE93E06ED13F21F6D2E301E +:1096600025B17D260BA1FF04FD65A3BE67EB12C6E5 +:10967000193D78DC64FD99DB89DAFEADE80C8542A2 +:1096800009727ABB663F1F0B5476D94627C7DF2283 +:1096900097579512F2628F045D0D567131BD3F5D93 +:1096A0007FF7DB89ECEA1712ED44B7A3F18567CFAA +:1096B0004FB01359E30BB8EFFF45EDC497B21B5FF2 +:1096C0006883F9FDF3ADAF51FEF8B12610988047DD +:1096D0006F742A3BEA45F92093FE2A6C008F0A93A7 +:1096E000BF25652CD27B4A344F9512F265DFC856F0 +:1096F000087E6FB14AFB65D0B40B5D71AF141210D8 +:109700006F7769713320DCB1B33D89EDF8BCF5F1B9 +:109710009C2E99E070E8E3B1500BE5D7CF64A447E5 +:10972000F43C109DAFF57E8E661BE37523E0E7A346 +:10973000D9FEC1FC2C8A4DEFDC8672E20591FCB0AB +:109740006F056EA6F7E678C0DFB2B97D582046FEF9 +:1097500086FDF434BCFAAD9BA0DD8A1DCE10AAE1D3 +:10976000E5DFF9E0FB550AE289AFFFFC258BEFADA1 +:10977000C279954832ED6F14F0388CA34520FF353F +:10978000A5C811DE01CFC3BEDADC9C04B80EFBEA2B +:10979000A93C7A0687EB18F4D9AE60BB4D0DE42FD7 +:1097A0007AF8BEF73145C960245718D913A2933F00 +:1097B000DD393C2EECCEE1F13C2987E3DB7552A08C +:1097C0004542BA6EC27D0B294679D0AE9312BD7761 +:1097D0000882A5BDA6F7E73A09C219F195666EEFB2 +:1097E000A0F7381F6C2F7A99C1BEF1E7703BD9DF23 +:1097F0000F471A87C36BEE279DBFD7F8CF0CC78AD8 +:10980000ECA941C4CB619F9A9BC3E3285C0EBB9F2C +:109810003F208C1F893CE6F9FA17072517C5F56E1E +:1098200013E225209FDA4B8FAD21B955E46AC2734C +:109830005209F693C0CFDDF0731503F669DFB43932 +:109840009518BD66CAFDA1C1F6D63B9527E6CDC1E8 +:1098500082767EE20A5DF6C6A00CF6DCDB5AB151D8 +:1098600019BD1643FD97D470FB6C31DA6721925B0A +:1098700006BBCB6C9FB941DFCF01BA58129064A4EC +:109880000BB39DD65E398FEC9A76B06B305F7BB0B0 +:109890009DC6E5CD1D511B53A1DE4B3522F9192F75 +:1098A00095F63E7701EA8B497685F44569DF1D73AD +:1098B000E8FB041AC7ADF977509F9F7708A5C54B01 +:1098C000E0DDCB3547DD8B13D6FBA54947C7A25F4B +:1098D000B035497E851EA7D97B0BCFFF7AE71E21C5 +:1098E000EE44BCDD2ADAB0DF85E51ECA5B9D26BAF0 +:1098F000699CC51BC5B89370A8A64FCB1EB01B9919 +:109900005893FD2AE2E14E3BC3F3830537F61AEC88 +:10991000DC8551A33D176902FB47397D3BD06CFFC5 +:1099200099ED98E5399AFD52C12AD07E79A9792717 +:109930003B5A3260C7CC4AB2FFADDB31E7DAEABE50 +:10994000ADD133ED1FCC92ACF7F72FD6FC5316E216 +:10995000FEE034F1435AAF63214941FCB96F7E9E6A +:10996000CE75B8FF5B0C5B8D77478E43DF8F237915 +:10997000BBB5228DF2AEF7DC72564E2FAD97725FFB +:109980000DAEFFF3769283C9F45B4A5464C530315F +:109990004F54A0A7BE9EA3A2292C513F8C4A92A748 +:1099A000F0A31C3E0FFFADCC867E76668CA9567E5A +:1099B000A95E0FFCD1E918A386FADD9900DFF5C591 +:1099C000368AFBEB7E698A9D9FF7B5EF5A1943FFF4 +:1099D0007414C0877028001FCAE1A2681A9547470F +:1099E000BDF41C13CDA46771348FBE9744C7D0F368 +:1099F0008C6811BD3F337A36954BA313E839365A3C +:109A00004ECFB3A2E7D1F36CD05B58AF2C5A4BCFFB +:109A100071D1AFD3FBF1D139F43C273A9B9EA1E839 +:109A200037E97B7974313D2BA28DF47E42F43A2ADA +:109A300057466FA0725574253DABA3DFA5E7C468F8 +:109A40002B3D27455BA8DEE4E8062A9F1BBD9B9EB5 +:109A5000E74537D1B326BA85BEEBFC9CA6D9D32FF8 +:109A600006B6C9946FCFBACB503E26E3C3439A3CA7 +:109A7000AECB51F722FDE9F5F66BE70ECCF50EE41F +:109A80000C9D77F3AAB65E1F858EFC008FD3EAEBA0 +:109A9000B63E30741C8195F986D9B7E2F37B3A471C +:109AA000E1F42B7590BDB1B589513E98A7B24740FE +:109AB00079D319906658D1913BC0F3C08A7222477E +:109AC000517FB883EFEEC5FDA84B623DBEA9482F7C +:109AD000215FEA54E86F549B8DDC6B85C902969533 +:109AE0007A2677B381780ED85706BD260574FBAD6C +:109AF00067E60484E7ACE20AB25FB5FDE4FDB78C2B +:109B000066E8776C75740B12CACB558C25DAE15B6D +:109B1000D72E7A28F19C8614E0FC396A1D7B0AE373 +:109B200064451D4A1D9E271CB3597D0A533C4BE2D8 +:109B300091BA54289FF970EC297C8EED8AD7A5C183 +:109B4000F3EC9DDD4FA1F819D7DD5BE786F239CF45 +:109B5000B2A731FC54DEA34CF54079C201F569DCB3 +:109B600026A9EA8D4C4D57109E786B3AC0B3F56D1F +:109B700030B4A03CE9C30E11DC9281F507BBEDF1D6 +:109B800084754929EE5145F867FE8D7239CAD9AD01 +:109B9000526F4A66D9E0F5E9C479E33C41AF6CD72E +:109BA000F6D1E584F50805043D1EE80B24C4033B0B +:109BB000DB5EA1786067AA5C8BA1AEBE694C7E506B +:109BC000413AE67E42EA9AD1A49F74BA03FC1AECA9 +:109BD0004929C0E96E6BBFBD698DDF10E2B7EA7F2E +:109BE0000F7EFF3347935F49F0FB22CE23383C1FA3 +:109BF000D706385F021F9F1FA84A5EEF2A0DFF6637 +:109C00003C6F95E4B3085F6E668B950FAC5BA34623 +:109C1000DFC3E1F59BFFCBE876526068BCB24A2F08 +:109C20008F336BF969C9E4CDFE24E7449A0283E4DB +:109C30001C8F97CA20E7C6249773358161E4579239 +:109C40007C87DB027ABE43F8BB8111C4F5EFB0C953 +:109C5000B598EF121BCFC84F00FBB20DF37746C586 +:109C6000940ADAC642A18C78AC389BFCF422B03757 +:109C7000A40A86A98EDDF8BCB832D3B6A80CF31AB4 +:109C8000347E931B0389FCA6EBFB017ED4E922AB57 +:109C900093CE5900BD623EE12E0D4F03FDF078C416 +:109CA000DA9B733BDB13E46067288FCA7AFD64F4A8 +:109CB000FBA6F61DE405EDF75F5C639D6FF2EB809C +:109CC000A8D9397D2AD2796C0A93E9BC73DB119249 +:109CD0004F99209F84221E1EC2F1F3A3A90F619CFD +:109CE000F657816C4D9ECBA99779FEFFD1733BF857 +:109CF000EAC44F35F21E3C57310AF4908272B20624 +:109D000060AF443DE7A07557185F47A586C5BB0502 +:109D1000C25B37FACD311B3F9FB1DFD1A592DE7117 +:109D200064CA987FB2CB1FD91BF027E70B394D29A6 +:109D3000C745FDC3E66B67BA83989723A762F915F9 +:109D400028DF3109F3847A9956BEC33DF98BC71FCA +:109D5000FE10B8663FEE535507D457919E81AEFF73 +:109D60008070A967CA12C58747B8FFA4F3E7003F10 +:109D7000C9E53A3F3596913C7C2790B04F9ECCBECA +:109D8000F9A1263FFB0243DB373ADD9FB67DA3C135 +:109D9000FBF630FC3FF3B957376F6303F13F4FEEEB +:109DA000EB3D9282F6F654767402C6BD7A38DD3306 +:109DB0001EE75331FE07749052E932C56D85195A7A +:109DC000DC65C878AD1E4FD6E37D7A5C2F5DA32B92 +:109DD000BC3000F578FA24595A44FDF5B24BA13F46 +:109DE0004F90E349E76B945BB83FEF5A93258D2E74 +:109DF0001BE8172425C9A9CE0626B767F2FDD70CA4 +:109E0000902F1DAB19F979B19744EAFFB86AFBC0EE +:109E100009F58E570202512EA84C91B3B573084430 +:109E2000E432D1AB93B12EF4B7D9F7422E07C6B9BD +:109E30003F15980A70EFFF54A4A784116E687471DF +:109E4000A83C848D6B336A42B81F281E8532C059E6 +:109E50009F519381E5FDFB27849845FCEEF248A3D2 +:109E600021BE64C6537FBD6FADA17C852DC3EC7F41 +:109E70004E0A3A74BBB32288F6CE957D6D0E6560AE +:109E8000FF53DFD70B163F7121DEB3135CC6EDCF56 +:109E90005C166F49B49B12F6176BB09F2D03FB8BBA +:109EA0003D6724EE2FAEC8BD158FEEFFB07F7F312A +:109EB000720ED657BD5DE5489F7A3EEC7E07DF0700 +:109EC00060135EF02916F4B1A0FC193FD1A3E64F50 +:109ED0000CFAAEC5CDCC7EF0ACA0318E7F3C3427E1 +:109EE000A31B3F2689E3EBF13CDD0FC6789D6CC9CF +:109EF0007746FCEBE32F10B81FCBEC02C93B5D6F3C +:109F0000823C8904FDD48CE2D1AA53A07CADE3A1AC +:109F1000C50AF94549E44BFFBE01EB2EB1DA675D96 +:109F2000A0E59D98DFDF1CE4FA79819DC72985951E +:109F30004B2238EE82A04B7026D8495705B9FED285 +:109F4000F75F1CB927AB10CF0E4744B19AB7791F02 +:109F5000E5AA20EB3FEF16B2D07BC9F074C0DE411A +:109F6000FB72079688745EF7786422DDFB904C2EB6 +:109F7000BC89F453C25838978F37B08ED678D3F354 +:109F800064CCFB55FDDF1B53E8FC8D395FE6510DBA +:109F90006FFB34BCFCBBF365F669F87B518BCFE8F3 +:109FA000F1AC8B93C8FB736D750F131D0D139739AF +:109FB00043CFF7D1F0C39E1E4BF7726CE8B1C75385 +:109FC0000484C746FB970D7F1043687FE9EDDC26CC +:109FD00079A1E7EFE8E5B493028B27EC23A4495D70 +:109FE00014274D3B29D17B33FFDD6EE23F7D5D922F +:109FF000ADB3BE2EE6F79DDABA1C68FC8F009E77E3 +:10A00000D990C22CF3893E0B1AE3EFE63C8064FB47 +:10A01000DC07B576C7239373502E3738622523E1CA +:10A020007B1D3FAF7FFE1B17F2D98693CE1956EBEF +:10A03000F14A90FB2DA04FD725EE837AE6BFDA8652 +:10A04000BDA649C67D505D9FEAFBA06995E67D34BB +:10A05000EB7DD00DCC5A3E26DB071DB4FFA9E9DB12 +:10A0600013C124FB9F65439F67DFADD1F370791F58 +:10A07000973BF87959F3FB17FAD7617DC10F80AF91 +:10A080006E6874D2EE5377A393F87071630AC56556 +:10A090001797F378EFE27B056DBFCE18877D11E44B +:10A0A000C5323C5FAFE99DA32C5C8DF6E8AC4AC19C +:10A0B000B04F1EAE493194E72FB9FB45BC37E1A53F +:10A0C000497685E2CFD0570CED821A9EA7C894BE80 +:10A0D0003B30CEADC79FF5F57FA9E628DD8316039B +:10A0E0003BBF2484F16791F8EBA5D726F07BE98488 +:10A0F00081FD7005EC840DE78EA17C8F8365DFA068 +:10A1000038EF068C8BC34C377CFE9B194447A094D8 +:10A1100063C8AFE3B3E2281F178FABC846BA7C7A97 +:10A12000FCA71E8C8BBE73EB713FAE536F7313E5B0 +:10A130001D98D7DD1C6736C7974F379E3C31B73F18 +:10A140004F80E8E145533C59975766F991104FBE4F +:10A15000207704F1645D6EE97242975F07CBDADF26 +:10A160007A10FE7930E22498DED4E6DDCF971A5DCE +:10A170001ED4F9F07327D9234F8FFF2DE55BE9F546 +:10A180009A8399C487DF288BDB697F16F3144A070B +:10A19000D6657EE49AFE3276FBCDA52B0DF4D12F49 +:10A1A000A786956343CB293197C72792E56BEA7C55 +:10A1B0003058FF94909D9AF67B7BDC55F4C5F550A2 +:10A1C00043E3AF146C07CFCDD47EBC2312B7D04F7E +:10A1D0006678D24E8A2C3E21F1BDC2DFF7EB010733 +:10A1E0007D8FD529AB57FBB83DDD4AFC1973D2FEF4 +:10A1F000B94F6DCE85FA3EBF1A437A78C8A7B6E448 +:10A2000026C8D3563BDF8F146D2CF2B8055E9ECC6A +:10A21000D5F4320B07B0BF35B5C6F35CFA737B2EAD +:10A22000DFDFDBE3AF0EA07DDD7AB83C80FCB3D787 +:10A23000534DF676B275BB53E727945F2503FEC4F2 +:10A24000466DBD814555DCC75D630F0712E38DEB9D +:10A2500072791E47FAE4277AD06E6E956D9427D8EE +:10A260002AF3FCEB36B734639BD6CE676827E9E761 +:10A27000A8E8BE0CC96DCCAF7E52B37792CDF3C9BE +:10A280005C9B76BF68F73D35C2805EB11FA975D172 +:10A29000FD0F4C95797E53C8904F6DD7F44B9D2997 +:10A2A0005F4394BF98DF16F44776E55AF86D7B7CE0 +:10A2B000EA93B8DE5129E644FA88BAACF9FE696D32 +:10A2C0005DBFA7CDD77CAFAA68BAF74134DDFB10DC +:10A2D000AB6BFA692FD2DB6AA7DCEAA37B1EE8DE50 +:10A2E00087285EB904CF7FA6F07C16F0FF26F2F334 +:10A2F00006A15E94AF2CE0A2785447BEAAE643596B +:10A30000F4D81E5C0DFDB5AA752A1E5DE970DB3A16 +:10A31000719F2F33183988F398EA9148EF745C9451 +:10A320004A7A08BEA77039C264A19AFC41BA3405C2 +:10A330007D703C5F660F38289ED51A61BDCE31FC1A +:10A34000FC3FF653CBBAF7D714A1BDEDAA443CEDC0 +:10A350000F4DC88858C809FD69DEFF7FEBDB6F141D +:10A3600062BB0231F221E2BDA761F146DCD75FB1E9 +:10A37000530CE13EC2B7BE73F00C7EDEC8B8CF7C92 +:10A380005FDA945ED46751B783EAEDF15477209E8B +:10A390005A054F07FABBAD8757FE18F1D8DAC2E36A +:10A3A000DC663CEFF57C87EED7380ECB89F5CDF730 +:10A3B0006BB08E957C9D9C2EDAB784F9B2BC2ABE18 +:10A3C0008E141F3CE4A17BA08EEF7FDA8DF07D8997 +:10A3D00079A7E5F9879A77BE4CF68B463F4C0AAFD2 +:10A3E000C379DD247A3ADA7D784F1AAC37C2BDCB17 +:10A3F0004EFEFE7D69E9B4AE51800FD755F4D4AB63 +:10A40000E892FD7DA748EB1C959A685E2C26B1ED7D +:10A41000F87ED789EF9F8774A066D1AE9658D04456 +:10A4200078F93BE065B5055E807E8A10DEA777DDB2 +:10A4300040FD74385C325A36AD9E6A3AAF3CD2FB6E +:10A4400045CAF2389F24DC2F52965765515FF3B30B +:10A45000D0DFC6716B65F6499C0DE03D59FECA79A7 +:10A460005AFFFDFD0C9FBF725EE2F8FAB85F625DB5 +:10A47000A79FCEBAB6BAFEEF74B4B354313D94522E +:10A4800008655C27C43FAE13AE9716B72115A4200C +:10A490001DC8DD79480737A487903E87931B12E3D8 +:10A4A000EB6E97809EC1AE73CA91037476518BF7A1 +:10A4B000E8F2C4CC67AD2EA3BC6AD5EFE53B3432DD +:10A4C0007905F47215E2C12CB7464A272BF304F341 +:10A4D0003D342BF3FCC9E9C41E0CDF80EB8878CA3D +:10A4E000ABA078C5B7B1FEFEFDE20EC7681C8FC7F2 +:10A4F000CDFA824C7E30212F4B87A70D37BB799C3C +:10A500009AE21F5203639807E72D0D0972D988E874 +:10A51000A82D11BEAF808EEE1C8A8EDCAC87CE6B70 +:10A520002CD7F373760C9D9FF365F50FAC6727E28C +:10A53000B7D5F31DA2CFB57697CCEF513BBD757D56 +:10A5400064F0BA3E32F4BA461EC3EF6A5E35DD638C +:10A55000C4263592DDB4CBAFBE8179A44C0A19E490 +:10A56000E220FED1E4F64D672A94AFBABB4593735F +:10A570002D4E19EDF1677C373C86F5EF624A18E302 +:10A58000A1536CAB084F7F87F93D1822B95A8AFB5B +:10A590003E51961AD2F4E8538887194A8B9005EFFA +:10A5A0007D0B141B5D43AA6C62B6B291E3E1C5C199 +:10A5B00072F0C561E4608F46CF37223DEBE7ED9343 +:10A5C000C9C143A72F070F7DC572F0CF79A7A1D7C7 +:10A5D000BF0279F3098E6796376E8D9FAF08B11071 +:10A5E000C6CB479ACF06F6A682FC559BEE22FA69A7 +:10A5F0007D5CA07C29B0C32354F6B848D8ECF5386C +:10A6000078FEEF0EFE5DACE37836E3E9F3BC2C9EFA +:10A6100077D3B5322C19F2A462C40F77AAC7E462CB +:10A6200011F3FB6B889EBD9A3DA3E7F5A76BF2BFC4 +:10A630005FCFCFB4D178DE022EDFBD60EFA05DC466 +:10A64000A45E867EFC4D793C7F1FF881E81B46099D +:10A65000233F644C924C795A9C5FFC12B777327D51 +:10A660004C205D837962F0FE04D813783F41A66ADE +:10A670006C7753EA1502EAADDE46779340E7F4C300 +:10A680007B7E04E52CCCF702BEF1CE30D6F7B38446 +:10A69000B2857F1EAB63A598B75896AFF9E90E1641 +:10A6A00020FDA8F9E9FA7D81E2F0795F95F9238828 +:10A6B0002F9E9BAFE79918F571570AB38CAFFD57E2 +:10A6C0003E975BF5BDB5756857AFF230B2AB56A19A +:10A6D000EEC472A683EEB509EDA97459DD5791A9B0 +:10A6E000DA0CF7F37A67A41AEEBDF587B30CE59C94 +:10A6F000865C43FD6064B4E17BDED2B30CDF0B9A71 +:10A700002A0CE551D1730DF58B00C189E531EB2E93 +:10A7100032D42FE9B8D4503E73F3370CF5C7C617BF +:10A7200019BE9FFDF0B586EFE3BA5619CAE7ECBC37 +:10A73000C550BF9559DFDFB9219FCB29E0779263E0 +:10A740002DEEBA06FA1D0DD96188F32FD1EAEDC9B5 +:10A75000AC2EC57848EB91F252F287D3CF1DD21FB1 +:10A7600036CBC564F2D8FCBE4D1BEFA3A7DEAB5EB3 +:10A7700086748E421EE4D247EE37D7E29CD697F11C +:10A78000BC04FD7731CCF7F2F7EF534A2ACD67418D +:10A790009683599D0F5892AF58EE2FB4092117EEAA +:10A7A0001525C39B4E8FC3E1ED0EADDE97C5DB21B2 +:10A7B000C11807427DF2B8055C7BF3FBEF3B7828BC +:10A7C0009FEBABCA54F230F83D0EA7AB4F74384044 +:10A7D0009F3C9EEF1F9C1FFE51C3AB57DDA760FD42 +:10A7E000AB787D5BA814D725D9BED2DE7CF3BE52F0 +:10A7F000D55294730B3CA942E27DCDBFD4EAE9F176 +:10A80000ECD6F44F695FA9D5112A1DC9BED22FF12C +:10A81000CE8D2AC4BFC2C7D3D7D5AE06644BFFCEF8 +:10A820006CC7B0E7F01E8C985BA2BC61B37F17D5F4 +:10A83000E4B6EECF497B6BC9DF6F758FA6BC8F5630 +:10A840007515E9CB8E247E2EE8CB3FE657613CE0C0 +:10A8500046833F37100F50693C684B76536B82FF3D +:10A860008FEBA0DEC7EFD5FE0AFCE00FF34FC34E1F +:10A870005018F7838F338EA7E3AA8DEC84E360270B +:10A88000A0FC5D2331DAF78E550A8A955FDCB15A58 +:10A89000B30F5773BC99F7BBCD76C6C5A19584B7E6 +:10A8A00035404FAE4A8CC771FB778D9DDFBF297B4A +:10A8B000C301D4B77D7E077B10A0DDEBE7F1391D26 +:10A8C0002F5F541E65160CB293330B86B093A78985 +:10A8D000655D786FEBB1933C2EA2E051441FDE43DF +:10A8E000CED76FD57373622B504F15494D98BF2E3D +:10A8F000322503F1B2E25991C5059463C6FC7C3B55 +:10A900006BFA01C6E3988FBF8F31570BDA49199361 +:10A910008C7A2C5335EA31EF8C2C935E33EAB19C60 +:10A9200006A31E0B468C7A2C6F698549AF19F5D8A2 +:10A93000A8689D49AF19F5D89875979AF49A518FE0 +:10A940009DB9D9A8C7C6C68D7AECEC875799F49AF9 +:10A95000518F9DB373B5E17B7977BBE1FB8467EFE2 +:10A960003294AB7AEE37D49F78E041C3F7C9BDFF8C +:10A97000C7F01D10FD0A9E67C07B687111CF7BFF79 +:10A9800009E377A63A301FFF3A3C9F09EB787EDF58 +:10A990006F0DFDB10E7E6E2106FFE17AFD9945E84F +:10A9A0001E009063FBF2A0DDF57121D4CD503F3D38 +:10A9B000FE1EEEDB5C1310C98F5B81C156A4874776 +:10A9C0003C71A487AB371BCF3F5C13379663403F86 +:10A9D0000AC615807E90BEAE33FD6E04D883446FE8 +:10A9E000D7295213DA9566FAFAB34E5F31F5153C62 +:10A9F000CFA1CF579F9F5D3F7FAAD19FAAD11F13A1 +:10AA00007711DCD7E589F4FB3BFA7C55F88F7FFFA3 +:10AA1000D081F338B153605EDCDF67B17D7916F326 +:10AA2000B97EE72607F2A7795EE6790CB2530B8C64 +:10AA3000FB8AD3447788F8EE3591F4114D01F9EC97 +:10AA4000517E5E6FD573229D8B413E447F418C3594 +:10AA5000105E56005EF0DE70DD6E3DA6B53BF68002 +:10AA600048E79B87E34745C3873360E4C71425D590 +:10AA7000444F46FCA6951AF9F3BAB72F74A0FCDA36 +:10AA800007F8162631E60919F9F53A7119EDF3E9D7 +:10AA90007856E03F1C57025317E77D3DCCBB5B194E +:10AAA0008CDFA5BB36ADCDB3A09BE1F0FB48817137 +:10AAB0009F4EDF9FAB05EC382CF24A75FCEDF2ABF4 +:10AAC0004FA07C4CE60FEF2E30EEAB8FC01FDE9D0B +:10AAD000286FBF027FF8B98221F55CDF2CF4A79CB8 +:10AAE0002C3DD46E11F79398DC8DF15A7B138FFBBC +:10AAF0000DC4EFBEF238CF3B08A724733D9922E97D +:10AB0000719ED08108DA27196785302F6AA4718E6B +:10AB1000BF140C8A73FCA560E838C71B780E50CDB3 +:10AB2000C8ADB7213349A152BADF1941E079481FB6 +:10AB3000E3BA0CCAD72DCED2F28F9521F38F2FD640 +:10AB4000F677AB03EA498403FAFB149FFDF7B1558E +:10AB5000FAA99FF461FA89D5717B2D66F374B472FA +:10AB60007B8DF699BE8238467A21FAA56E8EFF5605 +:10AB7000078FDB9E6E9C2D583808EFC1C221F0FE76 +:10AB8000CFB772F8B9D5105807E5C9E95B3F87A977 +:10AB900097D7671AFDE5B5151CAE126DFC6F66738D +:10ABA0007F607221E73F3DEF12F316532AA03C93DA +:10ABB0009F53D2CFB5EAFD4C2EF450FD4F02759352 +:10ABC0000BFD9837CBEFDF599B69BC87E76F05B565 +:10ABD00093715E13B4FE2717329ECF3C9AC365CEA5 +:10ABE0003BFD8756FF1F0575F4C473B4E8973844DE +:10ABF000D1129F530A799C40BFF766BA7E7EEE5E03 +:10AC00007EBECE7CEF02F0C9EBF8FB5047EFB0936D +:10AC1000BF07FA88CECF2DC9E3E710CDF729444A04 +:10AC2000E57D285E4FB032CB7B7906E5391CBA99B9 +:10AC3000F2EF5E9ACC6421387CDEC36585C6FB11D9 +:10AC4000BEC039BA2B0A4790F7B0503B47D79BCAD2 +:10AC5000F5585FD0157FD0C2DF8D6AEB7487E6D7D9 +:10AC6000E2FE34EE93E3FDDE56FBE5D1424E3F2398 +:10AC70003D577D97231241BE359FAB4E769EBAD786 +:10AC8000D1BB2607E11DCB4268BFE72C90F7E4401B +:10AC9000BDD47A85CE3FAE2D62E993F07BB92D8489 +:10ACA000E73A32E7CA6BEDC8A7C52C4B80726F6CD0 +:10ACB0000E8D7F4703934580ABB390EFA32FBCF578 +:10ACC000631ACF5F035353E8DCF974F4CF620D8C41 +:10ACD000EE2D34CFF32E8D5F5C6BF83D3919C5D660 +:10ACE00079F87769F408726B13F2456D31DBC1CFE7 +:10ACF000CFF2730A782D3DE56F8652695FF01258E6 +:10AD000037BE7FDE43EB776360EA7DB89E3ABF399A +:10AD1000B43C05F379F2CEC2D33B4F9EBAC01ADEE3 +:10AD2000DF69EBDDE80FFF14E14D2DEDE0BF5FFAC9 +:10AD3000F9A95362B5F6D38E0AB68F4450FFA580A9 +:10AD4000FE13F0A9C8748E96B9043A0FEB529A8894 +:10AD5000AE522685BCF8BB68EC4A1BC37B5CA66A76 +:10AD6000EDD50626E0EF49502E20C969D3EF4BA858 +:10AD7000A1B616683F0DF7CD4298F71D5A8AFDD54A +:10AD8000BB53658C6FA61437D5E27A3DB390F7714B +:10AD90005792F312FA39FB81FBA796BDBCB726E1A7 +:10ADA0005E81B557BD6CBC7FEAAA97BFCCFD530747 +:10ADB000B75EF5F2FFC4BD02BA7C03356447BBFE43 +:10ADC00080C8EFD1FBFB9397DB711DD6D6B22EC4A2 +:10ADD0007BEC53C0B36B00CFF6BAF0335BD02E5987 +:10ADE000951EE2BF2712FB16C2F9761A93B1BD9EDB +:10ADF0006F28B052D2D7731B04B21F98D4773D96F8 +:10AE0000E7EF4A93D17FF8FB936F14C4803EDFBA1B +:10AE1000EDB807F353DF91FA3C08D7FBB7BEEA4120 +:10AE2000FCBD75AB48792874EE3B214FEC738DBEA9 +:10AE3000168C0A1F47FA5AD8FCDFD589F6198BFA07 +:10AE400049DF5F13078813EDDE87D30CBF2BBABC35 +:10AE5000CB6B28EB7A7EB9D3FADC7CE5282E97AE53 +:10AE600079A4D391A7E0F811FB2898E7FBDA39A081 +:10AE7000F77778C88ED7E159F448B903EDE17776D2 +:10AE8000395937C5057BECCCCDF507E65D44F8D0E4 +:10AE900083E0DCB73BCF817CB644607D4E626EB60A +:10AEA0000FF1FD27CDFF33CF63C95BB203D77749DD +:10AEB0002DEBC373678B6E14D6DE04F51745DCE407 +:10AEC000F79BE769D63757E37D3682D53D704DFB5A +:10AED0007E07FD5C09FDA0FDB9A4C3F8FDD8B3371A +:10AEE000ECDB02E3EED8E9207BF1EA61E2FD6347A7 +:10AEF000697AA99A4D3C3586F45FC63825B9DDA13B +:10AF0000EBA3F79B1925A9FC057FDF179E1F36CB06 +:10AF1000F43C5EA8D07A5CB773CF3EFA6D61A9A706 +:10AF20001AE5DDCCE716A77D830DE4155577DEF035 +:10AF3000F41662053D5FB59BE27B13B5FB5FAED6B1 +:10AF4000CE7F541D30E7ABEE79E67768B7C1FC4F92 +:10AF5000E7DE9E0523BCB7E7D8B353D3E87C808EE9 +:10AF600097898017F1CBE32559BBE5497EB745E7C3 +:10AF7000A7E39ADEBD72DBECB5B9307EEB937F2E92 +:10AF8000C4F8718C71FAAE7A80FFFE4F953B9BE856 +:10AF9000CD85F41944BC9AEE7988B1D759027D5F0A +:10AFA000BD2B8DE82400F6907312BEE1F45A85F7AC +:10AFB00076227DBFC6DBBB34FF36B2EB365EFF7751 +:10AFC0000ED91920BE0CD8E8D91DB04DB2B867CB48 +:10AFD0007CBF5887B1FC91BDB710E5CAD5263FF4B8 +:10AFE00023C13A3FED8A51A3497E5DA9A8D3310F11 +:10AFF00060090BAFE5F15B7E6FCFFB52C7BEEF225E +:10B00000BF6F13580CF0B4FC378FFE1AE5D8B58F1C +:10B01000DD9B8E72EC03A9231BC75BB67D4D3ADE28 +:10B020002FF3BE144BC7F61FC4B93C1BA42F47090E +:10B03000DABE949A2E804CBE9E480DFE7F65DFDA04 +:10B040005B609C7F009E91EFAFDFF12F2AEF535D95 +:10B050007D2C80FDF64E4738AE697437B584D0BF7D +:10B0600034F2E7B53FBD375BA13C8F589E86BF3CAD +:10B070006C77FD363BE5F9A21F8FC3AC607D343F92 +:10B0800073FB155D471D28AF651BEBCB3F6FF0775A +:10B09000B0901CC86F2B766CF8584CC7E7076FE26E +:10B0A000EF41AD30D9A74B35F96DA6FF9F9BE81E48 +:10B0B000F043F18518C0C57F8E89CBF1D69FDD376F +:10B0C000FE30C0F7E1B617D2F1F72674FAD7EF7960 +:10B0D0003ED6B578A163887B843ED2F8A45F3F68F2 +:10B0E000FA49D90980E54071177F2EB377A79F07EA +:10B0F000F35DD6690F21CD2F7B5454DD68571D7445 +:10B10000923DB2ECD1E344B7CB04B54F203DC7D25A +:10B11000518EEBEB75DDA37F9A8E72FABAA0C866EA +:10B12000022B5EFBCB13BC3ED0790AD4BFEEF1C339 +:10B13000D3BF8B6590272E8BF59ADAB5C7D1EBB6C6 +:10B1400058AFAEC3D3313EDFFAB37FD27A7CB05B67 +:10B1500060394583DB2FEDFC13C5C13E8485F16664 +:10B16000727CA1BE59D125363A32ACD6AF7BD66FB0 +:10B170002BE93BE5850FB78E1B4631AE1F7FF3E809 +:10B180002F7E0B702C7DD3199A89E3FEE28674061C +:10B1900074F067A989D3FD8FD664A3FE5E6A8F65BC +:10B1A000CBF4E4EF976EFD36D1E3D5BFFF76B6B6AC +:10B1B000DF10B4913C8805719E4B1E9847F3BC8A02 +:10B1C00045881E97FE88DFB37802FC6C2B3FA152A6 +:10B1D000E172CBC9568EBFC5877213EF6C01381C64 +:10B1E0008CDFD7F50ACF7F77B24B3312ED5C87C285 +:10B1F000EDB9188BBF8D76E70A50CB28D7C4DF9FF7 +:10B20000988EFDDC58243539293E6A7D7FCDFF03B9 +:10B2100074C90FBA00800000000000001F8B0800F6 +:10B2200000000000000BE57D0B7854C5F5F8DCBD8F +:10B23000FB0A792D79404220DCBC1309718104128C +:10B2400040DD10C020AF0D444589B0040C0112123E +:10B250009116ACFE9A1B0208946A50AA54D02E088C +:10B260008ACF0604C18AB01145A8FD300AB5F8A2FC +:10B270008B206F6441A8EBBF54FEE79CB9377BEF8E +:10B28000261168FD7D5FFFDF3FFDEA70EECC9D3B40 +:10B2900073DE7366E66C0D83BF64C68A3E1ED6D528 +:10B2A0009BCD98855D34DF97CBD825C6A467EC8C01 +:10B2B000D530A3ECB532FABB9AC4D88975964EC284 +:10B2C000CD507661954DD0FE2AFEDD1628A74A02A4 +:10B2D0006379D4FC13D69FB1D9F82F09FAD97862D3 +:10B2E000F86AE897C5892C328EC3CFC430662B0F1D +:10B2F000AB8DCC87EF1D3C6AEE06F5728C81A5D92B +:10B30000A0BEE51B82993D56C2F66AFF35DB2DCC07 +:10B31000A38E07FE5FB3FE1B33C37E0CCCD77D50DC +:10B32000DB7AC66A737E1583F38894964179C2EC02 +:10B330001BFE367E07BEBB01BE53B112DA676AFA46 +:10B34000DB72EA739683EDCD81E749F8DF057C5E19 +:10B350006259A42B8CB1E9304D56D076FEF3BFACC8 +:10B360007FF43D4D7F395278CCF150F8C70036E07C +:10B37000AA18789FAD89652CBEEDFBDFD7C98FBEBB +:10B3800067C2B765C6A04995C9FD02E2A9EA338B39 +:10B390005D063C56BD76D96C009809CC97D699B11C +:10B3A00033AFEEFEF45E98CF992653CC28FAAA2349 +:10B3B00042E812C07BE5E66F86AF86F626C07B08C2 +:10B3C000D073F696EFCD06681F57C47C1618FF9908 +:10B3D000182763BD116FA6AFBD1ABC15C1736F18D6 +:10B3E0008D23C11087A5278141393B86D93DF0FEC9 +:10B3F000EC83A25D427C31DF625B58DBF76B9A8E97 +:10B4000006D1455FCF98CFECC4EF6EF9CD05314240 +:10B410008B77E3D75E0DDE553C07E3F59E20BC5EDF +:10B4200066D991F01976FAE5593D5DD96DF1ABE237 +:10B43000F5DB3A864CDEFAFC624F89F02C6D870F03 +:10B440007585BA1D4AC9D8A74C83C799AF9C23FEFE +:10B45000FD47BCC844E09BD9EB7F588C7C0568F560 +:10B4600059807F67BB2F10BCC861F531829B4B852B +:10B470009CF6E6ADC767707D77446A5E80FEA605E0 +:10B480004C0E877E7DEF88EE7530B4F3922F220A42 +:10B49000E6B728844D764279DEA6C09D55984D9E2C +:10B4A00002E33C2FE7D8647C2F844D6802FA9C7736 +:10B4B000FA223A8705E67D64871821417BAF9B1508 +:10B4C0003785B5E543C61AE8FB5ED6517D3D8D73E1 +:10B4D0009878E5752F7CEFA26C6416F89EB7FEFB9A +:10B4E000D7BD501E335A6D88A769F5774730037C66 +:10B4F0007F47CAD809D0EEFE7D803F9A9EC31C0FBD +:10B50000F89DCAA7CE4E32F9A9C1303F313C77CF62 +:10B51000DBF07E052056047E9DB65C8F9F99CC198A +:10B52000E94942B93505F884FEEB367BE0BDE9AE6A +:10B53000B0DA65F0DDCA35FAFA993BCE107FCD0C52 +:10B54000E22F17F2577C5BFEDAA0F2571FD607F9FD +:10B550006B981866407E3EBF57745BE09D8B0B4D29 +:10B560006C31C0175F15DC0CFAB9B8031A21BC9D09 +:10B57000C34C8E25BE55F95CC5DB59E4BF8CB6F8CB +:10B580006CADDFFA55FF87A149D59B5FE4AC86F22D +:10B59000EC9B9FA5BF8DF0B6BF257EC1DAB62FDA32 +:10B5A000F9C3241AD74E0BC3719DDFF941E2C308DA +:10B5B000FFC96247BE3DBFC0E260A8EF7686BBD33D +:10B5C000B0BE07F003D0BDE19DEF7350DF33B690FE +:10B5D000E8D82299A9BCB8E39F87059CC70E8B8445 +:10B5E000F3A8D9094880F76BFE14E266F8FE3BDF4A +:10B5F000F77785FD7CF3996D662EE2CF7036613367 +:10B60000F26F67E6C0F9D4BC5DF07C3D7CBF7A4B3D +:10B61000B3792AD417EDFA570EEAA3F39B9BCDA872 +:10B62000AFBE35799F63C01F5F48131B4D80E76F26 +:10B63000C3A1B36E8CCD4D5AED94C3DAC30BC7C30F +:10B6400079C003CE0BF052E9CEEE181F17FF6BF155 +:10B650007161127EBF6AC700262669F12238F8F3AD +:10B6600070B755A0F9F3E73BBFCF6161D79EAF2D0F +:10B67000C94CF2FEFFCB7C7392FE5BE9CBF9FD4D2A +:10B6800089DBA560BE6FCBD7DB7E49F0EBE1761A94 +:10B69000EF75CAFB98FFDAF9FFEFD0BBEABF76BEC1 +:10B6A000D7A2F73E85DEE1360BEAAD77FE95C86E90 +:10B6B00060DEBFF97F74DEADFE8FC16ECD85F17D9A +:10B6C000CEDC77160AE495B4EB8F6C4F12A83D538D +:10B6D000D61D6314BFA2817D3D740A7C57067F028C +:10B6E000FDFD86B0AF8D07016E013F01FD0B86CEDB +:10B6F00009E0A1A5B48F7B19DA6D632DB3016CFA53 +:10B70000742AC113CA7F30E642FB3BC1CFC3F6FBAC +:10B71000EBBDD3EAA17E7F6783D400F058C7F8B4AD +:10B720002D00DBBA89365CC73438FA5925CDF8C606 +:10B73000E6EBD723F706AD2BEE9EA0AFBF8BAD8B0C +:10B7400035427F77559A981BA6746750FBA7926C79 +:10B7500034CFBB59ED225BD88DE3E978125F9F357A +:10B76000B0BE7B25C48B43B46F606DF1C6106F888B +:10B7700097B87E6C991DBFE2351E04D8A2F857F029 +:10B7800047F278678CF505C49385CD61BF84FE2EA2 +:10B790004BC65A6C6F61B06EE4E316AE0A6DF106EB +:10B7A0007F92B13FB9E24482B18E0719E2199FF747 +:10B7B0008CD3BD4FF30EC6F38DE37541DA5388D7B2 +:10B7C000D270BB1BF9C2F17CAC11BED700781684D5 +:10B7D000003E553C05E3FD6DE40D8D5FAE96D9CC82 +:10B7E0003709FDCE0816615F06FD4758BB33239F1E +:10B7F00087CF128F858DE17A4D1CC29A96C17A8DC2 +:10B80000E51BCFB6CE2B99EA3D0FC37B0D0FC0FBD6 +:10B8100088D7EE4C7212FF97D98EF7C2659E8B5D6A +:10B820000D0DF89F1FE583FF994425F1ED47EBB916 +:10B83000BF7979F01B8BFB80283198B3DC1FFD5C4E +:10B84000E54FF696E17B2233D871FDCB1C0EC9D6AD +:10B850001FFB65B4AE89CC37E8D6BF9D1D9D7478BB +:10B860008B2E8ED2C1B1CE6EBAF65D2724EBEAE301 +:10B870005D37E9EA132AFBEAE01EB50375ED7BCEDE +:10B880001FA28393E43B74ED53968CD3C1698DF76B +:10B89000EADA67AC2AD7D567B967EAEA7B6D9CA379 +:10B8A000837B37FD4AD7FEE6ED0B74F57D3CCB7408 +:10B8B000F5FDF63EA183F35A9ED1B51F70689DAE8B +:10B8C000BEC0FBB2AE7ED0C9CD3AF816DF9F74ED94 +:10B8D0006FF3BFAB830BD987BAF645D6033A789896 +:10B8E000ED0B5DFBDBE38E06C53B6CF283B9A8C6AE +:10B8F000809F40CE46486774ED618556867C6352D2 +:10B90000F86164E677BAFAD1F67FEAFA33B35A20DF +:10B9100002B25523959D58139561AC85CA877ABBB1 +:10B920004626A33C3C272F46A6DA5FF07D22DA911B +:10B930008F063F2823DF5D8E6336B10F8C87F98C2D +:10B94000C8D786D02BDD5D9AB851845F649E7EC0D7 +:10B95000877E814A9B3F9479A2810FFD215446F94D +:10B96000A3E979B4BF339531FE047A1EEB8FA7B2F9 +:10B970008B3F85CAAEFE242AE3FCBDA88CF7675135 +:10B98000D9CDDF8FDE4BF0F7A1B2BB7F103DEFE1E9 +:10B990002FA032D15F44CF7BFA0BA994FC23A94C92 +:10B9A000F28FA032D93F9EDAA5F84BA84CF54FA4F0 +:10B9B000E769FE7BA84CF74FA532C33F85CA4CFF11 +:10B9C0002C2AB3FC33A8BCC9FF20BDD7CBFF009500 +:10B9D000D9FE87E9796FFF4354E6F81BA8BCD95F0D +:10B9E0004FA5DDFF1B6AD7C7BF94CABEFE27E97902 +:10B9F0003FFF0A2A73FDABE9799EFFF754F6F73F44 +:10BA00004FE500FF5A2AF3FDAF5059E07F89CA8104 +:10BA1000FE37E8BD41FE4D540EF6BF4DCF6FF1BF6E +:10BA200045E5ADFEDDF4FC367F33950EFF87F4BCB3 +:10BA3000D0BF8FCA21FE03F4BCC8FF319543FD5F20 +:10BA4000D0F361FECFA81CEE3F4AE5EDFE2354166D +:10BA5000FBCF5039C27F8ACA3BFCDFD17B23FD1765 +:10BA6000A81CE5FF273D1FEDFF81CAD678C26053B1 +:10BA7000905E6CD57F86AB50B2B0A876E36DADEF2B +:10BA80002BFA7845E8730CE31E636A055AA73F1D3D +:10BA9000FAED7BA4270B2C12C28BB0693CFF8EAD54 +:10BAA0000B63F7E13F24C69A0B2CB47EDFFF3FFC0B +:10BAB000BDC58547BF7C10EDE3031686F63158FF00 +:10BAC000AADFFD287F772CFA618BFB7AAB30FEF280 +:10BAD000DB246F1996DB92B93FF27A32B7B75B93EA +:10BAE0000D543EDEDB4665D903699114A78AB9BEC1 +:10BAF000795D56ECBEDAFEF7A90A1CE64B247B7191 +:10BB00009DFD5C6FBB45D65FFF01E33A8E06230BBC +:10BB1000B9156023B7F7F297E1EE0D30257948EDBE +:10BB20008B18E79117586C0D3188E75FFF11DBCF59 +:10BB300067CC6981F29964D77ED40BDF8724BAC1C0 +:10BB400038C25FED8071E13F6BFF9FFF2FF77FFCF5 +:10BB5000A7FAFFBBC247B7A7384F27A35F6074E4BB +:10BB6000201D862C881763E0FD29CB051BF2D1D45C +:10BB7000857D86237FF4650E8A93DE17CD263BDB19 +:10BB8000F1CBA2520C8A7F2199EF86F19C63CC8382 +:10BB9000FE44B9C4882FCB77086E99E2D08E88D145 +:10BBA00060BF2B15BE2D5F526F9E07EDAAE379BCD7 +:10BBB0008CB979BCCC0AFF43399AD5B8760F851B6E +:10BBC000C52B141FBB8C7E2FB0CEAC8D6DE3B1F3B3 +:10BBD00030CEBCDD6C43BB51DD1414CF0D8A9B0508 +:10BBE000C7CB4253C263505E999DD9799C3BACE26E +:10BBF0006FF83D16218931D7C68B1A9F9598D415B9 +:10BC0000F1384CCC8EC475CCC5BD69910C4B49EA5A +:10BC10008AED5C408B162805A36B003E077CCA4862 +:10BC2000575F7DA87B1D8CEB08D813A91F0AB76B43 +:10BC30008019E3919FF760CB04A21AF96135EB45B7 +:10BC4000F2EBBD0BFEB918E3D833928CB40E988298 +:10BC500031771CDF5B9DDDB240FD12DE7DAF091444 +:10BC60007795D99C388CEB6AF643C8AF752E8A1D40 +:10BC7000938F745AD2B9AF0569253B3E4DEDA2A111 +:10BC8000CFC206C26B795C34A7CF7613F9B5409F5B +:10BC90007AA4CF0CB7E99816CF97D91533EEC7948D +:10BCA0002FB940F49A19A097AE5D756333D115E8AA +:10BCB000A47B5E537B428DA31FFB297A15A628F136 +:10BCC0004D855E183FBF1B2B1F8926FD50B6C093C4 +:10BCD00056ABE1D3E07D89D46903239D200FC5DDF8 +:10BCE000383D98D1DE05E9F9DDF23CA257309D8A56 +:10BCF0007F9C4AF4609F87B30D309EFB52D8E4715D +:10BD0000F07CB2127FBDAF614431C6CBEF49E1FA9E +:10BD1000F223587F3A60FDF9719D953940351FA88F +:10BD2000B311FCD7BA3882FF562751F9595D2695D1 +:10BD3000C7CCACB249235FC000661CDF6445AE26A9 +:10BD4000A7A8FB5273E330EE5EFCE3813C03AA50EC +:10BD5000B9A964D82DB8BE002468F033A134947C0E +:10BD60006915F69A6CC3E3507F2C15EC1B90AECE90 +:10BD700041BAF62CB35F0046FB65E4FC047CB10ECF +:10BD8000F9EF9E51D1BAF6772D49D0C1F352241A5A +:10BD90005F49718AEEF9BD65BD74F0143FACE7E10F +:10BDA00053A952B14186FE2FFDC544FC7CA97640C3 +:10BDB000D7791C26BE0BC6FF31B34C7104799DC5E3 +:10BDC0008EFAEF6408E7EF937F15DD0DB4EE952949 +:10BDD000EE72D96A93709DF2CBA97222D6FF32140B +:10BDE0005CF23E882F9161FC80BD6C21FD39759518 +:10BDF000C06494111FA3F5F2DC972C34CF69AB44D7 +:10BE0000E6EA477C9288EDE7C64AD4DF7D295213E3 +:10BE1000F2B36F83C5BE0E6AA77A95F785BEB40FDD +:10BE2000523DE76F878D280FE92D3918DF2F4BF230 +:10BE3000C4A21E3CBBDE44FB5ED5E2DA8A3020D1D0 +:10BE4000ACDFBE11512091F8117E4F7F1CBB16E76D +:10BE50001F98AF9BE222DE9ECE6753009FA72BDC8C +:10BE600039B44E7E84C7E3DBE285919E920D11D2F8 +:10BE7000069CEF54D7005BB6D61EF27DBFA9267B89 +:10BE8000177B36727F6E3CEA8163CB4DC518770114 +:10BE9000BD3F06F174AC31DAB08C16559B89BFCA30 +:10BEA0008D9259FBDDF2E5A283DA837E2F417BBDC3 +:10BEB0004274B101083752FFF212C185FB4EA92C22 +:10BEC000BF2BF2ED830F0CE88AF398D4C13EE3B7A1 +:10BED00020332ECD3ED6CC7744A71BBF97EB3596AB +:10BEE000F6D68E9FC781525D4BBACF413A6D0AB1EB +:10BEF0002F9350AFA644E23AF5D441B01BF08D1910 +:10BF00000DCD3912B05ED583DB880E95639AD23D94 +:10BF1000F0BCC5EAFA00F17832BEE9A9411827DA87 +:10BF2000F17CA28C76703EDF5F9BF9F28C9E5A7F8B +:10BF3000BEAD3FC1E20CF95878BA08801797C486A5 +:10BF4000237E27B226257EE1A6F149A874011FB6FB +:10BF50002ABEFF36D5609F742017D11F6E43BAA842 +:10BF6000FD1D35F138D7E72982CE0EC7A672F99E9E +:10BF70006AE072C7760AC4A740B04F5335F6B2865E +:10BF80002D277B19972032DCB73B9512A5E8056E6B +:10BF9000FF66A1FDC37D619B40F251B5D1E27603FE +:10BFA0007FA5A472F99C697EEDA9BED83CA9D68C68 +:10BFB000DF99B14560CF40D3D32677450BEE4BD9FF +:10BFC000D62E8CA2F74C7637F2A9A2DFADA0105086 +:10BFD0002F4CC77F427DF54AC1ED217E71921D9A9B +:10BFE0008671135CFFA39ED7E89136FA3D48AFDF18 +:10BFF000CFF4F68835EAED8B3334DC8AE39CB992D2 +:10C00000FBB581F188EC2AE0AAC2E5DE3386C62BB7 +:10C01000505C24F8FBD3717C385E189FC77EE3E345 +:10C02000A9B07339AD6A14DCEE76C6A7E23572307A +:10C0300093D03ECF5A2FB8911F87C53C40F89D0939 +:10C04000F88D46BCCACE88BB01AE004672537C85D3 +:10C05000E3BF660DC73FD0F913ADDDFD26C66746C9 +:10C06000BC7E03F653C6FDC0DAEF89EE7B80BE28A6 +:10C07000BF3336B9CDB811798635468421DFAFFAA2 +:10C08000780F2E0BBE59F946175CBF964579D20C36 +:10C09000A0B7A2E5A8278A6F09F05FB0BD6E6397CD +:10C0A00083F0233327D9A13678B22E6FC17DEF36C6 +:10C0B000F453E262F7E3BF003FF7AF171D2139BA2F +:10C0C00076CA790499F8BF52F6919F5009F36CB083 +:10C0D000E1537938E2E57E3B23BD7BA3E30D1E27C8 +:10C0E00013CB883F31AE877EC8BF3BDE60FFA32401 +:10C0F000F5A7FD8F603D12EC7F7C69721816A0DFFA +:10C10000F731DF17BF64F4F440F9BD14936C871660 +:10C11000013D1ADBB72BEA79558F5628764BEDF7A0 +:10C120007EB457001F5FF54604D25DA5FF74B413BB +:10C13000D9013BF1CBA9D03F7CEF97DB42A8FF733D +:10C14000A3C14E419F65CF7E10C134FA6F414F5756 +:10C15000752AEA13D5AE896B136DC05FAABEBCD633 +:10C16000BAABC3798505CD2B5C3FAF729C57BF40FE +:10C170007F5395797DBD84CFE7E8723EBF696DE658 +:10C18000C5EDFE2F9FB7D865F20B3CB12887273746 +:10C1900089AC81E8CBFD86CB56E0A73E18BF594E4F +:10C1A00076FD542C9330AED3A1FD5E6121BF60C6F5 +:10C1B00056BEDF7A5A28EC4A1BFFEF79221E42B99D +:10C1C000DE2C32B44381F1B4DAED95A9B11ABB7D0E +:10C1D0009D78C3382BDAB3D9803AE4FBD93BBA3225 +:10C1E0003CE7B2BC903589B40FEF253D062C44F1F5 +:10C1F00069F0C375F1060BB35BAD48A70EE2AFFF64 +:10C2000048BB30690EE1C3978EF857BF5FD3C9634F +:10C21000EA8A7ECD2681FC9AEAB98511850CBFC3D6 +:10C22000E3669B53B99DDAAAE839C1514B7131F0ED +:10C23000696C8FE3B8D6F0F8307B9735217E11A674 +:10C24000F8B181CF43906CACAC2F8FCB5BD1AE8576 +:10C2500019C8AE05E3E16BE53BD5A281FCDF2A33CB +:10C26000F783CF0BFCFCC7BB8A7D7C3795FBC31FD4 +:10C27000A4F238C479F403A1DFF3B758DCF502BAAD +:10C28000AD465A271B075BDCE8CF18AD611E3107AE +:10C29000D16BFCB6559E015F93588B09E93926FF97 +:10C2A000818D389FC3DD984DEC4CD54EDC479848C6 +:10C2B0009A81B1FDA62FDFC778A40C6D45582B4C91 +:10C2C000CC3FD103DBAF4118E67F38A4E97D8CB3C6 +:10C2D0001C4E3232DC1790DFB190FD370DF1F6A025 +:10C2E000386527C61AFA603C66F722E4A33D71D18F +:10C2F0009936683FD9D8C92E72FD33F4028EB752F1 +:10C30000E0FB370BBD79489F9BD942DB712B6D2D2C +:10C310006CB91AFD53FC6364C7553E8031550D81DD +:10C320007F0C649CB1F2099F3A18F04AF0F7A973A8 +:10C33000C7ADEC8E9B26526FA47355B2CF88FB29F4 +:10C340003E81F9D6011EEECCF7191D482F076B1A56 +:10C350000BFCEBD9C704FC0E8A007EF76E4FF2305F +:10C36000C403CB945824D48F354A04772F6651A246 +:10C37000B26F8071AC438304A283C12A9970DECE70 +:10C3800062A12FEE8B562DB8BE71866CF8F5B8956C +:10C3900083013618F87AF621BE9E9D281F19467E25 +:10C3A000D26026201FD6443599681D0DF282E3EF36 +:10C3B00003DD68F137D1E8E5E3AB84F115A05CA4B7 +:10C3C000121FDF5B2B903F59636E3FAE119BA6EEB1 +:10C3D000CBD9246C3F0BFE857C3D6BC7B634FCDEAD +:10C3E0007281F3C12C95CF5ED5CBE58034467CDAE3 +:10C3F000115FE72AFDE7A619F839AED6EF3591DDD2 +:10C400009DB5E38343B8AEECA8FF6A0BF3105EDE84 +:10C41000B150FC4030F852892E8848A0C344F4271C +:10C42000C145EC9BC6FD44953F2BD0FF48C192C748 +:10C43000450CA03CD11E56363E6F46A4059F3F02D8 +:10C44000C787CE01CD5C1FFC5C135711757A87E25C +:10C450009E82D9370DC723DC1A62477D3CD1DC446C +:10C46000EBF2E076A646EE679996703F8BF6D50024 +:10C47000B62CE77EE6C4EEBEDE8CF49C6DB890C4AC +:10C480005AFDE20AFE69785EA5F38B2D1847C0B805 +:10C49000D72AEE0F1A15FFB57CB9DE5F98B850E3C6 +:10C4A0002F52B7BE6A1CAFE991508ABB58D09FD0BB +:10C4B000F8017F3794C8A887E564239DBF34B16035 +:10C4C0007FC2C9783C933F372A7EE2D034936EDF37 +:10C4D0004D1EC232110F65A8875250D53897603C67 +:10C4E000EF220B6FC4B8D930F1118AFF95D5F373E1 +:10C4F00069C1F1BF8BB5EF3F8BEDB11E9FCFEBF460 +:10C500006322EE6FC2B2D429DC0AF2DDE9F06517CE +:10C51000CA07282A13CA7BC8FE6F10160C914CC894 +:10C52000C7EF7B9EC5FE65B3D5867AEBE9D008EAF6 +:10C5300067FE7C81E2C30B6D5CDEBEFA327C1DEAD5 +:10C540002935DEBBB8B0DF2A3CB7F4EBB45DE3AC11 +:10C550003D503D303AB70486F11307CCA7F40AC822 +:10C560000DC1EF8F7344029FBFEF9B64053CADDCB0 +:10C57000F0FE3823F0E3F9DFF99E43F8850DFB392F +:10C58000FC5B5F6208C26907C619418ECED7ABFD5E +:10C590001D18E7C07DF7DF73B801EA6580CB50BF97 +:10C5A000E1BC070AB4EEDF8076293610EF2933BCF0 +:10C5B000CBCB21CC83F6F35AEDFE98E6DC80F65A1D +:10C5C0000C3F168EFEC5960C07C19B539C8FA5A1F0 +:10C5D0001F74D0DD2516E35806D68274013BE66849 +:10C5E0006F5F7A432A97DF4DE9BC3F155FD0CFD309 +:10C5F00069B137DECF6D6DFB71FF3BE3E99401FD5F +:10C60000E4E9FA79E9DFE9A72AA81FD56F030758FB +:10C61000423D7526D3F11ECE73D6AF1D43B6A0FEA4 +:10C62000D92F129F7E57BB2D1DEDFE77AF5AA2D199 +:10C63000FECD7AFDADC40A8C23287ED199E6CFCCFD +:10C6400012BC3FDB2F3207E8E91ABF40E5EC2DCDE5 +:10C65000E6E1D978AEB6D95CA4195795324EE074AC +:10C66000E3388D1FB32F4D8D3FAFA0F1CE7AFD94EF +:10C6700011E939CBD0741CCF1FB3813CEE153CBF00 +:10C68000CDCA7B87F1BC413B71808FD2B8DF11D717 +:10C69000CBB11FE7B709F539F28B819F0F096EDF28 +:10C6A000359DF757D689EBF9BC83F68A03B4EECBF8 +:10C6B000318850F63F546B2E87E70752861C4A6B31 +:10C6C000370EE9E371C81D3C0E5916D532178C1987 +:10C6D0008B4ABFF804CADBC8A755F900D103FD5245 +:10C6E0006C51E190F14307F33817C29737189EC495 +:10C6F00073847B3BB5FCE200DA87A5E16C1DC8D9E9 +:10C700007D03C21337C338A6CA9102D84E566809B2 +:10C710004F9F02ED4E241746A5F3F327E41F9E48D2 +:10C72000769EC3F17993420DE08C309799C7B35C44 +:10C730007F16299EE5CA0975B9DBC1D719059F5136 +:10C74000E9DC3FDB6B8071F6C571F0F3BDF097B8A3 +:10C7500019E34D0B7A0AC877EAF76F4F29EC9C9ED4 +:10C7600017F8FEED29CE1FD362B5ED2319B6BFDE53 +:10C7700071FC53B1A79DD339BD9C8381BF347A7FAF +:10C78000DCD0501D5C3A2A9A39B4F1CDD2041D3C5C +:10C79000A12C45D7FEDE69BD74F5A32D2DB9B537A3 +:10C7A000E0EF8B119991B4FECFE3EB90AF765CFE96 +:10C7B0007422FAB1EB45BB00F39AF1CE864F0751D4 +:10C7C000EF12C5B94EEF15C91E817B6BD6EE9F9C4B +:10C7D000632D74EED8D87921D9BF5971FC7CF70C40 +:10C7E000B77EFF438DCBB7B76F82F6AC0ACFC5B427 +:10C7F000B76F1288C7FFE4FE49BF74653DDC97F54B +:10C80000E5EBE1B37B60A6AC687B33D1AB619F689D +:10C8100047566DE8213001C679FB168B3B04C67D77 +:10C82000EEAD236649B37F52E30703108DEF1D3150 +:10C83000E379AA03695C6FCFDE71C1CC902F763C9F +:10C840004072DDD2EC8A8945FB05FEEAD65CE4AF96 +:10C85000A65CB47F7B0D3627EE87CD5A3282E2CCC0 +:10C8600091FE895456358EA07EABFDE3099EED0FF7 +:10C8700025F823B165CBC7D8CFD39136B4E7D546D9 +:10C88000F955A44BB514DA0FF7AB666FF9F8D2AFD0 +:10C89000D08EDAF8BD8ED1E227B9583FBAA7CDD0F5 +:10C8A000D019C71B42FDB40CF92217ED5231AE0B63 +:10C8B000E079D5E60217CA7D6143B80DE55EC4F3A1 +:10C8C00064EDF0E9E474AE5F4C5E3EDE61FE12EAB8 +:10C8D000AF757D9F9E4CF3576153EC7A23EA0F7539 +:10C8E0001E2630F858DEE1EF4565CD9612239E8B6B +:10C8F000FF73E6F3318827681F8665EAD041A46795 +:10C90000BEAB1D10C9DAD15B6A6951F4F044D4C3DF +:10C91000D05F69A6E3572897631EF11AADA847C3F5 +:10C92000AC36DCFF1893DF47AAD0CC477CF71E5CFF +:10C930004980AFE233A11F30114AADDE9EDC817D1C +:10C9400091D30D8A5F54CFCF75AAFA7DE5130CD72A +:10C950006193F859AD56B9AA56DAABEFB708DC1FA8 +:10C9600090B7F2B87E75A6EB491C6F4B219BB0992E +:10C97000F4694B6249F8CF37FE08630BD139C22600 +:10C9800019705F41AD5FD53A0F2EDFD79AC722A548 +:10C99000FD47229B8F7CF1D16DB7B538A0DFE687CC +:10C9A000FBF5133576EAA5747EAE99D97C57485FBE +:10C9B000EC0C95500F8CC6BD87DC80DF8FE72131F2 +:10C9C000AE51B3D3B20ECF83D544C03A1FBE3FAAF7 +:10C9D00097EB25C447F3AE824B788FC6810B33901B +:10C9E00073C78E0197F09CBDC30ADAC68E7E90E3B2 +:10C9F00065D2FF1D8CF75AFA2C75E8AC18F427BEE7 +:10CA00008321A1BD05BB9F7B90C34EC4976B099743 +:10CA10003F9722875314FE2D57E4708A91CBE1E4AF +:10CA20009591368C77963F22F4C6F3724C0AB7A3E1 +:10CA30000A30215FF643FEE47C59E5EFACC87392FF +:10CA4000D20FE7FF60F99CED8FA676AA9CBE9CE909 +:10CA50003AC4ED5C4BEE7C18D71D20D7A8F75C0BD1 +:10CA6000E273514E027C62B6213F019FC45568F8C3 +:10CA7000A0A1F90723F28969B0407C6281B248C362 +:10CA800047CE56FFC436BC0BFA550B930CCB58A0BF +:10CA9000FEAB74D54FB93E7EFFB3D2BE3C0CFC0852 +:10CAA0008AFF44308CAF5D8C91284E3A67290C1276 +:10CAB0005030C7E449C338CC9C0742280E5671B0A9 +:10CAC0007671B8D4965EF7F873687F79BC3F95CAE3 +:10CAD0000329AE33888F29FEBB143CE65CD7FE5C8D +:10CAE0009E83C7DD4C6E8B7D6D12C6DD5C22EDC76B +:10CAF000F560B627C94EA9FB713CEE86F13C8CEF80 +:10CB000005EFAF611C0ED7D39618836E9FB04D3CD6 +:10CB1000AE50BF9F56D5FC497F03D49F4E72505CE8 +:10CB2000CEDBD365CC8079CC1CE77EDDA4DD6753FA +:10CB3000F0D864F4A4A11D6DAAE5F8695A2E16D3A5 +:10CB40007E1363A1259AF3BAD7E2E399FE14C28F4C +:10CB50006A5F54BDBDAD8E0E7DB6EAEF6BD99D6A9E +:10CB600085DFAB91DFED6DED8CCAAFC1FCACEA6740 +:10CB700053EC41D24377C02BE83FA8FABAB868D04B +:10CB800060B4F3835E4AD9F227987F74A62B3703EB +:10CB9000F8E7B6577AE4AE06F80EA3DB680BBB1EC7 +:10CBA0007DF88389F4E123258CF421945A7D68EA89 +:10CBB000C00F2FC8B8317D9EA1B4073F96FB87A058 +:10CBC000AFB5FD55670E1985E32FC9E076F2E71A78 +:10CBD00077477ABC244395CFEBD3E3B72AEDAFA5D3 +:10CBE000C7A765703D1EACB7411B93DE3EFF4E16D6 +:10CBF000C5C90E33D0F368CF76844A1B9234E7DC84 +:10CC00003B45BAB57A3DAED7D469C8EFD7A1D7EFC7 +:10CC100047FCFDBB7A7D78C926F2ABE0CF39F656EA +:10CC2000587FFC06D677087F04EBBBA4B6F2102C25 +:10CC300007C17C0FEB912D1FC3F8F63ED593E20E92 +:10CC40002007C4F7D5C0F72807AABCCCDED227122C +:10CC5000F70DD85F4486FA3F580E8A8B5E31629C8E +:10CC60000AF538E26B37C83CEA99603BE1CF70AD1A +:10CC7000C4F9ABF2A0CAC1B5F9E82D13AE4B4D55BE +:10CC800017B89E8752ABE73BF2677E7F83FCFF6855 +:10CC9000C6F5F901AF66F07B103F23FFBC9A717DAA +:10CCA0007EC16B19FF915FF036F10FEA4F5CBF8DCB +:10CCB000FCD01E398FF30F9D4B047EC8C5B8F3DE40 +:10CCC000FE3DEC18A7197995FBF5A0D3C9AF0FF677 +:10CCD000AB272AFA6FB212273890E96CC9E0F24A02 +:10CCE0007E7B614A681FB457D7EBEF4D8CA965185E +:10CCF000679A0CA5564F58906EEDF8EB7FCDB83182 +:10CD0000FBBDFB3AE97B3CE33FF6F37CD7A30F5234 +:10CD10001DD6F188CFEF3C468678BAD67AC0B48A61 +:10CD2000E3598517798CAADD8C46BB09FC71E13F7C +:10CD3000E18FD1454D97AC40D7C84C6329C603EF6E +:10CD4000C2B31614CF30AD74A4A2BE61EABE00C552 +:10CD50003B3E1255D87C70288C63E4932CB06F0056 +:10CD6000F5C30647B6C6470416681F91291E5C4ED8 +:10CD7000E3E6E75598CB6BE4FB640A9C0B70B806BE +:10CD8000CE0F82D7F0F611462FB369FB51F4CF18BE +:10CD90001BDF1708ECE7F9867746FF6F8B60C3FD52 +:10CDA000857B079F37633C677491774F02B44BCA0A +:10CDB0000C2F0D03137FEF1681C6DB6763CC4A3956 +:10CDC000958E6C39F0BC61553EDF37B134350F7745 +:10CDD000B4C3877D32F5760AFF8C5D283E467F9688 +:10CDE00026819973793FC949D7F73ED28FDE4FA686 +:10CDF000F73D9698EB7FFFEEC1CCE16E878F6ECB4F +:10CE000054F421C685D5FE8126E39B04477B719BA4 +:10CE1000DB95F62D064335033C8DDD98B912E35EB4 +:10CE2000C318E78B928D19A532E73FE6089AEF4FBA +:10CE30008D372F53BF3EC33F49FFBEE7A7F035A84C +:10CE40000DBE14FA57EAF924D2E87CEF3B18476488 +:10CE50008C60433F75B63364398B44BA2B7C2DF715 +:10CE60002D750C86F985305D1CAF95AFE57EA5C8A4 +:10CE7000D7B399DA3E6F25D2DF69686DCFF97C8729 +:10CE8000D0FA7EA691E127E8FD591B7357629C1CDE +:10CE9000E841F5041B7F82CF9B82E0C14172C1381B +:10CEA0004C72897A19F093D6CEFEED1205BFE704D5 +:10CEB0007EBEA96508F7E75A9279F96226F7DF1E68 +:10CEC00057F0F8B452B674D2E0A17B80CEF0E7C13F +:10CED000F58066DE84A77B629479CBE34B47C1BCC7 +:10CEE0005AA2586F01F864EDC6B12B176AF8E4F93D +:10CEF0008DE34B110FADFDC92507118FF728787A07 +:10CF000071E3B883C84778E404E5AD3A9FEFBF5AB0 +:10CF1000B67CDCAEBCCD69CB3F32E657A82646C214 +:10CF2000F704872997F793DC0E7EE6B77DDF11F4CF +:10CF30003E33C5DCC8FB0A7D4605D1AF38887E4349 +:10CF400083E0323D1CF083A167F09FCAB7AF58D48D +:10CF500005E3671B05BA6305FAD92CC0F31D99F7E1 +:10CF60009586C5239F4AA60468EBC99C7CD09A0588 +:10CF7000F288FA8BF4AF8BF4F578947382A7943A25 +:10CF80006E46BEA95D1407EDF76496AFC47BAFF79C +:10CF90002E5C6142A4FF3973DA4A23F47B4FEE1F03 +:10CFA000F7607F46A1E2E028E127F8B431681E6B04 +:10CFB000826039A8FDCA6BE8F38541EF3F1254BF88 +:10CFC0003C085E15042FD1BF3F651ADFBF9C02F4F9 +:10CFD00043C45D4B5EBC99ADEB8656FB25A03DFB83 +:10CFE00050CFEF231B387C6AE383A54BC23470E635 +:10CFF0002F4AB5FC6B52ECC5C418A7A33DFE3DD427 +:10D0000011FF6406DB3559772EF130633AFBBB5BC9 +:10D01000D4C3CDA22A5F0B0ECECDD6EC07CAF5A5A0 +:10D02000184FE978BF422EC5FD8A918FABEDEB4AD0 +:10D030001D9AF9A9ED87FFEBAA88DFBB9A5957BA69 +:10D040009EF6FF94FDBB285EDE76E56A04D2653865 +:10D050009E1FC5FA4E9EB439D99AF9B1A6749C5F49 +:10D06000F3C3FCBEA1DC00F400392F6776DAFF6E53 +:10D070008E8C9CFF02B4DFFDB0381FEDD7E1F9D1F3 +:10D0800074DE686C16F7B77747F6EC723FC0CDA137 +:10D0900093CD18576D7E741895EF8A8EC53E407EED +:10D0A000F7ACC74AC3B2B03E92F012F7D2D2D27AEE +:10D0B0009083842C89DE7745D9BA6C473F7499896F +:10D0C000E1FE1363F6E7884F7E6B213F754A7D2FA3 +:10D0D000DAEF29FF5DC9F0786857BEC844F17FF8E0 +:10D0E000A3FB18AE65C3CC583F6DA152CAB753B964 +:10D0F000EBC7373ECCA17D1D91CEEDECF4471D076B +:10D1000049665FCBBDE9BEC25125BFCA962C5746C2 +:10D11000168CE3EBB3A9942F85D9A48871E8B7DD09 +:10D12000E4C8CC8A0DB4DBF5A348FB556F9F2DEF07 +:10D1300082FB7B7DB338BFECF4977729D7D8F58A8B +:10D140007346C2F32EB33417F5C6AE4E3D0499E4D0 +:10D15000B6291AE3ACD314BF19F864FE1BEDF061D5 +:10D16000CF2C91F072CC321FCFC2B2E6DFC40EC614 +:10D1700071A9EFE51D743560BE185377A9AFD63F8E +:10D180002E481B722B8E37C05FEB499F937F0CF0AC +:10D1900088ACB52B65B01F6C37F8F5388E18C770A2 +:10D1A000E427F53C1E8B6B4AD7C615027EE8024584 +:10D1B000FE79BBAFF070307CFFAB5743E8DCD7574C +:10D1C000F217E15AFF58958FE911FF73B885D6C55C +:10D1D000919290087C63AC3BFE10BC57F1AC89F493 +:10D1E00066C5B3B18FF8B01EE8895B86C1DF7D3EAE +:10D1F0008B9F07E8583E36970EEDAE958F4DA538BC +:10D20000DF8EE4636AD6A60EE4A3AE0BF2D1F0671C +:10D210004D74BEBAAC53ED5D18472C33DCCC1A60AC +:10D220007C439EFD4517DC6799FEAC85E8EA0D0F4F +:10D230003FCEE7D53309E7D56A7FB2B8BEF2D6173D +:10D2400090BD100DE09D81FE16179B683D22763142 +:10D2500093DE1323ECBCBE134B5A0076795178BE93 +:10D2600084F4752BF200F512F25951E4843BF05C22 +:10D27000CBE1F929B40F762A97EF83CD78E8F90846 +:10D28000F43FBF9ACBCF77CFC47C3BB8CEFD37F706 +:10D29000BD6A947C3BFF5BFB5E4F6429F7865AF7BF +:10D2A000BDF839D0DDF3FBE572BC30C982784AECB9 +:10D2B0004378B9DDCAA410C08B18C5D251FFA8FBB2 +:10D2C0005EE2AFB87E120D02ADD38FD5C994BFA078 +:10D2D00028C2CA9FFF8ADFDB139F2A61B40F16534F +:10D2E0004BFB60E188578CDF0ACC89F27334C49E13 +:10D2F000F84036F25F08D173FA73333EFD7D2ED2CB +:10D300006D748C2E9EA0F09FFAFE89FA5B687C27D4 +:10D310000466437B5FF4878CA1489F66D1F5D43DBA +:10D32000A4374369FF9CD9BCBF1D00F0F47A58674D +:10D3300033E49BF8C4E4EC403FD3173C9C8EF42EBE +:10D34000FA438807CFDF4C5B18B20ACF6154EDE097 +:10D35000F7BCA72CFD8ECEE3B224632DC639BF5E89 +:10D3600018C2CFA96F1940FC33C5C0CFB9B0443340 +:10D37000C597AAC214B87B3EC19AFB4B66A4877AB4 +:10D38000FF660FEA15F8FE71151FE837A2DE55CFCC +:10D39000D1B35A09E5BFCC20B47BCEEB6F59DC3F4B +:10D3A0009D9268A7F3A2D58F59EC0B92389DC5FECC +:10D3B000F85D46EBA26A836FF82AECD7C0A4AD36BD +:10D3C0005C3FB454E07A9B6DC9A03C04354666349A +:10D3D00047C17389EB33753C3552C9EDC44F46766E +:10D3E000C81885786CF9B405F96341B8847191EA7D +:10D3F000CE7617F51B6EB5713BA17C17C79E827C5C +:10D40000E03747211F7C2A182C3CFF80C300F5E73A +:10D4100019AF6FFDCEC2A5D9346FABCD30241EF944 +:10D42000EEC2F055F0DEED4C4A8EC77B624BA3EFA7 +:10D430009A80F5AF89A49740981ECB477FEF35B10E +:10D440001FAE53A72CDD4DF39BB5A90FDE20605313 +:10D450005E3F40F66996C25F5EE5DC5A39C09B10BC +:10D460008F8A5E7089AC96E2610A1E5BF1ABD4577D +:10D470002F35113DAA175988CED5F57FA37EABC3B2 +:10D480005BBA203DAAB79A287F87F5263E8FF2FA2D +:10D490001E830FC1B8CB4D9136011E55C9A3CD08CF +:10D4A00057350A04ABDFAB5EFAD72E866CDE1F96CB +:10D4B0001603DF670DF41B9B88F6ECCCABD18953C8 +:10D4C00034743FB3705B04EE3B1F0DF1A4E1395F90 +:10D4D000DF0321763C57A8C6D3CE2C4CE3F7816CF2 +:10D4E0002DE1B85F3D6D6E4A14DAB9C3368F19EB82 +:10D4F0000F3725E19139E6B0D90623EC30DE4CF048 +:10D5000019E51C09FD61FE4081F34DD5ABBBCDC9CA +:10D51000F0BDDE3771FC9C7BEDE89E81880FE02337 +:10D520001BEA9FC49674B4C3D58696F404A4CFCBEB +:10D5300002F90BB03E7560FE91D9C8577D411F2A94 +:10D540007C357BCBB679289FD56F9E1A8E783D3778 +:10D550009A99313E56ADCC1FD68FEF19A17DF5E6D5 +:10D56000B5C3197FFF3DE43BD5DE03BCD004F05EBC +:10D570003387736EE2FA79AFD94B79EFF6DEC518CF +:10D58000ED9F19D9506C0794E7F7004451B99F56A5 +:10D590001B378EE7DD93B5E7E766637D76A0BE2394 +:10D5A000BE197B9341A1B385ECD258C40BC0DEA554 +:10D5B0005B23902FCEBDB67BCF40948BCD828D69FF +:10D5C000E54195C3441FAF07FC3D81F8DB7C613822 +:10D5D000E6A19879365C421AAA7852E54DC54B0D02 +:10D5E000E37850F1526354F0A4D43B153C54311FFE +:10D5F000F5C7CEF6963660FF6FFE40FB6DE7A630AE +:10D60000819F13E679D1D4F9B9A2F4FBFBF5377108 +:10D61000BE9FA4CCB3CAC6ED62550C93EAFB109F23 +:10D6200039CC6A7E4968726ED311DDF8572972D001 +:10D630004A6F9C078CD36BE0F70483F5D75C85AF0A +:10D640008ED44FF4A05E9929433FB9280FB649B84C +:10D65000CFC95E1715FD0D3653F3DDA2578E101F8F +:10D6600082EE92A260CD62DA08E340FFEB6C0F8A93 +:10D67000171675F5D2BC378CB23103E89323823785 +:10D680007C3BDA838744D253EA381DF287440F4744 +:10D6900013974FE4178C0FB6EA85A0F1D62BE3B5AC +:10D6A00018EC5E3C17CC1608747F4D5C702EFC1095 +:10D6B000B77714490CF47FCB7BB81FE9B814210964 +:10D6C00054633762BBD9972292D17E1F51E20E4735 +:10D6D000166D8B28D7D0E1A98EBEB3788084F42F45 +:10D6E0000A3BF430CAD1634ABBBD66FBD0F9A80F30 +:10D6F0002E4748785E6A6F949C8D7ED45E035BC231 +:10D70000A2381F1ABB04F007F242F8837AE9495B9A +:10D71000402ED57103DD3C483768EFE07264A77D89 +:10D720008CD9317C5FF4DAF2D4CF4BFAA95E90D673 +:10D73000E506DAA9F7F21E55E64D32D225600F90C4 +:10D740003FD1DE59943C46C179506FEFDE3911F17B +:10D7500057136635E0122EB83E180EACA76A8DE856 +:10D76000E7B385717BB4F7D28E86C874FFCC172FD0 +:10D77000B275408FFA073EE0E77977F07B5BAA9DB0 +:10D7800086BFE5ADFC07EF55E65E188EFAF5C502DB +:10D790000BDD6BEADC2B99BE739A35990BD1FE9F9A +:10D7A0006C191E2105D627B75CF28891E42F24E975 +:10D7B000D6075567DF2379AE662D741F7BCAD20367 +:10D7C000A30720BD5F32D1F981698D4964E74EAD71 +:10D7D0009FDA0FE73B65511AC13336DCCFE1A53C38 +:10D7E000FFE19445792FA0FF7534C4311CF9D9B7F6 +:10D7F00042B0E1FA6AD086BC47EE85FA41E13D3B92 +:10D80000E3B8BF5A7F7434D2FDABF922E927C7FAD7 +:10D8100027EFC27AC776116F8CC17AC6F608E63553 +:10D8200065C6481BFA05EAF9C20613D7B76715BDE6 +:10D83000704CD113C714FE2B6A6848477FC9B716CE +:10D84000EC11EE7B9B7D1574BE5BB0D9D701BF9CFC +:10D8500014648299CD965C5F80F759D6507E9CF314 +:10D8600069161BFAC9F759981DFDDAFB76F5E88BA6 +:10D870004B0587B2AE1A1DCDBFABE24BFDFE19E5DD +:10D88000BB4C5C5E41FB0ED15232EAB7BDCAB9F166 +:10D89000A3CA784F2D7CE92EF40B4E6D4C8B621A87 +:10D8A000BC9F52F234CD003DB8B99DF59EFF2635A0 +:10D8B000EEE0A6EF542AF1C07DA6C6EE98F733F845 +:10D8C0007ED789B52156CCCF1B7CCFEB8489DB8FEB +:10D8D00036F7BDB6EBE1E03CB7C1E3695DCF04DFED +:10D8E000FFEF15D6AE1FAFCA59F0FB6DEE93A75EE2 +:10D8F000DFF92ACC4B86F7BD77DFC4E8BDA1A1FFD5 +:10D900007A03F57545A3C586F7EF8F8548B41E9257 +:10D91000F398B401ED8C558AC4F5FCB17DFDE8FCAB +:10D920005FC5978CE4AA628BE8C654C5EFADC87892 +:10D930007C30C0F76F31D9F1FD532B57DCC5C54C96 +:10D940009F67219F71F99C0EEB248F2DB02E0A5EEC +:10D950002FCD5CB589EE11FE5CEB25358E148CEF76 +:10D96000825EFA7C0BC1F7E77601DBE4F76D8BEFA3 +:10D97000B3752E5A177D5B57496541D3DAA2040966 +:10D98000EF531C796C10CA4D7824C543CED6D5D23E +:10D9900026DEB7DBFB5DC1FBA16F8745DA505F7CFC +:10D9A0005B375FB95CA0F089C297B76C6916131832 +:10D9B000B5DF3108DAEF0C8BA4BB2EA98EFC48B47E +:10D9C000F32A5D83EF37ABF33BFD10A7AB3ADED311 +:10D9D0001BA746A0DFD9BC3A7A4701F4278746DA6D +:10D9E000D0DF9EAE9C7F39BE8AEB9B93D6C817468C +:10D9F000E1F99935E3BBE0BAEE7E93CF6C877EED1B +:10DA0000EF9444E07AFF1BA33702EF1B7F03ED3D49 +:10DA100068278C6E11F5DCC06246FB78033D462614 +:10DA200025D19639F145C159A31BE97AC67369F727 +:10DA300055E4A3B3068A770166765F85F6F6F09E15 +:10DA40001427BCFF2DBEDE64FFEAC4EB83EE2D3E3F +:10DA5000D18BEBA5136BDE1843EBF3F5261B8EF38E +:10DA6000DBF57FED82E77066327EBEFEE44681E63E +:10DA70003113F8312409F5038F83CE04BD6F15DA15 +:10DA8000F261D1C67AE2C399C08716F4D31C3C1F59 +:10DA9000F34CCCC72CB136F93F3A2B7C370BF80E40 +:10DAA000EFEFFEDC793F96F50A3EB7CAF950A5BB09 +:10DAB0008A1795FE013E64BAFC82514D7D0A1358C7 +:10DAC000401FA8F73B98D1BB1CEF69CC13C31B3197 +:10DAD0005FD57E63ED1F286F8B6C641BC89EB34CB3 +:10DAE000CC97374FBCC98EF1C006736D6B5E17AC17 +:10DAF0000FCEEB2286F1F74B303F31CC372C3B89F0 +:10DB0000BE37CE661F86E836C578292E2016191C2A +:10DB1000742FAFC142EBE6603DF48A42DF3BD07721 +:10DB200040BFA7173FAFADDEFB534B30343D90DF16 +:10DB30004B42A32E4BD064FB2B9FDF89FBB4258384 +:10DB4000A27E9102DF6FEE75E44EBCB751D22F6A10 +:10DB50006B32C0BB5FF93BAFBF392ACF847E80F008 +:10DB6000F59D43D16FECE578B397E63B6ABFF0FCD7 +:10DB70002D7CFE79A2EB9D5E7CDFB402E97D5E88A0 +:10DB8000E0F9DE527D140755DFFB586087DF16028F +:10DB9000B0D7C41231AFC1DE5E5C9F7654C6643B21 +:10DBA000F6F0EFEB9F2385BEC375A6B2FF63B04AC4 +:10DBB00066F4FF9C76B39DE757644E2BF8556315CA +:10DBC000FE2DB75E194AF6B796D92D98C06489FE26 +:10DBD0003E5656E0DEDE9A1BB9B7C7649E87AF415A +:10DBE000C9C3D7D13D4A61C7073FA07F197C7FAA2F +:10DBF000DF5F5ADE443E19037C85F622B785C36396 +:10DC0000153EA9DE369AF23DCFF9D8E4463F61864B +:10DC1000E28FA5BA3A3109DA5D06F945BD70768C16 +:10DC2000271DF5C7893AD6989A86F12A970FE9B247 +:10DC300037E903CA8B76624D4304FA3DE7603D3114 +:10DC40000ABAA852FC7B7645F4DC867E7052D6BABE +:10DC5000651A7EFBA117B7FF67933C89B8BE919305 +:10DC60002C3C5FE395DD94E7B93879441EC691F604 +:10DC7000D76D6747D302EF75741F65A06108CBD6D7 +:10DC8000EC4B8E31B67F4EE3A49A4F733DB7DF164F +:10DC90006323E5D10252D6D613ECA4B8521CF22865 +:10DCA000C687A507095E3C83D9E81E6B609F8EEE90 +:10DCB00083AAF477D8AF0EC5766380FEA86F0C56A2 +:10DCC0009F116167313F9F920584437DA2D27F9867 +:10DCD000F8C863488739CA3DAE39422D874D563A58 +:10DCE000E71AAC1F31AE59467A53DE5380FE18E86E +:10DCF00049CAABA0E84509FE477991F2D79AA9D95C +:10DD0000B5F322ED29F80FF4634EB63E8FB84A27DB +:10DD1000D5BFEA884EAA9E047AF5BF117AA979CABE +:10DD2000E63CCBE39D739E9D1AD797F0061287FEC3 +:10DD300050DC1F29AE325D99035B134D7C6C1AE2F7 +:10DD40009450DF8EDE9EC024783463BB40E75B478F +:10DD50006D8F2638C21FCFF32A29F67EF48B5D879C +:10DD6000607CF2D40B5FCCC5BCF7A37EC3287E6C6D +:10DD7000080DA37C13E210258F8318F63EDE63BDE9 +:10DD800028196BD15E39599BFC0106A2FF5E7E4EBD +:10DD900016567932A713BFF737671FB7F3730AF91F +:10DDA000BEE0457C03DA5F2C15294FD3D3A139E4BB +:10DDB000BF35DC69A2FB114C767C82EBAA090A3FD5 +:10DDC00058E26061A9A1578804F2AAA1CFA3218FCC +:10DDD000BDEF82FEBDB0EE12BA811F9B19A5AB3715 +:10DDE000CA21DF60FE58539C6873C3F8C3EDDD742D +:10DDF000FD39C52A13C653988BFBD12A7F31F1AC6C +:10DE000091EECD0FE6F92BEE9CA0BF27691A7C613D +:10DE100028D99BC17AFFDB798DBC4DF3557ECA6250 +:10DE2000594A5E7AB2FF170FF2FB211273AE52E528 +:10DE300005F53F78374F237EEEDA6B626E89F0F797 +:10DE40001AD65F942D368C07B4FAE1A9F05E0C1A4D +:10DE5000492BF139E605D5CE13F3826AF182794177 +:10DE6000B530E605D5B6C7BCA0DA7ACC0BAAADC7EB +:10DE7000BCA05A18F3826ADB635E502D8C7941B5E1 +:10DE8000ED312FA816C6BCA0DAF69817545B8F792F +:10DE900041B5F59817540B635E506D7BCC0BAAAD62 +:10DEA000C7BCA0DA7ACC0BAA85312FA8B63DE6050F +:10DEB000D5D6635E506D3DE605D5C2981754DB1E7E +:10DEC000F3826A61CC0BAA6D8F7941B530E605D536 +:10DED000B6C7BCA0DA7ACC03AAADC7BC9F5A18F368 +:10DEE0007E6ADBB7B0856968C7DE4A72EDCD8EC544 +:10DEF0007DA793C4CF87EE037E4639DC3BDE46F92F +:10DF00000B6F709DD892ADAC5B14FEBDCCC226E108 +:10DF100039F48EDE57F9F3257C278FECC112E25FCE +:10DF200016DE88FEDCA34607DD87929BF8FD44667B +:10DF3000E47EC03C51F17F94BC10F34489FC00CCDA +:10DF40001D6CD48CA7B3C3CA8C1A3C4417DB747005 +:10DF5000AC334ED7BEEB0449571FEFCAD4D5275474 +:10DF6000DA75708FDA7C5DFB9EF31D3A38492ED648 +:10DF7000B54F59E2D4C1698D1374ED3356B974F5B8 +:10DF800059EE4A5D7DAF8DB53AB877D37C5DFB9B8A +:10DF9000B7CBBAFA3E9E25BAFA7E7B1B75705ECB74 +:10DFA0002A5DFB0187DCBAFA02EF465DFDA0934DC6 +:10DFB0003AF816DF765DFBDBFC1E1D5CC8F6E9DA7D +:10DFC00017593FD6C1C36C9FE9DADF1E7744573F2C +:10DFD000423AA5ABAF3AC3FD7BD600EB038C538628 +:10DFE000F1FC1AB33DAC09FD8B91991774ED4D31DD +:10DFF000B05E00FEA9067D887EDFF79D12291F33E3 +:10E00000AB8DB0E3BD6F7948ED1FB4F7BC47DB7F44 +:10E01000D07DFFE9D0084F08AD2FAC646F6FE9CD1C +:10E02000EF9BB5E61351EFB3331F8B8BA190900F8D +:10E03000FD23017F6109E00807CF0B0D7E10F94F2A +:10E0400036F08BD0DF6C5D17199292D02E8706FCCC +:10E05000E2EE5735795EAEE5178FC46FE7519E5EED +:10E06000476F2867366D1A8EEBAC194C5E8CFB89B6 +:10E070006A9EC5FD21FAF8965A8EB0027E35DFDB26 +:10E0800017D2D8BDEF4FC8FB08EB596ADFDAAF12E1 +:10E09000FF1260B27334FD3F06EB3F23C875631D6A +:10E0A000C81FF8434FD4D9085E591747F05375126B +:10E0B00095ABEA32A97CA6CE4EF56BEAF2097EAEAC +:10E0C000CE41B0BBAE98CA75754E7ABEBE6E02C167 +:10E0D0002FD4B9A8DC585749E5CB75B554FF6ADD94 +:10E0E0007C825FAF93A96CAA5B42CF37D73512BC55 +:10E0F000A56E15C16FD6B9A9DC5EB791CA3FD535FB +:10E1000051FD0EF0DF10DE59E721D853B797E077C5 +:10E11000EB5A087EAFEE10C17BEABC54EEAD3B4932 +:10E12000E59FEB7C54FF973A3FC167957D8879BDA9 +:10E1300005DD7D3C1536B263DCDFC3BC1598872155 +:10E14000DFF4ED4FE5C70DA6C369A57FD310709727 +:10E15000308EDC2D7D5D83665DD1D09BC72DEB0DB0 +:10E160003C7F4B7D37666B20BFDDC1F8392DEEB7A4 +:10E170004FC77F49F034A66E0FAE372A6A799EF2F8 +:10E180003CE4C74CE2C7BFDCD03A4D59176C4E7126 +:10E190003E81FCC8C2DC9F26E506EED11F4871FD1A +:10E1A0000E9F5FACBD7F0FB69E6EB3A7E347465B85 +:10E1B0003CB198FFCBB74FB4AF933AFE5E8D72FF80 +:10E1C000A1C3FA9DA7BAA3BD2AFE51A4B8FE7E53EF +:10E1D000F804DCE77F51C1C78BBD0DBAF2EE54E7FE +:10E1E0000BBD717F3FADF6850785C0FDFDB1B8C49D +:10E1F00007F92E6112E5C119CF1CEFA30B7E27385A +:10E200008208DFCD642A4F24BBFE88F3B9071620AD +:10E2100008BB065A12DB9B4FF078DE52C6F39632EB +:10E220000EB59C93EADC8EFD1D4B73E8C6F3A292FB +:10E230005F680CF33D87E3FAC73B178E0B29017C1F +:10E24000B7C653582DE5C928633C9EF228E6C58819 +:10E2500009E4C550D70F65FBF8EF1CD11FDACF7961 +:10E2600049B4BE0DCE9BB1B87037CF8301EB31BC42 +:10E27000FF5BF6C02F48FFE2EF41E1BDDD799D0E67 +:10E28000539E19EF0CE0D504CAABC1F3DEB8008190 +:10E2900009945783EA859BE0FFF1382E6BA691C65F +:10E2A000D789F29D3C1DBA9FF2D2604CC1D219F3BE +:10E2B0001E27D13CF73B2F70BF3BC647F75337A70C +:10E2C000B8BEEACDE3E44FF5C33811F2137EC7E6DA +:10E2D000A6F36BC04F660150343D06F8A91D7F437D +:10E2E000E59BD9CA3D1CF539F0E309C4F7B76F0DBA +:10E2F000C844BEA9D9592021BE1B0CFC3E9DFC6719 +:10E30000655F50F93D0431327B2DDD3B40671CE9F0 +:10E310005B104EF70E9A45367F533BFAD59AC3E908 +:10E32000BC3F8EE7936C08DA9F147238DD05A5DDDB +:10E33000E877F7511EB2D97B79BC9AE57AB39DEDA7 +:10E340009CCBAA99FF9BA75235F3A8D97E849FE75F +:10E3500062DE6CED392E49E957E53FD11CEE5A1BC0 +:10E36000A61D5FAB1C5872F2480E8EE3BDEE31164F +:10E3700029F26E817E1FEC5BCC2FE3FA838DCE03F6 +:10E38000AAE702A7312795D3C17222DF3BE51574B6 +:10E390007F7E266BA2E7B3F3A726225CC37C43E310 +:10E3A000707DB4A4FE7D0C078D6F5C312C1EE635AC +:10E3B000CE3DE57D2C4BD60BC76589E4280EBFEF1B +:10E3C000156A177583EFDDFB6AE1228C5B8F1139CB +:10E3D0001DD8879C0E65C0CF6254DBF981DCF4CC7C +:10E3E0008925B9A1F1AB7253B68039F0FC817A3F2F +:10E3F000A4558EF267FD3D01F770C09F447EADD9F4 +:10E400006989A2F529E699417DA5C8CF2223F72F76 +:10E41000654C6D4AFA93FB1B268792CF8B717F6404 +:10E4200096CCD763A74D5CDE4E7F15EE46FE9ED799 +:10E43000E9F544920F932A1F3F4EA2F33D0CFC8F47 +:10E440005BDBFA1FAD7966BA33F23758A22BAE6F99 +:10E450004AC09E9F36B8FB47F0BCFC0EC4D79E381E +:10E46000BE7E9E857968B0BEB353C278E9E9582B69 +:10E47000DD170ACE73C6989DE66752E607239B8098 +:10E48000FEB44589AB3504CDF7FB90449AAF54C830 +:10E490009A183A16469B3C15E5FE416E27E675FA3A +:10E4A000B50BBFEF0D61366110CD87E2B1B2813996 +:10E4B0001B787C96E637DF68B5E1B99CC55344AF5D +:10E4C000407602C689F1BC18AB9DE75555F36F073E +:10E4D0008FD7A11F9F3591E1FC1C22F3850CE2E34D +:10E4E000C5F1C9400FA20FC05334E3837EDD94FF12 +:10E4F0002754B2A11FB6F75F0FF2F8723DF71F6104 +:10E50000FC1B893EF130FE846B8FDF842C0AE39F75 +:10E5100093C3F55403EE208A68673B93FE2D09717F +:10E520003E807C98EA5AD67D0EC6350A2C768CDF62 +:10E53000B12B0DDD514F853189F26A8D71F0BC5AD6 +:10E54000D0DD42E48712CC5B67233FE0AC360F1B83 +:10E550000B8AAF015928BE3A0EE36BFC2ED17B1813 +:10E560009F1DAF9C6FCE625FAAF8A3F89A88E3A3C1 +:10E5700078B58BC66941CA421982711EA2839BE697 +:10E5800011CA3C4A3CBB85FC83150A1F0E3AC4F9EC +:10E59000705018D7773B8F30379EFB6AFEE1AEA2F2 +:10E5A00070842F18494F019E281FE0DB7FE571A979 +:10E5B0009DE78E27E03E4CFD0F7B12D04FDC697249 +:10E5C000893530EE9D0516DB027B20AEB1E3501895 +:10E5D0008FEB2871BE5B9479EE602D0D35509F1F37 +:10E5E0002F328C03E61DF484A23C0F54E2B2C1FA30 +:10E5F00070F025B3EE772D4C363D9CCF34701286EB +:10E60000C8827EFFF306D7B9AFE574F0BB9F2763DE +:10E61000AE6B3F147FCB87CE27E438DFCC21BB36EF +:10E620004E54F02E20BE400F34239D9FA936D3EFC9 +:10E630001A34579BE3BD9AF135CEF847029D73FE1D +:10E64000D73FC86EEDCA53F3E33485E073B31C4E75 +:10E6500071B767AE1828EEB6BAF26B5A9F34E6333C +:10E66000FA1DB1C62BE5E4075C2E66B889C4EA6FD3 +:10E67000FD3F95083F7E8B95BE173CFE6DE0CF7B3E +:10E6800080505BC19FC7D20DFEBC2703FDF4382A22 +:10E69000D7803F8FE533E0CF63FD2AF0E7117E0A94 +:10E6A000FC792C57823F8FCF9F007F1EE177C09F60 +:10E6B00047F86DF0E7117E0BFC792C1BAF7C5248BC +:10E6C000E39ACBE8DEFE82D088A5E8677493C3C9DD +:10E6D000DFF8C8D1B793576367F3BF34E8E8DCFFCE +:10E6E0006027DDEF9D24C95141BF47D32DE8F76A6C +:10E6F000F4BF6F9350A9FF7D9B7857DFA0DFC3194C +:10E7000018F47B3943827E4F47FFFB36B75E1AA76A +:10E71000AB1F7C56FFFB36038F95EBE0C7957C99CA +:10E720002A1DD3A5D742902F56578E8B64EDF8172C +:10E730006A89EB2B8F667FF5C987C409EDC59123E4 +:10E740006FE6F6FEDDAF2CFBD6033E77B14827C659 +:10E75000DD77390CA4979E59154671588B77E029BF +:10E76000E49F5D0E2621FF3C736548271C4F2190D6 +:10E77000119F275472BDD0ED6689F839A1D227E2E6 +:10E780007DD1DBAEF8ECC88F4F46F0DFD9827EDD5D +:10E790000BA0BF7747F7CFC238CE3361C0CF286F09 +:10E7A0001E5F682AC091570D0CF523D84ACAF32F73 +:10E7B000FF3E4C398F7A95EEC345A24E07BDB4ABF0 +:10E7C000927F3FDD7B2554EB0F3DFEE3B5F0C28821 +:10E7D000AF3AACBF6366328E378077508D50A6B3A8 +:10E7E0004AF618E2A38ACB4F63A581E4E932C81345 +:10E7F000E207664D74617838215EFB3DAB9E0E5595 +:10E80000C94B719ECFAC34D26ED930F1D57D37C3B0 +:10E810002BAB0F8AB4CD2ED97CA1EDF977EAB8578E +:10E820003BF8FCA2ECCC80762E0AF0E9A6FD6C7BCE +:10E83000BDF6F7AC7EAFC8E7EFF0FBF0DED30A3FE2 +:10E84000AC54E47398B866443A8E239FEB6BA0A750 +:10E8500080F7B12E4F63F43BA2BF2B4DEED45E9EEA +:10E86000EF95CA389E53E6B54691FB67B05FBCC7CB +:10E870002E9615623FAB9D8CF4F86AC7D7F518B792 +:10E88000BB5CCAFBEDF9885740FC76AFF509D87F31 +:10E890008FB91E2ADDCA38BB55B650BDDA9F6477E2 +:10E8A000737EAFFA9AED85F9E2215B91ECC559CA06 +:10E8B0008FBADA68646887519F217CD96AC43312A1 +:10E8C000ACDB8C630CEF33378619699F62F5ECD3B0 +:10E8D00004AFB0713842AECDC6F3176F29F38990FB +:10E8E0006582DD41F3499726476A7FCFF55A7AF072 +:10E8F0002D93CB7011C631E06F22FD7E4747EFA903 +:10E9000076F65AFAEA4FF88F78B20B0FDD8CEB6788 +:10E91000D94976415DB76D1DC5D76D2B42277D88DE +:10E92000EBFE52858F9E0E1DF33ED61F18C17F074A +:10E93000A779C4ED3DB47A72BB32EE6D0ADE0B8E60 +:10E9400039BE9A0BEF8F745A189EFB18293B7AFC3C +:10E9500002E15122E5351FC01A1BF05CC5C13C55D0 +:10E960002E9CA1287FEF8E9ACA0EE1778AB99DDF8F +:10E970005A3C9E9E4BCC39B237BCFF498B91FC1A56 +:10E9800078FE9372B94F19CF070A1EDF57E8B05BC4 +:10E99000A14333DA132877A13D217B6157EC05B7FA +:10E9A00027DBD09E64201DB83D69417B9281FB6FBF +:10E9B00013A8DD5FD09E40993BA288F6232F232326 +:10E9C000913D99CD16035C08E317DBA1D71DA9A2E1 +:10E9D0008E3EC5DD4375F4191E13AD83878625E889 +:10E9E000E021C6141DECB87253903DE81B640FF48F +:10E9F000F624FFCB21BAF6FD0FDEA1AB2F718CD729 +:10EA0000D58FCD9FA8AB1F6D9FAAAB9759635104BB +:10EA1000CC37EF4B467E685EA73522ADAB957D3493 +:10EA2000D5DF027A923F56F05791E456C5471E6BE8 +:10EA3000DDCF33D07E9ECC243CDF495B96C9BA7AC9 +:10EA4000F2A30E9A9C09780EB1BE04F80FCF231ED4 +:10EA5000AC18C5683F1EF818E42ACF79E24BCA3BD0 +:10EA60002A96F5237FE99251B7AF5610B43F36206E +:10EA70005BBF7F96778DFD33EFCDCAFE431BBFACE6 +:10EA8000FDDF450AF6CB40AE441CF7D3A1937623B5 +:10EA9000DF7CF819B757CD9F3DD51D9F7F824DA1D3 +:10EAA0009F7DBD9FEE8E7CBFAF553E5CA15ABF6B74 +:10EAB0006B26FF1D9A370F266FC7F546AE4920FD1E +:10EAC0009F9BF5249D47BC7CD040BFD3995E5C13CF +:10EAD0008A78D97A685D98FE1E95464F909FAED190 +:10EAE0001322FAF751FA7A6342004EE6C4C1F6FFE8 +:10EAF0001710600A2E008000000000001F8B080025 +:10EB000000000000000BED7D0B7C14D5BDF0D99DFD +:10EB10007D259BC08604DD400293F030228F0D7965 +:10EB20006D42122621D0A03C36801004E384A0D090 +:10EB3000566DEA137B6933493089014B546AC1FA37 +:10EB400058B1DAC7E7FD9A5A0950B15D9E55A1B296 +:10EB500048B051515779685BDA0F155AEFFDF17DD6 +:10EB60007EFFFFFF9C4976864D88BD7DD97B939FB4 +:10EB70004ECECC9933E7FCDFAF73608CB1CF24F875 +:10EB80001F9BC0422E463FBC3DD5D42E62A1ACE8AF +:10EB900076B9A97DB5A9FF0253FB3A53FF1586E765 +:10EBA000AF642D1CAA26C0DFF833FDE2EBB606C623 +:10EBB0004257F4F5CBB30524DFC48BFBE5775BFB51 +:10EBC000C685FF768F5B653D9FC25857B714746644 +:10EBD000C075EC2AA6E5C238DDD620B3D0D5CAE090 +:10EBE000F92B3DBCED64C10D53E1F9B66E9BAF5DF1 +:10EBF00066EC45FCAE93B1F1811B860612192BB170 +:10EC000085637EB7F49CF1BBAFF42C18CA62F4D3D1 +:10EC1000AFBF10E3BED0E0A275ED6CF0505B7F2E6D +:10EC2000FDDF7347E7E3BCB3241FDC86F997273386 +:10EC300058F72F2FAC74E3B8305FC6463036A33395 +:10EC4000ADBA712C63320B2658A1FFB62C89B5C31F +:10EC50003A738FF1EFE7DA95644F0CB8326635C23C +:10EC6000FFA2F1E007E174C11AC4F1F68C5BF2D0A7 +:10EC70005418FF60B7C4703E0E75B53B3009DA3DDD +:10EC80007C5EFAB8D33FB5F6E119FE2B3E136F80D8 +:10EC90004BD1C96186E7B9572E1C8AEF3BE4F9C90D +:10ECA00008DF4BCD93B178131D0D33B54718FA8F9C +:10ECB00097016F93FAC7C37681876D8807B86E8F07 +:10ECC000F3550762E06DDB78E7EA60D43A1B7C40DD +:10ECD0002C7978B5D235F74AC91702F89CEFB6FA05 +:10ECE0001078059E7AA93E06DCFDC78D7492DF1D63 +:10ECF0006F800793960FC8076B8E37B6EE8BEAFFCF +:10ED00000D5F62CA6937FC51C00A68FD9778FFCF72 +:10ED10000D5AEB3E3BD031634A27AC93552E64AC81 +:10ED2000B0FFFE8C35D1FA7438B2CA64C65207837C +:10ED3000A70E7AEF227CF5F37EDF381A63C3019EBB +:10ED4000005E9C57EBE4C0C33E1C275225E1F71F31 +:10ED500070DF2A45607DDF75DFBA17E9F3D07B0EDF +:10ED600019F97AF77B5D6978FF60F6F634A4FB83C6 +:10ED7000F04E18DACC065883B643BBDE8DF4F54A64 +:10ED8000F76DC43F32AB3F3889CB015F3B74DB9EEC +:10ED9000C5E9B0BF79BD24E4CF01C1AFFB04BFEE2C +:10EDA00069F0523BD420D3F5170D59747F57838FE8 +:10EDB000DA3F6FF0537B478342EDAE864ABA1E6955 +:10EDC00008D0FDC30DD5D4FE75834AD76D59B7570A +:10EDD000A03C3A9F0600807535B9E7D962E173B669 +:10EDE0002C19E8E64B5EB781AE667A920DED19AE4E +:10EDF0009186FE656C8CE1F9F44F27189E979C9DD7 +:10EE00006A684FFBB0C8D0BF30526E6817F45C6DB3 +:10EE1000E8BFA062A1E179A07899717E5202C997FA +:10EE20009D6719C9E579B97586E73BF10F94C31F52 +:10EE3000B2A09681705938A03CD5E5F45E819FDD83 +:10EE4000023FBF14F8E942F8139F571AE09D7FBCB8 +:10EE5000F39A29C0AFBF6A584DCF1D5943CF49F02F +:10EE6000DDED67E365947BFB1BEAA9DFC1B71F24D7 +:10EE7000BAD929E671D0CECE4929D8B6C84D968BDD +:10EE8000E793D763E4F3F1953790BCDCD9DDE44632 +:10EE90003ADB115930287DA7F7FBD5B90533902E01 +:10EEA000FCDDA0A3322EADF7747D75A9F1F57EA827 +:10EEB0004F63E909F3B857475489C13AB6F7D43FCD +:10EEC0009488EDD0972519DAF93DEA0CC4D7AE2C19 +:10EED0008B47B250BF190ACEFBE46DD7E0FD1DC7CA +:10EEE0006D569CF72190FFB88E9DA06F9DA87FCF97 +:10EEF0006D754F06F8BFD8F3E03593A19F76C6E64F +:10EF00001BC72E9EC7A86C89E4C2B6894EAB650AA2 +:10EF10005C8FDB5808E5974D25787645B6D215F518 +:10EF20001FBF5F4FF8BA32DB43EF6D3FF95C32B67B +:10EF3000ADAC9EE4C08BC7AD95C118EBBD12BF034D +:10EF4000B223EF4283DB03FD0F1C5FE146B9B2A39E +:10EF5000878F9FB75673239C0E46B626E0FD9D59BA +:10EF60003FA371774FE276C5CEE356A2E79D13AF7C +:10EF7000D8E0CBA575FA1076703F01DBDB7A6CD454 +:10EF80009699CAC2292877A460BB05D7B382BD066B +:10EF9000CFCFFBA420F27D1ED31CC0A26CDBFF6B85 +:10EFA000599CCDC1CF6C9731760B7F994D3B6BD47B +:10EFB000B3453D463DE2885C383A1FC6EB3AC3E5AF +:10EFC000DB8C4F8D7AF7E01B999B028897337C3E50 +:10EFD0003B8E2F58548572E77989DA8D93563DFA26 +:10EFE000757CBECDED73C2F7BE9CFB644B327F7D5A +:10EFF000C85C9847B19853DE19E33C0E5E59C73E92 +:10F00000C6759EB4D13AB61DE7F6D5F92CBEAE9DB5 +:10F01000BE3AF66DE42F617FCD78FBFBD74C4A41B9 +:10F02000BAB0925DF182EF67C939289F3C9281EEB8 +:10F03000004E4437E7BB198D031245BA15C629F0B7 +:10F040003B3DED1EE4C70EA29F836FDB7C4DF8585D +:10F050003AB4F736E89F375262B8A22F074DF2F262 +:10F06000876E43FB16D9282F9DAC6A40BB61DA59E5 +:10F070008751BE7EEA308C57C0A29E133EA39E6786 +:10F08000FC0576895D5D8676090B2F1A94BE66AC09 +:10F090009EE4C50EC67CED404085574A0AC1EFB8D4 +:10F0A0008BE057F0DDAA698CF4B43A0DF981883110 +:10F0B0004A2F5FD24EF1682C255F7C0AE980D94E39 +:10F0C00047A07F1B10C967A8BB851E378FDB9FBE7B +:10F0D0007FC03D84E47D718585F8E7BBEE5749BF6D +:10F0E000779DE2FA1D7F224077D7E21FA8EF4F39C4 +:10F0F000881E5E986D2139A2DB0B0B996247BE9981 +:10F10000E73F67BB1FE836E0AA99740B5C5F78A302 +:10F110006B24F2EF0B6817907CE8207E7668895AA2 +:10F12000328CB3ABC7497CB813F8CA85DFDDE52460 +:10F13000FA043E5D8F76C2AE30E7A3AEB3566EE7FB +:10F14000ED72139FECFE8383E6DDB5D6CDFD8B33E8 +:10F150000E05EDF09D6B13E9FDF17262C88676FC39 +:10F160001A3E7E8FC0EBEB02AF07859E7A19F594AD +:10F1700013F5904CD7FDC28ED88B768413F5995F2A +:10F18000E833AEC79E3FFBDC5B48FFE777C591BD28 +:10F19000399E6575E2BC762538689E66382F558D98 +:10F1A000F4BFA4DA682FCC9968A4FFABC78E34B43F +:10F1B0002BD3C618DE9F957295E17945428EE17991 +:10F1C000B96D9AA1AD5C30DA0BF3FDD718E9498926 +:10F1D000B21732F1FF467FF1DA687F11E5C8D90531 +:10F1E00064AFEDEC117AF964E65075E2C5FCB3F357 +:10F1F00024D79FDB8F7F9CA8C6B01F3E14FD7E27BF +:10F20000F07146E0E3B7A39493D94097E74F7EECC3 +:10F2100000A5D12F1DEBEFEBEF7D183C31245AAF49 +:10F22000A74B32D1B7DEFE43D75BE3F1F960F902B9 +:10F23000F4585B04F07CB794D8D10EAFB4DAEA9FEF +:10F24000C0B6A6D9D8D3B9048E2C1B3D9FE0437B12 +:10F25000A539B1FE07F87C5BA3D3B33505F9E85BAC +:10F260003FC1F61A6005275CFF1C372AC880D51CF1 +:10F2700053B9DFF28C3D30D2877AD31258760BF433 +:10F28000D7B6387C4FCB17CF2761AA4567F61DA8A4 +:10F290008724C1F7FF695113A6C27DE5590BF163BD +:10F2A0001C38A2380F270B8490FED96A6519F20723 +:10F2B000B302FFC0F51B39EA30ECCF14267B601C8B +:10F2C0001215F03D4BF8C07F58605E7656AFE138BE +:10F2D000CED52061809F1FC85653A9BF6D018DFFF9 +:10F2E000FC5CC6DA492106A89D7B17F3B427C1FC54 +:10F2F000986AFD18DACBC0CFC7EF5BDD37931E7A73 +:10F30000EBB7D6A014C35EEA85F3CDF633119DCEDC +:10F3100032FBEEEF1078ED1274B12323B02C965F20 +:10F320003815E182F6C5BBF324A4AF5CD71005ED18 +:10F330000A58A05405F27DC7FB57BB6B63BC37333B +:10F34000B776EAD428BAC80D774AB509080A4DC27B +:10F35000756D83BF715D3FEFB68610BFE7131C2448 +:10F36000B7FB5B4761C4A8870B7A8C7E3763CB3DC4 +:10F37000A7AF427877583EBB2A9ABE94F5D1F4F5F0 +:10F38000FCC5F44570BEFB6816C1B5D9C2E94B0394 +:10F39000FAC2E75A793DD197666581E65CA2377A71 +:10F3A0007F8DCDE57182845C353593E8A62B71CED7 +:10F3B0005B2199BE376601F97135C28FAB2139FFE8 +:10F3C000F23190F331ECE8DDC7168F8C00FCB68D7E +:10F3D0005B3212F9BC0B15C0089C7EFE52B42F7B29 +:10F3E000DB802EB20367320C55C1F3DCA50AF69F11 +:10F3F000ADB7F378FF32DEFFA6A99BB668F8FC7ABA +:10F40000F19C2DE4FDF5B656B0B40CFBDBADD47E1B +:10F410005BF47FC8A7AC42BC3D90ADACC66B361A5E +:10F420002B703D3D45F90AD2E9AAA98CD67BD714A9 +:10F43000E5E6E8F6CF262BB746B7B7F5FAA71DC223 +:10F440003FBD85ECD2977B16905E9259E01AD43B73 +:10F450002F87791C6ADBD881FD9F5F097B7EBFF017 +:10F460007FF6A23C223F88FB3FBF147AE545A157B7 +:10F470005E107A65A7D02BDB857FAAFB47AFA27F02 +:10F480000AD743C23F7D05FD25E8973BEE04D91519 +:10F49000E73F65C4BC4DEE5F48B1E46A659AD17E32 +:10F4A0009B9562B4B72A128CFAA6DC66D437CA855B +:10F4B0004C43BBF4DC0443BBF88CD13F2D3A596478 +:10F4C00068FB8F971BDAF9DD579BF4CF42C3F355E6 +:10F4D0005365C2E35C9FD14FBD26ABCED0AF0F6F5B +:10F4E00001613F3C968076DCB6B175026FDC5ED080 +:10F4F000F1D6F54F83B7BDE49F9D3FCB445CE171EE +:10F500002996FFF9AF8FB74BF05B02B7F32EC56FAB +:10F5100007847ED827F4C31EA1FF43C28EFB8588D3 +:10F5200007ED42BC511C88C7837620DEA2E211CFD2 +:10F5300023DE9CFDE3AD79EC439CDF4EEA78BB35DE +:10F5400026DEBEE435DA77333D46FB6E86CB88B7E0 +:10F5500032668C074DFFD488B792B3C678D0B40F0B +:10F560008D782B8C18E341053D46FB2E2F6C8C07C4 +:10F5700099F10676404ACE20F0067E924274EB1353 +:10F580007A3FB890F451CB5CAE1F810FC9FE7EE686 +:10F590004EB003B2FBE0F1BCC97F7ABE1FFD3D3E19 +:10F5A00087DB355D6FD5105CF3507FC7E8972DFA88 +:10F5B00065E778E8EAB4312D7E2A4D73DF08988F2D +:10F5C0006D2CB77B6C891B18D98B406ED6FC3E3BEB +:10F5D000494A08301C1FECA5EC9CBCBE716D9E7A9C +:10F5E00086F253723EB81CD7C524AB8FF4AEC93E29 +:10F5F00062AB3DCA6D78FFB621BE7680C54D3949F4 +:10F60000340F2FEBB4A39DF18D1CA508C795667030 +:10F61000786C4B071F1EE0B12D8EB73580D7D3D045 +:10F6200096862E27F87501BCA46C1C3F85DD05F37A +:10F630005A98E3E07058CA843E7DDAA80FD1608002 +:10F64000F633F1BC7D6DCE334BB5B43EFD5BF3B309 +:10F65000AE2D1A8C333E61441D9B0CE36ED686A101 +:10F660009D3911E687F2D1EADE951E4B4FF467878C +:10F6700069939545481F7709FD3A1E20629BDAFF82 +:10F68000FBCFC407BE8AF8CD457844C5BDE6E67019 +:10F69000FB6C218E9347F6A5126D5FB2F0426AB7FC +:10F6A0006473FA7A6AC302A2B70480979484F3E77A +:10F6B000F05B7607A7AFCFBB0E7DFE03D04920DA03 +:10F6C0009E8EA293BB62D1099BE3F392BFDE9F3D66 +:10F6D000A7F1F9360BFB51B7939D69BADD1C147085 +:10F6E00060A1A26174653301AEC33C8CE234351E67 +:10F6F0006B3008208B4B9A6A21B95361619E0C1CB8 +:10F700005D611C8F73E468F9638E0FFA8FC79BE409 +:10F71000BB31EE547C6684A15D7A2ED3E4274E3053 +:10F72000F99139263F739A493FCD30F4AF4CBBC6AF +:10F73000E4C72E34F9B946796363364DE0CB4A719C +:10F740000BCD22DBF2F13E23FC443D27BFB317CEA5 +:10F750008F2AD5C4AFC2AF31F3EB37726482B3C521 +:10F76000C3FD1A9D1FF4F775F839BC1AE17563BE25 +:10F77000AE9F7CA4775CA12F338CABBA7C3C4FA3AB +:10F78000F7DFDAE07AAB621C63DF6F606F5500F27F +:10F79000820D1EBA3EDEE0A5EBA30D325D1F69C8E7 +:10F7A000A27E9B1B7CD47EB8C14FD74D0D0ADD7F56 +:10F7B000B0A192DA1D0D016A6F68A8A66B7B834A1F +:10F7C000F7C7DA540DE32063DB984F83A58CEB80F9 +:10F7D000EF45C16D4C1BCC230AEE199AC7D01EBD54 +:10F7E000C66BE89F5E2F1B9E8F5C9D65789EAAFA74 +:10F7F0000CEDCBABFD86FEC3038AA19D5C5969E885 +:10F800009FA4040CED445FB5A1BF3B4B353CDF53D7 +:10F810005A343432001F773484C20887F686305D4C +:10F820003734BC44D796869E30C2E90CCA5FC0A369 +:10F83000C7D649F2C333D1C3304FE17201BE008F46 +:10F8400049368F25296AFC2405C6CB8A9E1F8C6702 +:10F85000F0CF82442FEEACB0E1BED3DB63786FA66D +:10F8600094508EF98923C512C5BD8E142727A2FD99 +:10F87000B2DEEE999B0BF3387C4CF26DC5F5E20BD2 +:10F8800031E4E529616FBA27BB482ECCDF64D92A61 +:10F89000115DF3F76FEA1E13337E74F89BAC1AD731 +:10F8A000E5DEB35346BA985F5C9B1C17E5AFCD0FFE +:10F8B000FD47452A8D979D1F07F4327F73ADA36ED8 +:10F8C00062DFBAF47E376D32DA977D741F74E13AE5 +:10F8D000C66BDF74A17C6B4FDB4AEDF6AC81F32481 +:10F8E000BF13EBF950D8CFA7851D7652D861EF0B27 +:10F8F0003B2C22ECB07784FD7C5CD8CF6F0A3BAC0C +:10F9000047D861AF0B3BAC5BD861AF093BAC3DEB7B +:10F91000B959240F9FB53029869FAA5FBFFA43A328 +:10F920001DF6E5A0D10E5BB5D96887DDD861B4C3FB +:10F93000EADA8C79B95AED2AC3F31BD618E36CD7EF +:10F94000D71BE5E1B2D5330CEDA5AA31CEB6A4DACA +:10F950006887E9F8B93660948B0B2B8D76587FEB6E +:10F960007D21349BF23F88C413517AAF378F8B7A55 +:10F9700005E825F702E8158A83079A317FB203BBB1 +:10F9800080FE2DB1868F4E41F9F9BAC430EEB4E74E +:10F990007CFE9CF9F2C5DFC9D78C74B3FCB831BECC +:10F9A00071DD1D46B856DD6CF44B1C9546B82A69CE +:10F9B00046BF64A159CF048C700529CD902ECDFA95 +:10F9C000C6EABE5946F9FD79F58E83815EE16D8305 +:10F9D000DE71E09D4CC373D23B6DB93C5E970FF373 +:10F9E0004063A131AEE010E693F6BC61A3FA109833 +:10F9F000E06B6341FF94E2DF00BF17EDAA560FF4FE +:10FA0000FACB42A7A7094C56269DD9FB35E8EF1043 +:10FA1000F910F6A9ED248EAFC22FE22B9F413B4A8D +:10FA2000CFE585F9F3A8F91A9E7F0F7136E07C9433 +:10FA3000D7C6E6FF3DE7939882F6109BC2A6509D7D +:10FA40004164D8A0E2ABE6FBB9216E07E5A6713BA5 +:10FA5000C89FBE40127927E6C1B695B9289E398A5B +:10FA6000059FC63867FC21F73C6836E390A9E85744 +:10FA700019F97FD19C81F3F25FF21AF97FB63CC687 +:10FA8000E40F19F97FAECFC8FF4E66B25F224C4635 +:10FA90007B927060353C2738BD26E8A8F1BD96659D +:10FAA00094874DE771379D7EA6097C31D6B9B7168C +:10FAB000F3CDE057A2BFE1645AF214AC2B0AD72B66 +:10FAC0007ADE8DF026ADF5915D7A86E3C70FBF88AB +:10FAD0003F3F8BC217E2EFB8117F4ED3F3D3829E24 +:10FAE0002E9E17A7A37FDCBC4C749530EC12F9B79F +:10FAF000D874551656A44498DF7E8F85F2A9FBC3AF +:10FB0000F5E132687FE2E5F542AD690B6C345FA642 +:10FB10000C9909789825D6EB1779ADAE064676C7CD +:10FB2000F30D2EBA32562FA13C6AF1DE968CFAB153 +:10FB30006B943A12EBD2BA8627ADC3FCFC367B52EB +:10FB40005AAC7A96DDF602D2A75DBB536D32BC5F2C +:10FB500066F3D8F0BDB2B41512FA7B5FEA616417A0 +:10FB600094A5F1BA8CE71B4247F8F754AABF8175F8 +:10FB7000CC40FBB4C2533B233105E3B3608BC9686F +:10FB8000E72691FFBA6FB893F0E6F4ACAAC0FCF197 +:10FB9000ABA912B3F8013F3EE60BA11E484BF0059E +:10FBA0007138AFFD7D84F36AF8FD2CB34F2F009FB1 +:10FBB000BF1F8D8F0216D5A6BC82B13D224FD43F08 +:10FBC00009FCC84CA53A8B961E9E1F6291D8799667 +:10FBD0007785DDA0C7F78F0BBBE14D11773B22EC9A +:10FBE000861661378484DD7054D80DFB84DD704047 +:10FBF000D80D2F09BBE11561371C127643AFBFC08A +:10FC0000EAC99EAE65AE08C6D95F05FF1CE58877D8 +:10FC1000A5255809EB98A17604CAA1ED5C6727F9E0 +:10FC2000393A4D6BC4F8B8B35A9B89EBF02E3FBB01 +:10FC30001AFBA7A6396405FA3796B6A746789E61DF +:10FC4000C85CE08F95825E96AAB30E207FE870674D +:10FC5000D2A379946FEAE0F076C12FC23B55857646 +:10FC6000941CA935C17529B6A3E48603E910E058B0 +:10FC70009927F82187E570786B7108EFB85A016F02 +:10FC80006F4A4CFED82CE0ADC36377E957AC1A74C9 +:10FC90003D9AC6EB258E167FC5FA2AACAF5B91283C +:10FCA0006FDA9DC6C75B20E8DF3C9E9E47DD583E6D +:10FCB000709CEEB0E8D7DB6E63B27368D438E5FFB2 +:10FCC0006697E1FD25A17BD2911F360ED1F3C33E8D +:10FCD000B2AB674AC5BFCE80798645DDA32E271714 +:10FCE00033011BD3F78E8A75F6379FA3E5D7D86506 +:10FCF000187751E81E86DF73DAEABDD1F5A4DD621C +:10FD00007EAD55B733E4C7F028C03BFAEF01A78CAE +:10FD1000F6F6E834DFBD88776F9A6ABF13EECF033B +:10FD200039287B705A1DBB53B01FBCF30843FA98A7 +:10FD3000D089FC7634DD45F2A6BFF95CA43F828C05 +:10FD4000EC90FEF407D031D941CE391F1C477F76A5 +:10FD500021ABF785E0BD70AE6F38F22FABB6935E86 +:10FD6000CE82DFE87C9A7E5D68D2DB6EBF7D40F993 +:10FD70003BFA42431BF2CD51C137AD3696887539F7 +:10FD8000E139B7BB103EF3D333F7207E58992B32BD +:10FD90000EE0D05A7CE7F508AFD639AB3C16A4ABE1 +:10FDA0009231F43C5CE63A8D9538BF29BB3B5D8EC1 +:10FDB0008277EB7DAC544578A7DFE5BD09D69599F0 +:10FDC000F6A7067532F4B3737FA7A7FCF76919513C +:10FDD000FD27E595FD200FF9B97238F1C378879AB0 +:10FDE00019AB1E58A7F3C6D278E2F3F76B799D02E0 +:10FDF000DCBF770DCC47C5BA155F1FFFDE28E829A9 +:10FE00006EDC39E273F53EA78C7E069396B7AC8123 +:10FE10007635DA4968376DE27CABF3717ABD515EB5 +:10FE2000AA26BEAD36F1B5CEC7BB75B9D9C7C7894D +:10FE300088D7B85ACE4FFDF1F1D24FC1BEA142A032 +:10FE4000A0C1AF7B63E59878AEBFA2ECDA2924931A +:10FE500064473E568132B26BE3C57320C9DD389FDB +:10FE6000F03D3973115F5A23D8FF38B735F63E7A23 +:10FE7000CBC475B2217E587FFC5A291BF329ACDE16 +:10FE8000DE6717671ABE4775028BA3DB48AF9AF28D +:10FE90001BB41F308C891FFDF37B47F637C3F7DA9D +:10FEA0004724B34684E71D9CFE5CF010C703353D34 +:10FEB000C48FCFBF352E1B53F72C9A5E61FC88C6CA +:10FEC0009FBFB36678369999A25D73CF98A9D8AED3 +:10FED0000AD84F46CB55566123FC5FBBD6B215E31B +:10FEE0007EE3A58FCEEE85FEF157397CCD30FEB591 +:10FEF0000FACB0235C1669EAFE3AB8BF08E822E806 +:10FF0000A37518F8E4A8CD63C7718E56585807B486 +:10FF1000E31719BF53B3D6C847663BE458A23ACAA1 +:10FF20000AEF7F6071B2AD70DDBD65D5E338DEA943 +:10FF3000079C544FC870AC7CD4034CC42595C7EFC4 +:10FF400081E72B363B19C603960A3B3F313F83C6F8 +:10FF5000B5BA97D3FBB5ED89E40F9FDE72F964C49F +:10FF60007FDBB0FA5B03C037A792D41AC4EB8AD602 +:10FF7000ABAC1A3C6F8BEF9889FD3FB032CFD66C9B +:10FF800068CB0FDA713E3D6017609C559F676D5BD3 +:10FF9000147EE1BFEA7C1E779F67656A670C7BA6CB +:10FFA00023DFA2C7573567D4FC1FCA97E9FEBCCC34 +:10FFB000612D0FE17700FB1E9F800BAE7B268F87A4 +:10FFC000B6A5F96A8643FBA485799A52F0AABC8348 +:10FFD000FCA9DDEF644F13FA19F5778C1CF1647BF3 +:10FFE00094DF3F497CF744127FFEBE373E88EB7CAE +:10FFF0005FE66DCD9B10247AB6A9598B13F97A2C44 +:020000022000DC +:1000000097E1AE073EBF6389B22393F0C1E4E76096 +:100010005E2B367D97F0BB0DE083FCD9E3915B76D8 +:10002000C33C4E83F2D6F0B9F7919908CFDBA70213 +:10003000A1A65E0CA77BF287F13CF4E6E644D2F77A +:100040001EA63A2EEB83476DC7F6BB2D9349CF6BA7 +:100050005C7E70FEB3B028F90EF89D57F81DFB0AC0 +:100060005C6F1CEB40BC58F7AD73E13C97D6DA29C6 +:100070002E94C00295284F6B3759A80D3F1B505F37 +:10008000AC10FCD5260F3B5087F0403B9CFCBC4796 +:10009000F7635D40AD905FD52B8D747AA3D766A0D2 +:1000A000E3AA3546BA86751ADA9BF379FEA5C77FAF +:1000B0002A05F5731B2C1BE1F2418B25B895E46BE7 +:1000C0006054745D9D9C6FD5EB56647B14FC5700A7 +:1000D000FDAD40BDE1621DE5A9B8EE71B390DE1D36 +:1000E000C7E2699E66F8FEB3C3E144BA5C331CE61E +:1000F0007302E818EB7EDEDFD24CF60BFE4806BE3C +:10010000F6B4207DDF04B37CC443F4E9C0FC914E17 +:100110002F3A7C6A37671CC07EDEFF932883D3C4E6 +:100120006ABD45AB30AFD34B4726F8E09A6DFA77FE +:10013000C6F4D1193D8F4167E5D097E345237EA9E9 +:10014000ADE8CDE78D1AA86E99F05D049FEB9ABCDF +:100150004C2B16EF03DD6F2C7D85E8E0130F0B4A67 +:10016000DC9F7D1DE57EA2989BC69410CAD721A274 +:100170005E14F512FAC9C962BD496B2C6F56E430A2 +:10018000366C8DF46605DC4CAA0887504F38BD42AA +:10019000EFEE2AF8C9F8CBFAF4D890F839BE10ADD2 +:1001A000C6934AFB12EC9E54B47F1EB058AA315E2F +:1001B0003F8419EDAA64133C58AEED64B43D1E2F84 +:1001C000E4FDAA99632CE4E7541AFD529BC92EFA68 +:1001D00011D2F5F0BEF5CBF827C0B105FC3694532B +:1001E000C3421D1D489F3560B70669FD3ECAE7380A +:1001F000407F3C62E98B5BFDA3E21617C5BF44DC80 +:10020000A2BFF8971E0758C86FB18D0ED58BF9BEE7 +:1002100085DE9BE6A01DDA58FA152FF94BDED36474 +:10022000973A845D1A376EA587E7CD38FFE87100ED +:10023000335D99E34966FE33DBA5BFCD17F6D304E2 +:1002400036E1F3C405F4F87D6B16F77B5AB35634E8 +:1002500061DDDA79E1F778342BE171F1220BE151BC +:10026000B7D716FBCF2E42FE7B55F81797F27BDAF5 +:100270004D7E48BCFF494589A13FED055C3EBA8BE8 +:10028000F9F3C52E667345E50D1C055CFF2E063D92 +:10029000E88225CE633CBF319F19F35249621CFDB1 +:1002A0000A3FE1A9F9863AC1A4027E9FF2A04E91CD +:1002B0000775893AC1B2EC737B3FC3FB0AAFFF7588 +:1002C0002AB58FDD8976DFA2449F95E8577DFA3BFA +:1002D000E81F2F7293BC4DC992A9DEB53ACDE52334 +:1002E000DAD794D7D12F5BC488B701D40AC9DB25EC +:1002F0005817E119C0DF710D1C2F4BD0FD9D624EC8 +:1003000057BD71A50097DF56F8457ABAB6DA482F7F +:100310004BD481E927BB40F8D162DFD6F8C885DD30 +:100320009F115D70FEDD388AE7A1CFCF813E98B77F +:10033000EDC71ED7FDDB043BF8450968BFEE257A03 +:100340000F67317B34BE03C592A1AE215CC8E23D8C +:1003500043713641C257D8CED21F80FE87CB3E6054 +:1003600077C0A712BE33CC82F57BFD7DD74CD7F783 +:100370008DBB89E2FCDF9E0D2082F9DE878965AAAC +:1003800023F8E9329CC7B7B14D75753F5A8675752C +:10039000DF8ED3DBCF7F4F89AA2BF87AC1AEEFA1D6 +:1003A0005C575DA05F613CB7CCA88E8AB14E92C706 +:1003B00012C6FD501E4F8C8227F90946F89AED7639 +:1003C00009F13719E9D1C8E7E6EFAE32E1A5BF750B +:1003D0009BDF839FEA09467AFF5AC10075B1E6F7B1 +:1003E00013B04E22F1F3D71780E0A43CB4C4AC3E66 +:1003F000F48F5939A3EF593C9C8E50A2A0DEB3D79D +:100400000FF111DCA01D877A20E8D6E3A734E93884 +:10041000A40309F38621D2DF309588650CF6D7EB6B +:100420000C54F6997BF0720EE42F8D2357F23CF2B8 +:100430001B0A8BE0F7C63FB239908FFEF931D0AB83 +:1004400032EAEDAF682E689F5BCB280FE0F6A8D4A8 +:10045000864F459A61BE5E95B76B0046A8879D5E44 +:10046000639DEBEED247CA1CF0BCA582C7550F377F +:1004700084DE588779DAE222928FEBB063D47CC3B2 +:100480007BE21C187751B5AFBBD04E7E77ADE4C090 +:100490006BB8A956C345BF91AA755A648C33A80C92 +:1004A000FD7AC7DAE69948BF6FD835DF30B8BE8726 +:1004B000715818BFAD49BB05FD1C459E539901728B +:1004C000616B9B8DF613BD57FEFB34398AEF7E5B63 +:1004D000C0FD845777C77D1BE1D06A7145E2F06AA1 +:1004E00057B7DE9782DF73F81A618A6F343E948EB5 +:1004F000DF69BDB1D5B7079F373A7187296BDDE258 +:10050000AAC6715BD36FF2DE1435AE6BA4A31EEFE7 +:100510008747B450FE59ADF439E292705D1F257AD9 +:10052000E1FDB6B539C9488B2DA98E5175D8EFA616 +:100530003FFFBA00F12E5BF391F51CDE0E3BAE7B64 +:10054000B457D5300F7E214FDD87F4BA74CD7B339D +:10055000A93EAE22E95EBC8EBEF0B53684FF1B22FA +:10056000FE12495D4179D99695752E9CEFFCD4CC4D +:10057000A6E8F84B4BF18DAEF1F05EA6D75ABB6AF8 +:10058000C8C5F4D182F19629382F58CF24ECF7A7AB +:100590000615FA45D21DD5B1F663BD2BE0E76A5EBC +:1005A00095897190962D2E4CC3B0168BBA19E39C89 +:1005B0005A4642CC7AF5097EFE5E8DEA99E99009A9 +:1005C0003FC46FBFDDFEFAF7B4B1684772FCB96C87 +:1005D000CC658FD27793F2CA4E1644F9CD177D378A +:1005E000B585E47F8B85F3EF04FF1FBF87754FCF81 +:1005F000E605CE20FC5ADBD4CD082FA6B9D890D280 +:10060000FEF924721F1BC540FEB6343AAB63D59B7E +:1006100045564AF3904F8083DE1B322A4ADE37D597 +:1006200065623C24D2780571776FFF2DAE77100F8D +:10063000912D5949A8FF22E92B3233916E055D9A1D +:10064000C7FFF7026E3FFE242760F5A35E9EC8F346 +:100650009BB30B02366AB30E2FDAB55F00BA1DE901 +:100660001FFE0FA55BD273EF6EFF1DD115F30C2E8D +:10067000EF1810F2B6B1F43F29BEBBBE90E74DF4BF +:1006800078A06EE7C68DFB7E08FDF140A19ED72ABB +:10069000BEF7768C1FE979D3393C1EE881DF58F12B +:1006A000C080291E18DF4F5C7F865FE83D61CFA6C2 +:1006B000C91D817294BB87241FFA0F98AEC079566A +:1006C000052CC110E51FE25D34EF1211D714FED6E0 +:1006D0005231EF371B5C0CF3461B1DCA7E9C7FBB5F +:1006E000C8FB5EB7FA817BD1EFC6B835CE7F1EE37B +:1006F000761C2B8EF351BC05892095F5FA670BF01B +:100700001EFAADD29CBC68BD083320BB653E33DA0F +:10071000730B98C9CF5AC9ED30DDCF5A66B213CCEE +:1007200076FE22D3F3BE7C0078174037E7FC391BF6 +:10073000B1B4ABC6BFEFDE480CB9734CE4E98E36FA +:10074000286FA21EBA77D1CF5C48A7EB6D9D2ED43F +:1007500027EBE7DC9E88F4B77EB9447C79A4A192AC +:10076000FA1D6E08D0F55BFEA4DE785648CF33C084 +:100770003C5EC953EE423AD7EDB14573CADE5C1711 +:1007800085E70515B30DED4071D59BEBA2E3903ADB +:10079000DD49AC3E561CED593FB7DB6D4097545FC9 +:1007A000283DEB1BA8EE06E8E85C349CD6FB8DE701 +:1007B00010BCEA9F3174203B465FAF0E271D0EFA36 +:1007C000F3FEE679A79FCBADBF749EC1CF394FF33F +:1007D000FCF479F7D73F2071BD70A7BF6C39EE17D5 +:1007E00079254FED4479BAA832693FC61A8EDA38B6 +:1007F0001F1D5512695FFBFE89566ABBB378BED5D3 +:100800008C5777652DC9B54BE137BED8C2E3CCE034 +:100810003F29F0E72CB1BFBE7D2223FE6C2CFDF1F9 +:100820004B987FFE4D999D0939336F6E94BFB4D1BB +:10083000D119BA338A4F81DFEE45BE75EB798780D7 +:10084000317F08FE8E217F6896336E53DEE1B00E55 +:10085000F77C80FB983EB8F7EFD7C4A60F407C1E0C +:10086000E2DD0CA75B4DF031E72702BBAA8CCF0776 +:10087000E9D76C6DCBDD8F79350DECCB7100A7D747 +:10088000F011BC17AFFC94D220AE42CE37E3236701 +:1008900036A09EEC069580FA66E382DB3763FB3C6C +:1008A000D80188DFFEF980FB6FCFE6291FFB63D4F8 +:1008B0000DE8D76EB417A6605E30B6BDD0BD72C667 +:1008C000DC98F6C282BACC3C9C5795D15EE8DE52E9 +:1008D000F9580EDE477B017EBA0BEB0CF602ABCC6F +:1008E000B9047CB8FC8D1B971BB33E6F7E9E3AB457 +:1008F000306A3DEEAC7A165DC7F8C77CC55308EF89 +:1009000057F59E43C2BF07F6D83E7B8CBA45FD7BA8 +:1009100053FC7C3FBF7E8EC860CF13D1EBA7D7DBE3 +:10092000956AB4FBF4B897DE6F4A218F73B4652AD9 +:10093000ABF1394B987A89711BF5384756F665A2A9 +:100940005E5866BDFED17F5A647A1EC3FF639897D6 +:100950008C4F3BBBCF035D4EFAD55C8443C9D9A015 +:1009600086F910E71C0BD94FCE344676CE60FDAD2C +:10097000C1F66B6BE2F2A775058F979765DBA81D33 +:10098000AF4A5B51FE4CBF30D4827223A04A4FE283 +:100990007CE3958F3E7C0AF535D801188709B07A3B +:1009A000DA5F9D600F507CA27D0E8C9C8D71982625 +:1009B0007B26C5D3337E9AE8C5AF05DB305EEEF407 +:1009C000F17D50D57EED5E3C2F637EC9380B83E709 +:1009D000F3025CEF2FC6F80D8EBBE8EC6E8CFF5C6B +:1009E000EBE7F20BFD38F4B396D4DD3DE961F92F66 +:1009F00089DB04DB9273299E2453FCC0141F7216FA +:100A0000CFA2F8905E271128E6E7F7B0B4043A7F4A +:100A1000C21CDF31C773CCF11E737CA7BE90EB7193 +:100A2000DDBEFA5AA1D1BEBA0BF71E0C47790B2ACC +:100A30000AF8BADDCED23B2646C75FAC0CE32F776F +:100A4000159AE28C83945B61902B2770217B5FB6B3 +:100A5000A3BFBB5CA9A5F89E99EE1F10F2ABB930FD +:100A6000C150D7116E5823DE8FD310CFCBC73A8237 +:100A700071197DE30C963FB6E42BF717723F6323A1 +:100A80005E994FA57D04B30B3C06BA65F5C3D989C1 +:100A9000E8BCAEE9BBFA7CF4F13FEF3C3608780FD6 +:100AA000964F369616B91CF0FD4F00C7BC3E1A0C87 +:100AB000ECA8F8B41E3FD7DFABC1BC410EDA9316E9 +:100AC000CA1FE8F7A3E2D836A4DBF8345509C4906E +:100AD00097E1C2DEB829E531F5EF308B4A72A14EBD +:100AE000E46BF4F16CCCDB487C80B4ADCF4B8A1165 +:100AF00037673E97134866C50689613C2881291DE2 +:100B0000187F76B4D9A9CDB4EA0363A3EA871CC5DC +:100B1000B30E609C4DE70B73DEC621A5CDC261EB21 +:100B20003A8CF92B737ECA6C57EBF1751B7C04E78A +:100B3000F507C4075F6F501ADC7A9FA4F57C41D794 +:100B4000ABD3D59C9CAF7AB1FEA4254EDD5C0BF3F4 +:100B5000D21E7351FCC28D73439884E017E5E463A1 +:100B6000FEA750FE5E28E4E7D1B458783DCABED453 +:100B70003FA544EF5BB850C8EDE1A70A651E27B159 +:100B8000B110EE93621353882FF4FA93C3A9DCBE1D +:100B90009C5F7263E87668FF2F51277955C9D37A35 +:100BA000BE7F48593EA3D20F6E0FF27AB4C357F6F8 +:100BB0009EA7B207FD4EBD5EF7AA4EA39F794D9644 +:100BC000DDD0BEC8CF34B5938ACC7564AA8BEAC891 +:100BD00052451D9998BF994F7ED8C0F31A3F16F51C +:100BE000FECF8AFDB2FF5BD4ED758AFDB2CF89FDE1 +:100BF000B23ADCD7DB558A4F9F9A0D365D765F5C43 +:100C00007063E937BCC8C7938B2C7A7E660FEAA95C +:100C1000BEFD15039F0BB6B0D29837BB3660CC9B98 +:100C20002DA936E6CDFE94A34C29C27CCBE4D54D4C +:100C3000783E41D52689CE27D8F8F0271F3E85F685 +:100C400062313F7FC7FC9D2362FF85BE7F43BF5F4C +:100C500056C4E9C3BD27D58E75F8559BAA66613C7D +:100C60009D79A60ECA7E9B8D317858B7BBC963C7E4 +:100C70007320AA424B1D38CE8D9B619C84C18F731B +:100C8000DFB8CB286EDD1BF7D7AEBC1EDF3FA2C797 +:100C9000FD59D6F565F0FC8888FB2FFBF984C7D099 +:100CA0003F7AAA50A94278FC5BA1B200AFCBC47CCA +:100CB000A0BD28BA0D3F2F2519CF9D585634407C32 +:100CC0005D9A6189E93FAE2CE27216F4516D118E86 +:100CD000EBEA8D7BD5E178CCD541FBEBEE2EE2F251 +:100CE000A9F94DB61AC769FE395BFD5C0CBBFBD692 +:100CF000228B3EDE57693CAFAEDF02B7F0F18DE3E9 +:100D000049CEAA5108E753585F1663BCBB8B1CFA47 +:100D10007877D2FB69BDF3BB3B7A7E7DFB663C896D +:100D2000C8B4EE1AD5DA03F4C31E96A82EDDDDE5AD +:100D3000995B88ED5963A88EE548C5C0E76BFEBD99 +:100D4000F6D11CA9F8D9BFE43E9AE78A3206B58FDE +:100D5000C6BD80A9B1F0FE7341977B8A73864606B3 +:100D6000C09363CDC130DA19BD6D9BCA30EFE7582F +:100D7000F32ADD5F1F17A889B5CF392CE8B4A56227 +:100D800065005344ADE9B30CE736FC3E57DD57141C +:100D9000E52F3BBCDC5FFA64ECB9BDA89A16545849 +:100DA0006C9614B2B77D16306D73D756495E993183 +:100DB0007FFD03332E87E78BD2C0BF8B5A77D1EAF2 +:100DC0009FEE057665C515479A53A0DFCE7C358C1E +:100DD000E3977AE57DD85E14C8A67AF7F5498CECDE +:100DE000BC53E31CE48F98E77D42CC1BE47293ED87 +:100DF00073C8E516939C6C4D1FDF84F31F5FCE22F2 +:100E0000286133BD67CB301F38294F3D817C96E97F +:100E1000658A7332DD5758543EC73CAE6B1AD7B75C +:100E2000E32369F7637CF9B0EEEF977E6E7FFF6C8A +:100E3000D100FEFE29911F68FD8E33665EE4D4CAA0 +:100E400085B1F3030FD7AD40BE3FF51DA3BF7F6A49 +:100E50004B750DEEEF3B25F203A766D60D981FD01C +:100E6000D70972C8310DE5506F7E40D8ED22CE3DD6 +:100E70003F4F89C3E7E0CFC74FCBA37DE86EBC32BD +:100E8000CD733DED4366B1F7C7B2473D0AFA39FA73 +:100E90007EF6297E3505C7D1F7C98E47D1368CF647 +:100EA00075DF1A8B9E478BF9FDE579D3DEBCA695DD +:100EB000F64F0F326E3FD87EB2BF93D7E3D8789DFE +:100EC000615C6AB917F355E727BA48BFB7E1FFA2DB +:100ED000F46A7A919A376D78F438A6F354E5C17DB7 +:100EE000375EF89BA8AF506F75335689F2E6DB4941 +:100EF000F514F79821E066BECE9A26F0CA3C290880 +:100F0000CFF4A2C04CC2E3F39D329DFB2AEEB3ACFA +:100F1000C1F99FCF38026FD3BEFA7249E675798C5A +:100F2000F8E28A2C0FE969DDFEAA9DC6E5A6934585 +:100F3000C63A609DCDCADE841CE8F7EEA3B66C7C91 +:100F4000ED0789CC8EF30E64819C8375947BD5D19B +:100F500003C9473C89C88AFB1E58C862F5D2359937 +:100F60005F350BDEBF881F1F3D371CEDF11F3CC6F0 +:100F7000F355573CB6D2B5226AFC87A709B999C682 +:100F8000E75FA358827206CEE72CE5A5AA64AB4FB3 +:100F90006198473E7F6C09C609C17E1B47ED4FA88B +:100FA0001D96AD3998E77ED7FBF131EC7FC5376FE1 +:100FB000BC8CE85FC0E386B539CF909D9FA7DE81EA +:100FC000F80F177F92386622D9F19B91FE6FB0B06F +:100FD000402C3B6683C0DBD54AFD754867572B4ED6 +:100FE00086FBD5C2654E82FB0F4A2C32DA95F3910F +:100FF000E6319EF3A88DE2CD008F9BF1F9219F9BF6 +:10100000CE892E577E6AC3F69F2659D8E503E8E3BA +:10101000CF0DD7E24F86233FBE8BF41763FEB56238 +:10102000FE3A3F01DCCB695E0AAF1FE98FAEFE5886 +:10103000A87C17E1D496A9AEA6F3103D0B06751E49 +:10104000E2FC1F06A976CFF9FDFA112C46FDD76107 +:10105000C127E6FB3F9CC6FD821BA7F17ACB2B1E66 +:101060003B776836F2F55ABB07F1FA5461E0C7D313 +:10107000A2FDAEBFB21C99292D27FC85E7C0DCF983 +:1010800041A089D89E37D646F8D3CAC5F91E773114 +:101090004F7312BD456DD75A0BF1993BA1A31A8D21 +:1010A000665B61FDB16BF1BD3289F6F347ED7319F3 +:1010B000B08E2C22F2592DB8EF0C6CF9F03A493F62 +:1010C0006F8B5940B6852B6CC2BEFFE031652CF0AA +:1010D000BDA8CF3CFEA2F571AC6B3966E5EDF08B97 +:1010E000D6514D400791517C1EED0F587C8D325EDC +:1010F0009FDC8C7906758DC55709ED9AD03D5E0C45 +:1011000071AD58E764E82ABC77EF15642F7EE2657D +:1011100074AEEC9254CE37756116B466F4F9B7EF3D +:10112000A4B3A09E3FC5FD737EA1671EC4FD6B30B6 +:10113000EF2F6DF8BA7637BC1700BF17E36AC37C90 +:101140003CBF191FB6F9820CFD5D5E1FD9D26861E4 +:101150000FE238D28666F4CF9D22FF11AFD492FF02 +:10116000380CE853C68879C466D8BFA63295E837EC +:10117000B91238231BAF46FF38F712FBD8965C3FF5 +:101180003C09F9E5DC34A35FDC5F7C5DBFE2393705 +:10119000889F2E916FDD01763BAEF7E760B7E37570 +:1011A00017D8ED781FCFA5C62BEE63C3EB1EB0DBBF +:1011B000F18AFBD8F08AFBD8F08AFBD8F03DDCC777 +:1011C0008657DCC746FB0E4BB4D050844F593CC306 +:1011D000FC508B9DD39996EEA03AF75009A37C7EE4 +:1011E00038DDB1B509E375168E272D893F0F27AA83 +:1011F0005FA176C64499D7C5B351B87F709D65A2EB +:101200008CF6539B43A63AFC534D36DA9F7062AE80 +:10121000E56DCCBB308BD527817DF3CBCF6E25F828 +:10122000D72ACC8AF2A109CF0B4579FC2113E71705 +:1012300084253C57AE3991097ABC2EA880CC7E1FFC +:10124000BF45F47A4045BF78BA536FEF55F179ED59 +:101250001A8BE8FFAB20D26FABDE5F3BF404FAAF32 +:10126000EB4CED6EABFEFE686A1FEBFDDEC81A05A7 +:10127000E93D537F9E7A03B62371FAFB7FBC01FBE5 +:10128000135CA8EEEDD413389F13E97A7FB986DAA0 +:10129000BD7573D7ABD8FFC470DE7FCB9E834F6222 +:1012A0009DC95F7BBC6655A338BEB688B1A7932E97 +:1012B000A6AF77A74BC678A86231C443F5F8BBD573 +:1012C000BDFC72DA7FD6E424B91849F7D5A0DEEE6A +:1012D0002F2E1A15AFA7B8E88FA6EBF5CCA6F827E6 +:1012E00070168E5B8DF1401F7D558DDE9FC62CF5EF +:1012F00021AC530F9C4994D18E74A445C5EF840C46 +:1013000018285ED85CCFE38361D54EE777E875FD9A +:101310008E6251D72FE2857A5D83A3F86143DEC0E8 +:101320001C2F64D2CD948F0EAC34C603E7AB9F2F35 +:101330005EB89C85EC9723FD2B16AA8B58EE91DFA7 +:10134000B90CED6836819FCB28BF14ECADEB9769E3 +:101350001819CF9BAA16EDF65BDE7B1BFB079BE201 +:1013600064DC84BFECE6B2772E23D32D81617C6BE5 +:1013700059093F9731EF43DF4B32CA53AFD5C7CD41 +:10138000B4C03751FE06562651DEE4FA3B2CF4DD9C +:101390005ACDCD104E60570A7AEF7A1CE94B725B3A +:1013A0000CEDDC513ABD5DFB38D2FFF464BD1DFF8E +:1013B00004F25B99437F3F8FDA4B558B789EF5841F +:1013C00002AAE458B94EDF2FD7E0F36BC7F48E477B +:1013D000F43DDDADB7AFB9019FB7F58E5747DFFBE1 +:1013E0000D9E6844ED194F203F9755097DA5BDF727 +:1013F000388EDFB25C1F7F7C10EB509759F5F759A0 +:1014000010C7AF63BD6D05F5E25B82FFBB8B3B6B25 +:10141000305E755DEFF34E5AEF72D17EBD587D029E +:10142000F9E95F7E7D7FE7EF99DBD7B3F0CCCB7333 +:10143000FBF8C22CAF7E55CAE5887FF54F91CCD919 +:10144000F2FA27E95C378C07F07C56EAA200D2B7A3 +:101450004BF20167B08037302B565DFCCA123ECE8E +:10146000E962635EACC594170B88FC547FE31C2AC9 +:10147000E5719DB6F2D87EECA4BCF28F8A319EC095 +:10148000CE4A389E470550823DDB98A3FE19EF03F4 +:10149000EB56903DC7980FEF835FACA19D390FC00D +:1014A0008979D8C6D247284E7FA2D06E380744CF5C +:1014B000736E7428241FDFC3BA0E908FCBCA959920 +:1014C00058CF78E308896DA57AB204CA37D8463A6E +:1014D0009E24B92EF29EFA391CF32EB12FC2BC2FD6 +:1014E000E58F62BD9F14B7DB513E6B4C9B59914B0E +:1014F000F23A8CF5C756F706CA033B4BED9447D03A +:10150000F3CF75E2DC6F3DEF3BFDC250AEDFB3F4CD +:10151000B8EEC0F9DFBA35BB03641F7448CC9A71CA +:10152000713EB836A0A5DF85F66F4522ED17A85E9F +:10153000F1328D7F6414A3F87BFCA27ADA1F640376 +:10154000FB50C17A17912FD6F7798FBEF035DA3775 +:10155000AAEAF5E7D29C2128279DADE067D1801C3F +:101560002E7ABEB8CA24EF6B8BF939730CECF87184 +:1015700049F89D81F73DDF3F9D9FEF77B283D7F319 +:10158000179418F3C7EBED3CCED79669A4ABEF4F99 +:10159000E7FEEA83D3453CB1F4C7D508974F98D509 +:1015A000877931F6283F0F0E632CB4DFCA7C0E73A7 +:1015B000D662B2EB1E1D0D4B045BDBB6E62D8A2B0B +:1015C0005A36F3F73E9CCCEAD16FB1D9781B2E1A6C +:1015D000E6FFA7F8D53925583FB6E61DEADFACF19E +:1015E000FAEFFEE237D525BABEE7F19B65DE033D93 +:1015F000B8AFECBF1CC731ED7B0DC8BCBE645DB19C +:10160000ACDB17741E2110AE1DEDC5F4A2C00A9C00 +:10161000379BD829E33C7479132AFD6A0DCA1BA6AF +:10162000C4CE4BEB7CDF62CA4B07BCFCFD43BFB8AA +:10163000AB06FF3D88FEF2109BCA7AF306B795E031 +:10164000BC52F4BC81723BB6FBF4282CC86FD0A30B +:1016500037ACFE6FA0477BED76ED580DCAD52FDA7B +:10166000FC81AEFE9DE8AA92C7CFBE68F32F9AA672 +:10167000ECC3F9FFADBF73D5B4C06BF89DFB2C4A2A +:1016800075024FEEF92CC63C5F4FC90079BE4BC5C1 +:101690001FFE27DE3070BCC15AFACF196FB0E39E2F +:1016A000AA3CE2A3CB4A918F8A391FFDABCB3D58B0 +:1016B0006F6E29F14367307ECC5FDFDF4F2F52CB57 +:1016C0004B490FAAD63D403FF795B9B83D13E2F01C +:1016D000ED8B67C0FCFD8678C613ABFF06F10C5896 +:1016E000EF02C26F85F8FE171F7F37137C156E4F10 +:1016F000FC0BD2671BADAF93AFEF1FF0FDCD442FB6 +:10170000CF727AE9830FB793A2E073C3EA7F0C7CB0 +:101710009E25F8ECE0F3FB02E0730FC1D3C7E77B33 +:1017200029FFFAAD629E0F81F75EA675E6723A78E0 +:101730005BD8D7E077CFB85CEEF3BBB7E42BBF2E16 +:10174000E579E4C3A586FA4F258CED01FCE2EED2E3 +:10175000D87EF19B38DF2F9A5FEC2EE170EBCBBB8C +:1017600004F979B7ACFAEA2BE13BEF00BC31DED6E5 +:10177000BE4622FBE27C1AA3F300747BE34412AF63 +:10178000DFBB787F584508E7ED2CE4E78CE8E703FA +:10179000D8A4E54343F2C5707D7588ECC07D482B25 +:1017A000144B0B9E133843FB88F69F391427FD3BDF +:1017B0005BA3BD3EFB1DE847839FFB25ACBF5CEDF3 +:1017C000A1FD27FA3E337DFFC78A50EA01DC77DBB3 +:1017D0000EF4900ADF995F61DC0F62B6376CA6B633 +:1017E000F9DF314D9E6E3C8F0AE04FF6CFF9365E41 +:1017F0001FD76E637BB0FE43DD2005C164624F6B73 +:10180000163A877325C0C90AED191D19544FEE48C1 +:10181000E3E79DE9FFCE29D041079DE7744C62784C +:101820009F897D65FAF9DE7173F9B97A11583F9E87 +:10183000DFA39F335125E8448767DCFDC90497F394 +:1018400000178671663FB747E7ADE1F9E096E537E7 +:1018500086918D6A8A3F5A17AB2E65B1D7784EBAFA +:10186000399E613E67DCC60243F1FC8AF9C5651A00 +:10187000DAAB4E51AF19CF143AD722A23DC5CFB53E +:10188000A8B01BCE11317F37DE44A74E53DCC14CCC +:10189000A766BCCC32E1E5691B3FC7B1A55BF26925 +:1018A00070BB65D3CA36DCA7AF6DB2F2BA79A6D0E9 +:1018B000B94F2D60F1D27E74982CC6EB970878EA68 +:1018C00078C183BCEE49413921F6A55BEBEFC5FD3C +:1018D000A54BC5BEF4EB5827ED33B89E45ECE80C9C +:1018E000DC80217209E3DDB2833B071E86F3A8ABDF +:1018F000E6E76458710D9827D864257E6DF1EEA156 +:101900007FEF2B34C29E743A8BFB13B1ECD9DEB857 +:101910000240E274541CFF7FE257FFB5F8555E09A0 +:101920003F8FAA252EE429CCE0E74DE03E87BC128C +:10193000599C37218FEA003E397CDF071ACA617D46 +:10194000BF03FCACBDCC788EC2E6E903F87FC525A9 +:101950008C7F2723928E7595EF8873FBCCF8FD253D +:101960003A0E5C0F3D399DF2EF60FFE6A2DCE3F634 +:10197000EFEC82C053D3A91E9DEF7BD6E34827FD31 +:10198000EA0FF17E09FEBB39B9B43F2788FB77E641 +:101990002758F65BE4BEEF33731DFB7FD3BCD5ED58 +:1019A000C51C1EE1385EDF1ACE60D5CFC5C0C74367 +:1019B000E55C1F86B363E34B7F0E76C6EB882FF49E +:1019C000878670A238E330C6078E0F441F3A1E93F5 +:1019D000672AEF10DEF57AF002F524B69BD5C0DB5E +:1019E000747EDB06496E44FD1A925FC5FDF5F3BEB9 +:1019F0002579108E7FEB3CDCBAE28C41E5E1962143 +:101A00009DE5F52FBFFED2EBFF0742E7FBCB008041 +:101A1000000000001F8B080000000000000BED7D9F +:101A20000B7855D595F03EF79CFBC8931B08F42224 +:101A3000014F0268D4602FEF04089E9B9B272470FF +:101A400041C0280F4F08626CD1466514289D9C90B8 +:101A5000104244C119ABAD75F4120CFE7FC7AFA69E +:101A6000FDAD15E9E38268A9851A6DA8B1551A90F4 +:101A70005AFA8F9DC10A63EBE8386BADBDCFBDE765 +:101A8000DCDCCBCBD8A1DF4CF8F4649FFD5A7BEDB6 +:101A9000B5D65EAF7D72D4C9189B01FF1993EBB424 +:101AA00002C63AB07C19C31F8D4179E9504B390702 +:101AB0009AF6F2F65768FF1636C63156CF447FD1F4 +:101AC000FE37126F7F34302C6CA4337693A887B224 +:101AD0008E65B33F634A6E4081FE0D9259DEA9299F +:101AE000D6F932776A30DF09A77DFC6562BC42ED2A +:101AF000131A3F149DFF93B006E5FE38F897335E46 +:101B00002ED5FE42EDEB9859FF171DD77B5C32CBEB +:101B1000E375EC7FC46596C7D6E1FC0FE4F2F1678C +:101B2000978C0F1B97203C9FF7F817DAFEED592A88 +:101B300063C3011F0DDF0D7E017E5DD6B853D6A1B4 +:101B4000DF5167E86D960D64F6A0A476419F42D6FA +:101B50002D3399C076C95360084D621D30D7AA1243 +:101B6000F8DF54C063BA83CF63F8C31AD0D9D2D98F +:101B7000269DD68671DE6474F79B7D773C8EEB8E56 +:101B8000C26DDCB1C206B731BE4E9B15833BB81F98 +:101B9000DAC3784BEFB8CD87702ECD33D73783E6D5 +:101BA00069CB32FBF59F75DE57F79512BE9746E776 +:101BB000A9A2F64B53CDF1168471DE183E97D07E64 +:101BC000C4E01A6DC3A7BF6409E133E40D6F1E01C1 +:101BD000F809F998DF007CDED4D02CEB05163E32F4 +:101BE000822AF1912F5A0EDBF9A880F868B0E11A29 +:101BF0003D23B455837D62F9DD6A68C2E7B1EE88A2 +:101C0000F30BB8EE6D12ADDBA4A3655E0BBD7B607C +:101C1000DDAA59BEB2AE217D30E6ED29A379DF03FE +:101C20007CB3183F3163649D967EE1E3B5A4E7B9C8 +:101C300070BF566A921686FE9FE2CF75B1E7DBB39E +:101C400024E217C0E7FF237C16023E33F03D233E1B +:101C5000786672E8071AD4335577EC07B85C9A8730 +:101C600075000EAAA687F6507BB6C387F8070068F2 +:101C70009CB6D798827C06BCE577CC84B293D576A7 +:101C8000170C9CF7E11207B56F61ACB21BE09AB27A +:101C900029B43A6469E72DE370658AE7918CFEE523 +:101CA000C361FE77A06A138CDFB20D98179EC71A26 +:101CB000A4B0044D8EE578E715427D4FAEC3BF0951 +:101CC000A6EF59EF1EBD16CA7DB9E97E84AE2F6B13 +:101CD000478617E639E697059DDE761CF9FA4846F1 +:101CE000949F0C3C5F7A245EFE9556D489FCF4A642 +:101CF000CACBDF2AFDF271A300E98D79D908C003B0 +:101D0000F6005E75A4CDF2B8010E57398813ECEBDE +:101D100065BA0BEADD580F4B5CB079D7D7AFA7D1C6 +:101D20006B5F1E378DB15AFC5DC5FE8AD1EFA1797C +:101D3000954F257A32E7B4D8B8AED696975A108F19 +:101D40003E9995206FF9787B1FEB6FFED481E343BA +:101D5000399F2109EEFB14F65C1265FCF914969884 +:101D6000CE4295B908573EF377C07C0B74E789687B +:101D70003D7F6C53A60938111E79636521FC9ADA00 +:101D8000606F37371FCA9E58794E6B7D0903BCCEF2 +:101D9000D1A0DB44C60EB5D647EA619E43856EAF3F +:101DA000049876E528B6F67359772BE29DA9070FBC +:101DB000C880971562BE16EF82B7719C95F95002E4 +:101DC000F88F7C359031351BF94DF63B441B8789E4 +:101DD0000F46ED9C8E6C92D37EDCEF9617CC7D9BEC +:101DE000DE897C20A749B672C065D64FE8443E3CE8 +:101DF0001295ABE3566279F158936F323A91AFAED8 +:101E00004B33CBAE95C847EF284E4127C33B914E8D +:101E1000DACDF18CED245FDE6066BD83EA4351F9D3 +:101E200057BE13CB4BBC021EE31F481EB668FC3CDA +:101E3000B96A5FA4DFB888F6C09F570690DF425C9E +:101E4000DEC5D7CFE80DB76422BD007EC6AB03F96F +:101E50006D4340263E0A69EFCBC837A58D8033D845 +:101E6000BF60ADD43B15695C61A391EFDB9A60ED77 +:101E7000E3A1FC62914BCD40B91E2AD712C88D1F39 +:101E80000438FFCE08A467BF8BB89BCC2623DDB5F2 +:101E900035AD13FD530CDCDFFA71AE704A6EF27192 +:101EA0005E0D3A48CEF448DE45FC7C96199ECF8103 +:101EB00007C7A617B158BBA783FC5C6E9EAC550440 +:101EC00060DE79207E19EC61F3EC47432530CF8941 +:101ED00022A7DF8DEB30B4D791CF160A1ADAEED2F3 +:101EE000D87A941B456EEF2694DD72C14BEBA0AC03 +:101EF0008C027EC57225A76F1DFE7D9A87E32A316D +:101F0000FA073816ACB3F383C22CF40DF53705325B +:101F1000B2DFBD060A57B3AB71FDF739432B508EC4 +:101F2000B5E785EEB0CAB3A7825C8E85C57AF7CFD8 +:101F3000FE762DE2E703E6F0A3FCD89D1A2279F69F +:101F4000BB4CC63A27E23E32D53B02F99AAF43CAB0 +:101F50005FC2B0FD6397C31246021CEB7ED3533AB7 +:101F600019DE7F83F73B792D6B64F85EE1657818A5 +:101F7000C6446C7794DADD1BC8A379D9E37E8F075A +:101F8000691F9AE37EA7B36E273E1D693F1CAD27EC +:101F900090D3E693AD71BE17C503F2129C84B86E60 +:101FA00089E98E4F71FD42FE039D6EC4FD01A94F6C +:101FB000E7C88C93A76CF43629A0121CF17407FDB6 +:101FC0005AA8DF22B31F73EA167D7D43E09170F3B8 +:101FD000383A8FB652BB74388FB26DE7D17D810429 +:101FE000E7D19555DAFDFC3D2F43FF0793F4FFC77A +:101FF00044FDA1FDC3F4DEA313BEAAA66B8F6079D6 +:10200000CA18539E4043109CD70D33CBA93737E4F1 +:1020100058E5CFD427505EDCA84BA23EFF09E4EF81 +:102020002325A6BCF9D90AAC8FCA23B6F809945F58 +:102030005179C4E6DE8CF551F9C3EA1F47F91595CD +:102040003F2CF804CA8FC002598C77EC711CBF6D0D +:102050009939FE15E100EA250EB33F0BE3F8C9F408 +:10206000C8DE59DD2BF09CBB295ADFFDB866B133C1 +:102070007E354B7F02CF45B66D387BC7E483BC818C +:10208000FC6ECA01937E4CFDF0D517C3BA01ED1664 +:10209000566A11EBBE44F5CC7EAEF7C4F4CBDF73C9 +:1020A000FD7BF0F5C7D768FE024E6F9FC3F86F5BEC +:1020B000C737F52978DF4FF427DE5F6AF61CC07753 +:1020C0009AE09BC2E1BB88FE1FD3BAFDFC9CFA2BB1 +:1020D000C09B5A62B1032E417C8EB9C4E19B5482ED +:1020E000FB5DCDF7FB698D99727C2AC13D800ECED8 +:1020F0009BFE8B69DC52BE6ECBB89A75BE64F63A15 +:10210000B42BB3B78BF24F25C125C63D4BFF1A7BCD +:10211000BB68FF5089853E0781CF6FB2EEEFE720A5 +:102120004756D3F8E3F8F8D7C7F0789BF5FDFFFAE8 +:10213000CDCE49E7DB899E1A393D9D87BEFD75C42A +:10214000EF56A95BCF243F9161E2FD1B380EBCEF37 +:1021500077C1FB88D88F5D45A16FE17B2CFA2659AA +:10216000EC1363E14E842F669FC04005D6F3FE86D4 +:102170009DD6F3FE7B2537ED34804EE4206FFFD4EF +:10218000FE97EB70FDF165D04BFE2FED7F36E82515 +:1021900013482FF936CE7FAE7101FE6EC2C3F39C99 +:1021A0006E12D43F4BE33ECDEBDB5D5C8F7D63D99C +:1021B00007A4C76977AA0ED4E3CC73FD27255C9FDB +:1021C000057DA432917FE127C29F06E3FE84E6ED00 +:1021D000E6F8EF0DC919A86F46F51616213B28A69B +:1021E00057AD223A8AE955B75279B6D8E7D74BBEF0 +:1021F0005427E07D85E341ACE7DCED7B080E1F6FE3 +:102200009FA0BE97C6CBE170B2F48327D06E257A2B +:10221000E53FE31C505E89BFA900BF73717136E8CA +:102220002DFB5B255586725DBBB9CF77135FC4F478 +:1022300036CE87370ABAFF53C906DAC71B4F9BFC55 +:10224000BF97DA4F89DAA91B08FE37857FE26BC199 +:102250000D267C27093E95C3F7398C7F9AF0C33849 +:102260007E6A99E144BD0CEDCA2E36707F3F167E22 +:102270001CE8F71FD4CFC3E1AAD525D2DF43AB8E2C +:102280003991DE57F4B284FE2739E832FBCB41D2D4 +:10229000CB857DEBE77EA1F8F629C1283DA5507BD3 +:1022A0002F9FEFAB45A1B420BC9FA5BF161CC1F763 +:1022B000C983FA68A8540A77E4A27D935E560AE5BA +:1022C000050ED64F761F639BD1EFEBFEA1C23AFC01 +:1022D000D45A552C7E1DE0D25FA11DB9586CFA026C +:1022E00016F5AF38D05F63F1DF901DE80EDE9BFF7F +:1022F000904A7E97975AD04FE693C9AE08DCBF2A22 +:10230000520FE5D442B7D78DF3C83964E7BAEE036C +:10231000FB1365D4226E5F3AE01FEAD1A9EB18D90E +:102320006FF30C29ACC23C6ECDEE7FD1379E6A2193 +:10233000FB6E15F36A59F02CB4D7BBE2ECD7E6C9B3 +:10234000BA1FF174BCBDDE81F80854713BEC78FB18 +:10235000D874E4BF783BFA78723BDA40BBB92766A1 +:10236000473BD70EA21D1D0CDAEDE8D145A132DCAA +:102370004FA66824DFF6CF9EB190EC6543666E6889 +:10238000DFFF909289FE3E639BE24777C331A7B699 +:1023900082FC07604FCB63689B18FAB7E60BF8FB2B +:1023A0008B4E9522FCDADD63FC48EFFDCD6EC273E7 +:1023B000FF2D59E134182FD3F8B03505EA5F0E8FA1 +:1023C00042275BD4BE8EB7C3C17C32906EFAD96807 +:1023D000D681FBA078D97A7C3666FA0D7FCCDE9E5A +:1023E0009FEF3570BCFA701AC37D8FFC8C49EFE605 +:1023F000330A39201D2F60AA130BD733CD89F85F1C +:10240000CC742ADF00FC268DC5F9F20DA203E03B57 +:10241000F4DF6D98ACDF46F8788CD3077B40D98920 +:10242000F18AFE6D0F66209FED4EB5FB1BCCE75A7F +:10243000E16FF0A09D3F6150EDFCF5048F9013E734 +:1024400021579AF87E727E3D8DF6EF703A271B90E9 +:10245000CF7B841FF8812CEE3F7928C8E54AFC1316 +:10246000183E1BFB5FE83901E7E5F6A0DD8EDF8152 +:10247000E5F3382F1F2639F32C5F675B9099F2E75D +:102480009B41AE07A899E44F01513C8DEF2FFE7C94 +:1024900024E94FE0F8DAD312ED578ACA480EB95949 +:1024A00028C289C910EB611B47D8FBED3E5BBF9B7F +:1024B000037CFE1385FA3FE3FCC5A78042A19DBBC8 +:1024C0005A0A4BD06E7EBAF492A4C6DA1D413F542C +:1024D00002397A54C85168167180BEB23D13F600B5 +:1024E000FDDB8A7F08CAEB379AB4A3A8C31D69AA8B +:1024F000A4679FD248F2A3AF5D0E37C33CBF6862AA +:102500003DA5E3078E5BBB2C70F484451ECD2F7B6D +:10251000D2034291B5E4771E94D05FAFB955E4DFA2 +:102520009E0CEF0385C8AFAFC9AC0BE05DB2A8EA63 +:10253000E8098B7C881F17E66306B0EC1B41EEC7E9 +:102540007C31E08E5C07F0ACDA268571BC55DB8E01 +:1025500039D15FB9625D1DD3619F5C85C714DCCF43 +:10256000F28097D639BF50668605AE6F4ED37A8219 +:10257000DCBFF33AEDAF3FAA47FD12CB01A796E9C6 +:102580002D88F921CDB8C0D3C15DA48FF664319AEE +:102590003FE463848FA096EBEAC7388BCF4B7ED3A2 +:1025A000434195E6AD6BDD49F0A4CE7A9FE001DDB5 +:1025B00039E2183A10DF261FBC26F0DE26F09E0C0A +:1025C000CF7F0A727F9E599E5FA664209E5F5754FC +:1025D0008A7324E3EF85A5F6FD71FB2A6DE516ED00 +:1025E0006E07D2D3F15639EC96E87918F7ED34EC52 +:1025F0001BFAE9CD717A3258ADF57C36F76756A9EA +:102600004C7099FBB3C2E0FBB3C208105E569456FF +:10261000B946F2B85A37D036AB2FAC6388179776E5 +:102620004C4139966CBF80DFDCA516FDF122FCE73A +:10263000434A2D7AEDE7EDDF87F946D37C717AF6D0 +:102640005F2BBE60D2532FCAD582985C2D2BE5E755 +:1026500041FCD394AB167D92FC9A163856365C0436 +:102660001C269F209F3643D3E00EC9897C12427EF0 +:102670009D80FAD91F367F211BF98675A7C0308E41 +:1026800052CE37AE59592EA48BBAF6F7153CAF008F +:102690009F15844F2187279632F31C9A4374D1C02B +:1026A000E9E2BF3BAE03F02C23389771382FB5B861 +:1026B000D3ED35A146842FA4815C4A477FBC57ECFB +:1026C0003F1BCDFDDE1716DF3CD67A37433D70C188 +:1026D0001F3354D4036F2AEAD272D584F14D55B218 +:1026E000C537EB4B488FD1182B19C9CE19DF8C8F0A +:1026F0009F0E8C771A142F35F5EEF878677C5C9373 +:1027000025897F0E8C77BE588D7AE61CBFEC55D597 +:10271000583CD335EBDDB7D8B503E39D9FC07A04B1 +:102720003EB39965BD7DA3D5EE08C0D731D2E3EFA6 +:10273000E4CD993C2D864738073C6E98A7B50CE050 +:10274000477D39B793E2C6163CBA080F1788478A07 +:102750006F235E5AA5F026DC07A5D140795EC7BC81 +:10276000EAA3DED87E46C7CBBF47F341FD57EBD384 +:10277000990310B239FB2E5607E5D443294C063D88 +:10278000F6907A17EDF7A1F732548CF7BA7D967D63 +:1027900010B8544CF8E48176D25F611F3D7989F618 +:1027A00051ED2CC573F67CF76F5751E808CA150F29 +:1027B0009CD7CAA4D8FBBED11C9FEF5CC5C29DD2DA +:1027C000C07D047C6B6477E6B39D846FD6C8D03F30 +:1027D000D02A31F551FF40BA70A46D341C682FAE79 +:1027E0004C273BAAA5B191F0FD1AE0DBF072FEC2C6 +:1027F00038D559F8CBA40B268D387FBA88DF778C73 +:10280000E3AFCBBEA4F735097FEEBAA07D9D3B5365 +:102810001B5236DCBACF5A56D9542BDF1A222FC599 +:10282000A07D341631D69535508FBA4CE4A5C078CA +:1028300023B1FFA83226FC80DA282C5F7F396B4C4D +:1028400094F7E2ACE076CC3250C1C9AF62A4B2AE2C +:10285000296865ED787B04EE9771958A65A61E0C54 +:10286000235DD589F51FD9B2B30FDBCF074C621EAC +:1028700004BE7558F0E32FCBA5718BD61C3BAC5230 +:10288000B5F7288EE702E18F76EA327C89E382BED3 +:102890008AF175A6E86C21C8FBE56BA5B771DC5A17 +:1028A000238DA15D1BCBAB782A2EAF8297E7E788FB +:1028B0007AE3FB74FEC4E298FBE2CEB7373A6D715F +:1028C0004CE3D84A7B1C93E7DB98E7D99197FE65E8 +:1028D000A5A158E398EFD3F8479799F315EEB2C73F +:1028E000313FA1F14D3F35631F765AE3946049D1E2 +:1028F000F96AFA91FF5C36BD9EFB4DF585B83F72D3 +:10290000506A44FD080E184D227F8DB713ED69D033 +:10291000FFAFC7FABFF575821E727B9925FEF1B72E +:1029200006FF31D3BF6F1C5AA9155CFAF002BEBF77 +:1029300045F8AEE4F8FE1B80F7BB6509E20097108E +:102940007C2F117CD138C47F3B3C6F9459ECCFCFA6 +:102950007BBE1933B51338DFE7B08E536596FC8321 +:10296000F368FFEFD45EC44BE3EB6F2FF7723F9633 +:102970008813BF198DE365D6C7C5F528EE158B23DF +:102980005E3E3630CE0AFFE5BBB0BD19479C5D9E6A +:102990005B4F79D149E2981AD62BD6FE2AF5EF88FB +:1029A0009BCF25EA17955F536FD8F07335B5EF8944 +:1029B0006B5F2BD6B7B27CD22EC3820FB038A97D05 +:1029C000542EB1E9F5F6B8E3D47A6BDC714DF9F425 +:1029D0005D66FCBF1CF1336E403EC4FF487C04CAF8 +:1029E00085BD29E2E5261D8E9EA195944FBDF4E09C +:1029F00085FD5B526EA1FFBFC27CABCA2D79171754 +:102A0000DA3FCA8FE2DC37F32700BF77E03A6EAFD8 +:102A10005009FFF1F912A69D18EA676427CE646198 +:102A200019E31221BFCED00F1AE56B43AB277F5DB0 +:102A3000F47E44E52EFBFD88E65DA85FC4CEEFE79B +:102A4000EAED790EE536B8B7BFFC9CB9EE96724B4D +:102A50003EC3608FBFA6C28E976859E067E91DDF4D +:102A60001C6DBF7F11DA45718CE8FD8B9B68DE58C9 +:102A70007EC7ADBBECF91D6BA91CDBAFA6B8FDFA98 +:102A80009A0DAE8FCB9B082E97C87B73AD9292DCCC +:102A9000AFB891E48219D785B24D2E50F97380EB0F +:102AA000804947824FA3700EC8CFABDB857EA6C19D +:102AB0009EDF22175E42BA187CBCF3FB1D26DE9314 +:102AC000DDEFB85135CB5FA96F28F8ECF362FE5FFC +:102AD00079C2FCA38B5D07BF2FE28ABF2FC2D6D776 +:102AE000DBE5CF79C3773AB1FC39BFFE9F24973F2E +:102AF000FF89F2A725DDE1423CEB3EA68513D8C74E +:102B0000B757F0B854943FC57D94EBB727B6A7BF2D +:102B10005CC1FDD7A6BF3BE03AB5CA1A071D26EA3D +:102B2000BD15D1BC016F058EBB8EC33706E521C62E +:102B30007B98C234E0A945D78FCE41F85A7ECDC7E5 +:102B4000633EB0933362E3CD14E399F3EC5B9051B1 +:102B50006BCD6BC811F38CA9904CFFF4980AC4E7B5 +:102B600046BE0E79C81ABAE715B5AB8D87487EB553 +:102B7000394D3BFBB15D24CFA272E89B44178BDD3E +:102B800026FD877759FDC6653FDDC5CF5528621CF8 +:102B90002FD6EF1BF564E79DA3DF6413CFAD62BFB3 +:102BA0008CE87E4D41B8CFD5DF624747A4EC981D35 +:102BB000FDCC646D16E219ECE9E2F31907F014A4F8 +:102BC0007D596BB7472CF51515B6BCA4536B30AEC9 +:102BD000992C2F6961C5D9F39216C6E86161854DBC +:102BE000AF0F664C453FC94847C27B14BAD8D75887 +:102BF0007ED77768BFDA4CBE13E507B278FDF29F47 +:102C00003E532FE0BFB9C212BF30E32DACE06004E9 +:102C1000FD3C96FC22CD61F5FB048F3971BC15ADEE +:102C2000D2F9F14BBB187F5B741F6FAFE0FE681DDC +:102C3000FD8E378A498EDCDA4CE3D6AEE2F7C2E28B +:102C4000F9E65EE1A7BA3746C7F7D2385A34DF66ED +:102C50003DE20D5306DC9362E39BF77B02CED08FFF +:102C600030AED366482ACA577D5D1DC51559256308 +:102C7000E3619F0223F3B6A1E830E7BBBC92EF17F4 +:102C8000FC5A8AED7C20218D9198275E4771E76977 +:102C90001ACF5B995EDD2C0F5729AFA503E72F5A9A +:102CA000B4B305977DC3B2EFCA89F2597A309F0554 +:102CB0006132D8EBE346007F0BF8F05EC85A98E724 +:102CC000CD683E4B75D93DD67C96D067CB6731FD3C +:102CD0007F4B4B00AF16FACBAAE478CDAAE4788DEF +:102CE000C58119C56FAF60B573AEC2BC14BCB70562 +:102CF000AF7B0C7ECFED4C0E0B63FCBF79762AF9CF +:102D0000F1FAB318C5556143326BA6611E09FF493C +:102D1000195FCA30CFC50DEBC275605C3672250CE9 +:102D20002F2F1B124940CFBFC8D4993F1DFDFEC6AF +:102D300066067413D41FA4F8DCE5ABDE6FC07957C8 +:102D4000E86E1549E0C6066F19E571ADF13BEF81FC +:102D5000F7F37D32D3D09F5DED3CCEE3341EC2D37A +:102D6000FC525E36F1E266CA712B5E94B8F2BAB7D5 +:102D70009AB71CB0B477455232302EF85285C80746 +:102D800012F78A989C4E7470C6E708631CAA4761C4 +:102D9000FB158C63E832C515BB5AEF3C8C7CBBC27B +:102DA000A7F81DB0CEE03A89F2BF6EF4723C7DD830 +:102DB000646C39003A6CCAC83C8AC39CF17AC81B5F +:102DC000DFB6AC8BFCF6402F3D0AB43FB69EE7174A +:102DD00099F94F0B04BD98784CA9FB80F07206E37B +:102DE000E18897C22CCA839A07F850BD14E76F4553 +:102DF0003CA5B2C6C830186789CFC122163F34AC93 +:102E0000DF9647066353DE99426F6CF5849FD4F5D5 +:102E1000419E8F26576BE89F3F53C8F715CA7EA483 +:102E20007756CAE9D4C47F6A1C9DBAE3F2C3E2E9CB +:102E3000341EFFA711EF96FB5C5D0AF34790DE7A24 +:102E400065D22FA279570F3928EF8AB130DD63EAB6 +:102E50006243FD1D28372312C5096E107833F1CE69 +:102E600058E3E695E8E76ECCF4A3FF9F391A376381 +:102E70007ED48DE134CABFBB8975531ED472B49021 +:102E800061DE9B99D785E595CC4F4F8915D0FD9292 +:102E900025BA447CA1B348CD5580BFC865CE2C6B04 +:102EA0005E55D2BC2658F9BB9678C4D04A212F3D36 +:102EB000BA8FE779EAE2DE8F46F9415965A51E3DF2 +:102EC000C1B931BB481F5969C9BB50BC8D8CE2D315 +:102ED00045A151955363FD9F9AACE554C2F85F2C10 +:102EE000D446E37337EA79701E040F8E7F12CF83C6 +:102EF000E6C99A8AEDE3E5D5B1E4F9771AF2751FD0 +:102F0000CA2BCA232C203E1CACFCBBC99503F2EF94 +:102F1000A6565AF2EF8E3AF9BD32CA459EC906DE70 +:102F20004F5B7703D59BF7D3E2EFA5B1C7781916AE +:102F30006474801C6F311A69DD26DEE3F1C3C4BD01 +:102F4000B4A5BE97FBA46B07216FCD0BCADDC8B338 +:102F5000D187C1EF2FD7DCD987F13A83299447D89D +:102F600096CBEF2FCFC385E23AC6717D9055F1F332 +:102F70006A4B56A3CF0FF55B9C3C1F86E5EBECFA42 +:102F8000099671AB64332EB402F1097A1FE94BA69E +:102F9000BE6AB6AB17E7C26A712E3C3339740BE1D7 +:102FA0003F96DFBD1AE988A547C20E336EC77F285A +:102FB0000E64EA0F474635523E8D3BC97DEF3B2BF1 +:102FC000A3E7F99D34FE43E679AEDD85E35F37CCB8 +:102FD000BB08F9CC159459279E63F36F27B9FB1CE6 +:102FE000E68D824E335D6F0E8E80FD6EAA14F1A6C3 +:102FF000862C4417EBD1783E69A4B8D187E7DD96DB +:103000009189EF7DBF2AD63965CC2919C7DD028A9F +:10301000CEA689883F83F2D88CC5204BA00CE6FE53 +:10302000018CCB78500F28C27391B7F736401BD86C +:10303000876EA12F04AE00FA41FD6BBC3D1FC97C19 +:103040009AEDE2F3AD409467E0BAE3F3DCCC7CABFD +:103050003EC5C8F027807F7ED95A0FE56BE5ACF4FA +:10306000E039D9A60569BCF8BCB72D396C34C21556 +:103070009FD766E64D99F952E6B8FFA7D29ED7E6EC +:10308000F6F1730B9E9427F39D4A957F9742B3E721 +:10309000B799F935D89EF26B7218CFAFF13532EC93 +:1030A000E78632B60F89FCB3F8BC2A9043DFC57DB2 +:1030B000BF50BDA92DA6376DAE1B44BDE93CE4EF62 +:1030C000CF10DE04F2F7E7C41F31F97B08E91BE4F7 +:1030D000EF617C9AF2E5CF959B48BE6C91387D6E8E +:1030E00081FDF85E8279FA049F6CC94A4C57A704A7 +:1030F0001D374F0EFD1AE7D5B2F9BD8F4B058F80F6 +:103100008F3F5AE537E0E35F13E1017E5A519E5845 +:10311000F24FFF9DD69324FF34BEFFC5DE1F5640FD +:103120009EF0EF4B685215D989AAB0F751A8602BD1 +:10313000F31E6E9C1C17F5E792E3BD0E90AF000FD7 +:10314000EA0A56B93FAC8AEFEB3533F56155442FA7 +:10315000FC1EF0D600BF07CC221AE9034732F45A0E +:10316000E45F963FE91CE746B3C8B3D51B4224FF92 +:10317000179EA3FD266A7FCD4C55F8C187D27AB63B +:103180004ADA3752E558F95CEB4BABD2F2ABD0EFF1 +:10319000A187E83B0A5BF21DAA014BBB6FBA7E2DEB +:1031A000BEDF92BF89F6AF03084E02793ACF71EACB +:1031B000FE3C89F2849F9786C0D303965C02BA9E38 +:1031C00029F0033A08D5B3B7349FD5FFB1BA2AEA3C +:1031D0006F11F6EFB79FB4E6092CFED9D3AB0CCB39 +:1031E000F9867E94EF25A08BB22ACE3FB2FB4EDB50 +:1031F000F919DFAEA28ADF0F595225E206E23C5CE4 +:10320000ECE6F6153B04F059CEDB6B6696CCC5F5C3 +:10321000039A0CC9724E9AE722D558DEBB7DFC5E3C +:103220000AEBB58F63AEF35641A7E6BC40AF3770EB +:103230007AD56AF169D62F9619F783F4D8F105F09B +:103240002CE774C64E2481E7C984F0F4D9E1B9357E +:103250004AB7DAADB83E38AF1B70DCF612A0BB043B +:10326000F89D30B5640DD62BCC68CFCB3DAB3CBDC3 +:10327000BB2AB13CFDBB2ABB3E7B4F1597A7F75637 +:10328000911C493CEF2681B741FBAEC079EA6DF74E +:10329000E1AF09F8A6A3FFD9B46B81D5DC6EE36E6C +:1032A000E2CF8249E7E02FCECF378F69243BFB473F +:1032B000423FF99193299877033CE64F940FF462CB +:1032C00095A98F8447215E5E48A28F44DB25C9BB48 +:1032D000BF92ED48BB18BDA463D69134D24B4E7754 +:1032E000A6E1F9FFC28992847AC98F72768C4AA4CA +:1032F00097EC49A297EC15FAEB8BBF73919E517C2A +:1033000092EB25C52777C8A85FECABE272BBE84417 +:103310008FAC03DCC5A897C0387B845E82ED492F53 +:1033200039BD4346B88A4EF650BF6228A35E529418 +:10333000442F012864C4C3F3C51DBFC4FD8B5F6F58 +:10334000F514FD152BDD16F6F790FFC7ECD791BFEE +:10335000294DA7FDB6D3CFEC22D596375FD8CFE95C +:103360003DBE5D323A2B93ABDBFB615D5B59C60E14 +:10337000CAD7541A9FC0B2612894C7851FDE40BACD +:10338000B9773EC09085ED1A9FEAC7F3C5707BF10F +:10339000BB071FA6AEE076D05AE675CE8CC9235A7D +:1033A0003A80669488F15C1E6F0BD8798FA4651201 +:1033B0001ED7794D7FCF8ECA3CE87FEF95E3E85E5C +:1033C00050C98330109467F6CA546FFA870E8F6421 +:1033D00094BF0FFC3BAF06C69F2EC687F34EBB1BA8 +:1033E000DA2F2E747BD1EE2E97D3A9FD7DF9BCFD8B +:1033F0004CE35403968BFA5D2ADE3F63F246F90EE6 +:10340000F4EBA25E02EDEFFB61A8CC03F5A9470047 +:10341000121CEF2D17F93734F887FC3BB5B79BF03A +:103420009976C265F37BA482848B58F417575C9914 +:10343000C9CB8624924FE633DE4F913247F829AE4E +:10344000655FFC14F4AD336C633BAED13DBEE4C5A7 +:103450005D6C607FD30FF12F53B42173601FC739A8 +:1034600075B26BF65402AE619FF63CF4D0DC6B1182 +:10347000EF3B14F2FB1EDD9046FBB4F7416527FAE3 +:103480009B8E029F72FFEEFA5B905EF76630334EC2 +:103490001441BFDDDEE87DE7E1B76896F2D8572634 +:1034A000FE0ECFC3BDC3CDF60FF3FE66D9D8760BA3 +:1034B000E675EC1DC9CB35AF3CD365101DF72B6409 +:1034C00077AF7B273D91FCCC9FCBF9CE2CCF2BBC8B +:1034D00093D3F139FA81BC9F382741BF941A6E7F8C +:1034E000ED5D06204D443CE9D3E6009FECE9BBAB23 +:1034F0007D024C3565D6861E92A3C3FAD72692FB71 +:103500006573F8F914290E933D06363EB787997214 +:1035100000F35BE7317512DAFDDB67BFF0F36B6137 +:103520009E5F148D9F2427E06B7D4E5EDCBA5E9318 +:1035300057A25C7AEFF8A24472606B953ED7BE1E2C +:103540001E3F6DD9A110FEBF3CF7F49398F71E29DA +:10355000DE41FEBD3D7F74B04D406F7B2670FD1F88 +:103560006FF0C9D98302DF43D313D01DC077732214 +:10357000F8AE9ACB689CEA295A1DD6C7C3ABA21FE6 +:103580001CE00535CB8F7224E50FFFD083FECE3DC6 +:10359000FD0E72BA9C39D129230976F4E595A2DA99 +:1035A0007A5DF5311949AAD8FBE0660C0DEB1B6575 +:1035B0001BFF4DEF4BB59597370EB39597368C8A19 +:1035C000F123C37B42636D65B7EF6A5B39C026DBCD +:1035D000CA8BAA67DAC62BF3066DE50ADF5C5BFBD4 +:1035E0002AF57A5B796EFE525BFB1A7FBDAD3E54C5 +:1035F0003051C12B7E40975B115F69BD1AF1F9967E +:10360000BEBBBC481791E210D9DB47327A72D09F1B +:103610007D38C977E77E394716E73BA8462827E17A +:103620003CDF94156B1FC8EBB7F9EB5F98C3F5D47B +:10363000EFCF89F7D727BB27C7CFE7F3BD1F177F8A +:103640000ECFBFEA2E924B1D8BE430DEB76AC97FE6 +:103650003DBD1FD7B388FB193A72609DE994AF4115 +:10366000FCF5E2E21B4663DC2D355F1F86F2DF3C92 +:10367000BF83F961F60ED4A77AC36C2CDE3F837248 +:10368000BDB887162CE0EFAF10EF57E313CEED7205 +:103690000BBEE2CFE38067E24B6036B0D97FF6D253 +:1036A000F7FD1615707F50E9E97029DEB79EABED86 +:1036B0003BC0AF5573F9F38BE2FF9F9DE4DCDE372F +:1036C00067AA9D7F901FF69C587856F9FFDB26EE7F +:1036D0007F7FAEC9C322B0BEB79ABCF4FC75938F8E +:1036E000DEBFD6A4D2B3AD299F9E91263FD5FFB2AF +:1036F000A9909E079A347ABEDC5449CF834D216A43 +:10370000F74A532D3D0F35E9F4FE777318D1C7A55D +:10371000028F966FFA15422F3A24C2EB224CE59D98 +:10372000715293ADF21DF0FA5E22BC5EEC391229A3 +:10373000EE1E15E2E756423EF2CC35EF8D713D7933 +:103740009E4E323F0A9F0BFD77D931FF9D1B559A44 +:10375000A104A73477F8E0C1B957F871F666B1DA79 +:10376000EF717BAA55A2F3C63B91CBF347432524C7 +:10377000CF874F4C2CCF7307C8F33A3AB7D841F4F0 +:10378000AB62DA110AE3069C7F6A42BF883124F7F4 +:10379000AC78A078A68907CB7EE5CDBD88FD8A5F91 +:1037A000FFEC22ED2AC427DE53710E1D788E5CD10A +:1037B000FFB186BEA9E70B38BCDB8F2F1C82FA8ACB +:1037C0001B9D52A4AF80E25688FBCD843EF2685721 +:1037D000C3AC81E3FCB6B89BCEF5FBA27ACE3F9199 +:1037E0009E13DF0E7E0E101EF0DCB2E021811C283D +:1037F00049B4FE32F987FD9BA0FFDE7E467E33157D +:10380000756A80FF05857FC761EF4907E1F98C473D +:1038100022F9E85E7FB7077DDFCF7F8DB7336A245B +:10382000BADF90B67F8F8A7A6AA05F1F86DF232B6C +:103830008C5439F1FBA125B326FA532C7450A2D82D +:10384000CF49D454A3E70E39C586C6952F8BB597BB +:1038500071FFF362E55CBA97BD1CD7B5F0542353F2 +:103860000B84FF35319ED64816BF9BC2FCEDD37347 +:1038700049EF3C7019C675C6B3307D1F02CC8390EA +:10388000C59F20A787E8DE9E69A77F2469B7E17CF2 +:1038900003C66FD0282EC71C0E8ACB6D98ACDF896B +:1038A0007432206EE37DF92F129C69ED0E1641FDF6 +:1038B000C2C87411FEE2F7EB8B8555F7E03CBECF32 +:1038C0006CD7EF90ACDF11B842BD8EECA933604FDE +:1038D000E13D951685DF9F32DECA087711902C1FD7 +:1038E000F5B67BE5ABFDB8FF8FA4FD3DD947EBC036 +:1038F000DE42FB6B9B90C30FA01C86E73627B7B751 +:10390000DA9ADDDECE6CB4B7320D071C5C1FA68CD4 +:10391000093358E723426EB9D9F221A10967815FC3 +:10392000D827CEE8BEE778C9DE10E57497EEF81325 +:10393000DA7547E430FADDB64E7CAC7625E26FA24C +:1039400087C7459588BA001534AFC1B22DF7FB651E +:10395000A6BC8B7EDA76506630FE7BBFB89F9BE1BB +:1039600077D8F49D2185767DED3B8304B70B251137 +:10397000DAADD9AE30E6E9A828B700EE769F83F835 +:10398000AB55E5F2A1355DF37813ECEF16C4B73B08 +:10399000F9FC726EAB17FDDE3BD21DC4BFEDAAB2BF +:1039A0003517CAEDE90AFFEEABEAA84C94C7F2CE90 +:1039B0005C9EC7024D52284F2AB090F49D64F37468 +:1039C000887D37CBA905BA467CA6FA43B89E96F403 +:1039D0006C09F7C5ACFFF15C497C6F81FB95B70AB8 +:1039E000FD2935BF3B827E9DB691AB2723BA3CA013 +:1039F0000FBD0BEF3D05DDA43FA55FE6D213C1FB74 +:103A00007B31DE56A7BF12F1B935C3C10CC0DFD67A +:103A1000DC2471AFB95C8F6C51278588BE011FE330 +:103A2000A581EDF68B7DDEECDCE1C3FB6C5BC72F83 +:103A3000A17CB1ADA3B97CFE4A755F577301F2CD8D +:103A400057D89F906FB215DA3795F93D78CEB57992 +:103A5000152FFA05A664DFE30958E45C3C9F38475C +:103A60002EACADA37C82543F22BD4C3E44DF1B698B +:103A7000F383DCCDC57CA646AFF53B02A0777F84FF +:103A8000F2E35C74AA32DD83F885F1898E92ED5FF2 +:103A90003C3CE92899269DA57D965E9BE83B16F95E +:103AA000D50E1BDD38CF4137E782DF762EE6C4CE58 +:103AB00045DF21DF6A8C77DCCF78FD65D5EF75A116 +:103AC0005D1F5FFEACFCD9A2EC20B9DD32CE45F41F +:103AD00014DF7F6B2E87E7E8CF7F4FF3A1FB01F761 +:103AE0002DCBC3FD4D0F140E4D492497CBA6E8FEF8 +:103AF0006A8B9E9355DA4DE76D4A3523BA4C57438E +:103B0000DE71304E7AAF0C340AF8767CFCE763EA5B +:103B1000C5E351D9D1C842305E66AF4CF4893F1F2E +:103B2000831C1C22E4E096CBFF95615EC9F6B18A46 +:103B30009FE7B3BCE73FDB799239CBEE4FBA507FBA +:103B4000D1FC6A91DF90C252783E51758942793C2E +:103B50000E7ECE6AF0DF08212224B1FF2378C89FB1 +:103B6000CE49C6FD64D9CB18C9CD685E0B7E9706D9 +:103B7000C7D119E92378B116DB5DB686EB5B39ACAA +:103B80005FC278E0E598DD2323BD73F97986E538D7 +:103B900028AF07A6C1BC14C970D0B9F8F0E547A595 +:103BA00000BC7DA068F544C447FC3A1A06ACE3ECBF +:103BB0007830E11C6C3A35CFEF160F3F8F3538B8AF +:103BC0005350598EF37F96C91BF9796CB8BD785E56 +:103BD000B7288DCF60197A87C85F1AE7FFFC308558 +:103BE000FB47A57B98572A22FF673EEED33A96EA19 +:103BF00047FFE41045F7607DDA3885FE5E03E8DDB7 +:103C0000D331DE12B3CBD5749E47B78EF20D7F82CF +:103C1000E71AB4DBFFF1D9E5D1B3E738D73A7AC771 +:103C2000A5937FDD539F86F6F873BEBC4368DF9C87 +:103C3000F1F03C30B3DDFEB8EFA2B40939F76AB554 +:103C4000F0A3A77C2863FFEB7CAA82F976259E89E6 +:103C500024DF5BA4C4F18237847CBB427D95D3D939 +:103C60001AF37B666B48FEFF2643D06F83BE94FC3D +:103C7000CA42DF639AA67AA7C5F43CF3BCF4295E76 +:103C8000E3761C47E4610D58E7FEDB187EA785F953 +:103C90002CFED93C9C7F4834FF8EF8394EBF4B86B2 +:103CA000CF0E611FB7F84A287FE30CCAAC04F113AA +:103CB000F3097AEA4F514E4DEDB1CB97B47CBB7C02 +:103CC000697734523E987135F362BE08ABF6FBACAF +:103CD0007A32E8AB87AAC93EB5EB9D6B6A18FFFE46 +:103CE0007696AAA09F26E809308C4B28393AC3FD66 +:103CF00070F9FC67DD8FAE6AAEA7B4E5AF0CA15DCD +:103D0000B37DF697082F532A797EAAD90ECECBA37E +:103D1000D516FBC6E5E3FAFA797F67C9EBB8A0EFE1 +:103D20002C75CCBA857F67C9B792BEB3F41CD02579 +:103D3000F2CBFE0C3D0DF5AF0BFDCED22D35E23BA7 +:103D40003E293C1F45E9E3F107A54FA7BC1297EFB9 +:103D500014C56FAE137928F1FE22B7BB91E26D91C5 +:103D6000E2C6A5567FB189BF2E41D7BF2DD6295FA8 +:103D700028D9DF8930DB21C6705D6EE10FDD52BCD2 +:103D800081F0BFB0328BFC518AF047B94EE9941FE5 +:103D90001C9EA267D658F0EFCE31E8BC4BFB7BC629 +:103DA000EFC17FC4EFC1A76D622578EFBDE4E349A1 +:103DB00014A72A89A4109FCD3EEDA7EF5897C94FAD +:103DC000B7E741FDFE5E85F2F2F6CF4ECDC673ED4C +:103DD000835EAEDFA6EDBFEAD017A15CDC5B8F3E51 +:103DE00001903B00CBD081EB987DDAF199ECCCA926 +:103DF00068675AE225E6B83F683A48F4F16C530F19 +:103E00003DF73445E8D9D1D447CF42450BE27A0A91 +:103E10007B2876C9669C807A0B1C856F417F0B3DA1 +:103E200078A7E8D36B88FF7A6CEDD2F2FB6CEDC01B +:103E3000CE9D89F8557C1C9FAE6AFE7738E6F7B1B7 +:103E4000CD92FA3F4A5E2D473C0C82BC5A597356BC +:103E500079C5E3A9257DE27B63A6DC12FCF8976AAD +:103E6000957F37C9E44B115735CFE976FC15CED392 +:103E700096CC2F71F966E66F887B8CE6F7EAD7D788 +:103E80009CDC8DDFBD6B7BD3ACFF78B766A967C6C2 +:103E9000BFADC6FB28FBD0B8053DF4B7353F5E8DFE +:103EA000FE8625B5598A06F00531009B15BB476390 +:103EB000E63BC6E3ED780DB7878EE479C90FDF06E0 +:103EC0007BD29900CF2FD708BB4DB5FF3D90D424AE +:103ED000F7872262DC43026FED2E9EA790EC9EC80E +:103EE000D745FB64F7447E5523E2F5E7B817F21D8A +:103EF000D1EEFB38EF70CAAFFC27E423F3EF75FC7B +:103F000040C013FD3B1D3E96709C2E217747CFE3AA +:103F1000F9C92E9F46DF4583F19EA2F1C4DF5530DB +:103F2000EB679C8CD6FF33D547FF7E824E7E22F313 +:103F30009E5ED7E1D776372BB1BC9CB6E8F71679F1 +:103F40009ED3FB02FEF8A7794F25F65DA9C3BB35CA +:103F5000CB77A51E3FDCFBAEF8EED55EA25F713FCE +:103F6000675B0C0F3FA6F771DF19D853F3F26EF1C0 +:103F70007DC5FD047763DCF7BBD8D1DDD6EF266CB9 +:103F80003BFCD66AD1FE20B517DFFB4A4017826E94 +:103F9000FB77E3BDD1F318EF75824F7CAF6B630DF8 +:103FA000E7A364F40CEDFBA87DF43BC6F51E3C577B +:103FB00062DF317E83F0731EF83A46E3E8E6BC4CDC +:103FC000E443717E31F3C94CBA90E7713ADD5C236A +:103FD00099F796FE407858356878F880E089BB9F5D +:103FE00074AE753C3339F411F5F345F394FF83CA8D +:103FF0009F111EF35E593C7F0C9D2799F9D129F33F +:10400000709E9CE8F73C53E725961317342F8C9B42 +:104010004DE3C6BE133A7CDE20AC87A9E7975FF27A +:104020005FBC10FE351071000000000000000000B1 +:104030001F8B080000000000000B0B146060F8519B +:104040008FC0DC687C5AE3BF4C0C0CFACC0C0C978C +:10405000D81818DC38191844F8C833E7329ABE87E4 +:1040600040B366F130302C636560D809C4865CD8F3 +:10407000F5D90922D8C7817E5F05C497E91C06A33C +:1040800078F0E03A11068629A208BE8118AA7CBD04 +:104090000882AD2745995D2E40FD00C5F694E2806B +:1040A00003000000000000001F8B0800000000005B +:1040B000000BD57D0D7854D5B5E83A3367CE9CF921 +:1040C0004B4E92012721E0991031D840074C145AE9 +:1040D0005A27116D14D4887FD17A7B07DB228ACAD4 +:1040E000D47A956BB199FC4F4280008A142D8C3F95 +:1040F00054B0FA9A2A5AACB577A2146DF55DD15A2C +:10410000ABBDB42F566BAB551B5B29F415E5EDB574 +:10411000F63E99734E66328348DB173FBFCD3EFBB8 +:104120006FEDF5B7D75E7BED3D0A5441D569008749 +:10413000F18FA5F7F900A03E93CEFAC605CB1EACD1 +:1041400063FFF6B923DB5832EBE97995B1DA4CFD20 +:104150007A90002600343E7DF91F81D5FB2F70EA4E +:104160006EF6E9C9C0882FC2F209C909D8CE0D0D73 +:1041700065E70459F94147A48FE5D3871C7E60FDAC +:10418000CC04278DA383E66F9EC1BECB171483A9F1 +:104190007F7BFAF94D32A4CB009EBA05E46656AF98 +:1041A0002B70EAE5C37E80E75BD37F7DE304806804 +:1041B0007ABAACB37E76B73E43F91FB7EEFDEB1B80 +:1041C0002E801894D0388DF3DE9717B3764FB9A0B0 +:1041D0006590B56B8C4AAEC5A6F162623E4F7944DC +:1041E000B9D620672D0FB072F6BD31787ED6F218A1 +:1041F0009B11D52B11FD1C1C76623D1D467C34CFD6 +:10420000438BB2CEF338D1CEC8D70DF3F93EF9EBDC +:10421000030B900E69286E76637AA86A1FE27B48CA +:1042200095740833FC0E9F4DF84D237E5917075E99 +:10423000E3F87EEA4347A48DE1BB51D5FC11960714 +:1042400099D1839537FA214A70C92C65702C10706A +:104250005F2AD24598125D74A2CB90CAE8E2CF0FD4 +:10426000EF699B1482D798E710CEB38076065DD9AC +:10427000577F7380B583EC7C30163F6CBC938F1CEA +:104280004E03AFCDF386FEFA860AF47798FD7F865B +:10429000F6D3BFBE5193C99F7670AF25CF381AD4DD +:1042A0005318BCF84F1D53F98361A33CCCCB719CD0 +:1042B00064ABFE4135E3BF8156F8A09AF1DF9A5610 +:1042C00095F2FDAD1AE5FB5A43944FCAAC09A363BE +:1042D000B21F5209D6BE24CAEA9BC62B9EC3DA99E6 +:1042E000E00B44344BDE5713B2D4F7E8BAA53CA92F +:1042F0005FEF4831BAF7D63A524E09E16032722286 +:10430000C2A152CAC07D39C4E653CD9BC06A97FE94 +:10431000CB2A84E70527B4B37C911E755CC1F253A8 +:10432000424E4845D8F8452300ACBFE42D00EB5978 +:104330007FFDB34E715CC1F27D73DD9A530348B1CA +:10434000FE936ED6CF4769BD03FB99A144B01F18F9 +:10435000907F8B7852D97F87AB00A6EACA6B8E22FA +:104360008070827D37CFCF9D08A15C17CFB17E9F33 +:10437000AA2FB91658FDA960FA1ECED0D318D7C8F7 +:10438000DBC7B38F73FC0A5BFFB67EA7E8C30D5A89 +:104390006DA6DFE361A44DF3FF2BF71B6D94904EE8 +:1043A00011D053B38E1DDCFE157F2979E3E40C9EFA +:1043B000FB5D5C0FDAE56D181CA43F409E005106C2 +:1043C00097AE3B527DAC9FBEB083F847EF8214EAB4 +:1043D000ADD593F7C631DF1756F476960FD7EC6953 +:1043E000916602AC9AAC11DFF53DE186F6088723B1 +:1043F000C8F8748AC1A71F0D3754211F4A1059CF1E +:10440000CAC3FA9B6D585F7BD9ABBBE68C9D1FACD2 +:10441000E0F3A73C9BFF08FEA37E6CBF3FAB57A217 +:10442000CDC8B70948B9193CBDD5ED4D0936CE9672 +:10443000840C283F7DB70CBE82784E9EC0E1B5CF7C +:104440007B8AAE2C46BE06F3F86CBC29D5172FC369 +:1044500079D9E130F4C59DAD1A4419BD36B7D6906F +:104460005C6E69D506514F6CFED09915BF0B24AE1A +:104470009FEF70353B12B8CE4E77A4B649D85F6C2B +:10448000F3550CDED5F51367E33A70FD748EEF0F2C +:10449000FA05BEA5D4A540F5159DEADBE47F8B1C8B +:1044A0006D47795E1D2A8304C3EB14D7DEA6A99855 +:1044B0005F51352B8178AFBBFB35EC6FCAF4693A9D +:1044C000E2636ACD9BFB502E377F9422B99D5AC37D +:1044D000E49ACD73CA8A8983D58C4F2AF5D4D7A89C +:1044E0007E8DA2A7A40C5F4E86483BD2EBF8161F28 +:1044F000A4B5FCFC39393E3E7F1E3B3DF08F91ABAD +:104500004936B9BA23875C2D941CC42FA37255C3B6 +:10451000E48AE175C74956B9DA3C39F55631CACF54 +:104520000CCEA7763E0FD7BCD98074ED67F2531A34 +:1045300002A8700FFC5942399CC5EA4B542E7D9954 +:10454000E5FFF40BAF0E284FB59CAEF9E4CAE0E7E7 +:104550004C6A1D774B9DA3B19981FAB3AB36BEED82 +:10456000C6F16A151DE5AC4FDEF467C4B35EAFE873 +:1045700009C9244FB55C9EA6D431F9C92257F9C6A2 +:104580004FB6A6E0752647EB5A43245F6B5B7592E6 +:10459000AF5542CED660D5B92C2FE40CE6CCA67C24 +:1045A0002EFB13A08DE44ED5F702DAC1EB58DF5095 +:1045B00081DFD3D1E83C80D23A230F69075BDBD798 +:1045C0008E9643142A09DF009F41F0FE9888B2F6C8 +:1045D0005A1DCF3FDEF6C7440713C2751E5EFF09A2 +:1045E000A9A62131CFDC7E0FF56FD467F97463B5CE +:1045F000A93FECDF028FA301EB1BFDBDDA56D19082 +:1046000060E3AF1579A5BD84E78F71FF4CDF841897 +:10461000D3439FAD9FD592E827F16C34EACF8C73DA +:10462000BBF456346129FF4314F164947FB7EDD98C +:104630004482D57F1F9ABF25313A4C9F1FAB605BE8 +:1046400018F036ED0534A5D6D9F09D99DF0B34BFAF +:10465000400DCFDFDDF66114F16D943F2A05DA10CD +:10466000DFC837FE89CCAEC27FB23157FDE4474B7D +:104670009FC37FCF29052867E3E803CCD264B3AF9B +:104680004E01EE3B7C35F29BA3FC0719BE63F03D67 +:1046900028B174FABCD865B81466812F6186CF182A +:1046A0003F1FBC061CB9F9938F6FE7A3C633E73CE5 +:1046B0003F8FC99B77AF2BC2C480CD4393701D2819 +:1046C00045A0985E2BF9E8E721DC8A81CCF478607C +:1046D0006CBFA5F32B206592FB4F9A9EDFC23CC7AF +:1046E000DB4B66BAB2FCCB663C3E88F5EAC7F29D6E +:1046F000313F8F989F67CCFCEE69C1F9E5C29B7D85 +:104700007E6B3D032DCD59F6119F7788FDEEE7E7CF +:104710009C87FDB3F100F597471F213B5EC3F1D89D +:1047200056B3F8A39FB720DFE71A4F9BC7C6AB3934 +:1047300076F8CCC7C701A6BF888FEB181FD7E6E66F +:1047400063BB3C1BF3F68A797B73CC9BAD9421DC75 +:104750008FFDFF3AEFBFC87C5E37B03E127C5E5CD7 +:104760003EFE49F3FACB736512AEEF088F93F373F5 +:10477000281B7FBD2EE9967DAE9DAF73CDEB9FC507 +:10478000A763E7353E9E8FB51E2A54BFB6BFEC2502 +:104790003CF6D5B27D02EE0B9E3983FC157DCF9D94 +:1047A0007E1CFA1FBCC94F41B40C601AF6CFEC89CD +:1047B0003EB42FB0FF4D7505D917FDAD30D8790245 +:1047C000C023450C0F7E9A27B5DFCCECCF14537075 +:1047D000752FEC5617637EE9432AFA95FA84BD5883 +:1047E000F7C2BDEBCE64F8F4CF289DE564ACD0E70A +:1047F00031BEEFFCE934B4E36BD977C45B80F7C713 +:10480000BEBF80F50333F8F75C70F994540CEDFBF0 +:104810004084C165E207A3FC6107B74B77A09D7593 +:1048200022C2A993BDE5F30EC690BEDECD8A7E7787 +:1048300096FDD2FF16FA74FB8C3D092FC285F61A3D +:104840009BF7937775575CCDDAF9EE04D2E7BE9A01 +:1048500054C2C150E7AB03DA0DEE7099E85E4970BF +:1048600009BA2E924E67EBA4CF96DF3C5AFF8B64B9 +:10487000B74CAAE5E58FB6FF4743876C2A4F5CD952 +:1048800010ADCC943FDF7E6D03AEBBD3D5D8AFE681 +:10489000B1F1A733BDD7C1F03A5D1E70C4899EC186 +:1048A000ACFCB27D9BDA92627D6CBF6B63D557B373 +:1048B000AC238C8A4467237FD2BD56BEDE21F0B77D +:1048C00059E0B39FA117EBFB6A07DA119F27DD0BB5 +:1048D000116738B7BECB49C73BADFA6EBA6C9DD7EE +:1048E000B19ACFFBA0F1FDB6E89FADEB2F3AF87C73 +:1048F0001C284727311A384B8E7E3E69C413B723D4 +:104900007E93ADFF7FD47CA7FBD938C14F7E1C9F1F +:104910006D9C5CFDDAF555A2112419F7FD151041C7 +:10492000784AE6C769FFE2F4EF0D25989E95B561D8 +:104930004A5DC1915082D97F4A482FC7D45D192959 +:10494000C7EFAB3F740A79EA6943BDBA6634DFDB6F +:10495000867A742DE6497E5651F9FAD1FC6ACA6FFF +:1049600098CCE5EB78E76D43A887AB503931B85662 +:104970000FBDDAF2650657D96E7F044D8D327F0484 +:10498000500F1BE56B86DE0AA968C7EDF68387F139 +:1049900043A9160573FBB5437F0BE19EC52FCAFDE6 +:1049A000C1664BF9FAA1E9E521D43FA2DC1B8A518B +:1049B000F986A1B9E53AEA93DD7E0DBFFB2AE3341F +:1049C000EEE94F5F43FC925CE820BD6EE031B970C8 +:1049D00036F9952F9762D39D8C1E0D4FF7AB68FF6C +:1049E0002777D792BEA7358BFC49F2FF457E245D21 +:1049F0004AEB985F7BF353825ECE0C3DFAF1BC82AA +:104A0000FCC0FC9C2229CE29128DE934F9678A3832 +:104A10009D184767FCCFD4FE998CBF9AF27B2DF985 +:104A200080968AE23E5E0E32FDC0DAFBA28928D271 +:104A30005DA9E479A73F9246FD71C75510F1EB4897 +:104A4000F72860FDB57379DE156CA6F6BDF53CAFB1 +:104A5000846209CC2767F1BCBB329EC6FCAAE93C44 +:104A60007F874167D861E503F813D1BD7734EF69DB +:104A7000C7F2A4C137E06BC7F2559FE37AB6426E26 +:104A80007812F17FC7D063AF2E61FD17233FB0FED0 +:104A90008B97462C74D9AC5BE9B259E7749955CC25 +:104AA0003081749075A2C7ACE3AF776878DEF129E6 +:104AB000EE176B7CFA471EB4F7EEA8994DE55364E8 +:104AC000A7F00F707FF836E10FA862D285FB9F6DCB +:104AD000C21FF0E46DD38AB1DD939B7F48F4FE3CA6 +:104AE0002A11D66E550D3FBF7990ADD3E8C7FF6E42 +:104AF000AB4AFEBA5DACBF18D3DB8FB6AA943ED4E6 +:104B0000AA418CF5FB3DA6C7313FC0CAD36E3A0F10 +:104B10008034FBFED84E47538AF5BBA9959966AC05 +:104B20009F8DAD2AA5B7B66A7F91597FEB5B439401 +:104B3000BFD2B1688593FC1A030B66B2793DF2626D +:104B400035F9F7E63EE868C6F6A00D5C706E5DE6E6 +:104B5000BB819F2B1D8DB720BFFE60A7DC847A062A +:104B6000E4F8B333B2D76BC77AA73E283753BD609A +:104B7000FCE7E704B3D6EBC17A0FEFE270831A7952 +:104B8000B6367B7FFD08EFC9DF77F0FE42919F2F9D +:104B9000CCDEDF3AAC37B84BE6FDF999CACE5E6F92 +:104BA000238E1BF9BE80AF12CA16661FF70EEC4F9C +:104BB0002DE5F6CA9C28905F6CD235FA5D92896F1C +:104BC0006EBF765072303AAB65A938D63B657E4AE7 +:104BD000AA62E97157A72407D3779396B272068F1A +:104BE00007FB61E9EC39BCFC762C0F98CAB13D4B50 +:104BF0003F3D8F95B3F4B865D67263BC495F815170 +:104C0000BF103A5B27C5C0B05F283FCDC1F38F3BD3 +:104C10007FDB80FA699AC2EBFF19F3AC9F492DD66E +:104C2000F6D3BC3CFF5BA37E116FEF90795E6566A7 +:104C30002CEDD336AB29B4BB6E3DBF3B74853F33FF +:104C4000DFE0A264CD15A6F9DDBA6873E88ADACC94 +:104C50007C8217DC5983F95CEB8A477740D4B40E29 +:104C60004D1BA8257BF75F5DBF5C645A37705DA95B +:104C7000C07581E1A782310A9633BC25B8BDCAF15F +:104C8000B6FE2C2BDE4ACFB6E26DFDD956BC952E72 +:104C9000181F6F3F13E3E7C21F1B3F6A1EFFB68B4F +:104CA000ACE34FB8D83AFE6D175BC79F70C9518F00 +:104CB0009F36F3CD8673ACE3979D6B1D7FC3B9D64A +:104CC000F1CBCE3BBAF10DFAF40E7DCBBAAED735AF +:104CD00083997EC9A1DE90655D8FF075DD285F3513 +:104CE000F45808D7770FAEEFE89FA9E1EBFBACD7FC +:104CF000DF0FA1DF7EEDE7F6846298B2BA7B6B33FB +:104D0000EBC6939FBBD1713FEBF7EBD31D74FE3322 +:104D1000F4B94755D4FFAB6A6693BE4F8AF3DCBE45 +:104D2000D6F4FE6B5C997905921E889AFCF7A3F67F +:104D300012FCAE01F93059E310F652797B94D9A2F6 +:104D4000EA74D992EFADE5E5377796B727D0972289 +:104D50000F96E33AE4AB810F6A4D7832FA37C637E3 +:104D6000E0C93D3EDF1767C69F6A1B7FAA657C23AB +:104D7000EF99C1CB13727523C27387D827DF20FF49 +:104D80008EF4CBB1836F467BB4DA0C1FCF67E0E3C0 +:104D90007903BE6FCA331B13D5FF48F84EB5E1EF58 +:104DA000541BFE4EB5E06F853CE788F067AFD76FC8 +:104DB000E3CF6510BD499E807204646FC6654D9C4B +:104DC00007F1FEEA64215F383EFAF2AF55522784BC +:104DD00079F922B6AE5D2E8B7D98A8DF64CB1BF6E9 +:104DE0002B2E4787C98F97DD7E5580EB6DB6AD8B37 +:104DF0006C23BD1E2179CAEC3BB81F43969BA3CD03 +:104E000059F4C146999F0F4B5AA405E194FD0AF944 +:104E10001373D51F9025615F272CE73BC530927631 +:104E2000221C21A0F8243874817EFE8CB170287277 +:104E3000730CC7716A0AA05EEB2CB95837C731ED05 +:104E400030E00945091E45E3F02872249ACD0F7C15 +:104E5000B7CCFD16463F0C42D17E84CE050CF8BA85 +:104E60003CCD2D8BD19E2F51084F9D01EBB9DE6FAC +:104E7000C4BC9E1769A7884BB28F07188D81F14B70 +:104E800013E7901DDA31A75145BED421A2A29FACF1 +:104E9000D39F3D9EC848FBD1EE3C11F95E25FB3304 +:104EA000C9EC52CC7733BB14D34EFF434DB8EEEC74 +:104EB000473ECEE2A719D5731107A44DFB6D5F8D58 +:104EC00017D2E6FDA8D8AF7AF452CB7777A8C2D232 +:104ED000CE3551267BBED3EF48E13E3F1FFCDD02BD +:104EE0007EA35E8F1C57B502F6CBEE9015DE63876E +:104EF0003FDEDEE71AD4B2C1F549E1CDE02B7BFFFE +:104F00004A991227FB596E0E99F9DFE9E27CAA94BF +:104F1000A971B29BD55CE55EDEDECFCAD12EF63735 +:104F2000EB78FEC2449EE2C4549403137E26897635 +:104F30009D2E711E0D713A3792F4780BF2915AC979 +:104F4000E4471ADBCE48BDA27DCF875F7F85E4634F +:104F5000824AF221E923E497B78FF3801C9DE8622F +:104F6000E926397A1CA6AE8F9CB16C7232C1C5E5B8 +:104F7000586D6ED6557E249E15FE9345BF0306FCE4 +:104F80008938F99B0B85BFAA40F84FCEC03FD35557 +:104F90004FF07F1AD35CF0CF10F094416408F7ED26 +:104FA000C8A0D82FC0F9BAD91FBE46F45B26E003CB +:104FB000F81AD1CD28EF157828743EF30A9CCF9AC1 +:104FC000CC7C9AC47CCE1A6F3E5F10F359E3E2EBBF +:104FD00095DAD4AC87185F95E6A0CB12D1FFE651E5 +:104FE000BA7CED88F8EAA202E7B124338FC582AF1C +:104FF000AE186F1E3101CF8013E6BE11443349ACA9 +:1050000037B0C84297AD065FB9F9BA0170BD852EB9 +:10501000B7897E0A9DCFF202E7B335339F6F08BA96 +:10502000AC1C6F3EA6FA6DA27EBB902BB25BB6BAEB +:105030009E6847FBE301B9B9DB559F198FD5EB316A +:10504000D79BD4D567D45B85DFA585A3F5FAC5F8D2 +:10505000C22EBA87F6635D686330FBE6DCAEE71B01 +:10506000D11E67EDD653FFCD7CDD64ED3698FB3F56 +:10507000B96B63BBA8773BD66B3BFD23A3FF4DE623 +:10508000FEB7BAD2061C77121C4DA3FD7DDB5C6F08 +:10509000896BB09D9F13566A6FFA4C764DA834CF3A +:1050A000B90CD7BBAE602C398CFE4A080CA0DDD100 +:1050B0002DC7B70E233F30236F1BFB7E933B2A493E +:1050C0006CFDD4A2F1FBB05E69C2AD39916E8DF179 +:1050D000EF613EE180668C8BBCDDF7CDAD985F2142 +:1050E000AB9A3B82F6964E47436B8232C5C97549EF +:1050F000B104AE8B07E4D82E17D93DAC4B36CE4D5C +:10510000653AC5FB94CC0789DB1D1CAE75BE2F2507 +:10511000110E37830BE383BB6C70B1F1685FDE3B2C +:1051200081C7DB800C3532F6E7F446B0BFA1093702 +:1051300012BCC936B786ED9327DC48F0B2B2668A56 +:10514000CF73C509DE1E97AA613CDEEDBEEB36616A +:10515000FCD68A4431D5273870FE53AB087E0FC485 +:10516000D38BC3A8BE06A2786ED3B550A1B8E464B1 +:10517000703DED6FFB16AAE4DFEFAB599FC076FBE5 +:10518000177A29BECEE31F008C032A5BA000C6C39A +:105190007A82036467969EEDE5F94AA0714A3FCB97 +:1051A000E3655D30AC55B1B42CC9E38EFB6A1625BE +:1051B00016A31D3387C7A34222FA22C6B79580F8EB +:1051C00073560E61FFAE494E704632F42D1B186DBA +:1051D0005F1CCB222FA3F55205D64B1756AF3429AF +:1051E00017566FA0C07AA902EBA5793D379C5F9C4A +:1051F000ED9C7594EFE72B647F18F16D45CCF21FA1 +:10520000B54FC2DC6E37DB2B2E5032F60AF299F323 +:10521000F271E158B1AF2DB8DB64DF04954090F630 +:105220001BA7C2A9249779DA1F684D0477BBF2CF78 +:1052300017252C6DF293E7ABBFAA95FB697395FB1D +:10524000665E1C227D36E332915ECED359EC7B2D17 +:10525000A62D227F99C85FDE12CD325E83C2F57023 +:105260000D348F4B078F80FF4D3CAB674D6A645602 +:105270003F4B9C8E91FA6B1D36BBD1AAEF5439D1AE +:1052800048E71C353C2ED78DC288721301D22F2ED1 +:10529000486B55B8178568D1E28919F9718526924E +:1052A000FCFC77B913A439449F08E2D1CE2776BE1F +:1052B000F0DBF8E268F9E4D263C427BEA4B320F9B6 +:1052C000F10D14582F5560BD7461F5FC49A9B07AF1 +:1052D0000305D64B15582FCDEBAD3A4711FED60539 +:1052E0001DE887F19DAB5AF2ABCEF55ACBCFF35BFD +:1052F000F2FD6759DBFBCFB6B6EF3FDBDADEBF80EE +:10530000B77FB8FBA2D3D1CF53A89CFCEE63CA49A8 +:105310008D3A7EFDD28579E44A4DD07ED223EB9042 +:105320000EE2FAC5D62989D2682A8B7DF75321FF70 +:10533000CFB9B81F272927685FFBAF3ECFEF2ADC24 +:105340006F64CC371FBC86FEFDBD53D85B76FB6B0C +:10535000D4AF73E8F0E153508F00064B83A6B3A996 +:10536000A11F17BC110C15F1540FD0F9B4BDFF5E8D +:1053700023BE0612A14526389E7373BFCA4FC2DDF5 +:10538000213AAF3D616308F7E9BD93A5AC7E968FE6 +:10539000147E2E5815F3919DD1A3ABA40F7B27F358 +:1053A0007B4CBDAE01F21FF786ADED55613F7CA48D +:1053B000F0F17A6F8903DAFF5D276C6CC171DDE96A +:1053C000FF049DC1FD1F93E3A0E3F86EBE0F70477D +:1053D0001380EB82AA27E8FCDD0E4FD2884B868132 +:1053E000D022D3BC2F32E6C5E653C8BC5E57141A90 +:1053F0004F8B72FCE5C257FA08F1B5D4ADF07B6271 +:10540000210FE16BFF3CBE7E20219D8C8EE452D4A7 +:10541000292F99F9CDBE1E037805BF1DA6BC2E5FAE +:105420003A2E3FAD12E7A7BDE88761EBB47EE76592 +:10543000E3F2738F58CFDDF045EAD7ADC7A3A8EFED +:105440007CB569403BDE53ADCD767270A23051F031 +:105450001FC1DD197504291E25B299B1BC6F426FB9 +:10546000242DE51E47AD55AC727384EB5A9DDBBA13 +:10547000AEED877E72C6AE76C0D26CF7018C754DEC +:105480000F5E3AEEFC57D9E6EFA88D0B3FE54A1EBA +:1054900057C5742BDECB84502FD9EB3E89CD3752C4 +:1054A000F83C5F75733DA687C687636D2BF7A3AD88 +:1054B00016F4CB556F353AA031BED7BDAD03F76BAF +:1054C00025F3B97C8CCA833C60E1DB830AF777F46F +:1054D0007AF4368A730973BFC9987E057FDBE52DA0 +:1054E00099E39E8D21CF7F5374AE9FD401F247186C +:1054F00072A7EBFF49FAAF7772BB8AFA21A9AF27EF +:10550000FFF1FE6A05303ECBAE278CB44FE0E134AC +:10551000E857F11E53DF4B4EBA176BAFE7C1CD9A78 +:10552000C9DFE7ABB1EAE57C7A66B39BE3E5E3EA82 +:10553000991F0ABA66D133B42E2FEDE97C0AE9D35C +:105540002BE20C4B9B12B0D834DFB542CFFDBB5BD6 +:10555000AC17951C8E5E97D660A65309FBDE60D60D +:10556000A739E8938BEE976190E0840C1CF6F9ED77 +:10557000107828C5F16BF3E3612C1D381F74BBB3A1 +:10558000F3C127359F2E81AF7C7CBC55CC67ABC067 +:10559000AB31AF7C7262F4FF30E2AB1EEBDBD603C3 +:1055A0003961A1BFD3C05B93AD9E6AAD67E047761A +:1055B000733BC6583FF2F5FF6B85C363EF3F971C03 +:1055C000FE66540E13E4AF35C671C3E3E457D8CF7B +:1055D000F474DF2C80623F48E837706A3CEE291093 +:1055E0006C06F3798F5D7F197A31973EB2EF67F2DF +:1055F000D55782CAB8F69361EF948A7B5FAA881365 +:105600005E2F653FFFF9BBA01B53F405C5FB61F896 +:1056100008E2039A21B58DE244A3436D2C3F31A2E9 +:10562000E87DE81791CF18BA8BE527FCC80D7D11EE +:1056300074C5CC1F1A62FCB62AAA366379851A1E75 +:10564000BD1F39700AFABBB83D06CE95AFE0FDE04C +:105650008997C8807875C35C8ADFDEBF02EF8E8DC4 +:105660008567A20C30A994A5C26F40E78AB8D5BC63 +:10567000D08A4F5868CAB3FDE304D5B6BF2B70DE9D +:10568000767872B5CB0B4F667FFA068EEF86F1D730 +:10569000B5239DDFA8BD5BE0BC686D36D50B1F74DC +:1056A000828EF7DE0F4A941E7FD047E994831E4A0C +:1056B000271F2C039D11ADF26009A5930E4EA2EF9A +:1056C0001507CB292D3F3895D2D0C130A525073FEE +:1056D00045A976703AA5EB841C161F3C99F250330D +:1056E0009BC62F3A388BF281839FA5D47F702E2FD3 +:1056F00017E7ACEB6E8901FAB1155C87987C749D55 +:10570000B184D625FBBC6E55F9BAD22DE2D6BB6D5D +:105710007AFB6151FEA048D709B900390E667F7A3D +:105720004AE57A615D558CECF26E633D2C5F6259FF +:105730000FEDF5BB73DCAF7CCC804BC003358BF237 +:10574000D0879FCBBA8331BA4F001023BD0472CCEF +:10575000A277BB0DF8051E73F727F078C6A3C4C760 +:105760001E85C72D7BBE7067CBBDA877CEBC71E907 +:105770006E267723EED8CD2AF2FB17AE26A6BBE322 +:10578000BA9B43741FF18C8D74EF09CD72BC4FD15D +:1057900073E6CAF8BDC4758C2E33A85D9B6A3A1FA8 +:1057A000ED5D7273CB77587F7AA7037413BF4E59A0 +:1057B000E905DDACBF0E959563FBCA1B4A2DDF2BB7 +:1057C000AEA9B0B4831AEE470F7DA5CA524F9B7F96 +:1057D00092A55ED1BCD9D676E2FCDC5FF7194B3BD3 +:1057E000B7DFC02B3F5F64F4B7AC1F3D52763A7E03 +:1057F0005D758CCB3797AAC22EF21746B75CFD1B9E +:10580000F3CDAB978279E741F6EED7D573E7E3396D +:10581000865B8BD1FD9523AF7F6CE751683DBBBEA6 +:105820002A427D5586FA44A2D48FFAAA0CF58887BD +:1058300052A3DE6AC36E29504E56A3BEF19BF44DAF +:105840003D93FB2CFC50EC195FDFCC14E535225D59 +:105850002DF8CACE37938C72D437B5F9F5CD24DB49 +:10586000B876B8EA3C421FFD93F54DEFEC8DB12FB1 +:10587000B39CE7D43B5BEE6169CFAC1B29CFF485C9 +:10588000DBC3CA7B4E5919BFC7A447E0D0CF395FED +:105890000A7E289E63D51F46FF81884D8F18F2F03F +:1058A00031E55AF270B9CD459FDF1FA55C1BFD7F26 +:1058B000D2722DF5AE3A22B91E5BFFD8CEA3D07AB4 +:1058C0008946489F86FB9269DE5407FAE31C031160 +:1058D0007EDF3346F13CBD3F75D17902AB41FBE23F +:1058E0007A357A0EF24FBDDA7C1EA6D787F5E370C3 +:1058F0009D66F9F36DF90B3C132CF98B6CF94B6C2D +:10590000F52FB5957FD15C9ED4F5E3D08F917CC601 +:1059100045E78649DDD194F53D0581A767D5E62F9A +:1059200063FB1353271D877461F9AF527F1EDE1F7F +:10593000CB5F49E365F257D9CA97D9CAAFB5E597A6 +:10594000DBEA7FCD9CEFFD68EAEDB8DE277EE682DC +:105950006D59FC4BAF083DD273C2CDB1762E97374F +:10596000935C4E5B19BF02882F00E176FA6DFB3F16 +:10597000C667667E7956E89B9F4CBE91F64D3D6C9E +:10598000FF44F18DE8DFCB829FDF78C4FB5CFA55E2 +:10599000742F22597E3DF9397A2ADB297E61BFAE08 +:1059A000D0B96D329CBD7D6F2BF773F454663F5FA9 +:1059B000F88D276C89D7826AEE17443138ECC077AE +:1059C00086B87EEF0A77937E55D25771FF46798C61 +:1059D000FC1BDB3C7CFD52FC71F22BB82BE359F72E +:1059E000F53DA3F8B0FA3B7F22F06AEC234DF82096 +:1059F00039ECF2FC6937FA37929EEC72B6538CEFB1 +:105A00000A1536FED8F9F3F1EFC6CB2E28AFB67DD6 +:105A10006DD2C5E3E71393B91F4066E398FD0AF61C +:105A2000F146E769DB67DF25F83CE9E1F1F7467FFE +:105A30007678EE17F3B9DFA359E6256B7C9C7CFDE5 +:105A4000FF182F71A11F40B3FB21AC7AAE55D4775C +:105A500005ADF572E127318A1F1EA765F06F3E7E06 +:105A600037C67916E1A2F385ECFB70FDD01C8AEBFA +:105A7000D80F81813EDC37CBDA2BE817BE896D93D6 +:105A8000D09FDD2127C8BF90D041E3EFECF07389B0 +:105A90009B9C274550DFA922DE0230DE22688A5710 +:105AA000147ECEDB7DDFBC0FCB5724DC1ABE7BF22D +:105AB00077CF543E9F432B28CEA297EDD471DC03C1 +:105AC0009E29297C4FC759DC4FF6BCD3392B9E2D1C +:105AD000FED4EDE5727CDAA1B5A467BB997EC3F371 +:105AE000A56E39A696D6A2EB3A41F2DAAB8F1FD754 +:105AF000688F8F7469F6B8442BBE225E4EDFA458BF +:105B00007F939E488B252ED0EBA1F2BF7BACF0F5A6 +:105B1000E8FCBE900E718A334D563A1C88B7630577 +:105B20009F31AE12E6F78F8210A338163524D3B812 +:105B30000E1FC76FAE714197DF31BF2B73ACF039C9 +:105B4000BAFEC6383FC9E0257ED2E7AB8DDB31FF18 +:105B50005327ADA7F6717EEF8D7DC66BD29BB21633 +:105B6000033A8717FD9D3581C77FCB95FC7EBA022E +:105B7000CD4D6136FF8E4AFEFEA2ECCF132F516948 +:105B8000F757E43AAFE3E72554C444B4E10F7C5C33 +:105B9000AF882308C030059116A34A9F8A7104BAC2 +:105BA000C4EFF747241E6F3E8FE2CB839E4FBADFD0 +:105BB000CBA95F29BA0E0EFB8EA05F7998FC5C9F83 +:105BC00078BF79E0F5C09DD42F86AC1E2ECBF48B28 +:105BD000FA979C4A870E1FC6F334714605861D2E20 +:105BE0003BF87D2BA828A278C4AEE0F5AA99AE9D1B +:105BF000DE2ACBFAAA68DD5FC3779494CA6BA2C38E +:105C0000E3F06552C89152F995E870017E4C994DC8 +:105C10003F9B3FB45B89A5DAD05E9CE2E771AC7232 +:105C20009CCE477AA4D2D97D7526FEAD54D2089772 +:105C30003F124D609C634F992382F15932F4EFA5D6 +:105C400077D39C0B23E3C9AB5C29BF6D9ECFB7BD57 +:105C50008120C129FC871D79F8BD4BE8EB5CE52E5E +:105C60002512CBA68707BD621DF3662F3FE06B7C34 +:105C7000D09B65DD490BFCF6943055FA69CE3EC8E1 +:105C80000772E59E57100F5D13CE1C5F3F6956FDEE +:105C9000F4BA2FFA43EFF870FCD85B9F857EFE6064 +:105CA00061FB038803DEA775BEE414E7BBD122695C +:105CB000229EDA1A7F11E864E5AE396E0DFDC9DE69 +:105CC000DA08DCCBF2A1D3D566790EBD1B47E7AC71 +:105CD000AE7227505C9E731E8F1BAAE17ED628FBF6 +:105CE0008FE2CBE68D1F4FE6B4E57F65A773EB2E01 +:105CF0007A3FC280DF885FB7CFEB07BEC6E1ECF822 +:105D0000286C1FB481F10BB8F15D3195D2B5AD1A95 +:105D1000A5AB5B4394AE6A65CC4EEB7F0DE56FC3DC +:105D2000A673312E249E0CE37E2474EF2B78257409 +:105D300003E296EE19DD7306DA597D98E7F7421310 +:105D400012E627F3F2437D1BCEC0FD609FC7A89FDC +:105D5000E4F547F37774A15DD827E26BCB56DD7B82 +:105D600006DAAD1B261BFEAFA87A91C9FEAAF1B9CF +:105D7000B89F266CB4EFEAC27DAC4736F28F9E61C5 +:105D8000CD4314E1F1A83C7F8EEF07040FA9003644 +:105D9000DE45BE5D94DF7082D8975FB8280F1EB9CC +:105DA0001FA3D7AB733BE842FEEE8AC2F8A68A7DFA +:105DB000DA20DECD2DB41FDCFFD07AF752F6F532B3 +:105DC000233779D6B50B0B7BFF85A183EC0BD4C3AE +:105DD000F8FEA2FC0B2E17C77ADC0DAE23C38B3A5C +:105DE0002F16C5EE8B9A06D348EA9F78630D3ED6F0 +:105DF0004FF1FCBDB4AC28A134B71B0A1CBFD2279D +:105E0000EE9BB179E3BA63E0DBB03F6E407A4EC8F7 +:105E1000F4E70A46E9DCCD23DE1B2E14EEABBC9A78 +:105E2000A51F786076F978E76DC1850E0C421AD50A +:105E30001BA5F3BD96BC36AF540475F07C515D854F +:105E400025EFAFADB2E45DDA4996F61F975E5FF2DB +:105E50006A16FEBEC036AF26FB3C0BECD7B3C2A918 +:105E6000BFC1EC84B06CD8A5EBE9DEF27EC431EAA8 +:105E7000C98159748F17AA8D7B0A40712C1E3D4A27 +:105E80007CEA65FA9AECE34AABBD2A07ADF66AA84C +:105E9000259136FAC5F86DCF0A85C61D5DAFFC9019 +:105EA000F6E0DD73A19769DF3E1555DE379E09F3F5 +:105EB0007611F3FD7C7B2A8B7333BA9B1FCE7FAEAA +:105EC0006A1F2774E1F8716CF6FAE097F5374D72A6 +:105ED00098BB9D0C6F9ADEDDD886B49F90C17F740D +:105EE000FB62F27FB881D9D30CCF1DA18B21C6E60E +:105EF000D98D5518FD9298323EEF0ECDD6284E5FC3 +:105F0000E77475A85C4E6EF2E916BBCCE9E77262E5 +:105F1000D4CB47FF9B9C10CFB6AEBDEAE3FBE503B5 +:105F2000DF8CFF09F799891741C7F3DFC1D683F4E6 +:105F30000E665DFA2C27FA4FF6F92652BDBADD51EE +:105F4000E7E9A67EEA80BF07CEFE9C66BFAAE127EE +:105F500086432AC50DEF4CF3B8E19DE93F3F751824 +:105F6000F3CF38E8DDD19D7BC7B7B306859D65D4F7 +:105F70001B7C86EF5B0765F0958E67EF88FB71B33E +:105F8000D2B6B844199C48FF03B7E84EB47B065B11 +:105F90005509D7FFD9629E75E9A813D7B17CF3DA0A +:105FA00063A3AF314FBC9F88F3ECF4F3FB829D1ADF +:105FB0009B2FF1357F4F3B17BCA3FB7F2D3B3E94BE +:105FC000007FB74371C5B46CF3CE778FF168E1EB16 +:105FD000B2C1D7EDE7FB73C37F900F1E25E8B0E891 +:105FE000096F9D26E182128081A6696142E38BB828 +:105FF0001F2255C1583DB06FAEB404E3C617FBA3D2 +:106000005208F39F95A63038B50A27DBE3307BA909 +:10601000F6C5F4AF713E2D3EBA97D151FB01C517BD +:10602000947C556EC375AA173B27BBA8BABB81C128 +:10603000D781FF642ABCBCBFFC4CB43B64E07A80CF +:1060400049982E4F44BB11F031979CFA80FD498747 +:10605000DD9976B9F064B73FDDB0687CFD24CEF9F8 +:1060600013EC3FD42F25B6F6C551AB7D1BB0DDA791 +:10607000380DF5777D01F7328E721C0DD6AB187A8C +:10608000E0AA766829AC0F5A09DE07F2CE9701E341 +:106090001BB5E048C2A1E7C77B275BC2B85CA52C53 +:1060A000E73017FAB9FF2774451DC5E1EC8F302E94 +:1060B0009885F957B2EEE3ECF72D56D5DE4D7AB25E +:1060C00083F113C69B246A1DB47FECAD7E4833CBAD +:1060D000D3D7C53819FA832E1BFB64BCBF5AED8891 +:1060E0007A667E7CFADBF71BF9E8EF5B688DFB399B +:1060F00052BAB4FA41C4B18C4FFFA31DC7A0DB58FC +:10610000F9681374FB0AE993EED091DD935955BBFE +:106110009EE8E6ADCE1EEFDEE997AC7A56A42ADB08 +:106120005F464CFB4BE771A7B4DC05E3D0654C7CC4 +:1061300015EFC7E9E77EB4D592378243ADCEE1577C +:106140009E1630E018E6717C73F784F0DCB8BFFE71 +:10615000CD109E6FACF930FBF9E382008F0FD7A30F +:10616000AF92FDBFA69EFB03F10FF5CE4DFC9F50F5 +:1061700095786B13BE6BB67A9FCF62FF18EB42AE79 +:106180007929154BE9BDC403AF49F4BEBA54B1E255 +:1061900044846B68EE127A87A4BBEE493A7FE98F9C +:1061A0008C4F1723BEB45BDC571F1D3FC779E1DF5F +:1061B000045DAA12CBC89E5C53FE228DB3BA6EFC5E +:1061C000719236FADB53D50131F213DBCE73F70946 +:1061D000B9DDE717E712AEE6F3A686318E2A4EFE4A +:1061E000B10935D121D4FB170662AFF859F99AB934 +:1061F0004BCA691FA15BD7C15B73CC2714E0FD1AA2 +:1062000076D281AAF8FFB9A50E7FAF62DAAC848995 +:106210001EFD39E2DA6B03C6B99787F639DD780FD0 +:1062200080C1D75F5E18FE0D3A9F06CFA9F8CE7ADF +:10623000778EF85E23B5AFEFF9F06EC7C31AD7308B +:10624000C53FAD91B2CF674180E37BCD2D697E9E86 +:1062500036F74D3A4FF3A75FA5B889FFA8DF4BE7A4 +:10626000697A809FFF04FCC3144F5A3487BF0F988C +:106270004B8E527E5E5FD6ACF5401EB69E0FF98DFA +:10628000F39EF1FB33E00475989FF38C954B5A7F96 +:10629000EEEBDFB687DE5181349D2774FFC2496F74 +:1062A000C11A7818235749FE3B316B241EB7BC2016 +:1062B000D0DA8DFE9135C6F9DA2CBE4F92EBD2744E +:1062C000BEE60DE8167BC71F31DE492C6C9E45B833 +:1062D00016D573B580EB2AFAE111BECE5917933F5C +:1062E00037175D6FF2C5EA03F5667F3EDF67FDABEA +:1062F000F1E1DFFCBA252EDDCE8F6EF8B723DAC7C9 +:10630000E5F22B1F10F269BCA36BB45F1C50B2E323 +:10631000F7D797E4C3EFE2C0846CF83DCB4BFB8822 +:1063200075E39FEF6CB2E9EF4D469C8D78D797F5FA +:10633000577E7E167BC258570F048CF77C9ABD3867 +:106340004E55A2D68B78DA965C44F96DB78E4F4FD6 +:1063500063FC2D42AF6F15EF9018E55B055FA66CEF +:10636000FAF66521D75B857C6D53A35E8C5F82A7AF +:10637000CEF24E67F80B33BE4057E2F15D2325E3C2 +:106380008DAFAFB4DAFD477ABF652060F5D7167AD6 +:106390006FF368F1921271352F07D224F7CE743162 +:1063A000C9537829903C85632369DC37550D3852F1 +:1063B0003AC5AF347BA733928696CA3AC5B2897B79 +:1063C000B0278AF51D9C2B1DB87F09897BE48C853D +:1063D0002FA338983BADBF07B24D8D342A78AEDC81 +:1063E00049118E104E9A7EAF8240B2FE1E4868DF81 +:1063F0005BF47B2A2130D50B1F3DDEFF2BF0F1EE45 +:10640000CB1E353FCA231EB33E3E5E82E66C7AFF4A +:1064100017C21E3BFE969D12C9E5357E78DDE4A7C6 +:106420004949232588DF2D2BDB25C467A2132227AA +:1064300064D1636F047C865ED88DEF2EB82A397DD7 +:10644000BBFEEDE2E12798CADAB2A211B2ED3F98A5 +:106450005E782340EB13D70B5B572EE2E92127F13F +:1064600049751252F83B2AF307626D2EA4FB52FEC7 +:106470002E75A8333E84F9F03510D159FF55E8D474 +:1064800067E356B7402A4A7C042F8726E2EFDDF007 +:10649000BFC9C38B87BECDEAEF99E3D6F07755E04D +:1064A000062BBF545C63FD7D95EA4E2BBF4CB4F1C7 +:1064B0008BBD7D581F390BE19D9A7400EEEB82175E +:1064C000DAFA83E11DF7E17C76FB2369066F75BF7D +:1064D000B5DCDEBF0C317711A3CB23371FEAAD61EA +:1064E000F5EF4E3696215EB6A9C0EF5B342B74BF34 +:1064F00035D73BC463F8D6B0FB0B7CB7D858F77AD6 +:10650000F649FCDD8B29DA6B61F46BBECC7FC72EBC +:10651000F38EC567E81D8BE320C6ED478852DA2964 +:10652000EC53EDF4CA30FA3F93BFF669782F4B2B4A +:10653000B3FACFE4D2267A1F6CD4EE2E6576372BD1 +:106540004F9658EDCBD38B389FCE2EE2F6A1E6E3E3 +:10655000FD801A2F37BFABB4B148B296FBE3E51705 +:1065600098CAE71789F767C5BBE30D450B7A502F2B +:10657000699358FD2CFC79A618D7288760642FBE34 +:106580000772FBA58BEACDFB8B8D45FC5C473B5E20 +:106590008C5B991DAE64988F7B9B18776391F10E8D +:1065A0005C9CBF03A7F1D4F87E5B6089F406FB7C9A +:1065B000C0058D18A7D231C141EF43DE34D1880721 +:1065C0001B5F4F187418C5B7C6E3902A96F27B97E5 +:1065D000B9DA6D6EE2FE41FBF7989847E7D2C681C3 +:1065E0006A36FFE86E203E710721EBF90F93EF58F2 +:1065F0005136BBAAB389F671074AB2FF4EA1917614 +:10660000D8D67D59F813C7D41374D25F0A118B778B +:1066100086B87FEE4089234AF7026B81DE3B3B5010 +:10662000CEFD75F6F6BDB6713CB0288AEB349EB34C +:10663000623CA3520D293CC8F10607B4B08EF101AB +:106640007BC94FA303C3272BEF8E00D9779D216E03 +:10665000C7C8A1810607AE1FD0A499EDB10AF17B8E +:106660008B1E7FACA3C812479220FD7BC095223DB4 +:10667000D21176C0DD59FC886B8AB89DBB595FF496 +:106680007C380BFD3614E916FBB9E220B7BF73D591 +:10669000CFD4E3708DF263284EE73EA0737EBC300A +:1066A00010BDBD689C382EC3EF78C51CA17041BFDA +:1066B000E47FD83CAE7AC64531E9A71DDABAE7DBFC +:1066C0000C4F4E714ECD56E53D4FB0F2AFE0BD27B9 +:1066D00096BF6ADF0C650A2B7FB9C2898B30FB6BD2 +:1066E0002EC271DF054713CAD3BBF062D1C926BAE7 +:1066F0003D5224ECD0A48BF4A6E18FFBEA80CBA220 +:1067000057AFDC64CD2F814513D14FB1E45617D973 +:106710002657D9D6FB6D62FE5742BC1BD7CF2E1130 +:106720003F7EED0F66282837579DAC859DA6FB560A +:106730004F087ABCCDF84737C9D9D5FE9482FBB84B +:10674000D7779E7CF16701FB497557E0FA59923D76 +:10675000FEEFCB492B9CF9E66187DB38BFCB058781 +:10676000BC5D8AA6B2C8D9B34556BF5087CADF47B9 +:106770008A76C8E0F93CC6DF01C94F625F80DEF36C +:106780004E34C6299E2ED1EED63A82145F477174DC +:106790002B18C1F03DA23F08FE33E2E900E2A7E278 +:1067A0003EED5A7558417FF47239DE843FA5669CF0 +:1067B000C3B85DB1E82406BF6B57437A1258EA2587 +:1067C0000BACF78C545550BD26C738FDBD27F4E4FB +:1067D000D30FDCA3E0FAF3EEFDAF9D8B72B8EC7142 +:1067E00027E095BCF71E08409AF60F2905E5FBEA5D +:1067F0009DCEAC7E36F2D4323C2EFB5E80F4E2D5E8 +:106800000FB9530B59FBAB1F7D7D2630797AAF7DD5 +:1068100064CF24C4DFFD123F1F4C0CCFC4F5E96ADE +:1068200019FE3DDB3B64BE62CE5FEF3CE66B41FA96 +:1068300049DB87BE44FD0E5EE232BFC7EE28E6EBC1 +:106840000FABC7E3257748A913B2E80F633FF4CE37 +:106850000E89C3B7CB95C250E0ABB7DFA5C4181CF7 +:10686000CBB7BF4FFC72FAF71E2C423C2CDFE5B4CD +:10687000EC2F977DEFC3EECF303A2F73C2C842940E +:1068800063E721CAEF8FAA234E926B1E9F721DA948 +:106890000056EFE1DF9FF93FACFCED901330B4F50B +:1068A000EDBDBF531EC77CCC1FC75F1459BECBCAFA +:1068B000D7CBB7BFAE205C9A03462A3F8BE79C56E6 +:1068C0003BC95E1F6044413DB57CB0F77D27E3B70F +:1068D000E53BDFFD15F2DD729B7CBC8DFF281F6B55 +:1068E0009F9F5C6CB3CFB797151487B2ECC1FD5B6B +:1068F000D01FF1CE437FDC82F767AFF9E82F5BBE94 +:1069000081F1603FF66828DFCBEFFF451198F4FE78 +:1069100039C55CCEDEDB71DF7736B3F9BFF7AA9BF2 +:10692000B0F5DE13BF9F82FE9FF7BEFFB789E80F69 +:10693000BAE189338E43FEBAE111FE7B36B9E040FD +:106940007E4D997F6F519C13E9BBC81803F891489D +:106950006DF480811105D7B3BF4A30D257C2BE0F44 +:106960007EA8A07DB6270A23889FA776BEBEE766CD +:10697000967F97D1C79D853E6CFE931CA49F99D8A6 +:10698000B0F4BA9D179CF7B93A4C5D11EC7E398C86 +:1069900090DE1C43D797185DEB3274B597EF8743B1 +:1069A0000A9E1B2C7F80D17126D293D171E6583A72 +:1069B000BE8BFF983B968ED714DBDF6FB866EB6615 +:1069C0002CDC5996D5DE35F659D73E72D1B8F69300 +:1069D000A117F2E179A9F093CC298EAE2C46397C2F +:1069E000E8BBDFD91CE4745EC810F3DE83FBA7E0CC +:1069F000A31C7F708D7C09F130F2845BC3F5FDEA46 +:106A0000277E49F2F6DE232F283AC5B54091740A55 +:106A1000CBC3E8DF8BC0F2D7493C73EDBD7F3FF3BA +:106A200057ACFDB5F853AA1AD18FF27B98FC113DF3 +:106A300052E737E9A877531368DED7A5B85C5C97AF +:106A40001ABA10E3F9EC787F44E817335DF17DA9B9 +:106A5000EB76BE7626F25F2E7A1AF3D770FEA7B2D7 +:106A6000F27BAD729B534E057DDFBBEB8082F6411E +:106A7000FA714573307BF83DD78842EBE3F79DDA36 +:106A8000B6C858BA67F02FE28E8E701F3E586CF36E +:106A90007F08FCE493F3FCF33A32BC6D29D62DFC5D +:106AA00063E0EF9D43D9F5FFB3C5DCDEBE0EE24DDA +:106AB0001553C7AE5F323427268533F0BE8371632A +:106AC0000CDE77EE77D23B7DDD834F911EB7EB8BEB +:106AD000EB72D8D1FB8CF1760DCD44BDF6CE938F01 +:106AE000115F5EF7C06B0AEE57F66C7F5819AECD9A +:106AF000C801AE0FE6DF297BE77F0DCD44FDB53C35 +:106B000047FCDF5BA2FFE53FB2F6BFFC81F72DFD3E +:106B10002F4B0C2AF43BAF79C6795B8E5E82F37DF6 +:106B20007BAF0B703FFCF6A0B3299B9DF3DF627D2A +:106B300034F0D41D38E595623CF72AE5EF3276B69D +:106B4000457F89BF379C78C125F6B7D157D09EE9DC +:106B50002851E81E4267E062F2D71BFD0DD8F0A96C +:106B600005B506DC0768F39BEBCCFB2A03FE92A875 +:106B7000C302FFFF03C228CF4D00800000000000C9 +:106B80001F8B080000000000000BD57C0B7C54D547 +:106B9000B5F73A73CE3C42269393D7E4693C4978E3 +:106BA0004AC02109101ED58120A6986A50AA5CEB24 +:106BB000D50121444832292A5AEB779990885EF012 +:106BC000B3B1D28296B60317AA95C40E1034B6811B +:106BD0000E606950B4019F7851A3D68A15C8180574 +:106BE0006DAFD6BBD6DAE730332783D0EFFEBEEFEA +:106BF000F7FBC2CFDF769FB3CF3E7BAFF55FCFBD54 +:106C0000CEDC91529DAD3901DA560268A30040F105 +:106C1000E4D4A600C8AED9D59089AD6A519324803A +:106C2000AFE9EFF2680B100498086075D6820F9FE9 +:106C3000B7AA16D01CC07F5F03CFD3DE8FCFDF256E +:106C4000A7B4AFA179ACCDBFA43EB428B0B58287BC +:106C50008D562AE8FE259E354500EB93FFED71BA6F +:106C60007F77C0AEDAB16D4D59F11BEAFF4A825A07 +:106C700019C7B5D2F3D806AC0E75AB8AD7D3607EF0 +:106C8000C8195D4FBE2AF17AC6E33AA8C53F1F4C2A +:106C9000C2F78A25412B34008E80A4CC60805AE351 +:106CA000B97F577D25EAC4685F76F681AF14E00AA4 +:106CB000D969A1FDDF9F6309DA8BA8BD36154A8724 +:106CC000D2C168EF5B590BE151E7BEDF9EE558B0DA +:106CD0000978DD010BCE1B901CC1ADB4102F68AA42 +:106CE0001B786DA0E17F484347CCBA718097F6A12D +:106CF000E8F7ADB82DBA698700B749C4076C93218E +:106D00000C500270A55A0C90059002FDFA2411A8AF +:106D10001D07302FC5E7A57D660FF749342E0BBC44 +:106D2000DC5640AD44F72DC937E5FABE617F304FE0 +:106D300039D13F5AE72FBEE25756417F450165588A +:106D400019AD63A3FA97B1380FDDCFA051015EC72B +:106D500084AAEBC7B6111C68F131747E78D6CC0CCE +:106D6000C28D31AED551785442BA78E52435A91098 +:106D7000FB0A5286F87D2C85E9F4A3E93833DEFF5F +:106D8000F1B194CD32F2E36149E0294078225C41CF +:106D9000F3E3840F17E2670D3D37B3F9378C170B18 +:106DA000D4B656E8947413FDC41FE28DF174B7E2B3 +:106DB00050ED1EA2AD5753681E1B04D748B45E1F8A +:106DC000D3D301EDDC0E8310B74EE8E37605D1791D +:106DD00022F1C1C3FD54E86F1F8ECFD5A8B50D2A8F +:106DE000EEE7C7D5E912EDCF09AA4EDF825C9FF32B +:106DF0001BE83B0BE9EB88D2D74EF44C1E4A4F07F9 +:106E0000A84C87340F78D64CE079218CFB78780633 +:106E1000046506910A2AE2255BDF6786CE67C20F0A +:106E2000ED2F6BBED89FF97D39D0CEE3F220C46D33 +:106E300001F4719BEE502585D7734CE7EF7BF0751D +:106E400072743D466B2704E3FCA70B70FE22A6B6C6 +:106E50004B72D3FE8DBF5AC6E11F2AF679AB709CE8 +:106E6000E2737AEDB895FF5D31934008D68B15201B +:106E7000BE3AFB17D4800B877B6C101E4DB307788E +:106E80007D49A345DFD02F766454D8583F3E673DF7 +:106E9000F6D1317ACE0A31E3681DF24DA944F78765 +:106EA000E8C294A174BFFB584BE67331F36E5153A3 +:106EB00032699F3019267F2D479F87CA7480DCA1D5 +:106EC000CF7FBE3290F99C354A8736C7BF312EBD81 +:106ED00008E0A4CBB04F38CE8CE21871C97A2EB03E +:106EE000CAAEB666320E19A7772381ECD87E9E54BF +:106EF00018E4FD43F3E46B510F5B1C5E49C2EB0DDC +:106F0000AA2B48F469748666B39E30E98D19F3D4D0 +:106F1000701E8E1B68060FD175FDCE6B8E135D073C +:106F2000DCA0D9D3042EBC93484F187A043419F945 +:106F3000BB5A9AE090B06DECFAE4A5DFE1F8A41E2C +:106F40001964BC3F807BEEA37D2BDE346262323C51 +:106F50001827DFAD0E213FC63ECDF2FACFEE133932 +:106F6000CFF3331F64D2BF0FFE3B3D3F0829ED3402 +:106F70007E8382AFA6F97BADC1AD4887E50765C6C4 +:106F8000DBF24E2908C467454BA5FE5D2FC820F0F3 +:106F9000077CFFAE5F96301E6518FBA3E9F8BC7F47 +:106FA000A3D5831A13D2BCF1F62AA37A1868313814 +:106FB0008080F7480ED26B914EAFF5C90F6DA2F5E8 +:106FC0006C6811F629AB363D6EFCE74957DBEA7079 +:106FD0007E2D17D7359570D3337235F697E5CBAA4A +:106FE0008C2A227B7E5EBC7D6CB7BE47F2A7E13F58 +:106FF000C2B7A1BFEA487F911E92EF65FB771AE9FD +:107000002593BC80B07F4DA8AFC238DF920DE279E6 +:1070100063BEFA9E8757E7637B5B30FEFA3250A26D +:107020007DB6B3AED1A407EE86611EBB3414FF4A11 +:107030001AE29F40E204A7E083D343FA65F015D932 +:107040006317A4607925BA931E91FB47AD9F8EF319 +:10705000F97BAD10D4885FE2FEE0463918288ACA71 +:10706000C760EF4EA6C7925CA407E2D39E134FFF02 +:10707000242D9EFEC9A3D3BF911F291E133DE51ADF +:10708000A63FD21B68FED4CAE2F8E7757A8FC67FA6 +:1070900082DE5E5E675DB7048F4944E7070FE46BED +:1070A00043E9DAD4FDB08DE4FF7C7435D3715C9A8A +:1070B000AE47743A9E869EBD3A2A6B1D6E5625BC1D +:1070C0000F456D9F41382D40B9259C98E5DAA09F6A +:1070D0003553F5DA70DC45340EF797E7080961F4AB +:1070E00080F232E165A1D0BBADAA97ED91A16F937B +:1070F000CFEAEDF7E16B6C33E7563C4038BA5D4AB6 +:107100006967BFCA24B76BC7AD60FD55B00AF531DA +:10711000DBD5783F2DB4D2E15984EB796A25781616 +:107120008D00D8B152E5D6ECBF19F2BE11FD37BBC8 +:10713000B0CF3CAF82F85DA392FEF1A8B4CE876CCD +:10714000C0723A500AC1CDF8FE50F83337F9A30F98 +:107150009545AEAE457FC4BF186A43D86E4DB7B0F3 +:107160007E7D365DF877D5E9366ED7D45AC08BEF81 +:1071700039D52307255CDF29D57BF072D23B3D56FC +:107180008DFD2B35F2D2F7F87EB9BA06E9996B6915 +:107190009F40EFC5F1D5419C77A0E77DD7AD317613 +:1071A000F954F72363C80F7AD402F5A104FE5063A3 +:1071B0009A78FFA9D1EFB971DBD0E888D800F174D3 +:1071C0007F7F732DF95B77256B7CDFD635239CCFD2 +:1071D000F899CBFEF17375C3186FBB4E4090E46E07 +:1071E000B67CD355E3B03FE555C56367A1F25EBDFC +:1071F00060120F61BEAFFBB27C03D1CF8FF45CC5D0 +:1072000017DB5F267E3DFB670548EE2A9A9F7EDFEF +:1072100087FB3C908368A80498E40D958771D4ACF3 +:107220009EB41924DFFE63C0F23AB14F89C32DC862 +:107230000DFBF349AFBC21DCC3C96F98EE43402678 +:10724000FF7F4A7FFCF569E7C1FB5A03EF2E7013FD +:10725000DE1F5BD90DEF935DD4ED671E6E30113DDF +:107260000D7C3F933CF39134F6274026DC7A94C49E +:10727000E3FF9C2E310ED67D294B84CB81087856B6 +:1072800021BD0616E5F1BE073E23870CDB2FE5EA9C +:1072900050027FEB89341B3FFFA84DE0FED13A67D7 +:1072A000B005F7B3AF6EE9C5FDF8BE333FF05DAC96 +:1072B0007E931F8CAAC552C9FC4A25BADF3EB74D42 +:1072C000623984F65CA29B79BC212786DC18F29295 +:1072D0005B37CC174CF09ED1FAFE66D68D966C8447 +:1072E000DB3D12101F4FADC2757D83FF188055F92D +:1072F000B41E7FF7A736B2D78E1EC91B4C30BE37DF +:10730000CD25F0BB2AD0320DE9B562213E4B72612A +:107310006B2F4A347F00D6E5A37308BF49D3785D4D +:10732000A71C700BC92528EDB964B74F75577D9B15 +:10733000F4FA632887E4373C6AF5F0BA038D28B382 +:107340004416723CB15F70356C5A1313471E499B4B +:10735000F1761AAEE3ED3495E7CDF079245AB7E72C +:10736000ABCF5D34FFC01776E65F1EC9708CDF7649 +:10737000264DD0E78174EF1B8C97FA4C56A61E9FC2 +:10738000CBB3A81CE0D26EA4770C2EA37C0BF073B9 +:10739000E9BE00AF27BD0F03278EBFBC1AF9CB7E15 +:1073A0005D394358026552543F57380AC2F9227E6C +:1073B0000865237DD3EB7FCCFA3A09F530B9E2D0EA +:1073C000171F17B146C6E749F6492FB4AAC2CF6ABC +:1073D0004B137AAEED6125D88AEFDDA8F4278DC076 +:1073E000B6C8ABCD5434D2F7A53C6FCE1DC0F26DFC +:1073F000710425D243C9253F4F3BEB774D03D8FE9F +:1074000095CCF437F3695CBA4117DF574497F1BD67 +:10741000917DE4BE79922083F83A5B76F2BEA79C18 +:1074200014FAC7AC6FE4F02F1F257D33A0C74F09B6 +:10743000F4CDAD645F0D7D0372E97EC2CFB417F465 +:107440003053D733187D301D261FF2B53A13E89715 +:107450004AA84D45129F57BF98F988CEFED97E01A4 +:1074600012A3BC17E528E679B33EBA283D5E1F9DFE +:1074700086E9D9576851BC94DDEDD96F8FC187A1DA +:1074800087A27809B29C98DF2381E36C5F2D21FDF0 +:1074900071484E25BD3303F98EF33FAFCB49DA6710 +:1074A000C16F13FFD7F55C9944B8DED15BE520B11D +:1074B000599E236B7F46FF59D93B2F003A5C48DF2A +:1074C00019EFB58243738E267A58980EB28AFD98CA +:1074D000F70FB64BD5A4179169A9F3C69D5B1F2C76 +:1074E000CFB1F17B76F416A7128E9C80F12DF2AF0E +:1074F000A247623FC18C6B338E5BF105168E1B6B0E +:10750000D99F90A5909E77888F4B8B0253D84EDDE4 +:10751000817138F9AD83BD68B7B0DD81769EFC948A +:1075200056E76CDEB7B15F637D77A4CCCC86D2A181 +:10753000FB375AFF1732043362FA4AC44638F67FE3 +:10754000618BBB6ED0F35C7430E83995E829FD9F00 +:10755000D3F35BE91AE3C14CD7FFE9FE0B96574220 +:10756000A2BCC0FF2FFB9F06BEDFF58B78EBB51CDE +:1075700077549F142CAF9697201D26913FEE89EAF1 +:107580000707FE237C8DEF6E677D5389FA86FCCC5E +:10759000FC8610EB97C939225E32EB8D4B7BE03ACB +:1075A000D28F53C2E8975E80FEF88CFE2797F3389F +:1075B000C174CA43FD71FEB20EBC345E838C1A7C6A +:1075C000CFF83EC543760FFA3212E605CC76C3F00B +:1075D0004B0D7FD43CCEF0470D7BD2A4D3E170BAE3 +:1075E0002F44EF07550D90BCA15C851EF330EC35A0 +:1075F000F2178EA4D5EEE4FBA343018E038A41A5C6 +:10760000BC0ECA2BFB61150E67581E3F543E934DAE +:10761000721842BA509E20E0B404474843D781EE26 +:107620007680FC3E7C80DF5F9F2EF2A50538869930 +:10763000D604ECFF178C071FD9DD82326C719F7F57 +:10764000D2ED4A9F3EDE6871DD07D329FFAB40C013 +:107650005EF6CFAF9796985F46F4F1FE91E67154CF +:107660007B79FDF92A78C88FCF57429207DF9FDEDA +:10767000A049679348869DC6F9F26B34B697F9C363 +:10768000B14FE3C9DF49C097F7D2ADBCDE4647FF33 +:10769000011BD2C15FD35CEDB244FD74BBD5E7CD15 +:1076A000A7FC51B7F0D781F27D9C3FF648B41F6527 +:1076B000A6A08F5F15F1951354D69B153A1F2B1C6E +:1076C000359CDF219B689F3274DF92E6E5C179F338 +:1076D000400B4C89EA5523FEC16980DE63D6AB03BB +:1076E000BB5FBF2880F2F8D6FFFA3405F0FE3B4AB4 +:1076F0002485E871FCDE9753BC488FB7EE15F1CBBB +:10770000CD26FFC89621F8539751FB15D1F59695D4 +:107710005F4D8AD52F707716CBC56D419982E1B345 +:10772000F2B3EC8964CE3D1BFDC650465CDF90830E +:10773000463B3427F2AB2FCB10F1D96D1D9B6C1457 +:1077400047D765F85233F0FDC775FFEF78570AE762 +:10775000038CF52CEC9860237ABFD36387302BC859 +:107760003EABE0B3F76A691225EFC59F799D07F636 +:10777000E4DB2C38DF62092222AF05077E86FD0F8D +:10778000726458E319BA8FC56FA936CAB72F9E0124 +:107790009100CAD5C23BA4D577E1F8853E27797020 +:1077A00043F6B920101FE72FD1FD955B1FB09AE279 +:1077B000A4E603942F5B84F3503CBBB83DFEFE600F +:1077C000EFED077E4676A0DBC67660C979E2A7F2C8 +:1077D0000C3DEF3209267F5D42FE4AE98F4AB573C0 +:1077E000EB25C35F39BE12083CF0D7950E6E4FAC47 +:1077F00054B9FD4AD7D7CBBAF71E605C2B7D93C82E +:10780000CEEEE87D3FF9462D6A372EDBF4E9FE9F88 +:1078100061BF9CF65944FA326C253C5EAEDB8D2587 +:10782000BA1F52FE85D96EECFDC3EF28CEC6FD6FA0 +:10783000E588EBC2FC919B40F92C960E861D31D356 +:1078400063B0B724997072BD41173D1FFB3FA5CBB4 +:10785000B99E6B9411D709F487214F5FE979874569 +:107860005BE6AECEC3F7B7EEFEB0B05FE8A5D7C01B +:107870001DC52B2A7AC6DB1280C81AC4A7AFE7073A +:1078800007884E07086F95D4BF88EFE754217E51D3 +:107890006E97F47CF4268C67F9CAB1E4501BCEA134 +:1078A000F8D28C4333FECC783B65ED2F24FD60C6C7 +:1078B000D92909E627DA577D8638BF58A479675356 +:1078C000BC8B666DB5CAFB11FAEFB8D27EE0872497 +:1078D000B75B248E0F1B9FE97C9AF4D1D2DFFCC4E6 +:1078E00045FAE823A5DD4DEF6BD87A9FCB4B7A495B +:1078F00009B8E8F98F82422F99DFB747A7A3712E05 +:1079000070D62E3D10597D0FD2E30CCA33C96F5388 +:10791000D7DF56DF437186D711A1B8F3B8D23F9BAA +:10792000D671DB0267738B87E2DBF87D2F7DFC2746 +:107930006E8DF3C7817C9D7E1CAF366DB17AC238E7 +:107940006FD32BB2875EE38708EFCFFCBC3FF4BE5A +:107950008DF4B76A8148C1B4A1F7918D36921B7F2F +:10796000D7DA4F6417B5825F7EA273CC3943BDAEC0 +:1079700087CD387E2A23FE3C01E9C3F9D400AE8BC3 +:10798000F2471014FAB8F5D7EBC7BF8BEB3BB1E564 +:107990000597541A7BAEB08AE93618BAF5970ECB24 +:1079A000B9F17B4AC77BD46F09F2735AB7240E83AF +:1079B0007A44DB600DBB286E6BD864F504F072432B +:1079C000A70C0EB25F47EDEC3734747ECAF86C90AA +:1079D000BC1169026FC325C5F811CB3A3F984DFA27 +:1079E0007659AE0C3528524B779E16E3BD1049C22E +:1079F000F1CBB6BF3BFB87D447BC3B12F0AB2AB4FC +:107A0000D726E4C6C4AFD0BBB3C91F6EFDF5E7CC23 +:107A10008F8FF648905D34F4F9FA4D1FD8C89E9CBC +:107A200040C664A4097A91DDF087E405B6D444FC2D +:107A30000B5FFDDB0ABECFF9BFF3F1F1213A6BCB4F +:107A400062BC3FF55B5C47FD9B764F0DBDF7A9DB44 +:107A50005D8038F8506916B8FFF97D6EB2C3F5D66F +:107A6000805BE5565CAFFFC59D8CC72587EF748BA7 +:107A7000F8C69B2BF245815CDAE7E28DDFE57DD627 +:107A8000818FF158FF73B996F234A715A8DE9E4096 +:107A90006E26654AFAF9DAF7C7DF23CE0380E2F3F0 +:107AA0000FF5BC69E088CC7E9B1DAE4D9D1B937F7E +:107AB0004ACA14F63800C1B7E95CD58FE695CF41C4 +:107AC0000E9F9E4DF3DC51A434D33911EE3FA0D369 +:107AD0004BFA9AF302A029317E56D5E12BB2292F19 +:107AE000668741DBBF56B05FAD91DF13F31CD3ED6A +:107AF000C3CDF661D2A5D8BA13E74D17EBFBC0BFD3 +:107B000023108327FF131F329E00ED776A8EE83F14 +:107B100046F2B8D0D99C8A74FBEC95F76D74AE151B +:107B2000C0FD8CA0F5F67DC07DF0646934DE98DF81 +:107B3000DF6D8F9E07925C6FF9C024D7F1F7D17E7D +:107B4000333DFD90AA51DCF6A12D329BEC7900DF8C +:107B50004BF50575EBEC71E78D51BC98CE1775F9B7 +:107B600034F29C4B4CFE98D19AF5C284CC78BB067B +:107B70001BB3129E2F9AE390066BF057449F86A387 +:107B8000768E5F1A3A85FCA1431D1981F2F071C708 +:107B9000FED76EC47D7C1CB266D6F0DBE2F56DFDCF +:107BA0000E945F1C2F23BD9358DF7ECEFE94618F11 +:107BB0003E76E2C57109E416AF27945B27B03EFB21 +:107BC0007FA567979C43CF7E2F73889F908AAF8154 +:107BD000BF3EB9EC62F22FCCF435F4AB596F9ECEB8 +:107BE000D012EA4DD0EDBC41C7A5DB4E326ECFE4DA +:107BF0008AF3A6A62D7F633B86648DD811B74DC14D +:107C00004FB87F1FD931EEEF9D278D4FB4EF787AB3 +:107C10009AEF5F4CBC65B989DC4C74962D2E8FC8E9 +:107C2000CFA97C9EDF4A7693F4B4A602F111664296 +:107C300088FC0EA9E78F7FA3F799E38AC04C18DD73 +:107C4000CCE7BAB036B63E27A4E8F51481C4F539BE +:107C5000ADB6E8792EDD3FD779EE715DCE3D4E951C +:107C6000CB11AC999A9CA8AEC45365491847ACCFC8 +:107C7000147ED608DA33B67FCAD4C4B9BA5CAB274F +:107C80001A45BC443954D67F692E3E0FB6EAF51921 +:107C900038730E9F1F245B3E4592C0CE7573E72854 +:107CA000941F2EB7DC5E82FDE7D72D9AA3207E3C81 +:107CB000D32C3B8BB17F68DD6271FF524BB915A1AC +:107CC000FF78A06ECE2CCA1B58DEFD29ED4F59A5BA +:107CD00000D58F94B47DC0FD3BACE2FCAAE9D95D30 +:107CE000F5F4FE26091981F46F73859AB98E210780 +:107CF000D455943CD676FAE8FEEA5C8CE7911FFBFB +:107D0000527DDB33C9AE38C22EAD98E24AEFFAEFAE +:107D1000E17DE588956242DCA7C8838FDD392D8738 +:107D2000F4EEFF85F7EFCD9C78EEF79FD871D57C08 +:107D30001A3F560655C6F9CA14AD8AFA768CAF2991 +:107D40006E33F850A608BA973A6D1CCFB5A5797373 +:107D5000084F7FCA34F875616DAB55F8A572B2C093 +:107D6000819C6A69DE8EED6B3AFF5FD7E9417F94B3 +:107D70001718D89DBD99EB56205248FC95E5CD9D2E +:107D8000448F488B029B29FFBAFBF14EC2E7EB36CA +:107D900007E78F6E487DD07A092EB9CC51783B81A8 +:107DA000FF4DA9E34E6A7F9FE57B2F53D4878569FA +:107DB000DE1B6F96C5BCCEE614B29FE045B91279C2 +:107DC0001AF6DFC18772456BDE8772358154417CBC +:107DD0009D93791D726A07AFE306BB58C7FC6071BB +:107DE0006B3FAE63823D7811C557F8FE41C2C18D2D +:107DF000E86E119E0305D04B7C7BFD964B3789FDC9 +:107E000015B0BCB2FCF3F9FB89A7683E3FCE4FE743 +:107E1000A87EA99FFB3B15871A50857E5F1093773C +:107E20007B16DA5F2E15F9FD568A3BA6E971B191F2 +:107E30007F33EA0D26F7FAAA9CA4B0E51E99F4CA8E +:107E400069F4D7488F99F36E534CFA775AF7C7AC59 +:107E500097CF771E9892A5FBBD799047FB08D17903 +:107E60002039BCBA9DF4D0796002F98F390FCCCAA1 +:107E7000BA80F3C03B33455CA1519D1CEE631027D3 +:107E800026BE0D1E5A0865155C8FD00C69E7B6AB8F +:107E90005D26FD6FE07CDC2BEAADA4CFC6BD02B74A +:107EA000D07EAFD0CF4F068F03D7034EE877707DDB +:107EB000A0B5D71A0C4A31F528472D5C8F32089EA1 +:107EC00020D7AF04EC6A80F5E578AE3F693BAA9F06 +:107ED000F7EAF50CE58264FF743D84B9FE61AAAB54 +:107EE000525E50C1E73320550EAD7F982ADF2493B0 +:107EF0005E8143829F67EB20E45299F6753A0C400D +:107F000021DAA45762F88DFF4DCE0CC85CFE742CAC +:107F1000FEFA54132ECCFCFF4E966E8F75FE9FB367 +:107F20008EE42391579B00E3B98EC46AAE2379C3D4 +:107F3000C2059BD13A92F220C9DBA41691373E5F6D +:107F40001D8FB94EC75C8793EB8BA7537EFD2571C0 +:107F5000F72F6A2E8BEB5F7CF7D4B8F1456850633E +:107F6000FB250FCC891B3FA2FDDAB8FEA80D37C652 +:107F70008D1F135C18777FEC134B13D6BD1838197F +:107F8000175A1E777F7DF253EF13BEDA726595FCA8 +:107F9000F94BBBEF31D5C54C675C4C35F2F03AFF7D +:107FA0008DBA3A2A03233A4F44FE3F56447ED3BD4E +:107FB00055923614079E7080EDF83F8B83874C38BE +:107FC00030E4FF7CF99B75BADF2327154AE4E77894 +:107FD000D1AF4A9A4675C4E2DC1EDE12F52A9F270D +:107FE000FD83FD224D7279E0327AAB2A911F7457DE +:107FF00095C67ED05DC30AF752FEA0FFFB2E8F947C +:1080000037B42ED45C079AEEF04E012EA115759070 +:108010006DA8E8B95E77A683FD8C872C965B6A63B2 +:10802000D6DF9125F44F4796B05B3FB385B6931EDC +:10803000501CA0B6E48AE7A9F801A8B207F9E2CA81 +:1080400000511F0647D7CC9A4EF6B37FB49646F53B +:10805000B3D8BF082F2B41B62737B62A1CE7AD4A45 +:108060007E8AED499922ECC90459D80DB423BFCDBD +:108070009A4876ED5EABF0B30256E24FBE0302AE15 +:1080800032B6AF7C4E9C0699D2F252AA4F3D6BB7E6 +:10809000B4AF114CFB974EB3109D0617C97C1EFC64 +:1080A000122D09D73B583F86EB9C07CFD6FF69A915 +:1080B000145F0F2E7AE4E49D1551B93C6A4B1CE71E +:1080C0009D2FEF56BFE991143A47393A1AE2EA3345 +:1080D0008E6509BFF158962CEA13821FB8894C03AC +:1080E0008BFF6B242DDA2FF5AD76E290FB377CBF4A +:1080F00096F862EB9A1BA0BCA691C73F1B07F6CC73 +:10810000E0FA6D235EBAE17591D7BBE1BFE2F3D629 +:1081100027B3AC7CFF24BD8FFC9A5EDF44E2DB35E5 +:1081200024109C57F64D24FFA056058DECFE7CDFF5 +:10813000823B0F617FEE8312FBFB749FC65F5B8007 +:10814000F606EFBF0C9E5777E1FAFE9E25D6330F59 +:108150006AADB4CED76E6E4C213CBD9E26C6472478 +:10816000D036C7CC778D3EDFEB372FDB45713ABD7C +:108170008FDE4FEBA1F7CF55A198FAAF81EFE4ABBB +:108180004543DF7B1D78AD7ABD9795EC6409043BD0 +:108190009F26BD7AD0E25903DC8633D82ED9D92E5A +:1081A0000DB4449E5A81EB7C67E9DF764948D7B726 +:1081B00017447EF5345EFF970D3268888B4FD37D70 +:1081C000567756944E47177D9A42F4447F65EB4F9D +:1081D00049EEB6D93D54D7F1E6D26D2363FDFA548A +:1081E000F78C616EF2AB2A2FEC3CADEAC9298CBF4B +:1081F000E55B05FE96FF7A5436E16C79CA59DC8955 +:10820000FED6123E279D2441C2F878CF4AF1DDC246 +:108210000EC4998638DBF385A82BDF7928BD9CD660 +:10822000A780EFE2D8FDEC7CE9C6B15CCFFB46E667 +:1082300005AD93643680FAF7065695002FEA723240 +:10824000BF27A35CF727C7D2FC37FEEED727FF93E3 +:10825000E8B27BDBD61FB28C5C181D86D6D1AADBB8 +:10826000583F197118D5BD529CB6DFC276F20AF993 +:108270005E8EC3A84E83E3AE61853C1E158E6A15E3 +:10828000FA4D7C27817E70AB87EB3D595EEF5685BA +:10829000DF62C449B2C593A3888F0C5E98C6F317FA +:1082A00003E5C75C145819FA0AFD08976CD1F51557 +:1082B000781D189F8ED5F559B57BC2556DE2BC2649 +:1082C000CEFFC47E554702BFB316FFB1DFB9D1D789 +:1082D0009AC47669A35C4A7E87D711263B6EF63B2B +:1082E000A7C1839C0718E27F3EF7D70BF23FFFD56B +:1082F0001DEF7F5EA8DDA9776BE2BC77B4D073A1D8 +:10830000F0308E73F0AF9CE46B64B6B04B7D1463B9 +:10831000519D9F746AB403E5B3C15DBEF6019449F3 +:10832000C770411FEAB7E2FF97689FEEFF9AFCC053 +:108330003E85F937F8DC25DFF81D4905CA2119FB10 +:10834000F081A95CEF3CD02BE4A3335DFBD3348AEE +:1083500033D0CFDC8C4B4C52FA6D6909F6F334E91B +:108360005F9207B7B0478E6E712EEAD0BC40FA25F7 +:1083700049552750606E8CAF730BFBD578E0CD422A +:108380001BF2E7A4E5908BCE571A76ED70E176E10B +:10839000BE0CDFFD84EF65478F4C52B9CE6D532183 +:1083A000C5DFA1F09199EC9F552369279C7B3FFE87 +:1083B0000DE5F41102346DC8E0760CE555F0923FFE +:1083C0002CF679AABB353D517EC0FFFBB7F6D17EB6 +:1083D000B7BD98C47ECBB6AC3E9683C05C80AD483A +:1083E000EF27BF18CBF32127781D97D46A12D9FB4A +:1083F0005FEAFBD9A6C797A7BE90799C31EFB8EE8C +:1084000019B28AB82A0DB7EFE33AAE1EBB46FC4D4F +:10841000DA02823E3D495C17E6DF73A5883BD3C490 +:108420007974E7B0C8DBF49EC86EBB4675AA496A8A +:108430003BA4E3FC9D366167C720F07738A3D78D56 +:10844000F725F5ACE78F2010175C8F97A4B4C3B75E +:108450009CB1F44FE1F586DD02579DC3C21627D9C2 +:10846000098C9536F3BAA2EB047EAFB1CE31EC178E +:1084700077DA227FA17C3BAE4B255C8C01B14EE8C4 +:1084800019A591BF92A48A73F52455F304A4A1EB16 +:10849000F28F87203A07F0D02A382BE75C47382C38 +:1084A000DA77A02C7416EB7E4C60F1DA5905317D39 +:1084B000526495D1E75F75D7AF6D2BA07D093BA8BE +:1084C00028213E1F77CD0795CEBF93142FC749496A +:1084D000F3406B417E253BBC7CDF8D73B44CE17E69 +:1084E00098D6AFD27DCACBA4AAC97370DDA95FA606 +:1084F000F2734D7D56AE3B6FF8C775A9A5B8BF1393 +:10850000967D2B3AB0FD784168249DD356A6FADEBD +:1085100021BC3E736CE1DA7138FEAF9D564F0DE918 +:10852000A5FEC08FE9DC7EE993568DECE2FD6F0C71 +:1085300086BF26FE3E2BB15E1CB08AFBD8D75AF010 +:108540007E53CF87363AD7BAB2FB5D1BE5BFEFC982 +:10855000F61D27FB56D9DD5245749B02EDAD94E71D +:10856000447DC8F512A11CA12F065F19B9B9258653 +:10857000CEAE6CFDDC2BE2BB98E4A64797CF3DE482 +:108580001F61BB4BF7D376EDFD97122DE6FC34004F +:10859000FB381FB80A9EE3BA4EE3FA4050A9261CE6 +:1085A0008D7DCD718B3706678E6C5DDEF5F7FD3CFA +:1085B000DBF70F96DBBDEFD95CB87FFF9F43856487 +:1085C000AF42E8CF7D531DA9DF242F67EB8E8E03CA +:1085D000EB916DAF75B3FFBDED1E358DE41ED70F6A +:1085E000A9D8DF85FE05C9D1AE2221772DAF9E190E +:1085F0004FF9E233BB975D4CF48AB8AD06BE670E07 +:108600002339DA0EACC70C392C2539C4A597AA2218 +:10861000DF534AF826B9B3F5CD61B9DB6501923B6A +:10862000C437E31DF1AD921F52AA22DEF9F9512C95 +:10863000C79D7D472EE17A7624EF8809D4B730BEF6 +:108640003AC37382123E5F610DEFA3E72BF0FD2D5D +:108650005A542E2BA4F8BA9E3AB7A89335F4E3EDFA +:108660006EA1EF43A3B5540F8E4F96E538FCC7D8E3 +:1086700049D1D7EDE80FD6FF74ED3A9487126FB960 +:108680006512F93B2FCA6C07F6E87EF2F23F4CBD4B +:10869000A6435C67FB19D671B14FF79B9F5B99C3EB +:1086A0007DB20B1AF26522B6DE72AAF76EAEA25444 +:1086B0005C6575FB7E6AA7D686AAE8B870FAFCBE30 +:1086C000FDE21B37EF58C25BD7BE6F8FE53AE9A3D7 +:1086D00076A0EF38BBFE1E79FB49DCFF8A3D486F70 +:1086E00048E89730DED06233FECE859301A9FFEAD9 +:1086F00069A897AF59FFF8550A1AF4260202EEBF8F +:1087000066FDD6B5E8BAC0ABD9DE6BB291DF5FE5E6 +:10871000F8AEC946BA0D1CFEBB9BECC9AE57DE7362 +:10872000911DEEB279C712AEBA8A318E4880C7E980 +:10873000D9A26EA7E21CF526CBB3C5F9D6C800AC0A +:1087400025BC3475C96A90ECB4B7EF6AB21B7F419F +:1087500052525EBB6E46C045F152FDAEFD5CA76F46 +:10876000C4D38B41FF936F9A4DF43F9D23E2E3BA4C +:1087700075D6B8F87614846D748EECF7399BC3C83F +:10878000927A93DF715BF726FE6E64E996F8E71A3A +:10879000C84F4108359C273E5E9EADFB29255042BF +:1087A0007E0AE286F324915765CF66E0FAAA5EAAB4 +:1087B000AFDA6611744A76405B6A7AD45F1993EB3C +:1087C0005D4272BE44C767A75EAF14E994F87B8A26 +:1087D000314F887879EA716D137F2715F0729D5EAD +:1087E0003D2D00D73D5509F0FEA7E6944000F75F08 +:1087F00089EA99E4A5AE470A323DF5EF5E14FC27FD +:10880000F2451B65FECE6FA3041945346F84E9B3AE +:1088100054CF1F2E7B22FEFCA261C3E103E42A3564 +:10882000864CE7413A7DCCE73B3BE87F129CEFACBE +:10883000CFD6F308855018F75D5EEF857D97F7B1C9 +:10884000FEBDEA117D7E63DC2E5D6F36E9FB6E08AE +:10885000CA62DFC80AAA8FBE5587891F3C4CA7464B +:10886000C409E1001E14FC36EA199742AD8DEAC82E +:108870001ABB5A0ED0F95B9DEED79AF18404657A43 +:108880002DD1EB86EA37C6DF5FAAD365A9892E4DC5 +:108890003EC9B43EE1775FE8FA50735D4F3858DA6D +:1088A00061E57AEED37013D75F35766DE2F5D4E9E2 +:1088B000FC1BBADE00EF6709EE87E4E942D76BE6FE +:1088C000DF9F0C9C5F0297C4F1AF3AE382F8570236 +:1088D000EA32DADF60AF886B077B8B392F61E0C546 +:1088E000FCFC6CDD8FBE7283F0374F765725933FCB +:1088F000307048F14888FBF2173F73D1F73765BBFA +:1089000065A073D2819EF2B501D4973B7B875FA7A8 +:10891000A11D287B5161BB51FE625930A988FA65BF +:10892000C9255C67A265501C80F3B01D1E3834FC5D +:10893000E552F6D367555088DA72A82C99FC859DCC +:1089400020F21BD28B1519FD3176E5C36C91DF58EF +:108950009DF3FE43A4A7AEDC6EE57CF095D6C84B34 +:108960001487EDEC553C2DD86F7871E1AA24E2F71D +:10897000AF250FB9DD07FA9667D2794D638F55B5EC +:10898000F37AEFDC47F7031D9267048EF7EFBE62C0 +:108990006C27E58936957B88BCC6FBCAD2B447A84C +:1089A000DE157293396EBFF2222BDBD71379C9FF24 +:1089B0005183FB5AEADD349BF4F089DFEEE4BA8A96 +:1089C000814E097224CA23EF7F8AEA7D4E3C7DD80E +:1089D00046E7C1555D87B96EE35CF6E0641071C788 +:1089E000717BBB8DE29BC64D46BF9FBF47A9D5FD9E +:1089F000A8A62DEF727F29C50184C78D7250C3FFD1 +:108A0000DDBFFB193E1F6EEA10751F67EF6F91F80F +:108A1000BE81F785BADE5A061AE37D998177BD3E9D +:108A2000CAC0FB69A8E13AAD651D0F33BE17EBF86C +:108A300036D74D0134DB4A3385BC52BECDFCFDDF59 +:108A40006D3ABE6F3B0FBEC7E6E8F81E036308DF52 +:108A50006766887ABA33878725D3FC670E72F6F586 +:108A60009B70CE76F790EE170C862D5EDBA5D1714C +:108A7000A7BA3FE5EF10FD87066D547732BBE713C9 +:108A8000E6474DCFDE5944EFEF80AF81E8F79D9E7A +:108A90006495FCE09A7EA1CFE6F4D8F97CE23B1025 +:108AA0006A233E0FEC79BC2D9D70F32B811B43CFC5 +:108AB0002DD1E97A55E9F76753FCBE54B78783BDDA +:108AC000B7CF66BD33018AC8DF9BA37FE73D27A4EC +:108AD000EBA18DF174A7736AE25B538F9DEB4DAEF2 +:108AE000827E1BD9B3AB74FB69B69303B9C9CCE7DB +:108AF00000DAAB1138BEA1C35447A9F4F37A06BB20 +:108B00006D7CDED564B2BF97E508BFF27CF1BD99FC +:108B10005F0B72747BA2F3AB2622EA18E6BC227BC1 +:108B2000E8FCA137BCAA94FC05836E667EF56A2535 +:108B3000A9DFF47B092FE97EBED1BF46FFFE2DA43D +:108B4000B63B63E3F6833916FD9C33F8D372DCE75A +:108B50001D12F4110E31BEB9A64C4A18DFDC938306 +:108B6000FAE38F05B73E382136BEF16E1A49FEDEB4 +:108B7000FDA857CA2BB87EA78FCF0B95F61A3A07D8 +:108B8000F377583D14D7F8BB65F607FC1DF6A00532 +:108B9000E7BD927084EBAAED91AE201C61DCB09A27 +:108BA000E69F4B29651C37B71BFD117C6EEEAC4F61 +:108BB000187F07878B7D0F2A5A76A238C2881F9AA2 +:108BC000BE10FEAA71BD09F5008D6FD2BF4BEBDA66 +:108BD000F7B7C2A2143AB7FDBC7001B64FE7083B25 +:108BE0006CF8AB11F4578B757F85EA2EEA04EBA085 +:108BF000EEB97B6CA4BF0ED00F5B50FDA4EA5B4DB9 +:108C0000F1B0EA83E61F91A321B5B11C35914C1157 +:108C10000E7749227FF3AC956A43A0E5C830AE0BCE +:108C20003CF59A388732CBFBA9857DAC2FCE2C70D2 +:108C30003613DE96956E5A9D4EF2BDE775D63763B4 +:108C40007F6B532D6A745F2DF4DD1DC7696D71FE56 +:108C5000F2A9EE561BE7A163BF1B2E1EEA1F359E2D +:108C6000278F75D0A45770FDECEF0E1C9455CA0BDE +:108C7000211D7F91174B2FDD1FEADA97C4F66BE0B9 +:108C8000B033487EFF5F753C9ED0F3F22D9532D312 +:108C9000C33245B463F73C534CFC257EF850DF6F7C +:108CA000DBF3CC255ECEA307451DF113F175D88DFE +:108CB000A1F83A6B83AE7E9DAEB8AE91F4BDB2B171 +:108CC000AE5D4ABFCB93408E24691FF3CB22C5C74C +:108CD000B9FE67E5DAD83A52DCCF2DA4F7FED3907F +:108CE0001725E2263BFC4E8EC6EB6BE911FCB5EC7A +:108CF000162DBEFF7A91AFB1F2FB87DC9F1968A0F9 +:108D0000FB678A92B9BE01BE08D4507F45B1F8FD19 +:108D1000801547968E8ACDD38124E271BF35C2F586 +:108D20007EFEC3165E9FFFF0A07BB893F4E2A659C7 +:108D300054477B95AE2F0E1427D713CE03F4DEECE9 +:108D4000E83C4B72C47903D07E73A2DF571AFB5DF7 +:108D500005D7321D56E9B87A4B8F73308EFA222729 +:108D6000411C752EFFF7ECBA75FFE9CC0CEDE5EF71 +:108D7000210ECA0E2A018AD777BE911424FBDFB2D6 +:108D80007BC93B140FFBDFB403F9212BF62C19C56B +:108D900075F83EDFA5A44FCEECB9ED52AE6394C496 +:108DA000F7A5015A5F0EF953AFBAC94F6ADCFD2A25 +:108DB000D73936EE9AF808F94FE82F5D45D7D18FAD +:108DC00061FC95BD58C1F8DB79A822A384160E9EDC +:108DD000649AB7F1A0C2758F8D072B5EA821BFE6FC +:108DE000C599EC3F19FE5239C5E3E43F1D1C1EE74F +:108DF0003FA5E60AFA0DEC4DE2FC8704C5023F30C0 +:108E00003C0E3F0D5D7F603FA301F55D2C8E8CE72E +:108E10004A72159E6754AE8E9F90E4657C6C176D08 +:108E200043F74EDEDF326B88F9DDD26115F73B4543 +:108E30006BD44907203D40F478812E211FE6D8826B +:108E400005146F3E5F14FFFB4446DB912BF209CF04 +:108E50001F15DF193F3FC3372AD1F7C6019829E212 +:108E60007049A77797B53AD1F7BC4FEAF3B93220EA +:108E7000EE5CD2687F922BF4EA1C9BC85399EF2FCB +:108E8000CC35EC0FACA5F398976BACAAF1FB2DB9E0 +:108E9000A877AF06E3CFF3EABC4C3AE7127135404E +:108EA000FF2CD287DFA53C3FF95F95C2AE1B79FE50 +:108EB000B91BE13E91E7BFC94A7AC1A82F99EB35AA +:108EC000FB5FB557D03CD7A27DA779AEAB8EBFFF75 +:108ED000DDF3F85D37E6EA767C248C1471853399EE +:108EE000ECC1E95EAB2AF33E82C3137D5F68E89F65 +:108EF000032BC5F9512FEA456A5BC6BCCE79ABE7B7 +:108F0000F71E7D2A8DF56A121423892FFFF21D7733 +:108F1000A2795ACECAEBBC38FC19FC3A497140E937 +:108F2000507EDDA9D3BDD171C2C6E79BD0FC804580 +:108F30003EF777492D633E6F23793AA97FF782EB9D +:108F40002BB4C7E8FD93B99FF0FD15332112C0FB88 +:108F50007BC7D8D9FE35CE92F8FCA0312CEC61E36A +:108F60003C610F4776CD65BE5C8F7CF17A584DBC75 +:108F70004675B906BF2FFF726096114FD2394E0B5E +:108F8000E19CF57426B78D5DEFB6F17925DA5DF2D7 +:108F90000BAFA98CE7DB28F0DD9785F76FA8963C2F +:108FA000684186F0FD869BE632DFAFD3BF8F391F65 +:108FB000DFB7E7FA36E492DCF70D5E3F0E49F4FCCA +:108FC000980F0BC9BE369D03D75B0C5C0F8F3C4DD1 +:108FD000E7659EB3E7E9FF783AF63C7DB8DBF71F1B +:108FE000B9A4572D5FBA2E019AAFFF17CB25E21314 +:108FF000F0F3E792AB2775B97A325715F9DD4C716A +:109000003E3456EF3F6F0D16F0F714A517760ED8C5 +:10901000F2EC1FC7939E3BB5F7E0785B0C5F4F2CDB +:1090200047FD40F666F77EFEFE308A3B8B8E3B8521 +:109030005B49BA56B7A3F1383C413824FDBC7DFFEB +:10904000D5143F9EECBA2E53D262ECECAE975D2362 +:1090500062E63DA9FF2E06C66D23BF9B12BBCEFB69 +:10906000C4797948CC87F23FF2BA71B1F75B753CAD +:10907000F7339EEF1FDDCCE7F4069E151078367EA1 +:109080000FE3EC779536E0EF1E037BEC5C5F31601D +:109090008D14A6C5C8CBC73A9D314E930B32999417 +:1090A0005CEF3A19D655F1390106EF6BA7D0E77797 +:1090B0002159D4873673DDE2F466F0106E25D8C8E6 +:1090C000FD49D5E2BC7C2AF4C9B4AECB20C2AD17B1 +:1090D0005485DA995461866DA52324933AE9ECDA34 +:1090E000974CF80ABB95B4BF3844E96922FE45F7AE +:1090F000AFC05F0CBCE2607482127EA7EFCE137526 +:109100000E9E64218F9193E2774FBE05FDBCFE69F0 +:109110004A1FAF3745D3D2E9BC64FB73CB65AA7F46 +:10912000D9035A84E4CC93D1CCF9B7C80C086D4E5E +:109130008BEEB792F6AB46FB53E78385F62B418760 +:10914000D87F33A4D3F9D81408F37B2EA705E37E88 +:109150006780A650DF9157A4D359C46F557AFC6637 +:109160007104B8EE27354FE03A5909CAB9159CDAAF +:109170000E3D4CE73325629F93F13A9FE3348B75A4 +:109180009FB5D77942DF4D8510F319EA417D817F84 +:109190005C61964AF492C26E0BFD9ED885D275C072 +:1091A0000DBC7ED7AD91533FAC889E7B797AB2B926 +:1091B0001EFA41C91291695D8E02510F1D86107F02 +:1091C00097198EFFBDB392BC6B8BF268BF3EF11D49 +:1091D000AEB9AEF389E066AEBB991F40F2D03C0554 +:1091E00000C7DDD13A006B7190EF5BE99C5DE53A19 +:1091F000D3728A177F9FE52BCACBE27AD3113C99B1 +:10920000129C589B12C53BAE8C7F7F271952DA49BE +:109210001FB5EAF5B401D5A5D73315F23E34D4F322 +:10922000FC23128AA8EBBEAB4AD49FDE356C0FD765 +:10923000F9F64BA04AF974FEBF87EB80E987E1ACF1 +:10924000F9DF70FE9FA9FFEE43B1EF8DC925BA92F9 +:10925000C7E75A8FA570FDAB32D3AB511DAFB95ED6 +:10926000BCA46DE203FD1C971AEB35D5892B1EBEFD +:109270007F97AE5F5B1DE27780A45576559A4EDFEF +:10928000BF2FE7DFB16A25D7A082BE7B5FCECF5369 +:109290001D33158146527DDF257A997F970AE13586 +:1092A000F83CCD9B3A92F37D89F831DDE087656823 +:1092B0009D14F2E166E2AF51776BD4DB122068DFD8 +:1092C000C95EF13B782AE2847FF70F9762275C7AC8 +:1092D000CDBFE721EA7FDB74FAE3BA9EE0BA4F879D +:1092E000F84EDBF89ED74C3703BFFF0D047C0BCE46 +:1092F00060530000000000000000000000000000BB +:109300001F8B080000000000000B9B29C3C0F0A3C6 +:109310001E8145A451F9E8F82C9A3C0B0303C34F76 +:10932000209EC7835F1F2E1CCD82607B8A3330183E +:109330008932301803F14C209E05C43F80D8408C00 +:1093400081C110888B80EC6220F6016207A0DA2FC1 +:109350001C0C0C138419186603F1326154739F328C +:109360004268252E06065320FEC784DDFEC96A0C1E +:109370000CDB7510FC385D068635FAE4F965140FD0 +:109380003DBCCD1195BFC70A95FFDC8681C1DE09C2 +:10939000C1DF6B459AF9D540BD354EB8E58FB9A10F +:1093A000F2F779A0F22DD1E41787416800E6955CC9 +:1093B000CAB8030000000000000000000000000028 +:1093C0001F8B080000000000000BED7D0D981C5560 +:1093D00095E8ADAEEAEAEAEEEA9E9A494FD293CC1E +:1093E00040CDA443069884CAFF04265033C130AC54 +:1093F000A84D94ECA0A89D1F312ACB6B780A01C11F +:10940000A9F9EF9924A4F3F342F89134D12CA0AE3A +:109410000EC87323B2CF4E88BCE0DBA711D12F6AF0 +:10942000F01B621E4FD45D67D92F4BBB06F3EE399C +:10943000F7D64C574DFF4D02ABDF7EAFF3E1F5544D +:10944000DD9F73CE3DF7DC73CE3D7547264D247608 +:109450000D21E7E047CB3F780921CB264BABC3C8B2 +:1094600092A5B4FC0A31FAE8A3CBB56C8740CB05D2 +:10947000EA9847D009B9229226C443486CF431E2F5 +:10948000A1F552F532196924C4AFAFAD22EA64BF29 +:10949000EEB2AF9B90ECFCE2EFC523C3513D44FB21 +:1094A0007B6A799749FB493DDDDA65B64CBEAF83EF +:1094B00041297E4D8462534BC840C35EE28910321D +:1094C00044C79E4FFF53EE4B90386D27678789BE88 +:1094D00000EA55637DE5D9E39EF5F4F99097748D24 +:1094E000D2523964658314EF85CF6B8B454A8F5F09 +:1094F000323DBFA5B03FEAC95840477417F67B8696 +:10950000D20543BD5BF42C017A281D6D15D2D356CC +:109510008C9EE72D0BE8B9E290BE289F1EA59ED138 +:10952000A3D4F7E23C9D89527A1A2F849E7B909EA9 +:10953000214ECF908B9EF7717AD6D9F4D40D223D6F +:10954000830D941EFAC8779F45E2B4BE02F484A04E +:109550009E939E41A0A7A5003DCA9F879E4F72790A +:109560004B023DCBCAD393047A6A2BA0474D138D8F +:109570003EF713C11C6D998A979FF371C1B3E9A897 +:1095800045FB1D7E5BC479A62B32BA76C164BD3122 +:109590008ED7F71A07A363205FF3F64609ED6FB87D +:1095A00041C0FAEE7E1F2232D6AFAD377BA0FFCB93 +:1095B0009E74F63FDCC0F0B5EBFF139FC77F2222FD +:1095C000B6AB51E3C3000FCFFB1649C038DE74546D +:1095D00083768DACDDC0BCE55D636AA1F68C9EE14F +:1095E000FB2D9467257B0FF2EB730D69A253D8FF17 +:1095F000648200FFE528C3C76E4FF122E44A20FBD6 +:109600002ED364F811329BCE937557D6A2E3C5D200 +:10961000B72B71CA8FE1BA5E05E84EE9BBBA406F5D +:109620009D89C9446C04BC0AF3C1968B6BC836A5EE +:1096300089CE67DF2BA23142A6D6B340B86A276134 +:1096400049F5906C33C1DF3902F42470FE07E6ED72 +:1096500045BA65A06B01D095243A7DFE1C971FDFAB +:10966000B31601B952742B6A2D983A4E0AF8DF02EC +:10967000BDA6A36BF3E8FFB93DBF745E5DF38B7CC1 +:10968000798898590BF8E277CE9B5DBEC4F97E4588 +:10969000BD85FC2D37FE54FAD9F87F4F74EC87282E +:1096A000E9683C3489CFB077AC17E49AAE49E3203F +:1096B000ADB2908ED39EC76FF77813744A69871C3A +:1096C0007F8BF369D83F7E24BF3F373EDFE5F5BE91 +:1096D0004B342C6DBA161E62E394EBFFC7C0E25AFE +:1096E000A8EF5A5792E5E0FBBDBCFE15CF3BEB154A +:1096F000E3CFE727F86345411EEDF5083F732621C8 +:109700005C64F0A72E27E452F83FB4C9EFD78FDD91 +:10971000054BEB1791C419E8E73692B8383097AE8D +:10972000176FE20928AF95CC7F83E7B495F6FAE589 +:109730005CEE44D4036C3CDA3DA1FD87787F92D087 +:10974000490895675F2BC98C50D4DE239ECC0A94C0 +:109750009FBB0831666979FBFA29B6AFAFD432AB4B +:10976000613FBF4AA284D0F1AA88E68712EA6769FE +:10977000BDF032D5A023111FF94855BC80DCF89705 +:1097800012CB5F45C76F951DEBC26F2608E8855069 +:109790009464FD614234211441FC5790150C7F5DA7 +:1097A00080FE6A24BD47A2E388318F71803EAD6A96 +:1097B000232B37E4C9A12E30F9ED89793C40D7201D +:1097C000D5FF3EBA24C30D74BDC37A88527BA380F3 +:1097D000DC4EE8F79C48B23368BF39816497505833 +:1097E000252B13B45DDA47569EC6718971A0809C03 +:1097F000AD13D8BC0AB1F173E7D02E2099EBD02E6F +:1098000048E33A96636913F601C50C1B3E98F6B31C +:109810003B985E93880972521D4B67ABE0BD7E4951 +:1098200023E03B2B9624AFB5B0F2541EBE8A6A45A6 +:10983000D17E6ABC44E8CDDBC70E53F93995276F5A +:10984000A9FB991D30D038C8F5CCA7507FDAEF3F7F +:10985000C6F9248F5164802E5DCE340953E53A2534 +:1098600014D6131B39BDF0BB76B9535EA5995C5E67 +:10987000E9103E89A07C0D3D4532802FE5E491F54D +:1098800014BEFCA84246A87CB590E31E909F856458 +:109890001C4B836822948B8981E55212C7F2F7ED45 +:1098A00054EE69799B49E5BD09E5FF2601F68986F5 +:1098B000C4FC307DEE8F5957C2FE42E57F1D3CA7A8 +:1098C0007222803CD598A4E07E592DB0F5BA53D2CF +:1098D000FC506FA749503FEE11FA2CD82752DC4EAE +:1098E0004AF989631D3FC0E94EF1B23A96206330D0 +:1098F000BF745E40AF1F6EBC15D7B14F62F0209DA4 +:109900001794BB556C1F73E3A1C0BC2C38FF79586A +:10991000F7E79F87416159C179188279582730FD4F +:1099200029FF9A8D5F823EDCA737F63C8EFC974F6D +:109930004FAFBE4DFF7297DE5CC1F5DC5564FC2273 +:1099400089EA91DB7D59591210EF2F02DEFFF6B341 +:10995000E31F037AC858623EEC5314EFC704E46770 +:10996000921CA7E34BAF8819F0533CC11B944409E8 +:109970003F8568549F295C9F35C1FFD66BAF07A711 +:10998000EADF4B463F7902ED0DA22446403FAD4A47 +:109990002A20177DF56B1590A3A17A0A83DC446514 +:1099A00045B882962AE904F9B3ED8F17A21B14D0AB +:1099B000CF723431C397B7FE574713E457B0CEB5D3 +:1099C0004454A474C899EB14A067405BABE4FB5704 +:1099D000B29A88CA54DE86A05F18C79B5404D493F9 +:1099E00064462FE5CBEAFA24F67338DA81F80C687E +:1099F0001BB0BD4EE26837BD50BFA1B311F68B5707 +:109A00003612D063C5F8E1B6A37D6A92C879FB81AE +:109A10004F4B12316F3E7D52320B7888D1C2FAF52E +:109A20000497738F1EC77D85A41F34152ADF5E3E01 +:109A3000D7DE28F999B0306F3E2279FB0B9D8F411C +:109A4000BFD15568FDD19DC2D9AF21106579E5FD23 +:109A50004EEEAB7C7ED32B526338BFA134CC6F1F4C +:109A6000D5EFB87F9E0C650E52127A5625F7C37B50 +:109A7000AF2591DE0876D30CFBD9DDE26506C8D9A7 +:109A800003C037CAD86DDD0A9623DD1A96A9EE28E1 +:109A9000960F06BFF0C4186DB7C5F2693E5ACAE901 +:109AA000BBBF01FD51EF3A3E02FD4668FFD0AFA4B7 +:109AB00068073580D9FEE28DB1F2660FE3A3EA09AB +:109AC00020BE8B3CCCDED68989F292D64AFBE35588 +:109AD000AD4E7B36640426E59EFE176CAE71C07EEB +:109AE0007DB6A3BE7B5DFC80EA26C0C72BC589D1AD +:109AF0000265617D7D5610114F515C340E768634BF +:109B00004BC6FD7F4070EAE7473C6C5FCB7814ECB6 +:109B1000374AC65F3847F9E1D53C68DF84AB9B46DE +:109B2000B3C09F5AD998478BB0774CAB29301E8968 +:109B300048BF1BCB5BCF4F0966A3E72F804F53E88D +:109B4000EFE970C875CAC3F6B5B37CBD883EB30BE8 +:109B5000F449948A2141F9D01F073E78826D46333B +:109B6000E5C340B5AC83DFD3DFE329B8BFB8F92044 +:109B700056DD12053DE8E6FBF35C8E9EE27CBFE617 +:109B8000EC07505F6CD73C9D19D41FC73B419FF732 +:109B90002FF57840CEFF62F8E7A2E3735C7ECE0A31 +:109BA000137420DFFA23CC3EDEA651F981F51C6147 +:109BB000F2A3936C27BE37285DC254BADCFC7BB796 +:109BC000E9B3F95E55ED89675A00BFF138E2D7264F +:109BD00015C4EF3F8AEF365EEA045E598697F19727 +:109BE00081D7534262BF87C20F70797D401A5340BC +:109BF0002F34423DD03B41B68EA6EA25C1DDCF933E +:109C0000A02776403FB4FE0E69DCD18F5D2F047C27 +:109C100060EB22CED685F4675D17365E231C6F9D00 +:109C200064985C371796EB771B2F7B3FED0D5E4DED +:109C300040DF54AB71B4B367A9F12CF0ABAF56D68B +:109C4000C1FEA10E11EED7D854CFF3876AD745D104 +:109C50007E09AD43FB7BC01B477BFC58EDB7CCF5C1 +:109C600094AEBEB355C46750BB3F78F5311DF4E2E6 +:109C70003111FDB2BEB37367250BCC7310E26014D3 +:109C8000FF00E087F6B33C616C03BE7D2A557CB4CF +:109C90009F375B4806F4A95735A3605FF72D508CBA +:109CA0005EAC1527C0DFDEE0C75A132D53DB07D5A6 +:109CB000C13BC48593E3D09F700E6C5CBA8783BFB1 +:109CC0008EF4098EF705F128077B27610DFBA7B0FD +:109CD000AE40D782796EEE24DF292DCD12EC9B2485 +:109CE00060C0FCC7E29DBD7F043EBD24A21E74F38C +:109CF000E75931E113F3E25EDE4802E7CDEEEFFA19 +:109D00005A09F5A8544F323E01468DA31DD957EF8D +:109D1000C1389AA4AEAD2A695FD757665F131EDFBC +:109D2000B0E5A1FDD76CDC80C1F477888C11889FE9 +:109D3000541116BFA826BA40B0BD21C43128D2861E +:109D4000719388FF9DEEF716EC5730779273C169D7 +:109D5000F42BD17EE7BE0BFD96C1D74F1EC57EA961 +:109D60007A889C9B31D9AF379AC487E4ECB973E207 +:109D700072C29AE02F81F22D790C5C9F6476D838FC +:109D8000488B81C89D0EBFE946B1C9111F95B5C169 +:109D90003B84302DEB6F33C7F2F4837B7E6F82817F +:109DA0009641BD4DE658057A03CCEE42F1A7413904 +:109DB00091E981FDFB2215E385444A62FC7748A8BE +:109DC000590CF6B35D4FAA97B380976A9816E88B43 +:109DD000A1191E4334A0DF6DC7C11F20E20D46A2AA +:109DE000441C49AA977E934FCFA745673CABAF8CE5 +:109DF000BC0F74973E87F0CA46A2903F73BFC8EC71 +:109E0000176FA0F0FBEBE58E7BC56553F9B69DF3AC +:109E100077A89ABAD65730F1013990EA5F3C017CB5 +:109E200018A85D132D452FD1A89D93E7172D93CD2D +:109E300021B1341E5BC5DA02F3A752E15959629C85 +:109E400009F94E120DFCC557983EA2F88685994C2B +:109E50003FB39F01361BF1B6FAB4113A6F811683F6 +:109E60007C99C2D1D54A5C6AA5F42E3D4044785F06 +:109E700027121174ACD866A0BE6A66FE9D49FF0128 +:109E80001DE136D9B16F81FE9CD8B71A41FE9DF015 +:109E90001330CFC1BC79EE3E447E356F127FFAC8D5 +:109EA0002C1417F6CB1D7F57981F3515F163379586 +:109EB0001770C87752BF11CA1DD46F84723BF51B4F +:109EC000A1DCDA4D859DCA537F7733C2FF0D9AAE70 +:109ED0008473B264AAB111E2A25F3EB1893EDA0D89 +:109EE00038CC866EFD1D10271F01F84A44C71200AA +:109EF000E6E7292F89FFDE0E719711BF5DFF9FDB1B +:109F0000B1FE042CF4425C7F24C4DA8F89C10EA810 +:109F1000BFBB81F0F8B9A9DC94E7FF9F11BD287F92 +:109F20006003B1F6BFED81FEFC920DD777401C7542 +:109F300002A67C047CFC0A8367F73774C0B906AAC2 +:109F4000003A5E53FF456CBC792C6E463EB4B60CAD +:109F50001F7B71FC7570D806347FA8060E8F894C64 +:109F6000E5A6893EDA5DCDF1AEB01F2225D87EC7C9 +:109F7000E347C5D74D997D8DE3517E3D9868BF81FC +:109F80001EB660DC9F14DEA7DFE971777BA7C717D9 +:109F9000A52D6142F7E1CED12C4CF52E31119668FA +:109FA0003F55D71EC76D458E6699DD50E1F86F8825 +:109FB0001A8F7F26305E68F35BD298FDD1EE9A4F00 +:109FC0006FC4C47348BFCAD661A5782F8771F2FAEF +:109FD000215F5B5C57687FB1CBC80D9E49BB8BFE90 +:109FE00057736DC0016B6D3593761CF063E96C0798 +:109FF000ACB6343960AF7699A3FDF9CED7E52E3AE9 +:10A00000749B7F1CAE75C195CB9FA4F3FDCE627689 +:10A01000E404CCF7E572F0D9F94E98F5EB231FAEC6 +:10A0200062760EB3673E4E781D371E469E1E16A101 +:10A030001E83758F406C3B37DB3CB5FF3EE50B184C +:10A040008F33FB24E2BF7A6ABCCEEA4862BCCDEA19 +:10A05000F5697D118CBF61BC6D0B35E87DB4BCDD4D +:10A060009BB855A2FC7ACB7F518684A1DFE40A8895 +:10A0700053F7B9E20A6E798A3D7A73C1F331BBECCA +:10A08000EF6671401B96EA0B9FFB6F9164A4E3257A +:10A090006F620BAC2349234731CE43ED6C11ED6C5D +:10A0A00013EDC7C3D56BA260C7A44C19FD1C297D55 +:10A0B0003BAE9707DA3CB85E7A241DF1EA5FD97BA4 +:10A0C0006C2EF8A3BA87737A0CED801DABE43A5876 +:10A0D00037616A8FC27949382614DCC7B64BFCFC5D +:10A0E0009A7CB4247DEEF9F838CF234A3708786E8D +:10A0F00067853CC8FF94EA413DBABD4D7E1CFC9F7C +:10A10000ED4B3D37C3FB336DB2472CA1DF06B9FDE4 +:10A11000B415E2A8B0EFA91BB09F33862753497E40 +:10A12000CEE1556B30FEDD2798CA5C3C5FF690832C +:10A13000C8B71F60FC6FC7A20ECC1FB02416F7DA99 +:10A14000BA20D09529741E2E85F1FD8EC6F6230FF8 +:10A15000015D542F1F44BF6DFCC4C6089C5F6A8B11 +:10A160004774A0DBF4BC01E3ACF4E0FB7463F20AD7 +:10A1700003E2B66D1E87FD915EC9F8B12342908E51 +:10A18000336DA7206909F653F321387F8D2C9DB0DC +:10A1900087EAF2ECA1706B724522EF1CC1B69F8A70 +:10A1A000ED4FA26C8C59F4BD7AD287FEAB107E9233 +:10A1B0008810A79E2DA2DF7CED82A3088B6382E12D +:10A1C000D3216E6F9904FD3D93C5F1EB0979983E5B +:10A1D0000FFE41C4736112E2F636B7AF34FA0FF6E0 +:10A1E0001D9FEE3C079E625F9D7CE324AC2BF164D7 +:10A1F000F0350F94AD89BF21E027BFFD4D8C1F3D89 +:10A20000D07A67A047986A879D59FA4C7A6E013DCB +:10A210006197C1B1309EF312F1969276B87AF253FB +:10A220003F3C9A87DFAF24971DCFED3BBB9F62F683 +:10A23000DD5BDD9B7F7894CAF8062F8B17F965F3F9 +:10A24000B7A0374EF1FD330DF93779F2B3C1CBD654 +:10A25000D11FF8FA8619067F1CFC6798DFFEF67599 +:10A2600038EFC5F0A6FAE00F4C1FD87E38B3E77779 +:10A27000B495F63B26F35CCEA21E2896E7F20129A0 +:10A28000217B97E5E927579E8BBD9E075799244A66 +:10A29000E7695B35C9C0F912B9C6241B417E056266 +:10A2A000F41AACFEF872BED5417E14794F16D6C5AD +:10A2B000195D32E05C3235EBFDD4A12C8EAFE49217 +:10A2C0009F72F3B9C5359F0D5EE77C8A245E0586D3 +:10A2D000492CAED46D02BDA3CA06AC4FEA1FE8F903 +:10A2E000FE8F3D9F64058B8B896A86141A7788EBF5 +:10A2F000F1A4D7BCD40BFB8D377902F4B0B54A4634 +:10A30000FFD85DFFE35EE6BF0D3612C962792DA866 +:10A310000749A769C2B95F4AD0920F6B887E1CCEED +:10A32000BF4097837FEF8BBE6EC2BA7B5424C9199E +:10A330006DD45FF63622FF77ACBA8BD9A1EF2582B8 +:10A34000580DF52DDCDFEA4C4DB0EA26F3CD88D66A +:10A3500013BD314F5FDFE4657A6DF2BD15BDC9F104 +:10A360009ED9EB83216EFF697DD11B4305DA571718 +:10A370003EB77E1FA7F3262FB747AC3ECC83494597 +:10A380006E3804269B74CD607A3D2D4D2D89725B0D +:10A3900040BE6F02F9F352F9663B15936FDB5E28FE +:10A3A00036FF6E3BC1AD7F2A3DC78DEDB9B9E438AC +:10A3B0006EFF7D90E7BB516977F0C9C7D7F942BE00 +:10A3C0005E26EDA934870DE48B0FFC7D3817075905 +:10A3D000C8B3C776733EFA02ECBD1B0FEA676F0184 +:10A3E000B9F385991F8E8B11EC3AC970CCF7047FB5 +:10A3F000F879E8418E4F2C7D358B0B87EC7CB94A80 +:10A40000F547E93C39AA3F1E28A53F4894C5016C91 +:10A41000FAA7E2C9F814E5F33ED430EDF8C42330CE +:10A420007E09BEED3F1FBE8DF03CBBEE811F1FE1DC +:10A4300079094EBD7DE93A8C9F15C393CAF5A8B73B +:10A4400080DE7E17E7E1BBDEDA0B9F07BB5E51FEC5 +:10A45000F37AFE2DA27E9AEEBB8D928576D4B0BEA5 +:10A46000CB427B0E6885FD3EBD08F3CD488CA07EB7 +:10A4700084869037E5D74DE45F801818D793EB9D1D +:10A48000784A11E77943B4CBCADAFD82FEF66F91C0 +:10A4900071DC89B896CAF2CC6C3B149615F82D3E47 +:10A4A000F2F9638DAC1DEAFD62F44884E90938FED7 +:10A4B000017BA358BEDB24FDCE71A21F8A97D65321 +:10A4C000AEFA4495F4D70B9C234E6D2791D7F3F445 +:10A4D000DB5BB08EF3F213CC27D77761BE1FF11888 +:10A4E00010EFEC8BAE23094AE720617A2505E54A97 +:10A4F000C83F59ACE13985CEFC3F8FC2E4F125AFAE +:10A50000EE88DF8A2AF3A7ED7AE5E6FF6EBA3F15FB +:10A51000B28F2E97D97EF1D61792BF87BC066B44B7 +:10A52000D0C10E3EDD9D43FB6A43F65219F2D716A9 +:10A53000CA33B1DE863D8DF2EA7C7B89B0BC018AEC +:10A54000889CBF3EED7529A77D4780EE536916179D +:10A550003995FE57CC0B38B54F443BFA54EA832566 +:10A56000D7D369BE8FDBF54EEF134DF453524266DD +:10A570001E6D7F5A32C305F308A8994EF2F4DC270A +:10A58000D2A2436EDFBA3F2183FE39DDAD08BFA200 +:10A5900073752BD049F1DF906E9421FE558E2E48B5 +:10A5A00067CFDF376C3AFB55E6D7F5ABCC4FE9D731 +:10A5B000DE447ACFD0E7A5FCA614A7B35F2BAC5F2F +:10A5C00094103BBF55BC56E1BC0917BD7EDDB94EAA +:10A5D000DF69FC8655765E3B2CA595F3C127645A4E +:10A5E00002D8D11AC9A6203F9FB2F165883360888E +:10A5F000918ABA76F229E19314AF1FAC574D210A24 +:10A60000F057858B28AC513FC81B05FFC373F85525 +:10A61000BA8E86BB8218471E6CDD7418CC84E83D68 +:10A620009FC5D0D33650F6183F7D5F5F7B0B5F67C9 +:10A63000B4F3CF0C76AC8678A544E23CBEE1D125DC +:10A64000DB5F2BB0BEF3FC65E19C6FB25D313E0574 +:10A650005CFE908FAC2DAD9F36337D66D17FA05FC1 +:10A66000A2AEF6336F71C6C1359207D3F73B65C210 +:10A67000E33537BEABE3CC2247141DCFB13C5A06BD +:10A68000EA13AB1AF2A742098980DD3EAB39D10E3D +:10A69000FC2FC7F761C2F2EA08394EF2D7D5DF7254 +:10A6A0003D547FE79705B0A7CF18540A1601AC2C8C +:10A6B0002A645FD8F95A1370EBCBA80F0729D61874 +:10A6C0003768F5A0DFBBCD38A5E5AFA7EFF1712660 +:10A6D000E79FE8D2723CADC5F9970D8FE95F78FE30 +:10A6E000F32F4F73FEC39B9D76F074E7E5475C0F35 +:10A6F000959BFF0B1DC79EB7A9EB83E9C3FA3B9F50 +:10A70000C57CC5AD2DA5EDA3A9F37604F7B790419F +:10A71000CC4C81763F9505977DCE4A8524899177EB +:10A720000E255EBE7C1FE415151B574CB8FC0DDED4 +:10A730004FEE135412F15C442FF33DDCE81E89EE1A +:10A7400087C12D57ED919640DE9689F95FC3DD26CE +:10A750003E9F987F9F87E32B108FED5FEB782EBA9B +:10A760004742BBC243CE2D21C861DD963B02F53A7C +:10A77000F7480A3EE5F905B4EA4C6847D06E5D0437 +:10A78000C19E5A3CBFC77EA023A827912E06D38620 +:10A79000006FF59A669CEBE53BE97AD8EAE7B0CE24 +:10A7A000E16A0E6B1C6EE430D9857050A630C4E9A6 +:10A7B000BD690DE100871B395CC3E16A0E37715832 +:10A7C000D885F05699F537226558FF010EEB1CAE7F +:10A7D000E1B0C6E1260E93036C7C1F8303DE0CEB15 +:10A7E0003FC8E1460ECFE0703587E7725838807079 +:10A7F00051BD1C3391BF93F3DFC9F84608F72FE32F +:10A800002EB86BB27E9EFF39D0AD0BF9E78ADE22FF +:10A8100071A7C53EA667C6DBE398BF44FD52EB5463 +:10A82000FE792475A00AC52D4DDE6EE23C3D5278BE +:10A830005DD8EBCEBD2E2AC56FCD79E2F7A1FF2002 +:10A84000FC3EECB3D73DF3C7C7DB0DC4D3DD9FBBE4 +:10A85000DD08D52F24CFFF0F48190BBEDBA0B60FA4 +:10A86000FA355EC599E77AB7CFCBBE5BF1B13CD77D +:10A870003E8EDF783B3B8F189817C81C10A6C61772 +:10A880003FE763FEFFF76D3C9551F48F8239BA6262 +:10A89000F3FC9DE1584799FC75E9DFF3F314DD7192 +:10A8A0008F7F8577749C805A984F774FE89B5BAC7D +:10A8B00053B4AEE2A7CFC16FD122D1FAFC7C6AFEBD +:10A8C0009E081E11F5CB595ACFCE2311B17F3C976C +:10A8D00020F52CEE25F2FA384E23FB8EC15C0CFBE2 +:10A8E0000C7DDECCC711A6F6EB6E97F5D5B0F9E27C +:10A8F000F8D8792B22791EFB99C0478A23BFDCCF79 +:10A90000213F59532FFCF985C25EBDC87869763E58 +:10A9100054AEFD135C5EA6C86791797DC467DB29E0 +:10A92000A3269C23D97264CBD7F9CAD105CB096C75 +:10A93000484B8BCB894592B86E247025174D5F5ECE +:10A940000AC84936BF7EAD52CDCFF90D94178A8F14 +:10A950008472AB317C6A1747B03F01D6389EB7701E +:10A9600018F840E9BD5CA9E67C60F18C009C3BE6F0 +:10A97000B5A7C421BE02758698DE67F5AE51D83AF8 +:10A980005FD551CFF027BC7F17BEB43F25BF3F91A5 +:10A99000D4BBE49CE1FDD70A9B5F5A9FC55DDCE315 +:10A9A0004B02E22B92B8E5A1ED3EC3EBBBF5975D00 +:10A9B000DECFF11BF690CD2CCF234EF2BFAB0C2A8D +:10A9C0001EFEDD235B676EFDE405B95A72FE72550B +:10A9D000A95EAF550AEF3B54CF37437CB6D8BE7360 +:10A9E0004299D80F9AF9BC4D6BDE7F077A68D9E49B +:10A9F0007C568AEFE57CDCE9E27B7A2ABE15C9D970 +:10AA00009B5C4F548ADF35E789DFCB2EFCDE29B90A +:10AA10003ECBF7A34AF1FFEBF394877F9CCADF8A12 +:10AA2000D69147991E7F3F739EF8FDD28D5F917539 +:10AA30002B2B8C5F1661F221A904E33395E2D75DDD +:10AA40001E3FEE8FAFE9376368AFA13FBE5D59D3BC +:10AA50006F4993F89984E9F5E98EBFA3E2F1DFDF4E +:10AA60006F4A93E37F5179BF637C89CA0F085BA566 +:10AA7000E33E56E9B8D64D0EBABF96BAC931EEF9E3 +:10AA8000F2FDEB158FFF5107DDCFA73EEAA45B3542 +:10AA9000304FA4D271FFE13CD7FB6F38BE41457304 +:10AAA000EC03C5ECF7B3DCAEFD84A239E4B858FD85 +:10AAB00037B9BDF2BE0AEB9FE6FDCFB5F12953FFD2 +:10AAC0001E8EFF3D15D6FF1DC7676585F87C9FAFBD +:10AAD000C362FB6780F33D083A32CFAFB9D03CA6E2 +:10AAE0004DBE84E08773CD67BBF1FBC1372545833D +:10AAF000F377D249D01EF79F0C1DC0DC4C3BCE4CE7 +:10AB00001296C0F430C6B7BC11239AEF5FD87E9777 +:10AB100024C5CD42E76BD57EA6FF04CDE862EB5D90 +:10AB200026F03D47B1FA417FE1F84B1519CF421E9F +:10AB30002F89F2F3A2B31FD40BC6FFA57802BFAFD3 +:10AB4000D6647200E2CED5EB1CE7F9311B9FA889D1 +:10AB5000F8C81AC347960CB350FE72839FCDABDD85 +:10AB60008FED1F0AD171C2EE7160F80DF8E35D78C8 +:10AB7000DE5F2D239FFA43CEF3F09B793F7FC5E93B +:10AB8000EBF796CE1BEB98D9AA40FF7DAD2C6EAEAD +:10AB90001303CF05FBD5D2F71A6CEB66E78123FCD4 +:10ABA000BBD2147C573A1FF2A4A23C3FEA19FC3EE8 +:10ABB000EF4C8BA7E4FD3821C3193F0F363BCFDDA7 +:10ABC000EC78BB5F777EEFE38B3ABFF7F1CE943C36 +:10ABD000F87D91CAF2B1CAE16FE773D9F586A4A4F2 +:10ABE000A215E453C611EFF7459DF8BE7BFC63ED5B +:10ABF00083DE51AD105EEF14DF8AC51B26E8AD92EF +:10AC00009319A6371CE7D4DD5CBE7C554A12F4329A +:10AC1000D5BB45DE07587B358E790A4A34AE633C96 +:10AC20009AEF030AAC873C3E3D68AFCB80C7CE436A +:10AC3000C6FB5E04DDC4734605D69130B5DDC4BCE9 +:10AC4000DA72FFF66ACC4FB46A155C27823E8EDF5B +:10AC50007BB9C799EF3777F96939C36FEE86D2FBB5 +:10AC600027315168BDECF4333DAADC10D79526742A +:10AC700055D1EE71E3F10DBEFE541B7FCBC473EED4 +:10AC80004AF17FAC42FCED7128FE5F013D4BF1FFC4 +:10AC90002A94C5F07F8AEBA31AA2F7E09EAD333D5C +:10ACA0004BC88D7A7E7C3D1060FDD6703D4548BB1B +:10ACB00023BFC4CBE9AA949E43B65E2B438F3D2E9F +:10ACC000A5E7289F8FEF959A8F17383D8100DBB756 +:10ACD000947D719D2E4D7249917939C5F19819E095 +:10ACE0007125AB7D5A72F5A30AE93835392FAFF2D9 +:10ACF00079F965293A4E72B94A8B64E569D84FE70C +:10AD0000DA790A6B1DF33287F327EDB3E7A5C33178 +:10AD10002FD5D39C97DF5648CF9CC979798BCF4BE1 +:10AD2000AE949CE5D57F9BD7FF13AF8F76E29CC096 +:10AD30001FFBE1BC6CBE3FEE09D44EEE6FB49E1813 +:10AD4000583659EFC1E163763D1FD6EB9CA8A704A6 +:10AD5000F2FA23D66BFD70AE3DC0BF0BF9FE70E872 +:10AD60003DBC5D18DBDDC0E8A1EDAAF2FBFFC6F03B +:10AD70002B76FF33A05ECFEA3FD9F522F9F5E60442 +:10AD8000FE64D78BC27361DF447F75F9789CF2FF54 +:10AD9000733FCBCF71E5776995E531782309BCE73F +:10ADA000A18684D290073B28B17B172C6A541F845C +:10ADB0003C595F224B2AB0BB3C0A6BE7A3F6167CDA +:10ADC0005F36432387FD3AB82006D907F9AD11094C +:10ADD000FD813BFD89A5815A8627C8CBC0ABCC1E1F +:10ADE000EB5197F2380AC36B67F06329E84FA378F9 +:10ADF00041FF0F06C387A1FEAE065907F93ADC7082 +:10AE000017DA893B7B2402EF775E2FA39DB8FBD531 +:10AE100010EEC3039281F9D59629EB6037DE1DF859 +:10AE2000D3894D141EEBA9D284AB911EC4DFF290DE +:10AE3000781FF6CFECCE2D147FC80BC6AD0BFAED04 +:10AE4000647E0CFDD541FBBB57EB984FA313767F77 +:10AE5000D350AB8CF9483BEB9BDA61BCDDAD0ADA31 +:10AE60001DBB6F68EAC13CEDD600813C801A5517C6 +:10AE700020EF31BC422616C011BD07ECCED0F20047 +:10AE8000E446929A7A365E683EC17BFEBC241D8FF2 +:10AE9000D1329C9231BF77F70D6B593E69AB4FC3EE +:10AEA000EFBC2CF3E5D872C25295E127FE23017C5A +:10AEB000BC734402FCB7E7399C9E685FF21C319C6E +:10AEC000A9B05EB6B27AA19484F74E95AD97AEB0B4 +:10AED0005EA6C27A5956AFECF93DCF9F54E83F8841 +:10AEE000C3F95DE7B760C797FA5E6EBAF9B93B037D +:10AEF000CEEFE9CAB5B7F372CBD10B879913788A35 +:10AF0000E5EB97FD1E73E65D51F83E6DA8F65E5EBB +:10AF1000DEC7CA3AFEBC6E4B14EF8BACE3EFEBEE30 +:10AF2000C3FB23DDFDFC0FAE8F9B49BCE43CD4701A +:10AF3000FC5FA7B8433CBB592A930F10F1B8EC4D06 +:10AF4000A7DE5324AB03D7ED0D2C2FC707CA00D6BD +:10AF50004D3D5BC75E928CC7309E658617CD9C5C6D +:10AF60003FDEB61771FDFCA04E24422BCE0FFB8EA8 +:10AF7000D225276EB9F0B9CEF52F544E7EFA2EC9E0 +:10AF800089372556B47EBCE90AEB652AAC97ADAC8F +:10AF90009E9C122AD22B72BAC27A990AEB6559BDCD +:10AFA000819532DFD7870720BEE5BD5271C00357B8 +:10AFB000069CEFAF521DF0E032677B79B9B3FDE03C +:10AFC00072677B79056B6F04F7BCC78A55BE4EFE6E +:10AFD000CF79AE9366A574FD506B9975A5687E68B0 +:10AFE0005F23E904EE1DA2FB5586EF5B05E33F6B93 +:10AFF000826CFD5F1FD01CF7D3FDA5D3D91C64F86C +:10B00000DAF496C3D7D6BFFF57E47657913CFB6A74 +:10B01000D03990774DB275D0EFE13BBE550776E55C +:10B0200023AFADC07B3DFADE67E7CD1898F7239DCF +:10B03000F8FECDA0C71E49CA04F2711EAD368E5D62 +:10B0400012C1EFC908D8CBD48DC2FB3E1ED92CA1AA +:10B05000FDD1775BE97B4DBED1CDF284FE8EFBFD49 +:10B060005FE5F7713DC5EFE37AA25BC7F260773326 +:10B07000965FEA36B07CBCBB15CBFDDD26EE1B5FD0 +:10B08000ECEEC4725F771CCBBDDD5D58EEE84E6020 +:10B09000B9BD7B33FF5E2D89E570F7162C87BA2D7D +:10B0A0002C07BA5358F675A7B19CFD3707862F5960 +:10B0B0008AF99290A156147FE37967DC61E1B301CC +:10B0C00007DCF23567BCE1B22FCF76CAC5A34D8E3F +:10B0D000FA97ECB9CCF13EB66DB1E37D53FF950E16 +:10B0E00058BFAFC3015FF4D9BF72B4AF4BAC75BCEE +:10B0F0009FD5F56167FE57DB06C7FBF0D24F3B607B +:10B10000B5E54E47FD40EC5E070CF73EE7D7BF3193 +:10B11000D8C4E2819111473D49DDE5A8F7A999E638 +:10B12000FE20C443D361B42F1F3929E03E38E32207 +:10B13000E3359027F25311E5895CCBF2DE673425C5 +:10B14000AF80FBCB88945CF1C150F97BA4ED788F84 +:10B15000186E4DC03EFBD66B820EF6AE10DE323F4F +:10B16000DF9FB3CBCD67926414E2923CCF4C9B4DF2 +:10B170004C13FC46AA4F08DAD9C9ECFD18B7F4E025 +:10B180007753692181F74E539BD9F8EF1AE4CBBB73 +:10B19000F7DF20DAE5673482EBA0BD4369ECA7ED69 +:10B1A000B72F90F17BBE29F8BABE8B7923C8FCD7A4 +:10B1B000ADF7B378A576C4DFA82C85FB321233C077 +:10B1C00055B5DBA9D997F0DE5335662C87AB01D492 +:10B1D000E60CD9A842BD2CDEBF40EB7F1396FD44A0 +:10B1E000FD4D594BA6CFEB3627E6C2773DDB79FF05 +:10B1F000DB0FFF8C5C42F91A5A7A9CDC8AFECE5E29 +:10B20000E45FA8758CACC95BBFDBDF2EFCBDD12F22 +:10B21000832CAF667B8F85F7CC29D96FE37DA8F6A9 +:10B220003C045B8E9304F4DF368EF7036FBF9F7D83 +:10B230008FB75DF85134CAE9EA71D285F8001DB7BD +:10B24000523DA7DE9214D6B4B0E773F3FA85F71B2C +:10B25000E17DC212205FBD127EC9F07C13E5179D0F +:10B260000775734628C9AF58967D1FD15C845F94DB +:10B270003FB7A29F3BE8881BDA7CDADE739C2C6F19 +:10B2800001FB9FD59FE02BE5C3AD797C9CE0C7B265 +:10B290009F627E6BC8FA1159A2B276406F88D2B70E +:10B2A000B100DF29FFB07F9B1FF63821CA2F869798 +:10B2B000657FDF88F775DAF91F767DF8752EE7F977 +:10B2C00087941FDEB1EA8DF03D687B4B02BF131EF1 +:10B2D000503D789FD080FA4CD6C3E519EA4992D9FF +:10B2E000FB639E67DE2B145A7F4EFB1F32A6F3BF13 +:10B2F0000BEB57D9BD990391327610BF2F58E4F765 +:10B3000005CB52BCB391AD53A3874CC64DA78EBF9E +:10B310000BE916A3CE7DB57F93733F8B691FC6F8EB +:10B32000745FA403E16279F976E9CB31BB51E6F8A9 +:10B33000787341768F71CE8F789AB919585E93AB36 +:10B34000C6F2EADC1C7CBF2A5787705B6E2EC257A0 +:10B35000E51AB1BC3277393E5F99BB14E1D6DC12F5 +:10B360002C57E416E1F3E5B9AB105E965B89F0D299 +:10B37000DC6A2C97E4DAB15C9C7B2FBE5F94BB1E29 +:10B380006123F7412C2FCDDD886573EE23F87E7E97 +:10B39000EE66842FC96D44785E6E3DC2B1DC6710E5 +:10B3A0009E9BFB14964DB9FF8A6563EE0E7CAFE75A +:10B3B0003E8FF0C5B97B10BE28D7877043AE07E13A +:10B3C000FADC5684E7E486B19C9DDB8D655D6E27D3 +:10B3D000BE9F957B08CB99B92FE1F3EADCE3586A6D +:10B3E000B9AFF27BA09FC2329CFB2696A1DCD3F8BA +:10B3F0005ECD7D07E160EEDB5806722F60A9E40E9A +:10B4000063596E9EDCDF2F8911E7BE7C0D99E190B8 +:10B410008B5539E7BE7CD57893035EF96BE7BEBCEC +:10B42000626CB1035E76C2B92F2F39DEE178BFE8D6 +:10B4300098735FBE34EBDC97E7673EEC80E7EDDBAB +:10B44000E0A83F37FD6907DC98BAD351FF62CBB95A +:10B450002F376C71EECB7392230EB86EF32E47FD2F +:10B4600059E461877F58DD75C051BFCAFC8AA37E4D +:10B47000A8F519D7B94986E979E339C773A5F94819 +:10B48000C1F395D89EEB3D6F803ED13DFC7B7A7E2B +:10B490004F2BBF0FCD3D9F355C0FCCC831BF28C2AD +:10B4A000D75D2DACBBBC7C266A3F3436417E08B7E5 +:10B4B0001F6634E94F1FA5F05B4DB2D14361DB7EBF +:10B4C000B0EB97FD7B14FC3B7D1F7CA7AFA3FD80F9 +:10B4D000F7B7DF7D4AC07B1E6AE6107EFEDFD90922 +:10B4E000FB5A0A6C69767F0EDEE7936AE0EFC9FAD1 +:10B4F000EBF07D23835FD876EF1A88A3A6BC76FB9A +:10B50000AF5E07718B949FC12F6F5B3F08EF6BAAF3 +:10B510001275B09FEE2D726EF973957DBFAEAAE6DF +:10B520004B6AEDE4FDD1BF8824FE37C0B729898B73 +:10B53000E12A6EB8BF1EEE67BE56327F00CF3F20B5 +:10B54000993F54715F70FA05EB20A7B516FFAEC4A2 +:10B550002B2ADA4F87703FAA79EF36FCFE3315A20B +:10B56000F8A8C5F139A68A13FB0DB1F79B268C9379 +:10B57000A29D37D840F0BEF85475DC82FBFBACEFDF +:10B5800029E4A00174A7591212CF3B4C5DAADB72CB +:10B59000E1D89FE09EBF0DF47D30A1EA6087A9E469 +:10B5A00038E65584C938961AD104C73DDA36FD0D00 +:10B5B0008C7ECA9771A04B26E6A1317EDECEEFA528 +:10B5C000FE17CE9737D565C5F9F21EF13EA2D1F12F +:10B5D000F7533B11F6C5FD5081D2F17494FA9D02E8 +:10B5E000E09988B760BFEC7E08FB7E38E9E4B7F1EC +:10B5F000DE063B8E23896D9DB83DB730BBAF93FE11 +:10B6000003BBAF36EEB423DDDF9948AEB8CE74E3AA +:10B61000385521771C47C573E2335D1EBC57B158BE +:10B620003F763CE7E9AED2FEDCD7F97AFA1ABF17CB +:10B63000E42BFC1CF7497E8EFBB7E0CFD1F2CBE0C8 +:10B64000CFD1F200F873B4CC803F47CBC7C09FCBBB +:10B65000FB6EE4B122F7BC5C526DE72B6C41BB3D45 +:10B66000C8EFD9206414ED7409EC742A574F1FED0C +:10B670009D19A37CA7BE06D2B7F9FA0EFC8E9F0EC9 +:10B6800061C077FEB7BFF1FACCFF1281AF6FD9F777 +:10B69000C3B43EE6494A2DEEEF48CA8C2399A81759 +:10B6A00082D41F481BC5F933ED7E1513AF6C9B7E0A +:10B6B000BFEC3E9FC975D389F924414EB78F7C07F3 +:10B6C000C739C3FD1922D6FF2FCC8FBA4222A5BE9F +:10B6D0000F9C32CE34E5EFE365E40FEECA44BB3392 +:10B6E000C9E663E173C7EA0ADD0B61CB61CF6B3E4C +:10B6F0008CAB0E7D8FFD1D8AA30DF21C885F8C1E06 +:10B700007EB111BF5FE4F2D877D4997F509F244275 +:10B710007EBF0F75B338445F84F5ABAB2C6FC14D62 +:10B720008FFD5D53AA4C3EC3837CDCAF07CDFB424B +:10B73000A80FB378EFE3C2E7948F00BE8FDEA114A9 +:10B74000E4F3D78389FE50ED543CF3DBE33D14C5AD +:10B75000DB6F0B2D2BDEBEE519E517A474FB3DA5B1 +:10B76000DA5FF615E59132F83F5A187F6B3FB4ABBC +:10B770008FB2BF4BD653F7FA81AD14DE7B07F38748 +:10B780008FDEBC0EFFAEC3402D9BB702FD3E510ABB +:10B79000AF85CF757595C1EB1BA5F9DAD55586AF89 +:10B7A0007F5FAA7DCB335D27CAF0F5BBA5F9DAB57B +:10B7B000AF0CFEFFB3707BEB62D03BF53A8BC7F565 +:10B7C0003452BE523C866CBEBAD643817E5F2E2771 +:10B7D0006F65F0FA79E979292BAFA74AF3B5ACBCCC +:10B7E000FEE602E5F5CD227CDD0F785F80BCBE7DF4 +:10B7F00081F2EA0D5F98BC86C225F5405979AD2DDE +:10B80000D5BE02796D2884BF8F044DB0A7CFB4B0E8 +:10B8100073AFCDED1EF6F79134A6EF8327AFC37D4E +:10B82000B49FEE53335A61BF3EB5F7F6A593FBB311 +:10B830007BFF71F7E7DE3F6FFF973544A5F022BE2F +:10B84000EFD9F80462EE7E4ADF2F31DD7125FE77F5 +:10B8500096ECF6B337BDD3E339F777E9281B9FD0D1 +:10B86000F157E33921BB3FB7AAD51D979CEEB8A588 +:10B87000EB476FB9307B607DD8793FD49C2DDFDCFE +:10B880007F3AEFDEB039FC3B2F2FF910DECF446E4C +:10B8900063F940E296A7F79F5E92774F141915F26D +:10B8A000F37FC4DB46F79FCEA33B07711F8C1F5B62 +:10B8B000989718D3AEC4FDBDDC3EFE28DFEF1FE62F +:10B8C000F6EC3E7E3EB1979F4FA4B93DFB003F9FF3 +:10B8D000D8C6EDD9117E3E91E2E71303FC7CE279F4 +:10B8E0007EBEF05CF73E7C7FA83B83E5B7BA9FC481 +:10B8F000F2D9EE517CFF4CF7218447BBB3CC2EBE6E +:10B90000E756CC839DA4C3E474DC8BF7BCF4D797D3 +:10B91000B6CB1B92CE78C89CCD01D73981F39C62FF +:10B920005697332FB2DA74C643AA5A2F73DD47EF06 +:10B930003CA708365FE9BA8FDE190F9123CE78C88D +:10B9400015879CF19005A3CE738ACB9F749E535CA0 +:10B950009A71C643E6EF739E53CC4BDFEBA83F379B +:10B96000D5EB8C9F58CE78C8AA71E7F9C455BF7E35 +:10B97000D819FF1973C643569C70C643961D7FC6DF +:10B98000012F39E68C837C2098C8823E5C9475C771 +:10B990004332A84F7FA2B2F33DDBCFA6F55F0CA3E5 +:10B9A000BFA966AFA2EBBE6F33BBD7BD8F687E0D5C +:10B9B000F5F067D16FF04EDCCF1CCFDE1F99D43F7E +:10B9C0003BAF3DF553F06BBC21764FE5EDC27559A9 +:10B9D00092EFF778DF12F2CF23A588534F94ED5FF3 +:10B9E00062F7107AC12FD18ACBDDD47EDD7EC9B556 +:10B9F00059C893F2025E06EA1B1C27CF2F1946BFD7 +:10BA00006496444AF9A753C699A61E7AD3A58726F9 +:10BA1000FC9228BB2F4597482FE0B1F7A8A7E0BDBF +:10BA2000BFB61EDA192DBD0EED3C979D5D95E56301 +:10BA3000EF3C5ABA9E1DBFD2F97DEC5EADF0B9F76E +:10BA40008B619657F9C12AC2FDE6FF2F3FEFA4FC98 +:10BA50005C59F59F467E78FC72E3107CCF24BB6076 +:10BA600091C3E1AA4FAF81EF9BB610760E445E61A1 +:10BA7000F7AE961B27D6F6D1CAEEF5D398BCC65AB8 +:10BA80005761FE24DE33562A2EE1BA57CDAB5AF069 +:10BA900047F726FEFEA3BBFECF6B58FC28D6F5B1B8 +:10BAA00092F6CD41BEFF7F89EFFF31B3F4BDBB8F6E +:10BAB00071FC5F787516DAB57B6F637A5BEAFA879B +:10BAC000C3609F8D72F9F791CFF85B80AEDB2402E3 +:10BAD000E7C373419669FD8B55928173D02DC440A5 +:10BAE000B9A63F3C5FB6FB176F73DA5B7FB0F91402 +:10BAF0002FCD57FB9E4CF7731FF94E3BF25727C9CA +:10BB000087ABE15AF52FC4FD149E534B10AFD41EE2 +:10BB100003ED2E99E2A11558A76E7CECF5697F4FD5 +:10BB20002A6DBADA82F673043BEE1434204FE78CA8 +:10BB3000AA96BCFF6D4ABFD35C8F5F9BB21E6FE8B5 +:10BB4000FD4964F2FE2BB285FE964FDEEF596C3D47 +:10BB5000DAF00BAF0EE1772D29D5BE1FD0BE4F8B8B +:10BB6000948C9B6EE57C1FE6F92D5B5B3A7A5F87D0 +:10BB70007353BA5EF2DB05173C8B71C77EED19BCBF +:10BB8000C7689BC1BED756171D55C01EE8D78EE0AB +:10BB90007D71C1FA7427DC3718A472043AD03F6F64 +:10BBA0000F7FBF0BDFABF599149C7FA8F09ED235B9 +:10BBB000D2FCCA61F89C3B50FDE6E10EA85F3F7ADB +:10BBC0000CDEFB3582ED2575F47807C8D966827FD7 +:10BBD0006FCBE2F72A356435CC5BB858653049D075 +:10BBE000F73ABED756537876177B6FA819F4D74823 +:10BBF0003331597B8A1F85A347359CDF996A3A8E7A +:10BC0000FD4758FB99C6B326E0311C637FCF47ED53 +:10BC1000228F031F16A90C6FF8CE8C8DC3E988B153 +:10BC200071BC6A26DD017AA6DEC693C210378DB0DC +:10BC30007164957D0F49C7C7FBA67C2ADB0727F4F3 +:10BC40004E5718C73B13218F97FA7B01F67A7F9CDA +:10BC5000DBF9FBB99D2F2973BE783AEF3E867EFE55 +:10BC6000F7421B55E777987FAC62EBF1C51A9667F0 +:10BC700056EE1E49F259763EFDFF00D7C62C0E0047 +:10BC8000800000001F8B080000000000000BC53D75 +:10BC90000B7854D59967EEDC796526E126992493D3 +:10BCA000D7E426241021E0000141B19D445454D42E +:10BCB00088B6069F43409E01026A89169B9B172403 +:10BCC00021C0A02E445E99605154D0C18252ABEE87 +:10BCD0008029C5D6B6A9F54195DA08181501532A69 +:10BCE000CAEEEABAFFFF9F7B93B9934982B5BB9B2B +:10BCF000EFD3C3B9E7FDBFCF7FFE738631C6BECD9C +:10BD000081FFCD8B61212BA33FCAFB1258283F2C0A +:10BD10005F9AA6CF7B72F4F98211FA7CEE587D7F90 +:10BD2000CE4B75E55F5DCF58870332A2D7CA0A2094 +:10BD300039F2A0B52496B1BA8C1A2B83EFE7EFD174 +:10BD4000CA991DF3B9528CC09C8CB5960A81260302 +:10BD500063C115350D79858CADCC10189321754DC7 +:10BD60001FE2837ADFE2DF0FFBA6DBAB180B0D6768 +:10BD7000ACA9CA4F6963550B0B59185B953170BB61 +:10BD800000B6837ADBAAAC946EA992A8FDA62A1706 +:10BD9000E55BAA644A3754E553EAAFF2505A573587 +:10BDA00091EAADADF252DA5C3595D2BD552554FE1F +:10BDB0007C5529E583553E4A9FAD9A47DF77555517 +:10BDC00050FEE9AA4ACAAF1E23DD5E02F0D959A58A +:10BDD00050FE89AA064AAB2558F77828BFD2E3C29D +:10BDE000F2DA2B596930CA3AAA2503D55B23012C14 +:10BDF0009318B3318F6006B831C8EF00B80D553CC9 +:10BE00003516C827DFC1088E432B3C356680B33416 +:10BE100085E7D7E138D0AE92312FC376B92CB02365 +:10BE20009BB19C06F69601F2AE7CA9CD98DD3BDE77 +:10BE3000F5EA7850EE12A89C05B0FCB8D97B839443 +:10BE400084FD312A1F16EA1400DDECE2B742350EFC +:10BE50001867D41B811A23E4474E56044C630BFD2C +:10BE600082AF00F12A14E338E75608D48F5CC80487 +:10BE700001E61774713A585D04F0095BB7EDFC36C2 +:10BE8000161AC758C38AE943D800784D29157AE9AC +:10BE900011FE8BF786D13FFCD710120E1A619C73EE +:10BEA000406F2CBBFF7E2EDEAFEF675430A29FD2D7 +:10BEB00081E73172A7BEFD458188F640D7C81FFDD6 +:10BEC000B51F76FE065A6F7F747CCA5C56258DEFCF +:10BED000CD8BE77FC042898CBDED90080F09D73527 +:10BEE000BB10CEF03705D72B6630822BA03B540613 +:10BEF0007913FCAB09AA8A0592978DC65456538FC5 +:10BF000097C561EA55F325947FDDE45B83781625B8 +:10BF10001FC3F920D9205FAFBE08FE9986F9AC0691 +:10BF2000EF64C8FF08FE792963374A23A62A90FFE9 +:10BF3000CAE4132A61BC3DD942603BC07B79CE582C +:10BF40009203B58E81F9B34EE5CF9EF549255E0388 +:10BF5000F4935E2E8D453AEAAFDDA3E5CFBF3E0CEC +:10BF6000EA294EC19327F72DDFA5D2F1A325C214EC +:10BF700007C22193D3B1B69EC8FAB0EE5DB86E93F6 +:10BF800093AF3BE996124A73775D632D1905EB8BEE +:10BF90001F980EB644AC2303060A46C1FB499C1702 +:10BFA0008C93FBC67C1BF53B63E07E1B55B9773E4B +:10BFB00020B00EC4B35841F236E9161FCB85753553 +:10BFC000A40A0107ACABE19B7B1BB2111E070492D4 +:10BFD0000B49B754305F41DF71C5DCEE6A01E9F20D +:10BFE000C07C26C3F8165705530A30AFC96B9F01B2 +:10BFF000E7932C495750CA025EEC3F79854FC171D7 +:10C00000CD2E3FC1A521B5A7BE0DBF6F080924DF06 +:10C0100057CAC06F064A9903F9BE82513E23F561A3 +:10C020001A977D0DF39900FDE0BF01C1960CBF1773 +:10C03000E541C345CC8372C496CF8ACCD928A60EDD +:10C040001B50AED91E609E269C6FEA130ACA23E5D8 +:10C050007246F80605C7107E30BEF526C0677ACB5B +:10C0600068E20B5B6EC880EBBEDDECEB427C6AEBFA +:10C0700037BB3A091E0DDF184BA3E1E537AA9CCC6C +:10C0800044BC45C1476C3C97D75F9982D7A01CDD63 +:10C090009324B0ED86BEF52C6ABDCDCEE97F94E544 +:10C0A0005EFED4CADFC64586F173FA7933CD3BF71D +:10C0B000963B87E07AFAA383552A7DAD1BC2F540F3 +:10C0C000EEE43BBD08EF73F05F5394792C182253D4 +:10C0D000BD9EF53B059D5CBAF0F989249F724F35F2 +:10C0E000927EFF2A7B607A6D50E7F955A6DE3E10FE +:10C0F000725B08CFAB5C804F19ED0481C5011C5BFE +:10C1000055FA804F84DF20E8A726C07FEB8AB3B6BC +:10C1100002C867BC6D4432017A98A7A01EB15DC405 +:10C12000E941923BBD0CEC9098FC6EA2C78C8A4E04 +:10C1300003A680F7BCF8F1480F1374F47046D59F3E +:10C14000F057E79AA08A3299F8BE201EBE7B77C1CD +:10C15000249CC80F7C7C13F32A669217952C08E365 +:10C16000DADF32D2779861E8A142945382A7C903FB +:10C1700074D05E938C7C684FE2F265DE35C524BFD7 +:10C1800000049E4D30E6E24FBB929740DEE3E27240 +:10C1900019EA5B719E628159A737061D47F48670C4 +:10C1A000FD7603F3F83DFDC3FF3BF76BF532948F4B +:10C1B000DFBD5F10A4C968DE7138323655C175DB4A +:10C1C000D5755BD8AF689C73380EC2DE98F13B849E +:10C1D000AF78B1C88C51E8B5DF718C770CA83F2AD5 +:10C1E0008FCEFF637B58FDD9F1B1CE2E9804BB846E +:10C1F0005DF22D128ED12120BFA21D40F607F20064 +:10C20000CCA3BE82E363F44B8753C3E9FFABAA79A7 +:10C210007F6C07A5B947D5FBD51F5A8AB1FDAA5F28 +:10C220000B010BB46FCF34A777C2F7E08143D93845 +:10C230002F4D3ED7B6EBF57C46053384F7FB98CA05 +:10C2400017B54EDEAFECF058A3F1FB5AB55E836331 +:10C2500060BB61A33AEEB3766F753CD175C880FCC4 +:10C2600039FA25EBED38DF2D4BAD51E1FCACDDD7D4 +:10C27000189FD4779EE1ED118F03B45F3F50FB828E +:10C28000E7ADEFB381DB3F163FBEFFF6239EB66EF0 +:10C290001E64FE6DD1C7575AB15D86CBCC90CEAB34 +:10C2A00053BBB6AF86FC86A5668F05E8B37DC68F07 +:10C2B0005D88B7FA248EB728FDEE1A685EA35F2A60 +:10C2C0002D1D645E7B076B3F085C5F1E18AEA547A3 +:10C2D00006816BFB40ED473C5DDA32C8FCDF883EEF +:10C2E0007F250BE54E866C263D539D0D704539AE7E +:10C2F000C135821FA2F4FBEEC07019945EFFF63DBB +:10C30000E9F5E381C6BF007AFD7C60B80E4AAF5FF5 +:10C31000F547AF38EFEF41AF42C2807019945E63CA +:10C3200012BE1FBD260CD4FE02E8356DA0F95F00D9 +:10C33000BDE6441BDFC2EC5E05EDA202AEC7E71509 +:10C34000095CAF4B5CDEDB8F5E4D7AB40EF454E2D9 +:10C3500044D4D7C7362C2EECD5CF91FA27B2BF489C +:10C36000FDB9F8EF57919D3B46D57BDA7C6272238D +:10C37000FBB97D40FBEEBB8E2BBA58C816D7DB3E0F +:10C380006DF6BF7A3CBD7E17DBF9F80CC6BF6222A2 +:10C39000EAD5691E84F79089669D5DF9DDC71DB8F1 +:10C3A000BEEB8EEF670FCC49007B6064AF3D905EC3 +:10C3B000F98BD61389BDFDA48B254C72A0BD778B5C +:10C3C00017E9829533CF0E2CAEDCD37A625CAF3D99 +:10C3D00000F037DC14B66F3496075B4F84ADFBFC7E +:10C3E0006CA6EECF14B27773A54B49BF0FA6C7B5A5 +:10C3F0007DE326F44F0D477F94A4FAA35CAA3F4A3D +:10C4000056FD50DC3FD58CFE29F2834DE47682EA5E +:10C410009FAA57FD532FABFEB19754FFD8FEAA0039 +:10C42000A52F54EDA4746F5590CA9FAFDA4FF960F1 +:10C430005588F2DB1E9823233E7BD7E155D7A1F91F +:10C44000F506B6FB332BF47E90F4797A3F482AFA4E +:10C4500023C3F229E1FE4886FE9B1C5DF9908923E7 +:10C4600074E5B19EB1BABC3DFF525D7D9B5CACCB27 +:10C470009B9DD7EAF217EF9F1EE1E7B94D573E7239 +:10C480006759841F6781AE7C78CB325D3ECFFFA0B9 +:10C49000AEFED0861A5D79B6D2A42BBFBCFB615D1F +:10C4A000FEB24F36E9EA4FEADCAE2BBFE4C8D3BA9E +:10C4B000F2F11DCFEBF2E30EBFA4AB7FA3DDF76B70 +:10C4C000948763420723ECF400C9D310C80ADCFF49 +:10C4D000B857485778A3E0F1BF86F07D2BD8ED45DB +:10C4E000642F833C6B1A83ED95121BE4D37F0D34CC +:10C4F00027E396DD676043216DD7CB1F63F977E3B0 +:10C500006BF400607D37FC215FFE97B6AFDD6953A9 +:10C510007E80E3FBB83C56A4008BD64FAD6AFFE6A5 +:10C52000EE9C3184E8532A96A2C985E366DF27E1B1 +:10C530007A4674E8E934D71BCBBC385EB9E637E3FA +:10C5400072CFC8ABB0F4A3571F36A09FACF4D57818 +:10C550009CC73675DC06955F57229F0EC7F55E16A1 +:10C56000B2A870DB04F29919277B06925391F0FA76 +:10C57000AE72CD90A8976B208F431FA1FC2E17039E +:10C5800003EDAF347996FBD6DD03E24783AF8647F0 +:10C59000A3245D81F2C196ABB032475F3819654E76 +:10C5A0000FFFDBEB9623D67D8EBD5CE4C5F309E679 +:10C5B000894A273DEB2DBD8BD6A1E133B2DE0E5566 +:10C5C0000E3FAEE2B54D95C342B347403BAC5595E7 +:10C5D000C7C2A3DE1A84731EECA7713F686EAE0853 +:10C5E0005901EFA60C467AD2E804388CEEED77D8E4 +:10C5F000A37ABF4B6EB35E2EE6D425E8E021AF48A8 +:10C60000FB4EFAB42FDF5D46F68D468783F11F920D +:10C61000FCB743FF99712E8CBFDB672753FF0FAA2E +:10C62000FC0D1CCD5385BD89F4533651252026DFE2 +:10C63000FA3EC075FE611343FFCE0FBF6E3DB415C9 +:10C64000D6619C6891D0DE014D78E815289FEDB544 +:10C6500096607EFED151663794BF930644E0C2F2E5 +:10C6600092389403A7993015FD77A7D99B71E3C23F +:10C67000F4EEB244331FB7C174ACD38AC32B748EAB +:10C68000758F9FE7B575CD6DD1E7E7B0E9C9228C0D +:10C6900033E751134852189789C73A353800FECB13 +:10C6A0001225EA772EAB58897644BD89917F71D1E6 +:10C6B0008BA3CC683FCF1F27651BC7F4CEE3C144D3 +:10C6C000EE673C09F42687F98B173802662FB43BD6 +:10C6D000BE77DC8F2F63D84F60651AFA3BE3C11E2B +:10C6E00091FBC27756837E9E83AD2372DE8CD590FC +:10C6F000BCEF6F1EE24E833710852F1B12B95F5DB2 +:10C70000C363ADF567AD9D304F6FADC86C3F80BC66 +:10C71000C8CF9994A3B1811D28BF8B2B9EEC44BF39 +:10C72000748D45AA8574A3FD67CF61FD4A4018CA80 +:10C73000CB3D8932F7ABDADC013C7F60ACE292E9B9 +:10C74000B1DFBFDF17B0DFA47F7DBFBFEA67BE8B5D +:10C75000AC9D66E4FF2562C55483807E453EBEC520 +:10C76000E4F3A6A33F717F51289DE9EA355C60BDE3 +:10C77000C3869C0BAA375518A0BF33AA7CFBCDAE4D +:10C78000C7CD28CF4E3FFDE10DB82F5AF82B23B36C +:10C7900042BD33BB625988ECBE8019EDBE057B8D6E +:10C7A000DE00E543136E8E0DE7EB5AEA7FE173B1CD +:10C7B000B4AF5AF0BC25300DDA2F78E1F86806F2F4 +:10C7C000E04C4DF7A17484DFD306B2A399D239FAB5 +:10C7D00066F8BE4064779744B1833F48E476C7A9C2 +:10C7E0005FDA4B91DE0C3B0FDC45FD066F3559C21D +:10C7F000F4D8DB8926AD1EF9BD95A70C813C039FBB +:10C80000DF4DA3C2E757CDEB3DC5FDB90BF69B024B +:10C81000369CDFCE36B30FEA2DD9F977A2EF2B9EE7 +:10C82000DB1D877058B2DFA8936B0B9FFB66E5A5F5 +:10C8300080E78546D63D8DF4F8D7943FE7B5761B63 +:10C84000490E79E30C20B71693C8827ABFF8F8AA8C +:10C85000F7A1FCA4CBC86C200A4E767C64FE15E6DA +:10C860007D8E0A5049D0BF9E0F97EC3C6EC6794929 +:10C8700002EBCE0046FFC117617CC9FAD667ACDB7C +:10C880008C727649B0F1EF46A0B7257B4FBF877415 +:10C89000B724829F4FE23F52FBEA4BB333525FBE55 +:10C8A0003101FDE66C276C8226F5AF2F35FE5EB8B0 +:10C8B000FBDC3605C63FF5FC67DB144079F97FFFEA +:10C8C00063DB4F61FEEC559B847269C9D36FC7B1BE +:10C8D00030F8673BF939D399A79E7C6213C0E1CC4D +:10C8E0005F2C04B533AF7CEC96D10FBFE73F92F1DC +:10C8F000DCE9BE57AE4C413ABB6FDF152903ED2B87 +:10C90000906E039670FC0608BFF27E182705B22FC2 +:10C91000AB69045E4EEDF9CA8CE7095F1A5837CA55 +:10C92000DFC5C16FCC78FE70C8CBBA114EAFED3DFC +:10C930007EE841C89F063C59A2E009D69F2E905E32 +:10C9400001F68174F1DE9B6FBCBC10539347463CEB +:10C95000B16E92F77DF0FB16E0B7B017BF91E5E737 +:10C96000D8D76684FF925D80CFD18857C0E7E8BEF4 +:10C97000F83C8DFF98D4179F5EA7DEBF7D8E95B7DC +:10C980006EC2C2BD8984FFFEF0B968DF8F06B4B302 +:10C9900034F930189CE719F8BC1C4E6F893309E94B +:10C9A000C2AEB8389E03D3A0ECCCEE736E0674F220 +:10C9B00089A9FB2E8443F72B1609CFC916BCF22E8A +:10C9C000F1DD997D7F3223FEE12FCE3001F2ACE71D +:10C9D000EF4D06F9C5DC06678B58F755EF1562CAAF +:10C9E000BA150FE18FF287800F091F819BA6CA2815 +:10C9F0007F0349B4EEC501CE1F8B03076E318CEE69 +:10CA00000BF726A7A0E9AD1EBC1A26223E3FBC0AA2 +:10CA1000E9AF3F7C6AEB9770FD9740F9CFF5FC1BBF +:10CA2000597F31F02BEE8FFAE03770E00F989E6956 +:10CA3000B38806B085CE9878BC4724DE7BE1CFF57D +:10CA4000F377B58FEB9C91FB02DE5E83D360FC3EF7 +:10CA5000D8FABE2BFC963965EA37128EA7BE8EAE89 +:10CA60000F02AAFC58CC2AA6A60DEDABCF4456A2C5 +:10CA7000A467F7CE7765D04872FED44EB0C70D7D5F +:10CA8000E5C5E27ECEE19F75723B66F1FE03A351E0 +:10CA9000AE9D3AF84B952E39DD2FDEF5A15951F5B3 +:10CAA00043205C3EF7733EBC5F9DF79297A3F7B7B8 +:10CAB00064D7DFA3F67752F4DE8AF33FD961620AC6 +:10CAC000747132689C1ACDEEDAEE34E9ECE795B178 +:10CAD000138E0C8176C6B81819D75D5BE37D57417C +:10CAE0003BE64D139DFF33D1F38905CA6B63636445 +:10CAF000F4E7D5C6CD6172981EAF8B8093E82AA16A +:10CB0000F355D15952C8F77401DD39B00908227CB8 +:10CB1000DEA07733502F7D30E66313AEF36F1176CE +:10CB2000E4DF44B63205FAFB9B62F054CBD1F60742 +:10CB3000FAFE7D2B8C4C0EEB7FB1A5FB03F2C7FDFB +:10CB4000BB8DA15D667CD5664079B2649B89F65D3C +:10CB50004B601B8570FB78AB2DA0407EE32FAAEEC7 +:10CB600042BDF4F9360B9EBDB2D7F62DEF7A00E543 +:10CB7000D26603437FFAE7BFACFA12F5F2FC2D460A +:10CB8000DC2AB2B9F6EE27B0FDDCE7D2592DB4FFAE +:10CB9000CC109C809BD9AEA4D004DC8774ED4EF5FC +:10CBA00028D4CF8B8BB1DF33CFD9A9DF33FFFE2E53 +:10CBB0008D73E6DF6349AF69F3077B5B0ED7E360F4 +:10CBC0006FCB3D7C40F41A96877116629ED7377CF6 +:10CBD000ABCA3C947F0B3105BA5FB87F8817F791D9 +:10CBE00061F5A89F2596EE9F7868FFADA409B477FC +:10CBF0000AA5213F2EDCA91FFFBF5579B7C4DC3D34 +:10CC000087D7F7A771BEEDA076F624955ED5F2C85A +:10CC1000F65A7D5B528EAE9ED67EB1855544E38337 +:10CC200064B5DF853BBF19AEEF4F51BF478EC3BF21 +:10CC3000DF6F600AEA67B6C746F169E5E6D0B0047F +:10CC4000E0DB17CC6C1EF26F795C68583C8CF72BDC +:10CC5000556E96C7401EBEA7A9F3C0FA9867D6CEF8 +:10CC60003388D7452FDAE85C65D10BEF7E89F83C35 +:10CC70008530068C9D4AEAF8F2A74007A7B61A99B4 +:10CC800002F6DA224BC8BD19F5D41E0BDB8EFCFD73 +:10CC9000EAEBA4B74E3F6F11C2E3E222D34541A0B5 +:10CCA000066BDF7528C52CBF02E6A3ACF70A6DB88A +:10CCB0006F386C0C54C3D895A2B7E6395CDF6113AA +:10CCC000ED33CECE66F9B8AF3CCBD23C0AE15F7E05 +:10CCD0005784F2E5BF35199AA28C6B3A0F4A7F1C34 +:10CCE000F0C1F9EB983C0EE3C08652BADC5C311C13 +:10CCF000E5AE5182C51590FF81EC7693D3C3E64231 +:10CD0000BA3C81F9107ECC716D0F7FFD1150BAECE9 +:10CD1000313905DBFD2089DBD5F393BDD726917E24 +:10CD20007448A43F543A55F6F1797E6588F154630E +:10CD30005CCEF907EF46F82EFBD02087C79DF4C6DE +:10CD4000837A28EEAB5294DF950B69BD248F72A5D0 +:10CD50001886703D2B0974BE7076B63C243E4C2E6E +:10CD6000AFAE92487E3456B9285D5595CF64F26BCC +:10CD70007B286F54D76F29509811FA419EC63F8B7C +:10CD8000A3C48B761ECE09E3828C0E1FD111C6354B +:10CD9000A11CB33A18ED638D0E85CD453FBF83C30B +:10CDA000C7E82821F898D5BCD8328DE009EDE9FB19 +:10CDB00094645F4512E0D39A31422797CCCEB1BA42 +:10CDC0007C1F7869F8DFFD7F053746706AACB25288 +:10CDD000BAAA6A22C1ABBECA4BF9FF07B86DE470AC +:10CDE000BB94C75AF4C0AD5897EF176E8F01DF3868 +:10CDF000C3F906E0887CC3623C3BA2AC3F32DD5005 +:10CE0000C528F8E6E1AA164AB5EF09FDE8ED2F932B +:10CE1000B81D50C97CD5261C47E2FE16E65458C6FC +:10CE2000845EFF2673294CC63CF22AE2E5480CC119 +:10CE30006ED95F6DE437364A6257B85C5B76BD9C4D +:10CE400082F2CB58F9383B9E18E6479B566293090D +:10CE5000AE1E3AAFAC55F5667D0FFEF47CB0BA4A13 +:10CE6000A6748DCA0FEB547E588F78C6B8130F3F47 +:10CE7000DF6C9ECA482FFE1BE4F93E3EC4C2CF9D24 +:10CE8000E23DC19009F04D3252A63444F1C0472C26 +:10CE9000813C68672F605EA48FF8230F90FF1823F2 +:10CEA00074D19F16AFC28DBD9C133F23969667E247 +:10CEB0007A871979EA37A13D1E09D75ACF412BEE5F +:10CEC000AFFB9B4FD107F30D38DE5733084DCC79BC +:10CED00047F008C6AB3A9AEDA457933D1559E8DFE1 +:10CEE00063472D449F0E8FCF30370C7FC9FDD87517 +:10CEF00095C9D79C40FAFB086D25C0EBC32D436D47 +:10CF000008E7D5A6A00BE5DDEA78AE3FE45280C283 +:10CF100025BDEDFEA0CAC1B8423DBF6BF2559A3C9B +:10CF20005647BF9A5C4D98A2A7734DAEEE4FE2F6FE +:10CF3000DAFCE4922F51AE269EDF427C1849F7B905 +:10CF4000D2A5A53E27EA01E669427B0D6D46B4E312 +:10CF50003E340438BD73FFD4D9CEECED68E7C0AEE3 +:10CF600080E48A82FC4078EA7EED5B68B75B950FCF +:10CF700035D6E9568A73043A6214B72E1380F1FC51 +:10CF800090A9F1ED9C3F2652AAD1676672B62E5E3B +:10CF9000D0987B48407CD5831D4171C5B0BF73E0FC +:10CFA000F9F8814956B4F74493E730CAA9EE5821FD +:10CFB000887AB3DE31DD8AE74A86F842C2FB97B150 +:10CFC0006559039D7B82DD427E5BC9E161C7701CB0 +:10CFD000C6C86F6B94C632DC27EE7674C4E0BEC55B +:10CFE000912CE8ECC4F9C9BE9CE4B0FC281C5DC5DA +:10CFF0001776BB5BED2772BCD1C9AADF324361DE75 +:10D00000B0738B4A8DBE65854D09E3EF9ABCAB5872 +:10D0100067415FBEEE576EEDF87E72AB362B40F87F +:10D020003245CA0B27C87107A58A0028352A59AB93 +:10D030006F1F4374558C70608EED3D76C80F73A2E0 +:10D04000D0D791112914B7D9A36760D75C407A660D +:10D05000E3446E8FA87A86EBA7B3CD76D24F67678D +:10D0600057503CD5D9E61419E9EEC0DACB46233C3B +:10D07000E69C6F6432CC6FEEF94994CE6B7984D222 +:10D08000B296362072C6AAD7CC5D3B03DA1D7FCCA0 +:10D09000E841BEEE0A8C3B5309F9AE660B9E11B116 +:10D0A000AE2DF766A15FBC0BC641FBAA6B4B1ED130 +:10D0B0005717C08DF20DFAFA182F6C04BC9431A6E4 +:10D0C000C619CA5EAC3FE775635B343BA96C9DC56E +:10D0D0001BED7CA7A7BC25BADD568BFF4CC5FF55C1 +:10D0E0000C4778157DF04016AE57E3FFE509208F19 +:10D0F000105E1F5858347FFC94E42B17223EA62460 +:10D100007BEFE5784988EA5FEBA57F3EEE7101ECA5 +:10D110005BC28B2FEE269D9F95FB318FABF62FB315 +:10D12000F6531EA7B697A2972F6AFEECD043905BEA +:10D130005550518244AFEDA745C6F7D38BF7DFA416 +:10D14000C6F9F3F9809D4A74CC001F285F66ABFED8 +:10D150001E80FB8D78AFE4F8EB4603D2472F3DF9F4 +:10D16000E2D06E31ACBEBE663794FFE330DF9FCDB8 +:10D170003FBF9EE49D61F5A88D93E0FBBDAF9B484A +:10D18000CE57375DB6EE0EC0EF176F18293FEFBCD4 +:10D190008DEA7DFA9067E31D50AFFBF726B2C3BF5F +:10D1A000387C25C54D7C6AD2FB092E4BE17CBC5FE7 +:10D1B000E5E739E75793FDA195CF69986596894EC4 +:10D1C000D7D2F739786883C1BECAADBF2B12F13C04 +:10D1D00087D1BD85FDC9B75C57437A6D2CD9FB73E8 +:10D1E000D7583CD1E2A8F727CB3AF933B7B399FA2D +:10D1F0006560173993D5FEC2E4C8DCF389C4074CD7 +:10D200005218C619CF51E549CFFCB69874F2E453D1 +:10D210005B743FC8E164BE8F9A73FE32E2AFBEEB2F +:10D22000FB017D9FA38DDBC9F9B1773D1B27455BD2 +:10D230004FEF3A2653FD4FE3A38FFFB93A7E57D500 +:10D240003CE605B95466817A0E1CFFDE95130B711E +:10D250001DF10986B075CD6D59C8BC61EB9ABB65EF +:10D26000A6B92CACDF5E3C2CFD5D516E2F1E3EDF5F +:10D27000507E5D0DCAA3E492F7916FCA565F3E1AC5 +:10D28000E9716E4B23C1F9B8C9E346F9FA71CBBD18 +:10D2900071BEA8F394757A6B6E8B8A1FB0770BC33F +:10D2A000F0A3E125B27DD75FE77EF910CA9FC7B82A +:10D2B00071D31FBCFAE02D3B3ADC6C291ADCF299E1 +:10D2C0008FE026BF7004E97A8DDD8374DD3FFC4674 +:10D2D00032DF40F0EBC77E057B474849C27119D168 +:10D2E000E9DC164E0783C1AD775C950E8AA2AFE7E5 +:10D2F0001295DFBAAA2A99020C7BCC3C181DFC942B +:10D3000029D601D6D14307FFA6A3834B52D6101DC1 +:10D310007C82F6CAF0BEF83F6656E22EC5739F26A1 +:10D32000239D2B1D8B51926FE3F931288F8FC5F907 +:10D330006FC0731A2D3F7F475EDCCCB0713F6E002B +:10D34000384481DF252911FCADD14FAEC20A26FC3D +:10D35000EFD1CF71F59C38B2DE94E4A2CB52507F6E +:10D36000F8A3FB6BB55493D7C6218E9E7D26EACFDA +:10D37000638E9C2F0350DA94ECBB1AFBA98BFFC978 +:10D38000DD280F8E1D3390BEADFEEBF2E1A8D72253 +:10D39000ED04D87F36E0B9E77263AC9FEC50B1A2E0 +:10D3A00095CE411591ED28C47D4AC5A61379E8377D +:10D3B000ACA494A976E872E3080FEA6123AB781273 +:10D3C000CF49814824AC2FB20A3A3705415882F937 +:10D3D0008D767EEE5A295A254B585CC252955FEAEB +:10D3E000AB4A1E39817E68ABC2A4F0B843C6EDAF2C +:10D3F000FFC47986E97BB3C92779701F6A6025C8A5 +:10D400001726D1D7900DFD9B5CCE314A181E96A4ED +:10D41000F0F3765B7B7B4336B4B7DDF37B89EE1D9F +:10D42000C138E867B3668867C3FDD5266790EE0903 +:10D43000B1DCB0EF6057390A20AFF303C07C07B00E +:10D440000B7F65F0B8BE447AACE6F098882082F491 +:10D450002FB387B6A15C9E28D61931EE68C63D79F8 +:10D4600094DF38EBDB619D51E861C6CBAB3AD09ECF +:10D4700099F172EA2C3C3F98E118F611A6B05DB024 +:10D48000C640FBD70C2CD804E914EBE314D7F89A68 +:10D49000EA1F6BC77C985E6C57E90DEC9CA97B205A +:10D4A0009D61F59B9616F4FAD322C7DDA0E2A5DDB7 +:10D4B000144C1A817400E3E03AEE7C39F02350FDFD +:10D4C000EC8E60E0FA51809FBB58B709E1E8631227 +:10D4D0009D7B687EDD32E651F38CF6A7EF979BB615 +:10D4E000239D44F6774788F777673BF407E95D8724 +:10D4F000BB7F8D6AD91794AEB2B3B0FEF67B0ED95E +:10D5000059DFFE22E1EC11AD46250CAE8022211C34 +:10D51000EE7DE03BA4F45A36BA7F3EEB85379F4759 +:10D52000243EBEC022E0D3408AF77994C35529DE59 +:10D530005F605A6EED768B4037EF3B7D2F221F2EBA +:10D5400036FAB292011EA7337DC393102E1DD1CFA0 +:10D550005F23F93BB7F4F456E49BBBAA4586785E9B +:10D56000B9EFE3ADC897A74DC047B01F78ED818FE5 +:10D5700063916E16010386CB930F2AF3C87E3ABBE4 +:10D5800077F880F1A71FA8FE923FAA7CA2ADF36EA8 +:10D59000644018EFEEBD76DACFDC5D69ECD9672127 +:10D5A000BDDF5DC9E34398D831FA169DDD59A79ECA +:10D5B000B3F5ED07F71191FD7455F95A89EF45DF81 +:10D5C00004B4BB8F57CD6B45F91239CF3C97EF1898 +:10D5D000C2756ECB4C5DDCEDECE6F9ADE17CA8D517 +:10D5E000AFED47BEBE344C5DA7958FC7E48B8B1C57 +:10D5F00013F05E35FFB385AC1F1AC2E861B0F15875 +:10D60000EE146F8F5CA07BF702EC59FBF617594FB5 +:10D61000EBDF5579053B3E0ED7E7FDCF94F183CF85 +:10D62000DFE452E599DA4EFB6EF3F919DA85B6AF0D +:10D6300087909DF0D230EECFF80FD52E600E582F88 +:10D6400032987FA3F7FF63BD3030C5E7D9B658A243 +:10D65000C615A5B9443ECFE0A1226B94F9F5E92F98 +:10D6600024B20BA9F7D230BE7E749391BF6B580CD5 +:10D67000ED6BCA2A6B699FDD08F203F541E47C8EED +:10D68000356DA678689BD92FA35FB4715872760D5B +:10D69000B403A9467E1F5B8C5F16C3BFABFE205B45 +:10D6A0008D5FC6FD6D635E1A7DD7FA6B347039AB42 +:10D6B000F14523ECFB9E27BF98C7351DE0D2F856F5 +:10D6C000606A2CB4DBBE92858C6EC60EBAD346E27D +:10D6D0003ED75F6FA6F3BDC67C217536E4E332AD5D +:10D6E000E41F6B8B0FCDC07B078A4124FDEA8F9727 +:10D6F000AF8945FF6E4D4A07CABF834BCDB4DED517 +:10D7000093F8BD35CBA527FC5760FFF7310FEAD55D +:10D71000EDE77FD182F7FE9423B09F45BF21760AC3 +:10D72000F268FBD4B336DCCFA5605C1DD0D91653AC +:10D7300090E6B5A9DA42FD6E6A339746C3DFC95455 +:10D7400091EA070C9D141F9CC8823684EBC353A733 +:10D750006FCC8576D9B94CC2FDFCEA82B3DABD72D2 +:10D76000233F8FD2FC88CCA69E6759D5732ADDFD56 +:10D77000B8CDFEBDE43FB44F0BF274AA40FEE7C83B +:10D7800079DCEBE27E37FBE48EA9A827EC85023337 +:10D79000A07F3397D1BD66692A58E19066E7B37ED2 +:10D7A000DAF3754B5E685FC8DBA34F48BAC0F60B6F +:10D7B0005D3CCE700DFAA1A03C60F218AE817904F8 +:10D7C000AE970C8ADC5BAFCEC5F56B2BF41F22390C +:10D7D0001AA075B9F38321A43777B940785A33F189 +:10D7E000189D0B3C5CA8F9513D348F2DD5EF1C40A2 +:10D7F000FB6BCBFD8CECA42D2843A1DD96EB59806F +:10D800009F27B134946F9BE69BAFA3F3FC0280BFCC +:10D8100081D2A8F3F6A55A892EDD2B1E0EE13DFE1E +:10D82000180FA37713208D5ABF2195C369932990B0 +:10D830008AFE91FEE8E256151FEE4AD5AE627E17CB +:10D84000E275AD0A1F76CB58EE5F10BD72781C579B +:10D85000AF3EE17E0C581FDDAB4DAC33933E12A6BC +:10D860008566E0BA12F2CDECEA6CE42F0E376594CF +:10D87000C0E3CE58A005F9B3EDA2648A275D250464 +:10D880005CE86F568ACD749E7C70A230631E94AFA4 +:10D89000AB33931F02F2C42F7E6F4E1BF29B7D723F +:10D8A00071E93CC8AF97CC12C2B7B640B2211DD7C0 +:10D8B0007A05C900F9B525DA3D091683781B63346A +:10D8C000DAF2A1BC3555401F2D6B351888DFEBBD52 +:10D8D000C5FEA1F0BD5E721AC2FD002FB9F8BEAA46 +:10D8E00022ABE42517F28DF761FF5099E3529C407B +:10D8F00024467FB12C340F636EDAEA9FA0FB546B91 +:10D90000C65819DAF199F7F9E97E57EC456619F12D +:10D91000BAFD7CE2485A5F9D59467E5E6F085C8383 +:10D920007CBF65E92105FDEAB68F1CCC08F682A311 +:10D93000F3EF55183FE62834479C633101E5B836CC +:10D94000AEE3AD10D153A7C1F7E758F2FF1434E5A9 +:10D950003BF11E46CC0484E7DA4BDFCB9F13852EC8 +:10D96000C8653B16ED6521346134CA29AEC79828D5 +:10D97000A586E3777D66DA5FD0CFB4AD08E68FE3A6 +:10D980005576DD41F3F2BEF353B4AB1C473FFD26A1 +:10D99000FA3CDF243D127BD41E124663BA681AD9C2 +:10D9A00067E1F540EEAFCDF29E70017C775773B919 +:10D9B000DF7C0FA37729F02F3F0CBECD0520A5E912 +:10D9C0006102803CD62B90C88FBE4A90832184E7A9 +:10D9D000682BD1538A7AEF2172BDF6A38D4B31EEBD +:10D9E000C8EED1CFF32B15BFF82726D379055AA25D +:10D9F000CC9C3ADB86F26FCF583915F7DB0FC7475F +:10DA0000D7F3EFA572F9B0DB10DD3EFF22D5C6FBE0 +:10DA10000759199A40A86214D707792199CE6DF851 +:10DA2000FB0A02970BEC5A467A2F6E4CA7CD1336A1 +:10DA30005E501D87FEA09F216A3B267587AA61FD67 +:10DA40006D40B578AF2D2E93C3D1A1F4C211EB4B2D +:10DA5000EABA800FAA8717221025AACF4ACC742EC3 +:10DA600002D250F956E88543AC5A7FD344D1608541 +:10DA700079E500300C503F7EAA59778E22D5BDA3A0 +:10DA800060F94F8D4C4E98D83BFED6312C5003E3B5 +:10DA90000FF1EAE11D7BDF0BCBD12E8FA4039C415C +:10DAA0004FBF182A3E5BDF2EF98E3E7C40F0A479F2 +:10DAB00002689ADF62DBCD0094E69DA2161F4BF24E +:10DAC00077BCB143417F28C0AA641FCC7FC4536F89 +:10DAD000797741BED9C7F92C36FF85E54897521AA8 +:10DAE000C7D311F42D039C3733E91F18B7A3540A89 +:10DAF00032E2635B2887F47823134B104F8D15EFC8 +:10DB00000828D757EF651E8301E9FFBF2DE1F39B7E +:10DB100091CACF69982893FC13DDFCFEE8EA02C1A4 +:10DB20008EF2F5E0D21748EF6D3D2030E4FFE2DFE2 +:10DB30001C7DCC8E74FD170BE59B5FAF20B9F113F4 +:10DB400068A744F19F0FA69723EBE72EDA6EC0F388 +:10DB500089AC79417A8F25D12F7AAE467CCCEBF017 +:10DB6000D23DF7427ECEE6981652288F5A0D6C525F +:10DB7000D9AFA6CDBC9CDD9240FBA85196CE866B5A +:10DB8000617E9B9F1219EA4BA325983A17FA35BE7E +:10DB9000E8404DD0677FB4795A2815E5784C058563 +:10DBA00041F7B5E352391FBAA7C9BF1D06FDC64FDD +:10DBB000E6B0B4F9530EA0BC449B19EF35D915AEAD +:10DBC000E7D68A012FC679AFBDCF67C6F199BA7F74 +:10DBD000695C54F604C2F91355EFB18A79F48E8961 +:10DBE0005BE5177B252B8AB6CFDAE88AE1F12D0FAA +:10DBF0000907903FDC5E46FA43AA0C8686AB7A1989 +:10DC0000272EAD78BE11F58BA35CA075AC153BAA91 +:10DC1000F15D89B5F731A95AEEDBDF3FDB7E79AAEA +:10DC200085E0B1D1C574EBA0F73040BEB9E7455FE0 +:10DC3000C7BFE1B8E37BD711A3AD23BF93F2DA3CB2 +:10DC40005ABDC10B9AC706B53F7F2A7FC7C85EC0C1 +:10DC5000DFEF8894F735F60FE85D9900D8EA46BA09 +:10DC60008F16BC16F3F27302E3F7B5F4FCDD27AFB1 +:10DC7000D255E47799858D938D74C7F10C74A7DA2A +:10DC80004FC07756140182FC2DF931FC34CF487A0D +:10DC9000FC5F978BE1F386FE631B9841BDA72A17B3 +:10DCA000A7F6958B4C958B56A68450FEFD5FCB4511 +:10DCB000908324179B61A589B053896D6F5A8A7A26 +:10DCC0005C9387E31127976227D6EB8B0B685F4441 +:10DCD000F909A9BF6FC6F8C855827ADEA5C205DD6D +:10DCE000500897AF5D728F9EC2EF1BF01F39F89EF0 +:10DCF0004AC2750530DEC6D29C31B8BFB0F95F2488 +:10DD0000FBC05DC0E357DC95FCFCDC9E3BE789F083 +:10DD10007B714B52B99DBE44A3BF4ABF0BC7598B01 +:10DD2000FDA27CCE3593BEDCCC825C1FAAF6E95600 +:10DD3000971A47ACD255249F44CAA771BF7716A340 +:10DD40007C4F355824DCCFA17E3E98ACD7D7482FE6 +:10DD50009ABE6EE9A889477F58B6EAEFCFB6EAE3E4 +:10DD60001C26A4717926A6723FC02AA182F69B4A7E +:10DD7000B140FB388DFE7AF478041C23E18784BA25 +:10DD80007202C5C7503EAEA89B21FF6E03925D8F05 +:10DD90007A2C5583BB44706EBB53188BF2724F7B49 +:10DDA000990DFDEB06B7F51ADC1FAE3330BAFFB89C +:10DDB000AEE84D8A2B69AA849E61518E7C61A6795A +:10DDC000745F3C031FD37ED5AE583AD0AF150C6DAF +:10DDD000A7B885A6C0A1198CDBB10CE3529AF26BEF +:10DDE000D216A07CCF2F2944FCB6D59B296E46CAFB +:10DDF0006751FD0827711F43F3FD6E7ACCAEED2FFE +:10DE0000CBA3EF2B6F4CE3FBDBA008A20AE69391B8 +:10DE10002F7890FF33EACC51E751ACE2292D8DDF0A +:10DE20000F6BAB3F44EFCC00BE026C207CC1F46BA7 +:10DE300092C3F031A91F7CB8347C881A3EE2671285 +:10DE40001F7676085CDE925E5BCBA4DB503F2A1522 +:10DE500066B2631B4D7C5FBEBD40E50BC9DA86C46C +:10DE6000F65DE93A6E9140F7703227F2F7F5ECE58E +:10DE7000CF535CD366D6FD3ACA3BA580DFA38F6C37 +:10DE80007F679AA0C2513678683FCDF10878A5F92E +:10DE90006CC94B6E0BE7D38DAA1DBDD1C5F9744B70 +:10DEA000FD06E2D30B9DA726B76B553B7ABED7671D +:10DEB0004675A0184AAE4A45FDF973FE1E15333A61 +:10DEC000C82EFF049B84F9652B337C4BD2C2FC72B5 +:10DED00092B742C07A57E2BB42D0FEE320BF07FAB6 +:10DEE00071F01745F41E978F1133CF671D066272CC +:10DEF00090A13B20EF128354EE9A077389A7DB9120 +:10DF000094B75A412FC2844E57F1FB175DF8BEE417 +:10DF1000707C2792BF2FF999FA9EE4A89655C59B6D +:10DF2000713C59F4A1CC3889EF4BE2FDE789EF5100 +:10DF30005CF42990B54DF1180FC3EF6F4B0F3249C8 +:10DF40009884F935C518F77CEFAB16F59E64470D3C +:10DF5000DE7B795C60F48EC46A11F4FD502C6A306B +:10DF60005484D1F1EECB3BE2F09CEF74F0E601FD7E +:10DF7000C7787F10E7B143A5F7F5F6C574BF6C8E7F +:10DF800023E4C6F607F63CF9C42618EFB37D567AAB +:10DF9000D764A37DB11BCB3F7BEC5D37EA8BD3FB12 +:10DFA000DE35473B9F5C2406AFC27B64E5CA105652 +:10DFB00003F32F0ACE3453FCC9AE03743F6D91E4D2 +:10DFC0003363FFE52D7B283F65D79FDC587E348D7A +:10DFD000F3C7E9549F1BFD12B92D969000FA67779D +:10DFE0008E7F41D47376951ED7DB5FA5FE37DA5F4F +:10DFF0003D847839FD9885FC6E071EFB0DF57B6A24 +:10E00000DF8B34DFCF76BF7B17DAD3E58C79509E78 +:10E010009FB6A97E3D6B475CF8FEF615151E5AFEAD +:10E0200074ACBA0FCE18A49E7A1EC31C007FBA3FF0 +:10E03000D01187F70B3F33F9CC088F85080F488B39 +:10E04000000E28F717060D34CF852D6D74DF6AE1B9 +:10E050005EEE1F5C08F022B8B41CA0F9BF8F7019E7 +:10E060008FEBF8B39BDE75D86BA1FDB3B6EE850ED2 +:10E070009F1BE1A3AD17E0C0D7BDFBC2F03447C37F +:10E0800053CB9F685EE57BF9BCCA77F179CCD90B9D +:10E090007872209E6612FE4FED6332DE83E9DAF37A +:10E0A000EE49B4674EEFB3CA685768F3CA00711BF4 +:10E0B0003716F988EB63B6D740FA98891D749EB37A +:10E0C0004892247C9FA0A73C600E7079DA519C0E88 +:10E0D000E5CF3C0AF62142420A8E40FFEAE934EDE0 +:10E0E000FE4F871BFD62BB2FF7137D7E1AABC25B11 +:10E0F000EC7063FCCC8674DFE9B4B07882D31FBEC9 +:10E100003802D7BDDC58F19B4C1CE7491E1FFA555D +:10E110004EC5DF1EA2790FD59D3746A600B7383C05 +:10E12000FFCE17988FEE25EF7D2D26FC1C5A48E771 +:10E130007EB78DF60FE83EE2697CE791E613A438DE +:10E14000AD61DE32379EF37DCA1C3E3C97FDECE7A5 +:10E15000AF51BC4D57AAE67FEAA07AA7F6BE9680DB +:10E1600069991A0FCF0237931C03383658C7469364 +:10E170008FEAFDA200BF3776C6000213F5C4560D24 +:10E18000CE15E6E9BA731D2E4733B664B793BF25A3 +:10E1900010FDBE59A4FCCD7D74129D2B9F63D1CF81 +:10E1A00095991A27B7DC1843F1371BED3FA3FBB74E +:10E1B000958A45C2FB2BC754B97842BD97FF554C91 +:10E1C0009C2200DDEC4FF7E5A48FEF7B0FB76CF5D9 +:10E1D0002237C2B70CCF3D28CEA0ED7A8C27EC4A6F +:10E1E00062AADDC942043F9356BE9197C7F3FCA4CF +:10E1F000CDC135F81E26C297D77F829767F3F21FED +:10E20000A9E573D24AC6A473FF0EBDAFC19829BE5B +:10E21000CBCA55783478F4C245645D9A5D0D95E7B4 +:10E22000E1E5DC24EAEF32EA4F84FE467DFFFE00A2 +:10E23000EF8A35E15FD08FF55FD54F90F492E0C360 +:10E24000B7AEE09B87EBBFC78B99D414FFFDFBFFF4 +:10E2500067DB2F377A854F910E870844F71A5F776F +:10E260003D367C0CEEFFCD0D4B43A836BB628BCD0B +:10E27000A9F0FD9CCCCF4FEE79743D8B164FA2BD1B +:10E280009BD19357CFF1CC43F5E7B3ABD3B9DE596C +:10E290009DDEEB7FC373393CAEA28D33FC35275333 +:10E2A000280CB7D3598580F187F9ED567ACFF7223C +:10E2B000068202E63F928504D4DFA35827E52F4665 +:10E2C000100CC5F7A8647A38731CEB768B43F1FC0D +:10E2D00039B412EDB4F79DBEC67418EFCBC73A3E01 +:10E2E0003040F94FD27C2F75A25F289DDB570EF589 +:10E2F0007D5C0953A043C13ECD154DEEF7C05312CE +:10E300004F859FB7DD287A1F49A7F564485DF65E03 +:10E31000386BF26081FAFE92D6FEE4534FE2563734 +:10E32000ECBD70EF80F781E754CE7FF4E7E3062879 +:10E3300057E5ECEEEAC06DE1FAFEC974AE679F4E98 +:10E34000177476218C4A76DCD33771FB69F7E5DEEA +:10E350009AC751DEB618693FFD69CB9FE9FDC773C7 +:10E36000258CECBAFEC6FD3402EF9FEE78328D9F0D +:10E370007704F4F1CB4FFC724478BC258059764E7B +:10E38000E0EF7010DE0F79148B91EE39923FC6CC1E +:10E390002A789C0ACE17D218DC8F0E453C75501A8D +:10E3A000C7BA29959844FEE904E6A1D4C94A284D84 +:10E3B0006615066EDFF9294D63414A33D03E457F2D +:10E3C0000FEBA654C61B9F61F11B3978623A14DF2C +:10E3D0005D2DE1DF23E28344C4E3B828F23C222E22 +:10E3E00048DC5949F21CE382F29C7DDF53D0E4F70C +:10E3F00086F4E2F7906EF6A77BDFC7F4F0B3BFE5D3 +:10E40000F72BD618C8BE3E6E9B66960175CF247852 +:10E41000E91D104560253B40BFCFD6FCFFF8A7C5DE +:10E420000923309B4DA7C2E37798D5918FE7C5B3F9 +:10E43000D4AAB3D4739059AA1F248631F59E9E871F +:10E44000EEDBCF52CF1F6645F85F98DFA2F3A3281B +:10E45000F80F58C72CBF81CE0D66C54C7BB593F520 +:10E460004F2761FDD1BDBFB2083FD4A0FEAC88FCF0 +:10E47000ECC8F65603B326E3774E4FCFFC4026BBDD +:10E480004EF36701C1C9D4AEC1F221F985FC577AB8 +:10E49000C3E19490C1F9C4E6BF3A2EDA3BD95A3AA7 +:10E4A0001BEC335342DFF6B0238C47BED7E4B046B3 +:10E4B000E7D9B8B1453ECA3707068A4B5DADEAFBDE +:10E4C000A687FC0CE76D0B3D40EF54DF9FA990AF92 +:10E4D000D65A10A0FB0131F9019712657E4DF8BEA6 +:10E4E00033F05753ACFEDC64A9BAAEA519DC7F7BD0 +:10E4F000E8A2E4623CCF5E250B746F7895BC8CCEAD +:10E500005907FB3D815AF57704B4FCCAC46D0CED84 +:10E5100036DBD7AD0CED499B18FD5ECA0C75FCF5DA +:10E520006AFD8D89DBC84FD290C7CFF723EB1FC898 +:10E53000DBE042FBBB311BF6BB983EA450FFF579F4 +:10E540001B4AB1BD35D4A8BBCFEBCBE0F6AD752FE0 +:10E55000A74763AE399083F420FA29BE40ABD7D8E1 +:10E56000CF79D2F56AFB265380EEC934A9F6D0D212 +:10E570002DB16BC92F97B1FD08BD6F95CBE8BCD10C +:10E58000167A8ACE11ACF9666683BC55F6337C5F89 +:10E59000C3561024FCA0B329A4A3DB98DE77368CE5 +:10E5A0007DFBAFFBD6EFC2F53566FB69FCC1D65BE0 +:10E5B000ACC2B351D5AF8D36FD39DAC20CAE57AF10 +:10E5C000CDE0F2DEFA32237932005CC8DEBB3E23B6 +:10E5D000EF06B4EFACFB0785A3AE7E362B1D128D84 +:10E5E0005F22E5BFA340887847C940F33AB7D7A078 +:10E5F000BEBBC8DFB1E8B5038266ECF7D75BCA0ED5 +:10E600005E03F359E07378317EF2C92DDBE99EFE9B +:10E61000C2174D149F30AC732697832DFC3D46EDF9 +:10E620007DA38B5A2CBAF7A416B1B0F71A61BC853A +:10E63000473F3DCAE89EB1FEBBF66EC06AFC10259E +:10E640004E2DF2DD81473222DF5D56DF1D2888EE38 +:10E65000A7897C7760575020BDB10CE358691FB083 +:10E66000AD18F73D95470DE437E8CB87F2D65C53FC +:10E6700058DEE0217A546263BC3BA2F0D37B999CC4 +:10E680005E76E3A11AD9FD3F5B1BC237BB581DC3A1 +:10E69000F3A6DAFB4409CFB56B033174BFA456125D +:10E6A00002183792195B6C45FF238B1724BC8776C1 +:10E6B000957132DD7B32DF2F8EA3775AB72FE8C0FA +:10E6C0007B75B52E91211F67C6F33802962AD0FBC1 +:10E6D0003475D29BF1B3701FE7E0F7F4B2241690C3 +:10E6E0000D68D779199E2FC366A52204A657A6C127 +:10E6F0001BC2F7AED8248BB483BF3373C39809E42D +:10E7000007A6BF036D57855EC171BCD612C4FF94C6 +:10E71000FB9D640F065C467CDB947D9CC1CF05CDE0 +:10E72000B1C5A1BFE2FC66D8C9B71B508404C4C3FD +:10E73000EB6D2BA75F0DDF4D0191E21DF2BFA9BD6F +:10E74000ED6A68DFDD66A6FB161A9CE43A51F77E97 +:10E75000837B853E6F8E78AF426461E5903FA2CEA9 +:10E7600083B152160A8FE3757AF9A1BBE4A0F729A9 +:10E770003E02FEA4F30F35FF9E9ADF69F213DE77A7 +:10E78000FED540FED5836D73B2485EDA17B7DA71F5 +:10E790005F78849F63F6279F7766C8DA3B0936F572 +:10E7A0009D0A1BFABD22E9A9AE8A7930CED01A683B +:10E7B0008F1989F83D6CF2605873BD2A1F45079781 +:10E7C000E31ADD44A6F511F4576FF2E4FBA17EFDD8 +:10E7D000374675DF78FA86D0640C7B90695F6DCA26 +:10E7E000601E640F93B3234D82798C7CD1ECC1DF22 +:10E7F00055B8EAB9822128E747BE3683E41BC289AF +:10E80000DE87AF347BD04EB6543A3DE238ACE720D9 +:10E81000BA3CEB30933D2456DAFD647FB54D70C9A8 +:10E8200061726F6595E4114DF47B3794AEEC47DE71 +:10E8300067C50B25E87735ABF672B2BAAEE44C3B50 +:10E84000A5496ABE5554A6233DB702DD60DCCD81E3 +:10E85000159CBE97A55A496F2E7B7D68CA40FEC1A4 +:10E8600027AA5C9E5C00ECB61565E4B72D7AE044FF +:10E8700023D2DDB258AB8474688C1BB67132D2FDE2 +:10E880006F4D74CFB33676823C2BAC3F63DC4417BC +:10E89000C2C328286948CF233383378893904E9486 +:10E8A0004D789F7FDCD68D3788205F76C62A6978C1 +:10E8B0005E76D9D6CDBC3C49D96480F22BB6B6F28F +:10E8C000F24C254D80FC755B1FE7E579CA26CCDF4D +:10E8D000BCF5495E3E8AEBA3DBB73E7303EAA35A5D +:10E8E00093A714FDD3CFC2FC0BF2F09D549EDEA97A +:10E8F000C2452B7F1EBF9BF05D559E4696BFA0B6BE +:10E90000DBDF4FF94B6AF9CBFDF4FFAADA2ED44FC7 +:10E91000FB836ABBF67EDA1F52DB1DEEA7FCB76AEB +:10E92000F91BFDF4FF07B55D473FEDDF54DBBDD5B7 +:10E930004FFB77D47647FA297F4F2D3F1AD1FF0737 +:10E940006AFD4EF5BB3BB6E13DB4D7DC20AF509E2F +:10E95000E4C73690BF6B5B6521D17FED78AEFF35A4 +:10E960007A77ABF702DECEE471A56F6772FB66794A +:10E9700026B70B8A1EC85D3719E9F0F7FC9E22E81E +:10E980008F23780F57794020FFDEB2D7F9BB32CB07 +:10E990001E1075BF1FA4B5D7E61F50E759A7A64B99 +:10E9A0003273689C6CC5E59916A61F4D923E6F05A3 +:10E9B0007EC2F8FF3A27D733F90F1437E0B9492D53 +:10E9C000E8195C5FBDC31C42FF57BD2452799DB35B +:10E9D000D88FE7FD8A24921EAA772684F0BDE6BA76 +:10E9E000BA42DD7B9F759248EFC788F153ACB31CE8 +:10E9F0002837A649283FEB98945044E76AB04F4324 +:10EA00007D52592CA1DCC98E7726A05C9E95C5E16C +:10EA1000DE1EDB65C37B14E24302BD15304C128958 +:10EA2000DF73EB84800CF368979691FF7547B37A98 +:10EA3000A6C8F879A226E777FEEC2AD263B5A0C76C +:10EA400064D2636CC898E4DEFB9BE2D19166D45B30 +:10EA5000529A9199402E1FCA4CA071773CCAF55624 +:10EA60001EE82D7C67ADB590F177DE5C56F2EB9633 +:10EA700089CC9518E6C73C946954DF47E2EF50E72C +:10EA8000E17B8861F01DEAD7EBADEC41F4565625E9 +:10EA9000C8CBB0FA1697A4CB3F97A9BEABE4611ED2 +:10EAA000B46FAE7A6E0BE993B3A84F18EA973FC4E0 +:10EAB0008C44FD027AC4C2FACA414D1E6B768B2685 +:10EAC000A76B55BD511BA1370697BBFF787D38D189 +:10EAD000A7A07B87A63FF9BB1CE304005E269F81AD +:10EAE000F40A137D74BF7F30B8994C2512DAE383A2 +:10EAF000C1CF94F4453CCA69934FF49C88724F6A25 +:10EB000030F86AF5CCD6F4ADA8D7BE38BA3C1FFDB4 +:10EB10005E2B4D1D337721DD1A86D0FD0E59F53B56 +:10EB20006CABDACF8EE7E1EFFABCBFA56E1CDE1F3F +:10EB3000F74AE42F492D96B19D0DF6E98964C7F196 +:10EB4000FD26937CFE0568CFBF6896F15CE0F0B3CC +:10EB5000EAFB0D990E82E7BD7BEEA3762643858BFB +:10EB60009FF73382F7AAB404B2CBE59D56D56E3C2D +:10EB7000BDCE0B65B542A701F5CF5BAD817556D40F +:10EB800027EA7E8029811B71FF130C98D5A01ABC3F +:10EB9000E8CED81EC1A0F99FBDA22BDC0E35DD3812 +:10EBA00065329E874A2345E82FD56D5B67CAC472DC +:10EBB000416BEFC5CB4328BEB4BC087878A65D2B6B +:10EBC0004F593705E6B3C7CCB4FE15ACBF071F835A +:10EBD000A4BCB40EFBDF5DACB6573E5F87BFDF055C +:10EBE000F3B9CE087BB0E1DBD2D639527BE79BD3B9 +:10EBF0002AAFABCE052A943BE3701BB7A8ED443295 +:10EC0000EAED55A5FCFEB0F6FB59DA3DE21EBCED7F +:10EC1000BD494157ECE787FE33AE008A96183B0F9B +:10EC2000D9016E8BF657584D02BEDFC5DFEDD2DA43 +:10EC30002DDA3B93EC9C252F17515C70947687F16D +:10EC4000FECC3FD1CE6ABE80F14E87DE5CBC4BC6A7 +:10EC50007B33150D0E23D567DCFF157D7D5AFBD365 +:10EC6000BBDEFC318E7746EE4CBE166AAF0A015C05 +:10EC7000A2B4D3EA6BF7AB27B9BC13DCF0FD3FDCE1 +:10EC80009C0F9958E1413F53D0EAA77B6C3693BF64 +:10EC900004F509803E80710A5A3AC99D4BF523BF9D +:10ECA00047F257D0CA12A7A1BCBC4FA473F7A05516 +:10ECB000B18F867C33EC53AA614A3563DE198BF140 +:10ECC00002CDFB1C24D76BEF6B77E1EF2B291E33B2 +:10ECD00043BBB7F9F28E5409E65177BFB9F4E74860 +:10ECE000BFA165AE7BC2ECB09C2C1EC79D19EF2F57 +:10ECF000457EB4013FA23E6E34F9ACF86E8A922A8A +:10ED0000505CB50DCADFA0F24CB5DC33F56ADA977A +:10ED10000912CEAB3E77F6D462D46BAE04D207B6FE +:10ED2000BC29A573A13C20992524AF8AACB2BB11A4 +:10ED30004ECF889E0AE4BF671C0E09E3B14056928D +:10ED40003E10F39C149F6551EF3B658EE17ABE67E0 +:10ED50005FEE56FD026E1EDFD31CDB715311B48BC8 +:10ED600079509014E8BFF1FE0D25189FB8F5FE7795 +:10ED7000FE84F1AD4DC922BD33B0BB3AE4C57ADDA6 +:10ED800006D6B11DECC83595D33B703FBA86C93263 +:10ED9000DAEBBB0DD3FDA89FBB9344B65DE6BFEF96 +:10EDA000101EAFEA28D0C74B6594EBF36BB37C0F12 +:10EDB000BAC7633C5061118E936490657C3AB8B0D9 +:10EDC00083517C7E726EAE8471DD71851171B0935A +:10EDD000F5FD244CD1973BA745C46DDDA22FC7DFBD +:10EDE0004F08CFE3EF4484E74F223D523C093F7F79 +:10EDF00088E145009F2718EAE9C6AF87503C2BC23F +:10EE000011EDF69861A207CF4532CD1D33300E8E3D +:10EE10008D88217BE9A03B86C990B72C66244F2DB5 +:10EE200009C103B85FB5085289421A2A78E0AF5089 +:10EE30006E87FD2ACADF48F8656672FFA043FD3D74 +:10EE4000B0A018223BC2F6C010A9DA835BC7083F06 +:10EE50006C79589EC77B6F77ABE7282E2D4E8DF0CF +:10EE60000A2B43BC4D62017C8732F3FE134A08E64D +:10EE7000B146CEAD403B6395D049E328650E1FEE09 +:10EE8000BB9330CEDB88F1DE0AA591F8D8E3E6F635 +:10EE90009FCC66FB118FAE9902C58FD41F8AA9C380 +:10EEA000C3977AF5BD062D8E4DA3CB97DCDCFEDC37 +:10EEB000D32E085EF483DF91BB1DF1ADE55B7C4E84 +:10EEC000FA1DCECC31159D4897EC7A6E87821EA034 +:10EED0007BD95A9C981657F85196999FE767093D38 +:10EEE000F80B6971446171E0747467C4A30BBF844B +:10EEF000E73D99634A2494338F68F72F18EF179FE3 +:10EF00002FA473836982F722D59F8E765DA23A5E25 +:10EF1000A253F4D2FBEE302701EA3FCA78FDC4DCED +:10EF2000BDCBF1DED51E241CE49F7B389C23E93643 +:10EF3000B5DD5F320AE165007D98D1978E0DEE1642 +:10EF40003A0FAC7F902558C6F4A5EBF1466EFF74DE +:10EF5000CF9729CE72303AFFC41DCFFDD8499B24EC +:10EF6000B46FD3721FADA67B300F3209F55D5A7BAB +:10EF7000C74DE8F78AE487803D6E2C8F93FB6E7E49 +:10EF800078A391F3074B11096F91F1A591F1A43981 +:10EF900059F1AA9F02F4402CDE0790AEC038C1EEB2 +:10EFA0000718BD1350FC62F36DBF83FEBECC334B1C +:10EFB00028AFB3DEF23D6987797DF94B5F16CAE968 +:10EFC0006D62A72D3ECCEF290AFCFE59A4BCCEC928 +:10EFD000E27427A3DE70FDF36926D2F710FC7DBE34 +:10EFE000E4919284FDAEFFA335E9FFD06E61563FF8 +:10EFF000DA2DEE762D9F417658D65B3C7F893B63B8 +:10F000009D928B702B277FD1C1CC39E42F12DFE387 +:10F01000FEA251466F00F3EC7D1BC5DDEDDC77C72A +:10F020003C8C57AB4FBE5646FD3C4EDDFF8CC9D2E3 +:10F03000F85BBF7ED1ECF521DF447E1F99A5C59515 +:10F04000947C3213F037EA7133C5DDE50B65F47B50 +:10F050009CDD8D46C26799515EBC3A6C9FD6945C2C +:10F06000549495C47F97D8071B06F9BC81F980D9C1 +:10F07000DCCE634548AF59C066285FB2146E406667 +:10F0800055C6305F189DCAE745AADF94EC2DCAE249 +:10F09000710874EE635259FA9984123613F5327C72 +:10F0A00043BD6BDA15C3CF7B9CFAFB9146238F17C8 +:10F0B000B9415DBF09CF75C6E27B6F42C832BA6FF6 +:10F0C000FD9BD57AA2D511320E413FD91B47E8DE10 +:10F0D00065C43930EE6F292EA79C911F14E142F9C7 +:10F0E0007B25FE6E77258F07A85DC10C781650AB87 +:10F0F000DE5351EEE2BF4FCCBC5E19DF57A12DA607 +:10F100008CFF0B11FFBAAC2C01EBA7B20E8A636423 +:10F11000ED4CE6F112FA73A76DFDBC03A5F901C42D +:10F120004A23ED5346BE66A3714D958CDE09A73781 +:10F130009B70FFBB82054443AF1FEEED4C99DA692B +:10F14000E7B1BBBFF9200DE572BEB0DDF706D90D02 +:10F15000B1D276D48F317A3ED4EEAFD5A874B2ADA9 +:10F160004A227C6BE56EE518C5DB67B1EE6ADC67A9 +:10F17000655526E8F0DCE3973D9FCE7CE3C2FB0DAE +:10F1800070BECE15E99D2EF9BC9BCAB755C983F454 +:10F190009FD34FFFA9444FFDF79F41E5ADA12FE25B +:10F1A0006F00506CEB3E115F22F7DAAD917076AFD5 +:10F1B000D0CBEF8BF747C69373B8D84C5EE74D00C2 +:10F1C00037DB4382A78DE1EFDEE8EB4DCD3E17CF75 +:10F1D000CFCBB5FA21E7CD581FF6BD6D32FE8E8E2E +:10F1E000BE7E49D147F1FCDC5DABCFE7F7C3F3FA54 +:10F1F0007A91F8899C2FCC2BE94761F3BAC26AD186 +:10F200009597CEEC33AFA45BC3E675B54B5FDF5784 +:10F210001D7D5ED7E55B069C9756EFC68917562F76 +:10F22000721D374FB5F403775EFFD6D20BEBF7F6BE +:10F230007903D7BBBB32721C85DF53377BDF46397E +:10F2400057C6E495F84E3873C4448D0B2E52F9E33B +:10F25000EFE8A748C27800EF516CF779268F4B3959 +:10F26000FCEC023F9EC32CDB6796F1BC2353F55B9D +:10F2700083E05988FCBBC72AC5633CA0C52DABFB06 +:10F28000AB8E6C8CE7DBB3F39DDB48EE31BD3DC349 +:10F2900098A708F5358830BA97F1276C97141E4760 +:10F2A000E125FBAF5EF0FC99F6553FE6FB2A2D7E8B +:10F2B0003FDCCE62137AED2C2D7E7BBD3ACE3759E2 +:10F2C000DC1F08763EFD3E6A72AE48F1CD8F583B9A +:10F2D000D6E3FDA3479CCE78DCCFFC469DB76637CE +:10F2E0006AF71A5266E68E3146819796FE0F29DC40 +:10F2F000A2280080000000001F8B08000000000012 +:10F30000000BDD7D0B7814559AE8A9AEEA57D2DDE3 +:10F31000A90E9D178F509D7720840A8418909126FE +:10F3200009195486E9A022E80C360908485E181F1E +:10F330006165C7CA431E51C7384604046CA228BE83 +:10F34000669A59D488C16DA3C3E82E8E61D7191D62 +:10F35000C7CBB6C05506105ADD41BDABC33DFF7FDC +:10F36000AA92EE4AB7C2E8CEDDEF663EA73875EA4C +:10F37000BCFEF3BFFFFF9CBE2B81AC0C1411FCE361 +:10F380004A0971E6E4F476B9091957E215A7D0F7EE +:10F39000BFCD3410328D900DF44168BD9227F877BF +:10F3A00073F4DF2221EBCBE8F7D0308B9007C44118 +:10F3B000A740EB1F7009A2C2413B09DBED7DCD6088 +:10F3C000F0B80879E82739BDBC7BB8BCC5E7DA05D9 +:10F3D000E57106E20BD8A0137135A1EFF75A446727 +:10F3E00057092D0A83EE1A3B2DEFF9C3759C8390C4 +:10F3F000CCF1F45D0A2175AD95E4D854429E378571 +:10F400005F3D0FF3D9CCF977D37E5EE829A9166862 +:10F41000FBE52708B1D24FEBD65EF5C0F151844C25 +:10F420003F2ECE86F775DB9D324FDF370E3657C342 +:10F4300038A499C8B9322169FC6CDE4EFB49BBFB8C +:10F44000B0DC41A7FCE080D417A2E5F02E4EEE958B +:10F45000A07E4DC91A808FCD23D9E87A97C254F186 +:10F46000BDB3DA08EDAE32C99DB49FD346B208E011 +:10F47000781EFE660D3F97FE442A2774FE4B036BF1 +:10F4800097E2B8220559062D5B449C87451293DB11 +:10F4900068392D8158AC5308296B170FDE01E3AF93 +:10F4A000B28BBD14C68E72F1E0C3B0AEE64C91973C +:10F4B00061703FC255EB7FB9C76B2274DC897B4C0E +:10F4C000B433B68FE7E97F9302D1E5C97DD1E592E8 +:10F4D000607479EAEBD1E57D1283F70CCB981DC7F8 +:10F4E00029BC070E9809CC77F5A904BF99C27BBF48 +:10F4F000911058BFF2AC19F1A172B5CD03F871EAC1 +:10F5000064C22E332DBFF25E027E7FD3D356F6BD8A +:10F5100021F04B282BBF4C24F0FDEA5181B2643A14 +:10F52000EF97BEE66FF016B16519A1FF5F16EEEA20 +:10F5300082FAA9813291BE7F7E022183502FF88BFF +:10F54000619DCFFF95C77EC34F9AFDBDB4DF532F9A +:10F550003EF14B80D7A927C7247374CE971A7AA798 +:10F5600076417D9B5DEAA5EF679C7A26DB17B12F7C +:10F57000ABF798A3D6D92C71B8CE56C1D3FE28ECE0 +:10F58000CF2123E253CB727F5D90B66FE1326505E8 +:10F59000FA31513C2D82B29CE6A4F83AC3C1F0B6D0 +:10F5A000C54ACB31F65D7BD66EE1896FEA70F9E82A +:10F5B000A627703E0527DE45BCDE6F540C0900C748 +:10F5C0004D9CBC9BCE7FBFD5514C92E099E907BCC6 +:10F5D000B95332E0FCE8BA1E6E04BC7893977B49BD +:10F5E000FCF10AD2FFB4BD6AEA37D4D371DDC58419 +:10F5F0009CFD73C20D1E3A8FFC2DD1FB5EE88F2E51 +:10F600006F00F8507CAB2511EFDD309FACF5E94879 +:10F610002704E75370E2FDEBDC74BEA3CDA419E030 +:10F62000A21FB75B627CE4A9A7683F05D80D7F9E47 +:10F6300067FD49A9745F54BA7A89637444FF6E19EF +:10F6400043E96D35C7F88BF67EB56E1E5AFFD3D5EC +:10F65000FE5D26F9BE10EEBF5984FD3F79E7DC0759 +:10F660008E1B47CEE7C33B3D9EAA88F7376E597382 +:10F670003083B6ABDF9B32858F806FFD93AFA65E84 +:10F680004FDF9FDE23C8C002EB173FFEF319F0DD0A +:10F69000937C00E60BF51EBADED381DF38E0BB1B9E +:10F6A000B73BA7F0D270FB155BE678AA0A86E17932 +:10F6B000B174FA4239E373AB0346BF05E822F0FBAD +:10F6C000EA3180A75B3839978E5326F878A03B7BC8 +:10F6D000A9C7A84C2764D657FF7C7034AD6F3A3069 +:10F6E000ADAC8BD67719BC57FD08E86E272FEFA677 +:10F6F000CD9E7BFBE6545FC4FEFC56C5FFAE85F590 +:10F70000D88F4271239732F58182DA4A28CF282296 +:10F710009C99F263C709E2F1DB603CF2AE2199905B +:10F7200013FD77150B06E447D7039D9C220E19E8BD +:10F730006EBFBDF9DF71BC678D38DEAC601207FCAF +:10F7400077FF639CDC45001ED1F477E244BB63364F +:10F75000A3EB1BBC28070CC445FB5BF9E824E403BE +:10F76000DA7BFDFEADF247F7A3C78B132ADE026AF0 +:10F7700046E297FEBB51F31413D0637D2B9517110E +:10F7800074537FBCDB446C23C72164087F09E02FDE +:10F79000C54B22E17AADC837E81F67A1787B12FE1E +:10F7A00095CDCA848E7F13874B23AB2704F280CF7D +:10F7B000718258D19931CC5F49B91FF9FC69FACFF0 +:10F7C0002E19F842E008D03BC8D2DD205FC4E09992 +:10F7D0006D50AF8CF7003F1A0D484A9FE45789C817 +:10F7E0007F4F4BA1C7B1FD33936485BE3E0BF462DE +:10F7F000C3768EE408FED41678D511A2E5537B4774 +:10F8000055F00EC0DB7F75C03A4F064655981CF187 +:10F81000F9869E6FD29921DE7C00FFA47897E4F6EA +:10F8200024B869997452A10BF26C547349738C7D9E +:10F83000D3DAB94CCD2512F08F9FDA64E0E3C99694 +:10F84000BA47405EC39F87BEFFF4F551BDB0FFBF0E +:10F8500050E5EA528E8DA3F533DACDE8FDF557F287 +:10F860009242749C4F899404F2E2E96CEF38377D40 +:10F870009F5E31E8E1293CD2AF2072076D7A8C9708 +:10F880006F13E97E2C23545EC2B3D46702BE423AA2 +:10F890005370BE84C8D500CF15F328FC4B5819E42B +:10F8A000DB2AAF49EEA272B84E60F0AEDBC3F93B83 +:10F8B000E85C96DD130D8F1B7BCCC37801FFB73D51 +:10F8C000A29E8EB34AF0AF07B935968A9C51E514D3 +:10F8D0001F1E8BFE7E3509E2BCEA9F396F8E05E75D +:10F8E000BFA8707E3ADB7309AC8F5B60C1F9B43C92 +:10F8F000CBA17C759902A84F84D7507E4CE74BDE94 +:10F9000066FB709DAA2F35AD5DEA59469F675BEB9C +:10F910003CCB6815921AF0919E24C49FD5558183E3 +:10F92000C85788F8EBEBD3A13FE211A1BCD9CEF4C4 +:10F930003DF2D8ABC057FE42C400E0E18C951CB646 +:10F940009FF136DF4B319C5C37B47F5E8463BD44EE +:10F950004480E37B462FAE5B5945C4DD94AFD45B56 +:10F96000BC9AFE25FE90AEE746D28CEB5EE8CEC296 +:10F97000FD5C49BAB1DC404226C2C3FE962501BEF9 +:10F980007E4664DC5FAA27116BF248BC02F87B223A +:10F99000E0B6727B74993C1651CE0238D37204FCE7 +:10F9A0001BF79D377B62C0FDC12179E42FAC991410 +:10F9B00089C76D38DF23EABE3C78CD8D19C047EE8C +:10F9C000038578B4DA4139F05FFAAF19580E5A68F6 +:10F9D000FF095387CA585FD6CECA2DEE17BD5B28E4 +:10F9E000726C36FA3244BA3975BCF7A081C27561BF +:10F9F0008EEF76D8EF3A832753407EE2C9F3D2796F +:10FA00009056B6BF0F4D692E6C8EA17F68F3DFCC88 +:10FA1000058206E0232F32FDC25E1A3646F2FFFB56 +:10FA2000DD8C4F260D8470FFC3CF7104F4DEADDC96 +:10FA3000FD19B08F5B3324AE83AEA9745FDB6CE439 +:10FA4000379417E5D27D6DD8F7C1C131B45C3A77F0 +:10FA500010B689AEDBBBE63740CFD31298DE9CD818 +:10FA6000BCCB40FB4BBBA1604A07C5CFCD6E09E7BD +:10FA70009330B5FB15E827BC46127B693FE9ED8A58 +:10FA8000FBE62218BFB90DF1B786E0FB946BD7B542 +:10FA9000C177778F26C93C7C47DA38F8EE410741B9 +:10FAA0007D31C5C0DF5003E529AC9CBC8EF3F42248 +:10FAB00052DF8FE3A499C95C2E99BDF71721297AEB +:10FAC000F662BD1FD79B56D95C02FDA565B3A7CBD7 +:10FAD000E433E4D0F10E1D36FADBE97C0FA9FB7E9E +:10FAE000CBAE8AB448FE79E8B4453050FDEC50BA4C +:10FAF000A697066DA097DE52529906449595333726 +:10FB000009F6C795195D7FD6E8499A0A7470982757 +:10FB1000B00FFF69F324811E79A989CD5FBF7FFFF4 +:10FB2000ACEE4BD3171CF147C8A5A645E750DF6FD5 +:10FB3000FA42887A7FFA4E0B01513524BF560E5493 +:10FB4000C3770D64703DE053432091F823F0FBD25E +:10FB500084D8E36A78DDF4054F9498E39AA2DF7FB6 +:10FB6000318A28A3627D971AFD9EAE23AADCF7F99D +:10FB7000D03AE03D290F39BCD4DE9B07F29096CFF6 +:10FB8000FA0D8A7132A8E34C8E9D11430ED0B3A9B1 +:10FB9000DC6B867D39238550AE9D25642ED45F6A4B +:10FBA00030DC5003FB2B841D0BECC3E368F5D03E27 +:10FBB000721FCF2C329120EE4F18E701F053F2095B +:10FBC000D9D6FF8949027DA0FF15849F862F9170A9 +:10FBD0005422F8466AC760D040E9E3FFB8BFEA2E76 +:10FBE0002AA4A837A0D1F75FBB3D33693D6F88A237 +:10FBF000F7C4D221FA4776F3A08157F9C5F9EEAAE6 +:10FC0000999165F67D44FB9A2ACA1F4A8B587B213D +:10FC10008B3BDC9E03AFBB999E238433017E4365FF +:10FC20008BAE6CA3E54911655157EFD2D5A7EBCA4E +:10FC300063D9F7A7EDC14CB04393B28C3502E57B95 +:10FC4000A733824B385ABEA7C35C5345CB0DA54C96 +:10FC5000EE36F673328A0D157E8D32D31F6D72C863 +:10FC600054570470183C08FCA1BE8F13394A0FB6D4 +:10FC7000C0DE2096A19D14D12EC061BBFAC007D86A +:10FC80002E6EFF0506A4F3AE82A3ECBBC04728DFAF +:10FC90003774AEF102837AC3C8F88F407C9E3194EA +:10FCA000BE1BFB6A88CF36CC27CF64785E453E7991 +:10FCB0008013813E87F014FAB50DD385F6FD9F269B +:10FCC000F5FF1ED487C45B3E6913E8F7FFABE1A3E1 +:10FCD00069A0DFFD4995079B397F218CBB8DF80A10 +:10FCE000419EFDB421F71503FDEE8831B40378E899 +:10FCF0008FB3C6D508947F1FB187C671545ED76491 +:10FD000015B0724A6807C0F3C9AC42561E171A678D +:10FD1000A0E56B7AAF46781FC90DED80F2CF7A6708 +:10FD2000B1FA49A1713C6D9FAD7810FEBBC5D87486 +:10FD30003D278BF1136D7EFF36D5E3C982F5D433B1 +:10FD400039B2E4A6F71603FF5D622022A1FC76F724 +:10FD5000E963CFEEA6F0D8DD9A487A193A7A05AA77 +:10FD6000D7A631D4A7FCBE1BF973D84DF9353A811B +:10FD70000643E03F4A9C6691BADCC3FBA28D9F36E6 +:10FD8000A1792FF49FB6A408E581C5ED790AC6D7FD +:10FD90009E6F15B2E7535922E3DFBCC183DFDF61F9 +:10FDA000F7C3F7F759D9BA28FDE03EDBD47DB95E39 +:10FDB0005DD7F5594C1F9CE69EF354560AE823AADA +:10FDC0005EBD31903281CEAB872301B04FDE33125E +:10FDD000C58AFA4802EA353D3077A8BF3FC3AFD0A5 +:10FDE00071AEE78817F88BC64F7A9C9E8CE408FBAF +:10FDF000A4A784966DC3F6684F8D2723C105CF5401 +:10FE000003E8EA1A7FEA71B3769A7C4AEB60E3A4CE +:10FE1000DD57D80BEB491408FA4B962FCAEB6D430C +:10FE200039BF00E74D3C9E0C8EF6777C559601E07D +:10FE3000A8EDD767533DB7017CAEE3997DADED9B4F +:10FE400006DFA7B2989FA08EA77A02C5BBE21C1F4F +:10FE5000C293EA0DC528A055BDE12940DA08381340 +:10FE600021340DDEFF7F08AFED8807DF115E0DAD99 +:10FE7000948F182E808FA870DCCC058D698C8FA094 +:10FE8000FD0BEF411EAD73FB025911F4B0E48E0679 +:10FE9000D417B57925DEFEC2DC6B09D0E149A4BBDD +:10FEA00025FF9088F6AA5E9FD3EC244DEFFC451CFD +:10FEB000BFE3CBEAFA64CDBFAACE23B128F4ECBDF0 +:10FEC000145EC9C42E021F3D620A4D9269FB2306CF +:10FED000DFA32FC0BC47F322E52123FABB2D9B47AC +:10FEE000BCB16A7842C28E09AE613CD944F1C40209 +:10FEF000ED6B4C6807F738FD5B6F043CB966ACAC42 +:10FF0000482887919E95D644ACBFD4709480BF3862 +:10FF10003C5D14415FA47885F53D8BF3FC0AB3FB8F +:10FF2000152BFA4113FCBD8077251400D0DFE209C0 +:10FF3000580F7637FA2B165BD87823F18AD9C7F990 +:10FF400084D5BB55BC5D9585789BDA4198BF41F05F +:10FF500014D744E80B85D90C6E89A5A1E7DE013BD7 +:10FF6000E51EAB9C4B9829077E0CD29D86FD517CEB +:10FF70003995C5FC0B8897CB7E6EDFC5F89E5C0675 +:10FF800070DE60EF266BD10F65C4F96FB706519F25 +:10FF900036582427F87B97F064731EF4D761140158 +:10FFA0004FF4F0B667C7F34B866E8DF44B2E312BB2 +:10FFB000E64CA8BFD38AFABDE69F5C92C4E84AF338 +:10FFC0004F027DC6920B9A7FF20615AF46D4777D1D +:10FFD000995B4BFBFB0F15CFE4812F7297DAD8BAF0 +:10FFE000C1CF510BFFA2E3D6AEB37E00FECC5AC503 +:10FFF00018343B808FCCF18422EC2DB285ADC3F751 +:020000023000CC +:10000000A6D10F706A15C8E6C7617F14B6FE96E5E3 +:10001000FE5591EBDA6662EB52FEC11EB5AE6D0E77 +:1000200016AFF8EEEBFAF3B4E8759D98A6AE8B58D0 +:1000300052693B55CEDDD06AFF802BA64F58177D05 +:100040009275745D05C3EB9A93CDF8E912958F8D87 +:1000500090BB71F7F17FC87ABB1FF2C45AAF7E9D87 +:100060004F677BAAB353906E8262E9305EFBB6D2D3 +:100070007595C2BEA6F8DB705F197E12E290818F83 +:10008000B52CA7EB82675B1AFAA59698A53EF0CF30 +:10009000928793D47512E4032D5BC7215D52BC6532 +:1000A00074FB108BEBB45899BFA0658D282B22AC44 +:1000B000FFD768CF86297F45BDA4359AAF7F3B1C0B +:1000C000AC99B5459170B0642E2D8AB1EF8A19F1C3 +:1000D00039DEBEFF071FBE95CB8EEF2F23EBA2FDAF +:1000E0000DE0371C2AF323CB7AFF05B51FCCD1DFF7 +:1000F0002BF1F8C14F23F1E88851C5A3B556943FC1 +:100100001A1E1DB1B3F5EAF188502D1AE8585BB7F5 +:100110001E8E4B008E31E209149F72018E4754FBF4 +:100120008CE2532EC051A3831B5A193FD0C3ED89D3 +:10013000F87CEDBBAD4387C7DF751D5A7DBC756884 +:10014000FAED166ECD56C0CF2D1944EC403D383433 +:1001500009EC2497C95F08F3DA66A2F44BFBAD55AE +:10016000C707CD01F0FBB343CCBF79541D573FAF58 +:10017000E75539A4F77F3539C23B410F694A60F230 +:10018000F0CC013BD20DC9092D01FDFBEC7E330102 +:10019000FEDAC885F2E0BB339C67297ED7962881BA +:1001A0005CD4FC86C79E677E438550FB17FC753E7A +:1001B000E6F76C52FE753DECC3F96CA119ECCFA6C5 +:1001C000BE683F195D9F03D67BC64006E1FB46DE55 +:1001D000BF0A4CD6CD26A60F6C369000ECDFB05D82 +:1001E0007E340FED840C91805FA7D1F041DECD11FC +:1001F000767CA35ADF98C9FC4C1057467F390CE532 +:100200001E0997C67B4E7D0D71B1C67D7A7A89A68F +:10021000A7FAE132779E83FE22EADDC3F484F63842 +:10022000E06115F1E772E01F63E5C4B9837E884F92 +:1002300037A9FED394815035E80BF6D200013EDA9F +:100240007482D92133FA77BD0A7E33E7DCC171A00D +:100250009234A97104BDFD33BDFF7E1EFC439AFD9F +:1002600012E18F2A5C10E5576CC776E0DF82F1421D +:10027000F00AFCD302D37337AB7A2ED587916F2E59 +:10028000EFCE477D18F455D03B34FF18E821A08FFE +:100290002ECCA91072E83ABFCCA9380FFC1BC6437C +:1002A000BB1F9C2ED3BF817FA9F0D1BE033FD9379E +:1002B000FBF3993E3543E7C7BFF98D14C4F3FD71D5 +:1002C000F4D45139437EFC34F0E3DFCC496980E754 +:1002D0001FF23EF4D7AF200AFA8157817F1CF960E4 +:1002E00010FDCB373513B90BE3E1BEF5506E58491D +:1002F000C42EF02F57F9B01EFCCB574E67F12629BC +:10030000027F219E1359267B68398A4F0FA2BFBAFC +:1003100091F6B04D063F42F4F74DC45F29005EF4FC +:100320009D3747F5D3C3E074838A2F5BADCC4F3D37 +:1003300063DD2E9E44F81992A678DC77013DBC61FE +:10034000443FE9FF56F75783C7D3D915D61C0A8F08 +:1003500004F0FBC077779951CE1E379095802FF728 +:1003600039C90D0BC09F7527F1E418012FC4CC4883 +:100370007F97F6ECDA6F5D0978362B87F111EDFD8A +:10038000996C2396D1EF8CFA6922C6D1295B2A0693 +:100390003C2CCBD2F462520CFEEE0F54FED4B8D0FB +:1003A000E683FE4206C6CFE6E530BB7B5E8E09FBE8 +:1003B000D3CA43FE2215CFE838D85FC2541215C7FE +:1003C000BB2A87C901CD5F4BD4F8CAE655094C8FCB +:1003D0001EC27703F2B3C422AFC987FCA402F95945 +:1003E000F8CF3609E032F754FD2A58C7A78B120818 +:1003F000E41D2C53E3448D394EEC578B0BC5D0BF15 +:10040000AE0FBA86E58D869F9A9CD96F67EBBED8F2 +:10041000F8BEFE39B7AB10F9B7368F193ABD241EB6 +:100420005DDC364C1751F12D0AD744E0B3FB0DCCFF +:10043000EEDA4F110BFD560135FE48ED649003FBDB +:10044000F7E5A39EBD54F5A7523989F65598CA0B16 +:10045000B6DFBEADCBE1BB402EC6653F30FA9F7C18 +:100460001CE4ED01664768FBB17FFF183FD0EF8CBD +:10047000535F6502FCF79F786A0CC4BBF7ABF1C50C +:100480007A53300FED7D13D353EB1DC13C80DF4B0E +:100490002ADED427D0327D9F95E2EB063EA4E50705 +:1004A000403B27AE477280BFE1986A471EA576257C +:1004B000CC8B52CB20C43DE97E674039BC298DE905 +:1004C0007B745E8017C70E4CC2F56D36323C565EAB +:1004D000E4D03F71D418FEB0957E7F34632A69134F +:1004E00041DE7DF1F841E87F274FCC22E45F7C7E3E +:1004F000AE8F7E7F96DAB9E037AB3378AB33805F6F +:100500003CCFEC75FD3E80FC8B8CC79D21E14CF40B +:10051000EBADCC0A00FE9CE92FC4BC22E21289425A +:10052000CB4D2F32FB461F273E6E8CC67F7DBFB062 +:100530002EF0AF35C1BF41BE47B68FD1DFB795CFE3 +:100540001843796B293CAA245F302785B163D8CF43 +:10055000A69733901F1FBBF773DC4FD2CDE29FC726 +:100560008D9E25303F6755D0541B818FEFA8FCA38B +:10057000CECCE435E5BFA6487EA3D59755909871BB +:10058000FA3FA87CC13EC8E4DEC87A86E7B7924746 +:1005900079E017EFE448D8DF7835DFE056F2D92B61 +:1005A00066D04F022598CF307E5D10F9009D2FE276 +:1005B000E7F1AD49C81FC93D0C5F6F7CD88CFCE3E7 +:1005C000462A3F98BDCDF2ABC83D2C8FE2C3BBDCC1 +:1005D00088CF65EDC132A4072791412F79A1F3039C +:1005E00085A7F54BF77025903FB6B4D38D76CA4DED +:1005F000FBDCB8BF3354BE5E67F660BE187984C5B5 +:10060000D396FD62158ED390489C3CEA7F7E13C83A +:10061000E5957B3802743523C0F87FBD107C05F466 +:10062000487DFE03F147C789411E91083D13E40F41 +:10063000D1D905D1FBAE5C94FCD5CB1B3E37B6FCC3 +:10064000A5F69E90CBF695C989BD1CE31BAAFC6D4F +:1006500000F90BBA9A2AF734B9B942959B1FF24CAC +:100660006EDF68BE1F9F19B96E1CE72688EB621CFF +:10067000336C02FD241E5E64E432BCD2F062746E00 +:10068000345ED49F081E34A39D293F0FF1EAFA750A +:100690002468A776DA8D4233CA87D1221131AFAEF2 +:1006A000D287F34A6BA1FA39DDE71B21063BE5E26D +:1006B000F582117A804EFE6BF3D6F044AFFFCD5831 +:1006C000E7E7219E74328FE07BED29924009CCB799 +:1006D000C6C2F4EF1A8B2DC883BD59653C1D696FE6 +:1006E000FC58F094E5A25C1DEBFC7022B20802FD00 +:1006F0004E737B664D9836AC57269686D7DF4BFBFC +:1007000033926203F0496D7C8B7BF692220ABF26FE +:100710006110ED15924EC4DD74BC2B8B249C4722D6 +:10072000DD875D14AE464141F8192DA2B3CD09FB1A +:100730003F887199700A413F9DB65F3BEC44817CD4 +:10074000C52B8B187D5F5924E293B6C738AEB180B4 +:10075000B6A7FD57ECB7225D9E7BD1EE07F94CE5BD +:10076000CE7827AD4FFD13B55368F9CC7E3BEA290F +:10077000675479E1D2FCB5643DEEF722156F14524F +:100780003106EC11C25D3186CE9D687A7283335E8C +:100790001C53AD770F2E64F86B467DE19C33741BC0 +:1007A00094E97C30B7C69BCBD6DFB4AFB2E40EE0A1 +:1007B000DF5E9BCCA0EE2B01FDC7CCDFB2D0428127 +:1007C0005DCDAF0BAF05BC1F6713CDB449D5F8F7AE +:1007D000FFB09896FFBCCF48CC803FBBAF4A0A42DF +:1007E00033C193EE9D34723EABFCC6A3A1083A5EC2 +:1007F000BD27BADC10882E3711E1682882FFB7BE0A +:10080000BFEAADD722F06D6DAEDD05784024229FA2 +:10081000A7F474FCCE3E720C6421FF9324E08FCBCE +:1008200028F9C7D22B3EBF73E55BAFD1EFACA68AE8 +:10083000B65C940B9209E8AB96EA0DB1ECD0C9B95D +:100840004C4F339B9B4FECA2F031BF6496DB68ABFF +:1008500079B9BE2EC0C74643F820ECAB79FCE962FB +:10086000F067578CFF0AF302CEFD2391014EE7ACEF +:10087000B3119FCE6DB54A60A7F664DA981FF6658E +:10088000CECF31BB65FEB454C8FBC0B5503E165E3A +:10089000BF15F8F474B3D82EE2722D06DC6F6ABD72 +:1008A000D1678F49590F7ED51E6A40B6C960E70DE2 +:1008B0003A80180655FED0C43F63B2D07FBA3B3DA4 +:1008C000856DF4BBD5DE0402F978C2D78217F06CCF +:1008D00003741561F73CAEF2BF46F1EDF5307ED3FF +:1008E00057B7CC4D310CFBF9CD46E6E737F6CD0EC8 +:1008F0008EA14D57B456A27D47F92DE38B07185FA3 +:100900005CB17636BEE716CCC5F57E48D70B70795C +:1009100075AB19D7FBE1381BDADB1FEEE0B0BC4248 +:1009200034613E1FD54F46CD76C17BA3682623E1B7 +:10093000D1B465C3FAADB4FE77193CE128FE7FB4AB +:10094000FDB7188FF888B0F1957D3CEA3D1F89E12D +:10095000B220C0536A7644DA932B76F05EE0972B90 +:1009600076DCFABBE900B705D795023C66396F49DA +:10097000956CC3F59ABE2724973F0E7439EBEBCAEA +:10098000C159A077EDA07443E72D18880FEC8FD7DD +:1009900076FC10F5ED1535094E589FB47D7735C8B6 +:1009A000B78F6A461B705DCF72440478385B53E1A1 +:1009B000FD0A4EF0C6C2AB65B92C9E307BBC4D061D +:1009C0007FC38ADFF3882F94CE16421CA161871162 +:1009D000F5F9D716BCF787C5AE613AE3166C993FB7 +:1009E00003BE7FC288DF0FE953DB3F7E1FFC02F0AE +:1009F00047253BC821849F9EEECCE3D7E5C1BCF4DC +:100A0000F4B7A2BD398FC5F72F8E0EC9764687275A +:100A1000299D9C37FC4D74F829E3EB174687646CDD +:100A20007294FC1EC9F714FC4E8B8F5A64E2D96D88 +:100A3000C37C180F47F9F5983C01E13E268FD96D2C +:100A4000C29737EF7993C26947AE4FC8A3EFC71378 +:100A50004F09C867292C56802BD6A6EA8D643BCB5C +:100A6000F306FB02F67F730A79BC2BC23F93A6F60E +:100A700047F9821DFA39F3C7AF0EC27E35669E2E46 +:100A800006BDBAE98BFFC4BC0A5B3FCBC7B1C961E5 +:100A9000CC3732BABC888F1ADF6F92991CD2AFABB9 +:100AA0003D8FD9AD4DAE30F6F3423EA34F2D1EB96A +:100AB000AD3501E342DB5C7E2BF3B3507D8FF63F17 +:100AC000AF94473E6329ED2020C748398FF19C59E8 +:100AD0005FBD4520FEF5BB999532E895B6D25785A6 +:100AE00051B0CE72A35AFFAB8D59B4FEAD9973D0FD +:100AF0003EBA399D9740AF9A579AADA0FCF4B0FC2E +:100B0000DB595F25211DCE5F351FF54A6DBE5E6244 +:100B1000916C144F1650628DCC539E3FD32AD9222C +:100B2000F0EBD36E6E2ED3ABA5A4AB2731BF50A094 +:100B300088C9F34838DC9C6EC2F1BFCC997D09C0EE +:100B400077D6656C1F4E3E6BF6B7D3714F5A63DB99 +:100B500091D5790C6FB284CB912FDDF2AC19E3F310 +:100B6000A7B8D8DFDFB491C7BCA2551B39E2A7E311 +:100B70009D7CF2854CE0EB7FDEFD42666DC47CE23D +:100B8000B5AFCB63FAC0487B3BB82CD2DE9E676220 +:100B9000710132C51CE5DF9DE750F3EC2F30DEF12B +:100BA000A3B87EFE37C6C27CDF1CF2F3BF3E3632EE +:100BB000DE3114B792999F5F1FAFCA29FF1775BE28 +:100BC0002CAFB95550E72B9B59DC62398B8BB71C86 +:100BD00018857837CF14FE39C6B35EE64535AEE1E9 +:100BE000B160FB74561F675DC4E3C97195A1BF096D +:100BF000E7C3F57141BBE33BAC8FB038867E7DB572 +:100C0000FD7CCCB8DC97F92C0F20B1288C76D5D19F +:100C1000D71F85C8FB10BE5BFBDD86C87CF8217D35 +:100C200056C5EFAB00BFE9FAAC1B59391E5EC7E3EE +:100C300057A9798C8E35FC3EBA313B09F0ED2E4B2D +:100C400063E820859F874F22D6D1B4ACC6FF95F7C5 +:100C5000593E2A1F61E7001DEC78DF8E764E87B182 +:100C6000F91138BFA3B40964377DEF4A68F4B7D1EE +:100C7000B264B463DED4ED09F377815D17A20A2E66 +:100C800047CB9F271CD9057A02B12411231D47A900 +:100C900050DB9B2C6207D52F1E4A74207F695D466E +:100CA000507EA79120C75180ECCF63F9AA29AB9F52 +:100CB000E7308F98523CE87D72766C7DF4572A5D60 +:100CC000BC0B0934F42957C6FE6E7F9EE617137CD1 +:100CD000A1083B6F03274BC877E85FDB74D0EF07B1 +:100CE00017235FA67AFC5B541E8CE17F8DFED963CF +:100CF00077FA1E8975DE6148EE56C6B6D35F55E7B2 +:100D000057D0CDF98D0EA45FC3AE28FA55E378F61F +:100D100054994A1888DFB2385D0ED1F2DEB780DF11 +:100D20007E74399BA3C31322A05FA4775F4E7CA37C +:100D3000809E66A4817C6B591EED4F4BAFDD988180 +:100D40007EBDDADBE683FCDE62B46DE492E019ED91 +:100D50008FDBA2F3C77D1B5F488F4B37D3D3C1BF57 +:100D6000B16538FE87F8D3B154F4F31CAE8244C6A3 +:100D7000B5533BA4833ED083665BE45E7924FD904B +:100D800072391DFD9CF9EABEA9F4DCA4A226D7CFD6 +:100D9000A15D3A921FAAF06C188BF0B476DF8E76C4 +:100DA000536209F36327AEAAF501FF49A4FC07ECDF +:100DB0003893A999C3FD9FC1ECB6168E955B668BDF +:100DC000A242BF37399A6763FD152CCFBAC5EAF343 +:100DD00045C6D32E35DC3C3B32BF5624B43DF0E152 +:100DE000456CBC7996752CBFD74775A48C61385675 +:100DF000A870CC294F60F9E6B75AD0BFB5DDDA8DBF +:100E0000F33548CCCEAEEDB222BF1BC31760DC6415 +:100E1000C0C8F043B15B905EE58177313F6CCC2573 +:100E2000E912EF8EC09F5B58BD861744975760321A +:100E30004907C17F472722435E4A0B271DACC07577 +:100E40008961458675AB7CB93881C9116A6EA63354 +:100E5000B8B2B8986EBF28DE30BFFA241BF31B115E +:100E60009F847A976EBD23F1E6C502E0B70343780D +:100E7000D357108BDFDEE7940EF646E20B91D68354 +:100E80005FF56E030977C5C21F39DACED7E7C9E926 +:100E9000EDFDC6D64AAF6A7F2816DC4F13DA1F8DE8 +:100EA0006B677B99FD51D006FEA7A6755452D136CB +:100EB00095FD9C05FA6B5AE440FBBBA96F2FC6CF8A +:100EC0001BE71219A651ABFA87B5751E35B2381E4D +:100ED00095590188DFF738433BE17C5DCF2A2D8FA0 +:100EE00087E5B5287D9C9AC7A3E57D858F80FFB3F4 +:100EF0008793D00F3A744E8FEE3FCBDFB9B83C30BA +:100F00007B91D70D96F8F4DCDE7F4B98763179B47F +:100F10001FF5409E6CDC3C5A25780DD45B602FD4C5 +:100F20007A4003AA2F6B658F5582FC9DE17A81DAA6 +:100F30009D963E4E1DAFFA9A393978BE46EDAFFF09 +:100F4000013847779F95448D17393F41D73F989691 +:100F50003649FB7EFB02E8EFC1296A59F9FA17907E +:100F6000377C9F31BA3F4419B53D14B4F1D29E7E0F +:100F7000ACE79E99C37A3BD5E3FF317FDAB0FEBE82 +:100F8000E1BD79DD93E95889E267789E49D3C39B37 +:100F90005C2CAF568FE71B553ED6600955836ABD62 +:100FA00061D11A2FF43B94F7D6BFD40376B096F7ED +:100FB000D6B4CE8BE79AA8DE7F4F3EE4D1FEF1F4A3 +:100FC00087AF10B0334FA23FA0E90B81F99DA9FD77 +:100FD000C0517CB1F4DF8FF843F618FDE0DAE97117 +:100FE0002A04F0B1E700370DF08B90E6CC6B28ECCB +:100FF0008FE77B7A601D67E2C4C79FCD67767B531E +:1010000041C5D63C80F5631C017DBCABE053B42BDD +:101010001A5F9C332DF21CDEAABE07D979AE3DC6FD +:1010200098EB7E369FC7F535BEF81CC64F4EFA3991 +:10103000A4B995827F13D89B2B571AC0B222A5FE64 +:10104000A598274B169908CCFF01D50E69DA739540 +:1010500002E7029BE87F9404C836EF8DA86F6F5BB0 +:1010600064B1411CBBA9A0760DF23B31C103A69C23 +:101070007E9E43F96F6B13308FA6ABCF3817ECA46D +:10108000324A17FF6403BE7AD8BD0BF8E7A8297C63 +:1010900087087986B1F5EF670A991CEFE4BCCA8F1F +:1010A0004B312E4222F399C7F731FBEBB57C5354F9 +:1010B0005CF0B57C6617CE54062B01D75E164289CC +:1010C000600F3711CF27E0F7225E9B847121124019 +:1010D0007FA0EB4E09ED268B2B74F764A89F29A007 +:1010E000DDA4F911CEBC9886FA584981EF30E0456D +:1010F000191F7AE0C700B7BB0535BEC4F84AE655EC +:10110000B629605F195D4C9FB1527D06CE7B5CB6FF +:10111000E9F8BF56026F7579518F2054C8C1B9F1F3 +:101120004A0BC7E22B3ABD99887215B4AF56FDD26F +:10113000B974B73EB4206A769E1F05FE0C9702F084 +:101140007E9D2E6014AD9F433C9DB02F5FAAFBB7E0 +:10115000D9C4F4F5CD060BEAEB9A3E9CE81A443B61 +:10116000B121C0E1380D05BFC6F302ABD5BCF4A177 +:10117000FC702184F9F2A7F313D5F86727C34F3227 +:1011800088FE30F20CDB07AA79621EBD06772DAF10 +:101190005CEBCFA4C64B1B547F2E0518D67F9EAFA9 +:1011A000C557DBA3E3ACEAB84490CA22FD8E9B6B23 +:1011B0000819C479490E986F57AA9714D0EF8F5227 +:1011C0003C063C3BBA31D10FE7B63673831E887BB1 +:1011D00028252C9EA1C7A794024E3D1F14AEC6BC65 +:1011E000AB17E39C0FEA8B3E1F44F9C39ADFD07123 +:1011F0004A4BDF9301BFEF73AAED2F27984FAE3F05 +:101200001F34BA40C271FEDBCE07C99CA7973E735C +:101210000A9CECFC8F763E486670D7F231F4E78288 +:10122000CE64040596C71FDAB91BE59E19EDBB977E +:101230003E3ED809FEE2B3252619CE43A45EF77AD6 +:1012400027E6C5704233C415F5727D97BBB218E02E +:10125000FFE035CFCB98F7AB93EBF1EC798C794687 +:10126000F87B3CEA7E7C5FF6BCB5FB7307E0CD29DA +:101270002EFC73C847550EF031F3516F28E0E2E4BD +:101280006D791645EA999D5ADE9633212A8FB1333E +:101290004EDE563CFD5D889BAF7539EA619D43F992 +:1012A0005A73353D2C3A1F554CF846BB571B7F6E81 +:1012B000C81D155FBFE582D7A9DA2371D617CFFE07 +:1012C000BAD87C013D1C3AE3C8C37505F1F2053C70 +:1012D00022C4D73B21BE4E9F024714F483ED1DCAA2 +:1012E0001708A2DFF7B97CF45F99E3E60BB03C3254 +:1012F000E140BE04DF6D307A3D6097287B8D2A3F48 +:10130000F73F09FE8FCE0319E82F2305A162E07392 +:1013100082B33A1DF4A34E153FEB2F3C5F6073413F +:101320008C7C815DFE293FCF6276F06022D5AF765E +:1013300011266F947EE69FA4F346FF5CF8DE71A849 +:1013400077720B2CB88E632F9B7BCDA84FCB18FFE9 +:10135000AF4DE74590133D35651F821C3A46155049 +:10136000A0E3BA9BD6A11D1A6F7FEA3646C763B5C4 +:10137000F717BA4FCFA9FB7414EC7414980AFA7DCE +:10138000576EE45EC1BC5B5D3CF805E021C8EFA38D +:10139000E3FBE7ACB331AE7ADB2F6A309EAA9DA3A4 +:1013A000D5CECF12356E226D1490DF4B7B38BFE463 +:1013B000666462401B5D34E07D1E544C6D03D1A613 +:1013C00050AAB984BEE60C1CE89B52272DA7D17504 +:1013D0006D129474FADDAE7713D18FBAC125A9E7E7 +:1013E00021981DA5DCC3A11E47FB453B58E9A47805 +:1013F00043FB79A780F9F7CF16303D83A2881FE71A +:10140000A33E3BD57C086DBC366208C2D3C0B1E7B1 +:101410000651981B4B4FD3FAEB34365B206E121EED +:1014200067C0B8E439936711C6F592F308D87D9D7B +:10143000F6E68D73593DF2D073D6B017EB7F2030AE +:10144000859F48C930DF37D5FDD0EFEBF2EEE8B22B +:101450003E6EAFBF17A08EF8F233B2479E937F5314 +:10146000956BE7BADCEABEC818F7EE344AFFE60629 +:1014700039B7494079DA3696C1CD308E3DB39C55A7 +:101480008B509E3AA99E89F365F3CFFA818B03FABC +:10149000EB7432FCFAAEF3D6CFF7F3823CA63F8270 +:1014A000F24FC7EBDCC4F919BCD8BC2FD4EF9C5267 +:1014B000F8FDFA9D8F71F2E341C0339BFF61F0DFCD +:1014C000D5B59945E067A73895FE37F1C8CFB6ADD9 +:1014D0004CC6F2D18DB9E8CF19A2DB13EBD7C07D92 +:1014E00007179A7F955FC8F0E2773A7F5A6D397790 +:1014F00018FAD1C31D104AD0E40F6D5A79555135F1 +:10150000F0C7460391D2401FD8A8CBF3D0D1739532 +:10151000E49B5608FAA269F020E353A13C01F56868 +:10152000AB0C707BD0706CEF6F015FF65A316FB00F +:10153000715DF871F03BA64ABE998514CEA7D7BE5F +:1015400057CD49D81DDA5B670FE4E3FD19B59DBAA5 +:101550007B09EE89CE2F211B9359FE464FF47B3831 +:101560003F1FD56E44DE09D33F379B7C856027CC77 +:10157000BA8CE5EB7DBCCA40002F3EB632FC51EE82 +:10158000B5AB7246CE8BD44F1717EAF4987BAD8873 +:101590001F75EA7925FD7E34007ED07DAB57F1E3DF +:1015A000E3E72EC903FC38BDF7923CC08FCDC66E71 +:1015B0000FDE2390E3FB29C0F1F81CEF4103E34B5E +:1015C000791783B7F5FA79FD9DF4ABBB0BE3C54DF5 +:1015D000A49F44C64D068CCCDFA558A3CFFB0C5C62 +:1015E000A47F34BE9FAB3027DACF55901353BFB2E0 +:1015F00058BF51BFBAF875103CEFA5C55306ECE1D2 +:101600009F3F1E01AF162BCB2B69291445A504D68D +:10161000579B8DE7C7FE68917BB9EF759D51FEBC66 +:1016200097BFCA5EDF0DF3F030FFE3CB8274F05258 +:101630003AEECB84F91FF5EBFE7D3ECB83D1EC6710 +:10164000CD9ED38FBF57DDEF8142CF4B601FCFFAC6 +:10165000EA3CFA034EC03D39745C8BFF9FD02E23C9 +:10166000FD9C88E7CF2416CF6C7C71F9A3E03F5D29 +:10167000E557E390FB38B4BB573DF609D69FE9AB7D +:10168000C37A5B3F17847866D35803CA6D2D8F41A8 +:10169000F3E334F5CF2680A79A1F87CEE30598475A +:1016A000A22B6C42BE0576226DD728B0386DA38B75 +:1016B000C80AB0DABE68FF8796E7B4CD6B427ADF1E +:1016C000D6CFF9C1AE4E35F9DC63119E63C50F1359 +:1016D00087F9C65B859ECF805F6979684F677B0E0F +:1016E00003BDBA4C2413F3DDD5FDF00DC577D879D1 +:1016F00089BFBCCDCE4B84E2F0EBF70BB5F3120BF8 +:10170000517FFE0BF126C5CE23F7B33CF2A1BC35C9 +:10171000962F5E3F8FDAC84E56867B5F1AE0DE1743 +:1017200099C9CFA04E7E4696214F2C18C137EB8524 +:1017300041CC47D7EE7981BCB1C8EF1BE1BC45363F +:10174000CB1F8BEA47E5A769FCCD18C789113FFD80 +:1017500049A4FD7148B3B34AB4F3316113F8695A2F +:10176000DA5C6188071CB2ABE776D5BCD8166BF89B +:1017700018F8315A9E4CC3732043FAFDB366D50F57 +:10178000CEF0BE9EFD9334AD3C8AF67A139CCFE733 +:1017900086E9695E5CBBEC8D1C88AB1C1AB2CB5E23 +:1017A000CF8173341A9FAD9719BFA8EFE3D879AAF8 +:1017B00040F4799A3113BE5FBEAB7D17AFFDF409DB +:1017C000F1F8EDB7C199F1DB43F1CE21A97C528349 +:1017D000A39E1F5D2CFC86E492063F4AD7C86F7516 +:1017E000F0D3FBC334BF16E914D1EF45759200E482 +:1017F000656A7EAD0B9587F3BFE77DB95079D83028 +:10180000219E1DFEDDF6279E9CB8D87D19210F6113 +:101810007F8AE3CBC39CF27F51E7ADCF2750E7AD82 +:10182000CB2738640CCF67F75150F8B847E613C49C +:10183000C5BF6FC927F81BD6A9CB27F8E675EAF311 +:10184000091E39F09003426E70EE0CFC0E03BB8D46 +:101850001847AFE66D1E96E7C5B3BC50E2C1FB3139 +:101860009B2C56F42FE8F3E028A75ADF0CFA6539D1 +:10187000D5FBE15CCE8E0E94CB0D193CFA1C21EF0A +:101880004F9462E4590A3549416964BE17E4B1E3F3 +:10189000F9FE8BCCF7DA336128EFD2FD37E65D062F +:1018A000265C40BE57712EA3BB576D9F8D8ABCBF6F +:1018B000B2A2881AEA45F1F3ED5F56E93551CDD36E +:1018C000B5080A89F447C56B777002B3775E358532 +:1018D000DF0D805E45BB81F865BA895AD3A5C3E7A1 +:1018E000D68FE77B5F87F9537D04F7F7CC8BEFA0AA +:1018F000DFFE910C2242FEFB234605F75949218861 +:10190000D75A5E8236CE5AD58F7DA1FCE7C8DF5903 +:101910002EFCD7FF74BE33227F89D1E3DFC06F90E6 +:10192000FE86F88991C575B47B2BBE55CE7DDF7CD4 +:10193000469777116F5D5FE613C487F113BD1913E6 +:10194000918E3CE867BC58F997584AF52180C73E0C +:10195000B304A46651EFA720F764687E5176DFDFF9 +:101960007DE350EFFCD8CAE6ABDDBBA1AD67CAC4CE +:10197000EFD78E2DCEF1964EA4F33E3EDB83E77774 +:1019800037D899DE167E92E5AFEBEF91A074C3EEE7 +:10199000D550EFE1D59F87AFD6CFEFEF24BF974F5C +:1019A000FC1F4E471729BF2F7E1DD1F6EC213BCBE4 +:1019B0000F1CB667FFDBD67551F25ACB172EAB184A +:1019C00054FDFD1C017FBF364ED3203B6FB351DD6C +:1019D0004FEDFDEF54FFDEA1899E4D4087A5A5C1C7 +:1019E0009D70EEA49138F01EF1C6C0ED7BDE74B19F +:1019F00073B4582E607147E2B5E139EB1DB9BE07EB +:101A000018FD86D6037D8E779132881B74152C20A5 +:101A10007536CC277808E860FCBAD0CE374B319FBA +:101A2000AA19E855CB272E3BFFD9FAB9A5385FF4A0 +:101A3000FFBACCD1F76FF44D64F6A0F67C4EA50347 +:101A4000BAED19309FD32BD9B9D2269747043FB2AC +:101A500016BF4E940631FEDFB88F194565602B42E4 +:101A6000FD1D6391BE1AF7CD2E81B82609584BF0A3 +:101A7000FEDD3FB17BAF4FAF1D8DFEC69202DF2F63 +:101A8000615DF652FFE560478FA7E340FCF3F4DEAB +:101A9000CB4B7C31F8661A9FAC407C388D27810790 +:101AA000C461BE45EDE7C5E82F5E1F463FD6CE892F +:101AB000128B27BB985C6FEAAF21CB6DC3659B2B64 +:101AC000FA1CD540E19C9D308F9D13595C5FCBE79C +:101AD0007453350CFC867A7C72ABF99C356ABE3245 +:101AE000512CC379CA59DF9ECFA9CD4F2B6BF99CDE +:101AF000895F30FB3D4B3461FE877D23E3AB641D82 +:101B0000C1B8C1CCF060651285534E4F7026C02914 +:101B100009C08EF7B186EE9E4CDFBB460933C11F6C +:101B2000B2B375CA00E8BFC2A6C11FC09648DD6245 +:101B300005B81877E47ADF033C21427301F0A58AE7 +:101B4000DF1BD979A34D89A857F664D6E379A3336F +:101B5000EF9963DE27A03D15D29E0E7187AC8DFFF5 +:101B60008EF17DFB3E2EE6B9B44B8B6CEA79A4F680 +:101B7000748863D8370E2AE5B4FFAC7B39A29AD1BA +:101B8000195C3AF8870503C8D7BA3E764F5D5DB752 +:101B9000B3C282F286F96BC84C17CA1161D395069D +:101BA000E013421BD562E93AA714B1F8746E8F684E +:101BB0000039F5CF5FF331E348E755BC6EB0844C94 +:101BC00000AE0673F860BA7B385F473BAFA2F97B83 +:101BD00086E4CFBEA5E8EFB9F8FCECF0F598FFF786 +:101BE000752AC657E639983D4205917A4F4B74FBEA +:101BF00011F7B4A87A8B6617EBE9409FEF9C533E30 +:101C00001AE982F2D1C036318AEFC5CC7B6E1598C5 +:101C1000DE4DD7616A8179CC4E97C13F77A179E6D5 +:101C20007A7B7A48CF51F5126DDE7F6B5EB6565FD8 +:101C30000FF9D831FC1F9A5ED3A99D67FE9ADDA3E8 +:101C4000355EB5278E76FD5731BBAF50CBFFF0E345 +:101C5000533052FE89F813BA4C013CD8E73434169D +:101C6000617CA911FBD9C4EEDB1FBF31BBBDBC1425 +:101C70009E22E128BC8FEE5F3D1EE3B7942E726377 +:101C8000D0C5918946D6FFA644C463E17E82D98C33 +:101C9000823315F1587890E1EBBB13197E69F9672F +:101CA0005A1CF0D0449F17CE1B0EDDAFD19AC0EE68 +:101CB000D750F3B8EDADEF3D0BF756EC54E3C0034E +:101CC0002F4F5C80F1B94D0207F6E139E7D2F1E020 +:101CD000BFBBBE88E1B95D1824A22D925E07F01C3F +:101CE00060D601767E4950F34D854DAE5D809F16DE +:101CF000B70FCF3BFEA033C8633E9378FC81B91287 +:101D0000D81D6113E49F9D6C13C2ED4ED49FA2FCBD +:101D1000647ABF171102985FD354F4F7B543EE2DE0 +:101D20008AEB9FFA4EE728C8B7F8A7BE2B5EC7F329 +:101D30004F5DFC3AF4E727987D425E66794A31D6DA +:101D400015E5BFFCDED7A5F92DF5796723E898F9ED +:101D50003F347B488B3F108F1295173E601483A051 +:101D6000F7409EED7332E8D54F5823F3C29E57F1EA +:101D70007EE8FE3EE2B7C2B9FB8FE1DC30CA3B79B8 +:101D800023C4416FE7EDDD60DF7540BE3EE897009C +:101D90005F2EE2DCC2FB76CC7B6815D8B906A2B018 +:101DA00073112DCB9B9F80F62D6D6922C05FA968B2 +:101DB000FE159E7B30106F077D7EAEFEFE84361FC3 +:101DC0002D8F3F9EFC1C91C7FF2DE71032E29C43F4 +:101DD000785BC5FB826504CF21908D9E5D30AF9E00 +:101DE000368140BC37792E2B8F172CF87B2856C8AC +:101DF000871E85E746316F394CE109F9D756C88708 +:101E00001E05E744D87D85DC82B9887FC9143EA0D1 +:101E1000177418D9FD84CA3536C4A7CAB92C7E995F +:101E2000EC3521FF394B64CC9F57E01E3317E05946 +:101E30003BE267D89E8AF1D7E41CA6475ABD2683A9 +:101E4000C58DF9CE88AF614ECB77667CAF67A9842C +:101E500079E843F7152E27B83F9B72AB33E0770044 +:101E6000465F65E2205EA3C9990A153F7A76A9ED1F +:101E70001B587BB8CF10E6475A58FBA1FB0C7FCA12 +:101E8000EA5B8510DE07447518F53E3D56DFB23833 +:101E900015E98757CFAB92EBD47C7B8EDD1FD5B293 +:101EA0007834AB77303E486E4A50E5B9DAFED664F6 +:101EB000BF1A2F6079F3AB0CEA3D00DD24329EABF4 +:101EC000D159F2B79CBBF8C570FE3CD273C7E5226E +:101ED000E6076AF73156D84CEC3C96259AAE9E2917 +:101EE0004A66785F2E5B60DC656E4FFAA498FCD181 +:101EF000BF3492AF8CD6F8CA4D269D5D96C6E0EAF7 +:101F000008EF64E7B6CC176597C58F2B3E99111D76 +:101F100057DC93111957D4F6B762A509F94A8F53C4 +:101F20007A0DF28FB651D0C2FD76FA756F1BBAA743 +:101F3000DA6F05BD546F0F1E8A9367B46812F3E71A +:101F4000C971FC108B26C5932F71E2B425E6FFA65C +:101F50007833E3BF0371CEE90DC14BD39B2CFAB8A4 +:101F60008772517E9F01CBCF900F7A3A0462BD8C6D +:101F70009675E7CA281F44BEA8B49BC50E17F0D1BA +:101F80009F215F6CA596AB39822F5273F412E0C784 +:101F9000037716E0EFCBBC76A78CCFB3562EC04F9D +:101FA00086677809684C4B8A0F2C847B9BCFDAC3F9 +:101FB0009970CFF3BAC96F5C8BE594F01128DF51AB +:101FC0004C16613937BC13EE7DBEBFB8FD5AB8D789 +:101FD000F92CD0D868426E7DF6B66B9522FC3D8414 +:101FE000F583A0DF97EAF2F175F7D0C2B951584FE7 +:101FF0009ACD8471DF34F5BC2EA952FD4390E905DA +:1020000074975182797A3622ED1B84FAB14CEED264 +:10201000FA36B8E7B423D7CDE2D084F1013256CDF9 +:10202000E3202105FC511D6E27B61FD2EFF699D58E +:102030003C3036FEE1E7D8FD3CDA396442C47160D9 +:1020400037DA241255D6EE752682380EEE61ED5041 +:10205000F1402BF7A7F91E9A1461571E9E737B114E +:10206000ACF3E3E7EFC8017DEA87EAEF32E9F1EA92 +:10207000C6C90CBFDB13FFBA04F8F8BBBC4306FFAC +:10208000414B9A6F17F4B7DCD536CD49F1A74A9C7E +:102090008DBFFF324359CC015F715ECDE6E7ACF2F4 +:1020A00072CB8B867F1726C527A09F9EF87A78D0A3 +:1020B000B7538E7B45804FBD259C29D07EFEE4F230 +:1020C0003D03FD9E5BFAC16D989737FAF011B81F7A +:1020D000F2B0B1BBD201F8E456EF03A63B06E763CA +:1020E0000E8E19DFABFEBE0D3B2793CBA971D860D6 +:1020F00015C8852B08C35B2843FD95EA7D67D5226B +:10210000BB3FB3BAD48DBF57369F8405C087EA77EB +:10211000BD0E02F471B5AF34D6FD13DA93A41BA53E +:1021200048FAB95C8A28D3FFAE2C882EFF488E2E41 +:10213000FFB8FCEBFCA8B2E07963520AC837267FEF +:1021400094E94CFE8824D00EF2F1A966710AC6D536 +:102150005D9C02E5892F8CC6BC2492CEF2192638EC +:10216000B2FC0C0ED9DB615D612AE77B5DF0BB47F9 +:10217000EC1EABD4774DBBE09E042249DB810E9F61 +:10218000371660DE66AAADF69FDA509FB1935CE425 +:1021900053D276C46BBB4582DF6F78C5CEF2113A5D +:1021A000EE3760BC8973580C1EFA1DDF2B30F96FB7 +:1021B0005F5909F57C19DD102AAB079CEC77943A3E +:1021C000A611637B09EC9BFC2EEA45760BE6ED57E6 +:1021D000390A7E02F5BCC384F73ABC622FF3A9E347 +:1021E00011E8FF31FB4A6C0F3CDA48E977C0CAFCC2 +:1021F000EB3CB58FDBD9F8F87B69FCCD441DDF42A1 +:102200004C50AE2598873FE014D97C6F35603C0474 +:10221000EA2FC3F959B05EBB8770F8DCEB6C01EFB5 +:1022200063E7881A1F6BC3F2432A1FEC308AAF00A2 +:102230009E2A7F2604F6A3CAF105D2016F70C878E2 +:102240006F8E87E4B85209F359D0EFF9543108F989 +:10225000ECFCCD0EB49B41F3817AF02110A46BC14C +:1022600043CA54D70C8EE7390A783C9E235ED88F38 +:102270006B8BB3901F3D6A38BC05F32B6C5EB34C7F +:10228000C7315D47707FE5C4D8E75DF38A199D8E3D +:10229000DCBFB274C8E3E01CE5123C3BECE5129CE9 +:1022A000DF1970CAE9DE88728C7DF103DE0CEF8BDA +:1022B00025682886FD9025D02FBEBD3F5A6F83F537 +:1022C00048382F7EB42C811D9AE3A0FD50BE2F8F7D +:1022D0008ABD8E6BD57504D4FBF1F4F595C586EFF8 +:1022E0007B9D3AFCFB8EEB4C8D5EE7F738CF10F709 +:1022F0003DCC93CFA4F3B30DCF8FFE13EFEBBAC257 +:102300006640FCBA42BB37A920FADC85FE9C0595E5 +:10231000C05B81CFFC50CD1FAD48FC47F4E35F4E5E +:10232000F57C906B07137F9603F99BD5496D9D8CC7 +:10233000389A4F2F077E6CE190EF5C4982EBE1FD0C +:10234000D9D9BE479CD9C8F75717C3B931DE979F73 +:102350004CCB1F1BBB73D6B8912FD6C37B1B092355 +:10236000DD5D01BF8F067437CFDF09653A4633DE86 +:102370009F45E910E856A3C391F3A77449BF1FD343 +:10238000ECC0734D3B48100FA6A5936E8EF95B9A77 +:10239000516E1169DCF03A29D1565B9A711DBF6DFF +:1023A00053503EFCD0F98000E587655F1BCC6BD1B4 +:1023B000E44FF0DE7B92BE341FEC4E3ADFF6FF971F +:1023C000F31D79DEFC9BCF51FCBDECD1C78B599C32 +:1023D00043B3475D09549FA0F39438874CA8FE3857 +:1023E000649F1A2D9897307C3E375C87E780B9242C +:1023F0002FC833ED7CAE9EEFCEBA8CF1DD8FD7388F +:10240000E476BCAF700FDAA54D57DBB4F3BBA87F01 +:1024100035AD34A8E77739942B8DC482F7070DFDCD +:102420007E1CFDE352877F9F633F9CE32DFDA673D7 +:10243000BC129E1356D6B138FD907DD72032FB5585 +:10244000FB9D875BB3B4FBF8999EB2865C907D1BC5 +:10245000E37C2FEA8D24C9A0DAAF4C5FE8992E897E +:102460000AC1F82AD3C3179BB07E73821F7F37A59A +:102470008EEF4624F963B153BD17C16FC5DF5732E4 +:10248000C979C027B438EBC21CDFFB80BFCB8B3CC3 +:10249000991C5D4A9D89C54F291D6C1FA4ADE6920C +:1024A000E6C7E0F7B32E27CD6F1BB2910E8E221D2B +:1024B0004CFC84FDAED6301D1C2B86FC06C2FC01F4 +:1024C00057A871A2973E7EBC13F6FD2C47D8F9AEF3 +:1024D00002FDF92EEFA9629C5F48FD5D9D68BE1369 +:1024E000318FE346360F17CFE33C3E8B358F1174A7 +:1024F00048FC383EDDDF663C47AEC323FD7CB8FEBA +:10250000DBF1BCFFF6EB89C84F07393E6805788ED2 +:10251000058CC88675FA0C93A7A13CF7C1FD669A95 +:102520005D3D62DEBC0DF775E1E2A13C9DF91965E8 +:10253000102762E33E94D8F820F83D9AAE37227F08 +:10254000AFE99F847ADA41C52C421224A962F93599 +:1025500032FD1FCC6B11F1CC71D27EAE126BF0BE8E +:10256000B4ABE7E9F37294BB9A69FB6BD43C9F85EB +:10257000571B8F46EA9B678DF718010E4A9DAD9950 +:102580009F01FD09C3EDDD23E132E2BEA64EC69FE9 +:1025900008D573A0FF8EF200F2A7787C2A6FF25064 +:1025A000BE4FFEDF98EF533C19F1E29BF37D64359B +:1025B000DFE7356318EFE1FC4DCA8AED6BE83AF3CB +:1025C0001F2EC2DF139D93BAEAB1FB69F9896D131F +:1025D000B0FC9BD4EB6F390CF53BF3B05C65F86451 +:1025E00009D04341D9E22BE077585FB3B27ED213D2 +:1025F0007C3D35F4BBF4E2AC2970B14B95298CDFFE +:102600005D39B9612AF863AA1258F950C93B53B031 +:102610009CA596A7BC3401CAAF719F2C89C517270A +:102620001670C1422A6FAB92D9F7F3A63C391AEC67 +:10263000F8AA0A569E28CFDE940DF5864F97C4D28D +:1026400097AE9FCCF8EAACAFCE768E72415898FD2B +:102650003EE80B9E0FF07736BC54DEC2397C6F39F2 +:102660008BC3793D2502FCAE538587952B6D6D1983 +:10267000C007E7FB4CA51077156DEE4EF8BDC2A460 +:10268000F2D9D360DF2BA9BA0D714E4A5F37009E95 +:102690002FBAE4934C07EAA51A7D8946787EC37D5C +:1026A0008BCBD8BE45D303ED6F15F67769B4FC1C10 +:1026B00041AF3A3CBCC23296E11D958BE6F291F4F3 +:1026C000AAE7DF647D808BA4D71D80973CD2ED5AAA +:1026D00018DF641894E0FD784E9E207E03FD9E3541 +:1026E000BEEFC638107DC15F1A836FD03F41D3F370 +:1026F000D92C443115F397595E4FFF3BD81E8E837A +:10270000F01938FE26189FAC67F3D901F790F060F6 +:10271000EFF91E053ED198CE7EF711E2FA40A7E907 +:102720001ABFEA8B5E6F47B97C93931F395F83852D +:10273000C1F16A551FFB7DAB37A5844E7621693602 +:10274000C27A1F4A742810CF6DAA65F74906D27C59 +:102750000FC33EF106E540889697138F89F137CF76 +:102760007698A7B62F8DEABE345ADEC77C36F8833A +:102770007B4E46C0A34FCF47A3D73FBC2F8319F052 +:10278000CC807B54B2619DF2463EC67A88D0BC298B +:10279000D24FFFD0B7FAE909F3B7C866F55E94F0F7 +:1027A00092487F5C87BDF991483B999A65789FD1A3 +:1027B000A1B61C120BEF343DE910A7FAB5A8DE0B49 +:1027C000FAC0E7097F45FD84528CD798097EADF9A0 +:1027D000A8C770268B08F1EBF4DA74C4D72D542FF8 +:1027E000013FBB5211C8467FF94E9EC0FD03C37026 +:1027F000A033710FE3E7F1C9CC0E4C1B8287827CBA +:10280000D464E062EA57C7271BD47B50D9F9D2467B +:102810008B99E57FAABF4BA1E5B1345A8AD637E33D +:10282000FA2C8C7E74FB3422AF459F27674943FD09 +:10283000429C4264908723F360F4768282EBF8D165 +:10284000507C8130FD67AD1DF59F1FA9F1056EC15C +:1028500017B83FC914BFCC2E8823481CD82BC9A554 +:1028600087053269F87724E1F797C09FF57C96EFEA +:1028700093C911F1F837A73D817921470C2C0EAA95 +:1028800087CF5743F00961BE6AA3C6AFF4EB8F331D +:10289000FFFE34EF5F61BC8FB9C132A8D4E253545C +:1028A000ECBBA1BFFF0B8F9234BF00800000000083 +:1028B0001F8B080000000000000BE57D097C5445DB +:1028C000B677DDBEBD25E9249D859010960E3B129E +:1028D000B03B21618726408651C000A2A008371076 +:1028E000D6AC82CEA0E3980E0144079D38A2328A6E +:1028F000DA202028308D02A246A70544FC74346EED +:10290000E3FA98C40551B61844719E6FFCCEFFD40B +:10291000BDA46F13467CCBEF37EFFBF0375339B7CD +:10292000EADEAA3AE7D4D9EA5475923B6B5492474F +:1029300008F1C38F3FFE982FC495F4A7E82644639F +:1029400037CDEECD13E26A5134D6AA08913C4EB38E +:10295000692E21C6AAF47F038468D9A6041DF47CDD +:102960008C3FC6225285A83C640B06095EFC8A2A6D +:10297000002F7E480D0A825B84776D23DA071CEEF8 +:102980000095F7C7F5FFFD302A3F7DC8E675A0DF4B +:1029900080FFADDED46F09FA25B8D75A8BF0380521 +:1029A000FFFB91FED727182B3CBD5BE1BE5B924D30 +:1029B00070BF500753FB4BF77635D5FBC29798EAAB +:1029C000730FE598E0BC8621A6F603DF2F30C183A4 +:1029D0001B2F33B51F7A74B2091EDE7C8DA9FDC88A +:1029E000B3B34DF5A509850797D27C0FA6AB421965 +:1029F00024C428516A6A5FAA96D98585FEA8B37D4A +:102A0000D248EF55D17F3F7625589D61059ECFEC8A +:102A100055444A9610F3D7CA7AE3BD05F577AFCC93 +:102A2000A47261D0FCBC54585B617A6FE9C70BDFBC +:102A30003810D15FAFD4624B1295A3BCF1A947FA0D +:102A400062C262E08F2AD3D51B069DDE51BD0E49BE +:102A50000AA6F3E2ED4AF00EA2634FD1E37ED08DD9 +:102A6000E82C821ED055D6B7AC538301EAE7BBEA07 +:102A7000056F1CB0117C28776D23D17F7E8DC3AD8F +:102A800052BD23DD4CCF188F999E71BDCDF48CF7CC +:102A90009AE99938C84CCF24BF999E29E3CCF46CAD +:102AA0005764A667FB69667A6668667A662E30D3D5 +:102AB000B35395999E5D969AE999155864AA8FE645 +:102AC000DF6EAB169BEAEF8F7BE188467848EDA07E +:102AD000BA1D6E217AD4DD6CFA9E50C7DB5710BE4A +:102AE0004A3355A1BA5BF92040FF311F882A5E5F47 +:102AF000F3880F1E203A9C11AB0F667ACEE7878AC7 +:102B0000BD77DBB13E7F2E3F2C8BE203E2BB447CE2 +:102B1000E747FC1B797E69D0F90AAB7F95B79D101A +:102B20000F7AB5DFA19CD6EBEBCE56921BA2A8B8CC +:102B30005751BC102ED13C13FC542112BC77A07409 +:102B40007E9C057EC13F4706FD9F5F74B712DE1471 +:102B50001D6F62AFED78A3312E9AB752FF5E16E675 +:102B6000BD8E985145FB892145D0F83A8A860CC81C +:102B7000A70C51A5A04C17DE552AC6EDE99484791F +:102B8000E0CF1F3399309630BDFF41898DF97759D9 +:102B90005CFF6DE0CBF76B255F9E4693C1425C23E3 +:102BA00042367CE783D8073BA1BF0242B832189572 +:102BB00075D761FC33307EAF10D789461B3E3E4B44 +:102BC000083BCA62E1E1728EF0DBF1FE5C115E89C6 +:102BD000C97C94AA6D073E2A54AD4B1AF0D1B1A11D +:102BE00073513F2A5F4BC1A02F8857505CD07B6F39 +:102BF000E34F6AF789B76837BE33DAE9B9E15EC2F5 +:102C0000CF3E8B581022BA88F1293C6E612DEA37ED +:102C1000B95F5BDF5946424D88E7144D03BE031987 +:102C20004EEF2620393DF4A442F3BB24D9937347D9 +:102C3000526BFB035E0BB727D60B28D4FEF15DB1B8 +:102C40008CAFBEEDD727635E3FB7DF06AFFF558C75 +:102C5000DB68FF53F3B5DBBD8B6EA47E9B1551B5CE +:102C60008106F18E4E974C07F10F8D37534DF0D6FC +:102C7000826E71330FB6233C2C69AF7D00BD34EDFD +:102C8000EA5FAE04ACEC4BF12CA6F19D2A6ECCC7EA +:102C90007809FFFF86FA3227E19FA676A293D62B0A +:102CA000114C5124F14F7FF42B6A73FC723C077472 +:102CB000FCD7B7D78EE03BFB2C0D9DBDA0A3B52163 +:102CC0009FE9E896F33A619778B9101E0AE23ACD87 +:102CD00000FE4B1C0EAF4AF82C50E4773F4B9C355E +:102CE000B392C63DD7529416564DE3FE06782B7329 +:102CF0001577C9C0B86DFAB89DED74BC7BB2B1AEA2 +:102D00002E34EE5A7C9FF014F8AD12DC9485E7E186 +:102D1000AD809F166EF71D3E5A7316A9979B6B9454 +:102D2000E006AA7F43C7F343366A8775E914C935BD +:102D300034BE2B86AF588F76BFD39C3CEE4DC27B02 +:102D4000C99A2CD043B0BCCFBC4D09D6123C5B789D +:102D500099EF4B4451E75DB00F7C5ABC8FC6F1B779 +:102D6000B87FE465597819E7BD43DFD9B3ACBDF747 +:102D70000E40C32E8EFF7B93E440FF932748BD3364 +:102D800057C7DB95A288D7E955A28A4B5AF0272A64 +:102D9000A8DD34FA0BEB93E07E18DF74C0BED67565 +:102DA0003D4334703953B89F6FA46FBD55D3FEC6F1 +:102DB0009BA8CD644B7367BB8A754AEB368BF1DFFA +:102DC0001DE3FF76EC9B8715E0FD169263A0F79A52 +:102DD0007617C5C79314894F5AB7D9BE3C5EB7035F +:102DE0007C9688F533A69DE43FABBBC73F5B3F2491 +:102DF000181332D284F8851485E2FED3092295E6B1 +:102E0000D9D0550D3AB2A0A76FB1EEA27936903D58 +:102E1000E1C0BCFDC51D4E51FD38D2B77748F91A47 +:102E20001F2078A25F1577301F342E5F48CF5F1BBD +:102E300044F5D4FEE51A113F80E0977D366F2DF101 +:102E4000E1D8B3DA81442A2792DC0F53EBCBD2EFDF +:102E50001E03FB605C47D223117AE2B2EE6698163D +:102E60004247D0E9721DDFE3B3CD7A6722F48ED1F9 +:102E7000BE0DBD43F255057E27FB74FD7389B80472 +:102E8000FA677FF55EF129E917430F8DA61986B21F +:102E90002FAC8762EC05D7806E447F3BD6C76C2B86 +:102EA000B507BEDD5A874911EB656FBEC274F2905B +:102EB000E2B1D0FCDF38A406811FAB3F3C14F85BC5 +:102EC000FCBCC27CFA079F3617DF3B696B9C07BED0 +:102ED0006918969B28A8FF4FAA6920BD68FD563B3C +:102EE000859FD6C2916A37C347ABD3B9FCAADAC370 +:102EF000E5F1EADE5C7FB2DACBF0B3BEA20AF0C342 +:102F0000EC555F5BB56CF45FC5F6D1921AAB00BDB2 +:102F100096C42F96B0CDE98610BEADD3414B1CC1EF +:102F2000B705152FF4E2C25DC1957134AED27ABFF8 +:102F3000DD05F9D72979B40BEDEF5598EBE71DAA1C +:102F40003A88E99E7CE793AB2688D6F9969F55840C +:102F5000464BAE5B9EFFB798CF17D583785C5F5624 +:102F6000FB795CFEFAA68329F4BD63D5E3187EC71E +:102F700057548B767EF135DB1113B6355961678C6A +:102F8000F52B7ED079845F048384AFB536A957D6FC +:102F9000925E811C18D56FF2433708C87DED4ECC88 +:102FA000736AF29CB1B057270E2A66FBF5EA1F043C +:102FB000DBAF06FFFFD43AF288869399D4DF89808D +:102FC000C44FCBAEB7196EB1127E68C62FEC2A2D56 +:102FD00015641FB49C7D4B3EA7766CA7EE96ED164C +:102FE000DB64BBC5BB7F97CCCF15A55944E8BB6359 +:102FF000444741788873663EF419E1E7D8F65FA745 +:103000006B11FC752C39F4ED879093FF66F16E60BF +:103010003ED53E7D167274B99BE5CC495BE8C8038A +:1030200090B39D48AF727D55DC64E2B30ABBD09883 +:10303000EF84D617F0B15831ABC825FBF3F492CF2B +:10304000C18F3D77DCDFF5379ED6FEB684E67EF88D +:1030500000E8B0E3A3844B68BC7D541152317F215A +:10306000C711D818CBFD943D797BB29FE0AD8A683B +:1030700051594E04595EFCCE26A6A1DFDE8AD5BE8C +:103080003499FCAA3B9FCEC4BC7BA9A24AA5753942 +:10309000E7AE67329FA1F71E2359A4D2F89FB379F8 +:1030A0004FEEC5771FA2F153BF8FDD599E037958AC +:1030B000F2878597000F7F81D0223A3CF1F44EB61B +:1030C000178827BDA349AEF55BF3E2B20C6A7FE92E +:1030D000BA264B072A7D1B955A94A5DB76BE55432D +:1030E000FDE5BA2D55B05FDFF279785C39A1F51BAB +:1030F00014E8811F1EED807599BDE6EB820EE2C2D9 +:1031000076C6139DDF6F29F6B05CE0F777D74F796D +:10311000FB5A013B862C188CB7D8EE65BD46D3B65A +:10312000013FBBBAADC7FB7B2C01D65781D9D2CEAC +:10313000395114F823E65F4EED030497FB1A9A6E9B +:10314000A2FAF2A4AE2240F33F1A5C321DF5031539 +:10315000E1067E2A76DD5BD881E013C38457A1FEA9 +:1031600017EC3E5DC8FAB013D9EAF8DEAEDAB46BFC +:10317000A00FB30BF254AA2F5243DC9FA894FD5525 +:10318000D6EF740226D427ABC46749F5A3F6677A55 +:103190005AE96369BC2BCB4ADF6B47FA14E35D9BAA +:1031A00015C8A872B5EADF645FD169AC1BE1BEA7A0 +:1031B00018DFF99CC605FBEC62F5A5DD52B590C79A +:1031C000932EDC81C1ADDFED64092FC43C6875B876 +:1031D00003F49D4DEE86E9DC8EE0DF73BF9A9A938F +:1031E00007FB8AB09E2AF57B2DFA754FE90C7A5DB4 +:1031F0006CFFF7C7FD83EDB44A4B82D731A0D5CE23 +:10320000999652FB7C23D12BD85E4BCC6907FB5897 +:10321000DAC9C2EAF540EE57B7F7BB73D84E233D83 +:103220006C61FD9B9A1361379FB3DB9C17A77F43AB +:10323000EDFD1DF0BD8B6DEFD1E312E7E4F0991CBD +:10324000931CAE8DB70B1F3DAF5DE3E03886386051 +:10325000293B48FECA707CC2D2FABD25F139EDA1E6 +:103260001F6A8568135F2FD0FAD708B761D21B1A7F +:10327000C98111679B558DE544C3FEC40190B7C257 +:103280001FEF41DCC022B408FD18FD1DA2D760CCA1 +:103290006F9488135A849EF58B243BD6AD70255FBE +:1032A000E4BCC38F9AF5CFBE4723E73DACE5FD38BC +:1032B0009860848FF6282F34AFE7F579FD19F3A2D3 +:1032C00072677ED1E5A0DFF06FDC56CC6FB8755227 +:1032D000675F571EF7243C1FF18DC53CEE1F624D02 +:1032E000F0C58EFF46851C3BF0F1D7F620D65F3D3A +:1032F0006C059A47FDC2EC20D6FB1EBB0838E1F7EF +:103300004CB6B31D5C1F1F88875CAD57DC21C49F82 +:103310009EB3354C977E91706FF2817F5F7F10FC7A +:103320007F4D8B5D413CAB83431C817D25D444B1F3 +:103330002935E2FBEDDC1CE750A13772091EAC3FDA +:103340009F6EE7E7B536C17A32303D96C7B526A9FC +:10335000EAD57E54BFA626D34B2317EF8BE0AAAE47 +:10336000A8BF4565793ED4B261D37DF07B26A5B375 +:103370009E599314CEAC44FB85977803C40F7BFE13 +:10338000A1B2FE58E3F36724BB200749CE139DD7B3 +:103390004CF267C4A6A24CB360BE1D48CEF3F32C1A +:1033A0006A47E58736D9EE039D6E84E90CC8DB07D2 +:1033B0004A7A08963F390577F03AA10A27F1F35483 +:1033C0004902317DEEBDE226B4D3D4A09A05BCDC1F +:1033D00075674F82AF99ADBA11A79BBA20A649E98C +:1033E0004FA5A6861D09F4C29563FD91FEFADA1C6D +:1033F000FF1DA07379A84FB7CF22F878FADC1EBF63 +:10340000827CF884FC68F8DD77A4697FE0FEF7FA37 +:10341000B8DD5E326E7E849E707AFAB3BD5D62F86E +:1034200099E139C0EF0BCD4EB6632FC40F42789DA2 +:1034300097D0F7EFB38810F8B98BAED76B110000B7 +:103440009D4331CC07E3263BFD1CAF725936C08E3D +:103450007E84E805FD16D8ED607A91A064FADDF768 +:103460004227D64BB37439563B2D96DFABDD690B43 +:103470005A406725B87533DE7B3E86F567995DB0A7 +:10348000BF52F66C5FE6833D767FD60AF4FB82433B +:10349000EAED044F22D7FF9F1481FAE7747D5D1691 +:1034A0001BEE994474EADA4E7B0A7823BEABE2E75E +:1034B00076F9FC70B0603DD6A520FB266E04C1C233 +:1034C000BF1EF22A4076D026AFA41FC6A5D576DA55 +:1034D00080F16A340ED059DCACF27C0ED35AC6FCB3 +:1034E0000E5775E2712993C765CCA5FA4F17C771BE +:1034F000DCF570D1C133B0030EA7ABBCEE4942DDA1 +:103500003990EA49E736DC4170E5C24F5E1F484F0B +:103510002B6A3FE8BCD7D38AF719CBCAC70BE28323 +:10352000198B6E9928122EBC5E679439E053B6AEA3 +:103530006F618773276192EB4D39FE06F0C17FE41E +:10354000686FA3ACCC267B9BF8E8A4BDE161C455B1 +:103550008E7AB4BF022FA79EF962339E0B6B734F16 +:10356000E60F676321E23265161957BA2B57FB380D +:1035700087F56C02D3AF32E460FAC5653748B97895 +:10358000CBC5E983AFEA37ED51A89FD2D8FA0A2E0E +:10359000D5607FE8AB634A3841E9C6F8D5B0AE8E56 +:1035A000BBC309A08F6691F65EE996E879D250D345 +:1035B00010771342FAA921FB501AD72212BD0FB877 +:1035C000F1DCDEDA3EAB958EF41DA6A3707D3CF3F4 +:1035D0003768BFB54FCE1D84F7D2A4BD770DCD3A65 +:1035E0001F7FD1B0319FF3C7A3AF93A27002D6C99A +:1035F0003145AE93E342CAAFC096183D5E20C77115 +:10360000F299F63C8E347D1D9D54F4765B1DB21DFF +:10361000F11EEC99D23F49BEBBCFE665BD19207DB6 +:103620000279599A22E15247BA1BF656073560894A +:10363000055F560B5E2F34365E97C77664F2FB86C5 +:103640005C13454240AE95EEC8D820ED3ADD6FC61A +:1036500004A8FDA227647F8021FFBF7A3C53EF5F5F +:10366000AEA768BA46E3A15BAE8C73D5C6E7B7FFD9 +:1036700067F1CDDEE91FAD8308BACF26D775205E8E +:10368000EA11B25BD227F5C3FE84DDF4DD93F1F6D7 +:10369000597E17F629CCCF8DEF5D9AAB70BF5DA236 +:1036A000E8DE416D7E11F6927854B09C881E477E0C +:1036B000AEF4571F7FFC1C9D554977622483BF3CA5 +:1036C0008C3F61037D3EB01B74BC2193E47A29706A +:1036D000D5B5158F7B7C5A26F4C849C084EF3D4987 +:1036E0000467C3DE92FAC3800D7A44F3E9B20FE6B1 +:1036F0006536D2FB7372A57F501B93D05F24A2EC7A +:103700001C841CA821BCA29EF4E0ACA26CF8C3E30C +:10371000EEF9CCD63A9F23D57E3FA9A073F0BCB575 +:103720003E27D6E7FC753EE7EC087AD46EC93DE447 +:1037300021BC1FDF62456452D45A83770D49C5739B +:103740003514105CEF04BE8FBBF6BD8E76F3D62524 +:10375000E5A811F269FEDAB1FE92083AF4DD62A63C +:103760004BBF9019BE74AF192E27DD8EF9FDDCF723 +:103770007C61339C7BC80C3F3DA859FD11FAC9659B +:10378000093A15942DEA8F90EF4135083FA3CB2DD0 +:10379000455326107C74DD1C2FC83CFFDD65F9A065 +:1037A000DF89DDB7ED29A7F78E265BBCF0AF8E89E8 +:1037B000D05F27103DE6D5DF6DB77A305F339FEFDE +:1037C000B1E87CFBB88C032E0C9AEBCF970F357ABF +:1037D000DC49F48EE4AB68FA53BF57F96960654B76 +:1037E000A7DC03FB67C17862781ADFE0D0DD76E101 +:1037F000BA987E028C576B8208A7D3F89A6E8BE733 +:10380000F8CB90A5A3C5A7F4BD72AB3BFF3734CF6F +:10381000D94EC51D70B7C6D59B766654409F6E7253 +:103820005BBCE4E308F7A0AA839903E04F8890DB30 +:103830008BB8FEAD2BE1F72FA84A60FC2C14418E0B +:10384000CBCF5EEE68958FF4BF92D551E3591351FB +:103850004FF358B0CEDC7ED1C61F1D91B0E1970E5C +:10386000A95FAF62BE73F571AB8189AC9787E8F150 +:103870008ACFD094F4CD13DD8A76E4D27C87AC195C +:1038800025EBAD4E5DCFFAD9CF2B77D93D2CCFAC00 +:103890006FAEE4FD1D5A87D00F87E2E7FD0AF2EE16 +:1038A000B453B81D3EB4D7183E9222FD42DEB7A0F5 +:1038B000F6A7D729ACD7CB53245CFEA812440CB88A +:1038C0001C415BC08FC9386D998E0FF0893F623EF5 +:1038D000A057242CEA8CF87898FDDF8A2AE1851D10 +:1038E00020888E7E036FBC1F15B61F859E0D28A1F4 +:1038F000077CB0F7CCDFA9DCFBA323123E175F26C1 +:10390000D2D5F0F7838C47D52EFC90E3EAADB16CAD +:10391000B7930288857EB7E9F6B558156C077DB573 +:1039200006FA8ACA15BA1D1EB85BEAAB3549FE9E77 +:103930006ED4DF9DE1051EAE5174FF16767D12EC4C +:10394000EB7DDC6FB3E2766F48427B11884965FB03 +:103950005AFA09FF5059DF3593FDBE01F6BA2F140C +:10396000C678D6DC9BC5F6FA7386DEBB3346DAF33F +:10397000E7DBDD6C5F897BA4FDF8A1E0BEC555DD0A +:10398000B593B934BF396A116F46952CF367E0BB24 +:103990002593ED16D0432CB8B87D914D56D97F3381 +:1039A000CD17F1FACF94A28396483B58D70FF9056B +:1039B000FECD7A3B2FDA9558DE643C9458841BFE8A +:1039C000FCA6B3AAB012BCA9CE115C46AF9474F5A4 +:1039D000F75C9C8DF7647CEAB04FCAFBB801C21F4C +:1039E000A4D239407ED739C0622AC5181967F92C8C +:1039F00046F2E10C5154C8FB031E29EFA3E7913AAC +:103A000040EABD127B83793C1FEF67BA90CE732FDB +:103A1000037F8F9176C767D72BACCF693E3DDD041E +:103A2000E7FF2186E38B9FE9FAC8C02FF14F1EE222 +:103A30006886DC4AD2F965CDEDC1AD3184EFBB6D4E +:103A4000C437A01BF1CDA6014C77B60BD74C4F6302 +:103A5000BA5FA3D355DC19CF741B6AB1483CDF9918 +:103A6000C178A6F6E2EF786FAC47DAF317E9871171 +:103A7000DDB307E49DEF8F19F416D660DE3FDBBFA0 +:103A8000297F7AFB9E00F1FFA23FDD9B20A8DD97F6 +:103A9000D6BA342FBD5FB66945829FCAA3D640828D +:103AA0009BFAFF32A88E0BB681EF453ABEB17FA0DC +:103AB000A461DF55CAF1AF1EFFF79537D338BF5564 +:103AC0004433E463C5AEEF57DE4CF33BE87736434F +:103AD0009E1EB5361642EE2E2C7655D578B17ECD8B +:103AE00071FC458FDD9BE6617C07322DE9BCFE331E +:103AF000F15EC5469B177E5DC53BAAD783752F9A9D +:103B000057627CD1EF57863EB503FF6E8B68EE3867 +:103B1000B48D7AD1C872BE72D7EFBE5613507EF9FB +:103B200021FC8BCAA8FD8305FAFE4AF43EC2350388 +:103B3000E2538F2040AEEF5F137E388F2140E3EADF +:103B4000C1EC22E3CEB55BEFEFDF04BB61E3AB0971 +:103B50004A76EBFE81B1EFD2129AF3C8B39E0BAF57 +:103B6000CB937ADCB8956E528E79F6D2C0DA0B041C +:103B700018B82CB3851360EF97ADB7B11C29DBFEE5 +:103B8000E8E607C06F1F38BC3D3C804FDB210FCA01 +:103B9000147FB3C2F25D2428F9ADF42ADDFE79E189 +:103BA00083B0AF3354319EE8B5E8A933B2BD5F347A +:103BB000C750FBD29D4D85F00FCA345795B30D7A8F +:103BC0008D0EBD686F74B541AF505321C7A9B67E45 +:103BD000C7F4F8F20545B4CF3AFFFD05EB3FB70B4C +:103BE000E91F34A724497C41DF5586D4627BE2F982 +:103BF000EDE9FB139F1DC0F56EF82B3F45C721C0B3 +:103C000005F37BBC4882DEFED0111C0FFAEE589201 +:103C10002088FFBFB05649BE7F68451AECBC05B688 +:103C2000409A9B4BF97CC1C337323FCE57AAD2DCB6 +:103C3000D9CCEF1996413CDF0CCC73EEBAA93CCF3E +:103C40007942637E5CF0905A14A4F28C558CDBD9D7 +:103C5000C6BAF94C5F370E717D7FAC9333F425E81B +:103C6000F12F74BF3EF096F4A71D627262E47ED21B +:103C70006E5D2E0644F030F44065838DE314EA9BBC +:103C8000670AF19D1BB2AC55C8F7A0F907747C29EF +:103C90003F4AFFC583BC874AFC45FA74F49B63DB4B +:103CA0003766E3FB2DF6EBA8DF6FE0277A4DEF31A7 +:103CB000DEBED8E088552EA5324DDAEFD1F348C9E3 +:103CC00033D6BF784B44F053E5962F989F44BA2AD9 +:103CD00012D3258CFD0BF76C575522E1ED9B773EF7 +:103CE000B523FE1D48B5881E186FC3E70C0B6F3B4C +:103CF0000FDA1BDFAFDCEB10E1C875BBF1F3A87581 +:103D00006DAE17A28AF15929123DD0DF5FD89B0B07 +:103D10009F433FD4EF26EA671ED95F61937DD55C50 +:103D2000F820E4C95EBB9BE30F647F8623F8E6DCE2 +:103D3000FEA8BE2F385F9707D17888960F87A3E437 +:103D400083F1BE58D7F67E54AB5C08307DCB6C2235 +:103D5000003BA3EC0307EB8FB2ED723D0A92A73D47 +:103D6000687D1CDBB6FFAFD7C09F0DD952C773AFBC +:103D700066F9BBE0C9CF795E7308FF315EC8DFEF3B +:103D8000ECF07FD3478B66078DFFD86A9F1D7C7F41 +:103D9000DE3AA6E76DAEE3D50ACBB7FFAADC257CF9 +:103DA000DB616FFDD47A9D7F01B91B9367CE1B3A0F +:103DB00023B21387A2D25DDC85F70FA2F06BE0354A +:103DC0005A8EAE1FE09171E928394AFFFE2A22F08F +:103DD000284423F3F1B72417B10F57B1F17BD66B09 +:103DE00084D66607F17145F06B865740AF31FCE22F +:103DF0009588579E3F6F333EA3EB5F05EF139F15EA +:103E00003D6363BBA0AC5EE639D27BEC7754225EA7 +:103E1000CFADEB0E66A646C2C1283814D5DE1F050D +:103E20001745B5D7A2E02A53FBB2BDFBD9CFA2718B +:103E30009BDA39965ECE7EC8F9764590E751B9EBAC +:103E40006B7B00FCD1B1D90EB9685B2602F1F47E20 +:103E5000F3F32ADBBDA73CCD09B05356C4483BEE73 +:103E6000945B87930C58CC2AA6719C0AF47723AFF5 +:103E7000A03946C65B4E1535272445F8ED4DF56A49 +:103E80008287DA3706C5B8B6F3626A99CE8DE24208 +:103E9000F5D29E1BABFEB043E68B5A8583FA6BAC22 +:103EA000F96E07E2499F91FF04FBA5A4E6EA04EC42 +:103EB000BF9CAAEF76C534F881AFA89CF325027E9B +:103EC0003BF226E648528AA32270DF309A9F1A3FBF +:103ED000E0E073F0AF8851B0FF59B23ACABE114565 +:103EE0008961F8D36BA2F31B8276D837F349CF42AE +:103EF0001E2D5867AE5F547F8CD7CBA2A8F5A2E9E0 +:103F000071E3E8F55269AC179FF0E9F9969CD77711 +:103F1000EA90CAFCD5B2DC2656A6CABC5AE4A3B4C1 +:103F2000D4CB7C9D96BD1216013D0F485FB706DECF +:103F30008E633DF5BAB0DD727CF7BFE5FF06FCB3DA +:103F4000E7A3FE0F52797CCF073D9F03FCF47B9DD6 +:103F50003F12E7B71FFDC2F733795C2F3804C675EF +:103F6000EA85973BC3DE38F5AC83F3114E2D73B071 +:103F7000BD1E78219EE316A73A497BB8F6F9EFFA01 +:103F800037B23E5ECE747C20CF2EEDAAFA7F67FD5D +:103F9000D852EFF0601E952FC4F1BAAA7C3686F78E +:103FA000D54E3DFF5D7E643CEEBF3A1F631FFE545D +:103FB000BC98F624F857B7FF2B9F1BFC680DFCE557 +:103FC0005D2FDAE720AFE4CFFFD11FF2F5D4932FB6 +:103FD000B2FC3D696B7C18B1CD4D79E1076C831162 +:103FE000D7A38F75106244BEB83690DD165E241ECE +:103FF0004E111E302FC2CB02D8E517C2473DF0D17B +:10400000EE5F111F5FCF94726EA0C0BE4F2B5E1487 +:10401000BF7C1ECFF12A9ABF7CFEC277FD21877E2E +:104020006ABE1FFE7F36DFB3FFB2F395FC1EC8F3F6 +:10403000F038A3F9FE7CBE7EFA570CEF88F7F278D1 +:104040002F72BDA7E7FFABAEF7FF197AE7FFCBCE24 +:10405000F7A7E8FD8A4EEF7837F6414F3DFF1F9DE9 +:10406000C5CF98F7D4FFA5F336ECF902D57BC84746 +:10407000ED5F15A177BC596C95B4698F2CD3F3050E +:1040800085EE4F8DC65F1EB4CF591EC27A207B02CB +:104090007E4CAD2BE7C09B04BF4C7682CAFBB2328C +:1040A0009EF472BA2F28E3BB5502F1AC82F7E630DA +:1040B000FC9AEF1707905752A8CA78CCFE1AEFC6A1 +:1040C000069AC7FE248BA796E0311DE77CB693EADB +:1040D000DD1D5437FCB3DA8EB94E4FC4F8C6B8CCE8 +:1040E0007ED6E5517ED22F3DE6FA71E2C954ECD777 +:1040F0008DCBB6099CCF2944FB08BF52CB77F33C4C +:104100007F29EA96BB5D3F1F4FA17CE977125E785D +:10411000DF26D051D5F3E2CC7813C05B2AF092CBE6 +:10412000F67B40780FBC49B055B7AF84BEFF58E866 +:104130008CDF0C3FDA210AC24182CF78AC55686F20 +:1041400015E40FCB79B21F1D8D37A1FBD5569D0409 +:10415000633A8E0E03CF78DE25DDF43ECF3B1ACFD7 +:104160003F1FAFFB3A2E015ED3E3BD41F045C7A729 +:10417000521167AD253C2B4A2B3E0D3C45E37D0596 +:104180008D55F297C47747ABCF8A75365CB7E7C7D2 +:10419000589324DCB1412DE2F517947CFD8DD70AAC +:1041A0007B7E942B89F349857ECE42D5F7C39161FE +:1041B000C7E320FF1479B95758B5703EFCE6F16E9D +:1041C0005100BFB5408410BF55EA5FFE1EFE11CE00 +:1041D0009714F1BEE6C1F701F772BAC2F007C53A0B +:1041E000EBF1737632E2FE51E72B260EDA390AF450 +:1041F0009ABD949E218EE5F61CC47A2CBEC7E101BF +:10420000FD3A5A1BB89E7C2D77CD60EC5687188EF0 +:104210002D214B3F03ED5E1EC5ED9708B7928474C8 +:10422000BB9002D8E596F96AE4BC7E0BD8BE3CDEB2 +:10423000532BE32602FCD41D65577C5FB64F1F430A +:10424000DF43BE9BD0D85E8EEDCE9120D15529E2C2 +:10425000FDF72EDD645E44F30A07FB3BC5B775EA44 +:1042600009B934BEC01CB7CE1D28F7878D3238502F +:10427000CA11D5E24DC777662FEFC3FE971A5B547C +:10428000BE1B78DC11C77C5EBCF2BA0979F4FDE292 +:104290001D295E0CF3AB893BF365FBE937BE4BCFC1 +:1042A000B52D31FC7CFF40AD391F79068A67E66E7B +:1042B0007A307BEA7E7B3A75A185269D40DC71626F +:1042C00060E7EBD8E79C78A5CAED27EAF99F627909 +:1042D0001CEF9B4F087C6D4DA7EF4D20A706F54DB9 +:1042E00031EECED7D3F88BF578F30FBABC52638595 +:1042F000F6A40BE3EAD4B32B3D9F20643E74F4BADA +:104300001D3450B6EF32DAEB49057E9418F786017A +:10431000ADEDF11D7C77C44019E772E8A501135E8D +:10432000392E5EB2CAD1D42D01A52DDC8BCA5F0D0A +:104330002E881B48F5E3BB8AC2B5F8EE4DAAD8C05B +:10434000E36D2EE6387B7C6F0FE8A0893ACE3712FA +:104350006B7AF07E4ED328C1FCD3747796416FCE32 +:104360004F32FCB9A651DE83C8DF6A1EE5F46EF059 +:1043700022BF2514461CE5F05AB95FD3A536DC1DD3 +:1043800072B6D927F7413E5F9AEB019FCCBD774AC1 +:1043900002E4E79C356AD8017E5F6DCE5B126E2F1A +:1043A000E78DCFA91B6587FF5AE2F2DB312FFF2093 +:1043B000AD17E6619C8BBC0463C2B99FBAE2D7E03B +:1043C000F7A909B49EB1FEAC9E04F8D5D1794F95FA +:1043D0007A7E9301DF91A679F1BDD9899E1DE08F88 +:1043E0004F9676E3B86AD540297F8535DC1DF8798C +:1043F00098D602D6E7A7F992FFC627BB7BBA987F6B +:104400006304E6D56473F7043F37AD88B1004FE32A +:1044100097493EBEDD2AD757D0EFB10490C7A9F324 +:10442000EF8C1A6BD17AEAA7A35358E39385786A85 +:10443000B0E6C03826046A0EC3BF9EA3EBAB39AB0F +:10444000E5F9B12EA3255D85B5614C0A3D3FBA293A +:104450002B0779F106DF3C35B8E01703F35AE93F43 +:10446000BEC05FD88EBE33DEE269811C2EB95279A0 +:10447000B19BE483F1E867AC5ACFEBBC85E48423BD +:1044800009E7061B248C7C55C88DBAFBFDCE08BFFE +:10449000DD2E7671BDBD44E6A376B1876B38FFEAA9 +:1044A0007AE15E46F066B223AC3621B6543BB97C65 +:1044B000BC9AE45D0F21B655A733BCA3DAC365A847 +:1044C000BA373F7FB2DACBF0AEEA410CEFA9F63350 +:1044D000BCB77A1C97CF5617F1F368F933C7358FFD +:1044E000E589BB27D17AF0F97C33D343E382FC71B1 +:1044F0000AF76D38AF24A4BC4BEA2DE58FD0E55107 +:10450000D73E82CFDF54811E840FDBAA51163EEFC7 +:10451000696DCC00DF8D558F6F7F1AF18E052ECE21 +:10452000CB6A118DBC4E5A84C51B1820E58F83F8C9 +:10453000AECBADE3B222F3D4AF5DA0086B047F5DD8 +:10454000571523AC11FA69D6D224133C63E9DB2F4B +:10455000B5A7EFF7EAAAD5802E876F3DF2D07BF49E +:10456000FC915BBFEA21CFF5FEB03E32EED2229A3B +:10457000256C75F27EFC233767A4A57495DF03BD17 +:1045800066E30F0FE8D3FCE56358872B54EF3282C4 +:104590003F047D089F1FEBF4295ED16DE5AFB1AEFE +:1045A000FD4EAF42DF397C73DFC241D4FE117D3F47 +:1045B0004AAC22BC46EA9974A9BF3E81FE4A92FAEF +:1045C000AC0072342CF5D627BF4D0BDC86FAEB130A +:1045D000BC3801A1AD6A1F984FF06A9FDDAB22AED7 +:1045E000572F56226E4338967645C066D6638D1D8A +:1045F00093100F663D3612FB9E41279FD3A28EB0CB +:104600001F33BBF73E9101B954A7B8B15F83739DC7 +:10461000CE64C83785F74791077425E9CBC707AA49 +:104620004CCF23F95679DE0BC97204C7082FC76730 +:104630004A56537BC8C73A9F7D5E84FC9DAD3F9F21 +:10464000D3DBC2A5F1FC197C0FFB87AB7CD3C01F69 +:104650001D509F8D32671AC6D7C155685522F67F07 +:104660009F1A68D5FB97FD1680A8F4FE1DBDBBDA26 +:10467000E766F3F92CD65B463FB37BE7ACEC0A7DEB +:10468000BD7A14B0236A6DDEF4546A577FEE3B6E38 +:10469000195F77CAFCECB20BE80D234E77147FCA82 +:1046A00073923CDF453B9ED88173128B3E72B0FE05 +:1046B0005A74A9D44B223B983F85039AE6B8F898E0 +:1046C000274E1CBC8DC67302E79810EFDFF5A91DBD +:1046D000F9A1B46CAA123300AB4DC8338D8ECF1E36 +:1046E000D8F151429B71F15DEAC5C5C5951F12A075 +:1046F000178CF98C7DFE4C1AECAC4AE52CEF335547 +:104700003EBF22ADADFCB0E8B8F8B9F8B958FDB578 +:104710008A38F32D47DB8C9F47C7019B0746EF473D +:10472000B80A2027CE1C5283D84F6F09F648146D63 +:10473000F46FC4CF2BD7D24B2958979E44EC879D5A +:10474000BA805D9E3748DAE527F478FBA96D2AFB2D +:104750004BA7B6C507619F566CBBE720F6292B36E1 +:104760002A6C9E978B06C617E1513823F518F2DDA7 +:1047700052605C7B1221AF8CF1953E115F05BE5AF1 +:104780001852FC9B681C2D4E4F62BB8871240D9201 +:10479000EBA2D411CA67BCEAE3760C9272D068B778 +:1047A000B0FE1E8E4B53BB936CEFFC294E709EA047 +:1047B000687E1DE33BB62ED78B7DC585A19D159CDC +:1047C000DFB12DCE8D38C4577A9EB3F19D4E7A7FDE +:1047D0009D0649FBED98BE7F776C873C9F8E71628A +:1047E0003D7DA598F305BB0D92FCDF6D90B4875E0F +:1047F000D1D7B1D17E61A829A13BB5FF62EFDB5CC7 +:10480000F6D3FB59E86AE80FBDFBC5AE38DE8FFF73 +:1048100062D7838588339F088D4A05FF1BDF1F3AC7 +:10482000C826E9B04E1D077C89A0CCB329075E736A +:1048300023C799B23E9015B9CE64BED1B15D4F2564 +:1048400058B25BE958EEAC72E27C68E5AEEB8BC027 +:10485000C7AFD8243EEDBB260570ECB992D42DF439 +:1048600004AFB30C6EBFCA12D1CE61F3B3F0B3ED97 +:104870002DF6A3BD11875EBCDBC6E70B675EEAB908 +:10488000FA5AACC3576D4C87C57D3C57733E528373 +:10489000CAF9CB8BB34418F6C7929BE2D7633FCCDF +:1048A00018EFCC5CB9DECB5629C24FF32A0BAA42D3 +:1048B000A3B203D13D801CA5F4C63CE44F36650588 +:1048C0006FEF99CAE77DC31B525BF34C691DF7C4B8 +:1048D000B9C89241C93CEFFBA617B2BE3B6C1701A9 +:1048E000C885C093320FA7ACABCC8F7E007C8FFE07 +:1048F00092C33D5308AFC775BA964D0EF7445E4656 +:10490000D993199C9771DC2EF74BF11CFBC56539C7 +:10491000F43EB54BD5F379F17E52041F95CDF67A6E +:10492000D04E4DF67A7C2E8CD77D92EDD6DDF102FD +:1049300076ABE5E9783DBF2A86F3C88DF796EA7C29 +:1049400097AAD3535C23F331EFB3C97CD5FB36650B +:10495000F0FD1846FBFB6CDA74D84F9807ECF58530 +:10496000F6BA9ED87731C6BB30A18EC7795CE7F323 +:1049700085B175322F5C3F778CF6809BF43CF6E670 +:10498000AD0ECE5FF92AA3E15B8CF7ABAD7D900352 +:10499000037CCFDBCBF5643F123D173DEE08A3FE51 +:1049A000CBAD326EFDA52DF82DE4F0970FA5F0F9F3 +:1049B000A82FDB05F3393F40715B609F7DA9E8B00C +:1049C000CDCD7665173BC1D43E35565890BF336E7A +:1049D000F2DA99C86F68D9E8007B8AAF36DF9FC6E4 +:1049E0007E8DF024729ECD2155806E5F3DFEEF7D61 +:1049F00022ED17A35CB4D19C77D79425ED4AA37E12 +:104A0000ADBE2ED70E927EC7BA41524F95C785EEE6 +:104A1000EBCAF393F826FAB07F470A3E9EF327B617 +:104A2000F75020371E10C15F7D3480BD6C0FF2E659 +:104A3000CB9EDCFA3AF66BBFB28806D81FCAAD5BD4 +:104A40007E85FB3952EF4A643D24C4469EDF976E53 +:104A500079AE95162CCF7F617B092F9AB2A527E0FE +:104A600083A473145A5F8B2C0AF7BF684F3FCEB7ED +:104A7000237A58789F6CA7AA8F876C4AE06FB3CCD3 +:104A8000571E9F1CDC0C7BAFF9A16E02E7DDC7AAA5 +:104A9000EBFA837EA737C659C04FE5B70D4D1C0A08 +:104AA000BCBDA10AD81FA7ADDEF6917184687C4514 +:104AB000E7819FD0E55319AD3B9CFF2CDDF310DF60 +:104AC0002F520ABE045E1E57781FBB74E5D0FB99B7 +:104AD0004F5FB7891ED4EFF1D03D0991F4792FFAD9 +:104AE0003B762FB72FA5F6F2FD5713789C9B6D9C54 +:104AF000D7124DD78B7EFF71F5A2DE3F37FF10D95D +:104B000005FDCFC7C369D1F0AB8FE8FBDF6C8B61CC +:104B10007F903C003EC776CC169A87791FDB1EC378 +:104B2000F2EB589294135F903C0DF4C2382EFF3D87 +:104B3000F3E95B53F8BCDFFCA0F9BB46BF1FEB7287 +:104B4000BC3CC59B08BFB3FC0D290F895E57F0FB29 +:104B50006FD8F8FDE8793C87F7DA45ACD3ED71CC36 +:104B600017C73A487A1CDBD18BF55353925B30DF81 +:104B70006CB5C97A5BA833ECE063DB7BF96A23BED2 +:104B80007B2C29D4D91DF1BCC9165C3950CAD36617 +:104B9000F8C5228C583CF28B04C73F8CF74A9DAB7A +:104BA0001B60A720BF373F87CBB023F9FC3CDDF16A +:104BB000C9D29F1C3058DA0F9CB39AA6E793B3DD95 +:104BC00013B2438E6BBA7D58B62D3ACF57D6A7187D +:104BD000EFD3BA4B35F28A2D186FC89ECEF106E19D +:104BE0007992C65BBAFCFA85C81F2FADBAFB5AD8BA +:104BF0004FA55631CE4EE36A52541E47538C98351A +:104C0000197664643F11F65BE7C1E7E2B4C29DC662 +:104C1000762BEBB7AE83A5BE035C47DF2B5BAEAC58 +:104C2000C6F70DF9C281C2B4563C21AF15F93D4D0E +:104C3000A3F4FA0BCCBBC926EBA3E76D8C277FB09E +:104C400094534D599EDF0F035DFEA2F2F9AED33FA0 +:104C5000E42626B761A7B5EA7B7B6B9E2D8D1F6787 +:104C60006E595F0F96F2AE94C68771F65C67CE2BD5 +:104C7000EFBDD10C5FB2CD0C67EF32C3FDEBCDB011 +:104C8000F78019EE8B7EF3A49F8D73CBF0B351C2E6 +:104C9000CFF638A49F0D187E364AF8D9780E3F1B00 +:104CA00030FC6CC0F0B3011BF886BF0D18FE36EA6D +:104CB0006FD0F124FCE134E46B5658649E2FD1C3CD +:104CC000CFE798A6DB4DE7524E3D2FCFA5103F48CA +:104CD00079BFD0C5EBE401B4180CBD24D753EAB3B7 +:104CE0008EE032C4773DDACCC158AF6BBF9E07BEB1 +:104CF000ABE8DAC879AF4D2B5EEE790FB56B54E2B5 +:104D000005EC8A8AB55FCF841D95E6D14A06D37833 +:104D10002A631B560EE4B87D98E547638DE78D91B5 +:104D2000928E1C7F2956715306D52F486E337F28EB +:104D30003AEF5CAC36E799FF54DE79341F1876E021 +:104D400023B6E60C37FBE9C31E469C77B112EF860B +:104D50009FFE698C5886FB8302AFC83CB5964336EC +:104D60009937B05AD92022EC93653ABE0D78CED946 +:104D70005CB6C7CFC1AB158BB85488EE5A7313FC21 +:104D8000EBD30B2C6C779F5E5050D80EF61FF96555 +:104D90005813B89F2B72BCB89FCBC43F5B92A3CE75 +:104DA0004D7430B5C7FD5CE673139798EAA7ACCE97 +:104DB00035D597140D35D57717727C4B16CAF195FA +:104DC000907EF0A7005EC6798B4B403BB2533A2BE6 +:104DD00081952C97D72B7C6EDCB3745521F0729C97 +:104DE000D8197104836FE6E8FA45580376F0DD9927 +:104DF0005459FFA5D270E4367AEF84AF6E33AE4ECD +:104E000039615977DF300FF2EBD77776D33ABC416F +:104E100009A541F4FC7E80B61D7CF399B57112EFB3 +:104E200027EE6C975C03BBF350DEEB83D0DF369547 +:104E3000F3260C7EE96C9371BAF5838866644FACF7 +:104E4000AF93F9BCEBEB5262BB47ECBF18F36C01BC +:104E50001D04CA6569A91C17120D9807D9EDCB600E +:104E6000B79D3E24ED76633EDD97873B2EA1FA1B6E +:104E700076C6307E3ED3FD86E37D5EECEFC1F98DD4 +:104E8000EABD9D55D803966D9BE147B852B597B0E2 +:104E90004E16ACEFF11EEEF75AF4AE2A709EE6F312 +:104EA00035A31306D377BEDA6EF38E27F8B6BA476A +:104EB000EDF09317598376CEC3DCBADE8EBCE45F87 +:104EC0006C59CFCFE76D29E6BCCBF9A28AFDC8A308 +:104ED000FAB92C63DE0B0A94756EE2AF5E43241FB1 +:104EE0002E8895FB79C4CF2F615EA7B7283ED88F57 +:104EF0005716EDB417D3F3C33ABF7AA64D1B0BFE7A +:104F00006B09C9FB395A5E53E5BD6357AA322FE6D8 +:104F100002F7F94C399BC5FC7DE5D9BEEC674D0D18 +:104F2000F7917E6CB6941F2DF52AEFC7B5BCB63F3E +:104F3000750ABE576FE3DDBB05F60679FEDF22AAD0 +:104F4000708EC033AD41F25596A882FDB7E42F6F45 +:104F50001FC4BA5B92E5F4603D140D534DFC593902 +:104F600026CEC4BFD344B2E91CCD55482A8980AFB0 +:104F70001CDFCDD4FEEA2BFB46C9839CD67A96076C +:104F800043A2CE011698E0722A6F817C129799DEB7 +:104F90002B17935BDBC11FDE28EDD6F25D491BB0FA +:104FA0002FBEC022FDA1699A7C5EB1573E1722F642 +:104FB000DCB9749CC7477CC0746E5BDFE743BF1CE1 +:104FC0000FECD6C0719DE60C929784D1F2DE8D76FF +:104FD000C4D3C85C6E469CB43C4030FAF58BE65AAC +:104FE0009C1FB14AFCBABCEEAECB325AF9A2629712 +:104FF00039DFAAE2D0DBDCCEC8678CAE273B7D650B +:10500000078C7BBCE2E37393DB9AEC88075DA975A0 +:10501000E47B29A2EF4B2B0B35F138A7EE4D7363E0 +:10502000DFB622EA9EB485433C523FE9F17FDC3390 +:1050300024ED8406BB8CDBBAF65978FDC97B79CEAA +:10504000F1E5028BBC2F200A2FE37DEF727F1D322A +:10505000641E1AF0628DC04B341F014FD6083CCD40 +:1050600013124FF3489A0409EE003E8BC4CFCFC40D +:10507000D77CFC41F5F3F72A41E4BF45E3679ED6B0 +:10508000C8F89BA7B9AA82EEF3E75371CBFB0721BF +:105090009F7664C87B0DA3F1375F34AC84DF3B9F00 +:1050A000F4463889F9C2EE643F4DF1426F7B063514 +:1050B000DA6D529E719CB7E5B5B779DDB578695563 +:1050C000832F04D5537B97DFD3BCAC8D3CDFC967FE +:1050D00065FCE4AAB3562EAF1C6F5E7753CFA6F1E2 +:1050E000F39F8B970AE0197C8EB85E421BF7EC2188 +:1050F000CE9770FE7C8DFD10430EB7DA75E6BCE5E9 +:105100000BD97FD171C21B87E871C23C9167CA5B22 +:10511000BE80DD119DB76CE8F11697D49363D5EC92 +:10512000373C34EFE25754F6D33DD3C659F8FCF878 +:105130002BF27E3C6DC59926F0A7166F6139B83801 +:10514000BE2BDF6BA1E971BB73F6764D4A1AE27F85 +:10515000C5316ECEC72FAE518BA0BF8AA99D27A2A5 +:10516000DDCAE5DD3A432F7C727BAF8703B45E3E38 +:10517000B929350D71FF4F57D85249729E6BF7C947 +:105180008AB19D919FF1E9DD8E69C136F0F3D010AF +:10519000195729BFF57DD65B272CAF254CA3F7CB3C +:1051A00056EC4E40DA7FE98AB7F3DD6452F80668C0 +:1051B000EB86E421BEB77EB31BF872AFE7FB04B603 +:1051C00093B8043E8A57AC60BA2F52E47EF50D4A7C +:1051D000F8C8486A773CE6EE8469443F8DFE87FD57 +:1051E000C3331BE3F5F368359C37743C96EC016AD6 +:1051F0007F3446E2F3E8CE782FDF89E10D7466FF55 +:10520000AD9DDCDF29B5D45F85F14C4CD5B60FE1FF +:105210007DDEE0E67495DBF1B975ADA647625BF122 +:105220000FA3DCACEB69D8DB28616F235F06F63691 +:1052300060D8DB28616FE379E55AB3FDF6B2BE5F53 +:1052400068C483BBD436FB60EF060A44EF2AD6B3AA +:10525000E30BFE08BDF58AB4179628DE558D6C2F3A +:10526000C5D7C1EFACB54A3B3BF0B13C1745FF7A1F +:10527000433EFD5ABDC48BFDFCFBE36E7D04ED9700 +:10528000627F6800EE3D25DB2B825F479E758AC8F2 +:1052900073B7A3C8088B84473B334CEDC7BAB34CF4 +:1052A000F5BF48EF63AAFFA5C767822FEF3DD8D4AB +:1052B0007E82779409BE62D02F4DED27F92799E0C1 +:1052C00029E3A69BDA4F2D2A36D55F3D6DA1A97E35 +:1052D000BA76BD09BE76C14DA6F6D755D598EA85F2 +:1052E000A87A0CF8F107E43D6CF5F09F1CB8FFC5F7 +:1052F000C925D5FF0979CCA348D4F3BD2B7FB9F1DB +:1053000011C0FB90D74C2B6ED8684B555B71FC1FBE +:10531000747BE9EA61FE6F87B03FDDC0F7682276F3 +:105320000BBE8B1BEAD1FD5FF9BCA3D5885B35644E +:10533000F07D0951ED2FD46E58DCBED31E62B92525 +:10534000431FB8CE4AF26BD8C07DB9DD08DEFDDC64 +:10535000C7121EBAEFA9AE043F3FB4C74C862FDD7B +:10536000771AF5970F6B92F553049B262F3FB7E200 +:105370003AE4A70C1BD975B557C645DA3CDF6E94E5 +:10538000C013CE85034F28C3C4F728F711DFA33C11 +:10539000407C5F4272ED20F13DCA43E467E2F9FFD1 +:1053A000213F13E56BE467A27C9DFC4B940DE45F09 +:1053B000A27CAB7A1A97EF546BFCDE5FAB1770F9E7 +:1053C0007E75153FFFB07A29971F5707F879CFA14F +:1053D000328EE022BD03FD5E813C18E40B44DD4BC0 +:1053E0002AAADC7CFF41ADAEB744BD9E57B38FFC0B +:1053F00057E0B3D19A74C4D9BABF78617FDF2A8EDF +:1054000044D86D5758FD3943998E1DDD2CF7F5E7CB +:105410004F7AB5814389EEEF664DE991AB42DF5596 +:10542000BD944875EF5ADABE7F326EA8E497DEC3AA +:10543000FCC3F0DE70E761DE4FF76490B53A94612B +:1054400005F4577264FC72B8B5A116F5B5DF0B0F01 +:10545000FCE617E3FFCAFBE0B5642EE3FCB172562D +:10546000FA2B23F4FDFBDAEFE5FEFD088C9DEA87BD +:10547000BB657DED5CD2743ED487F8FB2370DA59AE +:105480009E6F33E5ED8C39DB309AEB5D760FF24D94 +:105490004738C3F27B4EE1467CF9C5F83DB2FFB117 +:1054A000B2FF8DDF87F9FBF03E91973DDCD93A9E44 +:1054B000653CBE06793F5DB66C5FABB71FA151FF7F +:1054C00049185F951C5F31B597E367393702DF4CA8 +:1054D00082B72DEB63D3E5F9E43167F57AAF9C6FC2 +:1054E0007BAB8471A604F599299AF0537F9999C2F0 +:1054F0008BF8DB88D4860C6EAFE733C45BE5F7121C +:10550000BDF23EAEEE7FD7E47E002100E337F2929B +:105510008C75DB29399C013BAFD3623B7F2F53DD78 +:10552000E983BCEEE3D37E0D7EB03A2D3CBF5ABF7B +:105530003C2FFFE6F39E4EB88F74926EAFFF13FAC6 +:10554000DF82F7873B5F90F4C7256F99ADB0328F4C +:10555000FE37B84DFA4B7C11BF60FE447FA607E8CA +:10556000A9D35F31F0A3D3FF1CBD9645D6EBFC71E8 +:105570003EFD4392DE3A3F8D70CABC09B407FD87F9 +:105580005B253FD4C6C87C8F17E30B1FC03D5984F1 +:105590009B22C4E7871BFC5225CF0FFF6FA5FF009E +:1055A000ABBC47CE51E6E47BEA7E8A1F66358B4270 +:1055B000DCD379CAA7C5615D179FF51C043C478CF5 +:1055C0002A84796ED49FBD40BDF64DB30DB0F1BCB9 +:1055D0004B8E6C67D45B9D6FC541EE19DF31DA8D60 +:1055E00038AF5D8E13FA62C9D8D03AE8AF7135563C +:1055F0008E5B9365C2F021D267329FD39FE04B8BC5 +:10560000CCFFF41E583C00F78BCAF35BC225ED6A51 +:105610000FFD07B95AF843D172F427D46D56F81D1F +:1056200067904F4BDF294C35DBE7E3A2F6D72FCB52 +:10563000FE82EDF1CB7EE29EEBBF0DD5CFDF64891C +:10564000ACFFE43DA35F48F97C71F78CF616F5CC0E +:1056500007638A653E17CDDF9283B88D5F54012EB4 +:10566000145556F0C1385167957EA5FF78C500F6F0 +:10567000DA193F978B303F9F400A05CAE40A621F40 +:10568000C0FBE326CEC0FDC1A3734777C7F388FBF9 +:10569000F37EC0F82A54ED6FEE88FBF3F68D91EBA4 +:1056A0006DF154196FDAE7ECD6A61DFA0AE9DBEEC4 +:1056B0003D8017C1E54BA48FBBD3BC5F267D0CF8A2 +:1056C000B2DE35BCAF5CE831E71D19EF5FEE1E2D91 +:1056D000AC2917D67797F77FA623F0FC6A52AF3133 +:1056E000A0D7AB4903C7201EFF6A527B8B2C1D76C7 +:1056F0002EFB3DDDBDADF119EBA3B5BF42EECFB83A +:105700002F784C3B795F70345E2F1321137EC7EBEB +:10571000F8FD1978ED352CEF7CBCC6E1B0631EF0C6 +:10572000F9F61E236F0AF1E4EECB1B18BEC126D793 +:1057300041F9D3130A9017BDF85D99DFF125860270 +:10574000BDBB74288F7FC4D2C1C29ACBFB5101E08C +:10575000BBCC29F17822F0627FDC6BFE528A3608DE +:10576000FD7FB14EE5F3F6279E8CE178DCD1E05366 +:1057700009C0A7C1C765AA67B517EBF05555DEB3D9 +:10578000F4C3FECEB887F4427C4DFC3C6A585E1BE5 +:10579000FCEC227EEE773E3F8B8DF21E83326761FA +:1057A0009B7436FC4E678E3F0E7CE816E1EBC1FF22 +:1057B0001542FA4715CED7E43D9504E3DC6BB45DA2 +:1057C000951F4BEDA9DEEE94F9C206BD331DF21E06 +:1057D000CBCC38E1461C4468B997705CBE9B7F1AFD +:1057E000C64F7EEDB6C8BCB511E1BEBCEF3CEE9035 +:1057F000CAF9EE2FC7CA7BDF1B891E0AD9A7BFE8EB +:105800005BE5EA4A749C99AFCD198679A93FA8E86F +:10581000F7B51E8A48E1F879AE8BFDEC9FE9AF97AA +:105820000ED3FDF5FEA2FF3FFD3D8576F2DEE1C51C +:10583000AFE40631EEC535A4D552F97731F89EB8FC +:105840005AF8E759AD726784E8C9BF97313AD5C6AF +:1058500079E6FFDB7E4F215368BCFEFEB3BFAB3061 +:105860004E3E3AEF77153213561DD0525B7F5723C9 +:10587000FA771532F5FBAC8547EA0FE3F714460AD1 +:105880003FE7E58F4D37EB95D1EE5107DC5C9AE3AE +:105890003D993F91CFF5F8305DAFFC14DDCB854EDF +:1058A0007779AE137CA0FF3E4A10FC69FC3E8A412A +:1058B00077E377526ADBC9DF49F957FB5D9468FAF1 +:1058C00044FF4E4A347DA27F37658416CB781A5D3B +:1058D000E662BE36E8348DFE637B00E77295FF7E9C +:1058E0007A3546ADD33362751EEE293D552CE5FA67 +:1058F00085F4FF835EFF11C88B6F114FC27917A724 +:105900008C87F86BAD226684C0FD849C2FFBEB5A1C +:10591000790F54AD55C603024457DC8BF75DEC3F5D +:10592000E47D8E641FD93A202E53C5EF07EC4E77E5 +:10593000AD17F44E603E59BA549E073E6CA9E3DFA2 +:10594000BB98955DA560FFF268967616FDA78BA2C1 +:105950009DF3382E5F3510F27DE69F1D9D513FB3BC +:105960008BBC3F526437E645DA233333F53CCCE158 +:10597000FA7EBC57E661A9C3655C2DDEEBE6730DCC +:10598000C5D942CF6F159D67F6031F7FCC767C8B00 +:1059900047DAD58D36798F65E01599CFB3AEEA2D0C +:1059A000B6FB37915DAB4AFB66ED9D1C674810D88E +:1059B000C77D24A63909E3EFB55698EC853E41A78B +:1059C000292FB9EF16B709EE174A37B5BF74AFC71D +:1059D00054EF0BF736D5E71EF29AE0BC8641A6F6E7 +:1059E00003DFF79BE0C18DE34CED871E2D32C3C36F +:1059F000BB4A3C8127693E3397B883F21E7D192745 +:105A0000E96297F654ED4DD29F30F2D7357D1D44B3 +:105A1000E7AF77B2CAFC757B95D46B9A4BFAB7EEB9 +:105A200064E156F95C4C03C3B81B82F3C603E63C41 +:105A3000F38E4EE95F59C648FFC3AEE799C7F696A5 +:105A4000E75E8CBC72F22BFCC07777D1389D7FEF7C +:105A500040BF4F349A9F7FA1D33D7ADC5DECF23C8E +:105A60005DED4D76DE3FD75CF62625E1FCF1540D69 +:105A700094FCBFC9D9F6BD4F53753E7B2CB768C2A5 +:105A8000702A1F26B5C5F6D779FD791B21EF6A7FED +:105A90006BE7BCF19FEA6FE6A5723E332C965993F3 +:105AA000B2D91FE4738046BF73F57E7F39526973A4 +:105AB0007E33139BF9DE359168F7807F35D74A86B0 +:105AC000DDB122496D03EFADE732649EFE75AB4355 +:105AD00077F6A271CEB0D7D9E48503411BF8617C7B +:105AE00001D991B43E5EDE33FC2117D1E3E1A55626 +:105AF0008E83950D7F6666A03BECCC66E60724A2FC +:105B0000603F11F6A79AD33AEEA611328FFC4E5C95 +:105B10002CCDE7257EE071B5E8F19116113A777E3C +:105B200022D006BF69AE837C0EC1BD58F253A78850 +:105B30007356F03FFFA7CE4B08EC90523FB63A2188 +:105B4000CF39FE04FE8C732A9EEB6D451B5C382F0B +:105B500022C6291178F866848C5BFC79B8A437DA00 +:105B6000411E5DA81DD97D89D85F68119E44F74FFD +:105B7000C4D5FF27E69F69957186CE4E795EA493C2 +:105B800055637961EFADDF73771EBFEB72438F937F +:105B900075B4CA75DFD12BD7F5F972E1007FDFAE9E +:105BA000C97BD3A2F1CBFF22E22AC6F995D83152A4 +:105BB0008E1872E1DC39941ED20FB5E9F221D8DDDE +:105BC000C27907B7C59BD771B32E1FEE31F445805C +:105BD000FCF87C939C10D8D7AB5DA1B29C2039799E +:105BE00050A37116E35E1677EBEFC3CDBD57EAB154 +:105BF00011FEA2FBB06F327B8D4DACE77D05793F86 +:105C0000EC7C3D4E5E1C88BA9F45B7C7CFAC56DCD6 +:105C1000F8DD8839ABCCF5F35D473E86FF3837FABF +:105C20009E1A63BFEE27E2008DC3757BCD2BBC7A35 +:105C3000FEFD328CEF4C50DE7B7DEEBC921EFF6988 +:105C4000093E25E15B8488FC1D09C32E30600FF6F8 +:105C5000C922EE6121FCC6F6867E5F6E6D33BFD130 +:105C6000C0EFB93C0F7D9F8ECA652BD89F91F90D6F +:105C7000240F785FEE38D5C30E3C1E38CDED8FEF84 +:105C80008AE1BC9213BE86FED8BF35F6E9BA6B72C4 +:105C90001FAB6557BCCC6F705924BC45DE63BFE8B1 +:105CA000EFC1FEF0631B034F99CE39688DE67DBED0 +:105CB000E852ABD9CDFEA66F80163382F8EA98D5AC +:105CC000EBF4127CBB6B1FDFD3359EFC47C835E479 +:105CD000A5AC4895E367F915382DF15725F17705FF +:105CE000197A909FEF0A929E88630AF26AA92C0E95 +:105CF0000FE6FE7FEE3ED894B33EB9FF7B7628BF19 +:105D0000AFAD1ACC70EF60F3A8F7A9DFAB349707FB +:105D100071A4A9B5BF1E1B0BFAFFD1B582CB4EE60D +:105D2000F30346D97B84A44BA3ADEDFA3F8E90EBF1 +:105D300063CF08A1DF5723F97D718DC2FB6A8BC148 +:105D4000E380EF94F7731AF0E93A1D1E2BE1252B3F +:105D5000240CD5043B78B6FE3B699BF5F80BE68F27 +:105D600012F3475C609B1E9FC1FC5162FE780E7966 +:105D70000518F20A30E41560C82B94905778FE7924 +:105D8000D268DED7C6BEDD9888F5847DBB3111EBC5 +:105D900003FB769130F6ED22DB63DF2EB21EFB763D +:105DA00091F5D8B78B84B16F17D91EFB7691B018D7 +:105DB000F4CB561872CD3FC9044F217F604CC47A92 +:105DC000C6BE5DE4F7B16F67FA9E76BDE9FD6BC5AF +:105DD00052D3FBD8B78B6C3F6BA962DAD72309C8C3 +:105DE0007A7DCEDA14E6A3645FD1BC1179FCBB5690 +:105DF00037DABAB27CE038C6E2F258AFA477DD38C1 +:105E0000497F8B3C1FA134F3EF0B9CBEC52EE1B143 +:105E1000E6FC6DA3C4BED7189BDCF742897D2F94A6 +:105E2000D8F742897DAF313DE4BE174AEC7BE139BA +:105E3000F6BD5062DF0B25F6BD5062DF0B25F6BDC7 +:105E40005062DF0BEF61DF0B25F6BDF01CFB5E2817 +:105E5000B1EF85E787691C2511720CF67A77939F5D +:105E6000497C68F233DD2618F67A647BD8EB91F52D +:105E7000B0D723EB61AF47C2B0D723DBC35E8F84BB +:105E80001F1BEE613D06BB3DF23DD8ED9170BFBAE0 +:105E9000C04B88AD4D5877F200CAC678E5619C3793 +:105EA0007CEC852B6659491F36C6289D9348A6DB96 +:105EB00094A9B3C640DFEAF98FFD45B305F24783E5 +:105EC000333980CF19725E69BFEF33B8FE65E35C8A +:105ED0001CFE11DD7DBB04FFEE8CB1DF6EBCEF2537 +:105EE000B58DD268DF0AB7DD2EBA7FA31DE7564510 +:105EF0008C03279A9137E3BBC595033F64B345E113 +:105F00003C93CDCB645E74345F7DACDB479B2D3B13 +:105F1000F7E11C4C73B1E2C5B98FEE751A9F33EBF4 +:105F2000374358545FEB7C7A3D92C079B50746C839 +:105F3000389F317E233E4AF282CF0F0E6B6E189D42 +:105F400048EDB5C028FE1D9CF176693790A5310457 +:105F5000FE64DF80E2DF10C1E7AFEBDFD302721C2B +:105F60008F3D3251BE172BDF7BEC9104EE7FE27246 +:105F700085F3CC866D137E9C537E4F97AF7DB7859E +:105F800055F457BC5CF6677CB7785D673BCE731BF6 +:105F9000F82A168D63709FB418A0E04E59D1D3AA89 +:105FA000B15DDA7E86DB023BE862CF410D1F9034A3 +:105FB000167988A25EF0BDA11306BC699A2FA32BA7 +:105FC0001FBF832AD837D402D75BD0EF4442400AA0 +:105FD000E2C904633E9A26AAB208BF574D2B667CDD +:105FE000F79E2114E0BBCF8CF596547AAFAFF6A2A2 +:105FF00005F65ABFBA462E8D79788725A980C7DB6A +:10600000DC6331FEF16315961FD1793CB00F185E49 +:106010006E637D6ED80F8BE3CFE5F9BC873C9FD3D1 +:10602000876C9CE7737AF919AE2FDE1DC3793DDAD0 +:106030005A85E59A613718793B65D7BF9B0FFC7C81 +:106040009515DC9CD48DF5BC7D24F269BAEE4CC06C +:10605000119CE3CB775F85A37BA797EF96BF57ABE8 +:10606000EFEF18BF7B2AB2FD9C0F66D88142ADB717 +:1060700047EEE318BF9F46F293DB9DDE6B77F3EFAD +:10608000D7E9BF776AC47D8AFF927B10782D7E485E +:10609000FEFED9EC5577174E23789EDF19C6EF62C6 +:1060A00045E7632D8CB2037FEAF74E3D23F5F84FA9 +:1060B000ABFDC7FC72E63569FF15FF65FF5469AF9C +:1060C000D838EF7F468D8CD7899D82EF3F9A513328 +:1060D000DA827BA467ECF67B154FAB1DF8866EB7B2 +:1060E0004C3E9BC9F87D5BB753A622FF94F03BBEA4 +:1060F0003146CF57CBE0F2EAB3321F75B24BAEF761 +:10610000C66704DBD32D0187CC23AC177A7EAB990D +:10611000EF7C82F883E873895FD98FB4E509B07B9F +:10612000E87BD36007A5808F8B57205F96DE66BB28 +:10613000339A8F275BC357E2FB93BD36E6AF7FC62A +:10614000C7B897E39C5C12552FE19CBFD8287FC746 +:10615000619A26F9BBAFCEDF33E3F4F8934BC697D1 +:10616000CEC59F3048C4CCC4D659C8179E89E48593 +:106170000E3C2D3FF2F5E2B365FD3523B7CE5A0E46 +:1061800067E6027109F5663BDF5FADB99CFC3B3405 +:10619000178A13203E00F978DD0D3EFBEC08F95814 +:1061A00030AA608D3F2FE2BCE3ED320F6AF1ED3D86 +:1061B000DAB775DED628E7107EB13E662636DE8871 +:1061C000F3E64B470AFF9841F27726E5BC4418797D +:1061D00098D7E8F0C63F37FC6D958BF1C1F00D7F85 +:1061E000DE330BF7C7953B1B0BC16E95D955E3907A +:1061F00077DD2A87347F6616E4D0A830E4D085E2C4 +:106200000E1B474A3A44C71FE6644BF92CF4FBC205 +:106210003FB9FDE91D90E7C6F83FB9C0EF63AC1B7D +:10622000A9EB89EAFF9E731ED1E73BDEE8A3DD35CB +:10623000B21D7E97C7DF843CFA0E6A9D9E3F2BEF0E +:10624000F530E81B53F71DC73B4AF4FBF0499EB0FD +:106250003F39DBEFF4D6408EF4162B715E68A62A28 +:106260009A79DFF83CBA4B3C3E32FDEF0B918FFB45 +:10627000C86F63E5791D1D7F33EC0D2F39B35AF1DB +:10628000F7D1D23FD8A4FC0AF7C0BEDC3555319C0B +:10629000DF5630AAE851C8BBB86C2FDF83B1C62FD8 +:1062A000F9C9DEB568339E97AF7EF161DC9750592E +:1062B0009FC5BF2B53BCD7B712E71C0B46694F6075 +:1062C0009EC52E37DF1B52B13C89F5D3CCF67ADC64 +:1062D0005534F33E9C81F7037A7CEA9E51F2FBA78A +:1062E000743F03827092A9DD85E27432FF06F939AA +:1062F000883F6AAE3D1C2770DF2CEFA9B08B776416 +:10630000FC31BDEDB841A61E6FCCF0CAF89081BF3C +:106310003B7ACF66396733E2B9E7F0673E8F69941D +:106320006EBFD4EFB36F50D85F2D59A3F2B9F2B15D +:10633000EA78BEC765F1DD8A87D7D7BDDD38DF7B58 +:10634000F1ED648D7970BECC53D87E00EE5B57DCE6 +:10635000B04B66801611F19D92B58379BD9504A965 +:106360006CE35E53A3BCF6EEFD9D9EF1808C7EDE59 +:10637000BF2C71FBEDC911EB7D4E9D62BA5FC180F0 +:10638000855FC6DB66085290348E19DD3D0AF6152E +:10639000DD7E8987EB6EC8B2E3F74866D0972D396A +:1063A00017EEFFFF95F2FF02371C2052008000001D +:1063B000000000001F8B080000000000000BE57DBE +:1063C000097854E5B9F077E6CC99992433E1640172 +:1063D0009200F1241088803861A72E1C1202130845 +:1063E000305940F086308120A1456F0497D04699FE +:1063F0009085104143890D52D461F3564B352ED709 +:1064000042C57600EB525131486B1793617169DDDB +:106410005228B5BD0FF7FABFEFFB9D93CC39990415 +:10642000B4F6FEFD9F3F3E78F29D6F7FBF777FDF22 +:10643000EF243F9DBDCC2632D6B54D90F7A4315602 +:106440002EABB6F14EC6BEC49FE98C2D6F16D4C0DC +:10645000D89E727E3A5BE68572B4EA626C1263651E +:10646000B2624B4EC3A76C8B87F7CBEF3822B14497 +:10647000C6568C604CC882F6F16E9B13C75F0DE365 +:106480000B8CDD2C0773B1FEE6B10AAB8983F67580 +:10649000593606F3F9B6F0797C8D71B66BA05C665F +:1064A000956DC3A05C12CD18B687F505B07F795005 +:1064B000B5C53B715CB6ACD0C9D71B1FB6BE326D3B +:1064C000BDE5CD71B69586F7DB2405CA4B1853DBC5 +:1064D000C2F6A73FA7AB02ED67795D416A2BACB767 +:1064E000DCEF9271DE72AB6A73E3BA705CE8B7A45A +:1064F000A5554A0BEB7F8D6AA17ED355859EF9E9A0 +:10650000C10C01F77B7B941BD7BB446E96109EF9A0 +:106510003A9C1FE4705829073370FC950E0E077DD6 +:10652000BCF2163E4FEFF5717897B794D914A8BF17 +:10653000C5EA4D6D85FEB7C03AFDF05CB2E3488612 +:1065400080CFCA28B700E7C1645FAAD7D5D3FF833D +:10655000076F4AA5FDC3FA11DE2EB7322B09D6B359 +:10656000A21916A3D093E62D9DC02ADBC2E0769334 +:106570006A656C203E2DF464CDADAA6310C083F132 +:106580009FAB6C2766E03E6AAF666C23ECC3E77C8A +:106590007E06EE53FE2E63E23458EF96B7A97E4591 +:1065A000129305A8B7B1E704ACB795431F28337F12 +:1065B000AE1ACAE4637D99CED8301C19DA3B017F4C +:1065C000FCC98C554E5168DE252CB4840D8771B6FC +:1065D00014C01CB0CEC17C9DA50358E53311E0D595 +:1065E000A2ADF766EDBC4B2CEC2516DF537FAF76E2 +:1065F000DE2588CF61FD713C1C778D5E9F1DCCB878 +:106600007D6C4F7B7DDE9278DE0FE901F1708D8627 +:1066100007D87E2DB5E7E55CD1B9B11EF6B376ABF0 +:1066200018B00BF8DC5B3F08CB4F0B6E84FBC76BDD +:106630007FFAE62278FEE907BB4B717FFA3A56FEF5 +:106640002D8B290970BE7FBB8E9EE5C1694C99D008 +:106650007B9FC7A6F8BEA74E0AC39FED3F19E983EB +:10666000F93F7EF2F50C84F31F00074480F3BFFD71 +:1066700064AFC4D27BD6BFBCF16DA9CC190E2F81FB +:10668000E0D594D94EE7B72293F75B51F7E7323C58 +:106690000FE6B4291969BDCFBFACEE69DEBECA4DA5 +:1066A000ED7DCE5FF3F34F61B2987CF9F3D6CFD78F +:1066B0007CEE8F48DE609280E7D36CA07FF3FE1FF4 +:1066C000D6D61DD0E8EF660D8F6FAED846FD963753 +:1066D00096ED1561DD4B74FA2D37BED7CFE7FC166A +:1066E00089CEE7FC968C86242CB7F1F3F98ED83648 +:1066F000EE6E68F7F19AFDB725A7E3AA03A9DE6B52 +:10670000F8F9B009FC7CF0B90ACE8725443C9FA774 +:10671000C2CF67D5A3FC7C563CF9C67B3F5308FF2C +:10672000F8FEB6DA03C87F97B73D7DEA5BF07E4995 +:10673000E336290DDAFD424DA37DE9FD575466C9C4 +:106740002C16F6D7B85B423EF00B558988E73A5CC9 +:106750009995F399472438DB38AA67427C4FFB258B +:106760004C1D8C7C84F987B2FD89BDD7FF278D8EA7 +:10677000F2D3DDB6C1C8BFEA63D81E19D751763F40 +:106780001BD7BBBDFE3C1BC5E96239CC83F47976CF +:10679000863B15E9A2C46231D09BFE3CADD1D790B7 +:1067A00098B625B8DE21094CAE0510FF305ACDB69B +:1067B000C0BC3FFC9643AE75637F9F82F57607931E +:1067C000FD00F23D16653CE1276C795332C232344C +:1067D00009F9DE8835A13FE3FA109DA2C6F3A70BA5 +:1067E000F66D9FC1F104CA6C107F1FC4E7306B1BAC +:1067F000F1A9E82A8E7F36F60E956DC0B7106FF5B9 +:106800007E43D80901DF27C35A70FEA6CCE5747E0B +:10681000D2084E2F7DEDEFCB2BDCDFD9345F80E447 +:10682000441493F7C4D1FED662B97B7F994CB5402E +:10683000FFD2EF5DB3BB09863C5BA31EB541FDD91A +:10684000F54EEAFF4DEDD7BCCF25E565867D76D3C5 +:106850004D33F0B5347C4E48C5759E77C044507FAB +:10686000F6F6280BC2FF6C1AD717180BB90AE15CB1 +:106870001EDB00BFDA19FBD106073D9FD800C834E4 +:106880008AB1031B92A8FCE406859E6D1B32E97D4C +:10689000FA0C8E7F25D16A2CCAE5AE1A97BC07E1A7 +:1068A00011E474D351359CE0007A02E7C79A5ED0B8 +:1068B00021875CF1617C1AE4C7569477AC6A38DBB7 +:1068C0000F5374349F7559C6225EF2F5E9EDEF90CF +:1068D0009AD97A6CF79010D80FE3C6DCF176EE60A7 +:1068E00094D32D695902F45B5A7581F8E152E7207F +:1068F00085A11C77FA1AA660FD8E347923748B6902 +:10690000C9EAA882FE2BEB46B9B1FD1D82D240F345 +:10691000D6086E9C177E54C764E003F81B94573961 +:106920005F1EA1F14B0BF2CB15F7AF6F4886F269F2 +:106930000BEB120134F996825958CEDF19E7AE45B8 +:10694000795BCBF7C376011F75F4F05175AAF7FA9E +:106950001970CEEC12E01B8C3F1AD6C644DC4F9B5C +:106960008AEB67A077EC67B85EAF0DFBBFA0F1CBF9 +:106970008E96D32E453B9F02A41B5FD7E94D78AE80 +:106980004E8BBB4941F9AEBCA520DC5F13D91E0577 +:10699000F187D7AF75F17A786EAC87FAB5BBC500D1 +:1069A000C223572C191442FD6B87487C71E5EEA277 +:1069B00041A86FAC8432CAAF9D3815E053434B0EEB +:1069C0006FB72DF7077EE0A7A902F3223F3A670DC4 +:1069D00015203C3EDA3D38BE06F5BD5B6B4732A85C +:1069E0002FDFBD29159F1FED8E5A8C7C7CA65C3055 +:1069F000330EF59F5D7159A2D243671533389D7DE3 +:106A0000FBD69CC128EFD6FCCFB1476490AB2B01DD +:106A1000476518F7625B4CC00F4DD66C38982A0258 +:106A20006A39137D2B106EDFB11C5E340DE5B0109A +:106A3000782C99DA2B83E54874ACEB5380C70AE0D5 +:106A4000E9ADF7BE4BE37C6A393E7F09F45F73EB37 +:106A5000B3B138CE771E3C395986F759137DFF8E76 +:106A6000E3FF49D8FD980C20613B768F43F95139FB +:106A70008371BE1AEF5DB484C3D7BD47E97BBE8A7C +:106A80008302C1532F2F0D0CB031D44B83CC26E39E +:106A90005366A4077F24B22A94EFBA5EA2BFAFD593 +:106AA000E0F2D180E6543CFFD58FB5A6A2FCF8A356 +:106AB0008B977DFB5E59F95D5887AFC52233C03B8C +:106AC0009F9591DEBBC2CFF5695601CC24B967FE14 +:106AD000AD336268FDAB774C30C83D908F34CF1F2B +:106AE000ADCC83EBB8AAB62B0BF5A7DF5B832BF1FC +:106AF0005C7F0FFAA93F0DCF89E3DFEF9BC559F803 +:106B0000DE7F87C032042C3FEB1AE1243DCC427C6F +:106B1000FD0529B01FDABB26B60591EFDDFA5CDC76 +:106B2000780463AE387630E2CFDA43D2AC215C9F92 +:106B30009271F635D6A02DD2B97D5BD3A3BACBCF57 +:106B40003D6D43BC5F7300F401A4CFE78400EA37D6 +:106B50006BDA9E7E3905C6BBED60D9049C476F7F1A +:106B6000DB731C0E512C642B0AD3ABCB32E31B8698 +:106B7000008F7C72C6BBCB1E842D95E1397D0BF84E +:106B8000D7F45FFB6A46E053A67D326B17E9E3A0BA +:106B90005FD950FEDF5AC7C7BB35B3BD219DF6553F +:106BA00090C0C2CEFFA91912F5D3FBC3BEA95FAD39 +:106BB000E3DE4743B05EB5D6CAA26E84B295FDE16E +:106BC00031841F8B95F7E33EACECDCCBF0BC5B1C57 +:106BD000C09AE0B9AB72ED7F50FB1ABB2CC2B3F682 +:106BE000D6EAA742309F22322F83FEFEEC4A1ACF0C +:106BF0006FE3F2A735E6C9876E817255B1D30DE810 +:106C00000DE55882CFE1BB2CC4E79359D7310B3C3B +:106C10000733A02200D04769BEE3C47718E7C777DF +:106C2000AF5302C88F61E502E2F9E72F7E3801D742 +:106C30007DE355A10B885752CD87BE9940FFEFCC1D +:106C400090B97E32363401DB0D3CAAF135EB099266 +:106C50008F5292128FFA4A10C7C2F5FDDD4278704A +:106C60005808EEC5797538456573FDEFEF6EDF7B2B +:106C7000B80E5590EE0C42FB0542AC1BF77B225E32 +:106C8000CC180FF4FCB9F487341CD70F682B0EE92D +:106C9000D163B3B5A5DB52A6EE40B8CC0080B2EB11 +:106CA000C196191BCFAC50BE8F59BAECB08EECAE6A +:106CB000DFEDAE81B2FCFD014C0451551B95CAB20B +:106CC000617CE1286C14F67374ECD115B8CEFBBA74 +:106CD0001C0CE1C41C463DD766490E7E0FF1B9324B +:106CE000D6CD92500EB565213F62B739DD4DD07ECD +:106CF000E9A550C6BFA35CFAFB71D2D347A5FBBE82 +:106D00009801FB4A11D5D33EA8BF4F0E0E7F00C796 +:106D1000AF8A71D77039C2C2D77F78FDDF6313A005 +:106D2000DFE75D23AD4F41BBCF55871B3458D6F10C +:106D3000DD312F5D07E5EB3579625ED7E7498A15CE +:106D4000ED8ECFBB1C41D4433E775A02028034FB08 +:106D5000F0B1770590DFD90E67508CC57ED227E160 +:106D6000F2869D1816F7C1181231EC4B80E7204DC2 +:106D70002EDD38C0683FA664733B28259BF31FAB0C +:106D8000E226389FF75B5913E2218332CE6B75C838 +:106D90004DB0BE9F3B1F5B0A94CFCEFF2D7D00CA36 +:106DA0008DF387870F6063FBE68B27519F003D6162 +:106DB000D178352D7B528F7C5DA8C125AAF9260993 +:106DC000E1510BF06802782C745A8276D8172B3672 +:106DD000C28155759522DE304BAC1BE906CF17CF2B +:106DE0005F112C5DECBADEE73DFD921CFC1E949712 +:106DF000C279225C4BCF7F70CD038CCEED1A5C073D +:106E00009C63FDB5ACE7FCFED5CE8B59DD8D780ECD +:106E1000778BAE663C875A2BD7F7FC805BFBE3A8E9 +:106E2000DB63782E77D78EA0731A540B7C02ED9417 +:106E30001A2BDB93887CA59DDAEFD7F4419659494C +:106E40007CA6B4D62E23FCBE888EA5FE0CCE554A59 +:106E500089C467385FA92A67C457968DAD14F0DCE2 +:106E6000937006D84F8725E4C27D86A2408B84E7C5 +:106E7000FAEC74A2F321C81186F373C6FE0FAF7744 +:106E8000ED417E233A863C7C0E44116BEC8A1D0D4D +:106E9000EB6A11581BED4BD2F8C76A27E9732D71C5 +:106EA00001E26F2D0B87BA71AF9F33ADBE229AF806 +:106EB000CB75160B95BB960C227BAC250E582B8EF2 +:106EC000B76434E90DCFFF8FC8EDB50CC6EBB3D86E +:106ED000C81D585F9049E3BDA0F3ABAD2E1AAFA516 +:106EE000404D8EA6FA4116EC5F9EE65B87F8912234 +:106EF000F276A07850BB9D3BD5643CCF9D85366A29 +:106F0000F703C1BB64258E738D93F4C6D092E82736 +:106F10001FE3C71944FF524715DFB74E0795533893 +:106F20003FBDCA7FFA21E41FFE6C381127CA8BCF00 +:106F300096225EAB62AC1B50B8D7397FD18DE7ACDF +:106F40000B80CB12A33BC85E573218021BCE4F6694 +:106F5000D98827C7009ED0DE2FC13927F273DE986B +:106F600088E73C7F77F839C378FEBBE1BDB036D601 +:106F70002D4CA573CEC4F1AB58B41BEDEBEEF3FB77 +:106F800079200B9FA2C59D6407583C9FEE7B307B08 +:106F9000608F1C79F83DD81FC0A5D41E9AD48CFAF6 +:106FA000B98555B445E0038F6673FB40665D12CA30 +:106FB000D7653AFE579BF03F3434EE83180DFFA19E +:106FC000DFE1C1DEDD780E9F0A2727E3CBE3FF2D4B +:106FD0002E8E34FEE39A7C792BD1FB235CDF08EB09 +:106FE000D1A1EB50DF586F27FD975D3A3614E7AD1E +:106FF0004EF3FE18C78B1AD16543FF54477297842E +:10700000FBEB58F2A761A8672DAB7A85E8F34AD766 +:10701000B731669C847233CE932585A0FF604FD62E +:107020002FF15CDAE7D9157B043FC891795386A12B +:107030003E74326FCA30E497278701C9933C75BB11 +:10704000908F4A07AF71E13A4F7A265059618A56BC +:107050002EEA97BF7E0CFC35088AC01FC15EC3E7CD +:107060008760AF0581DFBE0FF61A3ECF82BD86EF87 +:107070004F83BD86CFCE0D6E7A7FD233FC20E2C522 +:10708000C566EE4759617547D4CBD61C105950E7F9 +:107090006FF0EFDBFB620CE58A5D0986F22D2D8037 +:1070A000418E9E72F996E186B2AE7F2EAF1B637859 +:1070B000EFAB9E60286F8C2995F09CE28AD3387CD8 +:1070C0008BD308BEA7F2FA806FDE28826FFBC25115 +:1070D000C3107EED085FD48BAD8A0BE1271D5CEAFF +:1070E000423DA6BD78389501BE5B27E2789A1DD552 +:1070F0005EDC3F9CFF88701E85F07568F095099EE8 +:107100006735389F46388F42F866D2B31DE10CF5DB +:10711000B5C50067C0C78B7E941E805FD62E29A29E +:10712000FEBB4F34ECBF62578C09AE4638976F19DF +:1071300062282FAF1B6E28EB70F6551BE15CE499BB +:10714000606AC7D816907B45F80BE0F91B9366136D +:107150003F3D29B0CA0478C6C99C0F5ABD02F9DF69 +:10716000F0A719E47721FE02F463752AF5585F074A +:10717000EDBF0F6DD106463B8431B75406EF177A49 +:10718000A26494EB8B5825D1DB62D64CCF9B591B64 +:107190003D4BD8097A96324E8F9F978526E3F3F7B9 +:1071A00089BEF41CA0E7350EDFA38968BF0DF38DFF +:1071B0004A40BEE48C27FBB4AF73424D9B697CCA46 +:1071C0003959DB17FC14E3DAA15F7BCCB83BEF54F1 +:1071D0007AE6D1C787F9DC38DFA7129FE78D4953DC +:1071E0008621FE31EF40835DD5D77CDB347959E6CB +:1071F000E17042DF2D96CF2D14021BA17C649BDD34 +:10720000867E86739B254D6FBF97ECDDD3A7B87F35 +:10721000E65CFDEC54C4BF9A6DA35211DFCF494A1E +:107220007D15C0FFDC34E0E36EF2E7B8514E9CF10F +:10723000B8A83F488CD82C38B715DAFECE286EDBBC +:107240007A68BF3059647E68EFF3A7C5E2FAF57D2E +:107250009BD7BD7C8BDD80170BA61ACB0B99AD0796 +:107260004FD2F0BC6D3DF5A82F8925037CFDD8DFFA +:10727000557F58FDD64B6178F66F39AE44D46FD840 +:107280001436E54BB1A77F5FF0FD6243C55B2F4924 +:107290003DF0D5F16A528EB71CCF095EDB903F02FC +:1072A0005C2C28974F1EE470DC1673E3D6EB000EBF +:1072B00085EF888CC3B9D4FF7BC4E743DCBF6F9EE6 +:1072C00027A4D175A7C63FCBEADE263B6E597501D0 +:1072D000F19F4267D730F43F1DB907F80BF295795B +:1072E0009CBF1CCB1BF5F01D306E67BEE8B6033E9D +:1072F0001DC9BFB015CB27AB4519E7ED3C7841E37D +:10730000E35D6F4C81F57DE69188CF741EFCE7F05C +:10731000F3C2431A9F09707EBECAEA650D30EF2A98 +:10732000800BDAF3FF6CBE7E397EDE2E7973072286 +:10733000BC6A0437FAE16AF2ECA447B4037DD83999 +:107340003ED5DF81F2682AD8C132E29B7712DA9605 +:10735000270F0E1F88F0627EB53D73720FBEAFA877 +:107360005E958F7E76B6453A83FA373A45504E178A +:1073700032EB9950189EFA9E937ACA84D7D633A1DD +:1073800030BC36E3699B094F2FB24BA9B6745E7FC0 +:1073900062500FDFC39F70FE729B186C60693D786E +:1073A000FBD7BCB74B515900BEF202E2EB5DE3D311 +:1073B0005E0C09617CE50AF918E033C9BFD6981B59 +:1073C000B97EB190CBBF230B6F3AFA3B80DFC7F396 +:1073D000385E7F9CF753E21F1F839685F87A2A3F19 +:1073E0002116F1EF745D11D1994E3FE679DA357CC3 +:1073F000D3DB155A15C91D013F8B3C467CC9786EFD +:10740000E90094A77DAD5F1F576FA78F5B88718DD3 +:10741000B17D8FFB610EB74733F695F43B3E188282 +:107420003DF885FC8445F78C03E5233FB98961DC91 +:10743000F5643187CFC903A3881EDB8B75FDCA476E +:10744000F5A73C6200F5D893C513DE9888F4E39560 +:10745000484EF735EF396D5F67343DA053D303F4E1 +:107460007AF1C1858B96E0B81A5F38E5E1F8FB7ECA +:10747000CB42D23B603DE47FB2CDFC9F32F43F81F2 +:107480007DED42FED59E2F325C47615E11D9D585D8 +:10749000923230929E60DEB779BC233FB1935F0E8B +:1074A000C623BA2A9E57C41A705FC5DCFFDB8EED77 +:1074B00061BEE20779F918B69F688013F19176E012 +:1074C00023283AA4833790DEB4B2D9784E2B1A63BE +:1074D0004CF46EE417C50B399F6BCFCF191889DFB9 +:1074E0005DEEFCF4FE577AFE15D81FCAB8E62F49A8 +:1074F0004F89378C07169D69BE7453FD6853FD781C +:1075000043F972F8D8A9C991761D2FA294A5DE0877 +:10751000EB6F7FD25E119EAF317726B75FE6CED498 +:10752000E2F75F51AECE9A09FC2A86F592AB7DF563 +:10753000D7F9D3A81CEFBC99385FB048C27D5D294C +:107540003F0A93C30BA97F48B061FF6D9A9CAD6859 +:10755000E378D41A73FFCB88879F6AF6D091799C21 +:10756000DF7FA6F1FBCFFE532BFF440820DF3C76E4 +:10757000E8EE58D4DF3F3C382A16EDB1336DB5B193 +:107580005C4FF7C77E0BF0F313A0CB2698EEA3B6A3 +:107590007F8E9E5EFCB4660FFD88EBE9ABADCD91AE +:1075A000FDD4DFB09E6ED6CF73C592A3BF83757C2A +:1075B00018E07034EBEB1F2A4AAC4CF0E170F84C49 +:1075C0005262D1AF7726C0F97D5FF8A8C3E11CC233 +:1075D000218CDFF705C7B35A7FBD0CF621D92D45A5 +:1075E0000EF72F13D19FB0457063BC8A59199B0ABF +:1075F000E778A2386B6F53989E11972B12BE9CAE02 +:107600003B569A8CFC070C5DF4F7BE527D2C15FDA1 +:10761000AC650762883F9AE72DCF37F2994FEA0BA6 +:10762000B27F0FFD8ADE11030E84477E1CE75F4F99 +:107630008B0111CA9DD539B1E1FBF8D02477565999 +:107640002B239E63C52EE33916E5D7D038271F14A8 +:10765000DA8401F03C324D525CBDFB1559F9FE57FE +:107660001D10C9CFBBAAEECF6F607C7115F07B54A3 +:10767000135E69AC9D8F787DDA2B5910CF3BDB12FE +:10768000E6237CFCC5A23B03DA1F6F1C4E787EA666 +:10769000316710CEF7CB9922C9BB0F0FDA2DC2B5D7 +:1076A000F0F44A2C487E81209DE727754524AF3EA3 +:1076B00044B8903D2B135D9C98C9E30EA7611CACA8 +:1076C000B7009DA03EDC19103D8108F47162263F91 +:1076D0008FB3971E20FC7939702C16F58AD36D7CF8 +:1076E000FCB3D5722CC6A95EAF9BE0A2F5E5C3B88A +:1076F000A8F71EE272F4C33A8E8FB84EB20F1BB9D0 +:10770000FC3859B7E2FE69008F4FB788A4777EDA5C +:1077100058347F1A9EF71689CA39050B29CE713263 +:10772000C0E5D1A9C0D9523CBF0FEBE0F4A15C7316 +:10773000680AC9DD4FEA25C287F203C67359B82526 +:10774000C66CAFC66681DE558EBF29F83F7516DA66 +:1077500049CB93407E02E59ECE2F92D04F59E84F01 +:10776000308C63670512E21DEA97D86EF9C3459322 +:1077700082487F7E81E4DFB2E7009F603DD2BEEBAE +:1077800049DE9535DB0DF316561BEDA3E5267BC8C8 +:107790006C2F5D4E5E9CD6F054B73B4E4B95A59139 +:1077A000F212E45C4D2E307916C2FD0C18D64D59FC +:1077B00000CFE74415CB17EBA2887F962D3B7F8344 +:1077C000A697DE8878C0DC7E3655B7D3C3E86C79DF +:1077D0009D6892DB46F882FEFC01EAC78D099A1C7F +:1077E000F51791DF6E548E1A9F8BEBB852FBFB8A14 +:1077F000F5DB524DBF2D25FDF624EAB7B09F766C20 +:1078000012D61FF45DF2EF9C9A7713D95FA7BAFDE9 +:10781000675ECD7FC6F59453F9459A7FC7AD97074C +:10782000B07EF89CCE2FDED7CEE1ACC6274F6B7C66 +:10783000B253B3B71A347951A7C98B53F99ABD958E +:10784000C8485E58AD2ABB123E734B4B8C493E2450 +:1078500098ECA821A6F331CA8BED5EDF6C3C077B68 +:10786000D268C37B491E6FD4CFF71D263FF24585F2 +:10787000E7156D429CC0B8C9429EA7C51C6DE44780 +:107880005EE856A87E08C60BA13D9A54984FA2E325 +:10789000A7FE5E4EE4EFF5723CECBA06DBA5B551EF +:1078A000B9762163980F33421F07C051037AC21083 +:1078B000F467C33C4960A0617B1DDF87166FA37628 +:1078C000D9154C16A0DDEADC34C28724A6127F1934 +:1078D000B486A998F7C202CF52BBBDF7C23E00EFF3 +:1078E00043B5D3C92E2F72C4F2B837C8C7FEF1AC66 +:1078F00086C7773D09A4B70CB572D4EC136FB57683 +:1079000097C3DB303DE82EA20B66217FC4B6987189 +:1079100012E269A1D34B7E03C0EBA577A27EFFA242 +:107920008DFB0916723F707BDE9487D1DE1DF794C4 +:10793000937CCAED2B757F6517E1736775911FE521 +:10794000DEAF3D5CCE8D79EA130BE6BD751E646E2D +:107950002C1FAB7EF6FCAF486F17C81F74B23A8776 +:10796000F365C6BC98C779D293B391CA53C130CEE0 +:10797000427A50375A711D00D726AA5FB17512EAB4 +:107980003BC745C2DF242DDF48C6734DEE2927AA29 +:107990005A991DA472523ECF13FC99A61FB469E7F1 +:1079A000F9B8E6A7784CA39B168D6EBEAFD1CD6615 +:1079B000B3DF7917A79B9156F7D618288FF4BB48E9 +:1079C000CEBC957F96D60DF42F635C372D4F6C9A05 +:1079D00008701B630F119F2E02B1B711F63323BF3E +:1079E00086F2188B7C8CE21685C535B4BE10C6981D +:1079F000AE43BDA94610B57AE48F631282D4BED0DF +:107A0000C164EC5FE479FA08E6E32EF40168A03C77 +:107A1000B3B84620F894C178D0FE48F5761AEF54F2 +:107A2000055F47BB8BF73F59C6643F943398E7E83F +:107A30001D7C9D5E8C8B9EAA7EF608C1BB98C3FB05 +:107A4000BA8F2C067ACC0A461BE87AF4BE7843FD3E +:107A5000A81D2986F2406FBAA17D82C748EFD123C5 +:107A6000C61BEA4F7A8A2C2867753B4FF78B757ACD +:107A7000B8DC9DF194D382F058A4F90B1061D920A1 +:107A8000B4BA18F97D1B353D91350F6798C7B1F72A +:107A9000BB16CA13D85C5CEBC0FC878B6D563A2FC3 +:107AA0001897F8C8A9C3561AD7915627A01FF33EB6 +:107AB00080B318A6FF35EAF24D8B5FE07AAC61EB3C +:107AC000895718668E75B76FD1F069BBB60EE0DBCB +:107AD0003324B2C7399E24E4338B04FD071673396F +:107AE0006DA6CB36ADFFE35AFFC7347CECF4ECDD7A +:107AF000188D7059CC481FC915D76C8CC275E433EA +:107B0000A2C7B6E0D1E870FDF1677D8D533C2197A7 +:107B1000C6F1733E3A7A81501B85E7BA2BF4A7373A +:107B2000E1F9C2A70D1B6361BD4F08AC0D294AE7FF +:107B30009FBAFE7DDD678D543F7A3C986850FFC246 +:107B4000674DBCFD64A6A0BFEB679ADC69D4E8274B +:107B500063DF58F22F5EDC6123BBE7B1F9ABF6B40B +:107B6000C07A47CDBDE789E7105FE6DFF3BBE79456 +:107B70001E3DBF687E7207E6F18FDCE062C81FF42D +:107B80007933F67D924DEB96AD0CF1F4C7FB9F5F18 +:107B90008EE33DFE58B44585F17FBCC74AFCE5EA5B +:107BA000FB1EDEB383E48D492FF618EDFCC737B713 +:107BB0003E7110DF573DFBE8B9B07C9D93F3360D65 +:107BC00043BF69FB868A9699197DF3CF221BF3A1E7 +:107BD000FFC7F3C227CFBC0EF3FFC677F5F8703BA3 +:107BE00060D42CEEFF69DF50D53213ECD4D122CF14 +:107BF000576056FF4684C7E89F0E52507F0352B02D +:107C0000FA00969E39511615F6F79B807537F1816B +:107C1000399B33F03CB37F9C7FF4233CE7531ABE7F +:107C2000F7A18FE87EAAEEB2A410DCFD2F3AB87D52 +:107C3000A32AC3C83E762BC30AC3F4B9F67BF43833 +:107C40009EFB3DE4E3852531145FD6E32EA2E7CF0A +:107C5000F5C8E7974DAD9C24D3FA8DF1FC1484DF71 +:107C6000048CF7F2B8BDDF6F65941F045B433AB92B +:107C70005B1C4D7927EFAEBE8BE2F6FE1ABB9C91E2 +:107C8000487183A7B05C057CC73E91E2B901CA3751 +:107C90009EC5F3372E2CAE7DD8A6F40DFFBACB9C33 +:107CA0008FA49D8FF9FDCDDAB9D4E2B96418CEE581 +:107CB000A86F6284738975107EE9E722C636D2B94F +:107CC00030873313F33F067394C2FDBC8172A8E37F +:107CD000944872EC3725EB6AEE86F2F94B0318D222 +:107CE000851E57294DE279087424C0B724ADFF6082 +:107CF0004DEF463E867A77A91677E958CA28EEA254 +:107D00008F77B16A80CCC7BB8DF4E6D24AA07F944E +:107D100025313F27FDA27E38CF932875762DA5BC4F +:107D200055C1E2C6F8F960935EEF6795B4DEC1EF26 +:107D300088E4CFB7C46CA1FE83013C6216B6B211D1 +:107D400010A83D0A76305A31AF24055F28617A9633 +:107D500096B73BB8EAA75C3FCA819EC986F9842FD3 +:107D600069FDB5EF8BC807AAEC0AF23DCCD142BE43 +:107D70004DF04B433C6AA5FEF2B7998CF73998CA8F +:107D800094C4C9DC0F86F399D70FE371BD10F433A7 +:107D9000DCAF50CDE7DF3597DF07618799126EB70B +:107DA000B0F0F50C3794353F99B12C25D90C72EA17 +:107DB00037978A0654F6EBC733F6B728DEFEFDBECA +:107DC000156176577A4F7B3D5F4C87734A95FDB4BA +:107DD00010DB77BFED5EF5C02CC06727F366FF0AA6 +:107DE000E0E17B4724796789394EF0084571F874E2 +:107DF000EBB38BB9BE0BDA790DE55D83BCC3F3C37E +:107E00007CED9180EFCC6FCC17D0E7D5E34B1D1AFA +:107E10003F0EA58522FA058F69F4DBB9E173CA2B01 +:107E20002845FD167039B4F163C33D900105338ECA +:107E3000E1BACDF908BA5E8A7296F0D7CFE56C87C1 +:107E40007F02F19D8BCCD54CFABF99DF5819E57FA5 +:107E5000DC2D46BB9BC86F772FE58F54F9EDB21D23 +:107E60009EF3DC467FCC82A9467950A02698E48513 +:107E7000D1DFB5D06B8C138D68594FFCEB22EA4DE6 +:107E8000C4EFF87AAC5A7E9984F74C44B4D7FDF429 +:107E90003CAEF1E737353D330AF92BBC8FC1047393 +:107EA000C047170B517900A2FC704C6D5728EF3179 +:107EB00081A9541EC87C54D6F3219359809E7A9E82 +:107EC000CB3016A2F255A80F8948520A3D87A31D50 +:107ED000321CF53C7777BC87F22773D2285E50C0FE +:107EE000D4F7B05DFE844F49EEE5DFC4C80FCFFC88 +:107EF000F52B5428772CD4CA98098FF926B98C23EE +:107F0000A7BF96D7E7E9E5BA152AD6CFE0EDA5D900 +:107F10004D7BFD4EE25F5AFD265EDF5D6E583103FC +:107F2000CB9285CA715AFBC299AA6D36E62DCD66F1 +:107F30008407C11CD5317B604FB92C478D0E2FAF04 +:107F4000CB559DE1E567B3D5D8F07267B62A879720 +:107F500087E6AAF1BCCCFD4EEF48EA30B477E1E702 +:107F600047C2648E87F8F39AE44BC176EA0181E058 +:107F70006507BE8DF092981A44A60464E3C07C2283 +:107F8000E033B63BA19E8DB751DE9F25C699DA9F9F +:107F90003FD24C5F21891D443FDD02AB2F13F76DAB +:107FA000E67B82FF95BF633E0FD04336EAF9A16AB4 +:107FB000AE0784AAB93F40A713FDBD79BECBE13D12 +:107FC00053C3FCBCE93DE3F6B57E331E9FD0F4BD40 +:107FD000764DDF7B47F34B77EF37648DFBC0D143A2 +:107FE000DF7DF34F2BFB208C7FF6DEEFD9A51297B8 +:107FF0001F32CA8B8E28B638D2FDCABED6E7CC99BE +:1080000055309BECDBA132C51998CEF739BFE9C0DA +:108010005F810F8E19A0DBAF6E07C2218325CDC90A +:108020008479B77918E9AFB5338F1622FFB95802B2 +:10803000120CD675F68E7348714C788ADB13CDC35B +:1080400018ADD7952647A1BE54AFF14D3B8BCB1B46 +:1080500081EB1F6A25796B5E777D6C40C0B8624A00 +:10806000308AFB371259200AC649F1B83D94B7E26D +:1080700017650F964BD8FC4C282F6F11150F8C737A +:10808000ACA58895C3B8E55381CF51663ACFA78890 +:10809000D7F0788C9D51BE45EB4027C5ABEB368FB2 +:1080A0003AB212F966B2C832A0FDD8FAF11EF47BDA +:1080B000D63AE3E329E6A4ADA7D6E97E15EF63F847 +:1080C000650BBF4F22AB0ECC47DF7D87D583FC7C91 +:1080D000D8D31363C530F89FAD3B1F8579EE8FCAA7 +:1080E00016AA7FB43ADB718B13EF130655CA33908F +:1080F000CFA84E987727B4190CE3DD5F71A67924D9 +:10810000EB1B1F623D36039EC6B86D263FA8D16F9C +:108110002999F483E6D95AFC7B329B8CE77CED13DA +:108120009724D473973915F2A367370A949F123AAC +:10813000E24EC5733ABB7514F9CDEB1A45CD6FED20 +:1081400026BF7568184BC57B3665CD02E9C562DD73 +:108150009F6BB0DF55994A328E73D5C4AEE4707F01 +:10816000D9A3F7DC15857CB4AEC4A2F9B9198DA3E7 +:1081700028AA230DF6FF7E9DC0F3272459C0FBCC0F +:10818000AE07C5285C57A7C4FD144DC04FF19E6EC5 +:10819000D38CC27EE950FA1BAC33CC6EA94F4C8F06 +:1081A000C6797BF05725FFFAB9E609141FD9D39891 +:1081B0004DF920E671EEDBC0DAD03EA9DFE0A06722 +:1081C000AFFA546FAA1BFABFBF6D46030829F6FE2B +:1081D00091D549784F6865B39D4545C0E373DBA6EB +:1081E000D07C2BF13E33CEDB5C60433931BB6586FE +:1081F0000DE176DF06F5E9F079EE2CF0BD8C7C2FF1 +:10820000A6F969C213270BFA119EBFB8414D45FD6F +:10821000E25C068B982F796236D7335EBFC14BF78D +:108220004ADE1F16B9DD3BB3B9DF792E120BCA0F38 +:108230002B7B7315C0B90CE8A9065E9D6D9C108B55 +:10824000782BB135C4A47E5352E4477BEE02EAEDAD +:10825000C0CF1BEE59B4A31CDAD5DF3BF22D64CF9F +:10826000D7DAB8DECC7E2D125D805E5886F4F997A1 +:1082700062875C1BC67F517F540DF9825E86FA9D32 +:10828000D428066DC0CFA5C31FFC37DA3B88B76A78 +:10829000181ED3CF64CD2ED0F235922693364E3FA2 +:1082A000F5731605820CE32E2B1C789E663DBD17D8 +:1082B0009EF45A47D8F8A8E7CE646A54D83A802585 +:1082C00004C95FEEE3F376B7D3EAADC060BE0CD36A +:1082D000DFCDF5FA3E46ED30D2ABC3C3CF0BE0DBCA +:1082E0006FBCEEEA80B1DF480FA3731B2DAA473F96 +:1082F0004039DB2A527EF598561EFFBF3894919F75 +:10830000A8AFF174FE8B3FD6411A1C01AE0D8985D2 +:10831000749E7DF5B3054EA869E37AECC3AB938CEC +:10832000EBD2DB8DECDED73A16CDF5C136B4CFEC0F +:1083300001E07BE3F0794245F99DB9FB0EB9BF7DC1 +:108340009BF9D94A5669437D4D51427BEE43BED1DC +:10835000E222F983E83062325D5D24B983FDD430D6 +:10836000BEE77A706FD36858C7B95DDC1FDAB46DA9 +:10837000EF134FA0DCD915E3E671267E4EE3982E6D +:10838000FF78FECF2DACE74719A48D0FED3FD2E467 +:1083900029C350D5A09E78D50707967FF604FCFA2E +:1083A0003EAB9C8A7C4CDA5DE4B819CAE36C81244C +:1083B000E4A7B7ECB2F7AC0BFED95B8C65699FBD47 +:1083C000175E3A747C82F19A0E3DB16339CAA943B3 +:1083D0000E37A688237EF90D74124A2F007AEABC64 +:1083E000E73FE89E7EB47C7E29E5B957DBE97E97BE +:1083F00019BEFB6673BB9F69F736747A8A6A1EC51D +:10840000D0BF7846B39BCE6C013B15CA0DD536055F +:10841000BF6FD0E92E5093228C67ABB69DC67365B3 +:10842000E176627ACF3EF4F13BFDDC0FD900E30B3D +:1084300011FC7D971BEF4F5EB5C203F87FC1EBFDCA +:10844000B607D67F76CB0ADA6FD5C1EACE5FE1F9FF +:108450000EF2DD86F567B60C9F2CA023D2AAD0BD04 +:10846000BFBABA67489E344F857760CF37B759A3F4 +:1084700050FFF0D759287EDBDC96183D02E594D3F7 +:108480001231CE1AF070BED9234FBCB1E1FA50D3ED +:108490004CAE0F094F95DC9F0EF0AA3BC5F3147547 +:1084A000FD43D6F0648C5D26FE2CD7F13CB71E7DD3 +:1084B00088EBD51751AF467D6952B91C2E9FEA63F0 +:1084C000F9F730CA67BAFD781F33C7C9487E5C85A3 +:1084D0009716D06FE16481D969F8BD0C37C3FCDC15 +:1084E00078D07F14C0F8C12D5CDF89763ADD2AE2AE +:1084F000BBCAE9CA01FF213CA3335586F3584DFAA4 +:1085000085CDA43F88A6F24E8F519F50983B16E12F +:10851000ECDADA7F1E87EECF05BD89EE9BF919C034 +:108520001FF1D4E1A7F389054302ED0AA6AA4AE2A6 +:10853000A01EBD1FEFB571FF8A4CF122416D20BF17 +:10854000FDAE09DCBF91CC78DC2B45E5F6FCB8A983 +:108550007E2A83FD407128F673168D7C79BBD7F790 +:108560000CE24D9A1020FB2F7E2C1388ECBFA65EE8 +:10857000CEAAAE2CAEF4C3A3DCFF576B897647FAC4 +:108580009EC2A1B99C1EA38FC1DEA09D789383E2F9 +:1085900079B9E28146C4A79D132DE4D7DEC94EC840 +:1085A000C84F8E7B787ED125AFF7750FC565BD6945 +:1085B00008FF242B5854A0ECDA343FEEB03BD3A391 +:1085C00051D4BF9BFC3CC1C30FB0CB807FBBAB126F +:1085D000E333E1FD23551B09AECA40EE27D3EF9FDD +:1085E00027C8FC9E7F93F7BC1FEFF9FE702EBF07D4 +:1085F000145D609D930EE5ABAA4302D2DD26977B06 +:1086000031E273A3F20C9D475A9662417FD9102B39 +:108610007BD53E9EB127E3783D0A4AACFFC1D241EB +:10862000BBC3F3491ED0F6FD0321B2BEB27C2E9728 +:10863000271D87009003D03E669AFDFD7839D9CF7B +:10864000DD65801BF47FC0CFEDE73F7B1E2FF75B1E +:10865000C92ED2ECF7F672B2CF315E0AF573F2D6BC +:1086600095FBA1FC485AE47913F2397C1F794DDD62 +:108670001103F0F86B0D8F63F57DCEAA6001DE5219 +:108680003B90A5E23AEB5CB6C591BE27B3329FEFB3 +:10869000B723B18DE0C5409EC75E47F7E94DFA6A42 +:1086A00080F4E00B15E3FD536877958CE2FFC04F33 +:1086B000264DA6ABFEF4E39AC4E5A8596FD5F52B79 +:1086C0007DDEFB522B9351FF6C75A9C43F5A416F5D +:1086D000453C2BADE67A6BA9B5EB3DBC3F94729C53 +:1086E000E7BF084F8D6DC2EF1B00BC14C4BBD94E51 +:1086F0009521BF1963F7D23DA35ACC5F977BF457FE +:10870000260E3DE283F7D21091F4C418B98DF457C8 +:108710003693E7E5AAF01FF21B5D9F758EB51AF23E +:1087200077EDA6FC5EC994CF9B99A7E5C369FCC60B +:10873000356962BF7AD3CFC1DEC5751D067E83CF92 +:1087400020D8BDF83C0A76393E5F02BB1CFDDD2F08 +:108750006FC8A4E7AB1BDCF4FE571BA6D2737A6A82 +:1087600048427D9BFCCEE47C644181FC773A3E0527 +:1087700046648FC5FBC7BC7EE69C94FFF05F0FF597 +:10878000895A7BFF17849FDD65A6ACC4F6A549BC5A +:108790007C302F7525FA775E2B56B3F300CF065A3F +:1087A000BC65F85D07F65D3BC527CCFB3996A7CBCA +:1087B000EBC8F63AC34F1618FD35DEBC7EFC353FDC +:1087C00010F83A96CF5DB70FD731A0C0EA457C4D7F +:1087D0004D37C609F6E769F107ED99FAABCA878804 +:1087E0001E04A08789FDD14390213DEC74B11B91FB +:1087F0001E5A5747A6871BF2B95C6D75727B8FCDE9 +:10880000017A1802E512B3FD16A2FC8F0B557B8F7F +:10881000647C23F4A026A13CAD5B0DF214C6A93BF9 +:10882000B2FA5D92A3480FD07A30D203D247183DF6 +:10883000E077585AE3347A900302C681801E82782A +:108840005FB04EBBCF11460F02CAE16E7AA8F86640 +:10885000E9A129CF287FBF2A3DFCE28610E53174CB +:10886000A40592110E3B25EE3FFAAA74326C8E8D50 +:10887000FB8BAE7127217FA995383F9D3DF434F9DC +:10888000E1F21D6E11E58A47E178983B71027DFFA8 +:10889000E7CD3C1BFF5EC102750FE1FFA28FC8DF71 +:1088A0003AD0C2E9EBD86B7BCB112F87D5B717CC69 +:1088B00046BC582F92DEDB6B7FF334FC11F8FA4193 +:1088C000034A0E8FE7FD671EAF57D69FE4FC368E36 +:1088D000C919B09E24BF5CE8C1F8CCF516FABEC732 +:1088E0008082F6389493FA78CC5A998CF8852AA825 +:1088F000637C6F7A819F36699081DE7EDE1FBD5D6D +:108900008EBE676BF4053F9477EBD3EE2D7E55FF5B +:10891000699FFEBC6B22FB07B76872AE55E27918FF +:10892000D05AC67BFA4F797DBFCD23FFAB490F3BB1 +:108930002C07D15FC6D6C6927F37C9CAF5AE24854B +:10894000E78F0C617E82B31E07D3F53645E5793E8D +:10895000B905BEB338EE6EA61CC1EF1938DD6C3117 +:10896000C5B9407FC578F576AF7A8EE6FD9AFA589C +:108970004281FA497FF874FD22B50BC7EFAB7E4602 +:10898000C15F8E7D89718B6A9ECF6CADBE9DEE738B +:108990008960AF5830DEE969A3EF02C9B24D51C812 +:1089A000EE52E763DE62AC069F59E227A47FB7264A +:1089B00081FEEFEEF183EE4CE6714E113DDCA077C7 +:1089C000B61E77FB6F81796CC037FC788F3D1FF442 +:1089D0007428C7A09E8E634DE5FAB87EFF2566AC6D +:1089E000A6A7ABC638DCE5F4F4017334B9399E4D63 +:1089F00044F8A45A94EDD3E0FD8487724FE2F14C21 +:108A00007A7865028AB329BBEB8BF0FB57ABF7BFD3 +:108A1000BF1BFD92D37E6B6748A7AD87B89EA22E81 +:108A200060742FF90AF83CD1C90DF94F97FB472024 +:108A30007F898C77AF6B78D781789768C0BBCC394A +:108A40000323E29D1FF9F13F8077E3E718F12EDF62 +:108A5000847713E6FC6378771DAEFB138CFFC03878 +:108A6000EF2D546F98D30F1EA62E5467CCE9070F35 +:108A7000C3FCEE644F8D645551E1DF15D49F0D2882 +:108A8000E7FA89FBDB379F21B9595B95E340FDADE0 +:108A9000AEE4CC1B1847F84B955D09F713819E6730 +:108AA000D083615CE60703F6683ECF633EB6DE1E08 +:108AB0009C0EFD4A65EECF2F95DD0CF3A845679718 +:108AC000E4037EB52CC9C750BFB627597AFC12F013 +:108AD000EF5AE9843707E0DC097214CE984DBF677E +:108AE0007B22FA9B5E3B3495FC4E3A7D74C4F17157 +:108AF0006FE802F914D67FFADF406E85E1FB0C6067 +:108B0000E0E1E51C47B2A17DAE9C66A89F9D74B5CF +:108B1000A1DE3569DF4CC40BB14C8BEB6BF7CF7426 +:108B2000FD618C5D253C6BD5F4DB3C25CBD01FF57E +:108B30005CE47F5694EB503F37739A613E5DBE5FB5 +:108B40000FFF21DD8A26B96D96F356939CEFACBEDC +:108B5000108FFCBE618EF1BEDA666B289BF808E3CD +:108B6000796A575DFA05E17FA7C2F1BB4EE2F8EEE4 +:108B70009FAA7D67C5443FE36CDC6F56BBC4417E52 +:108B8000FBDA43DF7AD717E64F622CF01ADE671C58 +:108B9000171BAFA03F7E8895DBCFB2CAEDC0B1AE48 +:108BA000EFD3F86C35979F82CCBF37B90BF8027EB4 +:108BB0003F8B1D0E913DCFBE6BA3FB4EE3E6C7116D +:108BC000DEECACB0501ED60F856094301CE9562503 +:108BD00039C392985C47F9876FF3EF1432E6DE9C55 +:108BE0008CA6B44A79826CAAA3EB352D2F15ED948F +:108BF000280F736F9C867C90EF337E223F3FA79BAC +:108C000097E5EB7959B75FE3925833E6990EC1F1D6 +:108C1000A06D6215936BC94F10A4FAA11E76A2969F +:108C2000E6E7FD0797336F2394C54A55F3DFFAB49F +:108C3000787517C591D3057734F2EDE1A297E2C8B4 +:108C4000B14CA638730AABA4678C10E44CE36BF20A +:108C50008F6B010018AF67B136F2E766FFD8C9D055 +:108C6000EFD6EAB2EDA1FC9890427EB94DA7F8BDCF +:108C7000B6DAA577BD3109DA37BEC1F3F3370DF3A4 +:108C8000BF8B748D3889F742456725D50F7E5574A3 +:108C9000CF56F07D33C37BC4CB9C9600860AAEB51D +:108CA00075FD12F3EE58BC8DA13E5207FDCBA0BE60 +:108CB00073A905793143CDB4DBFF88F53778FDAF73 +:108CC000A39EFBDF03E81E3233F90D5B7D5C5F6E14 +:108CD0004DB4119DD7966427E1780D89D174DF6C6E +:108CE000F18D956F20FFA87D5B746F14781FF4A73A +:108CF00013EE613CDFE64D433DD4E6B4517E87D9A7 +:108D0000EF6763DEB726C1BEEAE26E49EA4F1FEAAB +:108D100033CE506209DA62AF3CCE507FEF4D14572C +:108D2000D0D7A9EFB3A1E4BCB45CC1DFFEC1384326 +:108D3000B51039CE10E2DFD3C8C0FA71081FEECFEC +:108D4000FEBA71861DF3BE5E9C41DFF73CEDF77CF9 +:108D5000406C2D5F82FCED746E969EF585C1711F8F +:108D6000AEAF147F53F87BF49F2FD0CA6F1C68FFFF +:108D700004FDE4C77F74F4003EA75F7AB4642DE07D +:108D800045C154EECF7FEB7B710FF2E18C7EF97918 +:108D90006EA3BF1C7F103F691D02BFE71E5E5F60B0 +:108DA0005A57B6D5E85F9FE934B69F9568ACF70C83 +:108DB0003596F5BC15F37E37C6DC4F79679BD63107 +:108DC000FA1E110B3F0FF1F265BBD21B4FC2FDE53E +:108DD000CC9D4674DFF90EA77BEF8B7F71915D9977 +:108DE0006491D10EBDB0B87ED3EB4A783CC0A322CB +:108DF0001E7DF193B16FA25F9BC9BE20E6F12DCF1E +:108E0000E1DF61EAE59FD7FCE3195547DA6686C5DD +:108E10004F9B06F96E9A0BFA4B4649A105F5878CD4 +:108E2000AA97A87ED19249FDE291AFEA98611CFC15 +:108E30009E1DDAB7BEAA97E97D5FFA8E45F1F37CF5 +:108E4000B86ABB42FE5FD3F76E7D98CF867C3E9DAD +:108E5000CB9B5A89CB273815265EC7485909DF971F +:108E600045E17CFDE2547E4F820117427EA58F676B +:108E7000968FBA1C70AA5C7FF4559BF2EF4CE36F9F +:108E8000F7FAEE990B7425381B789E5D8ED6EE307E +:108E9000D74BD91C26A35C867D46CCBBAC9BABD9FB +:108EA000997DE47B31DD0E2C7EF55DE4875FD90E84 +:108EB000EC63DCE9A9A1A591EE23EDCED3F4F1A8F2 +:108EC000D030E4C31D5264BDFDF6E2593BE6F6A383 +:108ED000D7629E6A78DE44AF7D7FCD3CD5DF7AB81D +:108EE000FF4B8F3FEAF9AACC1A188FDFCFCC74FE64 +:108EF000FA668A2BF691A7BAC9E50EA1BFAAB62CCD +:108F00008ABEF7F875FDD56734BFFB037319F78781 +:108F10009BFCF5E6751FD1FCD797BCDE20E24B5FCA +:108F20007E7ABDFDBBC991FD64C9F3F5FBF3DAFDA3 +:108F30001F0FD7FB54C9CD22D9057A7EA2F93DD89F +:108F400041EDB80EBD5C569F417EB65689E32DE5D6 +:108F5000740CE9C96775A2FE477A5433D5C75670B9 +:108F60007D50D7B3642D4E60A627A08FD3441F2514 +:108F70003CEED0A3276AF4B108E803E87228E37452 +:108F80006CD1F230873A784AF7D7D5A37ADB4D1EF9 +:108F900047A4BCD3CBDA4DF5931C643739C7BF8ADD +:108FA0007A556715BFBFD6E1EA7261DE8AFF6D911F +:108FB000BE67DB577FDD7E12E71BEDA76525DCCEA4 +:108FC0005956A2DB4F21C9E742BF30D84FE487F59D +:108FD000D9F307F6B6A3305F14CF09EC4C47FE3740 +:108FE000C11F4C7EA263985700EB3C32E23CF93F34 +:108FF000065771FFC7E02AEEFF4841FF471AFA37CC +:10900000B8BD56EBE6FE0CDD7EABD3F2BC747FC878 +:10901000551A1E8CB157727F88664FD51EEF22FB02 +:10902000C9A97DCF06E3758847B66A21802E4226FE +:109030005ECA453DD83E983E6FCA58B5D10F62CE44 +:1090400043769AFC1DE6BC816BF3353B4AF37F3CCB +:109050002228F74D83799EDD91FB3AA2ED7FEE5AEF +:109060001983FE8F9F06EAE76AFE8F87F0BEC5A1CF +:1090700077B9FFA3EE10F74BFB5081B92E12FEF526 +:109080008AFB90FF6365BE9FFC1FBA3F6999533B03 +:109090007727DF2FC297BEE7E9E165F4432804CFC5 +:1090A0004F7E8971C2BA6B782EB89D6511FCF4FBB6 +:1090B000AD3AFC772619E1ADFB9FC6D803AFE1FAC4 +:1090C0003B92AD6C23CA51F1138AD7889A1FFA9B41 +:1090D000F22BDD9C6FF42B8D7F68C276FC0EEFC403 +:1090E000878B4EE273F2EE750937C373EAFEED45E6 +:1090F000F864AF7238FE751EE75B98311DCEB796E7 +:10910000E729C44F7BE0CAFD4A3A3EF6F8E378BC53 +:10911000BBB482913FAE54ADA43B8C98E78DF8A3CD +:10912000C3A7D5849FB5C3783965666510EDDE0C9D +:1091300080A72AF7C6D7D6E36D6B89EFADB6297E37 +:1091400082DFA51AF4D3D9357BDF8C8F197EE3FD3E +:10915000E1CBE1638D096ECFEC98701FC2EBB95D76 +:1091600045AFE3F3F9C0BA1884D7C17DDBE7F60158 +:10917000B764431E3FC26D526F7C3C5EE06BCE878E +:10918000F7D3DD012BF1DB0A8CD961DEDBDA286352 +:109190005C45E7933F8AFA5A7C72F379BAD7585BF9 +:1091A0007D81FC4A7555FCBB101D2EB571E4C42BA6 +:1091B000E793D7CEE3F7D8753E99A2F99952E41018 +:1091C000D1E332A047CCFF5C56CDE30A78CC310026 +:1091D0000F31890563C87FE0207ADA89F9C3D7F6B1 +:1091E000E04F27B4B30F60BDE49399BF825C7C1E4F +:1091F000E1D5599D407ED93DDAF74555AB9BECC78B +:10920000D9C5DE8358AFC7A5B67BD543C487BFBEDB +:10921000BFF0487E98BFB0238E75FBD76A601F39B8 +:1092200055590CE34BA2DC2529E85FABDE2DA09C51 +:10923000583A87D349CAD04A9217BDFD6D5D396847 +:109240002F74E04DF12CC283B771DD1D557B090FE2 +:10925000AE5DCDFD241D55171222E3C1DF5C5FCF4B +:10926000CF389EF2837579B9B31B0F02AF4DF90A5F +:10927000F272FE3CA3BC4CD1E83EA5FAF443E89759 +:1092800016353C109DDC2F8DFC13F160701FFE47DE +:109290001D0FEA1056801775B239AEC8EFE55EA80B +:1092A000DE4B7FBEA5AFF55D3E2F548BAF633C9187 +:1092B000C7D7DF453CB556F17862C7FAD964275E57 +:1092C000A81664F437EFA9BE5DC0F39B5D1210428F +:1092D000CEF0797AE5833AE60DEC891FEAF1C2E334 +:1092E00005DE687C3F1D702A291EFD7F9A1F7D6860 +:1092F00064FF1FE077FC3CD43F0FCB244F743F3A10 +:109300009374FC561370BC71B6AE6132E1B72F098D +:10931000DB771EFA2FCA0BE8F113F23CB37FD8CFEC +:10932000556AF473ED5C6ADB43DFD763A15C8A8F17 +:10933000601C01F9F6363BE533960B0AE5FFFDB5F7 +:10934000C03796F6C1BC9467EA2B76C8E40F734D1C +:109350004E42FC286D10496EF7659FF4A6B3D3C446 +:109360005F5200AF347E437044391D158774271057 +:109370007F1181BFC4A01C44BA1B1BCE5F024B8867 +:10938000BF328B3B36F58AF84C0EC2B91F3E933B79 +:10939000CFC86766CDFB07E212C17CC6ED3A6DDF30 +:1093A000A87FD2BE357AEADE77099733A287EFBB72 +:1093B0005B2FD5F88C998ECCFBFA7F90AED6F54119 +:1093C000577722BCBF025DDD7319BABA17EBC3E849 +:1093D000AA96CEFF5F8FAE5AAF84AEC6CE63C6FCF0 +:1093E00063ED3BCA63BE63E1F98BFF97F38F13E72D +:1093F00072FBDC9C7F8CF92258CE87B3A1F3D1CAD3 +:10940000F3273205EFA7D977BFB465B4C2C70BF70E +:109410007B3293BF9399FC9B66FD2E823FD4E0FF85 +:109420003CFEC4EF8E8F865F7FFCE47F915EFBC6BF +:109430002C81E28FF3477D7118F5FD82CD6BB53C31 +:10944000F7FEFD9FFF6C7F27FE84FB57CDFBDA14F0 +:1094500073BF068FAFE6EF64EE1AFA7E7867257366 +:1094600013DC2FE3FFEC94471AF285BD2F963FB82B +:1094700010FD9FC7F977F8CC7E4F3D0FB8B5643922 +:10948000E9F96754875B8CE0F75C9EA0DC46FEDC64 +:10949000DE7ECFBF221DFCA37ECF657315C243B312 +:1094A000FFB318D8D5FC7EE2BE1D719502F2BB9CBD +:1094B0001237E5DBB14BEBE8EF39882521D2034BBE +:1094C000ABB81E38A0C0E7C2715286B27107D13E58 +:1094D000A912DC16A5375F063D33767E785EC93764 +:1094E000EC2FF867F9FB5E99FBD5EEA5BF82F09EE5 +:1094F000D4CFFD7425F430E6AD3D52E3A2EF563DE6 +:10950000A2E9D11D929A84DF397F2BEE030BF2EF93 +:10951000408B85E1BD31B35EDCF7FEB8FCEACBCF12 +:1095200024A17D34B6C73EAAEDF623B91DE17EA481 +:10953000FA0D9E43E722C049D78BB7CD37DA47A54E +:1095400025DC9E2D2D51C98F549AE861387E8A936F +:10955000B5A15C1493BA24D4539655F8C8BE37C746 +:10956000E1CD78628ECB9BE3F0E638FDFFAF71F979 +:10957000F5F38DDF651CA7E5A1206FC7EFE998E340 +:10958000F09BADDC4ED9A9C23BDCCC578CCB5F75D0 +:10959000E9011EE757B9BF3499713D2D259FFB4B5B +:1095A000CD7AC723526033DADD8FD458F4EF5618E2 +:1095B000E2FA635D3C3F7ADCFC05FB293F47D70BB1 +:1095C0002B402F14482FA4EF1C9556540A1CAFAA09 +:1095D0008EE03DD36532C7ABF9F339DD5887BA4920 +:1095E0000F16AB6F67FCDE959FDE97A6F2FB60D18E +:1095F0008867D054CCE4715FF984E8C6FB095BB19D +:10960000E934BC0FCAB81F679A85FEBE438B5099D8 +:109610008CFCF80141A627E84A748FF0C93875D050 +:1096200012F2DF58C86F7F2CB72109D7D758B32D56 +:1096300009F336DB34BFF8B6DC0FE8FB0EE2582640 +:10964000A39E02CF887FCFF39E0582F67781DA92C0 +:10965000E8FB02AC99F44931D3C6F8DFCF71075764 +:10966000201E9D73929EF08010E0F76E5C0EBADFB4 +:10967000D67CB52DB91CD6D3E4B291165177F5AC92 +:109680001369F0BE69A01C8B7180BAB474D94F7194 +:10969000EA865791BE9BD2D219E6CF37964CA67B6D +:1096A000748D9780B140CFDAD123DF9A04EF370B66 +:1096B00021FA0E8F7F9A85E2F02D57CF4A0EBFE731 +:1096C00028CA3653DC93EB95A262A17B73A216CF16 +:1096D000167BC5B38DF1E9AB1670BD4861CD8BE942 +:1096E0005EA5D326E37E4BAF1E4F79AF179D36CADA +:1096F000072A9518FF8EC6D58CCE2502BF337C571E +:109700004532AD6F3306A629FFF98155A887E31DC1 +:10971000409E9F5FC3CBDDF5DF5B85F8431FDB8198 +:10972000F2D937EF5A85F9F80AE37FF7A33693E7C2 +:109730004F96BA0A89FF964AA188DFCDBDDC7A141C +:109740001650B5F1D8FFE6789BAFB62DC67B44978F +:109750001BAFE75C02C4BFBFEAB87A3BF3B8E67E52 +:10976000FF5BEDFBDAA76581FEBD43467910A41AC5 +:109770006AF7C3503FB66AFCB0367B7220A8603EE1 +:10978000AF9FD3459C2562BE6CDFF411363E4FCEB1 +:10979000257E4BE3E3B75CAAF2826913F9FBC2A40E +:1097A0001EBAE9CEBFD0C683AA97514E6CD2F90536 +:1097B000560DEA19F7372513280F16EC0B25C11D96 +:1097C00081FEB43C0D6A9F46F7647F8B79E26C346E +:1097D000233EA2B7B76AF39AF336B66BF37ED5BCD5 +:1097E0008D73B88789246BC80EACFB6D33E52F31C0 +:1097F000FCB813FA67B364BA5F769F10A07B91FE42 +:10980000951CBEFA3944B1EE1FB27BF47C9848F93E +:109810003268BF25E9ADC3CF219DCE7204EAED9B2E +:10982000478DA3BF136965CD8F3F01CF1D0736FE5E +:1098300011F33EA2478CBB7FEA44BCC76E71E3F2D2 +:109840009CFFB6E36FA80A378C5DD98CC3ACD822D5 +:10985000A8E8D7B7CBCE3D681F318740768375FB2C +:1098600060E20B49E5C6736F15D45FE377F4FC5BE8 +:1098700005E2A3516EA35D611B6A6CBF4EA33BB3AF +:109880007DF2801039EEFDCC022E67AC686F84E962 +:109890000DDB2485BE0BBB6DB388914CB66DBD9DB1 +:1098A000F8D9CB6F15AEC2EF76DF592F11DC5B6FA5 +:1098B000B0D1DF8B6A75C98B16635993677A9CF9AF +:1098C000816B4606C2FFAED0D39A9C6DBEC146F2F4 +:1098D0008059BB92D02F6BBE6FDDCBBE32E1DDE590 +:1098E000F02C7741BC86DF01922BDD76FD280BBF83 +:1098F000573CCAF22F71AF786E373D7CB3F78AE7D9 +:10990000A2613EB027DFCFDA2BBF2795FC7BF5B3F2 +:109910006DF4FDB5AF6AEF6E5BBF8AE485FF76E656 +:10992000CE70F7CE0BF3BE3882F0476C14C90F2708 +:109930009AECD9FDF3A56EFEE308E3937A5ED07648 +:10994000ED9EEE766F03E5CFD479F83DDDA8E655C0 +:1099500064276F033D0CF3AA74BBF8CCD4F4C9029E +:10996000E5FDA87EFC4EC6996C2D2F48367E4789B2 +:1099700069F97DFA7CDBA6A6D37C756887F7830737 +:10998000568F766FD7345E37BF467B3BECEF6982EC +:10999000BD7D6E01C0FF7EA71B9D7050FF12D5B329 +:1099A00089F15774AFB2137F85761945EAC7384EEF +:1099B0005EC6243FDA7967D80086F038E772CF4276 +:1099C000B5BB43723BC2FFFE416DB3A47D8F02E67F +:1099D0001D4BF96D4B0B11EF4748C43FC4C42C7AA3 +:1099E0005FEEF25A2DB02EC19B6E884FE6B116EB9A +:1099F0005AB2AB023329FE5DCE648CB794B99A2972 +:109A0000CE928B0B8489672B33C8CEF31CE6DF59CB +:109A10009C1EF7FD449443FF0700378FAE00800083 +:109A2000000000001F8B080000000000000BAD3B91 +:109A30006B705BD599DFD5BDBA926C49BEB2652318 +:109A40001313AEED189CC43137217165089BEB47A9 +:109A5000880D29556CC749769C548140C3B4D36A9C +:109A60005BBA4D76682DC772E2386014D3D661CBED +:109A7000B622C0B6BB74C0A52FC8D08E1CB29467E6 +:109A8000715BDAC2B643454ABDA5D31FEE23E0EEB3 +:109A90006427FB7DDFB93796642571D28881C3B90D +:109AA000E79CEF9CF3BD1FC78DC78E54451B00205C +:109AB0006EFEB4BE092000E2B7DC3515695B0D30DF +:109AC000F89A6CECE32FDA643408A084641831004F +:109AD000A4A7D686325EEC7BA77F0D7E809B6600B6 +:109AE000DADD62ED19FC77DDAC1BDAEBE7FA2D0865 +:109AF00039BBDFE6AECC99BF5EABCE1997C134D28D +:109B000012C086D0D29C79BE35AB353A6FA7BE3233 +:109B1000E7FBADF5CD39EBA15D3999C1FE5AFCE704 +:109B20004C0DC1137D1EAF06F036603F6BBD025970 +:109B30007D1CAF8BF882D3C5D8F9107CE88C0CB0B3 +:109B4000118CAD10A45187F138E2A5E2983B53EC9B +:109B5000C0AE69EAC10AC4070DE9007D115CBC060C +:109B6000FBDE6907E0BC8711865C09D0A8651C9FF5 +:109B7000263C6B13127F0798184164871493E741C2 +:109B800008B404CE5B047149C3BE2F0449EA5F05E3 +:109B9000499E8FBFE483CD004BDC62BDBF0B8C07B9 +:109BA00070BCB8212E49D82FED004346785E634A39 +:109BB000A2736AB85E5E09500969EE5775C0D42079 +:109BC000C337F7D1FACA3DA00D5512D8388FA7FA7E +:109BD000204EE779040C70C9848F08402D800A312B +:109BE0006EAF06BD1491088F82B18AFA759021A4D8 +:109BF00022555312F5AF80098DFA006988ACC02652 +:109C0000A304A6DD3C05CEACC37FE957A0A59DA665 +:109C10006DBAE0E4AFDC667647107FBDDBD69444D6 +:109C2000BDE75EA7EC797EA2FDFAB9FE6804915FFC +:109C30004EDF37003450FB028F3F1589EC88E0F788 +:109C40004684EF5E75F1F86F54053E131218719C4F +:109C50009F78F696D04E1C8F3FEB36EA80F08BF85B +:109C600024BE08BB675E6A16EB891E41A407E1BBF0 +:109C7000B40124C2C1554407FCAE221D0E321D930F +:109C80000C77710C8C016B5FEA57221D882E29D04E +:109C90008A08AF72ECE2E8C03F8473C533EE4746F2 +:109CA00024C22ED2A5F6B2D0653FE1F162E9924F0F +:109CB0000FB8B70CA0F97CFBC6998E5F91D21EA994 +:109CC00096C882F4C1FB48481FC26708043D54008F +:109CD00083F05408FFD4F7AC067D1FF7C57CA2675C +:109CE000BC798EFF4B90FF455FC85700E920FA8290 +:109CF0004E419217EC872213BCBE741744EEAF247A +:109D00007A988C3C2744B975C18C446D8D6430BD04 +:109D10006AE58883FAC5525A20192949FAC00F1AF0 +:109D2000D3E74A88711B74CE4C9EC17D125E472AD0 +:109D30005E4DEDD32DB4CFE046D43028B70DBEB183 +:109D400016E6CBBB41AB43BE5BAC9AEE6AE29765CD +:109D50008A11D7B3F1B58FE1836E1E29A671870FE3 +:109D60004656CFED9B701AA124D2EB75DFF4F12893 +:109D70007E2FAA94C165CCE1F9A453DC8F60CA8B15 +:109D8000481E847C84C27896C07CFD165204DF7A1B +:109D90007723FE101F3B6800F1240D7F9FBF3FDC3F +:109DA00026F4DD8391E8EB24C7A49F187F2668A4DE +:109DB0009F3403586F3AF4F8EF64FC7E6AD8A51319 +:109DC0009F4272DC74E33E3BAD7D760EBBDE91FCC0 +:109DD00059F74CB8206DEBE71A5A1F29617E3624DB +:109DE00070372D7CDDA5F23FEC292766BB20DFB65E +:109DF0003CB5B624D370EE792AC94759F63A4127C3 +:109E00003588FCE4A5F11778FC42709C7B2673E44E +:109E1000CC86E30C45188E73CF09216F64B7909EF2 +:109E200077A1DD1A417C7FD4D454C19733FF45F626 +:109E3000FCF698DF207BCE28C2797724A5D408F2DF +:109E4000E39D1053894F25581227FAED884BC60819 +:109E50004EA939B8CBCFFE02B46B841F297DA37CF9 +:109E600066F945E0D1C2D38EF47B4EDD4778F5C16B +:109E70006FEDF19AB9F1BFF4D5BEBE4627A5EDADA1 +:109E800027FA165BF445B51D7F05CFE93C5D02233B +:109E90001A727FF1175E5B87E71BFA996CC8D5349D +:109EA0004F0513E11581B0E3C524A7B5C42F13E90D +:109EB0008F13BFED29D1E8BEF63CB0E6C5216AD2CA +:109EC0003D8B510F105C47F17DCC9FC57E55979916 +:109ED000F951E364DFC38D7C57C1A8E65FB99A4EA0 +:109EE000937C95B7BA8D815CF8D2195A8F30A1C294 +:109EF000BA87347FFF15D477F350CB196B3FD39DCE +:109F0000B55F5EDF19CAEA83188F67CF3754486799 +:109F1000E1F5ACBC5872669FDBEB5573E5256F9D90 +:109F20004D8F06A7E08F4008520378DEE1E1D2961C +:109F300062EC8F064077E1D0FE1B2A2440B96ED533 +:109F4000C43C7F15A45C12EDA38FD4B3DFE865FE9B +:109F5000F1FFDE4C7F9CF831ECD274C453E08FC625 +:109F60009489FD3B436EC3C4F1419A4FF6B50AFD97 +:109F70002C9DB7FF05F9A57758E7BD82708372F86D +:109F8000B14DC2CF927DABF7BF82F00F5C29834CFD +:109F90007BCB1B0DE2CF3B1480B252ECDFE764BFFA +:109FA0000FFD3BBE8F5A95EBF7DD79C439E717C239 +:109FB0007C3FF0AE4DB97E606C13F0BE749EB2551E +:109FC0007F3F7CE80BB2FE5CA14C39B40276D5C66B +:109FD000BFF49497F1FA8372C42BAD8388F929EC0E +:109FE000BB108FC4AFA8A8FD6B104F84439213DF42 +:109FF0009AEF7C9AE6BB4E21FFD27CD9DBFE29DCAE +:10A00000CAB908F1C4FADFC9E730F11F3A77BE3F99 +:10A01000ECCA3BA733CF7F962D3A8C107E50FEA121 +:10A02000099A083FE89FB37F00DE60413BFF5C3F39 +:10A030006A0EE4A51FF6BBB94DF76BDC1EEF0F717E +:10A040007BA25F877674AC5EE8AFE7F6C57E83BF20 +:10A05000BFDC1FE6D6C6C7B9F48DAFDCC1FEC2E1D6 +:10A060007B1D291226A5417BE95AC4C3956FC8AC54 +:10A070003EFCA07B14D4077EC48182F3AEEE505226 +:10A0800026DDC58A7FAEB0F86CB96B66D245FC5D43 +:10A0900009C63E5A08B1813B56CFC53F37CD38E699 +:10A0A000E40428DE299AB33340F14E594EBFCDBDAA +:10A0B0002867FE7AAD3667DCA6EFD79A85DC6C0898 +:10A0C0002DCF997FB8BD35FD313CAFBFD9A5119FCC +:10A0D00077EAD7E78CDF5A7F630E3C5B0E4AFB942E +:10A0E0001CFEF3E7D155DD7DFE38C8A6F38F6C3A30 +:10A0F0005B72702EFAE6F3AD8DD7D2B37815716529 +:10A1000082E24A9DEEDD20ED0C129E6DBFC4848874 +:10A110008FF480D85709637CD978F9E34B3FC59712 +:10A12000D585E2CB7735E2DF0BC6971DB9F1653EE9 +:10A130005E2F145FFE691E3E4B1784CF1D8B63AFED +:10A14000ADA178EF5599FD40B923C6F6AF6C4A36FC +:10A150003620DC72CB1FF391CCE3BC1D6B54F62F81 +:10A160000F43264476FF0109B18AFC5FD660549202 +:10A17000BE793260566CA338BFD3611CC525CFB7FA +:10A180007C39447EC7C1814742689420D8E5607D10 +:10A19000976C99DE4E72A5E8E8C749DC9AA902FEE1 +:10A1A000893DFFB3434E8E431ED8AEA6249CFF804C +:10A1B0004FEBDD4A7D6B1F4408DBDBF135D7A4C8CC +:10A1C000FF2BEFD205BF403C44F47F707B53251B2F +:10A1D0002905FB2B68BAC1767CC46798248789DF80 +:10A1E00079218E9FEE9734BF44FEEB7687F638DEFA +:10A1F00073BC63D55BBBB07FD0AB1A24F0894053EE +:10A2000025F197BC03DD1EEC8F758CBDC8725CE731 +:10A21000E07E62FB35AF93FB3C5EAE75D6509CB7DB +:10A22000BE86300DF233A7FB29AF91084C8768FD3D +:10A23000E00D62FDB9E8236B59F61C387FC1E79544 +:10A240009738D22AC2919F9BFE3F822767DB71D647 +:10A25000E3B97EC54840A52001CCAE2BFF23BE84C8 +:10A2600054B969121DC751E6094F3BB67795503C6A +:10A27000B5C399292F642F8650BFA6AFCDF237837F +:10A28000B97E423E7CFE35117EF1E7105DBDC20A0B +:10A290005DF097B8EDE6549AF006C98E1AB2CB5E1F +:10A2A000B4CB709EF8CF9B8B071B3EC3C3FFC87B0C +:10A2B0003CA6270B0F78AD34F93BBD5D12F3CD966C +:10A2C000B37C001C77D8E7523A1CBCCED60FC8C767 +:10A2D0005B27883F2CBC87D064901CDAE7885AF053 +:10A2E00076CEC103AD22EB1C6B550B9EC171F1758F +:10A2F000AA902BF885CC7EC73C3A59FE1BAFAF9E87 +:10A300001B57ACF35F7B44CDD1BF9FA1FD71DF5FD5 +:10A31000F6759F375E5E9ACA5D77B80BF8DCCB6442 +:10A32000F3F834C5B5D73A528F23A8E5D73A589EEB +:10A330004FA15F4576ED5CF06CFAB388553077A19C +:10A34000D38EFE59B08BF9FC5CEBD4D49459DD4824 +:10A35000FB426C02F96B6928F75CF6BCC367EFF54A +:10A360001928A2F3A0434EF6C8954A9BA4A75D08FE +:10A3700047C2B6FE917BB4F3DDDB0559F0119FEFC8 +:10A380004A425FC503C0F74DBC9562F98167667E9E +:10A390004BF29D585AA18FB0BC40684913F923E293 +:10A3A0005ECE3C3A8D78049CB195C24F1DB3FAF154 +:10A3B00015022E64CB29AEF7587995AF77D5F2BD4B +:10A3C00054D2334464C55C4C7CE155BE15D7901F14 +:10A3D0008ABC872180AD2BB8334EEDBAC5FA681818 +:10A3E000CF35B6D4C1766CCC177D6488F4D0526F6B +:10A3F00041F9F81EE945843F4C7CCBF113980E924D +:10A400003BC91612883A905EE3CCF9002F750544DB +:10A410003E4B4B866F473C1EB7F802EFC3EBF3E1B0 +:10A420009F980FFF31E2D784059CE0EC44382F5B06 +:10A43000720164502AACB80FF773EBC930F90BAF57 +:10A440007469425E949506DD7F2C5078BF57ACFD51 +:10A450004C474CA27957F489F5E016EB1E9066B68E +:10A460009E14F46479A2FD69BCD8C8D50FF9703D7B +:10A47000F5B9FA4AADCA9DFF96C57FF9F1D0FD52F4 +:10A48000E173FEAF75DF758B81ED11F1C5BE027C06 +:10A49000912FEF2AE53F11EE7B4407C697D03B5E34 +:10A4A00065AA95E21E6F0318ECA328937CDF7DC597 +:10A4B000B7719C3C74ABC873A88AD0DB555B110C98 +:10A4C000DAE3C80FDAE3D497EF01CD15988F878BC5 +:10A4D0008DF7C8DEC4B3D69F26FE2817F78867DD40 +:10A4E00023E9D46FA37D930765203F20B9D7B5B585 +:10A4F00090DD862EE7593DE9B6F52ED20D8C6A70B7 +:10A50000E0FA236FC89C173812DECF717122A2EADD +:10A510005235E5291E86BD38FE17D3C17EEB9E67F6 +:10A52000EEFDCDCBB8EC647B4D93E46039823B719A +:10A53000FE498C8BC96F26F9CBC9C72062DD4D73EC +:10A54000FB25DB6B78BF04EE279D47CF29118C5B81 +:10A550001BE7C33B6B8FF3F223231551BD1BEF7732 +:10A56000D86B703E52B6F3233DC105E5757448A61D +:10A57000F7905EE903C683AF730CF6523E2124E2E6 +:10A580008CE36B5C82BFF64A567C06ED60EB29FCDF +:10A590006DECD31F2A23FBF2A60BEA70BCF589579A +:10A5A00015EA8F553A9A287EBE4ECD1CBA8EC69BB0 +:10A5B0009CAC3F5A9092E91CFE48BB1C213E8F6A1E +:10A5C000B5B268D312B56DEEE21C7DBD5ECB8D3F9A +:10A5D00046678FCB25C49F1A1812E279B4C5304B59 +:10A5E00048F7189941FA3EBA5E374674F28773E32A +:10A5F00094D14E55E8D36A6177C626F587C8BF3A2D +:10A60000B0C7C3FEE7FD550E71EF2590227EE8D45A +:10A6100073E39AB1899A834B48CE924ECE977F735B +:10A6200042CCDF35B0324571A966F9ABBB2A5BD9A4 +:10A630000F852131EFD6FAE579F79FD2882F927BEB +:10A640009D40F83F5075FB30E543DF4938AF277137 +:10A65000F96EB7CE726AD36DE7D09D5C271A52614E +:10A660001B9D7F74BBCAFC3F5AFECE913B484F975F +:10A6700017319EC7B7AB95D12C7978AFDBC570C6C3 +:10A68000B70BFFA2DC01D18902E3EF750BBDF2E14C +:10A69000BB81EF43F90E1D3FE94A2CED227C5401AA +:10A6A000FC2B5D27F4EE97F8FE1D0EA8C3238E0544 +:10A6B000FBD87FCBE7B30FBAEB72CEEF0A3B72F059 +:10A6C000E87445629CE7BE1574D257ED1DD8A7F813 +:10A6D000BE4F05E23757E81EBE6729F63DD87777AB +:10A6E00024E30AF6DD4BA2D793DFFAFCDE2DC32D5F +:10A6F00041B25F0E8DF8CDD57757A49BE6AF768239 +:10A7000007C78740974274CEB804A4AF7588769087 +:10A71000BF3E16726894B7D998D8BC9BF6DF182C48 +:10A7200002A2F38E4E07EF77CA543969554E8E0652 +:10A73000E5BF2ABC6C77DF76C61EDA82F3DF467A85 +:10A74000C561EE5E8F76D7F03D3D7A6EFCEC8624D7 +:10A75000DBE1B5E6541FEDB336AC5245038E374FFF +:10A760001F217F7D7C8DCB70E1B9C69B25C6F7FB91 +:10A770006B9C293C2AFC509D9269DF1FBE8FBC5107 +:10A780005D487ECF2F37F9F347C35D6EE287FD301A +:10A79000D543F889CF8A3C54FEBC253D82FEFB118F +:10A7A0002F84E7389EB78EE2A219942B841E988DD1 +:10A7B0007C837244DBBA15D61F9FAD74C4A92E7476 +:10A7C000A053653939E08B0E57531FF99DE3A16003 +:10A7D00094F979AC32C87268EF33D6DC5B4FFCF287 +:10A7E000DA1A0FFBED7D3FFBD5DDE4B7B7CA7FFC7E +:10A7F000F653143F55A94CCF03CE48FA65E2EB4E11 +:10A80000E12F9EB8EA9F59EE86FA6E07C21BC46319 +:10A810006F52DD6A687533C3B7F30D6357897CD215 +:10A8200050F0D3F15DD84F87457EC12C3F2A01EB14 +:10A830006791576AB1F4D87257ECA53A5A77B722A4 +:10A84000EAC2725582F4816B91C8BF998A3327EEB0 +:10A85000BD6926370EBE322F0ECECF33817B6A49BB +:10A8600037DAD39F775B79372BAF445760395EED8A +:10A87000E278713C2CE2A0A43356A935CC97E31FB3 +:10A880005B7EF054BF1B3900E0A7FD1AF7FDE69F81 +:10A8900006CA10D41BFD21FEFE91B58F48D9EB46A8 +:10A8A000576F76EBAC373221829BAF2FF2F9E08EF7 +:10A8B000EE22E6038CD380E83B3A038C5F5FF3AA79 +:10A8C00034F1E9A9BF02C7A1FFD03EE5859AF9EBB3 +:10A8D000D3744E17E5BFC4394FD0395D94FF12E7EA +:10A8E0007BB15FE7F6E5FE7A6E57F680C8F3DBFAD8 +:10A8F000E06AD40788B7F62AD127F9273B5C1ABC4F +:10A900003D42FCE50A291AC9B7BB2A9996B2F4C19F +:10A91000B82FF616D9E503E55EE6BFFC73057A1C91 +:10A92000D6BD62DB08EE28C225BC3FBFF77FBE5410 +:10A930004BFBBC21335F95F6F5EE66BD837AC1C350 +:10A94000FE86D087C9722FE71DC6F7D64921ECEFE6 +:10A9500018108EEE05E51EF749E1BAE3A8AFA97F0E +:10A9600000E59CEE73A0F99D8FD33EEFFFAD882AE2 +:10A970007C48EF5FB0DCBF860148D965947B5BCE35 +:10A98000BEDFFDA4157F47B63C23EECF7A70DC37DF +:10A9900095A4FB1FF8B90C85F076A9740573617E48 +:10A9A000484A99993C132C50373445DD7070E23B8E +:10A9B000DC8F6F04A8C3FE579DA69BF8E0AB038E07 +:10A9C000F3D60DBF3A70FEBA61EA8B0E706973E779 +:10A9D000580419CEB352084F75C0211AC2B6A92720 +:10A9E0007A5B0FFBCBA2AEA83753CE81FA5A11F98E +:10A9F000CF4F45CC8FF4909F1914F9AE9032912629 +:10AA0000BB1EA27AB94EEF17E25CF7D4280C5B3973 +:10AA1000FFFE83CE4C2BDF0FA750BD32BF3E2979FE +:10AA2000BF27EAFBB5A20E69D7271BD5CCD143843B +:10AA3000A76D6EC6C3E0B337BC49F52FBB8E1FB2FE +:10AA4000EAC0DA6ED006C43D3EC6E77C4ED443E190 +:10AA500006BCC74ADA2453B36905D7373F41E31729 +:10AA60003AFF42EB861B2DFD86CC9D2279FE8D851B +:10AA70004F7BDE80258FD7A9226F0D7E95F57CEB6D +:10AA8000135E90C95FF6A947494E7642663DC9D329 +:10AA90006040F86D89C34EF6DBF6F5E8BCBE5C3568 +:10AAA000F9FD42F9BF788C01049398D4FC9447AA2D +:10AAB000EB36F7F5F039923D5D748E6199F5DDDB8B +:10AAC00075EBE3C41F9D5209CBA3A2998BB3F5E5A7 +:10AAD000A33D3539F9F84EF8A242EF5CD62D9EE938 +:10AAE000E2FD7D0EA0782BE1315ED409DF3F5018E6 +:10AAF0006E27A4DAF9BEBB346918EF39E83DC9F412 +:10AB00005957E75A49FAE951CBBE267C85E3BA7F0B +:10AB1000EB11F1E7FA4DD187E9DCB7C04C1BE937FF +:10AB2000146D23CEEF5A445EE751D29722AEB9D7C7 +:10AB3000D13497D77AC9197D94D699DF14FE842B26 +:10AB400024FC7A279869C2D7AB9BCCC7888F371271 +:10AB50009FAF6645058FAF9C7F8E27AC73F4F69848 +:10AB6000FF49F08E59FAB95133B9EEDA080E633065 +:10AB7000985557D717565797B4EF897AFA8D828F21 +:10AB8000E1B9B8E0C356D0489E90FF8ED1F9ECF7FA +:10AB9000258DC7765773DDE512EBDBEF6F328F1330 +:10ABA000BC3F442227E81E6FEFDD020C6F81EF35BA +:10ABB000D62DCE8422642F3DC26F7EB2C5D81AC96D +:10ABC000CAFF9CB2F8F79445D7E5C84E53942F506E +:10ABD0000CB6E3D740D84DFA211F7EA21F26A8EE5F +:10ABE00073AEFD9D074FBA294F3C186E75D37BB4E9 +:10ABF00084B7B584FAA3556688F61FEAEF78F6DDC8 +:10AC00003AE223C1F7F166918FD88FFA39EE9A8331 +:10AC1000F3871E99CFD5168634E5D3FD5EE117F98B +:10AC2000315ED4918FFCC130DB73FC3E41A9833F80 +:10AC3000933C51BC1D32C0A478321C05920BBF3628 +:10AC4000B79E4C5E5B380374AE73C191AB70BD9719 +:10AC5000D6C718DFE59B353E872BE4988BE361E18F +:10AC6000F8DA4FF8AA3B4FDE8DF0D5706E7C9DC5AB +:10AC7000BB2577F978F26D96F9DECF07A6F95E70FD +:10AC8000BA8DF3227E547854CF2FDB2CF48CEC3524 +:10AC900021EAA37A5994EF970864C06898C32FFA01 +:10ACA0008A8C5F59CBF03A7FD880E80AC2478CF192 +:10ACB000997FFFC663DF6827BCBDB453E8D5758AAA +:10ACC000A53F627817E4CF7FB2F41B5876A9D3234F +:10ACD000ECCE46F88957E4B5059F36A23BEE2E9D93 +:10ACE000AF5FEDF6492BAF9CFFFDE79B3D220FA028 +:10ACF0004FB07E1FEC10F07D3EE1871E1D5EC5FE4D +:10AD0000C3CD957545D9FAF172D709F3EB8217AA2D +:10AD100003CEF18DC974FF8B7632BE493F377F1C5D +:10AD2000B2E46DA8DF5D50EE0E2D8E840C92AB6602 +:10AD3000330E48B7FD814C88F86768F23DF693956D +:10AD4000576583FC4D458900CDBBB93CC3F4DF108A +:10AD50003681EA4A87FACD6F65C3FDECA668F766CF +:10AD60007A27A44D9804C70BE938D9A35BCACC58FD +:10AD7000A4001D3EBA59E4FF5EDD14D9B699F40E65 +:10AD8000E9CE55E86B45CC7FA4FE42F5D57C79EA47 +:10AD90007093BDB87479EA72D3FD46AB22FC4E6B5A +:10ADA000F42732795873FEA5254FA3CDD3AC276C79 +:10ADB000B9FADCE63CBD13B4F44ED064B9F8FC66D5 +:10ADC000DDCA0347583E9C244FD97A2668EB199375 +:10ADD000E55109DAF264C91FC9137EBFCE39D346E3 +:10ADE0007ECA1088778CF9F235BE299A203A5C57D2 +:10ADF000FEE7EE6A7DEEFDA7AE0B791AADB2F8BDA7 +:10AE0000F969E6FF53C8FFF45878D05B93C3EF7637 +:10AE1000BB7656863492E2A65989DB7F982DE6767A +:10AE2000DDAC875B73B68CDB96D900B7ADB38BB85E +:10AE30006D9BADE4B67D16F9FE7AE4FFD96A6E6FBC +:10AE40009E5DCEED86D9A5DC76CC5ECFF33A675712 +:10AE5000727BCBEC8DDCDE3ADB2CF6A19A5069419B +:10AE6000FEA772D665E07F234EF5D1A1C9BBDF24D2 +:10AE7000FC383595F328894013D77B9C4A86F9FF27 +:10AE80006858D8870D5E419F7CFE7F7553F4DB8543 +:10AE9000F87FD009CF90CB95EF27A0BFF32CF1B965 +:10AEA000E47DE16F9CFF740A3F07FD8F63CCFF9741 +:10AEB00068FFCFFA9515B97EE56879AE5F39D46C35 +:10AEC000FB95AE14D5C176493ABF137B7F53F4C7C7 +:10AED0009B59FF4676D278B4C7AD913F9508DC1CEC +:10AEE000F2627FC77E1928DF87FEC514CF43FD407D +:10AEF0007663A1F29AB6DEF7DAF31BE1A4237611AA +:10AF0000FEC9DBF4BFCD85E4BEDE734976D4D92615 +:10AF1000E45E13729FA88A0C53BE259127F7B61DD5 +:10AF2000453CE4C8FDFBB6DC5B725C1A14EF3E4A9C +:10AF300049EE919EA7CFCA7DAE1D55ACF9CE0E51FC +:10AF4000DF6A0B0ABDAA74087DA168B97614F905F9 +:10AF50007A0BF8137145F04D67DD77CFDA33B2AB7A +:10AF6000A5C18054825B6B7FCDC489FD26955A961E +:10AF7000EF7C394A68AB98CF2795362824FF0B968B +:10AF8000A3806D474CB623F9F36C791A9AEC64BC34 +:10AF9000D8766512EF6D66D9930D9AC003DA93AB3C +:10AFA0007A0BC8D3BAC5663452E09C2B7A85FFFE73 +:10AFB000CA4D11E12FA29F487E4AC259D80F58D1DD +:10AFC0002BE856DA9154086FEB758895A11EECE8D2 +:10AFD00048B7510D03E579452FC2BBC9CC0C920C83 +:10AFE0000E7AC782747E94CF463AD7A5CA67D9260F +:10AFF000AB2EB7A78CFD16BBBD10DFDBFE8ECDFFE1 +:10B00000F9F39EAC36B716C2CB915EE1AF1F1D7E41 +:10B010003A873F924AED2D865E50AF9AC665D1AB16 +:10B020000BF32B26D1CEB15E3DB75FB183E8B050B4 +:10B03000BFE2CEDEB37EC52EA2D3BA06E1571CE92D +:10B0400085CBEB2FB4D8F1CAA5F90B9FEF3DBFBF5D +:10B0500030D8ABF3B8827E35E90DBFA5372ED65F69 +:10B0600028E01F1CECE5387A46A6FA1FA2DA10F990 +:10B07000105117453D733FE10DE378F6178E7A05C1 +:10B08000BF988A6D9F220FD078D214FEC2E592033A +:10B09000F4FB1EEA2D5FB83C2C745EDD636B8733D6 +:10B0A000E4E7802F49EFA607E9BD12C58FBFF689F7 +:10B0B000770400F594F7FF9CBCCC203B375EFC8501 +:10B0C000AFD1FC3D7105E8DDE083FD22FF374AF991 +:10B0D000BF6BB1EF8C7D9DC6F70FB8B4A308EF83AB +:10B0E000227FDC813CF58167718ADE051DB3E4CDEA +:10B0F00005DB4B0AF1D5DCF9C4FB5C7ABA7286FF3A +:10B10000AEA34AE33CB98D1F350271843FB2C2C180 +:10B11000F591910F7FF3C8ED74EE0FBB0DAA3F714F +:10B12000A115FB65CB429C47476F10C25979111995 +:10B130009469CAC70FD31BF5ACFA6B7023C6D159FB +:10B140007146493892D3D721CAFB1E0E3A18EEA198 +:10B150007611171DF24EB8B502FAE5BEFEDC774A4D +:10B16000F9ADBCE60D7E273856AF70DDE7FED54B56 +:10B170003A494E0E2EE14A3114D53922A902727C89 +:10B18000DA92631D740FE1D1D3D95552C8AED8ED10 +:10B1900060DE39642D6A92BE2EAA4E46888F8BEAF5 +:10B1A00082523C0B0FBFB4E08F48F1F43A7E8F26F9 +:10B1B000EC04C5BBF44E65A8FC2EAE47BA31DE9F49 +:10B1C000C6EF6EB44BBFC5B6AC428D163A2F6C11AC +:10B1D000F99011672A42741959AA709D1279AA60D0 +:10B1E000DEEBF796BD2AAA1BE3F3419DC275A7FCCF +:10B1F00079BFB2E7A949AE631CACFB779DE4EEE0F2 +:10B2000055C0F9EDFFFEE5AE270648BFF4231D9DAE +:10B21000C4AF1DDC162DFB06E37DB451D1E81EEB57 +:10B22000E5B5035C27DA0806F927F97C50BC62898A +:10B2300087F39D1D0EF6EFF2F9A20819758AFC340A +:10B2400025C376C2092FB2DE1C3544DCA463B42AC0 +:10B25000FA825FEC7A53D0E2C7FC7B8D5A72B5DF7D +:10B26000CAAB97587F8733D6F167AEF78E2E4EB3B1 +:10B270001DB9AF251DA2BAA13FE836285439D01C0C +:10B28000E1FCF6E84A07FBADF3E0AE147A39FF3C87 +:10B29000CEE3EF09FDA888FC85BF4191C8EE7CC9CB +:10B2A0003AC70653C8931616FE9BD613030D0F5FBD +:10B2B000FE869CD2711F69D9EFE34E1C4F6E136F4F +:10B2C0008B8B54912753CD9B07C8AEFDB8520629EE +:10B2D0004C82F70983F36D1121DFF6BBEC8A1E3532 +:10B2E00027BE2F81AC3EBF53C9ED83DC77DEF76606 +:10B2F0007B7E7DF7EB27B2E0B56EC9ADB35D68FD2F +:10B3000007FDBB5F3F817C32669C5FAE6CFA24FB1D +:10B31000C342FF59FC65F31B8580F428F85CEB1FE2 +:10B320000C440BFA25FBB6083D79217DA4B9A23166 +:10B330005A7FF8A65C387759F2769705C7B558ABAF +:10B34000E479D63BA7C31ED8FA74817B8D6C517902 +:10B35000FE1C3FDB7EC08B9796875BD123E2876024 +:10B360008D87EC30E2F345D21F7F0DAA7A367F0E2F +:10B37000F972FD50DB0FF8E9162B0F575E21D1FA59 +:10B38000806EDBF1DC3C41BE1D2F72A6382F5DB410 +:10B3900054B5F50CEB830F7AEF79224EF2933EC849 +:10B3A000FE9E8AFC4BF5BC32328805E804A1DCBF66 +:10B3B00013D9B205183F65FAC4542BDEA32CA27032 +:10B3C0003D4449829126781B8BF8EF3FE877BA8994 +:10B3D000EC1C70509B6CFB24A471FE03B58AC1EF7A +:10B3E00008C1D9FC2ED9DD2A3FD7516DB9B810BD9F +:10B3F000ED73D17BB1DC77F017270F8F6DB1DE6570 +:10B400007BC023E461A36388F31D8E14BF85477955 +:10B41000579AAC9202D5FB4908703C48EF8224ABA6 +:10B420008E543B272770ABF56E73B7783FC37F5FB1 +:10B43000584B7F0F9AE1BF1BBC9A5EB7CA82AE24FD +:10B4400027A7A0CA4175E2F871493AEB1F2DA2A7C0 +:10B450008E8683D62D8108B7F9E7BE0662FCBD1E35 +:10B4600092DC2E83096E1B608ADB4698E196D41528 +:10B470009DC73821EA1DABC090E9FB6A8870DB04E8 +:10B48000316EC390E4F6CB6D9FFCD64EA4C38FE61D +:10B49000E145E0B5805CA711E8D9FBDB78FEC21678 +:10B4A0007D41723B14107993B6709AFD7AAF1EE11C +:10B4B000B8CF19147C6DC3719E234FFCF7FA4FF976 +:10B4C0007F5FF2FF519E9355203F00000000000077 +:10B4D0000000000000000000000000180000000054 +:10B4E000000000000000004000000000000000001C +:10B4F0000000002800000000000000000000001014 +:10B50000000000000000000000000020000000001B +:10B51000000000000000001000000000000000001B +:10B520000000000800000000000000000000000013 +:10B5300000000000000000000000003900000000D2 +:10B5400000000000000000380000000000000000C3 +:10B5500000000000000000000000000000000008E3 +:10B5600000000000000000000000000000000000DB +:10B57000000000000000000C0000000000000000BF +:10B580000000000E000000000000000000000004A9 +:10B590000000000000000000000000180000000093 +:10B5A000000000000000001C00000000000000007F +:10B5B0000000001C0000000000000000000000135C +:10B5C00000000000000000000000003A0000000041 +:10B5D000000000000000000100000000000000006A +:10B5E0000000000200000000000000000000000158 +:10B5F000000000000000000000000010000000003B +:10B6000000000000000000500000000000000000EA +:10B610000000000000000000000000000000000327 +:10B620000000000000000000000000AB000000006F +:10B630000000000000000008000000000000000002 +:10B640000000C00000100000000000080000C0085A +:10B6500000100000000000020000C0000010000008 +:10B660000000001000009FB0000000000000000873 +:10B670000000C08000100000000000040000C0882E +:10B6800000100000000000020000C0800010000058 +:10B6900000000010000091200000000000000008E1 +:10B6A00000009340000100040000000100009348E6 +:10B6B00000000000000000020000935000000000A5 +:10B6C0000000000800009354000000000000000289 +:10B6D00000009418000000000000000800009358CB +:10B6E000000800000000000800009AB000400000C0 +:10B6F00000000040000093980008000000000008CF +:10B70000000093D80008000000000008000094200A +:10B7100000C8000000000098000095B000980000EC +:10B7200000000028000095F00098000000000028AC +:10B730000000C480054000300000054000009D204E +:10B74000000800000000000100009D21000800002A +:10B7500000000001000020080010000000000010A0 +:10B7600000002000000000000000000800009CD83D +:10B77000000800000000000200009D18000000000A +:10B7800000000001000000010000000000000000B7 +:10B79000000000090000000000000000000000029E +:10B7A00000000000000000000000CF2000000000AA +:10B7B000000000200000CF46000000000000000153 +:10B7C0000000600000200000000000200000730066 +:10B7D000000800000000000800009FA0000000001A +:10B7E0000000000100009FA8000000000000000110 +:10B7F00000009F60000000000000001000009F6338 +:10B80000000000000000000100009F610000000037 +:10B810000000000100009F66000000000000000121 +:10B8200000009F67000000000000000000009F680B +:10B83000000000000000000400009F6C00000000F9 +:10B8400000000004000000520000000000000000A2 +:10B8500000000003000000000000000000000003E2 +:10B8600000000000000000000000000500000000D3 +:10B8700000000000000000020000000000000000C6 +:10B8800000060000000000000000002000009F7083 +:10B89000000000000000000100009F900000000078 +:10B8A000000000080000005300000000000000003D +:10B8B00000009F98000000000000000200009F9C14 +:10B8C000000000000000000100009F9D000000003B +:10B8D000000000010000000900000000000000005E +:10B8E0000000000100000000000000000000004413 +:10B8F0000000000000000000000000010000000047 +:10B9000000000000000000500000000000000000E7 +:10B91000000000890000000000000000000012C8C4 +:10B920000080000000000080000000010000000016 +:10B93000000000000000A000071000000000071039 +:10B9400000001AC800000000000000080000AEC09F +:10B9500000080000000000080000AE4000080000E1 +:10B96000000000080000AE80000800000000000891 +:10B97000000020080010000000000010000020005F +:10B9800000000000000000080000A01007100040A8 +:10B990000000004000001BF800080000000000014B +:10B9A00000001BF9000800000000000100001AD090 +:10B9B000000000000000000100001AD80000000094 +:10B9C0000000000200001ADA00000000000000027F +:10B9D0000000000000000000000000000000AF00B8 +:10B9E000000000000000002000001B78002800007C +:10B9F000000000040000E000002000000000002023 +:10BA00000000F300000800000000000800001AF029 +:10BA1000000000000000010800001B3700000000CB +:10BA20000000000100001B0F0000000000000001EA +:10BA300000001B70000000000000000400001B74E8 +:10BA400000000000000000040000005000000000A2 +:10BA500000000000000000030000000000000000E3 +:10BA600000000005000000000000000000000006CB +:10BA700000000000000000000000000700000000BF +:10BA80000000000000001BC80000000000000001D2 +:10BA900000001BE80000000000000008000000514A +:10BAA000000000000000000000001BD000000000AB +:10BAB0000000000400001BD400000000000000048F +:10BAC00000001BD8000000000000000400001BDC88 +:10BAD00000000000000000080000B0000018000096 +:10BAE000000000180000C0000040000000000040FE +:10BAF0000000C00000400002000000010000C00182 +:10BB000000400002000000000000E20000200000F1 +:10BB1000000000200000E2040002000800200002F3 +:10BB20000000000000000000000000000000E20033 +:10BB300000080020000000040000F40000280000BD +:10BB4000000000280000F540001000000000001078 +:10BB50000000F5C000200000000000200000F5C03B +:10BB600000020020000000020000F300002000009E +:10BB7000000000200000200800100000000000105D +:10BB80000000200000000000000000080000110874 +:10BB90000008000000000008000011680008000014 +:10BBA00000000008000011A80008000000000008C4 +:10BBB00000001240000800000000000100001241D7 +:10BBC0000008000000000001000040000020000408 +:10BBD00000000010000059000030001800000010A4 +:10BBE0000000590800300018000000020000570053 +:10BBF00000080000000000010000570100080000DC +:10BC000000000001000011E8000000000000000139 +:10BC1000000011F00000000000000001000011F819 +:10BC200000000000000000100000124400080000A6 +:10BC30000000000400004000002000000000002080 +:10BC40000000530000100000000000100000153834 +:10BC500000000000000000010000000300000000E0 +:10BC600000000000000000000000000000000000D4 +:10BC700000000001000000000000000000000004BF +:10BC80000000000000000000000015080000000097 +:10BC9000000000010000152800000000000000085E +:10BCA00000000050000000000000000000008308B9 +:10BCB0000080000000000080000000010000000083 +:10BCC000000000000000200800100000000000102C +:10BCD00000002000000000000000000800008410A8 +:10BCE0000008000000000008000084700008000048 +:10BCF0000000000800060000046000280000046046 +:10BD000000008520000800000000000100008521DF +:10BD1000000800000000000100000000000000001A +:10BD20000000000000008408000000000000000186 +:10BD3000000084F40008000000000002000084F607 +:10BD40000008000000000002000085040010000050 +:10BD500000000004000087600000000000000020D8 +:10BD600000006000002000000000002000007300C0 +:10BD700000080000000000080000000300000000B0 +:10BD800000000000000000050000000000000000AE +:10BD90000000000600000000000000000000000796 +:10BDA0000000000000000000000088080000000003 +:10BDB00000000001000088280000000000000008CA +:10BDC000000000500000000000000000000088108B +:10BDD00000000000000000040000881400000000C3 +:10BDE00000000004000088180000000000000004AB +:10BDF0000000881C00000000000000080000300067 +:10BE00000040000000000008000030080040000072 +:10BE1000000000280000339001C00010000000085E +:10BE20000000320000200000000000200000372049 +:10BE3000000000000000000800001020062000386C +:10BE4000000000080000A00000000000000020002A +:10BE500000003EA9000000000000000100003EC8F4 +:10BE600000000000000000020000000000000000D0 +:10BE7000000000000000600000200000000000083A +:10BE80000000400000080000000000010000400128 +:10BE9000000800000000000100004040000800040D +:10BEA00000000002000040600008000400000004E0 +:10BEB00000004000000800000000000400004004F2 +:10BEC00000080000000000040000404000000000E6 +:10BED00000000008000040480000000000000008CA +:10BEE0000000800000000000000000100000504032 +:10BEF00000010004000000010000500000000000EC +:10BF000000000020000050080010000000000004A5 +:10BF10000000500C0010000000000001000052C79B +:10BF20000000000000000001000052C600000000F8 +:10BF30000000000100003000003000180000000484 +:10BF40000000300400300018000000040000300839 +:10BF500000300018000000020000300A0030001815 +:10BF6000000000020000300C00300018000000014A +:10BF70000000300D00300018000000010000300EFD +:10BF800000300018000000010000301000300018E0 +:10BF9000000000040000301400300018000000040D +:10BFA0000000500001000080000800040000500460 +:10BFB00001000080000800040000000A00000000EA +:10BFC0000000000000005068010000800000000137 +:10BFD0000000506901000080000000010000506C6A +:10BFE00001000080000000020000506E010000808F +:10BFF00000000002000050700100008000000004FA +:10C000000000507401000080000000040000506631 +:10C010000100008000000002000050640100008068 +:10C0200000000001000050600100008000000002DC +:10C03000000050620100008000000002000050502B +:10C040000100008000000004000050540100008046 +:10C0500000000004000050580100008000000004AF +:10C060000000505C01000080000000040000507CD3 +:10C0700001000080000000010000507D01000080F0 +:10C080000000000100004018001000000000000443 +:10C0900000004090001000000000000400004098E4 +:10C0A000001000000000000400004110000000002B +:10C0B0000000000200004112000000000000000229 +:10C0C00000004114000000000000000200004116C2 +:10C0D00000000000000000020000604000080000B6 +:10C0E00000000002000060420008000000000002A2 +:10C0F00000006044000800000000000400006080B0 +:10C100000008000000000008000060C000400008B7 +:10C1100000000008000060000008000000000002AD +:10C120000000600200080000000000010000600440 +:10C13000000800000000000200006340000800004A +:10C1400000000008000063800008000000000004F8 +:10C15000000063840008000000000001000063C0CC +:10C160000008000000000002000063C40008000096 +:10C17000000000020000640000080000000000044D +:10C1800000007000001000000000000400007004B7 +:10C190000010000000000004000070080010000003 +:10C1A00000000004000090000008000000000002F1 +:10C1B0000000900200080000000000010000900450 +:10C1C000000800000000000200009040000800008D +:10C1D000000000020000904400080000000000027F +:10C1E0000000904600080000000000020000964891 +:10C1F0000008000000000008000090800008000017 +:10C20000000000020000908400080000000000020E +:10C210000000968800080000000000080000804030 +:10C22000000800000000000100008041000800003C +:10C230000000000100008042000800000000000132 +:10C2400000008043000800000000000100008000A2 +:10C25000000800000000000200008002000800004A +:10C26000000000010000800400080000000000023F +:10C27000000080C00008000000000002000080C232 +:10C280000008000000000002000080C40008000058 +:10C290000000000200008080000800000000000193 +:10C2A0000000808100080000000000010000808282 +:10C2B000000800000000000100008083000800006A +:10C2C0000000000100008084000800000000000160 +:10C2D000000080850008000000000001000080864A +:10C2E00000080000000000010000600000080000DD +:10C2F00000000002000060020008000000000001D1 +:10C30000000060040008000000000002000060421D +:10C3100000C00018000000020000604000C00018CB +:10C32000000000020000604C00C00018000000087F +:10C330000000604400C000180000000800006057C2 +:10C3400000C00018000000010000605400C0001888 +:10C35000000000020000605600C00018000000014C +:10C360000000664000080000000000080000668031 +:10C370000008000000000008000066C0000800007F +:10C38000000000080000DA4200180000000000026F +:10C390000000DE4000000000000000000000E0009F +:10C3A00000000000000000040000D0C000000000F9 +:10C3B000000000040000D0C40000000000000004E1 +:10C3C0000000D0C800000000000000040000D0CC35 +:10C3D00000000000000000040000D0D000000000B9 +:10C3E000000000040000D0D40000000000000004A1 +:10C3F0000000D0D800000000000000040000D0C001 +:10C4000000000000000000200000DB000000000031 +:10C41000000000040000DB000000000000000068D5 +:10C420000000B94800000000000000000000D0003B +:10C4300000000000000000040000B0C00000000088 +:10C44000000000040000B0C4000000000000000470 +:10C450000000B0C800000000000000040000B0C0F0 +:10C4600000000000000000100000D6B00000000036 +:10C47000000000040000D6B400000000000000042A +:10C480000000D6B800000000000000040000D6BC88 +:10C4900000000000000000040000D6B00000000012 +:10C4A000000000100000D348000000000000000859 +:10C4B0000000D358000000000000008000000010C1 +:10C4C00000000000000000000000D3580000000041 +:10C4D000000000080000000006002200000000002C +:00000001FF -- cgit v1.2.3 From 523224a3b3cd407ce4e6731a087194e13a90db18 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:23:26 +0000 Subject: bnx2x, cnic, bnx2i: use new FW/HSI This is the new FW HSI blob and the relevant definitions without logic changes. It also included code adaptation for new HSI. New features are not enabled. New FW/HSI includes: - Support for 57712 HW - Future support for VF (not used) - Improvements in FW interrupts scheme - FW FCoE hooks (stubs for future usage) Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 532 +++++- drivers/net/bnx2x/bnx2x_cmn.c | 488 ++--- drivers/net/bnx2x/bnx2x_cmn.h | 256 ++- drivers/net/bnx2x/bnx2x_ethtool.c | 20 +- drivers/net/bnx2x/bnx2x_fw_defs.h | 819 ++++---- drivers/net/bnx2x/bnx2x_fw_file_hdr.h | 1 + drivers/net/bnx2x/bnx2x_hsi.h | 1467 +++++++-------- drivers/net/bnx2x/bnx2x_init.h | 41 + drivers/net/bnx2x/bnx2x_init_ops.h | 338 ++++ drivers/net/bnx2x/bnx2x_link.c | 3 +- drivers/net/bnx2x/bnx2x_main.c | 3302 ++++++++++++++++++++------------- drivers/net/bnx2x/bnx2x_stats.c | 12 +- drivers/net/cnic.c | 285 ++- drivers/net/cnic.h | 51 +- drivers/net/cnic_defs.h | 456 +++-- drivers/net/cnic_if.h | 2 + drivers/scsi/bnx2i/bnx2i.h | 2 + drivers/scsi/bnx2i/bnx2i_hwi.c | 3 +- firmware/Makefile | 4 +- 19 files changed, 4812 insertions(+), 3270 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 64329c5fbdea..8b053e0c00ab 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -33,13 +33,11 @@ #define BNX2X_NEW_NAPI - #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" #endif - #ifdef BCM_CNIC #define BNX2X_MIN_MSIX_VEC_CNT 3 #define BNX2X_MSIX_VEC_FP_START 2 @@ -129,16 +127,18 @@ void bnx2x_panic_dump(struct bnx2x *bp); } while (0) #endif +#define bnx2x_mc_addr(ha) ((ha)->addr) #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) -#define REG_ADDR(bp, offset) (bp->regview + offset) +#define REG_ADDR(bp, offset) ((bp->regview) + (offset)) #define REG_RD(bp, offset) readl(REG_ADDR(bp, offset)) #define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset)) +#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset)) #define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset)) #define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset)) @@ -160,6 +160,9 @@ void bnx2x_panic_dump(struct bnx2x *bp); offset, len32); \ } while (0) +#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \ + REG_WR_DMAE(bp, offset, valp, len32) + #define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \ do { \ memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \ @@ -175,16 +178,52 @@ void bnx2x_panic_dump(struct bnx2x *bp); offsetof(struct shmem2_region, field)) #define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field)) #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) +#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ + offsetof(struct mf_cfg, field)) -#define MF_CFG_RD(bp, field) SHMEM_RD(bp, mf_cfg.field) -#define MF_CFG_WR(bp, field, val) SHMEM_WR(bp, mf_cfg.field, val) +#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) +#define MF_CFG_WR(bp, field, val) REG_WR(bp,\ + MF_CFG_ADDR(bp, field), (val)) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) +/* SP SB indices */ + +/* General SP events - stats query, cfc delete, etc */ +#define HC_SP_INDEX_ETH_DEF_CONS 3 + +/* EQ completions */ +#define HC_SP_INDEX_EQ_CONS 7 + +/* iSCSI L2 */ +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + +/** + * CIDs and CLIDs: + * CLIDs below is a CLID for func 0, then the CLID for other + * functions will be calculated by the formula: + * + * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X + * + */ +/* iSCSI L2 */ +#define BNX2X_ISCSI_ETH_CL_ID 17 +#define BNX2X_ISCSI_ETH_CID 17 + +/** Additional rings budgeting */ +#ifdef BCM_CNIC +#define CNIC_CONTEXT_USE 1 +#else +#define CNIC_CONTEXT_USE 0 +#endif /* BCM_CNIC */ + #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR +#define SM_RX_ID 0 +#define SM_TX_ID 1 /* fast path */ @@ -254,11 +293,21 @@ union db_prod { #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) +union host_hc_status_block { + /* pointer to fp status block e1x */ + struct host_hc_status_block_e1x *e1x_sb; +}; struct bnx2x_fastpath { struct napi_struct napi; - struct host_status_block *status_blk; + union host_hc_status_block status_blk; + /* chip independed shortcuts into sb structure */ + __le16 *sb_index_values; + __le16 *sb_running_index; + /* chip independed shortcut into rx_prods_offset memory */ + u32 ustorm_rx_prods_offset; + dma_addr_t status_blk_mapping; struct sw_tx_bd *tx_buf_ring; @@ -288,10 +337,15 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 +#define BNX2X_FP_STATE_TERMINATING 0xd0000 +#define BNX2X_FP_STATE_TERMINATED 0xe0000 u8 index; /* number in fp array */ u8 cl_id; /* eth client id */ - u8 sb_id; /* status block number in HW */ + u8 cl_qzone_id; + u8 fw_sb_id; /* status block number in FW */ + u8 igu_sb_id; /* status block number in HW */ + u32 cid; union db_prod tx_db; @@ -301,8 +355,7 @@ struct bnx2x_fastpath { u16 tx_bd_cons; __le16 *tx_cons_sb; - __le16 fp_c_idx; - __le16 fp_u_idx; + __le16 fp_hc_idx; u16 rx_bd_prod; u16 rx_bd_cons; @@ -312,7 +365,7 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - __le16 *rx_bd_cons_sb; + unsigned long tx_pkt, @@ -356,6 +409,8 @@ struct bnx2x_fastpath { #define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) #define MAX_TX_BD (NUM_TX_BD - 1) #define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) +#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL +#define INIT_TX_RING_SIZE MAX_TX_AVAIL #define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) #define TX_BD(x) ((x) & MAX_TX_BD) @@ -370,6 +425,8 @@ struct bnx2x_fastpath { #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) #define MIN_RX_AVAIL 128 +#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL +#define INIT_RX_RING_SIZE MAX_RX_AVAIL #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) @@ -420,11 +477,12 @@ struct bnx2x_fastpath { le32_to_cpu((bd)->addr_lo)) #define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes)) - +#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */ +#define BNX2X_DB_SHIFT 7 /* 128 bytes*/ #define DPM_TRIGER_TYPE 0x40 #define DOORBELL(bp, cid, val) \ do { \ - writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \ + writel((u32)(val), bp->doorbells + (bp->db_size * (cid)) + \ DPM_TRIGER_TYPE); \ } while (0) @@ -482,31 +540,15 @@ struct bnx2x_fastpath { #define BNX2X_RX_SUM_FIX(cqe) \ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags) - -#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES) -#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES) - -#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS -#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS -#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS +#define U_SB_ETH_RX_CQ_INDEX 1 +#define U_SB_ETH_RX_BD_INDEX 2 +#define C_SB_ETH_TX_CQ_INDEX 5 #define BNX2X_RX_SB_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]) - -#define BNX2X_RX_SB_BD_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX]) - -#define BNX2X_RX_SB_INDEX_NUM \ - (((U_SB_ETH_RX_CQ_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \ - ((U_SB_ETH_RX_BD_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER)) + (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX]) #define BNX2X_TX_SB_INDEX \ - (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]) - + (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) /* end of fast path */ @@ -553,10 +595,16 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; + u32 mf_cfg_base; u32 hw_config; u32 bc_ver; + + u8 int_block; +#define INT_BLOCK_HC 0 + u8 chip_port_mode; +#define CHIP_PORT_MODE_NONE 0x2 }; @@ -590,27 +638,98 @@ struct bnx2x_port { /* end of port */ +/* e1h Classification CAM line allocations */ +enum { + CAM_ETH_LINE = 0, + CAM_ISCSI_ETH_LINE, + CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE +}; +#define BNX2X_VF_ID_INVALID 0xFF -#ifdef BCM_CNIC -#define MAX_CONTEXT 15 -#else -#define MAX_CONTEXT 16 -#endif +/* + * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is + * control by the number of fast-path status blocks supported by the + * device (HW/FW). Each fast-path status block (FP-SB) aka non-default + * status block represents an independent interrupts context that can + * serve a regular L2 networking queue. However special L2 queues such + * as the FCoE queue do not require a FP-SB and other components like + * the CNIC may consume FP-SB reducing the number of possible L2 queues + * + * If the maximum number of FP-SB available is X then: + * a. If CNIC is supported it consumes 1 FP-SB thus the max number of + * regular L2 queues is Y=X-1 + * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor) + * c. If the FCoE L2 queue is supported the actual number of L2 queues + * is Y+1 + * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for + * slow-path interrupts) or Y+2 if CNIC is supported (one additional + * FP interrupt context for the CNIC). + * e. The number of HW context (CID count) is always X or X+1 if FCoE + * L2 queue is supported. the cid for the FCoE L2 queue is always X. + */ + +#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ +#define MAX_CONTEXT FP_SB_MAX_E1x + +/* + * cid_cnt paramter below refers to the value returned by + * 'bnx2x_get_l2_cid_count()' routine + */ + +/* + * The number of FP context allocated by the driver == max number of regular + * L2 queues + 1 for the FCoE L2 queue + */ +#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) union cdu_context { struct eth_context eth; char pad[1024]; }; +/* CDU host DB constants */ +#define CDU_ILT_PAGE_SZ_HW 3 +#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */ +#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) + +#ifdef BCM_CNIC +#define CNIC_ISCSI_CID_MAX 256 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) +#endif + +#define QM_ILT_PAGE_SZ_HW 3 +#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */ +#define QM_CID_ROUND 1024 + +#ifdef BCM_CNIC +/* TM (timers) host DB constants */ +#define TM_ILT_PAGE_SZ_HW 2 +#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */ +/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */ +#define TM_CONN_NUM 1024 +#define TM_ILT_SZ (8 * TM_CONN_NUM) +#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ) + +/* SRC (Searcher) host DB constants */ +#define SRC_ILT_PAGE_SZ_HW 3 +#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */ +#define SRC_HASH_BITS 10 +#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */ +#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM) +#define SRC_T2_SZ SRC_ILT_SZ +#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) +#endif + #define MAX_DMAE_C 8 /* DMA memory not used in fastpath */ struct bnx2x_slowpath { - union cdu_context context[MAX_CONTEXT]; struct eth_stats_query fw_stats; struct mac_configuration_cmd mac_config; struct mac_configuration_cmd mcast_config; + struct client_init_ramrod_data client_init_data; /* used by dmae command executer */ struct dmae_command dmae[MAX_DMAE_C]; @@ -638,37 +757,71 @@ struct attn_route { u32 sig[4]; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + +struct hw_context { + union cdu_context *vcxt; + dma_addr_t cxt_mapping; + size_t size; +}; + +/* forward */ +struct bnx2x_ilt; + typedef enum { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, } bnx2x_recovery_state_t; +/** + * Event queue (EQ or event ring) MC hsi + * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2 + */ +#define NUM_EQ_PAGES 1 +#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem)) +#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1) +#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES) +#define EQ_DESC_MASK (NUM_EQ_DESC - 1) +#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2) + +/* depends on EQ_DESC_CNT_PAGE being a power of 2 */ +#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \ + (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1) + +/* depends on the above and on NUM_EQ_PAGES being a power of 2 */ +#define EQ_DESC(x) ((x) & EQ_DESC_MASK) + +#define BNX2X_EQ_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_EQ_CONS]) + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure */ - struct bnx2x_fastpath fp[MAX_CONTEXT]; + struct bnx2x_fastpath *fp; void __iomem *regview; void __iomem *doorbells; -#ifdef BCM_CNIC -#define BNX2X_DB_SIZE (18*BCM_PAGE_SIZE) -#else -#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) -#endif + u16 db_size; struct net_device *dev; struct pci_dev *pdev; + struct iro *iro_arr; +#define IRO (bp->iro_arr) + atomic_t intr_sem; bnx2x_recovery_state_t recovery_state; int is_leader; -#ifdef BCM_CNIC - struct msix_entry msix_table[MAX_CONTEXT+2]; -#else - struct msix_entry msix_table[MAX_CONTEXT+1]; -#endif + struct msix_entry *msix_table; #define INT_MODE_INTx 1 #define INT_MODE_MSI 2 @@ -680,7 +833,8 @@ struct bnx2x { u32 rx_csum; u32 rx_buf_size; -#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ +/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -689,13 +843,12 @@ struct bnx2x { #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ L1_CACHE_SHIFT : 8) #define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT) +#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) - struct host_def_status_block *def_status_blk; -#define DEF_SB_ID 16 - __le16 def_c_idx; - __le16 def_u_idx; - __le16 def_x_idx; - __le16 def_t_idx; + struct host_sp_status_block *def_status_blk; +#define DEF_SB_IGU_ID 16 +#define DEF_SB_ID HC_SP_SB_ID + __le16 def_idx; __le16 def_att_idx; u32 attn_state; struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; @@ -711,6 +864,13 @@ struct bnx2x { /* used to synchronize spq accesses */ spinlock_t spq_lock; + /* event queue */ + union event_ring_elem *eq_ring; + dma_addr_t eq_mapping; + u16 eq_prod; + u16 eq_cons; + __le16 *eq_cons_sb; + /* Flags for marking that there is a STAT_QUERY or SET_MAC ramrod pending */ int stats_pending; @@ -737,6 +897,8 @@ struct bnx2x { #define MF_FUNC_DIS 0x1000 int func; + int base_fw_ndsb; + #define BP_PORT(bp) (bp->func % PORT_MAX) #define BP_FUNC(bp) (bp->func) #define BP_E1HVN(bp) (bp->func >> 1) @@ -801,6 +963,7 @@ struct bnx2x { #define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 #define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 +#define BNX2X_STATE_FUNC_STARTED 0x7000 #define BNX2X_STATE_DIAG 0xe000 #define BNX2X_STATE_ERROR 0xf000 @@ -809,6 +972,15 @@ struct bnx2x { int disable_tpa; int int_mode; + struct tstorm_eth_mac_filter_config mac_filters; +#define BNX2X_ACCEPT_NONE 0x0000 +#define BNX2X_ACCEPT_UNICAST 0x0001 +#define BNX2X_ACCEPT_MULTICAST 0x0002 +#define BNX2X_ACCEPT_ALL_UNICAST 0x0004 +#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 +#define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_PROMISCUOUS_MODE 0x10000 + u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 #define BNX2X_RX_MODE_NORMAL 1 @@ -817,12 +989,25 @@ struct bnx2x { #define BNX2X_MAX_MULTICAST 64 #define BNX2X_MAX_EMUL_MULTI 16 - u32 rx_mode_cl_mask; - + u8 igu_dsb_id; + u8 igu_base_sb; + u8 igu_sb_cnt; dma_addr_t def_status_blk_mapping; struct bnx2x_slowpath *slowpath; dma_addr_t slowpath_mapping; + struct hw_context context; + + struct bnx2x_ilt *ilt; +#define BP_ILT(bp) ((bp)->ilt) +#define ILT_MAX_LINES 128 + + int l2_cid_count; +#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ + ILT_PAGE_CIDS)) +#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT)) + + int qm_cid_count; int dropless_fc; @@ -842,9 +1027,10 @@ struct bnx2x { void *cnic_data; u32 cnic_tag; struct cnic_eth_dev cnic_eth_dev; - struct host_status_block *cnic_sb; + union host_hc_status_block cnic_sb; dma_addr_t cnic_sb_mapping; -#define CNIC_SB_ID(bp) BP_L_ID(bp) +#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp)) +#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb) struct eth_spe *cnic_kwq; struct eth_spe *cnic_kwq_prod; struct eth_spe *cnic_kwq_cons; @@ -914,12 +1100,167 @@ struct bnx2x { const struct firmware *firmware; }; +/** + * Init queue/func interface + */ +/* queue init flags */ +#define QUEUE_FLG_TPA 0x0001 +#define QUEUE_FLG_CACHE_ALIGN 0x0002 +#define QUEUE_FLG_STATS 0x0004 +#define QUEUE_FLG_OV 0x0008 +#define QUEUE_FLG_VLAN 0x0010 +#define QUEUE_FLG_COS 0x0020 +#define QUEUE_FLG_HC 0x0040 +#define QUEUE_FLG_DHC 0x0080 +#define QUEUE_FLG_OOO 0x0100 + +#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR +#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR +#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 +#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR + + + +/* rss capabilities */ +#define RSS_IPV4_CAP 0x0001 +#define RSS_IPV4_TCP_CAP 0x0002 +#define RSS_IPV6_CAP 0x0004 +#define RSS_IPV6_TCP_CAP 0x0008 #define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) + +#define RSS_IPV4_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY + +#define RSS_IPV4_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY + +#define RSS_IPV6_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY + +#define RSS_IPV6_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY + +/* func init flags */ +#define FUNC_FLG_RSS 0x0001 +#define FUNC_FLG_STATS 0x0002 +/* removed FUNC_FLG_UNMATCHED 0x0004 */ +#define FUNC_FLG_TPA 0x0008 +#define FUNC_FLG_SPQ 0x0010 +#define FUNC_FLG_LEADING 0x0020 /* PF only */ + +#define FUNC_CONFIG(flgs) ((flgs) & (FUNC_FLG_RSS | FUNC_FLG_TPA | \ + FUNC_FLG_LEADING)) + +struct rxq_pause_params { + u16 bd_th_lo; + u16 bd_th_hi; + u16 rcq_th_lo; + u16 rcq_th_hi; + u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */ + u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */ + u16 pri_map; +}; + +struct bnx2x_rxq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + dma_addr_t sge_map; + dma_addr_t rcq_map; + dma_addr_t rcq_np_map; + + u16 flags; + u16 drop_flags; + u16 mtu; + u16 buf_sz; + u16 fw_sb_id; + u16 cl_id; + u16 spcl_id; + u16 cl_qzone_id; + + /* valid iff QUEUE_FLG_STATS */ + u16 stat_id; + + /* valid iff QUEUE_FLG_TPA */ + u16 tpa_agg_sz; + u16 sge_buf_sz; + u16 max_sges_pkt; + + /* valid iff QUEUE_FLG_CACHE_ALIGN */ + u8 cache_line_log; + + u8 sb_cq_index; + u32 cid; + + /* desired interrupts per sec. valid iff QUEUE_FLG_HC */ + u32 hc_rate; +}; + +struct bnx2x_txq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + + u16 flags; + u16 fw_sb_id; + u8 sb_cq_index; + u8 cos; /* valid iff QUEUE_FLG_COS */ + u16 stat_id; /* valid iff QUEUE_FLG_STATS */ + u16 traffic_type; + u32 cid; + u16 hc_rate; /* desired interrupts per sec.*/ + /* valid iff QUEUE_FLG_HC */ + +}; + +struct bnx2x_client_ramrod_params { + int *pstate; + int state; + u16 index; + u16 cl_id; + u32 cid; + u8 poll; +#define CLIENT_IS_LEADING_RSS 0x02 + u8 flags; +}; + +struct bnx2x_client_init_params { + struct rxq_pause_params pause; + struct bnx2x_rxq_init_params rxq_params; + struct bnx2x_txq_init_params txq_params; + struct bnx2x_client_ramrod_params ramrod_params; +}; + +struct bnx2x_rss_params { + int mode; + u16 cap; + u16 result_mask; +}; + +struct bnx2x_func_init_params { + + /* rss */ + struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */ + + /* dma */ + dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */ + dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */ + + u16 func_flgs; + u16 func_id; /* abs fid */ + u16 pf_id; + u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ +}; + #define for_each_queue(bp, var) \ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) #define for_each_nondefault_queue(bp, var) \ @@ -957,6 +1298,38 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } +#define BNX2X_ILT_ZALLOC(x, y, size) \ + do { \ + x = pci_alloc_consistent(bp->pdev, size, y); \ + if (x) \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ILT_FREE(x, y, size) \ + do { \ + if (x) { \ + pci_free_consistent(bp->pdev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define ILOG2(x) (ilog2((x))) + +#define ILT_NUM_PAGE_ENTRIES (3072) +/* In 57710/11 we use whole table since we have 8 func + */ +#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) + +#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) +/* + * the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) /* load/unload mode */ @@ -1032,7 +1405,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) -#define BNX2X_BTR 1 +#define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 @@ -1149,20 +1522,22 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) #define MULTI_MASK 0x7f - -#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES) -#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES) -#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES) -#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES) - -#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH - #define BNX2X_SP_DSB_INDEX \ -(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]) + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_DEF_CONS]) +#define SET_FLAG(value, mask, flag) \ + do {\ + (value) &= ~(mask);\ + (value) |= ((flag) << (mask##_SHIFT));\ + } while (0) +#define GET_FLAG(value, mask) \ + (((value) &= (mask)) >> (mask##_SHIFT)) #define CAM_IS_INVALID(x) \ -(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) + (GET_FLAG(x.flags, \ + MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ + (T_ETH_MAC_COMMAND_INVALIDATE)) #define CAM_INVALIDATE(x) \ (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) @@ -1181,6 +1556,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 +/* Congestion management fairness mode */ +#define CMNG_FNS_NONE 0 +#define CMNG_FNS_MINMAX 1 + +#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/ +#define HC_SEG_ACCESS_ATTN 4 +#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/ + #ifdef BNX2X_MAIN #define BNX2X_EXTERN #else @@ -1195,4 +1578,9 @@ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 + +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8d42067a6989..bcc4a8f4677b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -27,6 +27,8 @@ #include #endif +#include "bnx2x_init.h" + static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx @@ -190,14 +192,16 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, /* First mark all used pages */ for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); + SGE_MASK_CLEAR_BIT(fp, + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i]))); DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", - sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); /* Here we assume that the last SGE index is the biggest */ prefetch((void *)(fp->sge_mask)); - bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + bnx2x_update_last_max_sge(fp, + le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); last_max = RX_SGE(fp->last_max_sge); last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; @@ -298,7 +302,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Run through the SGL and compose the fragmented skb */ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); + u16 sge_idx = + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j])); /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ @@ -394,8 +399,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && is_vlan_cqe && - (!is_not_hwaccel_vlan_cqe)) + if ((bp->vlgrp != NULL) && + (le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) vlan_gro_receive(&fp->napi, bp->vlgrp, le16_to_cpu(cqe->fast_path_cqe. vlan_tag), skb); @@ -686,9 +692,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", - fp->index, fp->sb_id); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); + DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " + "[fp %d fw_sd %d igusb %d]\n", + fp->index, fp->fw_sb_id, fp->igu_sb_id); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -698,8 +705,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) /* Handle Rx and Tx according to MSI-X vector */ prefetch(fp->rx_cons_sb); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->u_status_block.status_block_index); - prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); return IRQ_HANDLED; @@ -774,27 +780,73 @@ void bnx2x_link_report(struct bnx2x *bp) } } +/* Returns the number of actually allocated BDs */ +static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, + int rx_ring_size) +{ + struct bnx2x *bp = fp->bp; + u16 ring_prod, cqe_ring_prod; + int i; + + fp->rx_comp_cons = 0; + cqe_ring_prod = ring_prod = 0; + for (i = 0; i < rx_ring_size; i++) { + if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx skbs on queue[%d]\n", i, fp->index); + fp->eth_q_stats.rx_skb_alloc_failed++; + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); + WARN_ON(ring_prod <= i); + } + + fp->rx_bd_prod = ring_prod; + /* Limit the CQE producer by the CQE ring size */ + fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, + cqe_ring_prod); + fp->rx_pkt = fp->rx_calls = 0; + + return i; +} + +static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + + bnx2x_alloc_rx_bds(fp, rx_ring_size); + + /* Warning! + * this will generate an interrupt (to the TSTORM) + * must only be done after chip is initialized + */ + bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, + fp->rx_sge_prod); +} + void bnx2x_init_rx_rings(struct bnx2x *bp) { int func = BP_FUNC(bp); int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : ETH_MAX_AGGREGATION_QUEUES_E1H; - u16 ring_prod, cqe_ring_prod; + u16 ring_prod; int i, j; - int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : - MAX_RX_AVAIL/bp->num_queues; - rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + + BNX2X_FW_IP_HDR_ALIGN_PAD; - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - if (bp->flags & TPA_ENABLE_FLAG) { - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + if (!fp->disable_tpa) { for (i = 0; i < max_agg_queues; i++) { fp->tpa_pool[i].skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); @@ -812,6 +864,35 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) mapping, 0); fp->tpa_state[i] = BNX2X_TPA_STOP; } + + /* "next page" elements initialization */ + bnx2x_set_next_page_sgl(fp); + + /* set SGEs bit mask */ + bnx2x_init_sge_ring_bit_mask(fp); + + /* Allocate SGEs and initialize the ring elements */ + for (i = 0, ring_prod = 0; + i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { + + if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx sges\n", i); + BNX2X_ERR("disabling TPA for" + " queue[%d]\n", j); + /* Cleanup already allocated elements */ + bnx2x_free_rx_sge_range(bp, + fp, ring_prod); + bnx2x_free_tpa_pool(bp, + fp, max_agg_queues); + fp->disable_tpa = 1; + ring_prod = 0; + break; + } + ring_prod = NEXT_SGE_IDX(ring_prod); + } + + fp->rx_sge_prod = ring_prod; } } @@ -819,98 +900,15 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) struct bnx2x_fastpath *fp = &bp->fp[j]; fp->rx_bd_cons = 0; - fp->rx_cons_sb = BNX2X_RX_SB_INDEX; - fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX; - - /* "next page" elements initialization */ - /* SGE ring */ - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - struct eth_rx_sge *sge; - - sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; - sge->addr_hi = - cpu_to_le32(U64_HI(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - sge->addr_lo = - cpu_to_le32(U64_LO(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - } - bnx2x_init_sge_ring_bit_mask(fp); - - /* RX BD ring */ - for (i = 1; i <= NUM_RX_RINGS; i++) { - struct eth_rx_bd *rx_bd; - - rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; - rx_bd->addr_hi = - cpu_to_le32(U64_HI(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - rx_bd->addr_lo = - cpu_to_le32(U64_LO(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - } + bnx2x_set_next_page_rx_bd(fp); /* CQ ring */ - for (i = 1; i <= NUM_RCQ_RINGS; i++) { - struct eth_rx_cqe_next_page *nextpg; - - nextpg = (struct eth_rx_cqe_next_page *) - &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; - nextpg->addr_hi = - cpu_to_le32(U64_HI(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - nextpg->addr_lo = - cpu_to_le32(U64_LO(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - } - - /* Allocate SGEs and initialize the ring elements */ - for (i = 0, ring_prod = 0; - i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { - - if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx sges\n", i); - BNX2X_ERR("disabling TPA for queue[%d]\n", j); - /* Cleanup already allocated elements */ - bnx2x_free_rx_sge_range(bp, fp, ring_prod); - bnx2x_free_tpa_pool(bp, fp, max_agg_queues); - fp->disable_tpa = 1; - ring_prod = 0; - break; - } - ring_prod = NEXT_SGE_IDX(ring_prod); - } - fp->rx_sge_prod = ring_prod; + bnx2x_set_next_page_rx_cq(fp); /* Allocate BDs and initialize BD ring */ - fp->rx_comp_cons = 0; - cqe_ring_prod = ring_prod = 0; - for (i = 0; i < rx_ring_size; i++) { - if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx skbs on queue[%d]\n", i, j); - fp->eth_q_stats.rx_skb_alloc_failed++; - break; - } - ring_prod = NEXT_RX_IDX(ring_prod); - cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); - WARN_ON(ring_prod <= i); - } + bnx2x_alloc_rx_bd_ring(fp); - fp->rx_bd_prod = ring_prod; - /* must not have more available CQEs than BDs */ - fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, - cqe_ring_prod); - fp->rx_pkt = fp->rx_calls = 0; - - /* Warning! - * this will generate an interrupt (to the TSTORM) - * must only be done after chip is initialized - */ - bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod, - fp->rx_sge_prod); if (j != 0) continue; @@ -921,6 +919,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, U64_HI(fp->rx_comp_mapping)); } + } static void bnx2x_free_tx_skbs(struct bnx2x *bp) { @@ -1252,6 +1251,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (rc) return rc; + /* must be called before memory allocation and HW init */ + bnx2x_ilt_set_info(bp); + if (bnx2x_alloc_mem(bp)) { bnx2x_free_irq(bp, true); return -ENOMEM; @@ -1339,6 +1341,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error2; } + if (rc) { + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + goto load_error2; + } + /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); @@ -1360,7 +1367,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - rc = bnx2x_setup_leading(bp); + rc = bnx2x_func_start(bp); + if (rc) { + BNX2X_ERR("Function start failed!\n"); +#ifndef BNX2X_STOP_ON_ERROR + goto load_error3; +#else + bp->panic = 1; + return -EBUSY; +#endif + } + + rc = bnx2x_setup_client(bp, &bp->fp[0], 1 /* Leading */); if (rc) { BNX2X_ERR("Setup leading failed!\n"); #ifndef BNX2X_STOP_ON_ERROR @@ -1377,37 +1395,37 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->flags |= MF_FUNC_DIS; } - if (bp->state == BNX2X_STATE_OPEN) { #ifdef BCM_CNIC - /* Enable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); + /* Enable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); #endif - for_each_nondefault_queue(bp, i) { - rc = bnx2x_setup_multi(bp, i); - if (rc) + for_each_nondefault_queue(bp, i) { + rc = bnx2x_setup_client(bp, &bp->fp[i], 0); + if (rc) #ifdef BCM_CNIC - goto load_error4; + goto load_error4; #else - goto load_error3; + goto load_error3; #endif - } + } + + /* Now when Clients are configured we are ready to work */ + bp->state = BNX2X_STATE_OPEN; + + bnx2x_set_eth_mac(bp, 1); - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); #ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, - CNIC_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); -#endif + /* Set iSCSI L2 MAC */ + mutex_lock(&bp->cnic_mutex); + if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); } + mutex_unlock(&bp->cnic_mutex); +#endif if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); @@ -1415,18 +1433,15 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Start fast path */ switch (load_mode) { case LOAD_NORMAL: - if (bp->state == BNX2X_STATE_OPEN) { - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); - } + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; case LOAD_OPEN: netif_tx_start_all_queues(bp->dev); - if (bp->state != BNX2X_STATE_OPEN) - netif_tx_disable(bp->dev); + smp_mb__after_clear_bit(); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; @@ -1512,21 +1527,22 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); - /* Disable HW interrupts, NAPI and Tx */ - bnx2x_netif_stop(bp, 1); - netif_carrier_off(bp->dev); - del_timer_sync(&bp->timer); SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); - /* Release IRQs */ - bnx2x_free_irq(bp, false); /* Cleanup the chip if needed */ if (unload_mode != UNLOAD_RECOVERY) bnx2x_chip_cleanup(bp, unload_mode); + else { + /* Disable HW interrupts, NAPI and Tx */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp, false); + } bp->port.pmf = 0; @@ -1634,27 +1650,28 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, thus we need - * to ensure that status block indices have been actually read - * (bnx2x_update_fpsb_idx) prior to this check - * (bnx2x_has_rx_work) so that we won't write the "newer" - * value of the status block to IGU (if there was a DMA right - * after bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed to right - * before bnx2x_ack_sb). In this case there will never be - * another interrupt until there is another update of the - * status block, while there is still unhandled work. + /* bnx2x_has_rx_work() reads the status block, + * thus we need to ensure that status block indices + * have been actually read (bnx2x_update_fpsb_idx) + * prior to this check (bnx2x_has_rx_work) so that + * we won't write the "newer" value of the status block + * to IGU (if there was a DMA right after + * bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed + * to right before bnx2x_ack_sb). In this case there + * will never be another interrupt until there is + * another update of the status block, while there + * is still unhandled work. */ rmb(); if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { napi_complete(napi); /* Re-enable interrupts */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, - le16_to_cpu(fp->fp_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, - le16_to_cpu(fp->fp_u_idx), + DP(NETIF_MSG_HW, + "Update index to %d\n", fp->fp_hc_idx); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, + le16_to_cpu(fp->fp_hc_idx), IGU_INT_ENABLE, 1); break; } @@ -1850,7 +1867,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -1926,10 +1943,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = (mac_type << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_ETH_ADDR_TYPE, + mac_type); /* header nbd */ - tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_HDR_NBDS, + 1); /* remember the first BD of the packet */ tx_buf->first_bd = fp->tx_bd_prod; @@ -1943,62 +1963,68 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef BCM_VLAN if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && (bp->flags & HW_VLAN_TX_FLAG)) { - tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(vlan_tx_tag_get(skb)); + tx_start_bd->bd_flags.as_bitfield |= + (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); } else #endif - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp->tx_desc_ring[bd_prod].parse_bd; - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); + if (xmit_type & XMIT_CSUM) { + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; + + if (xmit_type & XMIT_CSUM_V4) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IP_CSUM; + else + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IPV6; + if (!(xmit_type & XMIT_CSUM_TCP)) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IS_UDP; + } + pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); + /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) { hlen = (skb_network_header(skb) - skb->data) / 2; /* for now NS flag is not used in Linux */ - pbd->global_data = + pbd_e1x->global_data = (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); + ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); - pbd->ip_hlen = (skb_transport_header(skb) - + pbd_e1x->ip_hlen_w = (skb_transport_header(skb) - skb_network_header(skb)) / 2; - hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2; + hlen += pbd_e1x->ip_hlen_w + tcp_hdrlen(skb) / 2; - pbd->total_hlen = cpu_to_le16(hlen); + pbd_e1x->total_hlen_w = cpu_to_le16(hlen); hlen = hlen*2; - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - - if (xmit_type & XMIT_CSUM_V4) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IP_CSUM; - else - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IPV6; - if (xmit_type & XMIT_CSUM_TCP) { - pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); + pbd_e1x->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); } else { s8 fix = SKB_CS_OFF(skb); /* signed! */ - pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG; - DP(NETIF_MSG_TX_QUEUED, "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb)); + le16_to_cpu(pbd_e1x->total_hlen_w), + fix, SKB_CS(skb)); /* HW bug: fixup the CSUM */ - pbd->tcp_pseudo_csum = + pbd_e1x->tcp_pseudo_csum = bnx2x_csum_fix(skb_transport_header(skb), SKB_CS(skb), fix); DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd->tcp_pseudo_csum); + pbd_e1x->tcp_pseudo_csum); } } @@ -2016,7 +2042,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) " nbytes %d flags %x vlan %x\n", tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), - tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan)); + tx_start_bd->bd_flags.as_bitfield, + le16_to_cpu(tx_start_bd->vlan_or_ethertype)); if (xmit_type & XMIT_GSO) { @@ -2031,24 +2058,25 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd->tcp_flags = pbd_tcp_flags(skb); + pbd_e1x->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd_e1x->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd_e1x->tcp_flags = pbd_tcp_flags(skb); if (xmit_type & XMIT_GSO_V4) { - pbd->ip_id = swab16(ip_hdr(skb)->id); - pbd->tcp_pseudo_csum = + pbd_e1x->ip_id = swab16(ip_hdr(skb)->id); + pbd_e1x->tcp_pseudo_csum = swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); } else - pbd->tcp_pseudo_csum = + pbd_e1x->tcp_pseudo_csum = swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0)); - pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; + pbd_e1x->global_data |= + ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; @@ -2088,13 +2116,14 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (total_pkt_bd != NULL) total_pkt_bd->total_pkt_bytes = pkt_size; - if (pbd) + if (pbd_e1x) DP(NETIF_MSG_TX_QUEUED, - "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" + "PBD (E1X) @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" " tcp_flags %x xsum %x seq %u hlen %u\n", - pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id, - pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum, - pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen)); + pbd_e1x, pbd_e1x->global_data, pbd_e1x->ip_hlen_w, + pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags, + pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq, + le16_to_cpu(pbd_e1x->total_hlen_w)); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); @@ -2109,7 +2138,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) fp->tx_db.data.prod += nbd; barrier(); - DOORBELL(bp, fp->index, fp->tx_db.raw); + DOORBELL(bp, fp->cid, fp->tx_db.raw); mmiowb(); @@ -2141,16 +2170,51 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) return -EINVAL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (netif_running(dev)) { - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); - } + if (netif_running(dev)) + bnx2x_set_eth_mac(bp, 1); return 0; } +void bnx2x_free_mem_bp(struct bnx2x *bp) +{ + kfree(bp->fp); + kfree(bp->msix_table); + kfree(bp->ilt); +} + +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) +{ + struct bnx2x_fastpath *fp; + struct msix_entry *tbl; + struct bnx2x_ilt *ilt; + + /* fp array */ + fp = kzalloc(L2_FP_COUNT(bp->l2_cid_count)*sizeof(*fp), GFP_KERNEL); + if (!fp) + goto alloc_err; + bp->fp = fp; + + /* msix table */ + tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl), + GFP_KERNEL); + if (!tbl) + goto alloc_err; + bp->msix_table = tbl; + + /* ilt */ + ilt = kzalloc(sizeof(*ilt), GFP_KERNEL); + if (!ilt) + goto alloc_err; + bp->ilt = ilt; + + return 0; +alloc_err: + bnx2x_free_mem_bp(bp); + return -ENOMEM; + +} + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { @@ -2200,18 +2264,6 @@ void bnx2x_vlan_rx_register(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); bp->vlgrp = vlgrp; - - /* Set flags according to the required capabilities */ - bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); - - if (dev->features & NETIF_F_HW_VLAN_TX) - bp->flags |= HW_VLAN_TX_FLAG; - - if (dev->features & NETIF_F_HW_VLAN_RX) - bp->flags |= HW_VLAN_RX_FLAG; - - if (netif_running(dev)) - bnx2x_set_client_config(bp); } #endif diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 1ad08e4e88f4..2fb9045833e1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -106,6 +106,13 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); */ void bnx2x_int_enable(struct bnx2x *bp); +/** + * Disable HW interrupts. + * + * @param bp + */ +void bnx2x_int_disable(struct bnx2x *bp); + /** * Disable interrupts. This function ensures that there are no * ISRs or SP DPCs (sp_task) are running after it returns. @@ -163,27 +170,30 @@ int bnx2x_alloc_mem(struct bnx2x *bp); void bnx2x_free_mem(struct bnx2x *bp); /** - * Bring up a leading (the first) eth Client. + * Setup eth Client. * * @param bp + * @param fp + * @param is_leading * * @return int */ -int bnx2x_setup_leading(struct bnx2x *bp); +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading); /** - * Setup non-leading eth Client. + * Bring down an eth client. * * @param bp - * @param fp + * @param p * * @return int */ -int bnx2x_setup_multi(struct bnx2x *bp, int index); +int bnx2x_stop_fw_client(struct bnx2x *bp, + struct bnx2x_client_ramrod_params *p); /** - * Set number of quueus according to mode and number of available - * msi-x vectors + * Set number of quueus according to mode * * @param bp * @@ -228,16 +238,7 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); * @param bp driver handle * @param set */ -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set); - -/** - * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57710 - * - * @param bp driver handle - * @param set - */ -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set); +void bnx2x_set_eth_mac(struct bnx2x *bp, int set); #ifdef BCM_CNIC /** @@ -257,12 +258,15 @@ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set); * Initialize status block in FW and HW * * @param bp driver handle - * @param sb host_status_block * @param dma_addr_t mapping * @param int sb_id + * @param int vfid + * @param u8 vf_valid + * @param int fw_sb_id + * @param int igu_sb_id */ -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id); +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id); /** * Reconfigure FW/HW according to dev->flags rx mode @@ -294,14 +298,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp); */ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); -/** - * Configures FW with client paramteres (like HW VLAN removal) - * for each active client. - * - * @param bp - */ -void bnx2x_set_client_config(struct bnx2x *bp); - /** * Handle sp events * @@ -310,14 +306,29 @@ void bnx2x_set_client_config(struct bnx2x *bp); */ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); +/** + * Init/halt function before/after sending + * CLIENT_SETUP/CFC_DEL for the first/last client. + * + * @param bp + * + * @return int + */ +int bnx2x_func_start(struct bnx2x *bp); +int bnx2x_func_stop(struct bnx2x *bp); + +/** + * Prepare ILT configurations according to current driver + * parameters. + * + * @param bp + */ +void bnx2x_ilt_set_info(struct bnx2x *bp); static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { - struct host_status_block *fpsb = fp->status_blk; - barrier(); /* status block is written to by the chip */ - fp->fp_c_idx = fpsb->c_status_block.status_block_index; - fp->fp_u_idx = fpsb->u_status_block.status_block_index; + fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; } static inline void bnx2x_update_rx_prod(struct bnx2x *bp, @@ -344,8 +355,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, wmb(); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4, + REG_WR(bp, + BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset + i*4, ((u32 *)&rx_prods)[i]); mmiowb(); /* keep prod updates ordered */ @@ -434,6 +445,17 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) return hw_cons != fp->tx_pkt_cons; } +static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +{ + u16 rx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); + if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + rx_cons_sb++; + return (fp->rx_comp_cons != rx_cons_sb); +} static inline void bnx2x_free_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -454,13 +476,35 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } -static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, - struct bnx2x_fastpath *fp, int last) + + + + +static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) { - int i; + int i, j; - for (i = 0; i < last; i++) - bnx2x_free_rx_sge(bp, fp, i); + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + int idx = RX_SGE_CNT * i - 1; + + for (j = 0; j < 2; j++) { + SGE_MASK_CLEAR_BIT(fp, idx); + idx--; + } + } +} + +static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) +{ + /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ + memset(fp->sge_mask, 0xff, + (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); + + /* Clear the two last indices in the page to 1: + these are the indices that correspond to the "next" element, + hence will never be indicated and should be removed from + the calculations. */ + bnx2x_clear_sge_mask_next_elems(fp); } static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, @@ -540,33 +584,15 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, dma_unmap_addr(cons_rx_buf, mapping)); *prod_bd = *cons_bd; } - -static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) +static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, + struct bnx2x_fastpath *fp, int last) { - int i, j; - - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - int idx = RX_SGE_CNT * i - 1; + int i; - for (j = 0; j < 2; j++) { - SGE_MASK_CLEAR_BIT(fp, idx); - idx--; - } - } + for (i = 0; i < last; i++) + bnx2x_free_rx_sge(bp, fp, i); } -static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) -{ - /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ - memset(fp->sge_mask, 0xff, - (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); - - /* Clear the two last indices in the page to 1: - these are the indices that correspond to the "next" element, - hence will never be indicated and should be removed from - the calculations. */ - bnx2x_clear_sge_mask_next_elems(fp); -} static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -592,7 +618,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, } -static inline void bnx2x_init_tx_ring(struct bnx2x *bp) +static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i, j; @@ -611,7 +637,7 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); } - fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE; + SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); fp->tx_db.data.zero_fill1 = 0; fp->tx_db.data.prod = 0; @@ -619,22 +645,94 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) fp->tx_pkt_cons = 0; fp->tx_bd_prod = 0; fp->tx_bd_cons = 0; - fp->tx_cons_sb = BNX2X_TX_SB_INDEX; fp->tx_pkt = 0; } } -static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) { - u16 rx_cons_sb; + int i; - /* Tell compiler that status block fields can change */ - barrier(); - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; - return fp->rx_comp_cons != rx_cons_sb; + for (i = 1; i <= NUM_RX_RINGS; i++) { + struct eth_rx_bd *rx_bd; + + rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; + rx_bd->addr_hi = + cpu_to_le32(U64_HI(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + rx_bd->addr_lo = + cpu_to_le32(U64_LO(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + } } +static inline void bnx2x_set_next_page_sgl(struct bnx2x_fastpath *fp) +{ + int i; + + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + struct eth_rx_sge *sge; + + sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; + sge->addr_hi = + cpu_to_le32(U64_HI(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + + sge->addr_lo = + cpu_to_le32(U64_LO(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + } +} + +static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) +{ + int i; + for (i = 1; i <= NUM_RCQ_RINGS; i++) { + struct eth_rx_cqe_next_page *nextpg; + + nextpg = (struct eth_rx_cqe_next_page *) + &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; + nextpg->addr_hi = + cpu_to_le32(U64_HI(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + nextpg->addr_lo = + cpu_to_le32(U64_LO(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + } +} + + + +static inline void __storm_memset_struct(struct bnx2x *bp, + u32 addr, size_t size, u32 *data) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), data[i]); +} + +static inline void storm_memset_mac_filters(struct bnx2x *bp, + struct tstorm_eth_mac_filter_config *mac_filters, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_mac_filter_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); +} + +static inline void storm_memset_cmng(struct bnx2x *bp, + struct cmng_struct_per_port *cmng, + u8 port) +{ + size_t size = sizeof(struct cmng_struct_per_port); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port); + + __storm_memset_struct(bp, addr, size, (u32 *)cmng); +} /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); @@ -659,4 +757,16 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); int bnx2x_nic_load(struct bnx2x *bp, int load_mode); int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); +/** + * Allocate/release memories outsize main driver structure + * + * @param bp + * + * @return int + */ +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); +void bnx2x_free_mem_bp(struct bnx2x *bp); + +#define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ + #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index d9748e97fad3..56a0cb579c21 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1343,7 +1343,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) u16 pkt_prod, bd_prod; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; u8 cqe_fp_flags; @@ -1399,16 +1399,20 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = ((UNICAST_ADDRESS << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_ETH_ADDR_TYPE, + UNICAST_ADDRESS); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_HDR_NBDS, + 1); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd; + pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); @@ -1578,9 +1582,9 @@ static int bnx2x_test_intr(struct bnx2x *bp) bp->set_mac_pending++; smp_wmb(); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); if (rc == 0) { for (i = 0; i < 10; i++) { if (!bp->set_mac_pending) diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h index 08d71bf438d6..f4e5b1ce8149 100644 --- a/drivers/net/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x/bnx2x_fw_defs.h @@ -7,369 +7,272 @@ * the Free Software Foundation. */ - -#define CSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x7000 : 0x1000) -#define CSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8622 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100) + (index * 0x4)) : (0x3562 + (function * \ - 0x40) + (index * 0x4))) -#define CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8822 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200) + (index * 0x4)) : (0x35e2 + (function * \ - 0x80) + (index * 0x4))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8600 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3540 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8800 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c0 + (function * 0x80))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8608 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3548 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8808 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c8 + (function * 0x80))) -#define CSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff) -#define CSTORM_HC_BTR_C_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8c04 + (port * 0xf0)) : (0x36c4 + (port * 0xc0))) -#define CSTORM_HC_BTR_U_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8de4 + (port * 0xf0)) : (0x3844 + (port * 0xc0))) -#define CSTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6680 + (function * 0x8)) : (0x25a0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x66c0 + (function * 0x8)) : (0x25b0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_EQ_CONS_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2410 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2414 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x604c + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x241c + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6057 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2427 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_PROD_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2412 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6056 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2426 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6054 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2424 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6640 + (function * 0x8)) : (0x2590 + \ - (function * 0x8))) -#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define CSTORM_SB_HC_DISABLE_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x811a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x305a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_DISABLE_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb01a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x401a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x8118 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x3058 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x4018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8100 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3040 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb000 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4000 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8108 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3048 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb008 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4008 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_STATUS_BLOCK_C_SIZE 0x10 -#define CSTORM_SB_STATUS_BLOCK_U_SIZE 0x60 -#define CSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \ - (function * 0x8))) -#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3200 + (function * 0x20)) : 0xffffffff) -#define TSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0xa000 : 0x1000) -#define TSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x33a0 + (port * 0x1a0) + (client_id * 0x10)) \ - : (0x9c0 + (port * 0x120) + (client_id * 0x10))) -#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed8 : 0xffffffff) +#ifndef BNX2X_FW_DEFS_H +#define BNX2X_FW_DEFS_H + +#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[142].base) +#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[141].base + ((assertListEntry) * IRO[141].m1)) +#define CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[144].base + ((pfId) * IRO[144].m1)) +#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \ + (IRO[149].base + (((pfId)>>1) * IRO[149].m1) + (((pfId)&1) * \ + IRO[149].m2)) +#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \ + (IRO[150].base + (((pfId)>>1) * IRO[150].m1) + (((pfId)&1) * \ + IRO[150].m2)) +#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \ + (IRO[156].base + ((funcId) * IRO[156].m1)) +#define CSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[146].base + ((funcId) * IRO[146].m1)) +#define CSTORM_FUNCTION_MODE_OFFSET (IRO[153].base) +#define CSTORM_IGU_MODE_OFFSET (IRO[154].base) +#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[311].base + ((pfId) * IRO[311].m1)) +#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[312].base + ((pfId) * IRO[312].m1)) + #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ + (IRO[304].base + ((pfId) * IRO[304].m1) + ((iscsiEqId) * \ + IRO[304].m2)) + #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[306].base + ((pfId) * IRO[306].m1) + ((iscsiEqId) * \ + IRO[306].m2)) + #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[305].base + ((pfId) * IRO[305].m1) + ((iscsiEqId) * \ + IRO[305].m2)) + #define \ + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ + (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * \ + IRO[307].m2)) + #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ + (IRO[303].base + ((pfId) * IRO[303].m1) + ((iscsiEqId) * \ + IRO[303].m2)) + #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * \ + IRO[309].m2)) + #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ + (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * \ + IRO[308].m2)) +#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[310].base + ((pfId) * IRO[310].m1)) +#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[302].base + ((pfId) * IRO[302].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[301].base + ((pfId) * IRO[301].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[300].base + ((pfId) * IRO[300].m1)) +#define CSTORM_PATH_ID_OFFSET (IRO[159].base) +#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ + (IRO[137].base + ((pfId) * IRO[137].m1)) +#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \ + (IRO[136].base + ((pfId) * IRO[136].m1)) +#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[136].size) +#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \ + (IRO[138].base + ((pfId) * IRO[138].m1)) +#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[138].size) +#define CSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[143].base + ((pfId) * IRO[143].m1)) +#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \ + (IRO[129].base + ((sbId) * IRO[129].m1)) +#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \ + (IRO[128].base + ((sbId) * IRO[128].m1)) +#define CSTORM_STATUS_BLOCK_SIZE (IRO[128].size) +#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \ + (IRO[132].base + ((sbId) * IRO[132].m1)) +#define CSTORM_SYNC_BLOCK_SIZE (IRO[132].size) +#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \ + (IRO[151].base + ((vfId) * IRO[151].m1)) +#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \ + (IRO[152].base + ((vfId) * IRO[152].m1)) +#define CSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[147].base + ((funcId) * IRO[147].m1)) +#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[199].base) +#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ + (IRO[198].base + ((pfId) * IRO[198].m1)) +#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[99].base) +#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[98].base + ((assertListEntry) * IRO[98].m1)) + #define TSTORM_CLIENT_CONFIG_OFFSET(portId, clientId) \ + (IRO[197].base + ((portId) * IRO[197].m1) + ((clientId) * \ + IRO[197].m2)) +#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[104].base) #define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \ - (IS_E1H_OFFSET ? 0x1eda : 0xffffffff) -#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2940 + (function * 0x8)) : (0x4928 + \ - (function * 0x8))) -#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3000 + (function * 0x40)) : (0x1500 + \ - (function * 0x40))) -#define TSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed0 : 0xffffffff) -#define TSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \ - (function * 0x80))) -#define TSTORM_INDIRECTION_TABLE_SIZE 0x80 -#define TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(function, pblEntry) \ - (IS_E1H_OFFSET ? (0x60c0 + (function * 0x40) + (pblEntry * 0x8)) \ - : (0x4c30 + (function * 0x40) + (pblEntry * 0x8))) -#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6340 + (function * 0x8)) : (0x4cd0 + \ - (function * 0x8))) -#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x4c04 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x4c02 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x4c00 + \ - (function * 0x8))) -#define TSTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6080 + (function * 0x8)) : (0x4c20 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0x8)) : (0x4c10 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0x8)) : (0x4c12 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0x8)) : (0x4c14 + \ - (function * 0x8))) -#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3008 + (function * 0x40)) : (0x1508 + \ - (function * 0x40))) -#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2010 + (port * 0x490) + (stats_counter_id * \ - 0x40)) : (0x4010 + (port * 0x490) + (stats_counter_id * 0x40))) -#define TSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29c0 + (function * 0x8)) : (0x4948 + \ - (function * 0x8))) -#define TSTORM_TCP_MAX_CWND_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4004 + (function * 0x8)) : (0x1fb4 + \ - (function * 0x8))) -#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa000 : 0x3000) -#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2000 : 0x1000) -#define USTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x8000 : 0x1000) -#define USTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1010 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4010 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_CQE_PAGE_NEXT_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1028 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4028 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_ETH_PAUSE_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff) -#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1030 + (port * 0x680) + (clientId * 0x40)) : \ - 0xffffffff) -#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1dd0 + \ - (function * 0x8))) -#define USTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2448 : 0xffffffff) -#define USTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7044 + (function * 0x8)) : (0x2414 + \ - (function * 0x8))) -#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7046 + (function * 0x8)) : (0x2416 + \ - (function * 0x8))) -#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7688 + (function * 0x8)) : (0x29c8 + \ - (function * 0x8))) -#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7648 + (function * 0x8)) : (0x29b8 + \ - (function * 0x8))) -#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7040 + (function * 0x8)) : (0x2410 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7080 + (function * 0x8)) : (0x2420 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7084 + (function * 0x8)) : (0x2424 + \ - (function * 0x8))) -#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1018 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4018 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x1da8 + \ - (function * 0x8))) -#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \ - 0x28)) : (0x1500 + (port * 0x2d0) + (stats_counter_id * 0x28))) -#define USTORM_RX_PRODS_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \ - : (0x4000 + (port * 0x360) + (client_id * 0x30))) -#define USTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1db8 + \ - (function * 0x8))) -#define USTORM_TPA_BTR_OFFSET (IS_E1H_OFFSET ? 0x3da5 : 0x5095) -#define USTORM_TPA_BTR_SIZE 0x1 -#define XSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x9000 : 0x1000) -#define XSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3a80 + (port * 0x50))) -#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define XSTORM_E1HOV_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2c10 + (function * 0x8)) : 0xffffffff) -#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3a50 + \ - (function * 0x8))) -#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3b60 + \ - (function * 0x90))) -#define XSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2c50 : 0xffffffff) -#define XSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define XSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c0 + (function * 0x8)) : (0x1c30 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8080 + (function * 0x8)) : (0x1c20 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8081 + (function * 0x8)) : (0x1c21 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8082 + (function * 0x8)) : (0x1c22 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8083 + (function * 0x8)) : (0x1c23 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8084 + (function * 0x8)) : (0x1c24 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8085 + (function * 0x8)) : (0x1c25 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8086 + (function * 0x8)) : (0x1c26 + \ - (function * 0x8))) -#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8004 + (function * 0x8)) : (0x1c04 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8002 + (function * 0x8)) : (0x1c02 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8000 + (function * 0x8)) : (0x1c00 + \ - (function * 0x8))) -#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c4 + (function * 0x8)) : (0x1c34 + \ - (function * 0x8))) -#define XSTORM_ISCSI_SQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c2 + (function * 0x8)) : (0x1c32 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8043 + (function * 0x8)) : (0x1c13 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8042 + (function * 0x8)) : (0x1c12 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8041 + (function * 0x8)) : (0x1c11 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8040 + (function * 0x8)) : (0x1c10 + \ - (function * 0x8))) -#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0xc000 + (port * 0x360) + (stats_counter_id * \ - 0x30)) : (0x3378 + (port * 0x360) + (stats_counter_id * 0x30))) -#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3b20 + \ - (function * 0x90))) -#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \ - (function * 0x10))) -#define XSTORM_SPQ_PROD_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \ - (function * 0x10))) -#define XSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3a40 + \ - (function * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4000 + (port * 0x8)) : (0x1960 + (port * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4001 + (port * 0x8)) : (0x1961 + (port * 0x8))) -#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4060 + ((function>>1) * 0x8) + ((function&1) \ - * 0x4)) : (0x1978 + (function * 0x4))) + (IRO[105].base) +#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[96].base + ((pfId) * IRO[96].m1)) +#define TSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[101].base + ((funcId) * IRO[101].m1)) +#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \ + (IRO[195].base + ((pfId) * IRO[195].m1)) +#define TSTORM_FUNCTION_MODE_OFFSET (IRO[103].base) +#define TSTORM_INDIRECTION_TABLE_OFFSET(pfId) \ + (IRO[91].base + ((pfId) * IRO[91].m1)) +#define TSTORM_INDIRECTION_TABLE_SIZE (IRO[91].size) + #define \ + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfId, iscsiConBufPblEntry) \ + (IRO[260].base + ((pfId) * IRO[260].m1) + ((iscsiConBufPblEntry) \ + * IRO[260].m2)) +#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[264].base + ((pfId) * IRO[264].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \ + (IRO[265].base + ((pfId) * IRO[265].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \ + (IRO[266].base + ((pfId) * IRO[266].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \ + (IRO[267].base + ((pfId) * IRO[267].m1)) +#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[263].base + ((pfId) * IRO[263].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[262].base + ((pfId) * IRO[262].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[261].base + ((pfId) * IRO[261].m1)) +#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[259].base + ((pfId) * IRO[259].m1)) +#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ + (IRO[269].base + ((pfId) * IRO[269].m1)) +#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[256].base + ((pfId) * IRO[256].m1)) +#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[257].base + ((pfId) * IRO[257].m1)) +#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[258].base + ((pfId) * IRO[258].m1)) +#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \ + (IRO[196].base + ((pfId) * IRO[196].m1)) + #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, tStatCntId) \ + (IRO[100].base + ((portId) * IRO[100].m1) + ((tStatCntId) * \ + IRO[100].m2)) +#define TSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[95].base + ((pfId) * IRO[95].m1)) +#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \ + (IRO[211].base + ((pfId) * IRO[211].m1)) +#define TSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[102].base + ((funcId) * IRO[102].m1)) +#define USTORM_AGG_DATA_OFFSET (IRO[201].base) +#define USTORM_AGG_DATA_SIZE (IRO[201].size) +#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[170].base) +#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[169].base + ((assertListEntry) * IRO[169].m1)) +#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ + (IRO[178].base + ((portId) * IRO[178].m1)) +#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[172].base + ((pfId) * IRO[172].m1)) +#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ + (IRO[313].base + ((pfId) * IRO[313].m1)) +#define USTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[174].base + ((funcId) * IRO[174].m1)) +#define USTORM_FUNCTION_MODE_OFFSET (IRO[177].base) +#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[277].base + ((pfId) * IRO[277].m1)) +#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[278].base + ((pfId) * IRO[278].m1)) +#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[282].base + ((pfId) * IRO[282].m1)) +#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ + (IRO[279].base + ((pfId) * IRO[279].m1)) +#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[275].base + ((pfId) * IRO[275].m1)) +#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[274].base + ((pfId) * IRO[274].m1)) +#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[273].base + ((pfId) * IRO[273].m1)) +#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[276].base + ((pfId) * IRO[276].m1)) +#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ + (IRO[280].base + ((pfId) * IRO[280].m1)) +#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[281].base + ((pfId) * IRO[281].m1)) +#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ + (IRO[176].base + ((pfId) * IRO[176].m1)) + #define USTORM_PER_COUNTER_ID_STATS_OFFSET(portId, uStatCntId) \ + (IRO[173].base + ((portId) * IRO[173].m1) + ((uStatCntId) * \ + IRO[173].m2)) + #define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \ + (IRO[204].base + ((portId) * IRO[204].m1) + ((clientId) * \ + IRO[204].m2)) +#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \ + (IRO[205].base + ((qzoneId) * IRO[205].m1)) +#define USTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[171].base + ((pfId) * IRO[171].m1)) +#define USTORM_TPA_BTR_OFFSET (IRO[202].base) +#define USTORM_TPA_BTR_SIZE (IRO[202].size) +#define USTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[175].base + ((funcId) * IRO[175].m1)) +#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[59].base) +#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[58].base) +#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[54].base) +#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[53].base + ((assertListEntry) * IRO[53].m1)) +#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \ + (IRO[47].base + ((portId) * IRO[47].m1)) +#define XSTORM_E1HOV_OFFSET(pfId) \ + (IRO[55].base + ((pfId) * IRO[55].m1)) +#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[45].base + ((pfId) * IRO[45].m1)) +#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \ + (IRO[49].base + ((pfId) * IRO[49].m1)) +#define XSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[51].base + ((funcId) * IRO[51].m1)) +#define XSTORM_FUNCTION_MODE_OFFSET (IRO[56].base) +#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[290].base + ((pfId) * IRO[290].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ + (IRO[293].base + ((pfId) * IRO[293].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ + (IRO[294].base + ((pfId) * IRO[294].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ + (IRO[295].base + ((pfId) * IRO[295].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ + (IRO[296].base + ((pfId) * IRO[296].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ + (IRO[297].base + ((pfId) * IRO[297].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ + (IRO[298].base + ((pfId) * IRO[298].m1)) +#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ + (IRO[299].base + ((pfId) * IRO[299].m1)) +#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[289].base + ((pfId) * IRO[289].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[288].base + ((pfId) * IRO[288].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[287].base + ((pfId) * IRO[287].m1)) +#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[292].base + ((pfId) * IRO[292].m1)) +#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ + (IRO[291].base + ((pfId) * IRO[291].m1)) +#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ + (IRO[286].base + ((pfId) * IRO[286].m1)) +#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[285].base + ((pfId) * IRO[285].m1)) +#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ + (IRO[284].base + ((pfId) * IRO[284].m1)) +#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ + (IRO[283].base + ((pfId) * IRO[283].m1)) +#define XSTORM_PATH_ID_OFFSET (IRO[65].base) + #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, xStatCntId) \ + (IRO[50].base + ((portId) * IRO[50].m1) + ((xStatCntId) * \ + IRO[50].m2)) +#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ + (IRO[48].base + ((pfId) * IRO[48].m1)) +#define XSTORM_SPQ_DATA_OFFSET(funcId) \ + (IRO[32].base + ((funcId) * IRO[32].m1)) +#define XSTORM_SPQ_DATA_SIZE (IRO[32].size) +#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \ + (IRO[30].base + ((funcId) * IRO[30].m1)) +#define XSTORM_SPQ_PROD_OFFSET(funcId) \ + (IRO[31].base + ((funcId) * IRO[31].m1)) +#define XSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[43].base + ((pfId) * IRO[43].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \ + (IRO[206].base + ((portId) * IRO[206].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \ + (IRO[207].base + ((portId) * IRO[207].m1)) +#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \ + (IRO[209].base + (((pfId)>>1) * IRO[209].m1) + (((pfId)&1) * \ + IRO[209].m2)) +#define XSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[52].base + ((funcId) * IRO[52].m1)) #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 -/** -* This file defines HSI constants for the ETH flow -*/ -#ifdef _EVEREST_MICROCODE -#include "microcode_constants.h" -#include "eth_rx_bd.h" -#include "eth_tx_bd.h" -#include "eth_rx_cqe.h" -#include "eth_rx_sge.h" -#include "eth_rx_cqe_next_page.h" -#endif - /* RSS hash types */ #define DEFAULT_HASH_TYPE 0 #define IPV4_HASH_TYPE 1 @@ -389,11 +292,17 @@ #define U_ETH_NUM_OF_SGES_TO_FETCH 8 #define U_ETH_MAX_SGES_FOR_PACKET 3 +/*Tx params*/ +#define X_ETH_NO_VLAN 0 +#define X_ETH_OUTBAND_VLAN 1 +#define X_ETH_INBAND_VLAN 2 /* Rx ring params */ #define U_ETH_LOCAL_BD_RING_SIZE 8 #define U_ETH_LOCAL_SGE_RING_SIZE 10 #define U_ETH_SGL_SIZE 8 - + /* The fw will padd the buffer with this value, so the IP header \ + will be align to 4 Byte */ +#define IP_HEADER_ALIGNMENT_PADDING 2 #define U_ETH_SGES_PER_PAGE_INVERSE_MASK \ (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1)) @@ -409,16 +318,15 @@ #define U_ETH_UNDEFINED_Q 0xFF /* values of command IDs in the ramrod message */ -#define RAMROD_CMD_ID_ETH_PORT_SETUP 80 -#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85 -#define RAMROD_CMD_ID_ETH_STAT_QUERY 90 -#define RAMROD_CMD_ID_ETH_UPDATE 100 -#define RAMROD_CMD_ID_ETH_HALT 105 -#define RAMROD_CMD_ID_ETH_SET_MAC 110 -#define RAMROD_CMD_ID_ETH_CFC_DEL 115 -#define RAMROD_CMD_ID_ETH_PORT_DEL 120 -#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125 - +#define RAMROD_CMD_ID_ETH_UNUSED 0 +#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 1 +#define RAMROD_CMD_ID_ETH_UPDATE 2 +#define RAMROD_CMD_ID_ETH_HALT 3 +#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 4 +#define RAMROD_CMD_ID_ETH_ACTIVATE 5 +#define RAMROD_CMD_ID_ETH_DEACTIVATE 6 +#define RAMROD_CMD_ID_ETH_EMPTY 7 +#define RAMROD_CMD_ID_ETH_TERMINATE 8 /* command values for set mac command */ #define T_ETH_MAC_COMMAND_SET 0 @@ -431,7 +339,9 @@ /* Maximal L2 clients supported */ #define ETH_MAX_RX_CLIENTS_E1 18 -#define ETH_MAX_RX_CLIENTS_E1H 26 +#define ETH_MAX_RX_CLIENTS_E1H 28 + +#define MAX_STAT_COUNTER_ID ETH_MAX_RX_CLIENTS_E1H /* Maximal aggregation queues supported */ #define ETH_MAX_AGGREGATION_QUEUES_E1 32 @@ -443,6 +353,20 @@ #define ETH_RSS_MODE_VLAN_PRI 2 #define ETH_RSS_MODE_E1HOV_PRI 3 #define ETH_RSS_MODE_IP_DSCP 4 +#define ETH_RSS_MODE_E2_INTEG 5 + + +/* ETH vlan filtering modes */ +#define ETH_VLAN_FILTER_ANY_VLAN 0 /* Don't filter by vlan */ +#define ETH_VLAN_FILTER_SPECIFIC_VLAN \ + 1 /* Only the vlan_id is allowed */ +#define ETH_VLAN_FILTER_CLASSIFY \ + 2 /* vlan will be added to CAM for classification */ + +/* Fast path CQE selection */ +#define ETH_FP_CQE_REGULAR 0 +#define ETH_FP_CQE_SGL 1 +#define ETH_FP_CQE_RAW 2 /** @@ -458,6 +382,7 @@ #define RESERVED_CONNECTION_TYPE_0 5 #define RESERVED_CONNECTION_TYPE_1 6 #define RESERVED_CONNECTION_TYPE_2 7 +#define NONE_CONNECTION_TYPE 8 #define PROTOCOL_STATE_BIT_OFFSET 6 @@ -466,6 +391,16 @@ #define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) #define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) +/* values of command IDs in the ramrod message */ +#define RAMROD_CMD_ID_COMMON_FUNCTION_START 1 +#define RAMROD_CMD_ID_COMMON_FUNCTION_STOP 2 +#define RAMROD_CMD_ID_COMMON_CFC_DEL 3 +#define RAMROD_CMD_ID_COMMON_CFC_DEL_WB 4 +#define RAMROD_CMD_ID_COMMON_SET_MAC 5 +#define RAMROD_CMD_ID_COMMON_STAT_QUERY 6 +#define RAMROD_CMD_ID_COMMON_STOP_TRAFFIC 7 +#define RAMROD_CMD_ID_COMMON_START_TRAFFIC 8 + /* microcode fixed page page size 4K (chains and ring segments) */ #define MC_PAGE_SIZE 4096 @@ -473,46 +408,26 @@ /* Host coalescing constants */ #define HC_IGU_BC_MODE 0 #define HC_IGU_NBC_MODE 1 +/* Host coalescing constants. E1 includes E1H as well */ + +/* Number of indices per slow-path SB */ +#define HC_SP_SB_MAX_INDICES 16 + +/* Number of indices per SB */ +#define HC_SB_MAX_INDICES_E1X 8 +#define HC_SB_MAX_INDICES_E2 8 + +#define HC_SB_MAX_SB_E1X 32 +#define HC_SB_MAX_SB_E2 136 + +#define HC_SP_SB_ID 0xde #define HC_REGULAR_SEGMENT 0 #define HC_DEFAULT_SEGMENT 1 +#define HC_SB_MAX_SM 2 -/* index numbers */ -#define HC_USTORM_DEF_SB_NUM_INDICES 8 -#define HC_CSTORM_DEF_SB_NUM_INDICES 8 -#define HC_XSTORM_DEF_SB_NUM_INDICES 4 -#define HC_TSTORM_DEF_SB_NUM_INDICES 4 -#define HC_USTORM_SB_NUM_INDICES 4 -#define HC_CSTORM_SB_NUM_INDICES 4 - -/* index values - which counter to update */ - -#define HC_INDEX_U_TOE_RX_CQ_CONS 0 -#define HC_INDEX_U_ETH_RX_CQ_CONS 1 -#define HC_INDEX_U_ETH_RX_BD_CONS 2 -#define HC_INDEX_U_FCOE_EQ_CONS 3 - -#define HC_INDEX_C_TOE_TX_CQ_CONS 0 -#define HC_INDEX_C_ETH_TX_CQ_CONS 1 -#define HC_INDEX_C_ISCSI_EQ_CONS 2 - -#define HC_INDEX_DEF_X_SPQ_CONS 0 - -#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0 -#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1 -#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2 -#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3 -#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4 -#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5 -#define HC_INDEX_DEF_C_ETH_FCOE_CQ_CONS 6 - -#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1 -#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_CQ_CONS 4 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_BD_CONS 5 - +#define HC_SB_MAX_DYNAMIC_INDICES 4 +#define HC_FUNCTION_DISABLED 0xff /* used by the driver to get the SB offset */ #define USTORM_ID 0 #define CSTORM_ID 1 @@ -529,45 +444,17 @@ /**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ -#define EMULATION_FREQUENCY_FACTOR 1600 -#define FPGA_FREQUENCY_FACTOR 100 #define TIMERS_TICK_SIZE_CHIP (1e-3) -#define TIMERS_TICK_SIZE_EMUL \ - ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR))) -#define TIMERS_TICK_SIZE_FPGA \ - ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR))) #define TSEMI_CLK1_RESUL_CHIP (1e-3) -#define TSEMI_CLK1_RESUL_EMUL \ - ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define TSEMI_CLK1_RESUL_FPGA \ - ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP) -#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL) -#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA) #define XSEMI_CLK1_RESUL_CHIP (1e-3) -#define XSEMI_CLK1_RESUL_EMUL \ - ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK1_RESUL_FPGA \ - ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define XSEMI_CLK2_RESUL_CHIP (1e-6) -#define XSEMI_CLK2_RESUL_EMUL \ - ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK2_RESUL_FPGA \ - ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) #define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6)) -#define SDM_TIMER_TICK_RESUL_EMUL \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define SDM_TIMER_TICK_RESUL_FPGA \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - /**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ + #define XSTORM_IP_ID_ROLL_HALF 0x8000 #define XSTORM_IP_ID_ROLL_ALL 0 @@ -576,10 +463,36 @@ #define NUM_OF_PROTOCOLS 4 #define NUM_OF_SAFC_BITS 16 #define MAX_COS_NUMBER 4 -#define MAX_T_STAT_COUNTER_ID 18 -#define MAX_X_STAT_COUNTER_ID 18 -#define MAX_U_STAT_COUNTER_ID 18 +#define FAIRNESS_COS_WRR_MODE 0 +#define FAIRNESS_COS_ETS_MODE 1 + + +/* Priority Flow Control (PFC) */ +#define MAX_PFC_PRIORITIES 8 +#define MAX_PFC_TRAFFIC_TYPES 8 + +/* Available Traffic Types for Link Layer Flow Control */ +#define LLFC_TRAFFIC_TYPE_NW 0 +#define LLFC_TRAFFIC_TYPE_FCOE 1 +#define LLFC_TRAFFIC_TYPE_ISCSI 2 + /***************** START OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_NW_COS1_E2INTEG 3 + /***************** END OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_MAX 4 + + /* used by array traffic_type_to_priority[] to mark traffic type \ + that is not mapped to priority*/ +#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF + +#define LLFC_MODE_NONE 0 +#define LLFC_MODE_PFC 1 +#define LLFC_MODE_SAFC 2 + +#define DCB_DISABLED 0 +#define DCB_ENABLED 1 #define UNKNOWN_ADDRESS 0 #define UNICAST_ADDRESS 1 @@ -587,8 +500,32 @@ #define BROADCAST_ADDRESS 3 #define SINGLE_FUNCTION 0 -#define MULTI_FUNCTION 1 +#define MULTI_FUNCTION_SD 1 +#define MULTI_FUNCTION_SI 2 #define IP_V4 0 #define IP_V6 1 + +#define C_ERES_PER_PAGE \ + (PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem))) +#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1) + +#define EVENT_RING_OPCODE_VF_PF_CHANNEL 0 +#define EVENT_RING_OPCODE_FUNCTION_START 1 +#define EVENT_RING_OPCODE_FUNCTION_STOP 2 +#define EVENT_RING_OPCODE_CFC_DEL 3 +#define EVENT_RING_OPCODE_CFC_DEL_WB 4 +#define EVENT_RING_OPCODE_SET_MAC 5 +#define EVENT_RING_OPCODE_STAT_QUERY 6 +#define EVENT_RING_OPCODE_STOP_TRAFFIC 7 +#define EVENT_RING_OPCODE_START_TRAFFIC 8 +#define EVENT_RING_OPCODE_FORWARD_SETUP 9 + +#define VF_PF_CHANNEL_STATE_READY 0 +#define VF_PF_CHANNEL_STATE_WAITING_FOR_ACK 1 + +#define VF_PF_CHANNEL_STATE_MAX_NUMBER 2 + + +#endif /* BNX2X_FW_DEFS_H */ diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h index 3f5ee5d7cc2a..f807262911e5 100644 --- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h +++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h @@ -31,6 +31,7 @@ struct bnx2x_fw_file_hdr { struct bnx2x_fw_file_section csem_pram_data; struct bnx2x_fw_file_section xsem_int_table_data; struct bnx2x_fw_file_section xsem_pram_data; + struct bnx2x_fw_file_section iro_arr; struct bnx2x_fw_file_section fw_version; }; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 60d141cd9950..596041cbd977 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -6,6 +6,10 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. */ +#ifndef BNX2X_HSI_H +#define BNX2X_HSI_H + +#include "bnx2x_fw_defs.h" struct license_key { u32 reserved[6]; @@ -326,6 +330,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u32 lane_config; #define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff #define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT 0 + #define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK 0x000000ff #define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT 0 #define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK 0x0000ff00 @@ -1016,11 +1021,12 @@ struct shmem_region { /* SharedMem Offset (size) */ struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ - struct drv_func_mb func_mb[E1H_FUNC_MAX]; + struct drv_func_mb func_mb[]; /* 0x684 + (44*2/4/8=0x58/0xb0/0x160) */ + +}; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ - struct mf_cfg mf_cfg; -}; /* 0x6dc */ struct shmem2_region { @@ -1096,7 +1102,7 @@ struct emac_stats { }; -struct bmac_stats { +struct bmac1_stats { u32 tx_stat_gtpkt_lo; u32 tx_stat_gtpkt_hi; u32 tx_stat_gtxpf_lo; @@ -1202,8 +1208,8 @@ struct bmac_stats { union mac_stats { - struct emac_stats emac_stats; - struct bmac_stats bmac_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; }; @@ -1377,17 +1383,17 @@ struct host_func_stats { }; -#define BCM_5710_FW_MAJOR_VERSION 5 -#define BCM_5710_FW_MINOR_VERSION 2 -#define BCM_5710_FW_REVISION_VERSION 13 -#define BCM_5710_FW_ENGINEERING_VERSION 0 +#define BCM_5710_FW_MAJOR_VERSION 6 +#define BCM_5710_FW_MINOR_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 34 +#define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 /* * attention bits */ -struct atten_def_status_block { +struct atten_sp_status_block { __le32 attn_bits; __le32 attn_bits_ack; u8 status_block_id; @@ -1445,7 +1451,60 @@ struct doorbell_set_prod { /* - * IGU driver acknowledgement register + * 3 lines. status block + */ +struct hc_status_block_e1x { + __le16 index_values[HC_SB_MAX_INDICES_E1X]; + __le16 running_index[HC_SB_MAX_SM]; + u32 rsrv; +}; + +/* + * host status block + */ +struct host_hc_status_block_e1x { + struct hc_status_block_e1x sb; +}; + + +/* + * 3 lines. status block + */ +struct hc_status_block_e2 { + __le16 index_values[HC_SB_MAX_INDICES_E2]; + __le16 running_index[HC_SB_MAX_SM]; + u32 reserved; +}; + +/* + * host status block + */ +struct host_hc_status_block_e2 { + struct hc_status_block_e2 sb; +}; + + +/* + * 5 lines. slow-path status block + */ +struct hc_sp_status_block { + __le16 index_values[HC_SP_SB_MAX_INDICES]; + __le16 running_index; + __le16 rsrv; + u32 rsrv1; +}; + +/* + * host status block + */ +struct host_sp_status_block { + struct atten_sp_status_block atten_status_block; + struct hc_sp_status_block sp_sb; +}; + + +/* + * IGU driver acknowledgment register */ struct igu_ack_register { #if defined(__BIG_ENDIAN) @@ -1603,8 +1662,14 @@ struct dmae_command { #define DMAE_COMMAND_DST_RESET_SHIFT 14 #define DMAE_COMMAND_E1HVN (0x3<<15) #define DMAE_COMMAND_E1HVN_SHIFT 15 -#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17) -#define DMAE_COMMAND_RESERVED0_SHIFT 17 +#define DMAE_COMMAND_DST_VN (0x3<<17) +#define DMAE_COMMAND_DST_VN_SHIFT 17 +#define DMAE_COMMAND_C_FUNC (0x1<<19) +#define DMAE_COMMAND_C_FUNC_SHIFT 19 +#define DMAE_COMMAND_ERR_POLICY (0x3<<20) +#define DMAE_COMMAND_ERR_POLICY_SHIFT 20 +#define DMAE_COMMAND_RESERVED0 (0x3FF<<22) +#define DMAE_COMMAND_RESERVED0_SHIFT 22 u32 src_addr_lo; u32 src_addr_hi; u32 dst_addr_lo; @@ -1629,11 +1694,11 @@ struct dmae_command { u16 crc16_c; #endif #if defined(__BIG_ENDIAN) - u16 reserved2; + u16 reserved3; u16 crc_t10; #elif defined(__LITTLE_ENDIAN) u16 crc_t10; - u16 reserved2; + u16 reserved3; #endif #if defined(__BIG_ENDIAN) u16 xsum8; @@ -1654,96 +1719,20 @@ struct double_regpair { /* - * The eth storm context of Ustorm (configuration part) + * SDM operation gen command (generate aggregative interrupt) */ -struct ustorm_eth_st_context_config { -#if defined(__BIG_ENDIAN) - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 - u8 status_block_id; - u8 clientId; - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 -#elif defined(__LITTLE_ENDIAN) - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 - u8 clientId; - u8 status_block_id; - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 -#endif -#if defined(__BIG_ENDIAN) - u16 bd_buff_size; - u8 statistics_counter_id; - u8 mc_alignment_log_size; -#elif defined(__LITTLE_ENDIAN) - u8 mc_alignment_log_size; - u8 statistics_counter_id; - u16 bd_buff_size; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_sge_prod; - u8 __local_bd_prod; - u16 sge_buff_size; -#elif defined(__LITTLE_ENDIAN) - u16 sge_buff_size; - u8 __local_bd_prod; - u8 __local_sge_prod; -#endif -#if defined(__BIG_ENDIAN) - u16 __sdm_bd_expected_counter; - u8 cstorm_agg_int; - u8 __expected_bds_on_ram; -#elif defined(__LITTLE_ENDIAN) - u8 __expected_bds_on_ram; - u8 cstorm_agg_int; - u16 __sdm_bd_expected_counter; -#endif -#if defined(__BIG_ENDIAN) - u16 __ring_data_ram_addr; - u16 __hc_cstorm_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __hc_cstorm_ram_addr; - u16 __ring_data_ram_addr; -#endif -#if defined(__BIG_ENDIAN) - u8 reserved1; - u8 max_sges_for_packet; - u16 __bd_ring_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ring_ram_addr; - u8 max_sges_for_packet; - u8 reserved1; -#endif - u32 bd_page_base_lo; - u32 bd_page_base_hi; - u32 sge_page_base_lo; - u32 sge_page_base_hi; - struct regpair reserved2; +struct sdm_op_gen { + __le32 command; +#define SDM_OP_GEN_COMP_PARAM (0x1F<<0) +#define SDM_OP_GEN_COMP_PARAM_SHIFT 0 +#define SDM_OP_GEN_COMP_TYPE (0x7<<5) +#define SDM_OP_GEN_COMP_TYPE_SHIFT 5 +#define SDM_OP_GEN_AGG_VECT_IDX (0xFF<<8) +#define SDM_OP_GEN_AGG_VECT_IDX_SHIFT 8 +#define SDM_OP_GEN_AGG_VECT_IDX_VALID (0x1<<16) +#define SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT 16 +#define SDM_OP_GEN_RESERVED (0x7FFF<<17) +#define SDM_OP_GEN_RESERVED_SHIFT 17 }; /* @@ -1762,20 +1751,13 @@ struct eth_rx_sge { __le32 addr_hi; }; -/* - * Local BDs and SGEs rings (in ETH) - */ -struct eth_local_rx_rings { - struct eth_rx_bd __local_bd_ring[8]; - struct eth_rx_sge __local_sge_ring[10]; -}; + /* * The eth storm context of Ustorm */ struct ustorm_eth_st_context { - struct ustorm_eth_st_context_config common; - struct eth_local_rx_rings __rings; + u32 reserved0[48]; }; /* @@ -1785,338 +1767,54 @@ struct tstorm_eth_st_context { u32 __reserved0[28]; }; -/* - * The eth aggregative context section of Xstorm - */ -struct xstorm_eth_extra_ag_context_section { -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars1; - u8 __reserved50; - u16 __mss; -#elif defined(__LITTLE_ENDIAN) - u16 __mss; - u8 __reserved50; - u8 __tcp_agg_vars1; -#endif - u32 __snd_nxt; - u32 __tx_wnd; - u32 __snd_una; - u32 __reserved53; -#if defined(__BIG_ENDIAN) - u8 __agg_val8_th; - u8 __agg_val8; - u16 __tcp_agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars2; - u8 __agg_val8; - u8 __agg_val8_th; -#endif - u32 __reserved58; - u32 __reserved59; - u32 __reserved60; - u32 __reserved61; -#if defined(__BIG_ENDIAN) - u16 __agg_val7_th; - u16 __agg_val7; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val7; - u16 __agg_val7_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars5; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars3; - u8 __reserved62; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved62; - u8 __tcp_agg_vars3; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars5; -#endif - u32 __tcp_agg_vars6; -#if defined(__BIG_ENDIAN) - u16 __agg_misc6; - u16 __tcp_agg_vars7; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars7; - u16 __agg_misc6; -#endif - u32 __agg_val10; - u32 __agg_val10_th; -#if defined(__BIG_ENDIAN) - u16 __reserved3; - u8 __reserved2; - u8 __da_only_cnt; -#elif defined(__LITTLE_ENDIAN) - u8 __da_only_cnt; - u8 __reserved2; - u16 __reserved3; -#endif -}; - /* * The eth aggregative context of Xstorm */ struct xstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 agg_val1; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 agg_val1; -#endif + u32 reserved0; #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 __agg_vars4; - u8 __agg_vars3; - u8 __agg_vars2; + u8 reserved2; + u16 reserved1; #elif defined(__LITTLE_ENDIAN) - u8 __agg_vars2; - u8 __agg_vars3; - u8 __agg_vars4; + u16 reserved1; + u8 reserved2; u8 cdu_reserved; #endif - u32 __bd_prod; -#if defined(__BIG_ENDIAN) - u16 __agg_vars5; - u16 __agg_val4_th; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4_th; - u16 __agg_vars5; -#endif - struct xstorm_eth_extra_ag_context_section __extra_section; -#if defined(__BIG_ENDIAN) - u16 __agg_vars7; - u8 __agg_val3_th; - u8 __agg_vars6; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_vars6; - u8 __agg_val3_th; - u16 __agg_vars7; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val11_th; - u16 __agg_val11; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; - u16 __agg_val11_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved1; - u8 __agg_val6_th; - u16 __agg_val9; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val9; - u8 __agg_val6_th; - u8 __reserved1; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif - u32 __agg_vars8; -#if defined(__BIG_ENDIAN) - u16 __agg_misc0; - u16 __agg_val4; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4; - u16 __agg_misc0; -#endif -#if defined(__BIG_ENDIAN) - u8 __agg_val3; - u8 __agg_val6; - u8 __agg_val5_th; - u8 __agg_val5; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_val5; - u8 __agg_val5_th; - u8 __agg_val6; - u8 __agg_val3; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_misc1; - u16 __bd_ind_max_val; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ind_max_val; - u16 __agg_misc1; -#endif - u32 __reserved57; - u32 __agg_misc4; - u32 __agg_misc5; -}; - -/* - * The eth extra aggregative context section of Tstorm - */ -struct tstorm_eth_extra_ag_context_section { - u32 __agg_val1; -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars2; - u8 __agg_val3; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u8 __agg_val3; - u8 __tcp_agg_vars2; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val5; - u8 __agg_val6; - u8 __tcp_agg_vars3; -#elif defined(__LITTLE_ENDIAN) - u8 __tcp_agg_vars3; - u8 __agg_val6; - u16 __agg_val5; -#endif - u32 __reserved63; - u32 __reserved64; - u32 __reserved65; - u32 __reserved66; - u32 __reserved67; - u32 __tcp_agg_vars1; - u32 __reserved61; - u32 __reserved62; - u32 __reserved2; + u32 reserved3[30]; }; /* * The eth aggregative context of Tstorm */ struct tstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 __reserved54; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 __reserved54; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val4; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u16 __agg_val4; -#endif - struct tstorm_eth_extra_ag_context_section __extra_section; + u32 __reserved0[14]; }; + /* * The eth aggregative context of Cstorm */ struct cstorm_eth_ag_context { - u32 __agg_vars1; -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 __num_of_treated_packet; - u32 __last_packet_treated; -#if defined(__BIG_ENDIAN) - u16 __reserved58; - u16 __reserved57; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved57; - u16 __reserved58; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __reserved63; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved63; - u16 __reserved64; -#endif - u32 __reserved65; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __rq_inv_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 __rq_inv_cnt; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __packet_index_th; - u16 __packet_index; -#elif defined(__LITTLE_ENDIAN) - u16 __packet_index; - u16 __packet_index_th; -#endif + u32 __reserved0[10]; }; + /* * The eth aggregative context of Ustorm */ struct ustorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u8 __aux_counter_flags; - u8 __agg_vars2; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u8 __agg_vars2; - u8 __aux_counter_flags; -#endif + u32 __reserved0; #if defined(__BIG_ENDIAN) u8 cdu_usage; - u8 __agg_misc2; - u16 __agg_misc1; + u8 __reserved2; + u16 __reserved1; #elif defined(__LITTLE_ENDIAN) - u16 __agg_misc1; - u8 __agg_misc2; + u16 __reserved1; + u8 __reserved2; u8 cdu_usage; #endif - u32 __agg_misc4; -#if defined(__BIG_ENDIAN) - u8 __agg_val3_th; - u8 __agg_val3; - u16 __agg_misc3; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_misc3; - u8 __agg_val3; - u8 __agg_val3_th; -#endif - u32 __agg_val1; - u32 __agg_misc4_th; -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved2; - u8 __decision_rules; - u8 __decision_rule_enable_bits; -#elif defined(__LITTLE_ENDIAN) - u8 __decision_rule_enable_bits; - u8 __decision_rules; - u16 __reserved2; -#endif + u32 __reserved3[6]; }; /* @@ -2140,18 +1838,16 @@ struct timers_block_context { */ struct eth_tx_bd_flags { u8 as_bitfield; -#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0) -#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0 -#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1) -#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1 -#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<2) -#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 2 -#define ETH_TX_BD_FLAGS_END_BD (0x1<<3) -#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3 +#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0) +#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0 +#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1) +#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1 +#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2) +#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2 #define ETH_TX_BD_FLAGS_START_BD (0x1<<4) #define ETH_TX_BD_FLAGS_START_BD_SHIFT 4 -#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5) -#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5 +#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5) +#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5 #define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6) #define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 #define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) @@ -2166,7 +1862,7 @@ struct eth_tx_start_bd { __le32 addr_hi; __le16 nbd; __le16 nbytes; - __le16 vlan; + __le16 vlan_or_ethertype; struct eth_tx_bd_flags bd_flags; u8 general_data; #define ETH_TX_START_BD_HDR_NBDS (0x3F<<0) @@ -2179,48 +1875,48 @@ struct eth_tx_start_bd { * Tx regular BD structure */ struct eth_tx_bd { - u32 addr_lo; - u32 addr_hi; - u16 total_pkt_bytes; - u16 nbytes; + __le32 addr_lo; + __le32 addr_hi; + __le16 total_pkt_bytes; + __le16 nbytes; u8 reserved[4]; }; /* - * Tx parsing BD structure for ETH,Relevant in START + * Tx parsing BD structure for ETH E1/E1h */ -struct eth_tx_parse_bd { +struct eth_tx_parse_bd_e1x { u8 global_data; -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0) -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0 -#define ETH_TX_PARSE_BD_UDP_CS_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_UDP_CS_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5) -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 -#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6) -#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6 -#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7 +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0) +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7 u8 tcp_flags; -#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0) -#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0 -#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1) -#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1 -#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2) -#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2 -#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3) -#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3 -#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5) -#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5 -#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6) -#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6 -#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7 - u8 ip_hlen; +#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0) +#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1) +#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1 +#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2) +#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2 +#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3) +#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3 +#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7 + u8 ip_hlen_w; s8 reserved; - __le16 total_hlen; + __le16 total_hlen_w; __le16 tcp_pseudo_csum; __le16 lso_mss; __le16 ip_id; @@ -2242,79 +1938,23 @@ struct eth_tx_next_bd { union eth_tx_bd_types { struct eth_tx_start_bd start_bd; struct eth_tx_bd reg_bd; - struct eth_tx_parse_bd parse_bd; + struct eth_tx_parse_bd_e1x parse_bd_e1x; struct eth_tx_next_bd next_bd; }; + /* * The eth storm context of Xstorm */ struct xstorm_eth_st_context { - u32 tx_bd_page_base_lo; - u32 tx_bd_page_base_hi; -#if defined(__BIG_ENDIAN) - u16 tx_bd_cons; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u8 __local_tx_bd_prod; -#elif defined(__LITTLE_ENDIAN) - u8 __local_tx_bd_prod; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u16 tx_bd_cons; -#endif - u32 __reserved1; - u32 __reserved2; -#if defined(__BIG_ENDIAN) - u8 __ram_cache_index; - u8 __double_buffer_client; - u16 __pkt_cons; -#elif defined(__LITTLE_ENDIAN) - u16 __pkt_cons; - u8 __double_buffer_client; - u8 __ram_cache_index; -#endif -#if defined(__BIG_ENDIAN) - u16 __statistics_address; - u16 __gso_next; -#elif defined(__LITTLE_ENDIAN) - u16 __gso_next; - u16 __statistics_address; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_tx_bd_cons; - u8 safc_group_num; - u8 safc_group_en; - u8 __is_eth_conn; -#elif defined(__LITTLE_ENDIAN) - u8 __is_eth_conn; - u8 safc_group_en; - u8 safc_group_num; - u8 __local_tx_bd_cons; -#endif - union eth_tx_bd_types __bds[13]; + u32 reserved0[60]; }; /* * The eth storm context of Cstorm */ struct cstorm_eth_st_context { -#if defined(__BIG_ENDIAN) - u16 __reserved0; - u8 sb_index_number; - u8 status_block_id; -#elif defined(__LITTLE_ENDIAN) - u8 status_block_id; - u8 sb_index_number; - u16 __reserved0; -#endif - u32 __reserved1[3]; + u32 __reserved0[4]; }; /* @@ -2362,103 +2002,114 @@ struct eth_tx_doorbell { /* - * cstorm default status block, generated by ustorm - */ -struct cstorm_def_status_block_u { - __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * cstorm default status block, generated by cstorm - */ -struct cstorm_def_status_block_c { - __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * xstorm status block + * client init fc data */ -struct xstorm_def_status_block { - __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_fc_data { + __le16 cqe_pause_thr_low; + __le16 cqe_pause_thr_high; + __le16 bd_pause_thr_low; + __le16 bd_pause_thr_high; + __le16 sge_pause_thr_low; + __le16 sge_pause_thr_high; + __le16 rx_cos_mask; + u8 safc_group_num; + u8 safc_group_en_flg; + u8 traffic_type; + u8 reserved0; + __le16 reserved1; + __le32 reserved2; }; -/* - * tstorm status block - */ -struct tstorm_def_status_block { - __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; /* - * host status block + * client init ramrod data */ -struct host_def_status_block { - struct atten_def_status_block atten_status_block; - struct cstorm_def_status_block_u u_def_status_block; - struct cstorm_def_status_block_c c_def_status_block; - struct xstorm_def_status_block x_def_status_block; - struct tstorm_def_status_block t_def_status_block; +struct client_init_general_data { + u8 client_id; + u8 statistics_counter_id; + u8 statistics_en_flg; + u8 is_fcoe_flg; + u8 activate_flg; + u8 sp_client_id; + __le16 reserved0; + __le32 reserved1[2]; }; /* - * cstorm status block, generated by ustorm + * client init rx data */ -struct cstorm_status_block_u { - __le16 index_values[HC_USTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; +struct client_init_rx_data { + u8 tpa_en_flg; + u8 vmqueue_mode_en_flg; + u8 extra_data_over_sgl_en_flg; + u8 cache_line_alignment_log_size; + u8 enable_dynamic_hc; + u8 max_sges_for_packet; + u8 client_qzone_id; + u8 drop_ip_cs_err_flg; + u8 drop_tcp_cs_err_flg; + u8 drop_ttl0_flg; + u8 drop_udp_cs_err_flg; + u8 inner_vlan_removal_enable_flg; + u8 outer_vlan_removal_enable_flg; u8 status_block_id; - __le32 __flags; + u8 rx_sb_index_number; + u8 reserved0[3]; + __le16 bd_buff_size; + __le16 sge_buff_size; + __le16 mtu; + struct regpair bd_page_base; + struct regpair sge_page_base; + struct regpair cqe_page_base; + u8 is_leading_rss; + u8 is_approx_mcast; + __le16 max_agg_size; + __le32 reserved2[3]; +}; + +/* + * client init tx data + */ +struct client_init_tx_data { + u8 enforce_security_flg; + u8 tx_status_block_id; + u8 tx_sb_index_number; + u8 reserved0; + __le16 mtu; + __le16 reserved1; + struct regpair tx_bd_page_base; + __le32 reserved2[2]; }; /* - * cstorm status block, generated by cstorm + * client init ramrod data */ -struct cstorm_status_block_c { - __le16 index_values[HC_CSTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_ramrod_data { + struct client_init_general_data general; + struct client_init_rx_data rx; + struct client_init_tx_data tx; + struct client_init_fc_data fc; }; + /* - * host status block + * The data contain client ID need to the ramrod */ -struct host_status_block { - struct cstorm_status_block_u u_status_block; - struct cstorm_status_block_c c_status_block; +struct eth_common_ramrod_data { + u32 client_id; + u32 reserved1; }; /* - * The data for RSS setup ramrod + * union for sgl and raw data. */ -struct eth_client_setup_ramrod_data { - u32 client_id; - u8 is_rdma; - u8 is_fcoe; - u16 reserved1; +union eth_sgl_or_raw_data { + __le16 sgl[8]; + u32 raw_data[4]; }; - /* * regular eth FP CQE parameters struct */ @@ -2476,8 +2127,8 @@ struct eth_fast_path_rx_cqe { #define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4 #define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5) #define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5 -#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) -#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x3<<6) +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 6 u8 status_flags; #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 @@ -2498,7 +2149,7 @@ struct eth_fast_path_rx_cqe { __le16 pkt_len; __le16 len_on_bd; struct parsing_flags pars_flags; - __le16 sgl[8]; + union eth_sgl_or_raw_data sgl_or_raw_data; }; @@ -2510,11 +2161,10 @@ struct eth_halt_ramrod_data { u32 reserved0; }; - /* * The data for statistics query ramrod */ -struct eth_query_ramrod_data { +struct common_query_ramrod_data { #if defined(__BIG_ENDIAN) u8 reserved0; u8 collect_port; @@ -2597,9 +2247,9 @@ struct spe_hdr { __le16 type; #define SPE_HDR_CONN_TYPE (0xFF<<0) #define SPE_HDR_CONN_TYPE_SHIFT 0 -#define SPE_HDR_COMMON_RAMROD (0xFF<<8) -#define SPE_HDR_COMMON_RAMROD_SHIFT 8 - __le16 reserved; +#define SPE_HDR_FUNCTION_ID (0xFF<<8) +#define SPE_HDR_FUNCTION_ID_SHIFT 8 + __le16 reserved1; }; /* @@ -2607,12 +2257,10 @@ struct spe_hdr { */ union eth_specific_data { u8 protocol_data[8]; - struct regpair mac_config_addr; - struct eth_client_setup_ramrod_data client_setup_ramrod_data; + struct regpair client_init_ramrod_init_data; struct eth_halt_ramrod_data halt_ramrod_data; - struct regpair leading_cqe_addr; struct regpair update_data_addr; - struct eth_query_ramrod_data query_ramrod_data; + struct eth_common_ramrod_data common_ramrod_data; }; /* @@ -2637,7 +2285,7 @@ struct eth_tx_bds_array { */ struct tstorm_eth_function_common_config { #if defined(__BIG_ENDIAN) - u8 leading_client_id; + u8 reserved1; u8 rss_result_mask; u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2650,16 +2298,12 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 #elif defined(__LITTLE_ENDIAN) u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2672,18 +2316,14 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 u8 rss_result_mask; - u8 leading_client_id; + u8 reserved1; #endif u16 vlan_id[2]; }; @@ -2731,55 +2371,38 @@ struct mac_configuration_hdr { u8 length; u8 offset; u16 client_id; - u32 reserved1; + u16 echo; + u16 reserved1; }; /* * MAC address in list for ramrod */ -struct tstorm_cam_entry { +struct mac_configuration_entry { __le16 lsb_mac_addr; __le16 middle_mac_addr; __le16 msb_mac_addr; - __le16 flags; -#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0) -#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0 -#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1) -#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1 -#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4) -#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4 -}; - -/* - * MAC filtering: CAM target table entry - */ -struct tstorm_cam_target_table_entry { + __le16 vlan_id; + u8 pf_id; u8 flags; -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4 - u8 reserved1; - u16 vlan_id; +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE (0x1<<0) +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE_SHIFT 0 +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC (0x1<<1) +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC_SHIFT 1 +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE (0x3<<2) +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE_SHIFT 2 +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<4) +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 4 +#define MAC_CONFIGURATION_ENTRY_BROADCAST (0x1<<5) +#define MAC_CONFIGURATION_ENTRY_BROADCAST_SHIFT 5 +#define MAC_CONFIGURATION_ENTRY_RESERVED1 (0x3<<6) +#define MAC_CONFIGURATION_ENTRY_RESERVED1_SHIFT 6 + u16 reserved0; u32 clients_bit_vector; }; /* - * MAC address in list for ramrod - */ -struct mac_configuration_entry { - struct tstorm_cam_entry cam_entry; - struct tstorm_cam_target_table_entry target_table_entry; -}; - -/* - * MAC filtering configuration command + * MAC filtering configuration command */ struct mac_configuration_cmd { struct mac_configuration_hdr hdr; @@ -2787,37 +2410,6 @@ struct mac_configuration_cmd { }; -/* - * MAC address in list for ramrod - */ -struct mac_configuration_entry_e1h { - __le16 lsb_mac_addr; - __le16 middle_mac_addr; - __le16 msb_mac_addr; - __le16 vlan_id; - __le16 e1hov_id; - u8 reserved0; - u8 flags; -#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0) -#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0 -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1) -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1 -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2) -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2 -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1 (0x1F<<3) -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1_SHIFT 3 - u32 clients_bit_vector; -}; - -/* - * MAC filtering configuration command - */ -struct mac_configuration_cmd_e1h { - struct mac_configuration_hdr hdr; - struct mac_configuration_entry_e1h config_table[32]; -}; - - /* * approximate-match multicast filtering for E1H per function in Tstorm */ @@ -2826,65 +2418,6 @@ struct tstorm_eth_approximate_match_multicast_filtering { }; -/* - * Configuration parameters per client in Tstorm - */ -struct tstorm_eth_client_config { -#if defined(__BIG_ENDIAN) - u8 reserved0; - u8 statistics_counter_id; - u16 mtu; -#elif defined(__LITTLE_ENDIAN) - u16 mtu; - u8 statistics_counter_id; - u8 reserved0; -#endif -#if defined(__BIG_ENDIAN) - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 -#elif defined(__LITTLE_ENDIAN) - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 -#endif -}; - - /* * MAC filtering configuration parameters per port in Tstorm */ @@ -2895,8 +2428,8 @@ struct tstorm_eth_mac_filter_config { u32 mcast_accept_all; u32 bcast_drop_all; u32 bcast_accept_all; - u32 strict_vlan; u32 vlan_filter[2]; + u32 unmatched_unicast; u32 reserved; }; @@ -2918,41 +2451,6 @@ struct tstorm_eth_tpa_exist { }; -/* - * rx rings pause data for E1h only - */ -struct ustorm_eth_rx_pause_data_e1h { -#if defined(__BIG_ENDIAN) - u16 bd_thr_low; - u16 cqe_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_low; - u16 bd_thr_low; -#endif -#if defined(__BIG_ENDIAN) - u16 cos; - u16 sge_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_low; - u16 cos; -#endif -#if defined(__BIG_ENDIAN) - u16 bd_thr_high; - u16 cqe_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_high; - u16 bd_thr_high; -#endif -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 sge_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_high; - u16 reserved0; -#endif -}; - - /* * Three RX producers for ETH */ @@ -2974,6 +2472,18 @@ struct ustorm_eth_rx_producers { }; +/* + * cfc delete event data + */ +struct cfc_del_event_data { + u32 cid; + u8 error; + u8 reserved0; + u16 reserved1; + u32 reserved2; +}; + + /* * per-port SAFC demo variables */ @@ -2990,8 +2500,10 @@ struct cmng_flags_per_port { #define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3 #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4) #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4 -#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5) -#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5 +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<5) +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 5 +#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x3FFFFFF<<6) +#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 6 }; @@ -3025,9 +2537,43 @@ struct safc_struct_per_port { u8 __reserved0; u16 __reserved1; #endif + u8 cos_to_traffic_types[MAX_COS_NUMBER]; + u32 __reserved2; u16 cos_to_pause_mask[NUM_OF_SAFC_BITS]; }; +/* + * per-port PFC variables + */ +struct pfc_struct_per_port { + u8 priority_to_traffic_types[MAX_PFC_PRIORITIES]; +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u8 __reserved0; + u8 priority_non_pausable_mask; +#elif defined(__LITTLE_ENDIAN) + u8 priority_non_pausable_mask; + u8 __reserved0; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Priority and cos + */ +struct priority_cos { +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 cos; + u8 priority; +#elif defined(__LITTLE_ENDIAN) + u8 priority; + u8 cos; + u16 reserved1; +#endif + u32 reserved2; +}; + /* * Per-port congestion management variables */ @@ -3035,20 +2581,48 @@ struct cmng_struct_per_port { struct rate_shaping_vars_per_port rs_vars; struct fairness_vars_per_port fair_vars; struct safc_struct_per_port safc_vars; + struct pfc_struct_per_port pfc_vars; +#if defined(__BIG_ENDIAN) + u16 __reserved1; + u8 dcb_enabled; + u8 llfc_mode; +#elif defined(__LITTLE_ENDIAN) + u8 llfc_mode; + u8 dcb_enabled; + u16 __reserved1; +#endif + struct priority_cos + traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; struct cmng_flags_per_port flags; }; + +/* + * Dynamic HC counters set by the driver + */ +struct hc_dynamic_drv_counter { + u32 val[HC_SB_MAX_DYNAMIC_INDICES]; +}; + +/* + * zone A per-queue data + */ +struct cstorm_queue_zone_data { + struct hc_dynamic_drv_counter hc_dyn_drv_cnt; + struct regpair reserved[2]; +}; + /* * Dynamic host coalescing init parameters */ struct dynamic_hc_config { u32 threshold[3]; - u8 shift_per_protocol[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout0[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout1[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout2[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout3[HC_USTORM_SB_NUM_INDICES]; + u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES]; }; @@ -3072,7 +2646,7 @@ struct xstorm_per_client_stats { * Common statistics collected by the Xstorm (per port) */ struct xstorm_common_stats { - struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID]; + struct xstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3109,7 +2683,7 @@ struct tstorm_per_client_stats { */ struct tstorm_common_stats { struct tstorm_per_port_stats port_statistics; - struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID]; + struct tstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3130,7 +2704,7 @@ struct ustorm_per_client_stats { * Protocol-common statistics collected by the Ustorm */ struct ustorm_common_stats { - struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID]; + struct ustorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3143,6 +2717,70 @@ struct eth_stats_query { }; +/* + * set mac event data + */ +struct set_mac_event_data { + u16 echo; + u16 reserved0; + u32 reserved1; + u32 reserved2; +}; + +/* + * union for all event ring message types + */ +union event_data { + struct set_mac_event_data set_mac_event; + struct cfc_del_event_data cfc_del_event; +}; + + +/* + * per PF event ring data + */ +struct event_ring_data { + struct regpair base_addr; +#if defined(__BIG_ENDIAN) + u8 index_id; + u8 sb_id; + u16 producer; +#elif defined(__LITTLE_ENDIAN) + u16 producer; + u8 sb_id; + u8 index_id; +#endif + u32 reserved0; +}; + + +/* + * event ring message element (each element is 128 bits) + */ +struct event_ring_msg { + u8 opcode; + u8 reserved0; + u16 reserved1; + union event_data data; +}; + +/* + * event ring next page element (128 bits) + */ +struct event_ring_next { + struct regpair addr; + u32 reserved[2]; +}; + +/* + * union for event ring element types (each element is 128 bits) + */ +union event_ring_elem { + struct event_ring_msg message; + struct event_ring_next next_page; +}; + + /* * per-vnic fairness variables */ @@ -3181,6 +2819,137 @@ struct fw_version { }; +/* + * Dynamic Host-Coalescing - Driver(host) counters + */ +struct hc_dynamic_sb_drv_counters { + u32 dynamic_hc_drv_counter[HC_SB_MAX_DYNAMIC_INDICES]; +}; + + +/* + * 2 bytes. configuration/state parameters for a single protocol index + */ +struct hc_index_data { +#if defined(__BIG_ENDIAN) + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 + u8 timeout; +#elif defined(__LITTLE_ENDIAN) + u8 timeout; + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 +#endif +}; + + +/* + * HC state-machine + */ +struct hc_status_block_sm { +#if defined(__BIG_ENDIAN) + u8 igu_seg_id; + u8 igu_sb_id; + u8 timer_value; + u8 __flags; +#elif defined(__LITTLE_ENDIAN) + u8 __flags; + u8 timer_value; + u8 igu_sb_id; + u8 igu_seg_id; +#endif + u32 time_to_expire; +}; + +/* + * hold PCI identification variables- used in various places in firmware + */ +struct pci_entity { +#if defined(__BIG_ENDIAN) + u8 vf_valid; + u8 vf_id; + u8 vnic_id; + u8 pf_id; +#elif defined(__LITTLE_ENDIAN) + u8 pf_id; + u8 vnic_id; + u8 vf_id; + u8 vf_valid; +#endif +}; + +/* + * The fast-path status block meta-data, common to all chips + */ +struct hc_sb_data { + struct regpair host_sb_addr; + struct hc_status_block_sm state_machine[HC_SB_MAX_SM]; + struct pci_entity p_func; +#if defined(__BIG_ENDIAN) + u8 rsrv0; + u8 dhc_qzone_id; + u8 __dynamic_hc_level; + u8 same_igu_sb_1b; +#elif defined(__LITTLE_ENDIAN) + u8 same_igu_sb_1b; + u8 __dynamic_hc_level; + u8 dhc_qzone_id; + u8 rsrv0; +#endif + struct regpair rsrv1[2]; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_sp_status_block_data { + struct regpair host_sb_addr; +#if defined(__BIG_ENDIAN) + u16 rsrv; + u8 igu_seg_id; + u8 igu_sb_id; +#elif defined(__LITTLE_ENDIAN) + u8 igu_sb_id; + u8 igu_seg_id; + u16 rsrv; +#endif + struct pci_entity p_func; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e1x { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E1X]; + struct hc_sb_data common; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e2 { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E2]; + struct hc_sb_data common; +}; + + /* * FW version stored in first line of pram */ @@ -3203,12 +2972,22 @@ struct pram_fw_version { }; +/* + * Ethernet slow path element + */ +union protocol_common_specific_data { + u8 protocol_data[8]; + struct regpair phy_address; + struct regpair mac_config_addr; + struct common_query_ramrod_data query_ramrod_data; +}; + /* * The send queue element */ struct protocol_common_spe { struct spe_hdr hdr; - struct regpair phy_address; + union protocol_common_specific_data data; }; @@ -3241,7 +3020,7 @@ struct rate_shaping_vars_per_vn { */ struct slow_path_element { struct spe_hdr hdr; - u8 protocol_data[8]; + struct regpair protocol_data; }; @@ -3254,3 +3033,97 @@ struct stats_indication_flags { }; +/* + * per-port PFC variables + */ +struct storm_pfc_struct_per_port { +#if defined(__BIG_ENDIAN) + u16 mid_mac_addr; + u16 msb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 msb_mac_addr; + u16 mid_mac_addr; +#endif +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u16 lsb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 lsb_mac_addr; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Per-port congestion management variables + */ +struct storm_cmng_struct_per_port { + struct storm_pfc_struct_per_port pfc_vars; +}; + + +/* + * zone A per-queue data + */ +struct tstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct tstorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * zone A per-queue data + */ +struct ustorm_queue_zone_data { + struct ustorm_eth_rx_producers eth_rx_producers; + struct regpair reserved[3]; +}; + + +/* + * zone B per-VF data + */ +struct ustorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * data per VF-PF channel + */ +struct vf_pf_channel_data { +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 valid; + u8 state; +#elif defined(__LITTLE_ENDIAN) + u8 state; + u8 valid; + u16 reserved0; +#endif + u32 reserved1; +}; + + +/* + * zone A per-queue data + */ +struct xstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct xstorm_vf_zone_data { + struct regpair reserved; +}; + +#endif /* BNX2X_HSI_H */ diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 65b26cbfe3e7..5ae22e085518 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -148,5 +148,46 @@ union init_op { struct raw_op raw; }; +#define INITOP_SET 0 /* set the HW directly */ +#define INITOP_CLEAR 1 /* clear the HW directly */ +#define INITOP_INIT 2 /* set the init-value array */ + +/**************************************************************************** +* ILT management +****************************************************************************/ +struct ilt_line { + dma_addr_t page_mapping; + void *page; + u32 size; +}; + +struct ilt_client_info { + u32 page_size; + u16 start; + u16 end; + u16 client_num; + u16 flags; +#define ILT_CLIENT_SKIP_INIT 0x1 +#define ILT_CLIENT_SKIP_MEM 0x2 +}; + +struct bnx2x_ilt { + u32 start_line; + struct ilt_line *lines; + struct ilt_client_info clients[4]; +#define ILT_CLIENT_CDU 0 +#define ILT_CLIENT_QM 1 +#define ILT_CLIENT_SRC 2 +#define ILT_CLIENT_TM 3 +}; + +/**************************************************************************** +* SRC configuration +****************************************************************************/ +struct src_ent { + u8 opaque[56]; + u64 next; +}; + #endif /* BNX2X_INIT_H */ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index 2b1363a6fe78..aae7fea00622 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -151,6 +151,15 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, bnx2x_init_ind_wr(bp, addr, data, len); } +static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi) +{ + u32 wb_write[2]; + + wb_write[0] = val_lo; + wb_write[1] = val_hi; + REG_WR_DMAE_LEN(bp, reg, wb_write, 2); +} + static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) { const u8 *data = NULL; @@ -503,4 +512,333 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) } } +/**************************************************************************** +* ILT management +****************************************************************************/ +/* + * This codes hides the low level HW interaction for ILT management and + * configuration. The API consists of a shadow ILT table which is set by the + * driver and a set of routines to use it to configure the HW. + * + */ + +/* ILT HW init operations */ + +/* ILT memory management operations */ +#define ILT_MEMOP_ALLOC 0 +#define ILT_MEMOP_FREE 1 + +/* the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ILT_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) +#define ILT_RANGE(f, l) (((l) << 10) | f) + +static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line, + u32 size, u8 memop) +{ + if (memop == ILT_MEMOP_FREE) { + BNX2X_ILT_FREE(line->page, line->page_mapping, line->size); + return 0; + } + BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size); + if (!line->page) + return -1; + line->size = size; + return 0; +} + + +static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop) +{ + int i, rc; + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (!ilt || !ilt->lines) + return -1; + + if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) + return 0; + + for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) { + rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i], + ilt_cli->page_size, memop); + } + return rc; +} + +int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop) +{ + int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop); + + return rc; +} + +static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx, + dma_addr_t page_mapping) +{ + u32 reg; + + if (CHIP_IS_E1(bp)) + reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8; + + bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping)); +} + +static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt, + int idx, u8 initop) +{ + dma_addr_t null_mapping; + int abs_idx = ilt->start_line + idx; + + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping); + break; + case INITOP_CLEAR: + null_mapping = 0; + bnx2x_ilt_line_wr(bp, abs_idx, null_mapping); + break; + } +} + +void bnx2x_ilt_boundry_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, + u32 ilt_start, u8 initop) +{ + u32 start_reg = 0; + u32 end_reg = 0; + + /* The boundary is either SET or INIT, + CLEAR => SET and for now SET ~~ INIT */ + + /* find the appropriate regs */ + if (CHIP_IS_E1(bp)) { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_PSWRQ_CDU0_L2P; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_PSWRQ_QM0_L2P; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_PSWRQ_SRC0_L2P; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_PSWRQ_TM0_L2P; + break; + } + REG_WR(bp, start_reg + BP_FUNC(bp)*4, + ILT_RANGE((ilt_start + ilt_cli->start), + (ilt_start + ilt_cli->end))); + } else { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_RQ_CDU_FIRST_ILT; + end_reg = PXP2_REG_RQ_CDU_LAST_ILT; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_RQ_QM_FIRST_ILT; + end_reg = PXP2_REG_RQ_QM_LAST_ILT; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_RQ_SRC_FIRST_ILT; + end_reg = PXP2_REG_RQ_SRC_LAST_ILT; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_RQ_TM_FIRST_ILT; + end_reg = PXP2_REG_RQ_TM_LAST_ILT; + break; + } + REG_WR(bp, start_reg, (ilt_start + ilt_cli->start)); + REG_WR(bp, end_reg, (ilt_start + ilt_cli->end)); + } +} + +void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp, struct bnx2x_ilt *ilt, + struct ilt_client_info *ilt_cli, u8 initop) +{ + int i; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + for (i = ilt_cli->start; i <= ilt_cli->end; i++) + bnx2x_ilt_line_init_op(bp, ilt, i, initop); + + /* init/clear the ILT boundries */ + bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop); +} + +void bnx2x_ilt_client_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + + bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop); +} + +static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp, + int cli_num, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + bnx2x_ilt_client_init_op(bp, ilt_cli, initop); +} + +void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop); +} + +static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, + u32 psz_reg, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12)); + break; + case INITOP_CLEAR: + break; + } +} + +/* + * called during init common stage, ilt clients should be initialized + * prioir to calling this function + */ +void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU, + PXP2_REG_RQ_CDU_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM, + PXP2_REG_RQ_QM_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC, + PXP2_REG_RQ_SRC_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM, + PXP2_REG_RQ_TM_P_SIZE, initop); +} + +/**************************************************************************** +* QM initializations +****************************************************************************/ +#define QM_QUEUES_PER_FUNC 16 /* E1 has 32, but only 16 are used */ +#define QM_INIT_MIN_CID_COUNT 31 +#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT) + +/* called during init port stage */ +void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + int port = BP_PORT(bp); + + if (QM_INIT(qm_cid_count)) { + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, QM_REG_CONNNUM_0 + port*4, + qm_cid_count/16 - 1); + break; + case INITOP_CLEAR: + break; + } + } +} + +static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) +{ + int i; + u32 wb_data[2]; + + wb_data[0] = wb_data[1] = 0; + + for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { + REG_WR(bp, QM_REG_BASEADDR + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, + wb_data, 2); + + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, + wb_data, 2); + } + } +} + +/* called during init common stage */ +void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + if (!QM_INIT(qm_cid_count)) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_qm_set_ptr_table(bp, qm_cid_count); + break; + case INITOP_CLEAR: + break; + } +} + +/**************************************************************************** +* SRC initializations +****************************************************************************/ + +/* called during init func stage */ +void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, + dma_addr_t t2_mapping, int src_cid_count) +{ + int i; + int port = BP_PORT(bp); + + /* Initialize T2 */ + for (i = 0; i < src_cid_count-1; i++) + t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent)); + + /* tell the searcher where the T2 table is */ + REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count); + + bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16, + U64_LO(t2_mapping), U64_HI(t2_mapping)); + + bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16, + U64_LO((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent)), + U64_HI((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent))); +} + #endif /* BNX2X_INIT_OPS_H */ diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index a07a3a6abd40..51d468d430ee 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -28,7 +28,7 @@ /********************************************************/ #define ETH_HLEN 14 -#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */ #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -4066,6 +4066,7 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, "verification\n"); return -EINVAL; } + fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 3696a4b6547b..119ca871f016 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -149,6 +149,242 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void __storm_memset_fill(struct bnx2x *bp, + u32 addr, size_t size, u32 val) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), val); +} + +static inline void storm_memset_ustats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct ustorm_per_client_stats); + + u32 addr = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_tstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct tstorm_per_client_stats); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_xstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct xstorm_per_client_stats); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) +{ + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); +} + +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_function_common_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); +} + +static inline void storm_memset_xstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_tstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_ustats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_cstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_xstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_tstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ustats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_cstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); +} + +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} + +static inline void storm_memset_eq_data(struct bnx2x *bp, + struct event_ring_data *eq_data, + u16 pfid) +{ + size_t size = sizeof(struct event_ring_data); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_DATA_OFFSET(pfid); + + __storm_memset_struct(bp, addr, size, (u32 *)eq_data); +} + +static inline void storm_memset_eq_prod(struct bnx2x *bp, u16 eq_prod, + u16 pfid) +{ + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_PROD_OFFSET(pfid); + REG_WR16(bp, addr, eq_prod); +} + +static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 ticks) +{ + + int index_offset = + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, timeout); + REG_WR8(bp, addr, ticks); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n", + port, fw_sb_id, sb_index, ticks); +} +static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 disable) +{ + u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); + int index_offset = + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = REG_RD16(bp, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= enable_flag; + REG_WR16(bp, addr, flags); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n", + port, fw_sb_id, sb_index, disable); +} + /* used only at init * locking is done by mcp */ @@ -538,7 +774,12 @@ static void bnx2x_fw_dump(struct bnx2x *bp) void bnx2x_panic_dump(struct bnx2x *bp) { int i; - u16 j, start, end; + u16 j; + struct hc_sp_status_block_data sp_sb_data; + int func = BP_FUNC(bp); +#ifdef BNX2X_STOP_ON_ERROR + u16 start = 0, end = 0; +#endif bp->stats_state = STATS_STATE_DISABLED; DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); @@ -547,44 +788,124 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Indices */ /* Common */ - BNX2X_ERR("def_c_idx(0x%x) def_u_idx(0x%x) def_x_idx(0x%x)" - " def_t_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" + BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" " spq_prod_idx(0x%x)\n", - bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx, - bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); + bp->def_idx, bp->def_att_idx, + bp->attn_state, bp->spq_prod_idx); + BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", + bp->def_status_blk->atten_status_block.attn_bits, + bp->def_status_blk->atten_status_block.attn_bits_ack, + bp->def_status_blk->atten_status_block.status_block_id, + bp->def_status_blk->atten_status_block.attn_bits_index); + BNX2X_ERR(" def ("); + for (i = 0; i < HC_SP_SB_MAX_INDICES; i++) + pr_cont("0x%x%s", + bp->def_status_blk->sp_sb.index_values[i], + (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " "); + + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32)); + + pr_cont("igu_sb_id(0x%x) igu_seg_id (0x%x) " + "pf_id(0x%x) vnic_id(0x%x) " + "vf_id(0x%x) vf_valid (0x%x)\n", + sp_sb_data.igu_sb_id, + sp_sb_data.igu_seg_id, + sp_sb_data.p_func.pf_id, + sp_sb_data.p_func.vnic_id, + sp_sb_data.p_func.vf_id, + sp_sb_data.p_func.vf_valid); + - /* Rx */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - + int loop; + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p = + sb_data_e1x.common.state_machine; + struct hc_index_data *hc_index_p = + sb_data_e1x.index_data; + int data_size; + u32 *sb_data_p; + + /* Rx */ BNX2X_ERR("fp%d: rx_bd_prod(0x%x) rx_bd_cons(0x%x)" - " *rx_bd_cons_sb(0x%x) rx_comp_prod(0x%x)" + " rx_comp_prod(0x%x)" " rx_comp_cons(0x%x) *rx_cons_sb(0x%x)\n", i, fp->rx_bd_prod, fp->rx_bd_cons, - le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod, + fp->rx_comp_prod, fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb)); BNX2X_ERR(" rx_sge_prod(0x%x) last_max_sge(0x%x)" - " fp_u_idx(0x%x) *sb_u_idx(0x%x)\n", + " fp_hc_idx(0x%x)\n", fp->rx_sge_prod, fp->last_max_sge, - le16_to_cpu(fp->fp_u_idx), - fp->status_blk->u_status_block.status_block_index); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + le16_to_cpu(fp->fp_hc_idx)); + /* Tx */ BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)" " tx_bd_prod(0x%x) tx_bd_cons(0x%x)" " *tx_cons_sb(0x%x)\n", i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - BNX2X_ERR(" fp_c_idx(0x%x) *sb_c_idx(0x%x)" - " tx_db_prod(0x%x)\n", le16_to_cpu(fp->fp_c_idx), - fp->status_blk->c_status_block.status_block_index, - fp->tx_db.data.prod); + + loop = HC_SB_MAX_INDICES_E1X; + + /* host sb data */ + + BNX2X_ERR(" run indexes ("); + for (j = 0; j < HC_SB_MAX_SM; j++) + pr_cont("0x%x%s", + fp->sb_running_index[j], + (j == HC_SB_MAX_SM - 1) ? ")" : " "); + + BNX2X_ERR(" indexes ("); + for (j = 0; j < loop; j++) + pr_cont("0x%x%s", + fp->sb_index_values[j], + (j == loop - 1) ? ")" : " "); + /* fw sb data */ + data_size = + sizeof(struct hc_status_block_data_e1x); + data_size /= sizeof(u32); + sb_data_p = (u32 *)&sb_data_e1x; + /* copy sb data in here */ + for (j = 0; j < data_size; j++) + *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + j * sizeof(u32)); + + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e1x.common.p_func.pf_id, + sb_data_e1x.common.p_func.vf_id, + sb_data_e1x.common.p_func.vf_valid, + sb_data_e1x.common.p_func.vnic_id, + sb_data_e1x.common.same_igu_sb_1b); + + /* SB_SMs data */ + for (j = 0; j < HC_SB_MAX_SM; j++) { + pr_cont("SM[%d] __flags (0x%x) " + "igu_sb_id (0x%x) igu_seg_id(0x%x) " + "time_to_expire (0x%x) " + "timer_value(0x%x)\n", j, + hc_sm_p[j].__flags, + hc_sm_p[j].igu_sb_id, + hc_sm_p[j].igu_seg_id, + hc_sm_p[j].time_to_expire, + hc_sm_p[j].timer_value); + } + + /* Indecies data */ + for (j = 0; j < loop; j++) { + pr_cont("INDEX[%d] flags (0x%x) " + "timeout (0x%x)\n", j, + hc_index_p[j].flags, + hc_index_p[j].timeout); + } } +#ifdef BNX2X_STOP_ON_ERROR /* Rings */ /* Rx */ for_each_queue(bp, i) { @@ -642,7 +963,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]); } } - +#endif bnx2x_fw_dump(bp); bnx2x_mc_assert(bp); BNX2X_ERR("end crash dump -----------------\n"); @@ -708,7 +1029,7 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); } -static void bnx2x_int_disable(struct bnx2x *bp) +void bnx2x_int_disable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -817,76 +1138,35 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.ramrod_type); - bp->spq_left++; - - if (fp->index) { - switch (command | fp->state) { - case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | - BNX2X_FP_STATE_OPENING): - DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_OPEN; - break; - - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): - DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_HALTED; - break; - - default: - BNX2X_ERR("unexpected MC reply (%d) " - "fp[%d] state is %x\n", - command, fp->index, fp->state); - break; - } - mb(); /* force bnx2x_wait_ramrod() to see the change */ - return; - } - - switch (command | bp->state) { - case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT): - DP(NETIF_MSG_IFUP, "got setup ramrod\n"); - bp->state = BNX2X_STATE_OPEN; + switch (command | fp->state) { + case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | BNX2X_FP_STATE_OPENING): + DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid); + fp->state = BNX2X_FP_STATE_OPEN; break; - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE; + case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid); fp->state = BNX2X_FP_STATE_HALTED; break; - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid); - bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; + case (RAMROD_CMD_ID_ETH_TERMINATE | BNX2X_FP_STATE_TERMINATING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid); + fp->state = BNX2X_FP_STATE_TERMINATED; break; -#ifdef BCM_CNIC - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid); - bnx2x_cnic_cfc_comp(bp, cid); + default: + BNX2X_ERR("unexpected MC reply (%d) " + "fp[%d] state is %x\n", + command, fp->index, fp->state); break; -#endif + } - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): - DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); - break; + bp->spq_left++; - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); - break; + /* push the change in fp->state and towards the memory */ + smp_wmb(); - default: - BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n", - command, bp->state); - break; - } - mb(); /* force bnx2x_wait_ramrod() to see the change */ + return; } irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) @@ -917,22 +1197,19 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { struct bnx2x_fastpath *fp = &bp->fp[i]; - mask = 0x2 << fp->sb_id; + mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); if (status & mask) { /* Handle Rx and Tx according to SB id */ prefetch(fp->rx_cons_sb); - prefetch(&fp->status_blk->u_status_block. - status_block_index); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->c_status_block. - status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; } } #ifdef BCM_CNIC - mask = 0x2 << CNIC_SB_ID(bp); + mask = 0x2; if (status & (mask | 0x1)) { struct cnic_ops *c_ops = NULL; @@ -1422,7 +1699,7 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) bp->vn_weight_sum = 0; for (vn = VN_0; vn < E1HVN_MAX; vn++) { int func = 2*vn + port; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; @@ -1454,7 +1731,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) { struct rate_shaping_vars_per_vn m_rs_vn; struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); u16 vn_min_rate, vn_max_rate; int i; @@ -1511,7 +1788,83 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, ((u32 *)(&m_fair_vn))[i]); } +static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) +{ + if (CHIP_REV_IS_SLOW(bp)) + return CMNG_FNS_NONE; + if (IS_E1HMF(bp)) + return CMNG_FNS_MINMAX; + + return CMNG_FNS_NONE; +} + +static void bnx2x_read_mf_cfg(struct bnx2x *bp) +{ + int vn; + + if (BP_NOMCP(bp)) + return; /* what should be the default bvalue in this case */ + + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + int /*abs*/func = 2*vn + BP_PORT(bp); + bp->mf_config = + MF_CFG_RD(bp, func_mf_config[func].config); + } +} + +static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) +{ + + if (cmng_type == CMNG_FNS_MINMAX) { + int vn; + + /* clear cmng_enables */ + bp->cmng.flags.cmng_enables = 0; + + /* read mf conf from shmem */ + if (read_cfg) + bnx2x_read_mf_cfg(bp); + + /* Init rate shaping and fairness contexts */ + bnx2x_init_port_minmax(bp); + + /* vn_weight_sum and enable fairness if not 0 */ + bnx2x_calc_vn_weight_sum(bp); + + /* calculate and set min-max rate for each vn */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, vn); + + /* always enable rate shaping and fairness */ + bp->cmng.flags.cmng_enables |= + CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; + if (!bp->vn_weight_sum) + DP(NETIF_MSG_IFUP, "All MIN values are zeroes" + " fairness will be disabled\n"); + return; + } + + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "rate shaping and fairness are disabled\n"); +} +static inline void bnx2x_link_sync_notify(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func; + int vn; + + /* Set the attention towards other drivers on the same port */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + if (vn == BP_E1HVN(bp)) + continue; + + func = ((vn << 1) | port); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + + (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); + } +} /* This function is called upon link interrupt */ static void bnx2x_link_attn(struct bnx2x *bp) @@ -1669,120 +2022,390 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) return rc; } -static void bnx2x_e1h_disable(struct bnx2x *bp) +/* must be called under rtnl_lock */ +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) { - int port = BP_PORT(bp); + u32 mask = (1 << cl_id); - netif_tx_disable(bp->dev); + /* initial seeting is BNX2X_ACCEPT_NONE */ + u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; + u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; + u8 unmatched_unicast = 0; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + if (filters & BNX2X_PROMISCUOUS_MODE) { + /* promiscious - accept all, drop none */ + drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; + accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_UNICAST) { + /* accept matched ucast */ + drop_all_ucast = 0; + } + if (filters & BNX2X_ACCEPT_MULTICAST) { + /* accept matched mcast */ + drop_all_mcast = 0; + } + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_BROADCAST) { + /* accept (all) bcast */ + drop_all_bcast = 0; + accp_all_bcast = 1; + } - netif_carrier_off(bp->dev); -} + bp->mac_filters.ucast_drop_all = drop_all_ucast ? + bp->mac_filters.ucast_drop_all | mask : + bp->mac_filters.ucast_drop_all & ~mask; -static void bnx2x_e1h_enable(struct bnx2x *bp) -{ - int port = BP_PORT(bp); + bp->mac_filters.mcast_drop_all = drop_all_mcast ? + bp->mac_filters.mcast_drop_all | mask : + bp->mac_filters.mcast_drop_all & ~mask; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + bp->mac_filters.bcast_drop_all = drop_all_bcast ? + bp->mac_filters.bcast_drop_all | mask : + bp->mac_filters.bcast_drop_all & ~mask; - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); + bp->mac_filters.ucast_accept_all = accp_all_ucast ? + bp->mac_filters.ucast_accept_all | mask : + bp->mac_filters.ucast_accept_all & ~mask; - /* - * Should not call netif_carrier_on since it will be called if the link - * is up when checking for link state - */ + bp->mac_filters.mcast_accept_all = accp_all_mcast ? + bp->mac_filters.mcast_accept_all | mask : + bp->mac_filters.mcast_accept_all & ~mask; + + bp->mac_filters.bcast_accept_all = accp_all_bcast ? + bp->mac_filters.bcast_accept_all | mask : + bp->mac_filters.bcast_accept_all & ~mask; + + bp->mac_filters.unmatched_unicast = unmatched_unicast ? + bp->mac_filters.unmatched_unicast | mask : + bp->mac_filters.unmatched_unicast & ~mask; } -static void bnx2x_update_min_max(struct bnx2x *bp) +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) { - int port = BP_PORT(bp); - int vn, i; + if (FUNC_CONFIG(p->func_flgs)) { + struct tstorm_eth_function_common_config tcfg = {0}; - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); - - bnx2x_calc_vn_weight_sum(bp); + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + /* set rss flags */ + if (p->func_flgs & FUNC_FLG_RSS) { + u16 rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); - if (bp->port.pmf) { - int func; + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); } - /* Store it to internal memory */ - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); + storm_memset_func_cfg(bp, &tcfg, p->func_id); } -} -static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) -{ - DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); - if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { + /* statistics */ + if (p->func_flgs & FUNC_FLG_STATS) { + struct stats_indication_flags stats_flags = {0}; + stats_flags.collect_eth = 1; - /* - * This is the only place besides the function initialization - * where the bp->flags can change so it is done without any - * locks - */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; + storm_memset_xstats_flags(bp, &stats_flags, p->func_id); + storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_e1h_disable(bp); - } else { - DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); - bp->flags &= ~MF_FUNC_DIS; + storm_memset_tstats_flags(bp, &stats_flags, p->func_id); + storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_e1h_enable(bp); - } - dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; - } - if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { + storm_memset_ustats_flags(bp, &stats_flags, p->func_id); + storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); - bnx2x_update_min_max(bp); - dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + storm_memset_cstats_flags(bp, &stats_flags, p->func_id); + storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); } - /* Report results to MCP */ - if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); - else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } } -/* must be called under the spq lock */ -static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) +static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp) { - struct eth_spe *next_spe = bp->spq_prod_bd; + u16 flags = 0; - if (bp->spq_prod_bd == bp->spq_last_bd) { - bp->spq_prod_bd = bp->spq; - bp->spq_prod_idx = 0; - DP(NETIF_MSG_TIMER, "end of spq\n"); - } else { - bp->spq_prod_bd++; - bp->spq_prod_idx++; - } - return next_spe; -} + /* calculate queue flags */ + flags |= QUEUE_FLG_CACHE_ALIGN; + flags |= QUEUE_FLG_HC; + flags |= IS_E1HMF(bp) ? QUEUE_FLG_OV : 0; -/* must be called under the spq lock */ +#ifdef BCM_VLAN + flags |= QUEUE_FLG_VLAN; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); +#endif + + if (!fp->disable_tpa) + flags |= QUEUE_FLG_TPA; + + flags |= QUEUE_FLG_STATS; + + return flags; +} + +static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct rxq_pause_params *pause, + struct bnx2x_rxq_init_params *rxq_init) +{ + u16 max_sge = 0; + u16 sge_sz = 0; + u16 tpa_agg_size = 0; + + /* calculate queue flags */ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + if (!fp->disable_tpa) { + pause->sge_th_hi = 250; + pause->sge_th_lo = 150; + tpa_agg_size = min_t(u32, + (min_t(u32, 8, MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); + max_sge = SGE_PAGE_ALIGN(bp->dev->mtu) >> + SGE_PAGE_SHIFT; + max_sge = ((max_sge + PAGES_PER_SGE - 1) & + (~(PAGES_PER_SGE-1))) >> PAGES_PER_SGE_SHIFT; + sge_sz = (u16)min_t(u32, SGE_PAGE_SIZE * PAGES_PER_SGE, + 0xffff); + } + + /* pause - not for e1 */ + if (!CHIP_IS_E1(bp)) { + pause->bd_th_hi = 350; + pause->bd_th_lo = 250; + pause->rcq_th_hi = 350; + pause->rcq_th_lo = 250; + pause->sge_th_hi = 0; + pause->sge_th_lo = 0; + pause->pri_map = 1; + } + + /* rxq setup */ + rxq_init->flags = flags; + rxq_init->cxt = &bp->context.vcxt[fp->cid].eth; + rxq_init->dscr_map = fp->rx_desc_mapping; + rxq_init->sge_map = fp->rx_sge_mapping; + rxq_init->rcq_map = fp->rx_comp_mapping; + rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE; + rxq_init->mtu = bp->dev->mtu; + rxq_init->buf_sz = bp->rx_buf_size; + rxq_init->cl_qzone_id = fp->cl_qzone_id; + rxq_init->cl_id = fp->cl_id; + rxq_init->spcl_id = fp->cl_id; + rxq_init->stat_id = fp->cl_id; + rxq_init->tpa_agg_sz = tpa_agg_size; + rxq_init->sge_buf_sz = sge_sz; + rxq_init->max_sges_pkt = max_sge; + rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; + rxq_init->fw_sb_id = fp->fw_sb_id; + + rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + + rxq_init->cid = HW_CID(bp, fp->cid); + + rxq_init->hc_rate = bp->rx_ticks ? (1000000 / bp->rx_ticks) : 0; +} + +static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_txq_init_params *txq_init) +{ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + txq_init->flags = flags; + txq_init->cxt = &bp->context.vcxt[fp->cid].eth; + txq_init->dscr_map = fp->tx_desc_mapping; + txq_init->stat_id = fp->cl_id; + txq_init->cid = HW_CID(bp, fp->cid); + txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; + txq_init->fw_sb_id = fp->fw_sb_id; + txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; +} + +void bnx2x_pf_init(struct bnx2x *bp) +{ + struct bnx2x_func_init_params func_init = {0}; + struct bnx2x_rss_params rss = {0}; + struct event_ring_data eq_data = { {0} }; + u16 flags; + + /* pf specific setups */ + if (!CHIP_IS_E1(bp)) + storm_memset_ov(bp, bp->e1hov, BP_FUNC(bp)); + + /* function setup flags */ + flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); + + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + + /** + * Although RSS is meaningless when there is a single HW queue we + * still need it enabled in order to have HW Rx hash generated. + * + * if (is_eth_multi(bp)) + * flags |= FUNC_FLG_RSS; + */ + + /* function setup */ + if (flags & FUNC_FLG_RSS) { + rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | + RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); + rss.mode = bp->multi_mode; + rss.result_mask = MULTI_MASK; + func_init.rss = &rss; + } + + func_init.func_flgs = flags; + func_init.pf_id = BP_FUNC(bp); + func_init.func_id = BP_FUNC(bp); + func_init.fw_stat_map = bnx2x_sp_mapping(bp, fw_stats); + func_init.spq_map = bp->spq_mapping; + func_init.spq_prod = bp->spq_prod_idx; + + bnx2x_func_init(bp, &func_init); + + memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); + + /* + Congestion management values depend on the link rate + There is no active link so initial link rate is set to 10 Gbps. + When the link comes up The congestion management values are + re-calculated according to the actual link rate. + */ + bp->link_vars.line_speed = SPEED_10000; + bnx2x_cmng_fns_init(bp, true, bnx2x_get_cmng_fns_mode(bp)); + + /* Only the PMF sets the HW */ + if (bp->port.pmf) + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + + /* no rx until link is up */ + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); + + /* init Event Queue */ + eq_data.base_addr.hi = U64_HI(bp->eq_mapping); + eq_data.base_addr.lo = U64_LO(bp->eq_mapping); + eq_data.producer = bp->eq_prod; + eq_data.index_id = HC_SP_INDEX_EQ_CONS; + eq_data.sb_id = DEF_SB_ID; + storm_memset_eq_data(bp, &eq_data, BP_FUNC(bp)); +} + + +static void bnx2x_e1h_disable(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + + netif_tx_disable(bp->dev); + + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + + netif_carrier_off(bp->dev); +} + +static void bnx2x_e1h_enable(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); + + /* + * Should not call netif_carrier_on since it will be called if the link + * is up when checking for link state + */ +} + +static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) +{ + DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); + + if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { + + /* + * This is the only place besides the function initialization + * where the bp->flags can change so it is done without any + * locks + */ + if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + + bnx2x_e1h_disable(bp); + } else { + DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); + bp->flags &= ~MF_FUNC_DIS; + + bnx2x_e1h_enable(bp); + } + dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; + } + if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { + + bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); + bnx2x_link_sync_notify(bp); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + } + + /* Report results to MCP */ + if (dcc_event) + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); + else + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); +} + +/* must be called under the spq lock */ +static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) +{ + struct eth_spe *next_spe = bp->spq_prod_bd; + + if (bp->spq_prod_bd == bp->spq_last_bd) { + bp->spq_prod_bd = bp->spq; + bp->spq_prod_idx = 0; + DP(NETIF_MSG_TIMER, "end of spq\n"); + } else { + bp->spq_prod_bd++; + bp->spq_prod_idx++; + } + return next_spe; +} + +/* must be called under the spq lock */ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) { int func = BP_FUNC(bp); @@ -1790,7 +2413,7 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) /* Make sure that BD data is updated before writing the producer */ wmb(); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), bp->spq_prod_idx); mmiowb(); } @@ -1800,6 +2423,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common) { struct eth_spe *spe; + u16 type; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -1821,22 +2445,42 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spe->hdr.conn_and_cmd_data = cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | HW_CID(bp, cid)); - spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); + if (common) - spe->hdr.type |= - cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); + /* Common ramrods: + * FUNC_START, FUNC_STOP, CFC_DEL, STATS, SET_MAC + * TRAFFIC_STOP, TRAFFIC_START + */ + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + else + /* ETH ramrods: SETUP, HALT */ + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; - spe->data.mac_config_addr.hi = cpu_to_le32(data_hi); - spe->data.mac_config_addr.lo = cpu_to_le32(data_lo); + type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); - bp->spq_left--; + spe->hdr.type = cpu_to_le16(type); + + spe->data.update_data_addr.hi = cpu_to_le32(data_hi); + spe->data.update_data_addr.lo = cpu_to_le32(data_lo); + + /* stats ramrod has it's own slot on the spq */ + if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) + /* It's ok if the actual decrement is issued towards the memory + * somewhere between the spin_lock and spin_unlock. Thus no + * more explict memory barrier is needed. + */ + bp->spq_left--; DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, - "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", + "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) " + "type(0x%x) left %x\n", bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); + HW_CID(bp, cid), data_hi, data_lo, type, bp->spq_left); bnx2x_sp_prod_update(bp); spin_unlock_bh(&bp->spq_lock); @@ -1873,32 +2517,27 @@ static void bnx2x_release_alr(struct bnx2x *bp) REG_WR(bp, GRCBASE_MCP + 0x9c, 0); } +#define BNX2X_DEF_SB_ATT_IDX 0x0001 +#define BNX2X_DEF_SB_IDX 0x0002 + static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) { - struct host_def_status_block *def_sb = bp->def_status_blk; + struct host_sp_status_block *def_sb = bp->def_status_blk; u16 rc = 0; barrier(); /* status block is written to by the chip */ if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; - rc |= 1; - } - if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) { - bp->def_c_idx = def_sb->c_def_status_block.status_block_index; - rc |= 2; - } - if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) { - bp->def_u_idx = def_sb->u_def_status_block.status_block_index; - rc |= 4; - } - if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) { - bp->def_x_idx = def_sb->x_def_status_block.status_block_index; - rc |= 8; + rc |= BNX2X_DEF_SB_ATT_IDX; } - if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) { - bp->def_t_idx = def_sb->t_def_status_block.status_block_index; - rc |= 16; + + if (bp->def_idx != def_sb->sp_sb.running_index) { + bp->def_idx = def_sb->sp_sb.running_index; + rc |= BNX2X_DEF_SB_IDX; } + + /* Do not reorder: indecies reading should complete before handling */ + barrier(); return rc; } @@ -2144,8 +2783,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) int func = BP_FUNC(bp); REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = SHMEM_RD(bp, - mf_cfg.func_mf_config[func].config); + bp->mf_config = + MF_CFG_RD(bp, func_mf_config[func].config); val = SHMEM_RD(bp, func_mb[func].drv_status); if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, @@ -2598,6 +3237,140 @@ static void bnx2x_attn_int(struct bnx2x *bp) bnx2x_attn_int_deasserted(bp, deasserted); } +static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) +{ + /* No memory barriers */ + storm_memset_eq_prod(bp, prod, BP_FUNC(bp)); + mmiowb(); /* keep prod updates ordered */ +} + +#ifdef BCM_CNIC +static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, + union event_ring_elem *elem) +{ + if (!bp->cnic_eth_dev.starting_cid || + cid < bp->cnic_eth_dev.starting_cid) + return 1; + + DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid); + + if (unlikely(elem->message.data.cfc_del_event.error)) { + BNX2X_ERR("got delete ramrod for CNIC CID %d with error!\n", + cid); + bnx2x_panic_dump(bp); + } + bnx2x_cnic_cfc_comp(bp, cid); + return 0; +} +#endif + +static void bnx2x_eq_int(struct bnx2x *bp) +{ + u16 hw_cons, sw_cons, sw_prod; + union event_ring_elem *elem; + u32 cid; + u8 opcode; + int spqe_cnt = 0; + + hw_cons = le16_to_cpu(*bp->eq_cons_sb); + + /* The hw_cos range is 1-255, 257 - the sw_cons range is 0-254, 256. + * when we get the the next-page we nned to adjust so the loop + * condition below will be met. The next element is the size of a + * regular element and hence incrementing by 1 + */ + if ((hw_cons & EQ_DESC_MAX_PAGE) == EQ_DESC_MAX_PAGE) + hw_cons++; + + /* This function may never run in parralel with itself for a + * specific bp, thus there is no need in "paired" read memory + * barrier here. + */ + sw_cons = bp->eq_cons; + sw_prod = bp->eq_prod; + + DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n", + hw_cons, sw_cons, bp->spq_left); + + for (; sw_cons != hw_cons; + sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) { + + + elem = &bp->eq_ring[EQ_DESC(sw_cons)]; + + cid = SW_CID(elem->message.data.cfc_del_event.cid); + opcode = elem->message.opcode; + + + /* handle eq element */ + switch (opcode) { + case EVENT_RING_OPCODE_STAT_QUERY: + DP(NETIF_MSG_TIMER, "got statistics comp event\n"); + /* nothing to do with stats comp */ + continue; + + case EVENT_RING_OPCODE_CFC_DEL: + /* handle according to cid range */ + /* + * we may want to verify here that the bp state is + * HALTING + */ + DP(NETIF_MSG_IFDOWN, + "got delete ramrod for MULTI[%d]\n", cid); +#ifdef BCM_CNIC + if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) + goto next_spqe; +#endif + bnx2x_fp(bp, cid, state) = + BNX2X_FP_STATE_CLOSED; + + goto next_spqe; + } + + switch (opcode | bp->state) { + case (EVENT_RING_OPCODE_FUNCTION_START | + BNX2X_STATE_OPENING_WAIT4_PORT): + DP(NETIF_MSG_IFUP, "got setup ramrod\n"); + bp->state = BNX2X_STATE_FUNC_STARTED; + break; + + case (EVENT_RING_OPCODE_FUNCTION_STOP | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + break; + + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): + DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); + bp->set_mac_pending = 0; + break; + + case (EVENT_RING_OPCODE_SET_MAC | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); + bp->set_mac_pending = 0; + break; + default: + /* unknown event log error and continue */ + BNX2X_ERR("Unknown EQ event %d\n", + elem->message.opcode); + } +next_spqe: + spqe_cnt++; + } /* for */ + + bp->spq_left++; + + bp->eq_cons = sw_cons; + bp->eq_prod = sw_prod; + /* Make sure that above mem writes were issued towards the memory */ + smp_wmb(); + + /* update producer */ + bnx2x_update_eq_prod(bp, bp->eq_prod); +} + static void bnx2x_sp_task(struct work_struct *work) { struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); @@ -2616,31 +3389,29 @@ static void bnx2x_sp_task(struct work_struct *work) DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status); /* HW attentions */ - if (status & 0x1) { + if (status & BNX2X_DEF_SB_ATT_IDX) { bnx2x_attn_int(bp); - status &= ~0x1; + status &= ~BNX2X_DEF_SB_ATT_IDX; } - /* CStorm events: STAT_QUERY */ - if (status & 0x2) { - DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n"); - status &= ~0x2; + /* SP events: STAT_QUERY and others */ + if (status & BNX2X_DEF_SB_IDX) { + + /* Handle EQ completions */ + bnx2x_eq_int(bp); + + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, + le16_to_cpu(bp->def_idx), IGU_INT_NOP, 1); + + status &= ~BNX2X_DEF_SB_IDX; } if (unlikely(status)) DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", status); - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), - IGU_INT_ENABLE, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, ATTENTION_ID, + le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1); } irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) @@ -2654,7 +3425,8 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) return IRQ_HANDLED; } - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, + IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -2736,232 +3508,234 @@ timer_restart: * nic init service functions */ -static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) +static inline void bnx2x_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) { - int port = BP_PORT(bp); + u32 i; + if (!(len%4) && !(addr%4)) + for (i = 0; i < len; i += 4) + REG_WR(bp, addr + i, fill); + else + for (i = 0; i < len; i++) + REG_WR8(bp, addr + i, fill); - /* "CSTORM" */ - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_U_SIZE / 4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_C_SIZE / 4); } -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id) +/* helper: writes FP SP data to FW - data_size in dwords */ +static inline void bnx2x_wr_fp_sb_data(struct bnx2x *bp, + int fw_sb_id, + u32 *sb_data_p, + u32 data_size) { - int port = BP_PORT(bp); - int func = BP_FUNC(bp); int index; - u64 section; + for (index = 0; index < data_size; index++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + sizeof(u32)*index, + *(sb_data_p + index)); +} - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - u_status_block); - sb->u_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func); - - for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1); +static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) +{ + u32 *sb_data_p; + u32 data_size = 0; + struct hc_status_block_data_e1x sb_data_e1x; - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - c_status_block); - sb->c_status_block.status_block_id = sb_id; + /* disable the function first */ + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func); + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); - for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SYNC_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_SYNC_BLOCK_SIZE); +} - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +/* helper: writes SP SB data to FW */ +static inline void bnx2x_wr_sp_sb_data(struct bnx2x *bp, + struct hc_sp_status_block_data *sp_sb_data) +{ + int func = BP_FUNC(bp); + int i; + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32), + *((u32 *)sp_sb_data + i)); } -static void bnx2x_zero_def_sb(struct bnx2x *bp) +static inline void bnx2x_zero_sp_sb(struct bnx2x *bp) { int func = BP_FUNC(bp); + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct tstorm_def_status_block)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_u)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_c)/4); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct xstorm_def_status_block)/4); + sp_sb_data.p_func.pf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_valid = false; + + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); + + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_OFFSET(func), 0, + CSTORM_SP_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_SYNC_BLOCK_OFFSET(func), 0, + CSTORM_SP_SYNC_BLOCK_SIZE); + +} + + +static inline +void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm, + int igu_sb_id, int igu_seg_id) +{ + hc_sm->igu_sb_id = igu_sb_id; + hc_sm->igu_seg_id = igu_seg_id; + hc_sm->timer_value = 0xFF; + hc_sm->time_to_expire = 0xFFFFFFFF; } -static void bnx2x_init_def_sb(struct bnx2x *bp, - struct host_def_status_block *def_sb, - dma_addr_t mapping, int sb_id) +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id) { + int igu_seg_id; + + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p; + struct hc_index_data *hc_index_p; + int data_size; + u32 *sb_data_p; + + igu_seg_id = HC_SEG_ACCESS_NORM; + + bnx2x_zero_fp_sb(bp, fw_sb_id); + + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e1x.common.p_func.vf_id = 0xff; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_e1x.common.p_func.vnic_id = BP_E1HVN(bp); + sb_data_e1x.common.same_igu_sb_1b = true; + sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e1x.common.state_machine; + hc_index_p = sb_data_e1x.index_data; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + + + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID], + igu_sb_id, igu_seg_id); + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_TX_ID], + igu_sb_id, igu_seg_id); + + DP(NETIF_MSG_HW, "Init FW SB %d\n", fw_sb_id); + + /* write indecies to HW */ + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); +} + +static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, + u8 sb_index, u8 disable, u16 usec) +{ + int port = BP_PORT(bp); + u8 ticks = usec / BNX2X_BTR; + + storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks); + + disable = disable ? 1 : (usec ? 0 : 1); + storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); +} + +static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, + u16 tx_usec, u16 rx_usec) +{ + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX, + false, rx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, + false, tx_usec); +} +static void bnx2x_init_def_sb(struct bnx2x *bp) +{ + struct host_sp_status_block *def_sb = bp->def_status_blk; + dma_addr_t mapping = bp->def_status_blk_mapping; + int igu_sp_sb_index; + int igu_seg_id; int port = BP_PORT(bp); int func = BP_FUNC(bp); - int index, val, reg_offset; + int reg_offset; u64 section; + int index; + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); + + igu_sp_sb_index = DEF_SB_IGU_ID; + igu_seg_id = HC_SEG_ACCESS_DEF; /* ATTN */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, + section = ((u64)mapping) + offsetof(struct host_sp_status_block, atten_status_block); - def_sb->atten_status_block.status_block_id = sb_id; + def_sb->atten_status_block.status_block_id = igu_sp_sb_index; bp->attn_state = 0; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { - bp->attn_group[index].sig[0] = REG_RD(bp, - reg_offset + 0x10*index); - bp->attn_group[index].sig[1] = REG_RD(bp, - reg_offset + 0x4 + 0x10*index); - bp->attn_group[index].sig[2] = REG_RD(bp, - reg_offset + 0x8 + 0x10*index); - bp->attn_group[index].sig[3] = REG_RD(bp, - reg_offset + 0xc + 0x10*index); + int sindex; + /* take care of sig[0]..sig[4] */ + for (sindex = 0; sindex < 4; sindex++) + bp->attn_group[index].sig[sindex] = + REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); } reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : HC_REG_ATTN_MSG0_ADDR_L); - REG_WR(bp, reg_offset, U64_LO(section)); REG_WR(bp, reg_offset + 4, U64_HI(section)); - reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); + section = ((u64)mapping) + offsetof(struct host_sp_status_block, + sp_sb); - val = REG_RD(bp, reg_offset); - val |= sb_id; - REG_WR(bp, reg_offset, val); + bnx2x_zero_sp_sb(bp); - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - u_def_status_block); - def_sb->u_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func); - - for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1); + sp_sb_data.host_sb_addr.lo = U64_LO(section); + sp_sb_data.host_sb_addr.hi = U64_HI(section); + sp_sb_data.igu_sb_id = igu_sp_sb_index; + sp_sb_data.igu_seg_id = igu_seg_id; + sp_sb_data.p_func.pf_id = func; + sp_sb_data.p_func.vnic_id = BP_E1HVN(bp); + sp_sb_data.p_func.vf_id = 0xff; - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - c_def_status_block); - def_sb->c_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func); - - for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1); - - /* TSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - t_def_status_block); - def_sb->t_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_TSTRORM_INTMEM + - ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); - - /* XSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - x_def_status_block); - def_sb->x_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_XSTRORM_INTMEM + - ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); bp->stats_pending = 0; bp->set_mac_pending = 0; - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); } void bnx2x_update_coalesce(struct bnx2x *bp) { - int port = BP_PORT(bp); int i; - for_each_queue(bp, i) { - int sb_id = bp->fp[i].sb_id; - - /* HC_INDEX_U_ETH_RX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - bp->rx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - - /* HC_INDEX_C_ETH_TX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - bp->tx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - } + for_each_queue(bp, i) + bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, + bp->rx_ticks, bp->tx_ticks); } static void bnx2x_init_sp_ring(struct bnx2x *bp) { - int func = BP_FUNC(bp); - spin_lock_init(&bp->spq_lock); bp->spq_left = MAX_SPQ_PENDING; @@ -2969,91 +3743,25 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp) bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func), - U64_LO(bp->spq_mapping)); - REG_WR(bp, - XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4, - U64_HI(bp->spq_mapping)); - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); } -static void bnx2x_init_context(struct bnx2x *bp) +static void bnx2x_init_eq_ring(struct bnx2x *bp) { int i; + for (i = 1; i <= NUM_EQ_PAGES; i++) { + union event_ring_elem *elem = + &bp->eq_ring[EQ_DESC_CNT_PAGE * i - 1]; - /* Rx */ - for_each_queue(bp, i) { - struct eth_context *context = bnx2x_sp(bp, context[i].eth); - struct bnx2x_fastpath *fp = &bp->fp[i]; - u8 cl_id = fp->cl_id; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cl_id; - context->ustorm_st_context.common.status_block_id = fp->sb_id; - context->ustorm_st_context.common.flags = - (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT | - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS); - context->ustorm_st_context.common.statistics_counter_id = - cl_id; - context->ustorm_st_context.common.mc_alignment_log_size = - BNX2X_RX_ALIGN_SHIFT; - context->ustorm_st_context.common.bd_buff_size = - bp->rx_buf_size; - context->ustorm_st_context.common.bd_page_base_hi = - U64_HI(fp->rx_desc_mapping); - context->ustorm_st_context.common.bd_page_base_lo = - U64_LO(fp->rx_desc_mapping); - if (!fp->disable_tpa) { - context->ustorm_st_context.common.flags |= - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA; - context->ustorm_st_context.common.sge_buff_size = - (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE, - 0xffff); - context->ustorm_st_context.common.sge_page_base_hi = - U64_HI(fp->rx_sge_mapping); - context->ustorm_st_context.common.sge_page_base_lo = - U64_LO(fp->rx_sge_mapping); - - context->ustorm_st_context.common.max_sges_for_packet = - SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT; - context->ustorm_st_context.common.max_sges_for_packet = - ((context->ustorm_st_context.common. - max_sges_for_packet + PAGES_PER_SGE - 1) & - (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT; - } - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct eth_context *context = - bnx2x_sp(bp, context[i].eth); - - context->cstorm_st_context.sb_index_number = - C_SB_ETH_TX_CQ_INDEX; - context->cstorm_st_context.status_block_id = fp->sb_id; - - context->xstorm_st_context.tx_bd_page_base_hi = - U64_HI(fp->tx_desc_mapping); - context->xstorm_st_context.tx_bd_page_base_lo = - U64_LO(fp->tx_desc_mapping); - context->xstorm_st_context.statistics_data = (fp->cl_id | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + elem->next_page.addr.hi = + cpu_to_le32(U64_HI(bp->eq_mapping + + BCM_PAGE_SIZE * (i % NUM_EQ_PAGES))); + elem->next_page.addr.lo = + cpu_to_le32(U64_LO(bp->eq_mapping + + BCM_PAGE_SIZE*(i % NUM_EQ_PAGES))); } + bp->eq_cons = 0; + bp->eq_prod = NUM_EQ_DESC; + bp->eq_cons_sb = BNX2X_EQ_INDEX; } static void bnx2x_init_ind_table(struct bnx2x *bp) @@ -3072,47 +3780,11 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) bp->fp->cl_id + (i % bp->num_queues)); } -void bnx2x_set_client_config(struct bnx2x *bp) -{ - struct tstorm_eth_client_config tstorm_client = {0}; - int port = BP_PORT(bp); - int i; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.config_flags = - (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE | - TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE); -#ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - - for_each_queue(bp, i) { - tstorm_client.statistics_counter_id = bp->fp[i].cl_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4, - ((u32 *)&tstorm_client)[1]); - } - - DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); -} - void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { - struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; int mode = bp->rx_mode; - int mask = bp->rx_mode_cl_mask; - int func = BP_FUNC(bp); - int port = BP_PORT(bp); - int i; + u16 cl_id; + /* All but management unicast packets should pass to the host as well */ u32 llh_mask = NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | @@ -3120,28 +3792,32 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask); - switch (mode) { case BNX2X_RX_MODE_NONE: /* no Rx */ - tstorm_mac_filter.ucast_drop_all = mask; - tstorm_mac_filter.mcast_drop_all = mask; - tstorm_mac_filter.bcast_drop_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); break; case BNX2X_RX_MODE_NORMAL: - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST); break; case BNX2X_RX_MODE_ALLMULTI: - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); break; case BNX2X_RX_MODE_PROMISC: - tstorm_mac_filter.ucast_accept_all = mask; - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE); + /* pass management unicast packets as well */ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; break; @@ -3152,256 +3828,52 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) } REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK), + BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK, llh_mask); - for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4, - ((u32 *)&tstorm_mac_filter)[i]); - -/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, - ((u32 *)&tstorm_mac_filter)[i]); */ - } + DP(NETIF_MSG_IFUP, "rx mode %d\n" + "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode, + bp->mac_filters.ucast_drop_all, + bp->mac_filters.mcast_drop_all, + bp->mac_filters.bcast_drop_all, + bp->mac_filters.ucast_accept_all, + bp->mac_filters.mcast_accept_all, + bp->mac_filters.bcast_accept_all + ); - if (mode != BNX2X_RX_MODE_NONE) - bnx2x_set_client_config(bp); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); } static void bnx2x_init_internal_common(struct bnx2x *bp) { int i; - /* Zero this manually as its initialization is - currently missing in the initTool */ - for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_AGG_DATA_OFFSET + i * 4, 0); -} - -static void bnx2x_init_internal_port(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR); - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); -} - -static void bnx2x_init_internal_func(struct bnx2x *bp) -{ - struct tstorm_eth_function_common_config tstorm_config = {0}; - struct stats_indication_flags stats_flags = {0}; - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int i, j; - u32 offset; - u16 max_agg_size; - - tstorm_config.config_flags = RSS_FLAGS(bp); - - if (is_multi(bp)) - tstorm_config.rss_result_mask = MULTI_MASK; - - /* Enable TPA if needed */ - if (bp->flags & TPA_ENABLE_FLAG) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - if (IS_E1HMF(bp)) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM; - - tstorm_config.leading_client_id = BP_L_ID(bp); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), - (*(u32 *)&tstorm_config)); - - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ - bp->rx_mode_cl_mask = (1 << BP_L_ID(bp)); - bnx2x_set_storm_rx_mode(bp); - - for_each_queue(bp, i) { - u8 cl_id = bp->fp[i].cl_id; - - /* reset xstorm per client statistics */ - offset = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct xstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset tstorm per client statistics */ - offset = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct tstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset ustorm per client statistics */ - offset = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct ustorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - } - - /* Init statistics related context */ - stats_flags.collect_eth = 1; - - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + if (!CHIP_IS_E1(bp)) { - if (CHIP_IS_E1H(bp)) { + /* xstorm needs to know whether to add ovlan to packets or not, + * in switch-independent we'll write 0 to here... */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->e1hmf); REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - - REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func), - bp->e1hov); + bp->e1hmf); } - /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ - max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * - SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping)); - - /* Next page */ - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + /* Zero this manually as its initialization is + currently missing in the initTool */ + for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE)); - - REG_WR16(bp, BAR_USTRORM_INTMEM + - USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id), - max_agg_size); - } - - /* dropless flow control */ - if (CHIP_IS_E1H(bp)) { - struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; - - rx_pause.bd_thr_low = 250; - rx_pause.cqe_thr_low = 250; - rx_pause.cos = 1; - rx_pause.sge_thr_low = 0; - rx_pause.bd_thr_high = 350; - rx_pause.cqe_thr_high = 350; - rx_pause.sge_thr_high = 0; - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - if (!fp->disable_tpa) { - rx_pause.sge_thr_low = 150; - rx_pause.sge_thr_high = 250; - } - - - offset = BAR_USTRORM_INTMEM + - USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, - fp->cl_id); - for (j = 0; - j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; - j++) - REG_WR(bp, offset + j*4, - ((u32 *)&rx_pause)[j]); - } - } - - memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); - - /* Init rate shaping and fairness contexts */ - if (IS_E1HMF(bp)) { - int vn; - - /* During init there is no active link - Until link is up, set link rate to 10Gbps */ - bp->link_vars.line_speed = SPEED_10000; - bnx2x_init_port_minmax(bp); - - if (!BP_NOMCP(bp)) - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - bnx2x_calc_vn_weight_sum(bp); - - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); - - /* Enable rate shaping and fairness */ - bp->cmng.flags.cmng_enables |= - CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; - - } else { - /* rate shaping and fairness are disabled */ - DP(NETIF_MSG_IFUP, - "single function mode minmax will be disabled\n"); - } - + USTORM_AGG_DATA_OFFSET + i * 4, 0); +} - /* Store cmng structures to internal memory */ - if (bp->port.pmf) - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4, - ((u32 *)(&bp->cmng))[i]); +static void bnx2x_init_internal_port(struct bnx2x *bp) +{ + /* port */ } static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) @@ -3416,7 +3888,8 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bnx2x_init_internal_func(bp); + /* internal memory per function is + initialized inside bnx2x_pf_init */ break; default: @@ -3425,43 +3898,61 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) } } +static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) +{ + struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + + fp->state = BNX2X_FP_STATE_CLOSED; + + fp->index = fp->cid = fp_idx; + fp->cl_id = BP_L_ID(bp) + fp_idx; + fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; + fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; + /* qZone id equals to FW (per path) client id */ + fp->cl_qzone_id = fp->cl_id + + BP_PORT(bp)*(ETH_MAX_RX_CLIENTS_E1H); + /* init shortcut */ + fp->ustorm_rx_prods_offset = + USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); + /* Setup SB indicies */ + fp->rx_cons_sb = BNX2X_RX_SB_INDEX; + fp->tx_cons_sb = BNX2X_TX_SB_INDEX; + + DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) " + "cl_id %d fw_sb %d igu_sb %d\n", + fp_idx, bp, fp->status_blk.e1x_sb, fp->cl_id, fp->fw_sb_id, + fp->igu_sb_id); + bnx2x_init_sb(bp, fp->status_blk_mapping, BNX2X_VF_ID_INVALID, false, + fp->fw_sb_id, fp->igu_sb_id); + + bnx2x_update_fpsb_idx(fp); +} + void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) { int i; - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - fp->bp = bp; - fp->state = BNX2X_FP_STATE_CLOSED; - fp->index = i; - fp->cl_id = BP_L_ID(bp) + i; + for_each_queue(bp, i) + bnx2x_init_fp_sb(bp, i); #ifdef BCM_CNIC - fp->sb_id = fp->cl_id + 1; -#else - fp->sb_id = fp->cl_id; + + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); + #endif - DP(NETIF_MSG_IFUP, - "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n", - i, bp, fp->status_blk, fp->cl_id, fp->sb_id); - bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, - fp->sb_id); - bnx2x_update_fpsb_idx(fp); - } /* ensure status block indices were read */ rmb(); - - bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping, - DEF_SB_ID); + bnx2x_init_def_sb(bp); bnx2x_update_dsb_idx(bp); - bnx2x_update_coalesce(bp); bnx2x_init_rx_rings(bp); - bnx2x_init_tx_ring(bp); + bnx2x_init_tx_rings(bp); bnx2x_init_sp_ring(bp); - bnx2x_init_context(bp); + bnx2x_init_eq_ring(bp); bnx2x_init_internal(bp, load_code); + bnx2x_pf_init(bp); bnx2x_init_ind_table(bp); bnx2x_stats_init(bp); @@ -3620,8 +4111,6 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) else factor = 1; - DP(NETIF_MSG_HW, "start part1\n"); - /* Disable inputs of parser neighbor blocks */ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); @@ -3917,12 +4406,9 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); } -static int bnx2x_init_common(struct bnx2x *bp) +static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) { u32 val, i; -#ifdef BCM_CNIC - u32 wb_write[2]; -#endif DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); @@ -3964,12 +4450,8 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); #endif - REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); -#ifdef BCM_CNIC - REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5); -#endif + bnx2x_ilt_init_page_size(bp, INITOP_SET); + if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); @@ -4009,20 +4491,9 @@ static int bnx2x_init_common(struct bnx2x *bp) bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); -#ifdef BCM_CNIC - wb_write[0] = 0; - wb_write[1] = 0; - for (i = 0; i < 64; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2); - - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_write, 2); - } - } -#endif + /* QM queues pointers table */ + bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); + /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); @@ -4032,7 +4503,8 @@ static int bnx2x_init_common(struct bnx2x *bp) #endif bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); - REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); + REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); + if (!CHIP_REV_IS_SLOW(bp)) { /* enable hw interrupt from doorbell Q */ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); @@ -4184,7 +4656,7 @@ static int bnx2x_init_common(struct bnx2x *bp) return 0; } -static int bnx2x_init_port(struct bnx2x *bp) +static int bnx2x_init_hw_port(struct bnx2x *bp) { int port = BP_PORT(bp); int init_stage = port ? PORT1_STAGE : PORT0_STAGE; @@ -4203,9 +4675,10 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, CCM_BLOCK, init_stage); bnx2x_init_block(bp, XCM_BLOCK, init_stage); -#ifdef BCM_CNIC - REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1); + /* QM cid (connection) count */ + bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); +#ifdef BCM_CNIC bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); @@ -4327,25 +4800,6 @@ static int bnx2x_init_port(struct bnx2x *bp) return 0; } -#define ILT_PER_FUNC (768/2) -#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) -/* the phys address is shifted right 12 bits and has an added - 1=valid bit added to the 53rd bit - then since this is a wide register(TM) - we split it into two 32 bit writes - */ -#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) -#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) -#define PXP_ONE_ILT(x) (((x) << 10) | x) -#define PXP_ILT_RANGE(f, l) (((l) << 10) | f) - -#ifdef BCM_CNIC -#define CNIC_ILT_LINES 127 -#define CNIC_CTX_PER_ILT 16 -#else -#define CNIC_ILT_LINES 0 -#endif - static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) { int reg; @@ -4358,10 +4812,12 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); } -static int bnx2x_init_func(struct bnx2x *bp) +static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 cdu_ilt_start; u32 addr, val; int i; @@ -4373,72 +4829,67 @@ static int bnx2x_init_func(struct bnx2x *bp) val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; REG_WR(bp, addr, val); - i = FUNC_ILT_BASE(func); - - bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context)); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES); - } else /* E1 */ - REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, - PXP_ILT_RANGE(i, i + CNIC_ILT_LINES)); - -#ifdef BCM_CNIC - i += 1 + CNIC_ILT_LINES; - bnx2x_ilt_wr(bp, i, bp->timers_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i); - } - - i++; - bnx2x_ilt_wr(bp, i, bp->qm_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i); - } + ilt = BP_ILT(bp); + cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; - i++; - bnx2x_ilt_wr(bp, i, bp->t1_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i); + for (i = 0; i < L2_ILT_LINES(bp); i++) { + ilt->lines[cdu_ilt_start + i].page = + bp->context.vcxt + (ILT_PAGE_CIDS * i); + ilt->lines[cdu_ilt_start + i].page_mapping = + bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); + /* cdu ilt pages are allocated manually so there's no need to + set the size */ } + bnx2x_ilt_init_op(bp, INITOP_SET); +#ifdef BCM_CNIC + bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); - /* tell the searcher where the T2 table is */ - REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64); - - bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16, - U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping)); + /* T1 hash bits value determines the T1 number of entries */ + REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS); +#endif - bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16, - U64_LO((u64)bp->t2_mapping + 16*1024 - 64), - U64_HI((u64)bp->t2_mapping + 16*1024 - 64)); +#ifndef BCM_CNIC + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif /* BCM_CNIC */ - REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10); -#endif + bp->dmae_ready = 1; - if (CHIP_IS_E1H(bp)) { - bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PRS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + if (IS_E1HMF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); } + bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); + /* HC init per function */ if (CHIP_IS_E1H(bp)) { REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); @@ -4451,13 +4902,21 @@ static int bnx2x_init_func(struct bnx2x *bp) /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); + + bnx2x_init_block(bp, EMAC0_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, EMAC1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBG_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); + bnx2x_phy_probe(&bp->link_params); return 0; } int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) { - int i, rc = 0; + int rc = 0; DP(BNX2X_MSG_MCP, "function %d load_code %x\n", BP_FUNC(bp), load_code); @@ -4470,21 +4929,19 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: - rc = bnx2x_init_common(bp); + rc = bnx2x_init_hw_common(bp, load_code); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_PORT: - bp->dmae_ready = 1; - rc = bnx2x_init_port(bp); + rc = bnx2x_init_hw_port(bp); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bp->dmae_ready = 1; - rc = bnx2x_init_func(bp); + rc = bnx2x_init_hw_func(bp); if (rc) goto init_hw_err; break; @@ -4503,14 +4960,6 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); } - /* this needs to be done before gunzip end */ - bnx2x_zero_def_sb(bp); - for_each_queue(bp, i) - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#ifdef BCM_CNIC - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#endif - init_hw_err: bnx2x_gunzip_end(bp); @@ -4523,7 +4972,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_PCI_FREE(x, y, size) \ do { \ if (x) { \ - dma_free_coherent(&bp->pdev->dev, size, x, y); \ + dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ x = NULL; \ y = 0; \ } \ @@ -4532,7 +4981,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_FREE(x) \ do { \ if (x) { \ - vfree(x); \ + kfree((void *)x); \ x = NULL; \ } \ } while (0) @@ -4542,11 +4991,10 @@ void bnx2x_free_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { - /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk), + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + sizeof(struct host_hc_status_block_e1x)); } /* Rx */ for_each_queue(bp, i) { @@ -4580,21 +5028,28 @@ void bnx2x_free_mem(struct bnx2x *bp) /* end of fastpath */ BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); + sizeof(struct host_sp_status_block)); BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); + BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, + bp->context.size); + + bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); + + BNX2X_FREE(bp->ilt->lines); #ifdef BCM_CNIC - BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024); - BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024); - BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024); - BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024); - BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping, - sizeof(struct host_status_block)); + + BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); + BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); + #undef BNX2X_PCI_FREE #undef BNX2X_KFREE } @@ -4612,13 +5067,13 @@ int bnx2x_alloc_mem(struct bnx2x *bp) #define BNX2X_ALLOC(x, size) \ do { \ - x = vmalloc(size); \ + x = kzalloc(size, GFP_KERNEL); \ if (x == NULL) \ goto alloc_mem_err; \ - memset(x, 0, size); \ } while (0) int i; + void *p; /* fastpath */ /* Common */ @@ -4626,9 +5081,17 @@ int bnx2x_alloc_mem(struct bnx2x *bp) bnx2x_fp(bp, i, bp) = bp; /* status blocks */ - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), + BNX2X_PCI_ALLOC(p, &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + sizeof(struct host_hc_status_block_e1x)); + + bnx2x_fp(bp, i, status_blk.e1x_sb) = + (struct host_hc_status_block_e1x *)p; + + bnx2x_fp(bp, i, sb_index_values) = (__le16 *) + (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.index_values); + bnx2x_fp(bp, i, sb_running_index) = (__le16 *) + (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.running_index); } /* Rx */ for_each_queue(bp, i) { @@ -4664,37 +5127,36 @@ int bnx2x_alloc_mem(struct bnx2x *bp) } /* end of fastpath */ - BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); +#ifdef BCM_CNIC + BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); - BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, - sizeof(struct bnx2x_slowpath)); + /* allocate searcher T2 table */ + BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); +#endif -#ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); - /* allocate searcher T2 table - we allocate 1/4 of alloc num for T2 - (which is not entered into the ILT) */ - BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024); + BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, + sizeof(struct host_sp_status_block)); - /* Initialize T2 (for 1024 connections) */ - for (i = 0; i < 16*1024; i += 64) - *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, + sizeof(struct bnx2x_slowpath)); - /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */ - BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; + BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, + bp->context.size); - /* QM queues (128*MAX_CONN) */ - BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); + BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); - BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping, - sizeof(struct host_status_block)); -#endif + if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) + goto alloc_mem_err; /* Slow path ring */ BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); + /* EQ */ + BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); return 0; alloc_mem_err: @@ -4705,97 +5167,52 @@ alloc_mem_err: #undef BNX2X_ALLOC } - /* * Init service functions */ - -/** - * Sets a MAC in a CAM for a few L2 Clients for E1 chip - * - * @param bp driver descriptor - * @param set set or clear an entry (1 or 0) - * @param mac pointer to a buffer containing a MAC - * @param cl_bit_vec bit vector of clients to register a MAC for - * @param cam_offset offset in a CAM to use - * @param with_bcast set broadcast MAC as well - */ -static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 with_bcast) +int bnx2x_func_start(struct bnx2x *bp) { - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int port = BP_PORT(bp); - - /* CAM allocation - * unicasts 0-31:port0 32-63:port1 - * multicast 64-127:port0 128-191:port1 - */ - config->hdr.length = 1 + (with_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); - /* primary MAC */ - config->config_table[0].cam_entry.msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].cam_entry.middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].cam_entry.lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[0].target_table_entry.flags = 0; - else - CAM_INVALIDATE(config->config_table[0]); - config->config_table[0].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].target_table_entry.vlan_id = 0; + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_FUNC_STARTED, 0, &(bp->state), + WAIT_RAMROD_COMMON); +} - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n", - (set ? "setting" : "clearing"), - config->config_table[0].cam_entry.msb_mac_addr, - config->config_table[0].cam_entry.middle_mac_addr, - config->config_table[0].cam_entry.lsb_mac_addr); - - /* broadcast */ - if (with_bcast) { - config->config_table[1].cam_entry.msb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.middle_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.lsb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[1].target_table_entry.flags = - TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; - else - CAM_INVALIDATE(config->config_table[1]); - config->config_table[1].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[1].target_table_entry.vlan_id = 0; - } +int bnx2x_func_stop(struct bnx2x *bp) +{ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 1); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_CLOSING_WAIT4_UNLOAD, + 0, &(bp->state), WAIT_RAMROD_COMMON); } /** - * Sets a MAC in a CAM for a few L2 Clients for E1H chip + * Sets a MAC in a CAM for a few L2 Clients for E1x chip * * @param bp driver descriptor * @param set set or clear an entry (1 or 0) * @param mac pointer to a buffer containing a MAC * @param cl_bit_vec bit vector of clients to register a MAC for * @param cam_offset offset in a CAM to use + * @param is_bcast is the set MAC a broadcast address (for E1 only) */ -static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset) +static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) { - struct mac_configuration_cmd_e1h *config = - (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; + smp_wmb(); + + config->hdr.length = 1 + (is_bcast ? 1 : 0); + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + config->hdr.reserved1 = 0; config->hdr.length = 1; config->hdr.offset = cam_offset; @@ -4812,29 +5229,42 @@ static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, config->config_table[0].clients_bit_vector = cpu_to_le32(cl_bit_vec); config->config_table[0].vlan_id = 0; - config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); + config->config_table[0].pf_id = BP_FUNC(bp); if (set) - config->config_table[0].flags = BP_PORT(bp); + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); else - config->config_table[0].flags = - MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE; + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n", + if (is_bcast) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_BROADCAST, 1); + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", (set ? "setting" : "clearing"), config->config_table[0].msb_mac_addr, config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec); + config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); } -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int poll) + +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags) { /* can take a while if any port is running */ int cnt = 5000; + u8 poll = flags & WAIT_RAMROD_POLL; + u8 common = flags & WAIT_RAMROD_COMMON; DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", poll ? "polling" : "waiting", state, idx); @@ -4842,13 +5272,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, might_sleep(); while (cnt--) { if (poll) { - bnx2x_rx_int(bp->fp, 10); - /* if index is different from 0 - * the reply for some commands will - * be on the non default queue - */ - if (idx) - bnx2x_rx_int(&bp->fp[idx], 10); + if (common) + bnx2x_eq_int(bp); + else { + bnx2x_rx_int(bp->fp, 10); + /* if index is different from 0 + * the reply for some commands will + * be on the non default queue + */ + if (idx) + bnx2x_rx_int(&bp->fp[idx], 10); + } } mb(); /* state is changed by bnx2x_sp_event() */ @@ -4875,31 +5309,110 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, return -EBUSY; } -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set) +u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) { - bp->set_mac_pending++; - smp_wmb(); + return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); +} + +void bnx2x_set_eth_mac(struct bnx2x *bp, int set) +{ + u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : + bnx2x_e1h_cam_offset(bp, CAM_ETH_LINE)); - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), BP_FUNC(bp)); + /* networking MAC */ + bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, + (1 << bp->fp->cl_id), cam_offset , 0); - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + if (CHIP_IS_E1(bp)) { + /* broadcast MAC */ + u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); + } } +static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + + netdev_for_each_mc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting MCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + i++; + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + config_cmd->hdr.reserved1 = 0; + + bp->set_mac_pending = 1; + smp_wmb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +} +static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) { - bp->set_mac_pending++; + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; smp_wmb(); - bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0), - 1); + for (i = 0; i < config_cmd->hdr.length; i++) + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + } + #ifdef BCM_CNIC /** * Set iSCSI MAC(s) at the next enties in the CAM after the ETH @@ -4913,65 +5426,181 @@ void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) */ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) { - u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); - - bp->set_mac_pending++; - smp_wmb(); + u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : + bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); + u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID; + u32 cl_bit_vec = (1 << iscsi_l2_cl_id); /* Send a SET_MAC ramrod */ - if (CHIP_IS_E1(bp)) - bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, - 1); - else - /* CAM allocation for E1H - * unicasts: by func number - * multicast: 20+FUNC*20, 20 each - */ - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); - - /* Wait for a completion when setting */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); - + bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, + cam_offset, 0); return 0; } #endif -int bnx2x_setup_leading(struct bnx2x *bp) -{ - int rc; +static void bnx2x_fill_cl_init_data(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data) +{ + /* Clear the buffer */ + memset(data, 0, sizeof(*data)); + + /* general */ + data->general.client_id = params->rxq_params.cl_id; + data->general.statistics_counter_id = params->rxq_params.stat_id; + data->general.statistics_en_flg = + (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.activate_flg = activate; + data->general.sp_client_id = params->rxq_params.spcl_id; + + /* Rx data */ + data->rx.tpa_en_flg = + (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; + data->rx.vmqueue_mode_en_flg = 0; + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + + data->rx.inner_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; + data->rx.outer_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = + (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; + data->rx.is_approx_mcast = data->rx.is_leading_rss; + + /* Tx data */ + data->tx.enforce_security_flg = 0; /* VF specific */ + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.mtu = 0; /* VF specific */ + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* flow control data */ + data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + data->fc.safc_group_num = params->txq_params.cos; + data->fc.safc_group_en_flg = + (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; + data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW; +} + +static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); +} + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping) +{ + u16 hc_usec; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + int ramrod_flags = 0, rc; + + /* HC and context validation values */ + hc_usec = params->txq_params.hc_rate ? + 1000000 / params->txq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->txq_params.fw_sb_id, + params->txq_params.sb_cq_index, + !(params->txq_params.flags & QUEUE_FLG_HC), + hc_usec); + + *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + + hc_usec = params->rxq_params.hc_rate ? + 1000000 / params->rxq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->rxq_params.fw_sb_id, + params->rxq_params.sb_cq_index, + !(params->rxq_params.flags & QUEUE_FLG_HC), + hc_usec); + + bnx2x_set_ctx_validation(params->rxq_params.cxt, + params->rxq_params.cid); + + /* zero stats */ + if (params->txq_params.flags & QUEUE_FLG_STATS) + storm_memset_xstats_zero(bp, BP_PORT(bp), + params->txq_params.stat_id); + + if (params->rxq_params.flags & QUEUE_FLG_STATS) { + storm_memset_ustats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + storm_memset_tstats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + } + + /* Fill the ramrod data */ + bnx2x_fill_cl_init_data(bp, params, activate, data); + + /* SETUP ramrod. + * + * bnx2x_sp_post() takes a spin_lock thus no other explict memory + * barrier except from mmiowb() is needed to impose a + * proper ordering of memory operations. + */ + mmiowb(); - /* reset IGU state */ - bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); - /* SETUP ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0); + bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, + U64_HI(data_mapping), U64_LO(data_mapping), 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); - + rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, + params->ramrod_params.index, + params->ramrod_params.pstate, + ramrod_flags); return rc; } -int bnx2x_setup_multi(struct bnx2x *bp, int index) -{ - struct bnx2x_fastpath *fp = &bp->fp[index]; - - /* reset IGU state */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); - - /* SETUP ramrod */ - fp->state = BNX2X_FP_STATE_OPENING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, - fp->cl_id, 0); - - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(fp->state), 0); -} - - void bnx2x_set_num_queues_msix(struct bnx2x *bp) { @@ -4996,87 +5625,217 @@ void bnx2x_set_num_queues_msix(struct bnx2x *bp) } } +void bnx2x_ilt_set_info(struct bnx2x *bp) +{ + struct ilt_client_info *ilt_client; + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 line = 0; + + ilt->start_line = FUNC_ILT_BASE(BP_FUNC(bp)); + DP(BNX2X_MSG_SP, "ilt starts at line %d\n", ilt->start_line); + + /* CDU */ + ilt_client = &ilt->clients[ILT_CLIENT_CDU]; + ilt_client->client_num = ILT_CLIENT_CDU; + ilt_client->page_size = CDU_ILT_PAGE_SZ; + ilt_client->flags = ILT_CLIENT_SKIP_MEM; + ilt_client->start = line; + line += L2_ILT_LINES(bp); +#ifdef BCM_CNIC + line += CNIC_ILT_LINES; +#endif + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[CDU]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + /* QM */ + if (QM_INIT(bp->qm_cid_count)) { + ilt_client = &ilt->clients[ILT_CLIENT_QM]; + ilt_client->client_num = ILT_CLIENT_QM; + ilt_client->page_size = QM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + + /* 4 bytes for each cid */ + line += DIV_ROUND_UP(bp->qm_cid_count * QM_QUEUES_PER_FUNC * 4, + QM_ILT_PAGE_SZ); + + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[QM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + } + /* SRC */ + ilt_client = &ilt->clients[ILT_CLIENT_SRC]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_SRC; + ilt_client->page_size = SRC_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += SRC_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[SRC]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif + /* TM */ + ilt_client = &ilt->clients[ILT_CLIENT_TM]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_TM; + ilt_client->page_size = TM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += TM_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[TM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); -static int bnx2x_stop_multi(struct bnx2x *bp, int index) +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif +} +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading) { - struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_client_init_params params = { {0} }; int rc; - /* halt the connection */ - fp->state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, + IGU_INT_ENABLE, 0); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, - &(fp->state), 1); - if (rc) /* timeout */ - return rc; + params.ramrod_params.pstate = &fp->state; + params.ramrod_params.state = BNX2X_FP_STATE_OPEN; + params.ramrod_params.index = fp->index; + params.ramrod_params.cid = fp->cid; - /* delete cfc entry */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + if (is_leading) + params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, - &(fp->state), 1); + bnx2x_pf_rx_cl_prep(bp, fp, ¶ms.pause, ¶ms.rxq_params); + + bnx2x_pf_tx_cl_prep(bp, fp, ¶ms.txq_params); + + rc = bnx2x_setup_fw_client(bp, ¶ms, 1, + bnx2x_sp(bp, client_init_data), + bnx2x_sp_mapping(bp, client_init_data)); return rc; } -static int bnx2x_stop_leading(struct bnx2x *bp) +int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p) { - __le16 dsb_sp_prod_idx; - /* if the other port is handling traffic, - this can take a lot of time */ - int cnt = 500; int rc; - might_sleep(); + int poll_flag = p->poll ? WAIT_RAMROD_POLL : 0; - /* Send HALT ramrod */ - bp->fp[0].state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0); + /* halt the connection */ + *p->pstate = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, p->cid, 0, + p->cl_id, 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, - &(bp->fp[0].state), 1); + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, p->index, + p->pstate, poll_flag); if (rc) /* timeout */ return rc; - dsb_sp_prod_idx = *bp->dsb_sp_prod; + *p->pstate = BNX2X_FP_STATE_TERMINATING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, p->cid, 0, + p->cl_id, 0); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_TERMINATED, p->index, + p->pstate, poll_flag); + if (rc) /* timeout */ + return rc; - /* Send PORT_DELETE ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - /* Wait for completion to arrive on default status block - we are going to reset the chip anyway - so there is not much to do if this times out - */ - while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { - if (!cnt) { - DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " - "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", - *bp->dsb_sp_prod, dsb_sp_prod_idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); -#endif - rc = -EBUSY; - break; - } - cnt--; - msleep(1); - rmb(); /* Refresh the dsb_sp_prod */ - } - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - bp->fp[0].state = BNX2X_FP_STATE_CLOSED; + /* delete cfc entry */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, p->cid, 0, 0, 1); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, p->index, + p->pstate, WAIT_RAMROD_COMMON); return rc; } +static int bnx2x_stop_client(struct bnx2x *bp, int index) +{ + struct bnx2x_client_ramrod_params client_stop = {0}; + struct bnx2x_fastpath *fp = &bp->fp[index]; + + client_stop.index = index; + client_stop.cid = fp->cid; + client_stop.cl_id = fp->cl_id; + client_stop.pstate = &(fp->state); + client_stop.poll = 0; + + return bnx2x_stop_fw_client(bp, &client_stop); +} + + static void bnx2x_reset_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); int base, i; + int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + + offsetof(struct hc_status_block_data_e1x, common); + int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); + int pfid_offset = offsetof(struct pci_entity, pf_id); + + /* Disable the function in the FW */ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0); + + /* FP SBs */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + pfunc_offset_fp + pfid_offset, + HC_FUNCTION_DISABLED); + } + + /* SP SB */ + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + pfunc_offset_sp + pfid_offset, + HC_FUNCTION_DISABLED); + + + for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func), + 0); /* Configure IGU */ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); @@ -5099,6 +5858,8 @@ static void bnx2x_reset_func(struct bnx2x *bp) base = FUNC_ILT_BASE(func); for (i = base; i < base + ILT_PER_FUNC; i++) bnx2x_ilt_wr(bp, i, 0); + + bp->dmae_ready = 0; } static void bnx2x_reset_port(struct bnx2x *bp) @@ -5167,7 +5928,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) cnt = 1000; while (bnx2x_has_tx_work_unload(fp)) { - bnx2x_tx_int(fp); if (!cnt) { BNX2X_ERR("timeout waiting for queue[%d]\n", i); @@ -5186,39 +5946,21 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) msleep(1); if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - bnx2x_set_eth_mac_addr_e1(bp, 0); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - - config->hdr.length = i; - if (CHIP_REV_IS_SLOW(bp)) - config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0); + /* invalidate mc list, + * wait and poll (interrupts are off) + */ + bnx2x_invlidate_e1_mc_list(bp); + bnx2x_set_eth_mac(bp, 0); - } else { /* E1H */ + } else { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - bnx2x_set_eth_mac_addr_e1h(bp, 0); + bnx2x_set_eth_mac(bp, 0); for (i = 0; i < MC_HASH_SIZE; i++) REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); - - REG_WR(bp, MISC_REG_E1HMF_MODE, 0); } + #ifdef BCM_CNIC /* Clear iSCSI L2 MAC */ mutex_lock(&bp->cnic_mutex); @@ -5257,21 +5999,27 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) /* Close multi and leading connections Completions for ramrods are collected in a synchronous way */ - for_each_nondefault_queue(bp, i) - if (bnx2x_stop_multi(bp, i)) + for_each_queue(bp, i) + + if (bnx2x_stop_client(bp, i)) +#ifdef BNX2X_STOP_ON_ERROR + return; +#else goto unload_error; +#endif - rc = bnx2x_stop_leading(bp); + rc = bnx2x_func_stop(bp); if (rc) { - BNX2X_ERR("Stop leading failed!\n"); + BNX2X_ERR("Function stop failed!\n"); #ifdef BNX2X_STOP_ON_ERROR - return -EBUSY; + return; #else goto unload_error; #endif } - +#ifndef BNX2X_STOP_ON_ERROR unload_error: +#endif if (!BP_NOMCP(bp)) reset_code = bnx2x_fw_command(bp, reset_code, 0); else { @@ -5293,6 +6041,12 @@ unload_error: (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) bnx2x__link_reset(bp); + /* Disable HW interrupts, NAPI */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp, false); + /* Reset the chip */ bnx2x_reset_chip(bp, reset_code); @@ -5953,6 +6707,18 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->link_params.chip_id = bp->common.chip_id; BNX2X_DEV_INFO("chip ID is 0x%x\n", id); + bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ + + /* Set doorbell size */ + bp->db_size = (1 << BNX2X_DB_SHIFT); + + /* + * set base FW non-default (fast path) status block id, this value is + * used to initialize the fw_sb_id saved on the fp/queue structure to + * determine the id used by the FW. + */ + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + val = (REG_RD(bp, 0x2874) & 0x55); if ((bp->common.chip_id & 0x1) || (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) { @@ -6417,13 +7183,23 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_common_hwinfo(bp); + bp->common.int_block = INT_BLOCK_HC; + + bp->igu_dsb_id = DEF_SB_IGU_ID; + bp->igu_base_sb = 0; + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bp->e1hov = 0; bp->e1hmf = 0; if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { + + bp->common.mf_cfg_base = bp->common.shmem_base + + offsetof(struct shmem_region, func_mb) + + E1H_FUNC_MAX * sizeof(struct drv_func_mb); bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + MF_CFG_RD(bp, func_mf_config[func].config); - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) & + val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) bp->e1hmf = 1; @@ -6431,7 +7207,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) IS_E1HMF(bp) ? "multi" : "single"); if (IS_E1HMF(bp)) { - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func]. + val = (MF_CFG_RD(bp, func_mf_config[func]. e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { @@ -6453,6 +7229,10 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } } + /* adjust igu_sb_cnt to MF */ + if (IS_E1HMF(bp)) + bp->igu_sb_cnt /= E1HVN_MAX; + if (!BP_NOMCP(bp)) { bnx2x_get_port_hwinfo(bp); @@ -6462,8 +7242,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } if (IS_E1HMF(bp)) { - val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper); - val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower); + val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); + val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); @@ -6577,6 +7357,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) rc = bnx2x_get_hwinfo(bp); + if (!rc) + rc = bnx2x_alloc_mem_bp(bp); + bnx2x_read_fwinfo(bp); /* need to reset chip if undi was active */ if (!BP_NOMCP(bp)) @@ -6623,8 +7406,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->rx_csum = 1; /* make sure that the numbers are in the right granularity */ - bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); - bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); + bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; + bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); bp->current_interval = (poll ? poll : timer_interval); @@ -6724,73 +7507,16 @@ void bnx2x_set_rx_mode(struct net_device *dev) else { /* some multicasts */ if (CHIP_IS_E1(bp)) { - int i, old, offset; - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - i = 0; - netdev_for_each_mc_addr(ha, dev) { - config->config_table[i]. - cam_entry.msb_mac_addr = - swab16(*(u16 *)&ha->addr[0]); - config->config_table[i]. - cam_entry.middle_mac_addr = - swab16(*(u16 *)&ha->addr[2]); - config->config_table[i]. - cam_entry.lsb_mac_addr = - swab16(*(u16 *)&ha->addr[4]); - config->config_table[i].cam_entry.flags = - cpu_to_le16(port); - config->config_table[i]. - target_table_entry.flags = 0; - config->config_table[i].target_table_entry. - clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - config->config_table[i]. - target_table_entry.vlan_id = 0; - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config->config_table[i]. - cam_entry.msb_mac_addr, - config->config_table[i]. - cam_entry.middle_mac_addr, - config->config_table[i]. - cam_entry.lsb_mac_addr); - i++; - } - old = config->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - CAM_INVALIDATE(config-> - config_table[i]); - } - } - - if (CHIP_REV_IS_SLOW(bp)) - offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - offset = BNX2X_MAX_MULTICAST*(1 + port); - - config->hdr.length = i; - config->hdr.offset = offset; - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); + /* + * set mc list, do not wait as wait implies sleep + * and set_rx_mode can be invoked from non-sleepable + * context + */ + u8 offset = (CHIP_REV_IS_SLOW(bp) ? + BNX2X_MAX_EMUL_MULTI*(1 + port) : + BNX2X_MAX_MULTICAST*(1 + port)); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), - 0); + bnx2x_set_e1_mc_list(bp, offset); } else { /* E1H */ /* Accept one or more multicasts */ struct netdev_hw_addr *ha; @@ -6802,9 +7528,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - ha->addr); + bnx2x_mc_addr(ha)); - crc = crc32c_le(0, ha->addr, ETH_ALEN); + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); bit = (crc >> 24) & 0xff; regidx = bit >> 5; bit &= 0x1f; @@ -6817,6 +7544,7 @@ void bnx2x_set_rx_mode(struct net_device *dev) } } + bp->rx_mode = rx_mode; bnx2x_set_storm_rx_mode(bp); } @@ -7003,7 +7731,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, } bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, BNX2X_DB_SIZE, + min_t(u64, BNX2X_DB_SIZE(bp), pci_resource_len(pdev, 2))); if (!bp->doorbells) { dev_err(&bp->pdev->dev, @@ -7179,6 +7907,30 @@ static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n) } } +/** + * IRO array is stored in the following format: + * {base(24bit), m1(16bit), m2(16bit), m3(16bit), size(16bit) } + */ +static inline void bnx2x_prep_iro(const u8 *_source, u8 *_target, u32 n) +{ + const __be32 *source = (const __be32 *)_source; + struct iro *target = (struct iro *)_target; + u32 i, j, tmp; + + for (i = 0, j = 0; i < n/sizeof(struct iro); i++) { + target[i].base = be32_to_cpu(source[j]); + j++; + tmp = be32_to_cpu(source[j]); + target[i].m1 = (tmp >> 16) & 0xffff; + target[i].m2 = tmp & 0xffff; + j++; + tmp = be32_to_cpu(source[j]); + target[i].m3 = (tmp >> 16) & 0xffff; + target[i].size = tmp & 0xffff; + j++; + } +} + static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) { const __be16 *source = (const __be16 *)_source; @@ -7260,9 +8012,13 @@ int bnx2x_init_firmware(struct bnx2x *bp) be32_to_cpu(fw_hdr->csem_int_table_data.offset); INIT_CSEM_PRAM_DATA(bp) = bp->firmware->data + be32_to_cpu(fw_hdr->csem_pram_data.offset); + /* IRO */ + BNX2X_ALLOC_AND_SET(iro_arr, iro_alloc_err, bnx2x_prep_iro); return 0; +iro_alloc_err: + kfree(bp->init_ops_offsets); init_offsets_alloc_err: kfree(bp->init_ops); init_ops_alloc_err: @@ -7273,17 +8029,27 @@ request_firmware_exit: return rc; } +static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) +{ + int cid_count = L2_FP_COUNT(l2_cid_count); +#ifdef BCM_CNIC + cid_count += CNIC_CID_MAX; +#endif + return roundup(cid_count, QM_CID_ROUND); +} static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev = NULL; struct bnx2x *bp; int pcie_width, pcie_speed; - int rc; + int rc, cid_count; + + cid_count = FP_SB_MAX_E1x + CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ - dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT); + dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { dev_err(&pdev->dev, "Cannot allocate net device\n"); return -ENOMEM; @@ -7294,6 +8060,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); + bp->l2_cid_count = cid_count; + rc = bnx2x_init_dev(pdev, dev); if (rc < 0) { free_netdev(dev); @@ -7304,6 +8072,9 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (rc) goto init_one_exit; + /* calc qm_cid_count */ + bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); + rc = register_netdev(dev); if (rc) { dev_err(&pdev->dev, "Cannot register net device\n"); @@ -7360,6 +8131,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) if (bp->doorbells) iounmap(bp->doorbells); + bnx2x_free_mem_bp(bp); + free_netdev(dev); if (atomic_read(&pdev->enable_cnt) == 1) @@ -7387,16 +8160,9 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) /* Release IRQs */ bnx2x_free_irq(bp, false); - if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - } - /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); + for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); for_each_queue(bp, i) @@ -7641,8 +8407,8 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n", spe->hdr.conn_and_cmd_data, spe->hdr.type, - spe->data.mac_config_addr.hi, - spe->data.mac_config_addr.lo, + spe->data.update_data_addr.hi, + spe->data.update_data_addr.lo, bp->cnic_kwq_pending); if (bp->cnic_kwq_prod == bp->cnic_kwq_last) @@ -7736,8 +8502,24 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_START_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask |= (1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Set iSCSI MAC address */ + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + + mmiowb(); + barrier(); + + /* Start accepting on iSCSI L2 ring. Accept all multicasts + * because it's the only way for UIO Client to accept + * multicasts (in non-promiscuous mode only one Client per + * function will receive multicast packets (leading in our + * case). + */ + bnx2x_rxq_set_mac_filters(bp, cli, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + break; } @@ -7745,8 +8527,15 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_STOP_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask &= ~(1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Stop accepting on iSCSI L2 ring */ + bnx2x_rxq_set_mac_filters(bp, cli, BNX2X_ACCEPT_NONE); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + + mmiowb(); + barrier(); + + /* Unset iSCSI L2 MAC */ + bnx2x_set_iscsi_eth_mac_addr(bp, 0); break; } @@ -7770,10 +8559,12 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - cp->irq_arr[0].status_blk = bp->cnic_sb; + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); + cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; cp->irq_arr[1].status_blk_num = DEF_SB_ID; + cp->irq_arr[1].status_blk_num2 = DEF_SB_IGU_ID; cp->num_irq = 2; } @@ -7805,8 +8596,11 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, cp->num_irq = 0; cp->drv_state = CNIC_DRV_STATE_REGD; + cp->iro_arr = bp->iro_arr; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp)); + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); bnx2x_setup_cnic_irq_info(bp); bnx2x_set_iscsi_eth_mac_addr(bp, 1); @@ -7847,7 +8641,7 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->io_base = bp->regview; cp->io_base2 = bp->doorbells; cp->max_kwqe_pending = 8; - cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context); + cp->ctx_blk_size = CDU_ILT_PAGE_SZ; cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; cp->ctx_tbl_len = CNIC_ILT_LINES; cp->starting_cid = BCM_CNIC_CID_START; diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index efa1403ebf82..1256f62f7bff 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -153,7 +153,7 @@ static inline long bnx2x_hilo(u32 *hiref) static void bnx2x_storm_stats_post(struct bnx2x *bp) { if (!bp->stats_pending) { - struct eth_query_ramrod_data ramrod_data = {0}; + struct common_query_ramrod_data ramrod_data = {0}; int i, rc; spin_lock_bh(&bp->stats_lock); @@ -163,9 +163,9 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) for_each_queue(bp, i) ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, ((u32 *)&ramrod_data)[1], - ((u32 *)&ramrod_data)[0], 0); + ((u32 *)&ramrod_data)[0], 1); if (rc == 0) { /* stats ramrod has it's own slot on the spq */ bp->spq_left++; @@ -398,9 +398,9 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; @@ -571,7 +571,7 @@ static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp) { - struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); + struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; struct { diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 4e9d4ae1f303..80259815af06 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -942,7 +942,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & PAGE_MASK; - uinfo->mem[1].size = sizeof(struct host_def_status_block); + uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); uinfo->name = "bnx2x_cnic"; } @@ -1063,6 +1063,8 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) int i, j, n, ret, pages; struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info; + cp->iro_arr = ethdev->iro_arr; + cp->max_cid_space = MAX_ISCSI_TBL_SZ; cp->iscsi_start_cid = start_cid; if (start_cid < BNX2X_ISCSI_START_CID) { @@ -1127,8 +1129,6 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk; - memset(cp->status_blk.bnx2x, 0, sizeof(*cp->status_blk.bnx2x)); - cp->l2_rx_ring_size = 15; ret = cnic_alloc_l2_rings(dev, 4); @@ -1211,7 +1211,7 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid, cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) | BNX2X_HW_CID(cp, cid))); kwqe.hdr.type = cpu_to_le16(type); - kwqe.hdr.reserved = 0; + kwqe.hdr.reserved1 = 0; kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo); kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi); @@ -1527,8 +1527,10 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], ictx->tstorm_st_context.tcp.cwnd = 0x5A8; ictx->tstorm_st_context.tcp.flags2 |= TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN; + ictx->tstorm_st_context.tcp.ooo_support_mode = + TCP_TSTORM_OOO_DROP_AND_PROC_ACK; - ictx->timers_context.flags |= ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; + ictx->timers_context.flags |= TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; ictx->ustorm_st_context.ring.rq.pbl_base.lo = req2->rq_page_table_addr_lo; @@ -1717,6 +1719,7 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) int ret = 0; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; + u32 hw_cid, type; if (!(ctx->ctx_flags & CTX_FL_OFFLD_START)) goto skip_cfc_delete; @@ -1727,11 +1730,15 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) init_waitqueue_head(&ctx->waitq); ctx->wait_cond = 0; memset(&l5_data, 0, sizeof(l5_data)); - ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - req->context_id, - ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), - &l5_data); + hw_cid = BNX2X_HW_CID(cp, ctx->cid); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + + ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + hw_cid, type, &l5_data); + if (ret == 0) wait_event(ctx->waitq, ctx->wait_cond); @@ -2322,7 +2329,7 @@ static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 0, + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, CSTORM_ID, 0, IGU_INT_DISABLE, 0); } @@ -2357,7 +2364,7 @@ static void cnic_service_bnx2x_bh(unsigned long data) status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, status_idx, IGU_INT_ENABLE, 1); } @@ -3285,6 +3292,7 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; u32 pfid = cp->pfid; + u32 port = CNIC_PORT(cp); cnic_init_bnx2x_mac(dev); cnic_bnx2x_set_tcp_timestamp(dev, 1); @@ -3293,9 +3301,9 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(pfid), 1); + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port), 1); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(pfid), + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port), DEF_MAX_DA_COUNT); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + @@ -3859,32 +3867,48 @@ static int cnic_init_bnx2x_irq(struct cnic_dev *dev) return err; } +static inline void cnic_storm_memset_hc_disable(struct cnic_dev *dev, + u16 sb_id, u8 sb_index, + u8 disable) +{ + + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = CNIC_RD16(dev, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= (((~disable) << HC_INDEX_DATA_HC_ENABLED_SHIFT) & + HC_INDEX_DATA_HC_ENABLED); + CNIC_WR16(dev, addr, flags); +} + static void cnic_enable_bnx2x_int(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), - 64 / 12); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), 0); + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*HC_INDEX_ISCSI_EQ_CONS + + offsetof(struct hc_index_data, timeout), 64 / 12); + cnic_storm_memset_hc_disable(dev, sb_id, HC_INDEX_ISCSI_EQ_CONS, 0); } static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev) { } -static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring; - struct eth_context *context; - struct regpair context_addr; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = cp->l2_ring_map; + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int port = CNIC_PORT(cp); int i; int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); @@ -3909,33 +3933,23 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr); - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; txbd->next_bd.addr_hi = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_hi = val; + data->tx.tx_bd_page_base.hi = cpu_to_le32(val); - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; txbd->next_bd.addr_lo = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_lo = val; - - context->cstorm_st_context.sb_index_number = - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS; - context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID; - - if (cli < MAX_X_STAT_COUNTER_ID) - context->xstorm_st_context.statistics_data = cli | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE; + data->tx.tx_bd_page_base.lo = cpu_to_le32(val); - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); + /* Other ramrod params */ + data->tx.tx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_CQ_CONS; + data->tx.tx_status_block_id = BNX2X_DEF_SB_ID; /* reset xstorm per client statistics */ - if (cli < MAX_X_STAT_COUNTER_ID) { + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_XSTRORM_INTMEM + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) @@ -3943,24 +3957,31 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) } cp->tx_cons_ptr = - &cp->bnx2x_def_status_blk->c_def_status_block.index_values[ - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_CQ_CONS]; } -static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) (cp->l2_ring + (2 * BCM_PAGE_SIZE)); - struct eth_context *context; - struct regpair context_addr; + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; int port = CNIC_PORT(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; - struct tstorm_eth_client_config tstorm_client = {0}; + dma_addr_t ring_map = cp->l2_ring_map; + + /* General data */ + data->general.client_id = cli; + data->general.statistics_en_flg = 1; + data->general.statistics_counter_id = cli; + data->general.activate_flg = 1; + data->general.sp_client_id = cli; for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; @@ -3970,83 +3991,42 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32); rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr); - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; rxbd->addr_hi = cpu_to_le32(val); + data->rx.bd_page_base.hi = cpu_to_le32(val); - context->ustorm_st_context.common.bd_page_base_hi = val; - - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; rxbd->addr_lo = cpu_to_le32(val); - - context->ustorm_st_context.common.bd_page_base_lo = val; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_ISCSI_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cli; - context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID; - if (cli < MAX_U_STAT_COUNTER_ID) { - context->ustorm_st_context.common.flags = - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; - context->ustorm_st_context.common.statistics_counter_id = cli; - } - context->ustorm_st_context.common.mc_alignment_log_size = 0; - context->ustorm_st_context.common.bd_buff_size = - cp->l2_single_buf_size; - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(cp, BNX2X_ISCSI_L2_CID), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); + data->rx.bd_page_base.lo = cpu_to_le32(val); rxcqe += BNX2X_MAX_RCQ_DESC_CNT; - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) >> 32; rxcqe->addr_hi = cpu_to_le32(val); + data->rx.cqe_page_base.hi = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli) + 4, val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val); - - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; rxcqe->addr_lo = cpu_to_le32(val); + data->rx.cqe_page_base.lo = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli), val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli), val); - - /* client tstorm info */ - tstorm_client.mtu = cp->l2_single_buf_size - 14; - tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE; - - if (cli < MAX_T_STAT_COUNTER_ID) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; - tstorm_client.statistics_counter_id = cli; - } + /* Other ramrod params */ + data->rx.client_qzone_id = cl_qzone_id; + data->rx.rx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS; + data->rx.status_block_id = BNX2X_DEF_SB_ID; - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli), - ((u32 *)&tstorm_client)[0]); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli) + 4, - ((u32 *)&tstorm_client)[1]); + data->rx.cache_line_alignment_log_size = L1_CACHE_SHIFT; + data->rx.bd_buff_size = cpu_to_le16(cp->l2_single_buf_size); - /* reset tstorm per client statistics */ - if (cli < MAX_T_STAT_COUNTER_ID) { + data->rx.mtu = cpu_to_le16(cp->l2_single_buf_size - 14); + data->rx.outer_vlan_removal_enable_flg = 1; + /* reset tstorm and ustorm per client statistics */ + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_TSTRORM_INTMEM + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) CNIC_WR(dev, val + i * 4, 0); - } - /* reset ustorm per client statistics */ - if (cli < MAX_U_STAT_COUNTER_ID) { val = BAR_USTRORM_INTMEM + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) @@ -4054,8 +4034,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) } cp->rx_cons_ptr = - &cp->bnx2x_def_status_blk->u_def_status_block.index_values[ - HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; } static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) @@ -4066,7 +4045,7 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) dev->max_iscsi_conn = 0; base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR); - if (base < 0xa0000 || base >= 0xc0000) + if (base == 0) return; addr = BNX2X_SHMEM_ADDR(base, @@ -4103,14 +4082,19 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) } if (BNX2X_CHIP_IS_E1H(cp->chip_id)) { int func = CNIC_FUNC(cp); + u32 mf_cfg_addr; + + mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; + + addr = mf_cfg_addr + + offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].e1hov_tag); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].config); + addr = mf_cfg_addr + + offsetof(struct mf_cfg, + func_mf_config[func].config); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_PROTOCOL_MASK; if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) @@ -4122,11 +4106,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) static int cnic_start_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_eth_dev *ethdev = cp->ethdev; int func = CNIC_FUNC(cp), ret, i; - int port = CNIC_PORT(cp); u32 pfid; - u16 eq_idx; - u8 sb_id = cp->status_blk_num; + struct host_hc_status_block_e1x *sb = cp->status_blk.gen; cp->pfid = func; pfid = cp->pfid; @@ -4137,15 +4120,16 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return -ENOMEM; + cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2; + cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; cp->kcq1.hw_prod_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.index_values[ - HC_INDEX_C_ISCSI_EQ_CONS]; + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; cp->kcq1.status_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.status_block_index; + &sb->sb.running_index[SM_RX_ID]; cnic_get_bnx2x_iscsi_info(dev); @@ -4171,7 +4155,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfid, 0), cp->status_blk_num); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0), - HC_INDEX_C_ISCSI_EQ_CONS); + HC_INDEX_ISCSI_EQ_CONS); for (i = 0; i < cp->conn_buf_info.num_pages; i++) { CNIC_WR(dev, BAR_TSTRORM_INTMEM + @@ -4189,16 +4173,11 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid) + 4, (u64) cp->gbl_buf_info.pg_map_arr[0] >> 32); + CNIC_WR(dev, BAR_TSTRORM_INTMEM + + TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfid), DEF_RCV_BUF); + cnic_setup_bnx2x_context(dev); - eq_idx = CNIC_RD16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS])); - if (eq_idx != 0) { - netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx); - return -EBUSY; - } ret = cnic_init_bnx2x_irq(dev); if (ret) return ret; @@ -4218,8 +4197,9 @@ static void cnic_init_rings(struct cnic_dev *dev) cnic_init_bnx2_rx_ring(dev); set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - struct cnic_local *cp = dev->cnic_priv; u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cl_qzone_id, type; + struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; struct ustorm_eth_rx_producers rx_prods = {0}; u32 off, i; @@ -4228,23 +4208,36 @@ static void cnic_init_rings(struct cnic_dev *dev) rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT; barrier(); + cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); + off = BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(CNIC_PORT(cp), cli); + USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]); set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); - cnic_init_bnx2x_tx_ring(dev); - cnic_init_bnx2x_rx_ring(dev); + data = cp->l2_buf; + + memset(data, 0, sizeof(*data)); + + cnic_init_bnx2x_tx_ring(dev, data); + cnic_init_bnx2x_rx_ring(dev, data); + + l5_data.phy_address.lo = cp->l2_buf_map & 0xffffffff; + l5_data.phy_address.hi = (u64) cp->l2_buf_map >> 32; + + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); - l5_data.phy_address.lo = cli; - l5_data.phy_address.hi = 0; cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); + BNX2X_ISCSI_L2_CID, type, &l5_data); + i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && ++i < 10) @@ -4272,6 +4265,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); union l5cm_specific_data l5_data; int i; + u32 type; cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0); @@ -4292,9 +4286,12 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) cnic_kwq_completion(dev, 1); memset(&l5_data, 0, sizeof(l5_data)); - cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + BNX2X_ISCSI_L2_CID, type, &l5_data); msleep(10); } clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); @@ -4392,15 +4389,9 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev) static void cnic_stop_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); cnic_free_irq(dev); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS]), - 0); + *cp->kcq1.hw_prod_idx_ptr = 0; CNIC_WR(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_EQ_CONS_OFFSET(cp->pfid, 0), 0); CNIC_WR16(dev, cp->kcq1.io_addr, 0); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 481618399b1f..676d008509c6 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -12,6 +12,13 @@ #ifndef CNIC_H #define CNIC_H +#define HC_INDEX_ISCSI_EQ_CONS 6 + +#define HC_INDEX_FCOE_EQ_CONS 3 + +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + #define KWQ_PAGE_CNT 4 #define KCQ_PAGE_CNT 16 @@ -179,6 +186,14 @@ struct kcq_info { u32 io_addr; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + struct cnic_local { spinlock_t cnic_ulp_lock; @@ -213,6 +228,9 @@ struct cnic_local { u16 rx_cons; u16 tx_cons; + struct iro *iro_arr; +#define IRO (((struct cnic_local *) dev->cnic_priv)->iro_arr) + struct cnic_dma kwq_info; struct kwqe **kwq; @@ -231,12 +249,16 @@ struct cnic_local { union { void *gen; struct status_block_msix *bnx2; - struct host_status_block *bnx2x; + struct host_hc_status_block_e1x *bnx2x_e1x; + /* index values - which counter to update */ + #define SM_RX_ID 0 + #define SM_TX_ID 1 } status_blk; - struct host_def_status_block *bnx2x_def_status_blk; + struct host_sp_status_block *bnx2x_def_status_blk; u32 status_blk_num; + u32 bnx2x_igu_sb_id; u32 int_num; u32 last_status_idx; struct tasklet_struct cnic_irq_task; @@ -358,24 +380,33 @@ struct bnx2x_bd_chain_next { (BNX2X_MAX_RCQ_DESC_CNT - 1)) ? \ ((x) + 2) : ((x) + 1) -#define BNX2X_DEF_SB_ID 16 +#define BNX2X_DEF_SB_ID HC_SP_SB_ID -#define BNX2X_ISCSI_RX_SB_INDEX_NUM \ - ((HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) +#define BNX2X_SHMEM_MF_BLK_OFFSET 0x7e4 #define BNX2X_SHMEM_ADDR(base, field) (base + \ offsetof(struct shmem_region, field)) -#define CNIC_PORT(cp) ((cp)->func % PORT_MAX) +#define BNX2X_SHMEM2_ADDR(base, field) (base + \ + offsetof(struct shmem2_region, field)) + +#define BNX2X_SHMEM2_HAS(base, field) \ + ((base) && \ + (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \ + offsetof(struct shmem2_region, field))) + +#define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) -#define CNIC_E1HVN(cp) ((cp)->func >> 1) +#define CNIC_E1HVN(cp) ((cp)->pfid >> 1) -#define BNX2X_HW_CID(cp, x) (((CNIC_FUNC(cp) % PORT_MAX) << 23) | \ +#define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \ (CNIC_E1HVN(cp) << 17) | (x)) #define BNX2X_SW_CID(x) (x & 0x1ffff) +#define BNX2X_CL_QZONE_ID(cp, cli) \ + (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H)) + +#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4) #endif diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h index 7ce694d41b6b..328e8b2765a3 100644 --- a/drivers/net/cnic_defs.h +++ b/drivers/net/cnic_defs.h @@ -14,6 +14,7 @@ /* KWQ (kernel work queue) request op codes */ #define L2_KWQE_OPCODE_VALUE_FLUSH (4) +#define L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE (8) #define L4_KWQE_OPCODE_VALUE_CONNECT1 (50) #define L4_KWQE_OPCODE_VALUE_CONNECT2 (51) @@ -48,11 +49,14 @@ #define L4_KCQE_OPCODE_VALUE_UPLOAD_PG (14) /* KCQ (kernel completion queue) completion status */ -#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) -#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) +#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) +#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) -#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) -#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) +#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) +#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) + +#define L4_KCQE_OPCODE_VALUE_OOO_EVENT_NOTIFICATION (0xa0) +#define L4_KCQE_OPCODE_VALUE_OOO_FLUSH (0xa1) #define L4_LAYER_CODE (4) #define L2_LAYER_CODE (2) @@ -584,6 +588,100 @@ struct l4_kwq_upload { * bnx2x structures */ +/* + * The iscsi aggregative context of Cstorm + */ +struct cstorm_iscsi_ag_context { + u32 agg_vars1; +#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) +#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 +#if defined(__BIG_ENDIAN) + u8 __aux1_th; + u8 __aux1_val; + u16 __agg_vars2; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_vars2; + u8 __aux1_val; + u8 __aux1_th; +#endif + u32 rel_seq; + u32 rel_seq_th; +#if defined(__BIG_ENDIAN) + u16 hq_cons; + u16 hq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 hq_prod; + u16 hq_cons; +#endif +#if defined(__BIG_ENDIAN) + u8 __reserved62; + u8 __reserved61; + u8 __reserved60; + u8 __reserved59; +#elif defined(__LITTLE_ENDIAN) + u8 __reserved59; + u8 __reserved60; + u8 __reserved61; + u8 __reserved62; +#endif +#if defined(__BIG_ENDIAN) + u16 __reserved64; + u16 __cq_u_prod0; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod0; + u16 __reserved64; +#endif + u32 __cq_u_prod1; +#if defined(__BIG_ENDIAN) + u16 __agg_vars3; + u16 __cq_u_prod2; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod2; + u16 __agg_vars3; +#endif +#if defined(__BIG_ENDIAN) + u16 __aux2_th; + u16 __cq_u_prod3; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod3; + u16 __aux2_th; +#endif +}; + /* * iSCSI context region, used only in iSCSI */ @@ -696,7 +794,7 @@ struct ustorm_iscsi_st_context { struct regpair task_pbl_base; struct regpair tce_phy_addr; struct ustorm_iscsi_placement_db place_db; - u32 data_rcv_seq; + u32 reserved8; u32 rem_rcv_len; #if defined(__BIG_ENDIAN) u16 hdr_itt; @@ -713,8 +811,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 task_pdu_cache_index; u8 task_pbe_cache_index; #elif defined(__LITTLE_ENDIAN) @@ -725,8 +825,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 hdr_second_byte_union; #endif #if defined(__BIG_ENDIAN) @@ -777,14 +879,14 @@ struct ustorm_iscsi_st_context { */ struct tstorm_tcp_st_context_section { u32 flags1; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25) #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25 -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS (0x1<<26) -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS_SHIFT 26 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26 #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27) #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27 #define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28) @@ -793,11 +895,11 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29 #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30) #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30 -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3 (0x1<<31) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3_SHIFT 31 +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31) +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31 u32 flags2; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25) @@ -810,18 +912,18 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28 #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29) #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED (0x1<<30) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED_SHIFT 30 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO (0x1<<31) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO_SHIFT 31 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31 #if defined(__BIG_ENDIAN) - u16 reserved_slowpath; - u8 tcp_sm_state_3b; - u8 rto_exp_3b; + u16 mss; + u8 tcp_sm_state; + u8 rto_exp; #elif defined(__LITTLE_ENDIAN) - u8 rto_exp_3b; - u8 tcp_sm_state_3b; - u16 reserved_slowpath; + u8 rto_exp; + u8 tcp_sm_state; + u16 mss; #endif u32 rcv_nxt; u32 timestamp_recent; @@ -846,11 +948,11 @@ struct tstorm_tcp_st_context_section { #if defined(__BIG_ENDIAN) u8 statistics_counter_id; u8 ooo_support_mode; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 dup_ack_count; #elif defined(__LITTLE_ENDIAN) u8 dup_ack_count; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 ooo_support_mode; u8 statistics_counter_id; #endif @@ -860,13 +962,21 @@ struct tstorm_tcp_st_context_section { u32 isle_start_seq; u32 isle_end_seq; #if defined(__BIG_ENDIAN) - u16 mss; + u16 second_isle_address; u16 recent_seg_wnd; #elif defined(__LITTLE_ENDIAN) u16 recent_seg_wnd; - u16 mss; + u16 second_isle_address; +#endif +#if defined(__BIG_ENDIAN) + u8 max_isles_ever_happened; + u8 isles_number; + u16 last_isle_address; +#elif defined(__LITTLE_ENDIAN) + u16 last_isle_address; + u8 isles_number; + u8 max_isles_ever_happened; #endif - u32 reserved4; u32 max_rt_time; #if defined(__BIG_ENDIAN) u16 lsb_mac_address; @@ -876,7 +986,7 @@ struct tstorm_tcp_st_context_section { u16 lsb_mac_address; #endif u32 msb_mac_address; - u32 reserved2; + u32 rightmost_received_seq; }; /* @@ -951,7 +1061,7 @@ struct tstorm_iscsi_st_context_section { u8 scratchpad_idx; struct iscsi_term_vars term_vars; #endif - u32 reserved2; + u32 process_nxt; }; /* @@ -1174,24 +1284,12 @@ struct xstorm_iscsi_ag_context { #endif #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 + u8 __agg_vars4; u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 u8 agg_vars2; #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 @@ -1222,21 +1320,9 @@ struct xstorm_iscsi_ag_context { u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 __agg_vars4; u8 cdu_reserved; #endif u32 more_to_send; @@ -1270,8 +1356,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1286,8 +1372,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 u8 agg_val3_th; u8 agg_vars6; #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) @@ -1310,8 +1396,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1326,14 +1412,14 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 #endif #if defined(__BIG_ENDIAN) u16 __agg_val11_th; - u16 __agg_val11; + u16 __gen_data; #elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; + u16 __gen_data; u16 __agg_val11_th; #endif #if defined(__BIG_ENDIAN) @@ -1384,7 +1470,7 @@ struct xstorm_iscsi_ag_context { #endif u32 hq_cons_tcp_seq; u32 exp_stat_sn; - u32 agg_misc5; + u32 rst_seq_num; }; /* @@ -1478,12 +1564,12 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u8 state; #elif defined(__LITTLE_ENDIAN) u8 state; @@ -1496,63 +1582,63 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u16 ulp_credit; #endif #if defined(__BIG_ENDIAN) u16 __agg_val4; u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 #elif defined(__LITTLE_ENDIAN) u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) @@ -1562,100 +1648,6 @@ struct tstorm_iscsi_ag_context { struct tstorm_tcp_tcp_ag_context_section tcp; }; -/* - * The iscsi aggregative context of Cstorm - */ -struct cstorm_iscsi_ag_context { - u32 agg_vars1; -#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) -#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 rel_seq; - u32 rel_seq_th; -#if defined(__BIG_ENDIAN) - u16 hq_cons; - u16 hq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 hq_prod; - u16 hq_cons; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __cq_u_prod0; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod0; - u16 __reserved64; -#endif - u32 __cq_u_prod1; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __cq_u_prod2; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod2; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __aux2_th; - u16 __cq_u_prod3; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod3; - u16 __aux2_th; -#endif -}; - /* * The iscsi aggregative context of Ustorm */ @@ -1746,8 +1738,8 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u8 decision_rule_enable_bits; @@ -1790,30 +1782,14 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u16 __reserved2; #endif }; -/* - * Timers connection context - */ -struct iscsi_timers_block_context { - u32 __reserved_0; - u32 __reserved_1; - u32 __reserved_2; - u32 flags; -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0 -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2) -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2 -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3 -}; - /* * Ethernet context section, shared in TOE, RDMA and ISCSI */ @@ -1963,7 +1939,7 @@ struct xstorm_tcp_context_section { #endif #if defined(__BIG_ENDIAN) u8 original_nagle_1b; - u8 ts_enabled_1b; + u8 ts_enabled; u16 tcp_params; #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 @@ -1973,8 +1949,8 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) @@ -1991,15 +1967,15 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 - u8 ts_enabled_1b; + u8 ts_enabled; u8 original_nagle_1b; #endif #if defined(__BIG_ENDIAN) @@ -2030,8 +2006,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u8 ip_version_1b; #elif defined(__LITTLE_ENDIAN) u8 ip_version_1b; @@ -2042,8 +2018,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u16 reserved; #endif }; @@ -2284,7 +2260,7 @@ struct iscsi_context { struct tstorm_iscsi_ag_context tstorm_ag_context; struct cstorm_iscsi_ag_context cstorm_ag_context; struct ustorm_iscsi_ag_context ustorm_ag_context; - struct iscsi_timers_block_context timers_context; + struct timers_block_context timers_context; struct regpair upb_context; struct xstorm_iscsi_st_context xstorm_st_context; struct regpair xpb_context; @@ -2434,16 +2410,16 @@ struct l5cm_packet_size { * l5cm connection parameters */ union l5cm_reduce_param_union { - u32 passive_side_scramble_key; - u32 pcs_id; + u32 opaque1; + u32 opaque2; }; /* * l5cm connection parameters */ struct l5cm_reduce_conn { - union l5cm_reduce_param_union param; - u32 isn; + union l5cm_reduce_param_union opaque1; + u32 opaque2; }; /* diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 344c842d55ab..4018de12f819 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -138,6 +138,7 @@ struct cnic_irq { unsigned int vector; void *status_blk; u32 status_blk_num; + u32 status_blk_num2; u32 irq_flags; #define CNIC_IRQ_FL_MSIX 0x00000001 }; @@ -152,6 +153,7 @@ struct cnic_eth_dev { struct pci_dev *pdev; void __iomem *io_base; void __iomem *io_base2; + void *iro_arr; u32 ctx_tbl_offset; u32 ctx_tbl_len; diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 00c033511cbf..99568cb9ad1c 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -58,6 +58,8 @@ #define MAX_PAGES_PER_CTRL_STRUCT_POOL 8 #define BNX2I_RESERVED_SLOW_PATH_CMD_SLOTS 4 +#define BNX2I_5771X_DBELL_PAGE_SIZE 128 + /* 5706/08 hardware has limit on maximum buffer size per BD it can handle */ #define MAX_BD_LENGTH 65535 #define BD_SPLIT_SIZE 32768 diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index d23fc256d585..99c71e6d4c14 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2405,7 +2405,8 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { reg_base = pci_resource_start(ep->hba->pcidev, BNX2X_DOORBELL_PCI_BAR); - reg_off = PAGE_SIZE * (cid_num & 0x1FFFF) + DPM_TRIGER_TYPE; + reg_off = BNX2I_5771X_DBELL_PAGE_SIZE * (cid_num & 0x1FFFF) + + DPM_TRIGER_TYPE; ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, 4); goto arm_cq; } diff --git a/firmware/Makefile b/firmware/Makefile index 44b3aae66b84..e0a3439ab312 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,8 +32,8 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-5.2.13.0.fw \ - bnx2x/bnx2x-e1h-5.2.13.0.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ + bnx2x/bnx2x-e1h-6.0.34.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ -- cgit v1.2.3 From 6f7aeeec7e142caf30e3b420c2411ad85f23b9f5 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 15:25:08 +0200 Subject: bnx2x: remove old FW files Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex | 10191 ---------------------- firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex | 12849 ---------------------------- 2 files changed, 23040 deletions(-) delete mode 100644 firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex delete mode 100644 firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex diff --git a/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex deleted file mode 100644 index 651f4346d89e..000000000000 --- a/firmware/bnx2x/bnx2x-e1-5.2.13.0.fw.ihex +++ /dev/null @@ -1,10191 +0,0 @@ -:10000000000028B0000000600000068800002918E9 -:100010000000161400002FA800000098000045C042 -:10002000000073C400004660000000CC0000BA2845 -:1000300000009A700000BAF80000009400015570AA -:10004000000057BC00015608000000B80001ADC810 -:100050000000CE200001AE880000000400027CB049 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000060400CC0000000418 -:10010000020400DC00100000020400E012140000F1 -:10011000020400E422140000020400E8321400008B -:10012000060400EC000000040104012400000000AB -:1001300001040128000000000104012C000000005F -:10014000010401300000000002040004000000FF70 -:1001500002040008000000FF0204000C000000FF81 -:1001600002040010000000FF02040014000000FF61 -:1001700002040018000000FF0204001C000000FF41 -:1001800002040020000000FF020400240000003EE2 -:1001900002040028000000000204002C0000003FC0 -:1001A000020400300000003F020400340000003F61 -:1001B00002040038000000000204003C0000003F80 -:1001C000020400400000003F020400440000003F21 -:1001D00002042008000004110204200C00000400A6 -:1001E000020420100000040402042014000004197A -:1001F0000204201C0000FFFF020420200000FFFF7B -:10020000020420240000FFFF020420280000FFFF5A -:1002100006042038000000020204204000000034E0 -:100220000204204400000035060420480000007C41 -:100230000204223807FFFFFF0204223C0000003FB7 -:100240000204224007FFFFFF020422440000000FC7 -:1002500001042248000000000104224C00000000BC -:10026000010422500000000001042254000000009C -:1002700001042258000000000104225C000000007C -:10028000010422600000000001042264000000005C -:1002900001042268000000000104226C000000003C -:1002A000010422700000000001042274000000001C -:1002B00001042278000000000104227C00000000FC -:1002C000020424BC000000010C042000000003E82C -:1002D0000A042000000000010B0420000000000AB6 -:1002E0000205004400000020020500480000003222 -:1002F000020500900215002002050094021500205E -:1003000002050098000000300205009C0810000063 -:10031000020500A000000033020500A40000003028 -:10032000020500A800000031020500AC0000000238 -:10033000020500B000000005020500B40000000640 -:10034000020500B800000002020500BC0000000227 -:10035000020500C000000000020500C40000000506 -:10036000020500C800000002020500CC00000002E7 -:10037000020500D000000002020500D400000001C8 -:1003800002050114000000010205011C000000012B -:100390000205012000000002020502040000000125 -:1003A0000205020C0000004002050210000000409F -:1003B0000205021C000000200205022000000013BC -:1003C0000205022400000020060502400000000A89 -:1003D0000405028000200000020500500000000714 -:1003E0000205005400000007020500580000000844 -:1003F0000205005C00000008060500600000000423 -:10040000020500D800000006020500E00000000D13 -:10041000020500E40000002D020500E800000007CE -:10042000020500EC00000027020500F000000007B4 -:10043000020500F400000027020500F80000000794 -:10044000020500FC00000027020500040000000176 -:1004500002050008000000010205000C0000000178 -:100460000205001000000001020500140000000158 -:1004700002050018000000010205001C0000000138 -:100480000205002000000001020500240000000118 -:1004900002050028000000010205002C00000001F8 -:1004A00002050030000000010205003400000001D8 -:1004B00002050038000000010205003C00000001B8 -:1004C00002050040000000010406100002000020A8 -:1004D000020600DC00000001010600D80000000058 -:1004E0000406020000030220020600DC00000000F7 -:1004F00002060068000000B802060078000001143F -:10050000010600B800000000010600C8000000005D -:100510000206006C000000B80206007C0000011416 -:10052000010600BC00000000010600CC0000000035 -:100530000718040000950000081807600014022343 -:10054000071C000034D40000071C800034CF0D3697 -:10055000071D00000A191A6A081D14605D7402253F -:100560000118000000000000011800040000000055 -:1005700001180008000000000118000C0000000035 -:100580000118001000000000011800140000000015 -:1005900002180020000000010218002400000002E0 -:1005A00002180028000000030218002C00000000C0 -:1005B000021800300000000402180034000000019E -:1005C00002180038000000000218003C0000000182 -:1005D000021800400000000402180044000000005F -:1005E00002180048000000010218004C000000033F -:1005F0000218005000000000021800540000000122 -:1006000002180058000000040218005C00000000FE -:1006100002180060000000010218006400000003DE -:1006200002180068000000000218006C00000001C1 -:10063000021800700000000402180074000000009E -:1006400002180078000000040218007C000000037B -:100650000618008000000002021800A400003FFFFE -:10066000021800A8000003FF021802240000000086 -:1006700002180234000000000218024C00000000C2 -:10068000021802E4000000FF061810000000040039 -:10069000021B8BC000000001021B80000000003420 -:1006A000021B804000000018021B80800000000C2C -:1006B000021B80C0000000200C1B83000007A1204B -:1006C0000A1B8300000001380B1B83000000138805 -:1006D000021B83C0000001F4061A2000000000B2D3 -:1006E000061A23C800000181041A29CC0001022740 -:1006F000061A1020000000C8061A100000000002B0 -:10070000061A1E3800000002061A1E300000000201 -:10071000061A080000000002061A0808000000027D -:10072000061A081000000004041A1FB00005022871 -:10073000041A4CB00008022D061A22C8000000203E -:10074000061A400000000124021A4920000000009F -:10075000061A14000000000A061A145000000006D1 -:10076000061A150000000002041A150800050235DB -:10077000061A151C00000009061A15800000001456 -:10078000061A09C000000048061A0800000000020E -:10079000061A08200000000E041A1FB00002023AD8 -:1007A000061A2C2800000002061A23480000002028 -:1007B000061A449000000124021A49240000000097 -:1007C000061A14280000000A061A14680000000621 -:1007D000061A154000000002041A15480005023CE4 -:1007E000061A155C00000009061A15D00000001456 -:1007F000061A0AE000000048061A08080000000275 -:10080000061A08580000000E041A1FB80002024120 -:10081000061A2C30000000020200A2800000000135 -:100820000200A294071D29110200A29800000000F6 -:100830000200A29C009C04240200A2A00000000070 -:100840000200A2A4000002090200A4FCFF000000B4 -:10085000020100B400000001020100B80000000124 -:10086000020100DC000000010201010000000001A3 -:1008700002010104000000010201007C00300000C0 -:1008800002010084000000280201008C000000002A -:1008900002010130000000040201025C00000001BE -:1008A000020103280000000002010554000000308E -:1008B000020100C400000001020100CC00000001A0 -:1008C000020100F800000001020100F00000000138 -:1008D00002010080003000000201008800000028B2 -:1008E0000201009000000000020101340000000439 -:1008F000020102DC000000010201032C00000000E4 -:100900000201056400000030020100C8000000017F -:10091000020100D000000001020100FC0000000103 -:10092000020100F400000001020C10000000002091 -:10093000020C200800000A11020C200C00000A0022 -:10094000020C201000000A04020C201C0000FFFF13 -:10095000020C20200000FFFF020C20240000FFFFFB -:10096000020C20280000FFFF060C203800000002C7 -:10097000020C204000000034020C2044000000352E -:10098000020C204800000020020C204C0000002136 -:10099000020C205000000022020C20540000002312 -:1009A000020C205800000024020C205C00000025EE -:1009B000020C206000000026020C206400000027CA -:1009C000020C206800000028020C206C00000029A6 -:1009D000020C20700000002A020C20740000002B82 -:1009E000060C207800000056020C21D00000000107 -:1009F000020C21D400000001020C21D800000001EB -:100A0000020C21DC00000001020C21E000000001CA -:100A1000020C21E400000001020C21E800000001AA -:100A2000020C21EC00000001020C21F0000000018A -:100A3000020C21F400000001060C21F80000001057 -:100A4000020C223807FFFFFF020C223C0000003F8F -:100A5000020C224007FFFFFF020C22440000000F9F -:100A6000010C224800000000010C224C0000000094 -:100A7000010C225000000000010C22540000000074 -:100A8000010C225800000000010C225C0000000054 -:100A9000010C226000000000010C22640000000034 -:100AA000010C226800000000010C226C0000000014 -:100AB000010C227000000000010C227400000000F4 -:100AC000010C227800000000010C227C00000000D4 -:100AD000020C24BC000000010C0C2000000003E804 -:100AE0000A0C2000000000010B0C20000000000A8E -:100AF000020C400800000365020C400C0000035487 -:100B0000020C401000000358020C40140000037552 -:100B1000020C401C0000FFFF020C40200000FFFF01 -:100B2000020C40240000FFFF020C40280000FFFFE1 -:100B3000020C403800000046020C403C000000055A -:100B4000060C40400000005E020C41B800000001AD -:100B5000060C41BC0000001F020C423807FFFFFFDB -:100B6000020C423C0000003F020C424007FFFFFF26 -:100B7000020C42440000000F010C4248000000003B -:100B8000010C424C00000000010C4250000000002B -:100B9000010C425400000000010C4258000000000B -:100BA000010C425C00000000010C426000000000EB -:100BB000010C426400000000010C426800000000CB -:100BC000010C426C00000000010C427000000000AB -:100BD000010C427400000000010C4278000000008B -:100BE000010C427C00000000010C4280000000006B -:100BF000020C44C0000000010C0C4000000003E89F -:100C00000A0C4000000000010B0C40000000000A2C -:100C1000020D004400000032020D008C021500207D -:100C2000020D009002150020020D00940810000033 -:100C3000020D009800000033020D009C000000022D -:100C4000020D00A000000000020D00A4000000053D -:100C5000020D00A800000005060D00AC0000000217 -:100C6000020D00B400000002020D00B800000003F5 -:100C7000020D00BC00000002020D00C000000001D7 -:100C8000020D00C800000002020D00CC00000002AE -:100C9000020D010800000001020D015C00000001CE -:100CA000020D016400000001020D01680000000255 -:100CB000020D020400000001020D020C00000020E1 -:100CC000020D021000000040020D0214000000405E -:100CD000020D022000000003020D02240000001893 -:100CE000060D028000000012040D030000240243E0 -:100CF000020D004C00000001020D00500000000237 -:100D0000020D005400000008020D00580000000809 -:100D1000060D005C00000004020D00C40000000489 -:100D2000020D011400000009020D01180000002945 -:100D3000020D011C0000000A020D01200000002A23 -:100D4000020D012400000007020D01280000002709 -:100D5000020D012C00000007020D013000000027E9 -:100D6000020D01340000000C020D01380000002CBF -:100D7000020D013C0000000C020D01400000002C9F -:100D8000020D01440000000C020D01480000002C7F -:100D9000020D000400000001020D00080000000127 -:100DA000020D000C00000001020D00100000000107 -:100DB000020D001400000001020D001800000001E7 -:100DC000020D001C00000001020D002000000001C7 -:100DD000020D002400000001020D002800000001A7 -:100DE000020D002C00000001020D00300000000187 -:100DF000020D003400000001020D00380000000167 -:100E0000020D003C00000001020E004C0000003208 -:100E1000020E009402150020020E00980215002018 -:100E2000020E009C00000030020E00A0081000001E -:100E3000020E00A400000033020E00A800000030E3 -:100E4000020E00AC00000031020E00B000000002F3 -:100E5000020E00B400000004020E00B80000000002 -:100E6000020E00BC00000002020E00C000000002E2 -:100E7000020E00C400000000020E00C800000002C4 -:100E8000020E00CC00000007020E00D0000000029D -:100E9000020E00D400000002020E00D80000000183 -:100EA000020E00E400000001020E014400000001F7 -:100EB000020E014C00000001020E01500000000271 -:100EC000020E020400000001020E020C00000040AD -:100ED000020E021000000040020E021C000000047E -:100EE000020E022000000020020E02240000000E6C -:100EF000020E02280000001B060E03000000001274 -:100F0000040E0280001B0267020E00540000000C59 -:100F1000020E005800000009020E005C0000000FE5 -:100F2000020E006000000010060E006400000004C5 -:100F3000020E00DC00000003020E01100000000F92 -:100F4000020E01140000002F020E01180000000E16 -:100F5000020E011C0000002E020E00040000000121 -:100F6000020E000800000001020E000C000000014B -:100F7000020E001000000001020E0014000000012B -:100F8000020E001800000001020E001C000000010B -:100F9000020E002000000001020E002400000001EB -:100FA000020E002800000001020E002C00000001CB -:100FB000020E003000000001020E003400000001AB -:100FC000020E003800000001020E003C000000018B -:100FD000020E004000000001020E0044000000016B -:100FE0000730040000C900000830076800130282BF -:100FF00007340000334B00000734800037090CD35E -:101000000735000030161A96083572F051A2028496 -:10101000013000000000000001300004000000006A -:1010200001300008000000000130000C000000004A -:10103000013000100000000001300014000000002A -:1010400002300020000000010230002400000002F5 -:1010500002300028000000030230002C00000000D5 -:1010600002300030000000040230003400000001B3 -:1010700002300038000000000230003C0000000197 -:101080000230004000000004023000440000000074 -:1010900002300048000000010230004C0000000354 -:1010A0000230005000000000023000540000000137 -:1010B00002300058000000040230005C0000000014 -:1010C00002300060000000010230006400000003F4 -:1010D00002300068000000000230006C00000001D7 -:1010E00002300070000000040230007400000000B4 -:1010F00002300078000000040230007C0000000391 -:101100000630008000000002023000A400003FFF13 -:10111000023000A8000003FF02300224000000009B -:1011200002300234000000000230024C00000000D7 -:10113000023002E40000FFFF06302000000008003B -:1011400002338BC000000001023380000000001A4F -:10115000023380400000004E023380800000001007 -:10116000023380C0000000200C3383000007A12060 -:101170000A338300000001380B338300000013881A -:10118000023383C0000001F40C3383801DCD650061 -:101190000A3383800004C4B40B338380004C4B407B -:1011A00006321AA0000000C206321020000000C85B -:1011B0000632100000000002063214000000004059 -:1011C00006325098000000040632508000000005EE -:1011D00004325094000102860632500000000020C4 -:1011E00004322830000202870233080001000000A8 -:1011F00004330C00001002890233080000000000D4 -:1012000004330C400010029906321500000000B4AF -:1012100002321DC80000000006324000000000D865 -:10122000063217D0000000B402321DCC00000000CE -:1012300006324360000000D807200400009200003E -:1012400008200780001002A9072400002CD100000C -:10125000072480002AE50B350824DC6062DA02AB43 -:101260000120000000000000012000040000000038 -:1012700001200008000000000120000C0000000018 -:1012800001200010000000000120001400000000F8 -:1012900002200020000000010220002400000002C3 -:1012A00002200028000000030220002C00000000A3 -:1012B0000220003000000004022000340000000181 -:1012C00002200038000000000220003C0000000165 -:1012D0000220004000000004022000440000000042 -:1012E00002200048000000010220004C0000000322 -:1012F0000220005000000000022000540000000105 -:1013000002200058000000040220005C00000000E1 -:1013100002200060000000010220006400000003C1 -:1013200002200068000000000220006C00000001A4 -:101330000220007000000004022000740000000081 -:1013400002200078000000040220007C000000035E -:101350000620008000000002022000A400003FFFE1 -:10136000022000A8000003FF022002240000000069 -:1013700002200234000000000220024C00000000A5 -:10138000022002E40000FFFF062020000000080009 -:1013900002238BC000000001022380000000001027 -:1013A00002238040000000120223808000000030F1 -:1013B000022380C00000000E022383C0000001F45D -:1013C000062250000000004206221020000000C843 -:1013D000062210000000000206222000000000C0CB -:1013E000062225C00000024004222EC8000802ADDB -:1013F00002230800013FFFFF04230C00001002B588 -:10140000022308000000000004230C40001002C565 -:1014100006223040000000A00622354000000010E7 -:10142000062236C000000030062240000000020004 -:10143000062235C00000002006223840000000309F -:1014400006223000000000080222511800000000AF -:10145000062223000000000E0622241000000030A7 -:10146000062232C0000000A00622358000000010D5 -:1014700006223780000000300622480000000200EB -:10148000062236400000002006223900000000300D -:1014900006223020000000080222511C000000003B -:1014A000062223380000000E062224D0000000305F -:1014B00002161000000000280217000800000002B9 -:1014C0000217002C000000030217003C000000047B -:1014D0000217004400000008021700480000000244 -:1014E0000217004C0000009002170050000000900E -:1014F00002170054008000900217005808140000E2 -:10150000021700600000008A0217006400000080DB -:1015100002170068000000810217006C00000080C4 -:10152000021700700000000602170078000007D0C4 -:101530000217007C0000076C02170038007C1004C2 -:10154000021700040000000F0616402400000002ED -:10155000021640700000001C021642080000000144 -:101560000216421000000001021642200000000195 -:10157000021642280000000102164230000000015D -:10158000021642380000000102164260000000010D -:101590000C16401C0003D0900A16401C0000009C52 -:1015A0000B16401C000009C4021640300000000861 -:1015B000021640340000000C0216403800000010F3 -:1015C0000216404400000020021640000000000106 -:1015D000021640D800000001021640080000000179 -:1015E0000216400C0000000102164010000000012D -:1015F00002164240000000000216424800000000AF -:101600000616427000000002021642500000000060 -:101610000216425800000000061642800000000238 -:1016200002166008000006140216600C0000060096 -:1016300002166010000006040216601C0000FFFF86 -:10164000021660200000FFFF021660240000FFFF6A -:10165000021660280000FFFF02166038000000201C -:101660000216603C000000200216604000000034BA -:101670000216604400000035021660480000002396 -:101680000216604C00000024021660500000002585 -:101690000216605400000026021660580000002761 -:1016A0000216605C00000029021660600000002A3B -:1016B000021660640000002B021660680000002C17 -:1016C0000216606C0000002D0616607000000052CB -:1016D000021661B800000001061661BC0000001F80 -:1016E0000216623807FFFFFF0216623C0000003F4F -:1016F0000216624007FFFFFF021662440000000F5F -:1017000001166248000000000116624C0000000053 -:101710000116625000000000011662540000000033 -:1017200001166258000000000116625C0000000013 -:1017300001166260000000000116626400000000F3 -:1017400001166268000000000116626C00000000D3 -:1017500001166270000000000116627400000000B3 -:1017600001166278000000000116627C0000000093 -:10177000021664BC000000010C166000000003E8C3 -:101780000A166000000000010B1660000000000A4D -:10179000021680400000000602168044000000058A -:1017A000021680480000000A0216804C0000000566 -:1017B0000216805400000002021680CC00000004D3 -:1017C000021680D000000004021680D4000000043D -:1017D000021680D800000004021680DC000000041D -:1017E000021680E000000004021680E400000004FD -:1017F000021680E8000000040216880400000004BD -:10180000021680300000007C021680340000003D8B -:10181000021680380000003F0216803C0000009C49 -:10182000021680F000000007061680F40000000594 -:101830000216880C01010101021681080000000057 -:101840000216810C00000004021681100000000442 -:1018500002168114000000020216881008012004FC -:1018600002168118000000050216811C0000000508 -:1018700002168120000000050216812400000005E8 -:101880000216882C2008100102168128000000088A -:101890000216812C000000060216813000000007AD -:1018A0000216813400000000021688300101012078 -:1018B0000616813800000004021688340101010177 -:1018C0000616814800000004021688380101010153 -:1018D00006168158000000040216883C010101012F -:1018E00006168168000000030216817400000001E2 -:1018F00002168840010101010216817800000001F2 -:101900000216817C000000010216818000000001A7 -:1019100002168184000000010216884401010101C1 -:1019200002168188000000010216818C000000046C -:10193000021681900000000402168194000000024B -:10194000021688480801200402168198000000054C -:101950000216819C00000005021681A0000000050F -:10196000021681A400000005021688142008100148 -:10197000021681A800000008021681AC00000006D3 -:10198000021681B000000007021681B400000001B9 -:101990000216881801010120021681B8000000011A -:1019A000021681BC00000001021681C00000000187 -:1019B000021681C4000000010216881C0101010109 -:1019C000021681C800000001021681CC000000014F -:1019D000021681D000000001021681D4000000012F -:1019E0000216882001010101021681D800000001C1 -:1019F000021681DC00000001021681E000000001F7 -:101A0000021681E400000001021688240101010190 -:101A1000021681E800000001021681EC00000001BE -:101A2000021681F000000001021688280101010160 -:101A300002168240FFFF003F0616824400000002AB -:101A40000216824CFFFF003F021682500000010088 -:101A5000021682540000010006168258000000029F -:101A600002168260000000C002168264000000C0FE -:101A70000216826800001E000216826C00001E0022 -:101A800002168270000040000216827400004000BE -:101A900002168278000080000216827C000080001E -:101AA00002168280000020000216828400002000BE -:101AB0000616828800000007021682A400000001BA -:101AC000061682A80000000A021681F400000C0825 -:101AD000021681F800000040021681FC000001009F -:101AE0000216820000000020021682040000001787 -:101AF00002168208000000800216820C000002001C -:101B0000021682100000000002168218FFFF01FF7B -:101B100002168214FFFF01FF0216823C0000001330 -:101B2000021680900000013F021680600000014014 -:101B30000216806400000140061680680000000262 -:101B400002168070000000C00616807400000007B6 -:101B50000216809C00000048021680A00000004889 -:101B6000061680A400000002021680AC00000048A7 -:101B7000061680B0000000070216823800008000C0 -:101B800002168234000025E40216809400007FFFD4 -:101B900002168220000000070216821C00000007C7 -:101BA000021682280000000002168224FFFFFFFFB9 -:101BB00002168230000000000216822CFFFFFFFF99 -:101BC000021680EC000000FF02140000000000017B -:101BD0000214000C0000000102140040000000018B -:101BE0000214004400007FFF0214000C00000000FB -:101BF00002140000000000000214006C000000004D -:101C00000214000400000001021400300000000172 -:101C100002140004000000000214005C0000000038 -:101C2000021400080000000102140034000000014A -:101C30000214000800000000021400600000000010 -:101C40000202005800000032020200A0031500202A -:101C5000020200A403150020020200A801000030C7 -:101C6000020200AC08100000020200B000000033C5 -:101C7000020200B400000030020200B8000000318F -:101C8000020200BC00000003020200C000000006C7 -:101C9000020200C400000003020200C800000003AA -:101CA000020200CC00000002020200D0000000008E -:101CB000020200D400000002020200DC000000006A -:101CC000020200E000000006020200E4000000043E -:101CD000020200E800000002020200EC0000000224 -:101CE000020200F000000001020200FC00000006F9 -:101CF0000202012000000000020201340000000284 -:101D0000020201B0000000010202020C000000010A -:101D10000202021400000001020202180000000288 -:101D200002020404000000010202040C0000004052 -:101D300002020410000000400202041C0000000423 -:101D4000020204200000002002020424000000021D -:101D5000020204280000001F060205000000001215 -:101D600004020480001F02D5020200600000000F80 -:101D70000202006400000007020200680000000B7D -:101D80000202006C0000000E060200700000000459 -:101D9000020200F40000000402020004000000013E -:101DA00002020008000000010202000C0000000115 -:101DB00002020010000000010202001400000001F5 -:101DC00002020018000000010202001C00000001D5 -:101DD00002020020000000010202002400000001B5 -:101DE00002020028000000010202002C0000000195 -:101DF0000202003000000001020200340000000175 -:101E000002020038000000010202003C0000000154 -:101E10000202004000000001020200440000000134 -:101E200002020048000000010202004C0000000114 -:101E3000020200500000000102020108000000C878 -:101E40000202011800000002020201C400000000AA -:101E5000020201CC00000000020201D400000002D6 -:101E6000020201DC00000002020201E4000000FFA7 -:101E7000020201EC000000FF0202010C000000C899 -:101E80000202011C00000002020201C80000000062 -:101E9000020201D000000000020201D8000000028E -:101EA000020201E000000002020201E8000000FF5F -:101EB000020201F0000000FF0728040000B5000046 -:101EC00008280768001302F4072C000035D500002D -:101ED000072C80003A3E0D76072D00003B471C067C -:101EE000072D800022BC2AD8082DC770471202F6A1 -:101EF000012800000000000001280004000000008C -:101F000001280008000000000128000C000000006B -:101F1000012800100000000001280014000000004B -:101F20000228002000000001022800240000000216 -:101F300002280028000000030228002C00000000F6 -:101F400002280030000000040228003400000001D4 -:101F500002280038000000000228003C00000001B8 -:101F60000228004000000004022800440000000095 -:101F700002280048000000010228004C0000000375 -:101F80000228005000000000022800540000000158 -:101F900002280058000000040228005C0000000035 -:101FA0000228006000000001022800640000000315 -:101FB00002280068000000000228006C00000001F8 -:101FC00002280070000000040228007400000000D5 -:101FD00002280078000000040228007C00000003B2 -:101FE0000628008000000002022800A400003FFF35 -:101FF000022800A8000003FF0228022400000000BD -:1020000002280234000000000228024C00000000F8 -:10201000022802E40000FFFF06282000000008005C -:10202000022B8BC000000001022B8000000000008A -:10203000022B804000000018022B80800000000C62 -:10204000022B80C0000000660C2B83000007A1203B -:102050000A2B8300000001380B2B8300000013883B -:10206000022B83C0000001F40C2B8340000001F41C -:102070000A2B8340000000000B2B8340000000056A -:102080000A2B83800004C4B40C2B83801DCD650013 -:102090000B2B8380004C4B40062A3C400000000480 -:1020A000042A3C50000202F8062A300000000048D2 -:1020B000062A1020000000C8062A100000000002B6 -:1020C000062A31280000008E022A33680000000032 -:1020D000042A3370000202FA042A3A70000402FC57 -:1020E000042A3D0000020300042A15000002030236 -:1020F000062A150800000100022A197000000000DD -:10210000022A197800000000042A19600002030462 -:10211000062A4AC000000002062A4B000000000404 -:10212000042A1F4800020306022B080000000000DA -:10213000042B0C0000100308022B08000100000013 -:10214000042B0C4000080318022B080002000000BA -:10215000042B0C6000080320062A3A8000000014BB -:10216000062A3B2000000024062A14000000000A72 -:10217000062A145000000006062A3378000000D812 -:10218000022A3A3800000000042A3C5800020328C2 -:10219000042A3C680010032A062A5020000000028E -:1021A000062A503000000002062A500000000002FB -:1021B000062A501000000002022A504000000000D1 -:1021C000062A50480000000E022A50B80000000104 -:1021D000042A4AC80002033A062A4B1000000042B3 -:1021E000062A4D2000000004062A3AD00000001400 -:1021F000062A3BB000000024062A14280000000A2A -:10220000062A146800000006062A36D8000000D806 -:10221000022A3A3C00000000042A3C600002033C11 -:10222000042A3CA80010033E062A502800000002A1 -:10223000062A503800000002062A5008000000025A -:10224000062A501800000002022A50440000000034 -:10225000062A50800000000E022A50BC0000000137 -:10226000042A4AD00002034E062A4C1800000042FD -:10227000062A4D3000000004021010080000000182 -:102280000210101000000264021010000003D000C1 -:10229000021010040000003D091018000200035055 -:1022A00009101100002005500610118000000002E6 -:1022B0000910118800060570061011A00000001812 -:1022C000021010100000000006102400000000E0C2 -:1022D0000210201C0000000002102020000000015D -:1022E000021020C0000000010210200400000001C4 -:1022F000021020080000000109103C0000050576CE -:1023000009103C200005057B0910380000050580F8 -:1023100002104028000000100210404400003FFF5F -:102320000210405800280000021040840084924AA5 -:1023300002104058000000000610806800000004F1 -:1023400002108000000010800610802800000002AB -:102350000210803800000010021080400000FFFFD3 -:10236000021080440000FFFF0210805000000000B7 -:102370000210810000000000061081200000000211 -:1023800002108008000002B502108010000000005A -:10239000061082000000004A021081080001FFFFC1 -:1023A00006108140000000020210800000001A8028 -:1023B0000610900000000024061091200000004A42 -:1023C000061093700000004A061095C00000004AF5 -:1023D000021080040000108006108030000000020F -:1023E0000210803C00000010021080480000FFFF37 -:1023F0000210804C0000FFFF02108054000000001B -:102400000210810400000000061081280000000274 -:102410000210800C000002B50210801400000000C1 -:10242000061084000000004A0210810C0001FFFF2A -:1024300006108148000000020210800400001A808B -:102440000610909000000024061092480000004AF8 -:10245000061094980000004A061096E80000004A12 -:102460000212049000E383400212051400003C10A5 -:10247000021205200000000202120494FFFFFFFF79 -:1024800002120498FFFFFFFF0212049CFFFFFFFFF0 -:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0 -:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0 -:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C -:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68 -:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48 -:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28 -:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8 -:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7 -:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7 -:10252000021204F4FFFFFFFF021204F8FFFFFFFF97 -:10253000021204FCFFFFFFFF02120500FFFFFFFF76 -:1025400002120504FFFFFFFF02120508FFFFFFFF55 -:102550000212050CFFFFFFFF02120510FFFFFFFF35 -:10256000021204D4FFFF3330021204D8FFFF3340BD -:10257000021204B4F00030000212039000000008C0 -:102580000212039C00000008061203A000000002D3 -:10259000021203BC00000004021203C40000000485 -:1025A000021203D000000000021203DC0000000051 -:1025B0000212036C00000001021203680000003FD9 -:1025C000021201BC00000040021201C00000180805 -:1025D000021201C400000803021201C8000008032F -:1025E000021201CC00000040021201D000000003E2 -:1025F000021201D400000803021201D800000803EF -:10260000021201DC00000803021201E000010003D5 -:10261000021201E400000803021201E800000803AE -:10262000021201EC00000003021201F0000000039E -:10263000021201F400000003021201F8000000037E -:10264000021201FC0000000302120200000000035D -:10265000021202040000000302120208000000033C -:102660000212020C0000000302120210000000031C -:1026700002120214000000030212021800000003FC -:102680000212021C000000030212022000000003DC -:102690000212022400000003021202280000240398 -:1026A0000212022C0000002F02120230000000096A -:1026B00002120234000000190212023800000184E4 -:1026C0000212023C000001830212024000000306D5 -:1026D0000212024400000019021202480000000623 -:1026E0000212024C00000306021202500000030610 -:1026F00002120254000003060212025800000C8667 -:102700000212025C000003060212026000000306CF -:1027100002120264000000060212026800000006B5 -:102720000212026C00000006021202700000000695 -:102730000212027400000006021202780000000675 -:102740000212027C00000006021202800000000655 -:102750000212028400000006021202880000000635 -:102760000212028C00000006021202900000000615 -:1027700002120294000000060212029800000006F5 -:102780000212029C00000006021202A000000306D2 -:10279000021202A400000013021202A800000006A8 -:1027A000021202B000001004021202B40000100471 -:1027B0000212032400106440021203280010644037 -:1027C000021201B0000000010600A0000000001687 -:1027D0000200A06CBF5C00000200A070FFF51FEFBC -:1027E0000200A0740000FFFF0200A078500003E088 -:1027F0000200A07C000000000200A0800000A000F9 -:102800000600A084000000050200A0980FE0000070 -:102810000600A09C000000140200A0EC555400002B -:102820000200A0F0555555550200A0F40000555582 -:102830000200A0F8000000000200A0FC55540000B7 -:102840000200A100555555550200A1040000555540 -:102850000200A108000000000200A22C00000000FD -:102860000600A230000000030200A0600000000784 -:102870000200A10CBF5C00000200A110FFF51FEFD9 -:102880000200A1140000FFFF0200A118500003E0A5 -:102890000200A11C000000000200A1200000A00016 -:1028A0000600A124000000050200A1380FE000008E -:1028B0000600A13C000000140200A18C5554000049 -:1028C0000200A190555555550200A19400005555A0 -:1028D0000200A198000000000200A19C55540000D5 -:1028E0000200A1A0555555550200A1A40000555560 -:1028F0000200A1A8000000000200A23C00000000AD -:102900000600A240000000030200A06400000007CF -:1029100000000000000000000000002E0000000089 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:10297000002E0050000000000000000000000000D9 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000050008D5A -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000008D009200920096C0 -:1029D0000096009A000000000000000000000000C7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000009A00DB00DB00E900E900F7BE -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000F700FE00000000000000000000000001 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B2000000000000000000000FE01030103010E90 -:102B3000010E01190000000000000000000000006C -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000119011A00000000000000000000000010 -:102B90000000000000000000000000000000000035 -:102BA000000000000000000000000000011A0152B7 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD000000000000000000001520176000000002B -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000017601B5000000000000000097 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C300001B501F0000000000000000000000000ED -:102C40000000000000000000000000000000000084 -:102C500000000000000000000000000001F002354C -:102C6000023502380238023B00000000000000007C -:102C70000000000000000000000000000000000054 -:102C80000000000000000000023B02760276028095 -:102C90000280028A00000000000000000000000026 -:102CA0000000000000000000000000000000000024 -:102CB00000000000028A028B0000000000000000FB -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE000028B029D000000000000000000000000B8 -:102CF00000000000000000000000000000000000D4 -:102D0000000000000000000000000000029D02B270 -:102D100002B202B502B502B80000000000000000D7 -:102D200000000000000000000000000000000000A3 -:102D3000000000000000000002B802E600000000F1 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000002E6036D00000000000000000B -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D9000036D0374037403780378037C0000000060 -:102DA0000000000000000000000000000000000023 -:102DB000000000000000000000000000037C03BBD6 -:102DC00003BB03C303C303CB0000000000000000EB -:102DD00000000000000000000000000000000000F3 -:102DE000000000000000000003CB041F041F04319A -:102DF0000431044300000000000000000000000057 -:102E000000000000000000000000000000000000C2 -:102E1000000000000443044D00000000000000001A -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E4000044D0453000000000000000000000000DA -:102E50000000000000000000000000000000000072 -:102E600000000000000000000000000004530456B1 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E900000000000000000000456045B0000000079 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC00000000000045B045C045C046E046E04807B -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF000048004ED0000000000000000000000005D -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000004ED04EECE -:102F200004EE050205020516000000000000000086 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA000000000000000000000010000000204C05A -:102FB0000003098000040E4000051300000617C03E -:102FC00000071C800008214000092600000A2AC0D2 -:102FD000000B2F80000C3440000D3900000E3DC066 -:102FE000000F42800010474000114C00001250C0FA -:102FF0000013558000145A4000155F00001663C08E -:103000000017688000186D4000197200001A76C021 -:10301000001B7B80001C8040001D8500001E89C0B5 -:10302000001F8E8000209340000020000000400020 -:1030300000006000000080000000A0000000C00050 -:103040000000E0000001000000012000000140003D -:1030500000016000000180000001A0000001C0002C -:103060000001E00000020000000220000002400019 -:1030700000026000000280000002A0000002C00008 -:103080000002E000000300000003200000034000F5 -:1030900000036000000380000003A0000003C000E4 -:1030A0000003E000000400000004200000044000D1 -:1030B00000046000000480000004A0000004C000C0 -:1030C0000004E000000500000005200000054000AD -:1030D00000056000000580000005A0000005C0009C -:1030E0000005E00000060000000620000006400089 -:1030F00000066000000680000006A0000006C00078 -:103100000006E00000070000000720000007400064 -:1031100000076000000780000007A0000007C00053 -:103120000007E00000080000000820000008400040 -:1031300000086000000880000008A0000008C0002F -:103140000008E0000009000000092000000940001C -:1031500000096000000980000009A0000009C0000B -:103160000009E000000A0000000A2000000A4000F8 -:10317000000A6000000A8000000AA000000AC000E7 -:10318000000AE000000B0000000B2000000B4000D4 -:10319000000B6000000B8000000BA000000BC000C3 -:1031A000000BE000000C0000000C2000000C4000B0 -:1031B000000C6000000C8000000CA000000CC0009F -:1031C000000CE000000D0000000D2000000D40008C -:1031D000000D6000000D8000000DA000000DC0007B -:1031E000000DE000000E0000000E2000000E400068 -:1031F000000E6000000E8000000EA000000EC00057 -:10320000000EE000000F0000000F2000000F400043 -:10321000000F6000000F8000000FA000000FC00032 -:10322000000FE0000010000000102000001040001F -:1032300000106000001080000010A0000010C0000E -:103240000010E000001100000011200000114000FB -:1032500000116000001180000011A0000011C000EA -:103260000011E000001200000012200000124000D7 -:1032700000126000001280000012A0000012C000C6 -:103280000012E000001300000013200000134000B3 -:1032900000136000001380000013A0000013C000A2 -:1032A0000013E0000014000000142000001440008F -:1032B00000146000001480000014A0000014C0007E -:1032C0000014E0000015000000152000001540006B -:1032D00000156000001580000015A0000015C0005A -:1032E0000015E00000160000001620000016400047 -:1032F00000166000001680000016A0000016C00036 -:103300000016E00000170000001720000017400022 -:1033100000176000001780000017A0000017C00011 -:103320000017E000001800000018200000184000FE -:1033300000186000001880000018A0000018C000ED -:103340000018E000001900000019200000194000DA -:1033500000196000001980000019A0000019C000C9 -:103360000019E000001A0000001A2000001A4000B6 -:10337000001A6000001A8000001AA000001AC000A5 -:10338000001AE000001B0000001B2000001B400092 -:10339000001B6000001B8000001BA000001BC00081 -:1033A000001BE000001C0000001C2000001C40006E -:1033B000001C6000001C8000001CA000001CC0005D -:1033C000001CE000001D0000001D2000001D40004A -:1033D000001D6000001D8000001DA000001DC00039 -:1033E000001DE000001E0000001E2000001E400026 -:1033F000001E6000001E8000001EA000001EC00015 -:10340000001EE000001F0000001F2000001F400001 -:10341000001F6000001F8000001FA000001FC000F0 -:10342000001FE000002000000020200000204000DD -:1034300000206000002080000020A0000020C000CC -:103440000020E000002100000021200000214000B9 -:1034500000216000002180000021A0000021C000A8 -:103460000021E00000220000002220000022400095 -:1034700000226000002280000022A0000022C00084 -:103480000022E00000230000002320000023400071 -:1034900000236000002380000023A0000023C00060 -:1034A0000023E0000024000000242000002440004D -:1034B00000246000002480000024A0000024C0003C -:1034C0000024E00000250000002520000025400029 -:1034D00000256000002580000025A0000025C00018 -:1034E0000025E00000260000002620000026400005 -:1034F00000266000002680000026A0000026C000F4 -:103500000026E000002700000027200000274000E0 -:1035100000276000002780000027A0000027C000CF -:103520000027E000002800000028200000284000BC -:1035300000286000002880000028A0000028C000AB -:103540000028E00000290000002920000029400098 -:1035500000296000002980000029A0000029C00087 -:103560000029E000002A0000002A2000002A400074 -:10357000002A6000002A8000002AA000002AC00063 -:10358000002AE000002B0000002B2000002B400050 -:10359000002B6000002B8000002BA000002BC0003F -:1035A000002BE000002C0000002C2000002C40002C -:1035B000002C6000002C8000002CA000002CC0001B -:1035C000002CE000002D0000002D2000002D400008 -:1035D000002D6000002D8000002DA000002DC000F7 -:1035E000002DE000002E0000002E2000002E4000E4 -:1035F000002E6000002E8000002EA000002EC000D3 -:10360000002EE000002F0000002F2000002F4000BF -:10361000002F6000002F8000002FA000002FC000AE -:10362000002FE0000030000000302000003040009B -:1036300000306000003080000030A0000030C0008A -:103640000030E00000310000003120000031400077 -:1036500000316000003180000031A0000031C00066 -:103660000031E00000320000003220000032400053 -:1036700000326000003280000032A0000032C00042 -:103680000032E0000033000000332000003340002F -:1036900000336000003380000033A0000033C0001E -:1036A0000033E0000034000000342000003440000B -:1036B00000346000003480000034A0000034C000FA -:1036C0000034E000003500000035200000354000E7 -:1036D00000356000003580000035A0000035C000D6 -:1036E0000035E000003600000036200000364000C3 -:1036F00000366000003680000036A0000036C000B2 -:103700000036E0000037000000372000003740009E -:1037100000376000003780000037A0000037C0008D -:103720000037E0000038000000382000003840007A -:1037300000386000003880000038A0000038C00069 -:103740000038E00000390000003920000039400056 -:1037500000396000003980000039A0000039C00045 -:103760000039E000003A0000003A2000003A400032 -:10377000003A6000003A8000003AA000003AC00021 -:10378000003AE000003B0000003B2000003B40000E -:10379000003B6000003B8000003BA000003BC000FD -:1037A000003BE000003C0000003C2000003C4000EA -:1037B000003C6000003C8000003CA000003CC000D9 -:1037C000003CE000003D0000003D2000003D4000C6 -:1037D000003D6000003D8000003DA000003DC000B5 -:1037E000003DE000003E0000003E2000003E4000A2 -:1037F000003E6000003E8000003EA000003EC00091 -:10380000003EE000003F0000003F2000003F40007D -:10381000003F6000003F8000003FA000003FC0006C -:10382000003FE000003FE00100000000000001FF59 -:103830000000020000007FF800007FF80000026F27 -:1038400000001500000000010000000300BEBC20C5 -:103850000000000300BEBC2000000001FFFFFFFFCE -:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 -:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 -:1038800000000000FFFFFFFF00000000FFFFFFFF40 -:103890000000000300BEBC20FFFFFFFF000000008F -:1038A000FFFFFFFF00000000FFFFFFFF000000031D -:1038B00000BEBC2000002000000040C0000061806D -:1038C000000082400000A3000000C3C00000E480AC -:1038D0000001054000012600000146C0000167808C -:1038E000000188400001A9000001C9C00001EA8070 -:1038F00000020B4000022C0000024CC000026D8050 -:1039000000028E400002AF000002CFC00002F08033 -:103910000003114000033200000352C00003738013 -:10392000000394400003B5000003D5C00003F680F7 -:103930000004174000043800000458C000047980D7 -:1039400000049A400000800000010380000187000D -:1039500000020A8000028E0000031180000395001F -:103960000004188000049C0000051F800005A300CF -:10397000000626800006AA0000072D800007B1007F -:10398000000834800008B80000093B800009BF002F -:10399000000A4280000AC600000B4980000BCD00DF -:1039A000000C5080000CD400000D5780000DDB008F -:1039B00000007FF800007FF800000174000015008F -:1039C0000000190000000000FFFFFFFF40000000A2 -:1039D00040000000400000004000000040000000E7 -:1039E00040000000400000004000000040000000D7 -:1039F00040000000400000004000000040000000C7 -:103A000040000000400000004000000040000000B6 -:103A100040000000400000004000000040000000A6 -:103A20004000000040000000400000004000000096 -:103A30004000000040000000400000004000000086 -:103A400040000000400000004000000000007FF83F -:103A500000007FF80000050900003500FFFFFFFFB0 -:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 -:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012 -:103A80004000000040000000400000004000000036 -:103A90004000000040000000400000004000000026 -:103AA0004000000040000000400000004000000016 -:103AB0004000000040000000400000004000000006 -:103AC00040000000400000004000000040000000F6 -:103AD00040000000400000004000000040000000E6 -:103AE00040000000400000004000000040000000D6 -:103AF00040000000400000004000000000001000F6 -:103B000000002080000031000000418000005200D1 -:103B100000006280000073000000838000009400B9 -:103B20000000A4800000B5000000C5800000D600A1 -:103B30000000E6800000F700000107800001180087 -:103B400000012880000139000001498000015A006D -:103B500000016A8000017B0000018B8000019C0055 -:103B60000001AC800001BD000001CD800001DE003D -:103B70000001EE800001FF0000007FF800007FF8E8 -:103B8000000004480000150010000000000028ADEF -:103B90000000000000010001000D0205CCCCCCC1EA -:103BA000FFFFFFFFFFFFFFFF7058103C0000000009 -:103BB0000000000000000001CCCC0201CCCCCCCC39 -:103BC00000000000FFFFFFFF400000004000000079 -:103BD00040000000400000004000000040000000E5 -:103BE00040000000400000004000000040000000D5 -:103BF00040000000400000004000000040000000C5 -:103C000040000000400000004000000040000000B4 -:103C100040000000400000004000000040000000A4 -:103C20004000000040000000400000004000000094 -:103C30004000000040000000400000004000000084 -:103C40004000000040000000000E01B7011600D641 -:103C50000000FFFF000000000000FFFF0000000068 -:103C60000000FFFF000000000000FFFF0000000058 -:103C70000000FFFF000000000000FFFF0000000048 -:103C80000000FFFF000000000000FFFF0000000038 -:103C90000010000000000000007201BB012300F3CF -:103CA0000000FFFF000000000000FFFF0000000018 -:103CB0000000FFFF000000000000FFFF0000000008 -:103CC0000000FFFF000000000000FFFF00000000F8 -:103CD0000000FFFF000000000000FFFF00000000E8 -:103CE0000010000000000000FFFFFFF3318FFFFF16 -:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308 -:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69 -:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7 -:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3 -:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7 -:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61 -:103D50000C30C305C30C30C3CF300014F3CF3CF399 -:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4 -:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387 -:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98 -:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367 -:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2 -:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347 -:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45 -:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327 -:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6 -:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307 -:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47 -:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6 -:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2 -:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6 -:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60 -:103E50000C30C305C30C30C3CF300014F3CF3CF398 -:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3 -:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386 -:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97 -:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366 -:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2 -:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346 -:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24 -:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326 -:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45 -:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306 -:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46 -:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5 -:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1 -:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5 -:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F -:103F50000C30C305C30C30C3CF300014F3CF3CF397 -:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2 -:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385 -:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96 -:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365 -:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC -:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378 -:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62 -:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325 -:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23 -:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305 -:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45 -:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4 -:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0 -:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4 -:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E -:104050000C30C305C30C30C3CF300014F3CF3CF396 -:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1 -:104070000C30C30CC30C30C3CF3CF300F3CF3CF384 -:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31 -:104090000C30C30CC30C30C3CF3CC000F3CF3CF397 -:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B -:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377 -:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61 -:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324 -:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24 -:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304 -:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45 -:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3 -:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF -:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3 -:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D -:104150000C30C305C30C30C3CF300014F3CF3CF395 -:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0 -:104170000C30C30CC30C30C3CF3CF300F3CF3CF383 -:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94 -:104190000C30C30CC30C30C3CF3CF300F3CF3CF363 -:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B -:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376 -:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61 -:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323 -:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57 -:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337 -:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76 -:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316 -:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6 -:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34 -:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6 -:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12 -:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6 -:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE -:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396 -:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6 -:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376 -:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96 -:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356 -:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56 -:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336 -:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75 -:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315 -:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54 -:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5 -:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33 -:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5 -:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11 -:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5 -:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED -:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395 -:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5 -:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375 -:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95 -:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355 -:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335 -:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74 -:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314 -:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53 -:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4 -:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32 -:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4 -:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10 -:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4 -:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC -:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394 -:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4 -:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374 -:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94 -:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354 -:1044E0000040CF3CCDCDCDCD000C0000000700C07A -:1044F00000028130000B81580002021000010230DE -:10450000000F024000010330000C0000000800C052 -:1045100000028140000B816800020220000102407D -:1045200000070250000202C0000F0000000800F067 -:1045300000028170000B819800020250000102709D -:10454000000B828000080338001000000008010002 -:1045500000028180000B81A80002026000018280BD -:10456000000E82980008038000028000000B802863 -:10457000000200E0000101000000811000000118AD -:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B -:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B -:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B -:1045B000CCCCCCCCCCCCCCCC00002000000000007B -:1045C0001F8B080000000000000BFB51CFC0F00360 -:1045D0008A7BD81818F67020F843015F646260B8CF -:1045E0000CC45781588099812198918121849178B8 -:1045F000FD71A208F61321A019C240330419184E08 -:104600000B23C40F02D5988830307C878A5503D994 -:104610000CA2D471FF40E375529862AB2510ECF503 -:1046200058E491F10634792E4954FE4602FA071AED -:10463000DF5744E50B2940E86CA8F803347961A8FA -:10464000FC79A8BF1E2A6237F702541E005BBBD25A -:1046500053600300000000000000000000000000A4 -:104660001F8B080000000000000BED7D0B7854D577 -:10467000B5F03E73CE9C9949662627214F1E6112E4 -:1046800020028638BC0228B74E480850691D6C5578 -:10469000B468070810F296A297D6F6CB04428C8035 -:1046A00036F8FB408B3ABC2A2A6AC048510187A7DA -:1046B000E8F5F606AB9656EB8D68519147E456A5A2 -:1046C000FF6DAFFF5A6BEF9D39673201ECD77BFF6F -:1046D000FBDFEF8F9FDF619FBDCFDE6BAFD75E6BE0 -:1046E000EDB5F7D86D1EA65FCDD8D7F807CF7A1BEA -:1046F000632C23F67CC4CE7E18743356B0CEB7C27A -:104700009D0EEF77E56D4FF63196B37BAD3205DE4A -:10471000E7AC6F53E615C6BE0FB8A0723CBCDFB560 -:10472000562981F7396FB42973F1E9B0B14E68CFDA -:10473000345F0AC3270B3096C9D890894CFC05DC3E -:1047400039C58C0DC47F4217E78C64C6C63196B755 -:10475000D216092BF03E5439937919DB0470E5A485 -:10476000C177EA5FF6D9B16D8376BCCBC998537334 -:104770006A5FE733963B9BD9183C072FE3EFF1EFD5 -:104780006BF83F2F6C2D0F61A6721E963DE92760D6 -:1047900048E6619EAFD544F076EBC151B179CAE7E6 -:1047A000FA465FA65BEBFD5E3E97DCF6897E177CE2 -:1047B000FD18B61BCA5824AE7D6D58D7D815F00425 -:1047C00004B417F6FE7E262B29463ADCCAA6D0B3DF -:1047D0005EF3DD8878A93F62676180BBBEE1443942 -:1047E00096D92E850DCBEBFDFD2866277A943045B2 -:1047F0003B81F3F5322FCE4FADF13D540E786E482C -:104800000E9461BF0F2787E829DF67CF9B9E1D02AB -:10481000784A17158619D0FDDC3AC5EF80CF3F5690 -:1048200022BA1DE851FDFD86A269D0EE6D3D740DE2 -:104830007EB7488DB6D861FCDA390D054001D6A99E -:1048400073FE19BCABE4530DE83698B1704A1AD226 -:1048500085B1E3263AE0DFF1E1A2ACF68DC78B3DEE -:104860002BB01F0D7B89D07CE5FBBCF0912143E38D -:10487000C663C5040F433819EB5212D175F08B256E -:1048800047B4A2BEC7FBCF9F4798CB21E00EE95BA0 -:10489000EBD123CB01BFA52FD8A357033D6A3728FF -:1048A0001107946D7B5D01A4CF99CD5006BA443DAC -:1048B0003AB53F6D38A95CEFE8BCF72A2877BFA06E -:1048C000B28DD8EDF0241BCADD09013B1B0765C082 -:1048D000C742172FD66ED8772BF657B9CBC15C4895 -:1048E000CF17177DF72A282F027EC326B55B9AF4CF -:1048F000FE505E1C51DAB17C760A23FE08A7E991CE -:104900002D30DE596F67E6F5202F271B9DCC07A0C1 -:10491000ACF074667E1FF8A82AB2BD1CBFABDAA645 -:10492000F811EDA52F6C399C83F37A12F80AF8A8D8 -:104930007A6B32F349FCC1FF27602A5743FD129876 -:1049400027CAFF22D656CE541C7FADEEF3C4F075B5 -:10495000B2D1A0717AE4E9491807BEAB7B56F1E306 -:1049600014EB6C2C847275E645D7EC4D6E9C5F930E -:104970005EE0C179DDA563BB4591B93B5165554505 -:1049800036E8E5505FB57E83BEB010F1067AAF1011 -:10499000E1EA67856B9D1A40FC2E49756E54013F14 -:1049A000CC1DC8BE2E01FF9C6C043556102B57A1A0 -:1049B0007C933E89E8B34CEDCB9554E2D7EAAD2A1F -:1049C000F359F889D33F7C94D33FBCC713D99217CE -:1049D000A3DF1283EB4949BF25A9829E5A77712232 -:1049E00078EE457A003C6D882F78AE11F07927B3C8 -:1049F000120DE8E20D30436117E7CF363B9BCB60E9 -:104A0000EC37D982803609CA3ABB8DF91933B4DA4A -:104A1000401994FFC2826FE07C18F3FB8280E71696 -:104A200085CDC6791F4260613E2D393AE1AF6D6A8E -:104A3000F126551130A76379E12F57E5D1F76FD1F2 -:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3 -:104A5000FD7BD88E392FFC7D5BF995D6F1CBABE48D -:104A6000F71FD1F8EE0BC36F4C9B6C1D7F5A0D7D69 -:104A70005FEFE0F4EA4E75463642B9D9E50F684873 -:104A8000378D45F1BD9656B011DBA9921F5867408E -:104A900085EFDDDB52C7AC6266BE98F2271CCF0300 -:104AA000D262E68B948949167E4C0DA459CAD093E4 -:104AB00071E2F2981E0A789D048FDE5F277D51D245 -:104AC000DF49F0DEB1D745E53BAEE4F0DED1DF4DA6 -:104AD000728630B01C28EBA12B0CD37A04702A2CE0 -:104AE0009BB12F94904B196F7EEFB3E1FB2495356A -:104AF000E07C921C8CF4D15D79C59BC226FCB40E7F -:104B000002FA42395DD1391E055EEF1AB4307BAE30 -:104B1000699C9641FAEC8D85FCFD7C378E17CC5450 -:104B2000500FEADD0586BBF7388EFC8996719CB97B -:104B300095344E5EDC388EDCCAB8719CB3378AF788 -:104B4000629C21171AE7AEFC2BADF3C9ADA2718AA6 -:104B5000E2E7935B15374E129F0FBC17E3F8117F06 -:104B60007DCE67C864EB7C06D7D03857E138E34D7B -:104B7000F3195C13378E9BC6C1F7380E18523E9658 -:104B8000057477742F24FABFE2227B4177849EC09C -:104B90007ED9BB2E46FAC407E366A15E81C519E43F -:104BA0005753D2689C2F9380FE6E339DB93EA22747 -:104BB000E89F05024416018840FFD4091EADD8368F -:104BC0002BB7099FBB4AB3E7A25D72BFC73F0C4436 -:104BD000E7CCAE527D7E02FB66419BFD4497857F0C -:104BE00085DE9BC28637C0F81DA86C4CE513A0BFBC -:104BF00018E8ADE3A0BFF0F9B1B04F3F02FDC674B5 -:104C000033BC4D348F131AC7E389F57C1DF972ED5F -:104C1000513B187B38CC5B8500F70D621A0BDAC06C -:104C2000F833C959BDA047F78B8EC846A2476080AC -:104C30000DF89CADEB07B812EDC0CEFC83B047E198 -:104C40006F800D6CD99B5BB71FC266EF2873072D71 -:104C500081F9CEEE586B1F00E533F6AE5BFD6E5367 -:104C60003FB3EDC771DE4EF80FFBB92964B7D8A783 -:104C70003FA8B4966F89B3576B947C410F31AE2F28 -:104C800062477ADD90C9E1B9059F63B0DA207ADD29 -:104C90006AF06F253CF577DA5994D6A3AE0C5688A6 -:104CA000F8C820BB2824D79538F86EB53B0341A03F -:104CB000E7AD3F56098FF1F076ED4D0ED8C05EEAB4 -:104CC0005AF76F76B4BF2F06FF0F9759EB59988F9D -:104CD00027F12AF9E0C6D925FD3E32B5BB2934A318 -:104CE000DF47267EF941E52C4BF996869B2CED7F1C -:104CF000B86CAEA57E6E78B1A57E7EEB6D96F28225 -:104D0000B61F5BDA2F5AD764A95F1CB9DB525FBDAF -:104D100075ADA55CDBFEB0A57DFDAE0D967ADBDE44 -:104D200011D7A23CAE785B65689F7DE13E712FDABA -:104D3000575F189A1FDBD421AF811C7ED2984DFC9F -:104D40007DB2D147CF33BBC63AD11EAF4F02798671 -:104D5000B57EAFF28770EB64D423D01E74F87EE585 -:104D6000C370189CA7D7141FF1BDBA4E6751605588 -:104D700085A5F5F075B71AABD7BAA07E6CDFF5EA5A -:104D80003A2D61BDD6A525ECF7ACD25D80F65DF875 -:104D9000770E8676605FF603FC0DC0F5A2AFFA537E -:104DA0003656D96ED23B27141BF1C10DCA9413A8F5 -:104DB0009F6B742EEF353B72A6A03F58A3470B1A8A -:104DC000DC1718AF1D80C9C27EF2695E8B230362B7 -:104DD000F24BF41B6291FBA52CF447D4CFA7F6A9A4 -:104DE000A46759F440EEF746E1F88113F89EEDCA46 -:104DF000A0F5F19DC640BF8FC09F3BD6389D9EBF9A -:104E00006F0CF6FB0874CD7B8DB3A9FC7E63889E86 -:104E10005D8D95F43CDED840F51F352EA3F289C692 -:104E2000303D3F696CA5E7C9C636AA3FD5B88ECAE2 -:104E3000671A23F4ECF103843DCAD285FD27EC7593 -:104E40005839A87C4ECC41857F73BFD59F8D727D2C -:104E5000CEFD6501DAB9E78E816192C03F94CF78CB -:104E60007EEB9B7E015AEF174680FE637BD7BB9299 -:104E7000387D5C36369D81FEB97B98CE34183FE98B -:104E800095CBC95E86F71A237D19F1CFF224E81F6E -:104E9000E79C75713AF5F0C723FF5E8CF1871B84A0 -:104EA0003E4C3AA03670BA6DF223DD4CF8E376D969 -:104EB0000B429FC7E1916CB99CDEF83C9D21F1D972 -:104EC000998B7180FB95E0081BF0C1B90E07CDEB03 -:104ED000DCEEE408C36F313832E94278E370546F96 -:104EE000751966FD50DB9E6A58F5458E61D617E749 -:104EF0008E6CF2A2DC2FC9B6191F8D45FE0808FE84 -:104F0000E07C27FBAF6DCF33DC967EACE5736DCADA -:104F100074F48340B9A77C3F817F209F4BB275E337 -:104F20002390EF935B87A4E0B8E0C71938CEA94679 -:104F3000C3E0E3661B66BEAC599644ED257C7DF567 -:104F4000FBF7860F2D830F9D8C50FFF5906FEE675A -:104F500033ED4F14CF61BBED5FE2BAE380FFBFA634 -:104F600078804665D96F7DBB1A765C81EFB759C6EC -:104F700083EF7CD287C6F5AA6FBA6BEC84292E50DA -:104F80008763907FE4243A87A0C714E8EFACE66E0D -:104F900055609CE9361FD5D70B7EAC7576E9217834 -:104FA00075BA83D3A3AF714E361EF169A03F2A9D17 -:104FB000E091C13895ED23CA503F9EEE58911902F9 -:104FC000BEAD56CFDD114CF07DAB4DE1F044ECDDD4 -:104FD0005DA6F9C8380A63D0AF33063F72FA0953A9 -:104FE000395E5FCBE77DD82FF047DDB6A3E55701EB -:104FF000FC75BB3ED7118EE9B6D07DB68CD8FC15BA -:105000009C3FF453B5F5031DE7F7893D5C70E70558 -:10501000F4546F38DDD914B793F0855927DA31F39A -:105020007AE28ABE1BDF05D1FCF49FEC6C15C0C18F -:10503000FE02ADA0DE2E6A2B58D08BF89AD7514DC8 -:10504000F1C54F6DD26E6A2B46FE38CD6CD3717EA2 -:10505000A7D99BDEB126FC75D8B8DDCF5AB91D1390 -:1050600086FF101EB0672D76CDA275D6F242765D12 -:1050700026EA8D85F7DB590450B418ED22C91F309C -:10508000EFCD366EEF2E620D2D68CF690EEE1FCC80 -:1050900033983600E0AAFDD5A3C568F7BF6CB311FD -:1050A0007D649C61711A87BB2A3DA207A0FEC38E56 -:1050B000B1375C85DCE788B4E0BACC52987F0BEB63 -:1050C0008DCFF9AD56F82E067F3CBC8C2DB7C02194 -:1050D000FB9570A85B95402401DFBD26F94EE89151 -:1050E00034D56AE767C595DFB389F8A5CA54A4F338 -:1050F00069C319B6A550BD3F8AF1911D0EFF0AA0E4 -:10510000EFEDB66017EA67B00B8A98A9DDEDB6102F -:10511000BD3FA5BCB110ED53A6458BD0BF8735452B -:10512000437ED0053FA849DE228CC77A18AC9F2069 -:10513000970E840FFA69F154CE6445187F053985BE -:10514000FEEEF1961F51A0EC727730ECCF916D8D91 -:105150002FBB7CD6723DFE03E9309C511C2779B8E9 -:10516000B51E162C86FCE6F15BDFFFEF1E3C458981 -:105170006FBDC4D2F074BAA32A8CCF266AA7CC76AE -:10518000739D93C34F7E39B45F2AECF93AE60B5313 -:105190009C389BF3C1D219368267A9C7E70F43BD7C -:1051A000A20518CA1FC6AACDEB58FD7910B97EA674 -:1051B000B2D6AD235FD69FD75804F47D912DE4512C -:1051C000C723FE0264E73A01595F03C89A7BBAC558 -:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811 -:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B -:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF -:1052000062EDF212F557FBAB67768601FF55CF3D95 -:10521000E005E2B34FB5B64C3FBCAFD9B2D28B7C00 -:10522000FC8916F6E2BC3F8DA8D313F1F30DAA2238 -:10523000FCB1805B417F58D0E9E453ABBF8B78FF72 -:10524000728BDDC026F55B1D510710B1AE6331E7EF -:10525000A7AD8E0F78F9AECF919EF5BBACF256F5A7 -:10526000C4039918EF040C71BF9145C97EAEDBFCF5 -:10527000C772B447EA5937E989F8EF70FCF369B4AB -:105280007ECDD5537AD7CBFD977AC1F7F51DAB3FCD -:1052900057BD58B6CA77A5F047A6A99E748A2B4D6C -:1052A0006013906E120F2CC2EDE1154F3E54F401C5 -:1052B000C0716AF33F79154BDC88EB8773EDF31F00 -:1052C0007FC9D7B75E3F23FCF9D87711FACEB78BE9 -:1052D000DBEF6C377FD6D8A35EF4976A36D8FD2013 -:1052E00099ACE6994DBF7C04F9FA770E8A33543FA6 -:1052F00073E89D2BA15CBDDD9E3E934FC3AD64C69C -:10530000E8510FFF2F1B13C37FD5F38774DF28FEEF -:10531000FEA769313A546FDFA7B351BDF156DABE2B -:105320004FEF7227A047FB07E5686FAF78F22B1DA0 -:10533000E5EAD3BD0ACBCAEBFD7DE5864364CF2108 -:105340009E887E823E3DF4EA45A7E8775F1A47EDE6 -:105350000C5CBFFAA2D3485CFB32888F9F7D09E3C7 -:10536000F7BF77F871FE95CFFEC88BF3F8586BE066 -:10537000FCFCE8CACC008C5B690F671AF4E4EF2BE5 -:105380001FBB9DF86CD1D1DB33291EC00239365AC0 -:1053900043C33938BF05EBAFA7F92D6421E2B7CA83 -:1053A00047D56004E3591A9BBE3D813CBC21E4E132 -:1053B000E38D0E5C7BD8C7A860D13F7C53A57D02EE -:1053C000C66EA378C3ED721F822DA1F2174E4EA7B1 -:1053D0004DAA4DC6379C163EDD7C5727D2E7E4A088 -:1053E0004016C627010F61812F05F58E7A746A1663 -:1053F000A70FF369C5E23BD08BA5F81EDB77DA0374 -:10540000AE22CB77621DE3E32F15E303DC49688FFF -:105410007D9C09F64D82F97DA54ABD0CF68689BFB3 -:105420004C72CDE57CF3DD5CAEA59C47664DC7FABA -:105430003FBDC5E507BFC3751DE08A6651FDBEEFE0 -:105440002BA4071C2C9A489E37DB853C5BEBE5FEC2 -:1054500024C0ADE1FA14E313E83F8DF04F76DAC2D1 -:10546000FBE13B935EAEC7F1A89D1E7B6F5AD71739 -:1054700009F97F5515FBA342FED97A2EF77DDBBDD6 -:1054800061EE1FD823BF7C04E515E413D7999A6712 -:10549000EC419CF767DB0EBC7333F0F567ED524EC1 -:1054A000AD7A335E4E2B778C6789E4F433B79F2552 -:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17 -:1054C0004C9CDE947AB02FFCC5EBC135AA2FA11EEF -:1054D00084BFB758716FBE93FC26F9ACEAE9DAC114 -:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3 -:1054F000F8FA1785BE9174B62F67610FC64BF7A8EF -:10550000E45F9F05985A80BE67B7E54530EEBCD290 -:10551000C5E317678D6E6F1A3C57A6F2727786DE69 -:1055200082FA41BEEF76F1F8F6D960B737D5E45785 -:105530007CB05BF5FAA0BE2BC2A627F23740F3126F -:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0 -:10555000D27E7645D38D5EDC073EBB7BC8CF513F04 -:105560002D780D0C4C80F72CDA812938BD80867996 -:1055700009F305BD3F61E10727C3FCE6EFE6FE4204 -:10558000C59A38FBDEBD54477D03F6FD716B5C9B0D -:10559000F34D95E8A772BDB5BE8AAD21BA55C5F1E8 -:1055A0005148F8811334C147A3D968E187F1F885E0 -:1055B000D05753D5C29FA39D71F6088F2B9EDBADAC -:1055C00012FECF6D532218F7A1F8EE24A47FB7CEB8 -:1055D0004CFEF229E437BD6F393EF5C21F8AEF84D5 -:1055E00026353BDF2DFA053C4FEDFC5DC1CB58FE67 -:1055F000D56F73DF65BDDB97EEFD33ED1F9FDDEBF0 -:105600002038CEEE7D35F74E2CBFE4F0239C679713 -:105610003B68FF2CBCD7131986F58380DEB86EEE8D -:10562000F9AAA88BD69D66A2D33C8DEF779CDBFDB3 -:10563000EFEF2B987FB0DBE1C379D4EFE57921F56B -:105640002FB928EE7276CF57C521F7DF6F3E753A36 -:105650000B11FF79D8EC1DC8AFA97C1FA0FEE5494E -:105660009B9A703FBC639F8EFB2BA5AFFCB508F5E2 -:10567000CBD91DDC4E3863EF7A0CF7416BB5A1CB6B -:10568000ED28F768B3F507BBD3BE604AB830115EAA -:10569000381ECE021E705E80974AD48B7DE1A359DE -:1056A000E3FEE67F3F7C7C7E2B8E5FB37B02C94DA1 -:1056B0000C2F4A80BFF7449C0ACD9FBFDFFB5511DA -:1056C000DA3D9FB537D13A7EB1796FFA1F376F2532 -:1056D0007A29F3DEFFDF9CFFA76B7C5D8A9783DE70 -:1056E0007CFEAB3BA8FCACC74FF05EA2FC1FFF9F4B -:1056F00046F71D4077EFC5E9AED8FFBBCEFB62741D -:105700007F4DD0DD63605EC1D93D7FA578B99CFF38 -:10571000C5E6EDFB7F74DED2FE5965F3B7E543FBCA -:10572000352CDAE90338570EBFAE0DC34CE0260422 -:1057300013D923413BF78F5485C761D8201E1762C8 -:10574000C29FA014301FC65116925DA7B95BC8CE88 -:10575000649ABF3300F85835729E9F7235D89863AB -:10576000212C0F9CECA7F8669C5FA58DFCF611B46C -:10577000EF9B9B003E18A7D9A319602931FB705BF2 -:10578000D45144CF0FF079978867D90DDDE257B82F -:10579000E3FC0297CF5AEF10FD3BD97E03F3889CC0 -:1057A0007E8D45B01D6B0B9BF3071CCCF41DD417ED -:1057B0006200D6643F7E53FC35F5E06F4C6700F124 -:1057C00037C246712D4AEA237CF823AB781E85D375 -:1057D0008ACF964EC4A3C6C0FFE3F322BF91097FD0 -:1057E00051135D68C36D0197B59DF08B2E4A1F4E16 -:1057F0008FDC1A419F25167A48BC5F802E167A48A6 -:10580000FC7E53BAC4D3231EFFDFB7F3B89BA49327 -:1058100025BF2383FB2151F0435EDDB689E21DA73E -:105820009FFAE0BBC8A7D52FABCC09DF9FD9E661B3 -:1058300051945F2DA2A33F55D5A1268CF34ABBBC42 -:10584000FA390FF179D50E4764267C5FB5F3C32290 -:10585000B29B96771F1E807181A7144EBF7057119F -:10586000EEDB5569DC3F88EF6FBD9DC7054EBD98E7 -:105870003C1BE30FCA569EAF58D57EA3DD61DA7795 -:10588000FE5F769EF70AED489EC34F2AB4DEF4868B -:105890008FFB05A79E54387CBBEC11CC7BACDABAED -:1058A000410FA15FB9F5738A63973EF78CB78BFC04 -:1058B00045D5EA3F6F55899EF024BAC5FBB1751DE9 -:1058C000B5E427D4B50B3F31CE8FAA7E6ECFCE3054 -:1058D000A0A6FAF927BC187F39D9B9C54BFEE956FD -:1058E000EE7F6A6E2DB17F7A31BFB4FDEE847EE922 -:1058F00049FC07F813FBEC71FEFCD67E97B67FF9E6 -:10590000CC178F619CF4D48ECF1E43B86BFEE3DFBF -:105910001E43FB9EED75195B60BEF54FBD4DF12634 -:10592000F9DDBB424ECF0C62E11C6877E6770ECA08 -:105930001F39B3E7E35CF4E7CE6CFF7326FAF54B4F -:10594000F74CCDC2792F7DA1348B259077F944BED9 -:105950008C5C429C309E0E073A0E901F72FA988320 -:10596000FCBE9EF8427B2D8FD7F8445C615BE23829 -:10597000ACF487EB3A3E2CE7F131E1175F2C8EF067 -:1059800016D0F18A4BA0D73611278AA3D769FC0716 -:10599000D0E5AB387A7DC1428FE7E03E6447BF3E39 -:1059A000E308D14BC0938CEF1EB6076C3ACAC18E88 -:1059B000E41E3ACD443A3DF3452EC6C33FB177933A -:1059C000DDD3BDC761A07F5FB5E7B72417675E3839 -:1059D0004AF15326E2AC6758CF1F8F8B29627E9B1A -:1059E0003D3CFE20F08DF1099F97DE8B3804E75790 -:1059F000199FE82B2E314117794F22EE5CBBF95DE0 -:105A00009DC5C579948948A70F2CF17139EFF8FE2F -:105A10000CC4C304737C2D71DC47FACD313AF1B864 -:105A20009A8C9F9DD920E26EF07EE018F407791CD5 -:105A3000A33EA2FC96259043195F1BA3C7C961E44E -:105A4000D2E26A1783F76FC5C7309DAF0B122FA73D -:105A5000FE92580F7F47E7723DDD169AA99BF6B379 -:105A60007F28F65924BE24BCA7441EDEA9A7548A69 -:105A700007B5B41F207D1A2FCF757D9C83B855E7DD -:105A8000F1D6BA5DFB8A50EF9CDAFF22F15DDDB6FC -:105A90000FF430F47378EBF33AB727399FA39E8E57 -:105AA00098F4F4A967F715F1B81FCFBB8DEFBF5A73 -:105AB000F45FBFDBDA7FFDB6CF2DFD5787DB75BE08 -:105AC0005E5E789C935AE0469CEFC94E3B437D77DF -:105AD000B25D9D1E496407EA76CB3E68CB519DD6E8 -:105AE000AB716F26517EEED2A3D3DF4DC17D3A104C -:105AF00033B47F3B9A385F75FC2C3000E9D271F4E7 -:105B00006615D78D9D8847931D5CFC5643A907E415 -:105B1000B5F8BDE03864AB783D30E198CD02378C04 -:105B20009385FAB819FAC17C7ACC1FC2FD51D55BB6 -:105B30003E1DE1510D9BE14AB87EF2FEECEE2043A2 -:105B4000BBDC6E58F395B3AF1371B4A8356F3D5BF2 -:105B500067C3711F9CD992FCB81FB0644460F421E4 -:105B6000CCAB5F904D71E29CEFF1EF4E1BEEB0EDD0 -:105B70008AD8BE6DF279E81FF3606C91B573E0BB13 -:105B800064AD5DC17D007832A4CBEDB6D0463D0357 -:105B9000DBE9CC07AAF1315DD128FF429C7B91FD66 -:105BA000C9767DED07CB7348AA807F88D80F1EC4C5 -:105BB000BA14DC0F5EEFE1E79106BBD3E9BCD12656 -:105BC00061AFF970DF15DB3558D7ED8B9E476AB5AD -:105BD00096D34B4B6E1BEC073F58BFA354037D90ED -:105BE0007E63C9F60106EE4BDF5F8A79F7E94F94D1 -:105BF0008CCE81F26C475119D5FF4BC9E85C28FF68 -:105C0000A8755219D5572B9417B847EF2E0DBB63C3 -:105C1000F29901C62DE65B80DCEE47B93D1D3CD50F -:105C200082B5B5D77FA9F3F3302C88F31F3491CF19 -:105C30007FA0FBBDED38DFC1B6AE26E4BFC7F77C61 -:105C4000958AED7CCCA0791AACD9C07D797835F1F4 -:105C5000EB0BE4FFC4E7C1487E7F2E39F41B84E3DD -:105C6000EE79C31F2A479D5AE3273E8ADF276646FF -:105C70003AD1A542D005E1749AF2902BF12402E9C1 -:105C80009B3203C751C235EAD7977F73784E487E5F -:105C900011E7C04CE7A43E45381F4E0ED133FE9CA1 -:105CA000D47E3DF819F253CEC2F3B908BF3CFF547D -:105CB000BAC84D718173BB59C491407EE4736323AC -:105CC000CBD086F65DFFB623F4671C37FF15DF8E59 -:105CD00023D0DF1515BA1F53D7AE58362E431BCB32 -:105CE000F884D09E1074CB465AA27CDDC1F8B91C52 -:105CF000871240BFF1EC8F0CD2BF032B66925F710D -:105D00003639AF1DF327CEDEC9F300608557500E3C -:105D100006ED4E89A2FF037CFC651C1F7F695D6751 -:105D2000ACE39EFDDAB7AB8BFA33447F60E864A244 -:105D3000DCF0BFB32AB7B3CF36FA080E300BF7E169 -:105D40007A7AA9E3653BACE7F400EFFD1D26BCE7DA -:105D50003AFAA45F9E83D38F9EF1F45BE86CC8454A -:105D600039AE0AB697A36BFAF1C23B8A91A9DFD686 -:105D7000439761FB9AD99D8779CE504301EEB3F5E5 -:105D8000A62F3F8F95B97B6E931DE315481F5F6F5C -:105D90003A5EB1CC9FA1F5B3D0752CC27FC5EECFD2 -:105DA0006D08BFA4E74322CF3FFEFB6F3914316E6D -:105DB0004D931DE324BB74B267E3DB4DC74355E34A -:105DC00063E52267318D9B65E3F18EDEEDF9FA170D -:105DD000EBD749E7B2FAE2C72283F707F8FFB61913 -:105DE000FFDFED1BFFB3B01DE09F9EDF00FF3762BA -:105DF000FBBEF02FEDE86AA117AA711F05F8E88F26 -:105E000081EB3287C2F8E5AA9BE460F11695E40FB6 -:105E1000DACFCCC98CE991C5931AF6E17C173FAA79 -:105E200010BF568873A69F89BCFEF87CA885B3C3B3 -:105E3000B4BFD32B2F2A12E7D7C5E5BBD7C7F87657 -:105E400030CF53E3E7B6542117A58B0A53D01EDA9F -:105E50006BF7FD0BD9D9AFA96C6302FC6F402633F9 -:105E6000D1755083CD9227CB2A522DFD962D2AA491 -:105E70007DEF251EDF05FDAAC1CBACEB765ED87A9F -:105E8000CE6848ABF59CD1B0B6FE96F697ADCBB7D1 -:105E9000D48F888CB4D45FBE758CA53CAAFD4A4BC8 -:105EA000FB2B764DB1944747BF6D693FF6C8759699 -:105EB000F2F8CE9B2DED271C9B67A99FD45565A9B1 -:105EC000BFEA932596F23F74FFC46AA7D818E94742 -:105ED00096A490BE3CD8383117F3B1D938A50CF14F -:105EE000592AF2090FDEA6DB0C2F3E0B6C06E8AD3B -:105EF000FD0B66D2BA7FF0B6CC808F9EC501F46BE5 -:105F0000983A795CA27CCDA9C6A45C735E54A9D3EF -:105F10006ED16F530D6B79A743ECFB0DE67CF372EA -:105F20009C7CD91B2647C13264FD170FCDC2F140BE -:105F3000CEF60A3DB7F792F45C6643319641CE0E39 -:105F400026923326D6D912C14FF00CE8981F59E695 -:105F5000A1F538802F7DF43EAC81BC4C71FA071E50 -:105F6000C279D9FCE9C88465B38307797F625D662D -:105F7000C36DDF645D96729E6D13F96B693C7FEDB6 -:105F8000E1050529CC84DF3F386CC28E6EE34FE318 -:105F900088AB276F35DFFCFE9324CD942FA72C9A76 -:105FA00049F922D97DE8453D3B7FC666D0C77A8E48 -:105FB0008F9EF27DCB6C5BC23CB06EA147A5BD3518 -:105FC00022666F75233D4E67BFF920E629D5CDE9DE -:105FD000267B2BDBD676DB619CD7EBAA885FFAF8B1 -:105FE000F92A61272F9871DF6D87715FFA9F87917A -:105FF0007E92E3AC6F9C3E43339D231FD887DF74B2 -:10600000B993C3F358E3F0191594B76DF0F3A2A256 -:10601000FFDC706D39DACD8345BEE983B6C4F92E55 -:106020006ED14F16921CE135DC2427A717BEE7D5A9 -:10603000601E8FC0EAE5C47DDB2B3A8BB91D16F0DC -:10604000E339D4DCE82D0F62FBDC6C8DF25DE3C735 -:10605000CF9A136ACDC3F8679ACDEFA672B782EDD7 -:106060001D3F65AC1FB46FFE0F95E069DE3F89F2FE -:106070003F1CEE0686FBA9725E07D21E21FCA81DFE -:10608000C9B40E32B12F2EE3AD5F645774A2BDF1D7 -:10609000C5FD761AEF0B98A301FD7FD1A1D2BEEB0F -:1060A000E1B4A4A80DCA6AAB87D6EF5CB43DA1FDEC -:1060B000C20E4FC49717C38BB66E329D87710CE426 -:1060C000F36F4E7347DC7934EF749CB78453CE7B07 -:1060D000501F7E6689803BE7B29E731A0CF95835D3 -:1060E00034EA77412A3F8719699C28E8659D4F4B20 -:1060F000F675D7DE84E787DE5219A686F8BADA6825 -:10610000FE0B61FE115F6FFC9EF6E57D695309CEC3 -:106110001284535D574EF3A076F05DEDE30A7B24C5 -:106120000FF930349DE8DADF46E7027BD9074E2EBF -:106130005F339C3C2F57CF2E98B1B91F3E87925C9E -:106140007CC7D9E7BA1F74727D44CF6F70BF00ADB2 -:10615000FF521FA9019BB073B95EEAB19FF4D00F43 -:106160009C19B1B29AF2D322ECB76FFB6CFB3E1DC7 -:10617000ED333723FB59EACDBEEC33B4CB90DFA42B -:106180005DB6386E9E30BF1A31BF9A44F3EBA56FEF -:106190006F6E9076CD12E705ECCA0C3DB13E7A5297 -:1061A000D0A1DED019C59B688D02BDB3D846E78D5E -:1061B00099167199CF97AF774ABB6EF73E1DF10CD8 -:1061C000F3463C6783FF5C4E7AC79E302FFC62FE2D -:1061D00048FEEAC21D47B03FB07311FA736DBE941A -:1061E000B40BD817F665AFBBCC78BDCF29F2B96335 -:1061F000787C40E0F18184784C073CDA2CF6E1CEE3 -:10620000021FE1F117CE0BD887A7BFF77E31AE474B -:106210006704BEEA7AFC5CAE9FFBC32285F1AA5AF2 -:10622000CC5F76F232EE07E15E0CC6E18A6CC127E4 -:10623000B0FFFA5DD673873F73F2381973F373B307 -:10624000B2BF4CA1EFC1AFFED61F7DA4F7FF11E78F -:1062500013F3AFBB8AD1BF5AF1C26529689795ED98 -:10626000BCC9C0E7B9F4A1B49E9DDEE908209CA793 -:10627000D378BEDEE99D130E63FCE1B3C623F96655 -:106280007D7FFAD9A3C576E8E7F48EA3C51AE507A2 -:10629000472C7661EDD7BF29C6735832AFBA875FF6 -:1062A0009C7C9DB8DFC5E31A19997A0BE68B9F4F4A -:1062B0004A257C3D9069BB3751BC06D527EDDB7B79 -:1062C00074DAA75C32C2B7C28DF19A3C83F2705780 -:1062D00028819C05B8CF32CBE9C77D80F47C363C61 -:1062E0002F055118626EC0A7E3601B1D374DEA34BD -:1062F000F6A17924E3385A29D7B7DDD7EB9437963E -:10630000ACF91E9A03E5ECD91AAD7732AEE348E654 -:10631000E792655CA7079ED7ECB40E2DC90BB59527 -:10632000C0774B26A5D177DE59EF10BF9CF5D9C2B7 -:10633000769C8FD64DF19D9F370ECF180A78347218 -:106340006C33C8A6F90B60CB94FFEFD5583805EC39 -:106350009BD5C0FF4381FF3B1A9DD4BE05EC432370 -:106360008DEE4988DDF361929B1D8D06B5FB65635B -:10637000367D775FA38F9E3D7604E3DF5139817EC2 -:10638000FDCF7ADED3C8EF1391E57F1B07761AD0D5 -:106390003B7D025015F0922ECE9FCBFA471A5F1B21 -:1063A0005236542003F0D9BFC6D8B0EA02F0A63B5B -:1063B00022A978C4F872170B974DC43CBFEE7BCB73 -:1063C00053F17CC45D656523008FB8BF7D2590CAFD -:1063D000755F339E4FCDA9F13561DC2F6797D28E63 -:1063E000EB57CEAEB525B88F00EDE8DCA0EC37C397 -:1063F000C5F55CF2818795FC51B8B9C0F7E5D99E27 -:10640000E448A2F3A5E35C5CCFF95D7C7F70B5D86E -:1064100057EF9EE526BD987CC045FC92B3FB72DA2F -:10642000DF73F7B1AF1CDF4FF2813F531CD8ADB41F -:10643000EDC37D4AB680DB9F929FFAFA0EDBEB97A5 -:10644000D0FEAC5FA3B83098BD34BFD3B30612BE44 -:10645000B1BD598F9FD513DB650181A795F6C47136 -:106460007A8DF171C67576D37E26DEDB84F8CE791F -:10647000AB4D417FFDB4C2F331FA033E764039673C -:10648000721BDDEBF49C3354EE82EFFE641C2B5840 -:1064900009E0B80A7F9F8BDF497CA845BA13F5490C -:1064A000CEEE0FF8391F5B978EF96F8BEE7E9EE272 -:1064B0008FAA1ECCE3E5952B313E99E10D6E403E4F -:1064C00061E1E7CB0E029F3C20CE2DE31BD47BABDA -:1064D0005DA21C6E6F0E009FACB6F3F2A2BB9F23B1 -:1064E000BE596D0F2EC673CF586E86FE57A7B6677E -:1064F000DBA0EC6E7AA6F9C8202CCBF6CF34872728 -:10650000831DEA92FA39988378EF291B501E652A79 -:106510006BBCCC9CFC29E7577BE0CF870700BFD43E -:10652000EDE6F7DCF4E06DD75A05D7A35F361EF130 -:10653000356B424EA4FE8075FEB26C467E8A1E51BB -:1065400022F90ADEF7D19A69CE57F941B222E21652 -:10655000F0BD39FE1877AE8D8ECAE0FADCCCF3427E -:10656000E2E9FA7652495B52069E470DAD52510F51 -:106570003E633728AFBE4B23BD7D4AE6D537D8C929 -:106580001EAC11E75CEDCB43AB46A05CDCA2F9315D -:10659000BE509DD75682F650F58B79FE2616CBD38A -:1065A000AD4E6DCF1CE38EE5E9CAF20A1197CA4AD7 -:1065B0006D484D2DC4FD98B5B9B85F52C7DA6EFD70 -:1065C00009C2FB86CA90DF3FDD372905EF1DAA858A -:1065D00032C6C16A3B8EEA2168776512BFEFA6AE6C -:1065E00003F8C6CDEFA1091430B641339250CFFF66 -:1065F00032D030124DE24DAE5F97B9FE81B127F235 -:106600000306D2F995BB8F353BB1AC1B23D8682C60 -:10661000FF6B33F259F5681BE559B2F0BF1E0C0C45 -:1066200015FBBD506E750D9A6A8E7BE7887386F5F3 -:10663000EBDD741E0CD6E58DC8DF75EB6C61DC3FBD -:10664000B3393BE91CD02B2E26E8633D3F75BFC212 -:10665000F56178018FA72E9D91F66D3A3FB532DF37 -:10666000085F20AE5B793E89CE49C9F295493EEA82 -:10667000BF520BD33E52E5792F9DAFFAFB8DE7B4A5 -:106680009CD7EA3D9E9BE091E3D5C4C623BA1E1871 -:10669000F3FA8343816E4BB7DB6D0E13DF2DDD2ED6 -:1066A000F6E75D812CEC2743E77866E80F02AFD16F -:1066B0001D37BC1CD6B241FF4BF90E9F6B2E9B8C35 -:1066C000748BD533ABFC07D01FBF274996FFBDB9EC -:1066D0006C6082F64971EDF365FFEA4AEC3F1E9E5D -:1066E0008CA458D909EDB5BF3A7ACA08DF5A5B5C69 -:1066F0007F69B2EC5E89E34BBE6ABD3BFD5018F882 -:10670000EA9ED4B612D4FFDD0B980FEFD1427EF58E -:106710009BF46DAB8BCB75E5F97C0BBD63782FB02B -:10672000D0E5E3C66CCBBEE7A2394B697FB6D52571 -:10673000E8C5C2FC9CCDFA012C628A07FD7F38FEB9 -:106740005638AEEC038E6FFD17C3E1B38C1783632D -:10675000A805BEBF158E8D37147C3B0F9A3CA084D4 -:106760009DF9B82EFC8CE7C5A9A965BE26DC97F972 -:10677000994671FD618CE7BBE46BEC883606E5A7B2 -:106780002D807110B69CDB2BF0BED53E86D621F253 -:106790001786EC76CCC5BC8DFCCAC0627CB2818504 -:1067A000B4EF23F749998813CA7D9E61062BC17BFC -:1067B000FF8E27CDA5752A3F38A71AE3EAAA675CA2 -:1067C00012AE870FD822611C2F7C1F1F2FC31669A2 -:1067D00077A2BDE41D6AE07A97E1E5FA8FAD2AA4BD -:1067E000F56FA32D7FE46D00C74AA524E935C47376 -:1067F0006A3EC5C7F13DDEB3B351AC5B6AAADFC0E8 -:10680000756AA358B75608FD2EDF27A705E7A21D16 -:10681000F1F355D3A63A27A11E0AB4F683F5E6DEB6 -:1068200055D356664FC2F5C697EF84F5E5DEA469E9 -:106830002B9D30998D4DBEFE466AAC3CECAFB05AF4 -:10684000939E98B632007AA7D9BDA40AED1CA83F42 -:10685000847EE2136952EFF0FA7CA9A7502F811EC3 -:10686000539B7ACA61D44BF93D7A671AE99DCD8F63 -:10687000A9545E0AE3A11D03F308E3FD60DDC33400 -:10688000F28F5C004B12945D23F269FF0CE6CD920F -:10689000D0FF1FC1EBE57E873ECC46FB1DD81EF125 -:1068A000E8CAE1EDF559FCBCB4EE7193DF26F74F71 -:1068B00054B17F9724F254146316F9C1CE35639610 -:1068C000A01FE51C6ADD9FD6E3F259D4F8FC1677C9 -:1068D00094ECAEB62411BFEEC7B2E9DE04F11E2C73 -:1068E000E531F8CCBCA9B984EED3F33003F3A9B3F6 -:1068F000435166B697E4D301EBA8CF24370E370B8C -:1069000024CAA75898CCED61F7798DFB890AD8374E -:10691000B88E7A841D2EEC23BBBCE7286EDD95F67D -:10692000925DDCA7B774C6942C3C97A4BA034EB40E -:1069300073F61963689F4665FE6B4B4CF64E737495 -:1069400006C5273523C0D0CE795DD839AAE1676660 -:106950003BA7A5111C7058AB361517D0FD358FB865 -:10696000A2CE2148DF076C7ED41B07C65485158C48 -:106970004F2E6324A79B8A33A7E03EC3062D98724F -:106980000BCACB5B309E8FD38DEF73AF50309EFE22 -:1069900085339882FAE09E5466F1A3AE4DE6FEC8B8 -:1069A0009624AE7FA49FD002F044010EEDFC48BABD -:1069B000CF67B4B04BF53965142FC334208C7F3AC0 -:1069C0005803E587CAFBEA1CD9364BFEA376BE887E -:1069D000E2895B92F83872DCBBC47D83B2EC640D53 -:1069E0003C6E0C3C9EC87FAB15703AC01EF2917D88 -:1069F00012B7FFDFDB3E227B45D2A7C74E51F8B965 -:106A0000D0BEECA3FAF3368B9E8D9D67D7492F9F9E -:106A100011F705C83C10B7D0672DD9A1B6ABF2620B -:106A2000F70368221F648DB81780656BDDE673F885 -:106A3000C9188F81FA669117921C77AEDFE55E4A1E -:106A4000FE826BB8663907E66421FACEE1B3BED7A1 -:106A5000B2E3EF0B08F7E48151DEA2C61E56E872DE -:106A6000006EEF0E107958A793DFA77823D8BB07E5 -:106A70009CB42FC1CF89CA78D837B58F5F47BB8AFE -:106A8000FCC2E9A3B1DF45B81E613C9B0573F8A6C3 -:106A9000633BA3BCA1247F17E3778E91BDA54A3D3C -:106AA000177EBE19FDA80CB37D67B2D72E5FFD7CA3 -:106AB000737321F91D545E74771BE9C1952E595EDD -:106AC0004D6558AFA2E8F7B09D0E1FF2137C1F4032 -:106AD000B961371490BDACE6834B0B7097E1FD872D -:106AE000B83FB0D3B111ED59F06BE7B94C71B2D3E7 -:106AF0009E63B9AC30617F614B7FB9DFAC3F18BF9B -:106B000003F38C647D99775D54E5DFF9F03B36B093 -:106B1000F3FD30F4FFC00B0EBA9744DEB31CCFAFC9 -:106B20005392B9FF8E7AC39CCFA9CFA90820734A8C -:106B3000F974642759F2BFA5BC6AE787937CCAEF52 -:106B40005E4FE2FBC79A16A0B89A76BE90E47F8BA0 -:106B5000A06B4BA3719171D2FA18670CF5D3F7387B -:106B6000C5424F30B13FA619E67B64FA92D7F8FDD3 -:106B7000C078FD269F52BFED15FDCF4DB6C697AB31 -:106B8000D6B51F4616FA892D54913C1EF3BEDEF38E -:106B9000E2525C638B16A1BCDDDEFB7D1D4EEE4731 -:106BA000224E50B0F5B6FDC8AE0DC9A1F54950AEA4 -:106BB0004A16FB00D9B0AEA9B86EF1BCA587B11ECC -:106BC000F31B42BE87A6A29E9A554EF1EBE7928335 -:106BD000BFC1EFEEBEAE98620512EED58D3CDF4E22 -:106BE000EA4B37E20BDA3BB4061EF77407A2685F84 -:106BF000DC97FCF6540DF950E372B06CF5FE951875 -:106C000017716A7EE22BA7DBE6C3F5DD09FE1DAE38 -:106C10007B4D6E1BC59356E03DC0F0BE599969A0EF -:106C2000BC2EF1E467B10BE847ED7CA6D0BFD67B64 -:106C300075FEFEE3A4D3F7BDEEEF3930298AFD6976 -:106C40007E46F93388840F4D7A55AEEBF1DFC5F7F8 -:106C50002FF129F1EBD04284571DED8604703D9948 -:106C60006CDDB7CD92FA33F59D8228BCAD55BABC28 -:106C7000689F805E7C12F9A46E54F7AF151FE9D3AC -:106C80004C6ECF84E57D0596FB91645C5E7573BBAD -:106C900046C2BFE4B5079CE67DA77878E3D74B777B -:106CA000A1353FC3393029EEBEE0263E8E1624BE04 -:106CB000B14F0E38514E9A8C3106DA2BCD9AEFB780 -:106CC00001CA2BB193DD0C76B8657CF9BC47DC0FAB -:106CD0007C54D851F1F51E719F72FCFBCF85FD707D -:106CE000CFBE9B480FF7453F3C508DF4F5E433038E -:106CF000CFE7D805BCDE8BF4DB171FDDBB8FC77574 -:106D0000B589CE08BA58F1E3A9F66000CF93A9A3DC -:106D100019D9BBEA203E3ED0D2C0B8B0775C1A1B6E -:106D20006E5A67EF1E7A1DBFDF39C3A0F37DAAC775 -:106D3000164C64674A3C1D4C96F75470BEC9967C4D -:106D400033ECF7740FBA896FBA13F1CDC164AEAFEB -:106D5000100E333DEF1E9A9F95883E31BDC8F9EA6B -:106D6000627CD121EE4BAC45DC807F5323CEDB9F90 -:106D700012F704CD4B16F70519DC2E96F75F7468F1 -:106D80008164B4ABE6F5EC5307E85C4A8D2B903296 -:106D900009F9F228B77B3F2EE1F7967D6C0FA4200E -:106DA0009E3F3EAA2A4DB4CFCFF302659ED5C7764B -:106DB000DFEA91503FFF176AA089AAADF6DC2916D9 -:106DC00018FBCF68DFEE5269FF28EFBEB9EA2868EA -:106DD0005F01861EF2D1BC527718D7DF8EDF37BC39 -:106DE0008F7A68FE630EDF7218E7E0BAB15F62F96E -:106DF000C41A8FCF4171B27C05EF155FBA36CFA0B0 -:106E0000FDA3654CD81943CB4B8732F614FE53C60D -:106E10009D9D74CFB8A80FB694C1FC466674D8DCAB -:106E20000053C41D6CC1734E2B9B82D9E8FF5DBB20 -:106E3000A6A005E38F999981CEAB411FAF5833BC13 -:106E40001CFDC18E47447FE1112DE8EFBD6C0BE5C1 -:106E50002950FFD49A29E594973B44F67F03D5CF78 -:106E60007BFCB22F8F1988D3CA728C9915CF91F001 -:106E7000D49697826E5F30599697E8584E4F669633 -:106E800038983DE64F529CADA3C77FBCA31CE3607E -:106E9000F3A734946AD07F9EE7A72D85201A13DAD2 -:106EA0004A8C005E99EBB9AF3C39036FCD0B54E3CC -:106EB0007A32D2737F39CE27BD9FB5FF7455C45344 -:106EC000D9BA16ECAF07BEF0D6168CAFCAF66FDE95 -:106ED000F34E4B78608CEFBF1BBB5FE93BEE0CBA07 -:106EE000B7EE3086D8729775EB3C9F57E4DF0CEC19 -:106EF0002AE27945A23CBC8BE75DCB72362F772C1A -:106F00004FBCCEFFDCCBE5AD232971FDCFDC5C5F50 -:106F100000DCA4E7538EB1C0B6047254E17653BBD3 -:106F20004360E739D362F274AD83B18998DFE4E45A -:106F300070CA7EE2BFBF538CC3C2D7A6211FCF1435 -:106F40007C3EC4AFF03CA55DC911FC3D06F0B2B477 -:106F5000EFC17CB68A78C45617FBE12C183A338906 -:106F600085F0DE9C8C7E502EA4EF03DBDDB1FEDECF -:106F7000E022CCA60E096EC6FEA666E58C5E9117D1 -:106F8000EB07E06E768EB1C0AD4D4CC3FA707F8CCE -:106F900093F4E0B390CF03F884F005C33C8DBF1F9A -:106FA000D0D139321FF5EF484CBA31E9F9E2CEEBD6 -:106FB000E83CCD52AFD81FF1F1EF334A79DE4BF701 -:106FC0008BC9FCFE4C676781793FEB21B7C833B8AA -:106FD0006BE643740EBAD3CEE8FCC2F6920BE61D04 -:106FE000D6605CCE6437D66851F2C76A302E371649 -:106FF000FB7B83CE1F623F3E117FC6B85AC68AC450 -:10700000F497EB60CD798385FBF5D697B1FED35924 -:1070100078ECC5E715EBCFEA37F6EE4F17717C81B8 -:10702000774DE05D4F0CE75EC9A7806F9B89BF1667 -:10703000087E93FB8167768ED868DE7F95E7864071 -:107040003F3F8DBF8F10EE4C227FA5580B5C83ED28 -:107050008B3BD3687F40F287E40B49D78EB4068A16 -:10706000B7743FACD039AE78B80E49B8D6F17BFBD7 -:10707000B2E68454F33DE3521EA0FF0ED1FFB8895F -:10708000243F8F727900B9B905E517EF61C179F82E -:10709000BB8ACCBF4720E12F425E1C4F74E4F87FCF -:1070A000C125F25738DE7AE3BFFF45E8994BF42C4F -:1070B000EEDC4FF3ACE9436EABBC5E9EC7762CEAC8 -:1070C000F541BB3182FF3BDA3FA47BC53A76A94C40 -:1070D000F1F179A3DE2AEED1C7E35F9D02FA38AB66 -:1070E000A70CFAD28774E8D19F51A733D6FE07DEEA -:1070F000F1D39A515F8A7B7BD355586DC6C4E0F8B3 -:10710000939BDB57134389E3580D5E8F458F3DBC3E -:107110006C0AFB10E67FA59BE75F4DEC0AD3EFEA14 -:1071200048B98ED753FD3C9C8E86E7FF929E725DD8 -:10713000444FB9A49EE2EF0FA1CD3B06D7D7AE22B4 -:1071400005ECE60A5B2013FDAF8F8EFE84CEA72CE4 -:1071500012F939A3303F07D7CD63415A573EC54A8C -:107160009EA733D09381F9DAD63C1DB6999F6B8DDB -:10717000E7AB181F8585FD26E010EBC1B58EAE6725 -:10718000793CC32ACFB20C70D6D98698EADD7CDD73 -:107190009274007A37D33DC7428E8FEFCCDA80FAF3 -:1071A000F64D0FCFB3491F12188DF3977209EBAA52 -:1071B000E013DB0FAF7373BD715D02FE9DECE17AEE -:1071C00076C13ACE371DFFBBF41AC47BC79B69A9B1 -:1071D000CB4D7AA24CC8B1EC57EA21F99DAC9F2265 -:1071E000FA9BE6E17251E6E67C877024CA272833D1 -:1071F000ADAFC43FAD9C7F60BE61337FBF29FA8DC8 -:10720000E153ACAB02CFB53AE017F0B7D51EEE8F25 -:10721000F949C59D36EAAF629787F2322BDA391EFB -:107220002BDAF6D9AA4DF889EF6FA987CBD1067171 -:107230000FED211BF01BE2DDCDE13BB33387F4E71B -:10724000220FB71B2EBE6E5C9A9ED920F23180BEF3 -:1072500094BF58FBD2800D563DCDFB4BEF175A81A2 -:10726000E7F0D21F627ECC29033C451580FB4B8F93 -:10727000D03B7A40C7F3B6DD0F33DA8F1F362730A5 -:10728000DA07E5FAA07B8C02FD15B4713D5C7C3F0A -:10729000D83128774EB92EBCB6CD3CDE9D1E8FE589 -:1072A0001C61C53A8EBF6160FF3C8D4FE8E759B263 -:1072B000E3393CC71F6CBF0AE34EF2FB5641FF8B1C -:1072C000C1578CF08D8BC187FD53FE8A3BB81CFBE8 -:1072D000ADFBCD8E01E67E1FE8E977DE1417EAF9F3 -:1072E000B5B0EE9074860EE0B98B8ADDA906DE9308 -:1072F00000F26C437F478E5BA1C9DFCBE92AC67BD6 -:10730000C20B7AC69174FDDD33E6F96FF2B8FFAEB9 -:10731000F4EDD043349FEEED00AF2F86978EF6B993 -:10732000CB5DB84E1C637E5C2724BCC3E674793108 -:107330005FA45EAC1F305F1BFA2FE9BFF0B1158868 -:10734000B7CE29744F423C5F4B3A0D675C7EA49FD9 -:10735000361C03FC50DEED2912FA87919F7BFCA5B9 -:107360003D4FF37B2D385DEAE7703A7679425F7ADC -:1073700032627208FA9CEE2FAEB8BF471FB5F3F722 -:107380009DB973009FBFF64839B7D2253DD8EEA20C -:107390004B66055F9F7E71546415A7338DDFD1EE78 -:1073A00089280A9EA36D68427F5BEA0984C79CAF67 -:1073B00024E1E9A123033A8E8ABD1F3687F7570FD0 -:1073C000F28E7C54A33628390AE9018AAF66A11EE1 -:1073D0008072563B6FC776F3FB1B249E6A6E844E09 -:1073E000C1EFFC574F21CD43E22B6B4ED45653884F -:1073F000F9CAFB077F64A2F311B15F8078B98EFCF4 -:107400000DAEAF6BD4E040F45B599683CEA1C23A87 -:1074100044FAE5908B692EE8EF5578E2BA3455BD11 -:107420008DCE094D1DA2901C830690F11EFA3DAE33 -:107430006BAF4EE6795B7FF9D1509C674632E743EC -:10744000E8C729FA71D23A28D6837FC905BB4E898D -:10745000E9E5438A42FD1CFA87CB37AE50627C894E -:10746000FDA1FD7448993590D6CB8E0C911CD46546 -:10747000C927EBBD9E75E562BDD95F44FF2EE66F5F -:107480002A774D039E9A30BD3D8A574E3785D56980 -:10749000FF08E34E057FD385FAD3CBF9FA505E5847 -:1074A000F5225CC314BA5FF97052A890DFD3CBC742 -:1074B000C914719B4C91AF8CF6023E235EAEFF4720 -:1074C000A6F0E78FC533D39B38CEB356D4D78B7B8A -:1074D000AD579524CE671BE8552CF1966BC5BE05BC -:1074E000DEFFEBE57EA7C8B3E5FB1C60DF137E4B38 -:1074F000EF9A43FB765F745E9FC2EF6FE0FAE04362 -:1075000025F0EB1B157C06E9FEBCF0DB2AE5BF7F0E -:107510006404BC98DF549B94380FBB44CCAF56CC6A -:10752000FFE3467EDFC27CDC4F03FD31D6CBE7B103 -:10753000A86D6C39D27BD11A85F6D3E4BEBDA46F99 -:10754000E57AD5124F9F8FFB69FDFE163FCADF8794 -:107550001F35CEE247C971E3FDA9E38DD996B8FF87 -:10756000BCB621E29E0BDE7E3EF313DCF35B0758D4 -:10757000F6FF586BC6A5DD030AFE5338217C3AE9B5 -:107580005BF9FE78A39385CD707C3294F21E067A67 -:107590004337217D637024B3B0190E3699FFEE9501 -:1075A0008BC75DC10EE7FE0B3C37B8C94EA77B6A9F -:1075B0007BE260A03F8C14D4472573BDE3637E83D8 -:1075C00094AF9AC989FD8771C2CF1DE7E6FE71CAE3 -:1075D00031E94F27F9502F4A7B3CFEBB861EBEB5D2 -:1075E000DA93178B3F00FF86CDFE517CBF2DA2DFC3 -:1075F0006FCE2FF97DF04BC17F89DF5D3C3944F1BF -:107600003DD6A6502ECA8432AB1FF48897AFE78FC1 -:107610007893E97B695757CCB1B67B0CDB8DC76794 -:10762000F225C573CCF6BB3204F51FEF4FFEEE4ECC -:10763000DEC93729FFF377E827427F6FA404B6201D -:107640007FAC11F9F21BFE7A207B3EDA43FF6CA778 -:10765000FDFA924797AEC07C6677BB62D0F9A35D16 -:107660005679F8CEB2F6C115808F7641A71A3F9FA2 -:10767000478D3FAA0F75637E351F7F60FB3E453304 -:10768000F1DBC04ADEEE25AFDD129FD98B65E867DE -:10769000B7D7907ECBBE19E9D83EA0A11DD01F7FE1 -:1076A000EF06E0E9DFC0C88EEE3F4EA1FEBF336EAD -:1076B0008382BFBF25E7D96A9B5568C077AD99C95A -:1076C0007E5C6F328DD0419C67CD7BD1282E8F138D -:1076D000DEEBD4D0BF1A6E040EA1DCC979F954A335 -:1076E0003FDAEDC9EF71F8DA7AE24A7CBD616CB538 -:1076F000B04337727B4C654718B7C7695DCF5C3EB6 -:107700009CD63D399FCC34B16E64B210E61F43FB6A -:1077100056B2539C7CDDCF5CCE7F2F4FD233E667D1 -:107720008E18837EE69035516D1E7CF7D27A5BC24F -:10773000FB353E14788779BC6F9EC7C5F4956C679E -:10774000EF23CE28F93D797A62FF9DB17BA9BEE493 -:10775000D1F49B492E9B75BA0F51E27FB811FC1CE6 -:10776000E1E9DFBE4141DC1C177905C7573DADA0FB -:107770001DF9A3C5CC5013F0538FBC2EDB31B8C21A -:10778000A437A17FA2C786B83C71196F71A570FF9D -:10779000E71623C852C653DE2EF9CF8B37F3DFDD51 -:1077A000E8131F97882FA592DBE535B3F9EF8E9686 -:1077B0003CAA11BDAB9BF9EF0ED66CDB4EE7ECD8C3 -:1077C0004F991FE5BDA67DBB5201E3566FDBAE2C82 -:1077D00030E16F404D84F2AB2FF3C87D8728D9CDBF -:1077E000F17C8DF102B4530EBBB8BC9F2A71877136 -:1077F0001FE2943D5483ED4EE524FB719F52E2FB62 -:10780000D5EDD3E8BE03CF0E47149FADB68DD94E4C -:1078100068D73A52F7231F0D3742C3102F695AB069 -:1078200003BF4F4DF7F8711FC3E7606368BDBE44E7 -:107830003C4C88E387093FE57272638A57C805A309 -:10784000BCA7AB533CD27E22FD74D8CEE7B1837186 -:107850007823DEC0B814E4C323FC7713FAD74415A9 -:10786000CC17891F37C64F812B11FE4B87B35D475D -:10787000BD5E2DF44CC9A39B950F4D70CF40A30A5C -:10788000F973DB0605E364504F7A06DA33CC4BEA32 -:10789000BF8DFBA5D550BFC0A457E43C12E897208C -:1078A000C2E77EAFF320D72F51BE2F20E08DA7E790 -:1078B0009C141F8D5F0EE601BDD7C3C3D12F3E9C24 -:1078C0009F44FD49798F97CF3982CFFBAFDFACD88A -:1078D000DCB47F4276A4844FB67B23654A08E199E5 -:1078E00030BD93F050BB5EA3F94CD583436F33C9D1 -:1078F000435D0AB7E3F6DFF83EDDFF73FFAF8E129C -:107900003FD6823F4DFE44DB51FD7A5C57C24FAA01 -:10791000B8DF750D3749D883E25EAC6B3AB8FEAD7F -:10792000EDD8AEE13D92924FF34EEEA7FBB46ADB89 -:107930001D0CFD28E0BFA548EF783EBD547A821E9D -:10794000E27E525817F1BC501EFA39523F47843D2F -:10795000CADCFCFDBD024F31FE09B5A458F4AB8B67 -:10796000E422EFE498FD989759EB57E8BCA48427EC -:10797000BD34B17D2EF5A2D4D718370C9AF4FA5A3B -:10798000A4EB782A47B93FCAF2715D9670C6D3E975 -:10799000E514AEBF13F0D3232909D62BB97EE73DFA -:1079A000B643C37B91249F5C83F435F1C99329FCD2 -:1079B0007EDD275334EAFFC112BEBFF8A09DAF534E -:1079C0000F3639295FF2D59B78FE96E7663D8ACF60 -:1079D00043B67935587FA83F87A3D5B69CCED781CB -:1079E000FC3D95427CE2655C0F72BD77FFF35C6FF6 -:1079F000D584DDE4CFD684BE5F4179ADE92E3FDD8D -:107A0000F7193AA85FEF89E1359E8F7C3BF6D1EFFD -:107A10001D5FD3CEE50DF426F1510C7F1CCF524EE5 -:107A2000A43C44E4FE0DF001B77BB8BF5428CE3B24 -:107A3000563AFD745EB252C4550BC5B9C7E2630134 -:107A40005A0FE6093A14D982AFE2BC2AD6C4C5550A -:107A50002FD1EEAF5EF6FA08FC5DB0AAEC23F494E9 -:107A6000F2087EA9456EDF11FEDF1E41EF3F08F9E7 -:107A7000AF1ED74EF256FD5103C9A97B3AD757EE38 -:107A8000F7AC7A96B17BC47CD7D0775393DBCB71BC -:107A90005F78EAE30ADDABD9179C8BF01C18FA6F0C -:107AA000EB0F78E7A23C8BDF8792E765CE08393988 -:107AB000B55515BF97D9A05FC8AEBE587F2CFA96B2 -:107AC00042F795089FEFD4B6D2497F44BF736B0A43 -:107AD000FD7EC967DBBEF7E33FA6E3EF835CEDC73E -:107AE000F53F7D4590F8A53BC3E5DFC8E3ACD33156 -:107AF0000ED5D47EC08BE76B3E7DFA8A31A88FF11C -:107B0000DE2D9CFFC9E7D5658897E54F3CF72DAC86 -:107B1000AF8E28FDD02E3DB5F5F1FFC0DF81AADC88 -:107B20005C4FBFF3BCE2E957C8BEFF3F75A9C786EB -:107B300000800000000000001F8B08000000000013 -:107B4000000BD57D0B7854459A689D3EFD24DDA140 -:107B50003BE93CC9A393404025A1131208F2EA2453 -:107B600084872076408620AFE61D20241198591C7A -:107B7000DD9B8620221767E2EA28F8DA0E838A3333 -:107B8000CE18306A90A0CD43C4195D5B040767919D -:107B90006DD4419090F446671677B8C3ADFFAFAA95 -:107BA000749F930EA83BCE776FFCFC8A3A754E3DCE -:107BB000FE77FDFF5FD51A5FF3DF52ED8454EFE9E6 -:107BC0006F3510422EFEF2E1716428218D2D8DFA61 -:107BD000A099902F7FD98CF5C3CFBFF4C67FD3F780 -:107BE0006ADCB14E78EFCB970FE9E1798D47EB6A0C -:107BF000A125F11CD5CFB2D0D2FB824C1209994AF3 -:107C0000D8DF637B0FE91D79B4DE221142BF27550F -:107C10007ADFA02CFA5DCB5EED1233BCE123A49891 -:107C20008EFBFCC2511EA8B7251092127EBE554F86 -:107C3000BCC6385AF623C444CB4BA566AFD49F903C -:107C4000D565E6AD505EFA8DA9CA47BFABD50773BF -:107C50006D309FA1C405F578AB86900418E76E5D82 -:107C6000AD19BFC77E3ED21102651EF192F34308E3 -:107C7000A16FEDBE361CC6FB2DBE4FDF2B3115129A -:107C8000327BDE3909E61333B45EB71AE7F96BD6F7 -:107C90004E571DD93E623D1D8F8E7B0DFEC687CB94 -:107CA0003CAB19DFA700C132B5B532CD01EBB71B34 -:107CB0009CB07EB1BED46A4FA3853EBF6DBDC729BF -:107CC0003B0879FDC289890368FDF921D270195EEC -:107CD00097A5856EDA7FADD78CE3ACD950463EA32D -:107CE000F31D6F95F0FB442BB1DF4AD753A12576E6 -:107CF0003394849CD41542FFCF62BBC3405CA488FC -:107D0000966FCE7E7623FDE4319D27A518FAD91A09 -:107D1000D03BA0DCCDE64FBFB79A0BB13FEBADF047 -:107D2000BD91AC85EFBA364EB36F93B0DF802E2E87 -:107D30003C6F424219B3F2587F4500A7C9DE2A784A -:107D40009F38F4B8BE2FE115C4A3377F7E1E940F71 -:107D5000B1F96A8807E825514F4B84AB27AB92D223 -:107D6000CD7C6B6995B5385C26F663ED6AB83E0547 -:107D7000ED149E67AC2E2CC99E784246F57E4F943A -:107D800002FE876777EA8374DC470F9C43BAAD0530 -:107D9000BA85F13D9FEB611D826E9708BADD7F0EBB -:107DA000E976499B84F454DB56A0077ABDD4E022DF -:107DB0009F69699DD3DF63527039D0B577BFC9FA27 -:107DC0002C8553A7A0CFEDE7CECB141ED96D290E7D -:107DD000099EEF6774FA9646E30538BDB5EB96E663 -:107DE0004629729E1B113E5235413EA9AD273E03E6 -:107DF0006D2F7D7AFD8929B4BEA69A380D943E6A0E -:107E0000557494F5CCA75B805E6C35A4C8E480758E -:107E10009E9D3880F65F5B438A814F5327B8F643B7 -:107E20009DB4496410D4ABDD4B61FCDBEC2B9D327F -:107E3000EDDF36C1DD0AE3DD661FEB94697F8FA5B8 -:107E4000B76C31D2766F05B13EEB00FC36956969AF -:107E5000FDB10A87954292C26D7732B493217AE7D9 -:107E6000B340C79EA535D05F6DF25C27D0492FFE89 -:107E7000DFBF7108CCB7D6D1CF69A2EF4F6D939019 -:107E8000AE88D74C60FEB514BE509FEA1BED83F957 -:107E90005CE6F01370ECD40516C0FC3A5F31102F8D -:107EA0006D9F3A81D1AB6D420BCA8FB7F74F3A2E17 -:107EB000E587E9D2F2AAC10FF538AD5572825C228E -:107EC000330D91786DD291856EFA9D6D32EB2767F7 -:107ED0003BC3EF739C9F9E03B981A59EF36F13A3D1 -:107EE00077AB37DF4DE9E132C73FFC3968BFABF113 -:107EF0001F143F4BFDC84F352FB2FEEC0657C1BAD9 -:107F000008FAB59713E4E33D26B2B0923EDF63630F -:107F1000A59A5EDFE5F3C87A662DE27D09C53BE0F0 -:107F200035753B7D0E70A3740170A378443AB8CDCB -:107F3000BE02F1B664BB7417E2D13B82403D219E84 -:107F4000AD53DD7F80CBC53D26779144FB0B255893 -:107F50009CBB24988F4B63827A81CDB98BC0F7EE9E -:107F6000DD305E4292C9D91821AF08711769E8382F -:107F700017122D0CDFBEF7B533F2801F1DD86F82AC -:107F80004CFC04E50FC976E785BFABC861FD55F031 -:107F9000FEA63579F349368307C285C3C3B7B15FFF -:107FA00055A43CFD08E041FBF5DD44AA406EBCA5AC -:107FB000276623F46FA5E3D0FE12778DFEE5369C8D -:107FC0005F23BEF7A6D58A6545BCBBA81E44708E4C -:107FD0007B3DC045AC530D8FF91C1E87672F28D001 -:107FE000001DDF697602DF3D7A405A8C74ED355210 -:107FF000A604BA677C48283E802F88478BF8A8AD36 -:1080000077FBA2D37D25F259ADDDE4344948F72E44 -:10801000D47F5EB38FD13DD37F319399BE0239595E -:1080200099D75B1E083903FA0DE859F045EDB860A1 -:108030002EE0F7DBCA954E1DE3F34E0A07E023C19D -:108040003796D719BF6CDBE82885F66D94EF23F1DE -:108050007D4CEF45FE3D96DDCF09FDC23CDD96B07F -:108060007C4FB4BAFBD9609E1AFF166D56581ED7C6 -:10807000BEFE60AE270AFD09796CD4323967F4C5BB -:10808000F858BF6C3C2305B7A5104B2FE8A3980DFB -:108090000C3EEA7ED26D664E8F46EBE7548F4FA7BB -:1080A00048EA9F43C8648D27DD46FB5F630C1EA32F -:1080B0009825191B427A984722E82EE09F5D313EB1 -:1080C000905B8989C4B32F4ABFFD6D8CDE045E9A34 -:1080D000E2181F25C6B2F747D918BD0CB5313E2DA1 -:1080E000E3EF8BF90BFA77683CE788DCB71E13DF08 -:1080F000D17961BB980FFD7E2B61FA17E79BB829F8 -:1081000077D7B6087C84F9E8A642C053CE76BF760E -:10811000B1393C8ED0A76AFCC3FC817F603D95439A -:10812000FB7EAFE910E347353D4EE17C62B0112C98 -:108130009B74FE3F235FDD6D21BB607E3B882B9EE1 -:10814000CEABEE8DC18C1F5CA15CE8FF609C6737F5 -:10815000E063E4044EE7F4F90CFA7CB596780D146C -:1081600027ABF7E87C4123E3996BF4FF62C0139DD2 -:108170004797C5E895299DBF1FE7A982EFBD65C454 -:10818000E907BDF4532A3F80FF88BF18E44B1D095F -:10819000C6029C6BE5402EA1F8BF1AE3990FF4F8D4 -:1081A000A9269001CF090922BD9E31C5E613DA5FE9 -:1081B000ABDE9FFE4F30EF7764B28BF6D34D5C534E -:1081C000611DDD014D9C97AEE393B60F7F73807EFA -:1081D00035FFC0E5F9F70294B6C52C789296F38C7A -:1081E0001AA37678181E672CD1E5EB8F395D2434FD -:1081F00032BB2BB4D1E003F8A8DF1B1FC7F05F77B9 -:10820000259578E3239F33395AA70DE9C184ACBB88 -:108210009241BC74DC4F34A4BA258A9DF9A18DE942 -:10822000AB564AFAD1DA4F733ADBA323B93B603E2F -:10823000CD540E02FCB40E9417D58F6439B7D16AB1 -:108240006B76E818D811A15F4828FFCFE898DCA129 -:108250007F771A4784F5279827601F565BBD7E0DF0 -:10826000951BD5EB2D7E391F9F6BC700EEBC562D9D -:10827000C8C1C55C2F2EA97FFB1B2996B66B8971DF -:108280000CFDEE0BF3D258500BCB7FBC2E118CEFB4 -:10829000A4794DC89F844CB0823D2EB9A6C9D7623F -:1082A000AE67CF69D16E477AA1F82D8F733F09F879 -:1082B0009ED79FC17BDEBA189F3742FEDDC1E1A386 -:1082C000A6B33D40A374BE6725A657D4E3BC1057A0 -:1082D0003609FAFDABC5FD1CF6BFEE32CAB379070D -:1082E0004C19A0B7565FD1205EBA0A02B91BB28002 -:1082F0009E43197FA0F05BDD6EB07A1DD0AE57E0D3 -:10830000F5D3062AD072C3F5C517064E246680AB96 -:10831000730BE079C9D618E21D129E1F18D240B720 -:10832000B55708F6B3B8FDEDD320A76BB541A48BC4 -:10833000C54633C2BDF68A16E741B6EA3A82E27B09 -:108340003ABFF858573BCCDBFBC018DBF95BE8C3FE -:1083500024FA1CD7E5390CFCF4784C2C71313EF032 -:108360000DA6F3EF363AFAC75138D4E929DE876112 -:10837000376E6384DD44D22C4ABCB6BFF30DCC67A4 -:10838000A9D1A307782CABAAD703BFCDEBEF2FB6AB -:108390000E8DC4E718F9DA2DDF1E9FCF73F9F2892D -:1083A0009ED27B14FE3ACDE5EF782E273E49657CC0 -:1083B000F14906A9DE07E5CDB4A4DF7D92CDEB85BA -:1083C000ACAEEEE72AE78B4FF2991EF2AE657A412A -:1083D000FD5E271FAF3CCE751EE0269E0F8F63CF3C -:1083E0005F88735D043853397799D3A1DF46FB9BCF -:1083F000F7A601E9906C0EE5021E7BD695CBE79BB4 -:10840000187D5EB670BF5F437FF43D17DAE36F9867 -:108410007CB0BF20D3A8DC0539BB369D809CA5E38A -:108420005EC5F772E9B8F89E01D741B652F94B190B -:10843000ADABD88178D9564AE913F8FFA0C10AFC40 -:108440002FE849D0919A7E4C7142AF31FD7A07E80E -:108450005719F5AB298EE9573DF02FED51CFECBC04 -:1084600081886FA433F9DBE3FBA09170F8BAE3E3F2 -:10847000509FFBF3DC79BDE12CE4DF27FD9474E130 -:10848000E3781CC0DFEB81731C7BCF9EC3F499B0F3 -:10849000FB6FE1EBDACDE5B428857E1A3959696FB7 -:1084A000ECE6F263B72D164B8A97C1B07EA1D77A5E -:1084B000E1FB29866FFADE5058CF3C4368413CD53A -:1084C0004B3FA2F68EBE10BF7B1EBEEBE57F98C071 -:1084D000F469DD5A0B017D3F228ED9B1A4289401A5 -:1084E000FD9121B4CC03FEA3F246BA31FE60AF9FEA -:1084F0004279E4F65807DB57CA7440E09921C40179 -:10850000FD517897C62584E1AD1EEF0C3451FB6E0A -:108510006A9CA43D0F382A200580AF051F7C659911 -:108520004FBBBC6C357A35543FFC58E3B903FAE9CC -:10853000B8E71DB4E7CFE8FDB94DE628ED7AFF3383 -:108540008F4BE1F6852FC85E3D9533AD818E5FCCB4 -:10855000A674B938203B61C8C5F7FDF9BD91602705 -:1085600007744ED8AF523B61BB96CEFB8C86E1932D -:10857000D42BF7FBAB38DEA9BDA42523C2F249E812 -:10858000FB95C43F08EC8225C4A587F2D3BB574CAA -:1085900023145ECBCCEB516E5D5C3B05EDE0E5C496 -:1085A0008BED4BB6EA3E8DD413CB9A94F5153B94E4 -:1085B000F5953E65FDD24F18BDF5A67B665F259407 -:1085C00047B71B1EE17479491FBDBD318ED169F9D2 -:1085D00003D31E47FE0FE88881D2C9FA83A5492438 -:1085E000CAFBA2ACBB924D7C117A286C57E412DF17 -:1085F00070E8EF2AFAF9A01FD8BFAE37B992609F92 -:1086000071A92CFA3CFE778FDDD2AF8F7E63B1DF8C -:108610004BD9D75F67DD1523BED7FB7B33F64BED18 -:10862000A7A8DFEFE670B81417BDDDD7D37F32EA15 -:10863000C5F0778C0FC2E3A4A15EADBB6255E8E93B -:1086400070BB9DE955BEFFA778F5A2BDCBED39AA59 -:1086500010ADE763C2724CD78FCD47F0CD671231B2 -:10866000A6A0BFEC612E479DF960F77E067615F057 -:10867000ED24C71B413AD525F78ECAD56687F94A3E -:10868000BD1E4A8F5F0623EC82B6388B1DF5B99369 -:1086900038615CC10F0BEEA9E8EFA178FB8FFBCA34 -:1086A000933C4323E9CE8BE3D7EA853D6756E871D7 -:1086B000A2D2F34BDADE417B6DA9D19D0BC2E94F0B -:1086C00007EF413E594EDC89C01F5D07076778FE02 -:1086D00007FA5DCC67A677918ED9E714A8946F67E7 -:1086E000F0F9CC6C67F6A2C6E8D2E1382EE2B026EB -:1086F000E2169CCD970A592DAD8FED993F3813099D -:1087000019C3E72FC1F714BE637949167B9261DE66 -:108710000618978E6722BE64281B47391D508E9716 -:10872000DC5A360F1FE27922A94F83F735C6A0CC59 -:10873000D649679008DFF7C00BEB165EDF7C67F762 -:108740008265F0DC6C41F9A3E7F3F846C84D2331AC -:10875000C2BA0D66FF4558978597DE32667F7BB3B8 -:1087600089B391BED68FB41018D76CBEEC85C55AAC -:10877000895582BAC9DAED877DC865ABD9AB198650 -:10878000F2F4FFA03C95DE5D0E78A1F29BF9A5FA0C -:108790006AD7FA71FF23E4631C9F5F23978F2984B4 -:1087A000C1C14EDC875C94AEFFC5B27C1A89053529 -:1087B000EEC1F177C64E3E0EF305C0A39E9FACFD01 -:1087C0003452CF24B8B50AF99754A5ACA77894755C -:1087D00023396305FA95FCEEE46BF1B8AF1B027E1A -:1087E0001A1D973777F663F312F49316AF51D82119 -:1087F0006EBECFAF8DD313F40F261A8D6418DA2511 -:1088000069F1CC2E394B314DF7832194E705E35DB7 -:10881000837E41E1BCE503D9B989E2698BC5B151D9 -:108820000BF6DE1CC9F92C92678B1FFC3ECD0B6C3E -:10883000CE6DD06E72FDFCFF40FB0732017BAB0EAC -:10884000FCEDF1F0A2B514BE6BCEB0E27BF6F210F7 -:10885000FA49430F12B4A77AD1E9553A7F0AEF5F7C -:10886000429DC2B76EA975F58BF4FD14778C538ABF -:1088700068DF0DED749E12A70B783E7E04EC6BD979 -:108880005F4E7B41C0057E0B978CFAB0AEBDE08891 -:1088900099CE23C753E004B21DD8CEE32A76838F46 -:1088A000C51528D7D279CC32B279D4B597DE514CE0 -:1088B000DB07068613882FC41C77CCAD81260DDD1F -:1088C0004FC3776531E8CF3AC9FD4A84CB83912AFB -:1088D0007E1B1DA67F6C2F10756A36B84630770553 -:1088E000D6ED8C0F9C44FC31FEBC9584FFE0FBF27E -:1088F000707F288F26849BC3FC469756687436D6B3 -:10890000D0F7DEAA9C84745807FB2E8A8F915AFFF9 -:1089100021E0EFD1BC2CE02559DC84F0DCB6D17F1E -:108920005897052E14B70CF511D6071BA1BFB192AD -:108930001FCB8CAA871B81AC5E03E30CED4E4F0569 -:10894000F0E3960A6205FBABB1C4E9B4D2A6D955EF -:10895000CCEF3AABCAE8033FFE2C2D61F12EAD27D8 -:10896000EB4794AF7E348FF97BA13E2FC29F22E26A -:108970001B27E93E666F147BE0B578A6C7C4F77580 -:108980009BF58A38D2CBF1CCBFB5337EE24FE2D92A -:10899000FCB280FFEE8BE77265081902722582EF48 -:1089A000BDF05E47E9EFFB920BCA762E1766B91E43 -:1089B000D1A11DCFE58390C36EE043FA5D4072E91B -:1089C000007E1F9731F89F285D89F26136F1E073D0 -:1089D0004A203A77A41F6972843D44C799E556DA64 -:1089E00047B3AB947541AF62DC391E65FB0C61DFA8 -:1089F0004E56DAB7F3FEE9AA0DF56FD2736BAE658A -:108A000062DC04F7FF75144F2C6EA2657194CD7A69 -:108A10001FD849756D77BF95007C741FE17CB457F2 -:108A20005A3A14FDB0D2B2083B62408D4F02B93FB2 -:108A300098AE2980780D61BCE8A4CE7708E228279B -:108A400057D215D3791ED1B378E45113F1823F5A2E -:108A5000D0A76506F3A75232C6B8489A35C609F4BE -:108A6000B4555388FED7ADB11667A4BF73DB464A31 -:108A700077117E578781145A39DD44DBFFBEC9E583 -:108A8000E16312F37F7BE71871BF9790E356C41B35 -:108A90001264721AFC883F897788F7D1CF01F1BA46 -:108AA000E1B4F449CC9EE9F95E269BD1EFA8923F50 -:108AB00009F14EF4F727F4CF43BF7D557BC16E9487 -:108AC000376693739014EEBFCAD3AC5D06FE83F68F -:108AD00066ED527398EE4E00BD02DE62480CD06B1C -:108AE0008F1F6F9F01FD783FD6B83F02BAACD1FB14 -:108AF000F389929EF1795F7A6C05A7175D997BCE19 -:108B0000323A9FAEF7F4CCAF751F417E7D79BF0D31 -:108B1000FD90DA1904F5C9E65282F4D0D52CA1FDF6 -:108B2000F685AD1AF7019BA526D4139D7113117F0D -:108B3000ABCC47715F5BFD94EED348BB6BD56E65E4 -:108B40007D3509E0BEBAE6C55EF48CF24BC8C7DAE3 -:108B500056E57764A0523E1670B95FE876CEAC80D9 -:108B6000A9573973D8BE9AF80D741DC5EFEAB9FF3D -:108B7000771ED39BE43909ECAD2ECB0599F13993DF -:108B8000C7C5BC3FB51E2AE6F6D4382AB760FF2910 -:108B9000EC23FA3ED68F6ADAE5644D785E45FC3BFD -:108BA000619709B92DF0525A424809A5FB643B97D9 -:108BB00043D9241BF04AFB477EA0E37AF571D8BF66 -:108BC00017F66DA3F97814EF5ED0B35E8DD10774FC -:108BD000B445AA47396D245C5E4B1E94CBAF79BD7A -:108BE00032C07514A99F398DBE37C61888017850D8 -:108BF0007A48B32784E9A491F833F64A0A7AC1F691 -:108C00000EDBEFA3D28BD02FFE8F997D3195AE185E -:108C1000FAA980400E2D8F4A6C5F38C9FCA816BE99 -:108C2000FFBD660AD2C364E2D3C2FC2AAC4A3C4F01 -:108C30004A56D6A7387AD1810CE3BA383CA70E51F0 -:108C4000B6BB845C234AB99645AE229EC983C77ED3 -:108C50000C7E81980D6408D81DD442447E53CB838A -:108C60007176B3C23E8A88838CB317F78E83747192 -:108C7000BFEEAD24B8FC45A937BD74BEB5414E8EDC -:108C8000A02B41C7AFF3BC09E94D1E6F2D62FEC09A -:108C9000B09E67F43282D76E057AA3EF2F147492D8 -:108CA0004932814EC6B699FC32856B01EFE756A07A -:108CB0009BC2B03EF76BCC0E7D36D08773AB2CF7E2 -:108CC000B6DB13E31C4827C3352EA49362E28C075E -:108CD000FC94185B1AB530FFFD230778CC0ABA580C -:108CE00062473942E902F9AA975E54B6ABE846E01A -:108CF000EF38B7972711EF40188F8AB1A3602FFB89 -:108D0000B318DD541017D2C9DBD953783CDAA3C5A8 -:108D10007E88521F961B9574A0A62B3AA226725CE1 -:108D2000359DF54537994037421FC6DF986EEEEF07 -:108D30009B6EEEBF1EDDA8E945C893BD266B39D8F2 -:108D4000A575D512CAE1E1EF0D6C84FAE0355998AA -:108D5000D7B2D7E644BBB5AE9EB517055C32E4BDCD -:108D6000E4ACE7ED59EE72A8D76D60F187E2932C81 -:108D70002F66E07DACBD6053FD110BE8772FFBFE45 -:108D8000F58B5BE458DAEEDBC2BF2F6D2A877ADD04 -:108D900056F6FD17103FA2F81D71DAD708CF6FDA2B -:108DA0009EE564DB4F66CF8EE774BA57DA7704BF6F -:108DB0006B62DFAD3866EC47D00E6676EB38BECE20 -:108DC000F14FB175DA3FBB6DB283D2EFB29017EDC0 -:108DD000A6F39A9A11286FFAD867964A4D695052AD -:108DE000BA4139E33252BACE66F1C55D7488437632 -:108DF00066078AB81CE40944E6051CB233FFA37871 -:108E00002F318EB038F21316F4078BB8A1FF712200 -:108E1000019FC11AB9FE8F1A479C94538FF1C34921 -:108E200099227E18D42EA6E3165CFB6A62347FCAB0 -:108E3000713EEE059EF7209E57FBB23440177B81B2 -:108E400048520148AB7F0776D35EF0BF32A5E125DB -:108E500025805756FFC8BE62DBD6340A5F4DBDD6AB -:108E60000B4A2683EEBF68D7D303C4DF3FB6F7FCB7 -:108E70002769891FF413D1B2F92F6FA47A500ACB56 -:108E8000A55942EC8C19847C7A27C7D367766E6F1C -:108E90000C27C341DECCE278FB91B15EC7F4659349 -:108EA0004EC5FF5F20FFEFECD36E56B6ABE4433503 -:108EB0001F7739B797579210DA05E7251F9617766F -:108EC000327B79B5F924DA155D4F303BB18604D198 -:108ED000EE50FB0F57EF51D6D7B428EB756DCA7A19 -:108EE000579E17C7E9DAB96604F8EFAA77BC877E00 -:108EF000E16A21277C4A39410D2426271EBF19FD2E -:108F0000361A2395134500AE7E9847329CB8E2414D -:108F10001E8092BD46EB0FC22729B4AE711B1350C1 -:108F20005E4C8EFF5C8C2F639CF63D97238C979E46 -:108F30007DA14A4E14087FCCC038F45709B951C0FE -:108F4000ED123259BD6F7C14F96F38AFE52428F764 -:108F50003DC2CEA0DFA39D11D0987D1A4DA45DE146 -:108F6000437E2C34523D812CE434B2FD4A1351E14E -:108F70007730ACEB3AFB2665BB0AFF62DF3282E357 -:108F80007F0EF10C007CDC49DC6F817E38F171B51D -:108F900062BFF4F11F270A7F0AEE9BBEFB7EC9FF6A -:108FA000BDF64B3D783751FB9196E533A60CFA059B -:108FB000C4BD5B4D98CF5927313C27CE399911E973 -:108FC0003F3CD14012B4117CDF38C56084F860A307 -:108FD0008EED27664CFD64C4E208B9F192B1746A63 -:108FE0004231E021F0937F87FDC53B32C17C99F689 -:108FF00004C47B77137D4EE9ADFBA95B9C5EFAF858 -:10900000928EC51BBF90EA97438A9398C7F20DBF13 -:109010003369A91E5B21FBDE08427C55F2BD5A4331 -:10902000DB4EE93D73A0FFD51ABF9EF9ED0218276C -:1090300015FDF7ED87F4A2BED31F667A3124F573D0 -:10904000323FAE373732DE5495C8F657EFC7B9977F -:1090500001DE85DE13F18433774FEA0FAAE16BE27C -:10906000EA0F714E490BB1A7DEE341BEC0E608BF6F -:10907000F21953F4B8C0DA04265FF7016FD1FFED9F -:1090800036D73A18F702DFFF5DE0F1AE0BB12CFEE8 -:10909000F5BF7ADE67E5A309CCDF7D81C7C72EC4A3 -:1090A00029F78DE2BDC778F97983D1B839029F8E4F -:1090B000C70DF53ECC93E27921EB09DB27EDB735FF -:1090C0006F8B8887362794EE837925E4B8F42900DE -:1090D000BFFD4C0F433C1AE2C64556CF76C04BADA0 -:1090E00083B820EE4A1C41FD4C883FC2BE13ED07F9 -:1090F000462F5D26568A79352754EE83EFBAEE0E59 -:10910000223E7BEA954C3E3627B871DCAE59A29DD3 -:10911000D71F0A72FC33FF81F067F7150F53C7BFE3 -:10912000A8E26076B689C93175DC7BBE90633CEEFF -:109130003D8FCBA1F9EDCC3FBEC048B60CA0ED0BE6 -:10914000DB93D87E31D69BAB887B7B63BE531E837B -:10915000A0CFAEF4404FBCF6898878ED1A1EEF5BC5 -:1091600023D6D7AA5CDF9B097DC66BDF4C8812AF84 -:1091700055E705BC0AFA7D60189E6BAD6CFD157253 -:109180004DB91EE4C45282F9E16BDF59D268A4F5EF -:10919000B50F82E70FFE98BDBA86C3ABAFF925B80D -:1091A00035C4A1F013F7238E887D718A274E51476D -:1091B0000B3822BF724075AAE2FBF4FA6CC5FB992A -:1091C0001B6E56B467790B15F59CADB72ADE1FD41C -:1091D00054A6A80FDE719BE2FD0292D31FE3B1C734 -:1091E00065F095909B7C3314EDB7ECB94BF1FD170E -:1091F000A4FEB131F4BD5613D303C4EB0A0CA57021 -:1092000059CAE79FD7B258F17DA3D432C24FDF5F6E -:109210001A60FEF6616DAB14FD5D8A9DC8F6113CC7 -:10922000FE584FFF6372DC21A33DD4269127A4DEB4 -:10923000F1C8EAF687B70C20BDED0AFA877A7E15E9 -:10924000D5F36047A9ED0C39D16247FD904A52AF82 -:1092500045F055980ECC6887753F25A33FAD800C2F -:109260007E7C0CC247477C8EDEF8EA26CCCFD3FD4D -:10927000A2C509FEB215EF2C41FA33242BE9C0E454 -:1092800050D241CC10251D589C4ABCF72F51E25DAD -:109290000D679B4B4907028E02CEF193957421E036 -:1092A0005B42FF03F81692D031CC9FF6494E3F89BE -:1092B00012EF6D6BC675DCC86ECB53C173F8515796 -:1092C000A319E1C4F2A9849D64E0FE69B5DF5CD80E -:1092D0001F6313B9DDC3FB117EEE2D9217ED9C9E2B -:1092E0007856893FC39F05F64E3D61FE127769624D -:1092F0004254BF1A3EEFCBAF26E028EC99D560CFA1 -:10930000D07196110FCAA5CFB93DB3C2FC28C605CE -:109310002FFD91C1B79AF8505E7FD77839D889244C -:10932000C2DFA886A3D42EF92DC0075C6EA7927663 -:1093300021B73D983741C9CE3842115F50DAA1C4F8 -:109340002545CA2761978AF1043C85DC12E3194858 -:10935000BD9C0C7CA092636488DA4E55FA3D849FD4 -:1093600004078B88638CEC894FB07D62D8EFC5FC15 -:109370001C7266562301FBDB2AFC1A81B9F05CF8EB -:1093800035D4FBFB1BC545677AA5E09359BDE3A126 -:1093900022BE4A97F9D9BFD38FC7488E74186FC6BB -:1093A000EB831388269A5FCE79FA00ED47D684E2E4 -:1093B00023FD65C27FFDB614C479FF88B8EE27117E -:1093C000F6422D699938370BFC9F546FC542C9FC92 -:1093D0003EA44D6D97B278A286AE04E87B358988AD -:1093E000176685DBB12EF7AE8B3C971BE97747926A -:1093F000559C5BC965ED4CBE89FD5B5FFB2511CFBC -:109400007F4B4F615218CE6B793191EF33F3493E68 -:10941000F44FF9AA2511F7E7940FA548BEEBC983CD -:10942000C1F65E7CA75ABF88E7CB9622F4BB2C8995 -:109430005CEFB78087B023BEA26B83725BA203CBC5 -:1094400035FDCE7CE482E6A24046A4BD5BA76779E9 -:10945000C1A445693F9F4CD47078B9E46F03A7BE9F -:10946000F1C0F3C2381EBEAD3D24F2C204FCFE289A -:10947000E46018DE671572AC67DFD603EFB3D1E4A2 -:109480009C80C7E5E2C0738027D9723211E0FC5797 -:109490008BFB33C04FFAE9E0794903FAAEE3B92711 -:1094A000417FB5C9B83FAA1DCBF2836AF763B09C70 -:1094B00074B61B301E58DD7604EDB28E062A4007C6 -:1094C000F60D9F9E75AAE0DCD73E45ACE3BF557410 -:1094D00026F244E8FAFEA6A0A7DEEBFF5B347A137F -:1094E000F94915F2D0FEC188FD483BDFF798B46E0C -:1094F0006D12FDAEE8C3B458804B85DC7E2C15E0C0 -:10950000B05EC2F347E30DC40B7EFE147E0EAD24A5 -:1095100058EFB4527824A799F13CD1E01FCB6E8864 -:10952000637EB27E5DDC125A7ED94087A6FB8DC178 -:1095300092C68D7446F69DFD6911C4D7E661DEF1D1 -:109540007C038BFB67FD24C69F43E5C39B7A6204C3 -:109550003ED365D7E3798B904DC67D865D2613801B -:10956000AE049CED316C1DE279E9D3BB25C86312D2 -:10957000CFC7378686AFA5E539C07771789DE3CB35 -:1095800043C3EBCD61388BFC40A20D65CC88E08BEA -:1095900037393C6A13F45B400F761AF9FE8FEF03FC -:1095A00089558BF2633D8FB39F194477A2D88FDF23 -:1095B00002F958B52657FF91E0E7823C025A7C6DCC -:1095C00075F5B7E1FA1D682FAFE7765527CFDB5E5B -:1095D0003FA52C09F6517DE53D952631FBBE86C79A -:1095E000BFC5F31AAD1FF3956A20DF3822DFE9BB50 -:1095F000E61B8BFCF13EE160D3122D8543AD44DCCC -:10960000D77BEFC0DFE4A8FBDCEA24CD75F3DF16DF -:10961000F2F589FCB65AC86FA38FD6EF2F4D2251B1 -:10962000FAEBD133576E55E49189FCE8DA2BE3303D -:109630008FACFC810E3CF707FD38CCE1FCB6BEE0F8 -:10964000FC66229B472DE4850D8F7CCEE446B87FD7 -:109650003BE2E1570040F073B4C9E88FFDD571CD0E -:10966000E45D51E6FB501283CFCD095AE48F5BFCD9 -:10967000C4D51C657CF19E38170270AECCEB3DBFA3 -:10968000D6B2E002983FE4AD461BAF2189EDAFC5ED -:10969000BC5BE382CB399DE3B98C9EBA5589C77F09 -:1096A000E572BFF5B660069E2F9A123D3F5EE07BE5 -:1096B00084B65E0278042D9E03686FCEA6956190F5 -:1096C000D7EFD7B0FC29C6677DE13D0C6F8D229F97 -:1096D000B037BCF58867D19FD88F5CDC2163BCFFB5 -:1096E000E209CE97C46596287F2DE2FAEA226171DD -:1096F000838B4D12EE43167B08D940E5CBA2DDAB40 -:10970000316EB3FCD9E15B404DC1F3FBA81C599409 -:109710004CC8385A2EDEAC8CDB2EDDDE2B4E4322BD -:10972000F522353B715FBDFC51E577D564FB7F8247 -:10973000DD53ADB26B06733FD7BE249ECF37828C0C -:1097400000F9BEF6D9AFF490B2DB17BD7F49F97AC4 -:10975000A016E4A015CBA349AEFD49141E1F26791F -:10976000DA416E777DC0E0D05DD3CDE4FE5376D490 -:10977000370610CEF49F86B92CFEFA001517107725 -:109780003318985D23EC39595E27C7D2F6517F5ABA -:109790001F07F8B3FF7AD264B0F7137E1DE3027897 -:1097A0006D2B7515C0FE7F5BA519F3188C0616F797 -:1097B000F5FD6AD46108030C6C79B80CF69FD6F6F7 -:1097C000437EF08F6CD5FC279E2BD93A8EE5B98964 -:1097D00071EADA2BF7C27C32EE647A635B96ABC037 -:1097E0001AD12FE1F6592D8759D7C1C13F1F4DF12D -:1097F000F8E471348FE9FAB2D10F773361F814F9D4 -:10980000543076A41DDA41F50F24E589FACD2D9266 -:109810005F47D7B3A6752FC62F6A36F913E7829E26 -:1098200079418BF11F313FFB9B296510E711FA65E8 -:10983000AE6445FD2FECEC3944FCB1385115A783DB -:1098400039DCBE9E1BC3E0BB983833E0BBBB8C2425 -:1098500016FCD373CB5B8A51FFACD6D940AF8B7863 -:1098600047DFF640743F51ED7316763E560AE542E7 -:10987000275FD27D0761FEA2A8E78D4CC99CCF72FD -:10988000B9BD3790B820BE56FBC6E066F00718FA9F -:10989000B1382C953BC69242B4778DB08F5979C0C0 -:1098A000E467FE6A1F3F07EB2A807C90BA1969853E -:1098B0009897709ACA0F0B9C2F0C66209F52B92262 -:1098C00051DD969D1C334D4BE9BB3695DA53B4EE12 -:1098D000DE91CCEAD9C1E51A5ADF905CC8EA3707B5 -:1098E000CF437D53F258562F0C2E9769FDE9E4A91A -:1098F000AC0E1B3B4A58BF4A9E31CD0BF6848DEB14 -:109900006B6710CF05D7BE3E5813E9A77C2C99C9C9 -:10991000A52FB9BFF5CB2CB27006C07B4810CF9DE8 -:1099200089F77E9A2CEC5B96DF2BD629BE23C9D112 -:10993000FB2FE0DFADE4E779C7C790AD2616A7F2AD -:10994000C652F81F6D1F8C71B6C4E438E68FB3D2CF -:109950007E8AC2FD08388AFEC4B8AB40AF82BCD54F -:10996000317FA9681F97CCE4381D67338E3394C1CB -:10997000BF76465A01E08DE24BCBF1A565FBCE6682 -:109980001C17FAB5E5A37C1F0EFEEEA357E9FB59A1 -:10999000E179ABE9632AA78F958D2CBE18B2E5203B -:1099A0001D8D8F61F61E2952AEE3690E87C7926D39 -:1099B0000C8E3DF84892709C460EC7340AF7BCEFF7 -:1099C000BEEEF93FD0BA23F0E592A1BDEDA65D91C0 -:1099D000EB11F9DAA29F2F37AABE2B617953B5712B -:1099E00039F8DD032662C4E76457CF7759F9CCCE46 -:1099F00004FB53DCD740BCE3D04950C3A546CFFDA0 -:109A00000B2D3C7F70A08B9D3F9E31AD88AFCFCAA0 -:109A1000D7673546DCBBD0C38F274319775A7AD333 -:109A20006F0FDC7BFA1B5AC8FB53F075B4FE803F06 -:109A3000FAC2C7CFFFDEF810F354C1B307CEAAF9BC -:109A40000978023FE3774395F428E6B92959E40BF6 -:109A5000ABF83AEB7B8E57CABE5B730FCF03762809 -:109A6000E9794D6B9606E2E7E2BBC9E0634F08FB7C -:109A7000DBF625F37D6B1A49EB23FFEDD5E4E87E99 -:109A80003A7CAEDEBF75D958DEB3DA6FD095E00C04 -:109A9000C0793EEF65763E7DB4CADE80F8CB3E737A -:109AA000F8BBB03E51D6E514C607BDFD40213C4F82 -:109AB0005B64287BD9E1A47B9DE4EA695A6A571468 -:109AC000F52F5B9745EBA79257A1BC2E1A50F65580 -:109AD0001695DF7F485ECDEAB7947D950DF51DABF9 -:109AE000D9FBE35D2F837C27DED5D326A484ED87C5 -:109AF000D3C90E849B5CAE21404706F96E27E84926 -:109B000001CFBECA2283A63E9A7D7AAE870E587CCC -:109B1000A284EBE712B13F0F6A15FBF3AE5876DE75 -:109B2000B80BF4295D6F47B2E77C32D829311D0BA1 -:109B3000B268579B62CEEAC11E925C5477819FC384 -:109B40006125F3209FAE639B1BEC23B2CA69D4222C -:109B50003CB9DF89AEED1AEDE7C01B2FDC3B800D71 -:109B6000E386798CE2FC5FF7C6377F81F868DD9782 -:109B70006627B8F546B5EF5C07F6D5A8F6DF7FC3D4 -:109B8000F42D3BA721E63D0AFC87F479499B01E7C8 -:109B90003FAAFDA665F0FEE80FDB73803EC69EF18E -:109BA000378238E83AF8DA00C5F90CF285F47DCE50 -:109BB00067F4C0E34FD478EA8FF030A624003CAEBF -:109BC000629E5467C2892D41B4D394E760A85D8E2C -:109BD000F1D56ED2CF097102718E5BEDAF3C5D495C -:109BE000D7479F8F0DD11944D8CBE3AFD0FD7D84EB -:109BF0009D5D4A6C8A7AB93145F17E85354BD13EFF -:109C000029F92645FB144781A23E75C828C5FBB734 -:109C10003B4B15F53B4AA628DEAF74552AEA05FEF4 -:109C200016C5FBC38FB729DB4F3A100FC3CFB8CB94 -:109C3000C18E77063C8D508EEC682AEFEF20BDFC7C -:109C4000B445415F233C1F7DB5BED84FA29C5F59F0 -:109C5000E541FF7EAFF32BA5EC7C7BA7869DDF1053 -:109C60007ED9AB319EB180A7B7250A760AEC71C6C2 -:109C7000503CE0AB62E143982FD51D22E8CF6AD576 -:109C8000077F361AF4FC7C19EDDE569E67D35A9591 -:109C9000E7035FDE6929F82AC4E9BDF3D9F980B189 -:109CA000D4C2C575434C53023C7914EB2E252B5579 -:109CB00078BA5B51AFB0DEA3787F52F24645FB1411 -:109CC000C7832A3C3DACA8DFEEDCA9C253B30A4FE0 -:109CD0002F28DAC77E1E6C04361ADFE1952D74FE3C -:109CE000B79E6E2A07BC8C3EE39D0FFC52E4F7340E -:109CF00082382C3E5A7F044A3FDD4F819FEA7043F1 -:109D00003296471B1CE8673AD63004CBE30D4E7CF5 -:109D1000FEBB86122CDF6D7061F96F0D93B10C34B0 -:109D2000B8B16C6968C1F7F735B4614921980EFA8A -:109D3000C21EDF73AF423AECE73B35C15A88A0AE92 -:109D4000DB7900E56467BF6027D43791D7A74D80E2 -:109D5000F35CB09902FB0A4A8ACFFB525D7F49A1AE -:109D6000F54D29AC2EF2125A34AE02B0AF1FD8799D -:109D700064BB369D90FB37BA93AD365637D23A2244 -:109D80001BFAF01ED9EE4A23E437A0326EC5FA342E -:109D9000A8779958FBA69D47A679513FB0F8F19D49 -:109DA000E1F8F10330AE3A7EFC9B0B0E0BF8534EFC -:109DB0005C1D6C81759DE0FE231729D02DA265A93D -:109DC000B640077AF1B4CA8E10659DA6B409FA6D43 -:109DD000D13867615EF06D3A0279E83324B61FED41 -:109DE000B10353991CEFBADD80FB9D931AD732CC97 -:109DF000779242CF00BCF6A49C44BDD265096500B1 -:109E00001C9E4BF990D51342CF48CE88BA8EADF345 -:109E10005F534EE03E22CA3A77A7448993BF90C26F -:109E2000E3067E573A9EEBE5F59395AE35A0274EB7 -:109E300096BA06C17C4EB80DC83F5EB7C507F99605 -:109E400044EB2A9E15E157C949D5E17777EA199F76 -:109E500091BBE4A8E7CD4B53999D857883FDDC9CAD -:109E600018B4C34F6AA29F179F93CAF4F5A57ED179 -:109E7000FD2B77F1F6B29916ECAF6BBD09E3B75D38 -:109E8000EEC1680775D5532851FEE8BA507FF91521 -:109E90006C3788D016C629E77239F59BF6757F3E78 -:109EA00045DF3FBB3EC68932DC7A33EAA7BBF8CB3D -:109EB000F3E38D68B7CC9F915E067A692E8F772D7C -:109EC000B0681331ECA5B5E9E18AA0A5E6822DA022 -:109ED000FE97DB2BF5365AAF4EBB7B0B94AB063EA1 -:109EE000AC87239A3543F76E01F3710D65AD62DCE3 -:109EF0002F05DF6BA0F35AB84176B0FD933877B8E1 -:109F0000FA3BE557083A3CC9F364287C715F38375F -:109F100095ED7BC4777339BD5D4CE1765B1EC9BBA3 -:109F2000A68CE35C063AE998FF5E6E1F7E77653B80 -:109F3000B7DB3ED2B371D5F7508871E771BC9FD4BF -:109F400013970476DC5D16A48FFCAAAF3615D3F503 -:109F5000E7B75B35188717723CC0EE032BFEDC8336 -:109F6000726E6447F0B95304E9BC0DF8E4467A6AAE -:109F7000A67723EA87515F53FD0372F1AAE7EC2924 -:109F80006CB5473D8FE96FA8E6F2B11EE5DAD186E0 -:109F90000D583FD6E0C5F278C3562E1F9BB0FDDDAD -:109FA000861D5C3EFAB87CDC83CFDB1BAAB07CA3A9 -:109FB000C183E55F2DEEB8D40420360FE667BEB549 -:109FC000D340E0DEB4EE7603D229E580679EB44349 -:109FD000FE8BC10AE7EED479306A79DB83FFD65E67 -:109FE000F76164A41647E4BD807D96D937FD9C20B7 -:109FF0000E0BC893114F24DD0EF2F984C36101BB2F -:10A0000075646A32ABBB1C161DAD973C41EB54BE68 -:10A010009CF0382C065A1F959AC2DABD0E8B89D651 -:10A020006F7D2285B5FB0806A9C73F91713BC89F8C -:10A0300052221D057E2837664D8094D90A6BE9515E -:10A04000E08349C98B26001FFC36C5817438C5B131 -:10A05000F128D4A70E69D6C2511B97B960337C573B -:10A0600066AFD4C27713D2EEDE0CDF4D1CF8B036EB -:10A07000F2BBC943F76E86FA3467B316ECC1DFA6AC -:10A08000B0F3FDA21F5117ED42BE8A3CAD61ED6EEB -:10A0900094E3F96D6E94E3022E657756DE0F7EBA77 -:10A0A000BA36C92AC13CEE947A82EF900B577B9561 -:10A0B000720B95B3D39FB8C9B291F2571DD46FC537 -:10A0C000FA431BA3CBDD99A951F4CB1F389F82DE45 -:10A0D000847CE83FE8D97D1E2FF3F5D5B52FB22C4F -:10A0E000427DE5B1807EDD9FC2F4E541AE1F2FF3D6 -:10A0F000B29B3FAFD3B8E6C3384B53FBE4EB6A687F -:10A10000A77CAB3A27D0473BE7EB55A95C3FF07BF8 -:10A1100013D610769EE846F95A2B23F76F5990977D -:10A12000D3720CF245D5F90F3570CE28A7771E30C3 -:10A13000958B2CEFB14D993FDAB3FFE8C7E41E1CB5 -:10A140005F844D4763DFEB7E2035E1BAEB56B6F313 -:10A1500075AF242CBF59BD0EE24940DE12F9CEBDC9 -:10A16000D7138CBE9E5EEBE0F7EEA9F2ACA91DF40E -:10A1700038CCA762A18580FF26524E9CBA8E9C5097 -:10A18000CB9DBF973CBB8EBC79319ABC11E79DD566 -:10A19000A5B0E7E09C14E4DBC17D2FE0A7FFA74456 -:10A1A000CF6BD04F5759E82F1AD89FD9834867767D -:10A1B0009BE775782EE959DC5DE4B15ED0787F0BC2 -:10A1C00076D1B12796A01CEA04E540F9F10D5A07B3 -:10A1D000B9536475FB017E6408A39FBEF233DFE6CA -:10A1E0007AB177C9F849E42976357F93817EAC1B33 -:10A1F000D07B5F70A890C704E13C4077490C9A3C43 -:10A200001D12F14B85906F9D88764447BA5E0BE531 -:10A21000DF7B9FD8919E8BFDABF78B1D29254636A2 -:10A22000EEC4C950B6E93D3B16C13E699401F749F9 -:10A23000EFF3FCBEE99F5EB583BE9A2EFB13F3A538 -:10A24000DEFBCC8E77E69539F27BEF37E9FA26C054 -:10A25000FA6EB4EF741B03710046F5FEB366C35F7C -:10A2600008E4458FDE7095C07D6437DE8F1219C417 -:10A2700044E169E711288B3F77611ACE880BF547D7 -:10A28000A01CF535DB9EDF289FE8D62B2D47D8F1A3 -:10A29000F0A1CAFB164A7ECFF6ABBCEC754FDB2AA9 -:10A2A000AF324FADD45F8C7914723016CACB5210D6 -:10A2B000FD5EB286DDC320EE5FA0FBD8C401C5B051 -:10A2C000EF65F952E321CF884EAEE2A71F2FB817F2 -:10A2D000F9DE84F64FCF3EF6150DE609B46A5DFD52 -:10A2E000C7C23E76C320E7465AFF8F40C22F0ED02A -:10A2F000B2CEFA1712797F5BCD866E45BD6363F8E7 -:10A300009E20C883AEF99B8C7AA78690AD80AF1A49 -:10A310007258BF36420F9296FFEC81FB302AE72A33 -:10A320000170B8AFD24C77D1F72AF97E83781B59E8 -:10A330009DEFB308F9EC7617EDB73281BF4F664F4A -:10A34000C77ABA68AF62F541A2BFD7D8FB29A2CEBF -:10A35000FBBB49D47FCEEA59E2FB16F67D9E18FF7F -:10A36000BDDBB1DDC2DE1F3F60FD74900342BE570E -:10A370000CE0F925FC7E1F2AEFA70C48B86E5E8919 -:10A38000B29DEB03719F4FC54FA7C4BC07FCDC22F5 -:10A3900061EE5BCD7D3AF46F5F8A6BC98F3C9F2C79 -:10A3A000F250DCE51617D87B6B5E1DBC4BE6F93826 -:10A3B000606F6CE3F1E50AD98CF188EEED4CCEF7D5 -:10A3C00065AF2DDFF0BA029FBDDAF93DCA18A8A328 -:10A3D000E35D7E2809F3DBC9C000C6C3570C90C4F7 -:10A3E000F92A3CDF2AF2BDEC39C405FB53FB6B268E -:10A3F000764FE5E70194BFCB5F63FEDE353B8FA070 -:10A400009E5B2C3B908E0F6779D600DD765AD87D07 -:10A4100084CB37BC81FCBA2193DB09D6D050053CF4 -:10A420007BC3FF9E1BC0FF9E7F24FCD57E66713ED2 -:10A430007AD577CC4BEBB4B038A893E3E9538D636E -:10A440000487D723B09ECBCB02B9361992860389F5 -:10A450002CEFE8DD62D80775D75BF09EA379EB3E61 -:10A46000C98F3C97224AB5FD7F0EF8A8380CAFE69D -:10A47000DEF07D16F0731DF82ADB7F60F826698315 -:10A480007A27C44D4FB37BC746043ED547E6BBBCD5 -:10A490003580E9DDFEFC1E6A75DED65B032C0C4FB1 -:10A4A0003C1EB366C6BB63201E23F8617C0C6901A9 -:10A4B000FF3AA56B27A76B27D0B5A0DF705C867E1F -:10A4C0001785BFC2F44B147969EF0E50DE0B46E1DD -:10A4D00016B801DD06FE9174DB4AED5F8C63BE6247 -:10A4E00042FF891ACE5F71B80A786BD3AE0F676DE1 -:10A4F000DA0F03676D9A43E17F10F0EE4B3FA9F14D -:10A5000023E61D854F8BBF0F9F36A67339A50D62BD -:10A510009EA81AEF3169BDF0DE3FEDFA7857B6FF1D -:10A52000C07857C34D5DD6F0F8A6FA795E9A88FFD9 -:10A53000FE3070FCFFCD7F3EBFFE90A27DE18677AE -:10A5400014ED8BBC1F28EA638281722073E10F1F18 -:10A55000772184F6E5F7F5ABF7E54F9FFEF20A0D9C -:10A56000C4DB4A02CC9FFF65BA67531A85F3FB1A16 -:10A570005FA385C275E49916766F57752EE60FAD09 -:10A58000E373FC6ACC7F9DBD97D2CD57C480FE4E4D -:10A59000FFA19BB48EBCDE74507A45435C11796890 -:10A5A000A5469BD685FE1AE28A46370F70BAC1FCD3 -:10A5B0001FCAEF5546A2B3533EAFAA9230DFA98A15 -:10A5C000B07C685AFA3DB47DBA96F8E1DEE34AB34E -:10A5D000D66FC0389FF23CB381DF8B4CECF18A73AD -:10A5E000CDB24BC6BCB459252C3E7897B905CF9354 -:10A5F000CE39BEE9F2BDB49D6CF616B37C6B71FE2C -:10A60000EC8F9AEF12F77B208DF17997C4E3C89213 -:10A610000EEFC7527F37378DF1D97479A30CF92E1D -:10A62000A10F08DADD82EFE8FA8E1B0AD9F90AF8E1 -:10A630005D8A4AA2F30FC6F3CE0F97C3FB35271DE1 -:10A640000897BA928DF980C7BA09D239437E785FEC -:10A6500053B7E16BECA7427EB111DEEF3ECD5CE17A -:10A66000233BE83EC511E9AF0C2E00BEBCD1FE472E -:10A67000CCFB4C831FE9E96CC3712CDF1FF7FB6235 -:10A68000B033820D81A87EC9EFEB1F107E01E12758 -:10A69000107240DCCBB7378DCB05A33400EF53D31A -:10A6A000B252C8CBD7D27AD92B076E205F0FFC23CA -:10A6B000E5EBB7A5F39A64A617D5F4ADA66B41CF29 -:10A6C000709F37FC1EC15DD4DE03BD3A9778F36AF4 -:10A6D000A89CAD5AD1A41B2D7D7FBA5E65FE3C833C -:10A6E000443967F2DDE5B983E54796CBB83F10F909 -:10A6F00009020F9DBDF1D69D767D3B53D9FE0FB764 -:10A70000E33F5FF0FDF41A51D80396F45EEBB6A573 -:10A710005F7FDDCAF61F78DD11E75F16C89AF07912 -:10A720000FC81F063BAECBC7CE33566735E13DF2AF -:10A73000A424140B76E3CA8332D221D1BAB42911EE -:10A74000F74D7510FF47408F2BC6ACC07370BDEE40 -:10A750008932B7E2B938F57D51225FB896F7A3BECA -:10A7600037AA96E709D7AAF27646A4F3FCE042524C -:10A77000C8F22B9476A9BAEC6C200ABF64E7D50620 -:10A78000F4038C4B6FF999372D8C8709E9BDECB830 -:10A79000C937C0DBE47F24DED4F42A5B76E379A8F2 -:10A7A000EF4AAF57335DF3D313C272781EE47015CE -:10A7B000C13DEE061FDCF72FEEC7EE92D87D345D6B -:10A7C000E708FA8D6E74BFF2A8931E3CCF39F25D94 -:10A7D00097CCF20858BE81B05384DD32BA2324B33B -:10A7E000FBEDF939289E17F46DE5973360453B473B -:10A7F000F8DFFE5E7E6BA1E70E1A995C13FEC1A224 -:10A80000A01BEDB84E9DBF18EEB3F7EE3745B5036C -:10A810007E96AEB9EE3DAE7FB5787E06F43293CB30 -:10A8200077719F6B85CCEE7BEE0EC8E8BF5BFFCFE8 -:10A830001FFEF649C78DF7F575D6EEA8FB2251D657 -:10A8400069D87989C27207E6EDC17E09FC77C29F9B -:10A85000A77EFFF5CC321FCCAF421E83F76B76EF9D -:10A8600060F3E90B2F751B42387E9FED7CFCBA83A9 -:10A87000C5D6C8FB30CEA5F7ECCFACE78D61BC7E6A -:10A880005BFC8F0D5529EC9BFFD7F70DD3656A3A1A -:10A8900052FD9827F9987D4A989D3A8F04B05C4004 -:10A8A00042587A08CBA75F4C9C582E256E2CA76582 -:10A8B0007A4EA5637E4B2811F3215FFDEB50A09BE0 -:10A8C000CBE3463741EEDC0F65A775153870FCAE5B -:10A8D00057FE9A01792D37E2FFF858D70598A73A25 -:10A8E000AEF16FA532C64F88712DCAFB4A7E4B026E -:10A8F00099C0E262DB12B390DFC2F22FA959C83FC0 -:10A9000088B7E69DD3B0FC909512DEE7DA16D42026 -:10A910006BE52DCBF2C1FD3C6DADAC3D6F8DCD2710 -:10A92000D17ADE28136BBFDBE683730FF34910F98E -:10A9300071219C7A90E11C0C936FE2FE736AB167FF -:10A94000839DB5ACDDC8F2F7497020C8F1FC3EF636 -:10A95000371332189F0FCB66727B5899D20FD18F65 -:10A96000B7AFCC2C5B960171D90C574C065DDFB0AC -:10A97000B8C0B6478AD02F8FBFB3F2C5A87B307E50 -:10A9800028BE6BCA2CB3C27B2F492CDFDC7B90FF27 -:10A990006E01092546DE273A2DB33C11DE4BCF2050 -:10A9A000DC6E8E0E57F83D3A7794FD9CC8671C0606 -:10A9B0007B2AF48FB37BA95E92583DFF19EB1D9B58 -:10A9C00087A20FDF0B766D53A66730AC63989E109D -:10A9D00033CCFF69836F17DA9FF519E08F5CF18C38 -:10A9E000410376C1C754ADC2B9927F6F3062F90995 -:10A9F000DDE742F91F749F0BE539BACF85F233BA10 -:10AA0000CF8572D91527251A42DEC970B9603D225B -:10AA1000DEA69EEF28016F31FE413D8EBF32D3830B -:10AA2000F0EDC1F77EE28378C84BB6506ADC75E87A -:10AA3000AD6F39E3E5FBBDE8F959C332D8BE36BF87 -:10AA4000558B7A3CBF2D18BB3CE2BDE9197A6CCF1F -:10AA50007BE5733C27DA69ED81AF4BA24B9EAE617B -:10AA6000F5E9CFE4227C5766BA96C1BA297FCF8038 -:10AA700075E4B77DF82F709E87F68F79045D52E8F4 -:10AA800031B4F355EB50C341ACEB255B601B7CFF4D -:10AA9000D22BD9B0122A6F08E31BA02329DA7A3708 -:10AAA000E27CEF30848AE09CCA1DD7E4A879C32BEE -:10AAB000334B11CE12D05B42049C38BEBE2F5FF7E1 -:10AAC000C4B3399D1271BF06C84E07E8A1ABB1608F -:10AAD000D755F2787D5BEBC0F7617DDEE33219E498 -:10AAE00040FA55F0DD0E8E1F51E61DD4BB014F2FED -:10AAF0001D3C3F10EE5FA5781908F7B16ECD18A484 -:10AB0000F02FE68DFAE68947ECF83EFCB21A95CFB5 -:10AB1000CD15904F32D778E82D58D27CEBB90AC8C2 -:10AB20002759982C1D837291236B22E491887CF71E -:10AB300025434A8F012B4D7356A23D560AC225422A -:10AB40001F941B63F865D042FFC42BEA9392072839 -:10AB5000DE9FE2C851B44F1D728BA25D8C3BCD3994 -:10AB60005CF1DEB0B85036ECBFE83AD8FDD7CFCABA -:10AB7000987797F7CAC9DB6EA1F5E9CFCDC2FBFE86 -:10AB80005EE2EDD3F795E3EF0B765178EAA92175F4 -:10AB9000A1E4C1C71E81CE54F67DCDC15F1E7339BD -:10ABA000AE63DFDFC0AE17F27575BBB118E4EBB76B -:10ABB000B5F3D578792583DF1FC2EDFEBEE8A58702 -:10ABC0001F2407A3177EDF969A5E20B394D11F2B14 -:10ABD000A79F60E7C0BEAB1CFB13C8B18873983D4C -:10ABE000A5CADF364CEF7C7F1DF8DFDF93099EABF3 -:10ABF000E3E7F396C3BFE5309D93A5CDF7C37D5240 -:10AC0000F4B917EC4F3807EAA2FD5FCEE07653CDDA -:10AC1000A1FB538AC2ED64FD39C5FBE43E698BA2FA -:10AC2000BE394B59DF5EBA25F2FBBEE4E1F21D8B63 -:10AC3000F41E3CBF2945FD3D57319F8AC326CCCF2A -:10AC4000BB1DF24EE8A3DAA20FB4106FBDBD0FFD1D -:10AC500029E4CE1C99D4476BBF92C1E28ED30E9BE0 -:10AC6000309FE5BBF6FB318525E60BBEC6F4E7C792 -:10AC7000FD03DA48BCCB99ACFFCBC50FFFF35F20D7 -:10AC8000EEB99F60FEE6651B93FBF9AD5F6834B4D7 -:10AC90001CD68FD14BBE35A8017DD2551DE385FC56 -:10ACA000FCBA9516CCEB1C961DFAC85840484CE6E9 -:10ACB000B69F1B29BDFD110E3346E8D32ED8E3D035 -:10ACC000BAFD5F1FBC6333FDF7D4C326BFE67BAC80 -:10ACD000C74E6D28D47F658CBF1700DD70BD02BEE6 -:10ACE000F3BAFB498F9E017900EB87FA6D990FBD8E -:10ACF000FF289D77DD3B8CBF21534EBD6F9F1BB15D -:10AD00006F274F31BE34D2FFC09E5B75B4490FFB35 -:10AD1000B91BF3770BE6CD7C5BBECECFBC211F9F6A -:10AD2000984AF152B79FDD33D1DD3E08CFB5F6A585 -:10AD3000BFEB766890FF44BDB35D9E0CF4AA3E273E -:10AD40002EE049ACB98A7B9CD68EFDAF19A027D7DF -:10AD50001ED4B2648FBEC6D9AA218E88715E7AC312 -:10AD600050CD7EA792CDBF4BE8E7837F8E2B1DCAC7 -:10AD7000CA8D51F41CD5CB3A3BE8E54AF67B0BA7CC -:10AD80000E269501FC4F49C4EFC073572CCF78268F -:10AD9000EB0E9E9BF1FE90E421DAC87B0EC53E725D -:10ADA000D6C15983C08EFCA875F1298A19B22833FF -:10ADB00007E96536F1A2DD7BCAE64E077FC3741E44 -:10ADC000EF3F650B75803C3E35364682F83DED7FA2 -:10ADD0003389B8AFEF94CE9DCEEE831079C5377F1F -:10ADE000AF7BDB2AE4FB4AA742BC7A1EB1C23EF22B -:10ADF0000E99D9B5E44DC69742DED549813898E71A -:10AE0000B4CC19EB3221FEBBE167B8AFEC819B9665 -:10AE1000FFDED3B7B46B7BF6AF7B24764F8993D933 -:10AE2000FBB5632EFD62369C73A3FB6C89CE677104 -:10AE3000DB21BC8747BDAFEED9DFFC0FFDA3BDF71B -:10AE400047EE87607DC2EFADDE27F5D8E5C2BE7B59 -:10AE500096E5B91F19FB78E76A5A5FFF6C0CC2F1DF -:10AE6000E233062FC8EF8BBB0CB8DFB918173AB323 -:10AE70000EEAFBF29C5E1C2D17CF7709FA5EA171DA -:10AE8000FC01F40EF99D0EEFDDF8E26903FEBEC78A -:10AE9000CA5FDEB40BF64F5FA43B7EFD22F8F77E5F -:10AEA0009D80F7019064F6FDED9C1F81BF1C141F6F -:10AEB000F2F316B41B56BE9C82F24BE0EFC2D326CF -:10AEC0003C077FF1F8CCFEE007EBD0EC65BF3329FF -:10AED0009BBD208757EF32A1DD47F49E9760FDE5CB -:10AEE000CFDF3E7B388CFF610281F574B5BF8CFEED -:10AEF000C7307EA3EBF5EEF61C26077AF42CCB9B2D -:10AF00005D18BEA7F915E87F0D11F720B2BCD94234 -:10AF10005962BF3BF950F473E0C73299BD5823FC26 -:10AF200025F1C4980C7CE821ECDEC78706E33DBB25 -:10AF30006733F9F96512E2E71D05BD9DA93D80FE65 -:10AF40001203CBD7EBE35ECB1399367C7FB9F16B61 -:10AF500085DFA476C315657D28FB1DE6C246C7F0D4 -:10AF6000BB69B98EC3F9BF92DCA7607DAB5A1E7E68 -:10AF7000F55D84CB533FF9238C7BDC8C7E1AF22E5B -:10AF8000839F7AFFB2DC18E271876685DD7B7EE7FE -:10AF90001F307FE4FC2BB7E0EF942D9603E7E17EB2 -:10AFA000AC4E4BE0ECBDB4DC77FC04E2453DDF5E2B -:10AFB000717889C9951A58C770C85F715FCA44BE55 -:10AFC00065FCFEE9B63C849FF0D3765D8CBEBF1273 -:10AFD000F314FD8BF989FEC57BDF707C5DD607F22B -:10AFE000412FFB200E11B1AECBB1817CF8295C5F03 -:10AFF0003ACBE7BE1C47EB117473A378CDFF055C19 -:10B00000F134E600800000001F8B08000000000003 -:10B01000000BAD580F6C13E7157F77679F1D623BE0 -:10B020008684FC217F383B10D2262447FE786902B3 -:10B03000E39A908822B69AC0B48CC138DA42293497 -:10B040008D97C086E8242EF5C43F819A69DD46A716 -:10B05000D2192618D2404D3340AC02E68256C8863B -:10B060005A77651ADD2274CB5A16AD2149195B85D2 -:10B07000D42D7BEFBB3B9C73025BABD98A5FBEFBDD -:10B08000BEEF7DEFFDDEDFEFDA00E26A15C0B3B997 -:10B090006F80A31AE8137667037C05CC4F56A6038E -:10B0A0004200ABE87F099FD7FDF62EE703580DBDA0 -:10B0B0004E2806B8CE776F130580E1DEEF3B550FC3 -:10B0C0002D5AE2BF590AC0697FE4C7CB00C6E9B375 -:10B0D0007832057000ADA3CFB840BF1AC04CFC6DEC -:10B0E00084D208F2B9E5F7687C25C02C8973DC743A -:10B0F000E3742114D23A9C97E33548FB5C7214E563 -:10B10000D9C6878B24DCF7AC18AF0021B96F1BAF11 -:10B11000B2E7C3DCD58D10A4E3E215612FC0E8745B -:10B1200011B80CA433E58492857CFE01F251E4331E -:10B13000EA84B63E3CB7A6898FF4313D1C833ACAF7 -:10B14000C703C7E4AB29C3E7E5008BE8B9DB943B51 -:10B1500080CF2BEDEB93FAD8C767249EE95793C9AC -:10B16000477ACB27E3F1B8391F85B840B8E2679535 -:10B170001B716F307107500440BB3C678E9F737B1F -:10B18000E24205CAED736B02EAD3700EED82E3066C -:10B1900047FC4DA29C02B07D06AE3DEB1CBE2707CE -:10B1A000E1905BE6203EF5A67939E4B506D7EDE2FD -:10B1B0002240E7BAA187D17D5C82C9F1451863546A -:10B1C00001BF8328C2CFE8120833DA021146974242 -:10B1D0000FA3CBA097D1E59060141E8E4721402786 -:10B1E0007DC77F331DC9634FF3E3486BBE0A915E91 -:10B1F000CF641CBE4938D43E08078D237FFCAC3891 -:10B20000B4809ACBF8A5E25150CAFC3B150F17F950 -:10B2100023DA2D0D62B94417812E105D4C8E8B7C84 -:10B220001E05C941E32650D8B8F97FC4A14E571D69 -:10B230006AF91478344DED173B4CBF1827DD6726AB -:10B24000ED745292D8D8B217A09CE1F993ED683D05 -:10B25000AF496FFCBBE407F841AC31ECC8C3717572 -:10B260006357318E8F49ADC6B8A1F117411C1F8FAE -:10B27000AD0C3B1E21BF6EAC76CA00DDDDABC24B10 -:10B28000705E4DF35500C615B495F0E43F5BFD06C6 -:10B29000FE6AF736D98F71A4167A64D2CFED42CC0C -:10B2A000103FA158803AA4454BE3179DB86E89A87A -:10B2B000F6503CB6BBE33E0971DFDADD9C03A8EF34 -:10B2C0006ED158EFC27DEEAAA45EF85C4BC3715FED -:10B2D0005F591717BCFFF9C8F790544B72CCD58053 -:10B2E000E438CDC986251B73DA304F0C279CB04F4C -:10B2F0004A9EF3A31CF508C901EE1220BBE7BB0D63 -:10B300003EC37D65656497930412CD6705AA09B7AE -:10B310000F73C22769FDA8D7F0AF936487DAFBD318 -:10B32000DF4BCACF697DEAF3D10F5100DC7F415278 -:10B330005F27793BD23F2DA1BC34B2E0BD5D7A20BE -:10B34000E9A71C9EBF06F58E2A1013591E59E8BFA7 -:10B35000897914D006E368CFD10DC80771A809AB6D -:10B3600051273EFEC29AB1102629E27B8ECEED1007 -:10B37000F5A205B8EFA5953744C3CF0A0C3F33F3C8 -:10B38000D0F90BFDCFE71BC3304C88AB8E0B77FF9A -:10B39000F927C4AFE3B647A6E5C9787AB90B7CB400 -:10B3A000C863CB1B569CD59F75C5051F8D1FDA4002 -:10B3B000EB16BD37504C7A2D1ED0A35EE273FE0F04 -:10B3C000F9861C665D503EE13E4F5D6816283903E4 -:10B3D000749E16622EC4AB938B5CF2D2F824276B5A -:10B3E00028FF5FDDE81F19B45EF1E4A15E9B4CBD50 -:10B3F000DAFB8FEEF222DDF4CA93CBA182C2C1C97F -:10B40000F2B7845F8AFF2DC79DC97CCE7ED110A87C -:10B410006707589FB8487ED0DE6B5FD701FB3FA619 -:10B42000BCD33131CFA35CC392378BD9CBAC57405F -:10B430002504F93D6DEE253D3C24F77931E6E29097 -:10B440001EEA92FD3436E3074EBCC0FCD25A0FAF61 -:10B450006432DB5BF1F4CC1E943D338957E53197C0 -:10B4600042B8571ECB5148BF4A11D68519DE31E686 -:10B470007795E81B1CFAD36BD3C7823C9EF3DAF9AD -:10B4800052193328BCB15381BFCC49CAD769C653BE -:10B49000B370A249443FB8FD14F83124A1B3FFA70B -:10B4A00051378E3BF702AD80DBF4837C6E0FF131B8 -:10B4B000E253DF5F9D4BF63E65C6A72B97076902F7 -:10B4C0004E69D234904A93630B5F97699FF4D21907 -:10B4D000B679AF3CCBB63FA32E68DFAF2989F21017 -:10B4E000E56363FF74E561DBFADDBE962BE4978BC1 -:10B4F000121B97132E994BAB6CF32170B3FEA1B6C0 -:10B50000C023C7703FDC31EA791D7E593D808840F9 -:10B51000FA35E8003F467BD40F3B6C764FD3D11F02 -:10B52000715DDAB50976C73F97641FCF0F987E50DB -:10B53000000513FD2089B3E71E8ECC0FFA7111E1CF -:10B54000EC1563D8724CC22904733268BEF68A00C7 -:10B5500031867B971CC7E733C376BC73DAEC78E798 -:10B56000A9767CF337D9F12D8CD8F19DBDDD8E679E -:10B5700040B3E357BCA7DEB67E6E4FA36D3CEFE051 -:10B5800032DBFA8762ADB671D9F1D5B6F5F37B9FA0 -:10B59000B0CD579EDD6C9BB7FC2AD5EE0BE29DB675 -:10B5A00075A976AFBEB2C3C6D7B2B386DFFFA79D7B -:10B5B00037A7D8F95B281BC5DDDBBEA1FD14865F6C -:10B5C0004E37F252B3B030A190BD173A65B2E93BA5 -:10B5D00052669397E2DDAC4361B30E417817B37BBB -:10B5E000D8F41339215FA23C5A753DDCE4C3718D58 -:10B5F0001EB944E93834D4D39421313791FCB89E34 -:10B60000337179BC8E03872D5E709C9DC46DA5D669 -:10B610002D64E0E2864F6351962EC9A9F0FC567363 -:10B620009EAB33F2FA0A250D1C13F058643E072A2C -:10B63000DAC86FA131052BCDFB00F6E520525FCEB5 -:10B64000BB63D1C054FDA47C50607D92CAFAA6CBE6 -:10B650009CEA24BACA9D28A2FA75285B7D298079C4 -:10B660007E849725D667717A94941A25C558D17926 -:10B6700027AC9453FF8EFFCEC2BCCB5F0D6B1E2652 -:10B68000BE5F47F955539EC301F55000F11FE4FC1E -:10B69000BBAA71EFDBF51F1551FD71098804E6C1E6 -:10B6A0004C9FF2133A47DBBD703AB35B0EEA8779E1 -:10B6B00054E725D63F683B38761FF888983D3221FD -:10B6C0004EF73859DD01F37EB4D6C4CBBA1FAD3185 -:10B6D000CF1F44169B304FAF3D7B99E1B2257718C1 -:10B6E0001C99CCDF589FF46481A76A1FE9A454CB4E -:10B6F000ADF3E9B9755FCA173E4B5D6C16CA33F4FA -:10B7000029FA458B6EC91D62F7B97BFB4F1875E4AA -:10B71000FEFC355667937A1BFC07F7A6B3FA32B8DE -:10B72000B7B0916892FF08E3BF36F2AECD4FD66D49 -:10B730007FDFE67FEBB53FDBE6F5AC31673EEAAF96 -:10B740009FC96BF93AE277EBB42B44F746B4DB358B -:10B75000B28BC55F3F306F099DF7DFF5FC1BC377E8 -:10B760006067021C73927ADED8799D8DF59D3AA3AD -:10B77000A97A5AF74C8B8A17A1D481F619E3A6C986 -:10B78000470293CFD91C34FAF08147B31BA9CE0EE0 -:10B79000148A0E839618E3BC3AB7316E594A74D4B2 -:10B7A000E9D943F7CC010E140EFD610DA7BCBA1EFA -:10B7B000F97E3B5BFD98FCB363F3588503E3A1A3DB -:10B7C00052FF0647A97FBA7A87F4E7B0BDCB9BC189 -:10B7D000E42CA1BE6388D72A38CC0515C19C15D4AA -:10B7E000970F4DD346A812971C99618C45233E4272 -:10B7F000C17FB178A8F1ABFF263E1F70429CFC567A -:10B80000FB25173BCAFC4D175BBD2C9EDAE8DE45D5 -:10B81000F75DBA6F8CA619D419E4987E620AA55E0A -:10B820009D682868E4B566617F0947FDC1411750EE -:10B830003CE0390AF515DA7957EC288EB35176EAEF -:10B84000537E2D1AFD7CD5AF5C71CA1B1BDD77982A -:10B850009DF28201C62FAB183317F2C97AD1158B2E -:10B86000927C7AA26805CAD7E3C4FE85E2FA1ACEB2 -:10B8700023DF5B07E61DD937C11E7941E37E084F00 -:10B880000118F3398769BEBD7FF006E5918B01B5DC -:10B890003088FC0779294479A4DDF7A648F9A73256 -:10B8A00028B17D282FD317F3C1773986B3DBFF0189 -:10B8B000FAEB3A4C3619747FE3D5B9C15ABAA7E806 -:10B8C00022F1438F60FDDFFDF4BFB521F1C372A407 -:10B8D000235EB988CEB1CE45392A898FA5B72547D1 -:10B8E00092CF83FD7AA37BCC16BF375FDE5D4271BA -:10B8F0005225700C9FD4F52D262E034EA3FF4B9D91 -:10B900005F4FF6AC9DC23EF3007291BAA661AD43A3 -:10B91000BA927042FC6E7D0DF5617D8BB280ECDBDE -:10B92000DEEA91296F59FC918FFAFA03CEF92427A8 -:10B93000FC25B2C3E6C8F7CE5C9592F3E87FCCAEA7 -:10B94000DA01C35FDA2FBC7FE3793CE5999FCDAF85 -:10B95000A63C6DED4FC579C42BB1F73B4F087186FE -:10B9600023E2BB9AF8F75DF95D36E162E1FC79719B -:10B970001D2D4C88C47FF4F0DD2209F7B79FBB7CF6 -:10B980009DFCB6DD7CBF00A7ECEF0D102F8DEE9374 -:10B99000F7EA08E5D6D96C9A9BD8B7B9ACFD050E85 -:10B9A000FB7E6CD0793CEF94796F394BF9628AFB5E -:10B9B000EDA904CF4AF4A95CEC0BA9FE60BDA77AFF -:10B9C00063D5FBADEFF22C0EB60680CD935C6457C9 -:10B9D0004E7F8BD51FEBFD4594C3BA8AB8758AEAB2 -:10B9E0000BE497A076B17A24CC46BBE2BEBEDF2C36 -:10B9F00033EF69467DAB35EB592DF121F9CB335847 -:10BA00009DAB31CF0DB9B17F0A52A9D0CCF734E646 -:10BA1000FB8CBD6FD9EE77FF01E91E35E2601400A3 -:10BA200000000000000000001F8B08000000000064 -:10BA3000000BFB51CFC0F0038AD5151818D6293159 -:10BA400030DC5266607055616038278F90A31556C0 -:10BA5000E5A04CFF0B4606865740FC0688DF319276 -:10BA6000AE5F4B18C15EC9CBC0A00DE4D7006955CD -:10BA70000106062E205B0788F701F9F780F81510FC -:10BA8000BB08313070F331309802B11810EB02E589 -:10BA90007D81F4373EECE6EB09E3B7FFB9002A5F9E -:10BAA000521095CF20805F7F97207E796921D2C385 -:10BAB000C44E9DFCF868A240EF40E09B0CA87C0BB4 -:10BAC0005906062F3906861E7908FF1A92FC3CA0FB -:10BAD00098A52C345CC5816907C8BFCC80DD5C1992 -:10BAE000A0BC36507E15D41C00DF43986568030067 -:10BAF00000000000000000001F8B08000000000094 -:10BB0000000BE57D097C54D5D5F87DF3DE9B2DB384 -:10BB1000852C842D4C58141070085B1094C9860134 -:10BB2000020C8B881675588410208980FD51B51F32 -:10BB3000139688967E0DA2965AB0030D82FDB00D25 -:10BB4000183560A0C366B1451B5C10BB7C1D16D9BF -:10BB50000C2404A5A3C5FADD73EE7D99F75E664853 -:10BB6000B4FEBF7F7FFF7F102FF7DDFDDCB3DD73F9 -:10BB7000CEBD910D76424613F235FCD07499400843 -:10BB80004989A6F4E79F5FA71232C94CFF2512929C -:10BB90002FDA081942C8441B099A689D89A3E8C78F -:10BBA0006442DEAD128222B4A1F502C3082926EC5C -:10BBB0006792446A85DB0969CE7AB562909B10C1B1 -:10BBC000EB25CB3369EA769199908E3AF085E020A7 -:10BBD000C4996520A40F6BF335FD9BE8B5625F4AFD -:10BBE0003EA9A083269FE2EBACA9DF71460F4D79F9 -:10BBF000277F3F4D7997A24C4DBE5BD91D9AFADD48 -:10BC000097E768F21981719AFA3DD74ED1E47B57D4 -:10BC1000DEAFA97FEBC6D99AF2BEC1624DF96D3B8A -:10BC20009668F203AA1FD3D4BFBD76A5A67C50E8C0 -:10BC3000694DF9E0A3CF68F243EB5FD0D41F7E7269 -:10BC4000ABA67C44F8579AF29117766BF27736EDF3 -:10BC5000D5D41F1D39A8C967933F68EAE79ADFD793 -:10BC6000E4F35D7FD6D4BF3BED8CA67CACFB534D9B -:10BC7000B98207E3FB5CD37C9FE0F987A69D447CF7 -:10BC800014D884184919A6665289A99554636A2361 -:10BC9000F5989E49F7DF8FF8F962A08250BC5B15DA -:10BCA00068FAEF249ABE9BD5D3E9EF0FBD7909A1BD -:10BCB000783B91754D269A6D2191E299C94C0216F7 -:10BCC0008A0A8E08C5B7248A771182A92B42F16DA2 -:10BCD00030C5BB8819D30E910EF83D29E2C2343924 -:10BCE000D219BFA744D2304D8DF4C0B463C48D695E -:10BCF0005AA41FA69D227D30ED1CC9C4765D221E6C -:10BD00004CBB46EEC0EFDD225998A64772F07BF798 -:10BD100088175377641CA61991024C7B44A660BD1A -:10BD20009E111FA6BD22F7E3F7DE911998DE129946 -:10BD30008DE9AD113FA67D22C598F68D1461DA2FED -:10BD4000B204DBDD1629C3B47FE431FC3E20B21C13 -:10BD5000D381919598DE1E0960EA893C8DF50645F0 -:10BD6000D6629A197906BF0F8E54623A24F2027E87 -:10BD70001F1AD988E9B0C8564C8747829866457E15 -:10BD800085E988C80E4CEF88ECC6762323D5988EBB -:10BD90008AECC5EF77466A31BD0BF02D09F02E8491 -:10BDA000A937F27BFC9E1D398A694EE43DFC9E1B3F -:10BDB000A9C7342FF227FC9E1F3989E998C8694C1E -:10BDC000EF8E84312D885CC2746CE402A6E322CD30 -:10BDD000D86E7CA409D3C2C897F87D422482A9C238 -:10BDE000EF4896DC1056F0AF07FC7FA6EBDC6D94B5 -:10BDF0002F11BFE16B9A121BC58311D1FAFA94720D -:10BE00003BE49332C5AB048ADF899417023F9C5808 -:10BE10002604EFCEA0F8911C3E0C7939CBE436D144 -:10BE2000FC03A44906FC25A4DEEE1B40C88111E7F3 -:10BE3000BB8629BEBE9B12EA46911B7E90DFCA30AC -:10BE4000A79EC06F1BA430FD3E31F9608ADF06ED6E -:10BE5000296D64027AD3F101BF293A025F7E402244 -:10BE600001079DEA71E86104D60B99687E6621F1AD -:10BE700066D2FA15234C3382749C8A4C5F918FA64C -:10BE80003FCEF0CD80F4F7403C74FE87787A9C1862 -:10BE900030FD32DD85E9CC477A337ACAA340ECD451 -:10BEA000361C1E4865ED88AD291DD6D7DE7612A159 -:10BEB000ED8646EBBF4C7C1FC2F7400EE953668B04 -:10BEC000D6A3DF4F42BD18DFFF1CEB7BAD813202F2 -:10BED0000AFF400763701BC827E2764E867999DD1A -:10BEE000CE29F6F8F37A7285ABBFD44B3DCF20CE86 -:10BEF000EF4981CCA866FC256DCA00EC1FE561C046 -:10BF00006AC1FE450E7FA5DD67004FDAEE3D8BAFBF -:10BF100091C9537757848BCDD52EB8D076D7112EB3 -:10BF2000126D676F7FBBF869258333F1BA711EFC10 -:10BF30007BA9890404BA8EA66DF6E0D60CC06137E1 -:10BF4000F2CF221767A0C9141854AE1725C21208E1 -:10BF500039BC3F2164A0F573B6D9B7821ED09813BF -:10BF600078DE0770DE2A936DB4CACAFD3F3AF173DA -:10BF70009ACFD9221313CD2F48786E18A170BB55D4 -:10BF800010D8F801EF815EB47F3F517EBC02F43FD0 -:10BF90009FB0FE1B054647816D4E84EB85BCAA8A87 -:10BFA00091340DEF5B5C48281F3F4FC1DA89E2F7FF -:10BFB000022B9120A51CDC88F009C867C38A7C414C -:10BFC0007A96A279B1757E3EE415FAA7EB5E1094DD -:10BFD000A379FA77E10E6D5E052FDCF7268B1CDC6A -:10BFE0008A78D585C1478197B70B831F87579E45B0 -:10BFF0000E1892115E41E0034EC18D7028B2C82127 -:10C0000091F65344E1082458B4EFA95480D3C21DDB -:10C0100016D759D5B88BAB1335F9D2DA4EAEB32A51 -:10C0200039DA7CF4970EA0D3256906D759CADF1AEE -:10C03000567893CED22DBBB2A20053053F16576758 -:10C04000B86C9A7EB4F9E64AA180E1B7DB396D405D -:10C050007C3C5B9266749DA5A47A690793B797565A -:10C06000985D304EC30A978B8D9B86A902AF45CB56 -:10C07000AD585F995FBC7EBFEBF9115243CE9881FA -:10C080009FD3B29EF1EBC7A527E93323D2499D7C0C -:10C090001DF0C64CFF7E6D403CC2BCD26F69B51826 -:10C0A00030DD0EDF776AC6A3EDDCE754F2253EDD16 -:10C0B0004AE49C0A2F97420748A766DC673FEDD108 -:10C0C00049FB6B946C6B418F9AC0F1A714EA517EC7 -:10C0D000B0D81C36FAE9A7CB356C3FE28D7369C541 -:10C0E0008E2EC0D78ACC9546605645D57DF3809E6E -:10C0F0002ED7AC4A05F9B2506CFEBE2F46FB1F2B63 -:10C10000741B949BB4F232C8E749FBD5D019B1B582 -:10C11000AC9BE61B0C74285BEB7E7F2A30B953B2D4 -:10C12000F3F8989174FE25B5578D308F0982FFA7DB -:10C13000424A74FD02AC9FF653BCE39411D677419A -:10C140000EDCF278C64DE0D96A9EB6B47309AAF93E -:10C1500005A82249E9757616A757E2BEF7CF943EA7 -:10C160002FFE41264FD379901BB4162D4FE7A573B0 -:10C1700089CF01F09A5DB310F9CF45E03F208749A0 -:10C18000E530C08FCBC45000EBBB4CDE730C56C106 -:10C19000EFA060E4F0A1AA2CE507261C0AE1D6096D -:10C1A000F895A9A8A25E1C08DFA500E74BC2D7C876 -:10C1B0004F8202F2B322F63D40CCE5B88EB58C1F1B -:10C1C00005E81FC83F5CA9E54FF3376AF3F3C8944D -:10C1D0005489F29779CFCAB447CADFD4FC8FC2EF33 -:10C1E0006581C9DDF9A4ACC245E7BFD948F789CE5E -:10C1F0007FB68B485DE8FA16BFB179D82C9A7F5B81 -:10C200006072ECD20A3AFD5B683F1DD8FA8B970743 -:10C210008DDEFEADD777A666F0F49104FB63F2B134 -:10C220005891BFC42D0D436E4995DCF8EBEF5223B6 -:10C230007A2D0EA847BFABF8F39CB5DAF5B5B57EFD -:10C24000FD7A097906F1AD78C7640278A6AC47D9C2 -:10C250002F653DF20EC11B8C4107618EAF0A5F6BEB -:10C26000E2F053F48ECF75F92F75F9AF757905BFEC -:10C27000654EDF14EF3F1786023D378D6178123629 -:10C28000B2F30CAB678CD6FBF266F54C9C5E68BDD6 -:10C29000AF6F56CF12ED4F32A4B4AEB7F88D575EE4 -:10C2A0000F50FC2EFECD730E42F1F1A25499EAA17B -:10C2B000DF176D5BE300385D90020EC09B8B41B1D0 -:10C2C0002016BC46180445DFB00974DF4B14FC1F70 -:10C2D000553E11E4FBF56DB2EB69BA2FA53B4C213D -:10C2E00013DDEF929A05856420E64FB1FC93570168 -:10C2F0003F4A6BE5D3EA7D2DDEFE5CAADB8EFBD0E8 -:10C30000C5003A30097521342DA9FA640CE8D1A58D -:10C31000A409F159DF0EC687A31DE5D7B38CCED68D -:10C32000E5CAB9B1947D22A5353FBA0AE7C65222C3 -:10C330009D56E35111E032D5F3FA19ECC9705E2035 -:10C34000C3C970E02B0A1C483005F9F2AA977F3A5E -:10C35000F0149D4743D51F1C820A3E544342B83413 -:10C3600057CFF95BD24DE4C2158A9FE41675BB2006 -:10C37000B673D7D20974A4D93A962E92438E9114EB -:10C380009E8BB6C81E8A9964D12BBF7CE9054A777B -:10C39000E46393A73785F7C2578E9CB883E617EE00 -:10C3A00092930BD9326C426A743F4AE95FB0CB2852 -:10C3B000F02F7EF588D13D807D7FA243741F16EE5D -:10C3C0003A6024035AC32DB7FA80316C8BB11FD564 -:10C3D000A7C6803EB3EAE5BF1B61BF2FEE1748C773 -:10C3E0008CD6ED8BB61C41FD05E084FBC7F7A76535 -:10C3F000BF5AED5368E2DE2158CF05FC3ADE3ED944 -:10C4000041560F453CFEF55E3A7ED19F4C1E587F4B -:10C41000D1AF973A601DE7A53286CF9BD7A47AE9C2 -:10C42000B8457220D58529FB5EF4E2A38867F38FB7 -:10C430003F8A7A19C58F4E069419814EB0BE873750 -:10C44000DD83EB9B47FC886F459B455F10F880447C -:10C450000A76C5A087DF707A38BF95724ABABEF3F4 -:10C46000C01F41CF7D4FE4FCF111D4231FE56BA524 -:10C470009A0CE63F37B37DAA301814BB9C5983A7AA -:10C48000554F221FBDD4CDDBD1D51FE1A0F04DE427 -:10C49000A7E2F1FC8E6C7F18FFC57614EF72E13BCA -:10C4A000D4AF97BD96819A769C5FB2F197F1F1E98E -:10C4B000BCADA07F9C4F657242BFBE3F1914FE48C1 -:10C4C000E5AB0ABF5474CDE8BCEA2946D70A9D07FC -:10C4D000271740F9671F30FA8176207FE8BC421D9C -:10C4E000B1FCC03401F980898462D17395CCE959DB -:10C4F0005B4E3934EA6F74DE92E054E309EDBF031A -:10C50000C21FF59279CFD2762A7DBA14C6C37AC6F5 -:10C51000E8F78C28DDCEE7F4FF2BA0FF8428FD93FD -:10C520004D29ED3A9F2D92832FBD00F44AE933E067 -:10C53000067A957DB0EE4F771E3A713FC5EB4FAB53 -:10C54000153AD5F24D3D9D16ED7E94007EEAE9F454 -:10C55000D3AE6524269DD2EF31E9B46BF87F856FA9 -:10C560002A703BAE831BE583BFD8EB8E0F3F3D1F88 -:10C570002C35B863F241FAF30119D61AEF147C5343 -:10C58000F0ACF8BF1677077ED3828F0ABEB5E0A362 -:10C59000826FFA756AE1A62FDF04FC46A51FC82B3F -:10C5A00049C04EF7B9699F88E7C4467793A3031D36 -:10C5B000778D853C047A76A38BE71359BE29C5583D -:10C5C000017C41F9DE642133003F1B7D4D8E449593 -:10C5D000FE7CAA4E74B8697938480A62E9D594E3BA -:10C5E000E2F86112AFBC1CE1972FDAD2970F81738A -:10C5F00095E801DD6D6EF9BD0E305934D6F59C34E9 -:10C60000837E7FF86D116D1A8D56C74098173DB720 -:10C610004B9D287CE7F07DBE4002CF8FA2EB9A5362 -:10C62000C7F4E2B9EBB4F098675B66043E43F5CF1C -:10C63000281EA8F045F113146DD296179375B85FB4 -:10C64000C53AFCF1F3F34E2791E3CF2032889F37B0 -:10C650000CD0DF12CEA7F2C5FE936650B8371E1578 -:10C660008989E69BEB445201EBDC290409D0712057 -:10C6700005F1B084F207A23A1736009E19E3D36F92 -:10C68000C36B7F1DF638ADB2E8F53F0FFC394D1B8B -:10C690005EFFF8963721FFC647E97F26ADEBE7EE50 -:10C6A000FFE241E0EF8DFB4D04ED24FB7F97FE3868 -:10C6B000E4F79A3C68E75869F2A27EBCDF1EEC0DF5 -:10C6C000E5DD987D69D5BEBF0F0CA3BC598DFB94E9 -:10C6D00027B2734473DD3FFE5B488694AE0AE4E8FC -:10C6E000FE04D4AF4BF75A8270E86CDCF7F7617E3A -:10C6F000DB77B79E1223F123FED9C98CDD80AF8989 -:10C70000CC9E56FAE6885F96D3F117D71C30CEA19F -:10C71000E5B9BFFD6A20F095C6DD4C3FB822875FC2 -:10C72000241E422689CF95CB74BFAE80AED699F237 -:10C7300025F14476C0160B2E0C0E8D140EB02E0A69 -:10C740009722E087F1E031EFDF161E571F84F117C3 -:10C75000D50D2762861A2E82977DB707CD02AE9F30 -:10C760007DDFFFF781C0773FAD2E47F9DDD6BAD721 -:10C77000C0BA53FE5F5AB7106ACFBAABFE6DD7CDC1 -:10C78000F0BF9FC8E4919E0E5AE3F91BDFC7FCAFD0 -:10C79000ED1E9C6F3BE9FFF0BFEDFABFE5BEEF1663 -:10C7A000D01FD7D6BE9FF9B75D775BFBFE36DF772C -:10C7B000BB0BECBD8DFBBE4A27AAF5B7B56E83F463 -:10C7C000EFCADF6EBE6E45EFA93794B986D0F97D0A -:10C7D0004C2AEFC9A0E91FBDD792E1384A69C017BA -:10C7E000EBDC9029B1738309EC4C50F11E41B11779 -:10C7F000D56BFCB85D8B50CF98E8FD31EA07442A31 -:10C80000ABCFA6F5EB73E6789EC61A9927FD909FED -:10C810007627CF6BCF531373C61F05BDEEDD723A7B -:10C820003F885BE826B9A8A644267945D403698ADF -:10C83000FADF87E963B0DEA42CED79E23EDD79E032 -:10C84000DE19DAF27B78FFD3C9332960779B3E97F4 -:10C85000D9DDEE25656B5CAA7DBA47D78F4322DC14 -:10C860004EF2EDE037B7057E4B101E245BF46C23CF -:10C87000ED801F61F0AE9F3628087618227918FCEB -:10C88000A62FF6A01D949F3365DE5EB6ADAD07BA48 -:10C890009589F67CA99C13DB8233E1E74FECAF4727 -:10C8A00014EEB257C4F3A7AA5F848BB21FDF741FC4 -:10C8B00094FDFBB6FB310CF62386FF6C81D97C0F0F -:10C8C000F82FCC7D043CB74F5A27621C8CB9BF802F -:10C8D00070F465C9E8DFF9C4E01B068A73E1E0E1A2 -:10C8E000258FB16E3D009F051C8EF34819EA9DE42B -:10C8F000C6D75F8F02BF114286967B099940CF2130 -:10C90000F34609212B5DF77C89049C9960D714C8F4 -:10C9100069B55D33A8CDC3CF5DA9D17EDAAA1F8FDB -:10C920003F7CD7E9DF283F3ADD8B9E572095707812 -:10C93000497D4E7CA88EC1B1749110EC817814921F -:10C940007D2ABFCEC71CAFFFF6C460E473D93F1980 -:10C95000E0C4F3ABB71FEAFBA55CDF6F0EB89D60C8 -:10C96000AF69AEEBE9047B4CF3D15C879A2F2AE9DF -:10C97000717E8E7C7F8519D3C63CA15284F31669E3 -:10C980009A887238CF4280EFE8DBED9114BB4B19E7 -:10C99000F333D21F7118EC23FB994F9B3A3BA8F657 -:10C9A0006DDD848BD2C0D6FB003FA7557E927F15EC -:10C9B000BE706E05B81EB784C7F862ACF70F1C7E58 -:10C9C0008507BF30829D604A5D860C709992276A08 -:10C9D000E26E0E49FC3C35980C8679151E1CEB184E -:10C9E00001FB7254F458287C4BEBAE1AFD31FC6D00 -:10C9F0007A7842FF60173E237BE6013CCFFCD842A9 -:10CA000002941EDEE1FE1F5AE405FE45BBF2827D64 -:10CA1000EC0389F915FACACC2E3EB5305B4EA1E382 -:10CA2000F6AF710D0211D399D7EF2BBBB1BC0B6FD1 -:10CA3000A7D4EBBC88D53B657495C45AFF04235B2F -:10CA4000FF7CE2F97E96F0EFB76FD93FB187724075 -:10CA5000BEE709C8475AE33541FA682E1082207FA5 -:10CA6000E11C8BF94201E5FF3B06561E98C2E4A586 -:10CA700082F77A380B3283B3327E86CCF0D92833F2 -:10CA8000F8287056E0AB9FAF529FF2ABD16AFBCA59 -:10CA9000A4DA41BF06FDA4A44E7081E9AF440A1B8D -:10CAA000810E4B6BD7CBE02FB8CFCDFA25926FA07C -:10CAB000DA5FDB5796703E873247A2FE786D1DD352 -:10CAC0008FBD73AF3A400F7AC7E0F9E348A0C7774C -:10CAD000458C278807C73FAFD8312D4F52F79B8130 -:10CAE000F39CBA285B0673D0F7161D903BAAF0A9F9 -:10CAF000AFDC01CB95EF9D17B933E13B1D0FE7117B -:10CB0000F84F13D946BBE85F5D9F9340CBBF579664 -:10CB1000C8F0B0A8FA8011F319585F194F19474FA0 -:10CB20004FD30A1334F939B9E1AE009742536899EB -:10CB300027069E1E96153FC93794135E8AB703FFDA -:10CB40007F901357C77863C06D83DC4A3E748C2591 -:10CB50001F9694BB3B02FC97ECEBD9118863C9DBB1 -:10CB6000F9A9B1E4C3872B983FF023CACF206D9C6D -:10CB700046E5C3ED2AF930CD82F8A16FF743B99DA0 -:10CB8000F241D9AFFF653EF321C88718745D296B68 -:10CB9000E5C3F4BA59281FA64F13895B658F7B52F2 -:10CBA000E67EAEB8F2213BF53ECCCB9E841878F3FE -:10CBB000213F97005C218571404EFC96F37DBDBC02 -:10CBC00088C7CFA71805EEAF6E839FFF5F82B3C201 -:10CBD000CF97D0F30BE881ADF19020BF5E721FE5D7 -:10CBE000E702E023E3E74B1EE076491D7FF5017F76 -:10CBF0001DA2E6AFAC7D899FC983D2DA8C9FCEA4FB -:10CC0000E5F757CA1E33AD7F7F94DF0E53F3DBDFAA -:10CC1000727E4BE19CEE8AB1BF33662610B7965FF9 -:10CC2000F5023E7566D0EFFABF0A78FF8E887EC4A3 -:10CC30004FB81C3F36E87743C07E9E6C94107F3E11 -:10CC4000E1FCEBCA8AE0B43C4AC7B973993EBC78B0 -:10CC5000A7887028A9617A5E492F6BD04DF36332A3 -:10CC6000BF407FE0C27DCC1F48015598ADDAC78533 -:10CC7000EF842BBA40F91601FD99F33C0BD18E4F8E -:10CC800036323BB199FE61711D5EB4232FE6F05A36 -:10CC900050B705EDCD0B825A3BF4E25EE32EC2396C -:10CCA00040E1BF0B77E8CA3D4FA1BF6231D89B5529 -:10CCB000E70F91EB0F0F8BA1FEAF426CE71FD9B9C5 -:10CCC0004ABFFF4ABD96F517FD8BEB3F4ED73FE4B9 -:10CCD000BB5F7F7BD72D1B39BD679221401F9F18FB -:10CCE000BC48EF81DFD3F5D371E6AEEFDD511D67B0 -:10CCF00094C4E9F21D83BFA213D42B11B0DEFC4D06 -:10CD0000BB8EA4D2FCCC6A3208CCF4F3376AE5625D -:10CD10008B1CAE71A39C9D59B64B98DD1FE04DCA8C -:10CD200000CFE6649AFCE04F3D6E6942FEA5E0DD6F -:10CD30009D4686CF23F9B8673A37E5E139A25670A8 -:10CD4000215D842CEC5C41E16FA1F94323FE3E861A -:10CD5000C31BED31A5B56C7F4AE97E005D8DA9E36B -:10CD6000F91D4C0FFB1E9537E80FAB3B2043BB2250 -:10CD70005A3F09F94D3F8D9F0BFC73D9A9AA7DDB62 -:10CD8000778AE1ED36C14362EC5B1FFA27E6BE7D90 -:10CD900047F8AAC0E34E23D7E7F9FE1DB7D4170E14 -:10CDA000463F94E0D90A95EB12D18F72B6B227EEC6 -:10CDB000E3788EBF7ABC06FDDEADB2274D8689438F -:10CDC000BC658105E3DC70DC1E4CFF51F313FDB93B -:10CDD000B994D4A31E3341F0FF5552C5B54DE7F1C8 -:10CDE000278A9F5655EFA7F24DEA91349701F8E450 -:10CDF0005225DE12E28753316E097F0E751BF6D184 -:10CE00004CBADE6B6B450FF87FEE35B84F8C02FAEB -:10CE10007D5A268097D78EC95EA6772620DF9DF59E -:10CE2000CE19194C21B3284C60BF67FD90F1D73360 -:10CE3000D019FDF6272AB7BCE0AB27D543217E7871 -:10CE40009AE740BE9BEECB3D438EAF013FDCD45C06 -:10CE5000D7891300DFA74402F03DBD3617CF274B1B -:10CE60001F1110AF4F523842FB7BA6659C3841C75B -:10CE70007D606D0AFAD5667A8FE4039ECD9964B71A -:10CE8000817F6D7C1F91F855707C80D4A39D626674 -:10CE9000D923F7C07C8BA81C003B6B51DDF1FC8EC5 -:10CEA00090DF2478DCB4FFD280DFD8916E61FDC6BC -:10CEB000AB46B0B7CCA3F5607B4A37B17AA55582B3 -:10CEC000C702F858B71EF9CEBC2A81B8A03ED5F7E4 -:10CED000CCACDFA099F65BBF89B6A7F9F9D01EFAF2 -:10CEE000AD4A9C0E7EB4D263226B9F55FE16F0A510 -:10CEF00079B41D2D26F5558F607F0B3609248DF6EC -:10CF0000579495F19F59D0DF31D903E51F1DF8994A -:10CF100011E6FD201DAF13ED7F8E18CE87FAE47168 -:10CF2000C1B50DED4D2C4EB691D301F9A013A32F31 -:10CF300081E7B91EA8C8C3F78D3D109FE62D2FAF1E -:10CF400080758503291970042AADBD6A04BDEE2CD5 -:10CF500085B39FEA6D67781CDBA1C0196358C5A72C -:10CF60009A8C3DB1FDDCDA6CA4EF87890FFDDDFE04 -:10CF70007226874FADB10405D03F6417CAC9436B11 -:10CF80006E7D1ED67FE51519FDA357BA85D11E7B90 -:10CF90007E934C02748EAB3689C837CEEF64762010 -:10CFA00071B38CF9F98F1A317F68D3D431C00FCFA8 -:10CFB00053F8031EE66ECE37427E3EE5EBA618FC24 -:10CFC000639EBB98F10B1D7F98BF514BFFADF8C519 -:10CFD000B2318CBFEBF8C1E2AE1568E7D3F38952EA -:10CFE0006253F84326E4EB439D107F4B8EC904F453 -:10CFF000B912C9F5E046C09B9916F01453BA081D42 -:10D0000001BE762D28B803B4FC7B0FED190AF03B66 -:10D0100007F006BA589784FED479C1590857259E5F -:10D0200070FE462D3E2BF14BF7F945E255CB81A220 -:10D0300004E255D5FBE887142FE9780FD50A418B18 -:10D0400000F9536F3D3A04F32EC0C392E55C9EAEE7 -:10D05000B323DE7EF483AB6B002F1F7C42C0F993B9 -:10D0600080BF02E44AC946C10D76CCF94FB0F6F351 -:10D07000697BC0978F7EC6F087E2B11BF0BC64D39A -:10D08000FAB7B07E95E086FE3FDA320BE56F51408D -:10D0900024585E750AF5632A07300EE850404C05A7 -:10D0A0003C2F596D72C13E2AF8A2E0DF2999F9EDB3 -:10D0B00089D933702A6DB7C5E8C675EBF14E9C91DE -:10D0C00081F855BA5346FC280D307C3AF58A8878A9 -:10D0D0007868CDBD883F57B60971F02FD7D809F0D1 -:10D0E0002FC8CA5BF0EF6581E31FC3EBF3CB183E9B -:10D0F000E64239E0DF6B5C3F25C4A6D63B14FC5307 -:10D10000F0A92DBC6B2597E2E01BD58DA7C3BC967B -:10D11000AEB1E0BC732BF64C5F8E7423A37F3EB799 -:10D12000E207A940A7F3241687A1C071B1C4E27435 -:10D130005ACDE3D97263A7F6CC47378F0351B9981C -:10D14000097211E24A42749CDFEDFC25C6AF5DFE18 -:10D15000D5298C4B5CF826DD775AFFCA4E3B09A1D6 -:10D160003E1D44FE525C23625C289142C3A6AAEE97 -:10D170008F28F1160B7F6347F816EF36050B69FB16 -:10D18000E2D7CF0C447FF8CAA6B7807E02BF1298C0 -:10D190005D3E101E3815E22A2516F7A197BB234CD9 -:10D1A000CC5ED3B0276106E83FC28E03E84F2AAEBB -:10D1B000BE5736A9EC931E938CE3D27AEC9E0BDD1E -:10D1C00077F023C2FC260F50CFAF9CF5F732A39B1C -:10D1D000E25A19F5A2E21D5BD0AE57BAE32AC6BDEA -:10D1E000E6FEE61507C0A1B456D4C643ED104326AB -:10D1F0008CD7124F99187FD2C42595D4B07B1925AE -:10D20000D53CEE471717B3F037FB5E0F50D02C7CA0 -:10D2100075BB03E8E852FD3607C093F687F14493E7 -:10D22000B2E2C41BB5156754FD54CC38A34BF00FC4 -:10D230008A200F9AB4F1996407E35374D787F9628F -:10D24000D833157D65E12B9FBF0871AF0DBB3F7DC6 -:10D2500011E6BDE89FD75E84B80DB2DFE202FDA102 -:10D26000F4571F62FCA0D26EB9899F7F5EDE8E717B -:10D2700097573E36A1FE7765DFF974D00FAEECFA12 -:10D280002215E22997EDCB47FBC3B2D7723B921828 -:10D29000E75B2505BC0CB623EE53BF0F876AC4902D -:10D2A0008DCEF3F24913D2774BBC58F562167FE767 -:10D2B000E671623B63C7D52AF14D25355327DD0959 -:10D2C000FCAD86C9F19678A7B6E2C33EA0FB797B98 -:10D2D0003BF66D278FFFD3EDDB65F807DD9FE74C4D -:10D2E000DAF8B0CF6B1EFEC50B505613FB3E9942C9 -:10D2F000C76DC14B89DB9D63F2064D4037BBFF0B09 -:10D30000E3F060BF0ADD20E73F4F07BBE505B90941 -:10D31000ED814DFB4C2E88DB2ADEF711D2C795D765 -:10D320008E635C2CE1F1B35748CB0F8B77E43689E1 -:10D33000D22A3B8B2BE37087B833B703BFF3F832A5 -:10D3400086B74ADC59BC78B30F4D3DF8BD0B1617B4 -:10D35000B7D85D6F04F8ABE3D0842CD8A7539AF804 -:10D360003D65DDFAFE5C0087E1EAB8C978F17C5CD6 -:10D370001F6FD927C687AF6CE171942DF19184742A -:10D38000CD84781F26EF4A83C24724063D2A719335 -:10D39000F57A7A0CB62F5EB2EDF97E3B781C32310D -:10D3A000FB930297861BB1F9F1A79CBEE9B9E49201 -:10D3B00049752FE5217E2E51E2C894F9565433B9B0 -:10D3C000DBB083E9857A7A2EE1F676FD385FF0717D -:10D3D0004A6A0F0C04BED370700FC73786CF253B47 -:10D3E0004F19039C3F07D5FC19FA8BC14F4433EB0F -:10D3F0008F9E6363F657BAF36ACCFE2E49DE7B61DB -:10D40000FE97EA999E71A95A2C08C6E8FF32973F09 -:10D410002DEBB61BF15C253AACC87F96D9B34E3ADA -:10D4200093213562FCC2AA721EEFF0434F1AC079F5 -:10D43000957D1C81F9AC01F8A8CE99B2CB4F40CFB5 -:10D4400091D37C43E0FCA4CC572937261B4850BD20 -:10D45000FF5200EF474EECF17709E44BFD0AEDBDBA -:10D460008E7AC9752489F6579F2778409F6D8D67FE -:10D47000DAFE277B458D3D0C6CCFB0AE668F01F791 -:10D48000D36E08B9681562B7D4A7E141CE4DDC521E -:10D490002A8674A35FFBE9153BBAC13D2B07F1084F -:10D4A000506EF7B4DC6FC1FE9C4417671D201FC08F -:10D4B0007D481B67264EE23A0076096B1FD207FCB7 -:10D4C000D62E62F5C0FB0A1BF8BDC775763FCADBD6 -:10D4D000B874E361F75E143B91334BD2DC8B49F4B3 -:10D4E0006AF349BA7B900ABFC62B7414FE63F8BB7B -:10D4F0000F89F96CFD60AFEAAD9A6F620AF184A002 -:10D500007C820DE3996D36363F65BE743EC80F28A8 -:10D5100098D87CFA8703A087D379E9E898E0BD27FB -:10D520003ABFD3BAF969F4B8FBCC5C3E4844023E3A -:10D530006233D7130EE7666D9C698040BC81B305EA -:10D54000AEB49CF693214C3241DC820B4EC13D714E -:10D550003C5DBBAE2EF57DB15AF8C708F4171D36F9 -:10D56000829FDF2CC0F19974045C032048F54600CB -:10D57000C64F6D4A3E84FAA2AFE6389E3F17571F4A -:10D58000C77203E4699A94E0CEEB328890A7D6E69E -:10D59000E5A5F5857AB3D20C1ECC1F96808E26FBAE -:10D5A000D30C8360FA79AB0F8F22643B29EB07160B -:10D5B00025F36AEFE1A3DD00AF083AED48C07B1820 -:10D5C0007073BB92A70C10DE57D86E6DC97BCD94DB -:10D5D0002F6EEFD1920F40BE0A807F078CE73DBCD3 -:10D5E0001AE27CCCBED5663AEEE4CD06A4BBD111DE -:10D5F0001B9E3F48B803F26742CAACBE18F7A55B52 -:10D60000EC3CBC5E5B7C7C3B8F479EECF77BE0AAEE -:10D61000F7702E8F892B3C18EE63379A673F6F5651 -:10D62000D3E1E666B1079DDFF3B0F7B4BDB3C03513 -:10D63000AE0F9D9F739381C5CF9AFD3F87FABD9F23 -:10D64000F01BA0CA68125E2A001FFE4B32CE47199B -:10D65000A7621F3B5755AC31045722FEBA05906FA5 -:10D66000D1FD0BEBF6AF89ED5FED29DCBF92BA532C -:10D670006CFF6AB71C30727B3C9C5BB613CF2E30BC -:10D680003DED5A3B234FA2FB92646AAA807D95C967 -:10D69000F4BCC2BE08D7DFC4842B9F5F5B70DD7E05 -:10D6A00061EB8F06825EDF60F0F426517829F54E3B -:10D6B00098599CD864ABBF0EC6297D365C01E7DF64 -:10D6C000BD17DE433F70EF86E6D0403ADFDEA3B8F9 -:10D6D00039858FBBBD612BFA33B7031EBBC175EF14 -:10D6E0005F0972323E3C187EB7C0A3E614C2C70081 -:10D6F00079FA7D37BF4791532B78414E2499A81C66 -:10D70000A5E91FCDEC1C73C62CF294D9199D0D3DD3 -:10D7100024D08B73A619F03CE5E46974FD3CFECF80 -:10D720002C69E48BB29F0A1E11529900E79C02A754 -:10D73000FF2F5ABC7926A1072D1F7DF6F452B0EBBE -:10D7400029EDB6AD209EB9AAFBD0147FF668DAE5C4 -:10D750003F6A057BA8521FF032D63981B6BB04ED73 -:10D76000601C58C79EB3CD22C0BBBDFBAAFF5EBFE5 -:10D77000828ED72B3EFDF8B2D9BD22FDF77F9A15D8 -:10D78000BF23D347BCD17B7FFF047C586C0E3BA6E4 -:10D79000D1FD2DC9BE660438AC4CB8323296DF33A9 -:10D7A000DE3CEA6FDC6A03397D30628A798FA0AF94 -:10D7B00085E917EFAE98E1013FFC532DF704983C43 -:10D7C000CBE37C37AF577121635AAAB83130587018 -:10D7D000B9990F5FE8FC0AB27649203FF3894A5EA7 -:10D7E000323BC504D0479ECA1109C6A9B9648D7CD5 -:10D7F0001B0FF67207BC0B52761886BF3B4D7B0F92 -:10D8000074D2A85312BC5730368B8A6301DEA7D17D -:10D81000968FD7DD139DEC9DE5C9E3E5D7F0FF4179 -:10D820005CE7A4ACFB3C796A392155F6817D3EFE6C -:10D830009518536F7CB4053E3E84EB1B160A9FDBA4 -:10D84000619DB3563399747378E8E1A8874BDE5F26 -:10D85000E6317BA10E1E77DFA83C9C14030EADD7EA -:10D860005DD907E4A6023F3D1CEAA12EEA4DA620A1 -:10D87000E881F55218E1584FE118E07EAB7CF53EA7 -:10D880002BF3E1FAC378FE5D0F4F3D1CA97E81FAB0 -:10D89000C3D80176B4831D0378611C40E50726FADE -:10D8A000FDED5E32791A785F6834C619DE45105690 -:10D8B000E40DA12C0FFD322EE65FA1F29CE1C35FC7 -:10D8C00098FDAA30C2E63FC6CDE265283C4EEBE0AB -:10D8D000715A87079A738B7E9E6FC03F46C4C00FF4 -:10D8E0008E078B2CFC7C934EDC70FF7FD8C7439C4B -:10D8F0008C2FC4968FA323BE967E98DEC1DEE710E0 -:10D9000088BFE5BB8BF613F2CA18FF996B76217DB1 -:10D91000E4126F12BC07014186304F655E8305DF5C -:10D920000F2D29F07ED3D824F5FB10CAF8CABEE427 -:10D9300072F8E592C0013887E612E933F5BA95FE30 -:10D940002A2C5CCFEA4EBAA39F1C8CA143A3FD29CD -:10D95000EB4B4A22217C3F4430E33D27FA5FC0D89D -:10D96000213A9E123F9A689F526941BF4E196171D8 -:10D970001221DCCF1C5E9EC3DF6922E6B8EFF29075 -:10D98000AF13A2F37BD12248F86E029FDFE5A3E636 -:10D9900000C46B3C26F8B7021C1A846303015E5472 -:10D9A0001FBB05EFE9EBCAAF9D3C5C02E5B4DE3C72 -:10D9B000ACC7D7B5506476327AFEC7F7505AF371C8 -:10D9C000664FA3E426C1FC15FCCFB132FA1E4FDC32 -:10D9D0005DF1BD34E297203D6C61F7D0EE3EF90C6D -:10D9E000EEDF1FAC771F057A2B204109DFF9716943 -:10D9F000F1B04D3CEDA33FFFF2775DA4A67480EB40 -:10DA000041CBADBD408E29FAC27B16DF6F61BD07E9 -:10DA10002D8C3F9FF60E7D17E4C2ECECC12786D01B -:10DA2000D460F6E1BB0B0F035E517866015ED1B6A0 -:10DA300007A1EB4E88574761DFE6ACD5E19599D950 -:10DA4000D36653B605EBC8592B7FA99E570BBCB8BC -:10DA50005C6C4B3F2487A9429F0AEF2D30FC3C6849 -:10DA60003105406FCB798AC547CC21FE172B057C49 -:10DA70000740A3AFCFB530BBF7DC9F5990CE69E329 -:10DA80004D65E0E7B2F0F71CFAB077775AC6AB54B1 -:10DA9000B5877D37A7221ECEE5FEC3B3023BB7CCC8 -:10DAA000B5E4B37BBF1BE566353EEAC78FDBAFAE9F -:10DAB000DD4181D9490ECA6E8C0753DA5DB1303928 -:10DAC000DE6CEEBDC97093FBE0F3CC1DFA4B49D17F -:10DAD000FC398B65462CBD40E9AFE55CDE729E30BB -:10DAE000AE39DC357A9E3094CB47B4E709F9C8BF2C -:10DAF000729EB03F2D1F594DDBBF6DF3A55A617C5F -:10DB0000C9D717E0FE1CD70FA926D3576D974EB57E -:10DB100032FD3075790E393338FA3E9B20D199E0C9 -:10DB2000FB1AFE729037D20C82FC9FF2998762C575 -:10DB30000525DA733A5B8746E9EF2983BBAA92C5CC -:10DB40002BA0BFD7B77C36EA7353971761DA78FA00 -:10DB5000C62D4087391C9EB75A995E5A9AC0E84331 -:10DB600010FCB7427FF55ED10EFED485B522F7D703 -:10DB7000B177ADA64E1053E0FB19B38CE7C08376A6 -:10DB8000B6AF67087B9F26E7B8C95743D31B247BF2 -:10DB90009C55A5EFDD2079982769A9E8BF56EE2BA3 -:10DBA0009E21196CBE6B997FA0796D06C6311F94BA -:10DBB000B5F6A85156A60F8FB2B2FD9DCDDFB103C9 -:10DBC0007C82F724664B6EB40FCE8E18D93B6A74F4 -:10DBD0001E886F166D3FF956163F91CFE13F1BE44B -:10DBE000E460A8A7EF4762FD73BCD5C3FD4D4BEEC3 -:10DBF0005880D30DE21D6745BEEE96003E39430EB8 -:10DC00009F04FED6363F0F08C0CF4B6F08A1EE60D1 -:10DC10002FAB91F17CD6C0F5FBCB35875267D3741F -:10DC2000F1AEF71D700EFC9E95E95397A57A7C77AF -:10DC300062D16B22DE9BA6689AFA3D6C3F6718BBE7 -:10DC4000F7C1EE2D2872EE8EAF7A76F5613D76FF44 -:10DC500040D1AF72CD8120CCEF60B98876292A07F8 -:10DC600035EF90E4D7B07B097ABDEB11ABCCE3354F -:10DC7000D93E2E73B171E2D16D4EC44A822ABACD1B -:10DC800091DC12CC3F27E220410AF7CB17B66E9801 -:10DC900048F13C9026E3398F1E7F0EA3DEA7F8C122 -:10DCA00003344FC739CCD773A466EA34785FE52DC7 -:10DCB00052B67A00AD9317F6273322A6A7B4615166 -:10DCC000BD2BDFA5D5F7F4FA6041DDFAD5F0164B90 -:10DCD000037C80F1CD268C236EA5279AEF8EA91F99 -:10DCE00012B21EF1F08ED77E391EDE9FB8E3A2C1BC -:10DCF00005F39B6C7533FB62CD357C1FA18484A634 -:10DD00004379498DE80AD1564748CD6D201715391A -:10DD1000AEC02574E390D903FCDE22BA56C23ACDD8 -:10DD2000F7D820CE626463FF64906707CD32DA21B2 -:10DD3000732CBD6D7354F87C3099BD1B7024B9A74A -:10DD4000F6BB79C36D20D7F6F0B8B5C3E7EEB7855B -:10DD5000B1DED464D4CB1439AED357157BD7D8DE1B -:10DD6000628BBD4BADE71271D3B3165A3EFE561906 -:10DD7000EFBDE58599DFB4951CBFE15FCDCF239A58 -:10DD8000EF055C3F6825D7A370D6E8A16F58B95E50 -:10DD9000E9260340AF0CDDD8B010EFCBD625B8563E -:10DDA000A23D81E92D8D678B374C80EFC744661FFC -:10DDB000B921221D1DDCBFB07B5845BF5422E0BEF7 -:10DDC0005D1F74F5CA9B745FAE7F62F504E0B354C7 -:10DDD0007D5B6CBF5890C329D499D9D9039DD93B99 -:10DDE00018ECDC7957F4DCF90EF001784706C443EF -:10DDF000DAA65346381F5FA6AA38E2175D34E0D78B -:10DE00005DDEB0A8BE7F738AF3DFC956EFFBC01F8B -:10DE10000324A70B55424891D59B0D71E04D938982 -:10DE20006B2B5DCFBE0B39824CF3A3B66578049A99 -:10DE3000DF0D8A25F0CDD7C420C493EC867B6BB46C -:10DE4000DF05F595C60C3A6EA04644BBFE026E1F78 -:10DE5000BF2007D21355F85199C0F8C905D9FF0B57 -:10DE6000E8E7C2C726B4775FF8C41A53AECE48605D -:10DE70007CF74D2ECF3213DC980F35EC7DAB339D04 -:10DE80005728E21A04702FDE7155847793EEE4FA76 -:10DE900057E1B3F5ABC12E33715393047CC71774AC -:10DEA000E583489DB2C323831C9AB6D327839A3D4A -:10DEB000BDA60CE39066D4561E81FCFDA16ACCF78A -:10DEC0004FF047002E77AD6D3A04E8D2AB9248F898 -:10DED0008ECF674CAF4AE5F3E811F11C7422366728 -:10DEE0001B00BF5BC67FA25E02D57DE26A363EEDB7 -:10DEF000CF9040D77D5759532EC8B5F4E5ACBF74C9 -:10DF000072A0DCE98EF63BFA46BDA0B617BCF898C5 -:10DF1000AD88F15B06F7F4C73B6FC173197159F116 -:10DF20005D454E4F398FDBD00F70FD07CC0F707DF4 -:10DF300010D3A7AFFFC0160CC4D0A7A378163231F8 -:10DF4000FC52F08D9859DE6B067CFBFEF36556A003 -:10DF50009B649FDBA88E3FCCD950D8EF6DE8DF6281 -:10DF600042BB5CCB78EBD97810880B78ADC8B1D9BF -:10DF70003AFF4B940F30BAA05D04615C2525C24A7C -:10DF80001751E749280DE6939EC0F85C95D13D13E3 -:10DF9000C6ABB29A5C30DE6C736F23F0AD16FB2615 -:10DFA0008F4F1BC9F5CB7D170E26C1BE5F1F549E38 -:10DFB0000E7A73C8F073E4536DE1DD4FACDEE10916 -:10DFC00038CF00EAF94AFD3DE7ACFD414EBE69603D -:10DFD000714FC433AB3BAC5769378DA7BBB99F4E6C -:10DFE000A193E47AE2DDD21F41E5DDAD82C7A4044E -:10DFF000468F4ABA5B7607189DB1B8CEDDF690B968 -:10E0000027D0F39E9E984FF6119B07E2586A7B7BC0 -:10E01000C05F43F9C0A404955DEA4ECE1F92EB9B0E -:10E02000902EDB7B1E18C6E11B92AA397D11E453AA -:10E03000405F8C7F87BAF0F778D0FF077C83EF4F83 -:10E0400027210DE3C1719F95752773BEB08CD33D19 -:10E05000C001CA4B795E295FCCE1952FF677AAE320 -:10E06000C75AC9F5E56904F4C7FCE59D312DE5F310 -:10E070005D605E8FF6D205C9EBD14E9AECADC474EB -:10E08000415E257E4FDB340BF163C1C6D8EF8C1D9A -:10E09000E57AD9E50B06F69E94C1DA19F04F297F8F -:10E0A000C72A737EE97F1CF0E162CD86E707BAA339 -:10E0B00076DFEB96CA89F703FE6F135DE5B03F5537 -:10E0C000F9823B065EA9E107F02AADFA1CFDA62500 -:10E0D00024CCFCA6DC2FAAF84F83558C9F5EE4FA73 -:10E0E000599155AB57562618383FAD1F7F3B1D3F02 -:10E0F000D4DC2B13FC4121292C4A6CFFD06E047C0C -:10E10000D885F8FE74FA638047821DF51EE0ABBB2C -:10E1100054F8B170E7968ACEF49F77DD60F77742C6 -:10E1200012B1A9F9B782270A3FD6AF6F2BC75F0597 -:10E130000F4746E5D4D6046E1FED49FB2D59DF8C01 -:10E14000F6D137147A067C037A5EABE0DB20037BE2 -:10E15000374D4BC7C3BF23FEBEE79917D2D1FE9000 -:10E1600045E916DE5903BA8E8117BF6DE103FEBD86 -:10E170000931E4C145C1FF8BA49ED1F67BCE8DEB66 -:10E18000375BD5CFCF389E5F97FDDD5D31E01585DC -:10E190002BE90CF850447706E04036092E75DC7BFD -:10E1A000F22666E7AFE7F055BED7EBE03D3AFABEA0 -:10E1B0005C3D8377931144765A90E905C430AE33C1 -:10E1C000C8F90556EF38B4B7AC37107C4F55C84185 -:10E1D0007C4FAE7AEEDC574320B5F440BF09711B8B -:10E1E000008F163CE5C6F3E0CA972C8897E71258D3 -:10E1F0009CC4CA2A99E1A75C89F875F193E2EEE024 -:10E20000770950B9DE3B86DCF9AD4E9EBFCAE5A862 -:10E2100082773DD631BCAB92BCD644155E6E27DE0C -:10E220004CE6EF6772251E3E46F1C83548C1A3593A -:10E23000F47B8FB56111F68BEEE335A0DF9EEB9A90 -:10E24000909FC5DB47C5BFA6ECA7C2E787DBB4F745 -:10E25000FA641B5B4F729C7880A89CD3F26578FFB0 -:10E26000CF36544B0F70E552594F23874B3CBA9829 -:10E270006363EF3E57FC75C38340CF15EBAD9E95AE -:10E2800024EAA751FCA7CA3C3ADA048D3F47EF675E -:10E290006934FB536D2ABC023FA01BF93DF3AB2848 -:10E2A000BF8760C93616E7B4078A808F9CB506D54C -:10E2B000F7776F958857CAA470B565E0BA6F0516F1 -:10E2C00042F3C9CB8DA4173D775D1F71E0B083D6B3 -:10E2D0009FD0142EBC9D2E718F313C6D12D87D893C -:10E2E000B718F40CB4D103FE37B07E89AB5A33CFE4 -:10E2F000811CDECAFE54FC754E5A2C3F8002C77842 -:10E30000FB3287C3C3C9CBF5F46FE1E59FB69B7EB3 -:10E31000034EA0DFBB48A01CE22FE8011DE3D65A44 -:10E32000E8971ED8A1FF029B967E957C0CFA2DB033 -:10E33000A9E9371266F4CBE9D459257B63E92DD3DB -:10E340006DEC9CECACCACF0679E4F461D839D00D01 -:10E35000D2FB024AEF40C701A0DB8E004F86673D2B -:10E36000BC9518EFD8A38AE9E3D713D97A17DCE96B -:10E370003D00EF252FA0E7018156ADE4F41E1FEE0E -:10E3800021A7C0E49B13F8CC5DA3C2B92087DD6050 -:10E39000EFE888BFFA023765F428120CD17D77DFE9 -:10E3A000208C7F7CF2C2838F01DF586FC37B4F8A42 -:10E3B0005C4A4DF017DB86C6A76B8A975EB0572D77 -:10E3C000F9C2C6CE8D71FCE2A3971B48AF24C4F3FB -:10E3D000A56A3C1FED6B1201AE4909FE34399190DC -:10E3E000D5B69C31E66E747D1954EFA5F9729A5F2B -:10E3F00007F6B70E61C2F315B64EDFDE5EB77A9D43 -:10E40000F72DB0D7BD94E05D09EB82380048EFEA04 -:10E41000D224227F6BA75FBF14EC77743DA7EFE98E -:10E42000F7D22CFA75F67DBE0A2855ECC9C3B93D62 -:10E43000B9B46E10DA995576E50DB0FE7876E5B68A -:10E44000C67570BAA7F88DE73F47569308FC51E1AF -:10E450002B5B6C1D383E8709BCD7AED017F025D09A -:10E460007795F802B03BDAD15F11447C85BC333339 -:10E47000CA6FD6551A62C63F55DB6C1A7A51F82915 -:10E48000A9FBC7EB8F29EF2C32FE5AADE6AF5595AD -:10E49000A75399FECADE2D5BCA6D001B567AFED8C3 -:10E4A0002B397AEF7984C91880F716E981CEED52BD -:10E4B000C54F0A7542C80E71795FD222C0A32F0DD5 -:10E4C000986EF80F5F4106D8594E1A90FF96F07B70 -:10E4D0004D59DD09BEC353CBEDA3D9676C5EF0FF88 -:10E4E000370A66E49F8DA7AC0190AB8D7603DACF37 -:10E4F0000FEF33215D5CEB65E5F68FA0C64EA2F809 -:10E5000073AE1D9B9304FCFF79EED77CFEBE5BD0FF -:10E510006EA9D8732589C2BC0384E9B07B9939CB35 -:10E520003BA3BD55B1EFA69A67092C8888F52F99B2 -:10E53000D9BA5225BF00F6F12D6DC43F9CB1191513 -:10E540003DF82F00DFD227C24638E72A7AB022AF43 -:10E55000BB37F438007110DD0B98396D4B83C10067 -:10E56000EBDB42D12831A3355EB5E04FEB38838B2E -:10E570001AB9B486C519B4E479BB5FF03883D167A2 -:10E580004FBF8AEFE999FD1F6BDAE5A75863BDD34A -:10E590003D7DF963D83E1EDE4F37B0F779F4DF13C7 -:10E5A000EC9C6F4B655DF07ED4DFBE9FE08E61C753 -:10E5B00099FED7D9F87B24F476B7E8F8FFE1C9A330 -:10E5C000FB26DBB9DF2F9DA4835FAD2D3FA67EDE4A -:10E5D00027647FB758F2491F67A78CD7BA3D3B978E -:10E5E000B5D43312FF2E1BEB3753D5EF283BD37F27 -:10E5F000A60B04E3DFC95704E5B4822714EEDDED72 -:10E60000B47CD83B67065BD1CFD324021FB876B267 -:10E610005757F4AFC739872AF321C4DF3B561CC7CD -:10E6200074788727C6FA46D8997C9E2E333F85702A -:10E630005F6FB40B4CB7980475DC7E6F65BF74FEDA -:10E64000D88396E178BF11ECF9B1E0A7F7D3F606CD -:10E650001FEA5006174F0C7C52FC820A9C2BB2BD5D -:10E66000D912B3A7E13DB5642FE39FC90504FD6B43 -:10E67000C3052FC263BC3D03E7B785C7C75D3BC673 -:10E68000E2598765BBF1F73C51393116E03A9A847B -:10E690005F35A8E2AD143CA97885CA638DBD31A071 -:10E6A000394F27723EEC82F72654F5DC4F000F8875 -:10E6B000CA81AEABCD9A7CFA321791547222D19BAB -:10E6C000A6C977F5B9AC708EEA5AE0D6B453F04ECD -:10E6D00089F7C39F6458B70BDF3DEAC0E7335CF0AE -:10E6E00023DE005F033BF202BE9F74BDF371BD05E4 -:10E6F000E16B6ABC51D6DBD6BA4EAF70232F3CBB60 -:10E7000082CE97F28539EB32CAD310EE2E02E78B18 -:10E71000732BCCF8FD61DE3EF1D959788F3671B597 -:10E720001BEDB889DEB2B7E09E4F62991BEF15CCA6 -:10E73000AD1404B0F7503E83ED36AF7061AAECB76C -:10E740008B960BB6E83BE3F1E4D75A7BBBE5D75A8F -:10E750007B0CF965307BDE06BFFFE23AD10D78B164 -:10E76000AAB003DAFD3654B3FB6E87EA58DCDD86C7 -:10E77000E94C8E28E35E79CD89F2E28AF2FB54BC43 -:10E780005FA64EC178802F5381CF6EB3F99FB7AB90 -:10E79000F8E586BAA116FEFEB246FED01F17DC7F52 -:10E7A00040DF9C007AD2A0B5524FA4FB1761BE6433 -:10E7B0005E78B0A527E0A9FF7D78A7F4DAC9CFD2AB -:10E7C00061FF143F9FE20754C651FC8482E0DF6E74 -:10E7D00057F1A9D67E40ADFF4A7498314E374B644D -:10E7E00071BA2A394B601F57813E48F16CD5292BED -:10E7F000C263D5578CDEE83C5F85710EDB8721FE56 -:10E8000028F294CE73E0BB243ACF524353BAFA9D18 -:10E8100052D53CEB6E3E4F5D1C2B9F97689770BEA8 -:10E820008DC4EA8179D51A3D27FD2067AF58D19E66 -:10E83000D7E8BDC302EFCD36923B2CF00E6DB5CDBF -:10E840007F14F643ECD6E4003DFB50DDE0BE30DF44 -:10E8500078FED8265BCE31A84FD7F7474847BBC2D2 -:10E86000D77EED8EAEEF267EDCF7A1FE3758FF5F38 -:10E87000BEC9FA4BE1F767300339EA5302E7BB7AC6 -:10E88000BC12EA0E7C01F143947E306E33904E82CE -:10E89000AB289C2A0630FC227309FFFD395A3CD86C -:10E8A00066F335C07C14BABB097C9A609D1B6DBEB3 -:10E8B0006648611E700F84F299CFB8BC7AD568881B -:10E8C000EA5149498C5F3525128CAFD1FBC913ED54 -:10E8D00053FE01ED52FBF80557FF6F84E792E3A664 -:10E8E000F00B615C84720F7531F87321BEAB466E1C -:10E8F000D0FE9E1D2D1CAA6D3E8703FC3839EC3DD1 -:10E9000039C02B78FFED26F0E8E04078F85320B5C9 -:10E91000CB145F002859B3D200CE8D666F2AF895CC -:10E920007697333834BEC3E0B0E7AC01F1F839D2A2 -:10E930000FE92ED3D0FC20F44FF9477758D7A8A67B -:10E940006A01CEBF1D8BDC06E0B35D9A3CA2E1E616 -:10E9500078DBD381FCDE7F8B83EDC352D887C1C7C0 -:10E96000987DE62678DBCF91F28DE03ED891D27E7D -:10E97000FE42F16AB8438557ED8D9B12F8FD497D43 -:10E980007FF43C84FE83037B4CC88F4A76B3FBA2A2 -:10E9900025FBCFE3B9BB64AF0991326FAF85DD7B57 -:10E9A000A861E557B263C70178E1978F817CA87EA3 -:10E9B000C4A395BB0166AFF436BB7A8951BF6AD256 -:10E9C00004768F60158F4752FCAB0E8E6749DD7C55 -:10E9D0005E902B49F904EF13386C2CAEB0F57D0135 -:10E9E00046B729BC9DCBE51600DEFAFB0329F09E55 -:10E9F00034F38F23BE8806AB07E47E5281AE9EAD12 -:10EA000000FDAF29BAFB06F31DDCFF6A2469C0478D -:10EA1000AA2DB1EF097DE650F43A2B9EEB243EAFD0 -:10EA2000C376237BE7C56EC6752F49244985989721 -:10EA3000509EEBFB69C12BAF41730F25A9C0AA798A -:10EA40006721C5D74193EF38A3B3A67E277F0F4D2B -:10EA50007997A27E9AF26E65999A7CF7E57768EAD3 -:10EA600067508453E77BAE1DA7A9DFBB728A267F60 -:10EA7000EBC6FB35F5FB06676BCA6FDB51AC291F94 -:10EA800050BD4493BFBDF6314D7D318E9EBD87C3D1 -:10EA90005954F46CFB103FDE3BB29B0593EA3CF704 -:10EAA0002CAF97ED284803FFF76AFB9834386F1EA8 -:10EAB0004E1CE60CC7E85749BFED396CB743D0D8B8 -:10EAC0005773B8FDECCA41CA45E0F7591CA27880DB -:10EAD000BFBFC9BFDBC1F5A9596EA8CFDFB5903C58 -:10EAE000B88EE90E33DAC5F4FD3FEB706BEC758A36 -:10EAF0005E2F1A3CAE42213EBC3E6B27BCF67E47E1 -:10EB0000F03AA18B1752CE6FFA76571DCC7E4AF998 -:10EB1000ED07C00F5BCE69A449F4E139EDB32B01D9 -:10EB200002FC94A0DE124F0F50C61704DF5FA11F36 -:10EB30003D3FF52D9FC7CE99062FDED78A777EBB46 -:10EB4000CAD71F3DBFE5CFC0FD48346AE0F4B71611 -:10EB50003AF76ACE6FAB1387E1F96DB5EC4D6BCF29 -:10EB6000F9ED6FC0938602DCD9BEB6ECA7D1E3669F -:10EB7000F73CB5FA4B6B7D9BCA3FBACE0DA0C709D7 -:10EB8000A0972531FD7B377B0F4019B71DFAB6E4FE -:10EB90006C87BE6D229EB59288FB657532FD7AA9A1 -:10EBA00045FC56FA7592F31BC8BFF7640FC6FFBF4A -:10EBB000374124F02ECBB582E1788F3A1E3E7EC0DD -:10EBC000ED2FEF39197CDBB25FBCB7A2E8A6F72FB7 -:10EBD000DE1BCBE22CA7E8DEDF1DE164783095A7D1 -:10EBE00014406887B8FCBA1DE3E52F8FFB107F6FD8 -:10EBF000D2E59AC14302F87BC23CCB20DE2660B34B -:10EC0000A37D6FCAD8A143CAED2A3CE2BF8F2CF77F -:10EC10008D771C60BF99B2AB674AC0161F7FA6F202 -:10EC2000F511297C0BC653BF79117F5FCD943DBD93 -:10EC300053987D511B9FA6B7FB4C595E82F8A6E402 -:10EC4000174708C6A3B5E42576DF787144C2F8B546 -:10EC50006ECE96F8F6F49BBD9BD65E78EABF2BF09D -:10EC60007C6FEC45766FDE125BDF58E1143476245E -:10EC7000FDBD9578F731E6F1FEAF158CC0FBF7537B -:10EC80008CEEDEEDB1532970AABF713E01F8C27E51 -:10EC9000B80F13A3FF879C8C9FEDF77E920466E963 -:10ECA0006C73532EE07F36B783C788D75F0A7434FE -:10ECB0003A52F09DC4EB3FE1D4C6EB1738195FD14F -:10ECC000C7EBB775DF68B231B67C9BC1E14EE1F7A7 -:10ECD00021D0EBD2CD32C6FBCDA7730880FD6D8B62 -:10ECE0008CF6B7F76F9808F841CE6F927F09F169FB -:10ECF000459B7B6E7E96E68BC69AD06F337F0B7BEF -:10ED000087848CB504C12F5BB4E5D1547857FC538C -:10ED10004AB78BA8D2347FF373180FF3FED9A7310B -:10ED2000FEFA22D033FD5EF4D593D301FE7B8C95A1 -:10ED3000B70DA2E9A29D82E6FE447195459357E284 -:10ED4000FE94FD2342F45E859BCA91979CDAFB53A7 -:10ED500083A3FEAE979CE8EF0A639C7CC904767F90 -:10ED6000EAD039767E3FD28BC50586C6DE5B388811 -:10ED7000AE636C0A7BBF451F4748C03906EFABF056 -:10ED800038DFB11F4B2DF75C58B9D796AFBA3FF0BB -:10ED9000D68A32DC97B13F637693B1192CEE3D6E83 -:10EDA0007C615AAB7B007D406EB68A2B8CDEEF39DE -:10EDB0001D0B6F0EE9E8FAD039164738EF187B3F84 -:10EDC000AB2DBEF9019FF7FB67FB3DF06B0A8FF798 -:10EDD0000B18177FFFC6DD6BF07D1A9F40209EF356 -:10EDE000FC8DD8F7C8529C8ADEE46FB96F03FB3301 -:10EDF000B560414B1EC8F21EDF239AFB38EDE737A2 -:10EE000037E7274F3AD93D4A3D7FD7E3FDFF29FE3B -:10EE10003E65EC9174B89F4FD397F09EFE2EC61FAF -:10EE2000F574AEE7E733747C30CAC70D9A78E319FE -:10EE3000C00786AAF9B911F9FCFF00D1E7EDCB00B4 -:10EE4000800000001F8B080000000000000BDD7D2B -:10EE5000797C54D5F5F87DF3DE2C496692C96412AD -:10EE6000B2336189A088C3BE457D098B51080EB8B5 -:10EE7000A1824E02216C21816A456BBF1948C08076 -:10EE800060635D8A8A76A041D1A20D8835D6A01331 -:10EE9000A5086A357EC5AFD62A0D82088812412D95 -:10EEA0006DA5FCCE39F7DECCBCC984A5B5FFFCE26C -:10EEB000A7BDDC77F7B39F73970914319DB9190B80 -:10EEC0000CD782B50A631BED7EB33395B1A1F66012 -:10EED0004A2163ACCEB921C13F80B1941476ABCF47 -:10EEE000CED869FCBB3C9C76D88BE2B0FEAFE2FC8E -:10EEF00076E730A8F75666114B646CC8DB4D8A1F65 -:10EF0000EA1F53D8B4A618ED4EC5991883FA5BCD05 -:10EF1000BC7C2BD61B102ECF74169E8A837EB7D94D -:10EF200020857A8CD99C07FAC1BC988925A98C9533 -:10EF300028FE4C1CB7D2D67E5F29942EDCFDBD0581 -:10EF40008AD843167FBA3614D69369F16ECCEB3A61 -:10EF50006E1F271F376D4911DB3F8431AB8D05E2F2 -:10EF60000633A6682C601E8CE3F8979AA0BD368DF8 -:10EF7000B155008F3D3037ACCFFAA59B581A633F8F -:10EF8000B131FA0B14319C0C0B7C161FAC85714E01 -:10EF900031FD425CFFBF987E11CEEB13A60FC0BCC3 -:10EFA0001CB74EAC533331FF9618F028772A7C1CDF -:10EFB000E6CBF739205FC4FC91F090A9CFA951BDF1 -:10EFC000C2876FCC6D87F2CFF7DD94CB20DDF1D017 -:10EFD00088A4F618F565FA8B9A6AEF38687A6F8D0F -:10EFE0009FD224C6749CCF9A9A39DE717D187342E1 -:10EFF0001EE7556EF1E52747F433C499CC18AC27CA -:10F0000071D4D6B65E40270756AB4EC503293315DB -:10F0100063FBFDC1A4E26D03783BB7A11D9FA70A66 -:10F02000E4C57AC3BAEDDA3FDA05EC4E335C2FA3C0 -:10F030007EBB5B67B9C09385796DD8DEF2D9553652 -:10F04000D60BFA537427E6253D8C8211901EEEC133 -:10F050004FA3605CC57FAB93DAE929B2FC741E8EC6 -:10F060005F4C79393ECB763196D13DBC98A2CFC268 -:10F070007E0E31BD1CD3664BE02227ACB7399ECD46 -:10F080008945CFF3117FB09EFE4E412FCCEE3C78E8 -:10F0900091180FE6F76482BE10FB3966F355637A68 -:10F0A000595647AD8A7413E714F5DB19E21DCA6F90 -:10F0B000C77296DECEAE06785F06935D05D9970FD0 -:10F0C0007DC63C00A7C48E03CC03E32722FE62C0AA -:10F0D0002D2199C3ED0F8C15C7E63B4E670131CF4B -:10F0E00046E017933BCC2F4F41BB2D0390EFFC82A2 -:10F0F000EFF4AB503E34FED2A5AC82F25EBAC784C8 -:10F10000F4E16E637A10E121E02EFBFFC469A17E79 -:10F11000910F9533F0E143E7C9878DBF9C648AC3A3 -:10F1200079DEC5BC7D3D58EE596683FC138B9DDEB0 -:10F130005590EFBD1A080DEAE72C89DFA042FDA02B -:10F14000E0A79E0FB26571503B6F5D8786F261D27A -:10F15000DD6D9A0DEAE7D5B56B289F5EBAEBD15C01 -:10F16000A4ABC39F5FA53AB0FF6F64FF0020E0F738 -:10F17000314E8E4336B2B427E2A709E79D1AC15734 -:10F18000F1FEDF22BF5F56DD31D60AD57297300D12 -:10F19000E5E561C5FFEB94DED86FFCB4E000442FD9 -:10F1A000A7B7970E1EE95F06F9ED92DF95A24C9680 -:10F1B000CE5841A399E059D0F8D02D08EF82C62B44 -:10F1C0003405AA3CA185140DD759AD6B01C8BFEB1E -:10F1D00034D3F8873F9FD753C1F9FED9CAFAC68006 -:10F1E000EF9BA2FF2681E7972DB1E97667A7DCE1C7 -:10F1F000FC34862952BEEE443A04F99AD81BE0B199 -:10F20000F0CEE3245F9F727A68FC27B4A69D993400 -:10F210002FE60DC0A7799BDE23792FC791F5E66F06 -:10F220005EBF02EB65DFE61CA47AB05D7B1CD2CF2B -:10F23000F7711C5FDFDF191F5CAA10FD0FF25D1C68 -:10F24000830F59C86A4A270CD878AADB4C2301AF30 -:10F250001D1D8528F7A0CB65C89757257B681DB273 -:10F26000DDFA0E673CF2CBD9F4C14181CF73A5C35F -:10F270003792B9DC0A74D59B47115EE7A1373B840E -:10F28000DE3CF16FE94DA12FA5FE94E54A32C7E7B8 -:10F290003DCE6EF5A6923CACABDE74B3E0BD03612F -:10F2A0003DECA8C9BB91751D3720E4DBD178DD9A10 -:10F2B0000C6981C27C386EE2D1CF98122187160B7F -:10F2C000BEDE2AE9C0C56E9D12631D95A23FD3F430 -:10F2D0000E4B3BF6D3A210FD775DAF85EA815CEC67 -:10F2E00081F3BEAC27C84DA5ABDC8C818F5CAC9F95 -:10F2F000F5B6FE3A12C9E8E4C60440FF99F0D10B16 -:10F30000EBFF2A4EEF8DEB93F01F7C5ABDD537A053 -:10F310002BFC2F1470BECCA1F7C7767F137CD61DB3 -:10F320005E4625737BE6AA648E97AD0E512FCE58AC -:10F330006F6632874B45B2912F23F0372A3986DD2D -:10F3400023E5F0D1785F0196FFE1D0D604A42389AC -:10F3500027297FA2F115E6B3A5341EC0793CB68FEC -:10F36000D63FB27DB41E0AB70FD0BCD7231D21BF34 -:10F37000211D79B89E583F203C3F49E77EB1CE1F02 -:10F38000E2F52908BFE8793A8F9A9433CD33B9C3AF -:10F39000AD20FF27EB4E4A5F3E6452705ECE0E4DAD -:10F3A000C17939857E8CD683202E045C793F6F0825 -:10F3B000B9B1E2AB99E988E71585FEF46AA83FD9AF -:10F3C000A1CF4238DCE3D4CB717EA50E7D36E64F6B -:10F3D000C571FE1F95ACCFC1EFC9C28E8A9E67B5BD -:10F3E000C01FC0B30AEB258E6301D487979FB40773 -:10F3F00041C4020860DEA01F12756711EAB1C4752E -:10F40000CC8B749A92D0D16A857CC743CCBB01F275 -:10F41000F9018FC98AFAED367D19A62BBE52C9EEC5 -:10F420005C51C882CBA81F6E87B2BA5E41D2DFC0E2 -:10F430006F91F4BA4CC079593297736087D42473B2 -:10F440007E5A9A1C6187483EEACEAE88E0C3FAF342 -:10F45000E4C35FE078E7C1870F083E7CF05CF8F01A -:10F46000B1301F3E8AF5CFC687CF083E7CE32C7CA7 -:10F47000B85BC0ED5D513F061F3E138B0FDD821E52 -:10F4800024BD231FA2BE0F2577CACFDFC5A2F77305 -:10F49000E0CBE6E473B00B3BFB3B47FAEFCEFE1B41 -:10F4A000E33AB3FDB7C7EEA4F5487E067E793399FB -:10F4B000F48EFE16C205F8E56DCE2FB1F9AB53DF21 -:10F4C000747039C1584302D28F9CE7E702AF00AF96 -:10F4D0000FB01FC967D24F91F0EBA40761F71E155B -:10F4E0006962C7670CE502C06D6F24BD3E25F82533 -:10F4F000309211BF8047558476E54B47C18E44ABAF -:10F50000CFC5E75BB0B6ED756475A635244C757450 -:10F510000FA72217B773BA83138C7F2C963C6D41CB -:10F52000BCD9BBDAF3D1F8FA44ACC7E952CE88AF04 -:10F53000B3CD43C20FE77109CDC3635A15A1E7CD1F -:10F540002E45F2B7E682F4F2711D2AA3798512C026 -:10F5500085EA94A72C1BDA0FEDDADE1E6E6F77C1F9 -:10F560003C2FD7A1FD80707B189FE45DEFDB409EB0 -:10F57000919DAC9B503FADC8E3F4104DF78D683FB3 -:10F580000C88C0574326E1EB3E9B3F13FB6FD43CF6 -:10F5900026B4EB1AEB9D4A80F0581D8FF463B7EB4D -:10F5A00044B731E490C7757E72A88F8BCBA1BEAEF5 -:10F5B000739043035C9D72E822ACEF3C8B1C1A23D2 -:10F5C000EA17B8B87CE94E0E5D26EA1509F8C69030 -:10F5D00043635C31ECB96D369DFA8DC1A79763FD2D -:10F5E0004CA7AEBBB85E2B7445E835683716F3F709 -:10F5F00089F6AB1B4CFDC87E66F1DE587E86CF6572 -:10F6000037D829970AFF81B5FCF3F7770D67AC0A65 -:10F610008BF83C7DAED4B03FD1D8F0591AE21FFE32 -:10F620000C7195079679DFED83787B476568873E97 -:10F63000F03FED168477737CE240764978DCAA7F50 -:10F640000041A6005EFE61A254E27161CBD2210CA2 -:10F65000FC88C2FD3FE4A25D796CDF3F283ED261A9 -:10F660002FF3E3F83BB6F338C989B767A6A07D2E20 -:10F67000C75F8CF882798D5707348560BDC777598D -:10F68000BCA86F55E6F95501CCA76A979905494E74 -:10F69000311BD637F3E932F3AE156D6A22E6B58039 -:10F6A000886F28A7C99FF12421DD9A77A90CF990CA -:10F6B000B9797980D9969E067F3369A4897922E247 -:10F6C00021C97A3CF344C427528A5D867CAA2FD391 -:10F6D00050BFC7B45E86F20CFF8586F2AC39830D4D -:10F6E000F99CEAD186FA3DC1DF89CCE705AE32D478 -:10F6F000EF5D3FD590EFDB7093A1FE056BCB0CE582 -:10F70000FD83F30CE515BB9FB7A05F7DD1A6C58631 -:10F71000EF1737DD6568070069EB0374328B71F80A -:10F720005FD2BCCC507F56FBBC4948B78342AB8C00 -:10F73000ED1ACC07383C030CE1F905F35B90CE34AD -:10F74000D6B1330BE0BE30A87843506D6E735E6F58 -:10F75000E4872FDF2CDEA50C8479ADE5ED643F73E3 -:10F7600083C6FC7C7533F14F349EAB58AF24CF5029 -:10F77000A40395059530DEE76F32B66718EF827601 -:10F78000F3C57AA2E9E20B56FD7001D247406FEB58 -:10F7900093165EB799350D0FE17741274E412772D9 -:10F7A000FD72FE72DD4EF80FCB41E15B90CE663705 -:10F7B0002BEC51A5EBFAE6B4DCBF222BC63A190BB1 -:10F7C0005AD0DF8E9EFF0E97C37D3001FE91CB7223 -:10F7D000316EC5BAF0879DE4F1F1756AD00A74AD57 -:10F7E00006FA45F18771FDD1703C5F7EF10838580B -:10F7F000D38DFC12E7898FA6B7E121D615AE09FD9E -:10F800008C7C24E128E1EAF066C6A42B0FFCC7E15A -:10F81000ABB31F13BE1D08DF8BC2F03D66F39F40E4 -:10F82000397CE2A36F55A23B7FFB10D463DDE9A5D1 -:10F830006447D1DF44FD5CAC5F9500723109FAF991 -:10F84000EC877CE4B74EB9BCA4CC3B0EE4A2A2F892 -:10F85000594A6AF87B9BAE3A8602BEE637AB5ED465 -:10F86000C3C7347BBD72092DD3E34C43252DF1C6AC -:10F87000F128F1A6B4BCFE7705E0056DFC168CBF3F -:10F88000167B6D384FC6A6539C5301F7E67402E908 -:10F89000D9C414D2BF3AA3F8DF71E6AD85FE6A1D64 -:10F8A000BFBFE82CF110570AD90FFEB478B43F3A25 -:10F8B000DA4F3C87DD6B6D4E1C678ADF4FEB198199 -:10F8C0001304BB9A39014E11F12268978DE34E79EA -:10F8D000FC9709680FBF74E0B84AFAE51337D9C33B -:10F8E0004F315F7F940F5DEDEB00E93D69AF837FA2 -:10F8F000D43B85DBDB7D5322FDA34EBBFACCFD80E0 -:10F90000DDD10FED99EE52E53595F4698712EFDD03 -:10F9100010439F8E4C31EAF94BC3F1B8912911FA8B -:10F9200073E1ED2776E23C00DE63709E0E07D8356A -:10F93000CA39D93597633FBF4A4824BAEED8AD06D5 -:10F940002F8006C76D9E2417DA9142CF2A1AE8103D -:10F9500057843F6B730DD0866079FF2416C34F9197 -:10F960006911D64B09E75F8B33FAA32B06F3794D68 -:10F9700011EB5C29ECA7F2146EE754611C2E251CD8 -:10F9800087AB9AC6E3CC0F45C52FCB531C547FA53C -:10F99000BDA81CD7BF224F21BB6985A218F6915282 -:10F9A000530ACB71BDB78AFECBA16F1CF7A95E7C51 -:10F9B0005EEE28FF3D0FEB0FC394F70B9CD41FE9BD -:10F9C000CFA2AA31E1392F45C4B1E399B4BF896F01 -:10F9D000260ABE9920E4E5957D415E1273E993C63F -:10F9E00043F93851CED4757BAC503EF10233433AE3 -:10F9F0001B877209E5BCD3FC597BBFB09C9FD0AF7D -:10FA00007A078A872BD2E17B843C2966BE2CA483AB -:10FA10002B3DC6EF13F74C388CFC3A9169D40F7D1F -:10FA2000CFE3704D7085E97D594AA7BCF79C06BEAF -:10FA30000EC5FB1F28C1F8C39F54EF066AD53624B4 -:10FA4000D22FFB85C0DB6AE1A7E03E12FA1F2E91A0 -:10FA500046C3E717293CEEB0DBEEFB05C2F3214BB2 -:10FA6000DB4F70BE214B7B6D128EF301A37132E729 -:10FA7000E8AD981FE6F3308C13AFC863762FD2E75A -:10FA80002013C541DC7EE7380BE4DDEB14B4849928 -:10FA9000596301C7E0B05C684EC913F3AA6D4D828B -:10FAA000FA49EBBE61BDC87F708E73A21C9AC56215 -:10FAB000C6359F167431E5F15E1AFA614936450F75 -:10FAC000C658C7D302CF201736E13A2EB7ED1BA296 -:10FAD000907EE07E07BAB2F47F074CC18D4AD7F61C -:10FAE00076FBD8E7900E251D5FAAB2EA2D764E5F11 -:10FAF0005322E458B3A4A7738C470F9BC362C64D2F -:10FB0000DF17782AB7F95EC1F90EDBE3A1FD8E0A93 -:10FB100029EF679998067478A320C31BD7B5FE9D7B -:10FB2000EC8B1F4E9F56A5DDCEA87F86FB0F150BD5 -:10FB30001C41DC8FA868C90B50BC698E42FB245560 -:10FB40002DEFF9305F3174A893E46482A21CEC4776 -:10FB5000263FE37251630725FDA90248D0FF34A177 -:10FB600067409FAC4E807555AC5BDF9A01457F01C5 -:10FB7000C301F1FF9089FB7FD1EB4A8BE7F059314C -:10FB800005FCE04128764FACDC918D78AEBE50F19B -:10FB900082B1B2F4F8EE5D978AB85826961FDFADB1 -:10FBA0004B3F3293A61162309FA7E23BF3BA2D9DE3 -:10FBB000E481CC0730DF88CC361AECB5078EEFAE87 -:10FBC0001B40F44B7A8969200F2E0EF3FB47AAFFE6 -:10FBD000A39FC1BAAF0365BC6430A61A9B4E784A96 -:10FBE000A7755E2BD619F807530EDAC270B9AE6549 -:10FBF00037C1FB23338C07CC632EE2A031DF954461 -:10FC0000FBC9603FD03AAFB7358C47BD7ECCD2310F -:10FC1000D08BF184ED1FE60460FC4F7F7EC2C18073 -:10FC2000EEFEAA7538F0FBA1BBDF77E880DF4FEF6F -:10FC3000568B917E6F117A52C22DCECDE9E166B717 -:10FC40008FB9511ED69C1AEE8F8C0B2D4925FD368F -:10FC50003708338CB097E66F4A400BAE335FD994C8 -:10FC600062C84BBD576965D5B1E2A097BA39BEE607 -:10FC70006E5E6FC9F2E0F87E178E7F08F40BD2CD6E -:10FC8000A16D8E20FAEF723E659B0759D09EFA6BEC -:10FC90008B9585D03FD3DACCCCCEE5A602F4EA171B -:10FCA00074193DCF9DAF24507FE50F71395B0A6316 -:10FCB0002D01B8FA5BE6923C8D5E47F9A79E093D9F -:10FCC00000DEE52BC172F1F0FA7703DEFC4BEEF9B2 -:10FCD00006EDD3E87596068CF27566BD312FE57E8C -:10FCE00085C037889B7AB4F3CB1B8CF52A5AEEA5D6 -:10FCF000FE2B502ECBEFB0FE216E61170E67235006 -:10FD00000ED7DA7B25F9CFA0678FD680419ECFD85A -:10FD1000911A1BA5876A18A5CCED217C2C6879EF78 -:10FD2000A748370B9BB758B09FBAE078279033B3FA -:10FD3000B600C7A33D8DFBE3D07406EE8FC33C6BCA -:10FD4000712219B87FEE1BEF067C999D51FBE5628D -:10FD50007DD305FC99DD45F4351DD73310BF6BDF2E -:10FD600046AEE7F8AE21361C77B25CD70858977AD2 -:10FD7000EEEB92EB91EB93E595203763C90549DFF4 -:10FD8000CCCDF5CDACC6292B320114B5DBBFA038E4 -:10FD900000137E8826F0A3D957911FA231F033F8C3 -:10FDA0003AB91F12607B58049D45D35105C2019991 -:10FDB000D8C9DBD9847FD2493F2D6B081E12CFD022 -:10FDC000613ADFB70CA5E3BE25D0D181283A32E4F1 -:10FDD000CB1B8CF9AFCDEDB9C8DF402F0722E1FB7B -:10FDE00075D4791999CE70F7E2EBF7E8139C505E61 -:10FDF000CE7C2B9CB4FE06E2C3435AC3CE9F21DFC8 -:10FE00003572BAFFABC0FBC76E5F2DE29D69FA4049 -:10FE1000946F45CB325437D42B5DAD38919F66D665 -:10FE20000D9A807C3898E9D4DF8C6EECCB8D02FE85 -:10FE300065D5666601E3A0CCC348AE956D53833C9F -:10FE40004EA7DB4B00BE73041E2A576EB164403AC6 -:10FE5000A7BA82DB3D41CE2F0057B27BE6AD6EA53F -:10FE60003802F85131F94DEAA9CA266379155B4D7C -:10FE700078A88AB27F82921EBDCC8BF4E8FFA9C31A -:10FE8000A6249D7DBDAC6B9C88E248C777F5257B99 -:10FE9000F8B8C7D303EBF901E76D68E76BFE11F81B -:10FEA0001DE044FAB263694210EDFD7D27C18F4524 -:10FEB0001BD4E91F6101B8B47F9C437A5CD2A75C74 -:10FEC0004F956D35D1671533FAC9A5E09061FCB740 -:10FED00074634A10CF0340FF039BD18EDA68263B40 -:10FEE00029C016A733A033DF7233C9C3B2E664F268 -:10FEF000D3CBEAF8BE51D9E6E4A0CAE30F7B30EEDB -:10FF000022F1B0AF6EAC2583F094E745FDCB9ACDDE -:10FF100006FA96F889F673E7D5B7EE4CF7741F0723 -:10FF200089C0CF816EF07320123F7BA2F0C3EE4EEA -:10FF3000E17266D11FFBE23ED9F1EA38AF1AC36F16 -:10FF4000927A886503010E0FC7138B33393E98E60A -:10FF50004D437C9E583D8CF0158DA7E27FCD247CCF -:10FF6000B08F1D0CE3CC337AB35BA7C2F75B15CE21 -:10FF70001F336AAF2C467DFD959033EF827CD22DE6 -:10FF80008CBD07F24907F9F43EC82DCC7F50934E43 -:10FF9000F90F6B3C94FEB9A61FA50784DD27F9066F -:10FFA00008C08276E309C12F27A4FC62B7A5A3E9A4 -:10FFB00050FCAFF7879930741BB8EBAAF160CF5CA7 -:10FFC000AD1BF5DDB46B8DFAACDDEC9C908E76EE5E -:10FFD0004A85F653CA7C630CF599E6B14C417FBD66 -:10FFE000DF90F077B25F3D96A9C0EF374E4A31D42B -:10FFF000BFBE3ECB904F48F5D0FCA614F7367CBF71 -:020000021000EC -:1000000069FA45867CE94900C210A46617E1E13629 -:100010001B13F104178FF38AF334DF568FE871074F -:10002000CCF7DBB7CD541E8D0F89D7596B4DCC0F54 -:10003000539BB916D606FD1E68003C41BB2F3F728C -:1000400030A4E3159B87BC3312F2FB369B295EBBC1 -:10005000AF2EE53EB48FF66D4E4DC438B07F852A85 -:10006000EC08A78545C8ABB1754BE99C4D69D0EA52 -:10007000257B6147E00999F728C8F78CF3CB1E353B -:10008000887139C01F8F673C63A57D884360B7398D -:10009000412F1C52581DA6A85892A0FCBBB6D420D4 -:1000A000F273F1BF543D1DE9E99938B1CFA4507FF7 -:1000B00047DEEBBB6115D197A729447C6B25FF6711 -:1000C000663B5F1F53066721FE0F25333D192651FE -:1000D000B9F8C3BD1AE0696E7EDBC010B49B9E17F1 -:1000E0004ABD01DA1D6D34D3B91BECD709F9CADF5B -:1000F0005AD77339A2F7407F220CCFE0405CF70C4F -:1001000093EFF254C0DF91D9C18124CFEE4E25BECA -:100110008A86FB018B9FE01B403E50C2F231CC67C8 -:100120007CFF10845A06CA9999666F1AEAA703AB36 -:10013000CD647782FE48C4F119DB4A747C40F34CED -:10014000C0751FA8CF6328AFE4B865AB55F2B39074 -:10015000FEA8FEFDAA1F6C0426F554A05EF1B31E96 -:100160005DE9E6278B46F4C0F544DBB732FD1A782B -:10017000D51F612FCCDBAEFAD03F6243DBB56B2FCE -:100180008E5C471DDFB748E7FDDF26E4FA825E6F2D -:10019000ECB59B50AEF74E42BFE7F01E95E8EC7011 -:1001A000AF86E1E9BDF178CC6BC3EF80FC97258188 -:1001B000831AE49FB0FA17205CE79B563FA140BB2F -:1001C000632DFBEF1B03ED8E3C6BF6E2B0F39E99C3 -:1001D000DB93F619847DDD556EE9D23E4853D2D1CA -:1001E0008E7092DEF6D4C120B4FE20CDF366D6B474 -:1001F0001CF1E65CC0BFEF1FE65885719A99C01EDE -:100200009176F77E33B70BFE2795FBB552BFB7A4A7 -:1002100072F932D3C4E99ABDA2909F8AF64E9F0824 -:100220007D2CE5F29A546E4774EA65D644F26A363C -:100230009EDB81F52DD8640D06F3A88D13F97C2E75 -:10024000470FDB8D7202C69D6779F661E4A10AD67D -:1002500046FAF3883938BB2D0FDBAFAF73517BB350 -:1002600097E2C5429FD88081501E5508BEAB6C50A6 -:100270008221E21BAE17CB45FF0CF54C84FCEAAAA9 -:10028000578CFAA45CE8D17216156F6E30EA375FAE -:100290000277E2E7C1B8A82FC3F302FB186036DB90 -:1002A0001FDC3999E6AD788331E651C13A422ACE56 -:1002B0007B33DF77889E57F43ACE759EB3BD53C625 -:1002C000250F8D18376ADE12DE14B08EC08384FBD2 -:1002D000EC0087E7EC1685F0F5B9B0CBE4BE8BC433 -:1002E0007B05F34DC6F384150F82BCCC0BD341A71D -:1002F000DEDF12A4FD952F5943A21DE87EC1DA2D41 -:10030000D78FC276EBDE23FF62BA2BD4D794CC58BA -:100310004AE0F355C53931F655A2EC831F0B3E3840 -:100320007B6DB86807F0286F54F5B881867AD45E83 -:10033000DA077302010BC661E788F8E6D9E659854A -:10034000F5069FCB7C63DB33FFE9BCBF4F15F1B9EA -:100350002EF650DF987E54A71D7416FDFB89399444 -:1003600083FAB7234723FDF3ADE6FDB0D08DFAB88D -:100370002FF905DDC9D7D9420F97A35E86F4E0DADD -:10038000E713D16FFFFCC1E7693FD7F26C7922DA3E -:10039000C507D7CEBC2F002C7570F34CD2C3158F78 -:1003A0004A3DECB744EAF7B16B4B7FFD73A4CF4DE8 -:1003B00071B41F317B875FD8DDE0B7A01C5CAB3028 -:1003C000D20B0F72B95781FA6A00E9AB0BB0DE4F5E -:1003D00067FB2F403A8FF84E7AECA733FD23A83DF8 -:1003E0007386D0EF02C919427D25F5A9D4B39AC905 -:1003F000DF270DE1A5BEFDC19DB0FEAFB6AAE4DECC -:1004000055AAEB739DB8CFD18DDCFEF7E16DEA8480 -:1004100077DE39C0BB0CE14DF60F87F767F51CCED0 -:10042000FB5773B8AFD8DC3B11FDDBCFEA7B93DD24 -:10043000F3D9E6BE04EF59AB00DE64F77A8C764F51 -:100440003DC01BED7C84378C5BB6C323E0EDE5F04B -:10045000AE177A67354F6775816BE01694273FFDBD -:100460008DD58BFAFC505C2815FD91435B5486E7D3 -:100470002C3AED2261BF48387FC71A9E403BAA8BB9 -:100480003D73BF95617C76EE0B8E2083FC11A5B089 -:100490000722E068C31B89385E78FC4E3B665ADA57 -:1004A000B0083BE61CF1B390F9E81EC2C296373E95 -:1004B000423B5ED1B95FBFD0660F21DF82BF73348C -:1004C000529E2B1E94691827F1DA6C4807D9CCE3A9 -:1004D00023BB46EE77F919EE777DDFF79B5B1613AA -:1004E0003F77E447C6C9ABE243668C2F756C510871 -:1004F000DF95B715261632DC4FABA679DC9EC6F524 -:10050000B1A2EB1437B402DDC4C3784BD23C24CF84 -:10051000158F93C711D7C1B88EF07CA3BF4F46D2B9 -:10052000437D6E8F1D77DE98C6ED804AD5447EC729 -:10053000020BF73FE47996E5621ECBD3B81F726FCA -:100540001A3FCF770CCF8340BFC72EB58AF3D9E3CC -:10055000289ED9193F9170736A5F77CA2BE42BAD3F -:10056000231BE1B477F47B66946B7BB12D19D380A8 -:1005700080E168C7F0F6EF98EDF56857DE3CF20DC4 -:100580008A83EE8DF379D0DEDA9B6AF3221D05B6FD -:100590005B89FEEE89E7F16FE64ED2909F6E12F214 -:1005A00076468155C720EFCD05F7F830857102B842 -:1005B00009B1A2F0F5E54847B7A6EFBFDD064B5AF3 -:1005C0006AE2F6CA5217A373409780B98E71583CFD -:1005D00022733AE54C74638C5B2FC0F8EC68C60953 -:1005E0006A24C1D39007B852FEE587AF9BF8603606 -:1005F00063FFCB3C17239E17204C900E4A93C8FFF5 -:10060000BF1AE3C42E4C35A2AFA91A0B98785A8FA3 -:10061000213519379E2CD679DD48164A82F5857624 -:1006200033435CFD8690297401C0ED6A2DD48AF0B5 -:1006300033D93C66F4037CC5CA60F48F172C3BB7F2 -:10064000F9BEF3B07FE283059037F1C38B1D772AA3 -:10065000C10D00A79B81B9912E6FD1D80E7530C7FF -:100660001BD25D95CB13A07A8B14B13FC4E3F91272 -:100670002F83A0FB48F8DE2CE607FDD427627B4BD6 -:10068000ECB8D1C769D2FFE576E67CC1A7F3259D1A -:100690006D36F2E73F249FA03D0B70BB59A4DDD11E -:1006A000F9DF44FF7F1374FEF9798E576965215A8B -:1006B000F7762BE1518E7BB548BF4BE3F6B29C87B2 -:1006C000A45F26E24F2690184847071A6AC95E9A27 -:1006D0001315FF6591712A3556BE53EE984E636A25 -:1006E000E99885F3512E8B237EB9D9D2D4B7DADEBF -:1006F000B51ED8D184A24ABB8DECBF85AC9DC7B3D3 -:1007000084DD2FEDC5B968E761BCB291DBB59AB065 -:10071000C74BC13F43A22BAD8FB077E17F939BB70F -:100720008CC7783E18267EDAB7B0DBE8DCC6E40575 -:10073000463BC92CEC2273945DC4A2CF85083B29AB -:10074000FA5C882AF817EA727F459C0BD184FDDB9E -:100750004947696681CF80611F7E3A6B33F3FB6244 -:10076000227E27F4F378D5DE0FE5CD7425DE8BF6F7 -:10077000FEB14247C09484F125338D371DF800E562 -:10078000C82771FC7CC58CA49F4E463B787AA24555 -:10079000C3F45367AFA41B18CA1B55EC1B0527E213 -:1007A0003E532DCA4D9EBF57CFA62898C86F7C0BCD -:1007B000F767AEFD01E64BF92727EAE0BF1DFBA373 -:1007C000280F401EE975B9E4DBDFF2FC43B2FC7789 -:1007D0003CBF52966FA3F18EAD91FD8BFCFD51E5B0 -:1007E0004BA3CA1FE1F9F13DB64D0C207CC4BED32A -:1007F000F4D10AED3BCD41BE02F84D5F16227A9A44 -:100800006E7A8DA7452C84FB8E67ABB7A8876F0ED9 -:10081000EA67D571C081F6C99D19FA1CB4AFAE4D17 -:10082000F5FB7AA05F3845095870FF714F305FE8DB -:10083000AF98E7E7E7083E5D98EEA3F6D2DE857E47 -:100840006EFC77FA39D5A34B3F653D52CFBF9FDD94 -:10085000E97C7D11FDCCFF77FA1998619C8FB4FF7C -:10086000DEC8D457E0FAD801B7E15CE4FCFFF1261A -:10087000A1FDC8F05C24807EFEB2A6DC21D0FFFC86 -:10088000E75ECA9D1D115F5878D2C474B013AB4E99 -:10089000324ABF6CFDB3C503F359B8ADD53201EA96 -:1008A00055413A36625E0BE4B960D6AE4D8DB05F0D -:1008B000EEED6112FC743FBFC7F5DC61DA3F9E6F5D -:1008C0006A3AF828F2E3681E678C5EDF4F7AF0FD23 -:1008D000BEBD783E20867F727F0F6E8F6CCFD61B99 -:1008E000709D8B5146423AB636F6F98A8F457FD3D2 -:1008F000E3B93C9F39DC61F35C82FBD9FE5ABCAFA3 -:10090000377B5DDE608C57DF915AF4688F33C67F8A -:100910003B78FCB785C77FA7BBDA6E0365C53EF899 -:10092000D5FBF7DAC05F9DF82BD6B91F8C71D56265 -:10093000ABE4BB2313C715503C8FF2CD3D0EDC1B3F -:1009400080F6BBE2F9F99119232E8E4779D09E9754 -:100950006072829C08B84B3FC079CC1871E904FCE6 -:100960005E6875E497F2FD03A28B80DBD784EBC64B -:10097000FA18BFF15B783CCFFFA64AF13CFFC004F8 -:100980007FACF307CF09387CD083DB67BB00CD6831 -:1009900057C979C8F1C120BBAD0DFA3BB02C63102B -:1009A000DE8BFCD85DB887E022C6FFD8ED6F8D1CCA -:1009B0001F963B10BF9FEB3C5E1174B147E0CD57D3 -:1009C000A0323D42DE4F1D9760C85F3B2985E9910B -:1009D00071E56BB30CF969D37B1BEADF34EB22437F -:1009E0007989B56D68F579D8F9550E473C9E6FF851 -:1009F000B4E5BBFFBB19EDD746D5ABC07AE66EDFD9 -:100A0000F87F63A0D6713C364CF6A887E27B47F0AE -:100A1000BC21F29EA66B91FB525FB1363AA719B189 -:100A2000EF61D85F9AEFDC41E7447FAC7DA9133DCD -:100A3000C4BEC7603C628E7AE8835C3C5FB2D0CEB5 -:100A4000D7F3D54BFB2C74BF03F507D0F715D8505F -:100A5000453E0F50BC7D6CF33EBA47F7500F2E97C2 -:100A600017662FD2C002655590A2DC9F00F22909BB -:100A7000E8A3AD955DBC0DCF57E739E83C4CE5C91F -:100A8000A98CA5201D05062C827AF3EB8B29BFF0DB -:100A9000643CF5FBAEDA3681CED1BFA8D0BE484962 -:100AA000D68C65682760FD9FC07825BFBBA218E182 -:100AB000B3701B3F3753A2FEEF50EC67414331B593 -:100AC0002F51D92E05ECA18963B97E2D415B06F229 -:100AD000EA70C72AD4ABAA2594FF18CA138B83E403 -:100AE00049D2C99B68FCAA93366A9F95CEED3473B0 -:100AF0003B9FD7F8933EFA2EF19E97DECB70EFD353 -:100B00009CDAA895D9B13EA3FA579DBC9052B9CEB4 -:100B100037FBFDC68D72CC9CFAED043C27FCA65B2E -:100B200071927915256F4F548F486231E4914CAD25 -:100B300042CEDE7C929F43EF95A98F4887794EBEC7 -:100B4000BB5DC37D2A66B739115E93470EF2CC8E2A -:100B5000E023F5B51BD1336056778719F5F9CD90B1 -:100B600046CAE35BBB91C797A69B0CF776A47E6150 -:100B7000C11BC9FEBE45DE53167C72A1A82FDBB790 -:100B800091ED04787CC14A76D4984CBF2F1DCADB06 -:100B90000AD9B4AD241FDB72717FE8C79A3FE0D950 -:100BA000A6903FD34EF730268FF498D03EBC2EDD72 -:100BB00064B0D3CEB68E2251FF5D952D417DF2EE0D -:100BC000E597B7E9D05FEBCF860C41B92FC79D9D64 -:100BD000CEEF9D3367C70FE8B756BD92E041BE2EFA -:100BE000C1BDD6A161BB1DBE338C7356BD62DD8015 -:100BF000E799AA12C16F87F1C7BE1A17423A6E7DF4 -:100C0000354E43FDF075B67F36E273ECAB178CC3FF -:100C100073747A8B556364DFE81508B7EEE67B36AC -:100C2000F9144D67922FFDF59C5F4A059D9609FECC -:100C3000F30B3E3A51DD83F8F0C4DD30695847D9F3 -:100C4000DDCAC5DBD01EF038E81C96E4CB12F4F305 -:100C5000E07BC945C9E4EF46F01DF1E182934EEA1D -:100C6000AFF2A447F0B98BF292DFCA04BF48FAF69C -:100C7000093BE26799FE87111E25B5C0EF787F73A7 -:100C800059C650E4A330BD589C4857402FE9B323C0 -:100C9000E8A1B615E8C541F44272C8076924BD5CF5 -:100CA0002DEF1531E7843498F7E4BA3CC3BDA2C7F1 -:100CB000CE93EEEB05BD94D9437DD15E3557C77910 -:100CC000F19EE47137DF875ABC92C36FB1D93716F2 -:100CD000ED87C58F285EC00CD915288F867F546D8F -:100CE000898CABDE787220F3C0FAAF39D987D23B5A -:100CF00052FD4F231C4A4F5E2FE035F0DFDAEF1C28 -:100D0000A6F3389A3968F5AEC7FDC438BF8AF83DF6 -:100D100094C39C0F44C4D130EE87F13FB90F2AE34E -:100D20006A56DC378ED093DF690DB9E8E77489AF76 -:100D3000151AF70B17B4FEEF7013941FC9D329CE01 -:100D400036C3E47F1DE979DED4E07366C8CF5FF374 -:100D50007C22C6F5253C9BB4505FD4934D00478C54 -:100D6000F735AD568B83DC9E49E0FB7C9CAE251DA0 -:100D700047D3F7BC93BD889E4E545B49EF9C007AE5 -:100D800065117A275ADF483AAED498F05B93E8DCD5 -:100D90008894FF617DB3FEBED148774735A2FFB08E -:100DA000BE99EA2BE4F44FE7CEA3E9FFC59A743A63 -:100DB0004F24F548B4BE8996EB525F7D92E1FF1E49 -:100DC000E154F4DB7F3EFF317CBA4AE37AEB2ACD73 -:100DD00041F4F3DF92FBFF3C4FFA3F2CEA83FD4ADC -:100DE0007621CAF5C8FEC66416256640794A06D73C -:100DF000ABFF6D799F92717EF29E65F0F99F4DDE9B -:100E0000E76770791F2DDFF1A222CAF763DBFBD3FE -:100E10003EFC5E06FA00F55E4B8267A390FFA41FBE -:100E2000E293826792FFDBB367E667C496FF1764BD -:100E3000FC07F2FF7CF944D26F77FC32F15E6E9FC3 -:100E400031B4CF9448FB8CC365D7855C0F44D86917 -:100E50003C9E027CD55789E49B0DF78D46BE39E652 -:100E6000F6E25940C927926F24BFDC2CF8E356A163 -:100E700017247FBC9AE1BF11E125F963C1D668FD53 -:100E80007066FABAD95DCD503FDC0A69247D593BC2 -:100E9000F583912F6EE9A4AB73E38B4919E766479D -:100EA0002CCAE0F7DCFF8B74B508E927065D2DFE40 -:100EB0004FE8AAABFDFAE150BCAF766228D0515E94 -:100EC000988E26BEC5B8DDD09BDBFF9D7462C9A19C -:100ED000B8CEC4D3FC1CAFA45389DF68B9F85CA6B4 -:100EE000EF61C4B7F41BFE5BF2EFB1F3C4F3CA7356 -:100EF000C4F36681E71FD15E7C31165E99D36588A5 -:100F000047007F5F43765C48A32341DDE1D5BC9673 -:100F1000F397CC2F0F6952EFA6A0DE057A69FE4F3A -:100F2000E8A5642C13F18D4393304E39F11722CF8D -:100F30008E4E423EBC7EA42C3FBC5AEF837286C9C3 -:100F4000FD038A8FBCAB8A7CE0C8DBE3605E131FC5 -:100F500060E1FD05281F5F90D4194F41D743D6FFAC -:100F6000F0912FDE5E4DFCCCCFF9307FBBC6F7D5BC -:100F7000447E28E41D11F99151F975BC7EA2D6CEAC -:100F8000F8B9CC20D7032A6E3572FAF145D82580FE -:100F9000C909787E62F236C589F1909B0A8ED1FE2E -:100FA0007378FDC727E905B82FA888FCF76FE37AA7 -:100FB0006FDAC6F3A71EF9C7EA8026FA4BA37819A1 -:100FC000FD599B145DC5F320239560AFBCAE703E08 -:100FD00015A5F7F04F33B66778CEEA7CDA239EA9E1 -:100FE0007D2F6A1FB29EC7F83714C4BE27E2C8140B -:100FF000F5445C81FA07585ED314FB1E4CAAA8DFA7 -:1010000086FB4504AFA43508BF368B8467E21AA47B -:10101000A7F18CE77B3E9A581218C0A7AF47ADFFE7 -:101020004CF35732BBAEDF636C1F3A13FCAC5DDA96 -:101030000BFA9963A4A724CDB7E304CC23C9AD3838 -:10104000D13E5EE88B5B8D7E40983E324A703D6DAE -:101050009D71FD68FACF2C41FA5FC864FDEC35E460 -:10106000E7983AEB737E90F405EDFBF1F7F7A8FDF6 -:10107000A847B3D6207C003F544E79ED0CFCD01429 -:10108000952F88E21F41FFC4BF28E7013E7D63C85A -:101090009969023E5F8973E46D45DC5E6C13F7E28B -:1010A0009664F238AD3F93DB637324DE23EECDB05C -:1010B000083C3371AF2662DD04A71BDD72DD052518 -:1010C00093605D6D2E5EBE3873E49A4076381FDD06 -:1010D000DF6D990525B83F11EE7FF49F506FDC2836 -:1010E000E0B62473CC9F025C1E2AC89795442080EA -:1010F000F76D4A80CE61215DC458B7DE95AE0251CE -:10110000ED75F319DA4FE8DA5E8F6ACFCCEEF3694A -:101110002FF036290AAFC551781D17959F2EF34140 -:1011200083FC9372B1ACF9FEE5696E8C4F2A74A70B -:10113000374CCF57113DCF774AFA9DF827A4D730C7 -:101140003D4F22384F6D92F2B0640DCAC329280F6B -:101150004787F3D7A0BCA0FCE4123D29525F5CBDD9 -:1011600046073CDF502FEBFBA8FE4D75B2BF29545C -:101170002EF1C802534B70FC1B870A7D11B8E64F55 -:10118000583EAF85B7FFEDA3D7FE29D0E70CFCD0C2 -:101190001005977551F94054FD07CFA25FEAA2DA16 -:1011A000DF1D55BE3A2ABF362A5F6F6C5F3A4B216E -:1011B0003E2C057A40449C8D2F5FCEECF47F3AF5AF -:1011C000A96227BBCDC057136B79FE8F8F9696D43B -:1011D0000F88C867CE2C89E40BB9BF0AB23680FAF3 -:1011E000CADC8DBC7CBE3BBAEC17AD6F79F95FF100 -:1011F0009F19B4CF63B00B5E578DF95655CE7BD196 -:101200009F6E1B10B91F5A5D8271966EF75DD8C232 -:101210009271917649A092E844AE53D69F70EAB499 -:101220008AE3FD25B3B2A411F7758AC47EA48BA707 -:10123000A0D754D49B55222E3301CF0363BDF85061 -:10124000DFC59176086BCAC775B6FE8CDF9308D4EC -:10125000027E30CEC6BC168CABB426252D7912EAA0 -:10126000BFFE337509EAD1BD4B52E81CD66559DC87 -:101270008E7C3DA9675A39E45B136EB5E0FDF3D669 -:101280007BC653FA9AAAAFE8005EFBFBA37797D818 -:10129000FB637912C1E7BBCC25254B81CE4FE225FC -:1012A0002568EF7739D3F01E075B6566FC3D24EFB8 -:1012B0001344376BAC83D08F2E5D7A11ED5F953D73 -:1012C000346502DDD3586EA67D0DF8A3FB3AFE55BA -:1012D000E3E99CD7AC3A9106AEA0F4D57FFDA636E3 -:1012E00011CF2D3CAED0FD904BBF6D7A0BDF5DAAC8 -:1012F000A8EFED45D4BC02763D9EBFFA6CED0574B7 -:101300002F647F5C359D7385FA0CEB57FCE07967A1 -:10131000F250ACAF3AF148C941F88EF6F0C195EA07 -:101320000605E795E888C7733C074F79DE41BB1691 -:10133000CA9DCBE0FBC1E573D3D0CE3AA878121595 -:10134000BCC7F0D8AA92F40C7C3FC12AF0B9CA51AC -:101350000A7C5D6AEAA417D21FB393793E356B55B8 -:10136000C94698FFC1472EA0736EBFCCD2D3B2003E -:101370004EB766EB3DB286E13CB99E7AF55F7CDF05 -:10138000F0E5A36569484F79599C8E5F39599656A7 -:101390001661EFCCFE4A23BCBF6AF1DC86F37C35D4 -:1013A0003E47A1F3E8AC2905E3DEB3849F09F4BB13 -:1013B000E4F91876CF0F992AF57BC0BA84ED8779C6 -:1013C000B7DE7BDD5807C0A5F54585F0308BF96B9E -:1013D00031CF9A63EF8BFE90563410E71FA6FF754E -:1013E0002467C9DF80FCC8AC47D604D00610E73BB1 -:1013F00019BE3E85FCBA392E1807F09CE5D6276049 -:101400007D96DE943FD511C1A7A2FEA7017E7EF98D -:1014100053A88FFEDEA781BF3822F72F64FD8A44D0 -:1014200047008D8F2F1C0E0DF1B657AB3988E71E84 -:10143000673F6E263D31FBF1D4BB3B701D405F7DA5 -:1014400059D775D46599895FBADF2F7DDAC8B7ECB3 -:10145000E933F2EDD4C7369534DABBE7DB0AE1D7DE -:101460004C78DC4CE7F82B863934DCB72C7AFC8FCF -:101470001BE9DEF1A2B8C1787FA3E2712BE1B7DDF1 -:10148000E10838715F35D1A125632AE8616916E763 -:10149000B3B12AD36C8329A57B1B723FF0F092076E -:1014A0001EC663A64758F0FA1100BFE3882880CB18 -:1014B00071796F2D6A7FB072F7F396427686FDC11F -:1014C000B3EC0BE20D78E4DB73DD1FBC232B7A7FDA -:1014D000D09C8FFB8F15627F70EC3A1ED7A958C243 -:1014E000DF65199BC2E3C4076A02F81832AE37E021 -:1014F000C47BD60F727D54C194A00DFE79C5BA4548 -:10150000F45EED1121874AF15DB501C85FDE5CF440 -:10151000EB673F1E4770AD7862EEFF3D02EDDA9754 -:1015200096B823FDE835821EA07F86F798653F5F59 -:101530002CFD792ECABFB1BF067F18EF4326B3E753 -:101540006ECC433C65E4E23EA6AC57B1EC67F9BC17 -:101550001EF8D3E03797AE54797CEA052BE9479023 -:1015600009E92CE23EFAACBADD16CB80F0FDB8CF2B -:10157000208F4F2C44DC93B320BCE4BD2DFC4B1FCB -:101580002EEC730FC91B7A6F7ABA49A1FB5D20E973 -:10159000E85ED4CB593C1EDA94C5EDDED25C2FDD7B -:1015A0000FAABCCFEA5DC6CF2BB1CE7BF1781ECCA3 -:1015B000D4369BF62D7F6FA5384A555D9C1E97C883 -:1015C000CF536C1D40E7C6350BEEB778B85C795940 -:1015D000D05F9567CA15482F50FE9186E7D51C5CF1 -:1015E0007E56268BF700A1BD09C63986FFEACDFBE2 -:1015F000CD181831BE22BE433F9EC470BFBB4CAC59 -:101600001EE33458BFFF408463CAF5D3707ECFAA6F -:10161000C4C7B0F8FB46A23DF8AC3A04FDE0D29551 -:10162000AF4F588BF92D83F046072B7DEE7DD22FDF -:10163000F305FEDBC5B9B932C8E33B057B041FF9EE -:10164000551E1FDA23E025E9409657AEE4E7A72AA6 -:10165000975BC9DEA95CFA21F55BE9684B43395D0C -:10166000F98299EE797F28E65DB634A7E023A0AB36 -:10167000327312BD2BBE205062C1FC820685F2E19E -:1016800076A9B948A75FD6BD9888F4B33F2ED41782 -:10169000F556C7A2382F9E5794F1B92FEBFA6EC0BA -:1016A00038CE2C679B03EF6BCDBAADB70BE5FC5E74 -:1016B00067C882E57B9BF24C98D79DCE02CCEBDAD3 -:1016C0002594FF529C57A13FA41785E379C1E6D723 -:1016D0002DBD60BC1FC47ABF7AF6FD7CD46B95B972 -:1016E0006DF9A87F800EF2B310CECF28A4B7176E85 -:1016F000E6E7F8251D2C443A00BE9B27E860E1B6DA -:1017000017EF407E5888F81FDC958E804E77D0F713 -:10171000ADEB2730DE7E07D289D47790AF33BB3074 -:101720005E27F2300EE64F213C8751F9385E1E18D5 -:10173000C0CF03B6D3F9C62A719FB3533E7583E772 -:10174000CC6CB17FB6D44AF236339BAFBB7DE50B90 -:101750008988C7AF9E7D7D27C6892BB78256F7C47F -:10176000E00B01972A844322AD83EC902A5C7762D8 -:10177000180E9DF42FF8B18AF175CA755769020EDB -:10178000B25CB4CFCAE6EB5CC004DCB65DC0F94F16 -:10179000F01BF233BDBB24D6E77719DF97D7C5FA24 -:1017A000FA8B7401D005DE5F63787D53CA0928FA8D -:1017B0006ACB7A8A13497CC9794FCDF6483DA22776 -:1017C000BBC2786C37C57E5F7B54369727FB96F794 -:1017D000C86D06B87D09FE189D37007AD522C693DC -:1017E0007423C71BFBDB2957E17AA1FF10F62FC733 -:1017F000DD1B48D0B09FBD8CF307D227CA4FC997D5 -:10180000636B675C3508CF4307BE72F4467B5BE0D1 -:101810006F6A367F0750473B01DAEBCD0AC5A9F75F -:1018200009FF7FDFF21713CB22E0E413F3967486EF -:101830007F18BF92F3DDE5E271DFE8794B3924E7E9 -:101840003DF69E1BAEC2EF72FE925E257D4A384A7F -:101850003A95F703A3E995684DEA4FD520EF493F44 -:101860005E91FD8DC56FEFFA3D3ADF6937D5A5EF83 -:1018700088BCF7B65F9C77EF48653CDECF806A2373 -:10188000F48ED4F3117A65B516A157AADC3ABDB728 -:101890003367E8A27CD4632F64F37329475893A578 -:1018A00010FA5B70A86D42A2276CAF5EFA6D48C556 -:1018B000F76E166CE3E7D724DC171CDD41F45F29D3 -:1018C000EE6F95AE7CBF6404D2F9D366DAE72C5D87 -:1018D0003E9EEE69CFDD387338D211DEFB40B97E13 -:1018E000B871D810FE5C9B33ED7ABCFFD1F8C0F51F -:1018F00037C1F759CDAA97E43BF4837C5B7AFB10A0 -:10190000A6D07ADB4B70FFB4E34ED58976FE988D76 -:10191000C3EEC6FA631C3D93713D7A630AE5752DEB -:1019200089F483B48FE5B9BE5A33A78B5F67737FA1 -:10193000F5E1CE5411E7F96AF371FFBD637D1CBD7B -:101940007335DD22EEBB6EEF417E489505AF5ED26A -:10195000FD59B2C7E658982D839F0FB765C0F7DDD4 -:10196000E6B6DB518FECBEDD3188EE1FA83F0C2FB1 -:10197000E3FE23CDA324C5F8AE949CC71382DEA357 -:10198000FB93ED7789F3D9FBC5FC0FD73D7D3DEA8D -:10199000C1C39BFABA70DD5F6C8FA3F771BE887A02 -:1019A000AFF37CEFB301FD46DD175B46F36BCAB6C0 -:1019B000F3FB5CC28E93F47ED6FB5C9FB8A3F6115A -:1019C000CE7C3EE9680DA37BE7B7812D8EEDC72560 -:1019D0009C7A1ECF05CE6EB03AF1DECF01A477DC43 -:1019E000BF7A41E5F7936D9CFE0F6C1914447F7329 -:1019F000F627FC1ED68EFBEFA17309E5605FE2D1EE -:101A0000CD4E7BF9C1FBAF473638EEF5AFC88076D7 -:101A1000C737F173145DDE77D8FDFCCEC8F71DCE55 -:101A2000D74E3E57FB58C6233EC936BE1F20E12A7B -:101A3000FDA45701FF230787E1F475CD1CB28F8FFA -:101A4000D6F8293DA6ECBB6F0CD2AD2389EE37BC8E -:101A5000DCFC808AEFD1546E1BF403FAC5A3ED4978 -:101A60004EE4D7AF6B96D0FEE8D19A6AFEEE4AE715 -:101A7000BBCA414A2FDDD64AEDBE6E1ED282F78127 -:101A80005FB12709B91FBD1FC4F1D8DD3D67B9AEED -:101A90002377727CCA791FD9343311D7D5FA584AC3 -:101AA000CB28C463429213EDBC0A714EE4E05A6E37 -:101AB000471FB2253D3909E07368DD3569F85E508E -:101AC00079EBB5D7E3F7D9DB1527DAFFDEED531253 -:101AD000D13FFB5C6B4FC4FB5F9FAF95F7C682F4B1 -:101AE0007EEFE86246FB55A3431AF3E4D1D633D127 -:101AF000C9A8A31ADDCFFD12F7B1305EF2433CC591 -:101B00004B98D89F2A7F89C7593AFD59E1CF8D114B -:101B1000EB1E91E392FB0EF47DEC48FEFD8B75CF3E -:101B20004FC6FE0E379A9D38EFAF1BF93B16F3C038 -:101B30000FC3AB008736713F675E93427EF1E14D84 -:101B4000A0A7615D958BCC3ADD6B8DA2BFB1508EA5 -:101B5000E72225FDCDD38344D7D1EF8C24B326BA19 -:101B6000FFF663D1E3C539467FAD930EBBC3BF809B -:101B700013F22DD2A1C4F3BCB5FC7D5B57D3A042B8 -:101B8000A42789F7E87B0EB51646F71902A6787ADE -:101B9000177A8ADD635660FDD7B8DBC7A1F87C24CD -:101BA00087CB4575AC49C7FB7AAC96BF63D0253E61 -:101BB0009DC3E5E89B398CD2B21C7EDE58DE5B9378 -:101BC000292C2487DE654C707DE7812AD7E46C9A46 -:101BD000ACC1FCA78C71DDDEDBCBD8CD39CF4DD6C7 -:101BE000806EA70C71BDD00BF2331EDFCCF397B81B -:101BF000869921BF54F9DDE47190BF2B479F9293E2 -:101C00001A1E47F60BDFAFC5EF8752FC37E40C43D3 -:101C100039CEDF2D3BA6740C5C9217AEFF9EC2F648 -:101C2000BEAC84F3ED6646EFE594E1FC53BB4F3761 -:101C3000E4E8FE9C6131CA19A3FB6365017E1F08BD -:101C4000FE7CB6343AA746F45426EF07D51BEF07BF -:101C5000312FBF9F26EF6DC97B59FDC3F7CDD69DB0 -:101C6000CF7DB363E27E5CF4BD3FA585DF97AB0D0E -:101C7000B0F638C243D47D9F04FE7EE3E217BEDA9D -:101C800081643557DA2BA86C8787DF3960E9FCBCA3 -:101C9000C0ED820EBFA8617DFA002B5FDDD696E80D -:101CA00081C91E9D1CCA47FEF658FDF508A72FD610 -:101CB000D5662F76E3FD58AB7712D43F14E4F74F87 -:101CC0001708BB9335A60A3E57439743BD5D79FD80 -:101CD000E99D8B5F0A7A3A9A17CAC577870279DC41 -:101CE000CF817A74FEAD78D915A958EFE8967BFAC2 -:101CF0009403DEACF8AE9F8B5286F7C5AE84BE4728 -:101D0000BAE8BD3FA6D2FE6E90FAC37A89A8D73D45 -:101D100033D379FC9DDF2F947892F0EF82179802ED -:101D2000DAA5261B33E3FCFBB3754ED4C7123FF292 -:101D30007DDBC52FF038CA62A5BD2E05F3CF2A740E -:101D40007EEE0B1BBF0FD455CF6DB420A8E7AC9B24 -:101D50006978C748BE23FB63C7835ECA11F7C20711 -:101D6000B14191EFF45688B6E3D5E91E7C677471F2 -:101D7000AA8DDE3759FC786FD2272C703BD181AC0D -:101D8000C7D6A5107DACC85309CE739B19BD4F545F -:101D9000D29C49E71D2735BB284D3C994EDF0F3FAC -:101DA000F9D6502E7F381E4A9EEA41EF8A973C753D -:101DB00041117F74AFCB3B49FC3D6DBB8DEE1B2FBA -:101DC000DECDF5D2E2EB548A5332710FCC27A6E375 -:101DD000B3D7535CC7C762BF0FEC93EF03EBE63397 -:101DE000BE0F2CE16B15F8897E2FF8BADD43D2D1F6 -:101DF0005F95EF05CBF708DBC47DAFE87783EF494C -:101E00009C40EF064FD3B91E897E37580BC479D159 -:101E1000BE3567DBF9BB16FEE87784DB355CF7F58A -:101E200005FC1DE1EBA619EFD3990BBE21396D2EF0 -:101E3000E8F28E9219E9DBEA33D6FFBBD42FFD59C5 -:101E4000FF33BED39C6DA1F7F0347CC71CF2D78B57 -:101E5000779AD18E43FBFCB8CEDFDFB3C6F375B7FC -:101E6000B1A1E9C8F7FFBFBF4F7EB677C9A3DF2195 -:101E70008F7E7F7CC8AE5F1AF2C3DA1E35D41FF1A5 -:101E8000D10643F9A8F6670CE5630E6D35E42FED36 -:101E9000F883A1FEE5275F33E40BD95B86FA636D17 -:101EA000EF1BF2E39D7F31D4BF227DBFA1FC4ACF5F -:101EB0009786F289FD4E18D7A3F927E4223F7BFFCE -:101EC00069683799797E81EF7BDFE036D1BB26C523 -:101ED000B946BA1B97C3E30AAC0FCB45F9355E9DF3 -:101EE00044EF241D6F52F8FBD2DDE8B124B0F7B403 -:101EF000887192751B3882E17C4AB1D3904FF5A569 -:101F00001BEAF798E6319467F8FB19CAB3E6780D37 -:101F1000F99CEA9186FA3D97E8867C5EA0D850BF8E -:101F200077BDCF90EFDB30CD50FF82B57E4379FF98 -:101F3000E01C43F9459BAA0DF98B9B9618EA5FD2EA -:101F40001C30940F0AD51BCA87EC6A30E487B5AD04 -:101F500035D41FF151D0503EAA7D93A17CCCA1264F -:101F600043FED28E6643FDCB4F860CF942B6DB5062 -:101F70007FACED3D437EBCF3CF86FA57A4EF33949C -:101F80005FE9396C285FF0A597EE4BB397F97ED8DF -:101F9000C47EDF18CACD6E46EF6057B2782FEE3B95 -:101FA0004ABBA6C4FB7743BF4FE6F2380AD0527B48 -:101FB0001CBE1F19F051FCC7850702514EE13D754B -:101FC000173F4F339DE2486ED26FA48A3C78BE071C -:101FD000EC8044F4AEF2F2D04E4E08DB63D9A72376 -:101FE000CED79DCD1EDB96CB681EFB73FD4FE7A6BB -:101FF000A2FFB16502BDFBCE022B701EF23DC07781 -:10200000A2DEBB96E995B6432CF25DECDD710DD9ED -:1020100083CFE0BF5F693BCAF0BDEDCE7E45BC42D9 -:1020200081F52D8EE8FF3EF017B43E8C35D400FFCD -:10203000808DF4CB1A27E51FAC49A7FCC3351E4A97 -:10204000D7D6F4A3F4D11A2F95AFAB1949F9276A63 -:1020500074CA076B8A29DD50E3A3EF8D35D328FFBF -:1020600024F8C5986E023F19D367C0DFC5F2CDE0F2 -:10207000FF62FEB99A00A54D35F5F47D6B4D03E581 -:10208000B7D5ACA5FCEF6B829436D76CA2F40F35B4 -:102090004D54DE52D34CF9576A42940FD5ECA2FC52 -:1020A0006B356D94DF51F311E577D6B453BAABE6D7 -:1020B00010A56FD67450F9DB3527297F54C45DF71E -:1020C000E51AF723645EBE5B21EDBFC968BF2371CB -:1020D0008C347F6DB0DFA3ECE8687C1C11E3E03B3F -:1020E000BD43816ECD99F91B6A23FCA7AFC478F27A -:1020F000BD8AE8772798B04FE5FBB0F23D8BD962F7 -:102100005E1582FE87217DF623FA7CFB7CFC05E9C7 -:102110000F5E9BEA3F45F499630A903F6CE7F791A5 -:10212000EF48F5B39EC370DFB07C278DE7F4D2FE95 -:10213000618935947AC3507A079EE272DD8D572506 -:10214000CE89775BFECAE16CB4A78BFFA5D27B6416 -:10215000EF981DF4BB97293D395C527A9A0CE93F00 -:1021600053FDAE9E907EEFA8BEC504F3FFFEB245C0 -:102170004FFE242FEC275F8DAE26F8375398C74CBF -:10218000E71199FEC73CB49BC0B0C2FC0D2C40695E -:10219000C0EDCFC275DD080637E6FDA3ADB9B1D6F7 -:1021A000153DAF7C31AF7C311F99F64FF3F7C5FE7B -:1021B000BE77E834AF77465D918FEB92F39A27DED6 -:1021C0009D98CC3A9EC0F97DBFFD9B834AEF30FCC1 -:1021D000A53F4EEF02A0BFB34811EFFF75797F8096 -:1021E000CAA7DFAE907D3603FC19DC2792EF0D1CE9 -:1021F000AF36937CC4F709701FED78F5E776246756 -:10220000A8C7709FA3160FF64079EDCF15A2AFE9CE -:10221000F88E08B49F9196C7EF4B339B8E7A787AED -:102220008B753DD2E974B0F7D07F02FA2844B8CF5D -:102230001BA5D27DF5774CC17C85F693CB2D0ACCBE -:10224000ABC2ED35FC8E4434FE178AFB07F23BD05F -:10225000D54484D7D72F8DE847F1F7574679104EEC -:10226000B5267EEF28F0A62A7EDF8B8B6675CCC55F -:10227000145F649AD78B71A212714FA555654B629A -:10228000BD1F5F29F0F44E3A7F5FB0366A9FA5BC50 -:1022900027F72FCB7BF2B873C96BBBE99DA585BB34 -:1022A000F87B906C68FB80C877793AD7B3E4CDFEB1 -:1022B0007D22D651D5BC8F9FAF60ED0322CF9FAF5B -:1022C00010E34BFA512D0EFF7A7BE4FC3AE97901D9 -:1022D000D17332D0736FA2E783B8AF38D9EA49BA65 -:1022E00041C15FC7635FE3FB47FE5F3BE93C913C55 -:1022F00057348BF928AD00F423FDFA02F7D37BB7EE -:10230000F358137D5F387226FD3E6D15EB18970E5E -:1023100070BBAE7EE91FF1B9C06B1AEE1F8F71D58D -:10232000A9C1D23F623AA5513988FE29F0C3CF1125 -:102330001FED4AF5723CC279D3E6C2E5B83538598B -:10234000E5F8606F717C00BDE8AAABEB3A81FE97BF -:1023500013FD27EBB40E35B1D840FFD397315D7133 -:1023600087CFC777F2C3C8F97FC52D60A675D0BEE9 -:1023700079D52B5617E2791EE3FA3A6CFF493DCD29 -:10238000F5FF7CD0FF58EF88A0E723398CEE211CA5 -:102390005118DD6F97F623CBF5A70FEE1DD6B74783 -:1023A0004CC1E189BD491FAFC3F9EE4CBF86DE0FBA -:1023B0009AEFB6D1FBB0479283B951EFA1D07B4DD4 -:1023C000327E759F99C793A2E7A58CDCC97FE7C4CD -:1023D000C202B82F81BFF33D1CF938D3427C568B23 -:1023E000A0C5385891CF13ABFF3AD1EFAE53DCCF35 -:1023F0000DE4F0774BBA8CE314E3C4F371A4DEE888 -:10240000FC5DF13466186F7BCF3CCE070E9DE6BFB6 -:10241000D4944C7226C3E66FC1F5CB788EF4FF7668 -:10242000E57DD187FCF41F6AE93D267ABF00CFF530 -:102430005CC6E5D13B660FBD4BFC4E611EC5EDA5EC -:102440009CBD7A248F7B5D2DE35C055171AEA8386D -:102450000B2B881DF762CC6BC671FBB34F247C2815 -:10246000BEF25A8166F83DB1D784DF79BCD83D947D -:102470007E2FCAC3CF5925A6F0F7463A1C2AD1D9D8 -:10248000EB01AF1D7F9F6495888FAE8E7A177CD548 -:10249000D0C54E3C176075F0F73ED714C5CF893CC8 -:1024A000BFEECEE7EFC33C995F98E18174803D5861 -:1024B000446A59D73C387F45ACE72227C0DB84F615 -:1024C000A64FC439E5EFDC8C23BD2CF17CAE7AF944 -:1024D000192DB82C1ED7EB66C4778EB536929F6A3D -:1024E000931EC2A3D4B3F2A71E47B9C1345F3F1CE9 -:1024F000A775783CB343FDEF5B2D147F7AC554F686 -:102500006B7C97B8E3CF5686E71C9A1C591A1AB70A -:102510004DA72E1C47A963CC04FE3E274BC0774431 -:102520000739D96F7E874812F7C92CE9CFF80E809A -:10253000DC6E52D82EFE0E979E80EFE13599D88939 -:10254000CB617EFF0FA64C086300800000000000F6 -:102550001F8B080000000000000BED7D0B7854D5A8 -:10256000B5F03E33674E66269370327930E40167EA -:1025700092C98B4CE290F054AA93106840D0E15578 -:1025800083243A58F446854C8AB445AF5F339000B3 -:1025900001F42FA2B548BD7640A568B50D4A6D6C13 -:1025A00023770242B197EA606D8BBDB57FF0F6F7F5 -:1025B0006AAD12C47AB1A5E5AEB5F63E9939930974 -:1025C000A2BD7FFFEFBFDF8D1FEEECB3F7D98FB554 -:1025D000D77BAD7DF28CA3F6FECB18639359C0CCAC -:1025E0004A18D34A838A96CBD854D641F57B954076 -:1025F000DBEE1C289D565F18FAD58E33F919D4D915 -:10260000C78E48A9C458E0986C313B18EBF3041D01 -:10261000F8DE05FCB90A9EBB4C16C5CBD84685B57D -:10262000F54299E1B3336665F47301FE05CE953149 -:1026300056C7D858CDC4D814C6BA5DFE985F8ABFB5 -:102640009F5C32551E1AD4DF2FC6FF17AA6FA58BC9 -:10265000BA9931AF23D22061C52F6BEA54C6E8770F -:102660008DB12A95052D30451A0B30DC0F9BEEB34A -:1026700006AAB1B1517DAB02FBF9A50BE9179997F9 -:10268000C90CFBE9F3FC6102A3F51EB267D6B031B9 -:102690008C851BB4FB1A2743F953B3AF8B7AA993EC -:1026A00071FCCC6C1635C1F3A10C73648F9BB1C364 -:1026B00061EDA95EA81F96AB088EF774C266000490 -:1026C0005B3BA1A2C4E7DB3A798DAA013CD332CCB3 -:1026D0005F3A8C702E32A9A5B08FCDF3ED4D1180ED -:1026E000E3BD0DF6362C73CA2C8C01BC97165B68C3 -:1026F0003D7BCBEABF5D0CF5564760B6A47138B0A0 -:10270000BC381CE001E3FB0D32DC6F8BCA06A5442C -:10271000B830804B06DF00BE770DDF32BB4666E186 -:10272000314EC65E9EF1F663BD304EC64E587736CA -:10273000BCDF71460EC23AD8F90B57D901DE01BD94 -:10274000FF4C89BD9978CEF0EFCD0AB13F37C15328 -:102750007D4B6F375F3ADC2D4BD6573058EFA64E86 -:1027600017C1AB47F2F9C7C27872C7A93BF0F94667 -:10277000193A02BCC25E25F238CE23072A703FFA0E -:10278000782BCB1A6ED0004E19D3FE907E0BF4FB43 -:1027900028CFA42170366A377DDF8EE777329DE13E -:1027A0007B99D9B1B647A17DE8F572B60786F9E8FD -:1027B000D6E00415CE630B9CD39B1E5C4D64AC69C4 -:1027C0003A9683634D2E02AE8B9741177FCE447BA2 -:1027D00084EA6FB98BE99C00FEA2FF20F5DFA26CB2 -:1027E000B7DA711EB755DD9380F7579959472FCC4B -:1027F000F775A40B7CEF7C97B63003EB12D5EFEFA7 -:10280000DC19F89D07D713A1327B7E840501DFEC2C -:1028100015612D0CFDAC1B5810DF4F86E7DB6E9960 -:10282000DEB71E7A8869D02FDBE39382D02F673E14 -:102830008CA7C399D1B987C7D442BF3D80309311CB -:102840003EF64838055D5E93DB704CCE1CFDFC9275 -:10285000F180093CD0CFD3FA577310F902632E13DD -:10286000E2DB5A2BC7D3C6622BA379D729BBD3602F -:10287000DE27B42C5AF787390D639877F4F91E8157 -:10288000F309033D4580AEB0DCD3A9B230E0C963A3 -:10289000802F58DFDBA951B9AFB382CA273B7DD463 -:1028A000FE54E774AA7FAFD34FF5DECE26AA3FD3FE -:1028B00019A0FA81CE66AA3FD719A4B2AFB38DCAC8 -:1028C0001F7576507B7FE73AAA5F9506E786FBA9DE -:1028D00008BB16C179F4DCA9F83580CFA038C7C38E -:1028E000FEE26C1F9CB7ADC2043407E5F11D0CF786 -:1028F000637399FC1138874DAE1DEC8B505AA66658 -:10290000F448C057363EEDE8918031DBE4FB19F224 -:102910008347A4701BF331F693483020CF60CCE39B -:10292000FA528313EA3F8BDCB2DD0A785BA62D6C8A -:102930005E9F50D7326A6FDBAFC6EB13BCBB653B03 -:10294000B4BFAADDBA3D47E2EB60F98CFD26727B8D -:10295000603DE051B4988511EE436E2582F8B812BF -:10296000CF4BC6F5ABB4FEAB5997CB04EB9FA02978 -:10297000B54837D03FCA722EBDFFA0A6D1F3E4F709 -:102980002ED6CF34F992FA31F345C6C376E922E365 -:1029900058A5C5D618AC7D9B45F08F5C07F18F1EFE -:1029A0000BBB310070EFB1F1F2CA6289F8ACB3B879 -:1029B00061B71BE6DDEDE672ABC716561B70FE6A0B -:1029C000930FF9055BE7FE7931CCF7959FCA6CABA5 -:1029D00016C7CFFF1078503A2183CBCF7FB4464A39 -:1029E000619ECF4F78BADB09F5D2477D3E33F4DFE5 -:1029F000C67C76C493F03D26F638D4BF3BB9C4B943 -:102A000010BA574DF98113F9ED5237E70311C69A01 -:102A100010DFD66FBC65C220941F9DE07C4A71F325 -:102A200079765B621D749E531C6C0F0981EDE9C8B9 -:102A300077D6BBE090A631661AC74BC5A25E8FFD64 -:102A40001410D461588FF29769D6008CD7752EADCB -:102A500009F90863B174E4638A2DA866C1F3ED61D6 -:102A600013F1852ECD119160DC6D8EDA631AF24F71 -:102A7000D5E42B45387A4D04C76EC7172266E4CFDC -:102A8000D2FA36942F11F519AB1B9E47BC2615E9D7 -:102A90003CE25FD484F57050F6956A8241607BD049 -:102AA00019D98AE3B2A17FB90CDB5B980FE1B03191 -:102AB000EF4F87D2A1DEB554F599796F4D06B93342 -:102AC0000E7F8329BB2C831BD2711DCB787FF8CD61 -:102AD000B710E5701A3FBFAF0FCC558B49EECB61F5 -:102AE000A14748178010658BCFEA83F61A476D938C -:102AF0001F4A39A3D6AAC13EBBD55AEB0ADA3F73A7 -:102B0000803284228FF853976A22398CED5F447AA1 -:102B1000EF662F7AF28894A8BDDBB16300E121DF74 -:102B2000CC985BC3F5C17C3ADF0378584B661ED363 -:102B3000601F3DB738691FB2E4A33ABB59A675E7D9 -:102B40006BF628AB013EAF2C38C6807FE45B6F9FED -:102B50008FF5716DF2EF0613F8F4D8A0B19EDB6C1F -:102B6000AC6733A85BE3F32E7273FC4D865B323C9B -:102B7000C6A9DD2770FDE382323D4C5EFF43EA03C8 -:102B800059F50CD7E9A075E6396EAA070801CA0500 -:102B9000D623FEFDADEBAC511759DD307F4D8E894C -:102BA000D496CBD8D0061C779BC0F71E373FCF38C2 -:102BB0005D9975BADC8A7439619D898513E48E3B11 -:102BC0006C67E184F94A7A9C867AE9F67C43FFF2E5 -:102BD0009DC586F6CAC844437BD5BE5A43BDBAF7E5 -:102BE0007243FFCBFA1A0CF549D17986FE75C716E8 -:102BF00019EA5362D71BFA4F3B7993A17DC6E06D6A -:102C000086F62BDE5E63A87F6EE82E437F5DDF4E87 -:102C1000968FDD822F7C5A3D3BCD05989D305FB26B -:102C20001E9FAC875BFFDAA56D407CCE54089F6584 -:102C300094E7505F73A7124943FCBFD2A7217FB925 -:102C40004BE0A3B7DC7F1F9E5B7DA695E482ECE0A2 -:102C5000FD64C71CD253C6EF04BE54875A231B6EB3 -:102C60004F47FEDC190E783CF175DBD4ED0CE9B76B -:102C70003EB3890D3AE2EFCBAA9F0533703E8DE655 -:102C8000B3AA61EA67D3E0FD847D1D34999803F906 -:102C9000F88042FA7A6F46818CF4D7FB97898D547D -:102CA000665C3107F17D92CA1EFD3EF4EF95D83186 -:102CB000067A52AF899D059D8D3D936447E9F6D311 -:102CC0007813B363B95B1ABC83A19DD271A2612C46 -:102CD000233BEB59DCF7BDA043E0BEEEADE17AD675 -:102CE000C6BC791AEA653DEEDE63C5B89E5C902BE2 -:102CF000480872C0877A85BEDF37C479CAC53D836C -:102D000028FFD6645935D49764EBF6C0EF005E8F88 -:102D100058069FE8827AB7A4AE42BB237CA7C3F7CC -:102D20003843FD91C34DCB30D56D80717BD7FBE52A -:102D30002C68EFDDC27CDD481F39F51BB2E07969F4 -:102D4000E10A9313E9C1B37E0396AFA01E0BF0AB6B -:102D5000F4EE3665437BD5E4FA6686B25785F9B260 -:102D600047C72773E64E86FB611EF92DC42BD4BAE4 -:102D70002FC0D2EB9D70DE30AF0DCF5BA292E06032 -:102D80003BE788D8B0EEE170B1F9A5483AD4733C7E -:102D90007EC9EFC5F776D2F9DAA2463D16ECCF37F9 -:102DA000DC53509F359EAB6C7D80D6B7CDC4E9A275 -:102DB000274B3B8EF2B9C7ED717669F175EA7CE578 -:102DC0006D618FEACF75BE723DDA1453E2FA0DE001 -:102DD000F94E5309EA67DB19F227DBDDDB19E2B5AF -:102DE0004D0D6B0CF5F0AF8509CF75FDF60E413337 -:102DF0008DC5CD5694D767736A499FB5ADDB4BE758 -:102E0000950C37DBA089F92F02D7CCB25D24DF8186 -:102E1000016B68871FCA73B4ED4EA1F76FD0389D60 -:102E20006D01328E79098FACC8AF2DC2CE004C3007 -:102E3000A17C3BAB326E27F6BAA97E4716AFEBE317 -:102E4000DC915B3BF662FAB70DECC260C23EB6C0E5 -:102E50003C08978DE71736215C994CC4C1B6FDC577 -:102E6000BB7B2BC252D8351B04BCBFAE71F88E574A -:102E700018D905BE9CF94D24FF5C4FD2F905CE153B -:102E800093109E56EC24F883116DEEA0F55B74F957 -:102E900064BA7019AD595360FD05F8A4184B2EDFC4 -:102EA000A0CBC00509F97F823CE305C9F702FE3BD0 -:102EB000C803637BF94E63BD3292F47E98BD86F2FF -:102EC0007F25E3F0AADA676CFF16CA71E01B2B8539 -:102ED0001C67DB2D24EFACB0A20B5CFEC6E521F035 -:102EE000876B7A63F5E9304ED1748B414E1624F628 -:102EF00003F8D5DE6A0AA0DDA0FB5F74B807DA4CE0 -:102F00001685E84123380D3F17FE9664FE3D3E8D41 -:102F10009FCB212523B2C1CDFD12C1326E6707813F -:102F200024EF957DBF6A417BEC98D907983D7C9E44 -:102F3000C9E7BF6F583F0ECC2F267B77B00EED6FE1 -:102F40009C2F98309FEE37292C0F2E2A86FE1F3497 -:102F5000E54CC6734A2B6416A463DD2FA2DBF9BBD4 -:102F6000115760BC6DBE573B0EC33A369F4C239F32 -:102F7000C66CF3F1639D505F532413DF53A7ADFA82 -:102F800036DAD30DFF0AEDF0CE664D1B4BFAFC315D -:102F90000BD9F50D02DF1B849DA6FB4F6E2BE6FAC5 -:102FA000F42DA28437ECDC4E8FDA51EFADDA073C1A -:102FB000DB882FE9BCDD4F7A71756F72BB9F21BD35 -:102FC0004F14F80075473DD427897A2F93B25538AE -:102FD000E7CB9A070FA1C9E17DE9881DF5B0FD3661 -:102FE0008E1F4F0ABD2F8F49BE28AC3F6F9FC3175E -:102FF000817E1966B63F06FBF0BD28BF399800CF29 -:103000009A7E63DDCB12EA6E5C87B17E8FD621217A -:103010005CEE690154842D6F28CEC879AB8A21CC2F -:10302000CB10FF669B1D93D0EE5A53EF6008D7B4C8 -:1030300053E5DF8C219F396166283FD474EDBE468D -:10304000785FFD976CDF7A2D7EFE4F76228B67ECE2 -:10305000C10B3ED6ED89FBA99E82F34479F33DB0C6 -:10306000C7B1BD17CE15EBCF803D8EE501B0C7F1DE -:10307000F973608F63BD0FEC712C7F04F6383EEF5F -:10308000077B1CEB7BCBEA1F4CF66F25FAF9E2FEBF -:10309000AD4149F76FA5015C1BD04E9C92E0E70A59 -:1030A000723FD7278FE3D7C721FFE1887186FD885C -:1030B0005615FD27C5F0C61878FEDE9DBFDE8B7263 -:1030C000658114DC87F8BD7ACA9B0AD7B38714ECF4 -:1030D000FFB00DF01FF854E128FEC32B679DBA2303 -:1030E00017ECF41F15B72E443BFFCADB4FD58D8775 -:1030F0003A2B39C6EBDF39F56C01F0EA5B4AB6F0E2 -:10310000FAFDA7CE1642FB18F6ECC2C619E47724E6 -:1031100039F6B0C49A13F5C09F08FA0CADDB41FC38 -:1031200014E400433874E505488E9ECE19CA5C014C -:10313000FD43B94379375D84CF87D63D48F2AA2B4A -:10314000F3F7A4A7740DCB151FC9157D5E5DAE7C8A -:1031500020704F972B6B6CBC3ADC2F5842CFEF1787 -:10316000FE1F1629A57AB68DD7FF5783F60ADA47D0 -:10317000001FB2870F674EFCFA4CB43F9B645F1A86 -:10318000D4EF77D4DA502E9D15F40BE386D1DE0F01 -:10319000CFB6461EC743CDD1881E9DFAF8391E54BE -:1031A000CE9853ACE3C5CBED51F40774355AF7A074 -:1031B000DEB9C3514CE3754D57C2E887D1EB1B2EE6 -:1031C000BFDC8A7A4756A6D38D759D3FE9FE5BF832 -:1031D00031E3B80D62BB0D5647D49C89E861F943D1 -:1031E000A23EED6031C21F9F090C17A0B7AF9570CA -:1031F000BCAA63BE667CAE481D6144C68771EDB84B -:103200008F0CE1CF44093535611FFE02BE2F7D1FB3 -:10321000194A58EC83F4A91D0E5314F5C21DB02FA2 -:103220001CEFDF8B35824FF2BE18BA6861DC59D3D0 -:10323000C5BAD59907701DB34DFE6E7CEFC8C72D7A -:1032400039887E7358878CCF4BC0F245FF2DA07410 -:10325000F7858BE827C9FEDB2BFF4DA2FDB0DB1500 -:103260003A17A58CEF7B97127133328423E31665EE -:103270008C8EBF2525FC7CE3F8EB67484F5D4E3F05 -:10328000C75F7528733DE26FD650DE06DA5734E526 -:103290007924E371F2F9D4206D73396046F87ED257 -:1032A00079EAE7A8E341B2FCFA5A89AA9FAF8BF604 -:1032B000E9AFE074A0EB5B0CECA18C91F0DB04E3D4 -:1032C0006965F1BAE20A901E6DC9F155A09FB7EB8E -:1032D000AFE6B6547EDE1B049CD667DA49BFEECA61 -:1032E000E4FAF540E63C835DD408769204F861CEBA -:1032F00066BD4847E631D7939FCC3C1635285C57CE -:1033000092DE3A663ED75B55D05B53CCAB9732EA40 -:10331000AD29F4D961BDD5398FEBAD990AE9AD0F6F -:103320006728CDBB53F09BA9255C2F1CC07DA4B0A2 -:103330000BC11E247FA56E0F2A6A90EC3A7D9F5325 -:10334000055DE9FDD3D40E86FE33B3E2D3502F35AD -:10335000DBB99E9906DBAC4890DFFAFC934A785CB7 -:1033600025AB9CEBFB262BD74FAE7C45EA4805F7F7 -:103370005089EE5F498D777F03DE105FA875287E48 -:10338000D40F6A1DAE06D40F467B0F4CD2F0DBCEB5 -:10339000385FF1FD75AA99E48FEC73219EF55A060A -:1033A0009F7D05EDBD230E9237BD1985349EAE5F1E -:1033B000835D1BAE8041F6FF1928D134D29E053BB8 -:1033C0006B4B09C6BFD6E44DE6E3829E573D52AF34 -:1033D0004CF61B0CD37BE65E377F2F320EDF93D685 -:1033E0004C1F8B78954CEF7A59E4FA69D14A5857BB -:1033F000D1B86354EACFFF8999C90F97DC3F327C7B -:103400000E5C2E57C26463CC248F23B8EEF7D6BE71 -:103410009AE783A5B4CB67482E7FD0317DCC668DEB -:10342000F3DB7D2867BE2413BF2DBC7520CB9970BC -:10343000CEBB3AFB8A640FC61762458D1EF2F7F9C0 -:1034400053ADF7B83E7F7402F1678BC0032D27366A -:10345000B71CE0AE394C3E542540F81AF840BD9CEC -:10346000D5A8C2FC459DCCE780BA9BA9E4F72ABA4F -:1034700060267C2B3ABC8CF07842CE9014F626CC99 -:1034800083AC38217EF2614723D167D1D8617B8F2D -:10349000E20C1FE64417227D7FF8005F51D1A3C6DE -:1034A0007690B1E497BE65AD3D8226E384BB5513AB -:1034B000D68BBE2DB14237AEE3B07B33FA757E9822 -:1034C0004E7E1DF34E0FF965BE2D050F105C23DAFD -:1034D000574C2562B3D06FF557ED7BB6921C8BCD60 -:1034E0002539F665137B3C85DFE9E725DC8FF19A0A -:1034F000C0F722D7CB452BEBB03C4EE77DA9F4C4F7 -:1035000004DFDE3C663BC5C5C20DAC02EDC31E0B3D -:10351000E0550A7AF57B387F19E6C7027E36B45645 -:10352000602CB324F4BC7D4F3EF9641ECA6D46F690 -:103530006472BC36BDA2971AD37D7E86FE0949F51A -:10354000733EAB865D618C03FDC59C12AFC77804EA -:103550009F766F7261FF468FCF857430E09EEABA26 -:1035600009E0E770282C2D810FEB78F262C654D267 -:1035700043F471D664145FD42E57801F6B1791D318 -:103580000AFAC7519F3934C3AAC17A37396A63A886 -:103590006F6D72E4D4929FDD017C23C1EFE4701C57 -:1035A000253C74F8B83FCE81FC17FD4E62FF03EE58 -:1035B000A3B47FBDDFBB820F397C511EA7046B060D -:1035C000FBD9E44018ED0C5B0E23BBD266E5F49406 -:1035D0000EC7614DE023FABCBF2BE1F6DAA6C2DAD2 -:1035E000583DAD4F46CF01DBE4AA75913C4438A36A -:1035F0003E3A6E581F25FF4AB180B33E4ED700DFDA -:1036000067609DCBDF988D7668C0E5C1711D375925 -:10361000C3281732265F743CAF4732F887E2E3AD28 -:103620009B25C62BC6F1CC19B52A8E67413E910267 -:10363000FF6688757D56FF19405425BB8D71FD0AC4 -:1036400030DE954A8FD04BABF0838D7C8FF349B73A -:10365000B05F804FCEF6A0DD52F8E6D17AEAC5ED34 -:1036600016E75CB94286F3FA004ED02CC5EDF8643B -:103670007DA6DE3C44724D9747BA7CDA85FA8C12FF -:10368000A7A77CCEB958415B80E4B6941320BC0157 -:10369000FD4643BA31637C3805DCB608F84B99D354 -:1036A00035A497C6F38305F8DEC18CB70B5882BFEB -:1036B0004DE7872F7EBCD786ED1FB6355C546FD1A2 -:1036C000E3C7A3C58D33EFFAFD9712F596D1E2C893 -:1036D0009F143F3E94A9909FEE11C9C897BA043F2A -:1036E000FA9AC00B6771F02B88478F48011FE98D4C -:1036F000C29FE22D0FDE89E733BE47616138CF8379 -:103700001F4F75217E5C2A7C753F7BBED0A7F21DC2 -:103710007B25A4D3FCB688847EF282B65EC97F91F5 -:103720007E8B3C9C9EF5FE1631FE55F29019E5D538 -:1037300055828E0BCEC9AC22410F5CE0E1FA944574 -:10374000E8EF99879EB0E178874C819E32940F997B -:1037500026EDF1047AB7DC5A6B6D48840FC67F52B0 -:103760009CDF773DC37A17D947BABCB5E8722247C8 -:1037700036C889503AC75B5DDF095DCEED21490A45 -:103780003E86F03E7DF9EFAF4196755AEA55304ED0 -:10379000FE49F18F61BDC61459A1DB31482F3E5956 -:1037A000FDF120BC3FE93BF5440F535890CA698CAA -:1037B000EB7DA0473DE321FD0E969C70BE0C5D0F96 -:1037C000799FBC8F473C5CDEDD2BC7C8CF7AEF7991 -:1037D00089F878327CFEE8D1FD5AC371BE8BFA4974 -:1037E00035F493BA316E65F463D61D33D6A7C48C15 -:1037F000F5692793FDA2FE5F24FA451F06BA427EB3 -:10380000A0FB410BC3917A15D65BC47A296E58D0C0 -:10381000E634C0F54AB3C8A7607E29D13F5B202FAC -:103820007807DFFFFDF0B98749CFBA45B4FF43E31E -:10383000CAAF74A3ED3CEC67D5085EFF3077D16C5E -:103840003CD7647F6B514742FC918DF4B3DEF2B0FC -:10385000C5D01EF04F223B60F112A37F96D691CBCC -:10386000F75B503B72FE4F9E17FE3947CEAF8FBBC2 -:103870000BF80DF251761ECE752AC28DA1C78115A7 -:10388000C95109E3D7F91DCC8FFA70C15AE64F151B -:1038900007282CE578900C6716BE8AE0374B3CCBA6 -:1038A0007798C94ECF5F6B223D301FF801F2816BD4 -:1038B0005601B940BD6095467AE4B56D26867280A2 -:1038C0009DEF34BC0FCB257FA77EEEBB703CD4238D -:1038D00057B38809F7D33191E889D6556CF08BBF7F -:1038E000C9E16525785D3BDD62F06B16A11F3301F0 -:1038F0002E3A1E14243D7FC1A31AE802E45961291F -:10390000E13F9773A528E76049EFCD38B917F3D9A0 -:10391000AEDCC068BF4359F608CF93188E27982FA6 -:1039200094037FB2CEAA40BFCA36D56EC27C8683CE -:103930005983DF62598CD594B270E34CC6FED93EF0 -:10394000542541FDF2D24777F4C0A11CB40D7D1778 -:103950009DBD0EC7938B9A3E17AF67661EA43A9B18 -:10396000CE3419E063C719609F7675DE3E33CC6FA5 -:10397000F73AC8096967C3744AFBE9BE5CBB07F341 -:1039800041BA4B4DA427B1C476D8C7774A553DBF3D -:103990008CF2DD58138FEF278E2FE75C64FC7930B3 -:1039A000FEE44F31BE95AF3F0F1F817CC9C3F5A325 -:1039B0009F1AC7C7F3456751E2FC623C998577635C -:1039C000FC05E673487C3E15F34DF29831BF6078F4 -:1039D0003E15E6ABFE3BECA779E479582E761ED770 -:1039E0007FBAF3E836F969BDE11A07D93F0C9A4D61 -:1039F00053D1CEE0F3D964F6A25CCBE1DA3D350ECB -:103A000057D0F7685CE8BEFE8280B305E1AC2A04BB -:103A1000E7D1E07648E5F94E5B547B64BDFBFFC11E -:103A200079B9F87925CE877AE325CF773DCC97739E -:103A3000E9F3217C917E86E10B67B221EFD2E10BA5 -:103A4000AB0A5F0A7C0FC1B8A604B8C6F38A1E523F -:103A500051FFB75902561FF0DF03A53C5FD19BB35E -:103A6000C84A7906B98BAC98BFB7D1EB68C278DD8C -:103A700046CF12AB25414E6FF4B6503BF4A77C28DD -:103A80006FD48EEE0956CD6264FF6F99D9E85A81E2 -:103A9000F8D3C1F3ABF47C235D1E3211BFA47DC10A -:103AA0008B633E7760E810F4DFD23199F2C9C664C7 -:103AB000FD89F2A8B6B5F97CD8FE2D8C33813EF194 -:103AC000A0883321A2921FADE6F247312E5B5BBA8C -:103AD00046C2748EC25546F9949F94A7537B26D64E -:103AE00080F9586C05CFB772B5C849F2D048B7DB3A -:103AF00010AE3C2F2A2271F81AC6FB3D32E95CD485 -:103B0000EFF730B4EF9E85B1CC46FA32617E523287 -:103B10003DCA8A5FAD47BD7C8D89D65180217F101B -:103B200071B5D5F35D2BE079E1CDB24F82E763BD8E -:103B300077539E1268F5A46F78BDC71BB03E629F95 -:103B40002B8DFB48DE57F2BA4170911EA29F57EDB4 -:103B5000195F3ADA51B5A58B288F8C7E747A372796 -:103B6000ED271BED5F93DF0672CCEE49D81733F4D7 -:103B70001376DA7F6DFD242213D25172FCEB6B01B8 -:103B80005A671AF359157AAF85EC453DAE968FB456 -:103B900083E73E9EF1B844F2FB53F9FBCCC5E36CDE -:103BA0006976303D81FEA4DBECE4BF4C4B833A9C4C -:103BB0008FA430EB3878BE4BF8FDD64B4CC67A7CE0 -:103BC000BE28E5A9774981ED3E3796DC5EB26405F3 -:103BD000280F11C3B48976E721CCEF80F635B7BA48 -:103BE000C7A2DF6E0C10440CED661197D2FD24992C -:103BF0002583CB517E1797952CB6A27C46C7D2E57C -:103C00008C5DB6B7E8FEF0CC385DA69DCB675A82D6 -:103C1000FD922677509E47DAB9F1067F4A54D85D67 -:103C20007ADD9F2337E27C73D02EC0BC26A676E3D4 -:103C30007BF500142DD13F7ACE6518273E7EA16119 -:103C4000DE28D8CF897180D1C74F675A45E2F8C5C1 -:103C5000A38C5F9634BE9A72FCF8B8D9867137CAC5 -:103C60009C5F8473EC9154FEBC95650D5797E58E6F -:103C70009E87F6C532E177B302CBC7B893C09BCD20 -:103C8000AE0ECA4B33DB797CD422E2258733DA8847 -:103C90005FB142635E5A0353656CDF9839E798045D -:103CA000ED0D0EA39E7ED5F937CDC877AE928D7AF5 -:103CB000BA9F75107E5EC98CCF2D85463E40BA36C0 -:103CC000FAFD3326C7287F2DD7417906A3F90F7E49 -:103CD000D3C928AFCA921EE840197777D9B4EC8DC2 -:103CE000D3A13E86E3D7D6B2F98BD11FF41B81C78F -:103CF0001B81EE118E2D6BC6EE36278CDBA2444B5A -:103D0000518EB498781E3FFDC0FCBFC9CD277F6A95 -:103D1000F2BC94099CE08F6AED90029E847DFC4683 -:103D2000D0C5F07C7714EC463D7678BEB4E8149AA2 -:103D30006F381F48CC97F7D9E67B43D0B33E5FEB93 -:103D4000578CFB6B5562B4BF561313F9FF7CBE371B -:103D5000707FEECF309FC8EB1A9EEFABC6FDB5A6C5 -:103D6000C5687FADC3F6A4982FEFB3CD97A6745066 -:103D70003CE63E899FEBA1BD4BEE477FFCD9F96B3A -:103D800034C437DD3EA3FB3366BA3F4372EFDA42F9 -:103D900085F4067DDC7D9DD3995FE17E1B2C2B662F -:103DA0004A740FA072BAE4C778D8C340F7FE32F461 -:103DB0004BA9D41EE97451B9A753A3F231B007FD42 -:103DC000E49FF251FD6C19B787EF1BA72E5B89FAB0 -:103DD00042BD9DE741CFBC0234D1B8BD0506D82114 -:103DE0001BE61B7E814DDA8A68BE93C323A7312F61 -:103DF00082E7649FF462AC13EA6933CC1AE677A7D2 -:103E0000B9592095DFE57D913FB359CF9BFF9CC405 -:103E1000E3EDA08FD4C3FE6F14A066E6F912EA5555 -:103E2000D77E358BF491962583192AACE30669D2A7 -:103E30002F3C008FFF2DF4911BC7733A4EB62773AA -:103E400050B24CC6BC3E732402BF2ECE584CF6E88E -:103E5000E2A58C39E1FD6BF13D902BAF087DE6E5E5 -:103E6000C13486F65AB891C7996FB8DB6847DE67E8 -:103E70008BAAA8C7DD372987E179B4AC35B66F16B0 -:103E8000F182C54976E5B5497934A065F27C10DC4C -:103E9000F30CC6DE2DCBC8A13C589147F384F00B40 -:103EA000B1C21C4AB676CEF58CC1F8639A92FA7EFE -:103EB0008E3E5E8EE03B2CC74F70D0F3CA99F9A9B5 -:103EC00049F4BE984F7F6F97F4D4B88BF935416FA2 -:103ED0007B6BB082CB67D4AF59B931DFE7ECFCE242 -:103EE000AF37B254783B24A35F415FFFFF2D7CFDC9 -:103EF00011EE17CA57667D3899DF432B6489F7CFD7 -:103F0000F47CAAC5C37599A15EB954AFBA86BC78D2 -:103F1000DEAF7D2EDDB795F04FE80FD1D74D17D22C -:103F20003FFD78C3EB70F98BB83F4EDC1314E38D83 -:103F300006E7E47C07DD6F433F53E3FED8AEDD3C8C -:103F40002F323FA7E11DBC3F85CFDF34E095F19EC6 -:103F500054D7C01312DA17DFC27B5F727C3EF4D3F2 -:103F600086497F35DEDF1A218F19BF97A3AFA74B94 -:103F70006115648F9A803FC07C0B1C83B2A4A1DFC3 -:103F80007D88EEF3DD59CECF057387F97D18AEE756 -:103F9000990B4C3C7F6382C6F53ECFD0F8C4B8D0B5 -:103FA0000DE55CAE2F487F75AD06F26F49F9938B36 -:103FB000313F69C19857D7BAA17E5DF97717CB8099 -:103FC000470B0A5EFDD00D3ADBB2F2A778BDEAD509 -:103FD0000F8BA1BEBCFC695EBF8211505ACBBFB72C -:103FE00018F9EA0DE5AAF0F3C50A71BE0512A78F0C -:103FF000CF5A9AD34C29E3F7FF50AEFB139905E74C -:1040000009F4FFE424F2A380EE7FF527C51BB12954 -:104010000FEF13899F9C4CD267E6E1EF00CFABE531 -:10402000E800BE6FB24609AEE59837534128F0C0AC -:10403000858BE44724E39104E8BA0EF5654D652DC0 -:10404000A01F77AD63415B49029E33BFC0739EC71B -:10405000A3AF479F7FC4BAE0486567E2BA1EA67166 -:10406000F4759D9E9416C67B677AFC545FD7696988 -:10407000E811744644AB0697E2B99ECE181A2F4158 -:104080005DAB5097503D77E811C99750B7F073BCBE -:10409000B7FC27A4F7AC95FCF79623BF541C74BF5C -:1040A000AD47E879DB728361C6F57BCA770C17F1FF -:1040B0007B038D93257F627CFF9B02BFF22A7839B8 -:1040C0003B6D7BC709C0C7D00189AD87FEA1F367EF -:1040D00015B4C717F49F52D0EE6E3F704A41BBBA79 -:1040E0001DEB304EFBC30AF1AB64781754980D7189 -:1040F00074DD9E385254B63107D6D3BE52F2618A6F -:10410000EC9AE7B366637DCD0ADC2563D7CFDC3F4D -:104110001BC9BB3530B011CB1BD9E0118C172C0B50 -:104120001AF5FCE56D46BDBCB5C3A84FDFB81D4E02 -:1041300007E4D78DEB0A0CEF31D490613DCBC47905 -:104140002E73DD1333D7603DE1BE8E44644DFE9D7A -:10415000E57C07501AFD160BFA25A2E3F6662BF94B -:104160005F8F14F13CFBD02A33E50585101DB0DECE -:1041700021097F969FF8A32EBF67F79D395A80EFDC -:10418000AFB2101C58D81F43FF43B3C0A71B9B9B63 -:10419000DE413C6BD66EE3727CC25E0BF957825CEB -:1041A0001FD784FFBBA5EFBE4627EA9F6B25F26FA2 -:1041B0002C6F33EAEBADF80BEA6FEBA448D48D70AB -:1041C00032B6DFB8CE587FBD5CC8DB2A568574F2A4 -:1041D000DB7249A67BC5A2FE87A25FBE1C8589EE65 -:1041E0009202A710EF5629D11A946B774941AAEB96 -:1041F000EDF0BC9DCB1D2EEF4D4051C4772DDCAFB3 -:10420000105E2D113E2E1F21FF13F403F3C87A4ECA -:1042100005F7B777D9026BC95E7A4152511F69948D -:10422000FDB2D31BB76793F13157E0F7CB6CD08B5E -:10423000EB2A43A003FCCB168F89A03FACEC9F5721 -:10424000507E63599DE433113D9BD8BA5A2C65E2E8 -:104250000FA86FDAA02C33F73613BFBE4C5179FE8E -:10426000A08B25F201FF134C4278E1D271DEAB0B3B -:104270008F7D8CE778CDCE7BCE20BFF394F86BEFAB -:1042800083F56DB3F1F9B73D2F91FEDAEE3D4A7C2F -:10429000712CA009CEDBEE12FCB10FF8A3BEFF62B9 -:1042A000BCD70FFC0A2F8ECCF7D2BCE3F4F8809E6B -:1042B0005F1B6D305D00BE3356CC5B50A311BCF26A -:1042C0006EEB9570DF452CBC1EFD44328E991B2F82 -:1042D000753FFED278BCFA9B789EAB5D830AE9DF1E -:1042E000225E9DA2DFEE94FDFCCCE047986D3E9FE0 -:1042F0008971E5352F945C34AFC26C3519E8D5A2CD -:10430000DA0D747D758591CE17F88CF47DEDF4127D -:1043100043FB427F95A17D71539DA1BE347085A161 -:10432000FF75CDB38CF6BE6B9EA1BF4D5B64A8A795 -:10433000575C6FE89FE1BBC9C86F727A297F40B1B3 -:104340008607831ADEAF676CBA33CEAFAB32AD9857 -:1043500064CCEC753607963D93D2A2786E3DF93C5D -:104360009E9AF6D2975D5184FA98A7ACF5507E5785 -:104370008A3460BCC82AECBC897733033FFFA72A84 -:104380008EE77AB9A42278632594DE7D5A01CF970F -:104390008E4DC4F3B1A20311F1F8392BE91D972515 -:1043A000E9BF4535F5CB2AF0BDBBFD73C92FD5C795 -:1043B00054BC57BB47E1F94CE1E778FEACB76FD08E -:1043C000E44FA0B7FF53C1E5FD37020D949FD4DE43 -:1043D0000FD20CF17BE79B0AFAEDDAFB0732516E44 -:1043E000D404DE5450BF8E3F17F2441EB263FCF279 -:1043F000FBBDA9F3D0BE51A1D0F84705BF6DFD327A -:10440000E7B78070F3D13ED2F967EB7EBEBFD6A589 -:104410000AD1B7CE47817F1AE261C97C79F9CCC84D -:1044200046A45DE0A306FBE5C62573DE417B0824B8 -:1044300035E931C0478DED859B88BE6F4CB26FBAB0 -:104440002A86F9A9F702D0CBC98029E5BEF654C95E -:10445000B4AF93C15904EF6F00DCD06EFCC60838CE -:1044600071F87D127C9E16FE44FD9C92FB7DA78A0E -:104470009FD3D3A3F0CB77059FDD23C56A919985A0 -:104480000276C2D3E556EB52CC33385AF4D1268C9F -:1044900027B4FE40425B96FDEBC04B799877A0ECC9 -:1044A0003F9287F910A1DE23790CE0B4CAA2AD4790 -:1044B000BD18F0C0B71ECEA5BD2F4AEB5FDD5B3740 -:1044C00080CF57F7493E6485A10367E6D03ED9E027 -:1044D00026D4E3F78CB2AEFD153CAFADBF42E37915 -:1044E000F7419813E5EC8134B2635BF7031FC275A3 -:1044F0003D2FD13D8C3D5BACCDA9F493A7AAF877B5 -:104500001B5EDCA2308CA3AC82F7711F478B8E2A16 -:1045100056C49BFD12D984A1DE134BD11F1F5A6BC9 -:104520006118B7D5D7F75E51ECB7B8FFD7575A180F -:10453000DE2FEC5AC9E3B1AFAF35D338E69B2D542B -:104540005F762BCF133EBCF2DF3615C0B8AFAF920B -:1045500028BF7ED6CD7F3C8AF565B7723D28197F8E -:1045600087F135093F97058D7837024FDB3E1B9E5B -:104570009EAC10F66B15AB41390BE73E7B2CE2CFBE -:104580009D8CEE37369F3F6C190BEB2DDEA4FA3075 -:10459000B45B6D8E6CCC43BE7098B74F5AB55BE27E -:1045A000FC45A37BEF053D0A43BBF15D715EEFE285 -:1045B00079E5E2D68624CC6B6372AC18D7E716791E -:1045C0005CCF5858F37EF423C99CBF54FFD0B53B51 -:1045D000D18FB44BE0A3CEF7AAC0DEDF4F7EE8DE7A -:1045E0007CBC8FFEB485FBC7C68BF14A4B86E62C9C -:1045F0008432BD92CFFF47B10EBDFE9CC07FF687CF -:104600004709BE0BAC1CEEF3D6455B701FB7C8C1A3 -:104610003F23FF9B3FFE97AB50AEF514FFD44BDF1B -:1046200065611349AE85C4791C9EF1EF0FDF81F9F6 -:104630007695763AC785871E8AE1B9B67B64CA3318 -:10464000B4954E1E1BBC881F21744E33DCEF6BEFFC -:104650003F33C79F82AEF757F1FD578B7B7CAC9FF2 -:10466000FB0F801FCBD36BE3FDF4FDEB7E0F5BE90B -:1046700063744E777C894DE2F7FBEFA37196AF3AF6 -:1046800021E1BD94EB2C7E8B03E0FCCB316C29DA6D -:10469000C13FED64744FED38DE570356F272A74AFE -:1046A000F598B8B7F66AA746E5754A603CCA95A57D -:1046B0002F769422BC0E173D18C0EF359C3E2EF489 -:1046C00059A6F2FB8E02F7CEF69B9915DACF1E9013 -:1046D00022E43411EBBFE15C3E0B023FF9B5B81F99 -:1046E000B77ADDCF89CFF9DACECC413B63D2AA537A -:1046F0009BB01E5AF7C739A837FC16E404E257A846 -:104700004F622E18A7E59C93DE5FDD7742417BFE6A -:1047100069D3D01C847FF8A044F7AA421D67887F24 -:104720003E2CFC2B37546671BED13FC944E7E99F4C -:10473000C8ED1371FE0313FF9489FCCBBA4E7BE5E1 -:104740000A3CC763663AC7AD0D43996A8A73390953 -:10475000E3A24FFBD7221F2FB9BD5909935FB6596A -:10476000E06D72FBF59526DD0EB7883C2526C17AF3 -:104770005A047EB532FE9DA0963E296A07BA6DEDB9 -:104780009F45FE8DD68E8B7F0766347CBBD4B29D51 -:1047900071FF865E47FB2B315F0BED2FE37DF5301C -:1047A000E1555A91676CF022FA5D68309FE227ED7F -:1047B0003D8CE225ABCF4DA4F2FDE737D3BD27AB4F -:1047C0007DE841940BACCC447AFDEAB051BF992D01 -:1047D000E876B6D06FD654827D52C186ED13B043D1 -:1047E000BE5CC9ED90CC43CC609F243F27FBC42A1C -:1047F000FC86305CF09914EB9E57D57057652ED22D -:10480000D576C26F06F88D7895BCCF8D959C3E7598 -:104810007A5E76E81D05F5DD505F6A7A5E5A55BF0F -:1048200011D7B36594FCBBAB05BDAFDEC9085EA173 -:104830009D4E82D37B6C67A001F0F23D5807DE5F8E -:104840003F1D08A467C1FBA78381748CCFE9F4DF07 -:10485000BED34EEF6DF12CCAC6EF6DECAAE4F1F3B6 -:10486000F7FB665911CE37ECE474A7CFF7DBE8B25B -:104870006CA49F29962105FD9385FDA73251AF9B1E -:10488000F2FCE26CA4BFD1D6B975A258E7BAFCA578 -:1048900074EF077ECC40F7B70B3916DA105510FECF -:1048A000B7AF6384BF03CFFD6B3BD2EFFBFDE92ABB -:1048B000CAC9F75E480F23BF3F7D302D6282A156E3 -:1048C00089EF24BD6719BC86F4C7E7CD94AF103AD1 -:1048D000F8EE83488FA1E7D2E81ECDEDFD9BCFA077 -:1048E0009C5BD53FF71D19CBA7FEBEF4B07ADDF86F -:1048F000A589F9C5EF76EECB47FEF9BECCF9C4ED3C -:104900007DCF923E7BFBF9B335983FF8DE0B7F9E5F -:104910008AFC2CF4CF67A7221F0BFDF8EC546C0F18 -:10492000FD30BD23957EF2E32AEE3FD1E5A3FB35B2 -:10493000D9E067B959E087BB7B7B137ECF60CA891A -:10494000251407D0DBA794F27BCC537ED1987D73DE -:10495000C27BDD3199F225269F684C5F998097D7FD -:104960005759747FCDA5F947441E82EE1FD9129383 -:10497000F9BDBA36337DBF6E798CC7DF93FD268CC7 -:1049800005AEAEC6F3BE35D787DFF1C1FBEB181716 -:10499000397D676984EEAF87AD473C097AD0B2981C -:1049A000299A867E90FEB428EA43CB62F2A9B40429 -:1049B000BFC86FD56736A21ABF2C68F46324FB41C9 -:1049C000E027434E889FB4AE8D5A7439B500E6FF98 -:1049D000E546A662DC66847FA4F9F3E48749F69392 -:1049E00068B107ACF89EE6E1DFDDD1F54C3CAF03E2 -:1049F00029E87DC344CEB7743AEA8E99E81CBA63BD -:104A00000D560F94FF28DA0F80D80C635E50FFE23A -:104A1000C7D14EEF3E7F5D3AC2ABFBB5450CBF2B15 -:104A2000715A6DB096E27BE73F6F5DEA8DE3C70890 -:104A3000FE3191F3C7617D6014393753CCFBF79297 -:104A400077D3279A84BFE1FF6F790776F55513B9BD -:104A50005DBD9CFB3DB85D9D2C2774FEAB8F1B128A -:104A6000F01EC97FDF21FD05EC5FE2BFA1891AF5C9 -:104A70002BEC5F984D76F16B4BB235C7C8F14B64A8 -:104A80009FC9E91D39BEAEAF85C2FE2356B463FC93 -:104A90003CFF34B444A2EF4B850212E9D9A1164B76 -:104AA00004DBF5F5C496F0B8E0529F44DF0BD1F576 -:104AB0003F5D3F1C6E9F0CEDEEB8BEA8EB85B100CC -:104AC000F78B2EF15BA8FD3A25780BC2E9B7511B95 -:104AD0003D9F32838F0B7CE008FA3FAFFB8244DFBF -:104AE000F3D2F5451D3F93F5C90FFA4B2EFA9DBA47 -:104AF00087055EEAF4353E892E7439B5AB92C3A7BB -:104B00001DE57436CAE98F9541C7E87A37C8E9BB15 -:104B100070FDBB2A19BD3FF917722095DD9D21C696 -:104B2000DF8AE7066561ECC57A5C6F118B515ED454 -:104B300068F2F3B62A4E0FA3B5EFAABC343AFE8151 -:104B400098FFEF45C7FB27FEF7D05B87F53F25F5BC -:104B50003EE755D5FF6822C0D56EEEA0FB51EC5F55 -:104B60002CE4B74EEE1712F218E499018F8F142936 -:104B700026B47B426DDCEEEFC9D25E21FBE4257EDC -:104B8000EFFE7691AF74DB3995CA1EFC8018B67FB4 -:104B9000D94D7E9BDBF69DB0F8E1FDE56BA549E8BC -:104BA0000F5ADE66DC4F4FAE7F6EA21FBC675C2FD4 -:104BB000C515C28F9768387E2B6E16FD213DF91101 -:104BC0008C3DB6A31FE7327C9E70DF02E6592D9E16 -:104BD0005F21FC3B2C490FF8F1C0EBE4EFC1B810AA -:104BE000D2AFD22F515E48E818F777B4F773BEF012 -:104BF000769B44FCE46D919F115A6723FFB6AE4744 -:104C0000BC23FADD7AA744FADE08BDC26F8CBBACC8 -:104C10007EEC17C41793F508E7013E0EC65BD02F54 -:104C200073A468AA84F5D56017E2F74B439A766DB2 -:104C3000015F1F8B107FF11BFC281F1CFB37B22369 -:104C4000973F2FB16CD23B92E22F3DF392E22F4778 -:104C50008F14E03842CF50E13FF41F26EB19ED7D71 -:104C6000272C68177C529C45A91AF6B7905F708272 -:104C7000CCFDAC13FA2515FD4913049CA66DB113A8 -:104C80009CE6BCB1321BE95C3F9FF717F2F37AFF59 -:104C9000F50FEBF1BDA96FC82AF2DB1FBFBEF6E727 -:104CA00005BCAE59357C6F6D3ADA21EFBFB1261DD8 -:104CB000E1F86328F13B4A3F3C29A7F41FAE15FCFD -:104CC00008E45B4115E6DBDE2DFCC632C8B78CB8C4 -:104CD000FF25F9BD1DC21EEBC1EF1B21FE3DCFE339 -:104CE000DB3DE382F3A8FE5031CF239639BE3EDB95 -:104CF0009FA5A2BE57059BC538ECF7ECAC1BE32B78 -:104D00003DB9C19F127D3C6422FC85F7F97727F6F7 -:104D10006B24EF106418FFA8015963A5BCC61C8A58 -:104D200083E8DF85190776A8F88EC2128CBB5689F6 -:104D300038488D9DC938FE364B706B25C65D0664BC -:104D4000DF7A7C47F665E3F79292E3317A7C588FFD -:104D5000CBE871E2D1E23212CE53C3F12CF13B2702 -:104D60007AFC857D81E76F764DEFA0FBAF63B12FB5 -:104D7000F1CF11F194D5686F26C753EEAAD4FB1B6F -:104D8000E3695B2B9E217CFBB471B41F4C1C6D7ED0 -:104D90008D9E27CF3F39EB833CB25FFEF21F9924F3 -:104DA000CFFACF92DC393D9426EE710E723F75BF7B -:104DB00085ECF5D36007E526C8B35F55F2710FF5B2 -:104DC000CF227C3C106B4CC7FE7FADE4F0D9F2DA09 -:104DD00092C5A84F876332CFC766DCAE391093A760 -:104DE00070FD60049C364D4C0127AB3D751ED054C0 -:104DF00081D753ABF8BE67BDCEED95D05A1E3F505C -:104E000005BD859A14E227478BF224DD8F3C365589 -:104E10007CE1F921E2B3ADB7F2F8EE25C717FA0647 -:104E20002CAC3885DFB6690EF19B4BF5D732B482D6 -:104E3000A7C6F9F3769D9F5473FFADAB8AE7F33BAA -:104E40003B26D5E377F1F47DA78023F35E5A9C2FB0 -:104E5000B3FAD2FA2DACB8B47E9B2B529C5F8A7EFB -:104E6000DFB8C47E3FB8C479D353D1578A7E7FBCA4 -:104E7000C4795FAAFC9FF8E7703D39BE991C0F4DBD -:104E80008E73A6BD747318DB364BF70C4511BA99B7 -:104E9000CF35E3F7D3E5ACC7ACC8D7E6CFE0F180B8 -:104EA0002D8DD6C86E291E17D5E1F55135D7BB54C7 -:104EB000EF99307E3F71BC3FD6980D747C7A062303 -:104EC000BBE1B44D7C0F4956C72DA4F353E97B38A1 -:104ED0003DB6D4F1A527C578A3F191A29AFAF3556E -:104EE00053E8FE50CAEF54DC2FF440B58F91BF86D3 -:104EF000C9DAB84534AF360EE5CC9817F9F3CC28AB -:104F0000A3FC3E68772F22FD5973E3FA7688B897A1 -:104F1000735E991BFD744E90B71817B90FE323E425 -:104F2000D757A99F3E5F9797CFB7C3C2248C63859D -:104F30002B795E056BE935C4358E5BA2BF5B2151D1 -:104F40005C632CD2FBCF4C51EF1E373F1784AFF779 -:104F5000804AF19697677CA782EEC58B38C71D2AD9 -:104F6000EF7218ED0C58C71D2FD411FE2E3F34E3FD -:104F7000572DA80F7A6482F3083D5CD85727857DAA -:104F8000A8DB5783682726D81B555ED3687CA92ADF -:104F9000155FDA2171FB37FC336EFFD629BE92C450 -:104FA0007CAA69021E2BA2DC0FABDBB535FE88297B -:104FB0000FE05077A7399A06B2B76E53B582FCBAA4 -:104FC0006E53919DFC4A2BF79B7478A73AF77AB100 -:104FD000CE2DC786282EF16CF23D732F8FBB0E09A4 -:104FE000FCE9C2B385FA1DA572178ADF3133557308 -:104FF0002ABF782BE8FDB8BE153D7CBD7A1CA435D0 -:10500000AACDC2794E1D19DA84656D9B7B16F90D08 -:10501000579DD984723374FEECD1ABC80FA068A938 -:10502000EE0B586BCCB48E6751114178CD95296F3A -:10503000B76EAE4CE7ED6CB5911DEEB430337E9F8C -:10504000D5B990CBB1DAA69C5958674BB2480ED768 -:105050001ED3B26EF6C6ED7CE7DCB5B908A74F8A61 -:105060000FE9FE82EB14FF4D788E9F363EB4FAF8BE -:105070006B946776C3A0313EA4C77B468B0FE9F1E2 -:10508000D950D387867872481E9A837E95BA174E78 -:10509000517C38D427A92E773C6E143A704621F8FB -:1050A0008A7811F457F0BD3A38F6714EFCDE008F65 -:1050B0001F3D87F9B80A7E4F4FA5BCDB1F613E6ECE -:1050C000197E4F8FE7E31EC47C5C05EF7FF07CDC2C -:1050D0004322BF37D47F86E24D3D5E63BC428F479B -:1050E000DC2505B679730DF10AAA27C72BCC766E9D -:1050F00087868E59E8BBE8A1E356E2B3F5FD2B267F -:10510000A03EA67FAFBC1DE30509FEA5F7FD3E1B33 -:10511000DEEF793FE0B3619CA06EE01D4523BE1336 -:105120002DC014A67639A6A0BD8F70A03CBFFE7A14 -:105130001BC2F513FDFA7DFFE3D7FF347EFD8C38EB -:105140005D12FFA80D98E85E79ED31BFEDE604FE33 -:10515000B025C0FDC35B3CC5447F0F048AB356260F -:10516000FAF19BB8FDE69CEBB1253E5F54C3EF0F0F -:1051700038A5D4F70B5EF7EAFED711FCF6756F4A37 -:105180007D27753C604B13E723BABF7F647CC0F773 -:105190009227C1CFFFFECFACF47717069E4F23793D -:1051A000FED10B697B50EFAE6D5A392103EAB5276A -:1051B000D3989BCB23435C617993C96FCB4C154744 -:1051C000F017D0F74293E3054D26E2EFC3F18226B4 -:1051D000F914D5857E7EC3997FCFC04F643F2B45A0 -:1051E0007AD0BE7876B5E41B6023E3073070019B6C -:1051F0000EBB68E27682AFD94A76C127C5155A0E32 -:105200009CD8887E82496C7B0F7E7F7292C7A48275 -:10521000284A1157E0F99DB5428F48F60F207EA02D -:10522000DC4FF60B665673399459CDFD983B51AF60 -:10523000CF8D8FA3BF977CEE5F147269343FE3621A -:10524000D1DEDD54BB05CF2D3CDFC490FF77373571 -:10525000583D09E3B9AB79DECC0E8C53E424C62962 -:10526000783C22393EA1F3A7BA818FE7E0B93FD05D -:10527000CFFD472117F767D61DACA77B26F17572C6 -:10528000FC7CC0357CCF308BF17D312BF773915F87 -:10529000A176FE8787F0EF12B04016FD9D83D07196 -:1052A0004F9703F9C87C798AA4917F7BD8DF8DFE64 -:1052B000A8C5AFB4CDC37CE0BAA5934EE0B92C6DC0 -:1052C000B150DED1E2579AE9FBE3BABCAA5BBA7BE4 -:1052D00003FEDD9AA51592CFA6617B5303B65FFD51 -:1052E00054143D7B6C01AE0EE825761C7A17937F33 -:1052F000BBBE1AD65BB750F8BD5BB85C5DDABFD0F9 -:10530000C23F6E659473878B3E22BBF96C7F1DF99B -:10531000B3B331DEEA8DCB99BA1740FE64C4E5CF52 -:10532000DF2A77BE58CDEDC0CB40FEE07A9C0B79EA -:105330005C30F9FCDDE2FC479327A3F14F941FFC9E -:10534000EFF2840B24575CEE6A684F4F8BCB5FB54E -:105350000FEA6347C7BF87847E95358AFEF580C014 -:10536000F751F335FAFE3E7EEFEDD5FF3DE257BA39 -:105370007DA3FBBF757BE8F702CE7AF9AEC08BBF89 -:10538000395F198562CA7C6567EA7CE51B7A25FA74 -:105390000E8BC8573EA2B0FAFD3998A727EE2544D8 -:1053A00002A4DF1CD9F5EB4D4FE4E0BD044945B143 -:1053B000B3BAF704C9E7D5A0CF901ED4FF2EF74BA0 -:1053C000F5F2FCD2D57DC6FB0F7AE9ACE1F1F646E9 -:1053D000D80FF991451EDF9C039CAE437E25A2B9F0 -:1053E000D12FF41539D12F14D262B97A7E6084CBD3 -:1053F000A594797CED6C88F2FDDADB241FCA83CF9B -:10540000EC27F2F3FCBE4BF513FDBCDA987F7AAEC5 -:105410008ADFFB690E4A12EAA356536015E5F71EB0 -:1054200094D45479A2EF087973B5F0D3EE55381EB1 -:10543000ECBD5CA2BC5ABC1783E7BBF720CF9FDF53 -:105440005BCBF3E775BFAC9E175F19F7CBD27D1826 -:105450003D9F5ECF8FD7EF872EDC698FA27EB1CDC7 -:10546000D2EB423A1CFE4E0FEA22D06E17DF194FE4 -:105470005EE72FAAEB775553BF51F59B3F56A7D058 -:105480006FFCC24EFB73F5A87AF95FAB8D7A39D504 -:1054900093F5F2FF2ABFEC37C43E53F9D552EB67C0 -:1054A00023FABD7889FD7E980A1E5DB6D4DF0B6DA8 -:1054B000AD11FC37E9EF92B011F77BB87CEB91B4FA -:1054C0005F5D41712E0BC5B974FED293C1C7F78AD7 -:1054D000F1F4F2F3359CCF8CF65DC945A2DF5AC9D1 -:1054E0005F553305BF1F6FF49355F71AFD6497F5A9 -:1054F000390DF549D17C43FFBA63C586F629B189D8 -:1055000086F669276B0DF51983971BFA5FF1768391 -:10551000A1FEB921A39FECAA738B92EE1D71FCAE84 -:10552000078C487C6F96F58B867E056DC67D15755C -:1055300018F735619D715FFAB8EEB0717F253DC6F1 -:10554000FD39D17FEFFDECFEFB9857E3DFC1E92F7A -:10555000A1EFFEED68F2D077AEF5FB7FFF09FEEF1D -:10556000D922F072000000000000000000000000DE -:105570001F8B080000000000000B53E16760F8512A -:105580000FC15BF918182EF021F8F4C01CCC0C0CDC -:105590009C40ACC8C8C02001C4FC40CC06C49E0CD2 -:1055A0000C0CFF81F81B10BF05E22740EC0CC40770 -:1055B00058B09BE3C6CAC0E001C4DC40B378988908 -:1055C000B7DF8917C17ECCC3C0700E889FF1D0377A -:1055D0000C061B5E27403FBB7E43ED3A2932F0FEAE -:1055E00006612131609A1447F0A78AA3CA0B8B2168 -:1055F000D8C9D294D9950FD40F00F19321F080032C -:1056000000000000000000001F8B080000000000E8 -:10561000000BED7D0B7C94C5B5F87CBBDFBE92DD45 -:10562000CD26E44900370960501E4B80C84BDDF0A1 -:105630003252C40411828A2CAF10027914A9A5FF3A -:10564000DABB0B2804AADE5851A37F6A17041B2D6E -:10565000DA80D11B6DE02EA208D56A684551AB0DEA -:10566000888808498C8F6AB57ACF3933DF66E7CBF3 -:105670002E89B6FE6FFFBF7BC3AF1DE79B993367D3 -:10568000CE3973E6CC9999B3268383192E60EC1B2F -:10569000FCBB9C319B893136A62B6D573A86AB39C2 -:1056A0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D45 -:1056B0007907C3779FA1306867EC5EBF8BF2BFF0BC -:1056C00017525AEB2FA27A77FA4B287FBBDF47E9B4 -:1056D000667F197DAFF157537E837F0DA59BD4451F -:1056E000692C05FA66458559C98C553D9393B719C0 -:1056F000725B668D4F504743FE15233366017C9FD6 -:105700004AFD31D5BD69E0E8AE7A1A9E9BD449FDC9 -:10571000104EED128E17B3325B8C7A5938CE3B9710 -:105720000878F6D69A9CE4A8F50623BCDB4B00DE8D -:1057300050287085AC39D1E15D8CF03697A8BC5EFD -:1057400072B0263B3A3C0FD6ABB941C04B0F586301 -:10575000D41B83F536DC20F0EBE7ABC98ADEEF78AB -:10576000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4E04 -:105770005D2CF246CC263136AEAB9D3E652CC0701A -:105780009C2AF315121FDC995F7F93CFD84D081325 -:10579000DA0726B19011FA0F24B1E0FA2CA9FE4CD9 -:1057A000AADFDAF7EB6F52A5FA014394FA26D6A0E6 -:1057B00060F9CF518E80EFF7F97329DD28E4E7BE59 -:1057C000A106C6B05DBA393808DADDE3F790BCDC73 -:1057D000ED1F4BE5770939FC7721674121670FA25F -:1057E0009C41BA15E5CC8CFDF95A4B014EFBDE7895 -:1057F000B6D94DF2B598F05419C1DFB077C8F6CDDF -:1058000000FFBE1B569DDE06F46F6B1EE63142BDE7 -:105810007B866AF2C5BC2CB9ABDE3DB34F38170DA1 -:10582000257A97219CBB3D827F2A0C2CA2DEDD339A -:10583000C2F52AB0DE5D9E30BC5064BF774D09D7FB -:105840005B457C56584983BD3B5F763085E623082F -:105850000AD1D784F48579F9EC80EB9456689F924D -:105860009C97C6A0DDFD381FCD38EFDC4417AD3D59 -:10587000D2D907DF332CAC1AE10365F71B015FD3E4 -:105880006C7722D2E5F66B8B98328CB1BEA23C3598 -:1058900050A464015CFB9C2205BF9B6643397C7766 -:1058A00089F2E435BCFC762C7774952762397C4FFD -:1058B000AA8672C8DBE7F2F23BFCC089C15DF5360F -:1058C000019F7DC4EF74FE1DD88AF4318DE6A98650 -:1058D000F713282440BF83988EE9C27FD3A07B337F -:1058E00016DABBF0B50DAEA7BC86DFA6C17194D7A2 -:1058F000F0B15DD82F6321A47D97F465DE5C311F84 -:1059000058773A277AB3A5F24CD593A0029D325F1F -:1059100032B200B02013C413E1E9DB153103E1D941 -:10592000E3FC4BEEDDFC330D95E9A0A547053D34C6 -:105930003A6CEC2FD3C13240A6C3C601321D2C17DE -:105940009C9F0E3B989BE81C8B1E5ABF9B87C8FDF3 -:10595000C65D24F7BBF922B9DFB88BFF39FDD664E9 -:10596000C9FD5AB3E57E6BB2E57EAD39FF58BF4C39 -:10597000F5C064407DA5FD5D28E9B7AB99EF2CB675 -:10598000473D87F349D373A6641FF3D9BBF809EBEE -:105990001463F99170064B7A15E07C8AF5008EF756 -:1059A000FC705C3A3883F470BE16F8B0483DDD0DEB -:1059B0000E1BA81F8749E1ED428688FE99EA6345E0 -:1059C0008EC8761E5DFF39FAFE9D8A1887E1BCFD00 -:1059D000BB7574CDD6E39326F06186F3D183B97499 -:1059E00070B2F470DC029F90725E386EFD382E1437 -:1059F000FD071469FD027A0CEB6AD70EF8D13A95CF -:105A00006709EE04FD10DAF7E5295C07CE355EEB99 -:105A1000B640FDFD232DA1CBA1FC5CB0206881F236 -:105A2000C94F1E75A21D53F1A451C572C33E1BADD3 -:105A30002F6D3B142AAFB2B4DC3901CA3B9E34B29D -:105A4000EDD45DA601C7774AE81416E2F9521BCFE0 -:105A5000566CDB7F23B62F6BB2301BC0AB787AD984 -:105A6000CC09905F76C8C4B04AC5CEB5E6BE905F9B -:105A70001E541A300FF8D23A15C8B3057742FD7597 -:105A8000FBBE6C43FCCF359A06213E67609D70C318 -:105A90003AF192A3257536D0A73CB87B1AB62FDF12 -:105AA000A57840C301FE3B0F6620FE8F281E0BB079 -:105AB00070457D3C7347CC97538D461AEFAA6D4ACB -:105AC0009001BC65AC761AD2B302898378782C41F8 -:105AD0009BD235DFCEF8EBA83F2D5FF108F407ED40 -:105AE0002B1F573C38E44A03F3E13C6E7BDA56F255 -:105AF000901DC7BBD63CD881E3DC68C67ACB820B4D -:105B00009FB2B911CF6DE66988EFD66DE6D2A14894 -:105B100047B6A06828E2F77F65FCEA8C5E1CEFAA16 -:105B20009196ED46C083D943036739BAEBD933B0B8 -:105B30005EB923D6CF72067A9FD6EFA0B97858D730 -:105B4000F72F0D89A43F56D41B99DBDAD58F261F7A -:105B50008123423EF63A88DE1A3F57B9F814D0F84E -:105B6000B92A51F057EDC89F35AC3B3E77225FC84C -:105B70009E7651FA0B583731DD02EB3CD2EF5EB026 -:105B80009FDC64977BE8FB03602761BA15EC244C2B -:105B90001F043BC92DEC24ACB71DEC244C77809D31 -:105BA00084DF1F067B1CD37AB0C7F1FBA3608F6331 -:105BB000BACB1FA0EF8FFB6B286DF0D752BA07F955 -:105BC0000669A33F48F59EF2D753DAE46FA0EFCF02 -:105BD000F89B28BD5DD0D1399115E03AEAF432172F -:105BE000923D6986B7C004F9A4229E4FBD21506042 -:105BF000867CAA0FF24097BE2B430516C8F7ADE688 -:105C0000E5036E6193AC901F10E0E5D9B77B27D90F -:105C1000209F5DCBCB076F0D4C8A83FCE0202FBF0C -:105C2000685768523CE42F6AE0E5C39BD9643BE4C3 -:105C30008787783EEF25EF6407E4F35A783EFFCF7D -:105C400081C94EC8E7B7F2F6E3CF068DEE28EBEF39 -:105C50001E937B31AA9C03CADB5E3503F266F74DC7 -:105C6000A8128F2AA728DF68F252F9FB4ABB578592 -:105C700075BED1ECA5F22F94CF29FF94C947E5F169 -:105C800006A580F2661F95F737C451BEC914A0F26D -:105C900011863E3C6F0E507981A15F01C27FC61410 -:105CA000A4F26B0C8378DE1CA4F25FA8C30BA640A1 -:105CB000FDC70DBEBDA8EFD62BBE32B40F99DA904A -:105CC0008EFA4AB32B77E2E0D0CECC30D33CD8F377 -:105CD00087FC87681EE05F32E64B1F46BB14E01C62 -:105CE0002438268063EC194EDECB632538792F9754 -:105CF00069705E2138B6DEC1D9F3F278199F97CB6F -:105D00003538C7088EA377E3CA7B65A28CCF2B2BCF -:105D10003538C7094E62EFF0693C2AD3A7F168987D -:105D20003E67707D589FD23B7C46BF26D367F46B9D -:105D300061FA7C4CF864F40E4EE36B327D1A5F0B13 -:105D4000D3E72B82D3BF77E31AFDBA4C9FD1AF873D -:105D5000E96332209CACDEC179EA6D993E4FBD1DEE -:105D6000A68FD380F419D4BB71E5BF23D327FF9D41 -:105D7000307DD2089F21BD83F3D43B327D9E7A27AC -:105D80004C1F37E133AC77E3CAFF8B4C9FFCBF84D9 -:105D9000E93384E08CEC1D3E4DEFC9F4697A2F4C59 -:105DA0009F3C8233A677F88C3D25D367ECA9307DE4 -:105DB00026109C71BD83D3744AA64FD3A9307DA60B -:105DC000109D2FEDDDB8C6BE2FD367ECFB61FA5CEA -:105DD00045700A7CF5840F03388ED8709E3927D31E -:105DE000E7997361FACC213853014E4ECF70C6B794 -:105DF000C9F419DF16A6CF02827365EFE03CD32603 -:105E0000D3E799B6307DCA88CE57F56E5CE3DB6583 -:105E1000FA8C6FE7F4A9B278263BD0BE4B649EEDB6 -:105E2000D0E492930D079C9037D99907C1BEA48402 -:105E300076207C582BC92E543D9A9DE2616887CE0E -:105E400070BA3DE8F7316AF6086BA1FD827D57A272 -:105E5000E40FFAD230E916C4D701565BA45D923044 -:105E6000364EB28712BD4952BE4F615FA97E4A517C -:105E7000B6549E567291549EE1CB93F29965E3A578 -:105E8000FAFDAB2749F90BD64C97EA67056649F945 -:105E90009C9AEBA4FA836A1749E517D6954BE5431C -:105EA00082ABA4FCC5F5FF47AA3FAC619D543EA25E -:105EB00069B3543E32F40B293FEAD00352FD312D31 -:105EC000DBA5F24B8E3D2A958F6BDD23E5279C7E6B -:105ED000466707CAFBFFF5058CDB831966B20743EB -:105EE0000E33E5CDFB6C64FFEFC73CF0D3DC7706E7 -:105EF000E5CDCF2E7627E37E1A01C07A5FD0B7ECCE -:105F000042F4F7DC3CDE77A10BBEDF6CF68D70450A -:105F1000F1477854DF3E03F98B5A14968EA9DB8043 -:105F2000699C51ECD72D5CBE3666E53F148890D352 -:105F30009AFE30FF207FD86026FB5593EF8DFD4BF6 -:105F4000D31746F4B3A1BFB964FB50FE7DB11DFB6E -:105F50002B7A11E75995B96330E2A5EFC7923D5608 -:105F6000EAC73AA08CFA790DFB89F07B590694E9CF -:105F7000FAB1966C17DF453FC7705CB1FAD9983D0E -:105F80005E1ECF8072EAE75D5D3F1B0794EBFA89E6 -:105F9000E3E381EFA29FF7CE3B9E9C89F2782E58D7 -:105FA00049FD74E8E866B960A5AE1F3BF583DF17CD -:105FB000933F17760169C0674B4729C9C17FDA58FB -:105FC00000E4C29C59FE6BCCB3B76C6C10F6E38650 -:105FD0007EA11ECBE5FEA3A70D49349ECFE280FF34 -:105FE00011766AD77E3640FBE2A5024516048C6026 -:105FF0007F5B296473C9AEE20137B9216D3A30F095 -:106000006EEC678BC33308F26D4D93CD8BA3C8D371 -:10601000D25AD3A9D648BF88B6BF99C472ABA1FFE4 -:106020005D369794D7D2958A8B097F04E54FC0BE21 -:1060300085C17EE0CFB02F6040AA774D7C9FF60EE1 -:10604000EC6F30DF0AFB1B2C676C2DB53B21FCB4D9 -:10605000276E578248EFCF7EF24313E9F1007B357C -:106060003D15FD6EFC6FC19A78F4F187F15B18E87D -:1060700023E5415D661AD2695F48FBDF8EA72DC11B -:10608000ED48D79A4CA0A9A897CDD8EBB0C9CD4878 -:10609000A26CA6612C63B3AB8BA7A6D12C52FAAF2E -:1060A000023C67358E34410BD6666ABDD163EF8200 -:1060B000CBBCA613481F2BFC4338D714423EA2FF8B -:1060C0006B8BE4FC5CA676E581DF838DD9826FA2C1 -:1060D0005FB7D7847C2D4AE5F8CCC5340F8BB9BFA8 -:1060E000A3C4C5DB6AF8542D36B110ED4F03290C5B -:1060F000FDD18164AA779DB6CFD4E15762B27A8B85 -:1061000080AE250B8D44573DBE6FEE8BF71A86434C -:106110005A73B7095D9B3DE13FCF2797B332DE9FAE -:1061200046574D5E4E09FE9E40FE43FA3EF21FF07A -:106130003E29F8DF25C79CFF5516DF4CE47FC7FDDD -:106140004646FC127C9F23F8BEB456E6FB1CF49333 -:1061500043FD39ABB382EBB17E5D1F89BF307099CF -:106160000EB5774D05B5DA0DFFB7851C5C57B3FB4F -:106170007964EFF565BAF1093EDC28F8305F478FA6 -:1061800039826FF305DF96B1C06D19E43F0A9AD0EA -:106190002F36AF4C61A82FAA7EAAF1AD55E29B4FD6 -:1061A000E39B0EDF1B05DF6EFC09E79B1EEF56C16C -:1061B000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2BBA -:1061C000A0E75BAD38777099D1DE29F616F439195E -:1061D00051FF9AC22BFB9C8CD00BD716154BF9B9EB -:1061E00025F3A4FAF37C0BA5F2EBCB964BE5F3ABCE -:1061F0007F28E517ACF989547F6160AD54BEB8665D -:106200009354BEB4F62E29BFACEE7EA9FEF2E03662 -:10621000A97C45FD23527945C36E295FD5F4B4545A -:10622000DFB06FC8D5285F2F1D3532F4977DEA792E -:106230009FFC759F7A4C1EAC538932370EE5D94DC1 -:10624000F27CCA9F4BE969BF87E4FD8C7F2CA56D6A -:106250004D07ECE87FAC8A03BD9F0876B8F1CDB559 -:1062600035FD70BD81F6E3196B36B6AE0D40FE000C -:106270001E46C1BC99516766A1510CA4BB6F589EC4 -:106280003B8C11E5AD3D94D7A92CD4A77BF98CD6D6 -:10629000E8DFDB958EC119E8277CC3C27646F8EBB0 -:1062A000BA9F57B04CB42B62959F35B0B2C8F3ACCF -:1062B00093467E4EE2344E3A698474A599CFFF9599 -:1062C0007B32263127E64383ABA3F85DC2FD350060 -:1062D0003269C8E71C69DE2FABBBB86B9E33EC2775 -:1062E0009BE476797094F47D45FD04A95DAEE27B74 -:1062F000D708F5CEEE37D27ACD4207065C330CF1E3 -:10630000F39EC4EFAC2985ECAE16BFB7CFC9818C24 -:10631000FDD15F48E9ABFE224A5FF397507ACCEF9C -:10632000A3F44D7F19A57FF65753FA8E7F0DA5ADC7 -:10633000FE00A527FC35949EF4D7527ACA5F47E940 -:10634000697F90D233FE7A4ACFFA1B286DF337511A -:10635000AAE9CF9EE4EFB4585FCFA0FC459133F398 -:10636000AD6C5DCDC42E398B532DEB50CE34FACEAF -:10637000A8B308794895E42111D76192B31ECAEBFE -:106380004C420E63B58F5E8EF2D6F77B9037C6D641 -:10639000911CCC1472F75DE58DA1373E05E52953BC -:1063A000274FB21C6A72A4E9815CA568B83AA64B73 -:1063B000AE661AB99DA4C9D5CFD14E8C626FDDA04F -:1063C0002A62FDE3F611F36518D07E5B25FCFECC56 -:1063D0009D4EF94ED1F77A00D782F5D4602EAE23C8 -:1063E0009DB97F1B8CFEF1CE6316867EF858E3D3F1 -:1063F000CB4B6CBA7B69FF501A84456D54F7725BC6 -:106400001CA7ABCDC00A591E9ECFE61FF3013FE388 -:10641000FEF3E23CDCD7C27795915D15F41447F1A9 -:10642000B73394F1B49EE9ABD53FF5C097F9786ED8 -:106430003E53CCF3B803467EAE1D7AC8734DC4F903 -:106440000CECB7D3D1EFDC31C8EC22FB21D457A63A -:1064500063B0AF44C703833E1B8CE71B9B400E71A8 -:106460007E750E1C9CC0CE231F3DE9F99EE8B9281D -:10647000D8B797F434333C37027A6EC7FB2FBDA5EB -:10648000674F7AB227FD786233A7B353D8A7B1E834 -:10649000DC3E09E65D1439BE475565396603F97976 -:1064A00087467FDC9746D0FF52BB9BEA3FB7EFADF4 -:1064B00001ADD04F67E385098C9FE7905DD7F1A4CC -:1064C000B0DBDD99321F5BFB125C0DCE734FBE3E1D -:1064D00000F7C9B76106E6D993F145BF5253BAE058 -:1064E000F5F61C3ED6B8767FCBF9D99EAACDCF96CD -:1064F00001284F9F093D10737C3DC9298E0FE05C38 -:10650000A5F0F16D3016FD0EF54C787CA3537A356D -:10651000BEAA04335346007E0EB3992530B643F528 -:106520001D54691FE7690DA09F625FBC673DB0A461 -:10653000CA79E6E5901BDBC9FE8C15F536976C3FF2 -:1065400025BA64FB29C315693F751E7AC8E903FCA7 -:1065500056A51B5C2747E13AE715EB1C5F5735FC56 -:106560002A1AB25C76098E9CEFAC550A1B489EDC59 -:1065700009B3A39C9769E9AA74B3EB24AC5767EA03 -:106580007312B0DF337EAB8BAFAF2E17EF37DD1555 -:10659000B9BEAE5C1347F535FC62C1FD67E3C75871 -:1065A000237BD78AEB2294E5C4AE1F939FEA27662C -:1065B0003A976E367D86F6BB2D57B3DF55CA6B70A2 -:1065C000AB1A8C01CB08FCBE4BEA0FDAB9B53366C7 -:1065D0006C175B6E54764AE327F0DF8A07EFB46FDF -:1065E000B5129F7D003101E0B5ABF61A94AB132ACA -:1065F0009FCF55424E2BACAD669F9BC8DD82F2BC4F -:10660000682CD326CCDCB7404F7FF0A289EE69B16D -:10661000AF007A7ED7558125ACC8894ECF458D2BEA -:1066200066E0BAFD8141DB0FD7E6E3B8CF31432105 -:10663000EAA573EC8FCE5111F3758889FB63580D71 -:10664000DFE704E01F8E6F69ADBCEF595627E74BBB -:10665000D9AC54D4B7A55B4C2C08B82FC77D933662 -:106660006ED0BF1926EED758C6AA37E03EFD5E139E -:10667000F7F72C72313513F0AAF88F5FE6A3DFC766 -:1066800063E27687769EBC3C89E35D3E3B68F642DA -:10669000FD771B47CD018D0BED831BC8FE29669E40 -:1066A0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA61 -:1066B00076AE2DF048AE57BCC1287AEE329322F662 -:1066C0007F7C7ECC36C9FE9C7926D9EFA3C981494F -:1066D000C8C109D577B5690CE73BF251513BCCBE37 -:1066E000887AE6AE7AB3CF57CF82F58C546F9E2965 -:1066F00005EB754CA3FD3103791ADA55CFD605EFBA -:10670000460E4FAE57F11F8F3D15007929FFED3D25 -:106710004E06EBE6076A6DAA07BEAFDC799BD30B8A -:10672000E96935E0447E7E10341646A3C796303DB5 -:10673000BC7605FD69423E594D80FC149FED34B98D -:10674000C8CF5F6F0959404E2B1B97CF60C3297F7D -:106750009CE7377E64C47C93CCAFF25FDF93EAE6BC -:10676000F76CB83F8985C8CEADDCF1DE345C2FAA6A -:106770005807C999BE1DF6FF7912CDEB85E684EE68 -:10678000E58027F913AAC42CAB6AFCF9474627E633 -:1067900065F92813F62AD209F7F9B7991CC9A7E2B7 -:1067A000217B09BB04E7B9460F16E476EBFA47EE06 -:1067B0001B7E1CF039BBE345A73234523F7039EBE6 -:1067C0006C58FC2BAB21B61E6903398CB48F00309A -:1067D000B57337097BBB99A72B4D2127DE6759B9C4 -:1067E000CDE40109642B1F3332BC07C0DEB004D1F5 -:1067F0002FBAE2B1E75F1B0F745FB1DB943C830FEC -:10680000C7AEA476F1A50AFEB726AF8B0FE54F3CC5 -:106810006F760FE3DF6F49EAE2C78ADDFBCD6C5884 -:1068200077FA4D6ED86F6EB547E14BC3F169B8CEBC -:10683000AE7FE4AF66F4277EB04F616959DDDB9728 -:106840006D7B9ED63BA413F151F029CCB76EFC0AA8 -:10685000CD7C6634D573A11E8CC5AF6542EF823CFA -:106860003FFE0CDEFF79D3E2C1F1973D7E9313C763 -:10687000F1BE5ACDE5FA97B7A5E2FC2E3305525D7D -:1068800094F2EF650FFE88E46DD9911FA592BDC00B -:10689000BC1906D2C5810C1CDFD2ADD7D2F84A99FB -:1068A0008FE4AEEC97C622BC8FF8A9CA0A77479945 -:1068B00017716685F0797F3B183230BEF7717F899A -:1068C000FAEC8F46BA17C5D80FE9DED88FC45861E5 -:1068D000E5A3FCA756CEA7E3424FE24496E475C772 -:1068E000C616E4CF99FEDE343CE7003A0404BD94BA -:1068F0006F00AEF1C8D434CE1FE656F3453BD0EF5F -:1069000093F13BD66F31796DC3A576421FF2FE57E6 -:106910008BFE01EF385CAFDE4F8D6EEF8D11E383A0 -:10692000BF1616215F11F39BCFF71D9BF8FCD6E62F -:106930007BB0B810CB3F7995CF1F6C87EB03E01588 -:106940004AA3F2FDB315D207B0AF8E36AF7798C425 -:10695000BC96CBC152A4F51EF0569584483901F877 -:1069600049447FDA07976E817611F65715F647F599 -:10697000CC5DDF23D68765420F98CC30FF2FEE9A8F -:10698000FF6C2B9FF73DD9932B4DC1871FC0F9FAA0 -:1069900086C51370E37C3515E1B83FDC75E0B5EBD7 -:1069A00040AE3F6CD0E6A9AC3FF5F3B46CCF1816FF -:1069B0006D9E7E6887FD55B4790ADFA3CE537B2B8D -:1069C000C9F1F7AD3F35BA0D35CB7A13F5E033EEAB -:1069D000D8F4D3EBC1DF9BDC4447BD1E84BF5759BD -:1069E0007E77B9D3E44D93B3F2DF545C80FA262C62 -:1069F0008F9ABC85E5519337FD3865BAE9CBFF2AFC -:106A0000F4CDF5D6C26BD02EB67630DAAF14CC36D4 -:106A100006719F6CFD84D17C9F74433CE5E71A5B53 -:106A20009F409BEFAD8AB9C3701DBF9E054CFCDC37 -:106A3000BCD64476EA57DF7C3311C6739DA0EBF5D4 -:106A400040E6AB800F25AA128A033CE7A92C909060 -:106A500084FE62859D88C0E3FA32398F7F97A576E0 -:106A6000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8488 -:106A700029ED2FC0708E90A3E2667E4E51355A09E3 -:106A800066D3FC6B558B22F6098F99B99D7164CA48 -:106A90003563907E05738725907CD70EA17D609528 -:106AA000D05B9D017702EAF3CEE61CDAF7751E5A39 -:106AB000ECF045D15F07849C3D2FCE59DAED4AAD0D -:106AC00011E4BD9D7590DD12B0DBA2FADDEACC06C3 -:106AD00061EF08BEC19F11FA2F1172380F9A26E498 -:106AE00045F06DF6551FA8CEEE7CC0BF1311FB8696 -:106AF0007F94BE28D748DF03B6D6694551FC338F53 -:106B00000A7D7DD9B35F98719D9BD25CA0221DA7A1 -:106B1000D88D92BF63BB365F87B2A188D765CF2E71 -:106B2000BF630CC871D521A3C706E3AB6AFEC8ECEE -:106B30008BB27FD3D313E1A3FDD86AE6F6F15153AC -:106B4000D152A4EBD16BF979EE9FCC9E8A6878CEB6 -:106B5000B6723CE7B1A24F472BFF7AF42D98EB08B1 -:106B60004D027A74DAF9FDE4EEF2C7E77DA74B092E -:106B7000AE55500E8D3C9FCCEFFF4E63BE3B262A98 -:106B800034DF2F8FD45F054DC58FE17D96CA66C572 -:106B90006580F24AB5D58C725CD5B45B45BBFC0709 -:106BA0006EFECE82A9D5C36647F8B75ACDDC9F7476 -:106BB000E06FD7CD47FA7E3CDBC2102FEFD08F9C21 -:106BC000B8DE7FDC3C8AE641AC71FDC1EFB9660AF4 -:106BD000FAE3CD5C9FE9E5615A72BC94BF7632EB73 -:106BE00087E7BC97595A6FF244E1DF3A0B9FA7BD84 -:106BF000D66FD6FF61FA6D22E8372ED7A648FD364C -:106C0000DDC2E53E42BFA545D36FABD6BAD3502E09 -:106C100056EDCD4943BEAE3ABC34259A7E7B41EC5D -:106C20006B0F8B7BD2EDFD40BF8D88D06FFD40BFD9 -:106C300045F1838FB66876670FFACDFADF33FF5ED2 -:106C400040FD1665BC5708B9D3F45B61F35AD26FA7 -:106C500085FD8CD27DA4CB2CC28E8BA9DF16DE7372 -:106C60002DE54D9EF828F2837445FD7658E839EC01 -:106C700007F5DCCF2CDF4ECFCDB3727C7BD473FF16 -:106C80004D74D6F4DCAAFE0AD92FDDE590EBB95598 -:106C9000595CCFADDACBF5DCAA415CCFE9F5DBA4DA -:106CA0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF39 -:106CB0005762F258A1FE0CB7F6BEA07A4CA4BEFBF8 -:106CC000992586BEF380BEB3F7ACEF5E417DA792F7 -:106CD0001E1B88F3482F1FD307C64BF7D58E7E7136 -:106CE000EA37BFC5F9F20723DD077ADDC0F743FBBA -:106CF000BE38350AE7DDCB880FCC979D42FEDAFC23 -:106D000063499F4E1ECAE77BC5A1385A272A1B1527 -:106D10003EDE5B94A01BD781BF7D4EFBE4F97BF97F -:106D20003E79AE85D383FDD8C8DF4500091646C835 -:106D300043C9E7E5E4E72B519915EDD70587A67F11 -:106D40008076EB82CF6BC8DE5D80DFF17EC5EED64C -:106D50000D99D0EFFCE50AED3798B80FA1DD97B893 -:106D6000BE793FDD5FD1DF83D0F4F9FC6AF9FB0225 -:106D70009D5D7F408C13EC59A20B7BC518D53F77E6 -:106D8000404F0F0F1F7FC56A6E1F87E901F4712BFB -:106D9000DDE9011C9DB130B56BFCF39F8471257753 -:106DA0008D4BA3877E7CDAFE6481981BB1C6ABD184 -:106DB000AFDB78357AEAC6FDBC45D84517B36138F4 -:106DC000CF5E37F8EE188372F17B183FE03367DE51 -:106DD000A0B4483DFCA2D0E757F98E4F497523BDBA -:106DE000F8FBBBEBCA763F9F0AE3B8DA9B9587575F -:106DF00011AEFD9BD9877E8403B60ED26B9A5C5D83 -:106E000068E572FE7701E7685FD7145A3F9A141756 -:106E1000CD97904E6F897B6155404F9C8F554D6249 -:106E2000BD0179C3F9364D5B7F90FEF09F573573F6 -:106E3000FA57552B44FF99ACE320D2B73259F1846D -:106E400000D4B4A6DDB7E13DAA176CF01DE76D993B -:106E5000E2D9CEC961CF488D2A976A34B964D54347 -:106E6000C8AFA0AD830BB05E12BE17793D05ED1320 -:106E7000BDBD7199A5E528E271D98F4D6C1BEB6EF4 -:106E80007F68FCCE857FDF44BBCFD383FC0E12F638 -:106E9000E50B486F3BD2B5C38C725F15E2EB8656AB -:106EA0005EA5BAA7107D347A37C1BA309AD31BDFFA -:106EB0007DE9E979B5964779C6FACD8A09DB5F099C -:106EC0007CE80345930D5F1CD4E417DF89E9E98270 -:106ED000FBFF8C88F98E7A29F2DCB1B2E908D16522 -:106EE000FA6A30AB22E88EFAEA7CF4E9361F9AF6A9 -:106EF00047BD07F56DE7C38556793EECB375BC38E1 -:106F000002FD5B7B15D207AC3951DADF5F61E5FB2F -:106F1000A603361FC96DC76113DDF7D6EB8DB182AD -:106F2000FEB89F887C0737190782E7BB2E1B7B576B -:106F3000C3239BCB4FA4BE7EC1E6233EC5823F4DFB -:106F4000C08F652F85F1C5FEF03CC52DF7A75F2FDB -:106F5000343F4F4FE3BA46ACF7DF755CE1F349D6F7 -:106F60006266DC9FBFDB1C71CE3447F8F9353F58B1 -:106F700044BD999631B1EBA1BF2504E37E61D743AF -:106F8000E4D73DF7E8F19928B72B7E676456E073A4 -:106F9000DB2E070BF17B14665C57CB1B8D51CF4565 -:106FA000185B4FF8ADF8AD83F44AF91E4B7006B488 -:106FB0002F7FEADDE1E89F6A5BC7F54BE051211FB7 -:106FC00081D6E1785E5EAEF2F3623DBC1F0B79398B -:106FD000FB747C09EA47A59EBFEB2C6F986BB2440B -:106FE000ECCB2BF1C08DD7A37BC8814714F28377FC -:106FF000C76F2DAFF708D77BE54DA620BE0F2DAF8D -:10700000DF46FBD9AAFA8FCC68C74DFEED63644713 -:10701000543519653F61BD3164213FA6F138A67A28 -:107020007F5D656305CDC7CA06E10FD3F98B56FCBA -:1070300076EF530120CD8A277EED443D73A665A7E8 -:1070400093FC70F5DCCFA6DAD5E87EB89EFC6F0D18 -:107050009BA2FADFCEE07FC0FCDB6A95FD6FACBE81 -:107060004FAFCEC1573CF6E983782E7476CF870FA9 -:1070700022DE2BBFFEF8C19FA27DB2CFE6C2F5AEE5 -:10708000EAD1A3E457D7DA3D25E655DB23BF7EF8E6 -:1070900001987F6D6F58E8FE55DBDEF707B8619CFD -:1070A0006DBBBF4845FFE5EABD5369DFB2FAC9C908 -:1070B00069E7BB47827219ECC579889E0F071A8D64 -:1070C0000CDF419E3B66213B23EC476DA8E07E69C7 -:1070D000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52F3 -:1070E0005CF71A4D1E377D177EC09EFCA6AF023F8F -:1070F00047F4826FBB845F5CC7B773F81FC09F3FC4 -:1071000059657FF3A78D4B7FF5009635F689E937F2 -:107110000DF5825EDAB9D636ABF71D2BCE873DBFB3 -:1071200021FF34F20B6C6ED6F6D8A703D0DF70DAED -:10713000D47123DDBFD86BA17B42E57B5FA7F9D17A -:10714000F6E4113A2F62E25CA98D85FFF83980D808 -:10715000CB54ED70707FABA03BFA63DD4EFA2EFC92 -:10716000AE5C6E357F6C2C3F6C1F9BB8072ECED962 -:107170002A76BC65663ABFB63216F9745C3A17D403 -:10718000C6AD87E7423A5C12799E10CBCF2DF468EA -:10719000984FFC1CA16D9B385F089F1B30D62F0FAA -:1071A000EFBFF3F3EEAAA0F23A8B321FB5F304A7B8 -:1071B0004D371F83BD3B47E819DFEF460FC5C6F7C4 -:1071C000AD1A5DCE7E155D1F0FB129E2FD812FD76F -:1071D00016B1EE2C10EB4925D08BBF27E3F89E1596 -:1071E000FBBBB38F1A83B80FDED07080F4AA7E5E2B -:1071F00057B2E8F143C6DBB83EA96CDA3F1CF5CFC5 -:10720000D9679F26B9ABDC75DC1C003807EB9F30D3 -:10721000B70EED9273D4D7C1087D7DF6F1FDC3F9A9 -:107220003907DF47EAE15F21E05735CBF0AB767DE8 -:1072300024C15F116830BBEC3DF77346F5CEC5F154 -:107240009E6931515C94330DC6C268F14A86622052 -:10725000A9942E3A6D70F0F771C62433D991AB1D05 -:10726000638F2524636A76E33E7AFD5A7E1F72FDA2 -:10727000CF3CE9C897F58973E81CA856474757B231 -:10728000AB00F7D7AE2945A351ACF47A20D16B906F -:10729000F05EED284CC3F7DCB70A7B84A91E7ABFE9 -:1072A00067744E2BC471185D06972DEA3ACAE199AE -:1072B000EC45142FC2E492DFD37DEFF11FDCFDE437 -:1072C000F80F817EFF68FC07467130FEDFC77F083C -:1072D000603FFF02F11F42E4B7D1E23F247FCFF1CC -:1072E0001FD63239FE83E06738FE83E0E7FFC67FB2 -:1072F000F8FF2BFE8331EEEF53303E8316FF21253E -:10730000CE3C3532FEC38571095323E33F8C8B4B52 -:107310009F1A19FFE10771595323E33FCC8FBB68D4 -:107320006A64FC87AAB8515323E33FAC8D9B48792C -:107330002DFEC3DD7153A7CAF11F664E9D02F9B63B -:1073400038DFDF71BD8A15FFE13D9C2C637A8EFF2B -:107350000070CC716362C77FD0C38915FF01E02440 -:10736000109C18F11FBAE11323FE03C049273831DE -:10737000E23F74C32746FC078093457062C47FD008 -:10738000C38915FF01E05C1497123BFE831E4EACCF -:10739000F80F006714E11323FE43377C62C47F00BB -:1073A0003813094E8CF80FDDF08911FF01E04CA570 -:1073B00071C588FFA087132BFE03C09949F8C488C4 -:1073C000FFA087132BFE03C0994BF8C488FFD00D94 -:1073D0009F18F11F008E8FF08911FFA11B3E31E233 -:1073E0003F009CE5042746FC073D9C58F11F00CE5A -:1073F0002A821323FE831E4EACF80F00E7A7042752 -:1074000046FC876EF8C488FF00706E253831E23F75 -:1074100074C32746FC07807307C18911FF410F27FA -:1074200056FC0780732FC18911FF410F2756FC07B7 -:1074300080F32B821323FE43377C62C47F0038F530 -:10744000248731E23F74C3E7BBC67FB085062A3983 -:1074500014FF81E24486E33F247FEBF80FCD88EFF1 -:10746000FFC67FF89F19FFE166BBEFEB38F2837E22 -:10747000B7F80FB6F86F17FFE1667B517C3CEE2F33 -:10748000BF65FC87D4F86F17FF01FA498F1F13BB44 -:107490009F58F11F7274FDF414FF01FA1974DEF1A4 -:1074A000C488FFE0D1D1EDFB8AFFF045DCF9E33F72 -:1074B000FCCBC559806D0A9EFF149328B27F99B802 -:1074C0000BD7C6FF93E32E90B1F0AF1477417BBF8B -:1074D000DF60C2F5EA4DC1F7D7845CBC25E22F1C02 -:1074E0008B197F217815F94597CBF117A60B3ECE66 -:1074F000F3C9F2309DF1F386E953B278BCCC325D2A -:10750000FC855CF9FC7A86EFC81400C7AEF2C8E3CC -:107510003822E46166C947CF217BAE1E1B3DFEC207 -:107520002CC18F621D5DA60BBE158BF47A7C920276 -:10753000F23CA3EC888A749DE96E55C9AFFD038DBA -:107540007F6E897FB3055C3DBEB304FF665DC9F9FC -:10755000A7C7FB55E49F13D2B251C43F3DDE7A3C2E -:10756000F5FC6791FC8E889B51C0E4B80B93AD721B -:10757000DC85A92E39EEC215E972DC852BDD72DCC3 -:10758000851FE4CA7117AEF2C87117AE1E2BC75D16 -:1075900028F6AED5C57DD8A48BFB70972EEEC3FD23 -:1075A000BAB80FDB74711F1ED1C57DD8AD8BFBF04F -:1075B000B42EEEC37E29BFB8E6B0547F69ED112921 -:1075C000BFACEE0DA9FEF2E071A97C45FD07527932 -:1075D00045C34752BEAAE90BA97E6FE33EBC2ADE33 -:1075E00003BF26DE031F13EF81DF8C11F7E1AF3FEE -:1075F000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC86 -:10760000838D15F7215C1E23EE4357FB6F1FF72177 -:1076100025F99FFF0E3FC7CECF3727C44FCAB1A76A -:107620007CF777F8D716C9EF99E796C8EF9973EC0E -:107630005C9FCFF3C9EF9AAF2F93DF3597D97CD9F1 -:1076400088873EEEC384786F8E1DF5A5789F1FC294 -:10765000F7A9B0363E8BEF53217D0EE33E407A1002 -:10766000E33E407A08E33E40FA7B8CFB00E94B188E -:10767000F701D29731EE838A712302226E448D88FE -:107680001B512BE246D489B811411137A25EC48D3B -:10769000681071239A44DC8810C139E13F44E949FC -:1076A0007F0BA5A7FCC7283DED6FA5F48CFF34A583 -:1076B00067FD1D94B6F93FA7B4B7712334B9FC3305 -:1076C000DA0D66EC9FCBB126A733EC033744CA69C9 -:1076D00091FDA20D28A7B1E245CC459AA6C48E170C -:1076E000112E8F112FA2AB7DEC781169A3BFBF784B -:1076F00011FF16CFE5F51F8D1731BF5A8E67B060A9 -:10770000CDF9E34594D98A56A35C6AF2F86FF1FC8F -:10771000BCAAA77811DBEC8A58AF812E6877015D8F -:1077200068BDEEE1BDFD738E8773713FD1997BD14A -:1077300079E31CE8E52236BD795C83EBBEE73811BE -:107740003DD155ABFF66398F5FF06FF1E78F5FD0AA -:107750002D4E444FF105067D467AB2B771227A5A12 -:10776000177AA2E7ACEF394E444F7AB5277DFAC7B6 -:10777000E99CCE13E2CF1F8F231C17CEDA72901A2A -:10778000BBBC34B555F10EBC60B68BFC27EDBBC459 -:10779000BD312F73BB52F93B75B437DBF7240C674F -:1077A000F47EDDC5BCC09F78F15DD9B57F3F9EA753 -:1077B000DFEA64DEC4248A07EF36E6E03E6CA415F7 -:1077C000FD29158D1FBDFC3B806B6B36D27DB276DB -:1077D000C0A185EC3E6F22F22D9EDD4EFB743CE392 -:1077E000FAA64FE47B66DDEF37609588F39BA946E8 -:1077F0003BED9B3AB7F27B9E4676F17D1347D37DF6 -:107800006A167413FFC84E5D21F0ECC414EBFBAC98 -:10781000643F2E3BFC447E88F1F3CA48BF419F423F -:10782000D94F5367730EC777952CE06D41FB7B8969 -:1078300080975224FB6F3E5C547808CFE997F84A52 -:10784000E91E425A89ECCF61E2DD386EC7C2F7E526 -:10785000009FD226853DA0747F475ED67CD706DC8C -:10786000E72C0FEAED6F968B7256CEE23CB8EF5DD7 -:10787000512F973B1CE23E879DD97B45B7D60BEF36 -:107880009B987C5EBA7942587F9783EEC32E3BBCAF -:10789000D88CCCB2A4CB74B3B965BAC5E7CAF4D15D -:1078A000D3CFE191E9A3A75FC258D9FFA5D14FBBC0 -:1078B0006FA832715F34C8EF91767B87DFB48DF0AB -:1078C000D4D34F4FAF510E714FA28B5E45D6545259 -:1078D000F98467861A22F9D6CF874C7B48C1FFEE20 -:1078E0009F1C5C4BAD3C0E15F5563A07CD9425BC5C -:1078F0005D3CCE078C2BCB3C341F70478FFEDD7870 -:10790000F66721F7EFB26F20BDA9F8B9E38BA07439 -:107910002BCADB08FEFB0BE4AFD27E3781795CB863 -:107920008F6AF05BDD4B543C1764EE2503F13CD0CD -:1079300045E99DE2DD6FFB5046FBFE86D027A97826 -:107940008E76675EC74CF43F542D6545B87EFDC802 -:10795000C9DF5D6C12E90827F7CF6C2E3230EF6873 -:10796000FC1D1E635041BFABCB7BF872B4479B4DEF -:107970006E7A47ECEA78F97A2A1F45EFA3330CB503 -:1079800023111FA84FEF6BDB9BDF752E8ED0C36DCD -:107990004D770FC1FBC5F71BA2BFEB2D7568EFDB61 -:1079A000F8FD8E115D71064A1D63281EC19DD9D058 -:1079B0004F657127F15193CB0982FECF954E27FC7D -:1079C0009E6C56DCE8AF9B66BCE107C300BF714705 -:1079D00055AEBFC4BDEED1A2FED3CC938EF88EBB04 -:1079E0009429387FC6BDC13C0124717529DDA7FBF0 -:1079F0009D73DA21E4D7946690279C0F67ED1EBC37 -:107A00002A3FA645BE2F9738C57700EF175E728CC8 -:107A1000913EBBE498AABF1F63C4FDFEB856F9FBB4 -:107A200004DDFE739D26774E968A72B7E52B23E11F -:107A3000D5DEC13CEB006EFB92BE746EDBFE09230B -:107A40003BB1FD2B6361B4FB25773BB8DFEB7E33A5 -:107A500023FD7D7FA99DDE393C5B5A7E01DA179FAD -:107A6000FDC47741343F65849D96C0DF9F7B13D86A -:107A70005894C35B154EEFDA8CA228EB9626779AC2 -:107A80001C6AF297511AE78B765F33D9C9EDA34987 -:107A9000A5B98A19E5679FC290AE6DEB00AFF3AC54 -:107AA000DB01B62E13F1A96AFA98EE61599B95A8ED -:107AB000BFCBF384C3C9EF03AE0BACC5FB1737C311 -:107AC00024423D9561AECD8A063FC0B6905DFA80F6 -:107AD000C3CDDF0D58451C21B53603EF23B4354D1A -:107AE000BE7203E0F900CC07E4EFFD260FE11DA80C -:107AF000608CEE930A7F5DBF996CDBE608FB77AF85 -:107B0000A3E030CAED6107B71BFBF83C0AE2EDF9D0 -:107B1000FB5F9D08BFFD730BF1AFAFB037B57627A4 -:107B20001D9C3E254EEF016CCFCA9249F9787C4EE0 -:107B3000F7923EE837077A47B1AFB4753DC9C7E859 -:107B40007C22C96E089272F27ADD2EE9BE7780E659 -:107B50008D360F584861F85E5FD36F4AB31272805A -:107B6000DC8FB6DA4378FF2CA90CC69D8CF13CACB7 -:107B70001C5E8B7A56F66B813CE6A371CFE8BD3F65 -:107B80003A5211BEA6F7347D796B22D747B7DEA5EE -:107B9000523CD0AD6AAB0DFDA9595EF7240C4D9354 -:107BA000A4BAE95E4AFF323E0FE3737E9918B6032A -:107BB00060928FFCDAB820DA7BA60C94A714A49705 -:107BC000EF4307A4C30F753C8BE682C7C6FAF0FBF0 -:107BD00053424F08BB669A58EFC6BD67E0EF284393 -:107BE00097B3C8F7457A3D0172FF27FCFD9EFBDF86 -:107BF00053294E68583F944EA3F58919871E403982 -:107C00009BF022E3C751423FB8E01FD2E792977C36 -:107C1000EB118DEFAA17F4FC66216B388F3FCD3640 -:107C2000EA10CCB7C875D629D67BA1476E2A1EB8F4 -:107C30001EE797264717DCE231FA22E8A86F1FF605 -:107C4000532AD6F077770EEA91978C783FACBD0037 -:107C5000F80D747912E70BD03BF193E095C8F72D3E -:107C6000CD57D850BE6F0D4D72CD803689D6226269 -:107C70005E22F3923F270FA8837122D69350C07ED5 -:107C80005D2DCA72A6E03DAE42C9DFA3FD2E1E0CDB -:107C900094F812E603C871E43D564D3EF5F2A8C9CA -:107CA000EF7ADC60E1F91D7ACC21352A0DC4200B76 -:107CB000DBEA423DABD997EBC3F65C22ED33560BC2 -:107CC000BB68BD7D9A95D4C0FE645ACF57E3FA04D1 -:107CD000E35F9DC2681E68E3D0CB63D5E706168CD0 -:107CE000D81F54A91D748FAFEA73330BF6C171FB13 -:107CF00026E1B835BA8C1474D1D321DB29F69B82E6 -:107D00001EB1F1CC77E1FDD944AB976D243C27D16E -:107D10003DE786509E15D7DBDB7478F602BF39D17C -:107D2000F053ED31F013F1DB2630DFEF5A415EF313 -:107D30006FAACBE0EB057B353D827FFA7933B6A99C -:107D4000FA803962BE687E5DFD3C19D1CCAE41BA85 -:107D50008F0BA90CCF5F7B9A2F9F88F156C5737A42 -:107D6000B5CFE9188CF2B943F5553BC9BE6835600B -:107D7000DCDFF6A719CD67CFFE934E8A6FD4D2BB56 -:107D8000FBE99A1DA5D94FFA7A9AFDA4E95DED7E2B -:107D9000F876A7CF8FFD2B4D209F30FEF52EBE2FFE -:107DA000DAEBF0ADC3EFF130063C4A62B9A12CFE2C -:107DB000FE5596FF58F21EAF93E706A013FD4E1630 -:107DC000E8FF414A773CB4FEA73813F9790BCC663B -:107DD000D443FDF219EFAC92D1FDC97EC3990FD700 -:107DE000A77E79FCDE5F50ACDBDB84BED5D2BD8ED6 -:107DF000A2FB117F93CA0296BCEF8E37A28AF7B11D -:107E0000B73BBDF7A1FC590BBD348E4C17F3A0FD59 -:107E100099A93628F86E3269A55BE1F7B059D73BCE -:107E200026809739C35D80729289FB68ACDF1C3D68 -:107E30008ED6134E9364677A58384ED513D82FD800 -:107E40009907CD80779F195ADC2BEDDCC6A3209DC6 -:107E5000DA1C7308E9B64F156E8F27727AE9F703BB -:107E60004878C44F15F9DBCC4CB525B1AEDFE13411 -:107E700058C98E8F679E06D44B2F3BB3C5B9A8A7B0 -:107E800006F3FFAE7658138776C9F19D13677954D0 -:107E9000A8E2BCB47338EE99409E0F23BE6D133B2D -:107EA00007DF4AC4E818C0E5C66B94E2E268F46FE5 -:107EB0003249F4B7E13E3B520F3ACCB48F6C53E2F7 -:107EC0003C38CFDA962B1C4FC52AE206A9F2FE5F9A -:107ED000E8234DBF763AB308FF7816A07D00B37A49 -:107EE000AC748F5DE08F7115C9AFB3373EB81DCF4D -:107EF000A3747114F57116272FB6D3BD8B2D7B6D2E -:107F0000B42FED2CE2E7F39DCD16D2BFB1E6691A8E -:107F10002A83F3C40B04BA7520DDD24CD589A8F7A7 -:107F2000D2E6F3F9AFA7473B0E14F73B7F3005A32A -:107F3000BD57D7D2F4F4BEC56897A567A453AA7DF0 -:107F4000AFB3AB51EF611B1314294EDF10E851ECB6 -:107F5000738C09F0FD9CEF8FAF7959D7BDF6BA3815 -:107F60004EBF4EDFF8848751AE40E0E8F704B473AB -:107F70004DB19FD7E22769FD6CF15B8B31E467DD82 -:107F8000A2E9365C075298F7CA793829B798D84ED3 -:107F90006A972BDD77BDD73FB218DF276726F07BC6 -:107FA000B49F6C994AEF9953D93ADB60A043699129 -:107FB000C183FE80738BDE741A407E1665B6E4A31F -:107FC0009C26987C990963C87545FB8D6525E660FC -:107FD00008E8955C070A81E818B892E8B8D010D58F -:107FE0003F9C9DC0F79D6F89F5243D7D40F19251E6 -:107FF00091F97E44574D8E60FE642C19DD150F13E8 -:10800000F87951429479D06E624DF85E42D347C9F7 -:1080100042CC347DA8C97132CE0FB4E38A403F49C7 -:10802000E77D5035B5EBF70C95E617BE403BD679AA -:10803000E924D237306F6B48CE73B9FEB4A13E8BC2 -:10804000F05BB5EF7DBD3FBE637AFB671F3BF05D24 -:10805000CB5FD40E07EAAFD3B7FCC98171C0DEBED7 -:1080600085EF936FD4D9FF5709F90826144D41BA0B -:108070002EF0FF3D3FD25E636BB8FF7979507EBF33 -:108080008AF7BF23FD80150DFAFB00011EA74CFCEB -:108090003EA79E0FEB041F96EFDA66CE7463FFBE19 -:1080A00039D8FF69B1BF39DDE8A0F7141A3E8B76E5 -:1080B0008D34A3CDFF97668B78A7D762E27AD93B40 -:1080C00003DFE7F804DDF4781EDC174FF096DEC31B -:1080D000DFAF2E84BED6805EF435F3384AFA712CB9 -:1080E0007DDB3D0DFDE84B3729B48FC3FAB7C03AAD -:1080F000E15BB391DEF1E8C7B93020FB73F4F11A0C -:10810000B5FDC032C1FF25F86BBC3951E23836F3FA -:10811000F774CB74F645E7A19C781CFF9A0461675D -:10812000E7B34B306EE79E43D909D1E26168E95964 -:1081300071DE8FF7FA313DED67944E4970F3785D4B -:10814000CD476E46B9AA6CDA4DF111F705DFEB3376 -:108150001EAA14347F6144A12A10F6D87C618FEDE9 -:10816000615C6EC08EDE8CF27FF9E73A3B5A8CF38D -:10817000064DEE0F2591DCDC80E31A8EDFD54FA291 -:108180008DEBEE04F9FD576FC7A58D471B9F565E1B -:1081900021DE9FEBDB69723E45C8DD921DC51BFAEF -:1081A0000229D6EF7D7F8088234771B63439D2CB40 -:1081B000C932C1B7B03C34DF41E3D2F806F29E2E9B -:1081C000DE25A5A33FA327B9D0F3BFCDD43A00E75E -:1081D000AB9EFF6D31CE7DB627F0738D256EEF34EB -:1081E000F4AF8079B8C115613F9C566B0FFE14E760 -:1081F000D10E2EC791EB22194B2F9A689D5DE57029 -:10820000A725DA05DFC6E1FB454B00EB69FD9CF2D3 -:10821000D7CC1A48E78DB5B3060EA4771B946AE550 -:10822000A5F77FEC44FBB43D97917FA1CD21E37B83 -:1082300004179B319872FAAF545BBE7E0B75D08EDB -:10824000168ADF7AEA2BE19FF8CA52186D9C6713F1 -:10825000B81DA8DD3FB951CCA31B9BF97BBB455B87 -:108260008BCDE4075823DFD77849714DCB84A6BE68 -:10827000869166E4B39E1F4B3D57D03BF06E7C6108 -:10828000B7135F97EADFB5897B4C0B847CCC74B95C -:10829000859DE6A377C44BEA8C64DF2F7357D3FE2A -:1082A00066851AFD3DD61897E1BCE3D18F6361A3C3 -:1082B000427A4F8FFFB21D6B37F465387E3EBEEEBB -:1082C000E308F5233D23C6C95A2FE7EF32C5BAFDAF -:1082D0005F995EED8C008000000000001F8B08009D -:1082E00000000000000BB57C0D7854D5B5E83E7356 -:1082F000CEFC24334926FF21413C21111212E29089 -:1083000084000171F24BC4080301826075405184FE -:1083100090207A5BEFABB79990682DFA7AA358CB8F -:108320006DEDFD062BAD0A4880A08126E9041403FB -:10833000040D820A96D68014B1053280B5587D8F1F -:10834000B7D6DAFB64664E92426F5F87D69D7DCECC -:108350003EFBACBDFED7DA6B9F65ECD94B720E636A -:108360000FB7CB8CE53356FBACEC65A98C2D63CAFB -:10837000E9BE0C46BF6BA9F85F67E59204C6EEC57F -:108380003F5568DB57553278AE5CAE9985CFF56FB7 -:1083900090995982EB1EEF53C971D036498E461819 -:1083A000C71E379EEEB33066817FD746D33C8C25FF -:1083B000E0FCFCD723B1A75260FEB38AFFBD08786A -:1083C000EE2CC0E181799678F873F47EF8FF32C71D -:1083D0008C2F2478DFFDEDF229730E5E5D6D32C0C7 -:1083E000F8A52F496C1D8CBFFF69DD78B12EFD3AD1 -:1083F0001EDAF0A3B9E91981710F7B9F0BE9C3DA8B -:108400005456C0D87D023EF6EA7F05EE73F84DAEB5 -:1084100008C632ED117167B3A05BC0265D4B63AC3B -:10842000CE1A99C3A2A03533C2233B64F46E02B8BE -:10843000D644C08201CE355BA3BD1EC4E3EA68C644 -:1084400046C0B8F68D26B70DE6C4DFED8C9DAB6F48 -:108450009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB1AD -:1084600089408FB6E7685CB7E29A6487FE2A4BDFE3 -:108470008FEF5683F03899D363995C696286C07C2C -:10848000FA7659B3F1CBBEA0751621FC56F86312EB -:10849000C02FFF3DF8D5C4685B006EFDBC7FAADF2E -:1084A0001002F74A85395B6C81F568E326DA0DB472 -:1084B0001EFDF37A7A30E6A5717ABAAC443A04D15B -:1084C00017E15400AF3D1D56EF5A89F888E0F67465 -:1084D0008411DC1793D6CD3D93C7D8617C00E0AE04 -:1084E0001DF132F55F515C6E7B3C5EF48F728DC77F -:1084F0006762199B323CDE6046C6607C2ECE0FE37D -:10850000768539F3988CD75DB1C807D31BFAAA2CAE -:1085100040AA3AFBA40A05DE33FDB9BEAA30E83F03 -:10852000629FCCFB9BFA8E5A1C8C35B02915A5F0A6 -:10853000FC63700FE7BB5E9B6F762D66C05735807E -:10854000534B0CB4C7C6BC8DF256D35B5921454280 -:10855000CB984FCA057E7046FAAC39D4678530AEE9 -:1085600033CAFD1FB8BE55579B2EC938EE98C2E5D9 -:10857000A53B8EF0A000EC61F05C53B853B503BE90 -:108580009A622C8EC654BAEE098BC1BE535583AE87 -:108590006BF4C0E7108E2603734643DB75604C54C2 -:1085A0005FF6F078EBAA57AB14A0FFBEFA0C6AF5A1 -:1085B000F78B4CF674073C5F6460EE16DBE0FBAFB4 -:1085C00022BF109DD414A4736DB789E41C7F12F0F0 -:1085D000FD2AA1876A81405100CFAA63CC171E896A -:1085E000E3CABF50B06D95D8E910BE6281BE3C3C75 -:1085F000DC37DAD6E27C4A309F703C152BA9554A0D -:10860000D07B4B6D99217D39D19081EB6172B8633C -:1086100013E0574E31ACDE01EB976F8616F0A1D810 -:108620001DF212689B4BA6CB4BA16D34B2852DD8A1 -:108630001AD8F2603C750879D2DA4B76D76F90EE93 -:1086400017DEEF2DB0929E1A6927F916EB6D941C78 -:108650003ED4439E2EE6D804D79A6417E37CDCC24E -:10866000908F7F2FE671980D3B55E0D7F7EC0F12F6 -:10867000FF3AA20C8FA642FFA3E615150AF0AF231E -:10868000C570251578F478F34ADECF325C190DFDFC -:108690004F9A6B787F2A4C99CCD8C9E655159E6CB9 -:1086A0009C97EB31B6C59985EF510C12C9A9B2D789 -:1086B000E46D843F9B22393F3519812F6370BC4A9A -:1086C000E39F6A28DE6C05FE578A9DEA6A1BC73560 -:1086D000F2C3FFB4D5F0285B0DAB118FD822BECF0B -:1086E00088756B7460ADCEAC39A8175A9C5973234A -:1086F00010AFEECF11AF793DBDD3510FB77EF0492A -:10870000813B9BD30BE7C9EB612C12D673E1AD9B88 -:1087100036CA52803E97EC45E7515F4BA0A61F87B3 -:108720007549AA9DDD0372D7E864AA09D695C85E8B -:10873000B2A3FD30207D4005B532AE5F3AA35C5F49 -:10874000E2736CA48FEC4CB5DDF515BE5FD3CFACF6 -:108750003766483DACD757A69CC765067C1093D2B8 -:10876000767C29EAF3DF9A1DB7A8088F933D0E7037 -:108770006C333085C5107B642870DFCAC21DEB5096 -:10878000DE1D2CC903F2856823E0E01707F6D02828 -:1087900064485B073C5FCAA09D8470DD4AEB929100 -:1087A0009F2630978C7AAB8079ADD8F677BC9584CC -:1087B000F87A3E8CDDE782D6F22A737A83F4467E1D -:1087C000B444F89F1563A436DCD83217F934FC1290 -:1087D000B3A31FD0FF0B9382F38360DC89D71DFB0B -:1087E0000D0CE1FCB5D16B8F82BE3F53515F6681AA -:1087F000F9FA059DB5799F37A999D1D0AF8A91082B -:108800002FBF2EE2F6D8FF85C9FB722AE2C7B2DA83 -:108810001B2457E3A3F9B8BAB8E2B1D1F07C4B47B7 -:1088200038C3F74FEA0C3720FE376FC90D433ED8E7 -:1088300086B881F5C798ED8FE07C315700DE54BAD9 -:10884000EE24BC2AEA8428C06BE14C9BBA0EF0FEF1 -:10885000EBB09699C8F7FEAD06F632BC629BC93103 -:1088600007FBDB2EAB76D4B3BF4E6D09A7F56C3595 -:10887000D07AB685FBC7AD01B8D7652815089F62C9 -:10888000650AEA5FC550AC3E02D7A74573FDA8E96B -:10889000E39A6895FACF4BF0FE5C1C57447253265E -:1088A000DB48DEFAFDCC6B86F7C4CFEB95911EE179 -:1088B00073809590DF159FCC703E17121A5A9BD18A -:1088C000AB929E75DA9600DDA70B3D3BFD644D250E -:1088D0008BC48EE3D854986F9FCDC8705DB7B13EFE -:1088E000D902FDDBAE32870FF9E7AA427E981DFE62 -:1088F00005FB7B65629E5F494C898271455FAA0AD0 -:10890000F257110BF5DBCA36947F81F6ADC4A2BBDA -:108910008EFE5C24B64AE03ACCB3285AF861A3D85C -:10892000A86BA4CF60D6046147555C7FF67FE1BA9F -:10893000FA2B4C0E5CFF769BF3E3A9A8077B8D6CAA -:10894000131B5E8E7E550F1A7D0C08C7D570E68D01 -:10895000253EB421FDC76D68F684C17AC7A5F3F939 -:1089600091DF506F8CFD455C2CEAED8868AE4FB40A -:1089700056E32FE4237B14E723FBAD01F9FB5E7480 -:108980002A8DD3E409F90BE7D963F42E760D61172C -:10899000812FBF877CB9DDC62A90CF9F1961598886 -:1089A000F2A4BD67B7E07B7DFB54C39A2E23AEFBD8 -:1089B0002FA0FF01EED2E4ABA660FBDD15C7E12DD1 -:1089C00093BF25BFFA62BB44FE7C423BD7D7C17C34 -:1089D000316268BE7801F17A3DBED0C7011A5FEC02 -:1089E000B81E5F74FF637CF18B68E1DF0ECB17DF8D -:1089F00046E2FA1FEB2849647FC78F69137C30DC9D -:108A0000FD2956AED7F4D7DB053E779B9AEFCC41D4 -:108A1000B9BFCBE040B906AAA7CC05FBB23B9C3F4F -:108A2000C794D569D8DFAE703DB2BDDD4C7A64BB6A -:108A3000CDED267B9D6461E82730C5DDF77DD47FD1 -:108A4000C916755D10DF3E2EF4408BD137E573F407 -:108A50007F0F70FA4EBE2B5736C1B8110F70B9CECA -:108A60003F67DA28C33CD53145BE6818DF17CDED26 -:108A700062DD1918057C597BC644FAEDADCE23E5BD -:108A80004E1BF9374EE4AF497B8E941767E378CEDF -:108A900047DDA2D5FA53704D3164768E25017E5D97 -:108AA000C24E4C615C0FB9903F72027DE634523C7D -:108AB000A6F1413563596827E6F639CA908DAA2A8E -:108AC00042E95BED9B4971DFFCE3CEB20858D77CED -:108AD00097EEBEA07FB58EFEE007FF01E564D5E608 -:108AE000DE4E1BF2ADCAED698B697516F77B56A792 -:108AF000A1FFAFC911FD004F2DBFCF78795D901D4B -:108B00005763F83A9F752874DFD367F2DE0297FE49 -:108B100037E3CFB5087BF3AD90E3DCC7DE588CFCC0 -:108B20009BB7DCB90FF1BF284EA6EBFFC97C96348A -:108B3000A48F4321FFABC5A8967C2E05C631C595F1 -:108B40006183FB7BE2C3F3F0FDD531EE6B4827A6D2 -:108B5000F8BBF1B94985B9792857B6094DB1687F95 -:108B600034B801AE8A4DB6001C1A5CE785FEA98EAA -:108B700059720DF180CFA15E693B75D682CF6B74BF -:108B80006FE9B8C4E91D447FA47780FED27DD8D7B1 -:108B9000F06011ADD6FFE7E9EF1B89F41896FE18D7 -:108BA000F747FE8FE83F2A6608FA833F958ED73550 -:108BB0007FAAC5047E7576A0AFD1BDDA5E44E31C02 -:108BC000265819FA4F9D1057A21CBAA3D1B9613B80 -:108BD000EDFC5DFDBF3F3B0A5C4036292686CB930A -:108BE000C93F06FD8D093E89FCBE0920F0F7909F24 -:108BF0003592F49D43E0879D95A4B319DC05BF969B -:108C000082FE9F2F16E56082B9D287FCBEC33A3D33 -:108C100005FDB75CEBB434E4A737331E3B8426E78D -:108C2000CDE4E53B5F51037E8EA6D7F68969B5F7A3 -:108C300097C770FADF0E6A16FD3D740D83E1D0F41C -:108C4000379205E1907CD5866B56D2C7ED7D80AF1B -:108C5000DB110EC06B97C45A517F17199C7125E820 -:108C60008FC5FB14EED77D3D4A05BEA96C7FF73852 -:108C7000C25B69B1F930DFC21CC6F37D41F912BD98 -:108C80009FABF9259ADFAFF92D5A7C89FE0DDECF17 -:108C9000C7EB00BFDD0C00A2FDF159BC0DF0FEE7F3 -:108CA0002FAB994E21AF0AACA352AC6336EB25B87B -:108CB000D8B7D7AE4D03FACC12F8A8EC86B8300777 -:108CC000EF337617E0E12E85C78B7739203E0CE233 -:108CD000A3D99343FBF89B9E1098E77AE3F5FA7FBC -:108CE000AAC817FCB371A6D676831D3A0D0C70B0D6 -:108CF0009EC73485A3658F82F1803BD380FC5827C3 -:108D0000EC1A84C943DB2321AF8586BE1C07E0B77C -:108D10006BCF3764FFF6EEF9E623F4E7A67CA130CB -:108D2000333C5FF8457E14EA07E60A9DB7EE8FAD47 -:108D300056C6AF13FFD48AB5EFAFC78C18C267A170 -:108D4000F637E79F5F8FF37D7946E1BC2DDE5F6EDE -:108D500072A7DB6DD8F2787FBFC4FD1DEDFE7E23C8 -:108D6000C00DD737C568717FAF42F919F89983E80C -:108D70007C17C6FBB901BADE75AEE20B2567307D04 -:108D8000F0F7FF23DED7E2FCB744FCC0F69D30A924 -:108D900000D78CD64714F4A36724C9CC19F4DE3B62 -:108DA000542B7306C5FB6FC4E8FC907DAFAD9F05E7 -:108DB00076A4AE477684A1BCB66F3F9483FD5ED99E -:108DC000611D828FF4F89DD1FE8882FC9F10CBE557 -:108DD000E67AEF2F1C077C722BD29D911F77B14052 -:108DE0002239D2D377EF9E9FC7F6650F8FEFE1E868 -:108DF000AFA7C36FCE1747215EAE470F3DDF76C2E8 -:108E00003A3DB03E1FACD303FED6DE7A3BF5DFAE73 -:108E10004FA2BEC6AF751DBF8C457F4DE3D3B25880 -:108E2000CE375376AF8F65B600BD347C5D1474AB1E -:108E3000668EF9B3E0CF5D922382F48487F5261520 -:108E400004EC55F5B172F233347B552D671B51FF9D -:108E50006AF60AD3C2A8CFF4F6697E7A9111D5AA30 -:108E6000DE2EC1028DC8BFD50B43AF57F4342B1192 -:108E7000D433109D2449E043F8D51A3C1F3217C162 -:108E8000ABA7A7069F1E2ECD9FAE1674837596E1E5 -:108E9000D2E7AA45B48E417655ACF746EDA93936EE -:108EA00034CEBA72AEF4FD9C21F87538BED5DFD74A -:108EB000F44039BE20975A0FFA1109B10944AFF2B4 -:108EC000AB26E6047BC14686B1CF82F3EFAF649256 -:108ED000BD7B54D8DFE1F8A6F6AA81B96303FC6331 -:108EE0006C7BCE8AFCB35B69B662DEF136DB9CC676 -:108EF00028C053E91F8BE7A15F57D76760989A2A6C -:108F00006BBFB40FE3F6BAE3CC81FAB0B8BDAB04E3 -:108F1000F9ED6DA557A638FA4BC69E0BF20FDBDABA -:108F20001BADE83FB5C5C914A7EF8FE6FCA8DD6F00 -:108F300089E5FCD776E6F22CE710F73F13F74B4FA5 -:108F4000E51AD148F6C74750BEA1FC6903ADBF542E -:108F5000B25755A2FF718791FC7A885BFEF07DCCF9 -:108F600037B599B763AABEACED878FD881102DFFB6 -:108F7000E7B30633E60FE6488E97615CB9EAEFC2C5 -:108F80007EF9BC54DA8799F47F65F25FFD774B94E4 -:108F9000F7280776C17EF93DA95ECC3FEC9178DFDA -:108FA000D3C1F3FECCEE899D05EFF9A03276C23A2B -:108FB000E229AD7F4BEE3A261838289E7A6C17DFEF -:108FC0003F7AAC4CA2FDA3327B0AF304F155F9D3EE -:108FD00040CF3CE0C7F6C462E4DFAA0A997983F87F -:108FE0007ABECBCABC41E3F7877178FC92D98BF982 -:108FF000124D5E670AFEAE5E181B327E0EE37EE205 -:1090000042D66C44F9AE13F0D415013CF0FC4C117F -:10901000A7DEED4E09796F256641606856DC68B2BF -:109020008FB3BFEC23B33A473E796C31BC87657090 -:10903000F9D0E4AC4CAE69223E48921C181FCF9781 -:10904000C0AB9451DF85CAD1ECC9A1FD394EBD7EBC -:10905000089577BD1ED7E47C7E876CC4387A7E91F4 -:10906000E46043E803BD3FADD703930C8E7730AE89 -:109070009E7BD549FC35480F9CACF887F4C05B203B -:109080005B93415E7FA4E9839BD84DA80FCAE42D72 -:10909000EB913FFAC1AE9987E00FCD2E68F176399A -:1090A000C827F2033BCFF725CAAE829CC606E2ED85 -:1090B00001FD007E8363087FE657B16921FB490308 -:1090C000FA22C86F3016FCF37E4319F88BA65C8435 -:1090D0006F24F3E4919EA2FC1EB43ECAB3255DA2A8 -:1090E0003C4A1DC4F114CFB35F125CA8D7A498000A -:1090F000DFEBFD092D4F3B42E409F4FC3090B79BB8 -:1091000067F4229F69FC506EE772513E4FA6FCB98E -:109110009E3FB4F75D8F2F7C12F085F477F842C83C -:10912000D38DF2C5218D1FD259FA8DF083C6071A4F -:109130005FE8EDC5415DDE65387B71F23AF6E29D90 -:109140000C23E965BD9DD0ECC28138AE7FC7C7F264 -:109150007D8A9999F36DE8578C407D80FE9EB037EB -:109160000379A30D9C0FDEE95BAA486837500FA472 -:1091700006E15DE44D35BEAB7D9A51FEB052E89FED -:109180008B1D3C9F56572A7B2DF06749FB73EB796B -:10919000DF48F9B622A54BB1C0BCB31D9203F3352D -:1091A0004E917F9B75D5E455293F3FF47E7A95E03B -:1091B0001B8C7370FC6CA7E4851074901EAABACA4D -:1091C000EDBE5E1F5589FDF22ADD7EB9294ED0F530 -:1091D0006676F3BFD2EEC7C72570B919868EDAF36B -:1091E0001A1D35FA4DC0B1283FFBBE36A911DC3F30 -:1091F00046FACDB8AAD03CA3E242FD962FCFE7FEB7 -:1092000027C574627C5DFB25937BFCF0F05FCF2F5C -:10921000BD59F3C3855FAEBD7726C8780A3A863A52 -:10922000FBA1BDE7BAF6423CAFA7D3E4B8D0784281 -:10923000A387A64707E15BE8D9E1E8753D3DABE9C7 -:10924000B37FB59ED5E6D7EC80F65EBDFE1D2E3E03 -:10925000D3F4E9531B0D9417B94DC4C1B7893CEB46 -:109260008342CE970B7DDBFF178B01FDAC6D9DDC40 -:109270001F7198ED87D06F08E4F3385D9F8C601EF6 -:10928000DC2F674AAF85F62F8B81A4B87F99CCF786 -:109290002FB7283E17E96987C21A405EFE2AF216E8 -:1092A0004FEEF52C463DFDE4E93106DA47577CBD2B -:1092B00018174FCA55683F28DAAC52BEF76287D9F3 -:1092C0008ECFF5EFFE5E9711E7F90B7360A8F67687 -:1092D0008779603F06F54299DC23635EBEDF0FBEEF -:1092E000388C9FB6D05782F1CE6DACB711E3EA420D -:1092F000A4E310F47B55675FF479FB920EEE27959B -:1093000044F0BA9FE980467CEFF43613F985D7CB59 -:10931000DB177DC9C85F1A94AF6FE37A0606119F09 -:10932000DC68DEBE107D3DE0E39FE8F40E1B267F87 -:10933000BFCDC4F773FC478C0CFD5E762E6EC8BCA7 -:10934000CBF5F2F8BB3BC39D6A24EEBB71FF7C7783 -:1093500067B253CD197E7C4E9FBF18F395DBB6CC18 -:1093600055284E14F9CF41FB223AFCED9058931545 -:10937000F369ED8E528C3F86DBE728F63B69DE1BF6 -:10938000C51B63CD9CCEA27EE9762163DBCE863BF6 -:1093900091BFB79D4D76223CBB057F6AFCBEFBCCDE -:1093A000E570DACF343955DC07F6475B1C2F13BF65 -:1093B000723E6F1931C68BFBADDB853C6C0BF71F22 -:1093C000CC8A0BDECFE0FB179DF59EAA33E9B4DF14 -:1093D0002D61BE51DB27F680BC505D4E0C237E32E2 -:1093E000B21686EF6D74B29F633B7D9A1A85F8BE04 -:1093F0001CA7ED47AA519467F8F64A816BFC60BC44 -:10940000EFA877513D496BFDC22A05607CB3DE4D64 -:109410006D5BFD726AF7D4AFA6FB6B0F453E8E768F -:10942000BFCEB9A04A09D21B9FC5F3FC526ED6E944 -:1094300012E473F60D6318EF4C7FA24F463D71FBAB -:1094400055584748DD887219F14CF9CBB4403F5567 -:109450005A12867C79FB55E8078D97E2A3391D9A4D -:1094600094A65B0A485A881FC2E29D17E3E0FA0FF0 -:10947000ED2E7F5C3CF241F5BE0B8CFA97F1FA0EB3 -:10948000E96EF9028CCBF31551DE380FF3C6B9340F -:10949000ED62C4DFC42E13ED7B6BF9DB5C31AFF3FF -:1094A000ABD03C729EC8DBBEC9FA289F9C6F81C0BE -:1094B000CA807071FA39A5F94912E6FBE24D0EAC8B -:1094C000579898E6CAC37C6B573CA3FC695757C2B0 -:1094D0004815F0E054785ED7A9E575D9DFCFEB7673 -:1094E0007F1AE9217D057E0AEAA7EEA3910E1FED02 -:1094F000FF59C8FFDB810F627D4338AF1760F3E689 -:10950000511EFD760B5F07D89FF878CAFBF9F61D50 -:1095100086E77E7B99F17DC4DE93B43F5D62C84CE3 -:10952000EC0338F74963A3B07DF1D3C86C6A8F466A -:109530009E47FC741AAC2ABEF7C37A56857567CE6F -:10954000F76DB49F31FD7D9B82EDE1FA3EAA477B2A -:10955000BFFE1CB547EAFDD41EADBF4AED3B701DF2 -:10956000F9E7103C8F6DEEE2087A6EC7A20813C2CD -:10957000DB19C9B668EFC17A335FB8AF1593F9EF5D -:10958000C57FBECE7213D83BB37BBC3481B113F11F -:109590009FCF54A07F68C6A87FFF0BDCFFDD4F2E56 -:1095A000ACB3005CF38EDA5A7BA0FFE94F2EAEB36A -:1095B000A19E3D140ECA0EF546FF41907496873663 -:1095C0003D9971053B19FAB1A2EFE99F590A245F51 -:1095D00050D297C580B5A6FCC43FD302785C6075B5 -:1095E000FF1BF64D9E976696DE847DE6C17A2EBF00 -:1095F00064A4F89E8D94E2B07E6599DD7D2C3EC812 -:109600007E3BA53FD2FE51815362D1714457DACFE0 -:1096100062F653B1C1F2B6CC5E760CE971473CDF1D -:10962000BF9A384D7206D749E8C74D3CA396229D94 -:109630000ACE9537613BBB229AFAAE85939A509E2B -:109640004B6DC33D5F42CF2F8837127F162B524898 -:109650007D887E5C1E3013FAC7FE03E1941798786C -:10966000CCDD8875A36549A9B9B2D0798CFAD11B34 -:10967000711F6D62E587A5B1283F36C981E6A180DB -:10968000F535C5C661FD231644E1BA9E2BC1FA9D8E -:1096900089AAE440B41539BB5AF1F9224784A308DA -:1096A000FDF1636A299A9CA3CA84C3F9306E46BA55 -:1096B000ECB0C044477D774CBD00FDA28C28CAE3C6 -:1096C0001629ABAF1CA67E84A341C5756CFC792D11 -:1096D000CD63267BBE6356C97F20FF14BBA228E75B -:1096E000576A3B3537B82E0CD64D7017D9656F9831 -:1096F00084FCFD83523BF4778C9218CACF515FE60D -:109700009FE97E77B81A0680EE30D94B71BE1D26D0 -:10971000C9BE96FAAE121CEF196354314F541EF7AE -:1097200045C8FC334AA5296710FEECA80978AD624C -:10973000E4A590FB3D8BAC64272ADFCF267FA8678A -:10974000510AD98BCAF7A71563DB63E07E7AE5FB84 -:10975000951574DFC0E3DFCAC5DF718A3EC5BB95CE -:109760008B5751BF4B4AFC777CDF95ECA85CCCA3B0 -:10977000CD4CFF7AAE12ECFFADCE24F9CF1579BCFB -:109780002243E6FA6900FFA307F83E4465B6145287 -:1097900037372BFF54483DA86BDA1721FDB9A59741 -:1097A00042EA43E7557E1DD25F304FAA0A1E5F7A18 -:1097B000209FEC6BBEA85FD2F24B458285DEA9CF1D -:1097C000A82A05B93C00ED03A01F8A7A45DE55E1C1 -:1097D000717506FC433D586AD3E577994AFBD91564 -:1097E000DD7CDFBA3CCE783AD83E54C84F707F411A -:1097F000B7FEDC0346B293B9D132E5AB34F82A4662 -:10980000863EAFF95F1502CE1D0677530CE5C79C67 -:10981000BDE87F68F06BEFD7E0AE90EF29A5EDBF14 -:10982000EBC0AF87170025FF4D0FC78178118780E8 -:10983000BF41FE5937AF4B835FDC50765BF3CF2BD4 -:10984000414F4507EB299B1487F576C3E9296DDE67 -:10985000E1FC306DDE6576173DEFDCFAD9D1423997 -:10986000A89F7A2A3626B8FFDA67EB43EEC79FAA8D -:109870008A0EEE6FFAAC0AEF4F57D4461BF0E34165 -:1098800026393CC89F3DAA82FBCF25C79C4DD89660 -:109890009D746399299B71C6D384EDD4F3DE1E3386 -:1098A000ACEB8E0C59C5B85DF33FF4F09A13781CFD -:1098B00072F0AA6AC5FDD31D1ED58AFEFB8E275401 -:1098C0002BFA1F3B9CAC02E331679A6135FAF3CE69 -:1098D0002C5E677855E8E16FE2F9F35A7B5A717FA5 -:1098E000837A11EBC2D127A8FDDA4F75E007D1AF1B -:1098F000CA1EEC571D54BC367CDFC127BCB6E07DC8 -:10990000C21BF5ABFE8C363A1EF96C4E887C96581D -:10991000EEAE0A96EF32FB9290FB9FC6A904FF8C35 -:10992000A48743C6DDA13E12D2077F3103FD9146D5 -:1099300013A33A598F81D7C9EAF1F8A8C0A3C36627 -:1099400047378619E354AA6BD38F739470FCE9AF41 -:10995000A727F0B86823C80CB6F72470F8F475B1DF -:10996000FA3EC47C0B713E983909F9DC61355C0123 -:109970005797391392EEA47AD93CC3A369D0AF4E5E -:10998000C8E2FDA9869D581F7B774236EFDF6AC883 -:1099900033821FF02B36FE4EAC07AF0D13759D0FB3 -:1099A00024D27E9816DF2886532F2EC638738F91C7 -:1099B00061FEFE1913D8BDDCC0BEB9D5CCE352ABF5 -:1099C00089D76D3F957AF429D41B6A987B7A02F97E -:1099D00051C52AE2EFBCDD42759D8FED2E4B44FA56 -:1099E000DF93C0F35C593BA726A17EF917BC7F56D5 -:1099F000C2C4E1DF8F75BE38CFF91D59E47F67DD42 -:109A00000CE89502F887F098AE87419840E72598D2 -:109A10003309F36C8DD1269AE79E04CE7F37DA0E98 -:109A2000AAFB8D32ACDE0EEDFD82FE0FE07B095FFE -:109A3000FE51737063CEEE1F35773CEF237D6539A1 -:109A4000D78F7EACFF3B11B4AFC246FA69FFE5E3A6 -:109A50007BB21CE89F7E12CEF1B7D03BBAB14FC5A6 -:109A6000FA0DEF4D582F9191E8AE453C2C327B6FAB -:109A700021FEB1AD8EC0F96FB41E78F07B21800459 -:109A8000FA544FE1F4D1DE0B38B5A03DF8589C03F1 -:109A9000D1E080F7FF00F9408367000E5D5DB89666 -:109AA00067AEFBA381F20C7512E83DE8EF3CC91CE0 -:109AB0001E98E7A2E6AF8BBC266E45E17BA61C5E36 -:109AC0005A628336BF6D258F737B95903CD7A4E394 -:109AD0008A7EBF83ECD654ED795D9E71AA886BA710 -:109AE000EAE2DA1713849D4966C9C1798035226E8E -:109AF000B8DC333A0AFD4CD45132E0D5A4CA6C72BA -:109B00004C40CE5B21EE674171BFC667E38FD9EF52 -:109B100047B8C71F63F7915DD7E61DC82F70BC5CBF -:109B20003ECEF132A12FE3A7D3A06FEC3632AF1AAD -:109B3000584F2107955DC6FFE078BBC98B75CB05F3 -:109B4000077E99E7834BE624035383F010A6863300 -:109B500035482F5A336242FAB2866F61CFF3C4FCA4 -:109B6000118EE49079F6C49477A37DCFB32D27FBB3 -:109B70001E357974C83CAC4709B1F3B028DABF9CF4 -:109B80000840FD0CF05A704C09B1E793E23CB86212 -:109B900036F9A4A2B3FFCD32CA41E199D0EB0786D2 -:109BA000A3CB70F863393F45FFEE1FC55FB4331494 -:109BB0007FB115A1F88B7785E22F7161289E46B899 -:109BC00043F192B27C5CC8FD9B56E786F46F7EBC85 -:109BD00030647C2A18A4E07EDAD33343C6DFD23C5B -:109BE00037A43F76C3A290F199DEA521F7B35E5D5D -:109BF0007143F41EDFB226649C9EDEB7B6FDAF90C3 -:109C000079357A7BE0DFBF82DEE6C4507AA70AFDB1 -:109C10001AEDE4F565FD46DBD312E8234C13A15E93 -:109C20008B6E7FF76BCC43788A55AA9FF3CC64B4D4 -:109C30000FFD82EC92500FA5C0148634AA5FA7FADC -:109C4000BB1F1B0C21FBE28989DCBE2726F27CCDE1 -:109C5000CF4DFCDC520AF88F64870C2C102F031EAA -:109C600022315EA678FAC7CF60BCDC14DD97A14232 -:109C70007C6CC6FE4D017DB9C8AC36F6013E26C8E7 -:109C80005C1F829E4C4B84F93F919E30723FC263B1 -:109C9000443F22C5C23C91B9643F287F1CCDE224D9 -:109CA000ACC78F0AE869F51A106BDF8A2C3A07F502 -:109CB0001E4282FEAF2586ECE8DD9A7E5A9E49FA66 -:109CC000E9B22DD40FBBFC401A5D3F71AF99F6FB92 -:109CD0004F883A446DFDE784DEFA53BD85DAF3F52B -:109CE000F6103DB67CE3FA08F41F4F64707F51BB59 -:109CF0005E82789B88AD2CEC9AC58EF9AC7BC0381F -:109D00004701BE5775F7452E62E43716E3BA6B3745 -:109D10005EB9F74DE8D719FC09DC3E7878BDCCC7B1 -:109D20008CFCCFEA6F5888FF343791C7E973C5FCC4 -:109D30000BA0B1039E1600FEA3B17D775A39F2271E -:109D40005CA7F369B3BB19D59FCC71A7D23EE35191 -:109D5000E6F8701780F89D4495E09CC75CB45FFFFF -:109D6000D1BDAB2270DCC07CDA3CC028E86F7C1C23 -:109D7000ED312660DC7F1BAF6F80F759F0BAEB9EA8 -:109D80009427D10E69EFFB88B92F7C88FBDDCC418D -:109D9000F36AF3331613A29F762C5FF9692CBC6F1C -:109DA000CD0103E513D6749829EEEA5FF1D7AD2F04 -:109DB000C2FDFB52FA6E42BBFCC98A6FC6203FDC73 -:109DC000BD01F410ACB130CAFD7062509C72E281EA -:109DD0002B11781FECEBA617D1386E36537DEF2789 -:109DE0002B368F09F6471F4D2CAAC5E7D8E41B3B3D -:109DF0006F58F27A6622D563097E7A58F0D39AD7E3 -:109E0000C6921FB52662809F787F13AFEFD0D6F140 -:109E1000A1E0C715AF7F5D107CCE7407F0913A8644 -:109E2000EF6BA920533B7B2EE7E0FD57147713C25D -:109E3000D779F57424F677BEF737829FCDBB31789A -:109E400051063D0581FD65EDDCE5C2F6D83CA43B3D -:109E5000C85933CEBFE837AF5DF81DE2A763F3A65C -:109E6000EFE3981B3C7FC9847D71083C807DA1F89D -:109E7000A09F85F3731D428F2AB8839E86E7991CA5 -:109E80002AF1B3931DC27D97C62E03C3BA9548DC51 -:109E9000B409CAB345CA06CD08392D49A09F855ECD -:109EA0007925F1E49D4DE4E787FA3DF96FAF08F1BC -:109EB000775CF08FFC9D97DC8D9807BAAEDFE333BB -:109EC0002C3145DDB8FF0381B0532A105B38F06BAD -:109ED0004B14FB22420F77A21C61FD3FCE85F97A1D -:109EE0005F383F670CA602F5F80F604DF8B02945C2 -:109EF000B4D2C50C0BE8C5BD897F78E669D09396CE -:109F000074BE5EEC37E2DFDD9CDF06FCABB7C791C9 -:109F10009E62DFC2DB100F225FA1A7533EC8078BF2 -:109F20000D9233F1BC6FFFDF22314FBB35467D1FF1 -:109F3000E9E03F20D33E4D98D2678A1E222E7B1344 -:109F4000F59E89FB4D546FDEC6F38116D5C9300EE0 -:109F500008B3DB27049FB36B17FA6ED5FE4F469903 -:109F6000800E170C3D91D9307FCDAE1D91E8C6DF34 -:109F70006B747F8A7CB7F2C40705763ACFB671144A -:109F80009D03F08DA6BA83F10AF328B983E1A8DB1B -:109F9000904BC6B8760325E3D9F8F6BC87501FD599 -:109FA000F9F83A716E2CFCCB6C63D4BFD8D6188309 -:109FB000F3D5FDB62319E567733C8F135FBF3A8E67 -:109FC0003FAF3005C77F99182DF8D96BC03863B300 -:109FD000884F2E5E35D038EDFDE3DB8A643BF043DD -:109FE000B6AF792FC543ED6615E91AF60AE378682E -:109FF0000F2339AFEB9CC1309FDF1FCD1C12DCDF7C -:10A000001AEEFF039D33EB30AB981F0DB337B31837 -:10A01000987FABD80FCD048EC2F34ADA75ED7D611F -:10A02000ED3FC55802F981F2B4614A33BBCD168CBD -:10A03000E708C2733CF2533CBEC767C0FC88FF16FA -:10A04000C65E26B80270327AAF066726F9735B4D9A -:10A05000FEB3787E05E0B223FD33198793B58F55A3 -:10A0600031BE0FB33B691D6176D5E19106C35597AB -:10A07000C3BC68BF7FBC960DC82BCA6F5D78A06F4C -:10A080000119D83A9A09F9B63F5B3A2DB80F8A649C -:10A0900072E0F9711B629E6D1A49718347C63816CA -:10A0A000DA88185CA7CACF3B636A2897E301F7C533 -:10A0B000AD167E7F603CF0B70DFB363ECE1165B726 -:10A0C000CE94484E28AF572BE4FD31C977F67690F1 -:10A0D000D3BFF8F6E6A8004BCDBB7B884F571ADA02 -:10A0E0005F1C0FF7375ADCF94980CFB74E1AE81CCE -:10A0F000E99F5E0BF35662FCB87B63827308F9D06C -:10A10000CFFFC3E36B9F4F41FAEF9654CC9BF61BF6 -:10A11000FDA310DEDAF6CF4D548FD0768AEA938E07 -:10A1200024B99DF89EC96D0DB46F3C8535D3BE71C1 -:10A1300096387FDD92C4F5C7E563635E6E08C2FFA3 -:10A140008349DC0F637EF7CD2837ED423E3BD12FAC -:10A15000817697F08F7675DD9DA606E5FD1AD8DE2F -:10A1600014C4F75AF636B5DAF57E2F3FCF98F5913D -:10A17000E53E6710FFB993B89FE716EFF327B917CD -:10A1800024A1DC769D3645AA785EA56514DA911681 -:10A19000F09FEC43E065406E757254A7F84D38BEF1 -:10A1A000EE1C3F770A746EC2FAFFCD1FB58D5B02BD -:10A1B000D77701AEB1DED373C24C758FBB8CAE14B2 -:10A1C0001CDFF0E15739A8B72A1069F0BFAF3A5643 -:10A1D000DE8C7803BE2F0E47F9DACE488F69F299EC -:10A1E0008DF209CF6723DFE7633F93F4F056532FD7 -:10A1F0003FF7B98B9FFB04BE273900BEB7A39F90E2 -:10A200006D0739A0E7C7927C6FED35D0F9540FE8A0 -:10A21000F15BA85F5C85FDADBDA576926FCCC3E711 -:10A22000A29CFAF6D23C2D108320E924E60AF61F00 -:10A23000DB1323898F35FD783091EBFF960C350ABF -:10A24000EBFFADB21C2217417690F7859DECDD50F7 -:10A25000FCEC0BD3D0DE09BB20FC27769CEBF94746 -:10A2600085AD5AF34EE1EC2DB0CE3587E5817A6E9F -:10A27000F4577D824FF60AFF15ED849AC7EB67F01D -:10A28000FAC40DBCCEB5C0B9BA04CB38265734EFEA -:10A29000C3B6D0D55282678EA72DECDDC7CF1EF393 -:10A2A000F3E3AD7BEFC8C27DEAFE136686FB24AD07 -:10A2B0007FF3FFE175C0C3773B01FF43D825580EFC -:10A2C000F11F58EA149634F87EBFA4E98FF9952857 -:10A2D0006F175BE5401FEC612D3038F67F9D54F51C -:10A2E000AC07004B1BE17C1D59A230D94D6DFF918D -:10A2F000BF25A02DD8758CFB4DAD266716F24FEB10 -:10A30000E8D0F3FA5AFB62123FE79C6F6643E625FA -:10A310000F09BB37C6C39E413EAA6D95ED5EA0FBFB -:10A320008556D96902FFE6ACD39D806765CE31CFF3 -:10A3300082A968E745DCA87D4F6519FA2760A71E4A -:10A340007C61501EDF807CF450BBC47E066B5EFED9 -:10A35000D2D0FB0A35629E87DB36EE4F013AAE78EB -:10A3600025745C8DA813ABD1F92F8792447C98C6D5 -:10A37000D2D02F01FE21BD605458B719F8F5C16441 -:10A380007707C61B9BC5770C407F921C7608BEDC06 -:10A390002AEA04FC5B25DAD7CB7CD52B1BE0F942FB -:10A3A000C52BA39D62D0E23EC164A7BB1CF10BEBA1 -:10A3B0003E86FB35CB851E5CAEF9655EBE9F01E631 -:10A3C00096FCB229CCDB1889EB7E5572F854FC8ED2 -:10A3D000C8A03A5C5A779D5877CD8623FB318C5BB9 -:10A3E000D5123AAE4EACBB4EB76E6D5FFBCF49BADD -:10A3F00073C837B86FF16723F7133E10F368F7CDD2 -:10A4000023B83EAC05F0906E355ED9EBE57E9D0D30 -:10A41000BFC373BF80F77E41EF3AE633A5C0B8559E -:10A420002FF075B26743EB3F1F6C7DC484F1959E9E -:10A430002F966F31923F0A8833A1BFA8E78B156230 -:10A44000DD2B74EBAE754B3AB8B89F3C18AE960551 -:10A4500048D7555B8C0CEB11F5702D6B59528E7CE7 -:10A4600036985F395D5688F90270AEA6737C370A5C -:10A47000E7A811822FC7B17144978AD81BA28BDE3F -:10A480008FDDBE7F9C15E5FB72F7688ADF35BAEB7E -:10A490009F2F177EF08C0D8CDA0B6D25D6F118A747 -:10A4A000F4181C924AF156E478C0475E87CC2AA182 -:10A4B000DFDF9EB6DE0378CF3D9C5F85F17CDE61F9 -:10A4C000039D77DBD99D4FFBC07907D263D3281F4B -:10A4D000EDA0EFCDC03C643FFB7B72D7E3B980FEBB -:10A4E0009ED27C9C57827168E773851D68E8C9B568 -:10A4F000069FEF2E18C1E3F5A7923EFB31FAE13338 -:10A50000B61BE97CC30CA3FF3DAC9FDAD9ADD0BE2E -:10A5100075CDE1A56BC390AEAF49B46FBDBF774DAC -:10A52000DC62E4AB76A31DF7A1FBDBFF6D2FDEF74A -:10A530006C91E87B12751D65595BA19FBB31CF11F2 -:10A540007CDE2B375A25F8D8082BC5C3336E3292E0 -:10A550005D3C9F6CFD25FA372B9C1B498ECFEFD9B4 -:10A5600069A2FAB9AD1243D3BF3F69DF1B888FF3ED -:10A570006F1E31A1935DD27AC4D4F777ECFD052F1D -:10A5800004FE1407379B304E59B551EBF799904EA6 -:10A590002EE1FFD4BE728AFA2BDA24D2332B5E92DC -:10A5A000E93CFBBE8EB74CC8C7B55B2496981A74BD -:10A5B0007F8314F21D84A58CF3C152A1675632EF3C -:10A5C00053C9306E6533AF23604F87D6E5AEDC32BA -:10A5D00087BEDBB4AC79687DF3B0E0EB87301EBC9E -:10A5E00015BF83143AEE61EDBB5C3A7E7E5CE3E717 -:10A5F0004C9689FCFC55911A950DD7BF3AB2E2E60C -:10A60000A1CEB1F7083BACD9C1CB3E03D911FDB8FF -:10A610008B6D5708DEBA9ECB26B483E5ED9708EF25 -:10A6200095ED5D54C7711773D7209EEE6AB7DA5166 -:10A630008E2BFBB85E9AD96EF67A25BCDFD284F4F5 -:10A64000ECEFE4758B9E3D12F92F9ABE7A48E0EF4D -:10A650002181BF874041A7E4A21FCBE3DE873336C9 -:10A66000EE8F81FBB5E27ACD817D91E8EFCD6497E5 -:10A67000EE457AC07B18BE87BD148AE73B1987E395 -:10A68000CE2DBCDE596FAFFA4764CDA6FC23C49D26 -:10A69000084FCD96503CD7EAE2ED7523B87DDEA495 -:10A6A000C373A59F59B3110E5576786974AF82EFC5 -:10A6B000EDCE9128BFDAADA6450DB5FFA8B5EF09DF -:10A6C000BF59EBCF16E7AB5BECCDB6E038D894CCF6 -:10A6D000EDFF8A29B207E934103FA4EFCB510D8179 -:10A6E000F801E286DF8C88E771041674BC3B526681 -:10A6F000717181F8E18749EB2B73A15FB785CBF9C5 -:10A70000C5C9301F7EDF4B61E45FD66D31D339C0E0 -:10A710003AA03BC509EDFC1C83AB5D2A437A83FF5D -:10A72000FDEE888978AE8619E360DD73DA389FCF55 -:10A7300029BD447C72209DAFF7B2A2260EE58F6B37 -:10A740007E389EC35283CF3F805CE2F8DA765E0F9C -:10A75000D4BAF7EB51A9A8D73AFE3A6A09B45746DA -:10A76000F0F56B7E9E1FFCBCD1DCCF3986FEE78303 -:10A770009ADCD8F93EDA83C2CE30A989F8BBD6D8A4 -:10A78000F2760CFA4D5BF9BE3DDB6DC46F9CB18671 -:10A790000F5E6F8A81755F7C5DA27A347CFE09E072 -:10A7A000B38B4B5B4EA31FFDD5560BF98F0F828FDA -:10A7B000383D77B03C6A72AB7D77AA81AD257F7258 -:10A7C0002D6BA27695E0E38B6D8D26CA9B79839ED7 -:10A7D0001F3DD8EF58A5E33B537228BF357C104E80 -:10A7E000FE5FFF01D98EFB2780A7FF4E0EC687F0C4 -:10A7F0002F5AF786113DFB8FD8C85EFC49F0D979F6 -:10A8000091376E982CD3FA0D53789BD5F9D668A45E -:10A810001FE21BEBDE3777BE358E9FA7F612DE57A1 -:10A82000BE8A49F120385BAC94DBD3FA0D1F2CA211 -:10A83000EFF0D4ED19806B8C292E00D770FC2F49D6 -:10A840003C1E3448A1F160DD6ED9155CEF05EBB913 -:10A850000FF54F929003A6F813D02F1999AC92FDE3 -:10A860006A68E7F43474F016DEBF80E73B8CF4FED0 -:10A8700041F78B3D3578FFAB542BDF4FBEEAA9C4BF -:10A88000FE7747CB544FF9DD0F568C0DD69B0CE16C -:10A89000047AD619FD0914371E31107C75472E270E -:10A8A000A4DB501F6D2CB567A3DEE1FA6EFF68EBE9 -:10A8B00072E4630FBE373130CF6BC2DE325C6F1291 -:10A8C0007A152FF079C57AD7B2B9223EE67C942D5D -:10A8D000FC3D882B26264F1C1C57DCA83F09F6E0C0 -:10A8E000E86209EB89140FC6B53B8F737DD0D0F1B8 -:10A8F000D0A7C8E7759F98A9BEEABB9D0F8DA53A62 -:10A900005BB7FB56F42BBEEA7CF856CAF3496B09D9 -:10A910002E0FC29784FECB8709580FBAAAE3C3044F -:10A92000B2AFBB26AEF744A09F927B275E07BF81E4 -:10A93000F80FFC17E2BF9D3DF99ABF62C579571D1C -:10A94000505C889F5507F20F55A21F71B8381FD56C -:10A95000B874389FFC953CF4576C01FF455B4F651C -:10A9600032AF77E9EF0AA33C81C44673FE61E92167 -:10A97000FC53D3FA0ED9F59A3639A46E507BCE9D8E -:10A98000ACF07D7E8D7F5A2427F1C776DED6B4EDFC -:10A99000A4F5AD34B610BD1BB618F9FDADBCD5EAB3 -:10A9A000AA3D2CC683F8388497800E334D5EFA6E2C -:10A9B000C5C154EEBFEBE9F15932CF631C3CE1BE97 -:10A9C00019F9E560917BAC7D08FBE061C53C3E95E3 -:10A9D00004BE5BF97925FDB853C93C8E8F8C0D3DC3 -:10A9E0003F3A605F9239FFCC340DFD3DBD9F69F267 -:10A9F000C4D83306E08BA39546FB3AE1B78F08FA3B -:10AA00005E42D55D46F20F8E32FB3B5867384BD322 -:10AA1000AF93B95DD5F2DDAE0D2ADFD7197CAE91CB -:10AA2000F4E47C6D3EFD7969E1D7CCD7F935EB359F -:10AA3000FD37868D41FDD722CEB9ADC90CF306E7AF -:10AA4000A3F4ED7EB18F81E775B06DC8FC98F23646 -:10AA500007BB4EBC41756627C2D8689E97A3FCF51C -:10AA6000AA61F2D70D03F2382F84BF347A5C10DF6D -:10AA700055D1D3E30D81776D9F2D5CECB39D56DCF2 -:10AA80006F24535DD67913FF8E9A9FE2AB864CEE0E -:10AA90001F5D2893685F1CE01C650ED2EB1746F023 -:10AAA000B8EABB0B24CA9B76E1788C9F5A24AAABE8 -:10AAB0005EE5EB35211F8D695DF224C9AB871D630F -:10AAC00041DFA9986DE17671806EDABA07EC568C99 -:10AAD00087EBE1386A713CDAC159C2EEE9CF218DCA -:10AAE00065BDE51857563B2507EEDBEBE93D77E101 -:10AAF0008477E2FF013A9F4B761F21FDD67B7901D7 -:10AB0000E63F0F667E3E0AED65ED307CFB3BC1B74C -:10AB1000DAF7591C63D546FC3EC98F12DD9F207EB3 -:10AB2000FB0DDF468E63F87CDF7FAF91902E8CE8C3 -:10AB3000319C9C9C12F39D4A16DF258CE3FB24CBB1 -:10AB4000B18FF26AF48EA4FC42F68DED4B35EC7EAB -:10AB50003707F5D6C5AE0339A6203A9E5F03F28EBD -:10AB6000F6A3635F826A0BE63303F1972469FCA6C0 -:10AB700008BB18CA77E791EFB2B1FD30321DF5EE90 -:10AB8000F6A391B7E07CBB783BC09FED328D837814 -:10AB900067CCFC8860F89E24F82EB4F07918EB1B83 -:10ABA00053353EF87EE3707C6B4CE1F584217CAB41 -:10ABB000ADB705BF8783FE7DA799BE8783F9E6E819 -:10ABC00020B9484DE1F230497CFF660AF3D0F70026 -:10ABD0002789EFE04C51984F89C17D2E9FCCF765B6 -:10ABE000F9798602C1BF93145F17D6394C11FB3235 -:10ABF00085AC97C64D677E6A9DCC4EE7148A9983D3 -:10AC0000DAC916DF9D9876C96E69A1FA3F5F821294 -:10AC10007DD622CE430C41B7C0FA15FAEE0DF1A550 -:10AC20008CE76186FE6E4A650A9773FA3807D2F799 -:10AC300002A3FC147EDF0C5F325561155877749BBC -:10AC4000C22CE100EFF6B70D24BF9D7DAA17EB40A3 -:10AC50001DB1E2B92F18D5BB4E7272F944D382757B -:10AC600012DA7AF5782884F9303F364981C892F0B3 -:10AC7000E8A3F7DDCEF8398D22A6D207566EC78F2E -:10AC800027935EF7539C54027112EA7583C543F80B -:10AC900028C3E4CA44BEBF1109F314364BEC38EEA6 -:10ACA00057A4F1F56AF3170223E0B9BD32B15E4C47 -:10ACB000811E8FE1FB1E9154385C6AE7DF094AA0D0 -:10ACC000EF04DD285EFB13F8772123EFF75FFC7EAE -:10ACD0007E60FFC781DF0D8A0C7C8FD281E74C300C -:10ACE0007FE753CE07FBCD77A72CAD4E9918A897D9 -:10ACF000636EA6A25FA1AF9743F49D0B3ADFACD57C -:10AD00007BBCEA9DABE2B9B98571163A4F9B6B19D2 -:10AD10009587762B23D15D9D42751F5B6EA14914EB -:10AD2000EF44574480CFADCC3919F11CA8D7E3DFED -:10AD30004F1A38CF94C0E8FC9FD5CCEB199F01B9CE -:10AD4000C0EF178154A958D7C29E28A1FAC7A7A25D -:10AD50002D0E3C87604678AD01781B2DA2EE47573B -:10AD600077D96833D0F7381B59389DE79E15E6FE32 -:10AD70001EAEFFB188623A2F9DB56D5A12F983B0AD -:10AD8000DE69DA7A0D83EB10B1FE0F9FD3D7FF692E -:10AD9000EBC2E3EBF85EBBC097B64EBB76DEC7A94D -:10ADA000849CF7D1D6FF4C385FA71177E2D3E859DE -:10ADB00015F5837E7D1A3FFC3FDDFB356D605C0041 -:10ADC00000000000000000001F8B080000000000D1 -:10ADD000000B7B2ACBC0F0A31E818565181826F1D5 -:10ADE000A18AD112CFE066607804C42C3C0C0C859B -:10ADF000407B23807424101F01E2A340ACC2CBC06F -:10AE0000100BC471403C07C89F0BC4A5409C05753E -:10AE1000632B0B03433B107702713710EB30333059 -:10AE2000E832136F7FBE0803C31309045F51126831 -:10AE3000A734FDFC3FD8F00A7DFADA276DC0C0B018 -:10AE4000D502C15703B2B759A0AAD96E81DF8C1DB4 -:10AE500068F23BD1F8BBF0E83FAB87CAB7D540E515 -:10AE60004B693130782285899D067EB7A0E30AA020 -:10AE7000DE4A200600FB72DB43680300000000008E -:10AE800000000000000000001F8B08000000000010 -:10AE9000000BE57D0B7854D5B5F03E731EF3C8CC9E -:10AEA0006412420818C2092FA30D382121058AED2A -:10AEB000400091A206B50A1575C22309794DC0C795 -:10AEC0008FB56D0682111034582C51A39D2028781F -:10AED000830E3448908003581A7A5183D7FA687BDE -:10AEE000BD4129200412F185DEB6FE7BADBD4FE6E3 -:10AEF0009C9319E0DEDBFFBFFDEF1FBFF6B0CFD99B -:10AF00008FB5D76BAFB5F6DA7B648B8B484308F906 -:10AF100016FE7E40C8748910D23FFA74BE4E549219 -:10AF200048485D0E2DA710923E9C848840C8E46A74 -:10AF30005ACE23E4D13B49C89A49C8FE2316FCBE29 -:10AF4000CACFCAB45DD8720DFD3E82BD7F328BB6CA -:10AF5000A3EF9FBC2062BBE04C12DA4CCB4984F6D5 -:10AF6000368CD021FCF89CECADB78FA2F51BEFB46A -:10AF700010AB4AC8137418329E1017F1D9096DBA74 -:10AF80006A38EBEFF19996E745013E46D2E6D3F2F7 -:10AF9000EA29C5F9AB69698DCCE06A9853FC7C90CD -:10AFA000F6EFB10CC379D07A4F3A69BDC7DE2F21D5 -:10AFB000AB69BB0D732D427136ADD7A4CC0E65477E -:10AFC000E7AF3DE71289B70B5A2DE3E0E9E3CF88FD -:10AFD00002CF5F4CB4E0386BAB193E683DC592467A -:10AFE000484BC7019B9FF6B7B6A2E5E834FAFD913E -:10AFF000E1162FC52079A4E380FD4A3A7E30CFE2E6 -:10B000001D416BA74B11C1E38C8E379E50C0C7D238 -:10B010007ADE1D36D5D9B73EED7712CC7B0DC5BB98 -:10B0200098196D3706E0A4EDD6529285E9B8BF9421 -:10B03000BD8761DC5FDE902C0449B4DEF50024D4CA -:10B040009B6B21115A8F483D3642C7593DF16DDB4C -:10B05000085A7F75A1052641D67AB5EF5E3B81FE81 -:10B06000A68E3C3C1CE87A3DFD0EF3C87E7C36CCB7 -:10B07000FBB1290A01FCFF52A0F5288A1B8A941F04 -:10B08000027CAE6AE281F7F4E98B85D756C18670FF -:10B0900090351B08C9270002FEADF685560E05FE49 -:10B0A000CA235E28A77B697B67DFF69D8215E9D2FC -:10B0B00020070702FEE2D16F38C7E7EAAC2576A089 -:10B0C0000721F56985A308590F78824125BF3ACB3E -:10B0D00015ADBF5260F85927139F40E79790A7849A -:10B0E00096513C5BB23D7360BE4EBF42AEA3E55588 -:10B0F0004270A0087419A590CD2AF2857D042DAF69 -:10B10000BD2AD90BFC572784D324F87E03FD4EBB00 -:10B110003C5038660EF067A357417EA6FC7318F0CA -:10B12000BDD69F4C56ABF8BD03DB3B877BAC880993 -:10B130000A0FC54B3FCA4B80D79C9BEAAE1F06F453 -:10B14000196BF10085560B93D4F9203F49360F8CCB -:10B150002F8FBD19E927F74F16888EDE3F077A53E8 -:10B160003C3DAA16FE1C9E4FE77D943482D65F9329 -:10B17000F34A03D0E999FB6D48BF67C6762C06B940 -:10B180007AF242EEFB7E944BC5BB99F6F36CCE8906 -:10B190004C42077C7CFA474980BFC1C3EBEF216E6C -:10B1A000FA9CD953434653F8487DE1824CE413E1BD -:10B1B000168AD7C14B15A2DA182DBF25F09DF8C20B -:10B1C000D9ACECA4F319CCE9DCD2F1B6AD08FA9B0A -:10B1D0004B2223DDF8DE969A1CD53383F348249561 -:10B1E000F6FFE4C24328E7CF5C9DEA65729E86FCC9 -:10B1F00092C1FB4987FA54BFA4D94830813E07B7B2 -:10B20000F7DC0C700DCE3A3117E0DCFFC62101E807 -:10B21000F6ECE85415F45192BF837452BA0FCE7E07 -:10B22000F741A8E77286D20AB3B1FE5FB19D09FE6D -:10B2300066D5B709F0B64DA83E0CF409E658BC8CAB -:10B24000DE4C0FAEB93735047A64B0E34FB3C4A116 -:10B25000C80784A452F83C04E5A44E88D88641BBB4 -:10B260000758BB212424009E076705178B6EA8EFA3 -:10B27000170A5D7DC76D018D08F241391DF875BB58 -:10B2800042CA0A63C8C16B5C9EEB04321BF9994841 -:10B290007F03BE1992C4F8462B3F0BF0D071B7BFA5 -:10B2A0009EFCC36C0ACFAF960ECD11293C8F42BBDA -:10B2B0001872B396CB81A39D04058AD7FDBFFB9D71 -:10B2C0001DF0B6DD424AA1FEA4ACB0AD93D315E8A3 -:10B2D000B190B0FE1BB337DA505F0859C8770BC77F -:10B2E000293EFB6890BFE5829FB64FF330BDECF27C -:10B2F0002A21D0CBAEB4A060A1F0A8D9C4B33193B9 -:10B300007517A4F89B07FF00469758FD356B9342CD -:10B31000ABE9F779D954D0006F1457163AEE02C250 -:10B32000E639CF5BB718E84748A105F0B9DAC3E8BA -:10B33000D308E3D0A934A6B37ED6DE4742CB818FB3 -:10B340003CACFD706842E9363CEF95FF25D07ED3DA -:10B35000793B907B68979016B259683BB5DA4210FA -:10B360003E29725800BA8F4A55019EC634EFBFCCB1 -:10B3700004F8674BDE8DF4F3708083F6D3586DF1DB -:10B38000A1BEC8539A404FAFF6313DAFE12B938F2A -:10B390009BEE8D0874EE2493EA49C4932F62F74024 -:10B3A000399BC19399C7E6D50BFF2825B49C364E2F -:10B3B000B74508D4D3F050CCFB2BE6F370A68556E6 -:10B3C0004A00771E839BAECB084F7AB6D2047290A8 -:10B3D0009EC6FA53297E34BC035C0E0DAE3C5A1F48 -:10B3E000F4B0576902567070F88AB3193CFB8FBCF1 -:10B3F000DD2EB0FE50AE1C1C5E079F3F017853B996 -:10B400005EA7FD35CB1141A4F5436389BA918DA6A2 -:10B410004AF9D1EF8F57533CD082938F43D65B517B -:10B420001EE8ABE0B7940FE6D7D37256543E46AC55 -:10B43000B41AE4C5C9E74DEA991C51B68940BB4C22 -:10B44000C2CA1628D379146719E58C7875650A87FE -:10B450000BF89DEA9F65E315C63F57313B86105DAB -:10B460003DE0F3B1EA736BF0BB82EB7AC64F150394 -:10B470007C83AB53278BA04FDA9FBAD9027C752F00 -:10B48000B18889C8CF42AFFEA2E3ED5812B1C32400 -:10B490001DED85C980B78CEAE4C90AE0B1DD8F658E -:10B4A000477BB50F9FB0348D216410D18D9309FA7D -:10B4B000D553DE4CF14AAA9530E8EBB17A38E9F77A -:10B4C0008CD7EB6701BD1E5E7C6820C86FAAA9FD02 -:10B4D00068CB5094D3C1AFD35A38FE899F41FD55F4 -:10B4E0005C9F3800E231F87C1D9E839D54CF523D15 -:10B4F0009D4111AC8C89EA8BD557BD9BE37772FED9 -:10B5000049C667049E66BDA2AB7F15AF1F142E5AB5 -:10B51000EF04D6D3E0317F3F2758504FB9C0CEA4B7 -:10B52000F87D8C78E6E0BAECB5E0BA98C0DF87BD6C -:10B530000726233DC3C42B6482BEFD9B55CF073F26 -:10B540008197A06FA530CA8992E140FB90CA710231 -:10B55000AC7B8D527529BC0FA73B08E88503530FC0 -:10B560000980CFF456FF109043CDCE9DEC0DA7C1BE -:10B57000FB470EFBAF44F98C63376A76A2793E57DE -:10B580005CBB1CF5C1107F4F3BACF7CE0AC97B1DDD -:10B59000F0979FC2E5443DA992EF52F8BDC165A066 -:10B5A00067553F2D0FA0CF0AFE2C65DF57D594E6D7 -:10B5B0001E97A2FDAE1A4EED51AA17D777ACB7DD94 -:10B5C000007646B54505BE5DEB7DDBE673427972DC -:10B5D0003FC0734BA166F74504182FFD1D1FDA7994 -:10B5E000633D8A0794D6286B64A047B75E344E7DCE -:10B5F000770CC0416EA5441C189F8E74BEC867F1BD -:10B60000D61380C5A25B47F667EDC0F5E50D721550 -:10B61000D2455B57B475047BA4FA653E97A347D423 -:10B62000B04D407D456597D2673ED7234EAE37A9D2 -:10B630001E667A8EAF276B17A7E27AA2E94FB0ADEC -:10B640004149CCE7FA766DCEF3493750989CA06714 -:10B65000412FA591C9B0FE8E003D03FA490A0A3078 -:10B660005EE3580F598DEB98519F8EA8667AF09142 -:10B670003482FC44D7A12658EF1AD3C369D04F6354 -:10B68000F501C1AF5B3FB5F5CE55DD41400FCECBE7 -:10B6900063EBDCBC6C36DE1F00416319BCA057CDE8 -:10B6A000EBDE2F26EE406599C0ED2D33FE050BB382 -:10B6B000031F9BF936E271ED82C7F149EA37607FDB -:10B6C00069364683555907F0FD1ABF653AD8DDEB58 -:10B6D000A58E95C329FCEBA7CF5382F4FB1A2FF359 -:10B6E000BB564F9CF73CAC6B568BC2E0AA2E457BF9 -:10B6F0003581C3B501FA463F5141BFE8BE3B37AE85 -:10B700001C4AFB49A37E8CA042A590CD4ABF3B8139 -:10B71000A6A0BFFD1106BF974C2631E0FF57C1C15F -:10B72000FC507F47FB08A4A7C503F026787B6CE09C -:10B7300027AAD40F53558057B58F42782D9E656A3E -:10B74000B4FDEFB9BF70172CFC60DFCF79773AC832 -:10B75000D7BA3B995F6686FFBE49A1760B8E43D070 -:10B76000AD73C5C1EB5CD060A07FBC2184CB95C517 -:10B77000E03A2E307A3DD631F97AF4930AE97BDA51 -:10B78000D1E31D43ED20DF667BEF99840F73D0DE9C -:10B7900031AD33972A0F36E9FB51D6F00CE4B76D83 -:10B7A00016D45384303D27108BFAED305844185C82 -:10B7B000C87A547FAF90237316D0FA2B763A09E0FB -:10B7C0004BE38774DEE7EA6ACA0731E6DD2E88F1CB -:10B7D000E8CEEC0C4EF70E18AFFFA5E94FA5D90E39 -:10B7E000765B385437A80CFC8F6AE6EF8623075047 -:10B7F000FFA44FB90DFD942D4DA97316005F65F997 -:10B80000BC800E0D1EB04F62F989332CB68BFAEF57 -:10B81000F1F47043C50AF47B1B3A62CF7FA285F92D -:10B82000DB61AA27BDD9F1C7CFB7303B3AC9C2F90E -:10B830006EEAA134FD7AA6ADABDA3A3B582241510B -:10B84000B71EDECAF1675E3789546F1BC9F81CFD4D -:10B85000C786052C0EB161A205E32B1A9FD37A6926 -:10B8600080573A0FB4E7281F86C09E7B8CD4A3DC98 -:10B870000469FBCDA42FDC7712CB65CD6F029F5FEF -:10B88000EF78DCBFBE8BEBAB7539F7DBA12B3A5EF3 -:10B890001AF047C0CDF464A58BD9B1053BE5C80FBC -:10B8A000281C954D02DA59967D7684F3DC265AA63B -:10B8B0005D475C0AD63FEBB1613960ED78F47BB44B -:10B8C000DCB35324684766392CC0AF2738BF923C9D -:10B8D0005A067BD8CE8A954DFBEF82FE4A5BADC4FB -:10B8E0004EFBAFDC5D72E3F768B9A45D2650A5722C -:10B8F000F33265102D2F0A096128774FA60B15E04A -:10B9000025590981DFDEEDEE48FD119DF7E91A1B8F -:10B91000512928B5AE8ED45B293ECA42DBA741BB74 -:10B92000B2660134229DC7E64303615E5B052FF8D2 -:10B93000F7E55B120CF6E0093A951FD0EF4BE83CB7 -:10B94000412E4B48FD3458E72A37AF53545DFCE194 -:10B95000748D07C7D1CA955BE938B45DD54B8217A2 -:10B96000A65865217ED043E776DB673FE784F92D53 -:10B970005346BA605E0F2B50AF2454F48A5D05F82D -:10B980009A9469F47B59639302F1AD8095DC0D7E46 -:10B990006EF9967E46B81A4494D72549B68DA0CF45 -:10B9A00089D39776F3A8BE743E5D4375ECC868B939 -:10B9B0000CF421F2614899A5AB3F444C427E2DDF47 -:10B9C000221AED6CBEFE078F32FA07F7BA30EEA7E7 -:10B9D000D16F09F79735FA2D49E2F4947AF263C1F1 -:10B9E000F328D083C2530FF8A2CF351C3EF7443260 -:10B9F00009E22E6E1FF10831F8DAFCAC974911B05C -:10BA0000EE3F2D9F35491A88EEC362883C7956CCAB -:10BA1000993485967F6F29DC6C41FDE155418E3468 -:10BA20003FFB590B93CBBA810AE2AF7E6AFE732CBF -:10BA30003E4170DDAB9F5AFC3CD805B4FD360BCAC5 -:10BA4000216D3F2A7E7BCFB47186F69E69A55AFB95 -:10BA50009DD8DE76F1F6F5D32618C79F56A6B5DF3A -:10BA60008BF03B2F0EBFE7BA89C6F1AFABC0F60132 -:10BA70002BA3574F920DED9A1576AF4F6276540473 -:10BA8000DE4BC92337423D51E307D2E103FBDBD94B -:10BA90009C346635D1F3C5E437000E1795163D5F2B -:10BAA000248E7318F831C9976C28D39E3C27BEC3E7 -:10BAB000CB3088DB86F0288314D4179306D910DEA8 -:10BAC000FBF7D9B17CFF0406EFFD839C2867B8B66D -:10BAD000503ADEAFF8AFD1DBADB0324128E94DD1FD -:10BAE000FF11E037FA5EB5C07B8748AA513F5B097A -:10BAF000EAA38733F39F0BEAF0B37230A52F2D9F93 -:10BB000005FBA77F14AF0F0F2E4E2BD28D53375846 -:10BB100099BD319BBD9FEF84F10ABB010F01A56761 -:10BB200024D895E671AC43C719C6B16594E238DFF5 -:10BB300098C6B166949AC6B1CDDEC8DFF371FE0235 -:10BB4000F38A37CEC3432718E7935186E35845D38A -:10BB50007C32CA4CE338D87CE87B3E8E5DBCD87C16 -:10BB6000864D34CE6748058E93222A86B89575484F -:10BB700085691C278E03EF611C92CEFC1BC5DA532E -:10BB80008CF47FCD4EC09E56ACFE17A05FF2473BB3 -:10BB9000417DA2D27107805E49C6FD827FB524E354 -:10BBA0007CBE7450FA3BF5740E6A7601DA3B0B39B1 -:10BBB00088245487FE7915E7D105CDB33296C1B3F9 -:10BBC000B520AD08FCECF52E2FC44FCFB51628F3E9 -:10BBD00063D8050BEBE5139D06FEE57A6F32C9AA23 -:10BBE000063F8BDB015AF904D55F84EAAD8FA8FECE -:10BBF00082E74999EA69FAFE38D56F44D1C3BB0C94 -:10BC0000DB9D90181E4F34B275E4CB7547658CF3FD -:10BC100005C93B59741EB7F1692CAC4F60BE028751 -:10BC200023C0E9D1B3DB1ADA88F4F05D01760F693D -:10BC3000E84771C5EB0D057C517149C6E215601FDF -:10BC4000FD78E5F6DF40B57785A2C14BE87C67B7A4 -:10BC5000AC93AFA0E57372E75D5EA7AE9FD9F247E4 -:10BC6000306F1BFD0FFA99E3A765DDF877941ACBC7 -:10BC70007712295AA6749B2A0EE5F4E0E3AA21194B -:10BC8000E8755B2A83E74E788E81CF1EA4D75D1EB0 -:10BC9000D6568327F0A04C22B81E75F667C66D7F76 -:10BCA000ACE7D7D615137C77C9365F21A5E75D0FC2 -:10BCB00088884733BC9DFB127C16EA5775367C2674 -:10BCC000837F7929F8EF5E6AFC4E826C3C0DAF1AD7 -:10BCD0001FDC3E7B52BFE3BA7A73FCD7F73BAEE37F -:10BCE000973B4A6719CA7756CF31D4BF7B6991E138 -:10BCF0007B517091E1FBFC958B0DE585F50F18EA02 -:10BD000097342C337C5F145A65F85EBE659DA15C48 -:10BD1000197ED2503FD0DA64F86ED977D54D208F96 -:10BD2000B5BF1709D8675F384F3C0AF6D5174E09DB -:10BD3000FDAA2AE0352A87A76AD290BF4FD7A8F874 -:10BD40003CD79A8BFB6301079567BAD66FA83DBCB9 -:10BD50006CE544D023B43ED5E14FD7BEB52C487D29 -:10BD6000F78D10A4A67C2F362824D20FFC98E45E11 -:10BD7000BEEE1175DF3B2FF1BD812E58B97DBF8B13 -:10BD80009DB1DF770B3D23C1BE0B7E60C5FD9B7867 -:10BD9000F603FDBB82C4F01FB46717C437747AE79B -:10BDA0003591D9D5D788935F13E9B34261F25EB17B -:10BDB00063E064881754289191D531ECECDEF1C230 -:10BDC000149801D00F939745A12BA2F28BF41B6618 -:10BDD00090FB1B2CFE7DA09FBBF68B6C7F207230EE -:10BDE00003F669AE117DAFC17BD2DA1FD7C7776B7F -:10BDF0007CFD8E0F27E4FD9AE9F8FC434D613F88F6 -:10BE00001FFDA96636963FACF1E3B3B3A6149F1F9E -:10BE1000D554E3F7E3354BB17CA22688CF53352BBD -:10BE2000F179BAA61EBF77D53460F95C4D089F9AA8 -:10BE30001C68F62849E1F61FB7D7E9CA81E5F37C0B -:10BE40000E22FD7707CAB5370DE4FABCF3CB91603B -:10BE5000E79E7FDF8A41F4787832F35B7CFAF970F1 -:10BE6000BD2F0E51FAE7F6FD6E7730FAD82D643A01 -:10BE7000F867AB462804E2EA8ED7BE83F6327D2F00 -:10BE800011D49721AF7E1FB1B77F98F3804BD34970 -:10BE9000AB7FE2A97FCF9F970DF461F4751C14ABC3 -:10BEA00019DD9EF302DD74F86376D94EAECF4D787E -:10BEB00094B8DC99F179B6BF86CF8E0C88B7548AD6 -:10BEC000851689BE3BDF62C5799D6F4B60FBD89EAE -:10BED00094CB8AE7956FB17BF4FAA1329CE431EA06 -:10BEE0008B811EBDBE38DFFE9C1BE47E499AC57364 -:10BEF0003C17F8C3C7F983F19DD67F6538D3E33487 -:10BF0000F4632C9FAF17A6B37D4535F1D618FE819B -:10BF1000F65C92A6788E53BD707ACBB0441897FA2F -:10BF2000711E18A7ABC6E361E3A679F47C59B1D4BE -:10BF300081F535F8E2F5FBF7860F76FC3EB6B15891 -:10BF400013C469E2D58F4B0FE97305FC03D2267F3A -:10BF500009EB8E234B5B77242C6BFD06C262D07AF3 -:10BF60000DBC6F368C47DBA99A0F0DEDE2D35D2235 -:10BF700027347A523D791DCF0FA1CC8C74F6D31E95 -:10BF800013697FDD927325C479332515F55D0006AD -:10BF9000A2FC5469EB54FC2AA2BB03E39EE334B930 -:10BFA000576FFF2365B94FFE59C67806F90BED9D13 -:10BFB0007E97F9D705A4D00D4EC6BC96F299A0275E -:10BFC0003FB168F6407D3ECCFB2CB1E07EFE59F2DD -:10BFD000B63B576797954A3C3EB992ADCF41FA1FA1 -:10BFE000CC8FDA6986F5BAA4C1582E2637A7823CD1 -:10BFF00014AF9761C7962C82F55EB76F325BF2E0A3 -:10C00000BC4B48751DD829AB65B68F3ACF43A42BDE -:10C01000285C95BB9EC9077B3620317DAFF9CF8B5D -:10C020009219DC652921C547BF7FDC927BDBF708CD -:10C03000B40FD5815E0BBA8837563C66FE4A237C26 -:10C040009782DF0C2F21CB0D7068FD6A70885B84AE -:10C0500098791A3F93041ED761F2B15632DAAF8F46 -:10C06000733C68E50DA672A3A9BEC62732E7934CC0 -:10C07000C9FF38E89F4A5BCF34B4D308E58FEC683A -:10C080003D255A6FC3C5EA59A19E88F51AA5B1F19D -:10C09000EBD9A3FD35C5EAAF72D7B65782949FCAD4 -:10C0A0005E7EC20D41DF4FA4FA54887F556C7EC876 -:10C0B0000D783A2505DD40EF4F4262CCB8E07BBDFC -:10C0C000F8F23905F02390B529DE5F7CE446D0D73D -:10C0D0005F6E96312F26B0C51AB1523EAE6A593402 -:10C0E00013E2F7B47C8C951FFE14F60D03AD467A6F -:10C0F00096BDF0442AC489282699BD4D22687754FC -:10C100006DFAF334D0E301D2837C686E07E35F48B5 -:10C1100046B92F5212FB7ED7F215025CCE022D8F4C -:10C120007C0A79090113FF94F6AE279D0AC411DA3F -:10C1300025570AFAE5DF25DF053DA0E18384983D18 -:10C1400051BB75C3E863149EAE4DFFEC160C7E37F1 -:10C15000E3C3F3E1F9BF7A558DAF67CE717F28DA7B -:10C160002E84EDD45666FF9036F6AC90236EB03731 -:10C170002B9A642FE55052B1EDB9E79F023FED03D2 -:10C180002BFA69E5DB7EF3EE045A2EDF2EA7CC6492 -:10C19000D3710AA951BA04E8FF968E89D2A1ECD7CF -:10C1A000BF51D451ECFD4F93A3F428DFBE5F21A310 -:10C1B000FAE2AF20BC5FE974C6A04BF8D834B057A0 -:10C1C0006AB77EA580DFF5C93E810CC8ECDBBEB442 -:10C1D000E937B81E029E908E9C4EBD74EB43AFC8EB -:10C1E0008DAFE6613D0FE8C978F47A91EBE5CA5D61 -:10C1F0002E9204F1CF3F584333818E2FDDE38679B1 -:10C200009C94AA195F3FF3502AECFF95CAC1540FC2 -:10C210003ED9FBD267EF437E2B11AA53D93EA66FBE -:10C22000208F970F84F92D6CFC11CEAF98F891EF09 -:10C230004A9F110B213EFC8544A66F8F211737C8FA -:10C240006CFFE9E4462B24F9919360E7837DFDB60A -:10C250008871564216E33ED87D5A1C972CC1F217BE -:10C260007C5F6AB86CD1FC439B815F373DDC01F495 -:10C27000393DD83700E0A47808727C09B0DF2F1E62 -:10C280009D3A80D187E51B603BAAFF0BE03DD4EFD0 -:10C2900090719F50D78EEB4B36FEBD7C7C0AB70366 -:10C2A000D6B393A96CBFD23CBFA57C7EF4AF83E824 -:10C2B000F84B27DF4CDE37AD62F2ADC97B68D67430 -:10C2C000F8FEF93B4C7EA01DAC1F14AEC800FCBEAE -:10C2D000FF5601F581954462C9F52699CBB5F17BEE -:10C2E00080CA29C40528DC12E43344F984F69F8C03 -:10C2F000F847BFA4783D6DA7B3CF02301ED653A236 -:10C30000EF75EB4709D703D365A3FC93C6FE97658A -:10C310002F56C82408A665C50756F4BB2BB6C98599 -:10C3200030EF33CD07DFFD31E5EB33614D4E8DFA54 -:10C33000D32CA7A53B360BC09F66393D534A57EB1C -:10C3400058724ADFC794D3D2CEFF2BFA53C35BC0D7 -:10C350008437AA07872459E2E3CFAC075DB21A53AA -:10C360000FD2BF77487E5FBED3F84DE3336AA10D8D -:10C3700001FDDDCB8F1ABFF5F2A3C66FE6791AF186 -:10C3800066FE3E010C350A57E16E19FD928A36B6FB -:10C390007F43DB1DBA220FF1E3C3E58BD41FBA2222 -:10C3A000455F0E99CA61537D9FA95C68AAEF3795D6 -:10C3B000AB0DF52B5A0F2A2CC92862A8675DFA1419 -:10C3C000F938867DAFAD3381964F9520F0437A8F53 -:10C3D000027A4E5E4E4D33889FED15D1DFEA567BD3 -:10C3E000DCC9F4FD4376E6C7767B783989957BFA1C -:10C3F0002B75A0E7B4F73D7616E7EC2EEC7127E934 -:10C40000FCFB636DA21BF6833B432C1FB52F3CB591 -:10C4100028379D24DE7716179C2A3A339682FF56DA -:10C420002F7AC1355CB0EC7637ECBB75B70DBB69C4 -:10C43000367DBFF0B008E633E976B847035C24E800 -:10C440009306E6F3FC09FA778A047F3911F226DABB -:10C45000987DBD608DC91E76DEAB607ED97A5D5C4D -:10C460004BC7FF65BC9FD246E3F732B206F9AFCCAB -:10C47000240F7EEE0F1CD5E42187E4B0FD6DC2FCD5 -:10C4800058AE77A78AD937CDA678EF6E17316FF6F9 -:10C490007C9B48EA609ECD02EE7392607F94AB2A4B -:10C4A000D283FA4EC34B17C88D125F1F75EDFCD7B0 -:10C4B000FC07813F5EF9E3E8A7E9B3EB950F46EE91 -:10C4C00081F2AEF732FE48FAD62FD8F735EE237652 -:10C4D000EFB3629CAB7BDF6F331E84F2AB568C7381 -:10C4E000752FB7E23E4A709F2B3402BE0F66FE40A6 -:10C4F000EDDEAF46B33CC91548A7BFC8CC1F39DF36 -:10C50000F6EF1F42FEC8F9363A2BB00BF625A0DC39 -:10C51000045EB5A3FFDDBDF7AB7CBFF3EF379F2A09 -:10C5200085F891FF5C64F60EE0D724160F0EEC1927 -:10C53000FF1CE43757B6EC5720CE5EF0DA5F478336 -:10C540009EECDEC1EC9D7372E7B3B01F66553E5D95 -:10C550002E533C9F03E11944C873CA988260762C1D -:10C56000BC303C74533CC0BC285E4A41BFC7C34783 -:10C5700086F28F8A8F4FEF627AECBB98671FC58B6C -:10C58000E063EF5D219B80F367EFF77D351AF4CC14 -:10C5900099F032B4472E35EF6B15B6CFF23F67DE18 -:10C5A00042E472E63DF71F96DE8CFF3F82F5B57FD1 -:10C5B0005F39E8CBE7BBEEC7F24B2E2FC27B99F277 -:10C5C000FFD3FF6974DF41E9EEBE34DD9FFE879D36 -:10C5D000F7A5E87E98D3DDE581FDE5EEBD7FC5B822 -:10C5E000A936FF4BCDFBD5FF47E7ADD9EB332CD5B3 -:10C5F0004766D1FA4748647D2185F3F5F4A9EFCC6D -:10C60000A25F7F1BC71E39ADB0F8C76F09CB130CF3 -:10C61000A6092CCF83FB450584ADEB05592568673A -:10C6200014643D82F60191AA8FE4507CCCC858E88E -:10C6300065F96063F01CCA7503AFF5623CD0E41F76 -:10C64000165C7D7D3BF829079751F8E83807078B82 -:10C650001E6A299129E972C43A1A9FC7E079C83D38 -:10C660001DEB4D711AFDA399E0DFE8FCBDEB55E32E -:10C67000F769BCFFE9E4400AE4934CF7CA2404F5E7 -:10C6800048FD0AFD3EF234533F87C0AFD5C5CBFE0F -:10C69000A3F84BB7323FF2B764C9911CC05FBA8CA4 -:10C6A000F1C04BE28FB0FCAFEB06E6E079142279E3 -:10C6B000117F330655727C32BF59E2ED25675D0765 -:10C6C000C8AD44A8DFCBEC32F49735BFF7527826DB -:10C6D000DC9F96F8D01ADEA57419F35675FD225E1C -:10C6E000347AFC47E9A0D1EF3F4B8F73267AA47FC1 -:10C6F000EE91403E0BB8FD3FE5F30E11CBE95E092C -:10C70000F7A3B8FD3FC9992481FD7FAD745404B9E6 -:10C710002CB1B5CE8038BDCD2B205F5FD96541FFF0 -:10C72000C6962720DEB31A242C1FB578C682A17DB9 -:10C73000E3F7769D7980407CD8A7A0E14D0A597C2B -:10C74000FE2FDF7E3B513BAF81DF09B981FA5F0BE2 -:10C750001A49C441E7B75022C1C46488EF0AE423F0 -:10C76000437CD75886BFEFA746FBB954FD787AE4DF -:10C77000EFFDDC45F5D647942976C313F755282BF2 -:10C78000E8FCE3EFB6317C058E90D050D40B3EB17F -:10C7900050B76FF68895E98F5D7FDA910B71B149DB -:10C7A000DDD9894C9F0E47BF20C0FD82F3444D84E4 -:10C7B000FC83F36DC312715FB05D74F963C465B639 -:10C7C00072FFF99F209F823EBB37917A3887D14D07 -:10C7D0007A301E1BDC648BB9BF7BBF558B3771BAB7 -:10C7E000D13F513B6FA462BE4830514FB7AE999FC5 -:10C7F00048A3FBD201FE3ED2ED97FC57F10BFE3A67 -:10C80000E077ABBD735AACF3602B39FE6E3CF0356C -:10C81000C631AF6E6BB200FF5EBDC962D86F0C5AF5 -:10C82000B9DF35868C01B86E3C6077E5015DDA458D -:10C830002FE40F06DA3E55FC31F6ADCCF884FE212C -:10C840002EBECFCAE2FC7BE4F07CC0EB9EB336CCBC -:10C85000CFD9ADD497C782F34A3BD3730B49F89E27 -:10C86000D199FF78F89DD4ED8C4C063F7313E1719C -:10C870000C33FF11E4E3F35B089E0F05BF14F4C211 -:10C88000F966760E98A2642DF8D354DE7FA08FCB84 -:10C890005CD9BAFD9FC00EA86A133C903A5B25751F -:10C8A0002A106F0DB42689B0EEE6A85A5EA567D4AB -:10C8B000AD3AB9D86765F9C60727ECB903C6FDAC30 -:10C8C0004B21608FF85EEF71C3BAFD595B6E62ACAD -:10C8D000BC79EDF9EB1A32638A04FD10C4BB991FD1 -:10C8E000B29B1D86F2F744FF2090AF1BAD9DF77AF7 -:10C8F00063D0CF6F637C76D9FA2DF4FF997E7B47A6 -:10C90000D36F7EB150274759B63EFA6D402CFDB625 -:10C9100044500700DE97EC1D3600E8BAE4B0DC3F77 -:10C92000967EDB56C3F6F35EE6F9B0DD2D54BF5DAF -:10C93000A3D36F2D36CC8B33B74BB659F8BA7809E1 -:10C94000FD16FAEF91BF6DA0DF62CC77848DE90D03 -:10C950004DBF8D6E3B86FA6D748BC590379A6EBB5A -:10C96000947E13FADF0AF670BBEC4D88C13FDBB84A -:10C97000FDFD32CFC3837140CFDD6163FB9B97AB7D -:10C98000E7B2ED8CDE97D473FF4D78D6F4DC929D40 -:10C99000DA3947331F323DB76437D57302F023D3FA -:10C9A000734BF6B27B1CCCFA2DAB8F7E2358BF2A7B -:10C9B000C2DA075A3337CCA5FD8DF1C95E1BAD3FF6 -:10C9C00026AAEFC6EAF5DD1D3676EF421F7DD77E3B -:10C9D00079FA6E27D777548F0D05FD6AE60F6F9BA6 -:10C9E00031EF78CFF893CDBF06797943C47DC3A3E7 -:10C9F000FC5CDA9BE34FE6017F35DB98FEADE5FC9E -:10CA000077AE2688FD17BCCEE657E964F9C8552DE8 -:10CA1000CC3EAC6A16422AFDE7B4095F2B00FFA2A8 -:10CA2000BD021940CBB3ACAC3E7941DBF722337386 -:10CA300074FCB0605C39C6ED1748C40671F972E742 -:10CA4000B44F201E5F3E8EC5F1CBF9FB45873BEB13 -:10CA5000209EBDE84901F73D09CF07D0F21B4BDA14 -:10CA60009661BCD69C17A0E9F34521E3FB72533EC7 -:10CA700063139FE72CB113F142DE1263E62534996C -:10CA8000F1D1CEF1B149C475B3171F143F6A665F87 -:10CA90007C508ACECC498DCE7FD11B745E79D17902 -:10CAA00069F830CF4F8B3B97F376F1E6ABE1AFCF30 -:10CAB0007C357C9AE6FD1CE80D5008392417F2629B -:10CAC000281FA0DE08FE4EC4F3FB8593460CD0EB76 -:10CAD000E1AD5C9FE7D64F2A1848005FA41AF8A67C -:10CAE000B861F1A18174DE63DF57C7C0F2F8BD09F8 -:10CAF000563FEC8F6EB5F7A05ED3F8EA1BCE57EF2A -:10CB0000723CEE19548DE75403AD8207EC8A40C4A1 -:10CB10008EF80B50FCC1F995003FBF18A0FC05F240 -:10CB200074F0C92F19BEF60A2AC4C7A769EB0FE033 -:10CB30009FD6CF6D63F80F8404C47F1EE9C1FD91B9 -:10CB4000AA06C11BA1F5AB5A1763DE83A66FE99F46 -:10CB5000534F0F1D3F4AB1F8112BE9D6BF725EEF5C -:10CB6000466BFDBBC09F37BE2093261D7F66D1FF5D -:10CB7000BE8D41270D9F97E2CB0B1C4FDB008F4EE4 -:10CB8000C0570FB39F225FE3391AED7B400A1AF0BA -:10CB900058F0D4858BE269AC8627E053D0536D45BD -:10CBA00022948B5B05D22FB3EF3C617F522FB78B62 -:10CBB000F61E63FD3F23E0BD2566BED5E6DD876F2B -:10CBC000E3F02B9C4B03BFE872F9F61B13DFBE6941 -:10CBD000EF39920B7CBB5760F183B624C3FEE22091 -:10CBE0003B5BFFB7DA297FC3BED661D9BB51ED2BC2 -:10CBF000DF097CFD02BB5F7F2EE92A9808E43D6EC9 -:10CC0000B1611E19C23194D9957ABDBACD4EFADF01 -:10CC10009A17BFFF81BCFF78768D561E05E341BE93 -:10CC2000572B1D2F2B3A9E59AF6B7EFEA5E635F292 -:10CC3000BF38AFDE3C4CD281FB4E9992FF31AB2E18 -:10CC40000FEE369E67442140FB4A572FDB76917AE0 -:10CC500024CD83E79FEEF1687CC6F2DD0B791EFBE5 -:10CC60005471E27BB07E7EE663FB7C7916F2FB8931 -:10CC7000A09F27CB788EEFB32332C66B3F9BC2F2C7 -:10CC8000386F7AE3A004F1999B4039517CDC34562B -:10CC9000407F058E61C1BED92E6ADFF846E27C7204 -:10CCA000E11C57CEA6FA02387F3C664BA8169EDEE2 -:10CCB000829E9437018F93440278ECF0F52B80FB31 -:10CCC00093EEF933C1FB43E83A8BEDC7B493FE50C2 -:10CCD0006F82AF3FBA03E35BD617407C74D641A79F -:10CCE00013EE67C96AB4509F218ABF0924540B719F -:10CCF0009BF1C77DB700BCA5D45E80B873695B5358 -:10CD0000AD1BCA8D8257A5FD0782FE696E3A8F6DF5 -:10CD10000D9F4EFB0EC823AD07DD041A59BDC0267A -:10CD2000B87808DEAFC33C9BE24D021EFCDA161257 -:10CD3000888DF51BB2D17EB735D2F679B04ED0F6DC -:10CD4000D0EFA64FDFB905E4FD88C8DA37B37DEA36 -:10CD500062DA4E05BEDDB418FB5BD4289034DA5F8E -:10CD600069335B074A8FC85EF8DEB2FF495CC7666D -:10CD7000D2F1066682DE8F4C8132C9153C18EFACC9 -:10CD8000188974EBE6724E268E60FA43E065EE3742 -:10CD90006876D3BB7696EF5BEC5DA6F4A3FDBC3959 -:10CDA000AE7F26A405045A3FC5FDE7E314CF7EDA23 -:10CDB000E5519EB77170DCC74AA76E1DFACCCEEE66 -:10CDC000B75AD03A09F319169242CC67B8713CB3FE -:10CDD000D7DEBAD61E822B0EDE927BD2E1FDC16B6E -:10CDE000AD68FF9EDB26231F9D1BDC89F1E9938D37 -:10CDF000329E1BAE6D64F7739D6C66EBB8F80CDB6E -:10CE0000D72F7129583ED878CB3458DF4E6E62E761 -:10CE10001D0B9E99AA40B9A449F0B2FB8B987ED411 -:10CE2000FCB7620FCB47D0F45F259F779FBC45933B -:10CE3000BEABD4D61B93BEAB847D65373C8DEF0370 -:10CE4000C4C9F420D8FD40F7C8D7C8BF554764020D -:10CE500076BFF071D734CCC7DA2B603C7F7C9BE087 -:10CE6000837DFDD2F7AD21B457434577FF04F4F835 -:10CE7000075622A890D74EF14EF5C3386BCF9F7E50 -:10CE800041DF7F72D4069930944F8A10CF5AFE67E3 -:10CE9000DE6696C79277747D2A9CB72453FAA1BEAA -:10CEA0002D6910895FA7373E117CB7FC98E965BCF6 -:10CEB0009F42A35F9E525F0CEBD83007D34BEA66CC -:10CEC000197244C8611E27A1F6349EBF5DB47B5D14 -:10CED000AA42EBD5F1FC8F457BD7A58AF47D2DAC1A -:10CEE0005FB4FE2285F5BF689FE069D2F5AFB5D784 -:10CEF000FAD3FA51761BFB19B697972FB31F0D0E75 -:10CF00006DFC78F6F8B87FB9B01EEE8B19F79688ED -:10CF100049C7E33E9E394CBFDFA13DB5F86BFE3BF0 -:10CF200016E2D3E16DDC9F1CC4A7E38B96B154BE1F -:10CF300029DD6E681542004ACBD8634A651E963DCE -:10CF400020CF553C4E5B3585ED5BB5E41C5D01F2B1 -:10CF50003D334F403E2041BFD22F05ED2015F6173F -:10CF60004AF258FB12DA1EE4AEE5492687541FA8A0 -:10CF7000A02FAA1AD74DC3FA9B0415FA6F692AC2CB -:10CF8000F5BE749C48F0FBA663687F94B61E4B0107 -:10CF900079A5F2B91ED6DFAA8956BCCF4B933B4D7B -:10CFA0008EDF92F97D4D36CF28C8EB7F10808A2125 -:10CFB000BFE211C2FCD46619E52C308EC9E55BDBFB -:10CFC0004494E783D7DE8E72786EB310478E0B14CD -:10CFD00038977C32C4BEF7CAF15681CB31D30F27C4 -:10CFE0009D4CAE0BE03BC8F14E81FB83CC1E34CB95 -:10CFF000B126979792DFF22D26798E23B71D52E73F -:10D00000AD30EE3DD7DA11EE82EFEF7EF71ED43F62 -:10D0100032E67D147CFF8154D077C512CB57D2F015 -:10D020005829B17CB63E70AC5FA60CBC2C788C70D5 -:10D030003C6D7745F587087CCEEEE10A6E9291CF84 -:10D04000CD72F85F959FBF973C1FE6FCA3C123EE0E -:10D0500065ED217F2C42F1F4DBE6E7304FF5EC8BF8 -:10D06000C76E043C97EFA17C4BE77BAED9C5EF7B45 -:10D0700009E13A53D622621E389122F9B7B8F47208 -:10D08000C9F290CA5F76217F94ED60F9A465AF7C08 -:10D090003C1AF34496F7607E55F0456E6F063B47A9 -:10D0A000035F97492C1FCA2CE7B73A98FDD9B53BC7 -:10D0B0006136CC43D8C2CEE997856F97810FB57A98 -:10D0C0003F74C85A3DDCBF0C52BE85FD75804F7F52 -:10D0D000EE5CCB83EADACAE4BEAC55467FA96C4B62 -:10D0E00013C6B1035B3EC53CF78297B761FC20D005 -:10D0F0002A1AF31EB788B87F459FB84F65CE3FAC5C -:10D100006AA9C4FDB6AA30CFEF33E5BF95BFBCF71F -:10D110009520454DF9AF5F70831E38DDB1D90DF80C -:10D12000A4FD61DEE0F73F970C7951F1F37B7DC6FA -:10D130007CC2F0AA98F984A7E11F94C11F70707E89 -:10D14000D5F230B7F4E379DA91FCC218F1FBDE7363 -:10D150003BDBBE7816F2DCBB769C7916E0AEF8DBE2 -:10D1600067CF423E13D967C77529F0E2EF314F58B8 -:10D170006BF70B07F7F3B7BE80F9D5E73EB0A29F78 -:10D18000736EEFC90CC85F3BB7FDEB5488C7DDBBBE -:10D19000772AC62BEFDD593080C4D0EFDA13F8328E -:10D1A0007419F9DD663A1C6C3988795767DFB7A2C4 -:10D1B0003EEBCD0B0D57B23C5B95E78336C7CEA354 -:10D1C000D7F218AB5A6EB9E95AD0CF2DCC9EEBCD21 -:10D1D0006BBC541EE83B949ED75C06DD9A799EAFEB -:10D1E000896E67E11F943E6113DDBE6859F8ABA7F5 -:10D1F000E05B4BBFB879A091CBC09796A7FF738730 -:10D200006F8F03CEFDED4808A6317A85660A60EF80 -:10D210007D9101E71A4EC93D98EFD1B3D7EA817CE1 -:10D22000C6B2BDEFA17C9CDB7914E3AA84E7C99F59 -:10D2300023BD7F2CAF59E0F3DBE462F9A31CEF9030 -:10D240005FAABAF13DCF23657CABE597C6CB2BED4A -:10D25000710C6571687E6EA092FA49FCDEACDE7CD2 -:10D2600053611CD0E998214F579BB7B93F0FD79B0B -:10D27000D1FCE8D879BB5ABE60944E6C1DD1F29FA8 -:10D28000CF35F1BC69FA3E7D0CE4C1B1F53A10121C -:10D29000DE2331E451CB8F3EE330E545872E2F2F3F -:10D2A000FA52F0FE67F1F1A183C5AB35BC74FD25E0 -:10D2B000B63E561298DD49FD533901F705987F7A3D -:10D2C00037F74F357C69F0D68599DDD0B585F907FC -:10D2D0006679AE8A735F520A1FA7AA75FF68D03BB2 -:10D2E0005D0776737E63FC5CD57C8CE5DD52FD1CAE -:10D2F000D2EB677EBF84B9BF0CDE5FA02D767F8145 -:10D30000E64F63F6775AF2DD0EF09FEE6076D2E9D3 -:10D31000B0383DD6FD36B604D9903F50E762F76588 -:10D32000886E07DA47F7BAC6BD9F98024F05F37AB1 -:10D330006A97F13CA09F79F15ED15AD70C02F03C7C -:10D3400004F8D1C519648F9F809D26A715E6896AC8 -:10D3500014DE5E7AA45848484F7F29920EFAFCC327 -:10D360009C9332F4F76FA6F8C8BF49A46E0085EB12 -:10D37000DF828277991ADFAED6CAFE9F8A86784608 -:10D3800095B5E743B0CFC96B76DC0F17F7D9831893 -:10D390001F7B96DDAB7170E757CFE3BD3CBFB21288 -:10D3A0006E170AA00F4A789CE2E4CEAF9EFD77B0DC -:10D3B00023A1311DBFE4595A1FECE7E604B4F7BBC3 -:10D3C00077248E863840C96B0FDE08FAA204741FDA -:10D3D000D8992F0F08D5D2FE4EF467E513DB06E38C -:10D3E000B980F21D2ECC273CB8735715E8FB732F7C -:10D3F0002710D0F767E5CEBF4139B0279134A9682F -:10D40000F7A9FA7575119154BD3D570E65437E0B12 -:10D41000C1FC168CBF517E2E6F4DC4F31FBA7A5CCF -:10D420009E8383F83D518340EEA8DDA81AF39ED970 -:10D43000F705094C7F05AC3DF7B3FB1058FD80D2D2 -:10D4400053CCCAF58398DC7660FDC51ABFF2EF7D38 -:10D45000FB65F503092C1E10ED87B5AFB2B2FB35A5 -:10D46000CCF4FD6982C0CFE3FEF5CA58F74FC48003 -:10D470009FDDCB259020DCBF4AB6DB314FAB428924 -:10D480008C847CF55714B6FF51E18E8C847CF53D7D -:10D490005CFF55386899BE1FC4E180FA5026B6CEAD -:10D4A00097F05EA75D76BC0FAFF235970FFD8457FE -:10D4B000BE3AF1741EE4AB25609E74E56BFF0BE988 -:10D4C0005F698DDC05FCDFB3DD8AF793766D3F9CE9 -:10D4D000017643971CC948BEC8BE4E65D86AD8A716 -:10D4E000D6E671BA66E90438C7AB9D332C8BA32FFF -:10D4F000DE4860791D4D09BE5F313D67BC5FE67453 -:10D50000CD6CC3BD8965B6D87AAC19F4822E8E274E -:10D5100046CF153643BF674967DD204A924AA107C7 -:10D52000F7C7CBB664A683BF7BC07E25EE5B1D909C -:10D5300055F407E1A9D7C7A76ABCB9129EA7CFCAFD -:10D5400095281CDD4D9F160F22901F689F1D4B3F95 -:10D55000ED4D48407E2AB359639EDFFC1DE7B76D51 -:10D56000206F63D978DEECE8B807E49002704C7461 -:10D57000AA389F32EA07B07BA2E6E4EACF6D2F9289 -:10D58000EAB11E952FC4C722B25EC973F6D52B8BA4 -:10D5900096E6E54AB9A8B0BEE9E537314A27124C0C -:10D5A000413B49E23424EB071AF2FD25B9D006F8D5 -:10D5B0005248A1471281D4F528A70E12C6A7939A04 -:10D5C000216C1DAA26101F3FC5F767AD92FA18DE21 -:10D5D00037D32EA23EBF14DEDE4B7023DC56A99A51 -:10D5E00078D1DE98E9017B4C08FAC9B7941F6A6BC1 -:10D5F000A6E7B273E1C407796E6EC2E0737B0E7D5D -:10D600000DF601E533768FD5F749A8968E07C78CBE -:10D6100031FE3799DD676F1EEF2F9C0E24B8DF7047 -:10D62000DF39FCF568F7E781BF9EF8B771B01FE3FB -:10D63000F49008D84B094E1249180DF7E449A7F5A4 -:10D64000F2EB26AC3C94B233E835CF44E377335F5A -:10D6500013AFF479AF5E14B1FDE7A6F69F5FACBDE2 -:10D66000868F806DA3F7786E142F0E3E87E064EFEF -:10D67000854EC0C768B7B716E8A8F47CF820E06309 -:10D68000B493F983290D44EFAFE53A99BE5AC1EF3F -:10D690009FA67F854E5D7FC463C3F8E82A8EF7DEC0 -:10D6A000FA5ADCA44F7DBB0478ED53DF1EAFBE23D6 -:10D6B000767D573C781262C39314A7FF60ECFA554D -:10D6C000AFBDF7664485974C6F40709E9F5BCE75EB -:10D6D000827F95F8616A11E30AB61F60A29B03F886 -:10D6E0008FF28363B8EE3DFC5FB68E7E4363D09FBE -:10D6F0004490EF8A383CB4EC1C48E1FB310777CA10 -:10D7000026B65F39F75E1627FAB18DE5971EE3F767 -:10D7100001CD6D607EF5DCA56C1F9194B2733E1E49 -:10D72000FA1F8C77277442E97D67BD108A64C2BDF9 -:10D730003526FBB5F77E9C450AD42F32C55D347E75 -:10D74000D2CE23CDE7F67526E7CF85A4C705726F45 -:10D750003EF7FE3AD76B9ADE0FAE2359706E5FB478 -:10D7600038BCB03F2AF273A6C4CDEEF323BEC1ECA1 -:10D770007E392D8F2B4B4D84F58D84F97BBECFB236 -:10D78000E47A7580FE9C9674C181F783D4CADE3436 -:10D79000D083F2056AD751574DB93094A8BA736453 -:10D7A000D49E43E1963DECBE44C953484AC00EE4C2 -:10D7B000F703909419BD76D75B140F4BD6A9786EFA -:10D7C00075A193D999BF7015DEE31C0BF6E5382FD0 -:10D7D000BBE7D648C7E04E36BF5A985F665FB86B66 -:10D7E00015AF17EDCE19D462C0388E177FDF41B464 -:10D7F000AAEFA9208FFF2CB3DF2BE8830746BFF3E6 -:10D8000029C9782FFB02F7EA0F814FD7F0FB0857A1 -:10D81000D664E173754D1ADA9D75355E7C6A78B110 -:10D8200079EBF1DE37DB70D69FCDE3677605B56522 -:10D83000209F42F25447A06C4BAF2660EFDA7BF199 -:10D84000538FF8517ACB7E2C5B3DEC7723E486999D -:10D850008867DA9E94D0EF4B5CFEA7404EECEAD589 -:10D86000867BE4AC69634CF70D9AF0A6F1C7368667 -:10D87000BFB502E30F33FED6CA1D2AEC2BAFBDBEE7 -:10D88000F7DE19C41F35EF19FE7EC7F6D9E2E2CFE5 -:10D89000938CF6EB82FCBABB204FFA11BEBFF87036 -:10D8A000CD38C4D72A7E8FE443353E7C8A803F3A08 -:10D8B0003F6B7690C0FDE8ECB721E8D359E883FBD5 -:10D8C000678177017FA293E1D39A568DFB6B362750 -:10D8D000C397E80C225E6427C397E864FCA6F0B205 -:10D8E00004F8CBC5F6F89EE2EF00F0972D7D82019B -:10D8F0005F4ACAE4CBC3DF93147F148E142E5F6695 -:10D900003CA428EC7E4A4DAEE2D9714FD0F9C3BA9F -:10D91000BDA186E0B37F1C7F71A88BAD9B2996EAE1 -:10D92000FD32E02399F0F52448D2F3094B3D84BF42 -:10D93000B42051A12C303848FD60C3BD92A24732BB -:10D94000DDCBA66E003E587F58B640BEBCB874868C -:10D95000E13CA838DB97A4223EFD784FF323352A1B -:10D96000D26F1DD011EE01E5FED7439C9E0FF37BD5 -:10D97000285771F958CBE5E5312E27B5FCDEE435A3 -:10D98000D3599E554A8E85DF571621FA3CA6246F3F -:10D990009828142EB4A9557CE23D8BE47D6B680475 -:10D9A0006D97904D7CC02749EF3F1062F735160EFA -:10D9B000043B2849BB7F71A29A34070FC24624E674 -:10D9C000775055887E4C8725D63D55B5DE03368881 -:10D9D00087C68327C1EBCB7C888E97D0E042FBBD06 -:10D9E0009FBF70CE425A76362460FC2F81FF3E8B5B -:10D9F00093C25DA2A377BC7BA837BAAE4F74517AAD -:10DA00007A0046FA7CBC6118FE2ECB137221FE8E82 -:10DA1000CB137C3DD5EE39D7DA7DC3F5A33BEF6A56 -:10DA200083DFBA5EF6613BCF44A3FCAFE7FA3679F9 -:10DA30008A91CF357D7BBC57DFFA87023CA917A6B8 -:10DA4000A01E4BB939B6DEAD9515BCB7BC761493A4 -:10DA5000F36091C2CEB5F4D50318A73EEF1FB911FC -:10DA6000F4A8C657CB09D33B41E2F0E23AC4EFB782 -:10DA7000D1ECE095700F20D7AFF01487B3DF1F48CB -:10DA80009DCBEEF35DC3EFB17A94F215C17B4FBD30 -:10DA9000F89CE162FB13CB6D63F03EB55AA705F528 -:10DAA00084F48135042687B47FBC07E20592ECED4F -:10DAB000F041BCCF2585E1DEDC5A671EDEFB2E245B -:10DAC000E57980FE5FBA160CB9583E1D9D28DE9799 -:10DAD000E94929241F65E36E009E5F913D37138855 -:10DAE0001B6E48A9B603DEC6BB585CBFA1281FF158 -:10DAF00048F17B93AB7FB49F01B367F4DE8305DD10 -:10DB00006E88730EE60E17B397487A900CD7C979D2 -:10DB100083F63B276A9064E9E47DF9886904F68717 -:10DB2000FACA791C3DB699E9B115426C3DA6D9995E -:10DB30009A1E934DFA417BD60D996E38A7A5A4780D -:10DB40008177E119B478C1BE7BA5EE8E24C443353C -:10DB5000E081A4CDE8F55F7F3014ECC7FC98FC664B -:10DB6000D65F0B7AD7735F2AD0E994AC0E9803FC8A -:10DB70007438F67A3EE9F1AB1E033E58F03B51D0C3 -:10DB8000EFA7945C5889EB69F18571F82C6D988E3C -:10DB90007C4F200AAEF3C34E36DEE706B84E36F0B1 -:10DBA0003C80463904F919271BEEC3FB4A20CF5BA2 -:10DBB000D4EDEF933C15ED4BED9EB193A17BDCFAD8 -:10DBC000FDDDE25FD87D60B7C6E3AFE2C6D87E3D3B -:10DBD0009E35828D3CE2CD027B98DA373D11B07FD5 -:10DBE000365ABD41122D071FB7C7CC4F5CE29AFAD7 -:10DBF00004E07D89CBF70CC83971B27B41E3F3397E -:10DC00001BF7046C02C37ED3533C4F53F2BBF5F7B2 -:10DC1000BBF5DEC7C9E324C416E7BB43FB7D8338ED -:10DC2000DFDD2C9F8378627FD7FC8484A89FD00A95 -:10DC3000F3A86C3853F701E289FB091CEE533283D9 -:10DC4000FBD4F356F63B3726BE38C5F34716090C0E -:10DC5000AF1A7F9FEAB577FC780F8D99FF848D57B7 -:10DC60006D184FFBFDAC5DC6385C05E51FE01B6120 -:10DC7000E378CC5F171E1FFF18E4257D7E44C4EFB8 -:10DC800065176CF8BDEB67DE0D7321CEF3868CF75C -:10DC9000757FDE3E3591C5798C71E8856EB6CE9F75 -:10DCA000E6725F7C6135F2672F7FD42F5440AE8AD5 -:10DCB0002F3C8AF64CF11601EF8924C19E43932430 -:10DCC000CE8713A0FDD969CB01DF13EB717FA3646D -:10DCD000B3D5BB5AE84BE7D32ED570AF7A49E71AD4 -:10DCE000EC97507B2A45B7DF7D8AE701975C60F7A8 -:10DCF00003124F90A401DF73BD13E55FE3BDAF5D79 -:10DD0000F6D871F66FB83D537C6182C16F88CEEF53 -:10DD1000FB4C3EF97A5ED2398EC1D53B9F0DE36351 -:10DD2000CD273A8F89D8BE2B29F6F8991CCF276AC0 -:10DD30004AE1E406295558BDE2FAFB14D027C58D07 -:10DD400049C9826E5E250DE5863C8C92C622659E91 -:10DD5000AEDF281D1CBF9D343C4A87CC47E5EB96BF -:10DD60003B61BD2F74B961BC8D8BF27FA2427F4CA9 -:10DD7000FF7C22D76754A37EB9C71DEB5C43A65B2B -:10DD800035C4954A1A387DA89D9CA7A38F46177362 -:10DD9000FB134D25F93F8178F293EC5690F87AC742 -:10DDA00044B7CCD8789BD08BB72CCC07BA34DEBE26 -:10DDB00063C8FBE983374E5F0D2FDA7B6A1FE502EC -:10DDC000BE2640C0A93FF4C3E87F297C45C7E5F4DF -:10DDD0009F147B1EFEDE792C25416A3F2CB8E43C63 -:10DDE0001E2441DB45E6A1D19F5C6DA0BFFFD11190 -:10DDF000D7811C6AF45E70E049E4DF05541E615F60 -:10DE0000FE64FD7D86F5210A5F1CBA0F0F92ECFCC3 -:10DE1000FF7374FF440E6640DE57701D5B474E6D06 -:10DE20007C24438FE725AE490B812E6453FFCB5AE8 -:10DE30003F8293BDED2AAE4B32C6C376BBFC0137A1 -:10DE40007D5FCAFDEA1549D346C65AF7A95F381166 -:10DE5000E2CFB535D32742BC4DE67623FCB216D8C7 -:10DE60009B70057AACFBB5EA395D1FAAA9C6F835E7 -:10DE7000B10589477FDE9730BBE81BC2E22D5A3BD4 -:10DE800045F67B20FEA908A410ED39C9BF32330F37 -:10DE9000E2182939411DFE1E7533BB6E4DDA010FA4 -:10DEA000E4935A69FF108FB1A54BE78DFB94AC9CAE -:10DEB000238C97613E724A98603C339BBED7E15BEE -:10DEC00049A1705EC4DF946C6EDC2F9208B3D3B4AA -:10DED000F9D337B89E3DCCD7A5E510C74D013BCC53 -:10DEE00082FED07A1EA7FC654D21C78384EB98354E -:10DEF00089D5571219DC76885B8BB0AE46B0EC82C0 -:10DF00001B7644BC9A0C7F7F3489A8F83B7DFD4882 -:10DF1000A40EEF3199D4793FBCF725F8B7001F7CE8 -:10DF200039B0E34301E2D085FE2B61FD6D108339EA -:10DF30002AADFF2BB12707EAC1EF7BBD9FCC9E43E3 -:10DF4000206FD9AFDB9762F772AAFAB89EB93C642A -:10DF5000A964DAAFF9CB95FAEF4D09BE5D0047CA67 -:10DF6000C702EEC3D4DAD9BD3EB5AEDB1261FD3EC9 -:10DF7000CAE985F407FE696776CC79494D4CC6F845 -:10DF80006656EEEB86F1BD86B2C4FDB74D941F25F3 -:10DF9000DDBDACC3259F05F865443D7DAFA75F8C13 -:10DFA000B85AB213AFBF8DB90FA3C147C725803F81 -:10DFB000F1C234B6BE9AF8608FC0E00FBAB8BF4560 -:10DFC0008222D0738E765FB0B48295B5DF8B002A43 -:10DFD00052383ED0F617C80A56E6FB9481796C1F7A -:10DFE000D20CCF9CB6873B20AE3FA76DE07CD89F7C -:10DFF0009AE31CF96778EE917B0E24801D789F8050 -:10E00000E73F7EFCFBD7E504FADCF9CE463C6F7CAB -:10E0100096CBDD5DA407EF61F7130FDF270FE1FB60 -:10E0200079F00373580ECBE0A7CF8D847E74032D57 -:10E03000DDF97AE80630DBEE6AEFF90DA8017FD84A -:10E04000330DF700B476ADDE43ACCCDA45F160E3D6 -:10E05000F6A80DE7159DB70DF1F0416FDE7810E9D8 -:10E06000D18B277EAF928697DE7927DE3603E2BC1E -:10E07000F1F4D91C67D69FD9E60783CB8CA7CFE1F3 -:10E0800013B5233F77FBEC8954BF7DECF639E0599B -:10E0900061EBC99086A2BCB8A15C25FA87A4523C6A -:10E0A0009C1DECBFB23FE0A3A3DF65E9D10FED4CAF -:10E0B0000F90BC0C9C8F76EFFBC1074EBAC0EEAC44 -:10E0C000DBF95E063C2BC5CEB5B7637C53447FE8D5 -:10E0D0007CCB95173D1FF621C49DE8FA372251E30A -:10E0E0004336BFBBF9F99ABB5B12F07CCDDD4B45E3 -:10E0F000C3BDCD772F65797744EA187DABC15E5FEC -:10E1000011B71F880398FB99BF7432F9B81FECB39D -:10E110007A26615CE059C65FF3A7F844C8479EB011 -:10E1200052C078CBF8E36A6B272DCF0F25E1EF1DA6 -:10E13000CD7F60492EDC4350D5C1E27B03C4C53995 -:10E140003F83F8C901B68E437931C8B7D3A73A7572 -:10E15000F1FE2EB93A07EEDD0BDEE9F401FF14DD26 -:10E16000EAFB007F2F91C721B47575574311E6B1C3 -:10E1700016CD55C701DD8BC276FCFDC1221B911C5B -:10E18000548F1549C406CF010A91ECF074101B3C62 -:10E19000F397B37BB28B1B66A17DE01E57A8C0FD31 -:10E1A000B7456D2F7C01ED4BA4C87E76AE85E1A707 -:10E1B000A8EDF0D7C03F0B7D859877F89D2D8AC1DB -:10E1C000FF1B153696AF6935967322C6726EBBB1CA -:10E1D000BC15EE38D3D91107F65A719D283FC3CE2E -:10E1E000E9BD2AC0DA04F1602BCA5341795B3EECE9 -:10E1F000479F79C96581EF7BFECAFCDE9EAD76BC88 -:10E20000EF6DFF1F1CC40179852FDB37C2F7338EFA -:10E21000703EC4E1687DF63B5B85E191E0BFBD7275 -:10E22000B5E6A78746C3BC5EF91BCB93E9D96AC59F -:10E23000DF4F39B3FB8597605FECCCD62BD0CE7A1D -:10E2400055085AA0DFE02A467F339F966F31FAC502 -:10E25000F727327DD32D307C5FD9609CF755216341 -:10E26000F9E789CC9F9A4774EF3361FF5EAD4B832A -:10E2700075F5B9D8F70D3FC4E5E2C517158D6F45A3 -:10E280007E3F1B5175E797F644F7EFEEBD02F22A89 -:10E29000001743A3EFCB4DE36AFD1726B27DF814B8 -:10E2A000BE3FD3F38688F8396DFADDC25EBBAEA6F9 -:10E2B0007AE014DD3A54DCB03FB508FCA3C6FDA9F2 -:10E2C000F374EB4BC5D683A977605E9284BFCB54C1 -:10E2D00031E7F94727A4C07B310CF0C277887B7502 -:10E2E000857FE3867AD4DE1D23EAF05ED270DFC03C -:10E2F000293A39FD8FF2A5264F15DC3ED935AE639C -:10E300001AE4899737B0DF6F2A0FFFE816F8FD454A -:10E31000D2C8CE99E64BA450A4F253B1FD473F8436 -:10E32000DFE30A3C33D60BF0D02E6E85F7E5CD9FA8 -:10E33000E27982D5A6DF11D09EFB387D69FD888504 -:10E34000D65F7D9BB314F413EDF775281FC8DA88E8 -:10E35000F79BB84FB1382D7DFF3EFC24CAA9C9C137 -:10E3600037EFA04DCF90F0BB3764C2BC8D7C46F92F -:10E370005600BBAB67B380BF6B4B2DADFC9BC1A4FC -:10E38000F62DC3BC5BFAFDEE58E79D17858CFD9812 -:10E39000E9FF07CEBFF42F4BCF47E67AFD6606F1C3 -:10E3A0005C62C552AAEF74767EC5F17ABCCFD13CCF -:10E3B0000E06E174F906B05EAA28DF76EDFE21C1F3 -:10E3C00096CFF36687B132DE5B08FC4A19A5FC6A7A -:10E3D0003245057CDF4CA6C3F35521F2A828323D17 -:10E3E0008171A06D09A827BA3C9DCF3F0DFCD53C9B -:10E3F0000AE34F83F879CF2E3582F73C76F3F86441 -:10E40000978795CBDAEC980773E6AC827A7459F863 -:10E41000A01BE8D1F592DD02BF4B7A667BBFC990A5 -:10E4200027D91566F7FF9E0EF7C3DF7F8DB76E996C -:10E43000F581B64E1E837FC27A9AE8FB06D65BB2A0 -:10E4400082E5910EE8579D13EBF724B476294A75BF -:10E450000EF829FF1B63EBB5D4008000000000001C -:10E460001F8B080000000000000BDD7D0B7854D5E9 -:10E47000B5F03E73CEBC92996466324926218F096D -:10E48000841020E024860814EB24040C187542D173 -:10E49000A2B638804080BC44DB46A55F26244242B9 -:10E4A00051428D08087140B1F48A6DB0A8C106EFE1 -:10E4B00080F86AB537DADE5EB5FDB92370295A1ED9 -:10E4C00023F452DBDBD67FADB5F799993349AABD6A -:10E4D000F7B6FFF7FDE9478FFBECC7597BADB5D722 -:10E4E0005A7BADB5F744BE6EF1EC2D60F0172850A5 -:10E4F0009C8C5DF2BB3C9BA0BC4482573318333AE2 -:10E500007C465B3A63D672C6BCF0CFF186BC5786B8 -:10E51000FA53B2E79BB6718CDDC57C0686CF72BF1D -:10E52000818D853E9DD0388BB1650A0B290E782EE2 -:10E53000F4BE2F4DA53263D07FD92E29D801FDEF2F -:10E54000DA6C64CCC4E8EF33F8B7A217CAC5B1F2ED -:10E550002A16343019FE63575C3B187F95123A2A0D -:10E56000A530B6DAC442C930EEEAA7B4FDD6B01081 -:10E57000C1D370E03363FCF8303FC600B4FF64EAF7 -:10E58000BCBC6EDB34C69C0628C3BC236FEB8388FF -:10E5900087FF907D34AF35CC4FE3DCDE5AC54EA506 -:10E5A00031D67C5F6BD65DF0BCD87A7FD65D5743A1 -:10E5B0003DC201DFB730DE9FC1BCF601CED654B3F9 -:10E5C000502EC0B71CE69B5406E541293405CB26E6 -:10E5D000164829E3EF53CBF87CBD71F0D5B31EFA92 -:10E5E0005EFD2EED7BF68B34C267031BA27AF654D8 -:10E5F0005C3DE0A341E0A1E100BC8FC3C3CC03526A -:10E60000C07A1596821D19005FD359C63641A9E913 -:10E61000D06746CDF8AC8731C04366126366A0D799 -:10E62000A3125BD45F42FD26D64D8136F8771D9646 -:10E63000DBA9DD0981BF476F5991E587765BEC5017 -:10E64000CE16089E0EDFD0E1C7A91C32C17792AE6C -:10E650008E96A9BE623D2FD7D98A6BB6E730B64DEC -:10E66000EFCFB2011297C9BED77480BF271DFE5BE2 -:10E6700090DF96E9BC790ACE97798B7C00076BE531 -:10E680007878ACAC65624B490CAE187C9CBEDBA4C0 -:10E69000FE900EF82C7058F2EC7323DF46F47E4B9C -:10E6A000AC5DB34DA279A41E0BBF3606E9FEBCC417 -:10E6B000F642BB1DD287AF8D817E3BE6B9590794E8 -:10E6C0005D4027B90CDFB34E09F0527EA8EEEE573D -:10E6D00091CEE5499EF1F0683C5429375A68FE779F -:10E6E000FA009ECCE4963D3AA8CFBCB3B80CF91B17 -:10E6F000E67DE702787FAFCD4DDFCBB270BABBD6F7 -:10E70000070AD696E0F77D77BF0ADF8B4C49F2E027 -:10E71000F733015756073DBBCCD88EB54BD8EED159 -:10E72000143E7EBA4EBEB30ECB65BCEC582779F7CB -:10E7300012F36DA579671A590DC289EF8325B46468 -:10E74000BC07A93EC8E93BBBA514C7CB1CC79F4E5D -:10E75000432807C7794BA5F760968E6520BCF0DF8C -:10E7600000CFBD072B331DD0FFAD732645970A4F51 -:10E77000176343D84E0959183E0B8B797B93685F1A -:10E780003A3B131783334FDBEEA2DE9B7A35E0254D -:10E79000F08ECC901EBFB37853EDD0EE4B063E8F7B -:10E7A000443AF6217D603ECD9F02E46971745B744A -:10E7B000C580E3357FAAB0E0D5B1F7E7DA4C2C5835 -:10E7C000142B37D41F9B8BED1AD9D006E4ABC6FEB1 -:10E7D00064168CE3F72F258DFC5D95BF9B3FD5B16B -:10E7E000401AB16F8ECF8AF8896C588EF01F91D87D -:10E7F0003E86F5061688FB7EF3A70E6D390A67067E -:10E800008D136BC7B4ED067E4FEDD8F4700A7EE72A -:10E81000822D9CE210F3C37ED9326B41BA5C0CEAC4 -:10E82000027A58C717DCBCFE226335FD96587B750B -:10E83000BC0B8B0C2C44788FD0B8889700C8B69D41 -:10E84000839F18DC506E183C4A7851F9211E3F8195 -:10E8500038B991D13114D2C19AFE856D55578919B5 -:10E8600048714C5DBF6BBABCB3A05ED669D67372FB -:10E8700079747D93587954270B79D0D0553D2BBEB0 -:10E88000CCDBC7FA37D654C3FA2F2FE1FD4FD89A05 -:10E89000DE58AFC4E411CC230FF1122D9B12CA161F -:10E8A000284F892BDB12EA9D09F5AE84720E6F7F2B -:10E8B000CE1ACA933D8C7D645B5BA3807C3997152F -:10E8C0005A2C417973C7BD35D520E71ACB87BC32A6 -:10E8D000CACF41C923B118FE9A3CCC1B04FC593C59 -:10E8E00061C3B212C4C3D06BB8FE1B06249B047C68 -:10E8F0006EE93F18A232F673C7F5EB97A85F43FFA6 -:10E9000087D46FD4F18B75B48E37159FA4768000B1 -:10E91000DB69A0D35799C45201A5058AFF8FA8BF10 -:10E920001AFB7FC3F52E8B18F8FCB81CBC90E57D54 -:10E9300085E4E011C986EB2ECA7738AE25C6EF6AAA -:10E94000FB5F4D19FC571C26F9DE4FDA1568FF7F77 -:10E950001A7F338D01A97E854D66A05C0D4E447DE6 -:10E96000BC93F927A21EFA7AE3F8A33A6877421F0C -:10E97000DECD005FC5F64D350AB43B610DE74A2098 -:10E9800043266DEDE5E5F4F06EC46760EBA384DF2C -:10E9900013B9E15C1D94A7DA43BC3C3EBC1BCBB76A -:10E9A0006E7D8697A7847365E83F3670A0A61ACA65 -:10E9B000FB6C23AFD77C3B97E32A7C97C779B3EDF9 -:10E9C000E9C8765C4FECD603C6401E2E5EFDF1B35F -:10E9D000FB000F8BEF4F2639B5EFDC57E6FB68FEE7 -:10E9E000019F5201F290B33ED763248F15B203B258 -:10E9F00050773962F4B0E60DB949CE4F6A3988FADA -:10EA00003E737109C9F94F53BDEDF669B1E7271996 -:10EA1000F00438DAED362E97659D97DA3F6025BB16 -:10EA2000678B99CF07D60DD1D722E8512EE6536ECA -:10EA3000D7D133CF3687C6FB40F2EE30C9F8640138 -:10EA400033D2735512D91977EC01B90072B957C096 -:10EA5000DDBB75623000E3DF21311FCA8D5EBB373D -:10EA60000BE5C30B7F91EFC4F9F69642199E3F1652 -:10EA7000F2BEB7CE9B658FD38BBD7B78BD2A777AEC -:10EA80000B787F55DF6476F0EF646E99B817E791E5 -:10EA9000AC302F96972F2ADADB4E7A7B01CD9B790B -:10EAA000BD5912CCF7F4AAB13AB42355FAA4157A99 -:10EAB0006FC2F9DC8EE35B627452BFDF8EF346BD3A -:10EAC0002F83DE87F93EE0F0D3FCC10E984A76A092 -:10EAD000B003DA71BED362F8654A781ABEFFFF0848 -:10EAE0004FF760FDFF144F23C88B00B66B6C0579A0 -:10EAF000A18B9317027FDBA4903E93CB0B0FEA39D7 -:10EB00007CBF00E4E3ED36FF468447FDFEE2071AD2 -:10EB1000C9EE53E14AFED68B355F65C3D759A25D76 -:10EB200076E203D366067AEC84A19FE4E289F9CC0D -:10EB3000D38EF243C7EA118FAA5D5971FF9AB718B5 -:10EB4000D8B397ED32D1B95BF266E1BCBA81AE269B -:10EB5000D4C37586E0BE82985EECB50777AC40BA48 -:10EB6000DE52E209B8493FD27A0BB42653BB5E7B32 -:10EB70009829583FC36D034890CE448FC86D86E0F6 -:10EB80005E09E9CDF9A577D5A4604022BA07A8FFB0 -:10EB90006D9C7F7AEB18D9F7BDB7B9886FCC2C681C -:10EBA000467846E3838C0E467CC414EFD43A6B0C53 -:10EBB0000F3F13EB3AB93CFCFCBFA11DB9D94C7611 -:10EBC00024EA4CDC77B19E4C8217E8F902F187BA4F -:10EBD0005F7A242BB889F6679E0AA4C746AB7709EB -:10EBE000C1FFED6437C2BFCBCCBA4C65B8FD609DA8 -:10EBF00024EF043CACE73186F6D99DC23EFBF7FA20 -:10EC00004B56B4035EB573FB0A19C504F26F29E3D2 -:10EC1000F54BD7257F88FB99A5EBE49011F62BAC3B -:10EC20006B8E371CB7CF208E82F1FC425EB2ED11A5 -:10EC30002BF28D1FFBA5E0F87FB4BA2D5886FE534A -:10EC400091ECD0BF38D6FF3DB16E17CB1C7ED69667 -:10EC5000EC46FC26CAF5F754F87A1EF3C67F4FFD42 -:10EC60004EE2B8B08F7B1FF105780FA5A23DFF6D76 -:10EC700099E89A08AFD31079C80CF58BDB64FB7A5E -:10EC8000C0A7BFD54AF355E1BD3333722DEDAF12A6 -:10EC9000C63F93DC54A1E0FCC5FE83ADD3EEBF18A4 -:10ECA00033C4CAC017CB5984F631C3DE8B7D6BE207 -:10ECB000BE8FB1BF18E3DBA9EB85B9A504F8055FEA -:10ECC000B92505E9E69738DDA2F44E805BC5A7ECCF -:10ECD00018199F4E433817E595BFD5487848ECAFD3 -:10ECE000EABDC7CCB03E80AFB64B12F1E3F6FB9263 -:10ECF000498F3113A763F3EA2437F2E74E43E469FF -:10ED00005A372F1919D2F5A239F202C9A342EE37A8 -:10ED1000B8F833790FB6BB90CEF9FAC2613DAD2792 -:10ED20000E0CD83B3F93F752BDC4C7BDD09EECC676 -:10ED3000F5D88C9884EF3707FEAB8D01FE4EE9F8CD -:10ED40003EB87940BBDFBD00FFEACB6272E122E34F -:10ED5000DF090C703900335D45DFB923896D82719D -:10ED60009B749217EDA3A6D593821D9C5F4CB85E51 -:10ED70001A04484D3AD8F795C5D67793EE6411EE4C -:10ED80009B1A4C9B87E414AA3F8EFB2D86FB25E83B -:10ED9000B71A3B150CE7E7A6CDBFFD33C2DD7448BB -:10EDA0004BF786187F489F49D83F8E5F0A627C40A8 -:10EDB000F635CA876A161C2F713F0C96936B8682B4 -:10EDC000E8876916FE89F463E1B9C81FD6F27EB6FA -:10EDD000149ECD67B97D317370CF2BB8CFB5D70CEA -:10EDE000E5E2349B5BD75E7DFAEA187D5538670C07 -:10EDF0006E9571FFA6DA2571FBC7890BA6C43FD7B4 -:10EE0000533FDC8FE2F7C2F80AD785C2F5D936A1A5 -:10EE1000CF40EF91DC5DDE3381F41EEA25945FEA9A -:10EE20007E16E519CA8F271D558B1C30CF92B4AAC8 -:10EE3000AF38A6F1EF901D8F9BA019C3F199A85789 -:10EE4000D476B8AF6DB18CDE2EEAE7D991CAE583EE -:10EE5000225179C54FF57B36117C0AF1CBDADD05FD -:10EE6000246F557F4C83F043AD10FE9B15C27FB3DA -:10EE700072BB91B9E3FD55416DB941ACF74616E659 -:10EE80007EACFD501FEFB7A966212BD6A3FF069FCE -:10EE9000FDDAFECD2C385B41FA0E7C668C7FCF7A92 -:10EEA000F97CEF1474DF61E67E9B99EBF6C8DC1900 -:10EEB000C5E79B5AE62D7810F5C49B7AF22FFC87A4 -:10EEC000A0938A17A3A3EAEB88EF24DC8F61BB072A -:10EED0008D8497D3A08F0F0ABFC602DC67B6F9B343 -:10EEE0000A0B113DB6BC05D6E1F8DDF492B91EF966 -:10EEF00065B343A7E1A72A879ECAE4EF41BCB727C1 -:10EF0000935D0D689E8A7C543156D5936C2AFA998C -:10EF10003ED483BD05E5A65B2D7E1C2F8C76019427 -:10EF20007708F9B5C361A0F1D472741F27F805BE44 -:10EF300043E3A1DFC517C707C168FBADC25EE4723A -:10EF400061DBAA24924731BED531E2DB129F01FD7D -:10EF5000452F0939F2122094F651FD662E47142EE2 -:10EF60009F5E3A3B89E4DE1B1FAF26B972695112DE -:10EF7000334AD4DE2B61FDF3C6E07A28DF25FCA8F6 -:10EF80002F49DC0E0C1CB1D2380D06FF0EF42B34C9 -:10EF90003C37DE0314632F1882DF7F1AEB5F369352 -:10EFA000DFAA2185C3D9F0D21892933FD6079FF9E3 -:10EFB00001F9218C649F3524B953A9FE27690CEB14 -:10EFC000BB92FD8348CF6C23B71B1B0CA1223BE0F7 -:10EFD000F16490DBBF2751D0E0F88356B26B00CCD0 -:10EFE0002CFCFEA9EE4CCF26770C2FA71E9A4CFCCA -:10EFF000BF4DCFE91638CCFD9A27F5BEB959503E22 -:10F00000F97CA907768EECA2CF1032008CCD5BB8CC -:10F01000BDB64CE7EE6B45D9F472B247B3DF7C78EE -:10F02000652DD637AF5E7713CAC1D1D633CAF37810 -:10F030007FED0516C9A3FD66FDD8FE107CF7C2E082 -:10F04000440FA947E60262039FD878DBD37AC03722 -:10F05000F2D7113DF1EF171D1FE78BFB3FD42FF8BF -:10F060009D6690BF513F32C9DFB8B23C5299D3B3CD -:10F07000F9A54C619F69EBEF48F55F40B9D6F4DD27 -:10F08000DF9F6825FC4648FEB11EEE1F3FADF72E00 -:10F09000463EB557870C4BE3F6B78634BE8E9619BD -:10F0A000855E672143FCBA53EB2BAAB47CAE3EF5D8 -:10F0B000697C1F691DE2727C78BD4EAC9BAF185114 -:10F0C0006F71D70DECA7CF727F8621CD4DF533CF71 -:10F0D000860CCBA09CBF2E6458219EB82E00DF2149 -:10F0E00013CCFBF40E2B5FCF80061C67C57446F66D -:10F0F000C80A19ECD0327CEF1E08035DCE3C6FE7E6 -:10F10000FCF527C00AE07B0913ED8C60B782DC7A3E -:10F11000B1530AA15DBF64BB71AFB900D7B157B697 -:10F12000223D774B24B796745616ED80F2EA43538E -:10F1300088FE29D3395FAE0EDA49FFCD147270997B -:10F140003168203BFA19EEA783F1C91E6E804E5933 -:10F1500065C3F180F25BC30F416D9C6166BF90A7F0 -:10F16000FBE3E20B63E3E47A7F427FB0E3B4FC119C -:10F1700050F50E9773CC9D89724E95C34687AF3478 -:10F180008DE4526126D217E8C9E5E44189F0DAC876 -:10F190005AB8DE10F23EFA5DA12FCEC801AE978CB0 -:10F1A0005BE93937AD80E8B61AF50DF9CDF9FE6E99 -:10F1B000343E989BA6137271643EB85EF041C35909 -:10F1C00016BA16BED7B08E851AA7F2A7752AE941DE -:10F1D000AE0F4D229E61E2F18ECFD38B897A70986B -:10F1E000DE4BD0779906A1DF049DE3FDD9A8EF6738 -:10F1F000AE0BCAE8D7CCB379AFCD4C8FD92FCDEFBA -:10F20000994CEEABB0EC63632DE89FA97CC685FEFC -:10F210005DD88FE3BA4A06BCEC81F7BB55FBD6C577 -:10F22000E7EB3270FED52B3E566A41BA0CD17E35E3 -:10F2300092CE6CC88F2A3E775BA15F19F6E3EB2D67 -:10F24000DADFC43A93E2FA57BD6426B97AE5B035FD -:10F250006824BBC39F6F87F1327E65243BF4C24BA9 -:10F2600056D29F1784FE73AAFB7EB681E8D38A74B8 -:10F270004D476EAA1A83FE5326CD1F832250B5C375 -:10F280001AEDA3F9B3457DC1D0AD9CAF8CB45FBC82 -:10F29000620F7F13CB000F43FBBA05E98CFEF643E8 -:10F2A000B34B1F80F7CD3E8B8763DF5F8AFC6A9488 -:10F2B000EFBD15FD2A73E57591FB601E8DB9169B98 -:10F2C00011BA54E7FFFA97B741F9A3437A66443A73 -:10F2D000EF9BBD888D1D5DFEAE0AEA4F86E3D6CB5F -:10F2E0009AFDDA7263BFB6DCCC9493E13879FC58AE -:10F2F0009AD5796632C90ECF67C0DF4663CBD93D58 -:10F3000000AFF1C746D2470D69FE5D69E837D545C4 -:10F310005E433C1BF3CF4D453F4555FE9F28AE73E2 -:10F32000E5DBCC83705F315792FEBEB2C3EC0EC4F6 -:10F33000C9AF66C1FFBD79B554DFBBD3E896787D10 -:10F34000EDB40AB407E9DBF867D201FE9BB7CFFB47 -:10F3500088F64D68B543B917ED4BECF79C146C4734 -:10F36000FB713BD77BE7C17E34A1FE14EBA9591E8C -:10F370009C6B82FFEC75D44C44F9A2FC59F121FD41 -:10F3800037E25071F6EEE1E8FAE47E9C1BD08F3351 -:10F390008EFC3887516E349AC2864A18E7BA3FFF0E -:10F3A0008EE4F2CAD6A564D7C7EC5C23C99195F761 -:10F3B000F9E9FD2B3BAEA7799D8179237ECEECE662 -:10F3C000FBB995399620C2779D9DDBBF2BA19F2469 -:10F3D0000DC74B221E7EB3EB7A17D2FB378C7F2FE3 -:10F3E000D0CFED84DFD8865248FEB85B52D0CE6BCA -:10F3F000DE7EFD4728B756EE963DA8C7D9112BF9FA -:10F400003D56EE9E3371B905C7B99C568978EB9B82 -:10F410006393E9BDEC0B72FFC9D075F05EE9BBC622 -:10F420008DEBE4F86E2387CF6E7A1AE1BFEECF3210 -:10F43000F1BDA2637EB4577B0DDE89B8DEDCBBF67E -:10F44000CD45BCFEA62E5B47ED9F95980DF1606FF4 -:10F45000CDC0F72B25C587EBAB7EFBAADA787BA462 -:10F46000334D267C57E6AFCB085B88DF6F453DD731 -:10F47000B85B4F76DDF1051FFCF236678CDF57CAAB -:10F480003DB7CE8CB3379A77DD28F8013436E06982 -:10F49000A5C093317F5D117EF7F3F87FE5FA9622E0 -:10F4A0001E8FF9EBEB20BABE77F1F5F007D0F7B479 -:10F4B0005FCF7168ECFBD1F641AABFD9E461DE7D74 -:10F4C000168A1B7A719F9BE754A83ECFC9ED6CE565 -:10F4D0000F6BF7BF0DF0F7A7F98D4E789FCFBCA546 -:10F4E000485777C45605E6244E89EC1FB6CBC8EDC5 -:10F4F0004985FBDDB6A5B3A737C5C1998DE3A5D373 -:10F50000FAB43961DC0BEFFFE935C45F53DEB9A90A -:10F510003C9EF63B8A4F590679DCD2E2F131E48B0E -:10F52000E6C13A7657494C1E367BB8BC4E9CD77222 -:10F5300027DF67343B23344E753A5F67AABF77678E -:10F540006B12F9F5763A8366BEBF0D3094E73795B6 -:10F55000CB3CDE22EC129FF09399BCAF308CC730CD -:10F560008FEC190FE521EFA9CE3428BF5D3EC723EC -:10F5700043D9E27DB26B2CCEDBA317F5E3C85FF86D -:10F58000D6AC4AB24F6EF2CAF45D569F42FBF521EB -:10F59000EFCF9D77C1776F66DEB4D3F08D1A50D66A -:10F5A00048C721FC36DA018ABFDC19E75FBDD133D9 -:10F5B0002FED74BCBEF472FD8FFBF17E113718097C -:10F5C0000F2569953311BFD77D99D3E1E367F9FE24 -:10F5D000E36333F763ABED3EB6723D53EB94841DAA -:10F5E000D89F87723E5AFE5AB1260EEC34F4E7E1FA -:10F5F0003AFBADA41D6775978EE2B3ABBA18C5632D -:10F600003FFEFE8B79286F3FDAF762DED238F812C0 -:10F61000FBA9CF5B9D5ABF94EA87748AB8F4528FD6 -:10F6200091FBFB46F143AAEDD976BE1FBB08D21D64 -:10F63000F94EED77B13EC98B76E545662279B67411 -:10F6400050F835BDDE4227EE1FD4FE09E36F41FEC0 -:10F6500001B8A40189F6E7C9251192AFAB4CBED71A -:10F66000C6B8312FC54BF499877494905FBD069C42 -:10F67000B722F67946C5D788F45CDEA3A56396D396 -:10F6800026E2944EA2BBA1C9A2A07EC8E810F2FA5D -:10F690001B3ADABF18B25D16944BD715257562DC9C -:10F6A000DD99943215FDE6B9D9C5D43E50C5F93A75 -:10F6B00090C1C86F95C55A2492B736EEE7CE99CE61 -:10F6C0006C98E7F1A293DB832EE6D92E933DD82FD9 -:10F6D00091BF5FCC5F95EBC82F28E73E964CC42FB7 -:10F6E000D2A044F69DACEB5F8CE38EC63FBD09FC17 -:10F6F000D3FB0FE69F3EF57BC3F8C74F71BAA52E2B -:10F70000D3C8FC23FCAA5FB8FD6871C26F98543F50 -:10F71000B384F3AD15E3D59A2C21792AC98773F107 -:10F72000FED45D6067E27E448D2B8EE958E2E6767A -:10F73000FA5018F7E5C9D79848CF7D47375480F677 -:10F740007C629C11286B47798F3286FC8AAD55BE4E -:10F75000D36971FAFE08DF3734DDE7A5F7B307B9DF -:10F760007E6F2E3490DDD93C200590CE4D3E43D0A7 -:10F770005440719525A4B71F32BB799CC4DD4E71EE -:10F78000926FBB791C25EA470DF73D80FC566F212F -:10F79000BF4362BCE585BFC8FCFBE3197DBFB794DE -:10F7A000C7777AE7B9C9AF911847635DDAF5ABC699 -:10F7B000512E5A0131F0BDA59BCD44876C99E39938 -:10F7C000A59AB87E192E07C85F9B315D1046C43BD1 -:10F7D000A2EB1A240396B345BD1A9FB196F80AD03E -:10F7E000C2BD3DEDB93793D2FF967C86D6EFFCD5EE -:10F7F0007C8680B116F3194C683D8B7A041BF4ADFE -:10F800005AF69ADD18BF89D52B60379A0624F1BDC8 -:10F81000E76F9853087890D4EFAFDFE4B550BC5849 -:10F82000F3BD78F89484F1F530BEC52DDA070ECC1F -:10F830009BA3505C52D47FD68DF91B5BF4DAF108A0 -:10F84000A5A23F16D4EF1DCF9CFB9DCD3931BD0F36 -:10F850007680297D5A4CFF6FFCA0B6E72AF856B295 -:10F86000EDB201F5AAAAC79B9D3CBF2171BD3AD25A -:10F87000F97A05FBD5914E7283DBB5B5223E09F6C8 -:10F88000EC5C5C5ACDEB7C0CE393602F64A4631EAC -:10F89000C3FBE7CE1C45FA2DF898ECF9E64F15EEC0 -:10F8A0007701BB03ED7393E07336A0277DABF2C104 -:10F8B0006A217F7AEDA0EF915F8F48D302C4172DA4 -:10F8C00079B7000DEE4FF7BA697CB1EF4A847746FD -:10F8D0003AF793341757ED28C2F19F9218EAFB4D7F -:10F8E000C52733D02E691EFC3063795CBF55038F6A -:10F8F000121E56EDD78F38FF19E9DCBE6C3AFC3C7E -:10F90000F9073F0E4AB496EB9560F74C28D7D7EB32 -:10F91000D04263E5C125B791BF7F91818D87F9E51D -:10F920000B7DD4BCFF2B8199B83F837F12BCDAE9F1 -:10F930005B417A6FE7229305E30ECDC54BEF263C82 -:10F94000D892BC88874DC55559F89DA6BAB9368A54 -:10F9500013807D85F54DF7DD4E7E1315AE4D03FA10 -:10F960001AB4BB2AC0CEFA11C09DEB985FE381F5B3 -:10F9700037463E587A8F05E3C223CBDF7FC9E0F4D8 -:10F98000EC947C819BCBC94FC8E2FD7EF903DC9EE1 -:10F99000AB4B3768FCC275E9DCCE9C15189A8DBC60 -:10F9A000F7B2124E46BBB799793FC1FD25F359DC3A -:10F9B000FB884E5C8E38DBDCE43F3239C3DFB90AAA -:10F9C000EB6729B47F604AF811FCEE856EA76713D8 -:10F9D00013FC8BE5FB4A822847FF39DDBF18F9ACE1 -:10F9E00042D88F170E5F5F8A7E36D53EEADE630E01 -:10F9F000621CB0DBEAFE6E0DCAC13F283CEE6D8A88 -:10FA00000CCD467AFCD141E3769B83DD48FFC0569E -:10FA10003DD51FB6FA5721DF9CADAB29A2BC1B4BCD -:10FA2000A008E3BC7A670F433B01B60BE44F3039C3 -:10FA30007D0CE3A1B3034B1409E57C82DD315BE46B -:10FA40008F92F084F755428C8D072E3863A225D013 -:10FA5000F9595ACC0E79E34F0B157CA9DA273A13E2 -:10FA60008F67552F4A6232F2FD86C86B3AF45F3BCE -:10FA700087C87E6DEC97E83B8DC5CF513ED81A9173 -:10FA80007714CDFF51C2940FB53E3D59E8F14ECEEB -:10FA9000EF6C88F6CBEC00A7276361CA938AED234D -:10FAA000DAA99D3A9E41F8DD1B85DF053418D53F64 -:10FAB00094AEDA07EBC553CDEBE2DFDD260D7965B9 -:10FAC000C46BA9A4F117ABCFA7D2B97D987A2C3219 -:10FAD00017D76FE4B09AA7C9F330774C9BE441D3B2 -:10FAE00069589EE6C02773916FC0D0A6F5DA34F04E -:10FAF000C5F234BF2FF60DFFEB799A1EC9BB179ED6 -:10FB00003F4AB773BF959AA7E9E1F853E36C89F9C7 -:10FB10009917B2420ACFB70AF7ED43FE1C30521EC6 -:10FB200057EDC0EBEFA17EAC35B17E8C4326DA19E0 -:10FB30006DB6AF0C22DF5F3C7FA6EF418679BA2F0E -:10FB400078285F23C17E48DC27ECC52659A3DB7BE0 -:10FB5000EF46E9C9EDBD68F97FDDDEE3F67C601FA5 -:10FB6000CF0F50E579B3D89F5DACBF94827AE6445D -:10FB7000149E843C86A7441EC3E0C8790C8AC8073B -:10FB8000027B3D407C7290C775DE783A99E4C725C8 -:10FB90009BB217EDA5F3D6C83711598AB0933A8FA7 -:10FBA00018DD282F40DE91FC0E1CD4F3380DC66DF5 -:10FBB000308EF3F24411C711F1A29792C96E6948D1 -:10FBC00071A7627F354EF363A16F1A92787CA62BE2 -:10FBD000D97F397D84B8CD1E617FED81A16C38DE7F -:10FBE0007B4611C7060181FB9D877279DC41C46D9C -:10FBF0002E8AB8CDA9625DC8C0FD10E4A77277292E -:10FC00002C0BEADDEF99836EEECF32E940EF2F53F4 -:10FC1000E3362F733FD532119F39B5602EE5072D9E -:10FC2000C7FC7719FD18DCCF1CCDC767361DCE6722 -:10FC30000D888B9D28620280F56BE0B5A493D09E61 -:10FC4000707742998C656F4F0D7C7769A78EF6238C -:10FC5000CBBAB4FEF22B9BEEAE41FDBDB193C71FF4 -:10FC6000035D12E9EF65CCEB427B43E587828C3480 -:10FC7000A273A053E7C5EFCCC8E0FE04407D90E638 -:10FC8000279E9D7AE1671770B4335D089F3A893FDC -:10FC900037DA949A11F5B218AF53DF62AA443B36B3 -:10FCA00057477EDE2B06EF22F2933A8A886E9DD666 -:10FCB00096AE1A5E4F6BE58A39E2A3FA6B156EE8D1 -:10FCC00031B703E564668688DF24CC77798FB69CEC -:10FCD000187F5815D4969731FF842C3C87B05FFB72 -:10FCE0003E3383CBA92B9B0A849FDF437EFE4EBD10 -:10FCF000FBDD029453DD0AC9C9F61C8E2F5D2E7FF1 -:10FD00008EB5572F22FBC00E7605C1CBE11F7BAD10 -:10FD100053427DD969E77CF93F853B11DECA8C22CD -:10FD20006E27A07187EBA85B0A727C71B8BFA8BF71 -:10FD3000626986F01708F9132DFFEFEF37393F7628 -:10FD4000CB62BDD948FE2C15F1C65392E7E910BE2F -:10FD5000B7805D00702FEB96CBD03E99FD150BCD93 -:10FD6000A3E96573D008F58DEBC279B88E9AAAC263 -:10FD7000452D23E015A15554B905ED963A617F80D4 -:10FD8000EBB64B1B871A1E57F47E2B231DF721A7BA -:10FD90000EBE8EF43E6826BD04FF75D488FE8EC369 -:10FDA00005642F4D4DF5B765A03E4F0AF57DAF00B8 -:10FDB000ED136E1F350E1AF7A0FDB7B4537B6E8698 -:10FDC0006DD6C6B9589783FC19AC57FB1ECFA768F0 -:10FDD000FA0D8B7B713DBFCDE09F8876DD755FE6C8 -:10FDE000F1F5F3AB740CE9BB4CF6AC403972DEAC08 -:10FDF000B5BBCF5B39BDFAA274F614219DFB46A5B5 -:10FE0000B3A708E9BC4CC7FCF1E334229DAFC6ECB4 -:10FE1000734EE7F3CF5F5384743E77F09A22A4F3D6 -:10FE2000367D8F17D7CD930EFF5EC4CFE9393EB232 -:10FE30009BD4BCC92FCA8F8732B4FA305AFE3BF923 -:10FE40003F46D383A1281C5A3DE834B873501E2E78 -:10FE50003519FFAA3EC4BF11FD692623F9235EFEB2 -:10FE6000D3E58751BF050665B23FD4F15E56FCE38A -:10FE7000D05FF0F27B2E4F401A7DFC066157B94CE3 -:10FE80002C807E0FD5DE57EDC64479FC0B319FD315 -:10FE900019DE1AB4B355FF6CBD18D314BCCCEDD326 -:10FEA000A724F2BF9ADCFD3C7FFEC8121BFA67CF85 -:10FEB00006B93FB6E9F952F2D7AE0ABE12C2FC2724 -:10FEC0003628D970DFB0EAA90F53309E0DFBD0530E -:10FED0001971F19539621F7A36782A05E3DEF0FD53 -:10FEE0006AFC7EB2336240FE6D82FD1934614D4A78 -:10FEF00084CE0D353919E9FBF201ED7E4D8D4FEEC3 -:10FF0000F41948DEED1C9482B83FCB30F80B7250E8 -:10FF10003FB11CDB99E4D87AF924C36BCB9C161F44 -:10FF200017F65ECE88CB570AEF48253E0CEB999723 -:10FF3000EC801D56219778BCE63F77D9833C7F89BA -:10FF4000B7FFCF600195557DBD429CC35B21CEE1DB -:10FF5000A1FC0E25C8EFF87234DEAC9E3703791E83 -:10FF60001A29FE1D97B714DFBF8945447EDE674618 -:10FF7000CDB8D17C9D965237C0BDE66B163A67D896 -:10FF80000C7CDD5A16E3C3063115950F9B845FB7D1 -:10FF9000B9FE24ED039AF17C05DA551ECE870DB02B -:10FFA0003FC2FCCDC475CBFAB5F98CA3ADE329995A -:10FFB0005ABD122DFF83FC98D333B5EB579DBFEA92 -:10FFC000078FCE7350E2EB2B615E89FBCA44FFB50D -:10FFD000BA2FFCA272EDE64CAD5C8B96FFC172EDC0 -:10FFE0008ECCD1E49A363EF037CBB5C4384121F7F8 -:10FFF0007F639C00E3B6FFD338C147EE9E0C1DCF54 -:020000022000DC -:10000000C3D7C44FBBA4969B4CE330AEC8E3CB8DA3 -:100010005623C56113E3AACDEEB9228E38F4CB196D -:10002000A8370FE919EAF37ACB4A8A5736CB070C7F -:1000300078A470583C51394A76FBDF1A575F9F19F4 -:100040008DAB17605CFD15CBE5347F1C3DAB4AC022 -:10005000C02F193DDF68B3A053B2C88B30290166A9 -:100060008FEB3F5ABFDE4C6E27BF22F2635C069EC9 -:10007000C7BEC50AFB3098BF4BC7F377EE4FF76D8D -:1000800043F9687273FC3E71F8AB0CCF1D3DA1EFD4 -:1000900027391268B478501EAA7E17757C45F80F70 -:1000A000BE28DFFF2081EF7FF077E6FB447C0CA8C1 -:1000B00072E76F8D876D07DC68D607A3B8D75B182A -:1000C000CF2918CEC7A38D331A3FFF34D3F75A2652 -:1000D000C947EF54CACBFD82F226B93C720AFD3BF8 -:1000E000EC90D18DFB0D933897C13667893C4A4F10 -:1000F000451DE513F3730DEAF98FD1ECC20FA3721E -:100100009ADB851F8E2AA7FF7B76E1030EDF299CF1 -:10011000E7E94A6F11EACD8D56801FF77BDF378EF6 -:1001200078CE423D0F00FCC4CF9B3CCBE3E0897C02 -:10013000F58704FDF287BFB37E194D9EEA5D2A1C48 -:100140007F67795AFFC714F47B8E3E4E80E0A8A8E3 -:100150001AF28AB815C3B8913A8FE6219E7F96218C -:10016000F2AAD4F7116117DEE9F266BAA0FFB9F777 -:100170004D26960A2610F218DA633E0BC5039AFA4A -:10018000799E48D33A46715FF51C65D3401D43BB49 -:10019000AF3FCD5F8079601B3FB004E454F4932FF0 -:1001A0006068EF5D789F971BD2FCE3294F6C5D5828 -:1001B0001377A8F8ECF206F46700BCE41F708AFC21 -:1001C0004C15BE3A179767EAF32681EFE8BC9C1CF2 -:1001D0004ED62F07D14E4C760F911FA9E91037DE6E -:1001E0002A642FF9EBD91A079D9F683A54594AE7B8 -:1001F000CDFBCDA568E756FCAAD686FE8973D73A13 -:1002000029CF204F0EAF423BEB9FD3FDB3105E6B67 -:1002100079701EDAA9F960A7A2DD7BEEE0BC527FFF -:100220009CBF7B1BFABB61DC6D56AD3F9B99789EF2 -:1002300078FD5E9E077CD8EA9F8BF8DD66E6F006C7 -:10024000B68ABC67E1E74E5CFFEABA8F9E73BCC317 -:10025000447169552E6CD3333FEA3D559E94883CDA -:1002600039C007CFD31BACE3F91EA26C716AF3153A -:100270004F67CC2941784AD0D13B0DEF518848E8EF -:10028000775F2EE2F0D78B7C0A357FCAA8F8BE8E46 -:10029000EDD9BA9A58FC7D2CF617F177912793FC8B -:1002A00029B79FC7DA0CC43756585FE41F01BE4117 -:1002B000FACC8A0CCDC6F34485BDA15988CF973FAF -:1002C000D5113E94BAB7287E928A648371C66D0EAA -:1002D000774F403F8AED17D7225DDC3DB62A445D5B -:1002E0007F9AAF91E0505A8A715F59F5AF7A9E07B5 -:1002F000782499FC03BD790D940778E103E388E73E -:1003000046D46780ADA7BCBFB1033F273FBEF59081 -:1003100034623E6797CBC2CF0D078628BF8CCD7263 -:10032000123E9423BFA2B8AFD2AD9007A353EFD52E -:10033000E139A8403B23FFE5F85E9B0EE9922FF2DE -:100340004B2EBEFC5F53FDB44F51FDF6419E0FA4F2 -:100350000F6FC07D97D21EFE32AC60D678C8AE6BF0 -:100360002AC1F1224D3CAF3D99219FE40F8C5BFFE8 -:100370002528E777D99884F2E7A535F9E42F857920 -:100380008E1F619E77BB78FE8E722459877A4BD977 -:10039000CA28FF50B1675411DC8F4219C65923F89F -:1003A000468D4702B82ED44777BAFCBB11CFD17324 -:1003B00032AD49FC9C8C3877696DFDE0593C7FD2A9 -:1003C00067E0E70C8FBD3C7901F9EDBA1509E970DA -:1003D000C5BE24DF06EFF78B756B558698CD128F5F -:1003E000FF63946F39F608CF4B53F49C4F946EE73C -:1003F0001EF40B7E9AEAA7BCD26B3B4332C5B36CAA -:10040000A71FA971C7ED6BB6733DD2B49FEFA713B9 -:10041000F7319FA73F8EBAB47649B4FC0FB24BDEDA -:100420004AD01B7FF3FE8469F77589F649E23E6E78 -:1004300098DD9D30DE68768A9AD75115FB0EF1C3A0 -:100440002B56D50E0A68F25EAA2CE2DC9B493BFED5 -:1004500053224F47CD83C9E870B7635E79E4DB8CE4 -:10046000FC6C6A3E4EA08AEF1B023A139D8773B163 -:100470001ECAC319C3429244F67F98CE7566623E87 -:100480000EF47BDF3596E0DECD3C5D32C943B784A8 -:10049000709B318F83F236833B56E0776EB1D07715 -:1004A000CC98C7713586E2BD3B507ECEAEE77188F1 -:1004B0006CD0B7C8B7D9859C0FCD8B783E879AAFE3 -:1004C000A1E657A878A812F8CD9EB0A200F707DDE4 -:1004D00092FFFBEA79DAF873D2D1F3D1ABC6D279C5 -:1004E00093E8F9B94226EABFD839E9447CAAF91D54 -:1004F0005536BF2D2B7DF87959953FE2E84670EDD2 -:100500003CC2EDF5AA7A03C17F71D57CF2235E5C13 -:10051000A563B86EAA068D9CDF12BEB7337A0F466C -:10052000D04CF75D08BA7F9EBD0AF42C463FEDB172 -:10053000B69AAB4F036E8FB7F9E879D12CF5CB574C -:10054000D179C6C528992E67EDACC57B0A2E5A23F2 -:100550007978CFC1E5EC076FA4727AE404965376FC -:100560001EBA11EF3DB8383ED287F71E14EEACE448 -:10057000F5C883D98C5D9555716380E6CDFD4EB38A -:1005800063E7B3CB113F8D2CBC6188FC3B3C7F1FE4 -:10059000F3FD900E2E8B81EC1997C8B364D522EF32 -:1005A00012233050EEC82AA578B585B90F0D617DAC -:1005B0000E3F2704F5C4BF1DE3B95FD824E8CA7213 -:1005C000543F523880F2A9A3C04EFDA372F490317B -:1005D000C8FD59FCFBEF3C3F85E24B6AFE2863B641 -:1005E000DC855328DF445356EF37608A2D17ED859D -:1005F0000EBDB04B45392DD55F97156717BD33E755 -:100600005B25B80ECEBFF04021CAA5EB0D60B78FB9 -:1006100020877E9DCDE5D045BDA54B023BEDE7296A -:10062000FEDB719CF79217CFB5C3BC16A5551AEC2B -:10063000086FE0FB32CAC574416FFB420E9FBDDA02 -:10064000272D87713BCCB07EA17FBA5FF1529EBD52 -:100650007FA1740BC0DD2171790B9D52695F52EC53 -:100660004EC5FCE506715E5216EB7E46FF5619ED4F -:10067000E977DB06662A8531F87E2EE2CB3F2F60D4 -:1006800077D68DB0DF6DCDE2727B81EC9E827CB43B -:10069000411A78AB360BDFBBE9FD9C94D672CC3B9C -:1006A000BE3EB9A51CF5CFB0F7A9F0BE24AE6CE4F0 -:1006B000ED1A4C913C3C9FEC4DF6AFCBC2B8D092BA -:1006C0000F296EF9CDEC774E60DEC13BFA9ED92939 -:1006D000A85F0AC4B97EE1377C6D82EA3734F1F253 -:1006E00064EE378CE6734DE1F964B50BF939C55A00 -:1006F00091AF30D7C6CFF5CC2D2FF074008837B12D -:100700008882726FEE7BBE14DCB7B385FE72DF9415 -:10071000D1ED19E6D2BBE3D7EB3C775C19FEDD5097 -:10072000AC2DDFE8D1966F9EFEE709F1E53DC9DE0D -:100730001D38EF1F4B3CFF313083D9689E4E298016 -:1007400076C7E417B3C5F94E9EA7F74F625FF4E290 -:100750007446F519FB4D7B31FF5DF533CBA27EB2BC -:100760008B99F21DFCBE00D4571149E4FB39299640 -:10077000C25EB8DBC6F1076D0D30CE0B4BDCB43E6C -:10078000322C3AF6655C43E526B2432AC69892902D -:100790006F8E09BE53CFEBAA7C58A1301FE62FC045 -:1007A000A717E2F31DBDED28FA97031F31C6E955DF -:1007B000A950FEA1F81663ED547E4CF0F7310153B9 -:1007C000E0DB0AADE757AD06A2A7FC13790FEA09F3 -:1007D0008CCDA0DFF8D2E649049FBA7E6055173A67 -:1007E00033C8A52DC655740844B1B02754FE460B36 -:1007F00008DB8DC1FF2C203E27791399C6EF4FF8F7 -:100800007901972791AD0E711E8CC7CB724DD171B6 -:10081000BD386E56F43BFCBC51862843554807F35F -:10082000FE4D560197CB83AFFF81F4B2C5E3C7EF0E -:1008300018524C744E465D37B6CEDFBE553B03E7CB -:1008400059F40D9AE77CAB0DE7590C6CBDC8414FCC -:100850006F1A8DC7D78F9CE471E33AF94ACDE199BD -:100860004A1CDF40FF46DE3F59DBDF05FD1D71FD01 -:1008700053A07FC9F0FE4F594D21DD541CA7C21D66 -:1008800026791EA2C9CC17F3923378BFF9221FB480 -:100890003005DAA3BE29D6E66BB0E91E13BFAF431D -:1008A0009B9F71BDB42E0BD7D53C53E36018C67B1C -:1008B0005DD0ED7A9DFF77783FDDEB8B8B8EE37A11 -:1008C000AB310515DC0FDDC0421B9098172BFD4F97 -:1008D000D8C7913CF80BAE8B26D93FC101E5F3FA9E -:1008E0009EC2BB0B68BD7C96356D38BC2A5FA8F0F4 -:1008F000227F209F45F92301EE289D6EEAA744B68A -:10090000DD60F7E053B583186BE1F9C6EEDCD8BCC7 -:100910008089E69A5A0AD10E79BD3D4072E37AFB8E -:100920002394D7F4E7317E6736C0B5E8AA4FE85E76 -:1009300013E65A3201ED7B80373D3BFDFF1DBCAA1B -:10094000BD372CDFF6238326DF76B475A57EB799F5 -:10095000F1FB69660FEEA1FCD9E685160F9E836850 -:10096000C6FCCF728A2F911D87E784E99E13C924A4 -:10097000ECAE2F9A97CBD7616FA39BECB7A81C174F -:1009800079E5BDA51CEEDEBBDDEA3D27DCBE5BC222 -:10099000F83D29EA3D27CB6D54AFE69FF7EEE17EA7 -:1009A000BCDEE727D07929B0DFC85E60A93A0E5FC8 -:1009B00081F67E15FC933262F9D2DBF4DCDEDCA931 -:1009C000F354209E77621CE8AFC47FBF9AADF59BBD -:1009D000A8E544BFDE930EFFEDC817CB4BBC7912E0 -:1009E000F0CF3203F7DB017FEDC2B31535ACE5295B -:1009F000BC3F701E6BF9856E1CF1979FF86BF22758 -:100A0000FC5EC1187F2DE1FC1520A1A4F25794AF24 -:100A10008A13F3ABFCABB17DAFBDFF574D68A70E9A -:100A20001A892E6A9E5CE23A8E83E7B49EC3E394F1 -:100A3000658267ED48F07C113E8FE7AF4CC6F979CF -:100A4000347ECF5458C05A16E3F73DC9FE76843F32 -:100A5000CAF71BF87E6418DCB285F8E3D6DB649E27 -:100A60003F9ECCF515C62BB2E0FB75E2FBB7767363 -:100A70003EBAD56A20BEAB1B6CA47C2256CDE30ED9 -:100A80001EF81FDF077A09BF8B44BF85CE523DB2E7 -:100A9000ECC25A6D7C6291458D7FF8F4B81E6F5D93 -:100AA000A83F19AFEF17B1CD9F60DEDB228C63A8A2 -:100AB000FDE0BB8F6747E31813308E715CECD32FDA -:100AC000027F23FFBF9ABE72D7DDC0B7131E2F2946 -:100AD000437FCE9C8C554F6D85F2F7764EA2F2ABDC -:100AE0001977DCFB0ED6F71551B91A2F71C1FD46E7 -:100AF00023EF5F5C71DBFC02F8EE71B31817D715BA -:100B0000EEFB92FCBD75D0CE35756C19E623560B05 -:100B1000F970F16E9E0F7FC355569EE2B9D24D7E9D -:100B2000A3EA2451FF753EEE5BA5FF568679A9D551 -:100B300063238BE93EC6B21F4FC2F271E993C5230E -:100B4000C54D26174BA189809F6A076F5F5BF6FD35 -:100B50006CDCC75757F1F2644F65F738ACD75D5A74 -:100B60003CD2B9D09F8AF5143DF724D6E98BDE0F2D -:100B7000E99C93CF2479708ABEE91FF27B892C927D -:100B80000DFD8F3E6F81827ED2D95E9EB758656A19 -:100B9000CFC2FDEF4D7E4339E69FDA4CA5C7D1CEDB -:100BA000489D5E390DE93BDBC4F4A89780CFFF85F3 -:100BB000F8FC9A4FF25290B92C5A3E57F9A84EE5DC -:100BC000EF6A2D1FC3FAFCD7ECF4CF97AFA3F13136 -:100BD0007CFFDFB1FFA22F69F54A74BC84F596381B -:100BE000FE687200FFE2E55C0C8E7E5A573998155C -:100BF000360ED75D8FBAEE220887413744E73EF2C2 -:100C000025CF243AF0388AFE57E1CB05D9C6CA86EB -:100C1000C3857F8A6A9771086CB60CFC2EAF877EFD -:100C20005EE688C105DF676350EF6FE0F0EC965A2F -:100C3000B8DC1076B1BA3F6E52E73BA09D6F45120B -:100C40003FEFEC42FF05F673964EFA6B70370BBD23 -:100C5000B9D0E47BC80873B8C5BE8CF8E1AB2CF002 -:100C60003CDA27C654BF634C3AEEBB0247C205E4E8 -:100C7000CFA5BC01A077DA9838FB44852B111F4D16 -:100C8000A3C8C344B813F110A3CF10D957EAF9A9E8 -:100C9000E8BC12E6D361E5EB3532CDA8DE5F528CBD -:100CA000EBE26D699227DE9E7E3B416F27C2A5DA9B -:100CB00011AA5E55E1417F11FF7EA41DCF90DD3862 -:100CC000662CD99D2ADF640AB80C3A69C438EA8DCB -:100CD0006374AA7F4E43C7C4734E2ABED4BCA044DB -:100CE0003CA9793DC3E23509F1C8D1DA49603F8FAB -:100CF000710CC79F1AEF7144FD5C029FA512C93F9A -:100D000087F073CDF6F0F309B5ADFC9C7C6D0D4C0E -:100D10000070FFB6F01FA8787EC8EEBF8DF347784D -:100D20001AEED3BF3BEF698A73A8F7C825E267F9CB -:100D300028F8198DCF47833F2DD5B712BF7B5E1A98 -:100D4000AAC0CA2DE9E2FE41E62FC07560B715546E -:100D5000A21F02E4EA679FE1660EAB80AEE50E7F5C -:100D600033F2F957996F0ED2D751E3D773FF3A2375 -:100D7000FFED5AB1DF9A23F4EDA55D32C507AABD98 -:100D8000131F9B8576E21B7A16A4F5EE25FDB94666 -:100D9000C07F099FD8DEC2F5EECA377F54012B868B -:100DA0004DD8AE8BDDAF00FF26069334F72B4CDE1B -:100DB000EFD094A7F4676BDA5F353056535F1A9A19 -:100DC000A4A9BFFA8D324D79DAD04C4DFB6BDEAB66 -:100DD000D2946784E76BDA7FE9EC024DF9DAC8ED6B -:100DE0009AF6A7C4BE9805BC43C51978BF389FEFD3 -:100DF000759F2ED5F4FB6DCADC37900FEFDACCF37C -:100E0000972B01339A7B267AB85DD102FFE374F504 -:100E10002988AF15606F63DEF2CAED5ABBA37E70FE -:100E2000EB0694A5897915AB594B155E49979857F0 -:100E3000516D5BA243BEFBA731C2EEB8865D23EEC7 -:100E400085F9AB742D62E3FF5B7435BAB47435BBBE -:100E5000B5744D2ED6D2D5EAD1D23575BA96AE76C6 -:100E6000AF96AE69355ABAA6FBB474CD5CA4A56B37 -:100E7000965F4BD731F55ABAE6B668E99ADFAAA56C -:100E80005F4160B5965E09F456E5E5B8AEB59A7671 -:100E900051BAFBEA291F667CCFFD9A7155BA07E06B -:100EA0007F9CEE2D94AFFEB7D29DB120F95F13E980 -:100EB0007E3681DEA0AF3E42B90076C6397C2E9ADE -:100EC00020EC79DFC876862A7FE2F57AFCBE75349D -:100ED000B9344C8F897DECA87A2C611FFB3E66F1FA -:100EE000907DB499FC3CB709FEBC8CAF66A01FF5A1 -:100EF00007A49FDF0740A6035CEF23DCF09DF79378 -:100F000026939FE10E16D2D3BDBF98890883DE8950 -:100F100089C932DEE7E3A6E732A1BF970B3F8437EA -:100F2000D99F92C3FD0FF919F8DD9C217EFFF25B7A -:100F3000695FE89E8293E887079D721AFDF0F0BC16 -:100F400060E6FC7046950F5EE676C6E16DE96C8959 -:100F5000F4323A7C703FBBF4AB12C51996FE9E3F4B -:100F6000C7E770BB37F1D9D1AAE28DEF876EC871A0 -:100F700093FECD61FDC27E637ECB381A87FBCD9F89 -:100F8000E4F78F3E2B3165BA838E49111D334D1C1A -:100F9000AE67F5CC84F87B86F9DD8897EF28209A38 -:100FA000789EFE24E487A5BF7F672CFAB164D975CB -:100FB00013DE2F3D1DBF0770CCF95A8B847EDD4CAC -:100FC000578B847EA361EF0FDD2FE1F9C26899F1A1 -:100FD00076F8877850FD73C53A1EA78EDCCDF717DB -:100FE0004F7D9D91DFA9A3355019C0F8940C0607D9 -:100FF000E6B1E8F979E41B72B8DF2D8B0DD1BDA6FF -:10100000EC3561178AFBE04B44DEFB0511E759B173 -:10101000C7C4304FA2E4E05107C67556002D875073 -:101020009F297EBA5FA364C7AB0E7ECFB8DE8EE782 -:10103000D8543D3A3ABD1576262E7F1CE8D8329218 -:101040001E5F93CBE3B31D6D35B3302EA3C2F360A7 -:101050009B7716F287AC7818C693F0DE9DF8FC33C8 -:101060008313EAE3D6AF62A9D194F5161F5D66B18A -:10107000A1AD85F84C2FEE07DA98B3D616FFBB0169 -:10108000AB7374E21EF200433B9B8B7A7C2A675061 -:101090003EFC91F17DA8D105E3C4CBB57BF358BCF0 -:1010A0005FB9ABCD47F06E90FC7E1CC458C842E6D9 -:1010B00014CC5BC0B397F07EC7F56F601E8DC1BACC -:1010C000D613728F8E37A34BB9122F971EC801B952 -:1010D000941C934BDF6D3B4B78EA685B44DF037CE9 -:1010E000318C9F05B2B87DDAD1B684DEEBC0CE423A -:1010F0007E7A65C784A36EA83F01FFF09E1CA39370 -:10110000C3C5CAF3483F2D167C803EAB5CE09F13FD -:10111000AD7AE2B37B722D415C84F7BC3DFE28DEE4 -:10112000F369005E92FF06B8A3DF11783208B904B4 -:10113000FCE4C3F566C856C8FFEBB02D203AFD7736 -:10114000C753F16B3033BA87C6906B21BFCD17857B -:10115000F37B39097ABE3C8FE4E83D022FAFECE027 -:10116000794727EE6564BFDE731FF7BFDDD3C8285C -:10117000FF9BB5C25F458C6F54799D8E3781C0CB84 -:101180009E361034458C3DDC66C293572C19FD64A5 -:10119000E36274ECF12A7674C76FAD76D6E1F3E1C1 -:1011A000E9A77B50AC6C99F5BB217CA28F1BBF6F6C -:1011B0006B6141B43329160BDFB7D74319BE9F22A9 -:1011C000EA53FCBC9C2AEA5317F172AEF739A91A0C -:1011D000014B8883E45A1CF30A51EEDDC5F8B95B74 -:1011E00071EE7EB790BB632C8EBA6AACFF1AA37CFB -:1011F0007CB5FE71519F6539D9350EE5F2426DFF20 -:101200001D020F9996933DB3295EA2AD57E31BE9EA -:10121000964B6F50FF126DFDA3A2BFD57269683661 -:10122000D6176ABFFF90A84FB67079C87CFCFE54F1 -:10123000B5FE3BA2DE8CF5F87D8FB6BE5B7CBF436E -:101240000A127DE88E585C3FE9DC5FDAD7C6AEC58E -:10125000F5D3D316A175F470DBA7442709992C3D6B -:10126000B6AE6CAD6CC4F3E092906729EEB0D73B9C -:1012700082BC53EB1D367EDE5D7619888F8C16217D -:101280002FC43A8CCA0BA9C5C3998BFBB13F8F9F62 -:1012900061815D41FB220FFE909F73EED5317F9CF3 -:1012A000DCCA6E4862FEB8F6AEBB1C9A72C6D7B2F4 -:1012B00035ED9D0BC76AEA2DE59334F5CC9B4BEBDE -:1012C00065ADE0ABA492324DBD7A0E9FF5E46AECB9 -:1012D000677DE14C4DBB4BC56EFAFD9033F3D4DF17 -:1012E00019F198502EACB58ECD44BDF34CDB74345F -:1012F000B2D9B3B09EF0E8D4013BCF2F3E807159F4 -:10130000B4D7DBBCF47E1FD483E5C29E84F5E686A9 -:10131000F67BDA6C547EA2CD45CFDD6D6E7A3EDE73 -:10132000564CF53BDA3C547E0CC6C7E7A3300EBEE4 -:101330007FA4AD86CA5BDB7C54DED2B688CA0FB50B -:10134000F9E9F99DB67A7ADFDDD642E58D6DADF427 -:101350007CB02D40CF8EB62EAABF46D0FB8038C7BA -:1013600078A0929F4B4EA4E3AC5C49732F983596BE -:101370003F302B17F307FAC39AFBDD71DE349E99D9 -:10138000CF3F71BC3A1C0FBE3B890DB527F3754C9E -:1013900071C7F1039EF5C9C0EF635A381D0A0622D2 -:1013A000549F55CF695127E065CE00CBA9E0C750C7 -:1013B000B1DD0569A82A99C76129BF8CB9609E155E -:1013C000E27E1C62BBA00EE152A673BDA9D2353AE3 -:1013D0006F3B8713E73F12BC5F13F397CBFBF9FD1D -:1013E00017353D2164FB246F0BDD7F615AE40BE16F -:1013F000EF57387D7E3A8F3FE9D3B9B0B90139F361 -:10140000E997991B9E390DDA7D4FF65D659AFD854A -:10141000FCE9C3CC7D358C5BA2DD9F2415AED5F4F1 -:1014200033E5DCAFA93738D76BEA97AE29D8E0426D -:101430007C8E61149F316E6E6718525CDEBB95E046 -:10144000DA24F07E4172D379DEC041353ECFEDF330 -:10145000EF09BDC24C9B693D4CB0F362516A4087B5 -:101460007AE1DC8F52491E3DFD842E88FED7892CFF -:10147000A8C3F53F19CC3DAC9F8237E8CA74A58A52 -:101480008CE552E696B17C358BD0FE04ECF3F5B9D1 -:10149000DC3E7FC28CF1C15CFFF778DE5288F466D7 -:1014A00091A06791BA1FD9AE24FA65BB72890FB5B6 -:1014B000E7993A859DDE6EAFC8C4B8E88551F2CA97 -:1014C000ACAE9933F177B4AC59D3E9A9BE7FC8ADBE -:1014D0001BF19CEEE3025F2ADF4F0426177CFF38E6 -:1014E000CEE37CF9BB19B8DD6B2A8C10FF5F90BC92 -:1014F000AE2588D73765CE878359342F45E05539D7 -:1015000058E95A02F853DE1EE709B0D8779E6EF309 -:10151000CE549458B948E445EE6FAB9B591DF7FE85 -:1015200075014F311BAA41FD545CA2F30469649715 -:10153000467E990B7BBC78CE5C29631E146F1359D1 -:10154000CF7AD4D5CA5F64CA73518ECD606ED81776 -:10155000582C21867941AF47E7C934BFAFF43B5BD4 -:10156000752ADD17981D957BA813F1F79486907F57 -:101570007ED7ABE7F33AA6AD2FB6F0FC9D15C58636 -:10158000A05BC2B07A0FDD8BA7F4490C4D7FE52F2D -:10159000B3090FEC8564E2BFE4ED53E94AED9B1417 -:1015A000FF0F91BEE743EE1774E3042F42BBC6C999 -:1015B00086BD688F4D40BCE0840A8B09AFCBC57CEB -:1015C000F7B72D213CFD5ACCA33337011EE6F1E2DB -:1015D000BD912B7A55FF87769E0F9557DD8CF7ECE2 -:1015E000750CC9C256D2E273937E682AFE36DDF9C5 -:1015F00030C025139CBF46FACBDB2BE8F795408122 -:10160000D0FC1A9F80FD7E01C9A31AD2DBD374944B -:101610009F9AC857A7841C6BC9E5797F56D79767EF -:10162000E2EFBCC5CAB3883F9FD1B162CA2FD1F1E6 -:10163000FDA59ABF0186831BF775A579BAE83D1A07 -:10164000F3515FDB7594F727EF49A2F389B25DA1EF -:101650003CE34E4BB56D358E635328AE32579E3505 -:101660008476B3D1AEBB1AEDEEE37BEF1FC2FC1262 -:10167000395761E82FEAB429DCEEC8D1513E9662B1 -:10168000AF36611CA6C872BA12F17974CF37C9BFE0 -:10169000217F43E488087F925E90AC93B5D0F881B7 -:1016A0001C45DCE7E1AD2DCD10210437EE7F6A3E0D -:1016B000423FCA71DB2533DA2B6ECB0AF2A715E65F -:1016C00015D07CF4186F83F213EB2ED9516EBDB98F -:1016D0006783A300EDE7A0423648F19F3BB2E9DC07 -:1016E000F91E039D8B57F19A1F503471BBDC566D68 -:1016F000D99810BFD3279C4BCACA2B107A6E110BF6 -:10170000C5CD47EFE2FB35E6B4D07EA7304F629FF0 -:10171000E962E531A2BC5F1FC8F6007E8EED5991EB -:101720008FF3BA72D84F79BEA3D9FB1FE7BAD5DFC2 -:101730004332EBE87ED59019F37E9F6A63E968DF58 -:1017400099820AE55DEF13F2ACD0C2F9DF90CFF9D0 -:101750003CF159D8C3D79D722029988C74B3F59762 -:1017600005804F26BF328FB941FF15DABCE43F2C0C -:101770006C35A463FEC0DC1F5A884F2E5992C84FA7 -:10178000A8B42679F07DC7DE8A62771CDCC1365B9F -:101790003AE6E5EC6D33A5A39C0A8E225FC7D975A6 -:1017A00094AFECD6F17CBAF9791CAEF979FCBE970E -:1017B00079A2FCA4125880703E09F4C43CE9A39BB2 -:1017C000B93DBCB6DD4470AC7D731CD955A3E1EDC9 -:1017D000E936573ADE0FBF77B32E1BFD4795DD85FF -:1017E0009BF09E84B5567E4FAC9C3AE9314C4567E0 -:1017F0003FD533B4DF3B52667A96C5C97739755603 -:1018000031F2952C07B2D12F7267DEFC9B315F124B -:10181000E8B713CB2BFB4A79D91AC8C6FCCAE6BE77 -:1018200069BC9C1ED889F995DFEA9BC1CBB9816C54 -:10183000FC1DA9B6BE6B79797C60279637F655F208 -:1018400032FA9E40766EE99B7333CAD90E83A71E87 -:1018500005F20F00FE1280BF5F3CB70ABCA8F5CFAF -:10186000E17BC0F321F14CAC7F41F41B18A5FE25B0 -:10187000513F38CAF82F8B7EA151FA1F13FD8E8F6E -:10188000D2FF35D1EF8D51EA7F22EADF1A65FC9F46 -:10189000897E43A3F47F57F4FBC528FD7F29FABD59 -:1018A000374AFD07A2FED709E39F10EDC3E2FD58BA -:1018B000EBE60F42C07763418EA05C2AB66E76E0FD -:1018C0003ADFDB554EFCDF51C1E33B2ABF8FC5DF5A -:1018D0006F827A5D3EBF4F4A97CFE33CCF88F1815C -:1018E0000FB720DFAD7D5BA63C9B0E9DE76C10E53E -:1018F000E8261DD9036BDFE4FBF3B5DD4A30FEFCBF -:10190000C53309F06F10F0750A789FCCE3F139A365 -:10191000CB955E1BEF47B269CB9896857217E4377B -:10192000E5ED167757751597638C4C471688D26886 -:101930000AE17D0D8A55E8055B794F31C26751E8B0 -:101940009CBA625742FBB1BFAB9CEC3B15BE4E8BC1 -:1019500042F775C956AE07E6FE70960DEDAC4EE641 -:101960001FF2627F9742F6FBD1AE321BCA3D83F570 -:101970002E1BAEDF76379F5775537112CA6BF92154 -:101980001DC9EFE336BEDEFB5C3AF25B805EA1F37D -:101990002C20AF3DA82326B0503B9D8F78F885259D -:1019A000DCAFC7ACA515745E448D434B4A9CFD7FEC -:1019B00059E0275FE81105F50B3C9F2C17E71C0247 -:1019C000DCFF0464738D893BAF79394FE6E740D47F -:1019D00038A25C4BF716E5AD5334FEF79C7BB5653A -:1019E0004382DE5012F4CAB82E9093717AA7206019 -:1019F000D3944FE609BF8E8779D07E9DFBC3CD245B -:101A00000F2FA17E9346977B51F92BE4F193E21EB1 -:101A10009E2703FC1CF1D1CD653F417AAFEDD6D1B5 -:101A2000BDD35F548E3E93C7B87FDA0F7A07ED19A6 -:101A30008565E37EE9F3F0305EEF73D0BD0A9F83E6 -:101A40008FF18F963B50DE8EF72BA47786E98DCFF2 -:101A5000C1D7B392E73D3FD2D19EC4ED6A1B9F77B9 -:101A6000678693DF4724CE1FCAC25E7B50F8C195BC -:101A7000D4B96EFC89904E7B0B9537489ECC1BA049 -:101A8000FD46C96FC3F21B8E24AE777293880FF7A1 -:101A9000A32D43F71C16F8D03FD21F34A8F71486A5 -:101AA000F0FF0E627E8E7A0FA28BEC33710F63EF24 -:101AB000CDD5D85EB14D469373DA138F6DD1830DBA -:101AC0007AD0C0A2EDF13CD533C775E29EC4DD5B90 -:101AD000D05E3D98C434F7401E443F3A8D17DC82F7 -:101AE000F73EC2F76E90610F767DFEF7B658B26290 -:101AF000F054B90F6C69A73C59BE2FB1337E4FF734 -:101B000079773805970BEC4FAECAC77DF99ED3198C -:101B10009ADF5D13ED5345FBA6C148D30137B59F4E -:101B2000960FEBA07120925242EB2B5211DF3E45F3 -:101B3000ECF7E3DA7F89C61FA57DB10ACF81776F05 -:101B40002DE1ED2B71FC0BEE7006E5BC24C0933645 -:101B50007CFCEBFF1A3C9344FBF3A177A9FD05162F -:101B6000CE985240FD6EC27E17DF7AB742CC3B035F -:101B7000ED64908A37E37B34B7F8EFB1B490FDDCC5 -:101B80006FEAB1A1BD66D6F7F850EE16E2BD4ED3AE -:101B900063CF05F985DCAE4A78DF6F6269B5C88F1F -:101BA000AD3ADABFF49B86CA4AD09E7ED102320F8C -:101BB000F5C23A0FCAC181F05A4F09B4EBCB99452F -:101BC000FB8A8386967E3ADFBBC442E74FFB6C3DBF -:101BD000365C3F667B8F0DE308F27DDC7E52965AC1 -:101BE000FC4F213F85D6162F8F5BBF556E3DC1DF61 -:101BF000FDAA6533EE03BAF59E9E0968675B15CAB8 -:101C00003F57960ECEA7F3823FD03192EF30AF2AE6 -:101C1000287736EAE8BEFA87DD4BEF413C30C5E76E -:101C2000AB827E79E98A84E72F1E547C268C5F186C -:101C300085DDD6E7E1BFF7AA7E7787B02F77E4F39B -:101C40007BABBA971C287E0DFAF5B5AEEDC7EF99C0 -:101C5000279A18E699F5E59CE9C6F3A28FBB60C701 -:101C60000B78B034E8E8F75A1EAF8536A9E8CF30D4 -:101C700068FC15CF4AFDD43ED0A8A37D82A5C4A0A0 -:101C8000F16FA435E8BCE8773CE0F66F427EBBFA22 -:101C90006DE506FC9E6BBC6243FDF490EB17261DC0 -:101CA000C09952AE1DD7364B3B8EA35A5BEFACD5D5 -:101CB000D6672CD4D6BBBE6648F0D768CB29C847B8 -:101CC0008847900116D04349BC8A2559AED0EF858C -:101CD00075FB77F54C8036C6E440E96B006FD2A403 -:101CE00024DAEF6F7C3509171FC81F467267E314AB -:101CF0004679AFC772BFE9427D9A889FBE1C03CD6B -:101D0000D75208F82CC0FDFA59FA5D2F0B8B6B5790 -:101D100080F8F13E93CFF7EFCC5581FE394672F053 -:101D200059D57F7C0B3F4FD5D7CAFDD20F2DE27915 -:101D30008134830A5CDFBC7D0AFECED854F4DB77A5 -:101D4000DD8DF98E8978CDC4FC3239C61F1BD4F3E2 -:101D50002B787AB2828B655C7797DCFCFECD970599 -:101D6000DF1C14F72D44DB23FE3218DFCAC2786F64 -:101D7000E6ABFE077E1E609B1A8F1165BCC610CBBA -:101D8000078F3B6EC0F5B46DA1A30CD7D346619706 -:101D9000A5E618BC1301DE47DE3004A4ABA0ACB04E -:101DA000E37AD0E7071DFCBB86379302789EEA11E1 -:101DB00057399DCFFA389FFBF39EABF4FCBC96D607 -:101DC000A342E7DF1E717ACC65DCDEC0BBAE19A58D -:101DD00016816971B4B68CF6A98F783D665CAF8FB9 -:101DE000E478CC989F6CCE526CB88E1D2E85EED1C7 -:101DF0007AC4E4B7A1DDE2000588BF1F67C8ED998A -:101E000047E7920087BA0A1E1260228F0FF3E8D2CA -:101E100004BEFA5C77D9F0FCBAB3F0D0B7D0AF9E6D -:101E200086E3A5F07E8827BBC0D3A57C37CF4B16B1 -:101E3000E3A7DDF51CB5C7BFCE8AB8F13C9CBF0C4B -:101E4000F358907E074D7C5F1D273A3EF392DF7E6C -:101E5000C34F38DEDA73F9FD4186358CF661CF5514 -:101E6000FAF71F45FC6425D13E3BDB955D85FC916F -:101E7000FDC6CE05780E61C34FB8FE342CE7F1A63F -:101E80006C8599BE8CF34EF7DB108F89EB30EB78C5 -:101E90004F1D32DBFF054658D4C60080000000000D -:101EA0001F8B080000000000000BD57D0B7CD4C503 -:101EB000B5FFFCF6954DB249360F424248D8CD8B5E -:101EC000401E6CC24344D4E5114445BA913722FE0A -:101ED000420204482080F6A6D69AC50445C51A2AAF -:101EE0002A5AD48D02C58ABA5440ACE85D1E5AAA5B -:101EF00056D3AAB7542B4D842AC82B86F65EDA7ABD -:101F0000ED7FBE676692FD2D89D2DEDBCFE7FEE373 -:101F1000A71DE637AF33E79C3973E69C33B33B9399 -:101F2000D82D3E076349136DCC6567F4F777FEBF84 -:101F3000740B5B674E622C650AFF5E10F63D2D65E3 -:101F40007C7E0963A9D38DF5D35858DECDEB1DEE09 -:101F5000BC8DC53336A0DA58EF89D8A3A5CC845CF4 -:101F6000D877F3B7E79BB5F67B078F60CC9F6EF110 -:101F70006C75319619311E635F4721AF3193EBEFDA -:101F8000398C8D772532D60FDFEB5DBE62C676DAEF -:101F90009C131C298C75AE649EA779FBF12FAF9F13 -:101FA000FB36CFFF67A6C319C56B651C6E692BE2B4 -:101FB000DFD95E7D30EA6FB6E84FC5F2F2CD47FA61 -:101FC00033BFC658542CAB0F723CD94C4C47FA77F0 -:101FD000FC5D8D71AC34CE78179FD448C67817015C -:101FE00053DA3F9F06070E2C747AD09FBBCDCEFBF1 -:101FF0000D5A9C85169E1FF9D4A30F5A33310F0E2C -:10200000E3189AB6978D66ECB9437CDC013CE77F18 -:10201000E2C189165E1ED35DEE47F94E9349E4FD99 -:102020008107278E656CE0A1E01A8793B18AA7B675 -:102030003F68E7788BFE9528F7F1BCDF02BCD40E31 -:102040006AE7F33B90B594E6DFF4BB2816C5EB15C1 -:102050009B3D9B90671F47B3AD3CBF7DF7D8D92E02 -:102060005EAF296E944B2F626C9A4BA3F95720ED0B -:1020700077F1BCCC368FEE715CFCFD7A8937C63CBB -:10208000475A397D8B9FB1B1FB786101E006BD5A9B -:10209000A3034F83BE2D8F72A663ACDA29685EBDA1 -:1020A000E7BEACFD3C7D25AEA2CAC5DB57C74D4C93 -:1020B000053C191718D39339DD1AED4CE7B8CA4817 -:1020C000F999C6387C03530E8D630EF04DDB1A2749 -:1020D000D2FA18A687F165C6050BD387A33F2FF563 -:1020E000873F7B2AB850FC3527E96C0D87C7CF7135 -:1020F000BD15DCE98CE9D04AC0F813BDED6A7D64FA -:10210000834FD9EC6011B84EE0C1C6716A2DE3A9C6 -:10211000C3128AEAA5FE6DB29ED9EE089987F1D462 -:10212000F9E611EAD76139DD6EEFA9670F58081F8C -:10213000AC9605F234C2933F0AF98424CA33AFD770 -:1021400095920AFE6784DC0C0B3B14C5C725EEE5AF -:10215000EB279D85287D82A3C791834A99899FC5D6 -:10216000327C62E0E3A7199B1CCED72A350D3211D1 -:102170007CB90DA67EC7397E0A0F46131C96752CB6 -:1021800010CD07CB053D38DD72D7B380C58D7AB64B -:102190007EC793D1CE25F9C06962345E7028D6D54A -:1021A000A6371DEB5902D197E4CEA61856037CA999 -:1021B000F1185B43FC10907CB1B9D1497454E5032C -:1021C0006B0F44D031C94047552FE3C200A2674F7F -:1021D000BF01EA2FA36117F143C6852CC927AE6F53 -:1021E000E93FBB8FFED3A87DDFFD0FA4F19F087DE3 -:1021F000903895A3E2C79DBB127D3C8DB6B6F83CE6 -:10220000BDE039E356A39C1CB6D72877155EA2AD76 -:10221000DE940A8EFFE8DB4C9E56DEDF65478CF5C8 -:1022200026BB3F4CC47AECA91F4A9986FA75A2FED8 -:1022300015278CF57DE37647D417F05D7DC1582FC7 -:10224000923E91F072B8FACD08836B823DCAD07E7F -:1022500076E54570F59B1506D73569C6FAFA9ADE1C -:10226000E1BABE20EA1BE152F5BE33FAD2EA45CE0E -:1022700063DAE4A83EF02EEACF9A7D69FDDE54F3DE -:10228000CDF56E69881CC72FF72BBEB6F83A4EC63F -:102290003FF812486E3079A3F93EEA649D0CEBA832 -:1022A0004BAEAB24E6A4F5CC17BE8675F53EFE9981 -:1022B000CED810B7EF2BC8AF0976EFBC8779D58998 -:1022C00072BF6253788F97A3735FF18DC517F31FA9 -:1022D0006377115CAF6ABACE689FB57BB6F2F55DE5 -:1022E00098C1ECE95C0F606981EC1BE3188B752BDE -:1022F00079CD450D8773A8C4DDF30382AB12699DC8 -:10230000079200CF3F3A6E7FB737C9DDAFA77E6433 -:10231000BD9EFA024F365B7025E0ECAC7378B03F9F -:102320007C8022DEEE9999512133C7D739AB639D6A -:10233000C6E5CC91D8F96FF6E378783F5E77A1FFD8 -:10234000D9B3AEBD1B79ED40B26B1587EF5C65FB71 -:1023500028E0D51BABE7BA391CB5767D502A9FE241 -:10236000994C7D7002F0EB4B26BCF27F14FB7A8512 -:102370005FC0335113F84F4ED08B31CE4453DB93B3 -:102380003E7CB3B48D423BE6EC47F09DB17179D70A -:10239000CBFA5778182FFBD96FF57CD5C9E7B77FF3 -:1023A0004382A789C35B9D3C6BFE0A5EB4D0E44BBD -:1023B0000D990D705F81F16A1D9583D201B755C2E9 -:1023C0006DEF27F1EECDFD26B89B301EF6B51F68E8 -:1023D00081AD6E414BE45FF62706EEE3F928D3F9B1 -:1023E0000F203F3A8B4D1EBE47B0CD5CBFB0F37D92 -:1023F000E53D89EF27B8FA634FA2EFEBF03D2D469C -:10240000B44F7BC41468E2ED7DE35F213A3DB3DC59 -:10241000E131F3B12A99CB06BEAD625E1BE0FFE36A -:10242000B8BFBDD6CEE737C7AD4FC73C6E4936659E -:102430007D4070E885159CDFD85881FF6FE307C6A3 -:10244000D69BD828C66E94FAC14289C769CC6BC5A1 -:102450003833986EC5B8BF396BF3422FFD0D7450F9 -:102460000EEF2CE6A7EF735880D29B5888EADFCC9A -:10247000DA29FFEBD892CC060E5FC5A383F3B01E1A -:10248000C3F0BE54F2CB2D29825F3EEF0FBC6FEC40 -:102490007749FC5BA109FC0D71EBABDDB45E5D29F6 -:1024A0001EC0E49C30D01717B67E26F613FC677169 -:1024B000E67DD3FA69EB8A2F61C3481E38D2391EF4 -:1024C000AE91A4BCC6BB6C0AE60B0982F5FA1DB935 -:1024D0005ECBCD0E96C2E9D2E63207A2382C93C766 -:1024E000AD4CC37C7FB186FD6A38A7DF2FC69959F2 -:1024F00013D5F452BBA9B2BFA903279D847EF20E67 -:102500000BA58CE0EDCA2FE88712387EA69A7734A7 -:10251000738D9B4D1E68FDB43D4CAE5D9BB2D3C226 -:10252000B8FE725DAEF1FB94229E0F93BB5399A54A -:10253000A79CD37F3FF003B9C35ACCE0DF47DD71DE -:1025400029D057D85036549C0F3835C2E6D365FF92 -:10255000DA768EB77BCBAD3F093E5A9578763EE969 -:102560001D16319FE5EF9A49AFFCB49181F3D87104 -:10257000AE1F7AF319FB8CEB17C89F684CA3F40BC2 -:10258000AE0F203DDD5840E5671B3D94FFD2EDFBCB -:1025900009E8B460DD9716EC4BF7442B7C0B3856FA -:1025A0004BBEBB2773D4A37FE578BDE71DBE303893 -:1025B0003C35C19649007B75E6A777417F5EFDAC4F -:1025C000E641BD65FBBC36078767E121FD6E90796A -:1025D000F13BED532126EAA0BF72BDE15EAB6F3740 -:1025E000C61BF9E1F1549D57F0EEEB783399D7FF14 -:1025F000BC7134C175B2D14B709D6A9C4C694CB6AC -:10260000EF55D4F7B22F6DA87FC38E0E4B06AF5F88 -:10261000EED5BC588F57795920C0E1D96415F27DA9 -:102620001397EF589FE38A6F7CE25606F9ABBF81A0 -:10263000F63392AACA93F9F7A9A32B2DA837EB2B4F -:102640002ED3DC3D7CF8EDEB50E0A34ED2E5CCEB95 -:102650001AE1E9CC9EC2EF5CC1FB7BFDB0999939D0 -:102660005C5D174C0457D79198009456556FD56E02 -:1026700033E993AB326D01E06FD5EEC2FED0A74EC9 -:1026800071BAB1FC9EF14E3DFF6F2E3D4C8E9E4ABD -:102690000AFEE74790539F0839C5F5CDCF1E871C2A -:1026A0001B38C003BA9FB572BD1C8866F5B1D8C788 -:1026B00096DBE4FAE27206F95331E21C3CEA858CBF -:1026C000F1582F18CF65EB9143F92F3C9AFD7D57B8 -:1026D000CF78DB830B3F7A9CE7CF044C7E2BDF6700 -:1026E000CEB0E0D99F438E6E7178703EB847E3F06C -:1026F000601FDD3A80F2059A25A681F83940EBB5D6 -:102700004073591AB8FCA9FDD96303C04FAF721CBE -:102710008CE6E5AF6E8825F9F4AAD573B401FD3DCA -:1027200021FAFBC90FBFF7E95EA40FD4957D0F48CE -:10273000CE4E227C57FF68C950B4E7FB344BE7FD0F -:102740003DF7B2168AE6EBB378E3FEBBD2397CC321 -:1027500036779806F0B4748BD684B430F3BAC36677 -:102760005E6ECF76111CC377B8CD19585603021F81 -:102770005D4DFBB7715F2FDAF8E5781C2FD5FE3E73 -:10278000540B7ED18AF370D691329DF0D742FDEC86 -:10279000DE37EDFD9B18E6C13507C05D69F3D07EDD -:1027A00012F0B782CE67F402CF7D58D33EFF63A00C -:1027B000EF193DD583FD658FC91F3F06F58F5A6818 -:1027C0009E2F6FF975BC95E713765959342FAF2BAF -:1027D000ED9C84FA75992E3A87673E79CD64E0675F -:1027E000F9AEDDADD44FADDDA3619DED3EFF6606D4 -:1027F000CE43D7324F1EF86E97C8DF3FD1EB01BFF3 -:10280000D5B4FE59E4DB7C94F799FD6E0BEA5709C9 -:102810003DE751B98FB1F6129277C4CAAE1E7ADD88 -:10282000CF8B51BEC9ED4FAF77F4EC7F7CDF2ACC64 -:10283000E6E5E936D9DE392DCBF70FEC5B36B90F7B -:10284000A9FE1EB5317F34EF27937FD7B0AFDAC42E -:102850007EBB95CB17F08BDA6FF9B857648BF65EB9 -:10286000C8C90CBEB996F2F9643C1A15A03DFD1218 -:10287000C7577AD28A1821CF94FE313BB9E9B57691 -:102880008ED73FC5EBD7607E0BE57ECD2C9E34CC3A -:10289000EF58BC7732C6AFB57766610E7C3F9C823D -:1028A000FC7233D79F72C2F427FBA5ED875109DE76 -:1028B0001BD1FE52EB8F8DE95DFE8EED1A4DF2F7C6 -:1028C00035297F57FFD9C44A797EF5C351244F6813 -:1028D0004FEB052FAFF1F5AE73F9F2EFB01BF0F44B -:1028E000CA3FB59BE9FC71C854FB26DF4F69E86C11 -:1028F000FC5F6753C208CA7B41E6ABFE64EAF57C25 -:10290000A8524EA77ACCCBFB95D1DE70F5574E1B63 -:10291000F5EF48BAA4F99AFB98AF395ECC771FE679 -:10292000CB69B7FACB329297FB2E719E9951DE3567 -:10293000A06FE43C38DCF7E07B24DCDDFCDD79696A -:1029400070DFA631BF09EBEC4B5B00EB6C1F07138C -:10295000EB76DF92A200D6F31E9BC8FBE36DA47F4B -:10296000EE8B637EC88F7D15A901BF1B729009FD98 -:10297000B41F13E5D1B2FD9C546A3F208AF33FCFC8 -:10298000B39B6264FFF56F17A37C4D868743C0F548 -:10299000DBC0BA6CD26FCD64373C22E5F5C6C4D03B -:1029A0004D66FE7DE397F90CE31C61A18C15A857D9 -:1029B0001343726863A2373D89E371CFD766DA1794 -:1029C0003696F2BC83E434D977365678D313797EC1 -:1029D000AEA4CBC6D6C0D647D05F4581C7CFC719F6 -:1029E0006066F554CF2DFAF9C82ADAFD4ED285AFCC -:1029F000635AE7EF672F0801CFFAD4580BEC221C7B -:102A0000E3E91A87FFF1EA3C46F252DABD664B1A57 -:102A1000CCEDE103AF7D14F45AF13767E1D668C815 -:102A2000E31935D164973A5273579C8B8F374337EC -:102A300087A2A0FF4D2F37D89DDECFF6D2B8FC601D -:102A400021CF09A12AE0F1F54E3B835CEE8B9E7508 -:102A5000C171C9C7C3F8A1C626E4C709A90FBD1231 -:102A6000A7BF0B7E5FB1F7DAE4E361FA5EF5C2F26D -:102A70007CB2FB565FDAF9AE09741A46EBD56F02E9 -:102A80007F04A389FE936FB413BDBB1CA6A76197F7 -:102A9000BC45CAAB261C84F9F7A6DD5181BBF8B74B -:102AA0001551A19990579CFECF6E035D5F8B26FA5E -:102AB000D7DA043FD5FEBC90F86B8FCDEB5E8BFE72 -:102AC0005F8F22BAD7C6BB12A8FCAD6426F98FF47B -:102AD00086DA98507E22C7E7BA58FD24F0C6F98EF0 -:102AE000ECC1B536F1FDA8E4ABA3BC0FC0E1AF8FDC -:102AF000237E6432AF7F3F99CE535C1F25FED51FE6 -:102B00002CA4BC6EF3A62FC4FA58154BF01D95F6F5 -:102B1000B4A3B589C4DFF31E5CF60EE3F43CEADB34 -:102B2000766F3EAF77749FD5837DE9F70DE6908D84 -:102B3000D3F5EC1DC7466DE2F9F6BB3ECED2C3EC31 -:102B400068F3EEAA9B8276F396DE3115FB655FF89B -:102B50009E571BC5656E0F9D5272BCE61C8E7F4F43 -:102B60008E6ECBE1F35C51D4BE0872EFACADED4993 -:102B70009C0F3E4AD0A3F1FDDC2B9F6F237968E9BF -:102B8000CC877EBEDCC2F9007C29F7CF15922F5F7F -:102B9000CCD113509FE38FF4F1D8A23621F7EEB8D1 -:102BA0003439FFC5BEAD7B343ECEB2987DCB2935DE -:102BB000074AD0CF292D14AFE5007F5C8FE3FD9D40 -:102BC0007686E241075D9E9B966D37CE0B7FB0AB5C -:102BD0002CC33F78BB654133D955F8FE6E03FCCB5F -:102BE00060E935F813845CE1FD3C4DEBD0F1FBF975 -:102BF000DFE7F85FFAEC9032E893CB12F7FEF00AC9 -:102C0000AAC7DB293E375F9C57F3B9181E31BFD3E3 -:102C100092CF4F33290767DBBACFE1D083CE3EDFB7 -:102C2000DFC037679F1D42F92FB44E2D86C37556FE -:102C3000CA23E6098EAAC001C21B1C057DF611F944 -:102C40007D59727014E48F9247CC1E2CA17375418C -:102C5000B004E74925CF982F984FDF03C17CB4DF3C -:102C60006312760AFAC3BC9FCB68253CD8C57A5C50 -:102C7000FA5C21E1458D1349BFC8F94ECD11FE0123 -:102C80000EEF2D3E5E7FF0269BA17C48C0989F29C9 -:102C9000EB0F8AA0CB0073E7FE28C8FB6718ADD7FF -:102CA000C8716FCE11F6F49FFEB49B0E66795E6418 -:102CB0002E457F97D0B7ADC0F7EFBAF17D6B069781 -:102CC000A7CB30C7EC9EF9EF29D53320F7CF9A84F4 -:102CD0009D7A4F22CF1741CF11F8547985C7483ECE -:102CE000BAEB778B32E04F5997D3EDE7E80F7E6B65 -:102CF00082BCE4F2A2C92AF0F14563CDF0E3169C50 -:102D000047EBD3AB2D3DF359B4A9D48EF5B278730C -:102D1000A97D41D879A769FBF0C32E4E97D3DB2D4F -:102D2000643668B2047E083DBA69BB39E867546E00 -:102D3000F7F2FAA71D07DE45BD459B13CBA0F7AA06 -:102D4000F68B37DD965E1D86EFC2ED46FC17078DCC -:102D500079D8A3C3F33F822E38F21F6F571A32E699 -:102D6000871F36E63FFFE0D69960E397470B7E3F2B -:102D700011880BC04F55F3F1A4C3D8D74EEC793965 -:102D80001EF459F649F59B38B72CDE64E4334E3710 -:102D90000D7ABD7F9B46FCB12410B9EEE47ABF6882 -:102DA0003DAE5176CD82703E89A4E729169CE9E5B7 -:102DB000FC54DBB06A38FC21355338E372782E0FAF -:102DC0006EB0C16F10395E5FEB9E39BC2ED8AB2A56 -:102DD000478BB2310DE3D931187DD7FF7A12D65B1C -:102DE000E5FD1AEDFF952F0D3E04F9DDB173CE75AB -:102DF00094CE9C4C7850F6B3C5FBB4501CCF3B47E7 -:102E0000BBF6B6F3760B031AED0F0B9AA37AE41018 -:102E1000FF5FF5FA083836869573F817EFDDFF1770 -:102E20008DF75FB3D9D86E09C717E4FED22D7F8F17 -:102E30000AFFAECE7D63F6B59A31EF850A7EFF5567 -:102E40000CF3122E482E3AA4BE721C192EEFA39238 -:102E50007C6DD85FC66C14EDB8C0AAC47CEB1C3680 -:102E600017E65B6767A1580EC7E1389BD7C9BF9FBC -:102E7000DF1447F6A945515C2F2CA3944597A19DDB -:102E800087F6E9CFDE3393BE5287B1D1CF531A9D77 -:102E90007FEA606C44FE19915FC242340FF08B37B9 -:102EA0007C7E01639EB5887353AD25B41FF858CA64 -:102EB000DAC5B987D3D11BE68FABE5F33C92047D2D -:102EC000C8D87E050B52FD157BFF1E15FE3DCC4E6E -:102ED0004AE73975AE34DB9817FAB1F9CE18DAEF54 -:102EE000B9208E017FAED5BC8FD9CD48C5BCFC1BA7 -:102EF00084FE33B755EC175C3FCD077E366E18E283 -:102F0000819E3297EBD9D1D02396C450BD8D898C48 -:102F1000EC2B1BE7E40B3DFBEB974218A7F3618D0D -:102F2000EC231B4B45BF1B1F1842E590871A8D13DE -:102F3000457ACBC60A559E497AD247002D1D7AAEF6 -:102F4000FCDECF45DF0798BDF9D0D7D943D174DE79 -:102F5000577AED33497A7C6EBF9EF92A3D98D55C4D -:102F60009AFEB755EE779D1B84FFF7B8E67BD31426 -:102F7000A6970ECA15FBC3A8F1DE6DB21EF901AA11 -:102F80004D15F75DCDE1A97EC4E46A72F7E09D7945 -:102F9000BDF998FFF10DD165E0B351E385BDE76858 -:102FA000A990DBB1239837C0D3825CB17F14E49A37 -:102FB0000C695A0CE73FDECFF172611F8E1BE123D3 -:102FC0003B1BD7D9487E47CE638484AFDAE67BEBE0 -:102FD000CA5EE0E9E6838942CF38BE527B5AC0C55B -:102FE000E9CAF3A37E144DF6B9E3725F51F8E77CAA -:102FF0003392F66929AF36483ED900FA633F5B2227 -:10300000CE413D7C62E483B99AC02B7B40E8A71B8C -:1030100013455EF1013FEFB0BF824FCA19E1BDAF6A -:10302000738F9AE7C65651CEE93D05F48E3CF728DA -:103030007A334B6024CE8D7DD17BC1E8C4519A890F -:10304000FCD67EF8ADB1D7115EEEB504EEE2700CA1 -:10305000B408FC675A047F71A9EC8F29A3FA5E1BA0 -:10306000CF573EB4987979FDCA0C46F6205E9F256D -:10307000A03EEF06712CD82BD0AE3241F45BD99F25 -:10308000D13981FEB8BCCA459A4DFD7A4D49A27D21 -:103090007C19B5F79B447BAF85A78372843EDFB96B -:1030A000362AF034E4F33D99F9E08329E38D7CF08E -:1030B000EFB962BF57E9D03C97342A79D2B0BE1736 -:1030C000340FA1FDA229DA57B71B747B5EE8FF9588 -:1030D00077DF7CC348C0F742B207E07D317527F93E -:1030E0001B1634CFB9ED439C1BB647D3F76BF2F4F4 -:1030F000DB7347420F74CDDFCD3F2C9871D096C65D -:10310000DBEBC18A333FE7E954FFCE77A10F4C9D3B -:103110006EA6FA5399B08FB26631CE0DFE2F2D698F -:10312000BCBF1BC66A1433D011EDCC5AC9E1AF94B1 -:10313000F4BB5BF26F53349BFD3307E0CACCCFE6A0 -:10314000DF6F8086D98BFFEA90AA3F4EDB0CBD660D -:10315000D004B1BE547DF4837EDF92EB6983C48BCF -:10316000CA73BC52FDEA75511D39F148ADA1C13C8D -:10317000EDCC1FFF30F86A4A369BB40978FF9E19E0 -:10318000B10A1CDECE4A5AF771F92EF0A9CE588842 -:10319000E223024388AF3BC67576DCC3F31DAD83E3 -:1031A0003D64F391E7E885385FB9502EE498922F9B -:1031B000479DED71C4AFF25C5D2559E38F0D131E81 -:1031C000B98CD7AF72D83AB01F2C7C785A3CE24CFD -:1031D000AA369A453CC77AE3B99A9F7F5F045D227D -:1031E000CFC991E761F00CF8A87ABD467C38A8C930 -:1031F000634B2739A63931BF6A472817F2BDDA1366 -:10320000ED41F9E9466FF2F15CF8232653CABEE2BC -:10321000781F057B2CA3208E0379FA3EE0A9B2A586 -:1032200092CE8BB1453AC9A7BFE5BA08CF53604FDC -:1032300084BCB1B4A7631DD6A9EF49CE7C07F17356 -:1032400034031E3AACCE7CC0D5B136DA847D73CA65 -:103250005D82AFF93AB35B78FB7B2D2C06EBFD3E2C -:10326000D97EDE1A8BAF95E707DA99252E097C55B2 -:103270004A7C5D3658DF003C9CF8011B8DFDBF6A1F -:10328000FD068247F105B3B44D4C867EB7D55D7619 -:103290001FEBE1A3B2C1E3DF47BB6E7E98AE111F07 -:1032A000F0747F0EF1C38D47503E657C2877551131 -:1032B000FC58B5CC0B3F421AF3C01ED0C53A499F0B -:1032C000E8E2FA04E49992274A6E703EF022AE4793 -:1032D000D157C98F6D8D1C248ED7ED8D764A7FDA3C -:1032E000E864162E037634A651FE854617A5C1C69E -:1032F00002FAFEB3460FE577358EA6FC9E462FE513 -:10330000F7364EA6F4E78D3EFACEF1427248C91563 -:10331000258F143F29B914C947F3397AAF2AA3F688 -:1033200024F794BCC33C4C653DF248D1375BF3F9BC -:10333000D3DC9063ED73202FCACDA79F7F197692BF -:103340001A8727CA05BC08B9D7E5B0939CCFB2B19C -:10335000BD38AF37ADF476DC13B6AFDE54A3314BD6 -:10336000189FDE5C1FCD2C617C7C4B43A2213FAFBC -:10337000E1FD37FAF3FEB544DD91C7E1387AE7673E -:103380004FFC967F7FEACE2FF2406F0EC7D64731B3 -:10339000EE1D31DD702421DF6C25FD61508C380776 -:1033A000E10F7459C0C4FA7CEACEBFD2FAEE688845 -:1033B000729979BD050D5184AF8F40278ED7DF4BB1 -:1033C0003A55AE3DF6FCCB58E777D848CE2D6896F7 -:1033D000EB721DC76798BEF6693A23BD4CF33206FF -:1033E0003FCCA73FB085F89ECF3ED5EC010DBA0F7C -:1033F0003F24CDE3DFF575BFA0F82BADE130E9C385 -:103400003AE2B26027F05B0DF1585A838CD36A1F01 -:103410006888A38A1DE1B5413E80A741B70505072D -:1034200018D6356BD19CD802AAE5F7EA751AE91BC4 -:10343000DDFA429E99E8589F6BA1F45DAC71DA2FDA -:103440005A687F52FCCAE585378075D1526A5B1491 -:10345000268717C8EF5505264AD5F7FA5C1BF5F302 -:103460002E8403EFF7BE826CDB4292732E1BE48046 -:10347000AABFA0A0ECEEEC11E8675C0A0B5B8FDE44 -:103480003C0BB5AF47A017CE477661FFAFED631F8A -:10349000507AC909FCF372829FCE5B4B5F78EE05D0 -:1034A000F8C7967E1C45745A3A4CDA238A02A3A6C2 -:1034B000913EE375687C9ECB25FD273EF7497C3B1A -:1034C0002F5FB14BD82F79DA8174F91D3564D75A43 -:1034D000EEE1EB230972D5E8473EF4C2C7F1ED7483 -:1034E000AEF06720BE906F0B192C0DFEA2639360A7 -:1034F000175FC13AEF465C5764BB15DA57F1C2BE9D -:103500002FFCE4CA7F59FEDA9F53098EDDE7532171 -:10351000D756BCB63655EF65DE2B22FCD7CA6FAE48 -:10352000EC602BD8FA2FE1778BACB72A4FFAB52F86 -:103530006397919DC2C2288E61955DE0A12B909703 -:10354000C07A19AF7BDC4D5CB0F3736897C595E02A -:10355000E1709EEB238EEFE53CB13F9F917ED473EB -:103560003BCCA4179EDB1147FCBF7CC7436F5EC1F9 -:10357000F3CBB7681896D5B136C2D3F25D66660F45 -:103580003FDFC06E93DC379CCB9E8BAB073F2D0992 -:103590006ADEAD45F0CBBB12FA85EB8B929F964568 -:1035A0000547111D24FCF749FD48D55BB2EF211BEF -:1035B000E8C5EB9D25BDE5C558E8DAFCAFF35DC075 -:1035C000796AF370F2EB2E09EE5C4EFBFE8E582703 -:1035D000A6F885D5688F0AE489F514C813FAC629B8 -:1035E00069FF3DF58299E40FE0C43AFC4213765E30 -:1035F000D56E9B6CB74DE2ED863CB11E55FD25C1E5 -:103600008EF85C5EFFF3BDEF531A94F35AE2682B19 -:10361000C17EF9F9AED8C9014A7F3CE9553EDE9931 -:10362000E0B8142D6C5DBD9627E286CF6C364F0650 -:10363000BE5840C51905693EA776646874AE05BEDC -:10364000397E4EED7A29DE44EBD62FDA493A9AECF0 -:10365000C29EEAB6B8A4FDC2EE849E31976B75098E -:103660005CDED5ED12F10091DF557D5A6FE9E0F790 -:103670004E9BE07FE9BF97FE25C489903F3ECE1662 -:10368000C0FE3A7F986BD64D90676F5B053D06BADA -:103690001EC5B96AFE7BC964AF586575F547FE4F14 -:1036A000EF58C97E3E7FB85CE769ED23619FEC70FF -:1036B0008B7DBD761D5F217CCA0338FDFD7C7EB508 -:1036C0000113C5531ECBCB26B81EAF31796DE4E78D -:1036D00008E5C34E79D4C6FC66E8C93F8B26FDAE2B -:1036E000365BD8DD1F07BFF3B43629949F0C7B9758 -:1036F000A463ED8DBC3C8C9EB54F87F2A1B79CB600 -:10370000093B1ECA9D48CB44BD26C937E807FD7654 -:10371000B89D6749BFDC1DC7A0E79B5E8E13F6848A -:103720009F4493DF41F57B5EF25593F473F9B70A3A -:10373000F80017F4E625B6967CE8956ADC25F12DAD -:1037400034DE6939DE929816E13F907161A84FE34B -:103750005B9917E7F1CE67A3483FFD22BD6D0FC609 -:10376000FFE2D921E407EF700716EDA572AEB7713D -:103770003A2CFD695408F09E7C368EFC9C27AD42A5 -:103780000F3A19974A7AD0E1B847E6A3BFAE2D5158 -:103790001AEC292735664B43F9D67EE4AF5ADAD8BE -:1037A000407E82A57CB9C31FCDD3C9F02B9FDC3AE4 -:1037B00084EC2C277F6926FF22FFBE0EDF75D632F0 -:1037C000FF76ACBBEDB16467FBE2A77F1B12EE7F17 -:1037D00050E9D22D467B92A2BF2A4FC917EB2B2569 -:1037E0005FE0312D5FEC3375B1C147B2699E62BDB8 -:1037F000723AD0798BAF8F54D8A78F065F49D51C0A -:10380000C07328FFC7C0FB7671AEF9628795FC22B2 -:103810004B5F8EF392FDE69ECB4CD82F969A85FE99 -:10382000BB94B39B48857D68697C3ED98738BEE9E7 -:10383000FCD8B9D52CC711E39EDC9629ECEF219971 -:10384000DF531C009F4F4962B7DC48FACDE612E017 -:10385000F5FC965813F8828FE385DF7EE9EDDF17DC -:10386000F84C5844FA38431CF428F8CB85BCACBB60 -:10387000E78A04C4C3B0F7CC0CA2EFBCC5D31FF2D7 -:1038800030125F8BF3A5BCDCF3840DFEB35ABE5E31 -:10389000101FB44CFA4D97FD54237D6ED9DD573C73 -:1038A0004A72F05D2BCBE3709C0E3E141F4E8F0AC4 -:1038B000D94F4F7B0FD55FC6EB8BF66FC7133CDB41 -:1038C000AC1EC01349C74B6EFF53F325B5EFE68F0F -:1038D00020DFD74B2E9EF779D6F6DD8F2147764431 -:1038E0007BFCF435487EE753D6E022CCFBD4F3D101 -:1038F000245F4E258AF5FE3997877E1BE0B8FE418E -:10390000B26FFC661A83E85E1C30F6ABC69D992F39 -:10391000E46F5DB22701FE8C3A4E07F4C7E9F21D51 -:103920006AFF9E95DA47CE63A46CD7BD3E9F8F2574 -:103930007E393540D0E3D40B83695FE948147CCEEF -:10394000E1CDC239E554A2487153067CB0549E4380 -:103950004F8D0BD2B9FB94B693D20EAB68B7B4417E -:10396000FA6D39DFA5816FC093F05BD9D7B7418F6E -:10397000807D7A5419A5A1A8A48BEDCCE04FEC432F -:103980002FE40B7B16D41AC875F26F907E12B441E7 -:103990001EEB528FABDD71B1BF8CFCA03B34F2FB50 -:1039A0003C20D729A04E51F671CE8FCBFC9A17F14F -:1039B00046CB9A572E01BF2FABDF7013F85DCD6356 -:1039C00099854DC6F9AA4333133C1DD17CDD000F08 -:1039D000E1E365F7E07793821720A7929E49CAF545 -:1039E000E67CB15F21DFC2FBAB6DD6D6D3386E75F6 -:1039F0009E14F35378E268B1C14EC6CFF9A2BC8FD2 -:103A0000F92B3823E7AFE009E60BFB4487DBF5E051 -:103A100058D0FB5766B29F9EFF6A7842D237E8655E -:103A200038B175DB8B39FCAFF1BD1AFDF821DFB081 -:103A30009E618FE670E66F36FA3F0AB618F3437759 -:103A400018F345BB8CF9927DC6BCE79031BF558E0B -:103A5000ABF084732EE2DA70CE458A73AE2B5F9C96 -:103A60007391C7391729CEB9F88E732EF238E72231 -:103A70008F732EF238E722C53917DFCF4AF95D2B55 -:103A8000ED8EA003C557BD12ADFCE0B45ECECD49AE -:103A900025F9A9FC99E7961451BEDB9E5361277B5B -:103AA0008E8AD3B929413F924F7EC3B6BBD34137EB -:103AB0004B3BD97157FC5CD8716BCBA21DB02FB4B6 -:103AC000AFFDFC6EA84F2509FA27F914D7D4B94DDC -:103AD000C42B85486EB4AF71BD77B5A01FD93954DA -:103AE000DC4D25F6BBA4BEE918E94761EB8D7E935A -:103AF000483F4AA4FF24920F94DFE4296B673AE41D -:103B0000FDB167EDEB01FF31691F63B39DA47F2910 -:103B1000BDBA5BFF7A407B1AFBF6D7F949D4BEEBFE -:103B200030D7B77BD96F555A75A18CF4C6EEFC7AA5 -:103B3000CD44712369F1B40FAD963065699D1DF7D1 -:103B400040DEC599681F3FEF30D1B9E0FC0766D26F -:103B50002306433F0F9BCF90408C81BF0AB7274578 -:103B6000F8FF0618EA0FDB9B1DE1FF1B6AF44B4DC3 -:103B70005FB31FE7EB69EB871BEA55FBAE88C0A379 -:103B8000845BEAA54D776CCA82FC591DD745F0AF1E -:103B9000DE1D4D71B5D51C5E2FFC72C87014D4D8D3 -:103BA000BD5381BF9AA03511FB7C95DC7F58837192 -:103BB0003FAEB130BF33A987EF6A9CCC9BC8DB9F77 -:103BC000296DD966E2743B63DAFCC85817FC4AAD2C -:103BD000594ECE57B76AC1D4CB797F7FB3E84583BE -:103BE00039BF6559433F9C0779B93387ADE1F58EFD -:103BF000AD7F299EF46EC9675956670CE8DDDA621D -:103C0000A67301EC52E6A41E7E686D498EC975F458 -:103C1000CCB387FE5FD1FC385D3CB8A7D8E538301F -:103C20007035F4B8A0986FCD38CD4F7AB29CCF2ABA -:103C3000B9AFB05CD1CFAD327F5C9E17D4FC4E0FD4 -:103C4000D95FE2821FB3716F961972DCB4631BEE09 -:103C50000FDC19A35F337824E225F37E3B968FBBFC -:103C6000F44311AFFBC78D13E22F87FEF9BCD533A8 -:103C700085E7EF6979C68673F1524BC0867367CDCD -:103C8000B3AD362F4FAFD9DE4ADF176DAFA4F3F6D1 -:103C900062564FE7C8132AFE56E2A366BCB6D9C9DE -:103CA000E17E61B0901B3531226EA3DC3CF60DC481 -:103CB000A59FDFAE9562BED37D3B6D95B03FCB7ABD -:103CC00091EBA3EB9D69E5FD604F0A0ABF675FEBCF -:103CD0006146A880D6C3B40B2E4AA75F184AE7D81E -:103CE0000F99AF98E44451C479F61D1187DCB54FA4 -:103CF000AC831A5B28651AD6C9EB565A27755C7EC9 -:103D00008D2EC33999B1313CF58D351BF875C5C47D -:103D100058033FCF6649063FF24C5CDA0CCB4F9F0D -:103D20009263A83F6B7A6104FF97F594931C196323 -:103D30008833A9BBC3EFD2289E65BCF13B4FEF206F -:103D40003EBBCED0BE8EDDD8530FE7E02DBF263C64 -:103D500033D666C379ABC624E26A66EB1DF27B3BC1 -:103D60007DE71331ACC341399EDF8A7DD14A767934 -:103D700065979E8D7FE7F4B62F7242CB71111F0AB3 -:103D8000FB8221BE900340E74F26E85027ED3D75AA -:103D900005C2DE53E76FB321FE96E3DF92C151B255 -:103DA000BC45237B1EAF6FCF4812F93BF07D97F1E6 -:103DB000BE01FABB80F2C3E64AAC97C8F2E57CDEEE -:103DC000D03396C34E033B93EA5FF6ABF873F1260C -:103DD000A3DD6839EC396174FC72B08BF874E9F6D4 -:103DE0009D6F0EE07899E64B2CC5FAA90D56582B1D -:103DF0008B2EE63325DFCFD798C8CFDDF5CE41E255 -:103E0000B3AE1A0BF1F3B7E163B957D83323F96FA7 -:103E1000119F0FFCB28B76699E8026EA012F03C0AA -:103E2000971178C9E8055F0A4FDD788B285F8C7F92 -:103E30008C40DC801608B97BC38BC4A3EA3F024FD9 -:103E40006CB4110F8B74D77B90378B0E9B59E0129B -:103E5000E6BD18F3C3F87C7E18FFC60BC24EA2FC69 -:103E600006332F5828DFCD273E113F3D7D8A715DF7 -:103E700076F38D4FAC93191752A9DDFF36FF7C1BEB -:103E8000DF28B823E393D5FD9EFF1A2CED8423D9B8 -:103E9000485AFF971837ACF67B85E741778EA678AE -:103EA000A22E4736E90FDDFB8DD358BE2A2E9BE2AA -:103EB0008875699F53725797F5D43895BCDC351CCB -:103EC0007C3C301576D7BB9B73B2DAC3F4127DAD60 -:103ED00095ECA6596B9229AD8C76A662BFA85C635F -:103EE000F6611FFCF4DEFEA9A361875F6B4D99C2EA -:103EF000BBFEF47B23B25831F2E5941EDB10353B58 -:103F0000DC9EAD525781D80FEAEE3C42FBD719D365 -:103F10003BF1B3B1CED6EE8E4748CDB2B5EF8F723E -:103F200072D5A3D5A20F2A401CA1D6BACD09BC399F -:103F30005B4B608F1E06DAF5EBD11396AE2DEF0FBB -:103F4000FB57EDD7079FC4FEAEAFB1A642CF3CF9F9 -:103F500001DFFF34DABF483F3881F8E314F8AD627F -:103F6000E97EDB098D79E1BF5962DE5FE234ECA7BF -:103F7000FB66028E5762F46105E4A70D6C4BC3F833 -:103F80001E3FC54BEA6BF2127AB397A874C526A1FF -:103F9000BF6D53F65A69D785DE8E3CF4763885A01E -:103FA000B7230FBD1D29F4767CAF90F6FA414D9DE5 -:103FB000A53877FAC7B3827ADA5F1D05D0CB576B85 -:103FC000311EC89BD59AA73FEC606C4BBAD85723DB -:103FD000E8ABD22B3BB96E15C6EF575FB0B3F0F824 -:103FE000B1712CD1909F604F37D42F77BA0DE5D7A0 -:103FF000A40D31945FEB2A35E4AF2FB8DC50FF06F7 -:10400000CF3843FE3BA3AF35D4AFF05618F2D326DA -:10401000CF31D49FE1AB3494CF9ABDC4503E475FBB -:1040200069C8DF54F33D43FD9BEBD718CABDCC698B -:10403000C1FEB60FE7298EF7D7719EE2E9EA5FE588 -:1040400039C2E93A7682A9BE377BFC7725FF6E1A22 -:10405000E25D09FECC94F74032E57D8EE60217F171 -:104060006706EEEDD379B62D1D7C13592FB27C6C0B -:10407000EC81F32E4EC33F6C9F39DDC2E5C3D8CB34 -:104080000E0CCFE1F9A421F74FB770B932F68A03CD -:104090002F65F3FC80216F88F26107CEA3FCFE211F -:1040A0000F8AFC3446AA45F690F1D3FD7C1E63AF1F -:1040B000CE5EEF11F6905EE32D550A3C206E11782E -:1040C000401AE2FC89F400E74FA487387F56E732B4 -:1040D000F626E74FA487F9B912DFDFE2E74AA4EF3B -:1040E000F07325D277F9B912691B3F5722FD4DE3D2 -:1040F0006C4A3F68D4A9DD7F34D6507AA4B19EBE05 -:104100007FD4D840E9EF1BFDF43D50A0EC0721B26D -:10411000B3287FD272F8F16087DB6B3D1DEE6755E7 -:10412000FE40E5FF6BAA67EDB158A7ED96C4CFEC52 -:104130003D7EBDBEE5AC857D16A66FB5C67A9F2BCC -:10414000203BC94027C96BF97DBC362DB38CA77FB6 -:1041500071E93B41EF1965556B13DCB807526F05E8 -:10416000BF7C68EAFD5E707381B03FAC1AE2DD434C -:104170007C22FDD8CA8FDC1D9F12E6E73685C5C5B7 -:10418000D05F587C8BF237AB789AABEC223E4FF97C -:104190009355DC8CEAAFFC02237977E53A0BE927EB -:1041A00071161642FF2A3EE64A7BB014F10257D63A -:1041B0003A280EAD3FFF6E2BA37A5E334FB7FC99C2 -:1041C000D72FE9F15FF797F0F37282BFFC824E764A -:1041D000D72BA5FF1EEDEDA2DC8FF6889D829EC138 -:1041E00053B2AB3D8138A7B21E7F3AEAC78AFA21A3 -:1041F000F497FB9F7CBCF89EF59399142C453C5595 -:10420000E67207C5536D1E17A2FB5B2BDCFAA7A055 -:10421000932FCAF9492CAD9F9C4CD8092AA4DEFBE8 -:104220000D74F81CED147E149E155D147EC3E28E91 -:1042300008AF7DD129923E917451F428BFD0836795 -:10424000E0E9623AF4D009F6D8FF2B74186109D27C -:10425000FDBFA85ABB07707D1B5D6EE96493709F1C -:104260007870B6DE0C3C575E70BD897C151B370933 -:104270005B932AF77C4BF92C94F7EBBBFCB63ECA58 -:10428000DF8E56F1085E4729A7CB04293F56970BCE -:10429000FC4E769B09BF138A16933ECA1C42AF732D -:1042A000F1FF204F267DE56B467F93528CFAA1F2F9 -:1042B000075F27FB9B1CE107BE4EEA8DD745E885CB -:1042C000A38648BDCFCDDCE2DC27EEB94F94FB746A -:1042D00086A4730E3FCC8F051D996E81D03A847BE6 -:1042E000EE25B807EEA7FCB52C40E9F52C44FBD62B -:1042F0000D5CC021FF1DC6289EF160ECD4792B789F -:104300007F13864FC8C5F7B07B7DD70CE947F7FA16 -:10431000FEE00CBBD77760A28BF48603F61CD26359 -:10432000B00EAC6176B45F72B98F5086837C5F400B -:10433000FA06DF17723993FF82EF0BC85F57B0861A -:10434000A1DD249731DE44B5BFDE399E5986F72DB5 -:1043500077AF2F796520EC2B6F270E9E08BBF3DB20 -:1043600089974DC47CDF4EEC6F1269948DD2E29731 -:10437000737BD3B3141FF68C378959922FC6AFC203 -:1043800067241E157EFF097CAEEC0D9FCDC001ECAD -:104390007AF6F7E3D3B2E1FF12EBBFEEE5E2FE807F -:1043A000FF2440435CB25DE025D2BEF379231B08B5 -:1043B000FCB22D09F4FD36C94357368CA1FA5735A6 -:1043C0008CA6F95D11A3DF35848F73BA2C94CF3599 -:1043D00007F6F9E626BA7F7BE605B307FA77ADD98B -:1043E000B5DE83B5FEB6B82FC7BE3A98057F1BDB96 -:1043F000D27BDC6EAD5DE1CD4FF8F4667B9BC5FEF4 -:1044000027EE11ABFD776094887755F759FBDA8F6B -:1044100047C508B932304AC8414527DE8EF219BC7B -:104420009F515C6E643C1843FAF78824EF63C0A781 -:104430003A4723BE09FBD455A1C204E427E33CC993 -:10444000F36FC9FB696F0DAD4FC9E6F83E68D39FA6 -:10445000413B66FECA8C75DD94A7D13DF7AEC339EA -:1044600029C0F756B5EE4A5849F87B034A3FEE1E7D -:104470002FC54C7EF155F08FA6E0DC64277BD1552B -:104480002C9FFCA613E5F8E5BFACA27710D4BD8F36 -:10449000A83493F1FD1C578CE13D98D88224433E0B -:1044A000CE33C0503F6174B6A13CD13BD4509E3C4A -:1044B000B9CC90EFE71B63A8DF7FF678E3BB6EFA19 -:1044C0007586FA1935371AF24A7E65884F2CB37E05 -:1044D000AEA1FDA0860586FA6EFF52E3FB367E6F25 -:1044E0005B412AE49EF8CB59B7CA50FEE37871AF1E -:1044F00061B26311BD5791D772BB717C49A78C041F -:104500004127E612F2D5CFFF03DF94A719E5ED04AA -:10451000A7F1BCCDF5410DFB7B46BDC5F0FDD3FF3A -:10452000219D23F1D2C5B7A610EA431FE2F9ABF4EF -:10453000A10FC2AE3131C5EA0930614F0F9F17ECB0 -:10454000E9E178803D3D3C0F7BBAF15D2823DD61D8 -:104550004F0F2F1F7ED848F7916D46BA5F76C4483B -:1045600077C58F91F4B9BCDDC80F91F4B9E244046A -:104570007F487ACCE6FFFD5DDC93267A4D7268ECCD -:1045800071F73F4F9FD4A19C3E853DF4F9EF0C3D60 -:104590007D683FDC4F3F9F6503BD3AC57B7D2BA502 -:1045A000FC54F184FCBC2BEED3DD6E26FFFE515390 -:1045B0000BBD9774C0A9BBD1FE96A27A0DFE8334C1 -:1045C000E6DBB988C337FFDFA3C89F307F90B8D739 -:1045D000C98ADA29CE5EC9B9F919228E65C850791F -:1045E000BEF0887896A2A1422F8CF33829EEB5B29E -:1045F00048DC23E0C782ACF9C5E09F77A2F16E6189 -:10460000D74661BF6FB78AFBA57ECE47F08B414F7F -:10461000841E9729F5A8A6DFD9ED807FF02666D8FD -:10462000178704EC86B8CBC2ED4E43BE389866A817 -:104630003F6CAFCB505E1A2A30940F3FEC31E44709 -:10464000B68D36D4BFEC88D790BFBC7DB2A1FE1525 -:10465000277C867C06EB7C0CF81DA489F368F5505A -:1046600011C7C3D710F993E6DF9328EE0FCA73AAD8 -:10467000D283553CAE2EF92E529F1E64D329BEB76D -:10468000299D79E81E805D9E4F9851CFD6653CAD3F -:10469000D24799DF184FABE268BBF571A97F2B7D3C -:1046A000382C8ED61B1E473B5FDEF38DDCF7EA25E8 -:1046B000DD23E11F6413F36DFA9E8DEE2D28B822E1 -:1046C000E1F99B8CEFDC6AEFFDFEC89D4385BFFDE1 -:1046D0009739BEEF825F9F84F8C8E96D3C4FBB9F5E -:1046E000F357D30F6C9EBB5CDF3EDEFC61623EF392 -:1046F0004CA65B2A8A286E69F6CFC2C6FFA11C773A -:104700007591D6EBFCE62788B822966073817FFB13 -:104710001E4FE033CDC69AE99E8B8C3BBF797DF06E -:104720000198C8E7D95AACE2FDB28015FC30653C6F -:10473000D79F4A61B7FAFA2107D7339E6CB0901D14 -:10474000E2E1A137CCF0E7F6DC2318C4CF17E00F85 -:10475000E82A3897D88B44DCEC9EA162FD979BBF7A -:10476000EA8EFF267B3A63527E8B734B2FFC467C8E -:10477000A8E6F1AF8E038FC4933A1732B9EFE44A3B -:10478000B814FEBACFF1127F2A1EDFB5D2EA7BDA67 -:104790004171FD9311CFA4E837B048F0E589A182BB -:1047A000DEA80779D457BD72735102ECB55DCC9584 -:1047B000E0FC067BE4BF0A2F0AFF7DDDEFE94B3EFC -:1047C0005C2417FAB8EFD3177FD2DF3F70EF274C86 -:1047D0003E88F812498F40AE89FCB9F7C419D771E9 -:1047E000FF4281DF7D6ABFF0F3F3A4514E30D897CA -:1047F0009BD69AA59C10FB2AF40D7C5FB8D64AFA8A -:10480000066B10F1C835521633E64B1D3302FE58C5 -:104810002BBD67759597913EB2C0610BB4F2FA95C6 -:10482000FEC87DD54BEDC95FE3C2BB259EBB617F52 -:10483000AF5A67ACB7D821DEF55A18712E5D2CCF70 -:10484000A58B23CEA5D185725FF6300FE94DD2FF3F -:10485000ACE0ECE6AB400EC505E39C6A16F6128AA6 -:1048600057EAB6E3C3BF10F68E26C7674C01F6EDD4 -:10487000664BAF7164DDF8ECC34F7E1A7E7217D6BB -:104880007F17DDFFE9DA152DFC68CA7F21EB9FF663 -:104890009FA772D4476F674ADB4AE047EAF677443E -:1048A000F84DBA1CA6F8D1E86F87787F41C5012C76 -:1048B000FD6BA0C419E6E7D4DB4D86B88BC8545F06 -:1048C000B39BE2025A2D7A59219FC7298BC78EF7D5 -:1048D00022EF751C48C57DED29D25E13096FB71E06 -:1048E0003A56137E42BFD043BB266BA48772B9C829 -:1048F000B08E943FBB828552902AFF81BE6E34E118 -:1049000059F90F2A43A309CE194D8BAD78B2AFFDEB -:10491000B13BCA635C3D7E85F64C118FD2977F61B7 -:10492000DA050FF537FDC218EAA7A2D02DEE7135D2 -:104930003FB0127C34743BB3629EED11F1D82ADD96 -:104940005F28ECDF470B95DC96712E6B34A1676B0B -:104950004CC5BD90DC56F9F32D325F2EF2ABD78AF1 -:104960007CBB7CC7689BB437609E48311F9C8B77AB -:10497000487B04E68114F3C077C829E421A7908717 -:104980009C421E720A29E414BE2F60BEAC52B3F0E2 -:10499000834C0C5B37F0834C0CD383E00709CFC307 -:1049A0000F125E1F7E90F072F841C2CBE10709CF73 -:1049B000C30F125E1F7E90F03C1B7D6D4F1E72CDAB -:1049C0005B61C84FE3FAF8C4B0750B3F4878FFF05D -:1049D0008318FAD3571ADADFC41A0CEDE10709AFCE -:1049E0007F4B8366F093DC22EFA5576D4A22FE9839 -:1049F000E3F6FDB090D3F70FB15FDF66C539CDBCEC -:104A00006F099D9FEA623C82CE2D9305DD4D4CD00F -:104A1000B9730ED1F90E9BC8978BB8D8DEFC0D1375 -:104A20007385BF0129FC0D48E16F400A7F03DEC397 -:104A300086BF0129FC0DF80E7F0352F81B90C2DFE0 -:104A40008014FE06A4F0372085BF01EDE06F400A18 -:104A50007F03BEC3DF8014FE067C3F0ABF476E0F94 -:104A60005CD0DB730DE73BCE8786F39DD39087DE6A -:104A70001E5E1F7A7B7839F4F6F072E8EDE179E892 -:104A8000EDE1F5A1B787E7DB86BA685D427F0F6F7E -:104A900007FD3D3C5FDCE27F0336A61B369F3D846D -:104AA000B43D4E7B52E3A2E0BDE78ECD80DFA83D52 -:104AB0005ACB4AE44BDEAA9D9C3191EB67BA8C2F0E -:104AC0002B619DF4BEB32EDFADD1438CE2618BFF31 -:104AD0009226E482BA37843F4EF7D25D8CCE011520 -:104AE000723F55ED3DCC6926B925EBF7E47BAF1756 -:104AF00039BEAA47F2320C0E7E402C451C44E91DFB -:104B00008E32C4716F3369220EF22E11871AC95783 -:104B1000E6222197B699761E88415C4BA546EFC5E3 -:104B2000E75BD861BCE35DDC525F067DE15461A2C6 -:104B30009C57FD18C4C528B8951D90CB09BA5735A8 -:104B4000B693D9AA8BF09E18B32D847CB7093D018A -:104B5000ED707E2CF46BDEA7C3F8FBCF85627FD3AC -:104B6000FD2BC754F3EF853BEAC7E0BED69418D1BE -:104B7000EE274FC5131EA7366B4FE35EDCD81DCC66 -:104B80008BFB975F4B795AB8C369ABA6719D74CF05 -:104B90004BF55BB9398BEEA555B2F6896964CBD775 -:104BA000E81D7385373EBF43981F17F187ADA48F6B -:104BB0008AFB2231F2BE88BA27E2B6F8424347F6B2 -:104BC000DC17B972446239E2B5D83EF1EEDE0D234E -:104BD0002AD7F6E3FDEB01F1EEDE957FAA7F83F2A3 -:104BE0005BC4BB7BC406A3681CDAD706FB357AEF2F -:104BF00061AABFD594E2C2FDD135D654D4DFC13C01 -:104C0000507F0633710F52C157C4DA4C78779C6FCE -:104C1000310793C3F8884B80E9A07BA9C74AEF41CD -:104C200054589C56C88DC87DFCE278BA083D2122B4 -:104C30001EA2E98E2359E66CD87B4C9E10E4D6EE7A -:104C400058D21794BE5329E3A0CE37BF41EF59572E -:104C5000EE14FA81CEE500E49F8A8FA8CB0964990F -:104C6000A02F0C682D49328BFDBF08F791FC2FCD8A -:104C70001CEDC23DC637285EBF72EDC804715F47A8 -:104C8000F81FAA259EAA65FC0B2B72A642EF54EFD3 -:104C900098969BC726D07DB716A1CF29FB4BE5AFD1 -:104CA00086BF093A573E21DF03595749F78022E36F -:104CB00050947EA8DE3B59D26CA5F89625117AE077 -:104CC00032A9072E8BD003AF2B8AD003D5FB74B249 -:104CD0004EE5AF0ECE203DA55EBCC7376F8DD05BD5 -:104CE000D84EF18EFDBC35134C78B762DE6EAF47FF -:104CF000EB853FDE93FACB140C9A8C389F0194CE4F -:104D0000BC9046E9AC0B052407701703F46F7F8550 -:104D1000913EFDBED4576620CE0FF7E3FC51329E84 -:104D20008F91BE54CA9CE5901B43BDDA4198AFA752 -:104D300058F5B588239CD2CAE83ECC0DD06B78C11B -:104D40006CE839C3C1E7EE72BA173059A3FB1537C7 -:104D50008C5829F99AF339039FFB25DFFA28DFBD28 -:104D60001F48FED6FD1D167A97D5AFD9F02E9B2E83 -:104D7000CFB38A7F23F97CBEFCBD09E61076A66E10 -:104D80003B1480A5C755AE9A097D713E6C7703240C -:104D900021398AE28A447973D155339B71B8F91F5E -:104DA000DA27E6A9DF61E07A16E4E9CDB796DA16EC -:104DB00084C9958A92F1CF14F7EBA1FB82EE7B6355 -:104DC00045FDA1FFAFBA37AFFF37DD5FACE278C674 -:104DD000FA989FD07E1B5EC6DD52C4BC1347E33DEC -:104DE00066354F1642BCDA5C99FF75D1E2FF585721 -:104DF00044F8A17C60C794997E5A2F425EDD047905 -:104E000065869CD29F2CC2FD0E7BFB24D023B6A8C6 -:104E100053DE8797FB51843DE2D745820E91768918 -:104E2000AA2221C799C5957513DD5375915D4FC1B0 -:104E3000FFA9D5786F50A5BF54FB48E3BF26DEFE1F -:104E4000CB54FDE7901F8F98C4FDED01E61626EDCB -:104E500043E27732E4FA61F23D831EFA73A901FA64 -:104E6000DFAB39C3E9AFAFD3C4BDE93EEC38ACA08A -:104E7000F3B1ADB0E3358ADFE7782A5FF0D153B7FD -:104E8000DB48FF9E676B7B03EF34293C7EDCF0231D -:104E9000ABF89D97501EDE9F9A5B1F4DEFBD569459 -:104EA000F8DA4097D8220FD1E319C494F2FAED4E04 -:104EB000DFFB984FDDFAFD4FE2FEF88A7D6EBAD730 -:104EC00058B9B7F46EBC6B5151A21F4179A5C369A3 -:104ED000C3FEBDBC3991F6B3F9FDE5FD42D6497E6E -:104EE0002A85FFCE2261C7DA5622FA3F27CF21104A -:104EF0009415867A32AE38629D28FB60A49D21F21B -:104F00003D81BED68FB227C07E600BB32F2AFB84B3 -:104F1000B5E0D339D83FE7D98CF7E154EA2E96E7CC -:104F20005C790E5CD8BD7F154DEA0F7D798346BF55 -:104F30005B53ED70CDBA9CE7AB0F5B1129C8A6247B -:104F4000B9C43B12F78A772416F0F50A79334FC6B5 -:104F50000D556F1A4DEBAD3AC0D3E4BED7E54D1BEE -:104F60000E66BE02FE0979E99E78B5D36B4B0A5BEB -:104F7000F7552D9AE19EB9CA27160B7BDC3C3C61A4 -:104F80005E0679E1B6E12D97795CAD401C9ABBD8FD -:104F900065F0BBF27A14C730259BBD29DEF1E170C4 -:104FA000BBC5786561FD2F6831DE97E7F5C5BB1499 -:104FB000C571D45FA593CF1BF60FA793E0E47820CB -:104FC0003C753EC0FB73D138448FAA50C08AF3F6BB -:104FD0003CC44FF0FC5C67C08A7116348B772BF4AD -:104FE000F5621C7D5DA2AD18FA92C569CB04FEE4A2 -:104FF000BBF61C3E9283D51C2FB8FFA3EE0146E200 -:10500000A752C25BDD9268D4C35A3658418F397DAE -:10501000DC9FBF41D27D41F338BAFF5C6DF1527C19 -:10502000BD2EF1FBC795D1F7C13F3067E3A35637DB -:10503000CF5F592CF8F70689D729D9A13C7A9F660A -:1050400065B40770CE71B6D0FCBAF1FB30C7878665 -:1050500077507C845FCE177EC491556F34D2B307EE -:105060001E81DFEA8D95B4DE1659749B331C8E4D7C -:10507000FBF370AF670E5FDF7877873975BA6FF330 -:10508000D9C3B3B2689E1C4EE035CEE39A84F7666E -:10509000389F101F2B7E51F783D5780B8BC53DC1F0 -:1050A00085C5BDDBD77BD6A597F49B264E5FD8BDC3 -:1050B000FB5A97365C34E2E3DAAAC53B6091EB54C5 -:1050C000AD4FB52ED53A55EBF749AB2F94A6F5C8A1 -:1050D00019BEDFD6FFAC173C3D23E19D2BE9CAF199 -:1050E0007A28FC5ED1FA62218FE6651BD73BFA4332 -:1050F000BFB7ABF2F1A13CDC0354F5D5B8F3E4EF54 -:105100007481EFC16FB74BBAA3FE2AAA6FBC1F51BF -:10511000D52D2F76AC4D85BCD8A991BEBBEA818335 -:1051200099FF063DF679A1C79EAADDBA3C1D76031C -:105130004B202BFC7DA6EA90900F0BB9FE0379B1B2 -:1051400048EED3D7E4E9F7168F0CABF7D0F3F9BAF2 -:10515000902F21C897DF3FFFEA87635C3DFBA78262 -:105160007FC1BA5F5B2B1DE1F8127C7E5F4117DDCA -:10517000FBAA72D85C88B3AD6AAE2479CBD2F87939 -:10518000420B8B938AE083CA668DDECDAA6A18151E -:1051900030FF2FCAE5AAF515F4368FA2937A7F4324 -:1051A000EDA70AFE1D12FEB9928F5F94EB6F6E8D14 -:1051B000DBB688D6BDDB5605FE97E573AA8DDFBB4F -:1051C000E9D4ED672EBA3B4DDE63A173C97AABB06B -:1051D000EFED88237DF5D4AA97DF9DC9EB7DF148DB -:1051E0006B16F41305C76269C75B28ED718BA4DEEB -:1051F000CAE9F47A71989C5DFC94A053D50BBFFA70 -:1052000004EF43CDCB96F2EC0171BF7C417027D106 -:105210006DCEBA0D5637AFF76EB1DB20A7ABEA4BB8 -:105220009DB04FCF5DD76A851C78B758E02D92DFCF -:10523000E7C9B8548557EC3B5A98FF42D587FCDB49 -:10524000C9C7B97565743CE232D438FF25F9B8AAEC -:105250003E3109E355D557FE10E71E25EF23D7DD74 -:10526000B168B11E16F0FEB02E8F8DF3D03DDB7904 -:10527000F2F7A522EB9F9574FBB155BC2398111B47 -:105280007C96E20A56C478201F7273DB031817FC61 -:105290000CB86D26F1EE606E6DFB978083ABC51484 -:1052A0009F8214EF1D414D4EE5F9A74DE23E10627D -:1052B0004B90A694087E80690AE52CA59DDE3F0BE5 -:1052C0008BCF34F0AB8D6D5987F7576C298C7EEFFF -:1052D00045F1A7EA47F1A7E2DFBEE6E728B9B4F94E -:1052E0001D734B3B4481270BF728E63F3898DEE7D8 -:1052F000FFB679DAE43B78DDF38D12BF5B70D17CC9 -:1053000073C5B9A5EFF96E2C4FED65BE91F354EB63 -:1053100044C55E77FB155A845FE198C6F72FDEEE31 -:10532000D8CA688AFB52F35276EF4B8D97F79424D4 -:10533000493B427B1CF4C879F2F7205848E4F1BDA0 -:1053400022ECBBDAF7D5BB614A3E1FAF97FB226B5D -:105350007F00EB9935E4D03B19475B8EC5E1FD8EAC -:1053600063E3047CAADDAD5671EF95C5D95C783F47 -:10537000919FAFE8771F1636F7A773E4CD0D392458 -:10538000176EF6270ABB83D4EF174939187B6BE5F4 -:10539000DD97A1FE26B753E3E32C74783EDB44EDA2 -:1053A0000B3DD007633756D8B249EF15E700E50744 -:1053B000BA55633EBACF043989F565DA9F8B7D67AC -:1053C000F126710E986262EBE02F1CD4E49B940EE0 -:1053D00039F1987837926D36BEAB7420CF777D095E -:1053E000F016F11ED9ADD6A0B73FE438D7376067C5 -:1053F0005AE8F091DEFE969493473776D0FBE40AA4 -:10540000AF17DD53B1897BA99D7126B2BF5DEA7DDF -:10541000956AE94F527CA3FC518FE3FF2E079E4C07 -:10542000B4AF959BE7D1BB3E776F9C4069F586F2A0 -:1054300047FCC5B80FEB4B1D43705BC93E565D374B -:1054400041DC1F7D3A2A11E79B2CAB3F2B5C2FAD33 -:105450006EBD87EEA99C688DA67B2A139D1513133C -:1054600053E8BD5DBAF7A5EA7D5FAECBA575130C19 -:10547000F74C16F23E1107FBE7602CC595AAFB23FB -:1054800077C6E8DF2DE927EE915CEE12F747D2A947 -:10549000BEAB577BB84A3F6B14F711C2EEC54C9DAB -:1054A000C3DBD7D6BD148F7E963DFCFE288E19D85F -:1054B0009FEE02DDBAEFC56C12F7629A705E821E33 -:1054C00099E49B3907F8FFA599F0DFD77835F851B3 -:1054D00092B073C4CD8104D25BF510B3C19FAC3BD5 -:1054E00019E9C527CCAC017A80D25FD4F747245E96 -:1054F0004E24B464813F966C7B340BFBCBC938914E -:105500009FB76DD65B9057FA9628A19F5B18E9C3A9 -:10551000557EA15FB39A24F52E66F47CF8634B6246 -:10552000C53B3CF2FE8C824BBDB77AD222DE8BC1EA -:10553000BD18F0FBC796D042D0F763AEBFE21CFBAC -:105540007D29C73E6E31D3EF8EF8F942811EF2718C -:10555000CB4B71B89FABF4B572F3EFBD788F66D5C6 -:105560006E714F15EF9AD39B95D20EB25CDA41560D -:10557000BD629D84DF1DE1FA177DA9B5846CBDD1A4 -:105580006FA9D4AFBAF3BB76D2B9AD7687D01F6A14 -:10559000831DA43F287D44DD8B5BB6A383F409D52E -:1055A0006EF92E8197BA5DE27B25E2D6E5EF856A3A -:1055B000B9384F6B94FFA468C1AC3596F07C25E5F3 -:1055C0003F2952F6914ED207EF2BF80D9DC3EB9A6F -:1055D00065BF3C6F0D1BEF0D30693FF13DC781F694 -:1055E00062DF57E575BB12A97DA82E661DF679EF1F -:1055F00072870569539D83F6FDCDF5A602CB0800A1 -:1056000017E3811EB74FC66FF55BF61FD1B01FA41D -:10561000B3CE8378F7F580533F027E55BF67A9EE7E -:10562000BD9C7BEDF3E1E8FFAA41EDE7F1C6837590 -:105630004DDD2CF827DA4BE43C8ADA8783AFFB1D7B -:1056400010F2F9092B5B47EF075B7C0C76FB90F4BB -:105650002BFAFF6212BF2FA1859E09D7AF52860990 -:105660003DDC1725FC8B5EB77E12707C47B3169726 -:10567000E24CED32E7A17FF53B2A4A4F1D2FE5733F -:10568000A63C5FD906A439C0C79AD74BF710EF2ABA -:105690003A50857DF9FE4E3BFDBEAA8AC31BDF1939 -:1056A000437A6BE680C9B49FA97B29078A4C7EBCEC -:1056B0007B7E3FB38BB8007B845E6B8AA678646D7B -:1056C000DF2FFE02799E61FEF2207EA724E3DF3405 -:1056D0007AFF727ED7674FE03766E6B14029BD8317 -:1056E00097A89B86410E774DEED039C9EE7706ED2F -:1056F0001EB14FB070F8F77DEF2FF149A61EB8CE5E -:10570000757E46EF0A9EEBB493BD76FC3EF9DE5EF5 -:10571000043CE7D25C1417CDEB85F0BECA3987890B -:10572000DE191BBFEF20BD9B375EBDAB6737BEAB3D -:10573000C7DA3213614F261B2A570A529B04DDAE8B -:105740004A309E13F38689F356DE30213F14FEBAA9 -:10575000EC67DFD6B59E75B842F9EFD5EF4DD5446D -:10576000D1EF4D75EDCBF9C6F713DE87FEC0F5829C -:10577000F5D9DEE261FD7AF6CF19122F6A1F36CB1A -:10578000FE6748FCCC7098043E227E6F43F187A2EE -:10579000BF8257D157D18DDDDEF606EE05717A1541 -:1057A0003FC8884E97119DFEF2CE5A5CF31F60F6FB -:1057B00076E8EEFF8B740A450F869EF0B0F8FDADDB -:1057C000C8B84656C0689DCF37C7901D5097EF8226 -:1057D000F3F5FD06D6B75AD78326B717637F3CCAC1 -:1057E0008FDE80ABDD14A4EFDF1D26E20907B2B621 -:1057F00074197F33127A59937CFFB8FB770C973872 -:10580000E8BD917301F5FE71E0B1457CDC8D338A12 -:10581000C8AE7F8EC9F55ED3FD4EB678FFB8FB9D4E -:105820006CB39FEC247362C8CED3FD4E769E78EFA6 -:10583000FA558DE5E31D5A7F859DE2E323DFC9E636 -:10584000FBCCB3F0673C5E13437E28F53EF278A7AD -:105850005E0F3A46BE8FFC88E69BB310FD153BA851 -:10586000BFF639312F6C13680EC18E73B4218EDEF2 -:1058700085567CA9ECD783FC1D8F014FEA5EE71F9C -:10588000247F29BCAB7B6D0AFF8ACFFC5646F73FCD -:105890004107BC2BABDE67D7EE907243DD277CDD82 -:1058A000E342FA40A2BE0E7037ADE47283ECE2ED43 -:1058B000B761BE4F7C2FCE0BB88E9A8CBFDFABD2B8 -:1058C0008786990CBF133A5FEE57F355DC7F83311F -:1058D000EE3FF21DCDE404DFC3C378FB33DAFBA354 -:1058E000F0F19DFF36F71A47F2A45CFF2362F5271B -:1058F000505FDD7F50FAE13BA59F67D2EF8D7C754D -:10590000907E5771AED31740BDE85CE10FF8437A43 -:105910003BDDD7F8C39CBF66923DF90EF1FEE7A5CB -:10592000C279F17D5AC10FAB178A78C30C564FFC70 -:105930009BD6734F331A70FCFF769FB6E7BEEBE43D -:10594000E1C729EEC247BF5711498FB151075E72B7 -:10595000F193CA6F877D318BEE93261C58EDE6F9E3 -:10596000A32F9E15F98C03E7DD9C36ED2F9E13F9CE -:10597000C203E7711FF5D3173B45FE0A46FEACE3B1 -:105980002F7E390BF74FFBBBF53F825E332FD4BF21 -:1059900081EDF5C335372E74D37DCA8ACC02719F51 -:1059A000F26394CF485DB03641EBB94F69F2F8FE2F -:1059B00008BE3DF7A5E06F3787157CF2CFA6EA3E1B -:1059C000A992B77DC945B5EEFE55F761D53A66DBBC -:1059D0003CEBAC6042FF3F7D4F9579F8BCFE1F9BCE -:1059E0004A017000800000001F8B080000000000CA -:1059F000000BB57C0B7854D5B5F03E73E6994C920C -:105A000049C80B02E104420C18D299BCC05BEA1DE4 -:105A10002089015A1B6CB52018068D90D76442A8C6 -:105A20002DB5D80C0611A8DE0B5754B068274000DE -:105A300035E8A0012718EA00922252BF98FB37F2FE -:105A4000FD5FE10B3E90979310B557EF55B96BADE5 -:105A5000BD4FE64122DAFE7FF8DAEDDAEFBDD77B03 -:105A6000AD7D86B1B196F3D18CFEAEC98C1D3FFCE5 -:105A70009EA249646C4681D16A90A034772BC602FD -:105A80000EBB01DE7595F935B1BC9F36B45FA2D768 -:105A900066C17E7566EA973908FD72B1DF9F476B74 -:105AA000B1BE416F356430F6B48EB94D098CC5680E -:105AB0008EC8B84ECC2063CDD07FAC8131631E63DD -:105AC000297AC6B01DFA312394BB06F97AE3121A7B -:105AD000563098675C85D9DA9C81BBF53056C8583A -:105AE000DA28FF68DC5FDA4A3DD5C7687A94063366 -:105AF000638126FFDC0F33192B8E8ACD653F8052E0 -:105B0000CFB2711F4C13656D85F54AE4AFBAD20070 -:105B10006EEC906CB0342B36946F671319ABD702D0 -:105B20009088FF33795A711D6D77F51EE8D7939CE5 -:105B300066DD08E0D8D4832C331FC6BBCA72D804F4 -:105B4000C68E5A1C39D62468679B241C1F9DC3C768 -:105B5000FFAC2C7A870CE3FB0FDF54E880BA3B0CD8 -:105B6000CA0166652CDF3B7A81F61680E39442C950 -:105B700002B075EC02ED688053940312B41BDDA3F0 -:105B80001714DF82E7335A3ECC66EC174C62718003 -:105B9000970CAD63BA15CEEB2CFB44CF34D83EA0A6 -:105BA0002F9F0AF76A854960FDA4A3704FB0CF818B -:105BB00039319E1D703E96A314627BBA6E20D602C8 -:105BC000F7D1FF95B6CC63A671B13F87FA6BF8F7B2 -:105BD000AF8C3DD72953BD0AABE5375689EED79533 -:105BE000697E0CEFAF3ED568A4B2F36A29C379B4DD -:105BF000E59977C03C763D5B529E73FDF801AB861C -:105C0000F695B10E103A86C8CBCE14F8BF28A6C2BE -:105C10006E369DB1965F41C5BFF0763809D34FD23D -:105C200008F896ADC5DAB0FE76EC1F6C6776230BEC -:105C30008E775AA76E5D9B29D6433C2F639E497091 -:105C40008434D62031B8BF54E627FCBC644BA07323 -:105C5000D11FE0E9D94453CB46A45719E8328F4A03 -:105C60006681322D1AD683F6B4374C1EA4AB5D265E -:105C70004EB7991A5EEED2F0FEFA28E6463A1D07B4 -:105C80003083F26D9BE377B6249AC74FF3C8FB6D60 -:105C9000488FA39997D64F616EDA8FDA6F2CEB3667 -:105CA00021CCB40359844F5933EC7D26D9666E4616 -:105CB0003A0B34D9D947DA607D203A765528FEEA86 -:105CC00071BC3974DC2C1AA78E77AED2B08F46E146 -:105CD000E1FD443FCE4C8DDD9383E3D89B521ED62D -:105CE00077EBCB6382E37A9B8CEC23B8D7FFD3C4EA -:105CF000A83CDD64A1F5FF6F532A957F6B52A8FE87 -:105D00006C5336957D4D56AA7FBF693A95772D8A9B -:105D10002940FA77F966B28F8C42CEC0FF9C5E9D17 -:105D2000A32F04EE9D393C1DBD26E8A83763F8F685 -:105D30006E6C077CF6DECAF1D97F3FF3ECC820BA5F -:105D40005C6B49B81EFF30C284E7EB8F610BBC70FF -:105D50004F6F1748347FFF680EEFB7EA683EBB8687 -:105D60006DC5F16F17E8F9FC133455D86E4FE0F3A9 -:105D7000F666010CFB59307DE6CBC897F664A8CFD8 -:105D80000BC2BD5378BB7D0CAF57F7ABB6FFCE66E9 -:105D9000E17428F0DEAF83F57388DE697EB5FFD746 -:105DA000459C0F23FB7B3235659E61EE23C1C6FB0C -:105DB000135FC07DB8910F3242F8A25E21BE50E958 -:105DC00050A5BF976CFC9E330D82CE4127D0FDA11C -:105DD0006E40F99A027C20D1BDD8199C679724F8AF -:105DE00025921FA04439AEF283CA072ABDA7019F9E -:105DF0004909C173FC28825ED5F2B495E3A53B390D -:105E0000E601C26BA7CE02A210FA03221310BEB3A2 -:105E1000C00EE34A1E35370C27BFE2FED97B50E5A2 -:105E2000C108F770DDF9F5BCFCBEE727F986721BE7 -:105E3000E9761879F5B53581F6A3D26D92CDFE5F7E -:105E4000483FFD92492BC54169E2741379FEB70BB7 -:105E5000F83954FA79C9C6B8BEC4734EBC5EDEA91F -:105E6000E7193AE77246722F338AD747E2573D5710 -:105E700088DC8BB11506EF93316E0F8C057B606368 -:105E800046907E03495F2E43FDB5CDAAD0FEFEA00D -:105E90009109FFAA3E19AA97E425F373C2F40CB343 -:105EA000001E070E1B88BFFD1A56F50A8C6B255580 -:105EB000113CF76D362E0F06174CD2AC827D05FED5 -:105EC0006E76A3DE0A8C19382BC1F8C0563040C854 -:105ED0007EB0FF584A66EC7ED029A897AE809C63BE -:105EE000598CC9DB3E3F2BC1BE976D9319DA350142 -:105EF00010DB328C733D19E331F2718CC1B83A3149 -:105F0000AE79EBA777217D9D07FA44FBE62353FD8D -:105F1000040676CFEC6D3ABAC765317A0FD61FDB2F -:105F2000FAC48945009F6F9714B4374A6533B5D7D3 -:105F30003C2F7B709D3A73E94509EC9C407BCB5329 -:105F40005150EFDCAB63261857DA2E59FD30FF7243 -:105F50006F0CDE0C5BB645F77E5F76506EDE26F486 -:105F600058D52EC90314C3AAB687B7D7EC0A87EB56 -:105F7000983608C3FCB36C318964FF4D6636B4FFB4 -:105F8000D89604545643723B92AE506D237EEC8DEE -:105F90005C1E33F659F21D4097F2E1CFD3DF377321 -:105FA00078BE80CF01FCC9E7FCFED57BAB1732FF82 -:105FB00093D1ACC00BE7AC3F6CB2B8E160F51D32D9 -:105FC0009D23E08DA37B7645F5DD4E7C7A48B6A017 -:105FD0001DB6C127BBB1DDD969DAA98173D61F907F -:105FE00018DA9F4E9FC1C3EFE9EA326C5FEE335976 -:105FF000146C3F6460328C0F00DE4C88C7717D8466 -:106000007FC42BDAA7F0F763A928887F19F19518C8 -:10601000C457F356BE9FF37B397E4AE5D55AC25723 -:106020008BC45242F0FC67CD8B43F8C27EB3B7FD00 -:10603000B50BF1BC0CF6675010EF32E1F93CE0070C -:10604000E7D51FFE28BDCF1CC4B70CF8FEAD3A1E25 -:10605000FA2FBF01BEAB987B1DDA73DF17CF69C87B -:10606000FF4964F79EFF03DABD31608F23E908FB27 -:1060700038A9B6F778222C589170D9B902EA27A529 -:10608000BEC232C14E90E21D8F225F9F9DF39747A3 -:10609000101D3D735FB4215D34EBFA5A9F860A7779 -:1060A0007CB41579B03F63FEF6D7609DE2842FD3B0 -:1060B000F723BFFCC96041727A42F023FE1901FF49 -:1060C0004EC6EF1BF0780ECFEFEC34F80D708FACAE -:1060D000BDC43E640F4C407DECD5A39C2AD10F5427 -:1060E000AC407B1CE6C375242023E4EBDACE3F9F53 -:1060F00096609CA424B2C5081BCD7E19E769D35DC8 -:10610000193A37CC2359FE42FDDA6C13E8FC1353DD -:106110007EA4A0FC695EC81C5113BF4DCE3392F320 -:10612000CF0A7F6544FB6F0479AFDA7DCC3D361E24 -:10613000F90BEF82F30F973BCBA733F127F842C05F -:10614000556BDCB146E8BCFC666B2A9EFF63A4B3CA -:1061500058A4BF53DA51B0AFBA5689F0568FF483C2 -:10616000FE15EA37A8EFF70A39F27C77F1A8442C3C -:10617000252B702AABEE94AD7E68AFF6717ABA8E9D -:106180006E84FCA869E3F2E33A3A6A0338C44EAB82 -:1061900047BA5261C0F7C9A0FC987A0DF6FBF234F9 -:1061A00026F4955BD05B4E5C1FD0CB2053E22C399C -:1061B000217A4BE2F6962A576EDA0AA23E64DDC9CE -:1061C0001E23D386AC7BF35E4B183CD59B1AD6FFBF -:1061D000073E25ACDDE6CF0E6BCF3F610D830BBBD9 -:1061E000A787F59F76DA1E06DFD25716D6FF8717E8 -:1061F000CAC3E0C11C38CF3076C7901E4A95C2FA98 -:10620000CF514C61F3CFCB8E0F8307CDE27E841D3F -:10621000A8DAA75FD8B81D1459AAF7FB136BF83A90 -:10622000AA5FFCD3E9E1EBCDB787AFF75DF1B21B15 -:10623000EC7E2DD8F57B413F62F902D8FF5AB0EBD6 -:10624000DBC0FE47F825B0FFB1F482FD8FF5AF80CB -:10625000FD8F703BD8FF081F047F05615F531995C0 -:10626000879ACAA9FE46F7D725D63D21D63D29D61D -:10627000FD47EF492D9D6593345F009FCE4CB8A834 -:1062800047396C6FEC2BC538C0C05B32DB810CE248 -:10629000F09C684A447D348AA1DDC2CA07DEC63854 -:1062A00045FD8189968D0AEAA1FF7C07DB03EDB2EB -:1062B00082F2FCA8EF83589CE7CA17C087F938EE32 -:1062C0008358F48FEBBE64046F847605E039FB419C -:1062D00030903D03720DFB67AAB047CFA02C6FDB57 -:1062E000AF477CD4EEDD4FED6F7975E1ED7B5BC29E -:1062F000DA2DD81FCA5AAD87FCFB4B3E753E3FF5E1 -:10630000AFCB94EC68175FDAFB9FC9CBB05FDBBB08 -:10631000C9F77DCB7D7F72F0C51C94EB4ED0C37E58 -:1063200073701E67874EC07CDF7599FB4B1350114D -:10633000B4496C121457D826B60AE45DADAFB50E59 -:10634000E5506DF6221DCB207924E20D206DD15E43 -:1063500042E71EEEEF8AF7D3D8FB60DE37BCC76F8B -:10636000B723FE3A8FC5E2BAFDED72983F73771EF0 -:10637000B75BEFCED313DEAEB41F8B55A07D83F792 -:1063800018BF6FAD9FCE7D54C0FD50D23DFB643A27 -:1063900077F5171ABA7F75BEFBF3649A678E6F5252 -:1063A0000C9EABC7CBD773E529B4CE9CCCA595B8D2 -:1063B000FF93A90B0B65B2F34030A35C9D32AF1580 -:1063C000E303B55ED93E9CBFB546CCDBA5E374F8CC -:1063D00056E6AB5D63803E4E968DB291CC17FD7E46 -:1063E00093C7EDF152BD2313F5428F5989413A7E8F -:1063F000B86C620CE2F52896585FB653EF80B2A6EF -:106400009DAFD763E98E457AEB69CF97D16E51E79F -:106410005B89EB1686D0F510DEDC84A72A4F8B193A -:10642000E709E28FD7BBF2B81D7ED2F3EE5D68A715 -:10643000F464475B112F5D7A46FE6D2DE015F54142 -:106440004F675A0BDE83BA9E4BE0A33F5B43780D48 -:10645000F874A2DFA25616D64FC7F1B52B7C3F16B3 -:10646000CFB97F5B847AE959B0ABA1BA4ED7908C93 -:10647000E7FF787BF8FEAAC43DD7E9FCC9C921F43F -:106480005AD731C42F66A2EF0E953F14C2A78AC710 -:106490009E6C6EB7F5A41A3CE82FD6ED6F25BABEF8 -:1064A0003EBED39D81767EDAAF8D1437BC913FAB73 -:1064B000DA01217E0F433F4E5736B1503321A8EF0A -:1064C000AFD9EC2FE615A23F544EFE5E0F1B588647 -:1064D000CADF8976701CCADDBF3D85EB0EB683BD71 -:1064E00007EB3A8DBEB91F829D35680546817D0F49 -:1064F0006ED779847F6246FB7499B04F3F561C4536 -:1065000032E857E71A0D9DAF2E278ADBB5424E7E43 -:10651000B23FE3A748AF7527648B11ED50F05B08DD -:106520006EE37641BD37E3DF67A0BDDDA6233B40C8 -:10653000B53B9CC2EE382FECD9F36B06F464AF1E6A -:1065400096D813B08F2ADFE6AE346877E6CC257B89 -:10655000D529B751FC71F9D670BBA0DA130ED7EE6E -:106560000D879D117683EAB7F5E40DD90F93D1FF1E -:10657000289167A4201F7C2CF0A9FA232BA75A533B -:1065800090DF376895B96A3C00EFC975F8D56ADCC9 -:10659000AFA72ECA4A7EC1AA43749FFD9F71BFA3B5 -:1065A0003F9571FB88F17BEDF771FA76E924EE6790 -:1065B00000B9D27C46C9B3069AFADD83B124971894 -:1065C0002B437E685CC8FD483BC65CA1DC9727E294 -:1065D0004511FAF2566D9F1C1F221F3ECB9B40FBBC -:1065E0002FD63307EAA9953156D25BE38DDCDE2E38 -:1065F00059EDB5211D8C07FFD81012CF1E6F1E90CC -:10660000B0DFAE8778FC5CF5EFE76B2DBAF810BD14 -:106610000792276C7E90247CFC8DE6B7C0FCE6E0F8 -:10662000FC70DF7178DF9F1658491FA7CF67AC9BBE -:10663000F8B181F8513DCF15A0B362A0338C9920F9 -:10664000DEEAB61FA138B09375933F521ACBF751CB -:106650008AFB41388A97967C2E37CAF3F9BD350BF1 -:1066600058955B6FE5DBE3F3A1DC9BEF48CAA77AA3 -:106670000BD1E54A412B60A7A4F40D23771BFFC281 -:10668000FDAA4F810F90CFEF699094CC303B88D317 -:10669000B78B57B1CBCCDB3B03EFC16DEFCE4E4692 -:1066A0003F8AF3D59255262533844E5D48E7702FF7 -:1066B0005596EA1FA3DDED5895AC60BCDF85743FAD -:1066C00001AF91D37522FC43FFE23A3AF786C3F05B -:1066D000B71DE9AB9E19ACA8475CBEC876AB16E304 -:1066E0003AF9F9C0073707F9205DD0658B43F2A06E -:1066F000DC6FF94ACBE3588B258A5BDD0995489717 -:10670000F487FDAA667A70FE3B01447F886D4924B8 -:10671000BEA14690233F17E7BD53EB3F827C7C5CD4 -:10672000E7CDC078CA7127CFEB2C646070807C59AC -:10673000CCBAA9EC8DAE3FE0A7C9DDE3D06F7ECF28 -:1067400061A0384ECBDA1D31284F73D95ACBF96C82 -:1067500054EE6CEFB5FC91ED0A2024765EC50BC5B6 -:10676000853611FE55BCEECDB7CF47FC8F34BEF653 -:10677000AF076E4797A2F681567D0A279BEEECA2E3 -:1067800020FE5CCC9B8DFB55F135843FD8F358B887 -:1067900087056CA008FD1A156F46F8371CDED4FB80 -:1067A0004CD70DFC0CAF0CF412C997487CAAF75BD0 -:1067B000CF1A743CCED5F0CE42E87FF75A8D82F6E0 -:1067C000E175F8BD011EFC26DEE48F91C8DF1C09CF -:1067D0002F2A3E54FC9C8EE7E34EDF23539CEEFFB2 -:1067E000355EDECA773CFA6DFC18C97F23F1DB9277 -:1067F00055117C19C17F2ABE1CAB6289CF543CD68F -:10680000298CFCD6BACE18AB8705F167867F883F06 -:10681000CC53503CA65D62CF48DF850FFB28AF11FB -:10682000891FA00D3BCAF59D11FCA7E26D24F9A3B9 -:10683000CAAF33CC7FDC22517E80F3E7AF0C1ECC95 -:106840002FAAF901350F704CC8BFC8F20CD81D989B -:1068500077D998DD9384F65AAF5E9D87E71FCFAC5A -:10686000E91EB702C69F99C9CB5EB4D342607B14C0 -:106870008FC39D196D70E3BD9D9126CF423D7E462D -:10688000FAF5ED1C4ED12B082F4C996501B857A78E -:10689000C6ED1E1672D843E59985D38AA99FC4DE3A -:1068A000C4FB5024564EEB48524219ECE7CC0393FC -:1068B000F29A59F0FCAFE4737BD62BE4F9501CFB41 -:1068C0003712C5B197800AB060BC7DD6D36513A0DE -:1068D000FEEC83136D94FF6B0C5F1FF56806C50714 -:1068E00037D37CB77E31A05B9A13DCD790FE2BBEEA -:1068F000CAEB2B27913F512570684F98CCFD58CF9C -:10690000C438D447AA7E1A3CF1AA39347E7911F4EE -:1069100017D387C0931F4F0FD56F4776FF3E0BE706 -:10692000A9D2BB73AD507FA1E50FE9680754ED7E96 -:10693000348BECD2DD1BB2D0BFA8DAF1FB2C3BC10B -:10694000D10EF26FB4FCDC97F7DDB27363881DFCE7 -:106950006021F70B161B8F94A07D3AF7E64F1EC1FE -:1069600078F8A407258A8BDDC3BA1F41BD5991CDA4 -:10697000F9886D31925C87F928EFD83AF927BB5036 -:106980009E9FCCFE405709FD4C055ABA8F0AE67906 -:106990002C05E361EB258A8705FB8FA33CE6D2B586 -:1069A000923E3511F561BC4D56705C3CEDE3DEF571 -:1069B000B62EACAF58CDEBE71A3CED3D38CFD37ACD -:1069C0006BAB8213954F280FC90B9B0AB8DFB5E458 -:1069D0003189EC71759D494F25B7849ED35420F4BD -:1069E000F98C6EE2FF9F0ABCFC78F5BB6FA62A9873 -:1069F0004F72C41540FB3B4F9ECF44F9559C7031FC -:106A000007E97C92DEF14C359E7B8781E28705B9F0 -:106A100069720AF4CFFBE5CC27B05CB27AE933D5D2 -:106A20001807DD6A243F4ADD5FA3A468D0DF3CD6A7 -:106A3000F28B7BF1DE2E3C69243BBAB1E5A614361D -:106A40000C9FAAE51EC0BF92C5D8F34D462A5F6CC5 -:106A5000B230058EB8AF2995E0979B142AD9024E23 -:106A60005F8DC25F1D69BE7CF0F715905705EB6125 -:106A70003EB0376D26FB143CE7A429CE1D1BC4B9DC -:106A800026C1789B3B6336DE43C186155D688A2646 -:106A900017F0FCE2DB3DEBD3C98E5E7DEEB96A6890 -:106AA0005F5A509E5F00F76DDC7E95FCFC631D8F86 -:106AB00056505C7F87819F4F9CFBC2935929CF60C2 -:106AC000DCF52D1DF9DFAEEDE79EDB00E57D8FAD3A -:106AD000D087D2FB773DAF4DECE7467C35D23D7C8D -:106AE0007FBEFA7D3AF1CF0EE0AB9C7F9CAF5CABF2 -:106AF000D7D0FD3D5A507E37DEFB059D3B1DF9E9A1 -:106B0000C2E41F119DBB0F4B74FFAA1C57C72F1067 -:106B1000E7ADD5781F237B50C8F1CFC1F3C3FB3D50 -:106B2000D2F17116DAC39FFB167EEBB90F36610600 -:106B30001DE35A462A23DB8BF48E8956385F9186F3 -:106B4000DBC191ED0F17A871719E6FC73F8C0BD7FA -:106B500009FDE9848DC525A0FE93FC51B998E7B8DD -:106B6000EDA216FD2FF0EBDE0FB72FD9FB217A7CBB -:106B7000A4FDDEA8ACC779B441B93BEDB486F943B6 -:106B8000F4F62D7D51CC1FB2EE90DF01757ACCB3B7 -:106B9000748C26B98078C3BC4CA063F20E842FEAB3 -:106BA000391E0307C1BFE27115261705CF79B1E37E -:106BB000722ECAD9C8F3D61FBA4CF451E77BF4AA97 -:106BC00044E79F73519B7BE3F31FD97D3917F1771E -:106BD00051D757847E5440DF978B78A87F9DCBF3A5 -:106BE000EF7B0F6A7DF57A3D8FEF4916F2074BE494 -:106BF0002BE4C7074E703FBEBE6327C9D3C14E1EEC -:106C00004F7169BA4B5330FED070AE0BE5D9602A94 -:106C1000F7AF607E3BDEDB8C89420F6A07D2E783E9 -:106C20005C3B2AF2B5AA5F7701F9578FF378EBE85E -:106C30003D526E3443BBE212F233D457ACCA58878C -:106C4000747EC193849120F676EEFFD453FCED8DD3 -:106C5000688B4C762BD486E06FE81C1E993F9C61B4 -:106C6000AA9F1ECDEC21FD5C7AE5A7E41F9FE47985 -:106C700032D714CE4FEC10E727E7DA23FAD490F995 -:106C80005E52E587B01FE7BEF13FC497A76CF6538D -:106C900028CFA25116E27CA9711E4912FD8A827981 -:106CA0004073A7F0C7CB646A77F964361AC7A4C6E5 -:106CB00050BEBE8C6DD2A2BD3B977967F077327D16 -:106CC000FFF643689FF7869C8FEFB1C07EA6FC71EC -:106CD000699423B311ED238D24EED55B303F549F8F -:106CE00015727B6B862C911E1B181D4D76CA9C0558 -:106CF000CEC5B85FB55F9996EB339887EC2CE61953 -:106D0000C8C57C26F30FE4629E53ED77D71BD10DE7 -:106D1000A41799B7E0AE9075C61472BDF929E69F25 -:106D2000419EB844FEB344FEEA29F4A31A0FF33C93 -:106D300061AF26E33D7CAFE5867B46BC5E06BCDAF0 -:106D400051FF3898DD8EFC3335C983FCE3DA2731F7 -:106D50007CB756DF61D881719D7A5D5F32D2F306D0 -:106D6000DF5FF548CFAE03EFEA95A9389EC781C033 -:106D70005ED7E0FDBA84FE72FA6E7A0FE36ECE1330 -:106D80005C8B3AB5EF925F5FDBBE9FFCF73AE6277C -:106D9000FFBDAE2D9C5E0653799C3D923FC6142AE2 -:106DA000617C31672BE78BBB64D680728E89B8E932 -:106DB0009CD414B24782E3849D285F7E04ED97FE45 -:106DC00009925582A9FAA3DC6BD12E7267717BA65A -:106DD000FF4F2F162C23B9E229F819BE8B11F6EEBE -:106DE0009CF59BB572C87EE674F238617F14AB3AAD -:106DF00048F8768C453CA4E7958F2DE4EF6472E962 -:106E00009D8F86C73523CFF1AC88E39CC4384F4EA5 -:106E100070DFF3D2D2B81C631EA29F2E0D5F5F7D80 -:106E2000F7A28E5F21E869C81F92787C6A24B98234 -:106E300079944A9147A91479944A9147A91479946D -:106E40004A9147A91479944A9147A91479944A918F -:106E500047A9147914AC3F895BA5F7703B9F417A31 -:106E6000E8421E1B13847B1322E031E1FD7B13A457 -:106E700070788C44FD8B0B773EE3CEC138A645C8B5 -:106E8000252506EDAF0B261E5FEA8871CC2D84FA0E -:106E9000CA39CDBBF97B443BBD67294E58B818F9B8 -:106EA0006B30D1C0500EB90B1DF3111F274ECCCE45 -:106EB000DC4CF2D164C53C77EFDD37C7515CEE2D79 -:106EC00099C9B0E4CCECFCB50500CF344B44B720F5 -:106ED000277E50AEFA9330CFEC4E9ECF2891EB2A0E -:106EE00071FEC6D1A67C8A6BE53B161586C40F4A97 -:106EF000C72CCF443BA84BA7BC87F154F75F740C59 -:106F0000FD2835FEA6F6EBCD9B598DFB9A933D717E -:106F10006D1ECA1B602E946F763D6BC37DD935D133 -:106F20005233C92B458BFC5F2DF03D4BE1F6B05F32 -:106F3000AF6813D06F8F9A99E85678BEAA52E4AB27 -:106F40002A45BE0AF1730AE36650BE03F55876433C -:106F50003D9691EFB9761794AF24BA6503E9A1EF96 -:106F6000C1E6225F7139938EF4FC8288C367178A69 -:106F70007769F9E50FF2715E9AA756C4DF2EEBC26E -:106F8000F378EAB8E07846E51D3FE0F299C5E9F903 -:106F90007BD7B1CC8DEF69EF786D34C593021E8D30 -:106FA0005B170730F038CA2FF61AF76F592AE797A0 -:106FB0003B5E4DA17ECD220EEA4CE8CE4A40BD2B71 -:106FC000F84A850F7EC3DFF938F30086F275899F92 -:106FD000CF794777563CC001C9A4C1F8B873076F91 -:106FE000EF117CE79C20E613E761466F3AE2A3FFCE -:106FF000F06BE9F702BCD1EC5FC6E5BD3F8BE43432 -:10700000F367E17BA1CB92F72CBEB7FDF5C17F59A9 -:1070100084EF6B2FEBBCCF21FCDB8333382CED3FAF -:107020006B096D4FF2A6E37BDC5F1FFCE1227C9FC6 -:107030007B3969FF73F1D61058F7CA596CD73F3CBA -:10704000635131F49F67F09C6842BA7999D397698C -:10705000DF81F3783FB51DDC5E9FB5EFC0955750DB -:107060001F1F88A17CBDAF3083EEBBB963CF6348DF -:107070006F81FD3AE2838D6D7F7DEEB7D4CF4061A5 -:107080009479066F01865CDC457FBB1BF7352FDAF0 -:10709000FB19C29B8B6EA37DCE1BC5F9F9A9A2B9C2 -:1070A0008B903F0307F6FD0AF96F5E1C18B2B89F7C -:1070B000174D849F9A572717631C2010D35D81F3C7 -:1070C000D7BF60B0229DD6BC9A320BE302C70B79C2 -:1070D0007CBA7ACAA674D4AF9A43CFEFFE2DC629E4 -:1070E0005F30517EC695C0EDBB1AB9A56805E16F4A -:1070F000E76E7C371278DE4479D26A9803D7ABDE2C -:107100003D89E2EAAF7FFD4105E2A144DEBE1BEB13 -:107110003FDB65D2E03DF4E8ED713F423EECD191BA -:107120009F592DE0EADE517C3FD17DA584BFC44D3F -:10713000E9A85F6B46FDE676DCF73C79D373E8E7B8 -:10714000B03D06CA155C7C1EEE0DC65D6CD5D12B1C -:10715000D5C0F3315AA497CBD2A68A6770FE56DE0B -:10716000EFB26913DDA7BBF52686EB413F86F2EA55 -:10717000B2B439ACFE62EB9E5CF4432FBD308FFCA1 -:107180005195CE557EA9D96508D387240992C57B30 -:107190000952B36E66063D5B2DC04B07B7059E6175 -:1071A000C1F197DA747E3DDC51B581ADC5F7C12AD6 -:1071B0003FD4A4DD5686E7ABD1B464A1BD529DDFB8 -:1071C00057817C71D1C48CA9F88E4EE8AB9AF63504 -:1071D000F3D1EE1D693FB1E25DDFE7820F3FF79922 -:1071E0003CA1F9C1C8F26F4D4C3915F26EF89E06FC -:1071F00003D9EEEA7C6FEBBD75E89FD52770F97176 -:1072000016FAB7811C331771B9B76455787FA9880E -:10721000BF4BACD7F765A1DE53E7FFA650956B7D5A -:107220005928AF22C7CD9385BC7951227953D32EEB -:107230009D93E19E6A8C6E0FBEDFA94167929F53BA -:107240007B4DE2E3528BC4BDC3D8A78B3268DD9A75 -:107250003693DD04E36AA3FA62D11EAA8BE98B455B -:107260003B277048663B04BA1293057E2608948536 -:10727000C41DABBD3ABB2977183CA3DD84EF73F086 -:10728000BF61FDB622CE2755BE685A8F59FA8A9043 -:107290004EABB6878FC3735942F82FE0DB991CEAD7 -:1072A0008FDBC4BEFBA573C427FD5FBF9F8E78AF85 -:1072B000D1B0B59847BC24F1EF1E00A6EF1E2E8971 -:1072C0007C64CDDFCD51482F973EAF23BE0D487D66 -:1072D00024D7CE1C5C407229A0EB23B9D65354416D -:1072E000F22110DF578172EACCC17ADE3EBAAF429A -:1072F00081F64E84B17D1C237D7FB9E801921FF396 -:1073000064FEBE81EDD459781C687D6F13F9153A7F -:1073100025D4EFBE52A4E66DF4C173CB41BE093053 -:10732000655F3BF2619599E239603FB5BD8276DEDB -:10733000C2642BC6C5AB701CA7037D68FE2F31E16C -:10734000CB65889F45718E3B8B308F9DD347FE0365 -:107350005035D9E9F57F32901FD9AF1BD88D722AED -:1073600037CEB1B008F651A7EF5E87A1A72BBABE02 -:107370002ECCFBCD95B93C627B385D057276F2EF81 -:107380002444FEB0BA88CB5FD05BAC05E942E2F89A -:107390003DE67BF514CA9540F74492C7917C73D1C2 -:1073A000F7442CCA87D3A0C7DD217EFEE9A57B2840 -:1073B0004FBF00DF654079EFDA707A18FCEA67E4C6 -:1073C000EFB1C742EA910EB784C3917484F4E80F19 -:1073D000933B6EA29B3D82AF6A6775D7E33D0CC1BC -:1073E00077002C87C04723E088FEAC9CDB097BF04C -:1073F000BF61DEBA71FE5EF2CFF7F177B1CDA0BF0B -:10740000083E104D7963CD3ED04F895C3FA15EA808 -:107410008DEDA6B854E08081F2230F777C4CEF19F4 -:10742000810E29FE52DBF15A32FAED3EF4139248F6 -:107430000F26D33B95031DC9E86FA8F5751A6F9603 -:10744000788F4F76BA5AEF94FD59B8FF5AA93B1777 -:10745000DB7D8516D11F60196146E7A89338BFB35D -:107460000E99E47924DEF60A7A05B9904BEF2C0EDA -:10747000F1B8802A07AA853C398AF5399CEF2D6A34 -:107480005E49C2F772D1C3CA879B8A547BB881E236 -:1074900036BB8A147EAF623CCDCBE34AD45EFFFAA2 -:1074A000E5DC0939384E11E342E4D0C4A05C41FE6A -:1074B0004F25FE7F58970CE7AA794EB236A39C5A07 -:1074C000BCA614BAB3E5DA15A5142F13EF3F23F7C2 -:1074D000154947F6228EDF1A4D7C4962C87C97C059 -:1074E0005D4FCD233943EFE8EF4F7CBC14E313BF6E -:1074F00058BC99E87948DF84F2399E673B97E3C826 -:1075000036D734D7D3F1F286967529C3EC23729F10 -:10751000D58E96D264E5FA7A75BF974CEAFE66E995 -:107520009242EF61C19AD22428971BFFD17BE0E7FA -:10753000BDD461F0A35EAD5EBC625DDC3074739D52 -:107540003ED81EA2BF26207E3D94D71869FF9165C4 -:107550009DE4EFC5381103BE6A25FE027E09D10BFA -:107560006542BF0EC51BAA968E47BF9339968E47BC -:107570003D037C55611DC6AFC42F4B34F476C34D1B -:1075800065E47E3E2BE271D2B222CE2FA76CF66F5D -:1075900050BE8EF4BD85619AF4ADDF5BA46906DF51 -:1075A000417E4B4B8E51300F54323B9AF73B6CB2BD -:1075B00060DCA6FFF09714D7ED7FC4BC80E70BCC4E -:1075C0006C34B477A54EDD11AA473CD3385F46171B -:1075D00070BBC595ADFBF6B8504ECC505C88EC86C0 -:1075E0009C68CA93047C9F92DEEAEF2CB4603E2331 -:1075F000D00DDE21F093EBEBFF4A46FD1AE8FC8844 -:10760000DE8305BEFA98DE896D10EFF48EFAC43B76 -:10761000AB6E2586BE8B2BFBA014FB6D1465303E34 -:10762000C0E35A6AA9FAFF21FEEF946985C3FABF45 -:10763000090E73685C4049192E8E121A17C8D4F2CD -:10764000B800961817C8CCE4710184312E8025C685 -:1076500005B01EE30208635C00618C0B208C710195 -:107660002C312E80F59F89EF1FFA4130F178A599D2 -:10767000E4FA4A7CDF0EF7B7F230CF3BAD6C9529C8 -:107680007F8BDF3FA07EBBEEDD4CBB7837E3DD4C6C -:10769000793CD701D98A2872E9068E631CC7B55F89 -:1076A000B2AE41B9D2B480D6DFD059F8DE62AC6F49 -:1076B000D559350AD111C7638B44EFF46B3A5B2976 -:1076C000EE549C72584FF56D12C338E95D06EEE733 -:1076D0003A65A8CDA33C28D9C14E4337F91FB57BE5 -:1076E00025A532F49DC6F4AB2407D47CF232DEC467 -:1076F0009C5E935239CC3B90A177E7E2DDF432CC2B -:1077000033E37B71F92B7AD7EF04877414D2E156F7 -:10771000FEFED902FF88DF23DE35D574EE5F87EFEA -:10772000A122F3CD43DFD345E49DEBA789BCB28D05 -:107730007F5F51F664E5BE03B0DEE02603D91BEEA1 -:1077400042C703D39230EF6FA7F8C8F1C326F28B7C -:107750003EDC7C53587C84E53B1E9C46F9F9B11411 -:10776000AF68D449A48F67974D4CC17B9C7D42473D -:107770007AA737AF7C35F66B9CAA503CAAC4C01ED2 -:10778000A079C47B29151F25CD924703F05266A529 -:1077900077F64BE09A305ED9AF33AFC7774D4B18D1 -:1077A0007FE7A0D24DE36689E8060304789F15E2DF -:1077B0003E9774FEF94B7CC7709F81DBAD691A9EC2 -:1077C000BF4EDBC8DF33DCCF1C7AD4B3CB91BA64B5 -:1077D000D28F7FEA837A47F4D8746E972B2938FFCB -:1077E000D2933A7A6F5B92F2932C07E9E9627AC7F7 -:1077F00020F917C9D76E1E997F22DF311CD771B9C6 -:1078000002F748FE5017D225C5651C549E6CAAA2EB -:10781000F277E27B88EBDFFF0F9C453F312D25C6D9 -:107820008A726EC4EFDDA2BEFD7BAF17C4FBB53418 -:107830004D4FBE82F7F177B315EF437D2778CA56D7 -:10784000BE1FF1648F656E0B7D0F061210EEB5142E -:107850000F22615CDB6BC7EF8E060E4B167A977CAE -:107860009D7CDCFC08BE1371654A1649C1F8F7A679 -:107870009264D877E9840CDAB7CBC7E3A37443C921 -:10788000183FE7F84ACF731C9B5618AC9F27F82681 -:1078900000FD399DFCD083F4F61DE2A6BBB0BF9B72 -:1078A00099E87B6AFA83FDCCBB791CC54F55BA19A0 -:1078B0006C4BD98174F39E90FB8B17BFAB43FDDFFC -:1078C0009BEFE8C17D54545E7D2499CE377CFC4A01 -:1078D0007DA71E19BF0A959FFF3FDEA79F6A6AA07A -:1078E000F29DA655547637B9A93D44FE5F1A41FE74 -:1078F00047C63FAF227F47C63F99518923FD09FC08 -:10790000CDE3CD11F1CEB251F7AE87FB9BBD456FF4 -:10791000C52A35FE89EF87579A491EFCF7B461E303 -:107920009EEABD99294E3AC84C7978FFB3B2276ACE -:1079300035D0AE9DCEF1A7C61D913FF07CC81F5833 -:10794000227F68B541FE78560F2C5CC0F5BC9BF4D5 -:10795000BC89F0BA6E0DC80F80EF639630F97125BF -:10796000427E80C371377D57D56960182754DF5137 -:10797000CE82E28BBC61E48997CB937151DEE7E95B -:107980007BFFFA287A9F7B5CBC873BBE81BF87ABBD -:1079900064E5B4EE30722516F171DFA881B37F8003 -:1079A000FEF7FDDE4CF6CABAD1CB8AFE19B9724D8C -:1079B0007CD7F234FEAE80F6DB7E57E03109F3A1CE -:1079C0008DF7301BE259FD5D811491CFFE1EBF2B58 -:1079D000306D7AE177FF5D815BA78F5F1CFABB0298 -:1079E000B7FA3238ACFEAE001BBF7884DF15983D85 -:1079F0003DE9FADF15B86D3AF71747FA5D01B02790 -:107A0000CB705C92CD3E07CB34B1CFC8EF694F8AC3 -:107A1000FC5D97C6B118CBD258B796EA359E02FAEC -:107A20000E5EE3FD25F981F98E9FE3794B9FB04D02 -:107A3000C90638CDE02539D99B67BF13EBAFD9EC28 -:107A400077E13A917173C42DFAF7B09FBBB13DF263 -:107A5000DD958ACF15D3B9DC6814E58CE6E1BF2744 -:107A60006F9CCEF3F237DA37ECB706D71BDAFFA6F6 -:107A7000A505B81FD86F2DD6C37EEBB064E684B0E1 -:107A8000EF53AFA73337D155E3744E5F20CFE67D78 -:107A9000C8ED412AB3B49E78B41FC73CE489C7FD42 -:107AA0008E691930E177107F740F9850BFFF71F520 -:107AB0008009EBFF68E7EF9523E77F793AF703B298 -:107AC000660CD0F8F168E3937D3E108FF65356D5DF -:107AD00087EB28DFB27732E997F142BF8C7F68826B -:107AE000AF0FE86DFCB638CA67B3E2446AAF3172D3 -:107AF0003EAD79A8F2E00185BEDB9AF76188BD331F -:107B0000D903FB0EB3BFB483FCDD25C0784F7B7572 -:107B10000423CDA27DE564FCDDE5182137D04E5B62 -:107B20000C72C159F5E69794F7C7F1381FE66891D2 -:107B3000FE7CBA41F17D9A05FDD0E50BD674915FCC -:107B4000B875A85EF899FBD7A1DF0CF65B587D4DA0 -:107B5000E5912ED437B57BC3EB9D0D57C97F05FB4F -:107B60002DACFE9E5F9ED3F3DF2F08AF07FCEE45E2 -:107B7000BA54F17B5CE79D8C7EDE71679495BFDF24 -:107B8000F7D2EF95EC10DF3FEFFC8F599C6E04BEEF -:107B900061BC3774FCC8F4D14CFDDDB35836F2C378 -:107BA0008D4A552E0DFDFE899EB929BE373786E4D4 -:107BB0008E4BF855F59516D2F369F546925F25720E -:107BC0009415E1A1DF3F2993859CF212FFF7DC1E9B -:107BD0004F713C3A00C2095329EF93DCCCE1812478 -:107BE00003C987124D79DD1E28DFD4847FC7FE2CA0 -:107BF000CA0719F9977F87E9D27BF977E25AA5106E -:107C0000FDDC66C9BE0DBF7B6C96441CB1DA4CF935 -:107C1000827E8C2FC279B6C47BB62D8375B6DC9973 -:107C200043F6713FE3F2D4BD80E7ADB6C4972F5E53 -:107C300081ED0BA750FBC16F263E5E80F653759415 -:107C400015EDA72D366E5F6F999F4DEDAF4BCA1A9C -:107C50003CB7FB2146EB6C99CFCFBDE5F171E2FB60 -:107C60000B8F09F9794B8B7D34E6A366591C1710ED -:107C70005F63443E6E4B06D443F99454BEF07E9C41 -:107C8000672ADFEFEF6C0AC98FE30BA73CBE5B21CD -:107C900035E2C7BC906B6E0CF9C1FF0BB81F749432 -:107CA000704700000000000000000000000000001D -:087CB00005020D0000000000B8 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex deleted file mode 100644 index ea3e254335b1..000000000000 --- a/firmware/bnx2x/bnx2x-e1h-5.2.13.0.fw.ihex +++ /dev/null @@ -1,12849 +0,0 @@ -:1000000000003BE8000000600000068800003C5053 -:1000100000001968000042E0000000AC00005C50E5 -:1000200000008DF800005D00000000E80000EB001B -:100030000000E3140000EBF0000000940001CF0882 -:10004000000058E80001CFA0000000C40002289082 -:100050000000F9640002295800000004000322C0D7 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:1001800002040014000000FF02040018000000FF39 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200204203C00000000DE -:100240000204204000000034020420440000003575 -:10025000060420480000001C020420B80000000131 -:10026000060420BC0000005F0204223807FFFFFFE5 -:100270000204223C0000003F0204224007FFFFFF6F -:10028000020422440000000F010422480000000084 -:100290000104224C00000000010422500000000074 -:1002A0000104225400000000010422580000000054 -:1002B0000104225C00000000010422600000000034 -:1002C0000104226400000000010422680000000014 -:1002D0000104226C000000000104227000000000F4 -:1002E00001042274000000000104227800000000D4 -:1002F0000104227C000000000C042000000003E840 -:100300000A042000000000010B0420000000000A85 -:1003100002050044000000200205004800000032F1 -:10032000020500900215002002050094021500202D -:1003300002050098000000300205009C0810000033 -:10034000020500A000000033020500A400000030F8 -:10035000020500A800000031020500AC0000000208 -:10036000020500B000000005020500B40000000610 -:10037000020500B800000002020500BC00000002F7 -:10038000020500C000000000020500C400000005D6 -:10039000020500C800000002020500CC00000002B7 -:1003A000020500D000000002020500D40000000198 -:1003B00002050114000000010205011C00000001FB -:1003C00002050120000000020205020400000001F5 -:1003D0000205020C0000004002050210000000406F -:1003E0000205021C0000002002050220000000138C -:1003F0000205022400000020060502400000000A59 -:1004000004050280002000000205005000000007E3 -:100410000205005400000007020500580000000813 -:100420000205005C000000080205006000000001F9 -:100430000605006400000003020500D80000000665 -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C000020500E00000000D020500E80000000742 -:1004D000020500F000000007020500F80000000718 -:1004E000020500E40000002D020500EC00000027DA -:1004F000020500F400000027020500FC00000027B0 -:10050000020500E00000001D020500E800000017E1 -:10051000020500F000000017020500F800000017B7 -:10052000020500E40000003D020500EC0000003779 -:10053000020500F400000037020500FC000000374F -:10054000020500E00000004D020500E80000004741 -:10055000020500F000000047020500F80000004717 -:10056000020500E40000006D020500EC00000067D9 -:10057000020500F400000067020500FC00000067AF -:10058000020500E00000005D020500E800000057E1 -:10059000020500F000000057020500F800000057B7 -:1005A000020500E40000007D020500EC0000007779 -:1005B000020500F400000077020500FC000000774F -:1005C0000406100002000020020600DC000000010A -:1005D000010600D80000000004060200000302200B -:1005E000020600DC00000000010600B80000000068 -:1005F000010600C800000000010600BC0000000069 -:10060000010600CC000000000718040000A900004B -:10061000081807C800070223071C00002C2C000044 -:10062000071C800038930B0C071D0000293119317D -:10063000081D686052F40225011800000000000047 -:10064000011800040000000001180008000000006C -:100650000118000C0000000001180010000000004C -:100660000118001400000000021800200000000122 -:1006700002180024000000020218002800000003F5 -:100680000218002C000000000218003000000004D6 -:1006900002180034000000010218003800000000B9 -:1006A0000218003C00000001021800400000000495 -:1006B0000218004400000000021800480000000179 -:1006C0000218004C00000003021800500000000057 -:1006D0000218005400000001021800580000000435 -:1006E0000218005C00000000021800600000000119 -:1006F00002180064000000030218006800000000F7 -:100700000218006C000000010218007000000004D4 -:1007100002180074000000000218007800000004B5 -:100720000218007C00000003061800800000000290 -:10073000021800A400003FFF021800A8000003FFF9 -:100740000218022400000000021802340000000019 -:100750000218024C00000000021802E4000000FF32 -:100760000618100000000400021B8BC000000001EE -:10077000021B800000000034021B804000000018B3 -:10078000021B80800000000C021B80C000000020C3 -:100790000C1B83000007A1200A1B83000000013806 -:1007A0000B1B830000001388021B83C0000001F4B0 -:1007B000021B1480000000010A1B148000000000CE -:1007C000061A1000000003B3041A1ECC0001022711 -:1007D000061AA020000000C8061AA00000000002AF -:1007E000021A1ED000000000061A1ED800000006E3 -:1007F000061A36E800000004061A36E0000000027F -:10080000061A500000000002061A500800000004FA -:10081000061A501800000004061A502800000004B0 -:10082000061A503800000004061A50480000000460 -:10083000061A505800000004061A50680000000410 -:10084000061A507800000002041A404000020228F4 -:10085000061A400000000002061A400800000002CC -:10086000041A62C00020022A061AD1000000000209 -:10087000061A200000000124061AB000000000281B -:10088000061AB1400000000C061A330000000014E4 -:10089000061A33A000000068061A81080000000252 -:1008A000061AD1C800000002061AD1D800000020A4 -:1008B000061A249000000124061AB0A000000028A7 -:1008C000061AB1700000000C061A33500000001424 -:1008D000061A354000000068061A81100000000268 -:1008E000061AD1D000000002061AD25800000020DB -:1008F000021A292000000000061A30000000000241 -:10090000041A30080005024A061A301C00000009CB -:10091000061A320000000008061A5000000000020B -:10092000061A508000000012061A40000000000263 -:10093000061AD0C000000002021A2924000000009C -:10094000061A304000000002041A30480005024F29 -:10095000061A305C00000009061A32200000000868 -:10096000061A501000000002061A50C800000012BB -:10097000061A400800000002061AD0C80000000253 -:10098000021A292800000000061A30800000000228 -:10099000041A308800050254061A309C0000000931 -:1009A000061A324000000008061A5020000000021B -:1009B000061A511000000012041A401000020259D9 -:1009C000061AD0D000000002021A292C00000000F4 -:1009D000061A30C000000002041A30C80005025B8D -:1009E000061A30DC00000009061A32600000000818 -:1009F000061A503000000002061A5158000000127A -:100A0000041A401800020260061AD0D80000000242 -:100A1000021A293000000000061A3100000000020E -:100A2000041A310800050262061A311C0000000990 -:100A3000061A328000000008061A5040000000022A -:100A4000061A51A000000012041A4020000202679A -:100A5000061AD0E000000002021A2934000000004B -:100A6000061A314000000002041A314800050269EC -:100A7000061A315C00000009061A32A000000008C6 -:100A8000061A505000000002061A51E80000001239 -:100A9000041A40280002026E061AD0E80000000284 -:100AA000021A293800000000061A318000000002F6 -:100AB000041A318800050270061A319C00000009F2 -:100AC000061A32C000000008061A5060000000023A -:100AD000061A523000000012041A4030000202755B -:100AE000061AD0F000000002021A293C00000000A3 -:100AF000061A31C000000002041A31C8000502774E -:100B0000061A31DC00000009061A32E00000000875 -:100B1000061A507000000002061A527800000012F7 -:100B2000041A40380002027C061AD0F800000002C5 -:100B30000200A294071D29110200A29800000000E3 -:100B40000200A29C009C04240200A2A0000000005D -:100B50000200A2A4000002090200A270000000002E -:100B60000200A274000000000200A2700000000059 -:100B70000200A274000000000200A2700000000049 -:100B80000200A274000000000200A2700000000039 -:100B90000200A27400000000020100B40000000185 -:100BA000020100B800000001020100DC00000001A9 -:100BB0000201010000000001020101040000000127 -:100BC0000201007C003000000201008400000028C7 -:100BD0000201008C0000000002010130000000044E -:100BE0000201025C00000001020103280000000075 -:100BF0000201607000000007020160800000000137 -:100C00000201055400000030020100C40000000190 -:100C1000020100CC00000001020100F80000000108 -:100C2000020100F00000000102010080003000001D -:100C3000020100880000002802010090000000006E -:100C40000201013400000004020102DC0000000186 -:100C50000201032C00000000020160740000000784 -:100C60000201608400000001020105640000003000 -:100C7000020100C800000001020100D000000001D4 -:100C8000020100FC00000001020100F4000000016C -:100C9000020C100000000020020C200800000211CD -:100CA000020C200C00000200020C201000000204C4 -:100CB000020C201C0000FFFF020C20200000FFFFA0 -:100CC000020C20240000FFFF020C20280000FFFF80 -:100CD000060C203800000002020C20400000003406 -:100CE000020C204400000035020C204800000020C7 -:100CF000020C204C00000021020C205000000022B9 -:100D0000020C205400000023020C20580000002494 -:100D1000020C205C00000025020C20600000002670 -:100D2000020C206400000027020C2068000000284C -:100D3000020C206C00000029020C20700000002A28 -:100D4000020C20740000002B060C207800000056D6 -:100D5000020C21D000000001020C21D4000000018F -:100D6000020C21D800000001020C21DC000000016F -:100D7000020C21E000000001020C21E4000000014F -:100D8000020C21E800000001020C21EC000000012F -:100D9000020C21F000000001020C21F4000000010F -:100DA000060C21F800000010020C223807FFFFFF9C -:100DB000020C223C0000003F020C224007FFFFFF14 -:100DC000020C22440000000F010C22480000000029 -:100DD000010C224C00000000010C22500000000019 -:100DE000010C225400000000010C225800000000F9 -:100DF000010C225C00000000010C226000000000D9 -:100E0000010C226400000000010C226800000000B8 -:100E1000010C226C00000000010C22700000000098 -:100E2000010C227400000000010C22780000000078 -:100E3000010C227C000000000C0C2000000003E8E4 -:100E40000A0C2000000000010B0C20000000000A2A -:100E5000020C400800000411020C400C00000400C9 -:100E6000020C401000000404020C40140000042195 -:100E7000020C401C0000FFFF020C40200000FFFF9E -:100E8000020C40240000FFFF020C40280000FFFF7E -:100E9000020C403800000046020C403C00000005F7 -:100EA000060C404000000002020C40480000000A0E -:100EB000020C404C000000F0060C40500000001FE7 -:100EC000020C40CC00000001060C40D00000003AAB -:100ED000020C41B800000001060C41BC00000003F8 -:100EE000020C41C800000001020C41CC00000001CE -:100EF000060C41D00000001A020C423807FFFFFF29 -:100F0000020C423C0000003F020C424007FFFFFF82 -:100F1000020C42440000000F010C42480000000097 -:100F2000010C424C00000000010C42500000000087 -:100F3000010C425400000000010C42580000000067 -:100F4000010C425C00000000010C42600000000047 -:100F5000010C426400000000010C42680000000027 -:100F6000010C426C00000000010C42700000000007 -:100F7000010C427400000000010C427800000000E7 -:100F8000010C427C00000000010C428000000000C7 -:100F90000C0C4000000003E80A0C400000000001B7 -:100FA0000B0C40000000000A020D0044000000325B -:100FB000020D008C02150020020D00900215002089 -:100FC000020D009408100000020D0098000000338C -:100FD000020D009C00000002020D00A000000000B5 -:100FE000020D00A400000005020D00A8000000058D -:100FF000060D00AC00000002020D00B4000000026B -:10100000020D00B800000003020D00BC0000000249 -:10101000020D00C000000001020D00C80000000227 -:10102000020D00CC00000002020D010800000001CA -:10103000020D015C00000001020D016400000001CE -:10104000020D016800000002020D02040000000110 -:10105000020D020C00000020020D021000000040F2 -:10106000020D021400000040020D022000000003E7 -:10107000020D022400000018060D0280000000127C -:10108000040D03000024027E020D004C000000014C -:10109000020D005000000002020D00540000000884 -:1010A000020D005800000008060D005C000000045E -:1010B000020D00C400000004020D00040000000145 -:1010C000020D000800000001020D000C00000001EC -:1010D000020D001000000001020D001400000001CC -:1010E000020D001800000001020D001C00000001AC -:1010F000020D002000000001020D0024000000018C -:10110000020D002800000001020D002C000000016B -:10111000020D003000000001020D0034000000014B -:10112000020D003800000001020D003C000000012B -:10113000020D011400000009020D011C0000000A4C -:10114000020D012400000007020D012C0000000721 -:10115000020D01340000000C020D013C0000000BE8 -:10116000020D014400000007020D011800000029D3 -:10117000020D01200000002A020D012800000027B6 -:10118000020D013000000027020D01380000002C84 -:10119000020D01400000002B020D01480000002755 -:1011A000020D011400000019020D011C0000001ABC -:1011B000020D012400000017020D012C0000001791 -:1011C000020D01340000001C020D013C0000001B58 -:1011D000020D014400000017020D01180000003943 -:1011E000020D01200000003A020D01280000003726 -:1011F000020D013000000037020D01380000003CF4 -:10120000020D01400000003B020D014800000037C4 -:10121000020D011400000049020D011C0000004AEB -:10122000020D012400000047020D012C00000047C0 -:10123000020D01340000004C020D013C0000004B87 -:10124000020D014400000047020D01180000006972 -:10125000020D01200000006A020D01280000006755 -:10126000020D013000000067020D01380000006C23 -:10127000020D01400000006B020D014800000067F4 -:10128000020D011400000059020D011C0000005A5B -:10129000020D012400000057020D012C0000005730 -:1012A000020D01340000005C020D013C0000005BF7 -:1012B000020D014400000057020D011800000079E2 -:1012C000020D01200000007A020D012800000077C5 -:1012D000020D013000000077020D01380000007C93 -:1012E000020D01400000007B020D01480000007764 -:1012F000020E004C00000032020E00940215002085 -:10130000020E009802150020020E009C0000003022 -:10131000020E00A008100000020E00A4000000331E -:10132000020E00A800000030020E00AC00000031E8 -:10133000020E00B000000002020E00B40000000423 -:10134000020E00B800000000020E00BC0000000207 -:10135000020E00C000000002020E00C400000000E7 -:10136000020E00C800000002020E00CC00000007C0 -:10137000020E00D000000002020E00D400000002A5 -:10138000020E00D800000001020E00E4000000017F -:10139000020E014400000001020E014C0000000199 -:1013A000020E015000000002020E020400000001C3 -:1013B000020E020C00000040020E0210000000406D -:1013C000020E021C00000004020E02200000002099 -:1013D000020E02240000000E020E02280000001B74 -:1013E000060E030000000012040E0280001B02A281 -:1013F000020E00540000000C020E0058000000090C -:10140000020E005C0000000F020E006000000010E1 -:10141000020E00640000000B060E006800000003CE -:10142000020E00DC00000003020E000400000001B8 -:10143000020E000800000001020E000C0000000176 -:10144000020E001000000001020E00140000000156 -:10145000020E001800000001020E001C0000000136 -:10146000020E002000000001020E00240000000116 -:10147000020E002800000001020E002C00000001F6 -:10148000020E003000000001020E003400000001D6 -:10149000020E003800000001020E003C00000001B6 -:1014A000020E004000000001020E00440000000196 -:1014B000020E01100000000F020E01180000000EC5 -:1014C000020E012000000000020E012800000000B2 -:1014D000020E01140000002F020E011C0000002E5D -:1014E000020E012400000000020E012C000000008A -:1014F000020E01100000001F020E01180000001E65 -:10150000020E012000000000020E01280000000071 -:10151000020E01140000003F020E011C0000003EFC -:10152000020E012400000000020E012C0000000049 -:10153000020E01100000004F020E01180000004EC4 -:10154000020E012000000000020E01280000000031 -:10155000020E01140000006F020E011C0000006E5C -:10156000020E012400000000020E012C0000000009 -:10157000020E01100000005F020E01180000005E64 -:10158000020E012000000000020E012800000000F1 -:10159000020E01140000007F020E011C0000007EFC -:1015A000020E012400000000020E012C00000000C9 -:1015B0000730040000E50000083007D8000502BD30 -:1015C000073400002EF7000007348000311A0BBEEC -:1015D00007350000356F18050735800038C42561D0 -:1015E0000736000014C5339308363400398002BF33 -:1015F0000130000000000000013000040000000085 -:1016000001300008000000000130000C0000000064 -:101610000130001000000000013000140000000044 -:10162000023000200000000102300024000000020F -:1016300002300028000000030230002C00000000EF -:1016400002300030000000040230003400000001CD -:1016500002300038000000000230003C00000001B1 -:10166000023000400000000402300044000000008E -:1016700002300048000000010230004C000000036E -:101680000230005000000000023000540000000151 -:1016900002300058000000040230005C000000002E -:1016A000023000600000000102300064000000030E -:1016B00002300068000000000230006C00000001F1 -:1016C00002300070000000040230007400000000CE -:1016D00002300078000000040230007C00000003AB -:1016E0000630008000000002023000A400003FFF2E -:1016F000023000A8000003FF0230022400000000B6 -:1017000002300234000000000230024C00000000F1 -:10171000023002E40000FFFF063020000000080055 -:1017200002338BC000000001023380000000001A69 -:10173000023380400000004E023380800000001021 -:10174000023380C0000000200C3383000007A1207A -:101750000A338300000001380B3383000000138834 -:10176000023383C0000001F40C3383801DCD65007B -:101770000A3383800004C4B40B338380004C4B4095 -:101780000A331480000000000233148000000001BE -:10179000063220000000010206328020000000C84E -:1017A000063280000000000206323DA8000000045E -:1017B00006323D800000000904323DA4000102C150 -:1017C00006323D00000000200632500000000400F8 -:1017D0000632400000000004063240D00000000243 -:1017E00006326B680000000204326B70000202C215 -:1017F00006326B1000000002043274C0000202C402 -:101800000632DA40000000020632E0000000080064 -:10181000023308000100000004330C00001002C66F -:10182000023308000000000004330C40001002D610 -:1018300006322450000000B406322AD00000000214 -:1018400006321000000001A002323DB80000000086 -:101850000632500000000020063251000000002037 -:101860000632520000000020063253000000002023 -:10187000063254000000002006325500000000200F -:1018800006325600000000200632570000000020FB -:1018900006325800000000200632590000000020E7 -:1018A00006325A000000002006325B0000000020D3 -:1018B00006325C000000002006325D0000000020BF -:1018C00006325E000000002006325F0000000020AB -:1018D00006326B780000005206326E080000000CE1 -:1018E0000632DA880000000206322720000000B429 -:1018F00006322AD80000000206321680000001A03D -:1019000002323DBC00000000063250800000002082 -:101910000632518000000020063252800000002074 -:101920000632538000000020063254800000002060 -:10193000063255800000002006325680000000204C -:101940000632578000000020063258800000002038 -:10195000063259800000002006325A800000002024 -:1019600006325B800000002006325C800000002010 -:1019700006325D800000002006325E8000000020FC -:1019800006325F800000002006326CC0000000526A -:1019900006326E380000000C0632DA9000000002B9 -:1019A00002322A300000000006324010000000021F -:1019B0000632D0000000000602322A340000000087 -:1019C00006324020000000020632D0180000000657 -:1019D00002322A38000000000632403000000002C7 -:1019E0000632D0300000000602322A3C000000001F -:1019F00006324040000000020632D04800000006D7 -:101A000002322A400000000006324050000000026E -:101A10000632D0600000000602322A4400000000B6 -:101A200006324060000000020632D0780000000656 -:101A300002322A4800000000063240700000000216 -:101A40000632D0900000000602322A4C000000004E -:101A500006324080000000020632D0A800000006D6 -:101A6000072004000093000008200780001002E611 -:101A7000072400002ADE0000072480002E050AB893 -:101A80000824E4A061D202E8012000000000000068 -:101A900001200004000000000120000800000000F8 -:101AA0000120000C000000000120001000000000D8 -:101AB00001200014000000000220002000000001AE -:101AC0000220002400000002022000280000000381 -:101AD0000220002C00000000022000300000000462 -:101AE0000220003400000001022000380000000045 -:101AF0000220003C00000001022000400000000421 -:101B00000220004400000000022000480000000104 -:101B10000220004C000000030220005000000000E2 -:101B200002200054000000010220005800000004C0 -:101B30000220005C000000000220006000000001A4 -:101B40000220006400000003022000680000000082 -:101B50000220006C00000001022000700000000460 -:101B60000220007400000000022000780000000441 -:101B70000220007C0000000306200080000000021C -:101B8000022000A400003FFF022000A8000003FF85 -:101B900002200224000000000220023400000000A5 -:101BA0000220024C00000000022002E40000FFFFBF -:101BB000062020000000080002238BC00000000166 -:101BC0000223800000000010022380400000001269 -:101BD0000223808000000030022380C00000000E3D -:101BE000022383C0000001F40223148000000001DE -:101BF0000A231480000000000622100000000042AA -:101C000006227020000000C80622700000000002BA -:101C1000022211E80000000006223000000000C08F -:101C2000062240700000008006225280000000045E -:101C30000622670000000100062290000000040058 -:101C400004226B08002002EA02230800013FFFFF84 -:101C500004230C000010030A022308000000000007 -:101C600004230C400010031A06228100000000A08B -:101C7000062286000000004006228C000000003C86 -:101C80000622B0000000020006228800000000804A -:101C900006228DE00000003C0622404000000006C5 -:101CA00006228380000000A006228700000000407A -:101CB00006228CF00000003C0622B8000000020062 -:101CC00006228A000000008006228ED00000003C20 -:101CD000062240580000000606228000000000088E -:101CE000022211480000000006223300000000021A -:101CF000062260400000003006228020000000081C -:101D00000222114C000000000622330800000002ED -:101D1000062261000000003006228040000000081A -:101D200002221150000000000622331000000002C1 -:101D3000062261C00000003006228060000000081A -:101D40000222115400000000062233180000000295 -:101D50000622628000000030062280800000000819 -:101D60000222115800000000062233200000000269 -:101D70000622634000000030062280A00000000818 -:101D80000222115C0000000006223328000000023D -:101D90000622640000000030062280C00000000817 -:101DA0000222116000000000062233300000000211 -:101DB000062264C000000030062280E00000000817 -:101DC00002221164000000000622333800000002E5 -:101DD0000622658000000030021610000000002876 -:101DE00002170008000000020217002C0000000388 -:101DF0000217003C00000004021700440000000825 -:101E000002170048000000020217004C000000907A -:101E1000021700500000009002170054008000904C -:101E20000217005808140000021700600000008A22 -:101E300002170064000000800217006800000081A3 -:101E40000217006C000000800217007000000006FE -:101E500002170078000007D00217007C0000076C12 -:101E600002170038007C1004021700040000000F65 -:101E70000616402400000002021640700000001CFC -:101E80000216420800000001021642100000000184 -:101E90000216422000000001021642280000000144 -:101EA0000216423000000001021642380000000114 -:101EB00002164260000000020C16401C0003D09085 -:101EC0000A16401C0000009C0B16401C000009C4B0 -:101ED0000216403000000008021640340000000CDA -:101EE0000216403800000010021640440000002096 -:101EF0000216400000000001021640D80000000158 -:101F000002164008000000010216400C000000010B -:101F100002164010000000010216424000000000BE -:101F2000021642480000000006164270000000023F -:101F30000216425000000000021642580000000045 -:101F40000616428000000002021660080000042409 -:101F50000216600C00000410021660100000041449 -:101F60000216601C0000FFFF021660200000FFFF49 -:101F7000021660240000FFFF021660280000FFFF29 -:101F800002166038000000200216603C00000020AD -:101F90000216604000000034021660440000003564 -:101FA00002166048000000230216604C0000002466 -:101FB0000216605000000025021660540000002642 -:101FC00002166058000000270216605C000000291D -:101FD000021660600000002A021660640000002BF8 -:101FE000021660680000002C0216606C0000002DD4 -:101FF0000616607000000052021661B80000000171 -:10200000061661BC0000001F0216623807FFFFFFC2 -:102010000216623C0000003F0216624007FFFFFF0D -:10202000021662440000000F011662480000000022 -:102030000116624C00000000011662500000000012 -:1020400001166254000000000116625800000000F2 -:102050000116625C000000000116626000000000D2 -:1020600001166264000000000116626800000000B2 -:102070000116626C00000000011662700000000092 -:102080000116627400000000011662780000000072 -:102090000116627C000000000C166000000003E8DE -:1020A0000A166000000000010B1660000000000A24 -:1020B0000216804000000006021680440000000561 -:1020C000021680480000000A0216804C000000053D -:1020D0000216805400000002021680CC00000004AA -:1020E000021680D000000004021680D40000000414 -:1020F000021680D800000004021680DC00000004F4 -:10210000021680E000000004021680E400000004D3 -:10211000021680E800000004021688040000000493 -:10212000021680300000007C021680340000003D62 -:10213000021680380000003F0216803C0000009C20 -:10214000021680F000000007061680F4000000056B -:102150000216880C0101010102168108000000002E -:102160000216810C00000004021681100000000419 -:1021700002168114000000020216881008012004D3 -:1021800002168118000000050216811C00000005DF -:1021900002168120000000050216812400000005BF -:1021A0000216882C20081001021681280000000861 -:1021B0000216812C00000006021681300000000784 -:1021C000021681340000000002168830010101204F -:1021D000061681380000000402168834010101014E -:1021E00002168148000000000216814C0000000425 -:1021F0000216815000000004021681540000000203 -:1022000002168838080120040216815800000005D3 -:102210000216815C000000050216816000000005C6 -:1022200002168164000000050216883C2008100197 -:1022300002168168000000080216816C000000068A -:102240000216817000000007021681740000000170 -:102250000216884001010120021681780000000169 -:102260000216817C0000000102168180000000013E -:102270000216818400000001021688440101010158 -:1022800002168188000000010216818C0000000403 -:1022900002168190000000040216819400000002E2 -:1022A00002168848080120040216819800000005E3 -:1022B0000216819C00000005021681A000000005A6 -:1022C000021681A4000000050216881420081001DF -:1022D000021681A800000008021681AC000000066A -:1022E000021681B000000007021681B40000000150 -:1022F0000216881801010120021681B800000001B1 -:10230000021681BC00000001021681C0000000011D -:10231000021681C4000000010216881C010101019F -:10232000021681C800000001021681CC00000004E2 -:10233000021681D000000004021681D400000002C1 -:102340000216882008012004021681D8000000052A -:10235000021681DC00000005021681E00000000585 -:10236000021681E4000000050216882420081001EE -:10237000021681E800000008021681EC0000000649 -:10238000021681F0000000070216E40C00000000B5 -:1023900002168828010101200616E410000000043E -:1023A0000216E000010101010216E4200000000015 -:1023B0000216E424000000040216E42800000004D1 -:1023C0000216E42C000000020216E00408012004BA -:1023D0000216E430000000050216E4340000000597 -:1023E0000216E438000000050216E43C0000000577 -:1023F0000216E008200810010216E4400000000860 -:102400000216E444000000060216E448000000073B -:102410000216E44C000000000216E00C010101204D -:102420000616E450000000040216E010010101014C -:102430000216E460000000000216E46400000004DC -:102440000216E468000000040216E46C00000002BA -:102450000216E014080120040216E47000000005D2 -:102460000216E474000000050216E478000000057E -:102470000216E47C000000050216E0182008100196 -:102480000216E480000000080216E4840000000642 -:102490000216E488000000070216E48C0000000128 -:1024A0000216E01C010101200216E4900000000168 -:1024B0000216E494000000010216E49800000001F6 -:1024C0000216E49C000000010216E0200101010157 -:1024D0000216E4A0000000010216E4A400000004BB -:1024E0000216E4A8000000040216E4AC000000029A -:1024F0000216E024080120040216E4B000000005E2 -:102500000216E4B4000000050216E4B8000000055D -:102510000216E4BC000000050216E02820081001A5 -:102520000216E4C0000000080216E4C40000000621 -:102530000216E4C8000000070216E4CC0000000107 -:102540000216E02C010101200216E4D00000000177 -:102550000216E4D4000000010216E4D800000001D5 -:102560000216E4DC000000010216E0300101010166 -:102570000216E4E0000000010216E4E4000000049A -:102580000216E4E8000000040216E4EC0000000279 -:102590000216E034080120040216E4F000000005F1 -:1025A0000216E4F4000000050216E4F8000000053D -:1025B0000216E4FC000000050216E03820081001B5 -:1025C0000216E500000000080216E50400000006FF -:1025D0000216E508000000070216E03C0101012098 -:1025E00002168240003F003F0216824400000000B5 -:1025F0000216E524003F003F0216E5280000000017 -:1026000002168248000000000216824C003F003F84 -:102610000216E52C000000000216E530003F003FE6 -:1026200002168250010001000216825401000100CE -:102630000216E534010001000216E5380100010030 -:1026400006168258000000020216E53C0000000059 -:102650000216E540000000000216826000C000C0C3 -:102660000216826400C000C00216E54400C000C02B -:102670000216E54800C000C0021682681E001E0057 -:102680000216826C1E001E000216E54C1E001E0083 -:102690000216E5501E001E00021682704000400027 -:1026A00002168274400040000216E55440004000CB -:1026B0000216E55840004000021682788000800033 -:1026C0000216827C800080000216E55C800080009B -:1026D0000216E56080008000021682802000200043 -:1026E00002168284200020000216E56420002000EB -:1026F0000216E5682000200006168288000000020D -:102700000216E56C000000000216E57000000000F3 -:102710000216829000000000021682940000000061 -:102720000216E574000000000216E57800000000C3 -:1027300002168298000000000216829C0000000031 -:102740000216E57C000000000216E5800000000093 -:10275000021682A000000000021682A40000000100 -:10276000061682A80000000A021681F400000C0878 -:10277000021681F800000040021681FC00000100F2 -:1027800002168200000000200216820400000017DA -:1027900002168208000000800216820C000002006F -:1027A00002168210000000000216821801FF01FFCD -:1027B0000216821401FF01FF0216E51001FF01FF5E -:1027C0000216E50C01FF01FF0216823C0000001317 -:1027D000021680900000013F021680600000014058 -:1027E00002168064000001400616806800000002A6 -:1027F00002168070000000C00616807400000007FA -:102800000216809C00000048021680A000000048CC -:10281000061680A400000002021680AC00000048EA -:10282000061680B000000007021682380000800003 -:1028300002168234000025E40216809400007FFF17 -:1028400002168220000F000F0216821C000F000FDC -:102850000216E518000F000F0216E514000F000F16 -:10286000021682280000000002168224FFFFFFFFEC -:102870000216E520000000000216E51CFFFFFFFF26 -:102880000216E6BC000000000216E6C000000002CE -:102890000216E6C4000000010216E6C800000003AC -:1028A0000216E6CC000000040216E6D00000000686 -:1028B0000216E6D4000000050216E6D80000000764 -:1028C000021680EC000000FF02140000000000016E -:1028D0000214000C0000000102140040000000017E -:1028E0000214004400007FFF0214000C00000000EE -:1028F00002140000000000000214006C0000000040 -:102900000214000400000001021400300000000165 -:1029100002140004000000000214005C000000002B -:10292000021400080000000102140034000000013D -:102930000214000800000000021400600000000003 -:102940000202005800000032020200A0031500201D -:10295000020200A403150020020200A801000030BA -:10296000020200AC08100000020200B000000033B8 -:10297000020200B400000030020200B80000003182 -:10298000020200BC00000003020200C000000006BA -:10299000020200C400000003020200C8000000039D -:1029A000020200CC00000002020200D00000000081 -:1029B000020200D400000002020200DC000000005D -:1029C000020200E000000006020200E40000000431 -:1029D000020200E800000002020200EC0000000217 -:1029E000020200F000000001020200FC00000006EC -:1029F0000202012000000000020201340000000277 -:102A0000020201B0000000010202020C00000001FD -:102A1000020202140000000102020218000000027B -:102A200002020404000000010202040C0000004045 -:102A300002020410000000400202041C0000000416 -:102A40000202042000000020020204240000000210 -:102A50000202042800000020060205000000001207 -:102A600004020480001F032A020200600000000F1D -:102A70000202006400000007020200680000000B70 -:102A80000202006C0000000E020200700000000E46 -:102A90000602007400000003020200F400000004BB -:102AA0000202000400000001020200080000000110 -:102AB0000202000C000000010202001000000001F0 -:102AC00002020014000000010202001800000001D0 -:102AD0000202001C000000010202002000000001B0 -:102AE0000202002400000001020200280000000190 -:102AF0000202002C00000001020200300000000170 -:102B0000020200340000000102020038000000014F -:102B10000202003C0000000102020040000000012F -:102B2000020200440000000102020048000000010F -:102B30000202004C000000010202005000000001EF -:102B400002020108000000C8020201180000000291 -:102B5000020201C400000000020201CC00000000DB -:102B6000020201D400000002020201DC00000002A7 -:102B7000020201E4000000FF020201EC000000FF7D -:102B800002020100000000000202010C000000C867 -:102B90000202011C00000002020201C80000000045 -:102BA000020201D000000000020201D80000000271 -:102BB000020201E000000002020201E8000000FF42 -:102BC000020201F0000000FF020201040000000008 -:102BD00002020108000000C8020201180000000201 -:102BE000020201C400000000020201CC000000004B -:102BF000020201D400000002020201DC0000000217 -:102C0000020201E4000000FF020201EC000000FFEC -:102C100002020100000000000202010C000000C8D6 -:102C20000202011C00000002020201C800000000B4 -:102C3000020201D000000000020201D800000002E0 -:102C4000020201E000000002020201E8000000FFB1 -:102C5000020201F0000000FF020201040000000077 -:102C600002020108000000C8020201180000000270 -:102C7000020201C400000000020201CC00000000BA -:102C8000020201D400000002020201DC0000000286 -:102C9000020201E4000000FF020201EC000000FF5C -:102CA00002020100000000000202010C000000C846 -:102CB0000202011C00000002020201C80000000024 -:102CC000020201D000000000020201D80000000250 -:102CD000020201E000000002020201E8000000FF21 -:102CE000020201F0000000FF0202010400000000E7 -:102CF00002020108000000C80202011800000002E0 -:102D0000020201C400000000020201CC0000000029 -:102D1000020201D400000002020201DC00000002F5 -:102D2000020201E4000000FF020201EC000000FFCB -:102D300002020100000000000202010C000000C8B5 -:102D40000202011C00000002020201C80000000093 -:102D5000020201D000000000020201D800000002BF -:102D6000020201E000000002020201E8000000FF90 -:102D7000020201F0000000FF020201040000000056 -:102D80000728040000C00000082807A8000B03491A -:102D9000072C000032FC0000072C800035780CC0A6 -:102DA000072D00003AC11A1F072D800039E228D0F4 -:102DB000072E00001C3E3749082E3710391E034BE2 -:102DC00001280000000000000128000400000000AD -:102DD00001280008000000000128000C000000008D -:102DE000012800100000000001280014000000006D -:102DF0000228002000000001022800240000000238 -:102E000002280028000000030228002C0000000017 -:102E100002280030000000040228003400000001F5 -:102E200002280038000000000228003C00000001D9 -:102E300002280040000000040228004400000000B6 -:102E400002280048000000010228004C0000000396 -:102E50000228005000000000022800540000000179 -:102E600002280058000000040228005C0000000056 -:102E70000228006000000001022800640000000336 -:102E800002280068000000000228006C0000000119 -:102E900002280070000000040228007400000000F6 -:102EA00002280078000000040228007C00000003D3 -:102EB0000628008000000002022800A400003FFF56 -:102EC000022800A8000003FF0228022400000000DE -:102ED00002280234000000000228024C000000001A -:102EE000022802E40000FFFF06282000000008007E -:102EF000022B8BC000000001022B800000000000AC -:102F0000022B804000000018022B80800000000C83 -:102F1000022B80C0000000660C2B83000007A1205C -:102F20000A2B8300000001380B2B8300000013885C -:102F3000022B83C0000001F40C2B8340000001F43D -:102F40000A2B8340000000000B2B8340000000058B -:102F50000A2B83800004C4B40C2B83801DCD650034 -:102F60000A2B1480000000000B2B8380004C4B4088 -:102F7000022B148000000001062A29C8000000046A -:102F8000042A29D80002034D062A208000000048A8 -:102F9000062A9020000000C8062A900000000002C7 -:102FA000062A21A800000086062A20000000002032 -:102FB000022A23C800000000042A23D00002034F85 -:102FC000042A249800040351022A2C500000000017 -:102FD000022A2C1000000000042A2C0800020355CD -:102FE000042A300000020357062A300800000100BE -:102FF000062A404000000010042A40000010035937 -:10300000062A6AC000000002062A6B0000000004C5 -:10301000042A840800020369022B08000000000053 -:10302000042B0C000010036B022B080001000000B1 -:10303000042B0C400008037B022B08000200000058 -:10304000042B0C6000080383062AC000000000D88F -:10305000062A24A800000014062A254800000022A1 -:10306000042A25D00002038B062A266800000022CD -:10307000042A26F00002038D062A27880000002279 -:10308000042A28100002038F062A28A80000002224 -:10309000042A293000020391062AA000000000281B -:1030A000062AA1400000000C042A29E00002039334 -:1030B000062A502000000002062A503000000002BC -:1030C000062A500000000002062A501000000002EC -:1030D000022A520800000001042A6AC8000203956F -:1030E000062A6B1000000042062A6D200000000432 -:1030F000062ABCD000000002062AC360000000D8E7 -:10310000062A24F800000014062A25D80000002210 -:10311000042A266000020397062A26F800000022EF -:10312000042A278000020399062A2818000000229A -:10313000042A28A00002039B062A29380000002246 -:10314000042A29C00002039D062AA0A0000000282E -:10315000062AA1700000000C042A29E80002039F3F -:10316000062A502800000002062A503800000002FB -:10317000062A500800000002062A5018000000022B -:10318000022A520C00000001042A6AD0000203A1A6 -:10319000062A6C1800000042062A6D300000000468 -:1031A000062ABCD800000002022AC6C000000000A7 -:1031B000042A29F0001003A3062A50480000000E3C -:1031C000062AB00000000006022AC6C40000000063 -:1031D000042A2A30001003B3062A50800000000E93 -:1031E000062AB01800000006022AC6C80000000027 -:1031F000042A2A70001003C3062A50B80000000EEB -:10320000062AB03000000006022AC6CC00000000EA -:10321000042A2AB0001003D3062A50F00000000E42 -:10322000062AB04800000006022AC6D000000000AE -:10323000042A2AF0001003E3062A51280000000E99 -:10324000062AB06000000006022AC6D40000000072 -:10325000042A2B30001003F3062A51600000000EF0 -:10326000062AB07800000006022AC6D80000000036 -:10327000042A2B7000100403062A51980000000E47 -:10328000062AB09000000006022AC6DC00000000FA -:10329000042A2BB000100413062A51D00000000E9F -:1032A000062AB0A800000006021010080000000165 -:1032B0000210105000000001021010000003D000A6 -:1032C000021010040000003D091018000200042341 -:1032D0000910110000280623061011A00000001894 -:1032E00006102400000000E00210201C0000000076 -:1032F0000210202000000001021020C00000000287 -:10330000021020040000000102102008000000014B -:1033100009103C000005064B091038000005065056 -:10332000091038200005065506104C000000010069 -:1033300002104028000000100210404400003FFF2F -:103340000210405800280000021040840084924A75 -:1033500002104058000000000210800000001080A1 -:10336000021080AC00000000021080380000001045 -:103370000210810000000000061081200000000201 -:1033800002108008000002B502108010000000004A -:10339000061082000000004A021081080001FFFFB1 -:1033A00006108140000000020210800000001A8018 -:1033B0000610900000000024061091200000004A32 -:1033C000061093700000004A061095C00000004AE5 -:1033D0000210800400001080021080B00000000184 -:1033E0000210803C00000010021081040000000068 -:1033F00006108128000000020210800C000002B5B7 -:103400000210801400000000061084000000004A32 -:103410000210810C0001FFFF06108148000000022D -:103420000210800400001A80061090900000002412 -:10343000061092480000004A061094980000004AC6 -:10344000061096E80000004A02108000000010807C -:10345000021080AC00000002021080380000001052 -:103460000210810000000000061081200000000210 -:1034700002108008000002B5021080100000000059 -:10348000061082000000004A021081080001FFFFC0 -:1034900006108140000000020210800000001A8027 -:1034A0000610900000000024061091200000004A41 -:1034B000061093700000004A061095C00000004AF4 -:1034C0000210800400001080021080B00000000391 -:1034D0000210803C00000010021081040000000077 -:1034E00006108128000000020210800C000002B5C6 -:1034F0000210801400000000061084000000004A42 -:103500000210810C0001FFFF06108148000000023C -:103510000210800400001A80061090900000002421 -:10352000061092480000004A061094980000004AD5 -:10353000061096E80000004A02108000000010808B -:10354000021080AC0000000402108038000000105F -:10355000021081000000000006108120000000021F -:1035600002108008000002B5021080100000000068 -:10357000061082000000004A021081080001FFFFCF -:1035800006108140000000020210800000001A8036 -:103590000610900000000024061091200000004A50 -:1035A000061093700000004A061095C00000004A03 -:1035B0000210800400001080021080B0000000059E -:1035C0000210803C00000010021081040000000086 -:1035D00006108128000000020210800C000002B5D5 -:1035E0000210801400000000061084000000004A51 -:1035F0000210810C0001FFFF06108148000000024C -:103600000210800400001A80061090900000002430 -:10361000061092480000004A061094980000004AE4 -:10362000061096E80000004A02108000000010809A -:10363000021080AC0000000602108038000000106C -:10364000021081000000000006108120000000022E -:1036500002108008000002B5021080100000000077 -:10366000061082000000004A021081080001FFFFDE -:1036700006108140000000020210800000001A8045 -:103680000610900000000024061091200000004A5F -:10369000061093700000004A061095C00000004A12 -:1036A0000210800400001080021080B000000007AB -:1036B0000210803C00000010021081040000000095 -:1036C00006108128000000020210800C000002B5E4 -:1036D0000210801400000000061084000000004A60 -:1036E0000210810C0001FFFF06108148000000025B -:1036F0000210800400001A80061090900000002440 -:10370000061092480000004A061094980000004AF3 -:10371000061096E80000004A021205B00000000101 -:103720000212049000E383400212051400003C10D2 -:103730000212066C00000001021206700000000078 -:1037400002120494FFFFFFFF02120498FFFFFFFF25 -:103750000212049CFFFFFFFF021204A0FFFFFFFF05 -:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5 -:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5 -:10378000021204BCFFFFFFFF021204C0FFFFFFFF95 -:10379000021204C4FFFFFFFF021204C8FFFFFFFF75 -:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55 -:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D -:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D -:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED -:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD -:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD -:1038000002120500FFFFFFFF02120504FFFFFFFF8A -:1038100002120508FFFFFFFF0212050CFFFFFFFF6A -:1038200002120510FFFFFFFF021204D4FF802000E8 -:10383000021204B4F0005000021204B8F0001000AC -:1038400002120390000000080212039C000000080E -:10385000021203A000000008021203A400000002EC -:10386000021203BC00000004021203C000000005A5 -:10387000021203C400000004021203D00000000082 -:103880000212036C00000001021203680000003FF6 -:10389000021201BC00000040021201C00000180822 -:1038A000021201C400000803021201C8000008034C -:1038B000021201CC00000040021201D000000003FF -:1038C000021201D400000803021201D8000008030C -:1038D000021201DC00000803021201E000010003F3 -:1038E000021201E400000803021201E800000803CC -:1038F000021201EC00000003021201F000000003BC -:10390000021201F400000003021201F8000000039B -:10391000021201FC0000000302120200000000037A -:103920000212020400000003021202080000000359 -:103930000212020C00000003021202100000000339 -:103940000212021400000003021202180000000319 -:103950000212021C000000030212022000000003F9 -:1039600002120224000000030212022800002403B5 -:103970000212022C0000002F021202300000000987 -:103980000212023400000019021202380000018401 -:103990000212023C000001830212024000000306F2 -:1039A0000212024400000019021202480000000640 -:1039B0000212024C0000030602120250000003062D -:1039C00002120254000003060212025800000C8684 -:1039D0000212025C000003060212026000000306ED -:1039E00002120264000000060212026800000006D3 -:1039F0000212026C000000060212027000000006B3 -:103A00000212027400000006021202780000000692 -:103A10000212027C00000006021202800000000672 -:103A20000212028400000006021202880000000652 -:103A30000212028C00000006021202900000000632 -:103A40000212029400000006021202980000000612 -:103A50000212029C00000006021202A000000306EF -:103A6000021202A400000013021202A800000006C5 -:103A7000021202B000001004021202B4000010048E -:103A80000212032400106440021203280010644054 -:103A9000021205B400000001021201B00000000192 -:103AA0000600A000000000160200A0EC5554000023 -:103AB0000200A0F0555555550200A0F400005555E0 -:103AC0000200A0F8F00000000200A0FC5554000025 -:103AD0000200A100555555550200A104000055559E -:103AE0000200A108F00000000200A18C5554000063 -:103AF0000200A190555555550200A194000055555E -:103B00000200A198F00000000200A19C000000004B -:103B10000200A1A0000100000200A1A400005014B6 -:103B20000200A1A8000000000200A45C00000C003C -:103B30000200A61C000000030200A06CFF5C000055 -:103B40000200A070FFF55FFF0200A0740000FFFFFD -:103B50000200A078F00003E00200A07C000000005A -:103B60000200A0800000A0000600A0840000000564 -:103B70000200A0980FE000000600A09C00000007D3 -:103B80000200A0B8000004000600A0BC0000000372 -:103B90000200A0C8000010000600A0CC0000000336 -:103BA0000200A0D8000040000600A0DC00000003D6 -:103BB0000200A0E8000100000600A22C00000004A2 -:103BC0000200A10CFF5C00000200A110FFF55FFFE6 -:103BD0000200A1140000FFFF0200A118F00003E0A2 -:103BE0000200A11C000000000200A1200000A000B3 -:103BF0000600A124000000050200A1380FE000002B -:103C00000600A13C000000070200A15800000800C7 -:103C10000600A15C000000030200A1680000200073 -:103C20000600A16C000000030200A17800008000E3 -:103C30000600A17C000000030200A1880002000031 -:103C40000600A23C0000000400000000000000008C -:103C50000000003100000000000000000000000033 -:103C60000000000000000000000000000000000054 -:103C700000000000000000000000000000310032E1 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA000000000000000000000320056000000008C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000000000000056008C000000000000000002 -:103CE000008C009000900094009400980098009C34 -:103CF000009C00A000A000A400A400A800A800ACA4 -:103D000000AC00B100B100B300B300B5000000008A -:103D100000000000000000000000000000000000A3 -:103D200000000000000000000000000000B50102DB -:103D30000102010A010A01120112011B011B0124E7 -:103D40000124012D012D01360136013F013F0148BB -:103D5000014801510151015A00000000000000001B -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E00000000000000000000015A015F00000000F7 -:103E100000000000015F0160016001610161016259 -:103E2000016201630163016401640165016501666A -:103E300001660167000000000000000000000000B3 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000167016C016C0179017901860000000095 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB00000000000000000000186018700000000F3 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000018701BE00000000000000008B -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100001BE01E9000000000000000000000000F8 -:103F20000000000000000000000000000000000091 -:103F300000000000000000000000000001E9021A7B -:103F40000000000000000000021A022102210228E5 -:103F50000228022F022F02360236023D023D0244A1 -:103F60000244024B024B02520252028A000000003D -:103F700000000000028A028E028E029202920296D5 -:103F80000296029A029A029E029E02A202A202A631 -:103F900002A602AA02AA02FA02FA031103110328D6 -:103FA0000328032B032B032E032E03310331033489 -:103FB000033403370337033A033A033D033D034019 -:103FC00003400381038103880388038F038F0393D6 -:103FD000039303970397039B039B039F039F03A3F1 -:103FE00003A303A703A703AB03AB03AF03AF03B064 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:10401000000000000000000003B003C20000000028 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000003C203D703D703DA03DA03DD5D -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:1040700003DD040A00000000000000000000000052 -:104080000000000000000000000000000000000030 -:10409000000000000000000000000000040A050D00 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C0000000000000000000050D0514051405188F -:1040D0000518051C000000000000000000000000A2 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000051C055C00000000000000003E -:10410000055C05650565056E056E05770577058017 -:1041100005800589058905920592059B059B05A4E7 -:1041200005A405FD05FD0613061306290629062D1F -:10413000062D063106310635063506390639063DA7 -:10414000063D064106410645064506490649065014 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000006500656000000008D -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A0000000000006560659000000000000000054 -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D0000659065F0000000000000000000000001B -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:104200000000000000000000065F066E066E067DDE -:10421000067D068C068C069B069B06AA06AA06B996 -:1042200006B906C806C806D706D70748000000002A -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000748075B075B076C076C077DE1 -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000010000000204C00003098000040E4029 -:1042F00000051300000617C000071C8000082140BD -:1043000000092600000A2AC0000B2F80000C344050 -:10431000000D3900000E3DC0000F428000104740E4 -:1043200000114C00001250C00013558000145A4078 -:1043300000155F00001663C00017688000186D400C -:1043400000197200001A76C0001B7B80001C8040A0 -:10435000001D8500001E89C0001F8E800020934034 -:10436000000020000000400000006000000080000D -:104370000000A0000000C0000000E00000010000FC -:1043800000012000000140000001600000018000E9 -:104390000001A0000001C0000001E00000020000D8 -:1043A00000022000000240000002600000028000C5 -:1043B0000002A0000002C0000002E00000030000B4 -:1043C00000032000000340000003600000038000A1 -:1043D0000003A0000003C0000003E0000004000090 -:1043E000000420000004400000046000000480007D -:1043F0000004A0000004C0000004E000000500006C -:104400000005200000054000000560000005800058 -:104410000005A0000005C0000005E0000006000047 -:104420000006200000064000000660000006800034 -:104430000006A0000006C0000006E0000007000023 -:104440000007200000074000000760000007800010 -:104450000007A0000007C0000007E00000080000FF -:1044600000082000000840000008600000088000EC -:104470000008A0000008C0000008E00000090000DB -:1044800000092000000940000009600000098000C8 -:104490000009A0000009C0000009E000000A0000B7 -:1044A000000A2000000A4000000A6000000A8000A4 -:1044B000000AA000000AC000000AE000000B000093 -:1044C000000B2000000B4000000B6000000B800080 -:1044D000000BA000000BC000000BE000000C00006F -:1044E000000C2000000C4000000C6000000C80005C -:1044F000000CA000000CC000000CE000000D00004B -:10450000000D2000000D4000000D6000000D800037 -:10451000000DA000000DC000000DE000000E000026 -:10452000000E2000000E4000000E6000000E800013 -:10453000000EA000000EC000000EE000000F000002 -:10454000000F2000000F4000000F6000000F8000EF -:10455000000FA000000FC000000FE00000100000DE -:1045600000102000001040000010600000108000CB -:104570000010A0000010C0000010E00000110000BA -:1045800000112000001140000011600000118000A7 -:104590000011A0000011C0000011E0000012000096 -:1045A0000012200000124000001260000012800083 -:1045B0000012A0000012C0000012E0000013000072 -:1045C000001320000013400000136000001380005F -:1045D0000013A0000013C0000013E000001400004E -:1045E000001420000014400000146000001480003B -:1045F0000014A0000014C0000014E000001500002A -:104600000015200000154000001560000015800016 -:104610000015A0000015C0000015E0000016000005 -:1046200000162000001640000016600000168000F2 -:104630000016A0000016C0000016E00000170000E1 -:1046400000172000001740000017600000178000CE -:104650000017A0000017C0000017E00000180000BD -:1046600000182000001840000018600000188000AA -:104670000018A0000018C0000018E0000019000099 -:104680000019200000194000001960000019800086 -:104690000019A0000019C0000019E000001A000075 -:1046A000001A2000001A4000001A6000001A800062 -:1046B000001AA000001AC000001AE000001B000051 -:1046C000001B2000001B4000001B6000001B80003E -:1046D000001BA000001BC000001BE000001C00002D -:1046E000001C2000001C4000001C6000001C80001A -:1046F000001CA000001CC000001CE000001D000009 -:10470000001D2000001D4000001D6000001D8000F5 -:10471000001DA000001DC000001DE000001E0000E4 -:10472000001E2000001E4000001E6000001E8000D1 -:10473000001EA000001EC000001EE000001F0000C0 -:10474000001F2000001F4000001F6000001F8000AD -:10475000001FA000001FC000001FE000002000009C -:104760000020200000204000002060000020800089 -:104770000020A0000020C0000020E0000021000078 -:104780000021200000214000002160000021800065 -:104790000021A0000021C0000021E0000022000054 -:1047A0000022200000224000002260000022800041 -:1047B0000022A0000022C0000022E0000023000030 -:1047C000002320000023400000236000002380001D -:1047D0000023A0000023C0000023E000002400000C -:1047E00000242000002440000024600000248000F9 -:1047F0000024A0000024C0000024E00000250000E8 -:1048000000252000002540000025600000258000D4 -:104810000025A0000025C0000025E00000260000C3 -:1048200000262000002640000026600000268000B0 -:104830000026A0000026C0000026E000002700009F -:10484000002720000027400000276000002780008C -:104850000027A0000027C0000027E000002800007B -:104860000028200000284000002860000028800068 -:104870000028A0000028C0000028E0000029000057 -:104880000029200000294000002960000029800044 -:104890000029A0000029C0000029E000002A000033 -:1048A000002A2000002A4000002A6000002A800020 -:1048B000002AA000002AC000002AE000002B00000F -:1048C000002B2000002B4000002B6000002B8000FC -:1048D000002BA000002BC000002BE000002C0000EB -:1048E000002C2000002C4000002C6000002C8000D8 -:1048F000002CA000002CC000002CE000002D0000C7 -:10490000002D2000002D4000002D6000002D8000B3 -:10491000002DA000002DC000002DE000002E0000A2 -:10492000002E2000002E4000002E6000002E80008F -:10493000002EA000002EC000002EE000002F00007E -:10494000002F2000002F4000002F6000002F80006B -:10495000002FA000002FC000002FE000003000005A -:104960000030200000304000003060000030800047 -:104970000030A0000030C0000030E0000031000036 -:104980000031200000314000003160000031800023 -:104990000031A0000031C0000031E0000032000012 -:1049A00000322000003240000032600000328000FF -:1049B0000032A0000032C0000032E00000330000EE -:1049C00000332000003340000033600000338000DB -:1049D0000033A0000033C0000033E00000340000CA -:1049E00000342000003440000034600000348000B7 -:1049F0000034A0000034C0000034E00000350000A6 -:104A00000035200000354000003560000035800092 -:104A10000035A0000035C0000035E0000036000081 -:104A2000003620000036400000366000003680006E -:104A30000036A0000036C0000036E000003700005D -:104A4000003720000037400000376000003780004A -:104A50000037A0000037C0000037E0000038000039 -:104A60000038200000384000003860000038800026 -:104A70000038A0000038C0000038E0000039000015 -:104A80000039200000394000003960000039800002 -:104A90000039A0000039C0000039E000003A0000F1 -:104AA000003A2000003A4000003A6000003A8000DE -:104AB000003AA000003AC000003AE000003B0000CD -:104AC000003B2000003B4000003B6000003B8000BA -:104AD000003BA000003BC000003BE000003C0000A9 -:104AE000003C2000003C4000003C6000003C800096 -:104AF000003CA000003CC000003CE000003D000085 -:104B0000003D2000003D4000003D6000003D800071 -:104B1000003DA000003DC000003DE000003E000060 -:104B2000003E2000003E4000003E6000003E80004D -:104B3000003EA000003EC000003EE000003F00003C -:104B4000003F2000003F4000003F6000003F800029 -:104B5000003FA000003FC000003FE000003FE00138 -:104B600000000000000001FF0000020000007FF8CC -:104B700000007FF800000CDF0000150000000001BD -:104B80000000000100000001FFFFFFFFFFFFFFFF2B -:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 -:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 -:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 -:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 -:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 -:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0 -:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0 -:104C200000000000FFFFFFFF00000000FFFFFFFF8C -:104C3000FFFFFFFF00000000FFFFFFFF000000007C -:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF -:104C500000000000FFFFFFFF00000000FFFFFFFF5C -:104C60000000000300BEBC20FFFFFFFF00000000AB -:104C7000FFFFFFFF00000000FFFFFFFF0000000339 -:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92 -:104C900000000000FFFFFFFF0000000300BEBC207B -:104CA000FFFFFFFF00000000FFFFFFFF000000000C -:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F -:104CC00000000000FFFFFFFF00000000FFFFFFFFEC -:104CD0000000000300BEBC2000002000000040C017 -:104CE00000006180000082400000A3000000C3C0FB -:104CF0000000E4800001054000012600000146C0DC -:104D000000016780000188400001A9000001C9C0BE -:104D10000001EA8000020B4000022C0000024CC09F -:104D200000026D8000028E400002AF000002CFC082 -:104D30000002F0800003114000033200000352C063 -:104D400000037380000394400003B5000003D5C046 -:104D50000003F6800004174000043800000458C027 -:104D60000004798000049A40000080000001038064 -:104D70000001870000020A8000028E0000031180FB -:104D8000000395000004188000049C0000051F80AB -:104D90000005A300000626800006AA0000072D805B -:104DA0000007B100000834800008B80000093B800B -:104DB0000009BF00000A4280000AC600000B4980BB -:104DC000000BCD00000C5080000CD400000D57806B -:104DD000000DDB0000007FF800007FF80000192ABA -:104DE0000000350000001900001000000000000065 -:104DF00000000000FFFFFFFF400000004000000037 -:104E000040000000400000004000000040000000A2 -:104E10004000000040000000400000004000000092 -:104E20004000000040000000400000004000000082 -:104E30004000000040000000400000004000000072 -:104E40004000000040000000400000004000000062 -:104E50004000000040000000400000004000000052 -:104E60004000000040000000400000004000000042 -:104E7000400000004000000000007FF800007FF8C4 -:104E8000000005C700001500FFFFFFFFFFFFFFFF49 -:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:104F0000FFFFFFFFFFFFFFFF400000004000000029 -:104F10004000000040000000400000004000000091 -:104F20004000000040000000400000004000000081 -:104F30004000000040000000400000004000000071 -:104F40004000000040000000400000004000000061 -:104F50004000000040000000400000004000000051 -:104F60004000000040000000400000004000000041 -:104F70004000000040000000400000004000000031 -:104F800040000000400000000000100000002080F1 -:104F900000003100000041800000520000006280EB -:104FA0000000730000008380000094000000A480D3 -:104FB0000000B5000000C5800000D6000000E680BB -:104FC0000000F700000107800001180000012880A0 -:104FD000000139000001498000015A0000016A8087 -:104FE00000017B0000018B8000019C000001AC806F -:104FF0000001BD000001CD800001DE000001EE8057 -:105000000001FF0000007FF800007FF80000112E73 -:105010000000350010000000000028AD0000000076 -:1050200000010001000D0205CCCCCCC5FFFFFFFF45 -:10503000FFFFFFFF7058103C000000000000000060 -:1050400000000001CCCC0201CCCCCCCCCCCC0201F9 -:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA -:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA -:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A -:10508000CCCCCCCC00000000FFFFFFFF40000000B4 -:105090004000000040000000400000004000000010 -:1050A0004000000040000000400000004000000000 -:1050B00040000000400000004000000040000000F0 -:1050C00040000000400000004000000040000000E0 -:1050D00040000000400000004000000040000000D0 -:1050E00040000000400000004000000040000000C0 -:1050F00040000000400000004000000040000000B0 -:10510000400000004000000040000000002625A0F4 -:1051100000000000002625A000000000002625A0B9 -:1051200000000000002625A000000000000E023252 -:10513000011600D60010000000000000002625A087 -:1051400000000000002625A000000000002625A089 -:1051500000000000002625A00000000000720236BA -:10516000012300F300100000000000000000FFFF1A -:10517000000000000000FFFF000000000000FFFF33 -:10518000000000000000FFFF000000000000FFFF23 -:10519000000000000000FFFF000000000000FFFF13 -:1051A000000000000000FFFF000000000000FFFF03 -:1051B000000000000000FFFF000000000000FFFFF3 -:1051C000000000000000FFFF000000000000FFFFE3 -:1051D000000000000000FFFF000000000000FFFFD3 -:1051E000000000000000FFFF000000000000FFFFC3 -:1051F000000000000000FFFF000000000000FFFFB3 -:10520000000000000000FFFF000000000000FFFFA2 -:10521000000000000000FFFF000000000000FFFF92 -:10522000000000000000FFFF000000000000FFFF82 -:10523000000000000000FFFF000000000000FFFF72 -:10524000000000000000FFFF000000000000FFFF62 -:10525000000000000000FFFF000000000000FFFF52 -:10526000000000000000FFFF000000000000FFFF42 -:10527000000000000000FFFF000000000000FFFF32 -:10528000000000000000FFFF000000000000FFFF22 -:10529000000000000000FFFF000000000000FFFF12 -:1052A000000000000000FFFF000000000000FFFF02 -:1052B000000000000000FFFF000000000000FFFFF2 -:1052C000000000000000FFFF000000000000FFFFE2 -:1052D000000000000000FFFF000000000000FFFFD2 -:1052E000000000000000FFFF000000000000FFFFC2 -:1052F000000000000000FFFF000000000000FFFFB2 -:10530000000000000000FFFF000000000000FFFFA1 -:10531000000000000000FFFF000000000000FFFF91 -:10532000000000000000FFFF000000000000FFFF81 -:10533000000000000000FFFF000000000000FFFF71 -:10534000000000000000FFFF000000000000FFFF61 -:10535000000000000000FFFF000000000000FFFF51 -:10536000000000000000FFFF00000000FFFFFFF34F -:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4 -:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF -:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025 -:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9 -:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095 -:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3 -:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B -:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A -:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065 -:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D -:10541000302FFFFF0C30C30CC30C30C3CF3CF30064 -:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748 -:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083 -:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A -:10545000302FFFFF0C30C30CC30C30C3CF3CF30024 -:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC -:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3 -:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE -:10549000310FFFFF0C30C30CC30C30C3CF3CF30003 -:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8 -:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094 -:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2 -:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A -:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299 -:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064 -:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C -:10551000302FFFFF0C30C30CC30C30C3CF3CF30063 -:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747 -:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083 -:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519 -:10555000304FFFFF0C30C30CC30C30C3CF3CF30003 -:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB -:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042 -:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD -:10559000310FFFFF0C30C30CC30C30C3CF3CF30002 -:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7 -:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093 -:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1 -:1055D0001CBFFFFF0C30C305C30C30C3CF30001419 -:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298 -:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063 -:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B -:10561000302FFFFF0C30C30CC30C30C3CF3CF30062 -:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6 -:10563000056FFFFF0C30C30CC30C30C3CF3CC00060 -:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518 -:10565000310FFFFF0C30C30CC30C30C3CF3CF30041 -:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA -:10567000320FFFFF0C30C30CC30C30C3CF3CF30020 -:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC -:10569000310FFFFF0C30C30CC30C30C3CF3CF30001 -:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6 -:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092 -:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0 -:1056D0001CBFFFFF0C30C305C30C30C3CF30001418 -:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297 -:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062 -:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA -:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0 -:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5 -:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF -:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517 -:10575000310FFFFF0C30C30CC30C30C3CF3CF30040 -:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9 -:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0 -:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB -:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1 -:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5 -:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091 -:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4 -:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD -:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296 -:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061 -:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69 -:10581000302FFFFF0C30C30CC30C30C3CF3CF30060 -:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744 -:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F -:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B -:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0 -:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC -:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94 -:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC -:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74 -:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB -:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54 -:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA -:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34 -:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88 -:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14 -:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63 -:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3 -:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B -:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3 -:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B -:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3 -:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB -:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93 -:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB -:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73 -:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA -:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53 -:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9 -:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33 -:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87 -:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13 -:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62 -:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2 -:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A -:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2 -:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A -:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2 -:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA -:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92 -:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA -:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72 -:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9 -:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52 -:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8 -:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32 -:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86 -:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12 -:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61 -:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1 -:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39 -:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1 -:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09 -:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1 -:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9 -:105B7000000700C000028130000B815800020210B3 -:105B800000010230000F024000010330000C000051 -:105B9000000800C000028140000B81680002022062 -:105BA0000001024000070250000202C0000F000086 -:105BB000000800F000028170000B81980002025082 -:105BC00000010270000B8280000803380010000002 -:105BD0000008010000028180000B81A80002026021 -:105BE00000018280000E829800080380000B0000F4 -:105BF000000100B0000280C0000580E80002014002 -:105C000000010160000E017000038250CCCCCCCCAE -:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4 -:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C4000CCCCCCCC04002000000000000000000000 -:105C50001F8B080000000000000BFB51CFC0F003B9 -:105C60008A59051918AC84117C7A607E4ECAF43BBF -:105C7000F232303803B12B103700F1616E06862303 -:105C8000DCC4EB3F298F607BCB32309403F1766923 -:105C90000606133984B8AE0203C33C203F012AF63E -:105CA000144867CB53E6EEC182155431C564951193 -:105CB0006C452CF2C858094DBE461995AF4C40FFB3 -:105CC00040E3781D547E8F16847EAD0DA113D0E481 -:105CD0007BA1F28E507F25EA6037D789487FA7B233 -:105CE000A0B9078DDFCA88CA37E340E52741D5034D -:105CF000000749300AC8030000000000000000004F -:105D00001F8B080000000000000BED7D0D7854D5BE -:105D1000B5E83E73CE9C9949CE4C26BF4C20C04975 -:105D2000082168A4C70069B0584F2060A8D40E1499 -:105D300069AC8A032244082452EBC3ABFD328100D4 -:105D4000010204B13414A44300A5B7B43752B4D44B -:105D5000523AE0A7C5D6F7BDE0B356AFB66FB4145C -:105D60007F8A12F3AED6BE6BEBDB6BEDBD93734E49 -:105D7000664810BDED7DEFC6CFEFB0CFD93F6BAF1A -:105D8000BFBDD6DA6BEF71BBFC246F34211FC3DFBC -:105D90007584FC2F8D1092DBFF747B4934FD738476 -:105DA00064E698D1441921C372CC389944DF075571 -:105DB000DD23F5B713CF9399334350AF25D70C119B -:105DC000DA474BE67C1281BE227584E411A2780981 -:105DD000FE89FAEEE05C2F29C3577FFB587C9709B8 -:105DE00059172CCA8076CEFE09891132D95A7611FC -:105DF00022FAA4EDBC006F068557A72F289C699353 -:105E00005CB1EB0B29DC7A0CE14E2FA070D3F2C908 -:105E100091CF78C7D0F2A66B5D86075BDF4D480552 -:105E200021ABA02FDA76D35571FE5D31A03C433E05 -:105E3000DCAC427B9D181E5AF65FD51857B19DA960 -:105E4000E5D37641C2DA054B97CC261308C930D585 -:105E50007EB8583D9C7F3AAFE7D1E9F7D2FEEFE933 -:105E6000A4ED3D3900A50409FB69FF958EEFA5332C -:105E7000DF807ED389A55F3A8FEDF08F7C42BE40F4 -:105E8000FC39E7A0F3CF93CF031E487516215306C4 -:105E9000E2AF1F6F51A42F217536B8041D3418636B -:105EA0000C21D7B7265E72E550784C17013CCD9493 -:105EB00035DF185ADE765A463C6CABEDF106359C60 -:105EC000DFEC7CDA6E34EF677425C5039DCF9E2628 -:105ED0005AF60CC46FC1A46E13F8C33FA95B22B479 -:105EE000BF0283906C3A9F60232D17D176247E6683 -:105EF0000CE52FF2009B6F94FEF771513F1E331992 -:105F00000A88E6C07326E091E2A9E01EC7FB4A8634 -:105F1000BF4C62C16B217213E2E90EC0DF95C8F37A -:105F200063117FD12CC4EB50F127E011F80B723EC6 -:105F3000BEBE2651AB00DF4CA5F8037C513CA6D376 -:105F4000F9F6BEE489C985D08DD91D027C8BF95440 -:105F500032FED9C2E1DA08F81B879F5CAE1021BE81 -:105F6000B22E93C94B5C82727A199D01EDCF6732D4 -:105F7000FCCD903509C6DB5CCAF8940E20B92A071F -:105F8000C245FFB0FD660A8F668167B3B7CB2BD1E0 -:105F9000F2760A6F14F04F8E04811FC5BC3DBACB58 -:105FA00086572594E6E07306A7806FBBC9E4D80244 -:105FB00007BE27DD5DAD1285F383192EB2491ABCE9 -:105FC000DF6D7DFDD8FB77F63B287C89A0AF98CEAE -:105FD000EF8367656313C5CF66BDABD545E1D85682 -:105FE000CDE63B90CE97395E4F8FB77892653C8374 -:105FF000C9CBA73E0EC9B4CFAB32E80B965DFE38D5 -:1060000024B87034D03F153D3E35F8750ABF054FB2 -:10601000BEE2A004FDFBAE7AD04B50EE8F78010EAD -:10602000E73803E0758CEB1C47298D9A0A96ECFA49 -:10603000C8138C1162D12F58478727D3CBE9865DCF -:106040009FF84AEDFAD9A9CF15D03701686FD7D795 -:106050003D42CF083D3D69887AC6AC43788B48DF26 -:106060001FCAF3182ECFD30F253ABC147FC57B84EB -:106070009E7EE057A5941F0E829EA6E5831D04D741 -:10608000C38347498CC935D3D713786713B8DEF972 -:10609000419FBEB1E3E7CA76731AE89D3262BA7CCB -:1060A000B49F31878911A7EF0F93F8DCF1A0C78E59 -:1060B000B1F97BE97F563D7D05C7E395871B5D40C0 -:1060C000CF317BEC78BC82E3B7ECA8E33DC7DF15AA -:1060D0000EFC6D837F507CE54B1C8F634909E27198 -:1060E000EA10D73B8E47A7BEEEC3E31EAAAF29DE58 -:1060F000B2830C8F2D6D2E02FAA137E642FD585A5D -:10610000D8E842FDC9F5F6783EBFF17CBD3BC0F151 -:1061100027E02C9E6D5401DEC612E324E8E5CC7620 -:106120008A37027ABAA00ACA3B1E22489FB10FE9F9 -:106130002EAEDF109E4CBEFEEEA82E7F16E4A2F718 -:1061400021C590E9380789B1C62BF5E3379B8F9FAE -:10615000CDF1F86543B6F1A1938ED91CAF4EFC94F6 -:106160001EB0E37FAC834E63DAEDE56C075D6E90A5 -:106170001CF6C710E9E15148D49305E518DA755EBD -:106180008AFB5C5A967FFC940978D63AD8BBCC3609 -:1061900057AC908EE36F6165A54D8955513CDC0687 -:1061A00086172D8F6B2531B047E56A9324281EC7CB -:1061B00005E344A678CBAE268837E2B02F05FD8AEA -:1061C00039131473FECFF872B90FE8B52348F10EF6 -:1061D000EBE26C85B7377CE1ABFAF1EED40F5FAB45 -:1061E000B5E3FDA670BA0D5FB3F46C5B79E2E9E14B -:1061F00017A593D01F828F04DE06D0A1D55EF65777 -:10620000DBCB4EFD13951CFA678874524F91529068 -:106210008B71AE34A3B37060BDED928BDB43DED8DF -:10622000593ADE4222910CDAFF0A921805F83EA68E -:10623000E9F87DA52B9107E50BA467E7C831FDFDC3 -:106240008F52C83189DAED1245EF6A0AD2702F8970 -:10625000A7A33D4CC2DE3C4401E245A2FFDF8AFC1D -:10626000A2B8005F2382EC3D896628500E11F1A789 -:10627000239D3CFC9FF9AB9FF98B44E92BF1A70CC4 -:1062800074A4E3BB4904F9C14BDAB19C46BAF0A946 -:10629000916E7C06A8C68667900425786611039FD8 -:1062A000E48AD8637194C30782C8F7BE3F908FD346 -:1062B000FBE7B38ED36D3809FF48CA053AC4895746 -:1062C000EEE7433FE7436AAFA15ED64A19FF6A9300 -:1062D000E8BA5A86F28F7E17F988E2B702C665F5EA -:1062E00005BEB772BB7A4B9317F5CDE6A6203ED517 -:1062F000A98D61002FB33AD17107A55786AE1AD781 -:10630000D3F90FABEE89839CF85B99DF966630FC7E -:106310009EDCF8C44B8BE8FBB6428DF9412DCC9E38 -:10632000CDE0586C9B9C88ADA5F06D2DF41A56FFFE -:1063300040E8A7ADD7260EEDA7DF3B75DA23FDEBCE -:10634000AC3E9258037253A08226229B27FC930EE8 -:106350007A2DADB8A7C9AA77B40F65A6BC0AA25119 -:10636000E02B3ABF282CEF4EBE6A2BBF02F562DB52 -:10637000A967894E2B14D5C44DC0977F2A3565E98E -:106380003CFC35BA2BAA8154465E053C67B4062511 -:1063900093E22FAB5A9F0632AA119DE96BA53B04ED -:1063A000F23BA0FF91F1D01DB4BFE8B5AA7110D99E -:1063B0004A77CDF7A796872D1BEFFDBA99C4AE0A91 -:1063C000BA24A4FBA96BF3F2C1FFF591607EFA2415 -:1063D000902F951C8475EBDA25A32349DAF5CB5968 -:1063E0005CD835499FA9DAA5CBA4B1CBD26F898BF4 -:1063F000C9A1CBE5C5676619E3A3A252EE17B71290 -:106400003396040E93C3AF2971C2FC39DDF559E20E -:10641000EB6DAE2FB648A4B62BC9F74E0ECF0C7954 -:106420008F09EB6FC646B64EFA28A85D14BE2285CA -:106430003E2DED66F1FA87F8F312F450DE4320307A -:106440003943D3833EC7B8E259FE09C6DD46C79536 -:106450005D415CF704DE9DF4144F97CB87F53EB8A1 -:10646000F6C5101881A9E0D4414687D167017F861F -:1064700050D713BD943D9DE35D6A7F5F74B1793859 -:10648000FB2507985D95C1D7AF93534A9AD1EF9DED -:106490002DFC50BBDE007F18F451E701BAF01782E3 -:1064A000DE60E5CD318276566F1965E42288277467 -:1064B000A3BE2D20119463FA09CBAD5CFFAD07FD9F -:1064C000479FEF93F02DAEC9A04762A7145A69F613 -:1064D000A4BBA7258B1FDD09F231F9D2D6A92FD293 -:1064E000E7426F7829F4AF19674C505B99F3249415 -:1064F00027A75C51F60CCDB5C80D91055F30796AC0 -:10650000E1FC0E723387966B8A93C3D9B9B1223FEF -:1065100082FDE9C3D1EE50F4E1D67E3BBFCCE46A04 -:1065200087437E3AB8FCAF017EBCB479E6D5D0672C -:10653000D08899A02EE7471B9F06BACD93221B5CFB -:10654000B4DEBC7BC26E903FED40375D23F1FD268B -:10655000C0478DDE0E94239AD91D85E7E6B245A883 -:106560009F7B436CEAA9F82ACD74D9FD27A73F3851 -:1065700044791C6F44A701BC7AED7B277375A05347 -:10658000E461806B64F86415A05DD3CF9859167AE6 -:106590006597327DB882F371E66C4A37D0778A19F5 -:1065A0009AE387688EB91FE63BD4F153F13DD89D3D -:1065B00080AF6CCEE72D06E3732107195C0E5AE01D -:1065C0003BE06B12E3FB96607930D93AB187AFF3C9 -:1065D000DFE37C5F4092EBA193AE4BB7C3C6D367BA -:1065E000095DC1009EF749E469987F1697B3CCEA2C -:1065F000980BE011F234DB38539D9D03768A5E0ED2 -:1066000076B118F71DCE6F0BBDE6AFA17D4D71B30E -:106610009245E735AE8C18A05E6715674A563EFF77 -:106620006D5FFDF0F3505F2BEB46BF7CB076DD7CF9 -:106630007EF3A4F0CBC87F0FB42B5EA47BF815ECDF -:10664000E7816EE2B5E89B228E6779E3A92AA04331 -:106650006F2309025FCED71B9F9680BF43E1752E43 -:10666000CB3C66E9763B9EF2F99BD0EFC8463B7F78 -:10667000D69076855CC2BA314A8AF400BCB31FE872 -:10668000467833AB993F4CE1EE45BDF2E9C3FDF1ED -:10669000C5E07E13843517E47D1FEA330A9F225339 -:1066A00038C6CD8E2B5988F7330AC047F1ACCA16CD -:1066B000391FAA7CEF00E0260F2EE72DF08F29600E -:1066C00027477264E03B61F7264E12E66FD9E396E6 -:1066D000C25E0E84A8BD4CE525B32641C03FCE3E28 -:1066E0002D1BD7D32AC36A8804FE9FB063B3B85C5E -:1066F0000AB8B6723B794B5308E5285BEB390D714C -:10670000FEADF92E630D01F9AD40FB6D4755220436 -:106710007E60B0B262E31DB47D5B938EF5373619AF -:10672000D87E4353253EDB6B5E47FB776B88D9BF32 -:106730009B9B4AB9D3C1E0CE1276728D885FDAE1B5 -:10674000A2ED6DFB1FA23E0959E25A4596F63AD3D7 -:106750003783B54F9F648F8BF5B53787D6DE67D803 -:10676000DB57998956F087833CEE2FF45E80D7097A -:1067700056BAD06F1678F694DAE9DE5E937C3F471E -:106780003C9DE3113DCD367F12AD43F85671F85272 -:10679000F5B38EC75F44D9CDED4567BD15325F1F98 -:1067A000F9BE54908FB5C3A4F8B0C461B239DF6D9F -:1067B0009DCDFC321264F13AE197B909B1F9656EE9 -:1067C000BE1F8565D4F751A68F1DF08BF62A6F9FEB -:1067D0000A0ED5D9DF59DA4F85A51F079CA9E073AA -:1067E000EE939137EDFDA4D65F8E76E7874687015D -:1067F000EDC06A28B596B31CE5E18EFA458EEF57D9 -:1068000038BE973BCAD738EA4F7394BFE4A83FD746 -:1068100051FEBAA3FE22C7F7658EEFAB1CE57FB22F -:10682000D72FBBEB93E1F7FF333C09B91A88979850 -:106830006D9FD7295745243E2A0E7E43E6734BE0D1 -:106840005342969473CC1761712D129F60F55FFFD0 -:10685000A845FE00EB58E747665A98CAD581F6E787 -:1068600003A08FC4FBF3D2AB81F13A21F56A7C25FA -:106870008B03B5A3DCA411E5F544295049C2F8996E -:10688000575B8C28F716D3F7567DD5CEE4AD18FCB0 -:1068900022DA2EBA5D45BB2F3A92C4C6D2766A81FF -:1068A000BDBE9BF74F7258FFF89EF65BAE307F215E -:1068B000146EAF02D91D5EDB75129E4EFC84A64796 -:1068C000AF7E06E20B3B981F7E6006F5032C7AEE46 -:1068D0006685E9B7DB944BF64B5F9C28F7F77FE0C2 -:1068E0005B9AD14CAB1C0020C0EFFF963706F18CB1 -:1068F00051109F639B07189F1B49F81F8FC381BBD3 -:1069000008EBCB48ED34C6DBF4BAE029D0757395BB -:10691000121CEF7B52CF7818CF957EFE6AB62EFE02 -:10692000ED63B47B38FE429B2B12518A3FB24D354A -:10693000C61258520D94238F425A3CE5C01E0CDFFC -:106940006B61D565EF157F16C4D9C2585641EFC2A9 -:106950003A067C24C3FE761CCB7E92C07206B76FCB -:10696000C781B3087E00D125A6270D09F6994237C5 -:10697000503F3CC9BA1196AAC62993FBE39492CE24 -:10698000E29152DB337F91205E594A74B64FC5E3E2 -:10699000821B65E96388B70687B6CF13BAC54E5721 -:1069A000A2B49339163EBEA58F9E0C5F63426CFE67 -:1069B000A16D6A23F8310766D9F940D497954BF653 -:1069C00007774E18F3D9F141A63206E119C807B787 -:1069D00006213E2D4529DED2878EB7A06C7E5DC193 -:1069E00079122CFF40326F053A89B242CC05D6F2BB -:1069F0006FE5F0422847A791D246ADBF1FFA7E71DE -:106A00008AF74B93BD1F27ECD5B36CFD2EE1323EC8 -:106A10006C4FD005766461C7AA34AB7D55C2D7E907 -:106A2000473B8EF860BEBBEB93EB3FF1DCC2FDBD94 -:106A300054F502527718E841262BE460127BFC499A -:106A4000E06F8B1E0D38ECC2EA966815B4CFAA75BC -:106A500011880BD3F51DEDBA426E1FEE9C1A9554AA -:106A60002A873B7611B48FB35A16F9ACF3C9E7F312 -:106A7000D9393B2F0DEC957D8B177D09FD156AF7F4 -:106A8000CB181F8F6C82FEF36BD83EBF13BECD7C3C -:106A90007EED8B199E9CDFD355124926874F2ADC49 -:106AA000CF55A212C9EBDF37D97CF2BE5F8DA7E3C9 -:106AB0009554BA0C9FDE0FE7B83E7B2981F84ABF98 -:106AC00046096E027BAA43B5D999FBF63CB86B31F7 -:106AD000F837F43DA88347AE6D1C1EA6703DFAE55D -:106AE00025CFDE057CBFCE45401F0938B432BB9DA3 -:106AF0007BB24F3EEDE3D27E991F47970F39C9FE17 -:106B0000C9E5E2A3838F9B8A4F9CEBA9930F2E6567 -:106B10007DB851BEFCF9FD18E490C293C7F3B58669 -:106B2000D5EACC6FE37294ED158A848D93C7F92C66 -:106B30006BF6833EE0B35DB5E5283FBDB31749A0D2 -:106B40004F441E54AAF152C193EE6EF7411C74D704 -:106B5000E207A56478CB8FB0F890F3BDE966FAB48C -:106B60004D6997A07DAA7AA3DC9C1FB85CE5F379F8 -:106B700085A6C6C380AF3C43216B28BE76CC5E544D -:106B800055027C47E510E22AD53504ED877C93ED6C -:106B90000B0529BE9EA4EBDECEC5C488D37A3B4D3F -:106BA000D5B61F23E4D0C98F3B175F5CBF10AB7F06 -:106BB0004EF95F716B6C7FB09814831DB523857D92 -:106BC00076A9F80D2D76B1F86875F920FABCF9525E -:106BD000D7A9F9D7023F0E35DFCDA12FC853BB6629 -:106BE00095805F6B507D4192E1C7AE1F06C387134E -:106BF000FF13009FE99F1D3E9DDFB3DD3CBE3D447A -:106C00007CB4D516FD0FDC034F51DF391FD14EE4A4 -:106C1000A77D91F4C820FF2670E818F0260C7C565A -:106C200093303EBB95C857DCB4FE4CD28865117FCB -:106C3000AA53828C1E3CFF45EC732BD319DF8F9B2C -:106C400048629DB07E4C9DCB377F15F39C178C36E8 -:106C50000A47127F8A903538EF118EF558C427867F -:106C6000D5B7CF2EA7FD8E98EDC2F8C588CA23B63A -:106C7000752CC0E547F4B7BB7268EBF3238EF5F9CA -:106C8000112581F95D8F54AE6986E546C97A339442 -:106C9000ACFDB80E3B5EB77ED4E50B278167F7E20B -:106CA0006398C7B5BBF2E2F1934706E19B7172723C -:106CB0007BF68B1EB6AFB43BD37B334B2E5A6DCBDA -:106CC0004320B256681D77F74724337C517D629785 -:106CD00097AD6E9E6FE0277EE0FF54F810CFCF1A7D -:106CE0000F8F4E6B5C164ED2BEC4C3EC89759924CF -:106CF0002A533E79F4652506790E84EBE18A9BF5EB -:106D000018D80BEB404950FDFB6815C1EF1599FCF5 -:106D1000FBC33AE6558DE8205195AE67235E5ABC19 -:106D20002393D66B5B4C3DC7C2FEF76DC6A956D800 -:106D3000177EE20517C6732B7C71AF41E755C9D7A3 -:106D4000C1DD8B4F61DE71748F628C45FD2E11A900 -:106D500002BD785B1CF3845B61EBBDF1A04FA7ED36 -:106D600077E909ECE79B534E7975D82F2FE8F6C2E7 -:106D70003CB754B2F5F2C8E2A2AF96205AED79269C -:106D800033E5A9DD261D6FCB62B65F9199E8F67AEF -:106D9000E87C02B50AB99EC217D0D87CDBD6911820 -:106DA000AC53E53C9F442273D01FCE77E409E5390C -:106DB000F24D82C6CCB760DF3F08FBFB3009B97EDD -:106DC000C755A06F1B5C3C0DD54439F5F3F9F90D9F -:106DD00013EBCF948FFB60DF77578B12C4F5CFD1C5 -:106DE000AF731E411239694AD80F8EB3EB21B64EEC -:106DF00006276B06D558B429873B48E1CEA643B693 -:106E0000D8E11678758EE37794DF14FC3C828C050C -:106E10003D24E2CC027E27DFE654C48E3E4FE7BB22 -:106E2000FB050DD7EBDD95CFDFD200EB7CA907F397 -:106E300023BEF4C1A1FA7FA1CF5FBF77AC189E3704 -:106E4000E41F98D4007880FC8889A42F8E97073D92 -:106E5000A3FDCAF59A18AF6C5F8B3B075F45FDB485 -:106E6000BCE5D4CB75108FCEAF2768FFE62B8C3FE7 -:106E7000FD2DAE5833853FE79A76E48711B571044E -:106E80005AABED92A29678A7C8FBF6D747308FE2AF -:106E9000FADA76CCF7F6F3B8AF7F523BDA4933E44F -:106EA00057BD68AF71FA89FC77217F4EFA942CEEBA -:106EB000AE817E46B42806803DA2BED105709554B1 -:106EC000D2358BD2ADA4A34B62FE1FCBA76729CFCF -:106ED000F419AEC3BC2CB287E5178A3CF040BD9DC7 -:106EE0007EC1BEFCF9880BFCEFC20EC7F770CD1B4C -:106EF0008C0FEDF42C52393D4B781E21C7C3088E00 -:106F0000872DF57C7F4EF3C62E66D7BEC0F7E75EB1 -:106F100084F98F1BF8FDA614FAF746D0BFE0B7BA84 -:106F2000BA5B011FE41A17FA714E38B6D633BD7733 -:106F30004075D9ECF8CB1DFF36AEFF6557E2EF3256 -:106F40007E7DDFFCFF3EE3DFFF771E7FD3DF19FF8F -:106F5000BBFECEF33FF41F3CFFF9A592CD4FEB549F -:106F6000BDD8DF4F3C223E66D7DFB22BB9BFFDBA9A -:106F7000EAB2E5138BFCC4E9B5E6428897F80D76D2 -:106F8000DEC3D9DF0CF9B956D083BB785E36D5A302 -:106F900026E4A9664C1179324CFFD570FD57C3F534 -:106FA000DF91147AB5BC92E9776A5FC4F442583233 -:106FB000DAD19F099C56303FFB08A1CB0CE835DDA8 -:106FC00093343F3B8FC3EDD4A7795C9F963FE7781E -:106FD000CFF5A8739D2FEC8B9F128C9FFE7795E7C2 -:106FE000033BF4AAC0C3AE4A662FE7CC4D6E0FB682 -:106FF00039E8A84D6AC4FC03273D5E57997F2DE808 -:10700000B1D06BBEA2E6A6A67782D3FB3A4EEFDFE5 -:10701000A83C1F8AE789A4A277A5878DF379FFD9B9 -:107020005033CC265C857490399D64D2D68DF15F47 -:10703000F24D62F52FB77E44ED1058FF35CD584321 -:10704000CB9FCF212E9174FF91D89FA37FEE6E1618 -:107050004795735487BFE5B483BD513837B3DB74AC -:10706000C5A285604F74EE5E09EBD30B6998A7BC8F -:107070003BB3E339F4E7DA272A0087B01B098FCF47 -:107080008249C1F2509CFB4E76BB7FF7475D71B0E1 -:10709000BF828512C6FD5AF50773929EC773D8FB4F -:1070A0009AC76FF377C9F543B3DBD7727A537F3151 -:1070B000D76391EFB5FE9913591E547510F67724D6 -:1070C00073A60BE2E9A9FA8148EF39CB7E539D62A2 -:1070D0008E84FE24F01F4BFBFD47420A587C5ECC99 -:1070E0007FA8E707EAEF62FBDE1CAF39D7747D2A81 -:1070F0007EA4F0FB453D919FE7ACE7F4C7AF779BDB -:1071000053607E43857F2F301CC4B3CBE49A64F177 -:107110008304D7AF5AF8B1676FA25527CD93587C37 -:107120009F9A6DD6FDB4B61CA52659BCEB975C4E54 -:107130007EA3EA5CAFC7499684F92404E625E4D12E -:1071400039FED57CDCAB2F73FC17B85C5FCDE59ABC -:107150001003F763528D5BC5F586787ED271137C80 -:10716000DE552A8F6B0C32EE1C3ECF399739DFF398 -:107170007CDC39439CEF423EDEC2CB1CF7433EEE43 -:10718000C2218E7B37C7EFDD978967C52BF17E86DD -:1071900086E7663E5EF3658E1BE4E3360F71DCED39 -:1071A0001CBFDB2F13CF057CDCED0E3CA792DFCE9E -:1071B000CB1CAFD4CBE4E700975FA75E13E36BF97A -:1071C000AE30B4DF1DB2F77383878D2F9E24FE315E -:1071D000FAAF23F8BEEE9495F72E32938C2BEA3B50 -:1071E000D7E354E3DCC2E335E229C609F0FDD02938 -:1071F000D7D07192E047D4BF5A657A3055FFCB386B -:107200003CCB2E711EA27E15F43F3975FFF7713805 -:10721000EE73C03F58FFA2FE9C41E06FE570B45E84 -:1072200022FCA2FEC241FAFF0E87E33B9708BFA8EB -:107230007FF720F87984C3F1C825C22FEA370FD22F -:10724000FFE31C8EC72F117E517FFB20F8798AC384 -:10725000F1D425C22FEA1FE89377BBFC69E23E0612 -:107260008394429EF1289266E0FD0646E224F801EE -:10727000DA6A76BF01E9729E87B29CA3A2227EF2EF -:10728000BE9228D4DF7B178BFBEDBD9AA01FB137D0 -:1072900097E729F3B896C6EDC1BD57B338C8DE10DD -:1072A000FD6EF1CF44BC68AFC1F29C7B0B581EB39E -:1072B00056D68E26260E97C74D441DF269D8B92A98 -:1072C00061EF89F3556B799C6AAF49304EB5B78C45 -:1072D0009577579398ABD072EEAA348EF9A760D801 -:1072E000423CB6FFDC984956975BF23156C731DF16 -:1072F00040E179231421C49697E138AF25F60F6F4A -:1073000032CC19A0E60A27B1FDBCC2B0DD7FA88748 -:10731000435CB4FEEFB99E0C4E4A7E9EE6B05761C8 -:10732000F4E3F99AF3F8FC05DECA393DB7CE79AF3C -:107330007B3A9DE7B353DD983FFAEC698EC7A9729B -:107340008CED9F1377B27338A9E26C5A47E3293862 -:107350009F7BD373C40032FAF798EB748CAB7D84B7 -:10736000FC8771353AEE4D7BDA15E0BF591DFA7492 -:107370008807CE7B4E5FAB41DE7507314C40EF474F -:10738000DFC07EB25A881163A46A0EA29DEB88CF3B -:10739000F17393223E07E16AAB7F398BCFBBBC25EB -:1073A000B80EB6EECAAB3D36FB7516F733BF627A40 -:1073B000ECE725F9F9C7590E3FB3C36B8FD7691DA9 -:1073C000E11910FF96E79D31E1FCF3B8B0141C46BB -:1073D0003FDF16DEAE407C72D69E46CC5F4FB5BF17 -:1073E00095F1F05CBFD57E17FBD9BFD973717B5D7A -:1073F000C41944DCE134E4157BC04F0F71BA30BED0 -:1074000012FC91354FB2F1498797E9910E2F8BE32A -:10741000FF179F7CBA7CF23BAF3DFED001DFA83C5A -:107420009618C9F7E9EBBCEA7FC9EB674087802F64 -:10743000391D487D862D8F58E45539F1B681E34DCD -:1074400094BD29CEBD14F8F83AEBF4EB5F8D54C12E -:10745000BC449C8690FB1DFB9B538D8BC5256471A2 -:107460005F8CEB5519E653EAE3FA47210AF6EF98E9 -:1074700007CA7D1E9E53643038FA5BC7CFAB89794B -:10748000B98BC326DCB742C7C0FD3EC8573F520682 -:10749000EB63D0366FD3C7D69B4DA58CDF36952ACC -:1074A000B174965F65BFB7A8B8D39BCCAE104F62DE -:1074B000BDB7A26820BC6A71246A8547E5F038FB35 -:1074C000999B129E3A5BFCEB52E1F18C27A41BF8CE -:1074D000568911A697BF61EBCF551AC3F3FDA9FAE0 -:1074E00051743E2F075D528DEF2DB0E741A93969E8 -:1074F000367E57B42C479E9483BFFAE242431BCF9B -:10750000796EB1859F4771B6F729EDC44882779FA0 -:10751000EECCC788211D9CE76ADC4107DC8EFEDBD0 -:10752000E05D923C1C71DFD006BEAE6D5462686FA8 -:1075300045299890EFB98EF3A5128CE1BD5EDFF678 -:107540004949E74F8CE4EBAD529C1C7E6F811DEFE7 -:107550006A4E969D0E4AF2731C1B85DC070F98F647 -:107560007BAC9C727EDCB8D87ADE77AF96F43BF9C0 -:10757000633AA5833EC73D0943A4AFF261369E6BD3 -:10758000EF2B53BD0AF15A2A2398CFEBAC7F46E08C -:10759000EFD54E845FE8E9F43D22AFF693CD4392F8 -:1075A00008DF27B7B74F29875CCFC99CAF9F1E6400 -:1075B000FEA9E89B56ECCC2B1C1A7D7D20F7B0EE83 -:1075C0002926BF0CCB2EF7A9C6234136DF4B95FBEE -:1075D0004F0A67764D84803E53431112A1EB7C7EA7 -:1075E000A81DF7C935A9270AFE1895291DE8BC3B37 -:1075F0005B67F76658EA4DA3EDDC85AEA81BF24049 -:10760000F87D30D110E982FA108FE92CEBAFA74951 -:10761000240CFCAEE52A61782FFACB986AEF8F9A9A -:1076200009B2F51C96C817405787CEDF3D85FAA7EB -:10763000B4BD4AEDD07DC9F4491AB343D39FF29942 -:10764000982710D662C092F9936298CF995F470C41 -:10765000F0E74A3ABA498476FA6D8063327CA7F340 -:10766000D620FFA31DF7ED733CECDC7A7E7DBBB426 -:10767000D0324E691AE3EF6973BDB84E7CA38A9D80 -:10768000DBEB0E2D6AAF82F12AF97D7A390A194EA9 -:10769000F1E17FC9C3FCCF490902F809F2BC863782 -:1076A0009B48F9E2B184BCDDE4C5E7F9A6203E833E -:1076B0001FFDCF10E4B9AC9B5CA143BEF507FEBA39 -:1076C000D1B06EBCDB14C2EF5BBE65E8904F249F67 -:1076D0007A19EF8FE8E7F7A84C2A210F366102FDEF -:1076E0002CF3EFF459F6F9FBE645E7BB908EB3595E -:1076F00072DD0EE3417911F2A957562DF91F2AF7D1 -:107700001BDDEB48F8B132B8C72426DD5D6679EFA2 -:10771000A3761BACAF938348F77E7CC69A39BEAF85 -:10772000067F37FF398ED7B99517DD37696B8A77B2 -:10773000578FED2F6B29CEBBCD714FBB2E0DE2467F -:1077400070D8938E377D6EE930C0D743EEE4F72FC3 -:10775000C8C1894631D48DE6BB500EF93D2BABC66E -:10776000EBC3322DFDCFE17C299FFA29E237BD8C96 -:10777000E587D0BFD9F996FCFF82481DDE8F441AF9 -:10778000D93918B10F39FAD644336C498C5E6D3F44 -:107790001F33939FF32C5CE7C2FCD7C229A843494F -:1077A0006133BBBF6ABF6C94037F3F4C5EC88403E8 -:1077B000EB0514BE9154540BA3F67EF62F99FD0CE5 -:1077C000C401C4B9D1B52DACBF51BA715A87F849BB -:1077D000990BEDE5D1C4F042FFA3351781734563E2 -:1077E00088A59F4238476BEFD7096FA1DFE5827804 -:1077F0008780671439EA3573B07F12A3ED0BA89B1D -:107800003722097CCE71C6887A579597C7499271FD -:10781000494F33EC0B0D187F907E9BD2B81DEE279D -:1078200001D0E77B2436FFE8B3B27110E87AF72184 -:107830008CD714ACEAC075BD238DD977EBA93DA0D8 -:10784000B9C14EA1CFB1A9F9500E52C465E0FA9169 -:1078500094FF1E4DABDA9606F1B0B469DB800FD30E -:1078600014FD6B783FE76937817DCC34B31DE50F9C -:107870002E64023B6373595106C85B5AA39AD45FC6 -:107880006B4973237C7BD22405F242296FE1BC94BF -:107890007AFD3B3369B13BD7FC1E8CF397DC083E85 -:1078A000C5FBD0A25A1DF873FAD2328C7FF5764808 -:1078B00018FF7A438AA990AABD7C5EE304B82F67BB -:1078C0004E66E41168B7548EAF77537856DCDA58B9 -:1078D00002F8990DF97EB9305C94F98305AF1B0A63 -:1078E0009C072B50E26ECADFDEE0A997D8335A0519 -:1078F000FCEE859330949E8162F32DF09BFCFC1C82 -:10790000924C7AA2901718984AC8EB16BA814F6722 -:107910002DC39EAEB59C0AFF833D17D3B6AF8F85AE -:1079200055DE3025B40B62883F35684C0038E5D011 -:10793000E9BC62CB3AE7E1F3F34C5FC4EF4932B9FB -:107940007F6310AB7FEBE1F3021DFEBAA5BD3B6484 -:107950002FCBC14F771EC2EE967EF1D77340C7B5CD -:107960008FBB31EE39FD7177FC3A5A5EB14FC2756B -:10797000C67582E9F5770F4828F771BF8A7AE09DCE -:10798000A017CB0D9EEEAD5FA0E59EC765D28968BE -:10799000A9C57BA5CE89F5F4182B2FE10ED28A7DDF -:1079A0002717407F75C73C04D689153F5D7AE317DA -:1079B000687929E563A8B2E260B33A9C96EF8A49F8 -:1079C0005D50BE308D209F45B3D418E4B55C08747B -:1079D000E7DDA4E13A46F471B0BFDD9D378FF2E3F5 -:1079E000B2D86333A1DDB2C3124452E93C0E3E93D8 -:1079F0004FE15AF17D09D7C7E587D2D95D2B1C7FAE -:107A0000E7E854AEA3DF57D179823E5C4ADA6702D9 -:107A1000BD561CDCAE5AD7B9B79B4A31F5439457D3 -:107A20007C9F8E43DBADFC9164C0145742BE03AC17 -:107A3000973FF5D5EED7607ECD6A891FE6B54185C3 -:107A40007A4B630B9FF0E900DF3E7526FDBE6CCFDD -:107A50003E754919E08DDC0EEBEAF2435712DD4228 -:107A6000D7731D32FA0BAB32BD9D78BFA966BF0F2D -:107A7000A51F2E62836B19D71BD4EF53ADE7DD9E94 -:107A800048CF443E5D7E48B68D23E81F3D43D879FC -:107A9000B49FFBF13C9AA09F58AF04FD56890BFFA1 -:107AA000949E8A64F06C057AC0B91BEADFC0F3C10A -:107AB000A6103E1F6AD2914E3B018FE3585E0ABC6E -:107AC000A7725B05F756054CB8180CCEA5985590D3 -:107AD00087991566E5BC5B23927E113B5D3C77BAC6 -:107AE000230BC1C8999AFEDD190AF5C776AA91BB86 -:107AF00021641D543A6754D335AF3E3D5C916ED935 -:107B0000F75B2FB1F37D9F4BD771FEEBF355C4F7B5 -:107B1000CEDB2AF6F3F813AE933B6F5BF208C4C7D3 -:107B200069FB2FA6837FC1F7FF52B5CF5B50696B0E -:107B30009FB7A04EB49F89EDBD176FBF73C135F6D7 -:107B4000F1172C13ED6F44F8B58BC39F77FB54FBF3 -:107B5000F8B7D763FB060FA36F4FA617F3AD5B7C97 -:107B6000461CF4315EA83609F2C94B3AA19E5877FB -:107B7000A8E637217F5B3B9C59BE8958F968DA0239 -:107B80008003F2B2AC7C9451996693AB4C33CB56E4 -:107B9000CEAE196EAB9F1B2EB27D1F567B85832FF9 -:107BA000353CBF8865000A0C730AA73A5C457D54D2 -:107BB000359CD9C1F79EF061F9DE6BD8FCEE1DAEA5 -:107BC000A11C03CCE097DFAB463E67BDBF95C03D2F -:107BD0004854A7DEA945EE8379F4BFD75DF03E8D0A -:107BE000E73BA57908EABB0D8515FBA3167CB68E8D -:107BF000A4FC40CB2DE92AC33BA7C386914B425638 -:107C00007B7DFD48B516FC0D787F8706E385D7C3DD -:107C1000780D6A4F09D81DCE713C4595B671BCA34D -:107C2000EA709CEDE92C9E2AC6F18CAA738CE3AD18 -:107C3000EDE4EFF9383B80CF528DB3A1E81AFB7C1D -:107C4000462DC371F63AC6D9306A99639C34361F03 -:107C5000FA9E8F13BBD8389E3153EDF3195D8FE335 -:107C6000FCC0399FD1F58E71341C07DEC338D4F0C7 -:107C7000D5E1BE2CD5D3B304E9FF0B1FDA39AA270F -:107C8000F228DA39AFF8D0CEA1B54CA8474A997F8F -:107C90007B4F7A16D2E783344A7FCD4AE728CF3B21 -:107CA00088A25F7C270791C4284454BFADE43CB848 -:107CB000F8F09C51CDF03C363DB410FCD187FC1857 -:107CC000C77BF7D874F58E24FAE8CE76F7B98485A9 -:107CD0009FFBF42A8FC786D2D93EA4289FE3F19F49 -:107CE000D7214E449F6FB809FA436779BCA81FDEBD -:107CF000666C778EEFEB9DDBC3D6A90FB69F71A3A1 -:107D00001D11252F9451B8E7F369DCD96EBF2FB34D -:107D100081D3A3E7A71E760E889823F03EBC8E6C15 -:107D20005BBCF07727BEFC0CCBBB2323E0DEDFAFD0 -:107D3000B73EF634547B515A3872159D6FEDD1ED34 -:107D4000EE11B4FCAE3BB1C0D02CFDD4BAF1DCBD19 -:107D5000F0436E8EB86DF6F32D75F6F26D0E7BFA6C -:107D6000D5F422B13FCBC6D5636EA0D77CD863A52E -:107D700024BC0D9E987C17447A2D08B2B6029E86CC -:107D8000FBDD248EEB5D2217E39CD15C8CD344C4D5 -:107D9000BAE5806F81DB6B86293D17DC27231E9DAA -:107DA000F0264EA49B2EEAE7243AFEB71BCEF10C38 -:107DB00006FFEDABEDDF49D46DBB8740F0C1D76A5C -:107DC000ABF69FB5F0C7CD9159FBCFDAF034C7566B -:107DD000BEADF1665BFDDB572FB47D5F18BDCBF602 -:107DE000FD8ED6BB6DE53BDBEFB3D55FDAD16CFB27 -:107DF0007E576CA3EDFBF243DB6DE5155DBB6CF5C7 -:107E00001B8EEDB37D779D18FF15F4037F23E37977 -:107E1000E7F7B5735BC17E7B3FA8E07ECE9B7CFF1E -:107E2000EE6D7EDFCF4AE0BD29203F13BDE0373441 -:107E3000A45179A6B6C4042D777DEB54D02304AFAA -:107E4000D428D746AC8F5267770A3F9F2877A8245B -:107E50009E0DDB2BFD71D81EB9FFBB92A0DF27A6BC -:107E6000FE2E772849BF2B092569BF17A49E12B0A3 -:107E70001FA32F7B929E03EF974B32825CE43EC997 -:107E8000F32E5267F5DFE66B2C3EF44CFAB4F95A48 -:107E90002EDC8FC1E4BDFE48FE34F01BEAD57849E4 -:107EA000B27D9BBEF1BA24BC3770BEC6E4E5AED845 -:107EB000085B3C6DF9A13136B97F292D729346EBF1 -:107EC0009D3F29A39E25F1A7467DF52A18DF9C0F2B -:107ED000EFC9B15C5C1F5F6C32F79FA57EC04B4D54 -:107EE00035F8FCD7A6F0FEB3D4257CB5A916CBBFD8 -:107EF0006F8AE033D15487CFD79B1AF1FBD9A6D52F -:107F0000583ED714C5E79B4DADF87CBBA91DBF9F5C -:107F10006FEAC0F2BB4D317C0A3910F62E09737B33 -:107F2000526C981056EEE57390F3441CD3C0FBA33B -:107F30007AB50F4AC08EEE7DC98379B7A9F0E4E423 -:107F4000BBD4F43371BD5F12B3C799C5D397C6E8EC -:107F5000E373911AC891D83856C5385ADA2FAE440F -:107F60007B9CBE57D865B231634E927B3BF142E4B5 -:107F70006183D349D43FF7DD7FAF585406F42942DB -:107F80003CA53D253732BAED37BE7AD5E0F8439BA4 -:107F90002F7F201EA55FFC6E14C4A7DEC915F8EC68 -:107FA0001E05C12D450BEF023EEC3DEAC179F51EE1 -:107FB0004F67F92810541B42FEEBF243BE98553F21 -:107FC000ACE8CA8CD9F5457ECCAA2F7A4FEF0F804A -:107FD000DCAF0AC9B1B313813F4CCE1F8CEF44FF15 -:107FE0002BBA0A639AAD1F7BB9B75DAAC17B1F8903 -:107FF0009E312F89FF219EAB422A8EF3F6A1319844 -:108000007F40FDC4D85916EF8CB17143312B5FD638 -:10801000AF4E8F9DCDEE872F55BF9F367C841C259C -:108020007FF0A63E8F3BD89328FFA6E2FD6EC7DD0A -:108030001FC0BAE3A1FF7F8CF9420A9645BF0D5DD0 -:1080400072D403E779C961DB78B49D2E7C7458AF94 -:1080500052D3DD9E0FFE7BE0255CB7D9F9F2089C78 -:108060002FA7FD5D50B456E973FDE7CB1B385FAE1B -:10807000F026D4087DF5CED13117CD0779BBE97450 -:1080800050190B7904ED7871445DD7F86AD08FEF01 -:108090001C5D9B07F1B4E572EFBDC9CECD7EA8B1E2 -:1080A000381B89B97B1296F988F80C21B45F6F3FB1 -:1080B000FCC0E9E72C65A7BE164F979FC5DD571E8C -:1080C0003E33F30B14FE95C7DE53018E635AC4E5AD -:1080D000B7CC5FE2E7EB971D7A4D85F9BDE98E9647 -:1080E000DC7F113D35104E2D64DB0F8D926E90E3D9 -:1080F00045EC3718809FBEF60A15CDB77EED26F009 -:10810000BB0E62BF429C7B584CC201C0D7A2A3CB1E -:10811000313EFCD61337707BAEBD02F8E31DE2AAF8 -:1081200081F9BD439E0F4CB4E0AFD8CFFC18D2CA42 -:10813000EC18712E90DAB336BB666987BDBC84CC6F -:10814000CD03BDB1E42137895114DD452CF72FD182 -:1081500079E7F899BDBB9434AE077B4EF130FF60F0 -:1081600051902823A83E5DF193872BC0EEBFD2CF5C -:10817000F61D451CE3AE2C66EF2DCB89A9B09FF010 -:1081800087A313E77F01B8CF135B0FEB32C948BE5B -:10819000FF7747AB1DBEC1E077C22BCEBD0F88A7CE -:1081A0007038E44352D2FCB4297ECE775C8FACF1B8 -:1081B000DBEDFC0D8EF26C3F8FB3CA44063ABF1361 -:1081C000F4465D19F81DCFD9468F788CB53ADCA7F7 -:1081D000150E037F51BB6002B1D4FBA316C1F7E7B4 -:1081E000A5E796E03973253E01F3F1BC04F314557D -:1081F000CE0F725A6002F91CC4491BD1A95FEB0B68 -:10820000744279BD9F9D836A0039A5FD6D09CC3C00 -:108210000D717D2F698F9B85B0FF6D8F7FFB747B08 -:10822000391DE409F409BC007A1804E345E9A5F610 -:108230007A7EC35E5ED687A7B86C3DF711F06A718F -:10824000F89D2152A99CB7DACD2BBD0C7EB8111C2C -:10825000EADFC3EDF995448F62DE6288F1C13DB378 -:1082600058DEC43D7EDD88D2EF9262E2F9880DD0FF -:10827000D4B28E357C28919845AF37283D2AF065D9 -:10828000C3870ABEDFAB45BE057855898976AE97B0 -:10829000220DF6AF15ADC666F792027E2FA0237FA2 -:1082A000A1CD1FB4F97B422FB8B95EA4FA62833F17 -:1082B00017F460CF4CB6AF9E50D9FE0EABA7F6D7E1 -:1082C0006B033852D5F3F5D7DB9EACDE8A9FFCF00A -:1082D000892895F765FFF2ED006CA6BDA5B4E741CE -:1082E000FE43FDC17501E0E337956800E6FD562CBD -:1082F00079DEFB2FB9BE837C27382FBF92D3E9EDFF -:108300007FDE7C23E0FD83836E3C6FDF70C813F754 -:108310005022AE3C7A17E3A7439ED7587903FE6EEE -:1083200054C331BBBC2D7BF4DB793A6EEE4547F08C -:10833000FBD8D17E5E79E08F33C11E69203DA8272E -:108340009CED60FC0FB370FD5A08E7FE9DDF45BE53 -:108350005503E7FB86A39B31AFAAE1E82CCCA36AC7 -:1083600070C8791DF7438EF9EDBFB321F04162CC9F -:108370002E5EFBFDEF4C788DC273FEC0AF03922DD5 -:108380007EC4F4446FD71DDF7B524FADDFDFE57E47 -:108390007D7FBB18B6D38F313B9E1C67CF7A773C6D -:1083A000007E53FD3EB7413508A9FFE1FE47BE0BF5 -:1083B000FCFDB207E30DCB7FF8F48BD7D0F2F2C708 -:1083C000DC39B3D93434C80316748133EE90AF2B43 -:1083D000E8B0ECC74FABFA55ECFD0359FDF458FE7D -:1083E000D849955C35107FD3BB4EAAECFCB9832EDF -:1083F0005DAFCD04BB7BEDF7FFAC827CBD75422247 -:10840000C30A07B6AFDBF734DA758027A423A75376 -:108410001FDD06D02B7EE39393B05E10D6B1C1E88A -:10842000F55DE0995CE4EB1F3D09FB05FFEA3100D7 -:108430000F753FFA4600E6F386D2C8F8FBE175797E -:10844000B08F5EE78EE605F1C9DED7EDFD26F2DDE1 -:10845000D233DFCC637950663EFB5DA3683EC60134 -:10846000F7DC84F35C4222C87F750FCB9887FEBE91 -:10847000426A1E4B221FD705981E7BA3D38397DF2A -:10848000BD010A17FCC5E7E5183B6FCBF212BF2907 -:10849000F63DE0DE465A7EDFCBE8951B70897BAD6A -:1084A000BC36BE3DB0A11BE8F4F6487318C42B29B6 -:1084B0001EA21C6F12E821F9CC8C618C4E44572A05 -:1084C000783BAA27A7C37BA8DFED367D136CEDF8B8 -:1084D000BAC6C6BF878F4FE14E03FBEC8D3C6AEFF7 -:1084E0002499DFF280907F6A7F58F8CC22E74CEE27 -:1084F0000F6C64722EE43E36A706BEFFDB0B4C8E7B -:10850000A01DACF314AEF830FC7E729E847AC14399 -:10851000E2C9E4FB809BCBB7FD3BF5CAD1BE157C1D -:1085200042E15760DDEAE717B6CF4BE980F6DB9210 -:1085300087687BAB7D0EE3623DB5FFBD65BD5FCA5D -:10854000F5C13501C7EFEEECC91DD27D79F5EED846 -:1085500023DF05F9A5F20AEB4FFD0FDD9827F2A7FF -:10856000C34FBDF875CAE77FEA12726BD7A74EB941 -:10857000AD3B32992493DB3F6906492AB7F47D521B -:10858000B9D512C8CFFF51FA54E06F51C09EE7240D -:10859000F4632A3C3AF5E3DFFC3AE2D3A91FE9DFB2 -:1085A0000BA462201F0AFE137CB7EC072BF0774167 -:1085B000FAF853F05F1F7F0AFE73CED78E3FE7F7BE -:1085C0002BC15011F162FA74AF21513FC4537F2E79 -:1085D000633CF50285693DA5F385C385788E789D5A -:1085E0008FF9E717823D81AC32BC0707CB3DB9EA72 -:1085F0007AD017E27D8F8FC5BF2F847B02D63C9047 -:10860000D78ECB01D8EF4AC4484D327F846A648448 -:108610002341527D67F1E20B60FFC17869A362409C -:10862000B719B2366A35F8F9EDECBCFCE2E6AF05F5 -:10863000601FFEC2F131DB407FDDF9AC4CF8EF2862 -:108640002A906F7207A7FF9B24BA732A9DE71DC764 -:10865000995FB1B82D39BF2CE3F59768F7A8A097BB -:10866000A85FF0BA351EBE8CFF9E64DD1EC7FBE31B -:1086700037205F2D73F05584FB8D3F147C7535B921 -:108680009AFB6D2E6B3EDB0CB96C1BD825174EB3D5 -:108690003864EF7119E9D17B5862F94F100F9E02CF -:1086A000FCD0A35AF3D8CE03FF25B9DFA0EFFBE33C -:1086B000BFABB89F56A97FE29509BBE9F3FC132F26 -:1086C00097FC0CCA3FF9EDA857C8C0FAD34FFC0578 -:1086D000F7B32F9CF0201C174EFC72D4FD507ED2B5 -:1086E00083F7D55C58E361F99F27FCB1B1F07D2495 -:1086F000CB175AFBF33F4F48E0BAD482747B29C0B2 -:10870000FCB1DEE3FFFE7BC81FEE3DEED1611E0D26 -:1087100027D2717FABE1491FC6692EFCFCCF15D66D -:108720007CA6CB9DCF4A7E1FE2053FA9853CE50B89 -:10873000996CDFA0E16753F6C339A215474FAAB081 -:108740001F33FD177F9D007AE7C211664FBCEB4EC9 -:10875000EC857DD63F046EDFE086F82EACD7C309EA -:1087600069CA885D0FF7E10CC40BC3C3058A07987B -:1087700017C54B1DE8CB54F8F83FFFB0F8786F01F0 -:108780008C5F7FFCF32837FD78914CF6DE1F83A3C6 -:108790004D74FEECFD893F4F00FBE84F5DCDB8CE38 -:1087A0000F36EFFC8CFFD7E62DC58732EFCA7FD896 -:1087B0007933FE3F11D059DE9F430E06F2F94FEE9A -:1087C000C5F28FFC06C23B44F9AFFD879DFF27A48D -:1087D000FB114AF7C0E074FF6F196C5FF81F6FDE82 -:1087E00083D1FD594E777F10F2102EFCFCAF185F3D -:1087F00017F31F6CDE3BFF93CE5BD8439B5C467B3D -:108800005121E461C7BB750AE7BAD2B9ED1096925F -:1088100079DEB513AE6732987F214B2C6E4346B29A -:10882000F811E1FE46DFEF416AEC7C95A2AD67F7F7 -:10883000912906DEAFB7E98A4506E67690F29722DF -:10884000502E988ABF73EBF4BB942BBE741AECFEC7 -:1088500096660A1F1DA7C5AF04A9E544DCA5AEB8FE -:1088600067023E5F83E7061EFF7207559BDFA13953 -:10887000FC059F6EFFEEE1FD7BC9A920E42F790D79 -:1088800005F3537DA43D6ACD37F0104B3BFABD1381 -:108890007E10D0624F5E2AFEFE9CC1FC4F592AEF2B -:1088A00086BC5832DEC5EE3727EC5CF1A60223B653 -:1088B00089E55D78EDF85CDF0D785408F50FD9BCDB -:1088C000D0AF24DC9F5478174AA9CBF4D9EB717F41 -:1088D0006950FA307A8CAAE7F45965A387C0FB4542 -:1088E000E862A387C0EFA5D2C5490F27FE7F95C1D7 -:1088F000E274824EB67C905CE697C4A981FCCBC33F -:10890000FB312EF2CE3FBF7623F0E9F29FC9C44B74 -:10891000DBBF7BD84FE220BF4A4C053F6BD95119D2 -:10892000E3C2FF174BEE49A70080000000000000E3 -:108930001F8B080000000000000BED7D7B7C54D5F0 -:10894000B5F03E33672633999964F29ACCE4C52496 -:10895000811834E0248480823A218020F43AA008EF -:108960007AA38E10209827485BDAEA8F09411A1EF5 -:10897000B641E5A1453A2028ADD8061AB9A0A8838A -:108980003CC4566FA3E5DEA2450D8A82C823A51715 -:108990003FDACF5BBEB5D6DE3B73CE6402DAAFBF43 -:1089A000FBFDF3E59F937D1E7BAFBDDE6BEDB5F761 -:1089B0005CBE0C7FB73076595C196B652C83B1BAFD -:1089C0005F3B184B67ECC19D09E1C9F970DDF5E922 -:1089D000503684B1734B7A0E65C3FDD02F15DF5628 -:1089E0007C3DD43DF40EB8FFA0CAEE0F9444FB9139 -:1089F000D754A781B1E18C9DD9639B11B633A66C86 -:108A0000DB771FF5DB31DD94A044DFB33A4D342E24 -:108A1000BCE7C7E7A15F28E1414ADFFE186BE1FD33 -:108A2000FD42E1F0ED3685AD08DFB64DE620C0D160 -:108A3000B4EDCF663FC051F5EB1793BA61BCA6DD2C -:108A400046162966F47799E173632461285D8FE304 -:108A50009531BF5DA960AC11FFF5C2B5B361324B72 -:108A6000826BC7CA3F1B93F07BD327DD96E8F7756F -:108A7000BF7E7557085053F79BE793BC703DDDB53B -:108A8000358995507F0F98931953EDAAEE7DECF739 -:108A9000526ADF7E605CC65C709FDF624D1DCBF961 -:108AA000789DDF39C9103E06FD48B8617EA7F11FE9 -:108AB0000F63239D8EF4CFAF83FF47B011978D7066 -:108AC000DD96C6D80D7DF114C55788D3F3C58B1B31 -:108AD00043809F333BBFDC88F0D7FFFD2F1B7F0413 -:108AE000F863AF599D5B61DE4DBFFC8F24A4AFFCE2 -:108AF0006EAA53A1EFCEE5B29007DE3BF77E423877 -:108B000004B7CEBD7A32CF0BF33DB7E3AF2E2FBC07 -:108B1000BFF0D5719938FF852F5565327BFF709C6A -:108B20005BCC5838410B5798E8E8DD0D9D664273E1 -:108B3000AFB8C6D0637FE7FE3C84F3ECD1045F029C -:108B4000E209EE2D2A43FA009D86F2F6C380DFC6C5 -:108B5000ED3FFEB371683C3C87B20D6EA4EBA7E31A -:108B6000114EC622D9CC8DF8ED59E6B4F77DBF97EA -:108B70005E47809ED77F03BA6D5FCEC7ED00BA25F2 -:108B8000F5A5DB59FC07E8D38474B345E976910574 -:108B90007FEE298476671AD1351EBE22DF005FB5CD -:108BA0000AEFFF26A7FF874E949F9DB65E7A4D463B -:108BB0007ABD78318F01BD4F997AEE63E58CF5BCB3 -:108BC0009AE0DC0CF71F7CF58F2427E75E7AD78CC0 -:108BD00074843FBB02F33AC77AFFBA709E8D8A98BD -:108BE000E716472421298AF7C6F09409DE24BA7FC4 -:108BF0009CEE8739FF22FEB2913EE17D772A71E833 -:108C0000D1E12CA079B07006CDBB61CB9FCCC83729 -:108C1000924E481F6524D2EBF878BC2FE924E71D5B -:108C2000DB9F13F1304243B72D5C0EFBD2B5C7CCAE -:108C30000AE3D10BE0C5EF105E689FDB94A02AC960 -:108C4000FC7E0ECCE39C89CDE84038C2CA1FE3D13C -:108C500097B125349F1762E552CCEF6A727935B827 -:108C6000FF51BC3CE37452FF123F67BE8EAF9F0FB3 -:108C7000A19C03FCBBEDC183C83F8C59C227A09FB8 -:108C8000FB99C2920BA37893F09E5119E9DD33BF93 -:108C900034864330FF651DFB49CFC6CA37CCCBDFD6 -:108CA0001167BC3F8AF11A77EF1B8A7AE8CC1B7BED -:108CB00088FF1AB71F3787A09F43DB7E63EE2E899C -:108CC000F23BEAEFB0467F9FF9D5BEA1A46FB1FF9A -:108CD00038FAE684E8BF69AFBEFFA6ED7FD6F55F40 -:108CE00017EA303BED571FE7B4EA9F8EF33DDD6591 -:108CF00062A8FF4E77182784E38CFB96B05F124F73 -:108D0000CBDE35931D2B7F2F319C00785AF8EE84F3 -:108D10003F25A7E3D5EC05D4B2CE16CE579D8FF8EC -:108D2000B3912E9DEFDE63447BB20BF1784DB4DF3F -:108D30008A23CD550E90DB8A63817264AB587D30F7 -:108D4000E2A84107378C9389FA7929F4E3857E9864 -:108D5000EA7307A05F63D2F809088FD169705AE3FC -:108D6000DA55DE9FC91E604180CB0476DBABE1277C -:108D7000F7D4A4A12C19A7E731A05E5800EC85FA1E -:108D8000D96D66C52AC0C70C89BEADD0EF82C1FEC1 -:108D9000D283D05E30DBED0BC173CF1DFCBBB34E75 -:108DA0007BC8703DB6F3C22847B64B46E605D5777B -:108DB00046797B0E039560137C95DD61233B6353FD -:108DC000BDEBAAA16DAB557D8051F6993D989B9264 -:108DD00081DF99E93B4F8AA27E8EF34E6249286F6C -:108DE000B27FF99EEC97A991A1387F66612A03BBF7 -:108DF00092C338DC46319F42D6A5207FB74E49DA70 -:108E00008CED0D8E5AB2FF79AC679F1FE8F66CD2DD -:108E1000F8C3A8C7E05F03BE97DBACB7EF0316E962 -:108E2000DBF92135467EBD8600F05F619BFE7E7AD0 -:108E300055E5FC013EC6EE4BE99CA082FE4E9F5ECE -:108E4000B9231B703A69C57BBCFD7C65A907DAFFB5 -:108E5000B1BA61A20A7A24FDF795A579D0BE90FA3D -:108E60008389F4BC0E907423A8FED54327864AA2BA -:108E7000729B0160261B499E6F463C9C0D9C598647 -:108E80004F1BA67D658647F817403CE48EE478C802 -:108E9000B11FDBC1E0FD0186EE16E4CB9FBFFABF38 -:108EA00052F03D2F73D27C9D6CA9F3730B4E9E8DB7 -:108EB000BC3CEC4AFA4C659F4B3E3446E520D91544 -:108EC000BC3D05F86AD9CCE275E351D7D6FB88BF23 -:108ED000606427D943F9BE339DE85323E883705A71 -:108EE00080CF66F357582D6B177A68AC13C7514281 -:108EF000F5C6CBD77D7B78664ABE713007DE57EB6F -:108F0000BD045757867F36E2EBAF1941BACAFBEE74 -:108F10009933BC41C0EFCD2981B9380FCF9C4B7933 -:108F200008FFE41446FD55CDB5FBD1AE5ED80BEA83 -:108F30002F8E5CC9EBE6C5CCA70EEAFFF9D4D4E0CE -:108F400077B1FF82D7BD3B0F437FD7D7987D5618A7 -:108F5000E2FA45E53E358DF109A1DF21E8E6465A02 -:108F6000A2DC7D8F8551EECE27287E3FB4CF3FE433 -:108F700024BD9C5333F930DAB3F3B6FC8E08DEFF20 -:108F80009197E4113C0005E521776F72C49A44FC87 -:108F9000FC550C3F7FA5E75FFDB8E72F7B77775344 -:108FA0007F4ED11F3844F03C57D0E9BC91FBE5E738 -:108FB000177B090E701FF7A1BDFDA6E33D9922FCAA -:108FC00024419F47ACFE35480FC0FF3A2DFE7FD6A7 -:108FD0003F1D37E27B4047BAC6D2718EA5390FF5E7 -:108FE000C283818EF1A0B1D9C939DFAB40E69E9230 -:108FF00012DC82EFD7CFE83A6422689A8B506EFB7E -:10900000D259217DEEDAFB408B09DA4D48276F5F9C -:109010007A5EBFA894E8A6A16F07F67FFDDE3F1B2E -:10902000107E49D7750AB703B1DFBF92A28871EBF2 -:109030005B4C80CF0BBBCDE4FFC6BE7730C54BEF9A -:10904000C9F6504B854F0539CD34B060BC7E0FF664 -:10905000E9D7E24B88037F6F7F4EDE1FE0FF4D2D87 -:10906000FE7FD73FFEFF5DE0FFDFBF25FE8F209D27 -:10907000FBC3BFF4BBEB847EA863ABC8DFFCCC3F73 -:10908000D53510C61F6FB4933CCCDB6A243984F706 -:10909000277B5C517D32EF86E67D38DF79CF28C4AF -:1090A000B73541AEE7BF9C33F910EAF7D9ED7AFF47 -:1090B00069CE8C9019E19CBB5E7F7F5E38261E6472 -:1090C0001ABD0E7C7126CABF03B8DE7193BD340A87 -:1090D000F9A89A5B928CFED26B26EFEFC91F7FCB6B -:1090E000C836C7C17F5E6A3ED963D9CE6D06246992 -:1090F000EC3CABB11A505FCA7EC7CE2DC944BF66E7 -:1091000081C37BC5386CC022BD5DCF0F2532AFA6B1 -:10911000DFC2B6545D7B507B96EEFD6BD617E89EA2 -:109120000F0E5FAB7B7EDDB6325D7B48C78DBAF735 -:10913000AFDF3D46D72E8DDCA67B7FD8E1A9BAF6FE -:10914000F0AE7B74EF8F383A53F7FC86EE0775CF9D -:10915000479D5AA06BDFD4F343BD1F6360A427591A -:10916000A2427AF3C0E253152790E1CA95B188CFA5 -:10917000AA91FCDD03F3CD0667125E8B0C4EE08FE7 -:1091800037664F263FE0C07C97DF4BD70A3FC63F8C -:10919000CC38BA3C18C7CF1DE7FCA2E28466DC2AB3 -:1091A0008B49A7E7C639F5ED61A9227E18C0F9669B -:1091B00064AA5EBE8CCD9323666866CD1B9889E356 -:1091C000819C8D4AE57246D7ABCA59527305B641A8 -:1091D000CE2A53E3C81913F6B652F0135CFDE632FB -:1091E000642C07D9653FDEF4D2FD900AF1CA188BD2 -:1091F0002FE720CECBE04B47261C3B237080F72780 -:10920000EC332B367C1BFB2CE5DC6DF086C8AEA561 -:1092100032CA2F3D35BB289969F07B4FAA41E883BC -:10922000761E473AB70D53251E0BB4F7270C578B04 -:10923000A3F795B9933351EEDCFDE845B3BB70F06D -:1092400016D0C7664F3E5DE5FD65330C13C271E86D -:10925000DB90CAE30CE9770D8EFA5D0D88DFB3EE83 -:10926000F7D60E027C3556F790DFE536B4CF3F8453 -:10927000F3FAAD91E7CDC0B342BD305BF8D1B3276F -:109280003E3EFF10E8A7D9EF0C22FD24C7D9B03825 -:109290003258EB37E4F413576D13F06C5CEC1F5C41 -:1092A0003388E022FD20FDF4BC50C3788C7706B0F3 -:1092B000668A1BD71A586DBC7E968B7E3291E40865 -:1092C000AFD34E727276CEB12415E691E8082E47E0 -:1092D0007E9B797D5705F7C7FCBEA9C03F79917B7E -:1092E000D7E2FB796E958595BEE3675607DBF261A1 -:1092F0007E4B530D3E3BB57B147C3FE161C6D2E013 -:10930000FDA57F37123C4BDFB88161BC96606F666C -:10931000E8D7CA79ED4F7D9AF063ECB4911D64E80B -:109320009202FEBE2B687FD15DD3857EC7C5274DD7 -:1093300034DE4598A313FABFD8690CA3F37E283511 -:10934000316280B6B1CD41F63B0F7D50787F4EA79C -:1093500023ECCD8FE2455D3F9A45C0DE25E4F0F970 -:109360002F4DB587EDF934EFD5386F09A79C776E8F -:109370003F71682495DB59E62FD6D1D903315917AF -:109380008EAD82F30FFD189F34519C383BC54E7053 -:1093900086178706D798FACE6F997BEAED77033C5C -:1093A000AD478CCC08FD78BBDB091F73001F616FD4 -:1093B0005F7C9FF5E67F653012DC11E447E3FAF14C -:1093C000342F867E3D7CD7F073853D9D8F7C199C24 -:1093D0004074CE32B0ADF97DE7F1662ACFDF1E4E84 -:1093E00075D2D5EC2EE272E21E38780BF4F736EA2D -:1093F000290B8BE707FC3E95FBD3748DD54F600797 -:109400004308C785F50AD1F3A412369B006575772A -:1094100036933F20F593D16F24FF43EA290917E8DB -:10942000B10F5235F6D198FCF050ECB77F7F6DC785 -:109430003E33FA6B4E46FE9AD4A3FDF96BE8A721A2 -:10944000FF493FED54CC3C617E5F8AF97D196F7E08 -:109450007DF4EF3DCDD2CFF973EA15FCCC0C737CD3 -:10946000FD744D1AA74393D3CC283F85F132FA0FF0 -:10947000F30CE1CD988752C3D6291AFC64A5493F65 -:109480008FFB1BFDE9BDABC525052B4B48FF5EE8F7 -:10949000F226A7C235FD53A5395E3FC6452F0C43C2 -:1094A0003ACDB356DAD2004E679A1E5F4F2DEF6366 -:1094B000BFD2D238FEE8DA077F76C09F41E727EEB9 -:1094C0002AF212FE3C6957F013CFDEF15105DAA5FE -:1094D00073024F8DBD712FD7D35960AC30AFD5C05B -:1094E000FCCF9E28E6EDCB0AAD7A50BE6EA33D3090 -:1094F00008FB6FDA3DF159ADFDFE3A95E7D3983D93 -:1095000095F2ADB23F97D0FB1067DFFC9997F4FF5F -:109510005748DF68BCDD5D81F156EB4BD724A37F54 -:109520003676D7DD4EBC5E481F48783DBB2BC18FD9 -:10953000709E4D057D6CC7F688439887F872F1E1FF -:10954000542D5DCEFEEADD0A13F47376E7BB152ACF -:10955000E63344BEA6D71E5DFE434500BE0F8D61B7 -:10956000C5CD760D9F58B8BD78D2CAF31D192EF31C -:1095700032763DC4231929F4FD1A97E12778DF6874 -:10958000F943DE0994B398FCCE93266FAB1DF80C1B -:1095900062391FAE132C18ECF7CCC6FCCE1437E59D -:1095A000655A15AE4743B3791C9A5EC08AF3A13F52 -:1095B00093C168C4EF7A3CCCB7195E4938D01E41DC -:1095C000B597D8D5E147F0CB1353099FA3CE3815F3 -:1095D0008C27643E48ADE2FDF54C3387376BF24093 -:1095E000EE192AD9459BDAC1504F3F90914AF0CBF2 -:1095F0007C50D5D419814A84EB5103C533A078152A -:10960000D487D9621EF99E9DCBA56FA3BA902D1960 -:10961000267FD84AE0FF8180E724AFC18FF9D7A425 -:109620009CC85113F877D94B19FB44E347DACC4275 -:10963000DEDE3192BC39BEBEC53203FC235B22CFD5 -:10964000AB260596CDC7BC38DEFFD732A40BFF9EF4 -:10965000E863C434150B2503C88E91FA7E25FD3AC4 -:10966000175B7C0381A1772E76D2F5B9C56E82EBAC -:10967000F1C55EBAFE747131DDEF4F4EAF767D6C91 -:10968000318CABE1A7F4118015986FBA91913C3FF2 -:1096900036BC2279661C7F405E9F5E7CD835769012 -:1096A0004020D023ABDEB969453ED119850866F765 -:1096B000CE72FF68C61E35F9E73360ADD5695F8F9E -:1096C000C5BCD54AC54079AAC7D3DE5C1ECAC1ABAA -:1096D00097E86EDBFF3EC37CA7A7BC5D4179F7D45A -:1096E000B7131F947775B1A0B8EF87B6E708BFFF2F -:1096F000A895E379156313105EBBC202783D67E558 -:10970000FEE0E756AE1FBF10D72169C18D28C7FF05 -:10971000E53C5AF42880672DF9200FD73B6CFBFFFE -:109720004AF960E350B305E5C3B3F738AD83180DCC -:10973000DD660626F9F5273EA6FC9AD11CC8E7EDA2 -:109740009756603B2329B0095D3616FA78E2013757 -:10975000C80DF2C38D848D10CAF14AAB68878E1193 -:109760001E569A78FBF527FE44F35E690ACC43BC8B -:10977000607B29F4B732A5C36D80B6BDE5FDE587F2 -:109780006FC2B67CFFFDE521F8FEE534A96F021E2D -:10979000D41FBD6D27B48768DA2A6F330BBFCAF9AF -:1097A00035ECFFEBA16CE0D7C6BD4A0782E6D9BB1A -:1097B0005AC1797A76AF267CD31FC8074E83F2A4AC -:1097C000969019BF7F6EF161E752A0B39ADAE64234 -:1097D000BC5FE30EFAFDF1F21319D2FF85F7B579FC -:1097E000B6B0A9A75BE38F7B18971BB614F4431C94 -:1097F000FF626846E517E9D0CF934A708511F5CC32 -:109800008B2627EA11D6C5F5D019D1170B67917FA2 -:10981000536FE54DD392E08AC1A827EE557D183FDE -:10982000D7E5B757A27DAFDB93EF6B61517EA94BB4 -:10983000E9709521FFA4E8DBAD22EF9299D29C92CA -:109840005282EB11ABF370BDA091B5DFF74384F703 -:109850006D23433FFD8B7D37248F827603B4D16F18 -:1098600068E87CD78CFCF9443AD79F8D9DC03FD0E7 -:10987000CF2A902F3F38329B546722EAA7E7FCCDCE -:10988000D7A28BF7F5137F9B6805FA3E5FE077223E -:10989000BDDDE9A61516701A9F373B07B3526CDB86 -:1098A00089BFEA4A0D5C8E98FDB77E55AC7F42FBBE -:1098B000F813136FD3E6773DB82E03786EDA600F96 -:1098C0001992C9DEFC6FB4B78DEB0D21D45F064B46 -:1098D0009719E9EBC6B55DA28F93F0B650EAF3187D -:1098E0007DBD7062EA6DD85EF86881337485FC6571 -:1098F000ED251B0B6BFCA327D2B91CD7AA215A4715 -:10990000A9BD9444CFFF79E3595978D895C6B3D30C -:1099100073395E7D743CA2EBFEB2DFAE1D08745B52 -:10992000B8C36448D0F0DDC21D62BDDAEACFC47EA0 -:1099300032CC4CE01DFC7DC0AF9ADFDB0EA920E7E6 -:109940008FF5CAF98015634723DDA2CFD9489D1E44 -:10995000F063BCF958A2D403D7C47F3F31E6FD02BF -:10996000D9F6AD189BD3179E8CC468DB02EFABFF12 -:109970009DD0DB46F8561B62FA4B95E38FA4FE247C -:109980005F1D4FABFC6D68203C4F69AFC4FA8D9EE4 -:10999000D9CC8B7619F9D5A7D1FBC7D3B85CD75EE4 -:1099A0002AD4D13B8AF722DDFD938BDDBA75BFB98E -:1099B000D50B697DF238EA79EC878528AEAADD906F -:1099C000CDC21A7FEAFFC3F18FC231AA1F386EFEE3 -:1099D0001F86235F279F513806EAEEFFA3706CBEF7 -:1099E000ABE8B67C78658D12B214A05D78C440797E -:1099F0001363CA586F0BAE3F3CA2929F872E09D6C5 -:109A00007F14A8ECB05A86F2D3EEC7389F2DE1F947 -:109A100023B8DF662A233B447E70E1DE8407D04F03 -:109A20002BA8F5CFC32BCB29A1F50DB92EC8441E09 -:109A30004CAE670C72B24A159CB751190F909D2A13 -:109A40000854D7A13367749427A27D5C630887709C -:109A5000BCD0E37CBC0C43B8C382BA3769A013ED19 -:109A60005D4612D77F6C4509D9BFCD86826BE7036F -:109A70001C8F2A95896F219E530A28FF8BF717C0E8 -:109A8000FDCDC26E19537C4EB4539B85DD6A15FA29 -:109A90005DDEB7A5061E407FE254FAC2DB2C37A07C -:109AA0001EF2B7A581BD3999BE7085DB83F6C65B12 -:109AB0006001FB72F2C987C8DE6C6EF1663953A291 -:109AC000ED41FF0DD69AF4C4432BD05F596A5FF085 -:109AD00020FA3BF0FCB716D0B3CFA70ABD239E17E0 -:109AE000F4EA29D04BA0C78C2DBDED10EAA5825E0B -:109AF000BDF310E99D2D1B8DD47E07C643FF07E6FD -:109B00001132E27C07A9E4D75B019644685B071732 -:109B1000D03A11CC9B25A27F3D983F97F97CF3204A -:109B200003E5F3F17DC4A3D5C3DF374F613E5CD7B6 -:109B3000323BEC1487C8F501A358A74A14751A8A5A -:109B4000730AC5779655650B301EB30CD4AFC39A14 -:109B500063EA398CB1F51DF608F95F5FA48BBC7E12 -:109B60001A735F2E8CDE07BD5D8657D7DD4B2B1138 -:109B7000DE050EE634625E2518A175CE58BB66017F -:109B80003BEAD5C887C5CEFCF1EA090E65703FD621 -:109B90007E49A5F8E64905FC1BB4A30ECE67D23F6B -:109BA000323925DFEAEDAEF4974C297C2E0B278E57 -:109BB000C9C4F8DD68F75BD0CFD9E72CA3BC80918E -:109BC000F96EAFD4F83B4B231329FFA63AFDE48787 -:109BD000178A38D1E8F431AD9FB36C310496D73091 -:109BE000F66C45D1189487A7AD114B21D2778D81A2 -:109BF000E2BDFD650F8614CCBF2D6224A7CF56B8F9 -:109C0000C6601E7D931A48BE17E5E5088CE7E5742B -:109C1000E3EBB9AD0AE68B2F5A02C9A80F1E43BE6B -:109C2000D7E0E5D7021F7F4FE7FAE75113978B651F -:109C3000004F04E0502F5D47F9ADD5193CEF61AE00 -:109C40001E4BF91F33E003F37B09AC39E4A4F9F2AE -:109C50007C5D82DBA0AB0B542F0DA5EFFF9E6ED079 -:109C6000C5D56D304FAF467F595988F27588E3AD41 -:109C700071FC977732783C62017FC84BFE49CC3A41 -:109C8000775FFF88FC15499F5E3F4501FFE40AF1BD -:109C90005813C4CB5A7DDFA4F690FE6D827818EF7E -:109CA0009F735AC83F94750F76A1CF96B983EDA3E1 -:109CB00090CF139386621E40651D84945558F7809B -:109CC000FAD0ADF6F4F23FC87CAB356933BEB75479 -:109CD000D441D87C7AF94964ED113FCA67B1466E28 -:109CE00018E23B44FD2678F5F7190B328C33547794 -:109CF0006C9D44A8B71E8AEAF954F614AE5F4BBFB8 -:109D0000375BD4239DB57D447934F07B2BD3681D1C -:109D1000A087E21699EFF9B67E7221F68179844523 -:109D20007FA938817236657C3EDEB7A99C4FC0158D -:109D30005713CA30BC1A3F2F05E67FB7B07FE9C67C -:109D400076AA1B795DC4B3FFE59CE1A1380AF0490E -:109D5000F53689BE6E8A17859F66ECD58F1F2FF763 -:109D6000EBFDCE90D6CF5BB9E6E3E54B79BC42ED97 -:109D7000D79F8890FE7CD42ADBAF501BEC5C04E3B9 -:109D800025B62BC18B7C08DFFB51DED85D45E4672F -:109D90001B0B5816E2636C9285F4A67157C266F4E9 -:109DA00083212E7E394DB35E7CD671340FFDE138B0 -:109DB000FD8574FDE57DBBFE60FC4EACC791CFC751 -:109DC00026AD8F18F9775EFC8EE5747D1482FED780 -:109DD000BC94C056000A9F36E9E55D5E370B7946B4 -:109DE0007DA3AD873457D7F891A9A55C27B813593F -:109DF00044C34F52CED54B835944232785197C5DEC -:109E00005555FD9447522F95D0F3BFA34CD338CE70 -:109E1000AB8C93DACF38C3487FF43F4E85D02F4CBC -:109E2000AC5FA9545723F5427F721EBB4E16AB1789 -:109E3000E555EAC5CC0CDEFFBE0C7DFEF5C1F51D77 -:109E40008790854EDB830732A83EEA58129AF07A53 -:109E5000436428F2F1677DEF37E2E4DE4EE379FFF9 -:109E6000A26DF3DF4076EDCA085E443FE8B71962A1 -:109E70007DD20DF6D088F60EEC4509E5732FA6636A -:109E80003E37E85D378EA13CDD45F9DC6457A00420 -:109E9000FB5F36B582720E12EE958B799D9AD4B324 -:109EA000763548F8B2A8217E7506C186337621C37F -:109EB000344955109F5C8E8EAEB940726055FDC41A -:109EC0005756A7C18B7E8115E242D4BB2D4E035F4E -:109ED000BF715B28FFBF4C810811F4C68294822BAE -:109EE000AE8F9B2FB9C8DE02246EADDEFEE78F93E6 -:109EF0002EEC837E1CD5C9FD06B69FDB6144C2A74C -:109F00001A7D2CFD81D8EF62FB97F894F8B5205E9E -:109F10004BC81EC6F537AC2EFD7A66A6D4B71947D6 -:109F20008B2270B741E94E42BF06F4A8D5857A7AF4 -:109F3000484F92C14BFAD7C5FDA090E06B66D7F2AF -:109F4000B5CC53CB7949F817BC35DBA25D7F898549 -:109F500037D6CEDA4BF4750B56AFBE6E41EE0B30F2 -:109F6000AA01E21BD368BF05E5A4C559E6443F67D3 -:109F7000A9EAFDA39FEA2D4CE46F83FFAE1B5F5E51 -:109F80001F03F947384A5D065D5D8DBC3A701D259B -:109F9000CE77535C5C4F3DB6EF6ED2C3AA8FAF3322 -:109FA000C5D28FB176E21747117352FE54C09B742D -:109FB000957EFBE3A39FECB3929FAC8EB484B1AECD -:109FC00033763CA329E05750EF9632F2938DB97C5B -:109FD0007CE3204675E049E5A9AC5883C765EEA946 -:109FE000F47C41869321BD8D0E43201EBF483C0D5D -:109FF0007419747CE3967CE3F9A008E540C33781CB -:10A00000787C33D0C5F515C2A1A5EF327741663C07 -:10A01000FA44F522E7ABABF1C54C1BF7733ACD5CC4 -:10A020006F36208E205EAACF302FC3FCF7190B7F2E -:10A03000CEFCC5DC2FB3709E9B69CB0BA33FD4A98C -:10A04000FA6DE897CDEC5DB7F5D37E8F7AAB3FF92B -:10A0500006B48FEF72BFF964A5BD4D817E4E9AFCA8 -:10A06000C988EF93EF1A95165A07E7F573B20EE910 -:10A07000A4C9BBF25A783EEB67467F0B3DD6FB8303 -:10A0800067987FD83BE81FEF36D27A4BFEE30F1874 -:10A0900087C0FB35E028223FCDACB287D00E777E5B -:10A0A000D0FC11EAA3591B13BC4BB08E65FDB0AFB9 -:10A0B000B0FDF92A873781F26C058A07F35FABF3AD -:10A0C0009DB46EB2888978EECE4955A0437F89430E -:10A0D000CBFC35CCF973269F87568E85795E9BD154 -:10A0E00069B0034CCABAD04A0BD0EFD196801BE3BB -:10A0F000C70ED7F495183FBA5CFEAE5B205E3CE11C -:10A10000BA7B12B63B9F96FDDDB3D20F7AF91543A9 -:10A11000305F81E7B6CC872651FD6AA1EC7F193DFF -:10A120009FF9F36BBE3A0AFD97AE5B3F09736E155C -:10A13000D5E2FBD03304DFECD1B2BDD9563510BE29 -:10A14000B7315D1ECD148D47294FD7D9EB5F3D3711 -:10A1500009E3CF59639AAB54E87FC9BAED2B4B4062 -:10A160004446B4573AFDD0FEF1BA3726D980DF3ADB -:10A1700099BF0EE3DD95EB0E4CB2DC04FDA7E9FBC5 -:10A180004F378A7C6CE8F04ACCE3F5C2C7DE5FE962 -:10A190001F187D7F983B61552827CAFFFF22F81FB3 -:10A1A000F8FD572E5C07B4741FC2145DDEA21E3387 -:10A1B000AF7B15F52939DD4379DD8D681777F33AE3 -:10A1C00065D976F376E792F8F6FECF6E2E779D8905 -:10A1D000F19F7F24F439C0EDC7FA95E4A3CCBF3DCD -:10A1E0008E3C1D74D949FE0E82BF67498DCAD5EDDC -:10A1F00020DB23B1FEC7C2E194FDC47E7F4CE8277B -:10A2000016BA3D15F978B2E0F3429FC2EB7876DBDF -:10A21000C283D0DF6311F50E98CF3691CFD8666533 -:10A22000F74F81A15D892CB803FDCF346897D0F733 -:10A23000FE1DF6687F6F735166E30A035BB0BF7162 -:10A24000999ED2D6FC683F00F7524B990E6E75640A -:10A250002A3E0F65CD2FD1E0B384CF03F884F005FB -:10A26000C3BC700BC84B67D7B5052B600A2B5D5E6E -:10A270005DDC57D13595F6A5FCA79BFB3FCCCBBF4A -:10A28000CFA8E275213D7B6C94A76096AE22A49383 -:10A29000FCEE92C047D58F27AFC3F7EABB4C8CEAE0 -:10A2A000FF77545ED11FA8C7BC9EC67FAC5723144E -:10A2B000CFD5635E6F18F6F7B619ED18F6E315F90A -:10A2C0006BCCCB65B4C6A7BFB487F5975258685816 -:10A2D0005FBD19ED3F9D9E5F6D5ED1FEF47167DF3E -:10A2E000FECC621D40E05D157837C7877340A6E05D -:10A2F00053C0B741C35FB305BF81F6243FE0DCAE76 -:10A30000C19B57E46BC7E5FB6E403FBF700BEACBC8 -:10A31000AE448A5B2A54FF247CBFA22B95D6172417 -:10A320007F48BE9074ED4C6DA67C4DCF530AD9C1C9 -:10A3300058B88A245CEB158223B33A687C40039FAB -:10A340009407E8BF53F45F3E92E4E7192E0F2037DD -:10A35000F7A2FCE27A25CEC3D73D74EA90BEF0FFA7 -:10A3600014EDDF70A223C7FF4B5651CFC1F1D617B2 -:10A37000FFD957A1671E3DAFE87A83E659DF8FDC2E -:10A38000BEED4E2238338F4692BCF0DE1382FF3B87 -:10A390003B3E4D1A8572B1DBC8142F9F37EAAD0AD8 -:10A3A000A98FD99CB7C780FECBEC6D83BEF4221D6C -:10A3B0007AF567C46289BEFFAA7BCEE4A5F02C3D86 -:10A3C00081CB6BBA11AC4D59148E6999DCCF1A1937 -:10A3D0008CEF97BEE776D07389EFA71655B14F6122 -:10A3E0007E3F73F1F5CF91DD2105E922E53A564F25 -:10A3F0002DCCE4F2383FF3FF919EB25E454F59A554 -:10A400009EE2F70F427084EFB95CDD4315F09F6B5D -:10A410000C7E17C66127DEFD21EDE3982BEA5686F8 -:10A4200060DD0ADACDA301B22B5FE0435EBFF20824 -:10A43000C680B3DBF5F52B6C0BDF271ACB57513EEB -:10A440000A09FF5DC021ECC1ED09DDBFE245C67A16 -:10A4500079966D80B3D150A8796EE7764BD201E83A -:10A46000BD94A546E5F8935D999B50DF0E73F3BC50 -:10A47000627AA1BF14E72FE512ECAAE013C3FD53E3 -:10A48000ED5C6F4C8DC3BFCF08F99CBD9EF34DE7CB -:10A49000DFAA2621DE3BDF4B4D59A2D1135B851D80 -:10A4A00094FD4A3D24BF93CF9F15FCB12D3389DA2B -:10A4B0005B5D0E91E731C4DD37B755635F897FDAA5 -:10A4C00038FFC07C435AFE1EE65674F6B5D7AE0A76 -:10A4D0003C379801BF80BF6DA65016D6ED54741955 -:10A4E000A8BF9ADD0EAA07ACE9E078AC69DF67A8DF -:10A4F000D3E027B6BFFFC8E4FEC02603AF233A6807 -:10A50000007E43BCDB397CE77679487F1E16EF5D21 -:10A51000DD6E7C333DB3C9CCEB4881BE54CFD7F060 -:10A5200072F626BD9E6E11F80FB6E23EB6F475CCFB -:10A5300087B55680A78802704F770BBD63F69B7175 -:10A54000DF6ACF538CD6F30755FB4BBDD06E0AD8CC -:10A55000CB14E8AFA89DEBE18A27C18F41B9B3487E -:10A56000BBF0D676ED78C7321D221EE1FC5CB39EAF -:10A57000E36F10F83F2FE015FAF915F9F11C9E4F23 -:10A58000D6768CC2FC93FCFE0B41FFABC15781F029 -:10A590009547E1C3FE919F983DB004FB6DFCC3CE8F -:10A5A0006C6DBF5F65727D9B6E9C39C68A7A7E3505 -:10A5B000D81D92CEE07EDC9750B337C5B982913C6E -:10A5C0001B30EE91E3D6883C24C85DC514985A51DF -:10A5D000EF3892AEEFBFA89DBFEAE6FEDC3F8BBE30 -:10A5E0009DE620CDA76707C0EB8DE2A5B3E38125EB -:10A5F00056B41347990FED84847750757712D69D22 -:10A600003409FB01F33560FC92FE332F6B45BC75BA -:10A610008D3163FC14CBD7924EC58CCB8F8CD38AF3 -:10A62000718100DAB9EEA142FF308A773F79F9D51E -:10A630001756507CC5E9D254CDE958E90E4E7767DC -:10A6400044E510F47905EAAB9A277BF55107BFDFA3 -:10A6500095570DF8BCDE2DE55C4F97F4408715D774 -:10A6600035245F9FDD3324BC82D399C6EFEC708420 -:10A670001505F7A136B760DC2DF504C2A3ADC39470 -:10A68000F0F4D291011D8744EF0FAAE6FD3581BC9D -:10A69000231FD51B9B158F427A80F2AC99A807A087 -:10A6A0009DD9C1DF637BF9B908124FF5D3A1538857 -:10A6B0003BFDEE129A87C4576675C4500FB72658F3 -:10A6C000AAFC2734FEDA61B1DE8078994AF106D718 -:10A6D000D7F5C6400EC6AD2C3381F671821D22FD22 -:10A6E00072D0CA542BF4F7265CD12E8D33CEA77DC1 -:10A6F00034E30A159263D00032EF13417FFAF65B20 -:10A700006C24FFECEB8706E23C336C9C0FA11F8BA3 -:10A71000E8C7427650D883DFE7815FA744F5F2416E -:10A7200045A17E0EDE74DD66AA2D147C89FDA1FF95 -:10A730007450999243F6B23343141771F8FBB7671C -:10A74000DD79F85C1B2F627C178D374B57DD0A3C97 -:10A7500035624247C4E044E9289FFC7D807F1CC4E9 -:10A760009B5698FF0382AF0FE6878C4908D7209845 -:10A7700037DC3A94182C69B647C77189FC8D4BD4E5 -:10A78000EFA2BF80578387EBFF9F78B8BDF8505C7E -:10A790005D49F1F33D17C5F38FED5C4FAFA88CBF5A -:10A7A0006FFB11615764DC79BB58EF80B8F3113748 -:10A7B0008F3B45FD295F1F01FF9EF05BF5E36A5A61 -:10A7C000F7BBD8352D999F87C0F5C12C51FF79FF74 -:10A7D00023D37E8A7C7602EBCC010F9F0A7E39E17F -:10A7E000F427619D544362FC3AE267053C0D020F79 -:10A7F0002717F3F30B66E1BA1CF0DF1A37F7F3E61D -:10A80000B60F1B8F749FBB4AA17539B9FE2FE95C47 -:10A81000BBC1A8CBAFCFC275B9B47F249E2AED27A8 -:10A820009E2AD7C55372DCD8B8EA93C56EDD3AC00C -:10A83000CCF642717E047F7F16F311DCB3DAB27579 -:10A84000EB88AC2DE31BEDFBC7382A14173EB3EEA3 -:10A85000FE278B2D2CA485E3D440AA9F78C41D7CB1 -:10A86000C5AD83C3C642BA7CE86827ED27B2F23C87 -:10A870002CF8E33C8E81EB263BF9EB13D09FEDCD1A -:10A8800087811E7126A35EAADCEF1E1E8D1FA49C6D -:10A89000D58F8E1F47AC117ED01A178F93938FCA16 -:10A8A000B83AD18BFA51FAE5B1DFBDD7CBBF7ABF49 -:10A8B000F26A7908E0E390364E8AEDF794FB1F8D3B -:10A8C000BF0BFBE197A2FF91F8BB627490F27CACE6 -:10A8D0005DA19A961163F5F1D0D768D787E3D5A625 -:10A8E0008B876AAAF5EF310FB7FFCC63D3F9F1FD7F -:10A8F000E153EBC72B85A807797F8D822FF24FBFDD -:10A9000047F5A4A33DDC2FF265F9133C705D25EA01 -:10A91000C95759F97EFE4DFFBDDF3D0BFDA3774CB6 -:10A92000B4FECF7673BEA97C66612B9E0F60EF509C -:10A930009CDAFDABDF59A4F86B40AED3847EACF754 -:10A94000F1F9D4FB22E68176AC2FE670E474EC5387 -:10A95000540DDFE5D4F2F7723D265D5E3C5FB4072F -:10A96000789C328ED937311DDFF7ABE81764752834 -:10A97000643FB39A19F9D559E50AF5FF9DF24DCA1E -:10A98000AC92E87CDB0C534A9CF05D9BCBE643FB2E -:10A99000F3C3ACE0351E84EF582482E672C4B12EB6 -:10A9A00015E3AD5559FE62C4839CA7D7E8CC423F5E -:10A9B000DE768CC3D7DE9B67E2F687B195C22FDDCA -:10A9C000CCFD33233BCCB87F4E76DEB5A498ECA00B -:10A9D0009C8F2B55D811170BEEB4D3FB6DE4B758F1 -:10A9E000B81FE05A5244FEBCA46B34EE1C5C867166 -:10A9F00067E1AA883A13BE7B798321EE7915E305D6 -:10AA0000DE611E95DA795C4D6FC9F74CFDE41D25BA -:10AA1000DFDB26C48FE7C112D2F3CA67D2EF21F978 -:10AA20005C6A6698AF96F85F9515B813E1C9EAD8E5 -:10AA3000A4206E3E11750A9F24F27CFC272B5E50E9 -:10AA4000D0BF7C681E731A59FF70D72F32FA6BB4CF -:10AA5000F2BCD44C7491F14A141E9E8769F070FBCD -:10AA6000B42F2B5083E337EE5E4D71F5BC2DC7CD6F -:10AA7000575C87F88678536AB9BF5E3FC342F54C8E -:10AA800095CFA844F7BAA5665A37ACDFBE83F6A7C0 -:10AA9000B187990FE5BFBE63875203E3D66DDFA18F -:10AAA000CCD6E031BB3E4CF5DBD738E47A4484FCAD -:10AAB000E958FEC63C02FA2F87AC5CFECF54DA435D -:10AAC000B83E71C614ACC7F7CE786C3E5CC79478BC -:10AAD0007F73C7AD745E8063674204AF6D86CD6ED1 -:10AAE0000BBCD776ADD987FCB42A2BB81CF192AA3F -:10AAF000063AF1FB9474870FD737BC09AC8CECF79E -:10AB000037C4C38818BE18F130979757847E813FA9 -:10AB1000AAA77AD6C3FD725C5E427D75C8C4E7B150 -:10AB20009371780D1EFF7A944B763895C6CDAA8F17 -:10AB300028587F113B6E94AFFC1B3D19DF06CE0EEB -:10AB400033EAF93AA16F2A9FD9A27CAA81FB458FEB -:10AB500091E0CBDABE49C1FC193C277D03EF33AC51 -:10AB600077CADACEE3D53A783E5BA35FE43CE2E80D -:10AB7000994E84CF7EACEB00D73311BE5E20E08DC2 -:10AB8000A567C4E3A5F1C783BB40F7CDA1628C974D -:10AB90000F1524527F52EE63E534E2E17E65D686DE -:10ABA0002D8AC14EEB2AE45F4AF8E47BBEAC310744 -:10ABB0003C84872EC243C30695E633CE1C18385F0B -:10ABC000230FEF89FEDE98FE119DABF3E4BFBD4B72 -:10ABD000FCD8007136C519EDEF9AA7A19D09FDC2F9 -:10ABE00088EB6093B88BC2D68A73A72675723DDC5A -:10ABF000D0B9439D658FF269FEE937E8BCAA868E1D -:10AC00000486F115F0DF518427964FBF293D411F7F -:10AC1000F1F829641679BE603EC63F524F1B84FC92 -:10AC2000333BBF7F41B4A3FC133CEDD1E9592BC9A1 -:10AC300045FEE9B237B0DEB3C1A7D0791D129EF44C -:10AC4000AAF87EBBD48F526F633E31A0D1EF1705B7 -:10AC50005DA11DE1712A2B403B2DE18CA5D3802CF9 -:10AC6000AEC7E3F0D3DF11DE58BB25ED79FEC69DFC -:10AC70002AEEBF917C3209E9ABE113479699E07067 -:10AC800064A9D4FFDA4ABEEEB8D6C4EDD5DA160B05 -:10AC9000D561BE7937AF0B73DC638EE0F5A06166DA -:10ACA0003D3E3F98C5E168332CA1FD68207F49599E -:10ACB00019C827498CEB41AEF79EFC0DD75BF521F7 -:10ACC0003BC5B9F5C13B6B68DD3FDDEAC37A591678 -:10ACD0003C609EE688E235968FBC3BF799711E93E7 -:10ACE0003AB8BC81DE243E8AE22FAC9313290F864A -:10ACF0005E3F2198CFFD201E479588FD81B5161F28 -:10AD0000ED2FAC15F9D612B14FB0E2A89FECC14CB3 -:10AD100041878DF6C0755998A75915936FFD8671B7 -:10AD200040DDA2DF51DCF5A0FB2DBA4A79847855CD -:10AD300027B73766713F3B5F5C2BB3389FD495775D -:10AD400090BCD59D682639B54FE0FACA7E2CC62F37 -:10AD5000648F09BE5B45E38EB3758CC7F5E2713F26 -:10AD6000579CADAC7F38E7E23E2B8CE736EC4F7A50 -:10AD700000E5F96B882634FB70A666713939B30D8E -:10AD8000104EF6A8D97C253FFB6AFDB1C81185CECF -:10AD9000F910B83CB3BDEA86CF707D675BB20FF7A0 -:10ADA000D37FB9FD8E1F7C06709FD9728B0FED7F0C -:10ADB0007A6B80F8A527C3EADBCCF3AF13303FD51D -:10ADC000D2B13F09F7ED7CF1C2F565A88FE7657157 -:10ADD0003D75FA37C645889725CFFFFA667C5E1722 -:10ADE00056D2D02F3DB3EDE77FCF827E6AB734E1F4 -:10ADF0000962ACF585D7C9DF378437F1FBDB92C92F -:10AE00007FFDE2D9D53723BE5B3B5AE9F9E96737C5 -:10AE100051FB8DE77FFDDADFE0BDFA4012ED673EC2 -:10AE2000FD9B7D4497FAA04A75E7BD7C1CAB077774 -:10AE3000ECE37A10ED37F2FD0CAE9F241F4BFEFDC4 -:10AE4000E2F9FB6FD0DA0379BF4DE469DA12B97D1C -:10AE5000F852C869DD187B1B5EBF7CD14AE76E36AD -:10AE60009ABB8B307EAF2FE17CF17D818FFA8EF91A -:10AE7000A6463B7D4FFDFC27303D5E87007F627D0F -:10AE800017BCB5E532D529FD8AEB99443612F33863 -:10AE9000D3AB8FF37D9B25CDA63A82F305FE1C66CE -:10AEA000AD7D5EB1307EDCB83ACBAECBD366754EAD -:10AEB000C9F192DC27F80669FCDAACDA60AB03EE84 -:10AEC000DFB630E8C37DEF2F9F7A6F3CEE4F78BE40 -:10AED000581946F4372ADC7E85EC344E03AE0F4118 -:10AEE0005CF1AC9013084BD36F84F98C53593A6ED4 -:10AEF000DD1DC7D81113E985ADF41CFC17F2CBBCDE -:10AF0000AF4FDF8AFECC5A53D0331CFB6913766FE8 -:10AF10000B871FBE77DACBA83FE78DDC0F5F80DFA2 -:10AF20009D6F999C8E7E3BF4DB65D2C459C09179AC -:10AF300068F7B0BF72C4D384D00CB23F5E33CD4F3C -:10AF40009EE709F31F7AEF90A87CC6E691503F6117 -:10AF5000DE775F56E55ED433F2EAEA270FC3B2F933 -:10AF6000737FB69FAEDFF47CD037A69FE3F6FB95E8 -:10AF7000E3C4B78DC8B7387EF084CE7ECF927CBB59 -:10AF8000E738F1EDACDDDC7E37EE2E3523BF7EB940 -:10AF9000D8CF3E0507B651F0DF5AA57B0EEDFFDA9C -:10AFA00063A57D7DE7247FAE3AFE39D69B16ECF68D -:10AFB000509EE0DC1ECEA7070D068AEF0F6EBE6E18 -:10AFC00053ABD2D76E821F4D72D2D8CC841FBDF046 -:10AFD0003DF4BB1A6A799D79630C1FE56FFC641917 -:10AFE000F24B0A78BD583F037ECA78DA1759CF86EC -:10AFF000A39C668DF5EFC9A6F53F1E7767D5823E07 -:10B0000081F66DE9F37C789455CA58F07791FFD2B8 -:10B010006FF2613E6C6D6EC732F48B43E3189D9BFB -:10B02000BAD6D43E06E3DBB5E3BC4EC024E06D0BDC -:10B03000F9CDACD82CEC570DF9DB8DEE7FF551BE78 -:10B040003A56FEF7B490DFD6E84DF4E139B6937680 -:10B050002B0BB89F6267087F23E017DB93C2A3C264 -:10B0600008CF59813F89C773A62E3A4FF7DC4B09A9 -:10B07000743EE1A4B19C5F53C67690FE7873CFAD69 -:10B08000649F255F3A7625909D4E559D0AE62F18C0 -:10B09000BB23414BD77651879B22EC48E12A4EDFF8 -:10B0A000C46CEE6724661BC4D52CF85C9EB712A254 -:10B0B0007CC259417FFCF36ACE6B6AA889903CD56B -:10B0C0006FE7FDA527F84B1FD2F0AFF497E47A2B7A -:10B0D000AEBF4E89C3DF3E0147FEC60544F759B5F2 -:10B0E000E23C8755DC8F60C0178837A023F1C16D23 -:10B0F000E973896EB35629F7101D431594D7947ED2 -:10B10000576CFFE5D95C2F6EB306CAB18EAF27C36B -:10B11000E1C3FA806D297E03AD0F94A6507E2323F0 -:10B120008DFB8119C20F8CCA7DA0DC00E39C7239B3 -:10B1300038BDC3BF57316FEDCFF6C6F5EBFAC6EF9A -:10B14000BCBFC9EDA1A118CFC8F563898F704BE2D0 -:10B150000CAD3EBD51E0233C98CD40BD0171829DB8 -:10B16000F2EB4E1807F3049B473DCBF304FC5CE77E -:10B17000C26C9EA71B97162847BF2CA330B090DB4C -:10B180004F3ECF587CEC13F6FD8DE9F795627CDAE3 -:10B1900078A7DD8772F7E42BCA4CE2EB90050FFB32 -:10B1A00001BEE772080E13D5ADB1A04AF4686C0E6B -:10B1B00084E3F3FD1492B346F0F3D0BF9F847C9EEA -:10B1C0004E7C1FE67CCFED9FCC23A09ED4AEAB4837 -:10B1D0007D20F50CDA37E46729178D377717217D45 -:10B1E000BFA95E3967E2727E0EF0807224E5C6F177 -:10B1F000329797152DDE4A7CBE02E45E4BEFD8B83D -:10B200000BE1C4F855EAF71F66051AB3318E3044D6 -:10B2100096D1DE52A18F1B5F5E5E146F7F90D4C704 -:10B2200016711EA6256C0B6BD741B0B6C25146D71E -:10B2300010DA23DBA2F87996966C695FFBD4A5B58A -:10B24000640FEF5B97E642DB85F2B3D946FBD4642B -:10B25000DE29B6DF87B2155D7E47C625B89E81EF31 -:10B260003F23E4A75DF0E573D932CF1BD6F1BFD7FA -:10B27000103C8E7505FDD931F9DD3F2B0F26C791A6 -:10B28000F63496FE723D06E733A5A4FFF7DAF731F0 -:10B29000B1CEA7E7C717859CD46533BAB69B2217F2 -:10B2A00049AEE63B18D5F3AC67FE345CE77BED1A9C -:10B2B0002E0FFE9E22EC7F606ED09A9311CDF7E2A6 -:10B2C0007D8C3FEB54164A009AD46D3385B5FB64F0 -:10B2D0007E86B58600C779872564043EAFC80DEE2B -:10B2E00045FE0A8DE1FBE1423FB4D2FA1438D2C3E5 -:10B2F00051BF34B1EE24C473A3B1AB08F393D5AE00 -:10B30000E03EA4FF2786AE3C5ED7C1D7CF8E897CB6 -:10B31000EE3191CFED344772BF9F1E3D9FEE02E3A9 -:10B32000755517BA0CA918F77DB8FB0F2FBE025F31 -:10B33000DFFBCAD97B7F84D85A61BBEF6770ADB69B -:10B340001803AA26EF76CC115FCF7E20F8A8B7EEBF -:10B35000A925216E3E7F6B0E7FAF2966BD7A6B0EED -:10B36000D7A7D17D4F7CBDFAC37ECEB5BA2147D4D5 -:10B370004B8A7AACD8E737E7707EDB666245EB1123 -:10B380009E4D0E5AE7672A3F8FACF6897C1FAECFE1 -:10B390007716F0F3EF7BD62864078E99B8FE81BF4D -:10B3A0003B2D15513B8A6E0AFA89B5CE50C400FA7E -:10B3B000A376A12382E760C27D7534CA5AC8497555 -:10B3C000C133857D9CD5FCE65F319F51AB32CB68A4 -:10B3D000F8EEA4BD2609CDC39CEF3E8447CCB0CC8B -:10B3E000EA76513F2ACE57F34F365EB65DC9AFD3EA -:10B3F000EF1BF9454E80E5C0FCAB9339BEAB1FE2B5 -:10B40000E7ECCAF77F23E43696DFB621AF02BC1F14 -:10B4100029DCBEC48EE3CC1DF302F253B53B60A31E -:10B42000FE1F3A4B7AADFA152B9D7F5487EB5CA03B -:10B43000F2CE9776152DCA47BEEEC9FB23E6C9F6B4 -:10B4400026505D721DAE7769D6A7FB5BEFEA7F9D44 -:10B45000CB6B46FE6DBCA410FD67EE7DF328EAEBD6 -:10B4600046B59BF862A6C54E786FBCA4D273D6666B -:10B470003AA3DDDFB6D0EDCF47B8433F1E9D42EB88 -:10B480006599709FF0574CE7632C10F5E0CEDC60B7 -:10B4900031BEB7CE96743FC67D172CFC3CA4263334 -:10B4A000AFFB6662DFB0A43FCB71E8E9BBF7ADBF8D -:10B4B000225C3596209D2B397B06C4C946A447647F -:10B4C000B8B3444BD7D1DFEA5C5B7B0ED7371F9A0A -:10B4D00079DD4F5FBEE67A69AB7C2F8BCBC787796E -:10B4E000AC76275EAF852B7CF761816897F1766C2F -:10B4F0003F33857C7C3894DBA5D0025BDCF33CEEEB -:10B5000014E3FD22C73F19F125EF3F25E4CF99EB66 -:10B51000BF1DEF83DEBB03F51EF0632405FAAB7E8F -:10B520009DFFBE005BDA4375A7BDF32A12F0BAE2B5 -:10B53000C3F5FD68BFF7607FF09E9FFCF3D7ACB406 -:10B540006F8D4D063D8C7A77412E43BD0BE3CEC403 -:10B55000F1A1DF480ABD9740F3606DA08F41E0CEB6 -:10B560000FF7125D5654029F968BF3F2BD51BE92B7 -:10B57000FC14CB474D424FC5598F6F42B862D7E399 -:10B580000112A237F1DBB7D8FF352A8DEB7F90E7A8 -:10B590001FE4905D8D0CD1D6F3493C4B3DF861A280 -:10B5A0009E2F4C02CE16F15E2F9EC5F953E985DC25 -:10B5B000BEC93860B5A0BB557C27AFD25EC5E6F3E7 -:10B5C000ADA25F6B4E92A4CB6308A7B4737DE8BDB8 -:10B5D00081D31BDE7B9CF44742CF7D6960A7EE02DE -:10B5E000FF07CF9F84EFECF85D9F7CC4586E5F9B94 -:10B5F000163818DAFF0D39A24EBBBC87AFB715C39A -:10B600007508CA1FE81DE5EAF4C3D8DF037AEED750 -:10B6100058EF01E329583F944A6AC08BFD01BE9F51 -:10B62000D7E23B76BC63F808FCBD1D39625F5C293C -:10B630002B457ADDF7EE5F1CF77AF17C72BE1FF7BF -:10B64000337BF025ECE7CC0FDE22FFFE983952D495 -:10B650006E8FF3DC1CD9B84E893EBFFF17C610FEB3 -:10B660001E4567D79935D3812F6776197D38E4CC8D -:10B67000872FBE3302FDE62E13AD1B81DFB00ACF4C -:10B68000E73C26EA0059B33EFE7F57D047EE0B96C3 -:10B69000FA49DAFF79CCC7F552223F0FFD93F973CF -:10B6A000695F700D0B1CC2F3D0BF583091FCE2B93A -:10B6B0002C48E771CF6AD39F871B7B8E6EECF9B95C -:10B6C0009880477CC59EA3FBE5F7AE9C2F97F52B92 -:10B6D000B1CFFF26F8F1CB7EEACB4F0BFE95F500FC -:10B6E0004DB21EE0D52BD70334C5D40344FD0C590D -:10B6F0000FF035AF0778555F0FF0E598F8705C10E4 -:10B700007034E1393A71FB4DA2FB5F165C799E4DB6 -:10B71000782E4EDC7DDF76BADF5F3D822D57E0A9C3 -:10B720009F7A8C845CD9BF47678F6DB9DE183F2B39 -:10B73000879E37C5D435449FF37A06991700BA52CD -:10B74000FD9CF4EF62F7C3CB7CBC949F4F1566F170 -:10B75000501E6DB5881B7C43D11FFE14FD2C94DF59 -:10B760005BBDAF7503A8B37E7443915A1095AFD8F3 -:10B77000F9005F9ED6EE3B1F902BCE6FF0311FED90 -:10B780004B147271DF0FC625633EFFE387AB74FB7A -:10B79000CD7AF7A39BA57F67D7D9731663EF67EDC3 -:10B7A0007E8BFCB71A4B80F6BD7DF6EA0FC8CECF74 -:10B7B000610117CAC9F957AFC90BFE5FD87909CF24 -:10B7C0001DA1074CDC6F4F27FF64AA80E78EBDDC0C -:10B7D0007F3458FC261AC7CFBC4E1785E61C5E5036 -:10B7E000B678EEDD4DBDF097D07919A305FC0A7E41 -:10B7F0000FF8BD495CD9CCA01BE196FBF881EBDCCE -:10B80000786DBDC1E7C5EB2D4A40659AFD9DE359B2 -:10B81000730EBE6FB0741BC5F962742E7C42145F48 -:10B82000D47688F6D23B2FDC371BEFDBF9F9C26602 -:10B8300001473057EC5BB6300BCE3BC11EF982D6C8 -:10B84000FBC4353486FBE3A1025E479C88E717C042 -:10B85000B876FBD9104ED6C99CB42FDFEABC10C114 -:10B86000B844F3BB1035B9C335BF0BC1223C5FD51B -:10B87000DFF398DF8D4815F0B50A3DE9C1F3050BFC -:10B88000E91C05D2938F3BE6D079E219F685B40E18 -:10B89000FD54D2045AA77421E2B13E7E82E61C0414 -:10B8A000789E11D09F7F903943DFF604F56D0B3BF6 -:10B8B00046F55C4A24E0BE9C163DE7D124F4CD9DBC -:10B8C000891CAE3B1379FCD69AABDF971990BFE782 -:10B8D00092CACF4938E7B258B0AE02FC93D65CEEBC -:10B8E0009F7C0494863891FFDE4BE92DFE416BCAA4 -:10B8F000F1774C8CBE2540A7650E6F8B8A7EDFDD0D -:10B90000E277BFD40EAA57D8745F8A0FEB6B9659B3 -:10B910009D9598070DE5F2FC4F93D8A70114A9DB7C -:10B920000EDF6D9A9A4DEFA557F550FEB467392397 -:10B93000BFAA0F9F7E0DFC0FF87E16DB787E438D2D -:10B94000AF0BF7ED7AFC46AA3396CFB7E07380537E -:10B95000117C81F76FA988FE2E53E1DED2FD78FEBF -:10B96000240B2A3E9E8EF412BF4F13FE7CD3DECAF8 -:10B97000DB87035C855DC3888D07EE15EB2FE90936 -:10B98000627D989FBF1BFBFE407C1FDAB6C3DE7F43 -:10B99000ADC7470688BBF1BB31369AF711917F627C -:10B9A000423F8C8891BF515179A0E7A5A2DD24EADE -:10B9B00001F1CC087F054F6FD07BE95C3E7C4CFEEB -:10B9C00071B9BD9145FFB09FAA68BFA4A7C6461F25 -:10B9D00047E510A65866F1B5D6C37B07A7F075F406 -:10B9E000116A641FCAFB28712D155736B39DF0BB31 -:10B9F000A225F286291F532D0123B62B9CCB5BB1C8 -:10BA00009F9B94085DF366AC6E4535EDCD2B14FC21 -:10BA1000161C87F2B96C1CDFDFDC3AD2E773C2A3D5 -:10BA2000E933787E76DA0C0BD54D4F53F9794C4CCF -:10BA30000DE6DF0572765735CF0B63BB5A937791CE -:10BA4000EB204720BED911C73FF0E671BB25BF6F81 -:10BA500012753EF2790E1EF40C001AF2C67F9C4B52 -:10BA6000F684AFF77E962BFCB462561CF3FB315F75 -:10BA7000901EA8FC5D7F7A42FF5CE88969FE274C36 -:10BA8000E4DF0B7D21F57240D42F75897354DE1FDE -:10BA9000C3F1FE5EE53CD21777B266D2E777B1908C -:10BAA00009F1DBABFF2768FC2318675A40EF2F4DE5 -:10BAB0009F11EB57717E95E3DE1DD43F9F2AFDDE7B -:10BAC000097ABFB7FAFB5FA7905DCC7CAEE1F2804C -:10BAD000689D52534C9D52A3A8536ADA3DFF60867D -:10BAE000A64EA9692FAF536ADC7DB53AA51E5A57F9 -:10BAF0003A620AEFC3F59623F3402400CEFDA2AECE -:10BB0000E500D6B59445F9D23195E75D817D69FDB3 -:10BB100024C769F3213FB519CA284FDB96E4F069C1 -:10BB2000F3A22B5A80EF34F959599774A49FB8B8EF -:10BB3000388FC7A96B159E270FDD6DA13830A33054 -:10BB4000A05B97C830B2A3986FFC58F8416B451EB4 -:10BB500004D7F586C135AC70FFA6F77BDCEF84F91E -:10BB6000C9187D9491E6A375818CE42194DF9FB17F -:10BB7000B7740BE91BBBD587F5FCB2FF19C14D2A81 -:10BB8000D60B35EDDDA4D6D8A37C372A4FF0AB8D8C -:10BB9000D9905F7BF37D3B1328DFF7993D704B1EF7 -:10BBA000CCA7DE1C19CAF4FC4CF7FBB36B7305BFC2 -:10BBB00098C604EE9E0DF09C7FC7CCF35E0F3392C7 -:10BBC000D7DFEC49A17CA53A95917D595AC9F8EF88 -:10BBD000BB6C52C89F3B99C2CF0D5A3A85911D3C10 -:10BBE000973A9EE8378F850FE1B940B51B4CBAF301 -:10BBF0007F1EDCA26FD7B30EB237F5DBFBF033E963 -:10BC00002DA91F1B98D7887AA8B153FF3D1BA8D731 -:10BC10008FA5C21E0C9B36B6D504DF0D3370BDC593 -:10BC20001EF6654FA5B8BB9ADB51F61C9D3775DE35 -:10BC300071CAC8E59CEBE3E151ADA9B34BC3857F65 -:10BC400075B3CA7F1741FA4BC3C5EF241C30EC35DE -:10BC5000D26FF20878CAC577D24F93FA5AD2A5723A -:10BC600024FEC603443779C2DF2960054857E89FA0 -:10BC7000E441C140891F714CBFB7304A8C0774E75B -:10BC8000E7CD192C61E4A3654A33E9690B13FA5A2D -:10BC900009925EFEB750C8887C70036BBE037FBFFD -:10BCA00073B4A5CB467EA93DF868DEF0289FB4B2F8 -:10BCB00048DE0E45C72FF4FC4CCAEFE2F28BB42BE2 -:10BCC00091F7B9BF3189811F08E3FA3FE07ED001C7 -:10BCD00085C78BE00F1EC078F1778689C40F13618A -:10BCE0001AF8DE38A79ECEB7BAF5ED89DE3E7C6045 -:10BCF000D4FEFE04489C8AF04C2AD6BFE797FA8D02 -:10BD0000E9F55B3EFB9AD7C12F3FF45DCC1BD816FB -:10BD1000B162F463C073F4C5FB7DD16DC25EC459DA -:10BD200037D99697D177DDE4BCC8FFDEC8BAE76C97 -:10BD300057FAF2CDB9838B8C6E0D7F497E7E59D434 -:10BD40005928AF8BF5D9729E2F8CDA79CE3715A290 -:10BD50007523F21DBCFF96E417F13B2137EDB64683 -:10BD6000F077704A453F3722FF9445ED7AC460F77B -:10BD70009A0B904F7C6D46635F7FDE95EA257E19B6 -:10BD800066F013BF0C67BE34A4D3484B47AB8AF0B0 -:10BD9000EF19911DB4EBF8E31DE20F05F883F2599A -:10BDA0007DECA3FE790CFF483A1E167EF4ADCC4B19 -:10BDB00071C404E14747F239FF54D9EF54F1FB371E -:10BDC0000B78BE612C2E28D23E53BD5DACB2E8F993 -:10BDD0002096BF60448376DC587EEB8F6F0620DFB1 -:10BDE00048BB987675BE39DF3FDF9CBF12DFC4F2D7 -:10BDF0008BD42B3BACCE2A3BE6B76A15D2C7C3DE49 -:10BE000019D88AED6B1AF2A90E66478A6F3F3D6F0B -:10BE1000E6CFCBBBFC46AC93295C289EE707AAB0D3 -:10BE2000DDB488AF530C3FC2EB68063ECC9F972E23 -:10BE300069DE8FFBFA9A42FCFB97BF5846FB9BC218 -:10BE4000CBC4F795ED55D86E6AE3DF9FC4F5A6EB3A -:10BE5000B1FE2DDC8AF707AFCAF7F1B094FBB5B796 -:10BE6000083EDDA1ECDC4FDFB5F3EFE61EB224D2D5 -:10BE7000EF060ABFF56631CF5B36F079A67F7A1BF5 -:10BE8000FD8EE8EC9E10F94F9F1BEAE9776AFA8B6A -:10BE90003F2B95F61CBCDE8AFA040FDFB2005F1759 -:10BEA000F0F5C8CD30C47503B83F28D7F1B0AE4027 -:10BEB0005B4770DD001E17C9F75CA97C1F1A7BDA8F -:10BEC00041F962B9CE1859C71494339CA3F003E228 -:10BED000AE3BDE5AD84CEB8DB70E90EB8DDD2A9E33 -:10BEE000A35E7AF92FE3E3E559CA06F03CD0295165 -:10BEF0002721EFD786F3E977C1762093D03EFAF079 -:10BF0000EFA92DCE056762DFDA8E7CDEF60FD8F062 -:10BF1000D3B61CC0AFA159C573D4589E42FBF6FEE0 -:10BF2000A58B459293FAC27FABCA2266BEEF8EE024 -:10BF30009FD36ADECCF74F72BD344DAA9DD18348A2 -:10BF40004EEF1474FACE00E1770C63C350DF4C134C -:10BF500074BBCB027E2BE9B576538CFC4F1980FE67 -:10BF6000C653FDFACFFAE731FAA1568C3B47F8CD1C -:10BF7000F3F0F7478D78BE3BF79F4F3DC5FDE607D1 -:10BF80005907E523CF3FCDFDC506981EF24B9FDF35 -:10BF9000E7DAA66F3774C4FE2E6C88FAEFF3BBABFA -:10BFA000253CAF7BFEA9860ACCEFD5AE7F87F2C7D2 -:10BFB000B5525F84F5FA021C0CAE2FD65D4B791D8D -:10BFC0008385FF2EE630D017586F320CEB48A1FF67 -:10BFD000A162DFFE72FC84EFD77F6800E98D09540F -:10BFE000674AFD19697DF71DBF374A1F693762F53A -:10BFF00045A9CCD70C4CA57C96D41FA5C24F611384 -:10C0000062E3C727490E8789D64F06E8E320E97720 -:10C01000C0F7E4777419EC618341EB6784492ECB58 -:10C020002C602F48947C1626F6FFC7D0F971A273B6 -:10C03000FF7194FE790C1FC838A642F0C1DDCC4FC9 -:10C04000F1D12EC107EFBDCF7FBF6D9A7D21F1E108 -:10C05000FB1F70BF53C651DF3E7E8AFC43F1532F56 -:10C06000DDADE04FDAF07728260E5A83EBE49D56DB -:10C07000FE7BD50AA7B3EBEE2379DAFCE27BF8BBB3 -:10C080002B9ADF73689D9860C175C456138F2FA6D5 -:10C090004EFAB062A6467F0C49ABDC85F85AA6740E -:10C0A0007DEF4F186FBC25CE4FDD9B4174BFD0C5CF -:10C0B000EF5FD8709D2F04B7BF3489F3A894E63999 -:10C0C000581A25E198237EA765AE31FC5A37AEC7D2 -:10C0D0002AE15DF50AFDAECA01ECBFCE1031F3BC1A -:10C0E0005E17E5E965FFFDE72943A4CFCC6F70FB40 -:10C0F000D8A324FA789E37A4FBBD9E035E1E6F551D -:10C10000E406BA060C8FDABFD8BA8363F36FA57D55 -:10C11000A9FFC5FCC9B82EAAA8FCF79963C7C53A00 -:10C1200083A59A3CF5316BFCF5838F849ECF435CED -:10C13000C1F88BB2FD1FE33C4F89B8F094581F3B08 -:10C1400095C4D7CB4E0BFD9CE715EB79E27A4AAC50 -:10C15000A79D4AD5C793F23D83977F7762B125B0FB -:10C16000544357EFBA8466CC4B64148ABA92858CD8 -:10C17000C74F7B5274E72438BC9579DE0C7C4F9C0A -:10C1800033B087DB655CC7C675E6F559C14B88B728 -:10C19000462FF3E33A2DF3769BEFC0F54AB13FF714 -:10C1A000BCE09BF3567E957039BC53F2BC88EFF926 -:10C1B000DD44D7DEF6946ED297FF072EE42C97006D -:10C1C000800000001F8B080000000000000BD57DE0 -:10C1D000097C54D5F9E8B973670B9909939040101D -:10C1E00088938D246461B261D86492808A22262C5F -:10C1F00015651B50C2964DA0FDA5D5BE0C06117944 -:10C20000DA426B5BFCBBBC01C16AB52562B0B126EA -:10C2100076544AA1D53A22286A6A4754D69044A057 -:10C22000567FF2FBFBBEEF3BE764E6DE4CD89EFA9E -:10C23000DE4BFC7972EEB9F72CDFF9F6F37D07BB24 -:10C24000B322C999C058F7ECA099A98CD965FD21F2 -:10C250005E871F031BCCD862FCCB09A5D5E657F33C -:10C26000E0EF0DA6CE6026B5B36F52185354E665C5 -:10C270007150C964CE0A3B3E9DE0389A0D4514B416 -:10C28000433F7566DB066534BD5E6185FEE68BFE69 -:10C29000D870BB11FB9FC7BB62F3DBF67FA5C43030 -:10C2A000B6C0CAD60F83F6856D43CC3003B62CC614 -:10C2B0003BD291836F4C761C8571156FB4FA4D3467 -:10C2C000F48D3F93FA968C19D951393F5A8797319B -:10C2D0005CD78800AD6B63694FD27F1531D6D36EC2 -:10C2E000716C83716ADAFE7A588175D5C8F5B568C4 -:10C2F000D797ED54182BC69AD5F7A995B15B98C27C -:10C3000006423FAD364F36C2ABC61AA479428FE61D -:10C310008A5C18EDFE09B1B4FE21F03DCCE7C546BC -:10C3200037FBC41482E72A075FFF14B5BADC1CCFC1 -:10C33000D8993B99C3028F56EDBFA3C90AF5550F93 -:10C3400030071FDD6D6063A07F01AFFEE69750618F -:10C35000604EABA8E3B07306306766A83ED413A75F -:10C36000A943BF0CE7B152F43B6CD9559AEF47D4BF -:10C37000A768DEBFBA6194A63DD95BA0A9A76E18D5 -:10C38000A7793F7D5399A69EB1E546CDFBF92C7563 -:10C39000208375D6ED53990F409BE59BA169CF7E15 -:10C3A000FA76CDF7C758FDAF27C07B2D5131790CF8 -:10C3B000F0A8292A661B96CCEB0EE4007CEE14EB69 -:10C3C000C86D5EACE9E754CC75FB705FEF0C544D63 -:10C3D000638057A35B5768FA5DA956F37DDB643A27 -:10C3E0001284EFEAE117E159C07AF60E03FCA8F5D2 -:10C3F000292E3F342FDDC2DBE577CB5BB7D277CB7D -:10C400007DDAE72B9FD6D6BD652CB3DE06EB74DA5A -:10C41000E38F02BEB2ABD855DF84D155080FE025BB -:10C4200018EFCC63AACF928CF0C9F8CD04828F8923 -:10C43000F99C7DF7EB0C632E3FBEFF9CDDE585FA92 -:10C44000D2FD77D07C2C895A3C88726AF1203A530D -:10C450008B07769776DF079668F75D0FDF58F7A8AA -:10C460000BC277D00D5ABC90702D81DF6F13AE8F49 -:10C47000E8E059B8C7DD642338B159D631083F3EEA -:10C480005F0BAB50592AFC1D0F7C069EBB7817EC46 -:10C49000B4C3E63500FE3CE3548CC427443FF94660 -:10C4A000FFABB89EF58A97E17751CC9788FCA2A99B -:10C4B000C49FE4877D29B0D6E3CEB1CF6C15BF47CA -:10C4C000BAAF36FBF3B05DF6F799CD43CF3B953766 -:10C4D000AA18AC9719FD79C40FAD8CC697701C33A0 -:10C4E00080E3F14A5661C6715E14F8FCE9FBCB08A3 -:10C4F0008E55AC7EAF1BC63BF50187EF72E6A5F704 -:10C50000966CD2C2A10FFC747003B471E2B875626C -:10C51000DD2B18F31952FBC2536953FCF63C04435C -:10C520009BE4DB9E6F0A39DA213CC7B1DE1FE2DFF4 -:10C5300012BEF08212CE9F703CC7E0D078129E925D -:10C540006FC9712CAC5E4D443AD0F13196A9DD270C -:10C55000864C620CFD473F7F021E6A8D13830DC619 -:10C560007E70F28C5D23C6618B3D8908272BDB44EE -:10C57000FBB751716D50611CF5EAE42606F02C748E -:10C58000B855DCAF6216988BCF4BACCD4D46E8EA80 -:10C590006A76DE41F834E4A99A6F0685D6A1C8759B -:10C5A00079156684FA44519FE955828F26E37AFE15 -:10C5B000FA158E3B519433B184FD83657EF2217C64 -:10C5C0003C41718EC0F166FC292301F166BD52CF5A -:10C5D00074F33BFC32F4A31A7A06E17B5398C7C884 -:10C5E000E5AE8FE4CD5F9520CDFB07CC7D1F965245 -:10C5F000BED5B2E6EBE642BDB605E4560C96517EDA -:10C60000154AD6AA8327331EC1BA015682F8BD1235 -:10C61000EB72DF9343ED5457FBD6D7C21A86C65D43 -:10C620005CBE3F98EC10F2B167246FE7FC6D998017 -:10C63000D73229B77CDAF975E01F4319FB8B1960F3 -:10C6400052807464F51A063296980C7489F3CC63A0 -:10C6500079D83FD0D5F064E87F701CD0A1124E7716 -:10C66000FC7DD9DE87EE74EB67F5B0B96301DEF6C9 -:10C6700022B30758EE1DE1EBBD0478483D6221BEB0 -:10C680000BE37DE174525933A0E35D373617059211 -:10C6900050FECB7DAA33334F33EA2DCD0934AE7C27 -:10C6A000EE4E360878013E5E029CFADF8734D28770 -:10C6B000E43E5CAA3E347E109FBF84DF75C9820FC2 -:10C6C00086E07DA3069E0CE099AB81F78D91E02D6D -:10C6D000E171BA38F014EE936A3F3818E13C2FB19B -:10C6E000E2966400C188C3C1A38A01E55DE7538F68 -:10C6F000A2FC6A555D48C3B513397FAB7D492592CD -:10C70000EF6AB3F814F87E59EBEBA4977536020381 -:10C7100035F50F9FDE75EAE0DC170E7CFFE43AAAE0 -:10C720007478B6E0EDB3F6F94E5ADF8AE4840BAEC6 -:10C730005FDB2ED67FEA476C61450EAE2F67603017 -:10C7400027346E26EE37BCFFD3988A7A845BD13BC0 -:10C75000C363102E53D4B6BD57211CD6282E0B8C84 -:10C760003BC9C2BC51B0BF431BCAD927B04725C182 -:10C770007A9703E09138DCE652011E193F542B7C76 -:10C78000D0EF3FD7AC8EBB03CA938D30743A3C5781 -:10C790000C1584676CD7473F81FE32ECF35C1BA11C -:10C7A00036DF02F38171927F14ED4F05FEF067339F -:10C7B000B3229D9952EA0F4C857E7B625517EABFE2 -:10C7C000F12A9B8C7825E11C1FCDD7219F973EBE77 -:10C7D0005D09DA42CF2735F514AE82F2E66427AD63 -:10C7E0004BAE7352794F21EA3B12CEF1A9FC7D6624 -:10C7F000EC499A114617D9021E1DA8CF013C6B13B4 -:10C80000CCEB51FE7559799DB93349EF5D63E57401 -:10C81000D11195E443B9D8016B0D507F7E3BB385B0 -:10C82000F1C328F7C06B60DDEC6D95ED80E29CC331 -:10C830003D3096E0E1E0FD083DAB8BB11B104E6B47 -:10C84000A6960D898332A189C3478F273B93159AFA -:10C850005FF597407085A1E7D546BFD961C3E7660C -:10C86000CDF3230037AF25545F7C3CED3A46FCC541 -:10C87000B51EDFBF634334F386E9552D621EFDC14B -:10C88000A536D6C88C008F5A85555CE8BD97FF5BEE -:10C8900025F8EAE7FFAEE02F09E591D7F76632B752 -:10C8A00067CAEF9FF61BD43B6B03266681476B5E1E -:10C8B0002A1DC222F4D70BE72FC733DFA0B0BA314D -:10C8C00048F0A8FDF25A7A5E7E7FA719F11EFB712F -:10C8D000C2F33551EE21AE0BC0395BC0B9F6CB586F -:10C8E000E61D14FE9CE355A8FF786AFF1D0210F0B8 -:10C8F000D6DBAAFA76C0A7BFDB67B8615B84F97E96 -:10C900002DD63F2AC148F492ED67EEAD11C697EFE0 -:10C910000D8E033E6DE370AECCED3BBF96B2E002F0 -:10C920009CFF3593993BD278A7C57B72DE2D71C1F0 -:10C930002A81F7232BED617587761FA3C5F82D3764 -:10C940000693B0FFAEA96C4E7384FEE57E8F31D6A0 -:10C950002B088FD2444F06F291EA5BA10278326431 -:10C960009EDFE0C909D15D7FFB1E8237D85D851748 -:10C9700082B799DA657F270E08BA646E9B02F4B419 -:10C9800048C8AB45DB574E03DED96BBF9CD802F6D7 -:10C990000B0C7182D5BF6EC7FA2685EC93C51EC6F7 -:10C9A0001A80EF54ED285C8F626B512263D7C6F179 -:10C9B000E7F760B9CE1492B3F47F370B978B72FC14 -:10C9C0003B1FD4EAADCBD8839FA3DE73E200E70F11 -:10C9D000A09E92FD5DF5B0B6BF65DB6F3A86F35C55 -:10C9E000A6D37F3250C103FD233545D81363D81831 -:10C9F0009403AB769C35C738FBA7839340EF69E976 -:10CA0000C82F1D548E49718F4A81FDE87E9BCF73DC -:10CA10004A8A272F05FD0D6FF3799DA93EC3E5C412 -:10CA200063F1249F2CC8CCE14FCB5CABAF09E6711E -:10CA30003FB09328808FC5C2F520A9FFA9EA6A35C7 -:10CA400006DAC77EB6260EF737FED9EB6FC0FE12A8 -:10CA50009E8D76E37A3696BAF3D15FB0B1D2E66AAC -:10CA6000822EADF03DCA0FDFEFC6BE76156A07CD48 -:10CA70009BCB8621DAB5BDEA477FCA06C3E77B8731 -:10CA8000C1FB1BAE65AE26161AA7AEADF2799C4F60 -:10CA9000D22C2E673626BBF31D61FD32A1CFD50AFD -:10CAA000D875B767FC7C3CECEFA3FB489D86F5A5E9 -:10CAB0000C44BE318AF17D66E7014E80273876B896 -:10CAC000DEDA09F28A6584EAA39A15BF09D653D340 -:10CAD000F2BC01E561F5BDFEC173512E3D63746D7D -:10CAE0000B9B5FFC9F8796396342F268AEE2207D24 -:10CAF00041EAE5B731F99343783347E0CD6D421F02 -:10CB00009F1BCDE1BB98B992F0BBDBAD2CC60024D6 -:10CB100035B7BCB998E4D54A532CEA3FB89648FBE0 -:10CB20002DCBFEFC4AB54FD9BD0AEC7B97D2331210 -:10CB30003B3989BE1EEE5FF26D4BEEDBCFDD298205 -:10CB40000E470AFD308DB9EDB0EEDA5732B66E847D -:10CB500026CB00D8C702E24BD69202D28FAD68F73F -:10CB60002C7F39CAAFC484E0C21CEE7C03FA09668C -:10CB70000C2FD8883AE961E02F40605DA66012D1A1 -:10CB800031F01D0564DFC329932B8D80E7B55781F4 -:10CB9000FE05F5D7B655F27A4AB0CA00F593292BAF -:10CBA0002B8D8097B5A38247B17E2EE547BC5E10E2 -:10CBB000AC52A13E30751D7F1F0D4140ACE1A9FF75 -:10CBC000B3D20BFD9F8C15F2DD155C80F853FBA7EB -:10CBD0000CC3C6B0F55A5339DF3A19C5DF3B99CCBF -:10CBE00016CE4078670647E23C7BF12245EAC39BBC -:10CBF000A894EB94DFB1C4C8FD3F99C2FB5F5E2EE1 -:10CC0000F49268B601E106DBE48D01F8EF69CBD858 -:10CC100086EF6F488913F0827E8A42FD4838CAFE4B -:10CC2000E4B82B50EE223F36013F0EE3A3CD295C42 -:10CC30006EC238EB689C1C0EFFDA19C3F371DF601B -:10CC4000BF8C62BF8CDC4EDDCAE707FDC6E611FF74 -:10CC50002F34C2FB7BCEC3FBC9A179EBF1A35DE00E -:10CC6000C7F2266084A4A7A5121E4D8AE6FA212BDE -:10CC7000D2AE63602A879F353596AFB3773F86285B -:10CC8000344E9380E370807BEEE5AFFB2D319F6FD8 -:10CC90007BDD61FBE556B1BD356B5BF87A18DBAC2B -:10CCA000E9E7E45ADD77254080388FB854FAEEFE84 -:10CCB0002866A5E76C5BEF77C9795C2F457DB546A3 -:10CCC000E8D5CC7B2D3915AA05D7A8D910303BB1B2 -:10CCD000BD5971FB103FD3607D08DF19D38AC4FAB8 -:10CCE0001C627D0EBE3E9F064FD9C19EA459F6BE62 -:10CCF000F8DB0BF7DEFE720A447F1ABA8ED41FD21D -:10CD0000477FFBA1A47ECBFB21E7A983672F9C75FE -:10CD1000F393F0447AA6EF72B4F828E779AE3FBAFD -:10CD20004EBEC2F14AF977353F867D44FDC4A9C5A0 -:10CD3000E79A9664C3E29CD077ADB897C521FF5CB3 -:10CD40005AAAB07387B3E1C8BFBD65DC8FEADD6561 -:10CD5000713539C9AF97995A1CD1AF47CFF5F65EF7 -:10CD600077AC9929A41769FD0CDD09AE801BF5D4B9 -:10CD7000D3CCB503FA1DAFD33BBA613F77D942DFBD -:10CD800085E489B6FE43C13FFBFA8D7A92707E45F9 -:10CD900096B2179C2EC6CA52B712BF2E1A58B63A70 -:10CDA00019EAD7A73E49FCBA6858D95974CD4C4DF9 -:10CDB000DDCEEBD9656753B0FEE476FEFE24F70BBB -:10CDC000C8DF99777BE5E4A121FDE1C654278DAB4F -:10CDD000961B18E29145BDCB857252C2B3BFB2C853 -:10CDE00062A88FA4BFCEECA5677E9E5122E4738912 -:10CDF000B4E783468D3DDF1D63F5AA00D76E94A787 -:10CE0000B0DE05A99E3908FFBAE8CE05A80ADF1BE7 -:10CE1000FD9119F521C50DFA06FA459C0E360FE66F -:10CE2000A9746EAC203D7085CB6A24780A3F15AC9E -:10CE3000ED1BE8E7E5579EB97B181FA602E73156C0 -:10CE4000D07FDD2B5F7DF121CAD1933617AA816394 -:10CE5000DB1E598DFAD5D8B6BF7FC5E5AD8DCEA9FD -:10CE6000E4BCC7A2BF119E97B45A68FE63DBB296BA -:10CE7000E0FBE3DF694B45FC98D8E16F4276D0DDFB -:10CE8000FEC7619EF0732B764CF926FBF2F58B5EA4 -:10CE9000787C6666A85F023C7EC2E171BE0AFD8AAC -:10CEA0005D0907D607494F1BCEFD98E27BD0CB33F7 -:10CEB00091CECFB0012E3C57E8B6F37EF4FECDC341 -:10CEC00095B03E783EB1076610A6374FFAD20A0CED -:10CED00024542F65B19A7AB975A8E6FD298E644D60 -:10CEE000FBF589599AF6A9CE7C4DFDA6CCB19AF7EF -:10CEF0006F76956AEAB7944CD5BC5FE9AED4D4F3AB -:10CF0000FDCD9AF70BF7B56ADB0F3A691F0A3B2A8A -:10CF1000CA519F77053C4D585ED3B9A97CA093F5C3 -:10CF2000F1EB16057D4DF87CFCF9FA623FEBEBDF87 -:10CF3000652B3C741E60C17D51C3CE074A03448FEC -:10CF40005D069733DC8F3B6FB067672AF97101ECA0 -:10CF500000EC6BAD3D8370BFA62C7C488DC17DE994 -:10CF600061E4FF6A31077F361EE5FC7C95F4DE162E -:10CF70002323FDB1654EAE0F7D7F8795E08B1F2289 -:10CF80009F9A1F4DFC642268B8B46E3C0355709F95 -:10CF90003C9A7597B2E5BA7DBA4B539FE2F8B1E679 -:10CFA000FDEB13D76ADAA73A1FD0EDD3664DFD66C5 -:10CFB000D723BA7DDAAADBA76734ED133F0D3621FC -:10CFC000194DEAF4AA7698FFB8C39BCA715FC67779 -:10CFD00078E723BD14F93D4DC442F6D4BF8EA51F9A -:10CFE000EC2AF46BBDD69848E59E4627F9A5F6369F -:10CFF0006652B9AFD145CFFFD65842E51B8D6E2A98 -:10D00000FFD178039581C60A2A9B1B9BE9FD5D8DA4 -:10D01000AD54020447A0BC881F24E40FD4D1DEEF36 -:10D0200032046BF1C4F5B327CF115FEC1A10ECC2D8 -:10D03000FABDEC2CF1C5401A233AB4A633E2635D85 -:10D0400069EE6569509E4BE5F56E936D03CA816686 -:10D05000833B1FF5EBAF9E3CBFD93882B1FBD65660 -:10D06000243A6279DD0A75DA6C34CCBCE737BB87C9 -:10D0700033F67B1419E3A85E89F5EE28DE7EEEC94F -:10D08000F3955E9A1F3F6F9E153A6FFE2A35C2795F -:10D09000F3EF8F3BEDE86F39703EC38EEB3A20FC27 -:10D0A0004B6E966F5A0465A931DF8472F1B04E8FD2 -:10D0B00090E5BF6CA5065C4FB3C1351BF514EF8D31 -:10D0C00026B603F8C50C85DBA3BD7A601A9747DD49 -:10D0D000375BC8DE3968702F413C073EFD04C2EB68 -:10D0E000AA34FB0C845FB7BD2709E1909866E3F58D -:10D0F000849E27145758DDC4D7199B163DA39F75EE -:10D100000E4E8BB0CE61690E1A9FF9DD2350FECA18 -:10D11000FAC14A770DCA8983A5EE749CCF810A0BA8 -:10D12000D18FB7C2EE4B4726677417CF0EF3BBFC07 -:10D130002ACD44FB36CBCCE98CDDAEFA7644B0D3B5 -:10D140005E48E3FA3EED1BDA73B745931E7ED0C00E -:10D1500096ED8A00C7BFA77139776A4064FFCB1B81 -:10D16000027E6533EDD45FF79A283AEFEDAEC82022 -:10D170003DA8BB1EA004F4D17DBCFEF46E6AB7C806 -:10D18000A3303AD79C2BF8D4EFDB56FFFB10BCFF43 -:10D19000D19A6817F170C728924FB78B97E70FB2F3 -:10D1A00092DE327FC68832944B73C5F9D802BB71C8 -:10D1B000301D931963CD0EE8E74E5BFE7A14FF55E0 -:10D1C000F195E658A82F1B7ED77A2C57A46D36C749 -:10D1D00041599DF3FC7A541F6B80B48AC95E0ABE24 -:10D1E000D908F35AD8A03AB9FD24E49A7BE565C57D -:10D1F00063483C4438229E027CC92E7C53C05B7E2F -:10D20000F7A680E7DC34A1B7E5B2DC6FB4E73E0BEC -:10D21000114F3AE7BF39B21F3FBDB65DE86DEF9AD7 -:10D22000F9B82B9F36F9C2FD4972DC7F88791C342E -:10D2300033B7827ADCED76C28FBC3967EF2D86F585 -:10D24000E7B5390C746E2FF9788091FFBEF8530F53 -:10D25000F1B96B3A834F1D6284E7AD4827179353AA -:10D2600033BD6B493E8C3D07F207F9E279CF478722 -:10D27000880F2E137CB09EF8D79EC606AAEF6DF4D9 -:10D2800052B9AF7183E0839BA8FD8DC62D820FFA42 -:10D29000041F7C9A9EB735CEA1F295468FE083FCA1 -:10D2A0005C7586C0A779899E7548FFF2FC7296D599 -:10D2B000634278FDE5110B53F17CA2CD42780A144C -:10D2C000F0C4A3F1182F63716C74F68D9BD1F3DB5E -:10D2D000DEFDD79DF3AE49746FC27DE98D9341FDAC -:10D2E000ECEAFEF1E70073DA919F3CBDBD82F8C71E -:10D2F00001A7D38E7AEB3369953350AF3DE076DAF0 -:10D300004D50FFDDF64ADEEE71DA2D507F366D06A8 -:10D31000AF7B9DF628A83FB75DD47D8C0EB59FDF0F -:10D320007EEB0CF4639432650FD243B9357932B099 -:10D330006B908FA57B900EAE4F5C3419E9C099E6D7 -:10D34000247C98EA5CBB07EB37656E350E72A2371A -:10D35000347F1D7E57165F69C4EF260FBF6B1D7E9D -:10D36000775DDA6663F87737E43CBF0EEBD35C5B3E -:10D370008DA80F3AD3F879A9EC47D665BBE4AF681E -:10D3800027209E8E6EAB203E9ED75A417C5CC2A564 -:10D390006C56E57DE8A7AB6B551C0ACE6396D27B35 -:10D3A00058AF800E517B1EA805F8AC7FFBE2B8B5E4 -:10D3B000188782F57154FFC5DAC87CF72F88077A81 -:10D3C000BEFB9EA053949B95D0CF7B403FBBA09EBD -:10D3D0002ED657D7B6C8BE88EC198F1DE56B761AC6 -:10D3E000978BA385DC5C28EA778AFABF6CEEB7706E -:10D3F0009C77FBA7EB0FB01DE8B68ACFA30F5D6B40 -:10D40000DB055D770838B2A29E24ACD7B04DE42787 -:10D41000BC587CD7F270FB2D19E3249A29FE421FD9 -:10D420002751CD02BCBF665D9C050B9AE93CB63521 -:10D43000EC39F123617F0CE07C6F0E326BC0BF7F53 -:10D44000A78973C7BEEBFE4AF0ABFED6AD6D17EBF6 -:10D450005ECE7C14D7A65F07F324106DADB41DA477 -:10D46000FDECBB9E60E4F5F45907B7DF651C8BF457 -:10D47000CB831E14955E8C7CD0CED07F13CE270E2E -:10D480005D804FE8F9D1B7C5E72EC06F92709E7AE4 -:10D490007E23E3B3F4A5D4E7A0EEC5F83CEF2B510F -:10D4A000E4A7FFC4E9C9C27EBACB7ABE30A07D161C -:10D4B0001F243C6B002B0F9F2B667E4E0F5F8CC48E -:10D4C0007D3B6EF0FE01F5A2921D8F119FEA42E1B5 -:10D4D00000F4E8823AF29D2D575514E0772C93E33F -:10D4E0004FB7C2E5A2A47BD007A91C9BCEE551DFB4 -:10D4F0009269E21ABBB77E95447EAC8BE07B7F706D -:10D5000098A24E087A91DF974493CAD3A930BF02FC -:10D51000FA5F67E960D2233A47988D587EDB7662DE -:10D52000E78891D4BFDE5EEC1C5A62E5E35E7703C8 -:10D5300096AD66CF964568278DB5909DF496880781 -:10D540009C1ECDE3A7DEC27362786FFA91F3F128D7 -:10D55000BFF4F666E7FE7965CEBCBE7627AC7332C3 -:10D56000AEB3FA63C37DF8EC72EDD0EA862F987102 -:10D5700010C8ED86F3CC587829762953915D141C98 -:10D5800076BD8E65F1A781B83C27DA9F527F10F6F1 -:10D59000E945E2904A7AB8BE30E93CCB3416A19F07 -:10D5A00069009DDF28257FE776AB28E5B9C8043EF2 -:10D5B00005B6C060F39953347148894628E7A9C17C -:10D5C0003158EF62013A27D1DBB37F157E28B06B6B -:10D5D00037A6935F8AC727C18E0C42FC9DF293F752 -:10D5E00017DC4D7C208AF4A15EBB76B781E20C5A31 -:10D5F0008CEE8113D1AE6D4877AD85FABF0209BFBD -:10D600007A19CA3AC717043749BFD50D67099EBDB5 -:10D61000E703C2EFBBC904F207CAEAFF56490E5539 -:10D6200033B681F68DBD665E15261759F3E7BDF05A -:10D630001F0D7CAF12014876D684996EF8AE52D891 -:10D640001FCCDBCEEBC2EE626CC44C37F453992096 -:10D65000DE679B79FB08D9FE0B5E4F97FD7D3E830D -:10D66000EA43655DF49725EBFB793D598E7792F798 -:10D670009F2BEB165EB7F3F75F48FFC34CE40B92AA -:10D68000DFBF942EE4443ECB177139EDE9C5178C0A -:10D690004BD1B60BF9B0F019D56B1E8DFB3335FAB3 -:10D6A0004DA4EF668562E7AAEF3191BFFB545C732E -:10D6B000DEEA307B45C6B15494DBDDA8FFD5BC98CB -:10D6C000B14D15F13CA87F7CE1E47AF914D546E729 -:10D6D00013671EE47CBF3FFDADAAE165CD7EF66910 -:10D6E00057156E8FE3C11D8C77FAA1215BC9BE4827 -:10D6F0000BD0F9F98782DF0D06DE5A12178A178BD5 -:10D700004F656EB457E3FF08FC19F7F8D300F1E357 -:10D71000AA3F72FF6FCD23AF93DC5BAC3AC99F5B2E -:10D7200096E3F918E1D3650F905FB1AAE1159AD796 -:10D73000992C61573A7A72C2E179A22FFC4F5F04AB -:10D74000FEA7BF4FF8EBFDCE2B6C7B68BD2B2E33B5 -:10D75000AEADCBCECF455D629F8E189C6304BC2CD2 -:10D7600023012EA7970446C6AA18741C18CCE3966A -:10D77000DE2846BBE84CBD9DE1BECF5BFDCF3C4FF4 -:10D7800004BFAFDE1EB80DC72C0EC12B61641FF89D -:10D790000EC5F12E005F6DFB770CDF21C6A0D98589 -:10D7A000E7A88719F5332670C41C1E1F337624C7DB -:10D7B000CB81ADFCDC481FF73576A49DEF93389FF5 -:10D7C000A999F1C6043C9F91F430299A35A3BF1D55 -:10D7D000F0DA25F0DA85782DF137744E03DF45A0B5 -:10D7E000AF10FE6AE1EAEE0BD7C9232F8CB7DAF649 -:10D7F000EF18AE2DA00FD3B9E6EE28F2A7E8E1BCF2 -:10D8000074243FDF92F06EB8089C1BBE2338378C1F -:10D81000746AFC1112DEFDC927FDFEC87947A0D34A -:10D82000E22BA1D3AF33847D630C529CA97EDF1B16 -:10D83000FBEE7BD345E8A9E9FBA4273DDCF465B505 -:10D8400038EFD43FDF3A92FBCDBE2B38FEFFE64FD8 -:10D850009F5FFFAAA67D61C37E4DFB22EFDB9AFA94 -:10D860008460A01CD15CFAC7AF3DDEF33AD6AFD4DA -:10D87000CFDE9F7F7DFA0B4B0D78FE5612E0FEFD4A -:10D88000C5999E2F90AFBC65F035D901AED77434E1 -:10D89000AB741EE6CBA773C0D5628E6727FCE7A3E7 -:10D8A000BB016FCE320BF93FFDAF66199DB97DF11B -:10D8B000A0F44B95B9C3F4C4526BAC11F5A75260F8 -:10D8C0007991F0E66B8137140F04F43EC7CA4CF12E -:10D8D00040E773E62814FF3487F1786A28FD1E6854 -:10D8E0009F6E647E0BD42B6D46BF85CEFD78BEC384 -:10D8F0006C3E4D663182C686F65DFC20B28367E1E0 -:10D900004398AFEA56299E6D76093F2FBCDDD66C51 -:10D9100042797ADBBE7B4FDF0DED6C9DB798C76B0C -:10D92000CBFCB50F0C97730EF8F5484EE7DD8A383F -:10D9300057564C2E8C73D57FF7D6484E67D3D5B546 -:10D940002AC6BFF4BCCD48EF967407EBDB6729E02D -:10D95000F919E3709DCCE4CF8841FD797339BE5F3E -:10D960007DD04970A92B599B87FB583759F9D8921C -:10D9700017B26FEA1ACE919E3E457DAE09DF3F7326 -:10D9800098BBC6AFE9F4AA68AF84FC97C105489775 -:10D9900017B383E4BC3B1AFD844F1F35EEA3F2ADF1 -:10D9A0006BFF5E8C7A46B03110D17F79A5FE02E91B -:10D9B00027907E03C907FE754FF910C4CB74C917B1 -:10D9C000ACCA30E40BCCC84BC92FB333FAF0D7D173 -:10D9D000191796ABDAF6EF98BF5E2A9E572772B9F1 -:10D9E000A8C76F3D5E4B7C86CF8A1518F776D0F7B7 -:10D9F00050AECE65DEDC6AE0B373966E328D57AE04 -:10DA00001CAF57D83E4D6211F2542E9F9F3B79BCFC -:10DA100064B94AF6818C5790FBB03843F81943FB40 -:10DA200056957161B9A86DFFDEF5F84F175C995CEA -:10DA3000639AFC86B57DF1F5BE8BE0EB7DDF27BEFA -:10DA400086E5CF2C500DA17C118C27463DAEDBC75F -:10DA5000F32197256F8AA1E0CC929E18D41B97B72B -:10DA6000AB8487CCE8360E057C5D2AF0B593F9DFF0 -:10DA7000457C5C3A6129E5D12D7B2C725C71AD78D7 -:10DA80007F85ADC58CEB5CB15DFB5EAD882BAE7E5A -:10DA90004EEB17AD9D70FD31ECB75617CFF36C868A -:10DAA000881F2E60053CEE42AB9FEACBAE46A6F146 -:10DAB00057769D6F247FC00BBF3DF94BEF8430FB41 -:10DAC000BF2FDEB65F046FDBFF6FE2AD6ADF4E791A -:10DAD00055978BB73F1AE53E80F396FC781EF226E9 -:10DAE0001877DECB169F17CF478B9DDCBFA9F89A1E -:10DAF000F0BCADFB2B46FEA3C5C2CFD95F5EBA8C8E -:10DB000037187BD0D7C4E30DDC2AE6898ED957516C -:10DB10008EC715856FD4933ED2EFB995CCAF12F175 -:10DB20004397CAD7A45F6FCCF17AD2B35C0107E9FF -:10DB300043E3BE6C7E1DE5E3B7E5EF96F270FC2093 -:10DB4000EEBF280A56909ED765F217BF877AC24B60 -:10DB50005111F5047326D78B667A179978BE619FA9 -:10DB6000F34073269E070AFE6FB0BA4D08A7296AD4 -:10DB7000E7AF6E45FC09A8E4DF5BF3D377FEF0A8BE -:10DB8000F3E2767F9DE32CE90DFDE9FF75069E7FAC -:10DB90005150EEA4383FB4A7D0BF27FD7DFAF78BD4 -:10DBA0004695256692FF6942C08DF3D9C2E7D3DF5F -:10DBB000FED4357CAEF12FF6377E5D7BB1637118F4 -:10DBC0001DDC96A948BBC371D41ADADF4BC5838923 -:10DBD0003D7334FACFFFEB76C57415544B909FB963 -:10DBE0008A8FEBAF8CEBB1F35880CA05AC874A0F34 -:10DBF000E3F1F78B998BCA3B451EF3DE2CCFCD9911 -:10DC0000781E61EA194CF1932F7E9D837873FADABE -:10DC1000F19B30D6EEBBD2E3BAF39D347EF7EEAF84 -:10DC200093300EE6627C614DA2DB9319E1FCF91F93 -:10DC3000A52A9DB7B0C38F929CA814B730B0C9FC79 -:10DC40001CED0B6732E143882F0ED92AF9229ECFB3 -:10DC5000E67E6CE0F124CB155F3ABCDA1A34106929 -:10DC6000E52E49F6A9586FE1EDB935B13E05EAB99F -:10DC700063A378FB5DB13EF4A3CF6741A2C78540A3 -:10DC8000A2582E629CEFDDC1DC3CDF81F5A4A01E12 -:10DC9000B6A4CDCAE3FD59300DF97B5E3FF64F5B6C -:10DCA00026E7D3A353383F1F5DA6F553DC2BF8C0FE -:10DCB000275965FF447A3A96E96EC272745C60E354 -:10DCC0002F8BC86FCFD07E3836F6C774DE28BF1BC7 -:10DCD00030AA6C03C26FA7C2E3D3BDED168A8F8052 -:10DCE0002F065784C5F5EFCD2AFF19F6F72BE1F77C -:10DCF000EB0FAEF09D266F36444F5E9ADF68B4B9E5 -:10DD0000C8FF0E0F4A685CAA3FF5F4B459EB72C81D -:10DD1000C7EF45BD77C028CFFFC2798D363366C3C4 -:10DD2000F93F6EF16D23FDB43E09FD954B9FB01890 -:10DD3000506F781FC42DE6A17CD868A5F29F6007BC -:10DD400063F92FB083B1FC18EC602C3F013B18CB7A -:10DD5000255FE683B060AC2CCBDD9A591C3A9FD38B -:10DD6000CFF77901CFDEF1DBCD34FE27591E826F6C -:10DD7000EF7EBFC47C78A8B333B6E7AAB80BE05BEC -:10DD8000FF7C86C3459E17EADB7F2BF63DAFC54877 -:10DD9000F23DAF35185315F6DEDE4C33B5E7EEFE37 -:10DDA00094F250BB1CBDF0752BB0E4E9065EDFFBBE -:10DDB000F46282EF2759EE7F225C81BEFF86655EAA -:10DDC000EB3BBFC0FC1FE89FE20EBA959E5F931D20 -:10DDD000A05B871E0E725D3B63031BF1FB9DBB5373 -:10DDE0007025C06F18A71BC42325D27AD7D27C6FA9 -:10DDF000B1F414615ECB2DDFA811E38C3FC92A2555 -:10DE000038FF18F12D210C4E62BFAE94AE7BCFBF10 -:10DE1000059E32797F07F24E27CAA1F331A8EF554C -:10DE20008AF3FDD696B4B7707DDE7D2A4B7712FE5D -:10DE30006AE8CE91C5F14496B9EDE60ADCA79DEDFE -:10DE400047D3EEB4D1BEA42DC171B3D235FEC7DC29 -:10DE5000B15FFDD72FE3E97D070E751BDB3A05E3C4 -:10DE60004FE65A5FFD0B2E69BEE3E329187FB230FF -:10DE700051D98BE52267F275187722E3E3EFC82CBE -:10DE8000DD8BA434CD55497A5A2932973079506EBA -:10DE90008DC643C1DEFA14C7204DFDFAC4619AF75E -:10DEA000A73A5335ED3765666BDAE5B8D35C859AEA -:10DEB000F746C7F5A4A07D06EB207A603B548AD3D1 -:10DEC000CBDD7DF0C66CA84F7F6AB60BD5929DA2C4 -:10DED0007DFAAE721FEE4737C0D30C0AD4F1920719 -:10DEE0007EFD4BEC4CA7FF57B73FB9D7EDBC0CFDFF -:10DEF000BF1FBD5FF2D9956DD662E4B3976A07E89C -:10DF0000F7272F4B6B17F48737BD74A13839DEEC38 -:10DF100057D98E08788311A91C0F7939FD00CF1FBE -:10DF2000BB5C7EF619F2B34121FAE82D757EB9D1BA -:10DF300066D75BABD14FFFA6CA281F4FE4F555E16A -:10DF4000DF6A08DFD99D5BEF1B1A4FCFBDA8E762E0 -:10DF50007EA91BFAAFCA12FEEFEA57EF1B5A146AEA -:10DF6000676B3ED6BCCFEE51D66BEAEB92B5F507A8 -:10DF70004BD7877FDF1F5FACDAB2C8ECA1FC4FC57F -:10DF8000ED8BC01FE47CA6BC1645717D3763BC0ACF -:10DF90003CAA2D7ADB88E7B437F7234725FFB94D34 -:10DFA00065F591DAEF12FD4E7B2D8AE2602EB7DF28 -:10DFB000F701961467F8472E47DF1F183086EFFBEE -:10DFC0003D595C0F3D5DBCF9A75FE0F9E84B8CE281 -:10DFD0003E4FC772FE9FD772CC608072F4008E2FC6 -:10DFE000798EA001E54AF7B2682FC6F5D72DB75351 -:10DFF0003CE8E8949E77ADB0F5EB9ED9FBB015F602 -:10E00000ED034C820C93ABDD681441FDA1ACBDB3B4 -:10E01000D6C1DF37BD16E5375CC17A1EC2730994DD -:10E0200083659CCE1720DE08F9823EF6BAFB58AF16 -:10E03000BC41BE80EBC7FA9E67F61F7C18F5F0FD69 -:10E040009CCE31C24E6FDFCF0DB3EFD9639C2EADA6 -:10E05000F0CBE39474F4BD6793D976413A6FA6B8D8 -:10E060009B4BA5EFA7919EB32F48CF076E82FDA9CA -:10E070007B89DF6B71A62D9DF262FB93E7755B5484 -:10E08000A24359EF6A536F40BCD5E7A14BB832B7F2 -:10E090008BE853DE1BB56AE27F66A0DC5CD56EE4DC -:10E0A0004122FD8DB34165CEB07176BE625946798D -:10E0B0006E62FEDD525EB7FF3BAE3487976B23C8BE -:10E0C0003D90D3A67894D3950AD99587DA87942181 -:10E0D0009C0E29CCEFA4BC2D1EA73C937787CF6D57 -:10E0E000745F496226C5274BFB52DA95B3DB67A7FD -:10E0F000A35EF96ECBE243B073ECC3AC541AEF5697 -:10E10000E6253DF8506CC508F44B4C17F1018762C9 -:10E110007B3A912F1F9A18ADE0793FF4BF0EFB9721 -:10E12000EB3A64AA18C1EF9F9071C9A3AEE89EB8FC -:10E1300029EA3DA537E1F9F63CE640BBF21695EB3E -:10E14000B9ECCF9C3E25DFAB53027138CFBD5933BC -:10E150004E67C177431A7E26FCAA026E461E877858 -:10E16000A97A6EAF3DFBB4C2EF457171FDBF76C2B7 -:10E17000A95FDD8A797260772B309FC5ADAFD2BDC4 -:10E180003F7A3BBBD7DEF93FF4A7F6B5972A2CA31D -:10E19000C2FCE47ABBA9574F97FADE0E1E27FFFA9E -:10E1A000C4DF74AD84FA9A1DD104C7134F58BCC89C -:10E1B000C74F6CB390FD7322AEA76335D677E5BA2F -:10E1C000BC349A4B732FDA5283F33D943FEC6F26A5 -:10E1D000BAD7E3D8E3163FC67B2C7F326B1BDA53EA -:10E1E000C746389F7D0EFD81CF26D03D03CCC3BFEF -:10E1F000BF59D023D29713540FF5B776D22396BFC9 -:10E200003094F898DCBFE38F47511EFD897D3307BA -:10E21000A2BFACD3F03CE5F130D5E6457EBC725BE5 -:10E2200014E9810D0E4FD628585FF96F6FBEB510F7 -:10E23000C77F2781E17ABADB5E207F65687F23CBC9 -:10E24000F7336DA99C0FF4CA5B1E77BB10E36E53C6 -:10E2500029EE7634C2B786C97B1779DC6D81AAB8FE -:10E2600029EFE0A1C879E4EE515C7FAC96FE9341C2 -:10E27000CC9A8874E861B4DEEE8732B6A1BD33670C -:10E28000545CEFFD4C3C5F52E25B47EDCBE43FB1A9 -:10E29000F078BFA8C8E7D8D346F1BCE22AEB398DA5 -:10E2A000FFA6B6E12B8D5FA5368791DC2D6872162F -:10E2B000DE05E56A01E7E52915B7E0FA56346F7E19 -:10E2C000F10D82CB633FFA00C7DD6723BF0D7B836F -:10E2D000C34F6FCF54593F17F4B45573CFCCD147C8 -:10E2E000DEA37893A3BBB3F370DF16AB81A3781FD3 -:10E2F00057973DF0D1DD50EEDA7780F6453FDF3EAF -:10E30000E7F60AE72BD5B88E4118EF52B16414D165 -:10E310002DA7F7231B73097ED29FDB7D22B2BD257B -:10E32000E729FB97F393FDCBF7568BFD3A6D0EE48F -:10E33000A17C4ECC746AD6753A2690176BC3E7DC85 -:10E340009F773A0EEA6178F35D9DEFDC2EFC3C8707 -:10E350000D6B7F6806FCEB6CFEA5C913CE472FF34F -:10E360005C47CE57C695CA3CDA874789F388116C5B -:10E37000443FF9B75B90CEAAFBE6DFD2F3FEF26F23 -:10E380007BF36DFFCDF36D657E6D51B9A13E3CCF42 -:10E3900056F2C3A26C789E83E7FE5AF95E345AFBAC -:10E3A0007E7FFCB1209BDBD7458322E7BBEE1FC5F8 -:10E3B000DB9B989FDF3F28E4E278017779EF97D4E1 -:10E3C000536A05DF96799EE3DB78DCE67891B70344 -:10E3D0005C80F25CFBDCEF96984D7255DECFA74077 -:10E3E0005FF3E222E50B07681ED7B21E2ADDCC617F -:10E3F000C412C04FE5645641E575AC9ECA1BD826D1 -:10E400002A6F64CD544E63012AD928BF88F7BC8790 -:10E41000E7994E5D6A40F95A746B64BDF8D445E1E2 -:10E42000E0A5FB032F170ED7317ECF5F1F780CCFEF -:10E4300024FCD6C3439FAF399105E9E2924988B8DD -:10E44000A968073B29BEB59CB9A93EE512E1501267 -:10E45000F418797EAF0E1EE591F1E29CA0FF9FA219 -:10E46000EC2C0EED5356B693DFDF20F60B0CB144C7 -:10E47000E4FFFA7D94CF8BA2CBCE3A8145389E6DD6 -:10E480009C4D79DC8565AB53A19E92BD6936E579DB -:10E490008F2F7B01F3BCD39EDDCCEBA3CB0A4D2E9B -:10E4A000D022D7FE6236E6337A44DCB447C44B331D -:10E4B0004FBEE69E2CCFDA1FD2BD639E113617AE3B -:10E4C00053E685ABA9FC7C35E906FF6B2678AFDD0A -:10E4D000E189CE46B965F5C738514F583B85EE8F77 -:10E4E000BADFCCDF97F7D9C8F5C97B6E76EDCA5E87 -:10E4F000ADA45C7C1ED0FF50ECDFB3369DF2E33C54 -:10E50000BB15910F5736640EF08DCE8089617E81E8 -:10E510001CCF94E249C2F71926C5035D0C1372B8EB -:10E5200073577636EE5356B638DF8F4F2E4438DEAB -:10E530009A529185EFCBBCE82CDC9784FECBCA6C59 -:10E540007706BEAF7F2EF3B2C7657B72B1BD2EFAE0 -:10E550003CE59B75E5BFB33E98DC374FBDC9CD7C2C -:10E5600066E22BDAFCF4EE2566BACFA9A8C2D38402 -:10E5700021CAD7CCEB1983FA31F45B929D80F7095D -:10E580000693F2E1BB8767F2FC777DBE77FB2BFB3E -:10E5900035F9ED92CE7AF3DBCFF0FCF6107D3DB28B -:10E5A0009A85E5B74BBA9174370EF3DB63B09EB52D -:10E5B00004DF9BF84E07E5B74FEA088AFCF6F7B48C -:10E5C000F9EDEEFF5C517EFB3171EFDB312BBF2F9C -:10E5D00049DE27B56A373FFF5DA5F0FBA456FD9ED7 -:10E5E000DF2725EDC265627D35FB77ACC773BE655D -:10E5F0008FDD41F75131710FAA137EC3ED42792FA0 -:10E60000A93E0FA60EED41D29BFDA477E9F361EA86 -:10E610001E2B277BB04EA747AFC816F6A090674CBD -:10E62000E87F4BC5B7B80E1BD96766D23B573DBED6 -:10E63000DAE5C0BAA02BF6D87374EE26DF678F0D2B -:10E64000225C9074B67C8342FAAB84DFE8A72C6E20 -:10E65000BAC7F8A921A4B782BE2DF2987DDCCF0FEE -:10E66000B882F1F03B637B52504FDED99EE9020E37 -:10E67000CBFED4EFFDD3CFE9EE9F7E5273FFF419AA -:10E68000FC1FEA69C70D3EEC670CCBFCF904A81728 -:10E690001F37BA7CCED07DCC17BB7758C2DF22F6AD -:10E6A000EB72EF21D6DFF72CF31FF4F711DF2FEE1B -:10E6B000239ED8CF7DC416B54D25FDE19C51732F07 -:10E6C000F135629D254EE6C37B7EC7751A35FB5F2B -:10E6D00012DCC4501F8A3A68D4F8112C4E6DFD39F3 -:10E6E000890FE27E91BEF0B6F5C2D342F04CFB0D2D -:10E6F000C15377CFB38453EF3DCFC36D84F7E3F6B7 -:10E70000BFA0223FB8DCFBBEBFEFFBBD2F769FB79B -:10E71000FE9E6EFDBDDCFDDDF32DF73DDFBF4AF350 -:10E72000BE7EDF0BF7FD447B0FB5D86F2FFC7E9BC1 -:10E73000FB7D325BF877C57EF7E00568C0CFFE1140 -:10E7400073FC4124CBE9D1E23E3869D74F30919D2B -:10E75000F5967350B91DE95FC8A90A21A75845333A -:10E76000AF0B7C7105781C41C1617E7F455190C71C -:10E77000138C391E393FE896124573BEDBF7DE6213 -:10E780009E673CFE3C8FD3D39FFBCBBCA14A7794C2 -:10E79000F6FE867EF288A41F07F47866463DDEC04A -:10E7A000EFB38B70CFF11635353C8FC843FE9D59C2 -:10E7B000D64012E27354B2273E2721946F3409F3F6 -:10E7C0008A14B20785501AF8038CF3ECC624DBAB2D -:10E7D000307FD4F603CC9381E93B8263B8B98B3F99 -:10E7E000C9399E1139C0078F288EF585F0ED3FC6D7 -:10E7F0009D4A42F964C173ED023AF7BD3A27FCDC49 -:10E8000057DCCF1F343849BFF0FE4421FBE11476BA -:10E8100036368C5E3798445EA3EEDF2F10F694FCFC -:10E82000F70B8E4017CB806FCF6FE579D42B133B5E -:10E83000851DC6EF71BD63B88DEE7F62EE4217B7DE -:10E84000C3A57D354CBD1CB979B1F8A29589273493 -:10E85000762E7B6ED0259D2786D6CDFB3FF24034A9 -:10E86000C99B230F8C203F5FA8FF2EB2FBE7D76B1D -:10E87000E38C1736BCAFC1BF45DE8F35EDC1F81E46 -:10E88000D330587FF0C5A1D7CD05F89DDE6D198333 -:10E890007406FB362B27CC0E0E3E943199EB0117F4 -:10E8A0005BE7299A4787881395EBFCA8F130D5835D -:10E8B0008D415D3C8F576397CAD2FC1AA37B727A55 -:10E8C0009401AE487E9693395C6FEF1079901D22CB -:10E8D0000FB243E42D76883CC50E91A728F3473B41 -:10E8E00014E6C6788A798AFB8945C9943F7A17AEBF -:10E8F000B36E454F1EE6DBD58D0E2E5054CA1F5DFC -:10E9000083CF23E48FE661DEFB1F726EFD01EAF91F -:10E91000C70778E95E92A79E9BC1EB664E1F2FE664 -:10E920004CFC01CF27F5FC0FECE75345F5D3FD1761 -:10E930002F29749ECADC41F38C0BE497DE97C3CF7A -:10E9400017D6EB4AF2452760FF4CE47B3D3892F244 -:10E950007EB65828EF07C6A1FC2B79FEAFCFCF2A91 -:10E96000F8B3C58F7C43FA611EC94996F702937FBD -:10E9700025FEE7169EB7150C24619E17C6FBE0BD69 -:10E9800019EC2073F33C307E7F9FDC87477244DCB8 -:10E99000195EA45F14CA13ABD97FE423E42365395D -:10E9A0009EC771FD327FA926E6558A9BD899E3A4BC -:10E9B000EF60BEB45EE007EB1482731F3FDC0EFC19 -:10E9C0005E9FFFDEDFFA4F2F09FC3A2739943F158F -:10E9D0009637B53327CC5F26E711EAE7C2782DFDDD -:10E9E00049217FD7FD23914E0AD00F1EC1CEDE2BC9 -:10E9F000E0D2618AECBFFB384789983F5790C11835 -:10EA0000FA0BE57D93EF209CD0EF749B8BFB4119B3 -:10EA1000BFB7AE6686CD857C4BF68FF7E53E7F812E -:10EA20007196A754BC89EB5F51CFFD7DB2BD5BE110 -:10EA3000FBEA7D88E34BCD2BEF7F74378CB2FCB7BC -:10EA4000B985C8A7E5F77A3877D979FEDE62D54F60 -:10EA50007004F87E80FBA4F7F35D295C2F377F1AE2 -:10EA6000E045F730F6F583032285E96F16F9FD706E -:10EA7000EDFD6616FC771860BC1661F7B408BBA7FD -:10EA8000D524FE9D1C9D1DDC12E071442D89668AF3 -:10EA90001362E2DF7590727FCDDB3CAE684D32A32E -:10EAA000769C1FEEAF12DC4B72A8F79E2A05E42B72 -:10EAB000C0EF94C3A3E6A21FDAB39AE4927A35ECCE -:10EAC0002FFA4DFF76A3B0E7B89C2B1672AD18FB5A -:10EAD000C175E40C24795724C61D63AD277D7A2CBB -:10EAE000F30AFF8EF0833CB097ECC0FF0D9F4D61A1 -:10EAF00077606800000000000000000000000000D7 -:10EB00001F8B080000000000000BFB51CFC0F0037A -:10EB10008AF92C181856593130DCB0666070B4612F -:10EB200060D86C8E90BB218E6053133F97A74CFF2B -:10EB30003C4906860540BC0888974892AEFFB71648 -:10EB4000825DACCAC0F007C87701D25FD519186ED4 -:10EB500003D97F81B803C85F03C43B805804C8BF92 -:10EB600009A499D518189E00E97F40BE34907D44D1 -:10EB70000DBBF9FFB5F0DBBF5D0395FF128D7F4143 -:10EB80001DBFFE284DFCF2AF09C863C35EF6E4C7A3 -:10EB9000471F057A0702AF474BD7E2A60C0C7A66EF -:10EBA0000C0C85D0B4BF0649BE192826610A617FC6 -:10EBB000D103E617207F258E7CF11528CF0F94EF27 -:10EBC00037C76FBF38335A7AE1C154F39609C1AEE3 -:10EBD000174295DB248CA9FEA708030300E92850FF -:10EBE00078D80300000000000000000000000000D2 -:10EBF0001F8B080000000000000BE57D0F7454D54A -:10EC0000B5F7B973EFDC9924772693106042024E72 -:10EC100012D458038C18302613B821098424E0003C -:10EC20007E34565A07E421B640A3B5ADEDF395E125 -:10EC30008F315AACD0F2FAD4767DDF40D5D5F6B913 -:10EC4000DE0A8A4A43422790502488112DD66AFB57 -:10EC5000A276D9F81AED80C1C6EFA38FEFEC7DCE76 -:10EC6000C9CC3D994942F5AD7E7F64B537F7DE7377 -:10EC7000CFD9679FBDF7F9ED7DF63963B7B988E75E -:10EC80000A422EC17F0B09F95C2E21645EFC2A9E8C -:10EC90002F729270C61C42B29C077A67E710B2D8F6 -:10ECA00050FD4B7C844C75AEED26A5840488C3E7EB -:10ECB0005008E9525EE89D4DEF8FBBEC7E0781FF67 -:10ECC000EE22643E21773BE99FB4FCF173F40AEF36 -:10ECD0003FB145082D5FAB361205BE772A7E870F00 -:10ECE000CA9BC6B22984D410F6DF8273A446A1CF92 -:10ECF0006BBC773492D984547B68AD4EF6EE12FE2D -:10ED0000BF49082D5F4158FDA6D3FABE82EC3AA751 -:10ED1000BAE12EA60667D1FA2EEAD6F7DE257F24C1 -:10ED20006E2897F0BC80F603FEA03CB88AB872DE6D -:10ED3000CBA07FDF406EB8A4D2AB3689901BE37CBA -:10ED400091AF848409994C483BFF5E23C1D9704F31 -:10ED5000C833D87EB6E0635D3FF1D27EE79411FF01 -:10ED600012CA87A9756617A17CADA8D1191F6BE7D8 -:10ED7000E7F61B84FCE083B63C52423F8F6C423E78 -:10ED8000E6703E767DF0FC9B5B806F7504F976D86B -:10ED9000EECF0D968CA62750979D46683D7B824707 -:10EDA00033B01E42FEF3D2145E4F11211DC1C2CCFE -:10EDB0005092EFC4F591AD1E421CF1FBDD26A96B0C -:10EDC0003346977B1E06731E54BF06E9ACE0BCFCBD -:10EDD00081429ADAB0DD261CA7C39CFE6EF368461A -:10EDE0007F09BC8F66D8683FC2E76CE4495A45C7C3 -:10EDF000E0A274A077BB698BC2F38E413D02FC2078 -:10EE0000DEB6BC15B346D37FF8DCBAB9D8AFD0268E -:10EE10004BBBDF1FA4FD35A07FCF642CA6F59C1F44 -:10EE2000B479543AAE7BF8F3C3A1B60C0F7C37909B -:10EE30008DE3F9C856FAF7D5A9F9F1C8822F1786DC -:10EE40000C28E7B4F263F0FC89223A6E1D7B353F53 -:10EE5000F46B3C7E7E9FB723EEB3FDD16A0FAD37D6 -:10EE600010F32BA017D983844C2A00BDE838E6861E -:10EE7000F16D24A84781E0A2B42B593FFCAA0FDE14 -:10EE80009F52413E029E28F663841EA0EF6AA0D3E3 -:10EE90008BD747797B3F8471C4FE6D4FBB8AD27B91 -:10EEA000BE4CC37AF69BDBAB34ACEF62540579DC25 -:10EEB000C4E429C717DA6607FEAF27FEB00FEA25BC -:10EEC000D8EFFFCEFBFF635E9F68A76330BB4A03AA -:10EED000FA9A881FD4A456BDAF0BBE0F6C64F4CF52 -:10EEE000B8B75901FE5D715F3F5E239CCEDDF03DFA -:10EEF0002D90DF1C53806FD3EF89E275EFB6B7BA60 -:10EF000080BECC9D240D6CC19E1A5B167CB767F148 -:10EF1000B43478EF0E52C5A7F620E0F7DCD54DFBF0 -:10EF2000B3B746433AF70E52FED372EEB0C70F7A2C -:10EF3000ED0EFBF8D5EF87F2BFE4FC38CCDBEDE457 -:10EF400074B8C3262FD75C02E5DCE1305E23BC9F9A -:10EF5000C4B719E5EE6E2E77BFB4873E077CCF1994 -:10EF6000245E42F5F9F087F5B9D0AEA85F2EFFD444 -:10EF7000E3FFF37A783F7990BC6D9F0DD7E85A682C -:10EF8000EF6AE8871BEEFBD62A68A722A847E6456A -:10EF90001B21C5713B95331C5C7A13DAC75AD42305 -:10EFA00061072A06759B9299A86735A8077BB91E49 -:10EFB000D40C46514EA89E1DB3513E853FA07A46C3 -:10EFC000E5EB70D086E3FD444C473B4C8AA3792B9C -:10EFD0005CA3F5A8E3DC86B9C06FA14FA3EDC7FF22 -:10EFE0001BFAB597F62394C4AE89F684BEC9EFC761 -:10EFF000D5374F18F5AD83EA5B18F819B4A5CD04E1 -:10F00000FD6BB5A19E786BDABA98BE6C427DCB5988 -:10F01000CFE899BA26827A309EDEEDF579AA34A837 -:10F02000BF89E969C7E03BDB1C301E6B08B71317CB -:10F03000BBE03E702FD36B59CF643DCC0CF4A17E66 -:10F0400016EC8C11B8FA7634A25CD356D250FF522B -:10F05000E86107E861E9FF3F7A5823E671CA982C16 -:10F06000CAFFFA186178C8B30FF150AD8FE3A182DF -:10F07000D76FFD2A7DFFA23D03C7F5C5C9F421DE88 -:10F08000AB110238E3CA7F5973372D5F9F23F0CF4E -:10F0900046D4EF3AAEDFC7E011D59FAA7E85CCCF2C -:10F0A0008672EFEEAEA6E54F0E103FBC3AE9531163 -:10F0B0004F750F12AC4FE8671DEF6F37BC07791B18 -:10F0C0002611D04F81236AB97E9FCC61EFBB2F12EE -:10F0D000B403A2FC49A244547A7F9CCBDFF9E2DB63 -:10F0E000FF87BB90903F6F8BCD8ED2E7FF6E8B7DFD -:10F0F000DD468BFE7E99EF69B81FE0E5FE83CBE924 -:10F1000020C70D27AE0DDDA450FC5349621BEE86CF -:10F11000EFBC458FCC2550DF47330865ED57AFFE78 -:10F12000CB7BA4102869D383AEB85E89FA443D2F07 -:10F1300078434D0A1D8F81C8BB6E18BF0F0E7E34F9 -:10F140001BAEC49884386B3C3C1610E315EBDB0116 -:10F15000B883D450B9981F978BA9B1BE63886387D1 -:10F1600018FE22759B711C2A3D8C4F5D17CEE6C19F -:10F170007747385D9DE7FAF2D01ED659EBE9B4F730 -:10F18000AF09B2FAF1FB80878DA3A0A75DD8074530 -:10F19000E025365E01FE7DB9D637690EE57FF909B7 -:10F1A000D5BF8D7E573EDC5F4392D89D889285FD0A -:10F1B000AA18B0CA67E785E32AF085D2AB02BD95ED -:10F1C000B13E95D96D2657012E5795B133167B2E3A -:10F1D000DAEF8C9D699803F66380D9A7547CEDE63D -:10F1E000FD38CAC7FB88D04F12C900FA7B28FD0F33 -:10F1F0008DF17DAD47B5D02DF4ADDA9961C1E70B46 -:10F2000087B325BC6FA5778116457E2D007E91D4EE -:10F21000FCFAB6928DF52F1CFEDBF825DB11516F41 -:10F2200027F0B164345D04845BD0ADFE9FCFD74E30 -:10F230006E67A8BFD20DFA4AFA0FA8A08FB5AA81AF -:10F24000F6A5E26625E248B02FA29F0BB95E4DBD40 -:10F2500048D06E980304CB1D8E31FB9F8ACEA35BF2 -:10F260004DEC5FD645DF4E98571719C17CD09BAE49 -:10F27000C97F647AA69C43FD322FBED7FB55CAFFD7 -:10F28000535CEF0E6FADC3EBCB5B9B912F014371D2 -:10F290005D0F54CD64FA562DEC1A9F4F4E70FB71E2 -:10F2A0009CCF33AF6E0DE1F357B66EE47C65FD592C -:10F2B000C4FB1335AA0D18CF6E6711CEFB0B355367 -:10F2C0004BE65755C4AC7274CC47F18E0178EBA86D -:10F2D000713DCCC7D43F46BCC2EB19F92E5F6953D0 -:10F2E000E6C4EFCF0A5CC4CBFDCAFF2CF3EB6ECEB5 -:10F2F000C0F9A02216AA05BED63629C4097C9D3EB7 -:10F30000AB318B3EFF7C93759C457D3D39EF4E02C2 -:10F31000BE5704825A905E6BA3B7683E57EA71E805 -:10F32000D1828DD7E1F832FDA988F5D798948E2542 -:10F330009E8246F44787351BD8C3463ACFF5A35E75 -:10F340007890CF62FE3895A3D64500EF0DEECF0042 -:10F35000FABB3DEA64B86E87C981CA51ED458A4F50 -:10F36000E78CD1FEB046794E2BD2A2CC5FA3F5C07C -:10F37000B5C750F9F3208E470FAD179E77FDF5877F -:10F380008D737300F7ABC89F00F9DAA9EB60FEF24A -:10F39000DB91DF426F851C741B6C7EEC8959E7475B -:10F3A000C4B7F455CFE0F76F5E09F323B1235E12C3 -:10F3B000F8577C7FC4B87DEF0AD03BA2FA0919FD4B -:10F3C0007DF066D5A247E57EAB9ED5974EB2DCF7C1 -:10F3D0000CAEFBF15DD05E2C9DB517DE64A1F78805 -:10F3E000C1E6DF9E08C30762BE16EF0344D66FB9BD -:10F3F0003F8B4EF9C1CE50F9043B53FD49A951430F -:10F40000EBABC9513DA097C73CDBCE82BE7C10F868 -:10F41000F53760DEAD2BB1D2DF3138977DEF5591F6 -:10F42000BEF69CEBF1FEB0D72EFA6F2C037AE02FDC -:10F43000FAFE08E97F7536AD7755C44AD78A6086EB -:10F44000E57E73DD24896E6B5CA8FAE2068CEF2CF6 -:10F450002AEDDA914DEFCBC11415419CC961F92E0B -:10F46000E0B4DE97437C877EB78048CF2F2EC6B8A6 -:10F470004E39C475C473E0A764C7E93DD221E6796B -:10F48000593EC57C9D4A7EDB6D6423C443C8D0CA07 -:10F4900071E242DB93CEF744DBABC0F897739CD0AC -:10F4A0006E6FCB80E795E798FD2443D949F18D3CF9 -:10F4B000EF13F2359423C14FE209939CF9C8C7A416 -:10F4C000FD127C69A5C37209F00EC749F87112FDDF -:10F4D00096BF9F02FA4DFBB3B8E9408687CA5775BD -:10F4E000CC86F2D561EC41FD6CF7AB5C1FFB2F25A0 -:10F4F000CA674353D529880FD2F204F4B7C3B80BB7 -:10F50000F537781DD35FAADFA88F01AA8F897858B5 -:10F51000C8BF2CEF03247CF67A68977CF4DA2AC003 -:10F52000C10759BBB2DE53BD433D3E4FD4547A8E22 -:10F530007AD943F532593B97AFE73613DA3F7FD09C -:10F54000C570F7283D7FB56612B4E754587B9FB16C -:10F550009E1FE1FA23CBF7687D5F6480FD3F6FC893 -:10F56000FACEECDD62D7BBAFCE66C52D7AFF59E986 -:10F570007BA0789F0A5049E8F178FAFEB7EA794A09 -:10F58000FD9DA07ECBCFB7D814A62F29F433AEF7BC -:10F59000612CB7C3458A213ED6AEA4FBB717809E27 -:10F5A000B3788D5C3E5DE5F51267F80FB43F6BA94B -:10F5B00053964959BD99F4CF808156737DA8775BE6 -:10F5C0006CFD53E0FECF2436E55A15FC067208E2C6 -:10F5D000408A49C8BD9424C5E7216BA8A3D5A2865B -:10F5E0002ED968796520FA890203790FF101AEBB43 -:10F5F0005A09D954FADC41F963D0F2443B83788F3D -:10F6000022201CA7E55C09963B8D28C6CFCBEC8356 -:10F61000FD426ED05F5BE379EF5A5A2F892A97AE8D -:10F620008DF7F3297B24CF6F403F233FDA02F1A609 -:10F63000C774FF93BED1FDFCC426FC9FCBEBE7272C -:10F640005456909F36C6CFB02DDD0FF12CB97E53A6 -:10F65000BDECFACFA6D36B05F071CE683E2A839439 -:10F660007FC007ED3F2F81BF57E16572A5FE593777 -:10F6700021BE425467E4CA2474ACE774B4A8E66CB3 -:10F68000E0B75ADD86FC390CE36F00FF72C8371211 -:10F69000E4AB52D5B17F6A0369C67985446D6037A2 -:10F6A000C61B0FBB463415C6B1EF12DADB164E9FF0 -:10F6B000833E37E6A61E2FB5C11F8BD271227F660F -:10F6C000E37478A9552EBFC6E9FF32D0358F992152 -:10F6D000A8BFDCCBEC90FA27BD3992448E7708FEA8 -:10F6E000737EC9E50FDFC2FA2FCA7F87CBFD372FA4 -:10F6F0005FFE574F2D4A3D6E42DE95C1E3A9C6AF6E -:10F7000039D9FC364BB5713AC2CA44F4A15265727C -:10F71000A956D37183FED55AF9F86DCE8F55BCDE4C -:10F720002F2A6633C8C3D54AF06E15DAA9E943FD1E -:10F730002B847AE8F36B89790F3CA7EFBF01E5488A -:10F740009DF53D7DFE2D7CDED487EB4AE279976204 -:10F75000FE23FFEE9FB05ED3FA9ECAE156784EE5D7 -:10F7600085A873E1B90FE9A172429C602FF6DDFE16 -:10F7700005E02BFDFE7EAC9F9CB17C6F070391CD15 -:10F78000AECA5C767D1CE48EFB993B9A4CE4AB4E92 -:10F790009AB91FCCE6AD057CDE728202C33CECD187 -:10F7A000715ED4D2CC48945EB33D5113E278934855 -:10F7B0005F18FCA8D5D27CDBB4C63ABF7C61BD75AE -:10F7C0007E59B329CF72FFA57B8A2CF7A1FBAEB57A -:10F7D000D4B76EE7F596FBF5BB2A2CF71BF6565B04 -:10F7E000BEDFF8E306CBFB2F3FB1CA72BFE9E95B8E -:10F7F00093AE4B8AF9EE41DBDB9BC01FDB01AF12FE -:10F80000E60B2DBEEE686338CCFA1D153F9F361F00 -:10F81000CA110C29C872AA49EB96AF8FE8CFDD96C2 -:10F82000F9F668B820C74B596A166806C6DBC26687 -:10F83000DFCC29F1F9BCDA47E76337F8E1C9D757DC -:10F84000355EAE8AF457C3B8999AB59CC6D7590DA0 -:10F850007F0CE329F23AABE663F3B44CEF19D5958C -:10F86000037689D6EDC3F555237B42EBABE3F68FE8 -:10F870005AC209F58FB75705FD2C4ADDAF05A531F2 -:10F8800015C89B68BFE2745A718F58DF5EC68A92B2 -:10F89000F282273280DE653E86874829C3374EFADA -:10F8A0008FCDB38CFF0DBC7CF01E8F1DE2C8C11A3A -:10F8B0002B9D0D1C3F513DD4C04E94174BEF81CE74 -:10F8C000D950CE8A93BAB93CAA1A5FE79E4FE6E3B5 -:10F8D0003870BD5D21F4B696C5278827F9FA77FD03 -:10F8E000302D84819888256FE06471513A7CB7ACE3 -:10F8F00095F81C149F3C386F9B6711D5FF46D3EEDB -:10F90000AFA3A5ABFD2C1E5E6FAAB8CE7B4531BB65 -:10F910006FAC51224B287DF5A13E8CE735AE8F6C44 -:10F9200083EBB48D510DE990F8FAB82F926553E34B -:10F93000FCCDE3FCCA137CE57C14767CDA26EB383C -:10F9400036965AF9B59CF353E6F372CEC7E5121F0B -:10F9500045FCAC44E3F22CF17119C7A1CE794563A3 -:10F96000FA758FF33897901F4D9AD784FD1899DF59 -:10F97000B8FCB6801D079CE7E13885CF7B55331571 -:10F98000F4836ABD0AF2B776E63E4B7C73C9885CA5 -:10F99000323A6BF97897E7BF8A71CDCE1C3EEE9470 -:10F9A000AFB5F3E372D83093E563ECE4FDEEE038F5 -:10F9B000BA9DC72D5BBC67D4C4B857C78CBE7C3F0B -:10F9C000BD7FE942DF9AAF517A1AF3157F1DB41B50 -:10F9D000E271565EEFE1EBB6E5037D27CEF561DC23 -:10F9E000E7A59CA231E38802BFCBF250EE0FD6C050 -:10F9F0007CB224FA0B15FA5F1EA36C53002747351F -:10FA0000C05F8DDEBB358C73E5DFA541BCB1367FB1 -:10FA10005F35B41B20A1DD5510F7CAB1FBA33E88AA -:10FA2000FB8477BA419F4B985E6EA4FF12F552D0CB -:10FA30005D31D8AC019D4B7C92FFC2E5A8D62B3D31 -:10FA40009FB904E52820C9D13D420FAF245726CAEB -:10FA50008F8817E8E70AB91E26971F310EFFCEC719 -:10FA6000E1773C7EFC268F7FBEB1D587D75F6D2DB9 -:10FA7000C6E73D5BFD78FFFAD632BCFF358FCBBEC3 -:10FA80000A71568C930679BCB509EF7B79FC54C892 -:10FA9000E7037CBDA356EDC0F860833FE4F424ACDB -:10FAA0002B3470BA51A4015F9414255DBF75CC3816 -:10FAB00084FC3B3322FF04EDC0CAC682FD0F51BE59 -:10FAC00038BE434280171D477FA15D45E5BAA1AE10 -:10FAD000C0BE01DA0BB769D7D3FA1AA2BFD08AE049 -:10FAE00079E375F6DB93B42FDA49D5BE6CB756D5FA -:10FAF000A9921F2AD68F4261E8E7D458280AF40554 -:10FB0000BCBACF9104F777E56EF0825CB59C0B79B7 -:10FB100041AE5A72D93A032059901B9DCBA9281F98 -:10FB2000F05AD7D7754E77077D0EF476C4C65EF7C8 -:10FB3000167A20CA55686DAAC748DD3F397EB4538E -:10FB400049EE8F5ED46CF89D1BFA4FED37B5851AE0 -:10FB5000E8198828D03F958A0DE8976110B42F19CD -:10FB6000FE10B7B7D6F939AB2C18AC827239C4BFC6 -:10FB700004CC96D1EF05B951CB16BF0FF327294915 -:10FB8000B0C7E0CFC8FE7CE2BD8A262AECCA86ABAD -:10FB90005C8EF1D7E022D47A1DA3EF7B03D6F8AFB9 -:10FBA000C1F95BEE3BF11BB097DFF3DB58B91CB634 -:10FBB0004E7ABE6C1DE2AD728EF71D6437964F27EC -:10FBC0006D78DDC1F97DBEEC0C81F95BD5281ECEC8 -:10FBD000017A9C9130FDDE2DD96DCDB0F25BA13C58 -:10FBE0005903B87940B3F8114A19B3DF4EF0C3C1D5 -:10FBF0003FE1B824EEBF85C82560FE0471D24EBB3C -:10FC0000D5CF12D7DF6ACC0FB1D9A5FCB6FFEBF97F -:10FC100077FC33E59FF0FF46F0DBB13B09ACA788EA -:10FC2000FC3E51FE57521C49CF7FBBC64CC2F72A3F -:10FC30003BE3FB7576096F05E476D2C2C04F9DFAAF -:10FC40004969CAE87A52B54706E68E138FDAC6FCD0 -:10FC500044CDC3FAC7F373A8BBAD58FC0EA7E905A2 -:10FC6000BF6FD4F75E9B454F47D3CDF8F359D3BB55 -:10FC7000903A9A705D2EEC7019C3892B7C1427D2B0 -:10FC80003F57184C4E4F572991ED28A7A6C58FAA6C -:10FC90002B5BF23EDA25EA67E8F339FEA6F4B742B9 -:10FCA000BDB49E5772C57723F6C47669CEE87A82D2 -:10FCB000350CF790F0CF9726C60582545C8AE74250 -:10FCC000BDEC7B5AB4EB52323AB8DD0A96DDB5DCB6 -:10FCD00070C3BDA93C0A38AE24011F005F673AAC6F -:10FCE0007C96EC5FCD28BB67B5B78BA9FC1EA2ED57 -:10FCF000D4A9CD8D35B4FC923DEB0EBE88E408FF4F -:10FD0000C297B4DE53F0C78D80F6AC7885F8599E63 -:10FD10004575D887EB822B7214122900FAAD742C2A -:10FD2000CE97FCAB1CB91FBB711C8F6A741EA1E37C -:10FD300075948EE36EF47B93FB49C27F5B583084ED -:10FD40007E92F0E308F7E33CF45F221EABE4E5AB00 -:10FD5000EEF169B07E5025C58F2B47F28109FA4933 -:10FD60000B8995DE4AEECF554AFE9CD0F79F0ABD1F -:10FD700015FE2AB78737093FA93239BE10D70E2999 -:10FD8000BF8DE247B3ED32F4800055B4BD4632C2B8 -:10FD9000278B7C75155CD516A57CBDC99FC6F2AFB7 -:10FDA000299D9AB0E7C82786B797F3F237F974947C -:10FDB000FF804741FBDE384E3C2250C6D6555E36AA -:10FDC0001496371826AFE17A11A7A786FEEFDEB9A1 -:10FDD000D09E552EF27D7DD59939306F28FE0819B9 -:10FDE0002DAFB57C5CE1FBFBB2C14FA1BE7636AC5A -:10FDF00067C8F1883E0899527F9CFA4A05A3FDF92D -:10FE0000057C7CABFC04C47E943FBF808FEF8251A5 -:10FE1000FEBA1567BF1C7B07F3ACCE9728B82ED26D -:10FE200055F031FA09629D26CEBFE3E84F05CA3E80 -:10FE300062790323FE08AB6FB9A8AFEC18E617DEB2 -:10FE4000EF3986791CA74FB0F5EBD35ACC007F640D -:10FE5000A9C05794A35191FF5E007912ACBE28CF80 -:10FE60006778D9F96A06D84D9117D21948BE3EB7BE -:10FE70005065F16371CDD7198E2BD6D9FC23EEC511 -:10FE8000F88EC8937AAA94F97BDFB68CBB5C3F945A -:10FE90006FC2B85FB42438467E41A3C4678F6EC575 -:10FEA0001BE3E15AD14F990F723F47E98BCEE260D5 -:10FEB000ABEDE6747D72BC1D31DFC9E5573893E7C1 -:10FEC000CD549559E38E72DECC6A7BA804EAAFD696 -:10FED000949D993EB46BA84F472F1A8863CEC78E66 -:10FEE000EE8461ED196271CF4AA2F23C1AB311D6C9 -:10FEF000D3C43E871A1EA790E918AFFDCAA17EF4AD -:10FF0000B3AB866335207F3705BAD0AE2EA37675A6 -:10FF10005212BBBA581DDC3909F4D7AFA07D78F96D -:10FF2000ADBE9A494C9F313FD5AC2CD226811C786E -:10FF300092C7A116703949A577F4430D70C344F5F3 -:10FF40006EA53E82836EB85434FE38A59287F3B115 -:10FF5000F35F4B161F15D7EA14E3BB8548FCEDB0E1 -:10FF6000C695E57A449C87A81DF9A0CFC2FF95CB22 -:10FF70007D5B67F1FE9E597790FE04BF4ED803BDAE -:10FF8000ACCD80F8446FD9D8F3859CAF5645ACEB27 -:10FF9000CED54EEBBA73AB66FEA36EC1496B99BF6B -:10FFA0005AB616FDD5E5250EF457BB66DD81FEA9D0 -:10FFB000F0AB5B6E3C807117914725FC5399EEDEE8 -:10FFC000DC670C28371EDDC28FEF74B03C20F0DBFD -:10FFD0007DE8B7BF8DF94572F9430EC6AF2735F3FB -:10FFE0000740FF4EBBE95D0BEB87B31CFE27938CEC -:10FFF000C31B0EA6DFBD29D6514FC382C664EC07D2 -:020000021000EC -:10000000F2419E6F841F2BF60D4DF532BD6DE07EE3 -:100010006C45C95AD4C72C2FF55B816F7EE6B79229 -:1000200041AB9FBADCE8CB83F197E73B7588FBB522 -:1000300013F45B1F48637214F210A797BE4FD328C6 -:1000400034A5F3E82E75D173C08F07B208FA03A761 -:10005000B3F4C8FE24F18617B9BDAB553759E4ADEA -:1000600092E312BDA6DF8078C0E9A1B1F3F21E923F -:10007000707A6131A972B8E11AAB027ED07BD3816C -:10008000D718E64B7F77D686C264F5ED6FD592CE52 -:100090004B6FF1715BC9E7BBAC3A169FDC52A263B0 -:1000A000BC776ADDDBC7514E1BB99C2E7360BF7BEA -:1000B0006769382EBD3716B4C17A65EF2C27E6275D -:1000C00074CD7AE1ADBBC1AE96297CBFD9468BFC1D -:1000D00056525C9D0EF57B55C42B5BA8FF920EDF3C -:1000E0007BED0CBFF03C90CD7C4C4F1F64F8E64399 -:1000F000816F381F5709F96F14F1502B8EA2E6C497 -:10010000B24E43F8FAC312562DB5534C1F3E6C64E1 -:10011000F1CC2DA2FF870EEC043D6CE072D475612A -:100120008317F5F5D0018CA7B5CC5A8BF1A3AEDCC3 -:10013000B33ADC6FF6BEA7C3BD8C33C4386F297BDE -:100140001671482F1FE7CD1077A7F2BFC4CBF0552B -:1001500074CAB5769F11CF6396F1DDCA681AF67F2F -:10016000D5451BFA9D2BF9F747A6FC4987EFB64406 -:10017000A91E53FBDEA0F5CF00DC9221E1C50F9F45 -:100180003B900FFADD33FB8F58EE8AB2B75B80EEFF -:10019000696507308E9F77E8407736AD7F7931F11A -:1001A0009BBED1EDD7F2F9694B0EDB07B1C51F0934 -:1001B000C33EB00F8608CE4F0B9F3B56ADF892ADB5 -:1001C000B79804708858AFD1BC7CBD83AF3B908B8F -:1001D0009794C4F16AD0424EB0BF2D65AFBA81DEAC -:1001E000C283EA5A90EB9AE7AEFF22C81FB9D1E169 -:1001F000B992F6E703CFAFDD5719ECFD1DACBE0594 -:1002000021CA8F869203F91B668DB62B237A53F28F -:1002100097AD214AC7E9A52FE4035E7B95DA5B1F02 -:10022000B4C7ED95EC272D94E6D3C090B4CE24F559 -:10023000D7A5ADB8D1310FC6F347DE820479A2FA53 -:10024000BF0EE8DFFCA8D303FA9275E8155D05BB85 -:100250004671FB920479DECCE5A5C16076AF6516E8 -:10026000896C5740CEDE6BAC007D7B5165FB500E38 -:10027000BDCDF23EA579A197CF1742AE7B73DF715A -:1002800083DC7D7890EB47D8A624C6918CB2D8CD7C -:10029000301E823F1D929D0990E4F3C22907C3A935 -:1002A000951A7B6F50BB0DEBD4F27B13FC28C04139 -:1002B000DC9F12EFD73B18DE15D7CBC82BF8E177C0 -:1002C000A8BE77ED3AEABD1DED9381787DF3A103D9 -:1002D000C5B00633E5E0811A9EF78DFE98CAFB395A -:1002E00095F8D03E2D379CB87E20CBB7BD6C5F14FF -:1002F00060B3989FC111D7A6C4ED869A187F48E2D3 -:100300007F91B0F9DACC843C2C3AAF13B01FD55EA4 -:10031000167795E524ABECC04E361F50294C58C7D4 -:1003200095E5B6C10879617D9AEACDFB6C3D93CE27 -:10033000531097501BFD389E5C3E6DF41FCC7B190B -:100340007EAB7CDA8B750B4E91E978C4C1D7C5388A -:10035000EE17F37296B71FE95B6EB4E543FB53BD2E -:10036000FDE86751BB9E0F572167C24E8FC8DFACB7 -:100370001BEAC14E815CC392F7E9B2EBD3C1DE3513 -:1003800078193E21521CBDD73BB69FD12DC9E369D8 -:100390000FF3AB1ACA48BA2713F49DC59B7A1FCE38 -:1003A000DE9791108FDB630FFDAB6372FCDE5DF2B5 -:1003B000F97A8F1BEC0BCBC72AA766CB5E148F6331 -:1003C0008A78A958BF13F1D15171CC922ECCD7B2F3 -:1003D0008B3C0ABE9E372A8F6782F9678EED6D9A35 -:1003E0009FAF93200E6BE4F1B7A1B9E3C441B70905 -:1003F0005C76DC31797C5CF628F72BDF00E341AFDB -:10040000B7383C783520BF8492DA9B961CAF1DE04C -:10041000F8E572F4F3840ADFB176DE7458FD4AF130 -:100420003C8E83991E4C2D3BD09D88832B5B296F7E -:10043000E838E9AD6406C94C2D77CB47ECDEB3163E -:10044000F91AC1C5E3E061215F83AAF967C7BCD48B -:10045000E51A381DA9DEB7CC723441FE142D47A62B -:1004600066B2EBD5F4DA3DFB40BE8D3E3F09B82BBA -:10047000818EDEC70E613F5ED6D9FE97DE0B1B0A6A -:10048000611EEFD24CE29C3771F991F5C939CFF476 -:100490006DA3FAD799EFC4FD7E9D5E86375E81928B -:1004A00009F2B45E0F799C93718A304936377242F3 -:1004B000CEC168D64C6CFFD66D19FDF70413ECFA6B -:1004C0002E78958BE70660BF1ED4FB31BFE6365A07 -:1004D000BB83B673CC50A7ACA3F7454E66F78F85A8 -:1004E000ED16BE886B9193C9DD7A3D58047492B6BF -:1004F00066D4B3B58A1A04FD27FE89C5E576B4270C -:10050000CF132D8DD73F07EB3F48EB07DCE0E771BA -:1005100077E2999234CECEFB1D25A40EF4E57B59EB -:10052000563F739693E9D99C78FD1589F5CF7132C2 -:10053000F9A7CF17E0F3A7D9F35CFEBCAA88E5A919 -:10054000093E8A7A6BE3F5D5E27787D877939D7C6D -:10055000BD80D32DF0BD9CCF74431A1B8F2AA17789 -:100560009A8278BB9CE26FC4F7DABE6318BF73F25D -:10057000FD91690E7CDF916B477CDFF10941FCD96D -:10058000E962F1C8AE0B676FFD2ABDD78689251FCA -:10059000DCC165481B7A0AE36FE5F97C3F1BD7573E -:1005A000B16FEB486CBF655D55ECF3E974F23C0C40 -:1005B0005EDF025E1F9170BBE897C039ED7C9F4EF5 -:1005C000B9E8DF407407DA958128F6ABD2C3D68349 -:1005D000BBB2BE81FEF503179ABD8971C1AEE9C7F2 -:1005E000D9BEFD7C4A77499C2E8DE3B1F261DBA632 -:1005F00003C00F4DC18CEDAAE88B1905B4FF8B4EDB -:10060000A8FE34E8BFE4672CC9E779D41CE7A6C28A -:10061000F5BF54623F80FA6D19178B80FE2353FE9D -:1006200055053C5A1E7D43059C5EA9B1BCDD851273 -:10063000FE6887F33A809EBFDA2236DAAF9EF3EF88 -:10064000A9307F5C311CC17E4F1BEEC3BC89BC014D -:1006500016DF5D30534985EB7764421E868FED735C -:100660002DF7EFAEC9867A87F8BEE5D8F94940D7AD -:10067000685C6FC529015F15F67B04E7E7B3B8D264 -:10068000E5E2E94AEED708BF408C3FE503EEE36AB6 -:100690001FBEDB09F36315E76B61BE8DF907D30B52 -:1006A000D7A07FF089EE817CDF073C5F77A27F4097 -:1006B000DF837F5009FE4126C4E5FAF236B846F7DB -:1006C00047C853E1D0C75B43B4FC11FBEB79806BA7 -:1006D0008F5E782A0FECB2C80B17B85E9477695515 -:1006E000CF83BD16790802E73B04CE8F3513D8CFF0 -:1006F0005F396CB3E07C0797AB4A83E955FB5F0930 -:10070000AE7375BDFF5E6F01FDBEF34516879E1A81 -:10071000EB5713717E39E777E7277D78FE8890FFE6 -:10072000CEF7D939221DF97C7F0AC7F98B092BBF77 -:100730001870BEFBF271FEEC3466774C8EE317F353 -:100740007C54F1BE9FDB7119DFCBEF2F17DF138EC7 -:10075000DFE3B8D82AB75DBB0A713DA5DCE364FBD3 -:10076000CD0662CFDE45AF5362A127F600BF2FA6AC -:10077000FBE13307F7BFC6CDE794F0FE5412D79BD9 -:10078000287D9495DF8F7A5249F504F6938FD2072E -:1007900019FFE7C78E41F90584E955F57088AD8FDB -:1007A0008D83F72B8DFE3CC4FBC38BDF677EC3D8E4 -:1007B00078DF94F297EA663AC6F64FD3AC786C814C -:1007C00088770C37B378E47033C623170C717B79C4 -:1007D00081D94B319E0F70B913F65CE867E785B39A -:1007E0006A28C16E8EC8F730DB872BBEEFCC6778E6 -:1007F000FF275A1FEA73E7D0DCF4C438958CF73B27 -:1008000001EF97401C89E2FD39A0BF04ED5E27E0AF -:10081000FD04BDA578FF9AB404FCE61E5A5DEF8185 -:10082000F5E009E613083F7631F8B1D909F152A78E -:10083000D58F4D25DF67F9FC1DE7671F9B7F86FB82 -:100840008E25F253E3B8D60178724E7CFF7A672A80 -:10085000BE7E62DDC72CF2B53B8727E637515C5B75 -:100860009F363975B94A4E47AAF70F5CD011D702A7 -:100870001E9F3A875DAFA6D7EE8FFBF212712D3126 -:10088000181EEB7CEC37B83FB8338BE2D992443E6C -:100890006F1B077FB0FB055E3B5F87B1E20922CD8E -:1008A000FFED2E260747291EC1F848DAAF908F1DAD -:1008B0009F9CC5F6657C22F0888C4388843F04BDEC -:1008C000EDF98CEF476267BEEB877D7327C43E531B -:1008D0002B2E91F9353E1EE9437B2ECB7987CBC475 -:1008E000BCAB383ED1116F3C60677843E0138A3B64 -:1008F0008EAD05DC3140481A89D32F708AC01D6245 -:100900007E6C1FE6E72D79F8BC20E19411FBFF29EE -:10091000718AA847C629723D9D3CAFA39DE2966DA2 -:1009200088638EE33C3B51FC22E395F17049E54C32 -:10093000864BDAFDEC3C268167645C52E7EBC23CF7 -:1009400040815F268A5304CE91F18A4C5727E09765 -:1009500092387E91F18A2C4785F9642DC4F7058E73 -:1009600049A59F50EE0E771CDFA42A47ED33E29E87 -:1009700094F50CC52E17F7FC1AEC4A6ADCC3C6B90D -:10098000F222C13CA05478E4017F3F3B8F489A3764 -:100990008EE49F7913F7690EE83E157111B5934601 -:1009A0006A3C24F46EA4BF60074AE2F3524ABE0CCC -:1009B00070FDC81F7BFD65A27849CC17B3D3D87CE6 -:1009C000906A1D323D9DE1AA070B997F2CBF8FE7EE -:1009D00095587113C99985F2FD55BE2F39158E2290 -:1009E00024E66671A930B683F9E480C34037E7F3A3 -:1009F000BC024A6A70269909718D20BC8775AC7952 -:100A00004A244C495B01CFE9B856D5B075A033B341 -:100A1000D83913A7AB1C38AEA73E6479875D2E1674 -:100A2000573D7D5D9A7F3F25E143A897CEB767D2BA -:100A3000FA4A615CA78B7E66B37E2ECB886EC27548 -:100A4000F0EBAFB5850B46DB8707D3391DD906AE72 -:100A5000A735F0F814AC07E6CD1DBD1FA035BD00CD -:100A6000FB0DF9EF79B4DC4E5BDF770BE9A3341BA8 -:100A70005B3F95F9FADB7445E4EB841D097C689CC7 -:100A8000E934D3A83CA67D8EE50374D638709D2941 -:100A90000D96CC69BD0F1517BA92C987E897FCFC73 -:100AA00061DEEF33D363787EC6CB3C8F77B3A68409 -:100AB00081DF6880617E9A346DDF43B4E8D274765A -:100AC0006ECCCBCFBD8271A197B2381F4C05F31508 -:100AD0004EFB983E853D4604F655D2EFEDABC7D0B0 -:100AE000E7BEAA25C51C8F1105D6C9E08FC2D1FC6F -:100AF0005E55A762BF577976DD05F3C699BA5733BD -:100B0000E0DCC7E54336027AB7CA537E073CEF7292 -:100B10003139063E03FE5F55F3F9AFC0F3C646EB2D -:100B2000781C4C2F44FE56686C3C60FCF2E68E6EDE -:100B3000977848489F92C0FFC00BDF5412D62144DB -:100B40007E8A3345BE5EAA7E2B8976578DC719A74C -:100B500096EDDB0DFB5B82A5ECFCCB061F09C37A8F -:100B60006E839F440BB87C61DE4CF74CB6AF87EBCD -:100B70005756D9BED642884B0E696C9D599A5F2A4A -:100B8000E858E567439C9C8DCFE9792AE2910AC831 -:100B90006BC4F32B197E6F30D722FE6F7CB87B5766 -:100BA00021BC57F36BAB7C6C1DD492477588C5DDB7 -:100BB000564872EE92E2FA157E290F90E7EF75160D -:100BC0003FE101F979309BCBCF5C05F5E815C5F71E -:100BD0007061C23C7363BAF0CB88CF9E201F23F2B2 -:100BE000C0C757E67B2A7ECA7C92E542E6F7699742 -:100BF000C4AF14FC4FC5EF8AB2AABF2B7F3FB03BF6 -:100C0000EC20B75DF63FE6B37815B5C109F644E6CA -:100C1000DB0786CF0576E2CC108B87BD34DDF74548 -:100C20003C8F8AEA319E9FC9F5213E0E541FDC8914 -:100C3000FAFCFA0CD0672A6776A8A7D154CC34D036 -:100C4000BF830FDC85FD063D75C7F548E6FF28FD2F -:100C5000A3FFD304BD45A3F548CE0FFB5BF5EF4ED4 -:100C6000B0E7946F73D37D7815F6B49178BE98B8D9 -:100C70000F55AC937715B40461FF78C3808DC07CA9 -:100C8000D33EF48CB60EF6A5D62938AD19A40FE9DB -:100C9000355A59FEC3558FDF4B203FFDE1E9C40FA4 -:100CA000F6CA6865F910F43DE64308BC2ECE4DA4A3 -:100CB000EF4DE687B376EB79BB2EBF359F67E5E056 -:100CC000225C4FE82EE6F148EE37883C5622ED6371 -:100CD000698127B9F1FD1EAD1722E83FB4A7D8D727 -:100CE00022AEB21F205F7B8EFEEC2BE00754CED4E9 -:100CF0003D00292A87A24EA8EFBB2547EB105FD500 -:100D0000291E5867EBF9B86D07A172B4B2E49DA42F -:100D1000B8E4F0073FF4433F0EDB77FBB3C13E6C12 -:100D200067F356DAD525D3D78D817B427555750586 -:100D3000B353E78DDC9AC1E7F7AE3BF73F08EBD939 -:100D4000833AC643EB393E6ED07637ADA3E3D9BDC7 -:100D500054F16FA3CFBBAFD9D37C14E2C8EFEBC083 -:100D600071D27BE1A97CF0234E3EE66C82FA7B3E99 -:100D70007EEAC7983732A8CF87FE8ED07FA5C1DE26 -:100D80007FF8FC09B0332B8B5796423B691AD90D7B -:100D9000F274C550DB9B70AE41C3803E0FECCFCAEE -:100DA000BA7DCE7F003ED53DEBBC925EA70DF96AC1 -:100DB000613C33D243733228BD792505F7E7403BC8 -:100DC0007EE23791AF7D04F8BA528A3F5672B96914 -:100DD0005F5AE04A8C639C192A74617E421DCF4F92 -:100DE00058AA06C10F3EE3B9D28571C73A9697203B -:100DF000F36B25C7E92BEB0AA627C3E385757F4173 -:100E00001CDE7E8DA32919BF6FE2FC4EFBD386FD4D -:100E1000D0DFB41F393D00AFD352E45B6667F07C8E -:100E200052EFC4E22002CF50BE3AED0971108AF7AA -:100E30006FCE4888AF5C6EFBF519CC0E0CAAA12FC3 -:100E400001FF2B781C64BCF843F938EB6E548E908C -:100E50004F2B797C62A5884FD4174CB7C42788E9FB -:100E6000053B7B06D6DDC0CFD6566C013A7A3F6093 -:100E7000EB6EA9E477E5CCA76E3D9A60EF7AED269C -:100E8000EE97ECBE86F949FF55F23B226775CFB667 -:100E900096D2E70F95AC9C0CF62F418E5B613C2EF1 -:100EA000578E65FEB52F2D7211232ECF428E47CB64 -:100EB000A582FEA890EF54E301E5C01F5D398E3F87 -:100EC0007A66E9D549E53F5ECFB931F5A086CBD545 -:100ED0004D5CAE2A89E9C173A9F2DE44BFF557DC47 -:100EE0001E8FC889AB0FE341E1279DB83EDE7941F3 -:100EF000C7F3CD3B9FD8F8139837BA871679DEC36E -:100F000079BCCAB38AD2750DF80F25383EDD5A4236 -:100F1000BCFB8D0CB11E6ECDDFFD37CF1FB2ABD841 -:100F20003C6B54517ECFE1F3C4E70A9E4887F97CBD -:100F30000ECFA39FDDA1279D973984202539AFD8F7 -:100F400000FA971CB4963346F691B7D960DDEF737B -:100F50004F4BEFF9FE6739DFB13723F9BE6731DF59 -:100F60003A2F8C1D47FC39F7AB9FE6F9BCFFC6CF83 -:100F7000ED6BE3E7DC3E03FB56E9F520EC5BA5CF28 -:100F80009F877DABF4FE10DFB74AF227762EBB3881 -:100F90008749E77C68CD8D58D607C53EEDF652955A -:100FA0009D53E1D5F11C548A9B6C987FC2F1A22D10 -:100FB00023E0D4E9B8EAFF4130FFE4EBEFF7A13CCE -:100FC000ECE2F3AC8C633A243911573DCE470DE285 -:100FD000589DD3434DC1123E602037F3A6EE7B28C7 -:100FE000014FFF2F2E172DDC6F0B5F209127957877 -:100FF000F9972E90A71E421C45C22AE00EF88B8A54 -:1010000070FD00411C575FFA00FA5F80030197E111 -:10101000F96085101F7D1EF15CFDD0FC3BF8FAC124 -:10102000281C37C23715F9C4F079E92B1827A91FF6 -:10103000482E6FF1BCA5A6EE9909FB0C1A87C43A9D -:1010400005A5644A7C5FB92EC9955C4F56A982E319 -:10105000B2AC98EDFB12EB1C623C7734F7617E4733 -:101060006FA9C307F1051927CA385F2F65FBC2B402 -:101070001BD9FED4FA0B2CCF1005664AFCFC349D1C -:10108000E7EDB67B427E38AFA4C12FE1DE189BF7B7 -:101090002A8BAD785EC6FBFA802EE1FD309B0FB740 -:1010A000B3F13CFD21413FEAC9BD2C3E70D8EB6352 -:1010B000F24722E8F72CF4DAAE7BC807EB526CBF9C -:1010C00065F9103B6FB37CC087FBA7170E92E855FC -:1010D000B3213E4A5AF13C20897F0B095B7758E8DF -:1010E000F5754F86F8A34676C23930539C6B4DD0C8 -:1010F00003DDDB8CFB6BAA9D0A9E934DF8FA98E00A -:10110000AF9E7E6A07A8C0429ECF277E1762AAF3D1 -:1011100000CA813E4E5C56AC7FE95CEEC47A56153F -:10112000AFBF6A90E5B1C97290E53CF7269CA3BCBD -:1011300068C8C0753179DCE5715D64C4DE7D04E2A8 -:10114000F617D2FDDB619C9D6C9CC538EA6A870A64 -:10115000FB3588C6C64BAC7355CABF0F21ED8393D0 -:10116000E912E71F7CC590F685711CBF8853D79A9A -:1011700076C0B2BE22AF031CE6F9083FD1D839A22F -:101180008707C75EAF3ACCD7AB886782E70EF2F32A -:10119000022ACA483AE09C8A41C2E4EB615B2471AE -:1011A0007D4BDE27EE1E5C5D8FE7AB793C789E427F -:1011B00005A1D7523CE715F31B4D72C0B21E6772F2 -:1011C0007BAFF3B898AEB07E093EC9F4DD3664F566 -:1011D00087BE18B6EE6FB8F55EEB7E8C5B9AF32C8B -:1011E000EF976C2CB2BCAFF55D6BB9FFBCD77ACE74 -:1011F000CF7F0B59CFF959D5542D9D63673DE7E754 -:10120000A63AEB393F0DE6AD92FE9AD67507A58F4B -:10121000AF5FBC5534569C37617FE198E7FEA01F55 -:1012200098645F8BBC3FF1AC21E28D563DE80E57D0 -:10123000B17371067C7BABE8FD51E2D7D0C1E5E725 -:10124000FF887D7BB55EB69E337ABF1DA34BD84128 -:1012500079DF8F38B7AF62B00FE5A0523E9FCF9BCA -:10126000FC7CBE570C8E17C4391729CEB318357FB6 -:101270004FB47F7C1D6FDCFEF176CB49DF3138E760 -:101280002355FF26DAAF91BC2D383790F2A30F1EFD -:10129000E5B2F706D5B79D59C5789E85DDB92866B4 -:1012A0004C8EC73B8979FDC4F66DF3383E31578DBE -:1012B000539EE9BDDDE9637261327CB45331237022 -:1012C000CE5DFC3C0B827640E7F3A97CAE45DA4E5E -:1012D0006296501685179128E28D42676407AC83A9 -:1012E000E6B27DA32DD7D870FE693967EE86FC93F0 -:1012F000D66B34DCB758AB1A585ECF67F35300D6C1 -:10130000A0203FE2A4D964398FC3BBDD037AA2FFDA -:1013100098BD4FD59F8E5CB63E2C3F2F72313CD48A -:10132000A505F35C281FA697AD4744F0DC32916F0A -:101330009B2ACF9602470FDA6D22F0011BBFFB619B -:101340003D2589FEFA5D4CCF02254AC40E79A337AC -:1013500093887D0CBFB2C36B4B1ACFC875F1B8E848 -:10136000C54B781E9D2ECEC7CB63E7E37549E74E8C -:10137000E6F27E1E7039991C143CC5F6A34AE79428 -:10138000D7FB3690443C5BCEE7193DF60EC6994E2E -:101390000F8C8DC3C5FAD32EBE4FB9FA822D988C0F -:1013A000FEDFBB3496176CD893F66F3DA7B7638604 -:1013B000FFB5209583967FB6E1F9D2016FCB34DC7F -:1013C000C7EDFA07C2E25D8CFE7AAEA7016F640733 -:1013D000A1E31788BEF128FC3E875EE6C0F5E7D39F -:1013E000D7507C426568578CE2C58278FF5C7CBE32 -:1013F00009EC3D5A5754CACECD8778CF9201964713 -:10140000BEBC6C1F3F77A51FF725CABF0F525E17E2 -:1014100032615E5EDE18DD81F8C7EFABC2DF0B2103 -:10142000FE6D6CBD50DE3F6920EEEA186272DFF19E -:10143000537F17FEFE8657E046B3B1764AFC7CAF79 -:10144000CA734777C2128C7CBE977C8E90F0CB74A7 -:1014500009570A7FAC81448E69CAE838732A7FEC49 -:101460009F5C1C8F5C43FD313AFEB73958FE6CE03F -:101470003EA50C9CC6B4FB945CB05F2D7C9C5EAB1F -:101480000C615E404B8AFD747FE472FF5A6514F76D -:1014900029751484BCFE31CAE7BA542CAF5F64E7E7 -:1014A00078E84E96D73272E5795C42AE0BDD0E7667 -:1014B000AEA19BF9DB0B2F3D9D37D6FC591E0811C1 -:1014C000E80FB52F49F365F689F6A3EC3C0ABDF5A4 -:1014D0009D9A64FA2CF470BD1EFC890BF61D2ACD72 -:1014E0009134B403133F7F728EFAE9EDCD9F0CF374 -:1014F0001968FFA4FD5F7CA01F3B42D6DF7512D7A1 -:101500009346C889FCF71ECD007FF377E9A1C3603D -:10151000F720DE0DFB053B62CF38D19E4A7C97EB6E -:10152000B9CDCDC653F7B1F7E437A66F65429CE459 -:1015300006371B17BBD3EC81FA67DACDE340DF83B4 -:101540008B92AF43BAB44527A1DC7546F01494EBF7 -:1015500088EDC7F8F12769E64BF0BC54334FC375EB -:101560008FDD7C99D9E91ACF7BC5F17D0CA9C6190D -:10157000162EDE2B4EE4D7A7E3B3DD19EC87F6E990 -:101580003C18322E739CDDF45A07730BFDBEBF323C -:10159000F97A7B0B9727AA67989F25F6B904BCC4F4 -:1015A0004C367F89F274FCCF035D0FEAE120ECD763 -:1015B0003A3DCD46F627D839712E414B8CF985E757 -:1015C000EF51F633BF90E0FD4FEF2CD80FEBBB3758 -:1015D000CFE07ACCF759DC7E8F75DFB368F7CA4C61 -:1015E0006542FAF9CD4C260777673AF0BA2D93D1C8 -:1015F0003B61FDCC61F5083DD535765DEE61ED9F33 -:10160000E1F57FCCEFA91EE6B8991EF6BB2E6F7CE4 -:101610007EB8AAE8D3CB87D007DD6FCD33FD16D7D0 -:101620000761AF289DD7B8518E9A43E99747E79451 -:10163000F2CF408EC57E033543B1C4C303DC7EDEEA -:10164000E416B8C8AC7433FD5D00D731F477919BD4 -:10165000E96F8DDBAABFB56EA6BF8BDD4C7F97B857 -:101660003F85FE9E05FD81FC3C1EC727A7AC768703 -:10167000E2E255D07EBDA6F07DDBE40F4A82FF5149 -:101680003F1022269B2C9F48C40D14BF9AB85FE3DD -:10169000356B7D3D7CDEA276EC4B506F0FD7DF1DA6 -:1016A000BF65FC033E3E93442F051F55C75A2FE4E8 -:1016B000C5A79AE7026EB6BFBDCAC1F6539013B470 -:1016C000FD5996FE6C067E8DF4274C3DBBE4FD096A -:1016D00027ED4F9FB5BE84FEDC0BF58AFE2CBC7453 -:1016E0006A4C7D0C087DF4445598B7035AF279A1F1 -:1016F000DDCDE6CDDF67983BA17E59BEC475179757 -:10170000AF54FB5EBAB445BB80DFE51AB383C4882F -:10171000F6AB09FD2B2F5E2BFA1DB225C6D906921A -:10172000DBC947DD237AF728CADF5EB64F87CAF5E3 -:1017300063D0CE6D933CAB715FD747CC6E9EFDEB13 -:101740007D76F89D94A69C3DF7C3F5A49BE5BDACC2 -:101750003D57E88661E8AF64FB1D5B72D9F9682DDF -:101760008AF59CB4937C7ECCCD147EF5C4CF11C792 -:10177000B392FF4EF31BE54F07B74BFD69459767E3 -:1017800097E67D06EDDF3C83203E6ED9A7E33E035E -:10179000A137B7C1D8B2730D4CC8A3F812BDB7D1E9 -:1017A000FB7E70BA291DA17C42BC73B15C58C77323 -:1017B0000FCCD7983D327F0DE34BEDD0596E875E4D -:1017C000877B6A877EF369ECD0336EA637AD54868B -:1017D000FA400EB508DF8FC3FD11DED7F2E2639643 -:1017E000B89DF0A73A06F61B61C81B2C66FB4F5349 -:1017F000B52BF205C7FB3D82AA7F5EE70427600791 -:10180000C575104715BF5FD701ED1BD09EAD11F810 -:101810007A92A8B80E2FD7D7329DCFFB2E2ECFB9F4 -:101820001BD0BF927FBFAEDA1BD93597D613387164 -:101830003B3B2FE1E2ED64F52CC0272102E76AEA89 -:10184000F40AFBDA05DDAECCAB2CF1409D28DAE2E0 -:1018500092B81DA98E91E8C252C437B87F0BEAF145 -:10186000F17A42B360BECFC273564F1627CF4FD81E -:10187000A58672322727F041FADD0B3AFE93E13D4F -:101880001DFF2999F370FCA766B279C80BF7BFE179 -:10189000E3B84B0DE6C1F3500E5B82A6E5F379F990 -:1018A000E9999F819CEC20EC776F417E13D7ABF7D1 -:1018B00070FBF0B3C9A11268AFE6A72BBAA7D14F4E -:1018C00036B5ADC5738A175E11FBE865CA1F92A7CE -:1018D000E37A60CBC3D679E4071CFFFC3C53ACF73A -:1018E0005D1E8EA0F6EFC64CA48FD9BFB097FDBE8B -:1018F000E7DADCC2EF31F8481DCC29F1736A6B3CA2 -:101900002B6AE0F70ABFFC74C15C38D74AE7F67966 -:10191000B1B74B5F07E30ABFFF94C49E378ED8412F -:101920006ABD2DF354F2FCD42F65B2F993EAF1B2FB -:101930004CA6BFCB81CE7D93CD9B32E7FDFDECA3C2 -:10194000B043218DD91BEA3785C16F5A3DDCDC03DA -:10195000D35413D9530BEB1B542E3700BD5F701EAD -:10196000E8613F9D129E06ED5279BC83CBE3462E83 -:101970005F777279FCF2A7E9D76A687C5E6AFC2916 -:1019800070B8C0DFD4CE7F2B93E1649FFBB399374F -:1019900076F0FA42EECB9C376EF90CDAA778E3FBCF -:1019A000C0C7924C3226BE7D94CBD5639923F8F6FE -:1019B00031F86EA1D37C3C33116F949CF803E4C9D9 -:1019C000C5F14697CAF1869618CF0E50FCC5F3EACA -:1019D000D6DBE6C7F5448F25C7216599237ECACF9C -:1019E000D0AEEC6238A46C846EFF4004F4701AD759 -:1019F000F737983D5EABF7AF07FB7C3E8B7D1FCB87 -:101A000062E3F81CAFEF6DC59534BEF942E608EE0F -:101A10007901DBBB8FB5A7665CC77EB743D815BB22 -:101A200082ED88F87059B6B59D79D9360B4E95DBA5 -:101A3000E98EF7AB1BE5F81EB1EFD7EC81760371A9 -:101A4000BE4613F90AF6C5363F819F1CD7A5C27161 -:101A500009FC7B05FBD3CADA19E15F28B99DC5DF14 -:101A60003564B8F475A02F957CBCC5E5E37771F9B2 -:101A7000F81D978FDFC37737CF60E370DB24EB7EF1 -:101A8000F277F977F7723E89F192E9FF7A362B37D0 -:101A9000C20FDF892712716DA0386B7513C42D5BDF -:101AA00055BFCD375ADEE87F336D09F6581F88E001 -:101AB0003C510FF296C4EEFE25CEAFBFE0B8D43055 -:101AC0007E75A5F0E3EECC66FDBE257F5FCD646834 -:101AD0003F7CC9F27B2D5FD8D8A526FA09FF1BBE33 -:101AE0005F0B5400800000001F8B08000000000006 -:101AF000000BE57D0B6014D5D5F09D9DD9D94DB275 -:101B00009B4CDE1B48C224040D1A708110A304995B -:101B1000BC780688BC4445591E86F04A22624BAB0D -:101B2000FE2C2684A76DB43EB045BB2054AC682380 -:101B3000A64A31D00D08E2B3A1ADA2B58F2008A806 -:101B400008216A5DAB7EFCF79C7B273BB3D905D4AB -:101B5000B65FFBFFF1EB77B977EEDCC7799F73CF08 -:101B60009DBDFEC3E373350721E7E06F44B0AC4A87 -:101B7000B010924C48FD0CF741359F10AFCBE2DE20 -:101B80004A7AF65B1E2F63BF51D93E298EF67BE35E -:101B90002C5136D37E374C11345F1E21233B89E60E -:101BA000A3E37F192F103294104591B0FF1509ACB3 -:101BB0003E4AEE985B1966FEBEFCF9689568CD74E6 -:101BC0009CD10AD17684E977295FE7A8E8F0E38C15 -:101BD0008271E8F331848D13FA7C1C7F3EAA24FCC9 -:101BE000FB97C1F8741DD35DCF94271058CF26AB57 -:101BF00087F6CBB16AB90A6D5F53D2B128DC7B4E50 -:101C0000A9240F9E4751D059071372337DD742073D -:101C100098494B9996EB45CF6085CEEBA1E070D10A -:101C2000E7B45BAFCA01840C726843A0FD8B282D1A -:101C30001FCA7C491B0AE3DC6BD50AA04E889F9023 -:101C400002422610F637C1EEF08BB1F41F85D65351 -:101C50001D76D6762E1BFEFF0CE5F8E58408C42F12 -:101C60009CBB1CEA3E11C6BF5A3DF8B640FB5FADB7 -:101C7000BF77520A792F5D391EC3EB22AE0BE1B359 -:101C8000CBFA90EAB0F4DCA75EEE7278EC0087BF86 -:101C9000447BC6C33AEB5D9B1D2A85F72B9E66BB32 -:101CA0009BB61F8E2308C7BFC66813613FF5BB48AC -:101CB00075336D176384BA6603FCA6280C9F531511 -:101CC00086FF36499B0AFD47D8B56930EE944C8AA9 -:101CD000273AEECCC48EA546B8CFE474309DE3EB32 -:101CE0006699F50B5DE754DEAF4812BC31B026C7EC -:101CF000C163620A8507E9FECBB1D0FA58F8974A6A -:101D0000FB9D54A64D4FA2385B2DBA2DB42EE70A89 -:101D100048CFA1E32EE2EB9D2B572E82F512B54E54 -:101D2000AD7452FA90C3D3C731DEBF3C025D66F199 -:101D30007596C1F330EFA771FE284B6A13097DBF7A -:101D400088F35B68BF490922E36337191D6E9C7AEB -:101D500085D13F5D773DD297C2D69D63AD5C09FBCF -:101D600098A11C2A8FA7CDC5F7244D2349000F0B3E -:101D7000B165219CEC84C249E270A2CB24505F6221 -:101D80006775297A1189A365A6CBB76E20C0AFC14C -:101D9000EA5669FDBD93EF8984D2D9D6FBBB0442D4 -:101DA000E5C5AE4E4212B3601C1946843FCB39A143 -:101DB000E778F4992AE9F351D05C739268364ABF08 -:101DC000D714764E22B1A6F7C9393A9EA3B3DD2BBC -:101DD00000FEECC41B730592F11F735270541C2F4C -:101DE00095CE0BFB913F253ED88FE6F2549081842F -:101DF000C47776FCAC16DB1DEE51B82FE2007E0BEB -:101E0000EE7309F29FBE2ED9D1F1D88F69FFD6CFDC -:101E1000A2DD77C3BE3B477EC0D643BC4EE06BB16C -:101E2000C2EDC983F76CB83E0BFD0FF86C7880AE3D -:101E30003797AF1726C937AC9FF4DCCF7AB1F27968 -:101E4000C0C74C3BD16207A37CD809F5BE56DA81E6 -:101E5000C2B151117C5EDAAFF1FEB9ABB3405EAFF7 -:101E600097DCFD08D039D929503A1F46E75D46E591 -:101E70008E5C481C0AADCB2EB6FFC67B9236C508D9 -:101E8000F05C2233E8F3619DFE2F040A8758575512 -:101E90008542F721F3F7050A38785F501532633031 -:101EA000D06DBB48503EB8101E3AFF689712E1381B -:101EB0005D373C02FA2A9388D74EFB0B2E36EE355F -:101EC000A453247D010F5411D0B284B8B16C143DD9 -:101ED0006F02FDD9658A57BA7EBBC5EE5B2100FE55 -:101EE0002A5F1B8D702F538EE706E5592439049025 -:101EF0003BAEC355FCEE72AF7C6978BEFA30C83792 -:101F00001F32B94CF986CE33259BC99DFDCE8E1963 -:101F100046BE5FAA30B9B494F33D91189FCD95B5F4 -:101F2000B380C7487CBE8CBF9706CA07F89884E781 -:101F3000E39FC7B3F54CB9DBD7D88BC26F4282E0C1 -:101F4000063D5CBE7D96D45B0DF693B9BE3B97AC67 -:101F5000917894C3EE93BE24D03E32EAF7C677C898 -:101F600074187F16979F27F8B8EFC7B375C4703DF4 -:101F70007E44704E0F0717677CB71C74C2F8C4C349 -:101F8000E022C60CEAF4D379486F3E8F55C079DA67 -:101F9000B2997C8C4F30CF13CBE53895FBC9F12833 -:101FA000F77DE9D0EF152B5B5FE8BCE9C179D37110 -:101FB000DE456CDEB120E781FFD5832F829C2FE2C6 -:101FC000743AB6D343C0EE011EB61404E5BDACFAB4 -:101FD000C53ADA5E1441CEF70FCED31FE7A9637876 -:101FE000DC9EA25D06EBA476C1E550B6652B282FDA -:101FF000DFE865219B295FCE4ACBFE11884D7D9C91 -:102000004D7C9F6D598DAED9145F722771DB90CED8 -:10201000AB51EE1571F952BFCB43E0B9B7179599A3 -:1020200086F7E5CED976E2C0ADFCCF39BD3FF051A1 -:1020300067769C270C5EF472DD72268A88BA18DFF8 -:102040005BC2DF0BEDE778606F0C8CBF16FA5F4A5E -:10205000F996EB1BBA615CDF58CE3BF59D9B633A6A -:1020600068BF5DB9734CEBC1E7948F1A731F8B0186 -:102070007BA93583EA0190532F8B28271B9D0C8F5A -:102080008D6955C4638073A9CB2F1E8771BE9A4397 -:10209000A651FC15B93CE4126770DD45B9555E21C7 -:1020A00009DB9F8BA2E3CC89BF04E946CEF3909174 -:1020B0000E804B33A9A2FB9715BFE8A6656927F1EF -:1020C0008FC887FE54CE0B6C3CD5691C8734C3384F -:1020D000B29BD203BCD7E9C7F5EC3A797E383AF225 -:1020E0002C26F9ADF325B5EB6A802ECA946BCBE2B2 -:1020F000E9F80BB6670D16E9F8235D6DF2EC3C9438 -:10210000DBB5401F9B92B53AA49FFF257B6E3AF149 -:102110005901EFA332991E985023F83653F83486AC -:10212000D8098D9C4E2F0DDA37AB61FDA450B71343 -:10213000B435F1E7B783EF893FBF1DFC93F8F07624 -:10214000F0FDF1CC0E7E209ED9C10F4249EDE08713 -:10215000E2BF831D3C5C21BA1DEA43F8C7B37AFD98 -:102160009F983D1ABAFEF9F1CC0E5B4DF7DA0E746A -:1021700029F92446E78C4FAFE67C3AF624E597BC74 -:102180009EF4DF4AE9DF4BE9AF8BDA4D6256647AA1 -:10219000F25F245F163FC0F8BEDEB517F9EEB79CBC -:1021A0003F5BF9FCADB96205E0F315222AA2D073BA -:1021B000BCC60C8F0BE47A28FF695F99E9B9D4E5B6 -:1021C0005B3F18F8E6E01C372C2B941F655A560D20 -:1021D00008AEFBF79C0FBBE51311A49117C1873024 -:1021E0008E6700D819F112F05F3D61F37A0F8AA86B -:1021F0002722F111A59B77E30DF31503B00DEBA793 -:1022000074F367C02FE5B3BF7C177AF93EA70FEAD6 -:10221000871C87F192787D5604FFE2E3F86EBBE0FD -:10222000639C7706D343CE7895BD479264D02F9AAE -:10223000989109F2858E7B16C6DD1377FE710341F6 -:10224000BD1340BA5DC6C67D1E8CECE49EE38E4A8B -:10225000A0F6479871EC5C8EDF10C15F50B85D430B -:10226000F2BAED136B02FAED6C7D4F246BB684E489 -:1022700020DF1471BBE525C1AC9753B93E57B83F79 -:102280002726B0FE646EF7B80A8CA3C353B7036663 -:1022900071F9A08F93C4F92F2E4161EBAA66EF1359 -:1022A0005E1FC9FD270A97DEB82E3B7B7E21BFE863 -:1022B0002E85C52D2671BBAA1336C8F41BC27574B2 -:1022C00024BF2B68F7F507B81037EB9FC6E143DB57 -:1022D000F3B0BD82ADE352450D1B3F88841F1DFE48 -:1022E00052025F4F2E1B9F78BBE17625EC53A797D8 -:1022F0004870DB13C7E056A0C3AD818F13220FD601 -:1023000049CD7625CC3E47727AD5EB31B966F910C6 -:10231000299E9215D413E3111FF96CDD91E22BFD78 -:10232000F87E2FE378A0EF4D41F839D87AEF52BA12 -:10233000DBAFC3F67436DECC60FB0D388F8BF58FC8 -:10234000E4F7CFE4EB9A9AD08DA759385E127B2F31 -:10235000349EA09737F2F54D0FAEAF1ADFCB61EF89 -:102360004941BC2FC4F6D1ACFDFAF44D65C92AE051 -:102370008D8E037AC2C5F4C10DD56DA2D1DEB93EF2 -:1023800042FC4DE2F35605D7FB7DDCA7C6F67F2263 -:10239000AEBBFD87386F119B3792FC3811C7C6BBA7 -:1023A0009DEFE31AF08BE918F101922B2581D714E8 -:1023B000ED1E45BBA406343FE88F924F6515E474CB -:1023C000B9E8F00A541E4BAA1DFDE4288968E0D73D -:1023D000B67DF63D57471ED6FDA0D7574515DBC144 -:1023E000EF5C9D25B9411F16DF2B31FFFA9405E5FF -:1023F000FD4871118EB357D1EDDC5B4D7EB4AAA8B8 -:102400001551B00EBB4854E6FF578CA7CF477079E3 -:10241000BDD79E6881F18665B078C108B50AFD75A3 -:10242000F215F3A335FA1F93DF1AEA6599BF27A5C2 -:10243000D711014BB3BF2D93F567C581A817D08E77 -:102440001AD669F6BF6575E409185F2686F7E8BCF9 -:10245000DB129C49684FE5907EE728FFD872056241 -:10246000BB02FC6CCF76C0CF18B54A29A1FBB1A541 -:102470007BEC208773ACFEDE104F684897DD5E6012 -:10248000C3FBCBEC59E06F3551FF1CE1A0255C3B51 -:102490002088275B9146800E294E90BFBA4B072BB0 -:1024A000854486C7B7136C580EE275FD7928DEB3F4 -:1024B00013A319FF13BBF7582EC80981C4513A5C06 -:1024C0004C3A32811EC534C6E735968E14A89F213A -:1024D0009D2949B4AC6F924687F37FD6F1B8D41AE0 -:1024E0004B787BE95EEB9857010E12C40DAEC0B875 -:1024F00080C7D637183FD0ED553D8E10C96E6D148C -:102500002BDF04BA1614FF17D0BFA7FDEB65FB4EF7 -:1025100067725A2FF5758C4F64FC6E4BB463BF3DE8 -:10252000779692D92AE2E908C7D3C12B012A5973B9 -:1025300015C0D3CB590FE6405CCA9E757F12F0E7F9 -:1025400068C2ECD372FA8E8B962B1D9E9309067B84 -:10255000634CCE2CB49B8A32EBD09E5A15C12FBD52 -:1025600085AF43E27432C8E1390BFBDA7AFF123BE4 -:10257000BC2F2995D150EE094CC292DABD9FC0F311 -:1025800055E9AC7E213CBCC4F939D2FA47815E8062 -:10259000784D7AF73E84C4647CEE950707F761585E -:1025A0009F3531CCFA3EE5FA485F9794C3E932D7BC -:1025B0004C77457CBFA989BABF78D174F7D6C5D00E -:1025C0005DE87EC7642D1DDD9F04D7AFEF57DF3F69 -:1025D000DD6F1FD86FB9C4F6BF55F168300485B3FD -:1025E0000AFBECB12F7B78BDEF48B47CD3FD3C985F -:1025F000D0F7E2F7F30DC69D96F80DE0B47FB8E68C -:102600000279D2904CE993E2A94160A5DEFF0B6EFE -:10261000A7FDFC9BE32BA5DF37D85FB14B7811F406 -:10262000E108CF9152D86E59D120503BC08F930111 -:102630000F2579F74AB369BDF1CE39283FF70FAFBF -:10264000C375AF729AD7AB9742228FE3676AC87F90 -:102650000D9CFFCA09F323F57E4F72F918CA1FA11A -:10266000E385F2F54A873617D62524323D1BF4FF61 -:10267000DA45A3FF57C2F5D770FB6DA6F8C770EE19 -:10268000FFADFA34DBE1A51BEDA27AED9FE2FF7D01 -:10269000419F809F945E6237FA7F0DF6526C5F9582 -:1026A000A18DBE2209F4B1E8BE9B20FCD01FF40A24 -:1026B000A2B2358C3FB82A43F68FA0CF6D0AF90538 -:1026C000ACAF94EA4B88BFD8148D5C32A0A75FB83A -:1026D000D75E4A206ED2A590E7C01FBBD07E1E48B1 -:1026E000BCC464474AE017F2F1D12F54EA4807C648 -:1026F0007B4A09D835D0AEA25DA5118F13F408F539 -:102700000B0DF2A9CB7E1BF27BE87C546E3D027C64 -:10271000DEA0303E0EF507BB389FEB7236941ECA22 -:102720005D8C6EA2E8D2AD4C6EFC2271684FBAF897 -:10273000E6F2696E19B800D79115FBC1559B1AE8EE -:1027400094C0E59993C8F8A9D2F14C033CD7C70FC0 -:10275000C50FDDB906F174B06758FC86DA6BD48E0C -:10276000B2527B6DAD109C7F0DA78348F888A4AF53 -:10277000F775CBB5D038D16DE6F317C54B920A5833 -:102780005C9F8481BFC8EDA4D5945FE0FC668DD5C5 -:10279000ED02BFA2BE5FD1DB1EA0BF7E32B377A425 -:1027A00026D7B561FC90B511E2DAEF2526203CA3CF -:1027B000732C26FB8C7A0626FB31D2BE095F9795D7 -:1027C000EF4B0078E61AE119B2EF3205F70D663DDE -:1027D0008C1B6B71133FE58BD84CE24681156BC1A6 -:1027E00038ACCEE70AE7735D1E3814F6DEB0A4BE3F -:1027F000EC7C4F74748A145FEB92A83D4DC7A9D747 -:10280000F6A25ED5DF8FE3FB770C67F14687D3AF87 -:102810002861E4DD8F2F80DF264D8A2FA3EBFBB1EB -:10282000C2EC6F69B8A5D287F12816AF5538ECC451 -:10283000E27C3BD8ED05E0780F85F5EC508C712BF0 -:1028400091AF27C649D7731E39B98AF3B75EB7A9C6 -:102850001D65B07E294B53E20DEB1F94A4EB9576DA -:10286000E4EF48E3DDC3E5BC2DDD4DAAE8BC768787 -:10287000DB0FE75A36ADAA00FC05BBEA26730CED68 -:1028800076AD6088CD80F7A67EF2F4707CB92089A1 -:10289000C97FA7A455C27B4E4522704EE6E4F6726E -:1028A000A47123ADE342F38D8A349F1ADEAE884DC6 -:1028B00062FC270DDF5109729A0C9048BF307A42B2 -:1028C000E0FD62E50E15F88AD2A327DC7867126571 -:1028D0000EEF7F117FE8767771CBC16CBADE7A8715 -:1028E000E416407E159E6C570D7281EAF509490683 -:1028F0007B59747850BE892A3B771F6D63FEF6FEC4 -:10290000E1E673B2299C5E5EE56524B97079928533 -:10291000DB4DFF9A7D7E53FC0D4A2226B834015CC4 -:1029200008F0D77D0DF561E42585CF926F039F6593 -:102930009CBE1EB9007C32FECDF0B9105F07F9CC09 -:102940004B8E86916FF54E396D8E89FFA91D12A1B0 -:102950005F95A13D121FEAF4310AF002FCD0A49960 -:10296000E2027292B79DF995B79BF59CB8C8CDE588 -:1029700033F9AA808539E12FDE41FC31B1C1F1E59F -:1029800032733CE1C9241E17882251009F2EF72480 -:1029900001F214A22C3306410834853409A02752D1 -:1029A000609C81D44FE6F23C540F266BCC4FEE4D29 -:1029B000EA04A657D2717D497C1DA17A308DFA3583 -:1029C000108F0154833FDD5B82182F3CD5F01C5CD7 -:1029D000F05AD05F76119F00E3A7930E2CFB402A9C -:1029E000021D3F8BB40B39147FF796570D02F9FD8A -:1029F00062C83E2E648FEAA56E7F2CFB37C1FB9D1B -:102A0000FF5E78AF2835C0BBEB3BC27B0A973BA18A -:102A1000F1BC31DDF1BCA617310EF715B33FDABEBC -:102A20009631BED790C5E279E562C506B0E7C7A882 -:102A30003201FD26E576AC833C27DDEE049704E207 -:102A40005C7ADCCFDE6F4EE560782E9D4438E1D9AC -:102A5000908AF2CC998CF286D91123F8FAC7A8553E -:102A6000F62CD5E83F3599CECF644E07635C25E858 -:102A70003F357C757EBBE362FDA43DD2030EB06B97 -:102A800074FFA83E670EDA3DA1EFF9A5A63F435CAF -:102A9000D29F6353575078BCCCE5D5CBFD1E928CAA -:102AA000E7BFA17E906E578DE0EB2FCD997510FC9E -:102AB000AE31CA6C06130E0799CFD3E0EAC273F0A9 -:102AC000DF7E65417FAB8BFB5B63B89F05FE4E9558 -:102AD000B3E73E87279BCFD574FF694CB7FFD4245B -:102AE00019FDA73111FCA7D1B6CE57AF80BC9057C6 -:102AF00045CC0B8904DF50BF2954FF8C4E667A67A2 -:102B000076323F270A81A71EEF0B3D976ED4F94F0F -:102B1000F20A46FE0F9D5FDE3B06CF05896288C73D -:102B20006607E38982E625CB0607E38761E2863301 -:102B3000920D71435D8FE9746CA37DED78CE1C3EE0 -:102B40009ED89A75A02FF30B5F4C04FC972B2C6E2C -:102B5000A4AF8FFA85F3930D7E615127D3DBB6FFC7 -:102B600053D7B182C297241037F30FEA547B3EBA91 -:102B700013896B591C1DF3B4C638048C874BFE288F -:102B8000AC979D72FBA268DDB6F76109FC84524ADE -:102B90003F5142907EC670FFA221E7E83AA0AFAE57 -:102BA0005392FB7C7E7799430CA1D3E8601DE55BD3 -:102BB00082A9BE5AF2AC647CDB2B086F11F2C1B261 -:102BC0004DF9675B25AD11F63DCAAEAD4AFECFC4E7 -:102BD000FBCF605D8272E05BE13D380FD30760B3ED -:102BE0009134C37C0EDA7815CCA322FD77C7A59764 -:102BF000123C8FD90638033FF763E28338CB0BD6FC -:102C00009744D0478D7C9CAB49932AF765EB857E32 -:102C10004F6C756D5A0BF238390BC77BC1E1590FF8 -:102C200036E4C12DD22088DBD4ABCFDA217F76EF1A -:102C3000D6C6F40E03FF1D7CC2D3279C7FA897F451 -:102C40002FCE5288FB8A65A5265A5CD82E42BD87B6 -:102C50007DB6A54581799ED86A0F6B4775713EBFD9 -:102C60007A0BB36B47E75ADC1402A48878A50438C2 -:102C70008F7113B79F36C40CD8D15E02BA284B446B -:102C80003F9FD6F7C5D27ACC500DFD83FE0376E088 -:102C9000FBFD3F2E71B33C4AAF6330ADAFCB2D1976 -:102CA000BA16FA477BDE04FC513DD324A13E6D8E5B -:102CB000813C8098019392A98D4B620452192E0E8B -:102CC000F84132B3F39EB0EA7095300F72EF5619A7 -:102CD000F9EB609A88FC46E1B608EA7F4F8B2194B5 -:102CE000124999E62D03389693E67AF0A7CAD46B79 -:102CF0005F8C25DF027EF93B14E0FF756087875902 -:102D00005F1B5F1F0A114A3F07B634DC40C2E45123 -:102D1000EB74F88B18ED1380C31A7EAE4B5C939066 -:102D20007E22E3FB6EA41F67B3BF3E9AC2F1EAEDB9 -:102D30004DBD8CE3EF4F564DF1371DDF90FF4CAE8C -:102D400080FC5B0FE6D3D69FB420FC5EC9137C02E7 -:102D500085CF815C91DA6C745539765F3F5A5FCFCD -:102D6000E9B862FBA1865E00A494245CEF2BB98FC6 -:102D7000D9597EEBC5C7AF87503E5800E7C9141F2D -:102D8000A394689F4AF1B51086C887FC1CBBCF4F3F -:102D9000E76B73B697C6D1295E4816DC9B815E72DD -:102DA0008902F2035D100B439442EB2032909E9215 -:102DB00008E673AD2BC8DB0CF2766DBADA0CF98637 -:102DC000BB07D831DF2C349F78B750F7623CE499C9 -:102DD000C40B28AF0FE4FE1ECFE90EA4DB08D02BF6 -:102DE00026FCD2E70D098C4F63F2CDF6677E4A16BA -:102DF000F7B389D756105C574C8E5D8BA284F45282 -:102E00003C7BFF608EE0037A3BA872F940F7BB156C -:102E10001201A91D346D4064BCBEDC6F94AADBC5F1 -:102E200082BE4F4BCF7DBC20F85667C33EFAD37DA0 -:102E3000D0BA3357C0F99DCADA5B099685F3E01C16 -:102E40003374FD35298C2E654A76B920DF9A578F69 -:102E500031E6C7C885B74E70C4621E13DA95A9B9AA -:102E600002D35F27D9796E8FFC6C857864137EA8B6 -:102E7000D591121C2FE6D3E7BE0FF9BFE30A057FF9 -:102E800014AC87E737D3FF6B03FD22E7CC62F9D799 -:102E9000B99B703F630BAD6E38CB19EBF03595D015 -:102EA000FACB1F4818CF1E97330AF3AB43E75FAB4B -:102EB00010FF680ADF97F3248477D4258FE1386FF9 -:102EC000E45950DE8C837C6CC85F36E655A33E34F3 -:102ED000E7738F13FFAC1543B39BF12B91BCBD403F -:102EE000BE4F7099E1E73C693E2FAEC8B799EAE35F -:102EF000F2E49078A597C58733185DBCD45FF06D78 -:102F0000CE0AD2D9D893093EA033F8130B4C7034B3 -:102F1000ED33A653D6007E07FB3FFE1338278951B9 -:102F200057DD8AE7E01CFE3A9DC470BC3BD39FFF8F -:102F30003EE8291DFEA17470F1F8BFB6B218F09FEB -:102F4000AF9FDF87E03F04DF1883D4F7D1B727DED8 -:102F500071FEAC9EF8D6E9A0C7BEEF69599D4DF150 -:102F6000FA8A933E003C6F927D770B413C5D10AF37 -:102F700039C548376B952607C8FDA84B8E3AC0DF88 -:102F8000D0E98288ADF946BFE39F85EF92F50273E1 -:102F900026DD820FE27ABF83475705E77936A53BE6 -:102FA0009FE8D914D013952C8FA35E1BCCEE5DE562 -:102FB000337DDA433EA4B07B1D6DD697D2CF97A761 -:102FC0005AE1F010381FAB877C3BBA3F79FD2CB833 -:102FD000D140E429B3505E92F5028BCB17FD01E599 -:102FE000FB5C976FA510663EB464709D2A937B4589 -:102FF00089D89F4CD7F3922A5FC5F54F61F58B5D59 -:10300000D7EBFFA4751DA0B4420CFEE7446E37EB6E -:1030100076F70407CB3B9C5024223EDED822F830C2 -:103020003F92F6F3523A59C0C97622B703BB0A9FC2 -:103030006D1CA4823DA899EC4EA1A80DEDBEB8422E -:10304000B33F18AF459BF09F383AC1544FAEEC6583 -:10305000EA9F3A3DDB1C57F05C667ADEBB7AB0A98A -:103060009E5177B5A97F9F6525A67A9677ACA97FF3 -:10307000DFD5934CF57E4D3798FA5FBA61B6E979A2 -:103080007FDF02D3F3CBB72D31D50734FFD0D4FF88 -:103090008A9D779B9E0FF2AF353D1F72F03E537DA8 -:1030A00068FB4F4DFDAF7C7BB3E9F9551DBF343D47 -:1030B0001F767287A93EBC7397A9FF88C05E53BD77 -:1030C00098BC6AEA5F6AFF83A95EAEBC6BEA3FCA3E -:1030D00075D4F47C8CFA91E9B94E07E3723F31B5AF -:1030E0008F777F19724FA712E59B0CF180BEF0A875 -:1030F00009CB68D2CCCE75483B962F1578DCA94019 -:103100009F8F7A1B2121A9DEDBF957389A7EA3B065 -:103110006F1CB39F3462949F7A7E2AF55BBC5194F6 -:10312000146203946E8750BA0B08582A012A591367 -:1031300021DE138565422011DB1303F15826057A41 -:10314000637B72200DCB94405F2C53035958BA0215 -:1031500097639916E88F65AFC0107CAF77601096C3 -:10316000E98161D89E11B80ACBCC4029B6F7091481 -:1031700063A906C6619915188365766032F6EB1B64 -:10318000B816CB9CC08DD8DE2F703D969704E660B4 -:103190007969601696B9818558F60FCCC7F2B2C02E -:1031A0006DF8DEE5815BB1CC0BDC81ED03023FC045 -:1031B0007260A01ECB2B022BB07407D661BF418179 -:1031C00035580E0EFC04DB8704EEC5323FF0336C3D -:1031D0001F1A7818CB82C063585E19D8846561E0E5 -:1031E000492CAF0A3C81E5D58167F1BD618167B0AB -:1031F0002C0ABC80EDC303BFC1F29AC03E6C1F1104 -:1032000068C3520BBC8AEDC58197B12C09FC01DB68 -:103210004B0387B02C0BBC8BEDE58177B01C1938C4 -:103220008AE5A8C0112C47073EC2724CE0032CC7A8 -:10323000063EC1F7C605CE625911F812DBC707BEBC -:10324000C0B25BDE45CC57F658D09FE57E6A647FFE -:10325000C18B72D2CAEFC5416E35E6FFD709BE51A8 -:10326000943452933A305E682DB461BCF026D26932 -:1032700065E7D0ED4ED04B6D579D488738DA1BC9B6 -:10328000FE0C63BE8395C701CAC553188F9A90B4CC -:103290003719F4E94DB419F28C88760EF32027F033 -:1032A0003CC89B24EA60D1A51E8211AEC27E7E1B63 -:1032B000ADCFA820DA60DABFF12A1BDE2F6A1C4CE2 -:1032C000FD205ADE93C5F2657DA94C5F3ECCCBC78D -:1032D00053D9F9CB5F0B589EEB8C5BFB317E2A4BAD -:1032E000BC80DFC4E0307420CF8F757466627EECE2 -:1032F00045BEF7A714FE1EEFBF3CB5F2C954BA0E87 -:103300006F09C9AD7304FBD1F6A723B43F03F220C4 -:10331000B47DAF85E1C3FB96C8FD84CAB849E7F127 -:1033200013DE58DE7ED98BFD82F5DF45F043095967 -:10333000C1CE0FF77E50711DD587130B4537951CF5 -:10334000E4CFCB770E3FD68FCD0B71506F8988F1CC -:103350008B194587F627D2FA8CA5F19877DFBDAE99 -:10336000122B3E9FE07AEBB217E9D66FAAFBCDF0A5 -:1033700063A6789307EDAEDB388D12CDFA8F0EFD84 -:1033800039D22B8BFBDE0693AB20FFAC386EBB66CD -:10339000F59D2F3F866836A299E89EC16B1DAC1F34 -:1033A0007C7F62B7C0BCB1BC0F852BEA7D6FACECF3 -:1033B000AB17C07957E380EE62F23AC9F9E2CB006D -:1033C0004F092E4E920E07D83191E029B8581C347F -:1033D000AE487379297E1ABE16316EBC2FBE4001ED -:1033E000FAFF91232715F843E2FD1ADADEC1F856F9 -:1033F0005C7E27F13A58FC5EB5C139BA1DCB95CB3E -:10340000DD58362C2FC4726DFA7D76889788C9985E -:10341000094CA232E6623C489FDF1A3FDB5EEC2695 -:10342000E4CB87BE1E07212411E20CD444F89AD6BF -:1034300057509FE2642AA3CF375CC71CC00F2753A5 -:103440005596876F61E7C631F97E0DE28D316EA525 -:10345000445283EDF89784ED9BC11F798374AC9F30 -:103460000C70D4D87D8C7A7EDFB4BEB81F87ABFEDB -:103470005E08DE43F02CCA6E3CB716A369FFBCC8D9 -:103480007875B9585E02D09744E9EB6FB06EB037EB -:10349000B5180B8CA7E3B74BEAC47CAA7A217CDE73 -:1034A00065B68BC987064553CE778E4214E91F4611 -:1034B00079EAC8DB1942CF0E94AF58877C2E2EAF25 -:1034C00076A46AB92E3A7EF3355C0EA427A01CA020 -:1034D000EDF75D4DD7BBD3C2FC146F828CFC4281EB -:1034E0001087792F76356ED279F220562D5734C950 -:1034F0000AE7036A1CC06B15CFD7831BCA4639F095 -:10350000AFEA1794173E961719D27FA785F3557423 -:1035100014EE4BE4F0D0DF9BEE62F2F8C1ACCAF1DE -:103520002E8C8FA8E92057697D22C08BEE3F1DF8B5 -:103530008AD6AFC5BAD25D9F8CFD5DAC3F26D25C0A -:10354000841CA6EFDD80EF49DDE3CCC0BAA37BDEAF -:103550009B719EA4EEBA079FA7B3FE173B8F5E76C2 -:10356000EFFFF74C4E7E2A697109143E95CBE65465 -:103570009651BD3D79D97C2CDF5BDEAE815C3D4E42 -:10358000E54903856B6571DF24F073268FEFEB50FF -:103590000DF43A8FC735F7AEB68E067D57B246ACFE -:1035A000DC82FCB4C214B7FBBECBCAE34D6C1D5524 -:1035B00094C7EFA424376FC3A1CB1A0CF6E86CE2D2 -:1035C0009681DEE7ACB606E99A18F853616D3B2D9B -:1035D0009E1F5D0FFB582BF2F30ACEAFF184FBF375 -:1035E0006A4AE579F40E596D239E30F2B8277C08BB -:1035F000F907E5834F1D391897A5969A3DDCB83A2F -:103600009C22CD372F42FC5787930E6FBDFDE8FA01 -:10361000210AB3AB7D2638CEB96728C62BE7F178EF -:103620003D89B773FE64FDAAE83C3BE03D49538108 -:10363000DEA11E4EBEE8F356D17FDD39381C7C3941 -:103640001CD65A991E0F81EFF10DFD62410F85E2E4 -:10365000EF62E15C6B23789FA273AB93C59192A656 -:10366000E3F8D57C7E923403D753CDE77B714F8C42 -:10367000DF42FB976C756E063FF84C89F7C14A90A4 -:103680004F9BAD98CF76F79E756FFD0CEE7D6CB2BB -:10369000E299C9FC98070AE0FCF42F5C8E5205D031 -:1036A00006DF4FF010FD4F1360FC79848D7F463F9D -:1036B000FFD81A87F03C59B6A571182D3B762FAE6E -:1036C00080B8CB893DE30F80DF3C3F9A4878979DD7 -:1036D0002832F29FD77ACC6C1F48C1BAD8B33E0FBC -:1036E000EA86F8D17C9FF59891CE176E33D78DF08E -:1036F000B218E1A59699E1A5969BE025FCD6E917BD -:103700000DF02A8BEA97047A7DBF4BC5F1AAA35628 -:10371000A6007CAA77AFC172E1B628EF31C3BC8B9B -:103720009BE34DF5DA9D695EA35EE93AF8582CD02B -:10373000E11297E83D46F5DCA9E55A3DD831A79757 -:103740008FC652C7FFE2E62CAFC3348EB9DED52454 -:103750008C66F2598D9B721E7E5DE292719E0FB750 -:10376000317FF3C3E5762FCC736AB9E265F3BABC57 -:10377000CC8E62F05AB42CC67B6C48707D91C6FD2D -:1037800067AF8F901672D44EF0CECEB9F3E8ED88C5 -:103790007249FA5446FDD16AFD3BD08D9DFEEF1C67 -:1037A000C65125ACEBE3D6368B5EC8272664BB69D1 -:1037B0003EFA9E7ADCC06F91F582F93B13FD21162B -:1037C00086F2999D8378E01C848E774672AC8638A9 -:1037D000827E0E520B13D1BE8BED1DB287367DDC7F -:1037E000D2F7BCF7CC299EB2402F57DB9B6450B672 -:1037F000D5CDFDCB809F3E6EA94F01F9B150ECFABB -:103800005EB8FB5EA5699C6F7DD64EB3BFE8D3D78B -:10381000992599F88C38BAF74DEBA722E40B8F4F16 -:1038200063F66CCDF6432387D1F5D7EC3C2B63DEF2 -:103830005A9A677C9A61FF023F075AB0ED888CF66E -:10384000A7D57BC91DE7B3EF7BACD3E132E51D7A89 -:10385000493BF0E7EC42A233EC75EF5279F3C1AB90 -:103860005602E787E42BDA8B3ECFE44FE792CA5843 -:1038700080D7EC9685287F3E786EDC01967FD45405 -:1038800000F4F131B160DEDCC7E4F7B1430CF05B6A -:103890009626EB7144BB31BF852E300DF3D3AB1BA5 -:1038A000DBE1DE988D485E2E9704F6BD1A9F80F20C -:1038B000AC9AB57B897D05EE633593475EFA1FD4DC -:1038C0006F6932CBA7791BCCF52A322905F2BBAB45 -:1038D000EEB7420611996F947F147E33D3581EFBC6 -:1038E0003C52D708F6DC2332C5135DFF6C8548BD1A -:1038F000A91E5AFCFC2305B3687D791A3BDFF990B9 -:10390000FB19F3C13CA5CF172CF3C95A5ECFFD1D9F -:103910006D19326D18C1F198DE5AA0DBAD448538BF -:103920007E6FF85776E4FDF76E11F1DCA937B41B12 -:10393000E4F39CD5E6FD5D68FFA1FB25E43EDCC712 -:10394000826DD7A2DFA6EF47C797BE1FEBB6F0F791 -:103950007C1FE4F4DA7DBECAE1A7FBDD4FA631FB94 -:103960005DAF3787D47F1D52D7E9DBCAF99BD2FD03 -:103970009369C9C0CF9D23199D74C8C6F35039D827 -:10398000AFF97CFD6C9C5F68BF5F9FAF5F5470BCFC -:103990005DE1FA2D7EFEA9E7C01F5DF0AB0762E195 -:1039A00030E803A92905F284166D5D190B703A29D8 -:1039B0007963816E3EF089A3C3C1ABB31B5E9A43AA -:1039C000A078AFD1E9BF68C504D0EF7FDF6A55C0EA -:1039D0002FACDD66F3C3F7976A5AE6E3790DAD1FA6 -:1039E00061F55578AFB276A7F53D235E173CFE40F2 -:1039F0000AE677106F6F769EEEEF0D9F0EAAD9F252 -:103A0000FE48F0936B4927D273E87B307F2001E5B5 -:103A1000F52C39AEE7733D6E5ACB9A486DCBBAB3ED -:103A20001037AD6D197302F8BE9648EF19E9A91A5F -:103A3000689AFA2B47D278DEDD95E44A902F3A3C1B -:103A4000882F19E573FD130F0D3C42D7736ACBAB7A -:103A5000B182D15FE5E7ED5DCD73FE96781EFD7016 -:103A60009AD2A9313F5E97BBEA4EBA80545A6D652F -:103A7000E522AB3F761885EBA24D56BC1FBAE8A9EC -:103A8000C77EF153C8237AC786E71F0B9FDAFFD69C -:103A9000D5B4BEF0196B5205DB8603CE8375BCD45A -:103AA000D2FFC1F9848E8705CFEE9721FF0BDAC1D3 -:103AB0003FD0F1B1F09936990CE809BFD2E636B99A -:103AC000C311062FCD4746E23DA3273E9701EF1FC6 -:103AD000EC11486A56CFF7AB37ED473B06E08478E8 -:103AE000E478EAC65B0F7CF927ECCAC77E0AC8ED0A -:103AF0000BE16B1FE8D564A4EBA777D17554FFC920 -:103B0000E60638543F7D5B2CECE78454C7E8FB9114 -:103B1000952990E7566DF5A62858B2F6EA476F4703 -:103B2000BA9B77E8F61476CF414BE3F91D69B0CF25 -:103B30005B364EC57D56110FD25FF5236225E4C179 -:103B40007C2691D1CF84E18FEA5E4CAF9ED84C9118 -:103B50004BF77902E46552D0DFD1EF35DFDE1D0788 -:103B600061E7909FF173C86B7A594CFAA59B6EB7C9 -:103B7000AC42B9FA6186960AE793140EBA1C45F96D -:103B80002A1E2A4F657862F218DFA3F4570AEDD097 -:103B9000BFDD8AE7C286F7B8FC64F32FE5F3D3757F -:103BA00047833D722285E98DD0FDDDCFF747E0C226 -:103BB0008681CE0C7CCEF87ECB1AC6E73ADFFBAE10 -:103BC0001D0DCF3FFD23E323780FF4115D973F15C3 -:103BD0009FB74D11502ED8883F1C7F6FB172FE36B3 -:103BE0003FA71209ED399D4EE8FA25F81E59905E5F -:103BF000E83C098807B457AAEEA7EF1BECEC5A98EB -:103C000017FBC9C1F6AC201FCFE3F2604E2FB33CC7 -:103C1000201B932F2A2EB0C8EAFBC54F817F29BFF6 -:103C20007A55E05F2BDEBBF968FBBEB76EA074FE71 -:103C300051B3CEB766791ACAB7D53B6EC7F86028BC -:103C4000DF7E945E47C2F26D3ABF3717CAB7E91DEF -:103C5000FF5679AAC36F5D08FCA87CFCF92E3532AB -:103C60001C43E5E3A5BDD4B0F291FEFD9114F4A48C -:103C7000439DFE74BA5BF0E4E23E2087BAE953A7A5 -:103C8000BF6EFAD4E92F74BF66F8853E9F02C94E15 -:103C900006FBC17A37F13A29BE3B778BF8BDA433D6 -:103CA0006A672CC47F5646919960879F51783D9EE4 -:103CB000D53B93E54690137A7B67148B579EA9EC0E -:103CC0008C8D37D8D7475AC55888EF76F8C2DFE7CA -:103CD000C08C443A7F4784FB1E7A3CE24C74EC4033 -:103CE0009C2F3AD307F82A171D99CBF2C10F13F175 -:103CF0003B3E73575C170BF921675AFB4E9C4EDB1A -:103D00006F79997FC6CFAB496914CE7338DE4F12F5 -:103D1000EF8345747F735A99FD3C777D783AD1CF14 -:103D2000CDAB1C4B659047D46E0DD20781E7EC3BC1 -:103D30000BD51B43DA5BC7213D2D08A1270FF78F59 -:103D4000DE047A82B8EB203288FB2716633E48B93E -:103D5000983711BECB79E6A08879EB5DAD226984F6 -:103D60007D6E177C04F8DB9B8C745943E58731FE2C -:103D70007B0AE8EE3CF7E84EFDFA2F0577D02E8B54 -:103D80009E7B77E0CF6879EAB9772E7901EACF1F79 -:103D9000CE7C9784F1B3F67C7133C8FF337B6C041F -:103DA000E32A7B5ECABC03EABB6C987774E66E9B21 -:103DB00086F6F41E27E6D19DC960F1D4FADD9F0F87 -:103DC000C47C74D2C0E8AB37BBB7D5D5FAE55FF198 -:103DD0007E6D2BDD15E8DB3D31688FD7EE8AF281F1 -:103DE000937A66F7E705C6F38BEFBA9F1A99C5EF8A -:103DF000CF38C974887B9D896771EBDA17AE7A0C6E -:103E0000F2E117B7B4C9706FA7F4B75F0F04797305 -:103E10006607B3234E5B3B1E256E42627ADF768FC8 -:103E200095C2F934D87694571EEFDD321ECE377A1C -:103E3000C285C1E10C8503EC8BC2A51AE464247829 -:103E400064FFC7C2E3ECCD30FFA2D62BF1FC210802 -:103E5000174163ED4E9F5DC0FDB3F63D9F0F0479A2 -:103E6000FC51F30AD4EF17DA77F1FF73FB16FC1756 -:103E7000B36FCF7FECBE19FD1F07FD94DC930F7A63 -:103E8000D2F9F3DFC3FAD34E37AEF722F9DFDB9B6B -:103E9000C51DFEF3F6FF2DF1BE43C0FC950BE1FD01 -:103EA000E7FFB5787F99E3DDA9409EC499DD5F67A0 -:103EB00012C3FE2FB4EF3DFFA5FBD6EDA0764B9DC0 -:103EC000924FD7F70E699A9A45CBDF699F2481DB21 -:103ED0006A8B704E73BA37F32B6C02CBFB265305FB -:103EE0003DBED46ECA7B4AAF467B6382760FFB3EF3 -:103EF0009354D70E79A7ED2573DC6BB1C7E0B73DBE -:103F0000509F329CD7CDFED684927107C1CE7B6381 -:103F1000055D1FE4F965480ADCE598A8896817D2B1 -:103F200012EDC137334762BF8985667FE3FA103FE0 -:103F3000E1BAE9E6E753F9F8D3C87DC910A79B3683 -:103F400097C5E9AE23752B8DDF519B1A32CE2B100E -:103F50004033D891DF147E6ABA0EBF25080F52ACE9 -:103F60009FDB5D007E84C1BB7DCA20965F2CB919A2 -:103F7000FCA62D7663DC94FBA156FEBED5B1BA1D1E -:103F8000F8D64ACCFEA7EE475E08CE84FBA7385E83 -:103F90007610EE564D44FFD4302EC245C7C737C504 -:103FA000838EBF6F8B8F2EC087E15C572FE7DB6757 -:103FB0002D8473083BE4BBD37D4D5CCFEE8FD8F3EB -:103FC00004846365A115EF4DBE6FA92C00C3B962CF -:103FD000C895353F64C3BA013EF3391CAB481DDABE -:103FE0009DE4AB73E78A0AF0F40FEDD6F91A21E3EA -:103FF000A95F525524F8A3E9BEE749C41B3718E26C -:10400000A00279CF1807F599EBF0774D4A709C0B19 -:10401000F58F241FFED9E5DFA83C7A8F22FB089498 -:1040200098374324A3FF38B395C1B17691E0CB46CE -:104030003AF25B8DE7BF0FA4B378E3DFEE1C827228 -:10404000AEF8C703E2985F9B8FF93CB5DCDEEFF278 -:10405000AA7110CFE96AED1B07F19AAE83A5B1E111 -:10406000F2780E71BFF20FCBED589E29139AC43827 -:10407000BC773201F570591401B913FADEEDE97A13 -:104080005CA68E9D4B1296875FC5F7318FBE1A973F -:1040900060C0DBFAF11F48037BE201FEDE339CAB1C -:1040A0007C57F8821F0B703D14D53132DCF709576D -:1040B00071F855ECFD4286F8C1A4D62CFCBEE4A4F0 -:1040C00032D194A7BA3C9DFB5343C8105857C5DE64 -:1040D00031B157015E0E8AEE280ADFDAD6B3B22775 -:1040E000CCF95C283C617C88231FB5BAAB009E47A5 -:1040F000EF89C2FBFFAFF3F3A23CFE5D48F87410FA -:10410000C4CF9AD2593EC8FBE92C8E3EB9A2D89AA8 -:104110004CE7CD6B5106415E592FDEFFFD74159FB4 -:10412000F7E6EFE9FD7A2D62FD8EC84A4DB8FDC76E -:10413000640AFC3CC4FDBD42E13F0F6FC53F76FA07 -:10414000E15E5C5799C0EFCD84D23541FEE81A2D6F -:10415000F840FF821F8BF50A01F5FFEB7ADEDD24C4 -:10416000A62F75BA0F85F36E0E677DFEBFF0FA5E5F -:10417000AE377438EBF00D5DAFDE9FCAAB11C67879 -:10418000CBC49D839E06FBA4A655502C74A81AA9E7 -:1041900043063EACDD79AF15CE17AEE7BFCF42A4E4 -:1041A000CA81C6F3DDF7D3D9EFBCEC1B3C0CEDC7DD -:1041B0004FD633FB589B7B3616ECA0D72DEEDF0D88 -:1041C000037E7C43347DD73CB47C77B9B2A0CC6A03 -:1041D0001C370BD7397951B115C243372E6AB3A6B4 -:1041E0001AE8E97DC8C31A1A6CEFB548C5FC453A10 -:1041F0001FAEC3FB231B817C8CBCE6F69218FAFC35 -:10420000C6BA784687D5CD6D32D6D97786F5F9F41A -:104210007942F9694A458CA93EA7B4231DE0526151 -:10422000F32F7587A1536F867EAEF20DF58446E9B4 -:1042300076E0FF0F7AE2ECC870DF419D98D1433FF2 -:10424000A486D30F4B56A8A900FF25BBFBA602737B -:104250002C79B93C259C7E7873393B3F3CCCF32EBE -:10426000CF4CA1FAE10A837E981285F411FADE554B -:104270001917A91F747CFD9BE5CC9BA01FC2F0758C -:104280004586593F4C6B9D85FA61DA1491A8867872 -:104290005C69068FDF46D40FC529D763DDEA8E0936 -:1042A00043376F72BF04E00A25CC037AE28E0C26F6 -:1042B000F743F5452479AE5CAC3CFF5F82B32ECF6B -:1042C0009750FF85FD0E4E281D1294D74BAE17F068 -:1042D000F74B96EC66F27CC94D3C2E19225F2B41C0 -:1042E000BEE61BE52B7BBFC6C3F441EDCEAC8766B3 -:1042F000D0E7373459DD76DAFF86A0BC2D30CADB33 -:104300003B32241DCE994A18FC4E9F114354B3BC36 -:10431000CA01397574D04B79CF02DDBFCEEE99BD9D -:10432000CFF5F86B835ECA8778FAEFF9B89B391D31 -:104330009D5E4E1694513894CE65F6F0E2ED22C2A1 -:10434000A1A685D97935DB04BCCF3B72F017786E16 -:10435000B870373B3784EFF9161BF0B8F0F58EC60E -:10436000DEF07C9380E79E55EE85ECDEDF061627B7 -:10437000B6D3FF205F624D74EC6682793A1AC69B11 -:104380001773B855D83A0FC0FB158F0BEE4D28D7D1 -:10439000CCF1E9C539633F00BF60E1B69076F71A0A -:1043A0003CCF580C7167831FD2C6F7778BE8CF7B61 -:1043B00016F2027F2786FDBDB3B65038547F4738CA -:1043C0001CA270C8FFF670A86DBD17F36FBEEBFEA0 -:1043D000F76570FB7030C9077E79DFA221FF7B5F34 -:1043E00011F15EF1DC7BFBA51AF3940E6530BBE2A4 -:1043F000758BA7310DFAD5B0FBC7F3363EB31FAEB0 -:1044000086CF682683206C3F6F83594F76EBE51685 -:1044100015F5EE8CBA6704F89EFF2D22C1DF019BD3 -:1044200033D8E681F3D743519D28CF743AFC12E884 -:1044300090C2FD0B3EEFD15E9D65E857EC1414E48D -:1044400013F89E06D4291EA2603F577D3E92C31DDD -:10445000E333B53B199E6A295E80CF46527B17F441 -:10446000C88D54EFE079596B9B15FA57D37E892894 -:1044700077DCE8EFEAFA09CEEF8A530C78DB7D842B -:10448000D1EF56C14DC2E02D97FE773EBC45C29795 -:104490006E3F5C2CDE74787CA9CB6F8EBF4351EDF0 -:1044A0001543F09C8AFD0E10698DC77395634D7D91 -:1044B000118F519982E9BB32DD7805FD68882F5D47 -:1044C0000B0BC70FD747619E1CCE9BCDEC21A37C65 -:1044D00009F5A36B493BDA35629AE7E174435ED88C -:1044E000349EBFD27DAE1BEC37392339723FE22AAE -:1044F000C1F31F3DBF167E390AF3C1787D5F46C107 -:10450000E11974BF9FAC16F17EF27516F5AD22E08D -:10451000E3B5560274F9C96B568DD9A13128876766 -:10452000BD7ED40AA19159905F40FBCDBA8BC9DB07 -:10453000A330186DFB13D5631A7CB784340F85BC88 -:10454000FD29EEB672C8DB9E9A7F68259CD34D2E5E -:1045500055DE7A0BE0BB462400DFF75697A2BF7208 -:10456000DBAD02D2F5DBCBF1B7B0C8D429596FBDB2 -:1045700045E7BD6975329EB3CDD0F69703BDCD99A1 -:10458000E874C039DDB85C91780C70BC89B463DC28 -:104590006246DDAD5361BDD5542F40DCB5BAF55050 -:1045A000792AD4370AF83B6AB55E8F0C57A0DA3700 -:1045B0009C9521FE5245FB017A6A37B27EB55B04B9 -:1045C000BCDF5345E503ECAF6A8B40E022493BB5C5 -:1045D000FFEC6C5C9F9D8EDBBE91BE4FEBF3E07DEC -:1045E00018774B3CFEDE5DED6BEC7E5055E18A03A7 -:1045F000209FAAE87BF43169DF722B8E377FA340BE -:104600002035B8BA30EB478530DE6B56FC2EC8E15A -:10461000B6876558F7CD74BE343AFE1CB1A31CF3BF -:10462000ACEF1014CC83FEEA07C80767381F90D799 -:1046300096313E13789DDB85BA7EBC37339BE5BB54 -:104640002F5BD108FBEAF02667814B54BBF3AC0C1F -:1046500076DEB1E5F0E1198A379E07B7CF7B54EEDD -:1046600030C8A9A733FBB2EFE4EF2C463EBF855418 -:10467000E2B9B86705D3CB475646F904B047AC0A50 -:10468000EACD7D2B2F7D10F67FFA292B9E979ECEAB -:10469000E8C0F8EC898D56FC6E48FD4611E5C889E6 -:1046A000ED2C2E243E3275641AC08FCA01A0BB7D4A -:1046B0001B4B659087277C02BE5FFAC8ED292CEE64 -:1046C0006B961F55EA0294178F4431F9306F43F807 -:1046D000F3D588F262E94826DF43E4C1E2F4468C70 -:1046E000FB85CA895AE2D0E5C360A8B7FBD3907EA8 -:1046F0006B5EB312B0EF6A24E5E60D403733A2E0FB -:104700002499F2857F3FC8B74F7C82EAA5CF6F9C82 -:10471000F99BA100BFE3006FE08BF58978BE5AE5F5 -:104720009B8570D5F311E76D30D3B39EF774BD4709 -:104730000CDEF3A1FFBBB13A8668867E87EFA274D8 -:1047400049E79BB953C0EF211DBEEBC881DBF3B134 -:10475000AE001DD62CE37A75BD13E9F6F00FCEAE90 -:1047600004BABCF94E01D74FBC9E46D02B351B0472 -:1047700015E29AF3EE64EFCFA3EF03BD1C7E98D150 -:104780000FA56315E8BC66E3BD07B0FF164185F1D0 -:104790000F6F9A857AB8DA2B127CBEE508DACB5413 -:1047A0001F60DED03EAF9802745ED3605300AF3A14 -:1047B000BDE8F477847F7F9AD8DD0327C3EF536485 -:1047C000AAECBE7C08DD89D3B390BE6AB75B915E6C -:1047D0006ABD8C9E8E3C25221DEE5B79DD48A09F34 -:1047E000D35B8508F447E92B3F485FE223567C7F83 -:1047F000DE132CBEB06F23A3EB132DCC3E2D7DA476 -:104800001FFA35F35EB712167F200EA3FD71213A11 -:104810000CA5BB1E7A89D36124BAF3589BA741FE2D -:10482000C1ACA7E9FAD520BC4A1B7F807180D2C6F3 -:10483000EB71BF3AFFC0BD16C8DB98DBB482E5332D -:104840004A2CBFE71BAF2B641DCB339D41FA175990 -:10485000FE899FAEE3A5ED8FA11DF0F12F8F607E45 -:10486000E3C21728FE69FFD3DB9DC48F76B60FE540 -:10487000CC821611F34B89E42F986CB8BFA5E7657D -:104880002CFC9513E1BE6087CD5741DF5FF0DCD192 -:1048900081784E7E37B353BDBF64DF9921DE8E81B0 -:1048A00093213F5362F921A1FA3790C9E230A77EE4 -:1048B0001383DF6312B6B5E139D382E6EBAC36433E -:1048C000DCF24CA615E7A5FDD83D338A7F385F841E -:1048D000F5197F4F42CF0B39F504E39F053BAD68D7 -:1048E0001F2DD8B609E37DB5DBCE62FE6CE9AF9E25 -:1048F0008A0538D4EE14CDF953DB44BF0DF3BCC4A4 -:104900002336F65D0E531E534D0BBBDF51D3CCF354 -:104910008442F26716FE6AF7735E0A9A85CF3E1EDE -:104920000BFCF461FBD65880271D0FF38F2616462B -:10493000C84FBA505E52F31A9E97341E7FA7233495 -:104940002FE943F807D5E3997D42F2BAB631B9456C -:10495000B15F10EE1E926EBF2C7CEAB347218FF63A -:10496000D48E8F1E85F52FFA9F4F1E85BC0EB22761 -:104970004A017BA2F6976F62FEA1FE5E611F664F41 -:104980009D7EE271CCDF3CFD8E0DEDC2D3BB4F644A -:1049900082BD70FA992F52202F73E9EE728C4F2C42 -:1049A000FD7529DE0F8DE46F027DFA2E227F34140F -:1049B0001FFB5A44BF83AEF3E3B76DC8FFDD7966D2 -:1049C000CD8B59FE9ECAF3CBB687CFD3D5F3A16A60 -:1049D0005A264F1C0EF2AE85E9F5EEFCA80BE595C4 -:1049E000FD91E2F58A8BC0DF769E3FD83C3E6C5E3F -:1049F000D9C7F00F8AA76921F8FBACE5969FFF1491 -:104A00009EB584BFA7ADF3F585E0A6E701F7EDA35A -:104A1000CDEA037CB4E349CCE303BC55A8A0FF3F37 -:104A2000CB84F8E6496B27C60D3B77DB14C8F75AF1 -:104A3000B0FB30F2CBE95F1FC23C5BC2F3714F9316 -:104A4000EE3F9637C96317B55B9C2C1F8DC31FF2D1 -:104A5000D5D4586CE779698C8EF57CB548796A0FA6 -:104A6000F5C966F1439E9FBC586D971547105F804E -:104A70001FA110F075C494FFA7EF3B743C05E070D4 -:104A8000A531FF32523E20B7D37BE08BC9E5D39BE3 -:104A9000783E66779E2521E983213F88E9C35A9FA6 -:104AA00070381C7EF5FCCBFBFA70BF53E74FDFC5B7 -:104AB000E55D5E78DDDF0E2E0D7DD8FD001D3EA785 -:104AC000BE0A2FA79FE2FC4EFD96ED7D0CFECD4C5D -:104AD000EEB7E87967FA7A1B9B995E3EB58DD98D62 -:104AE000A1FC5D13E1F7B45EE8C3E20D353BDB06E4 -:104AF000821C3AB5F7379CEE7CFC1ECE11D9CBE573 -:104B0000B6CF28B723FC7ED97E3E1EF577C38E57DD -:104B1000BBFD6CD8F13E94B4EB60FD1FB6333BE4B3 -:104B2000C36631ECEF20FCAA8FD5E407363A65F472 -:104B3000BBC4D86894474B9D856FC377DD963A65B3 -:104B4000CC77A85FC1F323EE72E3EF78D43BC7E2E2 -:104B5000F74B57027C0C7EA855F1E0EF4E585D955F -:104B6000F9E05F85DEEB94932CC467C4BFE4C5FB1A -:104B7000BD13B23F9740EFB42F37DF1B699794FD09 -:104B80008974BCF632C10DF66E4F3A338F7FAD2675 -:104B90009AE26710AB867D75B9D9F7D09C16BF42F3 -:104BA000BB106754BB0B1D3D95FD5E35FC4C179C3F -:104BB00083AF5D6ECF817B5CB1C48DDF1976BABBEC -:104BC000EFCFE0787124246F9BFF5EB5830B95389F -:104BD000A2B441DC223A97FDFE8342A2DDF0FDA2A1 -:104BE0009FC46A78AF69BDD3837A3822DFB8D9BD54 -:104BF0001A3D9E1457C8EE51FE5FBBEBC4160080F1 -:104C0000000000001F8B080000000000000BB57DB5 -:104C10000B7854C5F5F8DCBD77379B6437D9900421 -:104C2000C2FB6EDE0921591E09A82837E16110D0A8 -:104C30000511505137E1FD4AE2A396AA9505621A83 -:104C4000296D8380528BBAD050FD5AB480B4828DC6 -:104C50007603D162AB36A0566DD52E101194C70ADB -:104C6000948FFAC3F29F7366267BEFCDE681ED3F0A -:104C7000FDEA30F7CE9DC779CF3967660921E40A8E -:104C8000FD7F92A6B485EC04FFA09E4C747537FCA2 -:104C90005723A4373CA77F2A211365072123E977EF -:104CA000132C811809DF4FC9A2EF1DEC1392944A0F -:104CB0003C41783FD5E1F1D3F60E876F0A49206475 -:104CC0004382F6A6444BE2518E8672A12B955C4935 -:104CD0002724B120E4B7D0C789A3E973DD3CE89F5E -:104CE000E475E2FC8E9AE677543FBFFEAA33E5787E -:104CF0003CAD2844B922D3F1ECAD84D0D2E951CEF9 -:104D0000C13891FEFC4429A1E3F0792612FA9EF6FF -:104D1000E396362A57E83A5CC425910C1CCFF4DDA3 -:104D20000017F60F75DAEF5EF8C73584F45BA6B6A8 -:104D3000D8E83ABD76C90560E843E7DA0A40505A38 -:104D40006D008CA71CA21EB49102DA6ECF215B8885 -:104D500096CB771EC2F716A8D332395E1DDF7F18B7 -:104D600021930359DEB43C68579166F160BD554903 -:104D700025A46E9A2FCD320CA69FD5D0328090E715 -:104D8000494DBE44DFDB6BDDAD07AF27005A3A1952 -:104D900078EF6ED50AE03DAF131224741DCFC7B56E -:104DA000D7357B1AADA7B7D7FD506F04E05F0BE393 -:104DB000B95B6BE9F7BB54EF44958E3BED190B9152 -:104DC0005208197BC91190800E42BD08E90B9FD58E -:104DD000C4015EAEC0DFD84809F025A99176E6F798 -:104DE000E676749EE53BE9FAA7F92ABCE347103260 -:104DF0004A627025AED088E94E9847E56CB538F226 -:104E0000DDB467CEC9E9747EB3294D11FA3CB1DC3B -:104E100075532E9D5FE2160A2D15DAFBEE82796737 -:104E20003DE2B300798C25A1FB258A4FF2490ACED9 -:104E3000478C53F79A8CF45BF79825B01AE957958D -:104E4000BC43F5F80B99F01766F8DB7B04F157D5F6 -:104E50007484E16FEFD666C07F5593E48A51613D5B -:104E60009E5D9488C8FD816BBCCA408AD798701D2E -:104E7000E0D54A4679A7C4225CEF85F574802B9F64 -:104E80005F77707DFEC4B61F17D2A6FE53164F166D -:104E900089C04BB4DBACDA102E7DD27D8F021CAA08 -:104EA0003786EA62E9BC5E3D7138C147E79B75EA27 -:104EB0005CB090CE376B0CB271FBB8CF9FDAD66C7A -:104EC000A3FF7C1EE898BEC826BED52E4757F060CB -:104ED000F4DD0E8F3D47103E16A8D3E7BB6D64117D -:104EE000E0B56CAFA40580BE63C83D5E5AAE572DD9 -:104EF000B88EEDAACC4B89E1F154BAA2D2EFCB66C1 -:104F000058B4002D137919597F2DB6DBAE2A580AF3 -:104F100078087C0A3A22A4217E1AC5635A8EEF597A -:104F200023DD3C119F4EDF8F6D3B7A3FB144BEDBEA -:104F3000BE9278E75923ED28FD3C6CF86EC2F7E28B -:104F40007C0591F64097402766FCD0EF7630BC3E5A -:104F5000110FEBD8D7764E0678F714AFE6E7AD2BF6 -:104F60007DDEF1D6CEF9C75B2A7B01AEE6E7418054 -:104F70002FC2C7EE6FCB05A92D91440A6AB9AF2F96 -:104F800008F35B6E0F25CCA0F8AD2A3D6F0338AC5B -:104F90008E3F739D2F4A3F9DCDA3F5728EC34BD795 -:104FA000B7FF520CC2DBDCFE2B8ECF7757CEF68ECE -:104FB000A704FA785C42210A5B3F793F93EA87F1C4 -:104FC0005CEE8ECF5C3285092DC5CFE5B8742586A1 -:104FD000A0425068BB09F084CEAF7CF42E85A44378 -:104FE0009DB613F2D88DFD6E2345800F6B1B3CB729 -:104FF000D3FF811E999C79D349D02FAD4A684D22A9 -:10500000057D6B9A84FAE7C6CB0D2DA0BB6E4CB321 -:105010001AF4DC24D5589F0C7A4F37CE348DE29D9C -:10502000BF3F8FFF0DE0FA6E56296869FF3767C6EC -:1050300005FC74C9B78CBEDD3B5EA72F0E7D2BDF50 -:10504000E32DE8089FD16E011F2FC2F595580A9FE6 -:10505000225867452DD3495DC3C30C47335CC67FD7 -:10506000B2600A29EC08979EAEBF1DAE84FC04D640 -:10507000375993C95A7704AE66F8D0BFA9D0EE501D -:10508000296D27815D704AB1D0FAA46B2422EC828D -:10509000097ABCF3F999E16A869FB03726F3EFDE0F -:1050A0000678517A9A2C6F71003D4CFA61EBF864E6 -:1050B0002AC7260D64F825410A5CAAD76F20083359 -:1050C00080EB36A43B9715ED0CAAD7197D7C32F105 -:1050D000A444C79F7289BEA3F39CA84A01CA2200B8 -:1050E00097A326B81C35D1C551FDBACDF37D05FE79 -:1050F000714D147A511A7281EF8BDCDC3E1944D465 -:105100002B541F957C3C3291C987E87A72EC256F4D -:105110007B3F0C1E0D483712F1B53F77D17E829A46 -:10512000358582818CB3BB904FC6116D4D9B1D4060 -:1051300021E33CC5BC4EA6793537FDBE944C5AD30D -:10514000A687F327429F33788FE3F01B47FCCD728D -:105150000294CA05FDBA457F93C47A0693C1600FD5 -:1051600035AB2AD3FBBC3FB1BEE4641294E804C360 -:10517000923DB04D82F913BFAD57643C2BC7EFC7CA -:1051800099D36F75A3DCAA21002F305B009F65FCCB -:105190007D99DD1184F910BBF5543B5EC086217307 -:1051A0005CC787205CC895F8C8FC2ADC92723C3743 -:1051B00032BFD307ED7E99D2B5A7AF6FBE9BCEF3BA -:1051C00094F47621C08BDA65D920CFCDEFCF7FD490 -:1051D0005205EF69BB05D88EAF6BA92C21DD845F2A -:1051E0008B096C734793E7AB98FCB5534BB42442DF -:1051F000F765718CCF2713AF02F6E5FE58C6672D11 -:10520000B18B911F26929ADAA1B4BFBFC4DD78108A -:10521000F86C12F163BB092E231D7647A73791F076 -:10522000DD60F74ECEB59AEC683FE2677F6C4E26A4 -:10523000E8B3FDB14C2E0BFBE149B7778D1BDF0FB7 -:105240000A805C3EAA15BF0B7AA2B274C4DF46D2B4 -:10525000D262F7DA009FF381BE285C47037DD16FED -:10526000F743D77D91BED601FEE6D69BE8CB9E8C58 -:10527000FD7BA91883799569D66FF476753BDCB808 -:105280009EECCE5E242D0AC9A5709DC7E9747F6C83 -:105290008C1FECB8B2C7291F53F8CD25BE671B245D -:1052A0009887D560BFCF8BB5A2BD37EFE7B1C8EF08 -:1052B000F4E32D3574C805F4F95ADA0FC95507E837 -:1052C000F53A69D07D0FF8B7AB488FF35CEC591B0A -:1052D000EDA36F2FE8974A370A4FB2D97A4E4F970E -:1052E000E6F13BEDD7F4DD7E89CC06BDBADFAA0E30 -:1052F000F0E8F4C76E37B39BCED9B3B658D23B872C -:10530000D3027BB2A68C88D48FC7C6CE8E66278880 -:10531000FE045C23FB8B130D2D6322FB0BCBAA2F0A -:105320004CFB8B2FFEABFDC5A1AD5FB4D6D2F934DB -:10533000647AFF0EF446146F1EC07D13B71729A5BB -:10534000E44DD3E1E1EF6E66CFF45E318E1CA3A491 -:10535000146327FED8E194DF15E2B70E87F6BE5539 -:10536000168A57653641FD43E50DDA99E6F57E9CD0 -:1053700059F6198C27F8B02C8ED239E5BBC72D6AA7 -:105380006303D8D37F96A96D49475F3117EDBC5BA6 -:10539000572CC6F2ECD1CBD9C0FF651CAEA7417F1C -:1053A000835D1DCFF8A73A9EF1CB2B69BED340FF9A -:1053B000AD9AEC1C49FB5BBA57F6C4E0F2C38360BC -:1053C0007DB74E9553E1F931BB15F789FB9D0CCFA5 -:1053D000C78854BE13ECDE4331DE3DB45C9056EA20 -:1053E0004AD7D9830BD2C6639D9453C38ED2DF7D37 -:1053F0007646F7C7889BCDBB5EF26CA78FCED5BB38 -:1054000013810EF75B89C1EEB0A4337BD992CEE055 -:1054100058798932E108465F3574FC4A45B5819D6B -:105420005F79C986CF611E487FB1C67EE2793FF1C0 -:10543000EDFD48E80CD81F6BEE4761CF391D9BF19D -:10544000F0A87B5C22AC67419AE64A4779AF2A0014 -:105450009FB2912D1F81DCEB5ECEFB2590F3D5979B -:10546000A5E060BAFE537BACB87F3BC5EDFFD37BB4 -:105470000EF4AEA4E5F25DEF25C03ED19DCEF075F1 -:105480005A694D80F92DFB1DB59B0B906C7BDF8914 -:10549000DFCF2D59CB86B1EBF5DFB5DF660CF062BF -:1054A0003B3AC19288FD35CEEE0FC0FCF6AF926755 -:1054B00003DEA87E14F69704F270C21E598B2DEC01 -:1054C00068978D4AB7727E63787CC0C5C6E98C8FB9 -:1054D000CB2EC593808E8FCB145581F9975D4AC032 -:1054E000E7A74F6CDB7033A57B7F9A15F781747B40 -:1054F000D48276A1C4FAA56CDD9249C769E1EB7943 -:1055000063CFAD33AEA3FF7C13F40C6D333EE44B9D -:10551000614C4D777125113B6B82CB680F9AED453D -:10552000A1B7CA9BD6D7F62700F7C0ADD7011D9EFD -:105530005008D061077BDA7E632776E37A84C7ABB5 -:105540007B7E89FBA53EE92AE3AB3DE727021D5799 -:1055500091E04CE8B76A8FEC0AD2D66F903D434099 -:105560007F08FDDEBEDFB97CC0EE01F91F2BBB5604 -:10557000C33AEDB739540AA7EBCE16A4A09EB35B8D -:10558000CB41FE95C56639E6EAE8797F8A5C0E7400 -:10559000F0464A86F1B97DC310D073FB2C4C1EB582 -:1055A0001CBFC311C276B7A6A0BD26F4BBC93E1569 -:1055B000FEB0495972209ADD4BE42D1B63E9FBC90B -:1055C000395622839D1E5A827ABF837EBFECC37DEB -:1055D0008059CF0BB8534823BF74B04F237036D8CF -:1055E000A98FA6533B6D08D2C050B03B8397372C90 -:1055F00085799E6D8A77AD46BF03B36BCEB62DD944 -:1056000030159EBF2DA31FE5EC6519F969FFEB4B23 -:105610000787747C4C3505E2E9E2B0AFCFFC81E24C -:10562000E7E2E7711E3F3C56760E89B62F16FB2542 -:105630003A723F4B1ACEBF9F6534B21BEE4F6F8854 -:10564000EC4F37A6E3FE343C11D446DA962336A05D -:105650008BD3D45487F9FA29F2B753B8DEA0856406 -:10566000976E3E2FA44BDCDFA13D0D72C54FCAFAE9 -:1056700053E3842C8AD34AAF03BB731A716DA3EB37 -:1056800079ED449964A5F531DBDD1E89D67783E198 -:105690000974FB3B39B09DC2613795C7BB69BF8BAD -:1056A0005B1B6C6E3AAE7F0F9DD4285AA7880438D6 -:1056B0009CB0FA0725E9E8645606932B27ACBEE7B1 -:1056C000A09F131FC710D8079EF83C2EAABE1D9C92 -:1056D000C1F4ED1FB89EFB37A7F7E0A957DFEC47F1 -:1056E000E715BCE41A06705FF2C2D772051DE77AAF -:1056F0006E974DD9D85A0BFE9B9BB78415903FDE11 -:10570000806B02A8DAE92F78ACA09766ECF05AC15A -:105710000C9FB9A7C60AEF67EF6D7803EA770477A5 -:1057200062FD7CBAEF8F00971BEAC307805C321BD7 -:1057300088027C412E307BEB533E8FF44B9EFD89DB -:1057400048D5A516A0F3F6F11F6955C0F4B9B9966E -:105750008D4FFB7B0BF074434D781CE8B7412B5801 -:105760007F8348F3AA4435D2EFD8CBAD92DEAFF0B9 -:10577000EC438E454CEE32B80F7AB8DFD6B5C82769 -:10578000AE38D0F782AFCA1E766880EF8B3F880BA9 -:10579000C4B881CE98BD7DF1078E803F8ABD1DA122 -:1057A000B3600CA32F416FC4CEEA9A1DE8EDC12768 -:1057B0006BE2407EA478559B4F87C7B20D53F2DF52 -:1057C00082FE6363D07FD73EDE7A361EFD3E1FE841 -:1057D0005AE8B34AA007835F4AC803C617B48B00D0 -:1057E0008C2B4A22AD76117D9D04D3603E9F03DC55 -:1057F000E9778D36750E8CD71817E382F12AED59AB -:1058000036905FED7E5070265239721DB73B5F3B7C -:10581000B13F19F07E71D8AA41B03F085A7E81F29B -:10582000AA3BBABB2D5DFB0FD3B7FE41B0BF12ED53 -:10583000F71D8F2B007DF9079077801F4FC56058AB -:10584000AFF8AE7F06D3F7945F70FD824F525A894E -:10585000B6B50041A5EDD6C1A337E70B51EEB6AA08 -:105860007EC667D44E01BE7306ED19C0CFFB32B0C1 -:105870009EE2250E0F7D5FBD37CB23AB28077A67ED -:10588000A446E4C3F55C3EA4B486912F7BBA4FF8DE -:1058900096C337A8ECE4FC45504E017F31391EEC2D -:1058A000CFE490BF3FE005E406C74F5F89960B3910 -:1058B0009EC5BA53B85CB84EAC0BEC375A2FC960D2 -:1058C000F247BC1FC9E136412E480C45F1FFB4D365 -:1058D000DD8ABE04ECC9092BFA635992C1E6BBD834 -:1058E000BE1EFDAA8B53D6A33F35456BC072F1F89F -:1058F000067C9EB6A502E963F166C9E01F15E5CFF7 -:10590000B87D76FA8405F51BB1C4F503FA13EF37B9 -:10591000723BA44FBAAF0CE07C72CF86270BD588C0 -:105920007FF8626CC3CD7700FD6F975DAB003F8D54 -:105930001324350A5DE9E107F0AA6EFCD744985FAD -:105940001509D5817C569B24949FEA5E5AF6A1C422 -:10595000DFC8E4E9496EA72D8A33DA97B338DC4E05 -:10596000585B2717D1F183E73287835F27A88464C8 -:1059700085E18F007F801C7621BDAF1DF410D09192 -:10598000E444FB07E4EA2E1D7D2CDDB1B5AE1FFD1E -:10599000E70D975DC364EC8738F4F25BD08990C75C -:1059A000E6F52DE6781574785D444F2DCEE07E54F3 -:1059B0004059D5FA73E8477D94E3AF11E80DF8B983 -:1059C0005ED0DB300BCA5B131F8FFA1FC9F77D4F08 -:1059D0003C3D08FD13A329DF52BE3E097C1D852EE8 -:1059E000EADAE5806F5546147D7052F23D979C11BE -:1059F000F97EDFF19BF22B75FDF8383C2E5A7D8342 -:105A00005D51E015812BE907F4B0886206E040B6ED -:105A1000482EB00BC5FB942D2C1EF014E723F15C2F -:105A2000D405BCC702BC3310DE4FC17CA95D600346 -:105A3000959D16607601B1DCD40FF4FCE238ED26BA -:105A4000F4C7ACB710F02F11A90CE93DA571D3F143 -:105A50006F4742199B8EF1156A77031D2D7E5CC539 -:105A60007DE2EA5FC5225DBE98918EEB5ADD6865E6 -:105A7000F4696D40FA3AF9F992C1109FF153BD9E55 -:105A80001545EFD499F4F943194C8F0ABA4B5FC707 -:105A9000E8AE51D1E2927474F93CD18683DC167A77 -:105AA000A5337A8CD0916B98A0A30AFA3CBD3E2412 -:105AB00003BE281E5F053ACC58174679D6191E45F5 -:105AC0001C4EE053C8F9FFF0F98BF1DFE6723E851A -:105AD000DB3B1DF1BACAC00FD747F8E12F0C3F11CD -:105AE0007EB0AA91F5FC9EC3A533BEC8CF7461BF3A -:105AF000759F6EB81BF8B96E7D9C673589C4734479 -:105B00009C55CCE3334E879DC56376A9BE4F334C7D -:105B1000F14215E53D8BBF4CE076FA7DDB63D0BEEC -:105B2000D807AF408EB4C505C0BE14DFE528445386 -:105B30008613F255861BE79F032284D65356D84816 -:105B4000261DF7E235CD2D09B4FDD470684A115DEC -:105B5000E23E5B68C62DE01726DA12B033D0970F0D -:105B6000F47F8AF54B5C3B0DF3FC1787B7C04FDD24 -:105B7000A773D3A2C50B041C3BC34B7E268F9FF19A -:105B8000F766FE6F15FAAAC7FCEB4F04FEBD81F85D -:105B90005741FC845C262ED0D3EDFC7B99B0F85C99 -:105BA000A6917F453D0AFF2666EAF9F75288F12F54 -:105BB000E7D3C446AB16CD6E19986965EB6A9C5065 -:105BC0000AFA28D14BD06F429789FCBE98F23BF07D -:105BD000B11FF8B60FC093C9DF74ADE16E789FDED8 -:105BE000C8ECF18B496CBD8BAFD79A65E07FBA1FCB -:105BF0009068D306CEEF9DC33D982831FD9608727C -:105C0000E68631A171A08755881BF481F531FC8EA1 -:105C10001D4302418A77F53261F2E3F3A7EF7E0874 -:105C2000E4C67A87274B8DE8A54FD37DC332533B1B -:105C3000E76B4A971AF8B1EEFBB783ED1F3B899FDC -:105C40008F5D2123FD513ABF365307FFB1DEB00C03 -:105C5000704D8EF7A55993E83EB0316BBA7D205D4B -:105C60009F9BDABDB45E4EEBEBC02FD72B4478FD83 -:105C70000947DFFF224F2033F330F8F1966768932E -:105C8000328B31AE3D19E67343FFB08CF2AD87F134 -:105C9000FF6AF0EBD1F51CBD2DFF5715F469E5ED5A -:105CA000DE3A782BFCCCA3B89FB9BA6918FA9F7575 -:105CB000FEE63B60BCCEFCCDDD8D9BC0F99ED237AD -:105CC000EEFF12468765908F42AE2CCAECC5E939CB -:105CD00044A60F8DF017C825B077451E02F8239D06 -:105CE00018CF0820FD413D717844DEAC6BB094477D -:105CF000A3EFEF673AA2CA53D2F47FBF7FA884AE66 -:105D0000175E31F9FAFD4C9D7C6D6C38DA9BD9AF8A -:105D100054FB537BE27EEE03D8B0DAF3D74CA0BB42 -:105D20007765F4C35C1363F34BE02FD088EAEACDC8 -:105D3000FB03B66B9282CE425AFF46221AF837BF57 -:105D400091B1DCF0A8B7DC0DFE968F2C287FABC09C -:105D50007EA3F0193D9804ECF49F7BB9DFB4F4986E -:105D600043833C81B3921DE5E7D923717ED0AB67B5 -:105D70009D16F4ABB7BC16837C713E338EFB41029B -:105D8000067F8988F79C7F7B6E32C8FF2779FCF3FA -:105D9000C958E68F7DF2F66CF4630A7FAFA250D843 -:105DA000F782B41E0AD75E6037F7473FACF0FFF6C4 -:105DB000B657482CE9888DA3D8D9FA7A2B3E09FC2E -:105DC000E75BBBC997F84DA64DD8C38D00E7EA47FE -:105DD0004236D8EF0A7B58E8EDC1A7D29B216F620B -:105DE000703973AF6D3D65B1C03AB752724A727780 -:105DF000A42F41475B3BE625ECCAD4EBA7C7585E0E -:105E0000427B9D7FF71CCF4B18DB76F465B0F328FF -:105E1000BF6F357C372135CE17456ECD5CF1307EB6 -:105E2000DF19FDCFB4105F343DF21ED72344A9E93A -:105E30000F7A8AFCF3C178358A3F67E6A795A900F7 -:105E400017B31F2E32FEA338FE3B99EDF1CE411061 -:105E50007FEB2EDE699EF7DFACBE81D1F494C0B338 -:105E600079BC8EDFB3FD597B3B1BF1ED72B07E87B1 -:105E7000EBFA55B2981D345362F17CF22D417D2D21 -:105E8000E884C2FD0BA08B92778E8D88C338505862 -:105E9000067970FEA3CC01188FEF643F2AE6432DEC -:105EA000E7AC68791F743C6F343C48594C8FCEB4D2 -:105EB000B23886747B16FA0766C6C648313AFBE4E8 -:105EC00074BBBED50C71DBFDB1A346A2DFD3AA0E15 -:105ED00088063F733CF774264178025C3C51E849E0 -:105EE000C49D059CEB4AB55285F9D5C83650811A38 -:105EF00093A329E504E36FA3240DE1910C467331CC -:105F0000D03FCBA73BFFB68C72A1A4540D4008959F -:105F1000EA8BA4AC62CCCF7AD9A2CBCF127452F761 -:105F200022D5CB06BFA3DFB0AF4EE2F2985A8FDA8C -:105F30002E5D3BF5119001117D30A0D66EA80F7A31 -:105F4000C045149DBE48D2D20CF5015E571CECA78B -:105F50000694AB86EF04DD89FC40FC4B8175BB02E7 -:105F6000901FD18BCF6794E443BA01F9067EE561B7 -:105F70001C9F74BD4559B41C5B1E3AAFA71BB1DE14 -:105F8000EED67574259D0F15606D2BE97CA95C9884 -:105F9000BBCEBD2A0DE1EE22B0CF38BED28ECFE708 -:105FA000F3EF933656D4F5A54324D5AAE8CF4DD2C6 -:105FB0006ADEEC0BF99835B44EFFE6354812F87DF1 -:105FC000A89CC1EF9E59E9C252E0DB45DF4BF4BD0E -:105FD000BF8CE4427CA7333DE6CD7218ECBE2EF4B4 -:105FE0009837ABB8A31EB3D83D6F417EC0F2265997 -:105FF00005BA5833A517FAFF36EC943CE08F3BD036 -:10600000C4F2F436CC64FA448C7BE67789A837CEA8 -:10601000488CCF494B12F2417512C74D6D12C66BB9 -:10602000CFF2FDF6B24C9F2F4B672F6D682A8EC5BD -:10603000B8AD492FD13F9744BFC3D89D04F6D3B024 -:106040007A2503E5C022F89E2C088D88CD00BAF58C -:10605000BD37460239706110E0D31C0F1471431133 -:106060004F7C25CD77AF7EFC8E7142637C4B4EB06A -:10607000E7029F8D96E33CB251FF12C0EB1AB013BA -:1060800029DDAD391287F059F32DE33F3ACF1F02D6 -:106090009C5B9C25484F42CFD27916BE4B3ACEB37B -:1060A000DA12463FA26E9E7559C55DCDD39407CBDB -:1060B000E7D50E7F1ED7929D0ACEFF2C89F3C03CF8 -:1060C000F7DA3C1FF9400F9F8943BF9FC04F15E788 -:1060D000B1B3141F129DE7D9BD23622D0EB08F7C82 -:1060E0004F02BCE481E104B0CF0F348DC883F57456 -:1060F00016DFDD9B59F67416F299EF19E43357E871 -:10610000FC4B6A64FD5DC485B742FBAB80CFAFBB7F -:10611000C6A3113ED58AA35E628E75B4C3242EA792 -:10612000CD74273535FF1BF29228BF615EA87F1022 -:1061300009ACA170AB1BCAE88FCC232AEA65139D7A -:106140002CCBF4BE0AF8127CDA057C5E8779DF93EB -:10615000E90D4209F3E83F1CE5D2FE2CA6DF5EB64E -:1061600059F07B96DF9244305FC71C77FF38B3F25B -:106170002DFC5ED85FB93EC95570557C70B86BF880 -:1061800005912E9673382D877830E4B3EDB19E32A9 -:10619000E44D98E0F0FD4CEF270C0E94CE46323AD9 -:1061A0005B43BA844708DADF93E93B06A5D34AE9A3 -:1061B000058032BA220DE0BC4BD5303F61F72A068C -:1061C0008FB3EF3078EC6BB3205D6F22F9C897C3C3 -:1061D0002DE7EE86FEA97C390DEB1A13DE29C1BE30 -:1061E000B9CF22D50272B97FD8235BBAA6DBAFB391 -:1061F00070FFE4BBC0F1703FE061C4DBCCAFD305FE -:10620000DD5EE274DB53B84BD95DF27507BAB26656 -:10621000A746E8AAA7F958942E48FF5E1DFBA3FBEA -:10622000288C3B34EF8B417955B55B42795EF5FAAA -:1062300017B85FAF7A35068972FCABB1F8FEDC1E89 -:10624000F6FE4C69F43C8284EC5EA8A796EFBCD7BE -:106250006BD4D37ED4473FD3CEB932E5485C367990 -:106260002A3BA7B086E73D89F86C02A7B3E4815EBC -:106270000DF450F20482F984090E96A7D8F13C027D -:10628000E3DB54FE9DCBA54A0067F3F904398EE5A4 -:106290001FA692755F039C92CB8DEF531DE518AF3F -:1062A0004D359D6310F02ECEE6F6B38DA4811CD93A -:1062B00069CAC710E5FE6C6E07D626E17E50E1F391 -:1062C0006A71DA906EEF73DA71DDF72591E429587F -:1062D0005750FF9BFB1165926621AAFE9C45791CD5 -:1062E0005175F651AAB797A1DE67763F43FBBEBE54 -:1062F00074C3FBFE8BF20DEF07D60C37D407AFB893 -:10630000D6D0DE4D01A0AF67D4DF64689FD530DD05 -:1063100050CFD97C87A17D5EA0D2F07EC80B4B0CFC -:10632000EF87EEBCCF502FDAFB90A1BDDC895DFE7C -:10633000A36CB63F92855DEE1CE903BA929D762967 -:1063400046B7FFABE4F8284D284F83B879AD7362A8 -:106350001AEC4F5B92A83EEEC2EFF65DF76D7E81C0 -:106360007F6E7F9571BFDB99FD548A50FAAB3A403E -:10637000E9A008ED2F7F36F72354A8D03E6C437D6B -:10638000A278701D3313ECE84F33F75F99AD1AFC18 -:106390007C621F205B3CAE2952E7F01274D91DBC11 -:1063A000EA395CFF5B78FDCD946F24F67BE6EFFE67 -:1063B000986DE1F6B86F5BB67E5F47C2B217F775AE -:1063C00017CEF809C85182764D75BC0BFD12663B9D -:1063D000408CFF4A9AF7372057CDF2D4BB62016B4D -:1063E00067A11B0CB9F3FDDE1FB3CDFBBD09B311D3 -:1063F0001F4936039C5E6CC7B366D8EFD52695E07F -:106400007EAFD6AAA5F564BFF762364178D7035EA2 -:1064100075FB3AD9E6515D28E78DF64B47FB9CEAC0 -:106420003FBACE0D60D749609725337B7DB784EBAB -:1064300016E37E07FBFCFDEC1ED8E731C453AFC862 -:1064400088BFBF67337BFCFE58F93BD9E3C7AE4634 -:106450001F1EB67A30CFFDF05499ACA2703C5F3E5F -:10646000AA0F89228F45F93EF7DF6CCB2188B7EE62 -:10647000FC1F87572EEAF2BCC7E1492C8F733AD034 -:10648000916EDCD81C46171939DC7F13C3FC18A7A2 -:106490007FEFC47309A76FFA208138212F6EC4489B -:1064A0003FE43913CF0390B7E37738D14F387D52AB -:1064B000F1C8554E1D5D8D66701EF7CA3B09E0FFA1 -:1064C00099BE2B23D5EFE89C9E32F8FA8812CAC6F3 -:1064D000BCED3F9CECADD272FABEAC54E6A734E6FC -:1064E000BB99FD46D3575419F878F925890492755C -:1064F00075A515F30A975F52F0F9E96CA35FA953EC -:1065000078F5109EE6E7029E87279D1C04FEF43373 -:10651000B1D1ED8F5B38BCDBE9C7744EA6B3F31F76 -:1065200025BCFFF3E5D7F4013937DDA666F5C4CF06 -:1065300025E0D47AF98B789013AFC3F99B28FD1727 -:10654000E5B0B8D2EBDAE7703C8294DAC3E380EED0 -:106550004BB93F3DCAB9807139E087B954FE3F3924 -:10656000173025C7782E202D478D7A2EA0BBF34DEE -:10657000D36CD1F55D6E047E1F00BFDEFF8CD505A8 -:10658000F35A08B613F8EFB65AD17FF7DEE51802D2 -:10659000F1942FB6587F09796E8B9EC9786623AD2A -:1065A0002F9A1483F19F855BAD2C3E37293600AEC0 -:1065B000AA455BBFD77B2E1DEF2BCAB7CBB2E8FB3A -:1065C0006736615ECD7B6D6B31BFFB24F0337DBEE2 -:1065D000E8DB1FCD04F8EFB3350C190676FF0EC9C2 -:1065E000704E634963ACA12EF20805FE881439BFD2 -:1065F000A1527DF2608EF1BCD68848DCECC11CE66D -:106600002FC13CFCAAA9ECBCD681E36CBFFF462697 -:10661000CB330C4E9A3565185DC7A4542BFA4BCC7E -:1066200079898420D2C9029E373CE96305CFE54EC3 -:106630001AEA443BF0CD95358807FA9D6382EEBC9B -:10664000C2A49F33BFCB2437CBABEF345FD194A729 -:1066500028CE0F75C84F8C9C1F3A1A8D6E36E4F009 -:106660003C45CED7078EB37CC4056FCB6C5DDDC8CF -:10667000CDF7F93ADE6BCBBFEB250A8FF7CA991439 -:106680007FEFF28D8F81DFEB0BAF44203FF48BCB9C -:10669000D1CFAD7DDEAE5F7DEDE77A003FB7962FBF -:1066A0006EAF035BDEE6BDD770EEA7E7F2A66B79AF -:1066B000322B87C521CCF2DD4CF7FFBFE4FBF44958 -:1066C0006F0CF23BB1FC1594A77631F968E673B311 -:1066D0003C17F332CF77F925D990BF9CCBE54044E6 -:1066E0009EDBF03D35F7713DFE1225B046423BE0A2 -:1066F000831CDA6EA423905C4A87A8756D8BEFCA61 -:106700007F43F7CF1F43FB3BDCBE4FA04CFE4BBF8C -:1067100032D0F723DEDE89F987673BC9436F769B6A -:10672000F2DA2463BCE0CB9CD266C8E77F50A5A513 -:10673000CEBE1E499990E73D7CC9F9F3A710B7ACCE -:106740007AEB22F2E7269B2F0DFC03FE7E36CFF676 -:106750002879231772AEEE3CC316EE9F27B9B9868F -:10676000781FF889306FE1681CFA89D6A669DFC006 -:106770007C9E4BD3FE0FCA2169DAE51C1D5E6AF9C7 -:106780003A154B74BBB83857D0BF17F5F8FC322A0E -:106790007FA3D0A19ACBCE01943E79FB20F0C77D98 -:1067A0007EE48E41201F5B368DEA32DFED67C09FAD -:1067B000547EFE18E47E56249EFA13CE37C2DF3D87 -:1067C000DFE6CDD6E769C9B949385EC235BB5BD3D0 -:1067D000299DB4AD93517EB739587EDB318752DEA7 -:1067E00058C0BE4B317CA7B0FD07D03DE563C5A1C5 -:1067F0007CA39747C5B90CAE9DADB33897ED136C2C -:10680000C46387EF6D476FB2831E9525CDC5FCFF2E -:106810008C1EAEA123003DFC88CBB19369BEA2DCE7 -:1068200062F88EE9DB6BB8BE551C26FD3AA0EBF88A -:1068300078639A3632978E3F314D2B86FEF6DAFC1E -:1068400043806FF6C645CF57BB2E97D923FFCEE1C5 -:10685000F4421C68BFE27832C6E96FC865717A0DF0 -:10686000CA1BFA87D7401E7AB3DBC5DB87F0DC1D75 -:106870007D3F01DE93B410B905F2E7E864E17CC422 -:106880001F4E1C2520BF12C26D04F269124C79B054 -:10689000A2FC0787DBAB3CEED991EFD83CBD1CFED8 -:1068A0008D945FE0BCA8E01788AF43BEC483AA8F75 -:1068B000F31DCBF7687CA297047196744DB5007DEB -:1068C00040FE29C827737ED08E5C76FE1DF850EA04 -:1068D000820FE7F379F6940F1B9F98628985793EC2 -:1068E0004430AF8372C26A3BAD3F7B9FCB03E7C7A7 -:1068F00032D611DC070D5C11B70DF649351C1F832C -:106900003792D5B1B4B59BE7F7897C6A776D48C1FA -:1069100073060FB1FCBD939FDF243BA1FFAF45FF82 -:10692000C67C4191DFE7CFB518ECC2DBD27D0F23E7 -:106930003E4DF9D89DE7817D9907790E3F11FCCE38 -:10694000F370C6F03C9C318D9BD01F37A6F14645B5 -:10695000A24D9E558212ECF79EADD114D037CFE5F3 -:10696000B2BC9CEEF2E39EE6FDFB01CFA99DE75988 -:106970003ED92E773AE4593E999BAACB2BFB01CB0B -:10698000B3FC7E2ED323CFF23C9A676B98BF6EC9BF -:106990000B8750DE8B71443B918F37E001968FF768 -:1069A000AC128A05FAB9184BDAF3CC57A1533E342E -:1069B0002CFAF90591576ECC271F1C0E97623E10DA -:1069C00021784F42BF3CD5A007B7865D71C02FDD4F -:1069D000E983DFE75E9D3E782A8FF14D14BDD9949F -:1069E0007B757A33087443F5E60128AF5A6F727DE0 -:1069F00029F4A7787F88E373562ED39F51F4E621BC -:106A00008E5783DE4C2101CCD320A72C1E7DBEA83F -:106A100028BDBCDF97D3B50F61BE63B83F25E1D475 -:106A20005122E9E45019E76B71FFC4F3BDC83DD3AF -:106A3000A2ACE37ACE9F963961BCAF22A1498A9A73 -:106A400087D6ECB689F8ED1730EF1B0653B92975D8 -:106A5000949B51F07106E6D9FF6DED0010C9B54960 -:106A60008DF1603E75818F73B968C768E7A114F036 -:106A70001F7EC5B88F14F0FF86C3C396A5FD1BC645 -:106A8000F913E7B3CEF0129BC7F0D12F8FD9332281 -:106A90007F7DB7C91E1D91C7E0322ACFC8973AFC47 -:106AA000C5E645B17B841C7E39DDEB80F7AF9ED80F -:106AB0001D0F7424F024E48F195F113E5B85E352AF -:106AC00038A7E6A576D43FE27BB31E8A7CEFC7F9F0 -:106AD0006E053A1AC9F27DF07C013FA720E627E84F -:106AE000DCC3D779205D73E715779CA7EB9445EA63 -:106AF0006A9E49E11409F83F497361F98713160941 -:106B0000E6E50A2B982FEFE2FAD1AC07A9B8E074BA -:106B1000C3FA798ACB8DBAD32C0FB1AED49706FEC7 -:106B2000FFDE59DAC83CE423AD18CABC2CAD04E63C -:106B3000D9EC66788ECDD346435DE40B98E7A9E5A2 -:106B4000B5E71D8C857609E3891FF421DC370371D5 -:106B500096049EC790A0B9CA408F256C21982790B3 -:106B60001C1F6E8E81F8DF26E2817353D97ED50219 -:106B7000FBAF8C07B4D550D69DE6F7E694123C7770 -:106B8000D99E47579B8E7974C06F7A7A9DCEE73134 -:106B90003D8FF125B5436EC963F39A06A5B0430452 -:106BA0001F756657E8F87076DED5F1E13DD0FE2A14 -:106BB000F8706E1EE3C379793DE0C3A579ED7CB82A -:106BC00004DA77C7870F71FE7BAA1B3EFC39A7CF7B -:106BD000E7F23A95A30FE54595A38C1E04BD031F6C -:106BE00082BE6FE0FD51F9B9321ABDF7802FEBF389 -:106BF0007A6017B6F7D743FAEFCCFE8BCFEFDAFE09 -:106C0000DB0279E3BAFD1EE597A7617E945F7E0102 -:106C100025E5972D8C5F54965F6EE2AF767D136607 -:106C20007202F2F3F4795ABFCB6BD737DB01CEE6B1 -:106C3000BC9C31267FFE3B9CBE9B7899103E4A400F -:106C40002E50B8BDA4A7D7E739BFF847B3BC53AAA5 -:106C5000D9CAC0AEDC778ADA91003E2E0FC66C6EC0 -:106C60003D007623511AE2E11EACCEE0D42B5F1535 -:106C7000F99551E144C7FF633479DA04787374B449 -:106C8000E7CDF8DA91C7E83CC4E1F15DE721E00720 -:106C9000F328C279A896B53A3DFF41445EBD0F780E -:106CA0001B3B3E2C139C57301EE227429E9201F460 -:106CB000FB911DBFFF24F2FD27B0DEB11AFDBE20FF -:106CC000F27D12B8F233408E51798676B286E71C97 -:106CD000EBDC8C1ECC74DF6863E724DAF1D5D00FCF -:106CE000F1E5557D5F42FF8D0A3B4FD258EF92D8B8 -:106CF000394196EFFB5E8686FC1A450E85AF520E33 -:106D00005DC843FB4CFB1794DDC9A1CB9CBFA91CFC -:106D1000FA3F681FCAE95A0EC5E7337839F2997C01 -:106D2000E94C0E25F076BDF225839F522787E2F3CA -:106D3000A3C8A107550687287C9A985F0CFE15CD3D -:106D400095CFF834295FA7D7E877C9D09F17BE4FF2 -:106D5000C5BC33CCB7F093384FB47D869AEFE86961 -:106D60001EB59A9FDA31FF8C749347BDE1D1900D27 -:106D7000E02DF29CC4B8E6FC6981C7AAA65523C8D9 -:106D800050C8D3BA3C08ECCAB347BE41FFC8DECCFA -:106D90004A0FACB3E5B55186BC2C31FE7DDC9F3685 -:106DA000412ED809FED973076DE8F79489FAD418F3 -:106DB0003A9FEA8356124039C5EE2910F130EBC1F3 -:106DC000BA56F0C75B89EEDE28DCCFA88940B7D67B -:106DD00083ECFE2692C2DEFB897D15DEB738DA1819 -:106DE000E74FD28C71FEE4F25EA6B8BF31CEDF670A -:106DF000B631CEDFD7678CF3F75F34DC14F737C6D4 -:106E0000F907AF2833C5FD8D71FE8CFAE9A6B8BF2E -:106E100031CE9FB3D918E7CF0B18E3FC0BDF7AD93B -:106E200006FBEA212FDC678AFF1BE3FD1420AD99E6 -:106E3000BAFB648AF6AE36B49F1762F7940D0BAEB8 -:106E4000357ED7C0EE39F0D3FF013CBF203E1BD0CA -:106E50009942C26FF687FC9680E409D2668BF7EE02 -:106E60002A817238F78B2FDC6CBC1F6171C058FF10 -:106E7000EACFE507210FAC1A9888F653FD82140873 -:106E8000B83BC7FBD2178CDF0B3FEF52BE9E73DCC3 -:106E90002838B745C6F3CC663A59F8D6ADFC5E3112 -:106EA000AD15EE8F107010F4E2E2F422E625E0B1A9 -:106EB000545E867C2EE020EED7AA32ADBFC37AF7AF -:106EC0006EC5EFCCEB36AF6353BE31CE473AF08997 -:106ED00083E509D175419C5CF6E79AF8C40887CE32 -:106EE000E0D753BE51391C62D28C7C13ABC699E9F2 -:106EF0000EF16D86677CAE919FCCF0747AFA45A551 -:106F00002F713F2AAE07E2217B25F2B4D411AE8B5C -:106F10009AD6D7F58F424F840430CFC30CDFE67C7E -:106F200063BC6597EA6B01F978FEA30B32E2D517D3 -:106F30001A01FAAC8BFCB383BC7D4FE3ED87F2758D -:106F4000FE1173BCFD2CE449EACEAB48ED78D34C7E -:106F5000799207FE0D7124FA8DCF067ED8728F9D2F -:106F6000DD1766CE5FF3FD331FF5B046D00F788E88 -:106F700078D6D0FED6387F3FA41BBFC8B1FC62963E -:106F80005F00FA6B6C3874FE25E85E6975C138D114 -:106F9000EE29359D3F3C0DDF77760FE4F3C49B4728 -:106FA000A2C4ADC5FE55D8ED749F74219FD9331787 -:106FB000A1BFF67D52BB7DDD753F228FACB352DAA7 -:106FC0002FA35E0D4B719E68F798C50E31EEFF75CD -:106FD000E73D6387E8F468D5F7CEBF09F3A0F07604 -:106FE0000CA1F3743AA97D23F5C8BE71413F4FC58A -:106FF00027205D87DF9203396EB8DF4A4DEC55D00C -:10700000F19E2691575803F73025C3F3BCC4AEF266 -:107010002FCA4CF76099EF33AA1BCEE695CED7392D -:1070200085DB5125BC2ECEA5097F5CF56CE66FDEB5 -:1070300064F263960C71627B6F665909ACBFCE2D0A -:10704000A1FD5427498678D2F1FC527CEFE1FD97EF -:1070500000EF15E3F93A9C578A691F7F8EB73F9777 -:10706000CFFA857BB180FE6CB21C159ED70D61F303 -:10707000FF3BB7A3BEC3FD34EFC78CEC783F8DF95F -:10708000FEC489B9352D201ECC71DFDF75773FCD69 -:10709000FB13A3C67F01BEF1BD22743F6388F19E3E -:1070A000C4609C6FC354F047BC237BB6E157AD234B -:1070B000F4FBB48A21CC2E5DC7F72D1057C2FD0812 -:1070C0002FCD70AAE0706AC8F45600FD6DB2B5DE2F -:1070D0000FF41BB4B1FB42C31F101CA7DF22AD1974 -:1070E000EAC55E15CF57D4B98903EE190A0FB3A0CC -:1070F0005F24C5E71A0FF7FEA66C917A0138855C0C -:10710000B02AC4EFA4F4B276881BF1B08EAC6986C5 -:107110007B5112B77C4DD2713FE11AEF0279348F67 -:1071200044F5733ECCE963DA33E90AECCB12EDD1D6 -:10713000EF79787888C863F33E04F431D67E6484AE -:10714000847A82ED43606B8BFF69B318CE358BF286 -:10715000BD8C717EF84ED0F3F532A9D9E56074A6E6 -:10716000BF7F6DED90ABF34F172F2251FDA8DBF9D8 -:10717000BA72546F03C0BDF87D15E31F0B85DC9F09 -:10718000672170CFE9ED9C1C6FDFC2F2E1C9E52BEE -:10719000576461C713EC9F403C62E1326700E21321 -:1071A0000B9BDC78FF1F592461DCA4BAE99017EA35 -:1071B0000B478E74A1BC8C9724B807124C08261F6D -:1071C00015725CD09FCC8144FB9FCDF50DD52BEB88 -:1071D000E2E9BA166ED9DA0CE72CFE410D08C0FFC1 -:1071E000267E6EDEBC2E713F5DE4FEBC4F36E9EFBD -:1071F000E7B6ACFAC707C6FBF3FEF1C17F737FDECB -:10720000BEDFFCE303B89FDB7C7F9EE0FB8F64DF87 -:10721000470FD37FDF4695F28AE1502A640EE229B8 -:107220000DD73983AFD3FF0D918EDB2370B9ADE954 -:107230002D84F747563A1E651E6B19038DF5A14440 -:107240008C2F8B7CA499F68609A0D7CFDAC28570E3 -:107250005EECEC6B1F0E84BC834F7F78DE097908EF -:10726000FF54C24E787EE291F79C1AC5EFA78FB00B -:107270007BB6EEE6FA52C0ED1F9C1E0A0BBC87815E -:107280001EEE59F96D89FEBE20B22215F5DCE280B2 -:107290008C292C428E2C7D211E2CB9F6FAF29DC928 -:1072A00086BAD07FCB63484D34BFA8AB80F1CDE226 -:1072B0001D5B6DFD5518DFD706E39F80C4694A3713 -:1072C00027F638D14E16F3A9DC31CC0676D53F9B94 -:1072D000624810F66B4AAB959D37D5A648945E7D03 -:1072E0009C2ECDF37CF3F578EC6FFE26266F2BE811 -:1072F000582B285C7D4DECBE4FF33AE67FAA4EEC4E -:1073000043E13DFF716AC1A8ACFD23146FBE153F78 -:10731000C2FC71F33A2BFCE6FB3D3594F70B397E4A -:10732000E7D61BDF2F6CFA31F6338FA8EB204F72B4 -:107330007E83F9FDA42F8048179AF2D16D055C1E5B -:10734000979051208FF7DB3312A39D3B15E5A9954C -:107350002E64A22F57DAB13CB192607978888A7096 -:107360005FD674E841A09FAABDBBF01EA696C0845C -:10737000144AD6E4C6A6DBF1FEDA1B79DCFCAE8E3D -:10738000F78BA6151443FE91E9BC375FF71C8E07F7 -:1073900071FE7B0EACB7109E2B17F4EB397730C320 -:1073A00001E3BAC5BA46D175C93D5F97588F589F5A -:1073B00078BF9CCACFA8F1704EE787B9BC9ED7387A -:1073C000ADAE1F05C59AD7BE40FF00E1FB92F6FBAC -:1073D00091ED3F6E85798F27A67D899FBC4F74F410 -:1073E000B69068783FAC99AE049EA9DEC6EFED7CFE -:1073F000DFD24E4F4D3F41B8087CC30D82FA7BA9C6 -:10740000285D19F609948E0CF5F90DC6FA196B680A -:1074100010F0FB42D3EF459C31E5D388D25390CE98 -:10742000E0A06A13E1DCD07CE2AD6379C7ECDCE17B -:1074300009A5E1CD87810F1B191FFC93E37F6781AD -:107440007716E09F285A21DE17B9BAAF0C171F57DD -:10745000AC935CC05F736B87E1FD43C38986FDDD40 -:10746000D589DDF910E7FFCA1A2BB15163A1928EBD -:107470000172AE728F2CEEFB724CED0DF7D7303EE1 -:107480005AFEF82E5B5F5A2EAA59C8ECA100E31BE6 -:1074900071AFB6A03FA19F96AC6B46BF03DD6F19DD -:1074A000F8AB1ACE8114021F9B9ED7DC8878A836D1 -:1074B000D945DF2BE0FB330FF1007DFA1E74DAE1D2 -:1074C0001C5977EB261DFD49E86F3A77300BEDE547 -:1074D00073AADA07DAF912D83DFE92E21B05CF292A -:1074E000BC508F8657C5E3BDC6472EC944C5FB5562 -:1074F0007CA3E0BC7FE8EF0309BBAF8DD1AB586F35 -:10750000B57D1DEEA3AB4DF45A41376CE027AED8E4 -:107510009E8C796AB4FFC2BD605F6DB7A2FDE4279F -:10752000F7A5C1BD1ADEC7D8BDBC957B93701F5FA0 -:1075300059CBE24B953B92F09C30DD47BF0FFE19D3 -:10754000818F23B5E36C7D115F6EBC2F8CECB5FA97 -:10755000F93DE748E7024F1DF7C1263CD537BF99F3 -:10756000A676DC17EBF0D4D6099E0CF758FE5AC865 -:10757000118E27F208973FF7BE910571B57335B1AB -:107580001E39CAFEAAFD3EE379D7623E9DF03F96C2 -:10759000F713BFAFE0E90D783DBFAE18F166C657EF -:1075A000F97FE6225EC8DF9D04FCD27765907BA65A -:1075B000D3E7F7488C5FEE5A33A91CF4F9810266D1 -:1075C0001FFF95CA2D2D879043546E69546EBD4799 -:1075D000E519D43F589986F50F57AA587EBC321743 -:1075E000CB366E170A3EA2846003BBF2AD0266EF93 -:1075F000BC5520FCC10FA4816951FE9FF78A2DE084 -:10760000EAF5CF9F3981DA3BB768467D387B8651F2 -:10761000DF85ACAE89707ED9FF38BB17AED27B9DBB -:10762000A13D5154DB34D8D7E78E883C477E536D5B -:1076300070FEFEF629C986F633EBFB1BEA470A54B7 -:10764000764F507986E1F91D738618EA15FCDE5BEA -:10765000A28E46BE7980E7C912329AE185E7DF5CE7 -:10766000A819D5E7FB74BE17DEB6E27B333E045E95 -:10767000E76D96898FF6377733955F748A6D0D14B1 -:107680004FF4BBAF3E72C2591952B763C4BBA36972 -:10769000FDC80E96AF7BA436F9A7603F1DD9919A1D -:1076A000007E635F9DCCED0C17DEF726FA1D57BBFD -:1076B0000AF3722A023178EEA2A2C5FFACA8C34F2A -:1076C0002EA089077CF3BE1C084A883FE6F7F875B0 -:1076D0000CC62D4E50BBCE45F5C40989D4420907CE -:1076E000C512E9FB7FB5A60680AFCBFF236B6940CF -:1076F0004FBF8EE5712909FBFBF250D6B6B5485F46 -:10770000EACE20F26F0CEE8FE686D8FA8834BC3FC2 -:10771000E0FF4412D192E82496DFF7E1670AC5D36F -:10772000E2ECD642B817678E3B983A8B7E77AAD1A7 -:10773000CAEEE9A7FDBA687DF96F62F8FD8F5A1F9E -:10774000D86F44E019288475A7F6F3A60EA5FCF1BE -:10775000E5824021CAB5475291AFCC706FB3F910A2 -:10776000BE7EE003292227237CC6E28D54B8F505AE -:107770007933D7EAE90DFAAA6D9D95DD8FA76809DF -:10778000ECFEC9DD48C76D8A3A11D6DD56EFC6FB5F -:1077900083C4B895EB648DDD5F49E912DAAF977D5C -:1077A00070DF8FD05BFE7AC907F70299E9E6FE7BAE -:1077B00047619EBFD9FE15E519CAAB3E9D1DB1E4D8 -:1077C00035197FD7838C0C29330CF783B1DF3F2128 -:1077D000BED186FCDB65E97FFACC6141BB2611F6A0 -:1077E0004527DF9791CE4EA63794A465403ACDFE4B -:1077F00092EFD3FA5753FDC7E11CF13D837D65003D -:10780000D7A59675CF4A1638777DECA770CFEE973F -:107810002F5A3D30EC925F2F1E8C71096E7F77944A -:107820005B9AB0177AC33D5115AA0BF5B85A2B11C4 -:10783000B6FE00CEF34EB2F331C09B6B197B7EAC2B -:10784000D8B916FC03734DE7D88EF17B3A660C6508 -:10785000F244E8FB0D4399DD34D7C2E89ABC2EB15F -:107860007BB4F8EF5F087D20E4B590FBF38632FB34 -:1078700042C86B6A39A0DC5A00B747D1752E7B210C -:1078800086F9D355E202382E6668225B873279B1D9 -:10789000C4F6E293C04B0B492BEAD32FAD8105AD63 -:1078A0006EF87E6B6D2FFCDEEA41FF32D72F70CD74 -:1078B0003FC8A5859CFF963748781F14E17A723E31 -:1078C000EF9FBC608DE88DF428FAC5A457E673BD20 -:1078D0003A9F98ECC006A3BEF3C6B3CDFE123A2E73 -:1078E000E8CFC8BCA8FD4C61B7C01778F3669CB759 -:1078F000E4094499C742120EC2BD58CB77307FBD10 -:10790000795EE675F4749E0B3CD3C6278DD48D6BDF -:107910009AB780373AB8757810705FE067F05CD03E -:10792000C4E21F9F737B4DC46BCCF85F48BC3743E8 -:107930003EE2C28D547EBA23F420E860F1AE00C668 -:1079400067BE220D090ECA07CB36EF9A798D0AFB66 -:10795000FC43B80F99D32B9865492224D97FE8C9F5 -:10796000F281DDC727FE577022FC7E71FC8EC26556 -:107970007E23BB3F5CD78EE7DDFB91AE17F9FD366A -:10798000F0DF2EE2FED0EEE659ADB073FEDDCF970C -:10799000C1F17F3DEF778776661F6545DD6FB5DB0B -:1079A00045DDE8E34FACC181A08FC30315D4471771 -:1079B00014CF87A529A09FB370DFD099BC5DC0F517 -:1079C000F27CD0D3B43CBEF965BCE7E9F38D2F63FC -:1079D0003CD8F6E2FC04B0978F6F9EFB53380771DA -:1079E0007CC75CD4CB0B9F167AD967D3EBFB719B1A -:1079F0002B9EFB21D0E90BB118C758D0E2E3F63833 -:107A0000DDD7805CA4E3A19ED8C8E4E042D05F0546 -:107A1000A8BF72A0DD830B7C3940EFBAE7A8D71E60 -:107A20009CEB1B85DF135790DDB3EA0A82FE12FA46 -:107A300055E8DD57FBFA2E0F053E92DFFEE0077496 -:107A4000FDA777CBE8D3592E6F1D04BF0FD3991C28 -:107A5000FFEEF0B6B4C3DBDD03785702BCD11E6283 -:107A6000F03E5ACFE07C6C1D837BDD8E8C04D80702 -:107A70001FADCF403BE8E88E2C84F7BCB514DE6820 -:107A800007AB463BA89EC21BEC7F80371DB7B245B3 -:107A9000E5F0F63078D7733DB48E95F33AC0D57FD4 -:107AA00037C895077F19E3C1FBBA6383A9B04F3983 -:107AB000B14B2690A7D16E27717B46C0F95FA4E138 -:107AC00059B0AB3AD837EB6308F87317FFCE89E7A4 -:107AD000A4BE944AFB00024E35FC2901C68B8CDF04 -:107AE0006ED7780A8B75764D0FF15345BC788EA111 -:107AF000AAE94F1F815D0FD72CC1BEBF4ADC8FB1F1 -:107B0000D7783F86A4824CC3F3B2763BD0C100F352 -:107B1000FD213EFCBD9C8B595FDF7D1FF273385BFE -:107B2000EF57AF8E0B5AC11F15DE2521BE973F5070 -:107B30009A504A200E5783F3985AC8F4B3A469E8C0 -:107B4000678CA1741347C7F3C265C2F05C7531BF7F -:107B5000E3163AAE33325FF3F39B4110817E7744F4 -:107B6000F753FF908FB35CB6E03E64998DED4744C8 -:107B70003ECC5D85CC6EB8AB90ED4BE616B27C93F7 -:107B8000B3903C45FB3D7B7D0CCFEF1E8FFE4F71CC -:107B90003F8222E0E652CE187E674209E3EFC07CC6 -:107BA00076ED21BC7FF733F8168D6B8A8012B06BAF -:107BB000D8F7EF5AD9BD2E778EFE13FA4D3F8BF5CD -:107BC000AA607F7D966AF7001DF9E11E3C4A7F3F5F -:107BD0008A63FE729292A8007FDDC1E5ED5D63626B -:107BE00034D04B778EF991174A3A8E1F821675A5BD -:107BF000071E033ABA27EDD8F7EC7449AB2CCC6ECC -:107C000059D58B601E511135DFC16F4B5FEDB992B5 -:107C1000DC15DD18FDDCCBC09F7B2D6104351AE13E -:107C200069A853B8627DC34BA5B3360E20E430512A -:107C300087029E97014C800E2A12D12F700BF89567 -:107C40007B41A9207D4D5788DFC2CA7A07DEFBC180 -:107C5000FCCC37F375DE369A0413E9FA826F118390 -:107C60001F7E56D012CCA170BB45093603FC2C7682 -:107C7000D50AFB026FB9341CF6CBCB56F76CBEBFEE -:107C80007A69CAAC8D6368DDC2F21CC23F90F09E77 -:107C9000963B2973035DDEAD90167938C31BD05D2A -:107CA000752F761F79F85E89C79398FF5FE0651896 -:107CB000ED5E0FDF3BF9FC683FF509F0BD2DBA5FC3 -:107CC0006937A753616F2EE57CBA54D0D90E237F54 -:107CD0001E167C02F62D85DB9DBCEC8CCEFFCAFB0C -:107CE000FF6B21F35FBD7695E32D8F2141FDEF56AC -:107CF00089716FE1E53B85CC6E16F310F44BB85FEC -:107D0000CA422506D0515BC31AB4971699FCC444E5 -:107D1000EFBF92A3D5DBE58EE50A94B6F03C988FD1 -:107D200074432CF2CB9DB69D59EC9E1963BBE50DB7 -:107D30008CFE973BEC68078AFBC5C53E40D88D8B0F -:107D4000C1DE037BBF91D9B70AB7CB2BE87E0D8884 -:107D5000CE4A42B5FD61DF5CAFB37F519E717FCFEC -:107D60009E613E18E74E871DE39F372F33DA4B564F -:107D70006E475A3BFEFE9D31AF84DB4BE6BC129949 -:107D8000F3316DCBF6313CAF44E1F6B0A0A30F0B5D -:107D9000ADDCAFE237C4F1E790562BBF778EF9F731 -:107DA000B89E9E203BF03E863912BB67EB6CA9D390 -:107DB0006FA172E9137ECFCDB91A76CE79CE0FD8E6 -:107DC00039DEBB121FBC19ECE239093605CA4FF87F -:107DD000EF7D7DEA4A4F9C4540FEC83CEEF4935946 -:107DE00010BF59037294D59FD2C6A0178DD79FF8A4 -:107DF00010DECFB84CE78DF50DB3343ADED937F845 -:107E00007B3FAD437CE831C1C79B597D9378BF85EB -:107E1000D51F17EFB7B2FA4F44FFBCBEDEF47E9514 -:107E2000E9FDCF597D70D1D6597EB0E379DC6ACEB9 -:107E3000B512C6AD34E0330ACF39AB83485F732C3B -:107E4000FB5959468210B7ECAEDDE422AF06FA5A70 -:107E500076B639C15E99314CC37AFE505F7E11C54A -:107E6000CF926992DF06F1CBF703D95C9F45CFC76C -:107E7000E7FA699287F527EC5FDACF88A2E2ABEFE9 -:107E8000E7A3A20EFD8CF92EFD34769CCF84EFB2D1 -:107E9000AED861C67E843DB86DB8E6837991F1D7DE -:107EA00019FC9C4B1FF524823D49DE65BFBBB574B0 -:107EB000F5CE412368FF4B5FDA376881CEFF5075FE -:107EC00049261A95C3D597242CBF6AFED806F74BCE -:107ED00054ED69B64D2C80DF0B6AB68DD3CD6B990E -:107EE000C833262165BACE9E995F64E17CC57E7752 -:107EF00068E94B2731FEBCD4B2F3F8D3C097D73230 -:107F00003FA4797D53F9779F417E4194FDCAD222E7 -:107F100026879F1EA92D01B84D0198D1F6E3D644BE -:107F2000CFD3D8C3FB9B13C7E4FBDC12A75D2D8224 -:107F300078B86F0D9CFF5BB0C53D1CFCDA5387968B -:107F40003D50D4A57F38CCFCC34DCC3F3CA757EB6C -:107F500003547991DFFE36F814DCFB3CF929D21E7C -:107F60004F06BF2B1E8747BEFB70D6F831E8EFC324 -:107F7000FA1345879E82F3DF07F9EF31DC356A6833 -:107F80001CC885903BDEE2A2FC3CA3A0E2B780BF08 -:107F9000BB465D3F119E97C638B32B589C01E962E2 -:107FA0004681772DBC87F6E0DFF1D998BFCFF76720 -:107FB00019FD7DBEC2785FB4FC857A0E87DF16B1ED -:107FC000F31B072D749EC323F310E35303ED815677 -:107FD000DA5FDBEABEC3E09CE5CE82D297909EF8E2 -:107FE000F83B0B7CBFD08F0F1409CF7B3A8FCD4568 -:107FF0004C9FBEC4F1E61D43E94D27F7A78F8F378D -:10800000D4674C49269ADEEF3CA3BFA13E7B4E8647 -:10801000A1FD1DF38618DE4F8D691D597315767FFE -:10802000B5D31907F9119F36FDEB6F77823DDB2839 -:10803000E3EF172D7E6DFBDFE0F7BCCED10527A364 -:108040007DAAA2FFEFCB83EC775889A229FA38D614 -:1080500069D2FA24C47D75F191A8F163111F59EA20 -:108060006AC13CCDFF368EF56E118F630D87D475D6 -:10807000D0471F0C823C952A075BD7E97D47F0F774 -:108080004C20CFE34A09C47F091A89D59756E1EFFE -:10809000C88DE3BF275D5DC4E473D5807B15B8B799 -:1080A000A09A9620FF2752399548E9A4B5990CDD8E -:1080B0000379DB6E27E6D52CBF742BFAF50FC6F9D2 -:1080C0000BEEA5ED96D64FC27AD5A578ECF7AF7238 -:1080D000EB44CCCF7F45C2F8C9D4FE77AD86F943D7 -:1080E000FBFBE978537F7B6339C0A96A0FCBBF994B -:1080F0002A1F1E09FD2C6B9884DF4F95C94189DA30 -:10810000498997EEC47EA7828D43EB7289732DE86F -:108110005DD916CCFE05C8159B13E54AF5A558FC9C -:108120006EF238A69F2F16B17D8B35C4E635E1D2AD -:10813000347C2FF07FB928DD709ED49ADAA8C07DF8 -:10814000ADD69084ED6FBA34044BB1CE3FE7FE124A -:108150007F9FCC9A7A6122E4DFFE394572A1D9650E -:1081600092BBE76B4625EAF7D3FF0F762BD097003B -:10817000800000001F8B080000000000000BCD7D78 -:108180000B7854D5B5F03E73CEBC9299C9E4C9843E -:108190002470024908106032791042209310109127 -:1081A000C000550906199047401E21BEE295FB67A5 -:1081B0004212088216B5BF45453A205AB4B6372256 -:1081C00056DA224E006DACFE366A1F786B6D502F6A -:1081D00082458DE0B5F416E5AEB5F6D999394382FE -:1081E000D0DEFEFF1F3EBE9D75F63EFBB1D6DAEB3C -:1081F000B5D73EB978117ECA19BBA895E6F332F31C -:10820000263276D37989790B18FB3ADF9BE04E66EC -:108210006CD6861EC592C418B3599C4F66025C92F8 -:10822000AF2ECF0BBF271FA961EA18783FA9D7E867 -:10823000B5C1FB504EB185EB1731E6ED0098B11E8C -:1082400065AE3DFCDCE53630968CCF9B192B827EEB -:10825000FBDAFD8CB114C66E7632FED3088D52194E -:10826000336AEDC5FBDD12D4C1BC022F98834FC227 -:10827000EF291EFF6837F4D35DC1E6EFC77E94EEA9 -:108280002173ECFF73F3AF9699454AA0757871DCC2 -:108290005925AAE15EE8CFDDB78E0095DFB68E0CDA -:1082A000ADFDAF65D6D801F3F8757979B717FAEB5C -:1082B000BCA7A04056C3E356B84D8417E6ECBDC03A -:1082C0000A195B773856BD17D6590D3442B8F725D1 -:1082D00073704F263D67521296E63D12D4AF73F489 -:1082E000E6F860FC292F5B436C2CF4FBB25561303F -:1082F000CE1B85FE0AA4E794974754490E98E421C3 -:10830000B3C2A0DD75E3BC9588B781E67B318A4FA7 -:108310004429D6CBAA261A583163B759F86BD3E64D -:108320004881B838C6FCEDD73206735D7C7E1E638B -:10833000C04F4BCEC712ECDFCE9F9FAB1F340DF169 -:10834000786E034C1AD6B1648334E600AC8BA97600 -:108350007736E0A13A6DE146E640BC1B68BDD5A387 -:10836000E3832DD0F4BA29F680218EE8D185F45824 -:108370007D3E9EFA5B733E93C6597B3E91E075E766 -:10838000AD542E393F9A9E0BFEF6217F437983C769 -:10839000BF1EF151DD72CD741CC7BF31B5D06F8BDC -:1083A000E4179313F90AF8C5B53C821F5A3A815F66 -:1083B000ECC42F8A17F0EA8332925F6623FDF31034 -:1083C00013CE692930EF59AD99867B59B8FE4EA47A -:1083D0007FD195F3FD2D1ABF2CB185B20DD09FB181 -:1083E000DEEADE08F33A9BA44E43BC346CE1F86B42 -:1083F00030FAA6D861DE0D8F486EA00CBBA5D86EF2 -:108400006180A7E2E3F5267F04BFD79C1FCB54C051 -:10841000C7BCF35954568FF1B722FD179FBF41A334 -:10842000D3582A995A62C0F9DC8E74557142259C42 -:10843000CEDAFCBEAC1F3FE82E18FFCB378C545F62 -:10844000E40DDC8CF33106CDEEDD309F5356BF8C4E -:10845000F43D95C19C0FC1144F1959C009F4BA6578 -:1084600087CC02D0FF5228FD509E8A67DE780FE24B -:1084700013D699CBFBBE08FFFF53D93E840D07BA34 -:1084800036FCFE7D6518632B73BAC786A0DFDA8AD7 -:1084900050F28DD0EF99BD467700C65DDDF976B11B -:1084A00001EA3FC9F40E6232A06AB07F17D275D5D7 -:1084B000DCE04F8C00DF7ADFF38E096A189F1D4ADB -:1084C000285B81F73B008F019857C736797A90F087 -:1084D000CF62E78C09F3B5E0E368FE5E757E38E1B4 -:1084E000E75CBD79CC01E45FE0577CBE46E3F35B1B -:1084F00091EF890F39BF0B3E5EA37079B5C6161791 -:108500000CC03A8C3DBC5DF5BF01FF01CAD71ED837 -:108510007D7F29F2DD1985F87FB5B64FAAE5B9BE92 -:108520000ACEFFEE1678FE62930B9015E6FFA9E7E0 -:10853000E750BBB8F337517F82EFA3E579C4BE6142 -:108540000CDE7B31DFFF16E2A9F2477F7BFEDFE125 -:10855000D10C2594F358129676E29F7F96DCFFDDCE -:1085600055F2FF31ADFD74335BE4CBE3723DB2BF36 -:10857000144FE5695CC7676E89CBDF7FB2BCFFEC47 -:108580002AE5FD1FAE50DE4BF95CDE47CB7706FDDA -:10859000A17CFFFCA5914194FFEF33D007A8F70E13 -:1085A000C5AA4F6AF29FF4434C5CF072F2FFD1C24D -:1085B0005BA4FCFEE5BF21FF1F90FF7FEF3E11FC97 -:1085C00018BD5FAEDBDA4D7A81BD283194BF62FF02 -:1085D00074C570BC748DE27A20BC6F24DA570CF637 -:1085E00055B614B96FF6DC5F8AFBE6F324770B1BF4 -:1085F00078DFDCA4ED93459A5E10FBE3D17C7F61CC -:108600007EC4FE58BD3F5A3F5C9EBF6E4AAA67A813 -:108610001F164119C95FE63EFDA0DF1713F2AF6ECA -:108620005F8CD0DA7F1B5FCDFCE7F3D5CC01F8AAD5 -:108630003A3FF9EFE7AB687E3A57FFFB4215E67326 -:10864000AE10F82833CC3FD7BDCEB8DD30DCEE7E9F -:108650009245F0892923D882ED2EB27AC463B43CC6 -:10866000147CBB05EC009CA7A07B574C206F7DDEE3 -:108670003F4FFEDD997F7576EFD2FC2B931F9B91C8 -:10868000CED8EFFF9CBDF8607F74655E6E1784E9FD -:10869000629E47765C08149C34305D8D3BF8FE1278 -:1086A000705B48117A3711F52EF0CB43FF08BF54A9 -:1086B0004F815F0723FCBBF9DE74E8EFBB1A1C781F -:1086C000773ED2E7861251FFFB1DDE2C9433F06B10 -:1086D000298DE06516C2AF061F3F5E85FCFB505F2B -:1086E0007D00EBA796C569EF332FBA1EA2FDFEFCF5 -:1086F000DF1EDF46FB793BDFBFFE1EC53726022E9D -:1087000004D81E019744C13B797B87D2C39C848FD8 -:1087100020DFAFD0BFE4E1FCE38BB04B8092D3E22B -:10872000D1AE3C2039EF05FA2F28FBDC84F40AAFE8 -:10873000BF87D6BFF690A4C11F1DF70269161CE0C3 -:10874000F0F1FC533B028AD61FE079B58666738749 -:10875000E495818EAB4BA4E0B0CC4BF17CBC4F3E9A -:108760008979802AD6BFCF4C8557F73EEE6F7A7F46 -:1087700018BD1F325FC5F83796316FD07669BB538D -:10878000A2DD058045FF80CB79B0BE60DEA5ED7B24 -:10879000B5F6DD068386AFAF7720FEBA4D029F1790 -:1087A0007678CB80FE8CC3FF957F617E208F4FDF74 -:1087B0001BB5FECBCDFFBD7CBDDD803FAAFEFDD04D -:1087C000E5F0F7C125F8D3F8A74ECF4F718AEFD85F -:1087D0003998475C92E444FB78ADCFBA0DFD803008 -:1087E0007F986B703DDD56D6C7CF7AFEB7D454C1A3 -:1087F000FAD632511FF308F93986BEF67C3FF4F100 -:1088000017F3E6023FA10980EF2779AC8F046C448F -:108810001FAA2738EB32FBA1230A2E8BDA3F1AFF5F -:10882000D3FE45390FF8C9EE47CE1478387E3E9511 -:10883000D87C9493DD95DC5EEC1EC6CB791E89EA6C -:10884000277A381DA66865774C041ED2C374869FAC -:1088500010FA2311EB263CD52469EB0E8CAC990958 -:10886000EBEE4EE0F5D5FBB31F099485E1E8FE661B -:10887000EF1F59837CD3D77F60C4BB88D71A0D6F95 -:10888000F3F6E7BE1BE0F250C27DB9861804A87566 -:10889000400AC8B0EE35C817FDAC3BCD73C9BE0A5F -:1088A00044BDEF355EE6FDCC4BDFF746BDCF8C49CE -:1088B00057F3BE46B79951749D1E45D7AA28B8569E -:1088C000C0419DFC137271C9C107DA52601EB7EE38 -:1088D0009350CD44F07309F1F3AD4EC1BF13DE45A3 -:1088E000791FE6E75282E776087E9DF808CAFF39CD -:1088F000280F4BC3F03C94170497D578C745EA8BF3 -:1089000049547F63BB683F99E005ADA2BFF2475071 -:10891000BE0A3A02FA6A70BC9A42A12F2ADEC5F654 -:10892000AB0EF1F737792ADFBDEC7ED81E85979D17 -:10893000517020AAFDF7BE45BFB446BDBF21AA7E37 -:108940005B14BC230A6ED7BFBF78A944FB7031F01B -:108950000312E2DBF6E5C39E3E3BB54F9F4A36B2BB -:10896000DB74FBEABA160E073DB36BDA6D11F07ECD -:108970005F8D266F695F1819FF01591B407D651CCB -:10898000405EDE3F105FE646EB5B5EFF27FC351581 -:10899000ED60A6B30B8ECA7AB853D6E61DB8F9DDE2 -:1089A000DBF3F0A18017D6A07F70DDF7F5EB02BFF7 -:1089B00055ABBFA9A6AA2CC22E6137119F88758A14 -:1089C000F6D3BEBE28E3783FDDBFA0662FD4D756CE -:1089D00086B2EBB14CE025E83519F5E63A2D2E3399 -:1089E000ED25D9877AAD362694DD106987B08E1CC7 -:1089F0005C67E73D32D127D002F4C1381B739B304E -:108A0000AED21917D7F814B43F7A8FDC887AF4FD08 -:108A1000C6C4149C7F6A01B7238FC60D4D590670DA -:108A200067EC22930AED3A374FA5F288ECDDD40BC0 -:108A30007BED379E5535B691581F47F8E9DEBFAC40 -:108A4000A619F6C13B1E95DEF72738530EA2FD7C12 -:108A5000AF913DA9E27CDCBB886FEE33E7A31FBD7D -:108A6000B879740ADA934BFEF79C69A9D06E499BDA -:108A7000D12D513B3616E7EDBF77AA09EB97B66AC1 -:108A800065E01A2A5FFEE6891607B4EF7D5C72EF97 -:108A900081F693BEEC787D2CC02BDA87BB913487AE -:108AA000CF1B9813C6F960C788A00CFCF8A1B5FECF -:108AB000D559BC3DC3F62B2EA86FCE2AC4F6B2738F -:108AC00023B43F09CFD11E3EB945DE23E1BC1CF6DD -:108AD00018099674F26BF54DB46BA1DEB9119E9F27 -:108AE0006C5B998276D649497548B0FE5E4F638DBE -:108AF0000BF865C50EB346BFC6D4C5B0AF171BFA99 -:108B0000F885F4C7F2780EF7EEBFABE64998FFC9D7 -:108B100047463810CF6B0BBC5F78501F157ACF7A61 -:108B200092719E5C4FBDFC8DBC08EDF15F9C59922B -:108B30008271BB0B1A1F1F3EBF24654984BDB3FC65 -:108B40005385E8FEB249BD1DE7F9724C8684F12CCD -:108B5000A07B22C6BD976A7E26F06FE3F3FDD83D69 -:108B6000BFF7C844A78FCC8DEC43D8549D5BAF9F13 -:108B70006207BC74BE28111D96327F0BC2ECA0E4C4 -:108B800046FA45BFFF9BB195D682A248FEDF4272EE -:108B900096FC0D80139FDF44FA906D800713A03C74 -:108BA0006A253FDDF8AC3568057C2E4DF24EC3F6E4 -:108BB000CCD59133D71EB14FB5F67F0CD8A9FD1F88 -:108BC000A13DFA7B7F0CFCC1CE6C97DAFD2B1CF625 -:108BD000001A1F1FDBED0AD2ED7DA5E9E4DDF0DE12 -:108BE000F2C78DA427963F9EBCA117D701FC95CD57 -:108BF0002E5D87BFC048F81D70DFB2EFD754E9FC87 -:108C000089872FBB6FC7143C5CB3376FE07DBB42D5 -:108C1000F36BA63D6EF4E1BE5B51645718E89BCA46 -:108C2000C75F7912F7C78AF5568F1926BEE27133EE -:108C3000D1B7C76E0F38A1DEEFB02BF1504E2CE04C -:108C4000FCB0B040A5728ACC148B87CA568CAF9EFC -:108C500085F924027CBAF1A187C7C3389FB0E00D23 -:108C6000E3017F6791508097B307648A3F32C5ABB9 -:108C700054833CAD635C8EAC79ED795305FC5A5757 -:108C8000BF6226FA812B83C60F7A341FEFA2B64C3F -:108C900094BFEBF823D0C3FAFA756CDB17F2586275 -:108CA0007B13EEDF351D51F5F5D77C8C719C754C2F -:108CB000F9A047C479611EF30AEC49274703E06134 -:108CC0001EC0103B5B6FCC61B0C41536D887B0DED8 -:108CD000293B797C6745A31C3443FB29893C5EFC16 -:108CE0005113D07F04AD3BE00478C5F7B85E5AC19C -:108CF000A4A0057EBD66E77A05F7CF2B1E8EA7C51B -:108D000012F3E17EF8D0EA1E82FEFDF2C7AD84DFE9 -:108D100015BB56FEEE1178AFA7B93A29D29F5EA9CE -:108D2000F105F4CF2C09E17E3E6EFED7212807A77E -:108D3000FC00FC6258EF8A78F6939A4CA457EA102C -:108D4000D5166EB762E33D39BC1DF8D5B0EEC55BF4 -:108D5000641EA77AC14C7A1264838BE4B886CFA5CF -:108D6000ADAF994C7928D7B775CBD0FE0380651B82 -:108D7000E12BA0E1D184F85A84EFA6F2775CC59A82 -:108D80009DAE92DCF1E3FA6A0DD2A2B9A4077A4D46 -:108D90002807BE5FC0EDDE6D5AB97888FB668A434E -:108DA000DF6F76A35CC31F59CC03FCB03586EEE5BC -:108DB0001807663F35533C655DABD56B75909FE2F8 -:108DC000DD8FF3539862C2731795CB97EF6B7CB826 -:108DD0004E9D730DF20DD41F57A07E8D9DCBD135C6 -:108DE000F180776ED77A0D30CEE7F8DB70DE6FEA70 -:108DF000D888F125ED39F4A33AC2FD7619583BC65F -:108E000065B0FDC8B188C7C41BE6E3FC7E2CD37EE9 -:108E100086C5DF5F8276E18FE502F487176F393A06 -:108E20006D07C2CFE53BB1CBC53F7987F4CCAD1A16 -:108E3000FD7BD03F40BD03F073507668FBC92FF334 -:108E40003851878627C107A27ECD16238FDFB799B9 -:108E5000C9EE59D3FC7BEA778DBD3B05E5F59A1742 -:108E60008CC528D79FD7E6BDA439A3EC38F0D5121E -:108E7000639C538247AB03D52684576F97080EBF78 -:108E8000973C04F9F4CFAD2F3A907F3EB486B251AF -:108E90007FF5AEB7BAF7E002B438DD9F5BB3F76099 -:108EA0003C67A9B3DB2E41FDD2DB8727A0BC7FDF67 -:108EB000193261FDFB1D990684BD4E6719C25E65BE -:108EC0001CC17F0651D6A1F9ABC86F6B254EE7D503 -:108ED000CF1E350D83F18E17F0B8F9A73F7E270717 -:108EE000F5DB9A21DD39A887800F72D210CFCF48E9 -:108EF000A4BFD73E2B7BAD63C37CB016F900F6DD73 -:108F00002A8D0FD61E78F12EDC0F6B91FE9E4BF949 -:108F100008F8F4183DDFBF7B1AE3EF1F433E117AD8 -:108F20000FE05623C6DF4C1A0CE320FCAE864FA898 -:108F3000AFE2F581BC7A1E5733A19DBAEEA031D0C5 -:108F400013716E34109DBF2AD0CED19ACD2477BF35 -:108F5000D2D6DDB3E50507D2F1D31F1F7D15E3C5DA -:108F60006BF6837657FBD9171A5ED6211E1CB40EFA -:108F7000B247D6E1BA1D613CF4F1BFB61FD731BE8E -:108F80004EB1EE758A860751AFBDFF176D9DAB9947 -:108F900086B70323F8FED3F61BEE6794AB627DFE23 -:108FA00004FEBEE0D3F442BE3E6321E7D7D5C0172E -:108FB000EE3CE21FAF49C809A8FAF4B9DD142F123C -:108FC000F412F31E5BA80A79E78D4F08D3B1C7C02E -:108FD000EA3AFA89B3241772FC9D681B34E420E056 -:108FE000EDCFE097A1FD85FCAA448C27F8468C378D -:108FF000E5477366E07AA1FF10F62FC67D3F10AB00 -:10900000603FEF33BE3F903F517E8A7D39A565E1D9 -:109010008C7C07B6FBD43E3C0FD7CBC71F5BE8A4C4 -:10902000F7BD682FC0FBDE8312C5AB4F687180139C -:109030006D2F3A9644E0294F7B4FF019FE601C4B90 -:10904000CCB72B81C77FA3E72DE49098F794CD3759 -:10905000CEC0E762FE825F057F0A3C0A3E651B9236 -:10906000C9AE89E657E235A157659DBC27FD784D0D -:10907000FA1726BFEDD2E7D1709FFDD4EA3A9615D4 -:10908000A1D73FC4380FCA93A7E520C913065C1BBC -:10909000A17784BE6F5E7F8D13CF198DCF4A6E345A -:1090A0007D22F4CC362542CFD415AECF417DF6607B -:1090B000E1302EF793BCA7919EAB4F754F73A8611B -:1090C000FB75D29721390EE36107323D917A75F530 -:1090D0009963B40FD6B0EE4DE87F2DDEF24EF578F1 -:1090E000E4F7A78D74EEB9B86DAA09FD81954FDE3E -:1090F000528CFCF441FB7092EFA7F71615107F31EC -:1091000067CA0DB00F96EE7DE88605F07CE941D97F -:109110004D721EFAC1FDBBF88E0226D1BA7BAAF1B0 -:109120003CB5F76ED98976FFC4278B3660FB89F68C -:10913000A1F1B80EEFDE4482BD4A1CE909612FBFE0 -:10914000AFC9CB1623E78F0DDABEBAADAFE4FC335F -:10915000A5A52507CFE37B77839CC6736993DA11B6 -:10916000C2F15E1A447EC93A70A35C40FF5312B745 -:10917000CFEA4CCC92EAA1E7965478FE9AB1FB0E66 -:10918000D427AFDD61CF6FC609C8178A97707F9269 -:10919000E60176348D2FF026E6714F21D74FD1FDB1 -:1091A00089F7BBD0FF40B9AACDFF74EBD337A03EFF -:1091B0003CBD2F3B01D7FDF14BD676B4AB3E3672AA -:1091C000F9D867EF048D1F45DA6B60DFE960B0E71F -:1091D0007430F0F1477AFB7023CDEBBE429BCE9EFC -:1091E000137C5FBB3E3B2E320F21DA8E6759D1E7ED -:1091F0003DE3E3583F724794679A0051C0A873D08B -:10920000B68771AB62BF7EBE1BEDFEED66A719D6B9 -:10921000F911F23D9E67BD2007F1FC066D74DC0775 -:109220001F3D971F44FF73F97BFE69D8FFB10736D6 -:10923000539EC232B033074911F6F3F71EB801D975 -:10924000FFACDBBF2915DE3BBB8FE75540B52DCA10 -:109250006E7E3555FDC7EDE62BB597459CE2E7855B -:109260009ADDEC666EC4B3C0AFF09F5E063E28F197 -:1092700084F1F559531DD9CB679AFC547E2E9DB8C5 -:109280007F22F2AF3DCEBD075EFBC5C187E434A4AB -:10929000F381FC0BE82F97DAE29CB86F3F6B6AA46E -:1092A00043CB334DF5540A3A8B38DDA4039DF4DEED -:1092B00067070B0E4D84F70EDBE2B81EB8E49C88FE -:1092C000D3333A8FE4B6F5E307E173B1AE4FEEE680 -:1092D0007415F3FE64DF2D0E5C57E7638987262043 -:1092E0003D63E39C68F7ADD0F2474EEEE076F5299A -:1092F0004BDC533331EF64E7BC1406F27659E77761 -:109300006EC0E7CB5F929CE80FB85F9AE3C078EB42 -:109310007F283D0E2796F05E08E7A304659447A5D5 -:10932000D3199D63958614A666D2D130F1CB8433D0 -:109330004A10F34EFE8CE75B1847B910437114A630 -:109340009D5B2DFB198FBFF4F9B99A9F37515B775D -:109350004A5102E76FEDF99412FEFCE39DCFCFC2B4 -:10936000FE4EEF353A71DE9FED3552FFABC03F3315 -:10937000C07C4FEDE37ECFAA0E89FCE5D3FB406FA6 -:10938000C3BAD6AC377A4D7197F2E114A8EFB18524 -:10939000F970953748FCCD347EB4C0BF8BC32EE541 -:1093A000C778D6B109F1F18FF2A5AD48EFC7F5F155 -:1093B000E3407CA0E10BF731F2A3A0F72AA00B9EBB -:1093C000CF2674E457205F09FA0B3911A864B9A8B5 -:1093D0005F5B4C2C17F37802861837EEEF3936D5E1 -:1093E00028011EE625F554A138BDBB88CB49798AF2 -:1093F000C16B40FDD2622639102D47B28BB8BDF447 -:109400002CF234FCAF2872723B8AD5933F224AD0AB -:109410003B19A8C7E7C426FCA70A4D3C2F7C7F81D7 -:1094200002F39F3331E18EE16EE09B171E5FA000D7 -:10943000FFCE2948786118C065453B393C2EA1C84C -:10944000087073F3AE055500D71479DD45C9E17195 -:1094500044BFF0BC009FFF7CB4BF18CB75261BC96E -:10946000E9CFA5DEB18D99E1F66F49ECFD5F48616A -:10947000B8C7C886A09D57D137FFFECB8D45DE7299 -:109480003EAEFEF912C6DA28FF2EF0CBE312F7C784 -:109490007C9614CA6323BE5A62B185C8AF6F379EEB -:1094A000E9A337F2913B4E41BACED2F868B612EA40 -:1094B000C4F747B256E7490B99523B2F260E2CBFF3 -:1094C00061E3B193A23FE097CF8DB05EE06B09D826 -:1094D000B311B68C0448AE05F9251DFAE55FB1DF7E -:1094E0009600EBB1121D6A9DC86712F31B2E42B99C -:1094F00026D63116E3276B62870491EF1B5EF8F4E2 -:1095000018B2D74A61BFF84B88DF6F77F2F5307F2A -:1095100029F1E31D1A3F7EDCC4EAB360EBCDEEEE29 -:1095200076A830E933B34239B8DFFF34C45F5784DB -:10953000FEFECE96F406E09F4FF79BDD33A1FDA91A -:10954000E0F314BF5BADD9A56C6FB2B6EFE550394F -:10955000B4EBCA1CB907F54B4311D7D76732434365 -:10956000EE41B991C9FD2068477972D3375E938C7B -:10957000EDCE3CB7396B19D0CFACB0803D814AE617 -:1095800080755F0B7D97006C0458A673E020D10BAB -:10959000DB3950DFABB7B8789C9EF950AE087A093A -:1095A0003A5C421F9802DAAD060B33E2FC47B29DEB -:1095B000CE93B1613A7D6C013C621CCD027884FD92 -:1095C0003D15830F85884F1E7769907A5A1311FED7 -:1095D000B144797797EAC1274D88F2BA9DB790FCDC -:1095E000117247857FFDC99DAB8E1FED9CD2AFDC0C -:1095F000790CE50EAC83E5B3FC8BDC4024FAAED0ED -:10960000DE9D2AD7AA0ACE3BD9E2C6B85AC3E3C325 -:1096100049DFB00BBF217F58B4633B13895F3665C8 -:10962000CA84F79507259E1F79308DA95035F360C0 -:1096300022958EF3A9F4FCF453AF1772B9C4E95222 -:10964000FDC3419594AFFAC311548A7934687C37CD -:1096500055CEEB08A11D61837900DCF01AD75B0DB4 -:10966000D7CB14DF6428A2539098FCC7676BA73848 -:10967000908FF5D9F9D245B2DFD538A48BAF4B66C0 -:10968000C83FE07504389E2DCD8867B3CBC0D47E2B -:10969000EC0FB34627AB1AC3D408FF43098CFC6E0A -:1096A00019C665BF637407A1BEC5EAD883FB8905E7 -:1096B000BCDDE847CCD7DEEBB672FE88CD4DD0BD21 -:1096C000BFD931AD0BF96DBE97EB1DBB7BB06E7C86 -:1096D000B3BCDA884CC6FCDC5E14FC407C09E3CEEB -:1096E000F649A45FAF9F0FF511FD1ACBBE20396E6E -:1096F0002CD3DB99669FBEDD1F84DE19C94646D296 -:109700003F8C779B17EDF4B35E3BF13168F7EF9731 -:10971000017C439791E17ACD317C5D671153181F2D -:10972000F5CA418C9B6C463CC0F3B8123D3EE3BD8C -:109730007AFC254ED7E323D9A75FFFA0F9C374F5C0 -:10974000A9FE51BAFAB43A8F0ECEA82FD5B51FDABA -:1097500058A98333033374ED87B7CFD5C1D9DB174D -:10976000E8DA8FD8B144573F32B84A573F7A5F831F -:109770000E1ED3F12FBAF6E30E6ED4D5E787EED5E1 -:10978000D517743DA8838BBA1FD5B51F7F7C8FAECC -:109790007E42CF33BAFA89A7F6EBE049BD3FD7B591 -:1097A0002F3F7F440757B0D775EDA758DED1C1537F -:1097B0009D7FD0B5BFC6F5A1AEFE5AF5CFBAFAEB84 -:1097C00072CFE9F93586CBBF6AF7DF74EF7D9EE68D -:1097D0001F558C3A533EA320DFB62C945822C6D591 -:1097E000BBE659500EE4156B7248E3C3E1453C2ECD -:1097F000C1B2D810946753E5990CE376673BB87F04 -:109800003D90BE8B0375A5448C1BEFB58003198674 -:1098100013A73B7570B2CFA56B3F68BEAAAB4FF5DF -:10982000E7EAEAD3EADC3A38A3BE44D77E68A35716 -:10983000076706A6EBDA0F6FF7E9E0ECEDF375EDDD -:1098400047ECF0EBEA4706EB74F5A3F7D5EBE03114 -:109850001D8DBAF6E30E0674F5F9A1765D7D41D74C -:10986000761D5CD4BD43D77EFCF1A0AE7E42CF3ED8 -:109870005DFDC4531D3A7852EF415DFBF2F3211DAB -:109880005CC15ED3B59F62794B074F75BEAB6B7FF2 -:109890008DEB84AEFE5AF5B4AE7EF59FDD213A071E -:1098A000F8053F57BB2EF70B5DBD3109EC5A8C43D1 -:1098B000B218379E5F0AFBA7DAFD575DBFF7160F98 -:1098C00023FB0278A9C72AA37DE4A3F85102261638 -:1098D000025FC6811043BE4257A196E25049A4EFF1 -:1098E0004835A99827047602000986CC4CB4A763B2 -:1098F000C3765BFAC5822BB7DB76409F388F5F1645 -:10990000FBEF2B4E467FE5B96968B7AF64814D38F0 -:109910000FD07B713DB03FDEB4EAE319A2BCD602A2 -:10992000F88918EF35EBF674CF65FCFE6B2D67A850 -:109930007D5FBF5A9C4382F53544F47F3FF8150A9A -:10994000D875DB9B60FF80C3F8609393E0EF35B977 -:10995000087EB849A57247532E958F36B9A97E6700 -:109960005309C1BB9ABC04079BA653B9A7C947CFEB -:10997000F736CD27F829F0A3B1DC077E3596CF80E6 -:109980007F8CF5CF82BF8CF04F9A02547634B5D3DA -:10999000F3FD4DDB093ED0B483E09F3605A93CD8EA -:1099A000B48FCA9F377550FDA1A683041F6E0A119C -:1099B0001C6AEA22F8485337C1C79A8E13FC6A53CF -:1099C0000F955D4DA7A8FC55532FD5BFD1749EE0D0 -:1099D000335ADCF6956249776F4AC08C55113F08BF -:1099E000FB7016DAF9C81C25C6CF74767E94BD1DAF -:1099F0004D8F4FB4718C95602E62FC7070CE9E9628 -:109A0000083FEB2D6DBCCD312C6005F9D66CE07EA6 -:109A10006D7302A33C6EA6D9AF2B34BE6449DC6ED5 -:109A20005DAECD6B85C6FF45C89FB9C49F6F5C8D89 -:109A30005F21FCC65163FC27883F330C01F29F6D08 -:109A4000C11CB49FABC7F83F42B97EB67ED9AB34D8 -:109A50009ED34DE78FD5E650F28D181F794DA6782D -:109A6000DE40E3ADD3F2CD07AC3F7C3A1DEDEDE92E -:109A7000DFC87EC4D39B46FB7C8C17FCA598FBA754 -:109A80007F2936E8CA77C6F8BFC2797E65AFBFD9ED -:109A900000F3FF6AF2FAA76ECB0CFBD3B3D1250516 -:109AA0003F680E538D94D7C8BCAF644257D78381AB -:109AB00085F08D2C40E577F2FC17715D35608823C9 -:109AC000EC2F350FE96F5DD1F38A19CFE71533DE3F -:109AD000A02BA5B17EEBF8229C9797E6F5E6846B68 -:109AE00072705D625E956355ED3E44EF2E9CDF57CC -:109AF0002F7D71521A1EC6BFF0DB375568F928EB6F -:109B0000251E9713F69A96CF22FC8EDA3BA420DA14 -:109B1000EB0BC1DFC173A6F734FBF33D2BD7CF6747 -:109B2000EB8D24276BA518379EC79DADFF0F1BB289 -:109B300035B467785ED282894250DFF2AF12F159B4 -:109B40002DF463807E8AC666D27A6A99C58BFAB88C -:109B5000F6907937F26B2D987FE867019FE48C4788 -:109B60003E9920074C6007BF6908E648742EBDCCBB -:109B700024C1FC5624017F0C1B980FD66AF719C428 -:109B800073E02F37F6F7D9CFC6E7521CFFF0041564 -:109B9000F1D562E0F79802BF92DD3C3F868B687991 -:109BA000E2188A4F32C5EDC6F852B576EFA5536676 -:109BB0008DCFF5233FE78EE7FBEB4D97717A90FA57 -:109BC000D59FD7CC18CFFDD0195ABBEA23AF65E09B -:109BD000BDADB55D46F24358614F9ECFDECF7A1AD8 -:109BE000B7DE9915C1D7EB0E9EE0F91AAC272F32DC -:109BF0009FFD56AD5FC147B2C9EEDF6D8B9C1F1F45 -:109C00001FF87A0EE2E1AB78E0EBE1C4D727D1CEC2 -:109C10009E6556E36E84B207501482D2FF0327E597 -:109C200027893CA5A5CC47E50A6003E4635FE00112 -:109C300013E27F15EBA0E76B4B6E1982F03AD65B0F -:109C4000E5423FA2BDF91517CC72DEF607A6625CAD -:109C5000766E70F12B58CED92B9D44BF15F6C512E8 -:109C6000E4E31EA9BE6D308CB7E0D98AB634783EE5 -:109C70004BE6F460AF737A00BF78E5844BD709FBFD -:109C80006015ED83782FAD43764CD7ED83DA8DCC1C -:109C90002B2585F3EDFBF645C9AD7F4A433F48E9E7 -:109CA000A5F3F77587CD0948E7558CEBEDB01D2876 -:109CB000F435B7036E053B00DB7DA2F1F327198C69 -:109CC000EE357C228163E709DB916C88DFE5191EA4 -:109CD000D6BB9F1882C58EE1A4979B71BEAFBAE632 -:109CE000A9182FBB35C9E296B13E3E38849FA3F632 -:109CF000C9777631361CEFBADFC8E34FD1F3924A09 -:109D00005EFD2BDA0D66130BE0B906EC6B568CFB8F -:109D100079B089F6590BA216E366953EB5BFFE5B96 -:109D2000B57EBBBEE6FE6F00D683F77C2E19C7A9B1 -:109D30008D13C3C711FA03C723F991C274E3ED1958 -:109D4000CFF7F59B762FCDBFD9104FF2E60F43FD2D -:109D5000BB91EF44DC47F8855D991F6791FF7EA1B9 -:109D6000251DED73E05F9EC73899CBA5378D6A003E -:109D7000E1372B3229EE2FE4EDEC121E279B2DE26A -:109D800062655171B1A8780C2BEB3F4EC698DB8809 -:109D9000E38E64EF09FC501CE6489942740F00DD25 -:109DA00031CE7C44F34F2B62B95F9E509248EB4C0E -:109DB000B8368BF8CD91C842740E659789DF8EB2A4 -:109DC0007C5B42849CB8578BAF6E033B8845C4D5FF -:109DD000EF2D6CB060BEC1661BBFFF785F654C5D48 -:109DE000647E7CE2649EFFF2C3C915AC04F0976701 -:109DF0000B5692BAF62A2AAE47D2D637DA09F83786 -:109E000060D73E2D4EEAB6F0B85415E96B41F72BFA -:109E1000D5D7CF28C18D31B8FE2446FBD0BEC34A6A -:109E2000F254EEF08630557BD9E4B9EF223F33C5CA -:109E3000978BE37416C7301BB4FFAAD344FEFD61B1 -:109E4000C3921F9870FFBD6B6678DED9614F535087 -:109E50005F747C3DAA8A4AFBC4698CC739630D20B4 -:109E600028F29DEC897F43A269F7D54CAEA3933EBF -:109E700002147748AC8B51DCCD1B6B009FACC3C088 -:109E8000CE95C3FCF6DB3C0F8D2316F4C9B8DEA1DA -:109E900093FC9F227F15B37A82EF33F9EA76C3F8F9 -:109EA000F72558886F3CA906BA3FC8FE6AA3BC1FB5 -:109EB0005F97624415F76299FFDCF808BBCCE73284 -:109EC0001831FFA7CD04F23B0FE32831FCCC8A7197 -:109ED0007BDF773E87E6F78D264F5B5DDE6EBC88C5 -:109EE00032205E9D4A6F5FDC84F8329DE27D02CFB6 -:109EF00091F47416EBE8E93746D2B304E8392692B8 -:109F00009E5EE96AE8F90E26A1155DCAC7814AF589 -:109F100081AA42AEFF30952E9A8F2BCC936C980776 -:109F2000D3E9900D48D7CE98B43C8CDB093E167C23 -:109F3000DD0F3FAF3F8A72255D71E279B2B93A8693 -:109F4000CE67047F0BBE9E5EDAC7DF8F95023E1799 -:109F5000DA7C5351F644F337C6CF22F9B876407E07 -:109F600067CEC87D3E0BEC8DB804B4934EEDED8802 -:109F7000E0E3DAFA2F142E772E96C71487E37DB329 -:109F8000CA24F64124BDE1FF07B9DAFAC84E52C827 -:109F90003F1378BD52FC1BBFD39C8B76DF26BCFFE2 -:109FA00008F86A97DCDE411807AB3F711B3E6FD3A0 -:109FB000EE2507F24CDC1ED3F695E86FD9E4CA69AA -:109FC000B8FFEDE3CFC42E87765FA51854444E9BAF -:109FD000BAE4DF689F1E8F65F89E23B1BBEE09DAF5 -:109FE0007723189E277EB5D23F14CFF7B7009D3E4A -:109FF000A0A4EDE020039D7DF50CC27D07C875F19E -:10A00000D2EFE2CF99561F24F80F138669E78C5ED2 -:10A01000AD7D0FB5DF62DA6E89C171322DCE3D1193 -:10A02000FC5FAEC5E35B4BC4FD9F1615F3DF5A4BD7 -:10A03000B83DFB50D3BE491F65E37C3A267D04F34F -:10A04000499C19647EE0EB98DC808AA923966FA670 -:10A050004878CF818D621D18A7C7E7CD63C2FDAFD9 -:10A06000D4FAB5A09D03F4B36C0CA89172D662909B -:10A07000FCFDE5C9FC718242FBD5B29151BDE5C83A -:10A0800023F4FD80C42CB784F9D5968DDB199EDFAF -:10A090005843FC795296575A1AD16FD24C9877048C -:10A0A0005F007F05E2402E59F6006316221D6228EC -:10A0B0005E193DEEACE4CA2EC531309F44F31BD38C -:10A0C000F84DF08D5827DD8089F80E40D5300BE92A -:10A0D000C9B646D36EB4CF7795C4135EBE4CAA8C76 -:10A0E00063FDD8A7A2DC057C1030A33F6DA1720FE1 -:10A0F000F8E38111E84FBB087E0AFC712CF7813F21 -:10A100008EE533E08F63FDB3E08F23FC13F0C711BE -:10A11000EE007F1CE1FDE08F237C00FC71847F0A50 -:10A12000FE389607C11FC7F2E7E08F63FD21F0C735 -:10A13000112E37037FE07A7203AEB940D7F6BB4DDC -:10A140005ECC33FC6D0997A747BDC312DD407F6B22 -:10A15000AE8162E5D6371E64B81EABCB40F7CC3675 -:10A16000B91E64B7A09F5B6C277BABEDC7DC8EB1DB -:10A170002A0F31943BBBA4401D73C3782537D5E229 -:10A18000B960966B7D6502C0474A16EFB4C0FEC841 -:10A1900051E7CC6F8E8055BB67D573CE303C346FA2 -:10A1A000B7029E0CFBE5C15B76E215239C07E61720 -:10A1B000BF55B2BC16F3EA43C318D923BD9926CACA -:10A1C000E3598AF4CAC6F9F373C0EB588B0BCF3945 -:10A1D00087AAE02D49D49EE24C57DAFEB7252A3DE6 -:10A1E0008F7EEF72ED0C8557D48EC997E90FEBA5E2 -:10A1F000CBF46391E659BA61EE5B8D9A9C4AB691B5 -:10A200009C6AC7B80FE0BDDDCACBFC52BECF8DA59E -:10A21000950F4F80F2E1099CAEEDD680B312C71FB7 -:10A2200063A03C07D698F9CE3018EFCE5F290CF327 -:10A2300045057F9ED1F8207BA89DEBEB7B2C74CE4F -:10A240007FCDD01FB726009CFD84DB8DF9105B9974 -:10A250003B06F924B0CD4079913F2A1C9E30079AE5 -:10A260008F2E7A2101E5FA8C097C1E412D8FA8B929 -:10A270006DF9508C537DF51697877FD3C6D96DEC59 -:10A28000AE277A16D918CFCBDA4EF648B30B880D25 -:10A290003AD390CA4B93D1B900DB99C030C0BC6DA2 -:10A2A000D3D7E32DE80FB69C374FE779B5DD649F30 -:10A2B00098AC7E673C3CDF1E30905C68516D940723 -:10A2C000B7D5E6E9C27BD301A781F265B7E61908E5 -:10A2D0008FADB61B82E8072852731DEAB1A073BF89 -:10A2E00025139E07F30C94FF18F4CE9D8E70C0CFFB -:10A2F000BF47413F58EF4FA0FBE25B59EFEBE3B0A4 -:10A30000BE96DB696D29FF752416E3E2D73BDDFCC1 -:10A310001886A9983746296406F4C77B36C6E23CFE -:10A320006A98E6EF06C8BF759839FDBEDB79AD7354 -:10A3300018D91911E75D668CE1B92D6EA81F6BF372 -:10A340004C47FF53B17B2C9817D8EAF45816D3FA30 -:10A35000793E1BE56B40BF2D4E03F9C1587F0BEED4 -:10A36000F75646F97083B5FA56DB839D880F651959 -:10A3700063992ACE4F09449E275A869775A9B08EB5 -:10A38000F6E509B40E457213CC962934EFC16A0C78 -:10A39000DD937EC854DD85F6E460CBAD74EE955A4E -:10A3A000A7E8CEA506F9F570F27C3D9CC894F0B9FB -:10A3B00016F2D9041197D3E32D1A1FA9CED6B77080 -:10A3C000FEA97EBAC47BC9FC1F717E2FBE82E13C10 -:10A3D0006D34CF14DB920AB49B9299AF19F9EF1F39 -:10A3E0009DE758E75C4B268C3F36C940E6D138D60E -:10A3F000BB11FBDDAAF17B7B26A767785FC9625F93 -:10A40000364D48C6F305033874E1FE3303E0D8E95E -:10A41000CE17127470F6F6C1BAF623760CD3D58F28 -:10A420000C8ED2D58FDEE7D1C1633A4A75EDC71DD8 -:10A43000ACD4C1F9A119BAF6055D73757051F70274 -:10A440005DFBF1C797E8EA27F4ACD2D54F3CD5A025 -:10A450008327F5FE8BAEBDB0EFA3F5E3DD13B87D2A -:10A4600071B576BDD93558F7DD9C68BF21DAEEB7F6 -:10A470007CD3A26E447E7698889F15D4E7780E7DB3 -:10A4800037F79F2C93DD2AE5396BFC5854EEDD84B9 -:10A49000F2B4C26121BDA0D8783BC5368DEC9521C0 -:10A4A0003B4CF43D1FC5C9FAEA63513E37052665AA -:10A4B0006587E76D756E67B87F2B1CD319E6298910 -:10A4C000F715A797F9318F1B3FD28376923340ED72 -:10A4D000AC2ABC1FB18EC30603B3A11C073F0FFDFE -:10A4E0008381FC3AE1CF09FF6D20BF4DF86B430C2F -:10A4F0002C06CBDD52CF6DE8DFE7D5BF553988910B -:10A500005FB70FF9F53EBC078EFEDC586E67B5A548 -:10A51000CC5031DED39ED9D1350CE7936CA0382ACC -:10A52000D8CDEEB911F6E2DB9AFE5186B5F7A0FE62 -:10A530006B88B7A8682F2996DD933E027CED32F632 -:10A540003C8DF18B56C9B9BA03E5E2DD36CA0F7905 -:10A5500048C39B6A37146C847E3B9ABD0ADEF7EFD2 -:10A56000D8C2DCADB83F922A36C6C3F3ECF4C506B8 -:10A570000C138DC86ADE88E5B109FC3C6864DE6EA8 -:10A580004322D48F2EAC988F7131D9B99BFCD981DD -:10A59000F84976EC60B81E96A59C44BE42EBFE22BC -:10A5A0004CBD2201E80DE35A91DE12958407EB7948 -:10A5B0005BD08A7016C78BD52B0563256EB7627E7C -:10A5C0005D45C20EA2AFB067D1CEF5737FF76DE4E3 -:10A5D000A3A4997ABA2A96BD848FAD06BE2FDAE37A -:10A5E000D537503FB7676625B4A8E1790AB9F24775 -:10A5F000CD0E17CF855C998D3938C961FB06F87C83 -:10A6000007C6E7ACCA76BAE769DDB09D215F5BF1AA -:10A61000563CD9FB01D547FAC3A7CB4FAB1A36DF5F -:10A6200082FAFA5C9287EC596BE34F697ED178B37A -:10A63000F6F03CB581F0EAC87994F43B086015FD6A -:10A64000FE2329B6BAC8B8A828EFD2FC13A3C8279E -:10A65000024F02F5D93991AFE48DE5F38BE7F0D1E4 -:10A660009C0534BFDB923D832E676F5BC1DFF447EF -:10A67000D07D8BE2B3201EDA2ECC994EEB56683398 -:10A68000B0AD5FE7EDA678B3E62FDDA5E1B7B58401 -:10A69000E3738889DF337027CDA4EFA40DC6F84893 -:10A6A00041385E32AA94E737BA034CE6F1BEBEFCED -:10A6B00076C3C571346715EF1FE09920F2631AE382 -:10A6C000FA0C9A74623ECBF076459F0FAFE9F334F3 -:10A6D000FE3BC87F7DFD881D7A786430EAFD00FB73 -:10A6E0000DEA7BB477299EB14F5FFF18EA6D901396 -:10A6F0004B35BDCDB6F3FC120BCCE822D7B761FDCC -:10A7000007F260564777452CF49351A2CF3B498B13 -:10A710006C07F8F3AC34D0BD1211DF1178F7D519FE -:10A720008C26E27F55770E27E239D1F25ABAE7CC70 -:10A730007ADC5715B1B12ACA598C77F8CDDC7FF78E -:10A74000833F739FE2FE7D2DFA5F5D32E561097AFA -:10A7500046D37F6F9F3DEC2B2F253FBAA700FD7A94 -:10A760001CCF1F319E88CB6497FBA7623B119F399A -:10A770003B5D794552C3F116113F7818F719B4DBE8 -:10A78000EA7EBBFE28CCE3E87133C54AA6CA6F74E3 -:10A7900035619E55864272CE397EF50FD04FAFFCA3 -:10A7A00003D4635C52550791FDDE65A47841A5C6CC -:10A7B000EF959A5F26E2320BB579D7940A7B281081 -:10A7C000C3FDFF500CDAB9A3F7818CD6F34B2CAF45 -:10A7D000E771BA311DD1F55ECA7F1AA5F103E6AD66 -:10A7E00055A460BA18873B9894E8043A8F9BDF73AE -:10A7F000045D8CBCD75E8941BBEB392BE78F673496 -:10A800003B2F85496ECCEF4FD9677307A19D5D66DD -:10A81000CF75C33ADCC7145D9EDAD8437A388F45CA -:10A82000C099380F3DBC4DADC7A36BB6AD165811DE -:10A83000967C47A9964792C37290FFA6CAB67CF44D -:10A84000B31A2A6C0CF16A3E31E2FBDD2857DE9226 -:10A8500019EA0B67ACFA4015BCEF7C3DD1DDAC8644 -:10A86000E9FF0CF8DBA8471EBEE866ADC670FCEB3E -:10A8700059A067169D4F3BA9BE03E88AF07EF0BF42 -:10A88000B3E87C3A979EFF14FC6F840F82FF8DE53E -:10A89000CFC1FFC6E787C0FF46F887932B1EC4B819 -:10A8A000D97BD00EF92226FF806538C6CB6D32DD0C -:10A8B000DF89E6C7CDF51FDA6E049936CA953C33B9 -:10A8C00019F9E17699EE45432733D1BF8D8CBF4509 -:10A8D000C623C3F1B71E49C4DFCC409F519A7FD92C -:10A8E0001787F3F338DCB7F7E315FD509CF3927E3E -:10A8F000FAE29D96C047B928B2241607CF3FBDFBA8 -:10A90000DF9F427D24A7FAF7E23E5953F48189DBA9 -:10A91000E7FC5E56BAB68F765A793E6ABA96471405 -:10A920001DE79C3CE5C46DC980B2177F7ED3428C85 -:10A93000134CBEF544C11080BF29FD25877F78E206 -:10A94000F934C0D3D289ED1C7EE8C4B97437E671FE -:10A95000EC5F88F9C38E44AE07776AF79B047E8F5D -:10A9600069FB665DE313A4EFC11E61888F96141F17 -:10A97000E9E1CF937A1D8BD1AE4BEE4D597219BDE3 -:10A98000B1AEF1297A7FA7E43E15C4794FB0F0BC8F -:10A99000554D2F9DD57857E8A5062B07C57C187314 -:10A9A000D1F387B47811F3A6D17B89560E1F759425 -:10A9B00092FEBABF52FDB5CACF3FC98F3EEA18F525 -:10A9C0005DCCCB6B99AED0B9E443368F15F5DBE7A0 -:10A9D000DABAA0FF00C60902532D745EC492E6D312 -:10A9E000BE4E10E324D5523E4382369F63A53121EB -:10A9F0008C23B45459F6A01C7DD0368CFA6B2931C7 -:10AA000005307E23E08DA5301FC067BC2321136174 -:10AA100021E7447C99E1E91CF45BA92DBB52E44990 -:10AA2000588C6722ED701BEB26FE711B5419EDC884 -:10AA30000D13395F1530F77C7C6E92EA03C88CB831 -:10AA40000E43E43AD42AFD3AD4A9BA75480D9610BB -:10AA5000DA8F2D53611DD0FE98BD98E61B4D37B19E -:10AA60009E0F4B55C257F43A99762E25EE1F543A55 -:10AA7000CB0EE0BCA61ABCAD38AF57FE5A9B841F64 -:10AA8000E89BC6EA157C3E3C9C0FD47A35F91693B8 -:10AA90003F94F839DAAD265A9F71329FCFA3A66052 -:10AAA000265D0C5182A9787E3C101F674E8CE663B0 -:10AAB0002FC3FDD592E0E57CECEC7534231FC7F77E -:10AAC000A66CA47585FAA54F343F47D32B6F22138C -:10AAD000DF079111FFDF465F41D7E8F334C12F1B39 -:10AAE000263A05BD5DB4CED010DD7923F4A0F6770B -:10AAF000CEBE09FA5323CEE54C2E1FD9E3C62477E8 -:10AB00002EC6A55BBE91FBBD7F59ABE1A9D9114310 -:10AB1000767A8B83DBE99D8E193AFFAA0AFC2D3CDD -:10AB20008F96135907EE2B396E01C5DBE441689906 -:10AB3000115BE8EDDFB899DCFE757A2E7BFF4AE900 -:10AB40009175DF73BBC4FE4D98C1ED5F8789ECDF63 -:10AB50009D76D3FCDDFDC89DC289DC4FEAC475F447 -:10AB6000E35F825F49714FE1579A9C7EF20FC53ACD -:10AB70000BB57D26DA9B9DF50CE370B2C9ADA2BD85 -:10AB80002B6BF764312F3A37C22E10E38F9BC8ED41 -:10AB90008EC1E53C5F53E4C74FFEB554DF1FDED7DF -:10ABA0004C147649FF7CF70FF00DC9098FCDE445B1 -:10ABB000BBC36373511EF940EFE151F8A984B09C07 -:10ABC000717F532C933E52DC742FA0C3D8F3FCAF9B -:10ABD000D16F7CC5467AA7C39E4EFD09BBBD2296A8 -:10ABE000517E33F8C9815CE8ECB9BFC18E3484FD75 -:10ABF00063F0D7364F8C38D73CD27092CE8BA2ED13 -:10AC0000D5E8F843DF7E773C95C9E7134CC5FD2BAB -:10AC100035940C42BE8ADEEFA2CC70158C5A0AF332 -:10AC2000CA48CDA7523C7F9CC9D3FBFB6EDBAE3E2E -:10AC30003A703D3D12068B93493FEFC2797F7AFB14 -:10AC4000DB296E15EFEB7E417AFA6C7D49DC66E418 -:10AC5000F7DC0492AFE9DAFD33319FF4959DF109F9 -:10AC600036CC03EC1D89F973C126DFA82A23C50D54 -:10AC7000BDFDCDF757DAFE63A1A12CF2BB446A52A9 -:10AC8000F7B52300EFAACDE056697F3949FF0939AE -:10AC900050A1C4573981CF339A98DBA6E2A79B9D78 -:10ACA000143FCBB82813BF651CE5DF971E9AD42B41 -:10ACB000E1778FFAC6D1F2A4C439CC97F555B43FE9 -:10ACC000330631D68D7210F43DCAF92F934273705A -:10ACD0007F7FF93D3EA38C27F4F5A07329BEBDFC10 -:10ACE000F698A00A5D0FDD00F3C3F9FC4062E99914 -:10ACF000388FA3999B313EF4622CC587E41D59140B -:10AD0000DFB93ED5BF7F22CCE3D3A07AA761B8B626 -:10AD10005868B7E6AE18FA2EC14EA9FB5ACACBB88E -:10AD2000C340DF6D8DC6D75B13B95FF9F644BECF64 -:10AD3000325CC59CDEAEC2514B13AF7C3F7D83DFDE -:10AD4000D601FA6E8D0BD2799EC82BDB66EC9FAFD5 -:10AD5000CACAB87CE993C71AFE2CE80521BF489AF5 -:10AD6000DDB7EF99679E4961FC8AE2307E6E197902 -:10AD7000BE1C9315A4CA18B797E48FE4F47239EB9C -:10AD8000AC770580BF377F2DF73BBEBD4C93D31901 -:10AD900077BAB07D95EAA6B233A3F8F862C09FCD2A -:10ADA0006662E608392CF8245ACF37D8875DD6DF9B -:10ADB00037813C562F138F306979649B8E4CB0E0FD -:10ADC000774B37D93CDD687F6DB22579285E6F03FC -:10ADD000B91111BFB2D95E253EB4B9795CCF86F204 -:10ADE00017E357B8FE3C9CFFABB47ED1EEB4268788 -:10ADF0006CEE109DAB5ADDDBA99D45F1D1FD3B4BBF -:10AE000012A37C088B937FEF3426CBC02CFDC8E3C4 -:10AE10000F501E433F9BF23CDD95343F05AF65B1BB -:10AE20004D2E8F8BF421E219DE3F6A2F8E8BC4CF1B -:10AE3000500DCF2D9D7C7DBEC654675501FAB5BE21 -:10AE400094B222EC678905BFAF27DB0B2FDB4F6E77 -:10AE500019972BE17E1E49A94AA47E86623FB2DD86 -:10AE6000E3C47E8CDA775BA3F15CA4BDFFF7C6DD9B -:10AE70000083940F447821C2847474892E6D183F26 -:10AE80004BECEF3D2E173335FF05E4624519CC6BD3 -:10AE90004DDE07AFF23DC6FD96846B79BED1592DCC -:10AEA000DF3C3A4F23DA8E11FA47E823E847C67EA3 -:10AEB0001E453B6644781F0DE6128BA5D5F9F87E3A -:10AEC00049F211BF805DA3E27E91B57CC1E8F56CCB -:10AED000D6F027394A54D41755177AD2F0BDC3F6A5 -:10AEE0005369DC8ED59F471FFBEB5356ACFFB2AEC8 -:10AEF000F2B2F68A387F1EE8DCD9F12F9FAC8FB40E -:10AF000057063A87FEB6F3E7230E13C5F97649FADA -:10AF1000FBF5CD9A1CDA5026E232FEDB901EBB24F4 -:10AF20009F9B5F98E6F199A272FF9DF87C48BB89D0 -:10AF30000580AE87FF5AECF247F473A57816F1FA54 -:10AF4000C19A3D35D8F69484FB74705D50C2787B0D -:10AF50005A5D87E4BD4CBBD9655C8F8BF646ADFF6F -:10AF600072A557467D55EEE47A31EDBCC27223E4FA -:10AF7000CE8C32BE7F8D9AFDEE38F2B415FB3B626B -:10AF8000F0B5E7A07E7018D42723F6BB71A5C75291 -:10AF900019B1BE163C47EA878ECF94F5D95DA4BFA0 -:10AFA00085BE350A3D91A4E8F4C4BA58CEC7C2DEC6 -:10AFB0005957CAFDA175B1DC2F7FD1E57F02F7F3A8 -:10AFC000E7A59FCC1AAEE23DDB0E139EBB7FDB797B -:10AFD0004A9F7D63082E16FE0CF2BF5B71FEA2072E -:10AFE000DECFFF6105D97B45F8E512198F70B9FDF9 -:10AFF00007F6D473385E014E3D82DE2CEABB860331 -:10B00000AD67277E4BAD08E37FDD14C7BDEF82D46B -:10B01000EF7D8A2FCB84BDD0776E78D938AC8A711A -:10B02000D84C3C07D3C7490BBAF47051B71E1E7FEA -:10B030003C3AEEEAFD6D64DC7527EC33941322CEC6 -:10B040009A1E0856E03DF30CD641E7906975093A1F -:10B05000BC4E96B5FC0CFCBC7244FC374DA93E8D31 -:10B06000EF9FEE5B5780E9EE07542DBD133FC519E6 -:10B070008EE3AA84AF15D7CE9D8A748D8EE766D4F1 -:10B080002BBAFB84D171DCE53BF5F70D7DDE7CF25C -:10B0900007E67D471FFF1579EDB8DE34CFA5E37FC6 -:10B0A000FBB8F03FE1D2F145BF8F82FC21F9AA7DC8 -:10B0B000C73803ABB01F2524E179F8E07A46DF33C7 -:10B0C0004EBB9D79FB3B57489BC4F1158D671628F5 -:10B0D00027FC4DD19E0DB6F1BCD7C1B71BC81E1CB5 -:10B0E0000C7281FEDEC16AC612014E5BAD923D3923 -:10B0F000BBCEC0503FB00B4DBAF761BA144F1574B8 -:10B100007FD4C6F37A33D6B0A001D7533F8AF61363 -:10B11000CD6B982EEEAEFB2EC1EC12FD7DDF8CA820 -:10B120007BBE820FD2A29E1F2A73EAF605E8B9B44D -:10B1300049C4275CFF65A3FE83297D3AE1F8539853 -:10B1400087377923E3DFC3898FD1BE87D3775E2129 -:10B150005F047E3D6299928BF6CA56678C01F32399 -:10B160000EC7F73CC6E2191B338905F0FB9D2FC7BC -:10B17000F48E96009EF0D29E5DED4094C3D6DE1F05 -:10B180006130D9B6EDE99BA747C08EFB5F22989549 -:10B190003015BF2F84B9ABB8EF629C33F6E1F77C72 -:10B1A00063F26C149C8C61FAEFF8B496AADB30BFA2 -:10B1B000A435DBA0DDB38EA887753C35C929F2E242 -:10B1C000284F8F4DE7F90291FD639EF780FDCF80F8 -:10B1D000FE0BAFA27F0B9F7F0A3E023D9382F3C717 -:10B1E0003838F68FF4C5A051E4F85A7F0A0BECC644 -:10B1F000F31D18CF26F1F19C98BF92C2F4F90A7D95 -:10B20000E33961BC31FF17D633FF527A182F478FCD -:10B210000557478F568397E61B186B233F08BF8758 -:10B2200085DFBDB36AE359B5EF7F215E5B8BC378E1 -:10B23000053B90FA85E6CD17353C633E628AD344E0 -:10B24000781E086F479C3C7F6A8B3326D89CF9FF99 -:10B25000805E2E4EAFC8F1D09EBCE2F116C0784998 -:10B26000573E1EE217F74F1F7E81261B53AE1CBFB1 -:10B2700030ABC095E0F708F46B88C06B384FE9112C -:10B2800027FA0556A3CF82799BCF4FE2F98F7949F0 -:10B29000732D94B7903C97F290DBF26C9457DF9645 -:10B2A000F51D8B31424FB7E5D5523DB4A7FCAABC82 -:10B2B000500C8629D818D64D71802D65552EF40B6B -:10B2C00003F53C5F4BE42F097DC8B4F3515A17BC1A -:10B2D0001837E940EF1168BFA5BE90F2D3E2E2FF54 -:10B2E0008BF2B2B6D6B9DD58FF189E63813DF1B03E -:10B2F000768E858C4AF1B4B1A54FE0B9AF27BB413A -:10B30000C2E3A6F4D57AFD34382AEFC7F345772592 -:10B31000E677B1C53C7FCB55AB44E943FDBEDD8A42 -:10B3200078E579564189E357D7DFE949C9A4E7B6FB -:10B3300064ED6115D0EFF3D097ACDF5F06CC778A70 -:10B34000DE8F8AC94BDF29630D069A471AA6108043 -:10B350008AF38C99E95A0CCFD39729F4FDDA417915 -:10B360001B28EF09AC7CB237F2F2DEA844F89275E4 -:10B370002ED5AF237A5DD1F316DF5716F4F27CE1B8 -:10B380008E45FFCA933D97F2D2E847EC77396A3D84 -:10B39000600F5B930CF45DB998AC8875315D3BCD63 -:10B3A0007FFB9F857F3F8971FB39FA5CEC7FF1FB66 -:10B3B0004766E6B698E83D715F879FB70DC6BD83C7 -:10B3C000741FC2787E78F4FBC5FC7DE6E2E76FE689 -:10B3D0001866C1FB3AD2AA188A639ACD00E37D1E93 -:10B3E000ED7B658F6AF1B6668929A99EC8F1429402 -:10B3F0005F2F5BAECB42BFE188659E93EEC9697E4D -:10B400009431DE47F98D2C3741E78F1ED1EEBB35E5 -:10B41000ACCC1C84F1BB38A8EB46BF5A715B90DE04 -:10B42000226EE218DE7313EAF16193872FB2002EC9 -:10B430000EA3135CCAD8B8C3193FC0EF148BFD69C3 -:10B440003ECFBFF7D1072BF5943F623E3F44F73C18 -:10B45000A4F96102F626295538DE34F40F92F1DEA4 -:10B46000B8B315DFAB00E4E8BE2FA07D3FE4D2FE09 -:10B47000D375CF43E05F479E0B0CDC7FACEE3B0502 -:10B4800066F077FAEF3F27AA7F67BFFD87FB4DD4B1 -:10B49000F5DBA670B911488A09F617DF5B36B9F2F9 -:10B4A000BAC94503E7B72D9DACC5E12C20FAF11CC4 -:10B4B0004AE39FCDAE7ACA779363F8B9A911C4085D -:10B4C000F2D3517B1DC92D96AECF7713DF2769C309 -:10B4D000EF8E407DA54D6FAF57B0DEA3E324F4534C -:10B4E000F5F6FA645439783EC5A2EDF87A3A273574 -:10B4F000A6EBE5C2456DBF18EC85DD941F976CA3E4 -:10B50000BC8681E20BEF3531CADB32C6FAEA51E77D -:10B51000FDEBE1F143DB4A008EE37CB6F5F0CC4570 -:10B5200018377A4FE3E736900374CFB561D06E39A0 -:10B53000A2DF5A53281BF54AAD81DF17A01F18FF61 -:10B54000BDE4C114678D1E577C7F46C00BEBA54937 -:10B550005911EB7B4FDB1F7DE3DD96B61BEDDABEA9 -:10B56000F1CCA1221AAF2FFF481B2FE5EF1BEF8F65 -:10B57000DAFE16E32DBC53BFBE85A66E5ADF42ED40 -:10B58000FBA762BC3FE2FA32FF8EF1B4BCB1BEF160 -:10B59000EED2AF6FA1B99BD6B7B0CFBFD4C64BF92F -:10B5A000FBC613F90E66737D1DF2D340790F22DFBF -:10B5B00021C795A8CB77C09B2715598C3D2071BE1C -:10B5C000787D72CD0F30CE7F6E66839BEC14CDDF1D -:10B5D000A37B4432DD23223D3A3B9DDB21A2FF7D4C -:10B5E0004D25CC3B82C783B0CC2D93E89EC2C812B8 -:10B5F000C98BE76C3B417EE077F476C13EC7FA60C9 -:10B60000938BCA3D4D2A957BC1BFF452FCCB4DF0C4 -:10B6100085C9DC5F7C20D559B314ED8F8A189EA7AD -:10B620005D36112CDBB0FF06FBE58815F3216F605A -:10B63000F9F8772D7376707C2655A5D0F7F663F26E -:10B640008F753701BCB9445631FF7CB3DA7F3CE7D4 -:10B650002F5ABECF662DBF3280F72E49A9803F59A1 -:10B660004C7F3F8BFFC833E95ECEECBBE2C9BEA97D -:10B67000FD4E8FDD09F3B859CAFF6D16E0E34F9A0E -:10B680007DB368C80C9207D1FE69126AAA42CC3B0E -:10B69000948341F8759E7D1EF9B7F3AE672C01DEE9 -:10B6A0009F8DEF819EFAB5661FBDD96366E8FF05E1 -:10B6B000AAF8F9F5CD1BF47EE903D69013EDC20785 -:10B6C000F29318D2A3F6767DFD6613DF6FF3A2FC2A -:10B6D000D4D951793FE23B8A9BF1D7098C7D395906 -:10B6E000FB8E9196F7B35F8B33B1F4044A0617F7DC -:10B6F0003DCD66D6EFB9A4E82F11041DBD97E42512 -:10B700003C88BC77263F9B8FEF8BF1C47B8F4ACF61 -:10B71000A65E2E6E0A76E0C99E5CAEEFD15EB7964D -:10B72000EBE7796EE6B0EF56B1FEF8B657C1388553 -:10B7300098FF3F8B5F8FE27A414EFF7ACA9785FC74 -:10B740003E5E3A8BBC8727F2BFE6F5C10A7D9FF8C3 -:10B750007A01BA7AF390DEBF9914EBBE97F84FB333 -:10B760004742EF1A2EC65E7D7F7DF370793374F702 -:10B7700060B5FE06C2F340DFADA09FE2709CB7A5A6 -:10B78000D9EDA27B77C9FC9C6D7052E569BCE78559 -:10B79000F51FE8F84B7F9FABA5F36909FD96C7F04D -:10B7A0001E9C31224E54D721B5D9B0DF208F2B8576 -:10B7B0009EA6F86F7A5D486ACD0BDF1B8A968BE9EF -:10B7C000ABF5F7D2A2BFC7586DEB512415E3FDBD11 -:10B7D00074DFB1AD5C3B9F411C63BB646E4FCA69B3 -:10B7E000069E2F3254E5F66556EF90C8F38E55E568 -:10B7F000DC6EA88E7DFB761544AFBFBC6311E645B9 -:10B8000055C7BD7D7B26C0B7943FB708BFB3589DD1 -:10B81000F6F69799206F9795EFE7F0E8B7BF1C060B -:10B82000F08AF2E7398CF91E80A495E50716A1BCD1 -:10B830005D552EBEBFD84DF7BFE554CE477F776923 -:10B8400036F4BB2F6F2B17714B46F7BD7D877E7982 -:10B850001CE5944FC479BDFAF34DA67D7FF13AC142 -:10B860005E490EB29766E0EF80CFEBB4EFF6182C8E -:10B8700021C2EB88F07751BE7735DFED09DFB7E7FE -:10B88000DF9D6A69647EFDF715BD1AFFF3BC2131A7 -:10B890001F31FE25F3C2EF0B2644CE6B27F523E6BE -:10B8A000F579BE39208D0B9FD78A797D2EF5EEC2B2 -:10B8B000A047CF94DEC548D7CFEDBD43F0EFAB94A2 -:10B8C0008786FA094EEEDD25B9236023A7E323E539 -:10B8D000FF87ECA951A9DE47CA317FCFC4BF83D00F -:10B8E000AED9915B93FD01F4EB81DF286F3390C1FA -:10B8F000EF3B5415EAFF0EDC131A7F1579F9F9F4C2 -:10B9000054F3F6FAB70AF1BBEC126B86F6EB2E9CF9 -:10B9100033A1DF5F7DE88409FDFBB5074E98D07F3A -:10B920005F8B30F4B376A7A9DFBF4357EA95C5FE16 -:10B93000D5F92BAF64E4B425C17CD62EE5DF016BCD -:10B94000F859FC54841B16E32AF1EFF93D37155FD3 -:10B950005BE8EB6CC37211EB7905CF256AFC7A3F8B -:10B96000E2A63ABDDDBFB05E6FAF2FDA0ED401BDE7 -:10B97000B6A8312DEA7B80FC3B83351A3D6B5CDB3E -:10B98000BAF13B06352CEA3B83011E47BA89AF006A -:10B990004A7D7CA41AFF9E15AE63B54C71DE57320A -:10B9A0003629784F6E5DBD44F97B530F7E61A27AD4 -:10B9B0006887E74A2983F9F7F484FC14FAFDA6970F -:10B9C000761B315E10FDBDC145F3A7D377C5E7AB4C -:10B9D000ABB87E1FFABBA909F03CFA3B82B507B9A8 -:10B9E0007EAF6D9482F8DDDE9BEAF4FEC042D6DDC8 -:10B9F00086FECCC27AFDF3458D7AF823A1D746B3F3 -:10BA0000D1B83F4E974B0AED170D3E93F1BB37432C -:10BA100030BE3BD5C7BCC027AB4DA1B1A8E7DCA960 -:10BA20007E82453D3C5F8BF27FA07DF8FF4BF9DFC6 -:10BA30005818855400800000000000001F8B08008B -:10BA400000000000000BED5A7D70545596BFB7FB07 -:10BA500075A7BBF341E73B31045EBE58244D68D265 -:10BA60000441778AD7DD494FF8723A40866008343E -:10BA7000B350152549478953B1CADD341063072DEA -:10BA80004B59B4C0F28F06C5D51ADD0D92C1CED286 -:10BA9000301D302C3A387676D08171B582CB3A524F -:10BAA0008E9088A3B8CB167BCEBDEFD1FD3A2F8AFE -:10BAB000B353FEE16E527073DFFD3EF77CFCCE396E -:10BAC0009710E1A3B1D984E8082537F484EC344811 -:10BAD00056E7024202EDD47E5024A419DB4D84FDCA -:10BAE000DC28C1FF797F56D74FAE3B244A480DCCA6 -:10BAF00063F676119CE718B51E844FB5822464D98D -:10BB0000E03B254D0369D0177F96C4CB05928E90FC -:10BB10005C427E43C66CA48C90592930610E94AB74 -:10BB2000A78502B0EEAC5F6D0A50986F9683DA7508 -:10BB3000B0AFE5B0E3EE6A2C05B21ECABB0542CC3D -:10BB400050CED20F34E1BA649ED17A90EDB7809096 -:10BB500085842CC33F619CF432A11FC37970EBB87C -:10BB6000EEF2E9A7BFA619307EEFE3137A28CBCB1C -:10BB7000A4EAA7607F8F99F9FA8F0DD1D07698A7A4 -:10BB8000C376EA1CF6CB97085BB7A3202D8AFD4944 -:10BB9000D8F0C79BE72F8576D14AD6674165858D5A -:10BBA000AD5B28D30E56261F433F1A75E96E5442EB -:10BBB0003F79DD1F794476EEBCFB06289EBB9804D6 -:10BBC000B65358AF0CD6413A2A2521A6C04518DFF6 -:10BBD00008F7340DFAE90B7DCF2F8171ED0563462F -:10BBE000528AEDE346EF5CCD7EAF2EA9D1E8270166 -:10BBF00001617F0F58395DEAF4D73380F2E4816345 -:10BC000065F9C436F97E94526FD21151E107F86795 -:10BC1000B05A88383B5E5F3E3B5B555F692F52F5FB -:10BC2000FFC9A232557B8354A96A5F5DEF50D51BD3 -:10BC3000BD77A9FAAF6D72ABEA2905CB54FDCDE211 -:10BC40002A553D75F63DAAFEE9F69FA9DA49CE4090 -:10BC500081379D10A32930E6033A04815717C1FDAF -:10BC6000A518D382741A219519D0194A8BC39C86C2 -:10BC700065707E4A14EF2D785B4615D653DE7CB096 -:10BC8000208A549FF68AC909E52F68C8950D73006C -:10BC9000997C0340C7390F13299440CF636E1DBBB5 -:10BCA0004FA5DC26F9FECE09A5ED25B1086E047E70 -:10BCB0006273F07E4C16F813F9F88829847C3C0FE7 -:10BCC000E6248BE3F32CF138BB251CF7B0B414F950 -:10BCD000948489B502FA1D30C2CD423D70C4C8C6F5 -:10BCE000D9C2633A2941DE042797CFA7BDAEA53854 -:10BCF0007F47845A09F2F7DE8F8CA20DEBC319122D -:10BD00009455DE8F8C242DF1FB05237EEF10C62D7C -:10BD10005628FF69405F1FD2E09341C9C8F8F95423 -:10BD2000B191C94FCB83FA500A65FCBFC209FCD65A -:10BD300024CB61CBA1F1A81ED66F013D13804F4DDE -:10BD4000E27D2B08CA93CFC0F48D097E519E9E2EB2 -:10BD5000CC3840E671F92179846C94A5E99E45516F -:10BD600003D2ABB9D510D74FF06FE31ACF255A05E0 -:10BD7000F376267D9FDEC7E47B63A2BE427A49E963 -:10BD8000391F833C924A62BB01F272CEABD33CD7DF -:10BD900009B7C0CE75CEE766F47E1AE8A6A748C7F5 -:10BDA000643A71FA7D1B7D5EC5BB4EB8A7E47EFF89 -:10BDB000E2A6BCDF14FAD2E2E4ED0768AC1A95996A -:10BDC000DF6B617CDA6CDAB4F5A203E9FF651F452D -:10BDD000FAFF92921498FFFDE137F344E4F3432312 -:10BDE0007963309F7F60248F009FB519C4ED420EA8 -:10BDF000E303FB76B8978E7094EDBF7DC0318CDF86 -:10BE0000DBC3D48EAAD03F38E161E724637DD6340A -:10BE10005C577B5F31598FBF2F898CCFFC3E5833E5 -:10BE200007C7A7844214EF1DF410EE6B889227A178 -:10BE30007EA0DFD414D298E70CD21BC6BFD16F24EA -:10BE400002F0491B8CC7739C2A3E653421DF1C829B -:10BE500073513CC768632ACEDF6520228DEFEFB3B4 -:10BE6000E2D88778FEF39B0D2400DF776ED6337A15 -:10BE70009FEFD2B379F45BFEA3AF08EAEB80FF52E9 -:10BE800060AB27375F3D5504F39E6F853A9CD7BD65 -:10BE9000C5C0E46FDDFD94F54FE65F855F9F95F9C2 -:10BEA000739D4FCD6FC9FC3A894F5BBF1B9F7E15B9 -:10BEB000E7D32AB4B370EF75F9C83F0F11FB419473 -:10BEC0009FEB270DF9B0DFD23EAB7D07D4E7EA4305 -:10BED0008FE4A15E38C9DBE7B7EDA75CBF88F7E068 -:10BEE000B98A8246B28B221FF1FBB23845568A646A -:10BEF0009CA6A2BC0AB152D443B0B484F7FC9A8188 -:10BF0000341DB2E177AE5FE6BE5EB07F5702DF0E52 -:10BF1000499C1F15BD576924BE4369D87FE0B6060A -:10BF200098E755188FDF67C8F355948D7B1AA09C4E -:10BF3000E3E47A3047DE87527F4FE67FD22A50A46F -:10BF4000E34A13A7FBB2EEE87A3C47E974DF6DA839 -:10BF50003757CC78AF0DED5AB0F42D9B0FF747EC67 -:10BF60003AECEF97E97E72F11F9EDB06E735DF6E54 -:10BF700061F7DA70625F0CEFB9A35C2078EFE68AB4 -:10BF800005F93E0DFE534AFFB512E2CB8ED73B2298 -:10BF9000131E4943AE47DD5CAFCE35F2F393081074 -:10BFA000A990E963615175BC9F727E4276B0FEE64E -:10BFB0008A17D83D6DBB9FCC67708A3CC5CEDDDC4F -:10BFC000364A37C13C6B0D92210DE8FCDEB4A6ADBC -:10BFD000172B0879AB0754241CE44C8F89F8FE0A10 -:10BFE000F0528F95D5633D05ACFEAF3D222B7367B4 -:10BFF000787F84F4697CA3B302E975B2F819AF0BBA -:10C00000D6B972C6C0E840888BD1699BCC7B5723D8 -:10C010007A6282F6AB833444687CFF1BAE15111F35 -:10C02000E893DFE37A30B0BDFBB74CCFD95B273C58 -:10C03000621AF2D5853EACFBBBFFE441DCF021D8AF -:10C0400009E42F7F9892029867FDB56C36BE3D3C9F -:10C050006A14910F74E31EA47FE03825C897FECEC2 -:10C0600009A63F9F837349B0EFBF756672BD1199F2 -:10C07000AFE3F7B980E314F9FE87E7FC6706EA2F20 -:10C0800053B7F8CE5D788FA7F5EC1E77B9C633AC01 -:10C090001AF7720EE625297CFF5826B737190315C3 -:10C0A0007618D724F36D72FB43323F02850D881357 -:10C0B000F08702DDD6CBFCD50247990678617D98E2 -:10C0C000462D20B72D11F72501CB4E4A3E52E903EC -:10C0D000423E4AC0C953F1DBAD961D385F45BCBE38 -:10C0E000CE079326E09CE6D65434A209EB07185FEE -:10C0F000A51497E7FBBE01DFF9C700AFC17D75004E -:10C10000101281EFDBAF55B2F2F2D0A322CA89C977 -:10C1100032FE0CDA05324BC7707D7B408D6F36CB1B -:10C1200072BBD9CDE5F929271510F782DEAAC473B1 -:10C13000DB0B7D7B902FFF58FC5EC609F8DC668C1C -:10C140005611EDEF1D88874D284FB06E25DCCF6B63 -:10C150001AFBBED7EDDAE7CC45B97A92F13701FE8A -:10C1600046BE4A3EE70B32EE51E479DD894B46C4C8 -:10C17000BBFEB0B63C77B99D2FE07EFA09A9D7B2D5 -:10C1800073F7C9F2DEBE97327AF9F766333A7D4625 -:10C19000F67A5DC0979FC13E0E005F5EF17A533321 -:10C1A00061FC159F37352B2D2EFF1D7B53D9B8FE13 -:10C1B000F255D99BA03E847C0FE7B81C769B90CEAD -:10C1C0001BF672B953D6FB30BA2E1BE5A7C6306EEC -:10C1D000B443FBF4C8850CC4753543ABB351FEA61C -:10C1E000DAE7CB2E7E1FEDDDDBB65ECCE6FCA007EA -:10C1F00079DA2ADB31FF8EA811E9BFB59B30FE1D2D -:10C200003EF27E07CAEFE548AA15EDDE67C7520386 -:10C21000A8EFAF1C4F09E960AA36E477D0679F19F1 -:10C22000C6EE66F871486F45FFCC7FFCD367501EA1 -:10C23000FD47401A61DEAD914727D0BEB545965EF9 -:10C2400012B07CE5FB9587F6EE9FB3F32AF54F7BA2 -:10C250004C22EACFCB02D7135BC387199EDD7AFD50 -:10C260006A95D786E7FCAF85A8CFFCBFBABA10F5B0 -:10C2700098FFE8D585D8EE7F3DB5530B9FBCEFD630 -:10C2800033BA2AF6B1E4AC2025F6EB95F9A3A4F76E -:10C29000C9FA52A05FCDE81ABB5E8CB7D754E8BC90 -:10C2A000D8BFE6DDDAEC2D89E362423D7E5F305A8D -:10C2B0009BBA39812F1F721B643D04520DFA679D92 -:10C2C0004CC375058FC7F455581702328EA0371826 -:10C2D000DE26A2B010FD7782CE3DE98F090CCF0497 -:10C2E0005AF5A10A686F8EE9247315F3EF038938B4 -:10C2F0008310EFF2B978DFF7E6DA7789CCDE931EA8 -:10C30000AC3F5411427B4F02A691F2041CB42EA6FE -:10C310008BA600DF344552A28887D6C5840BAC2E8D -:10C32000E3A30FADAF3D826E27E0A38B893807F002 -:10C33000D045355E22E9B85F052FBD87B80AF06C9D -:10C340004B57D480F60A7092AAFFC6A61F5F423FE1 -:10C350006C63B7FA7B494CD0AD84739680BA433294 -:10C36000F4C7F698503E149C89F735A821EFFB5D81 -:10C37000FCBE1439EA8DE9D83DF4C65CA672289F4C -:10C3800095E568D0AA230198BF37B2FA20FAE9BD33 -:10C39000D7D7A622BD7ACFAE223B50DEAD2E5305B5 -:10C3A0008EBBFE6353A32DCE1F93F4878BEBC73850 -:10C3B0001ED0B673CDF2BEBE2F7BB7D6F5C3B07715 -:10C3C000E0576F70E532BFBA99C73DB85F9D6C27E3 -:10C3D00014FDABCCFB847CCF93F5EF25865FC0FFCB -:10C3E00065FAF70997C8FA4D8F346433BFF8EC9AB1 -:10C3F0006C316DF2FC65825D97659B3CBF82D7FC1A -:10C400000169C4847E8CA467F2E95F434314EB5E48 -:10C41000CA70B67FBD2184EDCA7E626B28EBD768F7 -:10C42000A721338DE33F051FDE6C5F00ED2571BC56 -:10C43000A8E0C29897323F688D6460EDB9337C8F75 -:10C44000B86AF07C66F6BD66319F17F4C008FA47FB -:10C450006B7F4A09D303325E54F833194F7E1E298D -:10C460009BF64D71A3E764BE54E46B46925C28765C -:10C470006A48B6D31D68A71D68A7BF36A21C4C85A5 -:10C48000BBC14EEF73B171848D5FF0AEE0D5F2BBEE -:10C490006DB21CBDACDC5BEC0D27EEB798C4B6A347 -:10C4A000BF3895FDEC9771CC54ED43323EFC3639E4 -:10C4B0003E2B9FEFFB92E3D80F448E6FE23FA3F633 -:10C4C00039EF753BCF23FF5AF49D3127CADDAF0DFD -:10C4D0002C6E9DDCEF09D91E833D53DDCF48B15151 -:10C4E000877E8FBF95C7018299E23BCC3F79534F3E -:10C4F000709EADD70A194EBBEF5A262B838584DB7D -:10C50000D1074B58DCE6BE97460D128C6FEEA2F3B6 -:10C51000311ED4DCAA3E4F30575A9A18070F160E18 -:10C520009C42B90A1C2C1371FE163C2CC6435A338C -:10C53000433B317E81719C79F8DD12A703ACD32E89 -:10C540007FBF4B8EEF90241C7074F83C8BF7F8077C -:10C550002941F93546407FA03E39CDE31D1D11AE7E -:10C56000173EE936337DF289C0CFE1EFA6A1ED3465 -:10C570008E232E459ECA43399B842724C01379718C -:10C580003CD1FEC2BB4C1F26E387AC41BE8EBF4DE3 -:10C590001FC278CC48F1428AF576F007F311278A5A -:10C5A000E24F8AF8BE4888E91549152739701BB74C -:10C5B000FB9F9FFE77E647360F5192CD7087142B75 -:10C5C000CF8BE38E8DC165CCFE2B3863E3CC532338 -:10C5D00045389F8C33ACF08BF1C3649CD1111E3570 -:10C5E000A05F30094F24E1880AB73A2E3853E07132 -:10C5F000D699116AC578D24C999E77F45B182EF6BD -:10C600007CB0391BE55CB99FCB0DFCBE2E9FFFC2F1 -:10C6100089E3167E205851DF1E3DDFF5DB225E17D1 -:10C620004D228EEB4A453FE4F2070FA4223D8F4294 -:10C6300049405E5F3F2768C60FFF3E1E37BED38D61 -:10C64000F6ED61396E2C807D4B8FC75F92C7BD269A -:10C650008F0B829BC1E28E4384F16FB0D0B78CD533 -:10C66000F79592832CEEC3F9F57024D38A78AF1234 -:10C670000EDB0D7AE21F2DA417F32BC15CDF5B4CA0 -:10C680003EF6E918FFC2789697091C1299BD4392AD -:10C6900061FEA3CA087BA9267C3190B739F2BD158B -:10C6A000821F8AF917D8CD9A1B40A74A390F5265C5 -:10C6B0002102CEFF98C1B7EB76CCBB0C0BF6ED3860 -:10C6C00046B06737A44FCEC70077B37D2979198A62 -:10C6D00079976FC8CB505CA78AF31BCBC31089DE58 -:10C6E000488DE75FC84FBD2C29B473512741BF73F4 -:10C6F000B187F0EF93F3298F3B35F229FBD0FE3061 -:10C700007DABCEA7ED9AFD1AE3B7EF9A473BEB520C -:10C71000E64B5E5FE47E67D2FA0B323FCF63FECB1F -:10C720007F7F95C1EC59E42AB33B57C653488CC56B -:10C73000EDC6789C3A6260FEFA15F0837213ECD96C -:10C74000974E4E87131137E3C7C1586D2AF62F96BF -:10C75000ED65FFD935AB57229FC4047B05DB25F778 -:10C760006B0663420DC70793E874D0A5919F3259B9 -:10C77000B83E4FE6CF46993F1BDD9CEEEEF3DC5F03 -:10C78000F177F1FC815596377F27657AE554711E64 -:10C7900055E2C8F95AF985A171A6675BEEA5F68046 -:10C7A00038757E61B7EC6724EBA18EF0217E6FC9EE -:10C7B00071DB7A0FD33BB71AB725E80D2F8CEBE965 -:10C7C0000145AFCCE571DC3BDC5676DEACCEF9CE74 -:10C7D0007C123FBF063DC55AAD3CDEE47EF3EA6EF7 -:10C7E0002D2FD829DD5ABF17A55B5B77F016FB9D6F -:10C7F000BDC57E73B4E44CA35F8EF3D6CEF18966DB -:10C80000BFFFA379D0E43C67725E3439DF99F2E66A -:10C810009600B63D4A1F1F8F2275338E3451105932 -:10C8200021F30513CAC98AC53C2FD05F6B0AEDA757 -:10C83000F1FCA842AF020FC75F56DB44201BE83C67 -:10C84000438AD566833C5F594C98FF70C5CCF3038F -:10C8500044B01636B0FBB316AE02BD1F346BE79979 -:10C860007E5D27E3E929F4C9128F733ACA8B1571EB -:10C87000B9C63D1E96E394D63061711B228885AB04 -:10C88000D8BA6221DA9B696FF0EF195122ED67FB8C -:10C89000124B56311C2D96E0FE76CBF9AFAC65B34A -:10C8A0004A305E97057617F3234F619E84F901564F -:10C8B000D64F59EFF95ABEDE6E03A198CF0ADCCEEF -:10C8C000DF57907FB3AAF21B670CD18B9B28CB6FED -:10C8D000DC81FB7F5B17B51D28E1F782F4B50D5AAB -:10C8E00059DEE5378BFF61B68FADC3F31DDBACBC02 -:10C8F000CB49F437601FDB8E3918FF369F58FCBBDD -:10C90000F5880BCB0546E749785CF6B3CEC97EA225 -:10C91000E2678DA1BF98E0772CAFD54DA59796D74C -:10C920006AC8D56ECAFDE0C0DBDC0F7618ED659DE8 -:10C9300009F7B4B696F3C3A6288FC72AFE6D9514DF -:10C94000D2E5011D1C0FE9A32960AF1D7D738DA8E1 -:10C95000B71D7DC516165FDA7C48A7D05BEBDE37C6 -:10C96000D5723BD27F7A9CE5270E27E5299FAF350C -:10C97000B2F62C991F9FAF251C4F55083BD10C4F89 -:10C98000FB6BAB5E2B3EDE02F81FF7B729C8F7AB97 -:10C99000E4435AA2A21BD7B93032DE8765756B8992 -:10C9A0009BC50FDB26FAD07EFAAF5F3DB584C50389 -:10C9B0008C22E2ABE479E778F46CFDC30848905E22 -:10C9C0004B8510F6732C15D87D67B598993F9E65F9 -:10C9D00020FA34AC37707B565D9FE3C63A5993C951 -:10C9E000EC71F56931738B2DEEEF672DEDCA453A89 -:10C9F0007D5B9E48891BE4CE907620BF7DD73C515D -:10CA0000FB99B3463CF78631759E48C9FB4C952788 -:10CA100052F2B4FEFA2F547965BF30EEC1F88AE3C2 -:10CA2000D8059627F687A9B5A0249E3FF20F4E1889 -:10CA3000197DE5BC11F437E2B8C11E9E3F3A02EB06 -:10CA4000631986F34AB08F7F86F3621981F3E2F7A8 -:10CA5000E33DB35919EDB1B3F244CF22563A806D9C -:10CA60000AB330EF34C1F24E2FD5AAF3164A5EC294 -:10CA70005EE8FD05D229216FC1EAC9790BBD85FBAE -:10CA8000A3FED306FB01F8EE3F63627AD619D934D0 -:10CA90001371D997A3BE99569607C8667EA5C20F93 -:10CAA0009725BB3913FD01AFDD8CF902C7F025A333 -:10CAB000C8F44EB4089F3275083123FAFD4807893F -:10CAC000E139A719E9FAADF1FDF0FFC7F7BF4B7CDB -:10CAD0007F5E5C2E99FEA8F6EAA4FD589E96CC5B7C -:10CAE00012F443BF97C789FBCB4B99FCEDF19666D7 -:10CAF0006E4E8CE7D7733F2E6B69B939F17B97C7C0 -:10CB0000C0711F255E2D3DF6F5D4FAF66B2D7D4BD9 -:10CB1000A6C80BF4D7733DA2C4FD27E709EC6F96B6 -:10CB200027C4FB2FBF0D7C0A7EEBF0500AB3E75FF2 -:10CB30001E4B3980F8BBBA7EF3CC74A8579F4B21AB -:10CB400025DC1EA9F20BCDF53AC99CA1954F908A20 -:10CB500074C0B793F206F53AA6DF6FE60DEA850BCF -:10CB6000AC2EE3F40D137F482FA148FF5010FD8C2D -:10CB7000C3EDD43E4C26E71160E222B2084E517F4D -:10CB800096E595ED9DD42E8ADF9E5FC893E30C1D3C -:10CB9000E14C3DF279CB1B84E0BBADC979867A8646 -:10CBA000F7ABC993C15A7C8F55AEB3A23D4B8E17DC -:10CBB000209FA0FD4F8E13CEABE3F7384FC62B61FD -:10CBC00019DF57CBB84419977CFFBD75EA7C4472D6 -:10CBD0007B97DCDE5B5FDD8FF71758A12368077A50 -:10CBE000EB5DA6F284F95C75FC1DCD6ECC5BE42494 -:10CBF000E62D787E22395FA1E829C7F0D71EBCFF59 -:10CC00003D111E4FF217F0F8A6E3B8F334CA7D7C4D -:10CC10009FDCDEEE813B8E311C65CF24FC5CC4C4FE -:10CC2000E35E2CCE50BDE28B13A9483F2FD82BD406 -:10CC30004B67CA77A6A13E5921D45091C5BB6FC698 -:10CC4000BF313EB5FA9DD66504ED7FE3FC51A47B70 -:10CC5000E37A037B87A4D8ABD5EF347978FBFE1D4C -:10CC6000166C9F4DED6611BFD7BBF0FBF257A218B3 -:10CC7000E9232B91DA2037B13317059497DC19BEDD -:10CC80009FA17FE46890E3E0EBB97D6D8C34184898 -:10CC9000DA647B77B2F84BE6475F8D38587C3B1BF4 -:10CCA000F3AFB6B8BD701C033B94FE97B343BD759C -:10CCB0005646CF796087703F590D3C4F987CFF2EC8 -:10CCC000F9FEA7B22B53E951B423BA455C6E684113 -:10CCD000DCFE8AE85FDF11B7C3D630D4F3BF21EEA4 -:10CCE0002DE3ACCC2970D82F657E9FF2FD46F8FB72 -:10CCF00089831FAAFB81C4C1653F4789872B7E5169 -:10CD00009A8C639532DDC3E9FEBF7EBF8CC651F3BA -:10CD1000FD7296F6FBE50D03147186F27E79C44828 -:10CD20009C8772F0DD1E25DB51BE430D0CE78C3C69 -:10CD3000FBFBBE97E17BC720B5A2F9691F1865769A -:10CD4000BA1D700DC343914F799C6A80BF376D0F38 -:10CD500053492B0EBA40B6CFB512617AA35D7ED788 -:10CD6000E719E4721D8F13FD5C488C13F9C558AEAA -:10CD7000F25E30C4ED93E6BBBE0E32CEDE0376B477 -:10CD8000527B14BE27C78D92E3454FCAEF00A78C94 -:10CD90001B49DFEDBDDF9FEAD2733E061650E2CF9E -:10CDA00005B53C4ED4E4A314E737E9BC6DECDDEFE8 -:10CDB000716AD57A3F9AEAE17667B91CBF7DD1C81E -:10CDC000F9E1C53B297B4FBF9CF038ED8BC7F9BB20 -:10CDD000FA17ABF9BB7A255EABBC97BF3D1EAFDD42 -:10CDE00083F15AE59DBDF26E9E9010BB8786BD967D -:10CDF00028E28DC70C0305288FCA7BA3A375DCDE50 -:10CE0000595248A7967C7E55E73C5AC7FAE9A6884E -:10CE100077FAF23D1A71209FECB7157BA6C4E9A200 -:10CE2000275785D3593D19A7FFA5E2B547EAC8544E -:10CE3000FBBF5F1BAF4DEA77F116FB9DABD3A0C7DD -:10CE40004E397E924CDF1E8FA287A75B193FDDDC37 -:10CE50003FE1F95C39EE3522DBB920157F7717CB3E -:10CE60007F1958FE4BD133C1743EFFDDB29E51CACB -:10CE70007BE53268D08ED374C9ED730AA595788F9F -:10CE8000952FA9E3667307D471B379E12C557D7EA4 -:10CE9000F436557FC7E952557B4D6C8EAAFD8E73D3 -:10CEA000D5AAFAE2B13B55FDEFFAC4A5AAFF685C2A -:10CEB0001D375B724D1D3753F8DB091C9138CE6D61 -:10CEC000FA1B55BFA256F5B98A3BD5E79AD9AD3EB4 -:10CED00097326F49407DBEB2A0FA7C5918D7B7FD92 -:10CEE000F971FDF15A518EEB979971DCEEFA7233BC -:10CEF000E2183DE631E1FBFF001DADB367003400F1 -:10CF000000000000000000001F8B0800000000006F -:10CF1000000BE3146060F8510FC1D3F9191836F310 -:10CF200023F8F4C0C79819188E83302303C33E201A -:10CF3000DE0AC46B80F83D0303C352203D078827F7 -:10CF400003711710BF048AD5B1623787858D81813F -:10CF50000D884F02CD3AC54CBCFD8A7C08F6215E97 -:10CF60000686B5407C9497BE6130D8F00C41FAD962 -:10CF7000F50C6AD76ED181F73708B38A3330304A5F -:10CF800020F8FD12A8F26CE20876960C6576950101 -:10CF9000F50300295128158003000000000000005F -:10CFA0001F8B080000000000000BED7D0978544540 -:10CFB000B670DDEE7B7B49BA3B9D90952574802051 -:10CFC0002A4BCB1201113B2189010306440928D2C7 -:10CFD0006C2184249D01661E3EFDFF6E0842C4D173 -:10CFE000898A1AFC195F83E004079DE0A0139DC0A5 -:10CFF000348B8833E804C70597795F401E204212BE -:10D00000A338E8F3C9AB73AA6EBAEB763769B7FFFA -:10D01000F97FFF840F8ABA55F7D4A9B3D5A9537500 -:10D020004F149D9524DD40C825F8A1E5AB0A2124C5 -:10D03000255876489DC3E581C1F6B55E177119097B -:10D0400079C06BC272BD379DB8AEA0CF47EB8AFCEA -:10D050001642EEF7DAF1F9E3DE122C1FF59662F9CB -:10D0600088D78DFD1EF29663F92B6F0D96F77A8B9C -:10D07000B0BDCEBB0AEB372A0BD2605C425CA6ACDB -:10D0800064423C2F0F1CB981D6D6678E4F9047D390 -:10D09000FA5FF5449F45DF1B2D17F987D206B9A427 -:10D0A000286B74B09F8AE78D4A5E5F80F3F8581D45 -:10D0B000EB67AA792D3B72BF2C3286E2395646FCCB -:10D0C00089A564727672C47E8301DE2343D93C89CC -:10D0D000DDF9DAA0C8F0AE06780F0DE5F825DB27FC -:10D0E0000F8A0CCF09FD7EE5E4F0D23B0F0F8CDCFC -:10D0F0006F0CF4AB7372787D7DA60191C71D0FFD97 -:10D1000062E013C589105F8BD19F9DF5FDF9455CE9 -:10D11000F42FC5A763AF79EB0609F9370DE8B4D64C -:10D12000BEFCCC163A4E7BCB30A7DE41C8672E67DB -:10D1300082DD1213DF6E8179C4C0B752182706BE94 -:10D14000CD8D916F0BA05F0C7C5B02FD62E05B6597 -:10D150008C7CFBD94F846FF7021EDF836F1B62D478 -:10D16000B75FC5C8B78D31F26D538CFAF6648C7C0D -:10D170007B2A946FEA73B5DC4124B48B372A253BB4 -:10D18000A09F27B3CD3620EB27C1BF3DDF53EFF67D -:10D19000C7C8BF5763E4DF11A04F0CFC3B1A23FF45 -:10D1A000DE89917F1FC4A8776DB8CE58E4AFDA86C8 -:10D1B00010FCB93400FEB5D84F5DCDEB7AC03B8989 -:10D1C000908C7039504BCA51940799B8DBD9BA5535 -:10D1D000F0CDA51C425698E87FE9FBBE3C12D0D3A7 -:10D1E000F17D36E2AF9584FE9F039E84E47F732930 -:10D1F00055E8EFD345EC4F74D0FE30C815E5FF6617 -:10D20000EF102CEBB91C6D2ED2A13CF8920D285FCB -:10D210004F789DD8DEE01D8BE5635C2E3772397A3E -:10D2200000E4EE0A90C3522E574CEE082971945335 -:10D23000BA76EC89271B1C28576609F09499BCDD47 -:10D24000BBE7CAAD1B28FCCD35BA2BB785C8D913AF -:10D2500045AA7C51C94C0EF67BA2FC846DC150A43A -:10D26000B70DE03414EBD47EBED07E0DEEEE7EBD65 -:10D27000A0DF63C55CBE6412081DF7B1D2EE7EE983 -:10D2800012A5CBBD12296DB284F3658AC4F4942A29 -:10D290000AF243E6F4DD9F7796B4D1F76DF6916913 -:10D2A00084964F827EA2FE39B054DFAFA7747653C6 -:10D2B0007A641A494D13E04B5A2585E22B8F752469 -:10D2C000821C3D34CE45242B21FDA19D8EDF677449 -:10D2D0001BC9A265E2F836220D837EB49DD6537831 -:10D2E0007BC650DA4EE13C04EDD6607B2A6F4F736B -:10D2F000F0F7AF63ED0F7B098EAFF6BB8FF2D94D20 -:10D30000F15B47F1C5E7C5C4057494293BFD21F3E2 -:10D310009F2DE971DE95BC54F1BF2FFB54C6FCA1D3 -:10D32000417CCD832F66CC0FC1EFBEC173B0AEE29E -:10D3300063BEA212EBFD57F5A69E18D707124EE763 -:10D34000D49903847687EC443FCD71444F7C945F3D -:10D350000E2A9E91F8F30515E71F54FF5C8C1EDA28 -:10D36000F6BB3574589721D2C1D05BA4C3BADE2274 -:10D370001D0C7D2E4F87299203E147A3873AEE8645 -:10D380002BC571E3AE12C7DD7095386EDCD53FCC8E -:10D39000B8EBFB89E31A33C571D7678AE31AFB7FC1 -:10D3A000BF7189ECA40F99B9200EF8679E60DF2E3B -:10D3B00010F7C3A0DF60E7F4C9413B27DB4B88DBF4 -:10D3C00012E42791E9CB39A170EE14EC2A85F37FA2 -:10D3D000381CD7E5E1D83570E66AE16CE37048A8FF -:10D3E0009D0E8343EED0CEE3B7FCBD802E647CBAA5 -:10D3F000BE92126BE87B4ECDF8B76BC7DF0D760C93 -:10D40000E6A1BBECF80E0D5DE768F1D9C3E110DDD4 -:10D41000E5E841EC1A38B3B5700E713801E9B27025 -:10D420004AB5F3785DE5AB24AC5F941EC382EF751B -:10D43000E4759E423FE845C5B19DB64B7FB2066E8E -:10D44000A0FD8F6C91FC465A0FEC8DC7F5E3FCB63E -:10D45000E958DF778D11D789F3CEC97E23B527939D -:10D460005E78DB06F6A5EA05BD0C75DDDE8F6D6D19 -:10D47000142F8FB1F5C1EBE8F3CE17F4642B4A6398 -:10D48000A10EE87E8ACB2659C5EA656656ADDAB2AA -:10D49000EF4E805BDE6C24660AA7EAA525D3AEA317 -:10D4A000F5258715025DAAB6AF36F4A6F5A57EA9C7 -:10D4B00009EA1D79A41CF469CDDEFF6C87F5E8FC50 -:10D4C0006E251BC63F4BD70907B5C747ACADA9337F -:10D4D000291E15FE5D85F05EC54EC9492D1CC57718 -:10D4E000FBA10CC07787E434527A2F6B8C270ED5C2 -:10D4F000DED1BFA776EB71FECBE9FC0985B784D4FA -:10D5000017023DAB803830BED3E8374B417D3BEB53 -:10D510003D8CE3A9F5AA1D743CFA7EF5739213A61F -:10D520005AAD236EC0B3FD2573E9531698E76AC35D -:10D53000602BCC6FBD01FA2DF1CF7FD1EC003CB751 -:10D54000180A01DFCD5B0C6543817E645EC950C063 -:10D55000EF2F227E0D7A17CC77F935C6AD7AE0A78A -:10D560002530688635DCCE9EA5EB952364FDAC2086 -:10D57000CCEE13D96F983E2CF8FC257D22CAC1B29F -:10D58000463D7184DA0D2E1FBEA384F9317BACFEBB -:10D59000ED59413E2EB77379E57C5C9EC8F92A7738 -:10D5A000E6CC18168ECF83C01723F38FA07C98AEDD -:10D5B0009B0EF47F1C48BFC7A8FFE440FFC889CF7B -:10D5C0009FA07E12949BA99F04E593D44F82D24FD3 -:10D5D000FD24E8B795FA49506EA37E123C7F9AFA73 -:10D5E000E7503652FF1C9E3F43FD7228777A7DF844 -:10D5F000FC396F1D964DDE7A2C9FF73660B9DBEB58 -:10D60000C77E2F7A1BB16CF636E1F397BDCD58B6C5 -:10D61000780358EE053ED332E06DC572BFF7189619 -:10D6200007BD6DF8DE21EF192C7FC9E96E9B4072B2 -:10D63000652A2F3617B1039B928A5DB9E0AF249516 -:10D64000B07AEA1DBE5C03ADA7BA699DD2B1776519 -:10D6500020D748EBBD6B587BE63D24CF44EB993E89 -:10D66000D63EE097AE3C33AD0FA867ED8337FBF2B3 -:10D67000E2687DB09FB55FB53390174FEB5735B17A -:10D68000F6E12D649285D68707587DE411D7242BC7 -:10D69000AD8F6C65F59C0F7D936CB49ED3C6DE1F79 -:10D6A0007F2E302981D6C777B2F6895F937C3BAD58 -:10D6B0004F2412D6F32CB9F989B49E6767F5C2BE20 -:10D6C000F3654784F57DAFD2B6104CDACF7539B922 -:10D6D00032F513F61ADA5680C95DAFBB21571E47E3 -:10D6E000E9A79045D0BE4957C4EA06B212DA7FAB2B -:10D6F0009B8EF5FD8A03DBF7E8E6B0BAC181ED7FCA -:10D70000D52DC4FA41C585EDC77595AC6E7061FB2A -:10D7100067BA9FE378871437B62BFAFFCDEA06374E -:10D72000B63F2CAFCFCDA7FD2BF56E8F8ECA75AD52 -:10D73000E42E2703415E9BD2C11EAEE37EEB2C9DFF -:10D7400003E57E5D8601F56CEF7FE53C857A063F5B -:10D75000C9502F7B1AFC5E0A6715C251281C7DCF69 -:10D7600070267E33568033F19B7215CE6A84638EA9 -:10D770000DCEDE6FC68BF87C53A1C2D9A0A3F6BE36 -:10D78000D61ADBBC265E9A20E273A95285F308E222 -:10D7900093181B3E01E55A014E4059A2C2D98C7024 -:10D7A0005262C3C7651827C0711996AA70B6239C28 -:10D7B0008CD8E0040CD789F81896A9709E43FAF427 -:10D7C0008B6D5E2EE3F5223EC62A15CE1F109FAC50 -:10D7D000D8E0ECB78AF4D96FEDA64F00E164C73604 -:10D7E000AF3C9B489F3C5B377D5E433857C606671E -:10D7F000BF4DA4CF7E5B377DDE4438C3629B575E4E -:10D8000082489FBC846EFA7C8070AE890D9F83290C -:10D81000227D0EA674D3E724C219131B3EF9A92258 -:10D820007DF253BBE9731EE18C8B0DCEC154913E4A -:10D830000753BBE9F305C2B93EB679E5A789F4C938 -:10D840004FEBA6CF258493EB6E447C0885638D0E49 -:10D85000E7503F913E87FA75D3C7A407380514CE29 -:10D86000C09EE114668AF429CCECA64FA21EF46295 -:10D87000726C700E658AF43994D94D9FDE88CFD4CE -:10D88000D8E655D85FA44F617F461F8FB173921DB4 -:10D89000FCC644E2DC4A5F9994FCB383B0EE2816E0 -:10D8A000E204B047A4C036804FD756F44B65A7EAD0 -:10D8B000073909F8B9C5368713E2017AD5DF21ADFA -:10D8C000B81FB1EC4C14E24D2FE9F38603BE56EAC3 -:10D8D0001586FA3D0963E3047F2BD19524D47B158B -:10D8E000F516FAA7940C10DAD34AAF12DA33DC2318 -:10D8F000857A9FF2F142FF7E357942BDFFAA294227 -:10D90000FF2CDF0CA13EB06E8ED03FBB7E81D07E5F -:10D91000454385D07EA57FB950BFBAF15F85FEC370 -:10D920009AD608ED239A3708EDD7041E16EAA30EFF -:10D930003F21F41FD3BA5568BFF6D83342FBB8B6BF -:10D94000E785FA75675E16FA5FDFB95FA8DF70F1E9 -:10D95000CF42FF5CF237A13EC9F481D0BFC0FE9137 -:10D96000D07E63FA271A3F568C5FD4E612E6CF6664 -:10D9700018D09F0D580D5837EC35B3FD0DD49321B9 -:10D980000E518C75C3FE858E6488070000EA4FE453 -:10D99000F62EBF02E255BF18EFBE02E2B8BF30B8A4 -:10D9A00047D823F841EDB2FB1E3DC6135B25920E0E -:10D9B000A54307659C9EC7138C4C7ED767E53CE565 -:10D9C0000BD183BA7ED4BFA0F5F57A8AC798A0FEA2 -:10D9D000ACEF57963E3F649C75FD0CA55B87B2E7A4 -:10D9E0000B2D305EC97D309EC7D03918F0D28E63C2 -:10D9F0001C305618C794598EE36C84715282E31818 -:10DA000033CB35E3984AB7F2E77C9CC7406FA28DD1 -:10DA1000B37EC078713E991538CE16CD38EB332BD6 -:10DA200034E3C4B1F9D0E77C9CA72E378E71E004B3 -:10DA3000713EFD2B719CE7B4F3E95FA919C782E33E -:10DA4000C0731887F4A5BB9834CA67636719CAC145 -:10DA50009FCC182733F4A9F80DD4C90766920DE3BB -:10DA600038E8B8B41F199244859A907FD127217F56 -:10DA7000BE88A3FC0F89A705F7E33EDCD72FE62875 -:10DA8000123FC588EE93AAB96C2EDA393D738583AF -:10DA900096CD07063D02E36CB43AB369BDBD7992F9 -:10DAA000616104795A5CAF9C6A0B91F3EEFD591EDB -:10DAB000195243C75F1167477CD4BA5A26E9C4E7B5 -:10DAC00027E8BE8BD0FDC987749F42E87EE5238599 -:10DAD000ED33FF9DEECFA0DE46F767D04EC86A7CDF -:10DAE000EF048F339FF8A5E4077A7F71D7CF145CDA -:10DAF000277CE4ADF4548826B09F79ABE2291382E9 -:10DB0000F8CDF7F512EAD41CF7D1A5E3BE16E3076A -:10DB10009D2F19FD5B81AE757D284D79BF0184BCB9 -:10DB2000BB77EA21C986D53EBAB184CCAC995E9068 -:10DB3000865A24F55B4EF19CB1FB1A85BE41DA95FD -:10DB4000B63B9D96205CE2524E007D4CF40FC0B96E -:10DB5000A588D643C6BFB544ACCF2272B04EF97D7E -:10DB6000523F80B0F83F1FD7E15280AF25748E1925 -:10DB700094D5B3A01C09CD2C5E536A67EFAAF87840 -:10DB8000162A2480FB6B5F0AC4B1892F19FBCD5183 -:10DB9000F7C91AFC4A1593AB84D2B574BE1EE9AA24 -:10DBA000C5F7FDBDF12EDD705AD63DA24068B627FF -:10DBB000FC67BBC57652CEC653E9AACACB29CEDFD5 -:10DBC00013C07F5A9E06FE53BC4F72FE07E598F1C4 -:10DBD000DF63744F03FE776ED213E417E7FB6D9C8F -:10DBE000EF8BEB45BEDF06E771B4FF6D2BB358BC7E -:10DBF000A9A197C05F3A71910EF50F1550B31A861F -:10DC0000FFDFB91CCCA9DBF50AB0F7F672CDFC3802 -:10DC10001FEEE47C98ABA1C76D9C6F7339DF961043 -:10DC2000DFBD1918BFF02B10D79B5D2E11B0179ECA -:10DC3000BB55BEB5097C73AB7CD3E07B27E7DB9D8E -:10DC40007731BE69F16EE37C6B6BF84C2103C2F156 -:10DC5000D6E2396F95665E3E2DDFEAB95CDA0DE0FB -:10DC60004F4D77E5AE3819D2FF96A2C92B4E86D814 -:10DC7000855B4BA60BF559A5B385FEB3DDF385F6A1 -:10DC8000DBCB970AED736B7E26D4E7ADBA4BE83F4A -:10DC9000DFB75A685F58779FD0BEB8FE21A1BEA4F7 -:10DCA0006193D07FA97F8BD0BEAC7187D05ED5B495 -:10DCB0004BA87B9A5F12FAEBF65E7933C8D791B71F -:10DCC000F504E27D179CA731CE78C1A938A1CF49D0 -:10DCD000AF03E5F89477089667BC4E94F3B3DEB1D2 -:10DCE0005856834C8E033B7BC002F1534F1CB5FB4F -:10DCF00089741D97C7ADA99B00EB0D6D1F4FC8BF61 -:10DD0000CA37ACF1F5A55A00716F4AFFE206030964 -:10DD10008C2254BA7B77CB73A73EA4BDAD87F606A1 -:10DD200099047A85B717B7457EDE21750ECE80B887 -:10DD3000EC7B46B23D24DE187EDE42FA805F11ADF8 -:10DD4000FD9C8E94879EF76C95D939CF117DDE5658 -:10DD500099E2556960FA5FF97C461EB1413D30B8E1 -:10DD6000C67299F19A283269C0E78182DE2F69B8BC -:10DD70003AA8E704C661F674A97F94F07C59E3756C -:10DD8000C27B6F48EE2D80C7B97D7A5CAF49E04019 -:10DD9000E62DC3003FD75619D6D1E614F4BB5ABDC1 -:10DDA000AE15271542DEF41661F996B704CB77BCA1 -:10DDB000A5581EF3BAB17CDF5B8EE587DE1A2CFF17 -:10DDC000DDBB0ACB36AF0FCB13DE3A2C4F7AEBB16B -:10DDD0003CE56DC0F28CD78FE5596F2396E7BC4DBB -:10DDE00058B67B9BB154ED674FF27786AFAF674172 -:10DDF0000E8DE1727670EDBC35757D837276582E8E -:10DE0000433953E95BDC60E4F2902AC8C35F611DCB -:10DE10004E0179E9A1BD41E17218EDFDC8ED206F19 -:10DE2000BD7F047923640DCA8105E4EE7BC81B81A4 -:10DE300053841490A73E1A7912E550952355CFDFED -:10DE4000904ACE817CA9726591993FA4CAD5FDE024 -:10DE50002746F0B77A2B125FFF987F4402B93A2029 -:10DE6000D9727E5E417C2EAC77F1B16B29B856E851 -:10DE700027FB87C03AD235E4ABC110DFEF3A4685C5 -:10DE8000202BFAFCB4F2129DEE2EDC3F94F929F31C -:10DE90007B85B79BE3185DCD3A524446C2F972CEFA -:10DEA0003137E567DC9FAE1E09FB66FA5C26490048 -:10DEB000C7EF9C1EE1BC800C2248E79EE8ABF63F12 -:10DEC000F5C47FE6C0B9BF05F49CCE3DEE80BE86AA -:10DED000E9EF53CE5B42CE973C46673AC4C13BB3B1 -:10DEE0000D76E63F4C12E94826E1F9814AC703D98D -:10DEF0005F0C86F399FBA81C827E750D1A9C402E40 -:10DF0000231F3DD9FB9EE8B900E61B133D0D04CE4F -:10DF1000B9283DB7C27DC758E9D9939DECC93E9E4B -:10DF2000D8C0E87C84FBA7D1E8AC9E8769F1B845EE -:10DF300091391FB81C933B34F42F15E8DFD7EAC0A2 -:10DF4000FE07F77E9009E7785DBBAF48204343DFCB -:10DF50002F60E73DDDEFE70B7A20FDE9EF99B03F59 -:10DF60003EF8C2BB58AE254C0F375A4AE62A6382A8 -:10DF7000F062BD47106D5E1E4512E7D5837E76A424 -:10DF8000AAFAD99A09F2B49BDB81B0F9F5209FEA8D -:10DF9000FC0EC0FC289CA920D3741EF972C95DC276 -:10DFA000FC46A7E0BC7B9A9F27C140A411143FAB5D -:10DFB000C14012A83C2AEEB50AEEEB9C6D3E885398 -:10DFC000EC8D77D65296786C67DF0838E03D319E4D -:10DFD000B1ACD15C23FA4F8935A2FF945113EA3FCB -:10DFE000751D7ECAE6A6F82D4FD7D79CEC05EB9C95 -:10DFF0008BAF736C5D55F1AB6ACAAAB10870C47A75 -:10E0000057BD54C4EEE13812664638EF53CBE5E90C -:10E01000061CE76CE3C00418F7ACD754C3D6577B93 -:10E020000D1B37BD26747DAD5C155F73725410BF38 -:10E0300068707F68FCA844908F4CB02ED2B681D116 -:10E04000FB47E5A7FCB901CFD55B942FC07F370F05 -:10E0500051FD7719EB2A5C4F93DE671C01CF770ADD -:10E06000E3D1F71CEAD938BC175D6E64724AE5A7A4 -:10E070001ECEBB08DF1F9890CF6E0A3181C2EB9095 -:10E080002D7520577E85E9B387CB6995A9CDE076BC -:10E0900020B95B41AE178C55E5DC31EB036AA73F35 -:10E0A000FE8B82F7CCC8D7147A4EF0AAC3225262F4 -:10E0B00083A0EA82DDCB8A61DDFEF8C59BF83EBD18 -:10E0C0003E07E67D9EE88AC02E9D276FDA4685E8EA -:10E0D000EB6985C5B1481DDBE7F8E81F98DFE27AF8 -:10E0E00071DFB3A441AC979119A9606FCB362AC4F4 -:10E0F0004F715F0AFB2675DED4FEBEABD811B92581 -:10E10000A4661DECD31F5358BC67819DC87DA8BD74 -:10E11000AEFAC3AF7320EED3AE307F573D0F5F9A98 -:10E12000C4F6831533FD0617EDFFD1EE51B7518BC1 -:10E130004BDFF7AF43FF673A716E27E1745F5827F3 -:10E14000E2D713FE5A7C553F28EC5C9EE391DC2815 -:10E1500045BC2FF535B773AA7E2419EC42DC274D58 -:10E160005357E540E172E057DC56430AE33BF05178 -:10E17000923B0DEE907E8660BF24C398E8FD8CD064 -:10E180004F8FFDD258BFCE42DC1F132A4F4383FD71 -:10E19000CC41787DD9B862BFAA3F3CFBA28FCA4B65 -:10E1A000C5EF1EB511BA6E7E2CD7A73AE9F3CAEDBA -:10E1B000F7DA5CB43C23FB6CC0CF8FFDFA88F77DA7 -:10E1C0006F31A8F470592488A771F924753E8C53D7 -:10E1D0007CB15DB1E33942A33160A4F259BD7B69E2 -:10E1E00031198EF5E3ACBEFE533DD49B457E55FC04 -:10E1F000E6D15407BB27C4E24924807E6EF5B6FF02 -:10E200002884F5C2433A51CEB4EFC1F8179350AF0A -:10E21000E71B12C2DBF162702ABCCF7E3CBBEFFF72 -:10E22000546F8372F269D0238F464ECAB9DF0AF465 -:10E2300082FD7EBEC19A8CF6FE5A722DE8BB4A174B -:10E24000E267FE6BED8EC7871FA7789DDBF6179BF5 -:10E250003434D44E3079EB6A5AF86F265D747BD231 -:10E260004EE531D44FA280F13D4733F7BB5B58599F -:10E27000A9046C701FA7728BE2A492482A9FD51341 -:10E28000B89F40DE33FA213EBAECD957DE194FE988 -:10E29000BF6C97925CCCA663915283FCF1D0BFAB6C -:10E2A0004606F951F1FB570C8E61ECF93D4941BE30 -:10E2B0002CDBB5CF408685D37152D33E439B2502DC -:10E2C0007F9A8E17C27A5BBBE31F06882B7EBC57F2 -:10E2D000226959E1EF976F7905D73DA013F293F3C7 -:10E2E000AB9B7F617C0B4C7B7934F6B3833DEC892F -:10E2F0006FD9B09F4B41F97EEE65B8C7F4BED10926 -:10E3000074287F6E850DE6735AAE6172FEEB7B5307 -:10E3100041DFCB155FAA1D4BF6BCFCC99FA3FC2DAA -:10E3200039FAF354F41F882B4387B6D99701F35C6D -:10E33000BCF9569C671971A31C96FF5A5F02F74CF3 -:10E340002FC8A46857043DF98B81ED5F4E6FA5CCB3 -:10E35000A5F33C0DF8817D7B53EFDF8E71F39FE1D8 -:10E360003DB89FF339D39510EB174C8C5F5B0C3A9B -:10E37000351E6A12E477DBFA56E0D3D97EAE343824 -:10E38000F7A074F071BA4997285CFDD18234C62792 -:10E39000E29073F87BD4DE4F82E7D0BF5571998746 -:10E3A0000BEF71FBC8C65FC9C7A778C7C1FA753A3A -:10E3B00035B2FFF70F3E3FFAD34A42E42C44DF99CF -:10E3C000FE6FBB8FE9BBAAFFFEE945D0FEF95B4CAF -:10E3D0008FE03D582F285E81346CDF375342FB407D -:10E3E000F7D991F47C9BC2F55C6CA73B1C5CFF5594 -:10E3F00039A1F8CB5242A8BCD07192900FB83F2EF1 -:10E40000DB48DF0FF1CB3C302EF633049F87AC1B8B -:10E410004BB85D38A4B10764734A4C7E74A5E27FA3 -:10E42000FA09D0DFF78C4E9F03F4572981F97FB2A8 -:10E43000F3C03B73A89C7FD2A4EAAD6857B57A5B62 -:10E44000FEFC1812496F3FB1D07D5724BDA5CF23E4 -:10E45000EAADA50DE5F9FF965D55E9D7AEA11FD848 -:10E46000C7971DD1E9A8B58F1B0C8E88F691FEBC0D -:10E470004572C2E550953F55EE2A7E5BD51FEC50A4 -:10E48000B77CAAF2D72D9FAAFC69E72BD24FDBFEFF -:10E4900007D06F8AD7EDA64DD3C07F3675128CC3D7 -:10E4A000E7CED4E33D4DD3E784DDD3B8231EEBB3F1 -:10E4B000F46DBF079FF083AA59C3609DBF9DF814F8 -:10E4C000766E5FAFA01FFBF5A54B13E87CE670FAF4 -:10E4D000DE4EC93D95F2A35496027114CFD932F1A4 -:10E4E0002524413C59222742F0B8BD5CACC3CFC4BF -:10E4F000D4209C9EFA7F5BBFFBBB9647295F4F648D -:10E5000013F2372871FF411DEB10799ADEC2CE312C -:10E510003CA325FF00D4C336B924641FE13132FB8C -:10E520007334FF963140BFDC59C312989C0FC6FD6F -:10E53000A287DBB12E9F2301EC7B57CB40DC177603 -:10E540001D5E687547B06707B89CBDC2CF613A2CA5 -:10E5500052BD9ECA7D07E944BFC66731478CCBCD0B -:10E5600031AA769AF38DFEE8E9F8A55C0E67D357D9 -:10E57000134686F06DE6D48F655B381FE0E744C82C -:10E58000BEE2FBD217E41AE87BC0DC565812217EAB -:10E5900053C9E93771FF970658F7F25B7265A063BC -:10E5A000BE452FC4431619B9BE0E254301AF89FBE2 -:10E5B000973E3086CAB1E7B0DE69A6F3F3B47C6A51 -:10E5C0007047D8DF69E909F0C1BFDC6A64FEF2DB9D -:10E5D0004AC962A0EBDBB7B2F3DEBF199C5591F0DC -:10E5E0004C37337F733629B9305AFAE9D1377796E9 -:10E5F000359047E9D16561F7B5C3E58FE97D975D52 -:10E60000F2AF96400EF5AC9ECCEE371712F703131F -:10E6100024D4F71B42ED576EF3F467E13E4D758B42 -:10E6200064D7D1F66AB9CD0072EC69DE2583DF7E4E -:10E630009383B8707F2DD70C9B1912FFA2CB1ED2EB -:10E64000EBC05773E6027D3F9B692480976BE8A778 -:10E650003658FF3F6B19857A106D5EAF7BC9B47C6D -:10E6600005E0307BA69587C2E478A17EEB24D21723 -:10E67000CE81271ADB563823F02FDFC4E42C66FB4B -:10E6800066FAFFCCBE4DA0F68DC9B5126ADF2CA686 -:10E6900030FB9616C9BE2D5FED4803B958BE672002 -:10E6A0007EBFB5FCB5C52991ECDBAB7CDFFB1ABFA7 -:10E6B00007DED197DAB71121F6AD2FB56F11E2E47D -:10E6C0005FC46ADF4CFF33FAF72AD8B708F3359BEB -:10E6D00044FB56D4B21AED5B515FBD705F8998A8B8 -:10E6E0007D8BBF9C7D9BFFE8AD58579CF111E407E3 -:10E6F000E80AF6ED356EE7601CB0733798587C3346 -:10E70000563BD72F563BF73F4467D5CE2DEF27A179 -:10E71000FF122E87CCCE2DCF62766EF91E66E7965D -:10E7200067333BA7B56F7961F68DBD5F3D84BE8FC2 -:10E73000FBC7ACC7EF80FB84A58AD344FB173BD44F -:10E74000EF276AC684DABB1B4C32D239CCDE393FA4 -:10E75000C5EF607AB2777F057B978D766C10E89174 -:10E76000563EA60C8A17EEB3BDFDE5A9DFFE0EF4FA -:10E77000E5753DDE177A57C7F6477BBF3C350AF48F -:10E78000EE2113B3BF4B4C8C9FED5E1FDAD3494390 -:10E7900099BE57DDC3E857BD5B62F35DA9F73B60E7 -:10E7A0001DF8EA22EE9FE7EE61FBE759C6D69478A2 -:10E7B000B897F42F0A61DF7D90E2F921F2507AB127 -:10E7C00002E380CFC7D9B6C2FEB2542626F063E773 -:10E7D0001D9EF231F8AFF32ED6A1DF3B0F9EC33959 -:10E7E00009BF27A1DEA398D3BCEB953E24FC7EC4D1 -:10E7F0004423E3C3C415927F4B16DC4710DBE76963 -:10E80000FCFA757C9ED49F45BA90BFEA23C6EFD62A -:10E8100069E9E164F3AF5AA917E9512345A407E573 -:10E8200068F1FCD4E0FCE7BED0B6AE0FB42F957013 -:10E830003FA5D2433B4F953EEA7E651ED7114FCB95 -:10E840002E05F8A59DBF4ABFB079ABF4D4CCBF4E1E -:10E85000B51F579361A06FEFEADC0F8C01F9F83315 -:10E86000A503C5EBB6D9D969A1F6F8416E97A6BA4A -:10E870008FE7A73A806EECBBC439E5BB5E49A5F3D0 -:10E88000B9D9953512BE1FBEF52B831BE20B07CC01 -:10E890009D68DF54F9FA84CB7B80C379BBB73D1FF9 -:10E8A000D79166C98E7A13D0D82F7E7FCC730FD3C1 -:10E8B000AB03D23FD6F5198D7485658014AAEB1091 -:10E8C000F081FE776A0BE38307F840FF3B8D741EEF -:10E8D000023A57274BCE00F46FDE752FC8CDAB66DA -:10E8E000FA1CF4B75C72B2EFCB882523F5B2F2299B -:10E8F00047924F0C4EE404D7C579D02F29DCEF980E -:10E90000686C7D1BF09848F5610B09F74354BE0F06 -:10E91000A17F2E45BAF7D3831C7FCCE5F355A0B772 -:10E9200005E8DA69007FC61360EB87DAEE911DF91E -:10E93000481F95DECD747D18CDE8AD8B40CF9BD5BB -:10E940003AA7A7A74552E0FDC974FFDA4B82D3ADC1 -:10E950002F0FA9720CDFC369E901F1808C10BD078C -:10E96000FB147A3E59DD7C14E932652575AF42E827 -:10E970000E76EB72F489A617D5CD3F8C5E7CA2D1C2 -:10E980008BBDE6CEBF8C80F8D71E09ED0369491414 -:10E99000F6FBF166E6671C30BB517E3B5F53F0FE31 -:10E9A000B9D68E7CCDE51EF617A1DFFD4D8289809C -:10E9B0009DB39BC9472A1E03981C85DAEF57CD6E7D -:10E9C000E45734F8717C1D8EE63FA9F51B613CB815 -:10E9D0008FE810C70BF32F78FCA7A779A5F171BFBB -:10E9E000EBBCBACF3349AB81B0F8FF0A63C8B9D4E6 -:10E9F0006DFC5CA03B4E16EC67375DA61FC45F0242 -:10EA000074DEAFEE7C0AE3BFE79F393E0DE477D9B1 -:10EA10001FF5C444F9DCBED34A02ECDE8501D6D929 -:10EA20008ADDFA88E72884D4B2EF1C7F6745FB5261 -:10EA3000F1BCD15F4CDFAF78F1A3E110B76A5FC3DF -:10EA4000EC8CEF192E1FBEB6E170BE5E21B3736170 -:10EA50002DBCEBB8BC9C7B29BE14ECA4D4C8BE5F13 -:10EA6000AD689AA51843F6E923CD0A8E4BFBE1BDAC -:10EA700065DF0E09E3E5E1F8AD66F07630FB57D1CE -:10EA8000ACF8E13BD88AC62DB8BFF5347E6A00BF2A -:10EA90006ED2EF9E65DFD736EBC5F861A33E60C44A -:10EAA00038A7FEB87138D35B49884755A15E563701 -:10EAB000F13899267EB4EC777B5EF451D22CFBFDC5 -:10EAC0006F6C606FCEB66EB7617CAE91C5DF648B44 -:10EAD0001C393ED7535CAEE93E1E979B7A9A0C0FC9 -:10EAE0008FCB9D85FF503D9C6FE6FAAAC6351B7BF8 -:10EAF000C5747EBEECD90B4FC279D2B9E73F79120B -:10EB0000F0AFFCE6B327EF867389BD663BAC7F9E12 -:10EB100067DEC6F8BBFADEDD5CCEDB77FCE6E92714 -:10EB2000A81EB6BF67C47B5BED7B4E67C2F78CED5A -:10EB3000BBBE4C85F8E6CA3D05B89F59F9C2A4B4DE -:10EB4000CBDD3F01F9F4C7707EA2E5C781DD7A0213 -:10EB5000DF739E3F6644FFA33BCEDA54C5E2D70E77 -:10EB60001E5FDD19F9BC4A8D0756EFBEE5E6EB6185 -:10EB70001DDCAD381DF89CC7077B8AABBE45F93A52 -:10EB80002206FEEDE4F1F3A6A911E3AAE7E13F9422 -:10EB90004F9BCC625CF5C2EEC5FFF604B4EDEE15FA -:10EBA00035AE1A88816EEA795899D9B5CD0CFAF14B -:10EBB000FC6F318E0D7CA33E39697FF64226C4235B -:10EBC000CE289D77E23DE53D46BC6754B1E75DD474 -:10EBD00097F6178EE23913E1E751EDA4FB879D1BF1 -:10EBE000F0BD8E679B95C56339FD215EEBB0E17387 -:10EBF0001E976572ACC66BA3C569DF37B3FB50EADD -:10EC0000F95CD5B60F0C4413FF96C602BF8E0BE716 -:10EC10008AEABCB5F0EC40876B43CF1FA2C5C3B9ED -:10EC20005D0DE3173B7768DFC2CF23BACF1908E940 -:10EC30003B12CEC7D9B9B9C72FBD1B89BFEAF9C3EB -:10EC4000DB5AFDF4C776EED033DEDF8D2EAF9AD9D6 -:10EC5000FE56A5CFB9AF23DBE94EAEEF749DE93088 -:10EC6000E3B9315B67E6F175A69AD28D7DF7C6F000 -:10EC70003DC7F781E79ED1FB61BFBCAEE900DA5B1F -:10EC8000AD9E571316FFD28E27C531FFA0BA79DF8C -:10EC900070B047E7F6BF84F257BDF3B8C147E11C37 -:10ECA0006AFCBDA16D6850DEC18EFB43ECF8B9E78C -:10ECB000F60D67E72291F3B4D8387C4F8B08DFB3A9 -:10ECC000F35301FE325F93C16EE9799CB3B26B16C8 -:10ECD000CCF76CAB42E03EFBD9267D913FC2B89F9A -:10ECE000C13A362648A77556F61D9F3EC9807EE676 -:10ECF0004AEBD863F0FDF84AABC101FBEDDAD5EC85 -:10ED00005E65EDFF72A6035F6A136FC373A37A0D8E -:10ED10001DEDC9F65CD887DBF34B46835869ED419E -:10ED2000A24B27E0BDD25A94E6B0405E2FE6A71072 -:10ED3000D989DF19EA6D8545300FBD5D6737475CBE -:10ED40005F193CC5C2F2662876F1BBBFEF9007831E -:10ED5000403E8E6F9D07A3539307A3FCC6FFD7F2D7 -:10ED600060F8609C9F401E8C00C677D43C18C93F59 -:10ED7000721E0C882F8D0EC983D1A9C983C1F9F8E1 -:10ED8000CF3C18FFCC8301A59A07E39D0D65059044 -:10ED9000A742CD83716683A700F252A87930BEDA0C -:10EDA000B08AD5791E0CCBFDAB0B42F36064DEBF9D -:10EDB00001DBD53C18CEFB1F2908CD839177FFE6F8 -:10EDC00082D03C1833EFDF5E109A07A3ECFEE70A0F -:10EDD000843C186BFF500079305E8F77B7C6A5442E -:10EDE000CF83D11CE788290F0685F31EC2899207BD -:10EDF000430B275A1E0C0AE744DC98E87930C2F02E -:10EE000089920783C2F904E144C98311864F943C77 -:10EE10001814CEE738AF287930B470A2E5C1A070DD -:10EE2000FE0BE144C983A185132D0F068563884F2E -:10EE3000899E07230C9F287930289C048413250F72 -:10EE400046183E51F2605038E908274A1E0C2D9CA6 -:10EE5000687930289C2C8413250F86164EB43C18F4 -:10EE600014CE55F163A2E7C108C3274A1E0C0A67F6 -:10EE700014E213250F46183E51F260503813104E1D -:10EE8000943C185A38D1F26050380538AF287930A0 -:10EE9000B470A2E5C1A070A6213E51F26084E113D6 -:10EEA000250F0685330BF1899207230C9F287930B3 -:10EEB000281C37E213250F86164EB43C1814CE5288 -:10EEC0008413250F86164EB43C1814CE7284132575 -:10EED0000F46183E51F260503877239C287930C293 -:10EEE000F0F9AE7930CC8141D240CC8381F938BB86 -:10EEF000F360247FEB3C18BF027CFF9907E39F7906 -:10EF0000307E8C3C18B75ADD7F8FC77DE377CB838B -:10EF100071265E9337A2873C18B75A4BCE823C7F4E -:10EF2000DB3C1817E2BF5D1E0C3ACE3F2E374EB4C5 -:10EF30003C183ACBB7CB8341C7912D632E339F2822 -:10EF40007930122C62FE901F2B0FC6B1F8249C4F13 -:10EF5000B43C183FB97C13749B05FBB4E9288AE4E0 -:10EF600027937F62B485C70D7FA8FC1330E99C9F6F -:10EF700052FE09358F419302EBE1FB9CEFEF70B934 -:10EF8000F880E7A13816350F857F2AC677978A79EA -:10EF900028A6703ECE768BF23085B0739429F9594D -:10EFA000FE5AD8AF976BF2500C11CFE98BDD47F3C7 -:10EFB000293832D529CEE328978769A59F1E04F604 -:10EFC000DC3C36721E8A199C1FD3357499C2F936FF -:10EFD0009D97B7C3A739549E8BCB8FCA40D7698EF4 -:10EFE0003619E3F437A9FC7308FC9BC9E16AF19D6B -:10EFF000C1F9376332E39F16EFB7807F14EFB7CACA -:10F000004721FFB4786BF1D4F29F84F23B247F4810 -:10F010002E11F34F4C3289F9270AEC62FE891BD37B -:10F02000C5FC13931D62FE899B8688F927A63AC505 -:10F03000FC13378F15F34F4C77ADD6E4BFB84F9321 -:10F04000FFE2214DFE8B4D9AFC175B34F92F766859 -:10F05000F25FECD2E4BF784993FF629F505F58F7AC -:10F060009AD07F71FD51A1BEA4E13DA1FF52FF7175 -:10F07000A17D59E3C7427B55D3A742DDD3FCA5D080 -:10F08000BFA7FC036FF1EFA1DFE1DF431FE3DF4325 -:10F09000BFDF43FE8B772C4BD785E6BF78DFE25985 -:10F0A0000779098E5B1C3CAF40E4FC16DDED51F2A4 -:10F0B0005F04DFFFF6F92F52927FF87C043A2BFBB6 -:10F0C0001EB0B7254F674DF9EEF9086E2D11BFEB55 -:10F0D0009E552A7ED7ADB3B2EFB567BBC5EFBB6F08 -:10F0E0002F17BFEF1E11E796000F6DFE8BDE1697F0 -:10F0F000CE0AF692E72908C077BAD9106F2BC2F270 -:10F1000020E4BFC886785B29968721FF052DFF0C78 -:10F11000F92F687904F25FD0F20DC87F910DF933B1 -:10F120007C3C7F461DCF9F51CFF36734F0FC197EA6 -:10F130009E3FA391E7CF68E2F9339A79FE8C00C233 -:10F1400039E13D8CE5496F2B96A7BCC7B03CE36D18 -:10F15000C3F2ACF70C96E7BC9D58B67B2F62196BD7 -:10F16000FE0C552E3F04BFE10A189FC9B32AA757CA -:10F170003FF0C8BAD0FC19231ED884721A2D6F46EE -:10F180000E7CD397123D6F46777B94BC19C1F7A3D1 -:10F19000E7CD481BFDE3E5CD986BF961F266CCAD98 -:10F1A00011F33ACC5B75F9BC1923E24A6E41F9E3DD -:10F1B000F238D7125BDE0C9F55E2DFE553BA80DFF1 -:10F1C00045E982EB750F79070E5A9F1E02FB89AE47 -:10F1D00021575D36DF83562EA2D39BE57798F32324 -:10F1E000E7CBE889AE6AFFF72B581E87B9966F996F -:10F1F0002FA3877C0B07B3BF403B196BBE8C9ED6F9 -:10F20000879EE839E347CE97D1935DEDC99EBE391D -:10F2100085D1B9770F7456BF97AE34B51EC297ED3E -:10F220002E546D997F0F9F3BD38EF1998E9DFC5E7E -:10F230009C8B38ECA9EC7B7DF0373B9E4F184EF051 -:10F240003B7E3B7151FEC4F3E7D2CE7DFBE05EC056 -:10F250005A1B71252681B3471CFA81B00FBBC60427 -:10F26000F19AAADD9FBEF1470AD7DCA2C7FB721D47 -:10F27000148756F4FB5C89C0B778F24BDCA7C3193E -:10F28000DDA55EA1DF756B7E0F0774490D9E3F15EE -:10F29000E82DB86FEADACCEEB3EAC9D58F4F188DF6 -:10F2A000F7C689DF81FC433F7519C7B38B10670030 -:10F2B000FAEFB4E2FDD525AF2D34C0A070DE1A1AE6 -:10F2C00037E85524C6811ACCB6E1706F2F5DBDBFFB -:10F2D000E773B5821FBE88C34D2911E3449F2C28D4 -:10F2E0003A0CFEF3227719DEAB482B15E346847FF8 -:10F2F000470FDB32F03365C2EF75FAD97DCFB0EF3F -:10F30000EA9BB7209E4BFD9AFB4B8D625DA5DB39D6 -:10F310002BBF9762219698E8D676C5E31392BF3D3E -:10F32000DD8CE922DDCC0E916EF14344BA68E966CA -:10F33000758A74D1D22D61AC185F53E9A6DEA7FCA3 -:10F34000A1E89664E3F73C82F42A31A5A2C9473CC0 -:10F3500033E400CAB7561FFA5802F01B7E48BF6458 -:10F36000FF6A7CCB6995C16EA533D0445AC4DE8B4D -:10F37000077D80FCBDC489FAA0FE3E8A78F2219701 -:10F38000FB8FC8255AAE987EF0F802DABA19E46D00 -:10F3900004FB3D1A18AF4A22B89F5388D30EFBA82E -:10F3A00026AFC9B94881734DE25C940DE799762C7C -:10F3B0001FE4DF3B770C25B8EF6F0A7C9E0AF70647 -:10F3C0001E1CD9390DE20F9EC5A404D6AF59096C95 -:10F3D0007D5DC64B5B028BCF6C28D111D768F87D61 -:10F3E0004A7ABF44C76BB7BB5EBB01FCD116763F00 -:10F3F00080D83BDFB81DDB47E1F7E119BAFA6B00B3 -:10F400001FDA1FBF2BEE68F9C8B630C40EB7373FFE -:10F410007225DC6BDDA48BFC3D73818DFFFE1D7EB0 -:10F420003F654430DF42816D0CE6657870001DA7B2 -:10F430007A7A17F25195CBEB38FD0F964D41FC5E71 -:10F4400068911C10AF2BD4DF71D3308ADFB8B76559 -:10F450007EAF97DD5F1FCDFBD79AA9FEA2FDAAFF65 -:10F460001BFC9E95974ECA980F71744D19DE13FCC4 -:10F47000A3ADF030F02BC7D5340AE429BF2511CF56 -:10F48000713D1F12277E9AD52ADE07CCE1F7B673AD -:10F49000DA881F84E2DA6362FBB836B17E9D66FFCC -:10F4A00039DFC6F5D4465241EE367EAD9760FDE8B1 -:10F4B000E824CE3514DF8E45BD71FC8ECF09FA8964 -:10F4C0001D5FEB8B22DD8F596E63FCDB642068BF10 -:10F4D000379559F0DEF9FEB28AFEE05F7C7197BB8A -:10F4E0007FA43865889F96C0BEBB772590B12087E2 -:10F4F0006B2546EFFA8C9208EB962A77AA1CAAF2A3 -:10F50000975116E78E740FF5339B847296573644E5 -:10F510003280FCEC9530FCD5BE86E2759975DB47F0 -:10F52000D6F4017C3CCD9FE17D32538BE48A744F4D -:10F53000E7619B8DDD6F5CE35B0DF7467E419508CF -:10F54000EC5486A13E2B127C1FD9887EE95D3607DC -:10F550007BCFC4F320C9F519709FA2BD79D2E475A1 -:10F5600014CF27A83EC07AB5497122DEBE2A42F0E8 -:10F570009E2C8FD7F59D46B66C08F17F37DB721B4A -:10F580006D145EA38D7D6FD9CBED94006FE77FFD89 -:10F59000C306F03B2E1A917FBDB9BFA9BE7780D3B9 -:10F5A000675C826B2BBC4FE0979F51E3E374DB9C5D -:10F5B0008B46415C9ED23BC40E06F9E663F951DCF2 -:10F5C00004CF3F922C3A9443E27239ECC27D761F0D -:10F5D000EA8DAA07242011C853A0DA37A9450A5892 -:10F5E000A9DC8F365902708F2EA99CCE3B19F29A56 -:10F5F0009818BC56F99C18D7A2F29803CE3DC1AB1F -:10F60000F3104805F8AADD53EDE5DA44668FD63EDF -:10F6100024635ED4CD729B19E2A9592E471EA4889B -:10F620004C921D78AFA65F3971520C49FCC05F2720 -:10F6300076FB0154C9AFF9463F2FD2775B176DCCEB -:10F64000DF1E97E0FE33D06BF8E1CEFDE02E38CD23 -:10F65000A417BBFFC5ED04F76B0AF97A37EE3F74C8 -:10F66000EC7BD1C00D24F43B2AAD9DD86466EBFC45 -:10F67000B8EBD9BA37EEBC05D7BD6E3B515688EB17 -:10F68000D4C8965107E09EC5C80F997E126E1FEC34 -:10F69000F40FD029E7B04F0FF4F9B67641CB6F12D3 -:10F6A0003075D787EAE01C86EA5BC8FB673576646D -:10F6B000C5F441B5185EE672D4FF1EA7DE1D4247B1 -:10F6C000EDFBDD714AC9D4FDDC3110ECC8113DDC25 -:10F6D0000BE9C8A5F3A3F3DFC8F525F173FF649820 -:10F6E000D7C6961BCD20DF6B0379F662FA4EA2A92E -:10F6F000049997485C18CF19493D32C88F518B4205 -:10F7000041FD41A58424A4C03DB42221DE432C49FF -:10F710003CFF4B00F9D22DA7548E43EFE5AAF2A986 -:10F720009547557E6BE1A005CE0721624E4BBDD4B7 -:10F7300084878146B2D90EEBBBEA5FD6727FAED624 -:10F740009CE9C7EF977C19E81FADE4FE51ADA5D049 -:10F7500084E6605F32AEEB2B217E42E9B03285D980 -:10F7600079753E5AB9F45CD4137FC83EC12377E261 -:10F770007D44CF45033E5FA7B807C0FC55FA5CC384 -:10F78000E9A3A58794C0F79D9C2E3DE39B63877BEF -:10F79000C1892617598FF8E6E13DEEA6C04813ACA3 -:10F7A000BFF76AF08D01CF6B13C684E3295BA2E03B -:10F7B00099CCF0BC8EB8FFD846E53767455D6D3C07 -:10F7C000EA15792B3D275CAFB47AA4EA8D1AE7BD20 -:10F7D000B6B2FE005EBBED416F3CF18C2E4EA5042F -:10F7E000EF5739F7C4A31DD1EAD3E77CFE9E7846D4 -:10F7F000BF058A7B06CCCFA3EBCC043919EE20BD24 -:10F800008A2992C39BF5A8E7A435B67BF8AA7FA501 -:10F81000FA55DA7EAA5FA5DA63F51EFCDA04F77CF6 -:10F820009003A999CA2DC5A7D6CEF64B9B6DEE4580 -:10F8300080573CC53D0EF68D430259ECFB5F512FBE -:10F84000A2E941BC46CE9B0232AE0B3EBA2E644BBF -:10F85000E178A8E30F4A48647CA45A0EEB7DDF1CD4 -:10F86000C206AB269837A7EF70E28675ABEF4876F5 -:10F870009F714D02B3BFB5096CDD52CBCDB692BBC3 -:10F8800051BF65E2338EFCEE7803AA70DF7C6D8297 -:10F89000EB2EA087A9C885F3E863274EF04BFBC881 -:10F8A0004D127C379A54E990D83D7312FC7E8BC27E -:10F8B000EB53ECC8057DED03FB6BE8DF1239CFD8C5 -:10F8C000A309EAFD5EE67F3A49771EAF471398FF2A -:10F8D0007908529FF42A56F382A9E7394E09E8D4F1 -:10F8E0006EBD0D916EBF20313F3D91D14BBB4F009E -:10F8F000C287FEFEBD7B0D44362791E0EF59D599B6 -:10F90000D0BF8F27CE26B057BB1206F0734C671DB1 -:10F91000D47F25779A128706E55D95E30727CC709B -:10F92000422A52DBF55DC3614F45E57A27D0BF7DA2 -:10F9300042D760CC41493A3399FCB8F442BE209595 -:10F940000FCD8AC00733ECC343EDA4D53004FCD1FE -:10F950007629CE09F72CDA974A0C5FC9C4F329C976 -:10F96000C23CD3E3997FDDC1EDD53B09592827AAD5 -:10F970003DA6F3AB83523B0F8F11EF7490CE3DF158 -:10F98000FEAD706EA5C93FA9CD4F3969A105EF7FC6 -:10F990006CDC63C6FD6B57093BC7EF6A31A27D8EF5 -:10F9A000A6B7696DE688711CB5A4F47B0BE897A631 -:10F9B000D424823D4C9B7BD2067CD7D2A543F25DFA -:10F9C0007308F645AF2B11BFBB55CBF4F49B121750 -:10F9D000D1FEE91993B1549F3758E488F7CD4F739E -:10F9E000BD52E5F14A3A22DF0F9D06793CEF7EF3E6 -:10F9F0001D1709DEDF6F8863746C886374EC728F87 -:10FA00004F781AE4CD9781FAB0583D07E5FB7F3572 -:10FA1000CF943ADE46AF2951A62AD0B0608A19D6D3 -:10FA20008914E29A3C1B9475A342E03BA2C7BC3BFD -:10FA300012F3318E6D12EFF9DAD9BDE1CF3716E04E -:10FA400077DEA9648D7930A5475989CE09F183F312 -:10FA50000BDEB7E9A83C2DE8D39A03F2FBBAE22605 -:10FA6000F63118EAC2FDC99252833F40F996DC4054 -:10FA70000D05A5CB7F03D85B39A8008000000000EE -:10FA80001F8B080000000000000BB57D0B7854D5DB -:10FA9000B5F03E73CE3C92992433794E1EC009E1F5 -:10FAA0009D108724BC1F4E9E448830BC0485EA808C -:10FAB00028CF2488D6DFB6DECBC444F4A2B745E90C -:10FAC000AFF4D6DB7FB0A2A8200182069AA413402F -:10FAD000E4113408A8A8AD5129620BC908EAC5D6BB -:10FAE0007BFDD75A7B9FCCCC4922D8DE4E3EBFED62 -:10FAF0003E8FBDD75EEFB5F6DA872EC977134B641C -:10FB0000CCB7D8C0B64A8C7D87BF1B43ADD96E60D9 -:10FB10002C89B196383BB54EE70CC7D284F07E8570 -:10FB200063693E63D5D6D85C16876D7F3F8B85F1C0 -:10FB30008A58EAD202685BACAE5A95B12546AFDD71 -:10FB40000ECF774EBA3CA48EE12FD8DF3392B12E80 -:10FB5000236B94E2B01F606C0C4350F8CFED56ED70 -:10FB6000D097F0FFE1FD448B2D20C3B8CCA35CEC13 -:10FB7000B0F047BE1B281E4D66CC285E939ADEF877 -:10FB800046CA652C7672116370DFCA5C8FB22CB8DE -:10FB9000318CA99E18C6A2D833F6F3D98C19F07D02 -:10FBA000584757F3BBFD7C00C71FFEE54A0C83FB9B -:10FBB0001F29C118570E63171E3C15E3B6C1F50780 -:10FBC000E5723FF46F4740C687F0926F870BA31929 -:10FBD0007BC4EE1981EBBA63DD7F8FF1DA42F7D98E -:10FBE00003703195B1157E19E7E6F0C27FABB659C7 -:10FBF00019B384FA95F509117DC018E1B5D2CCD6B8 -:10FC0000D4DB7AD26305D203E65DB17D8B295DC575 -:10FC1000F9BD93ECD0BFA0C0AB80EF0B0D317E5F80 -:10FC200066089E25DB4799D2E1D6474D661680755A -:10FC300030A5DDC86C84B50A09F0E61578D3C37920 -:10FC4000B8C54AE3DDF57F65BF1996BA18E67A2094 -:10FC50001E9E6F5A51C1727BAEE3AE3FA86529402C -:10FC6000BCBBFE4D623E953FFF601E3CFFC0235F64 -:10FC700020DDF4EB5CEC337ED211B16E376300CF44 -:10FC80003241EF3B1F8DBCBFACE9311A6729F39AB3 -:10FC9000909E776DD4DFBFE933E4BB654C095D0707 -:10FCA0003C5C3E9265453CDC618F493C0F20038FF4 -:10FCB0008DFD0EDEDF7D64609C37A7277EB5F6E202 -:10FCC0003AE06F33637F5E67A1F6C23A46ED08BB48 -:10FCD0004AF459DD74F27EE4AFAAC65D261CA7C5BE -:10FCE000FFA78409F04861D3373232572173DF7B95 -:10FCF0000EF0F92326B3EF007FBB19E79FF546CF3F -:10FD00003D48AF1BAF96D37DFDFA1769FC7F249E5B -:10FD1000F86711AE3B17AF2B5FF6B6AE9FE2BA8025 -:10FD20009FD95858977CFDEBD2D6A3AD4FBB5F2926 -:10FD300003DFF5F2BEC6EF23843E58FADCACF5696A -:10FD4000808ADAE6CFFA77103FB1D328BF1A3F2D69 -:10FD50001374D2F38D46C76EFE68FA775A9F463FFA -:10FD6000E07FA7C1896DC06918D7934FF47CA1E7E4 -:10FD7000834E63477F945F3D1F744A6C416FEBFA7B -:10FD800037FB405AD752D55D6687FB7731CF7A3B38 -:10FD9000AD67235DBFA06C3CFC3394ABE7385F7765 -:10FDA000EB3933973776DCE847BDB936464D71D825 -:10FDB00004FD80CE9DBBCC3E7C4E9BE7FC3AB77BDE -:10FDC0009011F15E4EED9FD779DC830687EEDFFD63 -:10FDD000AB2BB12ABCDF358C95A3DC77C644C2BB04 -:10FDE000CF2E133CFB900EC87F4AFBFF7C803AE984 -:10FDF000B9F631A847CF7FFB5FB11E78BEEB5B73CE -:10FE0000796FEB3C2DE807EAE5B413F8EC7621674F -:10FE1000B73755125D963C33CB84FCCC1EE0F8B46A -:10FE2000C01FEAD7B6A8D867711D8B1B24D2237ACE -:10FE30007ADCE59AFA39EADB3BFD85F47E0FFAB00D -:10FE4000C789BE77213D8685E831D6A1727854F8FE -:10FE500003BEB943F0CD79658DC9007AE4FC3380E7 -:10FE60006F007995C2DCBDE9C1FE0ECE877DAD473E -:10FE7000BF8EBEE05FF65CCDFA3486EB1F654AEBC1 -:10FE800045EF68EBBF8BB96249EF88F5B28E1B492D -:10FE90005EAB2D7C5E6D9D2B9AEE9C817C51B519DD -:10FEA000E895D973DDA87717F7026F997CD168813F -:10FEB000F7BA1E905CA86FFBA283A627EE12F85A31 -:10FEC000B96DF10C349A8B613E3913F5D1176FC6B9 -:10FED00024A25C415FFA1E7A35C91F9B711D8CE319 -:10FEE0007B09E07B8374FDF45BB6B9D03D28ECB9A7 -:10FEF00015FE9BDC83C2F5998EAE6CDBACD0F3644F -:10FF0000B7DD26B4C7F10EA1BF845EEE5BBE60E133 -:10FF100000E7DA1D0EB26F6C8D83F46375D3165350 -:10FF2000B8DDD5E44B93B7B10E3BF15955E313F46B -:10FF30001CE85FD501FD4A4BC7CF6F55C3F0394E62 -:10FF4000D051AE30A1FEEE4B7F82BEF9B2236C9D44 -:10FF5000231CC2AE08FD7B2DFDA0C1AD1F57D307EA -:10FF60001ADC1ADF6BEBD1F37D5FF0E9E9C2989FF1 -:10FF7000FB0B3AFAAC427A84F5115E05F0DBD66CE5 -:10FF8000F53F04F0B6491C7E5F7314C1DFE92C769F -:10FF90009F033FAF2A7521B527F0C554F4EB3CD33E -:10FFA000109F9A3FC70A1222FC247DABF93779C211 -:10FFB0009FDA1BE5CE0713093F4F02F2C3949A8ED6 -:10FFC000391620D9AD8EEDE50A8C3FE5898E395181 -:10FFD000D05FE8D8C1FB5B3B4E595C8CD5B057CAAB -:10FFE0004BA07F3BA013C7BB565B60F62C44F95D6A -:10FFF0000D7E9205ECD1EAD3430EA1DCAD6EAF28A5 -:020000022000DC -:1000000097C0EEAC068323813DAA74C706ACB9D471 -:100010006713E0B9E7EDDE65C42F57EBC86EAD3E60 -:10002000AD70B9399248EB5700F62878AF2E1AFC1C -:1000300055C0575DBCC5559B49D77D51F1D877ABAD -:100040006AD8758D1EF81EC25167606E07B4AD4741 -:1000500087C4757C8FDD6E5DC72A14E08383EB2C2B -:10006000D4EAEF179AEC83D0EE151A98B7377DF9DA -:10007000A483FB8DC0E4E948E7AA23269277FCA17C -:100080001F5829F4511510280EE0A93CCD02D1B11A -:10009000F85CD9E70AB60D12FB24C25F61A1BEDC91 -:1000A00037DCD7DB56E17883C3F984E3A948912A8A -:1000B00094B0794B6C51117D39C5300CD7C3E468CD -:1000C000D756C0AF9C6E58B31BD62F0F8016F0A129 -:1000D000D85DF2626837164F9197405B6BE476B556 -:1000E000D6C09687E3E905811FADFDC0E1D98A74CA -:1000F000BFF456FB182BE9AB0C3BC9B9586FADE404 -:100100000A50DCD4CA5C5BE15A9DEC619C8FEB1910 -:10011000F2F11B621C97D9B047057E6D747C40FCE0 -:10012000EB8A33DC9B09FDC0131FF17EBAE14A263E -:10013000F0F781273ACA15900757B6E1CA40E81F81 -:100140007AE2637E7F220C0906EAF0139F94FB6C2F -:10015000382ED7676CBB3B1BE7510C12C9A972C084 -:10016000E4AF85FFAD8BE5FC54073C82FCF786B01D -:10017000B3EB6B8A5EB602FF2B456E750D8CE3C741 -:100180008069F4DFDF6A7894AD068A53B0457CBF9E -:1001900029D6ADD18135B8B367A15EA87767CF8E78 -:1001A00041BC7A4F225EF3DBDAA7A03E6E78FBFDFE -:1001B00031E8AF22BD709CFC3688DD603D975EEB78 -:1001C000B7450E8B473F7014BEE3003996DCDC9FC9 -:1001D00094543B5B047257EB66AA09D695A28BEB4D -:1001E0001A18D72FCFDB3D7FC4F7584680EC4DA1BE -:1001F000C3FB31CEAF8F57597B7CAF7A59AFB74C29 -:10020000B90FC8E8E7C4A737BEB704F5FBEFCDAE1A -:10021000C12AC2E5660F003C3B0D4C61F1C426C308 -:1002200094028C3FA35D1B50EE5DCCE90339C330D3 -:100230008D80845FE298B0B855AC07DE2F61D08E18 -:1002400045F86EA0F5C9C857A3984746FD3586F90D -:10025000ADD87635BFE644BC3D19C5EE40BFCFB240 -:100260008DB9FD61FA63403CF7F726251809EE6861 -:1002700063FD6CE4D7E82F981DFDAAAEFF34293842 -:100280003E08C874BCEE3A6C6008E70B46BF3D0EF2 -:10029000FAC1E18AFA2C0B8DD725E8AD8DFBA44974 -:1002A0001DEE407D93C0FB2F1472FB1CFCDCE47F31 -:1002B0003613F16359E30F932F673CF75BBD494554 -:1002C000F1F1D0D63747339C7F6C4BB401E9F0F2A3 -:1002D000F6BC28E4879D881B587FBCD97E0F8E17FB -:1002E0007F05E0CDA4EB6EC2ABA28E8A03BC4E9814 -:1002F00066533700DE5F88AA9F86FC1FDC6160CFF3 -:10030000C2143B4DAE59D8DF7959B5A3BE7D21B398 -:100310003E9AD6B3C340EBD9191D1CB116E0DE30AE -:100320004C2947F8142B53500F2B8622F51EB83E4C -:10033000349EDB574D2F2F88E7F2F3A404F3E7E157 -:100340007385243FA5B28DE4AE2BC8FC669827695F -:100350006EBB8CF4889E05AC847CAF046406FD49BA -:100360001E46498D4936A35F257DEBB62D06BA4F53 -:1003700011FA76CA87AB2B78DCE33A3D11C63B68AD -:1003800033325CD764D621A33F38F92A7305907FB6 -:10039000AEF278C60E7FE83F3DAFF3074BC578EE6F -:1003A000A0BD042F17B2483FAE7473D9E712CDA396 -:1003B0002A68A78B2DBAFBE8E7C5621B193795C5DC -:1003C0000BFFA63FEBFF1DE937E05E98EF3E3B9F3A -:1003D000AF54CEF915AEAFABDCE4423CECB2B9DFC2 -:1003E0009D887AB1DDC8B6B2BEE5E979883FFDE007 -:1003F000730CBB6A65FE7CE2471BAE67C4E68DBE2C -:100400002858F788417C7CE43BD42343FF333101F7 -:10041000F5F855A15FB456E333E4277B1CE727FBCF -:100420000D2139BC333E939ED3E40AF90CC7D96F32 -:10043000F42FF4F46227813FEF44FEDC6563144738 -:100440003D966A598072A5CDF3BCE0637DBBBE6664 -:100450006DAB11D7FD15D80380BB24EDAA29DC9E16 -:10046000EF49E27C552A7F4BFE766793C4D0CF4F8D -:100470006EE2FA3B9C3F527BE78F5F225EAFC51F67 -:100480005ABCB0FB87F2C791BF8F3F365C933FBE2B -:100490008D453CDCD75C9CC2BEC7BF6914FCD0D77D -:1004A000FDF156AEE7F4D75F1178DD67DA383D1716 -:1004B000F5C0CD0617CA39503F7D36AC635F347F37 -:1004C0008F296BB2B0BF4BE17A65579399F4CA2E6E -:1004D0009BD74B76DC6961E83F30C5DBF133D487CD -:1004E0006916754318FF2E8DE7FC566F0C8CFF0CB8 -:1004F000FDE2A39CCEE36ECE934DF05CEA522EE774 -:1005000005174C5B300E2B4D28DC817C7402751670 -:10051000B4D5E7E029407CD53913E9BBD75A4E96CC -:10052000617E11FC1E37F2D9D8FD27CB8A72F07993 -:10053000AE4FF78A56EB8FC735C5B3EE78D723ECAD -:10054000C678C6F59207F92437D4676E23C56B1AAF -:100550003FD447033F805CCC67AA3116869C73CE9C -:10056000F330984336A73C92CEF303D3283E9C7BCE -:10057000BAFD55D0CC6C9E47775FF0C17C1D1F80C3 -:100580009D3D1E8FFED2F180C980F399D664737FA2 -:10059000684D16F293264FF4033CD5FF61D8B31B88 -:1005A000C2EC7B6C0297A3C75D0ADDF77598FC83EC -:1005B000E1D2BF33FE5EBDB03F9FA33C63FC70DF62 -:1005C0002B0BD18EE62F771F44FC4F4F92E9FA2F69 -:1005D00058C09285F47129E497D51BD5E2CFA4D0F9 -:1005E000734CF10CB3C1FDFD49D1F9387F6982F735 -:1005F00022D28929C123F8DED80979F9285FB651BA -:100600007509688F34B801AEF2ADB6101C1A5C677C -:10061000055F94262CBE88EBC7F750BF347E7CDE86 -:1006200082EF6B74AF6FFE82D33B8CFE48EF10FD00 -:10063000A53BB0AFE1E12BA157B4FE3F4A7F2D7F30 -:10064000704DFA637E20F6EFA2BF352129447FF07A -:10065000B3E2B1AFF7B3EA4DE077E7F4BC5EE82868 -:10066000A4E75D265821FA552D1077A23C7A1DB4D7 -:100670002FB0C7CEE7EAFAC3F9FEE022B2C109F112 -:1006800084F76A537008FA21A30212F985A340F097 -:100690001791FF95417ACF25F0C4CE4BD2F961DC9A -:1006A00045FF2E1DFDC34002FA51A3CC1501E4F70E -:1006B000DDD629E9E8D7E5592765215FBD3AECBECB -:1006C000E368825E4D5BBEE73935E4FF68FAEDA072 -:1006D00018569BBF2081EBA11B41DDA21F882E6312 -:1006E000381C9A3E47F2201C5260BEE13B2BE9E5E4 -:1006F000A60EA0C78D0807E0A155620DA8CF0B0D6F -:10070000EEC462F4D392020AF7F7BEE98FF9C18A08 -:10071000A637DE43782B703F04E35097F162773EB3 -:1007200062604F3F58F357B4B840F367B4F813FD15 -:100730001EBC3F405CB79B0140B447018BBF06E63F -:100740007FF2B23ADC2DE4568175548875CC64EDA5 -:100750000417FBF6BBEF26017D66087C541C81B8AC -:100760003117EF337633E0E16685C79337BB207EE0 -:100770000CE3A399E322FBF89B921C1AE75ACFEBF8 -:10078000EDC044DDFECC3FDA1E017BF409B8CEC7D4 -:10079000D6F1B874C240D9A7A0E11C9769407EACDD -:1007A00016F60DC2E85EEDD24BC22F9E60E8C8750A -:1007B000017E5BF7FF8DECE081FD7F7B07FDBCF1E7 -:1007C0009F2BCC0CEF4FF8BC200EF5041BA7125F3B -:1007D00069E356FFA9C1CAF875E2FF2AB1F6C30062 -:1007E0008F7B28C267A1F677179FDC84E37D794E63 -:1007F000E1BC2DE62F337907611EBBCCC4F3018722 -:1008000025EEFF68F70F1B016EB8BE2941CB0BB474 -:1008100093DDC79F398CCE37633E202F44D79B2F63 -:10082000947FAEE4F6A40FFEFE37F2015A1E60ABD1 -:10083000C01F3B78D6A4025C531BEE51D0BF9EEA8A -:1008400094993B6CDE9B542B7387E5039E49D0F94A -:1008500023075FDC3403EC49759BEC8A42796DDA3F -:10086000753C17FBEDB2CBDA0B1FE9F13BB5E91E86 -:1008700005F9DF98A8927C5F6BFE0923804F6E40DC -:10088000BA33F2EB3AC74824477AFA1ED8FFEB8412 -:100890008E9CBEF1DD17FDF574F8DDC522DAEFB9E7 -:1008A000163DF47CDB02EBF4C1FA02B04E1FF85D9A -:1008B00007D6D9A97F689D93FA1ABF5637FF36012C -:1008C000FD368D4F4B1338DF8CDFB72981D942F4C9 -:1008D000D2F0F5A1B0577BA3347FC3356F065C3AE5 -:1008E00005768718D4C7DA9D6342F66BFEE932F2CB -:1008F0003734FB355F5E544A6A53D82F4C23A35ECE -:10090000D3DBA9B9EA6223EBCD3E2D88EC97B76D16 -:100910005462A867203A4992C087F0B33538CE3088 -:100920000FC1A9A7A706971E1E6D7D9A7F3D5FD0B8 -:100930006FCEA04C23C2DFC3AE8A75E2409887B861 -:100940005EBBFAB58E9FAF5C28792BB717BEED8BD7 -:100950007FF5F7357D508613E451EB43BFC298987D -:100960004C742BBB6A626EB01B2C238A7D1A6657AF -:1009700058C550E29F7B851DEE8B7FAAAECACC9BEB -:100980001FE22363E31356E4A37DCA462BE6272721 -:10099000DB66D5C6019E4AFE543417FDBCEA0E0341 -:1009A000C3145669D3170731AEAF7E8FB9502F16D7 -:1009B00035B51623DF1D52DA658AB3BF64EC893082 -:1009C0007FB1B1A9D68AFE5463A24C71FC6107E7DE -:1009D0004BEDFE9644AE3F1ACF5D9EE1EEE5FE196B -:1009E00071BFE4E33CE2A3B24741AE310E4D8AA1B0 -:1009F000BC4489649F53817EC84D46F2F3218EF931 -:100A000023EE035E6A34EFC2D47E69E323F7D88114 -:100A100010F5FFFD698D19F30BB324D7B3F05C9982 -:100A20001A6CC57ED9DC4CAA7B18FB3F32F9B3C1E6 -:100A30005B25CA8B9401BB60BF6C51A61FF313FBEF -:100A400025DEF735F37D0266F725CC8079DEAE48EA -:100A500018B581784AEB0FCEDBC0042387C557F762 -:100A6000ED9549CFDC572AF971BFA9D49ECE7C61A0 -:100A70007C55F6A889D635BB29A508F9784EB9CC9E -:100A8000FC61FC1D107EE13C0FC4E161EF1D8EE2B4 -:100A900070051703DC52486EA7093E9FC5B89F3802 -:100AA0007F4142C47BF0C62D688F6E6D8238157A07 -:100AB000D344FC7AAB373D625E0FE37ECD09162C42 -:100AC0008983F1FB250D24FE9B11B48F0EA8A87716 -:100AD000CE24A25E63C3B89C6872572AAFAE237E51 -:100AE00070F27DB2791248938CFA2F529E668E8BEB -:100AF000ECCF72F7A83788907FBD5ED7E47E5EB3F7 -:100B00004CFB72F30A2517EB453FE8FDECB1D17DB4 -:100B1000E8856FD587E37AD30B1F96FF5D7AE135C1 -:100B2000082BC681FCFE3451E8877EAC1FEA875251 -:100B300079FB26E4972EB077E65EF845B3175A3C6A -:100B40005E06F24AF27E91EF67945E4D65BEFC5000 -:100B50003CDEAD2FC09F70F5E2E73C9D984572D416 -:100B6000AD5F34FD11E64F18C7FCE3FE4429F89150 -:100B7000A63C842F83E02B633C1F588685439897BF -:100B8000737E41F9966A88F329DE67BF25B850CF96 -:100B900049F12139D0FB195A5ED72AF2087ABEE80A -:100BA000CEF3CD35521D8CC61765762E1F65736545 -:100BB000CABBEBF9449B4FCF1F015D5EE69AFC2157 -:100BC000E4EC87F24773A2D8571DC4065D0F5F6837 -:100BD000FCA0F187DE8E1CD3E567FAB2236FA21D5D -:100BE00019DDB71D797D9891F4B5DE7E68F6E27760 -:100BF000495C2F6724F27D8E69C3E7D9D0EFB02618 -:100C0000F13A0DCD0E75E79736737E78BD63892274 -:100C1000A13D41BD9019867F916FD5F8AFEA51890A -:100C2000F28D15422F7536F3FC5B7589ECB7C0FF6A -:100C300016373DB189F78D949F2B545A150B8C3B79 -:100C4000D325B930AFE316F9BA196E89E7EB5C9199 -:100C5000FBF42D3AFACE117C349305EBD01FD7EB81 -:100C6000A53957B95FA0D74F73C4BEFB1CDDBEFBCF -:100C7000554DDE07B001FF4C7FC09CF4FDFE80F6B1 -:100C8000BE46478D7E2AEEC5A11C1DFCC6A4C670BB -:100C9000FF19E937F5AA42E3D893045F0A7FE6CB50 -:100CA0008B79BFA0984F3C5FDDF485C93BB26FF8EC -:100CB000AFE5B7C6A29F3E3AE4B76BF34E53184B6D -:100CC00047C74C674F6689EB3FD47E0CD7AD43A333 -:100CD00083A6477BE059E8D9BEE8742D3DABE9B364 -:100CE0007FB69ED5C6D7EC8036AF5EFFF615B769E6 -:100CF000FA74FD1603E54B268BF878B2C8C3CE4FC5 -:100D0000E2F1C1AD493CEEECFACA62407BB9B38571 -:100D1000FB272EB3FD38FA05A17C1FA7E7C331CC12 -:100D200087FBEC4C69B7D0BE67119012F73DD3F842 -:100D3000BEE77625E0213DED52580DC8C9397C0F3C -:100D4000E679F8806F21EAE9873F1962A0FD7725EF -:100D5000D08EFEC9D83C85F68F1C6695F2C19DCD1C -:100D6000663BBED7B5EFFFB41A719CAF980B43B882 -:100D700043CDE6EEFD1BD407A5729B8CF9FBAE209C -:100D8000C8083C3F6941A018E3A0C9ACBD16E57B8B -:100D900002D2B117FAFD2A498BB37BCFEF17377315 -:100DA0003FAE3846263F6E8AAFBD18F7ADA62892F3 -:100DB000AB169FD5E5F75FD1C51FA1FCBEAAF0FA1F -:100DC000435DFEBE91EB99EBCDEB4F40DD067CBC65 -:100DD0005EE373A16F581FF9FD9D26BEEF133C69BA -:100DE00064E807B30B89BDE663AE95E7DFD712ED84 -:100DF0005663719F8EFBEBFB5AD2DC6A6EDFCFE746 -:100E000076048BD03CEEDC3E5BA1FA35911FEDB150 -:100E10007FD2C7FE88BBD17E08D5695FFB21C55F45 -:100E2000AA94F6B95EBC69750B4CD43FDDC8B49F7B -:100E30009BE474E7F96837F2F9CEF3696E84EB79D5 -:100E4000C1A71ADFEF3B77399AF6414D6E15F78F40 -:100E5000830E8BEB59E25BCEEFF5A943FCB84FFB59 -:100E60001B21173BA383C7B213C3F73DF83E47CB03 -:100E7000BA47679F33D27EB984F9486D7FD907722C -:100E800043753DF18CE20F23AB67386FAD9BFD1AC4 -:100E9000DB2993D438C4FBE5446D1F538DA33CC4B8 -:100EA000B757A8CE508FFFDDEB9807EB511AD659F4 -:100EB0003C0AC8FFABEBECD46F5CE7A476FF3A9535 -:100EC000DA878EC73E8076BFDA6DF22861FAE39D3D -:100ED00064EE77E5657F524CC5DF7F6354873EE55E -:100EE000C10E19F5C58D57611D117527CA65C43727 -:100EF000E537B342FD4C69710CF66FBC0AFDB0E7F3 -:100F0000AF2439B83DAA53EA462793B4105FFC2DAD -:100F1000C9DD9104D7EF71783EC176B734FFE02583 -:100F200046FD73BC7FAB7C099ECB0F14525E391F0C -:100F3000F3CA7934EC42C4DFE85613ED976BF9DD60 -:100F40003C4DFEBE8ECC33E78BBCEEABAC83F2CD1A -:100F5000051608B40C0817A79F5B9AE794301F98F2 -:100F6000647261BDC3E82C4F3EE6635B9318C547CE -:100F7000ADADC9196A0E720FCFFBBAB5BC2FFBFE1F -:100F8000BCEF918F627DA4B7AE9A687FFAC8A9586A -:100F90005780F60B2DE4FF69F5C82DD1BCCE8065D6 -:100FA0002CA03CD38DA29ED162F69A93495F050E88 -:100FB0009E80F77E7F99F17DC7F60F695FBBD830C1 -:100FC0003C05EB7E0F4A43E3B07DEAA3D81C6A4F91 -:100FD000C55E44FCB418AC2ACE7B669D5A82756D02 -:100FE00027D6B112AC637B6B9D85DA93EBECD49E74 -:100FF0005AE7A4F675B88EFC731C9E477E71BF65D8 -:10100000A37D92296FD9146CF316C650BBFBB6189A -:1010100013C2DB12CBB66BF360BD5A203AD080C945 -:10102000FED6A7BC8F59FA81DD337B474AA3186BE4 -:101030007BCA3B5D990CE34EEDFF93AFE0FE9BC98D -:10104000CB1EB3005C734FD91ADAA0FF76F2F2C759 -:101050006CA86F8F4783D2C3F5AE38EE1E0474437D -:10106000A590C605978D837E82D65F31BD641263DD -:10107000B71477643360ADECE495D32D80C75BACD7 -:10108000DE1F63DFE44B9A5ED20FFBCC87F5604135 -:10109000C948713FCB9012B1FE65A6C3FB4672589A -:1010A000FD9E5BFA13ED338D714BCC41871F8CB4E1 -:1010B000EFC5EC1F2784CBDB4C47E91B488F89C960 -:1010C000BC0E78F424C91D5E5FA17F6EF439B504AF -:1010D000E934E642591DB633CB1DD4F72C185B8793 -:1010E000F25C62EBEBFD627ABF3C99D78D1429521A -:1010F000445D89FEB97C6026F48F8347A3294F3075 -:10110000FAB4B716EB4F4B9D9979B2A6FAA8EFD86F -:1011100082FB6DA32BCE9424A0FCD824179A89318E -:10112000ACA32E01EE17DAB1A00AD7F54431D6FFF1 -:101130008C562517A2ADD0DDDA80EF17BA625C8538 -:10114000E88F9F564BD0F49C52469D2880E7A60E10 -:10115000925D1618E854E0A68997A05F382C8EF2AD -:10116000BC85CA9A2B27A81FE3AA51711D5B7E5D1F -:1011700045E398C9AEEF9E51FC2FC83F459E38CA43 -:1011800009023E4AC2EBCA60DD0477A15DF6474919 -:10119000C8DFFF5A6287FEEEFE1296CBC37CC3FF08 -:1011A00042F78F44AB5100E86E93BD04C7DB6D92EC -:1011B000EC0F51DF538CCFFB861855CC1F9525467D -:1011C000458C3FB5441A7F0EE1CF891B85D7CA33C2 -:1011D0001C11F7DB6EB3929DA8782B87FCA2B6DBBF -:1011E000D2C95E54BC35A908DB3603F7D32BDEAA7F -:1011F00028A7FB061E07572CFC915BF429EEAD587F -:101200005849FD5629E52738DF959CB83CCCAF4DB1 -:101210001B945AA244F8810349FEF3447EAFD030B8 -:101220007CD32480FFDEA37C9FA2222733E2F9191E -:1012300005524978FDA8675254447F7689A324BC9F -:101240000E756E456A44FF96B99911FD92A3056427 -:10125000BF410F5494801E380AED5260C1025107FD -:10126000A5E59F0A054B15B68BBCACC2E3EB61F05C -:10127000877AB0C41669A77747733B5FCED6D0068E -:1012800049F911BEBF5D9668FC24DC4E94CB15363F -:101290005E97158987BCA346B2977931921FE3FA0E -:1012A00092A34BEBD0F4966744BEAFF961E5023EE2 -:1012B0006D5EE673B7A33FA2C1ADCDAFC15F2E2F68 -:1012C0002AA17CF735D6A18797C17A503FE8E1681B -:1012D0004A16FE1AF81FE4AF897324F04BECCD7E5A -:1012E0006BFE7A05E82B47B8BEB2498958B7D79745 -:1012F000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9F2D -:101300009E9A2087F5333F4E880FEFBFF8E9A688F5 -:10131000FB491FCF7184F7B77E3A07EF4F51D45A7C -:101320001BF0E53126B97CC8076DAA1203F4283EEC -:10133000EDAEC3B6F4432F96ABB2A9E77C75D84E99 -:10134000BCE86F33C3BA6E1A26AB18BF6B7E881E1B -:10135000DEBF26F3BCC3B1ABAA15F75977FB542BFC -:10136000FAF3BB1F54ADE887EC76F37319EE2C0348 -:101370009D8F7167F37AC5BF24F3BA834EF1BED651 -:10138000FA8DDE4E841BEBCCD137A8FA264875E5E2 -:10139000C7D0BFCAE9E95F1D53FC369CEFD8837EF6 -:1013A0005BF87EE2F5FA577F041E43380A99E40998 -:1013B000D723C596284FB8DC96DA1D11FD93C20FCE -:1013C00099EA4C8D78EF263533E239F01B87A15F1F -:1013D000526B62546FEB33F07A5B3D1E57A4F0F80A -:1013E000CE65B3A33B83FB66726FE7915CC5865EF7 -:1013F000CFB7A5A4707FF03F5218C1352B85C3A786 -:10140000AFAFD5F76BF17C0FE293B99CC8E72EAB79 -:10141000E10AB8BCACE0E927A6535D6DBEE1DE2C65 -:10142000E8573CBD753AAFAB35ECC13ADB194F3FDD -:10143000CFEFDF60C837823FB0CDF7C274AC2BAFBF -:101440008AE2F5095551A23EB46E7444DCA3183EFD -:101450007E6A21C69FFB8D0CF3FC8F99C00EE6853A -:10146000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A837 -:101470003F3E8BF2E6A5509EB148453C5EB45BA86A -:101480003EF4BE7DA529C807B35278DE2B7BCF443E -:10149000279D2FFBE7C151FC7D7060FD308E73717D -:1014A0007736F9E5D903189D27D1E801E1335D8F3F -:1014B00082F081CE6330B713F36FB50E138D332BEB -:1014C00085F3E3F5B63DEA89E30C6B7641BB2085F5 -:1014D000C7CDB7E2BC046FB0FF2CDCD0B307FBCFA5 -:1014E0001EC9FB486F59CE0BA27F1BFC510CEDC3EC -:1014F000BC1FCDF1C63282B46FF3EEA26CD706BA30 -:10150000CEF1B8C03FB0B643C5FA0F7F3FACB718B5 -:10151000E8F42E457CDC66F60F26BEB2AD89C179B3 -:10152000AEB7DEB8EFF921E0047B327F3CA79736F7 -:101530003FE0D882747C579C3BD1E001387E8C70B0 -:10154000687075C3A3AB3FEF147E7B278E971BCAD1 -:101550005357FFC940798A6A09F424F4F77CC85CC0 -:101560003E95E8437950DCD2C2F9C69F58526C834D -:10157000B6A071158F8FDB9588BC9866CF268AE759 -:10158000C7BEA744D8A38922FE1DAFCB4F4E6C9C8B -:101590004EE7F826EAE2E25FA488BC651A4B0BCF5F -:1015A00023AC15F1C6E5B68171E89F2A10E7CA8021 -:1015B0006F932AB371F121BDD0B08E459C53D4F8FE -:1015C00070E469FB9D38DFC8D3EC0EF207B471BB41 -:1015D000F3131C2F97DFE37819D531ECE949D037A5 -:1015E0001E3132BF1A5AE7040E2A833087E2A4CB99 -:1015F000176C645FC61C9D43F5DE66A781A961EB8D -:101600008F52A3991AA62FADC3E223FAB2A04F5D61 -:1016100054A41F902FE68971A5458CB73FBEEC08F6 -:10162000FA05F9B6E5E417C48D1B18311E6B532279 -:10163000FC833CE67163DCE802FAE27ED998D34A87 -:10164000841F302EB091CEA18EFB30F2FA847391BC -:10165000FD037DD1A52FFCB1DCA7D12FFCA1F87330 -:10166000B823F197501E89BF244F24FE521644E23E -:1016700027D51B898FF4E52322EEF75B9317D11F43 -:10168000F0C08488E733C18085F7B31E9D16F1FC56 -:10169000E08DB323FA4337DF16F1FC70FF9288FB2D -:1016A000D9DB56FE207A8FAC5F1BF1BC9EDE37344F -:1016B000FE34627C8DDE3EF8FBDFA437730AFF50F8 -:1016C000D03B51D859879BD7AD75196D8FE2797C86 -:1016D0003C3682FACE81E7E963D1FEAB5497E79BB3 -:1016E000C6685FFB97B24742BD940EA8356451BDF2 -:1016F0003CD5F5FDDC6088D867B73BB93F647772AD -:101700003DFE6B133F2F950EFE26D929030BC5D93D -:1017100016AC77648299AC8F639C5DE7E818A63AB3 -:10172000306F07FDC921BDAAE9D1DBCC6A6D07E89E -:10173000975132D793A03FFB39619EF7A5078DDC07 -:10174000FFF019D1FF48B7305F6C1ED919CA433B6F -:1017500058A284E700E2427A5CFD0E887570653617 -:101760009DC37A134140BF5975D17ED3AD9A9E5A1D -:101770003E9CF4D4655BA4FF767969165D3F7BBB24 -:1017800099EA07CE8A3A470D0FFAF3D6DA396CEDAB -:10179000FEF22D9B62D0EF3C2BCEFF6AD7270BFCCD -:1017A0004D76CAC2FE59D6603E6C1118F138C07B26 -:1017B000E5918ED8DB18F99B9370DD555BAEDCFEAE -:1017C0002AF4AB0DC1646E377CF4DEFC77F9B9EE18 -:1017D000F97F8BFCAE408593C7F91562FC5BA0B125 -:1017E000039E6E013A38B07D635219F2275CA7F36D -:1017F00071338F3023CAF32C6F26D54D9C62AE33E4 -:101800007B01C4F94E95E09CCB3C46CC5BBD737B21 -:10181000650C3ED73D9E360E300CFA25EF3A7CC65D -:1018200064CC1B4CE67513309F05AF7B16A53F8C2F -:1018300076499BEF1DE6BD7406E83B9BB9685C6D7D -:101840007C86E9F9303DB57BF9AA8F1260BEB547B9 -:101850000D948F58DB6CA678AD6BE57FED780AEEC2 -:10186000DF91DED10FEDF6FB2BFF3604F9E1D6CD8B -:10187000325381DEAADD7BA7336C5FE5ECD22B31DE -:10188000781FECEED6A7D058BE6CA63AE2F757BE4A -:101890003C24DC8FAD74162EC7F7D8B8EB3BEF585D -:1018A000FCD2F014AAF712FCB442F0D3DA178792F4 -:1018B000BFB536A69B9F787F2BAF1BD1D67146F064 -:1018C000E3CA97BE89F8CEC46EE023D5CCF7C5D461 -:1018D000A160EFDB2EE7D2771F8CDE7F75C2BC2DB7 -:1018E000573F89C5FE9E37FF4AF0B3B9D7072FCAC5 -:1018F000A26F4C687F5A3BEFB9A029211FE90E72F5 -:10190000B601C7BFED772F5EFA00F1D3FCF2D69F88 -:10191000E133D779FE7397967714F6C625F001F672 -:1019200086E28B2E16CDCF9308FF46C11DF92CFA07 -:101930009E874A7CED66C7711FA7B6D5407526B154 -:10194000B8091496AF8B950D9A51725B9CA0AF8528 -:101950009EF97FCEDB2AEAA83E20D21F2A38B43275 -:10196000C20FF2C05FAF7ED033DE5ACC2FE9FDA1AB -:10197000F101C36253DCF7F84587A6F5EA17414049 -:10198000ED96C688AD21F835E8F4F37E2157F53899 -:1019900016E6FF03D1FCFC33980EF47B7F9ACAF560 -:1019A000B72D83F1F36952E7300BE8CB16E7A2C7F6 -:1019B0001F856B96417CDDD8AFA53335F9C47FDD3B -:1019C0007ED7A111A4B7D8B7301BE243E43DF4742D -:1019D0002BC0F3ECF9617227DE0F1CFE6B2CE67D49 -:1019E00077C4AB6F213D824765DAFF89523A4C8E4E -:1019F0005EE2BB57510F029FCAA9DC1E581A797EBE -:101A0000D1A2BA19C60F5176FBA8F0737F8D4E1E76 -:101A10004F561E7EBFBF09E871C9D0169B03E3AFC6 -:101A2000DEBB3B16DDFF0C93F703E4C35567DF1EF7 -:101A300063A7FCCD96FE180FD607F87730462ACC60 -:101A4000A7E4F584A37A332C2601CFE927503BB2D3 -:101A5000297F19F2597580AF13C7C642BEE18D12B6 -:101A6000F53B1B6BE371BCEADF37A7A13CBD9CC40F -:101A7000E3CD97AE66F3F715A6E0F341A74310D385 -:101A80006FC0F8E46511D7745E95E9396DFE918DEC -:101A900085B21DF82127B0F100C5514D6615E91A30 -:101AA000F51CE378688A22B9AF6E99CAD0EE77390F -:101AB000984B82FB3BA2837FA4F36ECD6615F3ADFA -:101AC00051F68D2C1EC6DF21F659870347E179298F -:101AD000EDBA365F54D3D31873203F50DE374AD95E -:101AE000C826DBC2F11C437876A4723EDA111D30A1 -:101AF000609E253898B16709AE109C8CE6D5E01C35 -:101B0000EEC7F3843B4CC1F3786E06E0B223FD8749 -:101B1000330E276B1AAA629E20CAEEA67544D955C9 -:101B2000974FEA0957752EF3A35DFFF943AC5B6E3F -:101B3000518EABA3437D0BC8C08E814CC8F9CF1F1B -:101B40002FC908EF836219177A7FC8AF363E5E3718 -:101B500089E2099F8CF12FB431F1B84E95D6A76078 -:101B60008A298FE301F7DBAD167EBFFB79E06F1B9F -:101B7000F66DFC39579CDD3A4D2239E1F5B8421F2C -:101B8000DC2705CEDF08A4FD2A702057055856BF74 -:101B9000B19FF87495A1E9A99170FFEE28AF2B15BC -:101BA000E67BED43039D6BFDF38B51FE0AC0C7B08E -:101BB0007D5B92DDBDC8877EFC47DE7BE8C974A4EF -:101BC000FF3E49C53C6C973148DF37A96AFACC44DF -:101BD000F50D8D1F53DDD39BA9DE4938CFB8C61A4A -:101BE000DA8F1ECF36D27E74B6380F5EEFE4FAE39A -:101BF000F2E921CFD684E17F492A972F16F40E40CF -:101C0000B96912F2D9827E0AB47B85BFB4B7F5D622 -:101C10002C352C7F58C30EA423BE1F6287A8D5AED7 -:101C200077F9F9B9CAEC772C77B8C3F86F9190F7C8 -:101C300045A9224F96EA9D8DF0AE6AFDC414ABE231 -:101C40003999FAFE6857EAC19FB2F782976EB9D503 -:101C5000C951B51234E1F3D517F8F957A0731D9E99 -:101C60003778F99DC6118BE1FA5EC035D695FACE6C -:101C70009AA9BE72AFD1938ECFD79CF93A17F55679 -:101C8000090201F07CDDBC6A00E20DF8BE281AE50D -:101C90006B17233DA6C9670ECA27BC9F837C5F8054 -:101CA000FDE1A4877798DAF9F9D3BDFCFC29F03D72 -:101CB000C901F0BD1DFD861C3BC801BD3F94E47BFE -:101CC00047BB81CEC9FA408F0FA67ED11CECEF68CE -:101CD0002FB1937C635E3F0FE5347080C6A987D82F -:101CE000044927314FB83FD9E88C25BA69FAF1B0D9 -:101CF00093093BA1C6E17903AB2C47C845983DE465 -:101D00007D612F4FFC2AF0F82FD176B8855D10FE4B -:101D100014F3E6939EBF57D8AAB5AF4F98B91DD616 -:101D2000B9F684DC5D3F8EFE6B40F0C901E1CFA2C5 -:101D30009D5013783D0E5E1FBD99D7D58E71AF298A -:101D4000C6B3CFE3CA371EC47682A7BE18CF3E4FB4 -:101D50005AD07E909F81E6E7D91B0EDC948DFBDE86 -:101D60005D67CD0CF75D1AFE1AFCE34B8087FB5BC9 -:101D700000FFBDD825580EF11F58EC74E6EC79BF72 -:101D80004BD2F4C7A90AE4C7CE0639D40740AA80CB -:101D9000C1B1FFDBD4938FFBA09F95E67E3E15FD7E -:101DA000ED742FB55D27FF9A8CB660EF69EE47356D -:101DB00098DCD9C83F0D0323BF1FA0B54FA61A89D1 -:101DC0000E057D7CBFEB482ACF6F0EF1B1C7908F17 -:101DD000AA1A64BB1FE87EA941769BC01F3AEFF6A2 -:101DE00026E3D99C0BCC77CB44B4F3228ED4BEF738 -:101DF0007217FA2960A7EEFE65EFFB0FAB99F65B51 -:101E00006340BE5AD624B1FF001C2C7F26F2F9D5C0 -:101E1000DAF76A1AB71CC6EF88AD7C4E771FFD153E -:101E2000FA0E46A41F732455F827592C0BFD13E016 -:101E300023D20F46851D3103DFAE48F7EE437BFC0E -:101E4000B2F8BE02E85192C77D4E615744FD417021 -:101E500007AF2B1EBECD2F1BE0FD098A5F467BC559 -:101E6000A0C57D87716E6F197D87C9E73E8DFB3EEA -:101E7000CB853E5CAEF9697EBE3F026637C24FAB92 -:101E800016AB1FCFFCB5B1B8FE6D12C5CBABB645D6 -:101E9000EEA7548BF5AFDE7CF2309ABCCA7ADD7DBA -:101EA000B1FE6ADDFAB57DF3CF5323EBBFAE773FCA -:101EB000E42F46EE37BC2DC6D1EE9BD2B87EAC8265 -:101EC0006520DD56FB65BF9FFB7936FC5ED09D62C9 -:101ED0005D770AFAD33AE1B9CA6D923F803CFE7849 -:101EE000649DE95DF58BCB90AE7A3E5929D6BD7CD9 -:101EF000BB91FC55FCFE0FCA9D9E3F568AF5AFD4A0 -:101F0000ADBFCA2BE9E0E37E744FF8EA6F413A5760 -:101F10006E37B2DEE0D3E8B552E3EB3EE0D5E0D475 -:101F2000E0FEA1F0F64F13F9AD116C04D1A93CE12C -:101F3000BAE8A4F773771D1E41DF5BBB7C6420C544 -:101F4000FB1A1FE8DF2F137EF2D4CDDC6FBCD45810 -:101F50006C1D89F14C9BC125A9149FC58E04BCE45E -:101F600037CBAC02FA5D4D599BF0FB8379270AE62B -:101F700060FC9F7FC240E7EFF61C29A07DE7FCA331 -:101F80008312B228CFEDA2EFE3C038645FBBDAF270 -:101F900036E1F984AEB692021C5782E7D00FC8131F -:101FA00076A2A62DCF1A7EFE7C4C1A8FEFD73B3F30 -:101FB000FD39FAE9537719E99CC55463F04DACDB60 -:101FC000DA7344A17DF2D527963C1485F47D51A2A5 -:101FD0007DF2C3ED6B1317229F3519EDB8EFDDD5F8 -:101FE000F4E30378DFB75DA2EF5E54379766EF80C6 -:101FF0007EDE967C57F8F9B33C874AF0B1542BC586 -:10200000CF53FB19C96E5E4CB3FE16FD9F95EE2DA6 -:1020100024DF17F7EF3151DDDE0E89A1293BEC3CBF -:10202000F80AE2E3E2AB274DE88417379C34757C6D -:102030008F3F70C92FB300C5CD1B4D18C7546ED14B -:10204000FA1D26A49347F84755CF7D4CFD95E8CF60 -:10205000C37C2B9F91A97EF760F36B26E4E7AAED82 -:10206000124BC90CBBBF598AF85EC312C6F960890E -:10207000D03FAB987F7D1A3CB76A23AF5B608F4639 -:10208000D6016BFCBD42F0F7AAEDB3E8FB533DBEB1 -:102090005B8871E30DF81CE7EF659B23EFAF107CC5 -:1020A000BD42C7D73F4913FA67381B8E7CFD75A127 -:1020B0001A9703D7BF3EB972406FE7ECDB84BDD6F9 -:1020C000ECE5E58081EC8DFEB9CEC62B046775DBAF -:1020D0006513FAA7654D5F10FE2B9A5AA97EE46638 -:1020E000E65D8DF8BAB9C96A47B9AEE8E07A685AD0 -:1020F00093D9EF97F07E3DD53977B5F0BA49DF7EB9 -:1021000089FC1C4D8F69DF775C26F0B80C14787A57 -:102110001EFABB3C6EAE1271F28A615B0EE33E7B2F -:1021200095B8BFFAE8C158F40FA7B12F6E47FAC0AF -:102130007C0CE763CF44E27DBAD08BD3B773BDA8E4 -:10214000B76B5DA9D933298F09712AC2B57A7B246F -:10215000BEAB74F1F963693C3FF6820EDF15416650 -:10216000CD413854D9E5A7A7DB159CF7482ED85B9D -:10217000B4936AD6F77E87F14DE1676BFD99E21C57 -:1021800078BD7DA32D3C6E8E4AE7FEC2CAF1B20F28 -:10219000E9D51D6F0C3A98AB1A42F106C419CD6906 -:1021A000493CEEC082923732649698188A371E7185 -:1021B0006EAAC8837EF5762EF79DE3603C3C7FAD2A -:1021C00030F247ABB79BE99C6235D09FE28A267E0E -:1021D0009EC2D3249522DDC15F3F9A86FBB19852FF -:1021E0008575CF6AE47C3FABE40BE297A383F87A72 -:1021F0002F2B6A4A6FFEBBE6B7E3F93035CC7FAFD1 -:102200000239C5E7AB9A783D52C3816FFA67A29E47 -:102210006BFEAFFE8BA1FD5AD845CD2F0C825F38E7 -:1022200090FB45F4BDC9BB857C2DB3F37DBABB855E -:10223000FD61521DF17995B1FE503CFA593B78BDD4 -:1022400000DB871F8503FDF8F64B75F1B0EECE97E6 -:1022500024AA87C3F7F17B949D4BEA3F41BFFBEB78 -:102260001D16F237EF06BF654A5E4FB9D4E45BFB3B -:102270006E560D7B88FCCF87581DB595829F3B1B02 -:102280006BE9FBA09ABF42EF0FECE98F540ABEAF97 -:10229000D4F15F547A24DFD5BC1D4D7E63D751D96C -:1022A0008EFB3180AFDFA485E345F8210D07A288BE -:1022B000AE5D276D6447FE2CF8EDA2C83FD78C9326 -:1022C000090F86F1BCCD6E796D20D211F18EF5F734 -:1022D0002FB7BC36829FFBF613FE576D9323BE0FBC -:1022E0005B591FF9FDD79AB76FA3EF0855EFEF863B -:1022F0006B88293104575F7220493C8E34489171B4 -:1023000064F53ED9135E7706EBB903F551BA900731 -:10231000A6049331FF35009D0680AFA689D3D5D0A2 -:10232000CC5B98FF169E2731D2FC3DEE17F956E3A1 -:10233000FDAF33AD7CFFFAAAAF02FBF70F94A9AE55 -:10234000F3FEB7570E0DD7A30CE104BA561B83C991 -:10235000146F9E34107CD5272F270FB2A15EDA525E -:1023600082DF0F9D2EF4DFE181D6E5C8CF3E9C379A -:102370002534CECB69BC7E8FE17A9DE86DFC928FCF -:102380002BD6FB109B2DE26ACE4F39697CBD108F96 -:102390008C4BEF251EB95EBF13ECC3A98512D63353 -:1023A000293E8C87F7BCC7F5424DF3B28F90DFAB67 -:1023B000DF37539DD7FD2DCB8652BDAFD77B03FAB8 -:1023C0001B5FB7ACB881F283D24304970FE173A2CD -:1023D0005F732619EB522B9BCF2493DDDD3B7A9361 -:1023E0002F06FD97BCE9781DFC09E23FF06B88FFE2 -:1023F000F6B415687E8C15C7AD3CAA78103F95479A -:102400000B8E57A07F71A2A800D5B974A280FC984A -:102410007CF4636C21BFA65B4FA6733FA6AB358AE5 -:10242000F20B121BC8F9870D8AE09FD50DAF93BD43 -:102430005FDD2847D42F6AEFDD99AED038CB34FE6C -:10244000A997DCC41FBB78BBBA710FAD6F95B19E65 -:10245000E85DB3DDC8EFEFE0ADF67D581F8BF721E7 -:102460003E8EE325A0C334933F03F3D3C732B99F15 -:10247000AFA7C7E7E93CFF71ECAC7700F2CBB14204 -:10248000EF507B2F76C2C78A785C2B097C37F073BC -:1024900053FAE73E4B97C4774222CFB76AEDA9744F -:1024A000AE3FA7997AFF2EE06FD2B57309EC3143A6 -:1024B0000146C546FB06E1D7A7867DD761CECD464E -:1024C000F2174E31FBEB58EF3843D3B3E3B87DD569 -:1024D000E7CBE789F73C9B55BE5FA43B3F334F3BBF -:1024E000DFA43BEF364FF83BF374FECED3E9C28F47 -:1024F0001FC286A01EAC17E7EFD60E8FF287E7B398 -:10250000F4ED61B12F82E787B0AD19FE2EE57D8E27 -:10251000B59E7D85EADDCE46B1813CAF47F9EFCA75 -:102520003EF2DF35DD72393782CF34BA5C12DF8399 -:10253000D1D365B7A6AFC4BE5DB4D8B7F31BBDBBDE -:10254000519E2B2D174DBCEE3068427D56339CFBBF -:102550004D974A25DA6F0738FB9BC3F4FBA5541E41 -:102560007FDD7F8B4479D7567C1EE3AC7A89EABC49 -:102570002B03ED26E4A7210D8B1F26B9F5B1D32C33 -:10258000ECBB1A332DDC4E76D34F5B77B71D8BF740 -:10259000717D9C482D3E8F767186B083FA735143CE -:1025A000597B593AC033DF2DB9B01EA02F3ACF5E08 -:1025B00030EA7544C3F5D2BB33DDFB4E3ACA79FB32 -:1025C000E55B308F7A6CF867FDD18E56F5C1C71F79 -:1025D0000B3CEBBF2BE31AAAD6E2F7556A9DDE0E41 -:1025E000D29F866F6347301CA7E3376B25A4132364 -:1025F000FEEF4B7E3E13E37E96CEBF770FB8A77DEE -:102600009755E9BC4EEB98D19F41798A9CEBDBF75B -:10261000AAD9F7462EEAB3CED6A3B9A630BA5E5CE5 -:102620000B7A00ED4AF3C164D516CE7706E237493E -:10263000D2F84F11F632920F2F221FE6607B2676DA -:1026400010EAE35DA76207E3787B79DBCDAF4DFC51 -:102650007BF6101F0D9917130EDFC304DFA57A3E1A -:102660000E631D43E68C0CBF5FDB171F5B33888F47 -:102670003B22F8585B6F3D7ECF07E38016337DCF5A -:1026800007F3D78E3039199AC1F5CF58F1FD9EF175 -:10269000CC47DF391C2BBEE3335E6101251EF7CD2D -:1026A0000232DFF7E5E72DC6087E1EAB045AB18E75 -:1026B00062BCD8E799C0DAE9B9292C48AD9BD9E9C1 -:1026C0001C451173513BCE12988EEE544E7D3DD574 -:1026D00025069215C7798B38AFD10BDD42EB57E851 -:1026E000BB3DC49F329ED7E9FDBB2FB333B8DCD3CB -:1026F000C74590BE9718E5B9F07B6D38C9448595FC -:10270000637DD3648559A201DE5D870C24CF2D1D26 -:10271000AA1FEB535D09E2BDCF19D5E18E75737920 -:10272000459383F518DA7AF5789800E3619E6DACED -:10273000029128E13140F3DDC8F8399242A652FDFA -:10274000736946A6D0F7418AA38A218E427D6FB075 -:10275000F8081FD33354BA8FFB25B130CE848D12C5 -:102760007B0FF73FB2F87AB5F1270023E0F9C2E911 -:1027700019DC9E614AF5BD78BE8F124B05CD2576DA -:10278000FE9DA364FACED1F5E2B52B997FEF32F628 -:10279000CE60E7CF0A42FB492EFCEE516CE83B9B32 -:1027A0002EEDDF830844FE7B1077642CF911F2A331 -:1027B00056AFC7BCFCDF7DD0D7EB85D5E7B10B6149 -:1027C000E7B0B5BA926DFED92A9EF35B9068A1730B -:1027D000BF7996FEF968C7063ABD34FEFBD2F6C152 -:1027E0003498E21FED8909F1BB95B9C721BE437545 -:1027F00083FC3B50DDE7AE92199D57B49A797DE595 -:1028000063201FF81D26902E15EB68D883C5548FC2 -:10281000B9DE6171E1790933C26D0DC15D6B11DF04 -:1028200005B5F07D717D3D68ADCD40DF1DAD65D155 -:10283000740E3D29DABB2E03E0BA2FA688CE776747 -:10284000EF9CE444BF317CFD93B4F51B7AD647C2BC -:102850007A1FC9E8A51E515BA7F6EF76D805FEB42E -:1028600075DBB5734A6E25E29C92868FC7A2F9BAD2 -:102870008DB8F39F45EFAAA837F4EBFDFFDC29BC28 -:1028800016A064000000000000000000000000002E -:102890001F8B080000000000000BB3D36660F851E6 -:1028A0008FC0C19A0C0C5DD2A862B4C41D120C0C6E -:1028B0009780F80B106702EDF5926460F006E26D08 -:1028C00040BC1D88C5A518180280381088FB80FC04 -:1028D0007E204E07E224A81BB30519187281381F09 -:1028E000880B815848808141588078FB8B151918D6 -:1028F0005EAB22F85A6A0C0CC91AF4F3FF60C3816C -:10290000B6F4B5EF16D0BEE56E08BE0490BDC20D9C -:1029100055CD4A37FC66AC42935F8DC65F83477FD7 -:10292000810D2A7FAB292A7FAF3903C3072435DB0A -:102930004CF1BB051D2B00FDA788274C9730A2F258 -:102940002732A1F2F9A17C00BE1E313CA803000091 -:1029500000000000000000001F8B080000000000C5 -:10296000000BED7D0D7854D599F0B93F736726992A -:1029700099DC24433260126E7ED0A001879860B04B -:10298000586E20E147A30E082CB440262888166D07 -:10299000C49FC6DD500609BF0921E14F70D11D104B -:1029A0005DEA63FBC5565B75BB7682D646AB356880 -:1029B000D787767765A015BFBA761BD96D976EBBA2 -:1029C000F57BDFF79CCBCCBD9900FEECB7BBDFF30A -:1029D000C5C7E770EE3D3FEF79CFFB7FDE73C725BC -:1029E000FB59701A631FE31F9413731963B5A9B2DF -:1029F000C5C362D9398CE576488CD530B6B25D89CD -:102A0000CF827F1676B4BC82F5E56D6EC35DCA5881 -:102A1000FF036E7F0DD44F6F57C26EE8DAA8F8A897 -:102A2000BEACCB15761BF07CEB472FE7E3FB8D525A -:102A300098419DB1BB199BCCD81A0FFC13EACB2A45 -:102A4000921DF8FEDD2D523886AF99E99B04EF6F99 -:102A500065FC7DF3038AC664A8EFBBAD894D64ECC9 -:102A6000961E98C5430DD9C7BC3D63058C45F82318 -:102A7000D6B205DE57A6DE4758D7470AF46B8E3923 -:102A80009EEF9BF53E0BE07B2DF51CD6730CFF31C2 -:102A900085B14B993F783A1BFE1D66E18F15281BC7 -:102AA000F2191B9DC297B3640CA01FC5D85CC65C0D -:102AB000AC1CC6A9BDCCC5CA607D161EDB381E97EE -:102AC000354984C7653E46F577E74AF1074BA91FAC -:102AD0009B5E0D253C2FC88332C8CC4228231E960E -:102AE000C806F8E7B65DF61EAE7F034E359ADA27C4 -:102AF00002F07E018BBA18C0F7672C46E56216A774 -:102B0000F2CB2C41702C6543252AD4EF52129B182E -:102B1000CC130E45A7E3FEFEAEFED8BB12BCBFBF72 -:102B20005AAA9D0225F3E5D1BA2FB43E6B7E954596 -:102B3000AEC37118935D113F63E3AD751E66B18A34 -:102B400020637A8F8FD3CB61D6CFA03EBE41D04BCE -:102B5000E3FB7208D6DDF33C0B633D049B3905EAC9 -:102B6000A1AEACF806A8F73C1EAB47BC1C6B01CC71 -:102B700043FF638D6E295A05A54B7745A00CA98CA0 -:102B80002980A7FA86F59202EDE646F938E34D4D25 -:102B9000665742FD704C52C573ECAFEB314987FA72 -:102BA00078A83F28E17BDDC5609C86865C57B20A29 -:102BB000F1DD334687B2E2B0969001BFF5A64ECF65 -:102BC000195B4474355ED0DA5C93F79B7B38CFCFCA -:102BD000E83DFBD3C7D67BC0EF25457CDF8E1D2E9D -:102BE000CB417859D4DEBF4865314F5E0ACF3BD721 -:102BF000C10B770ABFBB0E976D45BC1DEB53C3825B -:102C0000946DE3C3B8BD0DF0FE4C951C560CE4B3B7 -:102C1000220E7F85EED77DA97176AE83F697A5E06B -:102C20006854A6F6133E4C46FC38B706DA57A5DAC8 -:102C30003F81ED018E3D080FF55B73D48BF3441893 -:102C4000CD33123DBCB04EA77E83621DD7FCEF3062 -:102C5000EDD3DC861689CF2BE06BB0C36795167C6D -:102C6000238D7F4CC0658D6FCDF7C4BA10958D4A0A -:102C7000D523F7E2BA8E687C5DF38DC77723FE8E8D -:102C800078C231A83F79DDDF8CB91786B862FAF3D4 -:102C9000973FC370BEE50FDF8EEB7A2E8BD6F5D44F -:102CA00087675EBB910D9FF72D81879F9E9B3F4459 -:102CB000756BFEB9A63446023AAB34A5840BE8E541 -:102CC00058FD571EBED7C07ABF89F2A4D23C664ACF -:102CD000504E846168BF99FAA78F419E554277E4B0 -:102CE000C7490D520BB67BE2C687BE741F3CFAA9DA -:102CF0008BC37DC55F72B82FBB7EED9308EF653740 -:102D0000AEFDF93350BF028520F0DDA537ED5FF34E -:102D100077F0CF6F2CFCCBE57B18C9855836C09176 -:102D20006B4A0CF777D9F7DD36B972EC793FC99564 -:102D300042B33486FCB7AC4F22F9DCDFE866417C55 -:102D4000FF3377DC8DFCF5806452FB67DD71940FF7 -:102D5000C75C8CA13C5E76DC1B477E61AB9691BC68 -:102D60008E58F2DACC5F7A2F8CF76E8325CF399D9F -:102D7000D27B58DFBBE62FB65F0DFDCF98AE308A11 -:102D80004D4B5E38F1FCAEC06FA4BE9CE860999AD2 -:102D9000748533D043739B6293DBF50D2789AE9620 -:102DA00041C9D2F874AEE0B3650DBF10FCA9935CC5 -:102DB00072C2F3466D617126BA3B25E0490A7A7BFF -:102DC00017F7FB32840F7A21DD742971254D4EC32C -:102DD0009F2B3281EA3164E95BB6D8E1B4E4764BEB -:102DE0002CDBA6AF40FEFE0BCACDE6B67CDBF3B90A -:102DF00039AC76EAA793C37F20399C94081ED0BFD4 -:102E0000B4FF91B81447B968EDCF1D627F22158CCD -:102E1000D6F3AB03523C06FBFBAB23627DFBA4B8AD -:102E20002211BD9AA73D382ECC599EDAFFDBC5FE94 -:102E3000A7F68FE3C7C2574ACFE56E4A02082DBEF8 -:102E40004809CA6B8B7F2CFCF6EFF95109EE5F61E4 -:102E50005B69771DC2794021FEFDB0FE6431EEDB77 -:102E6000BB2EC02BF48F1C7E2CC07C29F85B841CED -:102E7000FCA003E8059E4B0867651A9C026E17D6F6 -:102E8000A1DDED0D521FF2E92FC5BC56BF1F6D9994 -:102E90003113F173478FC4103FB71FE95DF6E7B0F8 -:102EA000FED5F1EC304EF1ABC6E2C02500CF8A1E54 -:102EB000FB7E9EDA727300E9E6C3BEFC021CE7F6F5 -:102EC000A9090DE15C9D78553380CE6699BD5A32D3 -:102ED000035D7DD8B72180ED3F547B6EBC06E7D9FA -:102EE000A784D7C3F8AB8F94CE34399D12FDAE16AC -:102EF000F83DA9F6CC1C03F0B57CA39CE4C17B7D16 -:102F0000CAEC7806F9F97549213A58DDE696719DC3 -:102F100023D1CB871D2E96C079D404E173A4761FEC -:102F2000F4B5D0FBFE070A6F40FBEDF67617C98BB0 -:102F3000DBDBDC444FAB1BA4389352FCB642C0BB76 -:102F40007AB742EF4F9A12C90F6BBF6E17F476F241 -:102F5000F055AFA0BE3F03F207E5EE8C8D3FD42EB7 -:102F6000013CACD8C2E5D1C9DDB94BEF413922F4FF -:102F7000E51D62DCDBE28A8D3F56B667DBF623DABD -:102F8000956FAB9F3E927F631DD2759742FAF39681 -:102F90008D8F6921924F767B13396C5241CABE3CAA -:102FA000C186165C23A5E8C9A29F5BDBC0DE0C0CC2 -:102FB000B7375B8E48648F5EB49DD90676E6C4E170 -:102FC00076A6254722689F95A7E4882537EE52A26A -:102FD000638300C7AF5DD1CBF2CB496E3C20D522D5 -:102FE0009DE8BF45BB92C5945A946F172B2F68B1CB -:102FF000161FC1DF7B1D405719E87506D215CC336B -:10300000B3A73F233DCF900C1A2F4537B704886FE5 -:10301000715080A3D96376219C97C0C4DE6A2A9937 -:1030200092C74B15EA9B1166A087536BA5F8A15276 -:10303000DECE87F214E0BA069E37775D1EDF26A14A -:103040005D087FA83FDBB8DD0DED4C7F1E3D3725C9 -:10305000288BDA4B5FC6FDB904048056CDDBE33C18 -:103060006067114AA07DC25D4D5D6301288BA19F01 -:10307000CCFBD37B6C1720391EA7F5E2F8384E85C0 -:10308000125F8372C6A2E36542EE805CAD5481BEDE -:103090009A595618F566735BF979ED971BC276F964 -:1030A00071539D5D0FCC35EDF2FFE6D997D8DA2F3D -:1030B0008894DBDEFFD9A22B6CEF1747AFB2D5BFE8 -:1030C000BCEA0BB6F64B5B67D8FDA49FE6D27AD676 -:1030D00008BE1C09EED785BCFC89C33EB5CAA6EB69 -:1030E00013356FC33EB175EEF0E3509C98C316F5EF -:1030F000A5C9159F2C113E7F036CC2FD833F7D4CFB -:10310000780CF1799BFEC2DD9A89EE34D10FCD2582 -:10311000B4979CED4F2C8679D2FAFD9B24111D9E0D -:10312000EBC73C3DBF04905B80937300F577B264BE -:1031300009EE9B3BD7A0F777C9C902ACFF860DED1E -:10314000CDC7FDF5258B917F9A55F69C9483FDC2E2 -:103150001E37CC07D6106B03FA6869FBD171B4E354 -:103160002423C89660DDE34B207FB30ED787490B3D -:10317000EFC087BDA1E88712C021B5F7FF5EC2F797 -:10318000DF6706EA61962CCA45FF11A74AE7C3A686 -:1031900019AC15F175A2D18E37AF58C7CF2599DA82 -:1031A0003DC7CCDF221F9D9474BE3E01EF36C93C63 -:1031B0008BF35970BF9BAB6BECD3C1ADC8B508F7AF -:1031C0008F08EE0DAD2C99AD8C0CF715CC74CBA3FC -:1031D00086C373969959999ECF0276CDF4FC7237C7 -:1031E000AB447BF58494155E5F8AE5D03F7E0DF895 -:1031F0002AF60D5FF87163385D4C957369FE666160 -:10320000EF16B64B896CB44F9987EC57D6F390E91B -:1032100041B926445C4B9B7412D7CF3A1ACDA427F0 -:10322000B55E66482CBDDDB97D6F73537B4BDE58B0 -:1032300072CBC2A725572CF965E1D539FE48720635 -:10324000C753F310FEE824399D4E74C0C70484C7E9 -:10325000ACC6FDB3F60DDCC898A77AE47DB3E414E0 -:10326000B463E8FF8FB45F8027B2EB5C6146787A85 -:103270003738B4F42958F7401BD7D7EF1631B20FBF -:10328000CFB45D359083F8F1782A103F857C2A56BB -:10329000181C5A87F2D5A726FA11AE42A1BFBC8CE2 -:1032A000EBAF4266ECB81AFDFBF6934BB09DB53F11 -:1032B000B9627F9A617FD01F69F60D15A39DE44620 -:1032C000BD06EDDC2077512E17B6BFFF1FA8170BE8 -:1032D0001D7A112161E9706455EDB8DA481FFFA32A -:1032E0008D685F5AE35287F4FD0F6A2711BF85EDA1 -:1032F0009BEF5602B6F1A58F110F426EA3D9756EE2 -:103300009E52B457E5843B90A20B275C56BF91E8D0 -:1033100084A5CF536EAB933DE1ACBBC39A4D3EBF8A -:10332000FBC7F29C56DF79E8CD399E93BE9D7C2089 -:10333000F0F029E87413A7532E172CBEFDCFA2D3AB -:10334000A8B5AFB1DC3B8EA07EEDD2C2B30CB413F6 -:10335000867EC8ED04B77108E92C266555C2FB6866 -:10336000874A76A36557F4AFFDEB2D65F0FC44ADBD -:103370004C7EC489F59CEEF73CC0ED514B6F478500 -:10338000DE46BB00F10A76C3809B971E1CC7BFFEBA -:10339000E65209E0F61843FD6E6CDF6690BD9A5365 -:1033A00017D71BA18C571CF28C3352722919CBCF23 -:1033B0005B0EFBF5AD5C635984ECEBE8E8B9FED439 -:1033C000FB1FCB5C3F4D2B6179B361BCE45639FCEC -:1033D00020F44FBAEC7ACC2AD7285C5F26BDAC0427 -:1033E000FDE091DA0D29965ED535DA97F903C771BC -:1033F0009F46DA07D8019DE298E7E890E31DE6A131 -:10340000F1937EBB1E3A29F49005FF27D0AB0B8BBE -:10341000813EF64A99E1FE488C177D0E0080FD8EB4 -:10342000AACCCCD4CEB9EE7F10FD12B24AF3EDA8EF -:10343000D8391BF73B1653C2E9FB61957FA170FD9C -:103440009933B721B711DAB1F599DBE589768FDDCC -:1034500097B508FD2B409D8AF19A504C9F371BE38E -:103460009153F326A18FFD63D43F30EFEEC819BD11 -:10347000C5F789F051105246C6C79BB2CCF7D1C1EF -:10348000B77BC05D43F999943C147F6989B933F2E5 -:10349000B125A79CF2C8A9E724D3646DD5C3E58AFA -:1034A00035EE27D567201FB2945129BBFD9C3EBB4A -:1034B000587A1C410E94C82CDA97C13FBD5AE17866 -:1034C000EA8FF138856ACAA4B7662A4D4C023C6D72 -:1034D0000832920779B8D7C8B70D2C0E2860F92C9E -:1034E0003CE0437912945982FC56A71F6836A11F0D -:1034F00018E4A0317D54597F213C0FCE5F49E70C81 -:103500002CC2E5AD0EFF713E32495FB8055EA3B136 -:103510004914E7CC6BB2CB7137FA81201FF506C78F -:10352000F3F933E9BCC1CDD29EC33AAE52FCC1D34C -:1035300060DAB36A5683FC59BDFFAA5D8B61FC9AC1 -:10354000476E7E1BCBC907EFC9FF1294758FEFBA88 -:1035500019CB92D7A26333C553AD123885C9750014 -:103560009F8F19EE9C91DB19EB9508DAD5B08F1D72 -:10357000480FC9587916D2F72A85F37FFF022D80AC -:10358000F119750B97ABEA7C401ED13FF7D39B53E3 -:10359000FE34F915AAF093947685E20849BD8CE2D1 -:1035A0002D87B6C81A96206763388F357FAF88534A -:1035B000778A78AB13BEDE92A162948327D67F44CC -:1035C000F6A1A2678567C37C5D7E5642708878410C -:1035D000B3D8BFE4DA7A4F7ABC48117E4EC7D139EE -:1035E0000306D2C18012F61AC4371A8E1BDD329D33 -:1035F00061FC65961E66684F740ABF47F1990CF727 -:10360000355B6733D1AF85575A08FB57B17002FB62 -:10361000B7F7236E61BDE6EDC8073FB896DB2127FB -:103620004AED721B48A80BF694CD2A5AAF226D368C -:1036300005275D8534FF7BA540C8554EAF6FD44E3E -:10364000796C1BD0C1736EF31E65D427E023875CB1 -:10365000FF01B009EEDBA3925D9E5BE541271FB53C -:10366000496417AA265FE74CE5C346D4931BC16E95 -:103670002C3486F3CBC6D719D98D1B81FF62A5994F -:10368000F8A75A421971B1FC93D79E2B611CE3B382 -:10369000F2CF5F2AE29C4EF00FD05902ED984725F9 -:1036A000A3730AACEF3BFB1A7F3C055E3F7B604592 -:1036B000F635507E2FBEF1FA6B60FEDB1FDF938D77 -:1036C000FBFCE8ABC04FE7F1E32D7E6A461BF63CFE -:1036D000713663AD9D9F8CF515C44F6F295C7FF5E6 -:1036E0002FF8DD1B57FF7F7E3A1F3FBDAD007D4E9B -:1036F000FBD3D9E2E879E45B7311D3D0DE823626BE -:10370000D27934682F7D6A16E17B9D8BCB31BFCB9C -:10371000CBED8E107FEF1CEF6FD44F1E3F5850FE45 -:10372000D9F9749DCFFCE8F3E077903B246F4E8C81 -:10373000B3F37DA78BD3DDAF5C9F787DEF7CE17326 -:10374000581FD8F564DF5DA73203FD80892F7848C4 -:1037500058BC3A6EE311648969F03C94C7DFBBF34F -:10376000485EC6D18E19522AA9BFC9B81DDF54B30D -:10377000F9083F9718AC5804FEF21CF817DA23D763 -:10378000F9B85F01E3B0108CBFDA1B2D5647D17832 -:10379000E45FBEFAFCBE20CA97D73D66093E674982 -:1037A0003517CF072CBB63647E57D9E9343FEB69EB -:1037B0008D111CA72ED5285E89622C00F5ADA5972A -:1037C000529C928563C725AC8FD219CA71251859AE -:1037D0004C76489BDB9805F5AD6040C58244B72424 -:1037E0003795F6DE5000E500D825F85E8DCDF568FA -:1037F000E8BF8C923108CDDC6D1F91DF7DA298CBA4 -:10380000DB8E298CCE69061EF8B7A532DA3BED6E49 -:103810003AB700BB91F8352AE44632383DD4827E6F -:1038200046911696A0BE29F68BE35FE3F2C4F44CF2 -:103830004E8F8FF078474B88FBBB4EBB6FF3D72F73 -:103840007BD3C0F17EF85AD7E550BEFEE4CF5FBF10 -:103850001CDEBDF1ADD76A30EEEDAED36C714737EB -:1038600033DE447B0B7CA68486F2397672096E6661 -:10387000CAAF9362889F688D3F8EEB45DE46FC247D -:10388000A728FC7C11FE42005F40C0D71D3C554577 -:10389000F3C4DEFF8F4CF29EFE260B3D02ED36E7B1 -:1038A000DD1F4739929A6F12C9A728C827F423A3AE -:1038B000BE9E256B683E7FF841ECF347D8D5C9A979 -:1038C000F3C2435BE6B5209EE72EF0E84867EED8EA -:1038D000E6BB91CE9DEB3CE37BF0520CCDD9E607E5 -:1038E0003E715768A697EC5F7698F64334B1E0D600 -:1038F000418160DC01FA2F5BC132F437A03FAE1387 -:10390000E419DADB563F206313D77BC637FD528AB2 -:10391000F78B7885D5EFA69844E7043795031B9479 -:103920000FC7D3069FFC93AFE1B94B4CD1154E079F -:10393000A18A34BCE19F3D6EC6E9E2B27D76BD0B43 -:10394000F32F2CC5F73185E8C5C92FE3E3F6F61B45 -:103950007CE73FD71FBE9F1CCF1305BF59FD2DF835 -:10396000085E29537CDD7E2E73539DBD3E77183E45 -:10397000CE0FD774D57E6ED3E0B38F3733687F3FD9 -:10398000BBC85EDF80F19B4FB26E07DF3D3DC6FCDA -:103990008EFA19FC7A4BEEBEEF89FC2D8DA38619A9 -:1039A0008ED3BF60EFFC794007853AB73B0AE72F1B -:1039B0006CC8AD4139C5449E4966FBA350E87BA560 -:1039C000FD252507FD5193B74F2E796B460E9E17A7 -:1039D000D7313A4F8FAAF7C4728C943DD2AF966715 -:1039E000219E3F7F7BE46E6F7ADE4DCA1E79E055E3 -:1039F000A326833DA2DE239930CEAC25608F54A54B -:103A0000DB23AD12CAA0EC25608F90DD117D0FF194 -:103A100035925DF263CBBEF767B6ABFFA0723D0B8C -:103A20007AE69F3E8B9E19E735FF45FD1CEC8169C8 -:103A300025C6CA48063AFC40E5F10E4B7F36061310 -:103A40000A9E9D83DE545DF0FCDABAE44B288E3B7F -:103A5000F49D415C37ACC7E5AAFDF4EB39A372785D -:103A600026AA3C0F66A47EDF1AC15FF16A5E61B7C9 -:103A7000D8F7BB7FC13BBA8CFE0BF831E8BF247D81 -:103A800065DB302E7826A652BC4E9DBF72F75CA433 -:103A900027B0B3393D9FDFBEBE7648B6F1F1B4B36F -:103AA0005936BEAF67F673BA191EFB395DA36E3F78 -:103AB000A79B15B29FD3CD31ECE774D757DACFE986 -:103AC0009CF6FDCCD1AEFF9EF67DA891113F5DC066 -:103AD000BE077EBA09E969247EBA2EDFB83F92613B -:103AE000BFAB356EA7AEF6461620DD4D33B85D1779 -:103AF0008DADA77CC0BC28C89B528A1B52DCCB8AE8 -:103B00006B59712F2B2FD08A6739E35756DCCB8A3C -:103B10006349311EB76AF6445720BCCDED27659442 -:103B200023FA73300F3282758E372C3EC7E5414B36 -:103B30007BE6B89C33FE3662BB4FC9579F837E58E5 -:103B40008FEBB5F403F0F9839F85CF416E6DC3F120 -:103B5000FE05F97D14C9936EDABF0AC035DAE9B003 -:103B60000F1AC6E9179CDE8FF138F5B89BF8F6629C -:103B7000FD5F4C749061D3A2E083633C2B1A2B252C -:103B8000FD62F18DC5274EFF78187FFC57F3CF45B6 -:103B9000FAC7C03FDF739D471F017F3C8FF89E56D9 -:103BA000C9F1EBE4078BFE8124125235EE773481A4 -:103BB000ED2D7A672F864D8473A2F06B4E8CD6C89C -:103BC000BF38F1FCBFF373D8E73DE171628DF87E39 -:103BD0006277417C5B698ACF2C7E6AF7447FEC4A2E -:103BE000CB03B1F21D0F7BCCD7F17948ED4BA0BFD1 -:103BF000129ACDC21B0CE2B363FC39E7535F9851B4 -:103C0000FCF433FB657B5D713C1F6A91869632F252 -:103C10005B99867CAB0A79F26256F424E2B3797A36 -:103C2000A484D3D3D0381FC0F58B0E85FCB5CFCA82 -:103C30004FCD23E1FF1C3EA243AEDAE1F901E97268 -:103C40000BE55B28A4C5374819E495C0579C85C788 -:103C5000E0FA603FFF1DF19857C5245A8EE0E366F5 -:103C60008FF907D767B33F14AD36C5C780378F8646 -:103C700072B11AF0563E1C6F275D7CFD4EFA0BA9FF -:103C80004919E93F0472748394764E2AF062AD6755 -:103C900024F96CD169DA7943484B5FEFFFA372D9FD -:103CA0009297977BA293711FDC6644C83F93F6D727 -:103CB000296786DB41329D339E01BB07BB5DAC7C2F -:103CC0009D76D68B87256CEA5985CA6BCFD2E109E0 -:103CD000FBE2D96C2ACDB3F954D69FCDA572FAD99F -:103CE0004BA89C717634950D67011830711ACF96E8 -:103CF0005239F3EC1554CE3A3B9ECAD967AFA2763F -:103D000073CE4EA2F2BAB35FA0F2FAB353A874DA3C -:103D10003FC67A95E4B725BF2CF9EE94DF96FCFBFD -:103D2000BF26BF630D1765FF80FEFBAA761EF93D17 -:103D300092BC00BEBE4F4B971329FD7CBFF619F80D -:103D4000FAB8E053E0DFF7300EE3012F8EE2546162 -:103D50001EA70A189A81791AFBB0096CA9BF3472A0 -:103D600012E306CD0B3C7A0CE01E28D5483E6D0BC5 -:103D70006A74EEB659D2477379904C20FDED0C6908 -:103D800034DEB63F2A5ECC5F7869544100E7E9F63D -:103D9000CB3AB6FF566E72DF2D788E3F85850FC108 -:103DA000782BF6ECF1A4FBE1FBD13800F802B1A7C7 -:103DB0001903BEDE38EA774B713EDF5446F118280E -:103DC000CD4CF962DF748BF36975288478DAEA9355 -:103DD000491F74EB1E91879A1C68413FB74E66DB02 -:103DE00060DE0DA3DFD98260ABE3CA7694417D67C4 -:103DF0005D991737E9E9573E08913D01EF10142806 -:103E000013A23473607F3ABD61E37CE76D8A31B4FD -:103E10000E8915FBBBAB476EB7C93F1042FAE89855 -:103E200034B9F21698BF7752C1689C7F7BCD511B85 -:103E30003E14DD1E4F5130E0887E785D92E26A1BB1 -:103E400064634719AC2F20F2AD01CCCA485ADE8119 -:103E5000058712867570B8120A5F0F2B80E7B97557 -:103E6000895892AFD7C4B8ABCF970CA1BFA8D49D47 -:103E7000A6785BA73FB988EA0E38ACF17FAB5979D9 -:103E8000019C6F7C826F9A277D7B11E5915769B405 -:103E90006FDDAEA105588FAD75B1C733C46F36085D -:103EA0007EDE5679FEB88CEAB3C3D1EDB5FB8B1636 -:103EB0003CEF8BD20947B36B6854A6FDFBB4F35FAC -:103EC00068DD9FF77C9D23E40F5CEEB6EF4340C8AE -:103ED000F3E629DF0EE1B9B8054FA704FB50F3F96B -:103EE000EF43F3142EAF3FEFF5FE4F1BF7F71A8F9A -:103EF000AB009FCE2EC738E398C9218CD7FAAC7897 -:103F000074384EF949018C47532F83F490AAF3314A -:103F1000149525900FE5EC0F13B84F4AB566282489 -:103F20006733EFBB12DE44796D4EFEB4E0A6BFC925 -:103F3000C274A0F343AF159F36D4C9FCBE04C67F3C -:103F400015669DCFF2F8B4D55FAD90291E4D81EC7A -:103F5000B47154D0C3788EA3609C3A6FF8FCDF4DE7 -:103F6000D1A37DFE221E1F5754EE07BE27717CC4CD -:103F70005E5528DFB3EB792EDFD87146F2BBABD6A6 -:103F8000A073951DF03FFA0FB15A5F1CE95671E41A -:103F9000E39DA99C1E42396AC5C5693E7E3E4071BB -:103FA0006ECC53A4B8B9C12AF07DB700CD1A47B57D -:103FB000E2F2956B26613BBFC13CCFC1FAFC752C88 -:103FC0007109C01B74B76EBDBC34433CBC72CD37A5 -:103FD0009E8479773F35FD574F427D971C7EB50E05 -:103FE000DAE57FB98EF0EA8C876FAB944D1DE583DF -:103FF000CF7708F7156C68A28B5B7BA4183ECFF6D1 -:10400000F90EF2FD6E0D298817D0938817AF332F64 -:10401000321DDF6508C7CE8179F06FEFD679CB709E -:104020005E841BF32B57F4D66BA867824BECE71723 -:10403000FE267BDD5B658773ABD8BF0BD1BF330F2B -:10404000B1C79CB708E9F64C5063286F36AEBDFA8D -:104050004692FBDB1536AE3403FD3AD6D5A9B948F6 -:10406000FF771BF57B2B506F346894D7D31DF7C6B1 -:1040700031C57B7B5DEADCC466BF1B1A3FC7AA91D2 -:1040800013EE4C76BC381F0B8867CC710ED63D5BA7 -:1040900026BBA6BB87CF638DD75DF79607E5C448DF -:1040A000E33E3DC63CE2467B2A9A7751F72EEEDB93 -:1040B000E8E2743D458B4BA5688FEA0B17417DF311 -:1040C0003899EC2126FCBFEE6BF979E2C39A61BB0B -:1040D0005FB169CA4AB21B6E72EB82BFC02E9C9060 -:1040E000BA6F71C06BBEE086E7EA733012D803EF97 -:1040F000E5866F44BA680C7E4476D4AD45B28EF442 -:10410000B5624F23AD6BB32EB304DABD6A2B19A988 -:104110004DACD5C4F3004CD444BA9B036F64BA17BA -:10412000913CD40970CE195738691BD4DC45AD9445 -:10413000C7D26848E4875D07984179D0521C51A5E1 -:104140002AEC37FF1DB4FBE6044B65F4F7AF535977 -:104150008396669F835D7CCC9DB6AE13E3F604E543 -:104160002A9C1FE6C1F91779E83E811BEDE32B532A -:10417000F6F14444649A9DFC6B342A319E5194F8C4 -:104180003DE5797F3F29E3BCEC0556BD4DFAE47E61 -:1041900035F897BFC4FD8C33A31F530D3F6B5CE212 -:1041A000EB9AD827716FE5B027F21B1CDF8A074C0A -:1041B000D4F8FDE6CD2D2C1C4B8BAB6C7EFECF8F47 -:1041C000A3BD6AC55FCEE5DD09382DB837492C8B14 -:1041D000F4BC27FA0777BA5FCC926573277C7E70B0 -:1041E00067C897F3D5023F8D15FC93575BE145B93E -:1041F0003916F37D701FDAB93C31E1BFF47C1F45FD -:10420000305F30DCDA2F1BC3E59222EE4D015D4BAF -:1042100068C73AF38114CCFB99385C6E1C10F47FAC -:104220008947E4FF4C6693B91F6E3FBFF22FE57AD2 -:104230009FB5E665BC87FA7DA1F75F147E6542DC19 -:104240006B3C2AEE2DBEBCCE203FEF957595540EEB -:10425000AC0BD3F3D7D6D55199BA5FC5E7CD177656 -:10426000988A41353CE7F7B1B801F0FA47AD192813 -:10427000453EAFE3F7BBBB9B4E6D2927BB919F5BD0 -:104280006C2EAA4E14A2FF02B0E643DDE5EBF3F07C -:104290007B5EE6606501577388F7FFEAF30A275DE6 -:1042A000E8D6FE3BF6DBC75A19CABB8069DFEFECE4 -:1042B000B0D3BFE1FBEF2ABAB87DEFC57FC03E7E29 -:1042C000C9DAF7ABD9D5FCFB0C17278F918F2A855C -:1042D0001C1803FC7400FC79B7C2F3D5F3799EABCC -:1042E00019E2FC66AABC1E1B2FDABB3809B1813C5F -:1042F0009ED75ECCCF13A81FE695E37B0C4BBEC0C8 -:10430000E35B2C47E4BF8F15E3AC16E34EACA67B12 -:10431000BBFCFC9FF5E958FA5892EAB9C007580669 -:1043200059AB84C81CC306C9DF2E9686A86E487A8E -:1043300016D6CBA47019F7C3E3A43FCB15F3DB1556 -:1043400084FC88CCE345C9C5644F825E46B91857E2 -:10435000238B50BE6C68D3C28089737972787F0ECC -:10436000CB0D7D350378FE118BC9247F94E75896D9 -:104370007E25D97BA4BF36ACCF3B984DF91A49CAEC -:1043800073DFEF29B5E9A989BE85D7E9B05F1B4581 -:104390003E9D0BFAB30CF9A7563E1D8C5B92E9BD0E -:1043A000556EF46B8B32F9FD0F7B2411CF488EA62E -:1043B00038A0D8D7F85439E37DC67D1E6ED73C5A55 -:1043C0009AD99E66EC411A6FBF47778C9B6CA1FB14 -:1043D000333A8F6F64B94CCAAFD9D8C6EFE95BF8EE -:1043E0001B0D762DDAC31BFBE6CF46FE8E55AA9435 -:1043F0006F0EEBF721FE5C222F79E3F8E0C16C1E13 -:1044000097284539DD8FF8AB4DC35F706513E2AF78 -:10441000E3559EDF0BFADCC732E41B5AF873F9D878 -:104420001733BDB7CA8E51DAA24CF7868F7A2C3B70 -:104430003D59CAE984E32FEB5A3592A97D42E0BB8E -:10444000A48C45CF87BF7E8F6E1BD73AF755468821 -:104450007749BE04C5B9266ADCCED8B098E375C3E7 -:10446000F3D71C8FA69D43FC12879C928A075B7131 -:10447000634B6FB67BA2FFE81995D297ECFB8CE4F7 -:104480002E7BC17310F72DC339C4294F6D867388F5 -:104490009E8BFBBECB58C1B787B61C9D87F3FC55DE -:1044A0001D23FB2AF00C9F37576771B914BF536067 -:1044B0004A1867B926A2D7A3FDE66A6726E6CF8C1D -:1044C00015719BC2F63E05E922087B5928E1BDA67D -:1044D000640CBF67327637233F512D9CB96ABD21EA -:1044E00044695A7E94C286FA697DED9AF1782981F1 -:1044F000F553D40F63C4FB40FBCC5FA1DC1C1389D4 -:10450000521E2EF48BF9D1BE10782CF072BE5DDEF7 -:10451000109624681F0C26293EE994EB63003F9710 -:10452000A4D96F015167ABB89C96E13FD4F3F91160 -:10453000BBDC1EE7B8171D70E4BDE47A45BEBB25A1 -:10454000B78BF8A64E5007E54C7E794ABF3AE04358 -:1045500019569DEA1FB0EA9F113E2004A2670B1E68 -:10456000BC4A8972778F4BFFCA53A89FEB359E4791 -:1045700026EECB650BBCFBD061867603535E3171B2 -:104580005F7784F97769CE4C9D477E68769D759FED -:104590008EDF5786328671BA6C31BF75AF2E9B198C -:1045A0006F96033D649B49BA57A75BDF55305902AC -:1045B000F370749F4C7974BA2F42F2A9678147C790 -:1045C000EF7C68E29E9E4BDC1FCF364FD3FDBAECEA -:1045D00061EBE3F7EB2CB8B3B3AADE2C376CF3AC8A -:1045E000C7F836AC7D74C6FB7575DC4FCA36791CCE -:1045F000226D7CBA5FB7636A99ED7E1DCD837E9C88 -:10460000A03FEB9E9D13AE73FD6A32DB6913C27649 -:104610003BE242F7EB5C217BFB1D17C8CFFAC4F7E6 -:10462000EB041E86B573D8832ECB0E1D2533DCBF5D -:10463000330D327D4724F7A3646486447109D2F7B1 -:10464000969D97C787FA6F67E7E55979FD0E3BCFCF -:10465000B2DF7267DBF1EDB4FBDC5511EA73B176C2 -:10466000DE2EFC07D0CB435E879DD794993E9CF20B -:10467000229F0DEEBE12C6395AFB2305F3D576E50F -:10468000F2EF1FB161FEC15B33685F7CFC7B47BB0F -:10469000A6F4ABF8FD9BDF2D656427597104B78044 -:1046A000795791BC9EC2EE5D0F117E82020F4DF8CC -:1046B00001B21AC2557C1CF199E9C5BC85FC26469D -:1046C0008D0A2BC2B4EFF85902992E6DC554D4E36C -:1046D000F58895343CCDF0D8BF13D0A8E73BF6D190 -:1046E000BECFE7CEC11FE4DF539863D8F7DDF29366 -:1046F000D09CC5F9AEAFB4D3C1092932A84097A761 -:10470000B34A85FD33A8A3BEEC5EEB22BBF1A12525 -:10471000655BAF447F3528EBFC3872681CDA47CD07 -:10472000474D2FDA79DB23D3BDE3E0FD431D4A1863 -:10473000CDC3A796AC7915EBB1DD2EB2839EEA9B73 -:1047400057B0228DEF36EF5EB07031BEEF70917EC4 -:104750005FB1E7BE81D220F677D5A67F6FAA65E369 -:104760007D3AFA6D6FD47A33DA31576771BB64A33F -:1047700096A4F8D3C6791A43976B6349FDE8156888 -:104780003F5CA365BC4F7E57969BDFE773B54A2815 -:10479000DF0BA399EF0558EDC6D6FC96CE3182B358 -:1047A00065867E9CEBFA7932D61F827DD5A5143DB5 -:1047B000E5097ADA5874EFD60A5CDF40E67B875663 -:1047C000B9366B1CA7D3889DCF5D854DA371DD2EB7 -:1047D0007764A01E89AB50D6312EE272B7466E4682 -:1047E0007BF46A175238DBDCF1C38645B82F614988 -:1047F00097609EA01A59457416CC62A80F1A964469 -:104800005A112F85A0FF30B45758F44B3AA728AC63 -:10481000D39817EA9E253D0917BCF75444AF42BC14 -:10482000BFB4967FE7A530E8A37B4185117E0E5784 -:10483000D8EE6668326C0417D845FE814471222791 -:104840001F59EB6A5ECAE5F8EEB5BF1D95E97B33EB -:104850001559658457AF615FB707F52E8C33D51CAA -:104860005C42F8AE71B338F1AF9BE87B57AD8BE09B -:10487000DA35E5E45710AEDFFD3E8BF6FB5A664AAB -:104880000857FE103F67B5E6C96F1A54783C9CF391 -:10489000A193EF2C7E70C2B773F63C3A8FDBCC0647 -:1048A000E723BE636765A2A3CD456BBCE971D15612 -:1048B000417FB00F245F623AA3FD56FE95ADC77CE1 -:1048C000D88D5F8C54227FBCEDE5F756EF5BAAD103 -:1048D0003A1E9AAB51BCF1217F2BD1FDA98DAEF0D0 -:1048E000210447D517E27EEE2EAE0863BCEDEFF053 -:1048F000F039CD3FD83DEA4B9588CF2FFE218B8FE5 -:104900003345B5C6F919D17BAD97E09CA1B4FF6CD6 -:1049100005DAA14BE4C9943BBD6A09C92F9790E31E -:104920002F2FC9AB473F2570C372C6E5218F5304B3 -:10493000D656F3FB0C0EB99FA85377CFA05DE2F1DA -:104940009F7A21EFC6DE30BD1ED7592FF482A966AB -:10495000FE2E63AE685F381441936C58FC2757E80D -:104960008FB1BB1DCF855EC81D16071FACB819E4FB -:10497000CF97B2841D3942DC67D79279C40F678024 -:104980001F282E5D7292E83F067202EDE637A4649E -:104990006845DA7998F59DB99F887850C42CA53C74 -:1049A000E1B7443CE8A7E2BB73EF8878D071110F00 -:1049B000FAB98807FD03C683F0FB61DECB69DFC669 -:1049C000D57DD48F719C9D350B3C068C33551F7C57 -:1049D0000981FCA239E813F9F7046FD0D24373CFF1 -:1049E0001FA74A205C6E8C4B71385F16DFA37B4596 -:1049F000C03520E07A4DC065E941941B48676CAC36 -:104A0000AA67928741B555C2F35E9417FD4192178C -:104A10003C4F3CB84632260C971330DEE8743BDD41 -:104A2000A2BF53A37C44C7CEF11FCDE2F70E5F5A5D -:104A30003B6B3F0BA6C9A3C8C2554877F9B03F28C6 -:104A40008FA24D5C8E47F1DE459A5CB5E269B023DA -:104A500061D23B37703C8D245F2E24570A1D72654E -:104A600037CA15A8EF46B9124C972BADFDB8EE200A -:104A7000CA1596D243C1C827932B3FF396D9E22497 -:104A8000967CB91AD898ECC430E853FFA7D7A76F23 -:104A90000B397121BD6AE57F044C467A7D0FE685AE -:104AA000A03F339ED13D1CC51CA47CA2DC7617C35D -:104AB0007C90ADD86534FA330B291F64C77C8F8E88 -:104AC00074F1B09408213EF7493D5EBE2F7A3FDA7B -:104AD0000BDB26F038C98E3FDEE3453BFBA5DB0B45 -:104AE00002788ED39B6BE581E88B6F85FAA94646E9 -:104AF00074B262CF0A5BDEC3CFB3F2081FB9319044 -:104B00003F808F876FE7FA4737781E089419F34084 -:104B1000DC3E110F526321A48F6D52D4437198462D -:104B200099F4546F98E7AFF4825F8EE783BD0D3B35 -:104B3000E7A07EDE70ABCC285FBCB2E71E94331DCD -:104B400013161AC897AED1656FA239BEC1277BD3A1 -:104B5000F348F13841ABE6E786A2347300E4CD5E5A -:104B6000D338DFFD5155F87DD8DF7D9E3CF8CEDC93 -:104B7000D0688C13F4362E0CE1BCBDA322A13CCA34 -:104B80004F1943F6C0C6519B1663FCA963B9C6D240 -:104B9000EDA461F305EDF6B51567541B78FE488763 -:104BA000CCFDCB5C713E0D7C5589784B5F27C2A94B -:104BB0009A3C7F04D7ABF0F5D2F74D731BC03FACE6 -:104BC000E2EB47FF55F7E9A3517EA80D3C7F64B3A4 -:104BD0005F5F8C7EA3130E6BFC6BB3259B7FA45B86 -:104BE000790BF56BF8396211CF5BE8759D3F6FA1CA -:104BF00043C843CB6F1C091F2EC73975AFD71E079B -:104C0000B4E0B952944E3846CA17F8B4F35F68DD81 -:104C10009FF77C23E511ACC9966CF72B72AD7C969F -:104C2000C635219413163C9B2F903FF269E16A6EC2 -:104C3000E4ED3FEFF5FE4F1BB73E9BEB47E0D301A2 -:104C4000BC47D931716608E5502A1E3334508EF6C0 -:104C50009CB8CF68E58FB874FE4F55E5DFB993B3C4 -:104C60008BE83BCBEA749E3F427F19F240363136E7 -:104C70001BFD1D55C46F9C7C7A21F89D792337FB61 -:104C800084DF1875CC27F2449823EF440DF1FC1211 -:104C90002B9FA44B82F50553F92023CEEBC0DB7884 -:104CA00021F7DF73F41FB6EE30BF5F69E59F0CCBD1 -:104CB00023992AEFC72D18964722F2517A728D3820 -:104CC000CF13E77925A836319E372C8F64EAF4108C -:104CD0007E53725A89E87703A3EFEFF67879BD77B0 -:104CE0000E8BE3F7CE7AB18EFC54CB28AF65587E9D -:104CF000C9D43584278D4596F1F31D7EDE6FE1C161 -:104D0000995F72417ABB401E49D0677D8F2242F382 -:104D1000F4F8C33FA923F8643A8F2FF8D2F170FA60 -:104D2000F897F8B89CEC1179783DB9F67CBCFBC4D7 -:104D3000BE548876CEFDD58B385D77D5EB1477776A -:104D400037F078E5B0EF40D4D8FD01673CEF8490B0 -:104D5000D7175ABF33AEB76D84FB660B7C3C8FEB25 -:104D6000A12587282FF6CC2AD0B380AF87319FA505 -:104D7000E6E2F3595ECFE2F92CBD46FDC24B518FFE -:104D8000453586F2B417F359E0FD868611F2594491 -:104D90003CD18A8F8E94CF927BEE3CDE9ECFD27B2D -:104DA0002BCF67E9EDE1F358E3F53654939D35D207 -:104DB000B84F8F31651FEE7FC5C59D9F4E2B89FC77 -:104DC00019E6AFF4946AFA8306D20BA7E7AE468DD4 -:104DD000E8BBCBC5FDD8D868EE3733351E5A086D11 -:104DE000B6F8138B289E2CF2327AC5FDF9BFCF326C -:104DF0006CF67167E3774368D7031DBEAC733EA1C1 -:104E000071F2D5D2F5600332B7DE62A24F3990CD90 -:104E1000E308AED0B181BA343ADD22F41DE2470690 -:104E2000FCE44AE7F015950B28BA4F7F6B047DBE72 -:104E300091CDE7B7E890A993C2FCFC8F55A01CB1B7 -:104E4000FCD761ED3CBCDD30F9E390233D98DF8673 -:104E5000154B9EDC60C9133B5D5AF28339E4CC39B3 -:104E6000793287DBE9E7E409C80FFCD499530EF5E2 -:104E70007AB9BEB0E071A3600639F29E2B6C8BD379 -:104E800038E5CE85F8E8F3963B2F65E70BFB83CB3F -:104E90009D20D206F24DB6758EC8EF3D9C99FA2042 -:104EA000C9438FCAD7ED8930FA9D00ACA33CF7E027 -:104EB000394A46B95E2D51BC419C8BE48BEF0F3EC5 -:104EC000EC0A537EDAC3C0CFE8E74D309CF6D9F93F -:104ED000CF159CE7490FAFFD1AF7CF00DFE8775DEC -:104EE000AC1CB2E4C487D97CDDE7E8CBE4705AF4AB -:104EF0009546CFF47D018B7EAD712D3A66C8A00535 -:104F0000E7A15741D7188EA638754C8A631CC4CACE -:104F100023B3C67BC3C7ED9191EE5759EDBE63F93C -:104F20005DE7E2C17A40A77CB21EBA6FCEBA38FD07 -:104F3000CD61BBD53555944FA032CA278894A03F88 -:104F400073D867F78BAD7CB06925E110CA890DC2B3 -:104F50004EB7F2C8ACBCB4C3BE5CEB9CD9969FB64E -:104F60006184FBD96F9EC3CFC57FFF04BFDBB6DA78 -:104F70006B3E8E7211F0658AEF39511E9A35EE77CD -:104F8000059E5EF7984FFA3EC3FDC917B3EC7957FB -:104F90009D3EC31117E0789DA8C7EAE93E5E94DF05 -:104FA000AB729EAB8F74FFD5796FEFDCFD5771FE4E -:104FB000DEEC89BE4CF0BFC8F3DFF470F46027FB71 -:104FC000FCD673C06BFE04C7EF14FC3D2DC8EFED9B -:104FD000BCEF89BE8DCFAF63DCAFB6EC9CC3D80EFF -:104FE000FAFB5F06A90DF4B2A996D36B5125A3EF86 -:104FF0008F4F6FE5F51D4BF9774DFB5FE7F73EB639 -:1050000045F9F74CA15F9F0C78D9319EEBC3FD5554 -:10501000BCDF7EBCDF847C5AC1EDAE3C8CDE2B282D -:10502000AEA3544EAFE9F14E80F70796CA1417DDD0 -:1050300023F822C04C8A736CABE4F3ECAA909F1067 -:10504000DFA359740BD43B67AF9C8CF74BB68B78BE -:10505000CABEC52B9FC0BCBE0F02E582EE1274EF24 -:10506000B5E7F86D141F7968499EB412D6B8EF60A1 -:10507000E6FC962ABF2AFAC5DC229E24CA8486E56D -:105080005653E4ADB632F13DF69886F1A76706793E -:10509000DE6AF7EA678ECD447D5C29539E59D7E0DE -:1050A00051EF65B8EE3A9ED753A426A474FFC5EB22 -:1050B00077713BADE6A8C7A81ADEFE99C1A3447775 -:1050C000DB01EF4A9AFF270B38BBD19F807E7B5DC7 -:1050D0003D0333A1DDDE717952CC48B51BEDE7FC11 -:1050E000D7BD4416DFA167F41D874EF39407E5662C -:1050F000279E7F40FBEE1A2B2FB587EE65ED9D3383 -:10510000790EE6896FBB81074BBBC287C84FEE990A -:10511000CDEDB2BD12B4837DD9D7A25D4FF7985AB9 -:10512000799C08CA8C71A25E4C0446BC8A733B4AC7 -:105130007D81793B1BFA06709EA23AFE7D8BA29A76 -:10514000CCFD5F08B8A9FF3E578CE29F23EDDFBF7F -:10515000FA383E3BABF8790163718A4BED167E1746 -:1051600053A346FA77425B021C3F3B5DCCC478995F -:10517000AF4E23BD2E870DB243FD603F623C6E9B58 -:10518000145B8CF921B1491A7B9C30627AC761FCAF -:105190006E425E18E96F939408E1779563E3787C3B -:1051A000FB686427DDBB3A00763485835982F4546A -:1051B00077348FEE431D8D540F527F5F85EEB634EA -:1051C0000AE6CDD38722199B74D9A6AD68D7744E51 -:1051D0009175CCDBEC94EAA3385E2CD7437164D78D -:1051E0009479B47FAE517952BA3EBAD1CFF5C2D0DC -:1051F00084C88D7E585768CAA95C8C5B6EAF7D658C -:105200001FEEDF23F77B888E1EA91DBC1BE7D97F0D -:10521000F6AAE351E24B7E5EF768EDE952B47B7685 -:10522000359DCA45FC15637C0EF46171058FA3A101 -:105230000624FB4CED6137031E8BDB3466A4E96367 -:105240002FE3E779F8E79B4C728FFE9E193CE569E6 -:10525000C1F196B0C4A5017AEEC1789625678AEBB4 -:1052600058A200E4E1FE15EFC4304FEE91890574B9 -:105270008FB248BC27C909E39588F1FADF78653D0C -:10528000B67BB4BAC04079513C30340F954471D5E7 -:10529000698AB385ACFB1F5163FFAD449F327DA784 -:1052A000B238FCCE5FE03A02BE3ED273D09EE266D8 -:1052B000CE7504269AF7F9018FDF945A5F1D174CBB -:1052C000F963F487FC782FBF975D9CF50F7395B455 -:1052D0007CDB121117D8240DCE26BBF4016E878F0C -:1052E00065719273C555B1BB79BE6D94F26D9DF336 -:1052F0006EF79FD3AF12DDA3CE6F12F74AF8EFD847 -:105300009488DFB171D27D28945FD57155AABE2FE4 -:105310007A8AE8FF69CDB82BD3F71EF609B9B049F0 -:10532000F863D6F86373F9F856FD519DD3E3D32F94 -:10533000E75D5F05EBF9ABB6B24918FFDC31821FC0 -:10534000B732C0E92F7B002C1CD003FDAFBDE6C5F2 -:105350007C96A765B60AE5547D55C293AC12788455 -:10536000F1C91783F10F84BFED41B9F4D54025C1D0 -:10537000B5622A8F1B74563D48E740219DEB1DE422 -:105380004F94EFBE504CC2B8F7F21AA61F12F19616 -:1053900018E09FEECECB2C95D7BF3D97FC1CE015B7 -:1053A0007EAF067393268BDF9F28C773A24D778B42 -:1053B000FC5919F1DD29E601BEA5790E148971EEBB -:1053C000E3F63FFA17D8BF5CCC535EF7DDAFA11E02 -:1053D0002FD2395DA4E0EBF3107CAD3223F8D4C4B6 -:1053E000ABE8876E9F546020DD1C0885DF6E82FA73 -:1053F000F2452AC5E3CB6B381C075A65FA3D207F7E -:105400009D7690EE8F99A02FD2F06588798B6A12E5 -:10541000129E6B19AD7C5DD0CE8B72D108033C50CF -:1054200037C4BACEC13F4923F88B3C83985B740ED6 -:105430000F2B713CA0DF9575BC9F3FD4B705E5D815 -:10544000F23A0E37E87782A728AC1D447D5F14E25C -:10545000E32D07FC1C925270655B70D5C9947F5593 -:1054600054A31D443F385BC0B732CCE1E97FFDD483 -:1054700080C4C73370BC6C016FB6583F25EC16086A -:10548000FD00E33DE54AD4E3BD9C5353987188CFBA -:1054900046F12CEBFDAE56C003E0C72FE661BBDD45 -:1054A000C44FB0C4D8C732FFFD10232D6E51B15B7D -:1054B000B3D5FD62FF58177F4E7E1CA9445E9785C9 -:1054C0005FB7B2CADE8FD5A4D5CBF07E19A7F7F5AA -:1054D000D7F2F38E0313B87D847EC739FE463A9F18 -:1054E000623CD615C4F71AE9BB9276FBB8C5AD0588 -:1054F000D3513E140F3C3C4F86F514DDCB64258719 -:10550000E8593A27FF60BE6FAF49D0FDD9EC81481A -:105510001ECABB92D6BCE9F8FDB7EC8128D5B3070B -:105520005A4D9E7F062E4C1EE6EBA5CD538A729AED -:10553000E7D3B156AD0FE55A6D3A9CF0BEE4E59E57 -:10554000B9D87FF3DDAF8C46FE2D70F4F7E470FF21 -:10555000A1F8656815C0F94FAFC5F6567C271B2129 -:10556000CEA3F2652C8B7D208FA12C11F97796BCF0 -:10557000E89CF0CEA4A84FD00FE5E3B144BA9DEF6C -:105580002CA1FD78D13E269DB7DD696A3752BC69F2 -:1055900020C0E34D0161AFF630633FE9F71A9EEF9B -:1055A000E1C3E7A03FFA6A8E4EA7FDEC6361A4E772 -:1055B000E2B63FB9D3E5F5CD8152710F3A4174AFF0 -:1055C0009564D1F91EF0317DDFF480DA4AE7AC7DD5 -:1055D00045FC5CF3E89C5724C467D1733C4FDBB2B5 -:1055E00097A7D72442F8BCEBD5E865C49F23D89F82 -:1055F00096BDE95CCF25F50F923C181B655E3C5FBC -:10560000F3AF56298FB5240A7055A15C00922E0481 -:10561000F86B62EB916E8C28AF1BAB45B90ACAAB35 -:10562000C1BE5D3750FE4B576ADCAD1560D7A2FD99 -:1056300034B8DB7303DA2BAD608D18682F9EF2E06F -:10564000F754BA5BA7E7239E9F8958F66542C2F1DB -:105650008B7E6A92BD58AB6B3AC66126B813A3D352 -:10566000CFE90ECC79A79ABE2736FFE2F2C946D21F -:1056700027088B9CA647FAAB8E927E79C23F9EF498 -:1056800090A5572C3D4223827CB945F0519791F06B -:105690004824AF807701CE5B508E001DFB8BB83C59 -:1056A0000739CCE59CA54FEEE67ADF929F15629C08 -:1056B0005B50DE42BFEEDA27726F40B922E4AC3FA6 -:1056C00064CCC4F3B90A215F991A9370BE0353F8EE -:1056D000F72A030E795AD1CAC7E90A31A227D04363 -:1056E00007916E0E1425E89EF881D6A352FA3D5319 -:1056F0004BDF055A930CF77F5C1D9783E3845CFDB9 -:105700008EDFE0F4E9E172F59CDE13F276AB79947A -:1057100089EFC266CCC3FA7BA1CF7B2A0E915FB022 -:10572000EDD653844F2B1E1A12F1D0EEAAB7E8FD26 -:10573000F628BF07B0CB9C3E87E08F2CD728FFB45C -:10574000E6E89C32F4379A966B68D79D0C1458E7BC -:105750005FDE85684FB6AE22FBD727F6F1A1301386 -:105760007EA7467ED67D4BBF3D80FD43E0174906B0 -:1057700036EAF3B891CEF17B0A88EFE82075F6D5CA -:1057800018F41D08E73ABE17E0DFA5F5479303E3D9 -:10579000685F65BAD2E3AB61E4772E07BF0E87DDA1 -:1057A000AD86BD13E0FDEE26595FCF52FDFF578059 -:1057B000E7A34DF4F37B0A3B179FDE8271BE9D4B3E -:1057C000C577CE1CF0DFD7D8E751681E8C09501E74 -:1057D00073C6EFED57F9B3F8F7176AFA06D09E0FC4 -:1057E0005471B85E0C181CEF831C8F3D1199F8683A -:1057F000D760B517F59DD36E7C24FBDD493CAFC562 -:10580000AE6F2E542F76C8FD09EEBEEB48DE7D53F9 -:105810002679C518977712930DFC5D8D9600A7A782 -:105820002A21AF3B5C89FD9857D0F1AC8FAD375240 -:10583000745124C6EC6C9533FE7EDAA180C2F77FEA -:10584000F8BE73FB41ECFB93020F17DA7F0CB3A099 -:105850003DDD17DF34E60E94E3ADDC7FEE4BBC4557 -:10586000794745B31792DF73E4E0A5E40F14559927 -:10587000B6DFD7CC1EC16FADC8F19C371E30923C4D -:10588000DEB7BA83FCEC7D8399EFC514E4F0BCB4B9 -:105890003E9097F87D9391E6D77338FFFD5340D043 -:1058A000DD9C77E87B19697AF665A16749DF16AB5D -:1058B0002CA6A4E5394C10F873EA4FA6C63D97D63E -:1058C000109D13FEF689F38B874C99F06ED1399EAB -:1058D0001F205E611DA6A0433ADFE861710FF24D03 -:1058E000AC89E77938E19EE0972F6A7DC11CEE878D -:1058F0009C9B4FF8EB13FD1CEE9DB5F7D33D4798ED -:105900002F84F421FDE03F4ED37DA8675DF47BB684 -:10591000339E752530A675E741FE7B8BF28B5E8248 -:10592000F39F0FF3EFAB27FCDC1EFBB5CE7FAFE898 -:10593000ABEEC1EE2F407DE85985913D1907C505B5 -:10594000F47A5AD02B7B8ED7577A79F5CE83FDCB5C -:1059500070BC55CFF13CCC3B9FBFEDC62F40FDB690 -:105960000117DD19B8F3F1F5DA18A8DF1E97FAB0C0 -:10597000FE9BE98C7EEF3396A7519CEB3781C18269 -:105980000580EF0FD679987119C649070BE6031EFB -:10599000EE883F3D13FBDDF1941446B69DF1ECE338 -:1059A000AF8C06B8EEFC8644F95F5F39926DB30B9D -:1059B0004FC352A6C1FB3507F9EF46DEC67A662211 -:1059C0003EEE7CBC977EFFD0C2E707EB2A9991F6AA -:1059D000BB61777EE369FA3DC3BBBE25D1EF2BDE09 -:1059E00025F37B44FFFCBC77D1633E5CDF7AED524C -:1059F0003FAE6BB386ED6E8BB77C17539AEE881F64 -:105A0000D466C2FB3B0E1CD456A25FE666CDA87FCF -:105A1000BE72E40A9BDC39BD4F21FF604DAE87EEBC -:105A2000D7339F199A3761F83E7FB08ED9E0BAC359 -:105A30008A13A8716D6E5A7B97CEFDDFAF1C516C37 -:105A4000F3587640EC18D70BB1BFF553FCDCDABF46 -:105A500035C2EFB6F66F8D15885787266782A71B6C -:105A6000F703E0E959A753B9735D88CADDEB0CDA97 -:105A7000A7BD884728BB04DC81A9AC1EBFCF1F305F -:105A800079DA715E93598F77CBF222BC5EB0244AEB -:105A90007EC848768C55EE75455BD087ECDCD13FEF -:105AA0004B05BB67AF16BD1B235F7AC7ABB31AA00C -:105AB000FE3739918D39246FC206F29DE59F7F3DF7 -:105AC00087CBDD4DA335C2F7DEA5931F532CFF0B0B -:105AD000E37E4B573E81F604F4DF9E437C1BA6EF2A -:105AE000748DD4BF60599DAD7FC1B25556FF3DD472 -:105AF000DF73FEFE7B975D639F7FD91D56FF4708CE -:105B00007EDFF9E12F689E6A9FBF7935F5FFAA9B7A -:105B1000EFEF50AE87F2E93BBCE1848BFC6746DFD8 -:105B2000E750F32E3D44DF4F3A17671A3451CFFA4E -:105B30009ECAAD463996A2A3E9DFC475F881BBD2EF -:105B4000E928A72ECBC657B9669EAD9E3F7B8CAD8C -:105B5000FDA84899ED7DE1A2CB1D74E9D3290F96EC -:105B6000717D6A629C13E0D4C6F0EF35D58FF1D019 -:105B7000FAEE7FD14BF5FBAFE1EBBB7F8C8FF89852 -:105B80007417ECFBFD5AF4CA74FB18D62561C8EBF8 -:105B9000193D3A90539BFEDC90F17996C27FC72E57 -:105BA000CBCDF5E5E6D2C98FC5D2F0B9A518E8018D -:105BB000EA6FE768B638CFE6E295A196B479361574 -:105BC0006B8B0E55F1E7B7A01DAF47FE0EE7FBAAA2 -:105BD000367429DAAFCE79DC6575B6793C25AB68C9 -:105BE0009EA4631E77C92AC73C9E4587C47331CFE4 -:105BF00029A49391E6D95C768D7D3D2577D03CBF75 -:105C0000C6796AD3D6537287639E2CBE1E782EE661 -:105C1000F9CD79D7533ED5BE9EB1AB699E7F77CC87 -:105C2000E31EBBDA318F8FE6C1E7380F2BE27E949B -:105C3000E61E5A49FBFF032FC33890E68EFE355D02 -:105C400052F97B2FC585A19589EDFE0FF9438DD2C1 -:105C500000800000000000001F8B08000000000012 -:105C6000000BE57D09785445B670DDBEF7F69274F9 -:105C7000773AFB420837801034C40E840CE0320DB2 -:105C8000411E3A80C1155CA0C3923DE988380F4798 -:105C90009D34041111B551D4A0C034080EF840034E -:105CA000132040C006D4C119D438CF7199059B4543 -:105CB0008210930651F1CDE25FE754DDF4BD9D0EF5 -:105CC00030CBFFBF79EF8FDF4C51B7F6B3D539A793 -:105CD0004E55939C0442461172308EA62308F92635 -:105CE000C67DB5C34AC8F7F0F74342FFBC8424F32E -:105CF0003485903984FFF9170BA490905A33CBCE9A -:105D0000DE3C256B01A42D45692505F41F2B6CCEC7 -:105D10002B14423A5B8A8CB372C3FDA9E91C9F7CA9 -:105D20003298C3DA7E4FC2E378C7929C3A3A7E59E2 -:105D30009C03E7A3E64FD6D3BC899063F504D376E2 -:105D400099CC28A6DF4FD4D3090CD6CE7701B63B29 -:105D500029D17F26D17495E0F70A745DCB3F90C9B5 -:105D6000001CE6C31CBA8E3BF832E6F862093187A4 -:105D7000E7E1311117B40BED32F9D709F0D5D5C7EA -:105D8000904693C64442D4F9F627E48FFB26BD2DF6 -:105D9000D831DBC7309290BB966C7D0BAA7D2494E2 -:105DA000F49D4BD73BB579B9DC87E63BE5E074A7BA -:105DB00055D3CF54F918ACDB4CFF837EA6B9695E8E -:105DC00033FEDDE5FAFCBD440AE7B309B9CAD19F49 -:105DD000E3838FABF865C0D71D744DE91485F74296 -:105DE0003A0C8A1D88AFE90ED6569D8FE72199049B -:105DF000603E523099E4424932D673433DA5E7FCF8 -:105E0000A6CB665731C5E7F407458463E47C83FB82 -:105E1000625D863C9A367E2593FE979EFF8CF9FA4A -:105E200072E265E3A97055E9E0CEA9639E3DA1A1A8 -:105E30008F69EE1B9F3DA183D3145DFEDEBA69BA64 -:105E4000FA33E697E8CA4BBC15BAF2594BEED3E5E4 -:105E5000E7F81ED4D52F6B5CA02BAFF03FAE2BAF75 -:105E6000DAB85C97AF695AA9ABEF6959AB2B37EC3D -:105E70001B7233A1706CF8AD484C148E5F5B4F3EC3 -:105E8000754D12A49213E07EAA3E0DE9FA74BD820C -:105E9000692DD0DE28E09FE16637C5932726544A56 -:105EA000E20979C477ED9225D7D2BC91968FA6D41A -:105EB000EE1BBBC49B49C8128782742F361A4980D7 -:105EC00092AA4012BAE93A246ACA8397286F944882 -:105ED0006078CF723118FD7B97101A9441D7E1FD9D -:105EE000D44436083DF93CCC97A40F49EBBDBCC364 -:105EF00040CA9B34726783C380F349768CDDE0A08F -:105F0000F4506D64FC5EBD2D7D2CB1433E30A8CEB7 -:105F10007A91F19AE86452A11FC62F15FE3E61FEE8 -:105F200045FC0DD0F1FDE038F77A071DAF63BF38AF -:105F300015E6410207B36E1D0AE3BB36C077D242B5 -:105F40003B49A7FC5DEF7AF6C415847C523F01D330 -:105F5000DFD5173F7B4226E40FF553317FA4DE8D5A -:105F600069B0BE1CD363F575587EA27E3EE64FD65F -:105F70007B313D55BF04D3D3F53E2CEFA86FC47CD5 -:105F800067BD1F53950FA83C9A510C7C5A5C6C005E -:105F90003E9D6B21FC8FE5CFF13588F4DF6DC8D7CE -:105FA000CE34E0EB73D66F0665507A3BF70925A631 -:105FB000ECDEE1144977BDE3CF6500FC95FA29F1E9 -:105FC00024F62CB7C430FC580C6402A1F2E7F12B84 -:105FD0008C44A2E3C7BC71D53A311BBF4B403A7425 -:105FE000E3704EB145E97F20417C5D0A4F6AFD9325 -:105FF0002FFEA970662EE0A73FD249CC41B18EE1B9 -:10600000ED6527E0ED52F093387F45C25178E38F7C -:1060100059415AFFCB64159E6D5984A6B73A8A4FF1 -:10602000011D9C6B36E1BACEB5C6FA09F4E14842CF -:10603000BAE81D6E6C1E551B2D3EAD7CA8698AF713 -:10604000E9E545BA4F2B2FCE1D7AD90E7C3F374D4F -:10605000F49D180EF4E1E2F4C1E84EEDBFA629DB91 -:1060600067D5F5A3CF9FF309139A50CE2B71B70DC7 -:10607000ED7D9E73D38C38CEE98D03E260DCD3F5E1 -:10608000661F8CD351EFF0B171D37C5ABAAC9E1F0E -:10609000EB3B91189E5F6FFDFEB3E7474833396EC7 -:1060A0002608FAEF07F45EBF577C48E78DC5401F0E -:1060B000ADF237B0EFC4E4A8FB8E8479B55F4F939F -:1060C000E8355D0DDF37EBC6A3ED94932A9EFA5FAA -:1060D0000CEF1239A9AE93CAC9A15476039D52623E -:1060E000463CBB698F71B4BF2EC9BA44A0E398E2A5 -:1060F000152CF7C040949E6ACC41A35B4170B781D8 -:106100009E3573A4CAF7CA9DBFA724F7C5AF65B271 -:1061100014CAFF4C7BA7E5322F9D4D8AED848E3744 -:10612000B3B96A22C8C92F76FC88EB29BE4258F75A -:1061300097C43001F8E44BF21BFB708D5E3639DEFC -:10614000C8E6B784EDCF5EFA1FAC8FEA69BAFDBA34 -:10615000AC519F2F25B7A4003F94AE90899FCEBD30 -:1061600002F67B75DD94EFAF8F677A5C19A95B0C43 -:106170007ACA52994C057CCF7410A90F9513353B00 -:10618000571796D0FCEDF106A4ABD354BF53A81C0F -:10619000AA48607A4C6592DFE8A2E5C79B87DF7169 -:1061A0000D81F6FEC520D7BC36E2DC407AC27DD632 -:1061B00012FDFC2E35FFC8F912B210E7ABCE43ED4D -:1061C000579D87B85170F9A3E8B3B3E285B09E4CF0 -:1061D000D3FBE3F5FAEB7CC86BF4DB4722F20B232D -:1061E000F22A9DC89C4E4CF1EEF9F1C94017A1F17D -:1061F000A8A7114A1FB9E17AC670BD472E56CF0431 -:10620000F544ACB7F062F52CE1FE1E8B56AF66E7A5 -:10621000961D5E4A4F95AF3F6727549E7F21F952E6 -:106220009CF47BF58647ED00A75392D70EF8FEC28B -:106230002F4E8806AF7DDDF0725905B02390B4294A -:10624000DC5F7D6232E849DF6C901D22ADE2D968E7 -:106250000A9828FDD636574C2479983FCAF28F9D6C -:106260001521DFA2C767E5CF9F4B516C8807A66F4A -:106270009300EA1DB5EB3F1F0F72DC434248879144 -:10628000ED60FC0B09C8F725C6B89EE5749EA827EB -:106290007B389F799A9F382BDA21BDB11DF8CC133A -:1062A0004147E5DDFB4BD0584CE7F37ABC2DE9E4E0 -:1062B0005534FB03F20390072A5C889FE9150D9B78 -:1062C0005EC83B4AE7D5B1FED77621572B47183D2C -:1062D0009E6B9AF5B3DD4AEFF2A693DB45E1767E3D -:1062E0006CA7B4303D88B4B2B45A0ED841EFAC5E5E -:1062F0002B3B29A592EA2D2FBFF222D86B9F9AD073 -:106300005EABDAF2D647A369BE6AAB9C34912DC767 -:106310002AA484F1E3A1FF9B3F2C8C8FCA5FBC654C -:106320005486B2EF0F2784F152B575BF910CED0979 -:10633000C7A2A6FDC6A0350A7E9A8E8E07BDA561AE -:10634000D3B746B0BFBED82790D4EC9EEDCBD7BE16 -:1063500085FB22C009F1C9F1D58DBF1E780B4CDE3B -:106360005D80F51C202F2F85371F97D3353B6D247B -:106370009ECEA3FC7726FF44C0E76BF7DB613DEDC3 -:10638000521DA3F3D58FA6B8E8F8E5B237C5812929 -:10639000FB5EBEE601A4BF32A12EC581FCE44A37F4 -:1063A000A0ECF6A6C33AE7ACBA1DD7594ADC488739 -:1063B000E5ABC5623F4DBF96C884AD51F8A43081AE -:1063C000F149FB3A8A5CBACE76D0FB41DFFE8DE81C -:1063D000DF80F6E97D04E4FF037CCD74A7C4FCD71D -:1063E00066862F6B8241B517CD3AFA5DFF581BE0E8 -:1063F000E9745F572ACC93C2C1CBE1267C4FFB15D1 -:106400003FB82195E1892852216F47F78322F80E82 -:10641000F5DB6497254FD78ECB4F36FE3C3E3E9D35 -:10642000770CEC6FED2954BF8FB2BE99B03EDC17EC -:10643000E93EA7A1330DBF33FE5FFF38E37795FF39 -:10644000FD532640F9F90F191F413BD84FE8BC0214 -:10645000A958BEFF3601E5838904A2F1F97A99F3C0 -:10646000B9BEDC43F915FC042A9DD0F94B429C9639 -:106470005EE838098807B4574A57D0F65AFD06C671 -:10648000C57AC6F077CDBE52C6E5427E029507B109 -:1064900061794056255F961E592D132FA89CD59FD4 -:1064A0009AD01EAFDE2217C3FACF6C3EF8D15D94AE -:1064B000CECF34A97CAB97AB917C5BBE6D8300746F -:1064C0001AC9B767CAE92E1E8D6FE9F7A87C5B1E53 -:1064D000FC7F2A5755F84D4BD0CB532A1FFB810A1E -:1064E000D11B1C23E5E3D7A06F25F7948FF4EF436E -:1064F00052D8930E55FA53E98E6A70FD40AE77D3A9 -:10650000A74A7FDDF4A9D25FE47AF5F08B2CEF0F78 -:106510003612A593E25D54A3A3F8AC6E15FC26E4F5 -:1065200073EFDB7D0A104E2EDCDE88EFED3E49DA9C -:10653000BC3F22DF1451DF15912F8EA8EF8EC8D7F4 -:10654000E9EA57B71C3412C47F4057CF34FF257295 -:106550003C8A3DA8EE3F9EE6B3462FD04566C8086C -:10656000724F5E485537F0AFED15D1BFD6A584EC1C -:1065700009F4FBA31666A77539783E9EE543C9C6A4 -:10658000C520F7D4EF210B41FBBCAB38648FD7D8C3 -:10659000FF475B45BB42CB837E3241EB4708CFA729 -:1065A00001F11D24BD9533BF61578C3D0FC78BC9C9 -:1065B000F203FDDD205AB3E683BDE7139D947CC84A -:1065C000EC0577DA09A5B3AED601374FA5DFE7BCF6 -:1065D0002382BA4DD1E392D229DDCCE2747C8A7851 -:1065E0009FBF96AE6F562BD3C3672F8B4EF795BCCC -:1065F0007EA9759E11E42BD5A38F69FDA295641920 -:10660000D25DF9AA88EFAD3F42FEA88CE00F37B704 -:106610001FF6AAFC914FF251BE10C2EC5F2E976F8D -:1066200010736F9E4AF1D07548242605EC59912CC1 -:1066300086756E16FCE02F20DE64E4B35A124279B0 -:10664000A8C2A903F86870EF72AA63FB1F0B1F02B0 -:106650007AD9F1FBBC9768DAB1E3D3417B20BFF371 -:10666000E3ACDF939EF58BF67D371DF6B3AE7D264A -:10667000F48B75EDFB65D64390DF6D42BF58D74272 -:10668000930BF8C0BBCFE6BF02CAFB32FBA161EFA0 -:10669000B77941DC5F1721DE4E2530FBE55CEB9FCF -:1066A0008E084990D25581FEB02F16F9C8B3DB820F -:1066B000F67AD7DE6F0BDDD67FDE7A6A8DC48DF475 -:1066C000682353B701FDC633FFB167CFA89717D032 -:1066D000F16B9AF71B67D1F2A237FE9207F2B36B08 -:1066E0001BD38B3AE5E01AE224E4AB84B2C765F031 -:1066F000F301336510F274E2C61BBDB9D1E0C2E00C -:10670000D045E100EBA2702907B9DF1B3C62128D76 -:1067100048EFFF7AF0383B9DC9B51F10F00B85E1BB -:1067200022B8D8779BDF2CE0FAD9F77DDFE681DC51 -:1067300039D3B400F5954BAD7B48E2BF2A1DFCBDB3 -:10674000EB160297B3EE09FFB2F866F4FF5E8282A1 -:10675000F38CE4839E74BEF3C7987FCDE6C4F95EE4 -:1067600026FF97FF6FC3FB368A77FBA5F1FED8FFA4 -:1067700058BCBFC3F16E7398409EEDFD0BFA59D51E -:10678000F55F6ADDAFFC0F5DB7AAC7DF64A83B3CCD -:1067900085D63F4C022B8AE93CDFCCBCE1C329B44F -:1067A000F497BDE8271F25323BF097A07C80FD972A -:1067B00026F837A05DC1ECA622C2F6F5A29C32D421 -:1067C000378A729E40BD81487587F3293C6ECA9A0C -:1067D000E35C8AD5877DE2A6F97F4BBFCE89FEC3F5 -:1067E00008FBB1E8CA1B0F81FD7270019D1F1DE7F8 -:1067F000605FD1413527322E530E98F2303D0AE9C1 -:10680000DBF609586F9C556F3F4D04BB47630FDEA5 -:10681000A8E8CBC7F3FE2790034912ED7F825326E9 -:106820007EA8477C8BB4E7CEE323FAD946754CADFE -:106830007FED6F859F3989D999BF24730FE703FCDA -:106840003265F41F5E127E006F8457BE7F29E856C2 -:106850009213E17753460D8727B3AB25DE5EB22E48 -:106860006E03BE9508B58B995E86F6B46A175F0A0B -:10687000CE84DBDB121F5A85BB9449ED6D7DBF08CA -:1068800017151F7F2B1E54FCFDBDF8F81DE0634457 -:10689000181F99E71D12F06711B707C69D6F1331D6 -:1068A0009FE994F0FC85DB0363ACF112D803D74970 -:1068B0001F88C09765E65D95708E60760A48D7831D -:1068C0003B0C68EF980B04847B4EA384F90F0C8E6D -:1068D00011A0684FBE66E7990709F8935D46A67850 -:1068E00017337FFE9FBFFFFEDA42F0ABB0BF32FA34 -:1068F000BF49D41E9BBD8A0462E8FAE648C40B2156 -:106900000E737C0239A6F307EBF3F0777D4AB89F4C -:106910004BD5EF4D8EFCB3D39D546E1DBB82905D65 -:10692000903267BFA4B59B7FD0CAE0E5394CFCFD2F -:10693000512EB8C462CD39DBBF2731F9B1F30FDB7B -:106940008683FF6C4C576E1C93A70506A04B0FB7B0 -:106950000BCE11250EE215CEB50E88C373C443A22B -:10696000CD1DC56FB389DBD3FF518F4E65D2B59E68 -:10697000F844B09B4808FDB7DEF5E6A8E7C13393BD -:106980000C9C6E38DEE89F5808E7166CFC39B46939 -:106990009C166F1D13BF90F27AE201FE8E69CE57EE -:1069A000FE51F882FD0EF0DD64098E2F8E223FE647 -:1069B00071F84D3EF01DFA3BAF6C5D6B00FABD7295 -:1069C000BD41773E599DC4EDAE616418CC6BF201B8 -:1069D0008BAD00F07248745AE8FA3CAD678DEE2832 -:1069E000E75C91F084FEC18FFE6A123B17D8233713 -:1069F000CD02B8EEF9D24CBC14BFBB8CBEAA68F372 -:106A00004C4A61726E0E69BA3F2FFB5F0FBE63BACC -:106A1000AC81B16067AE27DCAF11497F04E9F8DCD7 -:106A200046E287FD14EC52900BE73613DCCF294881 -:106A30009E04BB9AF2FB0FB57E9AC12D5BFF03F457 -:106A400080DA56C161A0E5B552D008FE584F4BBC64 -:106A500008FB6EBE425C783E2C3986DEA6E18B5781 -:106A6000932484EFC1D17BEE8671BFEA3012D04708 -:106A70005C6F86ECB06F7FD53A1CF9A0B775FDA2AC -:106A80009E548E93A11F260F23E92177738C2E7FAE -:106A90008DE8CE00FE9A6C0ACE7346C1DFC4644610 -:106AA00067972DDFFCFF9FC9B70F55F9E6168B35A9 -:106AB0007C9494CCE85E23DF52A3C9B7B982920AD2 -:106AC000709FBB77402AE075EE3B727234F9B6A531 -:106AD0009E9DFFBD4EF911D2AE662ADFAED6C8B775 -:106AE000662ADFB27BB6FBEBE5CA37FF7F0FFF6D8F -:106AF00001F91665BDF11C7EAA7CCB6B3D8AF22D97 -:106B0000AFD940148DDFC99C7C29F92624DF06FA11 -:106B1000F021D9191B857EB670FDFB751EB707E302 -:106B2000809CFBB764765E7AB9722E3D85F1C925EB -:106B3000E5DC7F139C553937773B9573D9D1E890C5 -:106B4000C9B9B9BBA89C13801E999C9BBB9730FF09 -:106B50005B847CCBE921DF08D6AF0DB0F69E96ECC6 -:106B600017EEA1FD0D73C94E33AD3F2C2CEF4668D7 -:106B7000E5DDBF254B08E71EF2EED0E5C9BBED5CB5 -:106B8000DE5139D61FE46B247D385B6374F93DA375 -:106B9000DA37FF02F8E55D11CF173F30B073A0F789 -:106BA00046B517007DADE4F3F170FAEBACF762FF88 -:106BB000456FB2F5D56C66FEEFDA66A61FD6AE1746 -:106BC000FD0AFDE7F8D1DF1961FE157B05924AF356 -:106BD000534CBEE7AD20837F2E13762E4626E66B00 -:106BE000E861F6C82AF4E33758ECEB08E5E3D9127C -:106BF0003183BFBECA3AFE0BF0D3578D64FEFD2A27 -:106C0000FE9DF0B801350EB2B4E5BEB7FB909EF123 -:106C100003934D0C8F935F16FC6BB3217E495F5E2F -:106C20001511FFF8145FE71431887021EF8B51E3E1 -:106C3000189E8A84C7210E0FBA7E1D3CFC425478F0 -:106C4000508C4ECC4F09AFBFE2DDE062F0E757ACAD -:106C500014F0DC578547E43A55F8A8FEE92ADEDE51 -:106C6000D37A1F9EFB47AE5F855F8F75ABF08C5864 -:106C7000BF2F999F7BE593E1104F43E901E587F72B -:106C800057140E749CE23157A46AE5F1F31C0EC34D -:106C90007D638AD209C08DD401FD9436DEF7763A41 -:106CA0005DFF884F9461B04D5E33DAE48673D44D56 -:106CB0009610CA3795BEDA557AE7FDECC9A81B8B4A -:106CC000F67A8BE000FDC213B0201C3D94CE2CB4AC -:106CD000CAC195DF8CE770749890AFF8BE43E16E3F -:106CE000A0F5C7ABFB10853BF0CDF0D6B3789E5B2B -:106CF0004042785E52DB283803741DB52D0C5EAA25 -:106D0000BCA57F562D3EA2D0A3148D1E0938890B39 -:106D1000C3FB6015AF37D9E4FB08CE6126537A5F19 -:106D20004BC278CCA1FF011E23F1A4C2F352F4F9A7 -:106D300039D73FB6001CAD00AF10D3A302745FB0CB -:106D400085CB3D925707C7A2172F30FADA2B287050 -:106D50009ED00D27A0575A3EA295D12BC04D01B809 -:106D6000B79688902FA5F04DCCEEB94E38BFD4F22F -:106D70006FC5DEA3ACFFD5829344A15F75DDBDD1A5 -:106D8000EF3F4AB7ED1174FB9E25747838D0ED5E65 -:106D900081F9115AE375E78EA61476EEBEC942E971 -:106DA0001BCEBBDE919DEB949E7C7E81C313F47F52 -:106DB00045E3971A020B80B3C08D668C3FC379F40C -:106DC00067FAA556BE6EB190E4DB0A7AEFDFC8ED34 -:106DD00081DEF41B353F14C603B9D742C7CB098FF8 -:106DE0001729DF557BFF52EB4A4CF9C7D6D51DBF9B -:106DF00049DAF0FCC914EF7E2809FD3F2C3EE90E6C -:106E00001E9F4467807A96A65E5AF288DEEB913424 -:106E100033EEC3F7F3B8F81B442BF1D2757CE5923F -:106E2000914EE92EFDDB6B412E8FA5FB084DBE3A3E -:106E30003CE2E37BB05CC4F3A89BDF4DAC8173BA4A -:106E40009B4118D1EF37E70BB8FF7E009D8D023DC7 -:106E5000D64C5C264EC2B47CE40FE2D16F94BFDE08 -:106E600057A4507E1AB6D1DF00A9B32894F41EC0EF -:106E70006F8C48007E6DAEC422D8BFEEFF9CE48BC1 -:106E80000AEEB3D8CFB0432419EA8D7625A3393062 -:106E9000AA794511F847A71CB45A81CE73561988B0 -:106EA0005B43BFA389BF01FC36A34EB86E05FE2B22 -:106EB000A7FA02F89DCB5BD736D821BF4A702AB417 -:106EC0007F8FD73DDE4EE7B5A5F1ECF8AB800F69BB -:106ED0003DE8C6B38AD5F3AC179C102A5BDABA1C1E -:106EE000E3714AD70BC401F5FD0231B37EFD66DACA -:106EF000EF9655B43DCD97417BE877FDD90F6F05EF -:106F00003E3F2CB2F69BD9B975296DA700BDAEBF27 -:106F10000FFBAB58259034DA5FF96626FFCB0FCB19 -:106F20004E286FDEBF12F7B18974BCF46C90F78104 -:106F3000719027C30507FA3B33EF42BEEEE27C4D6A -:106F40003AA632B921F03CB71B54BDE9400A8B0F79 -:106F50002E752E3026D27EDE1B999C0D61029E96E8 -:106F6000B3781E7D82C2D94DE1FC018FE73838F23B -:106F7000B831A8D97F3E4B19807438BB650CC6392F -:106F8000CC21C518E7307914D3D7DEBFCEE217E89D -:106F9000BCDE974399F0FDE07526D47F3BB7C878F7 -:106FA0005EDCD93788FEE9F6553281788D86552228 -:106FB000CAC5F6CD6C1F1757DF3E3E1DE0B74170C6 -:106FC00082DC3CB8AAC808FB5ABB5FC0F645AB1FC1 -:106FD0004861760C9387AADD56EAA8D0ED1F91F29E -:106FE0004D957F351C0E9172AE46DD6722E45C0D37 -:106FF0009C37DB21D57FF7102B937FA0F703DE03AF -:10700000DF21FDD61E9609E8FDC2F18EF118B70505 -:10701000FB262D1FD52AB8E09CBFFC13931FF55506 -:107020007FC98C9F80FCFED4440405E2E029DCA9E2 -:107030005C18690AFDE159FAFD8B0FCC102143E978 -:10704000A404E1ACC68B166C60F12D051FAC482979 -:1070500005388C4B44395BD62812B7465E7C21B884 -:107060006EBD8BC963C7068D3C2A30FA4A61FF7238 -:10707000A43239A86C902166846CE7F289EAD32E99 -:10708000D01B2A762D4F31D27A8B793C48C5DEE56C -:107090002954349006D8B768FD0A23EBBF629FE0FD -:1070A00058ABE95F6DAFF6A7F663DCA5EF67C05E8E -:1070B0009EBFCC7ED479A8E3F7A68F8FFCCF0B2B95 -:1070C00004DADFC8F7450C521E797CE200ED7987BF -:1070D0009AAAFED7C20F0DC4A581DBC83FC4109782 -:1070E000862E9A4750FEA6789BD4C2F4A1E611479B -:1070F0008D35059877003FD7723F6DED38766ED5A8 -:107100009CFFC122E0EF890502D201F1BA8D8949C5 -:10711000A8072970BE5056C0DA97D1F6C077CD2B9C -:10712000191F5279A080BCA85DB57C3CD65F2F2882 -:10713000D07FF3DA12DCE7CB478A04CBD71F45BDFB -:10714000A3BCE56812F02BE5CF15B0EFD65E6B72ED -:10715000007FA87CA7F2F1FB328B0F2166C750B8E5 -:10716000075096A244E55FF1306176EA6619F9CEE0 -:107170003392F1E5FB5B44E4E783D7DD391EF8B0D9 -:107180007383D00B1F533E2D08F3A9B89AC5EB9417 -:107190006D62F6CAC1554C3EB437333DB168B53C5B -:1071A00009F265EFCA84F9BD983E78B9FCDC434F1B -:1071B000D9189D9F7BE3DFC972D347F7D3F9DDFC74 -:1071C0001A9DBF128657D1F50FDAD14F7FFD345C7F -:1071D000AF2A874A2516CF34DBB780C5FB4A2CEE91 -:1071E000ED6F9E57C43C1E4BB185E58808F41ECF59 -:1071F000E2A4D7CB48EF91FCF88FF2D13F8BAFB729 -:10720000733A52E723EE65ED21AE2C40E1F8CBCD89 -:107210002F635CEB97AF1E9D0C78AEDA43E997AE17 -:10722000B773B38D04406E497EDC6F2A9B458C1F7B -:107230002752A0F0569B963F597C52D5EB36A49B23 -:10724000CA6D2CEEB472C7F13C8C175918C2B82B1A -:10725000EFAB5CDFF406F380BE2B25162715C9EFD4 -:10726000635299FED9B12B762AAC43D8B81FCF5BB5 -:107270002B9BEE9481FEBAE547AAACD6C3734C2F84 -:10728000A55F386787F94D19AA9DDF02C453C72649 -:10729000C6FF952DB2DF02F3DBB816FDD99E8D67D0 -:1072A000313EBEE8F52DE847F0B488FAB8C88D2223 -:1072B0009E63D114CFAB22E3136B9B6BF0DCADB6B6 -:1072C00089C7FF45C4C555BDBE77879782A6EA1713 -:1072D0003FB7833C38DDB6C10EF0A4FD615CE1F53B -:1072E000E7255D7C54EFF1C02E7DBC61D3E33CDE2D -:1072F00070523BC9EB196F781AFE01FB4D6A44BC12 -:10730000E6C6441EDF1D282C8EE2CFEFBEF7B3E5A4 -:10731000EB351027DFB1EDCC1A987FF55FBF5A032C -:10732000F14D649F05F729CFABBFC5B862B5DD82CB -:1073300054466F9D9B7E8E71D99D9F9AD0DEE9DC6D -:10734000DB9E05F16D9D5BBF4B01FFDCBCBD37A033 -:10735000FF72DEF6A2541245DEAB29D0A7FF32E25F -:10736000C223F171B0F920C6617DF98909E55B7727 -:10737000FC68530D8BCB5578DCE8E6E871F86A9C25 -:10738000636DF3AD375F07F2BA99E977DD718F97D7 -:107390008A17FD90E2F5EACBC0DF661E17DC3429C0 -:1073A0006ABCE897F00F8AA79FA5EAE345BF6E9EE7 -:1073B000F3B317A1AC39B1D778D1C065C04D8DF307 -:1073C000AF4E75BD9A0A7CB42DD69BC6F0E69F28B9 -:1073D000801EF87516DC8F382587300E24B4D7E46C -:1073E00080B8C7CABD1F23BF746EFF00FDAD84C740 -:1073F000D97792EE3F160F2DF075AEB7B138530E18 -:107400007F884355ECF89DC79B323A56E3507B8BFF -:107410003F0DA6F2FBC3FCDE410DB59B589C7A38AC -:107420002E551809F83AAA8BEB55D71DD99F83CB57 -:10743000D1705C75F4385F358EB027BED8BEA2C659 -:107440004D77AEE5F1D6F47BE630889363FBB9C7A0 -:107450002F7C1C0DBF6A5CF5EF23F0ABAEAF37BEDF -:1074600050F9F352F3FE7BE1F26E2AF367ABF0E9D9 -:10747000F8737439FD0DE7776AB77E9DAAB16F671F -:1074800070BB55859B3ADFC54D4CAFE8D8C8EC873B -:1074900048FEA6EB71458BB397D298FE5BDBB23FFB -:1074A0000FE450C7815D9CEE185DD76E3ECAE27452 -:1074B000A9DCF66BE536617EE4C8FEECBC3F4F6BA1 -:1074C000F4FE3C9BCF46EDEFB4E4BA13E67FBA8DF1 -:1074D000E951A79BC409FE28FD5FE0FB52F7BA6D96 -:1074E000468C9712ED31A84FCDB38DFC242E095256 -:1074F00023C6FD342CE071428F38D300CE0DB69BED -:1075000008CCE751808FC6FF203BDC04F43839AD4E -:10751000B84054C2F355CB8D4906E2D7E25F0A6406 -:10752000827C3F92DF2E437F9F45F84D3E93C8E219 -:10753000543AAFCFBC827381D2BBDEADE6DD0F8B98 -:107540003A3F47AD297404F477F28605FDD6E23E52 -:107550008B17FD666B2CB8CE83DBBF7D05E0D5F9BC -:10756000331361E7089430A85C28E3FE8BF6EDDF67 -:10757000AEF913E899D0988E5FB686D607FD7A7378 -:107580002CDA035DDBE2F2509F7CE3A1C92037CA0D -:10759000600F033DEFF5547F03EDEF6432CB9FDCCA -:1075A000D217EF13546DB361BCE1C1ED3B6B41FEEB -:1075B00077BE1E0BC7D1E44B39F857C87BF6C49190 -:1075C000B50AEA818A76BFAD2092A2D5F3AA20AF90 -:1075D0008B7F2168A7A33F8ED273554B1CDE1FD132 -:1075E000D4E3FCECCD60F7650219C077549FD48DCD -:1075F000A396DF96D69FDFEF0DFD98BDAFC0EA7B67 -:107600008CA15296F76530BE6DC3FA252ABDF2F201 -:107610009EFDB2FA33D2FAEBEAA9ED6B4DA42E1A15 -:107620001F54A709FC7EEF5F06477BCF22CAFCF1FF -:10763000FB0302F11A400FD86AC138AE6A636010CA -:10764000C4B7EF30B2F3916A7B6010C4B7EFE1F2D8 -:10765000AF3A86E6E9F70C3E0FA80F79620EBE0638 -:10766000F8AED969214BC17E7FC3E6023CD7ECF866 -:10767000F6E44B0510CF168B7EAB9A37FE1DF15FFB -:10768000630A4C07FA0F6D359175B47EC7D677B291 -:10769000408FE8900359091739F7A96932E9CEB14B -:1076A000D5759CAEF70F84FBEBEABDC5CA5EE4C599 -:1076B000DE34A68F2E4F733D9D867C6D75A0BC86F3 -:1076C000FE44E8A76580F65E73A5125D8EAD4A9311 -:1076D00075F768C5F03DC555D0EF9724B83883A23B -:1076E000A44608E1F979E5C6B343C11EFEECA757ED -:1076F000E1B9D667C6D05090DB9F6585866AE5F113 -:10770000A97AB322C9E897C0B46BEDD9D20C02F1C3 -:107710008396A9D1E4D396B4589C47E5C3B151EF01 -:1077200083EEE6F4B61A6830998D0B7E0875DCCFCF -:107730008C7E23CC23375DC1F2CA4CBF11BE576D7E -:10774000DC3540F7EE84E4C37A94BF101E156485DF -:10775000B1C0DA53AE54CCB72A12DE8F96FEAB9B83 -:10776000DEC4309ED0C909716A1C877467423FA885 -:107770007A1F40928BCD002F2329764822A0DA87EA -:107780007C1A439A30B5527584ED437504E28A4EF3 -:10779000F1F35B93A43C0DF2C3744844797E29B89D -:1077A000FD32CD8EF3364975C4897AC74407E8D5D2 -:1077B00082D74DBEA7F4D050BF71C00976FEEF82CC -:1077C00038383B61F3B33BDEFE0EF4034A6768676B -:1077D0007BAF27FE063A9E6464793296F8A39DC774 -:1077E00077703C10EF7E943F5612FE0BD17C2C4AF2 -:1077F000283A6EDC5F47829D6B759000E84DB1566C -:107800001288A5A935573AADE55F3B61F9FE949C16 -:1078100041AE39AED59747D235714AE7BBE5A2886C -:10782000EDCF47B43F7FB1F62A3C3CE601D9ECFEF0 -:107830003B834B0C5F8377ACF34210E09167773664 -:10784000001E8DA1230F013CF2ACCC4E4C6A245A91 -:107850003B6E403A93578B04B65FD2BF62ABA63FF4 -:10786000E230A3FFF4710EF7EEFAAA5FA5477D8B15 -:107870000470ED51DFD25BFD98E8F56DBDCD273684 -:10788000FA7CE27BE9DF1BBD7EED1B1FBF1750E0DA -:1078900023931B1231A8F7A007A483BD157724A555 -:1078A0008451053B2788C05B0CD01FA58798819A1F -:1078B000EFF07FB91AFCF58F827F1240BA2BE1F30B -:1078C000A1796B3A9DDF5D7CBAE3D6B373CC7BE6DE -:1078D000313FD25D0FB3FB42477FCAEEEDDFD3C825 -:1078E000ECED7BE6B3733352CEEE0139E87F30DE48 -:1078F000BDD009C5F7BD3EC11FC886777022F4D739 -:10790000EEF7761E90A07E49843F46A527F5DED28D -:107910002CAE5F6773FA9C434236E0FBC87BF4CD24 -:10792000692C2E8D9A632E58DFDD7C7DEA3EE05D6A -:107930004E72E05D00D110E384F31191DF5B257698 -:1079400023BBB77A5B824EFE9CCB51E260BF236FB4 -:10795000F2EFFC3DA2B9372AA9DA7B5ED285587CCA -:107960007FA44176A6815C942FFC8828942F8C17E5 -:10797000061045730F8DEA77C8ECB283A01F4772DB -:10798000149332D00BE3399D25DDD4AD87BD4FE193 -:107990003277B982F760EF4C67FBCBD28CE239408B -:1079A00017A27DA4D36DED8957EF76B6BE06585F5A -:1079B00076CF7937189D4ED4436FA21A04FA7B9C78 -:1079C00066988F68523E56803F7F2D13B0FF7BC272 -:1079D00081E1F35C52821FE25F66DB971E01BA5DB4 -:1079E00056EFC073B425F539982EAD4F433D7471F1 -:1079F000BD1353152E66A7CF2552389B07B2FECC78 -:107A00000E37D333E83E04F11792A32E0079736644 -:107A10001D01FDD7D20D1F1FC2C7D89D7763DE049D -:107A2000799ACA8D1311BEB43D29033F6A867B192A -:107A3000C0C7A25C49140D5D98D286E9F23DE0A66C -:107A4000D2C71606BF2705461F91F07B526E53E042 -:107A5000FCF9C91BBBDFB541F851759FC1EF57EC6D -:107A60007CAE57F83912509F9D5DB8783AC4553FA7 -:107A7000C1CF211FAB1F89F07A1CE2BA06837DE0DB -:107A8000C25404F8513A32E57A8948DB9B143667D0 -:107A900093B5D8652860B40BF013AD0C9EA6B43A2C -:107AA0003C8F335B19BC44AB17E1225B19BC442B00 -:107AB000A33723CF4B00BFE1D81EBF53F835A78FA4 -:107AC000003C8CD6C1CB9834F6F2E0B792C28FCE90 -:107AD0002389F357241C92E09E426E98AF7AD3EB31 -:107AE0009EA3EB877DFC050A1F48937BB11F933350 -:107AF000981C4D32D4ED97011E0984EF2F5E9259E8 -:107B00004858A822FCA57989027981CD83ACD7E3B6 -:107B100055744811EFBE292F001DAC784736C03987 -:107B2000A938FF47BAFBA4E25457BC82F0740BB0EB -:107B30003F3F51AF20FE96031E07C3FEC8ECB1477E -:107B4000393E1F033E41FC32FE7892F3CBD39C4F6B -:107B50001A9CECFEC4B2092C2E2B29DFC0DF430B8C -:107B6000106DDC53BCB38918E9BC50C756300DA06A -:107B70009EF189C97F056D179B4B5C4027F19F3CA7 -:107B8000E8C7B592E274D08BE2B9FE4BAE55E2A7DE -:107B9000E145DA80C4EC102A0AD1AE6933447B0790 -:107BA000ABC179C00C7ED3DEE6B37FCA0EA4CBD2C4 -:107BB000AB313C9824BA8BA7CDA1796B632CFA0723 -:107BC000639DEEC24781CF1B6D48A7563AFF320D29 -:107BD000DE637BC1EB8B19371A32281D8AA0B451A2 -:107BE000FC3ED338C002707E4E2E4E07F9FA1CDFE1 -:107BF00067290E14ED3954079793F6822B75F6EC2E -:107C00000AD985ED1CD7EAE5C00A2E7713C6E9E943 -:107C10005D95BB1F75CB5D7732CC27E5C238E4C7D5 -:107C2000A45BA2CBDF06D9E88577051A86327EF7FA -:107C30009618D97D989EF200FDDAE7DC83D6813C68 -:107C400055E96B2161F2C74B629CB81FF177745400 -:107C5000FD7809BC37C8E52CA4E24023D24DCA3DCB -:107C6000068CCF5BC6DFCB7A8AD217A43E4A5F90E0 -:107C70005E97C1CE33169A87E1BB6D0D5603CA0BD2 -:107C8000E95393DF0AFAEAFE510EF02348B2B3CD6E -:107C900005FE409BD4B48E40BD0233BC2721C417DF -:107CA00038800EBEB1CDEE77B1383C8A4E01E8C8BF -:107CB00091544C8EE5E2E901DE7B911DB710F02B6B -:107CC000BE90546701B8E56630BBABB1A410E14883 -:107CD000E13B362339DC4FEAD49BBADFDB826E5FAF -:107CE000E8E5FECCE40CAE47677AC9400DBF370A21 -:107CF0005C0F53BC2447C3F70BAF184FE05CA927B8 -:107D0000BFF722CF363079B648882ECF54FD539531 -:107D10006772849C50D3C5FD26E8EE7719939C408A -:107D2000BB907A0D144592F7EA27EF8E4738CC02C4 -:107D30003890B49BBAEDDA1FF607BDB2302ABD45C4 -:107D4000CAB1D9DDFBBA2B05F0744A5652A7013DE2 -:107D5000BDD3DBBEEE2A453AF4F551605FDAFFCCC5 -:107D60008FD0AF73E2199B0272A8ECC2E3B83F94C4 -:107D70005E18856979E38DB89F0BCF4E2A047A6827 -:107D80005F7543DEA7E0E7F1D970DF6E6F2C1A84D0 -:107D9000E791BE5805E23BDA1B697941B81CE2C5A0 -:107DA000454DBC0001EFBBE6FE372950502F55DF93 -:107DB0003DA3769D7D34F885568B782FACF4599B86 -:107DC0000BF4CFDEE8AF7455747F00DE614AC70163 -:107DD00073408FDE6F1F1D0AD07E67AF63E7080D0B -:107DE00046D7C900E84DCF58F01CB22121FABB207C -:107DF00073326E580672604E86EB39C49395BD534C -:107E0000DA3B3FB0F14FC221339C63BDC8DF4791DD -:107E1000DCF629BA7336768E7592FB5988B997F2DB -:107E2000185EAEF4526E67F122C411BD5CB53362C8 -:107E3000C3764613ACA3A6F1CCE24F115EDCCEE0D4 -:107E4000F33E25B3799F7AC5E45F1885FE4FF1F8BC -:107E5000940A81C157E58353DDFA911BDFC389A4DE -:107E60005361DD901746D17EBF3A24E3BE514DE900 -:107E70000BE96ADD288C8F179E19F534C40D9F3FDE -:107E80002C6279E5050B96773CE27C01E29E42EF9D -:107E9000CA04E4D3F94337C4313F91DE8F7D6F1FAD -:107EA00026178E71F9507AE109A4DF6E3AF1CD31CF -:107EB00002FF955E788AD1F74601DFAD24DEEA77CE -:107EC000C70CE4F4391ADA574C5A08F0BED687E7E3 -:107ED00024651B4C4ED00722F17C2C43D1F93DCABE -:107EE00082CBB05F42F5AF24CD79FA291E675C766C -:107EF00081BD57481C5E9206FCC0E553988EF5EF95 -:107F0000D07658A2FBE9CF71FDA7F4C2353A3B23E6 -:107F1000BCBEEBF17B29DFFFCB82A3301F5ECF0B12 -:107F2000A3A2AD27BC8E6BB17E477CF4F1D3399C04 -:107F30004FD6971317956FE54656AFD4F78011E4E7 -:107F40004EE9AAF80441B3AEB2C62A5D9C47D9AA4D -:107F500012E34C4DBF613C2C7E778C14C643FA4B28 -:107F60000B262DB4825E502CF7017E5A5751F81320 -:107F700005FA63F2E90BD99705F2BABDF17E7BB43D -:107F80007B13E97D22F0D3C8F143F5EA020D7E545C -:107F9000BC44B63FB9B6ACF027E08F5EC95E21E9BC -:107FA0005DFE44E02D3B3ADC8675C32D07E38D2E44 -:107FB0000DB7AB7471453DE0C6F1ABC245FD4EF562 -:107FC000A8ABFA8C80F108BBBFD3C8F07F297885B5 -:107FD000C7E5F81F137D1D53BBD7319F7829A3CE6A -:107FE000BEE43A1E225EF345D6A1E29FBCA2C3FFC7 -:107FF000D497D6221FAAF89E7D6025D2EF6CCA8F37 -:1080000070DEDFEE7BC01E2DBE686A6F781FE8252C -:10801000B985FFF7F0FE85ECCD82B832EF720BDA4E -:1080200023A7D63D91A585F39C8C31F7025EC8FA53 -:10803000E4CBDA3FBC639D87C0BEF43E23A33F6D13 -:108040006B86BB0CDA97733B7C51FCF841D1F4830F -:1080500047EB0F0D013F5D437D1BA632D72F09E88B -:1080600097D9A82FB9A2BDEFB5A40F932B8FD6B780 -:1080700031BFA7D94B1CDAFBC484E94FFF4598BF39 -:10808000466D6794DD0EF09F1A05528C7A9FE45E70 -:10809000925D007E8FA47CAF067E8BFBB0FB48CB4D -:1080A000D20E38E03EB189F60FFE1C73A6744E7FE7 -:1080B000CEC9F2F9C2A722C437CB494D04FDA1B9FC -:1080C000F4BB06DEC6A4369D7F3A120E92D98EE727 -:1080D0004D1261FA9CBA7EFA05F7A5C7F8BEB482C4 -:1080E000FB359FAF6F42BFFFC2583BEE7F8BFB1942 -:1080F000983D6596F0BD1A533CAB6F8C63F3B68028 -:10810000DF5B847D3580791BBCE823E2D36802E421 -:10811000E38922403E910416E33B2963823F86EFC8 -:10812000CE34B71FF0F84D7ADB1101FCD8C5EEC193 -:10813000B0FF368ADE7C85D6FF9918CA877A59B493 -:10814000E8930496F6837868B7E65C8BBD13AA685B -:10815000FD8291F97EF3A588F39E3F0FD6962F4FAF -:1081600073BD0EF368B0B07786928E0B789ED360A5 -:1081700061EF0D35D8EE88837DFC577D98DE8E74D7 -:1081800000747488E933E724252E81F94995377501 -:108190007E7EB3F2A6661C89DB7BEB295D4A9A736F -:1081A000958192CB007473858F7ED7CE338A3F2E14 -:1081B000C18ACFF2463DCF51E70771FB0047F1C2BC -:1081C00078B4D722E9614FB79FD92B023EA7A9EF18 -:1081D000174B8B583E9EA87F687F7DDAAD8F2E624D -:1081E000797ECEE999C9CE311B4AE2303E4E9DC719 -:1081F000B4D6C7DA404F9DD69A3E0BCEB7A65907E4 -:108200007D0EE91E39742016F4C00704BC5772D7DE -:108210006FDF946369BAFDC375789FF9732E4FA71A -:108220009310BE0BEF260E7ECEEEC7EF338993E799 -:108230009B64B0EBEF09F86F9F4473F7BEE99F04AE -:108240006ADBF443A1B7400CB89B1CE3F10C416D11 -:10825000D7E27C9BE559BBEEF54B665C4F78BD667B -:108260005CBFBA3E3A53847F377CF87B4D2A3CC4CE -:108270009974DD945EA6C5DD7113B9885E3ECD9A12 -:10828000F3393B3461F38984CF7928A2FA63471F1D -:1082900017C9A4F8FB7D1F970069B5399425F547E8 -:1082A0003E91215F2BBAFB41E8F3977DDD8393017B -:1082B0000E6D8997253F8F5818FF1F017A8638AFBA -:1082C0000B49B82EF51DFA830FB6DB40EF5CBCFD01 -:1082D000637C67B9460C3E7927FA4345B49BCE359B -:1082E0000FBEE8FDB323E0A7A2FB5FDF4CF59E25A0 -:1082F0005BE70C89F1C98CE6588CC79F315FD4BD10 -:10830000233D633E8BE723525BDE6D3A7D7D51AFAB -:10831000FD80BF20B29F59F38BC8F1E1704EEB187E -:1083200083FE83358CBE668D738910EF3C7A89801D -:10833000E7ADA34E282D419A9FE58F77027BCE7A39 -:10834000F03F07C03B07B56DCC1F982ADE97FF08AA -:10835000F8590EB07D1CF2F7019D585D8A55735E89 -:10836000D021D7E5C37B7FDE7BAD2EE0FF92DB5CC7 -:108370009FE27BBEDC5FA1EEAB3B1B4B304EB6E415 -:108380001E6524E0BFA4C9E2C2D44CA4182AC74A7F -:1083900024628634D548240BA431C40C69E142F62A -:1083A0006E7769E314D40FEC238B8DF01E6F49EBCD -:1083B000CFBF86F6655260BF9017864F49EB3BDF13 -:1083C000015EE7B88A319EF1AA8D469D1D38B449F9 -:1083D0009FBFBA459FCF0FE8F3C30FE9F31B3209E4 -:1083E000D2D14CF3ADB900AF037B4D742F82F83F6F -:1083F00013C6BB1C13187EBC9B2C280F8BAA5A0BD0 -:10840000C10E3EF39ACD0076F49EBFFC02CFC3436B -:108410005B6209C459EDFF5D0C898178C5D72DEBEE -:10842000A0BC8AE20EFC9755AF5BD6821DBEE34A24 -:10843000D58EF7E7C17A76FC95C5D7843699FC705E -:108440003E7E66D7CF5F83F3B4339BFAA07E754C34 -:10845000F01A6260FC2F98FF33C8DF8B0BF2F7E253 -:10846000AA36EAEDE2B9994CCE04175E13174D6FA8 -:1084700052D39CB4C4DC71746E5D8F9B66801F68A0 -:1084800070A31E2E6ABD217EFDF78778FFA3893178 -:108490004CA7D91027E06FB0C3FEFB72F477921798 -:1084A00072FE79F5D5EE76227F278E289A7B53616E -:1084B000F94DE6F581F80D807FFFF0F72AA2998F3C -:1084C000463F99C0FBFFCACCE29993F8FBFDA7EBAE -:1084D0000FE1BEDFADF7D5BB5CE334F9D2C6FD29B1 -:1084E00025603FADDA9F325303AFEA4D0753EEC626 -:1084F000B827093CB8A47ADA2B4F81BFA27A93D867 -:1085000004F38472805B47D35B76A847F5E161E0B2 -:108510000709EBA337B8C669F8F86FA55B95DFAA22 -:10852000B9FEB27364DB788853AF6A149C50ADAA6D -:10853000E9F65B2701BC57B17BAE85122916297F6E -:10854000556FBDFD4743216E66F50827CC877671D0 -:108550001B7CAFDA7C16EF332C8DF8DD0335DD9D07 -:10856000C9F4425A3F60A0F597DE612D07F945FB3B -:108570007D13F20772D6E1FB2AF653ECFC817EFFF5 -:10858000C440F5965363BDEFDD4D9B9E214D1F4DBD -:1085900002BF52A39E1E297D0BA097853608CE757B -:1085A000F87561E12DA072BB1660BC2F2D9F11EDF7 -:1085B000BE75855FDF4F24DE3FE2F3A57F395AFAAF -:1085C00089AC9738D18BF1E4D5F3A93CD4F809AA4A -:1085D0004FF8F07DC9C8718896AE993E41149087D6 -:1085E0005B2CEAFB4782B990C7E90E60797C571192 -:1085F000E894124AD595649C02F0BE854C80743490 -:10860000C815784F7F64531ED4DF2D045F7909FBB2 -:10861000B3A11CEF7004F09DC90C7ECFB44361F987 -:108620002EEEE754CB2B5B2D186773E64B23CAD98C -:10863000054D07318EBEE3358BC140E5C199AD894B -:1086400063211EB3A389BD537CBA2971ACF122FB0F -:1086500076A4DC50F7D3A3F04FBAEFFE29D3F54D43 -:1086600026EC538B58BC6A6A625D7EB4DFBF50DB78 -:108670002519EBF2C18E09DD6B75AE433879B32550 -:10868000F483A739214EA84460FD1AFB158B7D6940 -:108690007D1BAD0BFEE8844322FE5EC371D1F963FE -:1086A000C7007C4F1EF5A0D9056E7C9F922C62718D -:1086B00095B324129028BDCD82FD280FF32897672B -:1086C000AD1230AE6CF632FD7AE09D5CED3E5A4163 -:1086D000FCEC7D0BAD1FB13FC4BBD0FD06DEB53455 -:1086E000B3F88BCAF5FA76552480F3A9DEFCBD29D0 -:1086F0001ABCBE26EABA5C99B02EE11633CEEBFE68 -:10870000E7E2D8798F91B8603F0D3D6743F95E4548 -:10871000DCD8DF5D7C5FF73C58E29A0D7278FE2C66 -:10872000D7EC44B86FCBF63F34F990BF05DC77AA9D -:10873000C691405FF6EE06817DB5AA55080C85BC52 -:108740009978EDC3D877787F00D6ADBD5F534E7C66 -:10875000385EF92AFD77F221C36B35BFC748D66B67 -:10876000CAFB837EC6E051BDD9A4F3EB8CDE2C7826 -:108770006D78DFD5DF9042E7577B8ACA0A0271AA7B -:10878000DF9B74FD433CCF08DCF78985E2EDB96ED1 -:10879000B9EE1F122DCEFF0887E373B797A603BF6C -:1087A0003E0D7A6B0607F448945BDC7F4002663A24 -:1087B0004ECCF0EE3C96172E64F9C9AB5F99DC788D -:1087C0002DB5F364379E0BCD128BDF86FB602FF740 -:1087D00073DFD2978E33CBE0CA92906F5D83D01F48 -:1087E0003A9FC1E185617543EAA2E8812A9E9F17FD -:1087F0009A02702EEBDDC5F42F5B4148D6EEAFD563 -:108800007D993C8A3B10C47B13A1ED02DEB35C2949 -:108810001CC5FB882B6F5408D8F769144F208F575D -:108820000A649140E152D03CE5BEB700CF05314E1D -:10883000F8B98B9AE631628D15D7CFF4B4D8BAB5B2 -:10884000709E933A236718D0395DF78C5BE8F7FB8D -:10885000FA2A385EBA95E13D6DA1371B7E072AEEF4 -:1088600040F17D6F011F0E8DC17BB2A91456B60475 -:108870004C9780FE9546160850EF393BEB3FD920C8 -:10888000CE9802F9612C9FF0B0E05A87C4B71CFB68 -:108890004F359109304FF80E7AA419FC0A58EE674B -:1088A000F82DAACB87FE5207B034C918C8847E0EB3 -:1088B00077E3DB8D76C53CBE8FCDDB3A2615ECBC6D -:1088C000C31DD4E0A672EB709AAA0F05ACF8FB505A -:1088D0000373587D6E17CECB67F70D92B2F4F5BADD -:1088E0006457DC7090A31F303DFEBCD585FEE96B5C -:1088F0008CD1FD592FF5657A8BE78240FC9A7DC0BB -:1089000033F51BD42B3D1724DDF78E7AB32ECEB969 -:10891000BAFC00DEBBAF216D18875DD314AB8BDBD7 -:10892000BD2626FAB82A7D7B2E88C41B755CA3FE63 -:10893000FB8544E24D8C562F45FF9DAE43976FF962 -:10894000B67B1DF09D8C0CDAC11E9CC8F5DA2EBFDB -:10895000C12B5F1DC64BA723A8DB773A1596EFE224 -:10896000E7716AB9DA7FE75423BF57C4DE5506F8CA -:10897000780713F262EB59F44757B7EE1FCF7EDF4B -:108980008BD185164E5E8DFC4869680B18286FFFE9 -:10899000A6EFA9A7728750123BA0F2F1E9A75C9459 -:1089A0006F5344838EAF630BBAF91CC5CB7306912A -:1089B000CB85334F8DBB569B67F5C3ED3B268FA30D -:1089C000BA7D412E6BFF87BE5FBEB77060582ED157 -:1089D000756415DB34797344DE4AF34335794744D3 -:1089E000795244795A443E93D5EFB005B2442721D9 -:1089F000ED7DCF4E9646C13976603ABC28B0ACE1E9 -:108A0000ABC9E368BEA6A00DE3676A5B05271EEB52 -:108A1000ABF1F14EA667599D41FC3DBBD882B6B77C -:108A2000410E54B7080E81D2BBB5692BC6D554434D -:108A30003B45D3AE89D99DD54D47B15DAFFDE71814 -:108A4000909F97E61CC37AEAF9D19DA4FBF73A2ED2 -:108A500080BCAC696A67FB70C4F95167BAEB20CA85 -:108A6000C388FBAF1EE8D71AA67BB5FEEF87B6FE1C -:108A700016BA899D77768144EBFFB1A67D04E84B59 -:108A8000F0C625C8FDE705FF10D89F5F24EE21B092 -:108A90001FDD5B73C57E03AD77440EAE86A71A0655 -:108AA00065596E96A89C3E620BF615A82CC9599381 -:108AB0007833C0F34872105F68F8E99A2456DE37BD -:108AC000D817CE5D73B37EC8F257045743FEB63550 -:108AD00057B2FCD0605F91B6EFEFBDEA6680FF064B -:108AE0004774BEED9BC5E4B93ABFB27C575A16E84D -:108AF0009BD56CBF80EB97662A17A7579EDEB28185 -:108B0000C261FA4F62515E6DE8B8F5A6625CBFB70C -:108B100018E2DCD813EF7C3F43B92CA11E900E7BEA -:108B20005842181FB6AC3605E5FD95755B61DF4F01 -:108B30009D9E8BF2FE7CA6AB3E6B4438FD76004BCF -:108B4000EBB3D87D8F54D180F106A90FD9500F7A9D -:108B50009A9F2751BE41FC5A393E866531F9372C20 -:108B60008BD949197D6FA887F5DCC5F5D3158FFB27 -:108B7000375928FC7F07449284FE6DD477EF5E4B13 -:108B8000E5461CC453B8D2411EDC0DFEDFDC705E2E -:108B9000D5DF57E4D3BC356CA7AD98E24AD7C60100 -:108BA000AD58CBCA5579B3229BB557F79DD406066D -:108BB0009FD4A787AC8375C44A04EF5FCC993A6809 -:108BC000DD02DCBF6FC1F912972B1DECEF1315FD11 -:108BD0000DA057AAF8792CDF3511D723B278751577 -:108BE0004FEAF8F57CDDB344BAFFD3753ED4CF8DA0 -:108BF00070A4FA401E0B2E60FA403D386293C3F019 -:108C0000255270047CFF5F04A7FB60DDFF289CA257 -:108C1000C88B9FC2B835F3A9BC3068E40587DFF381 -:108C200042404E2DD0BC5F42BF831D78675FF7A3E3 -:108C3000599A739CE90FD5A0FEA7CE2BF6DF774E8D -:108C4000B893F4E4B348FDECC8EFCCCBD00F686C1C -:108C500042B978E426E25C00F2839FCBAAFA65E190 -:108C60004FAA0E831D752E4BC4761615AF42F1D652 -:108C7000520AA7C7E9B60AF7D1BD53587C8FBA6F1D -:108C8000AEE0EFEEAE78F02A8CF3EB2241FC5D36DD -:108C9000EF4882F2AFBB7CDA202CA7F8F65A80DFCF -:108CA0002B62F0770756E413BC67B362DA9558BEBF -:108CB00047F52B4D33E3382BA6307A5A51C1E230B9 -:108CC000611F01B8F5460F290DCCBF4124579E36D0 -:108CD0001EE05D8EBFD882E0F68F41AF5C6641BD7D -:108CE00012F64E3C1FF1A5E27814AFDBB390BED96B -:108CF0003C663D9BEE5F8AE33AD13E7FCCE62A415B -:108D000079F548AC02F35F65214BCCC3C01C218BC5 -:108D100050EEF1F910DF0B18E73183EB6B9F959F55 -:108D2000B3813EF02697374030602FCF24AC7CE6ED -:108D3000C3B147C1BE99F9B088F70BC9921B5CFA61 -:108D4000F30E3AD714F08FF3BFC6900DE0E08676AD -:108D500076E8FFBF6CF09E89FB6176BF9778697BF0 -:108D60004D3CF4C7C0BFE06717D9FC497DAC12ED9C -:108D70005DD08FB97CA7F37769C753C789EC97DAC1 -:108D8000779F00BC28DC03700F2CF488C87FAF5598 -:108D90003FDF2463E8490B2D9F5E2FC62FA4F0749C -:108DA000CFB7E17AD5F9CE480D5DC77E1756DFFF04 -:108DB000C9D8DA42F087ABF60879586F8F815FA285 -:108DC0003B2F629C34DA353DBE737B36D20E24E4F1 -:108DD000AF266DBDEE7B1A8A10317F4E578A200177 -:108DE000DEDC3C7EA11BDF11F356E169E8171D9E16 -:108DF00049C6605F905BEEF9268443647B75FF7B18 -:108E0000C142BC6027360A02D263E383B1B89F1126 -:108E100033C3A3A7324601FA7CD118C23826EF6EBD -:108E2000F6FB9F5D96D00E944B03993FA1EB3D71ED -:108E30002DD4EB4C6674DDB94BE6FC44D83B12EF05 -:108E400089EBB05C60FD762E88C5F828B8FF698490 -:108E50007B99DE3FD5837F45B5E38FEF60EF29C077 -:108E6000EFF668ED60B8375B3E2C2C1FF07D18E004 -:108E7000E79658EE277257E07877C71088C3A83571 -:108E80000818D75B5B7925DE2321FC1DE76A3EB518 -:108E90005A03B5078785F9BCD6706C10D853D5E650 -:108EA00065F8BE332D7F13EC30F899DDEEDFF1C8A5 -:108EB000EE49D7B5CBCEFC05EFB537EBF15F1DA67C -:108EC00013BC1F57A9A59BEC303DA0BE0D72621CC0 -:108ED000C17BF9369E8F9DD0E6073F8D87FB2D9293 -:108EE0000FB0776B6D054D04FCA69E534CDF18DD6B -:108EF000BAF620D8BFF113DAC0E2A2F599DF2DF25D -:108F0000FED0A8D6E522D875AA9EA2B12B87DC3266 -:108F1000549BB2FBB660A7C27841F804FC21B1FDB6 -:108F2000ED79BEBFD17D10E5F11CDF60DC07619FEC -:108F30000239A6DAB920D7408EBCDC6FECD47E743F -:108F40009D79CAD85BFBB1739821A8D77B2FEFBC62 -:108F500049AD07F6EEC5FD610C6EA195714C4EC092 -:108F60000F80829FF8D7F25A7CD71B042F9DEFDC2D -:108F7000D5D92877553F4D35F7539572BF4E29F710 -:108F8000EB805F551BF70A7E4B6DBE9AF37D0DFC9F -:108F90009E14BE17600AC7BD823F671C09D8A01C7B -:108FA000FC3A7676BF4EDBDE43FC4512D2F9F7265B -:108FB000DDBB582BD87A6770BCAFB4307FCEE88762 -:108FC000D78ACC49C5D61B37CC95FD6841F87DAE14 -:108FD000CF399E54B818FB8DBD17E01E23B2F7CDD4 -:108FE000438FB2DFBB3E41F7E7ADDCDF718B15EF9E -:108FF00017BB06425C82E4C8BA25CAEFB62EDD6D07 -:10900000C177FA97F563E7C1EAF7B1FDD8FD5DF4E2 -:109010000301DC17C4A29E4DC19C077454D85FDDC8 -:109020002F491EF89F8EF2F8CEDA3BAC6EE82FC8BF -:10903000FDE22BFBB17D6B653FF6DEBF9AEFB6EB31 -:1090400038BDA8E758E08FD1FAAFFDDDF599FF44B0 -:10905000DD5F9FAF8841B914A65B03DE9F8CCD2DE9 -:1090600036821F6937972325DC5EDF0D07B4204F5A -:109070009AB8DF59724C87DF05DA7D2A17E325930A -:109080008C4CBEECBE2B8640FCDEA1D3AF3EF11E65 -:109090002D3F77CA88EFE1CDE6FED6DD0271C178BB -:1090A000DEED26F423561B99BE58BD6F28D3538C92 -:1090B000EE9510D7EDDD26A35FABDAEEDFF40A966E -:1090C000A73B2966E13E28D37377C5B2F631FEFF90 -:1090D000780DECCE7DA94E2FAD3F3FCDBD0FF09A60 -:1090E0006152E2887AAE2A84EF8B1EF333BDF81802 -:1090F000081E18A7D5C67F47CE953E87F673FCF1AC -:10910000545C0F95B7A83F1D7FCA84E766CF778F61 -:10911000CBFC9FC7E4627C2FE6D8F67C27B52C49B0 -:1091200057B13100FE6DCFD34C9F9B6550D6007C6C -:10913000C8BE58A7CE1E7DAA8CBD1F51F9F0E48B86 -:109140009D63837CD7FA773B49280BEDD1F2FE4D26 -:10915000104FDAD93AC4C98EABD2F090A4969F2FA3 -:109160009F90197C437B65A4E7CBED1FE8A2FB77BA -:10917000EE4482BFDFA63D4F8B3C87E8996778F4C9 -:10918000EC4EE57A9BBEFCD64C7708E45BED33DF12 -:109190001E99AFC078219487C4C7FCE92764D774AF -:1091A000A0DBF871015D9C9659617C35CBC4F77BDF -:1091B00012306AF9502D2F1C4BA29EDB9814A60783 -:1091C000D8F8B97364F9FF014BC990C00080000062 -:1091D000000000001F8B080000000000000BC57D90 -:1091E0000B7854D5B5F03E73CEBC92996426992481 -:1091F00093F7C93BE4014308112DEA24040C98D2EB -:1092000009A062B538BC41C943B0BDB1C5662011E3 -:1092100002A2861A1128E0848762D5367801A34617 -:10922000EF8048B1D5FBC7475BB4F7F78B4A2952AB -:109230008188964BEFB5F55F6BED7D92394322D86F -:10924000DBDB3F7CB0D967BFD65E6BEDB5D65E7B0E -:10925000ED1DB36A602C81C1CF4C334B64EC1AC650 -:109260007F324F316FD0C6984555A9FC9A5321D310 -:109270007CC867AE0C991689D40FE909230B59CA2B -:1092800021DD620FEECCC2965E86FD2C9A00FF8532 -:10929000A68B64D66629C3EF6A4FBF8BB193079C38 -:1092A0009EF5F09D7DF995CC2A189BCB443D336B00 -:1092B000B7C431F67C9B14B240BDB99BCD3BADD059 -:1092C0005FC56AAF6C87FCC076C9B313EACD6DABDE -:1092D000CCDF02F93BF7977A64681A83E3603EE8D3 -:1092E0000CCA50FF9AE649ECE3718CCD37074D0A62 -:1092F0007C674F4B6C0FA3FEDBB0FF65D02819E0F5 -:10930000F90A7FAE1F4A176F36C364F9DCBFC27F0C -:109310008261F96CE8B7BB4B66305FB617BE170EBB -:109320007D5FA6840E49318CD57747B4677F330FB4 -:10933000D643405980F0E832B13B7C369A74525D96 -:1093400029637FC0FF263366CAF48D53C76326376F -:1093500069861DE65DC5E735B04F22BCD6B326133E -:10936000C37E3AE319BB3A6C5C0B0B45437A520E51 -:1093700050F922F3464A6BD42C1AEF4ED66F62395D -:10938000D8EF80C907E3D9FB80AE2597CEBF06F999 -:1093900060FCC87C3055F0C1B2532C742D8CB76C76 -:1093A000250BD58FE6A91DD2450A0BC4005E170117 -:1093B0000E62451A55C6F1AA160EE16569509F471F -:1093C0007CAA6178463C869737F67C650ECF279954 -:1093D00018B3C60DD119084570274D6A1ADB047001 -:1093E0005EB3322833985F4ABA77522EC01B5DCEE7 -:1093F000E7DB78DC6251C760DEC7B2A1DE17699592 -:10940000CFE54179A3C2BCDD501E0D78E982EFDBC8 -:10941000AD2C80FD3F9EA752BF6E13E75FA3E263B2 -:10942000636D4897BE9001E992C01CC88F1A3EB781 -:10943000DBA15D19B693A8DD607B0B6B8B0A6B5FBC -:10944000F5A29531582F175EB007CD509529FE4CE7 -:1094500027F497F87B335B0FF9B32FDA97607F67B8 -:109460008D6C7637D477C9ACA99BF8650DE1FF8781 -:1094700048D7F1C84D55A90C795F9A96CADC58BEF9 -:109480009ABED73B81BF86A1EF607956DFCD9CAFF6 -:10949000CCEA4E18EF82B3FF079807785800F2CB5A -:1094A000550E77E3FE49637F04DF1B7D360FC7BE91 -:1094B0007F2CF2AB59BEE7660BF0D71479E5C0BD3F -:1094C000308FFA749BC30C4DAA33FFE3B7B742FE4B -:1094D00093FD4666463AEF99349B655F0A87962E60 -:1094E0000D1A3FEA0F5B2F77EDD5E7EBBBF5F94699 -:1094F000A67CD4AFF101A0608B6A779D8C26D9E160 -:10950000F90AF8DB6C6E3AD505F09A5F327B56C1EA -:10951000E706D5BF03D7538361E028E2D99CF9E978 -:10952000683FE0A52AF3CBA3A988FFFB9807E1BE1B -:1095300060AD9C4BF4D862550361F2AB51F07F678C -:10954000462D95776E35AB122FAF1D0F726B092D1F -:1095500061AA623100FE1B374FFD441A4DE516A487 -:109560004727F029B57B4E0AAE82764B362FAE6583 -:10957000507E86054D1680E70F623D35CABD532CDF -:10958000F0DFCEB89A51285F94BF2A3EA4FF5AEC70 -:10959000EAEA217CBD34B83E2D1D27002F373289E1 -:1095A000C5E2BC9DFE97709EF5967E5325F473FD33 -:1095B0005FBF20B9BCB8F9D59C13E350DE78E71241 -:1095C000BD617E284716DF7B88BE4B332C04DFC984 -:1095D000745BD00CDF5FDD62E679A789F227B74BB9 -:1095E000945FDC2D052D5958FF627C25CAEFED46AE -:1095F00087995D8AA748BCFC71DBEF621880FC4745 -:10960000102DB8BE98A329C667C7B2A69819A58819 -:10961000AF1B3E41F9B578BBEC09A19C7ED9EEC9E0 -:1096200063989F3C6AA10DDB7F1E5F89F8DB31D90F -:1096300021D377D987728829DEBEEBE1BBB2E32A5A -:1096400015D7CB91ED1CEEC54ECB1348E7EBFF2AA7 -:1096500013FF2B06E6DF67433A7847E1BA53B7EDCD -:109660009982F8FD635D8A81EA3F2B3107E2C3D915 -:109670009C88DF174B8A0FD7D992CD4B6B59CC10F2 -:10968000DED7A832E1BD32736562BF8DF8FE66D4C5 -:1096900077F5DB81CF71FC19EFFFF656D710DF4B62 -:1096A00033364FBF06FB7FD248FCA5F5D3B8EDDBC0 -:1096B000823F180B019E160B3C993357E6E3F8974F -:1096C0005B0F8B5737E53B6C975F1783EB7D1BACCC -:1096D0008F62C6FEAA4AEC2BA0034B8B233D33D2EC -:1096E0007AD4F493ADD0C0F5BE8779F7409A64661A -:1096F0005E09E457769642E5D95926C287F297E586 -:109700007BDF04F89F53FDD15990CF64DEB1A86789 -:10971000D40147552CF4664306294738CCC13D2473 -:10972000E7200F78DA94C09E581F066786E80FD6A8 -:10973000AB0BFB39FBDE9747118F0D199F8E46BD92 -:10974000DD78F10B930AF4B4F54A24676D1E1F43CC -:10975000FE68ECAD630B4A86E463A387CBEF4BE472 -:109760004C9691CB33D700F533359BCBB74E275F63 -:109770009F5B9BA38228F7B6BA8256043ABA3CC0D4 -:1097800050BE4F2F973D08B666A7F82C9C5E16EF8B -:10979000AB4C467EF5C81E14F17DDE8FDBE221FF67 -:1097A00066F9648F0C799B77577B36CEDB6314E5C3 -:1097B00039019CF71B132BC95E99EE95695CB624A1 -:1097C0002688AAA2CFFB8E6B018CFB1DE67DE404EC -:1097D000D0B1069437D2B10FC7067A9D71F8272011 -:1097E0005EB4F97CDB33F59113E1768697DB03F009 -:1097F00089EBB1F2E1F1305AADBC0EFBB9FE3A4E45 -:1098000087D3CF9A83AB61FCD356D03361FAE2B4ED -:109810009DEB1D5F9624ECC2EE0C94FB837965945E -:1098200001D7FD3D0E8E0F97A93B03D7DB9F247D0B -:109830003F77B6CB2C08726669BBC48200E2E9A709 -:109840009ECF40F9FBC99EE733E685C117D94E4B41 -:10985000BFAB8DD7F198D702E3CD63DA78A1341C82 -:109860006F9EC7FC21CA0FD63ED9DB1F663F90848E -:109870000CABCF367B497E9F83D5887CA7B53BB7A1 -:1098800024CA8B76E63966094A30D4BC5E3964C690 -:10989000FEBCDE5C17D0BB416B1FD17FA7E01FA9C8 -:1098A000470AD9A17E74C900C9DBA516DFD15428A7 -:1098B0005A8A7484FA53918E12F2ABD784F35624E9 -:1098C0002ECFCF387C7767C1BC1676E8E9989EE545 -:1098D000E0F375B8B83DD86053505F24B6326E07D8 -:1098E0007EDF10447DED8A8A19CDC08E31A5B86D1A -:1098F00028A7AECF8F6A33C4E2F78C20D64F4F290A -:10990000A476812ACEDF8144166C95B0CB2689ECF3 -:1099100040473F53E07BDA04E6580FD9DE2C6E2730 -:10992000BA9967B34C7662B78476A286074DBE2398 -:10993000DFA0DC3B2D59886FA45E89EC3ED9D03D79 -:1099400007FB1D898FB644F0D1967F321FED1A9127 -:109950008FFC2AF191DB323C1F81DCFC46F559C0BB -:10996000A700BE9204BE1E16F265E0FB16A21BFC09 -:109970004838DF5AD15FADC5169247939CF87450B2 -:109980007E433FDBC0FEC47D4A32DACF90A6B6CE1E -:1099900055B9FDDED72F417FD1575948EF3D60E8DB -:1099A000CB423B3FA9A8691FF247D29C92B256B264 -:1099B0004FD29C28F751D6E0FC1B9A27F9B81D001E -:1099C000FD221FD599683FD1706FA58FDB0135B49B -:1099D0003E1A375855D467937AB356217F34AE0474 -:1099E000FB08E56F4FD79645906F9865F3A09D6291 -:1099F000B5CC2CC176AC5DBFCED649DD641707A6C9 -:109A0000320FCAED734143C03806E56CFF8E1FA1CB -:109A10001E5F5AE209A8B8DE045FE632D20B9D4E03 -:109A20006F721CE0F5E0DF64DA17758E853CA42FB9 -:109A3000097A76D679939D909FB7C14A78EFECE288 -:109A4000E5E7EC8020E83F45E6FDB1580BD73397BA -:109A5000CA030BE23D7102D37E36633E45CB773CB1 -:109A600046768CB6DE3BB3383CF6125F165ABEB76C -:109A7000ABE3FAA260BD27CA066D531440BB3B1A84 -:109A8000C7E4792F0EF7A8010049C1EC7F6FAC9EA7 -:109A9000189EE7F587DA3F30A33A8DF4EB60398200 -:109AA0000D7A57CB7BAD00C75AFB50B902F6A4A57F -:109AB0004712ED27CC980CAAF89C24C60F281BBD92 -:109AC000808F87AD4C375E387C4A44FF46E8DFA67E -:109AD0008AFA8152DFE45C80B74C6BBFAAC30BF0FB -:109AE0003D6CD4F7472815ED31A38DF7EBDCD73764 -:109AF0006E481BD2FF600FD8B3C70FD9016BDFAF21 -:109B0000ED180363453B3E37A17ED5F479A34B2284 -:109B10003B2372BD2665F3F50A766D5236C90D6E8C -:109B2000EFD6A2BD2B939D3B059756E34A1F43FBFF -:109B300012EC86D46CB21B3E3D7908BE77CE384D10 -:109B4000767EE34585EC8F46B03FD06EB7F4727BEE -:109B500096F51849EF6A74BF53C89F4E27E87DE415 -:109B6000D397A5F1C8A78C3565DC043468C9F6E63F -:109B7000211CDA7E2C12DEEBB2B95DDE5858B52519 -:109B80001FFBDF2D31D4FBEB0B3F4A44FBA4B1F7A5 -:109B9000C3C48561ED96F63C4A7858BAD738ECFCD8 -:109BA000AFCB9669FE0D2F1CF0E27A3F1D94682D15 -:109BB0002F5182EBD0AE5CB2C480961A2B0FCEBD73 -:109BC00015D73D9B6D627930BF5CD44BB89FD83BB5 -:109BD00033700DEEDBE0AF049FB6FA16D1FADE3A31 -:109BE000DB62635908E7BCBB090F8E282FE2617D59 -:109BF0006155328ED35037C581FE9346B0B3B0BCA9 -:109C0000E1DEEF923F45836B7D8FB106EDAF0AB089 -:109C1000B7FE15E04E8F9B56E381F5982AEF1BBBEC -:109C200002F29B4690BFBFC9E1F46C937C81EFE0E8 -:109C3000BA7F41627BD4A1F2CC1E6ED7DD9CCDED04 -:109C400040EDFBCDD9DCDE9C18E89B84BCF78AD2C2 -:109C50001F8DF66F23F37E86FB4EE6B3A97B884EFD -:109C60005CEEB85A54F22B595CFD0F8CC1F2890A94 -:109C7000ED2798D2FF088E7B769DCBB39E09FEC55B -:109C8000FCBD2541DA3F64FBE7237D2B841D79F67B -:109C9000851BC6CE2B19B293D6755983AB010FEB3A -:109CA000ECEA4F6A50BEFD4521F9C62C037D939026 -:109CB0001EFF1547FDAEB306D721FD031B8D54BE15 -:109CC0002FC5DF807C79AAAE261FF7C1CC16C8AF9E -:109CD000037E32BA3A18DA0BB07D203F83C5E563C4 -:109CE0002AE42705E62A12CAF908FB6312FA796802 -:109CF000DF0083C3F72A21B6F2800B4E5A6809B4FD -:109D00007D153F648F1CFB7296821F353BC560F149 -:109D10002FC5A6D5B3A3988C7CBF66E0A801E61337 -:109D2000EDEA233BB6BE5BA271EA0B9F33A1DFE4F1 -:109D3000AE6EBE2E1BC53E00F09781F6C0DAEC6811 -:109D4000A1C7DB38BFB33EDA47B367383D19837A22 -:109D5000F6F0FDC42AAAA7F5675ACDFD5EF5C21F2D -:109D6000037290CA7F922D897DED6A9176F0548CB2 -:109D7000BB49EAF3CA88D7B192279C6FB4F4292172 -:109D80002F620F0F4CC1F53B00FC857E992D52DDF3 -:109D9000DDAFC1FCB68C2FF2A009E5067692CBF0C0 -:109DA0003BB022E0BDBCE7B329C8376070D37A6D01 -:109DB000E8A994EB6DA4B769FF9814DDD485E54953 -:109DC0007714925E8D1AC7EE9801DF7F2EF09A6CA1 -:109DD000E37E2EF7EA40D6F2121CDF77F76B387E6F -:109DE0006914F929938036F6384ADBD12FE466AB43 -:109DF00024ACF7680CEF3FC120DF5157427297F255 -:109E0000711EC9BB13D29E6C27F76799590DC28981 -:109E1000DF693F069C81FB59F473613F49393C3D42 -:109E20009B1C5250406C65FD3BF6207FF6981D88C8 -:109E3000A7DA9E5F1E477D596B61DD32DA2B117602 -:109E4000C6CAF49987903FCF9D39B9E37EF8F6E80A -:109E50004D073D7EA28BDE7E88DC2FECC42AC92311 -:109E6000DB7BBFCBD6DB7B83F97FB8BDC7EDFAC008 -:109E70009E68754F983C6F14FBB4734BCEC7A09E81 -:109E8000F97890BF404F570CD92BF376477F88EB7A -:109E90006AD0EE8FB01B8E3D111D40FA9FEFB69237 -:109EA0009F4E41BB07E039631FF80122C765F27975 -:109EB00025DC3FEC337A56437F8D779EFEB901D681 -:109EC0009DD205764F2CDAFB6A2CC9D9D765B60727 -:109ED000ED32C5EB40BF8706BFE29CE2F696A05C80 -:109EE000E4F35F660AE5931D64624B281F13CA47BB -:109EF000BBE725A1779645411EBE37BBFD7F41BA22 -:109F0000A598B9BCC276F8BD4BD85B5D801207E25C -:109F1000E538ECBBB384FEC6FDCF83E9C1F5E4C7E9 -:109F2000B1103D3F7EC5BC13FD3C1F171A4226EE03 -:109F300097203F96DAAEB064A8AF1EB70655EEEF95 -:109F4000B21840FFCF7FF8AE37705F31FF15EEC714 -:109F50009A7FE7CAE9B8FFF878C61413CA9B85CC84 -:109F60004F7EE7C58CFBA197B220F757338701C717 -:109F7000BB0BC4C656143501C0FE55F059324868B3 -:109F800057A86D9027A3D9DB5103E3CE6B33D0BE26 -:109F9000647EBBDE9F7E61FDDD35A8C7D7B619B8EC -:109FA000FDD82E911E9FCFBC6EB43B34BC16E4C4CA -:109FB00073FF689BC18BE35C9F6322FE03120569FC -:109FC0007E226D330A3FBC80631533843035483CB4 -:109FD0005DEB506A86D3CF5A7F6DC6260BFAC30657 -:109FE000D20DE407BE60F2CE263F6A5C3E433F627C -:109FF0009BBDA9BD8697D39AB9601DF051F9B50AEA -:10A0000037F8981A87F2323D87DB0F91F35DD8A1BC -:10A01000CF479E4F2C0DEAF3F399BF203907FD4639 -:10A02000FAEFE9395C5E5D589F25CE013C740ED095 -:10A030006654DFCE4279B54E2179B92A8DE3CB90B3 -:10A04000CED36C67F56CE25F27D817042F873FFBF0 -:10A050005A97847AB3CDC9F9F27F0A7724BC37E4E2 -:10A06000E413BC6D68E4C1786DEBA420C71787FBCF -:10A070004AFD174B72F4726830FF8FDF77727E5C97 -:10A08000278BF5E6203934CFC1E7F4B1E479228497 -:10A09000DF6D601F00DCF3D7C96568A74C9A69A320 -:10A0A0007934BC62257F6BFDCAFE0CB267ABFAF354 -:10A0B0009B86C12B42AB68F20BEACD73C13E01D740 -:10A0C0006DBBFE9C0A342D0B3F779A99E6BD2F2776 -:10A0D00001F7231FEFFB25D27B9F95F413FCEF9034 -:10A0E00019E5D70B596437E5A7F9EFCF41BD1E1528 -:10A0F000DAF16416DA29DC4EAAEF3577A11D38AF04 -:10A100002DECDC0BFFD9A03F0763ED71E4DF609D10 -:10A11000FAEF4BB645B4BBE45C8CEBFB4D26FF2855 -:10A12000B4EFAEBFCE9B8C72F5CC520343FACE9700 -:10A130003D8B508E9CB1EAEDEF33764EAFDD8374EC -:10A14000F6E4239D778F48674F3ED279BE81F9C3ED -:10A15000FBA9473A037D97093A9F3970553ED2F9DA -:10A16000D37D57E5239D37193BBCB86E7665FAF76A -:10A17000221E4F4CF691FD04F22AFF9BF0E38B1157 -:10A18000FCF8E2FF1E3F52BB91F4E1D19CE1F5A146 -:10A19000CBA4A6A13C9C67317FAD5EC49F61FD6BE3 -:10A1A0001633F9255EF9F2F3879E403BA457263B10 -:10A1B00044EBEF15C59F837E85578EBB3D0169E457 -:10A1C000FEEF16FB18B78505D0FFA1D9FD9AFD1843 -:10A1D000298FDF17783C9DE3FD36ED1785BF768923 -:10A1E000E8D312FC9CDBA9BB25F2C75AD46E2FDA48 -:10A1F000BD0D2FCF75A0BFF65490FB671B0E8C25AD -:10A20000FFEDD2E0ABA154B40B7B2507EE1F96EE19 -:10A21000FE3006CFBB613FFA494ED87E74B2D88F6C -:10A220009E0A7E1C83E7E230FE54D4CBD1AE0113EC -:10A23000F26F03ECD3A00A6B50068E627F0D2EE600 -:10A2400009A0A8E8D1EFDBB4F3CBAD3E13C9BBAD99 -:10A25000BD5210F76989267F561AEA2796E6A07341 -:10A260002EB15EFE33C79B983B3EFCDCD8FB971CAF -:10A270007EAE4CEDFBB7C4121FF61B9997EC802DF8 -:10A280007621971492537FDEE6A47D0FFD40FD3FBB -:10A2900007B328AFE9EB450A0B2980F745B3BCEFBC -:10A2A00021DD507E8722E477787EF03C9AF571FDBF -:10A2B00002F23C34DCF9B838A7C6F3DDF0F60D6CD9 -:10A2C00080DAE139AFAE5F6D1FC09AC6AA00F75DB4 -:10A2D000B7DB3C68BF34025F37970DF1E1323115CF -:10A2E0008D0F1B849FB771C947B41F68EC911CE8A0 -:10A2F000DF5DE6E17CB80CF649E6D197AE5BD60DA2 -:10A300007C1806F748EB785CAE7E1D0FE6FF49FE31 -:10A31000CCEB72F5EB579BBFE6171F9C67AFC4D71A -:10A3200057C4BC22F79791FE6C6D7F78A572EDA69D -:10A33000087CDCF4BF8C8F91E4DADCDC91E49AFEDB -:10A34000BCE01BCBB5C873835CEE07C773033CD777 -:10A35000FD9F9E1B7CA276241A480F7A75E7A96898 -:10A36000A7E338EDDB65B20FA6C8FC1CBADE6E268B -:10A370003F6DE4796BA33A459C2FF6FDF66AD49FB6 -:10A38000FB8D0CF5FA12DB623ACF6C949F3139D415 -:10A3900061CE19954364BF7FD3F3F775B983E7EFB7 -:10A3A0005978FEFEAAEDF3787F185DAB4AC0D02F36 -:10A3B000A1389661E5F623824FA245FC8445093019 -:10A3C0006758FB91DAFD3497DBCBAF8A381AB7892F -:10A3D000B5637CC6C3F6682FEE4BDC061EE7D3924E -:10A3E000EDDB8E72D2A2723C3FFEC22DCC00F37F19 -:10A3F000DCD84DF224506FF3A05CD4FC305AFF56E9 -:10A40000B15FBD52FE3F30C8779CFF07F3FF247950 -:10A41000F06FDA78DFF49C6C33E046B74E189D8716 -:10A42000BD81E73B5997F2F348FD8CC4D76FE7FA3B -:10A43000DECC25B9E01D4DE7FE572877A2CB073EBD -:10A44000467F0FDB6F5671DF817E0FD2971B92B96B -:10A450001E533C158867B0F72A304EEA03FCEFD54F -:10A4600023DB87A706E513B70F4F8D289FFE3EFB22 -:10A47000F04799BED3C867272ABDF9A83FD7DA01AC -:10A480007EDCF73DC5E36BB659397F6E93385FB21A -:10A49000E678CD7F42F30A3CCBCFC723F98AE5E9C2 -:10A4A000F96A30FF4F96ABB64138FE97E5EA92FF66 -:10A4B0008A413FE8C8FD04886E15557D84B78197B1 -:10A4C00025B633CC3FDDD8C7E3D4D205BCDAF70BD1 -:10A4D000C2DE5D94E7CDC078AF4FDFB358582C98FB -:10A4E00042C8636897F96C743ED0D0CDE3481A56E1 -:10A4F000323A0F6E40FF6709FA05EB18DA7FCFA9F1 -:10A50000FEC2BCF1789E610BC8B1E8379FC1D0EEA6 -:10A510003BFB1ECF37A8FE122C6F5CD9AF3B87A840 -:10A52000F8EAF335E8D70078C94FE042BF4D189DEF -:10A5300066E7F1F84B2DBD29027EF4E313FF77CBDC -:10A5400041B417A3D53E3A1768D8CF8DB80AD94B76 -:10A55000FE7B76571C433E6AD85F39F635AA6F1DDD -:10A560008BF66EC5EF6B1DE8A7F8F45A17C51F648C -:10A57000C8FD4BD1DE3A92ED9F84F8B09707A7A2B1 -:10A58000BD9A09F62ADABF9FEE9B3A16E1D6E4DFC0 -:10A5900026F47F43BF9BEC7AFF36B378B3EE47FFD8 -:10A5A000F7CE24DA3FEE4BF17F1BE7BFC9CAE10DBE -:10A5B0006CB4F2F52AFCDE91EB5F5BF749B281C621 -:10A5C00049BACD42E7D49A5CD864647E4BCE903CC5 -:10A5D0001927E2E9001F3C9EAFB78EC78188BCCD2A -:10A5E000A58F6B3C9D33791CC2332E4FA1760B2D6A -:10A5F0000312FAE1178AF3F91B449C85166775C6A6 -:10A60000E15B80F8602B6B86CEE5B3B1BD83F3BF11 -:10A61000889F89BEC8EDE86C8789F8C6DECEF8B998 -:10A6200012F00DD267E240DFA458984F6E6768229F -:10A63000E2F3958B06C28752F7069DA7C422D9A0E4 -:10A640009F9C0DFDEB0AD09FE278F75AA48BDAE1CC -:10A65000A842D43DA7FAEEC9A375DE5488FBCBAA65 -:10A66000DF1879BCE0CBD1640774662CA378C1B342 -:10A67000EF03BF665DAA0FB434C056537C6076CF3B -:10A680003BE4D7B7EF97868DFB7C38CFC6E36F02EC -:10A690007D1487C626BA081FCACBBF0FA0FDA1AC88 -:10A6A00053C893D166F41AAC48D7558CFCF0799D09 -:10A6B0000E03D22553C49D9C7BE5BF47FB69BFA217 -:10A6C000F9F1833C4EC8D8BF06F75FCAAAFEEB601B -:10A6D00005B3FAFD4E4303FA3D8D030DE437793996 -:10A6E0009AFCA3993D39ABBF05F9CC76079350FE90 -:10A6F000BC785726F27500E69937CC3C9BF38CB4B6 -:10A700005E9497A30DA8B7948D8CE214156762151B -:10A71000C1FD28E4A19FE5826FB4F34900D78DFA0B -:10A7200068519E7F37D23B5AC801D61C45FE44BBB8 -:10A73000C2FD1EF6E6F79F5D05F91DC21F7BF89569 -:10A74000E219E4BF5BA74848870BCEB9990EF8FE23 -:10A750008B3C6E8FD8953EE6B085E3FF30C56566CD -:10A76000BFCCE3D61423E713659DAB0BFD835FA439 -:10A77000F929FEF4DAB6904CE75B8E138FD4A8610A -:10A78000FB9BCD5C8F34ECE5FBEAC8FDCCE5F4C760 -:10A79000B13CBD5D3E98FF27D925EF0C8EFF77EECB -:10A7A00053987E7F17699F44EEE72EB1BF23FA1BB3 -:10A7B000C94ED1E23CAA86C6217E78D5AED94101E8 -:10A7C0005D1C4C958D8FCB2CFAFE9F12F13B5A5C91 -:10A7D0004C62ABBA0AE3CF07EE63E46FD3E276B420 -:10A7E000389D4015DF47040C20F7B2F07CA883E2C7 -:10A7F0007352594892683FD0CFB07D12C6E940FBF2 -:10A80000FEBC6C827F3BF3B4CB24175509E1B762E1 -:10A810007C473CC21DDCB208C7BBC946E35931BE08 -:10A82000239EF611B48E537C3CAE73D2121E0F9A47 -:10A8300002FA17F329B99C2FADB34D14E7A9C56DE2 -:10A8400068F11D1A5EAA04BE530A1665E17E418BAB -:10A8500003D914157CCA2A63FC8790FB4B0D24F79F -:10A86000B5F8BACE3C3588FC7E0EE3406D571EEF3E -:10A8700011895F2DEEE3FA747F72FE788AFB203D2A -:10A88000AAC56B68FC1246C78015C6DFFA32B7DF6F -:10A89000AB969808FE734BA7917FF1DC5203C3750A -:10A8A00054D56BE6FC1731DED6D92616C27E95A0AC -:10A8B00015E5A7C60797B35F81AE85E8BF3DDCB25B -:10A8C00037E704ACF9232DDD949EB34ADDF2184C32 -:10A8D00007E6A0A41AFD64C64CE56A8C6319C8900B -:10A8E0008075CAF6E6CEA27CC2C007989FF6E4AC9B -:10A8F000590AE8897379033B24A8EF2FF87026E5FD -:10A90000912753189BF0C46F660668DEDC1F35493B -:10A91000F8A3CC4EFFB5F909785FA07F4D1FF97DF4 -:10A9200078DC3FC605223DDC3613D9376E118FC95E -:10A93000AA457C269ECC40BE35792C9D67DB98BA13 -:10A94000BF0FCBD3CC5CDF33CECFAD79DC5F4C2AED -:10A950001265679AE65FEA0FA0BC6ACD7252FB41AE -:10A96000B9BADF1CE47E2E3EFE5B074AE91C4A8B27 -:10A970003365CC913EAB94E25174F987ADFC5C94A5 -:10A98000298E74B41F5A8DC24E15F9A834FF77F37F -:10A99000C3ECA4B726FF4B09AE8733077F948B72B5 -:10A9A000EA0613D8F1C3C8A5D4422E97CE196DED8F -:10A9B00012D86D6FA4FAE723BE8E47CF99E284794F -:10A9C000CD8EAF343911DEC05332CAC904416FE7AE -:10A9D0002C0E9FB3DA272D847E5BADB09EA17D82C5 -:10A9E0005FF192BDEE9F25DD0470B74AC27E676AB3 -:10A9F0002CD9ED856A2C9EFB2D6B7E87E2AE6521FE -:10AA000007642107DE6EE9CF55F240E5766F94D1F9 -:10AA1000DE7E479C3FBF93C5EEA81B66FFBB299F08 -:10AA2000DB873364B514F9C875FFC4776A812F6476 -:10AA3000932748F44BB7ABC8EF87EC15EE7EE84799 -:10AA4000CABCAF1CE3965BD3EF2BC7B81339CEE378 -:10AA5000F685E537E5733EAEC67A88B7E8A672D4C8 -:10AA600063FFB0FE62A1BF92BFBFBFC17ECC1CAE70 -:10AA70006596810C05D6A7C7EDDF8A74BB30F74316 -:10AA80003A8FFD41CA5B1F60FCC45BC68E4931280A -:10AA900087B224C1B7DC5E3B5AA0F93D79DCFBD11B -:10AAA00062EEF70439C4E32B4BF93D9BDA598CD69F -:10AAB00073AD88BB98E2E0F796A69467795A616A0D -:10AAC000D3D98082727ACA715F0CD28FCDF297FB94 -:10AAD0004A47B6C398DBA886CB95A96A581EFEDE06 -:10AAE00058A8CF7FDBA3CF7F67C25F0BC2F31BDD0C -:10AAF000DEE771DE2F493C8E33703573D03C5D52FA -:10AB000000EDA5E2E753BA847F97E20D7F26F67346 -:10AB1000CF4F60549EB8D7B213EF1F687E7259941E -:10AB200017BB9925338EF0417A764012718B2E3AFD -:10AB30000B6207EF7670FC415D13F47370AE4AEB65 -:10AB400038D16660D7E15A2FB790FDA4AD8B562B54 -:10AB5000F037E0B122D51285FCDE6AF46CC6BEE4A3 -:10AB600028B38A7AB532C6427DCB3F56482FADB264 -:10AB70009A29F4F5F0835194AF50980FE33500C44F -:10AB80005998BE65F4049B70BE500FE7DBEA64245D -:10AB9000AFE40A13E969E897E87A78A321C868FE68 -:10ABA000950AC5630A98B5750723D1F7C7C4BA9645 -:10ABB0000D2C44722CC54272EC08F48FFD1E7E5D94 -:10ABC000EE223F5BA17A3B969FB714D0FD9CC6C195 -:10ABD0007B478A01812B147694B397DF0FD3D6B3CA -:10ABE000265F22D73348C15C5722E320AAF80F4CD6 -:10ABF0002311F53E237B5E3B3F4CB768E58A17C7C0 -:10AC0000491EACCFEF67258A7C6A4116AD37A81282 -:10AC10003294A1FDF1CBBF20DF6AF261C7DA1F9346 -:10AC20007CB814FF85DFA7FC34BB83E3BF200DD7BE -:10AC3000A11C559086FAAED5E9517D61F94258467E -:10AC4000B3E3103F500FF2336B3ECC55C2FC83A9E7 -:10AC5000052A094BA8E78D07380E5BD5345CAFC3D6 -:10AC60008C5BCFC78DFEC78EEB8671A1DE613B8CFE -:10AC70000BF5765BCD2143CC70E34F5071BCCB8D8F -:10AC80000BE824A44E137806BE08A05FEAB0DD40AE -:10AC9000FC394DC4EF1E4EE0E3B1427D7C4D6E1495 -:10ACA0008C4FFE587D3CCD0DD2B636D4CB8F596338 -:10ACB00076223FFE52F0C9D1E81FE7A25DF5CB39FD -:10ACC000F94750AE4C895DD5864C328D7593BCD119 -:10ACD000E4DE85E40F2B300FF2EF9A02A0FB0FB2F7 -:10ACE000DF9A839D1F713E968BFA0FE4C3B70A1259 -:10ACF0002E855FE3470D6EE4435C07837C1801BF3C -:10AD0000C6476C7A3705206E07BB1453CD4E65AC31 -:10AD100089C789ABE943F303269E6269E2F35815BC -:10AD200020B86F703E42F168D78EF2FB10DED96317 -:10AD30003ECB50B0B27B6E01EEC300DEBAFF9FF097 -:10AD400046DAE5978B97D6E08A5CC7DAF8D28CBDF5 -:10AD5000142FDD38CB46F1D39344DC69E31203C5ED -:10AD600011C1FE8DECFE066609A21CBE46D8D15A62 -:10AD70001CFF8B12F77F060E98D53D61F6F8A57182 -:10AD8000D42AC5690756F278EB417BBB9EDBDB8397 -:10AD90007A4DDC1BE81CCB6579E7DD2AC553BC2462 -:10ADA000F1FA81B98CDBEB75A27CA143C45BC05C7A -:10ADB0001287E2D93BBB18F17FA73D9BCA5364AE13 -:10ADC0007FD8B7B8FEE9CCE2F664E7ADF9540EFBE4 -:10ADD000825188F7F932D8CFFCFC9EEF0FF2F87859 -:10ADE000917EDA4D05DC2E1BB473443ED22FBB2B73 -:10ADF000D3BF05F9656189374302BE9A6FE27E577A -:10AE0000E0BB6D7867A68635ED5672F0FE45D3BB84 -:10AE1000861CE2BBC789EF8A81EF72747C172C18FD -:10AE2000CFE52F0A538DEF06F9AD30325ECEFF1419 -:10AE30008EDBE9ECFE7D03EE2B7ACD44072DEE315F -:10AE4000729D87C173C2C8E171C932C1B36F3878CE -:10AE5000AE84FFC3F92D89713E1F691D24292C6022 -:10AE60002F1B5A071BDDFE10C23FB81ED6F07DE433 -:10AE70002570CB36E28B9B6F9539BF46737D8EE78D -:10AE80004DC9307E9D18FFE675BE6A27D6AB930884 -:10AE90000F75BDF51417C6AAF9B99107FE203CAD90 -:10AEA00042CE69E75BB345FB998E3A23FAE366D558 -:10AEB000EACF9966DBF839D6CDB38C1F85DB3DB37D -:10AEC000D986CF308E71369E4369F5818FDE2F187B -:10AED0003C872AC073A823C2CF720EF81AF9FEB5B8 -:10AEE00084C5DBEE06BE2BF8694919FAE326272E46 -:10AEF000DDBD11F24F6E2DA2FC6B89B7DDF3169606 -:10AF0000EFC8A77CB541223E3D57CFDB1756DC3A50 -:10AF10002D2B06E5BFE817D713EED7A3FC9D755080 -:10AF2000CF3D3ABB0CE34BAB85DFE0DCDD8CCA6F79 -:10AF30001C63E721BB8B55F2FB554789F2EFF17E8D -:10AF4000DF18FBBB328C33AECE1E9883FCFD46D996 -:10AF50004B45983F227D3667B873AFE24229340AE9 -:10AF6000F0521DC7EBD7963D95827E98EA2A9E2F18 -:10AF7000F654AECBC172C3F939C3DDFF8D12FB9E0F -:10AF8000C1FB6C625D3FEFFD90EEAFF92C9207A71D -:10AF9000E89BF021F91D984D72A0EBCCE7CD52D083 -:10AFA000CF3DC9CBE350AB2CAB92517E4DF79BCA42 -:10AFB000319ED861197B04E30C6227548E47BA4E48 -:10AFC000B230A22BF0794C21FAB5AFFA2C230699B6 -:10AFD000CBA6E7738D8FEA34FEAED6F331AC4F5774 -:10AFE000E1F8CBCBDB91F818C6CFC0F6B3BFA5D73D -:10AFF0003783FD45ACB7C8FE479203F8132E178779 -:10B00000E0E8A6759586D17D39B8EE3AB475370675 -:10B01000E13019FAE81E4FA6E429A20BAD133C1645 -:10B02000D24711706BF0A5836C636597C2853F8A28 -:10B03000662F72081C8E441C9797433B2F8B1B82F4 -:10B040000BC6BF1EE9C0D67078B64B4D5C6E88FD4E -:10B0500081E6CF68D0E6DBA39F6F4514BFD7EE46ED -:10B06000BF13B6738D2DFA3AB81B853E9D65F13D31 -:10B07000688639DCE49C4FFC700B683427CCFF6F8A -:10B08000A9FE3AC447AB1478B93F8BFCF114FF0119 -:10B09000F49E51186607687045E2A36104791809A7 -:10B0A00077241E86E8D3978CA9761F6E705E11F305 -:10B0B00069B5F3F53A30DECCDFB550C01485FC9BA2 -:10B0C0005211C5A16870BD2971BF6440E2F78F3489 -:10B0D0007B2212BEC87B7A1A5CE8EFE3700CACC22C -:10B0E0003B820F166A7E3E4EAF24019FC9200D7B26 -:10B0F0001EFE60A141F3B3EAE819797F4DC39B16A8 -:10B10000E715892F2D4EEB9273B78873E591EA49C5 -:10B1100060A7A7C65D8A47EDDC2E6ED04FC9FD4003 -:10B1200003F7DA490EC60DFA298F2968DF4FF21CA2 -:10B1300052D02EAFAD8109000DDE147E1F0DDF0F42 -:10B1400064F8B71492DEEE1F8FFE959F4C7D82CE81 -:10B15000AB3E30703F7D247EF68C809F91F87D243D -:10B16000F8A3D27C4FE2B867A4BE0A2CECCC16E759 -:10B1700042CC9F85EBC1E9C8AA44FF11C8D7AFBE36 -:10B18000C24D2B16015DCB33FDBFC076B730DF64F7 -:10B19000A46F5C8DDFC8CF4918F9E1978BFDE3649C -:10B1A000A177CF6FE3F11ED5DE518F4D44BBF198EF -:10B1B000910569DD7B497FDE25E03F0F2A3684F566 -:10B1C0009FB193FE5DFCFA7C8AE328D86C187A4F15 -:10B1D00003FE8E0A46E9DED328DE1BA7CB9776A7AF -:10B1E000E8EA8FE9C9D6958F0D15E9CAC71D2BD39B -:10B1F000E5C7F75DA3AB7FD5F12A5DFEEAFE69BA2C -:10B20000FADF3A354397BF76E0BBBAFA1F0FFA0F61 -:10B2100084DD10F0F615C2BC1788795F7F719EAE91 -:10B22000FD9F62A61C437E5CB081C7A55702867451 -:10B23000EF8B7470FBA209FE207D27B3018A076C97 -:10B24000084A9E10C3F836BDFDB1B4A78BF078B99B -:10B25000FBF805AEB90634B94F170AFBE32A761599 -:10B260008F67FD7ABAE6B3BCBF8BAE66B79EAE56AB -:10B27000554FD7E8423D5DED1E3D5D6327E8E9EAA5 -:10B28000F4EAE91A5FA3A76B824F4FD7A4D97ABA21 -:10B2900026FBF5744D5DA2A76B7A939EAE99CD7A8D -:10B2A000BA6505EED4958F446F4D9EE6B42FD7D581 -:10B2B0001FA4BB6F09C537E575FC50D7BF46F70023 -:10B2C000FC41BA17301187F93FA47BE1283DBD410D -:10B2D0006F8D1A359EEC8D124C671708BBDE37BC9C -:10B2E000BDA1C99F70FD1EBEAF1D492E5DA2CFC47A -:10B2F0003E77447D16B1CF7D8F81BEA5413690DF6C -:10B30000EA56C19F87A338DE3FC7A2ABA11ED499DE -:10B310000070BD8770C338EF4515933FE2BBACDBCF -:10B3200088FDDFCEFA289DC30628F53307E9EF79BB -:10B33000CC43E902E63309FFC4F45109E8B7E8AFAA -:10B3400040FD7F61EE5B1FD0B9D61BF157F40EC5EF -:10B3500047787E92C7D849210F4EE0390AE4CF5A88 -:10B3600007F5ABEA0AC3DB49E16F9C3749223DCDC3 -:10B37000E4288AEF9A778B44E744F3FE93A78B4641 -:10B38000493C1E24226D6DD6F0C7F7473B47A90400 -:10B39000471AEB16F61CF3DB72A81F7EEEB1CB4406 -:10B3A000FB58B785C3F7ACC4940971741D8EE8EAE5 -:10B3B000B670789E35320BE2F369E65791180F2884 -:10B3C00020A2F83D8C22E48F79FFF95636FAE9A2E3 -:10B3D000A25E98557D359ECB0456919FFC7B4CEF29 -:10B3E00027BFBD49223FF9F7004E48DD0E8F1BED08 -:10B3F0007C2DFFB080B71AEBC1F7247793847EA928 -:10B400007F587FFB7FC8EBFD9DFD0DF6C3385CF8D0 -:10B4100083F4D3FC9E85061E27317037DF1FEDFEB7 -:10B420001EE3FEBBE6406500CF45653094308ECA12 -:10B43000C8EFC7EF1CC5FD9EC9AC8FFC0BECA8661E -:10B44000D7FA49FE9688FB1767C5B9E2A22E0BC34F -:10B45000389D927D87E2F01C7111F0601FEA61C592 -:10B460004FEFBF946C792D8EFBFD8C4EBC57A9E934 -:10B47000FF91F9546127C3EE3100DF350D677FBCC2 -:10B480005AC4E3035A5BFA46E139A006CFFD2DC743 -:10B49000282F2B1E86E797F83E5478FCA3C905E5B4 -:10B4A00061F24EB141FB303964B4F9E89195352D24 -:10B4B0007D74BE6814EF58AD4D5BEEF087D9898777 -:10B4C0004609FBC71260B84FE02A0A53E524CAB503 -:10B4D000FF627C1F6D76433FE1F2F362020B3F1F78 -:10B4E000686F394EF0AE91FC7EECC49CCB4256A006 -:10B4F0008F59C1BBC0F07DCB0DC7308ECB645FEEE2 -:10B5000009A923E3CDEC562E84CBD3B723E4E94F2E -:10B510005A068A719CD6967E0D5F0CCF6B03C9DCF0 -:10B52000BE6E6DF984BE1BC03E447E7B754BC1214F -:10B5300015CA3F80BFF8DE8ED9C5E162175DA457FA -:10B54000E7083E405F5C3AF0CF07CD46E2B315E92D -:10B55000363A2758F166DE212FAC67134C57FE06AA -:10B56000700F8DC3F16412F214F8C987F2C194A26E -:10B57000D079419C6306D1E9EFED4FC3AFC9CAE86A -:10B580009D2453BA8DEC822B85F36FA3F83B408347 -:10B59000F6C94517C9FF15022FDABB4F1FDCC3C818 -:10B5A000DFB3E25EEE375C51CFE81E026B869F8A06 -:10B5B00021BED1F44C02BE50031F3B5A60C5411757 -:10B5C0000FB55898BF00EC108CDBCF19A2638757DA -:10B5D000716288C1C66A571DA60F4D38D181E2EF4E -:10B5E000E1895FF4618A670438BEA38905D13EA66C -:10B5F000B37F18DFB904F2307E8C288FF1F37CAC76 -:10B60000288F9DCDF3E9DEE7A46A042CE23C2BDD14 -:10B6100016373517E5F402C6EF818B7720B60B7D20 -:10B62000916A8BABABC6F2DB19DD0BD1CA7F2ACA9C -:10B63000936D1FB5E7A01E99A56FBF45E021C9F620 -:10B6400051C7243AF7D2976BE74A09B6F3C7A87DEA -:10B6500089BEFC51D1DE6E3BDF3709CB73F5E33F8A -:10B6600028CAA36D5C1E321FE3EF1588F20744B9A8 -:10B6700015CB717C0F2F97B5773944BD75020E8CB1 -:10B68000A923BFEB28EE77DDD1622921BAB45C246F -:10B69000FA3CD4C2287F6B511CC909430DC7779C63 -:10B6A0008BF383A3990DFB4EC1AD42AEC5A8FD5EE1 -:10B6B000EF30724F2B8F73F0771864B789F8C96C2D -:10B6C000137243ACC741B92135793893713FFDE519 -:10B6D000F81A16DA05B48F32E007F93AED1E03F3D3 -:10B6E00087C9CB946551CC1F56DFBD204E974FBC08 -:10B6F0003D4557DF352B5B576E2B2FD295B35971D4 -:10B70000B46E960BFE8A2A29D3956BEF43B0DDA267 -:10B710009E58BFC6DC6B74F5CE17AAB1C8E327A745 -:10B7200082FEA178068F05E5C3727B7612EA9FA799 -:10B730005B2610729E857505462B7BC6C9E3DC9F90 -:10B74000C1F34328FF598B97BEEF817215D25DB0CC -:10B75000EE54A8DFD5E2A0FCE32D6E4AB7B7A8945B -:10B76000FEB4A590CAB7B47828FF18F48FE9A3D027 -:10B770000F7E7FA4A586F21B5B7C947FB86536E5BF -:10B780001F6CF153FA40CB12FABEAEA589F26B5B87 -:10B790009A29BDBF2540696B4B3B6F57C4F5CC332D -:10B7A000E25EED3395FCBE7C241D3B8B841F52C4AE -:10B7B000ADD887E2563A8B306EA5BB9FEC702D6EEC -:10B7C00005E74DFD59F9FC23FB7BAA88DB6F45ACEF -:10B7D0006F55345FCF743E9CD7E3591D0D7C9FDAC3 -:10B7E000C4E990D53340E5C94B382D9E12FCC95CA5 -:10B7F00001965641510254EFACD45715CDCFD529FF -:10B80000CE91B9619E15E2FD2662BBA001E15226F0 -:10B8100070FDA9D17570DE4E0E27CE7F3878F70BFC -:10B8200078E5F26EFE2E4B4D4708D93ECADB44EF59 -:10B83000B25866FB420AA42E9F9FDE8928BA3805BB -:10B840003667206F2E5EC75448D396E9F76D290BF3 -:10B85000CA74FB22F9E2434C0539602BD1EFAFA249 -:10B860007297EBDA59D27EA82B37B956EBCAE7DDCF -:10B8700095B5C68DF84CE5E74BE60DAB5832C0B533 -:10B88000B07323C1F59198C75949A5FBE5817D5A4D -:10B89000BC05DF5F3C29F40BB36C207BACC0C9B3A3 -:10B8A000F9B10103EA874FFF3596E4D2138F1B826B -:10B8B000E84706F164C0F55F0C661F9697B27ECA32 -:10B8C00063A80CE6C73255C6FC383640FB2BD85F60 -:10B8D000BC5F8471ABB2FF712BE4CFA4FB9FE4711A -:10B8E0007321D29FF9829EF9DA7E6AB312E95FEE84 -:10B8F0002F22FF8DFE7E5D9BD85FB459B99F6E9558 -:10B90000B32209EDD6B323C439DADDAF1E5D00F8EA -:10B91000B6271FA274D02FA71A86BD3FFE4504FF8D -:10B920008F026617FCFF05F2FF99F2B713D10DD510 -:10B93000903B40EBE0ACE475CF45FCBE2E737E84BB -:10B940001D17CE4F11F855F655BAE7021E953773FD -:10B950003C013634CE132DC773300E41CBE78B3804 -:10B96000DDBD2DC9B9D561DFD5624EC742D657833B -:10B97000FAAAB0C4E00962C75E87CE8F61CDEDF050 -:10B98000E27B084A19F3A0981BC53A56A3EE56FE6F -:10B9900026539C9572F86AA6C27EC6660B318C4B04 -:10B9A000D3FA65C21F728F909B5F38AA63E99DCB63 -:10B9B0009441F9873A927D61F3F6211F7DD169E4C4 -:10B9C000F33AAC2F2FB471BFE1A242535095F05D12 -:10B9D000B50E7AC751D921B1B42C846312E1811D0F -:10B9E0008C263E8CDE3C9A0560BD943BFD9662F44D -:10B9F000DB85D483861CC19350AFBED8B413EDB39E -:10BA000002C48B0DF1726B6E350E9D5B48F85D289C -:10BA1000E63DBE98D3AB2D3D021EE6F1E27BA78B3F -:10BA20003A353F8E7E9E0F96577D07DF856CED93EE -:10BA3000B95A8BC0E77A63DFE8B9D0F5997E804BBD -:10BA40002638C717A30DBAB98205488FF3F9D53F39 -:10BA50002EB1AD5924976A488F8F37B0F0F3532D2C -:10BA60009D58CCE5EFB1221E876A771F257E1CCA40 -:10BA70001F39BA00F0F1B48115D2B9B181EF8FB599 -:10BA8000781D19FD0078AFA158C845D6C6A6A1DE1D -:10BA9000761A28FE54EE8AA27BB3B253A1B8F736C9 -:10BAA0005BB5E34EECC7A1D039D11479621FDAD16E -:10BAB00066A7611CDAE14776FEB00FE386E4748581 -:10BAC000A1DFABCDA1703B24CD40F1808AB3DA82F7 -:10BAD000E74AF9B6139588CF435D3FA07722E4EF9C -:10BAE0008B981DE117330A92B5B126EA3F90A688DC -:10BAF000F766BCB56313C591888AFBA19A4F70BFE6 -:10BB00007DC471DE8AFB02D5B688FC81F715F37D12 -:10BB1000A211CF0F21FFF8CAF34E945FAF77AD8922 -:10BB2000CB427B3AA8902D52F8D7D6147A0FA1CBEE -:10BB300044EF356878CD0C28BA73C8F4667DDE1CF6 -:10BB4000711E698CB827B75C8C8F2797A1B0F91844 -:10BB5000DD7CFFC65C36DAFFDC572CDEE914F97BAE -:10BB6000447EAF3190E201FC1CEE5A9489F3BAF0A6 -:10BB7000829FE2CE47B2FF2715AB62BC80D540EF73 -:10BB80000287AC1887BEBB8579D0CEB30415BA073F -:10BB9000B047C8B35C1BE7FF3B4AF87A8D4C733B58 -:10BBA000F8BA539E890A4623DD1CDD650158E7C5B6 -:10BBB000AF4E652AE8C15C87D780FEF7DC66930745 -:10BBC000EDCF29BFB0119F9CB7F1382EA5F9011513 -:10BBD000BFB7EEAC2854C3E00EB6383C289F76B60B -:10BBE000583C181B1F1C41BEE6380D143FAF1A7895 -:10BBF0003CE72EB11E7715F3F788760A39B34B0967 -:10BC0000CC403877013D316EFFD0066E1F2F5F6547 -:10BC1000213896BF9E43F6D548787BA2C5EDC9452D -:10BC200078361852D05F55B92E773DBEDFB1DCCEE5 -:10BC3000DF3796638B1EC3AB11ECD74686F67C6B61 -:10BC4000CC359EF961F25D8E9D58887C25CB8114A0 -:10BC5000F4E7F43C7DE1268CE705FA6DC57CA8F895 -:10BC6000839B307E77AF3D9082F1BDC78A3FE2E58E -:10BC70000981AD18DFDB577C9297A707520C903FE4 -:10BC80005E7C9A97E705B662BEBFF82CCFE3D91B5E -:10BC9000C8CE53C5E76F0AA0BFC5E4598202F9E7D1 -:10BCA000007F092CB16E919E1678D1CA9FC3EFB068 -:10BCB00001DB2FD2C8F283A25DCF08E52F8AF2DE26 -:10BCC00011FA7F45B40B8DD0FEB068776484F647D7 -:10BCD00045BB632394FF4A94BF3142FFFF2EDAF540 -:10BCE0008DD0FE6DD1EEDD11DAFF56B43B3E42F948 -:10BCF000FBA2FC3F22FAFF40D4EF17DFB3ED1BDEBF -:10BD000047FF7D36C811944B85F60D71B8CE77B6D6 -:10BD10009713FFB756F0732A8DDFB32546EF0EDF7A -:10BD200056C2DF3BBBAD84CB71A584F339F0E1C3D0 -:10BD3000C877CBDF94299EA8D5E039154439BADEFF -:10BD400040F6C0F2D7F97E7DF93A25187E1F486B80 -:10BD5000AFC1BF06E103C66DC314D6DB97C5FC9C1B -:10BD6000D1EC767B6AC3E499D1A1CF83BC602877FC -:10BD7000417E53DC78E1BAAAF6C2723CEB339005FF -:10BD8000A2D45B42F88E8862177AC151DE5188F0E6 -:10BD9000D9147A3F4193F3CCE6D6F935DA6C0ABD73 -:10BDA0002727DB79F9945F4C74A09DD5C6FC7D5E96 -:10BDB0006CEF56C88E3FD45EE640B967B22F70E094 -:10BDC000FAFDB894E3BDBAA1300AE5B5FCA081E460 -:10BDD000F711075FEF3BDC3CCE0AF40ADDAF0279D6 -:10BDE000ED411D51C042AB506EEE7DE8E05CEEE7E8 -:10BDF00063F6B115747F493B579794B07D406D0948 -:10BE0000C74FA6D0230AEA174877958B7B3701EEF8 -:10BE10008FCA54983B35ECFE706D89CCEF3D69E7D5 -:10BE2000A1722DBDAB95B152D19D23A4DDA3CF9BB3 -:10BE300022F48612A15772DA414EEACE4F1CBAFCA8 -:10BE4000B74A849FC7C33C68C74EF9C5069287E7C7 -:10BE500051BF4923CBBD41F92BE4F12E4400CAD197 -:10BE600000BFDF7E6843D9AF90DECBD719E83DEB4A -:10BE70002B95A30AE218F090E797482FC0845270E0 -:10BE8000DF74393CE4197D71F4DEC765F091F76821 -:10BE9000791CCADB3CBF42FD5FA2372E83AF67250A -:10BEA000CF713FD2D11925EC6A6000F4DBC545752E -:10BEB000E1F9BE49F853B438652549E1EFF58B7BCC -:10BEC000B2B2E0E3FB99578DCBC1F78A9AC8BFBFE6 -:10BED00062DF3D6EB4DBD71AFC0ECC1F8B9B368025 -:10BEE000E32C874D3FE26F2FF641EF72BE7D33FAB0 -:10BEF0004DBA8326ED5DCD10FEB30FE38FB4773BD3 -:10BF0000DD64AF897CD5CDD530DF6EC5518C266818 -:10BF100047C9E44D46B049F799D8607DBCEFF7F4C6 -:10BF20001183E8EFC64DD52097F64531DDBBA5FB63 -:10BF3000D0CF4EF9E99BF09D5218EF4619F6663BBB -:10BF40009F99B5C976F5103CBB9FFDEEA655E8B0AC -:10BF500013FB1427E3EFCD9F51FB6390B4B05F59FF -:10BF60005F82FBF5AE1389E1FB75AD7EACA8DFD037 -:10BF70003BD0F08C4AF53B4A801FEA7B06624A08B8 -:10BF8000DF0315E1F563841F20ACFEA6AFAB5FA80D -:10BF9000C1F3CCDB3797F0FADBB0FE59B53F9162C5 -:10BFA0007A22E089BFB4FF9D04FF08FD1789FA6774 -:10BFB000426F53FDB3AC3FB1348BDA3D85E39C7BDC -:10BFC000E3ED0A31EF443CC779D7E6FD197E6FC136 -:10BFD0003E707FA734A9F8BDDBD2E140FBCD6AEC0F -:10BFE000F0A11CCEC5F7C7260CA5CFA2F2187FE999 -:10BFF000F7487EEEB6B0F85AE4D76603ED6F7AFAEA -:10C000000D0F205FEE489BE8C0FDF33E535F5909DA -:10C01000DAAF076C64BF1A323FB5A2DFDC5CC0D771 -:10C02000BFD5D9E42981BC35BD84DE0F95EF5DDE37 -:10C030004DEF98DFC7DFF7527E6CF2EF46FE0A2D18 -:10C040002F5C18B6BE7797F27B96EB5EB36DC0FDA2 -:10C05000C13AA3A7A300ED70BB42719FCA8F0F4ED8 -:10C0600023FBF0E70646F21FE65905FDB6CD55E87D -:10C07000F7300C94CEEB2B217CF87C55502F2341CC -:10C0800091F07ED0FD8ACF82E71D6661D7EDF0F09A -:10C09000FB61DAB81784FD79A184BFB7B623EDC27E -:10C0A0007B8B5DF8FE8389EE75DA961942A618BC83 -:10C0B000E7B6F3D462A46774FF3ABCE71C95A238D4 -:10C0C000707E3FAD85323A97EBA6EF817A03ED1B88 -:10C0D000E29719BCE87F8CCA35E9FC1D361827DCCD -:10C0E0001F1233DAFF47A4E7B837951B11CFEEBB19 -:10C0F0000DF43EEA83EE772D068033A65CDFDE3159 -:10C1000051DF3EAE5A5FEEAAD59727CED297BB6FCE -:10C110003745F875F4F9268DAF4026D8404F45F1E4 -:10C12000221665BBD082FB9EB5AF4531A2CFCA4D6A -:10C130001D05B83EA307085F514551E417589B6C95 -:10C1400022B9BEB694FBF50FA79B6EA43CCC0BF9AD -:10C150006347DA51DA8F5C8217DBA9BF62FF3616BC -:10C16000F61DFDF2A3BD96521E57C3DC15E8C7634A -:10C17000240F9F95BC9E4388EFB7B8BF624733F743 -:10C18000633F388BC741D20C2A70BDF3FA31960D4C -:10C190007DB82F8BB1B5DF8DF19D91784D14E70DF2 -:10C1A0003BF0762FF29D9FBF1BBD46BB6785DF2B03 -:10C1B000E8D604BD8B366BB478EF4FD809B1EEF8F2 -:10C1C00092B6B0FB1A89C26FF2F0C47956D41FFB45 -:10C1D000C43B2283FDA934280F79457F54A9E6AFDB -:10C1E000E1ED3769E73C229FE0E4F97D47E26EC468 -:10C1F000F5B569565C19EEF7D70AFB2E36CDE41D6E -:10C2000005F37AE49829208D81BCC28E18C12ED8FE -:10C2100017C7C735BD1E15C07B818FB8CBE99E619E -:10C22000AD80FBB94ACF3BB8DE07601DED84FE1F31 -:10C230007179AC65E2DC3400F051A8159828876A62 -:10C24000CB68BFFB88D76345BDF9489AC78A71DAC6 -:10C25000D664C581716B716E85DE897BC4E277A07F -:10C26000FD13078AD484E749E91D53E97E1DE0DA0E -:10C2700050C18F1A98886FC4F8C27881CF1DEE051F -:10C280000E7C97C195BBFF5FD04F1F8FFDC5F07629 -:10C290008827A7C0D3AC5295E07689FEE3173C47C8 -:10C2A000F5F1A7AD22AC3F4147D35416C47D9A3671 -:10C2B000BED6CF60FFCC4BE7006B7EC5F1B62A9DA2 -:10C2C000BF8F65BA8BD17EEEB94AFF5EE4B381E4DD -:10C2D00028927729EE942AE4A394635B67E0BD8BF0 -:10C2E00035BF8AE2E32CE4FC9EA230CB7538EF0424 -:10C2F000BF03F118B95E938F74D421536A74895CBB -:10C30000BFC90A6B97E32E5DC7C96E5755FEE8613A -:10C31000D673C47A493E36F07DEC3F725D6F8FFE76 -:10C32000602CD72361DFE5CBE7DBA4FE7524879380 -:10C33000155A67E911E3E13B7B98979841C5B8E846 -:10C34000DDA54EC1C7A0974A91EF1D936CFCBC9D23 -:10C35000F8ABEAF90DDFFD35E42FE0EFF3815AA9E0 -:10C36000C73AFA482FF6F80BB0FE36C5FF38FAD3B5 -:10C37000B71D4FA2F72BCDD1FCFD5153C47B299A99 -:10C38000BED85DCAFD486AC4BB9BDF34ED4E4B2B63 -:10C390007678B0BFB77F6B49F8C7DB3F6947BA57BC -:10C3A000D9604D3F5372F326BCFF6C7D93973F0DD0 -:10C3B000F980827859467E97C31977D2FC5BDF33C8 -:10C3C000933FAB54F66CC63CFBBD95FC717B0F4CA8 -:10C3D0009C8DEBA4D55EA1A2BD7F40ACE37F156927 -:10C3E000E4BC6493C78FF640E4F7674B35FF9BE7E7 -:10C3F0007817D0B7749789DE711A8C8FE8B2F2780B -:10C400005461872E10F26CC1C1F5198718BEC35153 -:10C41000F75A29B45F60AF4E4478522F4ACC0FF2DE -:10C420006F9B389F4D753D27A19C49731DA9447989 -:10C430009FCEFA56A1DC486FD29F97A55E54A8DD27 -:10C44000BE142FF5873F18076A62624DC7F9D92AD3 -:10C4500094F329FCBCC5E488E271A1EE6ADD3D6A73 -:10C46000ED7DDBB7851C35014E8D6590DA147E6F4E -:10C470003FA2FEEF443D19FDF6E8FC771C3D4EFD62 -:10C48000DA944FC3E34D715F4A426B193FFF043C9E -:10C4900005701FCA62E3F879A9D7AB86C7DFA68209 -:10C4A000DC359761FC4980E24492C5BD082DAE079A -:10C4B00030E044BF9B16F7B193E9ED112DD5F6E7B7 -:10C4C000B9CD32ED3B8A5FB5F2FD413B0B5A25F405 -:10C4D0008731923BB91BF8F9B4E617BB0D1713EA85 -:10C4E000257C0F97C6EBA6386ACDAE02FA92DC59CE -:10C4F00017F1CE94F68EB66134E78B6D2D0EA2A3A4 -:10C50000569EE68FA4A3FE9C53AB977A3195F9E330 -:10C51000C3FB0D527FA9CDFB891F522F6650F9B680 -:10C5200016F532FD678FD07F32F1CBC8FDA751F9E8 -:10C53000F6D0BBCEE9808A9F0EEC77FA54942BA1FB -:10C54000A99E61F09C7A8F5E4E8EE9D1CB5D0D2F56 -:10C55000DB14AFAB0EF0BDED1E83A78B61FCA9BE53 -:10C560005E4DD66F9CFC5D6BAD7EC83513EB2FE343 -:10C57000F5BF754A5FDF577920B23EC177FD457D33 -:10C58000BD48FA44C20B7025DC1406D7248BFEF795 -:10C59000DACD9E7B095C09B784C175835B5FDFBF21 -:10C5A0006A78B86E2C347F2D5C5ABDEF4CB8B27AE5 -:10C5B00091F39859631E01EFBCFE2DB3AFACDFDBE6 -:10C5C000967C7DBD3B9A23C7096871DB3A7B24BE0C -:10C5D00099DBEF0E364071269ADD11C71C22FE8BC7 -:10C5E000DB0DEFE07F93197B60B46FCEE804C4BF2E -:10C5F000F7F64755BC1FC3F515ABE5EF56C2BEA411 -:10C6000034FC5DEE21B85653BF2F61BC13E9598B42 -:10C6100007EDCEE254664946E3CB1DCCC6F7C7EA28 -:10C62000476BF29AC7971709DC3D9BD2BDDC49EBFB -:10C630003C1887F07CD371EF1DEDBD67F4F8A1FACB -:10C6400023F95B343C994CDDF47B1D06EA6D1ED466 -:10C650000FEF6211B4DB75B3398476B516877A3C77 -:10C660007ACED10495DE3D588DFDCFBE65EA1ACC59 -:10C670004B87E3D5E536BC37D5AFDD2F5D83785BDF -:10C6800066F167261AE87CB500F7C3CC172F2E2376 -:10C69000FB4A878BD3D0E0A99638FEA3D2FC0FE3E8 -:10C6A00038D586BE1D3EFCA6F4F17DB62381BFBB06 -:10C6B00084EFEB0CB3FE353C54897E0E193D5F0EC2 -:10C6C000C0FC0E6D8CA57BF80BE26F99836FB22CCA -:10C6D00034F812F1003D0CEEED04B76D6E6632C217 -:10C6E0006D14705B1204DEBDB95F07F760BCCC7DD2 -:10C6F00092F67E3AE59F0F38E9BEBBD9F0F9BB331D -:10C70000510F971A3C68776E03FB02DF77FB3F02FD -:10C71000DFDBF18C258EBED3BB6F6E71EFCBBDC955 -:10C7200040EFBCF8AA5E203AED6AB07970DF3E9720 -:10C73000A9F4EEEA7C710FE60F95FFFD723FCCEF96 -:10C74000A5D1FE83388F3BE20D19EF121CFE627AF1 -:10C75000476BE295C5CF6AE7F033847DB050E07156 -:10C7600026F352DCEE4DCC6FC471DF3E6BF2A25D5E -:10C77000FAB68847BE8505E8FBAD2C48E96D2C4428 -:10C78000F5BF872FCA42FEADE8D1E9CD005FDD637A -:10C790000579B81EC3F0FE06D219F8E50E17E79723 -:10C7A0003F2621DE3B13AE887FEB248EBF0746FB7E -:10C7B0007FC3D7ABEAF2204C8E4969E847195C3F4A -:10C7C000D5099CFF1447DED7AD9FBEF3DA7D7FAF5E -:10C7D0002DB902DFFBE23F3778EFA278718CCB777F -:10C7E000011DFA547ECF11C4863D0074AAA9942974 -:10C7F0006E6FED67E27E363A31A0DE2FC7CAF43E97 -:10C8000099762E395DF4373D8DDF57ACAD9CD91646 -:10C810000B7899F2657F7908D29A34FDFDC5A9AEEF -:10C820002E7AD27C5AAEFEFB8DAC830E886B4BF415 -:10C8300071E6D323FC9F87706CE0AB8BA345BC648F -:10C84000112B0ABF6FF01DD1F67CEDE7A673307E89 -:10C85000C918FF57488FE5DFFEC31CDAD729ECCD96 -:10C860007130BF867F97C99EFCA80566528071D53E -:10C8700016E60583FF24D815983FD5E2A6F434D8F0 -:10C8800001987EDA5248E5675B3C949F35C667198C -:10C8900003FDCE6BFF4C417DB4568BC7167068719B -:10C8A000856B45FCC40AFBF2E318BFB08202DE19B7 -:10C8B0002CF68E2908FE9D3DDD473185EF32EE4393 -:10C8C000566C94C8AFB3F0887F0D9279F11BFDD3FD -:10C8D000514C8CFFCD8944DCA7D7A31D0BACBF22E4 -:10C8E000CE9B340658C0DBFBE1D178A8FFC7960980 -:10C8F00004DF272D5E82EF4F2D3594D68FF1A5539F -:10C900003DF619BDF3F4ED673E54F0F7B34DF64A2A -:10C91000E4BFBFCECB8241C0EB662397EF9B41BE05 -:10C92000E3FAAC2C9DB1FD1E86F2D75F80F3BC29E3 -:10C930006EFEE478F83E7DC25C05EBDDF225E8A0F2 -:10C94000AC213EBC1C5F9F794522FC9C79C549F80F -:10C95000D0F0542FE875E660F177F0DDB3578EC95B -:10C96000147F7AFEA281E03B7F3C8AE25323DB2FD7 -:10C970003F909384F6D89F807E78F0B1FC4031F9E7 -:10C98000E3FFF4ECBFA8E171BF7F8AEBBEF03ECAC3 -:10C99000A9FFCBE514D89B27B7A21C4B4BA1F77B73 -:10C9A00006E3D5585334EAB10693585F206730FF49 -:10C9B000A728BE0FAEF8796A15AE171C0FE3BDCCE1 -:10C9C000E2F760407F1FFC10FA3BB8D54DEFFD7CCD -:10C9D000BAEFB16C1C7F6FF7C2F7B742FF6782FCFA -:10C9E000F7609C61DD675F4479BADB467ECBB512A8 -:10C9F000C085FA744F0AE50B2525AA999C19411E9A -:10CA00008722A90ABE7FB6ECB92D29C85F784F1DD1 -:10CA1000E3EA5FDA184D72EA25A3E78366EC6F3B21 -:10CA2000EFEFC987EEFDA807D307EBCBEE4539370B -:10CA300086C7312EF8C9D2226C0FFA9A7EDFF3D363 -:10CA4000CF4B21F48394761E5A8D714C63B67D686A -:10CA5000488174EC6EA915D3E2F469C7D07F70D712 -:10CA60001895DA8F7B264BC6D8F4A294E0FBD7F357 -:10CA7000B8119D7E2FE9FCAC0AB7999A9E2F92BA05 -:10CA80004F77E1BE38E37819BFDFC5DFAF3ED03B5B -:10CA9000F39DDB18CE032C08847BAE89E22E583040 -:10CAA000D085743EE32FF4D0BB2ABEC016E4AF336A -:10CAB000FE44BA5F78D01088C1DFE314F880FFBE6F -:10CAC000A1E777BF1583F114B1FB8D0C7F2F76FDA5 -:10CAD000D88129141F92AED27E3C7DC70D35889F28 -:10CAE00086FD07BAA89F65160FFA63971CF89CEE9F -:10CAF000BDB0A93C0EF5CC7E9E7FA0DA4BEF9D2FFA -:10CB0000E9FA33CFF7F928EF930359747F623EB700 -:10CB1000771E13FA8CF58F66E1EF2169F47A008AAB -:10CB2000B17C73562019DFBDD2F420E8AF8770FDC9 -:10CB3000A1DB91DA3B66F27BF257A8BF4C421F693A -:10CB4000FD3D66E2EFF4A218C1DF8BB3CDC4F5EE74 -:10CB50001E9037C82F9ADE857177E0BA3589FB328F -:10CB6000A9A064C7C27C521F3373F97D85E347DEF9 -:10CB700067D5EC90D9F1AD746FF5D354FFCF701C2D -:10CB8000EDFE2A533CF4AEE0EF53BD4F8F49E0EF8A -:10CB900075E01C402FFE02F30D32D85139617694B6 -:10CBA000E5CAF4E2DF52BD07709C2BAD1F29872731 -:10CBB0000AF857D80D8487158F9AC91F3651DC4360 -:10CBC0009D78FE7834CA93157F2E23B9D2CAD8B087 -:10CBD000F879B985C779FF1BFA1120BDF68B7E99CC -:10CBE000F623470CCB8E827E2510C87F38D01A5B87 -:10CBF0004E792F92FBBA2F0CC3EE17B514E8F52E21 -:10CC0000C9E92FF5FE87EBBF74D0EFCD64B6B82B22 -:10CC10009AF7D0FB3EFAF96BEF6CC1FCFA51BFAF4B -:10CC2000F8CC40FCBBE2B332929BBD57385FABCB34 -:10CC30007B12E18C9C0FC0FF29D22712FE417E1F80 -:10CC4000B832F8BF2F31FA7D43A0AEC8BFDD2BDE6E -:10CC500031E85D5A42EF691CC4F748506ECEE0F7E8 -:10CC60008E7AC5FDE4DE0407BDF7F19291E703B7C4 -:10CC70008AF6E27DC8DE5B53F87B1DE6A65F97620D -:10CC8000FFAD3C3EAED718A4DF53FBFF00D94A30BE -:10CC900097008000000000001F8B080000000000CB -:10CCA000000BE57D0B78D4D5B5EFFECF2B33C9242F -:10CCB000998490072161F220040D3879F10C3040FD -:10CCC0008268D10610058C71420284BC088FF6C4BC -:10CCD000969AC100A2C51A8E886851070A14156D6C -:10CCE000A888A8C13382505A5F69B51E5B2D4D04D8 -:10CCF0009F3C1282F6620FB7BDFBB7F6DE99F90FC3 -:10CD000089DADED3EFBBE7BBF1D3EDFEEFF75A6B69 -:10CD1000AFB5F65A7BED69FFD12097D7C998D13AC4 -:10CD200037E7743E63EFF90C5E7334632D9AFF5658 -:10CD3000630163DE0B16B63B8DB12D31FEE4E53C9D -:10CD4000BF65D95554FF3DC666B6E5E0BB3B2996A5 -:10CD5000A707FF66BCBDD4CEF3B93CCFD39734361A -:10CD60009FCA67BB9362787E6178D468760DCFEFF7 -:10CD7000F0EDDE1A87EFD9D4CF10236BA47A69A225 -:10CD80009F3F9A45BB3F30FE97C4D8A366E6B5C522 -:10CD90003236DEB568B8AB9031CF8D1126168D4294 -:10CDA0007792C6E7F348D57076AFC6B3AD0F3116AC -:10CDB000CFD87C2BA33F351E2A5AC730364F7C660E -:10CDC0000B16EFB679F87CE655DBBAB4D17C1DD5ED -:10CDD00077453AF978F33C467F5814AF705389BBD6 -:10CDE000335BD4FD7B3AC675D3B8AC6A10CFF0D4B0 -:10CDF000E4AF647CDC977BACEC5E0E97BFE36F4ADC -:10CE000020E510636C30639FDAC4F8F56D531F386A -:10CE1000ADFAE3FF565BEC1BB56894A7FA181F7FC9 -:10CE2000FF104F01FA5F7EE8BA074E5B03F5AA16C2 -:10CE30009764314360DCD07142C76B01DEF878C380 -:10CE40008047DEA485171880BF369B0FF863A69E27 -:10CE50003F2CE5F996F957B9EEE5D99973AC6E8D8B -:10CE6000E3A1F740982F4CC3F77037D6D57238D26C -:10CE700067E0F9DB3501FF168DD177EF7EB36F37B1 -:10CE8000FF5667F13DB187B7AB7B79A48B8FCC0E92 -:10CE90005AF87F50FE6284288F72A7AD2F40790226 -:10CEA000E1F725B3339ACA7F6D64541EEECF8AE151 -:10CEB000F06E4AF4CC71F1790F09E3F8B7A35FF192 -:10CEC000FDA4A4BF93BC5BE0D7DB1849FD3299F702 -:10CED000FC7090EF5E5A8F3B6931F2ABAEA6F578ED -:10CEE000300F3E2FD6A0D17A4F3A7CF764F1F293FF -:10CEF000ED83691E71921E4E96FEE58DB1BCDEC9B2 -:10CF0000434617FAFCA0C9E8B744A15CE0439B6321 -:10CF1000CDDAC6DB9D7A31D215C6CBCBEEAF7D1D07 -:10CF2000DFCBEEAA9F4569CD9A1B19AFDF79D7FBFE -:10CF3000A99E9C2BF15156C75B05E1F14E97BB1E94 -:10CF4000F87DC4E569C47A97E7742E619CAECE5B28 -:10CF50003A1E6346C6DE1DEA5985EFDD2F7CB20717 -:10CF6000DF399EB24A47F16598389D807E3B471372 -:10CF70005D2F97F49B9EEBB903FD713896B30CC6F9 -:10CF800022723A2C98075B33F85BD1C9E7EDBB0FEF -:10CF90006A7C9CDAF0F6064A8DBED1E8E78CE68F13 -:10CFA000D232088E1EECBFB30E7F14F0E131F03C9C -:10CFB000C74FED5EFDBAF067E2F3AAC5FFF076B5A4 -:10CFC0006D46B70DFB87F92C987F2DB304EAA7892E -:10CFD0007D083AE0FDECA4FD6AFFA0FC871C0F353C -:10CFE0004F8CCCBB97E3A736E6D04F26523DDE4EA2 -:10CFF000ED17E39579B59E2BE723D67756EE83B3ED -:10D00000FC8B19F4B32F4CD03F13F471FE892449E3 -:10D010003F826ECF3F31C287F9C4CB7D735EF31A76 -:10D02000C2D1EE47CCB59BCF8BB9DAC6CC1E85D921 -:10D03000B78D9913C9D856C9D76A07B58D01BF52A4 -:10D04000FC8B59DB46CFE6E52CBB6DF49C5101FE11 -:10D05000C74ADBB2E8BBAF2D0BED0F1A5835E0A97C -:10D06000E653F354F20E828755ECD79AA7AE26F812 -:10D07000A8715AC047C08FC12FA2AE5CF7CB2E4D0E -:10D08000ECFFC83109E06B03E13F3B71500E58C91A -:10D09000F90596DBDDBCDF11DB2CBA7E54BD913E79 -:10D0A000FDF75FA17F4E6FC342F039C4D8F34A1831 -:10D0B0009F2FFB198713BB72BC3765BB279FECC33F -:10D0C0009F51E09331A7A21B27C149E0E90F1685C4 -:10D0D000A7D5C99C5FD70226E901781DCCF524436A -:10D0E000AE9C471EF22686E779DA20E1AFF20AEE1F -:10D0F000A1F477D71F962477F2F6FFE532D0BC4231 -:10D10000E1BA96C30FE52D66767B296FFF79F38927 -:10D110008CD3E6C07A3E6E76BBB9A8E9CB2FD99600 -:10D120006BC5BE5BBA3DD7BA2808EE2D7BF34F38EE -:10D13000395ECFEE356124D662F2FD64421CBE1B1F -:10D14000DBBC8CCAAD6E5EFFACFDC89BA8B7647B30 -:10D150004C9ED11968BF745B89BB2A08FE57EFD576 -:10D16000E363549B3E7FCD217DDE9CCB881EFED1A8 -:10D1700076B97E7D3EFF843EFFC93BAB6FC63678F5 -:10D180007E9CD8379FFA227D560ED7EAF7679C809F -:10D190001CFDF4E0F351C057ED9FAA8E2733AC433A -:10D1A0004FA71C8F9A89AFD7BB47237A59E60BDD6F -:10D1B000BF926F5CB1AFD712BEB0B382E92614BF85 -:10D1C0006758DBCD6E4E5F754D6F67408FA99EC56A -:10D1D0000919F2BB6DB385D9AF1C6F20FEC1EC6E8F -:10D1E00027E3F457314E944D689ACE4EF1FED8A6FF -:10D1F000DFCEC07EADF8B146FA46C5B3235E05DD8D -:10D2000074ED5F703DA537CF24385432B705FC70FC -:10D2100069BBE68FE479C738E7A14EDE6EB14F7384 -:10D2200061DE8BD68505F819FFB76A53C83CB60492 -:10D2300095F3F92F3DF4CA571AEFBF7ABBBEDD3222 -:10D240000E2FC88F9A5D7F0F0BFECE152182D784DB -:10D25000F61D46AC7BB19CBF927FCC3B99617D13A0 -:10D260004413761AFFE172C332CC539C5B1890834F -:10D2700013B688F69CF15560DDF5768B13EBAEB7EF -:10D28000327F049FCF89488BDBC1BF5FDC1649FA30 -:10D29000C39230E6B5E651CA6C7968E78A46BB8F1F -:10D2A000DF32929E54CF790FF5F3B8E66B413F46DB -:10D2B0004DE47F26F2CB989FD603BA7107AFD3A770 -:10D2C000CFB3D641A497D499FCAF002E35AC93E0F0 -:10D2D000CD383EDD0A8E1C6E757C9DEFC542FFD2B7 -:10D2E000B75FCEDAA8FEF2437F0F0BFECEF54C6699 -:10D2F000E5F5B787F394E6EF23381A2DCC6DE0F30C -:10D3000034DE19EEF3921E521A0E3A354B7D79CB6C -:10D310003DEE2CCC7BBDE6CE72808F6DB6B9C0C71A -:10D3200016EE1072684B0CD75FE3486FA6F60BA1A0 -:10D330004F414F5920F8DD9698363FF8FE9607D3B7 -:10D34000843EF53723C1A5E73E9B6FA7067D5AE8CB -:10D350003D5B368FA0F6E097A44FDD1729DACF1694 -:10D3600070DD32D8E1F3F2FC1F31C524E8D9EE2C90 -:10D370002BB5E37A5A5A404E297DFA67C33C7701B0 -:10D38000DF6ABD4AFF66D5DF4EDFDC2DE567CF667D -:10D390003E4FDEFF69ADF4B821481F7E2057F0FFF5 -:10D3A00031D3DC7B643D17EA551966DF3B85CFB787 -:10D3B0006AABC1D99216803B73BBB300E7D39B6DB8 -:10D3C00079A0B331D3189D274EE60A7E1E51C0DCEA -:10D3D0003E9E6E97FD6ECF35E8D2C4704E7FBC9FE7 -:10D3E000D3257E33F01B59506A813CE4329CF87996 -:10D3F000E83AF6E60AB9596529FDCDA47EE6D34799 -:10D4000007C5426F39BD42DB29E625F03CE6DF6DFA -:10D41000AE165AB7989F823BA79B4292F7926FC570 -:10D42000F4D189EF091B47ED66A54F03FF9A8E4E95 -:10D43000089E5BEE1B45785C28F1CCEEB3493A615F -:10D44000ECAF282F7152F9379DB7D43A391D5039B6 -:10D45000C7B71FF80E3D6F297C3393AFB0347260AD -:10D460007C2F1A173346E3A04E36316F18870B64B2 -:10D470001EC1E51E93EF2E3E9FA12601FF1493A02F -:10D480002FCE9DBDE17954DF6DE1F98A07963237E1 -:10D49000AF5F91CC5C9AA8CFA2519F7763E42964D7 -:10D4A00006DA55448B7E2B1298EF2EA9F7835F6521 -:10D4B000224DA77EDD8658D13E2A8FDA7B0DA2BD94 -:10D4C000DBC4D3611962BFF4AC0FA3FD5371774A7B -:10D4D00016E860D6343D1DE4E709BA51E9E3794E18 -:10D4E00029675C89D8DF8BD68D24B9D1622BAD7FBB -:10D4F0000EF87A3A82F4C18A0DB7DD5088F93D33CF -:10D50000081A0EFBFCC6FD63406F8BD62DF8DEEFCC -:10D51000711ED96BA3EFED799EF3B9D0B73567F9DA -:10D5200073FCC3A279472D89BCBDA76DF6B91779E5 -:10D530007AA377FF9BD00B6EBCC948F56F646D7FF3 -:10D54000F923F8C23A31CE0DDE0BA644DEDF0D45DD -:10D550001A437997CD91BA82CFBF42E2EFAF721FE3 -:10D56000B4D8D8FC5FDA31AF94AC74FEFD0668AA7B -:10D57000FDE881E3F2A49E3855DB0EBD67D874B197 -:10D58000BF547DF4837E27031EBC9E59C245E539F6 -:10D590005CA97ED5C6B0AE8C28A466FF089E2E2E50 -:10D5A0009866CBE3F566A5B3193837F5DC61643BC3 -:10D5B00069BE3D15B4EF23B39CD8F71EC6FCC4F773 -:10D5C0007C2389EEBBA6F674DDCDF35D3B46B85AED -:10D5D00088AF8BF3FB620723F9DE3555F035C55F65 -:10D5E0004E3A3A23895EE579BE5292C6474DD3B78B -:10D5F0008EE5F52BED962EC883C50FCE8D72F27990 -:10D60000566EE1E7792EC7D826FD799E9FB733F293 -:10D61000065F792E0F3D7F83664047559B34A2C33A -:10D62000612D2E4B12F131CD81F555D9FD99907FA9 -:10D63000552E9B0BE5679BDD0F9CE6FAE1F9E69919 -:10D6400094B2CB1CEE7C9E5701797CDF8FCDF7B86E -:10D6500000A78AD60A3A4F46E478883F2D97743758 -:10D660008B835903BF317526611F76E5CAEFB18EF2 -:10D670002C3BD1B38D010E5D664716E6D5B5DE664F -:10D6800080DC9C7597A06BBECFAC26DEFE1E130B14 -:10D69000C77EFF1BDAF37596AD3595EEE0F9A1561E -:10D6A000668A8C055DE5125DFFBCC063061C3EFD0D -:10D6B000111B07BDA072D3669A8FA20B66EA281EC3 -:10D6C000043D6F775A1ECED78A8E7E5E30EDDABC6F -:10D6D000607AB849233AE0E92B19440F7366113D8B -:10D6E0004CF367AEE4F32A31D63137EC0C89CC1514 -:10D6F000C6E7DFCB7A489FE8E5FA04E499E2278A97 -:10D700006F703A705BE303F8DDD3CCA7C279F2DE29 -:10D71000662BA54F363B9889C3775F7322E59F69D7 -:10D720007652DAD69C4DDF7FD9ECA2FC81E671946B -:10D730003FD8ECA6FCA1E69994BED85C4ADF155F01 -:10D74000E270213EA4F88AE2478A9E145F0AA5A3EC -:10D750007227F606B527BEA7F81DD661C80BF023C1 -:10D7600085DF74ADD49B98063ED6B900FCA2C47880 -:10D77000F6E9E7397C7BABEDAE3027E022F85EAF0F -:10D78000DD4A723ED5C20EE1FCDFB2C2DD75779094 -:10D790005CBDB55A63A620BABDADD1C64C41747B01 -:10D7A0007B538C2E5FD6F4F6B104DEFFDF533C5E74 -:10D7B000E0E5E49D1F3FFA9FFCFBE3777E3E1CF80B -:10D7C000E6F3D8FD10C65D13DE378F58E4D79949CC -:10D7D000CE0C0B17E7A461E1E29C843FE0671113D4 -:10D7E000FBF4F13BFF4AFBBCAB29CC6984FE017C16 -:10D7F00071F87E20F1B5A8298CE058B1FED4D3CFC2 -:10D8000063BFAFB110BF5BB44EEECF8D1CAE417A9B -:10D81000DB87498CF433CDCD581387DF873FB2F8CF -:10D82000B9EC671F6A569FC61B6AFCD054C6BF7B03 -:10D8300036FEEA3DE8DB5AD309D28F3D56BBDF887E -:10D84000F979CD6783FBD39A8E533DD63934E6E31D -:10D8500008DA8A0C708C28705BC02740DBC0DFA21E -:10D86000EC230CFB9BB56A8EE17C5D55F27BD546C3 -:10D870008DF40E05FF27F28CB4AF4EE79A08AFD3B4 -:10D88000B0670713032339A5E896F30DB70FFBA381 -:10D8900035D7B224881F2F92DF2BB30D94AAEFA7A0 -:10D8A000F9B6443FD3B0B978BFF766A75B1613BF8C -:10D8B000735AC00F54FD45D9791BD20BD0CFD43841 -:10D8C00016B42F9FCB33C97939841CB37239C6DBA8 -:10D8D000D50D200F947EF229FE773CCD9FCE5F358B -:10D8E000CF3CF5CC8BB04BBC1F4678AAB946DA3793 -:10D8F000727C63E6925EE3B66B7C9D0D12FFC54FB2 -:10D90000FD29AA93972F3F20ECA73CED42DAB0A661 -:10D910009AEC650D2EBE4FB00F0E993FEC0CA2CBCA -:10D92000579F793FAA93CE17DE644322527F32E39A -:10D9300069C381533318FA633D1B1CF62BDB2DD7CB -:10D940002ED33953ADA3E4F097F134BE76299EEA85 -:10D950001F5E1FDF9F1D6439337DD8B77FC9CEE0BE -:10D96000D6D9D596B34D178C7CBECBD7CCFC0474DE -:10D970001E5AFF93BCC838D00F1BCBC6921DC3C420 -:10D980000CC0F74AAB8043AF6F7834FB1AFBCBF285 -:10D990006DBC1157B57A4DCE68179F6F37ECE7FD18 -:10D9A000D4CFC91772FD1CDF478C9FA5BAF719E9C0 -:10D9B000BCD0BD2F92E8BF61DF03C727F27CC32E26 -:10D9C0000DC3B27AD641706A386064D6607906FBBE -:10D9D000CEA081E759FB546423E869599BE6DECD6C -:10D9E000E7D36B75460F0E9A8F2D5FD0536D58DBC2 -:10D9F0001882AB9CFFDF253F53F596B53F6001BE13 -:10DA000078BDF3A4BFFC228291DD8CF5BC89799EA0 -:10DA1000D99EEF827D6F59DBFE0692FFFB221CC36D -:10DA2000F93A3E97767ED5CFE07CB19F06E70BBDF5 -:10DA3000E38CB4E79E79C6487C08F3C43EFC1C7AAC -:10DA40006ED03C93E53C93F3857E7304FBB130507C -:10DA50007F595B575426AFFFC9A1B7291D2EC7595F -:10DA600066EF180DB9F9C98188993E4A7F3AE325D6 -:10DA70003EDEB9B6A9715AD0BECACB3753BFE7B69E -:10DA80001B67025ECC3748EAF96DB49E33FB9235D2 -:10DA90003ADF02DE5CCF3F73E0D92803ED5BAF686D -:10DAA00027F168B00A3B6D588C53EA99D656E81BAB -:10DAB0000BB97617CDF95DFD810B247F43BFABFA1F -:10DAC000B4DF9270FEEE21BB06FF33807EEB1D02B9 -:10DAD000E725C69C04EC83F26B9CB7DC0A3EF69A01 -:10DAE00059E061A8F3219CABCADF1A44768B956696 -:10DAF0006702F25FBCCE0F827CDEE5F9727F27768B -:10DB000016C2CED99526E47ADD467E50E1EB19C2E5 -:10DB1000F1EEE54BAEF31999273FE0279A9F9F4E10 -:10DB2000EB7BA4DAE0B6909FC59F05BBE7490BF3FA -:10DB300092DFE89736E10F481776FD47A4BFA82E7D -:10DB4000D69F3508F62F89C7BA39BC3C089F753B6C -:10DB5000FD59D05FCE5A849D0FE50EA479A25E8B4D -:10DB6000A41BF4837EBBD21CE749CF7C2E9241DFFD -:10DB7000373C1F29EC0A3FB7ED0C0B929BD592AEB8 -:10DB8000B8CEE4C5FABDBBC5FC302FE8CFCB2CAD79 -:10DB900059D02FD5B8CBA25A69BCB372BC65E1ADE0 -:10DBA000C23F6111F648D4A7F1CD8CFC283D4F84CB -:10DBB000919EFA7952C7418CFFF9132319E47857E3 -:10DBC0009A6FC9212AE7FA1BC747CD93617ECCF72C -:10DBD000B327227D8CD7FFCC2CF4A1CF22E3491FA1 -:10DBE0003A11B9B59CFC32BBC234D8553ED3982506 -:10DBF00011E5BB851FA3A6B989FC0F357CBBB33CDF -:10DC00004A67B258948F247BCB67BFE6FB54A3EFDF -:10DC10001BF1DDC35ACB7F807DB73782EC6E9F3F0F -:10DC2000F95F23FBF35BD4ECD2DB97141DA8F27BE6 -:10DC3000245FBA47C2F1BE7C07E1BF3EA26D6B3ADA -:10DC4000AD53EC578E073A77F1FD110F7BF7C9B64C -:10DC500017E2353BE0ECCFFA29E0BE579C6F3EDF80 -:10DC60006726BF4BCDF3916EB2E3DC3DD600795110 -:10DC700063147A708D81838FA7DA9D7BB3A067B719 -:10DC80003C61CB033C38BCE91CD9B3DB28C711E3AA -:10DC90007EB62745D8F5FD327F7014D9F567C5B239 -:10DCA000DBE7909EB37D34E07A7157840174C1C77D -:10DCB000716B1C3E353FF8A18067F412D2CBF9FEA0 -:10DCC000237E5927F965FDDD13A327623FBD6564F7 -:10DCD000D00B2E9A5C09E087A1F0FA40F295DA8326 -:10DCE0008F5AE0B7ABE3FBC6C3F74DADF48FD53E1B -:10DCF000A9915E57BB61E243C407DF34B3E17C1EE8 -:10DD000067DB1E880AC6C771C9CF02ED5D54BF9696 -:10DD1000D717ED5F8BA2F9EC31BB309F503C7EEB07 -:10DD2000F64F1ABF55FB3EFA68E3727DF495EBBEE1 -:10DD3000C83ABEFF3EF8C93E1BD9AF38DE53A177C3 -:10DD40009C31B72DC1BACF3C6D233E732646ECF70C -:10DD50004F383FF48EC03CBE733FD9377E37974172 -:10DD60001E2CF5E9FB55E3BE26F96FFD205734EC78 -:10DD700064F51C0FE88FE3E5BBD4FE2D33B50F5DD2 -:10DD8000C793685718B43F9F8E207A393344E0E335 -:10DD9000CC332348AE74C5083AE7F34DC579E54C5A -:10DDA0008C481994114E0735F23C7A666A1B9DBF68 -:10DDB000CF68FB29ED328B76354DD26FCCE92E1131 -:10DDC00074039A843FCCBAA903FA04ECD563F22811 -:10DDD000F587C55E6977067D420E651408F9C53082 -:10DDE0005EBCF47F909ED266015FF6483DAE6EDF6A -:10DDF000957E38E0B76E9F467E2483EA87CF3A4E01 -:10DE0000D9CB393DD67A35B70DF359B76219F991A7 -:10DE10001A37DF0A7A57EBA835B199380F7569467A -:10DE20009A4F978DEF1BC02178BC20BD2B32300E4E -:10DE300073C4939E49CA754C819057C8B7F2FEEAE5 -:10DE4000D6699B689C3475AE14EB5370E260B1C028 -:10DE50005EC6CFFBA27C80F5AB7986AE5FCD6778DE -:10DE600081B05374A539EF2F02BEDF30BA704EBFB8 -:10DE700078393F3AF66BF4329CDCFAECC67CFE79DA -:10DE8000A0293EFF2F257FAB855D9ACF336BBBDE8C -:10DE90001F92BD4B9FBF6A9F3E9F73409F1FDDAE89 -:10DEA000CFBB5ED5E787C871159C70EE758E10E705 -:10DEB0005EA438F73AC3C4B917799C7B91E2DC8B36 -:10DEC000EF38F7228F732FF238F7228F732F529C7F -:10DED0007BF1BDB240F0EF3A6977041EE097612F05 -:10DEE000D8949F9DF64BF78278E29FCA4FDABD2CFB -:10DEF00087F27D769DD956B2EB90ED86EB25738740 -:10DF00007A6E282884FFB4634312F066EA247BEE1D -:10DF1000F217853DB72ECF66879DA173FD271BA005 -:10DF20003E650DF5CC41FD6E73CF1EA203939FF8A5 -:10DF300046E75AE75B5304FEC8DEC1ECB1743EA964 -:10DF400080BC8B1D188FA17E15B649EF4709F5AB34 -:10DF500084FA5342E940F9511E37F72481DF9F7A52 -:10DF6000C2BA09F33F25ED646CBE95F42FA557970F -:10DF700018ED04A795F7693B21A75615C452FBDE9F -:10DF8000135CDFEE47DEAAB4F252BED0AB557E93EF -:10DF900066203F8DC74D7268959C53AAD6D37537BE -:10DFA0006824D24072FCA2DD40E7828BEF18498FD3 -:10DFB00018B1CDA05BCF485FB88EBEAEDE1B1BE2B2 -:10DFC0000F1CA2AB7FCDA1F4107FE0557A3FD54D59 -:10DFD0006B5FC1F97AEEA67C5DBDAAD289217094EF -:10DFE000F3967A69CB9A6DA9E03FAB227B69FEABD1 -:10DFF0009EB3D1BD8B2A2E5FDC7CDDD5C870FE5868 -:10E000006D75DF08F855B7996360D7AA94F2873524 -:10E01000E9E571B589791DB101BAAB7630770C6F3E -:10E020007F2EB7758F81E3ED9C61FBD62227FC4BD9 -:10E030003B521D9CAE566B6DF1E3797FA7623C3B72 -:10E040000AF87E4E35FB7F52067EB93F83ADE5F57B -:10E050004E6D7A368AF46E4967A9664738F0BDA3DB -:10E06000D548E702D8A7600F52F4B0A3755078A640 -:10E070003DB0CE00FE2FD3FA385EE8DE48AFFDC8D3 -:10E08000D055D0E3DAC47AABA76A5ED293E57A566C -:10E090004AB9C2D6897E56CBFC69795E50EB3B3BD0 -:10E0A000F295D14EF8359B0FA51AC1C70DFBF6248A -:10E0B00041BF48F0B463FF54EF18FE9F457CDC9AE3 -:10E0C000DF1B19FCC81F6D991E351EFAE7D366D7F2 -:10E0D0002C9EBFBBF567169C0B6A4C3E0BCE9DD5A4 -:10E0E0004FECB0C0FF7FEDDE1DF47DC9DE0A3A6F54 -:10E0F0002F658D748EFCD42CE4B48247F5346DBB4F -:10E1000083CF3BB350F0D7EA70711FA4C458742C6E -:10E110000EEBDDABE562BD3795EEB754F0EFEF4A9D -:10E120003E1CBA3F7A5F9F5B321876A536E1071D29 -:10E13000683FCCF38FA4FD30F7521AA5375DBA9A29 -:10E14000CE55BF67A5A3884FE4849C675F370ABBA1 -:10E1500059BBD807D5167FDC5CEC9397CDB44FEA5A -:10E160004DB07DE39CCCD8049E96161975F4BABCCC -:10E17000384247CFF359ACCEAF7C331BA2CBDF3450 -:10E180002B4357FF969BAE0EA1FFBC4039F191097E -:10E19000BAFB2BF56BBC4E8DEC68D3F4DF79BA86F5 -:10E1A000E8EC7A5DFB7A3627500FE7E05DBF253853 -:10E1B00033D661C179ABDA20EEEBCCF774C9EF9DB1 -:10E1C000F49D2F44B70F8765B8FE53C84533D9E790 -:10E1D000957D7A3EFE3FA33FB9C8112DC78D360A03 -:10E1E000FB8247AF7774D0F993093CD44B7B4F7DCA -:10E1F000B6B0F7D47B3B2C8D7682BF299983A4A13E -:10E2000055237B1EAF6F4D8E15F935F87EC01CB0BF -:10E21000B330D1DF25949F305660BF849637F075B8 -:10E2200043CF6880BD86EC4C333F213B931A47F6C1 -:10E23000AFE874E936BDFDA801769D207C2E2B74D5 -:10E2400012BDD6ECDD7F7C0887CFDCD2985CECA3D6 -:10E25000BAB6D9E68A9C2BE94DF1F98BD506F27B4B -:10E26000F7BE7E94E8ADB7DA4474FD4D7069700B6B -:10E27000BB66281D2EE1EBB2F2F1971CD05C3E4D3F -:10E28000D4037C86803E43E093DC0FDC14BCFAE0D0 -:10E290001752BE14FF5380FB049ACF9FD61F5C42D7 -:10E2A000E0A9C60981171BA787C7128FF32DF09F1E -:10E2B00025278CCCF72DD6BF14EBC43CF83A318F10 -:10E2C000399784DD44F9136EBE64A27C1FDD94721D -:10E2D00078E561DFE9F7691F1D958A7D33EF523CD0 -:10E2E000B5FB57D1D337D1919ABFE2DB817D74174B -:10E2F000C98DE58591711F7356C1FFBF90F882E407 -:10E30000AF03EBA55EC1473D7A3933ECCE7174EFB4 -:10E31000A8D79E4E7A459F1C72E8CB5746A627A0E9 -:10E32000DC23ED768A1F7B643D354E052F770E0288 -:10E330005D0F8D873D76C3BA8CD4CE207DC5B3DE0C -:10E340001C0F7B61EADA419456D81CF19023156BBF -:10E350008DA5908F1FDE93103F0EF6F9F5E6B859A4 -:10E36000BCEB0FEF284865A3902FA1F4D4E6B0F9D9 -:10E37000C1766E956E2B147A68FD9DEF915C3B67BC -:10E38000783D6A3EF6DDFAE7A270F5A676FDDB631E -:10E390001C5C25B93BC6F35021F95177EC71006E36 -:10E3A0008E1DA361A7FE396C688303FA43CDFA92F0 -:10E3B00004D8C5EAFE76F431C87DCF5A733CF4CF59 -:10E3C000CFDEE1725123B9467AC3A73646E7A54F9F -:10E3D0007747F8E0BFFF54636EF87796195F19ED41 -:10E3E000D0C9D9F69B318FBD099E9F1716627CDF7D -:10E3F0009E448CEFF2D2FD4CCFDAE1D1FDD95154DD -:10E40000BA7C9BD0EBF6283BAEB4F7429F471EFA8E -:10E410003C1B21F479E4A1CF23853E8FEFC7A41DD7 -:10E420007F584B4F2ECEA3DE692CBB91E4AE3D1B33 -:10E43000FAFA2A2DDC457AA6E64A807D8CBD1323A4 -:10E44000E46D087E553AA987EB5C41743FE59295EF -:10E4500005DF339BCA6274F9E9D6245DFD12479A41 -:10E46000AEFCDAC491BAF2EB9CB9BAFC77B2C7EB56 -:10E47000EADFE09AAACB7F77DC75BAFAB3DDB37531 -:10E48000F9B93317E8EACF2BADD095DF327F99AEDB -:10E490007C8167852E7F6BF51DBAFAB735AED595B1 -:10E4A000BB99C304B9D78E731687FBCB3867F17459 -:10E4B000D51BC3EDC1782D9A6E68ECCF4E7F5EEA16 -:10E4C0004313C7BA3F037DA418041DF2D40D15E20F -:10E4D000B2942BC9CCAF89736E4712E826B45E683C -:10E4E0007951C4918B4E8EC32507636F35713E52AF -:10E4F00034F6487E06CF3F336681C84F3CF26C3A13 -:10E50000CF1F3CB8F55613E71F45D71CB988F2D189 -:10E5100063CB457E2E2395E3C898BF2DF4F2751486 -:10E520004D49DFE41276927EEF69AA1470C0FD4671 -:10E53000C001A99FD327D2239C3E91BECAE9B3CA8A -:10E54000CCD8714E9F484FF0F326BEFF869F37917F -:10E55000BECECF9B48DFE4E74DA41DFCBC89F47719 -:10E56000CDF3297DA7D943EDDE6DAEA6F4BDE64619 -:10E57000FAFEC7E6264A3F68F6D2F7C431CAAEE0D3 -:10E5800027FB8BF23335C0BF07FBDC21F3D9603F9B -:10E59000ACF2132ABF604B23EB8CC03EED34C57C3C -:10E5A0006C0DF8FB06E6B326F671901EB639D19DC8 -:10E5B0003186C61FEA207F8FFC3E4D9B9B02D7DF32 -:10E5C000ADA33D23C7707CCFCBAB5C1FCDF9C79407 -:10E5D000CB8D66D0CBEFE53DD5D0FE2F4B3A891BD6 -:10E5E000EB1E8D7693ADE21EDE64ABB86737D9D4EF -:10E5F000D9027ED4F22573E21ECD2B9116E24F2D67 -:10E60000F7987CB0536A5F30CA4F8A63946FF9B24F -:10E6100083EEE54D76B81249DEC87C9FFF1C7F4132 -:10E62000F765943F5BDD9329FEA2733AF480497647 -:10E630008B332CC4FF0EBFF52B91EFAAF9308CA7BA -:10E64000FCE4BBBE647EC3E8803F7CB2B5230D769C -:10E650008249ABADAEE0FB3FCAEFAD7DD161843CFA -:10E6600051F77CD4386ABE9126DE5F5EE01ECF642F -:10E67000475B2EEE35B4D4DBA9BF04FEDD9247F52F -:10E68000DC466AD7960B3BF0A43ABB0BF66DE56F00 -:10E690004F90EBE6F5689DC55F78E8BEC12479DF51 -:10E6A00000FD5845B917FD4C8AF32799B0FE468BFB -:10E6B0000BF6D04735DE3E2FE0FF47FD88A0FD8BEF -:10E6C00079A2DFCCBFF0F9426F77BB09BE73D5F9F1 -:10E6D000CD29F3523E33EB34B25F1965FEB7A33D4B -:10E6E000CB81F7D230C79F22689F67A4C0CE315B31 -:10E6F000EAED5F432FABFF7BE8C52DF03D94913DE4 -:10E700002D946E145E149E07A22385F7A0FB5A84F5 -:10E71000E7BEFB57B29F50FA1A88AE143D4DB60AB9 -:10E72000BC03AFB847A3E848FBA26D07ADA3CE4A30 -:10E73000724ED151281D5C4947822E5BBE67A5FEF3 -:10E74000AEA4A300FE018F7F9E8E3A8C90BBFF2863 -:10E75000FDDCDEC36644F3A27BAFF15C86DCA8B8C7 -:10E76000E43C8E7C259B3A0324A5CA1F40F9E02B8C -:10E77000CB43E94BD57F7180FE3C5FF498A383E8DF -:10E78000729294817F18A0FE6BF25EFC6B3675DF8F -:10E79000C36DCFE574305DF2E1552582BE66A619E2 -:10E7A000C99F313D6729E9F7CC2EF46327FF87EC39 -:10E7B0006DD2BF7EBD6C37E372E93A8C33234EAF26 -:10E7C0007F5F2FF5EE9921FEF6EB73AE253DFCFA47 -:10E7D000103DFBBD31528F4E6369E27CBD89F4DF91 -:10E7E00062B91F9325BE339C4656C4E15EC23C26E7 -:10E7F000088157CF5BDCE8EF5AE6A5FC75CC47E90A -:10E8000077989FF4801BB8C040FEBB8CD1FDD1A38C -:10E810001137962DE7FD4DCF9F9E89EF75D69E54FB -:10E820008B01B7033D9F413E34183D7F869E792E74 -:10E83000C53302E7E323C54ED2C38E5833482FC4F5 -:10E840007E3207D92B7FCDE56826977347B99C4563 -:10E850007A8CCBD94C2EEF7EC5E52CF2D767AF650D -:10E860006837C3A9BFDFA3DA7FC7319D99060D2C96 -:10E87000C7BE33FA85A1B063BD1633A218787B2DCD -:10E88000666C31D6FB5A4C8241A461164A473D9FC3 -:10E89000D99FDEAAE83530DE0C1A2F14BE0A9EA1DD -:10E8A0007054F0FD27E039686CE195F0BC0CFD1E5A -:10E8B000F653EBDB5189E9F033CA78BA08C107EBAC -:10E8C0009F1F958075D459055C26354DA47472D36D -:10E8D0007866CA273F9317F0FD0C4B80C139C4CE30 -:10E8E000C64CD328FF3D495BD9099EE198C7D93C66 -:10E8F0007F16D7C8D827DB5BA2703FF3DC334617FF -:10E90000CE357546E72617ECE4AF19455CD0E5A394 -:10E91000A9F06FB25DFDDF97AEB32AF87909AE3F7B -:10E92000BBC64DFB8DC13B1B1FD06B8686897BC64A -:10E93000E45EC81B58CF19132EF8CCD030C11F1578 -:10E94000BE783B2177793F63385F4BBE3F9CCE3525 -:10E9500005C3DC45580F3F2F505C516F7604D92B0F -:10E960007E23E31227FBAFA6B8BC9938B7F3EFC6F6 -:10E97000F0A89DD8F7BF917189BF18E4B916EDAF23 -:10E980004DCB4B043CA630E157B9CE6A76F9F99CE1 -:10E99000AE1B2BF7E168365AC6F5E8CE1FCA4ED239 -:10E9A0001B6724393499653D043B41F10933D9098A -:10E9B000FAEEBB250ABF68EF898B46F09592488D29 -:10E9C0000D4A0BC4E784251A9833486FB739C399A9 -:10E9D00033687F4464C7EAF291AE21BAFAD1E3D238 -:10E9E00075E531EEAB74E58366E6E9F2834B27E823 -:10E9F000EA27CC9FA6CB2779AED7D54FAE9EA3CB27 -:10EA00002BBE972C3EB194C685BAF6C39A16E9EA96 -:10EA1000A7796B74E50A0FCCEBEEC88E075F147F05 -:10EA2000191B57EAEAFD344AC49BCCB42F9985FDE3 -:10EA30003EBCF507FA79195FD7287ED429F8AD973F -:10EA4000FF033A2A49D4F3DFE90EBD5D23B9D1A40F -:10EA5000CB6FF847F1ECB94A87E7507870BCBBFC44 -:10EA6000A8CFE5B797E74B7E5D69827E01FF45F051 -:10EA7000FCE1BF085E2FFC17C179F82F82EBC37F42 -:10EA8000115C0EFF457079FE093D9E0B3BF4781E2C -:10EA9000FB9E1ECF8AFE06C2C7F84E3D1D84E26370 -:10EAA000E2A7217421F1309FFFD31F1EE828C2E99D -:10EAB0007F7A2323FBDC37E1E58510BC4C1AE9693A -:10EAC000C77E9D3FE862AA0578EAF18CC079F233EF -:10EAD000692709BDC7E9E5EA00C521FCC048F1374F -:10EAE000270DAD1AF8B23FC5736C2CAF7F7B4E2358 -:10EAF000D14F222BDDBF84CFA7FC3FC2C88F533E2E -:10EB00004CC4EBB29C4E8A7350FCAE3C59DC237A69 -:10EB100063AC3CBFB9C47DA28EB1429F8D7439E80D -:10EB2000DE71458E88E3E0C7AED4F251A09FD76D69 -:10EB300023400F5B84DFA413F1C271817861E89BED -:10EB4000D0EF52A47ED5F207AB15EB18B18DE9E4F6 -:10EB5000E4489F5577EFF5EABD0E5D7E545BA2AEAB -:10EB6000FE35879CBAF25C7FB6AE3CFF844B972F94 -:10EB7000EC18A7AB3FF63DB72E3FBE73A6AEFEC462 -:10EB80004F4B75F964D6F330E03B4C13E77D2BE730 -:10EB90004B740FCC29E281CAEF8E1171A0D20EA066 -:10EBA000F469751FDA23E92E544F1F66117A6A4BF8 -:10EBB0001213E730AB3C6F31BDBEEE91F799959ED5 -:10EBC000CABCFAFBCCEA1E739F5E2FF576A51F0721 -:10EBD000DD637607DF632E97F1DBA1F22F6E9CB029 -:10EBE000EF85CE7F9845ACB7E50E0BC58DA879852E -:10EBF000CE67799EA0DBDDD6FEE377D2C769D47FEE -:10EC0000516EE99071BCDE6366978FEC28578CE7F4 -:10EC1000EAF4E25CF9238BEB2EE7378F577E8D58B1 -:10EC20004F99C170FBEC1CBA2F36FF9741E3E78D7B -:10EC300013F41D3F41EB777DE5D1E23E178BB638EB -:10EC400041BF038F27E0996861EB28CE48DEFBBF08 -:10EC50006D53DB7D23785199A5D54CC60BE63383E4 -:10EC60001E664DE3FA542EEC822F3E62E7FAC6632D -:10EC70004D26B2F38C1F37AC8C6B627D711CC3F8D0 -:10EC80007903F4019D05E79427C71B699C85E3C4BC -:10EC9000FA4A8C97FBEEDF93FF8231C9BF19DD87FB -:10ECA000E987DE880ED53AFE55F7F115DD86C249B3 -:10ECB0009D2F99943B99725E0A7E6A3F28F8A97845 -:10ECC00008E70A73E94E3BC555CCC43D3285BF9772 -:10ECD000C70B7EB409F02814F5C08F06AA5762CC82 -:10ECE00089863DBC9739A31D5F63EFFD17C62910C8 -:10ECF000FC078AAF1A883F5CC1170688B71A883E9E -:10ED0000E9EF1F88BB0AE20FE25E8FC4872FD34072 -:10ED10007EF4BB23F5FBF8857102BE1EB98FB97C6A -:10ED2000B5E7EAF90483FDBE65BD51F2092157A19B -:10ED30006FE0FBE2F566D237182BDD8A38A28FB67A -:10ED400098E97EEB64B773864BF8E749EF20BF176D -:10ED50009F5A85572F4FB97CDF093D780A736D8024 -:10ED60003FA372A3BE7CA97DC66790E78B43CEA567 -:10ED70004BE5797569C8B9F4A971521EBB988BF43B -:10ED800024E9E7AF9675FAE8C897112DED2EB43F48 -:10ED9000794AF7C2145C9CF0D7E407F21C7EE1D9F3 -:10EDA00090D3EB4CFDDED7EB83DF00F711CEE23ED4 -:10EDB0008213FBBD97E2AD7A0FD8849F52F983642A -:10EDC000FDB3DE8B548EFAE8ED5C6EC768E8217DFA -:10EDD000FEA3103F54AFDD10350EFDED33537FEA37 -:10EDE000BE45CD5F7DA31D41FE644FA75177BFE5B2 -:10EDF0008AF9AF7D8EEE5FDC1DE379077CFC8CC960 -:10EE00006505FEEEB11F89479CFC2C69B7099D6F13 -:10EE10009FDE59A4093FAC57C4CDF6CED4E81E00FE -:10EE2000E7830CFB46DD1B98CDFC7148953FC6B3CC -:10EE3000713CC159F9632AFCE3699EF35A969AC35F -:10EE40007995CE87D794843B037E9ACE1471EF6771 -:10EE5000207FCDDC4BB9D4DF4D9726523F17C7A595 -:10EE600009BD6BDD7D2B404757ED6566ACB333E4E0 -:10EE7000DEBB4A2B25BFF18E577C5ADE275AAB11D9 -:10EE80009DAFD498BA5F447C5AE52FB6CA7C89C836 -:10EE9000AF5A2FF29D66F1CECC1E696FC03A9162D7 -:10EEA0003D3817EF93F608AC0329D681EFE04BC845 -:10EEB000832F210FBE843CF81252F0257C5FC44A98 -:10EEC00053738DC2AF541CB46FE0572A0ED27BE04F -:10EED000570ACEC3AF145C1F7EA5E072F89582CBB3 -:10EEE000E1570ACEC3AF145C1F7EA5E03C1B775DE3 -:10EEF000200F3EE69EADCBCFE5FA7771D0BE855FA1 -:10EF000029B87FF89574FD7956E8DADFCA9A74ED6E -:10EF1000E1570AAE7F7B93A6F33BDD2EDF03A8DC2F -:10EF20003688E8E3A5D1A5AEF17CBFFE39E26FDFFC -:10EF300033E31C606C5F06BA5D591FEE12786E9D5C -:10EF400029F06E6002CF3D0B08CF6B2C225F22EEC2 -:10EF50001FF7E7BF29360BFF0D52F86F90C27F8372 -:10EF600014FE9BE2E1C27F8314FE1B7C87FF06290F -:10EF7000FC3748E1BF410AFF0D52F86F90C27F8312 -:10EF800076F0DF2085FF06DFE1BF410AFF0DBE9F5F -:10EF9000841F29E8DD0CE8E999BA731DA743DDB9A0 -:10EFA000CEA1CB434F0FAE0F3D3DB81C7A7A7039DE -:10EFB000F4F4E03CF4F4E0FAD0D383F3ABC739893E -:10EFC0005F425F0F6E077D3D383FAAD57B0CB6A32D -:10EFD0001BB69F7F156967A4F698C659C18A170E9C -:10EFE00094C1CFD669D3526338A7346B2F9615F3EB -:10EFF000BC47DEE31BCD7A0CC037F9D939DE3C7E45 -:10F0000046F78E477D9544E5CAAF4B7F1CEFB907A5 -:10F0100018E9FDC764BCA76AEF620E2352553F9002 -:10F02000EFBF5EE8F8AA1EF1CBA079F083612EEE67 -:10F0300099E4AEB1E7E1BEFC1E8326EE9BDE25EE31 -:10F04000FB86D2D56EC997F618F61F09C7FDA10A2F -:10F05000CD8538862C133B61CE039C1AF3A01FDCB0 -:10F06000373E46AEAB7102EE1FA9792B3B20E7136A -:10F0700014BF56D4C32C557C9C495F30CB62F077CB -:10F080008BD00BD00EE7C5ABBD9A7B67107D3F34AC -:10F090005EC8378F77C5842AFEFDEA7D8D13101771 -:10F0A000372B5CB4FBF9E35104C71BD7693B117FD5 -:10F0B00058B48FB911EFEA93F3BE7A9FC35245E378 -:10F0C0003A289E4EF55BB13D95E2FF2A586731E242 -:10F0D0002B5881C6E01F5570E3EB7B15EBCBE25B51 -:10F0E000C54CFAA788CB099771392A1E272CA6B4DC -:10F0F0000A724BC5E54C2A8829C1BD38D6CE5C08BA -:10F1000003BEA1A062FD60DEBFC7E776E15ED1A4C9 -:10F110002F1A8F517E5729E5890CC6D03824D7463F -:10F1200078357A5FE346EF0E439C13F1BA6BCDF16D -:10F13000A8BF8FB9A0EE70514371A76A7E39ACC3E6 -:10F1400060D38077767450101D710E7013F09EEBB3 -:10F1500032D3FB1BB34D0E33F846A81CBFF2DE6260 -:10F16000889E1072BFA465CD7BA9C674DC2F31B810 -:10F17000FCE05BCF4590BEA0F49D0A79DFECE2BADB -:10F1800063836FE1E515FB857EE0D9A611FF53F798 -:10F190004DEA337CA906E80B43768C8E350AF90FCD -:10F1A000BE78C6FBECCDD8A215EB8F515C44C5FAF6 -:10F1B000C268111725FC1055124E55F25E11CB7125 -:10F1C000C443CFFC90F31DF708BA97184D7185AD75 -:10F1D000429F53F616A50FAAF7632ADEC83F0EBC5E -:10F1E000573C2ADF65D95841F157A1F77C6AA5BE83 -:10F1F000B76C9D99EE0F2D0BD1076BE57DA1DA1051 -:10F200007DF0DCF8107D509E5FD47DDE8A378ECE97 -:10F21000237DA5D14C7EB9B2B5427F61FB990FF138 -:10F220000C656BA71BF06E48D9736E97D60F9DBC0B -:10F2300025F598599D3682EB9C4BC994DE7C298933 -:10F24000D25B2E897B94887D011D74BEC0488F7E61 -:10F250005BEA2DF370AF12F188DE30797F9291DE98 -:10F2600094CB1C25E01F57B9B5A350FB66993DEB25 -:10F27000716F73D60E46F1473740BF41FC17F41D3E -:10F28000D8DD0BD24A280E63A646F12C3714AC9079 -:10F29000F4CDE99D81DEBD927E4B29DF2717249DA9 -:10F2A0007BBC5D26C0FD06AF66C13B7C1E798E55DA -:10F2B000741C4AEFE511D2FE6417F6A53EFB132637 -:10F2C0008B476DBCD1B7E17E6B396C764398403C7F -:10F2D0008779648E281FF162F46DEB70A8F9BFB4D2 -:10F2E0004B94190C22DE89EB5BE0ABB7ADCEB52CAD -:10F2F0000AE22F5F4C9C3663626100EF8B42E2F4BE -:10F3000056DE333CE1EBE2452B399CB14FCAA33BBF -:10F31000BFC729945D3B81B98BF999750163EAF107 -:10F320001E3FEE052E94F9D52F8EFBD3463BC187A9 -:10F33000F2D327A4DEE625BE2AF8D6ADE05B46F080 -:10F340002BCFD409C4AF3A67001F11393DF21D021B -:10F35000299742EC10AB2738C57A43EC11953982D6 -:10F360009F339333F5568A0B76923D4FCDFF43B3CF -:10F370003E4EB3CF2F3241CA93E67F4D7CC3FFCAC6 -:10F38000F0DC86F56D3588B8F921C65626ED42B415 -:10F39000FF15FF60F21D8900FEB99E467E74CD11F7 -:10F3A0008C7FCF464DC4A90F60BF61D93D0FEF865A -:10F3B000FDAED9C210E7FA7896A0A3C77F60213DC1 -:10F3C000BCCCD2710CEF642938BEDFF4EF66B2CB4F -:10F3D00033FF70BCFFB5B0D1E6027FFE6262E92A5E -:10F3E000CC3B22C745F898C1B719FA3F9952FA7D2C -:10F3F000C2D7A6571E43DCFEF2F6348A23AD3894FA -:10F40000BB01EF897C31D1F3C309F0E3DA1D16C8E3 -:10F41000F186753124D7CA13645C27EB213F9582AE -:10F42000FF031384FDEABA2241C7DDF23C028639AC -:10F430005B574FDEE30ED927CA2E186A5F087DC7D7 -:10F4400061A0FDA3EC08B01B5882EC8ACA2E61CEE5 -:10F45000FE7001E46899451F7FA8D25795DD4D9E47 -:10F460000717F7C9B19C1909D09B376B0EC8B12A91 -:10F47000BBF396F13C5F75C28C1B986C56AC53BCC9 -:10F48000DF718F78BF6311DFAFE03765F23E56D58D -:10F49000B6F1B4DFAA7C3CCD1F785FDEBAF968CA4A -:10F4A0000BA01FBF9BE2F2AB1C6E4B6CD0BEAF6CCF -:10F4B000D57471FD2A7F6082B0C39571351DF0BB94 -:10F4C0006D759A056FE89471F502F7FB5E9DE0D4C7 -:10F4D000C555F37A74AF61563A3B2EDE4FE2F34ED8 -:10F4E00013E3E505F5BFA855FF3E01AF4F7AD1CB39 -:10F4F0001322097F150EBEEE34A40E9A278703C18E -:10F50000A9E73EDE9F93C6217C54FA7D669CBBCB67 -:10F51000709F82E7173A7C668CB3689D782FC4B3DE -:10F52000498CE3D918631905BDC9E4B0A4007E383D -:10F530002CC7D1FC880F5671B820DE4AC55D86C243 -:10F54000A742CEB7AA3546AF8FB56E36031F0B065E -:10F5500078AFA047D2EDA2755329DEBCCAE4A678E5 -:10F56000068F84EF472B6CF7C22FB060CB43E63495 -:10F570009CB32708FB738FDC77B3D2FDC3E95DA092 -:10F58000153617E6B9C0D14AEBEB83EF831C1E1A80 -:10F59000DE9F2925F872BAF0E27E5ED5163D3E0365 -:10F5A000F311F0ADDA5241FB6D89C9637104CF6389 -:10F5B000DB2BC3710F6501DFDF78EF88393C14DF87 -:10F5C000F4F183B7A4D23AF93CE91E94CB3903EFA6 -:10F5D000FC703A213A56F4A2E2B2D578D689222EAE -:10F5E000D33AF19BF6A59BF49A168E5FD8BB07DA47 -:10F5F00097160476F1712D55E2FDB5D07DAAF6A7D8 -:10F60000DA976A9FAAFDFB98B9D49FA805F80C97D2 -:10F61000B78DBFEC074E33E47C174ABC72B8BE1AF4 -:10F620001CC775CD4481D7B274FD7E477FE837652E -:10F63000A2D8EF65D3FCC31177A9EAAB71CB6245C1 -:10F640003BD03DE82D65A2A1AFFE4AAAAF8F47A9E6 -:10F65000ECE317FBD6C7835FECD748EF5D79DFD1CA -:10F66000947F833EFBB4D067CFD4ED6E4882DE68D2 -:10F67000F2A506BF8B55E517FC6131D77FC02F96E9 -:10F680004839DD9EE7C99918B47FAB1E783ACB2381 -:10F69000F88B1FFCE583A75FFAFD0467407EAAF99B -:10F6A0002FDAF85B73853D185E627DF766F7529C32 -:10F6B0005DA5DDE2C4FDE5CA7515C46F59223F574B -:10F6C00068017C87D241C53A8DDE17AB6C1AE333F3 -:10F6D000FE37F2E5CA4DB3E94D248527F5DE899260 -:10F6E000A76AFEDF95F35F28E978CE44B1FF16568E -:10F6F000A75996D0BE4FB35482FE65F9822AFDF712 -:10F700003E3CF5F9977336607F206E88CE279BCC00 -:10F71000C2CEB72F92F4D5332B9F7FF3665EEFF303 -:10F72000AD3B52A19FA8792C95F6BCC5D22EB7440B -:10F73000EAAD1C4F15C1785AFAB8C053E5336FFCD7 -:10F7400009EF7295A54B7E769F88E75FD4B69FF050 -:10F75000B660E366731AAFB762629AEE9E4C652399 -:10F760003FE872782EDCB8C30C3EB062A2805B2802 -:10F77000BD97C9FBBE0AAE903B5A90DF42D507FF4A -:10F78000DBCFC759BDC21605FBB41AE71149D7959F -:10F790008D31B118AFB2B1E2273877287E1FBAEFAA -:10F7A0004ED9C47E58C4FBC3BE3C35D54571CDF09F -:10F7B0006BF52757374BBCFDD42CDE6F4C8E687B26 -:10F7C0000270485E1EEE027FC8CCEC24BF31E819FF -:10F7D000F3B618C47B8F99759D17300FAE52D3FDC9 -:10F7E00014A478670A2A763CCFEF3488F8AB74A368 -:10F7F000489F97F0E1E57E94B3B84E7A77AEEFDD9F -:10F80000A4107AB5B05D1BF1DE8D258EB95A9C012E -:10F81000FA54FD28FA54F43BD0FA7E21F9C837ADEA -:10F82000EF549AB44764BB5211A7527EFF0817ECFD -:10F8300033DFB44E8B7C7FB06FBD9C58C7C5F6B329 -:10F84000DE4C716E1978BD5B4AE2FB596FE83AD520 -:10F850003E5177DAFBFC0BADC2BF704AE3F28BB7C7 -:10F860003BB5C246F7BFD4BA94FDFBDBC621BC3D15 -:10F870003156DA133A23A1479685CBFDEF17797CF1 -:10F880009F1DF45DC97DF55E9BE2CFA71BA55C645F -:10F890009DF7613FB3A60C7A9FE464EBA948BC973F -:10F8A000726AAA989F6AB7DA2CE28C59A4C589F7C4 -:10F8B0000FF9F9EA6413FC3EEB12E81C795B53067E -:10F8C000F185DBBC31C2FE20F5FB25920F46ACAEC4 -:10F8D000D88077BE176F4B73687C9CC576D7C7DB23 -:10F8E000A8FDD52EE883115B665BD249EF15E700D2 -:10F8F000E5275AADB1528A1B039FC4FE32BC920960 -:10F90000B9B3749B3807CC32B08DF0130E6B299DC0 -:10F9100091043EF1B04671E66CBBFE1DABB1F9A59A -:10F92000E7E9FC17F20EDC6A739B3B017C9CEB1B46 -:10F93000B0372DB69792DE5E2FF9E4C92D5DF41E27 -:10F94000BD82EB15F13F161107DC1369203BDCB7D4 -:10F950008D03AA927E254537CA2FF508FE331E7007 -:10F9600032925C2B3196D17B4A1BB64CA7B46A739A -:10F97000C956EF28C41F97C64FA0799BC94E56554C -:10F980003F5DC4EBEE0C8BC1F926D5EC4D0DD64B8B -:10F99000AB76DC4DF13F9FEEB051FC4FB163767119 -:10F9A0004C1CBD774CF175AA5E6A91E03B35F5D3EE -:10F9B00075F13B8B799F7867F3CBB608BA1FA6E247 -:10F9C00072EA123C494583457CCE78A788CB49A290 -:10F9D000FACE7EEDE22AFDB859C47904C51BDDB824 -:10F9E00080B7AFAB7F360AFDD43EF8F6188781ECBE -:10F9F00050C3D17F5FBCD136116F9425CF4BB3621A -:10FA00004B6F5E00F8FFDA48F01F68BCEA439ACEFD -:10FA10008F779B2F9AF4568F9F59E047F63818E955 -:10FA2000C59F1A5913F400A5BFA8EFE3255C3E8DCE -:10FA30006E4D057D2CDBF3502AE4CB6791225FB637 -:10FA4000E796DF805F79768509FDDCC4481FAEF458 -:10FA50000AFD9A55C7AAF7486DE59C8EA6174588FA -:10FA6000778FB6E9E3CDD53BB79F99C4FB3C883788 -:10FA700002BDBF6FF22F067EDFE7FA2BCEB1A9459C -:10FA8000823EDF6F35CEA07B437CA3400F79BFF56C -:10FA9000D948C4432B7DADC4F8811BEFFFAC7C4E2D -:10FAA000C405E37D7A7A2B54DA411AA41D64E50B70 -:10FAB000E619C971A47FD1973A93DFD21FFE6AA4D9 -:10FAC0007ED5973FB09FCE6D75FB84FE50D7D6454F -:10FAD000FA83D24754DC61EDBE2ED22754BB860395 -:10FAE000022EF507C4F78A6C83B2A3B8B54C9CA765 -:10FAF00035CA7B5FCC2F5F6B0ACEE795AF05B39F0E -:10FB0000A0EC233DA40FDE9BFD3B3A87D7AF93FDCE -:10FB1000F2BC3968BC6A1051A1F89E61477BA7EE20 -:10FB20007C577F2086DAFBEBC33742CEBB1BEC262B -:10FB3000A42DF57692FBDB1B0DD9B8A7EED6C25DDE -:10FB4000D0E3DAE5FDADC1B5EFDA603F48623D478D -:10FB5000F1DEAE3FC5F3C322DE6F025E773106E20F -:10FB600089BA0F7F928FFE270FEBBC883735CCDA2E -:10FB70009472F8295A8AE43A723AF341D7838F088B -:10FB8000FEFCA8996DA4779B4DA50CF67BBFF42FC6 -:10FB90007ABF32D0FBB3ED9AFF67C1FAD521499FF6 -:10FBA000A561C2CFB873B46713E6F15DCD3C2A9767 -:10FBB000EE1D1A87A3FF6EE987547AEA34C99F5372 -:10FBC000E4F9CA3224D10E3A56F7ED34B79BE23D40 -:10FBD000EFCA395209F9FCE31E2BC50B4CEB092780 -:10FBE000BD3565C84C9267EADD7615F77324C7E02A -:10FBF000C57BF43F6656712FC01AA2DF1A6C743FA2 -:10FC0000596BFFD557E0EBC9C60B47A3715FF6DF11 -:10FC1000347A7FB4BCF7E347DF62380FFB72291EEA -:10FC20003AC5B307EB39D93BB3CBC351F763479B15 -:10FC3000D525E4050B5E47FB1D5F45C51A02F3EBB6 -:10FC4000EEF998DE75ECEEB192DD765ABB7CE730CA -:10FC5000643EDD894EBA27CDEBD1FBCFDD7603BD07 -:10FC6000EF36ADFD28BD57384DBD6768D5BF67C8B5 -:10FC70003A52626057265B2A570EE25B04FE264723 -:10FC8000EBCF8BAF15097DF1B522ADDFF7EE55DC7B -:10FC90008A922B2FDBF7DC26EC52629F2E577EFEDA -:10FCA0004BE9A44FF4B6677CED3B166F43AFE0FA27 -:10FCB000C2856BDC6F171506E4EA3C0927259F55C2 -:10FCC000DCC23C09AF797683804FC8EFAE28BA0911 -:10FCD000A58B50BC2B7CB21F741C433C16C7E3A8F9 -:10FCE000FB19E1EF24E1EFABD7D7E3D985214677C4 -:10FCF0009727EDFF45FCF96D23A0473C68203D4266 -:10FD0000DD77F4C8F7DAD5BD4796CD881F941BC3BD -:10FD1000C95EE891EFB4733E700C7C40EDFF613337 -:10FD20003B47418E9EE44774CCAFD3D046DF532788 -:10FD3000A5D37E1DCA3A92E4FD9C42E86FC6C0FB83 -:10FD4000D444F72D9AEFE125B87F39CF4EF7DCBBCD -:10FD50007D21EF53CB77CCBB99E40FF3D53BE67C09 -:10FD60003FF3765B1688F2BE77CC87333A476DC98E -:10FD70006559D0BFD4EFFE0CF88EF9B258B29B3E55 -:10FD8000F2886F24E4817ABF7A4A8A2771D2E02B05 -:10FD9000DFAFDEAA952EC0EFC0784789F9762E082E -:10FDA0007F668F00B71FF69E934D91F46EB7A253F6 -:10FDB00065E71EE6ED7A18705271B57F96F4A6E0FD -:10FDC000AFE20AE342F0A0E8CE6B6614870B7C201A -:10FDD000CEA8EFF763D648FEA2E23A5F763991FEED -:10FDE00038D5933B09FB70058733D9D13BBF87F5E5 -:10FDF0003E7A47A41BF33B297FD722745F154D320F -:10FE0000287F31C50D944BF956AEE2049AF4710285 -:10FE1000A1EF9C860F2D9D0CB89DD3DE1E838FAF66 -:10FE2000FF6F63BFF74FAE9D24F84466A267C624F8 -:10FE30009273D374FAE4EBB99FA4D0EFCC5C3E3A52 -:10FE400014F2EF9694D2EBD0AF2D53F80FFE9CD462 -:10FE500049711E7F5EF0D714B23FAF11EFB37EDB66 -:10FE6000795E19D72CE861D562712F319935121D51 -:10FE70002706E2656D98C7FFB4B8E640DCF15EFA8C -:10FE80007D91979BDB324E0FEF07EF61479E75F236 -:10FE9000938DF7F0CBE514F71B7D64551ACF6F3CBB -:10FEA0007CB49CE27C938F5C4CE3B8B9F7F0AB2256 -:10FEB0007FF5918B880BDE74F898A80FFFC110C6F0 -:10FEC0007E72F878B997E3E38ED19EFB81AF9B2FCA -:10FED000351E8338FEFDDA398BD328AE75764AB6E7 -:10FEE000886B5D07BCCF8B5FB43E5A0BC4B5EE9BED -:10FEF00024DA755F10FBA0FB82A0F330F083C1FF12 -:10FF00007CAAE27B151F1E885FAA7DF8AF8A4F5638 -:10FF1000FB99ED716D348318BDFF74DCF093936829 -:10FF20005DFAB8E16E73CF63E457BAC09CE013AFDB -:10FF300044BEEB84BC682914718D5A4F8713F73186 -:10FF40008A0A44BEE54287137C1E79D8B7BA634457 -:10FF5000BCA38A8B6DB9E04FC23E2942FC22AF5F41 -:10FF6000DCD3530E3E5A84FBBC69E8FFF851391EBE -:10FF7000437FBB2E88B8C36E5B87D321C7413F7CCC -:10FF8000DC34F0C7A2D556BA77D472A17105F55307 -:10FF900066EF1B570B19D7FAF5E34ED782C6CDECA7 -:10FFA00015F19D18D7A91BD74F71C1BC3F8A3FEDF2 -:10FFB0008E7125E2DCAFF2C528E7F987E4EF54142F -:10FFC00039FD46C8011527956091EF71CB730BAFD2 -:10FFD000477199BB7AC53ACF37FB6BB09F8A25DF53 -:10FFE0002EB608B9C90CE12EDCC72E315E3E9E8CC0 -:10FFF000F3C90BE27C521C56BA1DFBB1C124F80DAB -:020000023000CC -:100000008B53BF97D6B1ECE7BCDEEFE293E9F7C5BF -:1000100086261E6499381F2F9F9903B9C1F5EE33C8 -:10002000C0F7EF58AB267E874BB49F3B3382EEA1DF -:10003000741F1E5188FD3327CCF91CE3FBB677D221 -:1000400057B44FE7443B0B71E2E93DFC5F229FE070 -:100050007C0EFE5D2BFB8AF473E5AFBD25E0AFFDA2 -:100060005F18A77EE6398BD0CF7AE89DE6FF9A2409 -:10007000DEA7E3FA3BE91F3DD7C97737739C852894 -:100080004F35F744016EDD974DE2DD5AD6137553B7 -:10009000907FF6B176F19E6D285D1F9E2CE4C0F234 -:1000A0004C3BBD77D69068B552DA7E6106FD1E8C5A -:1000B000A93413E703B7A57FBBE32F260B7995B6C9 -:1000C000C112F0BF73F9E10E672AEF65E318DBF1A7 -:1000D000FDF0BEF317448C65B83C8F79131F2F36A3 -:1000E000E9EABB51BFAF9C8967DA54FB9C97ED8F5F -:1000F000AF33C9F180E725E2FE44A8BC689812DB63 -:10010000F75E21C9DD381BDDBBCA344A7B1EAFEB6D -:1001100020BBA0F0DF26FF878DE2E876D9041D66BC -:100120001A44BACB20E37DA5BD4F9D637E3CC53309 -:1001300069CA60EAC74FFD18F7E742AF48626D34FD -:10014000BED2CF543DAE87D988C9C8DF7B2B321AC7 -:10015000FA85E73B93A7964E2E045D7BD947417203 -:10016000E27C44545330FE1A8C7ABBE73B93A75190 -:100170003BD5BEBE693AFB88E211FD443FF59906C6 -:100180003AB73618D9ABF4BB03AC83FC99AADDBBF4 -:100190009C4F7E44EF36B8297D8FF3CB8FE8BEDFCE -:1001A0007C4A3F68F6D0F793CDD594763637D2F7B0 -:1001B0000F9B9B28BDF9D6C802D0FFF2436BD947ED -:1001C00041F2B1BECDEC09BE5FF3EED4FEE9E8FB2F -:1001D0009385DFE6DDB4FECBEF57E593053EBB1715 -:1001E0000B3D93D3E53A47ECC0FA4277A4B897F0B9 -:1001F000D234717EED4E12F9C6C9E2BD50B7816DA1 -:1002000043FB97A65928FF6EBA81DE7570C78A7EB8 -:10021000DFCD32909E76FD8CA90D80933B9E7FCFE3 -:100220000BE4DFBD4A94BB8788EF6ABEAA7CD294F8 -:100230003E3B4296381F0BFF3BA777EABF0FBFC577 -:10024000627EA1F5D57DFA5078FC56EE5BDA17D0C8 -:10025000DFB10FD282F6458393F685A243457F0D29 -:1002600053C47ECD0C9374CE6517C10F320CE7E3F7 -:10027000041BF907DDF05FF0F5EC92F1EE57EC07A7 -:10028000E90F50FB41ED0345EFC97C9F097F87587B -:10029000C72463FF76FA87268B7577C447927EDC86 -:1002A000DD6E7640DE4C320ABF4377FBBC02DC0BCE -:1002B0002FB9DBDED81FFF7A53B6FFA7E1A0F8C144 -:1002C0000070B862FD1669B7FF07D74FFC0D7C7B45 -:1002D000B1B897194AAFED9395DD5DD0ED3B93DD55 -:1002E00007413FDD9ACD84734AB7ADFF7BE42F4DC4 -:1002F00013FB42D14FC31426DFA1E1EBCCB892DF50 -:10030000A9F5F4AD732923BE9729E38D43F1ABD64C -:1003100015C4F75E9F3C38004FC6B8BEC2FB195AE1 -:1003200067A773AAA2DFF383BF5A02F9357FB253DE -:10033000F8990C46F91EAC90277DDF3523C55D0585 -:10034000C91906BDA5E7B0F0C7F9F93909FE2CD8DF -:10035000A083E3AE2D53C4BA7BE7171A602738FF9A -:1003600017BB1772EBFC909E93D04BCE6F13EF9D93 -:10037000F31E6769B83782F81F277EB745F8418CAE -:100380000F7F7912FAD092878DA4BF9CC7B199B71D -:100390005BFEA0F89D3B757FB04EB66BD976F166DB -:1003A000FA7D334E9FD07F3EB235A4432F9EFEF0A0 -:1003B0008327F0FEFA92E734989BD951D8DD79FE75 -:1003C000E3BD46F13BAB32EE6486BCDF5FB35BDC82 -:1003D000EFAF43BC09F497033BB6E2F727EBF79A7C -:1003E000998D7F9F8177D2F8384BDB22F94192F7C4 -:1003F000BB451F377A2DF36E803DB97ABBFE7BCDAE -:100400002E7DBE2EE4DEA23645FE9EC148964BF7F9 -:1004100013B7087BB1E2DB57EABB5E82AF7BA5BABC -:10042000AFFB05BDEF6D3CFC65EA8776919F2DF330 -:100430005D3C7FEE4B017F05B706C9F3CF25B18246 -:1004400036BEBE86C33607EC000D2F083BC1F9B699 -:100450006882F3F2F04EF22BB0178D0EE861F71CB4 -:1004600032925DA1BEDDF633FC2E6DC3731ABD570B -:100470005B7F28CC27E0736109CA971EB2399C289C -:100480007F318CC1FE7C9EE30DF762CFA77412FE14 -:100490008157D825F8DF2CFC7E85C2BFF161E14F82 -:1004A0005EF284C4CFB65526C2AB4F63096957E2EA -:1004B00049E1F95786A7FAF08476D31FFEFD7189CA -:1004C0007786789BA3DB2AE9773114BE2D873F4AD4 -:1004D00085DEABF06CE478FEA16AEF94EFE17D0D70 -:1004E0009EAB8167FB3F8EE73F423E1692DEFBF1FB -:1004F0004FA1F7465AC88FAEEC1ACA6E31B8F6DD76 -:1005000063717CE0E189CF929E5B1E7BA67E052312 -:100510003BDAB5536047BBEE0DFCAC2FFBDDF54F6E -:10052000E5823E5ACC9DF4BB31DE18F1AE7C77DA21 -:10053000ECEDCFF3F18A63BF4ADD8F7DF37218B91A -:100540004FE6CA7D893F6BF0BB80ED36B2B7D5B7B9 -:100550008709FBDA01BDFFAC3B49FC4E5F89A5A7CB -:100560007C05F472DE1FC651E7C1DA76F9FB2FF283 -:10057000FC56ABEC0CFB42DE8772BC41F5EAA68868 -:1005800078DB8C84494EF0A19605CC139EF175FC66 -:100590009E11BF57BF9737A01E3800DF57FA1FF3D1 -:1005A000EAED1C8AFF2C95BF2FD9B73F64BE7AAD08 -:1005B00037CA6A24BAA3771BEA1E15BFAFF809E849 -:1005C0002E2A404F0D323EEDD8F77F63C2EF3475CF -:1005D000EF12F7233887DC8A7BFA67DB443C5C4DFB -:1005E00041D718BF13BFD321F8D0B27D9ACF99D687 -:1005F0000F1D31DF06F1AE7D083DEDFBFA770FEF01 -:100600000DF091517FE7F0DC51C2A4DCF2F61B3F04 -:10061000D927BF427EC7E37F5A3C776F0E5FCFD7A3 -:10062000F81BAF4DD4BFE3729D53FF3B4DDFC9D6DE -:10063000FF4E53AF5DC247EA834A4F3D3445C8F190 -:10064000D054C1F706977E1C752EFEEE38FD78B3A8 -:10065000DDFAF1BE2D5EFE5571ADDF04BFE372DC45 -:100660001372DCDFC871FF5938A974A0F1FE7F4D09 -:10067000FF0F822563C60080000000001F8B08006A -:1006800000000000000BB55B0B7C94D595BFDF7CB0 -:10069000F3CC7308210904C2242421608803245464 -:1006A0002B94C9D300D6065C2D68840152C83B80C8 -:1006B000B5D2D6FE3208222F5BA8D1A2224E82E10B -:1006C000A1613B118289863A286411AD1B698BFDBB -:1006D000FD56DCF828F23213A374E5575DF6FCCF23 -:1006E000FD3E321942B5DDDDE4A737E7BEBE73CF6C -:1006F000FB9C7BA929CE317C394588DC9873E69E2A -:1007000008215CAB7A8A12B385E87B43154D0E2134 -:1007100084DB7BBC3E5688DA8EE1625332C1257D94 -:100720006F1A00B78DB36FA2F18DED7F781BE3BD1B -:1007300007558785C65F6BFF280AFB5CFC325C8827 -:10074000E158F7519420B8FAB2C2F0261A77103C5B -:10075000AB5515FE4CDACFE83363FC62AA0E7BCDB5 -:1007600082DA929656730FB5557B5B79FC0D9F69C3 -:10077000F0F8DEC641E376CCA7B6CAE88DB2537B6B -:10078000BE5DDFCFCFF3AB53159717FD7BFF10B7DF -:100790000CF35ADE895B4AED15FCCCBCB6FDF4D0F7 -:1007A0000B996E5A57D341FB440CEC53D361D26082 -:1007B0008977756A6B510CD14BB428228D9A8B6264 -:1007C000AB584DF4AC6A6FAE16D45F95718F49107B -:1007D0005D023EB518DFA71F8388A37576FA8BE804 -:1007E00077D1F779D452DAF755DFB1DB5DD4063A29 -:1007F0005F8FC2770307697EE6003ED35D44BF1C6E -:10080000B4662146D0BA83AF4739687CA3EF7549F7 -:100810006FA39FCFFD9A0607A8653AB7AB7CEE8A17 -:100820002F55A6BFBEDFAD2E95F799D59E168973BD -:100830009DF4C9EFCD7539647FEAE232E07F226131 -:10084000418E9ACC78BB000726CE69DE44A854F9C5 -:1008500068DFCC6BE9B654DBB7CB24E6FBC0B7D47A -:10086000035DA3483E4E140F9F4C2357E7DDE33250 -:10087000F0BC22B33B7505CD3B19E188B4D37E0FA4 -:10088000158F8B045F5F438BFEE25D6637B595077E -:10089000E5F74EDABBA3206F270F4E553DCAC07E49 -:1008A000776ADF15C2C3ED00DF3CCCA7726F63042B -:1008B000F619E09FEC9FEBB2F3FC13DE77EEBA87FC -:1008C000CE773223DC09BE749945B98FE5843E8228 -:1008D000EF752636820EFAF7E6821FB42E9061601D -:1008E000BEF6B69BB479F7348B41F34CCCB78BCFC3 -:1008F0000DC6C7EEFDE097F7D0FCEA675461A1EEA4 -:100900006AD38A389CFF931D83F12BD7E85C6DF284 -:10091000C7C505C96B75C7557D8960F9EED0F5C3AC -:10092000C1FCD4F978324395782558BC8250AE6E1C -:100930006D66B92675F3D8A6702BECD4268677277A -:100940002B74FEC407ACCEB584FF738A366EA03616 -:1009500086608384CDD45AA97DC624FBA1B6583FB6 -:1009600086D8A9106C2A1E976348A17DD4D6C9E009 -:10097000EBAB335D8FBA088FCD334B66CC043EA210 -:100980006F99A06FD65C8AF08868210AD5F79EC05F -:1009900077FB0F9A04EC478DB5A3F26392D37E27C1 -:1009A000290AE1DDBFC3E4F5B0FCB9229469422C09 -:1009B000BB49EACD270EF734751CCD5F63E0F355D4 -:1009C000B7A85E1BCDEBAD271210C93F6D4DFE01E0 -:1009D000E4B5FAB86AB7D2B9F37DC9BF9A0EB8C503 -:1009E000E4B4D0FA5A1F75125CBB57F13AE4FE0228 -:1009F0007A597313CBBA3863AB4D1159D4AEE9337E -:100A000063DE99C38A788CE66D0E8B6A02DE3599B7 -:100A1000B3CF2951D4AA5BD627D27ECBB79B3EEC6D -:100A2000B1CAB557E8BFBACE6D2CB715DEC1FD55BA -:100A30007B07C335C23800D3FECDF8E36621DA5C0C -:100A400091B1676EA0BF2788095754D0697A3CF4EA -:100A5000E104F84AF2241A88D82385B86F92331E2D -:100A60007ABFD1E8980D3A043A4D76D0ABEEF081DA -:100A70000AE0EDAD0E731AE8A8B5AB5F61BA06BE29 -:100A800020BADF486D82E0F30784A46FA05DCA79C5 -:100A90009D49F15AB19E68C8FB5915EF1A1A0A7898 -:100AA000FAA3D83E09510CBD58B520C7003B073505 -:100AB0001684CAAF747D506C46251AADD4FFEF1969 -:100AC0007BD4614176E23F5D298C7F8159B87DD42A -:100AD0007F5FA4331A723FD61A9505BCC65A93BCE1 -:100AE000A0FB5863DF1A7C7FF328C5F1106D7D24CD -:100AF000EBE5C90AE0DA0827E44449586C043D36BE -:100B00008F5A6C84BC8FB5FB324A3207E0028C43AB -:100B10001F8497BF5714E136E23BCF8D54FC06DAB1 -:100B20003F6023FCA02746BB09F8054C121662CD96 -:100B300020FCC82231FCFF8E9F9DF08B18C08FF8DF -:100B40001D8DF59F67137DA84D9A2B4437DB8515C6 -:100B50006C17747A5E24792F205EA529526EAA77CD -:100B60001C29C2788DE85E8F754551F21C45380FFF -:100B7000E030D9AAB9925FB95A7B7FAEF42FBAFDA3 -:100B8000ECC8751973A9DD9E5B62465BA866C6F763 -:100B90000C61EF5729569693CF49FF608FEF5DA107 -:100BA000D8533306E45BD7AB3AD975557FAA7EBFDD -:100BB000CB2C52F0395777068D970BA9D78B56DB84 -:100BC000ECA9C17A043D237A94DB2B6E13A46FEE5B -:100BD000D571F6D4A9D4AF5E340BC89EA65FB1F42C -:100BE0007B256508FDF285E865FB60D86F9372EEA2 -:100BF0008F54BC6B09FFD4DCC17A97A4E941A35B95 -:100C0000E1F3357E6564D853AA7841F33BA9737547 -:100C10008C7638CC2BCFF5C23FDE496029FA1B62B7 -:100C2000594F7990ECD7BF68E7BCD3E83F02FB711E -:100C3000CCE44BB6D3D0B11AAB13FB2F1014E89011 -:100C40005D2B15DDDC9E0AAF6DF3F3E69E3190AFB0 -:100C500077DD1627E2B0C6754D91B0E359629DFD70 -:100C60004C06820AB1F7CAD4EBC7332438E28CCEE3 -:100C70001738628A53C06F9DAFDB735D79B939D77E -:100C80005F5FF5A7B6DBBF03FB757FB3395E8A49AB -:100C900077C6B401BEE97CAD131EC65BE7D755FE2F -:100CA00011EEA3410FF5E25CB633CFAA82E30A8DC1 -:100CB0007F56FA1D8A7F3A7D676A7C58DE21ED51A6 -:100CC000285F757AFF9036C4F7C98FEE607E080BF7 -:100CD000DBBF50BE7F135F28C22CC5507EAC458061 -:100CE0009F8906691F1397919C10DEF708F7E11E94 -:100CF0006AEF0A7FCBC472A8F1E75EF087A6BE2B2D -:100D0000BCDFCF48FEBFE34F476EC903C17A18AAC4 -:100D100077D7D3B36A87F3DF75BF479686F42B4442 -:100D20003F43F44FE7977B7514EBD9553EAA2D52FC -:100D30005F357E45D0EF90FA863FE87B35ED8AD768 -:100D40009FFC2DF44F21C4896F8F85E89DCE9FEBCA -:100D5000D91DDD4E9D16FE63763AFFA9141907785A -:100D60007E62F136034E3794C3EE9D9A28DB039AD8 -:100D70007D0B6D4F539CA3901FDB94717204FCF5A7 -:100D800029B3BE8FCDDB4CF89F5ED33D6625AD3FCA -:100D90009D2BDB53880B836057985804BB7E7AA445 -:100DA000C5033A9D5626E4C13F9C561EB85DC2F16C -:100DB0006607E005F17976824F99E47CDDAFE8F6CD -:100DC000FFF482EF14F03C451C053D1C8A28E1EF3E -:100DD000284A4C31E173FAFEB4296BC5C0F99B7205 -:100DE0000DBCCEABD96FC283E9DEF753C5DB445DE2 -:100DF0008BE05208FFE4BCDF14A750FFFB3F1B371A -:100E000019FC75AD1AFC7DF8EBE41B016FE37DBEA8 -:100E1000F7659F6971905FBAEA270B3E93FD6539CC -:100E200006E84BB9C64357CC8468F0A7DF3B2E1ABF -:100E30007E47F743FDC70F44B883F8768EFC9418BD -:100E40001F044F783429D88F1DD9BD391DFB949BC1 -:100E50003D594EEA3FDBF87412E28DF2DD8FA47348 -:100E60001CBC7B633AF299F2A6CDE92E86C3DD9CC9 -:100E70004F19E5B92FECBF79D7A6A0B8BB2A5F659B -:100E8000FC4BAD470AE16F67DFF0E9C3769A97F64E -:100E900033C50EF1BA57743F0CFFB810F131F2B7F9 -:100EA000062BDB73DACF05FE374FF8FE73D0E31362 -:100EB000191F99CA68DEE55C23D367A1F06E89A784 -:100EC00071B141B1378BE0F9631A317FF13AC59CBA -:100ED000003BB062D864D58175C3188F251B267777 -:100EE000A17FE183B27FB6C57BF024F6F98DD9D915 -:100EF000EC607B9352326900FFCBB9665EB7688BBA -:100F0000C2F1BFFE9DB427E21A83CF7959E3BFF83F -:100F1000CAA2802F3FD0F872DB83EF1C4DA07DED7D -:100F2000B1EE2BB01B6F3F7E26D54FFD0531E7326A -:100F300021E76966F75315387793C5897364672588 -:100F4000AAF1347FCA8F731F43BBE8C1C54F55C098 -:100F5000DE6EB772DEA6E3B74A711A608F5F6FFC70 -:100F6000E112D0EDECE3568EDB57358E8F1743E858 -:100F7000A9DEEE21FE3B28D1D9576FE5F6857ABB75 -:100F800070903CECAF4F60F8B7F50E6EC57C295FF2 -:100F9000ABB4FCF87AFB4DFD325C38289ECDDE60A8 -:100FA000130EB2534971AE517974CEB489354D1BCD -:100FB000B573A5D1FAC99EE47CD0217BE3CA2E8407 -:100FC000BCE63C998FBD797243128CF2F2073FD890 -:100FD0005941E373F34AC6E551BF75C7675C57785B -:100FE000BDE39185A0777993459E4F3BF7D9C7D351 -:100FF000E39FA2FD3D6F9838DFAFDBF1C1CE8DD40A -:101000002EDDB2D21C2CEFDFF6BCC91A3EDFA4578E -:10101000D7A3C33FAE579B93587F9A48AF32FF790F -:10102000BDAA7B700DD3EF81BC92D9A0FB59932749 -:1010300009FA7476C20C9673CF6185E9AFDB717DD6 -:101040007DB176DE2A836FCBF4E4013B7E496433C5 -:101050007D8F747C928EB8F752FB82BF7BEE437417 -:101060006E3F9DBB9DE8EB1F7FEDF834B37B9C93F7 -:10107000CE37CD20E3DD6BE2D63C83562FE83697A2 -:10108000444A9A2BA8CB68FE93FC98279AF0A9EEC5 -:1010900054FC6159F067B79E3322DFA3BCF1C3E073 -:1010A00038827E3E0CF2DBD7C3F79BDA5AEC9336DC -:1010B0006077BFF36783F007F9E99B7BC2843FE861 -:1010C000BB57F313EA33139F7A3B46B25D00DF8CC4 -:1010D000A8C7754C68027CCE2CF9D87B88E22659CB -:1010E000C711EAB481739EEBB890053B1B7ADEDA38 -:1010F000972FB07C54B73FF299C2E79F75CE98F511 -:10110000CDE73FB2FB4216F877CED4330DF956AF98 -:10111000B9270B7CA87D45DAF37F940E7A7FC5064C -:101120003A08E979AD62653929542F72DDA0F7B824 -:10113000AC1BD476EC627BDADF29EB377586EEA246 -:1011400078D43B567CD0057BD69F20F328DADF0588 -:10115000BA4D1FA7F941635FD25CB26B2F5E950752 -:1011600099FF9D85FE8EC73EBE6AD80191152E104F -:10117000579C873E53FFC2D5C9EB21E767BD23A625 -:10118000C03EBE99F5B75AAEF7BD1A6E5739EEA1FB -:10119000DE20FE5D3D875715AE41F58070E10A9A6D -:1011A000576776FC80E3E313AA405C573751EA9314 -:1011B0007859EA53CDBA23E684A0FD76429F186F92 -:1011C000192FCE7EF56FAC975B66BA3AA197E1B066 -:1011D00085D82F21DAAB28DA3CE27FAD864344A7DD -:1011E00096F717AB3C5ED7AE8A91589310E94DA3A2 -:1011F00073148BAD46C4D3B3856F3AEA36C2D8F3C5 -:10120000CB5B687CCEABEAD44D82F3A745259C57D7 -:10121000BA5357213E32281A5D7DD97383FD599EFA -:10122000F453D35585FD58DFC8708E5366CDAF2972 -:1012300005BEFABCAC61721EEDC37196F0F665CDC9 -:10124000857EFAFBB2E6450ECCBBEBD5F015EC176C -:10125000852FFBAEA0EF84E5CBFAE8E7E447202733 -:10126000759764BDA350FDEA09C4E7AB0E93BC209B -:101270003E3424BF6B801D273A83AF1788AF2EF80A -:101280001FB770B9A03F934678A13F75FB15614425 -:101290009DA8C3D2843A52ADA9270EF2BCB1FD4F2E -:1012A00066C8735DDB3B66C724AC9775275248B6AA -:1012B000E3759AFFAA691FFF2EEA7C35C7A517AD13 -:1012C00031BEC3F97BD5C156CED3AB859FF3F4EACB -:1012D00096C1F2D29FE0E0BA48A87E84E53B06E9D9 -:1012E000C5ACED522FEE52C50AD839A1D569672594 -:1012F000C4733C32B04EC6BB2EF5C2C3885F022910 -:101300008A53A1AD02619E75888B3CE9329E09FC2F -:10131000EE85EC656C57BCD977D0B9025ABC3B6BF3 -:10132000C336A31A84CFAC4E59970C8489F243CCB0 -:101330006FF768F041B84A22F27358AFB2605703B2 -:101340000659470D3D47BD562F3A817A52E600DED9 -:10135000731213A51D135E969F2E83FCBECB40E334 -:101360005306D62FC997EB07F2215907BB9E5DD9CB -:101370004DFC2923FEEC253EA37D9EFC7119D999D5 -:1013800016F2C780FF95FC315A5F7D06F7BF58EF14 -:1013900064F860FD4D0C1FAA7731DC5E5FCCEDCBAD -:1013A000F525DC7F02A87E17FF7BBA11F2D0051D60 -:1013B0001B35009F8A0981470D9E7F2A46190C8F95 -:1013C00052787E76FED38D1ED48B66DA35FD764458 -:1013D00022FE3A6B9375A8B33659876A1DE5BE2580 -:1013E0009FC6CB66ADDD2DF350573AE615C42CE011 -:1013F000FCB59FF257D8A395F9EE3CF0E5F8F1FC67 -:10140000D46D6C276D5C073D75F70DD15C077C834F -:10141000F271FA746EC6D475D904E746282CBF64FD -:101420002F6E2CD1F34ADA27BF53DEA314AAD56559 -:10143000D87FD548DB54D8DFCF5DEEDB80874EEF19 -:10144000A251CB53110F75991CEFA28EEBF9BD4938 -:10145000209FD2EB7DFABC0E57EEDD58372B63DCB4 -:10146000BA29B03BA464B0732EB368015E2E43B8B2 -:10147000B296ED96C3083B70B726C7790E1917FBD5 -:10148000CD0E630CEA3761B9B11E5AD7A5F1F9B890 -:10149000C6E7131A9FDF429D8CDAB7A91F6D37F597 -:1014A000A39D01FA4A7965BA3D915752C6F22BFACB -:1014B0009200EB75C1D9D02F696F9220D75B34F9B8 -:1014C0004DD0EC4D576E49955CE7E37DAAB47ADBCD -:1014D00005ED1E443FAFBE6E60BDE076DE8DC2639B -:1014E000859D7F49E69D6234C52304CF7B299EED0F -:1014F000906ABD23F363D2F37953651E200E58E43E -:10150000BC04470EF464AD566FEDF51A3C26D4A723 -:1015100063BAD363E07F35FDD2E143FFADB2BDAE28 -:10152000994230B5AF28F27C35F3BAD38761BD62FA -:1015300033707DBB498E9FD4F4AF2645DB4F3B8F84 -:10154000B0FA92C08FC0E197929610BC29C2BF4CEE -:10155000DA7D7F3ADB6BE14F9F07BBA8F8DE174EC1 -:101560008A2B0BA62E318E043D7C3B015717E42CB1 -:1015700031DE8CF1D6F7EDC1E3237C498A1D70B6CC -:101580001C1FD1BA7398330836BDF83EC6CD869C71 -:10159000250504CFB1788FD7436E7E2BE5CBB6BF40 -:1015A000ED0CE856D521E3F6BCFD6D175F845F6E48 -:1015B0008B74C2BCEFCB4F667AAFEDD8B305F2D6D1 -:1015C000DB2AEF0336B5FC69E7CF799E05D724B453 -:1015D000AF2F5BD077561EFDE362E03527DCF705C1 -:1015E000E0878ECE643CE70C977AFDC8D1BC25D04D -:1015F000D3DEB6FD3F81FECD89A68016F8BC60E340 -:101600003A44E5810905D0D3DEC8EE85D8BFF67926 -:101610008B13725A79203E0FF58143F9B21E5E3169 -:10162000716B12FCACE1E57DBB7F8EFBD5E76D7C79 -:101630002F541723E3BC4AB571DA4AE6DFAEDD4F1B -:1016400003EF7D36BE9FAD40AD8AE08ADD695CC7A1 -:101650007FE5EB8F16820F85EA8EDDE8FFE2399B8E -:10166000017438697645CF801E9E3471BE59A1C180 -:1016700015A7864B7CC27B8A987FB15B93E0672B72 -:1016800087FFF476E03D47DDBA13F98ED863E1BBFE -:101690008973FB886EB4EE5CB3690AB8DCBB2FD2E9 -:1016A0000879B9A06C5DF814F66F96F32ED8B632AF -:1016B0003D3DCDE305BE47F304ECD60565DBA0FE5A -:1016C00073CD7BB2908F9E7F7E0EE7A5BAFCEAFABF -:1016D00052F99C65905F644B40F6A852FB5BD83D85 -:1016E0002282FC6D85069E3FF464EF536260FDF933 -:1016F0001693DF4C34AAB08875D698017DA84CBCEF -:10170000B518E7AB3434A6236EA998DAB3107A7112 -:10171000CE26AC0934EF4DCD6F551E5C3317F1EF7B -:10172000F5F0B9A2D9A34B09D27F5D6AB77983EFEF -:101730002543DBF7EA85FDADB401F8DE15168EE131 -:10174000F5FDDE34FBAA91A7D5C648FBF13ECD6F6F -:10175000213BF6B5E6EF16AD1E3CBF3F3F86BF5FAF -:101760006BEE4987FFD3F70FE46B7EC3D8930E7BF4 -:1017700015BA6E0EC211D8911714B6239507950F9E -:1017800054A253A5D5E355411761D6CF69BCA2C871 -:101790007509D334BAD3DA0D05C9FCDDCA169BCB63 -:1017A00046EBAAC27AA210175547F64421DEE97D1E -:1017B00059154D1ABB62E334FEA4682C0BAA3756A8 -:1017C000F84C2E5BD6107C46FC44F396E36FFAFE91 -:1017D0003305297C9EF2F670FE9EB0F74C839C96F2 -:1017E000EF18BC0EE7B207E95F6FFBAEB8E0BC3C98 -:1017F00045C33BA07CC07A12F8FAC324F0BDD220C6 -:10180000D6E1FEF23CADC1BD26C1C22A61BEF7AC35 -:10181000FC6B4418E4E5FCA56AD6DB5EA587EDDA2F -:10182000DB0573D92EF59A7AD8AEBD7EF42EB60FAD -:10183000BDC37A16C24EBD5DB05C8E8FEC59E8A078 -:10184000F1FD3A3C46B0DF7FEF680DDB8F39AA7CB3 -:1018500057217699ECB21EB4E1543DE71726477044 -:10186000FE7DBA40ABF70CF087F32E5D6F7A85638F -:10187000FF41E8617904D775288E6A7911F1DE821B -:101880003827DE6B94639D940373F07D636CCCE525 -:1018900065E0CF1DA3DD450539B8DFECE13C82A44E -:1018A0009AFD4DEDEF2C9C4F064C7DBB61A7D247B6 -:1018B000BB6717101ED5E6EEF5D984D245534F17F6 -:1018C0004AE4B355698FC41E2957BD99BBE43D8DC9 -:1018D000765F79B7467F41494C23E44291FC7DBD58 -:1018E000FDC05BB02BBDDDE3D81E87EACDB9F6C7DE -:1018F000A2601FFE4C7EDC1394EFFF79F11EBE67E1 -:101900009D8FF720D42E5937581EFABFBA83F33E65 -:10191000B125A81F72D830180E9523C8A37F90DD7B -:10192000F130DDB76B7A5595D75D0B3A5C85E711E1 -:10193000AC06C1AF85C021F345898C13B6C3FF1334 -:101940003DAAC7F84F719EBEDF2460C7D792FF62E1 -:10195000B82DDC8B7CC5B09FFC53ACF44FF00B551D -:1019600051DD5C9FEA6DB3F07DEF431D9F24E1FCE8 -:1019700024875C87A9EA78290EF9FB3E2D5F203F7A -:1019800018C7EF63DA3AE29077E8FDD5065F3AF0E0 -:10199000A28888E375BDBF46F5A703FF2AA53B0BC8 -:1019A000E3FBF2EDDA7C8255C082CF51AD487D1762 -:1019B0001D2ADBF350BE3DA9C92BD9852C7EDFF152 -:1019C000B2AC0FE876A042B327AFA13F53EABD5DAA -:1019D000BF57A2A515D0F721EC4342811E17AFE0F7 -:1019E000FACDE3050E096BEB795F595FE2F1DA5747 -:1019F0002E64A564629D362FD80E8D1BB02BD0FFB0 -:101A000004D6FF874C7174AECA9D8A732DEC54E9DD -:101A10009A229A2E961B571671DD4C78386F0BC59B -:101A20002B548E2617483A551A8615C606ED779E12 -:101A30006C7AC214B6337ED89D1FC53E5A843AC50F -:101A40000F4BE5BB81ABFE2658CF719E1DD28E4356 -:101A50006DAE18AE95E3E52B1AD7C70F8147289EC8 -:101A600015EEC6A238C7B5FD3ABEE76D3A7E79A637 -:101A700011C17498BFA66804B5CBADFF2C1DE479E5 -:101A8000CF7758FCF0AB15A52BD7470F2137D7F8E8 -:101A9000831D41FE2B05FCF5F2FDC6F5F00F6DAB85 -:101AA00015FF29D48B04E95533EB17E94B905FB848 -:101AB000B920A4EE50BE782CE26AE15E3C167E8628 -:101AC000F46AA17388FC920CE42803BF19F1701B1F -:101AD0008ACF5F0AE4BBA49B0BA49E6F99E90AC05E -:101AE0006ECE500D1C8787EEF765818C27BAE322F6 -:101AF000EFD7DF7380D9335449B74443FFDBD0B706 -:101B0000C4B84807EE830AF3C3E5BCC3363BEA37E3 -:101B100081C397B9BE1B783862BEBC378810236971 -:101B2000BC2B615253B01FF975A13C6F78B68C5B2A -:101B3000EA324C7FBF3E941979B53EC47143663892 -:101B4000DF97F4B67FCE7E2BD09963C7BD466F3743 -:101B50006587A44F755FFF571CFC6B6FE75FF81D2F -:101B60005AEF579FF0FBB48DDAFBC0D7DAB5F75DBB -:101B7000DD8E48F4078A3F2AC2BC4D5A3B5027905D -:101B8000F562BDD5F35FBD1E1094078F2E1C3A0F72 -:101B90008E714704D7091CF143D55582EB04A9691E -:101BA000B24E801675825493AC1300469D002DEA08 -:101BB00004E8479D0030EA04805127008C3A015A1E -:101BC000D409D0FFC57CF95E2640422CEB97116CFE -:101BD000DFEF6B56BD88CFEF3B2CEFA1EE6B54F8D7 -:101BE0009DD645FA3EFCDC35EF750E6AEF757CDB61 -:101BF000F85EAFAE4D75825575A6BE63A8EBD4B541 -:101C00002ACE35B02FF5F3F9FB1B3B73DE2D457F54 -:101C1000B3C96970804F97E250AFAAEC6CE6FA53F3 -:101C200041FC6133F3B74511A897DE6591796E8D5C -:101C30004ABD53F83E94E3E01A4B37E71F557B1536 -:101C40007B59F07DEE4D9FB11D586B8B6A029E351E -:101C50003E9BBD6C88F71F7C2FEC1057EF9B97C9FC -:101C600029A226A288EF9B97E19E995AA17E65E45E -:101C7000FB634A4C87431EF1AE2A0366DD2EF53E18 -:101C8000E43D556567EBFA4471ED3D342A03E07F8E -:101C9000E8FDB3BB3032F64C380C85988CB8A9F807 -:101CA000F1B2FD6DF4BDFEAD168E3B56E6BB97431B -:101CB0008E8E995C5C273976D8C6F9D1C7DBC60F02 -:101CC000AA937CEE725717F2FDFC68AE5BAC32292A -:101CD000EC97F38BC7C5F3BB81E326F63F1DAE92AD -:101CE0005ACC5B35C9C1F5A9428BB89FF7D1DE69E3 -:101CF00051CBFA54B856F11A085E2C9C66E8CF22F4 -:101D0000221BCB8B296203DE532D12F27D832E37EB -:101D1000ABB6291C1770A1200EF79292BE8B3AFF2A -:101D2000ED32DE2F2CB5C8F835D120EFB31337C90B -:101D3000F72D3F126E33FCED72F28B68C94FFEAE89 -:101D400087FADDE1A393647CEE88C7FE8B4F98F899 -:101D5000BD6F61FCF7D3DDECAF0BF81D83E2BF472D -:101D6000BD72C3F5F527F41DC33193B42F4447CE9C -:101D70008BBA20975C9F71737BA2BE9CDB1933A545 -:101D80009DBEFA2E91786407FEE17DEF235F4C8CB7 -:101D90008F74C2DEE97A7FCDFBC430D9EAEF13C776 -:101DA000502B82DE276E713978FF44C3C9A90ED04B -:101DB000E3AF114ED0437FA7B86566C92EF0C915B1 -:101DC000253CF82EEE51B6125D8B701005756E9F96 -:101DD0004B45DDFAB062E777D1D7D8C96D0FE31D67 -:101DE0004F5DAA62571CA8876F2D8C23BC8B529223 -:101DF00019EFBA76592F650AC5A19EAEE983CBDDEE -:101E0000563862A07F8EA617BD345FCAC92D5EC842 -:101E1000DBB7A8A33E87F91E6173366BF91AF83E4B -:101E2000E786315C4FD5E5A6BF25BE0972F346A112 -:101E3000F433A5A5EF98100774E5BA8FE2FC0BCB3D -:101E40003E7B388ECF37741D8BEC28DF4B86D6B1A6 -:101E500074BBBC5BAB83C37E1AB53AAB51ABB31A50 -:101E6000B53AAB51ABB31AB53AAB51ABB31AB53ABD -:101E7000AB51ABB31AB53AAB91EB772BB87DBB7EC8 -:101E800035B7DDF51E1E0FB2FFEF5DC7FE87D641E9 -:101E90003FC2BCD03AA8B03AA2D98F927ECBFA7397 -:101EA00048DDB378F8920D44BFFC06B3135D7A1D8C -:101EB00014EF97EF8B607B70B170C8FAA74EB7082C -:101EC000AE97F60BDB14D03F2F639CD140E37FD558 -:101ED000F8A0D71FA11F381FF4032DF4C39836A014 -:101EE0001FCF984985B3A5BFF7B0BFB7315FD7AF54 -:101EF00021FB41F052611F643F2E86D80F4A3CEE11 -:101F0000061ECB3AE5BB26FDFD661E355F4E19C2A7 -:101F10009EF8A43D1913E6DB87EF8CA90DE3F7C10A -:101F2000C7B4F758C736CA777165A284BF3B845DD2 -:101F300089023F960EEF7BFF699ABF747304C72D29 -:101F4000EB472E9BF6BFB12B9F150AA6DB6FEAFD70 -:101F5000951F132E056152FE0ACC2203F735C210DD -:101F6000C67A50A86E51703FBAEA5E31197C2EB025 -:101F700094EC009EF1DAFDB688D5EAADC6EE8A3D56 -:101F8000049F8C4B74E25E6B74C22181F74F8575A0 -:101F9000C599B08BFE31EE09453978BFBC55C1FA01 -:101FA000F04C79FE3B8AC39B205781C3E373C0EF9B -:101FB0007916471BEA00CEA284A5C8F3E7453B7219 -:101FC000500770768D9270BCA34D7122944D585A73 -:101FD000C0EFCFAC5B3FB6E2DD9A22A2E95C96612E -:101FE000EE1C7CA7A6F85399378B3EF6633717C9CA -:101FF000FC6BC46BC28F7BABBE59917C7F26321DBC -:102000003918A7B8F2BB45241F7FFC9EEB16AC4FD6 -:10201000D4F08CC72DA20AAE76DBD09ED0EEF3BAF8 -:102020000CEE52B445511E23F71BBCD968DF34F8BF -:102030007E8C7E92E722EC57F4D8E4891904275A63 -:102040007C6C273B5CAE5BB1FFAB335DC5180FAD5D -:102050009F83B7C8F3099FDB302FF41D96CECFA521 -:102060004552EECB8AA4FD98BE56DEC786F2BDACC3 -:10207000C8A0D9B7BF8F37E15B8AEFE9F88BAD8B8A -:10208000B3810FE17B2FF0247C17625C44C470BDE8 -:10209000E3FA72E6E1EF951549F9227B56F5B1B402 -:1020A00067DCA61BBDC3103F8EFA857718F01DD5DF -:1020B000D867C3BFC378D6D367837F7FF6C13E1B83 -:1020C000FA9F75C977D2A1FB3716C9F713E9D3FB7D -:1020D00078FD58FA5637C7E97DC31047A5977FBCEE -:1020E0005EDEBB64B07F19ABF997B1BF4869EF21E1 -:1020F000791BFB6434DF6F8B82581EAFB44A3DAD51 -:10210000FC45D9A1366AC76F277C83E2AF095EC25E -:102110007B505C64EC97EF2D09069DF69A1886CCEF -:1021200022BEAA11F2BDE528CD6E206E2B25BB5034 -:10213000537EF432BF03C07AEC8F3B5BC85FBB4970 -:10214000C2E4AE918F2E9FBFA68BF3C3ED57FBB5B4 -:102150007CB3753DF2678ADF06F557961DE982BFAD -:10216000A9DA3BB8BF66C5679CC752FC36A8FFDE3C -:102170001F7FC0EF6CEADA07F7137F9F029F75FE9F -:102180001E33F92620DF3B5613E694FF7EC0B712BC -:10219000FADE541DC1EF6777FD3A8FE546E737ADAC -:1021A0006FFA76F2B196E77BF24406F4E19BDA5ED1 -:1021B000D8A7B441F6C9C375BED9916C77EAB4FC0F -:1021C000AAB6CCCE7E3EB1D6CAF6AB500D7302AEE7 -:1021D000354A3B238A55CD4EF958FF4FDE3E8CEBF6 -:1021E000797C00C03193F8DD71DC5A09F78DB0B00D -:1021F0007D28349454EFA1F6A86105DB8104BCB8B6 -:1022000024BE3F03FBA0427F655DB5CEEC53E4FDE9 -:10221000BE2307F9AE7EDFD4B0D1DB7A10F9B2E28B -:102220007D7219EA8A7746F0FD4100F5463A4FC3C0 -:102230003069471B16A4B31F088892D2958843E6DD -:102240008771FDB16198E351DC2736544CE438FACC -:10225000D07F4BBFDB37D7EA441CD530D9B106EF6E -:10226000551A7EE1E0F15714B99FE751499F86B9AD -:10227000F2FC0D15319CF7E87C6868748DC4FDD4C0 -:10228000CC31EEFF00DF4769F7730DC9D44FED1372 -:102290004AC9821F619F4912DF19331DAC77C716E7 -:1022A0004C7C74B783DD891FF74475B32307E5C5FC -:1022B000FF033C759D8B10370000000000000000FC -:0822C00005020D000000000002 -:00000001FF -- cgit v1.2.3 From fb3bff178e722fe88b5ab02319c9636da0980e25 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:26:40 +0000 Subject: bnx2x: rename MF related fields MF (multi-function) mode supported not only by 57711E (E1H) devices, but also by coming 57712E, then we use more generic names. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 8 +++--- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 24 ++++++++--------- drivers/net/bnx2x/bnx2x_main.c | 56 +++++++++++++++++++-------------------- drivers/net/bnx2x/bnx2x_stats.c | 4 +-- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8b053e0c00ab..d7b24f9e7939 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -933,9 +933,9 @@ struct bnx2x { u32 vn_weight_sum; u32 mf_config; - u16 e1hov; - u8 e1hmf; -#define IS_E1HMF(bp) (bp->e1hmf != 0) + u16 mf_ov; + u8 mf_mode; +#define IS_MF(bp) (bp->mf_mode != 0) u8 wol; @@ -1127,7 +1127,7 @@ struct bnx2x { #define RSS_IPV6_CAP 0x0004 #define RSS_IPV6_TCP_CAP 0x0008 -#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ +#define BNX2X_MAX_QUEUES(bp) (IS_MF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index bcc4a8f4677b..ae05987e647e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -745,7 +745,7 @@ void bnx2x_link_report(struct bnx2x *bp) netdev_info(bp->dev, "NIC Link is Up, "); line_speed = bp->link_vars.line_speed; - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { u16 vn_max_rate; vn_max_rate = diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 56a0cb579c21..fa8f9526f93c 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -41,7 +41,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) (bp->link_vars.link_up)) { cmd->speed = bp->link_vars.line_speed; cmd->duplex = bp->link_vars.duplex; - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { u16 vn_max_rate; vn_max_rate = @@ -89,7 +89,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) struct bnx2x *bp = netdev_priv(dev); u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" @@ -1027,7 +1027,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, { struct bnx2x *bp = netdev_priv(dev); u32 cfg_idx = bnx2x_get_link_cfg_idx(bp); - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" @@ -1616,7 +1616,7 @@ static void bnx2x_self_test(struct net_device *dev, return; /* offline tests are not supported in MF mode */ - if (IS_E1HMF(bp)) + if (IS_MF(bp)) etest->flags &= ~ETH_TEST_FL_OFFLINE; is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; @@ -1808,8 +1808,8 @@ static const struct { #define IS_PORT_STAT(i) \ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) -#define IS_E1HMF_MODE_STAT(bp) \ - (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) +#define IS_MF_MODE_STAT(bp) \ + (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) static int bnx2x_get_sset_count(struct net_device *dev, int stringset) { @@ -1820,10 +1820,10 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) case ETH_SS_STATS: if (is_multi(bp)) { num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; - if (!IS_E1HMF_MODE_STAT(bp)) + if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; } else { - if (IS_E1HMF_MODE_STAT(bp)) { + if (IS_MF_MODE_STAT(bp)) { num_stats = 0; for (i = 0; i < BNX2X_NUM_STATS; i++) if (IS_FUNC_STAT(i)) @@ -1856,14 +1856,14 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) bnx2x_q_stats_arr[j].string, i); k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) break; for (j = 0; j < BNX2X_NUM_STATS; j++) strcpy(buf + (k + j)*ETH_GSTRING_LEN, bnx2x_stats_arr[j].string); } else { for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; strcpy(buf + j*ETH_GSTRING_LEN, bnx2x_stats_arr[i].string); @@ -1907,7 +1907,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) return; hw_stats = (u32 *)&bp->eth_stats; for (j = 0; j < BNX2X_NUM_STATS; j++) { @@ -1928,7 +1928,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } else { hw_stats = (u32 *)&bp->eth_stats; for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; if (bnx2x_stats_arr[i].size == 0) { /* skip this counter */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 119ca871f016..238e38f051fb 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1013,7 +1013,7 @@ void bnx2x_int_enable(struct bnx2x *bp) if (CHIP_IS_E1H(bp)) { /* init leading/trailing edge */ - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); if (bp->port.pmf) /* enable nig and gpio3 attention */ @@ -1792,7 +1792,7 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) { if (CHIP_REV_IS_SLOW(bp)) return CMNG_FNS_NONE; - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return CMNG_FNS_MINMAX; return CMNG_FNS_NONE; @@ -1906,7 +1906,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (prev_link_status != bp->link_vars.link_status) bnx2x_link_report(bp); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { int port = BP_PORT(bp); int func; int vn; @@ -2160,7 +2160,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, /* calculate queue flags */ flags |= QUEUE_FLG_CACHE_ALIGN; flags |= QUEUE_FLG_HC; - flags |= IS_E1HMF(bp) ? QUEUE_FLG_OV : 0; + flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; #ifdef BCM_VLAN flags |= QUEUE_FLG_VLAN; @@ -2262,7 +2262,7 @@ void bnx2x_pf_init(struct bnx2x *bp) /* pf specific setups */ if (!CHIP_IS_E1(bp)) - storm_memset_ov(bp, bp->e1hov, BP_FUNC(bp)); + storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); /* function setup flags */ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); @@ -3855,13 +3855,13 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) /* xstorm needs to know whether to add ovlan to packets or not, * in switch-independent we'll write 0 to here... */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - bp->e1hmf); + bp->mf_mode); } /* Zero this manually as its initialization is @@ -4418,7 +4418,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) - REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); + REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); msleep(30); @@ -4518,7 +4518,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif if (CHIP_IS_E1H(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); @@ -4596,8 +4596,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) { - REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); + REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); } if (CHIP_REV_IS_SLOW(bp)) @@ -4692,7 +4692,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) low = 0; high = 513; } else { - if (IS_E1HMF(bp)) + if (IS_MF(bp)) low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); else if (bp->dev->mtu > 4096) { if (bp->flags & ONE_PORT_FLAG) @@ -4758,7 +4758,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF * bits 4-7 are used for "per vn group attention" */ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_E1HMF(bp) ? 0xF7 : 0x7)); + (IS_MF(bp) ? 0xF7 : 0x7)); bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); @@ -4771,9 +4771,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); if (CHIP_IS_E1H(bp)) { - /* 0x2 disable e1hov, 0x1 enable */ + /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_E1HMF(bp) ? 0x1 : 0x2)); + (IS_MF(bp) ? 0x1 : 0x2)); { REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); @@ -4883,9 +4883,9 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); - REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); + REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); } bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); @@ -7189,8 +7189,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->igu_base_sb = 0; bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); - bp->e1hov = 0; - bp->e1hmf = 0; + bp->mf_ov = 0; + bp->mf_mode = 0; if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { bp->common.mf_cfg_base = bp->common.shmem_base + @@ -7202,19 +7202,19 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->e1hmf = 1; + bp->mf_mode = 1; BNX2X_DEV_INFO("%s function mode\n", - IS_E1HMF(bp) ? "multi" : "single"); + IS_MF(bp) ? "multi" : "single"); - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val = (MF_CFG_RD(bp, func_mf_config[func]. e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - bp->e1hov = val; + bp->mf_ov = val; BNX2X_DEV_INFO("E1HOV for func %d is %d " "(0x%04x)\n", - func, bp->e1hov, bp->e1hov); + func, bp->mf_ov, bp->mf_ov); } else { BNX2X_ERROR("No valid E1HOV for func %d," " aborting\n", func); @@ -7230,7 +7230,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } /* adjust igu_sb_cnt to MF */ - if (IS_E1HMF(bp)) + if (IS_MF(bp)) bp->igu_sb_cnt /= E1HVN_MAX; if (!BP_NOMCP(bp)) { @@ -7241,7 +7241,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 1256f62f7bff..c271fc52613d 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -253,7 +253,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) u32 *stats_comp = bnx2x_sp(bp, stats_comp); /* sanity */ - if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { + if (!IS_MF(bp) || !bp->port.pmf || !bp->port.port_stx) { BNX2X_ERR("BUG!\n"); return; } @@ -1284,7 +1284,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) static void bnx2x_func_stats_base_init(struct bnx2x *bp) { - int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; + int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX; int port = BP_PORT(bp); int func; u32 func_stx; -- cgit v1.2.3 From 8fe23fbd94af5a4c117fd0eb2f1c3f492f79efe8 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:27:41 +0000 Subject: bnx2x: change type of spq_left to atomic The field is now accessed from different contexts. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 +- drivers/net/bnx2x/bnx2x_main.c | 17 +++++++++-------- drivers/net/bnx2x/bnx2x_stats.c | 5 +---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index d7b24f9e7939..09fb7ff811d8 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -860,7 +860,7 @@ struct bnx2x { struct eth_spe *spq_prod_bd; struct eth_spe *spq_last_bd; __le16 *dsb_sp_prod; - u16 spq_left; /* serialize spq */ + atomic_t spq_left; /* serialize spq */ /* used to synchronize spq accesses */ spinlock_t spq_lock; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 238e38f051fb..2c04b97f85a9 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1161,8 +1161,8 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, break; } - bp->spq_left++; - + smp_mb__before_atomic_inc(); + atomic_inc(&bp->spq_left); /* push the change in fp->state and towards the memory */ smp_wmb(); @@ -2432,7 +2432,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spin_lock_bh(&bp->spq_lock); - if (!bp->spq_left) { + if (!atomic_read(&bp->spq_left)) { BNX2X_ERR("BUG! SPQ ring full!\n"); spin_unlock_bh(&bp->spq_lock); bnx2x_panic(); @@ -2472,7 +2472,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, * somewhere between the spin_lock and spin_unlock. Thus no * more explict memory barrier is needed. */ - bp->spq_left--; + atomic_dec(&bp->spq_left); DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) " @@ -2480,7 +2480,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, type, bp->spq_left); + HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left)); bnx2x_sp_prod_update(bp); spin_unlock_bh(&bp->spq_lock); @@ -3290,7 +3290,7 @@ static void bnx2x_eq_int(struct bnx2x *bp) sw_prod = bp->eq_prod; DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n", - hw_cons, sw_cons, bp->spq_left); + hw_cons, sw_cons, atomic_read(&bp->spq_left)); for (; sw_cons != hw_cons; sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) { @@ -3360,7 +3360,8 @@ next_spqe: spqe_cnt++; } /* for */ - bp->spq_left++; + smp_mb__before_atomic_inc(); + atomic_add(spqe_cnt, &bp->spq_left); bp->eq_cons = sw_cons; bp->eq_prod = sw_prod; @@ -3737,8 +3738,8 @@ void bnx2x_update_coalesce(struct bnx2x *bp) static void bnx2x_init_sp_ring(struct bnx2x *bp) { spin_lock_init(&bp->spq_lock); + atomic_set(&bp->spq_left, MAX_SPQ_PENDING); - bp->spq_left = MAX_SPQ_PENDING; bp->spq_prod_idx = 0; bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index c271fc52613d..32b6b1033a3b 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -166,11 +166,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, ((u32 *)&ramrod_data)[1], ((u32 *)&ramrod_data)[0], 1); - if (rc == 0) { - /* stats ramrod has it's own slot on the spq */ - bp->spq_left++; + if (rc == 0) bp->stats_pending = 1; - } spin_unlock_bh(&bp->stats_lock); } -- cgit v1.2.3 From f2e0899f0f275cc3f5e9c9726178d7d0ac19b2db Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:28:26 +0000 Subject: bnx2x: Add 57712 support 57712 HW supported with same set of features as for 57710/57711 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 124 ++- drivers/net/bnx2x/bnx2x_cmn.c | 275 ++++-- drivers/net/bnx2x/bnx2x_cmn.h | 137 ++- drivers/net/bnx2x/bnx2x_dump.h | 35 +- drivers/net/bnx2x/bnx2x_ethtool.c | 123 ++- drivers/net/bnx2x/bnx2x_hsi.h | 187 +++- drivers/net/bnx2x/bnx2x_init.h | 3 + drivers/net/bnx2x/bnx2x_init_ops.h | 28 +- drivers/net/bnx2x/bnx2x_link.c | 379 ++++++-- drivers/net/bnx2x/bnx2x_link.h | 6 +- drivers/net/bnx2x/bnx2x_main.c | 1777 +++++++++++++++++++++++++++--------- drivers/net/bnx2x/bnx2x_reg.h | 879 +++++++++++++++++- drivers/net/bnx2x/bnx2x_stats.c | 262 +++--- firmware/Makefile | 3 +- 14 files changed, 3428 insertions(+), 790 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 09fb7ff811d8..6f8e2666f05f 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -180,10 +180,16 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) #define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ offsetof(struct mf_cfg, field)) +#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ + offsetof(struct mf2_cfg, field)) #define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) #define MF_CFG_WR(bp, field, val) REG_WR(bp,\ MF_CFG_ADDR(bp, field), (val)) +#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field)) +#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \ + (SHMEM2_RD((bp), size) > \ + offsetof(struct shmem2_region, field))) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) @@ -296,6 +302,8 @@ union db_prod { union host_hc_status_block { /* pointer to fp status block e1x */ struct host_hc_status_block_e1x *e1x_sb; + /* pointer to fp status block e2 */ + struct host_hc_status_block_e2 *e2_sb; }; struct bnx2x_fastpath { @@ -564,12 +572,19 @@ struct bnx2x_common { #define CHIP_NUM_57710 0x164e #define CHIP_NUM_57711 0x164f #define CHIP_NUM_57711E 0x1650 +#define CHIP_NUM_57712 0x1662 +#define CHIP_NUM_57712E 0x1663 #define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710) #define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711) #define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E) +#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712) +#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E) #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ CHIP_IS_57711E(bp)) -#define IS_E1H_OFFSET CHIP_IS_E1H(bp) +#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ + CHIP_IS_57712E(bp)) +#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp))) +#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) #define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000) #define CHIP_REV_Ax 0x00000000 @@ -596,6 +611,7 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; u32 mf_cfg_base; + u32 mf2_cfg_base; u32 hw_config; @@ -603,10 +619,25 @@ struct bnx2x_common { u8 int_block; #define INT_BLOCK_HC 0 +#define INT_BLOCK_IGU 1 +#define INT_BLOCK_MODE_NORMAL 0 +#define INT_BLOCK_MODE_BW_COMP 2 +#define CHIP_INT_MODE_IS_NBC(bp) \ + (CHIP_IS_E2(bp) && \ + !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP)) +#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp)) + u8 chip_port_mode; +#define CHIP_4_PORT_MODE 0x0 +#define CHIP_2_PORT_MODE 0x1 #define CHIP_PORT_MODE_NONE 0x2 +#define CHIP_MODE(bp) (bp->common.chip_port_mode) +#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE) }; +/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */ +#define BNX2X_IGU_STAS_MSG_VF_CNT 64 +#define BNX2X_IGU_STAS_MSG_PF_CNT 4 /* end of common */ @@ -670,7 +701,7 @@ enum { */ #define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ -#define MAX_CONTEXT FP_SB_MAX_E1x +#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */ /* * cid_cnt paramter below refers to the value returned by @@ -754,7 +785,7 @@ struct bnx2x_slowpath { #define MAX_DYNAMIC_ATTN_GRPS 8 struct attn_route { - u32 sig[4]; + u32 sig[5]; }; struct iro { @@ -896,13 +927,20 @@ struct bnx2x { #define HW_VLAN_RX_FLAG 0x800 #define MF_FUNC_DIS 0x1000 - int func; + int pf_num; /* absolute PF number */ + int pfid; /* per-path PF number */ int base_fw_ndsb; - -#define BP_PORT(bp) (bp->func % PORT_MAX) -#define BP_FUNC(bp) (bp->func) -#define BP_E1HVN(bp) (bp->func >> 1) +#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \ + 0 : (bp->pf_num & 1)) +#define BP_PORT(bp) (bp->pfid & 1) +#define BP_FUNC(bp) (bp->pfid) +#define BP_ABS_FUNC(bp) (bp->pf_num) +#define BP_E1HVN(bp) (bp->pfid >> 1) +#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \ + 0 : BP_E1HVN(bp)) #define BP_L_ID(bp) (BP_E1HVN(bp) << 2) +#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ + BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) #ifdef BCM_CNIC #define BCM_CNIC_CID_START 16 @@ -932,7 +970,8 @@ struct bnx2x { struct cmng_struct_per_port cmng; u32 vn_weight_sum; - u32 mf_config; + u32 mf_config[E1HVN_MAX]; + u32 mf2_config[E2_FUNC_MAX]; u16 mf_ov; u8 mf_mode; #define IS_MF(bp) (bp->mf_mode != 0) @@ -1127,11 +1166,11 @@ struct bnx2x { #define RSS_IPV6_CAP 0x0004 #define RSS_IPV6_TCP_CAP 0x0008 -#define BNX2X_MAX_QUEUES(bp) (IS_MF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ - : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) +#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) +#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) #define RSS_IPV4_CAP_MASK \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY @@ -1342,14 +1381,40 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, /* DMAE command defines */ -#define DMAE_CMD_SRC_PCI 0 -#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC +#define DMAE_TIMEOUT -1 +#define DMAE_PCI_ERROR -2 /* E2 and onward */ +#define DMAE_NOT_RDY -3 +#define DMAE_PCI_ERR_FLAG 0x80000000 + +#define DMAE_SRC_PCI 0 +#define DMAE_SRC_GRC 1 + +#define DMAE_DST_NONE 0 +#define DMAE_DST_PCI 1 +#define DMAE_DST_GRC 2 + +#define DMAE_COMP_PCI 0 +#define DMAE_COMP_GRC 1 + +/* E2 and onward - PCI error handling in the completion */ + +#define DMAE_COMP_REGULAR 0 +#define DMAE_COM_SET_ERR 1 -#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT) -#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \ + DMAE_COMMAND_SRC_SHIFT) +#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \ + DMAE_COMMAND_SRC_SHIFT) -#define DMAE_CMD_C_DST_PCI 0 -#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \ + DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \ + DMAE_COMMAND_DST_SHIFT) + +#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \ + DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \ + DMAE_COMMAND_C_DST_SHIFT) #define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE @@ -1365,10 +1430,20 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET #define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT +#define DMAE_SRC_PF 0 +#define DMAE_SRC_VF 1 + +#define DMAE_DST_PF 0 +#define DMAE_DST_VF 1 + +#define DMAE_C_SRC 0 +#define DMAE_C_DST 1 + #define DMAE_LEN32_RD_MAX 0x80 #define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000) -#define DMAE_COMP_VAL 0xe0d0d0ae +#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit + indicates eror */ #define MAX_DMAE_C_PER_PORT 8 #define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ @@ -1534,6 +1609,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define GET_FLAG(value, mask) \ (((value) &= (mask)) >> (mask##_SHIFT)) +#define GET_FIELD(value, fname) \ + (((value) & (fname##_MASK)) >> (fname##_SHIFT)) + #define CAM_IS_INVALID(x) \ (GET_FLAG(x.flags, \ MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ @@ -1553,6 +1631,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0 #endif +#ifndef ETH_MAX_RX_CLIENTS_E2 +#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H +#endif #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 @@ -1570,13 +1651,18 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_EXTERN extern #endif -BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */ +BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ /* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type); + #define WAIT_RAMROD_POLL 0x01 #define WAIT_RAMROD_COMMON 0x02 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ae05987e647e..cffa778ec5bf 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include "bnx2x_cmn.h" @@ -118,16 +118,10 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) pkt_cons = TX_BD(sw_cons); - /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */ + DP(NETIF_MSG_TX_DONE, "queue[%d]: hw_cons %u sw_cons %u " + " pkt_cons %u\n", + fp->index, hw_cons, sw_cons, pkt_cons); - DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n", - hw_cons, sw_cons, pkt_cons); - -/* if (NEXT_TX_IDX(sw_cons) != hw_cons) { - rmb(); - prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb); - } -*/ bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); sw_cons++; } @@ -749,8 +743,9 @@ void bnx2x_link_report(struct bnx2x *bp) u16 vn_max_rate; vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; if (vn_max_rate < line_speed) line_speed = vn_max_rate; } @@ -912,14 +907,15 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) if (j != 0) continue; - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, - U64_HI(fp->rx_comp_mapping)); + if (!CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, + U64_HI(fp->rx_comp_mapping)); + } } - } static void bnx2x_free_tx_skbs(struct bnx2x *bp) { @@ -1308,23 +1304,27 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } else { + int path = BP_PATH(bp); int port = BP_PORT(bp); - DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]++; - load_count[1 + port]++; - DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 1) + DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + load_count[path][0]++; + load_count[path][1 + port]++; + DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + if (load_count[path][0] == 1) load_code = FW_MSG_CODE_DRV_LOAD_COMMON; - else if (load_count[1 + port] == 1) + else if (load_count[path][1 + port] == 1) load_code = FW_MSG_CODE_DRV_LOAD_PORT; else load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; } if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) bp->port.pmf = 1; else @@ -1349,7 +1349,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) && + if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) && (bp->common.shmem2_base)) SHMEM2_WR(bp, dcc_support, (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | @@ -1389,11 +1390,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif } - if (CHIP_IS_E1H(bp)) - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; - } + if (!CHIP_IS_E1(bp) && + (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED)) { + DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + } #ifdef BCM_CNIC /* Enable Timer scan */ @@ -1527,8 +1528,10 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); + /* Stop Tx */ + bnx2x_tx_disable(bp); del_timer_sync(&bp->timer); - SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1855,6 +1858,120 @@ exit_lbl: } #endif +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + if ((xmit_type & XMIT_GSO_V6) && + (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) + pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; +} + +/** + * Update PBD in GSO case. + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + */ +static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd->tcp_flags = pbd_tcp_flags(skb); + + if (xmit_type & XMIT_GSO_V4) { + pbd->ip_id = swab16(ip_hdr(skb)->id); + pbd->tcp_pseudo_csum = + swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + } else + pbd->tcp_pseudo_csum = + swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; +} +/** + * + * @param skb + * @param tx_start_bd + * @param pbd_e2 + * @param xmit_type + * + * @return header len + */ +static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + + pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - + skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + + return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; +} + +/** + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + * + * @return Header length + */ +static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + u8 hlen = (skb_network_header(skb) - skb->data) / 2; + + /* for now NS flag is not used in Linux */ + pbd->global_data = + (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << + ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); + + pbd->ip_hlen_w = (skb_transport_header(skb) - + skb_network_header(skb)) / 2; + + hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; + + pbd->total_hlen_w = cpu_to_le16(hlen); + hlen = hlen*2; + + if (xmit_type & XMIT_CSUM_TCP) { + pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); + + } else { + s8 fix = SKB_CS_OFF(skb); /* signed! */ + + DP(NETIF_MSG_TX_QUEUED, + "hlen %d fix %d csum before fix %x\n", + le16_to_cpu(pbd->total_hlen_w), fix, SKB_CS(skb)); + + /* HW bug: fixup the CSUM */ + pbd->tcp_pseudo_csum = + bnx2x_csum_fix(skb_transport_header(skb), + SKB_CS(skb), fix); + + DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", + pbd->tcp_pseudo_csum); + } + + return hlen; +} /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -1868,6 +1985,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -1895,9 +2013,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)" - " gso type %x xmit_type %x\n", - skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, + DP(NETIF_MSG_TX_QUEUED, "queue[%d]: SKB: summed %x protocol %x " + "protocol(%x,%x) gso type %x xmit_type %x\n", + fp_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); eth = (struct ethhdr *)skb->data; @@ -1988,44 +2106,21 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP; } - pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; - memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); - /* Set PBD in checksum offload case */ - if (xmit_type & XMIT_CSUM) { - hlen = (skb_network_header(skb) - skb->data) / 2; - /* for now NS flag is not used in Linux */ - pbd_e1x->global_data = - (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); - - pbd_e1x->ip_hlen_w = (skb_transport_header(skb) - - skb_network_header(skb)) / 2; - - hlen += pbd_e1x->ip_hlen_w + tcp_hdrlen(skb) / 2; - - pbd_e1x->total_hlen_w = cpu_to_le16(hlen); - hlen = hlen*2; - - if (xmit_type & XMIT_CSUM_TCP) { - pbd_e1x->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); - - } else { - s8 fix = SKB_CS_OFF(skb); /* signed! */ - - DP(NETIF_MSG_TX_QUEUED, - "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd_e1x->total_hlen_w), - fix, SKB_CS(skb)); - - /* HW bug: fixup the CSUM */ - pbd_e1x->tcp_pseudo_csum = - bnx2x_csum_fix(skb_transport_header(skb), - SKB_CS(skb), fix); + if (CHIP_IS_E2(bp)) { + pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum_e2(bp, + skb, pbd_e2, xmit_type); + } else { + pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type); - DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd_e1x->tcp_pseudo_csum); - } } mapping = dma_map_single(&bp->pdev->dev, skb->data, @@ -2057,26 +2152,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb_headlen(skb) > hlen)) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - - pbd_e1x->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd_e1x->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd_e1x->tcp_flags = pbd_tcp_flags(skb); - - if (xmit_type & XMIT_GSO_V4) { - pbd_e1x->ip_id = swab16(ip_hdr(skb)->id); - pbd_e1x->tcp_pseudo_csum = - swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - } else - pbd_e1x->tcp_pseudo_csum = - swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - pbd_e1x->global_data |= - ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; + if (CHIP_IS_E2(bp)) + bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + else + bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; @@ -2124,7 +2203,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags, pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq, le16_to_cpu(pbd_e1x->total_hlen_w)); - + if (pbd_e2) + DP(NETIF_MSG_TX_QUEUED, + "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n", + pbd_e2, pbd_e2->dst_mac_addr_hi, pbd_e2->dst_mac_addr_mid, + pbd_e2->dst_mac_addr_lo, pbd_e2->src_mac_addr_hi, + pbd_e2->src_mac_addr_mid, pbd_e2->src_mac_addr_lo, + pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); /* @@ -2327,6 +2412,8 @@ int bnx2x_resume(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); + /* Since the chip was reset, clear the FW sequence number */ + bp->fw_seq = 0; rc = bnx2x_nic_load(bp, LOAD_OPEN); rtnl_unlock(); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 2fb9045833e1..41d0a177db7f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -366,10 +366,77 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, fp->index, bd_prod, rx_comp_prod, rx_sge_prod); } +static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, + u8 segment, u16 index, u8 op, + u8 update, u32 igu_addr) +{ + struct igu_regular cmd_data = {0}; + + cmd_data.sb_id_and_flags = + ((index << IGU_REGULAR_SB_INDEX_SHIFT) | + (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | + (update << IGU_REGULAR_BUPDATE_SHIFT) | + (op << IGU_REGULAR_ENABLE_INT_SHIFT)); + DP(NETIF_MSG_HW, "write 0x%08x to IGU addr 0x%x\n", + cmd_data.sb_id_and_flags, igu_addr); + REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags); + + /* Make sure that ACK is written */ + mmiowb(); + barrier(); +} -static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, - u8 storm, u16 index, u8 op, u8 update) +static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, + u8 idu_sb_id, bool is_Pf) +{ + u32 data, ctl, cnt = 100; + u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA; + u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; + u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; + u32 sb_bit = 1 << (idu_sb_id%32); + u32 func_encode = BP_FUNC(bp) | + ((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT); + u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; + + /* Not supported in BC mode */ + if (CHIP_INT_MODE_IS_BC(bp)) + return; + + data = (IGU_USE_REGISTER_cstorm_type_0_sb_cleanup + << IGU_REGULAR_CLEANUP_TYPE_SHIFT) | + IGU_REGULAR_CLEANUP_SET | + IGU_REGULAR_BCLEANUP; + + ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT | + func_encode << IGU_CTRL_REG_FID_SHIFT | + IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT; + + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + data, igu_addr_data); + REG_WR(bp, igu_addr_data, data); + mmiowb(); + barrier(); + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + ctl, igu_addr_ctl); + REG_WR(bp, igu_addr_ctl, ctl); + mmiowb(); + barrier(); + + /* wait for clean up to finish */ + while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt) + msleep(20); + + + if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) { + DP(NETIF_MSG_HW, "Unable to finish IGU cleanup: " + "idu_sb_id %d offset %d bit %d (cnt %d)\n", + idu_sb_id, idu_sb_id/32, idu_sb_id%32, cnt); + } +} + +static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id, + u8 storm, u16 index, u8 op, u8 update) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_INT_ACK); @@ -390,7 +457,37 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, mmiowb(); barrier(); } -static inline u16 bnx2x_ack_int(struct bnx2x *bp) + +static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; + + bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, + igu_addr); +} + +static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm, + u16 index, u8 op, u8 update) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update); + else { + u8 segment; + + if (CHIP_INT_MODE_IS_BC(bp)) + segment = storm; + else if (igu_sb_id != bp->igu_dsb_id) + segment = IGU_SEG_ACCESS_DEF; + else if (storm == ATTENTION_ID) + segment = IGU_SEG_ACCESS_ATTN; + else + segment = IGU_SEG_ACCESS_DEF; + bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update); + } +} + +static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_SIMD_MASK); @@ -399,13 +496,34 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n", result, hc_addr); + barrier(); + return result; +} + +static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp) +{ + u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8); + u32 result = REG_RD(bp, igu_addr); + + DP(NETIF_MSG_HW, "read 0x%08x from IGU addr 0x%x\n", + result, igu_addr); + + barrier(); return result; } +static inline u16 bnx2x_ack_int(struct bnx2x *bp) +{ + barrier(); + if (bp->common.int_block == INT_BLOCK_HC) + return bnx2x_hc_ack_int(bp); + else + return bnx2x_igu_ack_int(bp); +} + /* * fast path service functions */ - static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ @@ -456,6 +574,17 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) rx_cons_sb++; return (fp->rx_comp_cons != rx_cons_sb); } +/** + * disables tx from stack point of view + * + * @param bp + */ +static inline void bnx2x_tx_disable(struct bnx2x *bp) +{ + netif_tx_disable(bp->dev); + netif_carrier_off(bp->dev); +} + static inline void bnx2x_free_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index 3bb9a91bb3f7..dc18c25ca9e5 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -31,14 +31,24 @@ struct dump_sign { #define RI_E1 0x1 #define RI_E1H 0x2 +#define RI_E2 0x4 #define RI_ONLINE 0x100 - +#define RI_PATH0_DUMP 0x200 +#define RI_PATH1_DUMP 0x400 #define RI_E1_OFFLINE (RI_E1) #define RI_E1_ONLINE (RI_E1 | RI_ONLINE) #define RI_E1H_OFFLINE (RI_E1H) #define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E2_OFFLINE (RI_E2) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) +#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) +#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) +#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) +#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) +#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) #define MAX_TIMER_PENDING 200 #define TIMER_SCAN_DONT_CARE 0xFF @@ -513,6 +523,12 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } }; +#define WREGS_COUNT_E2 1 +static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; + +static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { + { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } +}; static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 }; @@ -531,4 +547,17 @@ static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { 0x1640d0, 0x1640d4 }; +#define PAGE_MODE_VALUES_E2 2 + +#define PAGE_READ_REGS_E2 1 + +#define PAGE_WRITE_REGS_E2 1 + +static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 }; + +static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 }; + +static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = { + { 0x58000, 4608, RI_E2_ONLINE } }; + #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index fa8f9526f93c..8fb00276dc41 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -41,19 +41,19 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) (bp->link_vars.link_up)) { cmd->speed = bp->link_vars.line_speed; cmd->duplex = bp->link_vars.duplex; - if (IS_MF(bp)) { - u16 vn_max_rate; - - vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } } else { + cmd->speed = bp->link_params.req_line_speed[cfg_idx]; cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } + if (IS_MF(bp)) { + u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * + 100; + + if (vn_max_rate < cmd->speed) + cmd->speed = vn_max_rate; + } if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; @@ -298,6 +298,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) #define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) #define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) +#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE) static int bnx2x_get_regs_len(struct net_device *dev) { @@ -315,7 +316,7 @@ static int bnx2x_get_regs_len(struct net_device *dev) regdump_len += wreg_addrs_e1[i].size * (1 + wreg_addrs_e1[i].read_regs_count); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) regdump_len += reg_addrs[i].size; @@ -324,6 +325,15 @@ static int bnx2x_get_regs_len(struct net_device *dev) if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) regdump_len += wreg_addrs_e1h[i].size * (1 + wreg_addrs_e1h[i].read_regs_count); + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + regdump_len += reg_addrs[i].size; + + for (i = 0; i < WREGS_COUNT_E2; i++) + if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) + regdump_len += wreg_addrs_e2[i].size * + (1 + wreg_addrs_e2[i].read_regs_count); } regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); @@ -331,6 +341,23 @@ static int bnx2x_get_regs_len(struct net_device *dev) return regdump_len; } +static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p) +{ + u32 i, j, k, n; + + for (i = 0; i < PAGE_MODE_VALUES_E2; i++) { + for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { + REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]); + for (k = 0; k < PAGE_READ_REGS_E2; k++) + if (IS_E2_ONLINE(page_read_regs_e2[k].info)) + for (n = 0; n < + page_read_regs_e2[k].size; n++) + *p++ = REG_RD(bp, + page_read_regs_e2[k].addr + n*4); + } + } +} + static void bnx2x_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { @@ -350,7 +377,14 @@ static void bnx2x_get_regs(struct net_device *dev, dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); - dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; + + if (CHIP_IS_E1(bp)) + dump_hdr.info = RI_E1_ONLINE; + else if (CHIP_IS_E1H(bp)) + dump_hdr.info = RI_E1H_ONLINE; + else if (CHIP_IS_E2(bp)) + dump_hdr.info = RI_E2_ONLINE | + (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP); memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); p += dump_hdr.hdr_size + 1; @@ -362,16 +396,25 @@ static void bnx2x_get_regs(struct net_device *dev, *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) for (j = 0; j < reg_addrs[i].size; j++) *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); + + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, + reg_addrs[i].addr + j*4); + + bnx2x_read_pages_regs_e2(bp, p); } } -#define PHY_FW_VER_LEN 10 +#define PHY_FW_VER_LEN 20 static void bnx2x_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -474,7 +517,7 @@ static u32 bnx2x_get_link(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); - if (bp->flags & MF_FUNC_DIS) + if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN)) return 0; return bp->link_vars.link_up; @@ -1235,6 +1278,9 @@ static int bnx2x_test_registers(struct bnx2x *bp) for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { u32 offset, mask, save_val, val; + if (CHIP_IS_E2(bp) && + reg_tbl[i].offset0 == HC_REG_AGG_INT_0) + continue; offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; mask = reg_tbl[i].mask; @@ -1286,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp) u32 offset; u32 e1_mask; u32 e1h_mask; + u32 e2_mask; } prty_tbl[] = { - { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, - { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, - { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, - { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, - { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, - { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, - - { NULL, 0xffffffff, 0, 0 } + { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 }, + { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 }, + { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 }, + + { NULL, 0xffffffff, 0, 0, 0 } }; if (!netif_running(bp->dev)) return rc; + /* pre-Check the parity status */ + for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { + val = REG_RD(bp, prty_tbl[i].offset); + if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { + DP(NETIF_MSG_HW, + "%s is 0x%x\n", prty_tbl[i].name, val); + goto test_mem_exit; + } + } + /* Go through all the memories */ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) for (j = 0; j < mem_tbl[i].size; j++) @@ -1309,7 +1368,8 @@ static int bnx2x_test_memory(struct bnx2x *bp) for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { val = REG_RD(bp, prty_tbl[i].offset); if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { DP(NETIF_MSG_HW, "%s is 0x%x\n", prty_tbl[i].name, val); goto test_mem_exit; @@ -1324,7 +1384,7 @@ test_mem_exit: static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { - int cnt = 1000; + int cnt = 1400; if (link_up) while (bnx2x_link_test(bp, is_serdes) && cnt--) @@ -1343,7 +1403,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) u16 pkt_prod, bd_prod; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; u8 cqe_fp_flags; @@ -1411,7 +1472,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; + pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); @@ -1431,6 +1494,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) if (tx_idx != tx_start_idx + num_pkts) goto test_loopback_exit; + /* Unlike HC IGU won't generate an interrupt for status block + * updates that have been performed while interrupts were + * disabled. + */ + if (bp->common.int_block == INT_BLOCK_IGU) + bnx2x_tx_int(fp_tx); + rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) goto test_loopback_exit; @@ -1573,8 +1643,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) config->hdr.length = 0; if (CHIP_IS_E1(bp)) - /* use last unicast entries */ - config->hdr.offset = (BP_PORT(bp) ? 63 : 31); + config->hdr.offset = (BP_PORT(bp) ? 32 : 0); else config->hdr.offset = BP_FUNC(bp); config->hdr.client_id = bp->fp->cl_id; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 596041cbd977..18c8e23a0e82 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -663,6 +663,7 @@ struct shm_dev_info { /* size */ #define FUNC_7 7 #define E1_FUNC_MAX 2 #define E1H_FUNC_MAX 8 +#define E2_FUNC_MAX 4 /* per path */ #define VN_0 0 #define VN_1 1 @@ -821,6 +822,9 @@ struct drv_func_mb { #define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 #define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 #define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 + /* Load common chip is supported from bc 6.0.0 */ +#define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000 +#define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000 #define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 #define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 #define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 @@ -1026,7 +1030,17 @@ struct shmem_region { /* SharedMem Offset (size) */ }; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ +struct fw_flr_ack { + u32 pf_ack; + u32 vf_ack[1]; + u32 iov_dis_ack; +}; +struct fw_flr_mb { + u32 aggint; + u32 opgen_addr; + struct fw_flr_ack ack; +}; struct shmem2_region { @@ -1046,7 +1060,20 @@ struct shmem2_region { * For backwards compatibility, if the mf_cfg_addr does not exist * (the size filed is smaller than 0xc) the mf_cfg resides at the * end of struct shmem_region + */ + u32 mf_cfg_addr; +#define SHMEM_MF_CFG_ADDR_NONE 0x00000000 + + struct fw_flr_mb flr_mb; + u32 reserved[3]; + /* + * The other shmemX_base_addr holds the other path's shmem address + * required for example in case of common phy init, or for path1 to know + * the address of mcp debug trace which is located in offset from shmem + * of path0 */ + u32 other_shmem_base_addr; + u32 other_shmem2_base_addr; }; @@ -1206,10 +1233,126 @@ struct bmac1_stats { u32 rx_stat_gripj_hi; }; +struct bmac2_stats { + u32 tx_stat_gtpk_lo; /* gtpok */ + u32 tx_stat_gtpk_hi; /* gtpok */ + u32 tx_stat_gtxpf_lo; /* gtpf */ + u32 tx_stat_gtxpf_hi; /* gtpf */ + u32 tx_stat_gtpp_lo; /* NEW BMAC2 */ + u32 tx_stat_gtpp_hi; /* NEW BMAC2 */ + u32 tx_stat_gtfcs_lo; + u32 tx_stat_gtfcs_hi; + u32 tx_stat_gtuca_lo; /* NEW BMAC2 */ + u32 tx_stat_gtuca_hi; /* NEW BMAC2 */ + u32 tx_stat_gtmca_lo; + u32 tx_stat_gtmca_hi; + u32 tx_stat_gtbca_lo; + u32 tx_stat_gtbca_hi; + u32 tx_stat_gtovr_lo; + u32 tx_stat_gtovr_hi; + u32 tx_stat_gtfrg_lo; + u32 tx_stat_gtfrg_hi; + u32 tx_stat_gtpkt1_lo; /* gtpkt */ + u32 tx_stat_gtpkt1_hi; /* gtpkt */ + u32 tx_stat_gt64_lo; + u32 tx_stat_gt64_hi; + u32 tx_stat_gt127_lo; + u32 tx_stat_gt127_hi; + u32 tx_stat_gt255_lo; + u32 tx_stat_gt255_hi; + u32 tx_stat_gt511_lo; + u32 tx_stat_gt511_hi; + u32 tx_stat_gt1023_lo; + u32 tx_stat_gt1023_hi; + u32 tx_stat_gt1518_lo; + u32 tx_stat_gt1518_hi; + u32 tx_stat_gt2047_lo; + u32 tx_stat_gt2047_hi; + u32 tx_stat_gt4095_lo; + u32 tx_stat_gt4095_hi; + u32 tx_stat_gt9216_lo; + u32 tx_stat_gt9216_hi; + u32 tx_stat_gt16383_lo; + u32 tx_stat_gt16383_hi; + u32 tx_stat_gtmax_lo; + u32 tx_stat_gtmax_hi; + u32 tx_stat_gtufl_lo; + u32 tx_stat_gtufl_hi; + u32 tx_stat_gterr_lo; + u32 tx_stat_gterr_hi; + u32 tx_stat_gtbyt_lo; + u32 tx_stat_gtbyt_hi; + + u32 rx_stat_gr64_lo; + u32 rx_stat_gr64_hi; + u32 rx_stat_gr127_lo; + u32 rx_stat_gr127_hi; + u32 rx_stat_gr255_lo; + u32 rx_stat_gr255_hi; + u32 rx_stat_gr511_lo; + u32 rx_stat_gr511_hi; + u32 rx_stat_gr1023_lo; + u32 rx_stat_gr1023_hi; + u32 rx_stat_gr1518_lo; + u32 rx_stat_gr1518_hi; + u32 rx_stat_gr2047_lo; + u32 rx_stat_gr2047_hi; + u32 rx_stat_gr4095_lo; + u32 rx_stat_gr4095_hi; + u32 rx_stat_gr9216_lo; + u32 rx_stat_gr9216_hi; + u32 rx_stat_gr16383_lo; + u32 rx_stat_gr16383_hi; + u32 rx_stat_grmax_lo; + u32 rx_stat_grmax_hi; + u32 rx_stat_grpkt_lo; + u32 rx_stat_grpkt_hi; + u32 rx_stat_grfcs_lo; + u32 rx_stat_grfcs_hi; + u32 rx_stat_gruca_lo; + u32 rx_stat_gruca_hi; + u32 rx_stat_grmca_lo; + u32 rx_stat_grmca_hi; + u32 rx_stat_grbca_lo; + u32 rx_stat_grbca_hi; + u32 rx_stat_grxpf_lo; /* grpf */ + u32 rx_stat_grxpf_hi; /* grpf */ + u32 rx_stat_grpp_lo; + u32 rx_stat_grpp_hi; + u32 rx_stat_grxuo_lo; /* gruo */ + u32 rx_stat_grxuo_hi; /* gruo */ + u32 rx_stat_grjbr_lo; + u32 rx_stat_grjbr_hi; + u32 rx_stat_grovr_lo; + u32 rx_stat_grovr_hi; + u32 rx_stat_grxcf_lo; /* grcf */ + u32 rx_stat_grxcf_hi; /* grcf */ + u32 rx_stat_grflr_lo; + u32 rx_stat_grflr_hi; + u32 rx_stat_grpok_lo; + u32 rx_stat_grpok_hi; + u32 rx_stat_grmeg_lo; + u32 rx_stat_grmeg_hi; + u32 rx_stat_grmeb_lo; + u32 rx_stat_grmeb_hi; + u32 rx_stat_grbyt_lo; + u32 rx_stat_grbyt_hi; + u32 rx_stat_grund_lo; + u32 rx_stat_grund_hi; + u32 rx_stat_grfrg_lo; + u32 rx_stat_grfrg_hi; + u32 rx_stat_grerb_lo; /* grerrbyt */ + u32 rx_stat_grerb_hi; /* grerrbyt */ + u32 rx_stat_grfre_lo; /* grfrerr */ + u32 rx_stat_grfre_hi; /* grfrerr */ + u32 rx_stat_gripj_lo; + u32 rx_stat_gripj_hi; +}; union mac_stats { - struct emac_stats emac_stats; - struct bmac1_stats bmac1_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; + struct bmac2_stats bmac2_stats; }; @@ -1593,6 +1736,24 @@ union igu_consprod_reg { }; +/* + * Control register for the IGU command register + */ +struct igu_ctrl_reg { + u32 ctrl_data; +#define IGU_CTRL_REG_ADDRESS (0xFFF<<0) +#define IGU_CTRL_REG_ADDRESS_SHIFT 0 +#define IGU_CTRL_REG_FID (0x7F<<12) +#define IGU_CTRL_REG_FID_SHIFT 12 +#define IGU_CTRL_REG_RESERVED (0x1<<19) +#define IGU_CTRL_REG_RESERVED_SHIFT 19 +#define IGU_CTRL_REG_TYPE (0x1<<20) +#define IGU_CTRL_REG_TYPE_SHIFT 20 +#define IGU_CTRL_REG_UNUSED (0x7FF<<21) +#define IGU_CTRL_REG_UNUSED_SHIFT 21 +}; + + /* * Parser parsing flags field */ @@ -1923,6 +2084,27 @@ struct eth_tx_parse_bd_e1x { __le32 tcp_send_seq; }; +/* + * Tx parsing BD structure for ETH E2 + */ +struct eth_tx_parse_bd_e2 { + __le16 dst_mac_addr_lo; + __le16 dst_mac_addr_mid; + __le16 dst_mac_addr_hi; + __le16 src_mac_addr_lo; + __le16 src_mac_addr_mid; + __le16 src_mac_addr_hi; + __le32 parsing_data; +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13 +#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17) +#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17 +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31) +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31 +}; + /* * The last BD in the BD memory will hold a pointer to the next BD memory */ @@ -1939,6 +2121,7 @@ union eth_tx_bd_types { struct eth_tx_start_bd start_bd; struct eth_tx_bd reg_bd; struct eth_tx_parse_bd_e1x parse_bd_e1x; + struct eth_tx_parse_bd_e2 parse_bd_e2; struct eth_tx_next_bd next_bd; }; diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5ae22e085518..a9d54874a559 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -97,6 +97,9 @@ #define MISC_AEU_BLOCK 35 #define PGLUE_B_BLOCK 36 #define IGU_BLOCK 37 +#define ATC_BLOCK 38 +#define QM_4PORT_BLOCK 39 +#define XSEM_4PORT_BLOCK 40 /* Returns the index of start or end of a specific block stage in ops array*/ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index aae7fea00622..e65de784182c 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -486,18 +486,30 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); - if (r_order == MAX_RD_ORD) + if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD)) REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); - REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order)); + else + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); - if (CHIP_IS_E1H(bp)) { + if (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) { /* MPS w_order optimal TH presently TH * 128 0 0 2 * 256 1 1 3 * >=512 2 2 3 */ - val = ((w_order == 0) ? 2 : 3); + /* DMAE is special */ + if (CHIP_IS_E2(bp)) { + /* E2 can use optimal TH */ + val = w_order; + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val); + } else { + val = ((w_order == 0) ? 2 : 3); + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); + } + REG_WR(bp, PXP2_REG_WR_HC_MPS, val); REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); @@ -507,9 +519,15 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_WR_TM_MPS, val); REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); - REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); } + + /* Validate number of tags suppoted by device */ +#define PCIE_REG_PCIER_TL_HDR_FC_ST 0x2980 + val = REG_RD(bp, PCIE_REG_PCIER_TL_HDR_FC_ST); + val &= 0xFF; + if (val <= 0x20) + REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x20); } /**************************************************************************** diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 51d468d430ee..3e99bf9c42b9 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -377,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params, return 0; } +static void bnx2x_update_bmac2(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + /* + * Set rx control: Strip CRC and enable BigMAC to relay + * control packets to the system as well + */ + u32 wb_data[2]; + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 val = 0x14; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + /* Enable BigMAC to react on received Pause packets */ + val |= (1<<5); + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, + wb_data, 2); + udelay(30); -static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, + /* Tx control */ + val = 0xc0; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + val |= 0x800000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, + wb_data, 2); + + val = 0x8000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, + wb_data, 2); + + /* mac control */ + val = 0x3; /* Enable RX and TX */ + if (is_lb) { + val |= 0x4; /* Local loopback */ + DP(NETIF_MSG_LINK, "enable bmac loopback\n"); + } + + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); +} + + +static u8 bnx2x_bmac1_enable(struct link_params *params, + struct link_vars *vars, u8 is_lb) { struct bnx2x *bp = params->bp; @@ -389,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, u32 wb_data[2]; u32 val; - DP(NETIF_MSG_LINK, "Enabling BigMAC\n"); - /* reset and unreset the BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - msleep(1); - - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - - /* enable access for bmac registers */ - REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + DP(NETIF_MSG_LINK, "Enabling BigMAC1\n"); /* XGXS control */ wb_data[0] = 0x3c; @@ -479,6 +520,103 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, wb_data, 2); } + + return 0; +} + +static u8 bnx2x_bmac2_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_data[2]; + + DP(NETIF_MSG_LINK, "Enabling BigMAC2\n"); + + wb_data[0] = 0; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + udelay(30); + + /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */ + wb_data[0] = 0x3c; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, + wb_data, 2); + + udelay(30); + + /* tx MAC SA */ + wb_data[0] = ((params->mac_addr[2] << 24) | + (params->mac_addr[3] << 16) | + (params->mac_addr[4] << 8) | + params->mac_addr[5]); + wb_data[1] = ((params->mac_addr[0] << 8) | + params->mac_addr[1]); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR, + wb_data, 2); + + udelay(30); + + /* Configure SAFC */ + wb_data[0] = 0x1000200; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS, + wb_data, 2); + udelay(30); + + /* set rx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, + wb_data, 2); + udelay(30); + + /* set tx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, + wb_data, 2); + udelay(30); + /* set cnt max size */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, + wb_data, 2); + udelay(30); + bnx2x_update_bmac2(params, vars, is_lb); + + return 0; +} + +u8 bnx2x_bmac_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + u8 rc, port = params->port; + struct bnx2x *bp = params->bp; + u32 val; + /* reset and unreset the BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + udelay(10); + + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + + /* enable access for bmac registers */ + REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + + /* Enable BMAC according to BMAC type*/ + if (CHIP_IS_E2(bp)) + rc = bnx2x_bmac2_enable(params, vars, is_lb); + else + rc = bnx2x_bmac1_enable(params, vars, is_lb); REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); @@ -493,7 +631,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); vars->mac_type = MAC_TYPE_BMAC; - return 0; + return rc; } @@ -519,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && nig_bmac_enable) { - /* Clear Rx Enable bit in BMAC_CONTROL register */ - REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - + if (CHIP_IS_E2(bp)) { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + } else { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + } msleep(1); } } @@ -821,23 +971,31 @@ u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, return -EINVAL; } -static void bnx2x_set_aer_mmd(struct link_params *params, - struct bnx2x_phy *phy) +static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, + struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; u32 ser_lane; - u16 offset; - + u16 offset, aer_val; + struct bnx2x *bp = params->bp; ser_lane = ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? - (phy->addr + ser_lane) : 0; - + offset = phy->addr + ser_lane; + if (CHIP_IS_E2(bp)) + aer_val = 0x2800 + offset - 1; + else + aer_val = 0x3800 + offset; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, aer_val); +} +static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0x3800); } /******************************************************************/ @@ -2046,12 +2204,12 @@ static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, u8 rc; vars->phy_flags |= PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_serdes(params->bp, phy); rc = bnx2x_reset_unicore(params, phy, 1); /* reset the SerDes and wait for reset bit return low */ if (rc != 0) return rc; - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_serdes(params->bp, phy); return rc; } @@ -2076,7 +2234,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, vars->phy_flags &= ~PHY_SGMII_FLAG; bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); bnx2x_set_master_ln(params, phy); rc = bnx2x_reset_unicore(params, phy, 0); @@ -2084,7 +2242,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, if (rc != 0) return rc; - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); /* setting the masterLn_def again after the reset */ bnx2x_set_master_ln(params, phy); @@ -2358,7 +2516,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, 0x6041); msleep(200); /* set aer mmd back */ - bnx2x_set_aer_mmd(params, phy); + bnx2x_set_aer_mmd_xgxs(params, phy); /* and md_devad */ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, @@ -2721,7 +2879,10 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u8 gpio_port; /* HW reset */ - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_OUTPUT_LOW, gpio_port); @@ -2799,8 +2960,9 @@ static u8 bnx2x_update_link_up(struct link_params *params, } /* PBF - link up */ - rc |= bnx2x_pbf_update(params, vars->flow_ctrl, - vars->line_speed); + if (!(CHIP_IS_E2(bp))) + rc |= bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); /* disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); @@ -3443,7 +3605,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, u8 gpio_port; DP(NETIF_MSG_LINK, "Init 8073\n"); - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); @@ -3680,7 +3845,10 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u8 gpio_port; - gpio_port = params->port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", gpio_port); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, @@ -6371,7 +6539,10 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->mdio_ctrl = bnx2x_get_emac_base(bp, SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, port); - phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; + if (CHIP_IS_E2(bp)) + phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR; + else + phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", port, phy->addr, phy->mdio_ctrl); @@ -6742,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } bnx2x_emac_enable(params, vars, 0); - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); + if (!(CHIP_IS_E2(bp))) + bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); /* disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); @@ -6932,18 +7105,34 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /****************************************************************************/ /* Common function */ /****************************************************************************/ -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; u16 val; s8 port; + s8 port_of_path = 0; /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { + u32 shmem_base, shmem2_base; + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, - port, &phy[port]) != + port_of_path, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate_phy failed\n"); return -EINVAL; @@ -6981,9 +7170,15 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port); + port_of_path); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, @@ -7039,9 +7234,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem } return 0; } - -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { u32 val; s8 port; @@ -7056,6 +7252,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, bnx2x_ext_phy_hw_reset(bp, 1); msleep(5); for (port = 0; port < PORT_MAX; port++) { + u32 shmem_base, shmem2_base; + + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + } /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, port, &phy) != @@ -7077,14 +7283,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, return 0; } -static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index) +static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { s8 port; u32 swap_val, swap_override; struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; - DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); + s8 port_of_path; swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); @@ -7099,19 +7307,33 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { + u32 shmem_base, shmem2_base; + + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, - port, &phy[port]) != + port_of_path, &phy[port]) != 0) { DP(NETIF_MSG_LINK, "populate phy failed\n"); return -EINVAL; } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + port_of_path*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); /* Reset the phy */ @@ -7133,9 +7355,14 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; - + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], - port); + port_of_path); bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); @@ -7151,29 +7378,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, return 0; } -static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base, u8 phy_index, - u32 ext_phy_type) +static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 ext_phy_type, u32 chip_id) { u8 rc = 0; switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - rc = bnx2x_8073_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8073_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: - rc = bnx2x_8727_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8727_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: /* GPIO1 affects both ports, so there's need to pull it for single port alone */ - rc = bnx2x_8726_common_init_phy(bp, shmem_base, - shmem2_base, phy_index); + rc = bnx2x_8726_common_init_phy(bp, shmem_base_path, + shmem2_base_path, + phy_index, chip_id); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: rc = -EINVAL; @@ -7188,8 +7418,8 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, return rc; } -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, - u32 shmem2_base) +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id) { u8 rc = 0; u8 phy_index; @@ -7203,12 +7433,13 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; phy_index++) { ext_phy_config = bnx2x_get_ext_phy_config(bp, - shmem_base, + shmem_base_path[0], phy_index, 0); ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); - rc |= bnx2x_ext_phy_common_init(bp, shmem_base, - shmem2_base, - phy_index, ext_phy_type); + rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path, + shmem2_base_path, + phy_index, ext_phy_type, + chip_id); } return rc; } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index e98ea3d19471..58a4c7199276 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -22,7 +22,8 @@ /***********************************************************/ /* Defines */ /***********************************************************/ -#define DEFAULT_PHY_DEV_ADDR 3 +#define DEFAULT_PHY_DEV_ADDR 3 +#define E2_DEFAULT_PHY_DEV_ADDR 5 @@ -315,7 +316,8 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base); +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2c04b97f85a9..0ac416a14202 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -68,6 +67,7 @@ __stringify(BCM_5710_FW_ENGINEERING_VERSION) #define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -77,11 +77,13 @@ static char version[] __devinitdata = DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); -MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver"); +MODULE_DESCRIPTION("Broadcom NetXtreme II " + "BCM57710/57711/57711E/57712/57712E Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FW_FILE_NAME_E1); MODULE_FIRMWARE(FW_FILE_NAME_E1H); +MODULE_FIRMWARE(FW_FILE_NAME_E2); static int multi_mode = 1; module_param(multi_mode, int, 0); @@ -124,6 +126,8 @@ enum bnx2x_board_type { BCM57710 = 0, BCM57711 = 1, BCM57711E = 2, + BCM57712 = 3, + BCM57712E = 4 }; /* indexed by board_type, above */ @@ -132,14 +136,24 @@ static struct { } board_info[] __devinitdata = { { "Broadcom NetXtreme II BCM57710 XGb" }, { "Broadcom NetXtreme II BCM57711 XGb" }, - { "Broadcom NetXtreme II BCM57711E XGb" } + { "Broadcom NetXtreme II BCM57711E XGb" }, + { "Broadcom NetXtreme II BCM57712 XGb" }, + { "Broadcom NetXtreme II BCM57712E XGb" } }; +#ifndef PCI_DEVICE_ID_NX2_57712 +#define PCI_DEVICE_ID_NX2_57712 0x1662 +#endif +#ifndef PCI_DEVICE_ID_NX2_57712E +#define PCI_DEVICE_ID_NX2_57712E 0x1663 +#endif static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = { { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712E), BCM57712E }, { 0 } }; @@ -353,7 +367,8 @@ static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, u8 ticks) { - int index_offset = + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : offsetof(struct hc_status_block_data_e1x, index_data); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + @@ -369,7 +384,8 @@ static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, u8 disable) { u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); - int index_offset = + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : offsetof(struct hc_status_block_data_e1x, index_data); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + @@ -408,6 +424,75 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) return val; } +#define DMAE_DP_SRC_GRC "grc src_addr [%08x]" +#define DMAE_DP_SRC_PCI "pci src_addr [%x:%08x]" +#define DMAE_DP_DST_GRC "grc dst_addr [%08x]" +#define DMAE_DP_DST_PCI "pci dst_addr [%x:%08x]" +#define DMAE_DP_DST_NONE "dst_addr [none]" + +void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl) +{ + u32 src_type = dmae->opcode & DMAE_COMMAND_SRC; + + switch (dmae->opcode & DMAE_COMMAND_DST) { + case DMAE_CMD_DST_PCI: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + case DMAE_CMD_DST_GRC: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst_addr [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + default: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%x:%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + } + +} + const u32 dmae_reg_go_c[] = { DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, @@ -431,85 +516,137 @@ void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) REG_WR(bp, dmae_reg_go_c[idx], 1); } -void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, - u32 len32) +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type) { - struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; + return opcode | ((comp_type << DMAE_COMMAND_C_DST_SHIFT) | + DMAE_CMD_C_ENABLE); +} - if (!bp->dmae_ready) { - u32 *data = bnx2x_sp(bp, wb_data[0]); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode) +{ + return opcode & ~DMAE_CMD_SRC_RESET; +} - DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" - " using indirect\n", dst_addr, len32); - bnx2x_init_ind_wr(bp, dst_addr, data, len32); - return; - } +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type) +{ + u32 opcode = 0; + + opcode |= ((src_type << DMAE_COMMAND_SRC_SHIFT) | + (dst_type << DMAE_COMMAND_DST_SHIFT)); - memset(&dmae, 0, sizeof(struct dmae_command)); + opcode |= (DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET); + + opcode |= (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0); + opcode |= ((BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT) | + (BP_E1HVN(bp) << DMAE_COMMAND_DST_VN_SHIFT)); + opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT); - dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | #ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_B_DW_SWAP; #else - DMAE_CMD_ENDIANITY_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_DW_SWAP; #endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae.src_addr_lo = U64_LO(dma_addr); - dmae.src_addr_hi = U64_HI(dma_addr); - dmae.dst_addr_lo = dst_addr >> 2; - dmae.dst_addr_hi = 0; - dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", + if (with_comp) + opcode = bnx2x_dmae_opcode_add_comp(opcode, comp_type); + return opcode; +} + +void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae, + u8 src_type, u8 dst_type) +{ + memset(dmae, 0, sizeof(struct dmae_command)); + + /* set the opcode */ + dmae->opcode = bnx2x_dmae_opcode(bp, src_type, dst_type, + true, DMAE_COMP_PCI); + + /* fill in the completion parameters */ + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_val = DMAE_COMP_VAL; +} + +/* issue a dmae command over the init-channel and wailt for completion */ +int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae) +{ + u32 *wb_comp = bnx2x_sp(bp, wb_comp); + int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40; + int rc = 0; + + DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n", bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); + /* lock the dmae channel */ mutex_lock(&bp->dmae_mutex); + /* reset completion */ *wb_comp = 0; - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); + /* post the command on the channel used for initializations */ + bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); + /* wait for completion */ udelay(5); - - while (*wb_comp != DMAE_COMP_VAL) { + while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); if (!cnt) { BNX2X_ERR("DMAE timeout!\n"); - break; + rc = DMAE_TIMEOUT; + goto unlock; } cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); + udelay(50); } + if (*wb_comp & DMAE_PCI_ERR_FLAG) { + BNX2X_ERR("DMAE PCI error!\n"); + rc = DMAE_PCI_ERROR; + } + + DP(BNX2X_MSG_OFF, "data after [0x%08x 0x%08x 0x%08x 0x%08x]\n", + bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], + bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); +unlock: mutex_unlock(&bp->dmae_mutex); + return rc; +} + +void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, + u32 len32) +{ + struct dmae_command dmae; + + if (!bp->dmae_ready) { + u32 *data = bnx2x_sp(bp, wb_data[0]); + + DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" + " using indirect\n", dst_addr, len32); + bnx2x_init_ind_wr(bp, dst_addr, data, len32); + return; + } + + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_PCI, DMAE_DST_GRC); + + /* fill in addresses and len */ + dmae.src_addr_lo = U64_LO(dma_addr); + dmae.src_addr_hi = U64_HI(dma_addr); + dmae.dst_addr_lo = dst_addr >> 2; + dmae.dst_addr_hi = 0; + dmae.len = len32; + + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); + + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) { struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; if (!bp->dmae_ready) { u32 *data = bnx2x_sp(bp, wb_data[0]); @@ -522,62 +659,20 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) return; } - memset(&dmae, 0, sizeof(struct dmae_command)); + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_GRC, DMAE_DST_PCI); - dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + /* fill in addresses and len */ dmae.src_addr_lo = src_addr >> 2; dmae.src_addr_hi = 0; dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data)); dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data)); dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - - mutex_lock(&bp->dmae_mutex); - - memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4); - *wb_comp = 0; - - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); - - udelay(5); - while (*wb_comp != DMAE_COMP_VAL) { + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); - if (!cnt) { - BNX2X_ERR("DMAE timeout!\n"); - break; - } - cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); - } - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", - bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], - bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); - - mutex_unlock(&bp->dmae_mutex); + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, @@ -744,19 +839,24 @@ static void bnx2x_fw_dump(struct bnx2x *bp) u32 mark, offset; __be32 data[9]; int word; - + u32 trace_shmem_base; if (BP_NOMCP(bp)) { BNX2X_ERR("NO MCP - can not dump\n"); return; } - addr = bp->common.shmem_base - 0x0800 + 4; + if (BP_PATH(bp) == 0) + trace_shmem_base = bp->common.shmem_base; + else + trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr); + addr = trace_shmem_base - 0x0800 + 4; mark = REG_RD(bp, addr); - mark = MCP_REG_MCPR_SCRATCH + ((mark + 0x3) & ~0x3) - 0x08000000; + mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) + + ((mark + 0x3) & ~0x3) - 0x08000000; pr_err("begin fw dump (mark 0x%x)\n", mark); pr_err(""); - for (offset = mark; offset <= bp->common.shmem_base; offset += 0x8*4) { + for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, offset + 4*word)); data[8] = 0x0; @@ -822,10 +922,15 @@ void bnx2x_panic_dump(struct bnx2x *bp) for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int loop; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p = + CHIP_IS_E2(bp) ? + sb_data_e2.common.state_machine : sb_data_e1x.common.state_machine; struct hc_index_data *hc_index_p = + CHIP_IS_E2(bp) ? + sb_data_e2.index_data : sb_data_e1x.index_data; int data_size; u32 *sb_data_p; @@ -849,7 +954,8 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - loop = HC_SB_MAX_INDICES_E1X; + loop = CHIP_IS_E2(bp) ? + HC_SB_MAX_INDICES_E2 : HC_SB_MAX_INDICES_E1X; /* host sb data */ @@ -865,23 +971,36 @@ void bnx2x_panic_dump(struct bnx2x *bp) fp->sb_index_values[j], (j == loop - 1) ? ")" : " "); /* fw sb data */ - data_size = + data_size = CHIP_IS_E2(bp) ? + sizeof(struct hc_status_block_data_e2) : sizeof(struct hc_status_block_data_e1x); data_size /= sizeof(u32); - sb_data_p = (u32 *)&sb_data_e1x; + sb_data_p = CHIP_IS_E2(bp) ? + (u32 *)&sb_data_e2 : + (u32 *)&sb_data_e1x; /* copy sb data in here */ for (j = 0; j < data_size; j++) *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + j * sizeof(u32)); - pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " - "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", - sb_data_e1x.common.p_func.pf_id, - sb_data_e1x.common.p_func.vf_id, - sb_data_e1x.common.p_func.vf_valid, - sb_data_e1x.common.p_func.vnic_id, - sb_data_e1x.common.same_igu_sb_1b); + if (CHIP_IS_E2(bp)) { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e2.common.p_func.pf_id, + sb_data_e2.common.p_func.vf_id, + sb_data_e2.common.p_func.vf_valid, + sb_data_e2.common.p_func.vnic_id, + sb_data_e2.common.same_igu_sb_1b); + } else { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e1x.common.p_func.pf_id, + sb_data_e1x.common.p_func.vf_id, + sb_data_e1x.common.p_func.vf_valid, + sb_data_e1x.common.p_func.vnic_id, + sb_data_e1x.common.same_igu_sb_1b); + } /* SB_SMs data */ for (j = 0; j < HC_SB_MAX_SM; j++) { @@ -969,7 +1088,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) BNX2X_ERR("end crash dump -----------------\n"); } -void bnx2x_int_enable(struct bnx2x *bp) +static void bnx2x_hc_int_enable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -1011,7 +1130,7 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); barrier(); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { /* init leading/trailing edge */ if (IS_MF(bp)) { val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); @@ -1029,7 +1148,66 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); } -void bnx2x_int_disable(struct bnx2x *bp) +static void bnx2x_igu_int_enable(struct bnx2x *bp) +{ + u32 val; + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0; + + val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + if (msix) { + val &= ~(IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN); + } else if (msi) { + val &= ~IGU_PF_CONF_INT_LINE_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } else { + val &= ~IGU_PF_CONF_MSI_MSIX_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } + + DP(NETIF_MSG_INTR, "write 0x%x to IGU mode %s\n", + val, (msix ? "MSI-X" : (msi ? "MSI" : "INTx"))); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + + barrier(); + + /* init leading/trailing edge */ + if (IS_MF(bp)) { + val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); + if (bp->port.pmf) + /* enable nig and gpio3 attention */ + val |= 0x1100; + } else + val = 0xffff; + + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + + /* Make sure that interrupts are indeed enabled from here on */ + mmiowb(); +} + +void bnx2x_int_enable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_enable(bp); + else + bnx2x_igu_int_enable(bp); +} + +static void bnx2x_hc_int_disable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -1051,6 +1229,32 @@ void bnx2x_int_disable(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } +static void bnx2x_igu_int_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + val &= ~(IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN); + + DP(NETIF_MSG_INTR, "write %x to IGU\n", val); + + /* flush all outstanding writes */ + mmiowb(); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + if (REG_RD(bp, IGU_REG_PF_CONFIGURATION) != val) + BNX2X_ERR("BUG! proper val not read from IGU!\n"); +} + +void bnx2x_int_disable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_disable(bp); + else + bnx2x_igu_int_disable(bp); +} + void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; @@ -1194,7 +1398,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; #endif - for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { + for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); @@ -1579,7 +1783,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) /* Initialize link parameters structure variables */ /* It is recommended to turn off RX FC for jumbo frames for better performance */ - if (bp->dev->mtu > 5000) + if ((CHIP_IS_E1x(bp)) && (bp->dev->mtu > 5000)) bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX; else bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; @@ -1693,13 +1897,11 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp) static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) { int all_zero = 1; - int port = BP_PORT(bp); int vn; bp->vn_weight_sum = 0; for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int func = 2*vn + port; - u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; @@ -1727,11 +1929,12 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) CMNG_FLAGS_PER_PORT_FAIRNESS_VN; } -static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) +static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) { struct rate_shaping_vars_per_vn m_rs_vn; struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = MF_CFG_RD(bp, func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; + int func = 2*vn + BP_PORT(bp); u16 vn_min_rate, vn_max_rate; int i; @@ -1744,7 +1947,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; /* If min rate is zero - set it to 1 */ - if (!vn_min_rate) + if (bp->vn_weight_sum && (vn_min_rate == 0)) vn_min_rate = DEF_MIN_RATE; vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * 100; @@ -1807,7 +2010,7 @@ static void bnx2x_read_mf_cfg(struct bnx2x *bp) for (vn = VN_0; vn < E1HVN_MAX; vn++) { int /*abs*/func = 2*vn + BP_PORT(bp); - bp->mf_config = + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } } @@ -1878,7 +2081,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (bp->link_vars.link_up) { /* dropless flow control */ - if (CHIP_IS_E1H(bp) && bp->dropless_fc) { + if (!CHIP_IS_E1(bp) && bp->dropless_fc) { int port = BP_PORT(bp); u32 pause_enabled = 0; @@ -1906,37 +2109,19 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (prev_link_status != bp->link_vars.link_status) bnx2x_link_report(bp); - if (IS_MF(bp)) { - int port = BP_PORT(bp); - int func; - int vn; - - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; - - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } - - if (bp->link_vars.link_up) { - int i; - - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + if (bp->link_vars.link_up && bp->link_vars.line_speed) { + int cmng_fns = bnx2x_get_cmng_fns_mode(bp); - /* Store it to internal memory */ - for (i = 0; - i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); - } + if (cmng_fns != CMNG_FNS_NONE) { + bnx2x_cmng_fns_init(bp, false, cmng_fns); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + } else + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "single function mode without fairness\n"); } } @@ -1952,7 +2137,9 @@ void bnx2x__link_status_update(struct bnx2x *bp) else bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_calc_vn_weight_sum(bp); + /* the link status update could be the result of a DCC event + hence re-read the shmem mf configuration */ + bnx2x_read_mf_cfg(bp); /* indicate link status */ bnx2x_link_report(bp); @@ -1968,8 +2155,13 @@ static void bnx2x_pmf_update(struct bnx2x *bp) /* enable nig attention */ val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + } bnx2x_stats_handle(bp, STATS_EVENT_PMF); } @@ -1985,22 +2177,23 @@ static void bnx2x_pmf_update(struct bnx2x *bp) /* send the MCP a request, block until there is a reply */ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 seq = ++bp->fw_seq; u32 rc = 0; u32 cnt = 1; u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; mutex_lock(&bp->fw_mb_mutex); - SHMEM_WR(bp, func_mb[func].drv_mb_param, param); - SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); do { /* let the FW do it's magic ... */ msleep(delay); - rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); + rc = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_header); /* Give the FW up to 5 second (500*10ms) */ } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500)); @@ -2264,10 +2457,28 @@ void bnx2x_pf_init(struct bnx2x *bp) if (!CHIP_IS_E1(bp)) storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); + if (CHIP_IS_E2(bp)) { + /* reset IGU PF statistics: MSIX + ATTN */ + /* PF */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + /* ATTN */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + BNX2X_IGU_STAS_MSG_PF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + } + /* function setup flags */ flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); - flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + if (CHIP_IS_E1x(bp)) + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + else + flags |= FUNC_FLG_TPA; /** * Although RSS is meaningless when there is a single HW queue we @@ -2361,7 +2572,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) * where the bp->flags can change so it is done without any * locks */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + if (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED) { DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); bp->flags |= MF_FUNC_DIS; @@ -2548,14 +2759,13 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) { int port = BP_PORT(bp); - u32 hc_addr = (HC_REG_COMMAND_REG + port*32 + - COMMAND_REG_ATTN_BITS_SET); u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : NIG_REG_MASK_INTERRUPT_PORT0; u32 aeu_mask; u32 nig_mask = 0; + u32 reg_addr; if (bp->attn_state & asserted) BNX2X_ERR("IGU ERROR\n"); @@ -2630,9 +2840,15 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) } /* if hardwired */ - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - asserted, hc_addr); - REG_WR(bp, hc_addr, asserted); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_SET); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_SET_UPPER*8); + + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", asserted, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); + REG_WR(bp, reg_addr, asserted); /* now set back the mask */ if (asserted & ATTN_NIG_FOR_FUNC) { @@ -2753,6 +2969,10 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) /* RQ_USDMDP_FIFO_OVERFLOW */ if (val & 0x18000) BNX2X_ERR("FATAL error from PXP\n"); + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_1); + BNX2X_ERR("PXP hw attention-1 0x%x\n", val); + } } if (attn & HW_INTERRUT_ASSERT_SET_2) { @@ -2783,9 +3003,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) int func = BP_FUNC(bp); REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = - MF_CFG_RD(bp, func_mf_config[func].config); - val = SHMEM_RD(bp, func_mb[func].drv_status); + bp->mf_config[BP_VN(bp)] = MF_CFG_RD(bp, + func_mf_config[BP_ABS_FUNC(bp)].config); + val = SHMEM_RD(bp, + func_mb[BP_FW_MB_IDX(bp)].drv_status); if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, (val & DRV_STATUS_DCC_EVENT_MASK)); @@ -2815,13 +3036,13 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn); if (attn & BNX2X_GRC_TIMEOUT) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN); BNX2X_ERR("GRC time-out 0x%08x\n", val); } if (attn & BNX2X_GRC_RSV) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_RSV_ATTN); BNX2X_ERR("GRC reserved 0x%08x\n", val); } REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); @@ -3126,6 +3347,74 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp) attn.sig[3]); } + +static inline void bnx2x_attn_int_deasserted4(struct bnx2x *bp, u32 attn) +{ + u32 val; + if (attn & AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT) { + + val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS_CLR); + BNX2X_ERR("PGLUE hw attention 0x%x\n", val); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "ADDRESS_ERROR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "INCORRECT_RCV_BEHAVIOR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "WAS_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_LENGTH_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_GRC_SPACE_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_MSIX_BAR_VIOLATION_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_IN_TWO_RCBS_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "CSSNOOP_FIFO_OVERFLOW\n"); + } + if (attn & AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT) { + val = REG_RD(bp, ATC_REG_ATC_INT_STS_CLR); + BNX2X_ERR("ATC hw attention 0x%x\n", val); + if (val & ATC_ATC_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ADDRESS_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND) + BNX2X_ERR("ATC_ATC_INT_STS_REG" + "_ATC_TCPL_TO_NOT_PEND\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_GPA_MULTIPLE_HITS\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_RCPL_TO_EMPTY_CNT\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_IREQ_LESS_THAN_STU\n"); + } + + if (attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)) { + BNX2X_ERR("FATAL parity attention set4 0x%x\n", + (u32)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR))); + } + +} + static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) { struct attn_route attn, *group_mask; @@ -3156,17 +3445,28 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n", - attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]); + if (CHIP_IS_E2(bp)) + attn.sig[4] = + REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + port*4); + else + attn.sig[4] = 0; + + DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x %08x\n", + attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3], attn.sig[4]); for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { if (deasserted & (1 << index)) { group_mask = &bp->attn_group[index]; - DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n", - index, group_mask->sig[0], group_mask->sig[1], - group_mask->sig[2], group_mask->sig[3]); + DP(NETIF_MSG_HW, "group[%d]: %08x %08x " + "%08x %08x %08x\n", + index, + group_mask->sig[0], group_mask->sig[1], + group_mask->sig[2], group_mask->sig[3], + group_mask->sig[4]); + bnx2x_attn_int_deasserted4(bp, + attn.sig[4] & group_mask->sig[4]); bnx2x_attn_int_deasserted3(bp, attn.sig[3] & group_mask->sig[3]); bnx2x_attn_int_deasserted1(bp, @@ -3180,11 +3480,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) bnx2x_release_alr(bp); - reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_CLR); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_CLR_UPPER*8); val = ~deasserted; - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - val, reg_addr); + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", val, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); REG_WR(bp, reg_addr, val); if (~bp->attn_state & deasserted) @@ -3471,7 +3775,7 @@ static void bnx2x_timer(unsigned long data) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 drv_pulse; u32 mcp_pulse; @@ -3479,9 +3783,9 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse); + SHMEM_WR(bp, func_mb[mb_idx].drv_pulse_mb, drv_pulse); - mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) & + mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response * should be 1 (before mcp response) or 0 (after mcp response) @@ -3539,17 +3843,26 @@ static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) { u32 *sb_data_p; u32 data_size = 0; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; /* disable the function first */ - memset(&sb_data_e1x, 0, - sizeof(struct hc_status_block_data_e1x)); - sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; - sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; - sb_data_e1x.common.p_func.vf_valid = false; - sb_data_p = (u32 *)&sb_data_e1x; - data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); bnx2x_fill(bp, BAR_CSTRORM_INTMEM + @@ -3610,30 +3923,48 @@ void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, { int igu_seg_id; + struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p; struct hc_index_data *hc_index_p; int data_size; u32 *sb_data_p; - igu_seg_id = HC_SEG_ACCESS_NORM; + if (CHIP_INT_MODE_IS_BC(bp)) + igu_seg_id = HC_SEG_ACCESS_NORM; + else + igu_seg_id = IGU_SEG_ACCESS_NORM; bnx2x_zero_fp_sb(bp, fw_sb_id); - memset(&sb_data_e1x, 0, - sizeof(struct hc_status_block_data_e1x)); - sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); - sb_data_e1x.common.p_func.vf_id = 0xff; - sb_data_e1x.common.p_func.vf_valid = false; - sb_data_e1x.common.p_func.vnic_id = BP_E1HVN(bp); - sb_data_e1x.common.same_igu_sb_1b = true; - sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); - sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); - hc_sm_p = sb_data_e1x.common.state_machine; - hc_index_p = sb_data_e1x.index_data; - sb_data_p = (u32 *)&sb_data_e1x; - data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); - + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e2.common.p_func.vf_id = vfid; + sb_data_e2.common.p_func.vf_valid = vf_valid; + sb_data_e2.common.p_func.vnic_id = BP_VN(bp); + sb_data_e2.common.same_igu_sb_1b = true; + sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e2.common.state_machine; + hc_index_p = sb_data_e2.index_data; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e1x.common.p_func.vf_id = 0xff; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_e1x.common.p_func.vnic_id = BP_VN(bp); + sb_data_e1x.common.same_igu_sb_1b = true; + sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e1x.common.state_machine; + hc_index_p = sb_data_e1x.index_data; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID], igu_sb_id, igu_seg_id); @@ -3666,6 +3997,7 @@ static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, false, tx_usec); } + static void bnx2x_init_def_sb(struct bnx2x *bp) { struct host_sp_status_block *def_sb = bp->def_status_blk; @@ -3680,8 +4012,13 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) struct hc_sp_status_block_data sp_sb_data; memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); - igu_sp_sb_index = DEF_SB_IGU_ID; - igu_seg_id = HC_SEG_ACCESS_DEF; + if (CHIP_INT_MODE_IS_BC(bp)) { + igu_sp_sb_index = DEF_SB_IGU_ID; + igu_seg_id = HC_SEG_ACCESS_DEF; + } else { + igu_sp_sb_index = bp->igu_dsb_id; + igu_seg_id = IGU_SEG_ACCESS_DEF; + } /* ATTN */ section = ((u64)mapping) + offsetof(struct host_sp_status_block, @@ -3698,12 +4035,29 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) for (sindex = 0; sindex < 4; sindex++) bp->attn_group[index].sig[sindex] = REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); + + if (CHIP_IS_E2(bp)) + /* + * enable5 is separate from the rest of the registers, + * and therefore the address skip is 4 + * and not 16 between the different groups + */ + bp->attn_group[index].sig[4] = REG_RD(bp, + reg_offset + 0x10 + 0x4*index); + else + bp->attn_group[index].sig[4] = 0; } - reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : - HC_REG_ATTN_MSG0_ADDR_L); - REG_WR(bp, reg_offset, U64_LO(section)); - REG_WR(bp, reg_offset + 4, U64_HI(section)); + if (bp->common.int_block == INT_BLOCK_HC) { + reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : + HC_REG_ATTN_MSG0_ADDR_L); + + REG_WR(bp, reg_offset, U64_LO(section)); + REG_WR(bp, reg_offset + 4, U64_HI(section)); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_L, U64_LO(section)); + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_H, U64_HI(section)); + } section = ((u64)mapping) + offsetof(struct host_sp_status_block, sp_sb); @@ -3715,7 +4069,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp) sp_sb_data.igu_sb_id = igu_sp_sb_index; sp_sb_data.igu_seg_id = igu_seg_id; sp_sb_data.p_func.pf_id = func; - sp_sb_data.p_func.vnic_id = BP_E1HVN(bp); + sp_sb_data.p_func.vnic_id = BP_VN(bp); sp_sb_data.p_func.vf_id = 0xff; bnx2x_wr_sp_sb_data(bp, &sp_sb_data); @@ -3870,6 +4224,11 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_AGG_DATA_OFFSET + i * 4, 0); + if (CHIP_IS_E2(bp)) { + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_IGU_MODE_OFFSET, + CHIP_INT_MODE_IS_BC(bp) ? + HC_IGU_BC_MODE : HC_IGU_NBC_MODE); + } } static void bnx2x_init_internal_port(struct bnx2x *bp) @@ -3881,6 +4240,7 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) { switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: bnx2x_init_internal_common(bp); /* no break */ @@ -3911,9 +4271,11 @@ static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; /* qZone id equals to FW (per path) client id */ fp->cl_qzone_id = fp->cl_id + - BP_PORT(bp)*(ETH_MAX_RX_CLIENTS_E1H); + BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : + ETH_MAX_RX_CLIENTS_E1H); /* init shortcut */ - fp->ustorm_rx_prods_offset = + fp->ustorm_rx_prods_offset = CHIP_IS_E2(bp) ? + USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id) : USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; @@ -4248,9 +4610,19 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) static void enable_blocks_attention(struct bnx2x *bp) { REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); - REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0x40); + else + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + /* + * mask read length error interrupts in brb for parser + * (parsing unit and 'checksum and crc' unit) + * these errors are legal (PU reads fixed length and CAC can cause + * read length error on truncated packets) + */ + REG_WR(bp, BRB1_REG_BRB1_INT_MASK, 0xFC00); REG_WR(bp, QM_REG_QM_INT_MASK, 0); REG_WR(bp, TM_REG_TM_INT_MASK, 0); REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0); @@ -4271,6 +4643,13 @@ static void enable_blocks_attention(struct bnx2x *bp) /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); + else if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, + (PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF + | PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT + | PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN + | PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED + | PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED)); else REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000); REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); @@ -4288,11 +4667,11 @@ static const struct { u32 addr; u32 mask; } bnx2x_parity_mask[] = { - {PXP_REG_PXP_PRTY_MASK, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff}, - {HC_REG_HC_PRTY_MASK, 0xffffffff}, - {MISC_REG_MISC_PRTY_MASK, 0xffffffff}, + {PXP_REG_PXP_PRTY_MASK, 0x3ffffff}, + {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, + {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, + {HC_REG_HC_PRTY_MASK, 0x7}, + {MISC_REG_MISC_PRTY_MASK, 0x1}, {QM_REG_QM_PRTY_MASK, 0x0}, {DORQ_REG_DORQ_PRTY_MASK, 0x0}, {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, @@ -4407,23 +4786,97 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); } +static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num) +{ + u32 offset = 0; + + if (CHIP_IS_E1(bp)) + return; + if (CHIP_IS_E1H(bp) && (pretend_func_num >= E1H_FUNC_MAX)) + return; + + switch (BP_ABS_FUNC(bp)) { + case 0: + offset = PXP2_REG_PGL_PRETEND_FUNC_F0; + break; + case 1: + offset = PXP2_REG_PGL_PRETEND_FUNC_F1; + break; + case 2: + offset = PXP2_REG_PGL_PRETEND_FUNC_F2; + break; + case 3: + offset = PXP2_REG_PGL_PRETEND_FUNC_F3; + break; + case 4: + offset = PXP2_REG_PGL_PRETEND_FUNC_F4; + break; + case 5: + offset = PXP2_REG_PGL_PRETEND_FUNC_F5; + break; + case 6: + offset = PXP2_REG_PGL_PRETEND_FUNC_F6; + break; + case 7: + offset = PXP2_REG_PGL_PRETEND_FUNC_F7; + break; + default: + return; + } + + REG_WR(bp, offset, pretend_func_num); + REG_RD(bp, offset); + DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num); +} + +static void bnx2x_pf_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + val &= ~IGU_PF_CONF_FUNC_EN; + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 0); +} + static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) { u32 val, i; - DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); + DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp)); bnx2x_reset_common(bp); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) + if (!CHIP_IS_E1(bp)) REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); - msleep(30); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + if (CHIP_IS_E2(bp)) { + u8 fid; + + /** + * 4-port mode or 2-port mode we need to turn of master-enable + * for everyone, after that, turn it back on for self. + * so, we disregard multi-function or not, and always disable + * for all functions on the given path, this means 0,2,4,6 for + * path 0 and 1,3,5,7 for path 1 + */ + for (fid = BP_PATH(bp); fid < E2_FUNC_MAX*2; fid += 2) { + if (fid == BP_ABS_FUNC(bp)) { + REG_WR(bp, + PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, + 1); + continue; + } + + bnx2x_pretend_func(bp, fid); + /* clear pf enable */ + bnx2x_pf_disable(bp); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + } + } bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); if (CHIP_IS_E1(bp)) { @@ -4471,9 +4924,65 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) return -EBUSY; } + /* Timers bug workaround E2 only. We need to set the entire ILT to + * have entries with value "0" and valid bit on. + * This needs to be done by the first PF that is loaded in a path + * (i.e. common phase) + */ + if (CHIP_IS_E2(bp)) { + struct ilt_client_info ilt_cli; + struct bnx2x_ilt ilt; + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + memset(&ilt, 0, sizeof(struct bnx2x_ilt)); + + /* initalize dummy TM client */ + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + /* Step 1: set zeroes to all ilt page entries with valid bit on + * Step 2: set the timers first/last ilt entry to point + * to the entire range to prevent ILT range error for 3rd/4th + * vnic (this code assumes existance of the vnic) + * + * both steps performed by call to bnx2x_ilt_client_init_op() + * with dummy TM client + * + * we must use pretend since PXP2_REG_RQ_##blk##_FIRST_ILT + * and his brother are split registers + */ + bnx2x_pretend_func(bp, (BP_PATH(bp) + 6)); + bnx2x_ilt_client_init_op_ilt(bp, &ilt, &ilt_cli, INITOP_CLEAR); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_RD, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_SEL, 1); + } + + REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + if (CHIP_IS_E2(bp)) { + int factor = CHIP_REV_IS_EMUL(bp) ? 1000 : + (CHIP_REV_IS_FPGA(bp) ? 400 : 0); + bnx2x_init_block(bp, PGLUE_B_BLOCK, COMMON_STAGE); + + bnx2x_init_block(bp, ATC_BLOCK, COMMON_STAGE); + + /* let the HW do it's magic ... */ + do { + msleep(200); + val = REG_RD(bp, ATC_REG_ATC_INIT_DONE); + } while (factor-- && (val != 1)); + + if (val != 1) { + BNX2X_ERR("ATC_INIT failed\n"); + return -EBUSY; + } + } + bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); /* clean the DMAE memory */ @@ -4492,6 +5001,8 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); /* QM queues pointers table */ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); @@ -4512,14 +5023,26 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 248); + REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 328); + } + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); #ifndef BCM_CNIC /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif - if (CHIP_IS_E1H(bp)) + if (!CHIP_IS_E1(bp)) REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + int has_ovlan = IS_MF(bp); + REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); @@ -4536,6 +5059,9 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, COMMON_STAGE); + /* sync semi rtc */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x80000000); @@ -4546,6 +5072,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + if (CHIP_IS_E2(bp)) { + int has_ovlan = IS_MF(bp); + REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } + REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) REG_WR(bp, i, random32()); @@ -4583,6 +5115,11 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + + if (CHIP_IS_E2(bp) && BP_NOMCP(bp)) + REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x36); + + bnx2x_init_block(bp, IGU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); @@ -4590,16 +5127,35 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, 0x2814, 0xffffffff); REG_WR(bp, 0x3820, 0xffffffff); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_CONTROL_5, + (PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 | + PXPCS_TL_CONTROL_5_ERR_UNSPPORT)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC345_STAT, + (PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC678_STAT, + (PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5)); + } + bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); } + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); + } if (CHIP_REV_IS_SLOW(bp)) msleep(200); @@ -4622,15 +5178,17 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) } REG_WR(bp, CFC_REG_DEBUG0, 0); - /* read NIG statistic - to see if this is our first up since powerup */ - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); + if (CHIP_IS_E1(bp)) { + /* read NIG statistic + to see if this is our first up since powerup */ + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); - /* do internal memory self test */ - if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) { - BNX2X_ERR("internal mem self test failed\n"); - return -EBUSY; + /* do internal memory self test */ + if ((val == 0) && bnx2x_int_mem_test(bp)) { + BNX2X_ERR("internal mem self test failed\n"); + return -EBUSY; + } } bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, @@ -4647,10 +5205,23 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base, - bp->common.shmem2_base); - bnx2x_release_phy_lock(bp); + /* In E2 2-PORT mode, same ext phy is used for the two paths */ + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || + CHIP_IS_E1x(bp)) { + u32 shmem_base[2], shmem2_base[2]; + shmem_base[0] = bp->common.shmem_base; + shmem2_base[0] = bp->common.shmem2_base; + if (CHIP_IS_E2(bp)) { + shmem_base[1] = + SHMEM2_RD(bp, other_shmem_base_addr); + shmem2_base[1] = + SHMEM2_RD(bp, other_shmem2_base_addr); + } + bnx2x_acquire_phy_lock(bp); + bnx2x_common_init_phy(bp, shmem_base, shmem2_base, + bp->common.chip_id); + bnx2x_release_phy_lock(bp); + } } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -4671,6 +5242,14 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, PXP_BLOCK, init_stage); bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + /* Timers bug workaround: disables the pf_master bit in pglue at + * common phase, we need to enable it here before any dmae access are + * attempted. Therefore we manually added the enable-master to the + * port phase (it also happens in the function phase) + */ + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + bnx2x_init_block(bp, TCM_BLOCK, init_stage); bnx2x_init_block(bp, UCM_BLOCK, init_stage); bnx2x_init_block(bp, CCM_BLOCK, init_stage); @@ -4687,29 +5266,41 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, DQ_BLOCK, init_stage); - bnx2x_init_block(bp, BRB1_BLOCK, init_stage); - if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { - /* no pause for emulation and FPGA */ - low = 0; - high = 513; - } else { - if (IS_MF(bp)) - low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); - else if (bp->dev->mtu > 4096) { - if (bp->flags & ONE_PORT_FLAG) - low = 160; - else { - val = bp->dev->mtu; - /* (24*1024 + val*4)/256 */ - low = 96 + (val/64) + ((val % 64) ? 1 : 0); - } - } else - low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); - high = low + 56; /* 14*1024/256 */ + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, init_stage); + + if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BRB1_BLOCK, init_stage); + if (CHIP_REV_IS_SLOW(bp) && CHIP_IS_E1(bp)) { + /* no pause for emulation and FPGA */ + low = 0; + high = 513; + } else { + if (IS_MF(bp)) + low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); + else if (bp->dev->mtu > 4096) { + if (bp->flags & ONE_PORT_FLAG) + low = 160; + else { + val = bp->dev->mtu; + /* (24*1024 + val*4)/256 */ + low = 96 + (val/64) + + ((val % 64) ? 1 : 0); + } + } else + low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); + high = low + 56; /* 14*1024/256 */ + } + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); } - REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); - REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 + port*8, 248); + REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 + port*8, 328); + REG_WR(bp, (BP_PORT(bp) ? BRB1_REG_MAC_GUARANTIED_1 : + BRB1_REG_MAC_GUARANTIED_0), 40); + } bnx2x_init_block(bp, PRS_BLOCK, init_stage); @@ -4722,24 +5313,28 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, USEM_BLOCK, init_stage); bnx2x_init_block(bp, CSEM_BLOCK, init_stage); bnx2x_init_block(bp, XSEM_BLOCK, init_stage); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, init_stage); bnx2x_init_block(bp, UPB_BLOCK, init_stage); bnx2x_init_block(bp, XPB_BLOCK, init_stage); bnx2x_init_block(bp, PBF_BLOCK, init_stage); - /* configure PBF to work without PAUSE mtu 9000 */ - REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); + if (!CHIP_IS_E2(bp)) { + /* configure PBF to work without PAUSE mtu 9000 */ + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); - /* update threshold */ - REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); - /* update init credit */ - REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); + /* update init credit */ + REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); - /* probe changes */ - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); - msleep(5); - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + /* probe changes */ + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); + udelay(50); + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + } #ifdef BCM_CNIC bnx2x_init_block(bp, SRCH_BLOCK, init_stage); @@ -4753,6 +5348,8 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) } bnx2x_init_block(bp, HC_BLOCK, init_stage); + bnx2x_init_block(bp, IGU_BLOCK, init_stage); + bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); /* init aeu_mask_attn_func_0/1: * - SF mode: bits 3-7 are masked. only bits 0-2 are in use @@ -4771,11 +5368,25 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, (IS_MF(bp) ? 0x1 : 0x2)); + if (CHIP_IS_E2(bp)) { + val = 0; + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + val = 1; + break; + case MULTI_FUNCTION_SI: + val = 2; + break; + } + + REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_CLS_TYPE : + NIG_REG_LLH0_CLS_TYPE), val); + } { REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); @@ -4805,14 +5416,26 @@ static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) { int reg; - if (CHIP_IS_E1H(bp)) - reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; - else /* E1 */ + if (CHIP_IS_E1(bp)) reg = PXP2_REG_RQ_ONCHIP_AT + index*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); } +static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id) +{ + bnx2x_igu_clear_sb_gen(bp, idu_sb_id, true /*PF*/); +} + +static inline void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func) +{ + u32 i, base = FUNC_ILT_BASE(func); + for (i = base; i < base + ILT_PER_FUNC; i++) + bnx2x_ilt_wr(bp, i, 0); +} + static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); @@ -4825,10 +5448,12 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); /* set MSI reconfigure capability */ - addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); - val = REG_RD(bp, addr); - val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; - REG_WR(bp, addr, val); + if (bp->common.int_block == INT_BLOCK_HC) { + addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); + val = REG_RD(bp, addr); + val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; + REG_WR(bp, addr, val); + } ilt = BP_ILT(bp); cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; @@ -4854,10 +5479,38 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif /* BCM_CNIC */ + if (CHIP_IS_E2(bp)) { + u32 pf_conf = IGU_PF_CONF_FUNC_EN; + + /* Turn on a single ISR mode in IGU if driver is going to use + * INT#x or MSI + */ + if (!(bp->flags & USING_MSIX_FLAG)) + pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN; + /* + * Timers workaround bug: function init part. + * Need to wait 20msec after initializing ILT, + * needed to make sure there are no requests in + * one of the PXP internal queues with "old" ILT addresses + */ + msleep(20); + /* + * Master enable - Due to WB DMAE writes performed before this + * register is re-initialized as part of the regular function + * init + */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + /* Enable the function in IGU */ + REG_WR(bp, IGU_REG_PF_CONFIGURATION, pf_conf); + } + bp->dmae_ready = 1; bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func); + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); @@ -4868,7 +5521,24 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); + } + + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) + REG_WR(bp, QM_REG_PF_EN, 1); + bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); + + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); @@ -4880,10 +5550,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PBF_REG_DISABLE_PF, 0); + bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1); + if (IS_MF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); @@ -4892,13 +5568,117 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); /* HC init per function */ - if (CHIP_IS_E1H(bp)) { + if (bp->common.int_block == INT_BLOCK_HC) { + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } + bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + + } else { + int num_segs, sb_idx, prod_offset; + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } + + bnx2x_init_block(bp, IGU_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) { + int dsb_idx = 0; + /** + * Producer memory: + * E2 mode: address 0-135 match to the mapping memory; + * 136 - PF0 default prod; 137 - PF1 default prod; + * 138 - PF2 default prod; 139 - PF3 default prod; + * 140 - PF0 attn prod; 141 - PF1 attn prod; + * 142 - PF2 attn prod; 143 - PF3 attn prod; + * 144-147 reserved. + * + * E1.5 mode - In backward compatible mode; + * for non default SB; each even line in the memory + * holds the U producer and each odd line hold + * the C producer. The first 128 producers are for + * NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The last 20 + * producers are for the DSB for each PF. + * Each PF has five segments: (the order inside each + * segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; + * 144-147 attn prods; + */ + /* non-default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_NDSB_NUM_SEGS : IGU_NORM_NDSB_NUM_SEGS; + for (sb_idx = 0; sb_idx < bp->igu_sb_cnt; sb_idx++) { + prod_offset = (bp->igu_base_sb + sb_idx) * + num_segs; + + for (i = 0; i < num_segs; i++) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i) * 4; + REG_WR(bp, addr, 0); + } + /* send consumer update with value 0 */ + bnx2x_ack_sb(bp, bp->igu_base_sb + sb_idx, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_igu_clear_sb(bp, + bp->igu_base_sb + sb_idx); + } + + /* default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_DSB_NUM_SEGS : IGU_NORM_DSB_NUM_SEGS; + + if (CHIP_MODE_IS_4_PORT(bp)) + dsb_idx = BP_FUNC(bp); + else + dsb_idx = BP_E1HVN(bp); + + prod_offset = (CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_BASE_DSB_PROD + dsb_idx : + IGU_NORM_BASE_DSB_PROD + dsb_idx); + + for (i = 0; i < (num_segs * E1HVN_MAX); + i += E1HVN_MAX) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i)*4; + REG_WR(bp, addr, 0); + } + /* send consumer update with 0 */ + if (CHIP_INT_MODE_IS_BC(bp)) { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + CSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + XSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + TSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } else { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } + bnx2x_igu_clear_sb(bp, bp->igu_dsb_id); + + /* !!! these should become driver const once + rf-tool supports split-68 const */ + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_MSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_LSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_MSB, 0); + } } - bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); @@ -4920,7 +5700,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) int rc = 0; DP(BNX2X_MSG_MCP, "function %d load_code %x\n", - BP_FUNC(bp), load_code); + BP_ABS_FUNC(bp), load_code); bp->dmae_ready = 0; mutex_init(&bp->dmae_mutex); @@ -4930,6 +5710,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: rc = bnx2x_init_hw_common(bp, load_code); if (rc) goto init_hw_err; @@ -4953,10 +5734,10 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & + (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & DRV_PULSE_SEQ_MASK); DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); } @@ -4993,9 +5774,14 @@ void bnx2x_free_mem(struct bnx2x *bp) /* Common */ for_each_queue(bp, i) { /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), - bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e1x)); } /* Rx */ for_each_queue(bp, i) { @@ -5041,9 +5827,12 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_FREE(bp->ilt->lines); #ifdef BCM_CNIC - - BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); @@ -5055,6 +5844,22 @@ void bnx2x_free_mem(struct bnx2x *bp) #undef BNX2X_KFREE } +static inline void set_sb_shortcuts(struct bnx2x *bp, int index) +{ + union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); + if (CHIP_IS_E2(bp)) { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e2_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e2_sb->sb.running_index; + } else { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e1x_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e1x_sb->sb.running_index; + } +} + int bnx2x_alloc_mem(struct bnx2x *bp) { @@ -5074,25 +5879,23 @@ int bnx2x_alloc_mem(struct bnx2x *bp) } while (0) int i; - void *p; /* fastpath */ /* Common */ for_each_queue(bp, i) { + union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); bnx2x_fp(bp, i, bp) = bp; - /* status blocks */ - BNX2X_PCI_ALLOC(p, + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(sb->e2_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(sb->e1x_sb, &bnx2x_fp(bp, i, status_blk_mapping), sizeof(struct host_hc_status_block_e1x)); - bnx2x_fp(bp, i, status_blk.e1x_sb) = - (struct host_hc_status_block_e1x *)p; - - bnx2x_fp(bp, i, sb_index_values) = (__le16 *) - (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.index_values); - bnx2x_fp(bp, i, sb_running_index) = (__le16 *) - (bnx2x_fp(bp, i, status_blk.e1x_sb)->sb.running_index); + set_sb_shortcuts(bp, i); } /* Rx */ for_each_queue(bp, i) { @@ -5129,8 +5932,12 @@ int bnx2x_alloc_mem(struct bnx2x *bp) /* end of fastpath */ #ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, - sizeof(struct host_hc_status_block_e1x)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); /* allocate searcher T2 table */ BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); @@ -5210,11 +6017,6 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, bp->set_mac_pending = 1; smp_wmb(); - config->hdr.length = 1 + (is_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; - config->hdr.length = 1; config->hdr.offset = cam_offset; config->hdr.client_id = 0xff; @@ -5312,7 +6114,12 @@ int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) { - return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); + if (CHIP_IS_E1H(bp)) + return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); + else if (CHIP_MODE_IS_4_PORT(bp)) + return BP_FUNC(bp) * 32 + rel_offset; + else + return BP_VN(bp) * 32 + rel_offset; } void bnx2x_set_eth_mac(struct bnx2x *bp, int set) @@ -5804,9 +6611,11 @@ static void bnx2x_reset_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); - int base, i; + int i; int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + - offsetof(struct hc_status_block_data_e1x, common); + (CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, common) : + offsetof(struct hc_status_block_data_e1x, common)); int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); int pfid_offset = offsetof(struct pci_entity, pf_id); @@ -5839,8 +6648,13 @@ static void bnx2x_reset_func(struct bnx2x *bp) 0); /* Configure IGU */ - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } else { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } #ifdef BCM_CNIC /* Disable Timer scan */ @@ -5856,9 +6670,25 @@ static void bnx2x_reset_func(struct bnx2x *bp) } #endif /* Clear ILT */ - base = FUNC_ILT_BASE(func); - for (i = base; i < base + ILT_PER_FUNC; i++) - bnx2x_ilt_wr(bp, i, 0); + bnx2x_clear_func_ilt(bp, func); + + /* Timers workaround bug for E2: if this is vnic-3, + * we need to set the entire ilt range for this timers. + */ + if (CHIP_IS_E2(bp) && BP_VN(bp) == 3) { + struct ilt_client_info ilt_cli; + /* use dummy TM client */ + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + bnx2x_ilt_boundry_init_op(bp, &ilt_cli, 0, INITOP_CLEAR); + } + + /* this assumes that reset_port() called before reset_func()*/ + if (CHIP_IS_E2(bp)) + bnx2x_pf_disable(bp); bp->dmae_ready = 0; } @@ -5892,7 +6722,7 @@ static void bnx2x_reset_port(struct bnx2x *bp) static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", - BP_FUNC(bp), reset_code); + BP_ABS_FUNC(bp), reset_code); switch (reset_code) { case FW_MSG_CODE_DRV_UNLOAD_COMMON: @@ -6024,15 +6854,20 @@ unload_error: if (!BP_NOMCP(bp)) reset_code = bnx2x_fw_command(bp, reset_code, 0); else { - DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]--; - load_count[1 + port]--; - DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 0) + DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], + load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + load_count[BP_PATH(bp)][0]--; + load_count[BP_PATH(bp)][1 + port]--; + DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + if (load_count[BP_PATH(bp)][0] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[1 + port] == 0) + else if (load_count[BP_PATH(bp)][1 + port] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; else reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; @@ -6531,39 +7366,23 @@ reset_task_exit: * Init service functions */ -static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func) -{ - switch (func) { - case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0; - case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1; - case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2; - case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3; - case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4; - case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5; - case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6; - case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7; - default: - BNX2X_ERR("Unsupported function index: %d\n", func); - return (u32)(-1); - } +u32 bnx2x_get_pretend_reg(struct bnx2x *bp) +{ + u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; + u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; + return base + (BP_ABS_FUNC(bp)) * stride; } -static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) +static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp) { - u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val; + u32 reg = bnx2x_get_pretend_reg(bp); /* Flush all outstanding writes */ mmiowb(); /* Pretend to be function 0 */ REG_WR(bp, reg, 0); - /* Flush the GRC transaction (in the chip) */ - new_val = REG_RD(bp, reg); - if (new_val != 0) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n", - new_val); - BUG(); - } + REG_RD(bp, reg); /* Flush the GRC transaction (in the chip) */ /* From now we are in the "like-E1" mode */ bnx2x_int_disable(bp); @@ -6571,22 +7390,17 @@ static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) /* Flush all outstanding writes */ mmiowb(); - /* Restore the original funtion settings */ - REG_WR(bp, reg, orig_func); - new_val = REG_RD(bp, reg); - if (new_val != orig_func) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n", - orig_func, new_val); - BUG(); - } + /* Restore the original function */ + REG_WR(bp, reg, BP_ABS_FUNC(bp)); + REG_RD(bp, reg); } -static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func) +static inline void bnx2x_undi_int_disable(struct bnx2x *bp) { - if (CHIP_IS_E1H(bp)) - bnx2x_undi_int_disable_e1h(bp, func); - else + if (CHIP_IS_E1(bp)) bnx2x_int_disable(bp); + else + bnx2x_undi_int_disable_e1h(bp); } static void __devinit bnx2x_undi_unload(struct bnx2x *bp) @@ -6603,8 +7417,8 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); if (val == 0x7) { u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - /* save our func */ - int func = BP_FUNC(bp); + /* save our pf_num */ + int orig_pf_num = bp->pf_num; u32 swap_en; u32 swap_val; @@ -6614,9 +7428,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) BNX2X_DEV_INFO("UNDI is active! reset device\n"); /* try unload UNDI on port 0 */ - bp->func = 0; + bp->pf_num = 0; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); reset_code = bnx2x_fw_command(bp, reset_code, 0); @@ -6628,9 +7442,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) DRV_MSG_CODE_UNLOAD_DONE, 0); /* unload UNDI on port 1 */ - bp->func = 1; + bp->pf_num = 1; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; @@ -6640,7 +7454,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) /* now it's safe to release the lock */ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - bnx2x_undi_int_disable(bp, func); + bnx2x_undi_int_disable(bp); /* close input traffic and wait for it */ /* Do not rcv packets to BRB */ @@ -6679,9 +7493,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); /* restore our func and fw_seq */ - bp->func = func; + bp->pf_num = orig_pf_num; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); } else @@ -6705,20 +7519,42 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = REG_RD(bp, MISC_REG_BOND_ID); id |= (val & 0xf); bp->common.chip_id = id; - bp->link_params.chip_id = bp->common.chip_id; - BNX2X_DEV_INFO("chip ID is 0x%x\n", id); - - bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ /* Set doorbell size */ bp->db_size = (1 << BNX2X_DB_SHIFT); + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); + if ((val & 1) == 0) + val = REG_RD(bp, MISC_REG_PORT4MODE_EN); + else + val = (val >> 1) & 1; + BNX2X_DEV_INFO("chip is in %s\n", val ? "4_PORT_MODE" : + "2_PORT_MODE"); + bp->common.chip_port_mode = val ? CHIP_4_PORT_MODE : + CHIP_2_PORT_MODE; + + if (CHIP_MODE_IS_4_PORT(bp)) + bp->pfid = (bp->pf_num >> 1); /* 0..3 */ + else + bp->pfid = (bp->pf_num & 0x6); /* 0, 2, 4, 6 */ + } else { + bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ + bp->pfid = bp->pf_num; /* 0..7 */ + } + /* * set base FW non-default (fast path) status block id, this value is * used to initialize the fw_sb_id saved on the fp/queue structure to * determine the id used by the FW. */ - bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + if (CHIP_IS_E1x(bp)) + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + else /* E2 */ + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E2; + + bp->link_params.chip_id = bp->common.chip_id; + BNX2X_DEV_INFO("chip ID is 0x%x\n", id); val = (REG_RD(bp, 0x2874) & 0x55); if ((bp->common.chip_id & 0x1) || @@ -6734,15 +7570,15 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->common.flash_size, bp->common.flash_size); bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); + bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ? + MISC_REG_GENERIC_CR_1 : + MISC_REG_GENERIC_CR_0)); bp->link_params.shmem_base = bp->common.shmem_base; bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", bp->common.shmem_base, bp->common.shmem2_base); - if (!bp->common.shmem_base || - (bp->common.shmem_base < 0xA0000) || - (bp->common.shmem_base >= 0xC0000)) { + if (!bp->common.shmem_base) { BNX2X_DEV_INFO("MCP not active\n"); bp->flags |= NO_MCP_FLAG; return; @@ -6751,7 +7587,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERROR("BAD MCP validity signature\n"); + BNX2X_ERR("BAD MCP validity signature\n"); bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); @@ -6775,8 +7611,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) if (val < BNX2X_BC_VER) { /* for now only warn * later we might need to enforce this */ - BNX2X_ERROR("This driver needs bc_ver %X but found %X, " - "please upgrade BC\n", BNX2X_BC_VER, val); + BNX2X_ERR("This driver needs bc_ver %X but found %X, " + "please upgrade BC\n", BNX2X_BC_VER, val); } bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? @@ -6804,6 +7640,57 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val, val2, val3, val4); } +#define IGU_FID(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID) +#define IGU_VEC(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR) + +static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) +{ + int pfid = BP_FUNC(bp); + int vn = BP_E1HVN(bp); + int igu_sb_id; + u32 val; + u8 fid; + + bp->igu_base_sb = 0xff; + bp->igu_sb_cnt = 0; + if (CHIP_INT_MODE_IS_BC(bp)) { + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, + bp->l2_cid_count); + + bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * + FP_SB_MAX_E1x; + + bp->igu_dsb_id = E1HVN_MAX * FP_SB_MAX_E1x + + (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn); + + return; + } + + /* IGU in normal mode - read CAM */ + for (igu_sb_id = 0; igu_sb_id < IGU_REG_MAPPING_MEMORY_SIZE; + igu_sb_id++) { + val = REG_RD(bp, IGU_REG_MAPPING_MEMORY + igu_sb_id * 4); + if (!(val & IGU_REG_MAPPING_MEMORY_VALID)) + continue; + fid = IGU_FID(val); + if ((fid & IGU_FID_ENCODE_IS_PF)) { + if ((fid & IGU_FID_PF_NUM_MASK) != pfid) + continue; + if (IGU_VEC(val) == 0) + /* default status block */ + bp->igu_dsb_id = igu_sb_id; + else { + if (bp->igu_base_sb == 0xff) + bp->igu_base_sb = igu_sb_id; + bp->igu_sb_cnt++; + } + } + } + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count); + if (bp->igu_sb_cnt == 0) + BNX2X_ERR("CAM configuration error\n"); +} + static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) { @@ -7178,26 +8065,49 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func = BP_ABS_FUNC(bp); + int vn; u32 val, val2; int rc = 0; bnx2x_get_common_hwinfo(bp); - bp->common.int_block = INT_BLOCK_HC; + if (CHIP_IS_E1x(bp)) { + bp->common.int_block = INT_BLOCK_HC; + + bp->igu_dsb_id = DEF_SB_IGU_ID; + bp->igu_base_sb = 0; + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + } else { + bp->common.int_block = INT_BLOCK_IGU; + val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); + if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) { + DP(NETIF_MSG_PROBE, "IGU Backward Compatible Mode\n"); + bp->common.int_block |= INT_BLOCK_MODE_BW_COMP; + } else + DP(NETIF_MSG_PROBE, "IGU Normal Mode\n"); - bp->igu_dsb_id = DEF_SB_IGU_ID; - bp->igu_base_sb = 0; - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bnx2x_get_igu_cam_info(bp); + + } + DP(NETIF_MSG_PROBE, "igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n", + bp->igu_dsb_id, bp->igu_base_sb, bp->igu_sb_cnt); + + /* + * Initialize MF configuration + */ bp->mf_ov = 0; bp->mf_mode = 0; - if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { - - bp->common.mf_cfg_base = bp->common.shmem_base + + vn = BP_E1HVN(bp); + if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { + if (SHMEM2_HAS(bp, mf_cfg_addr)) + bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); + else + bp->common.mf_cfg_base = bp->common.shmem_base + offsetof(struct shmem_region, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb); - bp->mf_config = + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & @@ -7213,16 +8123,16 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { bp->mf_ov = val; - BNX2X_DEV_INFO("E1HOV for func %d is %d " + BNX2X_DEV_INFO("MF OV for func %d is %d " "(0x%04x)\n", func, bp->mf_ov, bp->mf_ov); } else { - BNX2X_ERROR("No valid E1HOV for func %d," + BNX2X_ERROR("No valid MF OV for func %d," " aborting\n", func); rc = -EPERM; } } else { - if (BP_E1HVN(bp)) { + if (BP_VN(bp)) { BNX2X_ERROR("VN %d in single function mode," " aborting\n", BP_E1HVN(bp)); rc = -EPERM; @@ -7230,15 +8140,25 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } } - /* adjust igu_sb_cnt to MF */ - if (IS_MF(bp)) + /* adjust igu_sb_cnt to MF for E1x */ + if (CHIP_IS_E1x(bp) && IS_MF(bp)) bp->igu_sb_cnt /= E1HVN_MAX; + /* + * adjust E2 sb count: to be removed when FW will support + * more then 16 L2 clients + */ +#define MAX_L2_CLIENTS 16 + if (CHIP_IS_E2(bp)) + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, + MAX_L2_CLIENTS / (IS_MF(bp) ? 4 : 1)); + if (!BP_NOMCP(bp)) { bnx2x_get_port_hwinfo(bp); - bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } @@ -7338,7 +8258,7 @@ out_not_found: static int __devinit bnx2x_init_bp(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func; int timer_interval; int rc; @@ -7362,6 +8282,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) rc = bnx2x_alloc_mem_bp(bp); bnx2x_read_fwinfo(bp); + + func = BP_FUNC(bp); + /* need to reset chip if undi was active */ if (!BP_NOMCP(bp)) bnx2x_undi_unload(bp); @@ -7650,7 +8573,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, bp->dev = dev; bp->pdev = pdev; bp->flags = 0; - bp->func = PCI_FUNC(pdev->devfn); + bp->pf_num = PCI_FUNC(pdev->devfn); rc = pci_enable_device(pdev); if (rc) { @@ -7964,6 +8887,8 @@ int bnx2x_init_firmware(struct bnx2x *bp) fw_file_name = FW_FILE_NAME_E1; else if (CHIP_IS_E1H(bp)) fw_file_name = FW_FILE_NAME_E1H; + else if (CHIP_IS_E2(bp)) + fw_file_name = FW_FILE_NAME_E2; else { BNX2X_ERR("Unsupported chip revision\n"); return -EINVAL; @@ -8047,8 +8972,25 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, int pcie_width, pcie_speed; int rc, cid_count; - cid_count = FP_SB_MAX_E1x + CNIC_CONTEXT_USE; + switch (ent->driver_data) { + case BCM57710: + case BCM57711: + case BCM57711E: + cid_count = FP_SB_MAX_E1x; + break; + + case BCM57712: + case BCM57712E: + cid_count = FP_SB_MAX_E2; + break; + default: + pr_err("Unknown board_type (%ld), aborting\n", + ent->driver_data); + return ENODEV; + } + + cid_count += CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { @@ -8086,7 +9028,10 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), - pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz", + pcie_width, + ((!CHIP_IS_E2(bp) && pcie_speed == 2) || + (CHIP_IS_E2(bp) && pcie_speed == 1)) ? + "5GHz (Gen2)" : "2.5GHz", dev->base_addr, bp->pdev->irq); pr_cont("node addr %pM\n", dev->dev_addr); @@ -8199,8 +9144,9 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) BNX2X_ERR("BAD MCP validity signature\n"); if (!BP_NOMCP(bp)) { - bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header) - & DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } } @@ -8283,7 +9229,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + printk(KERN_ERR "Handling parity error recovery. " + "Try again later\n"); return; } @@ -8560,7 +9507,11 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; + if (CHIP_IS_E2(bp)) + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e2_sb; + else + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; + cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 6be0d09ad3fd..18a86284ebcc 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2009 Broadcom Corporation + * Copyright (c) 2007-2010 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,20 @@ * */ - +#define ATC_ATC_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS (0x1<<2) +#define ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU (0x1<<5) +#define ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT (0x1<<3) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR (0x1<<4) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1) +/* [RW 1] Initiate the ATC array - reset all the valid bits */ +#define ATC_REG_ATC_INIT_ARRAY 0x1100b8 +/* [R 1] ATC initalization done */ +#define ATC_REG_ATC_INIT_DONE 0x1100bc +/* [RC 6] Interrupt register #0 read clear */ +#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +/* [RW 19] Interrupt mask register #0 read/write */ +#define BRB1_REG_BRB1_INT_MASK 0x60128 /* [R 19] Interrupt register #0 read */ #define BRB1_REG_BRB1_INT_STS 0x6011c /* [RW 4] Parity mask register #0 read/write */ @@ -27,9 +40,31 @@ /* [R 4] Parity register #0 read */ #define BRB1_REG_BRB1_PRTY_STS 0x6012c /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At - address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address - BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */ + * address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address + * BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. Warning - + * following reset the first rbc access to this reg must be write; there can + * be no more rbc writes after the first one; there can be any number of rbc + * read following the first write; rbc access not following these rules will + * result in hang condition. */ #define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200 +/* [RW 10] The number of free blocks below which the full signal to class 0 + * is asserted */ +#define BRB1_REG_FULL_0_XOFF_THRESHOLD_0 0x601d0 +/* [RW 10] The number of free blocks above which the full signal to class 0 + * is de-asserted */ +#define BRB1_REG_FULL_0_XON_THRESHOLD_0 0x601d4 +/* [RW 10] The number of free blocks below which the full signal to class 1 + * is asserted */ +#define BRB1_REG_FULL_1_XOFF_THRESHOLD_0 0x601d8 +/* [RW 10] The number of free blocks above which the full signal to class 1 + * is de-asserted */ +#define BRB1_REG_FULL_1_XON_THRESHOLD_0 0x601dc +/* [RW 10] The number of free blocks below which the full signal to the LB + * port is asserted */ +#define BRB1_REG_FULL_LB_XOFF_THRESHOLD 0x601e0 +/* [RW 10] The number of free blocks above which the full signal to the LB + * port is de-asserted */ +#define BRB1_REG_FULL_LB_XON_THRESHOLD 0x601e4 /* [RW 10] The number of free blocks above which the High_llfc signal to interface #n is de-asserted. */ #define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c @@ -44,6 +79,9 @@ /* [RW 10] The number of free blocks below which the Low_llfc signal to interface #n is asserted. */ #define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c +/* [RW 10] The number of blocks guarantied for the MAC port */ +#define BRB1_REG_MAC_GUARANTIED_0 0x601e8 +#define BRB1_REG_MAC_GUARANTIED_1 0x60240 /* [R 24] The number of full blocks. */ #define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090 /* [ST 32] The number of cycles that the write_full signal towards MAC #0 @@ -55,7 +93,19 @@ asserted. */ #define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8 #define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc -/* [RW 10] Write client 0: De-assert pause threshold. */ +/* [RW 10] The number of free blocks below which the pause signal to class 0 + * is asserted */ +#define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 0x601c0 +/* [RW 10] The number of free blocks above which the pause signal to class 0 + * is de-asserted */ +#define BRB1_REG_PAUSE_0_XON_THRESHOLD_0 0x601c4 +/* [RW 10] The number of free blocks below which the pause signal to class 1 + * is asserted */ +#define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0 0x601c8 +/* [RW 10] The number of free blocks above which the pause signal to class 1 + * is de-asserted */ +#define BRB1_REG_PAUSE_1_XON_THRESHOLD_0 0x601cc +/* [RW 10] Write client 0: De-assert pause threshold. Not Functional */ #define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078 #define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c /* [RW 10] Write client 0: Assert pause threshold. */ @@ -362,6 +412,7 @@ #define CFC_REG_NUM_LCIDS_ARRIVING 0x104004 /* [R 9] Number of Leaving LCIDs in Link List Block */ #define CFC_REG_NUM_LCIDS_LEAVING 0x104018 +#define CFC_REG_WEAK_ENABLE_PF 0x104124 /* [RW 8] The event id for aggregated interrupt 0 */ #define CSDM_REG_AGG_INT_EVENT_0 0xc2038 #define CSDM_REG_AGG_INT_EVENT_10 0xc2060 @@ -590,10 +641,17 @@ #define CSEM_REG_TS_8_AS 0x200058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define CSEM_REG_TS_9_AS 0x20005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define CSEM_REG_VFPF_ERR_NUM 0x200380 /* [RW 1] Parity mask register #0 read/write */ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 /* [R 1] Parity register #0 read */ #define DBG_REG_DBG_PRTY_STS 0xc09c +/* [RW 1] When set the DMAE will process the commands as in E1.5. 1.The + * function that is used is always SRC-PCI; 2.VF_Valid = 0; 3.VFID=0; + * 4.Completion function=0; 5.Error handling=0 */ +#define DMAE_REG_BACKWARD_COMP_EN 0x10207c /* [RW 32] Commands memory. The address to command X; row Y is to calculated as 14*X+Y. */ #define DMAE_REG_CMD_MEM 0x102400 @@ -758,6 +816,92 @@ #define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068 #define HC_REG_VQID_0 0x108008 #define HC_REG_VQID_1 0x10800c +#define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1) +#define IGU_REG_ATTENTION_ACK_BITS 0x130108 +/* [R 4] Debug: attn_fsm */ +#define IGU_REG_ATTN_FSM 0x130054 +#define IGU_REG_ATTN_MSG_ADDR_H 0x13011c +#define IGU_REG_ATTN_MSG_ADDR_L 0x130120 +/* [R 4] Debug: [3] - attention write done message is pending (0-no pending; + * 1-pending). [2:0] = PFID. Pending means attention message was sent; but + * write done didnt receive. */ +#define IGU_REG_ATTN_WRITE_DONE_PENDING 0x130030 +#define IGU_REG_BLOCK_CONFIGURATION 0x130000 +#define IGU_REG_COMMAND_REG_32LSB_DATA 0x130124 +#define IGU_REG_COMMAND_REG_CTRL 0x13012c +/* [WB_R 32] Cleanup bit status per SB. 1 = cleanup is set. 0 = cleanup bit + * is clear. The bits in this registers are set and clear via the producer + * command. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_CSTORM_TYPE_0_SB_CLEANUP 0x130200 +/* [R 5] Debug: ctrl_fsm */ +#define IGU_REG_CTRL_FSM 0x130064 +/* [R 1] data availble for error memory. If this bit is clear do not red + * from error_handling_memory. */ +#define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130 +/* [R 11] Parity register #0 read */ +#define IGU_REG_IGU_PRTY_STS 0x13009c +/* [R 4] Debug: int_handle_fsm */ +#define IGU_REG_INT_HANDLE_FSM 0x130050 +#define IGU_REG_LEADING_EDGE_LATCH 0x130134 +/* [RW 14] mapping CAM; relevant for E2 operating mode only. [0] - valid. + * [6:1] - vector number; [13:7] - FID (if VF - [13] = 0; [12:7] = VF + * number; if PF - [13] = 1; [12:10] = 0; [9:7] = PF number); */ +#define IGU_REG_MAPPING_MEMORY 0x131000 +#define IGU_REG_MAPPING_MEMORY_SIZE 136 +#define IGU_REG_PBA_STATUS_LSB 0x130138 +#define IGU_REG_PBA_STATUS_MSB 0x13013c +#define IGU_REG_PCI_PF_MSI_EN 0x130140 +#define IGU_REG_PCI_PF_MSIX_EN 0x130144 +#define IGU_REG_PCI_PF_MSIX_FUNC_MASK 0x130148 +/* [WB_R 32] Each bit represent the pending bits status for that SB. 0 = no + * pending; 1 = pending. Pendings means interrupt was asserted; and write + * done was not received. Data valid only in addresses 0-4. all the rest are + * zero. */ +#define IGU_REG_PENDING_BITS_STATUS 0x130300 +#define IGU_REG_PF_CONFIGURATION 0x130154 +/* [RW 20] producers only. E2 mode: address 0-135 match to the mapping + * memory; 136 - PF0 default prod; 137 PF1 default prod; 138 - PF2 default + * prod; 139 PF3 default prod; 140 - PF0 - ATTN prod; 141 - PF1 - ATTN prod; + * 142 - PF2 - ATTN prod; 143 - PF3 - ATTN prod; 144-147 reserved. E1.5 mode + * - In backward compatible mode; for non default SB; each even line in the + * memory holds the U producer and each odd line hold the C producer. The + * first 128 producer are for NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The + * last 20 producers are for the DSB for each PF. each PF has five segments + * (the order inside each segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; 144-147 ATTN prods; */ +#define IGU_REG_PROD_CONS_MEMORY 0x132000 +/* [R 3] Debug: pxp_arb_fsm */ +#define IGU_REG_PXP_ARB_FSM 0x130068 +/* [RW 6] Write one for each bit will reset the appropriate memory. When the + * memory reset finished the appropriate bit will be clear. Bit 0 - mapping + * memory; Bit 1 - SB memory; Bit 2 - SB interrupt and mask register; Bit 3 + * - MSIX memory; Bit 4 - PBA memory; Bit 5 - statistics; */ +#define IGU_REG_RESET_MEMORIES 0x130158 +/* [R 4] Debug: sb_ctrl_fsm */ +#define IGU_REG_SB_CTRL_FSM 0x13004c +#define IGU_REG_SB_INT_BEFORE_MASK_LSB 0x13015c +#define IGU_REG_SB_INT_BEFORE_MASK_MSB 0x130160 +#define IGU_REG_SB_MASK_LSB 0x130164 +#define IGU_REG_SB_MASK_MSB 0x130168 +/* [RW 16] Number of command that were dropped without causing an interrupt + * due to: read access for WO BAR address; or write access for RO BAR + * address or any access for reserved address or PCI function error is set + * and address is not MSIX; PBA or cleanup */ +#define IGU_REG_SILENT_DROP 0x13016c +/* [RW 10] Number of MSI/MSIX/ATTN messages sent for the function: 0-63 - + * number of MSIX messages per VF; 64-67 - number of MSI/MSIX messages per + * PF; 68-71 number of ATTN messages per PF */ +#define IGU_REG_STATISTIC_NUM_MESSAGE_SENT 0x130800 +/* [RW 32] Number of cycles the timer mask masking the IGU interrupt when a + * timer mask command arrives. Value must be bigger than 100. */ +#define IGU_REG_TIMER_MASKING_VALUE 0x13003c +#define IGU_REG_TRAILING_EDGE_LATCH 0x130104 +#define IGU_REG_VF_CONFIGURATION 0x130170 +/* [WB_R 32] Each bit represent write done pending bits status for that SB + * (MSI/MSIX message was sent and write done was not received yet). 0 = + * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_WRITE_DONE_PENDING 0x130480 +#define MCP_A_REG_MCPR_SCRATCH 0x3a0000 #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 #define MCP_REG_MCPR_NVM_ADDR 0x8640c #define MCP_REG_MCPR_NVM_CFG4 0x8642c @@ -880,6 +1024,11 @@ rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ #define MISC_REG_AEU_AFTER_INVERT_4_MCP 0xa458 +/* [R 32] Read fifth 32 bit after inversion of function 0. Mapped as + * follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC + * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6] + * CNIG attention (reserved); [7] CNIG parity (reserved); [31-8] Reserved; */ +#define MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 0xa700 /* [W 14] write to this register results with the clear of the latched signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP @@ -1251,6 +1400,7 @@ #define MISC_REG_E1HMF_MODE 0xa5f8 /* [RW 32] Debug only: spare RW register reset by core reset */ #define MISC_REG_GENERIC_CR_0 0xa460 +#define MISC_REG_GENERIC_CR_1 0xa464 /* [RW 32] Debug only: spare RW register reset by por reset */ #define MISC_REG_GENERIC_POR_1 0xa474 /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of @@ -1373,6 +1523,14 @@ #define MISC_REG_PLL_STORM_CTRL_2 0xa298 #define MISC_REG_PLL_STORM_CTRL_3 0xa29c #define MISC_REG_PLL_STORM_CTRL_4 0xa2a0 +/* [R 1] Status of 4 port mode enable input pin. */ +#define MISC_REG_PORT4MODE_EN 0xa750 +/* [RW 2] 4 port mode enable overwrite.[0] - Overwrite control; if it is 0 - + * the port4mode_en output is equal to 4 port mode input pin; if it is 1 - + * the port4mode_en output is equal to bit[1] of this register; [1] - + * Overwrite value. If bit[0] of this register is 1 this is the value that + * receives the port4mode_en output . */ +#define MISC_REG_PORT4MODE_EN_OVWR 0xa720 /* [RW 32] reset reg#2; rite/read one = the specific block is out of reset; write/read zero = the specific block is in reset; addr 0-wr- the write value will be written to the register; addr 1-set - one will be written @@ -1656,8 +1814,91 @@ /* [R 32] Interrupt register #0 read */ #define NIG_REG_NIG_INT_STS_0 0x103b0 #define NIG_REG_NIG_INT_STS_1 0x103c0 -/* [R 32] Parity register #0 read */ +/* [R 32] Legacy E1 and E1H location for parity error status register. */ #define NIG_REG_NIG_PRTY_STS 0x103d0 +/* [R 32] Parity register #0 read */ +#define NIG_REG_NIG_PRTY_STS_0 0x183bc +#define NIG_REG_NIG_PRTY_STS_1 0x183cc +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 +/* [RW 1] HW PFC enable bit. Set this bit to enable the PFC functionality in + * the NIG. Other flow control modes such as PAUSE and SAFC/LLFC should be + * disabled when this bit is set. */ +#define NIG_REG_P0_HWPFC_ENABLE 0x18078 +#define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 +#define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS0_PRIORITY_MASK 0x18058 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS1_PRIORITY_MASK 0x1805c +/* [RW 15] Specify which of the credit registers the client is to be mapped + * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For + * clients that are not subject to WFQ credit blocking - their + * specifications here are not used. */ +#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP 0x180f0 +/* [RW 5] Specify whether the client competes directly in the strict + * priority arbiter. The bits are mapped according to client ID (client IDs + * are defined in tx_arb_priority_client). Default value is set to enable + * strict priorities for clients 0-2 -- management and debug traffic. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT 0x180e8 +/* [RW 5] Specify whether the client is subject to WFQ credit blocking. The + * bits are mapped according to client ID (client IDs are defined in + * tx_arb_priority_client). Default value is 0 for not using WFQ credit + * blocking. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x180ec +/* [RW 32] Specify the upper bound that credit register 0 is allowed to + * reach. */ +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0 0x1810c +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1 0x18110 +/* [RW 32] Specify the weight (in bytes) to be added to credit register 0 + * when it is time to increment. */ +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0 0x180f8 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1 0x180fc +/* [RW 12] Specify the number of strict priority arbitration slots between + * two round-robin arbitration slots to avoid starvation. A value of 0 means + * no strict priority cycles - the strict priority with anti-starvation + * arbiter becomes a round-robin arbiter. */ +#define NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS 0x180f4 +/* [RW 15] Specify the client number to be assigned to each priority of the + * strict priority arbiter. Priority 0 is the highest priority. Bits [2:0] + * are for priority 0 client; bits [14:12] are for priority 4 client. The + * clients are assigned the following IDs: 0-management; 1-debug traffic + * from this port; 2-debug traffic from other port; 3-COS0 traffic; 4-COS1 + * traffic. The reset value[14:0] is set to 0x4688 (15'b100_011_010_001_000) + * for management at priority 0; debug traffic at priorities 1 and 2; COS0 + * traffic at priority 3; and COS1 traffic at priority 4. */ +#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT 0x180e4 +#define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 +#define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS0_PRIORITY_MASK 0x181ac +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS1_PRIORITY_MASK 0x181b0 /* [RW 1] Pause enable for port0. This register may get 1 only when ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ @@ -1742,6 +1983,10 @@ /* [RW 1] Disable processing further tasks from port 4 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c +#define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after @@ -1765,6 +2010,8 @@ #define PBF_REG_MAC_IF1_ENABLE 0x140034 /* [RW 1] Enable for the loopback interface. */ #define PBF_REG_MAC_LB_ENABLE 0x140040 +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause not suppoterd. */ #define PBF_REG_P0_ARB_THRSH 0x1400e4 @@ -1804,6 +2051,259 @@ #define PB_REG_PB_PRTY_MASK 0x38 /* [R 4] Parity register #0 read */ #define PB_REG_PB_PRTY_STS 0x2c +#define PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW (0x1<<8) +#define PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR (0x1<<1) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN (0x1<<6) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN (0x1<<7) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN (0x1<<4) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN (0x1<<3) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN (0x1<<5) +#define PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN (0x1<<2) +/* [R 8] Config space A attention dirty bits. Each bit indicates that the + * corresponding PF generates config space A attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_a_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_A_REQUEST 0x9010 +/* [R 8] Config space B attention dirty bits. Each bit indicates that the + * corresponding PF generates config space B attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_b_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_B_REQUEST 0x9014 +/* [RW 1] Type A PF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_A_PF_ENABLE 0x9194 +/* [RW 18] Type B VF inbound interrupt table for CSDM: bits[17:9]-mask; + * its[8:0]-address. Bits [1:0] must be zero (DW resolution address). */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF 0x916c +/* [RW 1] Type B VF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF_ENABLE 0x919c +/* [RW 16] Start offset of CSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_A 0x9100 +/* [RW 16] Start offset of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_B 0x9108 +/* [RW 5] VF Shift of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_VF_SHIFT_B 0x9110 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_CSDM_ZONE_A_SIZE_PF 0x91ac +/* [R 8] FLR request attention dirty bits for PFs 0 to 7. Each bit indicates + * that the FLR register of the corresponding PF was set. Set by PXP. Reset + * by MCP writing 1 to flr_request_pf_7_0_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0 0x9028 +/* [W 8] FLR request attention dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR 0x9418 +/* [R 32] FLR request attention dirty bits for VFs 96 to 127. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_127_96_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_127_96 0x9024 +/* [R 32] FLR request attention dirty bits for VFs 0 to 31. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_31_0_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_31_0 0x9018 +/* [R 32] FLR request attention dirty bits for VFs 32 to 63. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_63_32_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_63_32 0x901c +/* [R 32] FLR request attention dirty bits for VFs 64 to 95. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_95_64_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_95_64 0x9020 +/* [R 8] Each bit indicates an incorrect behavior in user RX interface. Bit + * 0 - Target memory read arrived with a correctable error. Bit 1 - Target + * memory read arrived with an uncorrectable error. Bit 2 - Configuration RW + * arrived with a correctable error. Bit 3 - Configuration RW arrived with + * an uncorrectable error. Bit 4 - Completion with Configuration Request + * Retry Status. Bit 5 - Expansion ROM access received with a write request. + * Bit 6 - Completion with pcie_rx_err of 0000; CMPL_STATUS of non-zero; and + * pcie_rx_last not asserted. Bit 7 - Completion with pcie_rx_err of 1010; + * and pcie_rx_last not asserted. */ +#define PGLUE_B_REG_INCORRECT_RCV_DETAILS 0x9068 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER 0x942c +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ 0x9430 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE 0x9434 +#define PGLUE_B_REG_INTERNAL_VFID_ENABLE 0x9438 +/* [R 9] Interrupt register #0 read */ +#define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 +/* [RC 9] Interrupt register #0 read clear */ +#define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c +/* [R 2] Parity register #0 read */ +#define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8 +/* [R 13] Details of first request received with error. [2:0] - PFID. [3] - + * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion + * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 - + * completer abort. 3 - Illegal value for this field. [12] valid - indicates + * if there was a completion error since the last time this register was + * cleared. */ +#define PGLUE_B_REG_RX_ERR_DETAILS 0x9080 +/* [R 18] Details of first ATS Translation Completion request received with + * error. [2:0] - PFID. [3] - VF_VALID. [9:4] - VFID. [11:10] - Error Code - + * 0 - Indicates Completion Timeout of a User Tx non-posted request. 1 - + * unsupported request. 2 - completer abort. 3 - Illegal value for this + * field. [16:12] - ATC OTB EntryID. [17] valid - indicates if there was a + * completion error since the last time this register was cleared. */ +#define PGLUE_B_REG_RX_TCPL_ERR_DETAILS 0x9084 +/* [W 8] Debug only - Shadow BME bits clear for PFs 0 to 7. MCP writes 1 to + * a bit in this register in order to clear the corresponding bit in + * shadow_bme_pf_7_0 register. MCP should never use this unless a + * work-around is needed. Note: register contains bits from both paths. */ +#define PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR 0x9458 +/* [R 8] SR IOV disabled attention dirty bits. Each bit indicates that the + * VF enable register of the corresponding PF is written to 0 and was + * previously 1. Set by PXP. Reset by MCP writing 1 to + * sr_iov_disabled_request_clr. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_SR_IOV_DISABLED_REQUEST 0x9030 +/* [R 32] Indicates the status of tags 32-63. 0 - tags is used - read + * completion did not return yet. 1 - tag is unused. Same functionality as + * pxp2_registers_pgl_exp_rom_data2 for tags 0-31. */ +#define PGLUE_B_REG_TAGS_63_32 0x9244 +/* [RW 1] Type A PF enable inbound interrupt table for TSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_TSDM_INB_INT_A_PF_ENABLE 0x9170 +/* [RW 16] Start offset of TSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_A 0x90c4 +/* [RW 16] Start offset of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_B 0x90cc +/* [RW 5] VF Shift of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_VF_SHIFT_B 0x90d4 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_TSDM_ZONE_A_SIZE_PF 0x91a0 +/* [R 32] Address [31:0] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_31_0 0x9098 +/* [R 32] Address [63:32] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_63_32 0x909c +/* [R 31] Details of first read request not submitted due to error. [4:0] + * VQID. [5] TREQ. 1 - Indicates the request is a Translation Request. + * [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] - + * VFID. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS 0x90a0 +/* [R 26] Details of first read request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS2 0x90a4 +/* [R 32] Address [31:0] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_31_0 0x9088 +/* [R 32] Address [63:32] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_63_32 0x908c +/* [R 31] Details of first write request not submitted due to error. [4:0] + * VQID. [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] + * - VFID. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS 0x9090 +/* [R 26] Details of first write request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS2 0x9094 +/* [RW 10] Type A PF/VF inbound interrupt table for USDM: bits[9:5]-mask; + * its[4:0]-address relative to start_offset_a. Bits [1:0] can have any + * value (Byte resolution address). */ +#define PGLUE_B_REG_USDM_INB_INT_A_0 0x9128 +#define PGLUE_B_REG_USDM_INB_INT_A_1 0x912c +#define PGLUE_B_REG_USDM_INB_INT_A_2 0x9130 +#define PGLUE_B_REG_USDM_INB_INT_A_3 0x9134 +#define PGLUE_B_REG_USDM_INB_INT_A_4 0x9138 +#define PGLUE_B_REG_USDM_INB_INT_A_5 0x913c +#define PGLUE_B_REG_USDM_INB_INT_A_6 0x9140 +/* [RW 1] Type A PF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_PF_ENABLE 0x917c +/* [RW 1] Type A VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_VF_ENABLE 0x9180 +/* [RW 1] Type B VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_B_VF_ENABLE 0x9184 +/* [RW 16] Start offset of USDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_A 0x90d8 +/* [RW 16] Start offset of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_B 0x90e0 +/* [RW 5] VF Shift of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_VF_SHIFT_B 0x90e8 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_USDM_ZONE_A_SIZE_PF 0x91a4 +/* [R 26] Details of first target VF request accessing VF GRC space that + * failed permission check. [14:0] Address. [15] w_nr: 0 - Read; 1 - Write. + * [21:16] VFID. [24:22] - PFID. [25] valid - indicates if there was a + * request accessing VF GRC space that failed permission check since the + * last time this register was cleared. Permission checks are: function + * permission; R/W permission; address range permission. */ +#define PGLUE_B_REG_VF_GRC_SPACE_VIOLATION_DETAILS 0x9234 +/* [R 31] Details of first target VF request with length violation (too many + * DWs) accessing BAR0. [12:0] Address in DWs (bits [14:2] of byte address). + * [14:13] BAR. [20:15] VFID. [23:21] - PFID. [29:24] - Length in DWs. [30] + * valid - indicates if there was a request with length violation since the + * last time this register was cleared. Length violations: length of more + * than 2DWs; length of 2DWs and address not QW aligned; window is GRC and + * length is more than 1 DW. */ +#define PGLUE_B_REG_VF_LENGTH_VIOLATION_DETAILS 0x9230 +/* [R 8] Was_error indication dirty bits for PFs 0 to 7. Each bit indicates + * that there was a completion with uncorrectable error for the + * corresponding PF. Set by PXP. Reset by MCP writing 1 to + * was_error_pf_7_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0 0x907c +/* [W 8] Was_error indication dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR 0x9470 +/* [R 32] Was_error indication dirty bits for VFs 96 to 127. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_127_96_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96 0x9078 +/* [W 32] Was_error indication dirty bits clear for VFs 96 to 127. MCP + * writes 1 to a bit in this register in order to clear the corresponding + * bit in was_error_vf_127_96 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR 0x9474 +/* [R 32] Was_error indication dirty bits for VFs 0 to 31. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_31_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0 0x906c +/* [W 32] Was_error indication dirty bits clear for VFs 0 to 31. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_31_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR 0x9478 +/* [R 32] Was_error indication dirty bits for VFs 32 to 63. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_63_32_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32 0x9070 +/* [W 32] Was_error indication dirty bits clear for VFs 32 to 63. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_63_32 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR 0x947c +/* [R 32] Was_error indication dirty bits for VFs 64 to 95. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_95_64_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64 0x9074 +/* [W 32] Was_error indication dirty bits clear for VFs 64 to 95. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_95_64 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR 0x9480 +/* [RW 1] Type A PF enable inbound interrupt table for XSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_XSDM_INB_INT_A_PF_ENABLE 0x9188 +/* [RW 16] Start offset of XSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_A 0x90ec +/* [RW 16] Start offset of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_B 0x90f4 +/* [RW 5] VF Shift of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_VF_SHIFT_B 0x90fc +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_XSDM_ZONE_A_SIZE_PF 0x91a8 #define PRS_REG_A_PRSU_20 0x40134 /* [R 8] debug only: CFC load request current credit. Transaction based. */ #define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164 @@ -1866,9 +2366,13 @@ #define PRS_REG_FLUSH_REGIONS_TYPE_5 0x40018 #define PRS_REG_FLUSH_REGIONS_TYPE_6 0x4001c #define PRS_REG_FLUSH_REGIONS_TYPE_7 0x40020 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PRS_REG_HDRS_AFTER_BASIC 0x40238 /* [RW 4] The increment value to send in the CFC load request message */ #define PRS_REG_INC_VALUE 0x40048 -/* [RW 1] If set indicates not to send messages to CFC on received packets */ +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PRS_REG_MUST_HAVE_HDRS 0x40254 #define PRS_REG_NIC_MODE 0x40138 /* [RW 8] The 8-bit event ID for cases where there is no match on the connection. Used in packet start message to TCM. */ @@ -1919,6 +2423,13 @@ #define PRS_REG_TCM_CURRENT_CREDIT 0x40160 /* [R 8] debug only: TSDM current credit. Transaction based. */ #define PRS_REG_TSDM_CURRENT_CREDIT 0x4015c +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT (0x1<<19) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF (0x1<<20) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN (0x1<<22) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED (0x1<<23) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED (0x1<<24) +#define PXP2_PXP2_INT_STS_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) +#define PXP2_PXP2_INT_STS_CLR_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) /* [R 6] Debug only: Number of used entries in the data FIFO */ #define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c /* [R 7] Debug only: Number of used entries in the header FIFO */ @@ -2244,8 +2755,17 @@ /* [RW 1] When '1'; requests will enter input buffers but wont get out towards the glue */ #define PXP2_REG_RQ_DISABLE_INPUTS 0x120330 -/* [RW 1] 1 - SR will be aligned by 64B; 0 - SR will be aligned by 8B */ +/* [RW 4] Determines alignment of write SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ #define PXP2_REG_RQ_DRAM_ALIGN 0x1205b0 +/* [RW 4] Determines alignment of read SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ +#define PXP2_REG_RQ_DRAM_ALIGN_RD 0x12092c +/* [RW 1] when set the new alignment method (E2) will be applied; when reset + * the original alignment method (E1 E1H) will be applied */ +#define PXP2_REG_RQ_DRAM_ALIGN_SEL 0x120930 /* [RW 1] If 1 ILT failiue will not result in ELT access; An interrupt will be asserted */ #define PXP2_REG_RQ_ELT_DISABLE 0x12066c @@ -2436,7 +2956,8 @@ #define PXP_REG_PXP_INT_STS_1 0x103078 /* [RC 32] Interrupt register #0 read clear */ #define PXP_REG_PXP_INT_STS_CLR_0 0x10306c -/* [RW 26] Parity mask register #0 read/write */ +#define PXP_REG_PXP_INT_STS_CLR_1 0x10307c +/* [RW 27] Parity mask register #0 read/write */ #define PXP_REG_PXP_PRTY_MASK 0x103094 /* [R 26] Parity register #0 read */ #define PXP_REG_PXP_PRTY_STS 0x103088 @@ -2566,6 +3087,7 @@ #define QM_REG_PAUSESTATE7 0x16e698 /* [RW 2] The PCI attributes field used in the PCI request. */ #define QM_REG_PCIREQAT 0x168054 +#define QM_REG_PF_EN 0x16e70c /* [R 16] The byte credit of port 0 */ #define QM_REG_PORT0BYTECRD 0x168300 /* [R 16] The byte credit of port 1 */ @@ -3402,6 +3924,14 @@ /* [R 32] Parity register #0 read */ #define TSEM_REG_TSEM_PRTY_STS_0 0x180114 #define TSEM_REG_TSEM_PRTY_STS_1 0x180124 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define TSEM_REG_VFPF_ERR_NUM 0x180380 +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [10:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 12'ha64. */ +#define UCM_REG_AG_CTX 0xe2000 /* [R 5] Used to read the XX protection CAM occupancy counter. */ #define UCM_REG_CAM_OCCUP 0xe0170 /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3851,6 +4381,17 @@ /* [R 32] Parity register #0 read */ #define USEM_REG_USEM_PRTY_STS_0 0x300124 #define USEM_REG_USEM_PRTY_STS_1 0x300134 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define USEM_REG_VFPF_ERR_NUM 0x300380 +#define VFC_MEMORIES_RST_REG_CAM_RST (0x1<<0) +#define VFC_MEMORIES_RST_REG_RAM_RST (0x1<<1) +#define VFC_REG_MEMORIES_RST 0x1943c +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [12:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 13'ha64. */ +#define XCM_REG_AG_CTX 0x28000 /* [RW 2] The queue index for registration on Aux1 counter flag. */ #define XCM_REG_AUX1_Q 0x20134 /* [RW 2] Per each decision rule the queue index to register to. */ @@ -4333,6 +4874,9 @@ #define XSEM_REG_TS_8_AS 0x280058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define XSEM_REG_TS_9_AS 0x28005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define XSEM_REG_VFPF_ERR_NUM 0x280380 /* [RW 32] Interrupt mask register #0 read/write */ #define XSEM_REG_XSEM_INT_MASK_0 0x280110 #define XSEM_REG_XSEM_INT_MASK_1 0x280120 @@ -4371,6 +4915,23 @@ #define BIGMAC_REGISTER_TX_SOURCE_ADDR (0x08<<3) #define BIGMAC_REGISTER_TX_STAT_GTBYT (0x20<<3) #define BIGMAC_REGISTER_TX_STAT_GTPKT (0x0C<<3) +#define BIGMAC2_REGISTER_BMAC_CONTROL (0x00<<3) +#define BIGMAC2_REGISTER_BMAC_XGXS_CONTROL (0x01<<3) +#define BIGMAC2_REGISTER_CNT_MAX_SIZE (0x05<<3) +#define BIGMAC2_REGISTER_PFC_CONTROL (0x06<<3) +#define BIGMAC2_REGISTER_RX_CONTROL (0x3A<<3) +#define BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS (0x62<<3) +#define BIGMAC2_REGISTER_RX_MAX_SIZE (0x3C<<3) +#define BIGMAC2_REGISTER_RX_STAT_GR64 (0x40<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRIPJ (0x5f<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRPP (0x51<<3) +#define BIGMAC2_REGISTER_TX_CONTROL (0x1C<<3) +#define BIGMAC2_REGISTER_TX_MAX_SIZE (0x1E<<3) +#define BIGMAC2_REGISTER_TX_PAUSE_CONTROL (0x20<<3) +#define BIGMAC2_REGISTER_TX_SOURCE_ADDR (0x1D<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTBYT (0x39<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPOK (0x22<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPP (0x24<<3) #define EMAC_LED_1000MB_OVERRIDE (1L<<1) #define EMAC_LED_100MB_OVERRIDE (1L<<2) #define EMAC_LED_10MB_OVERRIDE (1L<<3) @@ -4478,6 +5039,8 @@ #define HW_LOCK_RESOURCE_SPIO 2 #define HW_LOCK_RESOURCE_UNDI 5 #define PRS_FLAG_OVERETH_IPV4 1 +#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) @@ -4504,6 +5067,8 @@ #define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20) #define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0) #define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31) +#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2) #define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5) @@ -4796,6 +5361,253 @@ #define PCI_ID_VAL1 0x434 #define PCI_ID_VAL2 0x438 +#define PXPCS_TL_CONTROL_5 0x814 +#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/ +#define PXPCS_TL_CONTROL_5_BOUNDARY4K_ERR_ATTN (1 << 28) /*WC*/ +#define PXPCS_TL_CONTROL_5_MRRS_ERR_ATTN (1 << 27) /*WC*/ +#define PXPCS_TL_CONTROL_5_MPS_ERR_ATTN (1 << 26) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_BRIDGE_FORWARD_ERR (1 << 25) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_TXINTF_OVERFLOW (1 << 24) /*WC*/ +#define PXPCS_TL_CONTROL_5_PHY_ERR_ATTN (1 << 23) /*RO*/ +#define PXPCS_TL_CONTROL_5_DL_ERR_ATTN (1 << 22) /*RO*/ +#define PXPCS_TL_CONTROL_5_TTX_ERR_NP_TAG_IN_USE (1 << 21) /*WC*/ +#define PXPCS_TL_CONTROL_5_TRX_ERR_UNEXP_RTAG (1 << 20) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT1 (1 << 19) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 (1 << 18) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC1 (1 << 17) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP1 (1 << 16) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW1 (1 << 15) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL1 (1 << 14) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT1 (1 << 13) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT1 (1 << 12) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL1 (1 << 11) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP1 (1 << 10) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT (1 << 9) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT (1 << 8) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC (1 << 7) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP (1 << 6) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW (1 << 5) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL (1 << 4) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT (1 << 3) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT (1 << 2) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL (1 << 1) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP (1 << 0) /*WC*/ + + +#define PXPCS_TL_FUNC345_STAT 0x854 +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT4 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4\ + (1 << 28) /* Unsupported Request Error Status in function4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC4\ + (1 << 27) /* ECRC Error TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP4\ + (1 << 26) /* Malformed TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW4\ + (1 << 25) /* Receiver Overflow Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL4\ + (1 << 24) /* Unexpected Completion Status Status in function 4, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT4\ + (1 << 23) /* Receive UR Statusin function 4. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT4\ + (1 << 22) /* Completer Timeout Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL4\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 4, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP4\ + (1 << 20) /* Poisoned Error Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT3 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3\ + (1 << 18) /* Unsupported Request Error Status in function3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC3\ + (1 << 17) /* ECRC Error TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP3\ + (1 << 16) /* Malformed TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW3\ + (1 << 15) /* Receiver Overflow Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL3\ + (1 << 14) /* Unexpected Completion Status Status in function 3, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT3\ + (1 << 13) /* Receive UR Statusin function 3. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT3\ + (1 << 12) /* Completer Timeout Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL3\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 3, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP3\ + (1 << 10) /* Poisoned Error Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT2 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2\ + (1 << 8) /* Unsupported Request Error Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC2\ + (1 << 7) /* ECRC Error TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP2\ + (1 << 6) /* Malformed TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW2\ + (1 << 5) /* Receiver Overflow Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL2\ + (1 << 4) /* Unexpected Completion Status Status for Function 2, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT2\ + (1 << 3) /* Receive UR Statusfor Function 2. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT2\ + (1 << 2) /* Completer Timeout Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL2\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 2, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP2\ + (1 << 0) /* Poisoned Error Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define PXPCS_TL_FUNC678_STAT 0x85C +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT7 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7\ + (1 << 28) /* Unsupported Request Error Status in function7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC7\ + (1 << 27) /* ECRC Error TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP7\ + (1 << 26) /* Malformed TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW7\ + (1 << 25) /* Receiver Overflow Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL7\ + (1 << 24) /* Unexpected Completion Status Status in function 7, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT7\ + (1 << 23) /* Receive UR Statusin function 7. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT7\ + (1 << 22) /* Completer Timeout Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL7\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 7, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP7\ + (1 << 20) /* Poisoned Error Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT6 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6\ + (1 << 18) /* Unsupported Request Error Status in function6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC6\ + (1 << 17) /* ECRC Error TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP6\ + (1 << 16) /* Malformed TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW6\ + (1 << 15) /* Receiver Overflow Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL6\ + (1 << 14) /* Unexpected Completion Status Status in function 6, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT6\ + (1 << 13) /* Receive UR Statusin function 6. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT6\ + (1 << 12) /* Completer Timeout Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL6\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 6, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP6\ + (1 << 10) /* Poisoned Error Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT5 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5\ + (1 << 8) /* Unsupported Request Error Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC5\ + (1 << 7) /* ECRC Error TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP5\ + (1 << 6) /* Malformed TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW5\ + (1 << 5) /* Receiver Overflow Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL5\ + (1 << 4) /* Unexpected Completion Status Status for Function 5, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT5\ + (1 << 3) /* Receive UR Statusfor Function 5. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT5\ + (1 << 2) /* Completer Timeout Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL5\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 5, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP5\ + (1 << 0) /* Poisoned Error Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define BAR_USTRORM_INTMEM 0x400000 +#define BAR_CSTRORM_INTMEM 0x410000 +#define BAR_XSTRORM_INTMEM 0x420000 +#define BAR_TSTRORM_INTMEM 0x430000 + +/* for accessing the IGU in case of status block ACK */ +#define BAR_IGU_INTMEM 0x440000 + +#define BAR_DOORBELL_OFFSET 0x800000 + +#define BAR_ME_REGISTER 0x450000 +#define ME_REG_PF_NUM_SHIFT 0 +#define ME_REG_PF_NUM\ + (7L<executer_idx) { int loader_idx = PMF_DMAE_C(bp); + u32 opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); + opcode = bnx2x_dmae_opcode_clr_src_reset(opcode); memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : - DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = opcode; dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + @@ -257,19 +249,10 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, false, 0); dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC); dmae->src_addr_lo = bp->port.port_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); @@ -280,7 +263,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + @@ -301,7 +284,6 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) { struct dmae_command *dmae; int port = BP_PORT(bp); - int vn = BP_E1HVN(bp); u32 opcode; int loader_idx = PMF_DMAE_C(bp); u32 mac_addr; @@ -316,16 +298,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) bp->executer_idx = 0; /* MCP */ - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); if (bp->port.port_stx) { @@ -356,16 +330,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) } /* MAC */ - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_GRC); if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { @@ -376,13 +342,21 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_TX_STAT_GTBYT */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + } else { + dmae->src_addr_lo = (mac_addr + + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + dmae->len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT - + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + } + dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -391,15 +365,31 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_RX_STAT_GRIPJ */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + } else { + dmae->src_addr_lo = + (mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ - + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + } + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -480,16 +470,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; dmae->src_addr_hi = 0; @@ -519,16 +501,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -568,7 +542,6 @@ static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp) { - struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; struct { @@ -576,35 +549,74 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) u32 hi; } diff; - UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); - UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); - UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); - UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); - UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); - UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); - UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); - UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); - UPDATE_STAT64(tx_stat_gt127, + if (CHIP_IS_E1x(bp)) { + struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); + + /* the macros below will use "bmac1_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, tx_stat_etherstatspkts65octetsto127octets); - UPDATE_STAT64(tx_stat_gt255, + UPDATE_STAT64(tx_stat_gt255, tx_stat_etherstatspkts128octetsto255octets); - UPDATE_STAT64(tx_stat_gt511, + UPDATE_STAT64(tx_stat_gt511, tx_stat_etherstatspkts256octetsto511octets); - UPDATE_STAT64(tx_stat_gt1023, + UPDATE_STAT64(tx_stat_gt1023, tx_stat_etherstatspkts512octetsto1023octets); - UPDATE_STAT64(tx_stat_gt1518, + UPDATE_STAT64(tx_stat_gt1518, tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); - UPDATE_STAT64(tx_stat_gterr, + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + + } else { + struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats); + + /* the macros below will use "bmac2_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, + tx_stat_etherstatspkts65octetsto127octets); + UPDATE_STAT64(tx_stat_gt255, + tx_stat_etherstatspkts128octetsto255octets); + UPDATE_STAT64(tx_stat_gt511, + tx_stat_etherstatspkts256octetsto511octets); + UPDATE_STAT64(tx_stat_gt1023, + tx_stat_etherstatspkts512octetsto1023octets); + UPDATE_STAT64(tx_stat_gt1518, + tx_stat_etherstatspkts1024octetsto1522octets); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, + tx_stat_dot3statsinternalmactransmiterrors); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + } estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_bmac_xpf_hi; @@ -1121,24 +1133,17 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, false, 0); if (bp->port.port_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); if (bp->func_stx) - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_GRC); else - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1162,7 +1167,8 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) if (bp->func_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = + bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -1255,16 +1261,8 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) bp->executer_idx = 0; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1282,8 +1280,6 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) static void bnx2x_func_stats_base_init(struct bnx2x *bp) { int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX; - int port = BP_PORT(bp); - int func; u32 func_stx; /* sanity */ @@ -1296,9 +1292,9 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp) func_stx = bp->func_stx; for (vn = VN_0; vn < vn_max; vn++) { - func = 2*vn + port; + int mb_idx = !CHIP_IS_E2(bp) ? 2*vn + BP_PORT(bp) : vn; - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); bnx2x_func_stats_init(bp); bnx2x_hw_stats_post(bp); bnx2x_stats_comp(bp); @@ -1322,16 +1318,8 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = bp->func_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); @@ -1349,7 +1337,7 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) void bnx2x_stats_init(struct bnx2x *bp) { int port = BP_PORT(bp); - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); int i; bp->stats_pending = 0; @@ -1359,7 +1347,7 @@ void bnx2x_stats_init(struct bnx2x *bp) /* port and func stats for management */ if (!BP_NOMCP(bp)) { bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); } else { bp->port.port_stx = 0; diff --git a/firmware/Makefile b/firmware/Makefile index e0a3439ab312..494a167c6552 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -33,7 +33,8 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ - bnx2x/bnx2x-e1h-6.0.34.0.fw + bnx2x/bnx2x-e1h-6.0.34.0.fw \ + bnx2x/bnx2x-e2-6.0.34.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ -- cgit v1.2.3 From 749a85033ec7c5c0fa54a0023fd5d59eb5e57a20 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:29:05 +0000 Subject: bnx2x: remove unused parameter in reuse_rx_skb() Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 4 ++-- drivers/net/bnx2x/bnx2x_cmn.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index cffa778ec5bf..5b8c0b6369ff 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -595,7 +595,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_reserve(new_skb, pad); skb_put(new_skb, len); - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); skb = new_skb; @@ -614,7 +614,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) "of alloc failure\n"); fp->eth_q_stats.rx_skb_alloc_failed++; reuse_rx: - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); goto next_rx; } diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 41d0a177db7f..73ed5a63761f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -696,7 +696,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, * so there is no need to check for dma_mapping_error(). */ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, - struct sk_buff *skb, u16 cons, u16 prod) + u16 cons, u16 prod) { struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; -- cgit v1.2.3 From c518cd1c7aca2e2a65edcf4fa5ce4160d59878c2 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:29:41 +0000 Subject: bnx2x: remove unused fields in main driver structure Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 6f8e2666f05f..9b78a0487791 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1053,15 +1053,8 @@ struct bnx2x { #ifdef BCM_CNIC u32 cnic_flags; #define BNX2X_CNIC_FLAG_MAC_SET 1 - - void *t1; - dma_addr_t t1_mapping; void *t2; dma_addr_t t2_mapping; - void *timers; - dma_addr_t timers_mapping; - void *qm; - dma_addr_t qm_mapping; struct cnic_ops *cnic_ops; void *cnic_data; u32 cnic_tag; -- cgit v1.2.3 From 4bca60f44b4adca3197f61294956edda5bf9acea Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:30:27 +0000 Subject: bnx2x: use proper constants for dma_unmap* calls Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 5b8c0b6369ff..7ee9af020ed6 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -54,7 +54,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), - BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE); + BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); nbd = le16_to_cpu(tx_start_bd->nbd) - 1; #ifdef BNX2X_STOP_ON_ERROR diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 73ed5a63761f..f08a42ad6b47 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -597,7 +597,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, return; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), - SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); __free_pages(page, PAGES_PER_SGE_SHIFT); sw_buf->page = NULL; -- cgit v1.2.3 From 217de5aaed833982c420fc37d82272d84eaefe64 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:31:20 +0000 Subject: bnx2x: use L1_CACHE_BYTES instead of magic number Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 7ee9af020ed6..da46309a855c 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -358,7 +358,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, #endif prefetch(skb); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); #ifdef BNX2X_STOP_ON_ERROR if (pad + len > bp->rx_buf_size) { @@ -561,7 +561,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) dma_unmap_addr(rx_buf, mapping), pad + RX_COPY_THRESH, DMA_FROM_DEVICE); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); /* is this an error packet? */ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { -- cgit v1.2.3 From d6214d7aaa9a82b206dac9e3b0665c49c522a271 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:32:10 +0000 Subject: bnx2x: move msix table initialization to probe() Decide which interrupt mode to use (MSI-X, MSI, INTa) only once in probe() and initialize appropriate structures. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 3 + drivers/net/bnx2x/bnx2x_cmn.c | 206 +++++++++++++++++++---------------------- drivers/net/bnx2x/bnx2x_cmn.h | 75 ++++++++++++++- drivers/net/bnx2x/bnx2x_main.c | 78 ++++++++++++---- 4 files changed, 228 insertions(+), 134 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 9b78a0487791..d80809f5ffc9 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -308,6 +308,7 @@ union host_hc_status_block { struct bnx2x_fastpath { +#define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; union host_hc_status_block status_blk; /* chip independed shortcuts into sb structure */ @@ -920,8 +921,10 @@ struct bnx2x { #define USING_DAC_FLAG 0x10 #define USING_MSIX_FLAG 0x20 #define USING_MSI_FLAG 0x40 + #define TPA_ENABLE_FLAG 0x80 #define NO_MCP_FLAG 0x100 +#define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) #define HW_VLAN_TX_FLAG 0x400 #define HW_VLAN_RX_FLAG 0x800 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index da46309a855c..2998969beacc 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -29,7 +29,6 @@ #include "bnx2x_init.h" -static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx * return idx of last bd freed @@ -989,55 +988,49 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) } } -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) +void bnx2x_free_irq(struct bnx2x *bp) { - if (bp->flags & USING_MSIX_FLAG) { - if (!disable_only) - bnx2x_free_msix_irqs(bp); - pci_disable_msix(bp->pdev); - bp->flags &= ~USING_MSIX_FLAG; - - } else if (bp->flags & USING_MSI_FLAG) { - if (!disable_only) - free_irq(bp->pdev->irq, bp->dev); - pci_disable_msi(bp->pdev); - bp->flags &= ~USING_MSI_FLAG; - - } else if (!disable_only) + if (bp->flags & USING_MSIX_FLAG) + bnx2x_free_msix_irqs(bp); + else if (bp->flags & USING_MSI_FLAG) + free_irq(bp->pdev->irq, bp->dev); + else free_irq(bp->pdev->irq, bp->dev); } -static int bnx2x_enable_msix(struct bnx2x *bp) +int bnx2x_enable_msix(struct bnx2x *bp) { - int i, rc, offset = 1; - int igu_vec = 0; + int msix_vec = 0, i, rc, req_cnt; - bp->msix_table[0].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec); + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", + bp->msix_table[0].entry); + msix_vec++; #ifdef BCM_CNIC - igu_vec = BP_L_ID(bp) + offset; - bp->msix_table[1].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec); - offset++; + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d (CNIC)\n", + bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); + msix_vec++; #endif for_each_queue(bp, i) { - igu_vec = BP_L_ID(bp) + offset + i; - bp->msix_table[i + offset].entry = igu_vec; + bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " - "(fastpath #%u)\n", i + offset, igu_vec, i); + "(fastpath #%u)\n", msix_vec, msix_vec, i); + msix_vec++; } - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], - BNX2X_NUM_QUEUES(bp) + offset); + req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); /* * reconfigure number of tx/rx queues according to available * MSI-X vectors */ if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { - /* vectors available for FP */ - int fp_vec = rc - BNX2X_MSIX_VEC_FP_START; + /* how less vectors we will have? */ + int diff = req_cnt - rc; DP(NETIF_MSG_IFUP, "Trying to use less MSI-X vectors: %d\n", rc); @@ -1049,12 +1042,17 @@ static int bnx2x_enable_msix(struct bnx2x *bp) "MSI-X is not attainable rc %d\n", rc); return rc; } - - bp->num_queues = min(bp->num_queues, fp_vec); + /* + * decrease number of queues by number of unallocated entries + */ + bp->num_queues -= diff; DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n", bp->num_queues); } else if (rc) { + /* fall to INTx if not enough memory */ + if (rc == -ENOMEM) + bp->flags |= DISABLE_MSI_FLAG; DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc); return rc; } @@ -1083,7 +1081,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", bp->dev->name, i); - rc = request_irq(bp->msix_table[i + offset].vector, + rc = request_irq(bp->msix_table[offset].vector, bnx2x_msix_fp_int, 0, fp->name, fp); if (rc) { BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); @@ -1091,10 +1089,12 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return -EBUSY; } + offset++; fp->state = BNX2X_FP_STATE_IRQ; } i = BNX2X_NUM_QUEUES(bp); + offset = 1 + CNIC_CONTEXT_USE; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", bp->msix_table[0].vector, @@ -1104,7 +1104,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return 0; } -static int bnx2x_enable_msi(struct bnx2x *bp) +int bnx2x_enable_msi(struct bnx2x *bp) { int rc; @@ -1175,44 +1175,20 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) bnx2x_napi_disable(bp); netif_tx_disable(bp->dev); } -static int bnx2x_set_num_queues(struct bnx2x *bp) -{ - int rc = 0; - switch (bp->int_mode) { - case INT_MODE_MSI: - bnx2x_enable_msi(bp); - /* falling through... */ - case INT_MODE_INTx: +void bnx2x_set_num_queues(struct bnx2x *bp) +{ + switch (bp->multi_mode) { + case ETH_RSS_MODE_DISABLED: bp->num_queues = 1; - DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); + break; + case ETH_RSS_MODE_REGULAR: + bp->num_queues = bnx2x_calc_num_queues(bp); break; default: - /* Set number of queues according to bp->multi_mode value */ - bnx2x_set_num_queues_msix(bp); - - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", - bp->num_queues); - - /* if we can't use MSI-X we only need one fp, - * so try to enable MSI-X with the requested number of fp's - * and fallback to MSI or legacy INTx with one fp - */ - rc = bnx2x_enable_msix(bp); - if (rc) { - /* failed to enable MSI-X */ - bp->num_queues = 1; - - /* Fall to INTx if failed to enable MSI-X due to lack of - * memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); - } - + bp->num_queues = 1; break; } - netif_set_real_num_tx_queues(bp->dev, bp->num_queues); - return netif_set_real_num_rx_queues(bp->dev, bp->num_queues); } static void bnx2x_release_firmware(struct bnx2x *bp) @@ -1243,49 +1219,25 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - rc = bnx2x_set_num_queues(bp); - if (rc) - return rc; - /* must be called before memory allocation and HW init */ bnx2x_ilt_set_info(bp); - if (bnx2x_alloc_mem(bp)) { - bnx2x_free_irq(bp, true); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; + + netif_set_real_num_tx_queues(bp->dev, bp->num_queues); + rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues); + if (rc) { + BNX2X_ERR("Unable to update real_num_rx_queues\n"); + goto load_error0; } for_each_queue(bp, i) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); - for_each_queue(bp, i) - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, 128); - bnx2x_napi_enable(bp); - if (bp->flags & USING_MSIX_FLAG) { - rc = bnx2x_req_msix_irqs(bp); - if (rc) { - bnx2x_free_irq(bp, true); - goto load_error1; - } - } else { - bnx2x_ack_int(bp); - rc = bnx2x_req_irq(bp); - if (rc) { - BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - bnx2x_free_irq(bp, true); - goto load_error1; - } - if (bp->flags & USING_MSI_FLAG) { - bp->dev->irq = bp->pdev->irq; - netdev_info(bp->dev, "using MSI IRQ %d\n", - bp->pdev->irq); - } - } - /* Send LOAD_REQUEST command to MCP Returns the type of LOAD command: if it is the first port to be initialized @@ -1296,11 +1248,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_error2; + goto load_error1; } if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { rc = -EBUSY; /* other port in diagnostic mode */ - goto load_error2; + goto load_error1; } } else { @@ -1341,6 +1293,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) goto load_error2; } + /* Connect to IRQs */ + rc = bnx2x_setup_irqs(bp); if (rc) { bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); goto load_error2; @@ -1481,22 +1435,24 @@ load_error4: #endif load_error3: bnx2x_int_disable_sync(bp, 1); - if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); - } - bp->port.pmf = 0; + /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); -load_error2: + /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); +load_error2: + if (!BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + } + + bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); +load_error0: bnx2x_free_mem(bp); bnx2x_release_firmware(bp); @@ -1544,7 +1500,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_netif_stop(bp, 1); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); } bp->port.pmf = 0; @@ -1553,8 +1509,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; @@ -1624,7 +1579,7 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) * net_device service functions */ -static int bnx2x_poll(struct napi_struct *napi, int budget) +int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, @@ -2261,6 +2216,31 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) return 0; } + +int bnx2x_setup_irqs(struct bnx2x *bp) +{ + int rc = 0; + if (bp->flags & USING_MSIX_FLAG) { + rc = bnx2x_req_msix_irqs(bp); + if (rc) + return rc; + } else { + bnx2x_ack_int(bp); + rc = bnx2x_req_irq(bp); + if (rc) { + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + return rc; + } + if (bp->flags & USING_MSI_FLAG) { + bp->dev->irq = bp->pdev->irq; + netdev_info(bp->dev, "using MSI IRQ %d\n", + bp->pdev->irq); + } + } + + return 0; +} + void bnx2x_free_mem_bp(struct bnx2x *bp) { kfree(bp->fp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index f08a42ad6b47..1d9686ea6b66 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -23,6 +23,7 @@ #include "bnx2x.h" +extern int num_queues; /*********************** Interfaces **************************** * Functions that need to be implemented by each driver version @@ -193,12 +194,12 @@ int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p); /** - * Set number of quueus according to mode + * Set number of queues according to mode * * @param bp * */ -void bnx2x_set_num_queues_msix(struct bnx2x *bp); +void bnx2x_set_num_queues(struct bnx2x *bp); /** * Cleanup chip internals: @@ -325,6 +326,42 @@ int bnx2x_func_stop(struct bnx2x *bp); */ void bnx2x_ilt_set_info(struct bnx2x *bp); +/** + * Fill msix_table, request vectors, update num_queues according + * to number of available vectors + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msix(struct bnx2x *bp); + +/** + * Request msi mode from OS, updated internals accordingly + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msi(struct bnx2x *bp); + +/** + * Request IRQ vectors from OS. + * + * @param bp + * + * @return int + */ +int bnx2x_setup_irqs(struct bnx2x *bp); +/** + * NAPI callback + * + * @param napi + * @param budget + * + * @return int + */ +int bnx2x_poll(struct napi_struct *napi, int budget); static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { barrier(); /* status block is written to by the chip */ @@ -605,9 +642,41 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } +static inline void bnx2x_add_all_napi(struct bnx2x *bp) +{ + int i; + /* Add NAPI objects */ + for_each_queue(bp, i) + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, BNX2X_NAPI_WEIGHT); +} +static inline void bnx2x_del_all_napi(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); +} +static inline void bnx2x_disable_msi(struct bnx2x *bp) +{ + if (bp->flags & USING_MSIX_FLAG) { + pci_disable_msix(bp->pdev); + bp->flags &= ~USING_MSIX_FLAG; + } else if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } +} + +static inline int bnx2x_calc_num_queues(struct bnx2x *bp) +{ + return num_queues ? + min_t(int, num_queues, BNX2X_MAX_QUEUES(bp)) : + min_t(int, num_online_cpus(), BNX2X_MAX_QUEUES(bp)); +} static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) { @@ -877,7 +946,7 @@ void bnx2x_tx_timeout(struct net_device *dev); void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); void bnx2x_netif_start(struct bnx2x *bp); void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only); +void bnx2x_free_irq(struct bnx2x *bp); int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); int bnx2x_resume(struct pci_dev *pdev); void bnx2x_free_skbs(struct bnx2x *bp); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 0ac416a14202..2572eb40c0ed 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -90,7 +90,7 @@ module_param(multi_mode, int, 0); MODULE_PARM_DESC(multi_mode, " Multi queue mode " "(0 Disable; 1 Enable (default))"); -static int num_queues; +int num_queues; module_param(num_queues, int, 0); MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1" " (default is as a number of CPUs)"); @@ -6409,28 +6409,57 @@ int bnx2x_setup_fw_client(struct bnx2x *bp, return rc; } -void bnx2x_set_num_queues_msix(struct bnx2x *bp) +/** + * Configure interrupt mode according to current configuration. + * In case of MSI-X it will also try to enable MSI-X. + * + * @param bp + * + * @return int + */ +static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) { + int rc = 0; - switch (bp->multi_mode) { - case ETH_RSS_MODE_DISABLED: + switch (bp->int_mode) { + case INT_MODE_MSI: + bnx2x_enable_msi(bp); + /* falling through... */ + case INT_MODE_INTx: bp->num_queues = 1; + DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; + default: + /* Set number of queues according to bp->multi_mode value */ + bnx2x_set_num_queues(bp); - case ETH_RSS_MODE_REGULAR: - if (num_queues) - bp->num_queues = min_t(u32, num_queues, - BNX2X_MAX_QUEUES(bp)); - else - bp->num_queues = min_t(u32, num_online_cpus(), - BNX2X_MAX_QUEUES(bp)); - break; + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", + bp->num_queues); + /* if we can't use MSI-X we only need one fp, + * so try to enable MSI-X with the requested number of fp's + * and fallback to MSI or legacy INTx with one fp + */ + rc = bnx2x_enable_msix(bp); + if (rc) { + /* failed to enable MSI-X */ + if (bp->multi_mode) + DP(NETIF_MSG_IFUP, + "Multi requested but failed to " + "enable MSI-X (%d), " + "set number of queues to %d\n", + bp->num_queues, + 1); + bp->num_queues = 1; + + if (!(bp->flags & DISABLE_MSI_FLAG)) + bnx2x_enable_msi(bp); + } - default: - bp->num_queues = 1; break; } + + return rc; } void bnx2x_ilt_set_info(struct bnx2x *bp) @@ -6881,7 +6910,7 @@ unload_error: bnx2x_netif_stop(bp, 1); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); /* Reset the chip */ bnx2x_reset_chip(bp, reset_code); @@ -9024,7 +9053,16 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } + /* Configure interupt mode: try to enable MSI-X/MSI if + * needed, set bp->num_queues appropriately. + */ + bnx2x_set_int_mode(bp); + + /* Add all NAPI objects */ + bnx2x_add_all_napi(bp); + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); + netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), @@ -9068,6 +9106,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + /* Delete all NAPI objects */ + bnx2x_del_all_napi(bp); + + /* Disable MSI/MSI-X */ + bnx2x_disable_msi(bp); /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); @@ -9104,15 +9147,14 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; -- cgit v1.2.3 From c2bff63fad94eeecf59e4ba8e4cb51688ccae1ec Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:33:18 +0000 Subject: bnx2x, cnic: Fix SPQ return credit Return proper L2 and L5 SPQ (slow path queue) credits. Previously, all SPQ events were counted as L5 types. Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 13 ------- drivers/net/bnx2x/bnx2x_main.c | 86 +++++++++++++++++++++++++++++++++--------- drivers/net/cnic.c | 18 +++++---- drivers/net/cnic_if.h | 21 ++++++----- 4 files changed, 91 insertions(+), 47 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 2998969beacc..68181cdd2096 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1369,19 +1369,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_set_eth_mac(bp, 1); -#ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb_mapping, - BNX2X_VF_ID_INVALID, false, - CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); -#endif - if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2572eb40c0ed..a686a4c15710 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6462,6 +6462,12 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) return rc; } +/* must be called prioir to any HW initializations */ +static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp) +{ + return L2_ILT_LINES(bp); +} + void bnx2x_ilt_set_info(struct bnx2x *bp) { struct ilt_client_info *ilt_client; @@ -9347,19 +9353,53 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) #endif spin_lock_bh(&bp->spq_lock); + BUG_ON(bp->cnic_spq_pending < count); bp->cnic_spq_pending -= count; - for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending; - bp->cnic_spq_pending++) { - if (!bp->cnic_kwq_pending) + for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) { + u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type) + & SPE_HDR_CONN_TYPE) >> + SPE_HDR_CONN_TYPE_SHIFT; + + /* Set validation for iSCSI L2 client before sending SETUP + * ramrod + */ + if (type == ETH_CONNECTION_TYPE) { + u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons-> + hdr.conn_and_cmd_data) >> + SPE_HDR_CMD_ID_SHIFT) & 0xff; + + if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) + bnx2x_set_ctx_validation(&bp->context. + vcxt[BNX2X_ISCSI_ETH_CID].eth, + HW_CID(bp, BNX2X_ISCSI_ETH_CID)); + } + + /* There may be not more than 8 L2 and COMMON SPEs and not more + * than 8 L5 SPEs in the air. + */ + if ((type == NONE_CONNECTION_TYPE) || + (type == ETH_CONNECTION_TYPE)) { + if (!atomic_read(&bp->spq_left)) + break; + else + atomic_dec(&bp->spq_left); + } else if (type == ISCSI_CONNECTION_TYPE) { + if (bp->cnic_spq_pending >= + bp->cnic_eth_dev.max_kwqe_pending) + break; + else + bp->cnic_spq_pending++; + } else { + BNX2X_ERR("Unknown SPE type: %d\n", type); + bnx2x_panic(); break; + } spe = bnx2x_sp_get_next(bp); *spe = *bp->cnic_kwq_cons; - bp->cnic_kwq_pending--; - DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n", bp->cnic_spq_pending, bp->cnic_kwq_pending, count); @@ -9464,7 +9504,7 @@ static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid) ctl.data.comp.cid = cid; bnx2x_cnic_ctl_send_bh(bp, &ctl); - bnx2x_cnic_sp_post(bp, 1); + bnx2x_cnic_sp_post(bp, 0); } static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) @@ -9481,8 +9521,8 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } - case DRV_CTL_COMPLETION_CMD: { - int count = ctl->data.comp.comp_count; + case DRV_CTL_RET_L5_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; bnx2x_cnic_sp_post(bp, count); break; @@ -9528,6 +9568,14 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) bnx2x_set_iscsi_eth_mac_addr(bp, 0); break; } + case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; + + smp_mb__before_atomic_inc(); + atomic_add(count, &bp->spq_left); + smp_mb__after_atomic_inc(); + break; + } default: BNX2X_ERR("unknown command %x\n", ctl->cmd); @@ -9592,13 +9640,8 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, cp->drv_state = CNIC_DRV_STATE_REGD; cp->iro_arr = bp->iro_arr; - bnx2x_init_sb(bp, bp->cnic_sb_mapping, - BNX2X_VF_ID_INVALID, false, - CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); - bnx2x_setup_cnic_irq_info(bp); - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + rcu_assign_pointer(bp->cnic_ops, ops); return 0; @@ -9636,14 +9679,23 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->io_base2 = bp->doorbells; cp->max_kwqe_pending = 8; cp->ctx_blk_size = CDU_ILT_PAGE_SZ; - cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; + cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + + bnx2x_cid_ilt_lines(bp); cp->ctx_tbl_len = CNIC_ILT_LINES; - cp->starting_cid = BCM_CNIC_CID_START; + cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS; cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue; cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - + cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID; + cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; + + DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " + "starting cid %d\n", + cp->ctx_blk_size, + cp->ctx_tbl_offset, + cp->ctx_tbl_len, + cp->starting_cid); return cp; } EXPORT_SYMBOL(bnx2x_cnic_probe); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 80259815af06..27449bf775e3 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -242,14 +242,14 @@ static int cnic_in_use(struct cnic_sock *csk) return test_bit(SK_F_INUSE, &csk->flags); } -static void cnic_kwq_completion(struct cnic_dev *dev, u32 count) +static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; struct drv_ctl_info info; - info.cmd = DRV_CTL_COMPLETION_CMD; - info.data.comp.comp_count = count; + info.cmd = cmd; + info.data.credit.credit_count = count; ethdev->drv_ctl(dev->netdev, &info); } @@ -2069,7 +2069,7 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], static void service_kcqes(struct cnic_dev *dev, int num_cqes) { struct cnic_local *cp = dev->cnic_priv; - int i, j; + int i, j, comp = 0; i = 0; j = 1; @@ -2080,7 +2080,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK; if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; while (j < num_cqes) { u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag; @@ -2089,7 +2089,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) break; if (unlikely(next_op & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; j++; } @@ -2119,6 +2119,8 @@ end: i += j; j = 1; } + if (unlikely(comp)) + cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp); } static u16 cnic_bnx2_next_idx(u16 idx) @@ -4246,7 +4248,7 @@ static void cnic_init_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_SETUP did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); } } @@ -4283,7 +4285,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_HALT did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); memset(&l5_data, 0, sizeof(l5_data)); type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 4018de12f819..98ebac52013e 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.1.3" -#define CNIC_MODULE_RELDATE "June 24, 2010" +#define CNIC_MODULE_VERSION "2.2.5" +#define CNIC_MODULE_RELDATE "September 29, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -80,18 +80,15 @@ struct kcqe { #define DRV_CTL_IO_RD_CMD 0x102 #define DRV_CTL_CTX_WR_CMD 0x103 #define DRV_CTL_CTXTBL_WR_CMD 0x104 -#define DRV_CTL_COMPLETION_CMD 0x105 +#define DRV_CTL_RET_L5_SPQ_CREDIT_CMD 0x105 #define DRV_CTL_START_L2_CMD 0x106 #define DRV_CTL_STOP_L2_CMD 0x107 +#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c struct cnic_ctl_completion { u32 cid; }; -struct drv_ctl_completion { - u32 comp_count; -}; - struct cnic_ctl_info { int cmd; union { @@ -100,6 +97,10 @@ struct cnic_ctl_info { } data; }; +struct drv_ctl_spq_credit { + u32 credit_count; +}; + struct drv_ctl_io { u32 cid_addr; u32 offset; @@ -115,7 +116,7 @@ struct drv_ctl_l2_ring { struct drv_ctl_info { int cmd; union { - struct drv_ctl_completion comp; + struct drv_ctl_spq_credit credit; struct drv_ctl_io io; struct drv_ctl_l2_ring ring; char bytes[MAX_DRV_CTL_DATA]; @@ -162,7 +163,9 @@ struct cnic_eth_dev { u32 max_iscsi_conn; u32 max_fcoe_conn; u32 max_rdma_conn; - u32 reserved0[2]; + u32 fcoe_init_cid; + u16 iscsi_l2_client_id; + u16 iscsi_l2_cid; int num_irq; struct cnic_irq irq_arr[MAX_CNIC_VEC]; -- cgit v1.2.3 From f85582f8c48addd8166727ef692d88b0ff618c5e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:34:21 +0000 Subject: bnx2x: code beautify This patch does not include any functional changes. The changes are: empty lines, indentation and comments. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 54 ++++---- drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++---- drivers/net/bnx2x/bnx2x_cmn.h | 145 ++++++++++++++------ drivers/net/bnx2x/bnx2x_ethtool.c | 5 +- drivers/net/bnx2x/bnx2x_main.c | 275 +++++++++++++++++++------------------- drivers/net/bnx2x/bnx2x_stats.c | 4 +- drivers/net/bnx2x/bnx2x_stats.h | 8 +- 7 files changed, 318 insertions(+), 233 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index d80809f5ffc9..6fc77a4a5de6 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -180,13 +180,14 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) #define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ offsetof(struct mf_cfg, field)) -#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ +#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ offsetof(struct mf2_cfg, field)) #define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) #define MF_CFG_WR(bp, field, val) REG_WR(bp,\ MF_CFG_ADDR(bp, field), (val)) #define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field)) + #define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \ (SHMEM2_RD((bp), size) > \ offsetof(struct shmem2_region, field))) @@ -310,7 +311,7 @@ struct bnx2x_fastpath { #define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; - union host_hc_status_block status_blk; + union host_hc_status_block status_blk; /* chip independed shortcuts into sb structure */ __le16 *sb_index_values; __le16 *sb_running_index; @@ -349,8 +350,8 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_TERMINATING 0xd0000 #define BNX2X_FP_STATE_TERMINATED 0xe0000 - u8 index; /* number in fp array */ - u8 cl_id; /* eth client id */ + u8 index; /* number in fp array */ + u8 cl_id; /* eth client id */ u8 cl_qzone_id; u8 fw_sb_id; /* status block number in FW */ u8 igu_sb_id; /* status block number in HW */ @@ -375,8 +376,6 @@ struct bnx2x_fastpath { u16 last_max_sge; __le16 *rx_cons_sb; - - unsigned long tx_pkt, rx_pkt, rx_calls; @@ -977,7 +976,7 @@ struct bnx2x { u32 mf2_config[E2_FUNC_MAX]; u16 mf_ov; u8 mf_mode; -#define IS_MF(bp) (bp->mf_mode != 0) +#define IS_MF(bp) (bp->mf_mode != 0) u8 wol; @@ -1302,21 +1301,35 @@ struct bnx2x_func_init_params { for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); + +/* dmae */ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, u32 len32); +void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, + u32 addr, u32 len); +void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type); + int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); -void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, - u32 addr, u32 len); + void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_link_cfg_idx(struct bnx2x *bp); + static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) { @@ -1333,6 +1346,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } + #define BNX2X_ILT_ZALLOC(x, y, size) \ do { \ x = pci_alloc_consistent(bp->pdev, size, y); \ @@ -1353,6 +1367,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define ILT_NUM_PAGE_ENTRIES (3072) /* In 57710/11 we use whole table since we have 8 func + * In 57712 we have only 4 func, but use same size per func, then only half of + * the table in use */ #define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) @@ -1366,14 +1382,13 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) #define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) - /* load/unload mode */ #define LOAD_NORMAL 0 #define LOAD_OPEN 1 #define LOAD_DIAG 2 #define UNLOAD_NORMAL 0 #define UNLOAD_CLOSE 1 -#define UNLOAD_RECOVERY 2 +#define UNLOAD_RECOVERY 2 /* DMAE command defines */ @@ -1447,7 +1462,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ E1HVN_MAX) - /* PCIE link and speed */ #define PCICFG_LINK_WIDTH 0x1f00000 #define PCICFG_LINK_WIDTH_SHIFT 20 @@ -1596,6 +1610,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_SP_DSB_INDEX \ (&bp->def_status_blk->sp_sb.\ index_values[HC_SP_INDEX_ETH_DEF_CONS]) + #define SET_FLAG(value, mask, flag) \ do {\ (value) &= ~(mask);\ @@ -1630,6 +1645,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #ifndef ETH_MAX_RX_CLIENTS_E2 #define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H #endif + #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 @@ -1649,20 +1665,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ -/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ - extern void bnx2x_set_ethtool_ops(struct net_device *netdev); -void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); -u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); -u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); -u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, - bool with_comp, u8 comp_type); - - -#define WAIT_RAMROD_POLL 0x01 -#define WAIT_RAMROD_COMMON 0x02 - -int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 68181cdd2096..97ef674dcc34 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -15,7 +15,6 @@ * */ - #include #include #include @@ -136,7 +135,6 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) */ smp_mb(); - /* TBD need a thresh? */ if (unlikely(netif_tx_queue_stopped(txq))) { /* Taking tx_lock() is needed to prevent reenabling the queue * while it's empty. This could have happen if rx_action() gets @@ -623,6 +621,7 @@ reuse_rx: bnx2x_set_skb_rxhash(bp, cqe, skb); skb_checksum_none_assert(skb); + if (bp->rx_csum) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -704,7 +703,6 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp) { @@ -916,6 +914,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) } } } + static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; @@ -1185,6 +1184,7 @@ void bnx2x_set_num_queues(struct bnx2x *bp) case ETH_RSS_MODE_REGULAR: bp->num_queues = bnx2x_calc_num_queues(bp); break; + default: bp->num_queues = 1; break; @@ -1354,6 +1354,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Enable Timer scan */ REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); #endif + for_each_nondefault_queue(bp, i) { rc = bnx2x_setup_client(bp, &bp->fp[i], 0); if (rc) @@ -1473,11 +1474,13 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Stop Tx */ bnx2x_tx_disable(bp); + del_timer_sync(&bp->timer); + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); - bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_stats_handle(bp, STATS_EVENT_STOP); /* Cleanup the chip if needed */ if (unload_mode != UNLOAD_RECOVERY) @@ -1514,6 +1517,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return 0; } + int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) { u16 pmcsr; @@ -1560,12 +1564,9 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) return 0; } - - /* * net_device service functions */ - int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; @@ -1595,19 +1596,19 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, - * thus we need to ensure that status block indices - * have been actually read (bnx2x_update_fpsb_idx) - * prior to this check (bnx2x_has_rx_work) so that - * we won't write the "newer" value of the status block - * to IGU (if there was a DMA right after - * bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed - * to right before bnx2x_ack_sb). In this case there - * will never be another interrupt until there is - * another update of the status block, while there - * is still unhandled work. - */ + /* bnx2x_has_rx_work() reads the status block, + * thus we need to ensure that status block indices + * have been actually read (bnx2x_update_fpsb_idx) + * prior to this check (bnx2x_has_rx_work) so that + * we won't write the "newer" value of the status block + * to IGU (if there was a DMA right after + * bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed + * to right before bnx2x_ack_sb). In this case there + * will never be another interrupt until there is + * another update of the status block, while there + * is still unhandled work. + */ rmb(); if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { @@ -1626,7 +1627,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) return work_done; } - /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs @@ -1842,6 +1842,7 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; } + /** * * @param skb @@ -1914,6 +1915,7 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, return hlen; } + /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -2003,13 +2005,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - SET_FLAG(tx_start_bd->general_data, - ETH_TX_START_BD_ETH_ADDR_TYPE, - mac_type); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE, + mac_type); + /* header nbd */ - SET_FLAG(tx_start_bd->general_data, - ETH_TX_START_BD_HDR_NBDS, - 1); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1); /* remember the first BD of the packet */ tx_buf->first_bd = fp->tx_bd_prod; @@ -2065,9 +2065,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } + /* Map skb linear data for DMA */ mapping = dma_map_single(&bp->pdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); + /* Setup the data pointer of the first BD of the packet */ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ @@ -2101,6 +2103,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; + /* Handle fragmented skb */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -2165,6 +2168,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) fp->tx_db.data.prod += nbd; barrier(); + DOORBELL(bp, fp->cid, fp->tx_db.raw); mmiowb(); @@ -2187,6 +2191,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } + /* called with rtnl_lock */ int bnx2x_change_mac_addr(struct net_device *dev, void *p) { @@ -2319,6 +2324,7 @@ void bnx2x_vlan_rx_register(struct net_device *dev, } #endif + int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 1d9686ea6b66..7f52cec9bb99 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -63,6 +63,15 @@ u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); */ void bnx2x__link_status_update(struct bnx2x *bp); +/** + * Report link status to upper layer + * + * @param bp + * + * @return int + */ +void bnx2x_link_report(struct bnx2x *bp); + /** * MSI-X slowpath interrupt handler * @@ -234,7 +243,7 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); /** * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57711 + * netdev->dev_addr. * * @param bp driver handle * @param set @@ -270,10 +279,11 @@ void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, u8 vf_valid, int fw_sb_id, int igu_sb_id); /** - * Reconfigure FW/HW according to dev->flags rx mode + * Set MAC filtering configurations. * - * @param dev net_device + * @remarks called with netif_tx_lock from dev_mcast.c * + * @param dev net_device */ void bnx2x_set_rx_mode(struct net_device *dev); @@ -295,17 +305,17 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp); * Perform statistics handling according to event * * @param bp driver handle - * @param even tbnx2x_stats_event + * @param event bnx2x_stats_event */ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); /** - * Handle sp events + * Handle ramrods completion * * @param fp fastpath handle for the event * @param rr_cqe eth_rx_cqe */ -void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); +void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); /** * Init/halt function before/after sending @@ -326,6 +336,46 @@ int bnx2x_func_stop(struct bnx2x *bp); */ void bnx2x_ilt_set_info(struct bnx2x *bp); +/** + * Set power state to the requested value. Currently only D0 and + * D3hot are supported. + * + * @param bp + * @param state D0 or D3hot + * + * @return int + */ +int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); + +/* dev_close main block */ +int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); + +/* dev_open main block */ +int bnx2x_nic_load(struct bnx2x *bp, int load_mode); + +/* hard_xmit callback */ +netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); + +int bnx2x_change_mac_addr(struct net_device *dev, void *p); + +/* NAPI poll Rx part */ +int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); + +/* NAPI poll Tx part */ +int bnx2x_tx_int(struct bnx2x_fastpath *fp); + +/* suspend/resume callbacks */ +int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); +int bnx2x_resume(struct pci_dev *pdev); + +/* Release IRQ vectors */ +void bnx2x_free_irq(struct bnx2x *bp); + +void bnx2x_init_rx_rings(struct bnx2x *bp); +void bnx2x_free_skbs(struct bnx2x *bp); +void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); +void bnx2x_netif_start(struct bnx2x *bp); + /** * Fill msix_table, request vectors, update num_queues according * to number of available vectors @@ -362,6 +412,51 @@ int bnx2x_setup_irqs(struct bnx2x *bp); * @return int */ int bnx2x_poll(struct napi_struct *napi, int budget); + +/** + * Allocate/release memories outsize main driver structure + * + * @param bp + * + * @return int + */ +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); +void bnx2x_free_mem_bp(struct bnx2x *bp); + +/** + * Change mtu netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +int bnx2x_change_mtu(struct net_device *dev, int new_mtu); + +/** + * tx timeout netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_tx_timeout(struct net_device *dev); + +#ifdef BCM_VLAN +/** + * vlan rx register netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_vlan_rx_register(struct net_device *dev, + struct vlan_group *vlgrp); + +#endif + static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { barrier(); /* status block is written to by the chip */ @@ -558,9 +653,6 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) return bnx2x_igu_ack_int(bp); } -/* - * fast path service functions - */ static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ @@ -611,6 +703,7 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) rx_cons_sb++; return (fp->rx_comp_cons != rx_cons_sb); } + /** * disables tx from stack point of view * @@ -731,6 +824,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, return 0; } + static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -782,6 +876,7 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, dma_unmap_addr(cons_rx_buf, mapping)); *prod_bd = *cons_bd; } + static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -846,6 +941,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp) fp->tx_pkt = 0; } } + static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) { int i; @@ -931,40 +1027,11 @@ static inline void storm_memset_cmng(struct bnx2x *bp, __storm_memset_struct(bp, addr, size, (u32 *)cmng); } + /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -void bnx2x_link_report(struct bnx2x *bp); -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); -int bnx2x_tx_int(struct bnx2x_fastpath *fp); -void bnx2x_init_rx_rings(struct bnx2x *bp); -netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); - -int bnx2x_change_mac_addr(struct net_device *dev, void *p); -void bnx2x_tx_timeout(struct net_device *dev); -void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); -void bnx2x_netif_start(struct bnx2x *bp); -void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp); -int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); -int bnx2x_resume(struct pci_dev *pdev); -void bnx2x_free_skbs(struct bnx2x *bp); -int bnx2x_change_mtu(struct net_device *dev, int new_mtu); -int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); -int bnx2x_nic_load(struct bnx2x *bp, int load_mode); -int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); - -/** - * Allocate/release memories outsize main driver structure - * - * @param bp - * - * @return int - */ -int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); -void bnx2x_free_mem_bp(struct bnx2x *bp); - #define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 8fb00276dc41..54fe0615a8b9 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,7 +25,6 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" - static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); @@ -963,6 +962,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, return rc; } + static int bnx2x_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) { @@ -1288,6 +1288,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) save_val = REG_RD(bp, offset); REG_WR(bp, offset, (wr_val & mask)); + val = REG_RD(bp, offset); /* Restore the original register's value */ @@ -1471,6 +1472,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; @@ -1714,6 +1716,7 @@ static void bnx2x_self_test(struct net_device *dev, buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } + buf[2] = bnx2x_test_loopback(bp, link_up); if (buf[2] != 0) etest->flags |= ETH_TEST_FL_FAILED; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index a686a4c15710..7a9556b5b55d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -56,7 +56,6 @@ #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" - #include #include "bnx2x_fw_file_hdr.h" /* FW files */ @@ -1325,7 +1324,6 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) return false; } - #ifdef BCM_CNIC static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); #endif @@ -1754,12 +1752,12 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp) MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: @@ -1768,12 +1766,11 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp) default: bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + ADVERTISED_Pause); break; } } - u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { if (!BP_NOMCP(bp)) { @@ -1952,6 +1949,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * 100; } + DP(NETIF_MSG_IFUP, "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n", func, vn_min_rate, vn_max_rate, bp->vn_weight_sum); @@ -1991,6 +1989,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, ((u32 *)(&m_fair_vn))[i]); } + static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) { if (CHIP_REV_IS_SLOW(bp)) @@ -2625,13 +2624,13 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) wmb(); REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); + bp->spq_prod_idx); mmiowb(); } /* the slow path queue is odd since completions arrive on the fastpath ring */ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common) + u32 data_hi, u32 data_lo, int common) { struct eth_spe *spe; u16 type; @@ -3055,6 +3054,7 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) #define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) #define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS #define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) + /* * should be run under rtnl lock */ @@ -4376,7 +4376,6 @@ gunzip_nomem1: static void bnx2x_gunzip_end(struct bnx2x *bp) { kfree(bp->strm->workspace); - kfree(bp->strm); bp->strm = NULL; @@ -4641,6 +4640,7 @@ static void enable_blocks_attention(struct bnx2x *bp) REG_WR(bp, CCM_REG_CCM_INT_MASK, 0); /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */ /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ + if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); else if (CHIP_IS_E2(bp)) @@ -4672,29 +4672,29 @@ static const struct { {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, {HC_REG_HC_PRTY_MASK, 0x7}, {MISC_REG_MISC_PRTY_MASK, 0x1}, - {QM_REG_QM_PRTY_MASK, 0x0}, - {DORQ_REG_DORQ_PRTY_MASK, 0x0}, + {QM_REG_QM_PRTY_MASK, 0x0}, + {DORQ_REG_DORQ_PRTY_MASK, 0x0}, {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, - {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ - {CDU_REG_CDU_PRTY_MASK, 0x0}, - {CFC_REG_CFC_PRTY_MASK, 0x0}, - {DBG_REG_DBG_PRTY_MASK, 0x0}, - {DMAE_REG_DMAE_PRTY_MASK, 0x0}, - {BRB1_REG_BRB1_PRTY_MASK, 0x0}, - {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ - {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */ - {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */ - {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, - {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, - {USEM_REG_USEM_PRTY_MASK_0, 0x0}, - {USEM_REG_USEM_PRTY_MASK_1, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} + {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ + {CDU_REG_CDU_PRTY_MASK, 0x0}, + {CFC_REG_CFC_PRTY_MASK, 0x0}, + {DBG_REG_DBG_PRTY_MASK, 0x0}, + {DMAE_REG_DMAE_PRTY_MASK, 0x0}, + {BRB1_REG_BRB1_PRTY_MASK, 0x0}, + {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ + {TSDM_REG_TSDM_PRTY_MASK, 0x18}, /* bit 3,4 */ + {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {USDM_REG_USDM_PRTY_MASK, 0x38}, /* bit 3,4,5 */ + {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, + {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, + {USEM_REG_USEM_PRTY_MASK_0, 0x0}, + {USEM_REG_USEM_PRTY_MASK_1, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} }; static void enable_blocks_parity(struct bnx2x *bp) @@ -4906,7 +4906,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_ilt_init_page_size(bp, INITOP_SET); - if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); @@ -5003,6 +5002,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) if (CHIP_MODE_IS_4_PORT(bp)) bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); + /* QM queues pointers table */ bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); @@ -5036,6 +5036,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) #endif if (!CHIP_IS_E1(bp)) REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ @@ -5081,6 +5082,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) REG_WR(bp, i, random32()); + bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); #ifdef BCM_CNIC REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); @@ -5467,6 +5469,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) set the size */ } bnx2x_ilt_init_op(bp, INITOP_SET); + #ifdef BCM_CNIC bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); @@ -5692,6 +5695,7 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); bnx2x_phy_probe(&bp->link_params); + return 0; } @@ -5826,6 +5830,7 @@ void bnx2x_free_mem(struct bnx2x *bp) bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); BNX2X_FREE(bp->ilt->lines); + #ifdef BCM_CNIC if (CHIP_IS_E2(bp)) BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, @@ -5833,8 +5838,10 @@ void bnx2x_free_mem(struct bnx2x *bp) else BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, sizeof(struct host_hc_status_block_e1x)); + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif + BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, @@ -5862,7 +5869,6 @@ static inline void set_sb_shortcuts(struct bnx2x *bp, int index) int bnx2x_alloc_mem(struct bnx2x *bp) { - #define BNX2X_PCI_ALLOC(x, y, size) \ do { \ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ @@ -5951,6 +5957,7 @@ int bnx2x_alloc_mem(struct bnx2x *bp) sizeof(struct bnx2x_slowpath)); bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; + BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, bp->context.size); @@ -5997,7 +6004,7 @@ int bnx2x_func_stop(struct bnx2x *bp) } /** - * Sets a MAC in a CAM for a few L2 Clients for E1x chip + * Sets a MAC in a CAM for a few L2 Clients for E1x chips * * @param bp driver descriptor * @param set set or clear an entry (1 or 0) @@ -6007,8 +6014,8 @@ int bnx2x_func_stop(struct bnx2x *bp) * @param is_bcast is the set MAC a broadcast address (for E1 only) */ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 is_bcast) + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) { struct mac_configuration_cmd *config = (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); @@ -6060,9 +6067,8 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); } - int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags) + int *state_p, int flags) { /* can take a while if any port is running */ int cnt = 5000; @@ -6220,7 +6226,6 @@ static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) } - #ifdef BCM_CNIC /** * Set iSCSI MAC(s) at the next enties in the CAM after the ETH @@ -6564,6 +6569,7 @@ void bnx2x_ilt_set_info(struct bnx2x *bp) ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); #endif } + int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, int is_leading) { @@ -6949,7 +6955,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp) } } - /* Close gates #2, #3 and #4: */ static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) { @@ -6995,15 +7000,13 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val) static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val) { /* Restore the `magic' bit value... */ - /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb); - SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb, - (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */ u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); MF_CFG_WR(bp, shared_mf_config.clp_mb, (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); } -/* Prepares for MCP reset: takes care of CLP configurations. +/** + * Prepares for MCP reset: takes care of CLP configurations. * * @param bp * @param magic_val Old value of 'magic' bit. @@ -7532,7 +7535,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - } else bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } @@ -7651,7 +7653,8 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) } bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + bp->link_params.feature_config_flags |= (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; @@ -7768,7 +7771,7 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, SHMEM_RD(bp, dev_info.port_hw_config[port].external_phy_config2)); return; - } + } switch (switch_cfg) { case SWITCH_CFG_1G: @@ -7781,7 +7784,6 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + port*0x18); BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; default: @@ -7810,7 +7812,7 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); + SUPPORTED_1000baseT_Full); if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) @@ -7844,41 +7846,41 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->link_params.req_duplex[idx] = DUPLEX_FULL; link_config = bp->port.link_config[idx]; switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { - case PORT_FEATURE_LINK_SPEED_AUTO: + case PORT_FEATURE_LINK_SPEED_AUTO: if (bp->port.supported[idx] & SUPPORTED_Autoneg) { bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; bp->port.advertising[idx] |= bp->port.supported[idx]; - } else { - /* force 10G, no AN */ + } else { + /* force 10G, no AN */ bp->link_params.req_line_speed[idx] = SPEED_10000; bp->port.advertising[idx] |= (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); + ADVERTISED_FIBRE); continue; - } - break; + } + break; - case PORT_FEATURE_LINK_SPEED_10M_FULL: + case PORT_FEATURE_LINK_SPEED_10M_FULL: if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_10; bp->port.advertising[idx] |= (ADVERTISED_10baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_10M_HALF: + case PORT_FEATURE_LINK_SPEED_10M_HALF: if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) { bp->link_params.req_line_speed[idx] = SPEED_10; @@ -7886,70 +7888,74 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) DUPLEX_HALF; bp->port.advertising[idx] |= (ADVERTISED_10baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) { + case PORT_FEATURE_LINK_SPEED_100M_FULL: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_100; bp->port.advertising[idx] |= (ADVERTISED_100baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed[idx] = SPEED_100; - bp->link_params.req_duplex[idx] = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_100M_HALF: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; bp->port.advertising[idx] |= (ADVERTISED_100baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_1G: + case PORT_FEATURE_LINK_SPEED_1G: if (bp->port.supported[idx] & SUPPORTED_1000baseT_Full) { bp->link_params.req_line_speed[idx] = SPEED_1000; bp->port.advertising[idx] |= (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, bp->link_params.speed_cap_mask[idx]); - return; - } - break; + return; + } + break; - case PORT_FEATURE_LINK_SPEED_2_5G: + case PORT_FEATURE_LINK_SPEED_2_5G: if (bp->port.supported[idx] & SUPPORTED_2500baseX_Full) { bp->link_params.req_line_speed[idx] = @@ -7957,19 +7963,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_2500baseX_Full | ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_10G_CX4: - case PORT_FEATURE_LINK_SPEED_10G_KX4: - case PORT_FEATURE_LINK_SPEED_10G_KR: + case PORT_FEATURE_LINK_SPEED_10G_CX4: + case PORT_FEATURE_LINK_SPEED_10G_KX4: + case PORT_FEATURE_LINK_SPEED_10G_KR: if (bp->port.supported[idx] & SUPPORTED_10000baseT_Full) { bp->link_params.req_line_speed[idx] = @@ -7977,24 +7983,26 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); - } else { - BNX2X_ERROR("NVRAM config error. " + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", link_config, - bp->link_params.speed_cap_mask[idx]); - return; - } - break; + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - default: - BNX2X_ERROR("NVRAM config error. " - "BAD link speed link_config 0x%x\n", - link_config); - bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG; - bp->port.advertising[idx] = bp->port.supported[idx]; - break; - } + default: + BNX2X_ERROR("NVRAM config error. " + "BAD link speed link_config 0x%x\n", + link_config); + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] = + bp->port.supported[idx]; + break; + } bp->link_params.req_flow_ctrl[idx] = (link_config & PORT_FEATURE_FLOW_CONTROL_MASK); @@ -8056,14 +8064,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->wol = (!(bp->flags & NO_WOL_FLAG) && (config & PORT_FEATURE_WOL_ENABLED)); - BNX2X_DEV_INFO("lane_config 0x%08x" + BNX2X_DEV_INFO("lane_config 0x%08x " "speed_cap_mask0 0x%08x link_config0 0x%08x\n", bp->link_params.lane_config, bp->link_params.speed_cap_mask[0], bp->port.link_config[0]); bp->link_params.switch_cfg = (bp->port.link_config[0] & - PORT_FEATURE_CONNECTED_SWITCH_MASK); + PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); @@ -8458,12 +8466,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) if (dev->flags & IFF_PROMISC) rx_mode = BNX2X_RX_MODE_PROMISC; - else if ((dev->flags & IFF_ALLMULTI) || ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp))) rx_mode = BNX2X_RX_MODE_ALLMULTI; - else { /* some multicasts */ if (CHIP_IS_E1(bp)) { /* @@ -8503,12 +8509,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) } } - bp->rx_mode = rx_mode; bnx2x_set_storm_rx_mode(bp); } - /* called with rtnl_lock */ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) @@ -8999,6 +9003,7 @@ static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) #endif return roundup(cid_count, QM_CID_ROUND); } + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -9026,6 +9031,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, } cid_count += CNIC_CONTEXT_USE; + /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { @@ -9117,6 +9123,7 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) /* Disable MSI/MSI-X */ bnx2x_disable_msi(bp); + /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index ad7aa55efb63..5644bddb3d19 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -14,8 +14,8 @@ * Statistics and Link management by Yitchak Gertner * */ - #include "bnx2x_cmn.h" - #include "bnx2x_stats.h" +#include "bnx2x_cmn.h" +#include "bnx2x_stats.h" /* Statistics */ diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index 38a4e908f4fb..afd15efa429a 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -9,6 +9,10 @@ * Maintained by: Eilon Greenstein * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver + * UDP CSUM errata workaround by Arik Gendelman + * Slowpath and fastpath rework by Vladislav Zolotarov + * Statistics and Link management by Yitchak Gertner + * */ #ifndef BNX2X_STATS_H @@ -228,12 +232,8 @@ struct bnx2x_eth_stats { /* Forward declaration */ struct bnx2x; - void bnx2x_stats_init(struct bnx2x *bp); extern const u32 dmae_reg_go_c[]; -extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); - #endif /* BNX2X_STATS_H */ -- cgit v1.2.3 From 6fe8bce7b3b69835e8049106947db6b0f1f3a8d8 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:35:03 +0000 Subject: bnx2x: properly initialize FW stats Client statistics need to be initialized to -1 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_stats.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 5644bddb3d19..4733c835dad9 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -1339,6 +1339,7 @@ void bnx2x_stats_init(struct bnx2x *bp) int port = BP_PORT(bp); int mb_idx = BP_FW_MB_IDX(bp); int i; + struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); bp->stats_pending = 0; bp->executer_idx = 0; @@ -1380,6 +1381,18 @@ void bnx2x_stats_init(struct bnx2x *bp) memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); } + for_each_queue(bp, i) { + /* Set initial stats counter in the stats ramrod data to -1 */ + int cl_id = bp->fp[i].cl_id; + + stats->xstorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + stats->ustorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + stats->tstorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + } + memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); -- cgit v1.2.3 From 4f5157307652f1cbff2413b5e81ebcadd8e2524b Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 6 Oct 2010 03:35:11 +0000 Subject: bnx2x: update version to 1.60.00-1 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 6fc77a4a5de6..c49b643e009b 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-7" -#define DRV_MODULE_RELDATE "2010/09/12" +#define DRV_MODULE_VERSION "1.60.00-1" +#define DRV_MODULE_RELDATE "2010/10/06" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- cgit v1.2.3 From 700c2a779e6d5a60e2ef4716e75ea7f41546602f Mon Sep 17 00:00:00 2001 From: Krzysztof Piotr Oledzki Date: Wed, 6 Oct 2010 14:25:06 -0700 Subject: bonding: print information about speed and duplex seen by the driver before: bonding: bond0: link status definitely up for interface eth5 bonding: bond0: link status definitely up for interface eth0 after: bonding: bond0: link status definitely up for interface eth5, 100 Mbps full duplex. bonding: bond0: link status definitely up for interface eth0, 100 Mbps full duplex. Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6f5e6b453da6..e498ce3defad 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2406,8 +2406,9 @@ static void bond_miimon_commit(struct bonding *bond) slave->state = BOND_STATE_BACKUP; } - pr_info("%s: link status definitely up for interface %s.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n", + bond->dev->name, slave->dev->name, + slave->speed, slave->duplex ? "full" : "half"); /* notify ad that the link status has changed */ if (bond->params.mode == BOND_MODE_8023AD) -- cgit v1.2.3 From 546add79468183f266c75c632c96e4b0029e0d96 Mon Sep 17 00:00:00 2001 From: Krzysztof Piotr Oledzki Date: Wed, 6 Oct 2010 14:28:22 -0700 Subject: bonding: reread information about speed and duplex when interface goes up When an interface was enslaved when it was down, bonding thinks it has speed -1 even after it goes up. This leads into selecting a wrong active interface in active/backup mode on mixed 10G/1G or 1G/100M environment. before: bonding: bond0: link status definitely up for interface eth5, 100 Mbps full duplex. bonding: bond0: link status definitely up for interface eth0, 100 Mbps full duplex. after: bonding: bond0: link status definitely up for interface eth5, 10000 Mbps full duplex. bonding: bond0: link status definitely up for interface eth0, 1000 Mbps full duplex. Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e498ce3defad..d5004826d19e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2406,6 +2406,8 @@ static void bond_miimon_commit(struct bonding *bond) slave->state = BOND_STATE_BACKUP; } + bond_update_speed_duplex(slave); + pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n", bond->dev->name, slave->dev->name, slave->speed, slave->duplex ? "full" : "half"); -- cgit v1.2.3 From d9d9a5194bb96d60fc846c94c602c874802e107d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 16:39:17 -0700 Subject: iwlagn: fix module firmware name for 130 series device 130 series device should use firmware name with 130 in it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 43ec8988feb0..b448b03ae6d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -78,8 +78,8 @@ #define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) #define IWL130_FW_PRE "iwlwifi-130-" -#define _IWL100_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode" -#define IWL100_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api) +#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode" +#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api) static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { -- cgit v1.2.3 From cf9768d6a3f901b00fc9d8ecdf8e506d7cbcae99 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 16:39:18 -0700 Subject: iwlagn: add define for MODULE_FIRMWARE Adding MODULE_FIRMWARE define for 130 series of devices Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index b448b03ae6d7..6261aec5ebdc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -858,3 +858,4 @@ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX)); -- cgit v1.2.3 From 767e97e1e0db0d0f3152cd2f3bd3403596aedbad Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 6 Oct 2010 17:49:21 -0700 Subject: neigh: RCU conversion of struct neighbour This is the second step for neighbour RCU conversion. (first was commit d6bf7817 : RCU conversion of neigh hash table) neigh_lookup() becomes lockless, but still take a reference on found neighbour. (no more read_lock()/read_unlock() on tbl->lock) struct neighbour gets an additional rcu_head field and is freed after an RCU grace period. Future work would need to eventually not take a reference on neighbour for temporary dst (DST_NOCACHE), but this would need dst->_neighbour to use a noref bit like we did for skb->_dst. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 5 +- net/core/neighbour.c | 137 ++++++++++++++++++++++++++++++------------------ 2 files changed, 88 insertions(+), 54 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 37845dae6488..a4538d553704 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -91,7 +91,7 @@ struct neigh_statistics { #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) struct neighbour { - struct neighbour *next; + struct neighbour __rcu *next; struct neigh_table *tbl; struct neigh_parms *parms; struct net_device *dev; @@ -111,6 +111,7 @@ struct neighbour { struct sk_buff_head arp_queue; struct timer_list timer; const struct neigh_ops *ops; + struct rcu_head rcu; u8 primary_key[0]; }; @@ -139,7 +140,7 @@ struct pneigh_entry { */ struct neigh_hash_table { - struct neighbour **hash_buckets; + struct neighbour __rcu **hash_buckets; unsigned int hash_mask; __u32 hash_rnd; struct rcu_head rcu; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index dd8920e4f508..3ffafaa0414c 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -139,10 +139,12 @@ static int neigh_forced_gc(struct neigh_table *tbl) nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); for (i = 0; i <= nht->hash_mask; i++) { - struct neighbour *n, **np; + struct neighbour *n; + struct neighbour __rcu **np; np = &nht->hash_buckets[i]; - while ((n = *np) != NULL) { + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { /* Neighbour record may be discarded if: * - nobody refers to it. * - it is not permanent @@ -150,7 +152,9 @@ static int neigh_forced_gc(struct neigh_table *tbl) write_lock(&n->lock); if (atomic_read(&n->refcnt) == 1 && !(n->nud_state & NUD_PERMANENT)) { - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); n->dead = 1; shrunk = 1; write_unlock(&n->lock); @@ -208,14 +212,18 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) lockdep_is_held(&tbl->lock)); for (i = 0; i <= nht->hash_mask; i++) { - struct neighbour *n, **np = &nht->hash_buckets[i]; + struct neighbour *n; + struct neighbour __rcu **np = &nht->hash_buckets[i]; - while ((n = *np) != NULL) { + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { if (dev && n->dev != dev) { np = &n->next; continue; } - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); write_lock(&n->lock); neigh_del_timer(n); n->dead = 1; @@ -323,7 +331,7 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) kfree(ret); return NULL; } - ret->hash_buckets = buckets; + rcu_assign_pointer(ret->hash_buckets, buckets); ret->hash_mask = entries - 1; get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); return ret; @@ -362,17 +370,22 @@ static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, for (i = 0; i <= old_nht->hash_mask; i++) { struct neighbour *n, *next; - for (n = old_nht->hash_buckets[i]; + for (n = rcu_dereference_protected(old_nht->hash_buckets[i], + lockdep_is_held(&tbl->lock)); n != NULL; n = next) { hash = tbl->hash(n->primary_key, n->dev, new_nht->hash_rnd); hash &= new_nht->hash_mask; - next = n->next; - - n->next = new_nht->hash_buckets[hash]; - new_nht->hash_buckets[hash] = n; + next = rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock)); + + rcu_assign_pointer(n->next, + rcu_dereference_protected( + new_nht->hash_buckets[hash], + lockdep_is_held(&tbl->lock))); + rcu_assign_pointer(new_nht->hash_buckets[hash], n); } } @@ -394,15 +407,18 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; - read_lock(&tbl->lock); - for (n = nht->hash_buckets[hash_val]; n; n = n->next) { + + for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + n != NULL; + n = rcu_dereference_bh(n->next)) { if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { - neigh_hold(n); + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; NEIGH_CACHE_STAT_INC(tbl, hits); break; } } - read_unlock(&tbl->lock); + rcu_read_unlock_bh(); return n; } @@ -421,16 +437,19 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask; - read_lock(&tbl->lock); - for (n = nht->hash_buckets[hash_val]; n; n = n->next) { + + for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + n != NULL; + n = rcu_dereference_bh(n->next)) { if (!memcmp(n->primary_key, pkey, key_len) && net_eq(dev_net(n->dev), net)) { - neigh_hold(n); + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; NEIGH_CACHE_STAT_INC(tbl, hits); break; } } - read_unlock(&tbl->lock); + rcu_read_unlock_bh(); return n; } @@ -483,7 +502,11 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, goto out_tbl_unlock; } - for (n1 = nht->hash_buckets[hash_val]; n1; n1 = n1->next) { + for (n1 = rcu_dereference_protected(nht->hash_buckets[hash_val], + lockdep_is_held(&tbl->lock)); + n1 != NULL; + n1 = rcu_dereference_protected(n1->next, + lockdep_is_held(&tbl->lock))) { if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) { neigh_hold(n1); rc = n1; @@ -491,10 +514,12 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, } } - n->next = nht->hash_buckets[hash_val]; - nht->hash_buckets[hash_val] = n; n->dead = 0; neigh_hold(n); + rcu_assign_pointer(n->next, + rcu_dereference_protected(nht->hash_buckets[hash_val], + lockdep_is_held(&tbl->lock))); + rcu_assign_pointer(nht->hash_buckets[hash_val], n); write_unlock_bh(&tbl->lock); NEIGH_PRINTK2("neigh %p is created.\n", n); rc = n; @@ -651,6 +676,12 @@ static inline void neigh_parms_put(struct neigh_parms *parms) neigh_parms_destroy(parms); } +static void neigh_destroy_rcu(struct rcu_head *head) +{ + struct neighbour *neigh = container_of(head, struct neighbour, rcu); + + kmem_cache_free(neigh->tbl->kmem_cachep, neigh); +} /* * neighbour must already be out of the table; * @@ -690,7 +721,7 @@ void neigh_destroy(struct neighbour *neigh) NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh); atomic_dec(&neigh->tbl->entries); - kmem_cache_free(neigh->tbl->kmem_cachep, neigh); + call_rcu(&neigh->rcu, neigh_destroy_rcu); } EXPORT_SYMBOL(neigh_destroy); @@ -731,7 +762,8 @@ static void neigh_connect(struct neighbour *neigh) static void neigh_periodic_work(struct work_struct *work) { struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work); - struct neighbour *n, **np; + struct neighbour *n; + struct neighbour __rcu **np; unsigned int i; struct neigh_hash_table *nht; @@ -756,7 +788,8 @@ static void neigh_periodic_work(struct work_struct *work) for (i = 0 ; i <= nht->hash_mask; i++) { np = &nht->hash_buckets[i]; - while ((n = *np) != NULL) { + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { unsigned int state; write_lock(&n->lock); @@ -1213,8 +1246,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, } /* This function can be used in contexts, where only old dev_queue_xmit - worked, f.e. if you want to override normal output path (eql, shaper), - but resolution is not made yet. + * worked, f.e. if you want to override normal output path (eql, shaper), + * but resolution is not made yet. */ int neigh_compat_output(struct sk_buff *skb) @@ -2123,7 +2156,7 @@ static void neigh_update_notify(struct neighbour *neigh) static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, struct netlink_callback *cb) { - struct net * net = sock_net(skb->sk); + struct net *net = sock_net(skb->sk); struct neighbour *n; int rc, h, s_h = cb->args[1]; int idx, s_idx = idx = cb->args[2]; @@ -2132,13 +2165,14 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - read_lock(&tbl->lock); for (h = 0; h <= nht->hash_mask; h++) { if (h < s_h) continue; if (h > s_h) s_idx = 0; - for (n = nht->hash_buckets[h], idx = 0; n; n = n->next) { + for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; + n != NULL; + n = rcu_dereference_bh(n->next)) { if (!net_eq(dev_net(n->dev), net)) continue; if (idx < s_idx) @@ -2150,13 +2184,12 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, rc = -1; goto out; } - next: +next: idx++; } } rc = skb->len; out: - read_unlock(&tbl->lock); rcu_read_unlock_bh(); cb->args[1] = h; cb->args[2] = idx; @@ -2195,11 +2228,13 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - read_lock(&tbl->lock); + read_lock(&tbl->lock); /* avoid resizes */ for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n; - for (n = nht->hash_buckets[chain]; n; n = n->next) + for (n = rcu_dereference_bh(nht->hash_buckets[chain]); + n != NULL; + n = rcu_dereference_bh(n->next)) cb(n, cookie); } read_unlock(&tbl->lock); @@ -2217,16 +2252,20 @@ void __neigh_for_each_release(struct neigh_table *tbl, nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); for (chain = 0; chain <= nht->hash_mask; chain++) { - struct neighbour *n, **np; + struct neighbour *n; + struct neighbour __rcu **np; np = &nht->hash_buckets[chain]; - while ((n = *np) != NULL) { + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { int release; write_lock(&n->lock); release = cb(n); if (release) { - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); n->dead = 1; } else np = &n->next; @@ -2250,7 +2289,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) state->flags &= ~NEIGH_SEQ_IS_PNEIGH; for (bucket = 0; bucket <= nht->hash_mask; bucket++) { - n = nht->hash_buckets[bucket]; + n = rcu_dereference_bh(nht->hash_buckets[bucket]); while (n) { if (!net_eq(dev_net(n->dev), net)) @@ -2267,8 +2306,8 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) break; if (n->nud_state & ~NUD_NOARP) break; - next: - n = n->next; +next: + n = rcu_dereference_bh(n->next); } if (n) @@ -2292,7 +2331,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (v) return n; } - n = n->next; + n = rcu_dereference_bh(n->next); while (1) { while (n) { @@ -2309,8 +2348,8 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (n->nud_state & ~NUD_NOARP) break; - next: - n = n->next; +next: + n = rcu_dereference_bh(n->next); } if (n) @@ -2319,7 +2358,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (++state->bucket > nht->hash_mask) break; - n = nht->hash_buckets[state->bucket]; + n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); } if (n && pos) @@ -2417,7 +2456,6 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos) } void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags) - __acquires(tbl->lock) __acquires(rcu_bh) { struct neigh_seq_state *state = seq->private; @@ -2428,7 +2466,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl rcu_read_lock_bh(); state->nht = rcu_dereference_bh(tbl->nht); - read_lock(&tbl->lock); + return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN; } EXPORT_SYMBOL(neigh_seq_start); @@ -2461,13 +2499,8 @@ out: EXPORT_SYMBOL(neigh_seq_next); void neigh_seq_stop(struct seq_file *seq, void *v) - __releases(tbl->lock) __releases(rcu_bh) { - struct neigh_seq_state *state = seq->private; - struct neigh_table *tbl = state->tbl; - - read_unlock(&tbl->lock); rcu_read_unlock_bh(); } EXPORT_SYMBOL(neigh_seq_stop); -- cgit v1.2.3 From dd53df265b1ee7a1fbbc76bb62c3bec2383bbd44 Mon Sep 17 00:00:00 2001 From: Krzysztof Oledzki Date: Thu, 30 Sep 2010 06:19:04 +0000 Subject: bonding: add Speed/Duplex information to /proc/net/bonding/bond Effect: Slave Interface: eth5 MII Status: up Speed: 10000 Mbps Duplex: full Link Failure Count: 0 Permanent HW addr: XX:XX:XX:XX:XX:XX Slave queue ID: 0 Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d5004826d19e..a0bf35d0d4f5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3353,6 +3353,8 @@ static void bond_info_show_slave(struct seq_file *seq, seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); seq_printf(seq, "MII Status: %s\n", (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "Speed: %d Mbps\n", slave->speed); + seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); seq_printf(seq, "Link Failure Count: %u\n", slave->link_failure_count); -- cgit v1.2.3 From 9c6d5e5537e3997c47b65925a235392c1968fb51 Mon Sep 17 00:00:00 2001 From: John Heffner Date: Wed, 6 Oct 2010 21:18:02 -0700 Subject: TCP: Fix setting of snd_ssthresh in tcp_mtu_probe_success This looks like a simple typo that has gone unnoticed for some time. The impact is relatively low but it's clearly wrong. Signed-off-by: John Heffner Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f6fdd727a23d..e4fbdae066d5 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2874,7 +2874,7 @@ static void tcp_mtup_probe_success(struct sock *sk) icsk->icsk_mtup.probe_size; tp->snd_cwnd_cnt = 0; tp->snd_cwnd_stamp = tcp_time_stamp; - tp->rcv_ssthresh = tcp_current_ssthresh(sk); + tp->snd_ssthresh = tcp_current_ssthresh(sk); icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size; icsk->icsk_mtup.probe_size = 0; -- cgit v1.2.3 From 10e7e9c44d442275951d1cfc892c1c6606c85c94 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Wed, 6 Oct 2010 03:59:56 +0000 Subject: sundance: Drop legacy _COMPAT_WITH_OLD_KERNEL includes Drop legacy includes since 2.4.x Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sundance.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 8b5aeca24d5d..27d69aaba486 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -97,16 +97,9 @@ static char *media[MAX_UNITS]; #include #include #include -#ifndef _COMPAT_WITH_OLD_KERNEL #include #include #include -#else -#include "crc32.h" -#include "ethtool.h" -#include "mii.h" -#include "compat.h" -#endif /* These identify the driver base version and may not be removed. */ static const char version[] __devinitconst = -- cgit v1.2.3 From 1f4f0f645cc1d7f1187fcdb0ac22c2e69bd68050 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 5 Oct 2010 04:24:09 +0000 Subject: dccp: Kill dead code and add static markers. Remove dead code and make some functions static. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/dccp/dccp.h | 2 -- net/dccp/feat.c | 10 ---------- net/dccp/feat.h | 1 - net/dccp/options.c | 4 +--- net/dccp/proto.c | 48 ++++++++++++++++++++++++------------------------ 5 files changed, 25 insertions(+), 40 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 3ccef1b70fee..019d6ffee354 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -246,7 +246,6 @@ static inline void dccp_clear_xmit_timers(struct sock *sk) extern unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu); extern const char *dccp_packet_name(const int type); -extern const char *dccp_state_name(const int state); extern void dccp_set_state(struct sock *sk, const int state); extern void dccp_done(struct sock *sk); @@ -449,7 +448,6 @@ extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*); extern int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed); extern u32 dccp_timestamp(void); extern void dccp_timestamping_init(void); -extern int dccp_insert_option_timestamp(struct sk_buff *skb); extern int dccp_insert_option(struct sk_buff *skb, unsigned char option, const void *value, unsigned char len); diff --git a/net/dccp/feat.c b/net/dccp/feat.c index df7dd26cf07e..568def952722 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -730,16 +730,6 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, 0, list, len); } -/* Analogous to dccp_feat_register_sp(), but for non-negotiable values */ -int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val) -{ - /* any changes must be registered before establishing the connection */ - if (sk->sk_state != DCCP_CLOSED) - return -EISCONN; - if (dccp_feat_type(feat) != FEAT_NN) - return -EINVAL; - return __feat_register_nn(&dccp_sk(sk)->dccps_featneg, feat, 0, val); -} /* * Tracking features whose value depend on the choice of CCID diff --git a/net/dccp/feat.h b/net/dccp/feat.h index f96721619def..e56a4e5e634e 100644 --- a/net/dccp/feat.h +++ b/net/dccp/feat.h @@ -111,7 +111,6 @@ extern int dccp_feat_init(struct sock *sk); extern void dccp_feat_initialise_sysctls(void); extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, u8 const *list, u8 len); -extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val); extern int dccp_feat_parse_options(struct sock *, struct dccp_request_sock *, u8 mand, u8 opt, u8 feat, u8 *val, u8 len); extern int dccp_feat_clone_list(struct list_head const *, struct list_head *); diff --git a/net/dccp/options.c b/net/dccp/options.c index 92718511eac5..d4b1ae0daacb 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -369,7 +369,7 @@ int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); -int dccp_insert_option_timestamp(struct sk_buff *skb) +static int dccp_insert_option_timestamp(struct sk_buff *skb) { __be32 now = htonl(dccp_timestamp()); /* yes this will overflow but that is the point as we want a @@ -378,8 +378,6 @@ int dccp_insert_option_timestamp(struct sk_buff *skb) return dccp_insert_option(skb, DCCPO_TIMESTAMP, &now, sizeof(now)); } -EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp); - static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp, struct dccp_request_sock *dreq, struct sk_buff *skb) diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 096250d1323b..b054ba1f55d2 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -50,6 +50,30 @@ EXPORT_SYMBOL_GPL(dccp_hashinfo); /* the maximum queue length for tx in packets. 0 is no limit */ int sysctl_dccp_tx_qlen __read_mostly = 5; +#ifdef CONFIG_IP_DCCP_DEBUG +static const char *dccp_state_name(const int state) +{ + static const char *const dccp_state_names[] = { + [DCCP_OPEN] = "OPEN", + [DCCP_REQUESTING] = "REQUESTING", + [DCCP_PARTOPEN] = "PARTOPEN", + [DCCP_LISTEN] = "LISTEN", + [DCCP_RESPOND] = "RESPOND", + [DCCP_CLOSING] = "CLOSING", + [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ", + [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE", + [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ", + [DCCP_TIME_WAIT] = "TIME_WAIT", + [DCCP_CLOSED] = "CLOSED", + }; + + if (state >= DCCP_MAX_STATES) + return "INVALID STATE!"; + else + return dccp_state_names[state]; +} +#endif + void dccp_set_state(struct sock *sk, const int state) { const int oldstate = sk->sk_state; @@ -146,30 +170,6 @@ const char *dccp_packet_name(const int type) EXPORT_SYMBOL_GPL(dccp_packet_name); -const char *dccp_state_name(const int state) -{ - static const char *const dccp_state_names[] = { - [DCCP_OPEN] = "OPEN", - [DCCP_REQUESTING] = "REQUESTING", - [DCCP_PARTOPEN] = "PARTOPEN", - [DCCP_LISTEN] = "LISTEN", - [DCCP_RESPOND] = "RESPOND", - [DCCP_CLOSING] = "CLOSING", - [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ", - [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE", - [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ", - [DCCP_TIME_WAIT] = "TIME_WAIT", - [DCCP_CLOSED] = "CLOSED", - }; - - if (state >= DCCP_MAX_STATES) - return "INVALID STATE!"; - else - return dccp_state_names[state]; -} - -EXPORT_SYMBOL_GPL(dccp_state_name); - int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) { struct dccp_sock *dp = dccp_sk(sk); -- cgit v1.2.3 From c2dddf941409635601e56c1990c5ab0bd395742c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Oct 2010 09:24:59 +0000 Subject: eicon: make buffer larger In diva_mnt_add_xdi_adapter() we do this: strcpy (clients[id].drvName, tmp); strcpy (clients[id].Dbg.drvName, tmp); The "clients[id].drvName" is a 128 character buffer and "clients[id].Dbg.drvName" was originally a 16 character buffer but I've changed it to 128 as well. We don't actually use 128 characters but we do use more than 16. I've also changed the size of "tmp" to 128 characters instead of 256. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/debug.c | 2 +- drivers/isdn/hardware/eicon/debuglib.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 33ce89eed65b..362640120886 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c @@ -862,7 +862,7 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { diva_os_spin_lock_magic_t old_irql, old_irql1; dword sec, usec, logical, serial, org_mask; int id, best_id = 0, free_id = -1; - char tmp[256]; + char tmp[128]; diva_dbg_entry_head_t* pmsg = NULL; int len; word size; diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h index 8ea587783e14..02eed6b4354c 100644 --- a/drivers/isdn/hardware/eicon/debuglib.h +++ b/drivers/isdn/hardware/eicon/debuglib.h @@ -249,7 +249,7 @@ typedef struct _DbgHandle_ } regTime ; /* timestamp for registration */ void *pIrp ; /* ptr to pending i/o request */ unsigned long dbgMask ; /* current debug mask */ - char drvName[16] ; /* ASCII name of registered driver */ + char drvName[128] ; /* ASCII name of registered driver */ char drvTag[64] ; /* revision string */ DbgEnd dbg_end ; /* function for debug closing */ DbgLog dbg_prt ; /* function for debug appending */ -- cgit v1.2.3 From 3d3211ef5cf7558d289d1a1efbef8c45595639aa Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 6 Oct 2010 23:35:15 -0700 Subject: net: netif_set_real_num_rx_queues may cap num_rx_queues at init time Do not set num_rx_queues in netif_set_real_num_rx_queues() some drivers will increase the real_num_rx_queues later due to a feature changes or available interrupts increasing. By setting num_rx_queues here this ends up creating a cap on the number of rx queues available. For example the ixgbe driver sets the max number of queues it intends to use ever then sets the current number in use with the netif_set_num_{rx|tx}_queues calls. With the current implementation the number of rx queues gets limited so when a feature such as DCB or FCoE is enabled the queues are no longer available. kobjects will only be allocated for real_num_rx_queues so the waste in memory is minimal. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 7d149550e8d6..fd1b75a47e88 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1593,8 +1593,6 @@ int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) rxq); if (rc) return rc; - } else { - dev->num_rx_queues = rxq; } dev->real_num_rx_queues = rxq; -- cgit v1.2.3 From 9deec17f9fe260f1b6467748fe5e16feea8e98f0 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 1 Oct 2010 11:17:13 +0000 Subject: drivers/net/stmmac/: add HAS_IOMEM dependency The stmmac driver does not compile on s390: drivers/net/stmmac/stmmac_main.c: In function 'stmmac_adjust_link': drivers/net/stmmac/stmmac_main.c:210: error: implicit declaration of function 'readl' drivers/net/stmmac/stmmac_main.c:263: error: implicit declaration of function 'writel' drivers/net/stmmac/stmmac_main.c: In function 'stmmac_dvr_probe': drivers/net/stmmac/stmmac_main.c:1674: error: implicit declaration of function 'ioremap' drivers/net/stmmac/stmmac_main.c:1674: warning: assignment makes pointer from integer without a cast drivers/net/stmmac/stmmac_main.c:1761: error: implicit declaration of function 'iounmap' make[3]: *** [drivers/net/stmmac/stmmac_main.o] Error 1 Signed-off-by: Martin Schwidefsky Cc: Giuseppe CAVALLARO Cc: David S. Miller Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/stmmac/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig index 3c2af7c6a39b..7df7df4e79c5 100644 --- a/drivers/net/stmmac/Kconfig +++ b/drivers/net/stmmac/Kconfig @@ -3,7 +3,7 @@ config STMMAC_ETH select MII select PHYLIB select CRC32 - depends on NETDEVICES + depends on NETDEVICES && HAS_IOMEM help This is the driver for the Ethernet IPs are built around a Synopsys IP Core and only tested on the STMicroelectronics -- cgit v1.2.3 From b25ebfd21b03b3b59c1c7a7e0c597fd28286bb10 Mon Sep 17 00:00:00 2001 From: Peter Waskiewicz Date: Tue, 5 Oct 2010 01:27:49 +0000 Subject: ixgbe: Use affinity_hint when Flow Director is enabled Use the new infrastructure to balance interrupts for flow alignment when ATR or Flow Director are enabled. Signed-off-by: Peter P Waskiewicz Jr Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 2 ++ drivers/net/ixgbe/ixgbe_main.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 5cebc3755b64..a8c47b01a6fa 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "ixgbe_type.h" @@ -241,6 +242,7 @@ struct ixgbe_q_vector { u8 tx_itr; u8 rx_itr; u32 eitr; + cpumask_var_t affinity_mask; }; /* Helper macros to switch between ints/sec and what the register uses. diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c35e13c01dbe..95dbf60c8169 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1433,6 +1433,21 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector->eitr = adapter->rx_eitr_param; ixgbe_write_eitr(q_vector); + /* If Flow Director is enabled, set interrupt affinity */ + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* + * Allocate the affinity_hint cpumask, assign the mask + * for this vector, and set our affinity_hint for + * this irq. + */ + if (!alloc_cpumask_var(&q_vector->affinity_mask, + GFP_KERNEL)) + return; + cpumask_set_cpu(v_idx, q_vector->affinity_mask); + irq_set_affinity_hint(adapter->msix_entries[v_idx].vector, + q_vector->affinity_mask); + } } if (adapter->hw.mac.type == ixgbe_mac_82598EB) @@ -3816,6 +3831,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) u32 rxctrl; u32 txdctl; int i, j; + int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; /* signal that we are down to the interrupt handler */ set_bit(__IXGBE_DOWN, &adapter->state); @@ -3854,6 +3870,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ixgbe_napi_disable_all(adapter); + /* Cleanup the affinity_hint CPU mask memory and callback */ + for (i = 0; i < num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + /* clear the affinity_mask in the IRQ descriptor */ + irq_set_affinity_hint(adapter->msix_entries[i]. vector, NULL); + /* release the CPU mask memory */ + free_cpumask_var(q_vector->affinity_mask); + } + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) cancel_work_sync(&adapter->fdir_reinit_task); -- cgit v1.2.3 From a6d27d2ac89359f84c1a559b5530967ff671d269 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 7 Oct 2010 11:31:56 -0400 Subject: Revert "rtl8180: use NAPI for bottom-half processing" This reverts commit 030725d2c7c1fafec7ede618647bf30ed79601f0. This commit relies on commit 5ed3bc7288487bd4f891f420a07319e0b538b4fe ("mac80211: use netif_receive_skb in ieee80211_tx_status callpath") Unfortunately not all drivers are calling ieee80211_tx_status from a compatible context, so that commit needs to be reverted in 2.6.36. Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 128 +++++++++++++---------------- 1 file changed, 59 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 05c6badbe201..707c688da618 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -99,66 +99,19 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) } } -static void rtl8180_handle_tx(struct ieee80211_hw *dev) +static void rtl8180_handle_rx(struct ieee80211_hw *dev) { struct rtl8180_priv *priv = dev->priv; - struct rtl8180_tx_ring *ring; - int prio; - - spin_lock(&priv->lock); - - for (prio = 3; prio >= 0; prio--) { - ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - u32 flags = le32_to_cpu(entry->flags); - - if (flags & RTL818X_TX_DESC_FLAG_OWN) - break; - - ring->idx = (ring->idx + 1) % ring->entries; - skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), - skb->len, PCI_DMA_TODEVICE); - - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (flags & RTL818X_TX_DESC_FLAG_TX_OK)) - info->flags |= IEEE80211_TX_STAT_ACK; - - info->status.rates[0].count = (flags & 0xFF) + 1; - info->status.rates[1].idx = -1; - - ieee80211_tx_status(dev, skb); - if (ring->entries - skb_queue_len(&ring->queue) == 2) - ieee80211_wake_queue(dev, prio); - } - } - - spin_unlock(&priv->lock); -} - -static int rtl8180_poll(struct ieee80211_hw *dev, int budget) -{ - struct rtl8180_priv *priv = dev->priv; - unsigned int count = 0; + unsigned int count = 32; u8 signal, agc, sq; - /* handle pending Tx queue cleanup */ - rtl8180_handle_tx(dev); - - while (count++ < budget) { + while (count--) { struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; u32 flags = le32_to_cpu(entry->flags); if (flags & RTL818X_RX_DESC_FLAG_OWN) - break; + return; if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL | RTL818X_RX_DESC_FLAG_FOF | @@ -198,7 +151,7 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget) rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - ieee80211_rx(dev, skb); + ieee80211_rx_irqsafe(dev, skb); skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; @@ -215,16 +168,41 @@ static int rtl8180_poll(struct ieee80211_hw *dev, int budget) entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); priv->rx_idx = (priv->rx_idx + 1) % 32; } +} + +static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) +{ + struct rtl8180_priv *priv = dev->priv; + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; - if (count < budget) { - /* disable polling */ - ieee80211_napi_complete(dev); + while (skb_queue_len(&ring->queue)) { + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + u32 flags = le32_to_cpu(entry->flags); - /* enable interrupts */ - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); - } + if (flags & RTL818X_TX_DESC_FLAG_OWN) + return; + + ring->idx = (ring->idx + 1) % ring->entries; + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), + skb->len, PCI_DMA_TODEVICE); + + info = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(info); + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && + (flags & RTL818X_TX_DESC_FLAG_TX_OK)) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = (flags & 0xFF) + 1; + info->status.rates[1].idx = -1; - return count; + ieee80211_tx_status_irqsafe(dev, skb); + if (ring->entries - skb_queue_len(&ring->queue) == 2) + ieee80211_wake_queue(dev, prio); + } } static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) @@ -233,17 +211,31 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) struct rtl8180_priv *priv = dev->priv; u16 reg; + spin_lock(&priv->lock); reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); - if (unlikely(reg == 0xFFFF)) + if (unlikely(reg == 0xFFFF)) { + spin_unlock(&priv->lock); return IRQ_HANDLED; + } rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); - /* disable interrupts */ - rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); + if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) + rtl8180_handle_tx(dev, 3); + + if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) + rtl8180_handle_tx(dev, 2); + + if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) + rtl8180_handle_tx(dev, 1); - /* enable polling */ - ieee80211_napi_schedule(dev); + if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) + rtl8180_handle_tx(dev, 0); + + if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) + rtl8180_handle_rx(dev); + + spin_unlock(&priv->lock); return IRQ_HANDLED; } @@ -255,6 +247,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) struct rtl8180_priv *priv = dev->priv; struct rtl8180_tx_ring *ring; struct rtl8180_tx_desc *entry; + unsigned long flags; unsigned int idx, prio; dma_addr_t mapping; u32 tx_flags; @@ -301,7 +294,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) plcp_len |= 1 << 15; } - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) @@ -325,7 +318,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) if (ring->entries - skb_queue_len(&ring->queue) < 2) ieee80211_stop_queue(dev, prio); - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); @@ -871,7 +864,6 @@ static const struct ieee80211_ops rtl8180_ops = { .prepare_multicast = rtl8180_prepare_multicast, .configure_filter = rtl8180_configure_filter, .get_tsf = rtl8180_get_tsf, - .napi_poll = rtl8180_poll, }; static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) @@ -1003,8 +995,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, dev->queues = 1; dev->max_signal = 65; - dev->napi_weight = 64; - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); reg &= RTL818X_TX_CONF_HWVER_MASK; switch (reg) { -- cgit v1.2.3 From 4b34d432b0fcff422304de4eb49d6da861fe335c Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 7 Oct 2010 10:16:42 +0300 Subject: wl1271: Support FEM autodetection In the NVS/INI-parameters for the driver/firmware there is the FEM (front end module) selection option, which may configure the hardware FEM via autodetection or manual selection. So far, there has been support for manual selection only. Add support for FEM autodetection. Signed-off-by: Juuso Oikarinen Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_cmd.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 596e333919ae..5d3e8485ea4e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -108,6 +108,8 @@ out: int wl1271_cmd_general_parms(struct wl1271 *wl) { struct wl1271_general_parms_cmd *gen_parms; + struct wl1271_ini_general_params *gp = &wl->nvs->general_params; + bool answer = false; int ret; if (!wl->nvs) @@ -119,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; - memcpy(&gen_parms->general_params, &wl->nvs->general_params, - sizeof(struct wl1271_ini_general_params)); + memcpy(&gen_parms->general_params, gp, sizeof(*gp)); - ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); - if (ret < 0) + if (gp->tx_bip_fem_auto_detect) + answer = true; + + ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); + if (ret < 0) { wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); + goto out; + } + + gp->tx_bip_fem_manufacturer = + gen_parms->general_params.tx_bip_fem_manufacturer; + wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", + answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); + +out: kfree(gen_parms); return ret; } -- cgit v1.2.3 From 7b99a7c2dab7efe7c265b66fedbf3444958ebfe3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 12:55:24 +0200 Subject: mac80211: fix sw scan locking The recent scan overhaul broke locking because now we can jump to code that attempts to unlock, while we don't have the mutex held. Fix this by holding the mutex around all the relevant code. Reported-by: Ben Greear Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/scan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 523db930dabb..fb274db77e3c 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -681,8 +681,6 @@ void ieee80211_scan_work(struct work_struct *work) goto out_complete; } - mutex_unlock(&local->mtx); - /* * as long as no delay is required advance immediately * without scheduling a new work @@ -713,6 +711,7 @@ void ieee80211_scan_work(struct work_struct *work) } while (next_delay == 0); ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); + mutex_unlock(&local->mtx); return; out_complete: -- cgit v1.2.3 From 43b19952de54b0fccfcdc5968891ebe550367fe8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 13:10:30 +0200 Subject: nl80211: use new genl helpers for WDS Bill Jordan's patch to allow setting the WDS peer crossed with my patch removing all the boilerplate code in nl80211, and consequently he didn't make use of it yet. Fix that. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 524f55402838..4fed1663aba3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -876,48 +876,25 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct wireless_dev *wdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; u8 *bssid; - int err; if (!info->attrs[NL80211_ATTR_MAC]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - wdev = dev->ieee80211_ptr; - - if (netif_running(dev)) { - err = -EBUSY; - goto out; - } + if (netif_running(dev)) + return -EBUSY; - if (!rdev->ops->set_wds_peer) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->set_wds_peer) + return -EOPNOTSUPP; - if (wdev->iftype != NL80211_IFTYPE_WDS) { - err = -EOPNOTSUPP; - goto out; - } + if (wdev->iftype != NL80211_IFTYPE_WDS) + return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); - err = rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - - return err; + return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); } @@ -4860,6 +4837,8 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_wds_peer, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, }; -- cgit v1.2.3 From 388ac775be95e510c2095ed6cd59422a5183a9fb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 13:11:09 +0200 Subject: cfg80211: constify WDS address There's no need for the WDS peer address to not be const, so make it const. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 2 +- net/mac80211/cfg.c | 2 +- net/wireless/nl80211.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e76daaa7dc25..0778d04b3bbe 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1229,7 +1229,7 @@ struct cfg80211_ops { int (*get_tx_power)(struct wiphy *wiphy, int *dbm); int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, - u8 *addr); + const u8 *addr); void (*rfkill_poll)(struct wiphy *wiphy); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 2e5a3fb38efe..ecf9b7166ed1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1363,7 +1363,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) } static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, - u8 *addr) + const u8 *addr) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4fed1663aba3..882dc921103b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -879,7 +879,7 @@ static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; - u8 *bssid; + const u8 *bssid; if (!info->attrs[NL80211_ATTR_MAC]) return -EINVAL; -- cgit v1.2.3 From 15a6321d1c0f8db561932cd99e1b9897981da71f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 7 Oct 2010 20:58:39 +0530 Subject: ath9k_hw: Fix hw reset failure with HTC driver The following commit removed DISABLE_REGWRITE_BUFFER ops. The unnecessary REGWRITE_BUFFER_FLUSH was not removed properly which is causing failure on hw reset. Author: Felix Fietkau Date: Tue Oct 5 12:03:42 2010 +0200 ath9k_hw: clean up register write buffering Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e5784595bd0f..8c13479b17cd 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -491,8 +491,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REG_WRITE(ah, AR_DMISC(q), AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); - REGWRITE_BUFFER_FLUSH(ah); - if (qi->tqi_cbrPeriod) { REG_WRITE(ah, AR_QCBRCFG(q), SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | @@ -508,8 +506,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) AR_Q_RDYTIMECFG_EN); } - REGWRITE_BUFFER_FLUSH(ah); - REG_WRITE(ah, AR_DCHNTIME(q), SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); -- cgit v1.2.3 From 7314c2b377afaf367f2966bd9ea67bf83350e29b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:01:55 +0200 Subject: iwlagn: rename iwl_commit_rxon iwl_commit_rxon really should be named iwlagn_commit_rxon, so rename it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn.h | 3 +++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 834c2f9c15d7..09db9407aa54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2216,7 +2216,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, + .commit_rxon = iwlagn_commit_rxon, .set_rxon_chain = iwl_set_rxon_chain, .send_bt_config = iwl_send_bt_config, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 9ca6c91eaae6..901452ee623a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -360,7 +360,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) struct iwl_hcmd_ops iwlagn_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, + .commit_rxon = iwlagn_commit_rxon, .set_rxon_chain = iwl_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwl_send_bt_config, @@ -369,7 +369,7 @@ struct iwl_hcmd_ops iwlagn_hcmd = { struct iwl_hcmd_ops iwlagn_bt_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, + .commit_rxon = iwlagn_commit_rxon, .set_rxon_chain = iwl_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwlagn_send_advance_bt_config, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a6dce616ee3c..b59ce92730c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -91,14 +91,14 @@ static int iwlagn_ant_coupling; static bool iwlagn_bt_ch_announce = 1; /** - * iwl_commit_rxon - commit staging_rxon to hardware + * iwlagn_commit_rxon - commit staging_rxon to hardware * * The RXON command in staging_rxon is committed to the hardware and * the active_rxon structure is updated with the new data. This * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index eb3812a35862..2a1c83bda919 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -129,6 +129,9 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); void iwl_free_tfds_in_queue(struct iwl_priv *priv, int sta_id, int tid, int freed); +/* RXON */ +int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + /* uCode */ int iwlagn_load_ucode(struct iwl_priv *priv); void iwlagn_rx_calib_result(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6228b1c2ec96..d6d5bb0f0eb0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -432,7 +432,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void iwl_mac_remove_interface(struct ieee80211_hw *hw, -- cgit v1.2.3 From a77029ee3fc03a37238b73892e55b789273991aa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:01:56 +0200 Subject: iwlwifi: introduce post_scan hook The different drivers need to do different things after a scan, so create a post_scan hook to allow them to do this. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 + drivers/net/wireless/iwlwifi/iwl-3945.h | 1 + drivers/net/wireless/iwlwifi/iwl-4965.c | 13 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 11 +---------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 12 ++++++++++++ 9 files changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index cfdff5487e3c..87943a8da797 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2713,6 +2713,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .build_addsta_hcmd = iwl3945_build_addsta_hcmd, .tx_cmd_protection = iwlcore_tx_cmd_protection, .request_scan = iwl3945_request_scan, + .post_scan = iwl3945_post_scan, }; static const struct iwl_ops iwl3945_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 98509c5e708d..7ad4aff5a550 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -296,6 +296,7 @@ extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); /* scanning */ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwl3945_post_scan(struct iwl_priv *priv); /* Requires full declaration of iwl_priv before including */ #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 09db9407aa54..e161f5d7044d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2221,6 +2221,18 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { .send_bt_config = iwl_send_bt_config, }; +static void iwl4965_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); +} + static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .get_hcmd_size = iwl4965_get_hcmd_size, .build_addsta_hcmd = iwl4965_build_addsta_hcmd, @@ -2229,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .tx_cmd_protection = iwlcore_tx_cmd_protection, .calc_rssi = iwl4965_calc_rssi, .request_scan = iwlagn_request_scan, + .post_scan = iwl4965_post_scan, }; static struct iwl_lib_ops iwl4965_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 901452ee623a..634177d827d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -384,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { .tx_cmd_protection = iwlagn_tx_cmd_protection, .calc_rssi = iwlagn_calc_rssi, .request_scan = iwlagn_request_scan, + .post_scan = iwlagn_post_scan, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f5445d575fec..3fa2c5c3706a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1565,6 +1565,22 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) return ret; } +void iwlagn_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + for_each_context(priv, ctx) + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlagn_commit_rxon(priv, ctx); + + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); +} + int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2a1c83bda919..960fe2e5e579 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -227,6 +227,7 @@ void iwl_reply_statistics(struct iwl_priv *priv, /* scan */ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwlagn_post_scan(struct iwl_priv *priv); /* station mgmt */ int iwlagn_manage_ibss_station(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d6d5bb0f0eb0..09908f604e28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -112,6 +112,7 @@ struct iwl_hcmd_utils_ops { int (*calc_rssi)(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp); int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); + void (*post_scan)(struct iwl_priv *priv); }; struct iwl_apm_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index eaae49ee0c60..a7e8c7f969f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -559,7 +559,6 @@ static void iwl_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); bool aborted; - struct iwl_rxon_context *ctx; IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", priv->is_internal_short_scan ? "internal short " : ""); @@ -609,15 +608,7 @@ out_settings: * performing the scan, fire one off */ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - for_each_context(priv, ctx) - iwlcore_commit_rxon(priv, ctx); - - if (priv->cfg->ops->hcmd->set_pan_params) - priv->cfg->ops->hcmd->set_pan_params(priv); + priv->cfg->ops->utils->post_scan(priv); out: mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 43db5f38e3e6..db148d05af1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2983,6 +2983,18 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) return ret; } +void iwl3945_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); +} + static void iwl3945_bg_restart(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); -- cgit v1.2.3 From 8289e07b8a4b588e167bc84f93419458fd6efa3e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:01:57 +0200 Subject: iwl3945: use iwl3945_commit_rxon There's no need to go via the indirect function call from within the 3945 subdriver. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-3945.h | 3 +++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 87943a8da797..ef670879e359 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1763,8 +1763,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -static int iwl3945_commit_rxon(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) +int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 7ad4aff5a550..77e8e1970350 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -271,6 +271,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv, extern void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif); +extern int iwl3945_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + /** * iwl3945_hw_find_station - Find station id for a given BSSID * @bssid: MAC address of station ID to find diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index db148d05af1a..64eb049140dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2547,7 +2547,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); iwl3945_reg_txpower_periodic(priv); @@ -2992,7 +2992,7 @@ void iwl3945_post_scan(struct iwl_priv *priv) * performing the scan, fire one off if needed */ if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); } static void iwl3945_bg_restart(struct work_struct *data) @@ -3061,7 +3061,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) conf = ieee80211_get_hw_conf(priv->hw); ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); rc = iwl_send_rxon_timing(priv, ctx); if (rc) @@ -3087,7 +3087,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3226,7 +3226,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) /* RXON - unassoc (to set timing command) */ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); /* RXON Timing */ rc = iwl_send_rxon_timing(priv, ctx); @@ -3253,7 +3253,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) } /* restore RXON assoc */ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); } iwl3945_send_beacon_cmd(priv); @@ -3519,7 +3519,7 @@ static ssize_t store_flags(struct device *d, IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", flags); ctx->staging.flags = cpu_to_le32(flags); - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); @@ -3557,7 +3557,7 @@ static ssize_t store_filter_flags(struct device *d, "0x%04X\n", filter_flags); ctx->staging.filter_flags = cpu_to_le32(filter_flags); - iwlcore_commit_rxon(priv, ctx); + iwl3945_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); -- cgit v1.2.3 From 5de33068a2f841536ca8632534e3e193d5b2607f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:01:58 +0200 Subject: iwlwifi: move chain settings to agn The core module doesn't need to carry around the code for chain settings that is used for HT drivers (agn) only. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 140 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 141 ---------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 144 insertions(+), 145 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e161f5d7044d..20626c997b4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2217,7 +2217,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, .commit_rxon = iwlagn_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, + .set_rxon_chain = iwlagn_set_rxon_chain, .send_bt_config = iwl_send_bt_config, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 634177d827d3..ffb2f4111ad0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -361,7 +361,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) struct iwl_hcmd_ops iwlagn_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, .commit_rxon = iwlagn_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, + .set_rxon_chain = iwlagn_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwl_send_bt_config, .set_pan_params = iwlagn_set_pan_params, @@ -370,7 +370,7 @@ struct iwl_hcmd_ops iwlagn_hcmd = { struct iwl_hcmd_ops iwlagn_bt_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, .commit_rxon = iwlagn_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, + .set_rxon_chain = iwlagn_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwlagn_send_advance_bt_config, .set_pan_params = iwlagn_set_pan_params, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3fa2c5c3706a..0b45bced9c0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2065,3 +2065,143 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv) { cancel_work_sync(&priv->bt_traffic_change_work); } + +static bool is_single_rx_stream(struct iwl_priv *priv) +{ + return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC || + priv->current_ht_config.single_chain_sufficient; +} + +#define IWL_NUM_RX_CHAINS_MULTIPLE 3 +#define IWL_NUM_RX_CHAINS_SINGLE 2 +#define IWL_NUM_IDLE_CHAINS_DUAL 2 +#define IWL_NUM_IDLE_CHAINS_SINGLE 1 + +/* + * Determine how many receiver/antenna chains to use. + * + * More provides better reception via diversity. Fewer saves power + * at the expense of throughput, but only when not in powersave to + * start with. + * + * MIMO (dual stream) requires at least 2, but works better with 3. + * This does not determine *which* chains to use, just how many. + */ +static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) +{ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ + return IWL_NUM_RX_CHAINS_SINGLE; + } + /* # of Rx chains to use when expecting MIMO. */ + if (is_single_rx_stream(priv)) + return IWL_NUM_RX_CHAINS_SINGLE; + else + return IWL_NUM_RX_CHAINS_MULTIPLE; +} + +/* + * When we are in power saving mode, unless device support spatial + * multiplexing power save, use the active count for rx chain count. + */ +static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) +{ + /* # Rx chains when idling, depending on SMPS mode */ + switch (priv->current_ht_config.smps) { + case IEEE80211_SMPS_STATIC: + case IEEE80211_SMPS_DYNAMIC: + return IWL_NUM_IDLE_CHAINS_SINGLE; + case IEEE80211_SMPS_OFF: + return active_cnt; + default: + WARN(1, "invalid SMPS mode %d", + priv->current_ht_config.smps); + return active_cnt; + } +} + +/* up to 4 chains */ +static u8 iwl_count_chain_bitmap(u32 chain_bitmap) +{ + u8 res; + res = (chain_bitmap & BIT(0)) >> 0; + res += (chain_bitmap & BIT(1)) >> 1; + res += (chain_bitmap & BIT(2)) >> 2; + res += (chain_bitmap & BIT(3)) >> 3; + return res; +} + +/** + * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image + * + * Selects how many and which Rx receivers/antennas/chains to use. + * This should not be used for scan command ... it puts data in wrong place. + */ +void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + bool is_single = is_single_rx_stream(priv); + bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); + u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; + u32 active_chains; + u16 rx_chain; + + /* Tell uCode which antennas are actually connected. + * Before first association, we assume all antennas are connected. + * Just after first association, iwl_chain_noise_calibration() + * checks which antennas actually *are* connected. */ + if (priv->chain_noise_data.active_chains) + active_chains = priv->chain_noise_data.active_chains; + else + active_chains = priv->hw_params.valid_rx_ant; + + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ + active_chains = first_antenna(active_chains); + } + + rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; + + /* How many receivers should we use? */ + active_rx_cnt = iwl_get_active_rx_chain_count(priv); + idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); + + + /* correct rx chain count according hw settings + * and chain noise calibration + */ + valid_rx_cnt = iwl_count_chain_bitmap(active_chains); + if (valid_rx_cnt < active_rx_cnt) + active_rx_cnt = valid_rx_cnt; + + if (valid_rx_cnt < idle_rx_cnt) + idle_rx_cnt = valid_rx_cnt; + + rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; + rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; + + ctx->staging.rx_chain = cpu_to_le16(rx_chain); + + if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) + ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + else + ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + + IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", + ctx->staging.rx_chain, + active_rx_cnt, idle_rx_cnt); + + WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || + active_rx_cnt < idle_rx_cnt); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 960fe2e5e579..5d5cacb54eb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -131,6 +131,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, /* RXON */ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); /* uCode */ int iwlagn_load_ucode(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 516c55ae38aa..dd7c3cbd2f6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -439,12 +439,6 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv, EXPORT_SYMBOL(iwlcore_tx_cmd_protection); -static bool is_single_rx_stream(struct iwl_priv *priv) -{ - return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC || - priv->current_ht_config.single_chain_sufficient; -} - static bool iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, u16 channel, u8 extension_chan_offset) @@ -834,141 +828,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) } EXPORT_SYMBOL(iwl_set_rxon_ht); -#define IWL_NUM_RX_CHAINS_MULTIPLE 3 -#define IWL_NUM_RX_CHAINS_SINGLE 2 -#define IWL_NUM_IDLE_CHAINS_DUAL 2 -#define IWL_NUM_IDLE_CHAINS_SINGLE 1 - -/* - * Determine how many receiver/antenna chains to use. - * - * More provides better reception via diversity. Fewer saves power - * at the expense of throughput, but only when not in powersave to - * start with. - * - * MIMO (dual stream) requires at least 2, but works better with 3. - * This does not determine *which* chains to use, just how many. - */ -static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) -{ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - (priv->bt_full_concurrent || - priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { - /* - * only use chain 'A' in bt high traffic load or - * full concurrency mode - */ - return IWL_NUM_RX_CHAINS_SINGLE; - } - /* # of Rx chains to use when expecting MIMO. */ - if (is_single_rx_stream(priv)) - return IWL_NUM_RX_CHAINS_SINGLE; - else - return IWL_NUM_RX_CHAINS_MULTIPLE; -} - -/* - * When we are in power saving mode, unless device support spatial - * multiplexing power save, use the active count for rx chain count. - */ -static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) -{ - /* # Rx chains when idling, depending on SMPS mode */ - switch (priv->current_ht_config.smps) { - case IEEE80211_SMPS_STATIC: - case IEEE80211_SMPS_DYNAMIC: - return IWL_NUM_IDLE_CHAINS_SINGLE; - case IEEE80211_SMPS_OFF: - return active_cnt; - default: - WARN(1, "invalid SMPS mode %d", - priv->current_ht_config.smps); - return active_cnt; - } -} - -/* up to 4 chains */ -static u8 iwl_count_chain_bitmap(u32 chain_bitmap) -{ - u8 res; - res = (chain_bitmap & BIT(0)) >> 0; - res += (chain_bitmap & BIT(1)) >> 1; - res += (chain_bitmap & BIT(2)) >> 2; - res += (chain_bitmap & BIT(3)) >> 3; - return res; -} - -/** - * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image - * - * Selects how many and which Rx receivers/antennas/chains to use. - * This should not be used for scan command ... it puts data in wrong place. - */ -void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - bool is_single = is_single_rx_stream(priv); - bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); - u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; - u32 active_chains; - u16 rx_chain; - - /* Tell uCode which antennas are actually connected. - * Before first association, we assume all antennas are connected. - * Just after first association, iwl_chain_noise_calibration() - * checks which antennas actually *are* connected. */ - if (priv->chain_noise_data.active_chains) - active_chains = priv->chain_noise_data.active_chains; - else - active_chains = priv->hw_params.valid_rx_ant; - - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - (priv->bt_full_concurrent || - priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { - /* - * only use chain 'A' in bt high traffic load or - * full concurrency mode - */ - active_chains = first_antenna(active_chains); - } - - rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; - - /* How many receivers should we use? */ - active_rx_cnt = iwl_get_active_rx_chain_count(priv); - idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); - - - /* correct rx chain count according hw settings - * and chain noise calibration - */ - valid_rx_cnt = iwl_count_chain_bitmap(active_chains); - if (valid_rx_cnt < active_rx_cnt) - active_rx_cnt = valid_rx_cnt; - - if (valid_rx_cnt < idle_rx_cnt) - idle_rx_cnt = valid_rx_cnt; - - rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; - rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; - - ctx->staging.rx_chain = cpu_to_le16(rx_chain); - - if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) - ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; - else - ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; - - IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", - ctx->staging.rx_chain, - active_rx_cnt, idle_rx_cnt); - - WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || - active_rx_cnt < idle_rx_cnt); -} -EXPORT_SYMBOL(iwl_set_rxon_chain); - /* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, enum ieee80211_band band) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 09908f604e28..50a3c26e1412 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -407,7 +407,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int hw_decrypt); int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, struct iwl_rxon_context *ctx); void iwl_set_flags_for_band(struct iwl_priv *priv, -- cgit v1.2.3 From 575ccfd0f47e5d791246cb03c07d636190322fa1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:01:59 +0200 Subject: iwlwifi: rename iwl_mac_beacon_update Rename iwl_mac_beacon_update to iwlcore_beacon_update and make the calling convention a bit different. The old name with _mac_ indicated that it was a mac80211 callback, but that's no longer true. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 35 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index dd7c3cbd2f6b..71f245f3f0f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1617,25 +1617,25 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv, iwlcore_commit_rxon(priv, ctx); } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) +static void iwlcore_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; unsigned long flags; __le64 timestamp; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); - IWL_DEBUG_MAC80211(priv, "enter\n"); + if (!skb) + return; + + IWL_DEBUG_ASSOC(priv, "enter\n"); lockdep_assert_held(&priv->mutex); if (!priv->beacon_ctx) { IWL_ERR(priv, "update beacon but no beacon context!\n"); dev_kfree_skb(skb); - return -EINVAL; - } - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; + return; } spin_lock_irqsave(&priv->lock, flags); @@ -1648,12 +1648,16 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; priv->timestamp = le64_to_cpu(timestamp); - IWL_DEBUG_MAC80211(priv, "leave\n"); + IWL_DEBUG_ASSOC(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); - priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return; + } - return 0; + priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); } void iwl_bss_info_changed(struct ieee80211_hw *hw, @@ -1735,13 +1739,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, * mac80211 decides to do both changes at once because * it will invoke post_associate. */ - if (vif->type == NL80211_IFTYPE_ADHOC && - changes & BSS_CHANGED_BEACON) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - - if (beacon) - iwl_mac_beacon_update(hw, beacon); - } + if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) + iwlcore_beacon_update(hw, vif); if (changes & BSS_CHANGED_ERP_PREAMBLE) { IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", -- cgit v1.2.3 From d3f5ba958d6c425a87535c6fa2a69ca90eb6e930 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:00 +0200 Subject: iwlwifi: remove verify_signature eeprom operation All drivers share the same implementation, so there's no need to call this via a function pointer nor to export it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-3945.c | 1 - drivers/net/wireless/iwlwifi/iwl-4965.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - 7 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 134f54541330..8c2db55df426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -209,7 +209,6 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index ef670879e359..a7dbb2806b1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2686,7 +2686,6 @@ static struct iwl_lib_ops iwl3945_lib = { EEPROM_REGULATORY_BAND_NO_HT40, EEPROM_REGULATORY_BAND_NO_HT40, }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, .release_semaphore = iwl3945_eeprom_release_semaphore, .query_addr = iwlcore_eeprom_query_addr, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 20626c997b4e..08d2dbc4efb3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2280,7 +2280,6 @@ static struct iwl_lib_ops iwl4965_lib = { EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwl4965_eeprom_calib_version, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1b25ad63b5c1..ddbbb9320aca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -384,7 +384,6 @@ static struct iwl_lib_ops iwl5000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -456,7 +455,6 @@ static struct iwl_lib_ops iwl5150_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 6261aec5ebdc..198cd8f40de3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -323,7 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -398,7 +397,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 88f4a80d4733..bd51b06288eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -214,7 +214,7 @@ static const struct iwl_txpwr_section enhinfo[] = { * ******************************************************************************/ -int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) +static int iwl_eeprom_verify_signature(struct iwl_priv *priv) { u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; int ret = 0; @@ -246,7 +246,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) } return ret; } -EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) { @@ -523,7 +522,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.init(priv); - ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); + ret = iwl_eeprom_verify_signature(priv); if (ret < 0) { IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); ret = -ENOENT; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index a4772aff51fe..2ae0a11e523b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info { struct iwl_eeprom_ops { const u32 regulatory_bands[7]; - int (*verify_signature) (struct iwl_priv *priv); int (*acquire_semaphore) (struct iwl_priv *priv); void (*release_semaphore) (struct iwl_priv *priv); u16 (*calib_version) (struct iwl_priv *priv); -- cgit v1.2.3 From a30e3112a8bcb5bc1caa48547e597de3992e1b21 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:01 +0200 Subject: iwlwifi: move agn specific station code there By duplicating a little bit of code between 3945 and agn, we can move a lot of code into an agn specific station management file and thus reduce the amount of code in core that is dead to 3945. before: text data bss dec hex filename 212886 3872 96 216854 34f16 iwlcore.ko 620542 10448 304 631294 9a1fe iwlagn.ko 314013 3264 196 317473 4d821 iwl3945.ko after: text data bss dec hex filename 202857 3872 92 206821 327e5 iwlcore.ko 629102 10448 308 639858 9c372 iwlagn.ko 314240 3264 196 317700 4d904 iwl3945.ko delta: -10029 iwlcore.ko 8560 iwlagn.ko 227 iwl3945.ko so it's a net win even if you have both loaded, likely because a lot of EXPORT_SYMBOLs go away. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 32 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 716 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 31 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 - drivers/net/wireless/iwlwifi/iwl-sta.c | 725 +--------------------------- drivers/net/wireless/iwlwifi/iwl-sta.h | 35 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 25 +- 11 files changed, 823 insertions(+), 754 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-sta.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 493163925a45..b4b24b67892c 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o -iwlagn-objs += iwl-agn-tt.o +iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a7dbb2806b1a..4b3eb785dcb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2299,6 +2299,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) return (u16)sizeof(struct iwl3945_addsta_cmd); } +static int iwl3945_add_bssid_station(struct iwl_priv *priv, + const u8 *addr, u8 *sta_id_r) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int ret; + u8 sta_id; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} static int iwl3945_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add) { @@ -2306,10 +2332,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv, int ret; if (add) { - ret = iwl_add_bssid_station( - priv, &priv->contexts[IWL_RXON_CTX_BSS], - vif->bss_conf.bssid, false, - &vif_priv->ibss_bssid_sta_id); + ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0b45bced9c0c..3eeab0a99def 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1587,9 +1587,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; if (add) - return iwl_add_bssid_station(priv, vif_priv->ctx, - vif->bss_conf.bssid, true, - &vif_priv->ibss_bssid_sta_id); + return iwlagn_add_bssid_station(priv, vif_priv->ctx, + vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index f865685fd5f5..7e5cf1a2b21e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -39,6 +39,7 @@ #include "iwl-dev.h" #include "iwl-sta.h" #include "iwl-core.h" +#include "iwl-agn.h" #define RS_NAME "iwl-agn-rs" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c new file mode 100644 index 000000000000..35a30d2e0734 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -0,0 +1,716 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-agn.h" + +static struct iwl_link_quality_cmd * +iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) +{ + int i, r; + struct iwl_link_quality_cmd *link_cmd; + u32 rate_flags = 0; + __le32 rate_n_flags; + + link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); + if (!link_cmd) { + IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); + return NULL; + } + /* Set up the rate scaling to start at selected rate, fall back + * all the way down to 1M in IEEE order, and then spin on 1M */ + if (priv->band == IEEE80211_BAND_5GHZ) + r = IWL_RATE_6M_INDEX; + else + r = IWL_RATE_1M_INDEX; + + if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) + rate_flags |= RATE_MCS_CCK_MSK; + + rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << + RATE_MCS_ANT_POS; + rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) + link_cmd->rs_table[i].rate_n_flags = rate_n_flags; + + link_cmd->general_params.single_stream_ant_msk = + first_antenna(priv->hw_params.valid_tx_ant); + + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant & + ~first_antenna(priv->hw_params.valid_tx_ant); + if (!link_cmd->general_params.dual_stream_ant_msk) { + link_cmd->general_params.dual_stream_ant_msk = ANT_AB; + } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant; + } + + link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + link_cmd->agg_params.agg_time_limit = + cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + + link_cmd->sta_id = sta_id; + + return link_cmd; +} + +/* + * iwlagn_add_bssid_station - Add the special IBSS BSSID station + * + * Function sleeps. + */ +int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r) +{ + int ret; + u8 sta_id; + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + /* Set up default rate scaling table in device's station table */ + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", + addr); + return -ENOMEM; + } + + ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true); + if (ret) + IWL_ERR(priv, "Link quality command failed (%d)\n", ret); + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + bool send_if_empty) +{ + int i, not_empty = 0; + u8 buff[sizeof(struct iwl_wep_cmd) + + sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; + struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; + size_t cmd_size = sizeof(struct iwl_wep_cmd); + struct iwl_host_cmd cmd = { + .id = ctx->wep_key_cmd, + .data = wep_cmd, + .flags = CMD_SYNC, + }; + + might_sleep(); + + memset(wep_cmd, 0, cmd_size + + (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); + + for (i = 0; i < WEP_KEYS_MAX ; i++) { + wep_cmd->key[i].key_index = i; + if (ctx->wep_keys[i].key_size) { + wep_cmd->key[i].key_offset = i; + not_empty = 1; + } else { + wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; + } + + wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; + memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, + ctx->wep_keys[i].key_size); + } + + wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; + wep_cmd->num_keys = WEP_KEYS_MAX; + + cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; + + cmd.len = cmd_size; + + if (not_empty || send_if_empty) + return iwl_send_cmd(priv, &cmd); + else + return 0; +} + +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + lockdep_assert_held(&priv->mutex); + + return iwl_send_static_wepkey_cmd(priv, ctx, false); +} + +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", + keyconf->keyidx); + + memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); + /* but keys in device are clear anyway so return success */ + return 0; + } + ret = iwl_send_static_wepkey_cmd(priv, ctx, 1); + IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", + keyconf->keyidx, ret); + + return ret; +} + +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (keyconf->keylen != WEP_KEY_LEN_128 && + keyconf->keylen != WEP_KEY_LEN_64) { + IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); + return -EINVAL; + } + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = HW_KEY_DEFAULT; + priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; + + ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; + memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, + keyconf->keylen); + + ret = iwl_send_static_wepkey_cmd(priv, ctx, false); + IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", + keyconf->keylen, keyconf->keyidx, ret); + + return ret; +} + +static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + + key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (keyconf->keylen == WEP_KEY_LEN_128) + key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; + + memcpy(priv->stations[sta_id].keyinfo.key, + keyconf->key, keyconf->keylen); + + memcpy(&priv->stations[sta_id].sta.key.key[3], + keyconf->key, keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + int ret = 0; + __le16 key_flags = 0; + + key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = 16; + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + + + /* This copy is acutally not needed: we get the key with each TX */ + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +void iwl_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) +{ + u8 sta_id; + unsigned long flags; + int i; + + if (iwl_scan_cancel(priv)) { + /* cancel scan failed, just live w/ bad key and rely + briefly on SW decryption */ + return; + } + + sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta); + if (sta_id == IWL_INVALID_STATION) + return; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; + + for (i = 0; i < 5; i++) + priv->stations[sta_id].sta.key.tkip_rx_ttak[i] = + cpu_to_le16(phase1key[i]); + + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} + +int iwl_remove_dynamic_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + u16 key_flags; + u8 keyidx; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys--; + + spin_lock_irqsave(&priv->sta_lock, flags); + key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); + keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; + + IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", + keyconf->keyidx, sta_id); + + if (keyconf->keyidx != keyidx) { + /* We need to remove a key with index different that the one + * in the uCode. This means that the key we need to remove has + * been replaced by another one with different index. + * Don't do anything and return ok + */ + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { + IWL_WARN(priv, "Removing wrong key %d 0x%x\n", + keyconf->keyidx, key_flags); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, + &priv->ucode_key_table)) + IWL_ERR(priv, "index %d not used in uCode key table.\n", + priv->stations[sta_id].sta.key.key_offset); + memset(&priv->stations[sta_id].keyinfo, 0, + sizeof(struct iwl_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = + STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; + priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, u8 sta_id) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys++; + keyconf->hw_key_idx = HW_KEY_DYNAMIC; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_TKIP: + ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + default: + IWL_ERR(priv, + "Unknown alg: %s cipher = %x\n", __func__, + keyconf->cipher); + ret = -EINVAL; + } + + IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, + sta_id, ret); + + return ret; +} + +/** + * iwlagn_alloc_bcast_station - add broadcast station into driver's station table. + * + * This adds the broadcast station into the driver's station table + * and marks it driver active, so that it will be restored to the + * device at the next best time. + */ +int iwlagn_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, + "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +/** + * iwl_update_bcast_station - update broadcast station's LQ command + * + * Only used by iwlagn. Placed here to have all bcast station management + * code together. + */ +static int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + unsigned long flags; + struct iwl_link_quality_cmd *link_cmd; + u8 sta_id = ctx->bcast_sta_id; + + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (priv->stations[sta_id].lq) + kfree(priv->stations[sta_id].lq); + else + IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +int iwl_update_bcast_stations(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + int ret = 0; + + for_each_context(priv, ctx) { + ret = iwl_update_bcast_station(priv, ctx); + if (ret) + break; + } + + return ret; +} + +/** + * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table + */ +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) +{ + unsigned long flags; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + /* Remove "disable" flag, to enable Tx for this TID */ + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; + priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn) +{ + unsigned long flags; + int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) + return -ENXIO; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; + priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid) +{ + unsigned long flags; + int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); + return -ENXIO; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; + priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.sta.modify_mask = 0; + priv->stations[sta_id].sta.sleep_tx_count = 0; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} + +void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.sta.modify_mask = + STA_MODIFY_SLEEP_TX_COUNT_MSK; + priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b59ce92730c7..8233c6410411 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3089,7 +3089,7 @@ static int __iwl_up(struct iwl_priv *priv) } for_each_context(priv, ctx) { - ret = iwl_alloc_bcast_station(priv, ctx, true); + ret = iwlagn_alloc_bcast_station(priv, ctx); if (ret) { iwl_dealloc_bcast_stations(priv); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5d5cacb54eb7..632ea4ba82bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -252,4 +252,35 @@ const char *iwl_get_agg_tx_fail_reason(u16 status); #else static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } #endif + +/* station management */ +int iwlagn_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r); +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +void iwl_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); +int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn); +int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid); +void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); +void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); +int iwl_update_bcast_stations(struct iwl_priv *priv); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 50a3c26e1412..31ec9db58b26 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -750,8 +750,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); -extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - struct iwl_link_quality_cmd *lq, u8 flags, bool init); void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 6edd0341dfe2..7c7f7dcb1b1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -228,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, * * should be called with sta_lock held */ -static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - const u8 *addr, bool is_ap, - struct ieee80211_sta *sta) +u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta *sta) { struct iwl_station_entry *station; int i; @@ -317,6 +316,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return sta_id; } +EXPORT_SYMBOL_GPL(iwl_prep_station); #define STA_WAIT_TIMEOUT (HZ/2) @@ -381,108 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } EXPORT_SYMBOL(iwl_add_station_common); -static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv, - u8 sta_id) -{ - int i, r; - struct iwl_link_quality_cmd *link_cmd; - u32 rate_flags = 0; - __le32 rate_n_flags; - - link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); - if (!link_cmd) { - IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); - return NULL; - } - /* Set up the rate scaling to start at selected rate, fall back - * all the way down to 1M in IEEE order, and then spin on 1M */ - if (priv->band == IEEE80211_BAND_5GHZ) - r = IWL_RATE_6M_INDEX; - else - r = IWL_RATE_1M_INDEX; - - if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) - rate_flags |= RATE_MCS_CCK_MSK; - - rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << - RATE_MCS_ANT_POS; - rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) - link_cmd->rs_table[i].rate_n_flags = rate_n_flags; - - link_cmd->general_params.single_stream_ant_msk = - first_antenna(priv->hw_params.valid_tx_ant); - - link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant & - ~first_antenna(priv->hw_params.valid_tx_ant); - if (!link_cmd->general_params.dual_stream_ant_msk) { - link_cmd->general_params.dual_stream_ant_msk = ANT_AB; - } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { - link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant; - } - - link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; - link_cmd->agg_params.agg_time_limit = - cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); - - link_cmd->sta_id = sta_id; - - return link_cmd; -} - -/* - * iwl_add_bssid_station - Add the special IBSS BSSID station - * - * Function sleeps. - */ -int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - const u8 *addr, bool init_rs, u8 *sta_id_r) -{ - int ret; - u8 sta_id; - struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; - - if (sta_id_r) - *sta_id_r = IWL_INVALID_STATION; - - ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM\n", addr); - return ret; - } - - if (sta_id_r) - *sta_id_r = sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - if (init_rs) { - /* Set up default rate scaling table in device's station table */ - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", - addr); - return -ENOMEM; - } - - ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true); - if (ret) - IWL_ERR(priv, "Link quality command failed (%d)\n", ret); - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - } - - return 0; -} -EXPORT_SYMBOL(iwl_add_bssid_station); - /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station * @@ -738,405 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_get_free_ucode_key_index); -static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - bool send_if_empty) -{ - int i, not_empty = 0; - u8 buff[sizeof(struct iwl_wep_cmd) + - sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; - struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; - size_t cmd_size = sizeof(struct iwl_wep_cmd); - struct iwl_host_cmd cmd = { - .id = ctx->wep_key_cmd, - .data = wep_cmd, - .flags = CMD_SYNC, - }; - - might_sleep(); - - memset(wep_cmd, 0, cmd_size + - (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); - - for (i = 0; i < WEP_KEYS_MAX ; i++) { - wep_cmd->key[i].key_index = i; - if (ctx->wep_keys[i].key_size) { - wep_cmd->key[i].key_offset = i; - not_empty = 1; - } else { - wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; - } - - wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; - memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, - ctx->wep_keys[i].key_size); - } - - wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; - wep_cmd->num_keys = WEP_KEYS_MAX; - - cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; - - cmd.len = cmd_size; - - if (not_empty || send_if_empty) - return iwl_send_cmd(priv, &cmd); - else - return 0; -} - -int iwl_restore_default_wep_keys(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - lockdep_assert_held(&priv->mutex); - - return iwl_send_static_wepkey_cmd(priv, ctx, false); -} -EXPORT_SYMBOL(iwl_restore_default_wep_keys); - -int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf) -{ - int ret; - - lockdep_assert_held(&priv->mutex); - - IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", - keyconf->keyidx); - - memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); - /* but keys in device are clear anyway so return success */ - return 0; - } - ret = iwl_send_static_wepkey_cmd(priv, ctx, 1); - IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", - keyconf->keyidx, ret); - - return ret; -} -EXPORT_SYMBOL(iwl_remove_default_wep_key); - -int iwl_set_default_wep_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf) -{ - int ret; - - lockdep_assert_held(&priv->mutex); - - if (keyconf->keylen != WEP_KEY_LEN_128 && - keyconf->keylen != WEP_KEY_LEN_64) { - IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); - return -EINVAL; - } - - keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->hw_key_idx = HW_KEY_DEFAULT; - priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; - - ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; - memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, - keyconf->keylen); - - ret = iwl_send_static_wepkey_cmd(priv, ctx, false); - IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", - keyconf->keylen, keyconf->keyidx, ret); - - return ret; -} -EXPORT_SYMBOL(iwl_set_default_wep_key); - -static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; - - key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (keyconf->keylen == WEP_KEY_LEN_128) - key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; - - if (sta_id == ctx->bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; - - memcpy(priv->stations[sta_id].keyinfo.key, - keyconf->key, keyconf->keylen); - - memcpy(&priv->stations[sta_id].sta.key.key[3], - keyconf->key, keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (sta_id == ctx->bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, - keyconf->keylen); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, - keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - int ret = 0; - __le16 key_flags = 0; - - key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (sta_id == ctx->bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; - priv->stations[sta_id].keyinfo.keylen = 16; - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - - - /* This copy is acutally not needed: we get the key with each TX */ - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return ret; -} - -void iwl_update_tkip_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) +void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { - u8 sta_id; unsigned long flags; int i; - if (iwl_scan_cancel(priv)) { - /* cancel scan failed, just live w/ bad key and rely - briefly on SW decryption */ - return; - } - - sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta); - if (sta_id == IWL_INVALID_STATION) - return; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; - - for (i = 0; i < 5; i++) - priv->stations[sta_id].sta.key.tkip_rx_ttak[i] = - cpu_to_le16(phase1key[i]); - - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_update_tkip_key); - -int iwl_remove_dynamic_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - u16 key_flags; - u8 keyidx; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - ctx->key_mapping_keys--; - spin_lock_irqsave(&priv->sta_lock, flags); - key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); - keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; - - IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", - keyconf->keyidx, sta_id); - - if (keyconf->keyidx != keyidx) { - /* We need to remove a key with index different that the one - * in the uCode. This means that the key we need to remove has - * been replaced by another one with different index. - * Don't do anything and return ok - */ - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } - - if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { - IWL_WARN(priv, "Removing wrong key %d 0x%x\n", - keyconf->keyidx, key_flags); - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } + for (i = 0; i < priv->hw_params.max_stations; i++) { + if (!(priv->stations[i].used & IWL_STA_BCAST)) + continue; - if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, - &priv->ucode_key_table)) - IWL_ERR(priv, "index %d not used in uCode key table.\n", - priv->stations[sta_id].sta.key.key_offset); - memset(&priv->stations[sta_id].keyinfo, 0, - sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, - sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = - STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; - priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; + priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; + priv->num_stations--; + BUG_ON(priv->num_stations < 0); + kfree(priv->stations[i].lq); + priv->stations[i].lq = NULL; } - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_remove_dynamic_key); - -int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, u8 sta_id) -{ - int ret; - - lockdep_assert_held(&priv->mutex); - - ctx->key_mapping_keys++; - keyconf->hw_key_idx = HW_KEY_DYNAMIC; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_TKIP: - ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id); - break; - default: - IWL_ERR(priv, - "Unknown alg: %s cipher = %x\n", __func__, - keyconf->cipher); - ret = -EINVAL; - } - - IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n", - keyconf->cipher, keyconf->keylen, keyconf->keyidx, - sta_id, ret); - - return ret; } -EXPORT_SYMBOL(iwl_set_dynamic_key); +EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, @@ -1240,223 +758,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } EXPORT_SYMBOL(iwl_send_lq_cmd); -/** - * iwl_alloc_bcast_station - add broadcast station into driver's station table. - * - * This adds the broadcast station into the driver's station table - * and marks it driver active, so that it will be restored to the - * device at the next best time. - */ -int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - bool init_lq) -{ - struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; - u8 sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return -EINVAL; - } - - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - if (init_lq) { - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, - "Unable to initialize rate scaling for bcast station.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - } - - return 0; -} -EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); - -/** - * iwl_update_bcast_station - update broadcast station's LQ command - * - * Only used by iwlagn. Placed here to have all bcast station management - * code together. - */ -static int iwl_update_bcast_station(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - unsigned long flags; - struct iwl_link_quality_cmd *link_cmd; - u8 sta_id = ctx->bcast_sta_id; - - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - if (priv->stations[sta_id].lq) - kfree(priv->stations[sta_id].lq); - else - IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} - -int iwl_update_bcast_stations(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx; - int ret = 0; - - for_each_context(priv, ctx) { - ret = iwl_update_bcast_station(priv, ctx); - if (ret) - break; - } - - return ret; -} -EXPORT_SYMBOL_GPL(iwl_update_bcast_stations); - -void iwl_dealloc_bcast_stations(struct iwl_priv *priv) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&priv->sta_lock, flags); - for (i = 0; i < priv->hw_params.max_stations; i++) { - if (!(priv->stations[i].used & IWL_STA_BCAST)) - continue; - - priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; - priv->num_stations--; - BUG_ON(priv->num_stations < 0); - kfree(priv->stations[i].lq); - priv->stations[i].lq = NULL; - } - spin_unlock_irqrestore(&priv->sta_lock, flags); -} -EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); - -/** - * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table - */ -int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) -{ - unsigned long flags; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - /* Remove "disable" flag, to enable Tx for this TID */ - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; - priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); - -int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid, u16 ssn) -{ - unsigned long flags; - int sta_id; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - sta_id = iwl_sta_id(sta); - if (sta_id == IWL_INVALID_STATION) - return -ENXIO; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags_msk = 0; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; - priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; - priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_rx_agg_start); - -int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid) -{ - unsigned long flags; - int sta_id; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - sta_id = iwl_sta_id(sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); - return -ENXIO; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags_msk = 0; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; - priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_rx_agg_stop); - -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = 0; - priv->stations[sta_id].sta.sleep_tx_count = 0; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_sta_modify_ps_wake); - -void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = - STA_MODIFY_SLEEP_TX_COUNT_MSK; - priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); - int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 56bad3f60d81..06475872eee4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -43,35 +43,13 @@ #define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */ -int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *key); -int iwl_set_default_wep_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *key); -int iwl_restore_default_wep_keys(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); -int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *key, u8 sta_id); -int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *key, u8 sta_id); -void iwl_update_tkip_key(struct iwl_priv *priv, - struct iwl_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); - void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx); void iwl_clear_ucode_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - bool init_lq); void iwl_dealloc_bcast_stations(struct iwl_priv *priv); -int iwl_update_bcast_stations(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags); -int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, - const u8 *addr, bool init_rs, u8 *sta_id_r); int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, struct ieee80211_sta *sta, u8 *sta_id_r); @@ -79,13 +57,12 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); -int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid, u16 ssn); -int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid); -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); -void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); + +u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta *sta); + +int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct iwl_link_quality_cmd *lq, u8 flags, bool init); /** * iwl_clear_driver_stations - clear knowledge of all stations from driver diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 64eb049140dc..c06b2189e09e 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2661,12 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv) #define MAX_HW_RESTARTS 5 +static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + static int __iwl3945_up(struct iwl_priv *priv) { int rc, i; - rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS], - false); + rc = iwl3945_alloc_bcast_station(priv); if (rc) return rc; -- cgit v1.2.3 From 69fdb710b29d096bc50123f7c97891e31ffe45f9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:02 +0200 Subject: iwlwifi: move tx fail code to agn The code to print out TX failure reasons is AGN specific, so it can be in the AGN module. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 40 +++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 3 --- drivers/net/wireless/iwlwifi/iwl-tx.c | 38 ----------------------------- 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 77753b72f236..db57aea629d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1391,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); } + +#ifdef CONFIG_IWLWIFI_DEBUG +const char *iwl_get_tx_fail_reason(u32 status) +{ +#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x +#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x + + switch (status & TX_STATUS_MSK) { + case TX_STATUS_SUCCESS: + return "SUCCESS"; + TX_STATUS_POSTPONE(DELAY); + TX_STATUS_POSTPONE(FEW_BYTES); + TX_STATUS_POSTPONE(BT_PRIO); + TX_STATUS_POSTPONE(QUIET_PERIOD); + TX_STATUS_POSTPONE(CALC_TTAK); + TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); + TX_STATUS_FAIL(SHORT_LIMIT); + TX_STATUS_FAIL(LONG_LIMIT); + TX_STATUS_FAIL(FIFO_UNDERRUN); + TX_STATUS_FAIL(DRAIN_FLOW); + TX_STATUS_FAIL(RFKILL_FLUSH); + TX_STATUS_FAIL(LIFE_EXPIRE); + TX_STATUS_FAIL(DEST_PS); + TX_STATUS_FAIL(HOST_ABORTED); + TX_STATUS_FAIL(BT_RETRY); + TX_STATUS_FAIL(STA_INVALID); + TX_STATUS_FAIL(FRAG_DROPPED); + TX_STATUS_FAIL(TID_DISABLE); + TX_STATUS_FAIL(FIFO_FLUSHED); + TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); + TX_STATUS_FAIL(PASSIVE_NO_RX); + TX_STATUS_FAIL(NO_BEACON_ON_RADAR); + } + + return "UNKNOWN"; + +#undef TX_STATUS_FAIL +#undef TX_STATUS_POSTPONE +} +#endif /* CONFIG_IWLWIFI_DEBUG */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 632ea4ba82bb..d6645ec9ec5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -248,8 +248,10 @@ void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUG +const char *iwl_get_tx_fail_reason(u32 status); const char *iwl_get_agg_tx_fail_reason(u16 status); #else +static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 90a37a94c698..2b04714c3a9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1566,7 +1566,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id) } #ifdef CONFIG_IWLWIFI_DEBUG -const char *iwl_get_tx_fail_reason(u32 status); /* * iwl_get_debug_level: Return active debug level for device * @@ -1582,8 +1581,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv) return iwl_debug_level; } #else -static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } - static inline u32 iwl_get_debug_level(struct iwl_priv *priv) { return iwl_debug_level; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 3290b1552f5a..7261ee49f282 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -636,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) meta->flags = 0; } EXPORT_SYMBOL(iwl_tx_cmd_complete); - -#ifdef CONFIG_IWLWIFI_DEBUG -#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x -#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x - -const char *iwl_get_tx_fail_reason(u32 status) -{ - switch (status & TX_STATUS_MSK) { - case TX_STATUS_SUCCESS: - return "SUCCESS"; - TX_STATUS_POSTPONE(DELAY); - TX_STATUS_POSTPONE(FEW_BYTES); - TX_STATUS_POSTPONE(BT_PRIO); - TX_STATUS_POSTPONE(QUIET_PERIOD); - TX_STATUS_POSTPONE(CALC_TTAK); - TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); - TX_STATUS_FAIL(SHORT_LIMIT); - TX_STATUS_FAIL(LONG_LIMIT); - TX_STATUS_FAIL(FIFO_UNDERRUN); - TX_STATUS_FAIL(DRAIN_FLOW); - TX_STATUS_FAIL(RFKILL_FLUSH); - TX_STATUS_FAIL(LIFE_EXPIRE); - TX_STATUS_FAIL(DEST_PS); - TX_STATUS_FAIL(HOST_ABORTED); - TX_STATUS_FAIL(BT_RETRY); - TX_STATUS_FAIL(STA_INVALID); - TX_STATUS_FAIL(FRAG_DROPPED); - TX_STATUS_FAIL(TID_DISABLE); - TX_STATUS_FAIL(FIFO_FLUSHED); - TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); - TX_STATUS_FAIL(PASSIVE_NO_RX); - TX_STATUS_FAIL(NO_BEACON_ON_RADAR); - } - - return "UNKNOWN"; -} -EXPORT_SYMBOL(iwl_get_tx_fail_reason); -#endif /* CONFIG_IWLWIFI_DEBUG */ -- cgit v1.2.3 From 57934dc1fb7ef65a8a0f5d7a1578536b36043c0a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:03 +0200 Subject: iwlwifi: remove spurious exports A number of exports, especially related to thermal throttling, are unnecessary because the code lives in the same module that it is used in, so remove them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-core.c | 1 - drivers/net/wireless/iwlwifi/iwl-scan.c | 1 - 3 files changed, 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 0c6c4d969706..e3a8216a033c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -571,7 +571,6 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); queue_work(priv->workqueue, &priv->ct_enter); } -EXPORT_SYMBOL(iwl_tt_enter_ct_kill); void iwl_tt_exit_ct_kill(struct iwl_priv *priv) { @@ -581,7 +580,6 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv) IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); queue_work(priv->workqueue, &priv->ct_exit); } -EXPORT_SYMBOL(iwl_tt_exit_ct_kill); static void iwl_bg_tt_work(struct work_struct *work) { @@ -608,7 +606,6 @@ void iwl_tt_handler(struct iwl_priv *priv) IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); queue_work(priv->workqueue, &priv->tt_work); } -EXPORT_SYMBOL(iwl_tt_handler); /* Thermal throttling initialization * For advance thermal throttling: @@ -678,7 +675,6 @@ void iwl_tt_initialize(struct iwl_priv *priv) priv->thermal_throttle.advanced_tt = false; } } -EXPORT_SYMBOL(iwl_tt_initialize); /* cleanup thermal throttling management related memory and timer */ void iwl_tt_exit(struct iwl_priv *priv) @@ -701,4 +697,3 @@ void iwl_tt_exit(struct iwl_priv *priv) tt->transaction = NULL; } } -EXPORT_SYMBOL(iwl_tt_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 71f245f3f0f6..eefcb2d1a738 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2653,7 +2653,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) } return 0; } -EXPORT_SYMBOL(iwl_force_reset); /** * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a7e8c7f969f4..67da31295781 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -121,7 +121,6 @@ void iwl_force_scan_end(struct iwl_priv *priv) clear_bit(STATUS_SCAN_ABORTING, &priv->status); iwl_complete_scan(priv, true); } -EXPORT_SYMBOL(iwl_force_scan_end); static void iwl_do_scan_abort(struct iwl_priv *priv) { -- cgit v1.2.3 From 635b85b42796a6ab4e6a31cde78f1d9660c9c4a0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:04 +0200 Subject: iwlwifi: remove agn rates info there Code and data related to agn bitrates can be part of the agn module rather than being in the core module. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 9 ++++ drivers/net/wireless/iwlwifi/iwl-3945.h | 5 ++- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 68 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 10 ----- drivers/net/wireless/iwlwifi/iwl-core.c | 70 ------------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 2 - 6 files changed, 80 insertions(+), 84 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 4b3eb785dcb2..ba3ab04c1fba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ }; +static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) +{ + u8 rate = iwl3945_rates[rate_index].prev_ieee; + + if (rate == IWL_RATE_INVALID) + rate = rate_index; + return rate; +} + /* 1 = enable the iwl3945_disable_events() function */ #define IWL_EVT_DISABLE (0) #define IWL_EVT_DISABLE_SIZE (1532/32) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 77e8e1970350..09391f0ee61f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -138,8 +138,6 @@ enum iwl3945_antenna { #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -#include "iwl-agn-rs.h" - #define IWL_TX_FIFO_AC0 0 #define IWL_TX_FIFO_AC1 1 #define IWL_TX_FIFO_AC2 2 @@ -301,6 +299,9 @@ extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwl3945_post_scan(struct iwl_priv *priv); +/* rates */ +extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; + /* Requires full declaration of iwl_priv before including */ #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 7e5cf1a2b21e..5abe2e9ff0d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -77,6 +77,74 @@ static const u8 ant_toggle_lookup[] = { /*ANT_ABC -> */ ANT_ABC, }; +#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_SISO_##s##M_PLCP, \ + IWL_RATE_MIMO2_##s##M_PLCP,\ + IWL_RATE_MIMO3_##s##M_PLCP,\ + IWL_RATE_##r##M_IEEE, \ + IWL_RATE_##ip##M_INDEX, \ + IWL_RATE_##in##M_INDEX, \ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX, \ + IWL_RATE_##pp##M_INDEX, \ + IWL_RATE_##np##M_INDEX } + +/* + * Parameter order: + * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ + IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ + /* FIXME:RS: ^^ should be INV (legacy) */ +}; + +static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + /* HT rate format */ + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = (rate_n_flags & 0xff); + + if (idx >= IWL_RATE_MIMO3_6M_PLCP) + idx = idx - IWL_RATE_MIMO3_6M_PLCP; + else if (idx >= IWL_RATE_MIMO2_6M_PLCP) + idx = idx - IWL_RATE_MIMO2_6M_PLCP; + + idx += IWL_FIRST_OFDM_RATE; + /* skip 9M not supported in ht*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) + return idx; + + /* legacy rate format, search for match in table */ + } else { + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + return idx; + } + + return -1; +} + static void rs_rate_scale_perform(struct iwl_priv *priv, struct sk_buff *skb, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 357cdb26f16d..75e50d33ecb3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -299,7 +299,6 @@ enum { #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; -extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; enum iwl_table_type { LQ_NONE, @@ -453,15 +452,6 @@ static inline u8 first_antenna(u8 mask) } -static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl3945_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - /** * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index eefcb2d1a738..295038450a01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -69,79 +69,9 @@ EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); -#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ - [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ - IWL_RATE_SISO_##s##M_PLCP, \ - IWL_RATE_MIMO2_##s##M_PLCP,\ - IWL_RATE_MIMO3_##s##M_PLCP,\ - IWL_RATE_##r##M_IEEE, \ - IWL_RATE_##ip##M_INDEX, \ - IWL_RATE_##in##M_INDEX, \ - IWL_RATE_##rp##M_INDEX, \ - IWL_RATE_##rn##M_INDEX, \ - IWL_RATE_##pp##M_INDEX, \ - IWL_RATE_##np##M_INDEX } - u32 iwl_debug_level; EXPORT_SYMBOL(iwl_debug_level); -/* - * Parameter order: - * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate - * - * If there isn't a valid next or previous rate then INV is used which - * maps to IWL_RATE_INVALID - * - */ -const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { - IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ - IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ - IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ - IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ - IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ - IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ - IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ - IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ - IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ - IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ - IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ - IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ - IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ - /* FIXME:RS: ^^ should be INV (legacy) */ -}; -EXPORT_SYMBOL(iwl_rates); - -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) -{ - int idx = 0; - - /* HT rate format */ - if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = (rate_n_flags & 0xff); - - if (idx >= IWL_RATE_MIMO3_6M_PLCP) - idx = idx - IWL_RATE_MIMO3_6M_PLCP; - else if (idx >= IWL_RATE_MIMO2_6M_PLCP) - idx = idx - IWL_RATE_MIMO2_6M_PLCP; - - idx += IWL_FIRST_OFDM_RATE; - /* skip 9M not supported in ht*/ - if (idx >= IWL_RATE_9M_INDEX) - idx += 1; - if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) - return idx; - - /* legacy rate format, search for match in table */ - } else { - for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) - return idx; - } - - return -1; -} -EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); - u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) { int i; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 31ec9db58b26..56251de85100 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -547,8 +547,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); * Rate ******************************************************************************/ -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); - u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -- cgit v1.2.3 From facd982e8246ed25a049d270a71513fb11b901ec Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:05 +0200 Subject: iwlwifi: move iwl_toggle_rx_ant to agn The iwl_toggle_tx_ant function is only used by agn code, so it can be moved into the agn module instead of being exported from the core. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 17 +++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-core.c | 18 ------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3eeab0a99def..9f1c93bbb01c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2205,3 +2205,20 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || active_rx_cnt < idle_rx_cnt); } + +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) +{ + int i; + u8 ind = ant; + + if (priv->band == IEEE80211_BAND_2GHZ && + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) + return 0; + + for (i = 0; i < RATE_ANT_NUM - 1; i++) { + ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; + if (valid & BIT(ind)) + return ind; + } + return ant; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d6645ec9ec5b..cc7a3b56cfe5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -216,6 +216,8 @@ static inline bool iwl_is_tx_success(u32 status) (status == TX_STATUS_DIRECT_DONE); } +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); + /* rx */ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 295038450a01..88c1ed5b7dd7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -72,24 +72,6 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); u32 iwl_debug_level; EXPORT_SYMBOL(iwl_debug_level); -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) -{ - int i; - u8 ind = ant; - - if (priv->band == IEEE80211_BAND_2GHZ && - priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) - return 0; - - for (i = 0; i < RATE_ANT_NUM - 1; i++) { - ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; - if (valid & BIT(ind)) - return ind; - } - return ant; -} -EXPORT_SYMBOL(iwl_toggle_tx_ant); - const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EXPORT_SYMBOL(iwl_bcast_addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 56251de85100..0bc7b7a28a30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -550,8 +550,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); - static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) { return BIT(ant_idx) << RATE_MCS_ANT_POS; -- cgit v1.2.3 From fed732920bf9d96a95804a499ca586ff745540cd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:06 +0200 Subject: iwlwifi: move iwl_dump_csr to agn The iwl_dump_csr function is only used within the agn module, so it can be moved there instead of being exported by the core. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 69 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 71 ------------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 4 files changed, 70 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9f1c93bbb01c..de91ff6dcd6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2222,3 +2222,72 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) } return ant; } + +static const char *get_csr_string(int cmd) +{ + switch (cmd) { + IWL_CMD(CSR_HW_IF_CONFIG_REG); + IWL_CMD(CSR_INT_COALESCING); + IWL_CMD(CSR_INT); + IWL_CMD(CSR_INT_MASK); + IWL_CMD(CSR_FH_INT_STATUS); + IWL_CMD(CSR_GPIO_IN); + IWL_CMD(CSR_RESET); + IWL_CMD(CSR_GP_CNTRL); + IWL_CMD(CSR_HW_REV); + IWL_CMD(CSR_EEPROM_REG); + IWL_CMD(CSR_EEPROM_GP); + IWL_CMD(CSR_OTP_GP_REG); + IWL_CMD(CSR_GIO_REG); + IWL_CMD(CSR_GP_UCODE_REG); + IWL_CMD(CSR_GP_DRIVER_REG); + IWL_CMD(CSR_UCODE_DRV_GP1); + IWL_CMD(CSR_UCODE_DRV_GP2); + IWL_CMD(CSR_LED_REG); + IWL_CMD(CSR_DRAM_INT_TBL_REG); + IWL_CMD(CSR_GIO_CHICKEN_BITS); + IWL_CMD(CSR_ANA_PLL_CFG); + IWL_CMD(CSR_HW_REV_WA_REG); + IWL_CMD(CSR_DBG_HPET_MEM_REG); + default: + return "UNKNOWN"; + } +} + +void iwl_dump_csr(struct iwl_priv *priv) +{ + int i; + u32 csr_tbl[] = { + CSR_HW_IF_CONFIG_REG, + CSR_INT_COALESCING, + CSR_INT, + CSR_INT_MASK, + CSR_FH_INT_STATUS, + CSR_GPIO_IN, + CSR_RESET, + CSR_GP_CNTRL, + CSR_HW_REV, + CSR_EEPROM_REG, + CSR_EEPROM_GP, + CSR_OTP_GP_REG, + CSR_GIO_REG, + CSR_GP_UCODE_REG, + CSR_GP_DRIVER_REG, + CSR_UCODE_DRV_GP1, + CSR_UCODE_DRV_GP2, + CSR_LED_REG, + CSR_DRAM_INT_TBL_REG, + CSR_GIO_CHICKEN_BITS, + CSR_ANA_PLL_CFG, + CSR_HW_REV_WA_REG, + CSR_DBG_HPET_MEM_REG + }; + IWL_ERR(priv, "CSR values:\n"); + IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is " + "CSR_INT_PERIODIC_REG)\n"); + for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { + IWL_ERR(priv, " %25s: 0X%08x\n", + get_csr_string(csr_tbl[i]), + iwl_read32(priv, csr_tbl[i])); + } +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cc7a3b56cfe5..5458e63f803d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -162,6 +162,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); +void iwl_dump_csr(struct iwl_priv *priv); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 88c1ed5b7dd7..c0d531c669bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2351,77 +2351,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_update_stats); #endif -static const char *get_csr_string(int cmd) -{ - switch (cmd) { - IWL_CMD(CSR_HW_IF_CONFIG_REG); - IWL_CMD(CSR_INT_COALESCING); - IWL_CMD(CSR_INT); - IWL_CMD(CSR_INT_MASK); - IWL_CMD(CSR_FH_INT_STATUS); - IWL_CMD(CSR_GPIO_IN); - IWL_CMD(CSR_RESET); - IWL_CMD(CSR_GP_CNTRL); - IWL_CMD(CSR_HW_REV); - IWL_CMD(CSR_EEPROM_REG); - IWL_CMD(CSR_EEPROM_GP); - IWL_CMD(CSR_OTP_GP_REG); - IWL_CMD(CSR_GIO_REG); - IWL_CMD(CSR_GP_UCODE_REG); - IWL_CMD(CSR_GP_DRIVER_REG); - IWL_CMD(CSR_UCODE_DRV_GP1); - IWL_CMD(CSR_UCODE_DRV_GP2); - IWL_CMD(CSR_LED_REG); - IWL_CMD(CSR_DRAM_INT_TBL_REG); - IWL_CMD(CSR_GIO_CHICKEN_BITS); - IWL_CMD(CSR_ANA_PLL_CFG); - IWL_CMD(CSR_HW_REV_WA_REG); - IWL_CMD(CSR_DBG_HPET_MEM_REG); - default: - return "UNKNOWN"; - - } -} - -void iwl_dump_csr(struct iwl_priv *priv) -{ - int i; - u32 csr_tbl[] = { - CSR_HW_IF_CONFIG_REG, - CSR_INT_COALESCING, - CSR_INT, - CSR_INT_MASK, - CSR_FH_INT_STATUS, - CSR_GPIO_IN, - CSR_RESET, - CSR_GP_CNTRL, - CSR_HW_REV, - CSR_EEPROM_REG, - CSR_EEPROM_GP, - CSR_OTP_GP_REG, - CSR_GIO_REG, - CSR_GP_UCODE_REG, - CSR_GP_DRIVER_REG, - CSR_UCODE_DRV_GP1, - CSR_UCODE_DRV_GP2, - CSR_LED_REG, - CSR_DRAM_INT_TBL_REG, - CSR_GIO_CHICKEN_BITS, - CSR_ANA_PLL_CFG, - CSR_HW_REV_WA_REG, - CSR_DBG_HPET_MEM_REG - }; - IWL_ERR(priv, "CSR values:\n"); - IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is " - "CSR_INT_PERIODIC_REG)\n"); - for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { - IWL_ERR(priv, " %25s: 0X%08x\n", - get_csr_string(csr_tbl[i]), - iwl_read32(priv, csr_tbl[i])); - } -} -EXPORT_SYMBOL(iwl_dump_csr); - static const char *get_fh_string(int cmd) { switch (cmd) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 0bc7b7a28a30..7e99b7dccb84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -659,7 +659,6 @@ int iwl_pci_resume(struct pci_dev *pdev); void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); -void iwl_dump_csr(struct iwl_priv *priv); int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, -- cgit v1.2.3 From 84fac3d9604147db37bd8c68897f79442d7ed714 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:07 +0200 Subject: iwlwifi: move iwl_dump_fh to agn The iwl_dump_fh function is only used by the agn module, so it can be there instead of being exported by the core. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 61 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 63 ------------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 4 files changed, 62 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index de91ff6dcd6c..ff5f2fc4d6d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2291,3 +2291,64 @@ void iwl_dump_csr(struct iwl_priv *priv) iwl_read32(priv, csr_tbl[i])); } } + +static const char *get_fh_string(int cmd) +{ + switch (cmd) { + IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); + IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); + IWL_CMD(FH_RSCSR_CHNL0_WPTR); + IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); + IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); + IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); + IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); + IWL_CMD(FH_TSSR_TX_STATUS_REG); + IWL_CMD(FH_TSSR_TX_ERROR_REG); + default: + return "UNKNOWN"; + } +} + +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) +{ + int i; +#ifdef CONFIG_IWLWIFI_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif + u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, + FH_RSCSR_CHNL0_WPTR, + FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_MEM_RSSR_SHARED_CTRL_REG, + FH_MEM_RSSR_RX_STATUS_REG, + FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return pos; + } +#endif + IWL_ERR(priv, "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + IWL_ERR(priv, " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5458e63f803d..1fca5af35771 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -163,6 +163,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwl_dump_csr(struct iwl_priv *priv); +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c0d531c669bf..5cd16a745bac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2351,69 +2351,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_update_stats); #endif -static const char *get_fh_string(int cmd) -{ - switch (cmd) { - IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); - IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); - IWL_CMD(FH_RSCSR_CHNL0_WPTR); - IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); - IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); - IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); - IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); - IWL_CMD(FH_TSSR_TX_STATUS_REG); - IWL_CMD(FH_TSSR_TX_ERROR_REG); - default: - return "UNKNOWN"; - - } -} - -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) -{ - int i; -#ifdef CONFIG_IWLWIFI_DEBUG - int pos = 0; - size_t bufsz = 0; -#endif - u32 fh_tbl[] = { - FH_RSCSR_CHNL0_STTS_WPTR_REG, - FH_RSCSR_CHNL0_RBDCB_BASE_REG, - FH_RSCSR_CHNL0_WPTR, - FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_MEM_RSSR_SHARED_CTRL_REG, - FH_MEM_RSSR_RX_STATUS_REG, - FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, - FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_ERROR_REG - }; -#ifdef CONFIG_IWLWIFI_DEBUG - if (display) { - bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - pos += scnprintf(*buf + pos, bufsz - pos, - "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - pos += scnprintf(*buf + pos, bufsz - pos, - " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(priv, fh_tbl[i])); - } - return pos; - } -#endif - IWL_ERR(priv, "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - IWL_ERR(priv, " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(priv, fh_tbl[i])); - } - return 0; -} -EXPORT_SYMBOL(iwl_dump_fh); - static void iwl_force_rf_reset(struct iwl_priv *priv) { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7e99b7dccb84..b02db31d7d5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -659,7 +659,6 @@ int iwl_pci_resume(struct pci_dev *pdev); void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -- cgit v1.2.3 From 0453674c90be7b39c8925ba5e1d746447905f8ee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:08 +0200 Subject: iwlwifi: remove set_ct_kill operation This operation is only ever called from set_hw_params, which is also already based on the config/ops, so that there's no need to have a separate set_ct_kill op and we can just call the right ct_threshold function. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-4965.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-5000.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-6000.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 5 files changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8c2db55df426..8aed9ead3a75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -151,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl1000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -219,7 +218,6 @@ static struct iwl_lib_ops iwl1000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl1000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 08d2dbc4efb3..c192856bb644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -669,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + + iwl4965_set_ct_threshold(priv); priv->hw_params.sens = &iwl4965_sensitivity; priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; @@ -2292,7 +2292,6 @@ static struct iwl_lib_ops iwl4965_lib = { .isr = iwl_isr_legacy, .temp_ops = { .temperature = iwl4965_temperature_calib, - .set_ct_kill = iwl4965_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ddbbb9320aca..084271e5e468 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl5000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl5150_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -394,7 +392,6 @@ static struct iwl_lib_ops iwl5000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl5000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, @@ -465,7 +462,6 @@ static struct iwl_lib_ops iwl5150_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwl5150_temperature, - .set_ct_kill = iwl5150_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 198cd8f40de3..84f181443f02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -192,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl6000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -334,7 +333,6 @@ static struct iwl_lib_ops iwl6000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl6000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, @@ -408,7 +406,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl6000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, .update_bcast_stations = iwl_update_bcast_stations, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b02db31d7d5b..f3c3d8531505 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -137,7 +137,6 @@ struct iwl_debugfs_ops { struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); - void (*set_ct_kill)(struct iwl_priv *priv); }; struct iwl_tt_ops { -- cgit v1.2.3 From 9597ebac91e5a88f558d236a51d776508d42a237 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:09 +0200 Subject: iwlwifi: remove set_pwr_src operation The set_pwr_src operation is only ever used from within the same sub-driver that it is declared in, so it can just be called directly instead of being an operation. Also, it is never called to set the power source to V_aux, so change the two functions accordingly (but keep the V_aux code for documentation purposes in a comment). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-3945.c | 26 ++++++++++++-------------- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 19 ++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ---------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 8 -------- 9 files changed, 30 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8aed9ead3a75..5bdfe9dcd070 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -196,7 +196,6 @@ static struct iwl_lib_ops iwl1000_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl1000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index ba3ab04c1fba..824c9428efaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -816,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) return sta_id; } -static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) +static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) { - if (src == IWL_PWR_SRC_VAUX) { +/* + * (for documentation purposes) + * to set power to V_AUX, do + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, @@ -828,16 +831,14 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) CSR_GPIO_IN_VAL_VAUX_PWR_SRC, CSR_GPIO_IN_BIT_AUX_POWER, 5000); } - } else { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); + */ - iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ - } + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); - return 0; + iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ } static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) @@ -1031,9 +1032,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.init(priv); spin_unlock_irqrestore(&priv->lock, flags); - rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); - if (rc) - return rc; + iwl3945_set_pwr_vmain(priv); priv->cfg->ops->lib->apm_ops.config(priv); @@ -2707,7 +2706,6 @@ static struct iwl_lib_ops iwl3945_lib = { .init = iwl3945_apm_init, .stop = iwl_apm_stop, .config = iwl3945_nic_config, - .set_pwr_src = iwl3945_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index c192856bb644..cda4a319ed97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2268,7 +2268,6 @@ static struct iwl_lib_ops iwl4965_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl4965_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 084271e5e468..c90a16cdfaff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -370,7 +370,6 @@ static struct iwl_lib_ops iwl5000_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl5000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -440,7 +439,6 @@ static struct iwl_lib_ops iwl5150_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl5000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 84f181443f02..02103a7ae1df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -310,7 +310,6 @@ static struct iwl_lib_ops iwl6000_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl6000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -383,7 +382,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .init = iwl_apm_init, .stop = iwl_apm_stop, .config = iwl6000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ff5f2fc4d6d9..0ad0d44893ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -685,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) return 0; } +static void iwlagn_set_pwr_vmain(struct iwl_priv *priv) +{ +/* + * (for documentation purposes) + * to set power to V_AUX, do: + + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VAUX, + ~APMG_PS_CTRL_MSK_PWR_SRC); + */ + + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); +} + int iwlagn_hw_nic_init(struct iwl_priv *priv) { unsigned long flags; @@ -700,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); + iwlagn_set_pwr_vmain(priv); priv->cfg->ops->lib->apm_ops.config(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8233c6410411..75472a3d87de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -935,22 +935,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, wake_up_interruptible(&priv->wait_command_queue); } -int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) -{ - if (src == IWL_PWR_SRC_VAUX) { - if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VAUX, - ~APMG_PS_CTRL_MSK_PWR_SRC); - } else { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); - } - - return 0; -} - static void iwl_bg_tx_flush(struct work_struct *work) { struct iwl_priv *priv = diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f3c3d8531505..ae77279d3d98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -119,7 +119,6 @@ struct iwl_apm_ops { int (*init)(struct iwl_priv *priv); void (*stop)(struct iwl_priv *priv); void (*config)(struct iwl_priv *priv); - int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); }; struct iwl_debugfs_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2b04714c3a9c..2c57dbd2de19 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -282,13 +282,6 @@ struct iwl_channel_info { */ #define IWL_IPAN_MCAST_QUEUE 8 -/* Power management (not Tx power) structures */ - -enum iwl_pwr_src { - IWL_PWR_SRC_VMAIN, - IWL_PWR_SRC_VAUX, -}; - #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) @@ -732,7 +725,6 @@ struct iwl_hw_params { * ****************************************************************************/ extern void iwl_update_chain_flags(struct iwl_priv *priv); -extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); extern const u8 iwl_bcast_addr[ETH_ALEN]; extern int iwl_rxq_stop(struct iwl_priv *priv); extern void iwl_txq_ctx_stop(struct iwl_priv *priv); -- cgit v1.2.3 From 14e8e4afeb7e90f1f2d3f2d3b54da57c27f59f38 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:10 +0200 Subject: iwlwifi: remove apm_ops.stop Since all devices share the same operation here, there's no need to call it indirectly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-3945.c | 1 - drivers/net/wireless/iwlwifi/iwl-4965.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 10 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5bdfe9dcd070..db540910b110 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -194,7 +194,6 @@ static struct iwl_lib_ops iwl1000_lib = { .update_chain_flags = iwl_update_chain_flags, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl1000_nic_config, }, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 824c9428efaa..b06a7bd8b285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2704,7 +2704,6 @@ static struct iwl_lib_ops iwl3945_lib = { .dump_nic_error_log = iwl3945_dump_nic_error_log, .apm_ops = { .init = iwl3945_apm_init, - .stop = iwl_apm_stop, .config = iwl3945_nic_config, }, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index cda4a319ed97..28ba563197cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2266,7 +2266,6 @@ static struct iwl_lib_ops iwl4965_lib = { .set_channel_switch = iwl4965_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl4965_nic_config, }, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c90a16cdfaff..fd9fbc93ea1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -368,7 +368,6 @@ static struct iwl_lib_ops iwl5000_lib = { .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl5000_nic_config, }, .eeprom_ops = { @@ -437,7 +436,6 @@ static struct iwl_lib_ops iwl5150_lib = { .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl5000_nic_config, }, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 02103a7ae1df..a45929ef22ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -308,7 +308,6 @@ static struct iwl_lib_ops iwl6000_lib = { .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl6000_nic_config, }, .eeprom_ops = { @@ -380,7 +379,6 @@ static struct iwl_lib_ops iwl6000g2b_lib = { .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl6000_nic_config, }, .eeprom_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 75472a3d87de..b1af79e7020a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2983,7 +2983,7 @@ static void __iwl_down(struct iwl_priv *priv) iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); @@ -4597,7 +4597,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) * paths to avoid running iwl_down() at all before leaving driver. * This (inexpensive) call *makes sure* device is reset. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); iwl_tt_exit(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5cd16a745bac..b3efbe02df67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2599,7 +2599,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) * it will not call apm_ops.stop() to stop the DMA operation. * Calling apm_ops.stop here to make sure we stop the DMA. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); pci_save_state(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ae77279d3d98..c01262cf7249 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -117,7 +117,6 @@ struct iwl_hcmd_utils_ops { struct iwl_apm_ops { int (*init)(struct iwl_priv *priv); - void (*stop)(struct iwl_priv *priv); void (*config)(struct iwl_priv *priv); }; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index bd51b06288eb..66eccb12159d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -603,7 +603,7 @@ err: if (ret) iwl_eeprom_free(priv); /* Reset chip to save power until we load uCode during "up". */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); alloc_err: return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c06b2189e09e..980c6096620a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2637,7 +2637,7 @@ static void __iwl3945_down(struct iwl_priv *priv) udelay(5); /* Stop the device, and put it in low power state */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); @@ -4212,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) * paths to avoid running iwl_down() at all before leaving driver. * This (inexpensive) call *makes sure* device is reset. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); /* make sure we flush any pending irq or * tasklet for the driver -- cgit v1.2.3 From 0de76736552cff02cc6ee4bae41e5502d7673f8e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:11 +0200 Subject: iwlwifi: clean up declarations A number of declarations in iwl-core.h should be in agn specific files, and also rename the iwl-calib.h file to iwl-agn-calib.h to better reflect that it belongs to agn. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 86 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 23 ++++++++ drivers/net/wireless/iwlwifi/iwl-calib.h | 82 -------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 33 ----------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 1 - drivers/net/wireless/iwlwifi/iwl-rx.c | 1 - 11 files changed, 114 insertions(+), 121 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-calib.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-calib.h diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 28ba563197cb..b207e3e9299f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -43,7 +43,7 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-helpers.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-sta.h" #include "iwl-agn-led.h" #include "iwl-agn.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 4c5ab783737f..e2019e756936 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -65,7 +65,7 @@ #include "iwl-dev.h" #include "iwl-core.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" /***************************************************************************** * INIT calibrations framework diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h new file mode 100644 index 000000000000..e37ae7261630 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -0,0 +1,86 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +#ifndef __iwl_calib_h__ +#define __iwl_calib_h__ + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-commands.h" + +void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); +void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); + +void iwl_init_sensitivity(struct iwl_priv *priv); +void iwl_reset_run_time_calib(struct iwl_priv *priv); +static inline void iwl_chain_noise_reset(struct iwl_priv *priv) +{ + + if (!priv->disable_chain_noise_cal && + priv->cfg->ops->utils->chain_noise_reset) + priv->cfg->ops->utils->chain_noise_reset(priv); +} + +int iwl_send_calib_results(struct iwl_priv *priv); +int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); +void iwl_calib_free_results(struct iwl_priv *priv); + +#endif /* __iwl_calib_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 1e08eb455474..bbd40b7dd597 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -34,7 +34,7 @@ #include "iwl-dev.h" #include "iwl-core.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-sta.h" #include "iwl-io.h" #include "iwl-helpers.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index e1dd76267dca..3a9537953875 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -38,6 +38,7 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-agn.h" +#include "iwl-agn-calib.h" static const s8 iwlagn_default_queue_to_tx_fifo[] = { IWL_TX_FIFO_VO, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b1af79e7020a..763a93d832f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -57,7 +57,7 @@ #include "iwl-io.h" #include "iwl-helpers.h" #include "iwl-sta.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-agn.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 1fca5af35771..b4deef4e91db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -177,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +void iwl_rx_handle(struct iwl_priv *priv); /* tx */ +void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); +int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad); +int iwl_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq); void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, struct ieee80211_tx_info *info); int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); @@ -289,4 +296,20 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); int iwl_update_bcast_stations(struct iwl_priv *priv); +/* rate */ +static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) +{ + return BIT(ant_idx) << RATE_MCS_ANT_POS; +} + +static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) +{ + return le32_to_cpu(rate_n_flags) & 0xFF; +} + +static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) +{ + return cpu_to_le32(flags|(u32)rate); +} + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h deleted file mode 100644 index ba9523fbb300..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ -#ifndef __iwl_calib_h__ -#define __iwl_calib_h__ - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-commands.h" - -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); -void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); - -void iwl_init_sensitivity(struct iwl_priv *priv); -void iwl_reset_run_time_calib(struct iwl_priv *priv); -static inline void iwl_chain_noise_reset(struct iwl_priv *priv) -{ - - if (!priv->disable_chain_noise_cal && - priv->cfg->ops->utils->chain_noise_reset) - priv->cfg->ops->utils->chain_noise_reset(priv); -} - -#endif /* __iwl_calib_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c01262cf7249..a5e12b70c594 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -396,7 +396,6 @@ struct iwl_cfg { struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, struct ieee80211_ops *hw_ops); -void iwl_activate_qos(struct iwl_priv *priv); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); @@ -505,7 +504,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv, ******************************************************/ void iwl_cmd_queue_free(struct iwl_priv *priv); int iwl_rx_queue_alloc(struct iwl_priv *priv); -void iwl_rx_handle(struct iwl_priv *priv); void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); int iwl_rx_queue_space(const struct iwl_rx_queue *q); @@ -523,12 +521,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /***************************************************** * TX ******************************************************/ -void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad); -int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); @@ -547,24 +539,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) -{ - return BIT(ant_idx) << RATE_MCS_ANT_POS; -} - -static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0xFF; -} -static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0x1FFFF; -} -static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) -{ - return cpu_to_le32(flags|(u32)rate); -} - /******************************************************************************* * Scanning ******************************************************************************/ @@ -600,13 +574,6 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) -/******************************************************************************* - * Calibrations - implemented in iwl-calib.c - ******************************************************************************/ -int iwl_send_calib_results(struct iwl_priv *priv); -int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); -void iwl_calib_free_results(struct iwl_priv *priv); - /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index fc340311ea0a..96d9085639e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -39,7 +39,6 @@ #include "iwl-debug.h" #include "iwl-core.h" #include "iwl-io.h" -#include "iwl-calib.h" /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 10be197b0f22..f436270ca39a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -36,7 +36,6 @@ #include "iwl-core.h" #include "iwl-sta.h" #include "iwl-io.h" -#include "iwl-calib.h" #include "iwl-helpers.h" /************************** RX-FUNCTIONS ****************************/ /* -- cgit v1.2.3 From a313f3839eeeebb3cbbcf1fbd2aee92bde389032 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 18:02:12 +0200 Subject: iwlwifi: remove iwl_check_bits The function is used exactly once, and the caller doesn't even need the special check, it can be simplified to a simple bit check. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-helpers.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index b06a7bd8b285..7d74ae53950c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -348,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); iwl3945_tx_queue_reclaim(priv, txq_id, index); - if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) + if (status & TX_ABORT_REQUIRED_MSK) IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 621abe3c5afc..1aaef70deaec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf( return &hw->conf; } -static inline int iwl_check_bits(unsigned long field, unsigned long mask) -{ - return ((field & mask) == mask) ? 1 : 0; -} - static inline unsigned long elapsed_jiffies(unsigned long start, unsigned long end) { -- cgit v1.2.3 From 1cf263736092b3712103a5290a93dd0fff376f26 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Sep 2010 07:32:13 -0700 Subject: iwlwifi: fix dual-mode scanning The recent scanning code shuffle accidentally moved the SCAN_HW bit setting _after_ the PAN parameters are modified, which means that they don't take the scan into account -- fix that. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0ad0d44893ab..c1a389883af0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1565,13 +1565,15 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) cmd.data = scan; scan->len = cpu_to_le16(cmd.len); + /* set scan bit here for PAN params */ + set_bit(STATUS_SCAN_HW, &priv->status); + if (priv->cfg->ops->hcmd->set_pan_params) { ret = priv->cfg->ops->hcmd->set_pan_params(priv); if (ret) return ret; } - set_bit(STATUS_SCAN_HW, &priv->status); ret = iwl_send_cmd_sync(priv, &cmd); if (ret) { clear_bit(STATUS_SCAN_HW, &priv->status); -- cgit v1.2.3 From 65cccfb03d0dc99fd213d57be5f60f8ca6a60824 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 21 Sep 2010 16:15:58 -0700 Subject: iwlagn: no version check for experimental uCode For experimental uCode, it should work with the driver if driver has experimental uCode support option enabled; remove the API version checking. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 763a93d832f8..1b682ddcf4e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2104,18 +2104,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * firmware filename ... but we don't check for that and only rely * on the API version read from firmware header from here on forward */ - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } + /* no api version check required for experimental uCode */ + if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } - if (api_ver != api_max) - IWL_ERR(priv, "Firmware has old API version. Expected v%u, " - "got v%u. New firmware can be obtained " - "from http://www.intellinuxwireless.org.\n", - api_max, api_ver); + if (api_ver != api_max) + IWL_ERR(priv, + "Firmware has old API version. Expected v%u, " + "got v%u. New firmware can be obtained " + "from http://www.intellinuxwireless.org.\n", + api_max, api_ver); + } if (build) sprintf(buildstr, " build %u%s", build, -- cgit v1.2.3 From 642454cc0774e0774bc1ccb4292d6dc0abd06d20 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 21 Sep 2010 12:06:18 -0700 Subject: iwlagn: fix default calibration table size iwlagn driver uses the IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE as the chain noise reset calibration index and IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE+1 as the chain noise gain calibration index, if not specified by the TLV value in the new firmware format. However, this is broken if we need to add more calibrations like the temperature offset calibration because we increased IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE by 1. To fix this issue, define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE and use it as the calibration index instead. We still keep the IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE as a sanity check for the TLV value given by ucode. Signed-off-by: Shanyu Zhao Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1b682ddcf4e8..c4fe3f94c366 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2062,7 +2062,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) struct iwlagn_ucode_capabilities ucode_capa = { .max_probe_length = 200, .standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, }; memset(&pieces, 0, sizeof(pieces)); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index fe652568fec7..74b78d858936 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3784,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd { */ /* Phy calibration command for series */ - +/* The default calibrate table size if not specified by firmware */ +#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 enum { IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, IWL_PHY_CALIBRATE_DC_CMD = 8, -- cgit v1.2.3 From bf53f939e02c0e818df93ab130fedc0e4ba95796 Mon Sep 17 00:00:00 2001 From: Shanyu Zhao Date: Tue, 21 Sep 2010 16:54:01 -0700 Subject: iwlagn: add temperature offset calib for 6000g2 6000g2 devices need to have temperature offset calibration. The runtime uCode needs to receive the calibration results just like BB and LO calibration. To do this, driver reads the offset value from NVM and send it to uCode after runtime uCode is alive. Signed-off-by: Shanyu Zhao Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 27 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 10 +++++++++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a45929ef22ec..4810258aefd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -204,6 +204,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_BASE_BAND); if (priv->cfg->need_dc_calib) priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); + if (priv->cfg->need_temp_offset_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; @@ -536,6 +538,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .base_params = &iwl6000_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .need_temp_offset_calib = true, }; struct iwl_cfg iwl6000g2a_2abg_cfg = { @@ -552,6 +555,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .need_dc_calib = true, + .need_temp_offset_calib = true, }; struct iwl_cfg iwl6000g2a_2bg_cfg = { @@ -568,6 +572,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .need_dc_calib = true, + .need_temp_offset_calib = true, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -586,6 +591,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -605,6 +611,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .base_params = &iwl6000_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -625,6 +632,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -644,6 +652,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .base_params = &iwl6000_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -664,6 +673,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -683,6 +693,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .base_params = &iwl6000_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, + .need_temp_offset_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 3a9537953875..703621107dac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -215,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) (u8 *)&cmd, sizeof(cmd)); } +static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) +{ + struct iwl_calib_temperature_offset_cmd cmd; + __le16 *offset_calib = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; + cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); + if (!(cmd.radio_sensor_offset)) + cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; + cmd.reserved = 0; + IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", + cmd.radio_sensor_offset); + return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], + (u8 *)&cmd, sizeof(cmd)); +} + static int iwlagn_send_calib_cfg(struct iwl_priv *priv) { struct iwl_calib_cfg_cmd calib_cfg_cmd; @@ -321,6 +340,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) } iwlagn_send_calib_cfg(priv); + + /** + * temperature offset calibration is only needed for runtime ucode, + * so prepare the value now. + */ + if (priv->cfg->need_temp_offset_calib) + iwlagn_set_temperature_offset_calib(priv); + return; restart: diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 74b78d858936..424801abc80e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3794,7 +3794,8 @@ enum { IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18, + IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, }; #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) @@ -3864,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd { u8 pad[2]; } __packed; +#define DEFAULT_RADIO_SENSOR_OFFSET 2700 +struct iwl_calib_temperature_offset_cmd { + struct iwl_calib_hdr hdr; + s16 radio_sensor_offset; + s16 reserved; +} __packed; + /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ struct iwl_calib_chain_noise_reset_cmd { struct iwl_calib_hdr hdr; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a5e12b70c594..64527def059f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -342,6 +342,7 @@ struct iwl_ht_params { * @ucode_api_min: Lowest version of uCode API supported by driver. * @pa_type: used by 6000 series only to identify the type of Power Amplifier * @need_dc_calib: need to perform init dc calibration + * @need_temp_offset_calib: need to perform temperature offset calibration * @scan_antennas: available antenna for scan operation * * We enable the driver to be backward compatible wrt API version. The @@ -386,6 +387,7 @@ struct iwl_cfg { struct iwl_bt_params *bt_params; enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ const bool need_dc_calib; /* if used set to true */ + const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2c57dbd2de19..de43e1350ed1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -835,6 +835,7 @@ enum iwl_calib { IWL_CALIB_TX_IQ, IWL_CALIB_TX_IQ_PERD, IWL_CALIB_BASE_BAND, + IWL_CALIB_TEMP_OFFSET, IWL_CALIB_MAX }; -- cgit v1.2.3 From 00cbb3c5317d418c349c60876fe12fba7624f3e7 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 8 Oct 2010 16:16:16 +0300 Subject: wl1271: sdio: enable runtime PM Enable runtime PM for the wl1271 SDIO device. We request power whenever the WLAN interface is brought up, and release it after the WLAN interface is taken down. As a result, power is released immediately after probe returns, since at that point power has not been explicitly requested yet (i.e. the WLAN interface is still down). Signed-off-by: Ohad Ben-Cohen Acked-by: Luciano Coelho Tested-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 4c250d7dc3fa..f7bef32f04c9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "wl1271.h" #include "wl12xx_80211.h" @@ -160,12 +161,19 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, static int wl1271_sdio_power_on(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); + int ret; + + /* Power up the card */ + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); - return 0; +out: + return ret; } static int wl1271_sdio_power_off(struct wl1271 *wl) @@ -176,15 +184,12 @@ static int wl1271_sdio_power_off(struct wl1271 *wl) sdio_disable_func(func); sdio_release_host(func); - return 0; + /* Power down the card */ + return pm_runtime_put_sync(&func->dev); } static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) { - /* Let the SDIO stack handle wlan_enable control, so we - * keep host claimed while wlan is in use to keep wl1271 - * alive. - */ if (enable) return wl1271_sdio_power_on(wl); else @@ -256,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, sdio_set_drvdata(func, wl); + /* Tell PM core that we don't need the card to be powered now */ + pm_runtime_put_noidle(&func->dev); + wl1271_notice("initialized"); return 0; @@ -274,6 +282,9 @@ static void __devexit wl1271_remove(struct sdio_func *func) { struct wl1271 *wl = sdio_get_drvdata(func); + /* Undo decrement done above in wl1271_probe */ + pm_runtime_get_noresume(&func->dev); + wl1271_unregister_hw(wl); free_irq(wl->irq, wl); wl1271_free_hw(wl); -- cgit v1.2.3 From 674f3058c806ae2591b98f59194fa85b650aa667 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 8 Oct 2010 16:16:27 +0300 Subject: wl1271: sdio: add suspend/resume support Add required suspend/resume support to prevent the SDIO core from removing our card completely during system suspend. Signed-off-by: Ohad Ben-Cohen Tested-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl1271_sdio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index f7bef32f04c9..784ef3432641 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -290,11 +290,31 @@ static void __devexit wl1271_remove(struct sdio_func *func) wl1271_free_hw(wl); } +static int wl1271_suspend(struct device *dev) +{ + /* Tell MMC/SDIO core it's OK to power down the card + * (if it isn't already), but not to remove it completely */ + return 0; +} + +static int wl1271_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wl1271_sdio_pm_ops = { + .suspend = wl1271_suspend, + .resume = wl1271_resume, +}; + static struct sdio_driver wl1271_sdio_driver = { .name = "wl1271_sdio", .id_table = wl1271_devices, .probe = wl1271_probe, .remove = __devexit_p(wl1271_remove), + .drv = { + .pm = &wl1271_sdio_pm_ops, + }, }; static int __init wl1271_init(void) -- cgit v1.2.3 From 4e7f79511e7332ae4056eda9156a0299511ea41e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Oct 2010 10:33:39 -0700 Subject: net: Update kernel-doc for netif_set_real_num_rx_queues() Synchronise the comment with the preceding implementation change. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index fd1b75a47e88..4962c8afd606 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1576,8 +1576,8 @@ EXPORT_SYMBOL(netif_set_real_num_tx_queues); * * This must be called either with the rtnl_lock held or before * registration of the net device. Returns 0 on success, or a - * negative error code. If called before registration, it also - * sets the maximum number of queues, and always succeeds. + * negative error code. If called before registration, it always + * succeeds. */ int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) { -- cgit v1.2.3 From 993284dfff3ba4643f08b592427d0ac758d30156 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Oct 2010 10:36:10 -0700 Subject: sfc: Don't try to set filters with search depths we know won't work The filter engine will time-out and ignore filters beyond 200-something hops. We also need to avoid infinite loops in efx_filter_search() when the table is full. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/filter.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index abc884d09d57..52cb6082b910 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -20,6 +20,12 @@ #define FILTER_CTL_SRCH_FUDGE_WILD 3 #define FILTER_CTL_SRCH_FUDGE_FULL 1 +/* Hard maximum hop limit. Hardware will time-out beyond 200-something. + * We also need to avoid infinite loops in efx_filter_search() when the + * table is full. + */ +#define FILTER_CTL_SRCH_MAX 200 + struct efx_filter_table { u32 offset; /* address of table relative to BAR */ unsigned size; /* number of entries */ @@ -183,7 +189,8 @@ static int efx_filter_search(struct efx_filter_table *table, incr = efx_filter_increment(key); for (depth = 1, filter_idx = hash & (table->size - 1); - test_bit(filter_idx, table->used_bitmap); + depth <= FILTER_CTL_SRCH_MAX && + test_bit(filter_idx, table->used_bitmap); ++depth) { cmp = &table->spec[filter_idx]; if (efx_filter_equal(spec, cmp)) @@ -192,6 +199,8 @@ static int efx_filter_search(struct efx_filter_table *table, } if (!for_insert) return -ENOENT; + if (depth > FILTER_CTL_SRCH_MAX) + return -EBUSY; found: *depth_required = depth; return filter_idx; -- cgit v1.2.3 From 8391d07b80e8da957cd888870e23f8e218438622 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Thu, 7 Oct 2010 14:48:38 +0000 Subject: ipv4: Remove leftover rcu_read_unlock calls from __mkroute_output() Commit "fib: RCU conversion of fib_lookup()" removed rcu_read_lock() from __mkroute_output but left a couple of calls to rcu_read_unlock() in there. This causes lockdep to complain that the rcu_read_unlock() call in __ip_route_output_key causes a lock inbalance and quickly crashes the kernel. The below fixes this for me. Signed-off-by: Dimitris Michailidis Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 7864d0c48968..3888f6ba0a5c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2396,12 +2396,10 @@ static int __mkroute_output(struct rtable **result, rth = dst_alloc(&ipv4_dst_ops); - if (!rth) { - rcu_read_unlock(); + if (!rth) return -ENOBUFS; - } + in_dev_hold(in_dev); - rcu_read_unlock(); rth->idev = in_dev; atomic_set(&rth->dst.__refcnt, 1); -- cgit v1.2.3 From f7ec804a3edd2f7cf98a42bcad741d89d547c117 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Oct 2010 23:46:05 +0000 Subject: qlcnic: driver private workqueue Currently fw recovery usage global workqueue. As same workqueue used by kernel for ethtool and etc., supporting quiescent mode is not possible, without driver private workqueue. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4757908b29b5..7503c487075c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -46,6 +46,7 @@ char qlcnic_driver_name[] = "qlcnic"; static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; +static struct workqueue_struct *qlcnic_wq; static int qlcnic_mac_learn; module_param(qlcnic_mac_learn, int, 0644); MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); @@ -2886,7 +2887,8 @@ qlcnic_schedule_work(struct qlcnic_adapter *adapter, return; INIT_DELAYED_WORK(&adapter->fw_work, func); - schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay)); + queue_delayed_work(qlcnic_wq, &adapter->fw_work, + round_jiffies_relative(delay)); } static void @@ -4163,6 +4165,12 @@ static int __init qlcnic_init_module(void) printk(KERN_INFO "%s\n", qlcnic_driver_string); + qlcnic_wq = create_singlethread_workqueue("qlcnic"); + if (qlcnic_wq == NULL) { + printk(KERN_ERR "qlcnic: cannot create workqueue\n"); + return -ENOMEM; + } + #ifdef CONFIG_INET register_netdevice_notifier(&qlcnic_netdev_cb); register_inetaddr_notifier(&qlcnic_inetaddr_cb); @@ -4174,6 +4182,7 @@ static int __init qlcnic_init_module(void) unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); unregister_netdevice_notifier(&qlcnic_netdev_cb); #endif + destroy_workqueue(qlcnic_wq); } return ret; @@ -4190,6 +4199,7 @@ static void __exit qlcnic_exit_module(void) unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); unregister_netdevice_notifier(&qlcnic_netdev_cb); #endif + destroy_workqueue(qlcnic_wq); } module_exit(qlcnic_exit_module); -- cgit v1.2.3 From b8c17620458b82fd868f4813e1ff18368a832b7c Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Oct 2010 23:46:06 +0000 Subject: qlcnic: support quiescent mode Put device in quiescent mode during internal loopback test. Before running test, set state to NEED_QUISCENT. After getting ack from all function, change state to QUISCENT and perform test. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 + drivers/net/qlcnic/qlcnic_ethtool.c | 6 +++ drivers/net/qlcnic/qlcnic_main.c | 83 +++++++++++++++++++++++++++++-------- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index a1fabdc10b59..6909cfc6d2bd 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1313,6 +1313,8 @@ int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); /* Functions from qlcnic_main.c */ +int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter); +void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter); int qlcnic_reset_context(struct qlcnic_adapter *); u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter, u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd); diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 6a760140f792..018130193b5b 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -706,6 +706,11 @@ static int qlcnic_loopback_test(struct net_device *netdev) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; + if (qlcnic_request_quiscent_mode(adapter)) { + clear_bit(__QLCNIC_RESETTING, &adapter->state); + return -EIO; + } + ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); if (ret) goto clear_it; @@ -722,6 +727,7 @@ done: qlcnic_diag_free_res(netdev, max_sds_rings); clear_it: + qlcnic_clear_quiscent_mode(adapter); adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); return ret; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 7503c487075c..9b0acfb23e4c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2712,7 +2712,8 @@ qlcnic_fwinit_work(struct work_struct *work) goto err_ret; dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (dev_state == QLCNIC_DEV_QUISCENT) { + if (dev_state == QLCNIC_DEV_QUISCENT || + dev_state == QLCNIC_DEV_NEED_QUISCENT) { qlcnic_api_unlock(adapter); qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY * 2); @@ -2734,18 +2735,6 @@ qlcnic_fwinit_work(struct work_struct *work) skip_ack_check: dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (dev_state == QLCNIC_DEV_NEED_QUISCENT) { - QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, - QLCNIC_DEV_QUISCENT); - qlcnic_schedule_work(adapter, qlcnic_fwinit_work, - FW_POLL_DELAY * 2); - QLCDB(adapter, DRV, "Quiscing the driver\n"); - qlcnic_idc_debug_info(adapter, 0); - - qlcnic_api_unlock(adapter); - return; - } - if (dev_state == QLCNIC_DEV_NEED_RESET) { QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING); @@ -2802,7 +2791,12 @@ qlcnic_detach_work(struct work_struct *work) netif_device_detach(netdev); - qlcnic_down(adapter, netdev); + /* Dont grab rtnl lock during Quiscent mode */ + if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { + if (netif_running(netdev)) + __qlcnic_down(adapter, netdev); + } else + qlcnic_down(adapter, netdev); status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1); @@ -2844,6 +2838,61 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) qlcnic_api_unlock(adapter); } +/* Caller should held RESETTING bit. + * This should be call in sync with qlcnic_request_quiscent_mode. + */ +void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter) +{ + qlcnic_clr_drv_state(adapter); + qlcnic_api_lock(adapter); + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); + qlcnic_api_unlock(adapter); +} + +/* Caller should held RESETTING bit. + */ +int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter) +{ + u8 timeo = adapter->dev_init_timeo / 2; + u32 state; + + if (qlcnic_api_lock(adapter)) + return -EIO; + + state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state != QLCNIC_DEV_READY) + return -EIO; + + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT); + qlcnic_api_unlock(adapter); + QLCDB(adapter, DRV, "NEED QUISCENT state set\n"); + qlcnic_idc_debug_info(adapter, 0); + + qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT); + + do { + msleep(2000); + state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_QUISCENT) + return 0; + if (!qlcnic_check_drv_state(adapter)) { + if (qlcnic_api_lock(adapter)) + return -EIO; + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, + QLCNIC_DEV_QUISCENT); + qlcnic_api_unlock(adapter); + QLCDB(adapter, DRV, "QUISCENT mode set\n"); + return 0; + } + } while (--timeo); + + dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x" + " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE), + QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE)); + qlcnic_clear_quiscent_mode(adapter); + return -EIO; +} + /*Transit to RESET state from READY state only */ static void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) @@ -2951,11 +3000,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) qlcnic_dev_request_reset(adapter); state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (state == QLCNIC_DEV_NEED_RESET || - state == QLCNIC_DEV_NEED_QUISCENT) { + if (state == QLCNIC_DEV_NEED_RESET) { qlcnic_set_npar_non_operational(adapter); adapter->need_fw_reset = 1; - } + } else if (state == QLCNIC_DEV_NEED_QUISCENT) + goto detach; heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); if (heartbeat != adapter->heartbeat) { -- cgit v1.2.3 From a2152d096e0cd8593e883f72e875195ea0e89bb7 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Oct 2010 23:46:07 +0000 Subject: qlcnic: remove private LRO flag LRO was not getting enable after interface down/up. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 4 ++-- drivers/net/qlcnic/qlcnic_hw.c | 5 ----- drivers/net/qlcnic/qlcnic_main.c | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 018130193b5b..e07adb1dec4f 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -865,7 +865,7 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) return 0; } - if (adapter->flags & QLCNIC_LRO_ENABLED) { + if (dev->features & NETIF_F_LRO) { if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED)) return -EIO; @@ -1062,7 +1062,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) return -EINVAL; } - if ((data & ETH_FLAG_LRO) && (adapter->flags & QLCNIC_LRO_ENABLED)) + if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO)) return 0; if (data & ETH_FLAG_LRO) { diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 9d3e16dbd043..7f1f9b4ca0ff 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -582,9 +582,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) u64 word; int rv; - if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable) - return 0; - memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); @@ -599,8 +596,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) dev_err(&adapter->netdev->dev, "Could not send configure hw lro request\n"); - adapter->flags ^= QLCNIC_LRO_ENABLED; - return rv; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 9b0acfb23e4c..e3c1b80e00b1 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -657,8 +657,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) dev_info(&pdev->dev, "firmware v%d.%d.%d\n", fw_major, fw_minor, fw_build); - adapter->flags &= ~QLCNIC_LRO_ENABLED; - if (adapter->ahw.port_type == QLCNIC_XGBE) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; -- cgit v1.2.3 From 6336acd5522b150e7695cb3b42221999b352baa5 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 7 Oct 2010 23:46:08 +0000 Subject: qlcnic: fix board description Remove "Flex-10" from board description. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 6909cfc6d2bd..46a54b3ccea6 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1370,7 +1370,7 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { {0x1077, 0x8020, 0x1077, 0x20f, "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x103c, 0x3733, - "NC523SFP 10Gb 2-port Flex-10 Server Adapter"}, + "NC523SFP 10Gb 2-port Server Adapter"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; -- cgit v1.2.3 From ee07c1a70117fe93cf71686d481791c2498f80d2 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Thu, 7 Oct 2010 23:46:09 +0000 Subject: qlcnic: fix promiscous mode for VF o Allow promiscous mode setting for VF's depending upon the configuration. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_hw.c | 3 ++- drivers/net/qlcnic/qlcnic_main.c | 9 +++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 46a54b3ccea6..4025e203e8ae 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -920,6 +920,7 @@ struct qlcnic_ipaddr { #define QLCNIC_TAGGING_ENABLED 0x100 #define QLCNIC_MACSPOOF 0x200 #define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 +#define QLCNIC_PROMISC_DISABLED 0x800 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 7f1f9b4ca0ff..53e805316f4a 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -442,7 +442,8 @@ void qlcnic_set_multi(struct net_device *netdev) qlcnic_nic_add_mac(adapter, bcast_addr); if (netdev->flags & IFF_PROMISC) { - mode = VPORT_MISS_MODE_ACCEPT_ALL; + if (!(adapter->flags & QLCNIC_PROMISC_DISABLED)) + mode = VPORT_MISS_MODE_ACCEPT_ALL; goto send_fw_cmd; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index e3c1b80e00b1..4aada0b8ceb1 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -718,8 +718,8 @@ static void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) { - adapter->flags &= ~QLCNIC_MACSPOOF; - adapter->flags &= ~QLCNIC_MAC_OVERRIDE_DISABLED; + adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | + QLCNIC_PROMISC_DISABLED); if (esw_cfg->mac_anti_spoof) adapter->flags |= QLCNIC_MACSPOOF; @@ -727,6 +727,9 @@ qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, if (!esw_cfg->mac_override) adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; + if (!esw_cfg->promisc_mode) + adapter->flags |= QLCNIC_PROMISC_DISABLED; + qlcnic_set_netdev_features(adapter, esw_cfg); } @@ -845,6 +848,7 @@ qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) esw_cfg.pci_func = i; esw_cfg.offload_flags = BIT_0; esw_cfg.mac_override = BIT_0; + esw_cfg.promisc_mode = BIT_0; if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) esw_cfg.offload_flags |= (BIT_1 | BIT_2); if (qlcnic_config_switch_port(adapter, &esw_cfg)) @@ -3571,6 +3575,7 @@ validate_esw_config(struct qlcnic_adapter *adapter, QLCNIC_NON_PRIV_FUNC) { esw_cfg[i].mac_anti_spoof = 0; esw_cfg[i].mac_override = 1; + esw_cfg[i].promisc_mode = 1; } break; case QLCNIC_ADD_VLAN: -- cgit v1.2.3 From ff1b1bf867ebb7eb5e3ff0eab21c26b830d5e890 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Thu, 7 Oct 2010 23:46:10 +0000 Subject: qlcnic: change all P3 references to P3P This patch just rename all P3 #define to P3P. Signed-off-by: Sritej Velaga Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 38 ++++++++++++++++----------------- drivers/net/qlcnic/qlcnic_ethtool.c | 42 ++++++++++++++++++------------------- drivers/net/qlcnic/qlcnic_hdr.h | 24 ++++++++++----------- drivers/net/qlcnic/qlcnic_hw.c | 36 +++++++++++++++---------------- drivers/net/qlcnic/qlcnic_init.c | 4 ++-- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 4025e203e8ae..d32531441b6a 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -94,12 +94,12 @@ #define FIRST_PAGE_GROUP_START 0 #define FIRST_PAGE_GROUP_END 0x100000 -#define P3_MAX_MTU (9600) -#define P3_MIN_MTU (68) +#define P3P_MAX_MTU (9600) +#define P3P_MIN_MTU (68) #define QLCNIC_MAX_ETHERHDR 32 /* This contains some padding */ -#define QLCNIC_P3_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN) -#define QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3_MAX_MTU) +#define QLCNIC_P3P_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN) +#define QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3P_MAX_MTU) #define QLCNIC_CT_DEFAULT_RX_BUF_LEN 2048 #define QLCNIC_LRO_BUFFER_EXTRA 2048 @@ -307,20 +307,20 @@ struct uni_data_desc{ /* Magic number to let user know flash is programmed */ #define QLCNIC_BDINFO_MAGIC 0x12345678 -#define QLCNIC_BRDTYPE_P3_REF_QG 0x0021 -#define QLCNIC_BRDTYPE_P3_HMEZ 0x0022 -#define QLCNIC_BRDTYPE_P3_10G_CX4_LP 0x0023 -#define QLCNIC_BRDTYPE_P3_4_GB 0x0024 -#define QLCNIC_BRDTYPE_P3_IMEZ 0x0025 -#define QLCNIC_BRDTYPE_P3_10G_SFP_PLUS 0x0026 -#define QLCNIC_BRDTYPE_P3_10000_BASE_T 0x0027 -#define QLCNIC_BRDTYPE_P3_XG_LOM 0x0028 -#define QLCNIC_BRDTYPE_P3_4_GB_MM 0x0029 -#define QLCNIC_BRDTYPE_P3_10G_SFP_CT 0x002a -#define QLCNIC_BRDTYPE_P3_10G_SFP_QT 0x002b -#define QLCNIC_BRDTYPE_P3_10G_CX4 0x0031 -#define QLCNIC_BRDTYPE_P3_10G_XFP 0x0032 -#define QLCNIC_BRDTYPE_P3_10G_TP 0x0080 +#define QLCNIC_BRDTYPE_P3P_REF_QG 0x0021 +#define QLCNIC_BRDTYPE_P3P_HMEZ 0x0022 +#define QLCNIC_BRDTYPE_P3P_10G_CX4_LP 0x0023 +#define QLCNIC_BRDTYPE_P3P_4_GB 0x0024 +#define QLCNIC_BRDTYPE_P3P_IMEZ 0x0025 +#define QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS 0x0026 +#define QLCNIC_BRDTYPE_P3P_10000_BASE_T 0x0027 +#define QLCNIC_BRDTYPE_P3P_XG_LOM 0x0028 +#define QLCNIC_BRDTYPE_P3P_4_GB_MM 0x0029 +#define QLCNIC_BRDTYPE_P3P_10G_SFP_CT 0x002a +#define QLCNIC_BRDTYPE_P3P_10G_SFP_QT 0x002b +#define QLCNIC_BRDTYPE_P3P_10G_CX4 0x0031 +#define QLCNIC_BRDTYPE_P3P_10G_XFP 0x0032 +#define QLCNIC_BRDTYPE_P3P_10G_TP 0x0080 #define QLCNIC_MSIX_TABLE_OFFSET 0x44 @@ -719,7 +719,7 @@ struct qlcnic_cardrsp_tx_ctx { /* MAC */ -#define MC_COUNT_P3 38 +#define MC_COUNT_P3P 38 #define QLCNIC_MAC_NOOP 0 #define QLCNIC_MAC_ADD 1 diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index e07adb1dec4f..2568aa665024 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -96,7 +96,7 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { static const u32 diag_registers[] = { CRB_CMDPEG_STATE, CRB_RCVPEG_STATE, - CRB_XG_STATE_P3, + CRB_XG_STATE_P3P, CRB_FW_CAPABILITIES_1, ISR_INT_STATE_REG, QLCNIC_CRB_DRV_ACTIVE, @@ -189,9 +189,9 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) goto skip; } - val = QLCRD32(adapter, P3_LINK_SPEED_REG(pcifn)); - ecmd->speed = P3_LINK_SPEED_MHZ * - P3_LINK_SPEED_VAL(pcifn, val); + val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); + ecmd->speed = P3P_LINK_SPEED_MHZ * + P3P_LINK_SPEED_VAL(pcifn, val); ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; } else @@ -202,42 +202,42 @@ skip: ecmd->transceiver = XCVR_EXTERNAL; switch (adapter->ahw.board_type) { - case QLCNIC_BRDTYPE_P3_REF_QG: - case QLCNIC_BRDTYPE_P3_4_GB: - case QLCNIC_BRDTYPE_P3_4_GB_MM: + case QLCNIC_BRDTYPE_P3P_REF_QG: + case QLCNIC_BRDTYPE_P3P_4_GB: + case QLCNIC_BRDTYPE_P3P_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; - case QLCNIC_BRDTYPE_P3_10G_CX4: - case QLCNIC_BRDTYPE_P3_10G_CX4_LP: - case QLCNIC_BRDTYPE_P3_10000_BASE_T: + case QLCNIC_BRDTYPE_P3P_10G_CX4: + case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: + case QLCNIC_BRDTYPE_P3P_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = adapter->link_autoneg; break; - case QLCNIC_BRDTYPE_P3_IMEZ: - case QLCNIC_BRDTYPE_P3_XG_LOM: - case QLCNIC_BRDTYPE_P3_HMEZ: + case QLCNIC_BRDTYPE_P3P_IMEZ: + case QLCNIC_BRDTYPE_P3P_XG_LOM: + case QLCNIC_BRDTYPE_P3P_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; - case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: - case QLCNIC_BRDTYPE_P3_10G_SFP_CT: - case QLCNIC_BRDTYPE_P3_10G_SFP_QT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: + case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; check_sfp_module = netif_running(dev) && adapter->has_link_events; - case QLCNIC_BRDTYPE_P3_10G_XFP: + case QLCNIC_BRDTYPE_P3P_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; - case QLCNIC_BRDTYPE_P3_10G_TP: + case QLCNIC_BRDTYPE_P3P_10G_TP: if (adapter->ahw.port_type == QLCNIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); @@ -381,9 +381,9 @@ static u32 qlcnic_test_link(struct net_device *dev) struct qlcnic_adapter *adapter = netdev_priv(dev); u32 val; - val = QLCRD32(adapter, CRB_XG_STATE_P3); - val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); - return (val == XG_LINK_UP_P3) ? 0 : 1; + val = QLCRD32(adapter, CRB_XG_STATE_P3P); + val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val); + return (val == XG_LINK_UP_P3P) ? 0 : 1; } static int diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 716203e41dc7..4290b80cde1a 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -556,18 +556,18 @@ enum { #define XG_LINK_UP 0x10 #define XG_LINK_DOWN 0x20 -#define XG_LINK_UP_P3 0x01 -#define XG_LINK_DOWN_P3 0x02 -#define XG_LINK_STATE_P3_MASK 0xf -#define XG_LINK_STATE_P3(pcifn, val) \ - (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK) - -#define P3_LINK_SPEED_MHZ 100 -#define P3_LINK_SPEED_MASK 0xff -#define P3_LINK_SPEED_REG(pcifn) \ +#define XG_LINK_UP_P3P 0x01 +#define XG_LINK_DOWN_P3P 0x02 +#define XG_LINK_STATE_P3P_MASK 0xf +#define XG_LINK_STATE_P3P(pcifn, val) \ + (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3P_MASK) + +#define P3P_LINK_SPEED_MHZ 100 +#define P3P_LINK_SPEED_MASK 0xff +#define P3P_LINK_SPEED_REG(pcifn) \ (CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4)) -#define P3_LINK_SPEED_VAL(pcifn, reg) \ - (((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK) +#define P3P_LINK_SPEED_VAL(pcifn, reg) \ + (((reg) >> (8 * ((pcifn) & 0x3))) & P3P_LINK_SPEED_MASK) #define QLCNIC_CAM_RAM_BASE (QLCNIC_CRB_CAM + 0x02000) #define QLCNIC_CAM_RAM(reg) (QLCNIC_CAM_RAM_BASE + (reg)) @@ -592,7 +592,7 @@ enum { #define CRB_CMDPEG_STATE (QLCNIC_REG(0x50)) #define CRB_RCVPEG_STATE (QLCNIC_REG(0x13c)) -#define CRB_XG_STATE_P3 (QLCNIC_REG(0x98)) +#define CRB_XG_STATE_P3P (QLCNIC_REG(0x98)) #define CRB_PF_LINK_SPEED_1 (QLCNIC_REG(0xe8)) #define CRB_PF_LINK_SPEED_2 (QLCNIC_REG(0xec)) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 53e805316f4a..7a47a2a7ee27 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -754,9 +754,9 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) struct qlcnic_adapter *adapter = netdev_priv(netdev); int rc = 0; - if (mtu < P3_MIN_MTU || mtu > P3_MAX_MTU) { + if (mtu < P3P_MIN_MTU || mtu > P3P_MAX_MTU) { dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes" - " not supported\n", P3_MAX_MTU, P3_MIN_MTU); + " not supported\n", P3P_MAX_MTU, P3P_MIN_MTU); return -EINVAL; } @@ -1161,31 +1161,31 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter) adapter->ahw.board_type = board_type; - if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) { + if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) { u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I); if ((gpio & 0x8000) == 0) - board_type = QLCNIC_BRDTYPE_P3_10G_TP; + board_type = QLCNIC_BRDTYPE_P3P_10G_TP; } switch (board_type) { - case QLCNIC_BRDTYPE_P3_HMEZ: - case QLCNIC_BRDTYPE_P3_XG_LOM: - case QLCNIC_BRDTYPE_P3_10G_CX4: - case QLCNIC_BRDTYPE_P3_10G_CX4_LP: - case QLCNIC_BRDTYPE_P3_IMEZ: - case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: - case QLCNIC_BRDTYPE_P3_10G_SFP_CT: - case QLCNIC_BRDTYPE_P3_10G_SFP_QT: - case QLCNIC_BRDTYPE_P3_10G_XFP: - case QLCNIC_BRDTYPE_P3_10000_BASE_T: + case QLCNIC_BRDTYPE_P3P_HMEZ: + case QLCNIC_BRDTYPE_P3P_XG_LOM: + case QLCNIC_BRDTYPE_P3P_10G_CX4: + case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: + case QLCNIC_BRDTYPE_P3P_IMEZ: + case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: + case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: + case QLCNIC_BRDTYPE_P3P_10G_XFP: + case QLCNIC_BRDTYPE_P3P_10000_BASE_T: adapter->ahw.port_type = QLCNIC_XGBE; break; - case QLCNIC_BRDTYPE_P3_REF_QG: - case QLCNIC_BRDTYPE_P3_4_GB: - case QLCNIC_BRDTYPE_P3_4_GB_MM: + case QLCNIC_BRDTYPE_P3P_REF_QG: + case QLCNIC_BRDTYPE_P3P_4_GB: + case QLCNIC_BRDTYPE_P3P_4_GB_MM: adapter->ahw.port_type = QLCNIC_GBE; break; - case QLCNIC_BRDTYPE_P3_10G_TP: + case QLCNIC_BRDTYPE_P3P_10G_TP: adapter->ahw.port_type = (adapter->portnum < 2) ? QLCNIC_XGBE : QLCNIC_GBE; break; diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 908a25b5597a..0d180c6e41fe 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -259,14 +259,14 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) switch (ring) { case RCV_RING_NORMAL: rds_ring->num_desc = adapter->num_rxd; - rds_ring->dma_size = QLCNIC_P3_RX_BUF_MAX_LEN; + rds_ring->dma_size = QLCNIC_P3P_RX_BUF_MAX_LEN; rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN; break; case RCV_RING_JUMBO: rds_ring->num_desc = adapter->num_jumbo_rxd; rds_ring->dma_size = - QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN; + QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN; if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA; -- cgit v1.2.3 From b1091fea295825d99c3f7c69a58c057e7d972389 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Thu, 7 Oct 2010 23:46:11 +0000 Subject: qlcnic: update driver version 5.0.11 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index d32531441b6a..26c37d3a5868 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 10 -#define QLCNIC_LINUX_VERSIONID "5.0.10" +#define _QLCNIC_LINUX_SUBVERSION 11 +#define QLCNIC_LINUX_VERSIONID "5.0.11" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3 From 838e7a03a31b890ee82c74039b84c05fa237bd46 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Fri, 8 Oct 2010 04:02:00 +0000 Subject: Phonet: add to MAINTAINERS and add myself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 296c3d7cdb50..ba8603ce4441 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4565,6 +4565,14 @@ L: linux-abi-devel@lists.sourceforge.net S: Maintained F: include/linux/personality.h +PHONET PROTOCOL +M: Remi Denis-Courmont +S: Supported +F: Documentation/networking/phonet.txt +F: include/linux/phonet.h +F: include/net/phonet/ +F: net/phonet/ + PHRAM MTD DRIVER M: Joern Engel L: linux-mtd@lists.infradead.org -- cgit v1.2.3 From 6d8e74ed377dd4cbad7ccc69300f734090e15c05 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Fri, 8 Oct 2010 04:02:01 +0000 Subject: Phonet: advise against enabling the pipe controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it currently is, the new code path is not compatible with existing Nokia modems. This would break existing userspace for Nokia modem, such as the existing oFono ISI driver. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig index 901956ada9c8..a4fceb8fbcc2 100644 --- a/net/phonet/Kconfig +++ b/net/phonet/Kconfig @@ -24,4 +24,5 @@ config PHONET_PIPECTRLR data with Nokia Slim modems like WG2.5 used on ST-Ericsson U8500 platform. - If unsure, say N. + This option is incompatible with older Nokia modems. + Say N here unless you really know what you are doing. -- cgit v1.2.3 From 03789f26722a15ccfe6f191e9fb3d356f2f18a1e Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Fri, 8 Oct 2010 04:02:02 +0000 Subject: Phonet: cleanup pipe enable socket option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code works like this: int garbage, status; socklen_t len = sizeof(status); /* enable pipe */ setsockopt(fd, SOL_PNPIPE, PNPIPE_ENABLE, &garbage, sizeof(garbage)); /* disable pipe */ setsockopt(fd, SOL_PNPIPE, PNPIPE_DISABLE, &garbage, sizeof(garbage)); /* get status */ getsockopt(fd, SOL_PNPIPE, PNPIPE_INQ, &status, &len); ...which does not follow the usual socket option pattern. This patch merges all three "options" into a single gettable&settable option, before Linux 2.6.37 gets out: int status; socklen_t len = sizeof(status); /* enable pipe */ status = 1; setsockopt(fd, SOL_PNPIPE, PNPIPE_ENABLE, &status, sizeof(status)); /* disable pipe */ status = 0; setsockopt(fd, SOL_PNPIPE, PNPIPE_ENABLE, &status, sizeof(status)); /* get status */ getsockopt(fd, SOL_PNPIPE, PNPIPE_ENABLE, &status, &len); This also fixes the error code from EFAULT to ENOTCONN. Signed-off-by: Rémi Denis-Courmont Cc: Kumar Sanghvi Signed-off-by: David S. Miller --- Documentation/networking/phonet.txt | 15 ++------ include/linux/phonet.h | 3 +- net/phonet/pep.c | 72 ++++++++++++++++--------------------- 3 files changed, 34 insertions(+), 56 deletions(-) diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt index cccf5ff07ec2..2d9bc2b711fc 100644 --- a/Documentation/networking/phonet.txt +++ b/Documentation/networking/phonet.txt @@ -213,12 +213,9 @@ The implementation adds socket options at SOL_PNPIPE level: It then updates the pipe state associated with the sequenced socket to be PIPE_DISABLED. - PNPIPE_ENABLE - It follows the same sequence as above for enabling a pipe by sending - PNS_PEP_ENABLE_REQ initially and then sending PNS_PEP_ENABLED_IND after - getting responses from sequenced socket and remote-pep. - It will also update the pipe state associated with the sequenced socket - to PIPE_ENABLED. + PNPIPE_ENABLE accepts one integer value (int). If set to zero, the pipe + is disabled. If the value is non-zero, the pipe is enabled. If the pipe + is not (yet) connected, ENOTCONN is error is returned. PNPIPE_DESTROY This will send out PNS_PEP_DISCONNECT_REQ on the sequenced socket and @@ -226,12 +223,6 @@ The implementation adds socket options at SOL_PNPIPE level: It will also update the pipe state associated with the sequenced socket to PIPE_IDLE - PNPIPE_INQ - This getsocktopt allows the user-space running on the sequenced socket - to examine the pipe state associated with that socket ie. whether the - pipe is created (PIPE_DISABLED) or enabled (PIPE_ENABLED) or disabled - (PIPE_DISABLED) or no pipe exists (PIPE_IDLE). - After a pipe has been created and enabled successfully, the Pipe data can be exchanged between the host-pep and remote-pep (modem). diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 96f5625d62fa..e27cbf931740 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -38,9 +38,8 @@ #define PNPIPE_IFINDEX 2 #define PNPIPE_CREATE 3 #define PNPIPE_ENABLE 4 -#define PNPIPE_DISABLE 5 +/* unused slot */ #define PNPIPE_DESTROY 6 -#define PNPIPE_INQ 7 #define PNADDR_ANY 0 #define PNADDR_BROADCAST 0xFC diff --git a/net/phonet/pep.c b/net/phonet/pep.c index aa3d8700d213..f818f76d297d 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -327,29 +327,20 @@ static int pipe_handler_send_ind(struct sock *sk, u16 dobj, u8 utid, return pn_skb_send(sk, skb, &spn); } -static int pipe_handler_enable_pipe(struct sock *sk, int cmd) +static int pipe_handler_enable_pipe(struct sock *sk, int enable) { - int ret; struct pep_sock *pn = pep_sk(sk); - - switch (cmd) { - case PNPIPE_ENABLE: - ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, - PNS_PIPE_ENABLE_UTID, PNS_PEP_ENABLE_REQ, - pn->pipe_handle, GFP_ATOMIC); - break; - - case PNPIPE_DISABLE: - ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, - PNS_PIPE_DISABLE_UTID, PNS_PEP_DISABLE_REQ, - pn->pipe_handle, GFP_ATOMIC); - break; - - default: - ret = -EINVAL; + int utid, req; + + if (enable) { + utid = PNS_PIPE_ENABLE_UTID; + req = PNS_PEP_ENABLE_REQ; + } else { + utid = PNS_PIPE_DISABLE_UTID; + req = PNS_PEP_DISABLE_REQ; } - - return ret; + return pipe_handler_send_req(sk, pn->pn_sk.sobject, utid, req, + pn->pipe_handle, GFP_ATOMIC); } static int pipe_handler_create_pipe(struct sock *sk, int pipe_handle, int cmd) @@ -1187,23 +1178,6 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, break; } - case PNPIPE_ENABLE: - if (pn->pipe_state != PIPE_DISABLED) { - err = -EFAULT; - break; - } - err = pipe_handler_enable_pipe(sk, PNPIPE_ENABLE); - break; - - case PNPIPE_DISABLE: - if (pn->pipe_state != PIPE_ENABLED) { - err = -EFAULT; - break; - } - - err = pipe_handler_enable_pipe(sk, PNPIPE_DISABLE); - break; - case PNPIPE_DESTROY: if (pn->pipe_state < PIPE_DISABLED) { err = -EFAULT; @@ -1239,6 +1213,17 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, err = 0; } goto out_norel; + +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_ENABLE: + if (pn->pipe_state <= PIPE_IDLE) { + err = -ENOTCONN; + break; + } + err = pipe_handler_enable_pipe(sk, val); + break; +#endif + default: err = -ENOPROTOOPT; } @@ -1264,15 +1249,18 @@ static int pep_getsockopt(struct sock *sk, int level, int optname, val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE; break; + case PNPIPE_IFINDEX: + val = pn->ifindex; + break; + #ifdef CONFIG_PHONET_PIPECTRLR - case PNPIPE_INQ: - val = pn->pipe_state; + case PNPIPE_ENABLE: + if (pn->pipe_state <= PIPE_IDLE) + return -ENOTCONN; + val = pn->pipe_state != PIPE_DISABLED; break; #endif - case PNPIPE_IFINDEX: - val = pn->ifindex; - break; default: return -ENOPROTOOPT; } -- cgit v1.2.3 From a131d82266e77b8eb8a2dab930a94ed0de9e91b0 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Fri, 8 Oct 2010 04:02:03 +0000 Subject: Phonet: mark the pipe controller as EXPERIMENTAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are a bunch of issues that need to be fixed, including: - GFP_KERNEL allocations from atomic context (and GFP_ATOMIC in process context), - abuse of the setsockopt() call convention, - unprotected/unlocked static variables... IMHO, we will need to alter the userspace ABI when we fix it. So mark the configuration option as EXPERIMENTAL for the time being (or should it be BROKEN instead?). Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig index a4fceb8fbcc2..0d9b8a220a78 100644 --- a/net/phonet/Kconfig +++ b/net/phonet/Kconfig @@ -16,8 +16,8 @@ config PHONET will be called phonet. If unsure, say N. config PHONET_PIPECTRLR - bool "Phonet Pipe Controller" - depends on PHONET + bool "Phonet Pipe Controller (EXPERIMENTAL)" + depends on PHONET && EXPERIMENTAL default N help The Pipe Controller implementation in Phonet stack to support Pipe -- cgit v1.2.3 From 4315d834c1496ddca977e9e22002b77c85bfec2c Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Thu, 7 Oct 2010 10:09:10 +0000 Subject: net: Fix rxq ref counting The rx->count reference is used to track reference counts to the number of rx-queue kobjects created for the device. This patch eliminates initialization of the counter in netif_alloc_rx_queues and instead increments the counter each time a kobject is created. This is now symmetric with the decrement that is done when an object is released. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 1 - net/core/net-sysfs.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 4962c8afd606..193eafaabd88 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5024,7 +5024,6 @@ static int netif_alloc_rx_queues(struct net_device *dev) return -ENOMEM; } dev->_rx = rx; - atomic_set(&rx->count, count); /* * Set a pointer to first element in the array which holds the diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index fa81fd0a488f..b143173e3eb2 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -726,6 +726,7 @@ static struct kobj_type rx_queue_ktype = { static int rx_queue_add_kobject(struct net_device *net, int index) { struct netdev_rx_queue *queue = net->_rx + index; + struct netdev_rx_queue *first = queue->first; struct kobject *kobj = &queue->kobj; int error = 0; @@ -738,6 +739,7 @@ static int rx_queue_add_kobject(struct net_device *net, int index) } kobject_uevent(kobj, KOBJ_ADD); + atomic_inc(&first->count); return error; } -- cgit v1.2.3 From e18434c45765cfc4a74b5c61da9e9fbc6ddd3d5f Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Thu, 30 Sep 2010 06:17:44 +0000 Subject: net_sched: use __TCA_HTB_MAX and TCA_HTB_MAX Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/sched/sch_htb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 4be8d04b262d..87d944941867 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1302,14 +1302,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, struct htb_class *cl = (struct htb_class *)*arg, *parent; struct nlattr *opt = tca[TCA_OPTIONS]; struct qdisc_rate_table *rtab = NULL, *ctab = NULL; - struct nlattr *tb[TCA_HTB_RTAB + 1]; + struct nlattr *tb[__TCA_HTB_MAX]; struct tc_htb_opt *hopt; /* extract all subattrs from opt attr */ if (!opt) goto failure; - err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy); + err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy); if (err < 0) goto failure; -- cgit v1.2.3 From aa3bc6c68e3c1064969f5f2962be84491ffb69a0 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 7 Oct 2010 13:14:50 +0000 Subject: ehea: simplify conditional Simplify: ((a && b) || (!a && !b)) => (a == b) Signed-off-by: Nicolas Kaiser Acked-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 15401af30108..6932578816d3 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1918,7 +1918,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) struct hcp_ehea_port_cb7 *cb7; u64 hret; - if ((enable && port->promisc) || (!enable && !port->promisc)) + if (enable == port->promisc) return; cb7 = (void *)get_zeroed_page(GFP_ATOMIC); -- cgit v1.2.3 From 2259dca36a2f0226596ea37132a46338fcff6722 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 7 Oct 2010 23:29:27 +0000 Subject: net/tg3: simplify conditional Simplify: ((a && !b) || (!a && b)) => (a != b) Signed-off-by: Nicolas Kaiser Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e5b9ec5797c1..943c28325444 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9968,8 +9968,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam if (!(phydev->supported & SUPPORTED_Pause) || (!(phydev->supported & SUPPORTED_Asym_Pause) && - ((epause->rx_pause && !epause->tx_pause) || - (!epause->rx_pause && epause->tx_pause)))) + (epause->rx_pause != epause->tx_pause))) return -EINVAL; tp->link_config.flowctrl = 0; -- cgit v1.2.3 From 7b738b55b2ec0e95a5030037c45b3c312e385789 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 9 Oct 2010 02:17:01 +0000 Subject: sundance: get_stats proper locking sundance get_stats() should not be run concurrently, add a lock to avoid potential losses. Note: Remove unused rx_lock field Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/sundance.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 27d69aaba486..4283cc52a8c9 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -365,7 +365,6 @@ struct netdev_private { struct timer_list timer; /* Media monitoring timer. */ /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; - spinlock_t rx_lock; /* Group with Tx control cache line. */ int msg_enable; int chip_id; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ @@ -390,6 +389,7 @@ struct netdev_private { unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */ struct pci_dev *pci_dev; void __iomem *base; + spinlock_t statlock; }; /* The station address location in the EEPROM. */ @@ -514,6 +514,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, np->chip_id = chip_idx; np->msg_enable = (1 << debug) - 1; spin_lock_init(&np->lock); + spin_lock_init(&np->statlock); tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev); tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long)dev); @@ -1486,10 +1487,9 @@ static struct net_device_stats *get_stats(struct net_device *dev) struct netdev_private *np = netdev_priv(dev); void __iomem *ioaddr = np->base; int i; + unsigned long flags; - /* We should lock this segment of code for SMP eventually, although - the vulnerability window is very small and statistics are - non-critical. */ + spin_lock_irqsave(&np->statlock, flags); /* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); @@ -1506,6 +1506,8 @@ static struct net_device_stats *get_stats(struct net_device *dev) dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16; + spin_unlock_irqrestore(&np->statlock, flags); + return &dev->stats; } -- cgit v1.2.3 From 5b40964eadea40509d353318d2c82e8b7bf5e8a5 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 11 Oct 2010 00:46:51 +0200 Subject: irda: Remove BKL instances from af_irda.c Most of the times, lock_kernel() was pointless or could simply be replaced by lock_sock(). Signed-off-by: Samuel Ortiz --- net/irda/af_irda.c | 370 ++++++++++++++++++++++++++++------------------------- 1 file changed, 196 insertions(+), 174 deletions(-) diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index bf3635129b17..7f097989cde2 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -715,14 +715,11 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, struct sockaddr_irda saddr; struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); - int err; - lock_kernel(); memset(&saddr, 0, sizeof(saddr)); if (peer) { - err = -ENOTCONN; if (sk->sk_state != TCP_ESTABLISHED) - goto out; + return -ENOTCONN; saddr.sir_family = AF_IRDA; saddr.sir_lsap_sel = self->dtsap_sel; @@ -739,10 +736,8 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, /* uaddr_len come to us uninitialised */ *uaddr_len = sizeof (struct sockaddr_irda); memcpy(uaddr, &saddr, *uaddr_len); - err = 0; -out: - unlock_kernel(); - return err; + + return 0; } /* @@ -758,7 +753,8 @@ static int irda_listen(struct socket *sock, int backlog) IRDA_DEBUG(2, "%s()\n", __func__); - lock_kernel(); + lock_sock(sk); + if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && (sk->sk_type != SOCK_DGRAM)) goto out; @@ -770,7 +766,7 @@ static int irda_listen(struct socket *sock, int backlog) err = 0; } out: - unlock_kernel(); + release_sock(sk); return err; } @@ -793,7 +789,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len != sizeof(struct sockaddr_irda)) return -EINVAL; - lock_kernel(); + lock_sock(sk); #ifdef CONFIG_IRDA_ULTRA /* Special care for Ultra sockets */ if ((sk->sk_type == SOCK_DGRAM) && @@ -836,7 +832,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -856,12 +852,13 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) IRDA_DEBUG(2, "%s()\n", __func__); - lock_kernel(); err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); if (err) - goto out; + return err; err = -EINVAL; + + lock_sock(sk); if (sock->state != SS_UNCONNECTED) goto out; @@ -947,7 +944,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) irda_connect_response(new); err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -981,7 +978,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, IRDA_DEBUG(2, "%s(%p)\n", __func__, self); - lock_kernel(); + lock_sock(sk); /* Don't allow connect for Ultra sockets */ err = -ESOCKTNOSUPPORT; if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) @@ -1072,6 +1069,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, if (sk->sk_state != TCP_ESTABLISHED) { sock->state = SS_UNCONNECTED; + if (sk->sk_prot->disconnect(sk, flags)) + sock->state = SS_DISCONNECTING; err = sock_error(sk); if (!err) err = -ECONNRESET; @@ -1084,7 +1083,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, self->saddr = irttp_get_saddr(self->tsap); err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1231,7 +1230,6 @@ static int irda_release(struct socket *sock) if (sk == NULL) return 0; - lock_kernel(); lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; @@ -1250,7 +1248,6 @@ static int irda_release(struct socket *sock) /* Destroy networking socket if we are the last reference on it, * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ sock_put(sk); - unlock_kernel(); /* Notes on socket locking and deallocation... - Jean II * In theory we should put pairs of sock_hold() / sock_put() to @@ -1298,7 +1295,6 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - lock_kernel(); /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | MSG_NOSIGNAL)) { @@ -1306,6 +1302,8 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; } + lock_sock(sk); + if (sk->sk_shutdown & SEND_SHUTDOWN) goto out_err; @@ -1361,14 +1359,14 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, goto out_err; } - unlock_kernel(); + release_sock(sk); /* Tell client how much data we actually sent */ return len; out_err: err = sk_stream_error(sk, msg->msg_flags, err); out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1390,14 +1388,10 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __func__); - lock_kernel(); - if ((err = sock_error(sk)) < 0) - goto out; - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); if (!skb) - goto out; + return err; skb_reset_transport_header(skb); copied = skb->len; @@ -1425,12 +1419,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, irttp_flow_request(self->tsap, FLOW_START); } } - unlock_kernel(); - return copied; -out: - unlock_kernel(); - return err; + return copied; } /* @@ -1448,17 +1438,15 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(3, "%s()\n", __func__); - lock_kernel(); if ((err = sock_error(sk)) < 0) - goto out; + return err; - err = -EINVAL; if (sock->flags & __SO_ACCEPTCON) - goto out; + return -EINVAL; err =-EOPNOTSUPP; if (flags & MSG_OOB) - goto out; + return -EOPNOTSUPP; err = 0; target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); @@ -1500,7 +1488,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, finish_wait(sk_sleep(sk), &wait); if (err) - goto out; + return err; if (sk->sk_shutdown & RCV_SHUTDOWN) break; @@ -1553,9 +1541,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } -out: - unlock_kernel(); - return err ? : copied; + return copied; } /* @@ -1573,13 +1559,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int err; - lock_kernel(); - IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - err = -EINVAL; if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - goto out; + return -EINVAL; + + lock_sock(sk); if (sk->sk_shutdown & SEND_SHUTDOWN) { send_sig(SIGPIPE, current, 0); @@ -1630,10 +1615,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); goto out; } - unlock_kernel(); + + release_sock(sk); return len; + out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1656,10 +1643,11 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - lock_kernel(); err = -EINVAL; if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - goto out; + return -EINVAL; + + lock_sock(sk); err = -EPIPE; if (sk->sk_shutdown & SEND_SHUTDOWN) { @@ -1732,7 +1720,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, if (err) IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); out: - unlock_kernel(); + release_sock(sk); return err ? : len; } #endif /* CONFIG_IRDA_ULTRA */ @@ -1747,7 +1735,7 @@ static int irda_shutdown(struct socket *sock, int how) IRDA_DEBUG(1, "%s(%p)\n", __func__, self); - lock_kernel(); + lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; @@ -1769,7 +1757,7 @@ static int irda_shutdown(struct socket *sock, int how) self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ self->saddr = 0x0; /* so IrLMP assign us any link */ - unlock_kernel(); + release_sock(sk); return 0; } @@ -1786,7 +1774,6 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __func__); - lock_kernel(); poll_wait(file, sk_sleep(sk), wait); mask = 0; @@ -1834,20 +1821,8 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, default: break; } - unlock_kernel(); - return mask; -} -static unsigned int irda_datagram_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int err; - - lock_kernel(); - err = datagram_poll(file, sock, wait); - unlock_kernel(); - - return err; + return mask; } /* @@ -1860,7 +1835,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); - lock_kernel(); err = -EINVAL; switch (cmd) { case TIOCOUTQ: { @@ -1903,7 +1877,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); err = -ENOIOCTLCMD; } - unlock_kernel(); return err; } @@ -1927,7 +1900,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon * Set some options for the socket * */ -static int __irda_setsockopt(struct socket *sock, int level, int optname, +static int irda_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; @@ -1935,13 +1908,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, struct irda_ias_set *ias_opt; struct ias_object *ias_obj; struct ias_attrib * ias_attr; /* Attribute in IAS object */ - int opt, free_ias = 0; + int opt, free_ias = 0, err = 0; IRDA_DEBUG(2, "%s(%p)\n", __func__, self); if (level != SOL_IRLMP) return -ENOPROTOOPT; + lock_sock(sk); + switch (optname) { case IRLMP_IAS_SET: /* The user want to add an attribute to an existing IAS object @@ -1951,17 +1926,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * create the right attribute... */ - if (optlen != sizeof(struct irda_ias_set)) - return -EINVAL; + if (optlen != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -1971,7 +1951,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if(ias_opt->irda_class_name[0] == '\0') { if(self->ias_obj == NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } ias_obj = self->ias_obj; } else @@ -1983,7 +1964,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* If the object doesn't exist, create it */ @@ -1993,7 +1975,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, jiffies); if (ias_obj == NULL) { kfree(ias_opt); - return -ENOMEM; + err = -ENOMEM; + goto out; } free_ias = 1; } @@ -2005,7 +1988,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj->name); kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } /* Look at the type */ @@ -2028,7 +2012,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } /* Add an octet sequence attribute */ irias_add_octseq_attrib( @@ -2060,7 +2045,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj->name); kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } irias_insert_object(ias_obj); kfree(ias_opt); @@ -2071,17 +2057,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * object is not owned by the kernel and delete it. */ - if (optlen != sizeof(struct irda_ias_set)) - return -EINVAL; + if (optlen != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -2094,7 +2085,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Only ROOT can mess with the global IAS database. @@ -2103,7 +2095,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* Find the attribute (in the object) we target */ @@ -2111,14 +2104,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Check is the user space own the object */ if(ias_attr->value->owner != IAS_USER_ATTR) { IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__); kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* Remove the attribute (and maybe the object) */ @@ -2126,11 +2121,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_opt); break; case IRLMP_MAX_SDU_SIZE: - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Only possible for a seqpacket service (TTP with SAR) */ if (sk->sk_type != SOCK_SEQPACKET) { @@ -2140,16 +2139,21 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, } else { IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n", __func__); - return -ENOPROTOOPT; + err = -ENOPROTOOPT; + goto out; } break; case IRLMP_HINTS_SET: - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } /* The input is really a (__u8 hints[2]), easier as an int */ - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Unregister any old registration */ if (self->skey) @@ -2163,12 +2167,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * making a discovery (nodes which don't match any hint * bit in the mask are not reported). */ - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } /* The input is really a (__u8 hints[2]), easier as an int */ - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Set the new hint mask */ self->mask.word = (__u16) opt; @@ -2180,19 +2188,12 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, break; default: - return -ENOPROTOOPT; + err = -ENOPROTOOPT; + break; } - return 0; -} -static int irda_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, unsigned int optlen) -{ - int err; - - lock_kernel(); - err = __irda_setsockopt(sock, level, optname, optval, optlen); - unlock_kernel(); +out: + release_sock(sk); return err; } @@ -2249,7 +2250,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, /* * Function irda_getsockopt (sock, level, optname, optval, optlen) */ -static int __irda_getsockopt(struct socket *sock, int level, int optname, +static int irda_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; @@ -2262,7 +2263,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ int val = 0; int len = 0; - int err; + int err = 0; int offset, total; IRDA_DEBUG(2, "%s(%p)\n", __func__, self); @@ -2276,15 +2277,18 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, if(len < 0) return -EINVAL; + lock_sock(sk); + switch (optname) { case IRLMP_ENUMDEVICES: /* Ask lmp for the current discovery log */ discoveries = irlmp_get_discoveries(&list.len, self->mask.word, self->nslots); /* Check if the we got some results */ - if (discoveries == NULL) - return -EAGAIN; /* Didn't find any devices */ - err = 0; + if (discoveries == NULL) { + err = -EAGAIN; + goto out; /* Didn't find any devices */ + } /* Write total list length back to client */ if (copy_to_user(optval, &list, @@ -2297,8 +2301,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, sizeof(struct irda_device_info); /* Copy the list itself - watch for overflow */ - if(list.len > 2048) - { + if (list.len > 2048) { err = -EINVAL; goto bed; } @@ -2314,17 +2317,20 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, bed: /* Free up our buffer */ kfree(discoveries); - if (err) - return err; break; case IRLMP_MAX_SDU_SIZE: val = self->max_data_size; len = sizeof(int); - if (put_user(len, optlen)) - return -EFAULT; + if (put_user(len, optlen)) { + err = -EFAULT; + goto out; + } + + if (copy_to_user(optval, &val, len)) { + err = -EFAULT; + goto out; + } - if (copy_to_user(optval, &val, len)) - return -EFAULT; break; case IRLMP_IAS_GET: /* The user want an object from our local IAS database. @@ -2332,17 +2338,22 @@ bed: * that we found */ /* Check that the user has allocated the right space for us */ - if (len != sizeof(struct irda_ias_set)) - return -EINVAL; + if (len != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -2355,7 +2366,8 @@ bed: ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Find the attribute (in the object) we target */ @@ -2363,21 +2375,23 @@ bed: ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Translate from internal to user structure */ err = irda_extract_ias_value(ias_opt, ias_attr->value); if(err) { kfree(ias_opt); - return err; + goto out; } /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); @@ -2388,17 +2402,22 @@ bed: * then wait for the answer to come back. */ /* Check that the user has allocated the right space for us */ - if (len != sizeof(struct irda_ias_set)) - return -EINVAL; + if (len != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* At this point, there are two cases... @@ -2419,7 +2438,8 @@ bed: daddr = ias_opt->daddr; if((!daddr) || (daddr == DEV_ADDR_ANY)) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } } @@ -2428,7 +2448,8 @@ bed: IRDA_WARNING("%s: busy with a previous query\n", __func__); kfree(ias_opt); - return -EBUSY; + err = -EBUSY; + goto out; } self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, @@ -2436,7 +2457,8 @@ bed: if (self->iriap == NULL) { kfree(ias_opt); - return -ENOMEM; + err = -ENOMEM; + goto out; } /* Treat unexpected wakeup as disconnect */ @@ -2455,7 +2477,8 @@ bed: * we can free it regardless! */ kfree(ias_opt); /* Treat signals as disconnect */ - return -EHOSTUNREACH; + err = -EHOSTUNREACH; + goto out; } /* Check what happened */ @@ -2465,9 +2488,11 @@ bed: /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) - return -EADDRNOTAVAIL; + err = -EADDRNOTAVAIL; else - return -EHOSTUNREACH; + err = -EHOSTUNREACH; + + goto out; } /* Translate from internal to user structure */ @@ -2476,14 +2501,15 @@ bed: irias_delete_value(self->ias_result); if (err) { kfree(ias_opt); - return err; + goto out; } /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); @@ -2504,11 +2530,15 @@ bed: */ /* Check that the user is passing us an int */ - if (len != sizeof(int)) - return -EINVAL; + if (len != sizeof(int)) { + err = -EINVAL; + goto out; + } /* Get timeout in ms (max time we block the caller) */ - if (get_user(val, (int __user *)optval)) - return -EFAULT; + if (get_user(val, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Tell IrLMP we want to be notified */ irlmp_update_client(self->ckey, self->mask.word, @@ -2520,8 +2550,6 @@ bed: /* Wait until a node is discovered */ if (!self->cachedaddr) { - int ret = 0; - IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__); /* Set watchdog timer to expire in ms. */ @@ -2534,7 +2562,7 @@ bed: /* Wait for IR-LMP to call us back */ __wait_event_interruptible(self->query_wait, (self->cachedaddr != 0 || self->errno == -ETIME), - ret); + err); /* If watchdog is still activated, kill it! */ if(timer_pending(&(self->watchdog))) @@ -2542,8 +2570,8 @@ bed: IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__); - if (ret != 0) - return ret; + if (err != 0) + goto out; } else IRDA_DEBUG(1, "%s(), found immediately !\n", @@ -2566,25 +2594,19 @@ bed: * If the user want more details, he should query * the whole discovery log and pick one device... */ - if (put_user(daddr, (int __user *)optval)) - return -EFAULT; + if (put_user(daddr, (int __user *)optval)) { + err = -EFAULT; + goto out; + } break; default: - return -ENOPROTOOPT; + err = -ENOPROTOOPT; } - return 0; -} - -static int irda_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) -{ - int err; +out: - lock_kernel(); - err = __irda_getsockopt(sock, level, optname, optval, optlen); - unlock_kernel(); + release_sock(sk); return err; } @@ -2628,7 +2650,7 @@ static const struct proto_ops irda_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, @@ -2652,7 +2674,7 @@ static const struct proto_ops irda_dgram_ops = { .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, @@ -2677,7 +2699,7 @@ static const struct proto_ops irda_ultra_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, -- cgit v1.2.3 From f8cba16cad68c9b9ee7fecae48a1b91708e8e482 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 5 Oct 2010 01:24:20 +0200 Subject: irda: Remove BKL instances from irnet The code intends to lock the irnet_socket, so adding a mutex to it allows for a complet BKL removal. Signed-off-by: Samuel Ortiz --- net/irda/irnet/irnet.h | 2 ++ net/irda/irnet/irnet_ppp.c | 61 +++++++++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index 4300df35d37d..0d82ff5aeff1 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h @@ -458,6 +458,8 @@ typedef struct irnet_socket int disco_index; /* Last read in the discovery log */ int disco_number; /* Size of the discovery log */ + struct mutex lock; + } irnet_socket; /* diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 69f1fa64994e..0993bd454ea5 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -480,7 +480,6 @@ dev_irnet_open(struct inode * inode, ap = kzalloc(sizeof(*ap), GFP_KERNEL); DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); - lock_kernel(); /* initialize the irnet structure */ ap->file = file; @@ -502,18 +501,20 @@ dev_irnet_open(struct inode * inode, { DERROR(FS_ERROR, "Can't setup IrDA link...\n"); kfree(ap); - unlock_kernel(); + return err; } /* For the control channel */ ap->event_index = irnet_events.index; /* Cancel all past events */ + mutex_init(&ap->lock); + /* Put our stuff where we will be able to find it later */ file->private_data = ap; DEXIT(FS_TRACE, " - ap=0x%p\n", ap); - unlock_kernel(); + return 0; } @@ -664,7 +665,9 @@ dev_irnet_ioctl( { DEBUG(FS_INFO, "Entering PPP discipline.\n"); /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/ - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + err = ppp_register_channel(&ap->chan); if(err == 0) { @@ -677,14 +680,17 @@ dev_irnet_ioctl( } else DERROR(FS_ERROR, "Can't setup PPP channel...\n"); - unlock_kernel(); + + mutex_unlock(&ap->lock); } else { /* In theory, should be N_TTY */ DEBUG(FS_INFO, "Exiting PPP discipline.\n"); /* Disconnect from the generic PPP layer */ - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open) { ap->ppp_open = 0; @@ -693,24 +699,31 @@ dev_irnet_ioctl( else DERROR(FS_ERROR, "Channel not registered !\n"); err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); } break; /* Query PPP channel and unit number */ case PPPIOCGCHAN: - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan), (int __user *)argp)) err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); break; case PPPIOCGUNIT: - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan), (int __user *)argp)) err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* All these ioctls can be passed both directly and from ppp_generic, @@ -730,9 +743,12 @@ dev_irnet_ioctl( if(!capable(CAP_NET_ADMIN)) err = -EPERM; else { - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + err = ppp_irnet_ioctl(&ap->chan, cmd, arg); - unlock_kernel(); + + mutex_unlock(&ap->lock); } break; @@ -740,7 +756,9 @@ dev_irnet_ioctl( /* Get termios */ case TCGETS: DEBUG(FS_INFO, "Get termios.\n"); - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + #ifndef TCGETS2 if(!kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios)) err = 0; @@ -748,12 +766,15 @@ dev_irnet_ioctl( if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios)) err = 0; #endif - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* Set termios */ case TCSETSF: DEBUG(FS_INFO, "Set termios.\n"); - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + #ifndef TCGETS2 if(!user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp)) err = 0; @@ -761,7 +782,8 @@ dev_irnet_ioctl( if(!user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp)) err = 0; #endif - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* Set DTR/RTS */ @@ -784,9 +806,10 @@ dev_irnet_ioctl( * We should also worry that we don't accept junk here and that * we get rid of our own buffers */ #ifdef FLUSH_TO_PPP - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; ppp_output_wakeup(&ap->chan); - unlock_kernel(); + mutex_unlock(&ap->lock); #endif /* FLUSH_TO_PPP */ err = 0; break; -- cgit v1.2.3 From 3b06dbbeadb6488cd00999b61b080bb6f0218503 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 5 Oct 2010 01:30:02 +0200 Subject: irda: Test index before read in stir421x_patch_device() Test whether index exceeds fw->size before reading the element Signed-off-by: Roel Kluin Signed-off-by: Samuel Ortiz --- drivers/net/irda/irda-usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index cce82f101f50..e4ea61944c22 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1124,11 +1124,11 @@ static int stir421x_patch_device(struct irda_usb_cb *self) * The actual image starts after the "STMP" keyword * so forward to the firmware header tag */ - for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) && - (i < fw->size); i++) ; + for (i = 0; i < fw->size && fw->data[i] != + STIR421X_PATCH_END_OF_HDR_TAG; i++) ; /* here we check for the out of buffer case */ - if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) && - (i < STIR421X_PATCH_CODE_OFFSET)) { + if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size && + STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) { if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG, sizeof(STIR421X_PATCH_STMP_TAG) - 1)) { -- cgit v1.2.3 From efc463eb508798da4243625b08c7396462cabf9f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 11 Oct 2010 01:17:56 +0200 Subject: irda: Fix parameter extraction stack overflow Cc: stable@kernel.org Reported-by: Ilja Van Sprundel Signed-off-by: Samuel Ortiz --- net/irda/parameters.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/irda/parameters.c b/net/irda/parameters.c index fc1a20565e2d..71cd38c1a67f 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -298,6 +298,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, p.pi = pi; /* In case handler needs to know */ p.pl = buf[1]; /* Extract length of value */ + if (p.pl > 32) + p.pl = 32; IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__, p.pi, p.pl); @@ -318,7 +320,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, (__u8) str[0], (__u8) str[1]); /* Null terminate string */ - str[p.pl+1] = '\0'; + str[p.pl] = '\0'; p.pv.c = str; /* Handler will need to take a copy */ -- cgit v1.2.3 From 37f9fc452d138dfc4da2ee1ce5ae85094efc3606 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 6 Oct 2010 01:03:12 +0200 Subject: irda: Fix heap memory corruption in iriap.c While parsing the GetValuebyClass command frame, we could potentially write passed the skb->data pointer. Cc: stable@kernel.org Reported-by: Ilja Van Sprundel Signed-off-by: Samuel Ortiz --- net/irda/iriap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/irda/iriap.c b/net/irda/iriap.c index fce364c6c71a..5b743bdd89ba 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -502,7 +502,8 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); /* Make sure the string is null-terminated */ - fp[n+value_len] = 0x00; + if (n + value_len < skb->len) + fp[n + value_len] = 0x00; IRDA_DEBUG(4, "Got string %s\n", fp+n); /* Will truncate to IAS_MAX_STRING bytes */ -- cgit v1.2.3 From 34d101dd6204bd100fc2e6f7b5f9a10f959ce2c9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Oct 2010 09:16:57 -0700 Subject: neigh: speedup neigh_hh_init() When a new dst is used to send a frame, neigh_resolve_output() tries to associate an struct hh_cache to this dst, calling neigh_hh_init() with the neigh rwlock write locked. Most of the time, hh_cache is already known and linked into neighbour, so we find it and increment its refcount. This patch changes the logic so that we call neigh_hh_init() with neighbour lock read locked only, so that fast path can be run in parallel by concurrent cpus. This brings part of the speedup we got with commit c7d4426a98a5f (introduce DST_NOCACHE flag) for non cached dsts, even for cached ones, removing one of the contention point that routers hit on multiqueue enabled machines. Further improvements would need to use a seqlock instead of an rwlock to protect neigh->ha[], to not dirty neigh too often and remove two atomic ops. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 6 +++ net/core/dst.c | 4 +- net/core/neighbour.c | 99 +++++++++++++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 40 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 6abcef67b178..4160db3721ba 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -281,6 +281,12 @@ struct hh_cache { unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; }; +static inline void hh_cache_put(struct hh_cache *hh) +{ + if (atomic_dec_and_test(&hh->hh_refcnt)) + kfree(hh); +} + /* Reserve HH_DATA_MOD byte aligned hard_header_len, but at least that much. * Alternative is: * dev->hard_header_len ? (dev->hard_header_len + diff --git a/net/core/dst.c b/net/core/dst.c index 6c41b1fac3db..978a1ee1f7d0 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -228,8 +228,8 @@ again: child = dst->child; dst->hh = NULL; - if (hh && atomic_dec_and_test(&hh->hh_refcnt)) - kfree(hh); + if (hh) + hh_cache_put(hh); if (neigh) { dst->neighbour = NULL; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 3ffafaa0414c..2044906ecd1a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -709,8 +709,7 @@ void neigh_destroy(struct neighbour *neigh) write_seqlock_bh(&hh->hh_lock); hh->hh_output = neigh_blackhole; write_sequnlock_bh(&hh->hh_lock); - if (atomic_dec_and_test(&hh->hh_refcnt)) - kfree(hh); + hh_cache_put(hh); } skb_queue_purge(&neigh->arp_queue); @@ -1210,39 +1209,67 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, } EXPORT_SYMBOL(neigh_event_ns); +static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, + __be16 protocol) +{ + struct hh_cache *hh; + + for (hh = n->hh; hh; hh = hh->hh_next) { + if (hh->hh_type == protocol) { + atomic_inc(&hh->hh_refcnt); + if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) + hh_cache_put(hh); + return true; + } + } + return false; +} + +/* called with read_lock_bh(&n->lock); */ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, __be16 protocol) { struct hh_cache *hh; struct net_device *dev = dst->dev; - for (hh = n->hh; hh; hh = hh->hh_next) - if (hh->hh_type == protocol) - break; + if (likely(neigh_hh_lookup(n, dst, protocol))) + return; - if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) { - seqlock_init(&hh->hh_lock); - hh->hh_type = protocol; - atomic_set(&hh->hh_refcnt, 0); - hh->hh_next = NULL; + /* slow path */ + hh = kzalloc(sizeof(*hh), GFP_ATOMIC); + if (!hh) + return; - if (dev->header_ops->cache(n, hh)) { - kfree(hh); - hh = NULL; - } else { - atomic_inc(&hh->hh_refcnt); - hh->hh_next = n->hh; - n->hh = hh; - if (n->nud_state & NUD_CONNECTED) - hh->hh_output = n->ops->hh_output; - else - hh->hh_output = n->ops->output; - } + seqlock_init(&hh->hh_lock); + hh->hh_type = protocol; + atomic_set(&hh->hh_refcnt, 2); + + if (dev->header_ops->cache(n, hh)) { + kfree(hh); + return; } - if (hh) { - atomic_inc(&hh->hh_refcnt); - dst->hh = hh; + read_unlock(&n->lock); + write_lock(&n->lock); + + /* must check if another thread already did the insert */ + if (neigh_hh_lookup(n, dst, protocol)) { + kfree(hh); + goto end; } + + if (n->nud_state & NUD_CONNECTED) + hh->hh_output = n->ops->hh_output; + else + hh->hh_output = n->ops->output; + + hh->hh_next = n->hh; + n->hh = hh; + + if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) + hh_cache_put(hh); +end: + write_unlock(&n->lock); + read_lock(&n->lock); } /* This function can be used in contexts, where only old dev_queue_xmit @@ -1281,21 +1308,17 @@ int neigh_resolve_output(struct sk_buff *skb) if (!neigh_event_send(neigh, skb)) { int err; struct net_device *dev = neigh->dev; + + read_lock_bh(&neigh->lock); if (dev->header_ops->cache && !dst->hh && - !(dst->flags & DST_NOCACHE)) { - write_lock_bh(&neigh->lock); - if (!dst->hh) - neigh_hh_init(neigh, dst, dst->ops->protocol); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - write_unlock_bh(&neigh->lock); - } else { - read_lock_bh(&neigh->lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - read_unlock_bh(&neigh->lock); - } + !(dst->flags & DST_NOCACHE)) + neigh_hh_init(neigh, dst, dst->ops->protocol); + + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); + read_unlock_bh(&neigh->lock); + if (err >= 0) rc = neigh->ops->queue_xmit(skb); else -- cgit v1.2.3 From 419c20465d6319274e7286f0966e2390540e6e0a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 10 Oct 2010 23:26:56 +0000 Subject: NET: pch, fix use after free Stanse found that pch_gbe_xmit_frame uses skb after it is freed. Fix that. Signed-off-by: Jiri Slaby Cc: Masayuki Ohtake Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 53c56cf8aca2..e44644f169fd 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -1847,9 +1847,9 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) unsigned long flags; if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) { - dev_kfree_skb_any(skb); pr_err("Transfer length Error: skb len: %d > max: %d\n", skb->len, adapter->hw.mac.max_frame_size); + dev_kfree_skb_any(skb); adapter->stats.tx_length_errors++; return NETDEV_TX_OK; } -- cgit v1.2.3 From 7623225f905263424c7254dc6a07bff083a498dd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 11 Oct 2010 14:46:52 -0400 Subject: Revert "wireless: Use first phyX name available when registering phy devices." This reverts commit 5a254ffe3ffdfa84fe076009bd8e88da412180d2. The commit failed to take into account that allocated wireless devices (wiphys) are not added into the device list upon allocation, but only when they are registered. Therefore, it opened up a race between allocating and registering a name, so that if two processes allocate and register concurrently ("alloc, alloc, register, register" rather than "alloc, register, alloc, register") the code will attempt to use the same name twice. Signed-off-by: Johannes Berg --- net/wireless/core.c | 54 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 1684ad91763c..9c21ebf9780e 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, char *newname) { struct cfg80211_registered_device *rdev2; - int result; + int wiphy_idx, taken = -1, result, digits; assert_cfg80211_lock(); + /* prohibit calling the thing phy%d when %d is not its number */ + sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); + if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { + /* count number of places needed to print wiphy_idx */ + digits = 1; + while (wiphy_idx /= 10) + digits++; + /* + * deny the name if it is phy where is printed + * without leading zeroes. taken == strlen(newname) here + */ + if (taken == strlen(PHY_NAME) + digits) + return -EINVAL; + } + + /* Ignore nop renames */ if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) return 0; @@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, /* Ensure another device does not already have this name. */ list_for_each_entry(rdev2, &cfg80211_rdev_list, list) if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) - return -EEXIST; + return -EINVAL; result = device_rename(&rdev->wiphy.dev, newname); if (result) @@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work) struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) { static int wiphy_counter; - int i; - struct cfg80211_registered_device *rdev, *rdev2; + + struct cfg80211_registered_device *rdev; int alloc_size; - char nname[IFNAMSIZ + 1]; - bool found = false; WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); @@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { wiphy_counter--; - goto too_many_devs; - } - - /* 64k wiphy devices is enough for anyone! */ - for (i = 0; i < 0xFFFF; i++) { - found = false; - snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i); - nname[sizeof(nname)-1] = 0; - list_for_each_entry(rdev2, &cfg80211_rdev_list, list) - if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) { - found = true; - break; - } - - if (!found) - break; - } - - if (unlikely(found)) { -too_many_devs: mutex_unlock(&cfg80211_mutex); - /* ugh, too many devices already! */ + /* ugh, wrapped! */ kfree(rdev); return NULL; } - /* give it a proper name */ - dev_set_name(&rdev->wiphy.dev, "%s", nname); - mutex_unlock(&cfg80211_mutex); + /* give it a proper name */ + dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + mutex_init(&rdev->mtx); mutex_init(&rdev->devlist_mtx); INIT_LIST_HEAD(&rdev->netdev_list); -- cgit v1.2.3 From b38afa87698375179026224522c2e48dcbf17e65 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 7 Oct 2010 16:12:06 -0700 Subject: mac80211: Improve mlme probe response log messages. Old messages didn't mention the device in question. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5695c94c49aa..a3a9421555af 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "No probe response from AP %pM" - " after %dms, try %d\n", bssid, - (1000 * IEEE80211_PROBE_WAIT)/HZ, - ifmgd->probe_send_count); + wiphy_debug(local->hw.wiphy, + "%s: No probe response from AP %pM" + " after %dms, try %d\n", + sdata->name, + bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, + ifmgd->probe_send_count); #endif ieee80211_mgd_probe_ap_send(sdata); } else { @@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) */ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); - printk(KERN_DEBUG "No probe response from AP %pM" - " after %dms, disconnecting.\n", - bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); + wiphy_debug(local->hw.wiphy, + "%s: No probe response from AP %pM" + " after %dms, disconnecting.\n", + sdata->name, + bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); mutex_lock(&local->mtx); -- cgit v1.2.3 From 5a5c731aa59cc2c44ca20f45b1a577cd4f5435e2 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 7 Oct 2010 16:39:20 -0700 Subject: wireless: Set some stats used by /proc/net/wireless (wext) Some stats for /proc/net/wireless (and wext in general) are not being set. This patch addresses a few of those with values easily obtained from mac80211 core. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 ++++ net/mac80211/cfg.c | 4 +++- net/wireless/wext-compat.c | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0778d04b3bbe..f920a06f363e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -403,6 +403,7 @@ struct station_parameters { * @STATION_INFO_TX_PACKETS: @tx_packets filled * @STATION_INFO_TX_RETRIES: @tx_retries filled * @STATION_INFO_TX_FAILED: @tx_failed filled + * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -417,6 +418,7 @@ enum station_info_flags { STATION_INFO_TX_PACKETS = 1<<9, STATION_INFO_TX_RETRIES = 1<<10, STATION_INFO_TX_FAILED = 1<<11, + STATION_INFO_RX_DROP_MISC = 1<<12, }; /** @@ -468,6 +470,7 @@ struct rate_info { * @tx_packets: packets transmitted to this station * @tx_retries: cumulative retry counts * @tx_failed: number of failed transmissions (retries exceeded, no ACK) + * @rx_dropped_misc: Dropped for un-specified reason. * @generation: generation number for nl80211 dumps. * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that @@ -487,6 +490,7 @@ struct station_info { u32 tx_packets; u32 tx_retries; u32 tx_failed; + u32 rx_dropped_misc; int generation; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ecf9b7166ed1..25fb351e00f8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_PACKETS | STATION_INFO_TX_RETRIES | STATION_INFO_TX_FAILED | - STATION_INFO_TX_BITRATE; + STATION_INFO_TX_BITRATE | + STATION_INFO_RX_DROP_MISC; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; @@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->tx_packets = sta->tx_packets; sinfo->tx_retries = sta->tx_retry_count; sinfo->tx_failed = sta->tx_retry_failed; + sinfo->rx_dropped_misc = sta->rx_dropped; if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6002265289c6..12222ee6ebf2 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) } wstats.qual.updated |= IW_QUAL_NOISE_INVALID; + if (sinfo.filled & STATION_INFO_RX_DROP_MISC) + wstats.discard.misc = sinfo.rx_dropped_misc; + if (sinfo.filled & STATION_INFO_TX_FAILED) + wstats.discard.retries = sinfo.tx_failed; return &wstats; } -- cgit v1.2.3 From 92c68a66a8f73c51f062ae8cae958c86a21fea78 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 8 Oct 2010 09:43:29 -0700 Subject: ath5k: Print out opmode in debugfs. Helps debug multi-VIF scenarios. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 10 ++++++++++ drivers/net/wireless/ath/debug.c | 29 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/debug.h | 3 +++ 3 files changed, 42 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index c2d549f871f9..a342a9da1b3e 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -60,6 +60,7 @@ #include "base.h" #include "debug.h" +#include "../debug.h" static unsigned int ath5k_debug; module_param_named(debug, ath5k_debug, uint, 0); @@ -492,6 +493,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, char buf[700]; unsigned int len = 0; u32 filt = ath5k_hw_get_rx_filter(sc->ah); + const char *tmp; len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", sc->bssidmask); @@ -524,6 +526,14 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, else len += snprintf(buf+len, sizeof(buf)-len, "\n"); + tmp = ath_opmode_to_string(sc->opmode); + if (tmp) + len += snprintf(buf+len, sizeof(buf)-len, "opmode: %s\n", + tmp); + else + len += snprintf(buf+len, sizeof(buf)-len, + "opmode: UNKNOWN-%i\n", sc->opmode); + if (len > sizeof(buf)) len = sizeof(buf); diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c index 53e77bd131b9..a9eb7876dbe1 100644 --- a/drivers/net/wireless/ath/debug.c +++ b/drivers/net/wireless/ath/debug.c @@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) va_end(args); } EXPORT_SYMBOL(ath_print); + +const char *ath_opmode_to_string(enum nl80211_iftype opmode) +{ + switch (opmode) { + case NL80211_IFTYPE_UNSPECIFIED: + return "UNSPEC"; + case NL80211_IFTYPE_ADHOC: + return "ADHOC"; + case NL80211_IFTYPE_STATION: + return "STATION"; + case NL80211_IFTYPE_AP: + return "AP"; + case NL80211_IFTYPE_AP_VLAN: + return "AP-VLAN"; + case NL80211_IFTYPE_WDS: + return "WDS"; + case NL80211_IFTYPE_MONITOR: + return "MONITOR"; + case NL80211_IFTYPE_MESH_POINT: + return "MESH"; + case NL80211_IFTYPE_P2P_CLIENT: + return "P2P-CLIENT"; + case NL80211_IFTYPE_P2P_GO: + return "P2P-GO"; + default: + return NULL; + } +} +EXPORT_SYMBOL(ath_opmode_to_string); diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index fd3a020682dc..a3a5a628d24d 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -77,4 +77,7 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) } #endif /* CONFIG_ATH_DEBUG */ +/** Returns string describing opmode, or NULL if unknown mode. */ +const char *ath_opmode_to_string(enum nl80211_iftype opmode); + #endif /* ATH_DEBUG_H */ -- cgit v1.2.3 From 62c58fb4316905cd9c1dbf01967935ed5610b45d Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 8 Oct 2010 12:01:15 -0700 Subject: ath5k: Adjust opmode when interfaces are removed. Otherwise, if there is an AP and a STATION, and AP is removed, the NIC will not revert back to STATION mode. Reported-by: Eliad Peller Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 66 +++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index dad726585637..c9732a6ce87f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -62,6 +62,7 @@ #include "reg.h" #include "debug.h" #include "ani.h" +#include "../debug.h" static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); @@ -517,12 +518,14 @@ struct ath_vif_iter_data { bool need_set_hw_addr; bool found_active; bool any_assoc; + enum nl80211_iftype opmode; }; static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { struct ath_vif_iter_data *iter_data = data; int i; + struct ath5k_vif *avf = (void *)vif->drv_priv; if (iter_data->hw_macaddr) for (i = 0; i < ETH_ALEN; i++) @@ -539,13 +542,34 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->need_set_hw_addr = false; if (!iter_data->any_assoc) { - struct ath5k_vif *avf = (void *)vif->drv_priv; if (avf->assoc) iter_data->any_assoc = true; } + + /* Calculate combined mode - when APs are active, operate in AP mode. + * Otherwise use the mode of the new interface. This can currently + * only deal with combinations of APs and STAs. Only one ad-hoc + * interfaces is allowed above. + */ + if (avf->opmode == NL80211_IFTYPE_AP) + iter_data->opmode = NL80211_IFTYPE_AP; + else + if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) + iter_data->opmode = avf->opmode; } -void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif) +static void ath_do_set_opmode(struct ath5k_softc *sc) +{ + struct ath5k_hw *ah = sc->ah; + ath5k_hw_set_opmode(ah, sc->opmode); + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", + sc->opmode, + ath_opmode_to_string(sc->opmode) ? + ath_opmode_to_string(sc->opmode) : "UKNOWN"); +} + +void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif) { struct ath_common *common = ath5k_hw_common(sc->ah); struct ath_vif_iter_data iter_data; @@ -558,6 +582,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif) memset(&iter_data.mask, 0xff, ETH_ALEN); iter_data.found_active = false; iter_data.need_set_hw_addr = true; + iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; if (vif) ath_vif_iter(&iter_data, vif->addr, vif); @@ -567,10 +592,18 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif) &iter_data); memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); + sc->opmode = iter_data.opmode; + if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED) + /* Nothing active, default to station mode */ + sc->opmode = NL80211_IFTYPE_STATION; + + ath_do_set_opmode(sc); + if (iter_data.need_set_hw_addr && iter_data.found_active) ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); - ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); + if (ath5k_hw_hasbssidmask(sc->ah)) + ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); } static void @@ -582,15 +615,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) /* configure rx filter */ rfilt = sc->filter_flags; ath5k_hw_set_rx_filter(ah, rfilt); - - if (ath5k_hw_hasbssidmask(ah)) - ath5k_update_bssid_mask(sc, vif); - - /* configure operational mode */ - ath5k_hw_set_opmode(ah, sc->opmode); - - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); + + ath5k_update_bssid_mask_and_opmode(sc, vif); } static inline int @@ -2688,7 +2715,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) SET_IEEE80211_PERM_ADDR(hw, mac); memcpy(&sc->lladdr, mac, ETH_ALEN); /* All MAC address bits matter for ACKs */ - ath5k_update_bssid_mask(sc, NULL); + ath5k_update_bssid_mask_and_opmode(sc, NULL); regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); @@ -2786,7 +2813,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, { struct ath5k_softc *sc = hw->priv; int ret; - struct ath5k_hw *ah = sc->ah; struct ath5k_vif *avf = (void *)vif->drv_priv; mutex_lock(&sc->lock); @@ -2850,18 +2876,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, sc->num_adhoc_vifs++; } - /* Set combined mode - when APs are configured, operate in AP mode. - * Otherwise use the mode of the new interface. This can currently - * only deal with combinations of APs and STAs. Only one ad-hoc - * interfaces is allowed above. - */ - if (sc->num_ap_vifs) - sc->opmode = NL80211_IFTYPE_AP; - else - sc->opmode = vif->type; - - ath5k_hw_set_opmode(ah, sc->opmode); - /* Any MAC address is fine, all others are included through the * filter. */ @@ -2905,7 +2919,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw, else if (avf->opmode == NL80211_IFTYPE_ADHOC) sc->num_adhoc_vifs--; - ath5k_update_bssid_mask(sc, NULL); + ath5k_update_bssid_mask_and_opmode(sc, NULL); mutex_unlock(&sc->lock); } -- cgit v1.2.3 From dfdac8ac033c9ad048a5c68563bd41bda6c5e60b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Oct 2010 22:13:51 +0200 Subject: ath9k_hw: store the clock rate in common data on channel changes Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 ++ drivers/net/wireless/ath/ath9k/ani.c | 26 ++------------------------ drivers/net/wireless/ath/ath9k/hw.c | 32 +++++++++++++++++++------------- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index cee0191704f5..b36d9d770ff1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -145,6 +145,8 @@ struct ath_common { DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; + unsigned int clockrate; + struct ath_regulatory regulatory; const struct ath_ops *ops; const struct ath_bus_ops *bus_ops; diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index f2a907b4acb8..f2aa68405d2f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -465,35 +465,13 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); } -static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) -{ - struct ath9k_channel *chan = ah->curchan; - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - u8 clockrate; /* in MHz */ - - if (!ah->curchan) /* should really check for CCK instead */ - clockrate = ATH9K_CLOCK_RATE_CCK; - else if (conf->channel->band == IEEE80211_BAND_2GHZ) - clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; - else if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; - else - clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; - - if (conf_is_ht40(conf)) - return clockrate * 2; - - return clockrate; -} - static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) { + struct ath_common *common = ath9k_hw_common(ah); int32_t listen_time; - int32_t clock_rate; ath9k_hw_update_cycle_counters(ah); - clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000; - listen_time = ah->listen_time / clock_rate; + listen_time = ah->listen_time / (common->clockrate * 1000); ah->listen_time = 0; return listen_time; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 05e9935ef160..f5d79177770c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) /* Helper Functions */ /********************/ -static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) +static void ath9k_hw_set_clockrate(struct ath_hw *ah) { struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ath_common *common = ath9k_hw_common(ah); + unsigned int clockrate; if (!ah->curchan) /* should really check for CCK instead */ - return usecs *ATH9K_CLOCK_RATE_CCK; - if (conf->channel->band == IEEE80211_BAND_2GHZ) - return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; - - if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) - return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; + clockrate = ATH9K_CLOCK_RATE_CCK; + else if (conf->channel->band == IEEE80211_BAND_2GHZ) + clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; + else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) + clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; else - return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; + clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; + + if (conf_is_ht40(conf)) + clockrate *= 2; + + common->clockrate = clockrate; } static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) { - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ath_common *common = ath9k_hw_common(ah); - if (conf_is_ht40(conf)) - return ath9k_hw_mac_clks(ah, usecs) * 2; - else - return ath9k_hw_mac_clks(ah, usecs); + return usecs * common->clockrate; } bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) @@ -1156,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, "Failed to set channel\n"); return false; } + ath9k_hw_set_clockrate(ah); ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(regulatory, chan), @@ -1368,6 +1372,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (r) return r; + ath9k_hw_set_clockrate(ah); + ENABLE_REGWRITE_BUFFER(ah); for (i = 0; i < AR_NUM_DCU; i++) -- cgit v1.2.3 From 9d119f3ebd074bde0b801f476a44ca60d222efb2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Oct 2010 22:13:52 +0200 Subject: ath5k: store the clock rate in common data on channel changes Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 13 ++++++++----- drivers/net/wireless/ath/ath5k/phy.c | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 0cba2e315d9a..4a367cdb3eb9 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1201,7 +1201,7 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); /* Clock rate related functions */ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); -unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); +void ath5k_hw_set_clockrate(struct ath5k_hw *ah); /* Queue Control Unit, DFS Control Unit Functions */ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 095d30b50ec7..074b4c644399 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) */ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) { - return usec * ath5k_hw_get_clockrate(ah); + struct ath_common *common = ath5k_hw_common(ah); + return usec * common->clockrate; } /** @@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) */ unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) { - return clock / ath5k_hw_get_clockrate(ah); + struct ath_common *common = ath5k_hw_common(ah); + return clock / common->clockrate; } /** - * ath5k_hw_get_clockrate - Get the clock rate for current mode + * ath5k_hw_set_clockrate - Set common->clockrate for the current channel * * @ah: The &struct ath5k_hw */ -unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) +void ath5k_hw_set_clockrate(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; + struct ath_common *common = ath5k_hw_common(ah); int clock; if (channel->hw_value & CHANNEL_5GHZ) @@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) if (channel->hw_value & CHANNEL_TURBO) clock *= 2; - return clock; + common->clockrate = clock; } /** diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 61da913e7c8f..219367884e64 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) ah->ah_current_channel = channel; ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; + ath5k_hw_set_clockrate(ah); return 0; } -- cgit v1.2.3 From b5bfc5683db44a121ad47ec0a9f4efd4aac040e0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Oct 2010 22:13:53 +0200 Subject: ath9k_hw: move the cycle counter tracking to ath Instead of keeping track of wraparound, clear the counters on every access and keep separate deltas for ANI and later survey use. Also moves the function for calculating the 'listen time' for ANI Signed-off-by: Felix Fietkau Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 14 +++++++ drivers/net/wireless/ath/ath9k/ani.c | 64 ++--------------------------- drivers/net/wireless/ath/ath9k/ani.h | 8 ---- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 7 ++-- drivers/net/wireless/ath/ath9k/hw.h | 2 - drivers/net/wireless/ath/ath9k/main.c | 12 +++++- drivers/net/wireless/ath/ath9k/reg.h | 11 ----- drivers/net/wireless/ath/hw.c | 59 ++++++++++++++++++++++++++ drivers/net/wireless/ath/reg.h | 11 +++++ 9 files changed, 101 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index b36d9d770ff1..501050c0296f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -19,6 +19,7 @@ #include #include +#include #include /* @@ -42,6 +43,13 @@ struct ath_ani { struct timer_list timer; }; +struct ath_cycle_counters { + u32 cycles; + u32 rx_busy; + u32 rx_frame; + u32 tx_frame; +}; + enum ath_device_state { ATH_HW_UNAVAILABLE, ATH_HW_INITIALIZED, @@ -147,6 +155,10 @@ struct ath_common { unsigned int clockrate; + spinlock_t cc_lock; + struct ath_cycle_counters cc_ani; + struct ath_cycle_counters cc_survey; + struct ath_regulatory regulatory; const struct ath_ops *ops; const struct ath_bus_ops *bus_ops; @@ -163,5 +175,7 @@ int ath_key_config(struct ath_common *common, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); bool ath_hw_keyreset(struct ath_common *common, u16 entry); +void ath_hw_cycle_counters_update(struct ath_common *common); +int32_t ath_hw_get_listen_time(struct ath_common *common); #endif /* ATH_H */ diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index f2aa68405d2f..3aa8fb1ad77f 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -465,18 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); } -static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - int32_t listen_time; - - ath9k_hw_update_cycle_counters(ah); - listen_time = ah->listen_time / (common->clockrate * 1000); - ah->listen_time = 0; - - return listen_time; -} - static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) { struct ar5416AniState *aniState; @@ -655,7 +643,9 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah) u32 phyCnt1, phyCnt2; int32_t listenTime; - listenTime = ath9k_hw_ani_get_listen_time(ah); + ath_hw_cycle_counters_update(common); + listenTime = ath_hw_get_listen_time(common); + if (listenTime < 0) { ah->stats.ast_ani_lneg++; ath9k_ani_restart(ah); @@ -796,54 +786,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); -void ath9k_hw_update_cycle_counters(struct ath_hw *ah) -{ - struct ath_cycle_counters cc; - bool clear; - - memcpy(&cc, &ah->cc, sizeof(cc)); - - /* freeze counters */ - REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); - - ah->cc.cycles = REG_READ(ah, AR_CCCNT); - if (ah->cc.cycles < cc.cycles) { - clear = true; - goto skip; - } - - ah->cc.rx_clear = REG_READ(ah, AR_RCCNT); - ah->cc.rx_frame = REG_READ(ah, AR_RFCNT); - ah->cc.tx_frame = REG_READ(ah, AR_TFCNT); - - /* prevent wraparound */ - if (ah->cc.cycles & BIT(31)) - clear = true; - -#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field - CC_DELTA(cycles, AR_CCCNT); - CC_DELTA(rx_frame, AR_RFCNT); - CC_DELTA(rx_clear, AR_RCCNT); - CC_DELTA(tx_frame, AR_TFCNT); -#undef CC_DELTA - - ah->listen_time += (ah->cc.cycles - cc.cycles) - - ((ah->cc.rx_frame - cc.rx_frame) + - (ah->cc.tx_frame - cc.tx_frame)); - -skip: - if (clear) { - REG_WRITE(ah, AR_CCCNT, 0); - REG_WRITE(ah, AR_RFCNT, 0); - REG_WRITE(ah, AR_RCCNT, 0); - REG_WRITE(ah, AR_TFCNT, 0); - memset(&ah->cc, 0, sizeof(ah->cc)); - } - - /* unfreeze counters */ - REG_WRITE(ah, AR_MIBC, 0); -} - /* * Process a MIB interrupt. We may potentially be invoked because * any of the MIB counters overflow/trigger so don't assume we're diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 98cfd8154c71..0cd6783de883 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -93,13 +93,6 @@ struct ath9k_mib_stats { u32 beacons; }; -struct ath_cycle_counters { - u32 cycles; - u32 rx_frame; - u32 rx_clear; - u32 tx_frame; -}; - /* INI default values for ANI registers */ struct ath9k_ani_default { u16 m1ThreshLow; @@ -164,7 +157,6 @@ struct ar5416Stats { void ath9k_enable_mib_counters(struct ath_hw *ah); void ath9k_hw_disable_mib_counters(struct ath_hw *ah); -void ath9k_hw_update_cycle_counters(struct ath_hw *ah); void ath9k_hw_ani_setup(struct ath_hw *ah); void ath9k_hw_ani_init(struct ath_hw *ah); int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index efb05599b84c..669b777729b3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) "** BB mode: BB_gen_controls=0x%08x **\n", REG_READ(ah, AR_PHY_GEN_CTRL)); - ath9k_hw_update_cycle_counters(ah); -#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles) - if (ah->cc_delta.cycles) +#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles) + if (common->cc_survey.cycles) ath_print(common, ATH_DBG_RESET, "** BB busy times: rx_clear=%d%%, " "rx_frame=%d%%, tx_frame=%d%% **\n", - PCT(rx_clear), PCT(rx_frame), PCT(tx_frame)); + PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); ath_print(common, ATH_DBG_RESET, "==== BB update: done ====\n\n"); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 87627dd63463..7f696c82ca0a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -740,8 +740,6 @@ struct ath_hw { int coarse_low[5]; int firpwr[5]; enum ath9k_ani_cmd ani_function; - struct ath_cycle_counters cc, cc_delta; - int32_t listen_time; /* Bluetooth coexistance */ struct ath_btcoex_hw btcoex_hw; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 74c2dc8a8b8a..360c6f5e843a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -399,6 +399,7 @@ void ath_ani_calibrate(unsigned long data) bool aniflag = false; unsigned int timestamp = jiffies_to_msecs(jiffies); u32 cal_interval, short_cal_interval, long_cal_interval; + unsigned long flags; if (ah->caldata && ah->caldata->nfcal_interference) long_cal_interval = ATH_LONG_CALINTERVAL_INT; @@ -449,8 +450,11 @@ void ath_ani_calibrate(unsigned long data) /* Skip all processing if there's nothing to do. */ if (longcal || shortcal || aniflag) { /* Call ANI routine if necessary */ - if (aniflag) + if (aniflag) { + spin_lock_irqsave(&common->cc_lock, flags); ath9k_hw_ani_monitor(ah, ah->curchan); + spin_unlock_irqrestore(&common->cc_lock, flags); + } /* Perform calibration if necessary */ if (longcal || shortcal) { @@ -635,6 +639,7 @@ irqreturn_t ath_isr(int irq, void *dev) struct ath_softc *sc = dev; struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); enum ath9k_int status; bool sched = false; @@ -684,7 +689,12 @@ irqreturn_t ath_isr(int irq, void *dev) if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && (status & ATH9K_INT_BB_WATCHDOG)) { + + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); ar9003_hw_bb_watchdog_dbg_info(ah); + spin_unlock(&common->cc_lock); + goto chip_reset; } diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 6d01e501b9b4..017617894533 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -107,12 +107,6 @@ #define AR_RXCFG_DMASZ_256B 6 #define AR_RXCFG_DMASZ_512B 7 -#define AR_MIBC 0x0040 -#define AR_MIBC_COW 0x00000001 -#define AR_MIBC_FMC 0x00000002 -#define AR_MIBC_CMC 0x00000004 -#define AR_MIBC_MCS 0x00000008 - #define AR_TOPS 0x0044 #define AR_TOPS_MASK 0x0000FFFF @@ -1524,11 +1518,6 @@ enum { #define AR_TPC_CHIRP 0x003f0000 #define AR_TPC_CHIRP_S 0x16 -#define AR_TFCNT 0x80ec -#define AR_RFCNT 0x80f0 -#define AR_RCCNT 0x80f4 -#define AR_CCCNT 0x80f8 - #define AR_QUIET1 0x80fc #define AR_QUIET1_NEXT_QUIET_S 0 #define AR_QUIET1_NEXT_QUIET_M 0x0000ffff diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index a8f81ea09f14..183c28281385 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c @@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common) REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); } EXPORT_SYMBOL(ath_hw_setbssidmask); + + +/** + * ath_hw_cycle_counters_update - common function to update cycle counters + * + * @common: the ath_common struct for the device. + * + * This function is used to update all cycle counters in one place. + * It has to be called while holding common->cc_lock! + */ +void ath_hw_cycle_counters_update(struct ath_common *common) +{ + u32 cycles, busy, rx, tx; + void *ah = common->ah; + + /* freeze */ + REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC); + + /* read */ + cycles = REG_READ(ah, AR_CCCNT); + busy = REG_READ(ah, AR_RCCNT); + rx = REG_READ(ah, AR_RFCNT); + tx = REG_READ(ah, AR_TFCNT); + + /* clear */ + REG_WRITE(ah, 0, AR_CCCNT); + REG_WRITE(ah, 0, AR_RFCNT); + REG_WRITE(ah, 0, AR_RCCNT); + REG_WRITE(ah, 0, AR_TFCNT); + + /* unfreeze */ + REG_WRITE(ah, 0, AR_MIBC); + + /* update all cycle counters here */ + common->cc_ani.cycles += cycles; + common->cc_ani.rx_busy += busy; + common->cc_ani.rx_frame += rx; + common->cc_ani.tx_frame += tx; + + common->cc_survey.cycles += cycles; + common->cc_survey.rx_busy += busy; + common->cc_survey.rx_frame += rx; + common->cc_survey.tx_frame += tx; +} +EXPORT_SYMBOL(ath_hw_cycle_counters_update); + +int32_t ath_hw_get_listen_time(struct ath_common *common) +{ + struct ath_cycle_counters *cc = &common->cc_ani; + int32_t listen_time; + + listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) / + (common->clockrate * 1000); + + memset(cc, 0, sizeof(*cc)); + + return listen_time; +} +EXPORT_SYMBOL(ath_hw_get_listen_time); diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h index e798ef476581..298e53f3fa48 100644 --- a/drivers/net/wireless/ath/reg.h +++ b/drivers/net/wireless/ath/reg.h @@ -17,6 +17,12 @@ #ifndef ATH_REGISTERS_H #define ATH_REGISTERS_H +#define AR_MIBC 0x0040 +#define AR_MIBC_COW 0x00000001 +#define AR_MIBC_FMC 0x00000002 +#define AR_MIBC_CMC 0x00000004 +#define AR_MIBC_MCS 0x00000008 + /* * BSSID mask registers. See ath_hw_set_bssid_mask() * for detailed documentation about these registers. @@ -24,6 +30,11 @@ #define AR_BSSMSKL 0x80e0 #define AR_BSSMSKU 0x80e4 +#define AR_TFCNT 0x80ec +#define AR_RFCNT 0x80f0 +#define AR_RCCNT 0x80f4 +#define AR_CCCNT 0x80f8 + #define AR_KEYTABLE_0 0x8800 #define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) #define AR_KEY_CACHE_SIZE 128 -- cgit v1.2.3 From 7109ca5c80a0bb94378ebd7f8bb6d00edb5e6fba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Oct 2010 22:13:54 +0200 Subject: ath5k: use the common cycle counter / listen time implementation Signed-off-by: Felix Fietkau Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ani.c | 41 ++++++++++++---------------------- drivers/net/wireless/ath/ath5k/ani.h | 5 +---- drivers/net/wireless/ath/ath5k/debug.c | 21 ++++++++--------- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index e4a5f046bba4..f1419198a479 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) /** - * ath5k_hw_ani_get_listen_time() - Calculate time spent listening + * ath5k_hw_ani_get_listen_time() - Update counters and return listening time * * Return an approximation of the time spent "listening" in milliseconds (ms) - * since the last call of this function by deducting the cycles spent - * transmitting and receiving from the total cycle count. - * Save profile count values for debugging/statistics and because we might want - * to use them later. - * - * We assume no one else clears these registers! + * since the last call of this function. + * Save a snapshot of the counter values for debugging/statistics. */ static int ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) { + struct ath_common *common = ath5k_hw_common(ah); int listen; - /* freeze */ - ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); - /* read */ - as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); - as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); - as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); - as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); - /* clear */ - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); - /* un-freeze */ - ath5k_hw_reg_write(ah, 0, AR5K_MIBC); - - /* TODO: where does 44000 come from? (11g clock rate?) */ - listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000; - - if (as->pfc_cycles == 0 || listen < 0) - return 0; + spin_lock_bh(&common->cc_lock); + + ath_hw_cycle_counters_update(common); + memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); + + /* clears common->cc_ani */ + listen = ath_hw_get_listen_time(common); + + spin_unlock_bh(&common->cc_lock); + return listen; } diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h index 55cf26d8522c..d0a664039c87 100644 --- a/drivers/net/wireless/ath/ath5k/ani.h +++ b/drivers/net/wireless/ath/ath5k/ani.h @@ -75,10 +75,7 @@ struct ath5k_ani_state { unsigned int cck_errors; /* debug/statistics only: numbers from last ANI calibration */ - unsigned int pfc_tx; - unsigned int pfc_rx; - unsigned int pfc_busy; - unsigned int pfc_cycles; + struct ath_cycle_counters last_cc; unsigned int last_listen; unsigned int last_ofdm_errors; unsigned int last_cck_errors; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index a342a9da1b3e..a3b217125331 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -725,20 +725,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "beacon RSSI average:\t%d\n", sc->ah->ah_beacon_rssi_avg.avg); + +#define CC_PRINT(_struct, _field) \ + _struct._field, \ + _struct.cycles > 0 ? \ + _struct._field*100/_struct.cycles : 0 + len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", - as->pfc_tx, - as->pfc_cycles > 0 ? - as->pfc_tx*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, tx_frame)); len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", - as->pfc_rx, - as->pfc_cycles > 0 ? - as->pfc_rx*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, rx_frame)); len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", - as->pfc_busy, - as->pfc_cycles > 0 ? - as->pfc_busy*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, rx_busy)); +#undef CC_PRINT len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", - as->pfc_cycles); + as->last_cc.cycles); len += snprintf(buf+len, sizeof(buf)-len, "listen time\t\t%d\tlast: %d\n", as->listen_time, as->last_listen); -- cgit v1.2.3 From d12c74528e3065c90df70fbc06ec6ffd6e804738 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 8 Oct 2010 22:27:07 +0200 Subject: mac80211: fix possible null-pointer de-reference This patch not only fixes a null-pointer de-reference that would be triggered by a PLINK_OPEN frame with mis- matching/incompatible mesh configuration, but also responds correctly to non-compatible PLINK_OPEN frames by generating a PLINK_CLOSE with the right reason code. The original bug was detected by smatch. ( http://repo.or.cz/w/smatch.git ) net/mac80211/mesh_plink.c +574 mesh_rx_plink_frame(168) error: we previously assumed 'sta' could be null. Cc: Reviewed-and-Tested-by: Steve deRosier Reviewed-and-Tested-by: Javier Cardona Acked-by: Johannes Berg Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ea13a80a476c..1c91f0f3c307 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m enum plink_event event; enum plink_frame_type ftype; size_t baselen; - bool deactivated; + bool deactivated, matches_local = true; u8 ie_len; u8 *baseaddr; __le16 plid, llid, reason; @@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* Now we will figure out the appropriate event... */ event = PLINK_UNDEFINED; if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { + matches_local = false; switch (ftype) { case PLINK_OPEN: event = OPN_RJCT; @@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* avoid warning */ break; } - spin_lock_bh(&sta->lock); + } + + if (!sta && !matches_local) { + rcu_read_unlock(); + reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); + llid = 0; + mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, + plid, reason); + return; } else if (!sta) { /* ftype == PLINK_OPEN */ u32 rates; @@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } event = OPN_ACPT; spin_lock_bh(&sta->lock); - } else { + } else if (matches_local) { spin_lock_bh(&sta->lock); switch (ftype) { case PLINK_OPEN: @@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m rcu_read_unlock(); return; } + } else { + spin_lock_bh(&sta->lock); } mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", -- cgit v1.2.3 From 15943a72c7d2031c9150917ca9161a9f891d455a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 8 Oct 2010 22:35:09 +0200 Subject: mac80211: temporarily disable reorder release timer Several serve threading problems in the current release reorder timer implementation have been discovered. A lengthy discussion - which lists some of the pitfalls and possible solutions - can be found at: http://marc.info/?t=128635927000001 But due to the complicated nature of the subject and the imminent advent of a new -rc cycle, it was decided to disable the feature for the time being. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b67221def584..902b03ee8f60 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, tid_agg_rx->buf_size; } + /* + * Disable the reorder release timer for now. + * + * The current implementation lacks a proper locking scheme + * which would protect vital statistic and debug counters + * from being updated by two different but concurrent BHs. + * + * More information about the topic is available from: + * - thread: http://marc.info/?t=128635927000001 + * + * What was wrong: + * => http://marc.info/?l=linux-wireless&m=128636170811964 + * "Basically the thing is that until your patch, the data + * in the struct didn't actually need locking because it + * was accessed by the RX path only which is not concurrent." + * + * List of what needs to be fixed: + * => http://marc.info/?l=linux-wireless&m=128656352920957 + * + if (tid_agg_rx->stored_mpdu_num) { j = index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; @@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, } else { del_timer(&tid_agg_rx->reorder_timer); } + */ + +set_release_timer: + return; } /* -- cgit v1.2.3 From 8610c29a2c9f273886b1c31ae4d92c69d4326262 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Oct 2010 02:39:29 +0200 Subject: cfg80211: add channel utilization stats to the survey command Using these, user space can calculate a relative channel utilization with arbitrary intervals by regularly taking snapshots of the survey results. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/linux/nl80211.h | 15 +++++++++++++++ include/net/cfg80211.h | 20 ++++++++++++++++++++ net/wireless/nl80211.c | 15 +++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c08709fe36fc..0edb2566c14c 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1413,6 +1413,16 @@ enum nl80211_reg_rule_flags { * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used + * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number * currently defined * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use @@ -1422,6 +1432,11 @@ enum nl80211_survey_info { NL80211_SURVEY_INFO_FREQUENCY, NL80211_SURVEY_INFO_NOISE, NL80211_SURVEY_INFO_IN_USE, + NL80211_SURVEY_INFO_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, /* keep last */ __NL80211_SURVEY_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f920a06f363e..24d5b5869272 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -294,6 +294,11 @@ struct key_params { * * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in * @SURVEY_INFO_IN_USE: channel is currently being used + * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in + * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in + * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in + * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in + * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in * * Used by the driver to indicate which info in &struct survey_info * it has filled in during the get_survey(). @@ -301,6 +306,11 @@ struct key_params { enum survey_info_flags { SURVEY_INFO_NOISE_DBM = 1<<0, SURVEY_INFO_IN_USE = 1<<1, + SURVEY_INFO_CHANNEL_TIME = 1<<2, + SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3, + SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4, + SURVEY_INFO_CHANNEL_TIME_RX = 1<<5, + SURVEY_INFO_CHANNEL_TIME_TX = 1<<6, }; /** @@ -310,6 +320,11 @@ enum survey_info_flags { * @filled: bitflag of flags from &enum survey_info_flags * @noise: channel noise in dBm. This and all following fields are * optional + * @channel_time: amount of time in ms the radio spent on the channel + * @channel_time_busy: amount of time the primary channel was sensed busy + * @channel_time_ext_busy: amount of time the extension channel was sensed busy + * @channel_time_rx: amount of time the radio spent receiving data + * @channel_time_tx: amount of time the radio spent transmitting data * * Used by dump_survey() to report back per-channel survey information. * @@ -318,6 +333,11 @@ enum survey_info_flags { */ struct survey_info { struct ieee80211_channel *channel; + u64 channel_time; + u64 channel_time_busy; + u64 channel_time_ext_busy; + u64 channel_time_rx; + u64 channel_time_tx; u32 filled; s8 noise; }; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 882dc921103b..c506241f8637 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, survey->noise); if (survey->filled & SURVEY_INFO_IN_USE) NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, + survey->channel_time); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + survey->channel_time_busy); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + survey->channel_time_ext_busy); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + survey->channel_time_rx); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + survey->channel_time_tx); nla_nest_end(msg, infoattr); -- cgit v1.2.3 From cac4220b2e93e6344f987581d52d5bd71ff2cc0e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Oct 2010 02:39:30 +0200 Subject: ath9k: add compile time checking for the size of the channel list This prevents random memory corruption if the number of channels ever gets changed without an update to the internal channel array size. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 4 +++- drivers/net/wireless/ath/ath9k/init.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7f696c82ca0a..6b9233472fbf 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -61,6 +61,8 @@ #define ATH9K_RSSI_BAD -128 +#define ATH9K_NUM_CHANNELS 38 + /* Register read/write primitives */ #define REG_WRITE(_ah, _reg, _val) \ ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) @@ -618,7 +620,7 @@ struct ath_hw { struct ath9k_hw_version hw_version; struct ath9k_ops_config config; struct ath9k_hw_capabilities caps; - struct ath9k_channel channels[38]; + struct ath9k_channel channels[ATH9K_NUM_CHANNELS]; struct ath9k_channel *curchan; union { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d76003c06fe4..a4c5ed41b176 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -481,6 +481,10 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) { void *channels; + BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + + ARRAY_SIZE(ath9k_5ghz_chantable) != + ATH9K_NUM_CHANNELS); + if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { channels = kmemdup(ath9k_2ghz_chantable, sizeof(ath9k_2ghz_chantable), GFP_KERNEL); -- cgit v1.2.3 From 3430098ae463e31ab16926ac3eb295368a3ca5d9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Oct 2010 18:21:52 +0200 Subject: ath9k: implement channel utilization stats for survey Results for the active channel are updated whenever a new survey dump is requested, the old data is kept to allow multiple processes to make their own channel utilization averages. All other channels only contain the data for the last time that the hardware was on the channel, i.e. the last scan result or other off-channel activity. Running a background scan does not clear the data for the active channel. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 + drivers/net/wireless/ath/ath9k/main.c | 112 ++++++++++++++++++++++++++++----- 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index de2b18ee7f77..4e81fe35aa3f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -593,6 +593,8 @@ struct ath_softc { struct delayed_work wiphy_work; unsigned long wiphy_scheduler_int; int wiphy_scheduler_index; + struct survey_info *cur_survey; + struct survey_info survey[ATH9K_NUM_CHANNELS]; struct tasklet_struct intr_tq; struct tasklet_struct bcon_tasklet; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 360c6f5e843a..865649120075 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -175,6 +175,44 @@ static void ath_start_ani(struct ath_common *common) msecs_to_jiffies((u32)ah->config.ani_poll_interval)); } +static void ath_update_survey_nf(struct ath_softc *sc, int channel) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_channel *chan = &ah->channels[channel]; + struct survey_info *survey = &sc->survey[channel]; + + if (chan->noisefloor) { + survey->filled |= SURVEY_INFO_NOISE_DBM; + survey->noise = chan->noisefloor; + } +} + +static void ath_update_survey_stats(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + int pos = ah->curchan - &ah->channels[0]; + struct survey_info *survey = &sc->survey[pos]; + struct ath_cycle_counters *cc = &common->cc_survey; + unsigned int div = common->clockrate * 1000; + + ath_hw_cycle_counters_update(common); + + if (cc->cycles > 0) { + survey->filled |= SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + survey->channel_time += cc->cycles / div; + survey->channel_time_busy += cc->rx_busy / div; + survey->channel_time_rx += cc->rx_frame / div; + survey->channel_time_tx += cc->tx_frame / div; + } + memset(cc, 0, sizeof(*cc)); + + ath_update_survey_nf(sc, pos); +} + /* * Set/change channels. If the channel is really being changed, it's done * by reseting the chip. To accomplish this we must first cleanup any pending @@ -453,6 +491,7 @@ void ath_ani_calibrate(unsigned long data) if (aniflag) { spin_lock_irqsave(&common->cc_lock, flags); ath9k_hw_ani_monitor(ah, ah->curchan); + ath_update_survey_stats(sc); spin_unlock_irqrestore(&common->cc_lock, flags); } @@ -1532,7 +1571,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; bool disable_radio; @@ -1598,6 +1638,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; + int old_pos = -1; + unsigned long flags; + + if (ah->curchan) + old_pos = ah->curchan - &ah->channels[0]; aphy->chan_idx = pos; aphy->chan_is_ht = conf_is_ht(conf); @@ -1625,12 +1670,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath_update_chainmask(sc, conf_is_ht(conf)); + /* update survey stats for the old channel before switching */ + spin_lock_irqsave(&common->cc_lock, flags); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + + /* + * If the operating channel changes, change the survey in-use flags + * along with it. + * Reset the survey data for the new channel, unless we're switching + * back to the operating channel from an off-channel operation. + */ + if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && + sc->cur_survey != &sc->survey[pos]) { + + if (sc->cur_survey) + sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE; + + sc->cur_survey = &sc->survey[pos]; + + memset(sc->cur_survey, 0, sizeof(struct survey_info)); + sc->cur_survey->filled |= SURVEY_INFO_IN_USE; + } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) { + memset(&sc->survey[pos], 0, sizeof(struct survey_info)); + } + if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ath_print(common, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } + + /* + * The most recent snapshot of channel->noisefloor for the old + * channel is only available after the hardware reset. Copy it to + * the survey stats now. + */ + if (old_pos >= 0) + ath_update_survey_nf(sc, old_pos); } skip_chan_change: @@ -2000,9 +2078,15 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_supported_band *sband; - struct ath9k_channel *chan; + struct ieee80211_channel *chan; + unsigned long flags; + int pos; + + spin_lock_irqsave(&common->cc_lock, flags); + if (idx == 0) + ath_update_survey_stats(sc); sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ]; if (sband && idx >= sband->n_channels) { @@ -2013,21 +2097,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, if (!sband) sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; - if (!sband || idx >= sband->n_channels) - return -ENOENT; - - survey->channel = &sband->channels[idx]; - chan = &ah->channels[survey->channel->hw_value]; - survey->filled = 0; - - if (chan == ah->curchan) - survey->filled |= SURVEY_INFO_IN_USE; - - if (chan->noisefloor) { - survey->filled |= SURVEY_INFO_NOISE_DBM; - survey->noise = chan->noisefloor; + if (!sband || idx >= sband->n_channels) { + spin_unlock_irqrestore(&common->cc_lock, flags); + return -ENOENT; } + chan = &sband->channels[idx]; + pos = chan->hw_value; + memcpy(survey, &sc->survey[pos], sizeof(*survey)); + survey->channel = chan; + spin_unlock_irqrestore(&common->cc_lock, flags); + return 0; } -- cgit v1.2.3 From cfdfa4d3a0c7aa1287c61326a7714f262466157a Mon Sep 17 00:00:00 2001 From: Steve deRosier Date: Sat, 9 Oct 2010 17:23:28 -0700 Subject: mac80211: Update mesh constants to approved IEEE ANA values This patch updates IEEE802.11 mesh constants to be consistent with newly approved values. It modifies some values, as well as adds many new constants in preparation for updating mesh code to the current 802.11s drafts. ANA numbers were taken from: https://mentor.ieee.org/802.11/dcn/09/11-09-0031-12-0000-ana-database-assigned-number-authority.xls A few notes are in order: 1. This will break backwards compatibility with existing Linux kernels as over-the-air constants have changed. 2. Some old and obsolete constants have been retained for now as the mesh code itself hasn't been updated yet to the new 802.11s draft. This was desired to keep the existing mesh scheme working until it can be updated. Adding the approved values is the first step in updating the mesh code. 3. Obsolete constants have been clearly marked. 4. All ANA approved 802.11s constants have been added. Signed-off-by: Steve deRosier Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 71 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 97b2eae6a22c..ed5a03cbe184 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -986,6 +986,7 @@ struct ieee80211_ht_info { #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_FT 2 +#define WLAN_AUTH_SAE 3 #define WLAN_AUTH_LEAP 128 #define WLAN_AUTH_CHALLENGE_LEN 128 @@ -1072,6 +1073,10 @@ enum ieee80211_statuscode { WLAN_STATUS_NO_DIRECT_LINK = 48, WLAN_STATUS_STA_NOT_PRESENT = 49, WLAN_STATUS_STA_NOT_QSTA = 50, + /* 802.11s */ + WLAN_STATUS_ANTI_CLOG_REQUIRED = 76, + WLAN_STATUS_FCG_NOT_SUPP = 78, + WLAN_STATUS_STA_NO_TBTT = 78, }; @@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode { WLAN_REASON_QSTA_REQUIRE_SETUP = 38, WLAN_REASON_QSTA_TIMEOUT = 39, WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, + /* 802.11s */ + WLAN_REASON_MESH_PEER_CANCELED = 52, + WLAN_REASON_MESH_MAX_PEERS = 53, + WLAN_REASON_MESH_CONFIG = 54, + WLAN_REASON_MESH_CLOSE = 55, + WLAN_REASON_MESH_MAX_RETRIES = 56, + WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57, + WLAN_REASON_MESH_INVALID_GTK = 58, + WLAN_REASON_MESH_INCONSISTENT_PARAM = 59, + WLAN_REASON_MESH_INVALID_SECURITY = 60, + WLAN_REASON_MESH_PATH_ERROR = 61, + WLAN_REASON_MESH_PATH_NOFORWARD = 62, + WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63, + WLAN_REASON_MAC_EXISTS_IN_MBSS = 64, + WLAN_REASON_MESH_CHAN_REGULATORY = 65, + WLAN_REASON_MESH_CHAN = 66, }; @@ -1139,20 +1160,33 @@ enum ieee80211_eid { WLAN_EID_TS_DELAY = 43, WLAN_EID_TCLAS_PROCESSING = 44, WLAN_EID_QOS_CAPA = 46, - /* 802.11s - * - * All mesh EID numbers are pending IEEE 802.11 ANA approval. - * The numbers have been incremented from those suggested in - * 802.11s/D2.0 so that MESH_CONFIG does not conflict with - * EXT_SUPP_RATES. + /* 802.11s */ + WLAN_EID_MESH_CONFIG = 113, + WLAN_EID_MESH_ID = 114, + WLAN_EID_LINK_METRIC_REPORT = 115, + WLAN_EID_CONGESTION_NOTIFICATION = 116, + /* Note that the Peer Link IE has been replaced with the similar + * Peer Management IE. We will keep the former definition until mesh + * code is changed to comply with latest 802.11s drafts. */ - WLAN_EID_MESH_CONFIG = 51, - WLAN_EID_MESH_ID = 52, - WLAN_EID_PEER_LINK = 55, - WLAN_EID_PREQ = 68, - WLAN_EID_PREP = 69, - WLAN_EID_PERR = 70, - WLAN_EID_RANN = 49, /* compatible with FreeBSD */ + WLAN_EID_PEER_LINK = 55, /* no longer in 802.11s drafts */ + WLAN_EID_PEER_MGMT = 117, + WLAN_EID_CHAN_SWITCH_PARAM = 118, + WLAN_EID_MESH_AWAKE_WINDOW = 119, + WLAN_EID_BEACON_TIMING = 120, + WLAN_EID_MCCAOP_SETUP_REQ = 121, + WLAN_EID_MCCAOP_SETUP_RESP = 122, + WLAN_EID_MCCAOP_ADVERT = 123, + WLAN_EID_MCCAOP_TEARDOWN = 124, + WLAN_EID_GANN = 125, + WLAN_EID_RANN = 126, + WLAN_EID_PREQ = 130, + WLAN_EID_PREP = 131, + WLAN_EID_PERR = 132, + WLAN_EID_PXU = 137, + WLAN_EID_PXUC = 138, + WLAN_EID_AUTH_MESH_PEER_EXCH = 139, + WLAN_EID_MIC = 140, WLAN_EID_PWR_CONSTRAINT = 32, WLAN_EID_PWR_CAPABILITY = 33, @@ -1211,9 +1245,14 @@ enum ieee80211_category { WLAN_CATEGORY_HT = 7, WLAN_CATEGORY_SA_QUERY = 8, WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, + WLAN_CATEGORY_MESH_ACTION = 13, + WLAN_CATEGORY_MULTIHOP_ACTION = 14, + WLAN_CATEGORY_SELF_PROTECTED = 15, WLAN_CATEGORY_WMM = 17, - WLAN_CATEGORY_MESH_PLINK = 30, /* Pending ANA approval */ - WLAN_CATEGORY_MESH_PATH_SEL = 32, /* Pending ANA approval */ + /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */ + /* mesh is updated to current 802.11s draft */ + WLAN_CATEGORY_MESH_PLINK = 30, + WLAN_CATEGORY_MESH_PATH_SEL = 32, WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, WLAN_CATEGORY_VENDOR_SPECIFIC = 127, }; @@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action { /* AKM suite selectors */ #define WLAN_AKM_SUITE_8021X 0x000FAC01 #define WLAN_AKM_SUITE_PSK 0x000FAC02 +#define WLAN_AKM_SUITE_SAE 0x000FAC08 +#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09 #define WLAN_MAX_KEY_LEN 32 -- cgit v1.2.3 From a23c22080345f1748a933f32736986ff11f44d60 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:33:16 +0200 Subject: rt2x00: Shortcut link state updates when not operating as STA Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00link.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 4d534e9dc628..46836f801b35 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -235,6 +235,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, struct link_ant *ant = &rt2x00dev->link.ant; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + /* + * No need to update the stats for !=STA interfaces + */ + if (!rt2x00dev->intf_sta_count) + return; + /* * Frame was received successfully since non-succesfull * frames would have been dropped by the hardware. -- cgit v1.2.3 From 546adf294e85ca0dcd9c052294ef35b83a6ab2f4 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:33:43 +0200 Subject: rt2x00: Optimize unmapping of skbs Since no skb will be mapped for RX and TX at the same time we can simply shortcut the check for SKBDESC_DMA_MAPPED_TX. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 6d41599a090c..4436ff72c864 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -115,9 +115,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, DMA_FROM_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; - } - - if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { + } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, DMA_TO_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; -- cgit v1.2.3 From ff6133becae9ae1657fcff339a160a21448fa11c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:34:11 +0200 Subject: rt2x00: Use proper type for rxwi_w2 in rt2800_agc_to_rssi Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 7f040b0eac36..b9433fe2855a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -499,7 +499,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_write_tx_data); -static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) +static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2) { int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); -- cgit v1.2.3 From c6084d5fa2e70a436ab944066146de01819f5493 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:34:43 +0200 Subject: rt2x00: Use unlikely for error case in rt2x00queue_write_tx_frame This is an error condition that is not supposed to happen. Hence, it is safe to add unlikely to this check. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4436ff72c864..83630f16dc64 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -489,7 +489,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, if (unlikely(rt2x00queue_full(queue))) return -ENOBUFS; - if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { + if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, + &entry->flags))) { ERROR(queue->rt2x00dev, "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", -- cgit v1.2.3 From 74374725cdf466629fd401a81b3a04e4cdb0815f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:35:13 +0200 Subject: rt2x00: Remove superfluous initialization of qidx There is no need to initialize qidx to zero as it will ever be overwritten by the correct value. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 85a134cd62bf..cc4e17c437d1 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -573,7 +573,7 @@ static void rt2800pci_kick_tx_queue(struct data_queue *queue) { struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); - unsigned int qidx = 0; + unsigned int qidx; if (queue->qid == QID_MGMT) qidx = 5; -- cgit v1.2.3 From 12eec2cc0d5eacd8287646585dc88ab558d4866d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 9 Oct 2010 13:35:48 +0200 Subject: rt2x00: Fix tx status handling in rt2800pci The patches "rt2x00: Improve TX status entry validation" and "rt2x00: rework tx status handling in rt2800pci" together were causing problems with tx status processing in rt2800pci: phy1 -> rt2800pci_txdone: Warning - Got TX status for an empty queue 3, dropping phy1 -> rt2800pci_txdone: Warning - Got TX status for an unavailable queue 7, dropping Fix this by using the correct field definition for getting the QID out of the tx status report. Reported-by: Luis Correia Signed-off-by: Helmut Schaa Tested-by: Luis Correia Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cc4e17c437d1..b26739535986 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -676,7 +676,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) break; } - qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1; + qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); if (qid >= QID_RX) { /* * Unknown queue, this shouldn't happen. Just drop -- cgit v1.2.3 From c8a16c68ef4eb7817e41759c7105678ebc155377 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 9 Oct 2010 21:37:11 +0200 Subject: carl9170: common error path for bad frames This patch replaces several identical frame drop paths with a single shared rx frame error handler. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/rx.c | 48 ++++++++++++++-------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 671dbc429547..31287e0d362f 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -598,18 +598,14 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (!IS_STARTED(ar)) return; - if (unlikely(len < sizeof(*mac))) { - ar->rx_dropped++; - return; - } + if (unlikely(len < sizeof(*mac))) + goto drop; mpdu_len = len - sizeof(*mac); mac = (void *)(buf + mpdu_len); - if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { - ar->rx_dropped++; - return; - } + if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) + goto drop; switch (mac->status & AR9170_RX_STATUS_MPDU) { case AR9170_RX_STATUS_MPDU_FIRST: @@ -638,8 +634,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) "is clipped.\n"); } - ar->rx_dropped++; - return; + goto drop; } break; @@ -659,8 +654,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) "is clipped.\n"); } - ar->rx_dropped++; - return; + goto drop; } case AR9170_RX_STATUS_MPDU_MIDDLE: @@ -672,8 +666,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) wiphy_err(ar->hw->wiphy, "rx stream does not start " "with a first_mpdu frame tag.\n"); - ar->rx_dropped++; - return; + goto drop; } head = &ar->rx_plcp; @@ -696,16 +689,12 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) } /* FC + DU + RA + FCS */ - if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) { - ar->rx_dropped++; - return; - } + if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN))) + goto drop; memset(&status, 0, sizeof(status)); - if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) { - ar->rx_dropped++; - return; - } + if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) + goto drop; if (phy) carl9170_rx_phy_status(ar, phy, &status); @@ -713,12 +702,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) carl9170_ps_beacon(ar, buf, mpdu_len); skb = carl9170_rx_copy_data(buf, mpdu_len); - if (likely(skb)) { - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - ieee80211_rx(ar->hw, skb); - } else { - ar->rx_dropped++; - } + if (!skb) + goto drop; + + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx(ar->hw, skb); + return; + +drop: + ar->rx_dropped++; } static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, -- cgit v1.2.3 From 9f59f3c694c184c69e0be7d0fd0829bcb61b0429 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 9 Oct 2010 22:23:37 +0200 Subject: carl9170: remove stale rx error path The total/fatal error bit was erroneously prefixed with AR9170_RX_ERROR instead of AR9170_RX_STATUS. Luckily, the hardware specification confirmed that the 0x80 flag will never be set for mac->error. So, it was always just a dead branch. This patch also imports the latest version of shared wlan.h header from the firmware git. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/rx.c | 3 --- drivers/net/wireless/ath/carl9170/wlan.h | 14 +++++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 31287e0d362f..256dd42bb4ab 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -604,9 +604,6 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) mpdu_len = len - sizeof(*mac); mac = (void *)(buf + mpdu_len); - if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) - goto drop; - switch (mac->status & AR9170_RX_STATUS_MPDU) { case AR9170_RX_STATUS_MPDU_FIRST: /* Aggregated MPDUs start with an PLCP header */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h index 48ead2268f50..24d63b583b6b 100644 --- a/drivers/net/wireless/ath/carl9170/wlan.h +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -74,6 +74,9 @@ #define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 #define AR9170_RX_STATUS_MPDU_LAST 0x10 +#define AR9170_RX_STATUS_CONT_AGGR 0x40 +#define AR9170_RX_STATUS_TOTAL_ERROR 0x80 + #define AR9170_RX_ERROR_RXTO 0x01 #define AR9170_RX_ERROR_OVERRUN 0x02 #define AR9170_RX_ERROR_DECRYPT 0x04 @@ -81,7 +84,6 @@ #define AR9170_RX_ERROR_WRONG_RA 0x10 #define AR9170_RX_ERROR_PLCP 0x20 #define AR9170_RX_ERROR_MMIC 0x40 -#define AR9170_RX_ERROR_FATAL 0x80 /* these are either-or */ #define AR9170_TX_MAC_PROT_RTS 0x0001 @@ -329,13 +331,15 @@ struct _carl9170_tx_superframe { #define CARL9170_TX_SUPERDESC_LEN 24 #define AR9170_TX_HWDESC_LEN 8 -#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \ - AR9170_TX_SUPERDESC_LEN) +#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \ + AR9170_TX_HWDESC_LEN) struct ar9170_rx_head { u8 plcp[12]; } __packed; +#define AR9170_RX_HEAD_LEN 12 + struct ar9170_rx_phystatus { union { struct { @@ -350,12 +354,16 @@ struct ar9170_rx_phystatus { u8 phy_err; } __packed; +#define AR9170_RX_PHYSTATUS_LEN 20 + struct ar9170_rx_macstatus { u8 SAidx, DAidx; u8 error; u8 status; } __packed; +#define AR9170_RX_MACSTATUS_LEN 4 + struct ar9170_rx_frame_single { struct ar9170_rx_head phy_head; struct ieee80211_hdr i3e; -- cgit v1.2.3 From 8f236d1bef659ca69c912536a69b3031e5ba3269 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 10 Oct 2010 01:15:07 +0200 Subject: carl9170: A-MPDU frame type filter In the past, carl9170 has been plagued by mysterious ghosts. e.g.: wlan4: deauthenticated from 02:04:d8:3c:ac:c1 (Reason: 0) Apparently, the AP sent us a bogus deauthentication notification. But upon closer inspection the "management frame" turned out to be a corrupted scrap of an unsuccessful A-MPDU. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/rx.c | 42 +++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 256dd42bb4ab..939a0e96ed1f 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -576,6 +576,41 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) } } +static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) +{ + __le16 fc; + + if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) { + /* + * This frame is not part of an aMPDU. + * Therefore it is not subjected to any + * of the following content restrictions. + */ + return true; + } + + /* + * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts + * certain frame types can be part of an aMPDU. + * + * In order to keep the processing cost down, I opted for a + * stateless filter solely based on the frame control field. + */ + + fc = ((struct ieee80211_hdr *)buf)->frame_control; + if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc)) + return true; + + if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) || + ieee80211_is_back_req(fc)) + return true; + + if (ieee80211_is_action(fc)) + return true; + + return false; +} + /* * If the frame alignment is right (or the kernel has * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there @@ -594,6 +629,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) struct ieee80211_rx_status status; struct sk_buff *skb; int mpdu_len; + u8 mac_status; if (!IS_STARTED(ar)) return; @@ -604,7 +640,8 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) mpdu_len = len - sizeof(*mac); mac = (void *)(buf + mpdu_len); - switch (mac->status & AR9170_RX_STATUS_MPDU) { + mac_status = mac->status; + switch (mac_status & AR9170_RX_STATUS_MPDU) { case AR9170_RX_STATUS_MPDU_FIRST: /* Aggregated MPDUs start with an PLCP header */ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { @@ -693,6 +730,9 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) goto drop; + if (!carl9170_ampdu_check(ar, buf, mac_status)) + goto drop; + if (phy) carl9170_rx_phy_status(ar, phy, &status); -- cgit v1.2.3 From f03ee1ec73d8cad07b0ef5ba6106a9fc4d179ecb Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 10 Oct 2010 11:28:31 +0300 Subject: wl1251: create a copy of wl12xx_80211.h for wl1251 In preparation of moving wl1251 out from drivers/net/wireless/wl12xx create a separate copy of wl12xx_80211.h. This file should not even exist, we should instead use generic ieee80211 definitions. This will be fixed in the future so that the file can be removed. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/wl12xx_80211.h | 156 +++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 drivers/net/wireless/wl1251/wl12xx_80211.h diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h new file mode 100644 index 000000000000..184628027213 --- /dev/null +++ b/drivers/net/wireless/wl1251/wl12xx_80211.h @@ -0,0 +1,156 @@ +#ifndef __WL12XX_80211_H__ +#define __WL12XX_80211_H__ + +#include /* ETH_ALEN */ + +/* RATES */ +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + + +/* This really should be 8, but not for our firmware */ +#define MAX_SUPPORTED_RATES 32 +#define COUNTRY_STRING_LEN 3 +#define MAX_COUNTRY_TRIPLETS 32 + +/* Headers */ +struct ieee80211_header { + __le16 frame_ctl; + __le16 duration_id; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __packed; + +struct wl12xx_ie_header { + u8 id; + u8 len; +} __packed; + +/* IEs */ + +struct wl12xx_ie_ssid { + struct wl12xx_ie_header header; + char ssid[IW_ESSID_MAX_SIZE]; +} __packed; + +struct wl12xx_ie_rates { + struct wl12xx_ie_header header; + u8 rates[MAX_SUPPORTED_RATES]; +} __packed; + +struct wl12xx_ie_ds_params { + struct wl12xx_ie_header header; + u8 channel; +} __packed; + +struct country_triplet { + u8 channel; + u8 num_channels; + u8 max_tx_power; +} __packed; + +struct wl12xx_ie_country { + struct wl12xx_ie_header header; + u8 country_string[COUNTRY_STRING_LEN]; + struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; +} __packed; + + +/* Templates */ + +struct wl12xx_beacon_template { + struct ieee80211_header header; + __le32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; + struct wl12xx_ie_ds_params ds_params; + struct wl12xx_ie_country country; +} __packed; + +struct wl12xx_null_data_template { + struct ieee80211_header header; +} __packed; + +struct wl12xx_ps_poll_template { + __le16 fc; + __le16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} __packed; + +struct wl12xx_qos_null_data_template { + struct ieee80211_header header; + __le16 qos_ctl; +} __packed; + +struct wl12xx_probe_req_template { + struct ieee80211_header header; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; +} __packed; + + +struct wl12xx_probe_resp_template { + struct ieee80211_header header; + __le32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; + struct wl12xx_ie_ds_params ds_params; + struct wl12xx_ie_country country; +} __packed; + +#endif -- cgit v1.2.3 From 9bc6772e15d25f58c1be638031280e04514287d4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 10 Oct 2010 11:28:32 +0300 Subject: wl1251: move to it's own directory wl1271 driver is under heavy development but on the other hand the older wl1251 driver is currently considered more as a legacy driver. To make it easier to develop wl1271 features move wl1251 to it's own directory, drivers/net/wireless/wl1251. There are no functional changes, only moving of files. One regression is that Kconfig won't be updated automatically and user needs to enable wl1251 manually with an older config file. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/wl1251/Kconfig | 33 + drivers/net/wireless/wl1251/Makefile | 6 + drivers/net/wireless/wl1251/acx.c | 1048 +++++++++++++++++++ drivers/net/wireless/wl1251/acx.h | 1411 +++++++++++++++++++++++++ drivers/net/wireless/wl1251/boot.c | 557 ++++++++++ drivers/net/wireless/wl1251/boot.h | 39 + drivers/net/wireless/wl1251/cmd.c | 496 +++++++++ drivers/net/wireless/wl1251/cmd.h | 415 ++++++++ drivers/net/wireless/wl1251/debugfs.c | 541 ++++++++++ drivers/net/wireless/wl1251/debugfs.h | 31 + drivers/net/wireless/wl1251/event.c | 168 +++ drivers/net/wireless/wl1251/event.h | 120 +++ drivers/net/wireless/wl1251/init.c | 423 ++++++++ drivers/net/wireless/wl1251/init.h | 86 ++ drivers/net/wireless/wl1251/io.c | 194 ++++ drivers/net/wireless/wl1251/io.h | 84 ++ drivers/net/wireless/wl1251/main.c | 1435 ++++++++++++++++++++++++++ drivers/net/wireless/wl1251/ps.c | 194 ++++ drivers/net/wireless/wl1251/ps.h | 35 + drivers/net/wireless/wl1251/reg.h | 655 ++++++++++++ drivers/net/wireless/wl1251/rx.c | 190 ++++ drivers/net/wireless/wl1251/rx.h | 122 +++ drivers/net/wireless/wl1251/sdio.c | 342 ++++++ drivers/net/wireless/wl1251/spi.c | 346 +++++++ drivers/net/wireless/wl1251/spi.h | 59 ++ drivers/net/wireless/wl1251/tx.c | 570 ++++++++++ drivers/net/wireless/wl1251/tx.h | 231 +++++ drivers/net/wireless/wl1251/wl1251.h | 433 ++++++++ drivers/net/wireless/wl12xx/Kconfig | 34 - drivers/net/wireless/wl12xx/Makefile | 9 - drivers/net/wireless/wl12xx/wl1251.h | 433 -------- drivers/net/wireless/wl12xx/wl1251_acx.c | 1048 ------------------- drivers/net/wireless/wl12xx/wl1251_acx.h | 1411 ------------------------- drivers/net/wireless/wl12xx/wl1251_boot.c | 557 ---------- drivers/net/wireless/wl12xx/wl1251_boot.h | 39 - drivers/net/wireless/wl12xx/wl1251_cmd.c | 496 --------- drivers/net/wireless/wl12xx/wl1251_cmd.h | 415 -------- drivers/net/wireless/wl12xx/wl1251_debugfs.c | 541 ---------- drivers/net/wireless/wl12xx/wl1251_debugfs.h | 31 - drivers/net/wireless/wl12xx/wl1251_event.c | 168 --- drivers/net/wireless/wl12xx/wl1251_event.h | 120 --- drivers/net/wireless/wl12xx/wl1251_init.c | 423 -------- drivers/net/wireless/wl12xx/wl1251_init.h | 86 -- drivers/net/wireless/wl12xx/wl1251_io.c | 194 ---- drivers/net/wireless/wl12xx/wl1251_io.h | 84 -- drivers/net/wireless/wl12xx/wl1251_main.c | 1435 -------------------------- drivers/net/wireless/wl12xx/wl1251_ps.c | 194 ---- drivers/net/wireless/wl12xx/wl1251_ps.h | 35 - drivers/net/wireless/wl12xx/wl1251_reg.h | 655 ------------ drivers/net/wireless/wl12xx/wl1251_rx.c | 190 ---- drivers/net/wireless/wl12xx/wl1251_rx.h | 122 --- drivers/net/wireless/wl12xx/wl1251_sdio.c | 342 ------ drivers/net/wireless/wl12xx/wl1251_spi.c | 346 ------- drivers/net/wireless/wl12xx/wl1251_spi.h | 59 -- drivers/net/wireless/wl12xx/wl1251_tx.c | 570 ---------- drivers/net/wireless/wl12xx/wl1251_tx.h | 231 ----- 58 files changed, 10266 insertions(+), 10268 deletions(-) create mode 100644 drivers/net/wireless/wl1251/Kconfig create mode 100644 drivers/net/wireless/wl1251/Makefile create mode 100644 drivers/net/wireless/wl1251/acx.c create mode 100644 drivers/net/wireless/wl1251/acx.h create mode 100644 drivers/net/wireless/wl1251/boot.c create mode 100644 drivers/net/wireless/wl1251/boot.h create mode 100644 drivers/net/wireless/wl1251/cmd.c create mode 100644 drivers/net/wireless/wl1251/cmd.h create mode 100644 drivers/net/wireless/wl1251/debugfs.c create mode 100644 drivers/net/wireless/wl1251/debugfs.h create mode 100644 drivers/net/wireless/wl1251/event.c create mode 100644 drivers/net/wireless/wl1251/event.h create mode 100644 drivers/net/wireless/wl1251/init.c create mode 100644 drivers/net/wireless/wl1251/init.h create mode 100644 drivers/net/wireless/wl1251/io.c create mode 100644 drivers/net/wireless/wl1251/io.h create mode 100644 drivers/net/wireless/wl1251/main.c create mode 100644 drivers/net/wireless/wl1251/ps.c create mode 100644 drivers/net/wireless/wl1251/ps.h create mode 100644 drivers/net/wireless/wl1251/reg.h create mode 100644 drivers/net/wireless/wl1251/rx.c create mode 100644 drivers/net/wireless/wl1251/rx.h create mode 100644 drivers/net/wireless/wl1251/sdio.c create mode 100644 drivers/net/wireless/wl1251/spi.c create mode 100644 drivers/net/wireless/wl1251/spi.h create mode 100644 drivers/net/wireless/wl1251/tx.c create mode 100644 drivers/net/wireless/wl1251/tx.h create mode 100644 drivers/net/wireless/wl1251/wl1251.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_acx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_acx.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_boot.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_boot.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_cmd.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_cmd.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_debugfs.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_debugfs.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_event.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_event.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_init.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_init.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_io.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_io.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_main.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_ps.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_ps.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_reg.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_rx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_rx.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_sdio.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_spi.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_spi.h delete mode 100644 drivers/net/wireless/wl12xx/wl1251_tx.c delete mode 100644 drivers/net/wireless/wl12xx/wl1251_tx.h diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 174e3442d519..4de4410cd38e 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/rt2x00/Kconfig" +source "drivers/net/wireless/wl1251/Kconfig" source "drivers/net/wireless/wl12xx/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index a13a602edb13..06f8ca26c5c1 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o +obj-$(CONFIG_WL1251) += wl1251/ obj-$(CONFIG_WL12XX) += wl12xx/ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig new file mode 100644 index 000000000000..1fb65849414f --- /dev/null +++ b/drivers/net/wireless/wl1251/Kconfig @@ -0,0 +1,33 @@ +menuconfig WL1251 + tristate "TI wl1251 driver support" + depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS + select FW_LOADER + select CRC7 + ---help--- + This will enable TI wl1251 driver support. The drivers make + use of the mac80211 stack. + + If you choose to build a module, it'll be called wl1251. Say + N if unsure. + +config WL1251_SPI + tristate "TI wl1251 SPI support" + depends on WL1251 && SPI_MASTER + ---help--- + This module adds support for the SPI interface of adapters using + TI wl1251 chipset. Select this if your platform is using + the SPI bus. + + If you choose to build a module, it'll be called wl1251_spi. + Say N if unsure. + +config WL1251_SDIO + tristate "TI wl1251 SDIO support" + depends on WL1251 && MMC + ---help--- + This module adds support for the SDIO interface of adapters using + TI wl1251 chipset. Select this if your platform is using + the SDIO bus. + + If you choose to build a module, it'll be called + wl1251_sdio. Say N if unsure. diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile new file mode 100644 index 000000000000..4fe246824db3 --- /dev/null +++ b/drivers/net/wireless/wl1251/Makefile @@ -0,0 +1,6 @@ +wl1251-objs = main.o event.o tx.o rx.o ps.o cmd.o \ + acx.o boot.o init.o debugfs.o io.o + +obj-$(CONFIG_WL1251) += wl1251.o +obj-$(CONFIG_WL1251_SPI) += spi.o +obj-$(CONFIG_WL1251_SDIO) += sdio.o diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c new file mode 100644 index 000000000000..64a0214cfb29 --- /dev/null +++ b/drivers/net/wireless/wl1251/acx.c @@ -0,0 +1,1048 @@ +#include "acx.h" + +#include +#include +#include + +#include "wl1251.h" +#include "reg.h" +#include "cmd.h" +#include "ps.h" + +int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, + u8 mgt_rate, u8 mgt_mod) +{ + struct acx_fw_gen_frame_rates *rates; + int ret; + + wl1251_debug(DEBUG_ACX, "acx frame rates"); + + rates = kzalloc(sizeof(*rates), GFP_KERNEL); + if (!rates) { + ret = -ENOMEM; + goto out; + } + + rates->tx_ctrl_frame_rate = ctrl_rate; + rates->tx_ctrl_frame_mod = ctrl_mod; + rates->tx_mgt_frame_rate = mgt_rate; + rates->tx_mgt_frame_mod = mgt_mod; + + ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES, + rates, sizeof(*rates)); + if (ret < 0) { + wl1251_error("Failed to set FW rates and modulation"); + goto out; + } + +out: + kfree(rates); + return ret; +} + + +int wl1251_acx_station_id(struct wl1251 *wl) +{ + struct acx_dot11_station_id *mac; + int ret, i; + + wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); + + mac = kzalloc(sizeof(*mac), GFP_KERNEL); + if (!mac) { + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < ETH_ALEN; i++) + mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; + + ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac)); + if (ret < 0) + goto out; + +out: + kfree(mac); + return ret; +} + +int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id) +{ + struct acx_dot11_default_key *default_key; + int ret; + + wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); + + default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); + if (!default_key) { + ret = -ENOMEM; + goto out; + } + + default_key->id = key_id; + + ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY, + default_key, sizeof(*default_key)); + if (ret < 0) { + wl1251_error("Couldn't set default key"); + goto out; + } + + wl->default_key = key_id; + +out: + kfree(default_key); + return ret; +} + +int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, + u8 listen_interval) +{ + struct acx_wake_up_condition *wake_up; + int ret; + + wl1251_debug(DEBUG_ACX, "acx wake up conditions"); + + wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); + if (!wake_up) { + ret = -ENOMEM; + goto out; + } + + wake_up->wake_up_event = wake_up_event; + wake_up->listen_interval = listen_interval; + + ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, + wake_up, sizeof(*wake_up)); + if (ret < 0) { + wl1251_warning("could not set wake up conditions: %d", ret); + goto out; + } + +out: + kfree(wake_up); + return ret; +} + +int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth) +{ + struct acx_sleep_auth *auth; + int ret; + + wl1251_debug(DEBUG_ACX, "acx sleep auth"); + + auth = kzalloc(sizeof(*auth), GFP_KERNEL); + if (!auth) { + ret = -ENOMEM; + goto out; + } + + auth->sleep_auth = sleep_auth; + + ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); + if (ret < 0) + return ret; + +out: + kfree(auth); + return ret; +} + +int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len) +{ + struct acx_revision *rev; + int ret; + + wl1251_debug(DEBUG_ACX, "acx fw rev"); + + rev = kzalloc(sizeof(*rev), GFP_KERNEL); + if (!rev) { + ret = -ENOMEM; + goto out; + } + + ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); + if (ret < 0) { + wl1251_warning("ACX_FW_REV interrogate failed"); + goto out; + } + + /* be careful with the buffer sizes */ + strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); + + /* + * if the firmware version string is exactly + * sizeof(rev->fw_version) long or fw_len is less than + * sizeof(rev->fw_version) it won't be null terminated + */ + buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; + +out: + kfree(rev); + return ret; +} + +int wl1251_acx_tx_power(struct wl1251 *wl, int power) +{ + struct acx_current_tx_power *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); + + if (power < 0 || power > 25) + return -EINVAL; + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->current_tx_power = power * 10; + + ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("configure of tx power failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_feature_cfg(struct wl1251 *wl) +{ + struct acx_feature_config *feature; + int ret; + + wl1251_debug(DEBUG_ACX, "acx feature cfg"); + + feature = kzalloc(sizeof(*feature), GFP_KERNEL); + if (!feature) { + ret = -ENOMEM; + goto out; + } + + /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ + feature->data_flow_options = 0; + feature->options = 0; + + ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, + feature, sizeof(*feature)); + if (ret < 0) { + wl1251_error("Couldn't set HW encryption"); + goto out; + } + +out: + kfree(feature); + return ret; +} + +int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map, + size_t len) +{ + int ret; + + wl1251_debug(DEBUG_ACX, "acx mem map"); + + ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_acx_data_path_params(struct wl1251 *wl, + struct acx_data_path_params_resp *resp) +{ + struct acx_data_path_params *params; + int ret; + + wl1251_debug(DEBUG_ACX, "acx data path params"); + + params = kzalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + ret = -ENOMEM; + goto out; + } + + params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; + params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; + + params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM; + params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM; + + params->tx_complete_threshold = 1; + + params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE; + + params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT; + + ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS, + params, sizeof(*params)); + if (ret < 0) + goto out; + + /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */ + ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS, + resp, sizeof(*resp)); + + if (ret < 0) { + wl1251_warning("failed to read data path parameters: %d", ret); + goto out; + } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) { + wl1251_warning("data path parameter acx status failed"); + ret = -EIO; + goto out; + } + +out: + kfree(params); + return ret; +} + +int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time) +{ + struct acx_rx_msdu_lifetime *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->lifetime = life_time; + ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, + acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("failed to set rx msdu life time: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter) +{ + struct acx_rx_config *rx_config; + int ret; + + wl1251_debug(DEBUG_ACX, "acx rx config"); + + rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); + if (!rx_config) { + ret = -ENOMEM; + goto out; + } + + rx_config->config_options = config; + rx_config->filter_options = filter; + + ret = wl1251_cmd_configure(wl, ACX_RX_CFG, + rx_config, sizeof(*rx_config)); + if (ret < 0) { + wl1251_warning("failed to set rx config: %d", ret); + goto out; + } + +out: + kfree(rx_config); + return ret; +} + +int wl1251_acx_pd_threshold(struct wl1251 *wl) +{ + struct acx_packet_detection *pd; + int ret; + + wl1251_debug(DEBUG_ACX, "acx data pd threshold"); + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + ret = -ENOMEM; + goto out; + } + + /* FIXME: threshold value not set */ + + ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); + if (ret < 0) { + wl1251_warning("failed to set pd threshold: %d", ret); + goto out; + } + +out: + kfree(pd); + return ret; +} + +int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time) +{ + struct acx_slot *slot; + int ret; + + wl1251_debug(DEBUG_ACX, "acx slot"); + + slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) { + ret = -ENOMEM; + goto out; + } + + slot->wone_index = STATION_WONE_INDEX; + slot->slot_time = slot_time; + + ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); + if (ret < 0) { + wl1251_warning("failed to set slot time: %d", ret); + goto out; + } + +out: + kfree(slot); + return ret; +} + +int wl1251_acx_group_address_tbl(struct wl1251 *wl) +{ + struct acx_dot11_grp_addr_tbl *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx group address tbl"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* MAC filtering */ + acx->enabled = 0; + acx->num_groups = 0; + memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN); + + ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, + acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("failed to set group addr table: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_service_period_timeout(struct wl1251 *wl) +{ + struct acx_rx_timeout *rx_timeout; + int ret; + + rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); + if (!rx_timeout) { + ret = -ENOMEM; + goto out; + } + + wl1251_debug(DEBUG_ACX, "acx service period timeout"); + + rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF; + rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF; + + ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, + rx_timeout, sizeof(*rx_timeout)); + if (ret < 0) { + wl1251_warning("failed to set service period timeout: %d", + ret); + goto out; + } + +out: + kfree(rx_timeout); + return ret; +} + +int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold) +{ + struct acx_rts_threshold *rts; + int ret; + + wl1251_debug(DEBUG_ACX, "acx rts threshold"); + + rts = kzalloc(sizeof(*rts), GFP_KERNEL); + if (!rts) { + ret = -ENOMEM; + goto out; + } + + rts->threshold = rts_threshold; + + ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); + if (ret < 0) { + wl1251_warning("failed to set rts threshold: %d", ret); + goto out; + } + +out: + kfree(rts); + return ret; +} + +int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter) +{ + struct acx_beacon_filter_option *beacon_filter; + int ret; + + wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); + + beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); + if (!beacon_filter) { + ret = -ENOMEM; + goto out; + } + + beacon_filter->enable = enable_filter; + beacon_filter->max_num_beacons = 0; + + ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, + beacon_filter, sizeof(*beacon_filter)); + if (ret < 0) { + wl1251_warning("failed to set beacon filter opt: %d", ret); + goto out; + } + +out: + kfree(beacon_filter); + return ret; +} + +int wl1251_acx_beacon_filter_table(struct wl1251 *wl) +{ + struct acx_beacon_filter_ie_table *ie_table; + int idx = 0; + int ret; + + wl1251_debug(DEBUG_ACX, "acx beacon filter table"); + + ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); + if (!ie_table) { + ret = -ENOMEM; + goto out; + } + + /* configure default beacon pass-through rules */ + ie_table->num_ie = 1; + ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN; + ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE; + + ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, + ie_table, sizeof(*ie_table)); + if (ret < 0) { + wl1251_warning("failed to set beacon filter table: %d", ret); + goto out; + } + +out: + kfree(ie_table); + return ret; +} + +int wl1251_acx_conn_monit_params(struct wl1251 *wl) +{ + struct acx_conn_monit_params *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; + acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; + + ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, + acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("failed to set connection monitor " + "parameters: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_sg_enable(struct wl1251 *wl) +{ + struct acx_bt_wlan_coex *pta; + int ret; + + wl1251_debug(DEBUG_ACX, "acx sg enable"); + + pta = kzalloc(sizeof(*pta), GFP_KERNEL); + if (!pta) { + ret = -ENOMEM; + goto out; + } + + pta->enable = SG_ENABLE; + + ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); + if (ret < 0) { + wl1251_warning("failed to set softgemini enable: %d", ret); + goto out; + } + +out: + kfree(pta); + return ret; +} + +int wl1251_acx_sg_cfg(struct wl1251 *wl) +{ + struct acx_bt_wlan_coex_param *param; + int ret; + + wl1251_debug(DEBUG_ACX, "acx sg cfg"); + + param = kzalloc(sizeof(*param), GFP_KERNEL); + if (!param) { + ret = -ENOMEM; + goto out; + } + + /* BT-WLAN coext parameters */ + param->min_rate = RATE_INDEX_24MBPS; + param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF; + param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF; + param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF; + param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF; + param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF; + param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF; + param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF; + param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF; + param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF; + param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF; + param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF; + param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF; + param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF; + param->antenna_type = PTA_ANTENNA_TYPE_DEF; + param->signal_type = PTA_SIGNALING_TYPE_DEF; + param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF; + param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF; + param->max_cts = PTA_MAX_NUM_CTS_DEF; + param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF; + param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF; + param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF; + param->wlan_elp_hp = PTA_ELP_HP_DEF; + param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF; + param->ack_mode_dual_ant = PTA_ACK_MODE_DEF; + param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF; + param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF; + param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF; + + ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); + if (ret < 0) { + wl1251_warning("failed to set sg config: %d", ret); + goto out; + } + +out: + kfree(param); + return ret; +} + +int wl1251_acx_cca_threshold(struct wl1251 *wl) +{ + struct acx_energy_detection *detection; + int ret; + + wl1251_debug(DEBUG_ACX, "acx cca threshold"); + + detection = kzalloc(sizeof(*detection), GFP_KERNEL); + if (!detection) { + ret = -ENOMEM; + goto out; + } + + detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; + detection->tx_energy_detection = 0; + + ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD, + detection, sizeof(*detection)); + if (ret < 0) { + wl1251_warning("failed to set cca threshold: %d", ret); + return ret; + } + +out: + kfree(detection); + return ret; +} + +int wl1251_acx_bcn_dtim_options(struct wl1251 *wl) +{ + struct acx_beacon_broadcast *bb; + int ret; + + wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); + + bb = kzalloc(sizeof(*bb), GFP_KERNEL); + if (!bb) { + ret = -ENOMEM; + goto out; + } + + bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; + bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; + bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE; + bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF; + + ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); + if (ret < 0) { + wl1251_warning("failed to set rx config: %d", ret); + goto out; + } + +out: + kfree(bb); + return ret; +} + +int wl1251_acx_aid(struct wl1251 *wl, u16 aid) +{ + struct acx_aid *acx_aid; + int ret; + + wl1251_debug(DEBUG_ACX, "acx aid"); + + acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); + if (!acx_aid) { + ret = -ENOMEM; + goto out; + } + + acx_aid->aid = aid; + + ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); + if (ret < 0) { + wl1251_warning("failed to set aid: %d", ret); + goto out; + } + +out: + kfree(acx_aid); + return ret; +} + +int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask) +{ + struct acx_event_mask *mask; + int ret; + + wl1251_debug(DEBUG_ACX, "acx event mbox mask"); + + mask = kzalloc(sizeof(*mask), GFP_KERNEL); + if (!mask) { + ret = -ENOMEM; + goto out; + } + + /* high event mask is unused */ + mask->high_event_mask = 0xffffffff; + + mask->event_mask = event_mask; + + ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK, + mask, sizeof(*mask)); + if (ret < 0) { + wl1251_warning("failed to set acx_event_mbox_mask: %d", ret); + goto out; + } + +out: + kfree(mask); + return ret; +} + +int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble) +{ + struct acx_preamble *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx_set_preamble"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->preamble = preamble; + + ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("Setting of preamble failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_cts_protect(struct wl1251 *wl, + enum acx_ctsprotect_type ctsprotect) +{ + struct acx_ctsprotect *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ctsprotect = ctsprotect; + + ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("Setting of ctsprotect failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) +{ + struct acx_tsf_info *tsf_info; + int ret; + + tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); + if (!tsf_info) { + ret = -ENOMEM; + goto out; + } + + ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO, + tsf_info, sizeof(*tsf_info)); + if (ret < 0) { + wl1251_warning("ACX_FW_REV interrogate failed"); + goto out; + } + + *mactime = tsf_info->current_tsf_lsb | + (tsf_info->current_tsf_msb << 31); + +out: + kfree(tsf_info); + return ret; +} + +int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats) +{ + int ret; + + wl1251_debug(DEBUG_ACX, "acx statistics"); + + ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats, + sizeof(*stats)); + if (ret < 0) { + wl1251_warning("acx statistics failed: %d", ret); + return -ENOMEM; + } + + return 0; +} + +int wl1251_acx_rate_policies(struct wl1251 *wl) +{ + struct acx_rate_policy *acx; + int ret = 0; + + wl1251_debug(DEBUG_ACX, "acx rate policies"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* configure one default (one-size-fits-all) rate class */ + acx->rate_class_cnt = 1; + acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; + acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; + acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; + acx->rate_class[0].aflags = 0; + + ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("Setting of rate policies failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_mem_cfg(struct wl1251 *wl) +{ + struct wl1251_acx_config_memory *mem_conf; + int ret, i; + + wl1251_debug(DEBUG_ACX, "acx mem cfg"); + + mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); + if (!mem_conf) { + ret = -ENOMEM; + goto out; + } + + /* memory config */ + mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); + mem_conf->mem_config.rx_mem_block_num = 35; + mem_conf->mem_config.tx_min_mem_block_num = 64; + mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES; + mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING; + mem_conf->mem_config.num_ssid_profiles = 1; + mem_conf->mem_config.debug_buffer_size = + cpu_to_le16(TRACE_BUFFER_MAX_SIZE); + + /* RX queue config */ + mem_conf->rx_queue_config.dma_address = 0; + mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF; + mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY; + mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE; + + /* TX queue config */ + for (i = 0; i < MAX_TX_QUEUES; i++) { + mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF; + mem_conf->tx_queue_config[i].attributes = i; + } + + ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf, + sizeof(*mem_conf)); + if (ret < 0) { + wl1251_warning("wl1251 mem config failed: %d", ret); + goto out; + } + +out: + kfree(mem_conf); + return ret; +} + +int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim) +{ + struct wl1251_acx_wr_tbtt_and_dtim *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->tbtt = tbtt; + acx->dtim = dtim; + + ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM, + acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("failed to set tbtt and dtim: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, + u8 aifs, u16 txop) +{ + struct wl1251_acx_ac_cfg *acx; + int ret = 0; + + wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " + "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->ac = ac; + acx->cw_min = cw_min; + acx->cw_max = cw_max; + acx->aifsn = aifs; + acx->txop_limit = txop; + + ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("acx ac cfg failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + +int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, + enum wl1251_acx_channel_type type, + u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, + enum wl1251_acx_ack_policy ack_policy) +{ + struct wl1251_acx_tid_cfg *acx; + int ret = 0; + + wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d " + "ps_scheme %d ack_policy %d", queue, type, tsid, + ps_scheme, ack_policy); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->queue = queue; + acx->type = type; + acx->tsid = tsid; + acx->ps_scheme = ps_scheme; + acx->ack_policy = ack_policy; + + ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("acx tid cfg failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/wl1251/acx.h new file mode 100644 index 000000000000..e54b21a4f8b1 --- /dev/null +++ b/drivers/net/wireless/wl1251/acx.h @@ -0,0 +1,1411 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_ACX_H__ +#define __WL1251_ACX_H__ + +#include "wl1251.h" +#include "cmd.h" + +/* Target's information element */ +struct acx_header { + struct wl1251_cmd_header cmd; + + /* acx (or information element) header */ + u16 id; + + /* payload length (not including headers */ + u16 len; +} __packed; + +struct acx_error_counter { + struct acx_header header; + + /* The number of PLCP errors since the last time this */ + /* information element was interrogated. This field is */ + /* automatically cleared when it is interrogated.*/ + u32 PLCP_error; + + /* The number of FCS errors since the last time this */ + /* information element was interrogated. This field is */ + /* automatically cleared when it is interrogated.*/ + u32 FCS_error; + + /* The number of MPDUs without PLCP header errors received*/ + /* since the last time this information element was interrogated. */ + /* This field is automatically cleared when it is interrogated.*/ + u32 valid_frame; + + /* the number of missed sequence numbers in the squentially */ + /* values of frames seq numbers */ + u32 seq_num_miss; +} __packed; + +struct acx_revision { + struct acx_header header; + + /* + * The WiLink firmware version, an ASCII string x.x.x.x, + * that uniquely identifies the current firmware. + * The left most digit is incremented each time a + * significant change is made to the firmware, such as + * code redesign or new platform support. + * The second digit is incremented when major enhancements + * are added or major fixes are made. + * The third digit is incremented for each GA release. + * The fourth digit is incremented for each build. + * The first two digits identify a firmware release version, + * in other words, a unique set of features. + * The first three digits identify a GA release. + */ + char fw_version[20]; + + /* + * This 4 byte field specifies the WiLink hardware version. + * bits 0 - 15: Reserved. + * bits 16 - 23: Version ID - The WiLink version ID + * (1 = first spin, 2 = second spin, and so on). + * bits 24 - 31: Chip ID - The WiLink chip ID. + */ + u32 hw_version; +} __packed; + +enum wl1251_psm_mode { + /* Active mode */ + WL1251_PSM_CAM = 0, + + /* Power save mode */ + WL1251_PSM_PS = 1, + + /* Extreme low power */ + WL1251_PSM_ELP = 2, +}; + +struct acx_sleep_auth { + struct acx_header header; + + /* The sleep level authorization of the device. */ + /* 0 - Always active*/ + /* 1 - Power down mode: light / fast sleep*/ + /* 2 - ELP mode: Deep / Max sleep*/ + u8 sleep_auth; + u8 padding[3]; +} __packed; + +enum { + HOSTIF_PCI_MASTER_HOST_INDIRECT, + HOSTIF_PCI_MASTER_HOST_DIRECT, + HOSTIF_SLAVE, + HOSTIF_PKT_RING, + HOSTIF_DONTCARE = 0xFF +}; + +#define DEFAULT_UCAST_PRIORITY 0 +#define DEFAULT_RX_Q_PRIORITY 0 +#define DEFAULT_NUM_STATIONS 1 +#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ +#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ +#define TRACE_BUFFER_MAX_SIZE 256 + +#define DP_RX_PACKET_RING_CHUNK_SIZE 1600 +#define DP_TX_PACKET_RING_CHUNK_SIZE 1600 +#define DP_RX_PACKET_RING_CHUNK_NUM 2 +#define DP_TX_PACKET_RING_CHUNK_NUM 2 +#define DP_TX_COMPLETE_TIME_OUT 20 +#define FW_TX_CMPLT_BLOCK_SIZE 16 + +struct acx_data_path_params { + struct acx_header header; + + u16 rx_packet_ring_chunk_size; + u16 tx_packet_ring_chunk_size; + + u8 rx_packet_ring_chunk_num; + u8 tx_packet_ring_chunk_num; + + /* + * Maximum number of packets that can be gathered + * in the TX complete ring before an interrupt + * is generated. + */ + u8 tx_complete_threshold; + + /* Number of pending TX complete entries in cyclic ring.*/ + u8 tx_complete_ring_depth; + + /* + * Max num microseconds since a packet enters the TX + * complete ring until an interrupt is generated. + */ + u32 tx_complete_timeout; +} __packed; + + +struct acx_data_path_params_resp { + struct acx_header header; + + u16 rx_packet_ring_chunk_size; + u16 tx_packet_ring_chunk_size; + + u8 rx_packet_ring_chunk_num; + u8 tx_packet_ring_chunk_num; + + u8 pad[2]; + + u32 rx_packet_ring_addr; + u32 tx_packet_ring_addr; + + u32 rx_control_addr; + u32 tx_control_addr; + + u32 tx_complete_addr; +} __packed; + +#define TX_MSDU_LIFETIME_MIN 0 +#define TX_MSDU_LIFETIME_MAX 3000 +#define TX_MSDU_LIFETIME_DEF 512 +#define RX_MSDU_LIFETIME_MIN 0 +#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF +#define RX_MSDU_LIFETIME_DEF 512000 + +struct acx_rx_msdu_lifetime { + struct acx_header header; + + /* + * The maximum amount of time, in TU, before the + * firmware discards the MSDU. + */ + u32 lifetime; +} __packed; + +/* + * RX Config Options Table + * Bit Definition + * === ========== + * 31:14 Reserved + * 13 Copy RX Status - when set, write three receive status words + * to top of rx'd MPDUs. + * When cleared, do not write three status words (added rev 1.5) + * 12 Reserved + * 11 RX Complete upon FCS error - when set, give rx complete + * interrupt for FCS errors, after the rx filtering, e.g. unicast + * frames not to us with FCS error will not generate an interrupt. + * 10 SSID Filter Enable - When set, the WiLink discards all beacon, + * probe request, and probe response frames with an SSID that does + * not match the SSID specified by the host in the START/JOIN + * command. + * When clear, the WiLink receives frames with any SSID. + * 9 Broadcast Filter Enable - When set, the WiLink discards all + * broadcast frames. When clear, the WiLink receives all received + * broadcast frames. + * 8:6 Reserved + * 5 BSSID Filter Enable - When set, the WiLink discards any frames + * with a BSSID that does not match the BSSID specified by the + * host. + * When clear, the WiLink receives frames from any BSSID. + * 4 MAC Addr Filter - When set, the WiLink discards any frames + * with a destination address that does not match the MAC address + * of the adaptor. + * When clear, the WiLink receives frames destined to any MAC + * address. + * 3 Promiscuous - When set, the WiLink receives all valid frames + * (i.e., all frames that pass the FCS check). + * When clear, only frames that pass the other filters specified + * are received. + * 2 FCS - When set, the WiLink includes the FCS with the received + * frame. + * When cleared, the FCS is discarded. + * 1 PLCP header - When set, write all data from baseband to frame + * buffer including PHY header. + * 0 Reserved - Always equal to 0. + * + * RX Filter Options Table + * Bit Definition + * === ========== + * 31:12 Reserved - Always equal to 0. + * 11 Association - When set, the WiLink receives all association + * related frames (association request/response, reassocation + * request/response, and disassociation). When clear, these frames + * are discarded. + * 10 Auth/De auth - When set, the WiLink receives all authentication + * and de-authentication frames. When clear, these frames are + * discarded. + * 9 Beacon - When set, the WiLink receives all beacon frames. + * When clear, these frames are discarded. + * 8 Contention Free - When set, the WiLink receives all contention + * free frames. + * When clear, these frames are discarded. + * 7 Control - When set, the WiLink receives all control frames. + * When clear, these frames are discarded. + * 6 Data - When set, the WiLink receives all data frames. + * When clear, these frames are discarded. + * 5 FCS Error - When set, the WiLink receives frames that have FCS + * errors. + * When clear, these frames are discarded. + * 4 Management - When set, the WiLink receives all management + * frames. + * When clear, these frames are discarded. + * 3 Probe Request - When set, the WiLink receives all probe request + * frames. + * When clear, these frames are discarded. + * 2 Probe Response - When set, the WiLink receives all probe + * response frames. + * When clear, these frames are discarded. + * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK + * frames. + * When clear, these frames are discarded. + * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames + * that have reserved frame types and sub types as defined by the + * 802.11 specification. + * When clear, these frames are discarded. + */ +struct acx_rx_config { + struct acx_header header; + + u32 config_options; + u32 filter_options; +} __packed; + +enum { + QOS_AC_BE = 0, + QOS_AC_BK, + QOS_AC_VI, + QOS_AC_VO, + QOS_HIGHEST_AC_INDEX = QOS_AC_VO, +}; + +#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1) +#define FIRST_AC_INDEX QOS_AC_BE +#define MAX_NUM_OF_802_1d_TAGS 8 +#define AC_PARAMS_MAX_TSID 15 +#define MAX_APSD_CONF 0xffff + +#define QOS_TX_HIGH_MIN (0) +#define QOS_TX_HIGH_MAX (100) + +#define QOS_TX_HIGH_BK_DEF (25) +#define QOS_TX_HIGH_BE_DEF (35) +#define QOS_TX_HIGH_VI_DEF (35) +#define QOS_TX_HIGH_VO_DEF (35) + +#define QOS_TX_LOW_BK_DEF (15) +#define QOS_TX_LOW_BE_DEF (25) +#define QOS_TX_LOW_VI_DEF (25) +#define QOS_TX_LOW_VO_DEF (25) + +struct acx_tx_queue_qos_config { + struct acx_header header; + + u8 qid; + u8 pad[3]; + + /* Max number of blocks allowd in the queue */ + u16 high_threshold; + + /* Lowest memory blocks guaranteed for this queue */ + u16 low_threshold; +} __packed; + +struct acx_packet_detection { + struct acx_header header; + + u32 threshold; +} __packed; + + +enum acx_slot_type { + SLOT_TIME_LONG = 0, + SLOT_TIME_SHORT = 1, + DEFAULT_SLOT_TIME = SLOT_TIME_SHORT, + MAX_SLOT_TIMES = 0xFF +}; + +#define STATION_WONE_INDEX 0 + +struct acx_slot { + struct acx_header header; + + u8 wone_index; /* Reserved */ + u8 slot_time; + u8 reserved[6]; +} __packed; + + +#define ADDRESS_GROUP_MAX (8) +#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX) + +struct acx_dot11_grp_addr_tbl { + struct acx_header header; + + u8 enabled; + u8 num_groups; + u8 pad[2]; + u8 mac_table[ADDRESS_GROUP_MAX_LEN]; +} __packed; + + +#define RX_TIMEOUT_PS_POLL_MIN 0 +#define RX_TIMEOUT_PS_POLL_MAX (200000) +#define RX_TIMEOUT_PS_POLL_DEF (15) +#define RX_TIMEOUT_UPSD_MIN 0 +#define RX_TIMEOUT_UPSD_MAX (200000) +#define RX_TIMEOUT_UPSD_DEF (15) + +struct acx_rx_timeout { + struct acx_header header; + + /* + * The longest time the STA will wait to receive + * traffic from the AP after a PS-poll has been + * transmitted. + */ + u16 ps_poll_timeout; + + /* + * The longest time the STA will wait to receive + * traffic from the AP after a frame has been sent + * from an UPSD enabled queue. + */ + u16 upsd_timeout; +} __packed; + +#define RTS_THRESHOLD_MIN 0 +#define RTS_THRESHOLD_MAX 4096 +#define RTS_THRESHOLD_DEF 2347 + +struct acx_rts_threshold { + struct acx_header header; + + u16 threshold; + u8 pad[2]; +} __packed; + +struct acx_beacon_filter_option { + struct acx_header header; + + u8 enable; + + /* + * The number of beacons without the unicast TIM + * bit set that the firmware buffers before + * signaling the host about ready frames. + * When set to 0 and the filter is enabled, beacons + * without the unicast TIM bit set are dropped. + */ + u8 max_num_beacons; + u8 pad[2]; +} __packed; + +/* + * ACXBeaconFilterEntry (not 221) + * Byte Offset Size (Bytes) Definition + * =========== ============ ========== + * 0 1 IE identifier + * 1 1 Treatment bit mask + * + * ACXBeaconFilterEntry (221) + * Byte Offset Size (Bytes) Definition + * =========== ============ ========== + * 0 1 IE identifier + * 1 1 Treatment bit mask + * 2 3 OUI + * 5 1 Type + * 6 2 Version + * + * + * Treatment bit mask - The information element handling: + * bit 0 - The information element is compared and transferred + * in case of change. + * bit 1 - The information element is transferred to the host + * with each appearance or disappearance. + * Note that both bits can be set at the same time. + */ +#define BEACON_FILTER_TABLE_MAX_IE_NUM (32) +#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6) +#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2) +#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6) +#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \ + BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \ + (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ + BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) + +#define BEACON_RULE_PASS_ON_CHANGE BIT(0) +#define BEACON_RULE_PASS_ON_APPEARANCE BIT(1) + +#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN (37) + +struct acx_beacon_filter_ie_table { + struct acx_header header; + + u8 num_ie; + u8 pad[3]; + u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; +} __packed; + +#define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ +#define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */ + +struct acx_conn_monit_params { + struct acx_header header; + + u32 synch_fail_thold; /* number of beacons missed */ + u32 bss_lose_timeout; /* number of TU's from synch fail */ +} __packed; + +enum { + SG_ENABLE = 0, + SG_DISABLE, + SG_SENSE_NO_ACTIVITY, + SG_SENSE_ACTIVE +}; + +struct acx_bt_wlan_coex { + struct acx_header header; + + /* + * 0 -> PTA enabled + * 1 -> PTA disabled + * 2 -> sense no active mode, i.e. + * an interrupt is sent upon + * BT activity. + * 3 -> PTA is switched on in response + * to the interrupt sending. + */ + u8 enable; + u8 pad[3]; +} __packed; + +#define PTA_ANTENNA_TYPE_DEF (0) +#define PTA_BT_HP_MAXTIME_DEF (2000) +#define PTA_WLAN_HP_MAX_TIME_DEF (5000) +#define PTA_SENSE_DISABLE_TIMER_DEF (1350) +#define PTA_PROTECTIVE_RX_TIME_DEF (1500) +#define PTA_PROTECTIVE_TX_TIME_DEF (1500) +#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000) +#define PTA_SIGNALING_TYPE_DEF (1) +#define PTA_AFH_LEVERAGE_ON_DEF (0) +#define PTA_NUMBER_QUIET_CYCLE_DEF (0) +#define PTA_MAX_NUM_CTS_DEF (3) +#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2) +#define PTA_NUMBER_OF_BT_PACKETS_DEF (2) +#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500) +#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000) +#define PTA_CYCLE_TIME_FAST_DEF (8700) +#define PTA_RX_FOR_AVALANCHE_DEF (5) +#define PTA_ELP_HP_DEF (0) +#define PTA_ANTI_STARVE_PERIOD_DEF (500) +#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4) +#define PTA_ALLOW_PA_SD_DEF (1) +#define PTA_TIME_BEFORE_BEACON_DEF (6300) +#define PTA_HPDM_MAX_TIME_DEF (1600) +#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550) +#define PTA_AUTO_MODE_NO_CTS_DEF (0) +#define PTA_BT_HP_RESPECTED_DEF (3) +#define PTA_WLAN_RX_MIN_RATE_DEF (24) +#define PTA_ACK_MODE_DEF (1) + +struct acx_bt_wlan_coex_param { + struct acx_header header; + + /* + * The minimum rate of a received WLAN packet in the STA, + * during protective mode, of which a new BT-HP request + * during this Rx will always be respected and gain the antenna. + */ + u32 min_rate; + + /* Max time the BT HP will be respected. */ + u16 bt_hp_max_time; + + /* Max time the WLAN HP will be respected. */ + u16 wlan_hp_max_time; + + /* + * The time between the last BT activity + * and the moment when the sense mode returns + * to SENSE_INACTIVE. + */ + u16 sense_disable_timer; + + /* Time before the next BT HP instance */ + u16 rx_time_bt_hp; + u16 tx_time_bt_hp; + + /* range: 10-20000 default: 1500 */ + u16 rx_time_bt_hp_fast; + u16 tx_time_bt_hp_fast; + + /* range: 2000-65535 default: 8700 */ + u16 wlan_cycle_fast; + + /* range: 0 - 15000 (Msec) default: 1000 */ + u16 bt_anti_starvation_period; + + /* range 400-10000(Usec) default: 3000 */ + u16 next_bt_lp_packet; + + /* Deafult: worst case for BT DH5 traffic */ + u16 wake_up_beacon; + + /* range: 0-50000(Usec) default: 1050 */ + u16 hp_dm_max_guard_time; + + /* + * This is to prevent both BT & WLAN antenna + * starvation. + * Range: 100-50000(Usec) default:2550 + */ + u16 next_wlan_packet; + + /* 0 -> shared antenna */ + u8 antenna_type; + + /* + * 0 -> TI legacy + * 1 -> Palau + */ + u8 signal_type; + + /* + * BT AFH status + * 0 -> no AFH + * 1 -> from dedicated GPIO + * 2 -> AFH on (from host) + */ + u8 afh_leverage_on; + + /* + * The number of cycles during which no + * TX will be sent after 1 cycle of RX + * transaction in protective mode + */ + u8 quiet_cycle_num; + + /* + * The maximum number of CTSs that will + * be sent for receiving RX packet in + * protective mode + */ + u8 max_cts; + + /* + * The number of WLAN packets + * transferred in common mode before + * switching to BT. + */ + u8 wlan_packets_num; + + /* + * The number of BT packets + * transferred in common mode before + * switching to WLAN. + */ + u8 bt_packets_num; + + /* range: 1-255 default: 5 */ + u8 missed_rx_avalanche; + + /* range: 0-1 default: 1 */ + u8 wlan_elp_hp; + + /* range: 0 - 15 default: 4 */ + u8 bt_anti_starvation_cycles; + + u8 ack_mode_dual_ant; + + /* + * Allow PA_SD assertion/de-assertion + * during enabled BT activity. + */ + u8 pa_sd_enable; + + /* + * Enable/Disable PTA in auto mode: + * Support Both Active & P.S modes + */ + u8 pta_auto_mode_enable; + + /* range: 0 - 20 default: 1 */ + u8 bt_hp_respected_num; +} __packed; + +#define CCA_THRSH_ENABLE_ENERGY_D 0x140A +#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF + +struct acx_energy_detection { + struct acx_header header; + + /* The RX Clear Channel Assessment threshold in the PHY */ + u16 rx_cca_threshold; + u8 tx_energy_detection; + u8 pad; +} __packed; + +#define BCN_RX_TIMEOUT_DEF_VALUE 10000 +#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000 +#define RX_BROADCAST_IN_PS_DEF_VALUE 1 +#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4 + +struct acx_beacon_broadcast { + struct acx_header header; + + u16 beacon_rx_timeout; + u16 broadcast_timeout; + + /* Enables receiving of broadcast packets in PS mode */ + u8 rx_broadcast_in_ps; + + /* Consecutive PS Poll failures before updating the host */ + u8 ps_poll_threshold; + u8 pad[2]; +} __packed; + +struct acx_event_mask { + struct acx_header header; + + u32 event_mask; + u32 high_event_mask; /* Unused */ +} __packed; + +#define CFG_RX_FCS BIT(2) +#define CFG_RX_ALL_GOOD BIT(3) +#define CFG_UNI_FILTER_EN BIT(4) +#define CFG_BSSID_FILTER_EN BIT(5) +#define CFG_MC_FILTER_EN BIT(6) +#define CFG_MC_ADDR0_EN BIT(7) +#define CFG_MC_ADDR1_EN BIT(8) +#define CFG_BC_REJECT_EN BIT(9) +#define CFG_SSID_FILTER_EN BIT(10) +#define CFG_RX_INT_FCS_ERROR BIT(11) +#define CFG_RX_INT_ENCRYPTED BIT(12) +#define CFG_RX_WR_RX_STATUS BIT(13) +#define CFG_RX_FILTER_NULTI BIT(14) +#define CFG_RX_RESERVE BIT(15) +#define CFG_RX_TIMESTAMP_TSF BIT(16) + +#define CFG_RX_RSV_EN BIT(0) +#define CFG_RX_RCTS_ACK BIT(1) +#define CFG_RX_PRSP_EN BIT(2) +#define CFG_RX_PREQ_EN BIT(3) +#define CFG_RX_MGMT_EN BIT(4) +#define CFG_RX_FCS_ERROR BIT(5) +#define CFG_RX_DATA_EN BIT(6) +#define CFG_RX_CTL_EN BIT(7) +#define CFG_RX_CF_EN BIT(8) +#define CFG_RX_BCN_EN BIT(9) +#define CFG_RX_AUTH_EN BIT(10) +#define CFG_RX_ASSOC_EN BIT(11) + +#define SCAN_PASSIVE BIT(0) +#define SCAN_5GHZ_BAND BIT(1) +#define SCAN_TRIGGERED BIT(2) +#define SCAN_PRIORITY_HIGH BIT(3) + +struct acx_fw_gen_frame_rates { + struct acx_header header; + + u8 tx_ctrl_frame_rate; /* RATE_* */ + u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */ + u8 tx_mgt_frame_rate; + u8 tx_mgt_frame_mod; +} __packed; + +/* STA MAC */ +struct acx_dot11_station_id { + struct acx_header header; + + u8 mac[ETH_ALEN]; + u8 pad[2]; +} __packed; + +struct acx_feature_config { + struct acx_header header; + + u32 options; + u32 data_flow_options; +} __packed; + +struct acx_current_tx_power { + struct acx_header header; + + u8 current_tx_power; + u8 padding[3]; +} __packed; + +struct acx_dot11_default_key { + struct acx_header header; + + u8 id; + u8 pad[3]; +} __packed; + +struct acx_tsf_info { + struct acx_header header; + + u32 current_tsf_msb; + u32 current_tsf_lsb; + u32 last_TBTT_msb; + u32 last_TBTT_lsb; + u8 last_dtim_count; + u8 pad[3]; +} __packed; + +enum acx_wake_up_event { + WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/ + WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/ + WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */ + WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */ + WAKE_UP_EVENT_BITS_MASK = 0x0F +}; + +struct acx_wake_up_condition { + struct acx_header header; + + u8 wake_up_event; /* Only one bit can be set */ + u8 listen_interval; + u8 pad[2]; +} __packed; + +struct acx_aid { + struct acx_header header; + + /* + * To be set when associated with an AP. + */ + u16 aid; + u8 pad[2]; +} __packed; + +enum acx_preamble_type { + ACX_PREAMBLE_LONG = 0, + ACX_PREAMBLE_SHORT = 1 +}; + +struct acx_preamble { + struct acx_header header; + + /* + * When set, the WiLink transmits the frames with a short preamble and + * when cleared, the WiLink transmits the frames with a long preamble. + */ + u8 preamble; + u8 padding[3]; +} __packed; + +enum acx_ctsprotect_type { + CTSPROTECT_DISABLE = 0, + CTSPROTECT_ENABLE = 1 +}; + +struct acx_ctsprotect { + struct acx_header header; + u8 ctsprotect; + u8 padding[3]; +} __packed; + +struct acx_tx_statistics { + u32 internal_desc_overflow; +} __packed; + +struct acx_rx_statistics { + u32 out_of_mem; + u32 hdr_overflow; + u32 hw_stuck; + u32 dropped; + u32 fcs_err; + u32 xfr_hint_trig; + u32 path_reset; + u32 reset_counter; +} __packed; + +struct acx_dma_statistics { + u32 rx_requested; + u32 rx_errors; + u32 tx_requested; + u32 tx_errors; +} __packed; + +struct acx_isr_statistics { + /* host command complete */ + u32 cmd_cmplt; + + /* fiqisr() */ + u32 fiqs; + + /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ + u32 rx_headers; + + /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ + u32 rx_completes; + + /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ + u32 rx_mem_overflow; + + /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ + u32 rx_rdys; + + /* irqisr() */ + u32 irqs; + + /* (INT_STS_ND & INT_TRIG_TX_PROC) */ + u32 tx_procs; + + /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ + u32 decrypt_done; + + /* (INT_STS_ND & INT_TRIG_DMA0) */ + u32 dma0_done; + + /* (INT_STS_ND & INT_TRIG_DMA1) */ + u32 dma1_done; + + /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ + u32 tx_exch_complete; + + /* (INT_STS_ND & INT_TRIG_COMMAND) */ + u32 commands; + + /* (INT_STS_ND & INT_TRIG_RX_PROC) */ + u32 rx_procs; + + /* (INT_STS_ND & INT_TRIG_PM_802) */ + u32 hw_pm_mode_changes; + + /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ + u32 host_acknowledges; + + /* (INT_STS_ND & INT_TRIG_PM_PCI) */ + u32 pci_pm; + + /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ + u32 wakeups; + + /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ + u32 low_rssi; +} __packed; + +struct acx_wep_statistics { + /* WEP address keys configured */ + u32 addr_key_count; + + /* default keys configured */ + u32 default_key_count; + + u32 reserved; + + /* number of times that WEP key not found on lookup */ + u32 key_not_found; + + /* number of times that WEP key decryption failed */ + u32 decrypt_fail; + + /* WEP packets decrypted */ + u32 packets; + + /* WEP decrypt interrupts */ + u32 interrupt; +} __packed; + +#define ACX_MISSED_BEACONS_SPREAD 10 + +struct acx_pwr_statistics { + /* the amount of enters into power save mode (both PD & ELP) */ + u32 ps_enter; + + /* the amount of enters into ELP mode */ + u32 elp_enter; + + /* the amount of missing beacon interrupts to the host */ + u32 missing_bcns; + + /* the amount of wake on host-access times */ + u32 wake_on_host; + + /* the amount of wake on timer-expire */ + u32 wake_on_timer_exp; + + /* the number of packets that were transmitted with PS bit set */ + u32 tx_with_ps; + + /* the number of packets that were transmitted with PS bit clear */ + u32 tx_without_ps; + + /* the number of received beacons */ + u32 rcvd_beacons; + + /* the number of entering into PowerOn (power save off) */ + u32 power_save_off; + + /* the number of entries into power save mode */ + u16 enable_ps; + + /* + * the number of exits from power save, not including failed PS + * transitions + */ + u16 disable_ps; + + /* + * the number of times the TSF counter was adjusted because + * of drift + */ + u32 fix_tsf_ps; + + /* Gives statistics about the spread continuous missed beacons. + * The 16 LSB are dedicated for the PS mode. + * The 16 MSB are dedicated for the PS mode. + * cont_miss_bcns_spread[0] - single missed beacon. + * cont_miss_bcns_spread[1] - two continuous missed beacons. + * cont_miss_bcns_spread[2] - three continuous missed beacons. + * ... + * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. + */ + u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; + + /* the number of beacons in awake mode */ + u32 rcvd_awake_beacons; +} __packed; + +struct acx_mic_statistics { + u32 rx_pkts; + u32 calc_failure; +} __packed; + +struct acx_aes_statistics { + u32 encrypt_fail; + u32 decrypt_fail; + u32 encrypt_packets; + u32 decrypt_packets; + u32 encrypt_interrupt; + u32 decrypt_interrupt; +} __packed; + +struct acx_event_statistics { + u32 heart_beat; + u32 calibration; + u32 rx_mismatch; + u32 rx_mem_empty; + u32 rx_pool; + u32 oom_late; + u32 phy_transmit_error; + u32 tx_stuck; +} __packed; + +struct acx_ps_statistics { + u32 pspoll_timeouts; + u32 upsd_timeouts; + u32 upsd_max_sptime; + u32 upsd_max_apturn; + u32 pspoll_max_apturn; + u32 pspoll_utilization; + u32 upsd_utilization; +} __packed; + +struct acx_rxpipe_statistics { + u32 rx_prep_beacon_drop; + u32 descr_host_int_trig_rx_data; + u32 beacon_buffer_thres_host_int_trig_rx_data; + u32 missed_beacon_host_int_trig_rx_data; + u32 tx_xfr_host_int_trig_rx_data; +} __packed; + +struct acx_statistics { + struct acx_header header; + + struct acx_tx_statistics tx; + struct acx_rx_statistics rx; + struct acx_dma_statistics dma; + struct acx_isr_statistics isr; + struct acx_wep_statistics wep; + struct acx_pwr_statistics pwr; + struct acx_aes_statistics aes; + struct acx_mic_statistics mic; + struct acx_event_statistics event; + struct acx_ps_statistics ps; + struct acx_rxpipe_statistics rxpipe; +} __packed; + +#define ACX_MAX_RATE_CLASSES 8 +#define ACX_RATE_MASK_UNSPECIFIED 0 +#define ACX_RATE_RETRY_LIMIT 10 + +struct acx_rate_class { + u32 enabled_rates; + u8 short_retry_limit; + u8 long_retry_limit; + u8 aflags; + u8 reserved; +} __packed; + +struct acx_rate_policy { + struct acx_header header; + + u32 rate_class_cnt; + struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES]; +} __packed; + +struct wl1251_acx_memory { + __le16 num_stations; /* number of STAs to be supported. */ + u16 reserved_1; + + /* + * Nmber of memory buffers for the RX mem pool. + * The actual number may be less if there are + * not enough blocks left for the minimum num + * of TX ones. + */ + u8 rx_mem_block_num; + u8 reserved_2; + u8 num_tx_queues; /* From 1 to 16 */ + u8 host_if_options; /* HOST_IF* */ + u8 tx_min_mem_block_num; + u8 num_ssid_profiles; + __le16 debug_buffer_size; +} __packed; + + +#define ACX_RX_DESC_MIN 1 +#define ACX_RX_DESC_MAX 127 +#define ACX_RX_DESC_DEF 32 +struct wl1251_acx_rx_queue_config { + u8 num_descs; + u8 pad; + u8 type; + u8 priority; + __le32 dma_address; +} __packed; + +#define ACX_TX_DESC_MIN 1 +#define ACX_TX_DESC_MAX 127 +#define ACX_TX_DESC_DEF 16 +struct wl1251_acx_tx_queue_config { + u8 num_descs; + u8 pad[2]; + u8 attributes; +} __packed; + +#define MAX_TX_QUEUE_CONFIGS 5 +#define MAX_TX_QUEUES 4 +struct wl1251_acx_config_memory { + struct acx_header header; + + struct wl1251_acx_memory mem_config; + struct wl1251_acx_rx_queue_config rx_queue_config; + struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS]; +} __packed; + +struct wl1251_acx_mem_map { + struct acx_header header; + + void *code_start; + void *code_end; + + void *wep_defkey_start; + void *wep_defkey_end; + + void *sta_table_start; + void *sta_table_end; + + void *packet_template_start; + void *packet_template_end; + + void *queue_memory_start; + void *queue_memory_end; + + void *packet_memory_pool_start; + void *packet_memory_pool_end; + + void *debug_buffer1_start; + void *debug_buffer1_end; + + void *debug_buffer2_start; + void *debug_buffer2_end; + + /* Number of blocks FW allocated for TX packets */ + u32 num_tx_mem_blocks; + + /* Number of blocks FW allocated for RX packets */ + u32 num_rx_mem_blocks; +} __packed; + + +struct wl1251_acx_wr_tbtt_and_dtim { + + struct acx_header header; + + /* Time in TUs between two consecutive beacons */ + u16 tbtt; + + /* + * DTIM period + * For BSS: Number of TBTTs in a DTIM period (range: 1-10) + * For IBSS: value shall be set to 1 + */ + u8 dtim; + u8 padding; +} __packed; + +struct wl1251_acx_ac_cfg { + struct acx_header header; + + /* + * Access Category - The TX queue's access category + * (refer to AccessCategory_enum) + */ + u8 ac; + + /* + * The contention window minimum size (in slots) for + * the access class. + */ + u8 cw_min; + + /* + * The contention window maximum size (in slots) for + * the access class. + */ + u16 cw_max; + + /* The AIF value (in slots) for the access class. */ + u8 aifsn; + + u8 reserved; + + /* The TX Op Limit (in microseconds) for the access class. */ + u16 txop_limit; +} __packed; + + +enum wl1251_acx_channel_type { + CHANNEL_TYPE_DCF = 0, + CHANNEL_TYPE_EDCF = 1, + CHANNEL_TYPE_HCCA = 2, +}; + +enum wl1251_acx_ps_scheme { + /* regular ps: simple sending of packets */ + WL1251_ACX_PS_SCHEME_LEGACY = 0, + + /* sending a packet triggers a unscheduled apsd downstream */ + WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1, + + /* a pspoll packet will be sent before every data packet */ + WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2, + + /* scheduled apsd mode */ + WL1251_ACX_PS_SCHEME_SAPSD = 3, +}; + +enum wl1251_acx_ack_policy { + WL1251_ACX_ACK_POLICY_LEGACY = 0, + WL1251_ACX_ACK_POLICY_NO_ACK = 1, + WL1251_ACX_ACK_POLICY_BLOCK = 2, +}; + +struct wl1251_acx_tid_cfg { + struct acx_header header; + + /* tx queue id number (0-7) */ + u8 queue; + + /* channel access type for the queue, enum wl1251_acx_channel_type */ + u8 type; + + /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */ + u8 tsid; + + /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */ + u8 ps_scheme; + + /* the tx queue ack policy, enum wl1251_acx_ack_policy */ + u8 ack_policy; + + u8 padding[3]; + + /* not supported */ + u32 apsdconf[2]; +} __packed; + +/************************************************************************* + + Host Interrupt Register (WiLink -> Host) + +**************************************************************************/ + +/* RX packet is ready in Xfer buffer #0 */ +#define WL1251_ACX_INTR_RX0_DATA BIT(0) + +/* TX result(s) are in the TX complete buffer */ +#define WL1251_ACX_INTR_TX_RESULT BIT(1) + +/* OBSOLETE */ +#define WL1251_ACX_INTR_TX_XFR BIT(2) + +/* RX packet is ready in Xfer buffer #1 */ +#define WL1251_ACX_INTR_RX1_DATA BIT(3) + +/* Event was entered to Event MBOX #A */ +#define WL1251_ACX_INTR_EVENT_A BIT(4) + +/* Event was entered to Event MBOX #B */ +#define WL1251_ACX_INTR_EVENT_B BIT(5) + +/* OBSOLETE */ +#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6) + +/* Trace meassge on MBOX #A */ +#define WL1251_ACX_INTR_TRACE_A BIT(7) + +/* Trace meassge on MBOX #B */ +#define WL1251_ACX_INTR_TRACE_B BIT(8) + +/* Command processing completion */ +#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9) + +/* Init sequence is done */ +#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14) + +#define WL1251_ACX_INTR_ALL 0xFFFFFFFF + +enum { + ACX_WAKE_UP_CONDITIONS = 0x0002, + ACX_MEM_CFG = 0x0003, + ACX_SLOT = 0x0004, + ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */ + ACX_AC_CFG = 0x0007, + ACX_MEM_MAP = 0x0008, + ACX_AID = 0x000A, + ACX_RADIO_PARAM = 0x000B, /* Not used */ + ACX_CFG = 0x000C, /* Not used */ + ACX_FW_REV = 0x000D, + ACX_MEDIUM_USAGE = 0x000F, + ACX_RX_CFG = 0x0010, + ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ + ACX_BSS_IN_PS = 0x0012, /* for AP only */ + ACX_STATISTICS = 0x0013, /* Debug API */ + ACX_FEATURE_CFG = 0x0015, + ACX_MISC_CFG = 0x0017, /* Not used */ + ACX_TID_CFG = 0x001A, + ACX_BEACON_FILTER_OPT = 0x001F, + ACX_LOW_RSSI = 0x0020, + ACX_NOISE_HIST = 0x0021, + ACX_HDK_VERSION = 0x0022, /* ??? */ + ACX_PD_THRESHOLD = 0x0023, + ACX_DATA_PATH_PARAMS = 0x0024, /* WO */ + ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */ + ACX_CCA_THRESHOLD = 0x0025, + ACX_EVENT_MBOX_MASK = 0x0026, +#ifdef FW_RUNNING_AS_AP + ACX_DTIM_PERIOD = 0x0027, /* for AP only */ +#else + ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */ +#endif + ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/ + ACX_GPIO_CFG = 0x002A, /* Not used */ + ACX_GPIO_SET = 0x002B, /* Not used */ + ACX_PM_CFG = 0x002C, /* To Be Documented */ + ACX_CONN_MONIT_PARAMS = 0x002D, + ACX_AVERAGE_RSSI = 0x002E, /* Not used */ + ACX_CONS_TX_FAILURE = 0x002F, + ACX_BCN_DTIM_OPTIONS = 0x0031, + ACX_SG_ENABLE = 0x0032, + ACX_SG_CFG = 0x0033, + ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */ + ACX_LOW_SNR = 0x0037, /* To Be Documented */ + ACX_BEACON_FILTER_TABLE = 0x0038, + ACX_ARP_IP_FILTER = 0x0039, + ACX_ROAMING_STATISTICS_TBL = 0x003B, + ACX_RATE_POLICY = 0x003D, + ACX_CTS_PROTECTION = 0x003E, + ACX_SLEEP_AUTH = 0x003F, + ACX_PREAMBLE_TYPE = 0x0040, + ACX_ERROR_CNT = 0x0041, + ACX_FW_GEN_FRAME_RATES = 0x0042, + ACX_IBSS_FILTER = 0x0044, + ACX_SERVICE_PERIOD_TIMEOUT = 0x0045, + ACX_TSF_INFO = 0x0046, + ACX_CONFIG_PS_WMM = 0x0049, + ACX_ENABLE_RX_DATA_FILTER = 0x004A, + ACX_SET_RX_DATA_FILTER = 0x004B, + ACX_GET_DATA_FILTER_STATISTICS = 0x004C, + ACX_POWER_LEVEL_TABLE = 0x004D, + ACX_BET_ENABLE = 0x0050, + DOT11_STATION_ID = 0x1001, + DOT11_RX_MSDU_LIFE_TIME = 0x1004, + DOT11_CUR_TX_PWR = 0x100D, + DOT11_DEFAULT_KEY = 0x1010, + DOT11_RX_DOT11_MODE = 0x1012, + DOT11_RTS_THRESHOLD = 0x1013, + DOT11_GROUP_ADDRESS_TBL = 0x1014, + + MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, + + MAX_IE = 0xFFFF +}; + + +int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, + u8 mgt_rate, u8 mgt_mod); +int wl1251_acx_station_id(struct wl1251 *wl); +int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id); +int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, + u8 listen_interval); +int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth); +int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len); +int wl1251_acx_tx_power(struct wl1251 *wl, int power); +int wl1251_acx_feature_cfg(struct wl1251 *wl); +int wl1251_acx_mem_map(struct wl1251 *wl, + struct acx_header *mem_map, size_t len); +int wl1251_acx_data_path_params(struct wl1251 *wl, + struct acx_data_path_params_resp *data_path); +int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time); +int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter); +int wl1251_acx_pd_threshold(struct wl1251 *wl); +int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); +int wl1251_acx_group_address_tbl(struct wl1251 *wl); +int wl1251_acx_service_period_timeout(struct wl1251 *wl); +int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); +int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); +int wl1251_acx_beacon_filter_table(struct wl1251 *wl); +int wl1251_acx_conn_monit_params(struct wl1251 *wl); +int wl1251_acx_sg_enable(struct wl1251 *wl); +int wl1251_acx_sg_cfg(struct wl1251 *wl); +int wl1251_acx_cca_threshold(struct wl1251 *wl); +int wl1251_acx_bcn_dtim_options(struct wl1251 *wl); +int wl1251_acx_aid(struct wl1251 *wl, u16 aid); +int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask); +int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble); +int wl1251_acx_cts_protect(struct wl1251 *wl, + enum acx_ctsprotect_type ctsprotect); +int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats); +int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); +int wl1251_acx_rate_policies(struct wl1251 *wl); +int wl1251_acx_mem_cfg(struct wl1251 *wl); +int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); +int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, + u8 aifs, u16 txop); +int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, + enum wl1251_acx_channel_type type, + u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, + enum wl1251_acx_ack_policy ack_policy); + +#endif /* __WL1251_ACX_H__ */ diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/wl1251/boot.c new file mode 100644 index 000000000000..61572dfa1f60 --- /dev/null +++ b/drivers/net/wireless/wl1251/boot.c @@ -0,0 +1,557 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "reg.h" +#include "boot.h" +#include "io.h" +#include "spi.h" +#include "event.h" +#include "acx.h" + +void wl1251_boot_target_enable_interrupts(struct wl1251 *wl) +{ + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); + wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL); +} + +int wl1251_boot_soft_reset(struct wl1251 *wl) +{ + unsigned long timeout; + u32 boot_data; + + /* perform soft reset */ + wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); + + /* SOFT_RESET is self clearing */ + timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); + while (1) { + boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET); + wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); + if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) + break; + + if (time_after(jiffies, timeout)) { + /* 1.2 check pWhalBus->uSelfClearTime if the + * timeout was reached */ + wl1251_error("soft reset timeout"); + return -1; + } + + udelay(SOFT_RESET_STALL_TIME); + } + + /* disable Rx/Tx */ + wl1251_reg_write32(wl, ENABLE, 0x0); + + /* disable auto calibration on start*/ + wl1251_reg_write32(wl, SPARE_A2, 0xffff); + + return 0; +} + +int wl1251_boot_init_seq(struct wl1251 *wl) +{ + u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq; + + /* + * col #1: INTEGER_DIVIDER + * col #2: FRACTIONAL_DIVIDER + * col #3: ATTN_BB + * col #4: ALPHA_BB + * col #5: STOP_TIME_BB + * col #6: BB_PLL_LOOP_FILTER + */ + static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = { + + { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/ + { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/ + { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/ + { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/ + { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */ + }; + + /* read NVS params */ + scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6); + wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6); + + /* read ELP_CMD */ + elp_cmd = wl1251_reg_read32(wl, ELP_CMD); + wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd); + + /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */ + ref_freq = scr_pad6 & 0x000000FF; + wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq); + + wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9); + + /* + * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME) + */ + wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6); + + /* + * set the clock detect feature to work in the restart wu procedure + * (ELP_CFG_MODE[14]) and Select the clock source type + * (ELP_CFG_MODE[13:12]) + */ + tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000; + wl1251_reg_write32(wl, ELP_CFG_MODE, tmp); + + /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */ + elp_cmd |= 0x00000040; + wl1251_reg_write32(wl, ELP_CMD, elp_cmd); + + /* PG 1.2: Set the BB PLL stable time to be 1000usec + * (PLL_STABLE_TIME) */ + wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20); + + /* PG 1.2: read clock request time */ + init_data = wl1251_reg_read32(wl, CLK_REQ_TIME); + + /* + * PG 1.2: set the clock request time to be ref_clk_settling_time - + * 1ms = 4ms + */ + if (init_data > 0x21) + tmp = init_data - 0x21; + else + tmp = 0; + wl1251_reg_write32(wl, CLK_REQ_TIME, tmp); + + /* set BB PLL configurations in RF AFE */ + wl1251_reg_write32(wl, 0x003058cc, 0x4B5); + + /* set RF_AFE_REG_5 */ + wl1251_reg_write32(wl, 0x003058d4, 0x50); + + /* set RF_AFE_CTRL_REG_2 */ + wl1251_reg_write32(wl, 0x00305948, 0x11c001); + + /* + * change RF PLL and BB PLL divider for VCO clock and adjust VCO + * bais current(RF_AFE_REG_13) + */ + wl1251_reg_write32(wl, 0x003058f4, 0x1e); + + /* set BB PLL configurations */ + tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000; + wl1251_reg_write32(wl, 0x00305840, tmp); + + /* set fractional divider according to Appendix C-BB PLL + * Calculations + */ + tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER]; + wl1251_reg_write32(wl, 0x00305844, tmp); + + /* set the initial data for the sigma delta */ + wl1251_reg_write32(wl, 0x00305848, 0x3039); + + /* + * set the accumulator attenuation value, calibration loop1 + * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and + * the VCO gain + */ + tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) | + (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1; + wl1251_reg_write32(wl, 0x00305854, tmp); + + /* + * set the calibration stop time after holdoff time expires and set + * settling time HOLD_OFF_TIME_BB + */ + tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000; + wl1251_reg_write32(wl, 0x00305858, tmp); + + /* + * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL + * constant leakage current to linearize PFD to 0uA - + * BB_ILOOPF[7:3] + */ + tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030; + wl1251_reg_write32(wl, 0x003058f8, tmp); + + /* + * set regulator output voltage for n divider to + * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2], + * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB + * PLL auto-call to normal mode- BB_CALGAIN_3DB[8] + */ + wl1251_reg_write32(wl, 0x003058f0, 0x29); + + /* enable restart wakeup sequence (ELP_CMD[0]) */ + wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1); + + /* restart sequence completed */ + udelay(2000); + + return 0; +} + +static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag) +{ + u32 cpu_ctrl; + + /* 10.5.0 run the firmware (I) */ + cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL); + + /* 10.5.1 run the firmware (II) */ + cpu_ctrl &= ~flag; + wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); +} + +int wl1251_boot_run_firmware(struct wl1251 *wl) +{ + int loop, ret; + u32 chip_id, acx_intr; + + wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); + + chip_id = wl1251_reg_read32(wl, CHIP_ID_B); + + wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); + + if (chip_id != wl->chip_id) { + wl1251_error("chip id doesn't match after firmware boot"); + return -EIO; + } + + /* wait for init to complete */ + loop = 0; + while (loop++ < INIT_LOOP) { + udelay(INIT_LOOP_DELAY); + acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + + if (acx_intr == 0xffffffff) { + wl1251_error("error reading hardware complete " + "init indication"); + return -EIO; + } + /* check that ACX_INTR_INIT_COMPLETE is enabled */ + else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) { + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, + WL1251_ACX_INTR_INIT_COMPLETE); + break; + } + } + + if (loop > INIT_LOOP) { + wl1251_error("timeout waiting for the hardware to " + "complete initialization"); + return -EIO; + } + + /* get hardware config command mail box */ + wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR); + + /* get hardware config event mail box */ + wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR); + + /* set the working partition to its "running" mode offset */ + wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START, + WL1251_PART_WORK_MEM_SIZE, + WL1251_PART_WORK_REG_START, + WL1251_PART_WORK_REG_SIZE); + + wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", + wl->cmd_box_addr, wl->event_box_addr); + + wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver)); + + /* + * in case of full asynchronous mode the firmware event must be + * ready to receive event from the command mailbox + */ + + /* enable gpio interrupts */ + wl1251_enable_interrupts(wl); + + /* Enable target's interrupts */ + wl->intr_mask = WL1251_ACX_INTR_RX0_DATA | + WL1251_ACX_INTR_RX1_DATA | + WL1251_ACX_INTR_TX_RESULT | + WL1251_ACX_INTR_EVENT_A | + WL1251_ACX_INTR_EVENT_B | + WL1251_ACX_INTR_INIT_COMPLETE; + wl1251_boot_target_enable_interrupts(wl); + + wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID | + SYNCHRONIZATION_TIMEOUT_EVENT_ID | + ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | + ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | + REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | + BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; + + ret = wl1251_event_unmask(wl); + if (ret < 0) { + wl1251_error("EVENT mask setting failed"); + return ret; + } + + wl1251_event_mbox_config(wl); + + /* firmware startup completed */ + return 0; +} + +static int wl1251_boot_upload_firmware(struct wl1251 *wl) +{ + int addr, chunk_num, partition_limit; + size_t fw_data_len, len; + u8 *p, *buf; + + /* whal_FwCtrl_LoadFwImageSm() */ + + wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x", + wl1251_reg_read32(wl, CHIP_ID_B)); + + /* 10.0 check firmware length and set partition */ + fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) | + (wl->fw[6] << 8) | (wl->fw[7]); + + wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len, + CHUNK_SIZE); + + if ((fw_data_len % 4) != 0) { + wl1251_error("firmware length not multiple of four"); + return -EIO; + } + + buf = kmalloc(CHUNK_SIZE, GFP_KERNEL); + if (!buf) { + wl1251_error("allocation for firmware upload chunk failed"); + return -ENOMEM; + } + + wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, + WL1251_PART_DOWN_MEM_SIZE, + WL1251_PART_DOWN_REG_START, + WL1251_PART_DOWN_REG_SIZE); + + /* 10.1 set partition limit and chunk num */ + chunk_num = 0; + partition_limit = WL1251_PART_DOWN_MEM_SIZE; + + while (chunk_num < fw_data_len / CHUNK_SIZE) { + /* 10.2 update partition, if needed */ + addr = WL1251_PART_DOWN_MEM_START + + (chunk_num + 2) * CHUNK_SIZE; + if (addr > partition_limit) { + addr = WL1251_PART_DOWN_MEM_START + + chunk_num * CHUNK_SIZE; + partition_limit = chunk_num * CHUNK_SIZE + + WL1251_PART_DOWN_MEM_SIZE; + wl1251_set_partition(wl, + addr, + WL1251_PART_DOWN_MEM_SIZE, + WL1251_PART_DOWN_REG_START, + WL1251_PART_DOWN_REG_SIZE); + } + + /* 10.3 upload the chunk */ + addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; + p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; + wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", + p, addr); + + /* need to copy the chunk for dma */ + len = CHUNK_SIZE; + memcpy(buf, p, len); + wl1251_mem_write(wl, addr, buf, len); + + chunk_num++; + } + + /* 10.4 upload the last chunk */ + addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; + p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; + + /* need to copy the chunk for dma */ + len = fw_data_len % CHUNK_SIZE; + memcpy(buf, p, len); + + wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", + len, p, addr); + wl1251_mem_write(wl, addr, buf, len); + + kfree(buf); + + return 0; +} + +static int wl1251_boot_upload_nvs(struct wl1251 *wl) +{ + size_t nvs_len, nvs_bytes_written, burst_len; + int nvs_start, i; + u32 dest_addr, val; + u8 *nvs_ptr, *nvs; + + nvs = wl->nvs; + if (nvs == NULL) + return -ENODEV; + + nvs_ptr = nvs; + + nvs_len = wl->nvs_len; + nvs_start = wl->fw_len; + + /* + * Layout before the actual NVS tables: + * 1 byte : burst length. + * 2 bytes: destination address. + * n bytes: data to burst copy. + * + * This is ended by a 0 length, then the NVS tables. + */ + + while (nvs_ptr[0]) { + burst_len = nvs_ptr[0]; + dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); + + /* We move our pointer to the data */ + nvs_ptr += 3; + + for (i = 0; i < burst_len; i++) { + val = (nvs_ptr[0] | (nvs_ptr[1] << 8) + | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); + + wl1251_debug(DEBUG_BOOT, + "nvs burst write 0x%x: 0x%x", + dest_addr, val); + wl1251_mem_write32(wl, dest_addr, val); + + nvs_ptr += 4; + dest_addr += 4; + } + } + + /* + * We've reached the first zero length, the first NVS table + * is 7 bytes further. + */ + nvs_ptr += 7; + nvs_len -= nvs_ptr - nvs; + nvs_len = ALIGN(nvs_len, 4); + + /* Now we must set the partition correctly */ + wl1251_set_partition(wl, nvs_start, + WL1251_PART_DOWN_MEM_SIZE, + WL1251_PART_DOWN_REG_START, + WL1251_PART_DOWN_REG_SIZE); + + /* And finally we upload the NVS tables */ + nvs_bytes_written = 0; + while (nvs_bytes_written < nvs_len) { + val = (nvs_ptr[0] | (nvs_ptr[1] << 8) + | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); + + val = cpu_to_le32(val); + + wl1251_debug(DEBUG_BOOT, + "nvs write table 0x%x: 0x%x", + nvs_start, val); + wl1251_mem_write32(wl, nvs_start, val); + + nvs_ptr += 4; + nvs_bytes_written += 4; + nvs_start += 4; + } + + return 0; +} + +int wl1251_boot(struct wl1251 *wl) +{ + int ret = 0, minor_minor_e2_ver; + u32 tmp, boot_data; + + /* halt embedded ARM CPU while loading firmware */ + wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT); + + ret = wl1251_boot_soft_reset(wl); + if (ret < 0) + goto out; + + /* 2. start processing NVS file */ + if (wl->use_eeprom) { + wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); + /* Wait for EEPROM NVS burst read to complete */ + msleep(40); + wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); + } else { + ret = wl1251_boot_upload_nvs(wl); + if (ret < 0) + goto out; + + /* write firmware's last address (ie. it's length) to + * ACX_EEPROMLESS_IND_REG */ + wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); + } + + /* 6. read the EEPROM parameters */ + tmp = wl1251_reg_read32(wl, SCR_PAD2); + + /* 7. read bootdata */ + wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8; + wl->boot_attr.major = (tmp & 0x00FF0000) >> 16; + tmp = wl1251_reg_read32(wl, SCR_PAD3); + + /* 8. check bootdata and call restart sequence */ + wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16; + minor_minor_e2_ver = (tmp & 0xFF000000) >> 24; + + wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x " + "minorE2Ver 0x%x minor_minor_e2_ver 0x%x", + wl->boot_attr.radio_type, wl->boot_attr.major, + wl->boot_attr.minor, minor_minor_e2_ver); + + ret = wl1251_boot_init_seq(wl); + if (ret < 0) + goto out; + + /* 9. NVS processing done */ + boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL); + + wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data); + + /* 10. check that ECPU_CONTROL_HALT bits are set in + * pWhalBus->uBootData and start uploading firmware + */ + if ((boot_data & ECPU_CONTROL_HALT) == 0) { + wl1251_error("boot failed, ECPU_CONTROL_HALT not set"); + ret = -EIO; + goto out; + } + + ret = wl1251_boot_upload_firmware(wl); + if (ret < 0) + goto out; + + /* 10.5 start firmware */ + ret = wl1251_boot_run_firmware(wl); + if (ret < 0) + goto out; + +out: + return ret; +} diff --git a/drivers/net/wireless/wl1251/boot.h b/drivers/net/wireless/wl1251/boot.h new file mode 100644 index 000000000000..7661bc5e4662 --- /dev/null +++ b/drivers/net/wireless/wl1251/boot.h @@ -0,0 +1,39 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __BOOT_H__ +#define __BOOT_H__ + +#include "wl1251.h" + +int wl1251_boot_soft_reset(struct wl1251 *wl); +int wl1251_boot_init_seq(struct wl1251 *wl); +int wl1251_boot_run_firmware(struct wl1251 *wl); +void wl1251_boot_target_enable_interrupts(struct wl1251 *wl); +int wl1251_boot(struct wl1251 *wl); + +/* number of times we try to read the INIT interrupt */ +#define INIT_LOOP 20000 + +/* delay between retries */ +#define INIT_LOOP_DELAY 50 + +#endif diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c new file mode 100644 index 000000000000..0ade4bd617c0 --- /dev/null +++ b/drivers/net/wireless/wl1251/cmd.c @@ -0,0 +1,496 @@ +#include "cmd.h" + +#include +#include +#include + +#include "wl1251.h" +#include "reg.h" +#include "io.h" +#include "ps.h" +#include "acx.h" + +/** + * send command to firmware + * + * @wl: wl struct + * @id: command id + * @buf: buffer containing the command, must work with dma + * @len: length of the buffer + */ +int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len) +{ + struct wl1251_cmd_header *cmd; + unsigned long timeout; + u32 intr; + int ret = 0; + + cmd = buf; + cmd->id = id; + cmd->status = 0; + + WARN_ON(len % 4 != 0); + + wl1251_mem_write(wl, wl->cmd_box_addr, buf, len); + + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); + + timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT); + + intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) { + if (time_after(jiffies, timeout)) { + wl1251_error("command complete timeout"); + ret = -ETIMEDOUT; + goto out; + } + + msleep(1); + + intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + } + + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, + WL1251_ACX_INTR_CMD_COMPLETE); + +out: + return ret; +} + +/** + * send test command to firmware + * + * @wl: wl struct + * @buf: buffer containing the command, with all headers, must work with dma + * @len: length of the buffer + * @answer: is answer needed + */ +int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer) +{ + int ret; + + wl1251_debug(DEBUG_CMD, "cmd test"); + + ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len); + + if (ret < 0) { + wl1251_warning("TEST command failed"); + return ret; + } + + if (answer) { + struct wl1251_command *cmd_answer; + + /* + * The test command got in, we can read the answer. + * The answer would be a wl1251_command, where the + * parameter array contains the actual answer. + */ + wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len); + + cmd_answer = buf; + + if (cmd_answer->header.status != CMD_STATUS_SUCCESS) + wl1251_error("TEST command answer error: %d", + cmd_answer->header.status); + } + + return 0; +} + +/** + * read acx from firmware + * + * @wl: wl struct + * @id: acx id + * @buf: buffer for the response, including all headers, must work with dma + * @len: lenght of buf + */ +int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len) +{ + struct acx_header *acx = buf; + int ret; + + wl1251_debug(DEBUG_CMD, "cmd interrogate"); + + acx->id = id; + + /* payload length, does not include any headers */ + acx->len = len - sizeof(*acx); + + ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_error("INTERROGATE command failed"); + goto out; + } + + /* the interrogate command got in, we can read the answer */ + wl1251_mem_read(wl, wl->cmd_box_addr, buf, len); + + acx = buf; + if (acx->cmd.status != CMD_STATUS_SUCCESS) + wl1251_error("INTERROGATE command error: %d", + acx->cmd.status); + +out: + return ret; +} + +/** + * write acx value to firmware + * + * @wl: wl struct + * @id: acx id + * @buf: buffer containing acx, including all headers, must work with dma + * @len: length of buf + */ +int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len) +{ + struct acx_header *acx = buf; + int ret; + + wl1251_debug(DEBUG_CMD, "cmd configure"); + + acx->id = id; + + /* payload length, does not include any headers */ + acx->len = len - sizeof(*acx); + + ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len); + if (ret < 0) { + wl1251_warning("CONFIGURE command NOK"); + return ret; + } + + return 0; +} + +int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, + void *bitmap, u16 bitmap_len, u8 bitmap_control) +{ + struct wl1251_cmd_vbm_update *vbm; + int ret; + + wl1251_debug(DEBUG_CMD, "cmd vbm"); + + vbm = kzalloc(sizeof(*vbm), GFP_KERNEL); + if (!vbm) { + ret = -ENOMEM; + goto out; + } + + /* Count and period will be filled by the target */ + vbm->tim.bitmap_ctrl = bitmap_control; + if (bitmap_len > PARTIAL_VBM_MAX) { + wl1251_warning("cmd vbm len is %d B, truncating to %d", + bitmap_len, PARTIAL_VBM_MAX); + bitmap_len = PARTIAL_VBM_MAX; + } + memcpy(vbm->tim.pvb_field, bitmap, bitmap_len); + vbm->tim.identity = identity; + vbm->tim.length = bitmap_len + 3; + + vbm->len = cpu_to_le16(bitmap_len + 5); + + ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm)); + if (ret < 0) { + wl1251_error("VBM command failed"); + goto out; + } + +out: + kfree(vbm); + return ret; +} + +int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) +{ + struct cmd_enabledisable_path *cmd; + int ret; + u16 cmd_rx, cmd_tx; + + wl1251_debug(DEBUG_CMD, "cmd data path"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->channel = channel; + + if (enable) { + cmd_rx = CMD_ENABLE_RX; + cmd_tx = CMD_ENABLE_TX; + } else { + cmd_rx = CMD_DISABLE_RX; + cmd_tx = CMD_DISABLE_TX; + } + + ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); + if (ret < 0) { + wl1251_error("rx %s cmd for channel %d failed", + enable ? "start" : "stop", channel); + goto out; + } + + wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", + enable ? "start" : "stop", channel); + + ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); + if (ret < 0) { + wl1251_error("tx %s cmd for channel %d failed", + enable ? "start" : "stop", channel); + return ret; + } + + wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", + enable ? "start" : "stop", channel); + +out: + kfree(cmd); + return ret; +} + +int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, + u16 beacon_interval, u8 dtim_interval) +{ + struct cmd_join *join; + int ret, i; + u8 *bssid; + + join = kzalloc(sizeof(*join), GFP_KERNEL); + if (!join) { + ret = -ENOMEM; + goto out; + } + + wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d", + bss_type == BSS_TYPE_IBSS ? " ibss" : "", + channel, beacon_interval, dtim_interval); + + /* Reverse order BSSID */ + bssid = (u8 *) &join->bssid_lsb; + for (i = 0; i < ETH_ALEN; i++) + bssid[i] = wl->bssid[ETH_ALEN - i - 1]; + + join->rx_config_options = wl->rx_config; + join->rx_filter_options = wl->rx_filter; + + /* + * FIXME: disable temporarily all filters because after commit + * 9cef8737 "mac80211: fix managed mode BSSID handling" broke + * association. The filter logic needs to be implemented properly + * and once that is done, this hack can be removed. + */ + join->rx_config_options = 0; + join->rx_filter_options = WL1251_DEFAULT_RX_FILTER; + + join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | + RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; + + join->beacon_interval = beacon_interval; + join->dtim_interval = dtim_interval; + join->bss_type = bss_type; + join->channel = channel; + join->ctrl = JOIN_CMD_CTRL_TX_FLUSH; + + ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join)); + if (ret < 0) { + wl1251_error("failed to initiate cmd join"); + goto out; + } + +out: + kfree(join); + return ret; +} + +int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode) +{ + struct wl1251_cmd_ps_params *ps_params = NULL; + int ret = 0; + + wl1251_debug(DEBUG_CMD, "cmd set ps mode"); + + ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); + if (!ps_params) { + ret = -ENOMEM; + goto out; + } + + ps_params->ps_mode = ps_mode; + ps_params->send_null_data = 1; + ps_params->retries = 5; + ps_params->hang_over_period = 128; + ps_params->null_data_rate = 1; /* 1 Mbps */ + + ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params, + sizeof(*ps_params)); + if (ret < 0) { + wl1251_error("cmd set_ps_mode failed"); + goto out; + } + +out: + kfree(ps_params); + return ret; +} + +int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, + size_t len) +{ + struct cmd_read_write_memory *cmd; + int ret = 0; + + wl1251_debug(DEBUG_CMD, "cmd read memory"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + WARN_ON(len > MAX_READ_SIZE); + len = min_t(size_t, len, MAX_READ_SIZE); + + cmd->addr = addr; + cmd->size = len; + + ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd)); + if (ret < 0) { + wl1251_error("read memory command failed: %d", ret); + goto out; + } + + /* the read command got in, we can now read the answer */ + wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); + + if (cmd->header.status != CMD_STATUS_SUCCESS) + wl1251_error("error in read command result: %d", + cmd->header.status); + + memcpy(answer, cmd->value, len); + +out: + kfree(cmd); + return ret; +} + +int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, + void *buf, size_t buf_len) +{ + struct wl1251_cmd_packet_template *cmd; + size_t cmd_len; + int ret = 0; + + wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id); + + WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE); + buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE); + cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4); + + cmd = kzalloc(cmd_len, GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->size = cpu_to_le16(buf_len); + + if (buf) + memcpy(cmd->data, buf, buf_len); + + ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len); + if (ret < 0) { + wl1251_warning("cmd set_template failed: %d", ret); + goto out; + } + +out: + kfree(cmd); + return ret; +} + +int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, + struct ieee80211_channel *channels[], + unsigned int n_channels, unsigned int n_probes) +{ + struct wl1251_cmd_scan *cmd; + int i, ret = 0; + + wl1251_debug(DEBUG_CMD, "cmd scan"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); + cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN | + CFG_RX_MGMT_EN | + CFG_RX_BCN_EN); + cmd->params.scan_options = 0; + cmd->params.num_channels = n_channels; + cmd->params.num_probe_requests = n_probes; + cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ + cmd->params.tid_trigger = 0; + + for (i = 0; i < n_channels; i++) { + cmd->channels[i].min_duration = + cpu_to_le32(WL1251_SCAN_MIN_DURATION); + cmd->channels[i].max_duration = + cpu_to_le32(WL1251_SCAN_MAX_DURATION); + memset(&cmd->channels[i].bssid_lsb, 0xff, 4); + memset(&cmd->channels[i].bssid_msb, 0xff, 2); + cmd->channels[i].early_termination = 0; + cmd->channels[i].tx_power_att = 0; + cmd->channels[i].channel = channels[i]->hw_value; + } + + cmd->params.ssid_len = ssid_len; + if (ssid) + memcpy(cmd->params.ssid, ssid, ssid_len); + + ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); + if (ret < 0) { + wl1251_error("cmd scan failed: %d", ret); + goto out; + } + + wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); + + if (cmd->header.status != CMD_STATUS_SUCCESS) { + wl1251_error("cmd scan status wasn't success: %d", + cmd->header.status); + ret = -EIO; + goto out; + } + +out: + kfree(cmd); + return ret; +} + +int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout) +{ + struct wl1251_cmd_trigger_scan_to *cmd; + int ret; + + wl1251_debug(DEBUG_CMD, "cmd trigger scan to"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->timeout = timeout; + + ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd)); + if (ret < 0) { + wl1251_error("cmd trigger scan to failed: %d", ret); + goto out; + } + +out: + kfree(cmd); + return ret; +} diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h new file mode 100644 index 000000000000..e5c74c631374 --- /dev/null +++ b/drivers/net/wireless/wl1251/cmd.h @@ -0,0 +1,415 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_CMD_H__ +#define __WL1251_CMD_H__ + +#include "wl1251.h" + +#include + +struct acx_header; + +int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len); +int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer); +int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len); +int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); +int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, + void *bitmap, u16 bitmap_len, u8 bitmap_control); +int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable); +int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, + u16 beacon_interval, u8 dtim_interval); +int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); +int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, + size_t len); +int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, + void *buf, size_t buf_len); +int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, + struct ieee80211_channel *channels[], + unsigned int n_channels, unsigned int n_probes); +int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout); + +/* unit ms */ +#define WL1251_COMMAND_TIMEOUT 2000 + +enum wl1251_commands { + CMD_RESET = 0, + CMD_INTERROGATE = 1, /*use this to read information elements*/ + CMD_CONFIGURE = 2, /*use this to write information elements*/ + CMD_ENABLE_RX = 3, + CMD_ENABLE_TX = 4, + CMD_DISABLE_RX = 5, + CMD_DISABLE_TX = 6, + CMD_SCAN = 8, + CMD_STOP_SCAN = 9, + CMD_VBM = 10, + CMD_START_JOIN = 11, + CMD_SET_KEYS = 12, + CMD_READ_MEMORY = 13, + CMD_WRITE_MEMORY = 14, + CMD_BEACON = 19, + CMD_PROBE_RESP = 20, + CMD_NULL_DATA = 21, + CMD_PROBE_REQ = 22, + CMD_TEST = 23, + CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */ + CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */ + CMD_NOISE_HIST = 28, + CMD_RX_RESET = 29, + CMD_PS_POLL = 30, + CMD_QOS_NULL_DATA = 31, + CMD_LNA_CONTROL = 32, + CMD_SET_BCN_MODE = 33, + CMD_MEASUREMENT = 34, + CMD_STOP_MEASUREMENT = 35, + CMD_DISCONNECT = 36, + CMD_SET_PS_MODE = 37, + CMD_CHANNEL_SWITCH = 38, + CMD_STOP_CHANNEL_SWICTH = 39, + CMD_AP_DISCOVERY = 40, + CMD_STOP_AP_DISCOVERY = 41, + CMD_SPS_SCAN = 42, + CMD_STOP_SPS_SCAN = 43, + CMD_HEALTH_CHECK = 45, + CMD_DEBUG = 46, + CMD_TRIGGER_SCAN_TO = 47, + + NUM_COMMANDS, + MAX_COMMAND_ID = 0xFFFF, +}; + +#define MAX_CMD_PARAMS 572 + +struct wl1251_cmd_header { + u16 id; + u16 status; + /* payload */ + u8 data[0]; +} __packed; + +struct wl1251_command { + struct wl1251_cmd_header header; + u8 parameters[MAX_CMD_PARAMS]; +} __packed; + +enum { + CMD_MAILBOX_IDLE = 0, + CMD_STATUS_SUCCESS = 1, + CMD_STATUS_UNKNOWN_CMD = 2, + CMD_STATUS_UNKNOWN_IE = 3, + CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11, + CMD_STATUS_RX_BUSY = 13, + CMD_STATUS_INVALID_PARAM = 14, + CMD_STATUS_TEMPLATE_TOO_LARGE = 15, + CMD_STATUS_OUT_OF_MEMORY = 16, + CMD_STATUS_STA_TABLE_FULL = 17, + CMD_STATUS_RADIO_ERROR = 18, + CMD_STATUS_WRONG_NESTING = 19, + CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/ + CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/ + MAX_COMMAND_STATUS = 0xff +}; + + +/* + * CMD_READ_MEMORY + * + * The host issues this command to read the WiLink device memory/registers. + * + * Note: The Base Band address has special handling (16 bits registers and + * addresses). For more information, see the hardware specification. + */ +/* + * CMD_WRITE_MEMORY + * + * The host issues this command to write the WiLink device memory/registers. + * + * The Base Band address has special handling (16 bits registers and + * addresses). For more information, see the hardware specification. + */ +#define MAX_READ_SIZE 256 + +struct cmd_read_write_memory { + struct wl1251_cmd_header header; + + /* The address of the memory to read from or write to.*/ + u32 addr; + + /* The amount of data in bytes to read from or write to the WiLink + * device.*/ + u32 size; + + /* The actual value read from or written to the Wilink. The source + of this field is the Host in WRITE command or the Wilink in READ + command. */ + u8 value[MAX_READ_SIZE]; +} __packed; + +#define CMDMBOX_HEADER_LEN 4 +#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 + +#define WL1251_SCAN_MIN_DURATION 30000 +#define WL1251_SCAN_MAX_DURATION 60000 + +#define WL1251_SCAN_NUM_PROBES 3 + +struct wl1251_scan_parameters { + __le32 rx_config_options; + __le32 rx_filter_options; + + /* + * Scan options: + * bit 0: When this bit is set, passive scan. + * bit 1: Band, when this bit is set we scan + * in the 5Ghz band. + * bit 2: voice mode, 0 for normal scan. + * bit 3: scan priority, 1 for high priority. + */ + __le16 scan_options; + + /* Number of channels to scan */ + u8 num_channels; + + /* Number opf probe requests to send, per channel */ + u8 num_probe_requests; + + /* Rate and modulation for probe requests */ + __le16 tx_rate; + + u8 tid_trigger; + u8 ssid_len; + u8 ssid[32]; + +} __packed; + +struct wl1251_scan_ch_parameters { + __le32 min_duration; /* in TU */ + __le32 max_duration; /* in TU */ + u32 bssid_lsb; + u16 bssid_msb; + + /* + * bits 0-3: Early termination count. + * bits 4-5: Early termination condition. + */ + u8 early_termination; + + u8 tx_power_att; + u8 channel; + u8 pad[3]; +} __packed; + +/* SCAN parameters */ +#define SCAN_MAX_NUM_OF_CHANNELS 16 + +struct wl1251_cmd_scan { + struct wl1251_cmd_header header; + + struct wl1251_scan_parameters params; + struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; +} __packed; + +enum { + BSS_TYPE_IBSS = 0, + BSS_TYPE_STA_BSS = 2, + BSS_TYPE_AP_BSS = 3, + MAX_BSS_TYPE = 0xFF +}; + +#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */ +#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */ + + +struct cmd_join { + struct wl1251_cmd_header header; + + u32 bssid_lsb; + u16 bssid_msb; + u16 beacon_interval; /* in TBTTs */ + u32 rx_config_options; + u32 rx_filter_options; + + /* + * The target uses this field to determine the rate at + * which to transmit control frame responses (such as + * ACK or CTS frames). + */ + u16 basic_rate_set; + u8 dtim_interval; + u8 tx_ctrl_frame_rate; /* OBSOLETE */ + u8 tx_ctrl_frame_mod; /* OBSOLETE */ + /* + * bits 0-2: This bitwise field specifies the type + * of BSS to start or join (BSS_TYPE_*). + * bit 4: Band - The radio band in which to join + * or start. + * 0 - 2.4GHz band + * 1 - 5GHz band + * bits 3, 5-7: Reserved + */ + u8 bss_type; + u8 channel; + u8 ssid_len; + u8 ssid[IW_ESSID_MAX_SIZE]; + u8 ctrl; /* JOIN_CMD_CTRL_* */ + u8 tx_mgt_frame_rate; /* OBSOLETE */ + u8 tx_mgt_frame_mod; /* OBSOLETE */ + u8 reserved; +} __packed; + +struct cmd_enabledisable_path { + struct wl1251_cmd_header header; + + u8 channel; + u8 padding[3]; +} __packed; + +#define WL1251_MAX_TEMPLATE_SIZE 300 + +struct wl1251_cmd_packet_template { + struct wl1251_cmd_header header; + + __le16 size; + u8 data[0]; +} __packed; + +#define TIM_ELE_ID 5 +#define PARTIAL_VBM_MAX 251 + +struct wl1251_tim { + u8 identity; + u8 length; + u8 dtim_count; + u8 dtim_period; + u8 bitmap_ctrl; + u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ +} __packed; + +/* Virtual Bit Map update */ +struct wl1251_cmd_vbm_update { + struct wl1251_cmd_header header; + __le16 len; + u8 padding[2]; + struct wl1251_tim tim; +} __packed; + +enum wl1251_cmd_ps_mode { + STATION_ACTIVE_MODE, + STATION_POWER_SAVE_MODE +}; + +struct wl1251_cmd_ps_params { + struct wl1251_cmd_header header; + + u8 ps_mode; /* STATION_* */ + u8 send_null_data; /* Do we have to send NULL data packet ? */ + u8 retries; /* Number of retires for the initial NULL data packet */ + + /* + * TUs during which the target stays awake after switching + * to power save mode. + */ + u8 hang_over_period; + u16 null_data_rate; + u8 pad[2]; +} __packed; + +struct wl1251_cmd_trigger_scan_to { + struct wl1251_cmd_header header; + + u32 timeout; +} __packed; + +/* HW encryption keys */ +#define NUM_ACCESS_CATEGORIES_COPY 4 +#define MAX_KEY_SIZE 32 + +/* When set, disable HW encryption */ +#define DF_ENCRYPTION_DISABLE 0x01 +/* When set, disable HW decryption */ +#define DF_SNIFF_MODE_ENABLE 0x80 + +enum wl1251_cmd_key_action { + KEY_ADD_OR_REPLACE = 1, + KEY_REMOVE = 2, + KEY_SET_ID = 3, + MAX_KEY_ACTION = 0xffff, +}; + +enum wl1251_cmd_key_type { + KEY_WEP_DEFAULT = 0, + KEY_WEP_ADDR = 1, + KEY_AES_GROUP = 4, + KEY_AES_PAIRWISE = 5, + KEY_WEP_GROUP = 6, + KEY_TKIP_MIC_GROUP = 10, + KEY_TKIP_MIC_PAIRWISE = 11, +}; + +/* + * + * key_type_e key size key format + * ---------- --------- ---------- + * 0x00 5, 13, 29 Key data + * 0x01 5, 13, 29 Key data + * 0x04 16 16 bytes of key data + * 0x05 16 16 bytes of key data + * 0x0a 32 16 bytes of TKIP key data + * 8 bytes of RX MIC key data + * 8 bytes of TX MIC key data + * 0x0b 32 16 bytes of TKIP key data + * 8 bytes of RX MIC key data + * 8 bytes of TX MIC key data + * + */ + +struct wl1251_cmd_set_keys { + struct wl1251_cmd_header header; + + /* Ignored for default WEP key */ + u8 addr[ETH_ALEN]; + + /* key_action_e */ + u16 key_action; + + u16 reserved_1; + + /* key size in bytes */ + u8 key_size; + + /* key_type_e */ + u8 key_type; + u8 ssid_profile; + + /* + * TKIP, AES: frame's key id field. + * For WEP default key: key id; + */ + u8 id; + u8 reserved_2[6]; + u8 key[MAX_KEY_SIZE]; + u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; + u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; +} __packed; + + +#endif /* __WL1251_CMD_H__ */ diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/wl1251/debugfs.c new file mode 100644 index 000000000000..6e5caaa9f613 --- /dev/null +++ b/drivers/net/wireless/wl1251/debugfs.c @@ -0,0 +1,541 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "debugfs.h" + +#include +#include + +#include "wl1251.h" +#include "acx.h" +#include "ps.h" + +/* ms */ +#define WL1251_DEBUGFS_STATS_LIFETIME 1000 + +/* debugfs macros idea from mac80211 */ + +#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ +static ssize_t name## _read(struct file *file, char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1251 *wl = file->private_data; \ + char buf[buflen]; \ + int res; \ + \ + res = scnprintf(buf, buflen, fmt "\n", ##value); \ + return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ +} \ + \ +static const struct file_operations name## _ops = { \ + .read = name## _read, \ + .open = wl1251_open_file_generic, \ +}; + +#define DEBUGFS_ADD(name, parent) \ + wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ + wl, &name## _ops); \ + if (IS_ERR(wl->debugfs.name)) { \ + ret = PTR_ERR(wl->debugfs.name); \ + wl->debugfs.name = NULL; \ + goto out; \ + } + +#define DEBUGFS_DEL(name) \ + do { \ + debugfs_remove(wl->debugfs.name); \ + wl->debugfs.name = NULL; \ + } while (0) + +#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \ +static ssize_t sub## _ ##name## _read(struct file *file, \ + char __user *userbuf, \ + size_t count, loff_t *ppos) \ +{ \ + struct wl1251 *wl = file->private_data; \ + char buf[buflen]; \ + int res; \ + \ + wl1251_debugfs_update_stats(wl); \ + \ + res = scnprintf(buf, buflen, fmt "\n", \ + wl->stats.fw_stats->sub.name); \ + return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ +} \ + \ +static const struct file_operations sub## _ ##name## _ops = { \ + .read = sub## _ ##name## _read, \ + .open = wl1251_open_file_generic, \ +}; + +#define DEBUGFS_FWSTATS_ADD(sub, name) \ + DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) + +#define DEBUGFS_FWSTATS_DEL(sub, name) \ + DEBUGFS_DEL(sub## _ ##name) + +static void wl1251_debugfs_update_stats(struct wl1251 *wl) +{ + int ret; + + mutex_lock(&wl->mutex); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + if (wl->state == WL1251_STATE_ON && + time_after(jiffies, wl->stats.fw_stats_update + + msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) { + wl1251_acx_statistics(wl, wl->stats.fw_stats); + wl->stats.fw_stats_update = jiffies; + } + + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1251_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u"); +DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u"); +DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u"); +DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u"); +DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u"); +/* skipping wep.reserved */ +DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u"); +DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u"); +DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u"); +DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u"); +DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u"); +/* skipping cont_miss_bcns_spread for now */ +DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u"); +DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u"); +DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u"); +DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u"); +DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u"); +DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u"); + +DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, + 20, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u"); +DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u"); + +DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count); +DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u", + wl->stats.excessive_retries); + +static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1251 *wl = file->private_data; + u32 queue_len; + char buf[20]; + int res; + + queue_len = skb_queue_len(&wl->tx_queue); + + res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} + +static const struct file_operations tx_queue_len_ops = { + .read = tx_queue_len_read, + .open = wl1251_open_file_generic, +}; + +static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1251 *wl = file->private_data; + char buf[3], status; + int len; + + if (wl->tx_queue_stopped) + status = 's'; + else + status = 'r'; + + len = scnprintf(buf, sizeof(buf), "%c\n", status); + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static const struct file_operations tx_queue_status_ops = { + .read = tx_queue_status_read, + .open = wl1251_open_file_generic, +}; + +static void wl1251_debugfs_delete_files(struct wl1251 *wl) +{ + DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); + + DEBUGFS_FWSTATS_DEL(rx, out_of_mem); + DEBUGFS_FWSTATS_DEL(rx, hdr_overflow); + DEBUGFS_FWSTATS_DEL(rx, hw_stuck); + DEBUGFS_FWSTATS_DEL(rx, dropped); + DEBUGFS_FWSTATS_DEL(rx, fcs_err); + DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig); + DEBUGFS_FWSTATS_DEL(rx, path_reset); + DEBUGFS_FWSTATS_DEL(rx, reset_counter); + + DEBUGFS_FWSTATS_DEL(dma, rx_requested); + DEBUGFS_FWSTATS_DEL(dma, rx_errors); + DEBUGFS_FWSTATS_DEL(dma, tx_requested); + DEBUGFS_FWSTATS_DEL(dma, tx_errors); + + DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt); + DEBUGFS_FWSTATS_DEL(isr, fiqs); + DEBUGFS_FWSTATS_DEL(isr, rx_headers); + DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow); + DEBUGFS_FWSTATS_DEL(isr, rx_rdys); + DEBUGFS_FWSTATS_DEL(isr, irqs); + DEBUGFS_FWSTATS_DEL(isr, tx_procs); + DEBUGFS_FWSTATS_DEL(isr, decrypt_done); + DEBUGFS_FWSTATS_DEL(isr, dma0_done); + DEBUGFS_FWSTATS_DEL(isr, dma1_done); + DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete); + DEBUGFS_FWSTATS_DEL(isr, commands); + DEBUGFS_FWSTATS_DEL(isr, rx_procs); + DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes); + DEBUGFS_FWSTATS_DEL(isr, host_acknowledges); + DEBUGFS_FWSTATS_DEL(isr, pci_pm); + DEBUGFS_FWSTATS_DEL(isr, wakeups); + DEBUGFS_FWSTATS_DEL(isr, low_rssi); + + DEBUGFS_FWSTATS_DEL(wep, addr_key_count); + DEBUGFS_FWSTATS_DEL(wep, default_key_count); + /* skipping wep.reserved */ + DEBUGFS_FWSTATS_DEL(wep, key_not_found); + DEBUGFS_FWSTATS_DEL(wep, decrypt_fail); + DEBUGFS_FWSTATS_DEL(wep, packets); + DEBUGFS_FWSTATS_DEL(wep, interrupt); + + DEBUGFS_FWSTATS_DEL(pwr, ps_enter); + DEBUGFS_FWSTATS_DEL(pwr, elp_enter); + DEBUGFS_FWSTATS_DEL(pwr, missing_bcns); + DEBUGFS_FWSTATS_DEL(pwr, wake_on_host); + DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp); + DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps); + DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps); + DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons); + DEBUGFS_FWSTATS_DEL(pwr, power_save_off); + DEBUGFS_FWSTATS_DEL(pwr, enable_ps); + DEBUGFS_FWSTATS_DEL(pwr, disable_ps); + DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps); + /* skipping cont_miss_bcns_spread for now */ + DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons); + + DEBUGFS_FWSTATS_DEL(mic, rx_pkts); + DEBUGFS_FWSTATS_DEL(mic, calc_failure); + + DEBUGFS_FWSTATS_DEL(aes, encrypt_fail); + DEBUGFS_FWSTATS_DEL(aes, decrypt_fail); + DEBUGFS_FWSTATS_DEL(aes, encrypt_packets); + DEBUGFS_FWSTATS_DEL(aes, decrypt_packets); + DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt); + DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt); + + DEBUGFS_FWSTATS_DEL(event, heart_beat); + DEBUGFS_FWSTATS_DEL(event, calibration); + DEBUGFS_FWSTATS_DEL(event, rx_mismatch); + DEBUGFS_FWSTATS_DEL(event, rx_mem_empty); + DEBUGFS_FWSTATS_DEL(event, rx_pool); + DEBUGFS_FWSTATS_DEL(event, oom_late); + DEBUGFS_FWSTATS_DEL(event, phy_transmit_error); + DEBUGFS_FWSTATS_DEL(event, tx_stuck); + + DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts); + DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts); + DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime); + DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn); + DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn); + DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization); + DEBUGFS_FWSTATS_DEL(ps, upsd_utilization); + + DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop); + DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data); + DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); + + DEBUGFS_DEL(tx_queue_len); + DEBUGFS_DEL(tx_queue_status); + DEBUGFS_DEL(retry_count); + DEBUGFS_DEL(excessive_retries); +} + +static int wl1251_debugfs_add_files(struct wl1251 *wl) +{ + int ret = 0; + + DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); + + DEBUGFS_FWSTATS_ADD(rx, out_of_mem); + DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); + DEBUGFS_FWSTATS_ADD(rx, hw_stuck); + DEBUGFS_FWSTATS_ADD(rx, dropped); + DEBUGFS_FWSTATS_ADD(rx, fcs_err); + DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); + DEBUGFS_FWSTATS_ADD(rx, path_reset); + DEBUGFS_FWSTATS_ADD(rx, reset_counter); + + DEBUGFS_FWSTATS_ADD(dma, rx_requested); + DEBUGFS_FWSTATS_ADD(dma, rx_errors); + DEBUGFS_FWSTATS_ADD(dma, tx_requested); + DEBUGFS_FWSTATS_ADD(dma, tx_errors); + + DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); + DEBUGFS_FWSTATS_ADD(isr, fiqs); + DEBUGFS_FWSTATS_ADD(isr, rx_headers); + DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); + DEBUGFS_FWSTATS_ADD(isr, rx_rdys); + DEBUGFS_FWSTATS_ADD(isr, irqs); + DEBUGFS_FWSTATS_ADD(isr, tx_procs); + DEBUGFS_FWSTATS_ADD(isr, decrypt_done); + DEBUGFS_FWSTATS_ADD(isr, dma0_done); + DEBUGFS_FWSTATS_ADD(isr, dma1_done); + DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); + DEBUGFS_FWSTATS_ADD(isr, commands); + DEBUGFS_FWSTATS_ADD(isr, rx_procs); + DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); + DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); + DEBUGFS_FWSTATS_ADD(isr, pci_pm); + DEBUGFS_FWSTATS_ADD(isr, wakeups); + DEBUGFS_FWSTATS_ADD(isr, low_rssi); + + DEBUGFS_FWSTATS_ADD(wep, addr_key_count); + DEBUGFS_FWSTATS_ADD(wep, default_key_count); + /* skipping wep.reserved */ + DEBUGFS_FWSTATS_ADD(wep, key_not_found); + DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); + DEBUGFS_FWSTATS_ADD(wep, packets); + DEBUGFS_FWSTATS_ADD(wep, interrupt); + + DEBUGFS_FWSTATS_ADD(pwr, ps_enter); + DEBUGFS_FWSTATS_ADD(pwr, elp_enter); + DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); + DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); + DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); + DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); + DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); + DEBUGFS_FWSTATS_ADD(pwr, power_save_off); + DEBUGFS_FWSTATS_ADD(pwr, enable_ps); + DEBUGFS_FWSTATS_ADD(pwr, disable_ps); + DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); + /* skipping cont_miss_bcns_spread for now */ + DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); + + DEBUGFS_FWSTATS_ADD(mic, rx_pkts); + DEBUGFS_FWSTATS_ADD(mic, calc_failure); + + DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); + DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); + DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); + DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); + + DEBUGFS_FWSTATS_ADD(event, heart_beat); + DEBUGFS_FWSTATS_ADD(event, calibration); + DEBUGFS_FWSTATS_ADD(event, rx_mismatch); + DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); + DEBUGFS_FWSTATS_ADD(event, rx_pool); + DEBUGFS_FWSTATS_ADD(event, oom_late); + DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); + DEBUGFS_FWSTATS_ADD(event, tx_stuck); + + DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); + DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); + DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); + DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); + + DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); + DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); + DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); + + DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); + DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir); + DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); + DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); + +out: + if (ret < 0) + wl1251_debugfs_delete_files(wl); + + return ret; +} + +void wl1251_debugfs_reset(struct wl1251 *wl) +{ + if (wl->stats.fw_stats != NULL) + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + wl->stats.retry_count = 0; + wl->stats.excessive_retries = 0; +} + +int wl1251_debugfs_init(struct wl1251 *wl) +{ + int ret; + + wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); + + if (IS_ERR(wl->debugfs.rootdir)) { + ret = PTR_ERR(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + goto err; + } + + wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics", + wl->debugfs.rootdir); + + if (IS_ERR(wl->debugfs.fw_statistics)) { + ret = PTR_ERR(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + goto err_root; + } + + wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), + GFP_KERNEL); + + if (!wl->stats.fw_stats) { + ret = -ENOMEM; + goto err_fw; + } + + wl->stats.fw_stats_update = jiffies; + + ret = wl1251_debugfs_add_files(wl); + + if (ret < 0) + goto err_file; + + return 0; + +err_file: + kfree(wl->stats.fw_stats); + wl->stats.fw_stats = NULL; + +err_fw: + debugfs_remove(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + +err_root: + debugfs_remove(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + +err: + return ret; +} + +void wl1251_debugfs_exit(struct wl1251 *wl) +{ + wl1251_debugfs_delete_files(wl); + + kfree(wl->stats.fw_stats); + wl->stats.fw_stats = NULL; + + debugfs_remove(wl->debugfs.fw_statistics); + wl->debugfs.fw_statistics = NULL; + + debugfs_remove(wl->debugfs.rootdir); + wl->debugfs.rootdir = NULL; + +} diff --git a/drivers/net/wireless/wl1251/debugfs.h b/drivers/net/wireless/wl1251/debugfs.h new file mode 100644 index 000000000000..b3417c02a218 --- /dev/null +++ b/drivers/net/wireless/wl1251/debugfs.h @@ -0,0 +1,31 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef WL1251_DEBUGFS_H +#define WL1251_DEBUGFS_H + +#include "wl1251.h" + +int wl1251_debugfs_init(struct wl1251 *wl); +void wl1251_debugfs_exit(struct wl1251 *wl); +void wl1251_debugfs_reset(struct wl1251 *wl); + +#endif /* WL1251_DEBUGFS_H */ diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c new file mode 100644 index 000000000000..712372e50a87 --- /dev/null +++ b/drivers/net/wireless/wl1251/event.c @@ -0,0 +1,168 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "wl1251.h" +#include "reg.h" +#include "io.h" +#include "event.h" +#include "ps.h" + +static int wl1251_event_scan_complete(struct wl1251 *wl, + struct event_mailbox *mbox) +{ + wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d", + mbox->scheduled_scan_status, + mbox->scheduled_scan_channels); + + if (wl->scanning) { + ieee80211_scan_completed(wl->hw, false); + wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); + wl->scanning = false; + } + + return 0; +} + +static void wl1251_event_mbox_dump(struct event_mailbox *mbox) +{ + wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); + wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); + wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); +} + +static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) +{ + int ret; + u32 vector; + + wl1251_event_mbox_dump(mbox); + + vector = mbox->events_vector & ~(mbox->events_mask); + wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector); + + if (vector & SCAN_COMPLETE_EVENT_ID) { + ret = wl1251_event_scan_complete(wl, mbox); + if (ret < 0) + return ret; + } + + if (vector & BSS_LOSE_EVENT_ID) { + wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); + + if (wl->psm_requested && wl->psm) { + ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); + if (ret < 0) + return ret; + } + } + + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { + wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); + + /* indicate to the stack, that beacons have been lost */ + ieee80211_beacon_loss(wl->vif); + } + + if (vector & REGAINED_BSS_EVENT_ID) { + if (wl->psm_requested) { + ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); + if (ret < 0) + return ret; + } + } + + return 0; +} + +/* + * Poll the mailbox event field until any of the bits in the mask is set or a + * timeout occurs (WL1251_EVENT_TIMEOUT in msecs) + */ +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms) +{ + u32 events_vector, event; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + + /* read from both event fields */ + wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector, + sizeof(events_vector)); + event = events_vector & mask; + wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector, + sizeof(events_vector)); + event |= events_vector & mask; + } while (!event); + + return 0; +} + +int wl1251_event_unmask(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask)); + if (ret < 0) + return ret; + + return 0; +} + +void wl1251_event_mbox_config(struct wl1251 *wl) +{ + wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR); + wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); + + wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", + wl->mbox_ptr[0], wl->mbox_ptr[1]); +} + +int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num) +{ + struct event_mailbox mbox; + int ret; + + wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); + + if (mbox_num > 1) + return -EINVAL; + + /* first we read the mbox descriptor */ + wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox, + sizeof(struct event_mailbox)); + + /* process the descriptor */ + ret = wl1251_event_process(wl, &mbox); + if (ret < 0) + return ret; + + /* then we let the firmware know it can go on...*/ + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); + + return 0; +} diff --git a/drivers/net/wireless/wl1251/event.h b/drivers/net/wireless/wl1251/event.h new file mode 100644 index 000000000000..30eb5d150bf7 --- /dev/null +++ b/drivers/net/wireless/wl1251/event.h @@ -0,0 +1,120 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_EVENT_H__ +#define __WL1251_EVENT_H__ + +/* + * Mbox events + * + * The event mechanism is based on a pair of event buffers (buffers A and + * B) at fixed locations in the target's memory. The host processes one + * buffer while the other buffer continues to collect events. If the host + * is not processing events, an interrupt is issued to signal that a buffer + * is ready. Once the host is done with processing events from one buffer, + * it signals the target (with an ACK interrupt) that the event buffer is + * free. + */ + +enum { + RESERVED1_EVENT_ID = BIT(0), + RESERVED2_EVENT_ID = BIT(1), + MEASUREMENT_START_EVENT_ID = BIT(2), + SCAN_COMPLETE_EVENT_ID = BIT(3), + CALIBRATION_COMPLETE_EVENT_ID = BIT(4), + ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5), + PS_REPORT_EVENT_ID = BIT(6), + SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7), + HEALTH_REPORT_EVENT_ID = BIT(8), + ACI_DETECTION_EVENT_ID = BIT(9), + DEBUG_REPORT_EVENT_ID = BIT(10), + MAC_STATUS_EVENT_ID = BIT(11), + DISCONNECT_EVENT_COMPLETE_ID = BIT(12), + JOIN_EVENT_COMPLETE_ID = BIT(13), + CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14), + BSS_LOSE_EVENT_ID = BIT(15), + ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16), + MEASUREMENT_COMPLETE_EVENT_ID = BIT(17), + AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18), + SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19), + PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20), + RESET_BSS_EVENT_ID = BIT(21), + REGAINED_BSS_EVENT_ID = BIT(22), + ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23), + ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24), + ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25), + + DBG_EVENT_ID = BIT(26), + BT_PTA_SENSE_EVENT_ID = BIT(27), + BT_PTA_PREDICTION_EVENT_ID = BIT(28), + BT_PTA_AVALANCHE_EVENT_ID = BIT(29), + + PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30), + + EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, +}; + +struct event_debug_report { + u8 debug_event_id; + u8 num_params; + u16 pad; + u32 report_1; + u32 report_2; + u32 report_3; +} __packed; + +struct event_mailbox { + u32 events_vector; + u32 events_mask; + u32 reserved_1; + u32 reserved_2; + + char average_rssi_level; + u8 ps_status; + u8 channel_switch_status; + u8 scheduled_scan_status; + + /* Channels scanned by the scheduled scan */ + u16 scheduled_scan_channels; + + /* If bit 0 is set -> target's fatal error */ + u16 health_report; + u16 bad_fft_counter; + u8 bt_pta_sense_info; + u8 bt_pta_protective_info; + u32 reserved; + u32 debug_report[2]; + + /* Number of FCS errors since last event */ + u32 fcs_err_counter; + + struct event_debug_report report; + u8 average_snr_level; + u8 padding[19]; +} __packed; + +int wl1251_event_unmask(struct wl1251 *wl); +void wl1251_event_mbox_config(struct wl1251 *wl); +int wl1251_event_handle(struct wl1251 *wl, u8 mbox); +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms); + +#endif diff --git a/drivers/net/wireless/wl1251/init.c b/drivers/net/wireless/wl1251/init.c new file mode 100644 index 000000000000..89b43d35473c --- /dev/null +++ b/drivers/net/wireless/wl1251/init.c @@ -0,0 +1,423 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +#include "init.h" +#include "wl12xx_80211.h" +#include "acx.h" +#include "cmd.h" +#include "reg.h" + +int wl1251_hw_init_hwenc_config(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_feature_cfg(wl); + if (ret < 0) { + wl1251_warning("couldn't set feature config"); + return ret; + } + + ret = wl1251_acx_default_key(wl, wl->default_key); + if (ret < 0) { + wl1251_warning("couldn't set default key"); + return ret; + } + + return 0; +} + +int wl1251_hw_init_templates_config(struct wl1251 *wl) +{ + int ret; + u8 partial_vbm[PARTIAL_VBM_MAX]; + + /* send empty templates for fw memory reservation */ + ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL, + sizeof(struct wl12xx_probe_req_template)); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL, + sizeof(struct wl12xx_null_data_template)); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL, + sizeof(struct wl12xx_ps_poll_template)); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL, + sizeof + (struct wl12xx_qos_null_data_template)); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL, + sizeof + (struct wl12xx_probe_resp_template)); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL, + sizeof + (struct wl12xx_beacon_template)); + if (ret < 0) + return ret; + + /* tim templates, first reserve space then allocate an empty one */ + memset(partial_vbm, 0, PARTIAL_VBM_MAX); + ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0); + if (ret < 0) + return ret; + + ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter) +{ + int ret; + + ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF); + if (ret < 0) + return ret; + + ret = wl1251_acx_rx_config(wl, config, filter); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_phy_config(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_pd_threshold(wl); + if (ret < 0) + return ret; + + ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME); + if (ret < 0) + return ret; + + ret = wl1251_acx_group_address_tbl(wl); + if (ret < 0) + return ret; + + ret = wl1251_acx_service_period_timeout(wl); + if (ret < 0) + return ret; + + ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_beacon_filter(struct wl1251 *wl) +{ + int ret; + + /* disable beacon filtering at this stage */ + ret = wl1251_acx_beacon_filter_opt(wl, false); + if (ret < 0) + return ret; + + ret = wl1251_acx_beacon_filter_table(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_pta(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_sg_enable(wl); + if (ret < 0) + return ret; + + ret = wl1251_acx_sg_cfg(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_energy_detection(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_cca_threshold(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_bcn_dtim_options(wl); + if (ret < 0) + return ret; + + return 0; +} + +int wl1251_hw_init_power_auth(struct wl1251 *wl) +{ + return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); +} + +int wl1251_hw_init_mem_config(struct wl1251 *wl) +{ + int ret; + + ret = wl1251_acx_mem_cfg(wl); + if (ret < 0) + return ret; + + wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map), + GFP_KERNEL); + if (!wl->target_mem_map) { + wl1251_error("couldn't allocate target memory map"); + return -ENOMEM; + } + + /* we now ask for the firmware built memory map */ + ret = wl1251_acx_mem_map(wl, wl->target_mem_map, + sizeof(struct wl1251_acx_mem_map)); + if (ret < 0) { + wl1251_error("couldn't retrieve firmware memory map"); + kfree(wl->target_mem_map); + wl->target_mem_map = NULL; + return ret; + } + + return 0; +} + +static int wl1251_hw_init_txq_fill(u8 qid, + struct acx_tx_queue_qos_config *config, + u32 num_blocks) +{ + config->qid = qid; + + switch (qid) { + case QOS_AC_BE: + config->high_threshold = + (QOS_TX_HIGH_BE_DEF * num_blocks) / 100; + config->low_threshold = + (QOS_TX_LOW_BE_DEF * num_blocks) / 100; + break; + case QOS_AC_BK: + config->high_threshold = + (QOS_TX_HIGH_BK_DEF * num_blocks) / 100; + config->low_threshold = + (QOS_TX_LOW_BK_DEF * num_blocks) / 100; + break; + case QOS_AC_VI: + config->high_threshold = + (QOS_TX_HIGH_VI_DEF * num_blocks) / 100; + config->low_threshold = + (QOS_TX_LOW_VI_DEF * num_blocks) / 100; + break; + case QOS_AC_VO: + config->high_threshold = + (QOS_TX_HIGH_VO_DEF * num_blocks) / 100; + config->low_threshold = + (QOS_TX_LOW_VO_DEF * num_blocks) / 100; + break; + default: + wl1251_error("Invalid TX queue id: %d", qid); + return -EINVAL; + } + + return 0; +} + +static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl) +{ + struct acx_tx_queue_qos_config *config; + struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map; + int ret, i; + + wl1251_debug(DEBUG_ACX, "acx tx queue config"); + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) { + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < MAX_NUM_OF_AC; i++) { + ret = wl1251_hw_init_txq_fill(i, config, + wl_mem_map->num_tx_mem_blocks); + if (ret < 0) + goto out; + + ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG, + config, sizeof(*config)); + if (ret < 0) + goto out; + } + + wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE); + wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK); + wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI); + wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO); + +out: + kfree(config); + return ret; +} + +static int wl1251_hw_init_data_path_config(struct wl1251 *wl) +{ + int ret; + + /* asking for the data path parameters */ + wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp), + GFP_KERNEL); + if (!wl->data_path) { + wl1251_error("Couldnt allocate data path parameters"); + return -ENOMEM; + } + + ret = wl1251_acx_data_path_params(wl, wl->data_path); + if (ret < 0) { + kfree(wl->data_path); + wl->data_path = NULL; + return ret; + } + + return 0; +} + + +int wl1251_hw_init(struct wl1251 *wl) +{ + struct wl1251_acx_mem_map *wl_mem_map; + int ret; + + ret = wl1251_hw_init_hwenc_config(wl); + if (ret < 0) + return ret; + + /* Template settings */ + ret = wl1251_hw_init_templates_config(wl); + if (ret < 0) + return ret; + + /* Default memory configuration */ + ret = wl1251_hw_init_mem_config(wl); + if (ret < 0) + return ret; + + /* Default data path configuration */ + ret = wl1251_hw_init_data_path_config(wl); + if (ret < 0) + goto out_free_memmap; + + /* RX config */ + ret = wl1251_hw_init_rx_config(wl, + RX_CFG_PROMISCUOUS | RX_CFG_TSF, + RX_FILTER_OPTION_DEF); + /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS, + RX_FILTER_OPTION_FILTER_ALL); */ + if (ret < 0) + goto out_free_data_path; + + /* TX queues config */ + ret = wl1251_hw_init_tx_queue_config(wl); + if (ret < 0) + goto out_free_data_path; + + /* PHY layer config */ + ret = wl1251_hw_init_phy_config(wl); + if (ret < 0) + goto out_free_data_path; + + /* Initialize connection monitoring thresholds */ + ret = wl1251_acx_conn_monit_params(wl); + if (ret < 0) + goto out_free_data_path; + + /* Beacon filtering */ + ret = wl1251_hw_init_beacon_filter(wl); + if (ret < 0) + goto out_free_data_path; + + /* Bluetooth WLAN coexistence */ + ret = wl1251_hw_init_pta(wl); + if (ret < 0) + goto out_free_data_path; + + /* Energy detection */ + ret = wl1251_hw_init_energy_detection(wl); + if (ret < 0) + goto out_free_data_path; + + /* Beacons and boradcast settings */ + ret = wl1251_hw_init_beacon_broadcast(wl); + if (ret < 0) + goto out_free_data_path; + + /* Enable data path */ + ret = wl1251_cmd_data_path(wl, wl->channel, 1); + if (ret < 0) + goto out_free_data_path; + + /* Default power state */ + ret = wl1251_hw_init_power_auth(wl); + if (ret < 0) + goto out_free_data_path; + + wl_mem_map = wl->target_mem_map; + wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x", + wl_mem_map->num_tx_mem_blocks, + wl->data_path->tx_control_addr, + wl_mem_map->num_rx_mem_blocks, + wl->data_path->rx_control_addr); + + return 0; + + out_free_data_path: + kfree(wl->data_path); + + out_free_memmap: + kfree(wl->target_mem_map); + + return ret; +} diff --git a/drivers/net/wireless/wl1251/init.h b/drivers/net/wireless/wl1251/init.h new file mode 100644 index 000000000000..543f17582ead --- /dev/null +++ b/drivers/net/wireless/wl1251/init.h @@ -0,0 +1,86 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_INIT_H__ +#define __WL1251_INIT_H__ + +#include "wl1251.h" + +enum { + /* best effort/legacy */ + AC_BE = 0, + + /* background */ + AC_BK = 1, + + /* video */ + AC_VI = 2, + + /* voice */ + AC_VO = 3, + + /* broadcast dummy access category */ + AC_BCAST = 4, + + NUM_ACCESS_CATEGORIES = 4 +}; + +/* following are defult values for the IE fields*/ +#define CWMIN_BK 15 +#define CWMIN_BE 15 +#define CWMIN_VI 7 +#define CWMIN_VO 3 +#define CWMAX_BK 1023 +#define CWMAX_BE 63 +#define CWMAX_VI 15 +#define CWMAX_VO 7 + +/* slot number setting to start transmission at PIFS interval */ +#define AIFS_PIFS 1 + +/* + * slot number setting to start transmission at DIFS interval - normal DCF + * access + */ +#define AIFS_DIFS 2 + +#define AIFSN_BK 7 +#define AIFSN_BE 3 +#define AIFSN_VI AIFS_PIFS +#define AIFSN_VO AIFS_PIFS +#define TXOP_BK 0 +#define TXOP_BE 0 +#define TXOP_VI 3008 +#define TXOP_VO 1504 + +int wl1251_hw_init_hwenc_config(struct wl1251 *wl); +int wl1251_hw_init_templates_config(struct wl1251 *wl); +int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter); +int wl1251_hw_init_phy_config(struct wl1251 *wl); +int wl1251_hw_init_beacon_filter(struct wl1251 *wl); +int wl1251_hw_init_pta(struct wl1251 *wl); +int wl1251_hw_init_energy_detection(struct wl1251 *wl); +int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl); +int wl1251_hw_init_power_auth(struct wl1251 *wl); +int wl1251_hw_init_mem_config(struct wl1251 *wl); +int wl1251_hw_init(struct wl1251 *wl); + +#endif diff --git a/drivers/net/wireless/wl1251/io.c b/drivers/net/wireless/wl1251/io.c new file mode 100644 index 000000000000..cdcadbf6ac2c --- /dev/null +++ b/drivers/net/wireless/wl1251/io.c @@ -0,0 +1,194 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "wl1251.h" +#include "reg.h" +#include "io.h" + +/* FIXME: this is static data nowadays and the table can be removed */ +static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = { + [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474), + [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478), + [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494), + [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498), + [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C), + [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0), + [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4), + [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8), + [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000), + [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C), + [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804) +}; + +static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr) +{ + /* If the address is lower than REGISTERS_BASE, it means that this is + * a chip-specific register address, so look it up in the registers + * table */ + if (addr < REGISTERS_BASE) { + /* Make sure we don't go over the table */ + if (addr >= ACX_REG_TABLE_LEN) { + wl1251_error("address out of range (%d)", addr); + return -EINVAL; + } + addr = wl1251_io_reg_table[addr]; + } + + return addr - wl->physical_reg_addr + wl->virtual_reg_addr; +} + +static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr) +{ + return addr - wl->physical_mem_addr + wl->virtual_mem_addr; +} + +void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len) +{ + int physical; + + physical = wl1251_translate_mem_addr(wl, addr); + + wl->if_ops->read(wl, physical, buf, len); +} + +void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len) +{ + int physical; + + physical = wl1251_translate_mem_addr(wl, addr); + + wl->if_ops->write(wl, physical, buf, len); +} + +u32 wl1251_mem_read32(struct wl1251 *wl, int addr) +{ + return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr)); +} + +void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val) +{ + wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val); +} + +u32 wl1251_reg_read32(struct wl1251 *wl, int addr) +{ + return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr)); +} + +void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val) +{ + wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val); +} + +/* Set the partitions to access the chip addresses. + * + * There are two VIRTUAL partitions (the memory partition and the + * registers partition), which are mapped to two different areas of the + * PHYSICAL (hardware) memory. This function also makes other checks to + * ensure that the partitions are not overlapping. In the diagram below, the + * memory partition comes before the register partition, but the opposite is + * also supported. + * + * PHYSICAL address + * space + * + * | | + * ...+----+--> mem_start + * VIRTUAL address ... | | + * space ... | | [PART_0] + * ... | | + * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size + * | | ... | | + * |MEM | ... | | + * | | ... | | + * part_size <--+----+... | | {unused area) + * | | ... | | + * |REG | ... | | + * part_size | | ... | | + * + <--+----+... ...+----+--> reg_start + * reg_size ... | | + * ... | | [PART_1] + * ... | | + * ...+----+--> reg_start + reg_size + * | | + * + */ +void wl1251_set_partition(struct wl1251 *wl, + u32 mem_start, u32 mem_size, + u32 reg_start, u32 reg_size) +{ + struct wl1251_partition partition[2]; + + wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", + mem_start, mem_size); + wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", + reg_start, reg_size); + + /* Make sure that the two partitions together don't exceed the + * address range */ + if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) { + wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual" + " address range. Truncating partition[0]."); + mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size; + wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", + mem_start, mem_size); + wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", + reg_start, reg_size); + } + + if ((mem_start < reg_start) && + ((mem_start + mem_size) > reg_start)) { + /* Guarantee that the memory partition doesn't overlap the + * registers partition */ + wl1251_debug(DEBUG_SPI, "End of partition[0] is " + "overlapping partition[1]. Adjusted."); + mem_size = reg_start - mem_start; + wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", + mem_start, mem_size); + wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", + reg_start, reg_size); + } else if ((reg_start < mem_start) && + ((reg_start + reg_size) > mem_start)) { + /* Guarantee that the register partition doesn't overlap the + * memory partition */ + wl1251_debug(DEBUG_SPI, "End of partition[1] is" + " overlapping partition[0]. Adjusted."); + reg_size = mem_start - reg_start; + wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", + mem_start, mem_size); + wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", + reg_start, reg_size); + } + + partition[0].start = mem_start; + partition[0].size = mem_size; + partition[1].start = reg_start; + partition[1].size = reg_size; + + wl->physical_mem_addr = mem_start; + wl->physical_reg_addr = reg_start; + + wl->virtual_mem_addr = 0; + wl->virtual_reg_addr = mem_size; + + wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition, + sizeof(partition)); +} diff --git a/drivers/net/wireless/wl1251/io.h b/drivers/net/wireless/wl1251/io.h new file mode 100644 index 000000000000..c545e9d5f512 --- /dev/null +++ b/drivers/net/wireless/wl1251/io.h @@ -0,0 +1,84 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#ifndef __WL1251_IO_H__ +#define __WL1251_IO_H__ + +#include "wl1251.h" + +#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 + +#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0 +#define HW_ACCESS_PART0_START_ADDR 0x1FFC4 +#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8 +#define HW_ACCESS_PART1_START_ADDR 0x1FFCC + +#define HW_ACCESS_REGISTER_SIZE 4 + +#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 + +static inline u32 wl1251_read32(struct wl1251 *wl, int addr) +{ + u32 response; + + wl->if_ops->read(wl, addr, &response, sizeof(u32)); + + return response; +} + +static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val) +{ + wl->if_ops->write(wl, addr, &val, sizeof(u32)); +} + +static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr) +{ + u32 response; + + if (wl->if_ops->read_elp) + wl->if_ops->read_elp(wl, addr, &response); + else + wl->if_ops->read(wl, addr, &response, sizeof(u32)); + + return response; +} + +static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val) +{ + if (wl->if_ops->write_elp) + wl->if_ops->write_elp(wl, addr, val); + else + wl->if_ops->write(wl, addr, &val, sizeof(u32)); +} + +/* Memory target IO, address is translated to partition 0 */ +void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); +void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); +u32 wl1251_mem_read32(struct wl1251 *wl, int addr); +void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val); +/* Registers IO */ +u32 wl1251_reg_read32(struct wl1251 *wl, int addr); +void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val); + +void wl1251_set_partition(struct wl1251 *wl, + u32 part_start, u32 part_size, + u32 reg_start, u32 reg_size); + +#endif diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c new file mode 100644 index 000000000000..7a8762553cdc --- /dev/null +++ b/drivers/net/wireless/wl1251/main.c @@ -0,0 +1,1435 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2008-2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wl1251.h" +#include "wl12xx_80211.h" +#include "reg.h" +#include "io.h" +#include "cmd.h" +#include "event.h" +#include "tx.h" +#include "rx.h" +#include "ps.h" +#include "init.h" +#include "debugfs.h" +#include "boot.h" + +void wl1251_enable_interrupts(struct wl1251 *wl) +{ + wl->if_ops->enable_irq(wl); +} + +void wl1251_disable_interrupts(struct wl1251 *wl) +{ + wl->if_ops->disable_irq(wl); +} + +static void wl1251_power_off(struct wl1251 *wl) +{ + wl->set_power(false); +} + +static void wl1251_power_on(struct wl1251 *wl) +{ + wl->set_power(true); +} + +static int wl1251_fetch_firmware(struct wl1251 *wl) +{ + const struct firmware *fw; + struct device *dev = wiphy_dev(wl->hw->wiphy); + int ret; + + ret = request_firmware(&fw, WL1251_FW_NAME, dev); + + if (ret < 0) { + wl1251_error("could not get firmware: %d", ret); + return ret; + } + + if (fw->size % 4) { + wl1251_error("firmware size is not multiple of 32 bits: %zu", + fw->size); + ret = -EILSEQ; + goto out; + } + + wl->fw_len = fw->size; + wl->fw = vmalloc(wl->fw_len); + + if (!wl->fw) { + wl1251_error("could not allocate memory for the firmware"); + ret = -ENOMEM; + goto out; + } + + memcpy(wl->fw, fw->data, wl->fw_len); + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static int wl1251_fetch_nvs(struct wl1251 *wl) +{ + const struct firmware *fw; + struct device *dev = wiphy_dev(wl->hw->wiphy); + int ret; + + ret = request_firmware(&fw, WL1251_NVS_NAME, dev); + + if (ret < 0) { + wl1251_error("could not get nvs file: %d", ret); + return ret; + } + + if (fw->size % 4) { + wl1251_error("nvs size is not multiple of 32 bits: %zu", + fw->size); + ret = -EILSEQ; + goto out; + } + + wl->nvs_len = fw->size; + wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL); + + if (!wl->nvs) { + wl1251_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; + goto out; + } + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static void wl1251_fw_wakeup(struct wl1251 *wl) +{ + u32 elp_reg; + + elp_reg = ELPCTRL_WAKE_UP; + wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); + elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); + + if (!(elp_reg & ELPCTRL_WLAN_READY)) + wl1251_warning("WLAN not ready"); +} + +static int wl1251_chip_wakeup(struct wl1251 *wl) +{ + int ret = 0; + + wl1251_power_on(wl); + msleep(WL1251_POWER_ON_SLEEP); + wl->if_ops->reset(wl); + + /* We don't need a real memory partition here, because we only want + * to use the registers at this point. */ + wl1251_set_partition(wl, + 0x00000000, + 0x00000000, + REGISTERS_BASE, + REGISTERS_DOWN_SIZE); + + /* ELP module wake up */ + wl1251_fw_wakeup(wl); + + /* whal_FwCtrl_BootSm() */ + + /* 0. read chip id from CHIP_ID */ + wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B); + + /* 1. check if chip id is valid */ + + switch (wl->chip_id) { + case CHIP_ID_1251_PG12: + wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)", + wl->chip_id); + break; + case CHIP_ID_1251_PG11: + wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)", + wl->chip_id); + break; + case CHIP_ID_1251_PG10: + default: + wl1251_error("unsupported chip id: 0x%x", wl->chip_id); + ret = -ENODEV; + goto out; + } + + if (wl->fw == NULL) { + ret = wl1251_fetch_firmware(wl); + if (ret < 0) + goto out; + } + + if (wl->nvs == NULL && !wl->use_eeprom) { + /* No NVS from netlink, try to get it from the filesystem */ + ret = wl1251_fetch_nvs(wl); + if (ret < 0) + goto out; + } + +out: + return ret; +} + +#define WL1251_IRQ_LOOP_COUNT 10 +static void wl1251_irq_work(struct work_struct *work) +{ + u32 intr, ctr = WL1251_IRQ_LOOP_COUNT; + struct wl1251 *wl = + container_of(work, struct wl1251, irq_work); + int ret; + + mutex_lock(&wl->mutex); + + wl1251_debug(DEBUG_IRQ, "IRQ work"); + + if (wl->state == WL1251_STATE_OFF) + goto out; + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL); + + intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); + wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); + + do { + if (wl->data_path) { + wl->rx_counter = wl1251_mem_read32( + wl, wl->data_path->rx_control_addr); + + /* We handle a frmware bug here */ + switch ((wl->rx_counter - wl->rx_handled) & 0xf) { + case 0: + wl1251_debug(DEBUG_IRQ, + "RX: FW and host in sync"); + intr &= ~WL1251_ACX_INTR_RX0_DATA; + intr &= ~WL1251_ACX_INTR_RX1_DATA; + break; + case 1: + wl1251_debug(DEBUG_IRQ, "RX: FW +1"); + intr |= WL1251_ACX_INTR_RX0_DATA; + intr &= ~WL1251_ACX_INTR_RX1_DATA; + break; + case 2: + wl1251_debug(DEBUG_IRQ, "RX: FW +2"); + intr |= WL1251_ACX_INTR_RX0_DATA; + intr |= WL1251_ACX_INTR_RX1_DATA; + break; + default: + wl1251_warning( + "RX: FW and host out of sync: %d", + wl->rx_counter - wl->rx_handled); + break; + } + + wl->rx_handled = wl->rx_counter; + + wl1251_debug(DEBUG_IRQ, "RX counter: %d", + wl->rx_counter); + } + + intr &= wl->intr_mask; + + if (intr == 0) { + wl1251_debug(DEBUG_IRQ, "INTR is 0"); + goto out_sleep; + } + + if (intr & WL1251_ACX_INTR_RX0_DATA) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); + wl1251_rx(wl); + } + + if (intr & WL1251_ACX_INTR_RX1_DATA) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); + wl1251_rx(wl); + } + + if (intr & WL1251_ACX_INTR_TX_RESULT) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); + wl1251_tx_complete(wl); + } + + if (intr & WL1251_ACX_INTR_EVENT_A) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A"); + wl1251_event_handle(wl, 0); + } + + if (intr & WL1251_ACX_INTR_EVENT_B) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B"); + wl1251_event_handle(wl, 1); + } + + if (intr & WL1251_ACX_INTR_INIT_COMPLETE) + wl1251_debug(DEBUG_IRQ, + "WL1251_ACX_INTR_INIT_COMPLETE"); + + if (--ctr == 0) + break; + + intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); + } while (intr); + +out_sleep: + wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, + u16 beacon_interval, u8 dtim_period) +{ + int ret; + + ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE, + DEFAULT_HW_GEN_MODULATION_TYPE, + wl->tx_mgmt_frm_rate, + wl->tx_mgmt_frm_mod); + if (ret < 0) + goto out; + + + ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval, + dtim_period); + if (ret < 0) + goto out; + + ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100); + if (ret < 0) + wl1251_warning("join timeout"); + +out: + return ret; +} + +static void wl1251_filter_work(struct work_struct *work) +{ + struct wl1251 *wl = + container_of(work, struct wl1251, filter_work); + int ret; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1251_STATE_OFF) + goto out; + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int, + wl->dtim_period); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + +static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct wl1251 *wl = hw->priv; + unsigned long flags; + + skb_queue_tail(&wl->tx_queue, skb); + + /* + * The chip specific setup must run before the first TX packet - + * before that, the tx_work will not be initialized! + */ + + ieee80211_queue_work(wl->hw, &wl->tx_work); + + /* + * The workqueue is slow to process the tx_queue and we need stop + * the queue here, otherwise the queue will get too long. + */ + if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) { + wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues"); + + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_stop_queues(wl->hw); + wl->tx_queue_stopped = true; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } + + return NETDEV_TX_OK; +} + +static int wl1251_op_start(struct ieee80211_hw *hw) +{ + struct wl1251 *wl = hw->priv; + struct wiphy *wiphy = hw->wiphy; + int ret = 0; + + wl1251_debug(DEBUG_MAC80211, "mac80211 start"); + + mutex_lock(&wl->mutex); + + if (wl->state != WL1251_STATE_OFF) { + wl1251_error("cannot start because not in off state: %d", + wl->state); + ret = -EBUSY; + goto out; + } + + ret = wl1251_chip_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1251_boot(wl); + if (ret < 0) + goto out; + + ret = wl1251_hw_init(wl); + if (ret < 0) + goto out; + + ret = wl1251_acx_station_id(wl); + if (ret < 0) + goto out; + + wl->state = WL1251_STATE_ON; + + wl1251_info("firmware booted (%s)", wl->fw_ver); + + /* update hw/fw version info in wiphy struct */ + wiphy->hw_version = wl->chip_id; + strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version)); + +out: + if (ret < 0) + wl1251_power_off(wl); + + mutex_unlock(&wl->mutex); + + return ret; +} + +static void wl1251_op_stop(struct ieee80211_hw *hw) +{ + struct wl1251 *wl = hw->priv; + + wl1251_info("down"); + + wl1251_debug(DEBUG_MAC80211, "mac80211 stop"); + + mutex_lock(&wl->mutex); + + WARN_ON(wl->state != WL1251_STATE_ON); + + if (wl->scanning) { + ieee80211_scan_completed(wl->hw, true); + wl->scanning = false; + } + + wl->state = WL1251_STATE_OFF; + + wl1251_disable_interrupts(wl); + + mutex_unlock(&wl->mutex); + + cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->tx_work); + cancel_work_sync(&wl->filter_work); + + mutex_lock(&wl->mutex); + + /* let's notify MAC80211 about the remaining pending TX frames */ + wl1251_tx_flush(wl); + wl1251_power_off(wl); + + memset(wl->bssid, 0, ETH_ALEN); + wl->listen_int = 1; + wl->bss_type = MAX_BSS_TYPE; + + wl->data_in_count = 0; + wl->rx_counter = 0; + wl->rx_handled = 0; + wl->rx_current_buffer = 0; + wl->rx_last_id = 0; + wl->next_tx_complete = 0; + wl->elp = false; + wl->psm = 0; + wl->tx_queue_stopped = false; + wl->power_level = WL1251_DEFAULT_POWER_LEVEL; + wl->channel = WL1251_DEFAULT_CHANNEL; + + wl1251_debugfs_reset(wl); + + mutex_unlock(&wl->mutex); +} + +static int wl1251_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1251 *wl = hw->priv; + int ret = 0; + + wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", + vif->type, vif->addr); + + mutex_lock(&wl->mutex); + if (wl->vif) { + ret = -EBUSY; + goto out; + } + + wl->vif = vif; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + wl->bss_type = BSS_TYPE_STA_BSS; + break; + case NL80211_IFTYPE_ADHOC: + wl->bss_type = BSS_TYPE_IBSS; + break; + default: + ret = -EOPNOTSUPP; + goto out; + } + + if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) { + memcpy(wl->mac_addr, vif->addr, ETH_ALEN); + SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); + ret = wl1251_acx_station_id(wl); + if (ret < 0) + goto out; + } + +out: + mutex_unlock(&wl->mutex); + return ret; +} + +static void wl1251_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1251 *wl = hw->priv; + + mutex_lock(&wl->mutex); + wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); + wl->vif = NULL; + mutex_unlock(&wl->mutex); +} + +static int wl1251_build_qos_null_data(struct wl1251 *wl) +{ + struct ieee80211_qos_hdr template; + + memset(&template, 0, sizeof(template)); + + memcpy(template.addr1, wl->bssid, ETH_ALEN); + memcpy(template.addr2, wl->mac_addr, ETH_ALEN); + memcpy(template.addr3, wl->bssid, ETH_ALEN); + + template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_QOS_NULLFUNC | + IEEE80211_FCTL_TODS); + + /* FIXME: not sure what priority to use here */ + template.qos_ctrl = cpu_to_le16(0); + + return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template, + sizeof(template)); +} + +static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct wl1251 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + int channel, ret = 0; + + channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + + wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", + channel, + conf->flags & IEEE80211_CONF_PS ? "on" : "off", + conf->power_level); + + mutex_lock(&wl->mutex); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + if (channel != wl->channel) { + wl->channel = channel; + + ret = wl1251_join(wl, wl->bss_type, wl->channel, + wl->beacon_int, wl->dtim_period); + if (ret < 0) + goto out_sleep; + } + + if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { + wl1251_debug(DEBUG_PSM, "psm enabled"); + + wl->psm_requested = true; + + wl->dtim_period = conf->ps_dtim_period; + + ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, + wl->dtim_period); + + /* + * mac80211 enables PSM only if we're already associated. + */ + ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); + if (ret < 0) + goto out_sleep; + } else if (!(conf->flags & IEEE80211_CONF_PS) && + wl->psm_requested) { + wl1251_debug(DEBUG_PSM, "psm disabled"); + + wl->psm_requested = false; + + if (wl->psm) { + ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); + if (ret < 0) + goto out_sleep; + } + } + + if (conf->power_level != wl->power_level) { + ret = wl1251_acx_tx_power(wl, conf->power_level); + if (ret < 0) + goto out_sleep; + + wl->power_level = conf->power_level; + } + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | \ + FIF_FCSFAIL | \ + FIF_BCN_PRBRESP_PROMISC | \ + FIF_CONTROL | \ + FIF_OTHER_BSS) + +static void wl1251_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed, + unsigned int *total,u64 multicast) +{ + struct wl1251 *wl = hw->priv; + + wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter"); + + *total &= WL1251_SUPPORTED_FILTERS; + changed &= WL1251_SUPPORTED_FILTERS; + + if (changed == 0) + /* no filters which we support changed */ + return; + + /* FIXME: wl->rx_config and wl->rx_filter are not protected */ + + wl->rx_config = WL1251_DEFAULT_RX_CONFIG; + wl->rx_filter = WL1251_DEFAULT_RX_FILTER; + + if (*total & FIF_PROMISC_IN_BSS) { + wl->rx_config |= CFG_BSSID_FILTER_EN; + wl->rx_config |= CFG_RX_ALL_GOOD; + } + if (*total & FIF_ALLMULTI) + /* + * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive + * all multicast frames + */ + wl->rx_config &= ~CFG_MC_FILTER_EN; + if (*total & FIF_FCSFAIL) + wl->rx_filter |= CFG_RX_FCS_ERROR; + if (*total & FIF_BCN_PRBRESP_PROMISC) { + wl->rx_config &= ~CFG_BSSID_FILTER_EN; + wl->rx_config &= ~CFG_SSID_FILTER_EN; + } + if (*total & FIF_CONTROL) + wl->rx_filter |= CFG_RX_CTL_EN; + if (*total & FIF_OTHER_BSS) + wl->rx_filter &= ~CFG_BSSID_FILTER_EN; + + /* + * FIXME: workqueues need to be properly cancelled on stop(), for + * now let's just disable changing the filter settings. They will + * be updated any on config(). + */ + /* schedule_work(&wl->filter_work); */ +} + +/* HW encryption */ +static int wl1251_set_key_type(struct wl1251 *wl, + struct wl1251_cmd_set_keys *key, + enum set_key_cmd cmd, + struct ieee80211_key_conf *mac80211_key, + const u8 *addr) +{ + switch (mac80211_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + if (is_broadcast_ether_addr(addr)) + key->key_type = KEY_WEP_DEFAULT; + else + key->key_type = KEY_WEP_ADDR; + + mac80211_key->hw_key_idx = mac80211_key->keyidx; + break; + case WLAN_CIPHER_SUITE_TKIP: + if (is_broadcast_ether_addr(addr)) + key->key_type = KEY_TKIP_MIC_GROUP; + else + key->key_type = KEY_TKIP_MIC_PAIRWISE; + + mac80211_key->hw_key_idx = mac80211_key->keyidx; + break; + case WLAN_CIPHER_SUITE_CCMP: + if (is_broadcast_ether_addr(addr)) + key->key_type = KEY_AES_GROUP; + else + key->key_type = KEY_AES_PAIRWISE; + mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + break; + default: + wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher); + return -EOPNOTSUPP; + } + + return 0; +} + +static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct wl1251 *wl = hw->priv; + struct wl1251_cmd_set_keys *wl_cmd; + const u8 *addr; + int ret; + + static const u8 bcast_addr[ETH_ALEN] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + wl1251_debug(DEBUG_MAC80211, "mac80211 set key"); + + wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL); + if (!wl_cmd) { + ret = -ENOMEM; + goto out; + } + + addr = sta ? sta->addr : bcast_addr; + + wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); + wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); + wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", + key->cipher, key->keyidx, key->keylen, key->flags); + wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); + + if (is_zero_ether_addr(addr)) { + /* We dont support TX only encryption */ + ret = -EOPNOTSUPP; + goto out; + } + + mutex_lock(&wl->mutex); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out_unlock; + + switch (cmd) { + case SET_KEY: + wl_cmd->key_action = KEY_ADD_OR_REPLACE; + break; + case DISABLE_KEY: + wl_cmd->key_action = KEY_REMOVE; + break; + default: + wl1251_error("Unsupported key cmd 0x%x", cmd); + break; + } + + ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr); + if (ret < 0) { + wl1251_error("Set KEY type failed"); + goto out_sleep; + } + + if (wl_cmd->key_type != KEY_WEP_DEFAULT) + memcpy(wl_cmd->addr, addr, ETH_ALEN); + + if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) || + (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) { + /* + * We get the key in the following form: + * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) + * but the target is expecting: + * TKIP - RX MIC - TX MIC + */ + memcpy(wl_cmd->key, key->key, 16); + memcpy(wl_cmd->key + 16, key->key + 24, 8); + memcpy(wl_cmd->key + 24, key->key + 16, 8); + + } else { + memcpy(wl_cmd->key, key->key, key->keylen); + } + wl_cmd->key_size = key->keylen; + + wl_cmd->id = key->keyidx; + wl_cmd->ssid_profile = 0; + + wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd)); + + ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd)); + if (ret < 0) { + wl1251_warning("could not set keys"); + goto out_sleep; + } + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out_unlock: + mutex_unlock(&wl->mutex); + +out: + kfree(wl_cmd); + + return ret; +} + +static int wl1251_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_scan_request *req) +{ + struct wl1251 *wl = hw->priv; + struct sk_buff *skb; + size_t ssid_len = 0; + u8 *ssid = NULL; + int ret; + + wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan"); + + if (req->n_ssids) { + ssid = req->ssids[0].ssid; + ssid_len = req->ssids[0].ssid_len; + } + + mutex_lock(&wl->mutex); + + if (wl->scanning) { + wl1251_debug(DEBUG_SCAN, "scan already in progress"); + ret = -EINVAL; + goto out; + } + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, + req->ie, req->ie_len); + if (!skb) { + ret = -ENOMEM; + goto out; + } + + ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data, + skb->len); + dev_kfree_skb(skb); + if (ret < 0) + goto out_sleep; + + ret = wl1251_cmd_trigger_scan_to(wl, 0); + if (ret < 0) + goto out_sleep; + + wl->scanning = true; + + ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels, + req->n_channels, WL1251_SCAN_NUM_PROBES); + if (ret < 0) { + wl->scanning = false; + goto out_sleep; + } + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + struct wl1251 *wl = hw->priv; + int ret; + + mutex_lock(&wl->mutex); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1251_acx_rts_threshold(wl, (u16) value); + if (ret < 0) + wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret); + + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + struct wl1251 *wl = hw->priv; + struct sk_buff *beacon, *skb; + int ret; + + wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); + + mutex_lock(&wl->mutex); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + if (changed & BSS_CHANGED_BSSID) { + memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); + + skb = ieee80211_nullfunc_get(wl->hw, wl->vif); + if (!skb) + goto out_sleep; + + ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, + skb->data, skb->len); + dev_kfree_skb(skb); + if (ret < 0) + goto out_sleep; + + ret = wl1251_build_qos_null_data(wl); + if (ret < 0) + goto out; + + if (wl->bss_type != BSS_TYPE_IBSS) { + ret = wl1251_join(wl, wl->bss_type, wl->channel, + wl->beacon_int, wl->dtim_period); + if (ret < 0) + goto out_sleep; + } + } + + if (changed & BSS_CHANGED_ASSOC) { + if (bss_conf->assoc) { + wl->beacon_int = bss_conf->beacon_int; + + skb = ieee80211_pspoll_get(wl->hw, wl->vif); + if (!skb) + goto out_sleep; + + ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, + skb->data, + skb->len); + dev_kfree_skb(skb); + if (ret < 0) + goto out_sleep; + + ret = wl1251_acx_aid(wl, bss_conf->aid); + if (ret < 0) + goto out_sleep; + } else { + /* use defaults when not associated */ + wl->beacon_int = WL1251_DEFAULT_BEACON_INT; + wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; + } + } + if (changed & BSS_CHANGED_ERP_SLOT) { + if (bss_conf->use_short_slot) + ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT); + else + ret = wl1251_acx_slot(wl, SLOT_TIME_LONG); + if (ret < 0) { + wl1251_warning("Set slot time failed %d", ret); + goto out_sleep; + } + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + if (bss_conf->use_short_preamble) + wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); + else + wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG); + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + if (bss_conf->use_cts_prot) + ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE); + else + ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE); + if (ret < 0) { + wl1251_warning("Set ctsprotect failed %d", ret); + goto out_sleep; + } + } + + if (changed & BSS_CHANGED_BEACON) { + beacon = ieee80211_beacon_get(hw, vif); + ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, + beacon->len); + + if (ret < 0) { + dev_kfree_skb(beacon); + goto out_sleep; + } + + ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, + beacon->len); + + dev_kfree_skb(beacon); + + if (ret < 0) + goto out_sleep; + + ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, + wl->channel, wl->dtim_period); + + if (ret < 0) + goto out_sleep; + } + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_rate wl1251_rates[] = { + { .bitrate = 10, + .hw_value = 0x1, + .hw_value_short = 0x1, }, + { .bitrate = 20, + .hw_value = 0x2, + .hw_value_short = 0x2, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 55, + .hw_value = 0x4, + .hw_value_short = 0x4, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 110, + .hw_value = 0x20, + .hw_value_short = 0x20, + .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 60, + .hw_value = 0x8, + .hw_value_short = 0x8, }, + { .bitrate = 90, + .hw_value = 0x10, + .hw_value_short = 0x10, }, + { .bitrate = 120, + .hw_value = 0x40, + .hw_value_short = 0x40, }, + { .bitrate = 180, + .hw_value = 0x80, + .hw_value_short = 0x80, }, + { .bitrate = 240, + .hw_value = 0x200, + .hw_value_short = 0x200, }, + { .bitrate = 360, + .hw_value = 0x400, + .hw_value_short = 0x400, }, + { .bitrate = 480, + .hw_value = 0x800, + .hw_value_short = 0x800, }, + { .bitrate = 540, + .hw_value = 0x1000, + .hw_value_short = 0x1000, }, +}; + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_channel wl1251_channels[] = { + { .hw_value = 1, .center_freq = 2412}, + { .hw_value = 2, .center_freq = 2417}, + { .hw_value = 3, .center_freq = 2422}, + { .hw_value = 4, .center_freq = 2427}, + { .hw_value = 5, .center_freq = 2432}, + { .hw_value = 6, .center_freq = 2437}, + { .hw_value = 7, .center_freq = 2442}, + { .hw_value = 8, .center_freq = 2447}, + { .hw_value = 9, .center_freq = 2452}, + { .hw_value = 10, .center_freq = 2457}, + { .hw_value = 11, .center_freq = 2462}, + { .hw_value = 12, .center_freq = 2467}, + { .hw_value = 13, .center_freq = 2472}, +}; + +static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + enum wl1251_acx_ps_scheme ps_scheme; + struct wl1251 *wl = hw->priv; + int ret; + + mutex_lock(&wl->mutex); + + wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + /* mac80211 uses units of 32 usec */ + ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue), + params->cw_min, params->cw_max, + params->aifs, params->txop * 32); + if (ret < 0) + goto out_sleep; + + if (params->uapsd) + ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER; + else + ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY; + + ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue), + CHANNEL_TYPE_EDCF, + wl1251_tx_get_queue(queue), ps_scheme, + WL1251_ACX_ACK_POLICY_LEGACY); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + +static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct wl1251 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = wl->noise; + + return 0; +} + +/* can't be const, mac80211 writes to this */ +static struct ieee80211_supported_band wl1251_band_2ghz = { + .channels = wl1251_channels, + .n_channels = ARRAY_SIZE(wl1251_channels), + .bitrates = wl1251_rates, + .n_bitrates = ARRAY_SIZE(wl1251_rates), +}; + +static const struct ieee80211_ops wl1251_ops = { + .start = wl1251_op_start, + .stop = wl1251_op_stop, + .add_interface = wl1251_op_add_interface, + .remove_interface = wl1251_op_remove_interface, + .config = wl1251_op_config, + .configure_filter = wl1251_op_configure_filter, + .tx = wl1251_op_tx, + .set_key = wl1251_op_set_key, + .hw_scan = wl1251_op_hw_scan, + .bss_info_changed = wl1251_op_bss_info_changed, + .set_rts_threshold = wl1251_op_set_rts_threshold, + .conf_tx = wl1251_op_conf_tx, + .get_survey = wl1251_op_get_survey, +}; + +static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) +{ + unsigned long timeout; + + wl1251_reg_write32(wl, EE_ADDR, offset); + wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ); + + /* EE_CTL_READ clears when data is ready */ + timeout = jiffies + msecs_to_jiffies(100); + while (1) { + if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ)) + break; + + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + } + + *data = wl1251_reg_read32(wl, EE_DATA); + return 0; +} + +static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset, + u8 *data, size_t len) +{ + size_t i; + int ret; + + wl1251_reg_write32(wl, EE_START, 0); + + for (i = 0; i < len; i++) { + ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +static int wl1251_read_eeprom_mac(struct wl1251 *wl) +{ + u8 mac[ETH_ALEN]; + int i, ret; + + wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE); + + ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac)); + if (ret < 0) { + wl1251_warning("failed to read MAC address from EEPROM"); + return ret; + } + + /* MAC is stored in reverse order */ + for (i = 0; i < ETH_ALEN; i++) + wl->mac_addr[i] = mac[ETH_ALEN - i - 1]; + + return 0; +} + +static int wl1251_register_hw(struct wl1251 *wl) +{ + int ret; + + if (wl->mac80211_registered) + return 0; + + SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); + + ret = ieee80211_register_hw(wl->hw); + if (ret < 0) { + wl1251_error("unable to register mac80211 hw: %d", ret); + return ret; + } + + wl->mac80211_registered = true; + + wl1251_notice("loaded"); + + return 0; +} + +int wl1251_init_ieee80211(struct wl1251 *wl) +{ + int ret; + + /* The tx descriptor buffer and the TKIP space */ + wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc) + + WL1251_TKIP_IV_SPACE; + + /* unit us */ + /* FIXME: find a proper value */ + wl->hw->channel_change_time = 10000; + + wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_BEACON_FILTER | + IEEE80211_HW_SUPPORTS_UAPSD; + + wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + wl->hw->wiphy->max_scan_ssids = 1; + wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; + + wl->hw->queues = 4; + + if (wl->use_eeprom) + wl1251_read_eeprom_mac(wl); + + ret = wl1251_register_hw(wl); + if (ret) + goto out; + + wl1251_debugfs_init(wl); + wl1251_notice("initialized"); + + ret = 0; + +out: + return ret; +} +EXPORT_SYMBOL_GPL(wl1251_init_ieee80211); + +struct ieee80211_hw *wl1251_alloc_hw(void) +{ + struct ieee80211_hw *hw; + struct wl1251 *wl; + int i; + static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; + + hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops); + if (!hw) { + wl1251_error("could not alloc ieee80211_hw"); + return ERR_PTR(-ENOMEM); + } + + wl = hw->priv; + memset(wl, 0, sizeof(*wl)); + + wl->hw = hw; + + wl->data_in_count = 0; + + skb_queue_head_init(&wl->tx_queue); + + INIT_WORK(&wl->filter_work, wl1251_filter_work); + INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); + wl->channel = WL1251_DEFAULT_CHANNEL; + wl->scanning = false; + wl->default_key = 0; + wl->listen_int = 1; + wl->rx_counter = 0; + wl->rx_handled = 0; + wl->rx_current_buffer = 0; + wl->rx_last_id = 0; + wl->rx_config = WL1251_DEFAULT_RX_CONFIG; + wl->rx_filter = WL1251_DEFAULT_RX_FILTER; + wl->elp = false; + wl->psm = 0; + wl->psm_requested = false; + wl->tx_queue_stopped = false; + wl->power_level = WL1251_DEFAULT_POWER_LEVEL; + wl->beacon_int = WL1251_DEFAULT_BEACON_INT; + wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; + wl->vif = NULL; + + for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) + wl->tx_frames[i] = NULL; + + wl->next_tx_complete = 0; + + INIT_WORK(&wl->irq_work, wl1251_irq_work); + INIT_WORK(&wl->tx_work, wl1251_tx_work); + + /* + * In case our MAC address is not correctly set, + * we use a random but Nokia MAC. + */ + memcpy(wl->mac_addr, nokia_oui, 3); + get_random_bytes(wl->mac_addr + 3, 3); + + wl->state = WL1251_STATE_OFF; + mutex_init(&wl->mutex); + + wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE; + wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE; + + wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL); + if (!wl->rx_descriptor) { + wl1251_error("could not allocate memory for rx descriptor"); + ieee80211_free_hw(hw); + return ERR_PTR(-ENOMEM); + } + + return hw; +} +EXPORT_SYMBOL_GPL(wl1251_alloc_hw); + +int wl1251_free_hw(struct wl1251 *wl) +{ + ieee80211_unregister_hw(wl->hw); + + wl1251_debugfs_exit(wl); + + kfree(wl->target_mem_map); + kfree(wl->data_path); + vfree(wl->fw); + wl->fw = NULL; + kfree(wl->nvs); + wl->nvs = NULL; + + kfree(wl->rx_descriptor); + wl->rx_descriptor = NULL; + + ieee80211_free_hw(wl->hw); + + return 0; +} +EXPORT_SYMBOL_GPL(wl1251_free_hw); + +MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kalle Valo "); +MODULE_FIRMWARE(WL1251_FW_NAME); diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c new file mode 100644 index 000000000000..5ed47c8373d2 --- /dev/null +++ b/drivers/net/wireless/wl1251/ps.c @@ -0,0 +1,194 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "reg.h" +#include "ps.h" +#include "cmd.h" +#include "io.h" + +/* in ms */ +#define WL1251_WAKEUP_TIMEOUT 100 + +void wl1251_elp_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1251 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1251, elp_work); + + wl1251_debug(DEBUG_PSM, "elp work"); + + mutex_lock(&wl->mutex); + + if (wl->elp || !wl->psm) + goto out; + + wl1251_debug(DEBUG_PSM, "chip to elp"); + wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); + wl->elp = true; + +out: + mutex_unlock(&wl->mutex); +} + +#define ELP_ENTRY_DELAY 5 + +/* Routines to toggle sleep mode while in ELP */ +void wl1251_ps_elp_sleep(struct wl1251 *wl) +{ + unsigned long delay; + + if (wl->psm) { + cancel_delayed_work(&wl->elp_work); + delay = msecs_to_jiffies(ELP_ENTRY_DELAY); + ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); + } +} + +int wl1251_ps_elp_wakeup(struct wl1251 *wl) +{ + unsigned long timeout, start; + u32 elp_reg; + + if (!wl->elp) + return 0; + + wl1251_debug(DEBUG_PSM, "waking up chip from elp"); + + start = jiffies; + timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); + + wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); + + elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); + + /* + * FIXME: we should wait for irq from chip but, as a temporary + * solution to simplify locking, let's poll instead + */ + while (!(elp_reg & ELPCTRL_WLAN_READY)) { + if (time_after(jiffies, timeout)) { + wl1251_error("elp wakeup timeout"); + return -ETIMEDOUT; + } + msleep(1); + elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); + } + + wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", + jiffies_to_msecs(jiffies - start)); + + wl->elp = false; + + return 0; +} + +static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable) +{ + int ret; + + if (enable) { + wl1251_debug(DEBUG_PSM, "sleep auth psm/elp"); + + ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); + if (ret < 0) + return ret; + + wl1251_ps_elp_sleep(wl); + } else { + wl1251_debug(DEBUG_PSM, "sleep auth cam"); + + /* + * When the target is in ELP, we can only + * access the ELP control register. Thus, + * we have to wake the target up before + * changing the power authorization. + */ + + wl1251_ps_elp_wakeup(wl); + + ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); + if (ret < 0) + return ret; + } + + return 0; +} + +int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) +{ + int ret; + + switch (mode) { + case STATION_POWER_SAVE_MODE: + wl1251_debug(DEBUG_PSM, "entering psm"); + + /* enable beacon filtering */ + ret = wl1251_acx_beacon_filter_opt(wl, true); + if (ret < 0) + return ret; + + ret = wl1251_acx_wake_up_conditions(wl, + WAKE_UP_EVENT_DTIM_BITMAP, + wl->listen_int); + if (ret < 0) + return ret; + + ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); + if (ret < 0) + return ret; + + ret = wl1251_ps_set_elp(wl, true); + if (ret < 0) + return ret; + + wl->psm = 1; + break; + case STATION_ACTIVE_MODE: + default: + wl1251_debug(DEBUG_PSM, "leaving psm"); + ret = wl1251_ps_set_elp(wl, false); + if (ret < 0) + return ret; + + /* disable beacon filtering */ + ret = wl1251_acx_beacon_filter_opt(wl, false); + if (ret < 0) + return ret; + + ret = wl1251_acx_wake_up_conditions(wl, + WAKE_UP_EVENT_DTIM_BITMAP, + wl->listen_int); + if (ret < 0) + return ret; + + ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE); + if (ret < 0) + return ret; + + wl->psm = 0; + break; + } + + return ret; +} + diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h new file mode 100644 index 000000000000..55c3dda75e69 --- /dev/null +++ b/drivers/net/wireless/wl1251/ps.h @@ -0,0 +1,35 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_PS_H__ +#define __WL1251_PS_H__ + +#include "wl1251.h" +#include "acx.h" + +int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); +void wl1251_ps_elp_sleep(struct wl1251 *wl); +int wl1251_ps_elp_wakeup(struct wl1251 *wl); +void wl1251_elp_work(struct work_struct *work); + + +#endif /* __WL1251_PS_H__ */ diff --git a/drivers/net/wireless/wl1251/reg.h b/drivers/net/wireless/wl1251/reg.h new file mode 100644 index 000000000000..a5809019c5c1 --- /dev/null +++ b/drivers/net/wireless/wl1251/reg.h @@ -0,0 +1,655 @@ +/* + * This file is part of wl12xx + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __REG_H__ +#define __REG_H__ + +#include + +#define REGISTERS_BASE 0x00300000 +#define DRPW_BASE 0x00310000 + +#define REGISTERS_DOWN_SIZE 0x00008800 +#define REGISTERS_WORK_SIZE 0x0000b000 + +#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC + +/* ELP register commands */ +#define ELPCTRL_WAKE_UP 0x1 +#define ELPCTRL_WAKE_UP_WLAN_READY 0x5 +#define ELPCTRL_SLEEP 0x0 +/* ELP WLAN_READY bit */ +#define ELPCTRL_WLAN_READY 0x2 + +/* Device Configuration registers*/ +#define SOR_CFG (REGISTERS_BASE + 0x0800) +#define ECPU_CTRL (REGISTERS_BASE + 0x0804) +#define HI_CFG (REGISTERS_BASE + 0x0808) + +/* EEPROM registers */ +#define EE_START (REGISTERS_BASE + 0x080C) +#define EE_CTL (REGISTERS_BASE + 0x2000) +#define EE_DATA (REGISTERS_BASE + 0x2004) +#define EE_ADDR (REGISTERS_BASE + 0x2008) + +#define EE_CTL_READ 2 + +#define CHIP_ID_B (REGISTERS_BASE + 0x5674) + +#define CHIP_ID_1251_PG10 (0x7010101) +#define CHIP_ID_1251_PG11 (0x7020101) +#define CHIP_ID_1251_PG12 (0x7030101) + +#define ENABLE (REGISTERS_BASE + 0x5450) + +/* Power Management registers */ +#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) +#define ELP_CMD (REGISTERS_BASE + 0x5808) +#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) +#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) +#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) + +#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) + +/* Scratch Pad registers*/ +#define SCR_PAD0 (REGISTERS_BASE + 0x5608) +#define SCR_PAD1 (REGISTERS_BASE + 0x560C) +#define SCR_PAD2 (REGISTERS_BASE + 0x5610) +#define SCR_PAD3 (REGISTERS_BASE + 0x5614) +#define SCR_PAD4 (REGISTERS_BASE + 0x5618) +#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) +#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) +#define SCR_PAD5 (REGISTERS_BASE + 0x5624) +#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) +#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) +#define SCR_PAD6 (REGISTERS_BASE + 0x5630) +#define SCR_PAD7 (REGISTERS_BASE + 0x5634) +#define SCR_PAD8 (REGISTERS_BASE + 0x5638) +#define SCR_PAD9 (REGISTERS_BASE + 0x563C) + +/* Spare registers*/ +#define SPARE_A1 (REGISTERS_BASE + 0x0994) +#define SPARE_A2 (REGISTERS_BASE + 0x0998) +#define SPARE_A3 (REGISTERS_BASE + 0x099C) +#define SPARE_A4 (REGISTERS_BASE + 0x09A0) +#define SPARE_A5 (REGISTERS_BASE + 0x09A4) +#define SPARE_A6 (REGISTERS_BASE + 0x09A8) +#define SPARE_A7 (REGISTERS_BASE + 0x09AC) +#define SPARE_A8 (REGISTERS_BASE + 0x09B0) +#define SPARE_B1 (REGISTERS_BASE + 0x5420) +#define SPARE_B2 (REGISTERS_BASE + 0x5424) +#define SPARE_B3 (REGISTERS_BASE + 0x5428) +#define SPARE_B4 (REGISTERS_BASE + 0x542C) +#define SPARE_B5 (REGISTERS_BASE + 0x5430) +#define SPARE_B6 (REGISTERS_BASE + 0x5434) +#define SPARE_B7 (REGISTERS_BASE + 0x5438) +#define SPARE_B8 (REGISTERS_BASE + 0x543C) + +enum wl12xx_acx_int_reg { + ACX_REG_INTERRUPT_TRIG, + ACX_REG_INTERRUPT_TRIG_H, + +/*============================================= + Host Interrupt Mask Register - 32bit (RW) + ------------------------------------------ + Setting a bit in this register masks the + corresponding interrupt to the host. + 0 - RX0 - Rx first dubble buffer Data Interrupt + 1 - TXD - Tx Data Interrupt + 2 - TXXFR - Tx Transfer Interrupt + 3 - RX1 - Rx second dubble buffer Data Interrupt + 4 - RXXFR - Rx Transfer Interrupt + 5 - EVENT_A - Event Mailbox interrupt + 6 - EVENT_B - Event Mailbox interrupt + 7 - WNONHST - Wake On Host Interrupt + 8 - TRACE_A - Debug Trace interrupt + 9 - TRACE_B - Debug Trace interrupt + 10 - CDCMP - Command Complete Interrupt + 11 - + 12 - + 13 - + 14 - ICOMP - Initialization Complete Interrupt + 16 - SG SE - Soft Gemini - Sense enable interrupt + 17 - SG SD - Soft Gemini - Sense disable interrupt + 18 - - + 19 - - + 20 - - + 21- - + Default: 0x0001 +*==============================================*/ + ACX_REG_INTERRUPT_MASK, + +/*============================================= + Host Interrupt Mask Set 16bit, (Write only) + ------------------------------------------ + Setting a bit in this register sets + the corresponding bin in ACX_HINT_MASK register + without effecting the mask + state of other bits (0 = no effect). +==============================================*/ + ACX_REG_HINT_MASK_SET, + +/*============================================= + Host Interrupt Mask Clear 16bit,(Write only) + ------------------------------------------ + Setting a bit in this register clears + the corresponding bin in ACX_HINT_MASK register + without effecting the mask + state of other bits (0 = no effect). +=============================================*/ + ACX_REG_HINT_MASK_CLR, + +/*============================================= + Host Interrupt Status Nondestructive Read + 16bit,(Read only) + ------------------------------------------ + The host can read this register to determine + which interrupts are active. + Reading this register doesn't + effect its content. +=============================================*/ + ACX_REG_INTERRUPT_NO_CLEAR, + +/*============================================= + Host Interrupt Status Clear on Read Register + 16bit,(Read only) + ------------------------------------------ + The host can read this register to determine + which interrupts are active. + Reading this register clears it, + thus making all interrupts inactive. +==============================================*/ + ACX_REG_INTERRUPT_CLEAR, + +/*============================================= + Host Interrupt Acknowledge Register + 16bit,(Write only) + ------------------------------------------ + The host can set individual bits in this + register to clear (acknowledge) the corresp. + interrupt status bits in the HINT_STS_CLR and + HINT_STS_ND registers, thus making the + assotiated interrupt inactive. (0-no effect) +==============================================*/ + ACX_REG_INTERRUPT_ACK, + +/*=============================================== + Host Software Reset - 32bit RW + ------------------------------------------ + [31:1] Reserved + 0 SOFT_RESET Soft Reset - When this bit is set, + it holds the Wlan hardware in a soft reset state. + This reset disables all MAC and baseband processor + clocks except the CardBus/PCI interface clock. + It also initializes all MAC state machines except + the host interface. It does not reload the + contents of the EEPROM. When this bit is cleared + (not self-clearing), the Wlan hardware + exits the software reset state. +===============================================*/ + ACX_REG_SLV_SOFT_RESET, + +/*=============================================== + EEPROM Burst Read Start - 32bit RW + ------------------------------------------ + [31:1] Reserved + 0 ACX_EE_START - EEPROM Burst Read Start 0 + Setting this bit starts a burst read from + the external EEPROM. + If this bit is set (after reset) before an EEPROM read/write, + the burst read starts at EEPROM address 0. + Otherwise, it starts at the address + following the address of the previous access. + TheWlan hardware hardware clears this bit automatically. + + Default: 0x00000000 +*================================================*/ + ACX_REG_EE_START, + +/* Embedded ARM CPU Control */ + +/*=============================================== + Halt eCPU - 32bit RW + ------------------------------------------ + 0 HALT_ECPU Halt Embedded CPU - This bit is the + compliment of bit 1 (MDATA2) in the SOR_CFG register. + During a hardware reset, this bit holds + the inverse of MDATA2. + When downloading firmware from the host, + set this bit (pull down MDATA2). + The host clears this bit after downloading the firmware into + zero-wait-state SSRAM. + When loading firmware from Flash, clear this bit (pull up MDATA2) + so that the eCPU can run the bootloader code in Flash + HALT_ECPU eCPU State + -------------------- + 1 halt eCPU + 0 enable eCPU + ===============================================*/ + ACX_REG_ECPU_CONTROL, + + ACX_REG_TABLE_LEN +}; + +#define ACX_SLV_SOFT_RESET_BIT BIT(0) +#define ACX_REG_EEPROM_START_BIT BIT(0) + +/* Command/Information Mailbox Pointers */ + +/*=============================================== + Command Mailbox Pointer - 32bit RW + ------------------------------------------ + This register holds the start address of + the command mailbox located in the Wlan hardware memory. + The host must read this pointer after a reset to + find the location of the command mailbox. + The Wlan hardware initializes the command mailbox + pointer with the default address of the command mailbox. + The command mailbox pointer is not valid until after + the host receives the Init Complete interrupt from + the Wlan hardware. + ===============================================*/ +#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) + +/*=============================================== + Information Mailbox Pointer - 32bit RW + ------------------------------------------ + This register holds the start address of + the information mailbox located in the Wlan hardware memory. + The host must read this pointer after a reset to find + the location of the information mailbox. + The Wlan hardware initializes the information mailbox pointer + with the default address of the information mailbox. + The information mailbox pointer is not valid + until after the host receives the Init Complete interrupt from + the Wlan hardware. + ===============================================*/ +#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) + + +/* Misc */ + +#define REG_ENABLE_TX_RX (ENABLE) +/* + * Rx configuration (filter) information element + * --------------------------------------------- + */ +#define REG_RX_CONFIG (RX_CFG) +#define REG_RX_FILTER (RX_FILTER_CFG) + + +#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002 + +/* promiscuous - receives all valid frames */ +#define RX_CFG_PROMISCUOUS 0x0008 + +/* receives frames from any BSSID */ +#define RX_CFG_BSSID 0x0020 + +/* receives frames destined to any MAC address */ +#define RX_CFG_MAC 0x0010 + +#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010 +#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000 +#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020 +#define RX_CFG_ENABLE_ANY_BSSID 0x0000 + +/* discards all broadcast frames */ +#define RX_CFG_DISABLE_BCAST 0x0200 + +#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400 +#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800 +#define RX_CFG_COPY_RX_STATUS 0x2000 +#define RX_CFG_TSF 0x10000 + +#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ + RX_CFG_ENABLE_ONLY_MY_BSSID) + +#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ + | RX_CFG_ENABLE_ANY_BSSID) + +#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ + RX_CFG_ENABLE_ANY_BSSID) + +#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ + | RX_CFG_ENABLE_ONLY_MY_BSSID) + +#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \ + | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \ + | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF) + +#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC) + +#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \ + RX_CFG_ENABLE_ONLY_MY_DEST_MAC) + +#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \ + RX_CFG_ENABLE_ONLY_MY_DEST_MAC) + +#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ + | CFG_RX_CTL_EN | CFG_RX_BCN_EN\ + | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) + +#define RX_FILTER_OPTION_FILTER_ALL 0 + +#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\ + | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN) + +#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ + | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\ + | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\ + | CFG_RX_PRSP_EN) + + +/*=============================================== + EEPROM Read/Write Request 32bit RW + ------------------------------------------ + 1 EE_READ - EEPROM Read Request 1 - Setting this bit + loads a single byte of data into the EE_DATA + register from the EEPROM location specified in + the EE_ADDR register. + The Wlan hardware hardware clears this bit automatically. + EE_DATA is valid when this bit is cleared. + + 0 EE_WRITE - EEPROM Write Request - Setting this bit + writes a single byte of data from the EE_DATA register into the + EEPROM location specified in the EE_ADDR register. + The Wlan hardware hardware clears this bit automatically. +*===============================================*/ +#define EE_CTL (REGISTERS_BASE + 0x2000) +#define ACX_EE_CTL_REG EE_CTL +#define EE_WRITE 0x00000001ul +#define EE_READ 0x00000002ul + +/*=============================================== + EEPROM Address - 32bit RW + ------------------------------------------ + This register specifies the address + within the EEPROM from/to which to read/write data. + ===============================================*/ +#define EE_ADDR (REGISTERS_BASE + 0x2008) +#define ACX_EE_ADDR_REG EE_ADDR + +/*=============================================== + EEPROM Data - 32bit RW + ------------------------------------------ + This register either holds the read 8 bits of + data from the EEPROM or the write data + to be written to the EEPROM. + ===============================================*/ +#define EE_DATA (REGISTERS_BASE + 0x2004) +#define ACX_EE_DATA_REG EE_DATA + +#define EEPROM_ACCESS_TO 10000 /* timeout counter */ +#define START_EEPROM_MGR 0x00000001 + +/*=============================================== + EEPROM Base Address - 32bit RW + ------------------------------------------ + This register holds the upper nine bits + [23:15] of the 24-bit Wlan hardware memory + address for burst reads from EEPROM accesses. + The EEPROM provides the lower 15 bits of this address. + The MSB of the address from the EEPROM is ignored. + ===============================================*/ +#define ACX_EE_CFG EE_CFG + +/*=============================================== + GPIO Output Values -32bit, RW + ------------------------------------------ + [31:16] Reserved + [15: 0] Specify the output values (at the output driver inputs) for + GPIO[15:0], respectively. + ===============================================*/ +#define ACX_GPIO_OUT_REG GPIO_OUT +#define ACX_MAX_GPIO_LINES 15 + +/*=============================================== + Contention window -32bit, RW + ------------------------------------------ + [31:26] Reserved + [25:16] Max (0x3ff) + [15:07] Reserved + [06:00] Current contention window value - default is 0x1F + ===============================================*/ +#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG +#define ACX_CONT_WIND_MIN_MASK 0x0000007f +#define ACX_CONT_WIND_MAX 0x03ff0000 + +/*=============================================== + HI_CFG Interface Configuration Register Values + ------------------------------------------ + ===============================================*/ +#define HI_CFG_UART_ENABLE 0x00000004 +#define HI_CFG_RST232_ENABLE 0x00000008 +#define HI_CFG_CLOCK_REQ_SELECT 0x00000010 +#define HI_CFG_HOST_INT_ENABLE 0x00000020 +#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040 +#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080 +#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100 +#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 +#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 + +/* + * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile + * for platforms using active high interrupt level + */ +#ifdef USE_ACTIVE_HIGH +#define HI_CFG_DEF_VAL \ + (HI_CFG_UART_ENABLE | \ + HI_CFG_RST232_ENABLE | \ + HI_CFG_CLOCK_REQ_SELECT | \ + HI_CFG_HOST_INT_ENABLE) +#else +#define HI_CFG_DEF_VAL \ + (HI_CFG_UART_ENABLE | \ + HI_CFG_RST232_ENABLE | \ + HI_CFG_CLOCK_REQ_SELECT | \ + HI_CFG_HOST_INT_ENABLE) + +#endif + +#define REF_FREQ_19_2 0 +#define REF_FREQ_26_0 1 +#define REF_FREQ_38_4 2 +#define REF_FREQ_40_0 3 +#define REF_FREQ_33_6 4 +#define REF_FREQ_NUM 5 + +#define LUT_PARAM_INTEGER_DIVIDER 0 +#define LUT_PARAM_FRACTIONAL_DIVIDER 1 +#define LUT_PARAM_ATTN_BB 2 +#define LUT_PARAM_ALPHA_BB 3 +#define LUT_PARAM_STOP_TIME_BB 4 +#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 +#define LUT_PARAM_NUM 6 + +#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) +#define USE_EEPROM 0 +#define SOFT_RESET_MAX_TIME 1000000 +#define SOFT_RESET_STALL_TIME 1000 +#define NVS_DATA_BUNDARY_ALIGNMENT 4 + + +/* Firmware image load chunk size */ +#define CHUNK_SIZE 512 + +/* Firmware image header size */ +#define FW_HDR_SIZE 8 + +#define ECPU_CONTROL_HALT 0x00000101 + + +/****************************************************************************** + + CHANNELS, BAND & REG DOMAINS definitions + +******************************************************************************/ + + +enum { + RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */ + RADIO_BAND_5GHZ = 1, /* 5 Ghz band */ + RADIO_BAND_JAPAN_4_9_GHZ = 2, + DEFAULT_BAND = RADIO_BAND_2_4GHZ, + INVALID_BAND = 0xFE, + MAX_RADIO_BANDS = 0xFF +}; + +enum { + NO_RATE = 0, + RATE_1MBPS = 0x0A, + RATE_2MBPS = 0x14, + RATE_5_5MBPS = 0x37, + RATE_6MBPS = 0x0B, + RATE_9MBPS = 0x0F, + RATE_11MBPS = 0x6E, + RATE_12MBPS = 0x0A, + RATE_18MBPS = 0x0E, + RATE_22MBPS = 0xDC, + RATE_24MBPS = 0x09, + RATE_36MBPS = 0x0D, + RATE_48MBPS = 0x08, + RATE_54MBPS = 0x0C +}; + +enum { + RATE_INDEX_1MBPS = 0, + RATE_INDEX_2MBPS = 1, + RATE_INDEX_5_5MBPS = 2, + RATE_INDEX_6MBPS = 3, + RATE_INDEX_9MBPS = 4, + RATE_INDEX_11MBPS = 5, + RATE_INDEX_12MBPS = 6, + RATE_INDEX_18MBPS = 7, + RATE_INDEX_22MBPS = 8, + RATE_INDEX_24MBPS = 9, + RATE_INDEX_36MBPS = 10, + RATE_INDEX_48MBPS = 11, + RATE_INDEX_54MBPS = 12, + RATE_INDEX_MAX = RATE_INDEX_54MBPS, + MAX_RATE_INDEX, + INVALID_RATE_INDEX = MAX_RATE_INDEX, + RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF +}; + +enum { + RATE_MASK_1MBPS = 0x1, + RATE_MASK_2MBPS = 0x2, + RATE_MASK_5_5MBPS = 0x4, + RATE_MASK_11MBPS = 0x20, +}; + +#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ +#define OFDM_RATE_BIT BIT(6) +#define PBCC_RATE_BIT BIT(7) + +enum { + CCK_LONG = 0, + CCK_SHORT = SHORT_PREAMBLE_BIT, + PBCC_LONG = PBCC_RATE_BIT, + PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT, + OFDM = OFDM_RATE_BIT +}; + +/****************************************************************************** + +Transmit-Descriptor RATE-SET field definitions... + +Define a new "Rate-Set" for TX path that incorporates the +Rate & Modulation info into a single 16-bit field. + +TxdRateSet_t: +b15 - Indicates Preamble type (1=SHORT, 0=LONG). + Notes: + Must be LONG (0) for 1Mbps rate. + Does not apply (set to 0) for RevG-OFDM rates. +b14 - Indicates PBCC encoding (1=PBCC, 0=not). + Notes: + Does not apply (set to 0) for rates 1 and 2 Mbps. + Does not apply (set to 0) for RevG-OFDM rates. +b13 - Unused (set to 0). +b12-b0 - Supported Rate indicator bits as defined below. + +******************************************************************************/ + + +/************************************************************************* + + Interrupt Trigger Register (Host -> WiLink) + +**************************************************************************/ + +/* Hardware to Embedded CPU Interrupts - first 32-bit register set */ + +/* + * Host Command Interrupt. Setting this bit masks + * the interrupt that the host issues to inform + * the FW that it has sent a command + * to the Wlan hardware Command Mailbox. + */ +#define INTR_TRIG_CMD BIT(0) + +/* + * Host Event Acknowlegde Interrupt. The host + * sets this bit to acknowledge that it received + * the unsolicited information from the event + * mailbox. + */ +#define INTR_TRIG_EVENT_ACK BIT(1) + +/* + * The host sets this bit to inform the Wlan + * FW that a TX packet is in the XFER + * Buffer #0. + */ +#define INTR_TRIG_TX_PROC0 BIT(2) + +/* + * The host sets this bit to inform the FW + * that it read a packet from RX XFER + * Buffer #0. + */ +#define INTR_TRIG_RX_PROC0 BIT(3) + +#define INTR_TRIG_DEBUG_ACK BIT(4) + +#define INTR_TRIG_STATE_CHANGED BIT(5) + + +/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ + +/* + * The host sets this bit to inform the FW + * that it read a packet from RX XFER + * Buffer #1. + */ +#define INTR_TRIG_RX_PROC1 BIT(17) + +/* + * The host sets this bit to inform the Wlan + * hardware that a TX packet is in the XFER + * Buffer #1. + */ +#define INTR_TRIG_TX_PROC1 BIT(18) + +#endif diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c new file mode 100644 index 000000000000..efa53607d5c9 --- /dev/null +++ b/drivers/net/wireless/wl1251/rx.c @@ -0,0 +1,190 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +#include "wl1251.h" +#include "reg.h" +#include "io.h" +#include "rx.h" +#include "cmd.h" +#include "acx.h" + +static void wl1251_rx_header(struct wl1251 *wl, + struct wl1251_rx_descriptor *desc) +{ + u32 rx_packet_ring_addr; + + rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr; + if (wl->rx_current_buffer) + rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; + + wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc)); +} + +static void wl1251_rx_status(struct wl1251 *wl, + struct wl1251_rx_descriptor *desc, + struct ieee80211_rx_status *status, + u8 beacon) +{ + u64 mactime; + int ret; + + memset(status, 0, sizeof(struct ieee80211_rx_status)); + + status->band = IEEE80211_BAND_2GHZ; + status->mactime = desc->timestamp; + + /* + * The rx status timestamp is a 32 bits value while the TSF is a + * 64 bits one. + * For IBSS merging, TSF is mandatory, so we have to get it + * somehow, so we ask for ACX_TSF_INFO. + * That could be moved to the get_tsf() hook, but unfortunately, + * this one must be atomic, while our SPI routines can sleep. + */ + if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) { + ret = wl1251_acx_tsf_info(wl, &mactime); + if (ret == 0) + status->mactime = mactime; + } + + status->signal = desc->rssi; + + /* + * FIXME: guessing that snr needs to be divided by two, otherwise + * the values don't make any sense + */ + wl->noise = desc->rssi - desc->snr / 2; + + status->freq = ieee80211_channel_to_frequency(desc->channel); + + status->flag |= RX_FLAG_TSFT; + + if (desc->flags & RX_DESC_ENCRYPTION_MASK) { + status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; + + if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL))) + status->flag |= RX_FLAG_DECRYPTED; + + if (unlikely(desc->flags & RX_DESC_MIC_FAIL)) + status->flag |= RX_FLAG_MMIC_ERROR; + } + + if (unlikely(!(desc->flags & RX_DESC_VALID_FCS))) + status->flag |= RX_FLAG_FAILED_FCS_CRC; + + + /* FIXME: set status->rate_idx */ +} + +static void wl1251_rx_body(struct wl1251 *wl, + struct wl1251_rx_descriptor *desc) +{ + struct sk_buff *skb; + struct ieee80211_rx_status status; + u8 *rx_buffer, beacon = 0; + u16 length, *fc; + u32 curr_id, last_id_inc, rx_packet_ring_addr; + + length = WL1251_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH); + curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT; + last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1); + + if (last_id_inc != curr_id) { + wl1251_warning("curr ID:%d, last ID inc:%d", + curr_id, last_id_inc); + wl->rx_last_id = curr_id; + } else { + wl->rx_last_id = last_id_inc; + } + + rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr + + sizeof(struct wl1251_rx_descriptor) + 20; + if (wl->rx_current_buffer) + rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; + + skb = __dev_alloc_skb(length, GFP_KERNEL); + if (!skb) { + wl1251_error("Couldn't allocate RX frame"); + return; + } + + rx_buffer = skb_put(skb, length); + wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); + + /* The actual lenght doesn't include the target's alignment */ + skb->len = desc->length - PLCP_HEADER_LENGTH; + + fc = (u16 *)skb->data; + + if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) + beacon = 1; + + wl1251_rx_status(wl, desc, &status, beacon); + + wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, + beacon ? "beacon" : ""); + + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx_ni(wl->hw, skb); +} + +static void wl1251_rx_ack(struct wl1251 *wl) +{ + u32 data, addr; + + if (wl->rx_current_buffer) { + addr = ACX_REG_INTERRUPT_TRIG_H; + data = INTR_TRIG_RX_PROC1; + } else { + addr = ACX_REG_INTERRUPT_TRIG; + data = INTR_TRIG_RX_PROC0; + } + + wl1251_reg_write32(wl, addr, data); + + /* Toggle buffer ring */ + wl->rx_current_buffer = !wl->rx_current_buffer; +} + + +void wl1251_rx(struct wl1251 *wl) +{ + struct wl1251_rx_descriptor *rx_desc; + + if (wl->state != WL1251_STATE_ON) + return; + + rx_desc = wl->rx_descriptor; + + /* We first read the frame's header */ + wl1251_rx_header(wl, rx_desc); + + /* Now we can read the body */ + wl1251_rx_body(wl, rx_desc); + + /* Finally, we need to ACK the RX */ + wl1251_rx_ack(wl); +} diff --git a/drivers/net/wireless/wl1251/rx.h b/drivers/net/wireless/wl1251/rx.h new file mode 100644 index 000000000000..4448f635a4d8 --- /dev/null +++ b/drivers/net/wireless/wl1251/rx.h @@ -0,0 +1,122 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_RX_H__ +#define __WL1251_RX_H__ + +#include + +#include "wl1251.h" + +/* + * RX PATH + * + * The Rx path uses a double buffer and an rx_contro structure, each located + * at a fixed address in the device memory. The host keeps track of which + * buffer is available and alternates between them on a per packet basis. + * The size of each of the two buffers is large enough to hold the longest + * 802.3 packet. + * The RX path goes like that: + * 1) The target generates an interrupt each time a new packet is received. + * There are 2 RX interrupts, one for each buffer. + * 2) The host reads the received packet from one of the double buffers. + * 3) The host triggers a target interrupt. + * 4) The target prepares the next RX packet. + */ + +#define WL1251_RX_MAX_RSSI -30 +#define WL1251_RX_MIN_RSSI -95 + +#define WL1251_RX_ALIGN_TO 4 +#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \ + ~(WL1251_RX_ALIGN_TO - 1)) + +#define SHORT_PREAMBLE_BIT BIT(0) +#define OFDM_RATE_BIT BIT(6) +#define PBCC_RATE_BIT BIT(7) + +#define PLCP_HEADER_LENGTH 8 +#define RX_DESC_PACKETID_SHIFT 11 +#define RX_MAX_PACKET_ID 3 + +#define RX_DESC_VALID_FCS 0x0001 +#define RX_DESC_MATCH_RXADDR1 0x0002 +#define RX_DESC_MCAST 0x0004 +#define RX_DESC_STAINTIM 0x0008 +#define RX_DESC_VIRTUAL_BM 0x0010 +#define RX_DESC_BCAST 0x0020 +#define RX_DESC_MATCH_SSID 0x0040 +#define RX_DESC_MATCH_BSSID 0x0080 +#define RX_DESC_ENCRYPTION_MASK 0x0300 +#define RX_DESC_MEASURMENT 0x0400 +#define RX_DESC_SEQNUM_MASK 0x1800 +#define RX_DESC_MIC_FAIL 0x2000 +#define RX_DESC_DECRYPT_FAIL 0x4000 + +struct wl1251_rx_descriptor { + u32 timestamp; /* In microseconds */ + u16 length; /* Paylod length, including headers */ + u16 flags; + + /* + * 0 - 802.11 + * 1 - 802.3 + * 2 - IP + * 3 - Raw Codec + */ + u8 type; + + /* + * Received Rate: + * 0x0A - 1MBPS + * 0x14 - 2MBPS + * 0x37 - 5_5MBPS + * 0x0B - 6MBPS + * 0x0F - 9MBPS + * 0x6E - 11MBPS + * 0x0A - 12MBPS + * 0x0E - 18MBPS + * 0xDC - 22MBPS + * 0x09 - 24MBPS + * 0x0D - 36MBPS + * 0x08 - 48MBPS + * 0x0C - 54MBPS + */ + u8 rate; + + u8 mod_pre; /* Modulation and preamble */ + u8 channel; + + /* + * 0 - 2.4 Ghz + * 1 - 5 Ghz + */ + u8 band; + + s8 rssi; /* in dB */ + u8 rcpi; /* in dB */ + u8 snr; /* in dB */ +} __packed; + +void wl1251_rx(struct wl1251 *wl); + +#endif diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c new file mode 100644 index 000000000000..74ba9ced5393 --- /dev/null +++ b/drivers/net/wireless/wl1251/sdio.c @@ -0,0 +1,342 @@ +/* + * wl12xx SDIO routines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Copyright (C) 2005 Texas Instruments Incorporated + * Copyright (C) 2008 Google Inc + * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) + */ +#include +#include +#include +#include +#include +#include +#include + +#include "wl1251.h" + +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI 0x104c +#endif + +#ifndef SDIO_DEVICE_ID_TI_WL1251 +#define SDIO_DEVICE_ID_TI_WL1251 0x9066 +#endif + +struct wl1251_sdio { + struct sdio_func *func; + u32 elp_val; +}; + +static struct wl12xx_platform_data *wl12xx_board_data; + +static struct sdio_func *wl_to_func(struct wl1251 *wl) +{ + struct wl1251_sdio *wl_sdio = wl->if_priv; + return wl_sdio->func; +} + +static void wl1251_sdio_interrupt(struct sdio_func *func) +{ + struct wl1251 *wl = sdio_get_drvdata(func); + + wl1251_debug(DEBUG_IRQ, "IRQ"); + + /* FIXME should be synchronous for sdio */ + ieee80211_queue_work(wl->hw, &wl->irq_work); +} + +static const struct sdio_device_id wl1251_devices[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) }, + {} +}; +MODULE_DEVICE_TABLE(sdio, wl1251_devices); + + +static void wl1251_sdio_read(struct wl1251 *wl, int addr, + void *buf, size_t len) +{ + int ret; + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + ret = sdio_memcpy_fromio(func, buf, addr, len); + if (ret) + wl1251_error("sdio read failed (%d)", ret); + sdio_release_host(func); +} + +static void wl1251_sdio_write(struct wl1251 *wl, int addr, + void *buf, size_t len) +{ + int ret; + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + ret = sdio_memcpy_toio(func, addr, buf, len); + if (ret) + wl1251_error("sdio write failed (%d)", ret); + sdio_release_host(func); +} + +static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) +{ + int ret = 0; + struct wl1251_sdio *wl_sdio = wl->if_priv; + struct sdio_func *func = wl_sdio->func; + + /* + * The hardware only supports RAW (read after write) access for + * reading, regular sdio_readb won't work here (it interprets + * the unused bits of CMD52 as write data even if we send read + * request). + */ + sdio_claim_host(func); + *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret); + sdio_release_host(func); + + if (ret) + wl1251_error("sdio_readb failed (%d)", ret); +} + +static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) +{ + int ret = 0; + struct wl1251_sdio *wl_sdio = wl->if_priv; + struct sdio_func *func = wl_sdio->func; + + sdio_claim_host(func); + sdio_writeb(func, val, addr, &ret); + sdio_release_host(func); + + if (ret) + wl1251_error("sdio_writeb failed (%d)", ret); + else + wl_sdio->elp_val = val; +} + +static void wl1251_sdio_reset(struct wl1251 *wl) +{ +} + +static void wl1251_sdio_enable_irq(struct wl1251 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + sdio_claim_irq(func, wl1251_sdio_interrupt); + sdio_release_host(func); +} + +static void wl1251_sdio_disable_irq(struct wl1251 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + + sdio_claim_host(func); + sdio_release_irq(func); + sdio_release_host(func); +} + +/* Interrupts when using dedicated WLAN_IRQ pin */ +static irqreturn_t wl1251_line_irq(int irq, void *cookie) +{ + struct wl1251 *wl = cookie; + + ieee80211_queue_work(wl->hw, &wl->irq_work); + + return IRQ_HANDLED; +} + +static void wl1251_enable_line_irq(struct wl1251 *wl) +{ + return enable_irq(wl->irq); +} + +static void wl1251_disable_line_irq(struct wl1251 *wl) +{ + return disable_irq(wl->irq); +} + +static void wl1251_sdio_set_power(bool enable) +{ +} + +static struct wl1251_if_operations wl1251_sdio_ops = { + .read = wl1251_sdio_read, + .write = wl1251_sdio_write, + .write_elp = wl1251_sdio_write_elp, + .read_elp = wl1251_sdio_read_elp, + .reset = wl1251_sdio_reset, +}; + +static int wl1251_platform_probe(struct platform_device *pdev) +{ + if (pdev->id != -1) { + wl1251_error("can only handle single device"); + return -ENODEV; + } + + wl12xx_board_data = pdev->dev.platform_data; + return 0; +} + +/* + * Dummy platform_driver for passing platform_data to this driver, + * until we have a way to pass this through SDIO subsystem or + * some other way. + */ +static struct platform_driver wl1251_platform_driver = { + .driver = { + .name = "wl1251_data", + .owner = THIS_MODULE, + }, + .probe = wl1251_platform_probe, +}; + +static int wl1251_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int ret; + struct wl1251 *wl; + struct ieee80211_hw *hw; + struct wl1251_sdio *wl_sdio; + + hw = wl1251_alloc_hw(); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + wl = hw->priv; + + wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); + if (wl_sdio == NULL) { + ret = -ENOMEM; + goto out_free_hw; + } + + sdio_claim_host(func); + ret = sdio_enable_func(func); + if (ret) + goto release; + + sdio_set_block_size(func, 512); + sdio_release_host(func); + + SET_IEEE80211_DEV(hw, &func->dev); + wl_sdio->func = func; + wl->if_priv = wl_sdio; + wl->if_ops = &wl1251_sdio_ops; + wl->set_power = wl1251_sdio_set_power; + + if (wl12xx_board_data != NULL) { + wl->set_power = wl12xx_board_data->set_power; + wl->irq = wl12xx_board_data->irq; + wl->use_eeprom = wl12xx_board_data->use_eeprom; + } + + if (wl->irq) { + ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); + if (ret < 0) { + wl1251_error("request_irq() failed: %d", ret); + goto disable; + } + + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + disable_irq(wl->irq); + + wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; + wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; + + wl1251_info("using dedicated interrupt line"); + } else { + wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; + wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; + + wl1251_info("using SDIO interrupt"); + } + + ret = wl1251_init_ieee80211(wl); + if (ret) + goto out_free_irq; + + sdio_set_drvdata(func, wl); + return ret; + +out_free_irq: + if (wl->irq) + free_irq(wl->irq, wl); +disable: + sdio_claim_host(func); + sdio_disable_func(func); +release: + sdio_release_host(func); + kfree(wl_sdio); +out_free_hw: + wl1251_free_hw(wl); + return ret; +} + +static void __devexit wl1251_sdio_remove(struct sdio_func *func) +{ + struct wl1251 *wl = sdio_get_drvdata(func); + struct wl1251_sdio *wl_sdio = wl->if_priv; + + if (wl->irq) + free_irq(wl->irq, wl); + kfree(wl_sdio); + wl1251_free_hw(wl); + + sdio_claim_host(func); + sdio_release_irq(func); + sdio_disable_func(func); + sdio_release_host(func); +} + +static struct sdio_driver wl1251_sdio_driver = { + .name = "wl1251_sdio", + .id_table = wl1251_devices, + .probe = wl1251_sdio_probe, + .remove = __devexit_p(wl1251_sdio_remove), +}; + +static int __init wl1251_sdio_init(void) +{ + int err; + + err = platform_driver_register(&wl1251_platform_driver); + if (err) { + wl1251_error("failed to register platform driver: %d", err); + return err; + } + + err = sdio_register_driver(&wl1251_sdio_driver); + if (err) + wl1251_error("failed to register sdio driver: %d", err); + return err; +} + +static void __exit wl1251_sdio_exit(void) +{ + sdio_unregister_driver(&wl1251_sdio_driver); + platform_driver_unregister(&wl1251_platform_driver); + wl1251_notice("unloaded"); +} + +module_init(wl1251_sdio_init); +module_exit(wl1251_sdio_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kalle Valo "); diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c new file mode 100644 index 000000000000..88fa8e69d0d1 --- /dev/null +++ b/drivers/net/wireless/wl1251/spi.c @@ -0,0 +1,346 @@ +/* + * This file is part of wl1251 + * + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include "wl1251.h" +#include "reg.h" +#include "spi.h" + +static irqreturn_t wl1251_irq(int irq, void *cookie) +{ + struct wl1251 *wl; + + wl1251_debug(DEBUG_IRQ, "IRQ"); + + wl = cookie; + + ieee80211_queue_work(wl->hw, &wl->irq_work); + + return IRQ_HANDLED; +} + +static struct spi_device *wl_to_spi(struct wl1251 *wl) +{ + return wl->if_priv; +} + +static void wl1251_spi_reset(struct wl1251 *wl) +{ + u8 *cmd; + struct spi_transfer t; + struct spi_message m; + + cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); + if (!cmd) { + wl1251_error("could not allocate cmd for spi reset"); + return; + } + + memset(&t, 0, sizeof(t)); + spi_message_init(&m); + + memset(cmd, 0xff, WSPI_INIT_CMD_LEN); + + t.tx_buf = cmd; + t.len = WSPI_INIT_CMD_LEN; + spi_message_add_tail(&t, &m); + + spi_sync(wl_to_spi(wl), &m); + + wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); +} + +static void wl1251_spi_wake(struct wl1251 *wl) +{ + u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; + struct spi_transfer t; + struct spi_message m; + + cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); + if (!cmd) { + wl1251_error("could not allocate cmd for spi init"); + return; + } + + memset(crc, 0, sizeof(crc)); + memset(&t, 0, sizeof(t)); + spi_message_init(&m); + + /* + * Set WSPI_INIT_COMMAND + * the data is being send from the MSB to LSB + */ + cmd[2] = 0xff; + cmd[3] = 0xff; + cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX; + cmd[0] = 0; + cmd[7] = 0; + cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3; + cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN; + + if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0) + cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY; + else + cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY; + + cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS + | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS; + + crc[0] = cmd[1]; + crc[1] = cmd[0]; + crc[2] = cmd[7]; + crc[3] = cmd[6]; + crc[4] = cmd[5]; + + cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1; + cmd[4] |= WSPI_INIT_CMD_END; + + t.tx_buf = cmd; + t.len = WSPI_INIT_CMD_LEN; + spi_message_add_tail(&t, &m); + + spi_sync(wl_to_spi(wl), &m); + + wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); +} + +static void wl1251_spi_reset_wake(struct wl1251 *wl) +{ + wl1251_spi_reset(wl); + wl1251_spi_wake(wl); +} + +static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, + size_t len) +{ + struct spi_transfer t[3]; + struct spi_message m; + u8 *busy_buf; + u32 *cmd; + + cmd = &wl->buffer_cmd; + busy_buf = wl->buffer_busyword; + + *cmd = 0; + *cmd |= WSPI_CMD_READ; + *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = 4; + spi_message_add_tail(&t[0], &m); + + /* Busy and non busy words read */ + t[1].rx_buf = busy_buf; + t[1].len = WL1251_BUSY_WORD_LEN; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = buf; + t[2].len = len; + spi_message_add_tail(&t[2], &m); + + spi_sync(wl_to_spi(wl), &m); + + /* FIXME: check busy words */ + + wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); + wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); +} + +static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, + size_t len) +{ + struct spi_transfer t[2]; + struct spi_message m; + u32 *cmd; + + cmd = &wl->buffer_cmd; + + *cmd = 0; + *cmd |= WSPI_CMD_WRITE; + *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = sizeof(*cmd); + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = buf; + t[1].len = len; + spi_message_add_tail(&t[1], &m); + + spi_sync(wl_to_spi(wl), &m); + + wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); + wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); +} + +static void wl1251_spi_enable_irq(struct wl1251 *wl) +{ + return enable_irq(wl->irq); +} + +static void wl1251_spi_disable_irq(struct wl1251 *wl) +{ + return disable_irq(wl->irq); +} + +static const struct wl1251_if_operations wl1251_spi_ops = { + .read = wl1251_spi_read, + .write = wl1251_spi_write, + .reset = wl1251_spi_reset_wake, + .enable_irq = wl1251_spi_enable_irq, + .disable_irq = wl1251_spi_disable_irq, +}; + +static int __devinit wl1251_spi_probe(struct spi_device *spi) +{ + struct wl12xx_platform_data *pdata; + struct ieee80211_hw *hw; + struct wl1251 *wl; + int ret; + + pdata = spi->dev.platform_data; + if (!pdata) { + wl1251_error("no platform data"); + return -ENODEV; + } + + hw = wl1251_alloc_hw(); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + wl = hw->priv; + + SET_IEEE80211_DEV(hw, &spi->dev); + dev_set_drvdata(&spi->dev, wl); + wl->if_priv = spi; + wl->if_ops = &wl1251_spi_ops; + + /* This is the only SPI value that we need to set here, the rest + * comes from the board-peripherals file */ + spi->bits_per_word = 32; + + ret = spi_setup(spi); + if (ret < 0) { + wl1251_error("spi_setup failed"); + goto out_free; + } + + wl->set_power = pdata->set_power; + if (!wl->set_power) { + wl1251_error("set power function missing in platform data"); + return -ENODEV; + } + + wl->irq = spi->irq; + if (wl->irq < 0) { + wl1251_error("irq missing in platform data"); + return -ENODEV; + } + + wl->use_eeprom = pdata->use_eeprom; + + ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); + if (ret < 0) { + wl1251_error("request_irq() failed: %d", ret); + goto out_free; + } + + set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + + disable_irq(wl->irq); + + ret = wl1251_init_ieee80211(wl); + if (ret) + goto out_irq; + + return 0; + + out_irq: + free_irq(wl->irq, wl); + + out_free: + ieee80211_free_hw(hw); + + return ret; +} + +static int __devexit wl1251_spi_remove(struct spi_device *spi) +{ + struct wl1251 *wl = dev_get_drvdata(&spi->dev); + + free_irq(wl->irq, wl); + wl1251_free_hw(wl); + + return 0; +} + +static struct spi_driver wl1251_spi_driver = { + .driver = { + .name = DRIVER_NAME, + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = wl1251_spi_probe, + .remove = __devexit_p(wl1251_spi_remove), +}; + +static int __init wl1251_spi_init(void) +{ + int ret; + + ret = spi_register_driver(&wl1251_spi_driver); + if (ret < 0) { + wl1251_error("failed to register spi driver: %d", ret); + goto out; + } + +out: + return ret; +} + +static void __exit wl1251_spi_exit(void) +{ + spi_unregister_driver(&wl1251_spi_driver); + + wl1251_notice("unloaded"); +} + +module_init(wl1251_spi_init); +module_exit(wl1251_spi_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kalle Valo "); +MODULE_ALIAS("spi:wl1251"); diff --git a/drivers/net/wireless/wl1251/spi.h b/drivers/net/wireless/wl1251/spi.h new file mode 100644 index 000000000000..16d506955cc0 --- /dev/null +++ b/drivers/net/wireless/wl1251/spi.h @@ -0,0 +1,59 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_SPI_H__ +#define __WL1251_SPI_H__ + +#include "cmd.h" +#include "acx.h" +#include "reg.h" + +#define WSPI_CMD_READ 0x40000000 +#define WSPI_CMD_WRITE 0x00000000 +#define WSPI_CMD_FIXED 0x20000000 +#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 +#define WSPI_CMD_BYTE_LENGTH_OFFSET 17 +#define WSPI_CMD_BYTE_ADDR 0x0001FFFF + +#define WSPI_INIT_CMD_CRC_LEN 5 + +#define WSPI_INIT_CMD_START 0x00 +#define WSPI_INIT_CMD_TX 0x40 +/* the extra bypass bit is sampled by the TNET as '1' */ +#define WSPI_INIT_CMD_BYPASS_BIT 0x80 +#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 +#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 +#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 +#define WSPI_INIT_CMD_IOD 0x40 +#define WSPI_INIT_CMD_IP 0x20 +#define WSPI_INIT_CMD_CS 0x10 +#define WSPI_INIT_CMD_WS 0x08 +#define WSPI_INIT_CMD_WSPI 0x01 +#define WSPI_INIT_CMD_END 0x01 + +#define WSPI_INIT_CMD_LEN 8 + +#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ + ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32)) +#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 + +#endif /* __WL1251_SPI_H__ */ diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/wl1251/tx.c new file mode 100644 index 000000000000..554b4f9a3d3e --- /dev/null +++ b/drivers/net/wireless/wl1251/tx.c @@ -0,0 +1,570 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include "wl1251.h" +#include "reg.h" +#include "tx.h" +#include "ps.h" +#include "io.h" + +static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) +{ + int used, data_in_count; + + data_in_count = wl->data_in_count; + + if (data_in_count < data_out_count) + /* data_in_count has wrapped */ + data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1; + + used = data_in_count - data_out_count; + + WARN_ON(used < 0); + WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM); + + if (used >= DP_TX_PACKET_RING_CHUNK_NUM) + return true; + else + return false; +} + +static int wl1251_tx_path_status(struct wl1251 *wl) +{ + u32 status, addr, data_out_count; + bool busy; + + addr = wl->data_path->tx_control_addr; + status = wl1251_mem_read32(wl, addr); + data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK; + busy = wl1251_tx_double_buffer_busy(wl, data_out_count); + + if (busy) + return -EBUSY; + + return 0; +} + +static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb) +{ + int i; + + for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) + if (wl->tx_frames[i] == NULL) { + wl->tx_frames[i] = skb; + return i; + } + + return -EBUSY; +} + +static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr, + struct ieee80211_tx_info *control, u16 fc) +{ + *(u16 *)&tx_hdr->control = 0; + + tx_hdr->control.rate_policy = 0; + + /* 802.11 packets */ + tx_hdr->control.packet_type = 0; + + if (control->flags & IEEE80211_TX_CTL_NO_ACK) + tx_hdr->control.ack_policy = 1; + + tx_hdr->control.tx_complete = 1; + + if ((fc & IEEE80211_FTYPE_DATA) && + ((fc & IEEE80211_STYPE_QOS_DATA) || + (fc & IEEE80211_STYPE_QOS_NULLFUNC))) + tx_hdr->control.qos = 1; +} + +/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */ +#define MAX_MSDU_SECURITY_LENGTH 16 +#define MAX_MPDU_SECURITY_LENGTH 16 +#define WLAN_QOS_HDR_LEN 26 +#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \ + WLAN_QOS_HDR_LEN) +#define HW_BLOCK_SIZE 252 +static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr) +{ + u16 payload_len, frag_threshold, mem_blocks; + u16 num_mpdus, mem_blocks_per_frag; + + frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; + tx_hdr->frag_threshold = cpu_to_le16(frag_threshold); + + payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH; + + if (payload_len > frag_threshold) { + mem_blocks_per_frag = + ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) / + HW_BLOCK_SIZE) + 1; + num_mpdus = payload_len / frag_threshold; + mem_blocks = num_mpdus * mem_blocks_per_frag; + payload_len -= num_mpdus * frag_threshold; + num_mpdus++; + + } else { + mem_blocks_per_frag = 0; + mem_blocks = 0; + num_mpdus = 1; + } + + mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1; + + if (num_mpdus > 1) + mem_blocks += min(num_mpdus, mem_blocks_per_frag); + + tx_hdr->num_mem_blocks = mem_blocks; +} + +static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb, + struct ieee80211_tx_info *control) +{ + struct tx_double_buffer_desc *tx_hdr; + struct ieee80211_rate *rate; + int id; + u16 fc; + + if (!skb) + return -EINVAL; + + id = wl1251_tx_id(wl, skb); + if (id < 0) + return id; + + fc = *(u16 *)skb->data; + tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb, + sizeof(*tx_hdr)); + + tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr)); + rate = ieee80211_get_tx_rate(wl->hw, control); + tx_hdr->rate = cpu_to_le16(rate->hw_value); + tx_hdr->expiry_time = cpu_to_le32(1 << 16); + tx_hdr->id = id; + + tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb)); + + wl1251_tx_control(tx_hdr, control, fc); + wl1251_tx_frag_block_num(tx_hdr); + + return 0; +} + +/* We copy the packet to the target */ +static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, + struct ieee80211_tx_info *control) +{ + struct tx_double_buffer_desc *tx_hdr; + int len; + u32 addr; + + if (!skb) + return -EINVAL; + + tx_hdr = (struct tx_double_buffer_desc *) skb->data; + + if (control->control.hw_key && + control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { + int hdrlen; + __le16 fc; + u16 length; + u8 *pos; + + fc = *(__le16 *)(skb->data + sizeof(*tx_hdr)); + length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE; + tx_hdr->length = cpu_to_le16(length); + + hdrlen = ieee80211_hdrlen(fc); + + pos = skb_push(skb, WL1251_TKIP_IV_SPACE); + memmove(pos, pos + WL1251_TKIP_IV_SPACE, + sizeof(*tx_hdr) + hdrlen); + } + + /* Revisit. This is a workaround for getting non-aligned packets. + This happens at least with EAPOL packets from the user space. + Our DMA requires packets to be aligned on a 4-byte boundary. + */ + if (unlikely((long)skb->data & 0x03)) { + int offset = (4 - (long)skb->data) & 0x03; + wl1251_debug(DEBUG_TX, "skb offset %d", offset); + + /* check whether the current skb can be used */ + if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { + unsigned char *src = skb->data; + + /* align the buffer on a 4-byte boundary */ + skb_reserve(skb, offset); + memmove(skb->data, src, skb->len); + tx_hdr = (struct tx_double_buffer_desc *) skb->data; + } else { + wl1251_info("No handler, fixme!"); + return -EINVAL; + } + } + + /* Our skb->data at this point includes the HW header */ + len = WL1251_TX_ALIGN(skb->len); + + if (wl->data_in_count & 0x1) + addr = wl->data_path->tx_packet_ring_addr + + wl->data_path->tx_packet_ring_chunk_size; + else + addr = wl->data_path->tx_packet_ring_addr; + + wl1251_mem_write(wl, addr, skb->data, len); + + wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x " + "queue %d", tx_hdr->id, skb, tx_hdr->length, + tx_hdr->rate, tx_hdr->xmit_queue); + + return 0; +} + +static void wl1251_tx_trigger(struct wl1251 *wl) +{ + u32 data, addr; + + if (wl->data_in_count & 0x1) { + addr = ACX_REG_INTERRUPT_TRIG_H; + data = INTR_TRIG_TX_PROC1; + } else { + addr = ACX_REG_INTERRUPT_TRIG; + data = INTR_TRIG_TX_PROC0; + } + + wl1251_reg_write32(wl, addr, data); + + /* Bumping data in */ + wl->data_in_count = (wl->data_in_count + 1) & + TX_STATUS_DATA_OUT_COUNT_MASK; +} + +/* caller must hold wl->mutex */ +static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info; + int ret = 0; + u8 idx; + + info = IEEE80211_SKB_CB(skb); + + if (info->control.hw_key) { + idx = info->control.hw_key->hw_key_idx; + if (unlikely(wl->default_key != idx)) { + ret = wl1251_acx_default_key(wl, idx); + if (ret < 0) + return ret; + } + } + + ret = wl1251_tx_path_status(wl); + if (ret < 0) + return ret; + + ret = wl1251_tx_fill_hdr(wl, skb, info); + if (ret < 0) + return ret; + + ret = wl1251_tx_send_packet(wl, skb, info); + if (ret < 0) + return ret; + + wl1251_tx_trigger(wl); + + return ret; +} + +void wl1251_tx_work(struct work_struct *work) +{ + struct wl1251 *wl = container_of(work, struct wl1251, tx_work); + struct sk_buff *skb; + bool woken_up = false; + int ret; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1251_STATE_OFF)) + goto out; + + while ((skb = skb_dequeue(&wl->tx_queue))) { + if (!woken_up) { + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + woken_up = true; + } + + ret = wl1251_tx_frame(wl, skb); + if (ret == -EBUSY) { + skb_queue_head(&wl->tx_queue, skb); + goto out; + } else if (ret < 0) { + dev_kfree_skb(skb); + goto out; + } + } + +out: + if (woken_up) + wl1251_ps_elp_sleep(wl); + + mutex_unlock(&wl->mutex); +} + +static const char *wl1251_tx_parse_status(u8 status) +{ + /* 8 bit status field, one character per bit plus null */ + static char buf[9]; + int i = 0; + + memset(buf, 0, sizeof(buf)); + + if (status & TX_DMA_ERROR) + buf[i++] = 'm'; + if (status & TX_DISABLED) + buf[i++] = 'd'; + if (status & TX_RETRY_EXCEEDED) + buf[i++] = 'r'; + if (status & TX_TIMEOUT) + buf[i++] = 't'; + if (status & TX_KEY_NOT_FOUND) + buf[i++] = 'k'; + if (status & TX_ENCRYPT_FAIL) + buf[i++] = 'e'; + if (status & TX_UNAVAILABLE_PRIORITY) + buf[i++] = 'p'; + + /* bit 0 is unused apparently */ + + return buf; +} + +static void wl1251_tx_packet_cb(struct wl1251 *wl, + struct tx_result *result) +{ + struct ieee80211_tx_info *info; + struct sk_buff *skb; + int hdrlen, ret; + u8 *frame; + + skb = wl->tx_frames[result->id]; + if (skb == NULL) { + wl1251_error("SKB for packet %d is NULL", result->id); + return; + } + + info = IEEE80211_SKB_CB(skb); + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && + (result->status == TX_SUCCESS)) + info->flags |= IEEE80211_TX_STAT_ACK; + + info->status.rates[0].count = result->ack_failures + 1; + wl->stats.retry_count += result->ack_failures; + + /* + * We have to remove our private TX header before pushing + * the skb back to mac80211. + */ + frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc)); + if (info->control.hw_key && + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen); + skb_pull(skb, WL1251_TKIP_IV_SPACE); + } + + wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" + " status 0x%x (%s)", + result->id, skb, result->ack_failures, result->rate, + result->status, wl1251_tx_parse_status(result->status)); + + + ieee80211_tx_status(wl->hw, skb); + + wl->tx_frames[result->id] = NULL; + + if (wl->tx_queue_stopped) { + wl1251_debug(DEBUG_TX, "cb: queue was stopped"); + + skb = skb_dequeue(&wl->tx_queue); + + /* The skb can be NULL because tx_work might have been + scheduled before the queue was stopped making the + queue empty */ + + if (skb) { + ret = wl1251_tx_frame(wl, skb); + if (ret == -EBUSY) { + /* firmware buffer is still full */ + wl1251_debug(DEBUG_TX, "cb: fw buffer " + "still full"); + skb_queue_head(&wl->tx_queue, skb); + return; + } else if (ret < 0) { + dev_kfree_skb(skb); + return; + } + } + + wl1251_debug(DEBUG_TX, "cb: waking queues"); + ieee80211_wake_queues(wl->hw); + wl->tx_queue_stopped = false; + } +} + +/* Called upon reception of a TX complete interrupt */ +void wl1251_tx_complete(struct wl1251 *wl) +{ + int i, result_index, num_complete = 0; + struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; + unsigned long flags; + + if (unlikely(wl->state != WL1251_STATE_ON)) + return; + + /* First we read the result */ + wl1251_mem_read(wl, wl->data_path->tx_complete_addr, + result, sizeof(result)); + + result_index = wl->next_tx_complete; + + for (i = 0; i < ARRAY_SIZE(result); i++) { + result_ptr = &result[result_index]; + + if (result_ptr->done_1 == 1 && + result_ptr->done_2 == 1) { + wl1251_tx_packet_cb(wl, result_ptr); + + result_ptr->done_1 = 0; + result_ptr->done_2 = 0; + + result_index = (result_index + 1) & + (FW_TX_CMPLT_BLOCK_SIZE - 1); + num_complete++; + } else { + break; + } + } + + if (wl->tx_queue_stopped + && + skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){ + + /* firmware buffer has space, restart queues */ + wl1251_debug(DEBUG_TX, "tx_complete: waking queues"); + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + wl->tx_queue_stopped = false; + spin_unlock_irqrestore(&wl->wl_lock, flags); + ieee80211_queue_work(wl->hw, &wl->tx_work); + + } + + /* Every completed frame needs to be acknowledged */ + if (num_complete) { + /* + * If we've wrapped, we have to clear + * the results in 2 steps. + */ + if (result_index > wl->next_tx_complete) { + /* Only 1 write is needed */ + wl1251_mem_write(wl, + wl->data_path->tx_complete_addr + + (wl->next_tx_complete * + sizeof(struct tx_result)), + &result[wl->next_tx_complete], + num_complete * + sizeof(struct tx_result)); + + + } else if (result_index < wl->next_tx_complete) { + /* 2 writes are needed */ + wl1251_mem_write(wl, + wl->data_path->tx_complete_addr + + (wl->next_tx_complete * + sizeof(struct tx_result)), + &result[wl->next_tx_complete], + (FW_TX_CMPLT_BLOCK_SIZE - + wl->next_tx_complete) * + sizeof(struct tx_result)); + + wl1251_mem_write(wl, + wl->data_path->tx_complete_addr, + result, + (num_complete - + FW_TX_CMPLT_BLOCK_SIZE + + wl->next_tx_complete) * + sizeof(struct tx_result)); + + } else { + /* We have to write the whole array */ + wl1251_mem_write(wl, + wl->data_path->tx_complete_addr, + result, + FW_TX_CMPLT_BLOCK_SIZE * + sizeof(struct tx_result)); + } + + } + + wl->next_tx_complete = result_index; +} + +/* caller must hold wl->mutex */ +void wl1251_tx_flush(struct wl1251 *wl) +{ + int i; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + + /* TX failure */ +/* control->flags = 0; FIXME */ + + while ((skb = skb_dequeue(&wl->tx_queue))) { + info = IEEE80211_SKB_CB(skb); + + wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb); + + if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) + continue; + + ieee80211_tx_status(wl->hw, skb); + } + + for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) + if (wl->tx_frames[i] != NULL) { + skb = wl->tx_frames[i]; + info = IEEE80211_SKB_CB(skb); + + if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) + continue; + + ieee80211_tx_status(wl->hw, skb); + wl->tx_frames[i] = NULL; + } +} diff --git a/drivers/net/wireless/wl1251/tx.h b/drivers/net/wireless/wl1251/tx.h new file mode 100644 index 000000000000..81338d39b43e --- /dev/null +++ b/drivers/net/wireless/wl1251/tx.h @@ -0,0 +1,231 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_TX_H__ +#define __WL1251_TX_H__ + +#include +#include "acx.h" + +/* + * + * TX PATH + * + * The Tx path uses a double buffer and a tx_control structure, each located + * at a fixed address in the device's memory. On startup, the host retrieves + * the pointers to these addresses. A double buffer allows for continuous data + * flow towards the device. The host keeps track of which buffer is available + * and alternates between these two buffers on a per packet basis. + * + * The size of each of the two buffers is large enough to hold the longest + * 802.3 packet - maximum size Ethernet packet + header + descriptor. + * TX complete indication will be received a-synchronously in a TX done cyclic + * buffer which is composed of 16 tx_result descriptors structures and is used + * in a cyclic manner. + * + * The TX (HOST) procedure is as follows: + * 1. Read the Tx path status, that will give the data_out_count. + * 2. goto 1, if not possible. + * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double + * buffer). + * 3. Copy the packet (preceded by double_buffer_desc), if possible. + * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double + * buffer). + * 4. increment data_in_count. + * 5. Inform the firmware by generating a firmware internal interrupt. + * 6. FW will increment data_out_count after it reads the buffer. + * + * The TX Complete procedure: + * 1. To get a TX complete indication the host enables the tx_complete flag in + * the TX descriptor Structure. + * 2. For each packet with a Tx Complete field set, the firmware adds the + * transmit results to the cyclic buffer (txDoneRing) and sets both done_1 + * and done_2 to 1 to indicate driver ownership. + * 3. The firmware sends a Tx Complete interrupt to the host to trigger the + * host to process the new data. Note: interrupt will be send per packet if + * TX complete indication was requested in tx_control or per crossing + * aggregation threshold. + * 4. After receiving the Tx Complete interrupt, the host reads the + * TxDescriptorDone information in a cyclic manner and clears both done_1 + * and done_2 fields. + * + */ + +#define TX_COMPLETE_REQUIRED_BIT 0x80 +#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf + +#define WL1251_TX_ALIGN_TO 4 +#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \ + ~(WL1251_TX_ALIGN_TO - 1)) +#define WL1251_TKIP_IV_SPACE 4 + +struct tx_control { + /* Rate Policy (class) index */ + unsigned rate_policy:3; + + /* When set, no ack policy is expected */ + unsigned ack_policy:1; + + /* + * Packet type: + * 0 -> 802.11 + * 1 -> 802.3 + * 2 -> IP + * 3 -> raw codec + */ + unsigned packet_type:2; + + /* If set, this is a QoS-Null or QoS-Data frame */ + unsigned qos:1; + + /* + * If set, the target triggers the tx complete INT + * upon frame sending completion. + */ + unsigned tx_complete:1; + + /* 2 bytes padding before packet header */ + unsigned xfer_pad:1; + + unsigned reserved:7; +} __packed; + + +struct tx_double_buffer_desc { + /* Length of payload, including headers. */ + __le16 length; + + /* + * A bit mask that specifies the initial rate to be used + * Possible values are: + * 0x0001 - 1Mbits + * 0x0002 - 2Mbits + * 0x0004 - 5.5Mbits + * 0x0008 - 6Mbits + * 0x0010 - 9Mbits + * 0x0020 - 11Mbits + * 0x0040 - 12Mbits + * 0x0080 - 18Mbits + * 0x0100 - 22Mbits + * 0x0200 - 24Mbits + * 0x0400 - 36Mbits + * 0x0800 - 48Mbits + * 0x1000 - 54Mbits + */ + __le16 rate; + + /* Time in us that a packet can spend in the target */ + __le32 expiry_time; + + /* index of the TX queue used for this packet */ + u8 xmit_queue; + + /* Used to identify a packet */ + u8 id; + + struct tx_control control; + + /* + * The FW should cut the packet into fragments + * of this size. + */ + __le16 frag_threshold; + + /* Numbers of HW queue blocks to be allocated */ + u8 num_mem_blocks; + + u8 reserved; +} __packed; + +enum { + TX_SUCCESS = 0, + TX_DMA_ERROR = BIT(7), + TX_DISABLED = BIT(6), + TX_RETRY_EXCEEDED = BIT(5), + TX_TIMEOUT = BIT(4), + TX_KEY_NOT_FOUND = BIT(3), + TX_ENCRYPT_FAIL = BIT(2), + TX_UNAVAILABLE_PRIORITY = BIT(1), +}; + +struct tx_result { + /* + * Ownership synchronization between the host and + * the firmware. If done_1 and done_2 are cleared, + * owned by the FW (no info ready). + */ + u8 done_1; + + /* same as double_buffer_desc->id */ + u8 id; + + /* + * Total air access duration consumed by this + * packet, including all retries and overheads. + */ + u16 medium_usage; + + /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */ + u32 medium_delay; + + /* Time between host xfer and tx complete */ + u32 fw_hnadling_time; + + /* The LS-byte of the last TKIP sequence number. */ + u8 lsb_seq_num; + + /* Retry count */ + u8 ack_failures; + + /* At which rate we got a ACK */ + u16 rate; + + u16 reserved; + + /* TX_* */ + u8 status; + + /* See done_1 */ + u8 done_2; +} __packed; + +static inline int wl1251_tx_get_queue(int queue) +{ + switch (queue) { + case 0: + return QOS_AC_VO; + case 1: + return QOS_AC_VI; + case 2: + return QOS_AC_BE; + case 3: + return QOS_AC_BK; + default: + return QOS_AC_BE; + } +} + +void wl1251_tx_work(struct work_struct *work); +void wl1251_tx_complete(struct wl1251 *wl); +void wl1251_tx_flush(struct wl1251 *wl); + +#endif diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h new file mode 100644 index 000000000000..e113d4c1fb35 --- /dev/null +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -0,0 +1,433 @@ +/* + * This file is part of wl1251 + * + * Copyright (c) 1998-2007 Texas Instruments Incorporated + * Copyright (C) 2008-2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1251_H__ +#define __WL1251_H__ + +#include +#include +#include +#include + +#define DRIVER_NAME "wl1251" +#define DRIVER_PREFIX DRIVER_NAME ": " + +enum { + DEBUG_NONE = 0, + DEBUG_IRQ = BIT(0), + DEBUG_SPI = BIT(1), + DEBUG_BOOT = BIT(2), + DEBUG_MAILBOX = BIT(3), + DEBUG_NETLINK = BIT(4), + DEBUG_EVENT = BIT(5), + DEBUG_TX = BIT(6), + DEBUG_RX = BIT(7), + DEBUG_SCAN = BIT(8), + DEBUG_CRYPT = BIT(9), + DEBUG_PSM = BIT(10), + DEBUG_MAC80211 = BIT(11), + DEBUG_CMD = BIT(12), + DEBUG_ACX = BIT(13), + DEBUG_ALL = ~0, +}; + +#define DEBUG_LEVEL (DEBUG_NONE) + +#define DEBUG_DUMP_LIMIT 1024 + +#define wl1251_error(fmt, arg...) \ + printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) + +#define wl1251_warning(fmt, arg...) \ + printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) + +#define wl1251_notice(fmt, arg...) \ + printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) + +#define wl1251_info(fmt, arg...) \ + printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) + +#define wl1251_debug(level, fmt, arg...) \ + do { \ + if (level & DEBUG_LEVEL) \ + printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ + } while (0) + +#define wl1251_dump(level, prefix, buf, len) \ + do { \ + if (level & DEBUG_LEVEL) \ + print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ + DUMP_PREFIX_OFFSET, 16, 1, \ + buf, \ + min_t(size_t, len, DEBUG_DUMP_LIMIT), \ + 0); \ + } while (0) + +#define wl1251_dump_ascii(level, prefix, buf, len) \ + do { \ + if (level & DEBUG_LEVEL) \ + print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ + DUMP_PREFIX_OFFSET, 16, 1, \ + buf, \ + min_t(size_t, len, DEBUG_DUMP_LIMIT), \ + true); \ + } while (0) + +#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ + CFG_BSSID_FILTER_EN) + +#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ + CFG_RX_MGMT_EN | \ + CFG_RX_DATA_EN | \ + CFG_RX_CTL_EN | \ + CFG_RX_BCN_EN | \ + CFG_RX_AUTH_EN | \ + CFG_RX_ASSOC_EN) + +#define WL1251_BUSY_WORD_LEN 8 + +struct boot_attr { + u32 radio_type; + u8 mac_clock; + u8 arm_clock; + int firmware_debug; + u32 minor; + u32 major; + u32 bugfix; +}; + +enum wl1251_state { + WL1251_STATE_OFF, + WL1251_STATE_ON, + WL1251_STATE_PLT, +}; + +enum wl1251_partition_type { + PART_DOWN, + PART_WORK, + PART_DRPW, + + PART_TABLE_LEN +}; + +struct wl1251_partition { + u32 size; + u32 start; +}; + +struct wl1251_partition_set { + struct wl1251_partition mem; + struct wl1251_partition reg; +}; + +struct wl1251; + +struct wl1251_stats { + struct acx_statistics *fw_stats; + unsigned long fw_stats_update; + + unsigned int retry_count; + unsigned int excessive_retries; +}; + +struct wl1251_debugfs { + struct dentry *rootdir; + struct dentry *fw_statistics; + + struct dentry *tx_internal_desc_overflow; + + struct dentry *rx_out_of_mem; + struct dentry *rx_hdr_overflow; + struct dentry *rx_hw_stuck; + struct dentry *rx_dropped; + struct dentry *rx_fcs_err; + struct dentry *rx_xfr_hint_trig; + struct dentry *rx_path_reset; + struct dentry *rx_reset_counter; + + struct dentry *dma_rx_requested; + struct dentry *dma_rx_errors; + struct dentry *dma_tx_requested; + struct dentry *dma_tx_errors; + + struct dentry *isr_cmd_cmplt; + struct dentry *isr_fiqs; + struct dentry *isr_rx_headers; + struct dentry *isr_rx_mem_overflow; + struct dentry *isr_rx_rdys; + struct dentry *isr_irqs; + struct dentry *isr_tx_procs; + struct dentry *isr_decrypt_done; + struct dentry *isr_dma0_done; + struct dentry *isr_dma1_done; + struct dentry *isr_tx_exch_complete; + struct dentry *isr_commands; + struct dentry *isr_rx_procs; + struct dentry *isr_hw_pm_mode_changes; + struct dentry *isr_host_acknowledges; + struct dentry *isr_pci_pm; + struct dentry *isr_wakeups; + struct dentry *isr_low_rssi; + + struct dentry *wep_addr_key_count; + struct dentry *wep_default_key_count; + /* skipping wep.reserved */ + struct dentry *wep_key_not_found; + struct dentry *wep_decrypt_fail; + struct dentry *wep_packets; + struct dentry *wep_interrupt; + + struct dentry *pwr_ps_enter; + struct dentry *pwr_elp_enter; + struct dentry *pwr_missing_bcns; + struct dentry *pwr_wake_on_host; + struct dentry *pwr_wake_on_timer_exp; + struct dentry *pwr_tx_with_ps; + struct dentry *pwr_tx_without_ps; + struct dentry *pwr_rcvd_beacons; + struct dentry *pwr_power_save_off; + struct dentry *pwr_enable_ps; + struct dentry *pwr_disable_ps; + struct dentry *pwr_fix_tsf_ps; + /* skipping cont_miss_bcns_spread for now */ + struct dentry *pwr_rcvd_awake_beacons; + + struct dentry *mic_rx_pkts; + struct dentry *mic_calc_failure; + + struct dentry *aes_encrypt_fail; + struct dentry *aes_decrypt_fail; + struct dentry *aes_encrypt_packets; + struct dentry *aes_decrypt_packets; + struct dentry *aes_encrypt_interrupt; + struct dentry *aes_decrypt_interrupt; + + struct dentry *event_heart_beat; + struct dentry *event_calibration; + struct dentry *event_rx_mismatch; + struct dentry *event_rx_mem_empty; + struct dentry *event_rx_pool; + struct dentry *event_oom_late; + struct dentry *event_phy_transmit_error; + struct dentry *event_tx_stuck; + + struct dentry *ps_pspoll_timeouts; + struct dentry *ps_upsd_timeouts; + struct dentry *ps_upsd_max_sptime; + struct dentry *ps_upsd_max_apturn; + struct dentry *ps_pspoll_max_apturn; + struct dentry *ps_pspoll_utilization; + struct dentry *ps_upsd_utilization; + + struct dentry *rxpipe_rx_prep_beacon_drop; + struct dentry *rxpipe_descr_host_int_trig_rx_data; + struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data; + struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data; + struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; + + struct dentry *tx_queue_len; + struct dentry *tx_queue_status; + + struct dentry *retry_count; + struct dentry *excessive_retries; +}; + +struct wl1251_if_operations { + void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); + void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); + void (*read_elp)(struct wl1251 *wl, int addr, u32 *val); + void (*write_elp)(struct wl1251 *wl, int addr, u32 val); + void (*reset)(struct wl1251 *wl); + void (*enable_irq)(struct wl1251 *wl); + void (*disable_irq)(struct wl1251 *wl); +}; + +struct wl1251 { + struct ieee80211_hw *hw; + bool mac80211_registered; + + void *if_priv; + const struct wl1251_if_operations *if_ops; + + void (*set_power)(bool enable); + int irq; + bool use_eeprom; + + spinlock_t wl_lock; + + enum wl1251_state state; + struct mutex mutex; + + int physical_mem_addr; + int physical_reg_addr; + int virtual_mem_addr; + int virtual_reg_addr; + + int cmd_box_addr; + int event_box_addr; + struct boot_attr boot_attr; + + u8 *fw; + size_t fw_len; + u8 *nvs; + size_t nvs_len; + + u8 bssid[ETH_ALEN]; + u8 mac_addr[ETH_ALEN]; + u8 bss_type; + u8 listen_int; + int channel; + + void *target_mem_map; + struct acx_data_path_params_resp *data_path; + + /* Number of TX packets transferred to the FW, modulo 16 */ + u32 data_in_count; + + /* Frames scheduled for transmission, not handled yet */ + struct sk_buff_head tx_queue; + bool tx_queue_stopped; + + struct work_struct tx_work; + struct work_struct filter_work; + + /* Pending TX frames */ + struct sk_buff *tx_frames[16]; + + /* + * Index pointing to the next TX complete entry + * in the cyclic XT complete array we get from + * the FW. + */ + u32 next_tx_complete; + + /* FW Rx counter */ + u32 rx_counter; + + /* Rx frames handled */ + u32 rx_handled; + + /* Current double buffer */ + u32 rx_current_buffer; + u32 rx_last_id; + + /* The target interrupt mask */ + u32 intr_mask; + struct work_struct irq_work; + + /* The mbox event mask */ + u32 event_mask; + + /* Mailbox pointers */ + u32 mbox_ptr[2]; + + /* Are we currently scanning */ + bool scanning; + + /* Default key (for WEP) */ + u32 default_key; + + unsigned int tx_mgmt_frm_rate; + unsigned int tx_mgmt_frm_mod; + + unsigned int rx_config; + unsigned int rx_filter; + + /* is firmware in elp mode */ + bool elp; + + struct delayed_work elp_work; + + /* we can be in psm, but not in elp, we have to differentiate */ + bool psm; + + /* PSM mode requested */ + bool psm_requested; + + u16 beacon_int; + u8 dtim_period; + + /* in dBm */ + int power_level; + + struct wl1251_stats stats; + struct wl1251_debugfs debugfs; + + u32 buffer_32; + u32 buffer_cmd; + u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; + struct wl1251_rx_descriptor *rx_descriptor; + + struct ieee80211_vif *vif; + + u32 chip_id; + char fw_ver[21]; + + /* Most recently reported noise in dBm */ + s8 noise; +}; + +int wl1251_plt_start(struct wl1251 *wl); +int wl1251_plt_stop(struct wl1251 *wl); + +struct ieee80211_hw *wl1251_alloc_hw(void); +int wl1251_free_hw(struct wl1251 *wl); +int wl1251_init_ieee80211(struct wl1251 *wl); +void wl1251_enable_interrupts(struct wl1251 *wl); +void wl1251_disable_interrupts(struct wl1251 *wl); + +#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */ +#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS +#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ + +#define WL1251_DEFAULT_POWER_LEVEL 20 + +#define WL1251_TX_QUEUE_LOW_WATERMARK 10 +#define WL1251_TX_QUEUE_HIGH_WATERMARK 25 + +#define WL1251_DEFAULT_BEACON_INT 100 +#define WL1251_DEFAULT_DTIM_PERIOD 1 + +#define WL1251_DEFAULT_CHANNEL 0 + +#define CHIP_ID_1251_PG10 (0x7010101) +#define CHIP_ID_1251_PG11 (0x7020101) +#define CHIP_ID_1251_PG12 (0x7030101) +#define CHIP_ID_1271_PG10 (0x4030101) +#define CHIP_ID_1271_PG20 (0x4030111) + +#define WL1251_FW_NAME "wl1251-fw.bin" +#define WL1251_NVS_NAME "wl1251-nvs.bin" + +#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */ + +#define WL1251_PART_DOWN_MEM_START 0x0 +#define WL1251_PART_DOWN_MEM_SIZE 0x16800 +#define WL1251_PART_DOWN_REG_START REGISTERS_BASE +#define WL1251_PART_DOWN_REG_SIZE REGISTERS_DOWN_SIZE + +#define WL1251_PART_WORK_MEM_START 0x28000 +#define WL1251_PART_WORK_MEM_SIZE 0x14000 +#define WL1251_PART_WORK_REG_START REGISTERS_BASE +#define WL1251_PART_WORK_REG_SIZE REGISTERS_WORK_SIZE + +#endif diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 4a8bb25c1739..b447559f1db5 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -5,40 +5,6 @@ menuconfig WL12XX This will enable TI wl12xx driver support. The drivers make use of the mac80211 stack. -config WL1251 - tristate "TI wl1251 support" - depends on WL12XX && GENERIC_HARDIRQS - select FW_LOADER - select CRC7 - ---help--- - This module adds support for wireless adapters based on - TI wl1251 chipset. - - If you choose to build a module, it'll be called wl1251. Say - N if unsure. - -config WL1251_SPI - tristate "TI wl1251 SPI support" - depends on WL1251 && SPI_MASTER - ---help--- - This module adds support for the SPI interface of adapters using - TI wl1251 chipset. Select this if your platform is using - the SPI bus. - - If you choose to build a module, it'll be called wl1251_spi. - Say N if unsure. - -config WL1251_SDIO - tristate "TI wl1251 SDIO support" - depends on WL1251 && MMC - ---help--- - This module adds support for the SDIO interface of adapters using - TI wl1251 chipset. Select this if your platform is using - the SDIO bus. - - If you choose to build a module, it'll be called - wl1251_sdio. Say N if unsure. - config WL1271 tristate "TI wl1271 support" depends on WL12XX && GENERIC_HARDIRQS diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 0d334d6f86f4..3a807444b2af 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -1,12 +1,3 @@ -wl1251-objs = wl1251_main.o wl1251_event.o \ - wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \ - wl1251_acx.o wl1251_boot.o wl1251_init.o \ - wl1251_debugfs.o wl1251_io.o - -obj-$(CONFIG_WL1251) += wl1251.o -obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o -obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o - wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ wl1271_event.o wl1271_tx.o wl1271_rx.o \ wl1271_ps.o wl1271_acx.o wl1271_boot.o \ diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h deleted file mode 100644 index e113d4c1fb35..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008-2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_H__ -#define __WL1251_H__ - -#include -#include -#include -#include - -#define DRIVER_NAME "wl1251" -#define DRIVER_PREFIX DRIVER_NAME ": " - -enum { - DEBUG_NONE = 0, - DEBUG_IRQ = BIT(0), - DEBUG_SPI = BIT(1), - DEBUG_BOOT = BIT(2), - DEBUG_MAILBOX = BIT(3), - DEBUG_NETLINK = BIT(4), - DEBUG_EVENT = BIT(5), - DEBUG_TX = BIT(6), - DEBUG_RX = BIT(7), - DEBUG_SCAN = BIT(8), - DEBUG_CRYPT = BIT(9), - DEBUG_PSM = BIT(10), - DEBUG_MAC80211 = BIT(11), - DEBUG_CMD = BIT(12), - DEBUG_ACX = BIT(13), - DEBUG_ALL = ~0, -}; - -#define DEBUG_LEVEL (DEBUG_NONE) - -#define DEBUG_DUMP_LIMIT 1024 - -#define wl1251_error(fmt, arg...) \ - printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) - -#define wl1251_warning(fmt, arg...) \ - printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) - -#define wl1251_notice(fmt, arg...) \ - printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1251_info(fmt, arg...) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1251_debug(level, fmt, arg...) \ - do { \ - if (level & DEBUG_LEVEL) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ - } while (0) - -#define wl1251_dump(level, prefix, buf, len) \ - do { \ - if (level & DEBUG_LEVEL) \ - print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ - DUMP_PREFIX_OFFSET, 16, 1, \ - buf, \ - min_t(size_t, len, DEBUG_DUMP_LIMIT), \ - 0); \ - } while (0) - -#define wl1251_dump_ascii(level, prefix, buf, len) \ - do { \ - if (level & DEBUG_LEVEL) \ - print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ - DUMP_PREFIX_OFFSET, 16, 1, \ - buf, \ - min_t(size_t, len, DEBUG_DUMP_LIMIT), \ - true); \ - } while (0) - -#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ - CFG_BSSID_FILTER_EN) - -#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ - CFG_RX_MGMT_EN | \ - CFG_RX_DATA_EN | \ - CFG_RX_CTL_EN | \ - CFG_RX_BCN_EN | \ - CFG_RX_AUTH_EN | \ - CFG_RX_ASSOC_EN) - -#define WL1251_BUSY_WORD_LEN 8 - -struct boot_attr { - u32 radio_type; - u8 mac_clock; - u8 arm_clock; - int firmware_debug; - u32 minor; - u32 major; - u32 bugfix; -}; - -enum wl1251_state { - WL1251_STATE_OFF, - WL1251_STATE_ON, - WL1251_STATE_PLT, -}; - -enum wl1251_partition_type { - PART_DOWN, - PART_WORK, - PART_DRPW, - - PART_TABLE_LEN -}; - -struct wl1251_partition { - u32 size; - u32 start; -}; - -struct wl1251_partition_set { - struct wl1251_partition mem; - struct wl1251_partition reg; -}; - -struct wl1251; - -struct wl1251_stats { - struct acx_statistics *fw_stats; - unsigned long fw_stats_update; - - unsigned int retry_count; - unsigned int excessive_retries; -}; - -struct wl1251_debugfs { - struct dentry *rootdir; - struct dentry *fw_statistics; - - struct dentry *tx_internal_desc_overflow; - - struct dentry *rx_out_of_mem; - struct dentry *rx_hdr_overflow; - struct dentry *rx_hw_stuck; - struct dentry *rx_dropped; - struct dentry *rx_fcs_err; - struct dentry *rx_xfr_hint_trig; - struct dentry *rx_path_reset; - struct dentry *rx_reset_counter; - - struct dentry *dma_rx_requested; - struct dentry *dma_rx_errors; - struct dentry *dma_tx_requested; - struct dentry *dma_tx_errors; - - struct dentry *isr_cmd_cmplt; - struct dentry *isr_fiqs; - struct dentry *isr_rx_headers; - struct dentry *isr_rx_mem_overflow; - struct dentry *isr_rx_rdys; - struct dentry *isr_irqs; - struct dentry *isr_tx_procs; - struct dentry *isr_decrypt_done; - struct dentry *isr_dma0_done; - struct dentry *isr_dma1_done; - struct dentry *isr_tx_exch_complete; - struct dentry *isr_commands; - struct dentry *isr_rx_procs; - struct dentry *isr_hw_pm_mode_changes; - struct dentry *isr_host_acknowledges; - struct dentry *isr_pci_pm; - struct dentry *isr_wakeups; - struct dentry *isr_low_rssi; - - struct dentry *wep_addr_key_count; - struct dentry *wep_default_key_count; - /* skipping wep.reserved */ - struct dentry *wep_key_not_found; - struct dentry *wep_decrypt_fail; - struct dentry *wep_packets; - struct dentry *wep_interrupt; - - struct dentry *pwr_ps_enter; - struct dentry *pwr_elp_enter; - struct dentry *pwr_missing_bcns; - struct dentry *pwr_wake_on_host; - struct dentry *pwr_wake_on_timer_exp; - struct dentry *pwr_tx_with_ps; - struct dentry *pwr_tx_without_ps; - struct dentry *pwr_rcvd_beacons; - struct dentry *pwr_power_save_off; - struct dentry *pwr_enable_ps; - struct dentry *pwr_disable_ps; - struct dentry *pwr_fix_tsf_ps; - /* skipping cont_miss_bcns_spread for now */ - struct dentry *pwr_rcvd_awake_beacons; - - struct dentry *mic_rx_pkts; - struct dentry *mic_calc_failure; - - struct dentry *aes_encrypt_fail; - struct dentry *aes_decrypt_fail; - struct dentry *aes_encrypt_packets; - struct dentry *aes_decrypt_packets; - struct dentry *aes_encrypt_interrupt; - struct dentry *aes_decrypt_interrupt; - - struct dentry *event_heart_beat; - struct dentry *event_calibration; - struct dentry *event_rx_mismatch; - struct dentry *event_rx_mem_empty; - struct dentry *event_rx_pool; - struct dentry *event_oom_late; - struct dentry *event_phy_transmit_error; - struct dentry *event_tx_stuck; - - struct dentry *ps_pspoll_timeouts; - struct dentry *ps_upsd_timeouts; - struct dentry *ps_upsd_max_sptime; - struct dentry *ps_upsd_max_apturn; - struct dentry *ps_pspoll_max_apturn; - struct dentry *ps_pspoll_utilization; - struct dentry *ps_upsd_utilization; - - struct dentry *rxpipe_rx_prep_beacon_drop; - struct dentry *rxpipe_descr_host_int_trig_rx_data; - struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data; - struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data; - struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data; - - struct dentry *tx_queue_len; - struct dentry *tx_queue_status; - - struct dentry *retry_count; - struct dentry *excessive_retries; -}; - -struct wl1251_if_operations { - void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); - void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); - void (*read_elp)(struct wl1251 *wl, int addr, u32 *val); - void (*write_elp)(struct wl1251 *wl, int addr, u32 val); - void (*reset)(struct wl1251 *wl); - void (*enable_irq)(struct wl1251 *wl); - void (*disable_irq)(struct wl1251 *wl); -}; - -struct wl1251 { - struct ieee80211_hw *hw; - bool mac80211_registered; - - void *if_priv; - const struct wl1251_if_operations *if_ops; - - void (*set_power)(bool enable); - int irq; - bool use_eeprom; - - spinlock_t wl_lock; - - enum wl1251_state state; - struct mutex mutex; - - int physical_mem_addr; - int physical_reg_addr; - int virtual_mem_addr; - int virtual_reg_addr; - - int cmd_box_addr; - int event_box_addr; - struct boot_attr boot_attr; - - u8 *fw; - size_t fw_len; - u8 *nvs; - size_t nvs_len; - - u8 bssid[ETH_ALEN]; - u8 mac_addr[ETH_ALEN]; - u8 bss_type; - u8 listen_int; - int channel; - - void *target_mem_map; - struct acx_data_path_params_resp *data_path; - - /* Number of TX packets transferred to the FW, modulo 16 */ - u32 data_in_count; - - /* Frames scheduled for transmission, not handled yet */ - struct sk_buff_head tx_queue; - bool tx_queue_stopped; - - struct work_struct tx_work; - struct work_struct filter_work; - - /* Pending TX frames */ - struct sk_buff *tx_frames[16]; - - /* - * Index pointing to the next TX complete entry - * in the cyclic XT complete array we get from - * the FW. - */ - u32 next_tx_complete; - - /* FW Rx counter */ - u32 rx_counter; - - /* Rx frames handled */ - u32 rx_handled; - - /* Current double buffer */ - u32 rx_current_buffer; - u32 rx_last_id; - - /* The target interrupt mask */ - u32 intr_mask; - struct work_struct irq_work; - - /* The mbox event mask */ - u32 event_mask; - - /* Mailbox pointers */ - u32 mbox_ptr[2]; - - /* Are we currently scanning */ - bool scanning; - - /* Default key (for WEP) */ - u32 default_key; - - unsigned int tx_mgmt_frm_rate; - unsigned int tx_mgmt_frm_mod; - - unsigned int rx_config; - unsigned int rx_filter; - - /* is firmware in elp mode */ - bool elp; - - struct delayed_work elp_work; - - /* we can be in psm, but not in elp, we have to differentiate */ - bool psm; - - /* PSM mode requested */ - bool psm_requested; - - u16 beacon_int; - u8 dtim_period; - - /* in dBm */ - int power_level; - - struct wl1251_stats stats; - struct wl1251_debugfs debugfs; - - u32 buffer_32; - u32 buffer_cmd; - u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; - struct wl1251_rx_descriptor *rx_descriptor; - - struct ieee80211_vif *vif; - - u32 chip_id; - char fw_ver[21]; - - /* Most recently reported noise in dBm */ - s8 noise; -}; - -int wl1251_plt_start(struct wl1251 *wl); -int wl1251_plt_stop(struct wl1251 *wl); - -struct ieee80211_hw *wl1251_alloc_hw(void); -int wl1251_free_hw(struct wl1251 *wl); -int wl1251_init_ieee80211(struct wl1251 *wl); -void wl1251_enable_interrupts(struct wl1251 *wl); -void wl1251_disable_interrupts(struct wl1251 *wl); - -#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */ -#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS -#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ - -#define WL1251_DEFAULT_POWER_LEVEL 20 - -#define WL1251_TX_QUEUE_LOW_WATERMARK 10 -#define WL1251_TX_QUEUE_HIGH_WATERMARK 25 - -#define WL1251_DEFAULT_BEACON_INT 100 -#define WL1251_DEFAULT_DTIM_PERIOD 1 - -#define WL1251_DEFAULT_CHANNEL 0 - -#define CHIP_ID_1251_PG10 (0x7010101) -#define CHIP_ID_1251_PG11 (0x7020101) -#define CHIP_ID_1251_PG12 (0x7030101) -#define CHIP_ID_1271_PG10 (0x4030101) -#define CHIP_ID_1271_PG20 (0x4030111) - -#define WL1251_FW_NAME "wl1251-fw.bin" -#define WL1251_NVS_NAME "wl1251-nvs.bin" - -#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */ - -#define WL1251_PART_DOWN_MEM_START 0x0 -#define WL1251_PART_DOWN_MEM_SIZE 0x16800 -#define WL1251_PART_DOWN_REG_START REGISTERS_BASE -#define WL1251_PART_DOWN_REG_SIZE REGISTERS_DOWN_SIZE - -#define WL1251_PART_WORK_MEM_START 0x28000 -#define WL1251_PART_WORK_MEM_SIZE 0x14000 -#define WL1251_PART_WORK_REG_START REGISTERS_BASE -#define WL1251_PART_WORK_REG_SIZE REGISTERS_WORK_SIZE - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c deleted file mode 100644 index 2f8a2ba744dc..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ /dev/null @@ -1,1048 +0,0 @@ -#include "wl1251_acx.h" - -#include -#include -#include - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_cmd.h" -#include "wl1251_ps.h" - -int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, - u8 mgt_rate, u8 mgt_mod) -{ - struct acx_fw_gen_frame_rates *rates; - int ret; - - wl1251_debug(DEBUG_ACX, "acx frame rates"); - - rates = kzalloc(sizeof(*rates), GFP_KERNEL); - if (!rates) { - ret = -ENOMEM; - goto out; - } - - rates->tx_ctrl_frame_rate = ctrl_rate; - rates->tx_ctrl_frame_mod = ctrl_mod; - rates->tx_mgt_frame_rate = mgt_rate; - rates->tx_mgt_frame_mod = mgt_mod; - - ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES, - rates, sizeof(*rates)); - if (ret < 0) { - wl1251_error("Failed to set FW rates and modulation"); - goto out; - } - -out: - kfree(rates); - return ret; -} - - -int wl1251_acx_station_id(struct wl1251 *wl) -{ - struct acx_dot11_station_id *mac; - int ret, i; - - wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); - - mac = kzalloc(sizeof(*mac), GFP_KERNEL); - if (!mac) { - ret = -ENOMEM; - goto out; - } - - for (i = 0; i < ETH_ALEN; i++) - mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; - - ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac)); - if (ret < 0) - goto out; - -out: - kfree(mac); - return ret; -} - -int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id) -{ - struct acx_dot11_default_key *default_key; - int ret; - - wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); - - default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); - if (!default_key) { - ret = -ENOMEM; - goto out; - } - - default_key->id = key_id; - - ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY, - default_key, sizeof(*default_key)); - if (ret < 0) { - wl1251_error("Couldn't set default key"); - goto out; - } - - wl->default_key = key_id; - -out: - kfree(default_key); - return ret; -} - -int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, - u8 listen_interval) -{ - struct acx_wake_up_condition *wake_up; - int ret; - - wl1251_debug(DEBUG_ACX, "acx wake up conditions"); - - wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); - if (!wake_up) { - ret = -ENOMEM; - goto out; - } - - wake_up->wake_up_event = wake_up_event; - wake_up->listen_interval = listen_interval; - - ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, - wake_up, sizeof(*wake_up)); - if (ret < 0) { - wl1251_warning("could not set wake up conditions: %d", ret); - goto out; - } - -out: - kfree(wake_up); - return ret; -} - -int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth) -{ - struct acx_sleep_auth *auth; - int ret; - - wl1251_debug(DEBUG_ACX, "acx sleep auth"); - - auth = kzalloc(sizeof(*auth), GFP_KERNEL); - if (!auth) { - ret = -ENOMEM; - goto out; - } - - auth->sleep_auth = sleep_auth; - - ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) - return ret; - -out: - kfree(auth); - return ret; -} - -int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len) -{ - struct acx_revision *rev; - int ret; - - wl1251_debug(DEBUG_ACX, "acx fw rev"); - - rev = kzalloc(sizeof(*rev), GFP_KERNEL); - if (!rev) { - ret = -ENOMEM; - goto out; - } - - ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); - if (ret < 0) { - wl1251_warning("ACX_FW_REV interrogate failed"); - goto out; - } - - /* be careful with the buffer sizes */ - strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); - - /* - * if the firmware version string is exactly - * sizeof(rev->fw_version) long or fw_len is less than - * sizeof(rev->fw_version) it won't be null terminated - */ - buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; - -out: - kfree(rev); - return ret; -} - -int wl1251_acx_tx_power(struct wl1251 *wl, int power) -{ - struct acx_current_tx_power *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); - - if (power < 0 || power > 25) - return -EINVAL; - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->current_tx_power = power * 10; - - ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("configure of tx power failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_feature_cfg(struct wl1251 *wl) -{ - struct acx_feature_config *feature; - int ret; - - wl1251_debug(DEBUG_ACX, "acx feature cfg"); - - feature = kzalloc(sizeof(*feature), GFP_KERNEL); - if (!feature) { - ret = -ENOMEM; - goto out; - } - - /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ - feature->data_flow_options = 0; - feature->options = 0; - - ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, - feature, sizeof(*feature)); - if (ret < 0) { - wl1251_error("Couldn't set HW encryption"); - goto out; - } - -out: - kfree(feature); - return ret; -} - -int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map, - size_t len) -{ - int ret; - - wl1251_debug(DEBUG_ACX, "acx mem map"); - - ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_acx_data_path_params(struct wl1251 *wl, - struct acx_data_path_params_resp *resp) -{ - struct acx_data_path_params *params; - int ret; - - wl1251_debug(DEBUG_ACX, "acx data path params"); - - params = kzalloc(sizeof(*params), GFP_KERNEL); - if (!params) { - ret = -ENOMEM; - goto out; - } - - params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; - params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; - - params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM; - params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM; - - params->tx_complete_threshold = 1; - - params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE; - - params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT; - - ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS, - params, sizeof(*params)); - if (ret < 0) - goto out; - - /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */ - ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS, - resp, sizeof(*resp)); - - if (ret < 0) { - wl1251_warning("failed to read data path parameters: %d", ret); - goto out; - } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) { - wl1251_warning("data path parameter acx status failed"); - ret = -EIO; - goto out; - } - -out: - kfree(params); - return ret; -} - -int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time) -{ - struct acx_rx_msdu_lifetime *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->lifetime = life_time; - ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, - acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("failed to set rx msdu life time: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter) -{ - struct acx_rx_config *rx_config; - int ret; - - wl1251_debug(DEBUG_ACX, "acx rx config"); - - rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); - if (!rx_config) { - ret = -ENOMEM; - goto out; - } - - rx_config->config_options = config; - rx_config->filter_options = filter; - - ret = wl1251_cmd_configure(wl, ACX_RX_CFG, - rx_config, sizeof(*rx_config)); - if (ret < 0) { - wl1251_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(rx_config); - return ret; -} - -int wl1251_acx_pd_threshold(struct wl1251 *wl) -{ - struct acx_packet_detection *pd; - int ret; - - wl1251_debug(DEBUG_ACX, "acx data pd threshold"); - - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) { - ret = -ENOMEM; - goto out; - } - - /* FIXME: threshold value not set */ - - ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); - if (ret < 0) { - wl1251_warning("failed to set pd threshold: %d", ret); - goto out; - } - -out: - kfree(pd); - return ret; -} - -int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time) -{ - struct acx_slot *slot; - int ret; - - wl1251_debug(DEBUG_ACX, "acx slot"); - - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) { - ret = -ENOMEM; - goto out; - } - - slot->wone_index = STATION_WONE_INDEX; - slot->slot_time = slot_time; - - ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); - if (ret < 0) { - wl1251_warning("failed to set slot time: %d", ret); - goto out; - } - -out: - kfree(slot); - return ret; -} - -int wl1251_acx_group_address_tbl(struct wl1251 *wl) -{ - struct acx_dot11_grp_addr_tbl *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx group address tbl"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* MAC filtering */ - acx->enabled = 0; - acx->num_groups = 0; - memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN); - - ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, - acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("failed to set group addr table: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_service_period_timeout(struct wl1251 *wl) -{ - struct acx_rx_timeout *rx_timeout; - int ret; - - rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); - if (!rx_timeout) { - ret = -ENOMEM; - goto out; - } - - wl1251_debug(DEBUG_ACX, "acx service period timeout"); - - rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF; - rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF; - - ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, - rx_timeout, sizeof(*rx_timeout)); - if (ret < 0) { - wl1251_warning("failed to set service period timeout: %d", - ret); - goto out; - } - -out: - kfree(rx_timeout); - return ret; -} - -int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold) -{ - struct acx_rts_threshold *rts; - int ret; - - wl1251_debug(DEBUG_ACX, "acx rts threshold"); - - rts = kzalloc(sizeof(*rts), GFP_KERNEL); - if (!rts) { - ret = -ENOMEM; - goto out; - } - - rts->threshold = rts_threshold; - - ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); - if (ret < 0) { - wl1251_warning("failed to set rts threshold: %d", ret); - goto out; - } - -out: - kfree(rts); - return ret; -} - -int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter) -{ - struct acx_beacon_filter_option *beacon_filter; - int ret; - - wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); - - beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); - if (!beacon_filter) { - ret = -ENOMEM; - goto out; - } - - beacon_filter->enable = enable_filter; - beacon_filter->max_num_beacons = 0; - - ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, - beacon_filter, sizeof(*beacon_filter)); - if (ret < 0) { - wl1251_warning("failed to set beacon filter opt: %d", ret); - goto out; - } - -out: - kfree(beacon_filter); - return ret; -} - -int wl1251_acx_beacon_filter_table(struct wl1251 *wl) -{ - struct acx_beacon_filter_ie_table *ie_table; - int idx = 0; - int ret; - - wl1251_debug(DEBUG_ACX, "acx beacon filter table"); - - ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); - if (!ie_table) { - ret = -ENOMEM; - goto out; - } - - /* configure default beacon pass-through rules */ - ie_table->num_ie = 1; - ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN; - ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE; - - ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, - ie_table, sizeof(*ie_table)); - if (ret < 0) { - wl1251_warning("failed to set beacon filter table: %d", ret); - goto out; - } - -out: - kfree(ie_table); - return ret; -} - -int wl1251_acx_conn_monit_params(struct wl1251 *wl) -{ - struct acx_conn_monit_params *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; - acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; - - ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, - acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("failed to set connection monitor " - "parameters: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_sg_enable(struct wl1251 *wl) -{ - struct acx_bt_wlan_coex *pta; - int ret; - - wl1251_debug(DEBUG_ACX, "acx sg enable"); - - pta = kzalloc(sizeof(*pta), GFP_KERNEL); - if (!pta) { - ret = -ENOMEM; - goto out; - } - - pta->enable = SG_ENABLE; - - ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); - if (ret < 0) { - wl1251_warning("failed to set softgemini enable: %d", ret); - goto out; - } - -out: - kfree(pta); - return ret; -} - -int wl1251_acx_sg_cfg(struct wl1251 *wl) -{ - struct acx_bt_wlan_coex_param *param; - int ret; - - wl1251_debug(DEBUG_ACX, "acx sg cfg"); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (!param) { - ret = -ENOMEM; - goto out; - } - - /* BT-WLAN coext parameters */ - param->min_rate = RATE_INDEX_24MBPS; - param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF; - param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF; - param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF; - param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF; - param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF; - param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF; - param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF; - param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF; - param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF; - param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF; - param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF; - param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF; - param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF; - param->antenna_type = PTA_ANTENNA_TYPE_DEF; - param->signal_type = PTA_SIGNALING_TYPE_DEF; - param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF; - param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF; - param->max_cts = PTA_MAX_NUM_CTS_DEF; - param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF; - param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF; - param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF; - param->wlan_elp_hp = PTA_ELP_HP_DEF; - param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF; - param->ack_mode_dual_ant = PTA_ACK_MODE_DEF; - param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF; - param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF; - param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF; - - ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); - if (ret < 0) { - wl1251_warning("failed to set sg config: %d", ret); - goto out; - } - -out: - kfree(param); - return ret; -} - -int wl1251_acx_cca_threshold(struct wl1251 *wl) -{ - struct acx_energy_detection *detection; - int ret; - - wl1251_debug(DEBUG_ACX, "acx cca threshold"); - - detection = kzalloc(sizeof(*detection), GFP_KERNEL); - if (!detection) { - ret = -ENOMEM; - goto out; - } - - detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; - detection->tx_energy_detection = 0; - - ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD, - detection, sizeof(*detection)); - if (ret < 0) { - wl1251_warning("failed to set cca threshold: %d", ret); - return ret; - } - -out: - kfree(detection); - return ret; -} - -int wl1251_acx_bcn_dtim_options(struct wl1251 *wl) -{ - struct acx_beacon_broadcast *bb; - int ret; - - wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); - - bb = kzalloc(sizeof(*bb), GFP_KERNEL); - if (!bb) { - ret = -ENOMEM; - goto out; - } - - bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; - bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; - bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE; - bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF; - - ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); - if (ret < 0) { - wl1251_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(bb); - return ret; -} - -int wl1251_acx_aid(struct wl1251 *wl, u16 aid) -{ - struct acx_aid *acx_aid; - int ret; - - wl1251_debug(DEBUG_ACX, "acx aid"); - - acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); - if (!acx_aid) { - ret = -ENOMEM; - goto out; - } - - acx_aid->aid = aid; - - ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); - if (ret < 0) { - wl1251_warning("failed to set aid: %d", ret); - goto out; - } - -out: - kfree(acx_aid); - return ret; -} - -int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask) -{ - struct acx_event_mask *mask; - int ret; - - wl1251_debug(DEBUG_ACX, "acx event mbox mask"); - - mask = kzalloc(sizeof(*mask), GFP_KERNEL); - if (!mask) { - ret = -ENOMEM; - goto out; - } - - /* high event mask is unused */ - mask->high_event_mask = 0xffffffff; - - mask->event_mask = event_mask; - - ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK, - mask, sizeof(*mask)); - if (ret < 0) { - wl1251_warning("failed to set acx_event_mbox_mask: %d", ret); - goto out; - } - -out: - kfree(mask); - return ret; -} - -int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble) -{ - struct acx_preamble *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx_set_preamble"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->preamble = preamble; - - ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("Setting of preamble failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_cts_protect(struct wl1251 *wl, - enum acx_ctsprotect_type ctsprotect) -{ - struct acx_ctsprotect *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ctsprotect = ctsprotect; - - ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("Setting of ctsprotect failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) -{ - struct acx_tsf_info *tsf_info; - int ret; - - tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); - if (!tsf_info) { - ret = -ENOMEM; - goto out; - } - - ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO, - tsf_info, sizeof(*tsf_info)); - if (ret < 0) { - wl1251_warning("ACX_FW_REV interrogate failed"); - goto out; - } - - *mactime = tsf_info->current_tsf_lsb | - (tsf_info->current_tsf_msb << 31); - -out: - kfree(tsf_info); - return ret; -} - -int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats) -{ - int ret; - - wl1251_debug(DEBUG_ACX, "acx statistics"); - - ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats, - sizeof(*stats)); - if (ret < 0) { - wl1251_warning("acx statistics failed: %d", ret); - return -ENOMEM; - } - - return 0; -} - -int wl1251_acx_rate_policies(struct wl1251 *wl) -{ - struct acx_rate_policy *acx; - int ret = 0; - - wl1251_debug(DEBUG_ACX, "acx rate policies"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* configure one default (one-size-fits-all) rate class */ - acx->rate_class_cnt = 1; - acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; - acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; - acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; - acx->rate_class[0].aflags = 0; - - ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("Setting of rate policies failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_mem_cfg(struct wl1251 *wl) -{ - struct wl1251_acx_config_memory *mem_conf; - int ret, i; - - wl1251_debug(DEBUG_ACX, "acx mem cfg"); - - mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); - if (!mem_conf) { - ret = -ENOMEM; - goto out; - } - - /* memory config */ - mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); - mem_conf->mem_config.rx_mem_block_num = 35; - mem_conf->mem_config.tx_min_mem_block_num = 64; - mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES; - mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING; - mem_conf->mem_config.num_ssid_profiles = 1; - mem_conf->mem_config.debug_buffer_size = - cpu_to_le16(TRACE_BUFFER_MAX_SIZE); - - /* RX queue config */ - mem_conf->rx_queue_config.dma_address = 0; - mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF; - mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY; - mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE; - - /* TX queue config */ - for (i = 0; i < MAX_TX_QUEUES; i++) { - mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF; - mem_conf->tx_queue_config[i].attributes = i; - } - - ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf, - sizeof(*mem_conf)); - if (ret < 0) { - wl1251_warning("wl1251 mem config failed: %d", ret); - goto out; - } - -out: - kfree(mem_conf); - return ret; -} - -int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim) -{ - struct wl1251_acx_wr_tbtt_and_dtim *acx; - int ret; - - wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->tbtt = tbtt; - acx->dtim = dtim; - - ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM, - acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("failed to set tbtt and dtim: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifs, u16 txop) -{ - struct wl1251_acx_ac_cfg *acx; - int ret = 0; - - wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " - "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ac = ac; - acx->cw_min = cw_min; - acx->cw_max = cw_max; - acx->aifsn = aifs; - acx->txop_limit = txop; - - ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("acx ac cfg failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, - enum wl1251_acx_channel_type type, - u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, - enum wl1251_acx_ack_policy ack_policy) -{ - struct wl1251_acx_tid_cfg *acx; - int ret = 0; - - wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d " - "ps_scheme %d ack_policy %d", queue, type, tsid, - ps_scheme, ack_policy); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->queue = queue; - acx->type = type; - acx->tsid = tsid; - acx->ps_scheme = ps_scheme; - acx->ack_policy = ack_policy; - - ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_warning("acx tid cfg failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h deleted file mode 100644 index c7cc5c1e8a75..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ /dev/null @@ -1,1411 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_ACX_H__ -#define __WL1251_ACX_H__ - -#include "wl1251.h" -#include "wl1251_cmd.h" - -/* Target's information element */ -struct acx_header { - struct wl1251_cmd_header cmd; - - /* acx (or information element) header */ - u16 id; - - /* payload length (not including headers */ - u16 len; -} __packed; - -struct acx_error_counter { - struct acx_header header; - - /* The number of PLCP errors since the last time this */ - /* information element was interrogated. This field is */ - /* automatically cleared when it is interrogated.*/ - u32 PLCP_error; - - /* The number of FCS errors since the last time this */ - /* information element was interrogated. This field is */ - /* automatically cleared when it is interrogated.*/ - u32 FCS_error; - - /* The number of MPDUs without PLCP header errors received*/ - /* since the last time this information element was interrogated. */ - /* This field is automatically cleared when it is interrogated.*/ - u32 valid_frame; - - /* the number of missed sequence numbers in the squentially */ - /* values of frames seq numbers */ - u32 seq_num_miss; -} __packed; - -struct acx_revision { - struct acx_header header; - - /* - * The WiLink firmware version, an ASCII string x.x.x.x, - * that uniquely identifies the current firmware. - * The left most digit is incremented each time a - * significant change is made to the firmware, such as - * code redesign or new platform support. - * The second digit is incremented when major enhancements - * are added or major fixes are made. - * The third digit is incremented for each GA release. - * The fourth digit is incremented for each build. - * The first two digits identify a firmware release version, - * in other words, a unique set of features. - * The first three digits identify a GA release. - */ - char fw_version[20]; - - /* - * This 4 byte field specifies the WiLink hardware version. - * bits 0 - 15: Reserved. - * bits 16 - 23: Version ID - The WiLink version ID - * (1 = first spin, 2 = second spin, and so on). - * bits 24 - 31: Chip ID - The WiLink chip ID. - */ - u32 hw_version; -} __packed; - -enum wl1251_psm_mode { - /* Active mode */ - WL1251_PSM_CAM = 0, - - /* Power save mode */ - WL1251_PSM_PS = 1, - - /* Extreme low power */ - WL1251_PSM_ELP = 2, -}; - -struct acx_sleep_auth { - struct acx_header header; - - /* The sleep level authorization of the device. */ - /* 0 - Always active*/ - /* 1 - Power down mode: light / fast sleep*/ - /* 2 - ELP mode: Deep / Max sleep*/ - u8 sleep_auth; - u8 padding[3]; -} __packed; - -enum { - HOSTIF_PCI_MASTER_HOST_INDIRECT, - HOSTIF_PCI_MASTER_HOST_DIRECT, - HOSTIF_SLAVE, - HOSTIF_PKT_RING, - HOSTIF_DONTCARE = 0xFF -}; - -#define DEFAULT_UCAST_PRIORITY 0 -#define DEFAULT_RX_Q_PRIORITY 0 -#define DEFAULT_NUM_STATIONS 1 -#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ -#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ -#define TRACE_BUFFER_MAX_SIZE 256 - -#define DP_RX_PACKET_RING_CHUNK_SIZE 1600 -#define DP_TX_PACKET_RING_CHUNK_SIZE 1600 -#define DP_RX_PACKET_RING_CHUNK_NUM 2 -#define DP_TX_PACKET_RING_CHUNK_NUM 2 -#define DP_TX_COMPLETE_TIME_OUT 20 -#define FW_TX_CMPLT_BLOCK_SIZE 16 - -struct acx_data_path_params { - struct acx_header header; - - u16 rx_packet_ring_chunk_size; - u16 tx_packet_ring_chunk_size; - - u8 rx_packet_ring_chunk_num; - u8 tx_packet_ring_chunk_num; - - /* - * Maximum number of packets that can be gathered - * in the TX complete ring before an interrupt - * is generated. - */ - u8 tx_complete_threshold; - - /* Number of pending TX complete entries in cyclic ring.*/ - u8 tx_complete_ring_depth; - - /* - * Max num microseconds since a packet enters the TX - * complete ring until an interrupt is generated. - */ - u32 tx_complete_timeout; -} __packed; - - -struct acx_data_path_params_resp { - struct acx_header header; - - u16 rx_packet_ring_chunk_size; - u16 tx_packet_ring_chunk_size; - - u8 rx_packet_ring_chunk_num; - u8 tx_packet_ring_chunk_num; - - u8 pad[2]; - - u32 rx_packet_ring_addr; - u32 tx_packet_ring_addr; - - u32 rx_control_addr; - u32 tx_control_addr; - - u32 tx_complete_addr; -} __packed; - -#define TX_MSDU_LIFETIME_MIN 0 -#define TX_MSDU_LIFETIME_MAX 3000 -#define TX_MSDU_LIFETIME_DEF 512 -#define RX_MSDU_LIFETIME_MIN 0 -#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF -#define RX_MSDU_LIFETIME_DEF 512000 - -struct acx_rx_msdu_lifetime { - struct acx_header header; - - /* - * The maximum amount of time, in TU, before the - * firmware discards the MSDU. - */ - u32 lifetime; -} __packed; - -/* - * RX Config Options Table - * Bit Definition - * === ========== - * 31:14 Reserved - * 13 Copy RX Status - when set, write three receive status words - * to top of rx'd MPDUs. - * When cleared, do not write three status words (added rev 1.5) - * 12 Reserved - * 11 RX Complete upon FCS error - when set, give rx complete - * interrupt for FCS errors, after the rx filtering, e.g. unicast - * frames not to us with FCS error will not generate an interrupt. - * 10 SSID Filter Enable - When set, the WiLink discards all beacon, - * probe request, and probe response frames with an SSID that does - * not match the SSID specified by the host in the START/JOIN - * command. - * When clear, the WiLink receives frames with any SSID. - * 9 Broadcast Filter Enable - When set, the WiLink discards all - * broadcast frames. When clear, the WiLink receives all received - * broadcast frames. - * 8:6 Reserved - * 5 BSSID Filter Enable - When set, the WiLink discards any frames - * with a BSSID that does not match the BSSID specified by the - * host. - * When clear, the WiLink receives frames from any BSSID. - * 4 MAC Addr Filter - When set, the WiLink discards any frames - * with a destination address that does not match the MAC address - * of the adaptor. - * When clear, the WiLink receives frames destined to any MAC - * address. - * 3 Promiscuous - When set, the WiLink receives all valid frames - * (i.e., all frames that pass the FCS check). - * When clear, only frames that pass the other filters specified - * are received. - * 2 FCS - When set, the WiLink includes the FCS with the received - * frame. - * When cleared, the FCS is discarded. - * 1 PLCP header - When set, write all data from baseband to frame - * buffer including PHY header. - * 0 Reserved - Always equal to 0. - * - * RX Filter Options Table - * Bit Definition - * === ========== - * 31:12 Reserved - Always equal to 0. - * 11 Association - When set, the WiLink receives all association - * related frames (association request/response, reassocation - * request/response, and disassociation). When clear, these frames - * are discarded. - * 10 Auth/De auth - When set, the WiLink receives all authentication - * and de-authentication frames. When clear, these frames are - * discarded. - * 9 Beacon - When set, the WiLink receives all beacon frames. - * When clear, these frames are discarded. - * 8 Contention Free - When set, the WiLink receives all contention - * free frames. - * When clear, these frames are discarded. - * 7 Control - When set, the WiLink receives all control frames. - * When clear, these frames are discarded. - * 6 Data - When set, the WiLink receives all data frames. - * When clear, these frames are discarded. - * 5 FCS Error - When set, the WiLink receives frames that have FCS - * errors. - * When clear, these frames are discarded. - * 4 Management - When set, the WiLink receives all management - * frames. - * When clear, these frames are discarded. - * 3 Probe Request - When set, the WiLink receives all probe request - * frames. - * When clear, these frames are discarded. - * 2 Probe Response - When set, the WiLink receives all probe - * response frames. - * When clear, these frames are discarded. - * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK - * frames. - * When clear, these frames are discarded. - * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames - * that have reserved frame types and sub types as defined by the - * 802.11 specification. - * When clear, these frames are discarded. - */ -struct acx_rx_config { - struct acx_header header; - - u32 config_options; - u32 filter_options; -} __packed; - -enum { - QOS_AC_BE = 0, - QOS_AC_BK, - QOS_AC_VI, - QOS_AC_VO, - QOS_HIGHEST_AC_INDEX = QOS_AC_VO, -}; - -#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1) -#define FIRST_AC_INDEX QOS_AC_BE -#define MAX_NUM_OF_802_1d_TAGS 8 -#define AC_PARAMS_MAX_TSID 15 -#define MAX_APSD_CONF 0xffff - -#define QOS_TX_HIGH_MIN (0) -#define QOS_TX_HIGH_MAX (100) - -#define QOS_TX_HIGH_BK_DEF (25) -#define QOS_TX_HIGH_BE_DEF (35) -#define QOS_TX_HIGH_VI_DEF (35) -#define QOS_TX_HIGH_VO_DEF (35) - -#define QOS_TX_LOW_BK_DEF (15) -#define QOS_TX_LOW_BE_DEF (25) -#define QOS_TX_LOW_VI_DEF (25) -#define QOS_TX_LOW_VO_DEF (25) - -struct acx_tx_queue_qos_config { - struct acx_header header; - - u8 qid; - u8 pad[3]; - - /* Max number of blocks allowd in the queue */ - u16 high_threshold; - - /* Lowest memory blocks guaranteed for this queue */ - u16 low_threshold; -} __packed; - -struct acx_packet_detection { - struct acx_header header; - - u32 threshold; -} __packed; - - -enum acx_slot_type { - SLOT_TIME_LONG = 0, - SLOT_TIME_SHORT = 1, - DEFAULT_SLOT_TIME = SLOT_TIME_SHORT, - MAX_SLOT_TIMES = 0xFF -}; - -#define STATION_WONE_INDEX 0 - -struct acx_slot { - struct acx_header header; - - u8 wone_index; /* Reserved */ - u8 slot_time; - u8 reserved[6]; -} __packed; - - -#define ADDRESS_GROUP_MAX (8) -#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX) - -struct acx_dot11_grp_addr_tbl { - struct acx_header header; - - u8 enabled; - u8 num_groups; - u8 pad[2]; - u8 mac_table[ADDRESS_GROUP_MAX_LEN]; -} __packed; - - -#define RX_TIMEOUT_PS_POLL_MIN 0 -#define RX_TIMEOUT_PS_POLL_MAX (200000) -#define RX_TIMEOUT_PS_POLL_DEF (15) -#define RX_TIMEOUT_UPSD_MIN 0 -#define RX_TIMEOUT_UPSD_MAX (200000) -#define RX_TIMEOUT_UPSD_DEF (15) - -struct acx_rx_timeout { - struct acx_header header; - - /* - * The longest time the STA will wait to receive - * traffic from the AP after a PS-poll has been - * transmitted. - */ - u16 ps_poll_timeout; - - /* - * The longest time the STA will wait to receive - * traffic from the AP after a frame has been sent - * from an UPSD enabled queue. - */ - u16 upsd_timeout; -} __packed; - -#define RTS_THRESHOLD_MIN 0 -#define RTS_THRESHOLD_MAX 4096 -#define RTS_THRESHOLD_DEF 2347 - -struct acx_rts_threshold { - struct acx_header header; - - u16 threshold; - u8 pad[2]; -} __packed; - -struct acx_beacon_filter_option { - struct acx_header header; - - u8 enable; - - /* - * The number of beacons without the unicast TIM - * bit set that the firmware buffers before - * signaling the host about ready frames. - * When set to 0 and the filter is enabled, beacons - * without the unicast TIM bit set are dropped. - */ - u8 max_num_beacons; - u8 pad[2]; -} __packed; - -/* - * ACXBeaconFilterEntry (not 221) - * Byte Offset Size (Bytes) Definition - * =========== ============ ========== - * 0 1 IE identifier - * 1 1 Treatment bit mask - * - * ACXBeaconFilterEntry (221) - * Byte Offset Size (Bytes) Definition - * =========== ============ ========== - * 0 1 IE identifier - * 1 1 Treatment bit mask - * 2 3 OUI - * 5 1 Type - * 6 2 Version - * - * - * Treatment bit mask - The information element handling: - * bit 0 - The information element is compared and transferred - * in case of change. - * bit 1 - The information element is transferred to the host - * with each appearance or disappearance. - * Note that both bits can be set at the same time. - */ -#define BEACON_FILTER_TABLE_MAX_IE_NUM (32) -#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6) -#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2) -#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6) -#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \ - BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \ - (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ - BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) - -#define BEACON_RULE_PASS_ON_CHANGE BIT(0) -#define BEACON_RULE_PASS_ON_APPEARANCE BIT(1) - -#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN (37) - -struct acx_beacon_filter_ie_table { - struct acx_header header; - - u8 num_ie; - u8 pad[3]; - u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; -} __packed; - -#define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ -#define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */ - -struct acx_conn_monit_params { - struct acx_header header; - - u32 synch_fail_thold; /* number of beacons missed */ - u32 bss_lose_timeout; /* number of TU's from synch fail */ -} __packed; - -enum { - SG_ENABLE = 0, - SG_DISABLE, - SG_SENSE_NO_ACTIVITY, - SG_SENSE_ACTIVE -}; - -struct acx_bt_wlan_coex { - struct acx_header header; - - /* - * 0 -> PTA enabled - * 1 -> PTA disabled - * 2 -> sense no active mode, i.e. - * an interrupt is sent upon - * BT activity. - * 3 -> PTA is switched on in response - * to the interrupt sending. - */ - u8 enable; - u8 pad[3]; -} __packed; - -#define PTA_ANTENNA_TYPE_DEF (0) -#define PTA_BT_HP_MAXTIME_DEF (2000) -#define PTA_WLAN_HP_MAX_TIME_DEF (5000) -#define PTA_SENSE_DISABLE_TIMER_DEF (1350) -#define PTA_PROTECTIVE_RX_TIME_DEF (1500) -#define PTA_PROTECTIVE_TX_TIME_DEF (1500) -#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000) -#define PTA_SIGNALING_TYPE_DEF (1) -#define PTA_AFH_LEVERAGE_ON_DEF (0) -#define PTA_NUMBER_QUIET_CYCLE_DEF (0) -#define PTA_MAX_NUM_CTS_DEF (3) -#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2) -#define PTA_NUMBER_OF_BT_PACKETS_DEF (2) -#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500) -#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000) -#define PTA_CYCLE_TIME_FAST_DEF (8700) -#define PTA_RX_FOR_AVALANCHE_DEF (5) -#define PTA_ELP_HP_DEF (0) -#define PTA_ANTI_STARVE_PERIOD_DEF (500) -#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4) -#define PTA_ALLOW_PA_SD_DEF (1) -#define PTA_TIME_BEFORE_BEACON_DEF (6300) -#define PTA_HPDM_MAX_TIME_DEF (1600) -#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550) -#define PTA_AUTO_MODE_NO_CTS_DEF (0) -#define PTA_BT_HP_RESPECTED_DEF (3) -#define PTA_WLAN_RX_MIN_RATE_DEF (24) -#define PTA_ACK_MODE_DEF (1) - -struct acx_bt_wlan_coex_param { - struct acx_header header; - - /* - * The minimum rate of a received WLAN packet in the STA, - * during protective mode, of which a new BT-HP request - * during this Rx will always be respected and gain the antenna. - */ - u32 min_rate; - - /* Max time the BT HP will be respected. */ - u16 bt_hp_max_time; - - /* Max time the WLAN HP will be respected. */ - u16 wlan_hp_max_time; - - /* - * The time between the last BT activity - * and the moment when the sense mode returns - * to SENSE_INACTIVE. - */ - u16 sense_disable_timer; - - /* Time before the next BT HP instance */ - u16 rx_time_bt_hp; - u16 tx_time_bt_hp; - - /* range: 10-20000 default: 1500 */ - u16 rx_time_bt_hp_fast; - u16 tx_time_bt_hp_fast; - - /* range: 2000-65535 default: 8700 */ - u16 wlan_cycle_fast; - - /* range: 0 - 15000 (Msec) default: 1000 */ - u16 bt_anti_starvation_period; - - /* range 400-10000(Usec) default: 3000 */ - u16 next_bt_lp_packet; - - /* Deafult: worst case for BT DH5 traffic */ - u16 wake_up_beacon; - - /* range: 0-50000(Usec) default: 1050 */ - u16 hp_dm_max_guard_time; - - /* - * This is to prevent both BT & WLAN antenna - * starvation. - * Range: 100-50000(Usec) default:2550 - */ - u16 next_wlan_packet; - - /* 0 -> shared antenna */ - u8 antenna_type; - - /* - * 0 -> TI legacy - * 1 -> Palau - */ - u8 signal_type; - - /* - * BT AFH status - * 0 -> no AFH - * 1 -> from dedicated GPIO - * 2 -> AFH on (from host) - */ - u8 afh_leverage_on; - - /* - * The number of cycles during which no - * TX will be sent after 1 cycle of RX - * transaction in protective mode - */ - u8 quiet_cycle_num; - - /* - * The maximum number of CTSs that will - * be sent for receiving RX packet in - * protective mode - */ - u8 max_cts; - - /* - * The number of WLAN packets - * transferred in common mode before - * switching to BT. - */ - u8 wlan_packets_num; - - /* - * The number of BT packets - * transferred in common mode before - * switching to WLAN. - */ - u8 bt_packets_num; - - /* range: 1-255 default: 5 */ - u8 missed_rx_avalanche; - - /* range: 0-1 default: 1 */ - u8 wlan_elp_hp; - - /* range: 0 - 15 default: 4 */ - u8 bt_anti_starvation_cycles; - - u8 ack_mode_dual_ant; - - /* - * Allow PA_SD assertion/de-assertion - * during enabled BT activity. - */ - u8 pa_sd_enable; - - /* - * Enable/Disable PTA in auto mode: - * Support Both Active & P.S modes - */ - u8 pta_auto_mode_enable; - - /* range: 0 - 20 default: 1 */ - u8 bt_hp_respected_num; -} __packed; - -#define CCA_THRSH_ENABLE_ENERGY_D 0x140A -#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF - -struct acx_energy_detection { - struct acx_header header; - - /* The RX Clear Channel Assessment threshold in the PHY */ - u16 rx_cca_threshold; - u8 tx_energy_detection; - u8 pad; -} __packed; - -#define BCN_RX_TIMEOUT_DEF_VALUE 10000 -#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000 -#define RX_BROADCAST_IN_PS_DEF_VALUE 1 -#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4 - -struct acx_beacon_broadcast { - struct acx_header header; - - u16 beacon_rx_timeout; - u16 broadcast_timeout; - - /* Enables receiving of broadcast packets in PS mode */ - u8 rx_broadcast_in_ps; - - /* Consecutive PS Poll failures before updating the host */ - u8 ps_poll_threshold; - u8 pad[2]; -} __packed; - -struct acx_event_mask { - struct acx_header header; - - u32 event_mask; - u32 high_event_mask; /* Unused */ -} __packed; - -#define CFG_RX_FCS BIT(2) -#define CFG_RX_ALL_GOOD BIT(3) -#define CFG_UNI_FILTER_EN BIT(4) -#define CFG_BSSID_FILTER_EN BIT(5) -#define CFG_MC_FILTER_EN BIT(6) -#define CFG_MC_ADDR0_EN BIT(7) -#define CFG_MC_ADDR1_EN BIT(8) -#define CFG_BC_REJECT_EN BIT(9) -#define CFG_SSID_FILTER_EN BIT(10) -#define CFG_RX_INT_FCS_ERROR BIT(11) -#define CFG_RX_INT_ENCRYPTED BIT(12) -#define CFG_RX_WR_RX_STATUS BIT(13) -#define CFG_RX_FILTER_NULTI BIT(14) -#define CFG_RX_RESERVE BIT(15) -#define CFG_RX_TIMESTAMP_TSF BIT(16) - -#define CFG_RX_RSV_EN BIT(0) -#define CFG_RX_RCTS_ACK BIT(1) -#define CFG_RX_PRSP_EN BIT(2) -#define CFG_RX_PREQ_EN BIT(3) -#define CFG_RX_MGMT_EN BIT(4) -#define CFG_RX_FCS_ERROR BIT(5) -#define CFG_RX_DATA_EN BIT(6) -#define CFG_RX_CTL_EN BIT(7) -#define CFG_RX_CF_EN BIT(8) -#define CFG_RX_BCN_EN BIT(9) -#define CFG_RX_AUTH_EN BIT(10) -#define CFG_RX_ASSOC_EN BIT(11) - -#define SCAN_PASSIVE BIT(0) -#define SCAN_5GHZ_BAND BIT(1) -#define SCAN_TRIGGERED BIT(2) -#define SCAN_PRIORITY_HIGH BIT(3) - -struct acx_fw_gen_frame_rates { - struct acx_header header; - - u8 tx_ctrl_frame_rate; /* RATE_* */ - u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */ - u8 tx_mgt_frame_rate; - u8 tx_mgt_frame_mod; -} __packed; - -/* STA MAC */ -struct acx_dot11_station_id { - struct acx_header header; - - u8 mac[ETH_ALEN]; - u8 pad[2]; -} __packed; - -struct acx_feature_config { - struct acx_header header; - - u32 options; - u32 data_flow_options; -} __packed; - -struct acx_current_tx_power { - struct acx_header header; - - u8 current_tx_power; - u8 padding[3]; -} __packed; - -struct acx_dot11_default_key { - struct acx_header header; - - u8 id; - u8 pad[3]; -} __packed; - -struct acx_tsf_info { - struct acx_header header; - - u32 current_tsf_msb; - u32 current_tsf_lsb; - u32 last_TBTT_msb; - u32 last_TBTT_lsb; - u8 last_dtim_count; - u8 pad[3]; -} __packed; - -enum acx_wake_up_event { - WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/ - WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/ - WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */ - WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */ - WAKE_UP_EVENT_BITS_MASK = 0x0F -}; - -struct acx_wake_up_condition { - struct acx_header header; - - u8 wake_up_event; /* Only one bit can be set */ - u8 listen_interval; - u8 pad[2]; -} __packed; - -struct acx_aid { - struct acx_header header; - - /* - * To be set when associated with an AP. - */ - u16 aid; - u8 pad[2]; -} __packed; - -enum acx_preamble_type { - ACX_PREAMBLE_LONG = 0, - ACX_PREAMBLE_SHORT = 1 -}; - -struct acx_preamble { - struct acx_header header; - - /* - * When set, the WiLink transmits the frames with a short preamble and - * when cleared, the WiLink transmits the frames with a long preamble. - */ - u8 preamble; - u8 padding[3]; -} __packed; - -enum acx_ctsprotect_type { - CTSPROTECT_DISABLE = 0, - CTSPROTECT_ENABLE = 1 -}; - -struct acx_ctsprotect { - struct acx_header header; - u8 ctsprotect; - u8 padding[3]; -} __packed; - -struct acx_tx_statistics { - u32 internal_desc_overflow; -} __packed; - -struct acx_rx_statistics { - u32 out_of_mem; - u32 hdr_overflow; - u32 hw_stuck; - u32 dropped; - u32 fcs_err; - u32 xfr_hint_trig; - u32 path_reset; - u32 reset_counter; -} __packed; - -struct acx_dma_statistics { - u32 rx_requested; - u32 rx_errors; - u32 tx_requested; - u32 tx_errors; -} __packed; - -struct acx_isr_statistics { - /* host command complete */ - u32 cmd_cmplt; - - /* fiqisr() */ - u32 fiqs; - - /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ - u32 rx_headers; - - /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ - u32 rx_completes; - - /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ - u32 rx_mem_overflow; - - /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ - u32 rx_rdys; - - /* irqisr() */ - u32 irqs; - - /* (INT_STS_ND & INT_TRIG_TX_PROC) */ - u32 tx_procs; - - /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ - u32 decrypt_done; - - /* (INT_STS_ND & INT_TRIG_DMA0) */ - u32 dma0_done; - - /* (INT_STS_ND & INT_TRIG_DMA1) */ - u32 dma1_done; - - /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ - u32 tx_exch_complete; - - /* (INT_STS_ND & INT_TRIG_COMMAND) */ - u32 commands; - - /* (INT_STS_ND & INT_TRIG_RX_PROC) */ - u32 rx_procs; - - /* (INT_STS_ND & INT_TRIG_PM_802) */ - u32 hw_pm_mode_changes; - - /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ - u32 host_acknowledges; - - /* (INT_STS_ND & INT_TRIG_PM_PCI) */ - u32 pci_pm; - - /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ - u32 wakeups; - - /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ - u32 low_rssi; -} __packed; - -struct acx_wep_statistics { - /* WEP address keys configured */ - u32 addr_key_count; - - /* default keys configured */ - u32 default_key_count; - - u32 reserved; - - /* number of times that WEP key not found on lookup */ - u32 key_not_found; - - /* number of times that WEP key decryption failed */ - u32 decrypt_fail; - - /* WEP packets decrypted */ - u32 packets; - - /* WEP decrypt interrupts */ - u32 interrupt; -} __packed; - -#define ACX_MISSED_BEACONS_SPREAD 10 - -struct acx_pwr_statistics { - /* the amount of enters into power save mode (both PD & ELP) */ - u32 ps_enter; - - /* the amount of enters into ELP mode */ - u32 elp_enter; - - /* the amount of missing beacon interrupts to the host */ - u32 missing_bcns; - - /* the amount of wake on host-access times */ - u32 wake_on_host; - - /* the amount of wake on timer-expire */ - u32 wake_on_timer_exp; - - /* the number of packets that were transmitted with PS bit set */ - u32 tx_with_ps; - - /* the number of packets that were transmitted with PS bit clear */ - u32 tx_without_ps; - - /* the number of received beacons */ - u32 rcvd_beacons; - - /* the number of entering into PowerOn (power save off) */ - u32 power_save_off; - - /* the number of entries into power save mode */ - u16 enable_ps; - - /* - * the number of exits from power save, not including failed PS - * transitions - */ - u16 disable_ps; - - /* - * the number of times the TSF counter was adjusted because - * of drift - */ - u32 fix_tsf_ps; - - /* Gives statistics about the spread continuous missed beacons. - * The 16 LSB are dedicated for the PS mode. - * The 16 MSB are dedicated for the PS mode. - * cont_miss_bcns_spread[0] - single missed beacon. - * cont_miss_bcns_spread[1] - two continuous missed beacons. - * cont_miss_bcns_spread[2] - three continuous missed beacons. - * ... - * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. - */ - u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; - - /* the number of beacons in awake mode */ - u32 rcvd_awake_beacons; -} __packed; - -struct acx_mic_statistics { - u32 rx_pkts; - u32 calc_failure; -} __packed; - -struct acx_aes_statistics { - u32 encrypt_fail; - u32 decrypt_fail; - u32 encrypt_packets; - u32 decrypt_packets; - u32 encrypt_interrupt; - u32 decrypt_interrupt; -} __packed; - -struct acx_event_statistics { - u32 heart_beat; - u32 calibration; - u32 rx_mismatch; - u32 rx_mem_empty; - u32 rx_pool; - u32 oom_late; - u32 phy_transmit_error; - u32 tx_stuck; -} __packed; - -struct acx_ps_statistics { - u32 pspoll_timeouts; - u32 upsd_timeouts; - u32 upsd_max_sptime; - u32 upsd_max_apturn; - u32 pspoll_max_apturn; - u32 pspoll_utilization; - u32 upsd_utilization; -} __packed; - -struct acx_rxpipe_statistics { - u32 rx_prep_beacon_drop; - u32 descr_host_int_trig_rx_data; - u32 beacon_buffer_thres_host_int_trig_rx_data; - u32 missed_beacon_host_int_trig_rx_data; - u32 tx_xfr_host_int_trig_rx_data; -} __packed; - -struct acx_statistics { - struct acx_header header; - - struct acx_tx_statistics tx; - struct acx_rx_statistics rx; - struct acx_dma_statistics dma; - struct acx_isr_statistics isr; - struct acx_wep_statistics wep; - struct acx_pwr_statistics pwr; - struct acx_aes_statistics aes; - struct acx_mic_statistics mic; - struct acx_event_statistics event; - struct acx_ps_statistics ps; - struct acx_rxpipe_statistics rxpipe; -} __packed; - -#define ACX_MAX_RATE_CLASSES 8 -#define ACX_RATE_MASK_UNSPECIFIED 0 -#define ACX_RATE_RETRY_LIMIT 10 - -struct acx_rate_class { - u32 enabled_rates; - u8 short_retry_limit; - u8 long_retry_limit; - u8 aflags; - u8 reserved; -} __packed; - -struct acx_rate_policy { - struct acx_header header; - - u32 rate_class_cnt; - struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES]; -} __packed; - -struct wl1251_acx_memory { - __le16 num_stations; /* number of STAs to be supported. */ - u16 reserved_1; - - /* - * Nmber of memory buffers for the RX mem pool. - * The actual number may be less if there are - * not enough blocks left for the minimum num - * of TX ones. - */ - u8 rx_mem_block_num; - u8 reserved_2; - u8 num_tx_queues; /* From 1 to 16 */ - u8 host_if_options; /* HOST_IF* */ - u8 tx_min_mem_block_num; - u8 num_ssid_profiles; - __le16 debug_buffer_size; -} __packed; - - -#define ACX_RX_DESC_MIN 1 -#define ACX_RX_DESC_MAX 127 -#define ACX_RX_DESC_DEF 32 -struct wl1251_acx_rx_queue_config { - u8 num_descs; - u8 pad; - u8 type; - u8 priority; - __le32 dma_address; -} __packed; - -#define ACX_TX_DESC_MIN 1 -#define ACX_TX_DESC_MAX 127 -#define ACX_TX_DESC_DEF 16 -struct wl1251_acx_tx_queue_config { - u8 num_descs; - u8 pad[2]; - u8 attributes; -} __packed; - -#define MAX_TX_QUEUE_CONFIGS 5 -#define MAX_TX_QUEUES 4 -struct wl1251_acx_config_memory { - struct acx_header header; - - struct wl1251_acx_memory mem_config; - struct wl1251_acx_rx_queue_config rx_queue_config; - struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS]; -} __packed; - -struct wl1251_acx_mem_map { - struct acx_header header; - - void *code_start; - void *code_end; - - void *wep_defkey_start; - void *wep_defkey_end; - - void *sta_table_start; - void *sta_table_end; - - void *packet_template_start; - void *packet_template_end; - - void *queue_memory_start; - void *queue_memory_end; - - void *packet_memory_pool_start; - void *packet_memory_pool_end; - - void *debug_buffer1_start; - void *debug_buffer1_end; - - void *debug_buffer2_start; - void *debug_buffer2_end; - - /* Number of blocks FW allocated for TX packets */ - u32 num_tx_mem_blocks; - - /* Number of blocks FW allocated for RX packets */ - u32 num_rx_mem_blocks; -} __packed; - - -struct wl1251_acx_wr_tbtt_and_dtim { - - struct acx_header header; - - /* Time in TUs between two consecutive beacons */ - u16 tbtt; - - /* - * DTIM period - * For BSS: Number of TBTTs in a DTIM period (range: 1-10) - * For IBSS: value shall be set to 1 - */ - u8 dtim; - u8 padding; -} __packed; - -struct wl1251_acx_ac_cfg { - struct acx_header header; - - /* - * Access Category - The TX queue's access category - * (refer to AccessCategory_enum) - */ - u8 ac; - - /* - * The contention window minimum size (in slots) for - * the access class. - */ - u8 cw_min; - - /* - * The contention window maximum size (in slots) for - * the access class. - */ - u16 cw_max; - - /* The AIF value (in slots) for the access class. */ - u8 aifsn; - - u8 reserved; - - /* The TX Op Limit (in microseconds) for the access class. */ - u16 txop_limit; -} __packed; - - -enum wl1251_acx_channel_type { - CHANNEL_TYPE_DCF = 0, - CHANNEL_TYPE_EDCF = 1, - CHANNEL_TYPE_HCCA = 2, -}; - -enum wl1251_acx_ps_scheme { - /* regular ps: simple sending of packets */ - WL1251_ACX_PS_SCHEME_LEGACY = 0, - - /* sending a packet triggers a unscheduled apsd downstream */ - WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1, - - /* a pspoll packet will be sent before every data packet */ - WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2, - - /* scheduled apsd mode */ - WL1251_ACX_PS_SCHEME_SAPSD = 3, -}; - -enum wl1251_acx_ack_policy { - WL1251_ACX_ACK_POLICY_LEGACY = 0, - WL1251_ACX_ACK_POLICY_NO_ACK = 1, - WL1251_ACX_ACK_POLICY_BLOCK = 2, -}; - -struct wl1251_acx_tid_cfg { - struct acx_header header; - - /* tx queue id number (0-7) */ - u8 queue; - - /* channel access type for the queue, enum wl1251_acx_channel_type */ - u8 type; - - /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */ - u8 tsid; - - /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */ - u8 ps_scheme; - - /* the tx queue ack policy, enum wl1251_acx_ack_policy */ - u8 ack_policy; - - u8 padding[3]; - - /* not supported */ - u32 apsdconf[2]; -} __packed; - -/************************************************************************* - - Host Interrupt Register (WiLink -> Host) - -**************************************************************************/ - -/* RX packet is ready in Xfer buffer #0 */ -#define WL1251_ACX_INTR_RX0_DATA BIT(0) - -/* TX result(s) are in the TX complete buffer */ -#define WL1251_ACX_INTR_TX_RESULT BIT(1) - -/* OBSOLETE */ -#define WL1251_ACX_INTR_TX_XFR BIT(2) - -/* RX packet is ready in Xfer buffer #1 */ -#define WL1251_ACX_INTR_RX1_DATA BIT(3) - -/* Event was entered to Event MBOX #A */ -#define WL1251_ACX_INTR_EVENT_A BIT(4) - -/* Event was entered to Event MBOX #B */ -#define WL1251_ACX_INTR_EVENT_B BIT(5) - -/* OBSOLETE */ -#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6) - -/* Trace meassge on MBOX #A */ -#define WL1251_ACX_INTR_TRACE_A BIT(7) - -/* Trace meassge on MBOX #B */ -#define WL1251_ACX_INTR_TRACE_B BIT(8) - -/* Command processing completion */ -#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9) - -/* Init sequence is done */ -#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14) - -#define WL1251_ACX_INTR_ALL 0xFFFFFFFF - -enum { - ACX_WAKE_UP_CONDITIONS = 0x0002, - ACX_MEM_CFG = 0x0003, - ACX_SLOT = 0x0004, - ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */ - ACX_AC_CFG = 0x0007, - ACX_MEM_MAP = 0x0008, - ACX_AID = 0x000A, - ACX_RADIO_PARAM = 0x000B, /* Not used */ - ACX_CFG = 0x000C, /* Not used */ - ACX_FW_REV = 0x000D, - ACX_MEDIUM_USAGE = 0x000F, - ACX_RX_CFG = 0x0010, - ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ - ACX_BSS_IN_PS = 0x0012, /* for AP only */ - ACX_STATISTICS = 0x0013, /* Debug API */ - ACX_FEATURE_CFG = 0x0015, - ACX_MISC_CFG = 0x0017, /* Not used */ - ACX_TID_CFG = 0x001A, - ACX_BEACON_FILTER_OPT = 0x001F, - ACX_LOW_RSSI = 0x0020, - ACX_NOISE_HIST = 0x0021, - ACX_HDK_VERSION = 0x0022, /* ??? */ - ACX_PD_THRESHOLD = 0x0023, - ACX_DATA_PATH_PARAMS = 0x0024, /* WO */ - ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */ - ACX_CCA_THRESHOLD = 0x0025, - ACX_EVENT_MBOX_MASK = 0x0026, -#ifdef FW_RUNNING_AS_AP - ACX_DTIM_PERIOD = 0x0027, /* for AP only */ -#else - ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */ -#endif - ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/ - ACX_GPIO_CFG = 0x002A, /* Not used */ - ACX_GPIO_SET = 0x002B, /* Not used */ - ACX_PM_CFG = 0x002C, /* To Be Documented */ - ACX_CONN_MONIT_PARAMS = 0x002D, - ACX_AVERAGE_RSSI = 0x002E, /* Not used */ - ACX_CONS_TX_FAILURE = 0x002F, - ACX_BCN_DTIM_OPTIONS = 0x0031, - ACX_SG_ENABLE = 0x0032, - ACX_SG_CFG = 0x0033, - ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */ - ACX_LOW_SNR = 0x0037, /* To Be Documented */ - ACX_BEACON_FILTER_TABLE = 0x0038, - ACX_ARP_IP_FILTER = 0x0039, - ACX_ROAMING_STATISTICS_TBL = 0x003B, - ACX_RATE_POLICY = 0x003D, - ACX_CTS_PROTECTION = 0x003E, - ACX_SLEEP_AUTH = 0x003F, - ACX_PREAMBLE_TYPE = 0x0040, - ACX_ERROR_CNT = 0x0041, - ACX_FW_GEN_FRAME_RATES = 0x0042, - ACX_IBSS_FILTER = 0x0044, - ACX_SERVICE_PERIOD_TIMEOUT = 0x0045, - ACX_TSF_INFO = 0x0046, - ACX_CONFIG_PS_WMM = 0x0049, - ACX_ENABLE_RX_DATA_FILTER = 0x004A, - ACX_SET_RX_DATA_FILTER = 0x004B, - ACX_GET_DATA_FILTER_STATISTICS = 0x004C, - ACX_POWER_LEVEL_TABLE = 0x004D, - ACX_BET_ENABLE = 0x0050, - DOT11_STATION_ID = 0x1001, - DOT11_RX_MSDU_LIFE_TIME = 0x1004, - DOT11_CUR_TX_PWR = 0x100D, - DOT11_DEFAULT_KEY = 0x1010, - DOT11_RX_DOT11_MODE = 0x1012, - DOT11_RTS_THRESHOLD = 0x1013, - DOT11_GROUP_ADDRESS_TBL = 0x1014, - - MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, - - MAX_IE = 0xFFFF -}; - - -int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, - u8 mgt_rate, u8 mgt_mod); -int wl1251_acx_station_id(struct wl1251 *wl); -int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id); -int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, - u8 listen_interval); -int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth); -int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len); -int wl1251_acx_tx_power(struct wl1251 *wl, int power); -int wl1251_acx_feature_cfg(struct wl1251 *wl); -int wl1251_acx_mem_map(struct wl1251 *wl, - struct acx_header *mem_map, size_t len); -int wl1251_acx_data_path_params(struct wl1251 *wl, - struct acx_data_path_params_resp *data_path); -int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time); -int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter); -int wl1251_acx_pd_threshold(struct wl1251 *wl); -int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); -int wl1251_acx_group_address_tbl(struct wl1251 *wl); -int wl1251_acx_service_period_timeout(struct wl1251 *wl); -int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); -int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); -int wl1251_acx_beacon_filter_table(struct wl1251 *wl); -int wl1251_acx_conn_monit_params(struct wl1251 *wl); -int wl1251_acx_sg_enable(struct wl1251 *wl); -int wl1251_acx_sg_cfg(struct wl1251 *wl); -int wl1251_acx_cca_threshold(struct wl1251 *wl); -int wl1251_acx_bcn_dtim_options(struct wl1251 *wl); -int wl1251_acx_aid(struct wl1251 *wl, u16 aid); -int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask); -int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble); -int wl1251_acx_cts_protect(struct wl1251 *wl, - enum acx_ctsprotect_type ctsprotect); -int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats); -int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); -int wl1251_acx_rate_policies(struct wl1251 *wl); -int wl1251_acx_mem_cfg(struct wl1251 *wl); -int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); -int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifs, u16 txop); -int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, - enum wl1251_acx_channel_type type, - u8 tsid, enum wl1251_acx_ps_scheme ps_scheme, - enum wl1251_acx_ack_policy ack_policy); - -#endif /* __WL1251_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c deleted file mode 100644 index 468b47b0328a..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include - -#include "wl1251_reg.h" -#include "wl1251_boot.h" -#include "wl1251_io.h" -#include "wl1251_spi.h" -#include "wl1251_event.h" -#include "wl1251_acx.h" - -void wl1251_boot_target_enable_interrupts(struct wl1251 *wl) -{ - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); - wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL); -} - -int wl1251_boot_soft_reset(struct wl1251 *wl) -{ - unsigned long timeout; - u32 boot_data; - - /* perform soft reset */ - wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); - - /* SOFT_RESET is self clearing */ - timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); - while (1) { - boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET); - wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); - if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) - break; - - if (time_after(jiffies, timeout)) { - /* 1.2 check pWhalBus->uSelfClearTime if the - * timeout was reached */ - wl1251_error("soft reset timeout"); - return -1; - } - - udelay(SOFT_RESET_STALL_TIME); - } - - /* disable Rx/Tx */ - wl1251_reg_write32(wl, ENABLE, 0x0); - - /* disable auto calibration on start*/ - wl1251_reg_write32(wl, SPARE_A2, 0xffff); - - return 0; -} - -int wl1251_boot_init_seq(struct wl1251 *wl) -{ - u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq; - - /* - * col #1: INTEGER_DIVIDER - * col #2: FRACTIONAL_DIVIDER - * col #3: ATTN_BB - * col #4: ALPHA_BB - * col #5: STOP_TIME_BB - * col #6: BB_PLL_LOOP_FILTER - */ - static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = { - - { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/ - { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/ - { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/ - { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/ - { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */ - }; - - /* read NVS params */ - scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6); - wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6); - - /* read ELP_CMD */ - elp_cmd = wl1251_reg_read32(wl, ELP_CMD); - wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd); - - /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */ - ref_freq = scr_pad6 & 0x000000FF; - wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq); - - wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9); - - /* - * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME) - */ - wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6); - - /* - * set the clock detect feature to work in the restart wu procedure - * (ELP_CFG_MODE[14]) and Select the clock source type - * (ELP_CFG_MODE[13:12]) - */ - tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000; - wl1251_reg_write32(wl, ELP_CFG_MODE, tmp); - - /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */ - elp_cmd |= 0x00000040; - wl1251_reg_write32(wl, ELP_CMD, elp_cmd); - - /* PG 1.2: Set the BB PLL stable time to be 1000usec - * (PLL_STABLE_TIME) */ - wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20); - - /* PG 1.2: read clock request time */ - init_data = wl1251_reg_read32(wl, CLK_REQ_TIME); - - /* - * PG 1.2: set the clock request time to be ref_clk_settling_time - - * 1ms = 4ms - */ - if (init_data > 0x21) - tmp = init_data - 0x21; - else - tmp = 0; - wl1251_reg_write32(wl, CLK_REQ_TIME, tmp); - - /* set BB PLL configurations in RF AFE */ - wl1251_reg_write32(wl, 0x003058cc, 0x4B5); - - /* set RF_AFE_REG_5 */ - wl1251_reg_write32(wl, 0x003058d4, 0x50); - - /* set RF_AFE_CTRL_REG_2 */ - wl1251_reg_write32(wl, 0x00305948, 0x11c001); - - /* - * change RF PLL and BB PLL divider for VCO clock and adjust VCO - * bais current(RF_AFE_REG_13) - */ - wl1251_reg_write32(wl, 0x003058f4, 0x1e); - - /* set BB PLL configurations */ - tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000; - wl1251_reg_write32(wl, 0x00305840, tmp); - - /* set fractional divider according to Appendix C-BB PLL - * Calculations - */ - tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER]; - wl1251_reg_write32(wl, 0x00305844, tmp); - - /* set the initial data for the sigma delta */ - wl1251_reg_write32(wl, 0x00305848, 0x3039); - - /* - * set the accumulator attenuation value, calibration loop1 - * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and - * the VCO gain - */ - tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) | - (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1; - wl1251_reg_write32(wl, 0x00305854, tmp); - - /* - * set the calibration stop time after holdoff time expires and set - * settling time HOLD_OFF_TIME_BB - */ - tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000; - wl1251_reg_write32(wl, 0x00305858, tmp); - - /* - * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL - * constant leakage current to linearize PFD to 0uA - - * BB_ILOOPF[7:3] - */ - tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030; - wl1251_reg_write32(wl, 0x003058f8, tmp); - - /* - * set regulator output voltage for n divider to - * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2], - * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB - * PLL auto-call to normal mode- BB_CALGAIN_3DB[8] - */ - wl1251_reg_write32(wl, 0x003058f0, 0x29); - - /* enable restart wakeup sequence (ELP_CMD[0]) */ - wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1); - - /* restart sequence completed */ - udelay(2000); - - return 0; -} - -static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag) -{ - u32 cpu_ctrl; - - /* 10.5.0 run the firmware (I) */ - cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL); - - /* 10.5.1 run the firmware (II) */ - cpu_ctrl &= ~flag; - wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); -} - -int wl1251_boot_run_firmware(struct wl1251 *wl) -{ - int loop, ret; - u32 chip_id, acx_intr; - - wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); - - chip_id = wl1251_reg_read32(wl, CHIP_ID_B); - - wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); - - if (chip_id != wl->chip_id) { - wl1251_error("chip id doesn't match after firmware boot"); - return -EIO; - } - - /* wait for init to complete */ - loop = 0; - while (loop++ < INIT_LOOP) { - udelay(INIT_LOOP_DELAY); - acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - - if (acx_intr == 0xffffffff) { - wl1251_error("error reading hardware complete " - "init indication"); - return -EIO; - } - /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) { - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1251_ACX_INTR_INIT_COMPLETE); - break; - } - } - - if (loop > INIT_LOOP) { - wl1251_error("timeout waiting for the hardware to " - "complete initialization"); - return -EIO; - } - - /* get hardware config command mail box */ - wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR); - - /* get hardware config event mail box */ - wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR); - - /* set the working partition to its "running" mode offset */ - wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START, - WL1251_PART_WORK_MEM_SIZE, - WL1251_PART_WORK_REG_START, - WL1251_PART_WORK_REG_SIZE); - - wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", - wl->cmd_box_addr, wl->event_box_addr); - - wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver)); - - /* - * in case of full asynchronous mode the firmware event must be - * ready to receive event from the command mailbox - */ - - /* enable gpio interrupts */ - wl1251_enable_interrupts(wl); - - /* Enable target's interrupts */ - wl->intr_mask = WL1251_ACX_INTR_RX0_DATA | - WL1251_ACX_INTR_RX1_DATA | - WL1251_ACX_INTR_TX_RESULT | - WL1251_ACX_INTR_EVENT_A | - WL1251_ACX_INTR_EVENT_B | - WL1251_ACX_INTR_INIT_COMPLETE; - wl1251_boot_target_enable_interrupts(wl); - - wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID | - SYNCHRONIZATION_TIMEOUT_EVENT_ID | - ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | - ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | - REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | - BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; - - ret = wl1251_event_unmask(wl); - if (ret < 0) { - wl1251_error("EVENT mask setting failed"); - return ret; - } - - wl1251_event_mbox_config(wl); - - /* firmware startup completed */ - return 0; -} - -static int wl1251_boot_upload_firmware(struct wl1251 *wl) -{ - int addr, chunk_num, partition_limit; - size_t fw_data_len, len; - u8 *p, *buf; - - /* whal_FwCtrl_LoadFwImageSm() */ - - wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x", - wl1251_reg_read32(wl, CHIP_ID_B)); - - /* 10.0 check firmware length and set partition */ - fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) | - (wl->fw[6] << 8) | (wl->fw[7]); - - wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len, - CHUNK_SIZE); - - if ((fw_data_len % 4) != 0) { - wl1251_error("firmware length not multiple of four"); - return -EIO; - } - - buf = kmalloc(CHUNK_SIZE, GFP_KERNEL); - if (!buf) { - wl1251_error("allocation for firmware upload chunk failed"); - return -ENOMEM; - } - - wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, - WL1251_PART_DOWN_MEM_SIZE, - WL1251_PART_DOWN_REG_START, - WL1251_PART_DOWN_REG_SIZE); - - /* 10.1 set partition limit and chunk num */ - chunk_num = 0; - partition_limit = WL1251_PART_DOWN_MEM_SIZE; - - while (chunk_num < fw_data_len / CHUNK_SIZE) { - /* 10.2 update partition, if needed */ - addr = WL1251_PART_DOWN_MEM_START + - (chunk_num + 2) * CHUNK_SIZE; - if (addr > partition_limit) { - addr = WL1251_PART_DOWN_MEM_START + - chunk_num * CHUNK_SIZE; - partition_limit = chunk_num * CHUNK_SIZE + - WL1251_PART_DOWN_MEM_SIZE; - wl1251_set_partition(wl, - addr, - WL1251_PART_DOWN_MEM_SIZE, - WL1251_PART_DOWN_REG_START, - WL1251_PART_DOWN_REG_SIZE); - } - - /* 10.3 upload the chunk */ - addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; - p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; - wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", - p, addr); - - /* need to copy the chunk for dma */ - len = CHUNK_SIZE; - memcpy(buf, p, len); - wl1251_mem_write(wl, addr, buf, len); - - chunk_num++; - } - - /* 10.4 upload the last chunk */ - addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; - p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; - - /* need to copy the chunk for dma */ - len = fw_data_len % CHUNK_SIZE; - memcpy(buf, p, len); - - wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", - len, p, addr); - wl1251_mem_write(wl, addr, buf, len); - - kfree(buf); - - return 0; -} - -static int wl1251_boot_upload_nvs(struct wl1251 *wl) -{ - size_t nvs_len, nvs_bytes_written, burst_len; - int nvs_start, i; - u32 dest_addr, val; - u8 *nvs_ptr, *nvs; - - nvs = wl->nvs; - if (nvs == NULL) - return -ENODEV; - - nvs_ptr = nvs; - - nvs_len = wl->nvs_len; - nvs_start = wl->fw_len; - - /* - * Layout before the actual NVS tables: - * 1 byte : burst length. - * 2 bytes: destination address. - * n bytes: data to burst copy. - * - * This is ended by a 0 length, then the NVS tables. - */ - - while (nvs_ptr[0]) { - burst_len = nvs_ptr[0]; - dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); - - /* We move our pointer to the data */ - nvs_ptr += 3; - - for (i = 0; i < burst_len; i++) { - val = (nvs_ptr[0] | (nvs_ptr[1] << 8) - | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); - - wl1251_debug(DEBUG_BOOT, - "nvs burst write 0x%x: 0x%x", - dest_addr, val); - wl1251_mem_write32(wl, dest_addr, val); - - nvs_ptr += 4; - dest_addr += 4; - } - } - - /* - * We've reached the first zero length, the first NVS table - * is 7 bytes further. - */ - nvs_ptr += 7; - nvs_len -= nvs_ptr - nvs; - nvs_len = ALIGN(nvs_len, 4); - - /* Now we must set the partition correctly */ - wl1251_set_partition(wl, nvs_start, - WL1251_PART_DOWN_MEM_SIZE, - WL1251_PART_DOWN_REG_START, - WL1251_PART_DOWN_REG_SIZE); - - /* And finally we upload the NVS tables */ - nvs_bytes_written = 0; - while (nvs_bytes_written < nvs_len) { - val = (nvs_ptr[0] | (nvs_ptr[1] << 8) - | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); - - val = cpu_to_le32(val); - - wl1251_debug(DEBUG_BOOT, - "nvs write table 0x%x: 0x%x", - nvs_start, val); - wl1251_mem_write32(wl, nvs_start, val); - - nvs_ptr += 4; - nvs_bytes_written += 4; - nvs_start += 4; - } - - return 0; -} - -int wl1251_boot(struct wl1251 *wl) -{ - int ret = 0, minor_minor_e2_ver; - u32 tmp, boot_data; - - /* halt embedded ARM CPU while loading firmware */ - wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT); - - ret = wl1251_boot_soft_reset(wl); - if (ret < 0) - goto out; - - /* 2. start processing NVS file */ - if (wl->use_eeprom) { - wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); - /* Wait for EEPROM NVS burst read to complete */ - msleep(40); - wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); - } else { - ret = wl1251_boot_upload_nvs(wl); - if (ret < 0) - goto out; - - /* write firmware's last address (ie. it's length) to - * ACX_EEPROMLESS_IND_REG */ - wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); - } - - /* 6. read the EEPROM parameters */ - tmp = wl1251_reg_read32(wl, SCR_PAD2); - - /* 7. read bootdata */ - wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8; - wl->boot_attr.major = (tmp & 0x00FF0000) >> 16; - tmp = wl1251_reg_read32(wl, SCR_PAD3); - - /* 8. check bootdata and call restart sequence */ - wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16; - minor_minor_e2_ver = (tmp & 0xFF000000) >> 24; - - wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x " - "minorE2Ver 0x%x minor_minor_e2_ver 0x%x", - wl->boot_attr.radio_type, wl->boot_attr.major, - wl->boot_attr.minor, minor_minor_e2_ver); - - ret = wl1251_boot_init_seq(wl); - if (ret < 0) - goto out; - - /* 9. NVS processing done */ - boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL); - - wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data); - - /* 10. check that ECPU_CONTROL_HALT bits are set in - * pWhalBus->uBootData and start uploading firmware - */ - if ((boot_data & ECPU_CONTROL_HALT) == 0) { - wl1251_error("boot failed, ECPU_CONTROL_HALT not set"); - ret = -EIO; - goto out; - } - - ret = wl1251_boot_upload_firmware(wl); - if (ret < 0) - goto out; - - /* 10.5 start firmware */ - ret = wl1251_boot_run_firmware(wl); - if (ret < 0) - goto out; - -out: - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h deleted file mode 100644 index 7661bc5e4662..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_boot.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __BOOT_H__ -#define __BOOT_H__ - -#include "wl1251.h" - -int wl1251_boot_soft_reset(struct wl1251 *wl); -int wl1251_boot_init_seq(struct wl1251 *wl); -int wl1251_boot_run_firmware(struct wl1251 *wl); -void wl1251_boot_target_enable_interrupts(struct wl1251 *wl); -int wl1251_boot(struct wl1251 *wl); - -/* number of times we try to read the INIT interrupt */ -#define INIT_LOOP 20000 - -/* delay between retries */ -#define INIT_LOOP_DELAY 50 - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c deleted file mode 100644 index 15fb68c6b542..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.c +++ /dev/null @@ -1,496 +0,0 @@ -#include "wl1251_cmd.h" - -#include -#include -#include - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_ps.h" -#include "wl1251_acx.h" - -/** - * send command to firmware - * - * @wl: wl struct - * @id: command id - * @buf: buffer containing the command, must work with dma - * @len: length of the buffer - */ -int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len) -{ - struct wl1251_cmd_header *cmd; - unsigned long timeout; - u32 intr; - int ret = 0; - - cmd = buf; - cmd->id = id; - cmd->status = 0; - - WARN_ON(len % 4 != 0); - - wl1251_mem_write(wl, wl->cmd_box_addr, buf, len); - - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); - - timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT); - - intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) { - if (time_after(jiffies, timeout)) { - wl1251_error("command complete timeout"); - ret = -ETIMEDOUT; - goto out; - } - - msleep(1); - - intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - } - - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1251_ACX_INTR_CMD_COMPLETE); - -out: - return ret; -} - -/** - * send test command to firmware - * - * @wl: wl struct - * @buf: buffer containing the command, with all headers, must work with dma - * @len: length of the buffer - * @answer: is answer needed - */ -int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer) -{ - int ret; - - wl1251_debug(DEBUG_CMD, "cmd test"); - - ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len); - - if (ret < 0) { - wl1251_warning("TEST command failed"); - return ret; - } - - if (answer) { - struct wl1251_command *cmd_answer; - - /* - * The test command got in, we can read the answer. - * The answer would be a wl1251_command, where the - * parameter array contains the actual answer. - */ - wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len); - - cmd_answer = buf; - - if (cmd_answer->header.status != CMD_STATUS_SUCCESS) - wl1251_error("TEST command answer error: %d", - cmd_answer->header.status); - } - - return 0; -} - -/** - * read acx from firmware - * - * @wl: wl struct - * @id: acx id - * @buf: buffer for the response, including all headers, must work with dma - * @len: lenght of buf - */ -int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1251_debug(DEBUG_CMD, "cmd interrogate"); - - acx->id = id; - - /* payload length, does not include any headers */ - acx->len = len - sizeof(*acx); - - ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx)); - if (ret < 0) { - wl1251_error("INTERROGATE command failed"); - goto out; - } - - /* the interrogate command got in, we can read the answer */ - wl1251_mem_read(wl, wl->cmd_box_addr, buf, len); - - acx = buf; - if (acx->cmd.status != CMD_STATUS_SUCCESS) - wl1251_error("INTERROGATE command error: %d", - acx->cmd.status); - -out: - return ret; -} - -/** - * write acx value to firmware - * - * @wl: wl struct - * @id: acx id - * @buf: buffer containing acx, including all headers, must work with dma - * @len: length of buf - */ -int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1251_debug(DEBUG_CMD, "cmd configure"); - - acx->id = id; - - /* payload length, does not include any headers */ - acx->len = len - sizeof(*acx); - - ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len); - if (ret < 0) { - wl1251_warning("CONFIGURE command NOK"); - return ret; - } - - return 0; -} - -int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, - void *bitmap, u16 bitmap_len, u8 bitmap_control) -{ - struct wl1251_cmd_vbm_update *vbm; - int ret; - - wl1251_debug(DEBUG_CMD, "cmd vbm"); - - vbm = kzalloc(sizeof(*vbm), GFP_KERNEL); - if (!vbm) { - ret = -ENOMEM; - goto out; - } - - /* Count and period will be filled by the target */ - vbm->tim.bitmap_ctrl = bitmap_control; - if (bitmap_len > PARTIAL_VBM_MAX) { - wl1251_warning("cmd vbm len is %d B, truncating to %d", - bitmap_len, PARTIAL_VBM_MAX); - bitmap_len = PARTIAL_VBM_MAX; - } - memcpy(vbm->tim.pvb_field, bitmap, bitmap_len); - vbm->tim.identity = identity; - vbm->tim.length = bitmap_len + 3; - - vbm->len = cpu_to_le16(bitmap_len + 5); - - ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm)); - if (ret < 0) { - wl1251_error("VBM command failed"); - goto out; - } - -out: - kfree(vbm); - return ret; -} - -int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) -{ - struct cmd_enabledisable_path *cmd; - int ret; - u16 cmd_rx, cmd_tx; - - wl1251_debug(DEBUG_CMD, "cmd data path"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->channel = channel; - - if (enable) { - cmd_rx = CMD_ENABLE_RX; - cmd_tx = CMD_ENABLE_TX; - } else { - cmd_rx = CMD_DISABLE_RX; - cmd_tx = CMD_DISABLE_TX; - } - - ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); - if (ret < 0) { - wl1251_error("rx %s cmd for channel %d failed", - enable ? "start" : "stop", channel); - goto out; - } - - wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", - enable ? "start" : "stop", channel); - - ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); - if (ret < 0) { - wl1251_error("tx %s cmd for channel %d failed", - enable ? "start" : "stop", channel); - return ret; - } - - wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", - enable ? "start" : "stop", channel); - -out: - kfree(cmd); - return ret; -} - -int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, - u16 beacon_interval, u8 dtim_interval) -{ - struct cmd_join *join; - int ret, i; - u8 *bssid; - - join = kzalloc(sizeof(*join), GFP_KERNEL); - if (!join) { - ret = -ENOMEM; - goto out; - } - - wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d", - bss_type == BSS_TYPE_IBSS ? " ibss" : "", - channel, beacon_interval, dtim_interval); - - /* Reverse order BSSID */ - bssid = (u8 *) &join->bssid_lsb; - for (i = 0; i < ETH_ALEN; i++) - bssid[i] = wl->bssid[ETH_ALEN - i - 1]; - - join->rx_config_options = wl->rx_config; - join->rx_filter_options = wl->rx_filter; - - /* - * FIXME: disable temporarily all filters because after commit - * 9cef8737 "mac80211: fix managed mode BSSID handling" broke - * association. The filter logic needs to be implemented properly - * and once that is done, this hack can be removed. - */ - join->rx_config_options = 0; - join->rx_filter_options = WL1251_DEFAULT_RX_FILTER; - - join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | - RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; - - join->beacon_interval = beacon_interval; - join->dtim_interval = dtim_interval; - join->bss_type = bss_type; - join->channel = channel; - join->ctrl = JOIN_CMD_CTRL_TX_FLUSH; - - ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join)); - if (ret < 0) { - wl1251_error("failed to initiate cmd join"); - goto out; - } - -out: - kfree(join); - return ret; -} - -int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode) -{ - struct wl1251_cmd_ps_params *ps_params = NULL; - int ret = 0; - - wl1251_debug(DEBUG_CMD, "cmd set ps mode"); - - ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); - if (!ps_params) { - ret = -ENOMEM; - goto out; - } - - ps_params->ps_mode = ps_mode; - ps_params->send_null_data = 1; - ps_params->retries = 5; - ps_params->hang_over_period = 128; - ps_params->null_data_rate = 1; /* 1 Mbps */ - - ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params, - sizeof(*ps_params)); - if (ret < 0) { - wl1251_error("cmd set_ps_mode failed"); - goto out; - } - -out: - kfree(ps_params); - return ret; -} - -int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, - size_t len) -{ - struct cmd_read_write_memory *cmd; - int ret = 0; - - wl1251_debug(DEBUG_CMD, "cmd read memory"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - WARN_ON(len > MAX_READ_SIZE); - len = min_t(size_t, len, MAX_READ_SIZE); - - cmd->addr = addr; - cmd->size = len; - - ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd)); - if (ret < 0) { - wl1251_error("read memory command failed: %d", ret); - goto out; - } - - /* the read command got in, we can now read the answer */ - wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); - - if (cmd->header.status != CMD_STATUS_SUCCESS) - wl1251_error("error in read command result: %d", - cmd->header.status); - - memcpy(answer, cmd->value, len); - -out: - kfree(cmd); - return ret; -} - -int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, - void *buf, size_t buf_len) -{ - struct wl1251_cmd_packet_template *cmd; - size_t cmd_len; - int ret = 0; - - wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id); - - WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE); - buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE); - cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4); - - cmd = kzalloc(cmd_len, GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->size = cpu_to_le16(buf_len); - - if (buf) - memcpy(cmd->data, buf, buf_len); - - ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len); - if (ret < 0) { - wl1251_warning("cmd set_template failed: %d", ret); - goto out; - } - -out: - kfree(cmd); - return ret; -} - -int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, - struct ieee80211_channel *channels[], - unsigned int n_channels, unsigned int n_probes) -{ - struct wl1251_cmd_scan *cmd; - int i, ret = 0; - - wl1251_debug(DEBUG_CMD, "cmd scan"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); - cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN | - CFG_RX_MGMT_EN | - CFG_RX_BCN_EN); - cmd->params.scan_options = 0; - cmd->params.num_channels = n_channels; - cmd->params.num_probe_requests = n_probes; - cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ - cmd->params.tid_trigger = 0; - - for (i = 0; i < n_channels; i++) { - cmd->channels[i].min_duration = - cpu_to_le32(WL1251_SCAN_MIN_DURATION); - cmd->channels[i].max_duration = - cpu_to_le32(WL1251_SCAN_MAX_DURATION); - memset(&cmd->channels[i].bssid_lsb, 0xff, 4); - memset(&cmd->channels[i].bssid_msb, 0xff, 2); - cmd->channels[i].early_termination = 0; - cmd->channels[i].tx_power_att = 0; - cmd->channels[i].channel = channels[i]->hw_value; - } - - cmd->params.ssid_len = ssid_len; - if (ssid) - memcpy(cmd->params.ssid, ssid, ssid_len); - - ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); - if (ret < 0) { - wl1251_error("cmd scan failed: %d", ret); - goto out; - } - - wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); - - if (cmd->header.status != CMD_STATUS_SUCCESS) { - wl1251_error("cmd scan status wasn't success: %d", - cmd->header.status); - ret = -EIO; - goto out; - } - -out: - kfree(cmd); - return ret; -} - -int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout) -{ - struct wl1251_cmd_trigger_scan_to *cmd; - int ret; - - wl1251_debug(DEBUG_CMD, "cmd trigger scan to"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->timeout = timeout; - - ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd)); - if (ret < 0) { - wl1251_error("cmd trigger scan to failed: %d", ret); - goto out; - } - -out: - kfree(cmd); - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h deleted file mode 100644 index e5c74c631374..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_CMD_H__ -#define __WL1251_CMD_H__ - -#include "wl1251.h" - -#include - -struct acx_header; - -int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len); -int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer); -int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len); -int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); -int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, - void *bitmap, u16 bitmap_len, u8 bitmap_control); -int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable); -int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, - u16 beacon_interval, u8 dtim_interval); -int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); -int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer, - size_t len); -int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, - void *buf, size_t buf_len); -int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, - struct ieee80211_channel *channels[], - unsigned int n_channels, unsigned int n_probes); -int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout); - -/* unit ms */ -#define WL1251_COMMAND_TIMEOUT 2000 - -enum wl1251_commands { - CMD_RESET = 0, - CMD_INTERROGATE = 1, /*use this to read information elements*/ - CMD_CONFIGURE = 2, /*use this to write information elements*/ - CMD_ENABLE_RX = 3, - CMD_ENABLE_TX = 4, - CMD_DISABLE_RX = 5, - CMD_DISABLE_TX = 6, - CMD_SCAN = 8, - CMD_STOP_SCAN = 9, - CMD_VBM = 10, - CMD_START_JOIN = 11, - CMD_SET_KEYS = 12, - CMD_READ_MEMORY = 13, - CMD_WRITE_MEMORY = 14, - CMD_BEACON = 19, - CMD_PROBE_RESP = 20, - CMD_NULL_DATA = 21, - CMD_PROBE_REQ = 22, - CMD_TEST = 23, - CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */ - CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */ - CMD_NOISE_HIST = 28, - CMD_RX_RESET = 29, - CMD_PS_POLL = 30, - CMD_QOS_NULL_DATA = 31, - CMD_LNA_CONTROL = 32, - CMD_SET_BCN_MODE = 33, - CMD_MEASUREMENT = 34, - CMD_STOP_MEASUREMENT = 35, - CMD_DISCONNECT = 36, - CMD_SET_PS_MODE = 37, - CMD_CHANNEL_SWITCH = 38, - CMD_STOP_CHANNEL_SWICTH = 39, - CMD_AP_DISCOVERY = 40, - CMD_STOP_AP_DISCOVERY = 41, - CMD_SPS_SCAN = 42, - CMD_STOP_SPS_SCAN = 43, - CMD_HEALTH_CHECK = 45, - CMD_DEBUG = 46, - CMD_TRIGGER_SCAN_TO = 47, - - NUM_COMMANDS, - MAX_COMMAND_ID = 0xFFFF, -}; - -#define MAX_CMD_PARAMS 572 - -struct wl1251_cmd_header { - u16 id; - u16 status; - /* payload */ - u8 data[0]; -} __packed; - -struct wl1251_command { - struct wl1251_cmd_header header; - u8 parameters[MAX_CMD_PARAMS]; -} __packed; - -enum { - CMD_MAILBOX_IDLE = 0, - CMD_STATUS_SUCCESS = 1, - CMD_STATUS_UNKNOWN_CMD = 2, - CMD_STATUS_UNKNOWN_IE = 3, - CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11, - CMD_STATUS_RX_BUSY = 13, - CMD_STATUS_INVALID_PARAM = 14, - CMD_STATUS_TEMPLATE_TOO_LARGE = 15, - CMD_STATUS_OUT_OF_MEMORY = 16, - CMD_STATUS_STA_TABLE_FULL = 17, - CMD_STATUS_RADIO_ERROR = 18, - CMD_STATUS_WRONG_NESTING = 19, - CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/ - CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/ - MAX_COMMAND_STATUS = 0xff -}; - - -/* - * CMD_READ_MEMORY - * - * The host issues this command to read the WiLink device memory/registers. - * - * Note: The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -/* - * CMD_WRITE_MEMORY - * - * The host issues this command to write the WiLink device memory/registers. - * - * The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -#define MAX_READ_SIZE 256 - -struct cmd_read_write_memory { - struct wl1251_cmd_header header; - - /* The address of the memory to read from or write to.*/ - u32 addr; - - /* The amount of data in bytes to read from or write to the WiLink - * device.*/ - u32 size; - - /* The actual value read from or written to the Wilink. The source - of this field is the Host in WRITE command or the Wilink in READ - command. */ - u8 value[MAX_READ_SIZE]; -} __packed; - -#define CMDMBOX_HEADER_LEN 4 -#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 - -#define WL1251_SCAN_MIN_DURATION 30000 -#define WL1251_SCAN_MAX_DURATION 60000 - -#define WL1251_SCAN_NUM_PROBES 3 - -struct wl1251_scan_parameters { - __le32 rx_config_options; - __le32 rx_filter_options; - - /* - * Scan options: - * bit 0: When this bit is set, passive scan. - * bit 1: Band, when this bit is set we scan - * in the 5Ghz band. - * bit 2: voice mode, 0 for normal scan. - * bit 3: scan priority, 1 for high priority. - */ - __le16 scan_options; - - /* Number of channels to scan */ - u8 num_channels; - - /* Number opf probe requests to send, per channel */ - u8 num_probe_requests; - - /* Rate and modulation for probe requests */ - __le16 tx_rate; - - u8 tid_trigger; - u8 ssid_len; - u8 ssid[32]; - -} __packed; - -struct wl1251_scan_ch_parameters { - __le32 min_duration; /* in TU */ - __le32 max_duration; /* in TU */ - u32 bssid_lsb; - u16 bssid_msb; - - /* - * bits 0-3: Early termination count. - * bits 4-5: Early termination condition. - */ - u8 early_termination; - - u8 tx_power_att; - u8 channel; - u8 pad[3]; -} __packed; - -/* SCAN parameters */ -#define SCAN_MAX_NUM_OF_CHANNELS 16 - -struct wl1251_cmd_scan { - struct wl1251_cmd_header header; - - struct wl1251_scan_parameters params; - struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; -} __packed; - -enum { - BSS_TYPE_IBSS = 0, - BSS_TYPE_STA_BSS = 2, - BSS_TYPE_AP_BSS = 3, - MAX_BSS_TYPE = 0xFF -}; - -#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */ -#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */ - - -struct cmd_join { - struct wl1251_cmd_header header; - - u32 bssid_lsb; - u16 bssid_msb; - u16 beacon_interval; /* in TBTTs */ - u32 rx_config_options; - u32 rx_filter_options; - - /* - * The target uses this field to determine the rate at - * which to transmit control frame responses (such as - * ACK or CTS frames). - */ - u16 basic_rate_set; - u8 dtim_interval; - u8 tx_ctrl_frame_rate; /* OBSOLETE */ - u8 tx_ctrl_frame_mod; /* OBSOLETE */ - /* - * bits 0-2: This bitwise field specifies the type - * of BSS to start or join (BSS_TYPE_*). - * bit 4: Band - The radio band in which to join - * or start. - * 0 - 2.4GHz band - * 1 - 5GHz band - * bits 3, 5-7: Reserved - */ - u8 bss_type; - u8 channel; - u8 ssid_len; - u8 ssid[IW_ESSID_MAX_SIZE]; - u8 ctrl; /* JOIN_CMD_CTRL_* */ - u8 tx_mgt_frame_rate; /* OBSOLETE */ - u8 tx_mgt_frame_mod; /* OBSOLETE */ - u8 reserved; -} __packed; - -struct cmd_enabledisable_path { - struct wl1251_cmd_header header; - - u8 channel; - u8 padding[3]; -} __packed; - -#define WL1251_MAX_TEMPLATE_SIZE 300 - -struct wl1251_cmd_packet_template { - struct wl1251_cmd_header header; - - __le16 size; - u8 data[0]; -} __packed; - -#define TIM_ELE_ID 5 -#define PARTIAL_VBM_MAX 251 - -struct wl1251_tim { - u8 identity; - u8 length; - u8 dtim_count; - u8 dtim_period; - u8 bitmap_ctrl; - u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ -} __packed; - -/* Virtual Bit Map update */ -struct wl1251_cmd_vbm_update { - struct wl1251_cmd_header header; - __le16 len; - u8 padding[2]; - struct wl1251_tim tim; -} __packed; - -enum wl1251_cmd_ps_mode { - STATION_ACTIVE_MODE, - STATION_POWER_SAVE_MODE -}; - -struct wl1251_cmd_ps_params { - struct wl1251_cmd_header header; - - u8 ps_mode; /* STATION_* */ - u8 send_null_data; /* Do we have to send NULL data packet ? */ - u8 retries; /* Number of retires for the initial NULL data packet */ - - /* - * TUs during which the target stays awake after switching - * to power save mode. - */ - u8 hang_over_period; - u16 null_data_rate; - u8 pad[2]; -} __packed; - -struct wl1251_cmd_trigger_scan_to { - struct wl1251_cmd_header header; - - u32 timeout; -} __packed; - -/* HW encryption keys */ -#define NUM_ACCESS_CATEGORIES_COPY 4 -#define MAX_KEY_SIZE 32 - -/* When set, disable HW encryption */ -#define DF_ENCRYPTION_DISABLE 0x01 -/* When set, disable HW decryption */ -#define DF_SNIFF_MODE_ENABLE 0x80 - -enum wl1251_cmd_key_action { - KEY_ADD_OR_REPLACE = 1, - KEY_REMOVE = 2, - KEY_SET_ID = 3, - MAX_KEY_ACTION = 0xffff, -}; - -enum wl1251_cmd_key_type { - KEY_WEP_DEFAULT = 0, - KEY_WEP_ADDR = 1, - KEY_AES_GROUP = 4, - KEY_AES_PAIRWISE = 5, - KEY_WEP_GROUP = 6, - KEY_TKIP_MIC_GROUP = 10, - KEY_TKIP_MIC_PAIRWISE = 11, -}; - -/* - * - * key_type_e key size key format - * ---------- --------- ---------- - * 0x00 5, 13, 29 Key data - * 0x01 5, 13, 29 Key data - * 0x04 16 16 bytes of key data - * 0x05 16 16 bytes of key data - * 0x0a 32 16 bytes of TKIP key data - * 8 bytes of RX MIC key data - * 8 bytes of TX MIC key data - * 0x0b 32 16 bytes of TKIP key data - * 8 bytes of RX MIC key data - * 8 bytes of TX MIC key data - * - */ - -struct wl1251_cmd_set_keys { - struct wl1251_cmd_header header; - - /* Ignored for default WEP key */ - u8 addr[ETH_ALEN]; - - /* key_action_e */ - u16 key_action; - - u16 reserved_1; - - /* key size in bytes */ - u8 key_size; - - /* key_type_e */ - u8 key_type; - u8 ssid_profile; - - /* - * TKIP, AES: frame's key id field. - * For WEP default key: key id; - */ - u8 id; - u8 reserved_2[6]; - u8 key[MAX_KEY_SIZE]; - u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; - u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; -} __packed; - - -#endif /* __WL1251_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c deleted file mode 100644 index 6ffe4cd58561..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1251_debugfs.h" - -#include -#include - -#include "wl1251.h" -#include "wl1251_acx.h" -#include "wl1251_ps.h" - -/* ms */ -#define WL1251_DEBUGFS_STATS_LIFETIME 1000 - -/* debugfs macros idea from mac80211 */ - -#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ -static ssize_t name## _read(struct file *file, char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1251 *wl = file->private_data; \ - char buf[buflen]; \ - int res; \ - \ - res = scnprintf(buf, buflen, fmt "\n", ##value); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ -} \ - \ -static const struct file_operations name## _ops = { \ - .read = name## _read, \ - .open = wl1251_open_file_generic, \ -}; - -#define DEBUGFS_ADD(name, parent) \ - wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ - wl, &name## _ops); \ - if (IS_ERR(wl->debugfs.name)) { \ - ret = PTR_ERR(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - goto out; \ - } - -#define DEBUGFS_DEL(name) \ - do { \ - debugfs_remove(wl->debugfs.name); \ - wl->debugfs.name = NULL; \ - } while (0) - -#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \ -static ssize_t sub## _ ##name## _read(struct file *file, \ - char __user *userbuf, \ - size_t count, loff_t *ppos) \ -{ \ - struct wl1251 *wl = file->private_data; \ - char buf[buflen]; \ - int res; \ - \ - wl1251_debugfs_update_stats(wl); \ - \ - res = scnprintf(buf, buflen, fmt "\n", \ - wl->stats.fw_stats->sub.name); \ - return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ -} \ - \ -static const struct file_operations sub## _ ##name## _ops = { \ - .read = sub## _ ##name## _read, \ - .open = wl1251_open_file_generic, \ -}; - -#define DEBUGFS_FWSTATS_ADD(sub, name) \ - DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) - -#define DEBUGFS_FWSTATS_DEL(sub, name) \ - DEBUGFS_DEL(sub## _ ##name) - -static void wl1251_debugfs_update_stats(struct wl1251 *wl) -{ - int ret; - - mutex_lock(&wl->mutex); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - if (wl->state == WL1251_STATE_ON && - time_after(jiffies, wl->stats.fw_stats_update + - msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) { - wl1251_acx_statistics(wl, wl->stats.fw_stats); - wl->stats.fw_stats_update = jiffies; - } - - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1251_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u"); -DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u"); -DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u"); -/* skipping wep.reserved */ -DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u"); -DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u"); -/* skipping cont_miss_bcns_spread for now */ -DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u"); -DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u"); -DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u"); -DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u"); - -DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, - 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u"); -DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u"); - -DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count); -DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u", - wl->stats.excessive_retries); - -static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct wl1251 *wl = file->private_data; - u32 queue_len; - char buf[20]; - int res; - - queue_len = skb_queue_len(&wl->tx_queue); - - res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); - return simple_read_from_buffer(userbuf, count, ppos, buf, res); -} - -static const struct file_operations tx_queue_len_ops = { - .read = tx_queue_len_read, - .open = wl1251_open_file_generic, -}; - -static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct wl1251 *wl = file->private_data; - char buf[3], status; - int len; - - if (wl->tx_queue_stopped) - status = 's'; - else - status = 'r'; - - len = scnprintf(buf, sizeof(buf), "%c\n", status); - return simple_read_from_buffer(userbuf, count, ppos, buf, len); -} - -static const struct file_operations tx_queue_status_ops = { - .read = tx_queue_status_read, - .open = wl1251_open_file_generic, -}; - -static void wl1251_debugfs_delete_files(struct wl1251 *wl) -{ - DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_DEL(rx, out_of_mem); - DEBUGFS_FWSTATS_DEL(rx, hdr_overflow); - DEBUGFS_FWSTATS_DEL(rx, hw_stuck); - DEBUGFS_FWSTATS_DEL(rx, dropped); - DEBUGFS_FWSTATS_DEL(rx, fcs_err); - DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_DEL(rx, path_reset); - DEBUGFS_FWSTATS_DEL(rx, reset_counter); - - DEBUGFS_FWSTATS_DEL(dma, rx_requested); - DEBUGFS_FWSTATS_DEL(dma, rx_errors); - DEBUGFS_FWSTATS_DEL(dma, tx_requested); - DEBUGFS_FWSTATS_DEL(dma, tx_errors); - - DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt); - DEBUGFS_FWSTATS_DEL(isr, fiqs); - DEBUGFS_FWSTATS_DEL(isr, rx_headers); - DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_DEL(isr, rx_rdys); - DEBUGFS_FWSTATS_DEL(isr, irqs); - DEBUGFS_FWSTATS_DEL(isr, tx_procs); - DEBUGFS_FWSTATS_DEL(isr, decrypt_done); - DEBUGFS_FWSTATS_DEL(isr, dma0_done); - DEBUGFS_FWSTATS_DEL(isr, dma1_done); - DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete); - DEBUGFS_FWSTATS_DEL(isr, commands); - DEBUGFS_FWSTATS_DEL(isr, rx_procs); - DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_DEL(isr, host_acknowledges); - DEBUGFS_FWSTATS_DEL(isr, pci_pm); - DEBUGFS_FWSTATS_DEL(isr, wakeups); - DEBUGFS_FWSTATS_DEL(isr, low_rssi); - - DEBUGFS_FWSTATS_DEL(wep, addr_key_count); - DEBUGFS_FWSTATS_DEL(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_DEL(wep, key_not_found); - DEBUGFS_FWSTATS_DEL(wep, decrypt_fail); - DEBUGFS_FWSTATS_DEL(wep, packets); - DEBUGFS_FWSTATS_DEL(wep, interrupt); - - DEBUGFS_FWSTATS_DEL(pwr, ps_enter); - DEBUGFS_FWSTATS_DEL(pwr, elp_enter); - DEBUGFS_FWSTATS_DEL(pwr, missing_bcns); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_host); - DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps); - DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps); - DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_DEL(pwr, power_save_off); - DEBUGFS_FWSTATS_DEL(pwr, enable_ps); - DEBUGFS_FWSTATS_DEL(pwr, disable_ps); - DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_DEL(mic, rx_pkts); - DEBUGFS_FWSTATS_DEL(mic, calc_failure); - - DEBUGFS_FWSTATS_DEL(aes, encrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, decrypt_fail); - DEBUGFS_FWSTATS_DEL(aes, encrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, decrypt_packets); - DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_DEL(event, heart_beat); - DEBUGFS_FWSTATS_DEL(event, calibration); - DEBUGFS_FWSTATS_DEL(event, rx_mismatch); - DEBUGFS_FWSTATS_DEL(event, rx_mem_empty); - DEBUGFS_FWSTATS_DEL(event, rx_pool); - DEBUGFS_FWSTATS_DEL(event, oom_late); - DEBUGFS_FWSTATS_DEL(event, phy_transmit_error); - DEBUGFS_FWSTATS_DEL(event, tx_stuck); - - DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization); - DEBUGFS_FWSTATS_DEL(ps, upsd_utilization); - - DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data); - - DEBUGFS_DEL(tx_queue_len); - DEBUGFS_DEL(tx_queue_status); - DEBUGFS_DEL(retry_count); - DEBUGFS_DEL(excessive_retries); -} - -static int wl1251_debugfs_add_files(struct wl1251 *wl) -{ - int ret = 0; - - DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); - - DEBUGFS_FWSTATS_ADD(rx, out_of_mem); - DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); - DEBUGFS_FWSTATS_ADD(rx, hw_stuck); - DEBUGFS_FWSTATS_ADD(rx, dropped); - DEBUGFS_FWSTATS_ADD(rx, fcs_err); - DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); - DEBUGFS_FWSTATS_ADD(rx, path_reset); - DEBUGFS_FWSTATS_ADD(rx, reset_counter); - - DEBUGFS_FWSTATS_ADD(dma, rx_requested); - DEBUGFS_FWSTATS_ADD(dma, rx_errors); - DEBUGFS_FWSTATS_ADD(dma, tx_requested); - DEBUGFS_FWSTATS_ADD(dma, tx_errors); - - DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); - DEBUGFS_FWSTATS_ADD(isr, fiqs); - DEBUGFS_FWSTATS_ADD(isr, rx_headers); - DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); - DEBUGFS_FWSTATS_ADD(isr, rx_rdys); - DEBUGFS_FWSTATS_ADD(isr, irqs); - DEBUGFS_FWSTATS_ADD(isr, tx_procs); - DEBUGFS_FWSTATS_ADD(isr, decrypt_done); - DEBUGFS_FWSTATS_ADD(isr, dma0_done); - DEBUGFS_FWSTATS_ADD(isr, dma1_done); - DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); - DEBUGFS_FWSTATS_ADD(isr, commands); - DEBUGFS_FWSTATS_ADD(isr, rx_procs); - DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); - DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); - DEBUGFS_FWSTATS_ADD(isr, pci_pm); - DEBUGFS_FWSTATS_ADD(isr, wakeups); - DEBUGFS_FWSTATS_ADD(isr, low_rssi); - - DEBUGFS_FWSTATS_ADD(wep, addr_key_count); - DEBUGFS_FWSTATS_ADD(wep, default_key_count); - /* skipping wep.reserved */ - DEBUGFS_FWSTATS_ADD(wep, key_not_found); - DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); - DEBUGFS_FWSTATS_ADD(wep, packets); - DEBUGFS_FWSTATS_ADD(wep, interrupt); - - DEBUGFS_FWSTATS_ADD(pwr, ps_enter); - DEBUGFS_FWSTATS_ADD(pwr, elp_enter); - DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); - DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); - DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); - DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); - DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); - DEBUGFS_FWSTATS_ADD(pwr, power_save_off); - DEBUGFS_FWSTATS_ADD(pwr, enable_ps); - DEBUGFS_FWSTATS_ADD(pwr, disable_ps); - DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); - /* skipping cont_miss_bcns_spread for now */ - DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); - - DEBUGFS_FWSTATS_ADD(mic, rx_pkts); - DEBUGFS_FWSTATS_ADD(mic, calc_failure); - - DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); - DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); - DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); - DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); - - DEBUGFS_FWSTATS_ADD(event, heart_beat); - DEBUGFS_FWSTATS_ADD(event, calibration); - DEBUGFS_FWSTATS_ADD(event, rx_mismatch); - DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); - DEBUGFS_FWSTATS_ADD(event, rx_pool); - DEBUGFS_FWSTATS_ADD(event, oom_late); - DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); - DEBUGFS_FWSTATS_ADD(event, tx_stuck); - - DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); - DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); - DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); - DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); - - DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); - DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); - DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); - - DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); - DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir); - DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); - DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); - -out: - if (ret < 0) - wl1251_debugfs_delete_files(wl); - - return ret; -} - -void wl1251_debugfs_reset(struct wl1251 *wl) -{ - if (wl->stats.fw_stats != NULL) - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); - wl->stats.retry_count = 0; - wl->stats.excessive_retries = 0; -} - -int wl1251_debugfs_init(struct wl1251 *wl) -{ - int ret; - - wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); - - if (IS_ERR(wl->debugfs.rootdir)) { - ret = PTR_ERR(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - goto err; - } - - wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics", - wl->debugfs.rootdir); - - if (IS_ERR(wl->debugfs.fw_statistics)) { - ret = PTR_ERR(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - goto err_root; - } - - wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), - GFP_KERNEL); - - if (!wl->stats.fw_stats) { - ret = -ENOMEM; - goto err_fw; - } - - wl->stats.fw_stats_update = jiffies; - - ret = wl1251_debugfs_add_files(wl); - - if (ret < 0) - goto err_file; - - return 0; - -err_file: - kfree(wl->stats.fw_stats); - wl->stats.fw_stats = NULL; - -err_fw: - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - -err_root: - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - -err: - return ret; -} - -void wl1251_debugfs_exit(struct wl1251 *wl) -{ - wl1251_debugfs_delete_files(wl); - - kfree(wl->stats.fw_stats); - wl->stats.fw_stats = NULL; - - debugfs_remove(wl->debugfs.fw_statistics); - wl->debugfs.fw_statistics = NULL; - - debugfs_remove(wl->debugfs.rootdir); - wl->debugfs.rootdir = NULL; - -} diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h deleted file mode 100644 index b3417c02a218..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef WL1251_DEBUGFS_H -#define WL1251_DEBUGFS_H - -#include "wl1251.h" - -int wl1251_debugfs_init(struct wl1251 *wl); -void wl1251_debugfs_exit(struct wl1251 *wl); -void wl1251_debugfs_reset(struct wl1251 *wl); - -#endif /* WL1251_DEBUGFS_H */ diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c deleted file mode 100644 index 54223556b308..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_event.h" -#include "wl1251_ps.h" - -static int wl1251_event_scan_complete(struct wl1251 *wl, - struct event_mailbox *mbox) -{ - wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d", - mbox->scheduled_scan_status, - mbox->scheduled_scan_channels); - - if (wl->scanning) { - ieee80211_scan_completed(wl->hw, false); - wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); - wl->scanning = false; - } - - return 0; -} - -static void wl1251_event_mbox_dump(struct event_mailbox *mbox) -{ - wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); - wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); - wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); -} - -static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) -{ - int ret; - u32 vector; - - wl1251_event_mbox_dump(mbox); - - vector = mbox->events_vector & ~(mbox->events_mask); - wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector); - - if (vector & SCAN_COMPLETE_EVENT_ID) { - ret = wl1251_event_scan_complete(wl, mbox); - if (ret < 0) - return ret; - } - - if (vector & BSS_LOSE_EVENT_ID) { - wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); - - if (wl->psm_requested && wl->psm) { - ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); - if (ret < 0) - return ret; - } - } - - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { - wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); - - /* indicate to the stack, that beacons have been lost */ - ieee80211_beacon_loss(wl->vif); - } - - if (vector & REGAINED_BSS_EVENT_ID) { - if (wl->psm_requested) { - ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); - if (ret < 0) - return ret; - } - } - - return 0; -} - -/* - * Poll the mailbox event field until any of the bits in the mask is set or a - * timeout occurs (WL1251_EVENT_TIMEOUT in msecs) - */ -int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms) -{ - u32 events_vector, event; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(timeout_ms); - - do { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - - msleep(1); - - /* read from both event fields */ - wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector, - sizeof(events_vector)); - event = events_vector & mask; - wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector, - sizeof(events_vector)); - event |= events_vector & mask; - } while (!event); - - return 0; -} - -int wl1251_event_unmask(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask)); - if (ret < 0) - return ret; - - return 0; -} - -void wl1251_event_mbox_config(struct wl1251 *wl) -{ - wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR); - wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); - - wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", - wl->mbox_ptr[0], wl->mbox_ptr[1]); -} - -int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num) -{ - struct event_mailbox mbox; - int ret; - - wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); - - if (mbox_num > 1) - return -EINVAL; - - /* first we read the mbox descriptor */ - wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox, - sizeof(struct event_mailbox)); - - /* process the descriptor */ - ret = wl1251_event_process(wl, &mbox); - if (ret < 0) - return ret; - - /* then we let the firmware know it can go on...*/ - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); - - return 0; -} diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h deleted file mode 100644 index 30eb5d150bf7..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_event.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_EVENT_H__ -#define __WL1251_EVENT_H__ - -/* - * Mbox events - * - * The event mechanism is based on a pair of event buffers (buffers A and - * B) at fixed locations in the target's memory. The host processes one - * buffer while the other buffer continues to collect events. If the host - * is not processing events, an interrupt is issued to signal that a buffer - * is ready. Once the host is done with processing events from one buffer, - * it signals the target (with an ACK interrupt) that the event buffer is - * free. - */ - -enum { - RESERVED1_EVENT_ID = BIT(0), - RESERVED2_EVENT_ID = BIT(1), - MEASUREMENT_START_EVENT_ID = BIT(2), - SCAN_COMPLETE_EVENT_ID = BIT(3), - CALIBRATION_COMPLETE_EVENT_ID = BIT(4), - ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5), - PS_REPORT_EVENT_ID = BIT(6), - SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7), - HEALTH_REPORT_EVENT_ID = BIT(8), - ACI_DETECTION_EVENT_ID = BIT(9), - DEBUG_REPORT_EVENT_ID = BIT(10), - MAC_STATUS_EVENT_ID = BIT(11), - DISCONNECT_EVENT_COMPLETE_ID = BIT(12), - JOIN_EVENT_COMPLETE_ID = BIT(13), - CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14), - BSS_LOSE_EVENT_ID = BIT(15), - ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16), - MEASUREMENT_COMPLETE_EVENT_ID = BIT(17), - AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18), - SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19), - PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20), - RESET_BSS_EVENT_ID = BIT(21), - REGAINED_BSS_EVENT_ID = BIT(22), - ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23), - ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24), - ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25), - - DBG_EVENT_ID = BIT(26), - BT_PTA_SENSE_EVENT_ID = BIT(27), - BT_PTA_PREDICTION_EVENT_ID = BIT(28), - BT_PTA_AVALANCHE_EVENT_ID = BIT(29), - - PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30), - - EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, -}; - -struct event_debug_report { - u8 debug_event_id; - u8 num_params; - u16 pad; - u32 report_1; - u32 report_2; - u32 report_3; -} __packed; - -struct event_mailbox { - u32 events_vector; - u32 events_mask; - u32 reserved_1; - u32 reserved_2; - - char average_rssi_level; - u8 ps_status; - u8 channel_switch_status; - u8 scheduled_scan_status; - - /* Channels scanned by the scheduled scan */ - u16 scheduled_scan_channels; - - /* If bit 0 is set -> target's fatal error */ - u16 health_report; - u16 bad_fft_counter; - u8 bt_pta_sense_info; - u8 bt_pta_protective_info; - u32 reserved; - u32 debug_report[2]; - - /* Number of FCS errors since last event */ - u32 fcs_err_counter; - - struct event_debug_report report; - u8 average_snr_level; - u8 padding[19]; -} __packed; - -int wl1251_event_unmask(struct wl1251 *wl); -void wl1251_event_mbox_config(struct wl1251 *wl); -int wl1251_event_handle(struct wl1251 *wl, u8 mbox); -int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c deleted file mode 100644 index c5daec05d9ee..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include - -#include "wl1251_init.h" -#include "wl12xx_80211.h" -#include "wl1251_acx.h" -#include "wl1251_cmd.h" -#include "wl1251_reg.h" - -int wl1251_hw_init_hwenc_config(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_feature_cfg(wl); - if (ret < 0) { - wl1251_warning("couldn't set feature config"); - return ret; - } - - ret = wl1251_acx_default_key(wl, wl->default_key); - if (ret < 0) { - wl1251_warning("couldn't set default key"); - return ret; - } - - return 0; -} - -int wl1251_hw_init_templates_config(struct wl1251 *wl) -{ - int ret; - u8 partial_vbm[PARTIAL_VBM_MAX]; - - /* send empty templates for fw memory reservation */ - ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL, - sizeof(struct wl12xx_probe_req_template)); - if (ret < 0) - return ret; - - ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL, - sizeof(struct wl12xx_null_data_template)); - if (ret < 0) - return ret; - - ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL, - sizeof(struct wl12xx_ps_poll_template)); - if (ret < 0) - return ret; - - ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL, - sizeof - (struct wl12xx_qos_null_data_template)); - if (ret < 0) - return ret; - - ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL, - sizeof - (struct wl12xx_probe_resp_template)); - if (ret < 0) - return ret; - - ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL, - sizeof - (struct wl12xx_beacon_template)); - if (ret < 0) - return ret; - - /* tim templates, first reserve space then allocate an empty one */ - memset(partial_vbm, 0, PARTIAL_VBM_MAX); - ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0); - if (ret < 0) - return ret; - - ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter) -{ - int ret; - - ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF); - if (ret < 0) - return ret; - - ret = wl1251_acx_rx_config(wl, config, filter); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_phy_config(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_pd_threshold(wl); - if (ret < 0) - return ret; - - ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME); - if (ret < 0) - return ret; - - ret = wl1251_acx_group_address_tbl(wl); - if (ret < 0) - return ret; - - ret = wl1251_acx_service_period_timeout(wl); - if (ret < 0) - return ret; - - ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_beacon_filter(struct wl1251 *wl) -{ - int ret; - - /* disable beacon filtering at this stage */ - ret = wl1251_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1251_acx_beacon_filter_table(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_pta(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_sg_enable(wl); - if (ret < 0) - return ret; - - ret = wl1251_acx_sg_cfg(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_energy_detection(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_cca_threshold(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_bcn_dtim_options(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1251_hw_init_power_auth(struct wl1251 *wl) -{ - return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); -} - -int wl1251_hw_init_mem_config(struct wl1251 *wl) -{ - int ret; - - ret = wl1251_acx_mem_cfg(wl); - if (ret < 0) - return ret; - - wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map), - GFP_KERNEL); - if (!wl->target_mem_map) { - wl1251_error("couldn't allocate target memory map"); - return -ENOMEM; - } - - /* we now ask for the firmware built memory map */ - ret = wl1251_acx_mem_map(wl, wl->target_mem_map, - sizeof(struct wl1251_acx_mem_map)); - if (ret < 0) { - wl1251_error("couldn't retrieve firmware memory map"); - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - return ret; - } - - return 0; -} - -static int wl1251_hw_init_txq_fill(u8 qid, - struct acx_tx_queue_qos_config *config, - u32 num_blocks) -{ - config->qid = qid; - - switch (qid) { - case QOS_AC_BE: - config->high_threshold = - (QOS_TX_HIGH_BE_DEF * num_blocks) / 100; - config->low_threshold = - (QOS_TX_LOW_BE_DEF * num_blocks) / 100; - break; - case QOS_AC_BK: - config->high_threshold = - (QOS_TX_HIGH_BK_DEF * num_blocks) / 100; - config->low_threshold = - (QOS_TX_LOW_BK_DEF * num_blocks) / 100; - break; - case QOS_AC_VI: - config->high_threshold = - (QOS_TX_HIGH_VI_DEF * num_blocks) / 100; - config->low_threshold = - (QOS_TX_LOW_VI_DEF * num_blocks) / 100; - break; - case QOS_AC_VO: - config->high_threshold = - (QOS_TX_HIGH_VO_DEF * num_blocks) / 100; - config->low_threshold = - (QOS_TX_LOW_VO_DEF * num_blocks) / 100; - break; - default: - wl1251_error("Invalid TX queue id: %d", qid); - return -EINVAL; - } - - return 0; -} - -static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl) -{ - struct acx_tx_queue_qos_config *config; - struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map; - int ret, i; - - wl1251_debug(DEBUG_ACX, "acx tx queue config"); - - config = kzalloc(sizeof(*config), GFP_KERNEL); - if (!config) { - ret = -ENOMEM; - goto out; - } - - for (i = 0; i < MAX_NUM_OF_AC; i++) { - ret = wl1251_hw_init_txq_fill(i, config, - wl_mem_map->num_tx_mem_blocks); - if (ret < 0) - goto out; - - ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG, - config, sizeof(*config)); - if (ret < 0) - goto out; - } - - wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE); - wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK); - wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI); - wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO); - -out: - kfree(config); - return ret; -} - -static int wl1251_hw_init_data_path_config(struct wl1251 *wl) -{ - int ret; - - /* asking for the data path parameters */ - wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp), - GFP_KERNEL); - if (!wl->data_path) { - wl1251_error("Couldnt allocate data path parameters"); - return -ENOMEM; - } - - ret = wl1251_acx_data_path_params(wl, wl->data_path); - if (ret < 0) { - kfree(wl->data_path); - wl->data_path = NULL; - return ret; - } - - return 0; -} - - -int wl1251_hw_init(struct wl1251 *wl) -{ - struct wl1251_acx_mem_map *wl_mem_map; - int ret; - - ret = wl1251_hw_init_hwenc_config(wl); - if (ret < 0) - return ret; - - /* Template settings */ - ret = wl1251_hw_init_templates_config(wl); - if (ret < 0) - return ret; - - /* Default memory configuration */ - ret = wl1251_hw_init_mem_config(wl); - if (ret < 0) - return ret; - - /* Default data path configuration */ - ret = wl1251_hw_init_data_path_config(wl); - if (ret < 0) - goto out_free_memmap; - - /* RX config */ - ret = wl1251_hw_init_rx_config(wl, - RX_CFG_PROMISCUOUS | RX_CFG_TSF, - RX_FILTER_OPTION_DEF); - /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS, - RX_FILTER_OPTION_FILTER_ALL); */ - if (ret < 0) - goto out_free_data_path; - - /* TX queues config */ - ret = wl1251_hw_init_tx_queue_config(wl); - if (ret < 0) - goto out_free_data_path; - - /* PHY layer config */ - ret = wl1251_hw_init_phy_config(wl); - if (ret < 0) - goto out_free_data_path; - - /* Initialize connection monitoring thresholds */ - ret = wl1251_acx_conn_monit_params(wl); - if (ret < 0) - goto out_free_data_path; - - /* Beacon filtering */ - ret = wl1251_hw_init_beacon_filter(wl); - if (ret < 0) - goto out_free_data_path; - - /* Bluetooth WLAN coexistence */ - ret = wl1251_hw_init_pta(wl); - if (ret < 0) - goto out_free_data_path; - - /* Energy detection */ - ret = wl1251_hw_init_energy_detection(wl); - if (ret < 0) - goto out_free_data_path; - - /* Beacons and boradcast settings */ - ret = wl1251_hw_init_beacon_broadcast(wl); - if (ret < 0) - goto out_free_data_path; - - /* Enable data path */ - ret = wl1251_cmd_data_path(wl, wl->channel, 1); - if (ret < 0) - goto out_free_data_path; - - /* Default power state */ - ret = wl1251_hw_init_power_auth(wl); - if (ret < 0) - goto out_free_data_path; - - wl_mem_map = wl->target_mem_map; - wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x", - wl_mem_map->num_tx_mem_blocks, - wl->data_path->tx_control_addr, - wl_mem_map->num_rx_mem_blocks, - wl->data_path->rx_control_addr); - - return 0; - - out_free_data_path: - kfree(wl->data_path); - - out_free_memmap: - kfree(wl->target_mem_map); - - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h deleted file mode 100644 index 543f17582ead..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_init.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_INIT_H__ -#define __WL1251_INIT_H__ - -#include "wl1251.h" - -enum { - /* best effort/legacy */ - AC_BE = 0, - - /* background */ - AC_BK = 1, - - /* video */ - AC_VI = 2, - - /* voice */ - AC_VO = 3, - - /* broadcast dummy access category */ - AC_BCAST = 4, - - NUM_ACCESS_CATEGORIES = 4 -}; - -/* following are defult values for the IE fields*/ -#define CWMIN_BK 15 -#define CWMIN_BE 15 -#define CWMIN_VI 7 -#define CWMIN_VO 3 -#define CWMAX_BK 1023 -#define CWMAX_BE 63 -#define CWMAX_VI 15 -#define CWMAX_VO 7 - -/* slot number setting to start transmission at PIFS interval */ -#define AIFS_PIFS 1 - -/* - * slot number setting to start transmission at DIFS interval - normal DCF - * access - */ -#define AIFS_DIFS 2 - -#define AIFSN_BK 7 -#define AIFSN_BE 3 -#define AIFSN_VI AIFS_PIFS -#define AIFSN_VO AIFS_PIFS -#define TXOP_BK 0 -#define TXOP_BE 0 -#define TXOP_VI 3008 -#define TXOP_VO 1504 - -int wl1251_hw_init_hwenc_config(struct wl1251 *wl); -int wl1251_hw_init_templates_config(struct wl1251 *wl); -int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter); -int wl1251_hw_init_phy_config(struct wl1251 *wl); -int wl1251_hw_init_beacon_filter(struct wl1251 *wl); -int wl1251_hw_init_pta(struct wl1251 *wl); -int wl1251_hw_init_energy_detection(struct wl1251 *wl); -int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl); -int wl1251_hw_init_power_auth(struct wl1251 *wl); -int wl1251_hw_init_mem_config(struct wl1251 *wl); -int wl1251_hw_init(struct wl1251 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c deleted file mode 100644 index ad6ca68b303f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_io.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" - -/* FIXME: this is static data nowadays and the table can be removed */ -static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = { - [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474), - [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478), - [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494), - [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498), - [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C), - [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0), - [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4), - [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8), - [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000), - [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C), - [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804) -}; - -static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr) -{ - /* If the address is lower than REGISTERS_BASE, it means that this is - * a chip-specific register address, so look it up in the registers - * table */ - if (addr < REGISTERS_BASE) { - /* Make sure we don't go over the table */ - if (addr >= ACX_REG_TABLE_LEN) { - wl1251_error("address out of range (%d)", addr); - return -EINVAL; - } - addr = wl1251_io_reg_table[addr]; - } - - return addr - wl->physical_reg_addr + wl->virtual_reg_addr; -} - -static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr) -{ - return addr - wl->physical_mem_addr + wl->virtual_mem_addr; -} - -void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len) -{ - int physical; - - physical = wl1251_translate_mem_addr(wl, addr); - - wl->if_ops->read(wl, physical, buf, len); -} - -void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len) -{ - int physical; - - physical = wl1251_translate_mem_addr(wl, addr); - - wl->if_ops->write(wl, physical, buf, len); -} - -u32 wl1251_mem_read32(struct wl1251 *wl, int addr) -{ - return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr)); -} - -void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val) -{ - wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val); -} - -u32 wl1251_reg_read32(struct wl1251 *wl, int addr) -{ - return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr)); -} - -void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val) -{ - wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val); -} - -/* Set the partitions to access the chip addresses. - * - * There are two VIRTUAL partitions (the memory partition and the - * registers partition), which are mapped to two different areas of the - * PHYSICAL (hardware) memory. This function also makes other checks to - * ensure that the partitions are not overlapping. In the diagram below, the - * memory partition comes before the register partition, but the opposite is - * also supported. - * - * PHYSICAL address - * space - * - * | | - * ...+----+--> mem_start - * VIRTUAL address ... | | - * space ... | | [PART_0] - * ... | | - * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size - * | | ... | | - * |MEM | ... | | - * | | ... | | - * part_size <--+----+... | | {unused area) - * | | ... | | - * |REG | ... | | - * part_size | | ... | | - * + <--+----+... ...+----+--> reg_start - * reg_size ... | | - * ... | | [PART_1] - * ... | | - * ...+----+--> reg_start + reg_size - * | | - * - */ -void wl1251_set_partition(struct wl1251 *wl, - u32 mem_start, u32 mem_size, - u32 reg_start, u32 reg_size) -{ - struct wl1251_partition partition[2]; - - wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - mem_start, mem_size); - wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - reg_start, reg_size); - - /* Make sure that the two partitions together don't exceed the - * address range */ - if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) { - wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual" - " address range. Truncating partition[0]."); - mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size; - wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - mem_start, mem_size); - wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - reg_start, reg_size); - } - - if ((mem_start < reg_start) && - ((mem_start + mem_size) > reg_start)) { - /* Guarantee that the memory partition doesn't overlap the - * registers partition */ - wl1251_debug(DEBUG_SPI, "End of partition[0] is " - "overlapping partition[1]. Adjusted."); - mem_size = reg_start - mem_start; - wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - mem_start, mem_size); - wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - reg_start, reg_size); - } else if ((reg_start < mem_start) && - ((reg_start + reg_size) > mem_start)) { - /* Guarantee that the register partition doesn't overlap the - * memory partition */ - wl1251_debug(DEBUG_SPI, "End of partition[1] is" - " overlapping partition[0]. Adjusted."); - reg_size = mem_start - reg_start; - wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - mem_start, mem_size); - wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - reg_start, reg_size); - } - - partition[0].start = mem_start; - partition[0].size = mem_size; - partition[1].start = reg_start; - partition[1].size = reg_size; - - wl->physical_mem_addr = mem_start; - wl->physical_reg_addr = reg_start; - - wl->virtual_mem_addr = 0; - wl->virtual_reg_addr = mem_size; - - wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition, - sizeof(partition)); -} diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h deleted file mode 100644 index c545e9d5f512..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_io.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ -#ifndef __WL1251_IO_H__ -#define __WL1251_IO_H__ - -#include "wl1251.h" - -#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 - -#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0 -#define HW_ACCESS_PART0_START_ADDR 0x1FFC4 -#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8 -#define HW_ACCESS_PART1_START_ADDR 0x1FFCC - -#define HW_ACCESS_REGISTER_SIZE 4 - -#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 - -static inline u32 wl1251_read32(struct wl1251 *wl, int addr) -{ - u32 response; - - wl->if_ops->read(wl, addr, &response, sizeof(u32)); - - return response; -} - -static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val) -{ - wl->if_ops->write(wl, addr, &val, sizeof(u32)); -} - -static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr) -{ - u32 response; - - if (wl->if_ops->read_elp) - wl->if_ops->read_elp(wl, addr, &response); - else - wl->if_ops->read(wl, addr, &response, sizeof(u32)); - - return response; -} - -static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val) -{ - if (wl->if_ops->write_elp) - wl->if_ops->write_elp(wl, addr, val); - else - wl->if_ops->write(wl, addr, &val, sizeof(u32)); -} - -/* Memory target IO, address is translated to partition 0 */ -void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); -void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); -u32 wl1251_mem_read32(struct wl1251 *wl, int addr); -void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val); -/* Registers IO */ -u32 wl1251_reg_read32(struct wl1251 *wl, int addr); -void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val); - -void wl1251_set_partition(struct wl1251 *wl, - u32 part_start, u32 part_size, - u32 reg_start, u32 reg_size); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c deleted file mode 100644 index faf221ca3f41..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wl1251.h" -#include "wl12xx_80211.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_cmd.h" -#include "wl1251_event.h" -#include "wl1251_tx.h" -#include "wl1251_rx.h" -#include "wl1251_ps.h" -#include "wl1251_init.h" -#include "wl1251_debugfs.h" -#include "wl1251_boot.h" - -void wl1251_enable_interrupts(struct wl1251 *wl) -{ - wl->if_ops->enable_irq(wl); -} - -void wl1251_disable_interrupts(struct wl1251 *wl) -{ - wl->if_ops->disable_irq(wl); -} - -static void wl1251_power_off(struct wl1251 *wl) -{ - wl->set_power(false); -} - -static void wl1251_power_on(struct wl1251 *wl) -{ - wl->set_power(true); -} - -static int wl1251_fetch_firmware(struct wl1251 *wl) -{ - const struct firmware *fw; - struct device *dev = wiphy_dev(wl->hw->wiphy); - int ret; - - ret = request_firmware(&fw, WL1251_FW_NAME, dev); - - if (ret < 0) { - wl1251_error("could not get firmware: %d", ret); - return ret; - } - - if (fw->size % 4) { - wl1251_error("firmware size is not multiple of 32 bits: %zu", - fw->size); - ret = -EILSEQ; - goto out; - } - - wl->fw_len = fw->size; - wl->fw = vmalloc(wl->fw_len); - - if (!wl->fw) { - wl1251_error("could not allocate memory for the firmware"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->fw, fw->data, wl->fw_len); - - ret = 0; - -out: - release_firmware(fw); - - return ret; -} - -static int wl1251_fetch_nvs(struct wl1251 *wl) -{ - const struct firmware *fw; - struct device *dev = wiphy_dev(wl->hw->wiphy); - int ret; - - ret = request_firmware(&fw, WL1251_NVS_NAME, dev); - - if (ret < 0) { - wl1251_error("could not get nvs file: %d", ret); - return ret; - } - - if (fw->size % 4) { - wl1251_error("nvs size is not multiple of 32 bits: %zu", - fw->size); - ret = -EILSEQ; - goto out; - } - - wl->nvs_len = fw->size; - wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL); - - if (!wl->nvs) { - wl1251_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - ret = 0; - -out: - release_firmware(fw); - - return ret; -} - -static void wl1251_fw_wakeup(struct wl1251 *wl) -{ - u32 elp_reg; - - elp_reg = ELPCTRL_WAKE_UP; - wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); - elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); - - if (!(elp_reg & ELPCTRL_WLAN_READY)) - wl1251_warning("WLAN not ready"); -} - -static int wl1251_chip_wakeup(struct wl1251 *wl) -{ - int ret = 0; - - wl1251_power_on(wl); - msleep(WL1251_POWER_ON_SLEEP); - wl->if_ops->reset(wl); - - /* We don't need a real memory partition here, because we only want - * to use the registers at this point. */ - wl1251_set_partition(wl, - 0x00000000, - 0x00000000, - REGISTERS_BASE, - REGISTERS_DOWN_SIZE); - - /* ELP module wake up */ - wl1251_fw_wakeup(wl); - - /* whal_FwCtrl_BootSm() */ - - /* 0. read chip id from CHIP_ID */ - wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B); - - /* 1. check if chip id is valid */ - - switch (wl->chip_id) { - case CHIP_ID_1251_PG12: - wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)", - wl->chip_id); - break; - case CHIP_ID_1251_PG11: - wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)", - wl->chip_id); - break; - case CHIP_ID_1251_PG10: - default: - wl1251_error("unsupported chip id: 0x%x", wl->chip_id); - ret = -ENODEV; - goto out; - } - - if (wl->fw == NULL) { - ret = wl1251_fetch_firmware(wl); - if (ret < 0) - goto out; - } - - if (wl->nvs == NULL && !wl->use_eeprom) { - /* No NVS from netlink, try to get it from the filesystem */ - ret = wl1251_fetch_nvs(wl); - if (ret < 0) - goto out; - } - -out: - return ret; -} - -#define WL1251_IRQ_LOOP_COUNT 10 -static void wl1251_irq_work(struct work_struct *work) -{ - u32 intr, ctr = WL1251_IRQ_LOOP_COUNT; - struct wl1251 *wl = - container_of(work, struct wl1251, irq_work); - int ret; - - mutex_lock(&wl->mutex); - - wl1251_debug(DEBUG_IRQ, "IRQ work"); - - if (wl->state == WL1251_STATE_OFF) - goto out; - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL); - - intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); - wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); - - do { - if (wl->data_path) { - wl->rx_counter = wl1251_mem_read32( - wl, wl->data_path->rx_control_addr); - - /* We handle a frmware bug here */ - switch ((wl->rx_counter - wl->rx_handled) & 0xf) { - case 0: - wl1251_debug(DEBUG_IRQ, - "RX: FW and host in sync"); - intr &= ~WL1251_ACX_INTR_RX0_DATA; - intr &= ~WL1251_ACX_INTR_RX1_DATA; - break; - case 1: - wl1251_debug(DEBUG_IRQ, "RX: FW +1"); - intr |= WL1251_ACX_INTR_RX0_DATA; - intr &= ~WL1251_ACX_INTR_RX1_DATA; - break; - case 2: - wl1251_debug(DEBUG_IRQ, "RX: FW +2"); - intr |= WL1251_ACX_INTR_RX0_DATA; - intr |= WL1251_ACX_INTR_RX1_DATA; - break; - default: - wl1251_warning( - "RX: FW and host out of sync: %d", - wl->rx_counter - wl->rx_handled); - break; - } - - wl->rx_handled = wl->rx_counter; - - wl1251_debug(DEBUG_IRQ, "RX counter: %d", - wl->rx_counter); - } - - intr &= wl->intr_mask; - - if (intr == 0) { - wl1251_debug(DEBUG_IRQ, "INTR is 0"); - goto out_sleep; - } - - if (intr & WL1251_ACX_INTR_RX0_DATA) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); - wl1251_rx(wl); - } - - if (intr & WL1251_ACX_INTR_RX1_DATA) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); - wl1251_rx(wl); - } - - if (intr & WL1251_ACX_INTR_TX_RESULT) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); - wl1251_tx_complete(wl); - } - - if (intr & WL1251_ACX_INTR_EVENT_A) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A"); - wl1251_event_handle(wl, 0); - } - - if (intr & WL1251_ACX_INTR_EVENT_B) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B"); - wl1251_event_handle(wl, 1); - } - - if (intr & WL1251_ACX_INTR_INIT_COMPLETE) - wl1251_debug(DEBUG_IRQ, - "WL1251_ACX_INTR_INIT_COMPLETE"); - - if (--ctr == 0) - break; - - intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); - } while (intr); - -out_sleep: - wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, - u16 beacon_interval, u8 dtim_period) -{ - int ret; - - ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE, - DEFAULT_HW_GEN_MODULATION_TYPE, - wl->tx_mgmt_frm_rate, - wl->tx_mgmt_frm_mod); - if (ret < 0) - goto out; - - - ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval, - dtim_period); - if (ret < 0) - goto out; - - ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100); - if (ret < 0) - wl1251_warning("join timeout"); - -out: - return ret; -} - -static void wl1251_filter_work(struct work_struct *work) -{ - struct wl1251 *wl = - container_of(work, struct wl1251, filter_work); - int ret; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1251_STATE_OFF) - goto out; - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int, - wl->dtim_period); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct wl1251 *wl = hw->priv; - unsigned long flags; - - skb_queue_tail(&wl->tx_queue, skb); - - /* - * The chip specific setup must run before the first TX packet - - * before that, the tx_work will not be initialized! - */ - - ieee80211_queue_work(wl->hw, &wl->tx_work); - - /* - * The workqueue is slow to process the tx_queue and we need stop - * the queue here, otherwise the queue will get too long. - */ - if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) { - wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues"); - - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_stop_queues(wl->hw); - wl->tx_queue_stopped = true; - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - - return NETDEV_TX_OK; -} - -static int wl1251_op_start(struct ieee80211_hw *hw) -{ - struct wl1251 *wl = hw->priv; - struct wiphy *wiphy = hw->wiphy; - int ret = 0; - - wl1251_debug(DEBUG_MAC80211, "mac80211 start"); - - mutex_lock(&wl->mutex); - - if (wl->state != WL1251_STATE_OFF) { - wl1251_error("cannot start because not in off state: %d", - wl->state); - ret = -EBUSY; - goto out; - } - - ret = wl1251_chip_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1251_boot(wl); - if (ret < 0) - goto out; - - ret = wl1251_hw_init(wl); - if (ret < 0) - goto out; - - ret = wl1251_acx_station_id(wl); - if (ret < 0) - goto out; - - wl->state = WL1251_STATE_ON; - - wl1251_info("firmware booted (%s)", wl->fw_ver); - - /* update hw/fw version info in wiphy struct */ - wiphy->hw_version = wl->chip_id; - strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version)); - -out: - if (ret < 0) - wl1251_power_off(wl); - - mutex_unlock(&wl->mutex); - - return ret; -} - -static void wl1251_op_stop(struct ieee80211_hw *hw) -{ - struct wl1251 *wl = hw->priv; - - wl1251_info("down"); - - wl1251_debug(DEBUG_MAC80211, "mac80211 stop"); - - mutex_lock(&wl->mutex); - - WARN_ON(wl->state != WL1251_STATE_ON); - - if (wl->scanning) { - ieee80211_scan_completed(wl->hw, true); - wl->scanning = false; - } - - wl->state = WL1251_STATE_OFF; - - wl1251_disable_interrupts(wl); - - mutex_unlock(&wl->mutex); - - cancel_work_sync(&wl->irq_work); - cancel_work_sync(&wl->tx_work); - cancel_work_sync(&wl->filter_work); - - mutex_lock(&wl->mutex); - - /* let's notify MAC80211 about the remaining pending TX frames */ - wl1251_tx_flush(wl); - wl1251_power_off(wl); - - memset(wl->bssid, 0, ETH_ALEN); - wl->listen_int = 1; - wl->bss_type = MAX_BSS_TYPE; - - wl->data_in_count = 0; - wl->rx_counter = 0; - wl->rx_handled = 0; - wl->rx_current_buffer = 0; - wl->rx_last_id = 0; - wl->next_tx_complete = 0; - wl->elp = false; - wl->psm = 0; - wl->tx_queue_stopped = false; - wl->power_level = WL1251_DEFAULT_POWER_LEVEL; - wl->channel = WL1251_DEFAULT_CHANNEL; - - wl1251_debugfs_reset(wl); - - mutex_unlock(&wl->mutex); -} - -static int wl1251_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1251 *wl = hw->priv; - int ret = 0; - - wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", - vif->type, vif->addr); - - mutex_lock(&wl->mutex); - if (wl->vif) { - ret = -EBUSY; - goto out; - } - - wl->vif = vif; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - wl->bss_type = BSS_TYPE_STA_BSS; - break; - case NL80211_IFTYPE_ADHOC: - wl->bss_type = BSS_TYPE_IBSS; - break; - default: - ret = -EOPNOTSUPP; - goto out; - } - - if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) { - memcpy(wl->mac_addr, vif->addr, ETH_ALEN); - SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); - ret = wl1251_acx_station_id(wl); - if (ret < 0) - goto out; - } - -out: - mutex_unlock(&wl->mutex); - return ret; -} - -static void wl1251_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1251 *wl = hw->priv; - - mutex_lock(&wl->mutex); - wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); - wl->vif = NULL; - mutex_unlock(&wl->mutex); -} - -static int wl1251_build_qos_null_data(struct wl1251 *wl) -{ - struct ieee80211_qos_hdr template; - - memset(&template, 0, sizeof(template)); - - memcpy(template.addr1, wl->bssid, ETH_ALEN); - memcpy(template.addr2, wl->mac_addr, ETH_ALEN); - memcpy(template.addr3, wl->bssid, ETH_ALEN); - - template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_QOS_NULLFUNC | - IEEE80211_FCTL_TODS); - - /* FIXME: not sure what priority to use here */ - template.qos_ctrl = cpu_to_le16(0); - - return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template, - sizeof(template)); -} - -static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct wl1251 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - int channel, ret = 0; - - channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - - wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", - channel, - conf->flags & IEEE80211_CONF_PS ? "on" : "off", - conf->power_level); - - mutex_lock(&wl->mutex); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - if (channel != wl->channel) { - wl->channel = channel; - - ret = wl1251_join(wl, wl->bss_type, wl->channel, - wl->beacon_int, wl->dtim_period); - if (ret < 0) - goto out_sleep; - } - - if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { - wl1251_debug(DEBUG_PSM, "psm enabled"); - - wl->psm_requested = true; - - wl->dtim_period = conf->ps_dtim_period; - - ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, - wl->dtim_period); - - /* - * mac80211 enables PSM only if we're already associated. - */ - ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); - if (ret < 0) - goto out_sleep; - } else if (!(conf->flags & IEEE80211_CONF_PS) && - wl->psm_requested) { - wl1251_debug(DEBUG_PSM, "psm disabled"); - - wl->psm_requested = false; - - if (wl->psm) { - ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); - if (ret < 0) - goto out_sleep; - } - } - - if (conf->power_level != wl->power_level) { - ret = wl1251_acx_tx_power(wl, conf->power_level); - if (ret < 0) - goto out_sleep; - - wl->power_level = conf->power_level; - } - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_BCN_PRBRESP_PROMISC | \ - FIF_CONTROL | \ - FIF_OTHER_BSS) - -static void wl1251_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, - unsigned int *total,u64 multicast) -{ - struct wl1251 *wl = hw->priv; - - wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter"); - - *total &= WL1251_SUPPORTED_FILTERS; - changed &= WL1251_SUPPORTED_FILTERS; - - if (changed == 0) - /* no filters which we support changed */ - return; - - /* FIXME: wl->rx_config and wl->rx_filter are not protected */ - - wl->rx_config = WL1251_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1251_DEFAULT_RX_FILTER; - - if (*total & FIF_PROMISC_IN_BSS) { - wl->rx_config |= CFG_BSSID_FILTER_EN; - wl->rx_config |= CFG_RX_ALL_GOOD; - } - if (*total & FIF_ALLMULTI) - /* - * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive - * all multicast frames - */ - wl->rx_config &= ~CFG_MC_FILTER_EN; - if (*total & FIF_FCSFAIL) - wl->rx_filter |= CFG_RX_FCS_ERROR; - if (*total & FIF_BCN_PRBRESP_PROMISC) { - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - wl->rx_config &= ~CFG_SSID_FILTER_EN; - } - if (*total & FIF_CONTROL) - wl->rx_filter |= CFG_RX_CTL_EN; - if (*total & FIF_OTHER_BSS) - wl->rx_filter &= ~CFG_BSSID_FILTER_EN; - - /* - * FIXME: workqueues need to be properly cancelled on stop(), for - * now let's just disable changing the filter settings. They will - * be updated any on config(). - */ - /* schedule_work(&wl->filter_work); */ -} - -/* HW encryption */ -static int wl1251_set_key_type(struct wl1251 *wl, - struct wl1251_cmd_set_keys *key, - enum set_key_cmd cmd, - struct ieee80211_key_conf *mac80211_key, - const u8 *addr) -{ - switch (mac80211_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - if (is_broadcast_ether_addr(addr)) - key->key_type = KEY_WEP_DEFAULT; - else - key->key_type = KEY_WEP_ADDR; - - mac80211_key->hw_key_idx = mac80211_key->keyidx; - break; - case WLAN_CIPHER_SUITE_TKIP: - if (is_broadcast_ether_addr(addr)) - key->key_type = KEY_TKIP_MIC_GROUP; - else - key->key_type = KEY_TKIP_MIC_PAIRWISE; - - mac80211_key->hw_key_idx = mac80211_key->keyidx; - break; - case WLAN_CIPHER_SUITE_CCMP: - if (is_broadcast_ether_addr(addr)) - key->key_type = KEY_AES_GROUP; - else - key->key_type = KEY_AES_PAIRWISE; - mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - break; - default: - wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher); - return -EOPNOTSUPP; - } - - return 0; -} - -static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct wl1251 *wl = hw->priv; - struct wl1251_cmd_set_keys *wl_cmd; - const u8 *addr; - int ret; - - static const u8 bcast_addr[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - wl1251_debug(DEBUG_MAC80211, "mac80211 set key"); - - wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL); - if (!wl_cmd) { - ret = -ENOMEM; - goto out; - } - - addr = sta ? sta->addr : bcast_addr; - - wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); - wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); - wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key->cipher, key->keyidx, key->keylen, key->flags); - wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); - - if (is_zero_ether_addr(addr)) { - /* We dont support TX only encryption */ - ret = -EOPNOTSUPP; - goto out; - } - - mutex_lock(&wl->mutex); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out_unlock; - - switch (cmd) { - case SET_KEY: - wl_cmd->key_action = KEY_ADD_OR_REPLACE; - break; - case DISABLE_KEY: - wl_cmd->key_action = KEY_REMOVE; - break; - default: - wl1251_error("Unsupported key cmd 0x%x", cmd); - break; - } - - ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr); - if (ret < 0) { - wl1251_error("Set KEY type failed"); - goto out_sleep; - } - - if (wl_cmd->key_type != KEY_WEP_DEFAULT) - memcpy(wl_cmd->addr, addr, ETH_ALEN); - - if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) || - (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) { - /* - * We get the key in the following form: - * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) - * but the target is expecting: - * TKIP - RX MIC - TX MIC - */ - memcpy(wl_cmd->key, key->key, 16); - memcpy(wl_cmd->key + 16, key->key + 24, 8); - memcpy(wl_cmd->key + 24, key->key + 16, 8); - - } else { - memcpy(wl_cmd->key, key->key, key->keylen); - } - wl_cmd->key_size = key->keylen; - - wl_cmd->id = key->keyidx; - wl_cmd->ssid_profile = 0; - - wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd)); - - ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd)); - if (ret < 0) { - wl1251_warning("could not set keys"); - goto out_sleep; - } - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out_unlock: - mutex_unlock(&wl->mutex); - -out: - kfree(wl_cmd); - - return ret; -} - -static int wl1251_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) -{ - struct wl1251 *wl = hw->priv; - struct sk_buff *skb; - size_t ssid_len = 0; - u8 *ssid = NULL; - int ret; - - wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan"); - - if (req->n_ssids) { - ssid = req->ssids[0].ssid; - ssid_len = req->ssids[0].ssid_len; - } - - mutex_lock(&wl->mutex); - - if (wl->scanning) { - wl1251_debug(DEBUG_SCAN, "scan already in progress"); - ret = -EINVAL; - goto out; - } - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, - req->ie, req->ie_len); - if (!skb) { - ret = -ENOMEM; - goto out; - } - - ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data, - skb->len); - dev_kfree_skb(skb); - if (ret < 0) - goto out_sleep; - - ret = wl1251_cmd_trigger_scan_to(wl, 0); - if (ret < 0) - goto out_sleep; - - wl->scanning = true; - - ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels, - req->n_channels, WL1251_SCAN_NUM_PROBES); - if (ret < 0) { - wl->scanning = false; - goto out_sleep; - } - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct wl1251 *wl = hw->priv; - int ret; - - mutex_lock(&wl->mutex); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1251_acx_rts_threshold(wl, (u16) value); - if (ret < 0) - wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret); - - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - struct wl1251 *wl = hw->priv; - struct sk_buff *beacon, *skb; - int ret; - - wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); - - mutex_lock(&wl->mutex); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - if (changed & BSS_CHANGED_BSSID) { - memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); - - skb = ieee80211_nullfunc_get(wl->hw, wl->vif); - if (!skb) - goto out_sleep; - - ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, - skb->data, skb->len); - dev_kfree_skb(skb); - if (ret < 0) - goto out_sleep; - - ret = wl1251_build_qos_null_data(wl); - if (ret < 0) - goto out; - - if (wl->bss_type != BSS_TYPE_IBSS) { - ret = wl1251_join(wl, wl->bss_type, wl->channel, - wl->beacon_int, wl->dtim_period); - if (ret < 0) - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ASSOC) { - if (bss_conf->assoc) { - wl->beacon_int = bss_conf->beacon_int; - - skb = ieee80211_pspoll_get(wl->hw, wl->vif); - if (!skb) - goto out_sleep; - - ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, - skb->data, - skb->len); - dev_kfree_skb(skb); - if (ret < 0) - goto out_sleep; - - ret = wl1251_acx_aid(wl, bss_conf->aid); - if (ret < 0) - goto out_sleep; - } else { - /* use defaults when not associated */ - wl->beacon_int = WL1251_DEFAULT_BEACON_INT; - wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; - } - } - if (changed & BSS_CHANGED_ERP_SLOT) { - if (bss_conf->use_short_slot) - ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT); - else - ret = wl1251_acx_slot(wl, SLOT_TIME_LONG); - if (ret < 0) { - wl1251_warning("Set slot time failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (bss_conf->use_short_preamble) - wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); - else - wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG); - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (bss_conf->use_cts_prot) - ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE); - else - ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE); - if (ret < 0) { - wl1251_warning("Set ctsprotect failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_BEACON) { - beacon = ieee80211_beacon_get(hw, vif); - ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, - beacon->len); - - if (ret < 0) { - dev_kfree_skb(beacon); - goto out_sleep; - } - - ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, - beacon->len); - - dev_kfree_skb(beacon); - - if (ret < 0) - goto out_sleep; - - ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, - wl->channel, wl->dtim_period); - - if (ret < 0) - goto out_sleep; - } - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_rate wl1251_rates[] = { - { .bitrate = 10, - .hw_value = 0x1, - .hw_value_short = 0x1, }, - { .bitrate = 20, - .hw_value = 0x2, - .hw_value_short = 0x2, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, - .hw_value = 0x4, - .hw_value_short = 0x4, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, - .hw_value = 0x20, - .hw_value_short = 0x20, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60, - .hw_value = 0x8, - .hw_value_short = 0x8, }, - { .bitrate = 90, - .hw_value = 0x10, - .hw_value_short = 0x10, }, - { .bitrate = 120, - .hw_value = 0x40, - .hw_value_short = 0x40, }, - { .bitrate = 180, - .hw_value = 0x80, - .hw_value_short = 0x80, }, - { .bitrate = 240, - .hw_value = 0x200, - .hw_value_short = 0x200, }, - { .bitrate = 360, - .hw_value = 0x400, - .hw_value_short = 0x400, }, - { .bitrate = 480, - .hw_value = 0x800, - .hw_value_short = 0x800, }, - { .bitrate = 540, - .hw_value = 0x1000, - .hw_value_short = 0x1000, }, -}; - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_channel wl1251_channels[] = { - { .hw_value = 1, .center_freq = 2412}, - { .hw_value = 2, .center_freq = 2417}, - { .hw_value = 3, .center_freq = 2422}, - { .hw_value = 4, .center_freq = 2427}, - { .hw_value = 5, .center_freq = 2432}, - { .hw_value = 6, .center_freq = 2437}, - { .hw_value = 7, .center_freq = 2442}, - { .hw_value = 8, .center_freq = 2447}, - { .hw_value = 9, .center_freq = 2452}, - { .hw_value = 10, .center_freq = 2457}, - { .hw_value = 11, .center_freq = 2462}, - { .hw_value = 12, .center_freq = 2467}, - { .hw_value = 13, .center_freq = 2472}, -}; - -static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - enum wl1251_acx_ps_scheme ps_scheme; - struct wl1251 *wl = hw->priv; - int ret; - - mutex_lock(&wl->mutex); - - wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - /* mac80211 uses units of 32 usec */ - ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue), - params->cw_min, params->cw_max, - params->aifs, params->txop * 32); - if (ret < 0) - goto out_sleep; - - if (params->uapsd) - ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER; - else - ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY; - - ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue), - CHANNEL_TYPE_EDCF, - wl1251_tx_get_queue(queue), ps_scheme, - WL1251_ACX_ACK_POLICY_LEGACY); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct wl1251 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = wl->noise; - - return 0; -} - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_supported_band wl1251_band_2ghz = { - .channels = wl1251_channels, - .n_channels = ARRAY_SIZE(wl1251_channels), - .bitrates = wl1251_rates, - .n_bitrates = ARRAY_SIZE(wl1251_rates), -}; - -static const struct ieee80211_ops wl1251_ops = { - .start = wl1251_op_start, - .stop = wl1251_op_stop, - .add_interface = wl1251_op_add_interface, - .remove_interface = wl1251_op_remove_interface, - .config = wl1251_op_config, - .configure_filter = wl1251_op_configure_filter, - .tx = wl1251_op_tx, - .set_key = wl1251_op_set_key, - .hw_scan = wl1251_op_hw_scan, - .bss_info_changed = wl1251_op_bss_info_changed, - .set_rts_threshold = wl1251_op_set_rts_threshold, - .conf_tx = wl1251_op_conf_tx, - .get_survey = wl1251_op_get_survey, -}; - -static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) -{ - unsigned long timeout; - - wl1251_reg_write32(wl, EE_ADDR, offset); - wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ); - - /* EE_CTL_READ clears when data is ready */ - timeout = jiffies + msecs_to_jiffies(100); - while (1) { - if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ)) - break; - - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - - msleep(1); - } - - *data = wl1251_reg_read32(wl, EE_DATA); - return 0; -} - -static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset, - u8 *data, size_t len) -{ - size_t i; - int ret; - - wl1251_reg_write32(wl, EE_START, 0); - - for (i = 0; i < len; i++) { - ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]); - if (ret < 0) - return ret; - } - - return 0; -} - -static int wl1251_read_eeprom_mac(struct wl1251 *wl) -{ - u8 mac[ETH_ALEN]; - int i, ret; - - wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE); - - ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac)); - if (ret < 0) { - wl1251_warning("failed to read MAC address from EEPROM"); - return ret; - } - - /* MAC is stored in reverse order */ - for (i = 0; i < ETH_ALEN; i++) - wl->mac_addr[i] = mac[ETH_ALEN - i - 1]; - - return 0; -} - -static int wl1251_register_hw(struct wl1251 *wl) -{ - int ret; - - if (wl->mac80211_registered) - return 0; - - SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); - - ret = ieee80211_register_hw(wl->hw); - if (ret < 0) { - wl1251_error("unable to register mac80211 hw: %d", ret); - return ret; - } - - wl->mac80211_registered = true; - - wl1251_notice("loaded"); - - return 0; -} - -int wl1251_init_ieee80211(struct wl1251 *wl) -{ - int ret; - - /* The tx descriptor buffer and the TKIP space */ - wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc) - + WL1251_TKIP_IV_SPACE; - - /* unit us */ - /* FIXME: find a proper value */ - wl->hw->channel_change_time = 10000; - - wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_SUPPORTS_UAPSD; - - wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - wl->hw->wiphy->max_scan_ssids = 1; - wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; - - wl->hw->queues = 4; - - if (wl->use_eeprom) - wl1251_read_eeprom_mac(wl); - - ret = wl1251_register_hw(wl); - if (ret) - goto out; - - wl1251_debugfs_init(wl); - wl1251_notice("initialized"); - - ret = 0; - -out: - return ret; -} -EXPORT_SYMBOL_GPL(wl1251_init_ieee80211); - -struct ieee80211_hw *wl1251_alloc_hw(void) -{ - struct ieee80211_hw *hw; - struct wl1251 *wl; - int i; - static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; - - hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops); - if (!hw) { - wl1251_error("could not alloc ieee80211_hw"); - return ERR_PTR(-ENOMEM); - } - - wl = hw->priv; - memset(wl, 0, sizeof(*wl)); - - wl->hw = hw; - - wl->data_in_count = 0; - - skb_queue_head_init(&wl->tx_queue); - - INIT_WORK(&wl->filter_work, wl1251_filter_work); - INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); - wl->channel = WL1251_DEFAULT_CHANNEL; - wl->scanning = false; - wl->default_key = 0; - wl->listen_int = 1; - wl->rx_counter = 0; - wl->rx_handled = 0; - wl->rx_current_buffer = 0; - wl->rx_last_id = 0; - wl->rx_config = WL1251_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1251_DEFAULT_RX_FILTER; - wl->elp = false; - wl->psm = 0; - wl->psm_requested = false; - wl->tx_queue_stopped = false; - wl->power_level = WL1251_DEFAULT_POWER_LEVEL; - wl->beacon_int = WL1251_DEFAULT_BEACON_INT; - wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; - wl->vif = NULL; - - for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) - wl->tx_frames[i] = NULL; - - wl->next_tx_complete = 0; - - INIT_WORK(&wl->irq_work, wl1251_irq_work); - INIT_WORK(&wl->tx_work, wl1251_tx_work); - - /* - * In case our MAC address is not correctly set, - * we use a random but Nokia MAC. - */ - memcpy(wl->mac_addr, nokia_oui, 3); - get_random_bytes(wl->mac_addr + 3, 3); - - wl->state = WL1251_STATE_OFF; - mutex_init(&wl->mutex); - - wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE; - wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE; - - wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL); - if (!wl->rx_descriptor) { - wl1251_error("could not allocate memory for rx descriptor"); - ieee80211_free_hw(hw); - return ERR_PTR(-ENOMEM); - } - - return hw; -} -EXPORT_SYMBOL_GPL(wl1251_alloc_hw); - -int wl1251_free_hw(struct wl1251 *wl) -{ - ieee80211_unregister_hw(wl->hw); - - wl1251_debugfs_exit(wl); - - kfree(wl->target_mem_map); - kfree(wl->data_path); - vfree(wl->fw); - wl->fw = NULL; - kfree(wl->nvs); - wl->nvs = NULL; - - kfree(wl->rx_descriptor); - wl->rx_descriptor = NULL; - - ieee80211_free_hw(wl->hw); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1251_free_hw); - -MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); -MODULE_FIRMWARE(WL1251_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c deleted file mode 100644 index 0b997bdfec09..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "wl1251_reg.h" -#include "wl1251_ps.h" -#include "wl1251_cmd.h" -#include "wl1251_io.h" - -/* in ms */ -#define WL1251_WAKEUP_TIMEOUT 100 - -void wl1251_elp_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1251 *wl; - - dwork = container_of(work, struct delayed_work, work); - wl = container_of(dwork, struct wl1251, elp_work); - - wl1251_debug(DEBUG_PSM, "elp work"); - - mutex_lock(&wl->mutex); - - if (wl->elp || !wl->psm) - goto out; - - wl1251_debug(DEBUG_PSM, "chip to elp"); - wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); - wl->elp = true; - -out: - mutex_unlock(&wl->mutex); -} - -#define ELP_ENTRY_DELAY 5 - -/* Routines to toggle sleep mode while in ELP */ -void wl1251_ps_elp_sleep(struct wl1251 *wl) -{ - unsigned long delay; - - if (wl->psm) { - cancel_delayed_work(&wl->elp_work); - delay = msecs_to_jiffies(ELP_ENTRY_DELAY); - ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); - } -} - -int wl1251_ps_elp_wakeup(struct wl1251 *wl) -{ - unsigned long timeout, start; - u32 elp_reg; - - if (!wl->elp) - return 0; - - wl1251_debug(DEBUG_PSM, "waking up chip from elp"); - - start = jiffies; - timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); - - wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); - - elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); - - /* - * FIXME: we should wait for irq from chip but, as a temporary - * solution to simplify locking, let's poll instead - */ - while (!(elp_reg & ELPCTRL_WLAN_READY)) { - if (time_after(jiffies, timeout)) { - wl1251_error("elp wakeup timeout"); - return -ETIMEDOUT; - } - msleep(1); - elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); - } - - wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", - jiffies_to_msecs(jiffies - start)); - - wl->elp = false; - - return 0; -} - -static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable) -{ - int ret; - - if (enable) { - wl1251_debug(DEBUG_PSM, "sleep auth psm/elp"); - - ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); - if (ret < 0) - return ret; - - wl1251_ps_elp_sleep(wl); - } else { - wl1251_debug(DEBUG_PSM, "sleep auth cam"); - - /* - * When the target is in ELP, we can only - * access the ELP control register. Thus, - * we have to wake the target up before - * changing the power authorization. - */ - - wl1251_ps_elp_wakeup(wl); - - ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); - if (ret < 0) - return ret; - } - - return 0; -} - -int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) -{ - int ret; - - switch (mode) { - case STATION_POWER_SAVE_MODE: - wl1251_debug(DEBUG_PSM, "entering psm"); - - /* enable beacon filtering */ - ret = wl1251_acx_beacon_filter_opt(wl, true); - if (ret < 0) - return ret; - - ret = wl1251_acx_wake_up_conditions(wl, - WAKE_UP_EVENT_DTIM_BITMAP, - wl->listen_int); - if (ret < 0) - return ret; - - ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); - if (ret < 0) - return ret; - - ret = wl1251_ps_set_elp(wl, true); - if (ret < 0) - return ret; - - wl->psm = 1; - break; - case STATION_ACTIVE_MODE: - default: - wl1251_debug(DEBUG_PSM, "leaving psm"); - ret = wl1251_ps_set_elp(wl, false); - if (ret < 0) - return ret; - - /* disable beacon filtering */ - ret = wl1251_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1251_acx_wake_up_conditions(wl, - WAKE_UP_EVENT_DTIM_BITMAP, - wl->listen_int); - if (ret < 0) - return ret; - - ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE); - if (ret < 0) - return ret; - - wl->psm = 0; - break; - } - - return ret; -} - diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h deleted file mode 100644 index e5db81fc1dfc..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_PS_H__ -#define __WL1251_PS_H__ - -#include "wl1251.h" -#include "wl1251_acx.h" - -int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); -void wl1251_ps_elp_sleep(struct wl1251 *wl); -int wl1251_ps_elp_wakeup(struct wl1251 *wl); -void wl1251_elp_work(struct work_struct *work); - - -#endif /* __WL1251_PS_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h deleted file mode 100644 index a5809019c5c1..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ /dev/null @@ -1,655 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __REG_H__ -#define __REG_H__ - -#include - -#define REGISTERS_BASE 0x00300000 -#define DRPW_BASE 0x00310000 - -#define REGISTERS_DOWN_SIZE 0x00008800 -#define REGISTERS_WORK_SIZE 0x0000b000 - -#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC - -/* ELP register commands */ -#define ELPCTRL_WAKE_UP 0x1 -#define ELPCTRL_WAKE_UP_WLAN_READY 0x5 -#define ELPCTRL_SLEEP 0x0 -/* ELP WLAN_READY bit */ -#define ELPCTRL_WLAN_READY 0x2 - -/* Device Configuration registers*/ -#define SOR_CFG (REGISTERS_BASE + 0x0800) -#define ECPU_CTRL (REGISTERS_BASE + 0x0804) -#define HI_CFG (REGISTERS_BASE + 0x0808) - -/* EEPROM registers */ -#define EE_START (REGISTERS_BASE + 0x080C) -#define EE_CTL (REGISTERS_BASE + 0x2000) -#define EE_DATA (REGISTERS_BASE + 0x2004) -#define EE_ADDR (REGISTERS_BASE + 0x2008) - -#define EE_CTL_READ 2 - -#define CHIP_ID_B (REGISTERS_BASE + 0x5674) - -#define CHIP_ID_1251_PG10 (0x7010101) -#define CHIP_ID_1251_PG11 (0x7020101) -#define CHIP_ID_1251_PG12 (0x7030101) - -#define ENABLE (REGISTERS_BASE + 0x5450) - -/* Power Management registers */ -#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) -#define ELP_CMD (REGISTERS_BASE + 0x5808) -#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) -#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) -#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) - -#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) - -/* Scratch Pad registers*/ -#define SCR_PAD0 (REGISTERS_BASE + 0x5608) -#define SCR_PAD1 (REGISTERS_BASE + 0x560C) -#define SCR_PAD2 (REGISTERS_BASE + 0x5610) -#define SCR_PAD3 (REGISTERS_BASE + 0x5614) -#define SCR_PAD4 (REGISTERS_BASE + 0x5618) -#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) -#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) -#define SCR_PAD5 (REGISTERS_BASE + 0x5624) -#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) -#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) -#define SCR_PAD6 (REGISTERS_BASE + 0x5630) -#define SCR_PAD7 (REGISTERS_BASE + 0x5634) -#define SCR_PAD8 (REGISTERS_BASE + 0x5638) -#define SCR_PAD9 (REGISTERS_BASE + 0x563C) - -/* Spare registers*/ -#define SPARE_A1 (REGISTERS_BASE + 0x0994) -#define SPARE_A2 (REGISTERS_BASE + 0x0998) -#define SPARE_A3 (REGISTERS_BASE + 0x099C) -#define SPARE_A4 (REGISTERS_BASE + 0x09A0) -#define SPARE_A5 (REGISTERS_BASE + 0x09A4) -#define SPARE_A6 (REGISTERS_BASE + 0x09A8) -#define SPARE_A7 (REGISTERS_BASE + 0x09AC) -#define SPARE_A8 (REGISTERS_BASE + 0x09B0) -#define SPARE_B1 (REGISTERS_BASE + 0x5420) -#define SPARE_B2 (REGISTERS_BASE + 0x5424) -#define SPARE_B3 (REGISTERS_BASE + 0x5428) -#define SPARE_B4 (REGISTERS_BASE + 0x542C) -#define SPARE_B5 (REGISTERS_BASE + 0x5430) -#define SPARE_B6 (REGISTERS_BASE + 0x5434) -#define SPARE_B7 (REGISTERS_BASE + 0x5438) -#define SPARE_B8 (REGISTERS_BASE + 0x543C) - -enum wl12xx_acx_int_reg { - ACX_REG_INTERRUPT_TRIG, - ACX_REG_INTERRUPT_TRIG_H, - -/*============================================= - Host Interrupt Mask Register - 32bit (RW) - ------------------------------------------ - Setting a bit in this register masks the - corresponding interrupt to the host. - 0 - RX0 - Rx first dubble buffer Data Interrupt - 1 - TXD - Tx Data Interrupt - 2 - TXXFR - Tx Transfer Interrupt - 3 - RX1 - Rx second dubble buffer Data Interrupt - 4 - RXXFR - Rx Transfer Interrupt - 5 - EVENT_A - Event Mailbox interrupt - 6 - EVENT_B - Event Mailbox interrupt - 7 - WNONHST - Wake On Host Interrupt - 8 - TRACE_A - Debug Trace interrupt - 9 - TRACE_B - Debug Trace interrupt - 10 - CDCMP - Command Complete Interrupt - 11 - - 12 - - 13 - - 14 - ICOMP - Initialization Complete Interrupt - 16 - SG SE - Soft Gemini - Sense enable interrupt - 17 - SG SD - Soft Gemini - Sense disable interrupt - 18 - - - 19 - - - 20 - - - 21- - - Default: 0x0001 -*==============================================*/ - ACX_REG_INTERRUPT_MASK, - -/*============================================= - Host Interrupt Mask Set 16bit, (Write only) - ------------------------------------------ - Setting a bit in this register sets - the corresponding bin in ACX_HINT_MASK register - without effecting the mask - state of other bits (0 = no effect). -==============================================*/ - ACX_REG_HINT_MASK_SET, - -/*============================================= - Host Interrupt Mask Clear 16bit,(Write only) - ------------------------------------------ - Setting a bit in this register clears - the corresponding bin in ACX_HINT_MASK register - without effecting the mask - state of other bits (0 = no effect). -=============================================*/ - ACX_REG_HINT_MASK_CLR, - -/*============================================= - Host Interrupt Status Nondestructive Read - 16bit,(Read only) - ------------------------------------------ - The host can read this register to determine - which interrupts are active. - Reading this register doesn't - effect its content. -=============================================*/ - ACX_REG_INTERRUPT_NO_CLEAR, - -/*============================================= - Host Interrupt Status Clear on Read Register - 16bit,(Read only) - ------------------------------------------ - The host can read this register to determine - which interrupts are active. - Reading this register clears it, - thus making all interrupts inactive. -==============================================*/ - ACX_REG_INTERRUPT_CLEAR, - -/*============================================= - Host Interrupt Acknowledge Register - 16bit,(Write only) - ------------------------------------------ - The host can set individual bits in this - register to clear (acknowledge) the corresp. - interrupt status bits in the HINT_STS_CLR and - HINT_STS_ND registers, thus making the - assotiated interrupt inactive. (0-no effect) -==============================================*/ - ACX_REG_INTERRUPT_ACK, - -/*=============================================== - Host Software Reset - 32bit RW - ------------------------------------------ - [31:1] Reserved - 0 SOFT_RESET Soft Reset - When this bit is set, - it holds the Wlan hardware in a soft reset state. - This reset disables all MAC and baseband processor - clocks except the CardBus/PCI interface clock. - It also initializes all MAC state machines except - the host interface. It does not reload the - contents of the EEPROM. When this bit is cleared - (not self-clearing), the Wlan hardware - exits the software reset state. -===============================================*/ - ACX_REG_SLV_SOFT_RESET, - -/*=============================================== - EEPROM Burst Read Start - 32bit RW - ------------------------------------------ - [31:1] Reserved - 0 ACX_EE_START - EEPROM Burst Read Start 0 - Setting this bit starts a burst read from - the external EEPROM. - If this bit is set (after reset) before an EEPROM read/write, - the burst read starts at EEPROM address 0. - Otherwise, it starts at the address - following the address of the previous access. - TheWlan hardware hardware clears this bit automatically. - - Default: 0x00000000 -*================================================*/ - ACX_REG_EE_START, - -/* Embedded ARM CPU Control */ - -/*=============================================== - Halt eCPU - 32bit RW - ------------------------------------------ - 0 HALT_ECPU Halt Embedded CPU - This bit is the - compliment of bit 1 (MDATA2) in the SOR_CFG register. - During a hardware reset, this bit holds - the inverse of MDATA2. - When downloading firmware from the host, - set this bit (pull down MDATA2). - The host clears this bit after downloading the firmware into - zero-wait-state SSRAM. - When loading firmware from Flash, clear this bit (pull up MDATA2) - so that the eCPU can run the bootloader code in Flash - HALT_ECPU eCPU State - -------------------- - 1 halt eCPU - 0 enable eCPU - ===============================================*/ - ACX_REG_ECPU_CONTROL, - - ACX_REG_TABLE_LEN -}; - -#define ACX_SLV_SOFT_RESET_BIT BIT(0) -#define ACX_REG_EEPROM_START_BIT BIT(0) - -/* Command/Information Mailbox Pointers */ - -/*=============================================== - Command Mailbox Pointer - 32bit RW - ------------------------------------------ - This register holds the start address of - the command mailbox located in the Wlan hardware memory. - The host must read this pointer after a reset to - find the location of the command mailbox. - The Wlan hardware initializes the command mailbox - pointer with the default address of the command mailbox. - The command mailbox pointer is not valid until after - the host receives the Init Complete interrupt from - the Wlan hardware. - ===============================================*/ -#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) - -/*=============================================== - Information Mailbox Pointer - 32bit RW - ------------------------------------------ - This register holds the start address of - the information mailbox located in the Wlan hardware memory. - The host must read this pointer after a reset to find - the location of the information mailbox. - The Wlan hardware initializes the information mailbox pointer - with the default address of the information mailbox. - The information mailbox pointer is not valid - until after the host receives the Init Complete interrupt from - the Wlan hardware. - ===============================================*/ -#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) - - -/* Misc */ - -#define REG_ENABLE_TX_RX (ENABLE) -/* - * Rx configuration (filter) information element - * --------------------------------------------- - */ -#define REG_RX_CONFIG (RX_CFG) -#define REG_RX_FILTER (RX_FILTER_CFG) - - -#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002 - -/* promiscuous - receives all valid frames */ -#define RX_CFG_PROMISCUOUS 0x0008 - -/* receives frames from any BSSID */ -#define RX_CFG_BSSID 0x0020 - -/* receives frames destined to any MAC address */ -#define RX_CFG_MAC 0x0010 - -#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010 -#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000 -#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020 -#define RX_CFG_ENABLE_ANY_BSSID 0x0000 - -/* discards all broadcast frames */ -#define RX_CFG_DISABLE_BCAST 0x0200 - -#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400 -#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800 -#define RX_CFG_COPY_RX_STATUS 0x2000 -#define RX_CFG_TSF 0x10000 - -#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ - RX_CFG_ENABLE_ONLY_MY_BSSID) - -#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ - | RX_CFG_ENABLE_ANY_BSSID) - -#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \ - RX_CFG_ENABLE_ANY_BSSID) - -#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\ - | RX_CFG_ENABLE_ONLY_MY_BSSID) - -#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \ - | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \ - | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF) - -#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC) - -#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \ - RX_CFG_ENABLE_ONLY_MY_DEST_MAC) - -#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \ - RX_CFG_ENABLE_ONLY_MY_DEST_MAC) - -#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ - | CFG_RX_CTL_EN | CFG_RX_BCN_EN\ - | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) - -#define RX_FILTER_OPTION_FILTER_ALL 0 - -#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\ - | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN) - -#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\ - | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\ - | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\ - | CFG_RX_PRSP_EN) - - -/*=============================================== - EEPROM Read/Write Request 32bit RW - ------------------------------------------ - 1 EE_READ - EEPROM Read Request 1 - Setting this bit - loads a single byte of data into the EE_DATA - register from the EEPROM location specified in - the EE_ADDR register. - The Wlan hardware hardware clears this bit automatically. - EE_DATA is valid when this bit is cleared. - - 0 EE_WRITE - EEPROM Write Request - Setting this bit - writes a single byte of data from the EE_DATA register into the - EEPROM location specified in the EE_ADDR register. - The Wlan hardware hardware clears this bit automatically. -*===============================================*/ -#define EE_CTL (REGISTERS_BASE + 0x2000) -#define ACX_EE_CTL_REG EE_CTL -#define EE_WRITE 0x00000001ul -#define EE_READ 0x00000002ul - -/*=============================================== - EEPROM Address - 32bit RW - ------------------------------------------ - This register specifies the address - within the EEPROM from/to which to read/write data. - ===============================================*/ -#define EE_ADDR (REGISTERS_BASE + 0x2008) -#define ACX_EE_ADDR_REG EE_ADDR - -/*=============================================== - EEPROM Data - 32bit RW - ------------------------------------------ - This register either holds the read 8 bits of - data from the EEPROM or the write data - to be written to the EEPROM. - ===============================================*/ -#define EE_DATA (REGISTERS_BASE + 0x2004) -#define ACX_EE_DATA_REG EE_DATA - -#define EEPROM_ACCESS_TO 10000 /* timeout counter */ -#define START_EEPROM_MGR 0x00000001 - -/*=============================================== - EEPROM Base Address - 32bit RW - ------------------------------------------ - This register holds the upper nine bits - [23:15] of the 24-bit Wlan hardware memory - address for burst reads from EEPROM accesses. - The EEPROM provides the lower 15 bits of this address. - The MSB of the address from the EEPROM is ignored. - ===============================================*/ -#define ACX_EE_CFG EE_CFG - -/*=============================================== - GPIO Output Values -32bit, RW - ------------------------------------------ - [31:16] Reserved - [15: 0] Specify the output values (at the output driver inputs) for - GPIO[15:0], respectively. - ===============================================*/ -#define ACX_GPIO_OUT_REG GPIO_OUT -#define ACX_MAX_GPIO_LINES 15 - -/*=============================================== - Contention window -32bit, RW - ------------------------------------------ - [31:26] Reserved - [25:16] Max (0x3ff) - [15:07] Reserved - [06:00] Current contention window value - default is 0x1F - ===============================================*/ -#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG -#define ACX_CONT_WIND_MIN_MASK 0x0000007f -#define ACX_CONT_WIND_MAX 0x03ff0000 - -/*=============================================== - HI_CFG Interface Configuration Register Values - ------------------------------------------ - ===============================================*/ -#define HI_CFG_UART_ENABLE 0x00000004 -#define HI_CFG_RST232_ENABLE 0x00000008 -#define HI_CFG_CLOCK_REQ_SELECT 0x00000010 -#define HI_CFG_HOST_INT_ENABLE 0x00000020 -#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040 -#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080 -#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100 -#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 -#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 - -/* - * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile - * for platforms using active high interrupt level - */ -#ifdef USE_ACTIVE_HIGH -#define HI_CFG_DEF_VAL \ - (HI_CFG_UART_ENABLE | \ - HI_CFG_RST232_ENABLE | \ - HI_CFG_CLOCK_REQ_SELECT | \ - HI_CFG_HOST_INT_ENABLE) -#else -#define HI_CFG_DEF_VAL \ - (HI_CFG_UART_ENABLE | \ - HI_CFG_RST232_ENABLE | \ - HI_CFG_CLOCK_REQ_SELECT | \ - HI_CFG_HOST_INT_ENABLE) - -#endif - -#define REF_FREQ_19_2 0 -#define REF_FREQ_26_0 1 -#define REF_FREQ_38_4 2 -#define REF_FREQ_40_0 3 -#define REF_FREQ_33_6 4 -#define REF_FREQ_NUM 5 - -#define LUT_PARAM_INTEGER_DIVIDER 0 -#define LUT_PARAM_FRACTIONAL_DIVIDER 1 -#define LUT_PARAM_ATTN_BB 2 -#define LUT_PARAM_ALPHA_BB 3 -#define LUT_PARAM_STOP_TIME_BB 4 -#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 -#define LUT_PARAM_NUM 6 - -#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) -#define USE_EEPROM 0 -#define SOFT_RESET_MAX_TIME 1000000 -#define SOFT_RESET_STALL_TIME 1000 -#define NVS_DATA_BUNDARY_ALIGNMENT 4 - - -/* Firmware image load chunk size */ -#define CHUNK_SIZE 512 - -/* Firmware image header size */ -#define FW_HDR_SIZE 8 - -#define ECPU_CONTROL_HALT 0x00000101 - - -/****************************************************************************** - - CHANNELS, BAND & REG DOMAINS definitions - -******************************************************************************/ - - -enum { - RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */ - RADIO_BAND_5GHZ = 1, /* 5 Ghz band */ - RADIO_BAND_JAPAN_4_9_GHZ = 2, - DEFAULT_BAND = RADIO_BAND_2_4GHZ, - INVALID_BAND = 0xFE, - MAX_RADIO_BANDS = 0xFF -}; - -enum { - NO_RATE = 0, - RATE_1MBPS = 0x0A, - RATE_2MBPS = 0x14, - RATE_5_5MBPS = 0x37, - RATE_6MBPS = 0x0B, - RATE_9MBPS = 0x0F, - RATE_11MBPS = 0x6E, - RATE_12MBPS = 0x0A, - RATE_18MBPS = 0x0E, - RATE_22MBPS = 0xDC, - RATE_24MBPS = 0x09, - RATE_36MBPS = 0x0D, - RATE_48MBPS = 0x08, - RATE_54MBPS = 0x0C -}; - -enum { - RATE_INDEX_1MBPS = 0, - RATE_INDEX_2MBPS = 1, - RATE_INDEX_5_5MBPS = 2, - RATE_INDEX_6MBPS = 3, - RATE_INDEX_9MBPS = 4, - RATE_INDEX_11MBPS = 5, - RATE_INDEX_12MBPS = 6, - RATE_INDEX_18MBPS = 7, - RATE_INDEX_22MBPS = 8, - RATE_INDEX_24MBPS = 9, - RATE_INDEX_36MBPS = 10, - RATE_INDEX_48MBPS = 11, - RATE_INDEX_54MBPS = 12, - RATE_INDEX_MAX = RATE_INDEX_54MBPS, - MAX_RATE_INDEX, - INVALID_RATE_INDEX = MAX_RATE_INDEX, - RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF -}; - -enum { - RATE_MASK_1MBPS = 0x1, - RATE_MASK_2MBPS = 0x2, - RATE_MASK_5_5MBPS = 0x4, - RATE_MASK_11MBPS = 0x20, -}; - -#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ -#define OFDM_RATE_BIT BIT(6) -#define PBCC_RATE_BIT BIT(7) - -enum { - CCK_LONG = 0, - CCK_SHORT = SHORT_PREAMBLE_BIT, - PBCC_LONG = PBCC_RATE_BIT, - PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT, - OFDM = OFDM_RATE_BIT -}; - -/****************************************************************************** - -Transmit-Descriptor RATE-SET field definitions... - -Define a new "Rate-Set" for TX path that incorporates the -Rate & Modulation info into a single 16-bit field. - -TxdRateSet_t: -b15 - Indicates Preamble type (1=SHORT, 0=LONG). - Notes: - Must be LONG (0) for 1Mbps rate. - Does not apply (set to 0) for RevG-OFDM rates. -b14 - Indicates PBCC encoding (1=PBCC, 0=not). - Notes: - Does not apply (set to 0) for rates 1 and 2 Mbps. - Does not apply (set to 0) for RevG-OFDM rates. -b13 - Unused (set to 0). -b12-b0 - Supported Rate indicator bits as defined below. - -******************************************************************************/ - - -/************************************************************************* - - Interrupt Trigger Register (Host -> WiLink) - -**************************************************************************/ - -/* Hardware to Embedded CPU Interrupts - first 32-bit register set */ - -/* - * Host Command Interrupt. Setting this bit masks - * the interrupt that the host issues to inform - * the FW that it has sent a command - * to the Wlan hardware Command Mailbox. - */ -#define INTR_TRIG_CMD BIT(0) - -/* - * Host Event Acknowlegde Interrupt. The host - * sets this bit to acknowledge that it received - * the unsolicited information from the event - * mailbox. - */ -#define INTR_TRIG_EVENT_ACK BIT(1) - -/* - * The host sets this bit to inform the Wlan - * FW that a TX packet is in the XFER - * Buffer #0. - */ -#define INTR_TRIG_TX_PROC0 BIT(2) - -/* - * The host sets this bit to inform the FW - * that it read a packet from RX XFER - * Buffer #0. - */ -#define INTR_TRIG_RX_PROC0 BIT(3) - -#define INTR_TRIG_DEBUG_ACK BIT(4) - -#define INTR_TRIG_STATE_CHANGED BIT(5) - - -/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ - -/* - * The host sets this bit to inform the FW - * that it read a packet from RX XFER - * Buffer #1. - */ -#define INTR_TRIG_RX_PROC1 BIT(17) - -/* - * The host sets this bit to inform the Wlan - * hardware that a TX packet is in the XFER - * Buffer #1. - */ -#define INTR_TRIG_TX_PROC1 BIT(18) - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c deleted file mode 100644 index 25764592a596..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_rx.h" -#include "wl1251_cmd.h" -#include "wl1251_acx.h" - -static void wl1251_rx_header(struct wl1251 *wl, - struct wl1251_rx_descriptor *desc) -{ - u32 rx_packet_ring_addr; - - rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr; - if (wl->rx_current_buffer) - rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; - - wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc)); -} - -static void wl1251_rx_status(struct wl1251 *wl, - struct wl1251_rx_descriptor *desc, - struct ieee80211_rx_status *status, - u8 beacon) -{ - u64 mactime; - int ret; - - memset(status, 0, sizeof(struct ieee80211_rx_status)); - - status->band = IEEE80211_BAND_2GHZ; - status->mactime = desc->timestamp; - - /* - * The rx status timestamp is a 32 bits value while the TSF is a - * 64 bits one. - * For IBSS merging, TSF is mandatory, so we have to get it - * somehow, so we ask for ACX_TSF_INFO. - * That could be moved to the get_tsf() hook, but unfortunately, - * this one must be atomic, while our SPI routines can sleep. - */ - if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) { - ret = wl1251_acx_tsf_info(wl, &mactime); - if (ret == 0) - status->mactime = mactime; - } - - status->signal = desc->rssi; - - /* - * FIXME: guessing that snr needs to be divided by two, otherwise - * the values don't make any sense - */ - wl->noise = desc->rssi - desc->snr / 2; - - status->freq = ieee80211_channel_to_frequency(desc->channel); - - status->flag |= RX_FLAG_TSFT; - - if (desc->flags & RX_DESC_ENCRYPTION_MASK) { - status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; - - if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL))) - status->flag |= RX_FLAG_DECRYPTED; - - if (unlikely(desc->flags & RX_DESC_MIC_FAIL)) - status->flag |= RX_FLAG_MMIC_ERROR; - } - - if (unlikely(!(desc->flags & RX_DESC_VALID_FCS))) - status->flag |= RX_FLAG_FAILED_FCS_CRC; - - - /* FIXME: set status->rate_idx */ -} - -static void wl1251_rx_body(struct wl1251 *wl, - struct wl1251_rx_descriptor *desc) -{ - struct sk_buff *skb; - struct ieee80211_rx_status status; - u8 *rx_buffer, beacon = 0; - u16 length, *fc; - u32 curr_id, last_id_inc, rx_packet_ring_addr; - - length = WL1251_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH); - curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT; - last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1); - - if (last_id_inc != curr_id) { - wl1251_warning("curr ID:%d, last ID inc:%d", - curr_id, last_id_inc); - wl->rx_last_id = curr_id; - } else { - wl->rx_last_id = last_id_inc; - } - - rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr + - sizeof(struct wl1251_rx_descriptor) + 20; - if (wl->rx_current_buffer) - rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size; - - skb = __dev_alloc_skb(length, GFP_KERNEL); - if (!skb) { - wl1251_error("Couldn't allocate RX frame"); - return; - } - - rx_buffer = skb_put(skb, length); - wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); - - /* The actual lenght doesn't include the target's alignment */ - skb->len = desc->length - PLCP_HEADER_LENGTH; - - fc = (u16 *)skb->data; - - if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) - beacon = 1; - - wl1251_rx_status(wl, desc, &status, beacon); - - wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, - beacon ? "beacon" : ""); - - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - ieee80211_rx_ni(wl->hw, skb); -} - -static void wl1251_rx_ack(struct wl1251 *wl) -{ - u32 data, addr; - - if (wl->rx_current_buffer) { - addr = ACX_REG_INTERRUPT_TRIG_H; - data = INTR_TRIG_RX_PROC1; - } else { - addr = ACX_REG_INTERRUPT_TRIG; - data = INTR_TRIG_RX_PROC0; - } - - wl1251_reg_write32(wl, addr, data); - - /* Toggle buffer ring */ - wl->rx_current_buffer = !wl->rx_current_buffer; -} - - -void wl1251_rx(struct wl1251 *wl) -{ - struct wl1251_rx_descriptor *rx_desc; - - if (wl->state != WL1251_STATE_ON) - return; - - rx_desc = wl->rx_descriptor; - - /* We first read the frame's header */ - wl1251_rx_header(wl, rx_desc); - - /* Now we can read the body */ - wl1251_rx_body(wl, rx_desc); - - /* Finally, we need to ACK the RX */ - wl1251_rx_ack(wl); -} diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h deleted file mode 100644 index 4448f635a4d8..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_rx.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_RX_H__ -#define __WL1251_RX_H__ - -#include - -#include "wl1251.h" - -/* - * RX PATH - * - * The Rx path uses a double buffer and an rx_contro structure, each located - * at a fixed address in the device memory. The host keeps track of which - * buffer is available and alternates between them on a per packet basis. - * The size of each of the two buffers is large enough to hold the longest - * 802.3 packet. - * The RX path goes like that: - * 1) The target generates an interrupt each time a new packet is received. - * There are 2 RX interrupts, one for each buffer. - * 2) The host reads the received packet from one of the double buffers. - * 3) The host triggers a target interrupt. - * 4) The target prepares the next RX packet. - */ - -#define WL1251_RX_MAX_RSSI -30 -#define WL1251_RX_MIN_RSSI -95 - -#define WL1251_RX_ALIGN_TO 4 -#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \ - ~(WL1251_RX_ALIGN_TO - 1)) - -#define SHORT_PREAMBLE_BIT BIT(0) -#define OFDM_RATE_BIT BIT(6) -#define PBCC_RATE_BIT BIT(7) - -#define PLCP_HEADER_LENGTH 8 -#define RX_DESC_PACKETID_SHIFT 11 -#define RX_MAX_PACKET_ID 3 - -#define RX_DESC_VALID_FCS 0x0001 -#define RX_DESC_MATCH_RXADDR1 0x0002 -#define RX_DESC_MCAST 0x0004 -#define RX_DESC_STAINTIM 0x0008 -#define RX_DESC_VIRTUAL_BM 0x0010 -#define RX_DESC_BCAST 0x0020 -#define RX_DESC_MATCH_SSID 0x0040 -#define RX_DESC_MATCH_BSSID 0x0080 -#define RX_DESC_ENCRYPTION_MASK 0x0300 -#define RX_DESC_MEASURMENT 0x0400 -#define RX_DESC_SEQNUM_MASK 0x1800 -#define RX_DESC_MIC_FAIL 0x2000 -#define RX_DESC_DECRYPT_FAIL 0x4000 - -struct wl1251_rx_descriptor { - u32 timestamp; /* In microseconds */ - u16 length; /* Paylod length, including headers */ - u16 flags; - - /* - * 0 - 802.11 - * 1 - 802.3 - * 2 - IP - * 3 - Raw Codec - */ - u8 type; - - /* - * Received Rate: - * 0x0A - 1MBPS - * 0x14 - 2MBPS - * 0x37 - 5_5MBPS - * 0x0B - 6MBPS - * 0x0F - 9MBPS - * 0x6E - 11MBPS - * 0x0A - 12MBPS - * 0x0E - 18MBPS - * 0xDC - 22MBPS - * 0x09 - 24MBPS - * 0x0D - 36MBPS - * 0x08 - 48MBPS - * 0x0C - 54MBPS - */ - u8 rate; - - u8 mod_pre; /* Modulation and preamble */ - u8 channel; - - /* - * 0 - 2.4 Ghz - * 1 - 5 Ghz - */ - u8 band; - - s8 rssi; /* in dB */ - u8 rcpi; /* in dB */ - u8 snr; /* in dB */ -} __packed; - -void wl1251_rx(struct wl1251 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c deleted file mode 100644 index 74ba9ced5393..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * wl12xx SDIO routines - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - * Copyright (C) 2005 Texas Instruments Incorporated - * Copyright (C) 2008 Google Inc - * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) - */ -#include -#include -#include -#include -#include -#include -#include - -#include "wl1251.h" - -#ifndef SDIO_VENDOR_ID_TI -#define SDIO_VENDOR_ID_TI 0x104c -#endif - -#ifndef SDIO_DEVICE_ID_TI_WL1251 -#define SDIO_DEVICE_ID_TI_WL1251 0x9066 -#endif - -struct wl1251_sdio { - struct sdio_func *func; - u32 elp_val; -}; - -static struct wl12xx_platform_data *wl12xx_board_data; - -static struct sdio_func *wl_to_func(struct wl1251 *wl) -{ - struct wl1251_sdio *wl_sdio = wl->if_priv; - return wl_sdio->func; -} - -static void wl1251_sdio_interrupt(struct sdio_func *func) -{ - struct wl1251 *wl = sdio_get_drvdata(func); - - wl1251_debug(DEBUG_IRQ, "IRQ"); - - /* FIXME should be synchronous for sdio */ - ieee80211_queue_work(wl->hw, &wl->irq_work); -} - -static const struct sdio_device_id wl1251_devices[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) }, - {} -}; -MODULE_DEVICE_TABLE(sdio, wl1251_devices); - - -static void wl1251_sdio_read(struct wl1251 *wl, int addr, - void *buf, size_t len) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - ret = sdio_memcpy_fromio(func, buf, addr, len); - if (ret) - wl1251_error("sdio read failed (%d)", ret); - sdio_release_host(func); -} - -static void wl1251_sdio_write(struct wl1251 *wl, int addr, - void *buf, size_t len) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - ret = sdio_memcpy_toio(func, addr, buf, len); - if (ret) - wl1251_error("sdio write failed (%d)", ret); - sdio_release_host(func); -} - -static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) -{ - int ret = 0; - struct wl1251_sdio *wl_sdio = wl->if_priv; - struct sdio_func *func = wl_sdio->func; - - /* - * The hardware only supports RAW (read after write) access for - * reading, regular sdio_readb won't work here (it interprets - * the unused bits of CMD52 as write data even if we send read - * request). - */ - sdio_claim_host(func); - *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret); - sdio_release_host(func); - - if (ret) - wl1251_error("sdio_readb failed (%d)", ret); -} - -static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) -{ - int ret = 0; - struct wl1251_sdio *wl_sdio = wl->if_priv; - struct sdio_func *func = wl_sdio->func; - - sdio_claim_host(func); - sdio_writeb(func, val, addr, &ret); - sdio_release_host(func); - - if (ret) - wl1251_error("sdio_writeb failed (%d)", ret); - else - wl_sdio->elp_val = val; -} - -static void wl1251_sdio_reset(struct wl1251 *wl) -{ -} - -static void wl1251_sdio_enable_irq(struct wl1251 *wl) -{ - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - sdio_claim_irq(func, wl1251_sdio_interrupt); - sdio_release_host(func); -} - -static void wl1251_sdio_disable_irq(struct wl1251 *wl) -{ - struct sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - sdio_release_irq(func); - sdio_release_host(func); -} - -/* Interrupts when using dedicated WLAN_IRQ pin */ -static irqreturn_t wl1251_line_irq(int irq, void *cookie) -{ - struct wl1251 *wl = cookie; - - ieee80211_queue_work(wl->hw, &wl->irq_work); - - return IRQ_HANDLED; -} - -static void wl1251_enable_line_irq(struct wl1251 *wl) -{ - return enable_irq(wl->irq); -} - -static void wl1251_disable_line_irq(struct wl1251 *wl) -{ - return disable_irq(wl->irq); -} - -static void wl1251_sdio_set_power(bool enable) -{ -} - -static struct wl1251_if_operations wl1251_sdio_ops = { - .read = wl1251_sdio_read, - .write = wl1251_sdio_write, - .write_elp = wl1251_sdio_write_elp, - .read_elp = wl1251_sdio_read_elp, - .reset = wl1251_sdio_reset, -}; - -static int wl1251_platform_probe(struct platform_device *pdev) -{ - if (pdev->id != -1) { - wl1251_error("can only handle single device"); - return -ENODEV; - } - - wl12xx_board_data = pdev->dev.platform_data; - return 0; -} - -/* - * Dummy platform_driver for passing platform_data to this driver, - * until we have a way to pass this through SDIO subsystem or - * some other way. - */ -static struct platform_driver wl1251_platform_driver = { - .driver = { - .name = "wl1251_data", - .owner = THIS_MODULE, - }, - .probe = wl1251_platform_probe, -}; - -static int wl1251_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret; - struct wl1251 *wl; - struct ieee80211_hw *hw; - struct wl1251_sdio *wl_sdio; - - hw = wl1251_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); - if (wl_sdio == NULL) { - ret = -ENOMEM; - goto out_free_hw; - } - - sdio_claim_host(func); - ret = sdio_enable_func(func); - if (ret) - goto release; - - sdio_set_block_size(func, 512); - sdio_release_host(func); - - SET_IEEE80211_DEV(hw, &func->dev); - wl_sdio->func = func; - wl->if_priv = wl_sdio; - wl->if_ops = &wl1251_sdio_ops; - wl->set_power = wl1251_sdio_set_power; - - if (wl12xx_board_data != NULL) { - wl->set_power = wl12xx_board_data->set_power; - wl->irq = wl12xx_board_data->irq; - wl->use_eeprom = wl12xx_board_data->use_eeprom; - } - - if (wl->irq) { - ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); - if (ret < 0) { - wl1251_error("request_irq() failed: %d", ret); - goto disable; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); - - wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; - wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; - - wl1251_info("using dedicated interrupt line"); - } else { - wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; - wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; - - wl1251_info("using SDIO interrupt"); - } - - ret = wl1251_init_ieee80211(wl); - if (ret) - goto out_free_irq; - - sdio_set_drvdata(func, wl); - return ret; - -out_free_irq: - if (wl->irq) - free_irq(wl->irq, wl); -disable: - sdio_claim_host(func); - sdio_disable_func(func); -release: - sdio_release_host(func); - kfree(wl_sdio); -out_free_hw: - wl1251_free_hw(wl); - return ret; -} - -static void __devexit wl1251_sdio_remove(struct sdio_func *func) -{ - struct wl1251 *wl = sdio_get_drvdata(func); - struct wl1251_sdio *wl_sdio = wl->if_priv; - - if (wl->irq) - free_irq(wl->irq, wl); - kfree(wl_sdio); - wl1251_free_hw(wl); - - sdio_claim_host(func); - sdio_release_irq(func); - sdio_disable_func(func); - sdio_release_host(func); -} - -static struct sdio_driver wl1251_sdio_driver = { - .name = "wl1251_sdio", - .id_table = wl1251_devices, - .probe = wl1251_sdio_probe, - .remove = __devexit_p(wl1251_sdio_remove), -}; - -static int __init wl1251_sdio_init(void) -{ - int err; - - err = platform_driver_register(&wl1251_platform_driver); - if (err) { - wl1251_error("failed to register platform driver: %d", err); - return err; - } - - err = sdio_register_driver(&wl1251_sdio_driver); - if (err) - wl1251_error("failed to register sdio driver: %d", err); - return err; -} - -static void __exit wl1251_sdio_exit(void) -{ - sdio_unregister_driver(&wl1251_sdio_driver); - platform_driver_unregister(&wl1251_platform_driver); - wl1251_notice("unloaded"); -} - -module_init(wl1251_sdio_init); -module_exit(wl1251_sdio_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c deleted file mode 100644 index 320de79667a6..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include -#include - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_spi.h" - -static irqreturn_t wl1251_irq(int irq, void *cookie) -{ - struct wl1251 *wl; - - wl1251_debug(DEBUG_IRQ, "IRQ"); - - wl = cookie; - - ieee80211_queue_work(wl->hw, &wl->irq_work); - - return IRQ_HANDLED; -} - -static struct spi_device *wl_to_spi(struct wl1251 *wl) -{ - return wl->if_priv; -} - -static void wl1251_spi_reset(struct wl1251 *wl) -{ - u8 *cmd; - struct spi_transfer t; - struct spi_message m; - - cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); - if (!cmd) { - wl1251_error("could not allocate cmd for spi reset"); - return; - } - - memset(&t, 0, sizeof(t)); - spi_message_init(&m); - - memset(cmd, 0xff, WSPI_INIT_CMD_LEN); - - t.tx_buf = cmd; - t.len = WSPI_INIT_CMD_LEN; - spi_message_add_tail(&t, &m); - - spi_sync(wl_to_spi(wl), &m); - - wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); -} - -static void wl1251_spi_wake(struct wl1251 *wl) -{ - u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; - struct spi_transfer t; - struct spi_message m; - - cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); - if (!cmd) { - wl1251_error("could not allocate cmd for spi init"); - return; - } - - memset(crc, 0, sizeof(crc)); - memset(&t, 0, sizeof(t)); - spi_message_init(&m); - - /* - * Set WSPI_INIT_COMMAND - * the data is being send from the MSB to LSB - */ - cmd[2] = 0xff; - cmd[3] = 0xff; - cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX; - cmd[0] = 0; - cmd[7] = 0; - cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3; - cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN; - - if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0) - cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY; - else - cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY; - - cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS - | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS; - - crc[0] = cmd[1]; - crc[1] = cmd[0]; - crc[2] = cmd[7]; - crc[3] = cmd[6]; - crc[4] = cmd[5]; - - cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1; - cmd[4] |= WSPI_INIT_CMD_END; - - t.tx_buf = cmd; - t.len = WSPI_INIT_CMD_LEN; - spi_message_add_tail(&t, &m); - - spi_sync(wl_to_spi(wl), &m); - - wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); -} - -static void wl1251_spi_reset_wake(struct wl1251 *wl) -{ - wl1251_spi_reset(wl); - wl1251_spi_wake(wl); -} - -static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, - size_t len) -{ - struct spi_transfer t[3]; - struct spi_message m; - u8 *busy_buf; - u32 *cmd; - - cmd = &wl->buffer_cmd; - busy_buf = wl->buffer_busyword; - - *cmd = 0; - *cmd |= WSPI_CMD_READ; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = 4; - spi_message_add_tail(&t[0], &m); - - /* Busy and non busy words read */ - t[1].rx_buf = busy_buf; - t[1].len = WL1251_BUSY_WORD_LEN; - spi_message_add_tail(&t[1], &m); - - t[2].rx_buf = buf; - t[2].len = len; - spi_message_add_tail(&t[2], &m); - - spi_sync(wl_to_spi(wl), &m); - - /* FIXME: check busy words */ - - wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); - wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); -} - -static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, - size_t len) -{ - struct spi_transfer t[2]; - struct spi_message m; - u32 *cmd; - - cmd = &wl->buffer_cmd; - - *cmd = 0; - *cmd |= WSPI_CMD_WRITE; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = sizeof(*cmd); - spi_message_add_tail(&t[0], &m); - - t[1].tx_buf = buf; - t[1].len = len; - spi_message_add_tail(&t[1], &m); - - spi_sync(wl_to_spi(wl), &m); - - wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); - wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); -} - -static void wl1251_spi_enable_irq(struct wl1251 *wl) -{ - return enable_irq(wl->irq); -} - -static void wl1251_spi_disable_irq(struct wl1251 *wl) -{ - return disable_irq(wl->irq); -} - -static const struct wl1251_if_operations wl1251_spi_ops = { - .read = wl1251_spi_read, - .write = wl1251_spi_write, - .reset = wl1251_spi_reset_wake, - .enable_irq = wl1251_spi_enable_irq, - .disable_irq = wl1251_spi_disable_irq, -}; - -static int __devinit wl1251_spi_probe(struct spi_device *spi) -{ - struct wl12xx_platform_data *pdata; - struct ieee80211_hw *hw; - struct wl1251 *wl; - int ret; - - pdata = spi->dev.platform_data; - if (!pdata) { - wl1251_error("no platform data"); - return -ENODEV; - } - - hw = wl1251_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - SET_IEEE80211_DEV(hw, &spi->dev); - dev_set_drvdata(&spi->dev, wl); - wl->if_priv = spi; - wl->if_ops = &wl1251_spi_ops; - - /* This is the only SPI value that we need to set here, the rest - * comes from the board-peripherals file */ - spi->bits_per_word = 32; - - ret = spi_setup(spi); - if (ret < 0) { - wl1251_error("spi_setup failed"); - goto out_free; - } - - wl->set_power = pdata->set_power; - if (!wl->set_power) { - wl1251_error("set power function missing in platform data"); - return -ENODEV; - } - - wl->irq = spi->irq; - if (wl->irq < 0) { - wl1251_error("irq missing in platform data"); - return -ENODEV; - } - - wl->use_eeprom = pdata->use_eeprom; - - ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); - if (ret < 0) { - wl1251_error("request_irq() failed: %d", ret); - goto out_free; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - - disable_irq(wl->irq); - - ret = wl1251_init_ieee80211(wl); - if (ret) - goto out_irq; - - return 0; - - out_irq: - free_irq(wl->irq, wl); - - out_free: - ieee80211_free_hw(hw); - - return ret; -} - -static int __devexit wl1251_spi_remove(struct spi_device *spi) -{ - struct wl1251 *wl = dev_get_drvdata(&spi->dev); - - free_irq(wl->irq, wl); - wl1251_free_hw(wl); - - return 0; -} - -static struct spi_driver wl1251_spi_driver = { - .driver = { - .name = DRIVER_NAME, - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = wl1251_spi_probe, - .remove = __devexit_p(wl1251_spi_remove), -}; - -static int __init wl1251_spi_init(void) -{ - int ret; - - ret = spi_register_driver(&wl1251_spi_driver); - if (ret < 0) { - wl1251_error("failed to register spi driver: %d", ret); - goto out; - } - -out: - return ret; -} - -static void __exit wl1251_spi_exit(void) -{ - spi_unregister_driver(&wl1251_spi_driver); - - wl1251_notice("unloaded"); -} - -module_init(wl1251_spi_init); -module_exit(wl1251_spi_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); -MODULE_ALIAS("spi:wl1251"); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h deleted file mode 100644 index 7dcf3cf7ae40..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_spi.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_SPI_H__ -#define __WL1251_SPI_H__ - -#include "wl1251_cmd.h" -#include "wl1251_acx.h" -#include "wl1251_reg.h" - -#define WSPI_CMD_READ 0x40000000 -#define WSPI_CMD_WRITE 0x00000000 -#define WSPI_CMD_FIXED 0x20000000 -#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 -#define WSPI_CMD_BYTE_LENGTH_OFFSET 17 -#define WSPI_CMD_BYTE_ADDR 0x0001FFFF - -#define WSPI_INIT_CMD_CRC_LEN 5 - -#define WSPI_INIT_CMD_START 0x00 -#define WSPI_INIT_CMD_TX 0x40 -/* the extra bypass bit is sampled by the TNET as '1' */ -#define WSPI_INIT_CMD_BYPASS_BIT 0x80 -#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 -#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 -#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 -#define WSPI_INIT_CMD_IOD 0x40 -#define WSPI_INIT_CMD_IP 0x20 -#define WSPI_INIT_CMD_CS 0x10 -#define WSPI_INIT_CMD_WS 0x08 -#define WSPI_INIT_CMD_WSPI 0x01 -#define WSPI_INIT_CMD_END 0x01 - -#define WSPI_INIT_CMD_LEN 8 - -#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ - ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32)) -#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 - -#endif /* __WL1251_SPI_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c deleted file mode 100644 index 388492a7f41f..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include - -#include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_tx.h" -#include "wl1251_ps.h" -#include "wl1251_io.h" - -static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) -{ - int used, data_in_count; - - data_in_count = wl->data_in_count; - - if (data_in_count < data_out_count) - /* data_in_count has wrapped */ - data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1; - - used = data_in_count - data_out_count; - - WARN_ON(used < 0); - WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM); - - if (used >= DP_TX_PACKET_RING_CHUNK_NUM) - return true; - else - return false; -} - -static int wl1251_tx_path_status(struct wl1251 *wl) -{ - u32 status, addr, data_out_count; - bool busy; - - addr = wl->data_path->tx_control_addr; - status = wl1251_mem_read32(wl, addr); - data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK; - busy = wl1251_tx_double_buffer_busy(wl, data_out_count); - - if (busy) - return -EBUSY; - - return 0; -} - -static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb) -{ - int i; - - for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) - if (wl->tx_frames[i] == NULL) { - wl->tx_frames[i] = skb; - return i; - } - - return -EBUSY; -} - -static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr, - struct ieee80211_tx_info *control, u16 fc) -{ - *(u16 *)&tx_hdr->control = 0; - - tx_hdr->control.rate_policy = 0; - - /* 802.11 packets */ - tx_hdr->control.packet_type = 0; - - if (control->flags & IEEE80211_TX_CTL_NO_ACK) - tx_hdr->control.ack_policy = 1; - - tx_hdr->control.tx_complete = 1; - - if ((fc & IEEE80211_FTYPE_DATA) && - ((fc & IEEE80211_STYPE_QOS_DATA) || - (fc & IEEE80211_STYPE_QOS_NULLFUNC))) - tx_hdr->control.qos = 1; -} - -/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */ -#define MAX_MSDU_SECURITY_LENGTH 16 -#define MAX_MPDU_SECURITY_LENGTH 16 -#define WLAN_QOS_HDR_LEN 26 -#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \ - WLAN_QOS_HDR_LEN) -#define HW_BLOCK_SIZE 252 -static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr) -{ - u16 payload_len, frag_threshold, mem_blocks; - u16 num_mpdus, mem_blocks_per_frag; - - frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - tx_hdr->frag_threshold = cpu_to_le16(frag_threshold); - - payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH; - - if (payload_len > frag_threshold) { - mem_blocks_per_frag = - ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) / - HW_BLOCK_SIZE) + 1; - num_mpdus = payload_len / frag_threshold; - mem_blocks = num_mpdus * mem_blocks_per_frag; - payload_len -= num_mpdus * frag_threshold; - num_mpdus++; - - } else { - mem_blocks_per_frag = 0; - mem_blocks = 0; - num_mpdus = 1; - } - - mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1; - - if (num_mpdus > 1) - mem_blocks += min(num_mpdus, mem_blocks_per_frag); - - tx_hdr->num_mem_blocks = mem_blocks; -} - -static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb, - struct ieee80211_tx_info *control) -{ - struct tx_double_buffer_desc *tx_hdr; - struct ieee80211_rate *rate; - int id; - u16 fc; - - if (!skb) - return -EINVAL; - - id = wl1251_tx_id(wl, skb); - if (id < 0) - return id; - - fc = *(u16 *)skb->data; - tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb, - sizeof(*tx_hdr)); - - tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr)); - rate = ieee80211_get_tx_rate(wl->hw, control); - tx_hdr->rate = cpu_to_le16(rate->hw_value); - tx_hdr->expiry_time = cpu_to_le32(1 << 16); - tx_hdr->id = id; - - tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb)); - - wl1251_tx_control(tx_hdr, control, fc); - wl1251_tx_frag_block_num(tx_hdr); - - return 0; -} - -/* We copy the packet to the target */ -static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, - struct ieee80211_tx_info *control) -{ - struct tx_double_buffer_desc *tx_hdr; - int len; - u32 addr; - - if (!skb) - return -EINVAL; - - tx_hdr = (struct tx_double_buffer_desc *) skb->data; - - if (control->control.hw_key && - control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { - int hdrlen; - __le16 fc; - u16 length; - u8 *pos; - - fc = *(__le16 *)(skb->data + sizeof(*tx_hdr)); - length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE; - tx_hdr->length = cpu_to_le16(length); - - hdrlen = ieee80211_hdrlen(fc); - - pos = skb_push(skb, WL1251_TKIP_IV_SPACE); - memmove(pos, pos + WL1251_TKIP_IV_SPACE, - sizeof(*tx_hdr) + hdrlen); - } - - /* Revisit. This is a workaround for getting non-aligned packets. - This happens at least with EAPOL packets from the user space. - Our DMA requires packets to be aligned on a 4-byte boundary. - */ - if (unlikely((long)skb->data & 0x03)) { - int offset = (4 - (long)skb->data) & 0x03; - wl1251_debug(DEBUG_TX, "skb offset %d", offset); - - /* check whether the current skb can be used */ - if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { - unsigned char *src = skb->data; - - /* align the buffer on a 4-byte boundary */ - skb_reserve(skb, offset); - memmove(skb->data, src, skb->len); - tx_hdr = (struct tx_double_buffer_desc *) skb->data; - } else { - wl1251_info("No handler, fixme!"); - return -EINVAL; - } - } - - /* Our skb->data at this point includes the HW header */ - len = WL1251_TX_ALIGN(skb->len); - - if (wl->data_in_count & 0x1) - addr = wl->data_path->tx_packet_ring_addr + - wl->data_path->tx_packet_ring_chunk_size; - else - addr = wl->data_path->tx_packet_ring_addr; - - wl1251_mem_write(wl, addr, skb->data, len); - - wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x " - "queue %d", tx_hdr->id, skb, tx_hdr->length, - tx_hdr->rate, tx_hdr->xmit_queue); - - return 0; -} - -static void wl1251_tx_trigger(struct wl1251 *wl) -{ - u32 data, addr; - - if (wl->data_in_count & 0x1) { - addr = ACX_REG_INTERRUPT_TRIG_H; - data = INTR_TRIG_TX_PROC1; - } else { - addr = ACX_REG_INTERRUPT_TRIG; - data = INTR_TRIG_TX_PROC0; - } - - wl1251_reg_write32(wl, addr, data); - - /* Bumping data in */ - wl->data_in_count = (wl->data_in_count + 1) & - TX_STATUS_DATA_OUT_COUNT_MASK; -} - -/* caller must hold wl->mutex */ -static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info; - int ret = 0; - u8 idx; - - info = IEEE80211_SKB_CB(skb); - - if (info->control.hw_key) { - idx = info->control.hw_key->hw_key_idx; - if (unlikely(wl->default_key != idx)) { - ret = wl1251_acx_default_key(wl, idx); - if (ret < 0) - return ret; - } - } - - ret = wl1251_tx_path_status(wl); - if (ret < 0) - return ret; - - ret = wl1251_tx_fill_hdr(wl, skb, info); - if (ret < 0) - return ret; - - ret = wl1251_tx_send_packet(wl, skb, info); - if (ret < 0) - return ret; - - wl1251_tx_trigger(wl); - - return ret; -} - -void wl1251_tx_work(struct work_struct *work) -{ - struct wl1251 *wl = container_of(work, struct wl1251, tx_work); - struct sk_buff *skb; - bool woken_up = false; - int ret; - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1251_STATE_OFF)) - goto out; - - while ((skb = skb_dequeue(&wl->tx_queue))) { - if (!woken_up) { - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - woken_up = true; - } - - ret = wl1251_tx_frame(wl, skb); - if (ret == -EBUSY) { - skb_queue_head(&wl->tx_queue, skb); - goto out; - } else if (ret < 0) { - dev_kfree_skb(skb); - goto out; - } - } - -out: - if (woken_up) - wl1251_ps_elp_sleep(wl); - - mutex_unlock(&wl->mutex); -} - -static const char *wl1251_tx_parse_status(u8 status) -{ - /* 8 bit status field, one character per bit plus null */ - static char buf[9]; - int i = 0; - - memset(buf, 0, sizeof(buf)); - - if (status & TX_DMA_ERROR) - buf[i++] = 'm'; - if (status & TX_DISABLED) - buf[i++] = 'd'; - if (status & TX_RETRY_EXCEEDED) - buf[i++] = 'r'; - if (status & TX_TIMEOUT) - buf[i++] = 't'; - if (status & TX_KEY_NOT_FOUND) - buf[i++] = 'k'; - if (status & TX_ENCRYPT_FAIL) - buf[i++] = 'e'; - if (status & TX_UNAVAILABLE_PRIORITY) - buf[i++] = 'p'; - - /* bit 0 is unused apparently */ - - return buf; -} - -static void wl1251_tx_packet_cb(struct wl1251 *wl, - struct tx_result *result) -{ - struct ieee80211_tx_info *info; - struct sk_buff *skb; - int hdrlen, ret; - u8 *frame; - - skb = wl->tx_frames[result->id]; - if (skb == NULL) { - wl1251_error("SKB for packet %d is NULL", result->id); - return; - } - - info = IEEE80211_SKB_CB(skb); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (result->status == TX_SUCCESS)) - info->flags |= IEEE80211_TX_STAT_ACK; - - info->status.rates[0].count = result->ack_failures + 1; - wl->stats.retry_count += result->ack_failures; - - /* - * We have to remove our private TX header before pushing - * the skb back to mac80211. - */ - frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc)); - if (info->control.hw_key && - info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen); - skb_pull(skb, WL1251_TKIP_IV_SPACE); - } - - wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" - " status 0x%x (%s)", - result->id, skb, result->ack_failures, result->rate, - result->status, wl1251_tx_parse_status(result->status)); - - - ieee80211_tx_status(wl->hw, skb); - - wl->tx_frames[result->id] = NULL; - - if (wl->tx_queue_stopped) { - wl1251_debug(DEBUG_TX, "cb: queue was stopped"); - - skb = skb_dequeue(&wl->tx_queue); - - /* The skb can be NULL because tx_work might have been - scheduled before the queue was stopped making the - queue empty */ - - if (skb) { - ret = wl1251_tx_frame(wl, skb); - if (ret == -EBUSY) { - /* firmware buffer is still full */ - wl1251_debug(DEBUG_TX, "cb: fw buffer " - "still full"); - skb_queue_head(&wl->tx_queue, skb); - return; - } else if (ret < 0) { - dev_kfree_skb(skb); - return; - } - } - - wl1251_debug(DEBUG_TX, "cb: waking queues"); - ieee80211_wake_queues(wl->hw); - wl->tx_queue_stopped = false; - } -} - -/* Called upon reception of a TX complete interrupt */ -void wl1251_tx_complete(struct wl1251 *wl) -{ - int i, result_index, num_complete = 0; - struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; - unsigned long flags; - - if (unlikely(wl->state != WL1251_STATE_ON)) - return; - - /* First we read the result */ - wl1251_mem_read(wl, wl->data_path->tx_complete_addr, - result, sizeof(result)); - - result_index = wl->next_tx_complete; - - for (i = 0; i < ARRAY_SIZE(result); i++) { - result_ptr = &result[result_index]; - - if (result_ptr->done_1 == 1 && - result_ptr->done_2 == 1) { - wl1251_tx_packet_cb(wl, result_ptr); - - result_ptr->done_1 = 0; - result_ptr->done_2 = 0; - - result_index = (result_index + 1) & - (FW_TX_CMPLT_BLOCK_SIZE - 1); - num_complete++; - } else { - break; - } - } - - if (wl->tx_queue_stopped - && - skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){ - - /* firmware buffer has space, restart queues */ - wl1251_debug(DEBUG_TX, "tx_complete: waking queues"); - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - wl->tx_queue_stopped = false; - spin_unlock_irqrestore(&wl->wl_lock, flags); - ieee80211_queue_work(wl->hw, &wl->tx_work); - - } - - /* Every completed frame needs to be acknowledged */ - if (num_complete) { - /* - * If we've wrapped, we have to clear - * the results in 2 steps. - */ - if (result_index > wl->next_tx_complete) { - /* Only 1 write is needed */ - wl1251_mem_write(wl, - wl->data_path->tx_complete_addr + - (wl->next_tx_complete * - sizeof(struct tx_result)), - &result[wl->next_tx_complete], - num_complete * - sizeof(struct tx_result)); - - - } else if (result_index < wl->next_tx_complete) { - /* 2 writes are needed */ - wl1251_mem_write(wl, - wl->data_path->tx_complete_addr + - (wl->next_tx_complete * - sizeof(struct tx_result)), - &result[wl->next_tx_complete], - (FW_TX_CMPLT_BLOCK_SIZE - - wl->next_tx_complete) * - sizeof(struct tx_result)); - - wl1251_mem_write(wl, - wl->data_path->tx_complete_addr, - result, - (num_complete - - FW_TX_CMPLT_BLOCK_SIZE + - wl->next_tx_complete) * - sizeof(struct tx_result)); - - } else { - /* We have to write the whole array */ - wl1251_mem_write(wl, - wl->data_path->tx_complete_addr, - result, - FW_TX_CMPLT_BLOCK_SIZE * - sizeof(struct tx_result)); - } - - } - - wl->next_tx_complete = result_index; -} - -/* caller must hold wl->mutex */ -void wl1251_tx_flush(struct wl1251 *wl) -{ - int i; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - - /* TX failure */ -/* control->flags = 0; FIXME */ - - while ((skb = skb_dequeue(&wl->tx_queue))) { - info = IEEE80211_SKB_CB(skb); - - wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb); - - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) - continue; - - ieee80211_tx_status(wl->hw, skb); - } - - for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) - if (wl->tx_frames[i] != NULL) { - skb = wl->tx_frames[i]; - info = IEEE80211_SKB_CB(skb); - - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) - continue; - - ieee80211_tx_status(wl->hw, skb); - wl->tx_frames[i] = NULL; - } -} diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h deleted file mode 100644 index 96011e78cd5a..000000000000 --- a/drivers/net/wireless/wl12xx/wl1251_tx.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * This file is part of wl1251 - * - * Copyright (c) 1998-2007 Texas Instruments Incorporated - * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __WL1251_TX_H__ -#define __WL1251_TX_H__ - -#include -#include "wl1251_acx.h" - -/* - * - * TX PATH - * - * The Tx path uses a double buffer and a tx_control structure, each located - * at a fixed address in the device's memory. On startup, the host retrieves - * the pointers to these addresses. A double buffer allows for continuous data - * flow towards the device. The host keeps track of which buffer is available - * and alternates between these two buffers on a per packet basis. - * - * The size of each of the two buffers is large enough to hold the longest - * 802.3 packet - maximum size Ethernet packet + header + descriptor. - * TX complete indication will be received a-synchronously in a TX done cyclic - * buffer which is composed of 16 tx_result descriptors structures and is used - * in a cyclic manner. - * - * The TX (HOST) procedure is as follows: - * 1. Read the Tx path status, that will give the data_out_count. - * 2. goto 1, if not possible. - * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double - * buffer). - * 3. Copy the packet (preceded by double_buffer_desc), if possible. - * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double - * buffer). - * 4. increment data_in_count. - * 5. Inform the firmware by generating a firmware internal interrupt. - * 6. FW will increment data_out_count after it reads the buffer. - * - * The TX Complete procedure: - * 1. To get a TX complete indication the host enables the tx_complete flag in - * the TX descriptor Structure. - * 2. For each packet with a Tx Complete field set, the firmware adds the - * transmit results to the cyclic buffer (txDoneRing) and sets both done_1 - * and done_2 to 1 to indicate driver ownership. - * 3. The firmware sends a Tx Complete interrupt to the host to trigger the - * host to process the new data. Note: interrupt will be send per packet if - * TX complete indication was requested in tx_control or per crossing - * aggregation threshold. - * 4. After receiving the Tx Complete interrupt, the host reads the - * TxDescriptorDone information in a cyclic manner and clears both done_1 - * and done_2 fields. - * - */ - -#define TX_COMPLETE_REQUIRED_BIT 0x80 -#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf - -#define WL1251_TX_ALIGN_TO 4 -#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \ - ~(WL1251_TX_ALIGN_TO - 1)) -#define WL1251_TKIP_IV_SPACE 4 - -struct tx_control { - /* Rate Policy (class) index */ - unsigned rate_policy:3; - - /* When set, no ack policy is expected */ - unsigned ack_policy:1; - - /* - * Packet type: - * 0 -> 802.11 - * 1 -> 802.3 - * 2 -> IP - * 3 -> raw codec - */ - unsigned packet_type:2; - - /* If set, this is a QoS-Null or QoS-Data frame */ - unsigned qos:1; - - /* - * If set, the target triggers the tx complete INT - * upon frame sending completion. - */ - unsigned tx_complete:1; - - /* 2 bytes padding before packet header */ - unsigned xfer_pad:1; - - unsigned reserved:7; -} __packed; - - -struct tx_double_buffer_desc { - /* Length of payload, including headers. */ - __le16 length; - - /* - * A bit mask that specifies the initial rate to be used - * Possible values are: - * 0x0001 - 1Mbits - * 0x0002 - 2Mbits - * 0x0004 - 5.5Mbits - * 0x0008 - 6Mbits - * 0x0010 - 9Mbits - * 0x0020 - 11Mbits - * 0x0040 - 12Mbits - * 0x0080 - 18Mbits - * 0x0100 - 22Mbits - * 0x0200 - 24Mbits - * 0x0400 - 36Mbits - * 0x0800 - 48Mbits - * 0x1000 - 54Mbits - */ - __le16 rate; - - /* Time in us that a packet can spend in the target */ - __le32 expiry_time; - - /* index of the TX queue used for this packet */ - u8 xmit_queue; - - /* Used to identify a packet */ - u8 id; - - struct tx_control control; - - /* - * The FW should cut the packet into fragments - * of this size. - */ - __le16 frag_threshold; - - /* Numbers of HW queue blocks to be allocated */ - u8 num_mem_blocks; - - u8 reserved; -} __packed; - -enum { - TX_SUCCESS = 0, - TX_DMA_ERROR = BIT(7), - TX_DISABLED = BIT(6), - TX_RETRY_EXCEEDED = BIT(5), - TX_TIMEOUT = BIT(4), - TX_KEY_NOT_FOUND = BIT(3), - TX_ENCRYPT_FAIL = BIT(2), - TX_UNAVAILABLE_PRIORITY = BIT(1), -}; - -struct tx_result { - /* - * Ownership synchronization between the host and - * the firmware. If done_1 and done_2 are cleared, - * owned by the FW (no info ready). - */ - u8 done_1; - - /* same as double_buffer_desc->id */ - u8 id; - - /* - * Total air access duration consumed by this - * packet, including all retries and overheads. - */ - u16 medium_usage; - - /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */ - u32 medium_delay; - - /* Time between host xfer and tx complete */ - u32 fw_hnadling_time; - - /* The LS-byte of the last TKIP sequence number. */ - u8 lsb_seq_num; - - /* Retry count */ - u8 ack_failures; - - /* At which rate we got a ACK */ - u16 rate; - - u16 reserved; - - /* TX_* */ - u8 status; - - /* See done_1 */ - u8 done_2; -} __packed; - -static inline int wl1251_tx_get_queue(int queue) -{ - switch (queue) { - case 0: - return QOS_AC_VO; - case 1: - return QOS_AC_VI; - case 2: - return QOS_AC_BE; - case 3: - return QOS_AC_BK; - default: - return QOS_AC_BE; - } -} - -void wl1251_tx_work(struct work_struct *work); -void wl1251_tx_complete(struct wl1251 *wl); -void wl1251_tx_flush(struct wl1251 *wl); - -#endif -- cgit v1.2.3 From cc2858c987f41286e059ee777c3bc09f7b7c19f6 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 10 Oct 2010 11:28:33 +0300 Subject: wl1251: update the new location to the maintainers file wl1251 is grown up now and can have its own room^H^H^H^Hdirectory. Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 529bfee8c4b2..339606e0a781 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6314,8 +6314,7 @@ L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained -F: drivers/net/wireless/wl12xx/* -X: drivers/net/wireless/wl12xx/wl1271* +F: drivers/net/wireless/wl1251/* WL1271 WIRELESS DRIVER M: Luciano Coelho -- cgit v1.2.3 From 730bd83b036e72b0134352ca27e76ea08475fbf1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 10 Oct 2010 18:52:10 +0200 Subject: mac80211: don't kmalloc 16 bytes Since this small buffer isn't used for DMA, we can simply allocate it on the stack, it just needs to be 16 bytes of which only 8 will be used for WEP40 keys. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/wep.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index f27484c22b9f..2ff6d1e3ed21 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, struct ieee80211_key *key) { u32 klen; - u8 *rc4key; + u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; u8 keyidx; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; unsigned int hdrlen; @@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, klen = 3 + key->conf.keylen; - rc4key = kmalloc(klen, GFP_ATOMIC); - if (!rc4key) - return -1; - /* Prepend 24-bit IV to RC4 key */ memcpy(rc4key, skb->data + hdrlen, 3); @@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, len)) ret = -1; - kfree(rc4key); - /* Trim ICV */ skb_trim(skb, skb->len - WEP_ICV_LEN); -- cgit v1.2.3 From 15d46f38df87f89242e470f5797120fa384c1fc3 Mon Sep 17 00:00:00 2001 From: Björn Smedman Date: Sun, 10 Oct 2010 22:14:25 +0200 Subject: mac80211: minstrel_ht A-MPDU fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes two problems with the minstrel_ht rate control algorithms handling of A-MPDU frames: 1. The ampdu_len field of the tx status is not always initialized for non-HT frames (and it would probably be unreasonable to require all drivers to do so). This could cause rate control statistics to be corrupted. We now trust the ampdu_len and ampdu_ack_len fields only when the frame is marked with the IEEE80211_TX_STAT_AMPDU flag. 2. Successful transmission attempts where only recognized when the A-MPDU subframe carrying the rate control status information was marked with the IEEE80211_TX_STAT_ACK flag. If this information happed to be carried on a frame that failed to be ACKed then the other subframes (which may have succeeded) where not correctly registered. We now update rate control statistics regardless of whether the subframe carrying the information was ACKed or not. Cc: Signed-off-by: Björn Smedman Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index c5b465904e3b..2a18d6602d4a 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, !(info->flags & IEEE80211_TX_STAT_AMPDU)) return; - if (!info->status.ampdu_len) { - info->status.ampdu_ack_len = 1; + if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { + info->status.ampdu_ack_len = + (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); info->status.ampdu_len = 1; } @@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, group = minstrel_ht_get_group_idx(&ar[i]); rate = &mi->groups[group].rates[ar[i].idx % 8]; - if (last && (info->flags & IEEE80211_TX_STAT_ACK)) + if (last) rate->success += info->status.ampdu_ack_len; rate->attempts += ar[i].count * info->status.ampdu_len; -- cgit v1.2.3 From ebd022873aa61937603d2c4dfea19ce63ea1a3c8 Mon Sep 17 00:00:00 2001 From: Björn Smedman Date: Sun, 10 Oct 2010 22:44:39 +0200 Subject: ath9k: A-MPDU rate control info fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the following problems with the rate control feedback generated by ath9k for A-MPDU frames: 1. Rate control feedback is carried on the first frame of an aggregate that is either ACKed, or has execeeded the software retry count and is considered failed. However, ath9k would incorrectly assume the aggregate had the length 1 if one of these conditions did not apply to the first frame of the aggregate, but instead a later frame. This fix therefor copies the bf_nframes field of the buffer in the same manner as the rates field of the tx status. 2. Sometimes the ampdu_len and ampdu_ack_len fields of the tx status was left uninitialized eventhough the IEEE80211_TX_STAT_AMPDU flag was set. This is now avoid by setting flag and fields in the same place. 3. Even if a frame has been selected for aggregation by mac80211 and marked with the IEEE80211_TX_CTL_AMPDU flag it can sometimes happen that ath9k transmits the frame without aggregation. In these cases the ampdu_ack_len field could be incorrectly computed because the nbad parameter to ath_tx_rc_status was incorrect. Cc: Signed-off-by: Björn Smedman Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index aa447770eb2b..9a11099dd86a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -317,6 +317,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; struct ieee80211_tx_rate rates[4]; + int nframes; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -325,6 +326,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, hw = bf->aphy->hw; memcpy(rates, tx_info->control.rates, sizeof(rates)); + nframes = bf->bf_nframes; rcu_read_lock(); @@ -341,7 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - ath_tx_rc_status(bf, ts, 0, 0, false); + ath_tx_rc_status(bf, ts, 1, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -446,6 +448,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { memcpy(tx_info->control.rates, rates, sizeof(rates)); + bf->bf_nframes = nframes; ath_tx_rc_status(bf, ts, nbad, txok, true); rc_update = false; } else { @@ -1979,9 +1982,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if (ts->ts_status & ATH9K_TXERR_FILT) tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + BUG_ON(nbad > bf->bf_nframes); + + tx_info->status.ampdu_len = bf->bf_nframes; + tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; + } + if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { if (ieee80211_is_data(hdr->frame_control)) { @@ -1991,8 +2000,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if ((ts->ts_status & ATH9K_TXERR_XRETRY) || (ts->ts_status & ATH9K_TXERR_FIFO)) tx_info->pad[0] |= ATH_TX_INFO_XRETRY; - tx_info->status.ampdu_len = bf->bf_nframes; - tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; } } @@ -2102,7 +2109,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) */ if (ts.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &ts, 0, txok, true); + ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) @@ -2220,7 +2227,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) if (!bf_isampdu(bf)) { if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &txs, 0, txok, true); + ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) -- cgit v1.2.3 From a8909cfb1832ac623142898df2a9374722cfe68f Mon Sep 17 00:00:00 2001 From: Björn Smedman Date: Sun, 10 Oct 2010 22:51:54 +0200 Subject: ath9k: built-in rate control A-MPDU fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch attempts to ensure that ath9k's built-in rate control algorithm does not rely on the value of the ampdu_len and ampdu_ack_len tx status fields unless the IEEE80211_TX_STAT_AMPDU flag is set. This patch has not been tested. Cc: Signed-off-by: Björn Smedman Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ce1cd6d85847..13f9e88e1187 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1375,6 +1375,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) return; + if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) { + tx_info->status.ampdu_ack_len = + (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); + tx_info->status.ampdu_len = 1; + } + /* * If an underrun error is seen assume it as an excessive retry only * if max frame trigger level has been reached (2 KB for singel stream, -- cgit v1.2.3 From a656b6a9665dce09a8f273091f1b4aa3d5cec721 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Mon, 11 Oct 2010 03:11:01 +0200 Subject: b43: N-PHY: grab more info about new channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 61 +++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 52ce4383a056..6ca41a09fec4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3323,9 +3323,9 @@ int b43_phy_initn(struct b43_wldev *dev) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ -static void b43_nphy_chanspec_setup(struct b43_wldev *dev, +static void b43_nphy_channel_setup(struct b43_wldev *dev, const struct b43_phy_n_sfo_cfg *e, - struct b43_chanspec chanspec) + struct ieee80211_channel *new_channel) { struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = dev->phy.n; @@ -3334,13 +3334,13 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, u32 tmp32; tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; - if (chanspec.b_freq == 1 && tmp == 0) { + if (new_channel->band == IEEE80211_BAND_5GHZ && tmp == 0) { tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); - } else if (chanspec.b_freq == 1) { + } else if (new_channel->band == IEEE80211_BAND_5GHZ) { b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); @@ -3350,13 +3350,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, b43_chantab_phy_upload(dev, e); - - if (nphy->radio_chanspec.channel == 14) { + if (new_channel->hw_value == 14) { b43_nphy_classifier(dev, 2, 0); b43_phy_set(dev, B43_PHY_B_TEST, 0x0800); } else { b43_nphy_classifier(dev, 2, 2); - if (chanspec.b_freq == 2) + if (new_channel->band == IEEE80211_BAND_2GHZ) b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); } @@ -3379,16 +3378,17 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ -static int b43_nphy_set_chanspec(struct b43_wldev *dev, - struct b43_chanspec chanspec) +static int b43_nphy_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) { + struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = dev->phy.n; const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; u8 tmp; - u8 channel = chanspec.channel; if (dev->phy.rev >= 3) { /* TODO */ @@ -3396,36 +3396,36 @@ static int b43_nphy_set_chanspec(struct b43_wldev *dev, if (!tabent_r3) return -ESRCH; } else { - tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel); + tabent_r2 = b43_nphy_get_chantabent_rev2(dev, + channel->hw_value); if (!tabent_r2) return -ESRCH; } - nphy->radio_chanspec = chanspec; + nphy->radio_chanspec.channel = channel->hw_value; + /* if (chanspec.b_width != nphy->b_width) - ; /* TODO: BMAC BW Set (chanspec.b_width) */ + ; TODO: BMAC BW Set (chanspec.b_width) + */ - /* TODO: use defines */ - if (chanspec.b_width == 3) { - if (chanspec.sideband == 2) - b43_phy_set(dev, B43_NPHY_RXCTL, - B43_NPHY_RXCTL_BSELU20); - else - b43_phy_mask(dev, B43_NPHY_RXCTL, - ~B43_NPHY_RXCTL_BSELU20); - } + if (channel_type == NL80211_CHAN_HT40PLUS) + b43_phy_set(dev, B43_NPHY_RXCTL, + B43_NPHY_RXCTL_BSELU20); + else if (channel_type == NL80211_CHAN_HT40MINUS) + b43_phy_mask(dev, B43_NPHY_RXCTL, + ~B43_NPHY_RXCTL_BSELU20); if (dev->phy.rev >= 3) { - tmp = (chanspec.b_freq == 1) ? 4 : 0; + tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0; b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */ - b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec); + b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel); } else { - tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050; + tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050; b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp); b43_radio_2055_setup(dev, tabent_r2); - b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec); + b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel); } return 0; @@ -3567,8 +3567,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) static int b43_nphy_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { - struct b43_phy_n *nphy = dev->phy.n; - struct b43_chanspec chanspec; + struct ieee80211_channel *channel = dev->wl->hw->conf.channel; + enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { if ((new_channel < 1) || (new_channel > 14)) @@ -3578,10 +3578,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev, return -EINVAL; } - chanspec = nphy->radio_chanspec; - chanspec.channel = new_channel; - - return b43_nphy_set_chanspec(dev, chanspec); + return b43_nphy_set_channel(dev, channel, channel_type); } static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) -- cgit v1.2.3 From e5c407f970ea2977600eb54cf4cc8a67a44fefeb Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Mon, 11 Oct 2010 03:11:02 +0200 Subject: b43: N-PHY: store info about current channel's type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.h | 4 +++- drivers/net/wireless/b43/phy_n.c | 14 ++++++++++---- drivers/net/wireless/b43/phy_n.h | 1 - 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index bd480b481bfc..6dcd0334ed02 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -2,6 +2,7 @@ #define LINUX_B43_PHY_COMMON_H_ #include +#include struct b43_wldev; @@ -250,8 +251,9 @@ struct b43_phy { * check is needed. */ unsigned long next_txpwr_check_time; - /* current channel */ + /* Current channel */ unsigned int channel; + enum nl80211_channel_type channel_type; /* PHY TX errors counter. */ atomic_t txerr_cnt; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 6ca41a09fec4..789d21c54139 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -74,6 +74,13 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); +static inline bool b43_channel_type_is_40mhz( + enum nl80211_channel_type channel_type) +{ + return (channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS); +} + static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) { return !chanspec->channel && !chanspec->sideband && @@ -3404,10 +3411,9 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, nphy->radio_chanspec.channel = channel->hw_value; - /* - if (chanspec.b_width != nphy->b_width) - ; TODO: BMAC BW Set (chanspec.b_width) - */ + if (b43_channel_type_is_40mhz(phy->channel_type) != + b43_channel_type_is_40mhz(channel_type)) + ; /* TODO: BMAC BW Set (channel_type) */ if (channel_type == NL80211_CHAN_HT40PLUS) b43_phy_set(dev, B43_NPHY_RXCTL, diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 8b6d570dd0aa..e7acae278be0 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -984,7 +984,6 @@ struct b43_phy_n { u16 papd_epsilon_offset[2]; s32 preamble_override; u32 bb_mult_save; - u8 b_width; struct b43_chanspec radio_chanspec; bool gain_boost; -- cgit v1.2.3 From 087de74ae512fe31894c1556d5f8d5a126322de7 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Mon, 11 Oct 2010 03:11:03 +0200 Subject: b43: N-PHY: fix logic in band switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 789d21c54139..19582ba20598 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3337,17 +3337,18 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev, struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = dev->phy.n; - u16 tmp; + u16 old_band_5ghz; u32 tmp32; - tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; - if (new_channel->band == IEEE80211_BAND_5GHZ && tmp == 0) { + old_band_5ghz = + b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; + if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); - } else if (new_channel->band == IEEE80211_BAND_5GHZ) { + } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); -- cgit v1.2.3 From f2a6d6a08cf13f621661dd57f32bf0a5100ba26b Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Mon, 11 Oct 2010 03:19:22 +0200 Subject: b43: N-PHY: prepare for rev3+ channel tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 3 ++- drivers/net/wireless/b43/tables_nphy.c | 24 +++++++++++++++++++++--- drivers/net/wireless/b43/tables_nphy.h | 4 +++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 19582ba20598..e532901246b6 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3399,7 +3399,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, u8 tmp; if (dev->phy.rev >= 3) { - /* TODO */ + tabent_r3 = b43_nphy_get_chantabent_rev3(dev, + channel->center_freq); tabent_r3 = NULL; if (!tabent_r3) return -ESRCH; diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index d96e870ab8fe..e74b8eb5795c 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -325,7 +325,7 @@ void b2055_upload_inittab(struct b43_wldev *dev, .phy_regs.phy_bw5 = r4, \ .phy_regs.phy_bw6 = r5 -static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = { +static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { { .channel = 184, .freq = 4920, /* MHz */ .unk2 = 3280, @@ -1326,8 +1326,8 @@ b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) const struct b43_nphy_channeltab_entry_rev2 *e; unsigned int i; - for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) { - e = &(b43_nphy_channeltab[i]); + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) { + e = &(b43_nphy_channeltab_rev2[i]); if (e->channel == channel) return e; } @@ -1335,6 +1335,24 @@ b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) return NULL; } +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { +}; + +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) +{ + const struct b43_nphy_channeltab_entry_rev3 *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) { + e = &(b43_nphy_channeltab_rev3[i]); + if (e->freq == freq) + return e; + } + + return NULL; +} + static const u8 b43_ntab_adjustpower0[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 8fc1da9f8fe5..3eedb869f492 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -90,10 +90,12 @@ void b2055_upload_inittab(struct b43_wldev *dev, bool ghz5, bool ignore_uploadflag); -/* Get the NPHY Channel Switch Table entry for a channel number. +/* Get the NPHY Channel Switch Table entry for a channel. * Returns NULL on failure to find an entry. */ const struct b43_nphy_channeltab_entry_rev2 * b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); /* The N-PHY tables. */ -- cgit v1.2.3 From a9325199edb093a5c7311a25d15da20ee984e80b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 11 Oct 2010 11:27:32 +0200 Subject: WIRELESS: at76c50x, remove unneeded NULL check Stanse found that urb cannot be NULL in at76_rx_tasklet because it is dereferenced earlier, so remove the unneeded check. Signed-off-by: Jiri Slaby Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 91c5f73b5ba3..1476314afa8a 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param) if (priv->device_unplugged) { at76_dbg(DBG_DEVSTART, "device unplugged"); - if (urb) - at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); + at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); return; } -- cgit v1.2.3 From fa69560f317d961c56e29dea788b346d2b34fb87 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:37:25 +0200 Subject: rt2x00: Simplify Queue function arguments A lot of functions accept a struct rt2x00_dev combined with either a struct queue_entry or struct data_queue argument. This can be simplified by only passing on the queue/entry argument. In cases where rt2x00_dev and a sk_buff are send together, we can send the queue_entry instead. rt2x00usb_alloc_urb and rt2x00usb_free_urb have a bit of vague naming. Instead they allocate all the data which belongs to a rt2x00 data queue entry. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 13 ++++---- drivers/net/wireless/rt2x00/rt2x00dev.c | 10 +++---- drivers/net/wireless/rt2x00/rt2x00lib.h | 11 +++---- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 49 +++++++++++++++---------------- drivers/net/wireless/rt2x00/rt2x00usb.c | 18 ++++++------ 8 files changed, 50 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4b88909275a1..095cb6982d7a 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1104,7 +1104,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); /* * Write the TX descriptor for the beacon. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 46ef692e404d..7d85bf9bd253 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1258,7 +1258,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); /* * Write the TX descriptor for the beacon. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 75ac6624bf9e..2322c84adc1c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1036,17 +1036,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) /** * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to map. + * @entry: Pointer to &struct queue_entry */ -void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_map_txskb(struct queue_entry *entry); /** * rt2x00queue_unmap_skb - Unmap a skb from DMA. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to unmap. + * @entry: Pointer to &struct queue_entry */ -void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_unmap_skb(struct queue_entry *entry); /** * rt2x00queue_get_queue - Convert queue index to queue pointer @@ -1093,8 +1091,7 @@ void rt2x00lib_dmadone(struct queue_entry *entry); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); -void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); +void rt2x00lib_rxdone(struct queue_entry *entry); /* * mac80211 handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 6f442b02b83e..9b745faef0ed 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -273,7 +273,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * Unmap the skb. */ - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + rt2x00queue_unmap_skb(entry); /* * Remove the extra tx headroom from the skb. @@ -465,9 +465,9 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, return 0; } -void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry) +void rt2x00lib_rxdone(struct queue_entry *entry) { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rxdone_entry_desc rxdesc; struct sk_buff *skb; struct ieee80211_rx_status *rx_status; @@ -481,14 +481,14 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, * Allocate a new sk_buffer. If no new buffer available, drop the * received frame and reuse the existing buffer. */ - skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); + skb = rt2x00queue_alloc_rxskb(entry); if (!skb) return; /* * Unmap the skb. */ - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + rt2x00queue_unmap_skb(entry); /* * Extract the RXD details. diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 70c85ac2e53e..619da23b7b56 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -100,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, /** * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @queue: The queue for which the skb will be applicable. + * @entry: The entry for which the skb will be applicable. */ -struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); +struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry); /** * rt2x00queue_free_skb - free a skb - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to free. + * @entry: The entry for which the skb will be applicable. */ -void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_free_skb(struct queue_entry *entry); /** * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 63c2cc408e15..2449d785cf8d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) /* * Send the frame to rt2x00lib for further processing. */ - rt2x00lib_rxdone(rt2x00dev, entry); + rt2x00lib_rxdone(entry); } } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 83630f16dc64..7e30144c5cfa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -33,9 +33,9 @@ #include "rt2x00.h" #include "rt2x00lib.h" -struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry) +struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct sk_buff *skb; struct skb_frame_desc *skbdesc; unsigned int frame_size; @@ -97,39 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, return skb; } -void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_map_txskb(struct queue_entry *entry) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct device *dev = entry->queue->rt2x00dev->dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); skbdesc->skb_dma = - dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); + dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE); skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; } EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); -void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_unmap_skb(struct queue_entry *entry) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct device *dev = entry->queue->rt2x00dev->dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len, DMA_FROM_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len, DMA_TO_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; } } EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); -void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_free_skb(struct queue_entry *entry) { - if (!skb) + if (!entry->skb) return; - rt2x00queue_unmap_skb(rt2x00dev, skb); - dev_kfree_skb_any(skb); + rt2x00queue_unmap_skb(entry); + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; } void rt2x00queue_align_frame(struct sk_buff *skb) @@ -438,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, * Map the skb to DMA. */ if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); return 0; } @@ -585,8 +588,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, /* * Clean up the beacon skb. */ - rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); - intf->beacon->skb = NULL; + rt2x00queue_free_skb(intf->beacon); if (!enable_beacon) { rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); @@ -827,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return 0; } -static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static void rt2x00queue_free_skbs(struct data_queue *queue) { unsigned int i; @@ -836,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, return; for (i = 0; i < queue->limit; i++) { - if (queue->entries[i].skb) - rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); + rt2x00queue_free_skb(&queue->entries[i]); } } -static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static int rt2x00queue_alloc_rxskbs(struct data_queue *queue) { unsigned int i; struct sk_buff *skb; for (i = 0; i < queue->limit; i++) { - skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); + skb = rt2x00queue_alloc_rxskb(&queue->entries[i]); if (!skb) return -ENOMEM; queue->entries[i].skb = skb; @@ -883,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) goto exit; } - status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); + status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx); if (status) goto exit; @@ -901,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); + rt2x00queue_free_skbs(rt2x00dev->rx); queue_for_each(rt2x00dev, queue) { kfree(queue->entries); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 4c5ae3d45625..451d637377a2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -398,7 +398,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work) /* * Send the frame to rt2x00lib for further processing. */ - rt2x00lib_rxdone(rt2x00dev, entry); + rt2x00lib_rxdone(entry); } } @@ -542,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static int rt2x00usb_alloc_entries(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; unsigned int i; @@ -561,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, * no guardian byte was required for the beacon, * then we are done. */ - if (rt2x00dev->bcn != queue || + if (queue->qid != QID_BEACON || !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) return 0; @@ -575,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, return 0; } -static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static void rt2x00usb_free_entries(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; unsigned int i; @@ -596,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, * no guardian byte was required for the beacon, * then we are done. */ - if (rt2x00dev->bcn != queue || + if (queue->qid != QID_BEACON || !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) return; @@ -623,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) * Allocate DMA */ queue_for_each(rt2x00dev, queue) { - status = rt2x00usb_alloc_urb(rt2x00dev, queue); + status = rt2x00usb_alloc_entries(queue); if (status) goto exit; } @@ -642,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; queue_for_each(rt2x00dev, queue) - rt2x00usb_free_urb(rt2x00dev, queue); + rt2x00usb_free_entries(queue); } EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); -- cgit v1.2.3 From cdfd2c5cffac2e744c855f9998212867387bb2de Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:37:47 +0200 Subject: rt2x00: Move watchdog work to kernel work_queue The watchdog function must run on a work_queue which is independent of any other work inside rt2x00. The main reasons, being that a broken work on the mac80211 work_queue can otherwise prevent the watchdog to run (while in fact the watchdog could fix the issue). And on the other hand because the watchdog relies on the completion of the completion handlers for RX/TX which for the USB case, occur on the mac80211 workqueue. This fixes some "Queue %d failed to flush" errors, which were caused by the watchdog function waiting on the completion handler which was scheduled to run right after the watchdog. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 5 +++++ drivers/net/wireless/rt2x00/rt2x00link.c | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2322c84adc1c..94fe589acfaa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -338,6 +338,11 @@ struct link { /* * Work structure for scheduling periodic watchdog monitoring. + * This work must be scheduled on the kernel workqueue, while + * all other work structures must be queued on the mac80211 + * workqueue. This guarantees that the watchdog can schedule + * other work structures and wait for their completion in order + * to bring the device/driver back into the desired state. */ struct delayed_work watchdog_work; }; diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 46836f801b35..b971d8798ebf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -417,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) return; - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->watchdog_work, WATCHDOG_INTERVAL); + schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); } void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) @@ -442,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work) rt2x00dev->ops->lib->watchdog(rt2x00dev); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->watchdog_work, WATCHDOG_INTERVAL); + schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); } void rt2x00link_register(struct rt2x00_dev *rt2x00dev) -- cgit v1.2.3 From 3590eea41815679e268c90d30795a13a732b8413 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:38:07 +0200 Subject: rt2x00: Validate MCS on RX path Similar to the PLCP signal and bitrates values, we should validate the MCS value from the RX descriptor before sending it to mac80211. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 72 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9b745faef0ed..db25209688fb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -432,36 +432,44 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, struct ieee80211_supported_band *sband; const struct rt2x00_rate *rate; unsigned int i; - int signal; - int type; + int signal = rxdesc->signal; + int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); - /* - * For non-HT rates the MCS value needs to contain the - * actually used rate modulation (CCK or OFDM). - */ - if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) - signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal); - else - signal = rxdesc->signal; - - type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); - - sband = &rt2x00dev->bands[rt2x00dev->curr_band]; - for (i = 0; i < sband->n_bitrates; i++) { - rate = rt2x00_get_rate(sband->bitrates[i].hw_value); - - if (((type == RXDONE_SIGNAL_PLCP) && - (rate->plcp == signal)) || - ((type == RXDONE_SIGNAL_BITRATE) && - (rate->bitrate == signal)) || - ((type == RXDONE_SIGNAL_MCS) && - (rate->mcs == signal))) { - return i; + switch (rxdesc->rate_mode) { + case RATE_MODE_CCK: + case RATE_MODE_OFDM: + /* + * For non-HT rates the MCS value needs to contain the + * actually used rate modulation (CCK or OFDM). + */ + if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) + signal = RATE_MCS(rxdesc->rate_mode, signal); + + sband = &rt2x00dev->bands[rt2x00dev->curr_band]; + for (i = 0; i < sband->n_bitrates; i++) { + rate = rt2x00_get_rate(sband->bitrates[i].hw_value); + if (((type == RXDONE_SIGNAL_PLCP) && + (rate->plcp == signal)) || + ((type == RXDONE_SIGNAL_BITRATE) && + (rate->bitrate == signal)) || + ((type == RXDONE_SIGNAL_MCS) && + (rate->mcs == signal))) { + return i; + } } + break; + case RATE_MODE_HT_MIX: + case RATE_MODE_HT_GREENFIELD: + if (signal >= 0 && signal <= 76) + return signal; + break; + default: + break; } WARNING(rt2x00dev, "Frame received with unrecognized signal, " - "signal=0x%.4x, type=%d.\n", signal, type); + "mode=0x%.4x, signal=0x%.4x, type=%d.\n", + rxdesc->rate_mode, signal, type); return 0; } @@ -523,18 +531,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry) skb_trim(entry->skb, rxdesc.size); /* - * Check if the frame was received using HT. In that case, - * the rate is the MCS index and should be passed to mac80211 - * directly. Otherwise we need to translate the signal to - * the correct bitrate index. + * Translate the signal to the correct bitrate index. */ - if (rxdesc.rate_mode == RATE_MODE_CCK || - rxdesc.rate_mode == RATE_MODE_OFDM) { - rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); - } else { + rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); + if (rxdesc.rate_mode == RATE_MODE_HT_MIX || + rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD) rxdesc.flags |= RX_FLAG_HT; - rate_idx = rxdesc.signal; - } /* * Update extra components -- cgit v1.2.3 From 1550c8ef835af17df322045e92541561afa0f017 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:38:26 +0200 Subject: rt2x00: Fix dead queue when skb allocation failed When the RX skb allocation failed, we should recycle the previously allocated skbuffer. By calling return we would kill the RX queue completely since the entry would be invalidated. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index db25209688fb..e5e8ba3bf228 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -491,7 +491,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry) */ skb = rt2x00queue_alloc_rxskb(entry); if (!skb) - return; + goto submit_entry; /* * Unmap the skb. -- cgit v1.2.3 From a1d1eabc8c42ddf5fd3ea4184094561b3edd127b Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:38:45 +0200 Subject: rt2x00: Make queue_entry flags access atomic All access to the queue_entry->flags can be done concurrently, so all flags must use the atomic operators. On most locations this was already done, so just fix the last few non-atomic versions. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 451d637377a2..769c53451b21 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -208,7 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -220,7 +220,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Check if the frame was correctly uploaded */ if (urb->status) - __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); /* * Schedule the delayed work for reading the TX status @@ -407,7 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -421,7 +421,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * a problem. */ if (urb->actual_length < entry->queue->desc_size || urb->status) - __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); /* * Schedule the delayed work for reading the RX status -- cgit v1.2.3 From 1a397696536e896e7d763c0c38f3ae3e588b5d52 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:39:04 +0200 Subject: rt2x00: Don't perform watchdog checks on empty queue The currently used watchdog functions cannot be applied to empty queues. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 769c53451b21..89d77f55d76c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -363,10 +363,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; tx_queue_for_each(rt2x00dev, queue) { - if (rt2x00queue_dma_timeout(queue)) - rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00queue_timeout(queue)) - rt2x00usb_watchdog_tx_status(queue); + if (!rt2x00queue_empty(queue)) { + if (rt2x00queue_dma_timeout(queue)) + rt2x00usb_watchdog_tx_dma(queue); + if (rt2x00queue_timeout(queue)) + rt2x00usb_watchdog_tx_status(queue); + } } } EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); -- cgit v1.2.3 From a13c8f3133b250e732c383b1c390d625e755db03 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 11 Oct 2010 15:39:48 +0200 Subject: rt2x00: Fix URB error handling kill_urb guarentees that when the function returns, the URB has been fully killed. This means we don't need the extra sleeping after the call to kill_urb. kill_urb can however also guarentee the submit_urb to fail, as a result, we must catch the return value from submit_urb an correctly mark the entry as owned by the driver, and the status as broken. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 1 + drivers/net/wireless/rt2x00/rt2x00usb.c | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e5e8ba3bf228..5ba79b935f09 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); void rt2x00lib_dmadone(struct queue_entry *entry) { + clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); } EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 89d77f55d76c..b3317df7a7d4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) entry->skb->data, length, rt2x00usb_interrupt_txdone, entry); - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + } } void rt2x00usb_kick_tx_queue(struct data_queue *queue) @@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) if ((entry->queue->qid == QID_BEACON) && (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) usb_kill_urb(bcn_priv->guardian_urb); - - /* - * We need a short delay here to wait for - * the URB to be canceled - */ - do { - udelay(100); - } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)); } void rt2x00usb_kill_tx_queue(struct data_queue *queue) @@ -469,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) rt2x00usb_interrupt_rxdone, entry); set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + } } } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); -- cgit v1.2.3 From 0ed8ddf4045fcfcac36bad753dc4046118c603ec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 7 Oct 2010 10:44:07 +0000 Subject: neigh: Protect neigh->ha[] with a seqlock Add a seqlock in struct neighbour to protect neigh->ha[], and avoid dirtying neighbour in stress situation (many different flows / dsts) Dirtying takes place because of read_lock(&n->lock) and n->used writes. Switching to a seqlock, and writing n->used only on jiffies changes permits less dirtying. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 16 +++++++++++++++- net/core/neighbour.c | 47 ++++++++++++++++++++++++++++++----------------- net/ipv4/arp.c | 6 ++---- net/sched/sch_teql.c | 8 ++++---- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index a4538d553704..f04e7a2522c5 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -105,6 +105,7 @@ struct neighbour { atomic_t refcnt; atomic_t probes; rwlock_t lock; + seqlock_t ha_lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; int (*output)(struct sk_buff *skb); @@ -302,7 +303,10 @@ static inline void neigh_confirm(struct neighbour *neigh) static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) { - neigh->used = jiffies; + unsigned long now = ACCESS_ONCE(jiffies); + + if (neigh->used != now) + neigh->used = now; if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) return __neigh_event_send(neigh, skb); return 0; @@ -373,4 +377,14 @@ struct neighbour_cb { #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) +static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n, + const struct net_device *dev) +{ + unsigned int seq; + + do { + seq = read_seqbegin(&n->ha_lock); + memcpy(dst, n->ha, dev->addr_len); + } while (read_seqretry(&n->ha_lock, seq)); +} #endif diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2044906ecd1a..b165b96355bf 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -294,6 +294,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) skb_queue_head_init(&n->arp_queue); rwlock_init(&n->lock); + seqlock_init(&n->ha_lock); n->updated = n->used = now; n->nud_state = NUD_NONE; n->output = neigh_blackhole; @@ -1015,7 +1016,7 @@ out_unlock_bh: } EXPORT_SYMBOL(__neigh_event_send); -static void neigh_update_hhs(struct neighbour *neigh) +static void neigh_update_hhs(const struct neighbour *neigh) { struct hh_cache *hh; void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) @@ -1151,7 +1152,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, } if (lladdr != neigh->ha) { + write_seqlock(&neigh->ha_lock); memcpy(&neigh->ha, lladdr, dev->addr_len); + write_sequnlock(&neigh->ha_lock); neigh_update_hhs(neigh); if (!(new & NUD_CONNECTED)) neigh->confirmed = jiffies - @@ -1214,6 +1217,7 @@ static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, { struct hh_cache *hh; + smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ for (hh = n->hh; hh; hh = hh->hh_next) { if (hh->hh_type == protocol) { atomic_inc(&hh->hh_refcnt); @@ -1248,8 +1252,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, kfree(hh); return; } - read_unlock(&n->lock); - write_lock(&n->lock); + + write_lock_bh(&n->lock); /* must check if another thread already did the insert */ if (neigh_hh_lookup(n, dst, protocol)) { @@ -1263,13 +1267,13 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, hh->hh_output = n->ops->output; hh->hh_next = n->hh; + smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ n->hh = hh; if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) hh_cache_put(hh); end: - write_unlock(&n->lock); - read_lock(&n->lock); + write_unlock_bh(&n->lock); } /* This function can be used in contexts, where only old dev_queue_xmit @@ -1308,16 +1312,18 @@ int neigh_resolve_output(struct sk_buff *skb) if (!neigh_event_send(neigh, skb)) { int err; struct net_device *dev = neigh->dev; + unsigned int seq; - read_lock_bh(&neigh->lock); if (dev->header_ops->cache && !dst->hh && !(dst->flags & DST_NOCACHE)) neigh_hh_init(neigh, dst, dst->ops->protocol); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - read_unlock_bh(&neigh->lock); + do { + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); + } while (read_seqretry(&neigh->ha_lock, seq)); if (err >= 0) rc = neigh->ops->queue_xmit(skb); @@ -1344,13 +1350,16 @@ int neigh_connected_output(struct sk_buff *skb) struct dst_entry *dst = skb_dst(skb); struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; + unsigned int seq; __skb_pull(skb, skb_network_offset(skb)); - read_lock_bh(&neigh->lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - read_unlock_bh(&neigh->lock); + do { + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); + } while (read_seqretry(&neigh->ha_lock, seq)); + if (err >= 0) err = neigh->ops->queue_xmit(skb); else { @@ -2148,10 +2157,14 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, read_lock_bh(&neigh->lock); ndm->ndm_state = neigh->nud_state; - if ((neigh->nud_state & NUD_VALID) && - nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, neigh->ha) < 0) { - read_unlock_bh(&neigh->lock); - goto nla_put_failure; + if (neigh->nud_state & NUD_VALID) { + char haddr[MAX_ADDR_LEN]; + + neigh_ha_snapshot(haddr, neigh, neigh->dev); + if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0) { + read_unlock_bh(&neigh->lock); + goto nla_put_failure; + } } ci.ndm_used = jiffies_to_clock_t(now - neigh->used); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index f35309578170..d8e540c5b071 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -502,10 +502,8 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) if (n) { n->used = jiffies; - if (n->nud_state&NUD_VALID || neigh_event_send(n, skb) == 0) { - read_lock_bh(&n->lock); - memcpy(haddr, n->ha, dev->addr_len); - read_unlock_bh(&n->lock); + if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) { + neigh_ha_snapshot(haddr, n, dev); neigh_release(n); return 0; } diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index feaabc103ce6..401af9596709 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -241,11 +241,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * } if (neigh_event_send(n, skb_res) == 0) { int err; + char haddr[MAX_ADDR_LEN]; - read_lock(&n->lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - n->ha, NULL, skb->len); - read_unlock(&n->lock); + neigh_ha_snapshot(haddr, n, dev); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, + NULL, skb->len); if (err < 0) { neigh_release(n); -- cgit v1.2.3 From fc66f95c68b6d4535a0ea2ea15d5cf626e310956 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 8 Oct 2010 06:37:34 +0000 Subject: net dst: use a percpu_counter to track entries struct dst_ops tracks number of allocated dst in an atomic_t field, subject to high cache line contention in stress workload. Switch to a percpu_counter, to reduce number of time we need to dirty a central location. Place it on a separate cache line to avoid dirtying read only fields. Stress test : (Sending 160.000.000 UDP frames, IP route cache disabled, dual E5540 @2.53GHz, 32bit kernel, FIB_TRIE, SLUB/NUMA) Before: real 0m51.179s user 0m15.329s sys 10m15.942s After: real 0m45.570s user 0m15.525s sys 9m56.669s With a small reordering of struct neighbour fields, subject of a following patch, (to separate refcnt from other read mostly fields) real 0m41.841s user 0m15.261s sys 8m45.949s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/dst_ops.h | 37 ++++++++++++++++++++++++++++++++++++- net/bridge/br_netfilter.c | 11 +++++++++-- net/core/dst.c | 6 +++--- net/decnet/dn_route.c | 3 ++- net/ipv4/route.c | 36 ++++++++++++++++++++++-------------- net/ipv4/xfrm4_policy.c | 4 ++-- net/ipv6/route.c | 28 ++++++++++++++++++++-------- net/ipv6/xfrm6_policy.c | 10 ++++++---- 8 files changed, 100 insertions(+), 35 deletions(-) diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index d1ff9b7e99b8..1fa5306e3e23 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -1,6 +1,7 @@ #ifndef _NET_DST_OPS_H #define _NET_DST_OPS_H #include +#include struct dst_entry; struct kmem_cachep; @@ -22,7 +23,41 @@ struct dst_ops { void (*update_pmtu)(struct dst_entry *dst, u32 mtu); int (*local_out)(struct sk_buff *skb); - atomic_t entries; struct kmem_cache *kmem_cachep; + + struct percpu_counter pcpuc_entries ____cacheline_aligned_in_smp; }; + +static inline int dst_entries_get_fast(struct dst_ops *dst) +{ + return percpu_counter_read_positive(&dst->pcpuc_entries); +} + +static inline int dst_entries_get_slow(struct dst_ops *dst) +{ + int res; + + local_bh_disable(); + res = percpu_counter_sum_positive(&dst->pcpuc_entries); + local_bh_enable(); + return res; +} + +static inline void dst_entries_add(struct dst_ops *dst, int val) +{ + local_bh_disable(); + percpu_counter_add(&dst->pcpuc_entries, val); + local_bh_enable(); +} + +static inline int dst_entries_init(struct dst_ops *dst) +{ + return percpu_counter_init(&dst->pcpuc_entries, 0); +} + +static inline void dst_entries_destroy(struct dst_ops *dst) +{ + percpu_counter_destroy(&dst->pcpuc_entries); +} + #endif diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 77f7b5fda45a..7f9ce9600ef3 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -106,7 +106,6 @@ static struct dst_ops fake_dst_ops = { .family = AF_INET, .protocol = cpu_to_be16(ETH_P_IP), .update_pmtu = fake_update_pmtu, - .entries = ATOMIC_INIT(0), }; /* @@ -1003,15 +1002,22 @@ int __init br_netfilter_init(void) { int ret; - ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + ret = dst_entries_init(&fake_dst_ops); if (ret < 0) return ret; + + ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + if (ret < 0) { + dst_entries_destroy(&fake_dst_ops); + return ret; + } #ifdef CONFIG_SYSCTL brnf_sysctl_header = register_sysctl_paths(brnf_path, brnf_table); if (brnf_sysctl_header == NULL) { printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + dst_entries_destroy(&fake_dst_ops); return -ENOMEM; } #endif @@ -1025,4 +1031,5 @@ void br_netfilter_fini(void) #ifdef CONFIG_SYSCTL unregister_sysctl_table(brnf_sysctl_header); #endif + dst_entries_destroy(&fake_dst_ops); } diff --git a/net/core/dst.c b/net/core/dst.c index 978a1ee1f7d0..32e542d7f472 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -168,7 +168,7 @@ void *dst_alloc(struct dst_ops *ops) { struct dst_entry *dst; - if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { + if (ops->gc && dst_entries_get_fast(ops) > ops->gc_thresh) { if (ops->gc(ops)) return NULL; } @@ -183,7 +183,7 @@ void *dst_alloc(struct dst_ops *ops) #if RT_CACHE_DEBUG >= 2 atomic_inc(&dst_total); #endif - atomic_inc(&ops->entries); + dst_entries_add(ops, 1); return dst; } EXPORT_SYMBOL(dst_alloc); @@ -236,7 +236,7 @@ again: neigh_release(neigh); } - atomic_dec(&dst->ops->entries); + dst_entries_add(dst->ops, -1); if (dst->ops->destroy) dst->ops->destroy(dst); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 6585ea6d1182..df0f3e54ff8a 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -132,7 +132,6 @@ static struct dst_ops dn_dst_ops = { .negative_advice = dn_dst_negative_advice, .link_failure = dn_dst_link_failure, .update_pmtu = dn_dst_update_pmtu, - .entries = ATOMIC_INIT(0), }; static __inline__ unsigned dn_hash(__le16 src, __le16 dst) @@ -1758,6 +1757,7 @@ void __init dn_route_init(void) dn_dst_ops.kmem_cachep = kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + dst_entries_init(&dn_dst_ops); setup_timer(&dn_route_timer, dn_dst_check_expire, 0); dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ; add_timer(&dn_route_timer); @@ -1816,5 +1816,6 @@ void __exit dn_route_cleanup(void) dn_run_flush(0); proc_net_remove(&init_net, "decnet_cache"); + dst_entries_destroy(&dn_dst_ops); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3888f6ba0a5c..0755aa4af86c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -159,7 +159,6 @@ static struct dst_ops ipv4_dst_ops = { .link_failure = ipv4_link_failure, .update_pmtu = ip_rt_update_pmtu, .local_out = __ip_local_out, - .entries = ATOMIC_INIT(0), }; #define ECN_OR_COST(class) TC_PRIO_##class @@ -466,7 +465,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v) seq_printf(seq,"%08x %08x %08x %08x %08x %08x %08x %08x " " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n", - atomic_read(&ipv4_dst_ops.entries), + dst_entries_get_slow(&ipv4_dst_ops), st->in_hit, st->in_slow_tot, st->in_slow_mc, @@ -945,6 +944,7 @@ static int rt_garbage_collect(struct dst_ops *ops) struct rtable *rth, **rthp; unsigned long now = jiffies; int goal; + int entries = dst_entries_get_fast(&ipv4_dst_ops); /* * Garbage collection is pretty expensive, @@ -954,28 +954,28 @@ static int rt_garbage_collect(struct dst_ops *ops) RT_CACHE_STAT_INC(gc_total); if (now - last_gc < ip_rt_gc_min_interval && - atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) { + entries < ip_rt_max_size) { RT_CACHE_STAT_INC(gc_ignored); goto out; } + entries = dst_entries_get_slow(&ipv4_dst_ops); /* Calculate number of entries, which we want to expire now. */ - goal = atomic_read(&ipv4_dst_ops.entries) - - (ip_rt_gc_elasticity << rt_hash_log); + goal = entries - (ip_rt_gc_elasticity << rt_hash_log); if (goal <= 0) { if (equilibrium < ipv4_dst_ops.gc_thresh) equilibrium = ipv4_dst_ops.gc_thresh; - goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium; + goal = entries - equilibrium; if (goal > 0) { equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1); - goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium; + goal = entries - equilibrium; } } else { /* We are in dangerous area. Try to reduce cache really * aggressively. */ goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1); - equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal; + equilibrium = entries - goal; } if (now - last_gc >= ip_rt_gc_min_interval) @@ -1032,14 +1032,16 @@ static int rt_garbage_collect(struct dst_ops *ops) expire >>= 1; #if RT_CACHE_DEBUG >= 2 printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire, - atomic_read(&ipv4_dst_ops.entries), goal, i); + dst_entries_get_fast(&ipv4_dst_ops), goal, i); #endif - if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) + if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) goto out; } while (!in_softirq() && time_before_eq(jiffies, now)); - if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) + if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) + goto out; + if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size) goto out; if (net_ratelimit()) printk(KERN_WARNING "dst cache overflow\n"); @@ -1049,11 +1051,12 @@ static int rt_garbage_collect(struct dst_ops *ops) work_done: expire += ip_rt_gc_min_interval; if (expire > ip_rt_gc_timeout || - atomic_read(&ipv4_dst_ops.entries) < ipv4_dst_ops.gc_thresh) + dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh || + dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh) expire = ip_rt_gc_timeout; #if RT_CACHE_DEBUG >= 2 printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire, - atomic_read(&ipv4_dst_ops.entries), goal, rover); + dst_entries_get_fast(&ipv4_dst_ops), goal, rover); #endif out: return 0; } @@ -2717,7 +2720,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = { .destroy = ipv4_dst_destroy, .check = ipv4_blackhole_dst_check, .update_pmtu = ipv4_rt_blackhole_update_pmtu, - .entries = ATOMIC_INIT(0), }; @@ -3287,6 +3289,12 @@ int __init ip_rt_init(void) ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep; + if (dst_entries_init(&ipv4_dst_ops) < 0) + panic("IP: failed to allocate ipv4_dst_ops counter\n"); + + if (dst_entries_init(&ipv4_dst_blackhole_ops) < 0) + panic("IP: failed to allocate ipv4_dst_blackhole_ops counter\n"); + rt_hash_table = (struct rt_hash_bucket *) alloc_large_system_hash("IP route cache", sizeof(struct rt_hash_bucket), diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index a580349f0b8a..4464f3bff6a7 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -174,7 +174,7 @@ static inline int xfrm4_garbage_collect(struct dst_ops *ops) struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops); xfrm4_policy_afinfo.garbage_collect(net); - return (atomic_read(&ops->entries) > ops->gc_thresh * 2); + return (dst_entries_get_slow(ops) > ops->gc_thresh * 2); } static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -232,7 +232,6 @@ static struct dst_ops xfrm4_dst_ops = { .ifdown = xfrm4_dst_ifdown, .local_out = __ip_local_out, .gc_thresh = 1024, - .entries = ATOMIC_INIT(0), }; static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { @@ -288,6 +287,7 @@ void __init xfrm4_init(int rt_max_size) * and start cleaning when were 1/2 full */ xfrm4_dst_ops.gc_thresh = rt_max_size/2; + dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); xfrm4_policy_init(); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 17e217933885..25661f968f3f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -109,7 +109,6 @@ static struct dst_ops ip6_dst_ops_template = { .link_failure = ip6_link_failure, .update_pmtu = ip6_rt_update_pmtu, .local_out = __ip6_local_out, - .entries = ATOMIC_INIT(0), }; static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = { .destroy = ip6_dst_destroy, .check = ip6_dst_check, .update_pmtu = ip6_rt_blackhole_update_pmtu, - .entries = ATOMIC_INIT(0), }; static struct rt6_info ip6_null_entry_template = { @@ -1058,19 +1056,22 @@ static int ip6_dst_gc(struct dst_ops *ops) int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout; unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc; + int entries; + entries = dst_entries_get_fast(ops); if (time_after(rt_last_gc + rt_min_interval, now) && - atomic_read(&ops->entries) <= rt_max_size) + entries <= rt_max_size) goto out; net->ipv6.ip6_rt_gc_expire++; fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net); net->ipv6.ip6_rt_last_gc = now; - if (atomic_read(&ops->entries) < ops->gc_thresh) + entries = dst_entries_get_slow(ops); + if (entries < ops->gc_thresh) net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1; out: net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity; - return atomic_read(&ops->entries) > rt_max_size; + return entries > rt_max_size; } /* Clean host part of a prefix. Not necessary in radix tree, @@ -2524,7 +2525,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v) net->ipv6.rt6_stats->fib_rt_alloc, net->ipv6.rt6_stats->fib_rt_entries, net->ipv6.rt6_stats->fib_rt_cache, - atomic_read(&net->ipv6.ip6_dst_ops.entries), + dst_entries_get_slow(&net->ipv6.ip6_dst_ops), net->ipv6.rt6_stats->fib_discarded_routes); return 0; @@ -2666,11 +2667,14 @@ static int __net_init ip6_route_net_init(struct net *net) memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template, sizeof(net->ipv6.ip6_dst_ops)); + if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0) + goto out_ip6_dst_ops; + net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, sizeof(*net->ipv6.ip6_null_entry), GFP_KERNEL); if (!net->ipv6.ip6_null_entry) - goto out_ip6_dst_ops; + goto out_ip6_dst_entries; net->ipv6.ip6_null_entry->dst.path = (struct dst_entry *)net->ipv6.ip6_null_entry; net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; @@ -2720,6 +2724,8 @@ out_ip6_prohibit_entry: out_ip6_null_entry: kfree(net->ipv6.ip6_null_entry); #endif +out_ip6_dst_entries: + dst_entries_destroy(&net->ipv6.ip6_dst_ops); out_ip6_dst_ops: goto out; } @@ -2758,10 +2764,14 @@ int __init ip6_route_init(void) if (!ip6_dst_ops_template.kmem_cachep) goto out; - ret = register_pernet_subsys(&ip6_route_net_ops); + ret = dst_entries_init(&ip6_dst_blackhole_ops); if (ret) goto out_kmem_cache; + ret = register_pernet_subsys(&ip6_route_net_ops); + if (ret) + goto out_dst_entries; + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; /* Registering of the loopback is done before this portion of code, @@ -2808,6 +2818,8 @@ out_fib6_init: fib6_gc_cleanup(); out_register_subsys: unregister_pernet_subsys(&ip6_route_net_ops); +out_dst_entries: + dst_entries_destroy(&ip6_dst_blackhole_ops); out_kmem_cache: kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); goto out; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 39676eac3a37..7e74023ea6e4 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -199,7 +199,7 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops) struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); xfrm6_policy_afinfo.garbage_collect(net); - return atomic_read(&ops->entries) > ops->gc_thresh * 2; + return dst_entries_get_fast(ops) > ops->gc_thresh * 2; } static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -255,7 +255,6 @@ static struct dst_ops xfrm6_dst_ops = { .ifdown = xfrm6_dst_ifdown, .local_out = __ip6_local_out, .gc_thresh = 1024, - .entries = ATOMIC_INIT(0), }; static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { @@ -312,11 +311,13 @@ int __init xfrm6_init(void) */ gc_thresh = FIB6_TABLE_HASHSZ * 8; xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; + dst_entries_init(&xfrm6_dst_ops); ret = xfrm6_policy_init(); - if (ret) + if (ret) { + dst_entries_destroy(&xfrm6_dst_ops); goto out; - + } ret = xfrm6_state_init(); if (ret) goto out_policy; @@ -341,4 +342,5 @@ void xfrm6_fini(void) //xfrm6_input_fini(); xfrm6_policy_fini(); xfrm6_state_fini(); + dst_entries_destroy(&xfrm6_dst_ops); } -- cgit v1.2.3 From e37ef961e50d74f55e9edb48e54dd2e7963aad39 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Oct 2010 12:20:54 +0000 Subject: neigh: reorder struct neighbour fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le mardi 12 octobre 2010 à 00:02 +0200, Eric Dumazet a écrit : > Here is the followup patch. > > Thanks ! > Oops, this was an old version, the up2date ones also took care of "used" field. I guess its time for a sleep, sorry again. [PATCH net-next V2] neigh: reorder struct neighbour fields (refcnt) and (ha_lock, ha, used, dev, output, ops, primary_key) should be placed on a separate cache lines. refcnt can be often written, while other fields are mostly read. This gave me good result on stress test : before: real 0m45.570s user 0m15.525s sys 9m56.669s After: real 0m41.841s user 0m15.261s sys 8m45.949s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index f04e7a2522c5..55590ab16b3e 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -94,8 +94,6 @@ struct neighbour { struct neighbour __rcu *next; struct neigh_table *tbl; struct neigh_parms *parms; - struct net_device *dev; - unsigned long used; unsigned long confirmed; unsigned long updated; __u8 flags; @@ -103,16 +101,18 @@ struct neighbour { __u8 type; __u8 dead; atomic_t refcnt; + struct sk_buff_head arp_queue; + struct timer_list timer; + unsigned long used; atomic_t probes; rwlock_t lock; seqlock_t ha_lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; int (*output)(struct sk_buff *skb); - struct sk_buff_head arp_queue; - struct timer_list timer; const struct neigh_ops *ops; struct rcu_head rcu; + struct net_device *dev; u8 primary_key[0]; }; -- cgit v1.2.3 From 22fa159d37efbfe781bbb99279efe83f58b87d29 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 11 Oct 2010 16:12:00 -0700 Subject: bnx2: Update firmware to 6.0.x. - Improved flow control and simplified interface - Use hardware RSS indirection table instead of the slower firmware- based table - Lower latency interrupt on 5709 Signed-off-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 65 +- drivers/net/bnx2.h | 17 +- firmware/Makefile | 10 +- firmware/WHENCE | 11 +- firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex | 5908 --------------------- firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex | 5815 +++++++++++++++++++++ firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex | 6081 ---------------------- firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex | 6488 ++++++++++++++++++++++++ firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex | 424 -- firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex | 366 ++ firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex | 462 -- firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex | 392 ++ firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex | 499 -- firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex | 425 ++ 14 files changed, 13533 insertions(+), 13430 deletions(-) delete mode 100644 firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex create mode 100644 firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex delete mode 100644 firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex create mode 100644 firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex delete mode 100644 firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex create mode 100644 firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex delete mode 100644 firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex create mode 100644 firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex delete mode 100644 firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex create mode 100644 firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index b10be27f340a..56f3dfe70038 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -61,11 +61,11 @@ #define DRV_MODULE_NAME "bnx2" #define DRV_MODULE_VERSION "2.0.17" #define DRV_MODULE_RELDATE "July 18, 2010" -#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw" -#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw" -#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j15.fw" -#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw" -#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-5.0.0.j10.fw" +#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" +#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" +#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" +#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw" +#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw" #define RUN_AT(x) (jiffies + (x)) @@ -1269,30 +1269,9 @@ bnx2_init_rx_context(struct bnx2 *bp, u32 cid) val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; val |= 0x02 << 8; - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - u32 lo_water, hi_water; - - if (bp->flow_ctrl & FLOW_CTRL_TX) - lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT; - else - lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS; - if (lo_water >= bp->rx_ring_size) - lo_water = 0; - - hi_water = min_t(int, bp->rx_ring_size / 4, lo_water + 16); - - if (hi_water <= lo_water) - lo_water = 0; - - hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE; - lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE; + if (bp->flow_ctrl & FLOW_CTRL_TX) + val |= BNX2_L2CTX_FLOW_CTRL_ENABLE; - if (hi_water > 0xf) - hi_water = 0xf; - else if (hi_water == 0) - lo_water = 0; - val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT); - } bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val); } @@ -1373,8 +1352,7 @@ bnx2_set_mac_link(struct bnx2 *bp) /* Acknowledge the interrupt. */ REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_init_all_rx_contexts(bp); + bnx2_init_all_rx_contexts(bp); } static void @@ -4974,6 +4952,11 @@ bnx2_init_chip(struct bnx2 *bp) REG_WR(bp, BNX2_HC_CONFIG, val); + if (bp->rx_ticks < 25) + bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 1); + else + bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 0); + for (i = 1; i < bp->irq_nvecs; i++) { u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) + BNX2_HC_SB_CONFIG_1; @@ -5242,18 +5225,20 @@ bnx2_init_all_rings(struct bnx2 *bp) bnx2_init_rx_ring(bp, i); if (bp->num_rx_rings > 1) { - u32 tbl_32; - u8 *tbl = (u8 *) &tbl_32; - - bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, - BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES); + u32 tbl_32 = 0; for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) { - tbl[i % 4] = i % (bp->num_rx_rings - 1); - if ((i % 4) == 3) - bnx2_reg_wr_ind(bp, - BNX2_RXP_SCRATCH_RSS_TBL + i, - cpu_to_be32(tbl_32)); + int shift = (i % 8) << 2; + + tbl_32 |= (i % (bp->num_rx_rings - 1)) << shift; + if ((i % 8) == 7) { + REG_WR(bp, BNX2_RLUP_RSS_DATA, tbl_32); + REG_WR(bp, BNX2_RLUP_RSS_COMMAND, (i >> 3) | + BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK | + BNX2_RLUP_RSS_COMMAND_WRITE | + BNX2_RLUP_RSS_COMMAND_HASH_MASK); + tbl_32 = 0; + } } val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI | diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 2104c1005d02..efdfbc2a9e37 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -352,12 +352,7 @@ struct l2_fhdr { #define BNX2_L2CTX_BD_PRE_READ 0x00000000 #define BNX2_L2CTX_CTX_SIZE 0x00000000 #define BNX2_L2CTX_CTX_TYPE 0x00000000 -#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT 4 -#define BNX2_L2CTX_LO_WATER_MARK_SCALE 4 -#define BNX2_L2CTX_LO_WATER_MARK_DIS 0 -#define BNX2_L2CTX_HI_WATER_MARK_SHIFT 4 -#define BNX2_L2CTX_HI_WATER_MARK_SCALE 16 -#define BNX2_L2CTX_WATER_MARKS_MSK 0x000000ff +#define BNX2_L2CTX_FLOW_CTRL_ENABLE 0x000000ff #define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28) @@ -4185,6 +4180,15 @@ struct l2_fhdr { #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI (2L<<2) #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI (3L<<2) +#define BNX2_RLUP_RSS_COMMAND 0x00002048 +#define BNX2_RLUP_RSS_COMMAND_RSS_IND_TABLE_ADDR (0xfUL<<0) +#define BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK (0xffUL<<4) +#define BNX2_RLUP_RSS_COMMAND_WRITE (1UL<<12) +#define BNX2_RLUP_RSS_COMMAND_READ (1UL<<13) +#define BNX2_RLUP_RSS_COMMAND_HASH_MASK (0x7UL<<14) + +#define BNX2_RLUP_RSS_DATA 0x0000204c + /* * rbuf_reg definition @@ -6077,6 +6081,7 @@ struct l2_fhdr { #define BNX2_COM_SCRATCH 0x00120000 +#define BNX2_FW_RX_LOW_LATENCY 0x00120058 #define BNX2_FW_RX_DROP_COUNT 0x00120084 diff --git a/firmware/Makefile b/firmware/Makefile index 494a167c6552..74d47cd0886c 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,11 +35,11 @@ fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ bnx2x/bnx2x-e1h-6.0.34.0.fw \ bnx2x/bnx2x-e2-6.0.34.0.fw -fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ - bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ - bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ - bnx2/bnx2-mips-06-5.0.0.j6.fw \ - bnx2/bnx2-rv2p-06-5.0.0.j3.fw +fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \ + bnx2/bnx2-rv2p-09-6.0.17.fw \ + bnx2/bnx2-rv2p-09ax-6.0.17.fw \ + bnx2/bnx2-mips-06-6.0.15.fw \ + bnx2/bnx2-rv2p-06-6.0.15.fw fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 1d3936c2e2f7..f22c4dfd0733 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -699,15 +699,16 @@ Found in hex form in kernel source. Driver: BNX2 - Broadcom NetXtremeII -File: bnx2/bnx2-mips-06-4.6.16.fw -File: bnx2/bnx2-rv2p-06-4.6.16.fw -File: bnx2/bnx2-mips-09-4.6.17.fw -File: bnx2/bnx2-rv2p-09-4.6.15.fw +File: bnx2/bnx2-mips-06-6.0.15.fw +File: bnx2/bnx2-rv2p-06-6.0.15.fw +File: bnx2/bnx2-mips-09-6.0.17.fw +File: bnx2/bnx2-rv2p-09-6.0.17.fw +File: bnx2/bnx2-rv2p-09ax-6.0.17.fw Licence: This file contains firmware data derived from proprietary unpublished - source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + source code, Copyright (c) 2004 - 2010 Broadcom Corporation. Permission is hereby granted for the distribution of this firmware data in hexadecimal or equivalent format, provided this copyright notice is diff --git a/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex b/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex deleted file mode 100644 index 8d379bffbfef..000000000000 --- a/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex +++ /dev/null @@ -1,5908 +0,0 @@ -:10000000080001100800000000004CC8000000C8F3 -:1000100000000000000000000000000008004CC8C4 -:100020000000001400004D90080000880800000047 -:10003000000058C400004DA408005A40000000848D -:100040000000A668080058C4000001540000A6EC97 -:10005000080031D808000000000075340000A840F6 -:1000600000000000000000000000000008007534DF -:100070000000002400011D7408000488080004002A -:100080000000175C00011D98000000000000000047 -:100090000000000000000000000000000000000060 -:1000A000080000A80800000000003B38000134F4FC -:1000B0000000000000000000000000000000000040 -:0800C000000000000000000038 -:0800C8000A00004400000000E2 -:1000D000000000000000000D636F6D352E302E30E3 -:1000E0006A36000005000002000000000000000366 -:1000F00000000014000000320000000300000000B7 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000100000030C -:1001E000000000000000000D0000000D3C020800AF -:1001F00024424D003C03080024634DFCAC40000049 -:100200000043202B1480FFFD244200043C1D080005 -:1002100037BD7FFC03A0F0213C1008002610011020 -:100220003C1C0800279C4D000E000214000000003A -:100230000000000D27BDFFE8AFBF0014AFB00010F5 -:100240009742010830437000240220001062000B26 -:10025000286220011440002F0000102124024000D9 -:1002600010620025000000002402600010620026D9 -:10027000000010210A0000948FBF001427500100D5 -:10028000920200091040001A240300013C020800F9 -:100290008C42002010400016000018210E00052B93 -:1002A00000000000960300083C06080094C64DBEFE -:1002B0008E0400188F8200209605000C00031C009D -:1002C00000661825AC440000AC450004240400017D -:1002D000AC400008AC40000CAC400010AC40001436 -:1002E000AC4000180E000550AC43001C0000182163 -:1002F0000A000093006010210E0003BD0000000002 -:100300000A000093000010210E000F810000000081 -:10031000000010218FBF00148FB0001003E0000810 -:1003200027BD001827BDFFE0AFB00010AFBF001819 -:10033000AFB10014275001009203000B2402001AF1 -:10034000961100081462005B00002821322200018F -:1003500010400008000000008E0200009603001408 -:10036000000211C200021040005A10210A0000DBF6 -:10037000A44300803C0208008C420020104000286A -:10038000000000000E00052B00000000974201084D -:100390009743010C8F8500203042003E3063FFFF01 -:1003A0000002140000431025ACA200008F4201009F -:1003B0003C06080094C64DBEACA20004974301164B -:1003C0009744010E3C02200000031C003084FFFF14 -:1003D00000641825ACA3000800C230259742011024 -:1003E0009743011224040001000214003063FFFF50 -:1003F00000431025ACA2000C974201143042FFFFCD -:10040000ACA200108F420118ACA200149342010B61 -:10041000304200FFACA200180E000550ACA6001C34 -:100420003C0208008C420040244200013C010800CC -:10043000AC2200403C0308008C63004432220002DE -:1004400032240004246300013C010800AC23004472 -:10045000108000180002282B8F4202B804430008C5 -:100460008E0200203C0208008C4200602442000101 -:100470003C010800AC2200600A0000FB24050001DA -:100480009603001600002821AF4202808E0200046D -:10049000A7430284AF4202883C021000AF4202B878 -:1004A0003C0208008C42005C244200013C01080030 -:1004B000AC22005C8FBF00188FB100148FB0001009 -:1004C00000A0102103E0000827BD002027BDFFE0A9 -:1004D000AFB00010AFBF0018AFB10014275001003B -:1004E0009203000B24020003961100081462006DB1 -:1004F000000020213222000110400008000000000E -:100500008E02000096030014000211C20002104087 -:10051000005A10210A000142A44300803C02080056 -:100520008C42002010400025000000000E00052B2A -:1005300000000000974201089743010C8F850020BE -:100540003042003E3063FFFF0002140000431025DC -:10055000ACA200008F4201003C06080094C64DBECC -:10056000ACA20004974301169744010E3C02200000 -:1005700000031C003084FFFF00641825ACA30008B2 -:1005800000C2302597420110974301122404000154 -:10059000000214003063FFFF00431025ACA2000CE2 -:1005A000974201143042FFFFACA20010ACA000142F -:1005B000ACA000180E000550ACA6001C3C020800C0 -:1005C0008C420040244200013C010800AC22004063 -:1005D0003C0208008C420044322300042442000103 -:1005E0003C010800AC2200441060001A32220002D4 -:1005F0008F4202B8044300088E0200203C0208002B -:100600008C420060244200013C010800AC220060E2 -:100610000A0001772404000196030016000020213F -:10062000AF4202808E020004A7430284AF420288D8 -:100630003C021000AF4202B83C0208008C42005C51 -:10064000244200013C010800AC22005C0A00017851 -:100650008FBF001810400013000020218F430104B9 -:100660003C026020AC4300148C420004240301FED1 -:10067000304203FF1443000B000020218F42010091 -:10068000000211C02442FFFC2C420008104000026E -:100690002403000200031F403C026000AC436914C5 -:1006A000000020218FBF00188FB100148FB0001000 -:1006B0000080102103E0000827BD00208F430100C7 -:1006C0002402010050620003000311C20000000D6B -:1006D000000311C200021040005A1021A440008003 -:1006E00003E00008000010219362000003E000080E -:1006F000AF80000003E000080000102103E00008C4 -:1007000000001021240201001482000800000000F3 -:100710003C0208008C4200FC244200013C0108001D -:10072000AC2200FC0A00019F30A200203C0208001D -:100730008C420084244200013C010800AC22008469 -:1007400030A200201040000830A300103C02080036 -:100750008C420108244200013C010800AC2201083F -:1007600003E0000800000000106000080000000026 -:100770003C0208008C420104244200013C010800B4 -:10078000AC22010403E00008000000003C02080065 -:100790008C420100244200013C010800AC2201000F -:1007A00003E000080000000027BDFFE8AFBF001015 -:1007B0002744010094830008306200041040001BAD -:1007C000306600028F4202B804410008240500018F -:1007D0003C0208008C420060244200013C010800F9 -:1007E000AC2200600A0001EB8FBF00108C82002059 -:1007F0009483001600002821AF4202808C820004FE -:10080000A7430284AF4202883C021000AF4202B804 -:100810003C0208008C42005C244200013C010800BC -:10082000AC22005C0A0001EB8FBF001010C0000674 -:10083000006028218F4401000E00018F000000009D -:100840000A0001EA240500018F8200088F43010499 -:1008500050430007000028218F4401000E00018F43 -:10086000000000008F420104AF8200080000282130 -:100870008FBF001000A0102103E0000827BD001862 -:100880003C0208008C420088274301009465000C5C -:10089000244200013C010800AC2200888C6400184E -:1008A0000345102190454000AF4400388C62001C85 -:1008B0002403FFF800052E000043102434420004F6 -:1008C000AF42003C3C020005AF4200300000000097 -:1008D0000000000000000000AF450404000000001C -:1008E00000000000000000003C020006344200014D -:1008F000AF420030000000000000000000000000D7 -:100900008F420000304200101040FFFD0000102117 -:1009100003E000080000000027BDFFE0AFB20018B0 -:100920003C036010AFBF001CAFB10014AFB00010AB -:100930008C6450002402FF7F3C1A80000082202437 -:100940003484380C24020037AC6450003C12080098 -:1009500026524D38AF42000824020C80AF420024DA -:100960003C1B80083C06080024C6062C02401021CF -:100970002404001C2484FFFFAC4600000481FFFD1A -:10098000244200043C0208002442016C3C0108009F -:10099000AC224D403C020800244204043C01080003 -:1009A000AC224D443C020800244207B83C01080038 -:1009B000AC224D883C0208002442025C3C03080043 -:1009C000246306343C040800248406E03C05080047 -:1009D00024A53B503C010800AC224DA03C0208007D -:1009E000244205F43C010800AC264D843C0108007B -:1009F000AC254D943C010800AC234D9C3C01080003 -:100A0000AC244DA43C010800AC224DA83C010800D8 -:100A1000AC234D3C3C010800AC204D483C01080093 -:100A2000AC204D4C3C010800AC204D503C0108006E -:100A3000AC204D543C010800AC204D583C0108004E -:100A4000AC204D5C3C010800AC204D603C0108002E -:100A5000AC244D643C010800AC204D683C0108000A -:100A6000AC204D6C3C010800AC204D703C010800EE -:100A7000AC204D743C010800AC204D783C010800CE -:100A8000AC264D7C3C010800AC264D803C010800A2 -:100A9000AC204D8C3C010800AC254D903C01080079 -:100AA000AC234D980E0006BB000000003C02800005 -:100AB000344200708C420000AF8200143C030800F6 -:100AC0008C6300208F820004104300043C028000ED -:100AD0000E0004F3AF8300043C0280003446007033 -:100AE0003C0308008C6300A03C0208008C4200A478 -:100AF000104300048F8400143C010800AC2300A4C0 -:100B0000A743009E8CCA00003C0308008C6300BC15 -:100B10003C0208008C4200B80144202300641821E4 -:100B2000000040210064202B0048102100441021C7 -:100B30003C010800AC2300BC3C010800AC2200B81A -:100B40008F510000322200071040FFDCAF8A0014F2 -:100B50008CC600003C0508008CA500BC3C040800C5 -:100B60008C8400B800CA302300A628210000102180 -:100B700000A6302B00822021008620213227000190 -:100B80003C010800AC2500BC3C010800AC2400B8C6 -:100B900010E0001F322200028F420100AF4200200D -:100BA0008F420104AF4200A89342010B0E0001885E -:100BB000305000FF2E02001D544000040010108031 -:100BC0000E00018B0A0002C5000000000052102137 -:100BD0008C4200000040F8090000000010400005B1 -:100BE0003C0240008F4301043C026020AC430014EF -:100BF0003C024000AF4201383C0208008C42003405 -:100C0000244200013C010800AC22003432220002E0 -:100C10001040000E322200048F4201400E00018875 -:100C2000AF4200200E00034B000000003C024000D9 -:100C3000AF4201783C0208008C4200382442000197 -:100C40003C010800AC220038322200041040FF981A -:100C50003C0280008F4201800E000188AF420020DC -:100C60008F43018024020F00146200050000000081 -:100C70008F420188A742009C0A0002FA3C02400011 -:100C80009362000024030050304200FF1443000828 -:100C90003C0240000E00032D000000005440000400 -:100CA0003C0240000E000E0D000000003C0240001F -:100CB000AF4201B83C0208008C42003C24420001D3 -:100CC0003C010800AC22003C0A00027A3C02800091 -:100CD0003C0290003442000100822025AF440020F5 -:100CE0008F4200200440FFFE0000000003E00008E7 -:100CF000000000003C0280003442000100822025F8 -:100D000003E00008AF44002027BDFFE0AFB10014AE -:100D1000AFB0001000808821AFBF00180E000302A2 -:100D200030B000FF9362007D022020210202802566 -:100D3000A370007D8F7000743C0280000E00030BD6 -:100D400002028024160000098FBF00188F4201F8AC -:100D50000440FFFE24020002AF5101C0A34201C4BF -:100D60003C021000AF4201F88FBF00188FB1001491 -:100D70008FB0001003E0000827BD002027BDFFE86A -:100D8000AFBF0010974201843042020010400005BE -:100D9000000020210E001042000000000A00034164 -:100DA000240400018F420188044000098FBF001015 -:100DB0008F4201883C03FF00004310243C030400E1 -:100DC00014430003240400019362003E8FBF00100F -:100DD0000080102103E0000827BD00182402000154 -:100DE000A3600022A76200168F4401400A0003108E -:100DF0002405000127BDFFE8AFBF0014AFB000100D -:100E000093620000304400FF3883002038820030B5 -:100E10000003182B0002102B00621824106000033E -:100E200024020050148200628FBF001493420148D4 -:100E3000304200FF2443FFFF2C6200051040005C9D -:100E40008FBF0014000310803C03080024634CC8CB -:100E5000004310218C420000004000080000000008 -:100E60000E0003028F4401408F70000C8F4201443A -:100E70001602000224020001AF62000C0E00030BF8 -:100E80008F4401408F420144145000048FBF00146E -:100E90008FB000100A000FB827BD00188F62000C39 -:100EA0000A0003B300000000976200108F43014462 -:100EB0003042FFFF1462000900000000240200011C -:100EC000A76200108F420140AF4202003C021000B6 -:100ED000AF4202380A0003BA8FBF001497620010B5 -:100EE0000A0003B3000000000E0003028F4401401B -:100EF000976200128F4301443050FFFF1603000237 -:100F000024020001A76200120E00030B8F4401406F -:100F10008F420144160200048FBF00148FB00010EE -:100F20000A00034527BD0018976200120A0003B3A8 -:100F300000000000976200148F4301443042FFFF1D -:100F4000146200068FBF0014240200018FB000104D -:100F5000A76200140A0012E227BD0018976200146D -:100F60000A0003B300000000976200168F4301449B -:100F70003042FFFF14620006240200018FBF0014FC -:100F80008FB00010A76200160A000BAA27BD001838 -:100F900097620016144000068FBF00143C02080040 -:100FA0008C420070244200013C010800AC22007019 -:100FB0008FB0001003E0000827BD001827BDFFE830 -:100FC000AFBF0014AFB000108F500100936200005B -:100FD00093430109304400FF2402001F106200A562 -:100FE0002862002010400018240200382862000AFD -:100FF0001040000C2402000B286200081040002C56 -:1010000000000000046000E528620002144000288F -:1010100024020006106200268FBF00140A0004B7E5 -:101020008FB000101062005E2862000B144000DCDC -:101030008FBF00142402000E106200738FB00010E6 -:101040000A0004B700000000106200C028620039E6 -:101050001040000A2402008024020036106200CAF8 -:1010600028620037104000B424020035106200C12D -:101070008FBF00140A0004B78FB000101062002B5D -:101080002862008110400006240200C824020039B2 -:10109000106200B48FBF00140A0004B78FB00010B4 -:1010A000106200998FBF00140A0004B78FB00010BF -:1010B0003C0208008C420020104000B98FBF001491 -:1010C0000E00052B000000008F4201008F830020DE -:1010D0009745010C97460108AC6200008F4201045D -:1010E0003C04080094844DBE00052C00AC62000452 -:1010F0008F4201180006340000C43025AC6200089D -:101100008F42011C24040001AC62000C9342010ACE -:1011100000A22825AC650010AC600014AC6000187B -:10112000AC66001C0A00048D8FBF00143C0208004E -:101130008C4200201040009A8FBF00140E00052B37 -:1011400000000000974401083C03080094634DBE72 -:101150009745010C000422029746010E8F82002061 -:10116000000426000083202500052C003C0300809D -:1011700000A6282500832025AC400000AC400004D8 -:10118000AC400008AC40000CAC450010AC40001472 -:10119000AC400018AC44001C0A00048C240400017C -:1011A0009742010C144000150000000093620005F6 -:1011B0003042001014400011000000000E00030235 -:1011C0000200202193620005020020213442001019 -:1011D0000E00030BA36200059362000024030020AD -:1011E000304200FF1043006D020020218FBF001429 -:1011F0008FB000100A00105827BD00180000000D25 -:101200000A0004B68FBF00143C0208008C42002084 -:10121000104000638FBF00140E00052B000000007B -:101220008F4201048F8300209744010C3C05080085 -:1012300094A54DBEAC6200009762002C000424000F -:101240003042FFFF008220253C02400E00A22825EC -:10125000AC640004AC600008AC60000CAC60001032 -:10126000AC600014AC600018AC65001C0A00048C73 -:10127000240400010E00030202002021A7600008E0 -:101280000E00030B02002021020020210E0003109B -:10129000240500013C0208008C4200201040004060 -:1012A0008FBF00140E00052B000000009742010CB8 -:1012B0008F8300203C05080094A54DBE0002140059 -:1012C000AC700000AC620004AC6000088F64004C9D -:1012D0003C02401F00A22825AC64000C8F62005025 -:1012E00024040001AC6200108F620054AC62001450 -:1012F000AC600018AC65001C8FBF00148FB00010EC -:101300000A00055027BD0018240200205082002545 -:101310008FB000100E000FA202002021104000200C -:101320008FBF0014020020218FB000100000282180 -:101330000A00031027BD0018020020218FBF0014EF -:101340008FB000100A00061827BD00189745010C41 -:10135000020020218FBF00148FB000100A00063851 -:1013600027BD0018020020218FB000100A00065D82 -:1013700027BD00189345010D020020218FB00010F9 -:101380000A0006A727BD0018020020218FBF001405 -:101390008FB000100A00068327BD00188FBF00140D -:1013A0008FB0001003E0000827BD00188F420278BC -:1013B0000440FFFE2402000234840080AF44024057 -:1013C000A34202443C02100003E00008AF4202784E -:1013D0003C04080094844DCA3C0208008C424DD461 -:1013E0003083FFFF000318C000431021AF42003CD0 -:1013F0003C0208008C424DD0AF4200383C02005005 -:1014000034420008AF42003000000000000000003D -:10141000000000008F420000304200201040FFFD1D -:10142000000000008F4204003C010800AC224DC0C7 -:101430008F4204043C010800AC224DC43C02002051 -:10144000AF420030000000003C02080094424DC84A -:101450003C03080094634DCC3C05080094A54DCE98 -:1014600024840001004310213083FFFF3C01080069 -:10147000A4224DC83C010800A4244DCA14650003F1 -:10148000000000003C010800A4204DCA03E0000851 -:10149000000000003C05000A27BDFFE803452821A5 -:1014A0003C04080024844DB0AFBF00100E0005B509 -:1014B0002406000A3C02080094424DB23C03080096 -:1014C00094634DCE3042000F2442000300431804C1 -:1014D00024027FFF0043102B10400002AF83001C4A -:1014E0000000000D0E0004C2000000003C020800D5 -:1014F00094424DBA8FBF001027BD001803E00008CA -:10150000A74200A23C02000A0342102194430006B5 -:101510003C02080094424DBA3C010800A4234DB699 -:10152000004310238F83001C0002140000021403E8 -:101530000043102B03E000083842000127BDFFE8FC -:10154000AFBF00103C02000A034210219442000683 -:101550003C010800A4224DB60E00050F000000005B -:101560005440FFF93C02000A8FBF001003E000085E -:1015700027BD001827BDFFE8AFBF00100E00050F04 -:101580000000000010400003000000000E00051DD8 -:10159000000000003C0208008C424DC08FBF0010CC -:1015A00027430400AF4200383C0208008C424DC47F -:1015B00027BD0018AF830020AF42003C3C0200056D -:1015C000AF42003003E00008AF8000188F8200189F -:1015D0003C0300060002114000431025AF420030DA -:1015E0000000000000000000000000008F4200002A -:1015F000304200101040FFFD27420400AF8200205F -:1016000003E00008AF8000183C0608008CC64DC4FB -:101610008F8500188F8300203C02080094424DBA49 -:1016200027BDFFE024A5000124630020244200011F -:1016300024C70020AFB10014AFB00010AFBF001836 -:10164000AF850018AF8300203C010800A4224DBAEA -:10165000309000FF3C010800AC274DC404C10008D5 -:101660000000882104E00006000000003C020800A1 -:101670008C424DC0244200013C010800AC224DC008 -:101680003C02080094424DBA3C03080094634DC8E4 -:101690000010202B004310262C420001004410258E -:1016A000144000048F830018240200101462000FFD -:1016B000000000000E000541241100013C03080059 -:1016C00094634DBA3C02080094424DC81462000372 -:1016D000000000000E0004C200000000160000031D -:1016E000000000000E00052B000000003C03080075 -:1016F00094634DBE3C02080094424DBC246300013B -:101700003064FFFF3C010800A4234DBE1482000397 -:10171000000000003C010800A4204DBE120000069D -:10172000000000003C02080094424DBAA74200A20B -:101730000A0005A3022010210E00050F0000000082 -:1017400010400004022010210E00051D00000000C2 -:10175000022010218FBF00188FB100148FB000102D -:1017600003E0000827BD00203084FFFF30A5FFFF05 -:1017700000001821108000070000000030820001E6 -:101780001040000200042042006518210A0005AB49 -:101790000005284003E000080060102110C000068A -:1017A00024C6FFFF8CA2000024A50004AC82000028 -:1017B0000A0005B52484000403E0000800000000CE -:1017C00010A0000824A3FFFFAC860000000000006A -:1017D000000000002402FFFF2463FFFF1462FFFAF1 -:1017E0002484000403E0000800000000240200013B -:1017F000AF62000CA7620010A7620012A76200147B -:1018000003E00008A76200163082007F0342102127 -:101810003C08000E004818213C0208008C420020C1 -:1018200027BDFFD82407FF80AFB3001CAFB200185C -:10183000AFB10014AFB00010AFBF00200080802116 -:1018400030B100FF0087202430D200FF1040002F6D -:1018500000009821AF44002C906200002403005047 -:10186000304200FF1443000E000000003C0208005C -:101870008C4200E00202102100471024AF42002CED -:101880003C0208008C4200E0020210213042007F3E -:101890000342102100481021944200D43053FFFF2E -:1018A0000E00052B000000003C02080094424DBED3 -:1018B0008F8300200011340000C2302500122C005C -:1018C0003C02400000C2302534A50001AC7000008D -:1018D0008FBF0020AC6000048FB20018AC7300080A -:1018E0008FB10014AC60000C8FB3001CAC6500100D -:1018F0008FB00010AC60001424040001AC6000182C -:1019000027BD00280A000550AC66001C8FBF0020D0 -:101910008FB3001C8FB200188FB100148FB000106D -:1019200003E0000827BD00289343010F24020010A4 -:101930001062000E2865001110A00007240200129A -:10194000240200082405003A10620006000030213D -:1019500003E0000800000000240500351462FFFCCD -:10196000000030210A0005D0000000008F42007402 -:1019700024420FA003E00008AF62000C27BDFFE87F -:10198000AFBF00100E000310240500018FBF001030 -:1019900024020001A762001227BD001824020001E2 -:1019A00003E00008A360002227BDFFE0AFB10014F0 -:1019B000AFB00010AFBF001830B1FFFF0E00030240 -:1019C000008080219362003F24030004304200FF26 -:1019D0001443000C02002021122000082402000AF7 -:1019E0000E0005C900000000936200052403FFFEFD -:1019F00000431024A362000524020012A362003FEA -:101A0000020020210E00030BA360008116200003BA -:101A1000020020210E00062D0000000002002021FF -:101A2000322600FF8FBF00188FB100148FB0001056 -:101A3000240500380A0005D027BD002027BDFFE09F -:101A4000AFBF001CAFB20018AFB10014AFB00010B0 -:101A50000E000302008080210E0005C90000000076 -:101A60009362003F24120018305100FF123200032D -:101A70000200202124020012A362003F93620005AD -:101A80002403FFFE004310240E00030BA362000595 -:101A9000020020212405002016320007000030211A -:101AA0008FBF001C8FB200188FB100148FB00010D0 -:101AB0000A00031027BD00208FBF001C8FB2001842 -:101AC0008FB100148FB00010240500390A0005D032 -:101AD00027BD002027BDFFE8AFB00010AFBF001446 -:101AE0009742010C2405003600808021144000102C -:101AF000304600FF0E000302000000002402001226 -:101B0000A362003F93620005344200100E0005C935 -:101B1000A36200050E00030B020020210200202119 -:101B20000E000310240500200A00069C000000009F -:101B30000E0005D0000000000E000302020020216C -:101B4000936200232403FF9F0200202100431024FE -:101B50008FBF00148FB00010A36200230A00030B94 -:101B600027BD001827BDFFE0AFBF0018AFB10014BC -:101B7000AFB0001030B100FF0E00030200808021E2 -:101B8000240200120E0005C9A362003F0E00030BE1 -:101B90000200202102002021022030218FBF0018E6 -:101BA0008FB100148FB00010240500350A0005D055 -:101BB00027BD0020A380002C03E00008A380002D97 -:101BC0008F4202780440FFFE8F820034AF42024011 -:101BD00024020002A34202443C02100003E0000879 -:101BE000AF4202783C0360008C625400304200082F -:101BF0001440FFFD000000008C625408AF82000C0E -:101C000024020052AC605408AC645430AC625434CA -:101C10002402000803E00008AC6254003C026000AB -:101C20008C42540030420008104000053C03600024 -:101C30008C625400304200081440FFFD0000000098 -:101C40008F83000C3C02600003E00008AC435408A2 -:101C500090A3000024020005008040213063003F73 -:101C600000004821146200050000502190A2001CD1 -:101C700094A3001E304900FF306AFFFFAD00000C46 -:101C8000AD000010AD000024950200148D05001C6D -:101C90008D0400183042FFFF00491023000211009C -:101CA000000237C3004038210086202300A2102BF9 -:101CB0000082202300A72823AD05001CAD040018D6 -:101CC000A5090014A5090020A50A001603E00008D4 -:101CD000A50A00228F4201F80440FFFE2402000200 -:101CE000AF4401C0A34201C43C02100003E000085D -:101CF000AF4201F83C0208008C4200B427BDFFE867 -:101D0000AFBF001424420001AFB000103C01080036 -:101D1000AC2200B48F4300243C02001F30AA00FF15 -:101D20003442FF8030D800FF006280240080F82118 -:101D300030EF00FF1158003B01405821240CFF8078 -:101D40003C19000A3163007F000310C000031940F2 -:101D5000006218213C0208008C4200DC256800016A -:101D6000310D007F03E21021004310213043007F3A -:101D700003431821004C102400794821AF4200246D -:101D80008D220024016C1824006C7026AD22000CFA -:101D90008D220024310800FFAD220010952200148E -:101DA000952300208D27001C3042FFFF3063FFFF8A -:101DB0008D2600180043102300021100000227C3E3 -:101DC0000040282100C4302300E2102B00C2302341 -:101DD00000E53823AD27001CAD2600189522002011 -:101DE000A522001495220022154B000AA5220016F8 -:101DF0008D2300248D2200082546000131450080F6 -:101E00001462000430C4007F108F000238AA0080E2 -:101E100000C0502151AF000131C800FF1518FFC9A3 -:101E2000010058218F8400343082007F0342182142 -:101E30003C02000A006218212402FF800082202454 -:101E4000AF440024A06A0079A06A00838C6200502D -:101E50008F840034AC6200708C6500743C027FFF9C -:101E60003442FFFF00A228240E000703AC65007473 -:101E7000AF5000248FBF00148FB0001003E00008A3 -:101E800027BD001827BDFFC0AFBE0038AFB7003474 -:101E9000AFB5002CAFB20020AFB1001CAFB000183E -:101EA000AFBF003CAFB60030AFB40028AFB30024E2 -:101EB0008F4500248F4600288F43002C3C02001FD2 -:101EC0003442FF800062182400C230240080A82120 -:101ED000AFA3001400A2F0240E0006C7AFA60010A6 -:101EE0003C0208008C4200E02410FF80036088213F -:101EF00002A2102100501024AF4200243C0208002E -:101F00008C4200E002A210213042007F03421821DF -:101F10003C02000A00629021924200D29363008446 -:101F2000305700FF306300FF2402000110620034CC -:101F30000360202124020002146200360000000029 -:101F40000E0012AE024028219223008392220083C9 -:101F50003063007F3042007F000210C00003194050 -:101F6000006218213C0208008C4200DC02A2102111 -:101F70000043382100F01024AF4200289225007859 -:101F80009224008330E2007F034218213C02000CBF -:101F900014850007006280212402FFFFA24200F1A5 -:101FA0002402FFFFA64200F20A0007BF2402FFFF3F -:101FB00096020020A24200F196020022A64200F200 -:101FC0008E020024AE4200F492220083A24200F06E -:101FD0008E4200C8AE4200FC8E4200C4AE4200F801 -:101FE0008E220050AE4201008E4200CCAE4201046F -:101FF000922200853042003F0A00081A3442004015 -:102000000E0012D102402821922200850A00081AEF -:102010003042003F936200852403FFDF3042003FDF -:10202000A36200859362008500431024A3620085AB -:102030009363008393620078307400FF304200FFA6 -:1020400010540036240AFF803C0C000C3283007FC1 -:10205000000310C000031940006218213C02080070 -:102060008C4200DC268800013109007F02A2102189 -:102070000043382130E2007F0342182100EA102497 -:10208000AF420028006C80218E020024028A1824AE -:10209000006A5826AE02000C8E020024310800FFB0 -:1020A000AE02001096020014960300208E07001C5A -:1020B0003042FFFF3063FFFF8E06001800431023FD -:1020C00000021100000227C30040282100C4302371 -:1020D00000E2102B00C2302300E53823AE07001CBD -:1020E000AE06001896020020A602001496020022F6 -:1020F000A602001692220079304200FF1054000719 -:102100000000000051370001316800FF9222007882 -:10211000304200FF1448FFCD0100A021922200832D -:10212000A22200798E2200500A00087AAE220070A6 -:10213000A22200858E22004C2405FF80AE42010CB5 -:102140009222008534420020A2220085924200D1D2 -:102150003C0308008C6300DC305400FF3C020800A4 -:102160008C4200E400143140001420C002A3182166 -:1021700000C4202102A21021006438210046102151 -:102180000045182400E52824AF450028AF43002C63 -:102190003042007F924400D030E3007F0342282188 -:1021A000034318213C02000C006280213C02000E17 -:1021B000309600FF00A298211296002A000000002D -:1021C0008E02000C02002021026028211040002510 -:1021D000261000280E0006E2000000009262000DAA -:1021E00026830001307400FF3042007FA262000DA0 -:1021F0002404FF801697FFF0267300203C0208009D -:102200008C4200DC0000A02102A210210044102416 -:10221000AF4200283C0208008C4200E43C03080066 -:102220008C6300DC02A2102100441024AF42002C79 -:102230003C0208008C4200E402A318213063007FB6 -:1022400002A210213042007F0342202103431821C3 -:102250003C02000C006280213C02000E0A00083C97 -:10226000008298218E4200D8AE2200508E4200D8C3 -:10227000AE22007092250083924600D19223008303 -:10228000924400D12402FF8000A228243063007F02 -:10229000308400FF00A628250064182A1060000280 -:1022A00030A500FF38A50080A2250083A225007973 -:1022B0000E0006D5000000009222007E02A0202120 -:1022C000A222007A8E2300743C027FFF3442FFFF7B -:1022D000006218240E000703AE2300748FA20010C2 -:1022E000AF5E00248FBF003CAF4200288FBE003895 -:1022F0008FA200148FB700348FB600308FB5002C3A -:102300008FB400288FB300248FB200208FB1001C3F -:102310008FB0001827BD004003E00008AF42002C3A -:1023200090A2000024420001A0A200003C0308008B -:102330008C6300F4304200FF1443000F0080302112 -:10234000A0A000003C0208008C4200E48F8400340E -:10235000008220213082007F034218213C02000CC1 -:10236000006218212402FF8000822024ACC30000F8 -:1023700003E00008AF4400288C82000024420020C3 -:1023800003E00008AC82000094C200003C08080092 -:10239000950800CA30E7FFFF0080482101021021A4 -:1023A000A4C2000094C200003042FFFF00E2102BE4 -:1023B00054400001A4C7000094A200003C030800A0 -:1023C0008C6300CC24420001A4A2000094A200006F -:1023D0003042FFFF544300078F8600280107102B6F -:1023E000A4A000005440000101003821A4C700004F -:1023F0008F8600288CC4001CAF44003C94A20000CF -:102400008F43003C3042FFFF000210C000621821E1 -:10241000AF43003C8F42003C008220231880000420 -:10242000000000008CC200180A0008DB24420001F2 -:102430008CC20018AF4200383C02005034420010F9 -:10244000AF4200300000000000000000000000006B -:102450008F420000304200201040FFFD00000000CD -:102460008F420404AD2200048F420400AD2200001C -:102470003C020020AF42003003E0000800000000F2 -:1024800027BDFFE0AFB20018AFB10014AFB000102D -:10249000AFBF001C94C2000000C080213C120800A5 -:1024A000965200C624420001A602000096030000D6 -:1024B00094E2000000E03021144300058FB10030A9 -:1024C0000E0008B0024038210A00090D000000008B -:1024D0008C8300048C8200042442004004610007C5 -:1024E000AC8200048C820004044000040000000060 -:1024F0008C82000024420001AC82000096020000A1 -:102500003042FFFF50520001A6000000962200005A -:1025100024420001A62200008F820028962300009A -:1025200094420016144300048FBF001C24020001D3 -:10253000A62200008FBF001C8FB200188FB10014BC -:102540008FB0001003E0000827BD00208F8900280D -:1025500027BDFFE0AFBF00188D22002827480400E8 -:1025600030E700FFAF4200388D22002CAF880030EA -:10257000AF42003C3C020005AF42003000000000CA -:10258000000000000000000000000000000000004B -:10259000000000008C82000C8C82000CAD02000058 -:1025A0008C820010AD0200048C820018AD0200087D -:1025B0008C82001CAD02000C8CA20014AD02001035 -:1025C0008C820020AD02001490820005304200FF92 -:1025D00000021200AD0200188CA20018AD02001C0F -:1025E0008CA2000CAD0200208CA20010AD020024D1 -:1025F0008CA2001CAD0200288CA20020AD02002C91 -:10260000AD060030AD000034978300263402FFFF92 -:1026100014620002006020213404FFFF10E000116A -:10262000AD040038952300369524003624020001BD -:102630003063FFFF000318C2006918219065004055 -:10264000308400070082100400451025A06200407D -:102650008F820028944200563042FFFF0A0009741E -:10266000AD02003C9523003695240036240200017B -:102670003063FFFF000318C2006918219065004015 -:102680003084000700821004000210270045102447 -:10269000A0620040AD00003C00000000000000000F -:1026A000000000003C02000634420040AF4200300F -:1026B0000000000000000000000000008F42000049 -:1026C000304200101040FFFD8F860028AF88003098 -:1026D00024C2005624C7003C24C4002824C500326C -:1026E00024C600360E0008EEAFA200108FBF0018FF -:1026F00003E0000827BD00208F8300243C0608006B -:102700008CC600E88F82003430633FFF00031980DD -:1027100000461021004310212403FF803046007F33 -:1027200000431024AF420028034618213C02000C4D -:102730000062302190C2000D30A500FF000038215A -:1027400034420010A0C2000D8F8900288F8A002417 -:1027500095230036000A138230480003240200014A -:10276000A4C3000E1102000B290200021040000554 -:10277000240200021100000C240300010A0009B821 -:102780000000182111020006000000000A0009B82C -:10279000000018218CC2002C0A0009B82443000153 -:1027A0008CC20014244300018CC200180043102B7B -:1027B00050400009240700012402002714A200034E -:1027C000000000000A0009C4240700019522003E11 -:1027D00024420001A522003E000A13823043000378 -:1027E0002C620002104000090080282114600004BF -:1027F0000000000094C200360A0009D43046FFFFF2 -:102800008CC600380A0009D400802821000030213D -:102810003C04080024844DD80A000921000000006F -:10282000274901008D22000C95230006012020215C -:10283000000216023046003F3063FFFF24020027EB -:1028400000C0282128C7002810C2000EAF83002432 -:1028500010E00008240200312402002110C2000907 -:102860002402002510C200079382002D0A0009F3FC -:102870000000000010C200059382002D0A0009F339 -:10288000000000000A00098C000000000A0006BEDB -:102890000000000095230006912400058D25000C02 -:1028A0008D2600108D2700188D28001C8D290020F2 -:1028B000244200013C010800A4234DDE3C01080035 -:1028C000A0244DDD3C010800AC254DE43C0108008E -:1028D000AC264DE83C010800AC274DF03C01080057 -:1028E000AC284DF43C010800AC294DF803E0000889 -:1028F000A382002D8F87002827BDFFC0AFB300340F -:10290000AFB20030AFB1002CAFB00028AFBF00387D -:102910003C0208008C4200D094E3003030B0FFFF4E -:10292000005010073045FFFF3063FFFF00C09821C3 -:10293000A7A200103C110800963100C614A300069F -:102940003092FFFF8CE2002424420030AF42003C72 -:102950000A000A2C8CE2002094E200323042FFFF91 -:1029600054A2000827A400188CE2002C2442003056 -:10297000AF42003C8CE20028AF4200380A000A3A1D -:102980008F84002827A5001027A6002002203821C8 -:102990000E0008B0A7A000208FA20018244200302B -:1029A000AF4200388FA2001CAF42003C8F84002849 -:1029B0003C020005AF4200309482003427430400FB -:1029C0003042FFFF0202102B14400007AF8300309B -:1029D0009482005494830034020210210043102397 -:1029E0000A000A4E3043FFFF94830054948200345F -:1029F0000223182100501023006218233063FFFFC8 -:102A0000948200163042FFFF1443000300000000D0 -:102A10000A000A5C24030001948200163042FFFF82 -:102A20000043102B104000058F8200309482001666 -:102A3000006210233043FFFF8F820030AC53000050 -:102A4000AC400004AC520008AC43000C3C02000651 -:102A500034420010AF4200300000000000000000CF -:102A6000000000008F420000304200101040FFFDC7 -:102A7000001018C20064182190650040320400075D -:102A8000240200018FBF00388FB300348FB20030B2 -:102A90008FB1002C8FB00028008210040045102553 -:102AA00027BD004003E00008A062004027BDFFA84A -:102AB000AFB60050AFB5004CAFB40048AFB3004460 -:102AC000AFB1003CAFBF0054AFB20040AFB0003870 -:102AD0008C9000003C0208008C4200E88F86003495 -:102AE000960300022413FF8000C2302130633FFFB1 -:102AF0000003198000C3382100F3102490B20000B5 -:102B0000AF42002C9203000230E2007F03423021EA -:102B10003C02000E00C28821306300C02402004045 -:102B20000080A82100A0B021146200260000A0218E -:102B30008E3400388E220018144000022402000156 -:102B4000AE2200189202000D304200201440001501 -:102B50008F8200343C0308008C6300DC001238C014 -:102B6000001231400043102100C7302100463821B7 -:102B700030E300073C02008030E6007800C23025D8 -:102B80000343182100F31024AF4208002463090016 -:102B9000AF4608108E2200188C63000800431021F5 -:102BA000AE2200188E22002C8E2300182442000131 -:102BB0000062182B1060003D000000000A000B109E -:102BC00000000000920300022402FFC00043102412 -:102BD000304200FF1440000524020001AE2200181C -:102BE000962200360A000AF93054FFFF8E220014A4 -:102BF00024420001AE2200189202000000021600DA -:102C000000021603044100290000000096020002A1 -:102C100027A4001000802821A7A200169602000217 -:102C200024070001000030213042FFFFAF82002462 -:102C30000E000921AFA0001C960300023C0408000E -:102C40008C8400E88F82003430633FFF00031980DA -:102C500000441021004310213043007F3C05000C4C -:102C60000053102403431821AF42002800651821A7 -:102C70009062000D001221403042007FA062000DE2 -:102C80003C0308008C6300E48F8200340043102171 -:102C90000044382130E2007F03421021004510211A -:102CA00000F31824AF430028AEA200009222000DCA -:102CB000304200101040001302A020218F83002812 -:102CC0008EA40000028030219462003E2442FFFF67 -:102CD000A462003E948400029625000E3084FFFF1B -:102CE0000E000A0B30A5FFFF8F82002894430034AA -:102CF0009622000E1443000302A0202124020001AA -:102D0000A382002C02C028210E00089600000000BB -:102D10008FBF00548FB600508FB5004C8FB4004861 -:102D20008FB300448FB200408FB1003C8FB00038A9 -:102D300003E0000827BD00588F82002827BDFFD080 -:102D4000AFB40028AFB20020AFBF002CAFB3002457 -:102D5000AFB1001CAFB00018904400D0904300D138 -:102D60000000A021309200FFA3A30010306300FFF9 -:102D70008C5100D88C5300DC1072002B240200010F -:102D80003C0308008C6300E493A400108F8200349D -:102D90002406FF800004214000431021004410213C -:102DA0003043007F00461024AF420028034318211F -:102DB0003C02000C006218218C62000427A400145D -:102DC00027A5001002228021027010230440001564 -:102DD000AFA300149062000D00C21024304200FF27 -:102DE00014400007020088219062000D3442004028 -:102DF0000E000896A062000D0A000B5593A2001069 -:102E00000E000A79241400018F830028AC7000D8CA -:102E100093A20010A06200D193A200101452FFD818 -:102E20000000000024020001168200048FBF002C65 -:102E30000E0006BE000000008FBF002C8FB40028DB -:102E40008FB300248FB200208FB1001C8FB0001808 -:102E500003E0000827BD003027BDFFD8AFB3001C3A -:102E6000AFB20018AFB10014AFB00010AFBF002078 -:102E70000080982100E0802130B1FFFF0E00052B7B -:102E800030D200FF00000000000000000000000041 -:102E90008F820020AC510000AC520004AC530008FB -:102EA000AC40000CAC400010AC400014AC4000182A -:102EB0003C03080094634DBE02038025AC50001C07 -:102EC00000000000000000000000000024040001D9 -:102ED0008FBF00208FB3001C8FB200188FB1001479 -:102EE0008FB000100A00055027BD002827BDFFE85D -:102EF000AFB00010AFBF001430A5FFFF30C600FF19 -:102F00000080802124020C80AF42002400000000D9 -:102F100000000000000000000000000000000000B1 -:102F20000E000B64000000003C040800248400E054 -:102F30008C8200002403FF808FBF00140202102146 -:102F400000431024AF4200248C8200003C03000A9E -:102F5000020280213210007F035010218FB0001038 -:102F60000043102127BD001803E00008AF820028AD -:102F700027BDFFE8AFBF00108F4401403C030800AD -:102F80008C6300E02402FF80AF84003400831821AA -:102F900000621024AF4200243C020008034240219A -:102FA000950500023063007F3C02000A03431821AC -:102FB0000062182130A5FFFF3402FFFF000030211E -:102FC0003C07602010A20006AF8300282402FFFF08 -:102FD000A5020002946500D40E000B8930A5FFFF06 -:102FE0008FBF001024020C8027BD001803E00008EA -:102FF000AF4200243C020008034240219502000237 -:103000003C0A0800954A00C63046FFFF14C000077E -:103010003402FFFF8F8200288F8400343C07602039 -:10302000944500D40A000BF230A5FFFF10C2002423 -:103030008F87002894E2005494E400163045FFFF87 -:1030400000A6102300A6182B3089FFFF1060000493 -:103050003044FFFF00C51023012210233044FFFF3E -:10306000008A102B1040000C012A102324020001BA -:10307000A50200162402FFFFA502000294E500D479 -:103080008F8400340000302130A5FFFF3C07602012 -:103090000A000B89000000000044102A10400008BC -:1030A00000000000950200163042000110400004AC -:1030B000000000009742007E24420014A502001682 -:1030C00003E00008000000008F84002827BDFFE017 -:1030D000AFBF0018948200349483003E1060001A41 -:1030E0003048FFFF9383002C240200011462002764 -:1030F0008FBF00188F820028000818C2310800070F -:10310000006218212447003A244900542444002036 -:10311000244500302446003490620040304200FFD5 -:103120000102100730420001104000168FBF001846 -:103130000E0008EEAFA900108F82002894420034E0 -:103140000A000C0B3048FFFF948300369482003451 -:103150001043000E8FBF001894820036A482003402 -:1031600094820056A48200548C82002CAC820024ED -:1031700094820032A48200309482003CA482003AFF -:103180008FBF00180A000BCB27BD002003E000080A -:1031900027BD002027BDFFE8AFBF00108F4A010008 -:1031A0003C0508008CA500E03C02080090424DE47C -:1031B0003C0C0800958C4DDE01452821304B003F2A -:1031C00030A2007F03424021396900323C02000AEC -:1031D0003963003F2C630001010240212D290001C9 -:1031E0002402FF8000A2282401234825AF8A00344E -:1031F00000801821AF4500240000302100802821E4 -:1032000024070001AF8800283C04080024844DD81E -:10321000AF8C002415200007A380002D240200207D -:103220005562000F006020213402FFFF5582000C20 -:10323000006020212402002015620005000000002B -:103240008C6300142402FFFF1062000700000000DE -:103250000E000921000000000A000C6800000000B8 -:103260000E00098C016028210E000C0000000000F7 -:103270008FBF001024020C8027BD001803E0000857 -:10328000AF4200243C0208008C4200E027BDFFA0B2 -:10329000AFB1003C008210212411FF80AFBE005866 -:1032A000AFB70054AFB20040AFB00038AFBF005C62 -:1032B000AFB60050AFB5004CAFB40048AFB3004458 -:1032C000005110248F4800248F4900288F47002880 -:1032D000AF4200243C0208008C4200E000809021B4 -:1032E00024060006008210213042007F034218218C -:1032F0003C02000A006280213C02001F3442FF8031 -:1033000000E2382427A40010260500F00122F02452 -:103310000102B8240E0005B5AFA700308FA2001837 -:10332000AE0200C48FA2001CAE0200C88FA200240F -:10333000AE0200CC93A40010920300D12402FF80BF -:103340000082102400431025304900FF3083007FA5 -:103350003122007F0062102A10400004000310C0D8 -:1033600001311026304900FF000310C0000319404E -:10337000006218213C0208008C4200DC920400D25A -:10338000024210210043102100511024AF420028B6 -:1033900093A300103063007F000310C000031940A6 -:1033A000006218213C0208008C4200DC024210211D -:1033B000004310213042007F034218213C02000CE0 -:1033C000006240218FA300142402FFFF106200302E -:1033D000309500FF93A2001195030014304400FFC4 -:1033E0003063FFFF0064182B1060000D0000000028 -:1033F000950400148D07001C8D0600183084FFFF13 -:1034000000442023000421000000102100E43821A2 -:1034100000E4202B00C230210A000CE200C430215D -:10342000950400148D07001C8D0600183084FFFFE2 -:1034300000822023000421000000102100801821B8 -:1034400000C2302300E4202B00C4302300E33823E3 -:10345000AD07001CAD06001893A20011A5020014D0 -:1034600097A20012A50200168FA20014AD02001050 -:103470008FA20014AD02000C93A20011A50200203F -:1034800097A20012A50200228FA20014AD02002410 -:103490002406FF80024610243256007FAF420024EB -:1034A000035618213C02000A006280218E02004C63 -:1034B0008FA200203124007F000428C0AE020050FB -:1034C0008FA200200004214000852821AE02007058 -:1034D00093A2001001208821A202008393A2001071 -:1034E000A2020079920200853042003FA2020085CC -:1034F0003C0208008C4200DC0242102100451021F1 -:1035000000461024AF42002C3C0208008C4200E42C -:103510003C0308008C6300DC0242102100441021AF -:1035200000461024AF4200283C0208008C4200E410 -:103530000243182100651821024210210044102185 -:103540003042007F3063007F93A5001003422021AA -:10355000034318213C02000E006240213C02000C93 -:1035600010B1008C008248213233007F16600019B0 -:103570002404FF803C0208008C4200DC024210213F -:1035800000441024AF42002C3C0208008C4200E4AE -:103590003C0308008C6300DC02421021004410242C -:1035A000AF4200283C0208008C4200E4024318218C -:1035B0003063007F024210213042007F034220210D -:1035C000034318213C02000E006240213C02000C23 -:1035D000008248219124000D2414FF800000102156 -:1035E00000942025A124000D9504000295050014E7 -:1035F0008D07001C3084FFFF30A5FFFF8D060018EB -:10360000008520230004210000E4382100C230217D -:1036100000E4202B00C43021AD07001CAD060018CB -:1036200095020002A5020014A50000168D020008F4 -:10363000AD0200108D020008AD02000C95020002E0 -:10364000A5020020A50000228D020008AD02002482 -:103650009122000D3042004010400042262200011D -:103660003C0208008C4200E0A3B300283C10000A92 -:103670000242102100541024AF4200243C020800F2 -:103680008C4200E0A380002C27A4002C02421021D1 -:103690003042007F03421821007018218C6200D84C -:1036A0008D26000427A50028AFA9002C0046102174 -:1036B000AC6200D80E000A79AF83002893A30028DB -:1036C0008F8200280E0006BEA04300D10E000C0021 -:1036D0000000000002541024AF4200243C02080005 -:1036E0008C4200DC00132940001320C000A42021DC -:1036F000024210210044102100541024AF42002C3B -:103700003C0208008C4200E43C0308008C6300DCAF -:10371000035630210242102100451021005410248C -:10372000AF4200283C0208008C4200E4024318210A -:103730000064182102421021004510213042007F10 -:103740003063007F03422021034318213C02000E16 -:10375000006240213C02000C00D080210082482100 -:10376000262200013043007F14750005304400FF1D -:103770002403FF800223102400431026304400FF5E -:1037800093A2001000808821250800281444FF76A9 -:103790002529002093A400108FA300142402FFFF0A -:1037A0001062000A308900FF248200012483000196 -:1037B0003042007F14550005306900FF2403FF806C -:1037C0000083102400431026304900FF9202007845 -:1037D000305300FF11330032012088213C020800E1 -:1037E0008C4200DC3225007F000520C00005294006 -:1037F00000A42021024210212406FF800044102151 -:1038000000461024AF42002C3C0308008C6300DC0F -:103810003C0208008C4200E40243182102421021BD -:103820000045102100641821004610243063007FF9 -:10383000AF420028034318213C02000E00624021E1 -:103840003C0208008C4200E48D06000C010020219F -:1038500002421021004510213042007F034218210E -:103860003C02000C0062482110C0000D01202821FC -:103870000E0006E2000000002402FF80022218244D -:1038800026240001006228263082007F14550002A1 -:10389000308300FF30A300FF1473FFD00060882145 -:1038A0008E0300743C027FFF3442FFFF0062182445 -:1038B000AE0300740E00070302402021AF5700241E -:1038C0008FA20030AF5E00288FBF005C8FBE005813 -:1038D0008FB700548FB600508FB5004C8FB400489E -:1038E0008FB300448FB200408FB1003C8FB00038DE -:1038F00027BD006003E00008AF42002C27BDFFD8C1 -:10390000AFB1001CAFBF0020AFB000182751018835 -:10391000922200032408FF803C03000A3047007F06 -:10392000A3A700108F4601803C0208008C4200E0F3 -:10393000AF86003400C2282100A81024AF42002422 -:103940009224000030A2007F034210210043102186 -:10395000AF8200283084007F2402000214820025F8 -:10396000000719403C0208008C4200E400C210210C -:103970000043282130A2007F0342182100A8102410 -:10398000AF4200283C02000C006218219062000D3A -:10399000AFA3001400481025A062000D8FA30014EF -:1039A0009062000D304200405040006A8FBF0020FE -:1039B0008F860028A380002C27A400148CC200D876 -:1039C0008C63000427A50010004310210E000A7923 -:1039D000ACC200D893A300108F8200280E0006BE50 -:1039E000A04300D10E000C00000000000A000EA34E -:1039F0008FBF00200E0006C700C020210E0006D594 -:103A0000000000003C0200080342802192230001D4 -:103A10009202007B1443004F8FBF002092220000CF -:103A20003044007F24020004108200172882000521 -:103A30001040000624020005240200031082000743 -:103A40008FB1001C0A000EA40000000010820012BA -:103A50008FBF00200A000EA48FB1001C92050083C6 -:103A6000920600788E0700748F84003430A500FF22 -:103A700000073E0230C600FF0E00070B30E7007F54 -:103A80000A000EA38FBF00200E000C6F8F8400343D -:103A90000A000EA38FBF002024020C80AF42002436 -:103AA0009202003E30420040104000200000000022 -:103AB0009202003E000216000002160304410006B6 -:103AC000000000008F8400340E00063824050093A7 -:103AD0000A000EA38FBF00209202003F24030018AB -:103AE000304200FF1443000C8F8400342405003959 -:103AF0000E0005D0000030210E0003028F84003438 -:103B000024020012A202003F0E00030B8F84003437 -:103B10000A000EA38FBF0020240500360E0005D03A -:103B2000000030210A000EA38FBF00200E00030208 -:103B30008F8400349202000534420020A202000566 -:103B40000E00030B8F8400340E0010588F84003455 -:103B50008FBF00208FB1001C8FB0001824020C8092 -:103B600027BD002803E00008AF42002427BDFFE87E -:103B7000AFB00010AFBF00142743010094620008EB -:103B8000000214000002140304410002000080211E -:103B90002410000194620008304200801040001A96 -:103BA00002001021946200083042200010400016EC -:103BB000020010218C6300183C021C2D344219EDC8 -:103BC000240600061062000F3C0760213C0208003A -:103BD0008C4200D4104000078F8200288F83002879 -:103BE000906200623042000F34420040A0620062E6 -:103BF0008F8200288F840034944500D40E000B89F6 -:103C000030A5FFFF020010218FBF00148FB00010FD -:103C100003E0000827BD001827BDFFE0AFB1001486 -:103C2000AFB00010A380002CAFBF00188F4501007B -:103C30003C0308008C6300E02402FF80AF85003461 -:103C400000A318213064007F03442021006218245F -:103C50003C02000A00822021AF43002427500100CB -:103C60008E0200148C8300DCAF84002800431023F4 -:103C700018400004000088218E0200140E000B1C66 -:103C8000AC8200DC9202000B24030002304200FFF1 -:103C90001443002F0000000096020008304300FF8C -:103CA0002402008214620005240200840E0009D65A -:103CB000000000000A000F2F00000000146200093D -:103CC000240200818F8200288F8400343C07602109 -:103CD000944500D49206000530A5FFFF0A000F1E90 -:103CE00030C600FF14620027000000009202000AA4 -:103CF000304300FF3062002010400004306200407A -:103D00008F8400340A000F1A24060040104000047B -:103D1000000316008F8400340A000F1A24060041A5 -:103D200000021603044100178F8400342406004269 -:103D30008F8200283C076019944500D430A5FFFF0E -:103D40000E000B89000000000A000F2F0000000089 -:103D50009202000B24030016304200FF10430006BD -:103D6000000000009202000B24030017304200FF05 -:103D700014430004000000000E000EA90000000023 -:103D8000004088210E000C00000000009202000A92 -:103D9000304200081040000624020C808F85002865 -:103DA0003C0400080E0012860344202124020C80EB -:103DB000AF4200248FBF0018022010218FB00010E6 -:103DC0008FB1001403E0000827BD002027BDFFE8E5 -:103DD000AFBF0014AFB000108F5000243C030800A8 -:103DE0008C6300E08F4501002402FF8000A31821AE -:103DF0003064007F03442021006218243C02000A42 -:103E000000822021AF850034AF43002490820062FD -:103E1000AF8400283042000F34420050A08200627C -:103E20003C02001F3442FF800E0006BE02028024C6 -:103E3000AF5000248FBF00148FB0001003E00008C3 -:103E400027BD00183C0208008C4200201040001DD5 -:103E50002745010090A300093C02000803422021ED -:103E600024020018546200033C0200080A000F708C -:103E700024020008034220212402001614620005D7 -:103E80002402001724020012A082003F0A000F7AC9 -:103E900094A700085462000694A7000893620005E6 -:103EA0002403FFFE00431024A362000594A700082A -:103EB00090A6001B8CA4000094A500060A000B64C9 -:103EC00000073C0003E00008000000002744010058 -:103ED00094820008304500FF38A3008238A2008495 -:103EE0002C6300012C4200010062182510600006BE -:103EF000240200839382002D1040000D000000007A -:103F00000A000C330000000014A2000524A2FF8068 -:103F10008F4301043C02602003E00008AC4300141E -:103F2000304200FF2C420002104000032402002215 -:103F30000A000ED40000000014A2000300000000DC -:103F40000A000F41000000000A000F5F000000009F -:103F50009363007E9362007A1443000900002021DD -:103F60009362000024030050304200FF1443000419 -:103F7000240400019362007E24420001A362007EBB -:103F800003E00008008010218F4201F80440FFFE8A -:103F900024020002AF4401C0A34201C43C0210004D -:103FA00003E00008AF4201F827BDFFE8AFBF0010F3 -:103FB0009362003F2403000A304200FF144300468E -:103FC000000000008F6300548F62004C1062007D7F -:103FD000036030219362000024030050304200FF50 -:103FE0001443002F000000008F4401403C020800F1 -:103FF0008C4200E02403FF80008210210043102443 -:10400000AF4200243C0208008C4200E08F6500545F -:104010003C03000A008220213084007F03441021E9 -:1040200000431021AC4501089762003C8F63004CAF -:104030003042FFFF0002104000621821AF63005CB5 -:104040008F6300548F64004C9762003C0064182317 -:104050003042FFFF00031843000210400043102AC3 -:1040600010400006000000008F6200548F63004C77 -:10407000004310230A000FF0000210439762003C37 -:104080003042FFFF00021040ACC200642402000175 -:10409000A0C0007CA0C2008424020C80AF42002497 -:1040A0000E000FA28F440140104000478FBF001048 -:1040B0008F4301408F4201F80440FFFE24020002BA -:1040C000AF4301C0A34201C43C021000AF4201F85B -:1040D0000A0010408FBF00109362003F24030010BD -:1040E000304200FF14430004000000008F440140F0 -:1040F0000A00102C000028219362003F24030016C0 -:10410000304200FF1443000424020014A362003F65 -:104110000A00103A000000008F62004C8F630050CC -:1041200000431023044100288FBF001093620081D8 -:1041300024420001A3620081936200812C420004AA -:1041400014400010000000009362003F24030004AC -:10415000304200FF14430006000000008F4401407D -:104160008FBF0010240500930A00063827BD0018F1 -:104170008F440140240500938FBF00100A0006A75A -:1041800027BD00188F4401400E000302000000000C -:104190008F6200542442FFFFAF6200548F620050D0 -:1041A0002442FFFFAF6200500E00030B8F4401401A -:1041B0008F4401408FBF0010240500040A00031043 -:1041C00027BD00188FBF001003E0000827BD0018AE -:1041D0008F4201889363007E00021402304400FF86 -:1041E000306300FF1464000D000000009362008043 -:1041F000304200FF1044000900000000A36400806A -:104200009362000024030050304200FF1443000476 -:10421000000000000A00076F8F440180A364008043 -:1042200003E000080000000027BDFFE8AFB0001069 -:10423000AFBF001493620005240300303042003009 -:1042400014430089008080213C0208008C42002039 -:1042500010400080020020210E00052B000000000D -:104260008F850020ACB000009362003E9363003F56 -:10427000304200FF00021200306300FF00431025AF -:10428000ACA2000493620082000216000002160332 -:1042900004410005000000003C0308008C63004856 -:1042A0000A00107E000000009362003E3042004091 -:1042B000144000030000182193620081304300FF86 -:1042C0009362008200031E00304200FF00021400CF -:1042D00000621825ACA300088F620040ACA2000C5D -:1042E0008F620048ACA200108F62004CACA2001498 -:1042F0008F6200508F63004C004310230441000381 -:10430000000000000A0010928F62004C8F62005083 -:10431000ACA200183C02080094424DBE3C03C00B06 -:1043200000002021004310250E000550ACA2001C07 -:104330008F6200548F840020AC8200008F6200588E -:10434000AC8200048F62005CAC8200088F62006067 -:104350008F43007400431021AC82000C8F62006414 -:10436000AC820010976300689762006A00031C002B -:104370003042FFFF00621825AC8300149362008274 -:1043800024030080304200FF1443000300000000BB -:104390000A0010C6AC8000188F63000C24020001D4 -:1043A0001062000E2402FFFF9362003E3042004084 -:1043B0001440000A2402FFFF8F63000C8F42007438 -:1043C000006218233C02080000621024144000021E -:1043D000000028210060282100051043AC8200184D -:1043E0003C02080094424DBE3C03C00C000020215A -:1043F000004310258F8300200E000550AC62001C86 -:104400008F6200188F8300203C05080094A54DBEE4 -:1044100024040001AC620000AC6000048F66006CF4 -:104420003C02400D00A22825AC6600088F6200DC2B -:10443000AC62000CAC600010936200050002160034 -:10444000AC620014AC6000180E000550AC65001C96 -:10445000020020218FBF00148FB00010A360000560 -:104460000A0004B927BD00188FBF00148FB00010D8 -:1044700003E0000827BD00189742007C30C600FF0B -:10448000A08600843047FFFF2402000514C2000B01 -:1044900024E3465090A201122C420007104000076E -:1044A00024E30A0090A30112240200140062100405 -:1044B00000E210210A0010FE3047FFFF3067FFFFC7 -:1044C00003E00008A4870014AC87004C8CA201080C -:1044D0000080402100A0482100E2102330C600FFE8 -:1044E0001840000393AA001324E2FFFCACA20108C9 -:1044F00030C2000110400008000000008D02005092 -:1045000000E2102304410013240600058D0200542C -:1045100010E20010000000008D02005414E2001AA6 -:10452000000000003C0208008C4200D8304200200D -:104530001040000A240200019103007891020083D8 -:10454000144300062402000101002021012028213B -:10455000240600040A0010EC00000000A100008402 -:1045600011400009A50200148F4301008F4201F899 -:104570000440FFFE24020002AF4301C0A34201C475 -:104580003C021000AF4201F803E000080000000008 -:1045900027BDFFE88FA90028AFBF00100080402191 -:1045A00000E918231860007330C600FFA080007C6B -:1045B000A08000818CA2010800E210230440004D7D -:1045C000000000008C8200509483003C8C840064C6 -:1045D000004748233063FFFF012318210083202B6D -:1045E00010800004000000008D0200640A00114FDA -:1045F00000E210219502003C3042FFFF0122102111 -:1046000000E21021AD02005C9502003C8D03005CCD -:104610003042FFFF0002104000E210210043102B47 -:1046200010400003000000000A00115E8D02005CD3 -:104630009502003C3042FFFF0002104000E21021D2 -:10464000AD02005CA1000084AD07004C8CA2010803 -:1046500000E210231840000224E2FFFCACA2010893 -:1046600030C200011040000A000000008D0200501E -:1046700000E2102304410004010020218D020054B7 -:1046800014E20003000000000A0011802406000567 -:104690008D02005414E200478FBF00103C02080056 -:1046A0008C4200D8304200201040000A2402000151 -:1046B0009103007891020083144300062402000154 -:1046C00001002021240600048FBF00100A0010EC16 -:1046D00027BD0018A1000084A50200148F4301002B -:1046E0008F4201F80440FFFE240200020A0011A5D7 -:1046F000000000008C82005C004910230043102B56 -:1047000054400001AC87005C9502003C3042FFFF42 -:104710000062102B14400007240200029502003CA6 -:104720008D03005C3042FFFF00621821AD03005C86 -:1047300024020002AD07004CA10200840E000FA26B -:104740008F4401001040001B8FBF00108F430100F9 -:104750008F4201F80440FFFE24020002AF4301C073 -:10476000A34201C43C021000AF4201F80A0011BB91 -:104770008FBF001030C200101040000E8FBF00101D -:104780008C83005C9482003C006918233042FFFF58 -:10479000006218213C023FFF3444FFFF0083102BCE -:1047A000544000010080182101231021AD02005C5B -:1047B0008FBF001003E0000827BD001827BDFFE8E9 -:1047C0008FAA0028AFBF00100080402100EA4823D4 -:1047D0001920002130C600FF8C83005C8C820064AD -:1047E000006A18230043102B504000100069182164 -:1047F00094A2011001221021A4A2011094A2011080 -:104800003042FFFF0043102B1440000A3C023FFFE0 -:1048100094A2011000431023A4A201109482003C32 -:104820003042FFFF0A0011DA00621821A4A0011033 -:104830003C023FFF3444FFFF0083102B5440000133 -:104840000080182100671021AD02005CA100007CEF -:104850000A001222A100008130C200101040003C6A -:10486000000000008C820050004A102318400038DD -:10487000000000009082007C24420001A082007CA5 -:104880009082007C3C0308008C630024304200FFCF -:104890000043102B1440005C8FBF00108CA2010855 -:1048A00000E2102318400058000000008C830054E0 -:1048B0009482003C006A18233042FFFF0003184333 -:1048C000000210400043102A1040000500000000C4 -:1048D0008C820054004A10230A001209000210437F -:1048E0009482003C3042FFFF00021040AD020064A1 -:1048F0009502003C8D0400649503003C3042FFFFAC -:1049000000021040008220213063FFFF0083182145 -:1049100001431021AD02005C8D020054ACA20108DD -:1049200024020002A10200840E000FA28F440100A5 -:10493000104000358FBF00108F4301008F4201F8F7 -:104940000440FFFE240200020A00124B0000000097 -:10495000AD07004C8CA2010800E2102318400002B1 -:1049600024E2FFFCACA2010830C200011040000AA2 -:10497000000000008D02005000E2102304410004FA -:10498000010020218D02005414E200030000000009 -:104990000A001242240600058D02005414E2001A97 -:1049A0008FBF00103C0208008C4200D8304200202B -:1049B0001040000A24020001910300789102008354 -:1049C00014430006240200010100202124060004F3 -:1049D0008FBF00100A0010EC27BD0018A100008452 -:1049E000A50200148F4301008F4201F80440FFFE2E -:1049F00024020002AF4301C0A34201C43C021000E4 -:104A0000AF4201F88FBF001003E0000827BD001877 -:104A10008FAA00108C8200500080402130C600FF19 -:104A2000004A102300A048211840000700E0182188 -:104A300024020001A0800084A0A00112A48200141E -:104A40000A0011BDAFAA0010A0800081AD07004C84 -:104A50008CA2010800E210231840000224E2FFFCAF -:104A6000ACA2010830C200011040000800000000A4 -:104A70008D0200500062102304410013240600053B -:104A80008D02005410620010000000008D020054DE -:104A900014620011000000003C0208008C4200D8A3 -:104AA000304200201040000A2402000191030078E7 -:104AB000910200831443000624020001010020211A -:104AC00001202821240600040A0010EC0000000048 -:104AD000A1000084A502001403E00008000000000B -:104AE00027BDFFE0AFBF0018274201009046000A33 -:104AF0008C4800148C8B004C9082008430C900FFDD -:104B000001681823304A00FF1C60001A2D46000679 -:104B1000240200010142100410C0001630430003BB -:104B2000012030210100382114600007304C000CB6 -:104B300015800009304200301440000B8FBF001870 -:104B40000A0012AC000000000E0011BDAFAB001057 -:104B50000A0012AC8FBF00180E001132AFAB00106C -:104B60000A0012AC8FBF0018AFAB00100E0012523B -:104B7000AFAA00148FBF001803E0000827BD002073 -:104B800024020003A08200848C82005403E0000809 -:104B9000ACA201083C020008034218219062008187 -:104BA000240600433C07601924420001A0620081F2 -:104BB000906300813C0208008C4200C0306300FF1B -:104BC000146200102403FF803C0208008C4200E0C5 -:104BD0000082102100431024AF4200243C02080050 -:104BE0008C4200E03C03000A008210213042007F2A -:104BF0000342102100431021944500D40A000B8980 -:104C000030A5FFFF03E000080000000027BDFFE023 -:104C1000AFBF0018AFB10014AFB000108F420180D9 -:104C20000080802100A088210E0012B300402021C6 -:104C3000A20000848E0200548FBF00188FB00010B5 -:104C4000AE2201088FB1001403E0000827BD002048 -:104C500027BDFFE03C020008AFB00010AFBF001856 -:104C6000AFB10014034280218F51014092030084B0 -:104C70008E0400508E02004C14820040306600FF0B -:104C80003C0208008C4200E02403FF800222102135 -:104C900000431024AF4200243C0208008C4200E094 -:104CA0009744007C92050081022210213042007F4F -:104CB000034218213C02000A0062182114A0000BD4 -:104CC0003084FFFF2402000554C20014248205DC56 -:104CD0009062011224420001A062011224020C80A1 -:104CE000AF4200240A00130B24020005A060011249 -:104CF0002402000514C20009248205DC920200810E -:104D00002C4200075040000524820A0092030081D3 -:104D10002402001400621004008210213044FFFFBE -:104D2000A60400140E0012B3022020219602003CBB -:104D30008E03004C022020213042FFFF0002104071 -:104D4000006218210E000302AE03005C9202007D97 -:104D500002202021344200400E00030BA202007DFD -:104D60008F4201F80440FFFE24020002AF5101C04F -:104D7000A34201C43C021000AF4201F88FBF0018EB -:104D80008FB100148FB0001003E0000827BD002091 -:104D900008000D9808000DE008000E2008000E6CB9 -:044DA00008000EA059 -:0C4DA4000A0000220000000000000000D7 -:104DB0000000000D6370352E302E306A3600000082 -:104DC00005000004000000000000000000000000DA -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000020A3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000191 -:104E20000000002B00000000000000000000000057 -:104E300010000003000000000000000D0000000D45 -:104E40003C02080024425AC43C03080024636190D9 -:104E5000AC4000000043202B1480FFFD24420004DE -:104E60003C1D080037BD7FFC03A0F0213C1008006A -:104E7000261000883C1C0800279C5AC40E0001A67E -:104E8000000000000000000D27BDFFE83C0960188D -:104E9000AFBF00108D2C5000240DFF7F240800317F -:104EA000018D5824356A380C24070C003C1A800008 -:104EB000AD2A50003C04800AAF4800083C1B800823 -:104EC000AF4700240E000935AF8400100E0008F82B -:104ED000000000000E000845000000000E0012DC7B -:104EE000000000003C0460168C8500003C06FFFFBB -:104EF0003C02535300A618241062004734867C00FD -:104F000094C201F2A780002C10400003A78000CCBF -:104F100038581E1EA798002C94C201F810400004B7 -:104F2000978300CC38591E1EA79900CC978300CCDC -:104F30002C7F006753E00001240300669784002C57 -:104F40002C82040114400002006028212404040083 -:104F50003C0760008CE904382403103C3128FFFF33 -:104F60001103001F30B9FFFF57200010A38000CEAF -:104F700024020050A38200CE939F00CE53E0000F86 -:104F8000A78500CCA78000CC978500CC8FBF0010F0 -:104F9000A780002CA7800034A78000E63C01080011 -:104FA000AC25008003E0000827BD0018939F00CEC9 -:104FB00057E0FFF5A78000CCA78500CC978500CCF3 -:104FC0008FBF0010A784002CA7800034A78000E6C4 -:104FD0003C010800AC25008003E0000827BD001854 -:104FE000A38000CE8CCB003C316A00011140000E42 -:104FF0000000000030A7FFFF10E0FFDE2402005099 -:105000008CCC00C83186000114C0FFDC939F00CE19 -:105010000A000074240200518C8F00043C0E6000D2 -:105020000A00005701EE30218CEF0808240D5708C4 -:10503000000F740211CD000430B8FFFF2405006694 -:105040000A000075240404001700FFCC939F00CED3 -:105050000A000074240200508F8600103089FFFF80 -:10506000000939408CC300103C08005000E820259E -:10507000AF4300388CC5001427420400AF82001CE7 -:10508000AF45003CAF4400300000000000000000CD -:105090000000000000000000000000000000000010 -:1050A00000000000000000008F4B0000316A00206B -:1050B0001140FFFD0000000003E0000800000000B8 -:1050C0008F840010948A001A8C8700243149FFFFD6 -:1050D000000940C000E83021AF46003C8C85002428 -:1050E0008F43003C00A3102318400029000000005B -:1050F0008C8B0020256200013C0D005035AC00086F -:10510000AF420038AF4C003000000000000000004B -:10511000000000000000000000000000000000008F -:1051200000000000000000008F4F000031EE002062 -:1051300011C0FFFD000000008F4A04003C08002061 -:10514000AC8A00108F490404AC890014AF480030C9 -:1051500000000000948600189487001C00C71821E6 -:10516000A48300189485001A24A20001A482001AC6 -:105170009498001A9499001E133800030000000050 -:1051800003E000080000000003E00008A480001A0B -:105190008C8200200A0000D63C0D00500A0000C797 -:1051A000000000003C0308008C6300208F82001880 -:1051B00027BDFFE810620008AFBF00100E0000FE20 -:1051C000AF8300183C0308008C6300202404000116 -:1051D000106400048F8900108FBF001003E00008E6 -:1051E00027BD00188FBF00103C076012A520000AE1 -:1051F0009528000A34E5001027BD00183106FFFF8E -:1052000003E00008ACA600903C0208008C4200209D -:1052100027BDFFC8AFBF0034AFBE0030AFB7002C12 -:10522000AFB60028AFB50024AFB40020AFB3001C68 -:10523000AFB20018AFB1001410400050AFB0001072 -:105240008F840010948600069483000A00C32823EC -:1052500030B6FFFF12C0004A8FBF00349489001897 -:10526000948A000A012A40233102FFFF02C2382B30 -:1052700014E0000202C02021004020212C8C0005F7 -:10528000158000020080A021241400040E0000AD4F -:10529000028020218F87001002809821AF800014A7 -:1052A00094ED000A028088211280004E31B2FFFF87 -:1052B0003C1770003C1540003C1E60008F8F001CA6 -:1052C0008DEE000001D718245075005002202021D7 -:1052D00002A3802B160000353C18200050780047B0 -:1052E00002202021241000018F8300141460003953 -:1052F000029158230230F8230250C82133F1FFFFF6 -:105300001620FFEE3332FFFF8F8700103C11002084 -:10531000AF5100300000000094E6000A3C1E60120D -:1053200037D5001002662821A4E5000A94E2000A9D -:1053300094F2000A94F400183057FFFF1292003BD9 -:10534000AEB700908CED00148CE400100013714097 -:1053500001AE4021000E5FC3010E502B008B48218F -:10536000012A1821ACE80014ACE3001002D3382362 -:1053700030F6FFFF16C0FFB98F8400108FBF0034D6 -:105380008FBE00308FB7002C8FB600288FB5002459 -:105390008FB400208FB3001C8FB200188FB100149F -:1053A0008FB0001003E0000827BD0038107E001BFE -:1053B000000000001477FFCC241000010E00162717 -:1053C000000000008F8300141060FFCB0230F82330 -:1053D000029158238F870010017020210A0001914B -:1053E0003093FFFF8F8300141460FFCB3C1100202B -:1053F000AF5100300A00015D000000000E00079E62 -:10540000024028210A000151004080210E00034B78 -:10541000024028210A000151004080210E0014EFB3 -:10542000022020210A000151004080210E0000C707 -:10543000000000000A00017302D3382327BDFFE8F3 -:10544000AFB00010AFBF00140E0000390000000024 -:105450003C028000345000700A0001B48E06000047 -:105460008F4F000039EE000131C2000110400024CE -:105470008F8600A88E0700003C0C08008D8C003C35 -:105480003C0908008D29003800E66823018D282199 -:105490000000502100AD302B012A402101062021BF -:1054A0003C010800AC25003CAF8700A83C01080087 -:1054B000AC2400380E000100000000003C0308008E -:1054C0008C6300701060FFE6006020213C0508003E -:1054D0008CA500683C0608008CC6006C0E0015B652 -:1054E000000000003C010800AC2000708F4F00005D -:1054F00039EE000131C200011440FFDE8F8600A8A2 -:105500008E0A00008F8B00A83C0508008CA5003C8B -:105510003C0408008C840038014B482300A9382142 -:105520000082182100E9402B006810213C0108008E -:10553000AC27003C3C010800AC2200388F5F010022 -:105540002419FF0024180C0003F9202410980012DD -:10555000AF840000AF440020936D0000240C0020B5 -:1055600031A600FF10CC0012240E005010CE000413 -:105570003C194000AF5901380A0001AD000000009D -:105580000E001252000000003C194000AF590138D3 -:105590000A0001AD000000000E000119000000002B -:1055A0003C194000AF5901380A0001AD000000006D -:1055B0008F58010000802821330F00FF01E02021D7 -:1055C0000E0002F8AF8F00043C194000AF590138BB -:1055D0000A0001AD0000000000A4102B240300010C -:1055E00010400009000030210005284000A4102BC5 -:1055F00004A00003000318405440FFFC00052840AD -:105600005060000A0004182B0085382B54E0000479 -:105610000003184200C330250085202300031842F0 -:105620001460FFF9000528420004182B03E000086D -:1056300000C310213084FFFF30A5FFFF8F4201B867 -:105640000440FFFE3C074080008730253C031000EB -:10565000AF400180AF450184AF46018803E00008F8 -:10566000AF4301B83084FFFF8F4201B80440FFFE12 -:105670003C0740388CA60000008728253C0310001A -:10568000AF460180AF45018803E00008AF4301B891 -:105690008F8300388F8600301066000B0080402119 -:1056A0003C07080024E75C38000328C000A710214D -:1056B0008C44000024630001108800053063000F53 -:1056C0005466FFFA000328C003E000080000102120 -:1056D0003C07080024E75C3C00A7302103E00008F9 -:1056E0008CC200003C03900034620001008220253F -:1056F000AF4400208F45002004A0FFFE0000000002 -:1057000003E00008000000003C0380003462000158 -:105710000082202503E00008AF44002027BDFFE001 -:10572000AFB100143091FFFFAFB00010AFBF001851 -:105730001220001500A080218CA5000010A00013ED -:10574000240400020E000C7C24060140AE00000080 -:105750008F4201B80440000D000028213C064000A3 -:10576000022620258FBF00188FB100148FB00010C3 -:105770003C03100027BD0020AF450180AF440188E5 -:1057800003E00008AF4301B88CA500008F4201B8C8 -:105790000440FFFE3C064000022620258FBF001873 -:1057A0008FB100148FB000103C03100027BD002003 -:1057B000AF450180AF44018803E00008AF4301B862 -:1057C0003086FFFF8F4201B80440FFFE3C094006CF -:1057D0008CA8000000C93825AF4801808CA40004C3 -:1057E0003C031000AF440184AF47018803E0000888 -:1057F000AF4301B827BDFFE0AFB00010AFBF001846 -:10580000AFB100149363003E008080210080282106 -:1058100030620040000020211040000F8E11000077 -:105820000E0008710220202193670000240400501C -:1058300030E500FF50A400128E0F0000022020214E -:105840008FBF00188FB100148FB00010A762013C09 -:105850000A00093127BD00200E0002870000000069 -:105860000E000871022020219367000024040050DC -:1058700030E500FF14A4FFF2022020218E0F00006B -:105880003C1008008E1000503C0D000C240BFF80D3 -:1058900001F05021314E007F01DA6021018D40215D -:1058A000014B4824AF490028022020218FBF001857 -:1058B0008FB100148FB00010A50200D627BD0020C4 -:1058C0000A000931AF8800D027BDFFE0AFBF001844 -:1058D000AFB10014AFB000109366000100808021CA -:1058E0000E00025030D1000493640005001029C25C -:1058F000A765000034830040A36300050E00025931 -:10590000020020210E0009330200202124020001A0 -:10591000AF62000C02002821A762001024040002DC -:10592000A762001224060140A76200140E000C7C3E -:10593000A76200161620000F8FBF0018978C003446 -:105940003C0B08008D6B00782588FFFF3109FFFFB5 -:10595000256A0001012A382B10E00006A7880034D0 -:105960003C0F6006240E001635ED0010ADAE005061 -:105970008FBF00188FB100148FB0001003E0000833 -:1059800027BD002027BDFFE0AFB10014AFBF001856 -:10599000AFB0001000A088211080000A3C03600016 -:1059A0002402008010820012000000000000000DA0 -:1059B0008FBF00188FB100148FB0001003E00008F3 -:1059C00027BD00208C682BF80500FFFE00000000BA -:1059D000AC712BC08FBF00188FB100148FB00010B6 -:1059E0003C09100027BD002003E00008AC692BF83B -:1059F0000E00025000A02021936500050220202106 -:105A00000E00025930B000FF2403003E1603FFE7EA -:105A1000000000008F4401780480FFFE2407000787 -:105A20003C061000AF51014002202021A347014451 -:105A30008FBF00188FB100148FB00010AF460178EF -:105A40000A0002C927BD002027BDFFE8AFBF001430 -:105A5000AFB000108F500020000000000E0009338E -:105A6000AF440020AF5000208FBF00148FB0001053 -:105A700003E0000827BD00183084FFFF8F4201B803 -:105A80000440FFFE3C074035008730253C031000F2 -:105A9000AF450180AF400184AF46018803E00008B4 -:105AA000AF4301B83084FFFF8F4201B80440FFFECE -:105AB0003C074036008730253C031000AF4501808D -:105AC000AF400184AF46018803E00008AF4301B84E -:105AD00027BDFFD0AFB3001C3093FFFFAFB500244C -:105AE000AFB20018AFBF0028AFB40020AFB10014B0 -:105AF000AFB0001030B5FFFF12600027000090210A -:105B00008F90001C8E0300003C06800024020040A1 -:105B100000033E0200032C0230E4007F006688246C -:105B20001482001D30A500FF8F8300282C68000A16 -:105B3000510000108F910014000358803C0C0800A5 -:105B4000258C58C4016C50218D49000001200008AB -:105B50000000000002B218213065FFFF0E00022491 -:105B600024040084162000028F90001CAF800028BF -:105B70008F910014260C0020264B0001018080210B -:105B80003172FFFF16200004AF8C001C0253282B3B -:105B900014A0FFDC00000000024010218FBF00288D -:105BA0008FB500248FB400208FB3001C8FB2001873 -:105BB0008FB100148FB0001003E0000827BD003043 -:105BC000240D003414AD00F600000000920B000E0E -:105BD000240A16803C07000CA36B00219203000DE1 -:105BE0000347F8213C066000A363002096110012D1 -:105BF0003C057FFF34ACFFFFA771003C960200100C -:105C0000240B00053054FFFFAF7400848E19001C74 -:105C1000AF4A00288FF800008CCF44480319702643 -:105C200001EE3021AF66004C8F69004C24CD00019D -:105C30003C197F00AF6900508F640050AF6400547E -:105C4000AF660070AF6D00588F6800582404005094 -:105C5000AF68005CA3600023AF6C0064A36B0037E7 -:105C60008E030014AF6300488F710048AF710024A9 -:105C70008E020018AF62006C9214000CA374003600 -:105C8000936A003E355F0020A37F003E8F7800744A -:105C90000319782435EE4000AF6E0074936900005C -:105CA000313000FF1204022C2418FF803C0408004D -:105CB00024845CB80E000294000000002406000456 -:105CC000240700013C0408008C845CB8A366007DB6 -:105CD000A36700058F4A01780540FFFE24020002F9 -:105CE000AF440140A34201448F90001C3C141000BB -:105CF000AF5401780A000373AF8000282CAD003741 -:105D000051A0FF9C8F9100140005A0803C18080052 -:105D1000271858EC029878218DEE000001C0000889 -:105D2000000000002406000614A600110000000078 -:105D30003C1F08008FFF5CB824040005AF5F002003 -:105D40008E190018AF7900188F78004CAF78001CBE -:105D50008F6F0050122000C2AF6F00700A000373F3 -:105D6000AF840028240A000710AA00842403000638 -:105D70003C05080024A55CB80E00025E24040081E6 -:105D80008F90001C0011102B0A000373AF820028B3 -:105D90002402000414A2FFF6240A00503C09080063 -:105DA0008D295CB8AF4900208E040008AF64004024 -:105DB0008E060008AF6600448E07000CAF670048EF -:105DC0008E0D0010AF6D004C8E080010AF6800847F -:105DD0008E050014AF6500508E0C0018AF6C005497 -:105DE0008E0B001CAF6B005893740000328300FFD1 -:105DF000106A01EE000000008F6700488F660040C7 -:105E000000E6682305A000042404008C1620FFDEB1 -:105E100024020003240400823C05080024A55CB889 -:105E20000E000287000000008F90001C000010216F -:105E30000A000373AF8200282404000514A4FFCCD9 -:105E4000240520003C1F08008FFF5CB8AF5F0020D6 -:105E50008E190004AF79005C921800082410000825 -:105E6000A37800218F8F001C91EE0009A36E002003 -:105E70008F86001C90C9000A312400FF109000108A -:105E8000288A00091540006C24020002240C00201E -:105E9000108C000B340580002885002114A0000818 -:105EA0002405400024080040108800053C0500013E -:105EB000240D0080108D00023C05000224054000E6 -:105EC0008F6E00743C0FFF0001CF48240125802510 -:105ED000AF70007490C4000BA36400818F84001C19 -:105EE0009487000C10E0019400000000948E000CD8 -:105EF000241FFFBF24060004A76E003C9089000EFB -:105F0000A369003E8F90001C9204000FA364003F21 -:105F10008F94001C8E8D00108F47007401A74023C2 -:105F2000AF6800608E850014AF650064968C001821 -:105F3000A76C0068968B001AA76B006A8E83001C02 -:105F4000AF63006C96820002A762013E928A000E47 -:105F5000A36A003E9379003E033FC02412200167EC -:105F6000A378003E8F90001C0A000373AF860028C0 -:105F70002414002214B4FF7E240300073C0208000E -:105F80008C425CB81220000CAF4200200A00037360 -:105F9000AF830028240C003310AC00142405002823 -:105FA0003C05080024A55CB80E00023024040081E2 -:105FB0000A0003F88F90001C3C04080024845CB89D -:105FC0000E00029400000000936B000024110050AA -:105FD000316300FF10710151000000008F90001C20 -:105FE000000018210A000373AF8300283C08080052 -:105FF0008D085CB824040081AF480020A3650034FC -:106000003C05080024A55CB80E000230000000002A -:106010008F90001C240200090A000373AF8200283D -:1060200002B288213225FFFF0E00022424040084DE -:106030000A0003738F90001C1082FFA12405040046 -:10604000288300031060016F240B00042414000156 -:106050005494FF9B240540000A00044724050100D6 -:106060003C04080024845CB88F62004C0E0002944B -:106070008F6300508F90001C000020210A000373E2 -:10608000AF8400288E1000042404008AAF50002042 -:10609000936E000531C900021520015E020028211F -:1060A0009378002302002821330F002015E00159C6 -:1060B0002404008D9362003F24190012305F00FF1A -:1060C00013F90154240400810E0002500200202123 -:1060D00093740023240A0004020020213683004226 -:1060E000A36300230E000259A36A007D8F4B017841 -:1060F0000560FFFE24050002AF500140A3450144A6 -:106100008F90001C3C0C1000AF4C01780A0003F982 -:106110000011102B8E1000042404008AAF500020C0 -:10612000936D000531A80002150000160200282119 -:106130009364003F2407000402002821308600FFFA -:1061400010C70010240400810E000250020020211C -:10615000937F002324180012240FFFFE37F900203C -:10616000A3790023A378003F936E0005020020214D -:1061700001CF48240E000259A3690005020028211E -:10618000000020210E000340000000000A0003F878 -:106190008F90001C8E0500043C0F0008034F402127 -:1061A000AF450020910E00002406005031C900FFC9 -:1061B00011260176240400888F5901B80720FFFEBC -:1061C0003C0C400E008C58253C031000AF4501806C -:1061D000AF400184AF4B0188AF4301B8910200008A -:1061E000240AFF8024040004004AF825A11F0000AF -:1061F0000E000C7C240600300A0003F88F90001C6F -:106200008E0F00043C14080026945CB83C01080082 -:10621000AC2F5CB8AF4F0020920E000331C90004D0 -:10622000112000022402001224020006A362003F93 -:106230009203001B240AFFC03062003F004AF82589 -:10624000A37F003E92190003333800011700011CA0 -:10625000000000008E020008AE8200083C02080028 -:106260008C425CC01040011B00000000000221C2F3 -:10627000A76400088E0D000C240B000124140014E8 -:10628000AF6D002C8E080010AF6800309605001628 -:10629000A7650038960C0014A76C003AAF6B000C91 -:1062A000A76B0010A76B0012A76B0014A76B00165A -:1062B00012200146A37400349206000330C7000286 -:1062C0002CF00001260200088F90001C0A000373C6 -:1062D000AF8200288E14000424030081AF540020F4 -:1062E000936800233105001010A001070000000092 -:1062F0008F4401B80480FFFE3C06401F0011382B7C -:10630000006610253C111000AF540180AF870028B3 -:10631000AF400184AF420188AF5101B80A00037455 -:106320008F9100148E0600043C19000803592021A7 -:10633000AF4600208E07000890980000240F005000 -:10634000331400FF128F0102240500888F4401B826 -:106350000480FFFE3C0D40090011602B00AD1025AC -:106360003C111000AF460180AF8C0028AF4701847C -:10637000AF420188AF5101B80A0003748F91001435 -:106380008E04001C0E00023B00000000104000E8DC -:10639000004048218F90001C240500898F4D01B8D2 -:1063A00005A0FFFE00000000AF4901808E0F001C19 -:1063B0003C1440010011702B00B448253C11100022 -:1063C000AF4F0184AF8E0028AF490188AF5101B8AB -:1063D0000A0003748F910014961900023C140800FF -:1063E00026945CB8333800041300008E3C02600031 -:1063F0008E1F001C3C010800AC3F5CB8AF5F002062 -:10640000920C0010240B0014318400FF148B00B890 -:106410000000000096090002312D000115A0014E78 -:10642000000000008E020004AE8200083C0E08004E -:106430008DCE5CC011C00144000000008F69007463 -:106440003C0E800024040001012E6825AF6D00740D -:10645000A3600005AF64000C3C0C08008D8C5CC090 -:106460008F88001CA7640010000C59C2A76400129A -:10647000A7640014A7640016A76B00088D0300082A -:1064800024040002AF63002C8D0A000CAF6A0030B8 -:1064900091070010A36700348F82001C9045001103 -:1064A000A36500358F86001C90D00012A3700036C3 -:1064B0008F9F001C93F90013A37900378F90001C65 -:1064C00096180014A778003896140016A774003A9E -:1064D0008E0F0018AF6F00245620FDA5AF84002852 -:1064E0003C05080024A55CB80E00025E00002021D7 -:1064F0008F90001C0A0004B6000020213C05080013 -:1065000024A55CB80E000287240400828F90001C32 -:10651000000030210A000373AF8600283C04080005 -:106520008C845CB80E001574000000008F90001C75 -:106530000A000490000018213C05080024A55CB85E -:106540000E0002872404008B8F90001C0011302B5A -:106550000A000373AF8600283C1908008F395CB825 -:106560003C1F08008FFF005024CCFFFE033F782122 -:1065700001F87024AF4E00283C0408008C845CB8FD -:106580003C0908008D2900500089682131A8007F4E -:10659000011A282100A78021AE0600D8AF9000D0B4 -:1065A000AE0000DC0A0003C2AE0C0108AF6000843C -:1065B0003C0508008CA55CB83C0808008D0800501C -:1065C000240CFF803C02000C00A8A021028C58245F -:1065D000AF4B00288E1F00143283007F007A5021B9 -:1065E00001427021ADDF00D88E190014AF8E00D0AB -:1065F000ADD900DC8E180010270FFFFE0A0004152D -:10660000ADCF0108548BFE2E240540000A0004473C -:10661000240510000E000335000000000A0003F8F6 -:106620008F90001C8C46442C3C056C6234B0797011 -:106630003C010800AC205CB814D00008240400021F -:1066400097880034978A002C02802821010A382B71 -:1066500010E0001124040092240400020E000C9AA1 -:10666000240501403C010800AC225CB8AF42002088 -:106670003C0308008C635CB81060000524040083B0 -:106680000E0008650000000010400009240400838B -:106690003C05080024A55CB80E00025E0000000066 -:1066A0008F90001C0011202B0A000373AF84002878 -:1066B0000E000869000000000A0005978F90001C7A -:1066C0008E0400080E00023B000000000A00052EA8 -:1066D000AE8200083C05080024A55CB80E0002301C -:1066E000240400878F90001C0A00054A0011102B1B -:1066F0000E00086D000000003C05080024A55CB8F1 -:106700000A00063D2404008B0E0002500280202166 -:106710009370002302802021360D00100E000259D4 -:10672000A36D00238F90001C0A0005530000182160 -:10673000240400040E000C9A240500301440002AA2 -:10674000004048218F90001C0A00057E240500832C -:106750009205000C30BF000113E0000300000000B0 -:106760009602000EA482002C920A000C314800020E -:106770001100FEF600002821960B00128E03001473 -:10678000A48B001A0A00056AAC83001C8F830038B2 -:106790008F8700301067FE88000020213C09080028 -:1067A00025295C3C000320C0008930218CD40000E6 -:1067B0001285005E247800013303000F5467FFFA4E -:1067C000000320C00A000505000020213C05080048 -:1067D00024A55CB80E000287240400828F90001C60 -:1067E0000A00054A000010213C0B0008034B202141 -:1067F00024030050240A0001AF420020A0830000BF -:10680000A08A00018F88001C91070004A08700184F -:106810008F82001C90450005A08500198F86001C02 -:1068200090DF0006A09F001A8F99001C9338000784 -:10683000A098001B8F94001C928F0008A08F001C52 -:106840008F90001C920E0009A08E001D8F8D001CE1 -:1068500091AC000AA08C001E8F8B001C3C0C080021 -:10686000258C5C3C9163000B3C0B0800256B5C386D -:10687000A083001F8F8A001C9148000CA088002074 -:106880008F87001C90E5000DA08500218F82001CE1 -:10689000240546469046000EA08600228F9F001CCD -:1068A00093F9000FA09900238F98001C93140010F7 -:1068B000A09400248F8F001C91F00011A09000255F -:1068C0008F90001C8F8E00308F990038960D001429 -:1068D000000E18C025C80001A48D0028960A0016D5 -:1068E000006C3021006BF821A48A002A960700185A -:1068F0003108000FA487002CA485002E8E02001CF6 -:10690000ACC90000AF88003011190003AFE20000ED -:106910000A00057E00002821250C00013184000FAB -:10692000000028210A00057EAF8400383C070800DB -:1069300024E75C380087802100002021ACC00000E3 -:106940000A000505AE0000003C05080024A55CB85F -:106950000A00063D240400878E0400040E00023B5A -:10696000000000000A0005A2AE8200083084FFFF8C -:1069700030C600FF8F4201B80440FFFE000644000D -:10698000010430253C07200000C720253C031000EF -:10699000AF400180AF450184AF44018803E00008A7 -:1069A000AF4301B827BDFFE8AFB00010AFBF001480 -:1069B0003C076000240600021080000600A0802131 -:1069C0000010102B8FBF00148FB0001003E00008E0 -:1069D00027BD00183C09600EAD2000348CE5201C5A -:1069E0008F82001C2408FFFC00A81824ACE3201CA4 -:1069F0000E0006F28C45000C0010102B8FBF001407 -:106A00008FB0001003E0000827BD00183C02600EA4 -:106A10003447010024090018274A04000000000040 -:106A200000000000000000003C06005034C30200DB -:106A3000AF440038AF45003CAF430030014018215F -:106A40008F4B0000316800201100FFFD2406007FFD -:106A50002408FFFF8C6C000024C6FFFF24630004A1 -:106A6000ACEC000014C8FFFB24E7000400000000A9 -:106A700000000000000000003C0F0020AF4F00307D -:106A80000000000024AD020001A5702B2529FFFFA6 -:106A9000008E20211520FFE101A0282103E000083D -:106AA0000000000027BDFFE0AFB10014AFBF001829 -:106AB000AFB000103C05600E8CA20034008088212D -:106AC000144000063C0460008C87201C2408FFFC56 -:106AD00000E8302434C30001AC83201C8F8B001CE1 -:106AE00024090001ACA90034956900028D650014E9 -:106AF0008D70000C2D2400818D6700048D660008C8 -:106B0000108000078D6A00102D2C00041580000EE7 -:106B100030CE0007312D000311A0000B0000000053 -:106B20002404008B020028210E0006F22406000334 -:106B30000011102B8FBF00188FB100148FB0001000 -:106B400003E0000827BD002015C0FFF62404008BD9 -:106B50003C030020AF43003000000000240200018D -:106B6000AF820014000000000000000000000000E0 -:106B70003C1F0150013FC825253800033C0F600E23 -:106B8000AF47003800181882AF46003C35E8003C9B -:106B9000AF590030274704008F44000030860020A2 -:106BA00010C0FFFD00000000106000082466FFFF19 -:106BB0002403FFFF8CEB000024C6FFFF24E7000442 -:106BC000AD0B000014C3FFFB250800043C08600E59 -:106BD000AD090038000000000000000000000000C7 -:106BE0003C070020AF470030000000000E00071AED -:106BF0000140202102002821000020210E0006F281 -:106C0000240600030011102B8FBF00188FB1001451 -:106C10008FB0001003E0000827BD002027BDFFD87B -:106C2000AFB200183092FFFFAFB10014AFBF002029 -:106C3000AFB3001CAFB000101240002C0000882140 -:106C40000A0007B22413000150B300408CE5000C89 -:106C50000000000D263900013331FFFF24F8002029 -:106C60000232382B10E00021AF98001C8F820014F4 -:106C70001440001E8F87001C3C0670003C0320005F -:106C80008CE400000086282414A300188F85003CA3 -:106C9000000444023C0980000089802414A0FFEA1B -:106CA000310600FF240A000210CA002E28CB000380 -:106CB00011600016240C000314D3FFE726390001ED -:106CC000020028210E000700240400018F87001C09 -:106CD000AF82003C263900013331FFFF24F8002049 -:106CE0000232382B14E0FFE1AF98001C0220102183 -:106CF0008FBF00208FB3001C8FB200188FB100141B -:106D00008FB0001003E0000827BD002810CC001A47 -:106D1000240D000414CDFFD026390001308EFFFF72 -:106D2000000E19C08F4401B80480FFFE3C0F100014 -:106D30003C102004AF430180AF400184AF50018874 -:106D4000AF4F01B80A0007AD263900010E0006F268 -:106D5000240400841600FFBF8F87001C0A0007ACC4 -:106D6000AF80003C020028210E0007000000202117 -:106D70000A0007CB8F87001C0E000740020020216D -:106D80008F87001C0A0007CCAF82003C3082FFFFD7 -:106D90001440000300001821000424022403001002 -:106DA000308500FF14A000053087000F246600081E -:106DB0000004220230C300FF3087000F14E00005FA -:106DC000308900032468000400042102310300FF1D -:106DD0003089000315200005388B0001246A000269 -:106DE00000042082314300FF388B00013164000130 -:106DF00010800002246C0001318300FF03E00008D2 -:106E000000601021308BFFFF000B394230E600FF9D -:106E10003C09080025295BB8000640800109602173 -:106E20008D8700003164001F240A0001008A1804C5 -:106E300030A500FF00E3202514A000020003102766 -:106E400000E22024240F000100CF70040109682112 -:106E5000000E282714800005ADA400008F86000CCA -:106E600000A6102403E00008AF82000C8F88000CFD -:106E700001C8102503E00008AF82000C3C06001F8B -:106E80003C0360003084FFFF34C5FF8024020020F3 -:106E9000AC602008AC60200CAC602010AC65201405 -:106EA000AC642018AC62200000000000000000006C -:106EB00003E000080000000027BDFFE82402FFFFF8 -:106EC000AFBF0010AF82000C000020213C0608007C -:106ED00024C65BB82405FFFF24890001000440801C -:106EE0003124FFFF010618212C87002014E0FFFA4F -:106EF000AC6500000E0008360000202124020001CD -:106F00003C04600024050020AC822018AC852000E1 -:106F1000000000000000000000000000244A000102 -:106F20003142FFFF2C46040014C0FFF78FBF001052 -:106F300003E0000827BD00188F8300082C620400BE -:106F400003E00008384200018F830008246200013A -:106F500003E00008AF8200088F8300082462FFFF6F -:106F600003E00008AF82000827BDFFE0AFB10014C6 -:106F7000AFBF0018AFB000108F6B00303C06600050 -:106F800000808821ACCB20088F6A002C3C02800056 -:106F900024030008ACCA200C9769003A97680038AF -:106FA00000092C003107FFFF00A72025ACC42010EA -:106FB000ACC22014ACC320000000000000000000A0 -:106FC000000000003C0360008C6D200031AC000824 -:106FD0001580FFF9000000008C6E201405C0002011 -:106FE000000000000E0007FA8F84000C00024080B1 -:106FF0003C09080025295BB8010938218CE4000010 -:107000000E0007FA00028140020220213090FFFFAB -:10701000020020210E000818000028213C0C8000EE -:10702000022C58253210FFFF3C116000240A00207A -:10703000AE2B2014AE302018AE2A20000000000035 -:107040000000000000000000020010218FBF0018A7 -:107050008FB100148FB0001003E0000827BD00209E -:107060008C6620143C02001F3443FF803C1FFFE865 -:1070700000C3C02437F9080003198021001079C229 -:107080003C0C8000022C582531F0FFFF3C116000C1 -:10709000240A0020AE2B2014AE302018AE2A200087 -:1070A00000000000000000000000000002001021AD -:1070B0008FBF00188FB100148FB0001003E00008DC -:1070C00027BD002027BDFFE8AFB000103402FFFF4E -:1070D0003090FFFFAFBF0014120200060200202113 -:1070E0000E00083600000000020020210E000818E3 -:1070F000240500018F8400088FBF00148FB000109A -:107100002483FFFF27BD001803E00008AF830008B9 -:10711000000439C230E6003F00043B42000718403B -:10712000240210002CC4002024C8FFE0AF42002C31 -:10713000246300011480000330A900FF00071840F9 -:10714000310600FF0003608024080001019A5821E5 -:107150003C0A000E00C82804016A382111200005ED -:10716000000530278CE900000125302503E00008E8 -:10717000ACE600008CEE000001C6682403E00008C5 -:10718000ACED000027BDFFE8AFBF0014AFB00010AA -:107190003C0460008C8508083403F00030A2F00045 -:1071A00050430006240200018C8708083404E000E4 -:1071B00030E6F00010C4001E24020002AF8200403E -:1071C0003C1060003C0A0200AE0A081424091000BA -:1071D0003C08000E8E03440003482021AF49002CD8 -:1071E000240501200E000CE0000030218F830040B8 -:1071F000106000043C021691240B0001106B000E7D -:107200003C023D6C344F0090AE0F44088FBF001419 -:107210008FB000103C0C6000240E10003C0D0200EA -:1072200027BD0018AD8E442003E00008AD8D081086 -:107230000A000907AF8000403C0218DA344F009082 -:10724000AE0F44088FBF00148FB000103C0C6000DC -:10725000240E10003C0D020027BD0018AD8E442006 -:1072600003E00008AD8D08100A0008DB24050001CA -:107270000A0008DB000028213C08080025085FC43C -:107280002404FFFF010018212402001E2442FFFFF6 -:10729000AC6400000441FFFD246300043C070800C7 -:1072A00024E760408CE5FFFC2404001C2406000158 -:1072B000308A001F01464804248400010009102779 -:1072C0002C8300201460FFFA00A22824ACE5FFFC08 -:1072D0003C05666634A4616E3C06080024C6610065 -:1072E000AF840058AF88009C2404FFFF00C0182121 -:1072F0002402001F2442FFFFAC6400000441FFFD94 -:10730000246300043C0766663C05080024A560C0B1 -:10731000AF86004834E6616EAF8600982404FFFF14 -:1073200000A018212402000F2442FFFFAC640000DB -:107330000441FFFD246300043C0B66663C06080024 -:1073400024C660403568616EAF8500A4AF880070C8 -:107350002404FFFF00C018212402001F2442FFFF65 -:10736000AC6400000441FFFD246300043C0D66662C -:107370003C0A0800254A618035AC616EAF860090FA -:10738000AF8C005C2404FFFF01401821240200039D -:107390002442FFFFAC6400000441FFFD24630004AD -:1073A0003C090800252961908D27FFFC2404000674 -:1073B000240500013099001F0325C0042484000126 -:1073C000001878272C8E002015C0FFFA00EF382413 -:1073D000AD27FFFC3C09666624030400240403DC9B -:1073E00024050200240600663522616E3C08080070 -:1073F00025085CC4AF820074AF830044AF83006C87 -:10740000AF830050AF830084AF8A008CAF840064E8 -:10741000AF85004CAF860054AF840078AF85006024 -:10742000AF86008001001821240200022442FFFFE1 -:10743000AC6000000441FFFD246300042404000349 -:107440002403000C3C0A0800254A5CD0AF8A00687F -:107450000A0009AE2405FFFF0004188024840001FF -:10746000006858212C8700C014E0FFFBAD650000C8 -:107470003C0E666635CD616E240C17A024081800FA -:10748000AF8D0088AF8C009403E00008AF88007CCB -:107490002484007F000421C200004021000030212C -:1074A00000003821000028210A0009C5AF8400A08F -:1074B0001060000624E7000100C4302124A500016B -:1074C0002CC20BF51440FFFA2CA300663C090800FF -:1074D0002529618001201821240200032442FFFF96 -:1074E000AC6000000441FFFD2463000410E0001ABA -:1074F00024E3FFFF0003294210A0000A000020211E -:107500002406FFFF3C0308002463618024840001FB -:107510000085502BAC660000250800011540FFFBDC -:107520002463000430E2001F104000080008688057 -:10753000240C0001004C38040008588001692821FF -:1075400024E6FFFF03E00008ACA6000001A94021EB -:107550002409FFFFAD09000003E00008000000005F -:10756000AF4400283C04000C03442021000528827D -:107570000A000CE000003021000421803C03600080 -:10758000AC6410080000000000052980AC65100CF8 -:107590000000000003E000088C62100C27BDFFE82B -:1075A0000080282124040038AFBF00140E0009F524 -:1075B000AFB0001024040E00AF4400283C10000CB3 -:1075C00003502021240500100E000CE000003021A3 -:1075D00003501021AC400000AC40000424040038EB -:1075E0008FBF00148FB0001024053FFF27BD001887 -:1075F0000A0009F58C430000000421803C03600070 -:10760000AC641008000000008C62100C03E000085D -:107610000002118227BDFFC8AFB400208F9400681C -:10762000AFBE0030AFB7002CAFB600280000B821C5 -:107630000080B021241E00C0AFBF0034AFB50024CD -:10764000AFB3001CAFB20018AFB10014AFB0001060 -:107650000A000A32AFA5003C504000018F94006838 -:1076600027DEFFFF13C00028269400048E9200003E -:107670003C03080024635FC01240FFF70283102B15 -:107680003C04080024845CC4028410230002A8C0C7 -:10769000000098210A000A412411000100118840CD -:1076A000122000260000000002B38021025128248D -:1076B0000200202110A0FFF9267300010E0009FE30 -:1076C000000000000016684032EC000101AC2021EF -:1076D0000E0009F5020028218F89009426F7000189 -:1076E0008FA6003C3AEB0001316A00012528FFFF1C -:1076F0000011382702CAB021AF88009416E6FFE7D0 -:1077000002479024AE92000002E010218FBF0034A7 -:107710008FBE00308FB7002C8FB600288FB50024A5 -:107720008FB400208FB3001C8FB200188FB10014EB -:107730008FB0001003E0000827BD00383C0E0800A1 -:1077400025CE5FC0028E102B0A000A2DAE920000DB -:1077500027BDFFD8AFB10014AFB00010AFBF0020FD -:10776000AFB3001CAFB2001800A0882110A0001F0A -:10777000000480403C13080026735CC40A000A7AA7 -:107780002412000112200019261000010E000A1513 -:1077900002002021000231422444FFA0000618808C -:1077A0003045001F2C8217A1007318212631FFFFDE -:1077B0001040FFF400B230048C6900000200202168 -:1077C00024053FFF012640241500FFEE0126382541 -:1077D0000E0009F5AC6700008F8A009426100001A6 -:1077E000254700011620FFE9AF8700948FBF0020D6 -:1077F0008FB3001C8FB200188FB100148FB000102F -:1078000003E0000827BD00288F85009C00805821D8 -:107810000000402100004821240A001F3C0C080001 -:10782000258C603C3C0D080025AD5FC48CA6000093 -:1078300050C000140000402100AD1023000238C0E9 -:10784000240300010A000AB30000202115000003F0 -:1078500000E41021244820240000482125290001AB -:10786000512B00132506DFDC106000062484000184 -:1078700000C3702415C0FFF5000318400A000AB1C8 -:107880000000402110AC002624A300040060282141 -:10789000254AFFFF1540FFE5AF85009C512B0004F2 -:1078A0002506DFDC0000402103E000080100102174 -:1078B0000006614230C5001F000C50803C070800E4 -:1078C00024E75FC424040001014730211120000F88 -:1078D00000A420043C05080024A560401480000595 -:1078E0002529FFFF24C6000410C500110000000078 -:1078F000240400018CCF00000004C02700042040B5 -:1079000001F868241520FFF5ACCD00008F990078B0 -:1079100001001021032B482303E00008AF89007801 -:107920003C05080024A55FC40A000ABB00004021F2 -:107930003C06080024C65FC40A000AD424040001DF -:10794000308800FF240200021102000A2403000311 -:107950001103005C8F8900A4240400041104005F5B -:1079600024050005110500670000182103E0000848 -:10797000006010218F8900483C0C0800258C6100B4 -:107980003C04080024846180240300201060000F60 -:1079900000005821240D0002240E00033C0F0800B3 -:1079A00025EF61008D27000014E0000B30F9FFFF88 -:1079B000252900040124C02B530000010180482127 -:1079C0002463FFFF5460FFF88D2700000160182139 -:1079D00003E0000800601021132000323C0500FF86 -:1079E00030E200FF004030211040004200005021F2 -:1079F00024050001000020210005C84000A6C02485 -:107A000017000003332500FF14A0FFFB24840001AE -:107A1000012CC023001828C000AA6021008C50212E -:107A20003144001F240C0001008C180400031027AF -:107A300000E23024110D0041AD260000110E004C73 -:107A4000000A1840110D00368F87006C510E005649 -:107A50008F8C0060240D0004110D005A8F8E00845D -:107A6000240E0005150EFFDA01601821240B1430D6 -:107A700011400006000018218F8400A0246300013B -:107A8000006A402B1500FFFD016458218F8A008099 -:107A9000AF89008C016018212549FFFF0A000B0BFC -:107AA000AF89008000E52024000736021080FFD057 -:107AB000240A001800075402314600FF0A000B1385 -:107AC000240A00103C0C0800258C60C03C0408000F -:107AD000248461000A000AFA240300103C0C080008 -:107AE000258C60403C040800248460C00A000AF928 -:107AF0008F89009000071A02306600FF0A000B13FE -:107B0000240A00088F89008C3C0C0800258C6180B9 -:107B10003C040800248461900A000AFA240300044B -:107B2000000A4080250B003024E6FFFF0160182189 -:107B3000AF8900480A000B0BAF86006C000AC982AF -:107B4000001978803C07080024E760C001E7202185 -:107B5000000A18428C8F00003079001F032C380473 -:107B60000007C02701F860240A000B28AC8C000035 -:107B7000000331420006288000AF28213062001F38 -:107B80008CB8000024630001004CC80400032142AB -:107B9000001938270004108003073024004F2021EB -:107BA0000A000B6CACA60000000A68C025AB0032CE -:107BB000258AFFFF01601821AF8900A40A000B0B82 -:107BC000AF8A0060254B1030AF890090016018210A -:107BD00025C9FFFF0A000B0BAF8900843086000720 -:107BE0002CC2000610400014000000000006408077 -:107BF0003C030800246359C8010338218CE40000C9 -:107C000000800008000000002409000310A9000EF5 -:107C100000000000240A000510AA000B000000006C -:107C2000240B000110AB0008000000008F8C00A0A6 -:107C300010AC00050000000003E000080000102167 -:107C40000A000A9900A020210A000AE700C02021AA -:107C500027BDFFE8308400FF240300021083000BDF -:107C6000AFBF0010240600031086003A2408000469 -:107C700010880068240E0005108E007F2CAF143091 -:107C80008FBF001003E0000827BD00182CA20030B1 -:107C90001440FFFC8FBF001024A5FFD0000531C2A7 -:107CA000000668803C07080024E7610001A7302136 -:107CB0008CC900000005288230AC001F240B000195 -:107CC000018B50048F840048012A4025ACC8000075 -:107CD0008C83000050600001AF8600488F98006CD4 -:107CE00030AE000124A6FFFF270F000115C00002DF -:107CF000AF8F006C24A600010006414200082080DE -:107D0000008718218C79000030C2001F2406000172 -:107D10000046F804033F382410E0FFDA8FBF00105C -:107D20000005C182001870803C0F080025EF60C07C -:107D300001CF48218D2B00000005684231A5001FAE -:107D400000A66004016C502527BD001803E0000860 -:107D5000AD2A00002CA7003014E0FFCA8FBF00102E -:107D600030B900071723FFC724A8FFCE00086A0216 -:107D7000000D60803C0B0800256B60C0018B30213A -:107D80008CC40000000828C230AA001F240800018B -:107D9000014848048F8200A400891825ACC3000064 -:107DA0008C5F000053E00001AF8600A40005704026 -:107DB000000E7942000F28803C04080024846100F2 -:107DC00000A418218C6B000025DF000131CD001FBD -:107DD000001F514201A86004016C4825000A108070 -:107DE000AC690000004428218CA600008F98006038 -:107DF00033F9001F8FBF00100328380400C778250F -:107E0000270E000127BD0018ACAF000003E00008FA -:107E1000AF8E006024A5EFD02CB804001300FF99AA -:107E20008FBF001000053142000658803C0A080050 -:107E3000254A6040016A30218CC4000030A3001F35 -:107E400024090001006910048F9900900082F82530 -:107E5000ACDF00008F27000050E00001AF860090EB -:107E60008F8D00848FBF001027BD001825AC000146 -:107E700003E00008AF8C008415E0FF828FBF001084 -:107E80008F8600A0000610400046F821001F210048 -:107E900003E4C8210019384024F8143000B8402BFE -:107EA0001100FF788FBF001024A4EBD00E00020D4C -:107EB00000C0282100027942000F70803C0D0800AC -:107EC00025AD618001CD20218C8B0000304C001F3E -:107ED00024060001018618048F89008C0163502557 -:107EE000AC8A00008D25000050A00001AF84008CFA -:107EF0008F9800808FBF001027BD00182708000151 -:107F000003E00008AF88008030A5000724030003C9 -:107F100010A3001028A20004144000082407000247 -:107F20002403000410A300152408000510A8000F66 -:107F30008F8500A003E000080000000014A7FFFDEB -:107F40000080282114C3FFFB240400020A000BABAD -:107F500000000000240900050080282110C9FFFB53 -:107F60002404000303E000080000000014C5FFF132 -:107F7000008028210A000BAB24040005240A00011C -:107F80000080282110CAFFF12404000403E0000847 -:107F90000000000027BDFFE0AFB00010000581C267 -:107FA0002603FFD024C5003F2C6223D024C6007FC7 -:107FB000AFB20018AFB10014AFBF001C309100FF8A -:107FC000000691C20005298202002021104000080D -:107FD0002403FFFF0E000A6B0000000002002021B6 -:107FE000022028210E000C590240302100001821E7 -:107FF0008FBF001C8FB200188FB100148FB000101B -:108000000060102103E0000827BD002027BDFFD835 -:1080100024A2007FAFB3001CAFB20018000299C2C7 -:10802000309200FF24A3003F02402021026028215B -:10803000AFB10014AFB00010AFBF00200E000B8E28 -:108040000003898200408021004020210220282155 -:1080500014400009000018218FBF00208FB3001CBE -:108060008FB200188FB100148FB000100060102183 -:1080700003E0000827BD00280E000A1C00000000D5 -:1080800000402821020020211051FFF3001019C0E8 -:108090000E000A6B0000000002002021024028218F -:1080A0000E000C59026030218FBF00208FB3001CDE -:1080B0008FB200188FB100148FB00010000018218B -:1080C0000060102103E0000827BD00283084FFFF76 -:1080D00030A5FFFF1080000700001821308200014A -:1080E0001040000200042042006518211480FFFBAC -:1080F0000005284003E000080060102110C00007C0 -:10810000000000008CA2000024C6FFFF24A500048C -:10811000AC82000014C0FFFB2484000403E00008CC -:108120000000000010A0000824A3FFFFAC860000A0 -:1081300000000000000000002402FFFF2463FFFF96 -:108140001462FFFA2484000403E000080000000029 -:1081500030A5FFFF8F4201B80440FFFE3C076015C9 -:1081600000A730253C031000AF440180AF400184DC -:10817000AF46018803E00008AF4301B88F8500D007 -:108180002C864000008018218CA700840087102BCB -:1081900014400010000000008CA800842D06400050 -:1081A00050C0000F240340008CAA0084008A482B92 -:1081B000512000018CA3008400035A42000B208050 -:1081C0003C05080024A55A400085182103E000085A -:1081D0008C62000014C0FFF4000000002403400083 -:1081E00000035A42000B20803C05080024A55A4099 -:1081F0000085182103E000088C6200008F8300D006 -:10820000906600D024C50001A06500D08F8500D005 -:10821000906400D090A200D210440017000000002B -:10822000936C00788F8B00BC318A00FFA16A000C30 -:1082300025490001938700C4312200FF3048007FA8 -:108240001107000B00026827A36200788F4E0178A7 -:1082500005C0FFFE8F9900B0241800023C0F1000EB -:10826000AF590140A358014403E00008AF4F017823 -:108270000A000D2931A20080A0A000D00A000D1F25 -:108280000000000027BDFFD8AFB200188F9200B8E1 -:10829000AFBF0020AFB3001CAFB00010AFB10014EF -:1082A0008F9300B48E5900283C1000803C0EFFEFE5 -:1082B000AE7900008E580024A260000A35CDFFFF81 -:1082C000AE7800049251002C3C0BFF9F356AFFFFF3 -:1082D000A271000C8E6F000C3C080040A271000BD4 -:1082E00001F06025018D4824012A382400E830255A -:1082F000AE66000C8E450004AE6000183C0400FF22 -:10830000AE6500148E43002C3482FFFFA660000887 -:108310000062F824AE7F00108E5900088F9000B0E4 -:10832000964E0012AE7900208E51000C31D83FFFDE -:1083300000187980AE7100248E4D001401F0602188 -:1083400031CB0001AE6D00288E4A0018000C41C2EE -:10835000000B4B80AE6A002C8E46001C01093821B0 -:10836000A667001CAE660030964500028E440020D1 -:10837000A665001EAE6400349243003330620004F0 -:1083800054400005924600008F8300D08C7F007C13 -:10839000AE7F0030924600008F8500BCA0A6000092 -:1083A000924400333082000250400007924E000198 -:1083B0008F8700BC240AFF8090E90000012A402535 -:1083C000A0E80000924E00018F8D00BC2409FFBF81 -:1083D0002404FFDFA1AE00018F8A00BC914C000D88 -:1083E000318B007FA14B000D8F8600BC90C8000D23 -:1083F00001093824A0C7000D8F9100BC8E650014C0 -:108400009223000D2CA200010002F9400064C82450 -:10841000033FC025A238000D8F8800BC9650001283 -:108420008F8700D0A51000028E45000490ED00BC9F -:1084300030AF0003000F702331CC000300AC1021DB -:1084400031AB0002156000022444003424440030A3 -:1084500090F100BC00B18024320F000415E000024E -:1084600024830004008018218F8900AC240A0002B4 -:10847000AD030004A12A00009248003F8F8700ACA2 -:10848000A0E800018F9100AC9246003F8E440004AA -:10849000A62600029765003C0E000CF630B0FFFFE8 -:1084A00000021380005020253C0342000083F82581 -:1084B000AE3F00048F8500AC8E590038ACB900186F -:1084C0008E580034ACB8001CACA0000CACA000105E -:1084D000A4A00014A4A00016A4A00020A4A0002220 -:1084E000ACA000248E620014504000012402000160 -:1084F0008FBF00208FB3001C8FB200188FB1001403 -:108500008FB00010ACA200080A000D1627BD00288D -:108510008F8600D027BDFFD0AFBF002CAFB600289C -:10852000AFB50024AFB40020AFB3001CAFB2001849 -:10853000AFB10014AFB0001094C300E094C200E2E9 -:10854000104300412405FFFF3C16000E90C400D0EC -:1085500090C800D1309200FF310400FF0244382B54 -:1085600010E0004426490001108900378F9800B0C0 -:108570003C0508008CA5005C2414FF8000B8602135 -:1085800001946824AF4D002C94CA00E2318B007F27 -:10859000017A482131447FFF013640210004104018 -:1085A0000048A82196A700003C1F08008FFF005834 -:1085B00030F53FFF0015198003E3C8210319882116 -:1085C0003233007F027A782102348024AF50002CAD -:1085D00001F69821926E000D31C5000410A00048EC -:1085E0000000000094C300E294C300E294D800E2CB -:1085F00024048000307F7FFF27F9000133317FFFA3 -:108600000304802402117825A4CF00E294CE00E276 -:108610003C1208008E52006031D47FFF129200DFBE -:10862000000000008E720018000028212646FFFF7F -:10863000AE66002C8F8600D094C800E094C900E29A -:108640001528FFC2000000008FBF002C8FB6002845 -:108650008FB500248FB400208FB3001C8FB2001898 -:108660008FB100148FB0001000A0102103E00008AB -:1086700027BD003090CD00D2264A000131AC00FF6A -:10868000008C5821116AFFF08F9800B03C0508005B -:108690008CA5005C2414FF8000B86021019468243C -:1086A000AF4D002C94CA00E2318B007F017A482143 -:1086B00031447FFF01364021000410400048A821CA -:1086C00096A700003C1F08008FFF005830F53FFFC1 -:1086D0000015198003E3C821031988213233007F74 -:1086E000027A782102348024AF50002C01F69821C0 -:1086F000926E000D31C5000414A0FFBA0000000006 -:108700008E6600100012C0C08E6E003000129140C4 -:1087100002587821036F582100CE6823256C008809 -:1087200024020002AE6D0010AF8C00ACA162008884 -:10873000976A003C8E6400308F9100AC0E000CF6FE -:108740003150FFFF00022380009048253C03420087 -:1087500001234025AE2800048E6700048F8C00ACF6 -:108760008E7F0000240D0008AD87001CAD9F00180F -:10877000AD80000CAD8000109265000A30B900FF9A -:10878000A5990014967800083C05000CA5980016E1 -:108790009271000A322F00FFA58F0020967000080A -:1087A00024110005A5900022AD800024926E000BDC -:1087B0002410C00031C600FFA5860002A18D000173 -:1087C0008E6B00308F8200AC8F8800B0AC4B0008FD -:1087D0003C0A08008D4A0054014820210094482496 -:1087E000AF4900283C0308008C630054006838211E -:1087F00030FF007F03FAC8210325C02102587821E9 -:10880000AF8F00BCAF9800C0A1F100008F8B00BCFF -:108810002403FFBF2405FFDF956E000201D0A024D2 -:1088200002959025A57200029166000230CD003FAE -:1088300035AC0040A16C00028F8800BC8F8200D054 -:108840003C0C7FFFAD0000048C4A007C358BFFFFA1 -:108850003C028000AD0A00089104000D3089007FC1 -:10886000A109000D8F9F00BC93F5000D02A33824D1 -:10887000A3E7000D8F9100BC9239000D0325C024A1 -:10888000A238000D8E6F00348F8D00BCADAF00108C -:108890008E6E002C8E70003001D0A023ADB4001479 -:1088A00091B200183246007FA1A600188F8700BC45 -:1088B0008E6A00308CE40018014B4824008240246A -:1088C0000109A825ACF500189263000AA0E3001C7A -:1088D000967F00088F8500BC8F9900D0A4BF001E32 -:1088E0008E7000308E6400300E00020D8F250084E3 -:1088F0008F8500D0000289400002C10090AE00BC0C -:10890000023878210040302131D400021280000367 -:10891000020F80210002A8800215802190B200BCC5 -:1089200032540004128000020006C880021980211F -:108930008E6F00308F8B00BC2406800031EE000368 -:10894000000E682331AC0003020C1021AD6200045C -:1089500094A400E294AA00E294A300E231507FFFC5 -:108960002604000130897FFF006640240109882524 -:10897000A4B100E294A700E23C1308008E730060EB -:1089800030FF7FFF13F30012000000000E000D16F1 -:10899000000000000A000E240000282194CD00E20F -:1089A00001A46024A4CC00E290CB00E290C200E2DB -:1089B000316A00FF000A49C200092027000441C0B3 -:1089C0003055007F02A838250A000E20A0C700E21B -:1089D00094B100E202263824A4A700E290BF00E28E -:1089E00090B400E233F300FF0013C9C200199027CE -:1089F0003298007F0012A9C0031530250E000D1615 -:108A0000A0A600E20A000E24000028213084FFFF07 -:108A100030A5FFFFAF440018AF45001C03E000087D -:108A20008F42001427BDFFB0AFB000288F9000D058 -:108A3000AFB40038AFBF004CAFBE0048AFB7004482 -:108A4000AFB60040AFB5003CAFB30034AFB20030BA -:108A5000AFB1002CA7A00014920600D1920500D05F -:108A60003094FFFF30C400FF30A300FF0064102BE0 -:108A7000A7A0001E10400071AFA00010920900D006 -:108A80000014982B312800FF0088382324F2FFFFC0 -:108A90000012882B0233782451E000758FB2001049 -:108AA00096180012961900100014F4000319B82348 -:108AB0000017B400001614030282A82A16A00002B0 -:108AC000001E2403004020210244F82B13E0000282 -:108AD00000801821024018210003340000061C0306 -:108AE0003065FFFF2CA200091440000200609821AD -:108AF000241300088E090008001359808E08000C0A -:108B00003164FFFF3C0A0010008A3825274A040020 -:108B1000AF490038AF8A00B8AF48003CAF470030DB -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40008F4D000031AC00201180FFFD0013702A12 -:108B500001D110240000A821104001C00000000035 -:108B60008F9800B03C0B08008D6B00542411FF80DF -:108B7000921E00D00178202100911024921900D07B -:108B8000AF4200288D4500103C0608008CC60058F6 -:108B90003C1708008EF7005430A73FFF00071980EC -:108BA00000C34021030820210091F824920B00D03B -:108BB000AF5F002C9148000033D600FF332F00FF39 -:108BC00002F8702100166140000F68C031C9007FB3 -:108BD000018D3821013A2821316300FF3086007F62 -:108BE0003C02000C00A2B021000389400367C821A9 -:108BF00000DAF8213108003F3C1E000E0236B82191 -:108C00002738008803FE88212D0F0008AF9800AC9C -:108C1000AF9700BCAF9600C011E0018FAF9100B4D8 -:108C2000000868803C0E080025CE59E001AE6021A6 -:108C30008D8900000120000800000000920E00D283 -:108C4000920D00D00014982B31CA00FF31AC00FF08 -:108C5000008C5823014B20212492FFFF0012882B07 -:108C60000233782415E0FF8E000000008FB2001060 -:108C70008FBF004C8FBE00483A4200018FB70044BE -:108C80008FB600408FB5003C8FB400388FB30034EE -:108C90008FB200308FB1002C8FB0002803E00008A5 -:108CA00027BD0050915800013317002012E0020444 -:108CB00024160001921F00BC0000B02133F900010E -:108CC0001320000D241E00018D4800148E03008423 -:108CD0000103B02B16C00002010030218E06008473 -:108CE0008E05006400C5382B14E0000200C020216E -:108CF0008E0400640080B0218D4200148E0B00644D -:108D0000004B302B14C00002004020218E04006470 -:108D10000096B82356E00001241E0002025E202BBC -:108D200014800148000018218D5900388E2F000C46 -:108D30003C180080AE3900008D5000343C0EFF9F7F -:108D400001F86025AE3000049149003F35CDFFFFAA -:108D5000018D20243C0A00203C0BFFEFA229000BD0 -:108D6000008A38253562FFFF00E228243C0600080F -:108D70008F8700B800A6C825AE39000C8CE300141C -:108D8000AE2000183C08FFFBAE2300148CF800183E -:108D9000351FFFFF033F7024AE38001C8CEF000826 -:108DA00002D78021AE2F00248CED000CAE30002CB9 -:108DB000AE2E000CAE2D0020AE200028A6200038DC -:108DC000A620003A8CEC001401964823013750236A -:108DD00011400011AE2A001090EE003D8E2C0004D0 -:108DE0008E240000000E6900018D28210000502112 -:108DF00000AD302B008A582101661021AE250004F9 -:108E0000AE22000090E3003DA223000A8F8800B844 -:108E1000951F0006A63F00088F8B00AC24060002B9 -:108E200002C02021A16600009765003C8F9000AC35 -:108E300030A2FFFF0E000CF6AFA200208FA300208F -:108E4000000243808F8500B80103C8253C1F420003 -:108E5000033FC025AE1800048F8400AC8CAF0038EF -:108E6000AC8F00188CB00034AC90001CAC80000CAF -:108E7000AC800010A4800014A4800016A480002000 -:108E8000A4800022AC80002490A7003FA4870002A9 -:108E900012C00210240D000152E0000290A2003D19 -:108EA00090A2003E244A0001A08A00018F8400ACF9 -:108EB000AC9600088F8300D024070034906F00BC6C -:108EC00031EE000251C00001240700308F8200B84B -:108ED0008F9900BC906800BC905F000024100004D3 -:108EE00032CF0003A33F00008F9800B88F8C00BCE6 -:108EF000020F7023930D00012405C00031CA000346 -:108F0000A18D00018F9000BC8F8900B800F6382138 -:108F1000960400029526001200EA382100855824A4 -:108F200030C33FFF01631025A6020002921F00021A -:108F30003108000433F9003F37380040A21800021E -:108F400012C000028F8500BC00E838218F8600D057 -:108F5000ACA70004241FFFBF8CC3007C2ECB0001F4 -:108F6000240FFFDFACA3000890A8000D000B6940A0 -:108F70003102007FA0A2000D8F9000BC9219000D5D -:108F8000033FC024A218000D8F8A00BC914E000D33 -:108F900001CF6024018D4825A149000D8F8600B8BE -:108FA0008F8B00BC8CC70020AD6700108CC50024DF -:108FB000AD6500148CC40028AD6400188CC3002C6F -:108FC0000E000D16AD63001C2408000257C8009C5B -:108FD0008F9000D08F8F00D08F8A00C002E02021B8 -:108FE00091E800D091EB00D091E700D0311000FF64 -:108FF000316E00FF00106940000E28C001A5182145 -:1090000030E900FF0363C8210009314000CAF8219C -:1090100027220088AF8200ACAF9F00BCA33E00882F -:109020000E000CF68F9000AC8FB800200002638019 -:109030003C0F4200019840258F8C00B8010F582545 -:10904000AE0B00048D8400388F8B00AC000028210B -:1090500000053900AD6400188D8E00343C0F7FFF91 -:1090600035E8FFFFAD6E001C9183003E8D69001C4A -:109070008D6600180003510000036F02012AC02111 -:1090800000ED1025030AF82B00C2C821033F802100 -:10909000AD78001CAD700018AD60000CAD60001024 -:1090A0009184003E241F00052410C000A564001414 -:1090B000958E000402E8402402E02021A56E0016EF -:1090C0009185003EA5650020958D0004A56D0022C8 -:1090D000AD6000249187003FA56700029183003EA8 -:1090E0009189003D0123502325460001A16600011E -:1090F0008F8200AC8F9900BCAC570008A33F0000E2 -:109100008F8A00BC8F9800B8954F0002970E00120E -:109110002418FFBF020F682431C53FFF01A5382581 -:10912000A5470002914C00022405FFDF3189003F72 -:1091300035230040A14300028F9900BC8F8600D0E8 -:109140002409FFFFAF2000048CCB007C2403FF80A8 -:10915000AF2B00089322000D3C0B8000305F007F96 -:10916000A33F000D8F8E00BC91D0000D0218782413 -:10917000A1CF000D8F8C00BC918D000D01A538246E -:10918000A187000D8F8600BCACC90010ACD60014BE -:1091900090CA00180143B025A0D600188F8F00BCDC -:1091A0008F9800B88DE20018004BF82403E8C8251A -:1091B000ADF900189310003EA1F0001C8F8E00B88E -:1091C0008F8D00BC8F8700D095C50004A5A5001E1B -:1091D0000E00020D8CE500848F8700D000026140F4 -:1091E0000002210090EA00BC0184482100402821AF -:1091F0003156000212C0000302E930210002B080A3 -:1092000000D6302190EC00BC3184000410800003B3 -:1092100032EA00030005C08000D830212409000490 -:109220008F9700BC012A1023305F000300DFC821A4 -:10923000AEF900040E000D16A62500388F9000D060 -:1092400003C01821146000020060B02100009021CA -:1092500056C000868F9700B80012882B9609001020 -:10926000029550233C14002002A91021A6020010F0 -:10927000AF5400303154FFFF00000000961300107F -:10928000961F001213F30011000000008E17000C4F -:109290008E0C00080015C98002F94021001927C36F -:1092A0000119B02B0184782101F65821AE08000C79 -:1092B000AE0B00080014A82B023580241200FE6BB0 -:1092C0008F9000D00A000F3F00000000960B0014A2 -:1092D0008E0500043163FFFF000370C000AE38212B -:1092E000AF47003C8E0600048F4D003C00CDF023BC -:1092F0001BC00036000000008E080000250200019F -:109300003C16001036CF0008AF420038AF4F003097 -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:109330008F440000308C00201180FFFD00000000F1 -:109340008F5904003C170020AE1900088F55040403 -:10935000AE15000CAF570030000000003C060800BE -:109360008CC600442418000110D800D3000000006F -:10937000960700123C0508008CA5004000A7682154 -:10938000A60D0012961E001427C90001A60900149C -:10939000960200143044FFFF5486FFC70014A82B28 -:1093A00030A5FFFF0E000F1AA60000143C030800B2 -:1093B0008C630024960500120043702300AE302316 -:1093C000A60600120A0011450014A82B8E02000008 -:1093D0000A0011583C16001091560001241000019B -:1093E0000016784215F0001C97A8001E8D5F00142F -:1093F0002411C00033FE3FFF0111C8243C180800AF -:109400008F180060033EB82532E53FFF00B8502BAF -:1094100011400011A7B7001E3C1008008E10005824 -:109420008F8F00B000057180240CFF80020F68212F -:1094300001AE48213124007F012C5824009A2821B4 -:109440003C02000EAF4B002C00A2302190C7000D53 -:1094500034E30004A0C3000D0E000D38000000002E -:109460008F9000D0240300018F9700B826B9000127 -:109470000019AC00024390230015AC0326F800400D -:1094800002B3202A0012882B240C00010300502173 -:1094900000911024AF9800B80A000F6DAFAC001017 -:1094A000955600128F8400B032C5FFFF0E000CEB02 -:1094B000A7B600148F9000D00A0011B10000182147 -:1094C0008D590038A620000824040003AE3900009E -:1094D0008D570034A220000A8F9800B8AE370004E0 -:1094E0003C0F0080930C003FA224000C8E28000C3F -:1094F0003C0BFF9FA22C000B010F1825356EFFFFC0 -:109500003C05FFEF8F9700B8006E682434A7FFFF7B -:1095100001A73024AE26000C8EFE001496FF001228 -:109520008F8200B0AE3E00108EF00014AE20001806 -:10953000AE200020AE300014AE2000248EE90018CA -:1095400033F03FFF00105180AE2900288EF900084B -:109550000142C02133EC0001AE3900308EEB000C2B -:109560008F8500AC001879C2000C238001E44021F3 -:10957000240E0002A628001CA6200036AE2B002CCC -:10958000A0AE00009767003C8F8A00AC3C0342000D -:1095900030EDFFFF01A33025AD4600048F9E00B8DB -:1095A000240200012408C0008FD1003824060034B2 -:1095B000AD5100188FC90034AD49001CAD40000CFE -:1095C000AD400010A5400014A5400016A5400020A5 -:1095D000A5400022AD400024A5560002A142000192 -:1095E0008F9F00AC8F9900B88F9800BCAFF6000831 -:1095F00093370000A31700008F8C00B88F8F00BC3A -:1096000091840001A1E400018F8D00BC95AB0002A4 -:109610000168702401D02825A5A5000291A70002A9 -:1096200030E3003FA1A300028F8300D08F8400BCF1 -:10963000907100BC323E000253C00001240600308D -:10964000AC8600048C6F007C2403FFBFAC8F000845 -:109650009088000D310B007FA08B000D8F8700BC20 -:1096600090EE000D01C32824A0E5000D8F9E00BCE4 -:1096700093CD000D35A60020A3C6000D8F8A00B83B -:109680008F9100BC8D500020AE3000108D49002419 -:10969000AE2900148D420028AE2200188D5F002CE8 -:1096A000AE3F001C0E000D16000000008F9000D091 -:1096B0000A00112B02C01821960A00123C1F080054 -:1096C0008FFF002403EA9821A61300120A00114517 -:1096D0000014A82BA08D00018F8900AC240C000180 -:1096E000AD2C00080A0010458F8300D027BDFFE095 -:1096F0003C1808008F180050AFB00010AFBF001822 -:10970000AFB10014AF8400B09371007403047821EA -:109710002410FF8031EE007F3225007F01F05824B5 -:1097200001DA68213C0C000AA38500C401AC2821A1 -:10973000AF4B002494A900109768000690A6006221 -:1097400000803821240200300109202330C300F0BA -:10975000AF8500D0106200193090FFFF90AE00621C -:10976000240DFFF0240A005001AE6024318B00FF6D -:10977000116A002F0000000016000007241F0C00D3 -:10978000AF5F00248FB100148FBF00188FB000109E -:1097900003E0000827BD00200E000F20020020215A -:1097A000241F0C00AF5F00248FB100148FBF00187E -:1097B0008FB0001003E0000827BD002094A200E055 -:1097C00094A400E290BF0113008218263079FFFFB5 -:1097D00033E700C014E000092F3100011600003803 -:1097E000000000005620FFE6241F0C000E000DDBD9 -:1097F000000000000A001277241F0C001620FFDE74 -:10980000000000000E000DDB000000001440FFDC33 -:10981000241F0C00160000228F8300D090690113D2 -:109820003122003FA06201130A001277241F0C00AE -:1098300094AF00D48F8600D400E0282124040005D2 -:109840000E000C7C31F0FFFF1440000524030003E0 -:10985000979100E6000018212625FFFFA78500E666 -:109860008F5801B80700FFFE3C196013AF4001801C -:10987000241F0C00AF500184007938253C101000E3 -:10988000AF4701888FB10014AF5001B8AF5F00241B -:109890008FB000108FBF001803E0000827BD002024 -:1098A0000E000F20020020215040FFB5241F0C00A5 -:1098B0008F8300D0906901130A0012A03122003F6B -:1098C0000E000F20020020211440FFAD241F0C00C9 -:1098D000122000078F8300D0906801133106003FEB -:1098E00034C20040A06201130A001277241F0C004A -:1098F0000E000DDB000000005040FFA1241F0C00F3 -:109900008F8300D0906801133106003F0A0012D007 -:1099100034C20040AF9B00C803E00008AF8000ECF9 -:109920003089FFFF000940422D02004100092980D3 -:10993000144000020009504024080040000879400B -:109940000008C0C001F85821256701A800EF702168 -:1099500025CC007F240DFF80018D18240065302167 -:1099600000CA282125640088240A00883C010800D8 -:10997000AC2A004C3C010800AC240050AF8500D458 -:109980003C010800AC2900603C010800AC280064E0 -:109990003C010800AC2700543C010800AC230058EF -:1099A0003C010800AC26005C03E000080000000059 -:1099B000308300FF30C6FFFF30E400FF8F4201B864 -:1099C0000440FFFE00034C00012438253C086000E1 -:1099D00000E820253C031000AF450180AF4601841C -:1099E000AF44018803E00008AF4301B88F86001C34 -:1099F0003C096012352700108CCB00043C0C600E33 -:109A000035850010316A00062D480001ACE800C41D -:109A10008CC40004ACA431808CC2000894C3000242 -:109A2000ACA2318403E00008A78300E43C030800F3 -:109A30008C6300508F8400E88F86001C2402FF8016 -:109A40000064C0210302C824AF5900288CCD000453 -:109A50003305007F00BA78213C0E000C01EE28216E -:109A6000ACAD00588CC80008AF8500D03C07601230 -:109A7000ACA8005C8CCC001034E80010ACAC000C3E -:109A80008CCB000CACAB000894AA00143C0208007C -:109A90008C42004425490001A4A9001494A4001498 -:109AA0003083FFFF106200178F8400D03C0A08004B -:109AB0008D4A0040A4AA00128CCE0018AC8E00245F -:109AC0008CCD0014AC8D00208CC70018AC87002C06 -:109AD0008CCC001424060001AC8C00288D0B00BC3B -:109AE0005166001A8D0200B48D0200B8A482003ABB -:109AF000948F003AA48F003C948800D403E00008BF -:109B00003102FFFF3C0908008D290024A4A00014A5 -:109B10008F8400D0A4A900128CCE0018AC8E002433 -:109B20008CCD0014AC8D00208CC70018AC87002CA5 -:109B30008CCC001424060001AC8C00288D0B00BCDA -:109B40005566FFEA8D0200B88D0200B4A482003A87 -:109B5000948F003AA48F003C948800D403E000085E -:109B60003102FFFF8F86001C3C0C08008D8C0050DA -:109B7000240BFF808CCD00083C03000C000D51C06D -:109B8000018A4021010B4824AF8A00E8AF49002830 -:109B900090C700073105007F00BA1021004328213B -:109BA00030E400041080002FAF8500D090CF000774 -:109BB00031EE000811C0003C000000008CD9000C00 -:109BC0008CC400140324C02B1300002600000000E6 -:109BD0008CC2000CACA200648CCD00182402FFF8EB -:109BE000ACAD00688CCC0010ACAC00808CCB000C11 -:109BF000ACAB00848CCA001CACAA007C90A900BC51 -:109C000001224024A0A800BC90C3000730670008D0 -:109C100010E000048F8500D090AF00BC35EE00014D -:109C2000A0AE00BC90D90007333800011300000F2C -:109C30008F8400D024070020908200BC34490002A9 -:109C4000A08900BC8F8400D090880062310300F0AE -:109C500014670006240A0034AC8A00C00A0013B25C -:109C6000000000000A00138C8CC2001490CB000787 -:109C70003166000210C0000500000000908D00BC9D -:109C800035AC0004A08C00BC8F8400D090980113E8 -:109C9000330F003FA08F01138F8E00D095C500D4E5 -:109CA00003E0000830A2FFFFACA000640A00138D9F -:109CB0000000000027BDFFD8AFB000108F90001C3F -:109CC000AFBF0024AFB40020AFB20018AFB1001492 -:109CD000AFB3001C9613000E3C07600A3C146006EC -:109CE0003264FFFF369300100E0012DF34F40410CC -:109CF0008F8400D43C11600E0E0009BB3631001079 -:109D0000920E00153C0708008CE700603C126012C0 -:109D100031CD000FA38D00F08E0E00048E0D0008D3 -:109D200096080012961F00109619001A9618001E29 -:109D3000960F001C310CFFFF33EBFFFF332AFFFFB0 -:109D40003309FFFF31E6FFFF3C010800AC2B004068 -:109D50003C010800AC2C00243C010800AC2A004463 -:109D6000AE293178AE26317C92020015960300169A -:109D700036520010304400FF3065FFFF3C060800FB -:109D80008CC60064AE243188AE4500B4920800143D -:109D900096190018241F0001011FC004332FFFFF74 -:109DA0003C0508008CA50058AE5800B8AE4F00BC6A -:109DB000920C0014AF8E00D8AF8D00DC318B00FF09 -:109DC000AE4B00C0920A0015AE670048AE66004C6C -:109DD000314900FFAE4900C8AE65007C3C03080075 -:109DE0008C6300503C0408008C84004C3C08080044 -:109DF0008D0800543C0208008C42005C8FBF002498 -:109E0000AE6300808FB00010AE8300748FB3001C6F -:109E1000AE22319CAE4200DCAE2731A0AE2631A48A -:109E2000AE24318CAE233190AE283194AE253198DA -:109E3000AE870050AE860054AE8500708FB100141E -:109E4000AE4700E0AE4600E4AE4400CCAE4300D0E6 -:109E5000AE4800D4AE4500D88FB400208FB20018B1 -:109E600003E0000827BD002827BDFFE0AFB10014C4 -:109E7000AFBF0018241100010E000865AFB000103C -:109E800010510005978400E6978300CC0083102BC7 -:109E9000144000088F8500D4240700028FBF0018EB -:109EA0008FB100148FB0001000E0102103E0000813 -:109EB00027BD00200E000C9A24040005AF8200E8A4 -:109EC0001040FFF6240700020E0008698F90001C66 -:109ED000979F00E68F9900E88F8D00C827EF00015B -:109EE000240E0050AF590020A78F00E6A1AE00005D -:109EF0003C0C08008D8C00648F8600C8240A80000A -:109F0000000C5E00ACCB0074A4C0000694C9000A2B -:109F1000241FFF803C0D000C012AC024A4D8000A95 -:109F200090C8000A24182000011F1825A0C3000AA9 -:109F30008F8700C8A0E000788F8500C80000382116 -:109F4000A0A000833C0208008C4200508F8400E8EF -:109F50000044782101FFC824AF590028960B000265 -:109F600031EE007F01DA6021018D3021A4CB00D4D5 -:109F7000960A0002AF8600D03C0E00042549240159 -:109F8000A4C900E68E080004ACC800048E030008D3 -:109F9000ACC30000A4C00010A4C00014A0C000D036 -:109FA0008F8500D02403FFBFA0A000D13C0408008F -:109FB0008C8400648F8200D0A04400D28E1F000CDD -:109FC0008F8A00D0978F00E4AD5F001C8E190010BF -:109FD00024100030AD590018A5400030A5510054A0 -:109FE000A5510056A54F0016AD4E0068AD58008033 -:109FF000AD580084914D006231AC000F358B0010DC -:10A00000A14B00628F8600D090C900633128007F89 -:10A01000A0C800638F8400D02406FFFF90850063F2 -:10A0200000A31024A08200638F9100D000E01021D3 -:10A03000923F00BC37F90001A23900BC8F8A00D0E2 -:10A04000938F00F0AD580064AD5000C0914E00D326 -:10A05000000F690031CC000F018D5825A14B00D3B2 -:10A060008F8500D08F8900DCACA900E88F8800D8EC -:10A070008FBF00188FB100148FB0001027BD0020D3 -:10A08000ACA800ECA4A600D6A4A000E0A4A000E226 -:10A0900003E000080000000027BDFFE0AFB00010A3 -:10A0A0008F90001CAFB10014AFBF00188E190004D0 -:10A0B0003C1808008F180050240FFF80001989C039 -:10A0C0000238702131CD007F01CF602401BA5021C8 -:10A0D0003C0B000CAF4C0028014B4021950900D4EB -:10A0E000950400D68E0700043131FFFFAF8800D001 -:10A0F0000E000933000721C08E0600048F8300C8BC -:10A10000000629C0AF4500209064003E3082004028 -:10A11000144000068F8400D0341FFFFF948300D6C4 -:10A120003062FFFF145F000400000000948400D63A -:10A130000E0008C83084FFFF8E0500040220302185 -:10A140008FBF00188FB100148FB0001024040022BC -:10A1500000003821000529C00A00130327BD002094 -:10A1600027BDFFE0AFB100143091FFFFAFB000108A -:10A17000AFBF00181220001D000080218F86001C38 -:10A180008CC500002403000600053F0200051402F0 -:10A1900030E4000714830015304500FF2CA80006AA -:10A1A0001100004D000558803C0C0800258C5A0019 -:10A1B000016C50218D4900000120000800000000C2 -:10A1C0008F8E00EC240D000111CD0059000000001D -:10A1D000260B00013170FFFF24CA00200211202B42 -:10A1E000014030211480FFE6AF8A001C02001021DC -:10A1F0008FBF00188FB100148FB0001003E000086B -:10A2000027BD0020938700CE14E0003824040014FA -:10A210000E0013C4000000008F86001C2402000101 -:10A220000A00150BAF8200EC8F8900EC24080002B5 -:10A230001128003B240400130000282100003021D5 -:10A24000240700010E001303000000000A00150B94 -:10A250008F86001C8F8700EC2405000214E5FFF6B2 -:10A26000240400120E001370000000008F8500E827 -:10A2700000403021240400120E0013030000382196 -:10A280000A00150B8F86001C8F8300EC241F00032F -:10A29000147FFFD0260B00010E00132200000000E7 -:10A2A0008F8500E8004030212402000224040010C1 -:10A2B00000003821AF8200EC0E0013030000000004 -:10A2C0000A00150B8F86001C8F8F00EC24060002FD -:10A2D00011E6000B000000002404001000002821FB -:10A2E000000030210A001528240700010000282161 -:10A2F0000E001303000030210A00150B8F86001C8E -:10A300000E00143100000000144000128F99001C50 -:10A310008F86001C240200030A00150BAF8200EC9C -:10A320000E0014BD000000000A00150B8F86001CF3 -:10A330000E00131200000000240200022404001486 -:10A340000000282100003021000038210A001545B6 -:10A35000AF8200EC0040382124040010973800023E -:10A36000000028210E0013033306FFFF0A00150B1F -:10A370008F86001C8F8400C83C077FFF34E6FFFFF8 -:10A380008C8500742402000100A61824AC8300749C -:10A3900003E00008A082000510A000362CA2008077 -:10A3A000274A04003C0B00052409008010400007E8 -:10A3B0002408008030A6000F00C540212D03008135 -:10A3C0001460000200A0482124080080AF4B003038 -:10A3D0000000000000000000000000001100000963 -:10A3E00000003821014030218C8D000024E700045A -:10A3F00000E8602BACCD0000248400041580FFFA37 -:10A4000024C600040000000000000000000000005E -:10A410003C0E0006010E3825AF470030000000005A -:10A4200000000000000000008F4F000031E8001025 -:10A430001100FFFD000000008F42003C8F43003CF4 -:10A440000049C8210323C02B1300000400000000B2 -:10A450008F4C003825860001AF4600388F47003CFE -:10A4600000A9282300E96821AF4D003C14A0FFCECD -:10A470002CA2008003E000080000000027BDFFD0F0 -:10A480003C020002AFB100143C11000CAF45003893 -:10A49000AFB3001CAF46003C00809821AF420030B3 -:10A4A00024050088AF44002803512021AFBF0028B5 -:10A4B000AFB50024AFB40020AFB200180E00157D78 -:10A4C000AFB000103C1F08008FFF004C3C18080084 -:10A4D0008F1800642410FF8003F3A82132B9007F95 -:10A4E00002B078240018A0C0033A702100189140EF -:10A4F00001D12021AF4F00280E00157D02542821E4 -:10A500003C0D08008DAD00502405012001B35821F9 -:10A51000316C007F01705024019A482101312021C3 -:10A520000E00157DAF4A00283C0808008D08005435 -:10A530003C0508008CA500640113382130E6007F3B -:10A5400000F0182400DA202100912021AF430028D8 -:10A550000E00157D000529403C0208008C42005881 -:10A560003C1008008E1000601200001C005388216F -:10A570002415FF800A0016003C14000C3226007FD0 -:10A580000235182400DA202102402821AF43002898 -:10A59000009420210E00157D2610FFC01200000F30 -:10A5A000023288212E05004110A0FFF42412100071 -:10A5B0003226007F001091800235182400DA202115 -:10A5C00002402821AF430028009420210E00157D71 -:10A5D000000080211600FFF3023288213C0B0800A6 -:10A5E0008D6B005C240AFF8024050002017340216A -:10A5F000010A4824AF4900283C0408009484006202 -:10A600003110007F021A88213C07000C0E000CCA92 -:10A610000227982100402821026020218FBF0028B6 -:10A620008FB500248FB400208FB3001C8FB20018A8 -:10A630008FB100148FB000100A00157D27BD0030C7 -:10A640008F83001C8C620004104000030000000097 -:10A6500003E00008000000008C6400108C65000816 -:08A660000A0015B68C66000C1F -:08A66800000000000000001BCF -:10A670000000000F0000000A0000000800000006B3 -:10A6800000000005000000050000000400000004B8 -:10A6900000000003000000030000000300000003AE -:10A6A00000000003000000020000000200000002A1 -:10A6B0000000000200000002000000020000000292 -:10A6C0000000000200000002000000020000000282 -:10A6D0000000000200000002000000020000000272 -:0CA6E0000000000100000001000000016B -:04A6EC0008000F58FB -:10A6F00008000DB008000FEC0800109408000F804F -:10A7000008000FC0080011CC08000DCC080011F0A3 -:10A7100008000E1C08001634080015DC08000DCCDB -:10A7200008000DCC08000DCC0800127C0800127C3B -:10A7300008000DCC08000DCC0800158008000DCCD9 -:10A7400008000DCC08000DCC08000DCC080013F05B -:10A7500008000DCC08000DCC08000DCC08000DCC75 -:10A7600008000DCC08000DCC08000DCC08000DCC65 -:10A7700008000DCC08000DCC08000DCC08000DCC55 -:10A7800008000DCC08000DCC08000FE008000DCC2F -:10A7900008000DCC0800153008000DCC08000DCCC9 -:10A7A00008000DCC08000DCC08000DCC08000DCC25 -:10A7B00008000DCC08000DCC08000DCC08000DCC15 -:10A7C00008000DCC08000DCC08000DCC08000DCC05 -:10A7D00008000DCC08000DCC08000DCC0800145C5E -:10A7E00008000DCC08000DCC08001370080012E022 -:10A7F00008002E9408002E9C08002E6408002E707D -:10A8000008002E7C08002E88080046B408003F008F -:10A8100008004634080046B4080046B4080044B4B2 -:10A82000080046B4080046FC08005524080054E41B -:10A83000080054B008005484080054600800541CF8 -:10A840000A000C7600000000000000000000000D6F -:10A85000727870352E302E306A3600000500000305 -:10A8600000000000000000010000000000000000E7 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA100000000000000000000000000010000003F3 -:10DA2000000000000000000D0000000D3C02080096 -:10DA3000244275803C03080024637A28AC4000002F -:10DA40000043202B1480FFFD244200043C1D0800ED -:10DA500037BD7FFC03A0F0213C100800261031D810 -:10DA60003C1C0800279C75800E0010EF0000000091 -:10DA70000000000D30A5FFFF30C600FF27430180E6 -:10DA80008F4201B80440FFFE24020002AC64000093 -:10DA9000A4650008A066000AA062000B3C0210000A -:10DAA000AC67001803E00008AF4201B83C03600017 -:10DAB0008C624FF80440FFFE3C020200AC644FC091 -:10DAC000AC624FC43C02100003E00008AC624FF8A7 -:10DAD0009482000C2486001400A038210002130256 -:10DAE000000210800082402100C8102B1040005717 -:10DAF0000000000090C300002C620009504000515B -:10DB000090C20001000310803C03080024637534B8 -:10DB1000004310218C42000000400008000000007B -:10DB200090C300012402000A1462003A00000000C1 -:10DB3000010610232C42000A1440003624C60002BD -:10DB40008CE2000034420100ACE2000090C2000010 -:10DB500090C3000190C4000290C5000300031C00A4 -:10DB60000002160000431025000422000044102586 -:10DB70000045102524C60004ACE2000490C2000059 -:10DB800090C3000190C4000290C50003000216007B -:10DB900000031C000043102500042200004410254F -:10DBA0000045102524C600040A000CAAACE20008B7 -:10DBB00090C30001240200041462001624C600026F -:10DBC00090C2000090C400018CE30000000212002B -:10DBD000004410253463000424C60002ACE2000CAB -:10DBE0000A000CAAACE3000090C300012402000369 -:10DBF0001462000824C600028CE2000090C30000FA -:10DC000024C6000134420008A0E300100A000CAA58 -:10DC1000ACE2000003E000082402000190C3000110 -:10DC2000240200021062000224C40002010020212C -:10DC30000A000CAA008030210A000CAA24C60001A8 -:10DC400090C200010A000CAA00C2302103E00008C3 -:10DC50000000102127BDFFE8AFBF0014AFB00010D7 -:10DC60000E00130E00808021936200052403FFFE46 -:10DC700002002021004310248FBF00148FB0001039 -:10DC8000A36200050A00131727BD001827BDFFE88F -:10DC9000AFB00010AFBF00140E000F0E0080802147 -:10DCA0009362000024030050304200FF144300043C -:10DCB00024020100AF4201800A000D22020020214F -:10DCC000AF400180020020218FBF00148FB00010F0 -:10DCD0000A000FAD27BD001827BDFF80AFBE00783A -:10DCE000AFB70074AFB30064AFBF007CAFB60070D5 -:10DCF000AFB5006CAFB40068AFB20060AFB1005C0C -:10DD0000AFB000588F5001289363003F9362000525 -:10DD10000000F021307300FF0002102730420001A4 -:10DD20000000B82114400066AFA0005093420116D5 -:10DD300093430112304200FF306300FF0342202171 -:10DD400003431021244540008F82001C104000181E -:10DD5000249140008F4201043C0300010043102441 -:10DD600010400013000000008CA3000C8F620030F4 -:10DD7000146201B5240200018CA300108F62002CF4 -:10DD8000146201B1240200019762003A94834000BA -:10DD90003042FFFF146201AC240200019762003898 -:10DDA000962300023042FFFF146201A72402000103 -:10DDB00093620000304300FF24020020106200053F -:10DDC0002402005010620006000000000A000D6CE2 -:10DDD000000000000000000D0A000D75AFA000302B -:10DDE0003C1E080027DE75E80A000D75AFA0003064 -:10DDF0003C0208008C4200DC244200013C01080087 -:10DE0000AC2200DC0E0013D8000000000A000F0353 -:10DE10008FBF007C8F4201043C0300209234000D30 -:10DE2000004310240002202B00042140AFA4003046 -:10DE30008F4301043C020040006218241460000279 -:10DE4000348700400080382132820020AFA70030A4 -:10DE50001440000234E6008000E0302110C0000BC6 -:10DE6000AFA6003093C500088F67004C0200202148 -:10DE700000052B0034A5008130A5F0810E000C8D2B -:10DE800030C600FF0A000F00000000009362003E51 -:10DE9000304200401040000E24020004566200068A -:10DEA00024020012020020210E0014E6022030217C -:10DEB0000A000F038FBF007C1662000500000000FF -:10DEC0000E000D13000020210A000F038FBF007CFD -:10DED0009743011A9624000E9362003532850004A0 -:10DEE0003076FFFF00442004AFA400548E320004BB -:10DEF00010A000158E3500089362003E30420040AD -:10DF000010400007000000000E00142802402021ED -:10DF10001040000D000000000A000F00000000008B -:10DF20008F620044024210230440014500000000BB -:10DF30008F6200480242102304410141240400166C -:10DF40000A000E038FC200048F62004802421023B1 -:10DF500004400008000000003C0208008C42310030 -:10DF6000244200013C010800AC2231000A000EF5F9 -:10DF7000000000008F620040024210231840000998 -:10DF80002402000C3C0208008C423100329400FC58 -:10DF90000000B021244200013C010800AC22310005 -:10DFA0002402000CAFA200308F62004000522023F8 -:10DFB0001880000D02C4102A144001160000000051 -:10DFC0001496000602C410233A8200013042000178 -:10DFD000144001100000000002C4102302449021EC -:10DFE0000A000DEB3056FFFF0000202132820002B4 -:10DFF0001040001A328200109362003E304200400E -:10E00000504000118FC200040E00130E02002021A8 -:10E0100024020018A362003F936200052403FFFE60 -:10E0200002002021004310240E001317A3620005F4 -:10E0300024040039000028210E00141124060018C1 -:10E040000A000F0224020001240400170040F8090E -:10E05000000000000A000F0224020001104000F836 -:10E06000000000008F63004C8F62005402A2102356 -:10E070001C4000F302A31023044200010060A82109 -:10E08000AFA40018AFB20010AFB600149342012045 -:10E090008F6500409763003C304200FF034210212F -:10E0A000004410218FA400543063FFFF244240003D -:10E0B0000083182B8FA40030AFA20020AFA500284A -:10E0C00000832025AFA40030AFA50024AFA0002C12 -:10E0D000AFB500349362003E30420008504000115A -:10E0E0008FC200000220202127A500380E000CA4BA -:10E0F000AFA000385440000B8FC200008FA2003840 -:10E1000030420100504000078FC200008FA3003C46 -:10E110008F6200600062102304430001AF6300605F -:10E120008FC200000040F80927A400108FA2003021 -:10E130003042000254400001329400FE9362003EDF -:10E1400030420040104000378FA300148F6200540B -:10E1500016A2001A3282000124020014126200107A -:10E160002A62001510400006240200162402000C4A -:10E1700012620007328200010A000E5F00000000F8 -:10E1800012620005328200010A000E5F00000000EA -:10E190000A000E5A2417000E0A000E5A2417001007 -:10E1A0000A000E5E24170012936200232403FFBDB1 -:10E1B00000431024A36200233282000110400019A2 -:10E1C0008FA300142402000C1262000E2A62000DBC -:10E1D000104000062402000E2402000A126200070A -:10E1E0008FA200240A000E77244200011262000868 -:10E1F0008FA200240A000E77244200010A000E7547 -:10E20000241700082402000E16E20002241700164C -:10E21000241700108FA2002424420001AFA2002482 -:10E220008FA300148FA200248F730040004310219D -:10E23000AF6200408FA20054936400368F630040A9 -:10E2400002A288213402FFFF00821004006218211C -:10E25000AF6300488FA6003030C200081040000EA7 -:10E26000000000008F6200581622000430C600FF34 -:10E270009742011A5040000134C6001093C50008AF -:10E280008FA700340200202100052B0034A5008058 -:10E290000E000C8D30A5F0808F62004000531023DB -:10E2A000184000178FA200183C0208008C423198D9 -:10E2B00030420010104000092402000197620068FB -:10E2C0001440000624020001A76200689742007A09 -:10E2D0002442000A0A000EBBA7620012A7620012C5 -:10E2E0000E00130E020020219362007D2403000122 -:10E2F00002002021344200010A000EB9AFA30050F1 -:10E300001840000A000000000E00130E0200202139 -:10E310009362007D2403000102002021AFA300507E -:10E32000344200040E001317A362007D9362003E86 -:10E33000304200401440000C328200011040000ABC -:10E34000000000008F6300408FC200042404001806 -:10E35000246300010040F809AF6300408FA2003041 -:10E360000A000F02304200048F6200581051001062 -:10E37000000000008F620018024210231C400008B9 -:10E38000240400018F6200181642000900000000FA -:10E390008F62001C02A21023044000050000000050 -:10E3A000AF710058AFA40050AF720018AF75001CD9 -:10E3B00012E0000B8FA200500E00130E020020216D -:10E3C000A377003F0E0013170200202102E0302146 -:10E3D000240400370E001411000028218FA20050E1 -:10E3E00010400003000000000E000C9B02002021E2 -:10E3F00012C00005000018218FA200303042000436 -:10E400005040001100601021240300010A000F0297 -:10E41000006010210E00130E020020219362007D87 -:10E4200002002021344200040E001317A362007D75 -:10E430000E000C9B020020210A000F0224020001A2 -:10E44000AF400044240200018FBF007C8FBE0078E3 -:10E450008FB700748FB600708FB5006C8FB40068F2 -:10E460008FB300648FB200608FB1005C8FB0005832 -:10E4700003E0000827BD00808F4201B80440FFFE82 -:10E4800024020800AF4201B803E0000800000000C9 -:10E4900030A5FFFF30C6FFFF8F4201B80440FFFEEA -:10E4A0003C020008AF44018003421021AF44002029 -:10E4B000944200483044FFFF1080001924020003FA -:10E4C00024A200120082102B104000152402000329 -:10E4D000934201202403001AA343018B304200FF22 -:10E4E0002447FFFE8F8200000087182B386300014D -:10E4F0000002138200431024104000058F830004A3 -:10E5000034620001A74701940A000F39AF8200046A -:10E510002402FFFE006210240A000F39AF820004BB -:10E52000A342018B24020002A742018C8F820000CB -:10E530008F840004A745018EA74201908F82000CB2 -:10E5400030838000AF4201A8A74601881060000E0A -:10E550008F82000493420116304200FC24420004E2 -:10E56000005A10218C4240003042FFFF1440000648 -:10E570008F8200043C02FFFF34427FFF00821024A0 -:10E58000AF8200048F8200042403BFFF978400023F -:10E5900000431024A74201A69742010C0002140078 -:10E5A00000441025AF4201AC3C021000AF4201B85C -:10E5B00003E00008000000008F4700709342011242 -:10E5C0008F83000027BDFFF0304200FF0002288249 -:10E5D00030620100000030211040004324A40003F9 -:10E5E00030624000104000103062200000041080B3 -:10E5F000005A10218C43400024A400040004108021 -:10E60000AFA30000005A10218C424000AFA20004CA -:10E6100093420116304200FC005A10218C42400007 -:10E620000A000F86AFA200081040002F0000302122 -:10E6300000041080005A10218C43400024A40004E0 -:10E6400000041080AFA30000005A10218C4240004B -:10E65000AFA00008AFA200048FA80008000030217E -:10E6600000002021240A00083C0908002529010097 -:10E6700003A41021148A000300042A001100000AD8 -:10E680000000000090420000248400012C83000C54 -:10E6900000A2102100021080004910218C420000CD -:10E6A0001460FFF300C230263C0408008C8431045F -:10E6B0008F4200702C83002010600009004738232F -:10E6C0003C0308002463310800041080004310213B -:10E6D00024830001AC4700003C010800AC23310456 -:10E6E000AF86000C2406000100C0102103E00008E2 -:10E6F00027BD00103C0208008C42003827BDFFD027 -:10E70000AFB60028AFB40020AFB20018AFBF002CE6 -:10E71000AFB50024AFB3001CAFB10014AFB0001010 -:10E72000000090213C16080026D600381440000254 -:10E730002454FFFF0000A0219742010E8F840000A7 -:10E740003042FFFF308340001060000A2453000471 -:10E750003C020020008210245040000730828000DC -:10E760008F8200042403BFFF008318240A000FD700 -:10E7700034421000308280001040000A3C02002029 -:10E7800000821024104000078F8200043C03FFFF2A -:10E7900034637FFF0083182434428000AF8200047A -:10E7A000AF8300000E000F5E000000001440000761 -:10E7B000000000009743011E9742011C3063FFFFD9 -:10E7C0000002140000621825AF83000C9742010C70 -:10E7D0008F4340003046FFFF3402FFFF1462000306 -:10E7E000000000000A000FEF241200208F424000BA -:10E7F0003042010054400001241200108F840000B8 -:10E800003082100050400014365200013082002047 -:10E810001440000B3C021000008210245040000EF7 -:10E82000365200013C030E003C020DFF0083182409 -:10E830003442FFFF0043102B5040000736520001C6 -:10E840003C0208008C42002C244200013C010800DC -:10E85000AC22002C365200053C0508008CA5003483 -:10E8600054A000408F8400008F8200105440003D6F -:10E870008F8400008F8200043042400054400039F1 -:10E880008F8400003C021F01008210243C03100012 -:10E89000144300348F84000030C202001440003260 -:10E8A0003C0200013265FFFF364600028F4201B88C -:10E8B0000440FFFE3C020008AF40018003421021EB -:10E8C000944200483043FFFF10600019AF830008F6 -:10E8D00024A200120062102B104000162402000334 -:10E8E000934201202403001AA343018B304200FF0E -:10E8F0002443FFFE8F820000304240001040000899 -:10E900008F8200048F8200080043102B1440000403 -:10E910008F820004A74301940A00103A3442000198 -:10E920002403FFFE004310240A00103EAF820004BF -:10E9300024020003A342018B8F8300042402BFFF43 -:10E940000062182424020002A742018C8F8200007A -:10E95000A745018EA7460188A74301A60A0010D942 -:10E96000A74201903C020001008210241040000BDD -:10E970003C0210003C0208008C4200D89745010E72 -:10E98000240400802442000130A5FFFF3C01080060 -:10E99000AC2200D80A0010E22406000300821024F2 -:10E9A00010400041000000003C0208008C42003092 -:10E9B0001040000C8F8200043042400010400009DB -:10E9C0003C030F00008318243C0201000043102B7D -:10E9D00014400004364600023265FFFF0A0010E2D0 -:10E9E0002404008010A0000D308201001040000BB4 -:10E9F0003C020F00008210243C0302001043000779 -:10EA00008F82000C00541024005610219042000404 -:10EA1000244200040A001097000221C000000000F8 -:10EA20008F8600003C0508008CA500D00006160269 -:10EA30003050000F38A200012C4200012E03000CC0 -:10EA40000043102414400015001021C02602FFFCD2 -:10EA50002C420004544000110000202138A2000282 -:10EA60002C42000100431024104000030006124213 -:10EA70000A001097000020210010182B00431024DA -:10EA800050400006001021C0000020213265FFFF29 -:10EA90000E000F143246FFFB001021C03265FFFF4D -:10EAA0000A0010E2364600028F4240003C11080086 -:10EAB0008E310024304201001040003E322200011D -:10EAC0000220802110A00014325500043082010081 -:10EAD00010400012240200013C020F0000821024AA -:10EAE0003C0302001043000C8F82000C02403021D6 -:10EAF0003265FFFF0054102400561021904400049A -:10EB00003252FFFB248400040E000F14000421C0C5 -:10EB10002402FFFE022280242402000116020007C4 -:10EB2000320200013242000450400001365200021D -:10EB30003265FFFF0A0010E102403021104000075B -:10EB40003202000402403021000020210E000F1488 -:10EB50003265FFFF3252FFFB320200041040000713 -:10EB60008F82000030420800104000043265FFFF31 -:10EB7000024030210E000F142404010016A00015DD -:10EB80008FBF002C274301808F4201B80440FFFE55 -:10EB900024022000A462000824020002A062000BEC -:10EBA000A46000103C021000AF4201B80A0010E55A -:10EBB0008FBF002C104000078FBF002C3265FFFF75 -:10EBC00036460002000020210E000F140000000055 -:10EBD0008FBF002C8FB600288FB500248FB4002083 -:10EBE0008FB3001C8FB200188FB100148FB00010CB -:10EBF0000000102103E0000827BD003027BDFFC83A -:10EC0000AFB000103C04600CAFBF0030AFB7002CB9 -:10EC1000AFB60028AFB50024AFB40020AFB3001CDE -:10EC2000AFB20018AFB100148C8250002403FF7FF4 -:10EC30003C1A8000004310243442380CAC8250004F -:10EC4000240200033C106000AF4200088E02080856 -:10EC50003C1B80083C010800AC2000203042FFF043 -:10EC6000384200102C4200010E001C46AF82001CEE -:10EC70003C04FFFF3C020400348308063442000CCD -:10EC8000AE021948AE03194C3C0560168E0219807D -:10EC90008CA300003442020000641824AE021980E4 -:10ECA0003C0253531462000334A47C008CA2000481 -:10ECB000005020218C82007C8C830078AF82001869 -:10ECC000AF8300143C028000344200708C4300008B -:10ECD00000403821AF830020006030218CE8000024 -:10ECE0003C0508008CA500FC3C0408008C8400F85E -:10ECF000010630230000102100A6282100A6302B99 -:10ED000000822021008620213C010800AC2500FC67 -:10ED10003C010800AC2400F88F56000032C200030A -:10ED20001040FFEE010030218CE600003C05080099 -:10ED30008CA500FC3C0408008C8400F800C830233B -:10ED400000A628210000102100A6302B00822021DF -:10ED50000086202132C700013C010800AC2500FCE0 -:10ED6000AF8800203C010800AC2400F810E0016BE3 -:10ED700032C200028F4301283C02000803421021E6 -:10ED8000AF4300208F4301048F44010094420048A8 -:10ED9000AF830000AF8400043042FFFF0E000F0E6F -:10EDA000AF8200083C0208008C4200C010400008FE -:10EDB0008F8400003C0208008C4200C42442000101 -:10EDC0003C010800AC2200C40A0012AF00000000A1 -:10EDD0003C02001000821024144001358F8300048F -:10EDE0003C0208008C4200203C0308008C63003881 -:10EDF00000009021244200013C010800AC220020C8 -:10EE00003C17080026F70038146000022474FFFF46 -:10EE10000000A0219742010E308340003042FFFFE6 -:10EE20001060000A245300043C02002000821024D9 -:10EE300050400007308280008F8200042403BFFF0F -:10EE4000008318240A00118D3442100030828000A3 -:10EE50001040000A3C0200200082102410400007ED -:10EE60008F8200043C03FFFF34637FFF008318247C -:10EE700034428000AF820004AF8300000E000F5EBA -:10EE80000000000014400007000000009743011E2E -:10EE90009742011C3063FFFF000214000062182536 -:10EEA000AF83000C9742010C8F4340003046FFFFB8 -:10EEB0003402FFFF14620003000000000A0011A5E5 -:10EEC000241200208F4240003042010054400001D3 -:10EED000241200108F840000308210005040001473 -:10EEE00036520001308200201440000B3C0210001A -:10EEF000008210245040000E365200013C030E00E8 -:10EF00003C020DFF008318243442FFFF0043102B06 -:10EF100050400007365200013C0208008C42002C91 -:10EF2000244200013C010800AC22002C36520005AE -:10EF30003C0508008CA5003454A000408F840000DC -:10EF40008F8200105440003D8F8400008F820004A7 -:10EF500030424000544000398F8400003C021F01C1 -:10EF6000008210243C031000144300348F840000FE -:10EF700030C20200144000323C0200013265FFFF43 -:10EF8000364600028F4201B80440FFFE3C020008F2 -:10EF9000AF40018003421021944200483043FFFFFC -:10EFA00010600019AF83000824A200120062102B29 -:10EFB0001040001624020003934201202403001A8B -:10EFC000A343018B304200FF2443FFFE8F820000E9 -:10EFD00030424000104000088F8200048F820008F9 -:10EFE0000043102B144000048F820004A7430194B7 -:10EFF0000A0011F0344200012403FFFE00431024F4 -:10F000000A0011F4AF82000424020003A342018B22 -:10F010008F8300042402BFFF006218242402000230 -:10F02000A742018C8F820000A745018EA746018868 -:10F03000A74301A60A00128FA74201903C020001DB -:10F04000008210245040000B3C0210003C020800DB -:10F050008C4200D89745010E240400802442000110 -:10F0600030A5FFFF3C010800AC2200D80A0012982E -:10F07000240600030082102410400041000000001C -:10F080003C0208008C4200301040000C8F820004CB -:10F0900030424000104000093C030F000083182458 -:10F0A0003C0201000043102B1440000436460002CD -:10F0B0003265FFFF0A0012982404008010A0000DA2 -:10F0C000308201001040000B3C020F00008210242F -:10F0D0003C030200104300078F82000C00541024F0 -:10F0E0000057102190420004244200040A00124DEF -:10F0F000000221C0000000008F8600003C050800CF -:10F100008CA500D0000616023050000F38A2000176 -:10F110002C4200012E03000C004310241440001563 -:10F12000001021C02602FFFC2C42000454400011B4 -:10F130000000202138A200022C42000100431024CC -:10F1400050400003000612420A00124D0000202128 -:10F150000010182B0043102450400006001021C05E -:10F16000000020213265FFFF0E000F143246FFFB26 -:10F17000001021C03265FFFF0A00129836460002D7 -:10F180008F4240003C1108008E31002430420100C3 -:10F190001040003E322200010220802110A0001405 -:10F1A0003255000430820100104000122402000198 -:10F1B0003C020F00008210243C0302001043000CAC -:10F1C0008F82000C024030213265FFFF0054102472 -:10F1D00000571021904400043252FFFB24840004A5 -:10F1E0000E000F14000421C02402FFFE022280241E -:10F1F000240200011602000732020001324200041C -:10F2000050400001365200023265FFFF0A0012979B -:10F210000240302110400007320200040240302139 -:10F22000000020210E000F143265FFFF3252FFFB59 -:10F2300032020004104000078F82000030420800B4 -:10F24000104000043265FFFF024030210E000F1411 -:10F250002404010016A0002E3C0240002743018038 -:10F260008F4201B80440FFFE24022000A46200087F -:10F2700024020002A062000BA46000103C021000F7 -:10F28000AF4201B80A0012B43C02400050400020D6 -:10F290003C0240003265FFFF36460002000020219C -:10F2A0000E000F14000000000A0012B43C024000DF -:10F2B0002402BFFF0062102410400008000000007C -:10F2C000240287FF00621024144000083C02006002 -:10F2D0000082102410400005000000000E000D26E2 -:10F2E000000000000A0012AD000000000E0012F83D -:10F2F00000000000104000063C0240008F43012443 -:10F300003C026020AC430014000000003C024000BE -:10F31000AF4201380000000032C200021040FE6A15 -:10F320003C0280008F4201403C044000AF4200207C -:10F330008F4301483C027000006218241064002DC5 -:10F34000000000000083102B144000063C02600007 -:10F350003C022000106200073C0240000A0012F448 -:10F360000000000010620027000000000A0012F4F4 -:10F370003C0240008F4201482403000400021402B2 -:10F38000304200FF1443000B274401808F430140AB -:10F390008F4201B80440FFFE2402001CAC83000031 -:10F3A000A082000B3C021000AF4201B80A0012F428 -:10F3B0003C0240008F4201B80440FFFE0000000004 -:10F3C0008F42014800021402A482000824020002B5 -:10F3D000A082000B8F420148A48200108F4201449A -:10F3E000AC8200243C021000AF4201B80A0012F4C3 -:10F3F0003C0240000E00131C000000000A0012F442 -:10F400003C0240000E001C53000000003C02400083 -:10F41000AF420178000000000A0011223C02800087 -:10F420008F4201003042003E1440001124020001CE -:10F43000AF4000488F420100304207C01040000535 -:10F4400000000000AF40004CAF40005003E0000857 -:10F4500024020001AF400054AF4000408F42010041 -:10F460003042380054400001AF4000442402000103 -:10F4700003E00008000000003C029000344200015C -:10F4800000822025AF4400208F4200200440FFFE70 -:10F490000000000003E00008000000003C028000C3 -:10F4A000344200010082202503E00008AF44002020 -:10F4B00027BDFFE0AFB20018AFBF001CAFB1001412 -:10F4C000AFB000108F5001408F5101483C028000C6 -:10F4D0000011940202222024324300FF2402000E75 -:10F4E0001062008A2862000F104000122862003764 -:10F4F000240200061062003B28620007104000074B -:10F50000240200091060001A240200011062002584 -:10F51000000000000A0013D1000000001062007B10 -:10F520002402000B1062005B3222FFFF0A0013D19D -:10F530000000000010400008240200382862003556 -:10F54000104000802402001F1062007E00000000B6 -:10F550000A0013D1000000001062007A240200802B -:10F5600010620042000000000A0013D100000000F9 -:10F570008F4201B80440FFFE24020001AF50018019 -:10F58000AF400184A7520188A342018A24020002ED -:10F59000A342018BA75101908F4201440A0013CC72 -:10F5A000AF4201A41080000A240200023C010800BE -:10F5B000A02275D83C010800AC3075E08F420144B0 -:10F5C0003C010800AC2275DC0A0013D38FBF001C7D -:10F5D0008F4201B80440FFFE240200020A0013B665 -:10F5E000000000008F4201B80440FFFE0000000050 -:10F5F000AF5001803C020800904275D810400003D3 -:10F60000000018213C0308008C6375E0AF430184BF -:10F61000A75201883C020800904275D800001821CA -:10F6200034420001A342018A24020002A342018B5A -:10F63000A75101908F420144AF4201A43C0208004F -:10F64000904275D8104000033C0210003C030800B3 -:10F650008C6375DCAF4301A8AF4201B83C010800E0 -:10F66000A02075D80A0013D38FBF001C8F4201B8A9 -:10F670000440FFFE24020002A342018BA75201882E -:10F68000A75101908F420144A74201920A0013CE74 -:10F690003C0210001440001D0000000093620005B1 -:10F6A0003042000414400037000000000E00130E2A -:10F6B0000200202193620005020020213442000450 -:10F6C0000E001317A3620005936200053042000488 -:10F6D00014400002000000000000000D93620000D2 -:10F6E00024030020304200FF144300080000000003 -:10F6F0008F4201B80440FFFE24020005AF50018094 -:10F70000A342018B3C021000AF4201B88F4201B806 -:10F710000440FFFE24020002AF400180AF5001848C -:10F72000A7520188A342018AA342018BA7510190ED -:10F73000AF4001A48F420144AF4201A80A0013CE9A -:10F740003C0210008F4201B80440FFFE2402000179 -:10F75000AF500180AF400184A7520188A342018AC3 -:10F7600024020002A342018BA7510190AF4001A4E3 -:10F77000AF4001A83C021000AF4201B80A0013D309 -:10F780008FBF001C0000000D8FBF001C8FB200183F -:10F790008FB100148FB0001003E0000827BD0020D7 -:10F7A00027BDFFE8AFBF00100E000F0E00000000E5 -:10F7B000AF4001808FBF0010000020210A000FAD74 -:10F7C00027BD00183084FFFF30A5FFFF000018217F -:10F7D000108000070000000030820001104000028D -:10F7E00000042042006518210A0013E400052840A7 -:10F7F00003E000080060102110C0000624C6FFFFCF -:10F800008CA2000024A50004AC8200000A0013EEC4 -:10F810002484000403E000080000000010A0000899 -:10F8200024A3FFFFAC8600000000000000000000E1 -:10F830002402FFFF2463FFFF1462FFFA2484000404 -:10F8400003E000080000000027BDFFE8AFBF001480 -:10F85000AFB000100E00130E008080219362007D77 -:10F8600002002021344200200E001317A362007D05 -:10F87000020020218FBF00148FB000100A000C9BE3 -:10F8800027BD0018308300FF30A500FF30C600FF01 -:10F89000274701808F4201B80440FFFE00000000AE -:10F8A0008F42012834634000ACE2000024020001D2 -:10F8B000ACE00004A4E30008A0E2000A2402000275 -:10F8C000A0E2000B3C021000A4E50010ACE0002414 -:10F8D000ACE00028A4E6001203E00008AF4201B843 -:10F8E00027BDFFE8AFBF00109362003F2403001262 -:10F8F000304200FF1043000D008030218F62004431 -:10F90000008210230440000A8FBF00108F6200485D -:10F91000240400390000282100C2102304410004FF -:10F92000240600120E001411000000008FBF00100A -:10F930002402000103E0000827BD001827BDFFC80E -:10F94000AFB1002C00A08821AFB2003027A5001075 -:10F950000080902102202021AFBF0034AFB00028EA -:10F960000E000CA4AFA0001010400009024020219E -:10F970008E220008AF6200840E001402AF600040C7 -:10F98000240400382405008D0A0014DD240600122A -:10F990009362003E304200081040000F8FA200101A -:10F9A00030420100104000078FA300148F620060F6 -:10F9B0000062102304430008AF6300600A0014666D -:10F9C00000000000AF6000609362003E2403FFF778 -:10F9D00000431024A362003E9362003E30420008C0 -:10F9E000144000022406000300003021936200341A -:10F9F000936300378F640084304200FF306300FF60 -:10FA000000661821000318800043282100A4202B41 -:10FA10001080000B000000009763003C8F620084A0 -:10FA20003063FFFF004510230062182B14600004B0 -:10FA3000000000008F6200840A00148200458023C9 -:10FA40009762003C3050FFFF8FA30010306200042B -:10FA500010400004000628808FA2001C0A00148AAF -:10FA60000202102B2E02021850400003240202183A -:10FA70000A00149302051023306300041060000391 -:10FA8000004510238FA2001C004510230040802158 -:10FA90002C42008054400001241000800E00130E00 -:10FAA0000240202124020001AF62000C9362003E5C -:10FAB000001020403042007FA362003E8E220004EE -:10FAC00024420001AF620040A770003C8F620050EA -:10FAD0009623000E00431021AF6200588F62005041 -:10FAE00000441021AF62005C8E220004AF62001857 -:10FAF0008E220008AF62001C8FA200103042000866 -:10FB00005440000A93A20020A3600036936200369E -:10FB10002403FFDFA36200359362003E00431024FC -:10FB2000A362003E0A0014BD8E220008A3620035C5 -:10FB30008E220008AF62004C8F6200248F63004069 -:10FB400000431021AF62004893620000240300507C -:10FB5000304200FF144300122403FF803C020800DF -:10FB60008C4231A00242102100431024AF420028F1 -:10FB70003C0208008C4231A08E2400083C03000C9B -:10FB8000024210213042007F034210210043102125 -:10FB9000AC4400D88E230008AF820028AC4300DCC0 -:10FBA0000E001317024020212404003800002821F1 -:10FBB0002406000A0E001411000000008FBF00345C -:10FBC0008FB200308FB1002C8FB0002824020001CA -:10FBD00003E0000827BD003827BDFFE8AFBF0010D5 -:10FBE00090C7000D00C0282130E6001010C0000AA8 -:10FBF00030E200058CA300088F62005410620006FA -:10FC000030E20005144000178FBF001000002021D3 -:10FC10000A000D1327BD00181040000D30E300123C -:10FC200010C000108FBF00108CA300088F6200541A -:10FC30001462000D24020001240400382405008D04 -:10FC40000E001411240600120A0015098FBF0010BF -:10FC500024020012146200038FBF00100A00143F38 -:10FC600027BD00182402000103E0000827BD00188A -:10FC700027BDFFF827420180AFA20000308A00FFB5 -:10FC80008F4201B80440FFFE000000008F460128AB -:10FC90003C0208008C4231A02403FF80AF86005054 -:10FCA00000C2102100431024AF4200243C0208008F -:10FCB0008C4231A08FA900008FA8000000C2102143 -:10FCC0003042007F034218213C02000A00621821E2 -:10FCD000946400D48FA700008FA5000024020002C6 -:10FCE000AF830028A0A2000B8FA300003542600064 -:10FCF0003084FFFFA4E200083C021000AD260000A3 -:10FD0000AD040004AC60002427BD0008AF4201B878 -:10FD100003E00008240200018C8200048F83002885 -:10FD200000451023AC820004906200633042007FE3 -:10FD3000A06200638C820020938300308F850028AE -:10FD400034420002AF830044A7800042AC8200200E -:10FD5000A4A000E490A200632403FFBF004310248A -:10FD600003E00008A0A20063274301808F4201B88E -:10FD70000440FFFE8F820050AC6200008F420124DD -:10FD8000AC62000424026083A46200082402000222 -:10FD9000A062000B3C02100003E00008AF4201B873 -:10FDA0008F880044938200308F8300283C0708002E -:10FDB00024E779F400481023304200FF304900FC6A -:10FDC000246500888F860048304A0003112000090E -:10FDD00000002021248200048CA30000304400FF96 -:10FDE0000089102AACE3000024A500041440FFF9A8 -:10FDF00024E70004114000090000202124820001B2 -:10FE000090A30000304400FF008A102BA0E3000004 -:10FE100024A500011440FFF924E7000130C20003CB -:10FE2000144000048F850044310200031040000D8F -:10FE30000000000010A00009000020212482000121 -:10FE400090C30000304400FF0085102BA0E30000A9 -:10FE500024C600011440FFF924E7000103E0000874 -:10FE6000000000001100FFFD00002021248200049A -:10FE70008CC30000304400FF0088102BACE300006E -:10FE800024C600041440FFF924E7000403E000083E -:10FE9000000000008F8300449382003030C600FFD2 -:10FEA00030A500FF00431023304300FF8F8200285D -:10FEB000008038210043102114C00002244800882B -:10FEC0000083382130E200031440000530A2000313 -:10FED00014400003306200031040000D00000000D9 -:10FEE00010A00009000020212482000190E30000FE -:10FEF000304400FF0085102BA103000024E700011F -:10FF00001440FFF92508000103E00008000000008C -:10FF100010A0FFFD00002021248200048CE30000DB -:10FF2000304400FF0085102BAD03000024E70004DF -:10FF30001440FFF92508000403E000080000000059 -:10FF400027BDFFF82402FFFFAFA200000080382188 -:10FF50002405002F3C090800252975F4240800FF1A -:10FF60002406FFFF90E2000024A3FFFF0006220208 -:10FF700000C21026304200FF00021080004910210C -:10FF80008C420000306500FF24E7000114A8FFF553 -:10FF90000082302600061027AFA20004AFA20000A6 -:10FFA0000000282127A6000400C510239044000368 -:10FFB00024A2000100BD1821304500FF2CA200043E -:10FFC0001440FFF9A06400008FA2000003E00008C5 -:10FFD00027BD00080080482130AAFFFF30C600FF7F -:10FFE00030E7FFFF274801808F4201B80440FFFE41 -:10FFF0008F820050AD0200008F420124AD02000448 -:020000040001F9 -:100000008D220020A5070008A102000A2402001684 -:10001000A102000B934301208D2200088D240004CF -:10002000306300FF004310219783004200441021F9 -:100030008D250024004310233C0308008C6331A06D -:100040008F840028A502000C246300E82402FFFF2F -:10005000A50A000EA5030010A5060012AD050018A4 -:10006000AD020024948201142403FFF73042FFFF05 -:10007000AD0200288C820118AD02002C3C02100059 -:10008000AD000030AF4201B88D22002000431024A3 -:1000900003E00008AD2200208F82002830E7FFFF38 -:1000A00000804821904200D330A5FFFF30C600FFFA -:1000B0000002110030420F0000E23825274801807D -:1000C0008F4201B80440FFFE8F820050AD02000055 -:1000D0008F420124AD0200048D220020A5070008F4 -:1000E000A102000A24020017A102000B9343012081 -:1000F0008D2200088D240004306300FF004310218E -:1001000097830042004410218F840028004310236D -:100110003C0308008C6331A0A502000CA505000E6D -:10012000246300E8A5030010A5060012AD0000142A -:100130008D220024AD0200188C82005CAD02001CF0 -:100140008C820058AD0200202402FFFFAD02002483 -:10015000948200E63042FFFFAD02002894820060E6 -:10016000948300BE30427FFF3063FFFF0002120025 -:1001700000431021AD02002C3C021000AD00003005 -:10018000AF4201B8948200BE2403FFF700A2102101 -:10019000A48200BE8D2200200043102403E000084A -:1001A000AD220020274301808F4201B80440FFFEAA -:1001B00024020018AC640000A062000B8F820028AB -:1001C000944200E6A46200103C021000AC600030D3 -:1001D00003E00008AF4201B8274301808F4201B815 -:1001E0000440FFFE8F82002C9442001C3042FFFF2F -:1001F000000211C0AC62000024020019A062000BD2 -:100200003C021000AC60003003E00008AF4201B8CF -:100210008F87003430C300FF8F4201B80440FFFED7 -:100220008F82005034636000ACA200009382004CC7 -:10023000A0A200058CE20010A4A20006A4A300085E -:100240008C8200202403FFF7A0A2000A24020002EF -:10025000A0A2000B8CE20000ACA200108CE2000413 -:10026000ACA200148CE2001CACA200248CE20020A2 -:10027000ACA200288CE2002CACA2002C8C820024C2 -:10028000ACA200183C021000AF4201B88C820020E2 -:100290000043102403E00008AC8200209382004C4D -:1002A0002403000127BDFFE8004330042C42002056 -:1002B000AFB00010AFBF00142410FFFE10400005C7 -:1002C000274501803C0208008C4231900A0016A8A4 -:1002D000004610243C0208008C4231940046102451 -:1002E00014400007240600848F8300282410FFFF99 -:1002F000906200623042000F34420040A06200620F -:100300000E00167400000000020010218FBF0014C0 -:100310008FB0001003E0000827BD00188F83002C69 -:1003200027BDFFE0AFB20018AFB10014AFB00010AE -:10033000AFBF001C9062000D00A0902130D100FFE3 -:100340003042007FA062000D8F8500288E43001888 -:10035000008080218CA2007C146200052402000E23 -:1003600090A20063344200200A0016D1A0A20063CC -:100370000E001697A382004C2403FFFF1043004792 -:100380002404FFFF52200045000020218E4300007E -:100390003C02001000621024504000043C0200089F -:1003A000020020210A0016E0240200150062102439 -:1003B000504000098E450000020020212402001454 -:1003C0000E001697A382004C2403FFFF1043003356 -:1003D0002404FFFF8E4500003C02000200A210240E -:1003E000104000163C0200048F86002C8CC20014C2 -:1003F0008CC300108CC40014004310230044102B45 -:1004000050400005020020218E43002C8CC20010B9 -:1004100010620003020020210A00171124020012BA -:100420003C02000400A210245040001C00002021C7 -:10043000020020210A0017112402001300A2102438 -:10044000104000068F83002C8C6200105040001377 -:10045000000020210A00170B020020218C620010EE -:10046000504000048E42002C020020210A00171187 -:100470002402001150400009000020210200202128 -:10048000240200170E001697A382004C2403FFFFDE -:10049000104300022404FFFF000020218FBF001C36 -:1004A0008FB200188FB100148FB00010008010219F -:1004B00003E0000827BD00209383003027BDFFE044 -:1004C00024020034AFB20018AFB10014AFBF001C5B -:1004D000AFB00010008088211462000C00A09021B1 -:1004E0008F8400340E0015C08C900030120200077B -:1004F00024020005022020210E001697A382004C42 -:100500002403FFFF104300602404FFFF9242000415 -:10051000104000098F820028022020212402000CB4 -:100520000E001697A382004C2403FFFF10430056D1 -:100530002404FFFF8F820028A38000248E43000440 -:100540008C4400803C0200FF3442FFFF006218240C -:100550000083202B10800008AF83003C0220202164 -:10056000240200190E001697A382004C2403FFFFFB -:10057000104300452404FFFF978200428F87004408 -:100580008F85003C0047202310A0003AA78400423A -:100590008F86002830A200030002102390C300BC05 -:1005A0003050000300B02821000318823071000190 -:1005B0000011108000A228213C0308008C6331A0A8 -:1005C0008F8200503084FFFF0085202B00431021D4 -:1005D00010800010244200888F8400341082000DA7 -:1005E0003C033F018E420000004310243C032500E1 -:1005F0001443000630E500FF8C820000ACC2008886 -:100600008C8200100A001775ACC200980E00159578 -:1006100000003021938200248F8500288F830048BA -:10062000020238218F820044A387002494A400E4AE -:10063000006218218F82003C34841000AF83004890 -:1006400000503021A4A400E41220000EAF86004424 -:1006500024E20004A382002494A200E424C3000442 -:10066000AF83004434422000A4A200E40A001792A1 -:10067000000020218F820048AF80004400471021F5 -:10068000AF820048000020218FBF001C8FB20018ED -:100690008FB100148FB000100080102103E000081B -:1006A00027BD00208F86002827BDFFE8AFBF0014BC -:1006B000AFB0001090C2006330420020104000082C -:1006C00030A500FF8CC2007C2403FFDF2442000120 -:1006D000ACC2007C90C2006300431024A0C200633F -:1006E00010A000238F8300282750018002002821BA -:1006F0000E001674240600828F8200289042006348 -:100700003042004050400019A380004C8F830034D9 -:100710008F4201B80440FFFE8F820050AE020000FD -:1007200024026082A602000824020002A202000B3A -:100730008C620008AE0200108C62000CAE02001445 -:100740008C620014AE0200188C620018AE02002405 -:100750008C620024AE0200288C620028AE02002CBD -:100760003C021000AF4201B8A380004C8F830028E8 -:100770008FBF00148FB000109062006327BD001877 -:100780003042007FA0620063978200428F8600445F -:100790008F8500289383003000461023A7820042F3 -:1007A000A4A000E490A400638F820048AF830044BB -:1007B0002403FFBF0046102100832024AF8200489D -:1007C000A0A400638F820028A04000BD8F82002873 -:1007D00003E00008A44000BE8F8A002827BDFFE088 -:1007E000AFB10014AFB000108F880044AFBF001845 -:1007F00093890024954200E430D100FF0109182BB1 -:100800000080802130AC00FF3047FFFF00005821FE -:1008100014600003310600FF012030210109582334 -:10082000978300420068102B144000320000000043 -:1008300014680007240200018E0200202403FFFB3D -:1008400034E7800000431024AE020020240200019F -:1008500034E70880158200053165FFFF0E0015E5BD -:10086000020020210A001827020020210E0016167F -:10087000020020210E0016598F8400508F8400281A -:100880009482006024420001A4820060948200608F -:100890003C0308008C63318830427FFF5443000FD3 -:1008A0000200202194820060240380000043102471 -:1008B000A48200609082006090830060304200FF5C -:1008C000000211C200021027000211C03063007F35 -:1008D00000621825A0830060020020210220282148 -:1008E0008FBF00188FB100148FB000100A00179945 -:1008F00027BD0020914200632403FF8000431025A0 -:10090000A1420063978200423048FFFF110000209F -:10091000938300248F840028004B1023304600FF6F -:10092000948300E42402EFFF0168282B006218245E -:10093000A48300E414A000038E02002001005821CB -:10094000000030212403FFFB34E780000043102423 -:10095000AE02002024020001158200053165FFFF70 -:100960000E0015E5020020210A00184F978300426F -:100970000E00161602002021978300428F82004449 -:10098000A780004200431023AF82004493830024D9 -:100990008F8200288FBF00188FB100148FB0001015 -:1009A00027BD002003E00008A04300BD8F8200287F -:1009B00090430088904500BD244900883063003F83 -:1009C0002463FFE024020001006238042C6300204D -:1009D00030E80019A385002410600010AF890034AE -:1009E0003C0280003442000224050001240600017C -:1009F0001500000800E218240000282114600005FA -:100A000030E200201040000524050001912600017D -:100A100030C600010A0017E60000000003E00008ED -:100A20000000000027BDFFD8AFB000108F90003449 -:100A3000AFB40020AFB10014AFBF0024AFB3001CAF -:100A4000AFB200188E0500103C0208008C4231B095 -:100A50008F86003830A33FFF0062182B8CD3001420 -:100A6000008088218CD20020106000780000A02136 -:100A700090C3000D2402FF8000431024304200FF89 -:100A800050400073022020210005138230420003F1 -:100A90005440006F0220202194C3001C8F82002844 -:100AA0008E050028A44301148CC200100262182392 -:100AB000146500072402001F8F82003C0062102191 -:100AC0000262102B104000088F83002C24020018B3 -:100AD0000E001697A382004C2403FFFF1043006F03 -:100AE0002404FFFF8F83002C8F84003C8C62001055 -:100AF0000244902100441023AC6200108F82002831 -:100B0000AC7200208C4200680052102B104000098B -:100B10008F830038022020212402001D0E0016972A -:100B2000A382004C2403FFFF1043005C2404FFFF5A -:100B30008F8300388E0200248C630024104300074A -:100B4000022020212402001C0E001697A382004CD4 -:100B50002403FFFF104300512404FFFF8F84002C67 -:100B60008C82002424420001AC8200241253000431 -:100B70008F8200288C4200685642000E8E020000D0 -:100B80008E0200003C030080004310241440000D3E -:100B90002402001A022020210E001697A382004C86 -:100BA0002403FFFF1043003D2404FFFF0A0018E365 -:100BB0008E0200143C0300800043102450400003C8 -:100BC0008E020014AC8000208E0200142412FFFF5D -:100BD000105200062402001B022020210E0016974E -:100BE000A382004C1052002D2404FFFF8E0300004E -:100BF0003C020001006210241040001F3C020080F3 -:100C00000062102414400008022020212402001A4F -:100C10000E001697A382004C2403FFFF1043001F11 -:100C20002404FFFF02202021020028210E0016B715 -:100C3000240600012403FFFF2404FFFF1443000ED9 -:100C4000241400010A0019188FBF0024022020215B -:100C50002402000D8FBF00248FB400208FB3001C2E -:100C60008FB200188FB100148FB0001027BD00287C -:100C70000A001697A382004C8F83002C02202021AB -:100C800002803021946200362405000124420001D4 -:100C90000E0017E6A4620036000020218FBF00245A -:100CA0008FB400208FB3001C8FB200188FB10014D6 -:100CB0008FB000100080102103E0000827BD00283D -:100CC0008F83002827BDFFD8AFB40020AFB3001C2E -:100CD000AFB20018AFB10014AFB00010AFBF002426 -:100CE000906200638F9100342412FFFF3442004071 -:100CF00092250000A06200638E22001000809821DF -:100D000030B0003F105200060360A0212402000D05 -:100D10000E001697A382004C105200522404FFFFCD -:100D20008F8300288E2200188C63007C10430007FC -:100D3000026020212402000E0E001697A382004CB0 -:100D40002403FFFF104300472404FFFF2404002076 -:100D5000120400048F830028906200633442002054 -:100D6000A06200638F85003C10A0001E0000000000 -:100D7000560400048F820028026020210A001962B4 -:100D80002402000A9683000A2404FFFD94420060B6 -:100D90003042FFFF104300348FBF00243C020800A4 -:100DA0008C42318C0045102B14400006026020213B -:100DB000000028210E0017E6240600010A00198908 -:100DC000000020212402002D0E001697A382004C63 -:100DD0002403FFFF104300232404FFFF0A001989A6 -:100DE00000002021160400058F8400288E230014A3 -:100DF0002402FFFF506200180260202194820060EC -:100E000024420001A4820060948200603C03080038 -:100E10008C63318830427FFF5443000F02602021F1 -:100E2000948200602403800000431024A4820060A8 -:100E30009082006090830060304200FF000211C287 -:100E400000021027000211C03063007F00621825E5 -:100E5000A0830060026020210E0017992405000184 -:100E6000000020218FBF00248FB400208FB3001C0E -:100E70008FB200188FB100148FB0001000801021C5 -:100E800003E0000827BD00288F83002827BDFFE866 -:100E9000AFB00010AFBF0014906200638F870034C2 -:100EA00000808021344200408CE60010A062006384 -:100EB0003C0308008C6331B030C23FFF0043102B6D -:100EC0001040004E8F8500382402FF8090A3000D53 -:100ED00000431024304200FF50400049020020210E -:100EE0000006138230480003240200025502004429 -:100EF0000200202194A2001C8F85002824030023D7 -:100F0000A4A201148CE60000000616023042003F45 -:100F1000104300103C0300838CE300188CA2007C7B -:100F2000106200062402000E0E001697A382004CE9 -:100F30002403FFFF104300382404FFFF8F830028A1 -:100F40009062006334420020A06200630A0019CE60 -:100F50008F83002C00C31024144300078F83002CC0 -:100F600090A200623042000F34420020A0A2006232 -:100F7000A38800408F83002C9062000D3042007FD8 -:100F8000A062000D8F83003C106000180200202139 -:100F90008F8400388C8200100043102B1040000911 -:100FA00024020018020020210E001697A382004C94 -:100FB0002403FFFF104300182404FFFF0A0019F662 -:100FC000000020218C820010240500010200202155 -:100FD000004310238F83002C240600010E0017E627 -:100FE000AC6200100A0019F6000020210E001799CB -:100FF000240500010A0019F600002021020020212A -:101000002402000D8FBF00148FB0001027BD001800 -:101010000A001697A382004C8FBF00148FB00010F7 -:101020000080102103E0000827BD001827BDFFD86D -:10103000AFB000108F900034AFB3001CAFBF0020E2 -:10104000AFB20018AFB100148E1200103C030800BC -:101050008C6331B032423FFF0043102B1040007CC4 -:10106000008098218F8500382402FF8090A3000D16 -:1010700000431024304200FF5040007602602021DF -:101080000012138230420003240300015443007114 -:101090000260202190A2000D30420008544000035D -:1010A0008F82003C0A001A262402002450400003CC -:1010B0008E03000C0A001A26240200278CA20020AE -:1010C00014620005240200208E0300088CA2002474 -:1010D00010620008240200200E001697A382004C24 -:1010E0002403FFFF1043006A2404FFFF0A001A5183 -:1010F0008F84002C8E0200142411FFFF1451000372 -:101100008F8700280A001A4C240200258E0300183D -:101110008CE2007C146200162402000E8E03002470 -:101120008CA2002814620012240200218E060028DE -:101130008CA2002C14C2000E2402001F8E03002C6F -:101140001060000B240200238CE200680043102B87 -:1011500014400007240200268CA200140066182107 -:101160000043102B504000078F84002C24020022E3 -:101170000E001697A382004C105100452404FFFF77 -:101180008F84002C2403FFF79082000D004310246D -:10119000A082000D8F8600283C0308008C6331ACD0 -:1011A0008F82005094C400E08F85002C00431021F2 -:1011B00030847FFF00042040004410213043007F32 -:1011C000034320213C03000E008320212403FF80E1 -:1011D00000431024AF42002CA49200008CA20028EF -:1011E00024420001ACA200288CA2002C8E03002C0B -:1011F00000431021ACA2002C8E02002CACA20030C7 -:101200008E020014ACA2003494A2003A24420001E1 -:10121000A4A2003A94C600E03C0208008C4231B01F -:1012200024C4000130837FFF14620013008030214A -:10123000240280000082302430C2FFFF000213C26B -:10124000304200FF000210270A001A8E000233C04D -:10125000026020212402000D8FBF00208FB3001CEC -:101260008FB200188FB100148FB0001027BD002876 -:101270000A001697A382004C8F820028026020216A -:10128000240500010E001799A44600E0000020216B -:101290008FBF00208FB3001C8FB200188FB10014D5 -:1012A0008FB000100080102103E0000827BD002847 -:1012B00027BDFFE0AFB100148F910034AFB0001034 -:1012C000AFBF00188E2600103C0308008C6331B0BD -:1012D00030C23FFF0043102B1040005E0080802191 -:1012E0008F8500382402FF8090A3000D0043102456 -:1012F000304200FF50400058020020218F82003C05 -:1013000010400008000613828F8200289763000AAD -:101310002404FFFD944200603042FFFF104300555B -:1013200000061382304200031440000E000000004B -:1013300092220002104000058E2300245060001508 -:10134000922300030A001AC7020020218CA2002465 -:101350005062001092230003020020210A001ACFDD -:101360002402000F90A2000D3042000854400009F2 -:101370009223000302002021240200100E00169781 -:10138000A382004C2403FFFF1043003A2404FFFF14 -:1013900092230003240200025462000C92220003F4 -:1013A0008F82003C54400009922200030200202159 -:1013B0002402002C0E001697A382004C2403FFFF8A -:1013C0001043002C2404FFFF922200030220282156 -:1013D00002002021384600102CC600012C420001DA -:1013E0000E0016B7004630252411FFFF10510021D2 -:1013F0002404FFFF8F83003C1060001202002021B4 -:101400003C0208008C42318C0043102B1440000633 -:1014100000000000000028210E0017E6240600014D -:101420000A001B0D000020212402002D0E0016973B -:10143000A382004C1051000F2404FFFF0A001B0D73 -:10144000000020210E001799240500010A001B0D41 -:1014500000002021020020212402000D8FBF00186F -:101460008FB100148FB0001027BD00200A0016971E -:10147000A382004C8FBF00188FB100148FB00010F2 -:101480000080102103E0000827BD00209383004066 -:1014900027BDFFE024020002AFB10014AFB000107E -:1014A00000808821AFBF0018000080211062008CEE -:1014B0002404FFFD978500428F83004430A2FFFF84 -:1014C0000043102B5440007D8F8400480E001558B7 -:1014D000000000003C020800244279F40220202190 -:1014E000004028210E00171EAF8200342409FFFFA0 -:1014F0001049007B2404FFFF3C0808008D087A0493 -:101500003C0208008C4231B03C030800906379F43F -:1015100031043FFF0082102B1040001B3067003F5A -:101520003C0208008C4231A88F83005000042180C7 -:1015300000621821006418213062007F03422821D4 -:101540003C02000C00A228213C0200803442000131 -:101550003066007800C230252402FF80006210242B -:10156000AF42002830640007AF4208048F82002891 -:101570000344202124840940AF460814AF85002C81 -:10158000AF840038AC430118938300402402000369 -:101590001462003B240200012402002610E2003DF8 -:1015A00028E2002710400013240200322402002207 -:1015B00010E2003828E20023104000082402002432 -:1015C0002402002010E200242402002110E2001E68 -:1015D000022020210A001B8C2402000B10E2002DA7 -:1015E0002402002510E20010022020210A001B8C9A -:1015F0002402000B10E2001A28E20033104000061B -:101600002402003F2402003110E2000B02202021BE -:101610000A001B8C2402000B10E200110220202182 -:101620000A001B8C2402000B0E00187902202021D6 -:101630000A001BA7004080210E0019FB0220202178 -:101640000A001BA7004080210E001A9C02202021C6 -:101650000A001BA7004080211509000E00000000B1 -:101660000E001920022020210A001BA70040802123 -:101670000E001697A382004C0A001BA70040802191 -:1016800014620017020020212402002314E2000546 -:101690002402000B0E001992022020210A001BA731 -:1016A0000040802102202021A382004C0E001697CA -:1016B0002410FFFF0A001BA80200202130A500FF14 -:1016C0000E00159524060001978300428F82004486 -:1016D000A780004200431023AF8200440200202173 -:1016E0008FBF00188FB100148FB000100080102140 -:1016F00003E0000827BD002027BDFFE0AFB10014C4 -:10170000AFBF0018AFB000108F4601283C0308009F -:101710008C6331A02402FF80AF86005000C31821E3 -:101720003065007F03452821006218243C02000A2E -:10173000AF43002400A2282190A2006200808821EB -:10174000AF850028304200FF00021102A382004052 -:1017500090A200BC30420002144000022403003476 -:10176000240300308F820028A3830030938300403D -:101770008C4200C0A380004CAF82004424020004CD -:10178000106200308F8400448E2400045080002DAD -:101790008F8400448E2200103083FFFFA784004214 -:1017A0001060001FAF8200488F8300282405FF804F -:1017B000022020219062006300A21024304200FF2A -:1017C0001440000D000000000E001B139790004213 -:1017D00010400010004018212402FFFD5462001147 -:1017E0008E230020020028210E0015360220202121 -:1017F0000A001BF98E2300209062006300A21024CF -:10180000304200FF10400003022020210E00185B30 -:1018100000000000978200421440FFE48F830028FC -:101820008E23002030620004104000068F840044A4 -:101830002402FFFB006210240E00154AAE22002095 -:101840008F8400448F8300288FBF00188FB100144D -:101850008FB000102402000127BD002003E0000823 -:10186000AC6400C030A500FF2403000124A90001DE -:101870000069102B1040000C00004021240A0001D8 -:1018800000A31023004A38042463000130820001C1 -:101890000069302B1040000200042042010740255F -:1018A00054C0FFF800A3102303E00008010010213A -:1018B00027BDFFE03C021EDCAFB20018AFB1001440 -:1018C000AFBF001CAFB0001034526F410000882140 -:1018D000240500080E001C09022020210011808030 -:1018E0003C07080024E775F40002160002071821DF -:1018F000AC6200000000282124A200013045FFFF57 -:101900008C6200002CA60008044100020002204066 -:101910000092202614C0FFF8AC640000020780216A -:101920008E0400000E001C0924050020262300015F -:101930003071FFFF2E2301001460FFE5AE020000AE -:101940008FBF001C8FB200188FB100148FB0001031 -:1019500003E0000827BD00203C02080024426EB8C6 -:101960003C010800AC2275E83C02080024425430D7 -:101970003C010800AC2275EC240200063C01080082 -:10198000A02275F00A001C1C0000000027BDFFD833 -:10199000AFB3001CAFB20018AFBF0020AFB100144E -:1019A000AFB000108F5101408F48014800089402E9 -:1019B000324300FF311300FF8F4201B80440FFFEA5 -:1019C00027500180AE1100008F420144AE02000496 -:1019D00024020002A6120008A202000B2402001436 -:1019E000AE13002410620025286200151040000884 -:1019F000240200152402001010620030240200129C -:101A0000106200098FBF00200A001D468FB3001C22 -:101A10001062007024020022106200378FBF002085 -:101A20000A001D468FB3001C3C0208008C4231A006 -:101A30002403FF800222102100431024AF4200241F -:101A40003C0208008C4231A0022210213042007F6B -:101A5000034218213C02000A00621821166000BCF3 -:101A6000AF830028906200623042000F34420030A1 -:101A7000A06200620A001D458FBF00203C04600088 -:101A80008C832C083C02F0033442FFFF00621824D0 -:101A9000AC832C083C0208008C4231A08C832C08BB -:101AA0002442007400021082000214800062182593 -:101AB000AC832C080A001D458FBF00203C020800A3 -:101AC0008C4231A02403FF80022210210043102405 -:101AD000AF4200243C0208008C4231A03C03000AC3 -:101AE000022210213042007F0342102100431021C6 -:101AF0000A001D44AF8200283C0208008C4231A03D -:101B00002405FF800222102100451024AF4200244A -:101B10003C0208008C4231A0022210213042007F9A -:101B2000034218213C02000A0062182190620063FF -:101B300000A21024304200FF10400085AF8300282F -:101B400024620088944300123C0208008C4231A8B1 -:101B500030633FFF0003198002221021004310214F -:101B60003043007F03432021004510243C03000C38 -:101B700000832021AF4200289082000D00A2102493 -:101B8000304200FF10400072AF84002C9082000DA4 -:101B9000304200101440006F8FBF00200E00166608 -:101BA000000000008F4201B80440FFFE000000006A -:101BB000AE1100008F420144AE0200042402000274 -:101BC000A6120008A202000BAE1300240A001D4555 -:101BD0008FBF00202406FF8002261024AF42002081 -:101BE0003C0208008C4231A031043FFF00042180F8 -:101BF0000222102100461024AF4200243C030800BA -:101C00008C6331A83C0208008C4231A03227007F4F -:101C10000223182102221021006418213042007F83 -:101C20003064007F034228213C02000A0066182429 -:101C300000A22821034420213C02000C0082202124 -:101C4000AF4300283C02000803471821006290219E -:101C5000AF850028AF84002C0E001666010080219D -:101C60008F4201B80440FFFE8F82002C8F84002831 -:101C7000274501809042000DACB10000A4B00006E1 -:101C8000000216000002160300021027000237C2ED -:101C900014C00016248200889442001232033FFFD1 -:101CA00030423FFF1443001224026082908300639D -:101CB0002402FF8000431024304200FF5040000CFB -:101CC00024026082908200623042000F3442004061 -:101CD000A082006224026084A4A200082402000DF5 -:101CE000A0A200050A001D2F3C02270024026082EA -:101CF000A4A20008A0A000053C02270000061C00CA -:101D00000062182524020002A0A2000BACA3001060 -:101D1000ACA00014ACA00024ACA00028ACA0002C07 -:101D20008E42004C8F84002CACA200189083000DD2 -:101D30002402FF8000431024304200FF10400005C1 -:101D40008FBF00209082000D3042007FA082000DE6 -:101D50008FBF00208FB3001C8FB200188FB100140A -:101D60008FB000103C02100027BD002803E00008DF -:041D7000AF4201B8C5 -:0C1D7400080033F8080033F80800337052 -:101D8000080033A8080033DC0800340008003400E1 -:081D900008003400080032E0F5 -:081D98000A0001220000000016 -:101DA000000000000000000D747061352E302E30F0 -:101DB0006A3600000500000100000000000000007D -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E20000000000010000003000000000000000D92 -:101E30000000000D3C02080024421B803C03080007 -:101E400024632014AC4000000043202B1480FFFDCD -:101E5000244200043C1D080037BD2FFC03A0F021E4 -:101E60003C100800261004883C1C0800279C1B809E -:101E70000E00015A000000000000000D3084FFFF3A -:101E8000308200078F85001810400002248300076D -:101E90003064FFF80085302130C41FFF034418214F -:101EA000247B4000AF85001CAF84001803E00008CD -:101EB000AF4400843084FFFF308200078F8500200C -:101EC0008F86002810400002248300073064FFF84A -:101ED000008520210086182B14600002AF850024A5 -:101EE000008620230344282134068000AF8400208C -:101EF000AF44008000A6202103E00008AF84003832 -:101F000027BDFFD8AFB3001CAFB20018AFB00010B0 -:101F1000AFBF0024AFB40020AFB100143C0860088C -:101F20008D1450002418FF7F3C1A800002989824DA -:101F30003672380CAD1250008F5100083C07601CFF -:101F40003C08600036300001AF500008AF80001838 -:101F5000AF400080AF4000848CE600088D0F080879 -:101F60003C0760168CEC000031EEFFF039CA00101F -:101F70003C0DFFFF340B80003C030080034B4821E5 -:101F80002D440001018D28243C0253533C010800DC -:101F9000AC230420AF890038AF860028AF8400103E -:101FA000275B400014A2000334E37C008CF900049A -:101FB000032818218C7F007C8C6500783C0280000F -:101FC00034520070AF85003CAF9F00403C130800C6 -:101FD00026731BC40240A0218E4800008F460000DB -:101FE00038C300013064000110800017AF8800344E -:101FF000028048218D2D00003C1908008F39045CB7 -:102000003C1108008E31045801A8F823033F7821C1 -:10201000000040210228382101FF802B00F07021B0 -:102020003C010800AC2F045C3C010800AC2E0458B5 -:102030008F4C0000398B0001316A00011540FFED23 -:1020400001A04021AF8D00348E4E00003C0C0800F2 -:102050008D8C045C3C0A08008D4A045801C8682332 -:10206000018D28210000582100AD302B014B20218B -:10207000008610213C010800AC25045C3C010800EE -:10208000AC2204588F4501088F44010030A920007C -:10209000AF850000AF84000C1120000A00A03021A1 -:1020A0003C0708008CE7042C24EF00013C010800E9 -:1020B000AC2F042C3C104000AF5001380A000190B6 -:1020C0000000000030B002001600001424110F00C0 -:1020D0001091001224070D001087023330B0000663 -:1020E0005200FFF53C104000936D0000240C0010DE -:1020F00031A600F010CC0269240E007010CE02DD73 -:102100008F8B001425670001AF8700143C1040003E -:10211000AF5001380A000190000000009748010408 -:102120001100FFE53C10400030B84000170000A24D -:10213000000000008F5901780720FFFE8F870038CC -:1021400024090008240508008CE30008AF45017845 -:10215000A7490140A7400142974201048F86000031 -:102160003049FFFF30DF000113E002D5012040219C -:102170002524FFFE240A0002A74A01463088FFFFFB -:10218000A74401483C0B08008D6B043C156002C459 -:102190008F8F000C30C3002014600002240400095B -:1021A0002404000130CD0C00240C040051AC0001CB -:1021B00034840004A744014A3C0508008CA504208F -:1021C0003C0200483C19000100A2F82530D800026A -:1021D00003F9282513000004000018213C04010025 -:1021E00000A428252403000130CA00045140000542 -:1021F000AF8300083C06001000A628252403000138 -:10220000AF830008AF451000000000000000000090 -:1022100000000000000000008F8300081060002311 -:10222000000000008F4B10000561FFFE0000000061 -:102230001060001E000000008F4D10003C030020C5 -:1022400001A36024118000198F8F000031EE00027D -:1022500011C0001600000000975010141600001363 -:10226000000000009745100830BFFFFF27F8000668 -:102270000018C8820019308000C7282133110001DE -:1022800033030003122003208CA200000000000D85 -:1022900000C7F821AFE200003C1908008F39043074 -:1022A000272600013C010800AC2604308F6A00009C -:1022B0003405FFFFAF8A00048CE200001045029A4B -:1022C000000020218CE5000030BF010013E0027EF9 -:1022D000010020213C0708008CE704743C10080032 -:1022E0008E10044C00E858213C1808008F18047028 -:1022F0000168882B3C0808008D08044800007821FC -:1023000002046021030F18210184702B010F682142 -:102310000071502101AE10213C010800AC2C044C8E -:102320003C010800AC2204483C010800AC2B0474BA -:102330003C010800AC2A04708F8D00180120302168 -:102340003129000725AE000831C21FFF034260217A -:10235000AF8D001CAF820018259B4000AF42008467 -:10236000112000038F90002024C800073106FFF8D9 -:102370008F84002800D0282100A4782B15E00002CB -:10238000AF90002400A428230345202134038000BB -:10239000008310213C061000AF850020AF8200387A -:1023A000AF450080AF4601788F8B00142567000190 -:1023B0000A0001DDAF8700148F6200088F670000FC -:1023C000241100300007C602330300F0107100A290 -:1023D000241900401479FF4B8F8B00148F4A017829 -:1023E0000540FFFE30A7020014E000030005128242 -:1023F0000000000D0005128230500003001049005B -:1024000001307021000E688001B06021000C5880FE -:10241000017380218E0800001500000200000000FA -:102420000000000D8F6F000405E202B19203000668 -:1024300092070005920F00043C020001000728806B -:1024400000B060218D8900182771000825EE000575 -:1024500001226821000E3082AD8D0018022020215B -:102460000E00058026050014920B00068F7F0004E5 -:102470003C087FFF000B2080009130218CC30004BA -:10248000350AFFFF03EAC8240079C021ACD8000454 -:102490009207000592090004960D000800072880A5 -:1024A00000B1F8218FEF0000974201043C07FFFFC5 -:1024B00001E75024304EFFFF01C96021018D5823F0 -:1024C0003168FFFF01482025AFE4000092030007B8 -:1024D00024190001107902692406000310660279AC -:1024E000000000008E190010241F000AA75F0140A1 -:1024F000A7590142920300048F86000024070001BF -:10250000A7430144A74001469758010430D1000277 -:102510003C050041A758014800001821A747014A7F -:102520001220000330CA00043C05014124030001CD -:1025300051400005AF8300083C08001000A8282582 -:1025400024030001AF830008AF4510000000000025 -:102550000000000000000000000000008F8B000859 -:1025600011600004000000008F4410000481FFFE91 -:10257000000000008F6A0000920700043C0508007C -:102580008CA50444AF8A0004975F01043C0F080047 -:102590008DEF044030E300FF33F9FFFF0079C021E5 -:1025A00000B868210000102124E6000A30C8FFFFAF -:1025B00001B8482B01E2702101C9602131100007E8 -:1025C0003C010800AC2D04443C010800AC2C044044 -:1025D000120000038F8D0018250B00073168FFF8EB -:1025E000010D702131CC1FFFAF8D001CAF8C001886 -:1025F000AF4C008497440104034C80213084FFFFDA -:102600003088000711000003261B400024890007C2 -:102610003124FFF88F8200208F850028008220213E -:102620000085782B15E00002AF820024008520236E -:102630000344882134058000022510213C06100047 -:10264000AF840020AF820038AF440080AF460178ED -:102650000A0002858F8B00148F5F017807E0FFFE70 -:1026600030AA020015400003000542820000000D60 -:1026700000054282310200030002710001C268219C -:10268000000D6080018248210009288000B380216C -:102690008E0B000011600002000000000000000D21 -:1026A0008F6F000C05E001F38F87003824190001BB -:1026B000AE1900008CE30008A20000078F78000428 -:1026C00000181C02306600FF24D100050011308282 -:1026D0002CC4004114800002A20300040000000D7D -:1026E0008F6B00043C0EFFFF00E028213164FFFFE8 -:1026F000248F000B000F4082000810800047482103 -:102700008D2D000026040014A60B000801AE6024E5 -:102710000E000580AD2C00008F5F01083C0A100000 -:1027200003EA382410E001A30000000097460104EA -:102730009203000724D1FFEC346500023224FFFF2E -:10274000A2050007960600082CC7001354E00005F8 -:1027500092030007920A0007355F0001A21F0007DD -:1027600092030007240B0001106B01BA2409000337 -:10277000106901CD8F88003830CFFFFF25E40002BB -:102780000004C883333F00FF001F2880A219000502 -:1027900000A858218D780000975101043C03FFFFE9 -:1027A000030360243222FFFF004F702325CDFFFE7C -:1027B000018D4825AD690000920600053C02FFF638 -:1027C000344EFFFF30CA00FF000A388000F020219D -:1027D000909900143C1FFF7F37E7FFFF3323000F62 -:1027E0000066782131F800FF0018288000B08821A9 -:1027F0008E2D002000A86021A20F000601AE482403 -:10280000AE0D000CAD89000C920B00068E04000C7E -:102810000127F824000B50800150C821972600267C -:102820000148C02100874024AF260024AE08000CD8 -:10283000AF3F0020AF0600108F860000240C001070 -:1028400024090002A74C0140A7400142A7400144CF -:10285000A7490146974B01042407000130C8000234 -:10286000256AFFFEA74A01483C050009A747014A1F -:1028700011000003000018213C0501092403000198 -:1028800030CD000451A00005AF8300083C060010C5 -:1028900000A6282524030001AF830008AF451000DF -:1028A0000000000000000000000000000000000028 -:1028B0009218000427110002322F0007000F102386 -:1028C000304E0007AE0E00108F900008120000047A -:1028D000000000008F4310000461FFFE00000000B4 -:1028E0008F7800008F8F00183C1008008E10044471 -:1028F000AF9800049751010425E6001030CA1FFF6D -:102900003222FFFFAF8F001CAF8A0018AF4A00844D -:102910002449FFFE3C0B08008D6B0440974E0104D8 -:1029200001206821000967C3020D282131C9FFFF7A -:1029300000AD402B016C382100E82021034AF8212A -:10294000313900073C010800AC2504443C01080073 -:10295000AC2404401320000327FB4000252300077C -:102960003069FFF88F9F00208F840028013F3821B5 -:1029700000E4C82B17200002AF9F002400E4382396 -:102980000347202134058000008510213C061000FB -:10299000AF870020AF820038AF470080AF46017894 -:1029A0000A0002858F8B0014975801041300FDC2A2 -:1029B0003C1040008F4301780460FFFE30B94000B6 -:1029C000132000033C0400080000000D3C04000834 -:1029D000AF44014024080800AF4801788F8B000005 -:1029E000974A0104317F000113E000E93146FFFFFF -:1029F00024D0FFFE240C0002A74C0146A75001483A -:102A00008F8F00182405000DA745014A8F71000023 -:102A100025E2000830491FFF0349702130CD00072F -:102A2000AF910004AF8F001CAF89001800C038219F -:102A3000AF49008411A0000325DB400024C6000735 -:102A400030C7FFF88F9800208F84002800F83021CD -:102A500000C4382B14E00002AF98002400C43023D7 -:102A60008F8A001403465821340880000168F82139 -:102A7000255900013C0310003C104000AF860020A7 -:102A8000AF9F0038AF460080AF430178AF99001484 -:102A9000AF5001380A000190000000008F6900006B -:102AA000974401043127FFFF3088FFFF8F4F0178E3 -:102AB00005E0FFFE30FF0007001F182330780007F5 -:102AC00024E6FFFE2419000AA7590140A758014235 -:102AD000A7460144A7400146A74801488F42010884 -:102AE00030510020162000022403000924030001B5 -:102AF00030AA0002A743014A3C04004111400003F0 -:102B0000000018213C0401412403000130AB000403 -:102B100051600005AF8300083C05001000852025AA -:102B200024030001AF830008AF4410000000000040 -:102B30000000000000000000000000008F9000086E -:102B400012000004000000008F4C10000581FFFE01 -:102B5000000000008F780000276200088F8D003C85 -:102B6000AF980004944600089451000A944F000C5A -:102B700030CEFFFF0011240031E9FFFF11CD00A28C -:102B8000008920253C0308008C6304443C1808009D -:102B90008F18044000E85021255FFFFE007F782158 -:102BA0000000102101FF302B03028821022648215A -:102BB0003C010800AC2F04443C010800AC2904404F -:102BC00024EB00083162FFFF3047000710E00003EC -:102BD0008F850018245000073202FFF83106FFFFEE -:102BE00030C800070045702131CD1FFF034D602123 -:102BF000AF85001CAF8D0018259B4000AF4D0084B1 -:102C0000110000038F8F002024C400073086FFF8D6 -:102C10008F84002800CF282100A4482B1520000213 -:102C2000AF8F002400A42823AF850020AF4500808B -:102C30003C1108008E3104340345C0213402800069 -:102C40000302302112200005AF860038938300175D -:102C50002419000E1079000D241F043F3C0A1000B7 -:102C6000AF4A01788F8B0014256700010A0001DD4F -:102C7000AF8700140E0005A63C1040008F8B001497 -:102C8000256700010A0001DEAF8700143C0A10002E -:102C9000A75F0148AF4A01780A0004B48F8B001483 -:102CA000240E0F0011EE003D30D10020162000024E -:102CB00024030009240300010A000208A743014A73 -:102CC0000A0001FBA740014694E5000894E2000ACF -:102CD00094EB000C8F86003C0002FC00316AFFFF81 -:102CE00030B9FFFF1326003703EA20253C05080012 -:102CF0008CA504443C1F08008FFF044000005021B5 -:102D000000A8382100E8302B03EAC8210326C0219F -:102D10003C010800AC2704443C010800AC380440E6 -:102D20000A0002698F8D00183C1908008F39047C55 -:102D30003C0308008C6304543C0608008CC60478ED -:102D40003C0F08008DEF04500328382100686821EB -:102D500000E8C02B00C4882101A8402B01E47021A9 -:102D60000238582101C860213C010800AC2D0454F0 -:102D70003C010800AC2C04503C010800AC27047C4A -:102D80003C010800AC2B04780A0002698F8D001802 -:102D9000A74001460A00041B8F8F001830D0002086 -:102DA0001600FFC52403000D240300050A000208D5 -:102DB000A743014A975901042738FFF00A00036B23 -:102DC0003304FFFF8F8C0040148CFFC8000080216B -:102DD0003C1108008E31046C3C0408008C840468AB -:102DE0000228702101C8782B00904021010F682132 -:102DF0003C010800AC2E046C3C010800AC2D0468BA -:102E00000A0002698F8D00188F9900401499FF5DA8 -:102E1000000060213C0508008CA5046C3C100800F3 -:102E20008E10046800E82021248EFFFE00AEF821F9 -:102E300003EE582B020C5021014B18213C010800D5 -:102E4000AC3F046C3C010800AC2304680A00048B0E -:102E500024EB00088F8800383C02FFFF8D0E000C29 -:102E600001C2682401A46025AD0C000C0A0003799E -:102E700030CFFFFF0A0003A9AE000000974B01040A -:102E8000920400048E2A000C01644021251FFFF2E9 -:102E90000147182433F9FFFF0079C025AE38000C34 -:102EA0000A0002D48E1900103C03FFFF8D110010A0 -:102EB0000223282400A47825AD0F00100A0003790E -:102EC00030CFFFFF97450104920600048E2F0010BB -:102ED00000A610212449FFEE01E76824312EFFFFF0 -:102EE00001AE6025AE2C00100A0002D48E1900102D -:102EF0008E06000CAE0000000003C0800310882185 -:102F00000A0002A6AE2600201460000D3050FFFF1C -:102F10003C04FFFF0044602401846826000D582B08 -:102F2000000C502B014B1024104000020000000048 -:102F30000000000D8CA300000A00023E0064102572 -:102F40003A11FFFF0011782B0010702B01CF2024C5 -:102F500010800002000000000000000D8CB800008E -:102F60000A00023E3702FFFF3084FFFF30A5FFFF5B -:102F7000108000070000182130820001104000027C -:102F800000042042006518211480FFFB0005284042 -:102F900003E000080060102110C0000700000000DE -:102FA0008CA2000024C6FFFF24A50004AC82000010 -:102FB00014C0FFFB2484000403E0000800000000AC -:102FC00010A0000824A3FFFFAC8600000000000052 -:102FD000000000002402FFFF2463FFFF1462FFFAD9 -:102FE0002484000403E0000800000000308EFFFF8E -:102FF00030D8FFFF00057C0001F8602539CDFFFFC8 -:1030000001AC5021014C582B014B482100094402CE -:103010003127FFFF00E830210006240230C5FFFF02 -:1030200000A418213862FFFF03E000083042FFFFD0 -:103030003C0C08008D8C0484240BFF8027BDFFD03E -:1030400001845021014B4824AF4900203C0808006E -:103050008D080484AFB20020AFB00018AFBF0028C5 -:10306000AFB30024AFB1001C936600040104382103 -:1030700030E4007F009A10213C03000800439021B7 -:1030800030C50020036080213C080111277B000827 -:1030900014A00002264600702646006C921300041D -:1030A00097510104920F00043267000F322EFFFF88 -:1030B00031ED004001C7282311A000050000482180 -:1030C000925900BC33380004170000900000000043 -:1030D000924300BC307F000413E0000F00000000AA -:1030E00010A0000D00000000960E0002240AFF80D0 -:1030F00000A7602125CDFFFEA74D1016920B0004FE -:10310000014B2024308200FF10400085010C402537 -:103110003C0F0400010F40258F5301780660FFFE2D -:103120002404000AA7440140960D0002240400096B -:1031300031AC0007000C5823316A0007A74A01424E -:10314000960200022443FFFEA7430144A740014624 -:10315000975F0104A75F01488F59010833380020A9 -:103160005300000124040001920F000431EE00100E -:1031700015C000023483001000801821A743014AC3 -:10318000000000000000000000000000000000003F -:10319000AF48100000000000000000000000000028 -:1031A000000000008F5110000621FFFE3113FFFFC9 -:1031B00012600003000000008F481018ACC8000027 -:1031C00096030006307FFFFF27F90002001998825E -:1031D00000138880023B30218CD800001520005756 -:1031E00000183402920300042405FF8000A3F82491 -:1031F00033F100FF1220002C00000000924700BCB9 -:1032000030F200021240002800000000974B100C22 -:103210002562FFFEA7421016000000003C0A0400D1 -:1032200035490030AF4910000000000000000000E8 -:1032300000000000000000008F4C10000581FFFE20 -:10324000000000009749100C8F51101C00C0202175 -:103250003127FFFF24F2003000121882000328807B -:1032600000BBF8213226FFFFAFF100000E000595EC -:1032700000112C020013C880033B98218E780000B7 -:1032800000027400AFB800108FA80010310FFFFFCC -:10329000AFAF00108FA4001001C46825AFAD0010BF -:1032A0008FA60010AE66000097730008976D000AA5 -:1032B0009766000C8F8A003C000D5C0030CCFFFF4D -:1032C0003262FFFF104A0036016C2025960600028C -:1032D0003C10100024D300080E0001393264FFFFB7 -:1032E000974C01040E0001473184FFFFAF50017875 -:1032F0008FBF00288FB300248FB200208FB1001C35 -:103300008FB0001803E0000827BD003010A0FF7048 -:103310000000000024A5FFFC0A0005CE24090004DB -:103320008CD10000AF5110188F5301780660FF7ADE -:103330002404000A0A0005E30000000000A7C821D9 -:103340008F8800388F4E101C0019C08200187880BA -:1033500001E82021AC8E0000000E2C0200C02021CC -:103360000E00059531C6FFFF023B28218CAD000001 -:103370000002540000403021AFAD00108FAC0010AF -:10338000318BFFFFAFAB00108FA200100142482528 -:10339000AFA900108FA700100A000613ACA7000009 -:1033A0008F8F0040148FFFC9000000009742010476 -:1033B000960B00023C0508008CA5046C3049FFFF09 -:1033C000316AFFFF3C1108008E310468012A382160 -:1033D00024F2FFFE00B240210012FFC30112C82BED -:1033E000023FC021031920213C010800AC28046CD5 -:1033F0003C010800AC2404680A00064D00000000EF -:1034000000A4102B104000092403000100052840EF -:1034100000A4102B04A00003000318405440FFFC3C -:103420000005284010600007000000000085302BD8 -:1034300014C0000200031842008520231460FFFB23 -:103440000005284203E00008008010218F85002C31 -:1034500027BDFFE8000530272CC300012CA4000283 -:103460000083102510400003AFBF00102405007F2B -:10347000AF85002C0005282730A5FFFF0E0005743E -:10348000240426F58F830030240402BD004030213F -:103490000083382B10E000092405000100042040BF -:1034A0000083102B04800003000528405440FFFCDB -:1034B0000004204010A0000800C350210064402BED -:1034C00015000002000528420064182314A0FFFB29 -:1034D0000004204200C350218FBF0010000A4C029C -:1034E000312200FF27BD0018AF8A002C03E000083E -:0434F000AF89003070 -:0C34F4000A00002A000000000000000098 -:103500000000000D747870352E302E306A360000C1 -:10351000050000000000000A000001360000EA601B -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:103550000000000000000016000000000000000055 -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:1035800000000000000000000000000000001388A0 -:1035900000000000000005DC00000000000000004A -:1035A00010000003000000000000000D0000000DEE -:1035B0003C02080024423B603C03080024633D14A5 -:1035C000AC4000000043202B1480FFFD2442000487 -:1035D0003C1D080037BD7FFC03A0F0213C10080013 -:1035E000261000A83C1C0800279C3B600E0002BA75 -:1035F000000000000000000D8F8300383C088000B0 -:10360000350700708CE50000008330253C029000F7 -:1036100000C22025AF850030AF4400208F49002034 -:103620000520FFFE3C038000346200708C450000E2 -:103630008F8600303C1908008F39007C3C0E080052 -:103640008DCE007800A62023032458210000782185 -:103650000164682B01CF6021018D50213C010800DD -:10366000AC2B007C3C010800AC2A007803E0000889 -:10367000000000000A000041240400018F8400388B -:103680003C05800034A200010082182503E00008F8 -:10369000AF43002003E00008000010213084FFFF4A -:1036A00030A5FFFF108000070000182130820001C4 -:1036B0001040000200042042006518211480FFFB26 -:1036C0000005284003E000080060102110C000073A -:1036D000000000008CA2000024C6FFFF24A5000407 -:1036E000AC82000014C0FFFB2484000403E0000847 -:1036F0000000000010A0000824A3FFFFAC8600001B -:1037000000000000000000002402FFFF2463FFFF10 -:103710001462FFFA2484000403E0000800000000A3 -:10372000308AFFFF93A80013A74A014497490E1659 -:1037300030C600FF3C021000A7490146AF450148D2 -:10374000A3460152A748015AAF4701608FA4001851 -:103750008FA30014A7440158AF43015403E00008AD -:10376000AF42017803E00008000000003C03800045 -:10377000346200708C4900008F88000024840007A8 -:1037800027BDFFF83084FFF8AF890030974D008ADD -:1037900031ACFFFFAFAC00008FAB000001685023DD -:1037A0002547FFFF30E61FFF00C4282B14A0FFF7BA -:1037B0003C0C8000358B00708D6A00003C070800CF -:1037C0008CE700843C0608008CC60080000810824C -:1037D000014918230002788000E3702100002021B5 -:1037E00001C3C82B00C4C02101FA4021031948219C -:1037F0002502400027BD00083C010800AC2E0084D3 -:103800003C010800AC29008003E000080000000033 -:103810008F8200002486000730C5FFF800A218211F -:1038200030641FFF03E00008AF8400008F8700387A -:103830008F8A004027BDFFB88F860044AFB6004096 -:10384000AFBF0044AFB5003CAFB40038AFB30034F5 -:10385000AFB20030AFB1002CAFB000288F450104EB -:103860008D4900ACAF4700808CC8002000A93823E8 -:103870000000B021AF480E108F440E100000482108 -:10388000AF440E148CC20024AF420E188F430E18A2 -:10389000AF430E1C10E001252D230001936B00089F -:1038A000116000D400000000976E001031CDFFFFC2 -:1038B00000ED602B158000CF000000009770001015 -:1038C000320FFFFFAF4F0E008F5200003251000841 -:1038D0001220FFFD0000000097540E088F460E04D2 -:1038E0003285FFFF30B3000112600132000000009A -:1038F0000000000D30B8A04024150040131500C092 -:1039000030A9A0001120012D00000000937F0008C5 -:1039100013E000080000000097630010306BFFFF09 -:1039200000CB402B1100000330AC0040118001237C -:1039300000000000A785003CAF86003493660008B5 -:1039400000E02821AFA7002014C0012427B30020E5 -:10395000AF60000C9782003C3047400014E000024A -:10396000240300162403000E24194007A363000A51 -:10397000AF790014938A003E8F7400143158000709 -:103980000018AA4002959025AF7200149784003C5D -:103990008F7000143091001002117825AF6F001461 -:1039A000978E003C31CD000811A00147000028216E -:1039B0008F6700143C0210003C0C810000E22825B7 -:1039C000AF65001497460E0A2408000E3405FFFC6C -:1039D00030C3FFFF006C5825AF6B0004A3680002E2 -:1039E000937F000A27E90004A369000A9786003C38 -:1039F0009363000A30CC1F00000C598301634021FF -:103A0000251F0028A37F000997490E0CA769001005 -:103A100093790009272A0002315800070018A823CB -:103A200032B10007A371000B937400099764001072 -:103A30008F910034978F003C329200FF0244802126 -:103A40000205702131ED004011A0000531C4FFFFD7 -:103A50000091282B3C12800010A000140000A0212F -:103A60000224382B14E0011B8FA500208F4D0E146B -:103A7000AF4D0E108F420E1CAF420E18AF440E0019 -:103A80008F4F000031EE000811C0FFFD0000000064 -:103A900097540E080080882100009021A794003CD4 -:103AA0008F500E0424140001AF900034976400106E -:103AB0003095FFFF8E6800000111F82317E0000920 -:103AC000AE7F00008F6500148F8B004434A6004049 -:103AD000AF6600148F4C0E10AD6C00208F430E1893 -:103AE000AD6300249367000814E000D200000000DA -:103AF0000E00009E240400108F8900483C0832000C -:103B000000402821312600FF0006FC0003E8502574 -:103B100025390001AF990048AC4A000093780009AC -:103B20009370000A330400FF00047400320F00FF9A -:103B300001CF6825AC4D00048F820048064000EAA2 -:103B4000ACA20008ACA0000C9783003C306B0008CE -:103B5000156000022628000626280002974E0E1443 -:103B60008F450E1C8F670004936D000231C4FFFF68 -:103B700031A200FFAFA200108F6C0014AFA8001894 -:103B80000E00008BAFAC0014240400100E0000C720 -:103B9000000000008E7200001640000500000000CA -:103BA0008F6400142405FFBF00859824AF730014B0 -:103BB0008F79000C03353821AF67000C937500082E -:103BC00016A000080000000012800006000000009F -:103BD0008F7F00143C0BEFFF3568FFFE03E848249D -:103BE000AF690014A37400088FA500200A000246E4 -:103BF00002202021AF470E000A0000F5000000005F -:103C00008F5901780720FFFE241F08008F840000D1 -:103C1000AF5F0178974B008A316AFFFF0144482368 -:103C20002528FFFF31021FFF2C4300081460FFF915 -:103C3000000000008F8E00488F8D003800C04821A2 -:103C40000344202125C60001240C0F00AF86004844 -:103C500000E938232486400031CA00FF11AC00057A -:103C6000240800019391003E3230000700107A4092 -:103C700035E80001000AAC003C18010002B8A0259C -:103C8000AC9440008F93004830B2003630A4000856 -:103C9000ACD300041080009701123025974E0E0A15 -:103CA0008F8D00003C02810031CCFFFF25AB000866 -:103CB000018240253C03100031651FFF25390006B5 -:103CC000241F000EAF48016000C33025A75F015AD2 -:103CD000AF850000A759015814E0000A8F930038FF -:103CE00024120F00527200022416000134C6004054 -:103CF0008F580E108F940044AE9800208F550E18E8 -:103D0000AE9500248F450E14AF4501448F590E1C0B -:103D1000AF590148A34A01523C0A1000AF46015472 -:103D2000AF4A017814E0FEDD2D2300010076A025C6 -:103D3000128000178FBF00448F84003824160F00B4 -:103D400010960084000000008F45017804A0FFFE5B -:103D500024150F001095006E000000008F470E1410 -:103D6000240202403C1F1000AF4701448F440E1C48 -:103D7000AF440148A3400152A740015AAF4001603F -:103D8000A7400158AF420154AF5F01788FBF004494 -:103D90008FB600408FB5003C8FB400388FB300342D -:103DA0008FB200308FB1002C8FB0002803E00008E4 -:103DB00027BD004814C0FED030B8A0408F420E147A -:103DC0008F84004400004821AC8200208F510E1CDB -:103DD000AC9100240A00020E2D2300018F910034C3 -:103DE000978A003C3C1280000220A82131580040F4 -:103DF0001700FF300000A021976900108F92003457 -:103E00003139FFFF133200350000202100804821A6 -:103E10001480FEA000A038218F420E148F8400442D -:103E2000AC8200208F510E1CAC9100240A00020EBF -:103E30002D230001936A00099378000B315000FF95 -:103E4000330F00FF020F702125C2000A3050FFFF20 -:103E50000E00009E020020218F8600483C1F41007A -:103E600024CD0001AF8D0048936C000930C600FFDF -:103E700000064400318300FF246B0002010B48253B -:103E8000013FC825AC5900008F67000C97440E1401 -:103E900000F22825AC4500048F450E1C8F670004F6 -:103EA000936A00023084FFFF315800FFAFB8001062 -:103EB0008F6F0014AFB100180E00008BAFAF00146D -:103EC0000A0001A602002021AF6000040A00013EA2 -:103ED000A36000020A000246000020210000902199 -:103EE0000A000170241400013C1280000A000195B0 -:103EF000ACB2000C8F91000025240002A7440158A9 -:103F000026300008320F1FFF0A0001F9AF8F0000B2 -:103F1000AF40014C1120002C000000008F590E1002 -:103F2000AF5901448F430E18240200403C1F10007B -:103F3000AF430148A3400152A740015AAF4001607E -:103F4000A7400158AF420154AF5F01780A00022731 -:103F50008FBF0044112000060000000097460E08A5 -:103F600030CC004015800002000000000000000D71 -:103F70008F4D017805A0FFFE0000000097530E1042 -:103F80003C120500240E2000326AFFFF0152C025BA -:103F9000AF58014C8F4F0E143C021000AF4F01443C -:103FA0008F500E1CAF500148A34001528F8400383F -:103FB000A740015AAF400160A7400158AF4E0154DD -:103FC0000A000215AF4201788F490E14AF4901442F -:103FD0008F430E1C0A00028E240200403C0E20FF7C -:103FE00027BDFFE03C1A80003C0F800835CDFFFD67 -:103FF000AFBF001CAFB20018AFB10014AFB00010DB -:10400000AF8F0040AF4D0E00000000000000000028 -:104010000000000000000000000000003C0C00FF59 -:10402000358BFFFDAF4B0E003C0660048CC9500081 -:10403000240AFF7F3C116000012A40243507380C18 -:10404000ACC750008E24043824050009AF45000891 -:104050003083FFFF38622F712450C0B3AF80004817 -:104060000E000068AF80000052000001AE20442C1A -:104070000E0004353C1180000E000EA83630007092 -:104080008F8A00403C12080026523BC8020088215B -:104090008E0800008F5F00003BF9000133380001FB -:1040A00013000017AF880030022048218D27000040 -:1040B0003C0F08008DEF006C3C0C08008D8C0068F4 -:1040C00000E8C02301F828210000682100B8302B47 -:1040D000018D5821016640213C010800AC25006C8F -:1040E0003C010800AC2800688F44000038830001C0 -:1040F000306200011440FFED00E04021AF87003046 -:104100008E0C00003C0508008CA5006C3C040800E7 -:104110008C8400680188302300A63821000010211B -:1041200000E6402B008218210068F8213C010800BD -:10413000AC27006C3C010800AC3F00688F490100CF -:1041400025590088AF990044AF890038AF49002055 -:104150008E070000AF8700308F4D017805A0FFFE6D -:10416000000000008E0600003C0B08008D6B007400 -:104170003C0408008C84007000C728230165F821E6 -:104180000000102103E5402B0082382100E8C821FF -:10419000240908003C010800AC3F00743C01080001 -:1041A000AC390070AF49017893580108A398003EDC -:1041B000938F003E31EE000115C000158F8300384B -:1041C000240E0D00106E0019240F0F00106F001D3B -:1041D000000000009159000024180050332900FF0E -:1041E000113800043C1F4000AF5F01380A0002E7AD -:1041F000000000000E0008EE000000008F8A004062 -:104200003C1F4000AF5F01380A0002E700000000D9 -:10421000938D003E31AC0006000C51000E0000CE24 -:104220000152D8210A0003438F8A00403C1B08003A -:10423000277B3C480E0000CE000000000A0003432C -:104240008F8A00403C1B0800277B3C680E0000CE94 -:10425000000000000A0003438F8A004090AA00017A -:104260008FAB00108CAC00103C0300FF8D68000485 -:10427000AD6C00208CAD001400E060213462FFFFC3 -:10428000AD6D00248CA700183C09FF000109C02473 -:10429000AD6700288CAE001C0182C8240319782564 -:1042A000AD6F0004AD6E002C8CAD0008314A00FFEC -:1042B000AD6D001C94A900023128FFFFAD6800100D -:1042C00090A70000A5600002A1600004A1670000A3 -:1042D00090A30002306200FF000219821060000506 -:1042E000240500011065000E0000000003E0000836 -:1042F000A16A00018CD80028354A0080AD780018EA -:104300008CCF0014AD6F00148CCE0030AD6E000861 -:104310008CC4002CA16A000103E00008AD64000C0D -:104320008CCD001CAD6D00188CC90014AD69001453 -:104330008CC80024AD6800088CC70020AD67000C55 -:104340008CC200148C8300640043C82B1320000728 -:10435000000000008CC20014144CFFE400000000B8 -:10436000354A008003E00008A16A00018C820064E5 -:104370000A0003990000000090AA000027BDFFF882 -:104380008FA9001CA3AA00008FAE00003C0FFF8085 -:104390008FA8001835E2FFFF8CCD002C01C26024ED -:1043A000AFAC0000A120000400E06021A7A0000243 -:1043B0008FB800008D2700040188182100A0582123 -:1043C00000C05021006D28263C06FF7F3C0F00FFF7 -:1043D0002CAD000135EEFFFF34D9FFFF3C02FF009A -:1043E00003193024000D1DC0010EC82400E2C024B2 -:1043F00000C3702503197825AD2E0000AD2F0004F1 -:104400008D450024AFAE0000AD2500088D4D002085 -:104410002405FFFFAD2D000C956800023107FFFF5A -:10442000AD2700109166001830C200FF000219C2CB -:10443000506000018D450034AD2500148D670008E3 -:1044400027BD0008AD27001C8C8B00CCAD2C0028AC -:10445000AD20002CAD2B0024AD20001803E0000897 -:10446000AD20002027BDFFE0AFB20018AFB10014AF -:10447000AFB00010AFBF001C9098000000C08821B2 -:104480003C0D00FF330F007FA0CF0000908E000195 -:1044900035ACFFFF3C0AFF00A0CE000194A6001E31 -:1044A000A22000048CAB00148E29000400A08021FF -:1044B000016C2824012A4024008090210105202538 -:1044C000A6260002AE2400042605002026240008AB -:1044D0000E00007624060002924700002605002800 -:1044E0002624001400071E000003160324060004FF -:1044F000044000032403FFFF965900023323FFFF0B -:104500000E000076AE230010262400248FBF001C6E -:104510008FB200188FB100148FB000102405000373 -:10452000000030210A00008027BD002027BDFFD8F1 -:10453000AFB1001CAFB00018AFBF002090A80000C2 -:10454000240200018FB0003C3103003F008088212D -:10455000106200148FAA0038240B0005506B00165F -:10456000AFAA001000A0202100C028210E0003DC0B -:1045700002003021922400BC30830002106000034E -:1045800026060030ACC0000024C600048FBF002007 -:104590008FB1001C8FB0001800C0102103E000088C -:1045A00027BD0028014038210E00035AAFB000108B -:1045B0000A000420000000000E0003A1AFB00014A8 -:1045C0000A000420000000003C02000A03421821F7 -:1045D0003C04080024843CAC2405001A000030216F -:1045E0000A000080AF8300543C03800034620070F6 -:1045F0008C48000000A0582100C04821308A00FFEC -:10460000AF8800308F4401780480FFFE3C0C8000AE -:10461000358600708CC500003C0308008C63007474 -:104620003C1808008F18007000A82023006468213F -:104630000000C82101A4782B0319702101CF60214B -:104640003C010800AC2D00743C010800AC2C00704B -:104650008F480E14AF480144AF47014CA34A0152A2 -:10466000A74B01589346010830C5000854A000012B -:1046700035291000934B090024070050316A00FFD0 -:1046800011470007000000008F450E1CAF45014890 -:10469000AF4901543C09100003E00008AF4901781C -:1046A000934D010831A8000811000010000000001F -:1046B000934F010831EE001051C000013529000868 -:1046C0003C04080090843D10A34401508F4309A48A -:1046D000AF4301488F4209A0AF420144AF490154A2 -:1046E0003C09100003E00008AF4901783C190800BC -:1046F0008F393CCC333800085700FFF135290008CA -:104700000A0004730000000024070040AF470814AB -:10471000AF4008108F4209448F4309508F44095419 -:104720008F45095C8F46094CAF820064AF8300500F -:10473000AF84004CAF85005C03E00008AF860060EA -:104740009346010930C5007F000518C000052140CF -:104750000083102103E00008244200883C0A08007E -:10476000914A3CD13C09080095293CCA3C051100FE -:10477000000A3C002528000200E8302500C5182565 -:1047800024820008AC83000003E00008AC80000431 -:104790008F4A002C974E09083C0F000E034F38211A -:1047A00031CDFFFF000D41C0AF48002C97430908F1 -:1047B00094EC001A0080402124020001318BFFFF9D -:1047C000AC8B00008CE9001C00A0582100C06021C7 -:1047D000AC8900048CE40020AD04000890E30019CB -:1047E00030630003106200400000000028650002F2 -:1047F00014A00073240600021066004E00000000A2 -:104800002418000310780057000000003C0908003D -:1048100095293CC093450934934609213C0E080074 -:1048200095CE3CC630A200FF0002C88294E5002A63 -:1048300030C400FF978700580019C60000041C0010 -:10484000312FFFFF0303102501CF6821004DC8253C -:1048500000A720213C0640000326C02500044C0090 -:10486000AD090004AD180000934F09203C03000679 -:1048700025090014000F760001C36825AD0D00085E -:104880008F42092C24E5000130A67FFFAD02000C09 -:104890008F59093025020028A7860058AD1900104D -:1048A0008F440938AD040014AD2B00048F58094023 -:1048B000AD380008934F09373C0D080091AD3CD04E -:1048C000AD20001031EE00FF01CC1821000367007D -:1048D000000D4400018858253567FFFFAD27000C07 -:1048E00003E00008AF4A002C3C09080095293CC0B1 -:1048F0003C05080094A53CCA3C0F080095EF3CBC61 -:1049000094E400243126FFFF00A6702101CF682324 -:1049100000041C0025A2FFF20062C825241808002C -:10492000AD19000CAD180014AD0000100A0004C849 -:104930002508001894E6002494E500283C090800A6 -:1049400095293CC000067C000005740035ED81000F -:1049500035C40800AD0D000CAD0400100A0004C8F9 -:10496000250800143C09080095293CC03C020800B9 -:1049700094423CCA3C06080094C63CBC94E4002423 -:104980003125FFFF94F800280045C821032678232D -:1049900000181C0000046C0025EEFFEE006EC82518 -:1049A00035A2810024180800AD02000CAD190010DA -:1049B000AD180018AD0000140A0004C82508001C3A -:1049C0001460FF920000000094E300243C090800FA -:1049D00095293CC00003140034590800AD19000C9F -:1049E0000A0004C82508001003E00008240201F4AE -:1049F00027BDFFE8AFB00010AFBF00140E0000608D -:104A00000080802124050040AF4508148F830050AA -:104A10008F84004C8F85005C007018210064102387 -:104A200018400004AF830050AF6300548F660054F9 -:104A3000AF86004C1200000C000000008F44007490 -:104A4000936800813409FA002D07000710E0000583 -:104A500000891021936C0081240B01F4018B500418 -:104A600001441021AF62000C8F4E095C01C5682320 -:104A700019A000048FBF00148F4F095CAF8F005C3A -:104A80008FBF00148FB000100A00006227BD00180D -:104A90008F8400648F8300508F82004CAF64004489 -:104AA000AF63005003E00008AF6200543C03800095 -:104AB000346200708C43000027BDFFF8308700FF90 -:104AC00030A900FF30C800FFAF8300308F44017869 -:104AD0000480FFFE3C028000345900708F380000D3 -:104AE000A3A700033C0708008CE700748FAC00000C -:104AF0003C0608008CC60070030378233C0E7FFF41 -:104B000000EFC82135CDFFFF00005021018D282482 -:104B100000CA1821000847C0032F202B00A8102529 -:104B20000064C021AFA200003C010800AC39007451 -:104B30003C010800AC380070934F010AA3A00002AA -:104B40003C0E80FFA3AF00018FAC0000312B007F33 -:104B500035CDFFFF018D4824000B5600012A40256A -:104B6000240730002406FF803C05100027BD000804 -:104B7000AF48014CAF470154A7400158A34601522A -:104B800003E00008AF45017827BDFFE8AFBF001480 -:104B9000AFB000108F6500743C068000309000FFBD -:104BA00000A620250E000060AF640074936300052A -:104BB000346200080E000062A3620005020020219A -:104BC0008FBF00148FB000102405000524060001DB -:104BD0000A00056E27BD001827BDFFE03C038000DA -:104BE000AFB00010AFBF0018AFB100143462007056 -:104BF0008C470000309000FF30A800FFAF870030E6 -:104C00008F4401780480FFFE3C188000371100704B -:104C10008E2F00003C0D08008DAD00743C0A08008A -:104C20008D4A007001E7702301AE28210000582151 -:104C300000AE302B014B4821012638213C010800F1 -:104C4000AC250074000088213C010800AC270070EE -:104C50001100000F000000008F6200742619FFFF92 -:104C60003208007F0002FE0233E5007F15000006D7 -:104C7000332200FF2407FF800207202624A3FFFF22 -:104C800000838025320200FF00408021241110089B -:104C90000E000060000000008F4908183125000454 -:104CA00014A0FFFD3218007F001878C00018714072 -:104CB00001CF682125AC0088AF4C0818274A09802D -:104CC0008D4B0020AF4B01448D460024AF46014878 -:104CD000A35001500E000062A7400158022010218D -:104CE0008FBF00188FB100148FB0001003E00008D0 -:104CF00027BD002027BDFFE8308400FFAFBF0010B4 -:104D00000E0005B930A500FF8F8300508FBF001043 -:104D1000344500402404FF903C02100027BD0018D9 -:104D2000AF43014CA3440152AF45015403E00008D6 -:104D3000AF4201789343093E306200081040000DF5 -:104D40003C0901013528080AAC8800008F4700742F -:104D5000AC8700043C06080090C63CD030C500106B -:104D600050A00006AC8000088F6A0060AC8A000882 -:104D70002484000C03E00008008010210A000620B3 -:104D80002484000C27BDFFE8AFBF0014AFB00010B3 -:104D90009346093F00A05021000528800085382354 -:104DA00030C200FF240300063C09080095293CC6D8 -:104DB00024E8FFD82405000410430037240600022D -:104DC0009750093C3C0F020400063400320EFFFFEE -:104DD00001CF6825AC8D0000934C093E318B00203B -:104DE0001160000800000000934309363C020103F3 -:104DF000345F0300307900FF033FC025240500081D -:104E0000AC98000493430934935909210005F882B2 -:104E1000306200FF0002C082332F00FF00186E00D6 -:104E2000000F740001AE6025018920253C09400077 -:104E300000898025ACF0FFD8934309378F4F09488C -:104E40008F580940306200FF004AC821033F70219B -:104E500001F86023000E6F0001A650253185FFFF89 -:104E6000001F58800145482501683821AD09002000 -:104E70000E00006024F00028240400040E000062EC -:104E8000A364003F020010218FBF00148FB00010F8 -:104E900003E0000827BD00180A00063324060012AC -:104EA00027BDFFD024090010AFB60028AFB50024FD -:104EB000AFB40020AFB10014AFB000103C01080047 -:104EC000A0293CD0AFBF002CAFB3001CAFB200187C -:104ED00097480908309500FF3C02000E3107FFFF9C -:104EE000000731C0AF46002C974409089344010BDA -:104EF00030B400FF03428021308300300000B02135 -:104F00001060010700008821240C00043C01080007 -:104F1000A02C3CD0934B093E000B5600000A2E03F8 -:104F200004A0014B00000000AF400048934F010B6C -:104F300031EE002011C00006000000009358093E29 -:104F400000189E00001396030640016B000000004D -:104F50009344010B30830040106000038F93005096 -:104F60008F8200502453FFFF9347093E30E600082C -:104F700014C0000224120003000090219619002C96 -:104F800093580934934F0937A7990058330C00FF01 -:104F900031EE00FF024E6821000D5880016C502157 -:104FA000015140213C010800A4283CC6920500188C -:104FB00030A900FF010918213C010800A4233CC8C6 -:104FC00092110018162000032467000A0000000D4B -:104FD0002467000A30F0FFFF3C010800A4233CCA0C -:104FE0003C010800A4203CC03C010800A4203CBCBB -:104FF0000E00009E020020210E00049A0040202195 -:105000008F4B002C974A09083C0C000E034C3821AA -:105010003145FFFF000549C0AF49002C97430908FF -:1050200094F1001A00404021241F00013226FFFFA6 -:10503000AC4600008CE2001CAD0200048CE40020B1 -:10504000AD04000890E3001930630003107F00D620 -:10505000286D000215A0011C240E0002106E010E26 -:10506000240F0003106F00E3000000003C0908005B -:1050700095293CC0934E0934935109213C0A0800FC -:10508000954A3CC631CD00FF94F9002A000D1882E4 -:1050900097870058322C00FF00032E00000C2400DC -:1050A0003126FFFF3142FFFF00A4F82500464821CA -:1050B00003E97825032770213C18400001F8682592 -:1050C000000E8C00AD0D0000AD110004934C0920C2 -:1050D0003C03000625110014000C2E0000A310252F -:1050E000AD0200088F49092C24E40001309F7FFFA6 -:1050F000AD09000C8F46093025090028A79F0058EC -:10510000AD0600108F59093801203021AD19001467 -:10511000AE3300048F580940AE380008934F09376A -:105120003C0C0800918C3CD0AE20001031EE00FF0A -:1051300001D26821000D2F00000C1C0000A31025D7 -:105140003447FFFFAE27000CAF4B002C934B093EBA -:10515000317300081260000D3C0F010135E7080AA9 -:10516000AD0700288F4B0074AD2B00043C130800E2 -:1051700092733CD03268001051000003AD2000084B -:105180008F780060AD3800082526000C12C000386A -:1051900000000000935F093F241600062407000466 -:1051A00033F900FF133600D2240800029743093C6C -:1051B0003C0C02043064FFFF008C2825ACC50000C5 -:1051C0009342093E304900201120000800000000F1 -:1051D000934B09363C130103366E0300316D00FF1B -:1051E00001AE8825ACD10004240700089349093496 -:1051F00093590921314BFFFF313F00FF001FB0825F -:10520000333800FF0016560000187C00014F982527 -:1052100000122880026B68253C0E400000C5502318 -:1052200001AE8825AD51FFD8934309378F5F0948F8 -:105230008F490940306C00FF019210210007208245 -:105240000044C82103E978230019C7000008B4000E -:105250000316402531E7FFFF010730250E000060EF -:10526000AD46FFF8241200040E000062A372003F56 -:105270000E0000C7020020213C12080092523CD0D0 -:10528000325000031200000F02A020218F82005034 -:1052900024470001AF870050AF6700508F6800546B -:1052A0000107302318C0000200E020218F64005461 -:1052B000AF6400548F4C0074258401F4AF64000C7B -:1052C00002A0202102802821A76000680E0005B9F5 -:1052D0003C1410008F8D005034550006AF4D014C2A -:1052E0008F9100488FBF002C8FB600282623000125 -:1052F000AF8300488FB3001CA35101528FB2001836 -:10530000AF5501548FB10014AF5401788FB500240C -:105310008FB400208FB0001003E0000827BD0030DC -:105320009358093E00189E00001396030642005150 -:105330002411000293440923308300021060FEFB15 -:105340008F8600608F82005014C2FEF800000000BB -:105350000E000060000000009369003F2407001663 -:10536000312800FF1107000C240500083C0C080040 -:10537000918C3CD0358B00013C010800A02B3CD027 -:10538000936A003F314300FF10650065240D000A59 -:10539000106D005E2402000C0E0000620000000090 -:1053A0000A00068E000000003C09080095293CC058 -:1053B0003C04080094843CCA3C1F080097FF3CBC96 -:1053C00094F800243123FFFF0083C821033F782392 -:1053D00000186C0025EEFFF201AE6025240A0800DB -:1053E000AD0C000CAD0A0014AD0000100A0006E080 -:1053F000250800183C09080095293CC03C1F0800FE -:1054000097FF3CCA3C19080097393CBC94EF002434 -:105410003124FFFF94EE002803E4C0210319682320 -:10542000000F2C00000E540025ACFFEE014C882527 -:1054300034A2810024060800AD02000CAD1100105A -:10544000AD060018AD0000140A0006E02508001C97 -:105450008F6E00848F4D094011A0FEB3AF8E0050B7 -:10546000240F00143C010800A02F3CD00A00068D38 -:10547000000000003C010800A0313CD0935F093ED1 -:105480002416000133F900201720FEA8241100087B -:105490000A00068E2411000494E5002494F10028EB -:1054A0003C09080095293CC0000514000011340097 -:1054B0003444810034C30800AD04000CAD03001077 -:1054C0000A0006E0250800141460FEE80000000051 -:1054D00094FF00243C09080095293CC0001FCC0023 -:1054E00037380800AD18000C0A0006E02508001047 -:1054F0000A00072E240800128F7F004CAF7F005453 -:105500008F7900540A000697AF790050A362003FDC -:105510000E000062000000000A00068E000000007D -:10552000240200140A000807A362003F27BDFFE819 -:10553000308400FFAFBF00100E0005B930A500FF9A -:105540009378007E9379007F936E00809368007A51 -:10555000332F00FF00186600000F6C0031CB00FFF6 -:10556000018D4825000B52008FBF0010012A3825FD -:10557000310600FF3444700000E628252402FF8134 -:105580003C03100027BD0018AF45014CAF44015447 -:10559000A342015203E00008AF43017827BDFFD8C2 -:1055A000AFB20018AFB10014AFB00010AFBF002011 -:1055B000AFB3001C93420109308600FF30B000FFFA -:1055C000000618C232040002307100011480000588 -:1055D000305200FF9367000530E5000810A0000D71 -:1055E00030C80010024020210E0005A5022028210D -:1055F000240400018FBF00208FB3001C8FB200185D -:105600008FB100148FB000100080102103E000085B -:1056100027BD002815000032000000009343010957 -:10562000000028213062007F000220C00002F94003 -:1056300003E4982126790088033B98218E78002482 -:105640008E6F0008130F0046000000008F64008476 -:10565000241800020004FD8233F900031338007C93 -:105660000000000093660083934A0109514600043C -:105670003205007C10A00060000000003205007CB4 -:1056800014A000530240202116200006320400011D -:105690008E7F00248F59010417F9FFD600002021C6 -:1056A000320400011080000A024020218F4209408C -:1056B0008F93006410530006000000000E00066B7C -:1056C000022028218F430940AF630044024020217B -:1056D0000E000600022028210A00084024040001D0 -:1056E0003C0908008D290064252600013C010800C2 -:1056F000AC26006416000012000000008F6D0084CC -:105700003C0E00C001AE602415800005024020213F -:105710000E00080E022028210A000840240400017F -:10572000240500040E00056E24060001024020211D -:105730000E00080E022028210A000840240400015F -:105740000E00004124040001936B007D020B5025E4 -:105750000E000062A36A007D0A0008838F6D00843A -:105760008F6600748F4801048E67002400064E0285 -:105770001507FFB63126007F936B00832644000196 -:10578000308A007F11460043316300FF5464FFB04C -:105790008F6400842645000130B1007F30A200FFF5 -:1057A0001226000424050001004090210A0008563A -:1057B00024110001240FFF80024F702401CF902696 -:1057C000324200FF004090210A00085624110001D7 -:1057D0000E00066B02202821321800301300FFAAA9 -:1057E00032100082024020210E0005A5022028214F -:1057F0000A000840240400018F6E00743C0F8000F2 -:105800002405000301CF9025AF72007493710083CB -:10581000240600010E00056E322400FF0E00004138 -:1058200024040001936D007D020D60250E000062CE -:10583000A36C007D3C0B08008D6B005425700001AB -:105840003C010800AC3000540A0008402404000168 -:105850008F6800743C098000240500040109382584 -:10586000AF67007493630083240600010E00056E89 -:10587000306400FF0E000041240400019362007DAB -:10588000020298250E000062A373007D0A00084002 -:1058900024040001324D008039AC0080546CFF6C50 -:1058A0008F6400840A0008A92645000127BDFFC8AF -:1058B0003C0A0008AFBF0030AFB5002CAFB40028E1 -:1058C000AFB30024AFB20020AFB1001CAFB00018DE -:1058D000034AD82124090040AF490814AF400810FA -:1058E0008F4209448F4309508F4609548F47095C02 -:1058F0008F48094C934401089345010BAF82006423 -:10590000308400FF30A500FFAF830050AF86004C0D -:10591000AF87005C0E00082AAF8800601440017455 -:105920008FBF0030A7600068934D0900240B005022 -:105930003C15080026B53C8831AC00FF3C1208003D -:1059400026523C98118B0003000000000000A821A3 -:1059500000009021935101098F9F005024040010F2 -:10596000322E007F000E68C0000E6140018D28219C -:1059700024B40088AF5408188F4901048F4A09A441 -:105980003C0B000E034BC021012A10233C010800F0 -:10599000AC223CAC8F4309583C010800A0243CD009 -:1059A00097470908007F30233C010800AC263CB033 -:1059B00030E8FFFF0008C9C03C010800AC3F3CD400 -:1059C000AF59002C974209089710002C8EB10000A7 -:1059D000930F001803749821A7900058AF930044C8 -:1059E0000220F80931F000FF304E000215C001A975 -:1059F000304F000111E0015D000000009343093EBB -:105A00003066000814C00002241400030000A02126 -:105A10008F5809A4241300013C010800AC383CD87D -:105A2000934F09349351093731EC00FF322E00FFB8 -:105A3000028E6821000D288000AC502101505821B1 -:105A40003C010800A42B3CC83C010800A42A3CC629 -:105A500093490934312200FF0202202124900010D2 -:105A60003C010800A4303CC4240700068F9F00506E -:105A70003C010800AC273CCC8F88005C8F5909584A -:105A800000008021011F282304A00151033F20238F -:105A90000480014F00A4302B10C001510000000011 -:105AA0003C010800AC253CB08E4200000040F809E3 -:105AB0000000000030430002146000F10040882123 -:105AC00030440001548000108E4200043C0908005C -:105AD0008D293CB43C0AC000012A8025AF500E003D -:105AE0008F45000030AB00081160FFFD0000000092 -:105AF000974D0E0824100001A78D003C8F4C0E041A -:105B0000AF8C00348E4200040040F8090000000011 -:105B100002228825322E000215C0016F000000000D -:105B20003C09080095293CBC3C06080094C63CC8CA -:105B30003C04080094843CBE3C1808008F183CB418 -:105B4000012658213C0F08008DEF3CD83C1F08006F -:105B500097FF3CD2016418218F4D09400309C821E9 -:105B6000246E0002033F282101F860213C01080057 -:105B7000A42B3CCAAF8D00643C010800AC2C3CD87F -:105B80003C010800A4253CC00E00009E31C4FFFF6C -:105B90008F870048004020213C010800A0273CD10D -:105BA0008E42000824E80001AF8800480040F80950 -:105BB000000000008F4B002C974909083C0A000E9A -:105BC000034A38213124FFFF000419C08F8A005096 -:105BD000AF43002C9743090894E6001A0040402187 -:105BE00030DFFFFFAC5F00008CF9001CAC590004F3 -:105BF0008CF80020AC58000890EF001931E3000346 -:105C0000107300FB0000000028620002144001171E -:105C10002405000210650109240C0003106C00BC6F -:105C2000000000003C09080095293CC0935F09343E -:105C3000934C09213C0D080095AD3CC633F900FF9B -:105C400094E5002A0019C082318F00FF978C00581C -:105C500000181600000F74003124FFFF004E382595 -:105C600001A4302100E6F82500ACC8213C03400027 -:105C700003E3C02500194C00AD180000AD09000475 -:105C8000934F09203C0E000625090014000F6E00FA -:105C900001AE2825AD0500088F46092C258200019C -:105CA00030477FFFAD06000C8F440930A7870058AE -:105CB00025060028AD0400108F43093800C02021BC -:105CC000AD030014AD2A00048F5F0940AD3F00080A -:105CD000935909373C0E080091CE3CD0AD200010FE -:105CE000333800FF03147821000F6700000E6C00AA -:105CF000018D282534A2FFFFAD22000CAF4B002CF4 -:105D00009347093E30EA00085140000F8E58000CBE -:105D10003C0301013469080AAD0900288F4A007468 -:105D2000ACCA00043C0B0800916B3CD031680010F9 -:105D300051000003ACC000088F650060ACC50008CE -:105D400024C4000C8E58000C0300F8090000000069 -:105D50003C0F080095EF3CCA3C02080094423CBE50 -:105D600001E2702125C400020E0000C73084FFFF4D -:105D70003C0608008CC63CAC3C0D08008DAD3CB424 -:105D800000CD38233C010800AC273CAC14E00006F1 -:105D9000000000003C1908008F393CCC372C004033 -:105DA0003C010800AC2C3CCC120000858F8B0044D9 -:105DB0008F480E108F900044AE0800208F5F0E18A1 -:105DC000AE1F00243C10080096103CC00E0000607E -:105DD0000000000024050040AF4508148F830050E8 -:105DE0008F89004C0070182100695023194000046D -:105DF000AF830050AF6300548F670054AF87004CEF -:105E00001200000C000000008F440074936D0081AC -:105E1000340EFA002DA6000710C00005008E1821D0 -:105E200093780081240201F40302780401E418212C -:105E3000AF63000C8F4C095C8F99005C01992023A3 -:105E400018800003000000008F50095CAF90005CD8 -:105E50000E000062000000008F8B00508E48001082 -:105E60003C010800AC2B3CD40100F8090000000004 -:105E70003C1F08008FFF3CAC17E0FEFC2407000627 -:105E80008F450024974209088F8A00648F94005040 -:105E90003C0F001F978700588F8300548F93004C4E -:105EA000304DFFFF35EEFF8000AE4824000D31C0BD -:105EB00032320010AF460024A467002CAF49002402 -:105EC000AF6A0044AF740050AF7300545640007E78 -:105ED0008EB8000432240040548000328EB1000895 -:105EE0008EAC000C0180F809000000008FBF00306C -:105EF0008FB5002C8FB400288FB300248FB2002000 -:105F00008FB1001C8FB0001803E0000827BD0038D7 -:105F10003C09080095293CC03C04080094843CCA14 -:105F20003C1F080097FF3CBC94F800243123FFFF7E -:105F300094EF00280083C821033F702300182C0031 -:105F4000000F640025CDFFEE018D302534A28100C5 -:105F500024030800AD02000CAD060010AD030018CC -:105F6000AD0000140A0009CE2508001C9347010962 -:105F70008F8800380007FE0003E8C825AF5900806D -:105F80008F5809A08F5309A4AFB80010AF580E1452 -:105F90008FB40010AF540E10AF530E1C0A0009420C -:105FA000AF530E180220F809000000008EAC000C60 -:105FB0000180F809000000000A000A7F8FBF00304E -:105FC000A5600020A57300220A000A34AD730024E6 -:105FD0003C010800AC203CB00A00096E8E42000073 -:105FE0003C010800AC243CB00A00096E8E4200005F -:105FF0003C09080095293CC03C1F080097FF3CCA9B -:106000003C19080097393CBC94EF00243124FFFF71 -:1060100003E4C02103197023000F640025CDFFF2B3 -:10602000018D2825AC45000C24020800AD020014A7 -:10603000AD0000100A0009CE2508001894E60024DF -:1060400094E300283C09080095293CC00006240080 -:106050000003FC003499810037F80800AD19000CEA -:10606000AD1800100A0009CE250800141460FEEDDA -:106070000000000094EF00243C09080095293CC072 -:10608000000F740035CD0800AD0D000C0A0009CEDC -:106090002508001093520109000028210E00060077 -:1060A000324400FF8FBF00308FB5002C8FB4002822 -:1060B0008FB300248FB200208FB1001C8FB0001866 -:1060C00003E0000827BD00380300F80900000000C5 -:1060D0000A000A79322400401200FF690000000023 -:1060E0008F540E148F920044AE5400208F530E1C18 -:1060F0000A000A63AE5300248F82001C00804021F6 -:106100003C0401009047008530E300201060000946 -:10611000000000003C0708008CE73CD48F83001887 -:1061200000E32023048000089389000414E30003A3 -:106130000100202103E00008008010213C04010040 -:1061400003E00008008010211120000B00673823B5 -:106150008F8C002024090034918B00BC316A00022E -:10616000514000012409003000E9682B15A0FFF11F -:106170000100202100E938232419FFFC00B9C024C4 -:1061800000F9782400F8702B15C0FFEA01E82021FF -:1061900030C200030002182314C00012306900034B -:1061A0000000302100A9702101C6682100ED602B9C -:1061B0001180FFE03C0401002D2F00010006482B58 -:1061C0000105382101E9302414C0FFDA24E4FFFC82 -:1061D0002419FFFC00B9C0240308202103E00008B3 -:1061E000008010218F8B002024060004916A00BCDF -:1061F000314400041480FFEC00A970210A000B2D2B -:106200000000302127BDFFE8AFBF00108F4601001E -:10621000934A01093C1F08008FFF00902407FF806C -:10622000314F00FF31E8007F0008614003E6C821DC -:10623000032CC02127090120012770243C010800FC -:10624000A02F3D10AF4E080C3C0D08008DAD009006 -:106250003C0400803482000301A65821016C1821FF -:106260002465012030AA007801424025AF48081C6F -:106270003C1F08008FFF00908F88004003E6C0217C -:106280003319000703074824033A7821AF4900284F -:1062900025E909C0952E00023C0D08008DAD008C4B -:1062A0003C0A08008D4A009031CC3FFF01A618211E -:1062B000000C5980006B282100A72024AF44002C3B -:1062C000952200023C1F08008FFF008C910700857B -:1062D00030593FFF03E678210019C1800146702143 -:1062E00001F8682131CC007F31AB007F019A282171 -:1062F000017A50213C03000C3C04000E00A328212D -:106300000144102130E6002027470980AF82002C8D -:10631000AF88001CAF890024AF85002010C00006A4 -:10632000AF8700288D0200508CA4010C004430235C -:1063300018C0007700000000910C0085240DFFDFDD -:10634000018D3824A10700858F8B001C8F890024C4 -:106350008F8700288D65004CAF850018912F000DA8 -:1063600031EE002011C000170000000024090001D8 -:10637000A3890004AF80000C8CE400248F85000CFE -:10638000240A0008AF800008AF8000103C0108001C -:10639000A42A3CBE3C010800A4203CD20E000B0104 -:1063A000000030218F8500248FBF0010AF820014C1 -:1063B00090A8000D27BD00180008394203E000082E -:1063C00030E20001913F00022418000133F900FF80 -:1063D0000019218210980039240800021088005BFF -:1063E0008F86002C8CE5002414A0001B8F9F0020BA -:1063F00091220000240A00053046003F10CA0047E1 -:10640000240400018F860008A3840004AF860010D6 -:10641000AF86000C8CE400248F85000C240A000851 -:106420003C010800A42A3CBE3C010800A4203CD248 -:106430000E000B01000000008F8500248FBF0010AC -:10644000AF82001490A8000D27BD00180008394243 -:1064500003E0000830E200018CF800088CF9002409 -:106460008FEE00C4A38000048CE40024AF8E000CE7 -:106470008F85000C8F86000803197823240A0008F2 -:10648000AF8F00103C010800A42A3CBE3C0108006C -:10649000A4203CD20E000B01000000008F850024D8 -:1064A0008FBF0010AF82001490A8000D27BD001808 -:1064B0000008394203E0000830E2000191230000A7 -:1064C0003062003F104400278F8500208CE40024B8 -:1064D00014800021000000008D2E00183C187FFF62 -:1064E0008F850020370FFFFF01CF1824AF830008EE -:1064F0008F9F00088CA8008403E8C82B1720000297 -:1065000003E020218CA400840A000BBCAF840008A7 -:106510008CA3010C0A000B9AAF8300188D2C001875 -:106520008F8600083C0D7FFF8F89002035A3FFFF79 -:106530000183582424040001AF8B0010AD2000CC4F -:10654000A38400040A000BC8AF86000C8CCA001498 -:106550000A000BBCAF8A00088CA300C80A000BFF1E -:10656000AF8300088F84002C8CAC00648C8D0014E9 -:10657000018D582B11600004000000008CA2006403 -:106580000A000BFFAF8200088C8200140A000BFF88 -:10659000AF8200088F85000C27BDFFE0AFBF001859 -:1065A000AFB1001414A00007AFB000108F86002414 -:1065B0002402000590C400003083003F106200B642 -:1065C0008F8400208F91000800A080218F8C0028EC -:1065D0003C0508008CA53CB08D8B000431663FFF64 -:1065E00000C5502B5540000100C02821938D0004A8 -:1065F00011A0007300B0F82B8F9800202404003401 -:10660000930F00BC31EE000251C0000124040030A1 -:1066100000A4C82B172000D10000000000A42823EC -:1066200000B0F82B3C010800A4243CBC17E0006833 -:10663000020020213C0308008C633CAC0083102B3B -:1066400054400001008018218F8800243C0108007C -:10665000AC233CB4000048219104000D308300209D -:10666000506000018F490E188F8300140123382BCE -:1066700010E00059000000003C0408008C843CB489 -:1066800000895821006B502B114000560090602B60 -:106690000069302300C020213C010800AC263CB436 -:1066A00012000003241FFFFC1090008A3227000311 -:1066B000009FC8243C010800AC393CB43C010800F0 -:1066C000A4203CD28F84000C120400078F8300208A -:1066D000AF910008020020218C7100CCAF90000C1B -:1066E00026300001AC7000CC3C0208008C423CB467 -:1066F0008F8A0010240700180082202301422823DB -:10670000AF84000C10800002AF8500102407001039 -:106710008F86001C3C010800A0273CD024070040C5 -:1067200090CC0085318B00C0116700408F8D001424 -:1067300014A0001500002021934A01098F4209741A -:10674000314500FF0002260224A300013090007FA3 -:106750003071007F1230007A2407FF80A0C30083CD -:106760003C0908008D293CCC8F880024240D0002B0 -:10677000352C00083C010800A02D3D113C0108000B -:10678000AC2C3CCC24040010910E000D31C600202E -:1067900010C0000500801821240800013C010800F9 -:1067A000AC283CB4348300018FBF00188FB10014B3 -:1067B0008FB000100060102103E0000827BD00200A -:1067C0003C010800A4203CBC13E0FF9A02002021F9 -:1067D0000A000C5000A020213C0408008C843CB42A -:1067E0000090602B1180FFAE000000003C0F0800FD -:1067F00095EF3CBC01E4702101C6682B11A0000795 -:106800002C8200043C1F60008FF954043338003F91 -:106810001700FFE5240300422C8200041040FFA073 -:10682000240300420A000CAE8FBF0018152DFFC0D4 -:10683000000000008CDF00743C0380002405FF8012 -:1068400003E3C825ACD9007490D80085240E000459 -:1068500024040010330F003F01E54025A0C8008547 -:106860008F8800243C010800A02E3D112403000164 -:106870009106000D30C90020152000030000000023 -:106880003C0308008C633CB43C010800AC233CACE6 -:106890000A000CA5000000008F8700108C8800847F -:1068A00000E8282B14A0000200E088218C910084CD -:1068B00024090001A38900048F440E180220282116 -:1068C0000E000B0102203021022080210A000C362C -:1068D000AF82001400071823306600033C01080053 -:1068E000A4263CD2122000058F8C0020918B00BC86 -:1068F000316A00041540001524CD00043C0F080047 -:1069000095EF3CD201E4702100AE302B50C0FF6EF9 -:106910008F84000C2C85000514A0FFA324030042E3 -:106920003098000317000002009818232483FFFC0E -:106930003C010800AC233CB40A000C7200000000CB -:1069400000A758240A000C9A016718263C01080089 -:10695000A42D3CD20A000D02000000003C010800FA -:10696000AC203CB40A000CAD240300428F8300101D -:1069700014600007000010218F8800242405000502 -:106980009106000030C400FF1085000300000000E5 -:1069900003E0000800000000910A0018314900FFE0 -:1069A000000939C214E0FFFA8F85001C3C0408007E -:1069B00094843CBC3C0308008C633CD43C19080024 -:1069C0008F393CB43C0F080095EF3CD20064C021E5 -:1069D0008CAD00540319702101CF6021018D582323 -:1069E0001960001D00000000910E001C8F8C002C0F -:1069F000974B0E1031CD00FF8D850004016D3023C3 -:106A00008D88000030CEFFFF000E510000AAC82183 -:106A10000000382101072021032A182B0083C02100 -:106A2000AD990004AD980000918F000A01CF682154 -:106A3000A18D000A8F88002C974B0E12A50B000821 -:106A4000950A003825490001A50900389107000D75 -:106A500034E60008A106000D03E000080000000075 -:106A600027BDFFE0938700048F8F00248FAD0014B3 -:106A70003C0E7FFF8F89000C35C8FFFFAFBF001CA5 -:106A8000AFB0001801A8182491EA000D000717C044 -:106A90003C1FBFFF006258252D2E00018F9000186B -:106AA00037F9FFFF3C1808008F183CD43C0F080052 -:106AB00095EF3CCA01796824000E47803C07EFFF40 -:106AC0003C05F0FF01A818253149002034E2FFFF02 -:106AD00034ACFFFF0310582327A500102406000242 -:106AE00025EA00020062182400808021152000029F -:106AF000000040218F480E1CA7AA00120560003735 -:106B00002407000030FF00FF001FCF008F8B001C08 -:106B100000793825AFA70014916F00853C08080064 -:106B200091083CD13C18DFFF31EE00C0370AFFFF6F -:106B3000000E182B3C1F080097FF3CC400EA682495 -:106B4000A3A800110003174001A248258FB9001027 -:106B5000AFA900143C0A0800914A3CD3A7BF001615 -:106B60008FA80014032CC0243C0B01003C0F0FFF26 -:106B7000030B18253147000335EEFFFF010C682495 -:106B800000071600006EF8243C09700001A2C82519 -:106B900003E95825AFB90014AFAB00100E00007622 -:106BA000A3A000158F8C0024260200089186000DFA -:106BB00030C40020108000068FBF001C3C05080078 -:106BC00094A53CC024B0FFFF3C010800A4303CC0A9 -:106BD0008FB0001803E0000827BD00208F98001434 -:106BE0000118502B5540FFC7240700010A000D85EE -:106BF00030FF00FF9382000427BDFFE0AFBF001805 -:106C00001040000F008050218F880024240B0005C5 -:106C10008F890008910700008F840020010028213F -:106C200030E3003F8F86002C106B000800003821F5 -:106C3000AFA900100E00040EAFAA0014A380000438 -:106C40008FBF001803E0000827BD00208D19001831 -:106C50003C0F08008DEF3CB48F9800103C027FFF82 -:106C60008D080014345FFFFF033F682401F8702192 -:106C700001AE602301883821AFA900100E00040E78 -:106C8000AFAA00140A000DD3A38000048F8700244C -:106C90003C05080094A53CD23C0208008C423CCC48 -:106CA00090E6000D0005240030C300201060002C89 -:106CB000004440258F85001C00006021240B00014A -:106CC00090A3008500004821240A00013C0F8000A9 -:106CD00035EE00708DC70000AF8700308F58017807 -:106CE0000700FFFE3C038000347900708F380000FD -:106CF0003C0508008CA500743C0D08008DAD0070AB -:106D00000307782300AF38210000102100EF302B5B -:106D100001A22021008618213C010800AC27007444 -:106D20003C010800AC230070AF4B01483C1908003F -:106D30008F393CD4A7490144A74A0146AF59014CB9 -:106D40003C0B0800916B3CD1A34B0152AF4801545E -:106D50003C081000A74C015803E00008AF48017838 -:106D60008F4B0E1C3C0A08008D4A3CB497490E1606 -:106D7000974D0E1401456021312AFFFF0A000DF6E0 -:106D800031A9FFFF8F8300249064000D3082002022 -:106D900010400029000000000000482100005021A0 -:106DA000000040213C07800034EB00708D6700003C -:106DB000AF8700308F4C01780580FFFE3C0D8000CE -:106DC00035AC00708D8B00003C0508008CA500746C -:106DD0003C0408008C8400700167302300A67821F1 -:106DE0000000102101E6C82B0082C0210319702188 -:106DF0003C010800AC2F00743C010800AC2E007070 -:106E0000AF4901483C0D08008DAD3CD4A748014472 -:106E100024090040A74A01463C081000240AFF91BB -:106E2000AF4D014CA34A0152AF490154A74001584C -:106E300003E00008AF4801788F490E1897460E12FC -:106E400097450E1030CAFFFF0A000E2C30A8FFFF36 -:106E50008F83002427BDFFF89064000D308200204E -:106E60001040003A00000000240B000100004821FF -:106E7000240A00013C088000350700708CE3000004 -:106E8000AF8300308F4C01780580FFFE3C0E800000 -:106E90003C04080090843D1035C700708CEC000065 -:106EA0003C0508008CA50074A3A400033C1908004D -:106EB0008F3900708FAD00000183302300A6382188 -:106EC000000010210322782100E6C02B01F8602188 -:106ED00001AE4025AFA800003C010800AC270074BB -:106EE0003C010800AC2C00709346010A3C040800E9 -:106EF00090843D11A3A00002A3A600018FA300006F -:106F00003C0580FF3099007F34A2FFFF00627824A7 -:106F10000019C60001F87025240D3000AF4E014C59 -:106F200027BD0008AF4D0154A7400158AF4B0148A1 -:106F3000A7490144A74A01463C091000240AFF80E2 -:106F4000A34A015203E00008AF4901788F4B0E18A5 -:106F500097460E1297450E1030CAFFFF0A000E60CA -:106F600030A9FFFF8F85001C2402008090A40085BB -:106F7000308300C0106200058F8600208F880008D3 -:106F80008F87000CACC800C8ACC700C403E0000881 -:106F9000000000003C0A0800254A38903C0908001F -:106FA0002529395C3C08080025082D103C070800FD -:106FB00024E73A703C06080024C637003C05080068 -:106FC00024A534783C040800248430A03C03080045 -:106FD000246337983C0208002442356C3C010800C9 -:106FE000AC2A3C903C010800AC293C8C3C010800D8 -:106FF000AC283C883C010800AC273C943C010800CC -:10700000AC263CA43C010800AC253C9C3C0108009B -:10701000AC243C983C010800AC233CA83C0108008F -:0C702000AC223CA003E0000800000000CF -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex new file mode 100644 index 000000000000..e9bbdc3b0397 --- /dev/null +++ b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex @@ -0,0 +1,5815 @@ +:10000000080001180800000000004A68000000C84D +:1000100000000000000000000000000008004A6826 +:100020000000001400004B30080000A00800000091 +:100030000000568800004B4408005800000000846F +:100040000000A1CC08005688000001580000A25012 +:100050000800321008000000000072D00000A3A8C1 +:10006000000000000000000000000000080072D046 +:100070000000002400011678080004900800040025 +:10008000000017D40001169C0000000000000000D2 +:100090000000000000000000000000000000000060 +:1000A000080000A80800000000003BFC00012E70C2 +:1000B0000000000000000000000000000000000040 +:0800C000000000000000000038 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E302E31E1 +:1000E0003500000006000F020000000000000003C1 +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C02080024424AA03C03080015 +:1002000024634B9CAC4000000043202B1480FFFD76 +:10021000244200043C1D080037BD7FFC03A0F021F0 +:100220003C100800261001183C1C0800279C4AA01E +:100230000E000168000000000000000D27470100CB +:1002400090E3000B2402001A94E5000814620028D1 +:10025000000020218CE200003C0308008C63004475 +:1002600094E60014000211C20002104030A4000203 +:10027000005A10212463000130A50004A446008028 +:100280003C010800AC23004410A000190004202BFE +:100290008F4202B804410008240400013C02080017 +:1002A0008C420060244200013C010800AC22006046 +:1002B00003E00008008010218CE2002094E3001687 +:1002C00000002021AF4202808CE20004A743028498 +:1002D000AF4202883C021000AF4202B83C02080064 +:1002E0008C42005C244200013C010800AC22005C0E +:1002F00003E00008008010212747010090E3000B75 +:100300002402000394E50008146200280000202164 +:100310008CE200003C0308008C63004494E6001467 +:10032000000211C20002104030A40002005A102145 +:100330002463000130A50004A44600803C010800AD +:10034000AC23004410A000190004202B8F4202B8F7 +:1003500004410008240400013C0208008C420060B3 +:10036000244200013C010800AC22006003E00008C8 +:10037000008010218CE2002094E300160000202170 +:10038000AF4202808CE20004A7430284AF4202889D +:100390003C021000AF4202B83C0208008C42005CF4 +:1003A000244200013C010800AC22005C03E000088C +:1003B000008010218F4301002402010050620003DD +:1003C000000311C20000000D000311C20002104022 +:1003D000005A1021A440008003E000080000102112 +:1003E0009362000003E00008AF80000003E0000813 +:1003F0000000102103E00008000010212402010089 +:1004000014820008000000003C0208008C4200FC3E +:10041000244200013C010800AC2200FC0A0000DD7F +:1004200030A200203C0208008C42008424420001DB +:100430003C010800AC22008430A2002010400008DB +:1004400030A300103C0208008C4201082442000145 +:100450003C010800AC22010803E000080000000095 +:1004600010600008000000003C0208008C420104FB +:10047000244200013C010800AC22010403E0000812 +:10048000000000003C0208008C42010024420001F0 +:100490003C010800AC22010003E00008000000005D +:1004A00027BDFFE8AFBF0010274401009483000878 +:1004B000306200041040001B306600028F4202B818 +:1004C00004410008240500013C0208008C42006041 +:1004D000244200013C010800AC2200600A0001290E +:1004E0008FBF00108C82002094830016000028210A +:1004F000AF4202808C820004A7430284AF4202888C +:100500003C021000AF4202B83C0208008C42005C82 +:10051000244200013C010800AC22005C0A000129D1 +:100520008FBF001010C00006006028218F4401001A +:100530000E0000CD000000000A0001282405000183 +:100540008F8200088F4301045043000700002821D8 +:100550008F4401000E0000CD000000008F42010416 +:10056000AF820008000028218FBF001000A01021DA +:1005700003E0000827BD001827BDFFE8AFBF001447 +:10058000AFB00010974201083043700024022000F1 +:100590001062000B286220011440002F000010217F +:1005A00024024000106200250000000024026000C8 +:1005B00010620026000010210A0001658FBF0014A0 +:1005C00027500100920200091040001A2403000184 +:1005D0003C0208008C420020104000160000182148 +:1005E0000E00049300000000960300083C0608007B +:1005F00094C64B5E8E0400188F8200209605000C76 +:1006000000031C0000661825AC440000AC45000443 +:1006100024040001AC400008AC40000CAC400010C9 +:10062000AC400014AC4000180E0004B8AC43001CF1 +:10063000000018210A000164006010210E0003254B +:10064000000000000A000164000010210E000EE905 +:1006500000000000000010218FBF00148FB00010B8 +:1006600003E0000827BD001827BDFFE0AFB2001867 +:100670003C036010AFBF001CAFB10014AFB000105E +:100680008C6450002402FF7F3C1A800000822024EA +:100690003484380C24020037AC6450003C1208004B +:1006A00026524AD8AF42000824020C80AF420024F0 +:1006B0003C1B80083C06080024C60324024010218D +:1006C0002404001D2484FFFFAC4600000481FFFDCC +:1006D000244200043C020800244204B03C0108000B +:1006E000AC224AE03C020800244202303C010800EF +:1006F000AC224AE43C020800244201743C03080096 +:100700002463032C3C040800248403D83C0508001F +:1007100024A538F03C010800AC224B403C02080004 +:10072000244202EC3C010800AC264B243C010800AA +:10073000AC254B343C010800AC234B3C3C01080089 +:10074000AC244B443C010800AC224B483C0108005F +:10075000AC234ADC3C010800AC204AE83C0108001C +:10076000AC204AEC3C010800AC204AF03C010800F7 +:10077000AC204AF43C010800AC204AF83C010800D7 +:10078000AC204AFC3C010800AC204B003C010800B6 +:10079000AC244B043C010800AC204B083C01080091 +:1007A000AC204B0C3C010800AC204B103C01080075 +:1007B000AC204B143C010800AC204B183C01080055 +:1007C000AC264B1C3C010800AC264B203C01080029 +:1007D000AC254B303C010800AC234B380E000623FF +:1007E000000000003C028000344200708C42000097 +:1007F000AF8200143C0308008C6300208F82000449 +:10080000104300043C0280000E00045BAF83000430 +:100810003C028000344600703C0308008C6300A05A +:100820003C0208008C4200A4104300048F84001492 +:100830003C010800AC2300A4A743009E8CCA000022 +:100840003C0308008C6300BC3C0208008C4200B8EA +:100850000144202300641821000040210064202B63 +:1008600000481021004410213C010800AC2300BCCA +:100870003C010800AC2200B88F5100003222000772 +:100880001040FFDCAF8A00148CC600003C05080055 +:100890008CA500BC3C0408008C8400B800CA30233E +:1008A00000A628210000102100A6302B0082202164 +:1008B00000862021322700013C010800AC2500BC45 +:1008C0003C010800AC2400B810E0001F32220002F6 +:1008D0008F420100AF4200208F420104AF4200A8C6 +:1008E0009342010B0E0000C6305000FF2E02001E86 +:1008F00054400004001010800E0000C90A000213CA +:1009000000000000005210218C4200000040F80955 +:1009100000000000104000053C0240008F4301042D +:100920003C026020AC4300143C024000AF4201385E +:100930003C0208008C420034244200013C010800C3 +:10094000AC220034322200021040000E3222000499 +:100950008F4201400E0000C6AF4200200E000295FB +:10096000000000003C024000AF4201783C02080059 +:100970008C420038244200013C010800AC220038BF +:10098000322200041040FF983C0280008F42018018 +:100990000E0000C6AF4200208F43018024020F00EA +:1009A00014620005000000008F420188A742009CED +:1009B0000A0002483C0240009362000024030050F9 +:1009C000304200FF144300083C0240000E00027B4E +:1009D00000000000544000043C0240000E000D7571 +:1009E000000000003C024000AF4201B83C02080099 +:1009F0008C42003C244200013C010800AC22003C37 +:100A00000A0001C83C0280003C0290003442000110 +:100A100000822025AF4400208F4200200440FFFECA +:100A20000000000003E00008000000003C0280001D +:100A3000344200010082202503E00008AF4400207A +:100A400027BDFFE0AFB10014AFB0001000808821D7 +:100A5000AFBF00180E00025030B000FF9362007D5F +:100A60000220202102028025A370007D8F70007477 +:100A70003C0280000E000259020280241600000988 +:100A80008FBF00188F4201F80440FFFE24020002CD +:100A9000AF5101C0A34201C43C021000AF4201F8B3 +:100AA0008FBF00188FB100148FB0001003E0000852 +:100AB00027BD002027BDFFE8AFBF0010974201848B +:100AC0008F440188304202001040000500002821B8 +:100AD0000E000FAA000000000A00028D240500018C +:100AE0003C02FF0004800005008218243C02040040 +:100AF000506200019362003E240500018FBF001088 +:100B000000A0102103E0000827BD0018A360002208 +:100B10008F4401400A00025E2405000127BDFFE862 +:100B2000AFBF0014AFB0001093620000304400FF6C +:100B300038830020388200300003182B0002102B6D +:100B40000062182410600003240200501482008008 +:100B50008FBF001493620005304200011040007CFA +:100B60008FBF0014934201482443FFFF2C6200050D +:100B7000104000788FB00010000310803C03080084 +:100B800024634A68004310218C42000000400008A2 +:100B9000000000000E0002508F4401408F70000CD6 +:100BA0008F4201441602000224020001AF62000CD1 +:100BB0000E0002598F4401408F420144145000043A +:100BC0008FBF00148FB000100A000F2027BD00183F +:100BD0008F62000C0A0003040000000097620010FE +:100BE0008F4301443042FFFF1462001A00000000EE +:100BF00024020001A76200108F4202380443001053 +:100C00008F4201403C02003F3446F0003C0560004A +:100C10003C04FFC08CA22BBC0044182400461024C6 +:100C20000002130200031D82106200390000000060 +:100C30008F4202380440FFF7000000008F4201405D +:100C4000AF4202003C021000AF4202380A00032209 +:100C50008FBF0014976200100A0003040000000018 +:100C60000E0002508F440140976200128F430144EE +:100C70003050FFFF1603000224020001A762001299 +:100C80000E0002598F4401408F42014416020004B5 +:100C90008FBF00148FB000100A00029127BD00180A +:100CA000976200120A00030400000000976200141B +:100CB0008F4301443042FFFF14620006240200010A +:100CC0008FBF00148FB00010A76200140A00124AF0 +:100CD00027BD0018976200141440001D8FBF001438 +:100CE0000A00031C00000000976200168F430144B5 +:100CF0003042FFFF1462000B240200018FBF00147A +:100D00008FB00010A76200160A000B1227BD001852 +:100D10009742007824420004A76200100A000322D0 +:100D20008FBF001497620016240300013042FFFFBA +:100D3000144300078FBF00143C0208008C4200706F +:100D4000244200013C010800AC2200708FBF001457 +:100D50008FB0001003E0000827BD001827BDFFE892 +:100D6000AFBF0014AFB000108F50010093620000BD +:100D700093430109304400FF2402001F106200A5C4 +:100D80002862002010400018240200382862000A5F +:100D90001040000C2402000B286200081040002CB8 +:100DA00000000000046000E52862000214400028F2 +:100DB00024020006106200268FBF00140A00041FE0 +:100DC0008FB000101062005E2862000B144000DC3F +:100DD0008FBF00142402000E106200738FB0001049 +:100DE0000A00041F00000000106200C028620039E1 +:100DF0001040000A2402008024020036106200CA5B +:100E000028620037104000B424020035106200C18F +:100E10008FBF00140A00041F8FB000101062002B57 +:100E20002862008110400006240200C82402003914 +:100E3000106200B48FBF00140A00041F8FB00010AE +:100E4000106200998FBF00140A00041F8FB00010B9 +:100E50003C0208008C420020104000B98FBF0014F3 +:100E60000E000493000000008F4201008F830020D9 +:100E70009745010C97460108AC6200008F420104BF +:100E80003C04080094844B5E00052C00AC62000416 +:100E90008F4201180006340000C43025AC620008FF +:100EA0008F42011C24040001AC62000C9342010A31 +:100EB00000A22825AC650010AC600014AC600018DE +:100EC000AC66001C0A0003F58FBF00143C0208004A +:100ED0008C4200201040009A8FBF00140E00049333 +:100EE00000000000974401083C03080094634B5E37 +:100EF0009745010C000422029746010E8F820020C4 +:100F0000000426000083202500052C003C030080FF +:100F100000A6282500832025AC400000AC4000043A +:100F2000AC400008AC40000CAC450010AC400014D4 +:100F3000AC400018AC44001C0A0003F42404000177 +:100F40009742010C14400015000000009362000558 +:100F50003042001014400011000000000E0002504A +:100F6000020020219362000502002021344200107B +:100F70000E000259A36200059362000024030020C2 +:100F8000304200FF1043006D020020218FBF00148B +:100F90008FB000100A000FC027BD00180000000D20 +:100FA0000A00041E8FBF00143C0208008C4200207F +:100FB000104000638FBF00140E0004930000000077 +:100FC0008F4201048F8300209744010C3C050800E8 +:100FD00094A54B5EAC6200009762002C00042400D4 +:100FE0003042FFFF008220253C02400E00A228254F +:100FF000AC640004AC600008AC60000CAC60001095 +:10100000AC600014AC600018AC65001C0A0003F46E +:10101000240400010E00025002002021A7600008F5 +:101020000E00025902002021020020210E00025E63 +:10103000240500013C0208008C42002010400040C2 +:101040008FBF00140E000493000000009742010CB3 +:101050008F8300203C05080094A54B5E000214001D +:10106000AC700000AC620004AC6000088F64004CFF +:101070003C02401F00A22825AC64000C8F62005087 +:1010800024040001AC6200108F620054AC620014B2 +:10109000AC600018AC65001C8FBF00148FB000104E +:1010A0000A0004B827BD0018240200205082002541 +:1010B0008FB000100E000F0A020020211040002007 +:1010C0008FBF0014020020218FB0001000002821E3 +:1010D0000A00025E27BD0018020020218FBF001405 +:1010E0008FB000100A00058027BD00189745010C3D +:1010F000020020218FBF00148FB000100A0005A04D +:1011000027BD0018020020218FB000100A0005C57D +:1011100027BD00189345010D020020218FB000105B +:101120000A00060F27BD0018020020218FBF0014FF +:101130008FB000100A0005EB27BD00188FBF001408 +:101140008FB0001003E0000827BD00188F4202781E +:101150000440FFFE2402000234840080AF440240B9 +:10116000A34202443C02100003E00008AF420278B0 +:101170003C04080094844B6A3C0208008C424B7487 +:101180003083FFFF000318C000431021AF42003C32 +:101190003C0208008C424B70AF4200383C020050C9 +:1011A00034420008AF4200300000000000000000A0 +:1011B000000000008F420000304200201040FFFD80 +:1011C000000000008F4204003C010800AC224B608C +:1011D0008F4204043C010800AC224B643C02002016 +:1011E000AF420030000000003C02080094424B680F +:1011F0003C03080094634B6C3C05080094A54B6EBF +:1012000024840001004310213083FFFF3C010800CB +:10121000A4224B683C010800A4244B6A1465000317 +:10122000000000003C010800A4204B6A03E0000815 +:10123000000000003C05000A27BDFFE80345282107 +:101240003C04080024844B50AFBF00100E00051D65 +:101250002406000A3C02080094424B523C0308005A +:1012600094634B6E3042000F244200030043180485 +:1012700024027FFF0043102B10400002AF83001CAC +:101280000000000D0E00042A000000003C020800CF +:1012900094424B5A8FBF001027BD001803E000088E +:1012A000A74200A23C02000A034210219443000618 +:1012B0003C02080094424B5A3C010800A4234B56C0 +:1012C000004310238F83001C00021400000214034B +:1012D0000043102B03E000083842000127BDFFE85F +:1012E000AFBF00103C02000A0342102194420006E6 +:1012F0003C010800A4224B560E00047700000000B9 +:101300005440FFF93C02000A8FBF001003E00008C0 +:1013100027BD001827BDFFE8AFBF00100E000477FF +:101320000000000010400003000000000E000485D3 +:10133000000000003C0208008C424B608FBF001090 +:1013400027430400AF4200383C0208008C424B6443 +:1013500027BD0018AF830020AF42003C3C020005CF +:10136000AF42003003E00008AF8000188F82001801 +:101370003C0300060002114000431025AF4200303C +:101380000000000000000000000000008F4200008C +:10139000304200101040FFFD27420400AF820020C1 +:1013A00003E00008AF8000183C0608008CC64B64C0 +:1013B0008F8500188F8300203C02080094424B5A0E +:1013C00027BDFFE024A50001246300202442000182 +:1013D00024C70020AFB10014AFB00010AFBF001899 +:1013E000AF850018AF8300203C010800A4224B5AAF +:1013F000309000FF3C010800AC274B6404C100089A +:101400000000882104E00006000000003C02080003 +:101410008C424B60244200013C010800AC224B602E +:101420003C02080094424B5A3C03080094634B680A +:101430000010202B004310262C42000100441025F0 +:10144000144000048F830018240200101462000F5F +:10145000000000000E0004A9241100013C03080054 +:1014600094634B5A3C02080094424B681462000398 +:10147000000000000E00042A000000001600000317 +:10148000000000000E000493000000003C03080070 +:1014900094634B5E3C02080094424B5C2463000161 +:1014A0003064FFFF3C010800A4234B5E148200035C +:1014B000000000003C010800A4204B5E1200000662 +:1014C000000000003C02080094424B5AA74200A2D0 +:1014D0000A00050B022010210E0004770000000016 +:1014E00010400004022010210E00048500000000BE +:1014F000022010218FBF00188FB100148FB0001090 +:1015000003E0000827BD00203084FFFF30A5FFFF67 +:101510000000182110800007000000003082000148 +:101520001040000200042042006518210A00051343 +:101530000005284003E000080060102110C00006EC +:1015400024C6FFFF8CA2000024A50004AC8200008A +:101550000A00051D2484000403E0000800000000C8 +:1015600010A0000824A3FFFFAC86000000000000CC +:10157000000000002402FFFF2463FFFF1462FFFA53 +:101580002484000403E0000800000000240200019D +:10159000AF62000CA7620010A7620012A7620014DD +:1015A00003E00008A76200163082007F034210218A +:1015B0003C08000E004818213C0208008C42002024 +:1015C00027BDFFD82407FF80AFB3001CAFB20018BF +:1015D000AFB10014AFB00010AFBF00200080802179 +:1015E00030B100FF0087202430D200FF1040002FD0 +:1015F00000009821AF44002C9062000024030050AA +:10160000304200FF1443000E000000003C020800BE +:101610008C4200E00202102100471024AF42002C4F +:101620003C0208008C4200E0020210213042007FA0 +:101630000342102100481021944200D43053FFFF90 +:101640000E000493000000003C02080094424B5E30 +:101650008F8300200011340000C2302500122C00BE +:101660003C02400000C2302534A50001AC700000EF +:101670008FBF0020AC6000048FB20018AC7300086C +:101680008FB10014AC60000C8FB3001CAC6500106F +:101690008FB00010AC60001424040001AC6000188E +:1016A00027BD00280A0004B8AC66001C8FBF0020CC +:1016B0008FB3001C8FB200188FB100148FB00010D0 +:1016C00003E0000827BD00289343010F2402001007 +:1016D0001062000E2865001110A0000724020012FD +:1016E000240200082405003A1062000600003021A0 +:1016F00003E0000800000000240500351462FFFC30 +:10170000000030210A000538000000008F420074FC +:1017100024420FA003E00008AF62000C27BDFFE8E1 +:10172000AFBF00100E00025E240500018FBF001045 +:1017300024020001A762001227BD00182402000144 +:1017400003E00008A360002227BDFFE0AFB1001452 +:10175000AFB00010AFBF001830B1FFFF0E00025055 +:10176000008080219362003F24030004304200FF88 +:101770001443000C02002021122000082402000A59 +:101780000E00053100000000936200052403FFFEF7 +:1017900000431024A362000524020012A362003F4C +:1017A000020020210E000259A360008116200003D0 +:1017B000020020210E0005950000000002002021FB +:1017C000322600FF8FBF00188FB100148FB00010B9 +:1017D000240500380A00053827BD002027BDFFE09A +:1017E000AFBF001CAFB20018AFB10014AFB0001013 +:1017F0000E000250008080210E0005310000000024 +:101800009362003F24120018305100FF123200038F +:101810000200202124020012A362003F936200050F +:101820002403FFFE004310240E000259A3620005AA +:10183000020020212405002016320007000030217C +:101840008FBF001C8FB200188FB100148FB0001032 +:101850000A00025E27BD00208FBF001C8FB2001857 +:101860008FB100148FB00010240500390A0005382C +:1018700027BD002027BDFFE8AFB00010AFBF0014A8 +:101880009742010C2405003600808021144000108E +:10189000304600FF0E00025000000000240200123B +:1018A000A362003F93620005344200100E00053130 +:1018B000A36200050E00025902002021020020212F +:1018C0000E00025E240500200A000604000000004D +:1018D0000E000538000000000E000250020020211A +:1018E000936200232403FF9F020020210043102461 +:1018F0008FBF00148FB00010A36200230A000259AA +:1019000027BD001827BDFFE0AFBF0018AFB100141E +:10191000AFB0001030B100FF0E00025000808021F7 +:10192000240200120E000531A362003F0E0002598E +:101930000200202102002021022030218FBF001848 +:101940008FB100148FB00010240500350A0005384F +:1019500027BD0020A380002C03E00008A380002DF9 +:101960008F4202780440FFFE8F820034AF42024073 +:1019700024020002A34202443C02100003E00008DB +:10198000AF4202783C0360008C6254003042000891 +:101990001440FFFD000000008C625408AF82000C70 +:1019A00024020052AC605408AC645430AC6254342D +:1019B0002402000803E00008AC6254003C0260000E +:1019C0008C42540030420008104000053C03600087 +:1019D0008C625400304200081440FFFD00000000FB +:1019E0008F83000C3C02600003E00008AC43540805 +:1019F00090A3000024020005008040213063003FD6 +:101A000000004821146200050000502190A2001C33 +:101A100094A3001E304900FF306AFFFFAD00000CA8 +:101A2000AD000010AD000024950200148D05001CCF +:101A30008D0400183042FFFF0049102300021100FE +:101A4000000237C3004038210086202300A2102B5B +:101A50000082202300A72823AD05001CAD04001838 +:101A6000A5090014A5090020A50A001603E0000836 +:101A7000A50A00228F4201F80440FFFE2402000262 +:101A8000AF4401C0A34201C43C02100003E00008BF +:101A9000AF4201F83C0208008C4200B427BDFFE8C9 +:101AA000AFBF001424420001AFB000103C01080099 +:101AB000AC2200B48F4300243C02001F30AA00FF78 +:101AC0003442FF8030D800FF006280240080F8217B +:101AD00030EF00FF1158003B01405821240CFF80DB +:101AE0003C19000A3163007F000310C00003194055 +:101AF000006218213C0208008C4200DC25680001CD +:101B0000310D007F03E21021004310213043007F9C +:101B100003431821004C102400794821AF420024CF +:101B20008D220024016C1824006C7026AD22000C5C +:101B30008D220024310800FFAD22001095220014F0 +:101B4000952300208D27001C3042FFFF3063FFFFEC +:101B50008D2600180043102300021100000227C345 +:101B60000040282100C4302300E2102B00C23023A3 +:101B700000E53823AD27001CAD2600189522002073 +:101B8000A522001495220022154B000AA52200165A +:101B90008D2300248D220008254600013145008058 +:101BA0001462000430C4007F108F000238AA008045 +:101BB00000C0502151AF000131C800FF1518FFC906 +:101BC000010058218F8400343082007F03421821A5 +:101BD0003C02000A006218212402FF8000822024B7 +:101BE000AF440024A06A0079A06A00838C62005090 +:101BF0008F840034AC6200708C6500743C027FFFFF +:101C00003442FFFF00A228240E00066BAC6500746E +:101C1000AF5000248FBF00148FB0001003E0000805 +:101C200027BD001827BDFFC0AFBE0038AFB70034D6 +:101C3000AFB5002CAFB20020AFB1001CAFB00018A0 +:101C4000AFBF003CAFB60030AFB40028AFB3002444 +:101C50008F4500248F4600288F43002C3C02001F34 +:101C60003442FF800062182400C230240080A82182 +:101C7000AFA3001400A2F0240E00062FAFA60010A0 +:101C80003C0208008C4200E02410FF8003608821A1 +:101C900002A2102100501024AF4200243C02080090 +:101CA0008C4200E002A210213042007F0342182142 +:101CB0003C02000A00629021924200D293630084A9 +:101CC000305700FF306300FF24020001106200342F +:101CD000036020212402000214620036000000008C +:101CE0000E001216024028219223008392220083C4 +:101CF0003063007F3042007F000210C000031940B3 +:101D0000006218213C0208008C4200DC02A2102173 +:101D10000043382100F01024AF42002892250078BB +:101D20009224008330E2007F034218213C02000C21 +:101D300014850007006280212402FFFFA24200F107 +:101D40002402FFFFA64200F20A0007272402FFFF39 +:101D500096020020A24200F196020022A64200F262 +:101D60008E020024AE4200F492220083A24200F0D0 +:101D70008E4200C8AE4200FC8E4200C4AE4200F863 +:101D80008E220050AE4201008E4200CCAE420104D1 +:101D9000922200853042003F0A0007823442004010 +:101DA0000E00123902402821922200850A00078283 +:101DB0003042003F936200852403FFDF3042003F42 +:101DC000A36200859362008500431024A36200850E +:101DD0009363008393620078307400FF304200FF09 +:101DE00010540036240AFF803C0C000C3283007F24 +:101DF000000310C000031940006218213C020800D3 +:101E00008C4200DC268800013109007F02A21021EB +:101E10000043382130E2007F0342182100EA1024F9 +:101E2000AF420028006C80218E020024028A182410 +:101E3000006A5826AE02000C8E020024310800FF12 +:101E4000AE02001096020014960300208E07001CBC +:101E50003042FFFF3063FFFF8E060018004310235F +:101E600000021100000227C30040282100C43023D3 +:101E700000E2102B00C2302300E53823AE07001C1F +:101E8000AE06001896020020A60200149602002258 +:101E9000A602001692220079304200FF105400077B +:101EA0000000000051370001316800FF92220078E5 +:101EB000304200FF1448FFCD0100A0219222008390 +:101EC000A22200798E2200500A0007E2AE220070A2 +:101ED000A22200858E22004C2405FF80AE42010C18 +:101EE0009222008534420020A2220085924200D135 +:101EF0003C0308008C6300DC305400FF3C02080007 +:101F00008C4200E400143140001420C002A31821C8 +:101F100000C4202102A210210064382100461021B3 +:101F20000045182400E52824AF450028AF43002CC5 +:101F30003042007F924400D030E3007F03422821EA +:101F4000034318213C02000C006280213C02000E79 +:101F5000309600FF00A298211296002A000000008F +:101F60008E02000C02002021026028211040002572 +:101F7000261000280E00064A000000009262000DA4 +:101F800026830001307400FF3042007FA262000D02 +:101F90002404FF801697FFF0267300203C020800FF +:101FA0008C4200DC0000A02102A210210044102479 +:101FB000AF4200283C0208008C4200E43C030800C9 +:101FC0008C6300DC02A2102100441024AF42002CDC +:101FD0003C0208008C4200E402A318213063007F19 +:101FE00002A210213042007F034220210343182126 +:101FF0003C02000C006280213C02000E0A0007A493 +:10200000008298218E4200D8AE2200508E4200D825 +:10201000AE22007092250083924600D19223008365 +:10202000924400D12402FF8000A228243063007F64 +:10203000308400FF00A628250064182A10600002E2 +:1020400030A500FF38A50080A2250083A2250079D5 +:102050000E00063D000000009222007E02A020211A +:10206000A222007A8E2300743C027FFF3442FFFFDD +:10207000006218240E00066BAE2300748FA20010BD +:10208000AF5E00248FBF003CAF4200288FBE0038F7 +:102090008FA200148FB700348FB600308FB5002C9C +:1020A0008FB400288FB300248FB200208FB1001CA2 +:1020B0008FB0001827BD004003E00008AF42002C9D +:1020C00090A2000024420001A0A200003C030800EE +:1020D0008C6300F4304200FF1443000F0080302175 +:1020E000A0A000003C0208008C4200E48F84003471 +:1020F000008220213082007F034218213C02000C24 +:10210000006218212402FF8000822024ACC300005A +:1021100003E00008AF4400288C8200002442002025 +:1021200003E00008AC82000094C200003C080800F4 +:10213000950800CA30E7FFFF008048210102102106 +:10214000A4C2000094C200003042FFFF00E2102B46 +:1021500054400001A4C7000094A200003C03080002 +:102160008C6300CC24420001A4A2000094A20000D1 +:102170003042FFFF544300078F8600280107102BD1 +:10218000A4A000005440000101003821A4C70000B1 +:102190008F8600288CC4001CAF44003C94A2000031 +:1021A0008F43003C3042FFFF000210C00062182144 +:1021B000AF43003C8F42003C008220231880000483 +:1021C000000000008CC200180A00084324420001ED +:1021D0008CC20018AF4200383C020050344200105C +:1021E000AF420030000000000000000000000000CE +:1021F0008F420000304200201040FFFD0000000030 +:102200008F420404AD2200048F420400AD2200007E +:102210003C020020AF42003003E000080000000054 +:1022200027BDFFE0AFB20018AFB10014AFB000108F +:10223000AFBF001C94C2000000C080213C12080007 +:10224000965200C624420001A60200009603000038 +:1022500094E2000000E03021144300058FB100300B +:102260000E000818024038210A000875000000001E +:102270008C8300048C820004244200400461000727 +:10228000AC8200048C8200040440000400000000C2 +:102290008C82000024420001AC8200009602000003 +:1022A0003042FFFF50520001A600000096220000BD +:1022B00024420001A62200008F82002896230000FD +:1022C00094420016144300048FBF001C2402000136 +:1022D000A62200008FBF001C8FB200188FB100141F +:1022E0008FB0001003E0000827BD00208F89002870 +:1022F00027BDFFE0AFBF00188D220028274804004B +:1023000030E700FFAF4200388D22002CAF8800304C +:10231000AF42003C3C020005AF420030000000002C +:1023200000000000000000000000000000000000AD +:10233000000000008C82000C8C82000CAD020000BA +:102340008C820010AD0200048C820018AD020008DF +:102350008C82001CAD02000C8CA20014AD02001097 +:102360008C820020AD02001490820005304200FFF4 +:1023700000021200AD0200188CA20018AD02001C71 +:102380008CA2000CAD0200208CA20010AD02002433 +:102390008CA2001CAD0200288CA20020AD02002CF3 +:1023A000AD060030AD000034978300263402FFFFF5 +:1023B00014620002006020213404FFFF10E00011CD +:1023C000AD04003895230036952400362402000120 +:1023D0003063FFFF000318C20069182190650040B8 +:1023E000308400070082100400451025A0620040E0 +:1023F0008F820028944200563042FFFF0A0008DC1A +:10240000AD02003C952300369524003624020001DD +:102410003063FFFF000318C2006918219065004077 +:1024200030840007008210040002102700451024A9 +:10243000A0620040AD00003C000000000000000071 +:10244000000000003C02000634420040AF42003071 +:102450000000000000000000000000008F420000AB +:10246000304200101040FFFD8F860028AF880030FA +:1024700024C2005624C7003C24C4002824C50032CE +:1024800024C600360E000856AFA200108FBF0018F9 +:1024900003E0000827BD00208F8300243C060800CD +:1024A0008CC600E88F82003430633FFF0003198040 +:1024B00000461021004310212403FF803046007F96 +:1024C00000431024AF420028034618213C02000CB0 +:1024D0000062302190C2000D30A500FF00003821BD +:1024E00034420010A0C2000D8F8900288F8A00247A +:1024F00095230036000A13823048000324020001AD +:10250000A4C3000E1102000B2902000210400005B6 +:10251000240200021100000C240300010A0009201B +:102520000000182111020006000000000A00092026 +:10253000000018218CC2002C0A000920244300014D +:102540008CC20014244300018CC200180043102BDD +:1025500050400009240700012402002714A20003B0 +:10256000000000000A00092C240700019522003E0B +:1025700024420001A522003E000A138230430003DA +:102580002C62000210400009008028211460000421 +:102590000000000094C200360A00093C3046FFFFEC +:1025A0008CC600380A00093C008028210000302138 +:1025B0003C04080024844B780A00088900000000CD +:1025C000274901008D22000C9523000601202021BF +:1025D000000216023046003F3063FFFF240200274E +:1025E00000C0282128C7002810C2000EAF83002495 +:1025F00010E00008240200312402002110C200096A +:102600002402002510C200079382002D0A00095BF6 +:102610000000000010C200059382002D0A00095B33 +:10262000000000000A0008F4000000000A0006266E +:102630000000000095230006912400058D25000C64 +:102640008D2600108D2700188D28001C8D29002054 +:10265000244200013C010800A4234B7E3C010800F9 +:10266000A0244B7D3C010800AC254B843C010800B4 +:10267000AC264B883C010800AC274B903C0108007D +:10268000AC284B943C010800AC294B9803E00008AF +:10269000A382002D8F87002827BDFFC0AFB3003471 +:1026A000AFB20030AFB1002CAFB00028AFBF0038E0 +:1026B0003C0208008C4200D094E3003030B0FFFFB1 +:1026C000005010073045FFFF3063FFFF00C0982126 +:1026D000A7A200103C110800963100C614A3000602 +:1026E0003092FFFF8CE2002424420030AF42003CD5 +:1026F0000A0009948CE2002094E200323042FFFF8D +:1027000054A2000827A400188CE2002C24420030B8 +:10271000AF42003C8CE20028AF4200380A0009A218 +:102720008F84002827A5001027A60020022038212A +:102730000E000818A7A000208FA200182442003025 +:10274000AF4200388FA2001CAF42003C8F840028AB +:102750003C020005AF42003094820034274304005D +:102760003042FFFF0202102B14400007AF830030FD +:1027700094820054948300340202102100431023F9 +:102780000A0009B63043FFFF94830054948200345A +:102790000223182100501023006218233063FFFF2A +:1027A000948200163042FFFF144300030000000033 +:1027B0000A0009C424030001948200163042FFFF7E +:1027C0000043102B104000058F82003094820016C9 +:1027D000006210233043FFFF8F820030AC530000B3 +:1027E000AC400004AC520008AC43000C3C020006B4 +:1027F00034420010AF420030000000000000000032 +:10280000000000008F420000304200101040FFFD29 +:10281000001018C2006418219065004032040007BF +:10282000240200018FBF00388FB300348FB2003014 +:102830008FB1002C8FB000280082100400451025B5 +:1028400027BD004003E00008A062004027BDFFA8AC +:10285000AFB60050AFB5004CAFB40048AFB30044C2 +:10286000AFB1003CAFBF0054AFB20040AFB00038D2 +:102870008C9000003C0208008C4200E88F860034F7 +:10288000960300022413FF8000C2302130633FFF13 +:102890000003198000C3382100F3102490B2000017 +:1028A000AF42002C9203000230E2007F034230214D +:1028B0003C02000E00C28821306300C024020040A8 +:1028C0000080A82100A0B021146200260000A021F1 +:1028D0008E3400388E2200181440000224020001B9 +:1028E000AE2200189202000D304200201440001564 +:1028F0008F8200343C0308008C6300DC001238C077 +:10290000001231400043102100C730210046382119 +:1029100030E300073C02008030E6007800C230253A +:102920000343182100F31024AF4208002463090078 +:10293000AF4608108E2200188C6300080043102157 +:10294000AE2200188E22002C8E2300182442000193 +:102950000062182B1060003D000000000A000A7899 +:1029600000000000920300022402FFC00043102474 +:10297000304200FF1440000524020001AE2200187E +:10298000962200360A000A613054FFFF8E2200149E +:1029900024420001AE22001892020000000216003C +:1029A0000002160304410029000000009602000204 +:1029B00027A4001000802821A7A20016960200027A +:1029C00024070001000030213042FFFFAF820024C5 +:1029D0000E000889AFA0001C960300023C0408000A +:1029E0008C8400E88F82003430633FFF000319803D +:1029F00000441021004310213043007F3C05000CAF +:102A00000053102403431821AF4200280065182109 +:102A10009062000D001221403042007FA062000D44 +:102A20003C0308008C6300E48F82003400431021D3 +:102A30000044382130E2007F03421021004510217C +:102A400000F31824AF430028AEA200009222000D2C +:102A5000304200101040001302A020218F83002874 +:102A60008EA40000028030219462003E2442FFFFC9 +:102A7000A462003E948400029625000E3084FFFF7D +:102A80000E00097330A5FFFF8F82002894430034A5 +:102A90009622000E1443000302A02021240200010C +:102AA000A382002C02C028210E0007FE00000000B7 +:102AB0008FBF00548FB600508FB5004C8FB40048C4 +:102AC0008FB300448FB200408FB1003C8FB000380C +:102AD00003E0000827BD00588F82002827BDFFD0E3 +:102AE000AFB40028AFB20020AFBF002CAFB30024BA +:102AF000AFB1001CAFB00018904400D0904300D19B +:102B00000000A021309200FFA3A30010306300FF5B +:102B10008C5100D88C5300DC1072002B2402000171 +:102B20003C0308008C6300E493A400108F820034FF +:102B30002406FF800004214000431021004410219E +:102B40003043007F00461024AF4200280343182181 +:102B50003C02000C006218218C62000427A40014BF +:102B600027A50010022280210270102304400015C6 +:102B7000AFA300149062000D00C21024304200FF89 +:102B800014400007020088219062000D344200408A +:102B90000E0007FEA062000D0A000ABD93A20010FD +:102BA0000E0009E1241400018F830028AC7000D8C6 +:102BB00093A20010A06200D193A200101452FFD87B +:102BC0000000000024020001168200048FBF002CC8 +:102BD0000E000626000000008FBF002C8FB40028D6 +:102BE0008FB300248FB200208FB1001C8FB000186B +:102BF00003E0000827BD003027BDFFD8AFB3001C9D +:102C0000AFB20018AFB10014AFB00010AFBF0020DA +:102C10000080982100E0802130B1FFFF0E00049376 +:102C200030D200FF000000000000000000000000A3 +:102C30008F820020AC510000AC520004AC5300085D +:102C4000AC40000CAC400010AC400014AC4000188C +:102C50003C03080094634B5E02038025AC50001CCB +:102C6000000000000000000000000000240400013B +:102C70008FBF00208FB3001C8FB200188FB10014DB +:102C80008FB000100A0004B827BD002827BDFFE858 +:102C9000AFB00010AFBF001430A5FFFF30C600FF7B +:102CA0000080802124020C80AF420024000000003C +:102CB0000000000000000000000000000000000014 +:102CC0000E000ACC000000003C040800248400E050 +:102CD0008C8200002403FF808FBF001402021021A9 +:102CE00000431024AF4200248C8200003C03000A01 +:102CF000020280213210007F035010218FB000109B +:102D00000043102127BD001803E00008AF8200280F +:102D100027BDFFE8AFBF00108F4401403C0308000F +:102D20008C6300E02402FF80AF840034008318210C +:102D300000621024AF4200243C02000803424021FC +:102D4000950500023063007F3C02000A034318210E +:102D50000062182130A5FFFF3402FFFF0000302180 +:102D60003C07602010A20006AF8300282402FFFF6A +:102D7000A5020002946500D40E000AF130A5FFFF01 +:102D80008FBF001024020C8027BD001803E000084C +:102D9000AF4200243C020008034240219502000299 +:102DA0003C0A0800954A00C63046FFFF14C00007E1 +:102DB0003402FFFF8F8200288F8400343C0760209C +:102DC000944500D40A000B5A30A5FFFF10C200241E +:102DD0008F87002894E2005494E400163045FFFFEA +:102DE00000A6102300A6182B3089FFFF10600004F6 +:102DF0003044FFFF00C51023012210233044FFFFA1 +:102E0000008A102B1040000C012A1023240200011C +:102E1000A50200162402FFFFA502000294E500D4DB +:102E20008F8400340000302130A5FFFF3C07602074 +:102E30000A000AF1000000000044102A10400008B7 +:102E4000000000009502001630420001104000040E +:102E5000000000009742007E24420014A5020016E4 +:102E600003E00008000000008F84002827BDFFE079 +:102E7000AFBF0018948200349483003E1060001AA3 +:102E80003048FFFF9383002C2402000114620027C6 +:102E90008FBF00188F820028000818C23108000771 +:102EA000006218212447003A244900542444002099 +:102EB000244500302446003490620040304200FF38 +:102EC0000102100730420001104000168FBF0018A9 +:102ED0000E000856AFA900108F82002894420034DB +:102EE0000A000B733048FFFF94830036948200344D +:102EF0001043000E8FBF001894820036A482003465 +:102F000094820056A48200548C82002CAC8200244F +:102F100094820032A48200309482003CA482003A61 +:102F20008FBF00180A000B3327BD002003E0000804 +:102F300027BD002027BDFFE8AFBF00108F4A01006A +:102F40003C0508008CA500E03C02080090424B8440 +:102F50003C0C0800958C4B7E01452821304B003FEE +:102F600030A2007F03424021396900323C02000A4E +:102F70003963003F2C630001010240212D2900012B +:102F80002402FF8000A2282401234825AF8A0034B0 +:102F900000801821AF450024000030210080282146 +:102FA00024070001AF8800283C04080024844B78E3 +:102FB000AF8C002415200007A380002D24020020E0 +:102FC0005562000F006020213402FFFF5582000C83 +:102FD000006020212402002015620005000000008E +:102FE0008C6300142402FFFF106200070000000041 +:102FF0000E000889000000000A000BD0000000004D +:103000000E0008F4016028210E000B68000000008B +:103010008FBF001024020C8027BD001803E00008B9 +:10302000AF4200243C0208008C4200E027BDFFA014 +:10303000AFB1003C008210212411FF80AFBE0058C8 +:10304000AFB70054AFB20040AFB00038AFBF005CC4 +:10305000AFB60050AFB5004CAFB40048AFB30044BA +:10306000005110248F4800248F4900288F470028E2 +:10307000AF4200243C0208008C4200E00080902116 +:1030800024060006008210213042007F03421821EE +:103090003C02000A006280213C02001F3442FF8093 +:1030A00000E2382427A40010260500F00122F024B5 +:1030B0000102B8240E00051DAFA700308FA2001832 +:1030C000AE0200C48FA2001CAE0200C88FA2002472 +:1030D000AE0200CC93A40010920300D12402FF8022 +:1030E0000082102400431025304900FF3083007F08 +:1030F0003122007F0062102A10400004000310C03B +:1031000001311026304900FF000310C000031940B0 +:10311000006218213C0208008C4200DC920400D2BC +:10312000024210210043102100511024AF42002818 +:1031300093A300103063007F000310C00003194008 +:10314000006218213C0208008C4200DC024210217F +:10315000004310213042007F034218213C02000C42 +:10316000006240218FA300142402FFFF1062003090 +:10317000309500FF93A2001195030014304400FF26 +:103180003063FFFF0064182B1060000D000000008A +:10319000950400148D07001C8D0600183084FFFF75 +:1031A00000442023000421000000102100E4382105 +:1031B00000E4202B00C230210A000C4A00C4302158 +:1031C000950400148D07001C8D0600183084FFFF45 +:1031D000008220230004210000001021008018211B +:1031E00000C2302300E4202B00C4302300E3382346 +:1031F000AD07001CAD06001893A20011A502001433 +:1032000097A20012A50200168FA20014AD020010B2 +:103210008FA20014AD02000C93A20011A5020020A1 +:1032200097A20012A50200228FA20014AD02002472 +:103230002406FF80024610243256007FAF4200244D +:10324000035618213C02000A006280218E02004CC5 +:103250008FA200203124007F000428C0AE0200505D +:103260008FA200200004214000852821AE020070BA +:1032700093A2001001208821A202008393A20010D3 +:10328000A2020079920200853042003FA20200852E +:103290003C0208008C4200DC024210210045102153 +:1032A00000461024AF42002C3C0208008C4200E48F +:1032B0003C0308008C6300DC024210210044102112 +:1032C00000461024AF4200283C0208008C4200E473 +:1032D00002431821006518210242102100441021E8 +:1032E0003042007F3063007F93A50010034220210D +:1032F000034318213C02000E006240213C02000CF6 +:1033000010B1008C008248213233007F1660001912 +:103310002404FF803C0208008C4200DC02421021A1 +:1033200000441024AF42002C3C0208008C4200E410 +:103330003C0308008C6300DC02421021004410248E +:10334000AF4200283C0208008C4200E402431821EE +:103350003063007F024210213042007F034220216F +:10336000034318213C02000E006240213C02000C85 +:10337000008248219124000D2414FF8000001021B8 +:1033800000942025A124000D950400029505001449 +:103390008D07001C3084FFFF30A5FFFF8D0600184D +:1033A000008520230004210000E4382100C23021E0 +:1033B00000E4202B00C43021AD07001CAD0600182E +:1033C00095020002A5020014A50000168D02000857 +:1033D000AD0200108D020008AD02000C9502000243 +:1033E000A5020020A50000228D020008AD020024E5 +:1033F0009122000D30420040104000422622000180 +:103400003C0208008C4200E0A3B300283C10000AF4 +:103410000242102100541024AF4200243C02080054 +:103420008C4200E0A380002C27A4002C0242102133 +:103430003042007F03421821007018218C6200D8AE +:103440008D26000427A50028AFA9002C00461021D6 +:10345000AC6200D80E0009E1AF83002893A30028D6 +:103460008F8200280E000626A04300D10E000B68B4 +:103470000000000002541024AF4200243C02080067 +:103480008C4200DC00132940001320C000A420213E +:10349000024210210044102100541024AF42002C9D +:1034A0003C0208008C4200E43C0308008C6300DC12 +:1034B00003563021024210210045102100541024EF +:1034C000AF4200283C0208008C4200E4024318216D +:1034D0000064182102421021004510213042007F73 +:1034E0003063007F03422021034318213C02000E79 +:1034F000006240213C02000C00D080210082482163 +:10350000262200013043007F14750005304400FF7F +:103510002403FF800223102400431026304400FFC0 +:1035200093A2001000808821250800281444FF760B +:103530002529002093A400108FA300142402FFFF6C +:103540001062000A308900FF2482000124830001F8 +:103550003042007F14550005306900FF2403FF80CE +:103560000083102400431026304900FF92020078A7 +:10357000305300FF11330032012088213C02080043 +:103580008C4200DC3225007F000520C00005294068 +:1035900000A42021024210212406FF8000441021B3 +:1035A00000461024AF42002C3C0308008C6300DC72 +:1035B0003C0208008C4200E4024318210242102120 +:1035C0000045102100641821004610243063007F5C +:1035D000AF420028034318213C02000E0062402144 +:1035E0003C0208008C4200E48D06000C0100202102 +:1035F00002421021004510213042007F0342182171 +:103600003C02000C0062482110C0000D012028215E +:103610000E00064A000000002402FF800222182447 +:1036200026240001006228263082007F1455000203 +:10363000308300FF30A300FF1473FFD000608821A7 +:103640008E0300743C027FFF3442FFFF00621824A7 +:10365000AE0300740E00066B02402021AF57002419 +:103660008FA20030AF5E00288FBF005C8FBE005875 +:103670008FB700548FB600508FB5004C8FB4004800 +:103680008FB300448FB200408FB1003C8FB0003840 +:1036900027BD006003E00008AF42002C27BDFFD823 +:1036A000AFB1001CAFBF0020AFB000182751018898 +:1036B000922200032408FF803C03000A3047007F69 +:1036C000A3A700108F4601803C0208008C4200E056 +:1036D000AF86003400C2282100A81024AF42002485 +:1036E0009224000030A2007F0342102100431021E9 +:1036F000AF8200283084007F24020002148200255B +:10370000000719403C0208008C4200E400C210216E +:103710000043282130A2007F0342182100A8102472 +:10372000AF4200283C02000C006218219062000D9C +:10373000AFA3001400481025A062000D8FA3001451 +:103740009062000D304200405040006A8FBF002060 +:103750008F860028A380002C27A400148CC200D8D8 +:103760008C63000427A50010004310210E0009E11E +:10377000ACC200D893A300108F8200280E0006264A +:10378000A04300D10E000B68000000000A000E0BE1 +:103790008FBF00200E00062F00C020210E00063D26 +:1037A000000000003C020008034280219223000137 +:1037B0009202007B1443004F8FBF00209222000032 +:1037C0003044007F24020004108200172882000584 +:1037D00010400006240200052402000310820007A6 +:1037E0008FB1001C0A000E0C0000000010820012B5 +:1037F0008FBF00200A000E0C8FB1001C92050083C1 +:10380000920600788E0700748F84003430A500FF84 +:1038100000073E0230C600FF0E00067330E7007F4F +:103820000A000E0B8FBF00200E000BD78F840034D0 +:103830000A000E0B8FBF002024020C80AF42002430 +:103840009202003E30420040104000200000000084 +:103850009202003E00021600000216030441000618 +:10386000000000008F8400340E0005A024050093A2 +:103870000A000E0B8FBF00209202003F24030018A5 +:10388000304200FF1443000C8F84003424050039BB +:103890000E000538000030210E0002508F840034E5 +:1038A00024020012A202003F0E0002598F8400344D +:1038B0000A000E0B8FBF0020240500360E000538CD +:1038C000000030210A000E0B8FBF00200E000250B6 +:1038D0008F8400349202000534420020A2020005C9 +:1038E0000E0002598F8400340E000FC08F84003404 +:1038F0008FBF00208FB1001C8FB0001824020C80F5 +:1039000027BD002803E00008AF42002427BDFFE8E0 +:10391000AFB00010AFBF001427430100946200084D +:103920000002140000021403044100020000802180 +:103930002410000194620008304200801040001AF8 +:10394000020010219462000830422000104000164E +:10395000020010218C6300183C021C2D344219ED2A +:10396000240600061062000F3C0760213C0208009C +:103970008C4200D4104000078F8200288F830028DB +:10398000906200623042000F34420040A062006248 +:103990008F8200288F840034944500D40E000AF1F1 +:1039A00030A5FFFF020010218FBF00148FB0001060 +:1039B00003E0000827BD001827BDFFE0AFB10014E9 +:1039C000AFB00010A380002CAFBF00188F450100DE +:1039D0003C0308008C6300E02402FF80AF850034C4 +:1039E00000A318213064007F0344202100621824C2 +:1039F0003C02000A00822021AF430024275001002E +:103A00008E0200148C8300DCAF8400280043102356 +:103A100018400004000088218E0200140E000A8461 +:103A2000AC8200DC9202000B24030002304200FF53 +:103A30001443002F0000000096020008304300FFEE +:103A40002402008214620005240200840E00093E54 +:103A5000000000000A000E97000000001462000938 +:103A6000240200818F8200288F8400343C0760216B +:103A7000944500D49206000530A5FFFF0A000E868B +:103A800030C600FF14620027000000009202000A06 +:103A9000304300FF306200201040000430620040DC +:103AA0008F8400340A000E82240600401040000477 +:103AB000000316008F8400340A000E8224060041A1 +:103AC00000021603044100178F84003424060042CC +:103AD0008F8200283C076019944500D430A5FFFF71 +:103AE0000E000AF1000000000A000E97000000001E +:103AF0009202000B24030016304200FF1043000620 +:103B0000000000009202000B24030017304200FF67 +:103B100014430004000000000E000E11000000001D +:103B2000004088210E000B68000000009202000A8D +:103B3000304200081040000624020C808F850028C7 +:103B40003C0400080E0011EE0344202124020C80E6 +:103B5000AF4200248FBF0018022010218FB0001048 +:103B60008FB1001403E0000827BD002027BDFFE847 +:103B7000AFBF0014AFB000108F5000243C0308000A +:103B80008C6300E08F4501002402FF8000A3182110 +:103B90003064007F03442021006218243C02000AA4 +:103BA00000822021AF850034AF4300249082006260 +:103BB000AF8400283042000F34420050A0820062DF +:103BC0003C02001F3442FF800E00062602028024C1 +:103BD000AF5000248FBF00148FB0001003E0000826 +:103BE00027BD00183C0208008C4200201040001D38 +:103BF0002745010090A300093C0200080342202150 +:103C000024020018546200033C0200080A000ED887 +:103C10002402000803422021240200161462000539 +:103C20002402001724020012A082003F0A000EE2C4 +:103C300094A700085462000694A700089362000548 +:103C40002403FFFE00431024A362000594A700088C +:103C500090A6001B8CA4000094A500060A000ACCC4 +:103C600000073C0003E000080000000027440100BA +:103C700094820008304500FF38A3008238A20084F7 +:103C80002C6300012C420001006218251060000620 +:103C9000240200839382002D1040000D00000000DC +:103CA0000A000B9B0000000014A2000524A2FF8064 +:103CB0008F4301043C02602003E00008AC43001481 +:103CC000304200FF2C420002104000032402002278 +:103CD0000A000E3C0000000014A2000300000000D7 +:103CE0000A000EA9000000000A000EC70000000034 +:103CF0009363007E9362007A144300090000202140 +:103D00009362000024030050304200FF144300047B +:103D1000240400019362007E24420001A362007E1D +:103D200003E00008008010218F4201F80440FFFEEC +:103D300024020002AF4401C0A34201C43C021000AF +:103D400003E00008AF4201F827BDFFE8AFBF001055 +:103D50009362003F2403000A304200FF14430046F0 +:103D6000000000008F6300548F62004C1062007DE1 +:103D7000036030219362000024030050304200FFB2 +:103D80001443002F000000008F4401403C02080053 +:103D90008C4200E02403FF800082102100431024A5 +:103DA000AF4200243C0208008C4200E08F650054C2 +:103DB0003C03000A008220213084007F034410214C +:103DC00000431021AC4501089762003C8F63004C12 +:103DD0003042FFFF0002104000621821AF63005C18 +:103DE0008F6300548F64004C9762003C006418237A +:103DF0003042FFFF00031843000210400043102A26 +:103E000010400006000000008F6200548F63004CD9 +:103E1000004310230A000F58000210439762003C31 +:103E20003042FFFF00021040ACC2006424020001D7 +:103E3000A0C0007CA0C2008424020C80AF420024F9 +:103E40000E000F0A8F440140104000478FBF001042 +:103E50008F4301408F4201F80440FFFE240200021C +:103E6000AF4301C0A34201C43C021000AF4201F8BD +:103E70000A000FA88FBF00109362003F24030010B8 +:103E8000304200FF14430004000000008F44014052 +:103E90000A000F94000028219362003F24030016BB +:103EA000304200FF1443000424020014A362003FC8 +:103EB0000A000FA2000000008F62004C8F630050C8 +:103EC00000431023044100288FBF0010936200813B +:103ED00024420001A3620081936200812C4200040D +:103EE00014400010000000009362003F240300040F +:103EF000304200FF14430006000000008F440140E0 +:103F00008FBF0010240500930A0005A027BD0018EC +:103F10008F440140240500938FBF00100A00060F54 +:103F200027BD00188F4401400E0002500000000021 +:103F30008F6200542442FFFFAF6200548F62005032 +:103F40002442FFFFAF6200500E0002598F4401402F +:103F50008F4401408FBF0010240500040A00025E58 +:103F600027BD00188FBF001003E0000827BD001810 +:103F70008F4201889363007E00021402304400FFE8 +:103F8000306300FF1464000D0000000093620080A5 +:103F9000304200FF1044000900000000A3640080CC +:103FA0009362000024030050304200FF14430004D9 +:103FB000000000000A0006D78F440180A36400803F +:103FC00003E000080000000027BDFFE8AFB00010CC +:103FD000AFBF00149362000524030030304200306C +:103FE00014430089008080213C0208008C4200209C +:103FF00010400080020020210E0004930000000009 +:104000008F850020ACB000009362003E9363003FB8 +:10401000304200FF00021200306300FF0043102511 +:10402000ACA2000493620082000216000002160394 +:1040300004410005000000003C0308008C630048B8 +:104040000A000FE6000000009362003E304200408C +:10405000144000030000182193620081304300FFE8 +:104060009362008200031E00304200FF0002140031 +:1040700000621825ACA300088F620040ACA2000CBF +:104080008F620048ACA200108F62004CACA20014FA +:104090008F6200508F63004C0043102304410003E3 +:1040A000000000000A000FFA8F62004C8F6200507F +:1040B000ACA200183C02080094424B5E3C03C00BCB +:1040C00000002021004310250E0004B8ACA2001C03 +:1040D0008F6200548F840020AC8200008F620058F1 +:1040E000AC8200048F62005CAC8200088F620060CA +:1040F0008F43007400431021AC82000C8F62006477 +:10410000AC820010976300689762006A00031C008D +:104110003042FFFF00621825AC83001493620082D6 +:1041200024030080304200FF14430003000000001D +:104130000A00102EAC8000188F63000C24020001CE +:104140001062000E2402FFFF9362003E30420040E6 +:104150001440000A2402FFFF8F63000C8F4200749A +:10416000006218233C020800006210241440000280 +:10417000000028210060282100051043AC820018AF +:104180003C02080094424B5E3C03C00C000020211E +:10419000004310258F8300200E0004B8AC62001C81 +:1041A0008F6200188F8300203C05080094A54B5EA9 +:1041B00024040001AC620000AC6000048F66006C57 +:1041C0003C02400D00A22825AC6600088F6200DC8E +:1041D000AC62000CAC600010936200050002160097 +:1041E000AC620014AC6000180E0004B8AC65001C92 +:1041F000020020218FBF00148FB00010A3600005C3 +:104200000A00042127BD00188FBF00148FB00010D2 +:1042100003E0000827BD00189742007C30C600FF6D +:10422000A08600843047FFFF2402000514C2000B63 +:1042300024E3465090A201122C42000710400007D0 +:1042400024E30A0090A30112240200140062100467 +:1042500000E210210A0010663047FFFF3067FFFFC1 +:1042600003E00008A4870014AC87004C8CA201086E +:104270000080402100A0482100E2102330C600FF4A +:104280001840000393AA001324E2FFFCACA201082B +:1042900030C2000110400008000000008D020050F4 +:1042A00000E2102304410013240600058D0200548F +:1042B00010E20010000000008D02005414E2001A09 +:1042C000000000003C0208008C4200D83042002070 +:1042D0001040000A2402000191030078910200833B +:1042E000144300062402000101002021012028219E +:1042F000240600040A00105400000000A1000084FD +:1043000011400009A50200148F4301008F4201F8FB +:104310000440FFFE24020002AF4301C0A34201C4D7 +:104320003C021000AF4201F803E00008000000006A +:1043300027BDFFE88FA90028AFBF001000804021F3 +:1043400000E918231860007330C600FFA080007CCD +:10435000A08000818CA2010800E210230440004DDF +:10436000000000008C8200509483003C8C84006428 +:10437000004748233063FFFF012318210083202BCF +:1043800010800004000000008D0200640A0010B7D5 +:1043900000E210219502003C3042FFFF0122102173 +:1043A00000E21021AD02005C9502003C8D03005C30 +:1043B0003042FFFF0002104000E210210043102BAA +:1043C00010400003000000000A0010C68D02005CCF +:1043D0009502003C3042FFFF0002104000E2102135 +:1043E000AD02005CA1000084AD07004C8CA2010866 +:1043F00000E210231840000224E2FFFCACA20108F6 +:1044000030C200011040000A000000008D02005080 +:1044100000E2102304410004010020218D02005419 +:1044200014E20003000000000A0010E82406000562 +:104430008D02005414E200478FBF00103C020800B8 +:104440008C4200D8304200201040000A24020001B3 +:1044500091030078910200831443000624020001B6 +:1044600001002021240600048FBF00100A00105410 +:1044700027BD0018A1000084A50200148F4301008D +:104480008F4201F80440FFFE240200020A00110DD1 +:10449000000000008C82005C004910230043102BB8 +:1044A00054400001AC87005C9502003C3042FFFFA5 +:1044B0000062102B14400007240200029502003C09 +:1044C0008D03005C3042FFFF00621821AD03005CE9 +:1044D00024020002AD07004CA10200840E000F0A66 +:1044E0008F4401001040001B8FBF00108F4301005C +:1044F0008F4201F80440FFFE24020002AF4301C0D6 +:10450000A34201C43C021000AF4201F80A0011238B +:104510008FBF001030C200101040000E8FBF00107F +:104520008C83005C9482003C006918233042FFFFBA +:10453000006218213C023FFF3444FFFF0083102B30 +:10454000544000010080182101231021AD02005CBD +:104550008FBF001003E0000827BD001827BDFFE84B +:104560008FAA0028AFBF00100080402100EA482336 +:104570001920002130C600FF8C83005C8C8200640F +:10458000006A18230043102B5040001000691821C6 +:1045900094A2011001221021A4A2011094A20110E2 +:1045A0003042FFFF0043102B1440000A3C023FFF43 +:1045B00094A2011000431023A4A201109482003C95 +:1045C0003042FFFF0A00114200621821A4A001102E +:1045D0003C023FFF3444FFFF0083102B5440000196 +:1045E0000080182100671021AD02005CA100007C52 +:1045F0000A00118AA100008130C200101040003C66 +:10460000000000008C820050004A1023184000383F +:10461000000000009082007C24420001A082007C07 +:104620009082007C3C0308008C630024304200FF31 +:104630000043102B1440005C8FBF00108CA20108B7 +:1046400000E2102318400058000000008C83005442 +:104650009482003C006A18233042FFFF0003184395 +:10466000000210400043102A104000050000000026 +:104670008C820054004A10230A001171000210437A +:104680009482003C3042FFFF00021040AD02006403 +:104690009502003C8D0400649503003C3042FFFF0E +:1046A00000021040008220213063FFFF00831821A8 +:1046B00001431021AD02005C8D020054ACA2010840 +:1046C00024020002A10200840E000F0A8F440100A0 +:1046D000104000358FBF00108F4301008F4201F85A +:1046E0000440FFFE240200020A0011B30000000093 +:1046F000AD07004C8CA2010800E210231840000214 +:1047000024E2FFFCACA2010830C200011040000A04 +:10471000000000008D02005000E21023044100045C +:10472000010020218D02005414E20003000000006B +:104730000A0011AA240600058D02005414E2001A92 +:104740008FBF00103C0208008C4200D8304200208D +:104750001040000A240200019103007891020083B6 +:104760001443000624020001010020212406000455 +:104770008FBF00100A00105427BD0018A10000844C +:10478000A50200148F4301008F4201F80440FFFE90 +:1047900024020002AF4301C0A34201C43C02100046 +:1047A000AF4201F88FBF001003E0000827BD0018DA +:1047B0008FAA00108C8200500080402130C600FF7C +:1047C000004A102300A048211840000700E01821EB +:1047D00024020001A0800084A0A00112A482001481 +:1047E0000A001125AFAA0010A0800081AD07004C7F +:1047F0008CA2010800E210231840000224E2FFFC12 +:10480000ACA2010830C20001104000080000000006 +:104810008D0200500062102304410013240600059D +:104820008D02005410620010000000008D02005440 +:1048300014620011000000003C0208008C4200D805 +:10484000304200201040000A240200019103007849 +:10485000910200831443000624020001010020217C +:1048600001202821240600040A0010540000000042 +:10487000A1000084A502001403E00008000000006D +:1048800027BDFFE0AFBF0018274201009046000A95 +:104890008C4800148C8B004C9082008430C900FF3F +:1048A00001681823304A00FF1C60001A2D460006DC +:1048B000240200010142100410C00016304300031E +:1048C000012030210100382114600007304C000C19 +:1048D00015800009304200301440000B8FBF0018D3 +:1048E0000A001214000000000E001125AFAB0010EA +:1048F0000A0012148FBF00180E00109AAFAB001000 +:104900000A0012148FBF0018AFAB00100E0011BACE +:10491000AFAA00148FBF001803E0000827BD0020D5 +:1049200024020003A08200848C82005403E000086B +:10493000ACA201083C0200080342182190620081E9 +:10494000240600433C07601924420001A062008154 +:10495000906300813C0208008C4200C0306300FF7D +:10496000146200102403FF803C0208008C4200E027 +:104970000082102100431024AF4200243C020800B2 +:104980008C4200E03C03000A008210213042007F8C +:104990000342102100431021944500D40A000AF17B +:1049A00030A5FFFF03E000080000000027BDFFE086 +:1049B000AFBF0018AFB10014AFB000108F4201803C +:1049C0000080802100A088210E00121B00402021C1 +:1049D000A20000848E0200548FBF00188FB0001018 +:1049E000AE2201088FB1001403E0000827BD0020AB +:1049F00027BDFFE03C020008AFB00010AFBF0018B9 +:104A0000AFB10014034280218F5101409203008412 +:104A10008E0400508E02004C14820040306600FF6D +:104A20003C0208008C4200E02403FF800222102197 +:104A300000431024AF4200243C0208008C4200E0F6 +:104A40009744007C92050081022210213042007FB1 +:104A5000034218213C02000A0062182114A0000B36 +:104A60003084FFFF2402000554C20014248205DCB8 +:104A70009062011224420001A062011224020C8003 +:104A8000AF4200240A00127324020005A060011244 +:104A90002402000514C20009248205DC9202008170 +:104AA0002C4200075040000524820A009203008136 +:104AB0002402001400621004008210213044FFFF21 +:104AC000A60400140E00121B022020219602003CB6 +:104AD0008E03004C022020213042FFFF00021040D4 +:104AE000006218210E000250AE03005C9202007DAD +:104AF00002202021344200400E000259A202007D13 +:104B00008F4201F80440FFFE24020002AF5101C0B1 +:104B1000A34201C43C021000AF4201F88FBF00184D +:104B20008FB100148FB0001003E0000827BD0020F3 +:104B300008000ACC08000B1408000B9808000BE4CE +:044B400008000C203D +:0C4B44000A000028000000000000000033 +:104B50000000000D6370362E302E3135000000004D +:104B600006000F040000000000000000000000002C +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000002005 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000001F4 +:104BC0000000002B000000000000000400030D4066 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000001000000300000000B2 +:104BF0000000000D0000000D3C0208002442588413 +:104C00003C03080024635F50AC4000000043202BAD +:104C10001480FFFD244200043C1D080037BD7FFCCA +:104C200003A0F0213C100800261000A03C1C080046 +:104C3000279C58840E0001AC000000000000000D0D +:104C400027BDFFE83C096018AFBF00108D2C500055 +:104C5000240DFF7F24080031018D5824356A380C5B +:104C600024070C003C1A8000AD2A50003C04800A46 +:104C7000AF4800083C1B8008AF4700240E00091510 +:104C8000AF8400100E0008D8000000000E000825B8 +:104C9000000000000E001252000000003C046016EC +:104CA0008C8500003C06FFFF3C02535300A61824ED +:104CB0001062004734867C0094C201F2A780002C69 +:104CC00010400003A78000CC38581E1EA798002C67 +:104CD00094C201F810400004978300CC38591E1E7E +:104CE000A79900CC978300CC2C7F006753E000018C +:104CF000240300669784002C2C82040114400002D7 +:104D000000602821240404003C0760008CE904387A +:104D10002403103C3128FFFF1103001F30B9FFFFAF +:104D200057200010A38000CE24020050A38200CEA2 +:104D3000939F00CE53E0000FA78500CCA78000CC46 +:104D4000978500CC8FBF0010A780002CA78000346F +:104D5000A78000E63C010800AC25008003E00008C5 +:104D600027BD0018939F00CE57E0FFF5A78000CC29 +:104D7000A78500CC978500CC8FBF0010A784002C9E +:104D8000A7800034A78000E63C010800AC25008025 +:104D900003E0000827BD0018A38000CE8CCB003CA8 +:104DA000316A00011140000E0000000030A7FFFF33 +:104DB00010E0FFDE240200508CCC00C831860001D8 +:104DC00014C0FFDC939F00CE0A00007A2402005139 +:104DD0008C8F00043C0E60000A00005D01EE302163 +:104DE0008CEF0808240D5708000F740211CD000441 +:104DF00030B8FFFF240500660A00007B240404008D +:104E00001700FFCC939F00CE0A00007A24020050C6 +:104E10008F8600103089FFFF000939408CC30010D5 +:104E20003C08005000E82025AF4300388CC5001432 +:104E300027420400AF82001CAF45003CAF44003065 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60008F4B0000316A00201140FFFD0000000060 +:104E700003E00008000000008F840010948A001AEC +:104E80008C8700243149FFFF000940C000E8302131 +:104E9000AF46003C8C8500248F43003C00A31023C8 +:104EA00018400029000000008C8B002025620001C2 +:104EB0003C0D005035AC0008AF420038AF4C00301C +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE0008F4F000031EE002011C0FFFD00000000D8 +:104EF0008F4A04003C080020AC8A00108F4904044B +:104F0000AC890014AF4800300000000094860018FF +:104F10009487001C00C71821A48300189485001AE8 +:104F200024A20001A482001A9498001A9499001EE9 +:104F3000133800030000000003E000080000000038 +:104F400003E00008A480001A8C8200200A0000DC24 +:104F50003C0D00500A0000CD000000003C0308009A +:104F60008C6300208F82001827BDFFE810620008C4 +:104F7000AFBF00100E000104AF8300183C0308000F +:104F80008C63002024040001106400048F89001049 +:104F90008FBF001003E0000827BD00188FBF00106E +:104FA0003C076012A520000A9528000A34E500108D +:104FB00027BD00183106FFFF03E00008ACA60090F3 +:104FC0003C0208008C42002027BDFFC8AFBF003460 +:104FD000AFBE0030AFB7002CAFB60028AFB500248D +:104FE000AFB40020AFB3001CAFB20018AFB10014D3 +:104FF00010400050AFB000108F840010948600065F +:105000009483000A00C3282330B6FFFF12C0004A71 +:105010008FBF003494890018948A000A012A402323 +:105020003102FFFF02C2382B14E0000202C020212F +:10503000004020212C8C0005158000020080A0215A +:10504000241400040E0000B3028020218F8700107A +:1050500002809821AF80001494ED000A028088211C +:105060001280004E31B2FFFF3C1770003C1540002B +:105070003C1E60008F8F001C8DEE000001D71824AD +:10508000507500500220202102A3802B160000350D +:105090003C182000507800470220202124100001F5 +:1050A0008F83001414600039029158230230F823D2 +:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D +:1050C0008F8700103C110020AF510030000000001D +:1050D00094E6000A3C1E601237D5001002662821B3 +:1050E000A4E5000A94E2000A94F2000A94F400187D +:1050F0003057FFFF1292003BAEB700908CED0014CA +:105100008CE400100013714001AE4021000E5FC31B +:10511000010E502B008B4821012A1821ACE8001405 +:10512000ACE3001002D3382330F6FFFF16C0FFB9FE +:105130008F8400108FBF00348FBE00308FB7002CDB +:105140008FB600288FB500248FB400208FB3001CC9 +:105150008FB200188FB100148FB0001003E0000868 +:1051600027BD0038107E001B000000001477FFCC24 +:10517000241000010E001598000000008F83001419 +:105180001060FFCB0230F823029158238F87001064 +:10519000017020210A0001973093FFFF8F830014D4 +:1051A0001460FFCB3C110020AF5100300A000163B6 +:1051B000000000000E00077D024028210A00015770 +:1051C000004080210E00033A024028210A000157C6 +:1051D000004080210E001460022020210A000157A7 +:1051E000004080210E0000CD000000000A0001797F +:1051F00002D3382327BDFFE8AFB00010AFBF0014C3 +:105200000E00003F000000003C028000345000709F +:105210000A0001BA8E0600008F4F000039EE00012F +:1052200031C20001104000248F8600A88E070000C4 +:105230003C0C08008D8C003C3C0908008D2900388E +:1052400000E66823018D28210000502100AD302B9D +:10525000012A4021010620213C010800AC25003C28 +:10526000AF8700A83C010800AC2400380E000106FE +:10527000000000003C0308008C6300701060FFE633 +:10528000006020213C0508008CA500683C06080051 +:105290008CC6006C0E001527000000003C010800C1 +:1052A000AC2000708F4F000039EE000131C20001C8 +:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6 +:1052C0003C0508008CA5003C3C0408008C84003898 +:1052D000014B482300A938210082182100E9402B06 +:1052E000006810213C010800AC27003C3C0108008C +:1052F000AC2200388F5F01002419FF0024180C0035 +:1053000003F9202410980012AF840000AF4400205D +:10531000936D0000240C002031A600FF10CC001279 +:10532000240E005010CE00043C194000AF59013843 +:105330000A0001B3000000000E0011C800000000C8 +:105340003C194000AF5901380A0001B300000000C9 +:105350000E00011F000000003C194000AF59013849 +:105360000A0001B3000000008F58010000802821CE +:10537000330F00FF01E020210E0002F1AF8F000487 +:105380003C194000AF5901380A0001B30000000089 +:1053900000A4102B2403000110400009000030215C +:1053A0000005284000A4102B04A0000300031840AF +:1053B0005440FFFC000528405060000A0004182BF0 +:1053C0000085382B54E000040003184200C3302548 +:1053D00000852023000318421460FFF900052842CD +:1053E0000004182B03E0000800C310218F4201B80D +:1053F0000440FFFE00000000AF4401803C031000A9 +:1054000024040040AF450184A3440188A3460189D8 +:10541000A747018A03E00008AF4301B83084FFFFCB +:105420000080382130A5FFFF000020210A00022A59 +:10543000240600803087FFFF8CA40000240600387B +:105440000A00022A000028218F8300388F8600304E +:105450001066000B008040213C07080024E759F843 +:10546000000328C000A710218C4400002463000121 +:10547000108800053063000F5466FFFA000328C04F +:1054800003E00008000010213C07080024E759FC55 +:1054900000A7302103E000088CC200003C0390000C +:1054A0003462000100822025AF4400208F45002097 +:1054B00004A0FFFE0000000003E000080000000060 +:1054C0003C038000346200010082202503E00008D4 +:1054D000AF44002027BDFFE0AFB100143091FFFFC3 +:1054E000AFB00010AFBF00181220001300A0802141 +:1054F0008CA2000024040002240601401040000F8A +:10550000004028210E000C5C00000000000010216B +:10551000AE000000022038218FBF00188FB10014A8 +:105520008FB0001000402021000028210000302111 +:105530000A00022A27BD00208CA200000220382188 +:105540008FBF00188FB100148FB0001000402021D1 +:1055500000002821000030210A00022A27BD002077 +:1055600000A010213087FFFF8CA500048C440000B0 +:105570000A00022A2406000627BDFFE0AFB0001093 +:10558000AFBF0018AFB100149363003E00808021CC +:105590000080282130620040000020211040000FD0 +:1055A0008E1100000E000851022020219367000098 +:1055B0002404005030E500FF50A400128E0F0000BC +:1055C000022020218FBF00188FB100148FB000106F +:1055D000A762013C0A00091127BD00200E000287C6 +:1055E000000000000E0008510220202193670000F7 +:1055F0002404005030E500FF14A4FFF20220202113 +:105600008E0F00003C1008008E1000503C0D000C66 +:10561000240BFF8001F05021314E007F01DA602120 +:10562000018D4021014B4824AF4900280220202150 +:105630008FBF00188FB100148FB00010A50200D6E4 +:1056400027BD00200A000911AF8800D027BDFFE068 +:10565000AFBF0018AFB10014AFB0001093660001E7 +:10566000008080210E00025630D1000493640005B2 +:10567000001029C2A765000034830040A363000521 +:105680000E00025F020020210E00091302002021FB +:1056900024020001AF62000C02002821A762001062 +:1056A00024040002A762001224060140A76200142D +:1056B0000E000C5CA76200161620000F8FBF0018AA +:1056C000978C00343C0B08008D6B00782588FFFF19 +:1056D0003109FFFF256A0001012A382B10E000067E +:1056E000A78800343C0F6006240E001635ED00102C +:1056F000ADAE00508FBF00188FB100148FB00010F6 +:1057000003E0000827BD002027BDFFE0AFB1001473 +:10571000AFBF0018AFB0001000A088211080000AB1 +:105720003C03600024020080108200120000000090 +:105730000000000D8FBF00188FB100148FB0001053 +:1057400003E0000827BD00208C682BF80500FFFE51 +:1057500000000000AC712BC08FBF00188FB1001487 +:105760008FB000103C09100027BD002003E00008A6 +:10577000AC692BF80E00025600A0202193650005AD +:10578000022020210E00025F30B000FF2403003E03 +:105790001603FFE7000000008F4401780480FFFE3D +:1057A000240700073C061000AF51014002202021D1 +:1057B000A34701448FBF00188FB100148FB00010B1 +:1057C000AF4601780A0002C227BD002027BDFFE8CE +:1057D000AFBF0014AFB000108F50002000000000D9 +:1057E0000E000913AF440020AF5000208FBF0014FB +:1057F0008FB0001003E0000827BD00183084FFFFC1 +:10580000008038212406003500A020210A00022A49 +:10581000000028213084FFFF008038212406003654 +:1058200000A020210A00022A0000282127BDFFD065 +:10583000AFB3001C3093FFFFAFB50024AFB2001828 +:10584000AFBF0028AFB40020AFB10014AFB000105C +:1058500030B5FFFF12600027000090218F90001CE0 +:105860008E0300003C0680002402004000033E023C +:1058700000032C0230E4007F006688241482001D9F +:1058800030A500FF8F8300282C68000A510000100B +:105890008F910014000358803C0C0800258C56881A +:1058A000016C50218D49000001200008000000001B +:1058B00002B210213045FFFF0E000236240400849E +:1058C000162000028F90001CAF8000288F910014DA +:1058D000260C002026430001018080213072FFFF4A +:1058E00016200004AF8C001C0253502B1540FFDC27 +:1058F00000000000024010218FBF00288FB5002457 +:105900008FB400208FB3001C8FB200188FB1001429 +:105910008FB0001003E0000827BD0030240E0034D3 +:1059200014AE00F9000000009203000E241F168040 +:105930003C07000CA36300219202000D0347C8211D +:105940003C066000A3620020961100123C0A7FFF13 +:10595000354CFFFFA771003C960B00102403000597 +:105960003168FFFFAF6800848E05001CAF5F002820 +:105970008F3800008CC4444803057826008F3021FE +:10598000AF66004C8F69004C24CE00013C057F00BF +:10599000AF6900508F740050AF740054AF66007050 +:1059A000AF6E00588F6D005824140050AF6D005C2E +:1059B000A3600023AF6C0064A36300378E02001461 +:1059C000AF6200488F710048AF7100248E0B001841 +:1059D000AF6B006C9208000CA3680036937F003E0A +:1059E00037F90020A379003E8F78007403058024E6 +:1059F000360F4000AF6F007493640000308900FFE1 +:105A0000513402452404FF803C04080024845A7861 +:105A10000E00028D000000003C1008008E105A7825 +:105A20000E00025602002021240600042407000173 +:105A3000A366007D020020210E00025FA36700051F +:105A40008F5F017807E0FFFE240B0002AF5001409A +:105A5000A34B01448F90001C3C081000AF48017814 +:105A60000A000362AF8000282CAD003751A0FF98D8 +:105A70008F9100140005A0803C180800271856B02C +:105A8000029878218DEE000001C00008000000009F +:105A90002418000614B80011000000003C0808009B +:105AA0008D085A7824040005AF4800208E1F001886 +:105AB000AF7F00188F79004CAF79001C8F650050C4 +:105AC000122000C0AF6500700A000362AF84002896 +:105AD0002406000710A60083240300063C050800E6 +:105AE00024A55A780E000264240400818F90001CC3 +:105AF0000011102B0A000362AF8200282407000463 +:105B000014A7FFF6240500503C1808008F185A7897 +:105B1000AF5800208E0F0008AF6F00408E090008BC +:105B2000AF6900448E14000CAF7400488E0E001054 +:105B3000AF6E004C8E0D0010AF6D00848E0A001405 +:105B4000AF6A00508E0C0018AF6C00548E04001C1D +:105B5000AF64005893630000306B00FF116501D8FB +:105B6000000000008F7400488F6900400289702394 +:105B700005C000042404008C1620FFDE240200036C +:105B8000240400823C05080024A55A780E000287F0 +:105B9000000000008F90001C000010210A0003622A +:105BA000AF820028240F000514AFFFCC240520008D +:105BB0003C0708008CE75A78AF4700208E060004A7 +:105BC000AF66005C9208000824100008A36800215A +:105BD0008F9F001C93F90009A37900208F86001C79 +:105BE00090D8000A330400FF10900011000000005C +:105BF0002885000914A0006924020002240A00205C +:105C0000108A000B34058000288D002115A00008A3 +:105C100024054000240E0040108E00053C050001C4 +:105C200024140080109400023C050002240540006A +:105C30008F7800743C19FF00031980240205782531 +:105C4000AF6F007490C4000BA36400818F84001CAC +:105C50009489000C11200192000000009490000C27 +:105C60002406FFBF24050004A770003C908F000E9F +:105C7000A36F003E8F84001C9089000FA369003F32 +:105C80008F8B001C8D6E00108F54007401D468231C +:105C9000AF6D00608D6A0014AF6A0064956C0018E7 +:105CA000A76C00689563001AA763006A8D62001CE8 +:105CB000AF62006C9167000EA367003E9368003EE0 +:105CC0000106F8241220014BA37F003E8F90001C98 +:105CD0000A000362AF8500282407002214A7FF7F73 +:105CE000240300073C0B08008D6B5A781220000C2F +:105CF000AF4B00200A000362AF830028240C00335E +:105D000010AC0014240A00283C05080024A55A7889 +:105D10000E00023C240400810A0003EB8F90001C5B +:105D20003C04080024845A780E00028D0000000014 +:105D30009363000024110050306200FF10510135C0 +:105D4000000000008F90001C000018210A00036270 +:105D5000AF8300283C0D08008DAD5A7824040081E3 +:105D6000AF4D00203C05080024A55A780E00023CE7 +:105D7000A36A00348F90001C240200090A00036209 +:105D8000AF82002802B288213225FFFF0E000236C2 +:105D9000240400840A0003628F90001C1082FFA478 +:105DA00024050400288B000311600170240C0004FA +:105DB000240300015483FF9E240540000A00043B95 +:105DC000240501003C04080024845A788F62004CAA +:105DD0000E00028D8F6300508F90001C0000202168 +:105DE0000A000362AF8400288E1000042404008A95 +:105DF000AF50002093790005333800021700015F8F +:105E0000020028219368002302002821311F00206E +:105E100017E0015A2404008D9367003F2406001206 +:105E200030E200FF10460155240400810E000256A6 +:105E30000200202193630023240500040200202196 +:105E4000346B0042A36B00230E00025FA365007D4C +:105E50008F4401780480FFFE240A0002AF50014005 +:105E6000A34A01448F90001C3C0C1000AF4C0178F9 +:105E70000A0003EC0011102B8E1000042404008A89 +:105E8000AF500020936E000531CD000215A0001622 +:105E900002002821936F003F2414000402002821EF +:105EA00031E900FF11340010240400810E00025675 +:105EB000020020219362002324080012241FFFFE09 +:105EC00034460020A3660023A368003F93790005B1 +:105ED00002002021033FC0240E00025FA3780005CA +:105EE00002002821000020210E00033400000000E1 +:105EF0000A0003EB8F90001C8E1000043C03000886 +:105F00000343A021AF500020928B000024050050D5 +:105F1000316400FF10850161240700880200202100 +:105F2000000028210E00022A2406000E928D000097 +:105F3000240EFF800200282101AE8025A2900000DF +:105F4000240400040E000C5C240600300A0003EB5D +:105F50008F90001C8E0800043C14080026945A7888 +:105F60003C010800AC285A78AF480020921F00037B +:105F700033F9000413200002240200122402000658 +:105F8000A362003F920B001B2404FFC03165003F59 +:105F900000A43825A367003E9206000330C200012A +:105FA00014400132000000008E020008AE8200089A +:105FB0003C0208008C425A8010400131000249C264 +:105FC000A76900088E14000C240C0001240300149F +:105FD000AF74002C8E0E0010AF6E0030960D0016C0 +:105FE000A76D0038960A0014A76A003AAF6C000C3F +:105FF000A76C0010A76C0012A76C0014A76C001609 +:1060000012200136A3630034920F000331F0000226 +:106010002E1100018F90001C262200080A00036246 +:10602000AF8200288E0400043C0E0008034E30218D +:10603000AF4400208E05000890CD0000240C0050D5 +:1060400031AA00FF114C00862407008824060009AD +:106050000E00022A000000000A0003EB8F90001CD3 +:106060008E04001C0E00024100000000104000F4ED +:10607000004050218F89001C240700890140202105 +:106080008D25001C240600010E00022A00000000DD +:106090000A0003EB8F90001C960D00023C140800D0 +:1060A00026945A7831AA0004514000B83C10600090 +:1060B0008E0E001C3C010800AC2E5A78AF4E00201A +:1060C000920700102408001430E200FF144800D6A4 +:1060D00000000000960B00023163000114600165AE +:1060E000000000008E020004AE8200083C1408008C +:1060F0008E945A801280015B000000008F7400743F +:106100003C0380002404000102835825AF6B007417 +:10611000A3600005AF64000C3C0708008CE75A80C0 +:106120008F86001CA7640010000711C2A76400122C +:10613000A7640014A7640016A76200088CC80008B2 +:1061400024040002AF68002C8CC5000CAF65003041 +:1061500090DF0010A37F00348F99001C9330001152 +:10616000A37000358F98001C930F0012A36F0036A8 +:106170008F89001C912E0013A36E00378F90001C96 +:10618000960D0014A76D0038960A0016A76A003A0B +:106190008E0C0018AF6C00245620FDCCAF84002874 +:1061A0003C05080024A55A780E0002640000202156 +:1061B0008F90001C0A0004A7000020218E1000040C +:1061C00024070081AF500020936900233134001070 +:1061D000128000170000000002002021000028218A +:1061E0002406001F0E00022A000000000A0003EB34 +:1061F0008F90001C3C05080024A55A780E000287E9 +:10620000240400828F90001C000028210A000362F1 +:10621000AF8500283C0408008C845A780E0014E5F1 +:10622000000000008F90001C0A000482000018216A +:106230000E00025602002021937800230200202144 +:10624000370F00100E00025FA36F002300003821FB +:1062500002002021000028210A0005A82406001FB2 +:10626000920F000C31E90001112000030000000032 +:106270009618000EA4D8002C921F000C33F90002CF +:1062800013200005000038218E0200149608001229 +:10629000ACC2001CA4C8001A0A0005432406000969 +:1062A0003C05080024A55A780E0002872404008BC0 +:1062B0008F90001C0011282B0A000362AF85002874 +:1062C000AF6000843C0A08008D4A5A783C0D0800F3 +:1062D0008DAD0050240CFF803C02000C014D1821B4 +:1062E000006C2024AF4400288E070014306B007F20 +:1062F000017A282100A2C821AF2700D88E060014F9 +:10630000AF9900D0AF2600DC8E080010251FFFFEDD +:106310000A000408AF3F01083C0508008CA55A7824 +:106320003C1908008F39005024CCFFFE00B9C02171 +:1063300003047824AF4F00283C1408008E945A7848 +:106340003C0908008D2900500289702131CD007F61 +:1063500001BA502101478021AE0600D8AF9000D08D +:10636000AE0000DC0A0003B1AE0C0108548CFE3014 +:10637000240540000A00043B240510000E00032EF3 +:10638000000000000A0003EB8F90001C8E0F442CCD +:106390003C186C62370979703C010800AC205A78CF +:1063A00015E9000824050140979F00349786002CCA +:1063B0000280282103E6C82B132000112404009238 +:1063C000240501400E000C7A240400023C01080060 +:1063D000AC225A78AF4200203C0508008CA55A78C0 +:1063E00010A00005240400830E00084500000000F2 +:1063F00010400009240400833C05080024A55A78B5 +:106400000E000264000000008F90001C0011202B81 +:106410000A000362AF8400280E0008490000000053 +:106420000A00055F8F90001C0E00084D0000000060 +:106430003C05080024A55A780A00062F2404008B86 +:10644000240400040E000C7A240500301440002AB5 +:10645000004050218F89001C240700830140202127 +:106460008D25001C0A000551240600018E04000839 +:106470000E000241000000000A00051BAE82000869 +:106480003C05080024A55A780E00023C240400872D +:106490008F90001C0A0005360011102B8F830038E6 +:1064A0008F8600301066FE9D000038213C070800F2 +:1064B00024E759FC000320C0008728218CAC000091 +:1064C00011900061246A00013143000F5466FFFA05 +:1064D000000320C00A0004F6000038213C05080033 +:1064E00024A55A780E000287240400828F90001C95 +:1064F0000A000536000010213C0B0008034B202148 +:106500002403005024070001AF420020A0830000B4 +:10651000A08700018F82001C90480004A08800180A +:106520008F85001C90A60005A08600198F9F001C77 +:1065300093F90006A099001A8F90001C921800078A +:10654000A098001B8F94001C928F0008A08F001C45 +:106550008F89001C912E0009A08E001D8F8D001CBC +:1065600091AC000AA08C001E8F8B001C3C0C080014 +:10657000258C59FC9163000B3C0B0800256B59F8E6 +:10658000A083001F8F87001C90E8000CA0880020CB +:106590008F82001C9045000D24024646A0850021F4 +:1065A0008F86001C90DF000EA09F00228F99001C98 +:1065B0009330000FA09000238F98001C93140010BC +:1065C000A09400248F8F001C91E90011A089002560 +:1065D0008F89001C8F8E00308F900038952D00140D +:1065E000000E18C025C80001A48D002895270016AC +:1065F000006C3021006BC821A487002A9525001863 +:106600003108000FA485002CA482002E8D3F001CB1 +:10661000ACCA0000AF88003011100006AF3F000088 +:10662000000038218D25001C014020210A00055161 +:1066300024060001250C00013184000F00003821E0 +:106640000A0006B8AF8400383C07080024E759F870 +:106650000087302100003821ACA000000A0004F6B9 +:10666000ACC000003C05080024A55A780A00062F9B +:10667000240400878E0400040E0002410000000084 +:106680000A00056AAE8200083084FFFF30C600FFB2 +:106690008F4201B80440FFFE00064400010430258B +:1066A0003C07200000C720253C031000AF400180BC +:1066B000AF450184AF44018803E00008AF4301B84F +:1066C00027BDFFE8AFB00010AFBF00143C0760006B +:1066D000240600021080000600A080210010102B6C +:1066E0008FBF00148FB0001003E0000827BD001812 +:1066F0003C09600EAD2000348CE5201C8F82001C0C +:106700002408FFFC00A81824ACE3201C0E0006D1CE +:106710008C45000C0010102B8FBF00148FB00010A0 +:1067200003E0000827BD00183C02600E344701005A +:1067300024090018274A040000000000000000009F +:10674000000000003C06005034C30200AF44003893 +:10675000AF45003CAF430030014018218F4B000093 +:10676000316800201100FFFD2406007F2408FFFF90 +:106770008C6C000024C6FFFF24630004ACEC000016 +:1067800014C8FFFB24E70004000000000000000024 +:10679000000000003C0F0020AF4F00300000000060 +:1067A00024AD020001A5702B2529FFFF008E2021BA +:1067B0001520FFE101A0282103E0000800000000EF +:1067C00027BDFFE0AFB10014AFBF0018AFB000109D +:1067D0003C05600E8CA20034008088211440000625 +:1067E0003C0460008C87201C2408FFFC00E8302457 +:1067F00034C30001AC83201C8F8B001C24090001D2 +:10680000ACA90034956900028D6500148D70000CF0 +:106810002D2400818D6700048D660008108000071C +:106820008D6A00102D2C00041580000E30CE00075C +:10683000312D000311A0000B000000002404008B88 +:10684000020028210E0006D1240600030011102B9F +:106850008FBF00188FB100148FB0001003E0000844 +:1068600027BD002015C0FFF62404008B3C03002048 +:10687000AF4300300000000024020001AF8200148A +:106880000000000000000000000000003C1F01505C +:10689000013FC825253800033C0F600EAF47003884 +:1068A00000181882AF46003C35E8003CAF59003074 +:1068B000274704008F4400003086002010C0FFFDF1 +:1068C00000000000106000082466FFFF2403FFFFA3 +:1068D0008CEB000024C6FFFF24E70004AD0B000092 +:1068E00014C3FFFB250800043C08600EAD09003806 +:1068F0000000000000000000000000003C07002035 +:10690000AF470030000000000E0006F901402021D2 +:1069100002002821000020210E0006D124060003D9 +:106920000011102B8FBF00188FB100148FB0001012 +:1069300003E0000827BD002027BDFFE0AFB200182C +:106940003092FFFFAFB10014AFBF001CAFB000101A +:106950001640000D000088210A0007AA022010211D +:1069600024050001508500278CE5000C0000000D77 +:10697000262300013071FFFF24E200200232382B71 +:1069800010E00019AF82001C8F8200141440001622 +:106990008F87001C3C0670003C0320008CE5000043 +:1069A00000A62024148300108F84003C00054402BC +:1069B0003C09800000A980241480FFE9310600FF13 +:1069C0002CCA00095140FFEB262300010006688015 +:1069D0003C0E080025CE578C01AE60218D8B000047 +:1069E0000160000800000000022010218FBF001C81 +:1069F0008FB200188FB100148FB0001003E00008B0 +:106A000027BD00200E0006D1240400841600FFD804 +:106A10008F87001C0A00078BAF80003C90EF0002BC +:106A200000002021240600090E0006D1000F2E00D0 +:106A30008F87001C0010102B0A00078BAF82003CD0 +:106A4000020028210E0006DF240400018F87001CAD +:106A50000A00078BAF82003C020028210E0006DFEF +:106A6000000020210A0007C38F87001C0E00071FAB +:106A7000020020210A0007C38F87001C30B0FFFFEF +:106A8000001019C08F5801B80700FFFE3C1F2004FA +:106A90003C191000AF430180AF400184AF5F018813 +:106AA000AF5901B80A00078C262300013082FFFF8E +:106AB00014400003000018210004240224030010E5 +:106AC000308500FF14A000053087000F2466000801 +:106AD0000004220230C300FF3087000F14E00005DD +:106AE000308900032468000400042102310300FF00 +:106AF0003089000315200005388B0001246A00024C +:106B000000042082314300FF388B00013164000112 +:106B100010800002246C0001318300FF03E00008B4 +:106B200000601021308BFFFF000B394230E600FF80 +:106B30003C09080025295978000640800109602198 +:106B40008D8700003164001F240A0001008A1804A8 +:106B500030A500FF00E3202514A000020003102749 +:106B600000E22024240F000100CF700401096821F5 +:106B7000000E282714800005ADA400008F86000CAD +:106B800000A6102403E00008AF82000C8F88000CE0 +:106B900001C8102503E00008AF82000C3C06001F6E +:106BA0003C0360003084FFFF34C5FF8024020020D6 +:106BB000AC602008AC60200CAC602010AC652014E8 +:106BC000AC642018AC62200000000000000000004F +:106BD00003E000080000000027BDFFE82402FFFFDB +:106BE000AFBF0010AF82000C000020213C0608005F +:106BF00024C659782405FFFF248900010004408041 +:106C00003124FFFF010618212C87002014E0FFFA31 +:106C1000AC6500000E0008160000202124020001CF +:106C20003C04600024050020AC822018AC852000C4 +:106C3000000000000000000000000000244A0001E5 +:106C40003142FFFF2C46040014C0FFF78FBF001035 +:106C500003E0000827BD00188F8300082C620400A1 +:106C600003E00008384200018F830008246200011D +:106C700003E00008AF8200088F8300082462FFFF52 +:106C800003E00008AF82000827BDFFE0AFB10014A9 +:106C9000AFBF0018AFB000108F6B00303C06600033 +:106CA00000808821ACCB20088F6A002C3C02800039 +:106CB00024030008ACCA200C9769003A9768003892 +:106CC00000092C003107FFFF00A72025ACC42010CD +:106CD000ACC22014ACC32000000000000000000083 +:106CE000000000003C0360008C6D200031AC000807 +:106CF0001580FFF9000000008C6E201405C00020F4 +:106D0000000000000E0007DA8F84000C00024080B3 +:106D10003C09080025295978010938218CE4000034 +:106D20000E0007DA00028140020220213090FFFFAE +:106D3000020020210E0007F8000028213C0C8000F2 +:106D4000022C58253210FFFF3C116000240A00205D +:106D5000AE2B2014AE302018AE2A20000000000018 +:106D60000000000000000000020010218FBF00188A +:106D70008FB100148FB0001003E0000827BD002081 +:106D80008C6620143C02001F3443FF803C1FFFE848 +:106D900000C3C02437F9080003198021001079C20C +:106DA0003C0C8000022C582531F0FFFF3C116000A4 +:106DB000240A0020AE2B2014AE302018AE2A20006A +:106DC0000000000000000000000000000200102190 +:106DD0008FBF00188FB100148FB0001003E00008BF +:106DE00027BD002027BDFFE8AFB000103402FFFF31 +:106DF0003090FFFFAFBF00141202000602002021F6 +:106E00000E00081600000000020020210E0007F806 +:106E1000240500018F8400088FBF00148FB000107C +:106E20002483FFFF27BD001803E00008AF8300089C +:106E3000000439C230E6003F00043B42000718401E +:106E4000240210002CC4002024C8FFE0AF42002C14 +:106E5000246300011480000330A900FF00071840DC +:106E6000310600FF0003608024080001019A5821C8 +:106E70003C0A000E00C82804016A382111200005D0 +:106E8000000530278CE900000125302503E00008CB +:106E9000ACE600008CEE000001C6682403E00008A8 +:106EA000ACED000027BDFFE8AFBF0014AFB000108D +:106EB0003C0460008C8508083403F00030A2F00028 +:106EC00050430006240200018C8708083404E000C7 +:106ED00030E6F00010C4001E24020002AF82004021 +:106EE0003C1060003C0A0200AE0A0814240910009D +:106EF0003C08000E8E03440003482021AF49002CBB +:106F0000240501200E000CC0000030218F830040BA +:106F1000106000043C021691240B0001106B000E5F +:106F20003C023D2C344F0090AE0F44088FBF00143C +:106F30008FB000103C0C6000240E10003C0D0200CD +:106F400027BD0018AD8E442003E00008AD8D081069 +:106F50000A0008E7AF8000403C0218DA344F009086 +:106F6000AE0F44088FBF00148FB000103C0C6000BF +:106F7000240E10003C0D020027BD0018AD8E4420E9 +:106F800003E00008AD8D08100A0008BB24050001CD +:106F90000A0008BB000028213C08080025085D8481 +:106FA0002404FFFF010018212402001E2442FFFFD9 +:106FB000AC6400000441FFFD246300043C070800AA +:106FC00024E75E008CE5FFFC2404001C240600017D +:106FD000308A001F0146480424840001000910275C +:106FE0002C8300201460FFFA00A22824ACE5FFFCEB +:106FF0003C05666634A4616E3C06080024C65EC08B +:10700000AF840058AF88009C2404FFFF00C0182103 +:107010002402001F2442FFFFAC6400000441FFFD76 +:10702000246300043C0766663C05080024A55E80D6 +:10703000AF86004834E6616EAF8600982404FFFFF7 +:1070400000A018212402000F2442FFFFAC640000BE +:107050000441FFFD246300043C0B66663C06080007 +:1070600024C65E003568616EAF8500A4AF880070ED +:107070002404FFFF00C018212402001F2442FFFF48 +:10708000AC6400000441FFFD246300043C0D66660F +:107090003C0A0800254A5F4035AC616EAF8600901F +:1070A000AF8C005C2404FFFF014018212402000380 +:1070B0002442FFFFAC6400000441FFFD2463000490 +:1070C0003C09080025295F508D27FFFC2404000699 +:1070D000240500013099001F0325C0042484000109 +:1070E000001878272C8E002015C0FFFA00EF3824F6 +:1070F000AD27FFFC3C09666624030400240403DC7E +:1071000024050200240600663522616E3C08080052 +:1071100025085A84AF820074AF830044AF83006CAB +:10712000AF830050AF830084AF8A008CAF840064CB +:10713000AF85004CAF860054AF840078AF85006007 +:10714000AF86008001001821240200022442FFFFC4 +:10715000AC6000000441FFFD24630004240400032C +:107160002403000C3C0A0800254A5A90AF8A0068A4 +:107170000A00098E2405FFFF000418802484000102 +:10718000006858212C8700C014E0FFFBAD650000AB +:107190003C0E666635CD616E240C17A024081800DD +:1071A000AF8D0088AF8C009403E00008AF88007CAE +:1071B0002484007F000421C200004021000030210F +:1071C00000003821000028210A0009A5AF8400A092 +:1071D0001060000624E7000100C4302124A500014E +:1071E0002CC20BF51440FFFA2CA300663C090800E2 +:1071F00025295F4001201821240200032442FFFFBB +:10720000AC6000000441FFFD2463000410E0001A9C +:1072100024E3FFFF0003294210A0000A0000202100 +:107220002406FFFF3C03080024635F402484000120 +:107230000085502BAC660000250800011540FFFBBF +:107240002463000430E2001F10400008000868803A +:10725000240C0001004C38040008588001692821E2 +:1072600024E6FFFF03E00008ACA6000001A94021CE +:107270002409FFFFAD09000003E000080000000042 +:10728000AF4400283C04000C034420210005288260 +:107290000A000CC000003021000421803C03600083 +:1072A000AC6410080000000000052980AC65100CDB +:1072B0000000000003E000088C62100C27BDFFE80E +:1072C0000080282124040038AFBF00140E0009D527 +:1072D000AFB0001024040E00AF4400283C10000C96 +:1072E00003502021240500100E000CC000003021A6 +:1072F00003501021AC400000AC40000424040038CE +:107300008FBF00148FB0001024053FFF27BD001869 +:107310000A0009D58C430000000421803C03600072 +:10732000AC641008000000008C62100C03E0000840 +:107330000002118227BDFFC8AFB400208F940068FF +:10734000AFBE0030AFB7002CAFB600280000B821A8 +:107350000080B021241E00C0AFBF0034AFB50024B0 +:10736000AFB3001CAFB20018AFB10014AFB0001043 +:107370000A000A12AFA5003C504000018F9400683B +:1073800027DEFFFF13C00028269400048E92000021 +:107390003C03080024635D801240FFF70283102B3A +:1073A0003C04080024845A84028410230002A8C0EC +:1073B000000098210A000A212411000100118840D0 +:1073C000122000260000000002B380210251282470 +:1073D0000200202110A0FFF9267300010E0009DE33 +:1073E000000000000016684032EC000101AC2021D2 +:1073F0000E0009D5020028218F89009426F700018C +:107400008FA6003C3AEB0001316A00012528FFFFFE +:107410000011382702CAB021AF88009416E6FFE7B2 +:1074200002479024AE92000002E010218FBF00348A +:107430008FBE00308FB7002C8FB600288FB5002488 +:107440008FB400208FB3001C8FB200188FB10014CE +:107450008FB0001003E0000827BD00383C0E080084 +:1074600025CE5D80028E102B0A000A0DAE92000020 +:1074700027BDFFD8AFB10014AFB00010AFBF0020E0 +:10748000AFB3001CAFB2001800A0882110A0001FED +:10749000000480403C13080026735A840A000A5AEC +:1074A0002412000112200019261000010E0009F517 +:1074B00002002021000231422444FFA0000618806F +:1074C0003045001F2C8217A1007318212631FFFFC1 +:1074D0001040FFF400B230048C690000020020214B +:1074E00024053FFF012640241500FFEE0126382524 +:1074F0000E0009D5AC6700008F8A009426100001A9 +:10750000254700011620FFE9AF8700948FBF0020B8 +:107510008FB3001C8FB200188FB100148FB0001011 +:1075200003E0000827BD00288F85009C00805821BB +:107530000000402100004821240A001F3C0C0800E4 +:10754000258C5DFC3C0D080025AD5D848CA60000FB +:1075500050C000140000402100AD1023000238C0CC +:10756000240300010A000A930000202115000003F3 +:1075700000E410212448202400004821252900018E +:10758000512B00132506DFDC106000062484000167 +:1075900000C3702415C0FFF5000318400A000A91CB +:1075A0000000402110AC002624A300040060282124 +:1075B000254AFFFF1540FFE5AF85009C512B0004D5 +:1075C0002506DFDC0000402103E000080100102157 +:1075D0000006614230C5001F000C50803C070800C7 +:1075E00024E75D8424040001014730211120000FAD +:1075F00000A420043C05080024A55E0014800005BA +:107600002529FFFF24C6000410C50011000000005A +:10761000240400018CCF00000004C0270004204097 +:1076200001F868241520FFF5ACCD00008F99007893 +:1076300001001021032B482303E00008AF890078E4 +:107640003C05080024A55D840A000A9B0000402137 +:107650003C06080024C65D840A000AB42404000124 +:10766000308800FF240200021102000A24030003F4 +:107670001103005C8F8900A4240400041104005F3E +:1076800024050005110500670000182103E000082B +:10769000006010218F8900483C0C0800258C5EC0DA +:1076A0003C04080024845F40240300201060000F85 +:1076B00000005821240D0002240E00033C0F080096 +:1076C00025EF5EC08D27000014E0000B30F9FFFFAE +:1076D000252900040124C02B53000001018048210A +:1076E0002463FFFF5460FFF88D270000016018211C +:1076F00003E0000800601021132000323C0500FF69 +:1077000030E200FF004030211040004200005021D4 +:1077100024050001000020210005C84000A6C02467 +:1077200017000003332500FF14A0FFFB2484000191 +:10773000012CC023001828C000AA6021008C502111 +:107740003144001F240C0001008C18040003102792 +:1077500000E23024110D0041AD260000110E004C56 +:10776000000A1840110D00368F87006C510E00562C +:107770008F8C0060240D0004110D005A8F8E008440 +:10778000240E0005150EFFDA01601821240B1430B9 +:1077900011400006000018218F8400A0246300011E +:1077A000006A402B1500FFFD016458218F8A00807C +:1077B000AF89008C016018212549FFFF0A000AEB00 +:1077C000AF89008000E52024000736021080FFD03A +:1077D000240A001800075402314600FF0A000AF389 +:1077E000240A00103C0C0800258C5E803C04080034 +:1077F00024845EC00A000ADA240300103C0C08004E +:10780000258C5E003C04080024845E800A000AD9AE +:107810008F89009000071A02306600FF0A000AF301 +:10782000240A00088F89008C3C0C0800258C5F40DE +:107830003C04080024845F500A000ADA2403000490 +:10784000000A4080250B003024E6FFFF016018216C +:10785000AF8900480A000AEBAF86006C000AC982B3 +:10786000001978803C07080024E75E8001E72021AA +:10787000000A18428C8F00003079001F032C380456 +:107880000007C02701F860240A000B08AC8C000038 +:10789000000331420006288000AF28213062001F1B +:1078A0008CB8000024630001004CC804000321428E +:1078B000001938270004108003073024004F2021CE +:1078C0000A000B4CACA60000000A68C025AB0032D1 +:1078D000258AFFFF01601821AF8900A40A000AEB86 +:1078E000AF8A0060254B1030AF89009001601821ED +:1078F00025C9FFFF0A000AEBAF8900843086000724 +:107900002CC2000610400014000000000006408059 +:107910003C030800246357B0010338218CE40000C5 +:1079200000800008000000002409000310A9000ED8 +:1079300000000000240A000510AA000B000000004F +:10794000240B000110AB0008000000008F8C00A089 +:1079500010AC00050000000003E00008000010214A +:107960000A000A7900A020210A000AC700C02021CD +:1079700027BDFFE8308400FF240300021083000BC2 +:10798000AFBF0010240600031086003A240800044C +:1079900010880068240E0005108E007F2CAF143074 +:1079A0008FBF001003E0000827BD00182CA2003094 +:1079B0001440FFFC8FBF001024A5FFD0000531C28A +:1079C000000668803C07080024E75EC001A730215C +:1079D0008CC900000005288230AC001F240B000178 +:1079E000018B50048F840048012A4025ACC8000058 +:1079F0008C83000050600001AF8600488F98006CB7 +:107A000030AE000124A6FFFF270F000115C00002C1 +:107A1000AF8F006C24A600010006414200082080C0 +:107A2000008718218C79000030C2001F2406000155 +:107A30000046F804033F382410E0FFDA8FBF00103F +:107A40000005C182001870803C0F080025EF5E80A1 +:107A500001CF48218D2B00000005684231A5001F91 +:107A600000A66004016C502527BD001803E0000843 +:107A7000AD2A00002CA7003014E0FFCA8FBF001011 +:107A800030B900071723FFC724A8FFCE00086A02F9 +:107A9000000D60803C0B0800256B5E80018B30215F +:107AA0008CC40000000828C230AA001F240800016E +:107AB000014848048F8200A400891825ACC3000047 +:107AC0008C5F000053E00001AF8600A40005704009 +:107AD000000E7942000F28803C04080024845EC018 +:107AE00000A418218C6B000025DF000131CD001FA0 +:107AF000001F514201A86004016C4825000A108053 +:107B0000AC690000004428218CA600008F9800601A +:107B100033F9001F8FBF00100328380400C77825F1 +:107B2000270E000127BD0018ACAF000003E00008DD +:107B3000AF8E006024A5EFD02CB804001300FF998D +:107B40008FBF001000053142000658803C0A080033 +:107B5000254A5E00016A30218CC4000030A3001F5A +:107B600024090001006910048F9900900082F82513 +:107B7000ACDF00008F27000050E00001AF860090CE +:107B80008F8D00848FBF001027BD001825AC000129 +:107B900003E00008AF8C008415E0FF828FBF001067 +:107BA0008F8600A0000610400046F821001F21002B +:107BB00003E4C8210019384024F8143000B8402BE1 +:107BC0001100FF788FBF001024A4EBD00E00021329 +:107BD00000C0282100027942000F70803C0D08008F +:107BE00025AD5F4001CD20218C8B0000304C001F63 +:107BF00024060001018618048F89008C016350253A +:107C0000AC8A00008D25000050A00001AF84008CDC +:107C10008F9800808FBF001027BD00182708000133 +:107C200003E00008AF88008030A5000724030003AC +:107C300010A3001028A2000414400008240700022A +:107C40002403000410A300152408000510A8000F49 +:107C50008F8500A003E000080000000014A7FFFDCE +:107C60000080282114C3FFFB240400020A000B8BB0 +:107C700000000000240900050080282110C9FFFB36 +:107C80002404000303E000080000000014C5FFF115 +:107C9000008028210A000B8B24040005240A00011F +:107CA0000080282110CAFFF12404000403E000082A +:107CB0000000000027BDFFE0AFB00010000581C24A +:107CC0002603FFD024C5003F2C6223D024C6007FAA +:107CD000AFB20018AFB10014AFBF001C309100FF6D +:107CE000000691C2000529820200202110400008F0 +:107CF0002403FFFF0E000A4B0000000002002021B9 +:107D0000022028210E000C390240302100001821E9 +:107D10008FBF001C8FB200188FB100148FB00010FD +:107D20000060102103E0000827BD002027BDFFD818 +:107D300024A2007FAFB3001CAFB20018000299C2AA +:107D4000309200FF24A3003F02402021026028213E +:107D5000AFB10014AFB00010AFBF00200E000B6E2B +:107D60000003898200408021004020210220282138 +:107D700014400009000018218FBF00208FB3001CA1 +:107D80008FB200188FB100148FB000100060102166 +:107D900003E0000827BD00280E0009FC00000000D9 +:107DA00000402821020020211051FFF3001019C0CB +:107DB0000E000A4B00000000020020210240282192 +:107DC0000E000C39026030218FBF00208FB3001CE1 +:107DD0008FB200188FB100148FB00010000018216E +:107DE0000060102103E0000827BD00283084FFFF59 +:107DF00030A5FFFF1080000700001821308200012D +:107E00001040000200042042006518211480FFFB8E +:107E10000005284003E000080060102110C00007A2 +:107E2000000000008CA2000024C6FFFF24A500046F +:107E3000AC82000014C0FFFB2484000403E00008AF +:107E40000000000010A0000824A3FFFFAC86000083 +:107E500000000000000000002402FFFF2463FFFF79 +:107E60001462FFFA2484000403E00008000000000C +:107E700030A5FFFF8F4201B80440FFFE3C076015AC +:107E800000A730253C031000AF440180AF400184BF +:107E9000AF46018803E00008AF4301B88F8500D0EA +:107EA0002C864000008018218CA700840087102BAE +:107EB00014400010000000008CA800842D06400033 +:107EC00050C0000F240340008CAA0084008A482B75 +:107ED000512000018CA3008400035A42000B208033 +:107EE0003C05080024A558000085182103E000087F +:107EF0008C62000014C0FFF4000000002403400066 +:107F000000035A42000B20803C05080024A55800BD +:107F10000085182103E000088C6200008F8300D0E8 +:107F2000906600D024C50001A06500D08F8500D0E8 +:107F3000906400D090A200D210440017000000000E +:107F4000936C00788F8B00BC318A00FFA16A000C13 +:107F500025490001938700C4312200FF3048007F8B +:107F60001107000B00026827A36200788F4E01788A +:107F700005C0FFFE8F9900B0241800023C0F1000CE +:107F8000AF590140A358014403E00008AF4F017806 +:107F90000A000D0931A20080A0A000D00A000CFF49 +:107FA000000000008F8700D027BDFFC8AFBF0030A2 +:107FB000AFB7002CAFB60028AFB50024AFB4002097 +:107FC000AFB3001CAFB20018AFB10014AFB00010D7 +:107FD00094E300E094E200E2104300D72405FFFFA1 +:107FE0003C047FFF3497FFFF2415FF800A000DF04B +:107FF0003C16000E108A00D18FBF00308F9100B068 +:108000003C1808008F18005C001230C0001291402C +:108010000311702101D57824AF4F002C94EC00E2BD +:1080200031CD007F01BA5821318A7FFF0176482186 +:10803000000A804002091021945300003C08080007 +:108040008D0800580246C02132733FFF001319808B +:10805000010320210224282130BF007F03FAC82118 +:1080600000B5A024AF54002C0336A0218E87001049 +:108070008E8F003003785821256D008800EF702323 +:10808000240C0002AE8E0010AF8D00ACA16C0088F5 +:10809000976A003C8E8400308F9100AC0E000CD6A5 +:1080A0003150FFFF00024B80020940253C02420094 +:1080B00001022025AE2400048E8300048F8D00ACC5 +:1080C0008E860000240E0008ADA3001CADA600188B +:1080D000ADA0000CADA00010929F000A33F900FF84 +:1080E000A5B90014968500083C1F000CA5A5001634 +:1080F0009298000A331100FFA5B100209690000865 +:1081000024180005A5B00022ADA00024928F000B1A +:108110002410C00031E700FFA5A70002A1AE0001B6 +:108120008E8C00308F8B00AC8F8400B0AD6C00085B +:108130003C0A08008D4A005401444821013540247E +:10814000AF4800283C0208008C4200540044302113 +:1081500030C3007F007AC821033F282102458821CF +:10816000AF9100BCAF8500C0A23800008F8A00BC70 +:108170002403FFBF2418FFDF954F000201F03824CD +:1081800000F37025A54E0002914D000231AC003F76 +:10819000358B0040A14B00028F8600BC8F8900D038 +:1081A000ACC000048D28007C3C098000ACC80008ED +:1081B00090C4000D3082007FA0C2000D8F8500BCEE +:1081C00090BF000D03E3C824A0B9000D8F9100BC3F +:1081D0009233000D02789024A232000D8E9000346C +:1081E0008F8B00BCAD7000108E87002C8E8F0030FE +:1081F00000EF7023AD6E0014916D001831AC007F5C +:10820000A16C00188F9F00BC8E8A00308FE8001888 +:10821000015720240109302400C41025AFE20018C2 +:108220009283000AA3E3001C969900088F8500BC86 +:108230008F9800D0A4B9001E8E9000308E8400303C +:108240000E0002138F0500848F8500D0000291403C +:108250000002990090AF00BC0253882100403021F9 +:1082600031E7000210E0000302118021000290803B +:108270000212802190B900BC3327000410E00002F4 +:108280000006F880021F80218E9800308F8B00BC82 +:1082900024068000330F0003000F702331CD00034C +:1082A000020D6021AD6C000494A400E294AA00E2E7 +:1082B00094B000E231497FFF2522000130537FFF57 +:1082C0000206182400734025A4A800E294A400E24A +:1082D0003C1408008E94006030917FFF123400221D +:1082E000000000000E000CF6000000008F8700D098 +:1082F0000000282194F300E094F000E21213000F34 +:108300008FBF003090E900D090E800D1313200FFFB +:10831000310400FF0244302B14C0FF36264A00010E +:1083200090EE00D2264B000131CD00FF008D602180 +:10833000158BFF338F9100B08FBF00308FB7002CAB +:108340008FB600288FB500248FB400208FB3001C97 +:108350008FB200188FB100148FB0001000A0102150 +:1083600003E0000827BD003894A300E20066402423 +:10837000A4A800E290A400E290B900E2309100FFCE +:108380000011A1C20014F827001F39C03332007F4A +:10839000024730250A000DE8A0A600E23084FFFF66 +:1083A00030A5FFFFAF440018AF45001C03E00008F4 +:1083B0008F42001427BDFFB8AFB000208F9000D0CF +:1083C0003084FFFFAFA40010AFBF0044AFBE004039 +:1083D000AFB7003CAFB60038AFB50034AFB4003033 +:1083E000AFB3002CAFB20028AFB10024A7A0001893 +:1083F000920600D1920500D030C400FF30A300FFE8 +:108400000064102B10400122AFA00014920900D08C +:108410008FB50010312800FF0088382324F4FFFFB7 +:108420000014882B0015982B02339024524001260B +:108430008FB40014961E0012961F00108FB7001004 +:1084400003DFC823001714000019C400000224032E +:108450000018140302E2B02A52C00001004020219B +:108460000284282B10A0000200801821028018210D +:1084700000033C0000071C033064FFFF2C8600094A +:1084800014C000020060B821241700088E0A0008FA +:10849000001769808E09000C31ABFFFF3C0C001007 +:1084A000016C402527520400AF4A0038AF9200B853 +:1084B000AF49003CAF480030000000000000000061 +:1084C00000000000000000000000000000000000AC +:1084D00000000000000000008F4F000031EE00207F +:1084E00011C0FFFD0017982A027110240A000E83A4 +:1084F0000000B02155E001019258000131130080C5 +:10850000126001CF012020219655001232A5FFFFF5 +:108510000E000CCBA7B500188F9000D00291A023BD +:1085200026CD00018F9100B8000DB4000016B403F1 +:108530002638004002D7582A0014882B2405000151 +:108540000300902101711024AF9800B8AFA500146A +:10855000104001BC8F8900B03C0C08008D8C005489 +:10856000240BFF80921E00D001895021014B28244A +:10857000921900D0AF4500288E4700103C08080033 +:108580008D0800583C1808008F18005430E33FFF56 +:108590000003218001043021012658212402FF809C +:1085A0000162F824920C00D0AF5F002C92480000CA +:1085B00033D100FF333500FF0309982100117140CA +:1085C000001578C0326D007F01CF382101BA282113 +:1085D000318300FF3164007F3C0A000C00AA88212F +:1085E0000367F02100033140009A10213108003F59 +:1085F0003C1F000E00D1C021005F982127D90088C0 +:108600002D150008AF9100C0AF9900ACAF9800BC29 +:10861000AF9300B412A0018A00008821240E00014B +:10862000010E4004310D005D11A0FFB2310F0002B8 +:108630008E4A00283C0300803C04FFEFAE6A000035 +:108640008E450024A260000A3488FFFFAE65000456 +:108650009247002C3C1FFF9F37FEFFFFA267000CD4 +:108660008E62000C3C180040A267000B00433025CE +:1086700000C8C824033E88240238A825AE75000C23 +:108680008E490004AE6000183C0F00FFAE69001474 +:108690008E4D002C35EEFFFF8F8B00B001AE6024B5 +:1086A000AE6C00108E470008A660000896450012C8 +:1086B000AE6700208E42000C30B03FFF00105180AA +:1086C000AE6200248E5E0014014B182130A400011C +:1086D000AE7E00288E590018000331C2000443808A +:1086E000AE79002C8E51001C00C8F821A67F001C1A +:1086F000AE710030965800028E550020A678001EFC +:10870000AE75003492490033313000045600000544 +:10871000925000008F8C00D08D8B007CAE6B0030AF +:10872000925000008F8F00BCA1F00000924E0033E9 +:1087300031CD000251A00007925E00018F8900BC7C +:108740002418FF80913100000311A825A1350000F5 +:10875000925E00018F9900BC2409FFBF240BFFDF4C +:10876000A33E00018F9500BC92B8000D3311007F2D +:10877000A2B1000D8F8E00BC91D0000D02097824AB +:10878000A1CF000D8F8800BC8E6D0014910A000DE2 +:108790002DAC0001000C2940014B382400E51825C0 +:1087A000A103000D964200128F8800BC8F8700D075 +:1087B000A50200028E45000490FF00BC30A4000317 +:1087C0000004302330DE000300BE102133F9000224 +:1087D00017200002244400342444003090E200BCFE +:1087E00000A2302430DF000417E0000224830004DC +:1087F000008018218F8F00AC24090002AD03000413 +:10880000A1E90000924E003F8F8D00ACA1AE0001A7 +:108810008F9500AC924C003F8E440004A6AC000241 +:10882000976B003C0E000CD63170FFFF00025380A6 +:10883000020A38253C05420000E51825AEA30004D5 +:108840008F8600AC8E480038ACC800188E440034C7 +:10885000ACC4001CACC0000CACC00010A4C0001420 +:10886000A4C00016A4C00020A4C00022ACC00024F4 +:108870008E6400145080000124040001ACC4000880 +:108880000E000CF6241100010A000E768F9000D025 +:10889000920F00D2920E00D08FB5001031EB00FF86 +:1088A00031CD00FF008D6023016C50212554FFFF66 +:1088B0000014882B0015982B023390241640FEDDFF +:1088C000000000008FB400148FBF00448FBE004032 +:1088D0003A8200018FB7003C8FB600388FB5003464 +:1088E0008FB400308FB3002C8FB200288FB10024DA +:1088F0008FB0002003E0000827BD0048331100209E +:10890000122000EF24150001921E00BC241F00015C +:108910000000A82133D900011320000DAFBF001CB7 +:108920008E4400148E0800840088102B144000022E +:10893000008030218E0600848E03006400C3A82BC3 +:1089400016A0000200C020218E0400640080A8212F +:108950008E4700148E05006400E5302B14C0000221 +:1089600000E020218E0400640095F02313C0000471 +:108970008FAC001C240A0002AFAA001C8FAC001CA4 +:10898000028C582B156000A8000018218E4F00386B +:108990008E6D000C3C0E0080AE6F00008E4A0034DD +:1089A0003C10FF9F01AE5825AE6A00049246003F7E +:1089B000360CFFFF016C38243C0500203C03FFEF20 +:1089C000A266000B00E510253468FFFF8F8700B812 +:1089D0000048F8243C04000803E4C825AE79000CE4 +:1089E0008CF80014AE60001802BE7821AE78001436 +:1089F0008CF10018AE71001C8CE90008AE690024EF +:108A00008CEE000CAE6F002CAE600028AE6E002025 +:108A1000A6600038A660003A8CED001401B58023F2 +:108A2000021E902312400011AE72001090EA003D29 +:108A30008E6500048E640000000A310000A6C82183 +:108A4000000010210326402B0082F82103E8C021FA +:108A5000AE790004AE78000090F1003DA271000AEA +:108A60008F8900B895320006A67200088F9800AC76 +:108A70002419000202A02021A31900009769003CDC +:108A80008F9200AC0E000CD63131FFFF00027B80CC +:108A90008F8500B8022F68253C0E420001AE80256C +:108AA000AE5000048F8400AC8CAC0038AC8C001845 +:108AB0008CAB0034AC8B001CAC80000CAC80001084 +:108AC000A4800014A4800016A4800020A4800022AA +:108AD000AC80002490A7003FA487000212A00135BB +:108AE0002403000153C0000290A2003D90A2003E6A +:108AF00024480001A08800018F9F00ACAFF500085A +:108B00008F8300D024070034906600BC30C500027B +:108B100050A00001240700308F9200B88F8A00BC5B +:108B2000906D00BC924B00002412C00032A50003DF +:108B3000A14B00008F8600B88F8800BC240200047F +:108B400090C400010045182330790003A1040001FE +:108B50008F8A00BC8F9F00B800F53821955800021D +:108B600097E9001200F9382103128824312F3FFFC2 +:108B7000022F7025A54E00029150000231A800047A +:108B8000320C003F358B0040A14B000212A00002C6 +:108B90008F8500BC00E838218F8E00D0ACA7000480 +:108BA000240BFFBF8DCD007C2EA400012403FFDF2A +:108BB000ACAD000890B0000D00044140320C007FC5 +:108BC000A0AC000D8F8600BC90CA000D014B102494 +:108BD000A0C2000D8F8700BC90E5000D00A3F82413 +:108BE00003E8C825A0F9000D8F9100B88F8D00BC57 +:108BF0008E380020ADB800108E290024ADA90014D5 +:108C00008E2F0028ADAF00188E2E002C0E000CF613 +:108C1000ADAE001C8FB0001C240C0002120C00EE44 +:108C20008F9000D08FA3001C006088211460000288 +:108C30000060A8210000A02156A0FE390291A023C7 +:108C40000014882B8FA90010960700103C1E0020EE +:108C50000136402302C750213112FFFFA60A00103F +:108C6000AFB20010AF5E0030000000009617001099 +:108C7000961300121277008F000000008E05000C82 +:108C80008E0B00080016698000AD7021000DC7C36F +:108C900001CDA82B0178782101F56021AE0E000CE2 +:108CA000AE0C00088FB300100013B82B02378024DD +:108CB0001200FF048F9000D00A000E3C000000005C +:108CC0008E4D0038A6600008240B0003AE6D000036 +:108CD0008E500034A260000A8F9800B8AE70000475 +:108CE0003C0500809311003FA26B000C8E6F000CBE +:108CF0003C0EFF9FA271000B01E5102535CCFFFF54 +:108D00003C03FFEF8F9200B8004C30243464FFFF27 +:108D100000C4F824AE7F000C8E590014964800124F +:108D20008F8A00B0AE7900108E490014AE60001832 +:108D3000AE600020AE690014AE6000248E470018BB +:108D400031093FFF0009F180AE6700288E4D000811 +:108D500003CA802131180001AE6D00308E4F000C27 +:108D60008F8C00AC001089C200185B80022B282178 +:108D7000240E0002A665001CA6600036AE6F002C13 +:108D8000A18E00009763003C8F8A00AC3C04420037 +:108D90003062FFFF00443025AD4600048F9F00B8CD +:108DA000240700012411C0008FF30038240600348A +:108DB000AD5300188FF90034AD59001CAD40000CC4 +:108DC000AD400010A5400014A5400016A5400020AD +:108DD000A5400022AD400024A5550002A147000196 +:108DE0008F9E00AC8F8800B88F9200BCAFD5000872 +:108DF000910D0000A24D00008F9000B88F8B00BC39 +:108E000092180001A17800018F8400BC94850002B3 +:108E100000B1782401E97025A48E0002908C000234 +:108E20003183003FA08300028F8300D08F8400BC79 +:108E3000906200BC305300025260000124060030F2 +:108E4000AC8600048C6F007C2403FFBF02A0882145 +:108E5000AC8F0008908E000D31CC007FA08C000DEF +:108E60008F8600BC90C2000D00432024A0C4000DDA +:108E70008F8900BC913F000D37F90020A139000D0A +:108E80008F8800B88F9300BC8D070020AE6700105C +:108E90008D0A0024AE6A00148D1E0028AE7E0018D4 +:108EA0008D12002C0E000CF6AE72001C0A00103D54 +:108EB0008F9000D0960E00148E03000431CCFFFF7B +:108EC000000C10C000622021AF44003C8E1F000443 +:108ED0008F46003C03E6C8231B20003C0000000036 +:108EE0008E0F000025E200013C05001034B500089B +:108EF000AF420038AF550030000000000000000015 +:108F00000000000000000000000000000000000061 +:108F100000000000000000008F580000330B00200C +:108F20001160FFFD000000008F5304003C0D002085 +:108F3000AE1300088F570404AE17000CAF4D00307D +:108F4000000000003C0608008CC600442416000106 +:108F500010D600BD00000000961F00123C0508005E +:108F60008CA5004000BFC821A61900129609001464 +:108F700025270001A6070014960A00143144FFFFBC +:108F80005486FF498FB30010A60000140E000E1681 +:108F900030A5FFFF3C0408008C84002496030012D7 +:108FA0000044102300623023A60600120A00105964 +:108FB0008FB30010A08300018F8200AC2404000155 +:108FC000AC4400080A000FF08F8300D08E0200002E +:108FD0000A0010EA3C0500108F8200C08FA7001C19 +:108FE000921800D0920B00D0920E00D0331100FFE7 +:108FF000316900FF00117940000928C001E56021B6 +:1090000031C300FF036C50210003314000C2C8216E +:10901000255F0088AF9F00ACAF9900BCA1470088D6 +:109020009768003C03C020218F9100AC0E000CD645 +:109030003110FFFF00026B80020DC0253C0442008E +:109040008F8D00B803045825AE2B00048DA900387D +:109050008F8B00AC0000882100118100AD690018E1 +:109060008DAF00343C087FFF3504FFFFAD6F001C5F +:1090700091AC003E8D65001C8D660018000C190037 +:10908000000C770200A33821020E102500E3F82B14 +:1090900000C2C821033F5021AD67001CAD6A001813 +:1090A000AD60000CAD60001091B8003E24050005D5 +:1090B00003C45024A578001495A9000403C02021FE +:1090C000A569001691AF003EA56F002095B1000480 +:1090D000A5710022AD60002491AE003FA56E000294 +:1090E00091B0003E91AC003D01901023244300015B +:1090F000A16300018F8600AC8F9F00BCACDE00082E +:10910000A3E500008F9000BC8F9900B82405FFBF35 +:1091100096070002973800120247782433093FFF70 +:1091200001E98825A6110002921200022418FFDF2F +:10913000324E003F35CD0040A20D00028F8600BCAC +:109140008F8C00D02412FFFFACC000048D8B007CFC +:109150003C0C8000ACCB000890C2000D3043007F77 +:10916000A0C3000D8F8700BC90FF000D03E5C8244D +:10917000A0F9000D8F9100BC9229000D01387824D0 +:10918000A22F000D8F9000BCAE120010AE1500147F +:10919000920E00182415FF8002AE6825A20D00185B +:1091A0008F8500BC8F8300B88CAB0018016C102435 +:1091B000004A3025ACA600189068003EA0A8001C0C +:1091C0008F9F00B88F8700BC8F9800D097F900045C +:1091D000A4F9001E0E0002138F0500848F8600D0B4 +:1091E000000279400002490090D200BC01E98821C8 +:1091F000004028213255000212A0000303D1202193 +:109200000002A8800095202190CD00BC31B200045E +:109210001240000333DF0003000540800088202156 +:10922000240600048F9E00BC00DFC8233327000300 +:1092300000875021AFCA00040E000CF6A665003866 +:109240000A0010388F9000D0961E00123C080800CB +:109250008D080024011E9021A61200120A00105948 +:109260008FB3001027BDFFE03C1808008F18005096 +:10927000AFB00010AFBF0018AFB10014AF8400B0A2 +:1092800093710074030478212410FF8031EE007F75 +:109290003225007F01F0582401DA68213C0C000AD5 +:1092A000A38500C401AC2821AF4B002494A9001071 +:1092B0009768000690A600620080382124020030E2 +:1092C0000109202330C300F0AF8500D010620019DF +:1092D0003090FFFF90AE0062240DFFF0240A005092 +:1092E00001AE6024318B00FF116A002F00000000E6 +:1092F00016000007241F0C00AF5F00248FB100147C +:109300008FBF00188FB0001003E0000827BD0020B9 +:109310000E000E1C02002021241F0C00AF5F002451 +:109320008FB100148FBF00188FB0001003E0000849 +:1093300027BD002094A200E094A400E290BF011396 +:10934000008218263079FFFF33E700C014E00009DF +:109350002F31000116000038000000005620FFE603 +:10936000241F0C000E000D18000000000A0011ED73 +:10937000241F0C001620FFDE000000000E000D1858 +:10938000000000001440FFDC241F0C001600002227 +:109390008F8300D0906901133122003FA062011336 +:1093A0000A0011ED241F0C0094AF00D48F8600D466 +:1093B00000E02821240400050E000C5C31F0FFFFC2 +:1093C0001440000524030003979100E600001821D3 +:1093D0002625FFFFA78500E68F5801B80700FFFE8E +:1093E0003C196013AF400180241F0C00AF50018472 +:1093F000007938253C101000AF4701888FB1001468 +:10940000AF5001B8AF5F00248FB000108FBF0018BD +:1094100003E0000827BD00200E000E1C02002021E2 +:109420005040FFB5241F0C008F8300D090690113BA +:109430000A0012163122003F0E000E1C02002021ED +:109440001440FFAD241F0C00122000078F8300D0B2 +:10945000906801133106003F34C20040A06201133E +:109460000A0011ED241F0C000E000D180000000072 +:109470005040FFA1241F0C008F8300D0906801137F +:109480003106003F0A00124634C20040AF9B00C8BC +:1094900003E00008AF8000EC3089FFFF0009404284 +:1094A0002D020041000929801440000200095040AB +:1094B00024080040000879400008C0C001F8582185 +:1094C000256701A800EF702125CC007F240DFF80C7 +:1094D000018D18240065302100CA282125640088E8 +:1094E000240A00883C010800AC2A004C3C0108001A +:1094F000AC240050AF8500D43C010800AC290060CA +:109500003C010800AC2800643C010800AC27005472 +:109510003C010800AC2300583C010800AC26005C6C +:1095200003E0000800000000308300FF30C6FFFFAA +:1095300030E400FF8F4201B80440FFFE00034C00FE +:10954000012438253C08600000E820253C03100079 +:10955000AF450180AF460184AF44018803E00008B5 +:10956000AF4301B88F86001C3C09601235270010FC +:109570008CCB00043C0C600E35850010316A00066F +:109580002D480001ACE800C48CC40004ACA43180B8 +:109590008CC2000894C30002ACA2318403E000082E +:1095A000A78300E43C0308008C6300508F8400E82C +:1095B0008F86001C2402FF800064C0210302C8249F +:1095C000AF5900288CCD00043305007F00BA782104 +:1095D0003C0E000C01EE2821ACAD00588CC80008F0 +:1095E000AF8500D03C076012ACA8005C8CCC0010AA +:1095F00034E80010ACAC000C8CCB000CACAB000819 +:1096000094AA00143C0208008C4200442549000141 +:10961000A4A9001494A400143083FFFF1062001763 +:109620008F8400D03C0A08008D4A0040A4AA001292 +:109630008CCE0018AC8E00248CCD0014AC8D002094 +:109640008CC70018AC87002C8CCC001424060001B9 +:10965000AC8C00288D0B00BC5166001A8D0200B442 +:109660008D0200B8A482003A948F003AA48F003C87 +:10967000948800D403E000083102FFFF3C09080091 +:109680008D290024A4A000148F8400D0A4A9001266 +:109690008CCE0018AC8E00248CCD0014AC8D002034 +:1096A0008CC70018AC87002C8CCC00142406000159 +:1096B000AC8C00288D0B00BC5566FFEA8D0200B80B +:1096C0008D0200B4A482003A948F003AA48F003C2B +:1096D000948800D403E000083102FFFF8F86001C4D +:1096E0003C0C08008D8C0050240BFF808CCD0008B2 +:1096F0003C03000C000D51C0018A4021010B48249D +:10970000AF8A00E8AF49002890C700073105007F05 +:1097100000BA10210043282130E4000410800039F1 +:10972000AF8500D090CF000731EE000811C000389F +:10973000000000008CD9000C8CC400140324C02B42 +:1097400013000030000000008CC2000CACA20064CA +:109750008CCD00182402FFF8ACAD00688CCC001052 +:10976000ACAC00808CCB000CACAB00848CCA001C71 +:10977000ACAA007C90A900BC01224024A0A800BC97 +:1097800090C300073067000810E000048F8500D008 +:1097900090AF00BC35EE0001A0AE00BC90D9000730 +:1097A00033380001130000088F8300D08F8700D06A +:1097B0002404003490E800BC35030002A0E300BCA0 +:1097C0008F8300D0AC6400C090C90007312600022E +:1097D00010C0000500000000906A00BC3542000483 +:1097E000A06200BC8F8300D09065011330AD003FB4 +:1097F000A06D01138F8C00D0958B00D403E000087E +:109800003162FFFF8CC200140A0013020000000046 +:109810000A001303ACA0006427BDFFD8AFB000104E +:109820008F90001CAFBF0024AFB40020AFB200186F +:10983000AFB10014AFB3001C9613000E3C07600AD2 +:109840003C1460063264FFFF369300100E00125580 +:1098500034F404108F8400D43C11600E0E00099B78 +:1098600036310010920E00153C0708008CE70060AE +:109870003C12601231CD000FA38D00F08E0E00045B +:109880008E0D000896080012961F00109619001AF7 +:109890009618001E960F001C310CFFFF33EBFFFFE4 +:1098A000332AFFFF3309FFFF31E6FFFF3C010800C9 +:1098B000AC2B00403C010800AC2C00243C0108000B +:1098C000AC2A0044AE293178AE26317C92020015D4 +:1098D0009603001636520010304400FF3065FFFF3B +:1098E0003C0608008CC60064AE243188AE4500B446 +:1098F0009208001496190018241F0001011FC004CB +:10990000332FFFFF3C0508008CA50058AE5800B867 +:10991000AE4F00BC920C0014AF8E00D8AF8D00DCAF +:10992000318B00FFAE4B00C0920A0015AE670048B5 +:10993000AE66004C314900FFAE4900C8AE65007C00 +:109940003C0308008C6300503C0408008C84004CED +:109950003C0808008D0800543C0208008C42005C62 +:109960008FBF0024AE6300808FB00010AE83007400 +:109970008FB3001CAE22319CAE4200DCAE2731A07A +:10998000AE2631A4AE24318CAE233190AE28319472 +:10999000AE253198AE870050AE860054AE8500707B +:1099A0008FB10014AE4700E0AE4600E4AE4400CCF8 +:1099B000AE4300D0AE4800D4AE4500D88FB40020EE +:1099C0008FB2001803E0000827BD002827BDFFE084 +:1099D000AFB10014AFBF0018241100010E000845FC +:1099E000AFB0001010510005978400E6978300CCBB +:1099F0000083102B144000088F8500D42407000238 +:109A00008FBF00188FB100148FB0001000E010213C +:109A100003E0000827BD00200E000C7A2404000596 +:109A2000AF8200E81040FFF6240700020E0008494C +:109A30008F90001C979F00E68F9900E88F8D00C8DB +:109A400027EF0001240E0050AF590020A78F00E639 +:109A5000A1AE00003C0C08008D8C00648F8600C80D +:109A6000240A8000000C5E00ACCB0074A4C0000689 +:109A700094C9000A241FFF803C0D000C012AC02459 +:109A8000A4D8000A90C8000A24182000011F182535 +:109A9000A0C3000A8F8700C8A0E000788F8500C8A7 +:109AA00000003821A0A000833C0208008C42005036 +:109AB0008F8400E80044782101FFC824AF590028B2 +:109AC000960B000231EE007F01DA6021018D30211A +:109AD000A4CB00D4960A0002AF8600D03C0E00044E +:109AE00025492401A4C900E68E080004ACC800047E +:109AF0008E030008ACC30000A4C00010A4C0001472 +:109B0000A0C000D08F8500D02403FFBFA0A000D14B +:109B10003C0408008C8400648F8200D0A04400D2F2 +:109B20008E1F000C8F8A00D0978F00E4AD5F001C61 +:109B30008E19001024100030AD590018A5400030D7 +:109B4000A5510054A5510056A54F0016AD4E006812 +:109B5000AD580080AD580084914D006231AC000FCB +:109B6000358B0010A14B00628F8600D090C9006336 +:109B70003128007FA0C800638F8400D02406FFFF37 +:109B80009085006300A31024A08200638F9100D011 +:109B900000E01021923F00BC37F90001A23900BC5F +:109BA0008F8A00D0938F00F0AD580064AD5000C094 +:109BB000914E00D3000F690031CC000F018D582564 +:109BC000A14B00D38F8500D08F8900DCACA900E8C1 +:109BD0008F8800D88FBF00188FB100148FB000108D +:109BE00027BD0020ACA800ECA4A600D6A4A000E0ED +:109BF000A4A000E203E000080000000027BDFFE091 +:109C0000AFB000108F90001CAFB10014AFBF0018B0 +:109C10008E1900043C1808008F180050240FFF8094 +:109C2000001989C00238702131CD007F01CF602436 +:109C300001BA50213C0B000CAF4C0028014B4021D5 +:109C4000950900D4950400D68E0700043131FFFF3A +:109C5000AF8800D00E000913000721C08E06000453 +:109C60008F8300C8000629C0AF4500209064003EE5 +:109C700030820040144000068F8400D0341FFFFF64 +:109C8000948300D63062FFFF145F000400000000E0 +:109C9000948400D60E0008A83084FFFF8E050004CF +:109CA000022030218FBF00188FB100148FB0001038 +:109CB0002404002200003821000529C00A0012797E +:109CC00027BD002027BDFFE0AFB100143091FFFF9A +:109CD000AFB00010AFBF00181220001D000080219F +:109CE0008F86001C8CC500002403000600053F027F +:109CF0000005140230E4000714830015304500FF0E +:109D00002CA800061100004D000558803C0C0800EE +:109D1000258C57C8016C50218D4900000120000896 +:109D2000000000008F8E00EC240D000111CD0059C1 +:109D300000000000260B00013170FFFF24CA002044 +:109D40000211202B014030211480FFE6AF8A001C55 +:109D5000020010218FBF00188FB100148FB00010C7 +:109D600003E0000827BD0020938700CE14E00038F0 +:109D7000240400140E001335000000008F86001C20 +:109D8000240200010A00147CAF8200EC8F8900ECF1 +:109D9000240800021128003B24040013000028219D +:109DA00000003021240700010E001279000000009D +:109DB0000A00147C8F86001C8F8700EC24050002AB +:109DC00014E5FFF6240400120E0012E60000000065 +:109DD0008F8500E800403021240400120E00127923 +:109DE000000038210A00147C8F86001C8F8300EC51 +:109DF000241F0003147FFFD0260B00010E001298D1 +:109E0000000000008F8500E800403021240200029D +:109E10002404001000003821AF8200EC0E001279FB +:109E2000000000000A00147C8F86001C8F8F00EC5D +:109E30002406000211E6000B0000000024040010BC +:109E400000002821000030210A0014992407000195 +:109E5000000028210E001279000030210A00147C35 +:109E60008F86001C0E0013A2000000001440001298 +:109E70008F99001C8F86001C240200030A00147CAA +:109E8000AF8200EC0E00142E000000000A00147CCB +:109E90008F86001C0E0012880000000024020002C1 +:109EA0002404001400002821000030210000382183 +:109EB0000A0014B6AF8200EC0040382124040010E0 +:109EC00097380002000028210E0012793306FFFFA8 +:109ED0000A00147C8F86001C8F8400C83C077FFF1B +:109EE00034E6FFFF8C8500742402000100A61824CC +:109EF000AC83007403E00008A082000510A00036C7 +:109F00002CA20080274A04003C0B00052409008095 +:109F1000104000072408008030A6000F00C5402133 +:109F20002D0300811460000200A048212408008055 +:109F3000AF4B0030000000000000000000000000F7 +:109F40001100000900003821014030218C8D0000F3 +:109F500024E7000400E8602BACCD0000248400045A +:109F60001580FFFA24C60004000000000000000075 +:109F7000000000003C0E0006010E3825AF470030FF +:109F80000000000000000000000000008F4F0000F3 +:109F900031E800101100FFFD000000008F42003C7E +:109FA0008F43003C0049C8210323C02B1300000449 +:109FB000000000008F4C003825860001AF460038B5 +:109FC0008F47003C00A9282300E96821AF4D003CE1 +:109FD00014A0FFCE2CA2008003E0000800000000C7 +:109FE00027BDFFD03C020002AFB100143C11000CB1 +:109FF000AF450038AFB3001CAF46003C008098214D +:10A00000AF42003024050088AF44002803512021CE +:10A01000AFBF0028AFB50024AFB40020AFB2001826 +:10A020000E0014EEAFB000103C1F08008FFF004C74 +:10A030003C1808008F1800642410FF8003F3A82147 +:10A0400032B9007F02B078240018A0C0033A702112 +:10A050000018914001D12021AF4F00280E0014EECE +:10A06000025428213C0D08008DAD0050240501202C +:10A0700001B35821316C007F01705024019A4821AE +:10A08000013120210E0014EEAF4A00283C080800E0 +:10A090008D0800543C0508008CA50064011338218C +:10A0A00030E6007F00F0182400DA20210091202102 +:10A0B000AF4300280E0014EE000529403C020800C2 +:10A0C0008C4200583C1008008E1000601200001CEA +:10A0D000005388212415FF800A0015713C14000CE0 +:10A0E0003226007F0235182400DA20210240282180 +:10A0F000AF430028009420210E0014EE2610FFC06C +:10A100001200000F023288212E05004110A0FFF43A +:10A11000241210003226007F00109180023518248E +:10A1200000DA202102402821AF430028009420219A +:10A130000E0014EE000080211600FFF30232882189 +:10A140003C0B08008D6B005C240AFF802405000294 +:10A1500001734021010A4824AF4900283C0408004B +:10A16000948400623110007F021A88213C07000CA1 +:10A170000E000CAA0227982100402821026020210D +:10A180008FBF00288FB500248FB400208FB3001C30 +:10A190008FB200188FB100148FB000100A0014EEB7 +:10A1A00027BD00308F83001C8C6200041040000328 +:10A1B0000000000003E00008000000008C640010B4 +:0CA1C0008C6500080A0015278C66000C56 +:04A1CC00000000008F +:10A1D0000000001B0000000F0000000A0000000843 +:10A1E000000000060000000500000005000000045B +:10A1F0000000000400000003000000030000000352 +:10A200000000000300000003000000020000000244 +:10A210000000000200000002000000020000000236 +:10A220000000000200000002000000020000000226 +:10A230000000000200000002000000020000000216 +:10A240000000000200000001000000010000000109 +:10A2500008000F2408000D6C08000FB808001060FB +:10A2600008000F4C08000F8C0800119408000D889E +:10A27000080011B808000DD8080015540800151C76 +:10A2800008000D8808000D8808000D88080012409D +:10A290000800124008000D8808000D88080014E02E +:10A2A00008000D8808000D8808000D8808000D883A +:10A2B000080013B408000D8808000D8808000D88F8 +:10A2C00008000D8808000D8808000D8808000D881A +:10A2D00008000D8808000D8808000D8808000D880A +:10A2E00008000D8808000D8808000D8808000FACD4 +:10A2F00008000D8808000D880800167808000D88F1 +:10A3000008000D8808000D8808000D8808000D88D9 +:10A3100008000D8808000D8808000D8808000D88C9 +:10A3200008000D8808000D8808000D8808000D88B9 +:10A3300008000D8808000D8808000D8808000D88A9 +:10A340000800141008000D8808000D880800133458 +:10A35000080012A408001E2C08001EFC08001F1490 +:10A3600008001F2808001F3808001E2C08001E2C9B +:10A3700008001E2C08001ED808002E1408002E1CF1 +:10A3800008002DE408002DF008002DFC08002E0820 +:10A39000080052E8080052A8080052740800524809 +:08A3A00008005224080051E0FE +:08A3A8000A000C840000000013 +:10A3B000000000000000000D727870362E302E3143 +:10A3C0003500000006000F0300000000000000013F +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000080000000001B +:10D59000000000000000000000000000000000008B +:10D5A0000000000000000000000000000000000A71 +:10D5B0000000000000000000000000001000000358 +:10D5C000000000000000000D0000000D3C020800FB +:10D5D000244273203C030800246377ACAC40000075 +:10D5E0000043202B1480FFFD244200043C1D080052 +:10D5F00037BD7FFC03A0F0213C100800261032103C +:10D600003C1C0800279C73200E0010FE0000000048 +:10D610000000000D30A5FFFF30C600FF274301804A +:10D620008F4201B80440FFFE24020002AC640000F7 +:10D63000A4650008A066000AA062000B3C0210006E +:10D64000AC67001803E00008AF4201B83C0360007B +:10D650008C624FF80440FFFE3C020200AC644FC0F5 +:10D66000AC624FC43C02100003E00008AC624FF80B +:10D670009482000C2486001400A0382100021302BA +:10D68000000210800082402100C8102B104000577B +:10D690000000000090C300002C62000950400051BF +:10D6A00090C20001000310803C030800246372D084 +:10D6B000004310218C4200000040000800000000E0 +:10D6C00090C300012402000A1462003A0000000026 +:10D6D000010610232C42000A1440003624C6000222 +:10D6E0008CE2000034420100ACE2000090C2000075 +:10D6F00090C3000190C4000290C5000300031C0009 +:10D7000000021600004310250004220000441025EA +:10D710000045102524C60004ACE2000490C20000BD +:10D7200090C3000190C4000290C5000300021600DF +:10D7300000031C00004310250004220000441025B3 +:10D740000045102524C600040A000CB8ACE200080D +:10D7500090C30001240200041462001624C60002D3 +:10D7600090C2000090C400018CE30000000212008F +:10D77000004410253463000424C60002ACE2000C0F +:10D780000A000CB8ACE3000090C3000124020003BF +:10D790001462000824C600028CE2000090C300005E +:10D7A00024C6000134420008A0E300100A000CB8AF +:10D7B000ACE2000003E000082402000190C3000175 +:10D7C000240200021062000224C400020100202191 +:10D7D0000A000CB8008030210A000CB824C60001F1 +:10D7E00090C200010A000CB800C2302103E000081A +:10D7F0000000102127BDFFE8AFBF0014AFB000103C +:10D800000E00130200808021936200052403FFFEB6 +:10D8100002002021004310248FBF00148FB000109D +:10D82000A36200050A00130B27BD001827BDFFE8FF +:10D83000AFB00010AFBF00140E000F3C008080217D +:10D840009362000024030050304200FF14430004A0 +:10D8500024020100AF4201800A000D3002002021A5 +:10D86000AF400180020020218FBF00148FB0001054 +:10D870000A000FE727BD001827BDFF80AFBE007864 +:10D88000AFB70074AFB20060AFBF007CAFB600703E +:10D89000AFB5006CAFB40068AFB30064AFB1005C6B +:10D8A000AFB000588F5001283C0208008C4231A0D4 +:10D8B0002403FF809365003F0202102100431024DF +:10D8C000AF4200243C0208008C4231A09364000562 +:10D8D00030B200FF020210213042007F03421821C3 +:10D8E000000420273C02000A006218213084000155 +:10D8F000AF8300140000F0210000B8211480005311 +:10D90000AFA0005093430116934401128F450104C8 +:10D91000306300FF3C020001308400FF00A2282495 +:10D92000034310210344182124564000246740007B +:10D9300014A001CD2402000193620000304300FFD7 +:10D94000240200201062000524020050106200062C +:10D95000000000000A000D74000000000000000D2F +:10D960000A000D7DAFA000303C1E080027DE736C5E +:10D970000A000D7DAFA000303C0208008C4200DCA4 +:10D98000244200013C010800AC2200DC0E00139F81 +:10D99000000000000A000F318FBF007C8F4201049D +:10D9A0003C03002092D3000D004310240002202BE2 +:10D9B00000042140AFA400308F4301043C0200402A +:10D9C0000062182414600002348500400080282181 +:10D9D00032620020AFA500301440000234A600805F +:10D9E00000A0302110C0000BAFA6003093C5000886 +:10D9F0008F67004C0200202100052B0034A5008118 +:10DA000030A5F0810E000C9B30C600FF0A000F2EDF +:10DA1000000000009362003E304200401040000FC2 +:10DA200024020004564200072402001202002021B2 +:10DA300000E028210E0013F702C030210A000F3148 +:10DA40008FBF007C16420005000000000E000D2173 +:10DA5000000020210A000F318FBF007C9743011A7C +:10DA600096C4000E93620035326500043075FFFFE6 +:10DA700000442004AFA400548ED1000410A000156F +:10DA80008ED400089362003E3042004010400007F0 +:10DA9000000000000E0013E0022020211040000DC5 +:10DAA000000000000A000F2E000000008F620044FA +:10DAB000022210230440016A000000008F62004827 +:10DAC0000222102304410166240400160A000E21DC +:10DAD0008FC200048F620048022210230440000815 +:10DAE000000000003C0208008C423100244200018A +:10DAF0003C010800AC2231000A000F2300000000A6 +:10DB00008F62004002221023184000128F840014FC +:10DB10003C0208008C423100327300FC0000A82156 +:10DB2000244200013C010800AC2231008F63004018 +:10DB30009482011C022318233042FFFF0043102A65 +:10DB4000504000102402000C8F6200400A000DF2C9 +:10DB5000022210239483011C9762003C0043102B87 +:10DB600010400006000000009482011C00551023A4 +:10DB7000A482011C0A000DF72402000CA480011CE1 +:10DB80002402000CAFA200308F620040005120231D +:10DB90001880000D02A4102A144001260000000085 +:10DBA0001495000602A410233A62000130420001DD +:10DBB000144001200000000002A410230224882148 +:10DBC0000A000E093055FFFF0000202132620002DA +:10DBD0001040001A326200109362003E3042004052 +:10DBE000504000118FC200040E00130202002021D9 +:10DBF00024020018A362003F936200052403FFFE85 +:10DC000002002021004310240E00130BA362000524 +:10DC100024040039000028210E0013C9240600182E +:10DC20000A000F3024020001240400170040F80904 +:10DC3000000000000A000F3024020001104001081B +:10DC4000000000008F63004C8F620054028210239A +:10DC50001C40010302831023044200010060A02144 +:10DC6000AFA40018AFB10010AFB50014934201206B +:10DC70008F6500409763003C304200FF0342102153 +:10DC8000004410218FA400543063FFFF2442400061 +:10DC90000083182B8FA40030AFA20020AFA500286E +:10DCA00000832025AFA40030AFA50024AFA0002C36 +:10DCB000AFB400349362003E30420008504000117F +:10DCC0008FC2000002C0202127A500380E000CB230 +:10DCD000AFA000385440000B8FC200008FA2003864 +:10DCE00030420100504000078FC200008FA3003C6B +:10DCF0008F6200600062102304430001AF63006084 +:10DD00008FC200000040F80927A400108FA2003045 +:10DD10003042000254400001327300FE9362003E24 +:10DD200030420040104000378FA200248F62005420 +:10DD30001682001A326200012402001412420010FE +:10DD40002A42001510400006240200162402000C8E +:10DD500012420007326200010A000E7D000000003E +:10DD600012420005326200010A000E7D0000000030 +:10DD70000A000E782417000E0A000E7824170010EF +:10DD80000A000E7C24170012936200232403FFBDB7 +:10DD900000431024A36200233262000110400019E6 +:10DDA0008FA200242402000C1242000E2A42000D11 +:10DDB000104000062402000E2402000A124200074E +:10DDC0008FA200240A000E9524420001124200088E +:10DDD0008FA200240A000E95244200010A000E932F +:10DDE000241700082402000E16E200022417001671 +:10DDF000241700108FA2002424420001AFA20024A7 +:10DE00008FA200248FA300148F76004000431021BE +:10DE1000AF6200408F8200149442011C1040000940 +:10DE2000000000008F6200488F6400409763003C50 +:10DE3000004410233063FFFF0043102A1040000805 +:10DE40008FA20054936400368F6300403402FFFCBD +:10DE50000082100400621821AF6300488FA20054B2 +:10DE60008FA600300282902130C200081040000EC0 +:10DE7000000000008F6200581642000430C600FF08 +:10DE80009742011A5040000134C6001093C50008A3 +:10DE90008FA700340200202100052B0034A500804C +:10DEA0000E000C9B30A5F0808F62004000561023BE +:10DEB0001840001B8FA200183C0208008C423198C9 +:10DEC000304200101040000D2402000197620068EB +:10DED0001440000A240200018F8200149442011CA5 +:10DEE0001440000624020001A76200689742007AED +:10DEF000244200640A000EE9A7620012A762001221 +:10DF00000E001302020020219362007D2403000111 +:10DF100002002021344200010A000EE7AFA30050A6 +:10DF20001840000A000000000E0013020200202129 +:10DF30009362007D2403000102002021AFA3005062 +:10DF4000344200040E00130BA362007D9362003E76 +:10DF5000304200401440000C326200011040000AC0 +:10DF6000000000008F6300408FC2000424040018EA +:10DF7000246300010040F809AF6300408FA2003025 +:10DF80000A000F30304200048F6200581052001017 +:10DF9000000000008F620018022210231C400008BD +:10DFA000240400018F6200181622000900000000FE +:10DFB0008F62001C02821023044000050000000054 +:10DFC000AF720058AFA40050AF710018AF74001CBE +:10DFD00012E0000B8FA200500E001302020020215D +:10DFE000A377003F0E00130B0200202102E0302136 +:10DFF000240400370E0013C9000028218FA200500E +:10E0000010400003000000000E000CA902002021B7 +:10E0100012A00005000018218FA200303042000439 +:10E020005040001100601021240300010A000F304D +:10E03000006010210E001302020020219362007D77 +:10E0400002002021344200040E00130BA362007D65 +:10E050000E000CA9020020210A000F30240200014A +:10E06000AF400044240200018FBF007C8FBE0078C7 +:10E070008FB700748FB600708FB5006C8FB40068D6 +:10E080008FB300648FB200608FB1005C8FB0005816 +:10E0900003E0000827BD00808F4201B80440FFFE66 +:10E0A00024020800AF4201B803E0000800000000AD +:10E0B0003C02000803421021944200483084FFFFD4 +:10E0C000248400123045FFFF10A0001700A4102B7D +:10E0D0001040001624020003934201202403001A7A +:10E0E000A343018B304200FF2446FFFE8F820000D5 +:10E0F00000A6182B3863000100021382004310248D +:10E10000104000058F84000434820001A74601946A +:10E1100003E00008AF8200042402FFFE0082102406 +:10E1200003E00008AF8200042402000303E00008BB +:10E13000A342018B27BDFFE0AFB10014AFB00010C8 +:10E14000AFBF001830B0FFFF30D1FFFF8F4201B8E2 +:10E150000440FFFE00000000AF440180AF440020F7 +:10E160000E000F42020020218F8300008F840004E4 +:10E17000A750019AA750018EA74301908F830008F2 +:10E1800030828000AF4301A8A75101881040000EE3 +:10E190008F82000493420116304200FC24420004A6 +:10E1A000005A10218C4240003042FFFF144000060C +:10E1B0008F8200043C02FFFF34427FFF0082102464 +:10E1C000AF8200048F8200042403BFFF00431024A9 +:10E1D000A74201A69743010C8F42010400031C00D3 +:10E1E0003042FFFF00621825AF4301AC3C02100033 +:10E1F000AF4201B88FBF00188FB100148FB000106C +:10E2000003E0000827BD00208F47007093420112F1 +:10E210008F83000027BDFFF0304200FF00022882FC +:10E2200030620100000030211040004324A40003AC +:10E230003062400010400010306220000004108066 +:10E24000005A10218C43400024A4000400041080D4 +:10E25000AFA30000005A10218C424000AFA200047E +:10E2600093420116304200FC005A10218C424000BB +:10E270000A000FC0AFA200081040002F000030219C +:10E2800000041080005A10218C43400024A4000494 +:10E2900000041080AFA30000005A10218C424000FF +:10E2A000AFA00008AFA200048FA800080000302132 +:10E2B00000002021240A00083C090800252901004B +:10E2C00003A41021148A000300042A001100000A8C +:10E2D0000000000090420000248400012C83000C08 +:10E2E00000A2102100021080004910218C42000081 +:10E2F0001460FFF300C230263C0408008C84310413 +:10E300008F4200702C8300201060000900473823E2 +:10E310003C030800246331080004108000431021EE +:10E3200024830001AC4700003C010800AC23310409 +:10E33000AF8600082406000100C0102103E0000899 +:10E3400027BD00103C0208008C42003827BDFFD0DA +:10E35000AFB50024AFB40020AFB10014AFBF0028A8 +:10E36000AFB3001CAFB20018AFB00010000088219E +:10E370003C15080026B50038144000022454FFFF65 +:10E380000000A0219742010E8F8400003042FFFF61 +:10E39000308340001060000A245200043C02002038 +:10E3A0000082102450400007308280008F820004D9 +:10E3B0002403BFFF008318240A0010103442100009 +:10E3C000308280001040000A3C02002000821024AD +:10E3D000104000078F8200043C03FFFF34637FFF7F +:10E3E0000083182434428000AF820004AF83000011 +:10E3F0000E000F980000000014400007000000000D +:10E400009743011E9742011C3063FFFF0002140076 +:10E4100000621825AF8300089742010C8F4340002B +:10E420003045FFFF3402FFFF1462000300000000CC +:10E430000A001028241100208F42400030420100C1 +:10E4400054400001241100108F840000308210001D +:10E450005040001436310001308200201440000B7F +:10E460003C021000008210245040000E36310001A2 +:10E470003C030E003C020DFF008318243442FFFFD2 +:10E480000043102B50400007363100013C020800C9 +:10E490008C42002C244200013C010800AC22002CDC +:10E4A000363100053C0608008CC6003454C00023F9 +:10E4B0008F8500008F820004304240005440001FCE +:10E4C0008F8500003C021F01008210243C031000D5 +:10E4D0005443001A8F85000030A202001440001738 +:10E4E0008F8500003250FFFF363100028F4201B8A5 +:10E4F0000440FFFE00000000AF4001800200202128 +:10E500000E000F42AF4000208F8300042402BFFFA3 +:10E51000A750019A006218248F820000A750018E34 +:10E52000A7510188A74301A6A74201903C02100011 +:10E53000AF4201B80A0010F5000010213C021000A3 +:10E5400000A210241040003A0000000010C0000F8C +:10E550000000000030A201001040000C3C0302004B +:10E560003C020F0000A2102410430008000000002D +:10E570008F8200080054102400551021904200049E +:10E58000244200040A00109F000221C00000000085 +:10E59000000516023050000F3A0300022E4203EF2E +:10E5A000384200012C6300010062182414600073DB +:10E5B000240200013C0308008C6300D02E06000CEE +:10E5C000386200012C42000100461024144000155E +:10E5D000001021C02602FFFC2C4200045440001110 +:10E5E00000002021386200022C4200010046102465 +:10E5F00010400003000512420A00109F0000202175 +:10E600000010182B0043102450400006001021C0B9 +:10E61000000020213245FFFF0E000F633226FFFB72 +:10E62000001021C03245FFFF0A0010F2362600021A +:10E630008F4240003C0308008C63002430420100FC +:10E640001040004630620001322200043070000D9C +:10E65000144000022413000424130002000512C217 +:10E66000384200012E4303EF3042000138630001BD +:10E6700000431025104000033231FFFB2402FFFB52 +:10E680000202802410C000183202000130A20100F2 +:10E6900010400015320200013C020F0000A21024BD +:10E6A0003C0302001043000F8F8200082403FFFE8A +:10E6B00002038024005410240055102190420004CD +:10E6C000023330252442000412000002000221C05F +:10E6D0003226FFFF0E000F633245FFFF12000027B6 +:10E6E00000001021320200011040000D320200042F +:10E6F0002402000112020002023330253226FFFFFD +:10E70000000020210E000F633245FFFF2402FFFEB0 +:10E7100002028024120000190000102132020004BD +:10E72000104000162402000124020004120200021C +:10E73000023330253226FFFF3245FFFF0E000F6304 +:10E74000240401002402FFFB020280241200000BBB +:10E75000000010210A0010F52402000110400007FB +:10E76000000010213245FFFF362600020000202164 +:10E770000E000F6300000000000010218FBF002872 +:10E780008FB500248FB400208FB3001C8FB2001807 +:10E790008FB100148FB0001003E0000827BD0030D7 +:10E7A00027BDFFD0AFB000103C04600CAFBF002C01 +:10E7B000AFB60028AFB50024AFB40020AFB3001C43 +:10E7C000AFB20018AFB100148C8250002403FF7F59 +:10E7D0003C1A8000004310243442380CAC825000B4 +:10E7E000240200033C106000AF4200088E020808BB +:10E7F0003C1B80083C010800AC2000203042FFF0A8 +:10E80000384200102C4200010E001B85AF82001818 +:10E810003C04FFFF3C020400348308063442000C31 +:10E82000AE021948AE03194C3C0560168E021980E1 +:10E830008CA300003442020000641824AE02198048 +:10E840003C0253531462000334A47C008CA20004E5 +:10E85000005020218C82007C8C830078AF820010D5 +:10E86000AF83000C8F55000032A200031040FFFD63 +:10E8700032A200011040013D32A200028F42012865 +:10E88000AF4200208F4201048F430100AF8200009D +:10E890000E000F3CAF8300043C0208008C4200C015 +:10E8A000104000088F8400003C0208008C4200C425 +:10E8B000244200013C010800AC2200C40A00126995 +:10E8C000000000003C020010008210241440010CE3 +:10E8D0008F8300043C0208008C4200203C030800A7 +:10E8E0008C63003800008821244200013C010800AC +:10E8F000AC2200203C16080026D600381460000226 +:10E900002474FFFF0000A0219742010E30834000D5 +:10E910003042FFFF1060000A245200043C02002035 +:10E920000082102450400007308280008F82000453 +:10E930002403BFFF008318240A0011703442100022 +:10E94000308280001040000A3C0200200082102427 +:10E95000104000078F8200043C03FFFF34637FFFF9 +:10E960000083182434428000AF820004AF8300008B +:10E970000E000F9800000000144000070000000087 +:10E980009743011E9742011C3063FFFF00021400F1 +:10E9900000621825AF8300089742010C8F434000A6 +:10E9A0003045FFFF3402FFFF146200030000000047 +:10E9B0000A001188241100208F42400030420100DB +:10E9C00054400001241100108F8400003082100098 +:10E9D0005040001436310001308200201440000BFA +:10E9E0003C021000008210245040000E363100011D +:10E9F0003C030E003C020DFF008318243442FFFF4D +:10EA00000043102B50400007363100013C02080043 +:10EA10008C42002C244200013C010800AC22002C56 +:10EA2000363100053C0608008CC6003454C0002373 +:10EA30008F8500008F820004304240005440001F48 +:10EA40008F8500003C021F01008210243C0310004F +:10EA50005443001A8F85000030A2020014400017B2 +:10EA60008F8500003250FFFF363100028F4201B81F +:10EA70000440FFFE00000000AF40018002002021A2 +:10EA80000E000F42AF4000208F8300042402BFFF1E +:10EA9000A750019A006218248F820000A750018EAF +:10EAA000A7510188A74301A6A74201903C0210008C +:10EAB000AF4201B80A001267000010213C021000AA +:10EAC00000A210241040003A0000000010C0000F07 +:10EAD0000000000030A201001040000C3C030200C6 +:10EAE0003C020F0000A210241043000800000000A8 +:10EAF0008F82000800541024005610219042000418 +:10EB0000244200040A0011FF000221C0000000009E +:10EB1000000516023050000F3A0300022E4203EFA8 +:10EB2000384200012C630001006218241460008543 +:10EB3000240200013C0308008C6300D02E06000C68 +:10EB4000386200012C4200010046102414400015D8 +:10EB5000001021C02602FFFC2C420004544000118A +:10EB600000002021386200022C42000100461024DF +:10EB700050400003000512420A0011FF000020214E +:10EB80000010182B0043102450400006001021C034 +:10EB9000000020213245FFFF0E000F633226FFFBED +:10EBA000001021C03245FFFF0A0012523626000233 +:10EBB0008F4240003C0308008C6300243042010077 +:10EBC0001040004630620001322200043070000D17 +:10EBD000144000022413000424130002000512C292 +:10EBE000384200012E4303EF304200013863000138 +:10EBF00000431025104000033231FFFB2402FFFBCD +:10EC00000202802410C000183202000130A201006C +:10EC100010400015320200013C020F0000A2102437 +:10EC20003C0302001043000F8F8200082403FFFE04 +:10EC30000203802400541024005610219042000446 +:10EC4000023330252442000412000002000221C0D9 +:10EC50003226FFFF0E000F633245FFFF120000391E +:10EC600000001021320200011040000D32020004A9 +:10EC70002402000112020002023330253226FFFF77 +:10EC8000000020210E000F633245FFFF2402FFFE2B +:10EC9000020280241200002B000010213202000426 +:10ECA0001040002824020001240200041202000285 +:10ECB000023330253226FFFF3245FFFF0E000F637F +:10ECC000240401002402FFFB020280241200001D24 +:10ECD000000010210A0012672402000150400019B0 +:10ECE000000010213245FFFF3626000200002021DF +:10ECF0000E000F63000000000A00126700001021E0 +:10ED00002402BFFF00621024104000080000000031 +:10ED1000240287FF00621024144000083C020060B7 +:10ED20000082102410400005000000000E000D3489 +:10ED3000000000000A001267000000000E0012C769 +:10ED400000000000104000063C0240008F430124F8 +:10ED50003C026020AC430014000000003C02400074 +:10ED6000AF4201380000000032A200021040FEBD98 +:10ED7000000000008F4201403C044000AF420020F0 +:10ED80008F4301483C027000006218241064004266 +:10ED9000000000000083102B144000063C026000BD +:10EDA0003C022000106200073C0240000A0012C32F +:10EDB000000000001062003C3C0240000A0012C348 +:10EDC000000000008F4501408F4601448F420148FA +:10EDD00000021402304300FF240200041462000AFF +:10EDE000274401808F4201B80440FFFE2402001C2A +:10EDF000AC850000A082000B3C021000AF4201B8BD +:10EE00000A0012C33C0240002402000914620012EE +:10EE100000061602000229C0AF4500208F4201B84B +:10EE20000440FFFE2402000124030003AF450180DB +:10EE3000A343018BA740018EA740019AA7400190F0 +:10EE4000AF4001A8A7420188A74201A6AF4001AC8C +:10EE50003C021000AF4201B88F4201B80440FFFEEF +:10EE600000000000AC8500008F420148000214023F +:10EE7000A482000824020002A082000B8F420148F5 +:10EE8000A48200103C021000AC860024AF4201B8FE +:10EE90000A0012C33C0240000E00131000000000E4 +:10EEA0000A0012C33C0240000E001BBA0000000022 +:10EEB0003C024000AF420178000000000A00112F20 +:10EEC000000000008F4201003042003E144000115B +:10EED00024020001AF4000488F420100304207C0C9 +:10EEE0001040000500000000AF40004CAF40005053 +:10EEF00003E0000824020001AF400054AF4000408E +:10EF00008F4201003042380054400001AF400044BD +:10EF10002402000103E00008000000008F4201B855 +:10EF20000440FFFE24020001AF440180AF40018491 +:10EF3000A7450188A342018A24020002A342018B53 +:10EF40009742014A14C00004A7420190AF4001A4B7 +:10EF50000A0012EF3C0210008F420144AF4201A4AC +:10EF60003C021000AF4001A803E00008AF4201B826 +:10EF70008F4201B80440FFFE24020002AF4401802A +:10EF8000AF440184A7450188A342018AA342018BB3 +:10EF90009742014AA7420190AF4001A48F42014429 +:10EFA000AF4201A83C02100003E00008AF4201B8E4 +:10EFB0003C0290003442000100822025AF44002032 +:10EFC0008F4200200440FFFE0000000003E0000824 +:10EFD000000000003C028000344200010082202535 +:10EFE00003E00008AF44002027BDFFE8AFBF0014D6 +:10EFF000AFB000108F500140934301499342014844 +:10F0000093440148306300FF304200FF00021200C9 +:10F0100000622825240200191062007630840080E6 +:10F020002862001A1040001C24020020240200085C +:10F0300010620077286200091040000E2402000BC5 +:10F0400024020001106200342862000250400005D2 +:10F050002402000650600034020020210A00139AA6 +:10F060000000000010620030020020210A00139A04 +:10F07000000000001062003B2862000C50400002BB +:10F080002402000E24020009106200560200202112 +:10F090000A00139A00000000106200562862002146 +:10F0A0001040000F240200382402001C1062005897 +:10F0B0002862001D104000062402001F2402001BCD +:10F0C0001062004C000000000A00139A00000000CB +:10F0D0001062004A020020210A00139A000000007A +:10F0E00010620045286200391040000724020080A9 +:10F0F0002462FFCB2C420002104000450200202178 +:10F100000A00139600003021106200090000000080 +:10F110000A00139A000000001480003D0200202124 +:10F120000A0013908FBF00140A00139624060001F2 +:10F130008F4201B80440FFFE24020002A342018B6B +:10F14000A74501889742014AA74201908F42014496 +:10F15000A74201923C021000AF4201B80A00139C82 +:10F160008FBF00149742014A14400029000000009C +:10F1700093620005304200041440002500000000A6 +:10F180000E001302020020219362000502002021DC +:10F19000344200040E00130BA362000593620005C5 +:10F1A0003042000414400002000000000000000D86 +:10F1B0009362000024030020304200FF1443001437 +:10F1C000000000008F4201B80440FFFE2402000549 +:10F1D000AF500180A342018B3C0210000A00139A39 +:10F1E000AF4201B88FBF00148FB000100A0012F2B6 +:10F1F00027BD00180000000D020020210000302172 +:10F200008FBF00148FB000100A0012DD27BD001858 +:10F210000000000D8FBF00148FB0001003E0000845 +:10F2200027BD001827BDFFE8AFBF00100E000F3C40 +:10F2300000000000AF4001808FBF001000002021BF +:10F240000A000FE727BD00183084FFFF30A5FFFF3D +:10F25000000018211080000700000000308200012B +:10F260001040000200042042006518210A0013AB80 +:10F270000005284003E000080060102110C00006CF +:10F2800024C6FFFF8CA2000024A50004AC8200006D +:10F290000A0013B52484000403E000080000000005 +:10F2A00010A0000824A3FFFFAC86000000000000AF +:10F2B000000000002402FFFF2463FFFF1462FFFA36 +:10F2C0002484000403E0000800000000308300FFF5 +:10F2D00030A500FF30C600FF274701808F4201B8EC +:10F2E0000440FFFE000000008F420128346340000C +:10F2F000ACE2000024020001ACE00004A4E300083A +:10F30000A0E2000A24020002A0E2000B3C0210006E +:10F31000A4E50010ACE00024ACE00028A4E6001254 +:10F3200003E00008AF4201B827BDFFE8AFBF0010FF +:10F330009362003F24030012304200FF1043000D8F +:10F34000008030218F620044008210230440000AB4 +:10F350008FBF00108F62004824040039000028216C +:10F3600000C2102304410004240600120E0013C939 +:10F37000000000008FBF00102402000103E000081D +:10F3800027BD001827BDFFC8AFB20030AFB1002CB9 +:10F39000AFBF0034AFB0002890C5000D00809021B1 +:10F3A00030A400101080000B00C088218CC300081E +:10F3B0008F6200541062000730A20005144000B5AF +:10F3C000240400010E000D21000020210A0014BBBE +:10F3D0000040202130A200051040000930A3001297 +:10F3E000108000AC240400018E2300088F620054BA +:10F3F000146200A98FBF00340A00142C24040038C2 +:10F4000024020012146200A324040001022020211F +:10F4100027A500100E000CB2AFA000101040001184 +:10F42000024020218E220008AF620084AF600040BD +:10F430000E001302000000009362007D02402021B4 +:10F44000344200200E00130BA362007D0E000CA9B5 +:10F4500002402021240400382405008D0A0014B83D +:10F46000240600129362003E304200081040000F54 +:10F470008FA2001030420100104000078FA300143B +:10F480008F6200600062102304430008AF630060D5 +:10F490000A00144100000000AF6000609362003E6B +:10F4A0002403FFF700431024A362003E9362003E52 +:10F4B00030420008144000022406000300003021FE +:10F4C00093620034936300378F640084304200FFFE +:10F4D000306300FF006618210003188000432821D4 +:10F4E00000A4202B1080000B000000009763003C5C +:10F4F0008F6200843063FFFF004510230062182BE9 +:10F5000014600004000000008F6200840A00145D93 +:10F51000004580239762003C3050FFFF8FA300100E +:10F520003062000410400004000628808FA2001CF6 +:10F530000A0014650202102B2E020218504000032C +:10F54000240202180A00146E02051023306300041E +:10F5500010600003004510238FA2001C00451023FB +:10F56000004080212C420080544000012410008083 +:10F570000E0013020240202124020001AF62000CA1 +:10F580009362003E001020403042007FA362003EA4 +:10F590008E22000424420001AF620040A770003CAC +:10F5A0008F6200509623000E00431021AF62005876 +:10F5B0008F62005000441021AF62005C8E22000474 +:10F5C000AF6200188E220008AF62001C8FA20010EC +:10F5D000304200085440000A93A20020A360003685 +:10F5E000936200362403FFDFA36200359362003E7E +:10F5F00000431024A362003E0A0014988E220008E3 +:10F60000A36200358E220008AF62004C8F62002496 +:10F610008F63004000431021AF62004893620000F6 +:10F6200024030050304200FF144300122403FF80E3 +:10F630003C0208008C4231A00242102100431024F9 +:10F64000AF4200283C0208008C4231A08E24000802 +:10F650003C03000C024210213042007F0342102183 +:10F6600000431021AC4400D88E230008AF82001460 +:10F67000AC4300DC0E00130B0240202124040038B0 +:10F68000000028212406000A0E0013C90000000013 +:10F69000240400018FBF00348FB200308FB1002CE2 +:10F6A0008FB000280080102103E0000827BD00383B +:10F6B00027BDFFF827420180AFA20000308A00FF7B +:10F6C0008F4201B80440FFFE000000008F46012871 +:10F6D0003C0208008C4231A02403FF80AF86004822 +:10F6E00000C2102100431024AF4200243C02080055 +:10F6F0008C4231A08FA900008FA8000000C2102109 +:10F700003042007F034218213C02000A00621821A7 +:10F71000946400D48FA700008FA50000240200028B +:10F72000AF830014A0A2000B8FA30000354260003D +:10F730003084FFFFA4E200083C021000AD26000068 +:10F74000AD040004AC60002427BD0008AF4201B83E +:10F7500003E00008240200018F88003C9382002807 +:10F760008F8300143C07080024E7777800481023B3 +:10F77000304200FF304900FC246500888F8600403D +:10F78000304A0003112000090000202124820004D7 +:10F790008CA30000304400FF0089102AACE3000075 +:10F7A00024A500041440FFF924E7000411400009D7 +:10F7B000000020212482000190A30000304400FFBB +:10F7C000008A102BA0E3000024A500011440FFF9DB +:10F7D00024E7000130C20003144000048F85003C80 +:10F7E000310200031040000D0000000010A00009CD +:10F7F000000020212482000190C30000304400FF5B +:10F800000085102BA0E3000024C600011440FFF97E +:10F8100024E7000103E00008000000001100FFFDE4 +:10F8200000002021248200048CC30000304400FF2B +:10F830000088102BACE3000024C600041440FFF93C +:10F8400024E7000403E00008000000008F83003C70 +:10F850009382002830C600FF30A500FF004310232C +:10F86000304300FF8F8200140080382100431021B4 +:10F8700014C00002244800880083382130E20003CD +:10F880001440000530A2000314400003306200035E +:10F890001040000D0000000010A000090000202111 +:10F8A0002482000190E30000304400FF0085102B0B +:10F8B000A103000024E700011440FFF9250800011E +:10F8C00003E000080000000010A0FFFD0000202160 +:10F8D000248200048CE30000304400FF0085102BDC +:10F8E000AD03000024E700041440FFF925080004DC +:10F8F00003E00008000000000080482130AAFFFF5C +:10F9000030C600FF30E7FFFF274801808F4201B873 +:10F910000440FFFE8F820048AD0200008F420124A8 +:10F92000AD0200048D220020A5070008A102000AF4 +:10F9300024020016A102000B934301208D2200082F +:10F940008D240004306300FF004310219783003AA8 +:10F95000004410218D250024004310233C0308009F +:10F960008C6331A08F840014A502000C246300E88E +:10F970002402FFFFA50A000EA5030010A506001231 +:10F98000AD050018AD020024948201142403FFF792 +:10F990003042FFFFAD0200288C820118AD02002C1E +:10F9A0003C021000AD000030AF4201B88D220020B3 +:10F9B0000043102403E00008AD2200208F820014D1 +:10F9C00030E7FFFF00804821904200D330A5FFFFC1 +:10F9D00030C600FF0002110030420F0000E238255F +:10F9E000274801808F4201B80440FFFE8F82004803 +:10F9F000AD0200008F420124AD0200048D220020E0 +:10FA0000A5070008A102000A24020017A102000BAA +:10FA1000934301208D2200088D240004306300FFF1 +:10FA2000004310219783003A004410218F84001472 +:10FA3000004310233C0308008C6331A0A502000C96 +:10FA4000A505000E246300E8A5030010A50600121A +:10FA5000AD0000148D220024AD0200188C82005CE1 +:10FA6000AD02001C8C820058AD0200202402FFFF72 +:10FA7000AD020024948200E63042FFFFAD02002870 +:10FA800094820060948300BE30427FFF3063FFFFAA +:10FA90000002120000431021AD02002C3C021000B5 +:10FAA000AD000030AF4201B8948200BE2403FFF7DE +:10FAB00000A21021A48200BE8D2200200043102449 +:10FAC00003E00008AD220020274301808F4201B8E7 +:10FAD0000440FFFE8F8200249442001C3042FFFF4E +:10FAE000000211C0AC62000024020019A062000BE9 +:10FAF0003C021000AC60003003E00008AF4201B8E7 +:10FB00008F87002C30C300FF8F4201B80440FFFEF6 +:10FB10008F82004834636000ACA2000093820044EE +:10FB2000A0A200058CE20010A4A20006A4A3000875 +:10FB30008C8200202403FFF7A0A2000A2402000206 +:10FB4000A0A2000B8CE20000ACA200108CE200042A +:10FB5000ACA200148CE2001CACA200248CE20020B9 +:10FB6000ACA200288CE2002CACA2002C8C820024D9 +:10FB7000ACA200183C021000AF4201B88C820020F9 +:10FB80000043102403E00008AC8200208F8600149C +:10FB900027BDFFE8AFBF0014AFB0001090C20063F4 +:10FBA000304200201040000830A500FF8CC2007CCD +:10FBB0002403FFDF24420001ACC2007C90C200633A +:10FBC00000431024A0C2006310A000238F83001400 +:10FBD00027500180020028210E0015D6240600823D +:10FBE0008F82001490420063304200405040001960 +:10FBF000A38000448F83002C8F4201B80440FFFE95 +:10FC00008F820048AE02000024026082A602000833 +:10FC100024020002A202000B8C620008AE02001057 +:10FC20008C62000CAE0200148C620014AE0200184C +:10FC30008C620018AE0200248C620024AE02002800 +:10FC40008C620028AE02002C3C021000AF4201B8CA +:10FC5000A38000448F8300148FBF00148FB0001066 +:10FC60009062006327BD00183042007FA0620063ED +:10FC70009782003A8F86003C8F850014938300287A +:10FC800000461023A782003AA4A000E490A40063D9 +:10FC90008F820040AF83003C2403FFBF0046102149 +:10FCA00000832024AF820040A0A400638F82001450 +:10FCB000A04000BD8F82001403E00008A44000BEF5 +:10FCC0008F8A001427BDFFE0AFB10014AFB0001061 +:10FCD0008F88003CAFBF00189389001C954200E458 +:10FCE00030D100FF0109182B0080802130AC00FFCB +:10FCF0003047FFFF0000582114600003310600FF69 +:10FD000001203021010958239783003A0068102B05 +:10FD10001440003C000000001468000724020001A9 +:10FD20008E0200202403FFFB34E7800000431024F0 +:10FD3000AE0200202402000134E70880158200058D +:10FD40003165FFFF0E001554020020210A001691B4 +:10FD5000020020210E001585020020218F8400481A +:10FD6000274301808F4201B80440FFFE240200189F +:10FD7000AC640000A062000B8F840014948200E643 +:10FD8000A46200103C021000AC600030AF4201B829 +:10FD90009482006024420001A4820060948200608A +:10FDA0003C0308008C63318830427FFF5443000FCE +:10FDB000020020219482006024038000004310246C +:10FDC000A48200609082006090830060304200FF57 +:10FDD000000211C200021027000211C03063007F30 +:10FDE00000621825A0830060020020210220282143 +:10FDF0008FBF00188FB100148FB000100A0015F9E2 +:10FE000027BD0020914200632403FF80004310259A +:10FE1000A14200639782003A3048FFFF11000020A2 +:10FE20009383001C8F840014004B1023304600FF86 +:10FE3000948300E42402EFFF0168282B0062182459 +:10FE4000A48300E414A000038E02002001005821C6 +:10FE5000000030212403FFFB34E78000004310241E +:10FE6000AE02002024020001158200053165FFFF6B +:10FE70000E001554020020210A0016B99783003A9B +:10FE80000E001585020020219783003A8F82003CE6 +:10FE9000A780003A00431023AF82003C9383001CEC +:10FEA0008F8200148FBF00188FB100148FB0001024 +:10FEB00027BD002003E00008A04300BD938200445A +:10FEC0002403000127BDFFE8004330042C4200203A +:10FED000AFB00010AFBF00142410FFFE10400005AB +:10FEE000274501803C0208008C4231900A0016D65A +:10FEF000004610243C0208008C4231940046102435 +:10FF000014400007240600848F8300142410FFFF90 +:10FF1000906200623042000F34420040A0620062F2 +:10FF20000E0015D600000000020010218FBF001443 +:10FF30008FB0001003E0000827BD00188F83002455 +:10FF400027BDFFE0AFB20018AFB10014AFB0001092 +:10FF5000AFBF001C9062000D00A0902130D100FFC7 +:10FF60003042007FA062000D8F8500148E43001880 +:10FF7000008080218CA2007C146200052402000E07 +:10FF800090A20063344200200A0016FFA0A2006382 +:10FF90000E0016C5A38200442403FFFF1043004750 +:10FFA0002404FFFF52200045000020218E43000062 +:10FFB0003C02001000621024504000043C02000883 +:10FFC000020020210A00170E2402001500621024EE +:10FFD000504000098E450000020020212402001438 +:10FFE0000E0016C5A38200442403FFFF1043003314 +:10FFF0002404FFFF8E4500003C02000200A21024F2 +:020000040001F9 +:10000000104000163C0200048F8600248CC20014AD +:100010008CC300108CC40014004310230044102B28 +:1000200050400005020020218E43002C8CC200109D +:1000300010620003020020210A00173F2402001270 +:100040003C02000400A210245040001C00002021AB +:10005000020020210A00173F2402001300A21024EE +:10006000104000068F8300248C6200105040001363 +:10007000000020210A001739020020218C620010A4 +:10008000504000048E42002C020020210A00173F3D +:10009000240200115040000900002021020020210C +:1000A000240200170E0016C5A38200442403FFFF9C +:1000B000104300022404FFFF000020218FBF001C1A +:1000C0008FB200188FB100148FB000100080102183 +:1000D00003E0000827BD00208F83001427BDFFD850 +:1000E000AFB40020AFB3001CAFB20018AFB1001422 +:1000F000AFB00010AFBF0024906200638F91002C5E +:100100002412FFFF3442004092250000A0620063E9 +:100110008E2200100080982130B0003F105200065F +:100120000360A0212402000D0E0016C5A382004426 +:10013000105200542404FFFF8F8300148E220018F5 +:100140008C63007C10430007026020212402000E13 +:100150000E0016C5A38200442403FFFF104300498C +:100160002404FFFF24040020120400048F830014E1 +:100170009062006334420020A06200638F850034E7 +:1001800010A0002000000000560400048F8200141C +:10019000026020210A0017902402000A9683000AB8 +:1001A000944200603042FFFF144300048F8200201D +:1001B0002404FFFD0A0017B7AF82003C3C02080090 +:1001C0008C42318C0045102B144000060260202127 +:1001D000000028210E001646240600010A0017B769 +:1001E000000020212402002D0E0016C5A382004429 +:1001F0002403FFFF104300232404FFFF0A0017B766 +:1002000000002021160400058F8400148E230014A2 +:100210002402FFFF506200180260202194820060D7 +:1002200024420001A4820060948200603C03080024 +:100230008C63318830427FFF5443000F02602021DD +:10024000948200602403800000431024A482006094 +:100250009082006090830060304200FF000211C273 +:1002600000021027000211C03063007F00621825D1 +:10027000A0830060026020210E0015F92405000112 +:10028000000020218FBF00248FB400208FB3001CFA +:100290008FB200188FB100148FB0001000801021B1 +:1002A00003E0000827BD00288F83001427BDFFE866 +:1002B000AFB00010AFBF0014906200638F87002CB6 +:1002C00000808021344200408CE60010A062006370 +:1002D0003C0308008C6331B030C23FFF0043102B59 +:1002E0001040004E8F8500302402FF8090A3000D47 +:1002F00000431024304200FF5040004902002021FA +:100300000006138230480003240200025502004414 +:100310000200202194A2001C8F85001424030023D6 +:10032000A4A201148CE60000000616023042003F31 +:10033000104300103C0300838CE300188CA2007C67 +:10034000106200062402000E0E0016C5A3820044AF +:100350002403FFFF104300382404FFFF8F830014A1 +:100360009062006334420020A06200630A0017FC20 +:100370008F83002400C31024144300078F830024BC +:1003800090A200623042000F34420020A0A200621E +:10039000A38800388F8300249062000D3042007FD4 +:1003A000A062000D8F83003410600018020020212D +:1003B0008F8400308C8200100043102B1040000905 +:1003C00024020018020020210E0016C5A38200445A +:1003D0002403FFFF104300182404FFFF0A00182421 +:1003E000000020218C820010240500010200202141 +:1003F000004310238F830024240600010E001646BC +:10040000AC6200100A001824000020210E0015F92B +:10041000240500010A0018240000202102002021E8 +:100420002402000D8FBF00148FB0001027BD0018EC +:100430000A0016C5A38200448FBF00148FB00010BD +:100440000080102103E0000827BD001827BDFFC869 +:10045000AFB20020AFBF0034AFB60030AFB5002C54 +:10046000AFB40028AFB30024AFB1001CAFB0001888 +:100470008F4601283C0308008C6331A02402FF80D2 +:10048000AF86004800C318213065007F034528214E +:10049000006218243C02000AAF43002400A2282175 +:1004A00090A2006200809021AF850014304200FFCE +:1004B00000021102A382003890A200BC3042000268 +:1004C0001440000224030034240300308F820014FF +:1004D000A3830028938300388C4200C0A38000448B +:1004E000AF82003C24020004106203148F84003C9D +:1004F0008E440004508003118F84003C8E42001013 +:100500003083FFFFA784003A106002F7AF820040FB +:100510008F8400142403FF80908200630062102403 +:10052000304200FF144002C79785003A9383003899 +:100530002402000230B6FFFF14620005000088218B +:10054000938200282403FFFD0A001B11AF82003CA8 +:100550008F82003C02C2102B144002998F8400400D +:100560000E0014EC00000000938300283C040800F7 +:1005700024847778240200341462002EAF84002C87 +:100580003C0A08008D4A77A82402FFFFAFA20010A2 +:10059000008038212405002F3C09080025297378A4 +:1005A000240800FF2406FFFF90E2000024A3FFFFC1 +:1005B0000006220200C21026304200FF0002108016 +:1005C000004910218C420000306500FF24E7000143 +:1005D00014A8FFF50082302600061027AFA20014F1 +:1005E000AFA200100000282127A7001027A60014A2 +:1005F00000C510239044000324A2000100A7182185 +:10060000304500FF2CA200041440FFF9A064000054 +:100610008FA2001011420007240200050240202191 +:100620000E0016C5A38200442403FFFF104300649C +:100630002404FFFF3C0208009042777C1040000930 +:100640008F820014024020212402000C0E0016C5E7 +:10065000A38200442403FFFF104300592404FFFF3A +:100660008F820014A380001C3C0308008C63777CFD +:100670008C4400803C0200FF3442FFFF00621824DB +:100680000083202B10800008AF830034024020211B +:10069000240200190E0016C5A38200442403FFFFA4 +:1006A000104300472404FFFF8F87003C9782003AE5 +:1006B0008F850034AF8700200047202310A0003B27 +:1006C000A784003A8F86001430A200030002102392 +:1006D00090C300BC3050000300B0282100031882F2 +:1006E000307300010013108000A228213C03080091 +:1006F0008C6331A08F8200483084FFFF0085202B5F +:100700000043102110800011244200888F84002CA7 +:100710001082000E3C033F013C0208008C427778B7 +:10072000004310243C0325001443000630E500FF7D +:100730008C820000ACC200888C8200100A0018E98C +:10074000ACC200980E001529000030219382001CD5 +:100750008F8500148F830040020238218F82003C75 +:10076000A387001C94A400E4006218218F82003447 +:1007700034841000AF83004000503021A4A400E472 +:100780001260000EAF86003C24E20004A382001C2D +:1007900094A200E424C30004AF83003C3442200050 +:1007A000A4A200E40A001906000020218F82004064 +:1007B000AF80003C00471021AF82004000002021A4 +:1007C0002414FFFF109402092403FFFF3C080800D3 +:1007D0008D0877883C0208008C4231B03C03080049 +:1007E0009063777831043FFF0082102B1040001B8C +:1007F0003067003F3C0208008C4231A88F830048DC +:100800000004218000621821006418213062007FFA +:10081000034228213C02000C00A228213C02008057 +:10082000344200013066007800C230252402FF8087 +:1008300000621024AF42002830640007AF42080471 +:100840008F8200140344202124840940AF460814F9 +:10085000AF850024AF840030AC4301189383003887 +:1008600024020003146201C72402000124020026AE +:1008700010E201C928E200271040001324020032D0 +:100880002402002210E201C428E2002310400008E4 +:10089000240200242402002010E201B024020021DE +:1008A00010E2013F024020210A001AF32402000B4B +:1008B00010E201B92402002510E2001002402021BC +:1008C0000A001AF32402000B10E201A628E200330A +:1008D000104000062402003F2402003110E2009282 +:1008E000024020210A001AF32402000B10E2019DAD +:1008F000024020210A001AF32402000B8F90002CE2 +:100900003C0308008C6331B08F8500308E040010EA +:100910000000A8218CB3001430823FFF0043102B4D +:100920008CB10020504001870240202190A3000D8F +:100930002402FF8000431024304200FF5040018118 +:100940000240202100041382304200031440017D44 +:100950000240202194A3001C8F8200148E040028E2 +:10096000A44301148CA20010026218231064000337 +:10097000024020210A00197C2402001F8F820034CB +:10098000006210210262102B104000088F830024A7 +:1009900002402021240200180E0016C5A382004444 +:1009A0001054016C2404FFFF8F8300248F840034D3 +:1009B0008C6200100224882100441023AC620010D5 +:1009C0008F820014AC7100208C4200680051102B03 +:1009D000104000098F830030024020212402001DB6 +:1009E0000E0016C5A38200442403FFFF10430159E3 +:1009F0002404FFFF8F8300308E0200248C630024C8 +:100A000010430007024020212402001C0E0016C5DE +:100A1000A38200442403FFFF1043014E2404FFFF80 +:100A20008F8400248C82002424420001AC820024A4 +:100A3000123300048F8200148C4200685622000E8C +:100A40008E0200008E0200003C0300800043102450 +:100A50001440000D2402001A024020210E0016C589 +:100A6000A38200442403FFFF1043013A2404FFFF44 +:100A70000A0019BA8E0200143C03008000431024BF +:100A8000504000038E020014AC8000208E0200143F +:100A90002411FFFF105100062402001B02402021F8 +:100AA0000E0016C5A38200441051012A2404FFFF42 +:100AB0008E0300003C02000100621024104000126E +:100AC0003C020080006210241440000802402021F3 +:100AD0002402001A0E0016C5A38200442403FFFF5F +:100AE0001043011C2404FFFF0240202102002821A2 +:100AF0000E0016E5240600012403FFFF1043011534 +:100B00002404FFFF241500018F83002402A030215C +:100B10000240202194620036240500012442000195 +:100B20000A001AD7A46200368F90002C3C030800FC +:100B30008C6331B08E13001032623FFF0043102BE4 +:100B4000104000898F8400302402FF809083000DC4 +:100B500000431024304200FF104000842402000DA6 +:100B60000013138230420003240300011443007F6A +:100B70002402000D9082000D304200085440000411 +:100B80008F820034024020210A001A082402002427 +:100B9000504000048E03000C024020210A001A0875 +:100BA000240200278C82002054620006024020218B +:100BB0008E0300088C820024506200098E0200140B +:100BC00002402021240200200E0016C5A38200440A +:100BD000105400712403FFFF0A001A3D8F84002483 +:100BE0002411FFFF145100048F86001402402021BD +:100BF0000A001A38240200258E0300188CC2007CDB +:100C0000106200032402000E0A001A38024020215C +:100C10008E0300248C82002810620003240200212D +:100C20000A001A38024020218E0500288C82002CF0 +:100C300010A200032402001F0A001A3802402021DB +:100C40008E03002C14600003240200230A001A38CB +:100C5000024020218CC200680043102B104000038A +:100C6000240200260A001A38024020218C82001437 +:100C7000006518210043102B104000088F840024C9 +:100C800002402021240200220E0016C5A382004447 +:100C9000105100412403FFFF8F8400242403FFF739 +:100CA0009082000D00431024A082000D8F86001456 +:100CB0003C0308008C6331AC8F82004894C400E090 +:100CC0008F8500240043102130847FFF00042040E2 +:100CD000004410213043007F034320213C03000ED9 +:100CE000008320212403FF8000431024AF42002C06 +:100CF000A49300008CA2002824420001ACA200288A +:100D00008CA2002C8E03002C00431021ACA2002CDE +:100D10008E02002CACA200308E020014ACA2003473 +:100D200094A2003A24420001A4A2003A94C600E032 +:100D30003C0208008C4231B024C4000130837FFFA4 +:100D40001462000F008030212402800000823024D1 +:100D500030C2FFFF000213C2304200FF0002102722 +:100D60000A001A76000233C02402000D024020213E +:100D70000E0016C5A38200440A001A7C0040182108 +:100D80008F82001402402021240500010E0015F975 +:100D9000A44600E0000018210A001B0E0060882114 +:100DA0008F90002C3C0308008C6331B08E0500103E +:100DB00030A23FFF0043102B104000612402FF804F +:100DC0008F8400309083000D00431024304200FFD8 +:100DD0005040005C024020218F8200341040000B04 +:100DE000000513828F8200149763000A944200600A +:100DF0003042FFFF14430005000513828F8200205C +:100E00002404FFFD0A001AEBAF82003C30420003CD +:100E10001440000E00000000920200021040000585 +:100E20008E03002450600015920300030A001AA7E5 +:100E3000024020218C8200245062001092030003A3 +:100E4000024020210A001AAF2402000F9082000DF8 +:100E50003042000854400009920300030240202160 +:100E6000240200100E0016C5A38200442403FFFFD5 +:100E7000104300382404FFFF920300032402000201 +:100E80005462000C920200038F8200345440000927 +:100E900092020003024020212402002C0E0016C5FD +:100EA000A38200442403FFFF1043002A2404FFFF11 +:100EB000920200030200282102402021384600103F +:100EC0002CC600012C4200010E0016E5004630251C +:100ED0002410FFFF1050001F2404FFFF8F830034F5 +:100EE00010600013024020213C0208008C42318C2B +:100EF0000043102B144000070000000000002821D0 +:100F0000240600010E001646000000000A001AEB3D +:100F1000000020212402002D0E0016C5A3820044EB +:100F20001050000C2404FFFF0A001AEB00002021DF +:100F30000E0015F9240500010A001AEB000020211B +:100F4000024020212402000D0E0016C5A382004499 +:100F5000004020210A001B0E008088211514000E7D +:100F6000000000000E00174C024020210A001B0E5A +:100F7000004088210E0016C5A38200440A001B0E03 +:100F80000040882114620017022018212402002347 +:100F900014E200052402000B0E0017C002402021BD +:100FA0000A001B0E0040882102402021A382004439 +:100FB0000E0016C52411FFFF0A001B0F0220182186 +:100FC00030A500FF0E001529240600019783003A82 +:100FD0008F82003CA780003A00431023AF82003C80 +:100FE000022018211220003E9782003A2402FFFDC1 +:100FF0005462003E8E4300208E4200048F83001412 +:1010000000561023AE420004906200633042007F1D +:10101000A06200638E4200208F840014A780003AF3 +:1010200034420002AE420020A48000E490820063BB +:101030002403FFBF00431024A08200630A001B5159 +:101040008E4300209082006300621024304200FF33 +:10105000104000239782003A90820088908300BD60 +:10106000248500883042003F2444FFE02C82002089 +:10107000A383001C10400019AF85002C240200013E +:1010800000821804306200191440000C3C028000F9 +:1010900034420002006210241440000B3062002031 +:1010A0001040000F9782003A90A6000102402021D4 +:1010B000240500010A001B4B30C60001024020211C +:1010C0000A001B4A240500010240202100002821BB +:1010D000240600010E001646000000009782003A28 +:1010E0001440FD0C8F8400148E43002030620004F5 +:1010F000104000128F84003C2402FFFB0062102489 +:10110000AE420020274301808F4201B80440FFFE19 +:101110008F820048AC6200008F420124AC62000460 +:1011200024026083A462000824020002A062000B73 +:101130003C021000AF4201B88F84003C8F83001442 +:101140008FBF00348FB600308FB5002C8FB40028CD +:101150008FB300248FB200208FB1001C8FB0001815 +:101160002402000127BD003803E00008AC6400C081 +:1011700030A500FF2403000124A900010069102B01 +:101180001040000C00004021240A000100A310239D +:10119000004A380424630001308200010069302BCA +:1011A00010400002000420420107402554C0FFF80F +:1011B00000A3102303E00008010010213C020800F6 +:1011C000244260A43C010800AC22736C3C0208007D +:1011D000244253083C010800AC227370240200062C +:1011E00027BDFFE03C010800A02273743C021EDC16 +:1011F000AFB20018AFB10014AFBF001CAFB0001009 +:1012000034526F4100008821240500080E001B7233 +:1012100002202021001180803C07080024E7737819 +:101220000002160002071821AC620000000028210D +:1012300024A200013045FFFF8C6200002CA60008AC +:1012400004410002000220400092202614C0FFF852 +:10125000AC640000020780218E0400000E001B72A7 +:1012600024050020262300013071FFFF2E230100FA +:101270001460FFE5AE0200008FBF001C8FB20018A3 +:101280008FB100148FB0001003E0000827BD0020CC +:1012900027BDFFD8AFB3001CAFB20018AFBF00200E +:1012A000AFB10014AFB000108F5101408F4801481A +:1012B00000089402324300FF311300FF8F4201B84F +:1012C0000440FFFE27500180AE1100008F42014410 +:1012D000AE02000424020002A6120008A202000BC3 +:1012E00024020014AE1300241062002528620015A9 +:1012F0001040000824020015240200101062003083 +:1013000024020012106200098FBF00200A001CADE9 +:101310008FB3001C1062007024020022106200379C +:101320008FBF00200A001CAD8FB3001C3C020800D8 +:101330008C4231A02403FF8002221021004310249C +:10134000AF4200243C0208008C4231A0022210214E +:101350003042007F034218213C02000A006218213B +:10136000166000BCAF830014906200623042000F30 +:1013700034420030A06200620A001CAC8FBF002023 +:101380003C0460008C832C083C02F0033442FFFFD5 +:1013900000621824AC832C083C0208008C4231A067 +:1013A0008C832C08244200740002108200021480F6 +:1013B00000621825AC832C080A001CAC8FBF0020EB +:1013C0003C0208008C4231A02403FF80022210213D +:1013D00000431024AF4200243C0208008C4231A09C +:1013E0003C03000A022210213042007F03421021F8 +:1013F000004310210A001CABAF8200143C0208001D +:101400008C4231A02405FF800222102100451024C7 +:10141000AF4200243C0208008C4231A0022210217D +:101420003042007F034218213C02000A006218216A +:101430009062006300A21024304200FF104000853B +:10144000AF83001424620088944300123C02080019 +:101450008C4231A830633FFF000319800222102123 +:10146000004310213043007F034320210045102416 +:101470003C03000C00832021AF4200289082000D25 +:1014800000A21024304200FF10400072AF840024FC +:101490009082000D304200101440006F8FBF00207A +:1014A0000E0015C8000000008F4201B80440FFFE86 +:1014B00000000000AE1100008F420144AE020004A3 +:1014C00024020002A6120008A202000BAE130024A0 +:1014D0000A001CAC8FBF00202406FF8002261024C7 +:1014E000AF4200203C0208008C4231A031043FFF93 +:1014F000000421800222102100461024AF42002463 +:101500003C0308008C6331A83C0208008C4231A0E7 +:101510003227007F022318210222102100641821A3 +:101520003042007F3064007F034228213C02000AE1 +:101530000066182400A22821034420213C02000C4C +:1015400000822021AF4300283C02000803471821F5 +:1015500000629021AF850014AF8400240E0015C8EE +:10156000010080218F4201B80440FFFE8F820024D9 +:101570008F840014274501809042000DACB100001B +:10158000A4B0000600021600000216030002102795 +:10159000000237C214C00016248200889442001250 +:1015A00032033FFF30423FFF1443001224026082A7 +:1015B000908300632402FF8000431024304200FF28 +:1015C0005040000C24026082908200623042000F82 +:1015D00034420040A082006224026084A4A2000879 +:1015E0002402000DA0A200050A001C963C02270060 +:1015F00024026082A4A20008A0A000053C022700EB +:1016000000061C000062182524020002A0A2000BA4 +:10161000ACA30010ACA00014ACA00024ACA0002827 +:10162000ACA0002C8E42004C8F840024ACA2001889 +:101630009083000D2402FF8000431024304200FFFD +:10164000104000058FBF00209082000D3042007FC7 +:10165000A082000D8FBF00208FB3001C8FB2001836 +:101660008FB100148FB000103C02100027BD00287D +:0816700003E00008AF4201B8DD +:08167800080034300800343092 +:10168000080033A8080033E0080034140800343898 +:0C16900008003438080034380800331813 +:04169C000A0001241B +:1016A00000000000000000000000000D74706136B2 +:1016B0002E302E313500000006000F010000000022 +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300010000003000000000000000D0000000D7C +:101740003C02080024421C003C030800246320944F +:10175000AC4000000043202B1480FFFD2442000415 +:101760003C1D080037BD2FFC03A0F0213C100800F1 +:10177000261004903C1C0800279C1C000E00015CF5 +:10178000000000000000000D3084FFFF30820007E1 +:101790008F85001810400002248300073064FFF892 +:1017A0000085302130C41FFF03441821247B4000F2 +:1017B000AF85001CAF84001803E00008AF4400842C +:1017C0003084FFFF308200078F8500208F8600283D +:1017D00010400002248300073064FFF800852021B8 +:1017E0000086182B14600002AF8500240086202399 +:1017F0000344282134068000AF840020AF440080D9 +:1018000000A6202103E00008AF84003827BDFFD8E0 +:10181000AFB3001CAFB20018AFB00010AFBF0024D0 +:10182000AFB40020AFB100143C0860088D14500024 +:101830002418FF7F3C1A8000029898243672380CD6 +:10184000AD1250008F5100083C07601C3C0860003E +:1018500036300001AF500008AF800018AF40008064 +:10186000AF4000848CE600088D0F08083C07601626 +:101870008CEC000031EEFFF039CA00103C0DFFFF88 +:10188000340B80003C030080034B48212D440001B1 +:10189000018D28243C0253533C010800AC23042052 +:1018A000AF890038AF860028AF840010275B400066 +:1018B00014A2000334E37C008CF9000403281821EF +:1018C0008C7F007C8C6500783C0280003C0B08001B +:1018D0008D6B048C3C0A08008D4A048834520070D9 +:1018E000AF85003CAF9F00403C13080026731C44AA +:1018F0000240A0218E4800008F46000038C300013E +:101900003064000110800017AF8800340280482145 +:101910008D2F00003C0508008CA5045C3C180800D5 +:101920008F18045801E8102300A280210000C8216C +:101930000202402B03198821022838213C010800AB +:10194000AC30045C3C010800AC2704588F4E00000A +:1019500039CD000131AC00011580FFED01E04021DF +:10196000AF8F00348E5100003C0708008CE7045C08 +:101970003C0D08008DAD04580228802300F0602142 +:10198000000070210190302B01AE1821006620214B +:101990003C010800AC2C045C3C010800AC24045859 +:1019A0008F4601088F47010030C92000AF86000034 +:1019B000AF87000C1120000A00C040213C1808002D +:1019C0008F18042C270800013C010800AC28042CC7 +:1019D0003C184000AF5801380A0001960000000092 +:1019E0009749010400002821014550213122FFFFC1 +:1019F000016258210162F82B015F502130D90200A9 +:101A00003C010800AC2B048C3C010800AC2A048883 +:101A10001720001524040F0010E40013000000003C +:101A200024080D0010E8023B30CD000611A0FFE9AC +:101A30003C184000936E00002409001031C400F0EF +:101A40001089027124020070108202E58F88001450 +:101A5000250F0001AF8F00143C184000AF5801382B +:101A60000A00019600000000974C01041180FFD984 +:101A70003C18400030C34000146000A1000000008A +:101A80008F46017804C0FFFE8F87003824100800BD +:101A9000240F00088CE30008AF500178A74F0140E5 +:101AA000A7400142974E01048F86000031C9FFFF15 +:101AB00030CD000111A002E1012040212531FFFEBF +:101AC00024180002A75801463228FFFFA7510148F9 +:101AD0003C1908008F39043C172002D08F8C000C71 +:101AE00030DF002017E00002240400092404000174 +:101AF00030C20C0024050400504500013484000469 +:101B0000A744014A3C1108008E3104203C180048CB +:101B10003C1000010238182530CF00020070282543 +:101B200011E00004000018213C19010000B928252B +:101B30002403000130DF000453E00005AF830008F8 +:101B40003C06001000A6282524030001AF830008EE +:101B5000AF45100000000000000000000000000081 +:101B6000000000008F8300081060002300000000C8 +:101B70008F45100004A1FFFE000000001060001E51 +:101B8000000000008F4410003C0C0020008C10244A +:101B9000104000198F8E000031CD000211A00016F8 +:101BA00000000000974F101415E000130000000023 +:101BB000975910083338FFFF2711000600111882CB +:101BC0000003308000C72821323000013223000397 +:101BD0001200032C8CA200000000000D00C7F821A9 +:101BE000AFE200003C0508008CA5043024A60001EB +:101BF0003C010800AC2604308F6D00003402FFFF6A +:101C0000AF8D00048CEC0000118202A600002021A0 +:101C10008CED000031AC01001180028A0000000050 +:101C20003C0208008C4204743C0308008C63044CA2 +:101C30003C1F08008FFF04703C1808008F180448F0 +:101C4000004838210068802100E8282B03E4302177 +:101C50000208402B0304882100C570210228782146 +:101C60003C010800AC30044C3C010800AC2F044897 +:101C70003C010800AC2704743C010800AC2E047041 +:101C80008F8400180120302131290007249F00088B +:101C900033F91FFF03594021AF84001CAF9900188E +:101CA000251B4000AF590084112000038F830020C2 +:101CB00024C200073046FFF88F84002800C3282183 +:101CC00000A4302B14C00002AF83002400A42823FA +:101CD00003456021340D8000018D10213C0F100060 +:101CE000AF850020AF820038AF450080AF4F01784C +:101CF0008F880014250F00010A0001EFAF8F001438 +:101D00008F6200088F67000024050030000776020C +:101D100031C300F0106500A7240F0040546FFF4C42 +:101D20008F8800148F4B01780560FFFE00000000D3 +:101D300030CA020015400003000612820000000DA8 +:101D400000061282304D0003000D4900012D1821BC +:101D500000038080020D40210008608001938021F3 +:101D60008E1F000017E00002000000000000000DC0 +:101D70008F6E000405C202BD92070006920E000598 +:101D8000920200043C090001000E18800070F82146 +:101D90008FED0018277100082448000501A9602173 +:101DA00000083082AFEC0018022020210E00059EB2 +:101DB00026050014920A00068F7900043C0B7FFF71 +:101DC000000A2080009178218DF800043566FFFF1D +:101DD0000326282403053821ADE70004920E0005F0 +:101DE000920D0004960C0008000E10800051C821CE +:101DF0008F230000974901043C07FFFF0067582428 +:101E00003128FFFF010DF82103EC50233144FFFF7F +:101E100001643025AF26000092030007241800015A +:101E200010780275240F0003106F02850000000077 +:101E30008E0500102419000AA7590140A745014248 +:101E4000921800048F860000240F0001A758014457 +:101E5000A74001469747010430D100023C050041EC +:101E6000A747014800001821A74F014A122000038C +:101E700030CB00043C050141240300015160000502 +:101E8000AF8300083C06001000A6282524030001AB +:101E9000AF830008AF451000000000000000000004 +:101EA00000000000000000008F8A000811400004BC +:101EB000000000008F4410000481FFFE00000000BD +:101EC0008F6B0000920800043C1108008E3104441E +:101ED000AF8B000497590104311800FF3C0E080035 +:101EE0008DCE04403325FFFF0305382102276021F2 +:101EF00000001021250F000A31E8FFFF0187482B61 +:101F000001C2682101A9F821311000073C01080035 +:101F1000AC2C04443C010800AC3F04401200000318 +:101F20008F8C00182506000730C8FFF8010C6821C7 +:101F300031BF1FFFAF8C001CAF9F0018AF5F008444 +:101F400097440104035F80213084FFFF308A00073B +:101F500011400003261B4000248900073124FFF8AC +:101F60008F8200208F850028008220210085702B21 +:101F700015C00002AF820024008520233C0B08001E +:101F80008D6B048C3C0A08008D4A04880344882128 +:101F900034038000022310213C0F1000AF84002086 +:101FA000AF820038AF440080AF4F01780A0002963C +:101FB0008F8800148F5001780600FFFE30D1020098 +:101FC00016200003000612820000000D0006128297 +:101FD000305F0003001F1900007F302100062080C1 +:101FE000009FC82100194880013380218E1800000D +:101FF00013000002000000000000000D8F6C000CB8 +:10200000058001FB8F870038240E0001AE0E000012 +:102010008CE30008A20000078F650004000554024D +:10202000314D00FF25A80005000830822CCB00416F +:1020300015600002A20A00040000000D8F78000461 +:102040003C03FFFF00E02821330BFFFF256C000B52 +:10205000000C108200022080008748218D3F000084 +:1020600026040014A618000803E3C8240E00059EE9 +:10207000AD3900008F4F01083C11100001F13824E8 +:1020800010E001AB00000000974D0104920800072A +:1020900025AAFFEC350600023144FFFFA206000727 +:1020A000960600082CC7001354E0000592030007B1 +:1020B00092110007362F0001A20F000792030007BC +:1020C00024180001107801C224090003106901D509 +:1020D0008F88003830CBFFFF257100020011788314 +:1020E00031E400FF00042880A20F000500A8482169 +:1020F0008D2D0000974A01043C0EFFFF01AEF8242D +:102100003143FFFF006B1023244CFFFE03ECC82576 +:10211000AD390000920600053C03FFF63462FFFF74 +:1021200030D800FF0018388000F08821922F00146A +:102130003C04FF7F3487FFFF31EE000F01C65821BA +:10214000316500FF00055080015068218DAC0020F2 +:102150000148F821A20B00060182C824AE0C000C35 +:10216000AFF9000C920900068E11000C03277824A9 +:102170000009C0800310702195C60026030828219D +:1021800002272024AE04000CADCF0020ADC60024F1 +:10219000ACA600108F8800003C0B08008D6B048CEF +:1021A0003C0A08008D4A0488241F001024190002EC +:1021B000A75F0140A7400142A7400144A75901463B +:1021C0009749010424070001310600022538FFFE6B +:1021D000A75801483C050009A747014A10C0000361 +:1021E000000018213C05010924030001310C000402 +:1021F00051800005AF8300083C08001000A8282586 +:1022000024030001AF830008AF4510000000000068 +:102210000000000000000000000000009205000423 +:1022200024AE000231CD0007000D182330620007F4 +:10223000AE0200108F9000081200000400000000A1 +:102240008F4F100005E1FFFE000000008F710000BD +:102250008F8E00183C0308008C630444AF91000487 +:102260009745010425CF001031E61FFF30A2FFFF84 +:10227000AF8E001CAF860018AF4600842449FFFED5 +:102280003C0C08008D8C0440974D010401208021F6 +:10229000000947C30070C02131A9FFFF0310F82BCC +:1022A0000188C821033F202103463821313100072E +:1022B0003C010800AC3804443C010800AC24044054 +:1022C0001220000324FB40002527000730E9FFF817 +:1022D0008F8600208F8400280126382100E4C02B3F +:1022E00017000002AF86002400E4382303472021B2 +:1022F00034198000009910213C0F1000AF87002096 +:10230000AF820038AF470080AF4F01780A000296D5 +:102310008F8800149747010410E0FDAE3C18400080 +:102320008F5801780700FFFE30C5400010A0000361 +:102330003C1F00080000000D3C1F0008AF5F01407B +:10234000241008008F860000AF50017897440104E4 +:1023500030D90001132000ED3086FFFF24CCFFFEB2 +:10236000240D0002A74D0146A74C01488F9100188B +:102370002408000DA748014A8F630000262F00089B +:1023800031E21FFF0342702130C90007AF83000410 +:10239000AF91001CAF82001800C03821AF4200840A +:1023A0001120000325DB400024D800073307FFF885 +:1023B0008F8500208F84002800E5302100C4382B51 +:1023C00014E00002AF85002400C430238F84001481 +:1023D0000346F821340C8000AF86002003EC8021F6 +:1023E000AF460080249900013C0610003C184000D4 +:1023F000AF460178AF900038AF990014AF5801385C +:102400000A000196000000008F630000975101044C +:102410003067FFFF3228FFFF8F4F017805E0FFFE96 +:1024200030EC0007000CF82333F0000724F9FFFE1E +:102430002404000AA7440140A7500142A7590144BF +:10244000A7400146A74801488F45010830B8002041 +:1024500017000002240300092403000130CD00020C +:10246000A743014A3C04004111A0000300001821C9 +:102470003C0401412403000130C90004512000053F +:10248000AF8300083C0600100086202524030001CD +:10249000AF830008AF4410000000000000000000FF +:1024A00000000000000000008F8E000811C0000432 +:1024B000000000008F4210000441FFFE00000000F9 +:1024C0008F7F0000276400088F91003CAF9F0004BD +:1024D000948500089490000A9499000C30AFFFFF97 +:1024E0000010C4003323FFFF11F100A603032025D1 +:1024F0003C0E08008DCE04443C0C08008D8C04403A +:1025000000E888212626FFFE01C628210000682158 +:1025100000A6F82B018D2021009F80213C0108009E +:10252000AC2504443C010800AC30044024E200081F +:102530003042FFFF3047000710E000038F83001890 +:10254000244F000731E2FFF83106FFFF30C80007D3 +:102550000043802132191FFF0359C021AF83001CA3 +:10256000AF990018271B4000AF59008411000003E9 +:102570008F8C002024C5000730A6FFF88F84002828 +:1025800000CC282100A4F82B17E00002AF8C002417 +:1025900000A42823AF850020AF4500803C0408003C +:1025A0008C84043403454821340E8000012E6821B8 +:1025B00010800005AF8D0038939100172406000E9F +:1025C000122600112407043F3C021000AF4201789C +:1025D0008F880014250F00010A0001EFAF8F00144F +:1025E0000E0005C400E020218F8800143C0B080079 +:1025F0008D6B048C3C0A08008D4A0488250F00016D +:102600000A0001EFAF8F00143C021000A7470148F9 +:10261000AF4201780A0004CE8F88001424040F0012 +:102620001184003D30CE002015C0000224030009B3 +:10263000240300010A00021AA743014A0A00020DFE +:10264000A740014694EF000894F1000A94F0000CB2 +:102650008F8C003C001174003207FFFF31EDFFFF4B +:1026600011AC003701C720253C1808008F1804441E +:102670003C0F08008DEF0440000080210308682112 +:1026800001A8382B01F0702101C760213C0108002E +:10269000AC2D04443C010800AC2C04400A00027A32 +:1026A0008F8400183C0208008C42047C3C03080024 +:1026B0008C6304543C1F08008FFF04783C1808000A +:1026C0008F180450004838210068802100E8282B2A +:1026D00003E430210208402B0304882100C5702147 +:1026E000022878213C010800AC3004543C01080069 +:1026F000AC2F04503C010800AC27047C3C010800CE +:10270000AC2E04780A00027A8F840018A740014694 +:102710000A0004358F91001830CD002015A0FFC5A8 +:102720002403000D240300050A00021AA743014AEE +:10273000974E010425C5FFF00A00038130A4FFFF76 +:102740008F9800401498FFC8000010213C05080035 +:102750008CA5046C3C1F08008FFF046800A8C821EA +:102760000328302B03E22021008640213C01080091 +:10277000AC39046C3C010800AC2804680A00027AF9 +:102780008F8400188F8C0040148CFF5900E8C821FA +:102790003C1808008F18046C3C1108008E31046846 +:1027A0002723FFFE03034821000010210123302BC3 +:1027B0000222702101C668213C010800AC29046C8A +:1027C0003C010800AC2D04680A0004A524E20008BE +:1027D0008F8800383C03FFFF8D02000C0043F82473 +:1027E00003E4C825AD19000C0A00038F30CBFFFFAE +:1027F0000A0003C3AE000000974A010492040004DB +:102800008E26000C014458212579FFF200C7C02410 +:102810003325FFFF03053825AE27000C0A0002E62A +:102820008E0500103C0DFFFF8D0A0010014D58244D +:1028300001646025AD0C00100A00038F30CBFFFF50 +:1028400097430104920E00048E290010006E10219F +:10285000244DFFEE0127602431A8FFFF0188F825F1 +:10286000AE3F00100A0002E68E0500108E0F000C2D +:10287000AE00000000078880023028210A0002B85C +:10288000ACAF00201460000D3058FFFF3C04FFFF88 +:102890000044682401A47026000E602B000D102B4C +:1028A000004CF82413E00002000000000000000DBE +:1028B0008CAF00000A00025001E410253B03FFFF2B +:1028C0000003882B0018802B0211202410800002A6 +:1028D000000000000000000D8CB900000A0002504A +:1028E0003722FFFF3084FFFF30A5FFFF1080000775 +:1028F0000000182130820001104000020004204234 +:10290000006518211480FFFB0005284003E0000843 +:102910000060102110C00007000000008CA2000021 +:1029200024C6FFFF24A50004AC82000014C0FFFBF6 +:102930002484000403E000080000000010A0000848 +:1029400024A3FFFFAC860000000000000000000090 +:102950002402FFFF2463FFFF1462FFFA24840004B3 +:1029600003E0000800000000308EFFFF30D8FFFFBA +:1029700000057C0001F8602539CDFFFF01AC502136 +:10298000014C582B014B4821000944023127FFFF1D +:1029900000E830210006240230C5FFFF00A4182102 +:1029A0003862FFFF03E000083042FFFF3C0C0800E4 +:1029B0008D8C0484240BFF8027BDFFD0018450211F +:1029C000014B4824AF4900203C0808008D080484CE +:1029D000AFB20020AFB00018AFBF0028AFB30024E3 +:1029E000AFB1001C936600040104382130E4007F7D +:1029F000009A10213C0300080043902130C50020BC +:102A0000036080213C080111277B000814A000020C +:102A1000264600702646006C92130004975101046C +:102A2000920F00043267000F322EFFFF31ED00409D +:102A300001C7282311A0000500004821925900BCBD +:102A4000333800041700009000000000924300BCDF +:102A5000307F000413E0000F0000000010A0000D04 +:102A600000000000960E0002240AFF8000A76021EB +:102A700025CDFFFEA74D1016920B0004014B20241C +:102A8000308200FF10400085010C40253C0F0400FF +:102A9000010F40258F5301780660FFFE2404000AD1 +:102AA000A7440140960D00022404000931AC000740 +:102AB000000C5823316A0007A74A0142960200021F +:102AC0002443FFFEA7430144A7400146975F01044A +:102AD000A75F01488F5901083338002053000001D7 +:102AE00024040001920F000431EE001015C0000212 +:102AF0003483001000801821A743014A0000000021 +:102B0000000000000000000000000000AF481000BE +:102B100000000000000000000000000000000000B5 +:102B20008F5110000621FFFE3113FFFF12600003DA +:102B3000000000008F481018ACC800009603000683 +:102B4000307FFFFF27F90002001998820013888068 +:102B5000023B30218CD800001520005700183402A9 +:102B6000920300042405FF8000A3F82433F100FF42 +:102B70001220002C00000000924700BC30F200023E +:102B80001240002800000000974B100C2562FFFE49 +:102B9000A7421016000000003C0A0400354900302E +:102BA000AF4910000000000000000000000000001D +:102BB000000000008F4C10000581FFFE00000000A7 +:102BC0009749100C8F51101C00C020213127FFFFA6 +:102BD00024F20030001218820003288000BBF82184 +:102BE0003226FFFFAFF100000E0005B300112C02EA +:102BF0000013C880033B98218E7800000002740007 +:102C0000AFB800108FA80010310FFFFFAFAF00105A +:102C10008FA4001001C46825AFAD00108FA600106E +:102C2000AE66000097730008976D000A9766000C67 +:102C30008F8A003C000D5C0030CCFFFF3262FFFF4A +:102C4000104A0036016C2025960600023C10100048 +:102C500024D300080E00013B3264FFFF974C0104AF +:102C60000E0001493184FFFFAF5001788FBF00286B +:102C70008FB300248FB200208FB1001C8FB00018DA +:102C800003E0000827BD003010A0FF700000000026 +:102C900024A5FFFC0A0005EC240900048CD10000E7 +:102CA000AF5110188F5301780660FF7A2404000A90 +:102CB0000A0006010000000000A7C8218F88003824 +:102CC0008F4E101C0019C0820018788001E8202166 +:102CD000AC8E0000000E2C0200C020210E0005B3B7 +:102CE00031C6FFFF023B28218CAD000000025400DA +:102CF00000403021AFAD00108FAC0010318BFFFFD2 +:102D0000AFAB00108FA2001001424825AFA9001000 +:102D10008FA700100A000631ACA700008F8F00407B +:102D2000148FFFC90000000097420104960B0002B7 +:102D30003C0508008CA5046C3049FFFF316AFFFF99 +:102D40003C1108008E310468012A382124F2FFFE6C +:102D500000B240210012FFC30112C82B023FC02164 +:102D6000031920213C010800AC28046C3C01080038 +:102D7000AC2404680A00066B0000000000A4102BBD +:102D800010400009240300010005284000A4102B76 +:102D900004A00003000318405440FFFC0005284035 +:102DA00010600007000000000085302B14C00002F6 +:102DB00000031842008520231460FFFB0005284211 +:102DC00003E00008008010218F85002C27BDFFE85C +:102DD000000530272CC300012CA40002008310251D +:102DE00010400003AFBF00102405007FAF85002C0A +:102DF0000005282730A5FFFF0E000592240426F5C4 +:102E00008F830030240402BD004030210083382B22 +:102E100010E0000924050001000420400083102B6D +:102E200004800003000528405440FFFC00042040BB +:102E300010A0000800C350210064402B15000002C0 +:102E4000000528420064182314A0FFFB0004204260 +:102E500000C350218FBF0010000A4C02312200FF36 +:102E600027BD0018AF8A002C03E00008AF890030AE +:102E70000A00002A00000000000000000000000D11 +:102E8000747870362E302E313500000006000F00A9 +:102E900000000000000001360000EA6000000000B1 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000016000000000000000000000000DC +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F00000000000000000000000013880000000026 +:102F1000000005DC000000000000000010000003BD +:102F2000000000000000000D0000000D3C02080041 +:102F300024423C203C03080024633DD4AC40000004 +:102F40000043202B1480FFFD244200043C1D080098 +:102F500037BD7FFC03A0F0213C100800261000A81C +:102F60003C1C0800279C3C200E0002BA0000000018 +:102F70000000000D8F8300383C088000350700708A +:102F80008CE50000008330253C02900000C2202523 +:102F9000AF850030AF4400208F4900200520FFFEA0 +:102FA0003C038000346200708C4500008F86003046 +:102FB0003C1908008F39007C3C0E08008DCE00784B +:102FC00000A6202303245821000078210164682BE7 +:102FD00001CF6021018D50213C010800AC2B007C09 +:102FE0003C010800AC2A007803E000080000000063 +:102FF0000A000041240400018F8400383C05800051 +:1030000034A200010082182503E00008AF4300202D +:1030100003E00008000010213084FFFF30A5FFFF0F +:1030200010800007000018213082000110400002CB +:1030300000042042006518211480FFFB0005284091 +:1030400003E000080060102110C00007000000002D +:103050008CA2000024C6FFFF24A50004AC8200005F +:1030600014C0FFFB2484000403E0000800000000FB +:1030700010A0000824A3FFFFAC86000000000000A1 +:10308000000000002402FFFF2463FFFF1462FFFA28 +:103090002484000403E0000800000000308AFFFFE1 +:1030A00093A80013A74A014497490E1630C600FFA3 +:1030B0003C021000A7490146AF450148A346015212 +:1030C000A748015AAF4701608FA400188FA30014CE +:1030D000A7440158AF43015403E00008AF42017810 +:1030E00003E00008000000003C0380003462007030 +:1030F0008C4900008F8800002484000727BDFFF85A +:103100003084FFF8AF890030974D008A31ACFFFF63 +:10311000AFAC00008FAB0000016850232547FFFFD4 +:1031200030E61FFF00C4282B14A0FFF73C0C8000E2 +:10313000358B00708D6A00003C0708008CE7008426 +:103140003C0608008CC60080000810820149182344 +:103150000002788000E370210000202101C3C82B09 +:1031600000C4C02101FA4021031948212502400072 +:1031700027BD00083C010800AC2E00843C0108007B +:10318000AC29008003E00008000000008F820000EE +:103190002486000730C5FFF800A2182130641FFF05 +:1031A00003E00008AF8400008F8700388F8A00405A +:1031B00027BDFFB88F860044AFB60040AFBF0044C4 +:1031C000AFB5003CAFB40038AFB30034AFB200309D +:1031D000AFB1002CAFB000288F4501048D4900AC81 +:1031E000AF4700808CC8002000A938230000B02120 +:1031F000AF480E108F440E1000004821AF440E144B +:103200008CC20024AF420E188F430E18AF430E1C21 +:1032100010E001252D230001936B0008116000D4FC +:1032200000000000976E001031CDFFFF00ED602B15 +:10323000158000CF0000000097700010320FFFFFD4 +:10324000AF4F0E008F520000325100081220FFFDD8 +:103250000000000097540E088F460E043285FFFFD1 +:1032600030B3000112600132000000000000000DC8 +:1032700030B8A04024150040131500C030A9A000AC +:103280001120012D00000000937F000813E00008CA +:103290000000000097630010306BFFFF00CB402B55 +:1032A0001100000330AC0040118001230000000039 +:1032B000A785003CAF8600349366000800E0282113 +:1032C000AFA7002014C0012427B30020AF60000C7A +:1032D0009782003C3047400014E0000224030016AF +:1032E0002403000E24194007A363000AAF790014D9 +:1032F000938A003E8F740014315800070018AA40CA +:1033000002959025AF7200149784003C8F700014D2 +:103310003091001002117825AF6F0014978E003C99 +:1033200031CD000811A00147000028218F6700144B +:103330003C0210003C0C810000E22825AF6500141F +:1033400097460E0A2408000E3405FFFC30C3FFFF29 +:10335000006C5825AF6B0004A3680002937F000A3D +:1033600027E90004A369000A9786003C9363000ADA +:1033700030CC1F00000C598301634021251F002819 +:10338000A37F000997490E0CA769001093790009E3 +:10339000272A0002315800070018A82332B100077D +:1033A000A371000B93740009976400108F9100348F +:1033B000978F003C329200FF024480210205702169 +:1033C00031ED004011A0000531C4FFFF0091282B12 +:1033D0003C12800010A000140000A0210224382B11 +:1033E00014E0011B8FA500208F4D0E14AF4D0E1061 +:1033F0008F420E1CAF420E18AF440E008F4F0000DC +:1034000031EE000811C0FFFD0000000097540E08C7 +:103410000080882100009021A794003C8F500E046A +:1034200024140001AF900034976400103095FFFF22 +:103430008E6800000111F82317E00009AE7F00003C +:103440008F6500148F8B004434A60040AF660014D3 +:103450008F4C0E10AD6C00208F430E18AD6300240E +:103460009367000814E000D2000000000E00009EE8 +:10347000240400108F8900483C08320000402821B5 +:10348000312600FF0006FC0003E850252539000125 +:10349000AF990048AC4A0000937800099370000A85 +:1034A000330400FF00047400320F00FF01CF6825D1 +:1034B000AC4D00048F820048064000EAACA2000830 +:1034C000ACA0000C9783003C306B00081560000234 +:1034D0002628000626280002974E0E148F450E1C43 +:1034E0008F670004936D000231C4FFFF31A200FF1B +:1034F000AFA200108F6C0014AFA800180E00008B54 +:10350000AFAC0014240400100E0000C7000000003F +:103510008E72000016400005000000008F64001449 +:103520002405FFBF00859824AF7300148F79000C29 +:1035300003353821AF67000C9375000816A000080A +:103540000000000012800006000000008F7F0014C1 +:103550003C0BEFFF3568FFFE03E84824AF69001419 +:10356000A37400088FA500200A0002460220202133 +:10357000AF470E000A0000F5000000008F590178E7 +:103580000720FFFE241F08008F840000AF5F017832 +:10359000974B008A316AFFFF014448232528FFFF2B +:1035A00031021FFF2C4300081460FFF900000000E7 +:1035B0008F8E00488F8D003800C0482103442021A1 +:1035C00025C60001240C0F00AF86004800E938230F +:1035D0002486400031CA00FF11AC00052408000118 +:1035E0009391003E3230000700107A4035E8000128 +:1035F000000AAC003C18010002B8A025AC944000C1 +:103600008F93004830B2003630A40008ACD30004D9 +:103610001080009701123025974E0E0A8F8D000002 +:103620003C02810031CCFFFF25AB00080182402520 +:103630003C03100031651FFF25390006241F000ED2 +:10364000AF48016000C33025A75F015AAF85000075 +:10365000A759015814E0000A8F93003824120F0074 +:10366000527200022416000134C600408F580E101A +:103670008F940044AE9800208F550E18AE9500240C +:103680008F450E14AF4501448F590E1CAF590148A8 +:10369000A34A01523C0A1000AF460154AF4A0178D8 +:1036A00014E0FEDD2D2300010076A0251280001716 +:1036B0008FBF00448F84003824160F0010960084BA +:1036C000000000008F45017804A0FFFE24150F00C4 +:1036D0001095006E000000008F470E142402024077 +:1036E0003C1F1000AF4701448F440E1CAF440148FB +:1036F000A3400152A740015AAF400160A7400158C2 +:10370000AF420154AF5F01788FBF00448FB60040D5 +:103710008FB5003C8FB400388FB300348FB20030C7 +:103720008FB1002C8FB0002803E0000827BD0048AF +:1037300014C0FED030B8A0408F420E148F840044D5 +:1037400000004821AC8200208F510E1CAC91002457 +:103750000A00020E2D2300018F910034978A003C4D +:103760003C1280000220A821315800401700FF3091 +:103770000000A021976900108F9200343139FFFFBB +:103780001332003500002021008048211480FEA063 +:1037900000A038218F420E148F840044AC82002098 +:1037A0008F510E1CAC9100240A00020E2D23000143 +:1037B000936A00099378000B315000FF330F00FF2C +:1037C000020F702125C2000A3050FFFF0E00009E3C +:1037D000020020218F8600483C1F410024CD0001BB +:1037E000AF8D0048936C000930C600FF000644000E +:1037F000318300FF246B0002010B4825013FC825DF +:10380000AC5900008F67000C97440E1400F2282575 +:10381000AC4500048F450E1C8F670004936A0002BC +:103820003084FFFF315800FFAFB800108F6F0014D5 +:10383000AFB100180E00008BAFAF00140A0001A654 +:1038400002002021AF6000040A00013EA3600002D4 +:103850000A00024600002021000090210A000170A9 +:10386000241400013C1280000A000195ACB2000C47 +:103870008F91000025240002A7440158263000083B +:10388000320F1FFF0A0001F9AF8F0000AF40014C5B +:103890001120002C000000008F590E10AF59014478 +:1038A0008F430E18240200403C1F1000AF43014814 +:1038B000A3400152A740015AAF400160A740015800 +:1038C000AF420154AF5F01780A0002278FBF004466 +:1038D000112000060000000097460E0830CC004082 +:1038E00015800002000000000000000D8F4D0178DF +:1038F00005A0FFFE0000000097530E103C120500CB +:10390000240E2000326AFFFF0152C025AF58014C3F +:103910008F4F0E143C021000AF4F01448F500E1C0D +:10392000AF500148A34001528F840038A740015A8C +:10393000AF400160A7400158AF4E01540A00021584 +:10394000AF4201788F490E14AF4901448F430E1CDA +:103950000A00028E240200403C0E20FF27BDFFE03B +:103960003C1A80003C0F800835CDFFFDAFBF001C26 +:10397000AFB20018AFB10014AFB00010AF8F00406D +:10398000AF4D0E000000000000000000000000002D +:1039900000000000000000003C0C00FF358BFFFD24 +:1039A000AF4B0E003C0660048CC95000240AFF7F18 +:1039B0003C116000012A40243507380CACC7500088 +:1039C0008E24043824050009AF4500083083FFFF2A +:1039D00038622F712450C0B3AF8000480E000068D9 +:1039E000AF80000052000001AE20442C0E000435D0 +:1039F0003C1180000E000ED9363000708F8A0040D6 +:103A00003C12080026523C88020088218E080000E3 +:103A10008F5F00003BF900013338000113000017ED +:103A2000AF880030022048218D2700003C0F08009D +:103A30008DEF006C3C0C08008D8C006800E8C02302 +:103A400001F828210000682100B8302B018D582191 +:103A5000016640213C010800AC25006C3C010800D7 +:103A6000AC2800688F4400003883000130620001F8 +:103A70001440FFED00E04021AF8700308E0C0000C5 +:103A80003C0508008CA5006C3C0408008C84006890 +:103A90000188302300A638210000102100E6402BC9 +:103AA000008218210068F8213C010800AC27006C56 +:103AB0003C010800AC3F00688F490100255900888F +:103AC000AF990044AF890038AF4900208E0700004D +:103AD000AF8700308F4D017805A0FFFE0000000089 +:103AE0008E0600003C0B08008D6B00743C0408003F +:103AF0008C84007000C728230165F8210000102184 +:103B000003E5402B0082382100E8C8212409080081 +:103B10003C010800AC3F00743C010800AC39007067 +:103B2000AF49017893580108A398003E938F003E57 +:103B300031EE000115C000158F830038240E0D00F2 +:103B4000106E0019240F0F00106F001D0000000000 +:103B50009159000024180050332900FF1138000447 +:103B60003C1F4000AF5F01380A0002E70000000080 +:103B70000E00090E000000008F8A00403C1F40002C +:103B8000AF5F01380A0002E700000000938D003E9D +:103B900031AC0006000C51000E0000CE0152D821BD +:103BA0000A0003438F8A00403C1B0800277B3D0826 +:103BB0000E0000CE000000000A0003438F8A004080 +:103BC0003C1B0800277B3D280E0000CE00000000B3 +:103BD0000A0003438F8A004090AA00018FAB0010B7 +:103BE0008CAC00103C0300FF8D680004AD6C00201D +:103BF0008CAD001400E060213462FFFFAD6D002445 +:103C00008CA700183C09FF000109C024AD670028FB +:103C10008CAE001C0182C82403197825AD6F000406 +:103C2000AD6E002C8CAD0008314A00FFAD6D001C5C +:103C300094A900023128FFFFAD68001090A7000092 +:103C4000A5600002A1600004A167000090A300022B +:103C5000306200FF00021982106000052405000197 +:103C60001065000E0000000003E00008A16A0001DA +:103C70008CD80028354A0080AD7800188CCF00140D +:103C8000AD6F00148CCE0030AD6E00088CC4002CDB +:103C9000A16A000103E00008AD64000C8CCD001C9B +:103CA000AD6D00188CC90014AD6900148CC80024D7 +:103CB000AD6800088CC70020AD67000C8CC20014F2 +:103CC0008C8300640043C82B132000070000000011 +:103CD0008CC20014144CFFE400000000354A008040 +:103CE00003E00008A16A00018C8200640A000399C5 +:103CF0000000000090AA000027BDFFF88FA9001C5B +:103D0000A3AA00008FAE00003C0FFF808FA8001810 +:103D100035E2FFFF8CCD002C01C26024AFAC000067 +:103D2000A120000400E06021A7A000028FB80000DD +:103D30008D2700040188182100A0582100C05021BF +:103D4000006D28263C06FF7F3C0F00FF2CAD0001D4 +:103D500035EEFFFF34D9FFFF3C02FF00031930248A +:103D6000000D1DC0010EC82400E2C02400C3702550 +:103D700003197825AD2E0000AD2F00048D450024D9 +:103D8000AFAE0000AD2500088D4D00202405FFFFDB +:103D9000AD2D000C956800023107FFFFAD27001024 +:103DA0009166001830C200FF000219C25060000185 +:103DB0008D450034AD2500148D67000827BD00082F +:103DC000AD27001C8C8B00CCAD2C0028AD20002C26 +:103DD000AD2B0024AD20001803E00008AD2000202A +:103DE00027BDFFE0AFB20018AFB10014AFB00010B4 +:103DF000AFBF001C9098000000C088213C0D00FF60 +:103E0000330F007FA0CF0000908E000135ACFFFF84 +:103E10003C0AFF00A0CE000194A6001EA2200004D0 +:103E20008CAB00148E29000400A08021016C282492 +:103E3000012A40240080902101052025A6260002A9 +:103E4000AE24000426050020262400080E0000767B +:103E500024060002924700002605002826240014AC +:103E600000071E000003160324060004044000039C +:103E70002403FFFF965900023323FFFF0E00007654 +:103E8000AE230010262400248FBF001C8FB2001820 +:103E90008FB100148FB00010240500030000302102 +:103EA0000A00008027BD002027BDFFD8AFB1001C4D +:103EB000AFB00018AFBF002090A80000240200019E +:103EC0008FB0003C3103003F008088211062001455 +:103ED0008FAA0038240B0005506B0016AFAA001003 +:103EE00000A0202100C028210E0003DC02003021A8 +:103EF000922400BC308300021060000326060030CC +:103F0000ACC0000024C600048FBF00208FB1001C8D +:103F10008FB0001800C0102103E0000827BD002862 +:103F2000014038210E00035AAFB000100A000420EF +:103F3000000000000E0003A1AFB000140A0004202E +:103F4000000000003C02000A034218213C04080063 +:103F500024843D6C2405001A000030210A000080F2 +:103F6000AF8300543C038000346200708C48000032 +:103F700000A0582100C04821308A00FFAF880030DF +:103F80008F4401780480FFFE3C0C80003586007071 +:103F90008CC500003C0308008C6300743C180800CA +:103FA0008F18007000A82023006468210000C82139 +:103FB00001A4782B0319702101CF60213C01080076 +:103FC000AC2D00743C010800AC2C00708F480E141E +:103FD000AF480144AF47014CA34A0152A74B0158D7 +:103FE0009346010830C5000854A00001352910008F +:103FF000934B090024070050316A00FF1147000766 +:10400000000000008F450E1CAF450148AF49015428 +:104010003C09100003E00008AF490178934D010806 +:1040200031A800081100001000000000934F0108A3 +:1040300031EE001051C00001352900083C04080091 +:1040400090843DD0A34401508F4309A4AF4301485D +:104050008F4209A0AF420144AF4901543C0910000E +:1040600003E00008AF4901783C1908008F393D8C06 +:10407000333800085700FFF1352900080A0004739F +:104080000000000024070040AF470814AF400810AC +:104090008F4209448F4309508F4409548F45095C6E +:1040A0008F46094CAF820064AF830050AF84004C50 +:1040B000AF85005C03E00008AF860060934601090D +:1040C00030C5007F000518C0000521400083102185 +:1040D00003E00008244200883C09080091293D9132 +:1040E00024A800023C05110000093C0000E830252E +:1040F00000C5182524820008AC83000003E00008F6 +:10410000AC8000049347010B8F4A002C974F09089D +:104110003C18000E0358482131EEFFFF000E41C04D +:10412000AF48002C97430908952C001A00804021C5 +:1041300024030001318BFFFFAC8B00008D2D001C90 +:1041400000A0582100C06021AC8D00048D24002007 +:1041500030E70040AD04000891220019304400030C +:10416000108300482885000214A000622406000283 +:104170001086005624190003109900660000000004 +:1041800010E0003A000000003C07080094E73D867C +:1041900024E20001934F0934934709219525002A11 +:1041A00031EE00FF000E488230ED00FF9787005887 +:1041B00000093600000D1C003044FFFF00C310252D +:1041C0000044C02500A778213C1940000319702540 +:1041D000000F4C00AD090004AD0E0000934D092006 +:1041E0003C03000625090014000D360000C32025FD +:1041F000AD0400088F59092C24E5000130A27FFF8F +:10420000AD19000C8F580930A782005825020028EC +:10421000AD1800108F4F0938AD0F0014AD2B0004FE +:104220008F4E0940AD2E0008934D09373C0508001C +:1042300090A53D908F4409488F46094031A700FF63 +:1042400000EC1821008678230003C7000005CC008D +:104250000319602531E8FFFC01885825AD2B000CBF +:10426000AD20001003E00008AF4A002C3C0D080010 +:1042700095AD3D863C0E080095CE3D800A0004C9F0 +:1042800001AE10213C05080094A53D8A3C060800BB +:1042900094C63D803C18080097183D7C952E00245C +:1042A00000A6782101F86823000E240025A2FFF261 +:1042B0000082182524190800AD03000CAD19001464 +:1042C000AD0000100A0004C425080018952600243B +:1042D000952500280006C40000057C00370E8100EB +:1042E00035ED0800AD0E000CAD0D00100A0004C441 +:1042F000250800141480FFA200000000952400246B +:104300000004140034430800AD03000C0A0004C488 +:10431000250800103C03080094633D8A3C05080012 +:1043200094A53D803C06080094C63D7C9539002448 +:1043300095380028006520210086782300196C003C +:104340000018740025E2FFEE01C2202535A381008C +:1043500024190800AD03000CAD040010AD190018BD +:10436000AD0000140A0004C42508001C03E0000886 +:10437000240201F427BDFFE8AFB00010AFBF001466 +:104380000E0000600080802124050040AF45081425 +:104390008F8300508F84004C8F85005C0070182143 +:1043A0000064102318400004AF830050AF63005432 +:1043B0008F660054AF86004C1200000C0000000015 +:1043C0008F440074936800813409FA002D070007B8 +:1043D00010E0000500891021936C0081240B01F48A +:1043E000018B500401441021AF62000C8F4E095C18 +:1043F00001C5682319A000048FBF00148F4F095C0A +:10440000AF8F005C8FBF00148FB000100A000062F5 +:1044100027BD00188F8400648F8300508F82004C6A +:10442000AF640044AF63005003E00008AF62005483 +:104430003C038000346200708C43000027BDFFF80D +:10444000308700FF30A900FF30C800FFAF83003085 +:104450008F4401780480FFFE3C02800034590070D4 +:104460008F380000A3A700033C0708008CE7007406 +:104470008FAC00003C0608008CC600700303782354 +:104480003C0E7FFF00EFC82135CDFFFF000050211B +:10449000018D282400CA1821000847C0032F202BB3 +:1044A00000A810250064C021AFA200003C01080054 +:1044B000AC3900743C010800AC380070934F010A1D +:1044C000A3A000023C0E80FFA3AF00018FAC000050 +:1044D000312B007F35CDFFFF018D4824000B5600A6 +:1044E000012A4025240730002406FF803C051000E7 +:1044F00027BD0008AF48014CAF470154A740015801 +:10450000A346015203E00008AF45017827BDFFE84C +:10451000AFBF0014AFB000108F6500743C06800080 +:10452000309000FF00A620250E000060AF640074EC +:1045300093630005346200080E000062A362000568 +:10454000020020218FBF00148FB000102405000549 +:10455000240600010A00057027BD001827BDFFE0F2 +:104560003C038000AFB00010AFBF0018AFB1001423 +:10457000346200708C470000309000FF30A800FFCC +:10458000AF8700308F4401780480FFFE3C18800024 +:10459000371100708E2F00003C0D08008DAD0074A7 +:1045A0003C0A08008D4A007001E7702301AE282103 +:1045B0000000582100AE302B014B48210126382144 +:1045C0003C010800AC250074000088213C01080073 +:1045D000AC2700701100000F000000008F62007413 +:1045E0002619FFFF3208007F0002FE0233E5007F3C +:1045F00015000006332200FF2407FF800207202653 +:1046000024A3FFFF00838025320200FF00408021A9 +:10461000241110080E000060000000008F490818E7 +:104620003125000414A0FFFD3218007F001878C067 +:104630000018714001CF682125AC0088AF4C0818E4 +:10464000274A09808D4B0020AF4B01448D46002442 +:10465000AF460148A35001500E000062A740015828 +:10466000022010218FBF00188FB100148FB00010EE +:1046700003E0000827BD002027BDFFE8308400FFCD +:10468000AFBF00100E0005BB30A500FF8F830050A8 +:104690008FBF0010344500402404FF903C021000FE +:1046A00027BD0018AF43014CA3440152AF4501544C +:1046B00003E00008AF4201789343093E30620008EE +:1046C0001040000D3C0901013528080AAC880000A3 +:1046D0008F470074AC8700043C06080090C63D90EC +:1046E00030C5001050A00006AC8000088F6A006042 +:1046F000AC8A00082484000C03E00008008010212C +:104700000A0006222484000C27BDFFE8AFBF001476 +:10471000AFB000109346093F00A05021000528804B +:104720000085382330C200FF240300063C0908003E +:1047300095293D8624E8FFD824050004104300375E +:10474000240600029750093C3C0F02040006340086 +:10475000320EFFFF01CF6825AC8D0000934C093E5F +:10476000318B0020116000080000000093430936DF +:104770003C020103345F0300307900FF033FC02592 +:1047800024050008AC980004934309349359092187 +:104790000005F882306200FF0002C082332F00FF64 +:1047A00000186E00000F740001AE602501892025FD +:1047B0003C09400000898025ACF0FFD893430937BD +:1047C0008F4F09488F580940306200FF004AC821C6 +:1047D000033F702101F86023000E6F0001A65025F1 +:1047E0003185FFFC001F58800145482501683821AC +:1047F000AD0900200E00006024F00028240400040D +:104800000E000062A364003F020010218FBF00145D +:104810008FB0001003E0000827BD00180A0006351D +:104820002406001227BDFFD024090010AFB60028CF +:10483000AFB50024AFB40020AFB10014AFB000108A +:104840003C010800A0293D90AFBF002CAFB3001C75 +:10485000AFB2001897480908309400FF3C02000EE0 +:104860003107FFFF000731C0AF46002C974409080D +:104870009344010B30B500FF0342802130830030A8 +:104880000000B0211060012500008821240C0004E4 +:104890003C010800A02C3D90934B093E000B5600B4 +:1048A000000A2E0304A0016000000000AF40004891 +:1048B000934F010B31EE002011C0000600000000F4 +:1048C0009358093E00189E00001396030640018984 +:1048D000000000009344010B30830040106000038F +:1048E0008F9300508F8200502453FFFF9347093E5F +:1048F00030E6000814C000022412000300009021DA +:104900009619002C93580934934F0937A7990058EA +:10491000330C00FF31EE00FF024E6821000D58807D +:10492000016C5021015140213C010800A4283D8622 +:104930009205001830A900FF010918213C01080068 +:10494000A4233D88921100181620000200000000E8 +:104950000000000D3C010800A4233D8A3C01080032 +:10496000A4203D803C010800A4203D7C935F010B06 +:104970003063FFFF33F00040120000022464000A9D +:104980002464000B3091FFFF0E00009E02202021C6 +:104990009358010B3C08080095083D8A00402021EF +:1049A00000185982316700010E00049A010728217E +:1049B000934C010B8F4B002C974E09083C0F000EB7 +:1049C000034F402131CDFFFF000D51C0AF4A002CF5 +:1049D000974309089505001A004038212404000176 +:1049E00030A9FFFFAC4900008D06001C00404821A3 +:1049F000318A0040AC4600048D020020ACE2000881 +:104A00009103001930630003106400EC2879000260 +:104A100017200118241000021070010C241F00033D +:104A2000107F011E00000000114000DE00000000A9 +:104A30003C09080095293D8625220001935F093431 +:104A4000934E09219504002A33F900FF0019C08212 +:104A500031CF00FF978E005800184600000F6C0001 +:104A6000010D80253045FFFF02051025008E5021E5 +:104A70003C03400000433025000A6400ACEC000415 +:104A8000ACE60000935F09203C19000624EC0014FA +:104A9000001FC60003197825ACEF00088F48092CC9 +:104AA00025CD000131A57FFFACE8000C8F50093007 +:104AB000A785005824E80028ACF000108F4409387E +:104AC00001008021ACE40014AD9300048F53094031 +:104AD000AD930008934A09373C19080093393D907B +:104AE0008F4309488F460940314200FF0052F821A8 +:104AF00000667023001F7F000019C40001F82825FC +:104B000031CDFFFC00AD2025AD84000CAD80001040 +:104B1000AF4B002C934B093E317300081260000D1F +:104B20003C06010134CC080AACEC00288F53007419 +:104B3000AD1300043C0B0800916B3D9031670010F1 +:104B400050E00003AD0000088F6A0060AD0A000865 +:104B50002510000C12C0003D000000009343093FE7 +:104B60002416000624060004306200FF105600C917 +:104B7000240700029758093C3C0F0204330DFFFF45 +:104B800001AF4025AE0800009345093E30A4002047 +:104B90001080000800000000935309363C0B01030D +:104BA000357F0300327900FF033F7025AE0E00040D +:104BB00024060008934F093493480921312AFFFF46 +:104BC00031ED00FF000D1082310300FF0002B6003E +:104BD00000032C0002C56025018A98250012208060 +:104BE0003C0940000204502302695825AD4BFFD810 +:104BF000935F09378F4F09488F58094033F900FFF9 +:104C0000033270210006B08201D6682100074400FB +:104C100001F82823000D1F000068302530A2FFFC9A +:104C20002547FFD800C26025001680800207482172 +:104C3000ACEC0020253000280E0000602412000497 +:104C4000A372003F0E000062000000009347010BBA +:104C500030F20040124000053C1900FF8E180000A1 +:104C6000372EFFFF030E3024AE0600000E0000C7F3 +:104C7000022020213C10080092103D9032110003C8 +:104C80001220000F02A028218F8900502533000137 +:104C9000AF930050AF7300508F6B00540173F82333 +:104CA0001BE00002026020218F640054AF640054B6 +:104CB0008F4C0074258401F4AF64000C02A02821FD +:104CC00002802021A76000680E0005BB3C14100084 +:104CD0008F85005034550006AF45014C8F8A00483F +:104CE0008FBF002C8FB3001C25560001AF960048E3 +:104CF0008FB20018A34A01528FB60028AF55015455 +:104D00008FB10014AF5401788FB500248FB4002008 +:104D10008FB0001003E0000827BD00309358093E13 +:104D200000189E000013960306420036241100026C +:104D300093440923308300021060FEDD8F860060FB +:104D40008F82005014C2FEDA000000000E000060E6 +:104D5000000000009369003F24070016312800FF7F +:104D60001107000C240500083C0C0800918C3D90B4 +:104D7000358B00013C010800A02B3D90936A003F59 +:104D8000314300FF10650065240D000A106D005EC0 +:104D90002402000C0E000062000000000A000690D1 +:104DA000000000003C09080095293D863C0A0800E7 +:104DB000954A3D800A0006F3012A10213C090800AB +:104DC00095293D8A3C04080094843D803C060800F7 +:104DD00094C63D7C95030024012410210046F8234D +:104DE0000003CC0027F0FFF20330C025240F080099 +:104DF000ACF8000CACEF0014ACE000100A0006EEBA +:104E000024E700183C010800A0313D90935F093E63 +:104E10002416000133F900201720FEA524110008F4 +:104E20000A000690241100048F6E00848F4D094003 +:104E300011A0FE9EAF8E0050240F00143C0108000C +:104E4000A02F3D900A00068F00000000950E002460 +:104E5000950D0028000E6400000D2C00358981009E +:104E600034A60800ACE9000CACE600100A0006EE1F +:104E700024E700141460FEEC0000000095020024FA +:104E800000021C0034640800ACE4000C0A0006EECA +:104E900024E700100A000741240700123C02080022 +:104EA00094423D8A3C06080094C63D803C030800BD +:104EB00094633D7C95100024951900280046F82144 +:104EC00003E3C02300106C0000197400270FFFEEED +:104ED00001CF282535AC8100ACEC000CACE500100E +:104EE00024070800AD2700182527001C0A0006EE3D +:104EF000AD2000148F7F004CAF7F00548F79005499 +:104F00000A000699AF790050A362003F0E000062CC +:104F1000000000000A0006900000000024020014B7 +:104F20000A000827A362003F27BDFFE8308400FF86 +:104F3000AFBF00100E0005BB30A500FF9378007EC8 +:104F40009379007F936E00809368007A332F00FF7F +:104F500000186600000F6C0031CB00FF018D482562 +:104F6000000B52008FBF0010012A3825310600FFC8 +:104F70003444700000E628252402FF813C03100021 +:104F800027BD0018AF45014CAF440154A342015264 +:104F900003E00008AF43017827BDFFD8AFB2001887 +:104FA000AFB10014AFB00010AFBF0020AFB3001C12 +:104FB00093420109308600FF30B000FF000618C29E +:104FC000320400023071000114800005305200FFED +:104FD0009367000530E5000810A0000D30C80010F0 +:104FE000024020210E0005A70220282124040001F0 +:104FF0008FBF00208FB3001C8FB200188FB1001438 +:105000008FB000100080102103E0000827BD0028A9 +:105010001500003200000000934301090000282120 +:105020003062007F000220C00002F94003E49821B2 +:1050300026790088033B98218E7800248E6F000823 +:10504000130F0046000000008F6400842418000243 +:105050000004FD8233F900031338007C00000000D7 +:1050600093660083934A0109514600043205007C8F +:1050700010A00060000000003205007C14A0005366 +:105080000240202116200006320400018E7F0024F9 +:105090008F59010417F9FFD60000202132040001C6 +:1050A0001080000A024020218F4209408F93006443 +:1050B00010530006000000000E00066D022028219B +:1050C0008F430940AF630044024020210E000602D6 +:1050D000022028210A000860240400013C0908007D +:1050E0008D290064252600013C010800AC260064DF +:1050F00016000012000000008F6D00843C0E00C0FE +:1051000001AE602415800005024020210E00082E0B +:10511000022028210A00086024040001240500045C +:105120000E00057024060001024020210E00082E0A +:10513000022028210A000860240400010E0000411A +:1051400024040001936B007D020B50250E000062C9 +:10515000A36A007D0A0008A38F6D00848F66007427 +:105160008F4801048E67002400064E021507FFB623 +:105170003126007F936B008326440001308A007F34 +:1051800011460043316300FF5464FFB08F64008414 +:105190002645000130B1007F30A200FF1226000436 +:1051A00024050001004090210A0008762411000126 +:1051B000240FFF80024F702401CF9026324200FF5F +:1051C000004090210A000876241100010E00066DAF +:1051D00002202821321800301300FFAA321000826A +:1051E000024020210E0005A7022028210A000860A5 +:1051F000240400018F6E00743C0F8000240500031E +:1052000001CF9025AF7200749371008324060001D2 +:105210000E000570322400FF0E000041240400013E +:10522000936D007D020D60250E000062A36C007D71 +:105230003C0B08008D6B0054257000013C010800F8 +:10524000AC3000540A000860240400018F68007428 +:105250003C0980002405000401093825AF6700746B +:1052600093630083240600010E000570306400FF84 +:105270000E000041240400019362007D0202982583 +:105280000E000062A373007D0A0008602404000180 +:10529000324D008039AC0080546CFF6C8F64008408 +:1052A0000A0008C92645000127BDFFC83C0A0008BE +:1052B000AFBF0030AFB5002CAFB40028AFB30024AF +:1052C000AFB20020AFB1001CAFB00018034AD82124 +:1052D00024090040AF490814AF4008108F42094428 +:1052E0008F4309508F4609548F47095C8F48094CFA +:1052F000934401089345010BAF820064308400FFA2 +:1053000030A500FFAF830050AF86004CAF87005C34 +:105310000E00084AAF8800601440017D8FBF003046 +:10532000A7600068934D0900240B00503C1508004D +:1053300026B53D4831AC00FF3C12080026523D58CE +:10534000118B0003000000000000A8210000902144 +:10535000935101098F9F005024040010322E007FCA +:10536000000E68C0000E6140018D282124B4008821 +:10537000AF5408188F4901048F4A09A43C0B000E52 +:10538000034BC021012A10233C010800AC223D6CD4 +:105390008F4309583C010800A0243D909747090815 +:1053A000007F30233C010800AC263D7030E8FFFF51 +:1053B0000008C9C03C010800AC3F3D94AF59002C27 +:1053C000974209089710002C8EB10000930F001827 +:1053D00003749821A7900058AF9300440220F80965 +:1053E00031F000FF304E000215C001B2304F000115 +:1053F00011E0014F000000009343093E30660008B1 +:1054000014C00002241400030000A0218F5809A436 +:10541000241300013C010800AC383D98934F093437 +:105420009351093731EC00FF322E00FF028E6821C4 +:10543000000D288000AC5021015058213C0108008B +:10544000A42B3D883C010800A42A3D8693490934D9 +:10545000312200FF02022021249000103C010800AC +:10546000A4303D84240700068F9F00503C010800B3 +:10547000AC273D8C8F88005C8F5909580000802133 +:10548000011F282304A00149033F20230480014772 +:1054900000A4302B10C00149000000003C010800AE +:1054A000AC253D708E4200000040F809000000006D +:1054B00030430002146000F80040882130440001AD +:1054C000548000108E4200043C0908008D293D7470 +:1054D0003C0AC000012A8025AF500E008F45000015 +:1054E00030AB00081160FFFD00000000974D0E0872 +:1054F00024100001A78D003C8F4C0E04AF8C0034AB +:105500008E4200040040F8090000000002228825B5 +:10551000322E000215C00180000000003C09080086 +:1055200095293D7C3C06080094C63D883C0A08004D +:10553000954A3D7E3C1908008F393D740126602153 +:105540003C1808008F183D983C03080094633D9276 +:10555000018A20218F4E09400329F821248F00025F +:1055600003E32821031968213C010800A42C3D8A8B +:10557000AF8E00643C010800AC2D3D983C01080052 +:10558000A4253D800E00009E31E4FFFF8F87004878 +:10559000004020213C010800A0273D918E420008D8 +:1055A00024E80001AF8800480040F809000000002E +:1055B0009344010B8F4C002C974A09083C0B000EBA +:1055C000034B40213149FFFF000919C08F8B005068 +:1055D000AF43002C974309089506001A0040382174 +:1055E000308A004030DFFFFFAC5F00008D19001CE7 +:1055F00000404821AC5900048D180020AC58000828 +:10560000910F001931E30003107300F00000000057 +:10561000286200021440010924050002106500FD03 +:10562000240D0003106D010D00000000114000D991 +:10563000000000003C0A0800954A3D862542000112 +:10564000934D093493580921950E002A31A300FF88 +:1056500000032082331F00FF9798005800047E004B +:10566000001FCC0001F940253049FFFF010910253A +:1056700001D830213C0540000045502500066C0053 +:10568000ACED0004ACEA0000934309203C040006A2 +:1056900024ED00140003FE0003E4C825ACF9000863 +:1056A0008F49092C270F000131EE7FFFACE9000C78 +:1056B0008F480930A78E005824E90028ACE8001074 +:1056C0008F45093801204021ACE50014ADAB000442 +:1056D0008F420940ADA20008934B09373C1F0800D8 +:1056E00093FF3D908F4309488F4A0940316600FF80 +:1056F00000D42021006A78230004C700001FCC00DA +:105700000319282531EEFFFC00AE1025ADA2000CD8 +:10571000ADA00010AF4C002C934C093E318B00081B +:105720005160000F8E58000C3C06010134CA080A73 +:10573000ACEA00288F4B0074AD2B00043C0C080031 +:10574000918C3D903187001050E00003AD2000089F +:105750008F620060AD2200082528000C8E58000CD6 +:105760000300F809010020213C19080097393D8AFF +:105770003C1F080097FF3D7E033F782125E900028A +:105780000E0000C73124FFFF3C0E08008DCE3D6C9B +:105790003C0808008D083D7401C828233C0108001E +:1057A000AC253D6C14A00006000000003C0308007E +:1057B0008C633D8C346400403C010800AC243D8C7B +:1057C000120000708F8C00448F470E108F900044A1 +:1057D000AE0700208F4D0E18AE0D00243C100800BF +:1057E00096103D800E000060000000002402004082 +:1057F000AF4208148F8600508F8A004C00D01821C9 +:10580000006A582319600004AF830050AF6300544E +:105810008F650054AF85004C1200000C00000000A2 +:105820008F440074936800813409FA002D0E00073C +:1058300011C0000500891821937F0081241901F40B +:1058400003F9780401E41821AF63000C8F44095C6C +:105850008F83005C0083C0231B0000030000000056 +:105860008F50095CAF90005C0E00006200000000E9 +:105870008F8C00508E4700103C010800AC2C3D94EA +:1058800000E0F809000000003C0D08008DAD3D6C03 +:1058900055A0FEF5240700068F45002497590908F6 +:1058A0008F8B00648F9400503C0F001F978200582C +:1058B0008F8600548F93004C3328FFFF35E9FF801B +:1058C00000A95024000871C032320100AF4E0024FC +:1058D000A4C2002CAF4A0024AF6B0044AF74005048 +:1058E000AF73005416400080323800105700008615 +:1058F0008EA40004322300405460001B8EB10008C7 +:105900008EB0000C0200F809000000008FBF0030CC +:105910008FB5002C8FB400288FB300248FB20020E5 +:105920008FB1001C8FB0001803E0000827BD0038BD +:10593000934701098F8800380007FE0003E8C82557 +:10594000AF5900808F5809A08F5309A4AFB8001039 +:10595000AF580E148FB40010AF540E10AF530E1C7E +:105960000A000962AF530E180220F8090000000077 +:105970008EB0000C0200F809000000000A000AA81E +:105980008FBF0030A5800020A59300220A000A5B8B +:10599000AD9300243C09080095293D863C0608008B +:1059A00094C63D800A0009F4012610213C0108003C +:1059B000AC203D700A00098E8E4200003C010800B8 +:1059C000AC243D700A00098E8E4200003C030800A2 +:1059D00094633D8A3C04080094843D803C1F080089 +:1059E00097FF3D7C951800240064C821033F78236D +:1059F00000186C0025EEFFF201AE2825AC45000C26 +:105A000024020800ACE20014ACE000100A0009EF28 +:105A100024E70018950600249509002800062400B4 +:105A200000091C00349F810034790800ACFF000C91 +:105A3000ACF900100A0009EF24E700141460FEFB23 +:105A4000000000009518002400187C0035EE0800C6 +:105A5000ACEE000C0A0009EF24E700103C07080038 +:105A600094E73D803C04080094843D8A3C03080090 +:105A700094633D7C95190024951800280087F8212F +:105A800003E378232407080000192C0000186C0099 +:105A900025EEFFEE01AE302534A28100AD270018BF +:105AA0002527001CAD22000CAD2600100A0009EFCE +:105AB000AD20001493520109000028210E000602B7 +:105AC000324400FF8FBF00308FB5002C8FB4002808 +:105AD0008FB300248FB200208FB1001C8FB000184C +:105AE00003E0000827BD0038935F010933E400FF9D +:105AF0000E00066D00002821323800105300FF7E92 +:105B0000322300408EA400040080F8090000000049 +:105B10000A000AA2322300401200FF5F00000000CA +:105B20008F540E148F920044AE5400208F530E1CDD +:105B30000A000A8AAE5300248F82001C0080402194 +:105B40003C0401009047008530E30020106000090C +:105B5000000000003C0708008CE73D948F8300188C +:105B600000E32023048000089389000414E3000369 +:105B70000100202103E00008008010213C04010006 +:105B800003E00008008010211120000B006738237B +:105B90008F8C002024090034918B00BC316A0002F4 +:105BA000514000012409003000E9682B15A0FFF1E5 +:105BB0000100202100E938232419FFFC00B9C0248A +:105BC00000F9782400F8702B15C0FFEA01E82021C5 +:105BD00030C200030002182314C000123069000311 +:105BE0000000302100A9702101C6682100ED602B62 +:105BF0001180FFE03C0401002D2F00010006482B1E +:105C00000105382101E9302414C0FFDA24E4FFFC47 +:105C10002419FFFC00B9C0240308202103E0000878 +:105C2000008010218F8B002024060004916A00BCA4 +:105C3000314400041480FFEC00A970210A000B5EBF +:105C40000000302127BDFFE8AFBF00108F460100E4 +:105C5000934A01093C1F08008FFF00902407FF8032 +:105C6000314F00FF31E8007F0008614003E6C821A2 +:105C7000032CC02127090120012770243C010800C2 +:105C8000A02F3DD0AF4E080C3C0D08008DAD00900C +:105C90003C0400803482000301A65821016C1821C5 +:105CA0002465012030AA007801424025AF48081C35 +:105CB0003C1F08008FFF00908F88004003E6C02142 +:105CC0003319000703074824033A7821AF49002815 +:105CD00025E909C0952E00023C0D08008DAD008C11 +:105CE0003C0A08008D4A009031CC3FFF01A61821E4 +:105CF000000C5980006B282100A72024AF44002C01 +:105D0000952200023C1F08008FFF008C9107008540 +:105D100030593FFF03E678210019C1800146702108 +:105D200001F8682131CC007F31AB007F019A282136 +:105D3000017A50213C03000C3C04000E00A32821F2 +:105D40000144102130E6002027470980AF82002C53 +:105D5000AF88001CAF890024AF85002010C000066A +:105D6000AF8700288D0200508CA4010C0044302322 +:105D700018C0007700000000910C0085240DFFDFA3 +:105D8000018D3824A10700858F8B001C8F8900248A +:105D90008F8700288D65004CAF850018912F000D6E +:105DA00031EE002011C0001700000000240900019E +:105DB000A3890004AF80000C8CE400248F85000CC4 +:105DC000240A0008AF800008AF8000103C010800E2 +:105DD000A42A3D7E3C010800A4203D920E000B3217 +:105DE000000030218F8500248FBF0010AF82001487 +:105DF00090A8000D27BD00180008394203E00008F4 +:105E000030E20001913F00022418000133F900FF45 +:105E10000019218210980039240800021088005BC4 +:105E20008F86002C8CE5002414A0001B8F9F00207F +:105E300091220000240A00053046003F10CA0047A6 +:105E4000240400018F860008A3840004AF8600109C +:105E5000AF86000C8CE400248F85000C240A000817 +:105E60003C010800A42A3D7E3C010800A4203D928C +:105E70000E000B32000000008F8500248FBF001041 +:105E8000AF82001490A8000D27BD00180008394209 +:105E900003E0000830E200018CF800088CF90024CF +:105EA0008FEE00C4A38000048CE40024AF8E000CAD +:105EB0008F85000C8F86000803197823240A0008B8 +:105EC000AF8F00103C010800A42A3D7E3C01080071 +:105ED000A4203D920E000B32000000008F850024AC +:105EE0008FBF0010AF82001490A8000D27BD0018CE +:105EF0000008394203E0000830E20001912300006D +:105F00003062003F104400278F8500208CE400247D +:105F100014800021000000008D2E00183C187FFF27 +:105F20008F850020370FFFFF01CF1824AF830008B3 +:105F30008F9F00088CA8008403E8C82B172000025C +:105F400003E020218CA400840A000BEDAF8400083C +:105F50008CA3010C0A000BCBAF8300188D2C00180A +:105F60008F8600083C0D7FFF8F89002035A3FFFF3F +:105F70000183582424040001AF8B0010AD2000CC15 +:105F8000A38400040A000BF9AF86000C8CCA00142D +:105F90000A000BEDAF8A00088CA300C80A000C3081 +:105FA000AF8300088F84002C8CAC00648C8D0014AF +:105FB000018D582B11600004000000008CA20064C9 +:105FC0000A000C30AF8200088C8200140A000C30EA +:105FD000AF8200088F85000C27BDFFE0AFBF00181F +:105FE000AFB1001414A00007AFB000108F860024DA +:105FF0002402000590C400003083003F106200B608 +:106000008F8400208F91000800A080218F8C0028B1 +:106010003C0508008CA53D708D8B000431663FFF68 +:1060200000C5502B5540000100C02821938D00046D +:1060300011A0007300B0F82B8F98002024040034C6 +:10604000930F00BC31EE000251C000012404003067 +:1060500000A4C82B172000D10000000000A42823B2 +:1060600000B0F82B3C010800A4243D7C17E0006838 +:10607000020020213C0308008C633D6C0083102B40 +:1060800054400001008018218F8800243C01080042 +:10609000AC233D74000048219104000D30830020A2 +:1060A000506000018F490E188F8300140123382B94 +:1060B00010E00059000000003C0408008C843D748E +:1060C00000895821006B502B114000560090602B26 +:1060D0000069302300C020213C010800AC263D743B +:1060E00012000003241FFFFC1090008A32270003D7 +:1060F000009FC8243C010800AC393D743C010800F5 +:10610000A4203D928F84000C120400078F8300208E +:10611000AF910008020020218C7100CCAF90000CE0 +:1061200026300001AC7000CC3C0208008C423D746B +:106130008F8A0010240700180082202301422823A0 +:10614000AF84000C10800002AF85001024070010FF +:106150008F86001C3C010800A0273D9024070040CA +:1061600090CC0085318B00C0116700408F8D0014EA +:1061700014A0001500002021934A01098F420974E0 +:10618000314500FF0002260224A300013090007F69 +:106190003071007F1230007A2407FF80A0C3008393 +:1061A0003C0908008D293D8C8F880024240D0002B5 +:1061B000352C00083C010800A02D3DD13C01080011 +:1061C000AC2C3D8C24040010910E000D31C6002033 +:1061D00010C0000500801821240800013C010800BF +:1061E000AC283D74348300018FBF00188FB10014B8 +:1061F0008FB000100060102103E0000827BD0020D0 +:106200003C010800A4203D7C13E0FF9A02002021FD +:106210000A000C8100A020213C0408008C843D74FD +:106220000090602B1180FFAE000000003C0F0800C2 +:1062300095EF3D7C01E4702101C6682B11A0000799 +:106240002C8200043C1F60008FF954043338003F57 +:106250001700FFE5240300422C8200041040FFA039 +:10626000240300420A000CDF8FBF0018152DFFC069 +:10627000000000008CDF00743C0380002405FF80D8 +:1062800003E3C825ACD9007490D80085240E00041F +:1062900024040010330F003F01E54025A0C800850D +:1062A0008F8800243C010800A02E3DD1240300016A +:1062B0009106000D30C900201520000300000000E9 +:1062C0003C0308008C633D743C010800AC233D6C2A +:1062D0000A000CD6000000008F8700108C88008414 +:1062E00000E8282B14A0000200E088218C91008493 +:1062F00024090001A38900048F440E1802202821DC +:106300000E000B3202203021022080210A000C678F +:10631000AF82001400071823306600033C01080018 +:10632000A4263D92122000058F8C0020918B00BC8A +:10633000316A00041540001524CD00043C0F08000C +:1063400095EF3D9201E4702100AE302B50C0FF6EFE +:106350008F84000C2C85000514A0FFA324030042A9 +:106360003098000317000002009818232483FFFCD4 +:106370003C010800AC233D740A000CA3000000009F +:1063800000A758240A000CCB016718263C0108001E +:10639000A42D3D920A000D33000000003C010800CE +:1063A000AC203D740A000CDE240300428F830010F1 +:1063B00014600007000010218F88002424050005C8 +:1063C0009106000030C400FF1085000300000000AB +:1063D00003E0000800000000910A0018314900FFA6 +:1063E000000939C214E0FFFA8F85001C3C04080044 +:1063F00094843D7C3C0308008C633D943C19080068 +:106400008F393D743C0F080095EF3D920064C02128 +:106410008CAD00540319702101CF6021018D5823E8 +:106420001960001D00000000910E001C8F8C002CD4 +:10643000974B0E1031CD00FF8D850004016D302388 +:106440008D88000030CEFFFF000E510000AAC82149 +:106450000000382101072021032A182B0083C021C6 +:10646000AD990004AD980000918F000A01CF68211A +:10647000A18D000A8F88002C974B0E12A50B0008E7 +:10648000950A003825490001A50900389107000D3B +:1064900034E60008A106000D03E00008000000003B +:1064A00027BDFFE0938700048F8F00248FAD001479 +:1064B0003C0E7FFF8F89000C35C8FFFFAFBF001C6B +:1064C000AFB0001801A8182491EA000D000717C00A +:1064D0003C1FBFFF006258252D2E00018F90001831 +:1064E00037F9FFFF3C1808008F183D943C0F080057 +:1064F00095EF3D8A01796824000E47803C07EFFF45 +:106500003C05F0FF01A818253149002034E2FFFFC7 +:1065100034ACFFFF0310582327A500102406000207 +:1065200025EA000200621824008080211520000264 +:10653000000040218F480E1CA7AA001205600037FA +:106540002407000030FF00FF001FCF008F8B001CCE +:1065500000793825AFA70014916F00853C0808002A +:1065600091083D913C18DFFF31EE00C0370AFFFF74 +:10657000000E182B3C1F080097FF3D8400EA68249A +:10658000A3A800110003174001A248258FB90010ED +:10659000AFA900143C0A0800914A3D93A7BF00161A +:1065A0008FA80014032CC0243C0B01003C0F0FFFEC +:1065B000030B18253147000335EEFFFF010C68245B +:1065C00000071600006EF8243C09700001A2C825DF +:1065D00003E95825AFB90014AFAB00100E000076E8 +:1065E000A3A000158F8C0024260200089186000DC0 +:1065F00030C40020108000068FBF001C3C0508003E +:1066000094A53D8024B0FFFF3C010800A4303D80EC +:106610008FB0001803E0000827BD00208F980014F9 +:106620000118502B5540FFC7240700010A000DB682 +:1066300030FF00FF9382000427BDFFE0AFBF0018CA +:106640001040000F008050218F880024240B00058B +:106650008F890008910700008F8400200100282105 +:1066600030E3003F8F86002C106B000800003821BB +:10667000AFA900100E00040EAFAA0014A3800004FE +:106680008FBF001803E0000827BD00208D190018F7 +:106690003C0F08008DEF3D748F9800103C027FFF87 +:1066A0008D080014345FFFFF033F682401F8702158 +:1066B00001AE602301883821AFA900100E00040E3E +:1066C000AFAA00140A000E04A38000048F870024E0 +:1066D0003C05080094A53D923C0208008C423D8C8C +:1066E00090E6000D0005240030C300201060002C4F +:1066F000004440258F85001C00006021240B000110 +:1067000090A3008500004821240A00013C0F80006E +:1067100035EE00708DC70000AF8700308F580178CC +:106720000700FFFE3C038000347900708F380000C2 +:106730003C0508008CA500743C0D08008DAD007070 +:106740000307782300AF38210000102100EF302B21 +:1067500001A22021008618213C010800AC2700740A +:106760003C010800AC230070AF4B01483C19080005 +:106770008F393D94A7490144A74A0146AF59014CBE +:106780003C0B0800916B3D91A34B0152AF48015463 +:106790003C081000A74C015803E00008AF480178FE +:1067A0008F4B0E1C3C0A08008D4A3D7497490E160B +:1067B000974D0E1401456021312AFFFF0A000E2774 +:1067C00031A9FFFF8F8300249064000D30820020E8 +:1067D0001040002900000000000048210000502166 +:1067E000000040213C07800034EB00708D67000002 +:1067F000AF8700308F4C01780580FFFE3C0D800094 +:1068000035AC00708D8B00003C0508008CA5007431 +:106810003C0408008C8400700167302300A67821B6 +:106820000000102101E6C82B0082C021031970214D +:106830003C010800AC2F00743C010800AC2E007035 +:10684000AF4901483C0D08008DAD3D94A748014477 +:1068500024090040A74A01463C081000240AFF9181 +:10686000AF4D014CA34A0152AF490154A740015812 +:1068700003E00008AF4801788F490E1897460E12C2 +:1068800097450E1030CAFFFF0A000E5D30A8FFFFCB +:106890008F83002427BDFFF89064000D3082002014 +:1068A0001040003A00000000240B000100004821C5 +:1068B000240A00013C088000350700708CE30000CA +:1068C000AF8300308F4C01780580FFFE3C0E8000C6 +:1068D0003C04080090843DD035C700708CEC00006B +:1068E0003C0508008CA50074A3A400033C19080013 +:1068F0008F3900708FAD00000183302300A638214E +:10690000000010210322782100E6C02B01F860214D +:1069100001AE4025AFA800003C010800AC27007480 +:106920003C010800AC2C00709346010A3C040800AE +:1069300090843DD1A3A00002A3A600018FA3000074 +:106940003C0580FF3099007F34A2FFFF006278246D +:106950000019C60001F87025240D3000AF4E014C1F +:1069600027BD0008AF4D0154A7400158AF4B014867 +:10697000A7490144A74A01463C091000240AFF80A8 +:10698000A34A015203E00008AF4901788F4B0E186B +:1069900097460E1297450E1030CAFFFF0A000E915F +:1069A00030A9FFFF8F85001C2402008090A4008581 +:1069B000308300C0106200058F8600208F88000899 +:1069C0008F87000CACC800C8ACC700C403E0000847 +:1069D000000000003C0A0800254A39543C09080020 +:1069E00025293A203C08080025082DD43C0708003A +:1069F00024E73B343C06080024C637C43C050800A5 +:106A000024A5353C3C040800248431643C03080080 +:106A10002463385C3C020800244236303C01080004 +:106A2000AC2A3D503C010800AC293D4C3C0108001B +:106A3000AC283D483C010800AC273D543C0108000F +:106A4000AC263D643C010800AC253D5C3C010800DF +:106A5000AC243D583C010800AC233D683C010800D3 +:0C6A6000AC223D6003E0000800000000D4 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex b/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex deleted file mode 100644 index 627baec7cb5c..000000000000 --- a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex +++ /dev/null @@ -1,6081 +0,0 @@ -:100000000800011008000000000051F8000000C8BE -:10001000000000000000000000000000080051F88F -:1000200000000038000052C00800008808000000EE -:100030000000528C000052F8080054800000008438 -:100040000000A5840800528C000001C00000A60832 -:10005000080031D808000000000081080000A7C88F -:1000600000000000000000000000000008008108FF -:1000700000000124000128D00800048808000400C2 -:10008000000017EC000129F400000000000000004F -:100090000000000008001BEC00000004000141E02B -:1000A000080000A808000000000038D0000141E46A -:1000B000000000000000000000000000080038D030 -:0800C0000000003000017AB4D9 -:0800C8000A00004400000000E2 -:1000D000000000000000000D636F6D352E302E30E3 -:1000E0006A31350005000002000000000000000336 -:1000F00000000014000000320000000300000000B7 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000100000030C -:1001E000000000000000000D0000000D3C020800AF -:1001F000244252603C0308002463539CAC4000003E -:100200000043202B1480FFFD244200043C1D080005 -:1002100037BD9FFC03A0F0213C1008002610011000 -:100220003C1C0800279C52600E00026B000000007E -:100230000000000D27BDFFE0AFBF0018AFB10014F4 -:10024000AFB000103C04800094820108304370007D -:10025000240220001062000B2862200114400036A6 -:1002600000001021240240001062002C0000000059 -:10027000240260001062002D000010210A00009D81 -:100280008FBF001834910100922400098E300018AD -:1002900010800020240300012402000914820006BB -:1002A0008F8200243C0280089442001A000214004D -:1002B000020280258F8200248C42000C1040001521 -:1002C000000018210E000D52000000008F83002452 -:1002D000962400088F8200209463001E9625000C4F -:1002E0000004240000832025AC500000AC4500042D -:1002F000AC400008AC40000CAC400010AC40001416 -:10030000AC400018AC44001C0E000D862404000113 -:10031000000018210A00009C006010210E00043B20 -:10032000000000000A00009C000010210E000C726A -:1003300000000000000010218FBF00188FB10014D2 -:100340008FB0001003E0000827BD00208F8200243A -:1003500027BDFFE0AFB00010AFBF0018AFB1001471 -:100360008C42000C3C1080008E11010010400034C3 -:100370008FBF00180E000D52000000008F85002076 -:1003800024047FFF0091202BACB100008E030104F8 -:100390009602010800031C003042FFFF006218258E -:1003A000ACA300049202010A96030114304200FF3C -:1003B0003063FFFF0002140000431025ACA20008C8 -:1003C0009603010C9602010E00031C003042FFFF51 -:1003D00000621825ACA3000C9603011096020112CE -:1003E00000031C003042FFFF00621825ACA3001080 -:1003F0008E020118ACA200148E02011CACA20018DF -:10040000148000088F820024978200003C0420059D -:100410000044182524420001ACA3001C0A0000DBA4 -:10042000A78200003C0340189442001E00431025A0 -:10043000ACA2001C0E000D86240400018FBF001822 -:100440008FB100148FB000100000102103E00008ED -:1004500027BD00203C0680008CC202B824030001A6 -:1004600004410008008028213C0208008C42006002 -:10047000244200013C010800AC22006003E00008B7 -:10048000006010218C83002094820016ACC302808F -:100490002442FFFCA4C202843C0208008C42005C9F -:1004A0008C84000494A3000E244200013C01080047 -:1004B000AC22005C3C021000A4C30286ACC40288DB -:1004C00000001821ACC202B803E00008006010214F -:1004D00027BDFFE0AFB000103C108000AFB20018A5 -:1004E000AFBF001CAFB10014361201009243000BE5 -:1004F0002402001A965100081462005A00002821B4 -:1005000032220001104000188F8200248E42000029 -:10051000000223403C02003F3442FFFF0044102B06 -:10052000104000043C030040964200140A000124DD -:10053000008320218E030100240201005462000682 -:10054000964200143C028008904200043042000FA2 -:10055000000225009642001400821025AE020080A1 -:100560000A000157000000008C42000C10400028D7 -:10057000000000000E000D5200000000960201086D -:100580009603010C8F8500203042003E3063FFFF50 -:100590000002140000431025ACA200008E020100EE -:1005A000ACA20004960301169604010E8F8200246B -:1005B00000031C003084FFFF00641825ACA3000872 -:1005C00096030110960401129446001E00031C00BD -:1005D0003084FFFF00641825ACA3000C3C0220000F -:1005E00000C2302596020114240400013042FFFFAE -:1005F000ACA200108E020118ACA200149202010BF2 -:10060000304200FFACA200180E000D86ACA6001C04 -:100610003C0208008C420040244200013C010800DA -:10062000AC2200403C0308008C63004432220002EC -:1006300032240004246300013C010800AC23004480 -:10064000108000080002282B024020218FBF001CD0 -:100650008FB200188FB100148FB000100A0000E3B1 -:1006600027BD00208FBF001C8FB200188FB100146F -:100670008FB0001000A0102103E0000827BD00206B -:1006800027BDFFE0AFB000103C108000AFB20018F3 -:10069000AFBF001CAFB10014361201009243000B33 -:1006A00024020003965100081462007500002821FE -:1006B00032220001104000178F8200248E43000078 -:1006C0003C02003F3442FFFF000323400044102B54 -:1006D0005040000524020100964200143C030040F3 -:1006E0000A00018F00832021546200069642001404 -:1006F0003C028008904200043042000F00022500B6 -:100700009642001400821025AE0200800A0001BF4C -:10071000000000008C42000C10400025000000008A -:100720000E000D5200000000960201089603010C15 -:100730008F8500203042003E3063FFFF000214002E -:1007400000431025ACA200008E020100ACA2000400 -:10075000960301169604010E8F82002400031C00EC -:100760003084FFFF00641825ACA300089603011035 -:10077000960401129446001E00031C003084FFFF03 -:1007800000641825ACA3000C3C02200000C23025F8 -:1007900096020114240400013042FFFFACA20010B5 -:1007A000ACA00014ACA000180E000D86ACA6001C76 -:1007B0003C0208008C420040244200013C01080039 -:1007C000AC2200403C0208008C420044322300046A -:1007D000244200013C010800AC22004410600008E3 -:1007E00032220002024020218FBF001C8FB200186D -:1007F0008FB100148FB000100A0000E327BD002065 -:100800001040001F000028213C05800034A2007029 -:100810008C4400008F82000C008210232C43012C9A -:1008200010600004AF820010240500010A0001EEF0 -:10083000AF84000C8CA301043C026020AC43001484 -:100840008C420004240301FE304203FF1443000BDA -:10085000AF84000C8CA20100000219C22462FFFCCC -:100860002C42000810400003240400022462FFFD13 -:10087000004420043C026000AC44691400002821BC -:100880008FBF001C8FB200188FB100148FB0001002 -:1008900000A0102103E0000827BD00203C048000D8 -:1008A0008C83010024020100506200033C02800896 -:1008B0000000000D3C02800890430004000010215D -:1008C0003063000F00031D0003E00008AC830080CC -:1008D0002C8407811080000A000028213C0280003F -:1008E00094420108240320003042700014430005A4 -:1008F0002783FFA43C02800890420005304500FF9A -:100900002783FFA40005208000832021000510C05C -:10091000004510238C8400003C0308002463532C02 -:10092000000210C0004310213C038000AC64009022 -:1009300003E00008AF82002403E00008000010215B -:1009400003E00008000010212402010014820008C6 -:10095000000000003C0208008C4200FC2442000120 -:100960003C010800AC2200FC0A00023030A200204A -:100970003C0208008C420084244200013C01080033 -:10098000AC22008430A200201040000830A30010E8 -:100990003C0208008C420108244200013C0108008E -:1009A000AC22010803E0000800000000106000080D -:1009B000000000003C0208008C42010424420001B7 -:1009C0003C010800AC22010403E000080000000024 -:1009D0003C0208008C420100244200013C01080056 -:1009E000AC22010003E000080000000027BDFFE882 -:1009F000AFB000103C108000AFBF001436040100FF -:100A00009483000830620004104000053066000244 -:100A10008FBF00148FB000100A0000E327BD00183C -:100A200010C00006006028218E0401000E00022084 -:100A3000000000000A000267240200018F82000803 -:100A40008E03010410430007000010218E040100F2 -:100A50000E000220000000008E020104AF82000898 -:100A6000000010218FBF00148FB0001003E00008B9 -:100A700027BD001827BDFFD83C036010AFB3001C92 -:100A8000AFBF0020AFB20018AFB10014AFB000107C -:100A90008C6450002402FF7F3C13080026735290A0 -:100AA000008220243484380CAC6450003C02800066 -:100AB00024030037AC4300083C06080024C6087035 -:100AC000026010212404001C2484FFFFAC460000B7 -:100AD0000481FFFD244200043C0208002442016C12 -:100AE0003C010800AC2252983C020800244205B8A0 -:100AF0003C010800AC22529C3C02080024420284C3 -:100B00003C010800AC2252D83C02080024420408F0 -:100B10003C030800246308783C040800248409246A -:100B20003C05080024A52C803C010800AC2252F8AA -:100B30003C020800244207D43C010800AC2652E0E5 -:100B40003C010800AC2552EC3C010800AC2352F4F7 -:100B50003C010800AC2452FC3C010800AC225300CC -:100B60003C010800AC2352943C010800AC2052A088 -:100B70003C010800AC2052A43C010800AC2052A863 -:100B80003C010800AC2052AC3C010800AC2052B043 -:100B90003C010800AC2052B43C010800AC2052B823 -:100BA0003C010800AC2452BC3C010800AC2052C0FF -:100BB0003C010800AC2052C43C010800AC2052C8E3 -:100BC0003C010800AC2052CC3C010800AC2052D0C3 -:100BD0003C010800AC2652D43C010800AC2652DC93 -:100BE0003C010800AC2052E43C010800AC2552E86E -:100BF0003C010800AC2352F00E0005670000000025 -:100C0000AF80000C8F8300043C0208008C4200205F -:100C10001062001F000088212792FFA43C100800EA -:100C20002610532C3C0208008C42002024050001B1 -:100C300002251804004320248F820004004310245E -:100C40005044000C2631000110800008AF900024B1 -:100C50008E4300003C028000AC4300900E000D1952 -:100C6000AE05000C0A0002EB26310001AE00000CBC -:100C7000263100012E220002261000381440FFE920 -:100C8000265200043C0208008C420020AF8200047F -:100C90003C1080008E110000322200071040FFDA65 -:100CA0008F83000432220001104000213222000212 -:100CB0008E020100AE0200208E020104AE0200A8E6 -:100CC0000E0002028E0401009202010B304300FF6D -:100CD0002C62001D54400004000310800E00021C12 -:100CE0000A00030C00000000005310218C42000099 -:100CF0000040F80900000000104000043C028000A1 -:100D00008C4301043C026020AC4300143C02080008 -:100D10008C4200343C0440003C038000244200012B -:100D2000AC6401383C010800AC22003432220002DD -:100D300010400010322200043C1080008E0201405E -:100D4000AE0200200E0002028E0401400E0003A439 -:100D5000000000003C024000AE0201783C020800A6 -:100D60008C420038244200013C010800AC220038CB -:100D7000322200041040FFA48F8300043C10800046 -:100D80008E020180AE0200200E0002028E0401805D -:100D90008E03018024020F00146200073C028008C9 -:100DA0008E0201883C0300E03042FFFF0043102523 -:100DB0000A000348AE0200803442008090420000E6 -:100DC00024030050304200FF1443000700000000DD -:100DD0000E0003810000000014400003000000002A -:100DE0000E00096A000000003C0208008C42003C32 -:100DF0003C0440003C03800024420001AC6401B884 -:100E00003C010800AC22003C0A0002D08F830004A1 -:100E10003C02900034420001008220253C02800008 -:100E2000AC4400203C0380008C6200200440FFFEA4 -:100E30000000000003E00008000000003C02800009 -:100E4000344300010083202503E00008AC44002067 -:100E500027BDFFE0AFB10014AFB0001000808821C3 -:100E6000AFBF00180E00035230B000FF8F83FF9C0D -:100E7000022020219062002502028025A07000251A -:100E80008C7000183C0280000E00035D020280247A -:100E90001600000A8FBF00183C0380008C6201F826 -:100EA0000440FFFE24020002AC7101C0A06201C434 -:100EB0003C021000AC6201F88FBF00188FB1001423 -:100EC0008FB0001003E0000827BD002027BDFFE819 -:100ED000AFBF00103C0380009462018430420200E6 -:100EE00010400005000020210E000FDA0000000075 -:100EF0000A000397240400018C6201880440000A60 -:100F00008FBF00108C6201883C03FF000043102457 -:100F10003C03040014430004240400018F82FF9C5E -:100F2000904200088FBF00100080102103E00008ED -:100F300027BD00188F82FFA02403000124050001B3 -:100F4000A040001A8F82FF9CA44300163C02800040 -:100F50000A0003628C4401408F85FF9C27BDFFE09F -:100F6000AFBF001CAFB20018AFB10014AFB000109B -:100F700090A20000304400FF388300203882003007 -:100F80000003182B0002102B0062182410600005CB -:100F90003C02800024020050148200818FBF001C9C -:100FA0003C02800090420148304200FF2443FFFF92 -:100FB0002C6200051040007A8FBF001C00031080D7 -:100FC0003C03080024635210004310218C420000AF -:100FD00000400008000000003C1180008E24014009 -:100FE0000E0003528F92FF9C8E50000C8E22014403 -:100FF0001602000224020001AE42000C0E00035D46 -:101000008E2401408E220144145000068FBF001C24 -:101010008FB200188FB100148FB000100A000F4675 -:1010200027BD00208E42000C0A00042F00000000A3 -:1010300094A200103C0480008C8301443042FFFFE6 -:10104000146200090000000024020001A4A20010A4 -:101050008C820140AC8202003C021000AC8202385B -:101060000A0004368FBF001C94A200100A00042F4F -:1010700000000000240200201482000E3C118000B9 -:1010800094A200123C0380008C6301443042FFFFB5 -:10109000146200050000000024020001A4A2001256 -:1010A0000A0004098FBF001C94A200120A00042F3A -:1010B000000000008E2401400E0003528F92FF9C1E -:1010C000964200128E2301443050FFFF16030002A7 -:1010D00024020001A64200120E00035D8E2401408E -:1010E0008E220144160200068FBF001C8FB200182A -:1010F0008FB100148FB000100A00039B27BD0020A1 -:10110000964200120A00042F0000000094A200146E -:101110003C0380008C6301443042FFFF14620008EE -:101120008FBF001C240200018FB200188FB1001481 -:101130008FB00010A4A200140A00143127BD0020B3 -:1011400094A200140A00042F0000000094A20016CC -:101150003C0380008C6301443042FFFF14620008AE -:10116000240200018FBF001C8FB200188FB1001441 -:101170008FB00010A4A200160A000B0D27BD00209E -:1011800094A20016144000068FBF001C3C02080009 -:101190008C420070244200013C010800AC22007027 -:1011A0008FB200188FB100148FB0001003E0000858 -:1011B00027BD002027BDFFD8AFB200188F92FF9C3B -:1011C000AFB10014AFBF0020AFB3001CAFB0001030 -:1011D0003C028000345101008C500100924200001A -:1011E00092230009304400FF2402001F106200AB6C -:1011F0002862002010400019240200382862000AEA -:101200001040000D2402000B286200081040002E40 -:101210008F82002404600103286200021440002A27 -:101220008F82002424020006106200268FBF002057 -:101230000A0005598FB3001C106200602862000B81 -:10124000144000F98FBF00202402000E10620078C5 -:101250008F8200240A0005598FB3001C106200D150 -:10126000286200391040000A24020080240200365F -:10127000106200E428620037104000C224020035EA -:10128000106200D88FBF00200A0005598FB3001CE0 -:101290001062002D2862008110400006240200C860 -:1012A00024020039106200C88FBF00200A000559CF -:1012B0008FB3001C106200A28FBF00200A000559E6 -:1012C0008FB3001C8F8200248C42000C104000D68B -:1012D0008FBF00200E000D52000000003C03800074 -:1012E000346301008C6200008F8500209467000841 -:1012F0009466000CACA200008C6400048F82002471 -:1013000000063400ACA400049448001E8C6200184F -:1013100000073C0000E83825ACA200088C62001CE5 -:1013200024040001ACA2000C9062000A00C2302527 -:10133000ACA60010ACA00014ACA00018ACA7001C18 -:101340000A0005188FBF00208F8200248C42000CF9 -:10135000104000B58FBF00200E000D5200000000AD -:101360008F820024962400089625000C9443001ECA -:10137000000422029626000E8F8200200004260020 -:101380000083202500052C003C03008000A62825B2 -:1013900000832025AC400000AC400004AC400008B5 -:1013A000AC40000CAC450010AC400014AC40001840 -:1013B000AC44001C0A000517240400019622000C0E -:1013C0001440001800000000924200053042001056 -:1013D00014400014000000000E00035202002021FF -:1013E0009242000502002021344200100E00035DED -:1013F000A24200059242000024030020304200FF78 -:1014000010430088020020218FBF00208FB3001CF2 -:101410008FB200188FB100148FB000100A00104373 -:1014200027BD00280000000D0A0005588FBF0020CE -:101430008C42000C1040007C8FBF00200E000D522B -:10144000000000008E2200048F8400209623000CF0 -:10145000AC8200003C0280089445002C8F8200245E -:1014600000031C0030A5FFFF9446001E3C02400E06 -:101470000065182500C23025AC830004AC8000084C -:10148000AC80000CAC800010AC800014AC80001864 -:10149000AC86001C0A000517240400010E0003524C -:1014A000020020218F93FFA0020020210E00035D87 -:1014B000A660000C020020210E000362240500013A -:1014C0008F8200248C42000C104000578FBF0020F8 -:1014D0000E000D52000000009622000C8F830020A9 -:1014E00000021400AC700000AC620004AC600008A4 -:1014F0008E4400388F820024AC64000C8E46003C81 -:101500009445001E3C02401FAC66001000A2282536 -:101510008E62000424040001AC620014AC60001868 -:10152000AC65001C8FBF00208FB3001C8FB2001869 -:101530008FB100148FB000100A000D8627BD00285F -:1015400024020020108200398FB3001C0E000F2CE3 -:1015500000000000104000348FBF00203C038000DA -:101560008C6201F80440FFFE24020002AC7001C04E -:10157000A06201C43C021000AC6201F80A000558E8 -:101580008FBF0020020020218FBF00208FB3001CDE -:101590008FB200188FB100148FB000100A000E75C2 -:1015A00027BD00289625000C020020218FBF0020B7 -:1015B0008FB3001C8FB200188FB100148FB00010D1 -:1015C0000A000E9A27BD0028020020218FB3001CBC -:1015D0008FB200188FB100148FB000100A000EC532 -:1015E00027BD00289225000D020020218FB3001C8A -:1015F0008FB200188FB100148FB000100A000F16C0 -:1016000027BD0028020020218FBF00208FB3001CBF -:101610008FB200188FB100148FB000100A000EEDC9 -:1016200027BD00288FBF00208FB3001C8FB2001889 -:101630008FB100148FB0001003E0000827BD002810 -:101640003C0380008C6202780440FFFE240200020A -:10165000AC640240A06202443C02100003E00008B7 -:10166000AC620278A380001803E00008A380001990 -:101670003C0380008C6202780440FFFE8F82001CD5 -:10168000AC62024024020002A06202443C0210004C -:1016900003E00008AC6202783C02600003E000084E -:1016A0008C425404908300302402000500804021C5 -:1016B0003063003F00004821146200050000502103 -:1016C0009082004C9483004E304900FF306AFFFF47 -:1016D000AD00000CAD000010AD0000249502001418 -:1016E0008D05001C8D0400183042FFFF00491023B7 -:1016F00000021100000237C3004038210086202379 -:1017000000A2102B0082202300A72823AD05001C77 -:10171000AD040018A5090014A5090020A50A0016AB -:1017200003E00008A50A002203E000080000000012 -:1017300027BDFFD8AFB200183C128008AFB400201C -:10174000AFB3001CAFB10014AFBF0024AFB00010A6 -:10175000365101003C0260008C4254049222000C7D -:101760003C140800929400F7304300FF240200016B -:1017700010620032008098212402000214620035B9 -:10178000365000800E00140B000000009202004C46 -:101790002403FF803C0480003042007F000211C01F -:1017A000244202400262102100431824AC830094BA -:1017B000924500089204004C3042007F3C038006B2 -:1017C00014850007004380212402FFFFA22200119C -:1017D0002402FFFFA62200120A0005CB2402FFFF0D -:1017E00096020020A222001196020022A6220012D8 -:1017F0008E0200243C048008AE2200143485008050 -:1018000090A2004C34830100A06200108CA2003C26 -:10181000AC6200188C820068AC6200E48C820064C8 -:10182000AC6200E08C82006CAC6200E82402000133 -:10183000A0A200680A0005E73C0480080E001424FA -:101840000000000036420080A04000680A0005E762 -:101850003C048008A2000068A20000690A00062279 -:101860003C028008348300808C620038348501009B -:10187000AC62006C24020001A062006990A200C565 -:1018800090830008305100FF3072007F123200193F -:10189000001111C024420240026210212403FF8083 -:1018A000004318243C048000AC8300943042007F45 -:1018B0003C038006004380218E02000C1040000D86 -:1018C000020020210E000577000000002622000102 -:1018D000305100FF9203003C023410260002102B0E -:1018E000000210233063007F022288240A0005F1E1 -:1018F000A203003C3C088008350401008C8200D023 -:1019000035070080ACE2003C8C8200D0AD020000C4 -:1019100090E5004C908600C590E3004C908400C593 -:101920002402FF8000A228243063007F308400FF5F -:1019300000A628250064182A1060000230A500FFC8 -:1019400038A50080A0E5004CA10500093C028008F4 -:101950009043000E344400803C058000A043000A00 -:101960008C8300183C027FFF3442FFFF0062182482 -:10197000AC8300188CA201F80440FFFE00000000B8 -:10198000ACB301C08FBF00248FB400208FB3001C04 -:101990008FB200188FB100148FB000102402000223 -:1019A000A0A201C427BD00283C02100003E00008EB -:1019B000ACA201F890A2000024420001A0A2000005 -:1019C0003C0308008C6300F4304200FF1443000223 -:1019D00000803021A0A0000090A200008F84001C95 -:1019E000000211C0244202402483004000822021D2 -:1019F0002402FF80008220243063007F3C02800AA2 -:101A0000006218213C028000AC44002403E000087E -:101A1000ACC3000094820006908300058C85000C06 -:101A20008C8600108C8700188C88001C8C84002009 -:101A30003C010800A422530E3C010800A023530DD2 -:101A40003C010800AC2553143C010800AC26531897 -:101A50003C010800AC2753203C010800AC2853246B -:101A60003C010800AC24532803E0000800000000FB -:101A70003C028008344201008C4400343C03800066 -:101A800034650400AC6400388C420038AF8500280F -:101A9000AC62003C3C020005AC620030000000007B -:101AA0000000000003E00008000000003C02000607 -:101AB000308400FF008220253C028000AC440030CE -:101AC0000000000000000000000000003C03800057 -:101AD0008C620000304200101040FFFD34620400B0 -:101AE00003E00008AF82002894C200003C08080010 -:101AF000950800CA30E7FFFF00804821010210214D -:101B0000A4C2000094C200003042FFFF00E2102B8C -:101B100054400001A4C7000094A200003C03080048 -:101B20008C6300CC24420001A4A2000094A2000017 -:101B30003042FFFF144300073C0280080107102BCE -:101B4000A4A000005440000101003821A4C70000F7 -:101B50003C028008344601008CC3002894A2000097 -:101B60003C0480003042FFFE000210C000621021E1 -:101B7000AC82003C8C82003C006218231860000498 -:101B8000000000008CC200240A0006B324420001B9 -:101B90008CC20024AC8200383C0200503442001059 -:101BA0003C038000AC620030000000000000000038 -:101BB000000000008C620000304200201040FFFD59 -:101BC0000000000094A200003C04800030420001AC -:101BD000000210C0004410218C430400AD2300001B -:101BE0008C420404AD2200043C02002003E0000803 -:101BF000AC82003027BDFFE0AFB20018AFB10014D7 -:101C0000AFB00010AFBF001C94C2000000C0802124 -:101C10003C120800965200C624420001A6020000B1 -:101C20009603000094E2000000E030211443000518 -:101C30008FB100300E000688024038210A0006EA03 -:101C4000000000008C8300048C82000424420040C9 -:101C500004610007AC8200048C820004044000048C -:101C6000000000008C82000024420001AC820000D1 -:101C7000960200003042FFFF50520001A600000013 -:101C80009622000024420001A62200003C028008A7 -:101C900034420100962300009442003C14430004A7 -:101CA0008FBF001C24020001A62200008FBF001C71 -:101CB0008FB200188FB100148FB0001003E000083D -:101CC00027BD002027BDFFE03C028008AFBF001801 -:101CD000344201008C4800343C0380003469040025 -:101CE000AC6800388C42003830E700FFAF8900282C -:101CF000AC62003C3C020005AC6200300000000019 -:101D000000000000000000000000000000000000D3 -:101D1000000000008C82000C8C82000C978300165F -:101D2000AD2200008C82001000604021AD22000432 -:101D30008C820018AD2200088C82001CAD22000CA1 -:101D40008CA20014AD2200108C820020AD22001461 -:101D500090820005304200FF00021200AD22001800 -:101D60008CA20018AD22001C8CA2000CAD22002019 -:101D70008CA20010AD2200248CA2001CAD220028F1 -:101D80008CA20020AD22002C3402FFFFAD260030D3 -:101D9000AD200034506200013408FFFFAD28003848 -:101DA00050E000113C0280083C04800834840100AB -:101DB000948200503042FFFFAD22003C94830044E7 -:101DC00094850044240200013063FFFF000318C221 -:101DD000006418219064005430A5000700A210048C -:101DE0000A0007550044102534420100AD20003C94 -:101DF00094430044944400443063FFFF000318C23E -:101E0000006218213084000790650054240200010C -:101E1000008210040002102700451024A062005424 -:101E20000000000000000000000000003C0200066E -:101E3000344200403C038000AC62003000000000EF -:101E400000000000000000008C6200003042001022 -:101E50001040FFFD3C06800834C20150346304008A -:101E600034C7014A34C4013434C5014034C6014486 -:101E7000AFA200100E0006CBAF8300288FBF001862 -:101E800003E0000827BD00208F8300143C060800F3 -:101E90008CC600E88F82001C30633FFF000319806E -:101EA00000461021004310212403FF800043182422 -:101EB0003C068000ACC300283042007F3C03800C0D -:101EC0000043302190C2000D30A500FF00003821F2 -:101ED00034420010A0C2000D8F8900143C0280081B -:101EE0003442010094430044000913823048000347 -:101EF00024020001A4C3000E1102000B29020002FB -:101F000010400005240200021100000C240300010F -:101F10000A00079D000018211102000600000000C1 -:101F20000A00079D000018218CC2002C0A00079DA2 -:101F3000244300018CC20014244300018CC2001809 -:101F40000043102B5040000A240700012402002700 -:101F500014A200033C0380080A0007AA240700011A -:101F6000346301009462004C24420001A462004CDE -:101F700000091382304300032C6200021040000964 -:101F800000802821146000040000000094C2003486 -:101F90000A0007BA3046FFFF8CC600380A0007BAAD -:101FA00000802821000030213C04080024845308CC -:101FB0000A0006FF0000000027BDFF90AFB60068D2 -:101FC000AFB50064AFB40060AFB3005CAFB200580F -:101FD000AFB10054AFBF006CAFB000508C900000A8 -:101FE0000080B0213C0208008C4200E896040032D8 -:101FF0008F83001C2414FF8030843FFF006218216F -:102000000004218000641821007410243C13800017 -:1020100000A0902190A50000AE620028920400323A -:102020003C02800C3063007F00628821308400C055 -:1020300024020040148200320000A8218E350038AE -:102040008E2200181440000224020001AE22001863 -:102050009202003C304200201440000E8F83001C8E -:10206000000511C02442024000621821306400784B -:102070003C0200800082202500741824AE63080012 -:10208000AE6408108E2200188E0300080043102151 -:10209000AE2200188E22002C8E230018244200014C -:1020A0000062182B10600043000000009242000004 -:1020B00024420001A24200003C0308008C6300F4AB -:1020C000304200FF50430001A24000009242000055 -:1020D0008F84001C000211C024420240248300406F -:1020E0003063007F008220213C02800A009420247B -:1020F00000621821AE6400240A0008CBAEC30000C1 -:10210000920300322402FFC000431024304200FF3B -:102110001440000524020001AE220018962200346B -:102120000A00083B3055FFFF8E22001424420001B4 -:10213000AE220018920200300002160000021603C0 -:102140000441001C000000009602003227A4001089 -:1021500000802821A7A2001696020032000030213C -:10216000240700013042FFFFAF8200140E0006FF7B -:10217000AFA0001C960200328F83001C3C040800B4 -:102180008C8400E830423FFF000211800064182177 -:102190000062182100741024AE62002C3063007FAE -:1021A0003C02800E006218219062000D3042007FD8 -:1021B000A062000D9222000D3042001050400078C5 -:1021C000924200003C028008344401009482004C9A -:1021D0008EC300003C130800967300C62442FFFF24 -:1021E000A482004C946200329623000E3054FFFF0C -:1021F0003070FFFF3C0308008C6300D000701807AC -:10220000A7A300389482003E3063FFFF3042FFFFF7 -:1022100014620007000000008C8200303C03800044 -:1022200024420030AC62003C0A0008638C82002C1F -:10223000948200403042FFFF5462000927A400400E -:102240008C8200383C03800024420030AC62003CA9 -:102250008C820034AC6200380A0008723C038000B3 -:1022600027A5003827A60048026038210E000688FE -:10227000A7A000488FA300403C02800024630030E8 -:10228000AC4300388FA30044AC43003C3C038000C7 -:102290003C020005AC6200303C028008344401007E -:1022A00094820042346304003042FFFF0202102B8C -:1022B00014400007AF8300289482004E94830042AC -:1022C00002021021004310230A0008883043FFFF58 -:1022D0009483004E94820042026318210050102320 -:1022E000006218233063FFFF3C0280083444010081 -:1022F0009482003C3042FFFF1443000300000000C2 -:102300000A000898240300019482003C3042FFFF39 -:102310000062102B144000058F8200289482003C3C -:10232000006210233043FFFF8F820028AC5500006D -:10233000AC400004AC540008AC43000C3C02000666 -:10234000344200103C038000AC620030000000000A -:1023500000000000000000008C620000304200100D -:102360001040FFFD3C04800834840100001018C2B6 -:102370000064182190650054320200072406000111 -:102380000046100400451025A062005494830042CA -:102390009622000E50430001A386001892420000CE -:1023A00024420001A24200003C0308008C6300F4B8 -:1023B000304200FF50430001A24000009242000062 -:1023C0008F84001C000211C024420240248300407C -:1023D000008220212402FF80008220243063007FBD -:1023E0003C02800A006218213C028000AC440024B8 -:1023F000AEC300008FBF006C8FB600688FB500645D -:102400008FB400608FB3005C8FB200588FB100545E -:102410008FB0005003E0000827BD007027BDFFD833 -:10242000AFB3001CAFB20018AFB10014AFB00010D2 -:10243000AFBF00200080982100E0802130B1FFFF75 -:102440000E000D5230D200FF00000000000000001E -:10245000000000008F8200208F830024AC51000018 -:10246000AC520004AC530008AC40000CAC4000106F -:10247000AC400014AC4000189463001E0203802599 -:10248000AC50001C00000000000000000000000034 -:10249000240400018FBF00208FB3001C8FB20018EE -:1024A0008FB100148FB000100A000D8627BD0028E0 -:1024B00030A5FFFF0A0008D530C600FF3C028008A7 -:1024C000344301009462000E3C080800950800C6E1 -:1024D0003046FFFF14C000043402FFFF946500DAA9 -:1024E0000A0009228F84001C10C20027000000008F -:1024F0009462004E9464003C3045FFFF00A6102318 -:1025000000A6182B3087FFFF106000043044FFFF47 -:1025100000C5102300E210233044FFFF0088102B79 -:102520001040000E00E810233C02800834440100F3 -:102530002403000134420080A44300162402FFFF5C -:10254000A482000E948500DA8F84001C00003021E4 -:1025500030A5FFFF0A0008FA3C0760200044102A5B -:10256000104000093C028008344300809462001649 -:1025700030420001104000043C0280009442007E82 -:1025800024420014A462001603E0000800000000CA -:1025900027BDFFE03C028008AFBF001CAFB00018B1 -:1025A00034420100944300429442004C1040001910 -:1025B0003068FFFF93830018240200011462002991 -:1025C0008FBF001C3C06800834D00100000810C2F8 -:1025D00000501021904200543103000734C70148D5 -:1025E000304200FF006210073042000134C9014E42 -:1025F00034C4012C34C5013E1040001634C60142DB -:102600000E0006CBAFA90010960200420A00093F57 -:102610003048FFFF3C0280083444010094830044AA -:10262000948200421043000F8FBF001C948200442C -:10263000A482004294820050A482004E8C82003812 -:10264000AC82003094820040A482003E9482004A12 -:10265000A48200488FBF001C8FB000180A0008FD3C -:1026600027BD00208FB0001803E0000827BD002020 -:1026700027BDFFA0AFB1004C3C118000AFBF005898 -:10268000AFB30054AFB20050AFB000483626018857 -:1026900090C200033044007FA3A400108E3201805A -:1026A00090C200003043007F240200031062003B10 -:1026B000AF92001C286200041040000624020004AF -:1026C00024020002106200098FBF00580A000B08A4 -:1026D0008FB300541062004D240200051062014EB9 -:1026E0008FBF00580A000B088FB30054000411C0BC -:1026F000024210212404FF8024420240004410249E -:1027000026430040AE2200243063007F3C02800A52 -:10271000006218219062003CAFA3003C00441025E9 -:10272000A062003C8FA3003C9062003C304200401D -:102730001040016C8FBF00583C108008A380001827 -:10274000361001008E0200D08C63003427A4003CB8 -:1027500027A50010004310210E0007BCAE0200D0D8 -:1027600093A200103C038000A20200C58C62027894 -:102770000440FFFE8F82001CAC6202402402000273 -:10278000A06202443C021000AC6202780E000932E2 -:10279000000000000A000B078FBF00583C058008AE -:1027A00090C3000190A2000B1443014E8FBF00584C -:1027B00034A400808C8200189082004C90A2000803 -:1027C0003C0260008C4254048C8300183C027FFF62 -:1027D0003442FFFF006218243C0208008C4200B41F -:1027E000AC8300183C038000244200013C01080037 -:1027F000AC2200B48C6201F80440FFFE8F82001C02 -:10280000AC6201C00A000ACF240200023C1080081A -:1028100090C300019202000B144301328FBF005895 -:1028200027A4001836050110240600033C026000AE -:102830008C4254040E000E150000000027A400284E -:10284000360501E00E000E15240600038FA20028B5 -:1028500036030100AE0200648FA2002CAE020068B5 -:102860008FA20030AE02006C93A40018906300C5E4 -:102870002402FF800082102400431025304900FF0D -:102880003084007F3122007F0082102A54400001F2 -:1028900039290080000411C0244202402403FF8033 -:1028A0000242102100431024AE2200942642004030 -:1028B0003042007F3C038006004340218FA3001C70 -:1028C0002402FFFFAFA800403C130800927300F7FA -:1028D0001062003393A2001995030014304400FFE6 -:1028E0003063FFFF0064182B106000100000000030 -:1028F000950400148D07001C8D0600183084FFFF1E -:10290000004420230004210000E4382100001021AD -:1029100000E4202B00C2302100C43021AD07001C90 -:10292000AD0600180A000A2893A2001995040014A5 -:102930008D07001C8D0600183084FFFF00822023C5 -:1029400000042100000010210080182100C2302363 -:1029500000E4202B00C4302300E33823AD07001C23 -:10296000AD06001893A200198FA30040A4620014C2 -:1029700097A2001AA46200168FA2001CAC6200107D -:102980008FA2001CAC62000C93A20019A46200206C -:1029900097A2001AA46200228FA2001CAC6200243D -:1029A0003C048008348300808C6200388FA20020B1 -:1029B00001208821AC62003C8FA20020AC82000084 -:1029C00093A20018A062004C93A20018A0820009F4 -:1029D000A060006893A20018105100512407FF80E6 -:1029E0003229007F000911C0244202400242102116 -:1029F0003046007F3C03800000471024AC62009406 -:102A00003C02800600C2302190C2003CAFA60040CC -:102A10000000202100471025A0C2003C8FA80040E4 -:102A200095020002950300148D07001C3042FFFF41 -:102A30003063FFFF8D0600180043102300021100D1 -:102A400000E2382100E2102B00C4302100C2302106 -:102A5000AD07001CAD06001895020002A502001487 -:102A6000A50000168D020008AD0200108D020008BE -:102A7000AD02000C95020002A5020020A500002274 -:102A80008D020008AD0200249102003C304200405B -:102A90001040001A262200013C108008A3A900382B -:102AA000A3800018361001008E0200D08D03003480 -:102AB00027A4004027A50038004310210E0007BCC2 -:102AC000AE0200D093A200383C038000A20200C5F1 -:102AD0008C6202780440FFFE8F82001CAC620240D0 -:102AE00024020002A06202443C021000AC620278A0 -:102AF0000E00093200000000262200013043007F52 -:102B000014730004004020212403FF8002231024BA -:102B10000043202693A200180A000A44309100FFC7 -:102B200093A400188FA3001C2402FFFF1062000A68 -:102B3000308900FF24820001248300013042007F9D -:102B400014530005306900FF2403FF800083102424 -:102B500000431026304900FF3C02800890420008E4 -:102B600001208821305000FF123000193222007FEE -:102B7000000211C002421021244202402403FF80BF -:102B8000004318243C048000AC8300943042007F52 -:102B90003C038006004310218C43000C00402021A0 -:102BA0001060000BAFA200400E000577000000008F -:102BB000262300012405FF803062007F14530002A9 -:102BC00002252024008518260A000AA8307100FF7B -:102BD0003C048008348400808C8300183C027FFF12 -:102BE0003442FFFF00621824AC8300183C038000CD -:102BF0008C6201F80440FFFE00000000AC7201C0CE -:102C000024020002A06201C43C021000AC6201F880 -:102C10000A000B078FBF00583C04800890C30001D6 -:102C20009082000B1443002F8FBF00583490008017 -:102C300092020008304200401040002000000000D6 -:102C4000920200080002160000021603044100056B -:102C5000024020210E000E9A240500930A000B0763 -:102C60008FBF00589202000924030018304200FF71 -:102C70001443000D02402021240500390E000E32BD -:102C8000000030210E0003528F84001C8F82FF9CB5 -:102C900024030012A04300090E00035D8F84001C72 -:102CA0000A000B078FBF0058240500360E000E32B5 -:102CB000000030210A000B078FBF00580E0003529E -:102CC00002402021920200058F84001C3442002023 -:102CD0000E00035DA20200050E0010438F84001C4D -:102CE0008FBF00588FB300548FB200508FB1004C8B -:102CF0008FB0004803E0000827BD00603C02800858 -:102D0000344501003C0280008C42014094A3000E37 -:102D10000000302100402021AF82001C3063FFFF03 -:102D20003402FFFF106200063C0760202402FFFF10 -:102D3000A4A2000E94A500DA0A0008FA30A5FFFF4D -:102D400003E000080000000027BDFFC83C0280002F -:102D50003C068008AFB5002CAFB1001CAFBF0030FF -:102D6000AFB40028AFB30024AFB20020AFB000185A -:102D70003451010034C501008C4301008E2200143F -:102D80008CA400D40000A821AF83001C00441023B1 -:102D900018400052A38000188E2200140000502119 -:102DA000ACA200D490C3000890A200C53073007F8D -:102DB000A3A200108CB200D08CB400D4304200FF2B -:102DC0001053003B93A200108F83001C2407FF8048 -:102DD000000211C00062102124420240246300401E -:102DE000004710243063007F3C0980003C08800AC3 -:102DF00000681821AD2200248C62003427A400143E -:102E000027A50010024280210290102304400028D0 -:102E1000AFA300149062003C00E21024304200FF97 -:102E200014400019020090219062003C344200409E -:102E3000A062003C8F86001C93A3001024C20040B7 -:102E40003042007F004828213C0208008C4200F4F8 -:102E500024630001306400FF14820002A3A3001069 -:102E6000A3A0001093A20010AFA50014000211C08F -:102E70002442024000C2102100471024AD22002449 -:102E80000A000B3E93A200100E0007BC00000000D9 -:102E90003C02800834420100AC5000D093A30010E3 -:102EA000240A0001A04300C50A000B3E93A20010B3 -:102EB00024020001154200093C0380008C62027864 -:102EC0000440FFFE8F82001CAC620240240200021C -:102ED000A06202443C021000AC6202789222000B15 -:102EE00024030002304200FF14430072000000007F -:102EF00096220008304300FF240200821462004042 -:102F0000240200843C028000344901008D22000C20 -:102F100095230006000216023063FFFF3045003F94 -:102F20002402002710A2000FAF83001428A200285B -:102F300010400008240200312402002110A20009E0 -:102F40002402002510A20007938200190A000BB684 -:102F50000000000010A20007938200190A000BB6BF -:102F6000000000000E000770012020210A000C362E -:102F7000000000003C0380008C6202780440FFFEE9 -:102F80008F82001CAC62024024020002A062024454 -:102F90003C021000AC6202780A000C36000000000F -:102FA00095230006912400058D25000C8D26001028 -:102FB0008D2700188D28001C8D2900202442000137 -:102FC0003C010800A423530E3C010800A024530D2B -:102FD0003C010800AC2553143C010800AC265318F2 -:102FE0003C010800AC2753203C010800AC285324C6 -:102FF0003C010800AC2953280A000C36A3820019B2 -:103000001462000A240200813C028008344201005C -:10301000944500DA922600058F84001C30A5FFFF3E -:1030200030C600FF0A000BF73C0760211462005C09 -:10303000000000009222000A304300FF30620020AE -:1030400010400007306200403C028008344201001A -:10305000944500DA8F84001C0A000BF5240600401A -:1030600010400007000316003C02800834420100B3 -:10307000944500DA8F84001C0A000BF524060041F9 -:1030800000021603044100463C028008344201005D -:10309000944500DA8F84001C2406004230A5FFFF0F -:1030A0003C0760190E0008FA000000000A000C3608 -:1030B000000000009222000B24040016304200FFA2 -:1030C000104400063C0680009222000B24030017E7 -:1030D000304200FF144300320000000034C50100FC -:1030E00090A2000B304200FF1444000B000080212E -:1030F0008CA200208CA400202403FF800043102415 -:10310000000211403084007F004410253C03200061 -:1031100000431025ACC2083094A20008000214003D -:1031200000021403044200012410000194A20008CC -:10313000304200805040001A0200A82194A20008EA -:1031400030422000504000160200A8218CA3001835 -:103150003C021C2D344219ED106200110200A8211E -:103160003C0208008C4200D4104000053C0280085C -:103170002403000434420100A04300EC3C02800818 -:1031800034420100944500DA8F84001C24060006B6 -:1031900030A5FFFF0E0008FA3C0760210200A821BD -:1031A0000E000932000000009222000A304200089E -:1031B0001040000402A010210E0013470000000080 -:1031C00002A010218FBF00308FB5002C8FB40028D3 -:1031D0008FB300248FB200208FB1001C8FB0001875 -:1031E00003E0000827BD00382402FF80008220246D -:1031F0003C02900034420007008220253C028000FF -:10320000AC4400203C0380008C6200200440FFFEA0 -:103210000000000003E00008000000003C03800004 -:103220002402FF80008220243462000700822025CF -:10323000AC6400208C6200200440FFFE000000000F -:1032400003E00008000000003C02800824030005A1 -:1032500034420100A04300EC3C0280008C4201009B -:103260003C038000AF82001C8C6202780440FFFEA9 -:103270008F82001CAC62024024020002A062024461 -:103280003C021000AC62027803E00008000000007D -:1032900027BDFFE83C068000AFBF001034C7010027 -:1032A00094E20008304400FF3883008238820084B2 -:1032B0002C6300012C420001006218251060002DD3 -:1032C0002402008393820019504000368FBF001003 -:1032D0003C020800904253148CC401003C060800D4 -:1032E00094C6530E3045003F38A3003238A2003F49 -:1032F0002C6300012C42000100621825AF84001CE1 -:10330000AF860014A38000191460000700E020219C -:103310002402002014A20012000000003402FFFF6B -:1033200014C2000F000000002402002014A20005B7 -:1033300000E028218CE300142402FFFF5062000B00 -:103340008FBF00103C040800248453080000302183 -:103350000E0006FF240700010A000CA98FBF001011 -:103360000E000770000000008FBF00100A00093235 -:1033700027BD0018148200062482FF808CC301043C -:103380003C026020AC4300140A000CDF8FBF001029 -:10339000304200FF2C4200021040000424020022B0 -:1033A0008FBF00100A000B2027BD001814820004F4 -:1033B0008F8200248FBF00100A000C6027BD001808 -:1033C0008C42000C1040001E00E0282190E3000910 -:1033D0002402001814620003240200160A000CCA1A -:1033E00024030008146200072402001724030012BB -:1033F0003C02800834420080A04300090A000CD738 -:1034000094A700085462000794A700088F82FF9CCD -:103410002404FFFE9043000500641824A043000527 -:1034200094A7000890A6001B8CA4000094A5000699 -:103430008FBF001000073C000A0008D527BD001808 -:103440008FBF001003E0000827BD00188F850024FF -:103450003C04800094A2002A8CA30034000230C0F7 -:103460002402FFF000C2102400621821AC83003C4B -:103470008CA200303C038000AC8200383C0200503B -:1034800034420010AC620030000000000000000078 -:10349000000000008C620000304200201040FFFD60 -:1034A00030C20008104000063C0280008C62040814 -:1034B000ACA200208C62040C0A000D02ACA2002415 -:1034C0008C430400ACA300208C420404ACA2002472 -:1034D0003C0300203C028000AC4300303C048000F0 -:1034E0008C820030004310241440FFFD8F8600249E -:1034F0003C020040AC82003094C3002A94C20028F1 -:1035000094C4002C94C5002E2463000100441021B3 -:103510003064FFFFA4C2002814850002A4C3002A5F -:10352000A4C0002A03E00008000000008F840024EB -:1035300027BDFFE83C05800424840010AFBF0010C5 -:103540000E000E152406000A8F84002494820012B7 -:103550009483002E3042000F2442000300431804DD -:1035600024027FFF0043102B10400002AC830000B8 -:103570000000000D0E000CE1000000008F8300240D -:103580008FBF001027BD0018946200149463001AC6 -:103590003042000F00021500006218253C02800036 -:1035A00003E00008AC4300A08F8300243C028004A9 -:1035B000944400069462001A8C650000A46400160E -:1035C000004410233042FFFF0045102B03E00008A9 -:1035D000384200018F8400243C0780049486001A3E -:1035E0008C85000094E20006A482001694E3000695 -:1035F00000C310233042FFFF0045102B384200016A -:103600001440FFF8A483001603E000080000000047 -:103610008F8400243C028004944200069483001AA4 -:103620008C850000A4820016006210233042FFFF48 -:103630000045102B384200015040000D8F850024BA -:10364000006030213C07800494E20006A48200164A -:1036500094E3000600C310233042FFFF0045102B07 -:10366000384200011440FFF8A48300168F8500241F -:103670003C038000346204008CA40020AF82002050 -:10368000AC6400388CA20024AC62003C3C02000513 -:10369000AC62003003E00008ACA000048F8400247A -:1036A0003C0300068C8200040002114000431025F8 -:1036B0003C038000AC62003000000000000000000D -:1036C000000000008C620000304200101040FFFD3E -:1036D00034620400AC80000403E00008AF820020E4 -:1036E0008F86002427BDFFE0AFB10014AFB00010FB -:1036F000AFBF00188CC300048CC500248F8200204B -:10370000309000FF94C4001A24630001244200207A -:103710002484000124A70020ACC30004AF82002051 -:10372000A4C4001AACC7002404A10006000088212C -:1037300004E2000594C2001A8CC200202442000159 -:10374000ACC2002094C2001A94C300282E040001C9 -:10375000004310262C420001004410245040000574 -:1037600094C2001A24020001ACC2000894C2001ADC -:1037700094C300280010202B004310262C42000187 -:103780000044102514400007000000008CC200080F -:1037900014400004240200108CC300041462000FC3 -:1037A0008F8500240E000D75241100018F820024E6 -:1037B000944300289442001A1443000300000000C0 -:1037C0000E000CE100000000160000048F850024AC -:1037D0000E000D52000000008F85002494A2001EF0 -:1037E00094A4001C244200013043FFFF1464000233 -:1037F000A4A2001EA4A0001E1200000A3C02800425 -:1038000094A2001494A3001A3042000F0002150085 -:10381000006218253C028000AC4300A00A000DECB9 -:10382000ACA000089442000694A3001A8CA40000E7 -:10383000A4A20016006210233042FFFF0044102BA8 -:10384000384200011040000D02201021006030219C -:103850003C07800494E20006A4A2001694E300064C -:1038600000C310233042FFFF0044102B38420001F8 -:103870001440FFF8A4A30016022010218FBF0018E7 -:103880008FB100148FB0001003E0000827BD0020A6 -:1038900003E00008000000008F82002C3C030006BB -:1038A00000021140004310253C038000AC62003050 -:1038B0000000000000000000000000008C6200001A -:1038C000304200101040FFFD34620400AF82002837 -:1038D00003E00008AF80002C03E000080000102186 -:1038E00003E00008000000003084FFFF30A5FFFF68 -:1038F0000000182110800007000000003082000145 -:103900001040000200042042006518210A000E0B3E -:103910000005284003E000080060102110C00006E8 -:1039200024C6FFFF8CA2000024A50004AC82000086 -:103930000A000E152484000403E0000800000000C3 -:1039400010A0000824A3FFFFAC86000000000000C8 -:10395000000000002402FFFF2463FFFF1462FFFA4F -:103960002484000403E00008000000003C028008FA -:103970003442008024030001AC43000CA443001037 -:10398000A4430012A443001403E00008A44300165B -:103990008F82002427BDFFD8AFB3001CAFB2001840 -:1039A000AFB10014AFB00010AFBF00208C47000CC7 -:1039B000248200802409FF803C08800E3043007F71 -:1039C000008080213C0A80000049202400681821E2 -:1039D00030B100FF30D200FF10E000290000982134 -:1039E00026020100AD44002C004928243042007F0B -:1039F000004820219062000024030050304200FF64 -:103A00001443000400000000AD45002C948200DA4D -:103A10003053FFFF0E000D52000000008F82002483 -:103A20008F83002000112C009442001E00122400FD -:103A30003484000100A228253C02400000A2282571 -:103A4000AC7000008FBF0020AC6000048FB2001883 -:103A5000AC7300088FB10014AC60000C8FB3001C75 -:103A6000AC6400108FB00010AC600014240400019E -:103A7000AC60001827BD00280A000D86AC65001C4C -:103A80008FBF00208FB3001C8FB200188FB10014BD -:103A90008FB0001003E0000827BD00283C0680001E -:103AA00034C201009043000F240200101062000E87 -:103AB0002865001110A0000724020012240200084B -:103AC0002405003A106200060000302103E00008DF -:103AD00000000000240500351462FFFC00003021C6 -:103AE0000A000E32000000008CC200748F83FF9C1D -:103AF00024420FA003E00008AC62000C27BDFFE8E1 -:103B0000AFBF00100E000362240500013C048008D2 -:103B10008FBF00102402000134830080A4620012D1 -:103B200027BD00182402000103E00008A080001A4D -:103B300027BDFFE0AFB20018AFB10014AFB0001066 -:103B4000AFBF001C30B2FFFF0E000352008088217F -:103B50003C028008345000809202000924030004D3 -:103B6000304200FF1443000C3C0280081240000861 -:103B70002402000A0E000E29000000009202000537 -:103B80002403FFFE00431024A202000524020012B9 -:103B9000A20200093C028008344200800220202159 -:103BA0000E00035DA04000271640000302202021E4 -:103BB0000E000E8D0000000002202021324600FF82 -:103BC0008FBF001C8FB200188FB100148FB000108F -:103BD000240500380A000E3227BD002027BDFFE073 -:103BE000AFBF001CAFB20018AFB10014AFB00010EF -:103BF0000E000352008080210E000E2900000000FC -:103C00003C0280083445008090A20009241200186C -:103C1000305100FF12320003020020212402001262 -:103C2000A0A2000990A200052403FFFE0043102477 -:103C30000E00035DA0A20005020020212405002043 -:103C400016320007000030218FBF001C8FB2001811 -:103C50008FB100148FB000100A00036227BD00204E -:103C60008FBF001C8FB200188FB100148FB00010EE -:103C7000240500390A000E3227BD002027BDFFE8C9 -:103C80003C028000AFB00010AFBF0014344201000E -:103C90009442000C2405003600808021144000125C -:103CA000304600FF0E000352000000003C02800876 -:103CB0003442008024030012A04300099043000511 -:103CC000346300100E000E29A04300050E00035DB2 -:103CD00002002021020020210E00036224050020A2 -:103CE0000A000F0A000000000E000E320000000063 -:103CF0000E000352020020213C0280089043001B6A -:103D00002405FF9F02002021006518248FBF0014A6 -:103D10008FB00010A043001B0A00035D27BD0018F0 -:103D200027BDFFE0AFBF0018AFB10014AFB0001067 -:103D300030B100FF0E000352008080213C02800859 -:103D400024030012344200800E000E29A043000913 -:103D50000E00035D020020210200202102203021FC -:103D60008FBF00188FB100148FB0001024050035EC -:103D70000A000E3227BD00203C0480089083000E0C -:103D80009082000A1443000B000028218F82FF9CC0 -:103D9000240300502405000190420000304200FF3F -:103DA00014430004000000009082000E2442000131 -:103DB000A082000E03E0000800A010213C03800058 -:103DC0008C6201F80440FFFE24020002AC6401C0D2 -:103DD000A06201C43C02100003E00008AC6201F8DC -:103DE00027BDFFE0AFB200183C128008AFB100144D -:103DF000AFBF001CAFB00010365100809222000906 -:103E00002403000A304200FF1443003E000000007B -:103E10008E4300048E220038506200808FBF001C49 -:103E20009222000024030050304200FF144300257A -:103E30003C0280008C4201408E4300043642010067 -:103E400002202821AC43001C9622005C8E230038FF -:103E50003042FFFF0002104000621821AE23001C18 -:103E60008E4300048E2400389622005C00641823E0 -:103E70003042FFFF00031843000210400043102AA5 -:103E800010400006000000008E4200048E2300381F -:103E9000004310230A000F78000220439622005CA2 -:103EA0003042FFFF000220403C0280083443010002 -:103EB00034420080ACA4002CA04000242402000165 -:103EC000A062000C0E000F2C0000000010400053F8 -:103ED0008FBF001C3C0280008C4401403C038000EA -:103EE0008C6201F80440FFFE24020002AC6401C0B1 -:103EF000A06201C43C021000AC6201F80A000FD5B8 -:103F00008FBF001C9222000924030010304200FFE2 -:103F1000144300043C0280008C4401400A000FBCA2 -:103F2000000028219222000924030016304200FFDD -:103F30001443000624020014A22200093C0280005F -:103F40008C4401400A000FCF8FBF001C8E22003826 -:103F50008E23003C00431023044100308FBF001C1F -:103F60009222002724420001A22200279222002749 -:103F70002C420004144000163C10800092220009DC -:103F800024030004304200FF144300093C02800077 -:103F90008C4401408FBF001C8FB200188FB10014F9 -:103FA0008FB00010240500930A000E9A27BD002050 -:103FB0008C440140240500938FBF001C8FB2001871 -:103FC0008FB100148FB000100A000F1627BD00201B -:103FD0008E0401400E000352000000008E420004D7 -:103FE0002442FFFFAE4200048E22003C2442FFFF29 -:103FF000AE22003C0E00035D8E0401408E040140A1 -:104000008FBF001C8FB200188FB100148FB000104A -:10401000240500040A00036227BD00208FB20018A7 -:104020008FB100148FB0001003E0000827BD0020FE -:104030003C0680008CC201883C0380083465008007 -:104040009063000E00021402304400FF306300FF52 -:104050001464000E3C02800890A20026304200FF4B -:10406000104400098F82FF9CA0A400262403005066 -:1040700090420000304200FF1443000600000000A0 -:104080000A00059A8CC401803C02800834420080FA -:10409000A044002603E000080000000027BDFFE068 -:1040A00030E700FFAFB20018AFBF001CAFB1001483 -:1040B000AFB000100080902114E0000630C600FF71 -:1040C000000000000000000D000000000A00102E9B -:1040D0002400010E3C0380089062000E304200FF75 -:1040E000144600233462008090420026304200FFD4 -:1040F0001446001F000000009062000F304200FFD5 -:104100001446001B000000009062000A304200FFCD -:10411000144600038F90FF9C0000000D8F90FF9CC1 -:104120008F82FFA03C118000AE05003CAC45000032 -:10413000A066000A0E0003528E240100A200002493 -:104140000E00035D8E2401003C0380008C6201F8A8 -:104150000440FFFE24020002AC7201C0A06201C450 -:104160003C021000AC6201F80A00102F8FBF001C47 -:10417000000000000000000D0000000024000137D6 -:104180008FBF001C8FB200188FB100148FB00010C9 -:1041900003E0000827BD00208F83FF9C3C028000C5 -:1041A0008C440100344201008C65003C9046001BA9 -:1041B0000A000FF5240700013C0280089043000E1E -:1041C0009042000A00431026304200FF03E000083E -:1041D0000002102B27BDFFE03C028008AFB10014A5 -:1041E000AFB00010AFBF001834500080920200053D -:1041F00024030030304200301443008500808821C1 -:104200008F8200248C42000C104000828FBF001867 -:104210000E000D52000000008F860020ACD100007F -:104220009202000892030009304200FF00021200CF -:10423000306300FF00431025ACC200049202004D21 -:1042400000021600000216030441000500000000F1 -:104250003C0308008C6300480A00106D3C10800885 -:104260009202000830420040144000030000182170 -:1042700092020027304300FF3C1080083611008076 -:104280009222004D00031E00304200FF0002140085 -:1042900000621825ACC300088E2400308F820024F1 -:1042A000ACC4000C8E2500349443001E3C02C00BAD -:1042B000ACC50010006218258E22003800002021B5 -:1042C000ACC200148E22003CACC200180E000D8659 -:1042D000ACC3001C8E0200048F8400203C058000CB -:1042E000AC8200008E220020AC8200048E22001CD2 -:1042F000AC8200088E2200588CA300740043102169 -:10430000AC82000C8E22002CAC8200108E22004069 -:104310008E2300440002140000431025AC820014D8 -:104320009222004D24030080304200FF1443000419 -:1043300000000000AC8000180A0010B18F82002439 -:104340008E23000C240200011062000E2402FFFFE5 -:1043500092220008304200401440000A2402FFFF6D -:104360008E23000C8CA20074006218233C0208000B -:10437000006210241440000200002821006028215F -:1043800000051043AC8200188F8200240000202119 -:104390009443001E3C02C00C006218258F8200204E -:1043A0000E000D86AC43001C3C0380083462010003 -:1043B0008C4200008F850020346300808FBF00187E -:1043C000ACA20000ACA000048C6400488F820024E2 -:1043D0008FB10014ACA40008ACA0000CACA000107D -:1043E000906300059446001E3C02400D00031E0031 -:1043F00000C23025ACA300148FB00010ACA0001890 -:1044000024040001ACA6001C0A000D8627BD002074 -:104410008FBF00188FB100148FB0001003E00008A8 -:1044200027BD00203C0280009443007C3C028008B1 -:1044300034460100308400FF3065FFFF2402000590 -:1044400024A34650A0C4000C5482000C3065FFFF2A -:1044500090C2000D2C4200071040000724A30A0060 -:1044600090C3000D240200140062100400A2102169 -:104470000A0010ED3045FFFF3065FFFF3C02800869 -:104480003442008003E00008A44500143C03800887 -:1044900034680080AD050038346701008CE2001CF0 -:1044A000308400FF00A210231840000330C600FF34 -:1044B00024A2FFFCACE2001C308200015040000846 -:1044C0003C0380088D02003C00A21023044100122E -:1044D000240400058C62000410A2000F3C03800835 -:1044E0008C62000414A2001E000000003C020800C0 -:1044F0008C4200D830420020104000093C02800865 -:1045000034620080906300089042004C1443000421 -:104510003C028008240400040A0010D700000000B8 -:104520003443008034420100A040000C240200010A -:10453000A462001410C0000A3C0280008C440100F8 -:104540003C0380008C6201F80440FFFE240200025C -:10455000AC6401C0A06201C43C021000AC6201F86E -:1045600003E000080000000027BDFFE800A61823B4 -:10457000AFBF001018600080308800FF3C02800848 -:1045800034470080A0E0002434440100A0E000276C -:104590008C82001C00A21023044000560000000082 -:1045A0008CE2003C94E3005C8CE4002C004530235A -:1045B0003063FFFF00C318210083202B108000040C -:1045C00000E018218CE2002C0A00114600A2102104 -:1045D00094E2005C3042FFFF00C2102100A21021D3 -:1045E000AC62001C3C028008344400809482005C71 -:1045F0008C83001C3042FFFF0002104000A21021FB -:104600000043102B10400004000000008C82001CAE -:104610000A0011593C0680089482005C3042FFFF7A -:104620000002104000A210213C06800834C30100A3 -:1046300034C70080AC82001CA060000CACE50038E0 -:104640008C62001C00A210231840000224A2FFFC70 -:10465000AC62001C31020001104000083C038008DD -:104660008CE2003C00A21023044100122404000547 -:104670008CC2000410A200108FBF00108C620004D6 -:1046800014A2004F8FBF00103C0208008C4200D8DB -:10469000304200201040000A3C0280083462008052 -:1046A000906300089042004C144300053C028008CF -:1046B000240400048FBF00100A0010D727BD001883 -:1046C0003443008034420100A040000C2402000169 -:1046D000A46200143C0280008C4401003C03800072 -:1046E0008C6201F80440FFFE240200020A0011A6B9 -:1046F000000000008CE2001C004610230043102B39 -:1047000054400001ACE5001C94E2005C3042FFFF25 -:104710000062102B144000072402000294E2005CA7 -:104720008CE3001C3042FFFF00621821ACE3001C48 -:1047300024020002ACE500380E000F2CA082000C11 -:104740001040001F8FBF00103C0280008C4401000D -:104750003C0380008C6201F80440FFFE240200024A -:10476000AC6401C0A06201C43C021000AC6201F85C -:104770000A0011BE8FBF001031020010104000105F -:104780008FBF00103C028008344500808CA3001CC1 -:1047900094A2005C006618233042FFFF00621821DB -:1047A0003C023FFF3444FFFF0083102B54400001C4 -:1047B0000080182100C31021ACA2001C8FBF001084 -:1047C00003E0000827BD001827BDFFE800C0402116 -:1047D00000A63023AFBF001018C00026308A00FFAB -:1047E0003C028008344900808D24001C8D23002C5D -:1047F000008820230064182B1060000F344701004C -:104800008CE2002000461021ACE200208CE2002067 -:104810000044102B1440000B3C023FFF8CE20020B0 -:1048200000441023ACE200209522005C3042FFFFE0 -:104830000A0011DE00822021ACE000200086202149 -:104840003C023FFF3443FFFF0064102B5440000143 -:10485000006020213C02800834420080008518213D -:10486000AC43001CA0400024A04000270A001230E6 -:104870003C03800831420010104000433C03800894 -:104880003C06800834C400808C82003C0048102321 -:104890005840003E3466008090820024244200018B -:1048A000A0820024908200243C0308008C63002432 -:1048B000304200FF0043102B144000688FBF0010EF -:1048C00034C201008C42001C00A210231840006377 -:1048D000000000008CC300049482005C0068182370 -:1048E0003042FFFF00031843000210400043102A2B -:1048F00010400005000000008CC200040048102396 -:104900000A001213000210439482005C3042FFFF41 -:10491000000210403C068008AC82002C34C50080A8 -:1049200094A2005C8CA4002C94A3005C3042FFFF96 -:1049300000021040008220213063FFFF008320210D -:1049400001041021ACA2001C8CC2000434C601007A -:10495000ACC2001C240200020E000F2CA0C2000CEE -:104960001040003E8FBF00103C0280008C440100CC -:104970003C0380008C6201F80440FFFE2402000228 -:104980000A0012600000000034660080ACC50038E8 -:10499000346401008C82001C00A210231840000225 -:1049A00024A2FFFCAC82001C314200015040000AEE -:1049B0003C0380088CC2003C00A210230443001476 -:1049C000240400058C62000414A200033C03800848 -:1049D0000A001252240400058C62000414A2001F75 -:1049E0008FBF00103C0208008C4200D830420020EB -:1049F0001040000A3C028008346200809063000886 -:104A00009042004C144300053C028008240400043A -:104A10008FBF00100A0010D727BD00183443008054 -:104A200034420100A040000C24020001A4620014E2 -:104A30003C0280008C4401003C0380008C6201F841 -:104A40000440FFFE24020002AC6401C0A06201C465 -:104A50003C021000AC6201F88FBF001003E00008B8 -:104A600027BD001827BDFFE83C0A8008AFBF001033 -:104A7000354900808D22003C00C04021308400FF79 -:104A8000004610231840009D30E700FF3547010025 -:104A90002402000100A63023A0E0000CA0E0000DDD -:104AA000A522001418C00024308200108D23001CA1 -:104AB0008D22002C006818230043102B1040000F9B -:104AC000000000008CE2002000461021ACE2002033 -:104AD0008CE200200043102B1440000B3C023FFFEF -:104AE0008CE2002000431023ACE200209522005C01 -:104AF0003042FFFF0A00128F00621821ACE0002054 -:104B0000006618213C023FFF3446FFFF00C3102B14 -:104B10005440000100C018213C028008344200804B -:104B200000651821AC43001CA0400024A0400027D1 -:104B30000A0012DD3C038008104000403C0380085E -:104B40008D22003C004810235840003D346700800F -:104B50009122002424420001A12200249122002459 -:104B60003C0308008C630024304200FF0043102BFC -:104B70001440009A8FBF00108CE2001C00A210238A -:104B800018400096000000008D4300049522005C50 -:104B9000006818233042FFFF000318430002104052 -:104BA0000043102A10400005012020218D420004FE -:104BB000004810230A0012C0000210439522005C36 -:104BC0003042FFFF000210403C068008AC82002CFF -:104BD00034C5008094A2005C8CA4002C94A3005CDB -:104BE0003042FFFF00021040008220213063FFFFAF -:104BF0000083182101031021ACA2001C8CC2000408 -:104C000034C60100ACC2001C240200020E000F2CAE -:104C1000A0C2000C104000718FBF00103C02800049 -:104C20008C4401003C0380008C6201F80440FFFECC -:104C3000240200020A00130700000000346700800D -:104C4000ACE50038346601008CC2001C00A21023C1 -:104C50001840000224A2FFFCACC2001C30820001FC -:104C6000504000083C0380088CE2003C00A2102366 -:104C700004430051240400058C62000410A2003E8D -:104C80003C0380088C62000454A200548FBF0010C3 -:104C90003C0208008C4200D8304200201040000640 -:104CA0003C02800834620080906300089042004C0F -:104CB000104300403C02800834430080344201002D -:104CC000A040000C24020001A46200143C028000F9 -:104CD0008C4401003C0380008C6201F80440FFFE1C -:104CE00024020002AC6401C0A06201C43C021000B6 -:104CF000AC6201F80A0013458FBF001024020005C2 -:104D0000A120002714E2000A3C038008354301007B -:104D10009062000D2C420006504000053C038008C4 -:104D20009062000D24420001A062000D3C03800847 -:104D300034670080ACE50038346601008CC2001C8A -:104D400000A210231840000224A2FFFCACC2001CE9 -:104D5000308200015040000A3C0380088CE2003C95 -:104D600000A2102304410014240400058C620004F6 -:104D700014A200033C0380080A00133C240400052D -:104D80008C62000414A200158FBF00103C020800C2 -:104D90008C4200D8304200201040000A3C028008BB -:104DA00034620080906300089042004C1443000578 -:104DB0003C028008240400048FBF00100A0010D7B2 -:104DC00027BD00183443008034420100A040000C8D -:104DD00024020001A46200148FBF001003E0000849 -:104DE00027BD00183C0B800827BDFFE83C0280006F -:104DF000AFBF001034420100356A00809044000AC1 -:104E0000356901008C4500148D4800389123000C51 -:104E1000308400FF010510231C4000B3306700FF01 -:104E20002CE20006504000B18FBF001024020001A8 -:104E300000E2300430C200035440000800A83023D0 -:104E400030C2000C144000A130C20030144000A356 -:104E50008FBF00100A0014090000000018C00024D1 -:104E6000308200108D43001C8D42002C00681823F6 -:104E70000043102B1040000F000000008D22002086 -:104E800000461021AD2200208D2200200043102B6F -:104E90001440000B3C023FFF8D22002000431023F2 -:104EA000AD2200209542005C3042FFFF0A00137DD6 -:104EB00000621821AD200020006618213C023FFF4F -:104EC0003446FFFF00C3102B5440000100C01821DE -:104ED0003C0280083442008000651821AC43001C6D -:104EE000A0400024A04000270A0013CB3C03800808 -:104EF000104000403C0380088D42003C00481023D5 -:104F00001840003D34670080914200242442000193 -:104F1000A1420024914200243C0308008C63002439 -:104F2000304200FF0043102B144000708FBF001070 -:104F30008D22001C00A210231840006C000000000D -:104F40008D6300049542005C006818233042FFFF27 -:104F500000031843000210400043102A10400005CF -:104F6000014020218D620004004810230A0013AE86 -:104F7000000210439542005C3042FFFF00021040E7 -:104F80003C068008AC82002C34C5008094A2005CF2 -:104F90008CA4002C94A3005C3042FFFF0002104060 -:104FA000008220213063FFFF0083182101031021BC -:104FB000ACA2001C8CC2000434C60100ACC2001CB0 -:104FC000240200020E000F2CA0C2000C104000476B -:104FD0008FBF00103C0280008C4401003C03800025 -:104FE0008C6201F80440FFFE240200020A0013FB59 -:104FF0000000000034670080ACE500383466010032 -:105000008CC2001C00A210231840000224A2FFFC46 -:10501000ACC2001C308200015040000A3C038008F2 -:105020008CE2003C00A21023044300142404000579 -:105030008C62000414A200033C0380080A0013EDF4 -:10504000240400058C62000414A200288FBF001005 -:105050003C0208008C4200D8304200201040000A78 -:105060003C02800834620080906300089042004C4B -:10507000144300053C028008240400048FBF001084 -:105080000A0010D727BD00183443008034420100C5 -:10509000A040000C24020001A46200143C02800025 -:1050A0008C4401003C0380008C6201F80440FFFE48 -:1050B00024020002AC6401C0A06201C43C021000E2 -:1050C000AC6201F80A0014098FBF00108FBF0010F6 -:1050D000010030210A00112827BD001801003021ED -:1050E0000A00126727BD00188FBF001003E00008F8 -:1050F00027BD00183C03800834640100240200032B -:10510000A082000C8C62000403E00008AC82001C4A -:105110003C05800834A300809062002734A501007C -:105120002406004324420001A06200279063002768 -:105130003C0208008C420048306300FF1462000407 -:105140003C07602194A500DA0A0008FA30A5FFFFA9 -:1051500003E000080000000027BDFFE8AFBF00101B -:105160003C0280000E0014128C4401803C02800836 -:1051700034430100A060000C8C4200048FBF00107B -:1051800027BD001803E00008AC62001C27BDFFE04B -:105190003C028008AFBF0018AFB10014AFB00010E0 -:1051A00034450080344601003C0880008D090140F0 -:1051B00090C3000C8CA4003C8CA200381482003BED -:1051C000306700FF9502007C90A30027146000095F -:1051D0003045FFFF2402000554E200083C0480082B -:1051E00090C2000D24420001A0C2000D0A00144D1F -:1051F0003C048008A0C0000D3C04800834820100FB -:105200009042000C24030005304200FF1443000AC2 -:1052100024A205DC34830080906200272C42000722 -:105220005040000524A20A009063002724020014C5 -:105230000062100400A210213C108008361000808B -:105240003045FFFF012020210E001412A605001496 -:105250009602005C8E0300383C1180003042FFFF54 -:105260000002104000621821AE03001C0E00035221 -:105270008E2401409202002534420040A202002503 -:105280000E00035D8E2401408E2401403C0380000B -:105290008C6201F80440FFFE24020002AC6401C0ED -:1052A000A06201C43C021000AC6201F88FBF00187C -:1052B0008FB100148FB0001003E0000827BD00205C -:1052C00080080100800800808008000000000C8039 -:1052D000000032008008024008000F1008000F682C -:1052E00008000FAC0800104408001084800801007A -:0852F000800800808008000026 -:0852F8000A0000220000000082 -:10530000000000000000000D6370352E302E306A62 -:10531000313500000500000400000000000000001E -:1053200000000000000000000000000038003C0009 -:10533000000000000000000000000000000000006D -:10534000000000200000000000000000000000003D -:10535000000000000000000000000000000000004D -:1053600000000000000000000000000021003800E4 -:10537000000000010000002B000000000000000001 -:105380000000000010000003000000000000000DFD -:105390000000000D3C020800244255043C030800B4 -:1053A00024635744AC4000000043202B1480FFFDD1 -:1053B000244200043C1D080037BD9FFC03A0F021DF -:1053C0003C100800261000883C1C0800279C55044F -:1053D0000E00029A000000000000000D00A018213D -:1053E00000801021008028213C0460003C07600000 -:1053F0002406000810600006348420788C420000E7 -:10540000ACE220088C63000003E00008ACE3200C51 -:105410000A000E6000000000240300403C0260000F -:1054200003E00008AC4320003C0760008F860004C6 -:105430008CE520740086102100A2182B1460000750 -:10544000000028218F8AFD9024050001A14400134B -:105450008F89000401244021AF88000403E0000884 -:1054600000A010218F84FD908F850004908600138A -:1054700030C300FF00A31023AF82000403E0000844 -:10548000A08000138F84FD9027BDFFE8AFB000100F -:10549000AFBF0014908900119087001124020028EA -:1054A000312800FF3906002830E300FF2485002C56 -:1054B0002CD00001106200162484001C0E0000395C -:1054C000000000008F8FFD903C0560002402020464 -:1054D00095EE003E95ED003C000E5C0031ACFFFF08 -:1054E000016C5025ACAA20105200000124020004D7 -:1054F000ACA220000000000000000000000000003E -:105500008FBF00148FB0001003E0000827BD001803 -:105510000A000071000028218F85FD9027BDFFD86B -:10552000AFBF0020AFB3001CAFB20018AFB1001482 -:10553000AFB000100080982190A4001124B0001C8E -:1055400024B1002C308300FF386200280E00005B7D -:105550002C5200010E000063000000000200202118 -:105560001240000202202821000028210E000039EC -:10557000000000008F8DFD903C0880003C0560001D -:1055800095AC003E95AB003C02683025000C4C0009 -:10559000316AFFFF012A3825ACA72010240202023D -:1055A000ACA6201452400001240200028FBF00204C -:1055B0008FB3001C8FB200188FB100148FB0001091 -:1055C00027BD002803E00008ACA2200027BDFFE0B3 -:1055D000AFB20018AFB10014AFB00010AFBF001CE5 -:1055E0003C1160008E2320748F82000430D0FFFFB6 -:1055F00030F2FFFF1062000C2406008F0E0000390D -:10560000000000003C06801F0010440034C5FF006D -:105610000112382524040002AE272010000030219A -:10562000AE252014AE2420008FBF001C8FB20018BE -:105630008FB100148FB0001000C0102103E00008EB -:1056400027BD002027BDFFE0AFB0001030D0FFFF26 -:10565000AFBF0018AFB100140E00003930F1FFFFEA -:1056600000102400009180253C036000AC702010E5 -:105670008FBF00188FB100148FB0001024020004F7 -:10568000AC62200027BD002003E0000800001021CC -:1056900027BDFFE83C0B6018AFBF00108D6F5000B6 -:1056A0002418FF7F340C807101F8702435CD380C3C -:1056B000240A00313C098000AD6D50003C08800A8E -:1056C000AD6C53BCAD2A00080E0004D1AF88004079 -:1056D0000E00048F000000000E00004800000000D3 -:1056E0003C0760008CE508082406FFF03C035709DE -:1056F00000A620243462F000108200622419000108 -:10570000AF80004C0E000BF2000000003C0660165B -:105710003C0760148CC400008CE500A03C03FFFF34 -:10572000008310243C1F535300052FC2105F004F0D -:1057300034C77C0094E201F2A780006410400003AB -:10574000A7800074384B1E1EA78B006494E201F8FA -:10575000104000048F8D004C384C1E1EA78C007426 -:105760008F8D004C11A0000497840074240E00203B -:10577000A78E0064978400742C8F008151E0000193 -:1057800024040080978600642CD804015300000193 -:10579000240604003C0260008C4504382419103CA7 -:1057A00030BFFFFF13F900033083FFFF10600018C4 -:1057B00024080050A38000769389007651200019B8 -:1057C000A7840074A7800074978C00748FBF0010AA -:1057D0003C0A600E24EB0388354600100000382197 -:1057E0000000202127BD0018A78000643C010800AC -:1057F000AC2C0080AF8B0010AF860048A780006CF7 -:10580000A780008AAF87001803E00008AF84001467 -:10581000A3880076938900765520FFEBA78000745B -:10582000A7840074978C00748FBF00103C0A600E30 -:1058300024EB0388A7860064000038213546001059 -:105840000000202127BD00183C010800AC2C00807E -:10585000AF8B0010AF860048A780006CA780008A3D -:10586000AF87001803E00008AF84001400055080E3 -:10587000014648218D2800043C0660000A00010F03 -:10588000010638210A000103AF99004C3083FFFF65 -:105890008F8800408F87003C000321403C0580003A -:1058A0003C020050008248253C0660003C0A010092 -:1058B00034AC04008CCD08E001AA58241160000526 -:1058C000000000008CCF08E024E7000101EA702509 -:1058D000ACCE08E08D19001001805821ACB9003819 -:1058E0008D180014ACB8003CACA9003000000000DA -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000003C038000D8 -:105910008C640000308200201040FFFD3C0F6000CE -:105920008DED08E03C0E010001AE18241460FFE18B -:1059300000000000AF87003C03E00008AF8B005080 -:105940008F850040240BFFF03C06800094A7001ACE -:105950008CA9002430ECFFFF000C38C000EB502471 -:10596000012A4021ACC8003C8CA400248CC3003C1C -:105970000083102318400033000000008CAD00208D -:1059800025A200013C0F0050ACC2003835EE0010DB -:105990003C068000ACCE003000000000000000009B -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000003C0480008C99000002 -:1059C000333800201300FFFD30E2000810400017BC -:1059D0003C0980008C880408ACA800108C83040C5F -:1059E000ACA300143C1900203C188000AF19003013 -:1059F00094AE001894AF001C01CF3021A4A600186B -:105A000094AD001A25A70001A4A7001A94AB001AB0 -:105A100094AC001E118B00030000000003E000089E -:105A20000000000003E00008A4A0001A8D2A040072 -:105A3000ACAA00108D240404ACA400140A0001BC1C -:105A40003C1900208CA200200A0001A43C0F005049 -:105A50000A0001920000000027BDFFE8AFBF001060 -:105A60000E0001D6000000008F8900408FBF00109B -:105A70003C038000A520000A9528000A9527000411 -:105A800027BD00183105FFFF30E6000F00061500A6 -:105A900000A2202503E00008AC6400803C0508005B -:105AA0008CA500208F83000C27BDFFE8AFB000104D -:105AB000AFBF001410A300100000802124040001D7 -:105AC0000204300400A6202400C310245044000621 -:105AD00026100001001018802787FD941480000A0A -:105AE00000671821261000012E0900025520FFF33F -:105AF0008F83000CAF85000C8FBF00148FB0001097 -:105B000003E0000827BD00188C6800003C058000F9 -:105B1000ACA800240E0001D8261000013C050800A6 -:105B20008CA500200A0001FD2E09000224050001B9 -:105B3000008518043C0408008C84002027BDFFC8A1 -:105B4000AFBF003400831024AFBE0030AFB7002CCD -:105B5000AFB60028AFB50024AFB40020AFB3001C2F -:105B6000AFB20018AFB1001410400051AFB0001038 -:105B70008F840040948700069488000A00E8302350 -:105B800030D5FFFF12A0004B8FBF0034948B00185C -:105B9000948C000A016C50233142FFFF02A2482B73 -:105BA0001520000202A02021004020212C8F00059A -:105BB00015E0000200809821241300040E00016506 -:105BC000026020218F87004002609021AF80004456 -:105BD00094F4000A026080211260004E3291FFFFAF -:105BE0003C1670003C1440003C1E20003C17600036 -:105BF0008F9900508F380000031618241074004F3E -:105C00000283F82B17E0003600000000107E0047EA -:105C10008F86004414C0003A2403000102031023BD -:105C2000022320213050FFFF1600FFF13091FFFFCB -:105C30008F8700403C1100203C108000AE110030E6 -:105C400094EB000A3C178000024B5021A4EA000AA2 -:105C500094E9000A94E800043123FFFF3106000FA5 -:105C600000062D000065F025AEFE008094F3000ACA -:105C700094F6001812D30036001221408CFF001455 -:105C80008CF4001003E468210000C02101A4782BEB -:105C90000298702101CF6021ACED0014ACEC001033 -:105CA00002B2382330F5FFFF16A0FFB88F84004002 -:105CB0008FBF00348FBE00308FB7002C8FB6002806 -:105CC0008FB500248FB400208FB3001C8FB2001852 -:105CD0008FB100148FB0001003E0000827BD00381A -:105CE0001477FFCC8F8600440E000DC102002021E6 -:105CF000004018218F86004410C0FFC90203102302 -:105D0000027070238F87004001C368210A00028857 -:105D100031B2FFFF8F86004414C0FFC93C11002040 -:105D20003C1080000A000252AE1100300E0003FA4F -:105D3000020020210A00027F0040182102002021D9 -:105D40000E000811022028210A00027F00401821BD -:105D50000E000192000000000A00026B02B238231C -:105D600027BDFFC8AFB7002CAFB60028AFB50024E1 -:105D7000AFB40020AFB3001CAFB20018AFB1001435 -:105D8000AFB00010AFBF00300E0000E624130001DA -:105D90003C047FFF3C0380083C0220003C010800DB -:105DA000AC2000703497FFFF34750080345200033C -:105DB0003C1612C0241400013C1080002411FF8006 -:105DC0000E0001E9000000008F8700488F8B00184B -:105DD0008F8900148CEA00EC8CE800E8014B302B32 -:105DE0000109282300A6102314400006014B1823A4 -:105DF0001440000E3C05800002C3602B1180000B94 -:105E0000000000003C0560008CEE00EC8CED00E82A -:105E10008CA4180CAF8E001804800045AF8D0014C0 -:105E20008F8F0010ADF400003C0580008CBF000097 -:105E30003BF90001333800011700FFE13C0380000B -:105E40008C62010024060C001046000900000000CE -:105E50008C6801002D043080548000103C048000C8 -:105E60008C6901002D2331811060000C3C048000FE -:105E70008CAA010011460004000020218CA601001C -:105E800024C5FF8130A400FF8E0B01000E00020D1F -:105E9000AE0B00240A0002F33C0480008C8E01004B -:105EA000240C0020AC8E002092AD000031A300FF36 -:105EB000106C00232407005010670026000000002B -:105EC0003C0480008C8F010015E0000300000000FE -:105ED000566000143C0440008C8701008C8D01004A -:105EE0000000982100F17024000E594031AC007F71 -:105EF000016C302500D22825AC8508308C8A010041 -:105F00008C83010025490100013110240002F94071 -:105F10003068007F03E8C8250332C025AC980830FC -:105F20003C044000AE0401380A0002B20000000048 -:105F300000973824ACA7180C0A0002CB8F8F0010F2 -:105F40008C8501000E0007C3240400800A0002F3C0 -:105F50003C0480008C8401000E001420000000002E -:105F60000A0002F33C04800000A4102B240300016B -:105F700010400009000030210005284000A4102B2B -:105F800004A00003000318405440FFFC0005284013 -:105F90005060000A0004182B0085382B54E00004E0 -:105FA0000003184200C33025008520230003184257 -:105FB0001460FFF9000528420004182B03E00008D4 -:105FC00000C310213084FFFF30C600FF3C07800073 -:105FD0008CE201B80440FFFE00064C00012430258D -:105FE0003C08200000C820253C031000ACE00180E4 -:105FF000ACE50184ACE4018803E00008ACE301B83F -:106000003C0660008CC5201C2402FFF03083020097 -:10601000308601001060000E00A2282434A5000183 -:106020003087300010E0000530830C0034A50004F8 -:106030003C04600003E00008AC85201C1060FFFDFC -:106040003C04600034A5000803E00008AC85201C77 -:1060500054C0FFF334A500020A00034B3087300020 -:1060600027BDFFE8AFB00010AFBF00143C076000D1 -:10607000240600021080001100A080218F830050B0 -:106080000E0003428C6400188F8200500000202113 -:10609000240600018C45000C0E00033300000000B4 -:1060A0001600000224020003000010218FBF00141C -:1060B0008FB0001003E0000827BD00188CE8201CFA -:1060C0002409FFF001092824ACE5201C8F8700502B -:1060D0000A0003688CE5000C3C02600E0080402141 -:1060E00034460100240900180000000000000000F0 -:1060F000000000003C0A00503C03800035470200CD -:10610000AC68003834640400AC65003CAC67003017 -:106110008C6C0000318B00201160FFFD2407FFFF15 -:106120002403007F8C8D00002463FFFF248400047F -:10613000ACCD00001467FFFB24C600040000000083 -:10614000000000000000000024A402000085282BAD -:106150003C0300203C0E80002529FFFF0105402163 -:10616000ADC300301520FFE00080282103E00008C7 -:10617000000000008F82005027BDFFD8AFB3001C85 -:10618000AFBF0020AFB20018AFB10014AFB0001025 -:1061900094460002008098218C5200182CC3008184 -:1061A0008C4800048C4700088C51000C8C4900106E -:1061B000106000078C4A00142CC4000414800013E3 -:1061C00030EB000730C5000310A0001000000000F5 -:1061D0002410008B02002021022028210E0003330E -:1061E00024060003166000022402000300001021B0 -:1061F0008FBF00208FB3001C8FB200188FB1001426 -:106200008FB0001003E0000827BD00281560FFF1E3 -:106210002410008B3C0C80003C030020241F000154 -:10622000AD830030AF9F004400000000000000007C -:10623000000000002419FFF024D8000F031978246F -:106240003C1000D0AD88003801F0702524CD00034B -:106250003C08600EAD87003C35850400AD8E0030F3 -:10626000000D38823504003C3C0380008C6B00003C -:10627000316200201040FFFD0000000010E0000827 -:1062800024E3FFFF2407FFFF8CA800002463FFFF27 -:1062900024A50004AC8800001467FFFB24840004DC -:1062A0003C04600EAC8600380000000000000000D6 -:1062B000000000003C0700203C0680000120202157 -:1062C00001402821ACC700300E0003780000802177 -:1062D0000E000342024020210A0003B802002021E0 -:1062E00027BDFFE0AFB200183092FFFFAFB100143E -:1062F000AFBF001CAFB000101640000D0000882199 -:106300000A000427022010212405000350850027DD -:106310008CE5000C0000000D262C00013191FFFFE0 -:1063200024EB00200232502B11400019AF8B00509B -:106330008F820044144000168F8700503C06700086 -:106340003C0320008CE5000000A6202414830010EC -:106350008F840058000544023C09800000A9802475 -:106360001480FFE9310600FF2CCA000B1140FFEB3F -:10637000262C0001000668803C0E080025CE52A0A5 -:1063800001AE60218D8B000001600008000000005C -:10639000022010218FBF001C8FB200188FB1001493 -:1063A0008FB0001003E0000827BD00200E0003336B -:1063B000240400841600FFD88F8700500A000408C8 -:1063C000AF800058020028210E00035A2404000167 -:1063D0008F8700500A000408AF820058020028216D -:1063E0000E00035A000020210A0004378F87005056 -:1063F0000E00039F020020218F8700500A0004082E -:10640000AF82005830AFFFFF000F19C03C0480007E -:106410008C9001B80600FFFE3C1920043C181000C7 -:10642000AC830180AC800184AC990188AC9801B840 -:106430000A000409262C000190E2000290FF0003EC -:106440000000202100023A0000FF28252406000851 -:106450000E000333000000001600FFDD24020003DD -:106460008F870050000010210A000408AF820058F6 -:1064700090E50002000020210A00045624060009CD -:1064800094E5000490E9000390E300020005340065 -:106490000009420000C82025008328252406000AA0 -:1064A0000A0004560000202190E50002000020218F -:1064B0000A0004562406000B000449C23127003F9D -:1064C000000443423C028000000820402403168060 -:1064D0002CE60020AC43002C24EAFFE024820001DB -:1064E00014C0000330A900FF00801021314700FFD5 -:1064F000000260803C0D8000240A0001018D2021F3 -:106500003C0B000E00EA2804008B3021112000050E -:10651000000538278CCE000001C5382503E00008AF -:10652000ACC700008CD800000307782403E0000803 -:10653000ACCF000027BDFFE0AFB10014AFB000103A -:10654000AFBF00183C0760008CE408083402F0007C -:106550003C1160003083F000240501C03C04800E33 -:106560000000302110620006241000018CEA0808A7 -:106570003149F0003928E0000008382B000780403E -:106580003C0D0200AE2D0814240C16803C0B80003C -:106590008E2744000E000E6AAD6C002C1200000421 -:1065A0003C02169124050001120500103C023D6CCE -:1065B000345800E0AE3844083C1108008E31007CAD -:1065C0008FBF00183C06600000118540360F168012 -:1065D0008FB100148FB000103C0E020027BD0020C8 -:1065E000ACCF442003E00008ACCE08103C0218DA1F -:1065F000345800E0AE3844083C1108008E31007C6D -:106600008FBF00183C06600000118540360F1680D1 -:106610008FB100148FB000103C0E020027BD002087 -:10662000ACCF442003E00008ACCE08100A00047090 -:10663000240500010A00047000002821240204003F -:10664000A7820024A780001C000020213C0608002F -:1066500024C655A82405FFFF2489000100044080BA -:106660003124FFFF010618212C87002014E0FFFAD7 -:10667000AC65000024040400A7840026A780001E47 -:10668000000020213C06080024C656282405FFFFF0 -:10669000248D00010004608031A4FFFF0186582191 -:1066A0002C8A00201540FFFAAD650000A780002865 -:1066B000A7800020A7800022000020213C060800BF -:1066C00024C656A82405FFFF249900010004C080B9 -:1066D0003324FFFF030678212C8E000415C0FFFA37 -:1066E000ADE500003C0560008CA73D002403E08F71 -:1066F00000E310243446014003E00008ACA63D004E -:106700002487007F000731C224C5FFFF000518C29F -:10671000246400013082FFFF000238C0A7840030EB -:106720003C010800AC270030AF80002C000028217D -:1067300000002021000030212489000100A7282129 -:106740003124FFFF2CA81701110000032C830080C7 -:106750001460FFF924C6000100C02821AF86002C78 -:1067600010C0001DA786002A24CAFFFF000A11429C -:106770003C080800250856A81040000A0000202107 -:10678000004030212407FFFF248E000100046880B0 -:1067900031C4FFFF01A860210086582B1560FFFA65 -:1067A000AD87000030A2001F504000080004308078 -:1067B000240300010043C80400041080004878212D -:1067C0002738FFFF03E00008ADF8000000C82021D3 -:1067D0002405FFFFAC85000003E000080000000076 -:1067E00030A5FFFF30C6FFFF30A8001F00806021EA -:1067F00030E700FF000529420000502110C0001DB5 -:1068000024090001240B000125180001010B2004BC -:10681000330800FF01267826390E00202DED0001F7 -:106820002DC2000101A218251060000D0144502561 -:106830000005C880032C40210100182110E0000F42 -:10684000000A20278D040000008A1825AD030000EF -:1068500024AD0001000040210000502131A5FFFFC0 -:10686000252E000131C9FFFF00C9102B1040FFE7A2 -:106870002518000103E00008000000008D0A000058 -:10688000014440240A000556AC68000027BDFFE81B -:1068900030A5FFFF30C6FFFFAFB00010AFBF001440 -:1068A00030E7FFFF000050213410FFFF000060219F -:1068B00024AF001F00C04821241800012419002023 -:1068C00005E0001601E010210002F943019F682A4B -:1068D0000009702B01AE402411000017000C188035 -:1068E0000064102110E000058C4B000000F840040B -:1068F0000008382301675824000038211540004162 -:1069000000004021556000163169FFFF258B000112 -:10691000316CFFFF05E1FFEC01E0102124A2003EF5 -:106920000002F943019F682A0009702B01AE402440 -:106930001500FFEB000C1880154600053402FFFF20 -:10694000020028210E00053A000038210200102123 -:106950008FBF00148FB0001003E0000827BD00189F -:106960001520000301601821000B1C0224080010F0 -:10697000306A00FF15400005306E000F250D00083D -:1069800000031A0231A800FF306E000F15C0000589 -:10699000307F00032510000400031902320800FFB5 -:1069A000307F000317E0000538690001250200026E -:1069B00000031882304800FF3869000131230001CC -:1069C00010600004310300FF250A0001314800FF78 -:1069D000310300FF000C694001A34021240A00019B -:1069E00010CAFFD53110FFFF246E000131C800FF2F -:1069F0001119FFC638C900012D1F002053E0001CEB -:106A0000258B0001240D00010A0005CD240E002075 -:106A100051460017258B000125090001312800FF90 -:106A20002D09002051200012258B00012543000173 -:106A3000010D5004014B1024250900011440FFF4FE -:106A4000306AFFFF3127FFFF10EE000C2582FFFFA9 -:106A5000304CFFFF000050213410FFFF312800FFB1 -:106A60002D0900205520FFF225430001258B000150 -:106A7000014648260A000587316CFFFF00003821D7 -:106A8000000050210A0005D93410FFFF27BDFFD8B0 -:106A9000AFB0001030F0FFFFAFB10014001039426A -:106AA0003211FFE000071080AFB3001C00B12823B3 -:106AB00030D3FFFFAFB2001830A5FFFF0080902158 -:106AC0000260302100442021AFBF00200E00056588 -:106AD0003207001F022288213403FFFF02402021D9 -:106AE00002002821026030210000382110430009F3 -:106AF0003231FFFF022010218FBF00208FB3001C16 -:106B00008FB200188FB100148FB0001003E000089E -:106B100027BD00280E000565000000000040882108 -:106B2000022010218FBF00208FB3001C8FB20018ED -:106B30008FB100148FB0001003E0000827BD0028BB -:106B4000000424003C036000AC603D0810A000027B -:106B5000348210063482101603E00008AC623D0453 -:106B600027BDFFE0AFB00010309000FF2E020006FE -:106B7000AFBF001810400008AFB100140010308003 -:106B80003C030800246352CC00C328218CA40000DD -:106B90000080000800000000000020218FBF0018C6 -:106BA0008FB100148FB000100080102103E00008A6 -:106BB00027BD00209791002A1620005100002021B7 -:106BC0003C020800904200330A000640000000002A -:106BD000978D002615A00031000020210A000640F4 -:106BE000240200089787002414E0001A00001821EE -:106BF00000602021240200011080FFE98FBF0018EF -:106C0000000429C20045302100A6582B1160FFE482 -:106C10003C0880003C072000000569C001A76025F2 -:106C2000AD0C00203C0380082402001F2442FFFF1B -:106C3000AC6000000441FFFD2463000424A50001B2 -:106C400000A6702B15C0FFF5000569C00A00062AD2 -:106C50008FBF00189787001C3C040800248455A8A7 -:106C6000240504000E0005E524060001978B00248E -:106C700024440001308AFFFF2569FFFF2D480400EE -:106C80000040282115000040A789002424AC3800CA -:106C9000000C19C00A00063EA780001C9787001E42 -:106CA0003C04080024845628240504000E0005E551 -:106CB0002406000197990026244400013098FFFF24 -:106CC000272FFFFF2F0E04000040882115C0002C45 -:106CD000A78F0026A780001E3A0200032624010089 -:106CE0003084FFFF0E0006122C4500010011F8C091 -:106CF00027F00100001021C00A000640240200080D -:106D00009785002E978700223C040800248456A80B -:106D10000E0005E5240600019787002A8F89002CC4 -:106D20002445000130A8FFFF24E3FFFF0109302BB9 -:106D30000040802114C00018A783002AA7800022E9 -:106D4000978500300E000E5402002021244A0500D1 -:106D50003144FFFF0E000612240500013C05080027 -:106D600094A500320E000E5402002021244521007B -:106D70003C020800904200330A000640000521C092 -:106D80000A000678A784001E24AC3800000C19C045 -:106D90000A00063EA784001C0A000692A78500226E -:106DA000308400FF27BDFFE82C820006AFBF00142F -:106DB000AFB000101040001500A038210004408042 -:106DC0003C030800246352E4010328218CA4000042 -:106DD000008000080000000024CC007F000751C2A2 -:106DE000000C59C23170FFFF2547C40030E5FFFF9A -:106DF0002784001C020030210E00053A2407000100 -:106E00009786002802062021A78400288FBF00143F -:106E10008FB0001003E0000827BD00183C050800F3 -:106E20008CA50030000779C20E00031C25E4DF00AA -:106E30003045FFFF3C040800248456A824060001C6 -:106E40000E00053A24070001978E002A8FBF001418 -:106E50008FB0001025CD000127BD001803E0000809 -:106E6000A78D002A0007C9C22738FF00001878C282 -:106E700031F0FFFF3C04080024845628020028213A -:106E8000240600010E00053A24070001978D002614 -:106E9000260E0100000E840025AC00013C0B6000B2 -:106EA000A78C0026AD603D083604000600003021A6 -:106EB0003C0760008CE23D04305F000617E0FFFDF8 -:106EC00024C9000100061B00312600FF0064402594 -:106ED0002CC50004ACE83D0414A0FFF68FBF0014DD -:106EE0008FB0001003E0000827BD0018000751C252 -:106EF0002549C80024060001240700013C040800BD -:106F0000248455A80E00053A3125FFFF97870024F9 -:106F10008FBF00148FB0001024E6000127BD0018B9 -:106F200003E00008A78600243084FFFF30A5FFFFA0 -:106F30003C0680008CC201B80440FFFE3C08408043 -:106F4000008838253C031000ACC00180ACC501842A -:106F5000ACC7018803E00008ACC301B83084FFFF70 -:106F60003C0680008CC201B80440FFFE3C0840385B -:106F70008CA70000008828253C031000ACC70180C6 -:106F8000ACC5018803E00008ACC301B88F83007072 -:106F90008F8600681066000B008040213C070800C7 -:106FA00024E756B8000328C000A710218C44000035 -:106FB00024630001108800053063000F5466FFFA57 -:106FC000000328C003E00008000010213C0708006F -:106FD00024E756BC00A7302103E000088CC2000063 -:106FE0003C03900034620001008220253C038000B5 -:106FF000AC6400208C65002004A0FFFE00000000AF -:1070000003E00008000000003C028000344300015F -:107010000083202503E00008AC44002027BDFFE0EA -:10702000AFB100143091FFFFAFB00010AFBF001838 -:107030001220001200A080218CA5000014A00011D5 -:10704000240400023C0680008CC201B80440FFFE0C -:107050003C074000022720258FBF00188FB1001485 -:107060008FB000103C03100027BD0020ACC501808C -:10707000ACC4018803E00008ACC301B80A000753A0 -:107080008CA500000E0006AA24060200000028219C -:107090000A000753AE0000003087FFFF3C06800067 -:1070A0008CC201B80440FFFE3C0A40068CA90000D7 -:1070B00000EA4025ACC901808CA400043C03100008 -:1070C000ACC40184ACC8018803E00008ACC301B8BB -:1070D0008F83FD8C27BDFFE8AFBF0014AFB0001059 -:1070E00090670008008010210080282130E60040D1 -:1070F0000000202110C000088C5000000E00008805 -:1071000002002021020020218FBF00148FB0001048 -:107110000A0004CD27BD00180E000768000000001B -:107120000E00008802002021020020218FBF0014E1 -:107130008FB000100A0004CD27BD001827BDFFE066 -:10714000AFB000108F90FD8CAFBF001CAFB2001825 -:10715000AFB1001492060001008088210E00073AAA -:1071600030D2000492040005001129C2A6050000D7 -:1071700034830040A20300050E00074402202021B2 -:107180000E0004CF0220202124020001AE02000CD8 -:1071900002202821A602001024040002A6020012E8 -:1071A00024060200A60200140E0006AAA60200167B -:1071B0001640000F8FBF001C978C006C3C0B080022 -:1071C0008D6B00782588FFFF3109FFFF256A0001DC -:1071D000012A382B10E00006A788006C3C0F6006DF -:1071E000240E001635ED0010ADAE00508FBF001C10 -:1071F0008FB200188FB100148FB0001003E00008A8 -:1072000027BD002027BDFFE0AFB10014AFBF0018BD -:10721000AFB000101080000400A08821240200807C -:1072200010820007000000000000000D8FBF001852 -:107230008FB100148FB0001003E0000827BD0020BC -:107240000E00073A00A020218F86FD8C022020210D -:1072500090C500050E00074430B000FF2403003E37 -:107260001603FFF1000000003C0580008CA40178AB -:107270000480FFFE240800073C071000ACB1014069 -:1072800002202021A0A801448FBF00188FB1001454 -:107290008FB00010ACA701780A00079127BD00202D -:1072A00027BDFFE0AFB00010AFBF0018AFB10014B2 -:1072B0003C1080008E110020000000000E0004CF62 -:1072C000AE040020AE1100208FBF00188FB1001453 -:1072D0008FB0001003E0000827BD00203084FFFFBE -:1072E0003C0680008CC201B80440FFFE3C084035DB -:1072F000008838253C031000ACC50180ACC0018477 -:10730000ACC7018803E00008ACC301B83084FFFFBC -:107310003C0680008CC201B80440FFFE3C084036A9 -:10732000008838253C031000ACC50180ACC0018446 -:10733000ACC7018803E00008ACC301B827BDFFD08B -:10734000AFB500243095FFFFAFB60028AFB40020E2 -:10735000AFBF002CAFB3001CAFB20018AFB1001428 -:10736000AFB0001030B6FFFF12A000270000A02130 -:107370008F9200508E4300003C06800024020040A3 -:1073800000033E0200032C0230E4007F00669824D4 -:107390001482001D30A500FF8F8300602C68000A56 -:1073A000510000108F860044000358803C0C0800F8 -:1073B000258C5300016C50218D49000001200008EC -:1073C0000000000002D4702131C5FFFF0E00070C41 -:1073D00024040084166000028F920050AF80006089 -:1073E0008F860044264F00202689000101E090216D -:1073F0003134FFFF14C00004AF8F00500295282BDA -:1074000014A0FFDC00000000028010218FBF002CC0 -:107410008FB600288FB500248FB400208FB3001CD6 -:107420008FB200188FB100148FB0001003E0000875 -:1074300027BD00302407003414A7014600000000D7 -:107440009247000E8F98FD908F90FD8C240F1600B0 -:10745000A30700199244000D3C0880003C07800CF3 -:10746000A3040018965F00123C0960003C117FFFE6 -:10747000A61F005C965900103622FFFF2404000569 -:107480003325FFFFAE0500548E46001CAD0F0028CB -:107490008CEE00008D2D444801C6182601A3302132 -:1074A000AE0600388E0C003824CA00013C0D7F0067 -:1074B000AE0C003C8E0B003CAF0B0004AE0A00206B -:1074C0008E130020AE13001CA300001BAE02002C84 -:1074D000A30400128E5F001424130050AE1F00346A -:1074E0008E190034AF1900148E450018AE050048FF -:1074F000924F000CA20F004E92090008352E00207A -:10750000A20E00088E030018006D6024358B400029 -:10751000AE0B0018920A0000315200FF125302A66F -:107520002413FF803C040800248457380E0007769B -:1075300000000000240C0004240800013C050800A1 -:107540008CA557383C048000A20C0025A208000539 -:107550008C9001780600FFFE8F920050240D0002EF -:107560003C031000AC850140A08D0144AC83017840 -:107570000A00083AAF8000602CAD003711A0FF99D7 -:107580008F860044000580803C1108002631532876 -:10759000021178218DEE000001C0000800000000FB -:1075A0002410000414B0008E3C0780003C0B08003F -:1075B0008D6B57388F86FD8CACEB00208E43000816 -:1075C0008F8FFD90240E0050ACC300308E4A00080F -:1075D000ACCA00508E42000CACC200348E44001085 -:1075E000ACC400388E5F0010ACDF00548E5900141C -:1075F000ACD9003C8E580018ADF800048E51001C28 -:10760000ACD1002090C5000030A900FF112E0276F9 -:10761000000000008CC500348CD1003000B1302354 -:1076200004C000F32404008C126000F02402000364 -:107630000A00083AAF820060240F000514AF00680A -:107640003C0B80003C0308008C6357388F86FD8C10 -:10765000AD6300208E4A00048F99FD90240720001E -:10766000ACCA001C9242000824120008A322001990 -:107670008F840050909F0009A33F00188F85005011 -:1076800090B8000A330400FF10920010288C000903 -:10769000158000BC24080002240E0020108E000B70 -:1076A00034078000288900211520000824074000A5 -:1076B00024110040109100053C070001240F0080B8 -:1076C000108F00023C070002240740008CDF0018E6 -:1076D0003C04FF0003E4C8240327C025ACD80018ED -:1076E00090B2000BA0D200278F8300509465000C4D -:1076F00010A0022A000000009467000C3C198000D2 -:10770000240BFFBFA4C7005C9062000E2407000496 -:10771000A0C200088F840050909F000FA0DF0009D6 -:107720008F8C00508D9200108F38007402582823DF -:10773000ACC500588D8F0014ACCF002C959100186B -:107740003229FFFFACC90040958E001A31D0FFFFEF -:10775000ACD000448D8D001CACCD00489588000253 -:10776000A4C800789183000EA0C3000890CA000846 -:10777000014B1024126001D4A0C200088F92005067 -:107780000A00083AAF8700602406000614A6001419 -:107790003C0D80003C1008008E1057388F8CFD88FF -:1077A000ADB000208E4800188F86FD8C8F8AFD902A -:1077B000AD8800008CC3003824040005AD830004AC -:1077C0008CCB003C12600081AD4B00000A00083AEF -:1077D000AF840060240E000710AE004B24040006A6 -:1077E0003C05080024A557380E00074924040081F1 -:1077F0008F9200500013102B0A00083AAF820060ED -:107800002419002314B9FFF63C0B80003C0C08003F -:107810008D8C57388F8AFD90AD6C00208F91FD8C38 -:107820008E4600042544002026450014AE2600287C -:10783000240600030E000E60255000308F87005094 -:1078400002002021240600030E000E6024E500083B -:107850003C040800248457380E000776000000001E -:1078600092220000241F0050304400FF549FFFE18B -:107870008F9200500E000E4B000000000A00093FDE -:107880008F9200502403003314A300323C02800086 -:107890003C1108008E3157388F8EFD90AC5100207E -:1078A0008E440008240900288F88FD8CADC4003068 -:1078B0008E5F000C24060009ADDF00348E590010E5 -:1078C000ADD900388E580014ADD800208E45001870 -:1078D000ADC500248E4F001CADCF0028A1C90011FA -:1078E0008E4D000412600031AD0D00288F920050C3 -:1078F0000A00083AAF8600602409002214A9FFB8E4 -:1079000000000000240400073C0F08008DEF5738EA -:107910003C118000AE2F00205660FEB1AF840060A5 -:107920003C040800248457380E00077624130050C6 -:107930008F98FD8C93120000324500FF10B301694F -:10794000000000008F920050000020210A00083A39 -:10795000AF8400603C05080024A557380E000719C5 -:10796000240400810A00093F8F92005002D498211C -:107970003265FFFF0E00070C240400840A00083A59 -:107980008F9200501088FF512407040028870003BD -:1079900010E001A324100004240D0001548DFF4BBE -:1079A000240740000A0008F5240701003C050800F0 -:1079B00024A557380E000768240400828F920050D7 -:1079C000000030210A00083AAF8600603C0408003D -:1079D000248457388CC200380E0007768CC3003CD4 -:1079E0008F9200500A000995000020212404008293 -:1079F0003C05080024A557380E0007680000000069 -:107A00008F920050000010210A00083AAF820060F7 -:107A10008E5000048F91FD8C3C0A8000AD500020F8 -:107A200092220005020028213046000214C0018085 -:107A30002404008A8F92FD90020028212404008DE6 -:107A4000924B001B3163002014600179000000009C -:107A5000922D0009240C001231A800FF110C0174B2 -:107A6000240400810E00073A020020219245001BE9 -:107A7000240E00040200202134A90042A249001B68 -:107A80000E000744A22E00253C0480008C91017852 -:107A90000620FFFE24180002AC900140A09801448B -:107AA0008F9200503C0F1000AC8F01780A00094003 -:107AB0000013102B8E5000048F91FD8C3C1F800012 -:107AC000AFF0002092390005020028213327000280 -:107AD00014E000172404008A9224000924120004F0 -:107AE00002002821308600FF10D2001124040081FA -:107AF0000E00073A020020218F8CFD90240B00120B -:107B00002403FFFE918D001B0200202135A80020D8 -:107B1000A188001BA22B0009922A00050143102412 -:107B20000E000744A22200050200282100002021A7 -:107B30000E000805000000000A00093F8F92005067 -:107B40008E5100043C0280003C100800261057387B -:107B5000AC5100203C010800AC315738924600037C -:107B600030C40004108001658F84FD8C240200065F -:107B7000A0820009924D001B2408FFC031AC003FD9 -:107B800001885825A08B000892430003306A000149 -:107B90001540015C000000008E420008AE020008A3 -:107BA0003C0208008C4257401040015B8F8EFD90D4 -:107BB000000281C28F85FD8CA5D0000C8E5F000C69 -:107BC000240F000124090014ADDF002C8E59001091 -:107BD000ADD9001C96470016A5C7003C9658001466 -:107BE000A5D8003EACAF000CA4AF0010A4AF0012AB -:107BF000A4AF0014A4AF00161260015FA1C9001168 -:107C000092440003309200022E5300018F920050E4 -:107C1000266200080A00083AAF8200608E4600041F -:107C20003C0580003C048008ACA600208E4700087C -:107C30009089000024110050312200FF105100B83B -:107C4000240500883C0480008C8F01B805E0FFFE0D -:107C50000013802B3C18400900B81025AF9000603D -:107C60003C101000AC860180AC870184AC82018896 -:107C7000AC9001B80A00083B8F8600448E45000492 -:107C80003C0680003C098008ACC50020913F000004 -:107C90002404005033F900FF132400B024060088A8 -:107CA0003C0480008C8A01B80540FFFE3C0E400E6B -:107CB00000CE68253C081000AC850180AC800184B2 -:107CC000AC8D0188AC8801B8912B0000240CFF809A -:107CD00024040004016C1825240600300E0006AAB6 -:107CE000A12300000A00093F8F9200508E5000042B -:107CF0008F91FD903C0F8000ADF000209225001B7D -:107D000030A900101120007C240300813C04800075 -:107D10008C8701B804E0FFFE3C1F401FAC9001803F -:107D2000007F10250013C82B3C101000AC8001848C -:107D3000AF990060AC820188AC9001B80A00083BA2 -:107D40008F8600448E44001C0E00072500000000B2 -:107D5000104000F8004038218F920050240600891E -:107D60003C0580008CAE01B805C0FFFE000000009D -:107D7000ACA701808E50001C3C1140010013782BF1 -:107D800000D138253C131000ACB00184AF8F0060E7 -:107D9000ACA70188ACB301B80A00083B8F86004449 -:107DA000965900023C10080026105738333800045A -:107DB000130000A33C0460008E5F001C3C068000A2 -:107DC000ACDF00203C010800AC3F5738964F000262 -:107DD00031E7000114E000E3000000008E420004DF -:107DE000AE0200083C1008008E105740120000D967 -:107DF0003C0680008F85FD8C241000018CBF00188C -:107E00008F91FD908F89FD8803E6C825ACB90018D5 -:107E1000A0A00005ACB0000C3C1808008F1857401B -:107E20008F870050A4B00010001879C2A4B00012CF -:107E3000A4B00014A4B00016A62F000C8CEE00080D -:107E40008F8D00508F8C0050AE2E002C8DA8000C12 -:107E500024070002AE28001C918B0010A22B0011F9 -:107E60008F830050906A0011A12A00088F82005071 -:107E700090440012A0A4004E8F920050924600132E -:107E8000A22600128F920050965F0014A63F003C7D -:107E900096590016A639003E8E580018AE380014C8 -:107EA0005660FD4FAF8700603C05080024A5573899 -:107EB0000E000749000020218F9200500000382159 -:107EC0000A00083AAF8700603C05080024A557382F -:107ED0000E000768240400828F9200500A000922D5 -:107EE000000038210E000E4B000000008F92005061 -:107EF0000A000995000020210E00073A0200202107 -:107F00009232001B02002021365800100E00074458 -:107F1000A238001B8F9200500A000A850000182129 -:107F20009243000C306A0001114000030000000081 -:107F3000964B000EA48B002C9248000C310C0002D2 -:107F40001180FF4000002821964E00128E4D001433 -:107F5000A48E001A0A000A53AC8D001C8F83007097 -:107F60008F8700681067FF4E000030213C08080032 -:107F7000250856BC000320C0008830218CD10000A9 -:107F8000122500C8246200013043000F1467FFFA75 -:107F9000000320C00A000A6A000030213C050800E6 -:107FA00024A557380E0007682404008B8F920050D8 -:107FB0000A0009220013382B3C0B08008D6B573840 -:107FC00024D8FFFE25710100322A007F014790214D -:107FD00002331024AD020028AE4600D0AE4000D4DB -:107FE0000A00088BAE58001CACC000543C0E0800C0 -:107FF0008DCE57383C09800C352C0100ACEE0028A2 -:108000008E500014AD9000D08E4D0014AD8D00D474 -:108010008E4800102507FFFE0A0008C7AD87001C28 -:108020005490FDAA240740000A0008F52407100018 -:108030000E0007F9000000000A00093F8F9200506F -:108040008C83442C3C05DEAD34B2BEEF3C0108000D -:10805000AC20573810720090000000003C046C62A5 -:10806000348279701462000824040002978A006C3C -:1080700097830064020028210143482B1120001936 -:1080800024040092240400020E00061A24050200B3 -:108090003C0B8000AD6200203C010800AC22573848 -:1080A0001040000D8F8E0050240C00282404000383 -:1080B00091CD001031A800FF550C000124040001EF -:1080C0000E00004C00000000104000042404008357 -:1080D0000A000AB58F920050240400833C05080072 -:1080E00024A557380E000749000000008F92005069 -:1080F0000013382B0A00083AAF8700600A000A1EF6 -:10810000240200128E4400080E0007250000000023 -:108110000A000A2AAE0200083C05080024A55738C8 -:108120000E000719240400878F9200500A000A47A6 -:108130000013102B240400040E00061A240500303E -:1081400014400014004038218F9200500A000A9A0F -:10815000240600833C05080024A557380A000B7B41 -:10816000240400878E4400040E0007250000000050 -:108170000A000ABBAE0200083C05080024A55738D7 -:108180000E000768240400828F9200500A000A47FC -:10819000000010218F9200503C0880083C0C8000A9 -:1081A000240B0050240A0001AD820020A10B000026 -:1081B000A10A000192490004A10900189244000597 -:1081C000A1040019924300063C040800248456BC14 -:1081D000A103001A924200073C030800246356B82A -:1081E000A102001B92450008A105001C924600094F -:1081F000A106001D925F000AA11F001E9259000BEC -:10820000A119001F9258000CA11800209251000DD6 -:10821000A11100219250000EA1100022924F000FD8 -:10822000A10F0023924E0010A10E0024924D0011C8 -:10823000A10D0025964C0014A50C0028964B0016A5 -:108240008F8A00688F980070A50B002A9649001845 -:10825000000A10C025450001A509002C8E46001C0F -:108260000044C8210043F82130A5000FAFE600000C -:10827000AF27000010B80003AF8500680A000A9A13 -:108280000000302124AD000131A8000F0000302192 -:108290000A000A9AAF8800708C83442C0A000B5A9B -:1082A0003C046C623C07080024E756B80087902124 -:1082B000ACC00000000030210A000A6AAE40000095 -:1082C0003C0482013C03600034820E02AC603D68D5 -:1082D000AF80009003E00008AC623D6C27BDFFE872 -:1082E000AFB000103090FFFF001018422C62004128 -:1082F000AFBF001414400002240400802403004097 -:108300003C010800AC3000603C010800AC23006474 -:108310000E000E5400602821244802BF2409FF806B -:108320000109282400103980001030408FBF00144C -:108330008FB0001000A7202100861821AF8300789D -:108340003C010800AC2500583C010800AC24005C4E -:1083500003E0000827BD0018308300FF30C6FFFF90 -:1083600030E400FF3C0880008D0201B80440FFFEAD -:1083700000035400014438253C09600000E9202531 -:108380003C031000AD050180AD060184AD040188F9 -:1083900003E00008AD0301B88F8600503C0960126D -:1083A000352700108CCB00043C0C600E3585001086 -:1083B000316A00062D480001ACE800C48CC40004FA -:1083C000ACA431808CC2000894C30002ACA23184FA -:1083D00003E00008A78300888F8500508F87FF186F -:1083E0008F86FF208CAE00043C0F601235E8001031 -:1083F000ACEE00688CAD0008ACED006C8CAC0010ED -:10840000ACCC004C8CAB000CACCB004894CA0054F4 -:108410003C0208008C42004425490001A4C90054D4 -:1084200094C400543083FFFF106200170000000066 -:108430003C0208008C420040A4C200528CA30018E9 -:10844000ACE300308CA20014ACE2002C8CB9001814 -:10845000ACF900388CB8001424050001ACF80034E5 -:108460008D0600BC50C500198D0200B48D0200B805 -:10847000A4E2004894E40048A4E4004A94E800DA46 -:1084800003E000083102FFFF3C0208008C42002498 -:10849000A4C00054A4C200528CA30018ACE3003066 -:1084A0008CA20014ACE2002C8CB90018ACF9003896 -:1084B0008CB8001424050001ACF800348D0600BC13 -:1084C00054C5FFEB8D0200B88D0200B4A4E2004851 -:1084D00094E40048A4E4004A94E800DA03E00008C9 -:1084E0003102FFFF8F8600503C0480008CC90008D9 -:1084F0008CC80008000929C0000839C0AC870020DA -:1085000090C30007306200041040003AAF85008C31 -:1085100090CB0007316A0008114000398F87FF1C9B -:108520008CCD000C8CCE001401AE602B118000327B -:10853000000000008CC2000CACE200708CCB001874 -:108540008F85FF188F88FF20ACEB00748CCA001059 -:108550002402FFF8ACAA00C88CC9000CAD09006069 -:108560008CC4001CACA400C090E3007C0062C82452 -:10857000A0F9007C90D80007330F000811E0000438 -:108580000000000090ED007C35AC0001A0EC007C08 -:1085900090CF000731EE000111C00009000000007B -:1085A00090E4007C2418000234820002A0E2007CE7 -:1085B00090A300EC307900FF133800132408003436 -:1085C00090C900073126000210C00004000000001E -:1085D00090EB007C356A0004A0EA007C90ED007D01 -:1085E00031AC003FA0EC007D94A700DA03E0000866 -:1085F00030E2FFFF8F87FF1C0A000C908CC2001432 -:108600000A000C91ACE000700A000CB2ACA800CCDF -:108610008F8C005027BDFFD8AFB3001CAFB200183D -:10862000AFB00010AFBF0020AFB10014918F0015A4 -:108630003C13600E3673001031EB000FA38B0094D7 -:108640008D8F00048D8B0008959F00129599001066 -:108650009584001A9598001E958E001C33EDFFFF3F -:10866000332AFFFF3089FFFF3308FFFF31C7FFFFC9 -:108670003C010800AC2D00243C010800AC2900445A -:108680003C010800AC2A0040AE683178AE67317C0E -:1086900091850015959100163C126012365200101B -:1086A00030A200FF3230FFFFAE623188AE5000B41E -:1086B00091830014959F0018240600010066C804E9 -:1086C00033F8FFFFAE5900B8AE5800BC918E0014CD -:1086D000AF8F007C3C08600631CD00FFAE4D00C07E -:1086E000918A00159584000E3C07600A314900FF0D -:1086F000AF8B00803084FFFFAE4900C835110010F9 -:108700000E000BF934F004103C0208008C420060AB -:108710003C0308008C6300643C0608008CC60058CB -:108720003C0508008CA5005C8F8400788FBF00207A -:10873000AE23004CAE65319CAE030054AE4500DC68 -:10874000AE6231A0AE6331A4AE663198AE2200486D -:108750008FB3001CAE0200508FB10014AE4200E097 -:10876000AE4300E4AE4600D88FB000108FB20018C0 -:108770000A00050227BD00289785008A97830074A8 -:1087800027BDFFE8AFB0001000A3102BAFBF00144F -:10879000240400058F900050104000552409000269 -:1087A0000E00061A8F850078AF82008C2404000327 -:1087B0001040004F240900023C0680000E00004CCF -:1087C000ACC2002024070001240820001040004D06 -:1087D00024040005978E008A8F8AFF1C240900500C -:1087E00025C50001A785008AA14900003C0D0800AD -:1087F0008DAD0064240380008F84FF18000D660097 -:10880000AD4C0018A5400006954B000A8F85FF204F -:108810002402FF8001633024A546000A915F000A0C -:108820000000482103E2C825A159000AA0A00008C1 -:10883000A140004CA08000C59618000297830088D4 -:108840003C020004A49800DA960F00022418FFBF2F -:1088500025EE2401A48E00AE8E0D0004ACAD0044C4 -:108860008E0C0008ACAC0040A4A00050A4A00054A2 -:108870008E0B000C240C0030AC8B00288E060010F0 -:10888000AC860024A480003EA487004EA48700503C -:10889000A483003CAD420074AC8800C8ACA8006062 -:1088A000A08700EC909F00C433F9007FA09900C41A -:1088B000909000C402187824A08F00C4914E007CD0 -:1088C00035CD0001A14D007C938B0094AD48007024 -:1088D000AC8C00CCA08B00C68F8800808F87007C7A -:1088E000AC8800B4AC8700B8A5400078A540007AF9 -:1088F0008FBF00148FB000100120102103E000088A -:1089000027BD00188F85008C0E0006AA8F86007880 -:108910000A000D7E2409000227BDFFE0AFB0001061 -:108920008F900050AFB10014AFBF00188E09000443 -:108930000E0004CF000921C08E0800048F84FF18A8 -:108940008F82FF20000839C03C068000ACC70020A1 -:10895000948500DA904300131460001C30B1FFFFCF -:108960008F8CFF1C918B0008316A00401540000B72 -:10897000000000008E0D0004022030218FBF00187F -:108980008FB100148FB000102404002200003821A1 -:10899000000D29C00A000C1827BD00200E0000633E -:1089A000000000008E0D0004022030218FBF00184F -:1089B0008FB100148FB00010240400220000382171 -:1089C000000D29C00A000C1827BD00200E00005B16 -:1089D000000000008E0D0004022030218FBF00181F -:1089E0008FB100148FB00010240400220000382141 -:1089F000000D29C00A000C1827BD002027BDFFE08C -:108A0000AFB200183092FFFFAFB00010AFBF001C34 -:108A1000AFB100141240001E000080218F8600506C -:108A20008CC500002403000600053F020005140267 -:108A300030E4000714830016304500FF2CA8000620 -:108A400011000040000558803C0C0800258C54049F -:108A5000016C50218D490000012000080000000039 -:108A60008F8E0090240D000111CD005024020002D1 -:108A7000AF820090260900013130FFFF24C800209A -:108A80000212202B010030211480FFE5AF88005036 -:108A9000020010218FBF001C8FB200188FB100148C -:108AA0008FB0001003E0000827BD002093870076F8 -:108AB00054E00034000030210E000CC6000000001D -:108AC0008F8600500A000DDE240200018F8700907F -:108AD0002405000210E500312404001300002821C1 -:108AE00000003021240700010E000C1800000000D7 -:108AF0000A000DDF8F8600508F8300902402000251 -:108B00001462FFF6240400120E000C7B000000002B -:108B10008F85008C00403021240400120E000C18B8 -:108B2000000038210A000DDF8F8600508F830090EF -:108B30002411000310710029241F0002107FFFCEB2 -:108B40002609000124040010000028210000302123 -:108B50000A000DFC240700018F91009024060002FA -:108B60001626FFF9240400100E000D20000000005E -:108B7000144000238F9800508F8600500A000DDEAD -:108B800024020003240400140E000C180000282105 -:108B90008F8600500A000DDE240200020E000D88B0 -:108BA000000000000A000DDF8F8600500E000C2828 -:108BB00000000000241900022404001400002821F1 -:108BC0000000302100003821AF9900900E000C18F1 -:108BD000000000000A000DDF8F8600500E000C38E8 -:108BE000000000008F85008C241900020040302115 -:108BF00024040010000038210A000E35AF990090BF -:108C00000040382124040010970F000200002821A2 -:108C10000E000C1831E6FFFF8F8600500A000DDFB2 -:108C2000AF9100908F84FF1C3C077FFF34E6FFFF6D -:108C30008C8500182402000100A61824AC830018BB -:108C400003E00008A08200053084FFFF30A5FFFF8D -:108C5000108000070000182130820001104000023F -:108C600000042042006518211480FFFB0005284005 -:108C700003E000080060102110C0000700000000A1 -:108C80008CA2000024C6FFFF24A50004AC820000D3 -:108C900014C0FFFB2484000403E00008000000006F -:108CA00010A0000824A3FFFFAC8600000000000015 -:108CB000000000002402FFFF2463FFFF1462FFFA9C -:108CC0002484000403E0000800000000000411C038 -:108CD00003E000082442024027BDFFE8AFB00010C7 -:108CE00000808021AFBF00140E000E7500A020216F -:108CF00000504821240AFF808FBF00148FB000105D -:108D0000012A30243127007F3C08800A3C042100DE -:108D100000E8102100C428253C03800027BD00186E -:108D2000AC650024AF820038AC400000AC65002484 -:108D300003E00008AC4000403C0D08008DAD005839 -:108D400000056180240AFF8001A45821016C48219C -:108D5000012A30243127007F3C08800C3C0421008C -:108D600000E8102100C428253C038000AC650028E1 -:108D7000AF82003403E00008AC40002430A5FFFFC0 -:108D80003C0680008CC201B80440FFFE3C08601520 -:108D900000A838253C031000ACC40180ACC001849D -:108DA000ACC7018803E00008ACC301B83C0D080063 -:108DB0008DAD005800056180240AFF8001A4582170 -:108DC000016C4021010A4824000931403107007F2D -:108DD00000C728253C04200000A418253C02800080 -:108DE000AC43083003E00008AF80003427BDFFE843 -:108DF000AFB0001000808021AFBF00140E000E75D0 -:108E000000A0202100504821240BFF80012B50247A -:108E1000000A39403128007F3C0620008FBF001433 -:108E20008FB0001000E8282534C2000100A21825E8 -:108E30003C04800027BD0018AC83083003E0000824 -:108E4000AF8000383C0580088CA700603C06800895 -:108E50000087102B144000112C8340008CA8006068 -:108E60002D0340001060000F240340008CC90060F7 -:108E70000089282B14A00002008018218CC30060F8 -:108E800000035A42000B30803C0A0800254A5480F7 -:108E900000CA202103E000088C8200001460FFF368 -:108EA0002403400000035A42000B30803C0A0800B3 -:108EB000254A548000CA202103E000088C8200006B -:108EC0003C05800890A60008938400A024C20001FD -:108ED000304200FF3043007F1064000C000238274E -:108EE000A0A200083C0480008C85017804A0FFFE4D -:108EF0008F8A0098240900023C081000AC8A0140C7 -:108F0000A089014403E00008AC8801780A000EFA49 -:108F100030E2008027BDFFD8AFB200188F92009CCE -:108F2000AFBF0020AFB3001CAFB00010AFB1001452 -:108F30008F9300348E5900283C1000803C0EFFEFC8 -:108F4000AE7900008E580024A260000A35CDFFFFE4 -:108F5000AE7800049251002C3C0BFF9F356AFFFF56 -:108F6000A271000C8E6F000C3C080040A271000B37 -:108F700001F06025018D4824012A382400E83025BD -:108F8000AE66000C8E450004AE6000183C0400FF85 -:108F9000AE6500148E43002C3482FFFFA6600008EB -:108FA0000062F824AE7F00108E5900088F90009860 -:108FB000964E0012AE7900208E51000C31D83FFF42 -:108FC00000187980AE7100248E4D001401F06021EC -:108FD00031CB0001AE6D00288E4A0018000C41C252 -:108FE000000B4B80AE6A002C8E46001C0109382114 -:108FF000A667001CAE660030964500028E44002035 -:10900000A665001EAE640034924300333062000453 -:1090100054400006924700003C028008344301009F -:109020008C7F00C0AE7F0030924700008F860038F2 -:10903000A0C700309245003330A4000250800007E2 -:10904000925100018F880038240BFF80910A003074 -:10905000014B4825A1090030925100018F90003842 -:10906000240CFFBF2404FFDFA21100318F8D0038D4 -:109070003C1880083711008091AF003C31EE007F32 -:10908000A1AE003C8F890038912B003C016C50242C -:10909000A12A003C8F9F00388E68001493E6003CA4 -:1090A0002D0700010007114000C4282400A2182544 -:1090B000A3E3003C8F87003896590012A4F90032D0 -:1090C0008E450004922E007C30B0000300107823FF -:1090D00031ED000300AD102131CC000215800002FB -:1090E00024460034244600303C028008344300808B -:1090F000907F007C00BFC8243338000417000002B2 -:1091000024C2000400C010218F98003824190002E6 -:10911000ACE20034A3190000924F003F8F8E00385C -:109120003C0C8008358B0080A1CF00018F91003866 -:10913000924D003F8E440004A62D0002956A005C0B -:109140000E000ED33150FFFF00024B800130382556 -:109150003C08420000E82825AE2500048E44003873 -:109160008F850038ACA400188E460034ACA6001CD5 -:10917000ACA0000CACA00010A4A00014A4A0001689 -:10918000A4A00020A4A00022ACA000248E620014A1 -:1091900050400001240200018FBF00208FB3001C4B -:1091A0008FB200188FB100148FB00010ACA200086D -:1091B0000A000EF227BD002827BDFFC83C05800825 -:1091C00034A40080AFBF0034AFBE0030AFB7002C76 -:1091D000AFB60028AFB50024AFB40020AFB3001C79 -:1091E000AFB20018AFB10014AFB000109483007894 -:1091F0009482007A104300512405FFFF0080F02183 -:109200000A0010020080B821108B004D8FBF00347F -:109210008F8600983C1808008F18005C2411FF808E -:109220003C1680000306782101F18024AED0002C8A -:1092300096EE007A31EC007F3C0D800E31CB7FFF43 -:10924000018D5021000B4840012AA82196A400005E -:109250003C0808008D0800582405FF8030953FFF2A -:1092600001061821001539800067C8210325F8245C -:109270003C02010003E290253338007F3C11800C52 -:10928000AED20028031190219250000D320F00043D -:1092900011E0003702E0982196E3007A96E8007A20 -:1092A00096E5007A2404800031077FFF24E3000163 -:1092B00030627FFF00A4F82403E2C825A6F9007AF3 -:1092C00096E6007A3C1408008E94006030D67FFF4A -:1092D00012D400C1000000008E5800188F8400983E -:1092E00002A028212713FFFF0E000EADAE53002C65 -:1092F00097D5007897D4007A1295001000002821A5 -:109300003C098008352401003C0A80089148000887 -:10931000908700C53114007F30E400FF0284302BB9 -:1093200014C0FFB9268B0001938E00A0268C00018B -:10933000008E682115ACFFB78F8600988FBF003470 -:109340008FBE00308FB7002C8FB600288FB5002459 -:109350008FB400208FB3001C8FB200188FB100149F -:109360008FB0001000A0102103E0000827BD0038D6 -:1093700000C020210E000E78028028218E4B0010A4 -:109380008E4C00308F84003824090002016C502379 -:10939000AE4A0010A089000096E3005C8E440030C5 -:1093A0008F9100380E000ED33070FFFF0002438013 -:1093B000011028253C07420000A71025AE2200041A -:1093C0008E5F00048F8A00388E590000240B00083D -:1093D000AD5F001CAD590018AD40000CAD40001051 -:1093E0009246000A240400052408C00030D000FF83 -:1093F000A550001496580008A55800169251000A6E -:109400003C188008322F00FFA54F0020964E000820 -:1094100037110100A54E0022AD400024924D000BF3 -:1094200031AC00FFA54C0002A14B00018E49003079 -:109430008F830038240BFFBFAC690008A0640030A4 -:109440008F9000382403FFDF9607003200E82824BD -:1094500000B51025A6020032921F003233F9003FFA -:1094600037260040A20600328F8C0038AD800034D1 -:109470008E2F00C0AD8F0038918E003C3C0F7FFFD7 -:1094800031CD007FA18D003C8F84003835EEFFFF89 -:10949000908A003C014B4824A089003C8F8500380D -:1094A00090A8003C01033824A0A7003C8E42003461 -:1094B0008F9100383C038008AE2200408E59002C6A -:1094C0008E5F0030033F3023AE26004492300048C8 -:1094D0003218007FA23800488F8800388E4D003047 -:1094E0008D0C004801AE582401965024014B4825AC -:1094F000AD0900489244000AA104004C96470008B8 -:109500008F850038A4A7004E8E5000308E44003066 -:109510000E00031C8C65006092F9007C0002F9408B -:10952000004028210002110003E2302133360002FE -:1095300012C00003020680210005B08002168021BF -:10954000926D007C31B3000412600002000570804F -:10955000020E80218E4B003024058000316A00030A -:10956000000A482331240003020418218F90003898 -:10957000AE03003496E4007A96E8007A96F1007A19 -:1095800031077FFF24E20001305F7FFF0225C824FE -:10959000033F3025A6E6007A96F8007A3C120800D0 -:1095A0008E520060330F7FFF11F2001800000000A0 -:1095B0008F8400980E000EAD02A028218F840098A1 -:1095C0000E000EBD028028210E000EF200000000E9 -:1095D0000A000FFE0000000096F1007A02248024A9 -:1095E000A6F0007A92EF007A92EB007A31EE00FF5B -:1095F000000E69C2000D6027000C51C03169007F68 -:10960000012A20250A000FF8A2E4007A96E6007AE3 -:1096100000C5C024A6F8007A92EF007A92F3007A8F -:1096200031F200FF001271C2000E6827000DB1C0B8 -:10963000326C007F01962825A2E5007A0A0010AF5F -:109640008F8400983C0380003084FFFF30A5FFFF2B -:10965000AC640018AC65001C03E000088C620014C8 -:1096600027BDFFA83C068008AFBE0050AFBF005426 -:10967000AFB7004CAFB60048AFB50044AFB4004040 -:10968000AFB3003CAFB20038AFB10034AFB0003080 -:1096900034C80100910500C590C70008309EFFFF47 -:1096A00030A500FF30E2007F0045182AA7A0001473 -:1096B000A7A0001E10600053AFA0001090C90008C2 -:1096C0003126007F00A620232493FFFF0013802B68 -:1096D000001E882B0211782451E000848FB3001003 -:1096E0003C1980089736005297370050001EC4007E -:1096F00002D7A8230015A4000014140303C2902A63 -:109700001640000200182C0300402821001314000A -:109710000002240300A4F82A57E0000100A0202141 -:1097200028830009146000020080A021241400088E -:109730003C0A80088D450048001449808D48004C43 -:109740003C0380003124FFFF3C06001000863825D2 -:1097500034710400AC650038AF91009CAC68003CEB -:10976000AC670030000000000000000000000000B6 -:1097700000000000000000000000000000000000E9 -:10978000000000008C6C0000318B00201160FFFD98 -:109790000014682A01B01024104000390000A821EC -:1097A0003C16800892D700083C1280008E440100CD -:1097B00032F6007F0E000E7802C028218E2F001096 -:1097C0008E4401000000902131F73FFF0E000E9003 -:1097D00002E02821922E000031C2003F2C500008E8 -:1097E00052000010000088210002F8803C030800AD -:1097F0002463542C03E3C8218F38000003000008C1 -:109800000000000090CE0008938B00A031CD007FB7 -:1098100000AD6023016C50210A0010F52553FFFFB5 -:10982000000088213C1080008E0401000E000EAD67 -:1098300002E028218E0401000E000EBD02C0282186 -:109840001220000F0013802B8F8A009C26A9000194 -:109850000009AC00027298230015AC0325450040B6 -:1098600002B4B02A0013802B2417000100A0882125 -:1098700002D01024AF85009C1440FFC9AFB7001080 -:109880003C07800894F100503C0580003C06002015 -:1098900002B1C821A4F90050ACA6003094F40050E5 -:1098A00094E3005203D560231074001D319EFFFF26 -:1098B0008CE5004C8CE900480015618000ACB021BB -:1098C0000000A02102CCA82B013450210155B82161 -:1098D000ACF6004CACF70048001E882B021178242F -:1098E00015E0FF803C1980088FB300108FBF005433 -:1098F0008FBE00503A6200018FB7004C8FB600480F -:109900008FB500448FB400408FB3003C8FB2003855 -:109910008FB100348FB0003003E0000827BD00583D -:1099200094F200548CEF0044325FFFFE001FC0C071 -:1099300001F87021ACAE003C8CEB00448CAD003CD7 -:10994000016D40231900003B000000008CE2004044 -:10995000244200013C07005034E400103C03800026 -:10996000ACA20038AC640030000000000000000031 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000008C76000032D70020AC -:1099900012E0FFFD3C118008962800543C0A80002C -:1099A0003C06800831190001001960C0018AA0211D -:1099B0008E8304003C0708008CE700443C1500201F -:1099C000ACC300488E89040424050001ACC9004CD6 -:1099D00010E50259AD550030963F00523C05080095 -:1099E0008CA5004000BFC021A6380052962F00541D -:1099F00025EE0001A62E00549626005430C4FFFF29 -:109A00005487FF34001E882B30A5FFFF0E0010D3B3 -:109A1000A62000543C0408008C84002496270052A1 -:109A20000044102300E29023A63200520A0010F7EF -:109A3000001E882B8CE200400A0011983C07005061 -:109A400092280001240700013102007F1447001C06 -:109A500097AC001E8E2A0014240BC00031443FFF37 -:109A6000018B48243C0608008CC600600124282590 -:109A700030A43FFF0086882B12200011A7A5001EEE -:109A80003C1108008E3100588F82009800044180FC -:109A90002407FF80022218210068F82103E7C82468 -:109AA00033EF007F3C1880003C12800EAF19002C71 -:109AB00001F2682191AE000D35D00004A1B0000D77 -:109AC0000E000F0724120001241100013C10800039 -:109AD0008E0401000E000EAD02E028218E0401006C -:109AE0000E000EBD02C028211620FF588F8A009C50 -:109AF0000A0011620013802B8F86009C90C9000120 -:109B00003125002010A0018A241000013C048008A7 -:109B1000348C0080918B007C8F9100340000902168 -:109B2000316A00011140000FAFB000208CD000144A -:109B30008C8E0060020E682B15A0000302003821F5 -:109B40008C8700603C048008348300808C72007035 -:109B500000F2782B15E0000200E020218C640070F8 -:109B6000008090213C07800834E500808CD90014E7 -:109B70008CBF0070033FC02B170000020320202180 -:109B80008CA400700092182310600003AFA300287B -:109B900024080002AFA800208FA500200265102B2A -:109BA000144000B5000018218CC400388E2F000C22 -:109BB0003C180080AE2400008CCE00343C10FF9F87 -:109BC00001F86025AE2E000490CB003F360DFFFF5C -:109BD000018D48243C0A00203C06FFEFA22B000B1D -:109BE000012A382534C5FFFF00E540243C02000867 -:109BF0008F87009C01022025AE24000C8CE300140A -:109C0000AE2000188FAF0028AE2300148CF8001887 -:109C10003C1FFFFB37F9FFFFAE38001C8CEE00083D -:109C200000996824024F8021AE2E00248CEC000C99 -:109C3000AE2D000CA6200038A620003AAE30002C35 -:109C4000AE2C0020AE2000288CEB00148FAA002838 -:109C500001724823012A302310C00011AE260010E3 -:109C600090F0003D8E2C00048E2A00000010690048 -:109C7000018D28210000102100AD302B0142482128 -:109C800001264021AE250004AE28000090E3003DEF -:109C9000A223000A8F9F009C97F90006A6390008AE -:109CA0008F8A0038240200023C068008A14200008E -:109CB00034C900809525005C024020218F90003837 -:109CC00030A8FFFF0E000ED3AFA800248FA30024FE -:109CD0000002FB808F85009C3C04420003E3C82502 -:109CE0000324C025AE1800048F8400388CAF0038E0 -:109CF000AC8F00188CAE0034AC8E001CAC80000C15 -:109D0000AC800010A4800014A4800016A480002061 -:109D1000A4800022AC80002490A7003FA48700020A -:109D20005240018C240700018FAB002851600002D3 -:109D300090A2003D90A2003E244C0001A08C0001A6 -:109D40008F840038AC9200083C18800837100080DF -:109D5000920F007C31EE000215C00002240700348F -:109D6000240700308F85009C3C088008350900805E -:109D700090A300009128007C32590003A08300309A -:109D80008F9F009C8F9000382404000493F80001FA -:109D900000997823240DC000A21800318F99003853 -:109DA0008F8E009C31E50003972C003295CB00127A -:109DB00000F24821018D502431623FFF01423025DD -:109DC000A7260032932300320125382131080004F0 -:109DD000307F003F37E40040A324003212400002ED -:109DE0008F85003800E838213C0C8008ACA700348F -:109DF000358B01008D6200C02E4400012403FFDF7B -:109E0000ACA2003890AA003C0004C9403146007F53 -:109E1000A0A6003C8F8900382405FFBF9127003C95 -:109E200000E54024A128003C8F8F003891FF003CC2 -:109E300003E3C02403198025A1F0003C8F8B009C14 -:109E40008F8A00388D6E0020AD4E00408D6D00244D -:109E5000AD4D00448D6C0028AD4C00488D62002C47 -:109E60000E000EF2AD42004C8FA600202407000227 -:109E700010C700118FA300200003202B00048023B3 -:109E80000270982400608021006090210A00114B2C -:109E90000010882B962700128F84009800009021D4 -:109EA00030E5FFFFA7A700140E000EA1241100014A -:109EB0000A0011F63C1080003C1980003C0280082A -:109EC0008F240100905800080E000E783305007FA3 -:109ED0008F8E00388FAF00208FA40028A1CF000004 -:109EE0000E000ED38F9000388FAD002400023B800F -:109EF0003C0B420000ED40258F87009C010B202584 -:109F0000AE0400048CE500388F900038000050212A -:109F1000000A1900AE0500188CEC00343C087FFFE5 -:109F20003504FFFFAE0C001C90E9003E8E1F001CA4 -:109F30008E1800180009C9000009370203F96821CA -:109F40000066102501B9782B0302702101CF58213A -:109F5000AE0D001CAE0B0018AE00000CAE000010E1 -:109F600090E5003E8FAF0028240E0005A6050014E2 -:109F700094EC00042405C00001E45824A60C00164B -:109F800090EA003E01E02021A60A002094E60004A9 -:109F9000A6060022AE00002490E3003FA6030002C4 -:109FA00090E9003E90FF003D03E9C82327380001F7 -:109FB000A21800018F8D00383C108008ADAF00085A -:109FC000A1AE00308F9800388F82009C360F0100C0 -:109FD000970C0032944A00122410FF8000AC382401 -:109FE00031463FFF00E61825A703003293090032EF -:109FF0002405FFBF2403FFDF313F003F37F9004056 -:10A00000A31900328F8C00382418FFFFAD80003474 -:10A010008DEE00C0AD8E0038918D003C31A2007FE6 -:10A02000A182003C8F87003890EA003C0145302433 -:10A03000A0E6003C8F9900389329003C0123F824C6 -:10A04000A33F003C8F8D00383C1F8008ADB8004016 -:10A05000ADB2004491AF00483C12800001F0702581 -:10A06000A1AE00488F8700388F86009C8CEC00489A -:10A0700001921024004B5025ACEA004890C5003EE8 -:10A08000A0E5004C8F88009C8F8300389509000460 -:10A09000A469004E8FE500600E00031C0000000064 -:10A0A0008F99FF248FAE002800028140932F007CFF -:10A0B0000002C1000218682131F20002004028218C -:10A0C000164000AA01CD30213C0A800835430080AB -:10A0D0009069007C313F000413E000038FAE00283C -:10A0E0000005608000CC3021240D00048F900038E2 -:10A0F00031C7000301A758233168000300C820219D -:10A10000AE0400343C068008A62500383C058000DB -:10A110008CA4010090D100080E000EBD3225007FF6 -:10A120000E000EF2000000000A0012E08FA30020D3 -:10A130008F8500348CC2003824180003A4A00008C6 -:10A14000ACA200008CDF0034A0A0000A8F92009C1B -:10A15000ACBF00043C040080924F003FA0B8000C4C -:10A160008CAE000C3C0DFF9FA0AF000B01C440253E -:10A1700035ABFFFF3C11FFEF8F98009C010B3024A3 -:10A180003639FFFF00D96024ACAC000C8F030014FB -:10A19000971F00128F870098ACA300108F0900143E -:10A1A000ACA00018ACA00020ACA90014ACA0002406 -:10A1B0008F0A001833E93FFF00091180ACAA00287C -:10A1C0008F1200080047782133EE0001ACB2003056 -:10A1D0008F08000C8F990038000F69C2000E238091 -:10A1E00001A45821241100023C068008A4AB001CE5 -:10A1F000A4A00034ACA8002CA331000034D9008006 -:10A20000972C005C8F8F00383C034200318AFFFF9F -:10A2100001433825ADE700048F82009C241800011B -:10A220002411C0008C5F003824070034ADFF0018F3 -:10A230008C520034ADF2001CADE0000CADE000101B -:10A24000A5E00014A5E00016A5E00020A5E000228E -:10A25000ADE00024A5F00002A1F800018F8B0038CA -:10A260008F8E009CAD70000891CD0000A16D003074 -:10A270008F88009C8F84003891050001A0850031F3 -:10A280008F920038964C00320191502401491825D4 -:10A29000A6430032925F003233E2003FA242003216 -:10A2A0009338007C330F000215E000028F840038E1 -:10A2B000240700303C028008AC870034345201008F -:10A2C0008E5F00C0240EFFBF02009021AC9F0038BB -:10A2D0009098003C330F007FA08F003C8F8800389F -:10A2E000910D003C01AE5824A10B003C8F86003834 -:10A2F00090D1003C36390020A0D9003C8F8A009CC8 -:10A300008F8500380010882B8D4C0020ACAC0040AD -:10A310008D430024ACA300448D490028ACA900481B -:10A320008D47002CACA7004C0E000EF23C108000B4 -:10A330000A00114C0000000094CD00523C0B0800B4 -:10A340008D6B0024016D8821A4D100520A0010F702 -:10A35000001E882BA08700018F840038240D000187 -:10A36000AC8D00080A0012953C188008000290800D -:10A370000A00137400D2302127BDFFE03C0D800895 -:10A38000AFB20018AFB00010AFBF001CAFB10014E7 -:10A3900035B200808E4C001835A80100964B00069F -:10A3A00095A70050910900EC000C56020167282384 -:10A3B0003143007F312600FF24020003A38300A065 -:10A3C000AF84009810C2001B30B0FFFF910600EC74 -:10A3D0002412000530C200FF1052003300000000BC -:10A3E000160000098FBF001C8FB200188FB1001437 -:10A3F0008FB00010240D0C003C0C800027BD002005 -:10A4000003E00008AD8D00240E0010DA02002021C8 -:10A410008FBF001C8FB200188FB100148FB00010D6 -:10A42000240D0C003C0C800027BD002003E0000838 -:10A43000AD8D0024965800789651007A924E007D9A -:10A440000238782631E8FFFF31C400C014800009CB -:10A450002D11000116000037000000005620FFE219 -:10A460008FBF001C0E000FB0000000000A00143C5B -:10A470008FBF001C1620FFDA000000000E000FB096 -:10A48000000000001440FFD88FBF001C16000022FF -:10A4900000000000925F007D33E2003FA242007D99 -:10A4A0000A00143C8FBF001C950900DA8F860078E3 -:10A4B00000802821240400050E0006AA3130FFFF89 -:10A4C0009783008A3C0480002465FFFFA785008AEB -:10A4D0008C8A01B80540FFFE00000000AC800180BE -:10A4E0008FBF001CAC9001848FB200188FB1001494 -:10A4F0008FB000103C0760133C0B1000240D0C00C3 -:10A500003C0C800027BD0020AC870188AC8B01B8D3 -:10A5100003E00008AD8D00240E0010DA02002021B7 -:10A520005040FFB18FBF001C925F007D0A0014698C -:10A5300033E2003F0E0010DA020020211440FFAA8F -:10A540008FBF001C12200007000000009259007D00 -:10A550003330003F36020040A242007D0A00143C26 -:10A560008FBF001C0E000FB0000000005040FF9E87 -:10A570008FBF001C9259007D3330003F0A001498B1 -:04A58000360200405F -:0CA58400000000000000001B0000000FA1 -:10A590000000000A0000000800000006000000059E -:10A5A000000000050000000400000004000000039B -:10A5B000000000030000000300000003000000038F -:10A5C0000000000200000002000000020000000283 -:10A5D0000000000200000002000000020000000273 -:10A5E0000000000200000002000000020000000263 -:10A5F0000000000200000002000000020000000154 -:08A60000000000010000000150 -:08A608008008010080080080B9 -:10A610008008000000000C000000308008001020BE -:10A62000080010CC080010E4080010F80800110C15 -:10A6300008001020080010200800114008001178C0 -:10A6400008001188080011B0080018A0080018A020 -:10A65000080018D8080018D8080018EC080018BC22 -:10A6600008001B1408001AE008001B6C08001B6C93 -:10A6700008001BF408001B24800802400800228008 -:10A68000080020CC080022A80800234008002490DD -:10A69000080024DC08002600080025080800258C96 -:10A6A0000800213C08002AA808002A4C080020E8DD -:10A6B000080020E8080020E8080026740800267436 -:10A6C000080020E8080020E808002924080020E805 -:10A6D000080020E8080020E8080020E80800298495 -:10A6E000080020E8080020E8080020E8080020E82A -:10A6F000080020E8080020E8080020E8080020E81A -:10A70000080020E8080020E8080020E8080020E809 -:10A71000080020E8080020E8080024FC080020E8E1 -:10A72000080020E8080029F4080020E8080020E8D4 -:10A73000080020E8080020E8080020E8080020E8D9 -:10A74000080020E8080020E8080020E8080020E8C9 -:10A75000080020E8080020E8080020E8080020E8B9 -:10A76000080020E8080020E8080020E80800284841 -:10A77000080020E8080020E8080027BC0800271887 -:10A78000080038600800383408003800080037D462 -:10A79000080037B40800376880080100800800808E -:10A7A0008008000080080080080047C808004800B2 -:10A7B00008004748080047C8080047C8080045285F -:08A7C000080047C808004B9C8B -:08A7C8000A000C7600000000FD -:10A7D000000000000000000D727870352E302E3021 -:10A7E0006A31350005000003000000000000000190 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000010000003000000000000000D57 -:10D9B0000000000D3C020801244282603C03080183 -:10D9C00024638320AC4000000043202B1480FFFD23 -:10D9D000244200043C1D080037BD9FFC03A0F02139 -:10D9E0003C100800261031D83C1C0801279C82609E -:10D9F0000E0011EA000000000000000D3C02800053 -:10DA000030A5FFFF30C600FF344301803C08800092 -:10DA10008D0901B80520FFFE00000000AC64000085 -:10DA200024040002A4650008A066000AA064000B9C -:10DA3000AC6700183C03100003E00008AD0301B818 -:10DA40003C0560008CA24FF80440FFFE000000007F -:10DA5000ACA44FC03C0310003C040200ACA44FC473 -:10DA600003E00008ACA34FF89486000C00A05021FE -:10DA70002488001400062B02000510800044482171 -:10DA80000109182B10600011000000009103000034 -:10DA90002C64000950800009911900010003608086 -:10DAA0003C0D080125AD8108018D58218D670000CE -:10DAB00000E0000800000000911900010119402158 -:10DAC0000109302B54C0FFF29103000003E000086D -:10DAD000000010210A000CBE25080001910F000172 -:10DAE000240E000A15EE00400128C8232F38000A32 -:10DAF0001700003D250D00028D580000250F00067F -:10DB0000370E0100AD4E0000910C000291AB0001F8 -:10DB100091A4000291A60003000C2E00000B3C0013 -:10DB200000A7102500041A000043C8250326C025BD -:10DB3000AD580004910E000691ED000191E700023E -:10DB400091E50003000E5E00000D6400016C3025BD -:10DB50000007220000C41025004518252508000AEA -:10DB60000A000CBEAD430008910F0001250400021D -:10DB70002408000255E80001012020210A000CBE03 -:10DB800000804021910C0001240B0003158B00162E -:10DB9000000000008D580000910E000225080003CF -:10DBA000370D0008A14E00100A000CBEAD4D00005C -:10DBB00091190001240F0004172F000B0000000032 -:10DBC00091070002910400038D43000000072A0022 -:10DBD00000A410253466000425080004AD42000CA2 -:10DBE0000A000CBEAD46000003E00008240200015C -:10DBF00027BDFFE8AFBF0014AFB000100E0014E661 -:10DC0000008080213C0480083485008090A60005B7 -:10DC10002403FFFE0200202100C310248FBF001444 -:10DC20008FB00010A0A200050A0014F027BD001854 -:10DC300027BDFFE8AFB00010AFBF00140E000F4EBD -:10DC4000008080213C06800834C5008090A400003C -:10DC500024020050308300FF106200073C0980005E -:10DC6000020020218FBF00148FB00010AD20018072 -:10DC70000A00101027BD0018240801003C0780008E -:10DC8000020020218FBF00148FB00010ACE801808B -:10DC90000A00101027BD001827BDFF703C0880083F -:10DCA000AFB60080AFB5007CAFB1006CAFBF008CE9 -:10DCB000AFBE0088AFB70084AFB40078AFB30074D4 -:10DCC000AFB20070AFB00068350500803C0780003F -:10DCD0008CF2012890A40009ACE0008490A6000515 -:10DCE000309100FF0000A8210006182730620001D3 -:10DCF0000000B02114400067AFA0005090A90000C0 -:10DD000024050020312400FF10850016240A00504D -:10DD1000108A008C000000003C0C08008D8C00DC98 -:10DD2000258B00013C010800AC2B00DC0E0015DC4B -:10DD3000000000008FBF008C8FBE00888FB700846A -:10DD40008FB600808FB5007C8FB400788FB30074DD -:10DD50008FB200708FB1006C8FB0006803E00008D4 -:10DD600027BD00900000000D3C108000AFA00030E7 -:10DD7000961F01168E1901043C1E002036130C005C -:10DD8000033EC0240018B82B00173140AFA6003066 -:10DD90008E0E010433F4FFFF3C0F004002938021FC -:10DDA00001CF68249213000D11A0004834C4004034 -:10DDB000326200201440000234860080008030214E -:10DDC00014C00093AFA600303C05800834A8008042 -:10DDD0009107000830E6004050C000063C0680086D -:10DDE00024090004122900A2240A0012122A002980 -:10DDF0003C06800834D401003C17800096EF011ADD -:10DE0000960D000E928E0008326B000431F7FFFF72 -:10DE100001CD6004AFAC00548E14000411600031D9 -:10DE20008E1E000834C3008090790008333800400B -:10DE300017000028000000008C730050029390230C -:10DE4000064000063C0C80008C7E0034029E80233D -:10DE5000060200838EA200083C0C8000AD800044C6 -:10DE6000240200018FBF008C8FBE00888FB7008412 -:10DE70008FB600808FB5007C8FB400788FB30074AC -:10DE80008FB200708FB1006C8FB0006803E00008A3 -:10DE900027BD00900E000D1A000020218FBF008CBE -:10DEA0008FBE00888FB700848FB600808FB5007C4E -:10DEB0008FB400788FB300748FB200708FB1006C94 -:10DEC0008FB0006803E0000827BD00900A000D7ABB -:10DED00000C020210E00163D028020211440FFDFEB -:10DEE0003C0C80003C038008346300808C6200346A -:10DEF0000282F82307E00017000000003C1508002C -:10DF00008EB5310026B100013C010800AC31310072 -:10DF10000E0014E6024020213C0B80083570008082 -:10DF2000920A002502402021354200040E0014F020 -:10DF3000A20200250E000C9E024020210A000DA71F -:10DF4000240200013C15080126B583100A000D6962 -:10DF50003C1080008C660030028620231880000868 -:10DF60002409000C3C0808008D083100327300FCC5 -:10DF70000000B821250700013C010800AC27310052 -:10DF8000AFA900308C65003000B4382318E000DB06 -:10DF900002E7502A1540FFDE0000000012E7002AC9 -:10DFA00002E768230287A02131B7FFFF326E00022B -:10DFB00011C00034327F00103C148008369000807D -:10DFC000920F000831F6004052C000CE8EA2000829 -:10DFD000024020210E0014E624130018A2130009A9 -:10DFE000921800052419FFFE024020210319B824CD -:10DFF0000E0014F0A21700052404003900002821A7 -:10E000000E001618240600180A000DA724020001AD -:10E0100092B6000C3C048008348300808C67003882 -:10E020000016AB0036B10081024020213225F0817C -:10E030000E000C8D30C600FF3C0C8000AD8000440B -:10E040000A000DA7240200013A6C0001318B000187 -:10E050001560FFAF0287A0210A000DF80000000044 -:10E060000040F809240400160A000DA7240200014C -:10E07000024020210E00171D020028210A000D5C1D -:10E080008FBF008C13E0FF743C038008346800806D -:10E090008D0400388C66000403C610231C40FF6FFB -:10E0A0003C0C800003C4282304A200010080F0215E -:10E0B000AFB40010AFB70014AFA700183C1F80002A -:10E0C00097E301208D0900309506005C8FB900545C -:10E0D0008FAC00303062FFFF30D8FFFF0047702167 -:10E0E00037EF40000338682B01CF5821018D5025B0 -:10E0F000AFAB0020AFA90028AFAA0030AFA9002421 -:10E10000AFA0002CAFBE00349107000830E4000837 -:10E110001480008F020020218EA200040040F80924 -:10E1200027A400108FA900303128000255000001FB -:10E13000327300FE3C048008348C0080918B000810 -:10E14000316A0040514000128FA400248C8D0004DD -:10E1500011BE00BE240E00143265000110A0000C98 -:10E160008FA400242404000C122400D42A27000DBC -:10E1700010E000CE2409000E2408000A52280001F5 -:10E18000241600088FA2002424440001AFA4002418 -:10E190008FA600143C038008346500800086F821B7 -:10E1A0008CB10030ACBF003090B9004E8CAE003066 -:10E1B0003418FFFF0338780401CF6821ACAD003478 -:10E1C0008FA600308FAC005430CA000803CC582111 -:10E1D0001140000CAFAB00588CA400208FB0005849 -:10E1E0001090009430C600FF92A2000C8FA700345C -:10E1F0000240202100024B00352800800E000C8DCB -:10E200003105F0803C0C8008359000808E0B00308A -:10E210000171502319400070265900803C180800F5 -:10E220008F183198241FFF80033F7824332D007FFF -:10E230003C0680003C0E800433110010ACCF0090EF -:10E240001220003401AE282190A3006B54600032EC -:10E250003C10800824070001A0A7006B94C4007A3A -:10E260002486000AA60600123C0D800835A5008011 -:10E2700090B10008322C0040158000043C03800857 -:10E28000326E000115C0006200000000346400809E -:10E290008C8F00208FB3005811F3000A3463010003 -:10E2A0008C7900000299C0231B0000778FA80058CA -:10E2B000AC880020AC74000024140001AC7E000483 -:10E2C000AFB4005016C00037000000008FA400500B -:10E2D000148000300000000012E00005000018214A -:10E2E0008FA900303137000452E0FE920060102107 -:10E2F000240300010A000D5B006010210A000DF9E3 -:10E30000000038210040F809240400170A000DA776 -:10E31000240200013C10800836100080240900010E -:10E32000024020210E0014E6A609001292080025E2 -:10E3300024050001AFA50050350200010240202154 -:10E340000E0014F0A20200250A000EA93C0D800860 -:10E3500027A50038AFA800600E000CA8AFA00038B9 -:10E360001440FF6D8FA800608FA5003830B0010009 -:10E370005200FF6A8EA200048FA3003C8D07005854 -:10E38000006720230483FF64AD0300580A000E5584 -:10E390008EA200040E000C9E024020210A000EC432 -:10E3A000000000000E0014E6024020213C05800819 -:10E3B00034A30080024020210E0014F0A076000952 -:10E3C00002C03021240400370E0016180000282156 -:10E3D0000A000EC28FA400508FA200185840FFA35D -:10E3E0003C0D80080E0014E602402021920A002510 -:10E3F000240B0001AFAB0050354200040240202145 -:10E400000E0014F0A20200250A000EA93C0D80089F -:10E410008CB600308EBE00082404001826D50001FA -:10E4200003C0F809ACB500308FB200300A000D5BB4 -:10E43000324200043C07800094E5011A50A0FF6AB4 -:10E4400034C600100A000E8992A2000C122E002A77 -:10E450002A2F001511E0001E241900162418000CA4 -:10E460005638FF3E326500013C1F800893E3001BD5 -:10E470002410FFBD2416000E00703024A3E6001BFC -:10E480000A000E65326500018C7F000017F4FF8DD5 -:10E49000000000008C67000403C7302304C1FF8420 -:10E4A0008FA800580A000EBF000000001629FF3692 -:10E4B0008FA200240A000E70241600102411000EF2 -:10E4C00052D1FF30241600100A000E6F24160016D9 -:10E4D0005639FF22326500013C1F800893E3001B80 -:10E4E0002410FFBD2416001000703024A3E6001B8A -:10E4F0000A000E65326500010A000E64241600123F -:10E500003C0380008C6201B80440FFFE2404080034 -:10E51000AC6401B803E000080000000030A5FFFF74 -:10E5200030C6FFFF3C0780008CE201B80440FFFECC -:10E5300034E80180AD040000ACE400203C04800815 -:10E54000948300483063FFFF1060001D3C0B800087 -:10E5500024AA0012006A482B5120001A240A000342 -:10E5600094F901208F890000240C001A3338FFFF32 -:10E570002707FFFE0067782B39EE000100096B8248 -:10E5800001AE5824A10C000B116000478F830004DA -:10E59000A50700148F88000435070001AF87000429 -:10E5A00030CC00405580000F3C0880003C0C8000BF -:10E5B00035840180A485000E0A000F988F8F000C0F -:10E5C000240A00033564018030CC00408F890000AC -:10E5D0008F870004A08A000B5180FFF53C0C80005F -:10E5E0003C088000950301203C08800895180040F5 -:10E5F0003079FFFF272EFFFE330FFFFF01CF682B7F -:10E6000011A0000301C02021950200403044FFFF0B -:10E610003C0B800000A4502335650180A4A4000EAB -:10E62000A4AA00248F8F000C3C05800034AE01802A -:10E630002418000230ED8000A5D8000CA5C90010F8 -:10E64000ADCF0028A5C6000811A0000E3C04800034 -:10E6500094AA01163142FFFC244800040105182148 -:10E660008C7940003326FFFF14C00007240EBFFF43 -:10E670003C0BFFFF35657FFF00E53824AF870004C2 -:10E680003C048000240EBFFF348C018000EE68241F -:10E69000A58D0026AD89002C3C071000AC8701B881 -:10E6A00003E00008000000002402FFFE006238249E -:10E6B0000A000F76AF8700043C05800034A4007088 -:10E6C0008C8A000090A601128F84000027BDFFF005 -:10E6D00030C300FF0003188230820100000038219F -:10E6E00010400039246600033087400050E00039B4 -:10E6F00030882000000610800045C8218F2F400080 -:10E700002478000400187080AFAF000001C56821B4 -:10E710008DAC4000AFAC000494AB01163169FFFC36 -:10E72000012540218D054000AFA500088FA90008F4 -:10E7300000003021000028213C07080024E70100E8 -:10E740000A000FE9240800089042000024A50001F7 -:10E750002CAD000C0062C8210019C080030778218D -:10E760008DEE000011A0000600CE302603A510217A -:10E7700014A8FFF500051A005520FFF49042000090 -:10E780003C048000348700703C0508008CA53104EF -:10E790008CE300002CA8002011000009006A382337 -:10E7A000000558803C0C0800258C3108016C48217C -:10E7B00024AA0001AD2700003C010800AC2A310466 -:10E7C000AF86000C2407000100E0102103E00008E0 -:10E7D00027BD00101100FFFC0000382100066080FA -:10E7E000018558218D6440002469000400093880A7 -:10E7F000AFA4000000E518218C664000AFA000081F -:10E800000A000FD9AFA6000427BDFFD8AFB2001889 -:10E81000AFB00010AFBF0024AFB40020AFB3001CF6 -:10E82000AFB100148F8700003C0480009483010E78 -:10E8300030E2400000008021104000103072FFFFE5 -:10E840003C06002000E6282410A0000D30EA8000DD -:10E850008F8800042409BFFF00E938243503100025 -:10E86000AF87000030F120001620000B3C1400049C -:10E870002418FFBF0A0010380078102430EA800006 -:10E88000154000863C0C002030F120001220FFF8DB -:10E890008F8300043C14000400F498241260FFF5F8 -:10E8A0002418FFBF3462004030F901001320000F2C -:10E8B000AF8200043C02002000E2F82413E00005CF -:10E8C0003C0B80003C04000400E41824106000CFDE -:10E8D00000000000956A011E9569011C3146FFFF8A -:10E8E0000009440000C82825AF85000C3C0E8000BC -:10E8F00095CD010C8DC44000340CFFFF108C00B08E -:10E9000031A5FFFF308F010055E0000124100010F9 -:10E9100030F11000522000083611000130F30020C1 -:10E920001660009F3C18100000F8A0241680009686 -:10E930003C040C003611000130E801001500000B0A -:10E940003C0A00018F8800043109400015200008AE -:10E9500000EA30243C0C1F0100EC58243C0A100053 -:10E96000516A00AE30AD02003C0A000100EA3024DA -:10E9700014C000953C05100000E520240000402153 -:10E98000108000070000902100079E023272000FE5 -:10E99000001278803C0E080125CE82C001EE402195 -:10E9A0008F9400181280004702208021108000916F -:10E9B000000000003C0980009539010E9103000021 -:10E9C000022030213338FFFF2705000410600008C3 -:10E9D0000000A021241F0003107F013A240400023C -:10E9E000910C00011184011830EA00400012A1C00E -:10E9F0008F92001C52400001362600403C138000DC -:10EA00008E6F400031F10100122000CB30D1FFFBAE -:10EA10003C1808008F18002430D20004330600048C -:10EA200014C000CC30B0FFFF564000013631000466 -:10EA300002802021020028210E000F5502203021E3 -:10EA40001640000D00002021366501803C04800046 -:10EA50008C9301B80660FFFE2419200024140002E4 -:10EA6000A4B90008A0B4000BA4A000103C0510003D -:10EA7000AC8501B8000020218FBF00248FB4002096 -:10EA80008FB3001C8FB200188FB100148FB000102C -:10EA90000080102103E0000827BD002800EC582466 -:10EAA0001160FF7A30F120008F8D00043C0FFFFFD2 -:10EAB00035EE7FFF00EE382435A380000A001027D2 -:10EAC000AF8700003C0208008C4200383C0408007C -:10EAD000248400381040004B2449FFFF3C03800091 -:10EAE000946C010E318BFFFF110000A02573000410 -:10EAF0003C1008008E1000301200000A30E60100C1 -:10EB00008F8A000431434000106000063C0F0F0064 -:10EB100000EF70243C0D010001AE402B110000DF1E -:10EB20003265FFFF10C000693C140F0000F4282478 -:10EB30003C18020010B800658F99000C3270FFFF7E -:10EB40000329982402649021924900042527000497 -:10EB5000000721C002002821362600020E000F55B2 -:10EB6000000000008FBF00248FB400208FB3001C72 -:10EB70008FB200188FB100148FB000100000102168 -:10EB800003E0000827BD00283C020BFF00E4182426 -:10EB9000345FFFFF03E3C82B5320FF6736110001EA -:10EBA0003C0608008CC6002C3611000524D000015C -:10EBB0003C010800AC30002C0A00105D30E8010078 -:10EBC0000A00105224100020024028213C120800A4 -:10EBD0008E5200D824040080264D00013C0108001C -:10EBE000AC2D00D80E000F55240600030A0010E8D3 -:10EBF0008FBF00243C080801250882C00A00107C51 -:10EC00003C0980000A0010C5000048210E000FBC1E -:10EC1000000000000A0010498F87000015A0FF5374 -:10EC20003C0A00012645000430AAFFFF36260002F8 -:10EC30003C0380008C7201B80640FFFE8F850008FF -:10EC400034690180AD20000010A000AF3C048000BA -:10EC5000254F001200AF702B51C000AC24030003FD -:10EC6000947801202414001A30F140003313FFFF80 -:10EC7000A134000B122000B62663FFFE00A3C82BB0 -:10EC8000572000B4241FFFFE35080001A5230014FF -:10EC9000AF8800043C108000240CBFFF010C482406 -:10ECA000240B000236080180A50B000CA50A000EFB -:10ECB000A5060008A5090026A50700103C071000BE -:10ECC000AE0701B80A0010E88FBF00243C0308001B -:10ECD0008C6300D02E45000C001221C0386B00015F -:10ECE0002D6200010045F82417E0FF9A3270FFFF03 -:10ECF000264CFFFC2D84000454800050000020218D -:10ED0000386A00022D430001006580241600004A85 -:10ED10003270FFFF00076A420012702B01AE4024E0 -:10ED20005500006300002021001221C002002821AC -:10ED30000A0010E53626000234DF0002028020219E -:10ED400033E6FFFF0E000F5530A5FFFF0A0010ACA1 -:10ED50000000202124040100020028210E000F558C -:10ED6000022030210A001098000000008C6640004C -:10ED700030CF010011E0003D30F801003C120800E6 -:10ED80008E52002413000011323400043C1F0F0087 -:10ED900000FFC8243C0502001325000C8F8C000CDA -:10EDA000022030213265FFFF0189582401641021BF -:10EDB000904900043230FFFB2411FFFE2527000498 -:10EDC0000E000F55000721C00251902424040001B9 -:10EDD00012440052324300011460005802003021F6 -:10EDE000324A0004114000048F8D000031A8080051 -:10EDF0001500005A3265FFFF1680FF5B8FBF0024AD -:10EE00003C138000366501803C0480008C9001B882 -:10EE10000600FFFE24062000240F0002A4A600081E -:10EE2000A0AF000BA4A000103C0E1000AC8E01B8E7 -:10EE30000A0010E88FBF00240000202102002821D2 -:10EE40000A0010E5362600021140FEE90000A0216C -:10EE5000952E0110950D000231C8FFFF51A8FEE468 -:10EE60000012A1C00A00108B8F92001C3C05080004 -:10EE70008CA5002430B800015300FF3B8FBF002455 -:10EE80003265FFFF36260002000020210E000F55DC -:10EE9000000000000A0010E88FBF002436260002A0 -:10EEA0000E000F55240400800A0010E88FBF0024D4 -:10EEB000020028210E000F553226FFFB0A001159CF -:10EEC000001221C091030001240200011062FEEA39 -:10EED00024040001241000021470FEC50000A021CB -:10EEE00030E300401060FEC38F92001C952B011090 -:10EEF000950900023167FFFF1127FEE08FBF002454 -:10EF00000A00108B000000002403000334820180FB -:10EF1000A043000B0A0011343C108000321400049E -:10EF2000168000033265FFFF361200023250FFFFE9 -:10EF3000020030210A0011B1000020210000202130 -:10EF40000E000F553265FFFF0A0011863210FFFBDD -:10EF5000241FFFFE0A001132011F4024020030214D -:10EF60000E000F55240401000A00118C000000005F -:10EF700027BDFFC8AFB00010AFBF00343C10600C1D -:10EF8000AFBE0030AFB7002CAFB60028AFB500243D -:10EF9000AFB40020AFB3001CAFB20018AFB1001483 -:10EFA0008E0E5000240FFF7F3C06800001CF6824A6 -:10EFB00035AC380C240B0003AE0C5000ACCB000871 -:10EFC0003C010800AC2000200E00174900000000A2 -:10EFD0003C0A0010354980513C066016AE09537C4E -:10EFE0008CC700003C0860148D0500A03C03FFFFA7 -:10EFF00000E320243C02535300051FC2108202622A -:10F0000034C57C008CBE007C8CBF00783C02600064 -:10F01000344420203C05080124A581382406000A38 -:10F020003C170098AF9E0014AF9F00100E0015F221 -:10F030003C11800036F600C03C1900103C18600CF2 -:10F040003C158000AF1953FC363E0180AEB6013C42 -:10F050008E300000320400031080FFFD32050001F5 -:10F0600014A000593206000210C0FFF93C048000D1 -:10F070008C92014024100040AC9200208C8F0148FB -:10F08000000F760231C300701070013E2C780041F1 -:10F090005300000824040060241900201079000E99 -:10F0A0003C1F40003C088000AD1F01780A0012227E -:10F0B000000000001464FFFB3C1F40000E001F66B0 -:10F0C000000000003C1F40003C088000AD1F01789C -:10F0D0000A001222000000008C940148241700044A -:10F0E0003488018000144C02312500FF8C830140DC -:10F0F00010B7017024ABFFFA2D6A000651400013CF -:10F100003C0580008C86014430A400FF30C300FF22 -:10F1100030D500FF2C76000816C0000226A7000498 -:10F1200024070003240C0009108C01A8288D000A74 -:10F1300011A001942413000A24050008108500146E -:10F140008F980018000719C03C0580008CA701B8F3 -:10F1500004E0FFFE24140002AD030000A50900082E -:10F16000A114000B8CB701483C0910003C1F400063 -:10F17000A51700108CA40144AD0400243C088000B5 -:10F18000ACA901B8AD1F01780A00122200000000EE -:10F19000000692020007C8803C040801248482C053 -:10F1A00003247821270E0001324500FF24100001BE -:10F1B000A1F2000014B0FFE3AF8E0018000719C0E1 -:10F1C0000A001260AF85001C8E3401283C068008BE -:10F1D000AE3400208E2A01048E29010094C8004814 -:10F1E000AF8A0000AF8900043103FFFF0E000F4E0D -:10F1F000AF8300083C0708008CE700C010E0002443 -:10F200008F8700003C0C08008D8C00C4258B00010A -:10F210003C010800AC2B00C43C1980008F24012461 -:10F220003C186020AF040014000000003C06800081 -:10F230003C174000ACD70138000000005280FF8A24 -:10F240003206000226870140268500802409FF80BF -:10F2500000E9682400A998240013194030AC007F0D -:10F26000000DB14030F5007F3C0B200035620002FC -:10F27000006C402502D550250142A0250102F82549 -:10F28000ACDF0830ACD408300A0012283206000285 -:10F290003C0E001000EE682415A000A68F83000429 -:10F2A0003C1508008EB500203C16800096D2010E59 -:10F2B00026B3000130EF40003255FFFF3C0108004B -:10F2C000AC33002011E000B6000090213C18002073 -:10F2D00000F8B82412E000B330E280008F990004F7 -:10F2E000241FBFFF00FF382437231000AF87000022 -:10F2F00030EA2000114000B5240CFFBF3C0B000495 -:10F3000000EB302410C00002006C10243462004076 -:10F3100030ED010011A0000EAF8200043C0F002070 -:10F3200000EF702411C000043C16000400F698247D -:10F3300012600135000000009622011E963F011C5C -:10F340003058FFFF001FCC000319B825AF97000C01 -:10F350009628010C8E2440003403FFFF108300C860 -:10F360003105FFFF308901005520000124120010F3 -:10F3700030E41000108000133653000130EA002002 -:10F380001540000A3C0B100000EB302410C0000DAB -:10F390003C0F0BFF3C130C0000F3702435EDFFFF16 -:10F3A00001AE602B11800007365300013C160800A7 -:10F3B0008ED6002C3653000526D200013C010800F1 -:10F3C000AC32002C30F7010016E0000B3C060001C7 -:10F3D0008F880004311840005700000800E62824F8 -:10F3E0003C021F0100E2F8243C19100013F9010A45 -:10F3F00030A302003C06000100E6282414A000A26D -:10F400003C09100000E92024000040211080000782 -:10F410000000A821000766023195000F00155880F2 -:10F420003C0A0801254A82C0016A40218F8D0018DC -:10F4300011A0006802609021148000033C09800044 -:10F440003C080801250882C0952E010E910300009A -:10F450000260302131C4FFFF2485000410600008E1 -:10F460000000B821240F0003106F011E24190002B0 -:10F47000911F000113F9002630E200400015B9C0C9 -:10F480008F89001C51200001366600403C16800028 -:10F490008ECB400031730100126000C530D50004EE -:10F4A0003C0C08008D8C002430D3FFFB3186000417 -:10F4B00014C0010630B2FFFF56A0000136730004ED -:10F4C00002E02021024028210E000F550260302169 -:10F4D00016A0000D0000202136C501803C048000EC -:10F4E0008C8D01B805A0FFFE240F2000240E000221 -:10F4F000A4AF0008A0AE000BA4A000103C051000B3 -:10F50000AC8501B8000020210A001367008010219B -:10F510001040FFDB0000B821952A0110950300027E -:10F520003148FFFF5068FFD60015B9C00A00132FFD -:10F530008F89001C2413BFFF0073282410A000072C -:10F54000240E87FF006E48241520000A3C1200603C -:10F5500000F2782411E00007000000000E000D34D6 -:10F56000000000001040FF323C0680000A001295A7 -:10F570003C1980000E0014CF000000000A00136741 -:10F58000000000000E0014F5000000003C1F4000C9 -:10F590003C088000AD1F01780A0012220000000024 -:10F5A00030E280001040FF528F8300043C050020B1 -:10F5B00000E520241080FF4E3C09FFFF35287FFF27 -:10F5C00000E838240A0012C9346380000A0012D20D -:10F5D000006C10243C0408008C8400381480000265 -:10F5E0002489FFFF000048213C0380009476010E2F -:10F5F00032D7FFFF110000EA26F600043C12080093 -:10F600008E5200301240000A30EA01008F99000447 -:10F6100033384000130000063C030F0000E3402491 -:10F620003C0201000048F82B13E000D232C5FFFF76 -:10F630001140002F3C0C0F0000EC30243C0B02006A -:10F6400010CB002B8F8F000C3C0E080025CE00380D -:10F6500032D2FFFF01E9282400AE682191A90004FD -:10F6600025270004000721C0024028213666000239 -:10F670000E000F55000000000A0013670000102163 -:10F680000A0012EA241200203C0308008C6300D810 -:10F6900002A0282124040080246200013C0108000B -:10F6A000AC2200D80E000F55240600030A00136791 -:10F6B000000010218C840140010028213C038000BF -:10F6C0008C7F01B807E0FFFE2402001CACA4000000 -:10F6D000A0A2000B3C081000AC6801B83C1F400021 -:10F6E0003C088000AD1F01780A00122200000000D3 -:10F6F0003C0308008C6300D02EA5000C001521C02F -:10F70000387800012F1200010245B82416E0FFD618 -:10F7100032D2FFFF26B9FFFC2F240004148000081A -:10F7200000002021386800022D0200010045F82465 -:10F7300013E0000600075A4232D2FFFF00002021EA -:10F74000024028210A0013AA366600020015182B71 -:10F75000016350241540000532D2FFFF001521C07F -:10F76000024028210A0013AA366600020000202168 -:10F77000024028210E000F553266FFFB0A0013E6F7 -:10F78000001521C010930068000768802406000B54 -:10F790001486FE6D000719C00007C0803C190801DF -:10F7A000273982C0031930210A001260A0C000016D -:10F7B00034D5000202E0202130A5FFFF0E000F55D6 -:10F7C00032A6FFFF0A001350000020210007A0808E -:10F7D0003C1F080127FF82C0029F102190570000A4 -:10F7E00012E0FE59000719C0A04000008F8A0018DF -:10F7F0002542FFFF1440FE54AF820018000719C0D5 -:10F800000A001260AF80001C0E000FBC0000000058 -:10F810000A0012E28F8700001460FEF73C06000128 -:10F8200026A900043125FFFF366600023C03800054 -:10F830008C7501B806A0FFFE8F8900083C0A800085 -:10F8400035440180AC8000001120009B2418000387 -:10F8500024AC0012012C582B11600097000000000E -:10F86000947201203C138000240F001A324EFFFFD7 -:10F87000366A018030ED4000A14F000B11A00091CD -:10F8800025C3FFFE0123B02B16C0008F2417FFFEF7 -:10F8900035080001A5430014AF880004241FBFFFF2 -:10F8A000011FC82424080002A7C8000CA7C5000E29 -:10F8B000A7C60008A7D90026A7C700103C0710005C -:10F8C000AE2701B80A0013670000102124040100CC -:10F8D000024028210E000F55026030210A00133C1F -:10F8E0000000000091030001241500011075FF06BF -:10F8F00024040001241200021472FEE10000B82169 -:10F9000030F6004052C0FEDF8F89001C95270110A1 -:10F910009518000230F7FFFF1317FEFB0000B82117 -:10F920000A00132F8F89001C3C120801265282C046 -:10F9300001B2702100067A02A1CF00013C0B6000E9 -:10F940008D6318202410000100F098043C05080184 -:10F9500024A582C20073B02501A5A8210006640277 -:10F96000000719C0A6AC0000AD7618200A0012618D -:10F970003C058000366600020E000F55240400800E -:10F980000A001367000010210003A080028698215E -:10F990008E7200043C1160000A00120F02512821EF -:10F9A0008C66400030D5010012A0003730EC010019 -:10F9B0003C1508008EB50024118000133277000436 -:10F9C0003C050F0000E568243C07020011A7000E6B -:10F9D0008F84000C3C180800271800380260302182 -:10F9E000008990240258782191EE000432C5FFFF6F -:10F9F0003272FFFB25C90004000921C00E000F551B -:10FA00002413FFFE02B3A8242419000112B9003008 -:10FA100032A200011040000732A800040240302149 -:10FA2000000020210E000F5532C5FFFF3252FFFBB0 -:10FA300032A80004110000048F8B0000316A080016 -:10FA40005540002B32C5FFFF16E0FEC60000102116 -:10FA50003C16800036C401803C0580008CA301B8B0 -:10FA60000460FFFE240C200024060002A48C000881 -:10FA7000A086000BA48000103C151000ACB501B8A6 -:10FA80000A001367000010213C0D08008DAD002412 -:10FA900031A7000150E0FEB30000102132C5FFFF86 -:10FAA00036660002000020210E000F550000000005 -:10FAB0000A00136700001021A3D8000B0A001436B7 -:10FAC000241FBFFF2417FFFE0A001434011740242F -:10FAD0003257000416E0000332C5FFFF365F000214 -:10FAE00033F2FFFF024030210A0014B80000202149 -:10FAF000024030210E000F55240401000A0014A01A -:10FB0000000000003C0380008C6401003082003E55 -:10FB10001440000800000000AC6000488C66010042 -:10FB200030C507C010A0000500000000AC60004C0C -:10FB3000AC60005003E0000824020001AC600054F7 -:10FB4000AC6000408C6801003107380010E0FFF91C -:10FB5000000000002402000103E00008AC60004443 -:10FB60003C03900034620001008220253C038000A9 -:10FB7000AC6400208C65002004A0FFFE00000000A3 -:10FB800003E00008000000003C0280003443000154 -:10FB90000083202503E00008AC44002027BDFFD8E7 -:10FBA000AFB100143C048000AFBF0020AFB3001C15 -:10FBB000AFB20018AFB000108C9201408C90014899 -:10FBC0002402000E00108C02322300FF1062005944 -:10FBD000020428242866000F10C00013286A00378A -:10FBE000240700061067008E286800075100002DCA -:10FBF00024040009106000783C06800024090001FC -:10FC0000106900B0000000000000000D8FBF002050 -:10FC10008FB3001C8FB200188FB100148FB000108A -:10FC200003E0000827BD002811400059240D0038CA -:10FC3000286B0035116000053C058000240C001F76 -:10FC4000146CFFF1000000003C0580008CB801B886 -:10FC50000700FFFE34B90180AF320000241F00010D -:10FC6000241200023C021000AF200004A73100085B -:10FC7000A33F000AA332000BA7300010AF200024DE -:10FC8000AF200028ACA201B88FBF00208FB3001CAA -:10FC90008FB200188FB100148FB0001003E000087D -:10FCA00027BD0028106400232405000B1465FFD62F -:10FCB0003218FFFF170000203C0580008F93FED014 -:10FCC000927F000533F900041720FFCF00000000E9 -:10FCD0000E0014E602402021926900050240202116 -:10FCE000352800040E0014F0A26800059267000594 -:10FCF00030E2000414400002000000000000000D8B -:10FD0000926B000024060020316A00FF1546000AAD -:10FD10003C0580008CA401B80480FFFE34AD018056 -:10FD2000240E00053C0C1000ADB20000A1AE000B8B -:10FD3000ACAC01B83C0580008CA301B80460FFFEA8 -:10FD400034AF018024130002ADF20000ADF20004D4 -:10FD5000A5F10008A1F3000AA1F3000BA5F0001023 -:10FD6000ADE000248CB101443C101000ADF100283E -:10FD7000ACB001B88FBF00208FB3001C8FB2001849 -:10FD80008FB100148FB0001003E0000827BD0028D9 -:10FD9000106DFFAD240E0080146EFF9B000000006C -:10FDA0003C0580008CA301B80460FFFE34AF0180E5 -:10FDB00024120002A1F2000BA5F10008A5F000102A -:10FDC0008CB301443C021000A5F30012ACA201B8B0 -:10FDD0000A0015318FBF00208CC301B80460FFFEFC -:10FDE00034D30180AE720000AE6000042412000122 -:10FDF000A671000824110002A272000AA271000B71 -:10FE0000A67000108CD001443C0F1000AE7000248E -:10FE1000AE600028ACCF01B80A00156C8FBF00207F -:10FE20003C0380008C6601B804C0FFFE3462018090 -:10FE30003C06080190C68300AC52000010C00003CD -:10FE4000000038213C0708018CE783083C0580004E -:10FE500034AA01802404000234CC0001AC47000421 -:10FE6000A5510008A14C000AA144000BA5500010A8 -:10FE70008CAB01440000202101402821AD4B00241F -:10FE800010C000038FBF00203C0408018C84830451 -:10FE90008FB3001C8FB200188FB100148FB0001008 -:10FEA0003C0E10003C0D800027BD0028ACA40028AB -:10FEB000ADAE01B83C010801A020830003E00008BA -:10FEC0000000000010A0000B3C0680008C9801444C -:10FED000241900023C010801A03983003C010801FB -:10FEE000AC3283083C010801AC3883040A00156C6D -:10FEF0008FBF00208CDF01B807E0FFFE34C7018010 -:10FF000024090002ACF20000ACF20004A4F10008E5 -:10FF1000A0E9000AA0E9000BA4F00010ACE0002466 -:10FF20008CC801443C021000ACE80028ACC201B807 -:10FF30000A00156C8FBF002027BDFFE8AFBF00107F -:10FF40000E000F4E000000003C0280008FBF00102A -:10FF500000002021AC4001800A00101027BD0018CD -:10FF60003084FFFF30A5FFFF10800007000018213C -:10FF70003082000110400002000420420065182178 -:10FF80001480FFFB0005284003E0000800601021FA -:10FF900010C00007000000008CA2000024C6FFFF74 -:10FFA00024A50004AC82000014C0FFFB24840004DC -:10FFB00003E000080000000010A0000824A3FFFFD9 -:10FFC000AC86000000000000000000002402FFFFDB -:10FFD0002463FFFF1462FFFA2484000403E0000896 -:10FFE0000000000027BDFFE8AFBF0014AFB0001055 -:10FFF0000E0014E6008080213C04800834830080D9 -:020000040001F9 -:10000000906500250200202134A200200E0014F08B -:10001000A0620025020020218FBF00148FB00010C5 -:100020000A000C9E27BD00183C03800027BDFFF886 -:1000300034620180AFA20000308C00FF30AD00FFC1 -:1000400030CE00FF3C0B80008D6401B80480FFFEC1 -:10005000000000008FA900008D6801288FAA000011 -:100060008FA700008FA400002405000124020002D5 -:10007000A085000A8FA30000359940003C051000C0 -:10008000A062000B8FB800008FAC00008FA60000AC -:100090008FAF000027BD0008AD280000AD40000470 -:1000A000AD800024ACC00028A4F90008A70D001002 -:1000B000A5EE001203E00008AD6501B83C0680081B -:1000C00027BDFFE834C50080AFBF001090A700092E -:1000D0002402001230E300FF1062000B0080302188 -:1000E0008CA8005000882023048000088FBF0010D7 -:1000F0008CAA0034240400390000282100CA4823B7 -:1001000005200005240600128FBF00102402000104 -:1001100003E0000827BD00180E00161800000000BC -:100120008FBF00102402000103E0000827BD001863 -:1001300027BDFFC8AFB1002C00A08821AFB20030AE -:1001400027A500100080902102202021AFBF00349D -:10015000AFB000280E000CA8AFA000101440009B08 -:100160003C07800834E400809086000830C5000811 -:1001700014A000698FA700103C1880083710008079 -:10018000920F000831EE000815C000022408000399 -:10019000000040213C0B800891650011916A00121B -:1001A000356600808CDF0054314900FF0128202192 -:1001B00030A300FF000410800062282100BFC82B7C -:1001C000132000080000000094D0005C8CCF005485 -:1001D000320DFFFF01E5702301AE602B118000940A -:1001E0000000000094D9005C3323FFFF30FF0004BF -:1001F00013E00074000830808FA8001C0068102BEA -:100200005040004F30E30004006610232C4600806D -:1002100010C0000200408021241000800E0014E66F -:10022000024020213C03800834660080240700013E -:10023000ACC7000C90C8000800106840346701008B -:10024000311F007FA0DF00088E390004273800012D -:10025000ACD80030A4D0005C8CCF003C9630000EAF -:1002600001F07021ACCE00208CCC003C018D5821D7 -:10027000ACCB001C8E2A0004ACEA00008E290008DA -:10028000ACE900048FA5001030A4000854800032AF -:1002900093A60020A0C0004E90C9004E2402FFDFAC -:1002A0003C188008A0E9000890C50008370D0080C0 -:1002B000240A005000A22024A0C400088E3900089F -:1002C000ADB900388F0F00148DB0003001F07021EF -:1002D000ADAE003491AC0000318B00FF116A002CF0 -:1002E000264501000E0014F00240202124040038AD -:1002F000000028210E0016182406000A8FBF0034C3 -:100300008FB200308FB1002C8FB000282402000182 -:1003100003E0000827BD003830E801001100003D6F -:100320008FA300148C8A0058006A48230520FF938D -:100330003C188008AC8300580A00166C8FA7001088 -:10034000240702181060FFB100E610238FA2001CE2 -:100350000A001691004610233C188008370D0080D3 -:10036000A0E600088E390008240A0050ADB9003814 -:100370008F0F00148DB0003001F07021ADAE00344D -:1003800091AC0000318B00FF156AFFD626450100B5 -:100390002406FF8000A610243C098000AD2200281E -:1003A0008E27000830A3007F3C04800C0064F821F5 -:1003B000AFE700D08E280008AF9F00280A0016C7BC -:1003C000AFE800D40A00168E2C6202188E230008B3 -:1003D0003C04800834820080AC4300540240202159 -:1003E0000E001607AC400030240400382405008DB0 -:1003F0000E001618240600128FBF00348FB2003092 -:100400008FB1002C8FB000282402000103E0000807 -:1004100027BD0038AC800058908C0008240DFFF7F1 -:10042000018D5824A08B00080A00166C8FA70010BD -:100430008CD800540A0016890305182327BDFFE84D -:10044000AFBF001090A6000D30C7001010E0000CE8 -:10045000008040213C0280088C4400048CA30008EA -:100460001064000830C9000530C5000510A0001C4C -:100470008FBF00102402000103E0000827BD001810 -:1004800030C900051120001030CB001210E0FFF938 -:100490008FBF00103C0880088CA700088D06000460 -:1004A00014E6FFF524020001240400382405008D21 -:1004B0000E001618240600128FBF0010240200013F -:1004C00003E0000827BD0018240A0012156AFFE99E -:1004D0008FBF0010010020210A00165A27BD001806 -:1004E000000020210A000D1A27BD00183C05080055 -:1004F00024A55D683C04080024847B343C02080089 -:1005000024425D70240300063C010801AC258310E1 -:100510003C010801AC2483143C010801AC2283187F -:100520003C010801A023831C03E000080000000038 -:1005300003E00008240200013C028000308800FF34 -:10054000344701803C0680008CC301B80460FFFE84 -:10055000000000008CC501282418FF803C0D800A93 -:1005600024AF010001F8702431EC007FACCE0024F0 -:10057000018D2021ACE50000948B00DA3509600084 -:1005800024080002316AFFFFACEA000424020001E3 -:10059000A4E90008A0E8000BACE000243C07100030 -:1005A000ACC701B8AF84002803E00008AF85005C49 -:1005B0008C9800048F8C00282409FFBF0305782342 -:1005C000AC8F0004918E00C42403FFEF31CD007F77 -:1005D000A18D00C48C8B00208F860028A780004C42 -:1005E000356A0002A4C000ACAC8A002090C800C4E8 -:1005F00001093824A0C700C48F840028AC8000DC27 -:10060000908500C400A3102403E00008A08200C469 -:100610003C028000344501803C0480008C8301B89A -:100620000460FFFE8F89005C2407608324060002BB -:10063000ACA900008C880124ACA80004A4A7000881 -:10064000A0A6000B3C05100003E00008AC8501B833 -:10065000938800388F8900508F82002830C600FFB1 -:100660000109382330E900FF0122182130A500FFDD -:100670002468007810C0000201243821008038214D -:1006800030E400031480000330AA00031140000D81 -:10069000312B000310A000090000102190ED000094 -:1006A000244E000131C200FF0045602BA10D000067 -:1006B00024E700011580FFF92508000103E0000888 -:1006C000000000001560FFF30000000010A0FFFB19 -:1006D000000010218CF8000024590004332200FF90 -:1006E0000045782BAD18000024E7000415E0FFF961 -:1006F0002508000403E0000800000000938500388E -:10070000938800488F870050000432003103007F37 -:1007100000E5102B30C47F001040000F0064282536 -:100720008F8400283C0980008C8A00DCAD2A00A45C -:100730003C03800000A35825AC6B00A08C6C00A08B -:100740000580FFFE000000008C6D00ACAC8D00DC6D -:1007500003E000088C6200A80A0017DA8F840028E2 -:10076000938800493C02800000805021310300FE44 -:10077000A383004930ABFFFF30CC00FF30E7FFFF21 -:10078000344801803C0980008D2401B80480FFFEBC -:100790008F8D005C24180016AD0D00008D22012401 -:1007A0008F8D0028AD0200048D590020A507000898 -:1007B000240201B4A119000AA118000B952F0120F1 -:1007C0008D4E00088D4700049783004C8D590024FE -:1007D00001CF302100C7282100A320232418FFFFC8 -:1007E000A504000CA50B000EA5020010A50C00121C -:1007F000AD190018AD18002495AF00D83C0B1000BF -:100800002407FFF731EEFFFFAD0E00288DAC00741A -:10081000AD0C002CAD2B01B88D46002000C728245C -:1008200003E00008AD4500208F8800280080582193 -:1008300030E7FFFF910900C63C02800030A5FFFFB2 -:10084000312400FF00041A000067502530C600FF65 -:10085000344701803C0980008D2C01B80580FFFEE3 -:100860008F82005C240F0017ACE200008D39012458 -:10087000ACF900048D780020A4EA0008241901B422 -:10088000A0F8000AA0EF000B952301208D6E000850 -:100890008D6D00049784004C01C35021014D6021EF -:1008A00001841023A4E2000CA4E5000EA4F90010BA -:1008B000A4E60012ACE000148D780024240DFFFFA4 -:1008C000ACF800188D0F006CACEF001C8D0E0068AA -:1008D0003C0F1000ACEE0020ACED0024950A00AEF9 -:1008E000240DFFF73146FFFFACE60028950C0070A1 -:1008F0009504007231837FFF0003CA003082FFFF3E -:100900000322C021ACF8002CAD2F01B8950E007267 -:100910008D6A002000AE3021014D2824A50600720A -:1009200003E00008AD6500203C02800034460180F1 -:100930003C0580008CA301B80460FFFE2409001868 -:10094000ACC40000A0C9000B8F8800283C04100034 -:10095000950700AEA4C70010ACC0003003E000084B -:10096000ACA401B83C028000344501803C04800006 -:100970008C8301B80460FFFE8F8A003424060019BE -:100980009549001C3128FFFF000839C0ACA70000C2 -:10099000A0A6000B3C05100003E00008AC8501B8E0 -:1009A0008F87003C0080402130C400FF3C0680005F -:1009B0008CC201B80440FFFE8F89005C938300580D -:1009C00034996000ACA90000A0A300058CE20010DF -:1009D000240F00022403FFF7A4A20006A4B9000814 -:1009E0008D180020A0B8000AA0AF000B8CEE00000C -:1009F000ACAE00108CED0004ACAD00148CEC001C0F -:100A0000ACAC00248CEB0020ACAB00288CEA002CB2 -:100A10003C071000ACAA002C8D090024ACA90018DA -:100A2000ACC701B88D05002000A3202403E0000816 -:100A3000AD040020938500582403000127BDFFE882 -:100A400000A330042CA20020AFB00010AFBF0014F0 -:100A500000C01821104000132410FFFE3C070800BE -:100A60008CE7319000E610243C08800035050180B9 -:100A700014400005240600848F890028240A0004FD -:100A80002410FFFFA12A00EC0E00187600000000E1 -:100A9000020010218FBF00148FB0001003E0000887 -:100AA00027BD00183C0608008CC631940A0018A81F -:100AB00000C310248F87003427BDFFE0AFB20018B9 -:100AC000AFB10014AFB00010AFBF001C30D000FFBA -:100AD00090E6000D00A088210080902130C5007FA5 -:100AE000A0E5000D8F8500288E2300188CA200C081 -:100AF0001062002E240A000E0E00189BA38A0058D4 -:100B00002409FFFF104900222404FFFF52000020A7 -:100B1000000020218E2600003C0C001000CC582440 -:100B2000156000393C0E000800CE682455A0003F37 -:100B3000024020213C18000200D880241200001F2F -:100B40003C0A00048F8700348CE200148CE3001010 -:100B50008CE500140043F82303E5C82B132000059F -:100B6000024020218E24002C8CF1001010910031C5 -:100B70000240202124020012A38200580E00189B7C -:100B80002412FFFF105200022404FFFF0000202166 -:100B90008FBF001C8FB200188FB100148FB00010EF -:100BA0000080102103E0000827BD002090A800C4A9 -:100BB000350400200A0018D1A0A400C400CA4824AB -:100BC0001520000B8F8B00348F8D00348DAC0010FE -:100BD0001580000B024020218E2E002C51C0FFEC0E -:100BE00000002021024020210A0018EC24020017F6 -:100BF0008D66001050C0FFE6000020210240202139 -:100C00000A0018EC240200110240202124020015E1 -:100C10000E00189BA3820058240FFFFF104FFFDC2B -:100C20002404FFFF0A0018DB8E2600000A001912B8 -:100C3000240200143C08000400C8382450E0FFD40B -:100C400000002021024020210A0018EC2402001399 -:100C50008F86002827BDFFE0AFB10014AFBF00189A -:100C6000AFB0001090C300C430A500FF3062002078 -:100C700010400008008088218CCB00C02409FFDFD1 -:100C8000256A0001ACCA00C090C800C4010938241C -:100C9000A0C700C414A000403C0C80008F84002832 -:100CA000908700C42418FFBF2406FFEF30E3007FC5 -:100CB000A08300C4979F004C8F8200508F8D002826 -:100CC00003E2C823A799004CA5A000AC91AF00C4D3 -:100CD00001F87024A1AE00C48F8C0028A18000C749 -:100CE0008F8A0028A5400072AD4000DC914500C409 -:100CF00000A65824A14B00C48F9000248F8400507C -:100D00009786004C0204282110C0000FAF850024F4 -:100D1000A38000483C0780008E2C000894ED012041 -:100D20008E2B0004018D5021014B802102062023CF -:100D30003086FFFF30C8000F390900013131000152 -:100D400016200009A3880048938600388FBF00183A -:100D50008FB100148FB0001027BD0020AF85005464 -:100D600003E00008AF86005000C870238FBF001852 -:100D7000938600388FB100148FB0001034EF0C0050 -:100D8000010F282127BD0020ACEE0084AF85005460 -:100D900003E00008AF860050359001800200282152 -:100DA0000E001876240600828F840028908600C4E6 -:100DB00030C5004050A0FFBAA38000588F85003C8A -:100DC0003C0680008CCD01B805A0FFFE8F89005C39 -:100DD0002408608224070002AE090000A60800086B -:100DE000A207000B8CA300083C0E1000AE030010FD -:100DF0008CA2000CAE0200148CBF0014AE1F0018B1 -:100E00008CB90018AE1900248CB80024AE18002844 -:100E10008CAF0028AE0F002CACCE01B80A001936FA -:100E2000A38000588F8A002827BDFFE0AFB10014CF -:100E3000AFB000108F880050AFBF00189389002C0E -:100E4000954200AC30D100FF0109182B00808021B1 -:100E500030AC00FF3047FFFF000058211460000352 -:100E6000310600FF01203021010958239783004CEF -:100E70000068202B1480001B000000001068004355 -:100E8000240A0001118A004834E708803165FFFF19 -:100E90000E001818020020210E0018588F84005CE4 -:100EA0008F840028948D007025AC0001A48C007004 -:100EB000948B00703C0608008CC6318831677FFF38 -:100EC00010E6004F0000000002002021022028212F -:100ED0008FBF00188FB100148FB000100A001922C4 -:100EE00027BD0020914400C42406FF800086882589 -:100EF000A15100C49784004C3088FFFF1100001CF2 -:100F00009389002C8F8E00282419EFFF008BF82383 -:100F100095D800AC0168682B33E900FF03197824E9 -:100F2000A5CF00AC51A0002A010058218E05002059 -:100F30002408FFFB2403000100A81024AE020020B7 -:100F40001183002534E78000020020213165FFFF76 -:100F50000E00181801203021978B004C8F8700500D -:100F6000A780004C00EB8023AF9000509389002CA9 -:100F70008F8C00288FBF00188FB100148FB0001025 -:100F800027BD002003E00008A18900C78E080020CB -:100F90002409FFFB34E7800001092824AE05002066 -:100FA000158AFFBA34E70880020020210E0017E6F8 -:100FB0003165FFFF02002021022028218FBF001889 -:100FC0008FB100148FB000100A00192227BD002035 -:100FD0000A0019D900004821020020213165FFFFD5 -:100FE0000E0017E601203021978B004C8F870050B0 -:100FF000A780004C00EB80230A0019E9AF90005055 -:1010000094890070240A8000012A4024A48800707A -:10101000908500709099007030A200FF000219C204 -:101020000003F827001FC1C0332F007F01F870258F -:10103000A08E00700A0019C1020020218F880028AC -:1010400024030001910A0078910500C72509007862 -:101050003147003F24E6FFE000C318042CC2002003 -:1010600030670019A385002C1040001AAF89003C9E -:101070003C0A8000354B00022405000124060001D3 -:1010800014E00016006B1024000028211440000F0B -:10109000306300201060000F240500018D060074ED -:1010A0008D1900742403FF8000C3102400027940CE -:1010B0003338007F01F868253C0E100001AE602532 -:1010C000AD4C083091280001310600010A00199743 -:1010D0000000000003E00008000000008D0F007415 -:1010E0008D0D00742418FF8001F87024000E41401B -:1010F00031AC007F010C50253C0B1000014B382512 -:101100003C0980000A001997AD27083027BDFFD899 -:10111000AFB000108F90003CAFB40020AFB100140E -:10112000AFBF0024AFB3001CAFB200188E05001093 -:101130003C0208008C4231B08F86004030A73FFF50 -:1011400000E2182B8CD20014008088218CD3002060 -:10115000106000070000A02190CB000D240AFF8042 -:10116000014B4824312800FF1500000C0005638264 -:10117000022020212411000DA39100588FBF0024CC -:101180008FB400208FB3001C8FB200188FB10014F1 -:101190008FB000100A00189B27BD0028318500037E -:1011A00054A0FFF40220202194CF001C8F8E002831 -:1011B0008E070028A5CF00D88CCD0010024D30231B -:1011C00010E6005C2402001F0E00189BA38200584A -:1011D000241FFFFF105F004E2404FFFF8F83004495 -:1011E0008F880034026398218D0900100123102399 -:1011F0008F830020AD020010AD1300208C670074B7 -:1012000000F3202B14800062022020218F860040F2 -:101210008E0C00248CC5002411850007022020219B -:10122000240E001C0E00189BA38E0058240DFFFFF7 -:10123000104D00372404FFFF8F8400348C98002465 -:10124000270F0001AC8F0024127200448F990020F8 -:101250008F320074125300413C0A00808E09000056 -:10126000012A10241440003A000000008E040014EB -:101270002412FFFF10920006240B001B02202021E5 -:101280000E00189BA38B0058105200212404FFFF6E -:101290008E0300003C0C0001006C282410A00013F9 -:1012A0003C0600800066A024168000090200282168 -:1012B00002202021240E001A0E00189BA38E005835 -:1012C000240DFFFF104D00122404FFFF020028210F -:1012D000022020210E0018BB240600012410FFFF6D -:1012E0002404FFFF1050000A241400018F8F0034E3 -:1012F000022020210280302195F2003424050001D3 -:10130000265800010E001997A5F80034000020218E -:101310008FBF00248FB400208FB3001C8FB2001841 -:101320008FB100148FB000100080102103E000087E -:1013300027BD00288F83004400E3C8210259C02B39 -:101340001300FFA88F8800340A001A8024020018B6 -:10135000AC8000200A001AAA8E0400148E1F000020 -:101360003C07008003E798241660FFF92408001A60 -:10137000022020210E00189BA38800582403FFFFA1 -:101380001443FFBA2404FFFF0A001AD38FBF0024BE -:10139000240B001D0E00189BA38B0058240AFFFF8E -:1013A000144AFF9A2404FFFF0A001AD38FBF0024B7 -:1013B0008F85002827BDFFD8AFB3001CAFB200183F -:1013C000AFB10014AFB00010AFBF002090A700C4B1 -:1013D0008F90003C2412FFFF34E200409206000090 -:1013E000A0A200C48E030010008098211072000695 -:1013F00030D1003F2408000D0E00189BA388005830 -:10140000105200252404FFFF8F8A00288E0900183F -:101410008D4400C01124000702602021240C000E1E -:101420000E00189BA38C0058240BFFFF104B001AD2 -:101430002404FFFF24040020122400048F8D0028C0 -:1014400091AF00C435EE0020A1AE00C48F850044EA -:1014500010A00019000000001224004A8F980028F4 -:101460008F92FED0971000709651000A52300048BB -:101470008F9300303C1F08008FFF318C03E5C82B91 -:101480001720001E02602021000028210E0019975D -:1014900024060001000020218FBF00208FB3001C14 -:1014A0008FB200188FB100148FB00010008010218F -:1014B00003E0000827BD00285224002A8E050014EE -:1014C0008F840028948A007025490001A489007047 -:1014D000948800703C0208008C42318831077FFFFD -:1014E00010E2000E00000000026020210E00192210 -:1014F000240500010A001B34000020212402002DD5 -:101500000E00189BA38200582403FFFF1443FFE141 -:101510002404FFFF0A001B358FBF00209499007040 -:10152000241F800024050001033FC024A4980070FC -:1015300090920070908E0070325100FF001181C2B5 -:1015400000107827000F69C031CC007F018D58252D -:10155000A08B00700E001922026020210A001B34AB -:10156000000020212406FFFF54A6FFD68F84002808 -:10157000026020210E001922240500010A001B34FC -:1015800000002021026020210A001B4E2402000AD4 -:101590002404FFFD0A001B34AF9300508F880028FD -:1015A00027BDFFE8AFB00010AFBF0014910A00C420 -:1015B0008F87003C00808021354900408CE6001078 -:1015C000A10900C43C0208008C4231B030C53FFF85 -:1015D00000A2182B106000078F850040240DFF80AB -:1015E00090AE000D01AE6024318B00FF1560000845 -:1015F0000006C382020020212403000D8FBF0014C7 -:101600008FB0001027BD00180A00189BA383005854 -:1016100033060003240F000254CFFFF702002021FD -:1016200094A2001C8F85002824190023A4A200D8AE -:101630008CE8000000081E02307F003F13F90035DF -:101640003C0A00838CE800188CA600C01106000834 -:10165000000000002405000E0E00189BA385005812 -:101660002407FFFF104700182404FFFF8F85002880 -:1016700090A900C435240020A0A400C48F8C00349D -:10168000918E000D31CD007FA18D000D8F83004420 -:101690001060001C020020218F8400408C980010F4 -:1016A0000303782B11E0000D2419001802002021FB -:1016B000A39900580E00189B2410FFFF1050000241 -:1016C0002404FFFF000020218FBF00148FB0001002 -:1016D0000080102103E0000827BD00188C86001050 -:1016E0008F9F00340200202100C31023AFE20010BE -:1016F000240500010E001997240600010A001BC0F2 -:10170000000020210E001922240500010A001BC040 -:1017100000002021010A5824156AFFD98F8C00345B -:10172000A0A600EC0A001BADA386004A27BDFFD887 -:10173000AFB000108F90003CAFB20018AFBF0020D8 -:10174000AFB3001CAFB100148E1100103C030800B1 -:101750008C6331B032253FFF00A3102B10400008EE -:10176000008090218F8600402409FF8090CA000DE0 -:10177000012A4024310700FF14E0000B00116B82A6 -:10178000024020212412000DA39200588FBF002098 -:101790008FB3001C8FB200188FB100148FB00010EF -:1017A0000A00189B27BD002831AC0003240B000160 -:1017B000558BFFF40240202190CF000D31EE000840 -:1017C00011C000608F9300441660000924020027B6 -:1017D0008E19000C8CD80020173800052402002038 -:1017E0008E0200088CDF0024105F004024020020DD -:1017F0000E00189BA38200582406FFFF10460033FA -:101800002404FFFF8F990034240AFFF73C13800E55 -:101810009329000D2404FF803C0D8000012AF82448 -:10182000A33F000D8F9900203C0808008D0831ACC3 -:101830008F83005C972700788F9F0034010310216D -:1018400030E57FFF000530400046782131F8007F09 -:101850000313602101E47024ADAE002CA5910000BB -:101860008FEB0028256A0001AFEA00288FE3002CE7 -:101870008E09002C00694021AFE8002C8E07002C57 -:10188000AFE700308E050014AFE5003497E6003A6C -:1018900024C20001A7E2003A973300783C10080008 -:1018A0008E1031B02663000130717FFF12300027A7 -:1018B000006030218F8F002002402021240500018C -:1018C0000E001922A5E60078000020218FBF00201D -:1018D0008FB3001C8FB200188FB100148FB00010AE -:1018E0000080102103E0000827BD00288E050014A9 -:1018F0002413FFFF10B3001D8F8300288E080018EB -:101900008C6700C0150700092402000E8E0A00240F -:101910008CC9002815490005240200218E070028E3 -:101920008CCB002C10EB00132402001F0E00189B20 -:10193000A38200581453FFB32404FFFF0A001C4283 -:101940008FBF00200A001C0A24020024240E8000FD -:10195000006E682431ACFFFF000C5BC2317100FFE8 -:10196000001180270A001C3B001033C00A001C59DC -:10197000240200258E05002C10A0FFEC2402002379 -:101980008F8E00208DCD007401A5602B1580FFE7A0 -:10199000240200268CCF001400A7C02101F8202BC0 -:1019A0001080FF998F990034024020210A001C59B1 -:1019B0002402002227BDFFE0AFB000108F90003C52 -:1019C000AFB10014AFBF00188E0500103C03080033 -:1019D0008C6331B00080882130A43FFF0083102B3E -:1019E000104000078F8600402409FF8090CA000D38 -:1019F000012A4024310700FF14E000098F8B0044C6 -:101A00002410000D02202021A39000588FBF001841 -:101A10008FB100148FB000100A00189B27BD002062 -:101A2000116000070005CB828F8F00288F8EFED0BB -:101A300095EC007095CD000A11AC00578F850030F1 -:101A4000333800031700001000000000921F00024E -:101A500013E00041000000008E06002450C0000F7B -:101A600092040003022020212402000F0E00189B84 -:101A7000A38200582408FFFF144800072404FFFF36 -:101A80000A001CD58FBF001890C7000D30E3000876 -:101A90001060003702202021920400032409000274 -:101AA000308A00FF15490005308500FF8F8B004408 -:101AB0005160003102202021308500FF38B800102D -:101AC0002CAF00012F0E000102002821022020214E -:101AD0000E0018BB01EE30252410FFFF1050000E41 -:101AE0002404FFFF8F830044106000170220202190 -:101AF0003C1F08008FFF318C03E3C82B5720000CDC -:101B00002411002D02202021000028210E00199709 -:101B100024060001000020218FBF00188FB100149F -:101B20008FB000100080102103E0000827BD0020C6 -:101B30000E00189BA39100581450FFF62404FFFFD9 -:101B40000A001CD58FBF00180E00192224050001C1 -:101B50000A001CD4000020218CC400248E02002422 -:101B60005444FFC1022020210A001CB59204000346 -:101B70000A001CA924020010240D002C0E00189B42 -:101B8000A38D0058240CFFFF104CFFE32404FFFF3B -:101B90000A001CBC920400032404FFFD0A001CD4AC -:101BA000AF85005030A500FF2406000124A90001E4 -:101BB00000C9102B1040000C00004021240A000135 -:101BC00000A61823308B000124C60001006A3804E7 -:101BD000000420421160000200C9182B01074025B3 -:101BE0001460FFF800A6182303E00008010010218C -:101BF00027BDFFD8AFB000188F90003CAFB1001CDC -:101C0000AFBF00202403FFFF2411002FAFA300105B -:101C10009206000024050008261000010066202618 -:101C20000E001CF7308400FF00021E003C021EDC88 -:101C300034466F410A001D1F0000102110A000094A -:101C4000008018212445000130A2FFFF2C45000828 -:101C50000461FFFA000320400086202614A0FFF94B -:101C6000008018210E001CF7240500208FA300100F -:101C70002629FFFF313100FF00034202240700FF45 -:101C80001627FFE20102182600035027AFAA00140E -:101C9000AFAA00100000302127A8001027A70014C9 -:101CA00000E6782391ED000324CE000100C86021F6 -:101CB00031C600FF2CCB00041560FFF9A18D000098 -:101CC0008FA200108FBF00208FB1001C8FB00018B2 -:101CD00003E0000827BD00289383003827BDFFE0FC -:101CE00024020034AFB10014AFB00010AFBF001C2D -:101CF000AFB20018008080211062006500A088212A -:101D000092240004148000488F880028A380002CAF -:101D10008E2500048D0700C83C0600FF34C3FFFF7A -:101D200000A3302400E6102B14400050AF8600447E -:101D30008F870050978A004CAF87003001474023BF -:101D400010C00034A788004C8F99002030DF0003BA -:101D5000001F20239332007C309000030206702184 -:101D60000012C082331200010012788001CF682176 -:101D7000310CFFFF018D582B5160005F8F880028C8 -:101D80008F8900248F8200541049007B3C033F015F -:101D90008E2600003C11250000C3282414B10078D1 -:101DA0008F84003C8F8A003C8F8800288D4B000078 -:101DB000AD0B00788D470010AD0700888F8700506D -:101DC0008F860044938C002C01276821020628216D -:101DD000020C1821A383002C950900ACAF8D0024C0 -:101DE00035301000A51000AC1640005024720004DD -:101DF000AF850050000020218FBF001C8FB200185B -:101E00008FB100148FB000100080102103E0000893 -:101E100027BD00208F840024AF8000500087402120 -:101E20000A001D8BAF880024241F000CA39F0058BC -:101E30000E00189B020020212419FFFF1059FFEE0D -:101E40002404FFFF8F880028A380002C8E25000427 -:101E50008D0700C83C0600FF34C3FFFF00A33024F9 -:101E600000E6102B1040FFB2AF8600440200202194 -:101E700024090019A38900580E00189B2410FFFFA5 -:101E80001050FFDD2404FFFF0A001D5A8F86004416 -:101E90008F8400288F87003C8CF20030908600C42D -:101EA00030C5001014A000108F8300502C6800056E -:101EB0001500002600000000908A00C4246BFFFC7F -:101EC0003149001015200008316400FF8F8D005447 -:101ED0008F8C002411AC0004388F000131EE00011A -:101EE00015C0002F000000000E001D0A00000000B9 -:101EF0000A001DE2000000008F890024938C002C52 -:101F00000127682102062821020C1821A383002C36 -:101F1000950900ACAF8D002435301000A51000AC41 -:101F20005240FFB4AF85005024720004A392002CED -:101F3000950F00AC24B80004AF98005035EE200097 -:101F4000A50E00AC0A001D8C000020218C8200DC54 -:101F50001242FF6B0200202124180005A3980058AC -:101F60000E00189B2412FFFF1452FF652404FFFF8C -:101F70000A001D8D8FBF001C0A001DCD8F88002810 -:101F800030E500FF0E0017A2000030218F880028E6 -:101F90008F8700508F8900240A001D7F8F860044A0 -:101FA0000E0017CD000000000A001DE20000000036 -:101FB0009383004A27BDFFE024020002AFB200185D -:101FC000AFB10014AFBF001CAFB00010008088217B -:101FD000106200B6000090219783004C8F8500505E -:101FE0003066FFFF00C5202B1480005B938700380C -:101FF0003C0880009504012010E500528F8A0024DF -:102000008F84005430A500FF0E0017A224060001A3 -:102010008F82005C3C0B80003C1F4080244E017886 -:1020200031D00078240FFF80021F60253578090029 -:1020300031D9000701CF6824AD6D08000338802135 -:10204000AD6C081002202021020028210E001D4442 -:10205000AF90003C2403FFFF104300332404FFFF34 -:102060008E0C00103C0708008CE731B0920600008F -:1020700031843FFF0087282B10A0002330CD003F84 -:102080008F99005C000479803C0408008C8431A89E -:102090002409FF809390004900994021010F2021DD -:1020A00000897824000F51403C098000309F007F58 -:1020B0003C0B00808F880028308E00783578000136 -:1020C000015F282530860007352709403C031000B2 -:1020D0003C02800C01D8582500C7C82100A3502518 -:1020E00003E2C021360E0001AD2F0804AF99004075 -:1020F000AD2B0814AF980034AD2F0028AD04007448 -:10210000AD2A0830A38E00499383004A24100003AF -:102110005070002725A3FFE0240C0001106C001C68 -:1021200024060023024020218FBF001C8FB200181C -:102130008FB100148FB000100080102103E0000860 -:1021400027BD0020314900035520FFAE8F84005485 -:102150000A001E1F8F9000548F840054306500FFCA -:102160000E0017A224060001938E003824070034C5 -:1021700011C700188F8500509783004C3078FFFFFF -:1021800000B87023AF8E00500A001E57A780004C85 -:1021900011A6003200000000022020212411000BB3 -:1021A0000E00189BA39100580A001E570040902172 -:1021B0002C7200201240FFF8000310803C0508013B -:1021C00024A581600045F8218FED000001A00008E2 -:1021D000000000002CB800051700FFE89783004CB2 -:1021E000978A004C3148FFFF00A848232D2B00059B -:1021F00011600003314400FF24AFFFFC31E400FF15 -:102200008F9000548F99002412190004389F000108 -:1022100033ED000115A00029000000008F85002883 -:1022200090A700C434E30010A0A300C49783004C1F -:102230008F8500508F8400283078FFFF00B870230E -:10224000AC8000DCA780004C0A001E57AF8E005007 -:102250002403FFFF11830005000000000E001B7522 -:10226000022020210A001E57004090210E001AFA79 -:10227000022020210A001E57004090210E001C7BE6 -:10228000022020210A001E57004090210E001BD979 -:10229000022020210A001E57004090210E001A51F2 -:1022A000022020210A001E5700409021938500380B -:1022B0002404FFFD0A001E58AF8500500E0017CD04 -:1022C000000000009783004C8F85005000402021C3 -:1022D0003066FFFF00A660232D8200051040FFA896 -:1022E0003078FFFF8F91002800B87023AE2400DC07 -:1022F000A780004C0A001E57AF8E005027BDFFD0AC -:10230000AFB20018AFB00010AFBF0028AFB50024C7 -:10231000AFB40020AFB3001CAFB100143C0C800080 -:102320008D880128240FFF803C07800A25100100BA -:10233000250B0080020F68243205007F016F702496 -:10234000AD8E009000A72821AD8D002490A700EC51 -:102350003169007F3C0A8004012A1821A387004AC2 -:102360009066007C00809021AF83002030C2000284 -:10237000AF88005CAF85002800A01821144000023F -:102380002404003424040030A38400388C6600CC7C -:1023900030F100FF24040004AF8600501224000432 -:1023A000A38000588E5300041660001D3C08800076 -:1023B0009387004930F200011240000F8FBF0028C0 -:1023C0008CB800748CA400742419FF80031988242D -:1023D00000117140308F007F01CF60253C0D20003F -:1023E000018D582530F500FE3C0A8000AD4B0830C9 -:1023F000A39500498FBF00288FB500248FB400201B -:102400008FB3001C8FB200188FB100148FB0001072 -:102410002402000127BD003003E00008ACA600CC78 -:102420008E590008951F01208E460010033FC021E1 -:102430003307FFFF30F5000F32B40001AF860024F0 -:102440001680003BA395004835060C0002A610211B -:1024500000F51823AD030084AF8200548E490004B8 -:102460003128FFFF1100002BA789004C2410FF80AA -:102470003C1580003C1420000A001F442413FFFE7A -:1024800090AE00C4020E682431AC00FF1580002A13 -:1024900002402021938400499786004C308F000130 -:1024A00011E0000B026428248F8900288D2300741A -:1024B0008D280074A3850049007010240002C940D3 -:1024C000311F007F033FC02503148825AEB10830BB -:1024D00010C000108F85002890A700C40207582460 -:1024E000316A00FF1540FFE6024020210E001DFA70 -:1024F0009791004C1040FFE8938400492405FFFDAC -:10250000544500058E430020022028210E00177A32 -:10251000024020218E430020307000041600000A83 -:102520002414FFFB8F8500280A001EFA8F860050B6 -:102530000A001F25AF8600540E001A1D000000007F -:102540000A001F3493840049007498240E001792E7 -:10255000AE5300208F8500280A001EFA8F86005097 -:1025600027BDFFD8AFB3001CAFB10014AFBF002030 -:10257000AFB20018AFB000103C0280008C52014096 -:102580008C4B01483C048000000B8C02322300FF7E -:10259000317300FF8C8501B804A0FFFE34900180E8 -:1025A000AE1200008C8701442464FFF02406000270 -:1025B0002C830013AE070004A6110008A206000B2E -:1025C000AE1300241060004F8FBF0020000448802D -:1025D0003C0A0801254A81E0012A40218D040000BF -:1025E00000800008000000003C1008008E1031A898 -:1025F00031733FFF001389800212C8212405FF8038 -:1026000003312021264C0100264700803C1F80001A -:1026100000E51824318F007F30E9007F308A007F89 -:102620003C18800A3C0E80043C0D800C0085102470 -:1026300001853024014D8021AFE6002401F84021BE -:10264000AFE30090012E9821AFE20028AF90003454 -:10265000AF880028AF9300200E001867016080212A -:102660003C0380008C6B01B80560FFFE8F8700344F -:10267000346501808F86002890E3000DACB2000025 -:10268000A4B00006000316000002FE03001F9027FE -:10269000001227C21080007A24C2007824196082B8 -:1026A000A4B90008A0A00005241F0002A0BF000BD1 -:1026B00000041C008F8B00203C0227000062902544 -:1026C000ACB20010ACA00014ACA00024ACA0002858 -:1026D000ACA0002C8D7300382410FF80ACB3001820 -:1026E00090E4000D02048824322500FF10A00005AC -:1026F0008FBF002090EC000D3188007FA0E8000D16 -:102700008FBF00208FB3001C8FB200188FB1001450 -:102710008FB000103C0D10003C0A800027BD00283F -:1027200003E00008AD4D01B8265F01002405FF80DD -:1027300033F8007F3C06800003E578243C19800ACA -:1027400003192021ACCF0024908E00C400AE682471 -:1027500031AC00FF1180FFEAAF840028248E00789E -:1027600095CD00123C0C08008D8C31A831AB3FFF99 -:1027700001924821000B5180012A402101052024AB -:10278000ACC400283107007F3C06800C00E6202105 -:102790009083000D00A31024304500FF10A0FFD847 -:1027A000AF8400349098000D330F001015E0FFD572 -:1027B0008FBF00200E001867000000003C0380005F -:1027C0008C7901B80720FFFE00000000AE12000067 -:1027D0008C720144AE120004A611000824110002FC -:1027E000A211000BAE1300240A001FCF8FBF0020E0 -:1027F0003C1260008E452C083C03F0033462FFFF5E -:1028000000A2F824AE5F2C088E582C083C1901B0A9 -:1028100003199825AE532C080A001FCF8FBF002044 -:10282000264D010031AF007F3C10800A240EFF804E -:1028300001F0282101AE60243C0B8000AD6C002427 -:102840001660FFAFAF85002824110003A0B100EC93 -:102850000A001FCF8FBF002026480100310A007FE9 -:102860003C0B800A2409FF80014B30210109202400 -:102870003C078000ACE400240A001FCEAF8600288D -:10288000944A001232083FFF314C3FFF1588FF8405 -:102890002419608290CF00C4240EFF8001CF482409 -:1028A000312D00FF11A0FF7E00000000240700046E -:1028B000A0C700EC8F870034241860842406000D24 -:1028C000A4B80008A0A600050A001FB9241F000232 -:1028D0000800330C0800330C080033E8080033BC50 -:1028E000080033A0080032F0080032F0080032F08F -:1028F0000800331480080100800800808008000070 -:102900005F865437E4AC62CC50103A453662198584 -:10291000BF14C0E81BC27A1E84F4B556094EA6FE49 -:102920007DDA01E7C04D748108007A8808007AB426 -:1029300008007A94080079D008007A9408007AD4C4 -:1029400008007A94080079D0080079D0080079D07E -:10295000080079D0080079D0080079D0080079D033 -:10296000080079D0080079D0080079D008007AC42E -:1029700008007AA4080079D0080079D0080079D03E -:10298000080079D0080079D0080079D0080079D003 -:10299000080079D0080079D0080079D0080079D0F3 -:1029A000080079D008007AA40800809008007F38D9 -:1029B0000800805808007F380800802808007E2022 -:1029C00008007F3808007F3808007F3808007F380B -:1029D00008007F3808007F3808007F3808007F38FB -:1029E00008007F3808007F3808007F3808007F38EB -:0429F00008007F60FC -:0C29F4000A0001220000000000000000AA -:102A00000000000D747061352E302E306A313500B3 -:102A100005000001000000000000000000000000B0 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A800010000003000000000000000D0000000D19 -:102A90003C02080024421C203C03080024631FA0C1 -:102AA000AC4000000043202B1480FFFD24420004B2 -:102AB0003C1D080037BD2FFC03A0F0213C1008008E -:102AC000261004883C1C0800279C1C200E0002E2F3 -:102AD000000000000000000D2402FF8027BDFFE081 -:102AE00000821024AFB00010AF420020AFBF00182A -:102AF000AFB10014936500043084007F03441821B3 -:102B00003C0200080062182130A5002003608021EB -:102B10003C080111277B000814A000022466005C19 -:102B200024660058920200049743010492040004B2 -:102B30003047000F3063FFFF3084004000672823D8 -:102B40001080000900004821920200053042000474 -:102B5000104000050000000010A00003000000006D -:102B600024A5FFFC24090004920200053042000461 -:102B7000104000120000000010A000100000000033 -:102B80009602000200A72021010440252442FFFEF6 -:102B9000A7421016920300042402FF800043102471 -:102BA000304200FF104000033C0204000A000172A2 -:102BB000010240258CC20000AF4210188F420178FC -:102BC0000440FFFE2402000AA742014096020002D0 -:102BD000240400093042000700021023304200079D -:102BE000A7420142960200022442FFFEA74201448E -:102BF000A740014697420104A74201488F420108BD -:102C000030420020504000012404000192020004E0 -:102C1000304200101440000234830010008018215C -:102C2000A743014A0000000000000000000000006F -:102C300000000000AF48100000000000000000008D -:102C400000000000000000008F4210000441FFFE61 -:102C50003102FFFF10400007000000009202000454 -:102C60003042004014400003000000008F42101862 -:102C7000ACC20000960200063042FFFF2442000270 -:102C800000021043000210400362882196220000D7 -:102C90001120000D3044FFFF00A710218F83003862 -:102CA0008F45101C0002108200021080004310218A -:102CB000AC45000030A6FFFF0E0002D100052C023B -:102CC00000402021A6220000920300042402FF807D -:102CD00000431024304200FF1040001F000000009D -:102CE00092020005304200021040001B000000006C -:102CF0009742100C2442FFFEA7421016000000006D -:102D00003C02040034420030AF42100000000000DA -:102D10000000000000000000000000008F421000D2 -:102D20000441FFFE000000009742100C8F45101C6C -:102D30003042FFFF24420030000210820002108067 -:102D4000005B1021AC45000030A6FFFF0E0002D151 -:102D500000052C02A622000096040002248400082C -:102D60000E0001E73084FFFF974401040E0001F5D7 -:102D70003084FFFF8FBF00188FB100148FB0001098 -:102D80003C02100027BD002003E00008AF4201789C -:102D90003084FFFF308200078F850024104000023E -:102DA000248300073064FFF800A4102130421FFF85 -:102DB00003421821247B4000AF850028AF82002405 -:102DC00003E00008AF4200843084FFFF3082000F30 -:102DD0008F85002C8F860034104000022483000F62 -:102DE0003064FFF000A410210046182BAF8500309E -:102DF0000046202314600002AF82002CAF84002C18 -:102E00008F82002C340480000342182100641821B2 -:102E1000AF83003803E00008AF4200808F820014C7 -:102E2000104000088F8200048F82FFCC1440000500 -:102E30008F8200043C02FFBF3442FFFF0082202447 -:102E40008F82000430430006240200021062000F4B -:102E50003C0201012C6200035040000524020004E2 -:102E60001060000F3C0200010A00022E000000006A -:102E700010620005240200061462000C3C020111DD -:102E80000A000227008210253C0200110082102552 -:102E9000AF421000240200010A00022EAF82000C93 -:102EA00000821025AF421000AF80000C000000002F -:102EB000000000000000000003E000080000000027 -:102EC0008F82000C10400004000000008F421000B0 -:102ED0000441FFFE0000000003E0000800000000C5 -:102EE0008F8200102443F800000229C224A2FFF0C0 -:102EF0002C63030110600003000210420A00025517 -:102F0000AC8200008F83001800A3102B1440000B2C -:102F10000000382100A31023244600018F82001CEA -:102F2000006210212442FFFF0045102B5440000492 -:102F30002402FFFF0A000255AC8600002402FFFFB6 -:102F40000A00025AAC8200008C8200003C03080098 -:102F500024631C5C000211400043382103E0000898 -:102F600000E010213C0908008D291D80000451401B -:102F70003C19080027391C5C00C0782100806021C2 -:102F8000240EFFFF00003821015940211120003696 -:102F9000000030213C18080027181D983C0D08003F -:102FA00025AD1D9C000F582B0006118000461021F6 -:102FB000000218C0007810218C4200001582002009 -:102FC000006D20218CA20000544000098D020018E1 -:102FD0003C0208008C421D8424420001AC820000A7 -:102FE0003C010800AC221D840A0002CF0000202111 -:102FF0008F47002000003021000211C01160004AFC -:10300000AF4200208D08001C3C0900088CA3000082 -:103010000066182100031880007A10210049102151 -:103020008C44000024C600010068182100CF102B3A -:103030001440FFF6AC6400000A0002CD000000005E -:103040008C840000008E102B5040000424C6000128 -:103050000080702100C0382124C6000100C9102B57 -:103060001440FFD20006118024020001ACA200002F -:103070003C0208008C421D7C3C0308008C631D80D0 -:103080000043102B1440002A2404FFFE0159102194 -:103090008C420018104000262404FFFF0007218006 -:1030A0003C0508008CA51D84008720218D06001892 -:1030B000000420C03C02080024421D980082102118 -:1030C0003C03080024631D9CAC4C000024A50001B7 -:1030D000008318213C02080024421DA0AC650000BA -:1030E000000631C03C010800AC251D84008220216F -:1030F0008F470020AD04001CAF46002011E0000AFD -:10310000000030213C020008034228218CA200006C -:1031100024C6000100CF182BAC82000024A50004B7 -:103120001460FFFA24840004AF470020000020212F -:1031300003E00008008010213084FFFF30C6FFFF4D -:1031400000052C0000A628253882FFFF004510212D -:103150000045282B0045102100021C023042FFFFD1 -:103160000043102100021C023042FFFF00431021E7 -:103170003842FFFF03E000083042FFFF27BDFFC8D1 -:10318000AFBF0030AFB3002CAFB20028AFB1002406 -:10319000AFB000203C0460088C8250002403FF7F05 -:1031A0003C066000004310243442380CAC825000CE -:1031B0008CC24C1C3C1A8000000216023042000FE8 -:1031C00010400007AF82001C8CC34C1C3C02001F47 -:1031D0003442FC0000621824000319C2AF830018B7 -:1031E0008F420008275B400034420001AF420008D4 -:1031F000AF8000243C02601CAF400080AF400084E0 -:103200008C4500088CC3080834028000034220214A -:103210002402FFF0006218243C0200803C010800F8 -:10322000AC2204203C025709AF8400381462000429 -:10323000AF850034240200010A000314AF82001499 -:10324000AF8000142403003D240200043C01080068 -:10325000AC221D943C010800AC231D903C010800E9 -:10326000AC231D8C3C010800AC231D883C130800D6 -:1032700026731C5C240400043C02080024421C74D5 -:10328000240300082463FFFFAC400004AC400000AE -:103290000461FFFC24420020000410C000441021FF -:1032A0002442003D3C010800AC221D902402000194 -:1032B0003C010800AC221D7C2402FFFF3C010800F9 -:1032C000AC221D983C010800AC201D848F420000F8 -:1032D00038420001304200011440FFFC8F8200148C -:1032E0001040001600000000974201041040000545 -:1032F0008F830000146000072462FFFF0A00034B65 -:103300002C62000A2C620010504000048F830000E1 -:1033100024620001AF8200008F8300002C62000A4B -:10332000144000032C6200070A000352AF80FFCC58 -:103330001040000224020001AF82FFCC8F4301083D -:103340008F44010030622000AF8300041040000869 -:10335000AF8400103C0208008C42042C244200017F -:103360003C010800AC22042C0A0006D73C024000B5 -:103370003065020014A0000324020F001482030928 -:1033800024020D0097420104104003713C024000EA -:1033900030624000144000AD8F8200388C44000839 -:1033A0008F4201780440FFFE24020800AF420178FA -:1033B00024020008A7420140A740014297420104AD -:1033C0008F8400043051FFFF30820001104000075D -:1033D000022080212623FFFE240200023070FFFF1E -:1033E000A74201460A00037FA7430148A7400146C0 -:1033F0003C0208008C42043C1440000D8F830010F6 -:10340000308200201440000224030009240300013C -:10341000006020218F830010240209005062000107 -:1034200034840004A744014A0A00039A0000000003 -:1034300024020F00146200053082002014400006B0 -:103440002403000D0A000399240300051440000220 -:103450002403000924030001A743014A3C02080099 -:103460008C4204203C0400480E00020A004420253F -:103470000E000233000000008F82000C1040003E5E -:10348000000000008F4210003C0300200043102485 -:10349000104000398F820004304200021040003694 -:1034A0000000000097421014144000330000000098 -:1034B000974210088F8800383042FFFF24420006F0 -:1034C000000218820003388000E8302130430001F8 -:1034D0008CC4000010600004304200030000000DA6 -:1034E0000A0003DB00E81021544000103084FFFF85 -:1034F0003C05FFFF00852024008518260003182BBB -:103500000004102B004310241040000500000000B0 -:10351000000000000000000D000000002400021C5C -:103520008CC200000A0003DA004520253883FFFF23 -:103530000003182B0004102B00431024104000053A -:1035400000000000000000000000000D000000006E -:10355000240002258CC200003444FFFF00E8102143 -:10356000AC4400003C0208008C42043024420001BC -:103570003C010800AC2204308F6200008F840038C8 -:10358000AF8200088C8300003402FFFF1462000F3A -:10359000000010213C0508008CA504543C040800E0 -:1035A0008C84045000B0282100B0302B00822021F0 -:1035B000008620213C010800AC2504543C01080091 -:1035C000AC2404500A0006CD240400088C820000BC -:1035D000304201001040000F000010213C0508009F -:1035E0008CA5044C3C0408008C84044800B02821BD -:1035F00000B0302B00822021008620213C010800F1 -:10360000AC25044C3C010800AC2404480A0006CD5B -:10361000240400083C0508008CA504443C04080070 -:103620008C84044000B0282100B0302B008220217F -:10363000008620213C010800AC2504443C01080020 -:10364000AC2404400A0006CD240400088F62000860 -:103650008F62000000021602304300F024020030A6 -:1036600010620005240200401062016B8F8200206E -:103670000A0006D52442000114A000050000000045 -:10368000000000000000000D0000000024000250B7 -:103690008F4201780440FFFE000000000E00023B54 -:1036A00027A4001014400005004080210000000005 -:1036B0000000000D00000000240002578E020000F0 -:1036C0001040000500000000000000000000000D98 -:1036D000000000002400025A8F62000C0443000323 -:1036E000240200010A00055DAE000000AE020000E9 -:1036F0008F8200388C450008A20000078F65000CFF -:103700008F64000430A3FFFF0004240200852023FF -:10371000308200FF0043102124420005000288830C -:103720002E220081A605000A14400005A204000410 -:10373000000000000000000D0000000024000272E4 -:103740003C0708008CE71D808FA800102409FFFFAC -:103750000000502110E00013000030213C0C080054 -:10376000258C1D9C01802821000018218CA2FFFCC3 -:103770005102002F006C18218CA400002463020861 -:103780000089102B1040000324A502080080482166 -:1037900000C0502124C6000100C7102B5440FFF484 -:1037A0008CA2FFFC3C0508008CA51D803C02080093 -:1037B0008C421D7C3C09080025291C603C03080044 -:1037C00024631D9800A2102B3C0C0800258C1D9C26 -:1037D0003C0408008C841D843C0B0800256B1DA054 -:1037E0001040001A000831400005118000451021EA -:1037F000000210C000C9382124840001004B302190 -:103800000043182124A50001004C1021AC680000E1 -:10381000ACE600183C010800AC241D84AC44000058 -:103820003C010800AC251D800A0004A88E04001C81 -:103830003C0208008C421D84244200013C01080027 -:10384000AC221D840A0004A7AC620000000A1180AB -:10385000004A1021000210C0004328218CA3000060 -:10386000004C3821248400010003194000C9302194 -:1038700000691821004B1021ACA80000AC600018B2 -:103880003C010800AC241D84ACC20018ACE400006C -:103890008E04001C8F8500380E0006E702203021C0 -:1038A0008F6200048F430108A60200083C0210004A -:1038B0000062182410600008000000009742010414 -:1038C000920300072442FFEC346300023045FFFFFF -:1038D0000A0004BCA2030007974201042442FFF03F -:1038E0003045FFFF960600082CC200135440000527 -:1038F000920300079202000734420001A20200076F -:103900009203000724020001106200052402000354 -:103910001062000B30C7FFFF0A0004DB24E2000244 -:103920008F8200383C04FFFF8C43000C0064182495 -:1039300000651825AC43000C0A0004DA30C7FFFF0D -:103940008F8200383C04FFFF8C4300100064182471 -:1039500000651825AC43001030C7FFFF24E20002C9 -:1039600000021083A20200058F830038304200FF5E -:1039700000021080004330218CC500008CC2000082 -:103980002403000400021702144300130000000087 -:10399000974201043C03FFFF00A318243042FFFFBD -:1039A000004710232442FFFE00622825ACC500001A -:1039B000920400058E03001C308200FF000210807C -:1039C00000431021904200003042000F00441021BB -:1039D0000A000510A20200068CC4000497420104EC -:1039E0009603000A3085FFFF3042FFFF0047102397 -:1039F0002442FFD60002140000A22825ACC5000412 -:103A00009202000792040005246300280003188333 -:103A10000064182134420004A2030006A202000739 -:103A20008F8200042403FFFB344200020043102471 -:103A3000AF820004920300068E07001C8F860038B8 -:103A400000031880006710218C44000C3C02FFF634 -:103A50003442FFFF0082282400661821AE04000CC7 -:103A6000AC65000C920300068E04000C3C02FF7F44 -:103A70003442FFFF0003188000A228240082202483 -:103A800000671821AE04000CAC65000C9202000621 -:103A9000000210800047102194450012AC45001030 -:103AA000920200060002108000461021AC45001072 -:103AB0008FA200109203000500021140000318803D -:103AC00000671821005320218C6200048C830018A9 -:103AD0001460000EAE0200143C0308008C631D8CC1 -:103AE000AC8300183C0208008C421D900062102B31 -:103AF00010400019000000003C0208008C421D9498 -:103B0000006210213C010800AC221D8C8E020018BE -:103B10008F48002000003021000211C01220000B4D -:103B2000AF4200203C0200080342282100E020218F -:103B30008C82000024C6000100D1182BACA200002A -:103B4000248400041460FFFA24A50004AF48002078 -:103B50000A00055E24020010000000000000000DB5 -:103B600000000000240002D424020010A7420140FB -:103B700024020002A7400142A7400144A742014697 -:103B8000974201043C0400082442FFFEA74201487A -:103B9000240200010E00020AA742014A9603000A0D -:103BA0009202000400431021244200023042000728 -:103BB00000021023304200070E000233AE02001054 -:103BC0008F6200003C0308008C630444240400104E -:103BD000AF820008974201043042FFFF2442FFFEFB -:103BE00000403821000237C33C0208008C420440E8 -:103BF000006718210067282B00461021004510217E -:103C00003C010800AC2304443C010800AC22044001 -:103C10000A0006620000000014A000050000000079 -:103C2000000000000000000D00000000240003045C -:103C30008F4201780440FFFE000000000E00023BAE -:103C400027A400141440000500408021000000005B -:103C50000000000D000000002400030B9206000489 -:103C60008FA4001427A50018000630820E00025C05 -:103C7000AFA00018504000068E02000000000000B7 -:103C80000000000D00000000240003118E0200005F -:103C90005440000692020007000000000000000DE2 -:103CA00000000000240003169202000730420004C6 -:103CB000104000058F8200042403FFFB3442000201 -:103CC00000431024AF8200048F6200040443000903 -:103CD00092020007920200068E03001C8E04000C64 -:103CE0000002108000431021AC44000CAE00000024 -:103CF00092020007304200045440000B920300047B -:103D0000920300058E0400148E05001C0003188029 -:103D10003C0200010082202100651821AE0400143D -:103D2000AC640004920300049602000A00621021B1 -:103D300024420005000290838FA200181040000D5D -:103D4000277100088FA40014000310820242302360 -:103D500027A500180E00025CAFA200185040000614 -:103D60008E05001C000000000000000D0000000097 -:103D70002400033F8E05001C022020210E0006E7D0 -:103D800002403021920400068F6500043C027FFF50 -:103D900000042080009120218C8300043442FFFF26 -:103DA00000A2282400651821AC83000492020007B9 -:103DB00092030004920500053042000410400014F4 -:103DC0009607000830A500FF0005288000B12821D3 -:103DD0008CA40004974201049606000A306300FF99 -:103DE0003042FFFF004310210046102130E3FFFF67 -:103DF000004310232442FFD83084FFFF0002140048 -:103E000000822025ACA400040A00061692030007D5 -:103E100030A500FF0005288000B128218CA40000F7 -:103E200097420104306300FF3042FFFF004310213E -:103E3000004710233C03FFFF008320243042FFFF94 -:103E400000822025ACA40000920300072402000198 -:103E5000106200060000000024020003106200113E -:103E6000000000000A0006398E030010974201048A -:103E7000920300049605000A8E24000C00431021D2 -:103E8000004510212442FFF23C03FFFF0083202461 -:103E90003042FFFF00822025AE24000C0A000639C4 -:103EA0008E03001097420104920300049605000A55 -:103EB0008E24001000431021004510212442FFEE03 -:103EC0003C03FFFF008320243042FFFF00822025B7 -:103ED000AE2400108E0300102402000AA742014005 -:103EE000A74301429603000A920200043C040040EA -:103EF00000431021A7420144A74001469742010414 -:103F0000A7420148240200010E00020AA742014A0A -:103F10000E000233000000008F62000092030004D4 -:103F200000002021AF820008974201049606000A93 -:103F30003042FFFF00621821006028213C03080086 -:103F40008C6304443C0208008C4204400065182144 -:103F5000004410210065382B004710213C01080067 -:103F6000AC2304443C010800AC2204409204000449 -:103F7000008620212484000A3084FFFF0E0001E720 -:103F800000000000974401043084FFFF0E0001F59B -:103F9000000000003C021000AF4201780A0006D485 -:103FA0008F820020148200273062000697420104AD -:103FB000104000673C0240003062400010400005A5 -:103FC00000000000000000000000000D00000000E4 -:103FD0002400041A8F4201780440FFFE24020800E6 -:103FE000AF42017824020008A7420140A7400142E5 -:103FF0008F82000497430104304200011040000703 -:104000003070FFFF2603FFFE24020002A742014694 -:10401000A74301480A00068C2402000DA740014670 -:104020002402000DA742014A8F6200002404000808 -:10403000AF8200080E0001E7000000000A000666DB -:1040400002002021104000423C0240009362000028 -:10405000304300F0240200101062000524020070BA -:10406000106200358F8200200A0006D5244200012C -:104070008F620000974301043050FFFF3071FFFF53 -:104080008F4201780440FFFE320200070002102335 -:10409000304200072403000A2604FFFEA743014024 -:1040A000A7420142A7440144A7400146A751014845 -:1040B0008F4201083042002014400002240300090E -:1040C00024030001A743014A0E00020A3C040040F9 -:1040D0000E000233000000003C0708008CE7044497 -:1040E000021110212442FFFE3C0608008CC6044049 -:1040F0000040182100E33821000010218F650000E6 -:1041000000E3402B00C230212604000800C8302103 -:104110003084FFFFAF8500083C010800AC27044451 -:104120003C010800AC2604400E0001E7000000003E -:104130000A000666022020210E000139000000005E -:104140008F82002024420001AF8200203C02400008 -:10415000AF4201380A000336000000003084FFFF40 -:1041600030A5FFFF000018211080000700000000AC -:104170003082000110400002000420420065182136 -:104180000A0006DD0005284003E000080060102159 -:1041900010C0000624C6FFFF8CA2000024A5000466 -:1041A000AC8200000A0006E72484000403E0000853 -:1041B0000000000010A0000824A3FFFFAC86000050 -:1041C00000000000000000002402FFFF2463FFFF46 -:1041D0001462FFFA2484000403E0000800000000D9 -:0441E00000000001DA -:0C41E4000A00002A00000000000000009B -:1041F0000000000D747870352E302E306A31350095 -:10420000050000000000000A000001360000EA601E -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:104240000000000000000016000000000000000058 -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:1042700000000000000000000000000000001388A3 -:1042800000000000000005DC00000000000000004D -:1042900010000003000000000000000D0000000DF1 -:1042A0003C020800244239203C03080024633BD42C -:1042B000AC4000000043202B1480FFFD244200048A -:1042C0003C1D080037BD7FFC03A0F0213C10080016 -:1042D000261000A83C1C0800279C39200E0004076B -:1042E000000000000000000D8F86003C3C039000A1 -:1042F0003C0280000086282500A32025AC44002035 -:104300003C0380008C67002004E0FFFE00000000FA -:1043100003E00008000000000A000041240400013E -:104320008F85003C3C0480003483000100A31025ED -:1043300003E00008AC82002003E000080000102128 -:104340003084FFFF30A5FFFF108000070000182118 -:104350003082000110400002000420420065182154 -:104360001480FFFB0005284003E0000800601021D6 -:1043700010C00007000000008CA2000024C6FFFF50 -:1043800024A50004AC82000014C0FFFB24840004B8 -:1043900003E000080000000010A0000824A3FFFFB5 -:1043A000AC86000000000000000000002402FFFFB7 -:1043B0002463FFFF1462FFFA2484000403E0000872 -:1043C0000000000090AA00318FAB00108CAC0040C0 -:1043D0003C0300FF8D680004AD6C00208CAD0044F0 -:1043E00000E060213462FFFFAD6D00248CA700481F -:1043F0003C09FF000109C024AD6700288CAE004CC9 -:104400000182C82403197825AD6F0004AD6E002C1D -:104410008CAD0038314A00FFAD6D001C94A900320C -:104420003128FFFFAD68001090A70030A5600002A2 -:10443000A1600004A167000090A30032306200FF79 -:104440000002198210600005240500011065000EAD -:104450000000000003E00008A16A00018CD80028D9 -:10446000354A0080AD7800188CCF0014AD6F001471 -:104470008CCE0030AD6E00088CC4002CA16A000107 -:1044800003E00008AD64000C8CCD001CAD6D00187D -:104490008CC90014AD6900148CC80024AD680008F4 -:1044A0008CC70020AD67000C8CC200148C83007098 -:1044B0000043C82B13200007000000008CC200142A -:1044C000144CFFE400000000354A008003E00008BF -:1044D000A16A00018C8200700A0000B70000000091 -:1044E0009089003027BDFFF88FA8001CA3A9000009 -:1044F0008FA300003C0DFF8035A2FFFF8CAC002C89 -:1045000000625824AFAB0000A100000400C0582195 -:10451000A7A000028D06000400A048210167C82161 -:104520008FA50000008050213C18FF7F032C20261F -:104530003C0E00FF2C8C0001370FFFFF35CDFFFF35 -:104540003C02FF0000AFC82400EDC02400C2782464 -:10455000000C1DC00323682501F87025AD0D000077 -:10456000AD0E00048D240024AFAD0000AD040008A2 -:104570008D2C00202404FFFFAD0C000C9547003269 -:1045800030E6FFFFAD0600109145004830A200FF65 -:10459000000219C2506000018D240034AD040014E3 -:1045A0008D4700388FAA001827BD0008AD0B0028E2 -:1045B000AD0A0024AD07001CAD00002CAD000018B2 -:1045C00003E00008AD00002027BDFFE0AFB20018F7 -:1045D000AFB10014AFB00010AFBF001C9098003016 -:1045E00000C088213C0D00FF330F007FA0CF0000EA -:1045F000908E003135ACFFFF3C0AFF00A0CE0001D9 -:1046000094A6001EA22000048CAB00148E29000486 -:1046100000A08021016C2824012A402400809021E0 -:1046200001052025A6260002AE2400042605002050 -:10463000262400080E000063240600029247003082 -:10464000260500282624001400071E000003160378 -:1046500024060004044000032403FFFF965900329F -:104660003323FFFF0E000063AE2300102624002436 -:104670008FBF001C8FB200188FB100148FB00010D4 -:1046800024050003000030210A00006D27BD002032 -:1046900027BDFFD8AFB1001CAFB00018AFBF0020DE -:1046A00090A900302402000100E050213123003F96 -:1046B00000A040218FB000400080882100C0482128 -:1046C000106200148FA70038240B000500A02021E1 -:1046D00000C02821106B0013020030210E0000F9E9 -:1046E000000000009225007C30A40002108000032E -:1046F00026030030AE000030260300348FBF0020B8 -:104700008FB1001C8FB000180060102103E000087A -:1047100027BD00280E000078AFB000100A0001404D -:10472000000000008FA3003C01002021012028216F -:1047300001403021AFA300100E0000BFAFB0001445 -:104740000A000140000000003C0580008CA30E1010 -:104750008F840044AC8300208CA20E1803E0000874 -:10476000AC8200243C0580008CA30E148F8400448E -:10477000AC8300208CA20E1C03E00008AC82002455 -:104780009382000C1040001B2483000F2404FFF0D0 -:104790000064382410E00019978B00109784000EF5 -:1047A0009389000D3C0A601C0A00017B01644023D0 -:1047B00001037021006428231126000231C2FFFF8B -:1047C00030A2FFFF0047302B50C0000E00E448210C -:1047D0008D4D000C31A3FFFF00036400000C2C037F -:1047E00004A1FFF30000302130637FFF0A00017352 -:1047F0002406000103E00008000000009784000E7A -:1048000000E448213123FFFF3168FFFF0068382BA7 -:1048100054E0FFF8A783000E938A000D11400005B5 -:10482000240F0001006BC023A380000D03E00008EB -:10483000A798000E006BC023A38F000D03E00008B3 -:10484000A798000E03E000080000000027BDFFE865 -:10485000AFB000103084FFFF3C10800093A8002B05 -:10486000AFBF0014A6040144960A0E1630C600FF1E -:104870008FA90030A60A0146AE050148A2060152E2 -:10488000A608015AAE0701608FA3002CA6090158A3 -:10489000012020210E000167AE0301543C021000EC -:1048A000AE0201788FBF00148FB0001003E0000843 -:1048B00027BD00188F8500002484000727BDFFF85E -:1048C0003084FFF83C06800094CB008A316AFFFFF9 -:1048D000AFAA00008FA90000012540232507FFFF94 -:1048E00030E31FFF0064102B1440FFF700056882BF -:1048F000000D288034CC400000AC102103E00008FB -:1049000027BD00088F8200002486000730C5FFF80D -:1049100000A2182130641FFF03E00008AF840000EC -:104920008F8500448F8A003C27BDFFB03C04800087 -:10493000AFB70044AFB40038AFB1002CAFBF0048F0 -:10494000AFB60040AFB5003CAFB30034AFB20030FB -:10495000AFB000288C8701048CA90024AC8A0080A9 -:104960008CA8002000E988230000B821AC880E1034 -:104970008CA600240000A021AC860E188C820E109C -:10498000AC820E148C830E18AC830E1C122000FB1C -:104990003C168000936B0008116000F100000000DD -:1049A000976E001031CDFFFF022D602B158000ECBB -:1049B0000000000097700010320FFFFFAECF0E0016 -:1049C0003C0580008CB30000327200081240FFFDED -:1049D0000000000094B50E088CA70E0432A5FFFF5E -:1049E00030B40001128000E1000000000000000D62 -:1049F00030B9A040241800401338011730B4A0008B -:104A0000128000DC000000009373000812600008B0 -:104A100000000000976900103122FFFF00E2202B08 -:104A20001080000330A6004010C000D2000000003B -:104A3000A7850040AF870038936A0008022038211C -:104A4000AFB10020154000F127B40020AF60000C8A -:104A50009785004030B14000162000022403001664 -:104A60002403000E24154007A363000AAF75001449 -:104A7000939000428F6F0014321900010019C24058 -:104A800001F84025AF680014978700408F63001439 -:104A900030EE0010006E6825AF6D0014978C00405A -:104AA000318B000811600165000000008F65001463 -:104AB0003C0B10003C0A800000AB8825AF7100144D -:104AC00095460E0A3C0981002413000E30C2FFFFF8 -:104AD00000492025AF640004A3730002937F000AFD -:104AE0003406FFFC27F20004A372000A978D0040F1 -:104AF00031AC200011800157000000003C0780000D -:104B0000978D004094EC0E0C97910040000D584298 -:104B10003185C000316A00030005130332291000FB -:104B200001429825000922030264F825001F90C065 -:104B3000A7720012979500409379000A00158182B0 -:104B40003218003C0319782125E8003CA3680009CD -:104B500094EE0E0C31C33FFFA76300109763001261 -:104B60009367000900E3702125CD000231AC0007F6 -:104B7000000C582331650007A365000B93710009F1 -:104B800097640012976A0010322200FF8F9100385C -:104B9000979F004000444821012A982102669021F5 -:104BA00033F5004012A000053246FFFF00D1402B34 -:104BB0003C12800011000016000098210226782B7C -:104BC00015E001368FA700203C1880008F100E14CE -:104BD0003C058000AF100E108F190E1CAF190E1877 -:104BE000AF060E008CB200003255000812A0FFFD87 -:104BF0000000000094BF0E0800C088210000902132 -:104C0000A79F00408CA60E0424130001AF86003835 -:104C1000976900103135FFFF8E8C00000191202331 -:104C200010800118AE8400009367000814E000D8DB -:104C3000000000000E0001B4240400108F8E004814 -:104C40003C0332000040282131C600FF00063C0032 -:104C500000E3602525CD0001AF8D0048AC4C00007D -:104C60009362000997640012937F000A304A00FFA4 -:104C7000308BFFFF014B48210009CC0033F000FFCF -:104C80000330C025ACB800048F8F004897880040DF -:104C90003103200010600103ACAF0008976F0012D1 -:104CA00031E8FFFF06400101ACA8000C97900040DE -:104CB0003205000814A0000226280006262800025B -:104CC0003C048000948B0E148C850E1C8F670004AE -:104CD000936A00023164FFFF314900FFAFA9001061 -:104CE0008F7F0014AFA80018AFBF00140E00019A08 -:104CF00000000000240400100E0001C800000000A5 -:104D00008E92000016400005000000008F7900140C -:104D10002405FFBF0325A024AF7400148F69000C85 -:104D20000135F821AF7F000C9375000816A000082C -:104D30000000000012600006000000008F6B0014ED -:104D40003C0CEFFF3584FFFE01645024AF6A001471 -:104D5000A37300088FA700200A0003160220202159 -:104D6000AED10E000A0001F83C05800014E0FF21DE -:104D700030B9A0400E0001600000A0212E9100017A -:104D80000237B02512C000178FBF00488F85003C46 -:104D900024170F0010B700CD3C0480008C990178D7 -:104DA0000720FFFE24150F0050B500EB3C048000E7 -:104DB0008C890E14240502403C141000AC89014477 -:104DC0008C9F0E1CAC9F0148A0800152A480015A08 -:104DD000AC800160A4800158AC850154AC9401788A -:104DE0008FBF00488FB700448FB600408FB5003C9E -:104DF0008FB400388FB300348FB200308FB1002CE5 -:104E00008FB0002803E0000827BD00508F910038C4 -:104E1000979300403C1280000220A821326A004093 -:104E20001540FF7D00009821976B00108F8500389A -:104E30003162FFFF104500A2000020210080A02168 -:104E4000108000E500E088211620FED2000000005E -:104E50000A0002E72E9100013C0380008C7F01785C -:104E600007E0FFFE240408008F860000AC64017890 -:104E70003C038000946C008A318BFFFF0166502355 -:104E80002549FFFF31281FFF2D0200081440FFF9BC -:104E9000000000008F8E0048346F40008F83003C7C -:104EA00000E0A021240D0F0025C70001AF870048B6 -:104EB00000CF3021023488233C08800031D500FF28 -:104EC000106D000524070001939300423272000127 -:104ED0000012824036070001001514003C09010051 -:104EE00000492025ACC400008F9F004830B900362F -:104EF00030B80008ACDF00041300009000F99825DA -:104F000095070E0A8F8E00003C03810030EDFFFFF5 -:104F100025CB000801A328253C0C1000316A1FFF97 -:104F2000269200062406000EAD050160026C98254D -:104F3000A506015AAF8A0000A512015816200008E4 -:104F40003C1080008F99003C24180F005338000259 -:104F500024170001367300400E0001593C108000F8 -:104F60008E1F0E1402402021AE1F01448E120E1C13 -:104F7000AE120148A2150152AE1301540E00016792 -:104F80003C151000AE1501780A000319000000005E -:104F900093780009976300129368000B330F00FFAA -:104FA00001E33821310200FF00E2702125D0000A20 -:104FB0003210FFFF0E0001B4020020218F8600484E -:104FC0003C1941003C07800024CD0001AF8D004812 -:104FD000936C00099764001230C600FF318A00FF0D -:104FE000308BFFFF014B482100062C00253F0002BB -:104FF00000BFC02503197825AC4F00008F68000C56 -:1050000094EE0E1401121825AC4300048CE50E1C1E -:105010008F670004936D000231C4FFFF31AC00FFC5 -:10502000AFAC00108F620014AFB100180E00019AEF -:10503000AFA200140A0002C502002021AF600004E4 -:10504000A3600002978D004031AC20001580FEABBC -:1050500000003021A7600012979000409378000A6A -:105060003C03800032191F000019798301F84021A8 -:1050700025070028A3670009946E0E0C0A00025E43 -:10508000A76E00108F6E001435CD00400E00015940 -:10509000AF6D00140A000291000000000A00031620 -:1050A000000020210641FF01ACA0000C8CB8000CD0 -:1050B0003C198000031990250A0002B2ACB2000C22 -:1050C000000090210A00028D2413000112800005C7 -:1050D0003C0D800095A60E0830D3004012600042BF -:1050E000000000008C9001780600FFFE0000000028 -:1050F00094920E103C030500240720003258FFFF55 -:1051000003037825AC8F014C8C880E143C0E1000E4 -:10511000AC8801448C820E1CAC820148A0800152F4 -:10512000A480015AAC800160A4800158AC8701546E -:10513000AC8E01780A0002EE3C0480008F900000E3 -:1051400026920002A5120158260F000831E81FFF21 -:105150000A000356AF880000AC80014C1280001991 -:10516000000000008C8A0E10AC8A01448C830E185B -:105170003C0C800024160040AC8301488FBF0048DF -:10518000A18001528FB70044A580015A8FB5003C21 -:10519000AD8001608FB40038A58001588FB3003412 -:1051A000AD9601548FB200308FB600408FB1002C05 -:1051B0008FB000283C04100027BD005003E0000819 -:1051C000AD8401788C8B0E14AC8B01448C830E1C47 -:1051D0000A0003E43C0C80000E0001602E910001E7 -:1051E0000A0002E80237B025000000000000000DB0 -:1051F000000000002400033A0A0003C03C048000C1 -:1052000027BDFFE0AFBF001C3C1F20FF3C07600034 -:105210003C0980002402001037F9FFFDACE23008A1 -:10522000AFB20018AFB10014AFB00010AD390E002E -:10523000000000000000000000000000000000006E -:10524000000000003C1800FF3712FFFDAD320E00D9 -:105250003C0B60048D7050002411FF7F3C0E000257 -:105260000211782435EC380C35CD0109ACED4C1821 -:10527000240A0009AD6C50008CE80438AD2A0008FF -:10528000AD2000148CE54C1C3106FFFF38C42F7193 -:1052900000051E023062000F2486C0B310400007D4 -:1052A000AF8200088CE54C1C3C09001F3528FC002F -:1052B00000A81824000321C2AF8400048CF1080860 -:1052C0003C0F57092412F0000232702435F0001010 -:1052D00001D0602601CF68262DAA00012D8B000188 -:1052E000014B382550E00009A380000C3C02601CF3 -:1052F0008C590008241F0001A39F000C33387C0048 -:10530000A7980010A780000EA380000DAF80004872 -:1053100014C00003AF8000003C066000ACC0442C09 -:105320000E0004B63C1080000E000E0E00000000BF -:105330003C110800263139883C12080026523A08F0 -:105340008E05000038A30001306400011480FFFCCA -:10535000000000008E0601003C0C800A240AFF8039 -:1053600024C7024030EB007F016C482100EA402452 -:10537000AE060020AF890044AE0800243C03800044 -:10538000AF86003C8C6D017805A0FFFE2419080053 -:10539000AC79017890780108A3980042938F00427D -:1053A00031EE000111C0000F240D0D0024C2F800E1 -:1053B0002C5F030113E0001C000629C224A3FFF0A8 -:1053C00000032042000431400E0001CF00D1D8215B -:1053D0003C0440003C068000ACC401380A0004577D -:1053E0000000000010CD0026240E0F0010CE002A71 -:1053F0003C028008345F008093F90000240F0050C5 -:10540000333800FF170FFFF33C0440000E00092F54 -:10541000000000003C0440003C068000ACC40138A1 -:105420000A000457000000008F83000400A3402BF3 -:105430001500000B8F8B0008006B50212547FFFFE4 -:1054400000E5482B1520000600A36023000C29402E -:105450000E0001CF00B2D8210A00047C3C044000B9 -:10546000000000000000000D00000000240003AD5B -:105470000E0001CF000000000A00047C3C04400044 -:105480003C1B0800277B3B080E0001CF00000000FA -:105490000A00047C3C0440003C1B0800277B3B289E -:1054A0000E0001CF000000000A00047C3C04400014 -:1054B000000411C003E00008244202403C0408003C -:1054C00024843B6C2405001A0A00006D0000302182 -:1054D00027BDFFE0AFBF001CAFB20018AFB1001492 -:1054E000AFB000103C108000920B01092412FF8025 -:1054F0000E0004B33164007F8F91003C00515021B5 -:1055000001524024AE080024920301090E0004B3A6 -:105510003064007F24060080240700C0240400407B -:10552000AE000810AE040814AE060818AE07081C3A -:10553000920C01090051F82133F8007F3C19800AD0 -:10554000031910213184007F0E0004B3AF820044A0 -:105550008E1101003C0C008035850001022278216B -:1055600001F24824AE0908048E0E010035980002AD -:105570003609090001C2682131AB00780165502568 -:10558000AE0A08208E0501008E080100360509804C -:10559000010218212464004000923024AE0608085D -:1055A0008E07010000E2F82127F90040333200782D -:1055B00002588825AE1108248E040100952F000C96 -:1055C0008FBF001C8FB2001831EEFFFF000E69C0C4 -:1055D000AE0D0800AE0C0828952B000C8FB10014FE -:1055E000316AFFFF000A41C0AE08002C8CA30050B6 -:1055F0008FB000108CA2003C8D2400048CA6001CEF -:105600008CA7003827BD0020AF830060AF82005018 -:10561000AF84004CAF86005803E00008AF87005C01 -:105620003C098000352309009128010B906A001184 -:105630002402002800804821314700FF00A070218B -:1056400000C068213108004010E20002340C86DD01 -:10565000240C08003C0A800035420A9A9447000056 -:10566000354B0A9C35460AA030F9FFFFAD390000E2 -:105670008D780000354B0A8024040001AD38000409 -:105680008CCF0000AD2F00089165001930A30003F6 -:105690001064008E28640002148000AD240500020E -:1056A0001065009C240F0003106F00B235450AA45A -:1056B000240A0800118A0047000000005100003C45 -:1056C0003C0B80003C04800034830900906700128A -:1056D00030E200FF004D7821000FC8802724000130 -:1056E0003C0A8000354F090091E50019354C0980CE -:1056F0008D87002830A300FF0003150000475825C0 -:105700000004C4003C19600001793025370806FF09 -:10571000AD260000AD2800048DEA002C25280028C5 -:10572000AD2A00088DEC0030AD2C000C8DE5003466 -:10573000AD2500108DE40038AD2400148DE3001C6D -:10574000AD2300188DE700203C038000AD27001C2E -:105750008DE20024AD2200208DF900283462093C3E -:10576000AD3900248C450000AD0E000434790900E9 -:10577000AD0500008C67010C25020014AD07000880 -:10578000932B00123C04080090843B90AD00001065 -:10579000317800FF030D302100064F0000047C002B -:1057A000012F702535CDFFFF03E00008AD0D000C83 -:1057B00035780900930600123C05080094A53B804B -:1057C00030C800FF010D5021000A60800A00053F2B -:1057D000018520211500005A000000003C08080047 -:1057E00095083B863C06080094C63B8001061021C4 -:1057F0003C0B80003579090093380011932A001979 -:1058000035660A80330800FF94CF002A00086082C2 -:10581000314500FF978A0054000C1E00000524004B -:105820003047FFFF006410250047C02501EA302102 -:105830003C0B4000030B402500066400AD2800002F -:10584000AD2C0004932500183C0300062528001405 -:1058500000053E0000E31025AD2200088F24002C37 -:105860003C0380003462093CAD24000C8F38001CDE -:10587000254F000131EB7FFFAD3800108C45000053 -:10588000AD0E000434790900AD0500008C67010CF1 -:10589000A78B005425020014AD070008932B0012BB -:1058A0003C04080090843B90AD000010317800FF6C -:1058B000030D302100064F0000047C00012F7025ED -:1058C00035CDFFFF03E00008AD0D000C3C020800E1 -:1058D00094423B8A3C05080094A53B8035440AA4C9 -:1058E0003C07080094E73B7C948B00000045C821EE -:1058F0000327C023000B1C002706FFF2006650257B -:10590000AD2A000CAD200010AD2C00140A000533A8 -:1059100025290018354F0AA495E500009564002854 -:105920000005140000043C003459810000EC5825A7 -:10593000AD39000CAD2B00100A00053325290014E9 -:105940003C0C0800958C3B860A00058325820001EB -:105950005460FF58240A080035580AA4970600002E -:1059600000061C00006C5025AD2A000C0A0005330F -:10597000252900103C03080094633B8A3C0708007B -:1059800094E73B803C0F080095EF3B7C94A400001B -:105990009579002800671021004F582300041C004F -:1059A000001934002578FFEE00D87825346A81008C -:1059B000AD2A000CAD2F0010AD200014AD2C001846 -:1059C0000A0005332529001C03E00008240207D043 -:1059D00027BDFFE0AFB20018AFB10014AFB00010A8 -:1059E000AFBF001C0E00004D008088218F88005042 -:1059F0008F87004C3C05800834B2008001112821BB -:105A00003C10800024020080240300C000A7202353 -:105A1000AE0208183C068008AE03081C188000047B -:105A2000AF850050ACC500048CC90004AF89004CA0 -:105A300012200009360409800E0005F9000000005C -:105A4000924C00278E0B007401825004014B3021D0 -:105A5000AE46000C360409808C8E001C8F8F0058D7 -:105A600001CF682319A000048FBF001C8C90001C7C -:105A7000AF9000588FBF001C8FB200188FB1001478 -:105A80008FB000100A00004F27BD00208F860060F5 -:105A90008F8300508F82004C3C05800834A4008026 -:105AA000AC860050AC83003C03E00008ACA20004CC -:105AB0003C0308008C63005427BDFFF8308400FFCE -:105AC0002462000130A500FF3C010800AC22005414 -:105AD00030C600FF3C0780008CE801780500FFFE1F -:105AE0003C0A7FFFA3A400038FA400003549FFFFF9 -:105AF00000891824000647C000681025AFA20000E6 -:105B000090F9010AA3A000023C1880FFA3B900018C -:105B10008FAE000030AD007F370FFFFF01CF58245C -:105B2000000D66003C090020016C50253526200040 -:105B30002405FF803C04100027BD0008ACEA014C9E -:105B4000ACE60154A4E00158A0E5015203E00008CE -:105B5000ACE40178308800FF3C03800030A400FFF3 -:105B60008C6201780440FFFE000000003C038000CE -:105B700034660A008CCA0020346709800004482B70 -:105B8000AC6A01448CC5002400091540AC6501488D -:105B9000A068015090E4004CA064016D03E000088F -:105BA000A460015827BDFFE8308400FFAFBF00109C -:105BB0000E00065C30A500FF8F8300508FBF0010E1 -:105BC0003C058000344600402404FF903C02100055 -:105BD00027BD0018ACA3014CA0A40152ACA60154EF -:105BE00003E00008ACA2017827BDFFE03C08800874 -:105BF000AFBF001CAFB20018AFB10014AFB00010BF -:105C0000351000808E0600183C078000309200FF9F -:105C100000C72025AE0400180E00004D30B100FF73 -:105C200092030005346200080E00004FA202000536 -:105C3000024020210E00067002202821024020216F -:105C40008FBF001C8FB200188FB100148FB00010EE -:105C500024050005240600010A00063327BD0020A4 -:105C60003C05800034A309809066000830C200081B -:105C70001040000F3C0A01013549080AAC890000B8 -:105C80008CA80074AC8800043C07080090E73B90A7 -:105C900030E5001050A00008AC8000083C0D8008E2 -:105CA00035AC00808D8B0058AC8B00082484000C30 -:105CB00003E00008008010210A0006B32484000CD1 -:105CC00027BDFFE83C088000AFB00010AFBF001454 -:105CD0003506098090C7000924020006350909002D -:105CE00030E300FF0080802100A06021240B00042D -:105CF000106200792407000294CF005C3C0E02047D -:105D000031EDFFFF01AE5025AE0A000090C500083E -:105D100030A40020108000080000000090C2004E57 -:105D20003C1F010337F90300305800FF03193025E9 -:105D3000240B0008AE0600049139001191260012D0 -:105D400091240011333800FF0018708230CF00FF1B -:105D500001CF5021014C6821308800FF31AAFFFF9C -:105D600039030028000A28801460002B0205402314 -:105D7000912400123C0E800035D90980308500FF47 -:105D800000AC182100031080004BF821001F840094 -:105D9000360906FFAD09000435C909009126001136 -:105DA000912F0012000BC0828F2B003431ED00FFC9 -:105DB0008DC4010C01AC282100B810210164F82326 -:105DC0000007840000021F000070C82533E9FFFFB0 -:105DD00030CF00FC032970250158202101E86821FB -:105DE00000045080ADAE000C0E00004D010A802171 -:105DF0003C078008240C000434EB00800E00004FA8 -:105E0000A16C0009020010218FBF00148FB0001098 -:105E100003E0000827BD0018912500119123001907 -:105E20003C18080097183B8630A200FF0002F88259 -:105E3000307000FF001FCE0000104C0003293025F9 -:105E400000D870253C0F400001CF68253C0E800033 -:105E5000AD0D000035C9090091260011912F0012E7 -:105E600035D90980000BC08231ED00FF8F2B003443 -:105E70008DC4010C01AC282100B810210164F82365 -:105E80000007840000021F000070C82533E9FFFFEF -:105E900030CF00FC032970250158202101E868213A -:105EA00000045080ADAE000C0E00004D010A8021B0 -:105EB0003C078008240C000434EB00800E00004FE7 -:105EC000A16C0009020010218FBF00148FB00010D8 -:105ED00003E0000827BD00180A0006C524070012C9 -:105EE00027BDFFD0AFB60028AFB50024AFB4002067 -:105EF000AFB10014AFBF002CAFB3001CAFB200189D -:105F0000AFB000103C06800090C3010B309400FF3E -:105F100030B500FF306200300000B0211040009D1D -:105F20000000882134C409809088000800083E00E1 -:105F300000072E0304A000C4240400048F8700502F -:105F40003C010800A0243B903C0C8000AD80004840 -:105F50003C038000906D010B31A5002010A00007CC -:105F60003C0B8000347209809250000800107E00C3 -:105F7000000F760305C000C93C1980089169010B28 -:105F8000356A098091480008312400400004102B34 -:105F900031030008241200031460000200E2982379 -:105FA000000090213C108000360E0A80360809005F -:105FB00095C7002C910300119102001291C50018A1 -:105FC000307800FF305F00FF025FC8210019788041 -:105FD00091CC001801F8682101B1302130B100FFE7 -:105FE00000D11821A78700543C010800A4263B8655 -:105FF0003C010800A4233B8815800002000000003B -:106000000000000D9204010B3065FFFF3C01080009 -:10601000A4233B8A308900403C010800A4203B8037 -:106020003C010800A4203B7C1120000224A4000AAB -:1060300024A4000B3091FFFF0E0001B402202021A8 -:106040009219010B3C0E080095CE3B8A3C0D0800CE -:1060500091AD3B910019C182330F000101CF28217E -:10606000000D340024A7000200C758253C0C110085 -:10607000016C5025AC4A000024440008026028212D -:10608000024030210E00050FAC4000040E00069FB8 -:106090000040202116C00068004020219212010B10 -:1060A0003256004012C000053C0200FF8C930000F5 -:1060B000345FFFFF027F8024AC9000000E0001C817 -:1060C000022020213C03080090633B9030710003C4 -:1060D000122000163C1080088F8C00503C0B80086A -:1060E00035640080258A0001AC8A003C3C058008AC -:1060F0008CA9000401402021012A4023190000023C -:10610000AF8A00508CA400040E0005F9ACA4000472 -:106110003C0E80008DCD00743C05800834A60080C4 -:10612000004D3821ACC7000C3C10800836120080AE -:106130000280202102A02821A240006B0E00065CF4 -:106140003C1480008F9600503C151000AE96014C18 -:106150008F980048344F00068FBF002C271900018C -:10616000AF9900488FB60028A29801528FB3001C47 -:10617000AE8F01548FB20018AE9501788FB1001424 -:106180008FB500248FB400208FB0001003E000080A -:1061900027BD003034C30980906F0008000F7600DF -:1061A000000E6E0305A0003334DF090093F8001BD6 -:1061B000241900103C010800A0393B903313000261 -:1061C0001260FF638F8700508F82005C1447FF616D -:1061D0003C0380000E00004D000000003C048008DD -:1061E0003485008090A8000924070016310300FFC1 -:1061F0001067000D0000000090AB00093C0608008D -:1062000090C63B9024090008316400FF34CA0001A5 -:106210003C010800A02A3B901089002F240C000AA2 -:10622000108C00282402000C0E00004F000000001B -:106230000A00075B8F8700500E0006B70240282136 -:106240000A0007AE004020213C0B8008356A008020 -:106250008D4700548CC9010C1120FF39AF870050C5 -:10626000240600143C010800A0263B900A00075AAF -:106270003C0C800090710008241200023C010800D0 -:10628000A0323B90323000201200000B2416000197 -:106290008F8700500A00075B241100083733008005 -:1062A0008E7F0038AF3F00048F380004AE78003C8A -:1062B0000A0007663C0B80008F8700500A00075BCE -:1062C00024110004A0A200090E00004F00000000ED -:1062D0000A00075B8F870050240200140A00083967 -:1062E000A0A2000927BDFFE8AFBF0014AFB00010A7 -:1062F0003C10800092020109240500010E00065C9A -:10630000304400FF3C1F800893F8000E37E3008004 -:1063100093F9000F906E002693E9000A332F00FFD7 -:1063200000186600000F6C0031CB00FF018D502576 -:10633000000B320001463825312800FF344560004B -:1063400000E820252402FF813C031000AE04014C2C -:106350008FBF0014AE050154A2020152AE030178B2 -:106360008FB0001003E0000827BD001827BDFFE82C -:10637000308400FFAFBF00100E00065C30A500FFA8 -:10638000344600403C0480002405FF92AC86015452 -:10639000A08501528F8300508FBF00103C02100077 -:1063A00027BD0018AC83014C03E00008AC820178E3 -:1063B00027BDFFD8AFB20018AFB10014AFB00010C6 -:1063C000AFBF0020AFB3001C3C07800090E2010982 -:1063D000308600FF30B000FF000618C23204000211 -:1063E0003071000114800007305200FF3C09800822 -:1063F00035330080926800053105000810A0000CBC -:1064000030CA0010024020210E00068102202821FF -:10641000240200018FBF00208FB3001C8FB2001830 -:106420008FB100148FB0001003E0000827BD0028D2 -:106430001540003034E50A008CB900248CB80008FF -:1064400013380047000040213C0E800835D30080FF -:10645000926D0068240B000231AC00FF118B0080AC -:106460003C068000927F004C90C40109509F0004BC -:106470003213007C11000067000000003213007C22 -:106480001660005A0240202116200008320C00013C -:106490003C07800034EB0A008D6500248CE8010481 -:1064A00014A8FFDC00001021320C00011180000D47 -:1064B000024020213C1080008E0E010C8F8D006068 -:1064C00011CD0008000000000E00073F0220282127 -:1064D0008E0F010C3C18800837100080AE0F005062 -:1064E000024020210E000670022028210A00088C9C -:1064F000240200013C0708008CE7006424E6000148 -:106500003C010800AC2600641600000D00000000ED -:10651000022028210E00067002402021926F0068A0 -:10652000240D000231EE00FF11CD00220240202197 -:106530000E000840000000000A00088C2402000140 -:106540000E00004124040001926C0025020C582525 -:106550000E00004FA26B00250A0008CC0220282163 -:106560008E6300188CE401048CBF00240003160223 -:10657000149FFFB53045007F9269004C264400010E -:106580003093007F12650040312300FF1464FFAF99 -:106590003C0E8008264800013111007F310200FFC7 -:1065A0001225000B24080001004090210A000899E0 -:1065B00024110001240500040E0006332406000106 -:1065C0000E000840000000000A00088C24020001B0 -:1065D0002407FF800247282400A79026324200FFAC -:1065E000004090210A000899241100010E00073F85 -:1065F000022028213206003010C0FFA33210008292 -:10660000024020210E000681022028210A00088C69 -:10661000240200018E63001802402021022028215C -:10662000006610250E000862AE6200189264004CED -:1066300024050003240600010E000633308400FF09 -:106640000E00004124040001926A0025020A482538 -:106650000E00004FA26900250A00088C24020001E8 -:106660008E7800183C1980000240202103197825FB -:10667000022028210E000670AE6F00189264004CB4 -:106680000A000914240500043246008038CA00803C -:10669000146AFF6E3C0E80080A0008ED26480001CF -:1066A00027BDFFC0AFB000183C108000AFBF00385E -:1066B000AFB70034AFB60030AFB5002CAFB4002890 -:1066C000AFB30024AFB200200E0004BBAFB1001C7A -:1066D000920401089205010B308400FF0E0008733C -:1066E00030A500FF144000E58FBF00383C0980084A -:1066F00035280080A100006B3607098090E6000075 -:10670000240200503C17080026F73B4830C300FF26 -:106710003C13080026733B58106200033C108000B5 -:106720000000B82100009821241F001036110A0033 -:10673000361409808E1601048F8D00508E38002487 -:1067400036190A808E9200203C010800A03F3B9041 -:10675000972C002C8EF50000932B0018024D70230F -:1067600002D878233C010800AC2F3B6C3C010800A8 -:10677000AC2E3B703C010800AC2D3B94A78C005420 -:1067800002A0F809317200FF304A0002154000E80B -:106790003045000110A000C300000000928A0008EC -:1067A0003150000816000002241400030000A0214C -:1067B0003C06800034C4090034C30A008C6E0024F7 -:1067C00090850011908200129099001130B800FF5E -:1067D000305100FF0291F821001FB080332F00FFDD -:1067E00002D85821024FA82126AC0010017268215E -:1067F0003C1580003C010800AC2E3B983C01080091 -:10680000A42D3B883C010800A42C3B843C010800DB -:10681000A42B3B8636B609808F8700508F8900589D -:106820008ED20020240800060127302302472823A7 -:106830003C010800AC283B8C04C000B5000090214E -:1068400004A000B300C5802B120000B500000000BA -:106850003C010800AC263B708E7100000220F80954 -:1068600000000000304A0002154000740040802102 -:10687000304B0001556000118E7100043C0D080082 -:106880008DAD3B743C0EC0003C04800001AE602521 -:10689000AEAC0E008C980000330F000811E0FFFD35 -:1068A00000000000949F0E0824120001A79F0040E2 -:1068B0008C990E04AF9900388E7100040220F809FB -:1068C000000000000202802532020002144000B4E1 -:1068D000000000003C08080095083B7C3C110800C3 -:1068E00096313B883C09080095293B7E3C03080013 -:1068F0008C633B74011168213C1F08008FFF3B989B -:106900003C07080094E73B923C11800001A920213C -:106910008E38010C006828212499000200A77021FC -:1069200003E37821AF9800603C010800AC2F3B984E -:106930003C010800A42E3B803C010800A42D3B8AAA -:106940000E0001B43324FFFF8F8C0048004020214B -:106950003C010800A02C3B918E620008258B0001B1 -:10696000AF8B00480040F809000000008F85005000 -:10697000028030210E00050F004020210E00069FEE -:10698000004020218E6A000C0140F80900402021BF -:106990003C08080095083B8A3C09080095293B7E85 -:1069A0000109382124E600020E0001C830C4FFFFAF -:1069B0003C0408008C843B6C3C0308008C633B74F3 -:1069C000008328233C010800AC253B6C14A0000682 -:1069D000000000003C0A08008D4A3B8C3546004010 -:1069E0003C010800AC263B8C124000438F8C0044D5 -:1069F0008E2B0E108F920044AE4B00208E220E186C -:106A0000AE4200243C04080094843B800E0005FB49 -:106A1000000000008F9900508E7800103C010800A3 -:106A2000AC393B940300F809000000003C0F08005B -:106A30008DEF3B6C15E0FF798F87005097940054E1 -:106A40003C13800E321501000E00062AA674002C9D -:106A500016A00046320300105460004D8EE500047D -:106A60003207004054E0001D8EF000088EE4000C58 -:106A70000080F809000000008FBF00388FB7003495 -:106A80008FB600308FB5002C8FB400288FB3002450 -:106A90008FB200208FB1001C8FB0001803E00008F7 -:106AA00027BD0040920901098F88003C00093E0083 -:106AB00000E83025AE0600808E2300208E240024BE -:106AC000AFA30010AE030E148FA20010AE020E1082 -:106AD000AE040E1C0A00096EAE040E180200F8097E -:106AE000000000008EE4000C0080F80900000000A7 -:106AF0000A000A268FBF0038240E0001240D000171 -:106B0000A5800020A58E00220A000A08AD8D002471 -:106B10003C010800AC203B700A00099E8E71000009 -:106B20003C010800AC253B700A00099E8E710000F4 -:106B300092110109000028210E000670322400FF86 -:106B40008FBF00388FB700348FB600308FB5002C60 -:106B50008FB400288FB300248FB200208FB1001CA7 -:106B60008FB0001803E0000827BD00403C1F8000E4 -:106B700093F60109000028210E00073F32C400FFF0 -:106B8000320300105060FFB7320700408EE500046A -:106B900000A0F809000000000A000A2032070040A7 -:106BA0005240FFA7979400548EB60E148F93004462 -:106BB000AE7600208EB40E1CAE7400240A000A17B4 -:106BC000979400548F8200140004218003E0000891 -:106BD000008210213C07800834E200809043006965 -:106BE00000804021106000093C0401003C070800BF -:106BF0008CE73B948F83003000E32023048000085F -:106C00009389001C14E300030100202103E0000825 -:106C1000008010213C04010003E0000800801021E6 -:106C20001120000B006738233C0D800035AC098033 -:106C3000918B007C316A000211400020240900344D -:106C400000E9702B15C0FFF10100202100E9382375 -:106C50002403FFFC00A3C82400E3C02400F9782B20 -:106C600015E0FFEA0308202130C4000300041023CC -:106C700014C00014304900030000302100A978211D -:106C800001E6702100EE682B11A0FFE03C0401003A -:106C90002D3800010006C82B0105482103193824AE -:106CA00014E0FFDA2524FFFC2402FFFC00A21824D4 -:106CB0000068202103E00008008010210A000A97E4 -:106CC000240900303C0C80003586098090CB007C84 -:106CD000316A00041540FFE9240600040A000AA6F0 -:106CE000000030213C0308008C63005C8F82001898 -:106CF00027BDFFE8AFBF001410620005AFB0001061 -:106D0000000329C024A40280AF840014AF830018BC -:106D10003C10800036030A00946500320E000A78A9 -:106D200030A43FFF8E0401003C180080370F0003A1 -:106D30000082C8212402FF80032260243329007FBF -:106D4000000CF94003E94025332E00783C0D10007B -:106D5000010D502501CF5825AE0C002836080980BA -:106D6000AE0C080CAE0B082CAE0A0830910300697B -:106D70003C06800C0126382110600006AF870034E5 -:106D80008D09003C8D06006C0126382318E0007F39 -:106D9000000000003C0C8008358B00803C0A80001D -:106DA000A1600069355009808E0200383C068000E1 -:106DB00034C50A0090AD003C31A800201100001934 -:106DC000AF820030240E00013C19800037300A00E9 -:106DD000A38E001CAF8000248E0400248F85002425 -:106DE00024180008AF800020AF8000283C01080074 -:106DF000A4383B7E3C010800A4203B920E000A7C94 -:106E000000003021920F003C8FBF00148FB00010A3 -:106E1000000F7142AF82002C27BD001803E000086C -:106E200031C2000190B90032240F0001333800FF55 -:106E300000182182108F003F241F0002109F006263 -:106E400034C20AC03C03800034640A008C990024D8 -:106E50001720001D3466090090830030241F0005B0 -:106E60003062003F105F004C240500018F86002037 -:106E7000A385001CAF860028AF8600243C19800043 -:106E800037300A008E0400248F850024241800085F -:106E90003C010800A4383B7E3C010800A4203B9242 -:106EA0000E000A7C00000000920F003C8FBF00140F -:106EB0008FB00010000F7142AF82002C27BD001868 -:106EC00003E0000831C200018C8800088C8D00248A -:106ED0008CCB00643C19800037300A00AF8B002453 -:106EE000A380001C8E0400248F8600208F85002440 -:106EF000010D602324180008AF8C00283C01080015 -:106F0000A4383B7E3C010800A4203B920E000A7C82 -:106F100000000000920F003C8FBF00148FB00010E3 -:106F2000000F7142AF82002C27BD001803E000085B -:106F300031C2000190A7003030E3003F50640028C8 -:106F400034C50AC08CAA00241540002234C80900A8 -:106F50008CAB00483C0C7FFF3585FFFF016510249A -:106F60003C188000AF820020370509008F8E00207A -:106F70008CAF006001CF682B15A0000201C020215A -:106F80008CA400600A000B18AF8400208D02006CF6 -:106F90000A000AF33C0680008C8900488F86002096 -:106FA0003C0A7FFF3550FFFF013038243C04800845 -:106FB00024050001AF870028AC80006CA385001C6D -:106FC0000A000B26AF8600248C4400140A000B181C -:106FD000AF8400208D0200680A000B603C1880001E -:106FE00034C409808C8600708CB0001400D0482B0B -:106FF00011200004000000008C8200700A000B6069 -:107000003C1880008CA200140A000B603C18800021 -:107010008F85002427BDFFE0AFBF0018AFB100147B -:1070200014A00008AFB000103C04800034870A00B0 -:1070300090E600302402000530C3003F106200BE1D -:10704000348409008F91002000A080213C0480003E -:10705000348E0A008DCD00043C0608008CC63B70BF -:1070600031A73FFF00E6602B5580000100E0302192 -:10707000938F001C11E0007600D0102B349909800A -:107080009338007C3304000210800077240300341E -:1070900000C3F82B17E000DD00C3302300D0102B15 -:1070A0003C010800A4233B7C1440006D0200182121 -:1070B0003C0408008C843B6C0064282B54A0000125 -:1070C000006020213C05800034A90A009128003C82 -:1070D0003C010800AC243B74310300201460000222 -:1070E000000048218CA90E188F88002C0128502BF5 -:1070F0001140005F000000003C0508008CA53B74B7 -:1071000000A96021010C582B1160005C00B0682BB5 -:107110000109382300E028213C010800AC273B741A -:10712000120000032403FFFC10B00093322B000375 -:1071300000A310243C010800A4203B923C0108005D -:10714000AC223B74004028218F84002412040006E6 -:107150003C0A80088D4B006C02002021AF9100207A -:1071600025700001AD50006C8F8C002800858823AD -:10717000AF91002401852023AF8400281220000253 -:1071800024070018240700103C0F800835E6008013 -:1071900090CE00683C010800A0273B902407000126 -:1071A00031CD00FF11A7004A000000001480001834 -:1071B000000028213C0C800091850109359109804F -:1071C0008E2B001830A500FF24A30001000B8602BF -:1071D0003206007F306A007F114600852407FF8059 -:1071E0003C04800834890080A123004C3C0808003E -:1071F0008D083B8C240F00023C010800A02F3BD1DE -:10720000350E00083C010800AC2E3B8C2405001014 -:107210003C028000345F0A0093F9003C33380020C0 -:107220001300000500A02021240300013C010800F8 -:10723000AC233B7434A400018FBF00188FB100143D -:107240008FB000100080102103E0000827BD00204F -:107250003C010800A4203B7C1040FF95020018214F -:107260000A000BB300C018210A000BAB2403003046 -:107270003C0508008CA53B7400B0682B11A0FFA84A -:10728000000000003C04080094843B7C00857821C9 -:1072900001E7702B11C000242CA300043C1F6000E8 -:1072A0008FF954043338003F1300001F0000000022 -:1072B0003C0208008C4200A41040FFDF240400427E -:1072C00014A000198FBF00180A000C16000000005F -:1072D0001528FFB6000000008CC300183C19800080 -:1072E000241F000200791025ACC2001837380A00AC -:1072F000A0DF00689309003C2404000400A01021D2 -:10730000312800203C010800A0243BD111000002DC -:1073100024050010240200013C010800AC223B6C53 -:107320000A000C0C3C0280001060FF7D2404004227 -:107330000A000C168FBF00188F8800288C89006007 -:107340000109282B14A00002010088218C91006003 -:107350003C0B80008D640E18240A000102202821B5 -:1073600002203021A38A001C0E000A7C022080210A -:107370000A000B9AAF82002C000B5023122000074A -:10738000314400033C0E800035CD098091A7007C7C -:1073900030EC000415800019248F00043C01080023 -:1073A000A4243B923C19080097393B920325C02145 -:1073B00000D8202B1080FF658F8400242CA60005A8 -:1073C00014C0FF9D2404004230BF000317E00002F8 -:1073D00000BF182324A3FFFC3C010800AC233B742E -:1073E0003C010800A4203B920A000BD90060282130 -:1073F00000A768240A000BFF01A718263C0108001B -:10740000A42F3B920A000C70000000003C01080011 -:10741000AC203B740A000C15240400428F83002822 -:107420003C0B8000356A0A00146000060000102141 -:10743000914600302405000530C400FF108500038C -:107440000000000003E0000800000000914900482F -:10745000312800FF000839C214E0FFFA3C0480081C -:107460003C06080094C63B7C3C0308008C633B94BC -:107470003C0508008CA53B743C18080097183B920B -:107480000066C8218C8E00040325782101F868214C -:1074900001AE60231980001D000000009158004CCF -:1074A0008F8D0034956E0E10330F00FF8DA90004F0 -:1074B00001CF30238DAA000030CFFFFF000F610005 -:1074C000012C2821000038210147202100AC182B75 -:1074D0000083C821ADA50004ADB9000091B8000A31 -:1074E00001F87021A1AE000A956C0E128F8A00344B -:1074F000A54C00089549003825280001A54800380A -:107500009147000D34EB0008A14B000D03E000088B -:107510000000000027BDFFD8AFB00018938F001CFB -:107520008FB000143C087FFF8F8700243C0C800044 -:107530003518FFFFAFBF0020AFB1001C35990A001E -:1075400002181824932A003C000F5FC03C02BFFFC2 -:107550002CF000013449FFFF006BF8253C080800BF -:107560008D083B948F9900303C18080097183B8A8F -:1075700003E9582400107F803C07EFFF3C05F0FF33 -:10758000016F18253C1180003149002034E2FFFFD3 -:1075900034ADFFFF362E098027A500102406000217 -:1075A00001194023270A000200621824008080216C -:1075B00015200002000058218D8B0E1CA7AA001276 -:1075C0000500003A2407000030EF00FF000F3F00E5 -:1075D000006740253C028008AFA80014344B0080AF -:1075E000916A00683C0F080091EF3B913C09DFFF76 -:1075F000353FFFFF000A602B3C02080094423B84A9 -:10760000A3AF0011011FC024000CCF40031918259F -:107610008FA70010AFA300143C1F080093FF3B93FB -:10762000A7A200168FA8001400ED48243C0B01000F -:107630003C0A0FFF012BC82533F80003354CFFFF30 -:10764000010D78243C027000032C382400181E0021 -:1076500000E2482501E35825AFAB0014AFA90010A4 -:1076600091DF007CA3BF00150E0000630000000046 -:10767000362D0A0091A6003C30C400201080000680 -:10768000260200083C11080096313B80262EFFFFA1 -:107690003C010800A42E3B808FBF00208FB1001C4E -:1076A0008FB0001803E0000827BD00288F8A002C47 -:1076B000016A602B5580FFC4240700010A000CFA00 -:1076C00030EF00FF9383001C3C02800027BDFFD8F1 -:1076D00034480A0000805021AFBF002034460AC061 -:1076E000010028211060000E344409809107003009 -:1076F000240B00058F89002030EC003F118B000B1C -:1077000000003821AFA900103C0B80088D69006C87 -:10771000AFAA00180E00012BAFA90014A380001C13 -:107720008FBF002003E0000827BD00288D1F004800 -:107730003C1808008F183B748F9900283C027FFF8B -:107740008D0800443443FFFFAFA900103C0B8008B4 -:107750008D69006C03E370240319782101CF68233D -:1077600001A83821AFAA00180E00012BAFA9001400 -:107770000A000D4FA380001C3C05800034A60A00BF -:1077800090C7003C3C06080094C63B923C020800AF -:107790008C423B8C30E30020000624001060001E69 -:1077A000004438253C0880083505008090A3006817 -:1077B00000003021240800010000202124030001E2 -:1077C0003C0580008CAC01780580FFFE00000000C5 -:1077D000ACA80148A4A40144A4A301463C030800AA -:1077E0008C633B943C188008370F0080ACA3014C9D -:1077F0003C19080093393B913C0D1000A0B901528F -:10780000ACA70154A4A6015891EE004CA0AE016DA6 -:1078100003E00008ACAD01788CA80E1C3C0B0800FE -:107820008D6B3B7494AA0E1694A90E140166302138 -:107830003143FFFF0A000D773124FFFF3C04800035 -:1078400034830A009065003C30A200201040001CE8 -:10785000000000000000302100002021000018215D -:107860003C0580008CA901780520FFFE0000000087 -:10787000ACA601483C0E08008DCE3B94240DFF9130 -:10788000240C00403C0B8008A4A30144356A00800E -:10789000A4A40146ACAE014CA0AD0152ACAC015465 -:1078A000A4A0015890A301099144004C90A601099D -:1078B0003C041000A0A6016D03E00008ACA4017810 -:1078C0008C860E1894880E1294870E103104FFFFD8 -:1078D0000A000D9F30E3FFFF3C04800034830A0060 -:1078E0009065003C30A200201040002627BDFFF824 -:1078F0002409000100003821240800013C06800012 -:107900008CC401780480FFFE0000000090CA0109C9 -:107910003C04080090843BD13C1880FFA3AA0003DC -:107920008FA300003085007F370FFFFF0066102512 -:10793000AFA2000090D9010AA3A0000200056E00CA -:10794000A3B900018FAE0000240A300027BD000853 -:1079500001CF6024018D5825ACCB014CACCA015439 -:10796000A4C00158ACC90148A4C701442409FF8040 -:10797000A4C801463C081000A0C9015203E0000859 -:10798000ACC801788C890E1894870E1294860E105C -:1079900030E8FFFF0A000DC630C7FFFF27BDFFE834 -:1079A000AFB000103C108000AFBF001436180A00C2 -:1079B000970F00320E000A7831E43FFF8E0E01006F -:1079C000240DFF803C04200001C25821016D602479 -:1079D000000C4940316A007F012A40250104382506 -:1079E0003C048008AE0708303486008090C50068EB -:1079F0002403000230A200FF104300048F9F0020E8 -:107A00008F990024AC9F0068AC9900648FBF00146C -:107A10008FB0001003E0000827BD00183C0A0800E2 -:107A2000254A36583C090800252936F43C08080048 -:107A300025082B003C07080024E737B83C0608005F -:107A400024C634E03C05080024A532383C04080074 -:107A500024842E2C3C030800246335943C02080047 -:107A6000244233303C010800AC2A3B503C01080062 -:107A7000AC293B4C3C010800AC283B483C010800C9 -:107A8000AC273B543C010800AC263B643C01080099 -:107A9000AC253B5C3C010800AC243B583C01080091 -:107AA000AC233B683C010800AC223B6003E00008CB -:047AB00000000000D2 -:0C7AB400800009408000090080080100EB -:107AC0008008008080080000800E00008008008090 -:107AD0008008000080000A8080000A008000098081 -:047AE0008000090019 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex new file mode 100644 index 000000000000..7f39b4a7f331 --- /dev/null +++ b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex @@ -0,0 +1,6488 @@ +:10000000080001180800000000005594000000C816 +:1000100000000000000000000000000008005594EF +:10002000000000380000565C080000A00800000036 +:100030000000574400005694080059200000008436 +:100040000000ADD808005744000001C00000AE5CBD +:100050000800321008000000000090900000B01C62 +:100060000000000000000000000000000800909068 +:100070000000033C000140AC0800049008000400AC +:10008000000012FC000143E8000000000000000036 +:1000900000000000080016FC00000004000156E407 +:1000A000080000A80800000000003D28000156E8F4 +:1000B00000000000000000000000000008003D28D3 +:0800C000000000300001941063 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E302E31E1 +:1000E00037000000060011020000000000000003BD +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C020800244256083C030800A1 +:1002000024635754AC4000000043202B1480FFFDB2 +:10021000244200043C1D080037BD9FFC03A0F021D0 +:100220003C100800261001183C1C0800279C5608AA +:100230000E000256000000000000000D27BDFFB4B4 +:10024000AFA10000AFA20004AFA30008AFA4000C50 +:10025000AFA50010AFA60014AFA70018AFA8001CF0 +:10026000AFA90020AFAA0024AFAB0028AFAC002C90 +:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 +:10028000AFB90040AFBC0044AFBF00480E001544FA +:10029000000000008FBF00488FBC00448FB90040B1 +:1002A0008FB8003C8FAF00388FAE00348FAD003078 +:1002B0008FAC002C8FAB00288FAA00248FA90020C0 +:1002C0008FA8001C8FA700188FA600148FA5001000 +:1002D0008FA4000C8FA300088FA200048FA1000040 +:1002E00027BD004C3C1B60108F7A5030377B502864 +:1002F00003400008AF7A00008F82002427BDFFE092 +:10030000AFB00010AFBF0018AFB100148C42000CAA +:100310003C1080008E110100104000348FBF001887 +:100320000E000D84000000008F85002024047FFF54 +:100330000091202BACB100008E030104960201084D +:1003400000031C003042FFFF00621825ACA300042C +:100350009202010A96030114304200FF3063FFFF4E +:100360000002140000431025ACA200089603010C03 +:100370009602010E00031C003042FFFF00621825A8 +:10038000ACA3000C960301109602011200031C009E +:100390003042FFFF00621825ACA300108E02011846 +:1003A000ACA200148E02011CACA20018148000083C +:1003B0008F820024978200003C0420050044182509 +:1003C00024420001ACA3001C0A0000C6A782000062 +:1003D0003C0340189442001E00431025ACA2001CB0 +:1003E0000E000DB8240400018FBF00188FB1001457 +:1003F0008FB000100000102103E0000827BD00208E +:100400003C0780008CE202B834E50100044100089A +:10041000240300013C0208008C42006024420001D9 +:100420003C010800AC22006003E0000800601021DD +:100430003C0208008C42005C8CA4002094A30016AF +:100440008CA6000494A5000E24420001ACE40280B6 +:100450002463FFFC3C010800AC22005C3C0210005D +:10046000A4E30284A4E5028600001821ACE6028819 +:10047000ACE202B803E000080060102127BDFFE0F5 +:100480003C028000AFB0001034420100AFBF001C3E +:10049000AFB20018AFB100148C43000094450008BF +:1004A0002462FE002C42038110400003000381C23D +:1004B0000A00010226100004240201001462000553 +:1004C0003C1180003C02800890420004305000FF44 +:1004D0003C11800036320100964300143202000FB6 +:1004E00000021500004310253C0308008C63004403 +:1004F00030A40004AE220080246300013C01080007 +:10050000AC2300441080000730A200028FBF001C03 +:100510008FB200188FB100148FB000100A0000CE07 +:1005200027BD00201040002D0000182130A20080BF +:1005300010400005362200708E44001C0E000C672F +:10054000240500A0362200708C4400008F82000C2D +:10055000008210232C43012C10600004AF82001095 +:10056000240300010A000145AF84000C8E42000400 +:100570003C036020AF84000CAC6200143C02080015 +:100580008C42005850400015000018218C62000475 +:10059000240301FE304203FF144300100000182121 +:1005A0002E020004104000032E0200080A00014041 +:1005B0000000802114400003000000000A000140F8 +:1005C0002610FFF90000000D2402000202021004B0 +:1005D0003C036000AC626914000018218FBF001C4E +:1005E0008FB200188FB100148FB00010006010217E +:1005F00003E0000827BD00203C0480008C8301003C +:1006000024020100506200033C0280080000000D3B +:100610003C02800890430004000010213063000F6A +:1006200000031D0003E00008AC8300800004188074 +:100630002782FF9C00621821000410C00044102390 +:100640008C640000000210C03C030800246356E4E0 +:10065000004310213C038000AC64009003E00008DC +:10066000AF8200243C0208008C42011410400019A3 +:100670003084400030A2007F000231C03C02020002 +:100680001080001400A218253C026020AC43001426 +:100690003C0408008C8456B83C0308008C630110AD +:1006A0003C02800024050900AC4500200086202182 +:1006B000246300013C028008AC4400643C01080053 +:1006C000AC2301103C010800AC2456B803E000083C +:1006D000000000003C02602003E00008AC4500146C +:1006E00003E000080000102103E0000800001021D2 +:1006F00030A2000810400008240201003C0208005B +:100700008C42010C244200013C010800AC22010C87 +:1007100003E0000800000000148200080000000050 +:100720003C0208008C4200FC244200013C0108000D +:10073000AC2200FC0A0001A330A200203C02080009 +:100740008C420084244200013C010800AC22008459 +:1007500030A200201040000830A200103C02080027 +:100760008C420108244200013C010800AC2201082F +:1007700003E0000800000000104000080000000036 +:100780003C0208008C420104244200013C010800A4 +:10079000AC22010403E00008000000003C02080055 +:1007A0008C420100244200013C010800AC220100FF +:1007B00003E000080000000027BDFFE0AFB1001417 +:1007C0003C118000AFB20018AFBF001CAFB00010EA +:1007D0003632010096500008320200041040000733 +:1007E000320300028FBF001C8FB200188FB10014BB +:1007F0008FB000100A0000CE27BD00201060000B53 +:10080000020028218E2401000E00018A0000000051 +:100810003202008010400003240500A10E000C6786 +:100820008E44001C0A0001E3240200018E2301040F +:100830008F82000810430006020028218E24010048 +:100840000E00018A000000008E220104AF82000821 +:10085000000010218FBF001C8FB200188FB1001450 +:100860008FB0001003E0000827BD00202C82000498 +:1008700014400002000018212483FFFD240200021E +:10088000006210043C03600003E00008AC626914DD +:1008900027BDFFE0AFBF001CAFB20018AFB100141E +:1008A000AFB000103C048000948201083043700017 +:1008B000240220001062000A2862200154400052E5 +:1008C0008FBF001C24024000106200482402600018 +:1008D0001062004A8FBF001C0A0002518FB200183C +:1008E00034820100904300098C5000189451000C90 +:1008F000240200091062001C0000902128620009F7 +:10090000144000218F8200242402000A5062001249 +:10091000323100FF2402000B1062000F00000000C3 +:100920002402000C146200188F8200243C0208008C +:100930008C4256B824030900AC83002000501021DB +:100940003C038008AC6200643C010800AC2256B84D +:100950000A0002508FBF001C0E0001E900102602A1 +:100960000A0002308F8200240E0001E900102602E6 +:100970003C0380089462001A8C72000C3042FFFF26 +:10098000020280258F8200248C42000C5040001E01 +:100990008FBF001C0E000D84000000003C02800090 +:1009A00034420100944300088F82002400031C009D +:1009B0009444001E8F82002000641825AC50000073 +:1009C00024040001AC510004AC520008AC40000CFF +:1009D000AC400010AC400014AC4000180E000DB844 +:1009E000AC43001C0A0002508FBF001C0E000440E4 +:1009F000000000000A0002508FBF001C0E000C9F78 +:100A0000000000008FBF001C8FB200188FB10014CF +:100A10008FB000100000102103E0000827BD002067 +:100A200027BDFFD8AFB400203C036010AFBF002447 +:100A3000AFB3001CAFB20018AFB10014AFB00010DC +:100A40008C6450002402FF7F3C1408002694563822 +:100A5000008220243484380CAC6450003C028000B6 +:100A6000240300370E0014B0AC4300083C07080014 +:100A700024E70618028010212404001D2484FFFFAF +:100A8000AC4700000481FFFD244200043C02080042 +:100A9000244207C83C010800AC2256403C02080032 +:100AA000244202303C030800246306203C04080072 +:100AB000248403B43C05080024A506F03C06080085 +:100AC00024C62C9C3C010800AC2256803C02080045 +:100AD000244205303C010800AC2756843C01080044 +:100AE000AC2656943C010800AC23569C3C010800FF +:100AF000AC2456A03C010800AC2556A43C010800DB +:100B0000AC2256A83C010800AC23563C3C0108002E +:100B1000AC2456443C010800AC2056603C0108005F +:100B2000AC2556643C010800AC2056703C0108001E +:100B3000AC27567C3C010800AC2656903C010800CE +:100B4000AC2356980E00056E00000000AF80000C2C +:100B50003C0280008C5300008F8300043C0208009C +:100B60008C420020106200213262000700008821C0 +:100B70002792FF9C3C100800261056E43C02080017 +:100B80008C42002024050001022518040043202483 +:100B90008F820004004310245044000C26310001D1 +:100BA00010800008AF9000248E4300003C028000BB +:100BB000AC4300900E000D4BAE05000C0A0002C1C4 +:100BC00026310001AE00000C263100012E22000269 +:100BD000261000381440FFE9265200043C020800A9 +:100BE0008C420020AF820004326200071040FFD91F +:100BF0003C028000326200011040002D326200028F +:100C00003C0580008CA2010000002021ACA2002045 +:100C10008CA301042C42078110400008ACA300A85B +:100C200094A2010824032000304270001443000302 +:100C30003C02800890420005304400FF0E0001593C +:100C4000000000003C0280009042010B304300FF96 +:100C50002C62001E54400004000310800E00018628 +:100C60000A0002EC00000000005410218C42000039 +:100C70000040F80900000000104000043C02800021 +:100C80008C4301043C026020AC4300143C02080089 +:100C90008C4200343C0440003C03800024420001AC +:100CA000AC6401383C010800AC220034326200021E +:100CB00010400010326200043C1080008E0201409F +:100CC000000020210E000159AE0200200E00038317 +:100CD000000000003C024000AE0201783C02080027 +:100CE0008C420038244200013C010800AC2200384C +:100CF000326200041040FF973C0280003C108000EC +:100D00008E020180000020210E000159AE02002059 +:100D10008E03018024020F00546200073C02800809 +:100D20008E0201883C0300E03042FFFF00431025A3 +:100D30000A000328AE020080344200809042000086 +:100D400024030050304200FF14430007000000005D +:100D50000E000362000000001440000300000000C9 +:100D60000E000971000000003C0208008C42003CAB +:100D70003C0440003C03800024420001AC6401B804 +:100D80003C010800AC22003C0A0002A33C028000A7 +:100D90003C02900034420001008220253C02800089 +:100DA000AC4400203C0380008C6200200440FFFE25 +:100DB0000000000003E00008000000003C0280008A +:100DC000344300010083202503E00008AC440020E8 +:100DD00027BDFFE0AFB10014AFB000100080882144 +:100DE000AFBF00180E00033230B000FF8F83FF94B6 +:100DF000022020219062002502028025A07000259B +:100E00008C7000183C0280000E00033D020280241A +:100E10001600000B8FBF00183C0480008C8201F884 +:100E20000440FFFE348201C024030002AC510000E4 +:100E3000A04300043C021000AC8201F88FBF0018F0 +:100E40008FB100148FB0001003E0000827BD002010 +:100E500027BDFFE83C028000AFBF00103442018094 +:100E6000944300048C4400083063020010600005C5 +:100E7000000028210E00100C000000000A0003787A +:100E8000240500013C02FF000480000700821824B2 +:100E90003C02040014620004240500018F82FF94C8 +:100EA00090420008240500018FBF001000A010210F +:100EB00003E0000827BD00188F82FF982405000179 +:100EC000A040001A3C028000344201400A00034264 +:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E +:100EE000AFB20018AFB10014AFB0001090A2000074 +:100EF000304400FF38830020388200300003182B74 +:100F00000002102B0062182410600003240200501D +:100F1000148200A88FBF001C90A20005304200017F +:100F2000104000A48FBF001C3C02800034420140EE +:100F3000904200082443FFFF2C6200051040009EF1 +:100F40008FB20018000310803C030800246355ACE6 +:100F5000004310218C420000004000080000000007 +:100F60003C028000345101400E0003328E24000008 +:100F70008F92FF948E2200048E50000C1602000205 +:100F800024020001AE42000C0E00033D8E2400003E +:100F90008E220004145000068FBF001C8FB2001870 +:100FA0008FB100148FB000100A000F7827BD002009 +:100FB0008E42000C0A000419000000003C0480006E +:100FC0003482014094A300108C4200043063FFFF80 +:100FD0001443001C0000000024020001A4A2001021 +:100FE0008C8202380441000F3C0380003C02003F29 +:100FF0003448F0003C0760003C06FFC08CE22BBC8C +:1010000000461824004810240002130200031D8229 +:10101000106200583C0280008C8202380440FFF7C6 +:101020003C038000346201408C44000034620200C2 +:10103000AC4400003C021000AC6202380A00043BE1 +:101040008FBF001C94A200100A00041900000000C9 +:10105000240200201482000F3C0280003C03800028 +:1010600094A20012346301408C6300043042FFFFFD +:10107000146200050000000024020001A4A2001276 +:101080000A0004028FBF001C94A200120A00041977 +:1010900000000000345101400E0003328E24000095 +:1010A0008F92FF948E230004964200123050FFFF6F +:1010B0001603000224020001A64200120E00033DA6 +:1010C0008E2400008E220004160200068FBF001C32 +:1010D0008FB200188FB100148FB000100A00037C8B +:1010E00027BD0020964200120A00041900000000EB +:1010F0003C03800094A20014346301408C6300041C +:101100003042FFFF14620008240200018FBF001C60 +:101110008FB200188FB100148FB00010A4A2001479 +:101120000A00146327BD002094A20014144000217B +:101130008FBF001C0A000435000000003C03800043 +:1011400094A20016346301408C6300043042FFFF18 +:101150001462000D240200018FBF001C8FB2001822 +:101160008FB100148FB00010A4A200160A000B1457 +:1011700027BD00209442007824420004A4A200105D +:101180000A00043B8FBF001C94A200162403000138 +:101190003042FFFF144300078FBF001C3C020800D1 +:1011A0008C420070244200013C010800AC22007017 +:1011B0008FBF001C8FB200188FB100148FB00010C9 +:1011C00003E0000827BD002027BDFFD8AFB20018FC +:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB +:1011E000AFB000103C028000345101008C5001006F +:1011F0009242000092230009304400FF2402001FA5 +:10120000106200AB28620020104000192402003850 +:101210002862000A1040000D2402000B286200081A +:101220001040002E8F820024046001042862000216 +:101230001440002A8F820024240200061062002637 +:101240008FBF00200A00055F8FB3001C1062006092 +:101250002862000B144000FA8FBF00202402000E09 +:10126000106200788F8200240A00055F8FB3001C93 +:10127000106200D2286200391040000A2402008067 +:1012800024020036106200E528620037104000C3D7 +:1012900024020035106200D98FBF00200A00055FCC +:1012A0008FB3001C1062002D2862008110400006E0 +:1012B000240200C824020039106200C98FBF002038 +:1012C0000A00055F8FB3001C106200A28FBF0020D0 +:1012D0000A00055F8FB3001C8F8200248C42000C33 +:1012E000104000D78FBF00200E000D8400000000CA +:1012F0003C038000346301008C6200008F85002075 +:10130000946700089466000CACA200008C64000492 +:101310008F82002400063400ACA400049448001E10 +:101320008C62001800073C0000E83825ACA20008D9 +:101330008C62001C24040001ACA2000C9062000A24 +:1013400000C23025ACA60010ACA00014ACA0001860 +:10135000ACA7001C0A00051D8FBF00208F8200244F +:101360008C42000C104000B68FBF00200E000D8490 +:10137000000000008F820024962400089625000CAF +:101380009443001E000422029626000E8F82002045 +:10139000000426000083202500052C003C0300806B +:1013A00000A6282500832025AC400000AC400004A6 +:1013B000AC400008AC40000CAC450010AC40001440 +:1013C000AC400018AC44001C0A00051C24040001B9 +:1013D0009622000C14400018000000009242000504 +:1013E0003042001014400014000000000E000332D0 +:1013F0000200202192420005020020213442001008 +:101400000E00033DA242000592420000240300208A +:10141000304200FF10430089020020218FBF0020CE +:101420008FB3001C8FB200188FB100148FB0001062 +:101430000A00107527BD00280000000D0A00055E97 +:101440008FBF00208C42000C1040007D8FBF002019 +:101450000E000D84000000008E2200048F84002006 +:101460009623000CAC8200003C0280089445002CBE +:101470008F82002400031C0030A5FFFF9446001E4D +:101480003C02400E0065182500C23025AC830004E4 +:10149000AC800008AC80000CAC800010AC80001464 +:1014A000AC800018AC86001C0A00051C2404000156 +:1014B0000E000332020020218F93FF9802002021AA +:1014C0000E00033DA660000C020020210E00034226 +:1014D000240500018F8200248C42000C104000582B +:1014E0008FBF00200E000D84000000009622000C2B +:1014F0008F83002000021400AC700000AC62000476 +:10150000AC6000088E4400388F820024AC64000C6C +:101510008E46003C9445001E3C02401FAC66001005 +:1015200000A228258E62000424040001AC6200148D +:10153000AC600018AC65001C8FBF00208FB3001C8E +:101540008FB200188FB100148FB000100A000DB8D0 +:1015500027BD0028240200201082003A8FB3001C0F +:101560000E000F5E00000000104000358FBF00200D +:101570003C0480008C8201F80440FFFE348201C0EC +:1015800024030002AC500000A04300043C02100001 +:10159000AC8201F80A00055E8FBF00200200202106 +:1015A0008FBF00208FB3001C8FB200188FB10014C2 +:1015B0008FB000100A000EA727BD00289625000C4A +:1015C000020020218FBF00208FB3001C8FB20018B3 +:1015D0008FB100148FB000100A000ECC27BD002878 +:1015E000020020218FB3001C8FB200188FB10014AD +:1015F0008FB000100A000EF727BD00289225000DBD +:10160000020020218FB3001C8FB200188FB100148C +:101610008FB000100A000F4827BD002802002021CB +:101620008FBF00208FB3001C8FB200188FB1001441 +:101630008FB000100A000F1F27BD00288FBF0020A9 +:101640008FB3001C8FB200188FB100148FB0001040 +:1016500003E0000827BD00283C0580008CA202782A +:101660000440FFFE34A2024024030002AC44000008 +:10167000A04300043C02100003E00008ACA2027882 +:10168000A380001803E00008A38000193C03800039 +:101690008C6202780440FFFE8F82001CAC62024024 +:1016A00024020002A06202443C02100003E0000891 +:1016B000AC6202783C02600003E000088C425404F3 +:1016C0009083003024020005008040213063003FF9 +:1016D0000000482114620005000050219082004C57 +:1016E0009483004E304900FF306AFFFFAD00000CCC +:1016F000AD000010AD000024950200148D05001C03 +:101700008D0400183042FFFF004910230002110031 +:10171000000237C3004038210086202300A2102B8E +:101720000082202300A72823AD05001CAD0400186B +:10173000A5090014A5090020A50A001603E0000869 +:10174000A50A002203E000080000000027BDFFD822 +:10175000AFB200183C128008AFB40020AFB3001C39 +:10176000AFB10014AFBF0024AFB00010365101007C +:101770003C0260008C4254049222000C3C1408008D +:10178000929400F7304300FF2402000110620032FF +:101790000080982124020002146200353650008037 +:1017A0000E00143D000000009202004C2403FF8054 +:1017B0003C0480003042007F000211C024420240FD +:1017C0000262102100431824AC8300949245000863 +:1017D0009204004C3042007F3C03800614850007D1 +:1017E000004380212402FFFFA22200112402FFFFF8 +:1017F000A62200120A0005D22402FFFF9602002052 +:10180000A222001196020022A62200128E020024BB +:101810003C048008AE2200143485008090A2004C65 +:1018200034830100A06200108CA2003CAC6200185E +:101830008C820068AC6200F48C820064AC6200F0C0 +:101840008C82006CAC6200F824020001A0A2006847 +:101850000A0005EE3C0480080E001456000000004B +:1018600036420080A04000680A0005EE3C04800873 +:10187000A2000068A20000690A0006293C02800854 +:10188000348300808C62003834850100AC62006CC7 +:1018900024020001A062006990A200D59083000894 +:1018A000305100FF3072007F12320019001111C058 +:1018B00024420240026210212403FF8000431824C6 +:1018C0003C048000AC8300943042007F3C038006DF +:1018D000004380218E02000C1040000D02002021E8 +:1018E0000E00057E0000000026220001305100FF9E +:1018F0009203003C023410260002102B0002102339 +:101900003063007F022288240A0005F8A203003C0D +:101910003C088008350401008C8200E03507008017 +:10192000ACE2003C8C8200E0AD02000090E5004C8F +:10193000908600D590E3004C908400D52402FF806F +:1019400000A228243063007F308400FF00A62825F1 +:101950000064182A1060000230A500FF38A500803E +:10196000A0E5004CA10500093C0280089043000E50 +:10197000344400803C058000A043000A8C8300189A +:101980003C027FFF3442FFFF00621824AC83001842 +:101990008CA201F80440FFFE00000000ACB301C0BF +:1019A0008FBF00248FB400208FB3001C8FB20018AB +:1019B0008FB100148FB0001024020002A0A201C455 +:1019C00027BD00283C02100003E00008ACA201F88B +:1019D00090A2000024420001A0A200003C030800E5 +:1019E0008C6300F4304200FF144300020080302179 +:1019F000A0A0000090A200008F84001C000211C073 +:101A00002442024024830040008220212402FF80DF +:101A1000008220243063007F3C02800A006218218B +:101A20003C028000AC44002403E00008ACC300008A +:101A300094820006908300058C85000C8C86001033 +:101A40008C8700188C88001C8C8400203C010800C6 +:101A5000A42256C63C010800A02356C53C0108003C +:101A6000AC2556CC3C010800AC2656D03C01080001 +:101A7000AC2756D83C010800AC2856DC3C010800D5 +:101A8000AC2456E003E00008000000003C0280089F +:101A9000344201008C4400343C038000346504006F +:101AA000AC6400388C420038AF850028AC62003C42 +:101AB0003C020005AC6200300000000000000000A5 +:101AC00003E00008000000003C020006308400FF34 +:101AD000008220253C028000AC4400300000000061 +:101AE00000000000000000003C0380008C62000049 +:101AF000304200101040FFFD3462040003E0000893 +:101B0000AF82002894C200003C080800950800CA73 +:101B100030E7FFFF0080482101021021A4C200002D +:101B200094C200003042FFFF00E2102B544000013D +:101B3000A4C7000094A200003C0308008C6300CC02 +:101B400024420001A4A2000094A200003042FFFF42 +:101B5000144300073C0280080107102BA4A00000DA +:101B60005440000101003821A4C700003C02800855 +:101B7000344601008CC3002894A200003C0480007D +:101B80003042FFFE000210C000621021AC82003C17 +:101B90008C82003C006218231860000400000000E2 +:101BA0008CC200240A0006BA244200018CC2002420 +:101BB000AC8200383C020050344200103C038000EC +:101BC000AC620030000000000000000000000000D7 +:101BD0008C620000304200201040FFFD0000000039 +:101BE00094A200003C04800030420001000210C0BA +:101BF000004410218C430400AD2300008C420404F7 +:101C0000AD2200043C02002003E00008AC8200305A +:101C100027BDFFE0AFB20018AFB10014AFB00010A5 +:101C2000AFBF001C94C2000000C080213C1208001D +:101C3000965200C624420001A6020000960300004E +:101C400094E2000000E03021144300058FB1003021 +:101C50000E00068F024038210A0006F10000000045 +:101C60008C8300048C82000424420040046100073D +:101C7000AC8200048C8200040440000400000000D8 +:101C80008C82000024420001AC8200009602000019 +:101C90003042FFFF50520001A600000096220000D3 +:101CA00024420001A62200003C02800834420100C8 +:101CB000962300009442003C144300048FBF001C94 +:101CC00024020001A62200008FBF001C8FB2001862 +:101CD0008FB100148FB0001003E0000827BD002072 +:101CE00027BDFFE03C028008AFBF0018344201006E +:101CF0008C4800343C03800034690400AC68003830 +:101D00008C42003830E700FFAF890028AC62003C0D +:101D10003C020005AC620030000000000000000042 +:101D200000000000000000000000000000000000B3 +:101D30008C82000C8C82000C97830016AD22000070 +:101D40008C82001000604021AD2200048C820018BB +:101D5000AD2200088C82001CAD22000C8CA2001465 +:101D6000AD2200108C820020AD220014908200056C +:101D7000304200FF00021200AD2200188CA20018B1 +:101D8000AD22001C8CA2000CAD2200208CA2001001 +:101D9000AD2200248CA2001CAD2200288CA20020C1 +:101DA000AD22002C3402FFFFAD260030AD20003400 +:101DB000506200013408FFFFAD28003850E00011E8 +:101DC0003C0280083C048008348401009482005066 +:101DD0003042FFFFAD22003C9483004494850044D0 +:101DE000240200013063FFFF000318C200641821C1 +:101DF0009064006430A5000700A210040A00075C8C +:101E00000044102534420100AD20003C94430044BE +:101E1000944400443063FFFF000318C2006218219D +:101E200030840007906500642402000100821004E1 +:101E30000002102700451024A0620064000000008A +:101E400000000000000000003C0200063442004098 +:101E50003C038000AC620030000000000000000085 +:101E6000000000008C620000304200101040FFFDB6 +:101E70003C06800834C201503463040034C7014A70 +:101E800034C4013434C5014034C60144AFA200104B +:101E90000E0006D2AF8300288FBF001803E00008B1 +:101EA00027BD00208F8300143C0608008CC600E884 +:101EB0008F82001C30633FFF000319800046102111 +:101EC000004310212403FF80004318243C068000B7 +:101ED000ACC300283042007F3C03800C004330211B +:101EE00090C2000D30A500FF0000382134420010E0 +:101EF000A0C2000D8F8900143C028008344201000A +:101F00009443004400091382304800032402000176 +:101F1000A4C3000E1102000B2902000210400005AC +:101F2000240200021100000C240300010A0007A48F +:101F30000000182111020006000000000A0007A49A +:101F4000000018218CC2002C0A0007A424430001C1 +:101F50008CC20014244300018CC200180043102BD3 +:101F60005040000A240700012402002714A20003A5 +:101F70003C0380080A0007B1240700013463010014 +:101F80009462004C24420001A462004C00091382B8 +:101F9000304300032C620002104000090080282119 +:101FA000146000040000000094C200340A0007C15D +:101FB0003046FFFF8CC600380A0007C10080282188 +:101FC000000030213C040800248456C00A000706A3 +:101FD0000000000027BDFF90AFB60068AFB50064F9 +:101FE000AFB40060AFB3005CAFB20058AFB1005403 +:101FF000AFBF006CAFB000508C9000000080B021EB +:102000003C0208008C4200E8960400328F83001CDA +:102010002414FF8030843FFF0062182100042180D7 +:1020200000641821007410243C13800000A090214B +:1020300090A50000AE620028920400323C02800CA1 +:102040003063007F00628821308400C02402004099 +:10205000148200320000A8218E3500388E2200182C +:102060001440000224020001AE2200189202003C3B +:10207000304200201440000E8F83001C000511C068 +:102080002442024000621821306400783C02008043 +:102090000082202500741824AE630800AE64081086 +:1020A0008E2200188E03000800431021AE22001873 +:1020B0008E22002C8E230018244200010062182B6F +:1020C0001060004300000000924200002442000122 +:1020D000A24200003C0308008C6300F4304200FF81 +:1020E00050430001A2400000924200008F84001C77 +:1020F000000211C024420240248300403063007F6C +:10210000008220213C02800A0094202400621821D1 +:10211000AE6400240A0008D2AEC30000920300326D +:102120002402FFC000431024304200FF1440000589 +:1021300024020001AE220018962200340A00084250 +:102140003055FFFF8E22001424420001AE220018F9 +:102150009202003000021600000216030441001C27 +:10216000000000009602003227A400100080282101 +:10217000A7A20016960200320000302124070001B9 +:102180003042FFFFAF8200140E000706AFA0001C14 +:10219000960200328F83001C3C0408008C8400E807 +:1021A00030423FFF000211800064182100621821B4 +:1021B00000741024AE62002C3063007F3C02800E5D +:1021C000006218219062000D3042007FA062000D75 +:1021D0009222000D304200105040007892420000E0 +:1021E0003C028008344401009482004C8EC30000FD +:1021F0003C130800967300C62442FFFFA482004CE3 +:10220000946200329623000E3054FFFF3070FFFFBF +:102210003C0308008C6300D000701807A7A30038A7 +:102220009482003E3063FFFF3042FFFF14620007DC +:10223000000000008C8200303C038000244200300B +:10224000AC62003C0A00086A8C82002C9482004038 +:102250003042FFFF5462000927A400408C820038FE +:102260003C03800024420030AC62003C8C8200348D +:10227000AC6200380A0008793C03800027A50038CA +:1022800027A60048026038210E00068FA7A000484C +:102290008FA300403C02800024630030AC43003830 +:1022A0008FA30044AC43003C3C0380003C0200058B +:1022B000AC6200303C028008344401009482004249 +:1022C000346304003042FFFF0202102B1440000769 +:1022D000AF8300289482004E9483004202021021B2 +:1022E000004310230A00088F3043FFFF9483004E01 +:1022F00094820042026318210050102300621823C8 +:102300003063FFFF3C028008344401009482003CAB +:102310003042FFFF14430003000000000A00089F42 +:10232000240300019482003C3042FFFF0062102B26 +:10233000144000058F8200289482003C0062102324 +:102340003043FFFF8F820028AC550000AC400004F2 +:10235000AC540008AC43000C3C02000634420010B0 +:102360003C038000AC620030000000000000000070 +:10237000000000008C620000304200101040FFFDA1 +:102380003C04800834840100001018C20064182145 +:102390009065006432020007240600010046100424 +:1023A00000451025A0620064948300429622000E2E +:1023B00050430001A386001892420000244200010D +:1023C000A24200003C0308008C6300F4304200FF8E +:1023D00050430001A2400000924200008F84001C84 +:1023E000000211C0244202402483004000822021C8 +:1023F0002402FF80008220243063007F3C02800A98 +:10240000006218213C028000AC440024AEC30000EE +:102410008FBF006C8FB600688FB500648FB400600A +:102420008FB3005C8FB200588FB100548FB0005052 +:1024300003E0000827BD007027BDFFD8AFB3001C24 +:10244000AFB20018AFB10014AFB00010AFBF0020A2 +:102450000080982100E0802130B1FFFF0E000D8444 +:1024600030D200FF0000000000000000000000006B +:102470008F8200208F830024AC510000AC520004F6 +:10248000AC530008AC40000CAC400010AC40001451 +:10249000AC4000189463001E02038025AC50001C61 +:1024A0000000000000000000000000002404000103 +:1024B0008FBF00208FB3001C8FB200188FB10014A3 +:1024C0008FB000100A000DB827BD002830A5FFFF0F +:1024D0000A0008DC30C600FF3C02800834430100DB +:1024E0009462000E3C080800950800C63046FFFFC5 +:1024F00014C000043402FFFF946500EA0A000929B1 +:102500008F84001C10C20027000000009462004E5F +:102510009464003C3045FFFF00A6102300A6182B52 +:102520003087FFFF106000043044FFFF00C5102318 +:1025300000E210233044FFFF0088102B1040000EF3 +:1025400000E810233C028008344401002403000109 +:1025500034420080A44300162402FFFFA482000E30 +:10256000948500EA8F84001C0000302130A5FFFF15 +:102570000A0009013C0760200044102A10400009AD +:102580003C0280083443008094620016304200010F +:10259000104000043C0280009442007E244200145B +:1025A000A462001603E000080000000027BDFFE061 +:1025B0003C028008AFBF001CAFB0001834420100DD +:1025C000944300429442004C104000193068FFFFD1 +:1025D0009383001824020001146200298FBF001C9D +:1025E0003C06800834D00100000810C200501021C1 +:1025F000904200643103000734C70148304200FFB5 +:10260000006210073042000134C9014E34C4012C6D +:1026100034C5013E1040001634C601420E0006D2F9 +:10262000AFA90010960200420A0009463048FFFF99 +:102630003C028008344401009483004494820042A8 +:102640001043000F8FBF001C94820044A4820042FC +:1026500094820050A482004E8C820038AC820030FC +:1026600094820040A482003E9482004AA4820048E2 +:102670008FBF001C8FB000180A00090427BD00207E +:102680008FB0001803E0000827BD002027BDFFA081 +:10269000AFB1004C3C118000AFBF0058AFB3005445 +:1026A000AFB20050AFB000483626018890C2000398 +:1026B0003044007FA3A400108E32018090C200003D +:1026C0003043007F240200031062003BAF92001CE5 +:1026D00028620004104000062402000424020002C4 +:1026E000106200098FBF00580A000B0F8FB300540F +:1026F0001062004D240200051062014E8FBF005889 +:102700000A000B0F8FB30054000411C002421021C5 +:102710002404FF8024420240004410242643004049 +:10272000AE2200243063007F3C02800A0062182140 +:102730009062003CAFA3003C00441025A062003C26 +:102740008FA3003C9062003C304200401040016C7E +:102750008FBF00583C108008A3800018361001007D +:102760008E0200E08C63003427A4003C27A50010F3 +:10277000004310210E0007C3AE0200E093A2001038 +:102780003C038000A20200D58C6202780440FFFE68 +:102790008F82001CAC62024024020002A06202444C +:1027A0003C021000AC6202780E0009390000000003 +:1027B0000A000B0E8FBF00583C05800890C3000133 +:1027C00090A2000B1443014E8FBF005834A4008028 +:1027D0008C8200189082004C90A200083C0260009D +:1027E0008C4254048C8300183C027FFF3442FFFF6C +:1027F000006218243C0208008C4200B4AC8300182C +:102800003C038000244200013C010800AC2200B4DB +:102810008C6201F80440FFFE8F82001CAC6201C094 +:102820000A000AD6240200023C10800890C300016E +:102830009202000B144301328FBF005827A40018E6 +:1028400036050110240600033C0260008C4254044B +:102850000E000E470000000027A40028360501F0F6 +:102860000E000E47240600038FA200283603010045 +:10287000AE0200648FA2002CAE0200688FA200306E +:10288000AE02006C93A40018906300D52402FF8070 +:102890000082102400431025304900FF3084007F5F +:1028A0003122007F0082102A544000013929008023 +:1028B000000411C0244202402403FF800242102180 +:1028C00000431024AE220094264200403042007F94 +:1028D0003C038006004340218FA3001C2402FFFF1D +:1028E000AFA800403C130800927300F71062003359 +:1028F00093A2001995030014304400FF3063FFFFDA +:102900000064182B106000100000000095040014F3 +:102910008D07001C8D0600183084FFFF0044202323 +:102920000004210000E438210000102100E4202BE5 +:1029300000C2302100C43021AD07001CAD060018D4 +:102940000A000A2F93A20019950400148D07001C99 +:102950008D0600183084FFFF008220230004210030 +:10296000000010210080182100C2302300E4202B39 +:1029700000C4302300E33823AD07001CAD06001867 +:1029800093A200198FA30040A462001497A2001A1A +:10299000A46200168FA2001CAC6200108FA2001C63 +:1029A000AC62000C93A20019A462002097A2001A46 +:1029B000A46200228FA2001CAC6200243C048008A8 +:1029C000348300808C6200388FA20020012088218F +:1029D000AC62003C8FA20020AC82000093A20018E1 +:1029E000A062004C93A20018A0820009A0600068B9 +:1029F00093A20018105100512407FF803229007F54 +:102A0000000911C024420240024210213046007FDA +:102A10003C03800000471024AC6200943C02800616 +:102A200000C2302190C2003CAFA60040000020212F +:102A300000471025A0C2003C8FA80040950200026C +:102A4000950300148D07001C3042FFFF3063FFFF29 +:102A50008D060018004310230002110000E2382107 +:102A600000E2102B00C4302100C23021AD07001C51 +:102A7000AD06001895020002A5020014A50000167C +:102A80008D020008AD0200108D020008AD02000C9E +:102A900095020002A5020020A50000228D02000878 +:102AA000AD0200249102003C304200401040001A68 +:102AB000262200013C108008A3A90038A38000183A +:102AC000361001008E0200E08D03003427A4004080 +:102AD00027A50038004310210E0007C3AE0200E016 +:102AE00093A200383C038000A20200D58C620278D9 +:102AF0000440FFFE8F82001CAC62024024020002F0 +:102B0000A06202443C021000AC6202780E00093957 +:102B100000000000262200013043007F14730004EF +:102B2000004020212403FF8002231024004320269C +:102B300093A200180A000A4B309100FF93A40018DA +:102B40008FA3001C2402FFFF1062000A308900FFDF +:102B500024820001248300013042007F14530005C9 +:102B6000306900FF2403FF800083102400431026F7 +:102B7000304900FF3C028008904200080120882173 +:102B8000305000FF123000193222007F000211C0C5 +:102B900002421021244202402403FF8000431824F3 +:102BA0003C048000AC8300943042007F3C038006EC +:102BB000004310218C43000C004020211060000BCA +:102BC000AFA200400E00057E000000002623000199 +:102BD0002405FF803062007F145300020225202468 +:102BE000008518260A000AAF307100FF3C048008F7 +:102BF000348400808C8300183C027FFF3442FFFF46 +:102C000000621824AC8300183C0380008C6201F839 +:102C10000440FFFE00000000AC7201C0240200026C +:102C2000A06201C43C021000AC6201F80A000B0E65 +:102C30008FBF00583C04800890C300019082000BB5 +:102C40001443002F8FBF0058349000809202000878 +:102C500030420040104000200000000092020008B6 +:102C60000002160000021603044100050240202164 +:102C70000E000ECC240500930A000B0E8FBF0058E7 +:102C80009202000924030018304200FF1443000D93 +:102C900002402021240500390E000E64000030217E +:102CA0000E0003328F84001C8F82FF9424030012D5 +:102CB000A04300090E00033D8F84001C0A000B0E88 +:102CC0008FBF0058240500360E000E64000030212E +:102CD0000A000B0E8FBF00580E0003320240202165 +:102CE000920200058F84001C344200200E00033D38 +:102CF000A20200050E0010758F84001C8FBF0058C3 +:102D00008FB300548FB200508FB1004C8FB0004889 +:102D100003E0000827BD00603C0280083445010044 +:102D20003C0280008C42014094A3000E0000302140 +:102D300000402021AF82001C3063FFFF3402FFFF00 +:102D4000106200063C0760202402FFFFA4A2000ED0 +:102D500094A500EA0A00090130A5FFFF03E000087E +:102D60000000000027BDFFC83C0280003C06800830 +:102D7000AFB5002CAFB1001CAFBF0030AFB400281E +:102D8000AFB30024AFB20020AFB00018345101003F +:102D900034C501008C4301008E2200148CA400E491 +:102DA0000000A821AF83001C0044102318400052EB +:102DB000A38000188E22001400005021ACA200E471 +:102DC00090C3000890A200D53073007FA3A200102A +:102DD0008CB200E08CB400E4304200FF1053003BA2 +:102DE00093A200108F83001C2407FF80000211C0F3 +:102DF0000062102124420240246300400047102456 +:102E00003063007F3C0980003C08800A006818217C +:102E1000AD2200248C62003427A4001427A50010E2 +:102E2000024280210290102304400028AFA3001426 +:102E30009062003C00E21024304200FF1440001970 +:102E4000020090219062003C34420040A062003CAD +:102E50008F86001C93A3001024C200403042007FE4 +:102E6000004828213C0208008C4200F42463000141 +:102E7000306400FF14820002A3A30010A3A000107E +:102E800093A20010AFA50014000211C0244202401A +:102E900000C2102100471024AD2200240A000B4577 +:102EA00093A200100E0007C3000000003C0280083F +:102EB00034420100AC5000E093A30010240A00014A +:102EC000A04300D50A000B4593A200102402000184 +:102ED000154200093C0380008C6202780440FFFE2A +:102EE0008F82001CAC62024024020002A0620244F5 +:102EF0003C021000AC6202789222000B2403000214 +:102F0000304200FF144300720000000096220008C7 +:102F1000304300FF24020082146200402402008437 +:102F20003C028000344901008D22000C95230006EC +:102F3000000216023063FFFF3045003F24020027E5 +:102F400010A2000FAF83001428A200281040000830 +:102F5000240200312402002110A2000924020025CD +:102F600010A20007938200190A000BBD00000000A8 +:102F700010A20007938200190A000BBD0000000098 +:102F80000E000777012020210A000C3D0000000000 +:102F90003C0380008C6202780440FFFE8F82001C9C +:102FA000AC62024024020002A06202443C02100013 +:102FB000AC6202780A000C3D000000009523000678 +:102FC000912400058D25000C8D2600108D270018FA +:102FD0008D28001C8D290020244200013C0108009E +:102FE000A42356C63C010800A02456C53C01080095 +:102FF000AC2556CC3C010800AC2656D03C0108005C +:10300000AC2756D83C010800AC2856DC3C0108002F +:10301000AC2956E00A000C3DA38200191462000A94 +:10302000240200813C02800834420100944500EAF9 +:10303000922600058F84001C30A5FFFF30C600FFDC +:103040000A000BFE3C0760211462005C00000000D7 +:103050009222000A304300FF306200201040000737 +:10306000306200403C02800834420100944500EA8E +:103070008F84001C0A000BFC24060040104000074F +:10308000000316003C02800834420100944500EA27 +:103090008F84001C0A000BFC24060041000216036A +:1030A000044100463C02800834420100944500EA95 +:1030B0008F84001C2406004230A5FFFF3C076019E6 +:1030C0000E000901000000000A000C3D0000000095 +:1030D0009222000B24040016304200FF1044000628 +:1030E0003C0680009222000B24030017304200FFB0 +:1030F000144300320000000034C5010090A2000B10 +:10310000304200FF1444000B000080218CA20020FC +:103110008CA400202403FF800043102400021140EF +:103120003084007F004410253C032000004310251C +:10313000ACC2083094A2000800021400000214037C +:10314000044200012410000194A2000830420080D3 +:103150005040001A0200A82194A20008304220002A +:10316000504000160200A8218CA300183C021C2D20 +:10317000344219ED106200110200A8213C0208003F +:103180008C4200D4104000053C0280082403000457 +:1031900034420100A04300FC3C028008344201009C +:1031A000944500EA8F84001C2406000630A5FFFF2A +:1031B0000E0009013C0760210200A8210E00093918 +:1031C000000000009222000A304200081040000473 +:1031D00002A010210E0013790000000002A01021AF +:1031E0008FBF00308FB5002C8FB400288FB3002420 +:1031F0008FB200208FB1001C8FB0001803E00008D0 +:1032000027BD00382402FF80008220243C02900069 +:1032100034420007008220253C028000AC4400209C +:103220003C0380008C6200200440FFFE0000000090 +:1032300003E00008000000003C0380002402FF803F +:10324000008220243462000700822025AC64002024 +:103250008C6200200440FFFE0000000003E0000834 +:103260000000000027BDFFD8AFB3001CAFB10014B1 +:10327000AFB00010AFBF0020AFB200183C1180000B +:103280003C0280088E32002034530100AE2400201E +:10329000966300EA000514003C074000004738250B +:1032A00000A08021000030210E0009013065FFFFE1 +:1032B000240200A1160200022402FFFFA2620009FC +:1032C000AE3200208FBF00208FB3001C8FB20018D9 +:1032D0008FB100148FB0001003E0000827BD002854 +:1032E0003C0280082403000527BDFFE834420100AA +:1032F000A04300FCAFBF00103C0280008C420100E4 +:10330000240500A1004020210E000C67AF82001CA4 +:103310003C0380008C6202780440FFFE8F82001C18 +:103320008FBF001027BD0018AC62024024020002CB +:10333000A06202443C021000AC62027803E0000884 +:103340000000000027BDFFE83C068000AFBF001072 +:1033500034C7010094E20008304400FF3883008243 +:10336000388200842C6300012C4200010062182581 +:103370001060002D24020083938200195040003B0E +:103380008FBF00103C020800904256CC8CC4010054 +:103390003C06080094C656C63045003F38A30032AC +:1033A00038A2003F2C6300012C4200010062182566 +:1033B000AF84001CAF860014A380001914600007BE +:1033C00000E020212402002014A2001200000000CE +:1033D0003402FFFF14C2000F00000000240200208E +:1033E00014A2000500E028218CE300142402FFFF52 +:1033F0005062000B8FBF00103C040800248456C0AC +:10340000000030210E000706240700010A000CD638 +:103410008FBF00100E000777000000008FBF001064 +:103420000A00093927BD001814820004240200850F +:103430008CC501040A000CE1000020211482000662 +:103440002482FF808CC50104240440008FBF00103B +:103450000A00016727BD0018304200FF2C4200021D +:1034600010400004240200228FBF00100A000B2726 +:1034700027BD0018148200048F8200248FBF001023 +:103480000A000C8627BD00188C42000C1040001E5C +:1034900000E0282190E300092402001814620003D0 +:1034A000240200160A000CFC240300081462000722 +:1034B00024020017240300123C02800834420080DA +:1034C000A04300090A000D0994A7000854620007F0 +:1034D00094A700088F82FF942404FFFE9043000508 +:1034E00000641824A043000594A7000890A6001BC0 +:1034F0008CA4000094A500068FBF001000073C00BC +:103500000A0008DC27BD00188FBF001003E0000888 +:1035100027BD00188F8500243C04800094A2002A57 +:103520008CA30034000230C02402FFF000C210243B +:1035300000621821AC83003C8CA200303C03800068 +:10354000AC8200383C02005034420010AC620030C3 +:103550000000000000000000000000008C6200007D +:10356000304200201040FFFD30C20008104000062D +:103570003C0280008C620408ACA200208C62040C27 +:103580000A000D34ACA200248C430400ACA300203C +:103590008C420404ACA200243C0300203C028000C6 +:1035A000AC4300303C0480008C8200300043102487 +:1035B0001440FFFD8F8600243C020040AC820030A6 +:1035C00094C3002A94C2002894C4002C94C5002EF1 +:1035D00024630001004410213064FFFFA4C20028CE +:1035E00014850002A4C3002AA4C0002A03E0000836 +:1035F000000000008F84002427BDFFE83C05800404 +:1036000024840010AFBF00100E000E472406000AED +:103610008F840024948200129483002E3042000F85 +:10362000244200030043180424027FFF0043102BB0 +:1036300010400002AC8300000000000D0E000D13CE +:10364000000000008F8300248FBF001027BD0018EA +:10365000946200149463001A3042000F00021500B7 +:10366000006218253C02800003E00008AC4300A083 +:103670008F8300243C028004944400069462001A64 +:103680008C650000A4640016004410233042FFFF44 +:103690000045102B03E00008384200018F8400240D +:1036A0003C0780049486001A8C85000094E2000692 +:1036B000A482001694E3000600C310233042FFFFEB +:1036C0000045102B384200011440FFF8A483001677 +:1036D00003E00008000000008F8400243C02800406 +:1036E000944200069483001A8C850000A482001680 +:1036F000006210233042FFFF0045102B38420001CA +:103700005040000D8F850024006030213C0780046C +:1037100094E20006A482001694E3000600C310237E +:103720003042FFFF0045102B384200011440FFF8E3 +:10373000A48300168F8500243C03800034620400BB +:103740008CA40020AF820020AC6400388CA200243E +:10375000AC62003C3C020005AC62003003E00008B3 +:10376000ACA000048F8400243C0300068C8200047B +:1037700000021140004310253C038000AC62003081 +:103780000000000000000000000000008C6200004B +:10379000304200101040FFFD34620400AC80000491 +:1037A00003E00008AF8200208F86002427BDFFE0E1 +:1037B000AFB10014AFB00010AFBF00188CC300044D +:1037C0008CC500248F820020309000FF94C4001A22 +:1037D00024630001244200202484000124A7002047 +:1037E000ACC30004AF820020A4C4001AACC70024FC +:1037F00004A100060000882104E2000594C2001A1A +:103800008CC2002024420001ACC2002094C2001AE5 +:1038100094C300282E040001004310262C4200010E +:10382000004410245040000594C2001A24020001F4 +:10383000ACC2000894C2001A94C300280010202BC8 +:10384000004310262C4200010044102514400007BC +:10385000000000008CC20008144000042402001084 +:103860008CC300041462000F8F8500240E000DA786 +:10387000241100018F820024944300289442001AEE +:1038800014430003000000000E000D1300000000B0 +:10389000160000048F8500240E000D840000000037 +:1038A0008F85002494A2001E94A4001C24420001D1 +:1038B0003043FFFF14640002A4A2001EA4A0001E57 +:1038C0001200000A3C02800494A2001494A3001A7F +:1038D0003042000F00021500006218253C028000F3 +:1038E000AC4300A00A000E1EACA0000894420006E3 +:1038F00094A3001A8CA40000A4A200160062102356 +:103900003042FFFF0044102B384200011040000DF0 +:1039100002201021006030213C07800494E2000660 +:10392000A4A2001694E3000600C310233042FFFF58 +:103930000044102B384200011440FFF8A4A30016E5 +:10394000022010218FBF00188FB100148FB000101B +:1039500003E0000827BD002003E00008000000008D +:103960008F82002C3C03000600021140004310250A +:103970003C038000AC62003000000000000000004A +:10398000000000008C620000304200101040FFFD7B +:1039900034620400AF82002803E00008AF80002CEE +:1039A00003E000080000102103E000080000000010 +:1039B0003084FFFF30A5FFFF0000182110800007B2 +:1039C000000000003082000110400002000420428C +:1039D000006518210A000E3D0005284003E000089C +:1039E0000060102110C0000624C6FFFF8CA200005A +:1039F00024A50004AC8200000A000E4724840004C1 +:103A000003E000080000000010A0000824A3FFFF4E +:103A1000AC86000000000000000000002402FFFF50 +:103A20002463FFFF1462FFFA2484000403E000080B +:103A3000000000003C0280083442008024030001A2 +:103A4000AC43000CA4430010A4430012A443001490 +:103A500003E00008A44300168F82002427BDFFD88E +:103A6000AFB3001CAFB20018AFB10014AFB000107C +:103A7000AFBF00208C47000C248200802409FF8007 +:103A80003C08800E3043007F008080213C0A80008B +:103A9000004920240068182130B100FF30D200FF17 +:103AA00010E000290000982126020100AD44002CFE +:103AB000004928243042007F004820219062000005 +:103AC00024030050304200FF1443000400000000B3 +:103AD000AD45002C948200EA3053FFFF0E000D84A8 +:103AE000000000008F8200248F83002000112C0032 +:103AF0009442001E001224003484000100A22825F4 +:103B00003C02400000A22825AC7000008FBF0020BE +:103B1000AC6000048FB20018AC7300088FB10014C1 +:103B2000AC60000C8FB3001CAC6400108FB00010B0 +:103B3000AC60001424040001AC60001827BD00280C +:103B40000A000DB8AC65001C8FBF00208FB3001CAD +:103B50008FB200188FB100148FB0001003E000087E +:103B600027BD00283C06800034C201009043000FAE +:103B7000240200101062000E2865001110A000073A +:103B800024020012240200082405003A10620006F4 +:103B90000000302103E0000800000000240500358B +:103BA0001462FFFC000030210A000E6400000000D7 +:103BB0008CC200748F83FF9424420FA003E000089E +:103BC000AC62000C27BDFFE8AFBF00100E0003423F +:103BD000240500013C0480088FBF0010240200016E +:103BE00034830080A462001227BD00182402000163 +:103BF00003E00008A080001A27BDFFE0AFB2001864 +:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 +:103C10000E000332008088213C028008345000806E +:103C20009202000924030004304200FF1443000CF8 +:103C30003C028008124000082402000A0E000E5BBD +:103C400000000000920200052403FFFE0043102440 +:103C5000A202000524020012A20200093C02800810 +:103C600034420080022020210E00033DA0400027A6 +:103C700016400003022020210E000EBF00000000AD +:103C800002202021324600FF8FBF001C8FB2001897 +:103C90008FB100148FB00010240500380A000E64A4 +:103CA00027BD002027BDFFE0AFBF001CAFB200184A +:103CB000AFB10014AFB000100E00033200808021BD +:103CC0000E000E5B000000003C02800834450080BE +:103CD00090A2000924120018305100FF1232000394 +:103CE0000200202124020012A0A2000990A20005D7 +:103CF0002403FFFE004310240E00033DA0A2000594 +:103D00000200202124050020163200070000302187 +:103D10008FBF001C8FB200188FB100148FB000103D +:103D20000A00034227BD00208FBF001C8FB200187D +:103D30008FB100148FB00010240500390A000E6402 +:103D400027BD002027BDFFE83C028000AFB0001077 +:103D5000AFBF0014344201009442000C2405003629 +:103D60000080802114400012304600FF0E00033214 +:103D7000000000003C02800834420080240300124E +:103D8000A043000990430005346300100E000E5B51 +:103D9000A04300050E00033D020020210200202167 +:103DA0000E000342240500200A000F3C0000000022 +:103DB0000E000E64000000000E00033202002021FD +:103DC0003C0280089043001B2405FF9F0200202135 +:103DD000006518248FBF00148FB00010A043001B93 +:103DE0000A00033D27BD001827BDFFE0AFBF001844 +:103DF000AFB10014AFB0001030B100FF0E000332BD +:103E0000008080213C02800824030012344200809C +:103E10000E000E5BA04300090E00033D02002021AE +:103E200002002021022030218FBF00188FB1001422 +:103E30008FB00010240500350A000E6427BD002055 +:103E40003C0480089083000E9082000A1443000B0B +:103E5000000028218F82FF942403005024050001D4 +:103E600090420000304200FF1443000400000000B4 +:103E70009082000E24420001A082000E03E00008A0 +:103E800000A010213C0380008C6201F80440FFFE7A +:103E900024020002AC6401C0A06201C43C02100014 +:103EA00003E00008AC6201F827BDFFE0AFB20018E4 +:103EB0003C128008AFB10014AFBF001CAFB00010BF +:103EC00036510080922200092403000A304200FF8C +:103ED0001443003E000000008E4300048E22003890 +:103EE000506200808FBF001C92220000240300500B +:103EF000304200FF144300253C0280008C42014008 +:103F00008E4300043642010002202821AC43001CED +:103F10009622005C8E2300383042FFFF00021040E2 +:103F200000621821AE23001C8E4300048E2400384A +:103F30009622005C006418233042FFFF0003184300 +:103F4000000210400043102A10400006000000004C +:103F50008E4200048E230038004310230A000FAA6B +:103F6000000220439622005C3042FFFF0002204006 +:103F70003C0280083443010034420080ACA4002C91 +:103F8000A040002424020001A062000C0E000F5E7D +:103F900000000000104000538FBF001C3C02800056 +:103FA0008C4401403C0380008C6201F80440FFFE19 +:103FB00024020002AC6401C0A06201C43C021000F3 +:103FC000AC6201F80A0010078FBF001C92220009A2 +:103FD00024030010304200FF144300043C02800020 +:103FE0008C4401400A000FEE0000282192220009B3 +:103FF00024030016304200FF14430006240200147C +:10400000A22200093C0280008C4401400A001001F9 +:104010008FBF001C8E2200388E23003C00431023EB +:10402000044100308FBF001C92220027244200016F +:10403000A2220027922200272C42000414400016DE +:104040003C1080009222000924030004304200FF4B +:10405000144300093C0280008C4401408FBF001CC7 +:104060008FB200188FB100148FB000102405009398 +:104070000A000ECC27BD00208C440140240500938B +:104080008FBF001C8FB200188FB100148FB00010CA +:104090000A000F4827BD00208E0401400E000332A5 +:1040A000000000008E4200042442FFFFAE420004E4 +:1040B0008E22003C2442FFFFAE22003C0E00033D56 +:1040C0008E0401408E0401408FBF001C8FB2001887 +:1040D0008FB100148FB00010240500040A000342C1 +:1040E00027BD00208FB200188FB100148FB00010D0 +:1040F00003E0000827BD00203C0680008CC2018838 +:104100003C038008346500809063000E00021402B6 +:10411000304400FF306300FF1464000E3C0280084E +:1041200090A20026304200FF104400098F82FF94C5 +:10413000A0A400262403005090420000304200FF5B +:1041400014430006000000000A0005A18CC4018091 +:104150003C02800834420080A044002603E00008AE +:104160000000000027BDFFE030E700FFAFB20018FD +:10417000AFBF001CAFB10014AFB0001000809021A1 +:1041800014E0000630C600FF000000000000000D33 +:10419000000000000A001060240001163C038008A3 +:1041A0009062000E304200FF14460023346200800B +:1041B00090420026304200FF1446001F000000001D +:1041C0009062000F304200FF1446001B0000000008 +:1041D0009062000A304200FF144600038F90FF9463 +:1041E0000000000D8F90FF948F82FF983C1180009B +:1041F000AE05003CAC450000A066000A0E0003328C +:104200008E240100A20000240E00033D8E24010034 +:104210003C0380008C6201F80440FFFE240200028F +:10422000AC7201C0A06201C43C021000AC6201F893 +:104230000A0010618FBF001C000000000000000D8C +:10424000000000002400013F8FBF001C8FB2001847 +:104250008FB100148FB0001003E0000827BD0020CC +:104260008F83FF943C0280008C44010034420100A3 +:104270008C65003C9046001B0A00102724070001B3 +:104280003C0280089043000E9042000A0043102632 +:10429000304200FF03E000080002102B27BDFFE0C2 +:1042A0003C028008AFB10014AFB00010AFBF0018DF +:1042B0003450008092020005240300303042003068 +:1042C00014430085008088218F8200248C42000CDA +:1042D000104000828FBF00180E000D840000000007 +:1042E0008F860020ACD100009202000892030009E2 +:1042F000304200FF00021200306300FF004310252F +:10430000ACC200049202004D000216000002160327 +:1043100004410005000000003C0308008C630048D5 +:104320000A00109F3C1080089202000830420040B2 +:10433000144000030000182192020027304300FFC0 +:104340003C108008361100809222004D00031E00B0 +:10435000304200FF0002140000621825ACC30008C0 +:104360008E2400308F820024ACC4000C8E250034D3 +:104370009443001E3C02C00BACC50010006218251F +:104380008E22003800002021ACC200148E22003C96 +:10439000ACC200180E000DB8ACC3001C8E020004A5 +:1043A0008F8400203C058000AC8200008E2200201B +:1043B000AC8200048E22001CAC8200088E220058C1 +:1043C0008CA3007400431021AC82000C8E22002CC0 +:1043D000AC8200108E2200408E23004400021400A4 +:1043E00000431025AC8200149222004D240300806B +:1043F000304200FF1443000400000000AC800018AD +:104400000A0010E38F8200248E23000C2402000196 +:104410001062000E2402FFFF92220008304200408A +:104420001440000A2402FFFF8E23000C8CA20074AB +:10443000006218233C0208000062102414400002AD +:10444000000028210060282100051043AC820018DC +:104450008F820024000020219443001E3C02C00CE7 +:10446000006218258F8200200E000DB8AC43001C9E +:104470003C038008346201008C4200008F850020DC +:10448000346300808FBF0018ACA20000ACA0000411 +:104490008C6400488F8200248FB10014ACA4000803 +:1044A000ACA0000CACA00010906300059446001E68 +:1044B0003C02400D00031E0000C23025ACA30014D6 +:1044C0008FB00010ACA0001824040001ACA6001CA2 +:1044D0000A000DB827BD00208FBF00188FB100144F +:1044E0008FB0001003E0000827BD00203C028000D0 +:1044F0009443007C3C02800834460100308400FF75 +:104500003065FFFF2402000524A34650A0C4000C20 +:104510005482000C3065FFFF90C2000D2C42000752 +:104520001040000724A30A0090C3000D24020014C9 +:104530000062100400A210210A00111F3045FFFF85 +:104540003065FFFF3C0280083442008003E0000831 +:10455000A44500143C03800834680080AD05003891 +:10456000346701008CE2001C308400FF00A210239D +:104570001840000330C600FF24A2FFFCACE2001C80 +:1045800030820001504000083C0380088D02003C4E +:1045900000A2102304410012240400058C620004D0 +:1045A00010A2000F3C0380088C62000414A2001EBD +:1045B000000000003C0208008C4200D8304200207D +:1045C000104000093C0280083462008090630008BB +:1045D0009042004C144300043C0280082404000470 +:1045E0000A00110900000000344300803442010039 +:1045F000A040000C24020001A462001410C0000AB4 +:104600003C0280008C4401003C0380008C6201F875 +:104610000440FFFE24020002AC6401C0A06201C499 +:104620003C021000AC6201F803E00008000000004A +:1046300027BDFFE800A61823AFBF00101860008058 +:10464000308800FF3C02800834470080A0E000244E +:1046500034440100A0E000278C82001C00A210233B +:1046600004400056000000008CE2003C94E3005C33 +:104670008CE4002C004530233063FFFF00C3182179 +:104680000083202B1080000400E018218CE2002C15 +:104690000A00117800A2102194E2005C3042FFFF72 +:1046A00000C2102100A21021AC62001C3C02800854 +:1046B000344400809482005C8C83001C3042FFFFF5 +:1046C0000002104000A210210043102B10400004F3 +:1046D000000000008C82001C0A00118B3C06800840 +:1046E0009482005C3042FFFF0002104000A21021C3 +:1046F0003C06800834C3010034C70080AC82001C33 +:10470000A060000CACE500388C62001C00A21023F5 +:104710001840000224A2FFFCAC62001C3102000120 +:10472000104000083C0380088CE2003C00A21023EB +:1047300004410012240400058CC2000410A20010E1 +:104740008FBF00108C62000414A2004F8FBF0010B6 +:104750003C0208008C4200D8304200201040000A81 +:104760003C02800834620080906300089042004C54 +:10477000144300053C028008240400048FBF00108D +:104780000A00110927BD001834430080344201009B +:10479000A040000C24020001A46200143C0280002E +:1047A0008C4401003C0380008C6201F80440FFFE51 +:1047B000240200020A0011D8000000008CE2001C54 +:1047C000004610230043102B54400001ACE5001CB0 +:1047D00094E2005C3042FFFF0062102B144000079F +:1047E0002402000294E2005C8CE3001C3042FFFFD4 +:1047F00000621821ACE3001C24020002ACE5003882 +:104800000E000F5EA082000C1040001F8FBF001032 +:104810003C0280008C4401003C0380008C6201F863 +:104820000440FFFE24020002AC6401C0A06201C487 +:104830003C021000AC6201F80A0011F08FBF0010BA +:1048400031020010104000108FBF00103C028008A1 +:10485000344500808CA3001C94A2005C00661823E1 +:104860003042FFFF006218213C023FFF3444FFFF4B +:104870000083102B544000010080182100C3102138 +:10488000ACA2001C8FBF001003E0000827BD001879 +:1048900027BDFFE800C0402100A63023AFBF0010B5 +:1048A00018C00026308A00FF3C028008344900808E +:1048B0008D24001C8D23002C008820230064182BDD +:1048C0001060000F344701008CE2002000461021E8 +:1048D000ACE200208CE200200044102B1440000BBE +:1048E0003C023FFF8CE2002000441023ACE2002099 +:1048F0009522005C3042FFFF0A0012100082202146 +:10490000ACE00020008620213C023FFF3443FFFF43 +:104910000064102B54400001006020213C028008FC +:104920003442008000851821AC43001CA0400024C4 +:10493000A04000270A0012623C03800831420010A8 +:10494000104000433C0380083C06800834C40080CB +:104950008C82003C004810235840003E34660080A2 +:104960009082002424420001A0820024908200242E +:104970003C0308008C630024304200FF0043102BEE +:10498000144000688FBF001034C201008C42001C2C +:1049900000A2102318400063000000008CC3000434 +:1049A0009482005C006818233042FFFF0003184324 +:1049B000000210400043102A1040000500000000D3 +:1049C0008CC20004004810230A0012450002104364 +:1049D0009482005C3042FFFF000210403C068008D9 +:1049E000AC82002C34C5008094A2005C8CA4002C06 +:1049F00094A3005C3042FFFF00021040008220219F +:104A00003063FFFF0083202101041021ACA2001CB1 +:104A10008CC2000434C60100ACC2001C2402000297 +:104A20000E000F5EA0C2000C1040003E8FBF0010B1 +:104A30003C0280008C4401003C0380008C6201F841 +:104A40000440FFFE240200020A001292000000004F +:104A500034660080ACC50038346401008C82001CD0 +:104A600000A210231840000224A2FFFCAC82001C0C +:104A7000314200015040000A3C0380088CC2003CD7 +:104A800000A2102304430014240400058C620004D7 +:104A900014A200033C0380080A00128424040005C9 +:104AA0008C62000414A2001F8FBF00103C0208009B +:104AB0008C4200D8304200201040000A3C0280089E +:104AC00034620080906300089042004C144300055B +:104AD0003C028008240400048FBF00100A00110962 +:104AE00027BD00183443008034420100A040000C70 +:104AF00024020001A46200143C0280008C440100E6 +:104B00003C0380008C6201F80440FFFE2402000296 +:104B1000AC6401C0A06201C43C021000AC6201F8A8 +:104B20008FBF001003E0000827BD001827BDFFE875 +:104B30003C0A8008AFBF0010354900808D22003C40 +:104B400000C04021308400FF004610231840009D23 +:104B500030E700FF354701002402000100A63023A2 +:104B6000A0E0000CA0E0000DA522001418C0002455 +:104B7000308200108D23001C8D22002C0068182329 +:104B80000043102B1040000F000000008CE20020BA +:104B900000461021ACE200208CE200200043102BE4 +:104BA0001440000B3C023FFF8CE200200043102326 +:104BB000ACE200209522005C3042FFFF0A0012C1E7 +:104BC00000621821ACE00020006618213C023FFF83 +:104BD0003446FFFF00C3102B5440000100C01821D1 +:104BE0003C0280083442008000651821AC43001C60 +:104BF000A0400024A04000270A00130F3C038008B7 +:104C0000104000403C0380088D22003C00481023E7 +:104C10005840003D34670080912200242442000166 +:104C2000A1220024912200243C0308008C6300246C +:104C3000304200FF0043102B1440009A8FBF001039 +:104C40008CE2001C00A21023184000960000000017 +:104C50008D4300049522005C006818233042FFFF5A +:104C600000031843000210400043102A10400005C2 +:104C7000012020218D420004004810230A0012F276 +:104C8000000210439522005C3042FFFF00021040FA +:104C90003C068008AC82002C34C5008094A2005CE5 +:104CA0008CA4002C94A3005C3042FFFF0002104053 +:104CB000008220213063FFFF0083182101031021AF +:104CC000ACA2001C8CC2000434C60100ACC2001CA3 +:104CD000240200020E000F5EA0C2000C1040007102 +:104CE0008FBF00103C0280008C4401003C03800018 +:104CF0008C6201F80440FFFE240200020A0013390E +:104D00000000000034670080ACE500383466010024 +:104D10008CC2001C00A210231840000224A2FFFC39 +:104D2000ACC2001C30820001504000083C038008E7 +:104D30008CE2003C00A2102304430051240400052F +:104D40008C62000410A2003E3C0380088C620004C8 +:104D500054A200548FBF00103C0208008C4200D8BF +:104D600030420020104000063C028008346200807F +:104D7000906300089042004C104300403C028008C1 +:104D80003443008034420100A040000C24020001A2 +:104D9000A46200143C0280008C4401003C038000AB +:104DA0008C6201F80440FFFE24020002AC6401C0E2 +:104DB000A06201C43C021000AC6201F80A00137743 +:104DC0008FBF001024020005A120002714E2000A72 +:104DD0003C038008354301009062000D2C42000620 +:104DE000504000053C0380089062000D2442000101 +:104DF000A062000D3C03800834670080ACE50038F9 +:104E0000346601008CC2001C00A21023184000026E +:104E100024A2FFFCACC2001C308200015040000AFA +:104E20003C0380088CE2003C00A2102304410014E3 +:104E3000240400058C62000414A200033C038008D3 +:104E40000A00136E240400058C62000414A20015ED +:104E50008FBF00103C0208008C4200D83042002076 +:104E60001040000A3C028008346200809063000811 +:104E70009042004C144300053C02800824040004C6 +:104E80008FBF00100A00110927BD001834430080AD +:104E900034420100A040000C24020001A46200146E +:104EA0008FBF001003E0000827BD00183C0B8008EE +:104EB00027BDFFE83C028000AFBF00103442010074 +:104EC000356A00809044000A356901008C45001461 +:104ED0008D4800389123000C308400FF0105102319 +:104EE0001C4000B3306700FF2CE20006504000B1C8 +:104EF0008FBF00102402000100E2300430C2000322 +:104F00005440000800A8302330C2000C144000A117 +:104F100030C20030144000A38FBF00100A00143BC1 +:104F20000000000018C00024308200108D43001CD7 +:104F30008D42002C006818230043102B1040000FF6 +:104F4000000000008D22002000461021AD2200202C +:104F50008D2200200043102B1440000B3C023FFF29 +:104F60008D22002000431023AD2200209542005CDA +:104F70003042FFFF0A0013AF00621821AD2000206D +:104F8000006618213C023FFF3446FFFF00C3102B90 +:104F90005440000100C018213C02800834420080C7 +:104FA00000651821AC43001CA0400024A04000274D +:104FB0000A0013FD3C038008104000403C038008B9 +:104FC0008D42003C004810231840003D34670080AB +:104FD0009142002424420001A14200249142002475 +:104FE0003C0308008C630024304200FF0043102B78 +:104FF000144000708FBF00108D22001C00A21023EF +:105000001840006C000000008D6300049542005CB5 +:10501000006818233042FFFF0003184300021040CD +:105020000043102A10400005014020218D62000439 +:10503000004810230A0013E0000210439542005C70 +:105040003042FFFF000210403C068008AC82002C7A +:1050500034C5008094A2005C8CA4002C94A3005C56 +:105060003042FFFF00021040008220213063FFFF2A +:105070000083182101031021ACA2001C8CC2000483 +:1050800034C60100ACC2001C240200020E000F5EF8 +:10509000A0C2000C104000478FBF00103C028000EF +:1050A0008C4401003C0380008C6201F80440FFFE48 +:1050B000240200020A00142D000000003467008062 +:1050C000ACE50038346601008CC2001C00A210233D +:1050D0001840000224A2FFFCACC2001C3082000178 +:1050E0005040000A3C0380088CE2003C00A21023E0 +:1050F00004430014240400058C62000414A200037D +:105100003C0380080A00141F240400058C6200047C +:1051100014A200288FBF00103C0208008C4200D867 +:10512000304200201040000A3C02800834620080B7 +:10513000906300089042004C144300053C02800834 +:10514000240400048FBF00100A00110927BD0018B5 +:105150003443008034420100A040000C24020001CE +:10516000A46200143C0280008C4401003C038000D7 +:105170008C6201F80440FFFE24020002AC6401C00E +:10518000A06201C43C021000AC6201F80A00143BAA +:105190008FBF00108FBF0010010030210A00115A8C +:1051A00027BD0018010030210A00129927BD001800 +:1051B0008FBF001003E0000827BD00183C038008E3 +:1051C0003464010024020003A082000C8C620004FD +:1051D00003E00008AC82001C3C05800834A300807A +:1051E0009062002734A501002406004324420001F8 +:1051F000A0620027906300273C0208008C42004810 +:10520000306300FF146200043C07602194A500EAAB +:105210000A00090130A5FFFF03E0000800000000BC +:1052200027BDFFE8AFBF00103C0280000E00144411 +:105230008C4401803C02800834430100A060000CD3 +:105240008C4200048FBF001027BD001803E0000847 +:10525000AC62001C27BDFFE03C028008AFBF001815 +:10526000AFB10014AFB000103445008034460100E7 +:105270003C0880008D09014090C3000C8CA4003CC8 +:105280008CA200381482003B306700FF9502007C3E +:1052900090A30027146000093045FFFF2402000599 +:1052A00054E200083C04800890C2000D2442000132 +:1052B000A0C2000D0A00147F3C048008A0C0000DAD +:1052C0003C048008348201009042000C2403000555 +:1052D000304200FF1443000A24A205DC348300801E +:1052E000906200272C4200075040000524A20A00CB +:1052F00090630027240200140062100400A2102111 +:105300003C108008361000803045FFFF012020212E +:105310000E001444A60500149602005C8E030038AB +:105320003C1180003042FFFF000210400062182153 +:10533000AE03001C0E0003328E24014092020025B1 +:1053400034420040A20200250E00033D8E2401409D +:105350008E2401403C0380008C6201F80440FFFE73 +:1053600024020002AC6401C0A06201C43C0210002F +:10537000AC6201F88FBF00188FB100148FB000101D +:1053800003E0000827BD00203C0360103C02080039 +:1053900024420174AC62502C8C6250003C048000AA +:1053A00034420080AC6250003C0208002442547C2D +:1053B0003C010800AC2256003C020800244254384C +:1053C0003C010800AC2256043C020002AC840008F8 +:1053D000AC82000C03E000082402000100A0302190 +:1053E0003C1C0800279C56083C0200023C050400B7 +:1053F00000852826008220260004102B2CA5000101 +:105400002C840001000210803C0308002463560035 +:105410000085202500431821108000030000102182 +:10542000AC6600002402000103E000080000000058 +:105430003C1C0800279C56083C0200023C05040066 +:1054400000852826008220260004102B2CA50001B0 +:105450002C840001000210803C03080024635600E5 +:105460000085202500431821108000050000102130 +:105470003C02080024425438AC62000024020001BF +:1054800003E00008000000003C0200023C030400AE +:1054900000821026008318262C4200012C63000194 +:1054A000004310251040000B000028213C1C080080 +:1054B000279C56083C0380008C62000824050001EC +:1054C00000431025AC6200088C62000C00441025DB +:1054D000AC62000C03E0000800A010213C1C080096 +:1054E000279C56083C0580008CA3000C0004202754 +:1054F000240200010064182403E00008ACA3000C9F +:105500003C020002148200063C0560008CA208D018 +:105510002403FFFE0043102403E00008ACA208D0DF +:105520003C02040014820005000000008CA208D098 +:105530002403FFFD00431024ACA208D003E00008C0 +:10554000000000003C02601A344200108C430080CE +:1055500027BDFFF88C440084AFA3000093A3000094 +:10556000240200041462001AAFA4000493A20001F4 +:105570001040000797A300023062FFFC3C0380004C +:10558000004310218C4200000A001536AFA200042F +:105590003062FFFC3C03800000431021AC4400005B +:1055A000A3A000003C0560008CA208D02403FFFEED +:1055B0003C04601A00431024ACA208D08FA300045E +:1055C0008FA2000034840010AC830084AC82008081 +:1055D00003E0000827BD000827BDFFE8AFBF0010AB +:1055E0003C1C0800279C56083C0280008C43000CA1 +:1055F0008C420004004318243C0200021060001496 +:10560000006228243C0204003C04000210A00005B3 +:10561000006210243C0208008C4256000A00155B10 +:1056200000000000104000073C0404003C02080099 +:105630008C4256040040F809000000000A00156082 +:10564000000000000000000D3C1C0800279C5608CC +:0C5650008FBF001003E0000827BD001809 +:04565C008008024080 +:1056600080080100800800808008000000000C8095 +:105670000000320008000E9808000EF408000F88A1 +:1056800008001028080010748008010080080080BD +:04569000800800008E +:0C5694000A0000280000000000000000D8 +:1056A0000000000D6370362E302E313700000000F0 +:1056B00006001104000000000000000000000000CF +:1056C000000000000000000038003C000000000066 +:1056D00000000000000000000000000000000020AA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:10570000000000000000000021003800000000013F +:105710000000002B000000000000000400030D400A +:105720000000000000000000000000000000000079 +:105730000000000000000000100000030000000056 +:105740000000000D0000000D3C020800244259AC8E +:105750003C03080024635BF4AC4000000043202BB2 +:105760001480FFFD244200043C1D080037BD9FFC4F +:1057700003A0F0213C100800261000A03C1C0800EB +:10578000279C59AC0E0002F6000000000000000D3E +:1057900027BDFFB4AFA10000AFA20004AFA3000873 +:1057A000AFA4000CAFA50010AFA60014AFA700185F +:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF +:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F +:1057D000AFB8003CAFB90040AFBC0044AFBF004819 +:1057E0000E000820000000008FBF00488FBC00445E +:1057F0008FB900408FB8003C8FAF00388FAE0034B7 +:105800008FAD00308FAC002C8FAB00288FAA002406 +:105810008FA900208FA8001C8FA700188FA6001446 +:105820008FA500108FA4000C8FA300088FA2000486 +:105830008FA1000027BD004C3C1B60188F7A5030B0 +:10584000377B502803400008AF7A000000A01821E1 +:1058500000801021008028213C0460003C0760008B +:105860002406000810600006348420788C42000072 +:10587000ACE220088C63000003E00008ACE3200CDD +:105880000A000F8100000000240300403C02600079 +:1058900003E00008AC4320003C0760008F86000452 +:1058A0008CE520740086102100A2182B14600007DC +:1058B000000028218F8AFDA024050001A1440013C7 +:1058C0008F89000401244021AF88000403E0000810 +:1058D00000A010218F84FDA08F8500049086001306 +:1058E00030C300FF00A31023AF82000403E00008D0 +:1058F000A08000138F84FDA027BDFFE8AFB000108B +:10590000AFBF001490890011908700112402002875 +:10591000312800FF3906002830E300FF2485002CE1 +:105920002CD00001106200162484001C0E00006EB2 +:10593000000000008F8FFDA03C05600024020204DF +:1059400095EE003E95ED003C000E5C0031ACFFFF93 +:10595000016C5025ACAA2010520000012402000462 +:10596000ACA22000000000000000000000000000C9 +:105970008FBF00148FB0001003E0000827BD00188F +:105980000A0000A6000028218F85FDA027BDFFD8B2 +:10599000AFBF0020AFB3001CAFB20018AFB100140E +:1059A000AFB000100080982190A4001124B0001C1A +:1059B00024B1002C308300FF386200280E000090D4 +:1059C0002C5200010E00009800000000020020216F +:1059D0001240000202202821000028210E00006E43 +:1059E000000000008F8DFDA03C0880003C05600099 +:1059F00095AC003E95AB003C02683025000C4C0095 +:105A0000316AFFFF012A3825ACA7201024020202C8 +:105A1000ACA6201452400001240200028FBF0020D7 +:105A20008FB3001C8FB200188FB100148FB000101C +:105A300027BD002803E00008ACA2200027BDFFE03E +:105A4000AFB20018AFB10014AFB00010AFBF001C70 +:105A50003C1160008E2320748F82000430D0FFFF41 +:105A600030F2FFFF1062000C2406008F0E00006E63 +:105A7000000000003C06801F0010440034C5FF00F9 +:105A80000112382524040002AE2720100000302126 +:105A9000AE252014AE2420008FBF001C8FB200184A +:105AA0008FB100148FB0001000C0102103E0000877 +:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 +:105AC000AFBF0018AFB100140E00006E30F1FFFF41 +:105AD00000102400009180253C036000AC70201071 +:105AE0008FBF00188FB100148FB000102402000483 +:105AF000AC62200027BD002003E000080000102158 +:105B000027BDFFE03C046018AFBF0018AFB1001420 +:105B1000AFB000108C8850002403FF7F34028071E6 +:105B20000103382434E5380C241F00313C1980006F +:105B3000AC8550003C11800AAC8253BCAF3F0008DA +:105B40000E00054CAF9100400E00050A3C116000AC +:105B50000E00007D000000008E3008083C0F570941 +:105B60002418FFF00218602435EEE00035EDF00057 +:105B7000018E5026018D58262D4600012D69000109 +:105B8000AF86004C0E000D09AF8900503C06601630 +:105B90008CC700003C0860148D0500A03C03FFFF8B +:105BA00000E320243C02535300052FC2108200550D +:105BB00034D07C00960201F2A780006C10400003F4 +:105BC000A780007C384B1E1EA78B006C960201F844 +:105BD000104000048F8D0050384C1E1EA78C007C96 +:105BE0008F8D005011A000058F83004C240E0020E3 +:105BF000A78E007CA78E006C8F83004C1060000580 +:105C00009785007C240F0020A78F007CA78F006C55 +:105C10009785007C2CB8008153000001240500808A +:105C20009784006C2C91040152200001240404008C +:105C30001060000B3C0260008FBF00188FB1001491 +:105C40008FB0001027BD0020A784006CA785007CC2 +:105C5000A380007EA780007403E00008A780009264 +:105C60008C4704382419103C30FFFFFF13F9000360 +:105C700030A8FFFF1100004624030050A380007EDF +:105C80009386007E50C00024A785007CA780007CFE +:105C90009798007CA780006CA7800074A780009272 +:105CA0003C010800AC3800800E00078700000000AF +:105CB0003C0F60008DED0808240EFFF03C0B600ED9 +:105CC000260C0388356A00100000482100002821B6 +:105CD00001AE20243C105709AF8C0010AF8A004859 +:105CE000AF89001810900023AF8500148FBF0018F3 +:105CF0008FB100148FB0001027BD002003E0000812 +:105D0000AF80005400055080014648218D260004D4 +:105D10000A00014800D180219798007CA784006C7C +:105D2000A7800074A78000923C010800AC38008076 +:105D30000E000787000000003C0F60008DED080892 +:105D4000240EFFF03C0B600E260C0388356A001011 +:105D5000000048210000282101AE20243C105709F2 +:105D6000AF8C0010AF8A0048AF8900181490FFDF95 +:105D7000AF85001424110001AF9100548FBF0018AB +:105D80008FB100148FB0001003E0000827BD002081 +:105D90000A00017BA383007E3083FFFF8F880040D1 +:105DA0008F87003C000321403C0580003C020050EE +:105DB000008248253C0660003C0A010034AC040027 +:105DC0008CCD08E001AA58241160000500000000F5 +:105DD0008CCF08E024E7000101EA7025ACCE08E092 +:105DE0008D19001001805821ACB900388D180014AD +:105DF000ACB8003CACA9003000000000000000007E +:105E00000000000000000000000000000000000092 +:105E100000000000000000003C0380008C640000D3 +:105E2000308200201040FFFD3C0F60008DED08E047 +:105E30003C0E010001AE18241460FFE100000000D8 +:105E4000AF87003C03E00008AF8B00588F8500400F +:105E5000240BFFF03C06800094A7001A8CA90024B4 +:105E600030ECFFFF000C38C000EB5024012A402129 +:105E7000ACC8003C8CA400248CC3003C00831023DD +:105E800018400033000000008CAD002025A2000166 +:105E90003C0F0050ACC2003835EE00103C068000CC +:105EA000ACCE003000000000000000000000000048 +:105EB00000000000000000000000000000000000E2 +:105EC000000000003C0480008C9900003338002062 +:105ED0001300FFFD30E20008104000173C0980006D +:105EE0008C880408ACA800108C83040CACA30014AC +:105EF0003C1900203C188000AF19003094AE001807 +:105F000094AF001C01CF3021A4A6001894AD001A54 +:105F100025A70001A4A7001A94AB001A94AC001E98 +:105F2000118B00030000000003E0000800000000E7 +:105F300003E00008A4A0001A8D2A0400ACAA0010F7 +:105F40008D240404ACA400140A0002183C1900209B +:105F50008CA200200A0002003C0F00500A0001EE53 +:105F60000000000027BDFFE8AFBF00100E000232A6 +:105F7000000000008F8900408FBF00103C038000AC +:105F8000A520000A9528000A9527000427BD0018BF +:105F90003105FFFF30E6000F0006150000A22025A6 +:105FA00003E00008AC6400803C0508008CA50020DC +:105FB0008F83000C27BDFFE8AFB00010AFBF001407 +:105FC00010A300100000802124040001020430040A +:105FD00000A6202400C3102450440006261000010F +:105FE000001018802787FDA41480000A006718217C +:105FF000261000012E0900025520FFF38F83000CAC +:10600000AF85000C8FBF00148FB0001003E00008B4 +:1060100027BD00188C6800003C058000ACA8002457 +:106020000E000234261000013C0508008CA500205B +:106030000A0002592E0900022405000100851804F7 +:106040003C0408008C84002027BDFFC8AFBF00348B +:1060500000831024AFBE0030AFB7002CAFB60028CD +:10606000AFB50024AFB40020AFB3001CAFB200182E +:10607000AFB1001410400051AFB000108F84004049 +:10608000948700069488000A00E8302330D5FFFF8B +:1060900012A0004B8FBF0034948B0018948C000A20 +:1060A000016C50233142FFFF02A2482B1520000251 +:1060B00002A02021004020212C8F000515E00002C5 +:1060C00000809821241300040E0001C102602021E9 +:1060D0008F87004002609021AF80004494F4000A52 +:1060E000026080211260004E3291FFFF3C1670006A +:1060F0003C1440003C1E20003C1760008F99005863 +:106100008F380000031618241074004F0283F82BF8 +:1061100017E0003600000000107E00478F86004424 +:1061200014C0003A2403000102031023022320219B +:106130003050FFFF1600FFF13091FFFF8F870040C6 +:106140003C1100203C108000AE11003094EB000A9E +:106150003C178000024B5021A4EA000A94E9000A8F +:1061600094E800043123FFFF3106000F00062D00E4 +:106170000065F025AEFE008094F3000A94F6001846 +:1061800012D30036001221408CFF00148CF4001052 +:1061900003E468210000C02101A4782B029870213B +:1061A00001CF6021ACED0014ACEC001002B238233A +:1061B00030F5FFFF16A0FFB88F8400408FBF00347A +:1061C0008FBE00308FB7002C8FB600288FB500240B +:1061D0008FB400208FB3001C8FB200188FB1001451 +:1061E0008FB0001003E0000827BD00381477FFCC03 +:1061F0008F8600440E000EE202002021004018218C +:106200008F86004410C0FFC9020310230270702360 +:106210008F87004001C368210A0002E431B2FFFF0A +:106220008F86004414C0FFC93C1100203C10800040 +:106230000A0002AEAE1100300E00046602002021FA +:106240000A0002DB00401821020020210E0009395B +:10625000022028210A0002DB004018210E0001EE76 +:10626000000000000A0002C702B2382327BDFFC8A1 +:10627000AFB7002CAFB60028AFB50024AFB40020F4 +:10628000AFB3001CAFB20018AFB10014AFB0001034 +:10629000AFBF00300E00011B241300013C047FFF40 +:1062A0003C0380083C0220003C010800AC20007048 +:1062B0003496FFFF34770080345200033C1512C03F +:1062C000241400013C1080002411FF800E000245C0 +:1062D000000000008F8700488F8B00188F89001402 +:1062E0008CEA00EC8CE800E8014B302B01092823F4 +:1062F00000A6102314400006014B18231440000E82 +:106300003C05800002A3602B1180000B0000000000 +:106310003C0560008CEE00EC8CED00E88CA4180CC1 +:10632000AF8E001804800053AF8D00148F8F0010C3 +:10633000ADF400003C0580008CBF00003BF900017B +:10634000333800011700FFE13C0380008C6201003C +:1063500024060C0010460009000000008C680100B3 +:106360002D043080548000103C0480008C690100B2 +:106370002D2331811060000C3C0480008CAA0100A8 +:1063800011460004000020218CA6010024C5FF81D5 +:1063900030A400FF8E0B01000E000269AE0B00243A +:1063A0000A00034F3C0480008C8D01002DAC3300AB +:1063B00011800022000000003C0708008CE70098D4 +:1063C00024EE00013C010800AC2E00983C04800043 +:1063D0008C8201001440000300000000566000148D +:1063E0003C0440008C9F01008C9801000000982123 +:1063F00003F1C82400193940330F007F00EF7025E6 +:1064000001D26825AC8D08308C8C01008C85010090 +:10641000258B0100017130240006514030A3007F1C +:106420000143482501324025AC8808303C04400037 +:10643000AE0401380A00030E000000008C99010030 +:10644000240F0020AC99002092F80000330300FFD5 +:10645000106F000C241F0050547FFFDD3C048000AF +:106460008C8401000E00154E000000000A00034F4E +:106470003C04800000963824ACA7180C0A000327BF +:106480008F8F00108C8501000E0008F72404008017 +:106490000A00034F3C04800000A4102B24030001D9 +:1064A00010400009000030210005284000A4102BF6 +:1064B00004A00003000318405440FFFC00052840DE +:1064C0005060000A0004182B0085382B54E00004AB +:1064D0000003184200C33025008520230003184222 +:1064E0001460FFF9000528420004182B03E000089F +:1064F00000C310213084FFFF30C600FF3C0780003E +:106500008CE201B80440FFFE00064C000124302557 +:106510003C08200000C820253C031000ACE00180AE +:10652000ACE50184ACE4018803E00008ACE301B809 +:106530003C0660008CC5201C2402FFF03083020062 +:10654000308601001060000E00A2282434A500014E +:106550003087300010E0000530830C0034A50004C3 +:106560003C04600003E00008AC85201C1060FFFDC7 +:106570003C04600034A5000803E00008AC85201C42 +:1065800054C0FFF334A500020A0003B03087300086 +:1065900027BDFFE8AFB00010AFBF00143C0760009C +:1065A000240600021080001100A080218F83005873 +:1065B0000E0003A78C6400188F8200580000202171 +:1065C000240600018C45000C0E000398000000001A +:1065D0001600000224020003000010218FBF0014E7 +:1065E0008FB0001003E0000827BD00188CE8201CC5 +:1065F0002409FFF001092824ACE5201C8F870058EE +:106600000A0003CD8CE5000C3C02600E00804021A6 +:1066100034460100240900180000000000000000BA +:10662000000000003C0A00503C0380003547020097 +:10663000AC68003834640400AC65003CAC670030E2 +:106640008C6C0000318B00201160FFFD2407FFFFE0 +:106650002403007F8C8D00002463FFFF248400044A +:10666000ACCD00001467FFFB24C60004000000004E +:10667000000000000000000024A402000085282B78 +:106680003C0300203C0E80002529FFFF010540212E +:10669000ADC300301520FFE00080282103E0000892 +:1066A000000000008F82005827BDFFD8AFB3001C48 +:1066B000AFBF0020AFB20018AFB10014AFB00010F0 +:1066C00094460002008098218C5200182CC300814F +:1066D0008C4800048C4700088C51000C8C49001039 +:1066E000106000078C4A00142CC4000414800013AE +:1066F00030EB000730C5000310A0001000000000C0 +:106700002410008B02002021022028210E00039873 +:10671000240600031660000224020003000010217A +:106720008FBF00208FB3001C8FB200188FB10014F0 +:106730008FB0001003E0000827BD00281560FFF1AE +:106740002410008B3C0C80003C030020241F00011F +:10675000AD830030AF9F0044000000000000000047 +:10676000000000002419FFF024D8000F031978243A +:106770003C1000D0AD88003801F0702524CD000316 +:106780003C08600EAD87003C35850400AD8E0030BE +:10679000000D38823504003C3C0380008C6B000007 +:1067A000316200201040FFFD0000000010E00008F2 +:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 +:1067C00024A50004AC8800001467FFFB24840004A7 +:1067D0003C05600EACA60038000000000000000080 +:1067E000000000008F8600543C0400203C0780001D +:1067F000ACE4003054C000060120202102402021DA +:106800000E0003A7000080210A00041D02002021C1 +:106810000E0003DD01402821024020210E0003A7C5 +:10682000000080210A00041D0200202127BDFFE096 +:10683000AFB200183092FFFFAFB10014AFBF001C21 +:10684000AFB000101640000D000088210A0004932C +:106850000220102124050003508500278CE5000C40 +:106860000000000D262800013111FFFF24E2002066 +:106870000232802B12000019AF8200588F82004430 +:10688000144000168F8700583C0670003C0320001F +:106890008CE5000000A62024148300108F84006083 +:1068A000000544023C09800000A980241480FFE90F +:1068B000310600FF2CCA000B5140FFEB26280001D7 +:1068C000000668803C0E080025CE575801AE6021B6 +:1068D0008D8B0000016000080000000002201021E4 +:1068E0008FBF001C8FB200188FB100148FB0001042 +:1068F00003E0000827BD00200E0003982404008454 +:106900001600FFD88F8700580A000474AF8000601B +:10691000020028210E0003BF240400018F870058C5 +:106920000A000474AF820060020028210E0003BF39 +:10693000000020210A0004A38F8700580E000404E1 +:10694000020020218F8700580A000474AF82006083 +:1069500030AFFFFF000F19C03C0480008C9001B8DD +:106960000600FFFE3C1920043C181000AC83018097 +:10697000AC800184AC990188AC9801B80A00047518 +:106980002628000190E2000390E30002000020218D +:106990000002FE0000033A0000FF2825240600083C +:1069A0000E000398000000001600FFDC2402000324 +:1069B0008F870058000010210A000474AF82006025 +:1069C00090E8000200002021240600090A0004C308 +:1069D00000082E0090E4000C240900FF308500FF21 +:1069E00010A900150000302190F9000290F8000372 +:1069F000308F00FF94EB000400196E000018740043 +:106A0000000F62000186202501AE5025014B28258C +:106A10003084FF8B0A0004C32406000A90E30002BE +:106A200090FF0004000020210003360000DF28252D +:106A30000A0004C32406000B0A0004D52406008BB8 +:106A4000000449C23127003F000443423C02800059 +:106A500000082040240316802CE60020AC43002CC4 +:106A600024EAFFE02482000114C0000330A900FFE3 +:106A700000801021314700FF000260803C0D800043 +:106A8000240A0001018D20213C0B000E00EA28049D +:106A9000008B302111200005000538278CCE000026 +:106AA00001C5382503E00008ACC700008CD8000001 +:106AB0000307782403E00008ACCF000027BDFFE007 +:106AC000AFB10014AFB00010AFBF00183C076000BA +:106AD0008CE408083402F0003C1160003083F000C0 +:106AE000240501C03C04800E000030211062000625 +:106AF000241000018CEA08083149F0003928E00030 +:106B00000008382B000780403C0D0200AE2D081411 +:106B1000240C16803C0B80008E2744000E000F8B47 +:106B2000AD6C002C120000043C02169124050001FB +:106B3000120500103C023D2C345800E0AE384408E9 +:106B40003C1108008E31007C8FBF00183C066000AD +:106B500000118540360F16808FB100148FB00010E1 +:106B60003C0E020027BD0020ACCF442003E000080B +:106B7000ACCE08103C0218DA345800E0AE384408B5 +:106B80003C1108008E31007C8FBF00183C0660006D +:106B900000118540360F16808FB100148FB00010A1 +:106BA0003C0E020027BD0020ACCF442003E00008CB +:106BB000ACCE08100A0004EB240500010A0004EB27 +:106BC0000000282124020400A7820024A780001CC2 +:106BD000000020213C06080024C65A582405FFFF67 +:106BE00024890001000440803124FFFF01061821A0 +:106BF0002C87002014E0FFFAAC6500002404040098 +:106C0000A7840026A780001E000020213C06080063 +:106C100024C65AD82405FFFF248D0001000460809B +:106C200031A4FFFF018658212C8A00201540FFFA6D +:106C3000AD650000A7800028A7800020A780002263 +:106C4000000020213C06080024C65B582405FFFFF5 +:106C5000249900010004C0803324FFFF030678213B +:106C60002C8E000415C0FFFAADE500003C05600065 +:106C70008CA73D002403E08F00E31024344601403C +:106C800003E00008ACA63D002487007F000731C266 +:106C900024C5FFFF000518C2246400013082FFFFF5 +:106CA000000238C0A78400303C010800AC27003047 +:106CB000AF80002C0000282100002021000030219E +:106CC0002489000100A728213124FFFF2CA81701E7 +:106CD000110000032C8300801460FFF924C600011A +:106CE00000C02821AF86002C10C0001DA786002AF6 +:106CF00024CAFFFF000A11423C08080025085B581F +:106D00001040000A00002021004030212407FFFF2E +:106D1000248E00010004688031C4FFFF01A86021B7 +:106D20000086582B1560FFFAAD87000030A2001FC7 +:106D30005040000800043080240300010043C804D0 +:106D400000041080004878212738FFFF03E0000886 +:106D5000ADF8000000C820212405FFFFAC8500002D +:106D600003E000080000000030A5FFFF30C6FFFF71 +:106D700030A8001F0080602130E700FF0005294295 +:106D80000000502110C0001D24090001240B000147 +:106D900025180001010B2004330800FF0126782686 +:106DA000390E00202DED00012DC2000101A2182591 +:106DB0001060000D014450250005C880032C4021BF +:106DC0000100182110E0000F000A20278D040000A8 +:106DD000008A1825AD03000024AD00010000402109 +:106DE0000000502131A5FFFF252E000131C9FFFF12 +:106DF00000C9102B1040FFE72518000103E0000830 +:106E0000000000008D0A0000014440240A0005D162 +:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC +:106E2000AFB00010AFBF001430E7FFFF00005021EB +:106E30003410FFFF0000602124AF001F00C0482174 +:106E4000241800012419002005E0001601E010219B +:106E50000002F943019F682A0009702B01AE40240B +:106E600011000017000C18800064102110E00005CC +:106E70008C4B000000F840040008382301675824B8 +:106E800000003821154000410000402155600016E7 +:106E90003169FFFF258B0001316CFFFF05E1FFEC3D +:106EA00001E0102124A2003E0002F943019F682A5C +:106EB0000009702B01AE40241500FFEB000C188078 +:106EC000154600053402FFFF020028210E0005B51B +:106ED00000003821020010218FBF00148FB0001075 +:106EE00003E0000827BD00181520000301601821E9 +:106EF000000B1C0224080010306A00FF154000053A +:106F0000306E000F250D000800031A0231A800FFA3 +:106F1000306E000F15C00005307F000325100004FF +:106F200000031902320800FF307F000317E000055C +:106F3000386900012502000200031882304800FF72 +:106F4000386900013123000110600004310300FFA3 +:106F5000250A0001314800FF310300FF000C6940A1 +:106F600001A34021240A000110CAFFD53110FFFF00 +:106F7000246E000131C800FF1119FFC638C9000195 +:106F80002D1F002053E0001C258B0001240D000163 +:106F90000A000648240E002051460017258B0001E8 +:106FA00025090001312800FF2D0900205120001281 +:106FB000258B000125430001010D5004014B1024D5 +:106FC000250900011440FFF4306AFFFF3127FFFF5D +:106FD00010EE000C2582FFFF304CFFFF0000502117 +:106FE0003410FFFF312800FF2D0900205520FFF24B +:106FF00025430001258B0001014648260A000602B0 +:10700000316CFFFF00003821000050210A000654B7 +:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 +:10702000AFB10014001039423211FFE000071080A8 +:10703000AFB3001C00B1282330D3FFFFAFB200185C +:1070400030A5FFFF00809021026030210044202104 +:10705000AFBF00200E0005E03207001F022288218A +:107060003403FFFF0240202102002821026030216A +:1070700000003821104300093231FFFF02201021A7 +:107080008FBF00208FB3001C8FB200188FB1001487 +:107090008FB0001003E0000827BD00280E0005E0B7 +:1070A0000000000000408821022010218FBF002036 +:1070B0008FB3001C8FB200188FB100148FB0001076 +:1070C00003E0000827BD0028000424003C03600002 +:1070D000AC603D0810A00002348210063482101605 +:1070E00003E00008AC623D0427BDFFE0AFB0001034 +:1070F000309000FF2E020006AFBF001810400008BD +:10710000AFB10014001030803C03080024635784A2 +:1071100000C328218CA400000080000800000000AB +:10712000000020218FBF00188FB100148FB0001015 +:107130000080102103E0000827BD00209791002A5D +:1071400016200051000020213C020800904200332C +:107150000A0006BB00000000978D002615A0003134 +:10716000000020210A0006BB2402000897870024A3 +:1071700014E0001A00001821006020212402000100 +:107180001080FFE98FBF0018000429C2004530219C +:1071900000A6582B1160FFE43C0880003C0720004B +:1071A000000569C001A76025AD0C00203C038008E4 +:1071B0002402001F2442FFFFAC6000000441FFFDD9 +:1071C0002463000424A5000100A6702B15C0FFF560 +:1071D000000569C00A0006A58FBF00189787001C2C +:1071E0003C04080024845A58240504000E0006605C +:1071F00024060001978B002424440001308AFFFFFD +:107200002569FFFF2D48040000402821150000409B +:10721000A789002424AC3800000C19C00A0006B964 +:10722000A780001C9787001E3C04080024845AD8BD +:10723000240504000E00066024060001979900262C +:10724000244400013098FFFF272FFFFF2F0E04007A +:107250000040882115C0002CA78F0026A780001EA3 +:107260003A020003262401003084FFFF0E00068D41 +:107270002C4500010011F8C027F00100001021C0CA +:107280000A0006BB240200089785002E978700227B +:107290003C04080024845B580E00066024060001AC +:1072A0009787002A8F89002C2445000130A8FFFF12 +:1072B00024E3FFFF0109302B0040802114C0001897 +:1072C000A783002AA7800022978500300E000F7543 +:1072D00002002021244A05003144FFFF0E00068DE4 +:1072E000240500013C05080094A500320E000F752E +:1072F00002002021244521003C0208009042003376 +:107300000A0006BB000521C00A0006F3A784001E80 +:1073100024AC3800000C19C00A0006B9A784001C70 +:107320000A00070DA7850022308400FF27BDFFE873 +:107330002C820006AFBF0014AFB000101040001543 +:1073400000A03821000440803C0308002463579CBF +:10735000010328218CA40000008000080000000028 +:1073600024CC007F000751C2000C59C23170FFFFCE +:107370002547C40030E5FFFF2784001C02003021B0 +:107380000E0005B52407000197860028020620217B +:10739000A78400288FBF00148FB0001003E00008FE +:1073A00027BD00183C0508008CA50030000779C2F5 +:1073B0000E00038125E4DF003045FFFF3C04080098 +:1073C00024845B58240600010E0005B52407000143 +:1073D000978E002A8FBF00148FB0001025CD0001BA +:1073E00027BD001803E00008A78D002A0007C9C2C6 +:1073F0002738FF00001878C231F0FFFF3C04080076 +:1074000024845AD802002821240600010E0005B564 +:1074100024070001978D0026260E0100000E84002F +:1074200025AC00013C0B6000A78C0026AD603D0838 +:1074300036040006000030213C0760008CE23D0469 +:10744000305F000617E0FFFD24C9000100061B00A5 +:10745000312600FF006440252CC50004ACE83D0443 +:1074600014A0FFF68FBF00148FB0001003E00008D7 +:1074700027BD0018000751C22549C8002406000195 +:10748000240700013C04080024845A580E0005B566 +:107490003125FFFF978700248FBF00148FB00010A5 +:1074A00024E6000127BD001803E00008A786002499 +:1074B0003C0660183C090800252900FCACC9502C8A +:1074C0008CC850003C0580003C020002350700805B +:1074D000ACC750003C04080024841FE03C030800B3 +:1074E00024631F98ACA50008ACA2000C3C01080066 +:1074F000AC2459A43C010800AC2359A803E00008BF +:107500002402000100A030213C1C0800279C59AC3B +:107510003C0C04003C0B0002008B3826008C4026FB +:107520002CE200010007502B2D050001000A4880C5 +:107530003C030800246359A4004520250123182199 +:107540001080000300001021AC660000240200013E +:1075500003E00008000000003C1C0800279C59AC18 +:107560003C0B04003C0A0002008A3026008B3826BF +:107570002CC200010006482B2CE5000100094080C8 +:107580003C030800246359A4004520250103182169 +:1075900010800005000010213C0C0800258C1F986D +:1075A000AC6C00002402000103E0000800000000B1 +:1075B0003C0900023C080400008830260089382677 +:1075C0002CC30001008028212CE400010083102539 +:1075D0001040000B000030213C1C0800279C59ACD7 +:1075E0003C0A80008D4E00082406000101CA68256F +:1075F000AD4D00088D4C000C01855825AD4B000C9D +:1076000003E0000800C010213C1C0800279C59AC76 +:107610003C0580008CA6000C0004202724020001F9 +:1076200000C4182403E00008ACA3000C3C020002D4 +:107630001082000B3C0560003C070400108700032B +:107640000000000003E00008000000008CA908D042 +:10765000240AFFFD012A402403E00008ACA808D05A +:107660008CA408D02406FFFE0086182403E000083E +:10767000ACA308D03C05601A34A600108CC300806F +:1076800027BDFFF88CC50084AFA3000093A40000C1 +:107690002402001010820003AFA5000403E00008DC +:1076A00027BD000893A7000114E0001497AC000266 +:1076B00097B800023C0F8000330EFFFC01CF682119 +:1076C000ADA50000A3A000003C0660008CC708D058 +:1076D0002408FFFE3C04601A00E82824ACC508D04A +:1076E0008FA300048FA200003499001027BD00086A +:1076F000AF22008003E00008AF2300843C0B800031 +:10770000318AFFFC014B48218D2800000A00080C3B +:10771000AFA8000427BDFFE8AFBF00103C1C080065 +:10772000279C59AC3C0580008CA4000C8CA2000462 +:107730003C0300020044282410A0000A00A31824DF +:107740003C0604003C0400021460000900A610245A +:107750001440000F3C0404000000000D3C1C080015 +:10776000279C59AC8FBF001003E0000827BD00180C +:107770003C0208008C4259A40040F80900000000B7 +:107780003C1C0800279C59AC0A0008358FBF00102C +:107790003C0208008C4259A80040F8090000000093 +:1077A0000A00083B000000003C0880008D0201B880 +:1077B0000440FFFE35090180AD2400003C031000A9 +:1077C00024040040AD250004A1240008A1260009DE +:1077D000A527000A03E00008AD0301B83084FFFFCD +:1077E0000080382130A5FFFF000020210A00084555 +:1077F000240600803087FFFF8CA400002406003898 +:107800000A000845000028218F8300788F860070C9 +:107810001066000B008040213C07080024E75B68ED +:10782000000328C000A710218C440000246300013D +:10783000108800053063000F5466FFFA000328C06B +:1078400003E00008000010213C07080024E75B6CFF +:1078500000A7302103E000088CC200003C03900028 +:1078600034620001008220253C038000AC640020CB +:107870008C65002004A0FFFE0000000003E000086B +:10788000000000003C0280003443000100832025FA +:1078900003E00008AC44002027BDFFE0AFB10014B6 +:1078A0003091FFFFAFB00010AFBF001812200013DF +:1078B00000A080218CA20000240400022406020003 +:1078C0001040000F004028210E0007250000000096 +:1078D00000001021AE000000022038218FBF0018E8 +:1078E0008FB100148FB0001000402021000028212B +:1078F000000030210A00084527BD00208CA20000AE +:10790000022038218FBF00188FB100148FB00010F3 +:107910000040202100002821000030210A000845F5 +:1079200027BD002000A010213087FFFF8CA5000498 +:107930008C4400000A000845240600068F83FD9C45 +:1079400027BDFFE8AFBF0014AFB00010906700087C +:10795000008010210080282130E600400000202116 +:1079600010C000088C5000000E0000BD0200202155 +:10797000020020218FBF00148FB000100A000548BC +:1079800027BD00180E0008A4000000000E0000BD76 +:1079900002002021020020218FBF00148FB00010B0 +:1079A0000A00054827BD001827BDFFE0AFB0001052 +:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 +:1079C00092060001008088210E00087230D2000467 +:1079D00092040005001129C2A6050000348300406E +:1079E000A20300050E00087C022020210E00054A9B +:1079F0000220202124020001AE02000C02202821D6 +:107A0000A602001024040002A602001224060200AE +:107A1000A60200140E000725A60200161640000F4D +:107A20008FBF001C978C00743C0B08008D6B007896 +:107A30002588FFFF3109FFFF256A0001012A382B45 +:107A400010E00006A78800743C0F6006240E0016A4 +:107A500035ED0010ADAE00508FBF001C8FB2001886 +:107A60008FB100148FB0001003E0000827BD002084 +:107A700027BDFFE0AFB10014AFBF0018AFB00010DA +:107A80001080000400A088212402008010820007DA +:107A9000000000000000000D8FBF00188FB100141F +:107AA0008FB0001003E0000827BD00200E00087210 +:107AB00000A020218F86FD9C0220202190C500057A +:107AC0000E00087C30B000FF2403003E1603FFF1D7 +:107AD0003C0680008CC401780480FFFE34C801405D +:107AE000240900073C071000AD11000002202021EE +:107AF000A10900048FBF00188FB100148FB00010CF +:107B0000ACC701780A0008C527BD002027BDFFE0EB +:107B1000AFB00010AFBF0018AFB100143C10800030 +:107B20008E110020000000000E00054AAE04002067 +:107B3000AE1100208FBF00188FB100148FB000105D +:107B400003E0000827BD00203084FFFF00803821BB +:107B50002406003500A020210A0008450000282145 +:107B60003084FFFF008038212406003600A0202149 +:107B70000A0008450000282127BDFFD0AFB500242A +:107B80003095FFFFAFB60028AFB40020AFBF002C88 +:107B9000AFB3001CAFB20018AFB10014AFB000100B +:107BA00030B6FFFF12A000270000A0218F920058DE +:107BB0008E4300003C0680002402004000033E0289 +:107BC00000032C0230E4007F006698241482001D1C +:107BD00030A500FF8F8300682C68000A1100001098 +:107BE0008F8D0044000358803C0C0800258C57B84A +:107BF000016C50218D4900000120000800000000A8 +:107C000002D4302130C5FFFF0E0008522404008446 +:107C1000166000028F920058AF8000688F8D00447C +:107C20002659002026980001032090213314FFFFDD +:107C300015A00004AF9900580295202B1480FFDC9A +:107C400000000000028010218FBF002C8FB600289A +:107C50008FB500248FB400208FB3001C8FB20018A2 +:107C60008FB100148FB0001003E0000827BD003072 +:107C70002407003414A70149000000009247000EB9 +:107C80008F9FFDA08F90FD9C24181600A3E700197C +:107C90009242000D3C0880003C07800CA3E20018D3 +:107CA000964A00123C0D60003C117FFFA60A005C62 +:107CB000964400103623FFFF240200053099FFFF91 +:107CC000AE1900548E46001CAD1800288CEF000041 +:107CD0008DAE444801E6482601C93021AE06003881 +:107CE0008E05003824CB00013C0E7F00AE05003C21 +:107CF0008E0C003CAFEC0004AE0B00208E13002075 +:107D0000AE13001CA3E0001BAE03002CA3E2001284 +:107D10008E4A001424130050AE0A00348E0400343E +:107D2000AFE400148E590018AE1900489258000CA8 +:107D3000A218004E920D000835AF0020A20F0008D7 +:107D40008E090018012E282434AC4000AE0C001817 +:107D5000920B0000317200FF1253027F2403FF8058 +:107D60003C04080024845BE80E0008AA0000000020 +:107D70003C1108008E315BE80E00087202202021C1 +:107D80002405000424080001A2050025022020216A +:107D90000E00087CA20800053C0580008CB001782C +:107DA0000600FFFE8F92005834AE0140240F0002FF +:107DB0003C091000ADD10000A1CF0004ACA90178AE +:107DC0000A000962AF8000682CAD003751A0FF9413 +:107DD0008F8D0044000580803C110800263157E05B +:107DE000021178218DEE000001C0000800000000A3 +:107DF0002411000414B1008C3C0780003C080800EA +:107E00008D085BE88F86FD9CACE800208E4500085D +:107E10008F99FDA0240D0050ACC500308E4C000899 +:107E2000ACCC00508E4B000CACCB00348E43001019 +:107E3000ACC300388E4A0010ACCA00548E42001405 +:107E4000ACC2003C8E5F0018AF3F00048E50001C97 +:107E5000ACD0002090C40000309800FF130D024AFF +:107E6000000000008CC400348CD00030009030231F +:107E700004C000F12404008C126000EE2402000310 +:107E80000A000962AF8200682419000514B900666F +:107E90003C0580003C0808008D085BE88F86FD9C4F +:107EA000ACA800208E4C00048F8AFDA0240720007F +:107EB000ACCC001C924B000824120008A14B001906 +:107EC0008F82005890430009A14300188F85005805 +:107ED00090BF000A33E400FF1092001028890009C7 +:107EE000152000BA240E0002240D0020108D000B76 +:107EF000340780002898002117000008240740005C +:107F000024100040109000053C0700012419008057 +:107F1000109900023C070002240740008CC20018A0 +:107F20003C03FF00004350240147F825ACDF001854 +:107F300090B2000BA0D200278F8300589464000CED +:107F4000108001FE000000009467000C3C1F8000C0 +:107F50002405FFBFA4C7005C9063000E2407000443 +:107F6000A0C300088F820058904A000FA0CA0009E1 +:107F70008F8900588D3200108FE400740244C823AA +:107F8000ACD900588D300014ACD0002C95380018B6 +:107F9000330DFFFFACCD00409531001A322FFFFFAB +:107FA000ACCF00448D2E001CACCE00489128000EB2 +:107FB000A0C8000890CC000801855824126001B6C2 +:107FC000A0CB00088F9200580A000962AF870068B2 +:107FD0002406000614A600143C0E80003C0F080086 +:107FE0008DEF5BE88F85FD98ADCF00208E4900189E +:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B +:1080000024040005ACA800048CCC003C1260008164 +:10801000AD6C00000A000962AF84006824110007FB +:1080200010B1004B240400063C05080024A55BE8C1 +:108030000E000881240400818F9200580013102B39 +:108040000A000962AF820068241F002314BFFFF6F4 +:108050003C0C80003C0508008CA55BE88F8BFDA0E4 +:10806000AD8500208F91FD9C8E4600042564002084 +:1080700026450014AE260028240600030E000F81BA +:10808000257000308F87005802002021240600034D +:108090000E000F8124E500083C04080024845BE8FE +:1080A0000E0008AA0000000092230000240A0050DD +:1080B000306200FF544AFFE18F9200580E000F6CAF +:1080C000000000000A000A6A8F920058240800335A +:1080D00014A800323C0380003C1108008E315BE89C +:1080E0008F8FFDA0AC7100208E420008240D002867 +:1080F0008F89FD9CADE200308E4A000C24060009F9 +:10810000ADEA00348E5F0010ADFF00388E440014DD +:10811000ADE400208E590018ADF900248E58001CE3 +:10812000ADF80028A1ED00118E4E00041260003160 +:10813000AD2E00288F9200580A000962AF860068B1 +:10814000240D002214ADFFB8000000002404000735 +:108150003C1008008E105BE83C188000AF10002037 +:108160005660FEAEAF8400683C04080024845BE8DF +:108170000E0008AA241300508F84FD9C90920000EA +:10818000325900FF1333014B000000008F9200585A +:10819000000020210A000962AF8400683C05080045 +:1081A00024A55BE80E000858240400810A000A6A2E +:1081B0008F92005802D498213265FFFF0E000852BA +:1081C000240400840A0009628F920058108EFF5325 +:1081D000240704002887000310E00179241100041B +:1081E000240F0001548FFF4D240740000A000A228B +:1081F000240701003C05080024A55BE80E0008A444 +:10820000240400828F920058000030210A00096285 +:10821000AF8600683C04080024845BE88CC2003808 +:108220000E0008AA8CC3003C8F9200580A000AC0B6 +:1082300000002021240400823C05080024A55BE8FE +:108240000E0008A4000000008F92005800001021CA +:108250000A000962AF8200688E5000048F91FD9C75 +:108260003C078000ACF00020922C00050200282181 +:10827000318B0002156001562404008A8F92FDA004 +:108280002404008D9245001B30A6002014C001502C +:1082900002002821922E00092408001231C900FF93 +:1082A0001128014B240400810E00087202002021D5 +:1082B0009258001B240F000402002021370D0042B9 +:1082C000A24D001B0E00087CA22F00253C0580005B +:1082D0008CA401780480FFFE34B90140241F000201 +:1082E000AF300000A33F00048F9200583C101000F4 +:1082F000ACB001780A000A6B0013102B8E500004FA +:108300008F91FD9C3C038000AC700020922A0005F8 +:108310000200282131420002144000172404008A80 +:10832000922C00092412000402002821318B00FF46 +:1083300011720011240400810E0008720200202135 +:108340008F89FDA0240800122405FFFE912F001B39 +:108350000200202135EE0020A12E001BA2280009DA +:108360009226000500C538240E00087CA2270005CF +:1083700002002821000020210E0009330000000027 +:108380000A000A6A8F9200588E4C00043C07800055 +:108390003C10080026105BE8ACEC00203C01080013 +:1083A000AC2C5BE8924B0003317100041220013BBE +:1083B0008F84FD9C24020006A0820009924F001BBE +:1083C000240EFFC031E9003F012E4025A08800089F +:1083D0009245000330A6000114C0013200000000E5 +:1083E0008E420008AE0200083C0208008C425BF09E +:1083F000104001318F90FDA0000219C28F8DFD9CAD +:10840000A603000C8E4A000C24180001240400145A +:10841000AE0A002C8E420010AE02001C965F0016C1 +:10842000A61F003C96590014A619003EADB8000CDA +:10843000A5B80010A5B80012A5B80014A5B800167C +:1084400012600144A2040011925100033232000272 +:108450002E5300018F920058266200080A0009621C +:10846000AF8200688E4400043C1980003C068008FE +:10847000AF2400208E45000890D80000240D005045 +:10848000331100FF122D009C2407008824060009E8 +:108490000E000845000000000A000A6A8F9200588A +:1084A0008E5000043C0980003C118008AD30002053 +:1084B0009228000024050050310400FF10850110AF +:1084C0002407008802002021000028210E00084512 +:1084D0002406000E922D00002418FF80020028219F +:1084E00001B8802524040004240600300E0007256E +:1084F000A23000000A000A6A8F9200588E500004D1 +:108500008F91FDA03C028000AC500020923F001BE8 +:1085100033F900101320006C240700810200202191 +:10852000000028212406001F0E000845000000005E +:108530000A000A6A8F9200588E44001C0E00085DE3 +:1085400000000000104000E3004048218F880058E0 +:1085500024070089012020218D05001C240600012C +:108560000E000845000000000A000A6A8F920058B9 +:10857000964900023C10080026105BE831280004F0 +:10858000110000973C0460008E4E001C3C0F8000E0 +:10859000ADEE00203C010800AC2E5BE896470002DF +:1085A00030E40001148000E6000000008E42000468 +:1085B000AE0200083C1008008E105BF0120000ECC8 +:1085C0003C0F80008F92FD9C241000018E4E0018FD +:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 +:1085E000A2400005AE50000C3C0808008D085BF06E +:1085F0008F840058A6500010000839C2A6500012FF +:10860000A6500014A6500016A5A7000C8C8C0008DC +:108610008F8B00588F8A0058ADAC002C8D63000CF6 +:1086200024070002ADA3001C91460010A1A6001172 +:108630008F82005890450011A3E500088F990058DB +:1086400093380012A258004E8F910058922F0013B9 +:10865000A1AF00128F920058964E0014A5AE003CB8 +:1086600096490016A5A9003E8E480018ADA8001432 +:108670005660FD6AAF8700683C05080024A55BE8EA +:108680000E000881000020218F9200580000382140 +:108690000A000962AF8700683C05080024A55BE872 +:1086A0000E0008A4240400828F9200580A000A4D8C +:1086B000000038210E000F6C000000008F9200585F +:1086C0000A000AC0000020210E00087202002021CA +:1086D0009223001B02002021346A00100E00087C47 +:1086E000A22A001B000038210200202100002821BE +:1086F0000A000BA52406001F9242000C305F000107 +:1087000013E0000300000000964A000EA4CA002CEB +:10871000924B000C316300025060000600003821CB +:108720008E470014964C0012ACC7001CA4CC001A53 +:10873000000038210A000B7F240600093C050800D0 +:1087400024A55BE80E0008A42404008B8F92005837 +:108750000A000A4D0013382B3C0C08008D8C5BE896 +:1087600024DFFFFE25930100326B007F016790211B +:1087700002638824AD110028AE4600E0AE4000E45C +:108780000A0009B3AE5F001CACC000543C0D0800E9 +:108790008DAD5BE83C18800C37090100ACED00287A +:1087A0008E510014AD3100E08E4F0014AD2F00E467 +:1087B0008E4E001025C7FFFE0A0009F4AD27001CED +:1087C0005491FDD6240740000A000A222407100015 +:1087D0000E00092D000000000A000A6A8F9200585E +:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 +:1087F000AC205BE810710062000000003C196C6264 +:1088000037387970147800082404000297850074C2 +:108810009782006C2404009200A2F82B13E0001948 +:1088200002002821240400020E00069524050200FF +:108830003C068000ACC200203C010800AC225BE892 +:108840001040000D8F8C0058240A002824040003D7 +:10885000918B0010316300FF546A00012404000171 +:108860000E0000810000000010400004240400837A +:108870000A000BC28F920058240400833C050800B4 +:1088800024A55BE80E000881000000008F920058CC +:108890000013382B0A000962AF8700680A000B49F1 +:1088A000240200128E4400080E00085D0000000043 +:1088B0000A000B55AE0200083C05080024A55BE841 +:1088C0000E000858240400878F9200580A000B728B +:1088D0000013102B240400040E000695240500301C +:1088E0001440002A004048218F8800582407008344 +:1088F000012020218D05001C0A000BB32406000175 +:108900008F8300788F8600701066FEEE000038219D +:108910003C07080024E75B6C000320C00087282187 +:108920008CAE000011D0005D246F000131E3000F18 +:108930005466FFFA000320C00A000B8C00003821A7 +:108940008E4400040E00085D000000000A000BC801 +:10895000AE0200083C05080024A55BE80E0008A450 +:10896000240400828F9200580A000B72000010212C +:108970003C05080024A55BE80A000C7C2404008761 +:108980008C83442C0A000C5B3C196C628F88005865 +:108990003C0780083C0C8000240B0050240A000196 +:1089A000AD820020A0EB0000A0EA000191030004CA +:1089B000A0E3001891040005A0E400199106000648 +:1089C0003C04080024845B6CA0E6001A91020007B6 +:1089D0003C06080024C65B68A0E2001B9105000865 +:1089E000A0E5001C911F0009A0FF001D9119000ABD +:1089F000A0F9001E9118000BA0F8001F9112000CA6 +:108A0000A0F200209111000DA0F100219110000EA4 +:108A1000A0F00022910F000FA0EF0023910E001094 +:108A2000A0EE0024910D0011A0ED0025950C00147E +:108A3000A4EC0028950B00168F8A00708F920078A6 +:108A4000A4EB002A95030018000A10C02545000178 +:108A5000A4E3002C8D1F001C0044C0210046C82147 +:108A600030A5000FAF3F0000AF09000010B20006B4 +:108A7000AF850070000038218D05001C01202021E9 +:108A80000A000BB32406000124AD000131A7000F3A +:108A9000AF8700780A000CF9000038213C06080076 +:108AA00024C65B680086902100003821ACA000003D +:108AB0000A000B8CAE4000003C0482013C036000C5 +:108AC00034820E02AC603D68AF80009803E000087D +:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 +:108AE000001018422C620041AFBF00141440000275 +:108AF00024040080240300403C010800AC300060E6 +:108B00003C010800AC2300640E000F7500602821B2 +:108B1000244802BF2409FF8001092824001039805D +:108B2000001030408FBF00148FB0001000A720212C +:108B300000861821AF8300803C010800AC25005856 +:108B40003C010800AC24005C03E0000827BD0018CD +:108B5000308300FF30C6FFFF30E400FF3C08800098 +:108B60008D0201B80440FFFE000354000144382583 +:108B70003C09600000E920253C031000AD050180A0 +:108B8000AD060184AD04018803E00008AD0301B81F +:108B90008F8500583C0A6012354800108CAC0004E8 +:108BA0003C0D600E35A60010318B00062D690001CA +:108BB000AD0900C48CA70004ACC731808CA20008AA +:108BC00094A40002ACC231848CA3001C0460000396 +:108BD000A784009003E00008000000008CAF00189C +:108BE000ACCF31D08CAE001C03E00008ACCE31D449 +:108BF0008F8500588F87FF288F86FF308CAE00044A +:108C00003C0F601235E80010ACEE00788CAD000827 +:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 +:108C2000ACCB004894CA00543C0208008C4200447B +:108C300025490001A4C9005494C400543083FFFFA7 +:108C400010620017000000003C0208008C42004047 +:108C5000A4C200528CA30018ACE300308CA2001414 +:108C6000ACE2002C8CB90018ACF900388CB80014B8 +:108C700024050001ACF800348D0600BC50C5001975 +:108C80008D0200B48D0200B8A4E2004894E40048CC +:108C9000A4E4004A94E800EA03E000083102FFFF80 +:108CA0003C0208008C420024A4C00054A4C200521C +:108CB0008CA30018ACE300308CA20014ACE2002CB2 +:108CC0008CB90018ACF900388CB8001424050001E8 +:108CD000ACF800348D0600BC54C5FFEB8D0200B823 +:108CE0008D0200B4A4E2004894E40048A4E4004AE1 +:108CF00094E800EA03E000083102FFFF8F86005885 +:108D00003C0480008CC900088CC80008000929C0F8 +:108D1000000839C0AC87002090C30007306200040F +:108D20001040003EAF85009490CB0007316A0008E8 +:108D30001140003D8F87FF2C8CCD000C8CCE001491 +:108D400001AE602B11800036000000008CC2000CC8 +:108D5000ACE200708CCB00188F85FF288F88FF3025 +:108D6000ACEB00748CCA00102402FFF8ACAA00D847 +:108D70008CC9000CAD0900608CC4001CACA400D0F0 +:108D800090E3007C0062C824A0F9007C90D8000722 +:108D9000330F000811E000040000000090ED007C9B +:108DA00035AC0001A0EC007C90CF000731EE000153 +:108DB00011C000060000000090E3007C241800347D +:108DC00034790002A0F9007CACB800DC90C2000746 +:108DD0003046000210C000040000000090E8007C53 +:108DE00035040004A0E4007C90ED007D3C0B600E97 +:108DF000356A001031AC003FA0EC007D8D4931D4C4 +:108E00003127000110E00002240E0001A0AE00098D +:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 +:108E20000A000DAF8CC200140A000DB0ACE0007057 +:108E30008F8C005827BDFFD8AFB3001CAFB200180D +:108E4000AFB00010AFBF0020AFB10014918F00157C +:108E50003C13600E3673001031EB000FA38B009CA7 +:108E60008D8F00048D8B0008959F0012959900103E +:108E70009584001A9598001E958E001C33EDFFFF17 +:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 +:108E90003C010800AC2D00243C010800AC29004432 +:108EA0003C010800AC2A0040AE683178AE67317CE6 +:108EB00091850015959100163C12601236520010F3 +:108EC00030A200FF3230FFFFAE623188AE5000B4F6 +:108ED00091830014959F0018240600010066C804C1 +:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 +:108EF000AF8F00843C08600631CD00FFAE4D00C04E +:108F0000918A00159584000E3C07600A314900FFE4 +:108F1000AF8B00883084FFFFAE4900C835110010C8 +:108F20000E000D1034F004103C0208008C4200606A +:108F30003C0308008C6300643C0608008CC60058A3 +:108F40003C0508008CA5005C8F8400808FBF00204A +:108F5000AE23004CAE65319CAE030054AE4500DC40 +:108F6000AE6231A0AE6331A4AE663198AE22004845 +:108F70008FB3001CAE0200508FB10014AE4200E06F +:108F8000AE4300E4AE4600D88FB000108FB2001898 +:108F90000A00057D27BD0028978500929783007CF5 +:108FA00027BDFFE8AFB0001000A3102BAFBF001427 +:108FB000240400058F900058104000552409000239 +:108FC0000E0006958F850080AF8200942404000374 +:108FD0001040004F240900023C0680000E00008172 +:108FE000ACC2002024070001240820001040004DDE +:108FF00024040005978E00928F8AFF2C24090050CC +:1090000025C50001A7850092A14900003C0D08007C +:109010008DAD0064240380008F84FF28000D66005E +:10902000AD4C0018A5400006954B000A8F85FF3017 +:109030002402FF8001633024A546000A915F000AE4 +:109040000000482103E2C825A159000AA0A0000899 +:10905000A140004CA08000D5961800029783009094 +:109060003C020004A49800EA960F00022418FFBFF7 +:1090700025EE2401A48E00BE8E0D0004ACAD00448C +:109080008E0C0008ACAC0040A4A00050A4A000547A +:109090008E0B000C240C0030AC8B00288E060010C8 +:1090A000AC860024A480003EA487004EA487005014 +:1090B000A483003CAD420074AC8800D8ACA800602A +:1090C000A08700FC909F00D433F9007FA09900D4C2 +:1090D000909000D402187824A08F00D4914E007C88 +:1090E00035CD0001A14D007C938B009CAD480070F4 +:1090F000AC8C00DCA08B00D68F8800888F87008422 +:10910000AC8800C4AC8700C8A5400078A540007AB0 +:109110008FBF00148FB000100120102103E0000861 +:1091200027BD00188F8500940E0007258F860080CC +:109130000A000E9F2409000227BDFFE0AFB0001017 +:109140008F900058AFB10014AFBF00188E09000413 +:109150000E00054A000921C08E0800048F84FF28F4 +:109160008F82FF30000839C03C068000ACC7002069 +:10917000948500EA904300131460001C30B1FFFF97 +:109180008F8CFF2C918B0008316A00401540000B3A +:10919000000000008E0D0004022030218FBF001857 +:1091A0008FB100148FB00010240400220000382179 +:1091B000000D29C00A000D2F27BD00200E000098C9 +:1091C000000000008E0D0004022030218FBF001827 +:1091D0008FB100148FB00010240400220000382149 +:1091E000000D29C00A000D2F27BD00200E000090A1 +:1091F000000000008E0D0004022030218FBF0018F7 +:109200008FB100148FB00010240400220000382118 +:10921000000D29C00A000D2F27BD002027BDFFE04B +:10922000AFB200183092FFFFAFB00010AFBF001C0C +:10923000AFB100141240001E000080218F8600583C +:109240008CC500002403000600053F02000514023F +:1092500030E4000714830016304500FF2CA80006F8 +:1092600011000040000558803C0C0800258C58BCBB +:10927000016C50218D490000012000080000000011 +:109280008F8E0098240D000111CD005024020002A1 +:10929000AF820098260900013130FFFF24C800206A +:1092A0000212202B010030211480FFE5AF88005806 +:1092B000020010218FBF001C8FB200188FB1001464 +:1092C0008FB0001003E0000827BD00209387007EC8 +:1092D00054E00034000030210E000DE700000000D3 +:1092E0008F8600580A000EFF240200018F87009825 +:1092F0002405000210E50031240400130000282199 +:1093000000003021240700010E000D2F0000000096 +:109310000A000F008F8600588F83009824020002F5 +:109320001462FFF6240400120E000D9A00000000E3 +:109330008F85009400403021240400120E000D2F70 +:10934000000038210A000F008F8600588F83009894 +:109350002411000310710029241F0002107FFFCE8A +:1093600026090001240400100000282100003021FB +:109370000A000F1D240700018F91009824060002A7 +:109380001626FFF9240400100E000E410000000014 +:10939000144000238F9800588F8600580A000EFF53 +:1093A00024020003240400140E000D2F00002821C5 +:1093B0008F8600580A000EFF240200020E000EA93C +:1093C000000000000A000F008F8600580E000D3FBD +:1093D00000000000241900022404001400002821C9 +:1093E0000000302100003821AF9900980E000D2FA9 +:1093F000000000000A000F008F8600580E000D5775 +:10940000000000008F8500942419000200403021E4 +:1094100024040010000038210A000F56AF9900986C +:109420000040382124040010970F0002000028217A +:109430000E000D2F31E6FFFF8F8600580A000F0047 +:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D +:109450008C8500182402000100A61824AC83001893 +:1094600003E00008A08200053084FFFF30A5FFFF65 +:109470001080000700001821308200011040000217 +:1094800000042042006518211480FFFB00052840DD +:1094900003E000080060102110C000070000000079 +:1094A0008CA2000024C6FFFF24A50004AC820000AB +:1094B00014C0FFFB2484000403E000080000000047 +:1094C00010A0000824A3FFFFAC86000000000000ED +:1094D000000000002402FFFF2463FFFF1462FFFA74 +:1094E0002484000403E0000800000000000411C010 +:1094F00003E000082442024027BDFFE8AFB000109F +:1095000000808021AFBF00140E000F9600A0202124 +:1095100000504821240AFF808FBF00148FB0001034 +:10952000012A30243127007F3C08800A3C042100B6 +:1095300000E8102100C428253C03800027BD001846 +:10954000AC650024AF820038AC400000AC6500245C +:1095500003E00008AC4000403C0D08008DAD005811 +:1095600000056180240AFF8001A45821016C482174 +:10957000012A30243127007F3C08800C3C04210064 +:1095800000E8102100C428253C038000AC650028B9 +:10959000AF82003403E00008AC40002430A5FFFF98 +:1095A0003C0680008CC201B80440FFFE3C086015F8 +:1095B00000A838253C031000ACC40180ACC0018475 +:1095C000ACC7018803E00008ACC301B83C0D08003B +:1095D0008DAD005800056180240AFF8001A4582148 +:1095E000016C4021010A4824000931403107007F05 +:1095F00000C728253C04200000A418253C02800058 +:10960000AC43083003E00008AF80003427BDFFE81A +:10961000AFB0001000808021AFBF00140E000F9685 +:1096200000A0202100504821240BFF80012B502452 +:10963000000A39403128007F3C0620008FBF00140B +:109640008FB0001000E8282534C2000100A21825C0 +:109650003C04800027BD0018AC83083003E00008FC +:10966000AF8000383C0580088CA700603C0680086D +:109670000087102B144000112C8340008CA8006040 +:109680002D0340001060000F240340008CC90060CF +:109690000089282B14A00002008018218CC30060D0 +:1096A00000035A42000B30803C0A0800254A59202A +:1096B00000CA202103E000088C8200001460FFF340 +:1096C0002403400000035A42000B30803C0A08008B +:1096D000254A592000CA202103E000088C8200009E +:1096E0003C05800890A60008938400AB24C20001CA +:1096F000304200FF3043007F1064000C0002382726 +:10970000A0A200083C0480008C85017804A0FFFE24 +:109710008F8A00A0240900023C081000AC8A014096 +:10972000A089014403E00008AC8801780A00101BFE +:1097300030E2008027BDFFD8AFB200188F9200A49E +:10974000AFBF0020AFB3001CAFB00010AFB100142A +:109750008F9300348E5900283C1000803C0EFFEFA0 +:10976000AE7900008E580024A260000A35CDFFFFBC +:10977000AE7800049251002C3C0BFF9F356AFFFF2E +:10978000A271000C8E6F000C3C080040A271000B0F +:1097900001F06025018D4824012A382400E8302595 +:1097A000AE66000C8E450004AE6000183C0400FF5D +:1097B000AE6500148E43002C3482FFFFA6600008C3 +:1097C0000062F824AE7F00108E5900088F9000A030 +:1097D000964E0012AE7900208E51000C31D83FFF1A +:1097E00000187980AE7100248E4D001401F06021C4 +:1097F00031CB0001AE6D00288E4A0018000C41C22A +:10980000000B4B80AE6A002C8E46001C01093821EB +:10981000A667001CAE660030964500028E4400200C +:10982000A665001EAE64003492430033306200042B +:1098300054400006924700003C0280083443010077 +:109840008C7F00D0AE7F0030924700008F860038BA +:10985000A0C700309245003330A4000250800007BA +:10986000925100018F880038240BFF80910A00304C +:10987000014B4825A1090030925100018F9000381A +:10988000240CFFBF2404FFDFA21100318F8D0038AC +:109890003C1880083711008091AF003C31EE007F0A +:1098A000A1AE003C8F890038912B003C016C502404 +:1098B000A12A003C8F9F00388E68001493E6003C7C +:1098C0002D0700010007114000C4282400A218251C +:1098D000A3E3003C8F87003896590012A4F90032A8 +:1098E0008E450004922E007C30B0000300107823D7 +:1098F00031ED000300AD102131CC000215800002D3 +:1099000024460034244600303C0280083443008062 +:10991000907F007C00BFC824333800041700000289 +:1099200024C2000400C010218F98003824190002BE +:10993000ACE20034A3190000924F003F8F8E003834 +:109940003C0C8008358B0080A1CF00018F9100383E +:10995000924D003F8E440004A62D0002956A005CE3 +:109960000E000FF43150FFFF00024B800209382532 +:109970003C08420000E82825AE2500048E4400384B +:109980008F850038ACA400188E460034ACA6001CAD +:10999000ACA0000CACA00010A4A00014A4A0001661 +:1099A000A4A00020A4A00022ACA000248E62001479 +:1099B00050400001240200018FBF00208FB3001C23 +:1099C0008FB200188FB100148FB00010ACA2000845 +:1099D0000A00101327BD002827BDFFC83C058008DA +:1099E00034A40080AFBF0034AFBE0030AFB7002C4E +:1099F000AFB60028AFB50024AFB40020AFB3001C51 +:109A0000AFB20018AFB10014AFB00010948300786B +:109A10009482007A104300512405FFFF0080F0215A +:109A20000A0011230080B821108B004D8FBF003435 +:109A30008F8600A03C1808008F18005C2411FF805E +:109A40003C1680000306782101F18024AED0002C62 +:109A500096EE007A31EC007F3C0D800E31CB7FFF1B +:109A6000018D5021000B4840012AA82196A4000036 +:109A70003C0808008D0800582405FF8030953FFF02 +:109A800001061821001539800067C8210325F82434 +:109A90003C02010003E290253338007F3C11800C2A +:109AA000AED20028031190219250000D320F000415 +:109AB00011E0003702E0982196E3007A96E8007AF8 +:109AC00096E5007A2404800031077FFF24E300013B +:109AD00030627FFF00A4F82403E2C825A6F9007ACB +:109AE00096E6007A3C1408008E94006030D67FFF22 +:109AF00012D400C1000000008E5800188F8400A00E +:109B000002A028212713FFFF0E000FCEAE53002C1A +:109B100097D5007897D4007A12950010000028217C +:109B20003C098008352401003C0A8008914800085F +:109B3000908700D53114007F30E400FF0284302B81 +:109B400014C0FFB9268B0001938E00AB268C000158 +:109B5000008E682115ACFFB78F8600A08FBF003440 +:109B60008FBE00308FB7002C8FB600288FB5002431 +:109B70008FB400208FB3001C8FB200188FB1001477 +:109B80008FB0001000A0102103E0000827BD0038AE +:109B900000C020210E000F99028028218E4B00105A +:109BA0008E4C00308F84003824090002016C502351 +:109BB000AE4A0010A089000096E3005C8E4400309D +:109BC0008F9100380E000FF43070FFFF00024380C9 +:109BD000020838253C02420000E22825AE25000498 +:109BE0008E5F00048F8A00388E590000240B000815 +:109BF000AD5F001CAD590018AD40000CAD40001029 +:109C00009246000A240400052408C00030D000FF5A +:109C1000A550001496580008A55800169251000A45 +:109C20003C188008322F00FFA54F0020964E0008F8 +:109C300037110100A54E0022AD400024924D000BCB +:109C400031AC00FFA54C0002A14B00018E49003051 +:109C50008F830038240BFFBFAC690008A06400307C +:109C60008F9000382403FFDF9607003200E8282495 +:109C700000B51025A6020032921F003233F9003FD2 +:109C800037260040A20600328F8C0038AD800034A9 +:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F +:109CA00031CD007FA18D003C8F84003835EEFFFF61 +:109CB000908A003C014B4824A089003C8F850038E5 +:109CC00090A8003C01033824A0A7003C8E42003439 +:109CD0008F9100383C038008AE2200408E59002C42 +:109CE0008E5F0030033F3023AE26004492300048A0 +:109CF0003218007FA23800488F8800388E4D00301F +:109D00008D0C004801AE582401965024014B482583 +:109D1000AD0900489244000AA104004C964700088F +:109D20008F850038A4A7004E8E5000308E4400303E +:109D30000E0003818C65006092F9007C0002F940FE +:109D4000004028210002110003E2302133360002D6 +:109D500012C00003020680210005B0800216802197 +:109D6000926D007C31B30004126000020005708027 +:109D7000020E80218E4B00308F8800382405800031 +:109D8000316A0003000A4823312400030204182129 +:109D9000AD03003496E4007A96F0007A96F1007AEA +:109DA00032027FFF2447000130FF7FFF0225C824D5 +:109DB000033F3025A6E6007A96F8007A3C120800A8 +:109DC0008E520060330F7FFF11F200180000000078 +:109DD0008F8400A00E000FCE02A028218F8400A047 +:109DE0000E000FDE028028210E001013000000007C +:109DF0000A00111F0000000096F1007A022480245E +:109E0000A6F0007A92EF007A92EB007A31EE00FF32 +:109E1000000E69C2000D6027000C51C03169007F3F +:109E2000012A20250A001119A2E4007A96E6007A98 +:109E300000C5C024A6F8007A92EF007A92F3007A67 +:109E400031F200FF001271C2000E6827000DB1C090 +:109E5000326C007F01962825A2E5007A0A0011D015 +:109E60008F8400A03C0380003084FFFF30A5FFFFFB +:109E7000AC640018AC65001C03E000088C620014A0 +:109E800027BDFFA03C068008AFBF005CAFBE0058F6 +:109E9000AFB70054AFB60050AFB5004CAFB40048F8 +:109EA000AFB30044AFB20040AFB1003CAFB0003838 +:109EB00034C80100910500D590C700083084FFFF29 +:109EC00030A500FF30E2007F0045182AAFA4001043 +:109ED000A7A00018A7A0002610600055AFA000148E +:109EE00090CA00083149007F00A9302324D3FFFF26 +:109EF0000013802B8FB400100014902B02128824C2 +:109F0000522000888FB300143C03800894790052DB +:109F1000947E00508FB60010033EC0230018BC0092 +:109F2000001714030016FC0002C2A82A16A00002A3 +:109F3000001F2C030040282100133C0000072403CD +:109F400000A4102A5440000100A020212885000907 +:109F500014A000020080A021241400083C0C8008FA +:109F60008D860048001459808D88004C3C03800089 +:109F70003169FFFF3C0A0010012A202534710400DA +:109F8000AC660038AF9100A4AC68003CAC64003013 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB0008C6E000031CD002011A0FFFD0014782A26 +:109FC00001F01024104000390000A8213C16800840 +:109FD00092D700083C1280008E44010032F6007FC8 +:109FE0000E000F9902C028218E3900108E44010006 +:109FF0000000902133373FFF0E000FB102E028210F +:10A00000923800003302003F2C500008520000102C +:10A0100000008821000210803C030800246358E4FB +:10A020000043F8218FFE000003C00008000000007C +:10A0300090CF0008938C00AB31EE007F00AE682318 +:10A04000018D58210A0012172573FFFF0000882197 +:10A050003C1E80008FC401000E000FCE02E02821BC +:10A060008FC401000E000FDE02C028211220000F55 +:10A070000013802B8F8B00A426A400010004AC00E9 +:10A08000027298230015AC032578004002B4B02A70 +:10A090000013802B241700010300882102D0102414 +:10A0A000AF9800A41440FFC9AFB700143C07800864 +:10A0B00094E200508FAE00103C05800002A288217F +:10A0C0003C060020A4F10050ACA6003094F40050EF +:10A0D00094EF005201D51823306CFFFF11F4001EDD +:10A0E000AFAC00108CEF004C001561808CF500487F +:10A0F00001EC28210000202100AC582B02A4C02133 +:10A10000030BB021ACE5004CACF600488FB4001056 +:10A110000014902B021288241620FF7C3C03800838 +:10A120008FB300148FBF005C8FBE00583A620001ED +:10A130008FB700548FB600508FB5004C8FB40048D5 +:10A140008FB300448FB200408FB1003C8FB0003815 +:10A1500003E0000827BD006094FE00548CF2004428 +:10A1600033C9FFFE0009C8C00259F821ACBF003C4A +:10A170008CE800448CAD003C010D50231940003B9D +:10A18000000000008CF7004026E20001ACA200387D +:10A190003C05005034A700103C038000AC67003041 +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C0008C7800003316002012C0FFFD3C1180087F +:10A1D000962200543C1580003C068008304E000159 +:10A1E000000E18C0007578218DEC04003C070800B3 +:10A1F0008CE700443C040020ACCC00488DF40404FF +:10A20000240B0001ACD4004C10EB0260AEA4003073 +:10A21000963900523C0508008CA5004000B99021F9 +:10A22000A6320052963F005427ED0001A62D00549F +:10A230009626005430C4FFFF5487FF2F8FB40010C0 +:10A2400030A5FFFF0E0011F4A62000543C070800C3 +:10A250008CE70024963E00520047B82303D74823DA +:10A26000A62900520A0012198FB400108CE2004097 +:10A270000A0012BE00000000922400012407000121 +:10A280003085007F14A7001C97AD00268E2B00148C +:10A29000240CC000316A3FFF01AC48243C06080092 +:10A2A0008CC60060012A402531043FFF0086882BC0 +:10A2B00012200011A7A800263C0508008CA5005814 +:10A2C0008F9100A0000439802402FF8000B1182182 +:10A2D0000067F82103E2F02433F8007F3C1280008D +:10A2E0003C19800EAE5E002C0319702191D0000D38 +:10A2F000360F0004A1CF000D0E001028241200011B +:10A30000241100013C1E80008FC401000E000FCEFE +:10A3100002E028218FC401000E000FDE02C02821B8 +:10A320001620FF558F8B00A40A0012860013802B85 +:10A330008F8600A490C80001310400201080019194 +:10A34000241000013C048008348B0080916A007C5A +:10A350008F9E0034AFA0002C314900011120000F66 +:10A36000AFB000288CCD00148C8E006001AE602B45 +:10A370001580000201A038218C8700603C188008FD +:10A38000370300808C70007000F0782B15E000021D +:10A3900000E020218C640070AFA4002C3C028008F7 +:10A3A000344500808CD200148CBF0070025FC82B33 +:10A3B00017200002024020218CA400708FA7002CDF +:10A3C0000087182310600003AFA3003024050002AB +:10A3D000AFA500288FA400280264882B162000BA9D +:10A3E000000018218CD000388FCE000C3C0F00806C +:10A3F000AFD000008CCD00343C0CFF9F01CF58251E +:10A40000AFCD000490CA003F3586FFFF01662024CF +:10A410003C0900203C08FFEFA3CA000B0089382547 +:10A420003511FFFF00F118243C0500088F8700A4B8 +:10A430000065C825AFD9000C8CE20014AFC000182D +:10A440008FA60030AFC200148CF800188FB0002C1B +:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A +:10A4600003326824AFCF00248CEC000C020670216C +:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B +:10A48000AFCC0020AFC000288CEA00148FAB002CAA +:10A49000014B48230126402311000011AFC80010D2 +:10A4A00090EB003D8FC900048FC80000000B5100E5 +:10A4B000012A28210000102100AA882B010218215E +:10A4C0000071F821AFC50004AFDF000090F2003D3D +:10A4D000A3D2000A8F9900A497380006A7D80008D5 +:10A4E0008F910038240800023C038008A228000055 +:10A4F0003465008094BF005C8FA4002C33F0FFFF14 +:10A500000E000FF48F9200380002CB808F8500A4DC +:10A51000021978253C18420001F87025AE4E00045F +:10A520008F8400388CAD0038AC8D00188CAC0034B2 +:10A53000AC8C001CAC80000CAC800010A48000141B +:10A54000A4800016A4800020A4800022AC800024F7 +:10A5500090A6003F8FA7002CA486000250E0019235 +:10A56000240700018FA200305040000290A2003D5D +:10A5700090A2003E244A0001A08A00018F84003886 +:10A580008FA9002CAC8900083C128008364D008051 +:10A5900091AC007C3186000214C000022407003414 +:10A5A000240700308F8500A43C198008373F0080C5 +:10A5B00090B0000093F9007C240E0004A0900030BD +:10A5C0008F8F00A48FB8002C8F8D003891F200017E +:10A5D0003304000301C46023A1B200318F8E003820 +:10A5E0008F8600A42402C00095CA003294C90012CC +:10A5F0008FAB002C0142402431233FFF010388250B +:10A60000A5D1003291D000323185000300EBF82152 +:10A610003218003F370F0040A1CF00328FA4002C2A +:10A6200003E5382133280004108000028F850038AC +:10A6300000E838213C0A8008ACA700343549010005 +:10A640008D2800D08FA3002C2419FFBFACA80038A0 +:10A6500090B1003C2C640001240FFFDF3227007F03 +:10A66000A0A7003C8F98003800049140931F003C45 +:10A6700003F98024A310003C8F8C0038918E003C9D +:10A6800001CF682401B23025A186003C8F8900A447 +:10A690008F8800388D2B0020AD0B00408D220024C8 +:10A6A000AD0200448D2A0028AD0A00488D23002CFD +:10A6B0000E001013AD03004C8FB1002824070002D8 +:10A6C000122700118FA300280003282B00058023E8 +:10A6D0000270982400608021006090210A00126FAF +:10A6E0000010882B962900128F8400A00000902172 +:10A6F0003125FFFFA7A900180E000FC22411000189 +:10A700000A00131D3C1E80003C0B80003C12800898 +:10A710008D640100924900088F92FF340E000F995A +:10A720003125007F8F9900388FA700288FA4003033 +:10A73000A3270000965F005C33F0FFFF0E000FF4CC +:10A740008F91003800026B80020D80253C0842008A +:10A750008F8D00A402085025AE2A00048DA5003874 +:10A760008F8A003800007821000F1100AD450018D5 +:10A770008DB800343C047FFF3488FFFFAD58001CC7 +:10A7800091A6003E8D4C001C8D4900180006190052 +:10A79000000677020183C821004E58250323882B29 +:10A7A000012B382100F1F821AD59001CAD5F0018D4 +:10A7B000AD40000CAD40001091B0003E8FA40030C1 +:10A7C00024090005A550001495A500042419C00013 +:10A7D00000884024A545001691B8003EA5580020E9 +:10A7E00095AF0004A54F0022AD40002491AE003F7C +:10A7F000A54E000291A6003E91AC003D01861023BB +:10A80000244B0001A14B00018F9100388FA3003031 +:10A810003C028008344B0100AE230008A22900301E +:10A820008F8C00388F8700A4959F003294F000121F +:10A830002407FFBF033FC02432053FFF03057825EF +:10A84000A58F0032918E00322418FFDF31CD003FFA +:10A8500035A60040A18600328F910038240DFFFFFD +:10A86000240CFF80AE2000348D6A00D0AE2A003860 +:10A870009223003C3069007FA229003C8F90003871 +:10A880003C0380009219003C0327F824A21F003CDF +:10A890008F8E003891C5003C00B87824A1CF003CD1 +:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA +:10A8B000AD46004491420048004C5825A14B004849 +:10A8C0008F9000388F9900A48E09004801238824B6 +:10A8D00002283825AE070048933F003EA21F004CD7 +:10A8E0008F9800A48F8F003897050004A5E5004ECF +:10A8F0000E0003818DC500609246007C8FAC003055 +:10A9000000026940000291000040282130CB000283 +:10A9100001B21021156000AA018230213C0E80088E +:10A9200035C20080904C007C31830004106000032D +:10A930008FB900300005788000CF3021241F00043B +:10A940008F910038332D000303ED8023320800037C +:10A9500000C85021AE2A00343C188000A7C500383A +:10A960003C0680088F04010090DE00080E000FDE18 +:10A9700033C5007F0E001013000000000A00140D04 +:10A980008FA300288F9800348CC90038241F00033F +:10A99000A7000008AF0900008CC50034A300000A1E +:10A9A0008F9900A4AF0500043C080080932D003F60 +:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D +:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E +:10A9D00003D170243646FFFF01C61824AF03000CD4 +:10A9E0008F2C0014972900128F8400A0AF0C001048 +:10A9F0008F2F0014AF000018AF000020AF0F00141D +:10AA0000AF0000248F270018312F3FFF000F59801F +:10AA1000AF0700288F2500080164F821312D0001BF +:10AA2000AF0500308F31000C8F920038001F51C2EB +:10AA3000000D438001481021241E00023C068008BE +:10AA4000A702001CA7000034AF11002CA25E00007A +:10AA500034D20080964E005C8F9900383C0342004F +:10AA600031CCFFFF01833825AF2700048F8B00A472 +:10AA7000240500012402C0008D640038240700343E +:10AA8000AF2400188D690034AF29001CAF20000CE2 +:10AA9000AF200010A7200014A7200016A720002038 +:10AAA000A7200022AF200024A7300002A325000128 +:10AAB0008F8800388F9F00A4AD10000893ED000030 +:10AAC000A10D00308F8A00A48F98003891510001A9 +:10AAD000A31100318F8B0038957E003203C27024A1 +:10AAE00001CF6025A56C0032916300323064003FD5 +:10AAF000A16400329249007C3125000214A00002BA +:10AB00008F840038240700303C198008AC8700345B +:10AB1000373201008E5F00D0240AFFBF020090216F +:10AB2000AC9F0038908D003C31A8007FA088003C8D +:10AB30008F9E003893C2003C004A8824A3D1003C79 +:10AB40008F8300380010882B9066003C34CE0020A4 +:10AB5000A06E003C8F8400A48F9800388C8C00205D +:10AB6000AF0C00408C8F0024AF0F00448C8700286E +:10AB7000AF0700488C8B002CAF0B004C0E0010135D +:10AB80003C1E80000A0012700000000094C80052B1 +:10AB90003C0A08008D4A002401488821A4D10052B3 +:10ABA0000A0012198FB40010A08700018F840038AA +:10ABB000240B0001AC8B00080A0013BE3C12800875 +:10ABC000000520800A0014A200C4302127BDFFE048 +:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 +:10ABE000AFB1001435B200808E4C001835A80100BA +:10ABF000964B000695A70050910900FC000C5602E8 +:10AC0000016728233143007F312600FF240200031F +:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC +:10AC2000910600FC2412000530C200FF10520033D0 +:10AC300000000000160000098FBF001C8FB2001832 +:10AC40008FB100148FB00010240D0C003C0C80005C +:10AC500027BD002003E00008AD8D00240E0011FB8D +:10AC6000020020218FBF001C8FB200188FB100148A +:10AC70008FB00010240D0C003C0C800027BD00207C +:10AC800003E00008AD8D0024965800789651007AB4 +:10AC9000924E007D0238782631E8FFFF31C400C0B3 +:10ACA000148000092D11000116000037000000007B +:10ACB0005620FFE28FBF001C0E0010D100000000E4 +:10ACC0000A00156A8FBF001C1620FFDA0000000082 +:10ACD0000E0010D1000000001440FFD88FBF001CF0 +:10ACE0001600002200000000925F007D33E2003F6A +:10ACF000A242007D0A00156A8FBF001C950900EA78 +:10AD00008F86008000802821240400050E0007257E +:10AD10003130FFFF978300923C0480002465FFFFE1 +:10AD2000A78500928C8A01B80540FFFE0000000054 +:10AD3000AC8001808FBF001CAC9001848FB20018E2 +:10AD40008FB100148FB000103C0760133C0B100053 +:10AD5000240D0C003C0C800027BD0020AC8701882E +:10AD6000AC8B01B803E00008AD8D00240E0011FB90 +:10AD7000020020215040FFB18FBF001C925F007D78 +:10AD80000A00159733E2003F0E0011FB020020215C +:10AD90001440FFAA8FBF001C122000070000000013 +:10ADA0009259007D3330003F36020040A242007DC0 +:10ADB0000A00156A8FBF001C0E0010D100000000B1 +:10ADC0005040FF9E8FBF001C9259007D3330003FE2 +:08ADD0000A0015C6360200401E +:08ADD800000000000000001B58 +:10ADE0000000000F0000000A00000008000000063C +:10ADF0000000000500000005000000040000000441 +:10AE00000000000300000003000000030000000336 +:10AE10000000000300000002000000020000000229 +:10AE2000000000020000000200000002000000021A +:10AE3000000000020000000200000002000000020A +:10AE400000000002000000020000000200000002FA +:0CAE5000000000010000000100000001F3 +:04AE5C008008010069 +:10AE6000800800808008000000000C000000308096 +:10AE7000080011D00800127C08001294080012A8E3 +:10AE8000080012BC080011D0080011D0080012F010 +:10AE90000800132C080013400800138808001A8CBF +:10AEA00008001A8C08001AC408001AC408001AD82E +:10AEB00008001AA808001D0008001CCC08001D5836 +:10AEC00008001D5808001DE008001D108008024001 +:10AED000080027340800256C0800275C080027F4C8 +:10AEE0000800293C0800298808002AAC080029B479 +:10AEF00008002A38080025DC08002EDC08002EA4F3 +:10AF000008002588080025880800258808002B20CF +:10AF100008002B20080025880800258808002DD06F +:10AF2000080025880800258808002588080025884D +:10AF300008002E0C080025880800258808002588B0 +:10AF4000080025880800258808002588080025882D +:10AF5000080025880800258808002588080025881D +:10AF6000080025880800258808002588080029A8E9 +:10AF7000080025880800258808002E680800258814 +:10AF800008002588080025880800258808002588ED +:10AF900008002588080025880800258808002588DD +:10AFA00008002588080025880800258808002588CD +:10AFB00008002588080025880800258808002588BD +:10AFC00008002CF4080025880800258808002C6853 +:10AFD00008002BC408003CE408003CB808003C848E +:10AFE00008003C5808003C3808003BEC8008010091 +:10AFF00080080080800800008008008008004C6401 +:10B0000008004C9C08004BE408004C6408004C64A9 +:0CB01000080049B808004C6408005050CB +:04B01C000A000C8496 +:10B0200000000000000000000000000D7278703683 +:10B030002E302E3137000000060011030000000002 +:10B0400000000001000000000000000000000000FF +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000809F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E220000000000A000000000000000000000000E4 +:10E2300010000003000000000000000D0000000DB1 +:10E240003C020801244294003C03080124639634F4 +:10E25000AC4000000043202B1480FFFD244200044A +:10E260003C1D080037BD9FFC03A0F0213C100800B6 +:10E27000261032103C1C0801279C94000E001274DA +:10E28000000000000000000D3C02800030A5FFFFF0 +:10E2900030C600FF344301803C0880008D0901B87E +:10E2A0000520FFFE00000000AC6400002404000212 +:10E2B000A4650008A066000AA064000BAC67001803 +:10E2C0003C03100003E00008AD0301B83C0560000A +:10E2D0008CA24FF80440FFFE00000000ACA44FC029 +:10E2E0003C0310003C040200ACA44FC403E000084F +:10E2F000ACA34FF89486000C00A050212488001491 +:10E3000000062B0200051080004448210109182B4B +:10E310001060001100000000910300002C6400094F +:10E320005080000991190001000360803C0D080134 +:10E3300025AD9090018D58218D67000000E0000808 +:10E340000000000091190001011940210109302B42 +:10E3500054C0FFF29103000003E000080000102108 +:10E360000A000CCC25080001910F0001240E000AC0 +:10E3700015EE00400128C8232F38000A1700003D81 +:10E38000250D00028D580000250F0006370E0100F4 +:10E39000AD4E0000910C000291AB000191A400026F +:10E3A00091A60003000C2E00000B3C0000A71025D6 +:10E3B00000041A000043C8250326C025AD580004F8 +:10E3C000910E000691ED000191E7000291E5000336 +:10E3D000000E5E00000D6400016C30250007220075 +:10E3E00000C41025004518252508000A0A000CCC99 +:10E3F000AD430008910F000125040002240800022B +:10E4000055E80001012020210A000CCC00804021A9 +:10E41000910C0001240B0003158B00160000000076 +:10E420008D580000910E000225080003370D0008EA +:10E43000A14E00100A000CCCAD4D00009119000156 +:10E44000240F0004172F000B0000000091070002AA +:10E45000910400038D43000000072A0000A410254A +:10E460003466000425080004AD42000C0A000CCC00 +:10E47000AD46000003E000082402000127BDFFE8CC +:10E48000AFBF0014AFB000100E0015E50080802172 +:10E490003C0480083485008090A600052403FFFE1C +:10E4A0000200202100C310248FBF00148FB0001081 +:10E4B000A0A200050A0015EF27BD001827BDFFE840 +:10E4C000AFB00010AFBF00140E000FD40080802149 +:10E4D0003C06800834C5008090A40000240200504F +:10E4E000308300FF106200073C09800002002021F9 +:10E4F0008FBF00148FB00010AD2001800A0010A65D +:10E5000027BD0018240801003C07800002002021DC +:10E510008FBF00148FB00010ACE801800A0010A675 +:10E5200027BD001827BDFF783C058008AFBE0080DE +:10E53000AFB7007CAFB3006CAFB10064AFBF008475 +:10E54000AFB60078AFB50074AFB40070AFB200687A +:10E55000AFB0006034A600803C0580008CB201287A +:10E5600090C400098CA701043C020001309100FF17 +:10E5700000E218240000B8210000F021106000071C +:10E58000000098213C0908008D2931F02413000176 +:10E59000252800013C010800AC2831F0ACA0008423 +:10E5A00090CC0005000C5827316A0001154000721C +:10E5B000AFA0005090CD00002406002031A400FF41 +:10E5C00010860018240E0050108E009300000000EA +:10E5D0003C1008008E1000DC260F00013C010800F2 +:10E5E000AC2F00DC0E00165E000000000040182179 +:10E5F0008FBF00848FBE00808FB7007C8FB60078FD +:10E600008FB500748FB400708FB3006C8FB2006848 +:10E610008FB100648FB000600060102103E000083B +:10E6200027BD00880000000D3C1F8000AFA0003017 +:10E6300097E501168FE201043C04002030B9FFFF8A +:10E64000004438240007182B00033140AFA60030E7 +:10E650008FF5010437F80C003C1600400338802188 +:10E6600002B6A02434C40040128000479215000D69 +:10E6700032A800201500000234860080008030217E +:10E6800014C0009FAFA600303C0D800835A6008066 +:10E6900090CC0008318B0040516000063C06800899 +:10E6A000240E0004122E00A8240F0012122F003294 +:10E6B0003C06800834C401003C0280009447011AE3 +:10E6C0009619000E909F00088E18000830E3FFFF97 +:10E6D00003F9B00432B40004AFB6005CAFA3005835 +:10E6E0008E1600041280002EAFB8005434C3008090 +:10E6F000906800083105004014A0002500000000CB +:10E700008C70005002D090230640000500000000ED +:10E710008C71003402D1A82306A201678EE20008A2 +:10E72000126000063C1280003C1508008EB531F4E2 +:10E7300026B600013C010800AC3631F4AE4000447E +:10E74000240300018FBF00848FBE00808FB7007C40 +:10E750008FB600788FB500748FB400708FB3006CE3 +:10E760008FB200688FB100648FB00060006010212C +:10E7700003E0000827BD00880E000D2800002021BE +:10E780000A000D75004018210A000D9500C02021D7 +:10E790000E0016AE02C020211440FFE10000000070 +:10E7A0003C0B8008356400808C8A003402CA482300 +:10E7B0000520001D000000003C1E08008FDE310017 +:10E7C00027D700013C010800AC3731001260000679 +:10E7D000024020213C1408008E9431F42690000160 +:10E7E0003C010800AC3031F40E0015E53C1E8008F9 +:10E7F00037CD008091B700250240202136EE00047D +:10E800000E0015EFA1AE00250E000CAC0240202139 +:10E810000A000DCA240300013C17080126F794F8EA +:10E820000A000D843C1F80008C86003002C66023E5 +:10E830001980000C2419000C908F004F3C14080024 +:10E840008E94310032B500FC35ED0001268E0001BA +:10E850003C010800AC2E3100A08D004FAFA0005845 +:10E860002419000CAFB900308C9800300316A02397 +:10E870001A80010B8FA300580074F82A17E0FFD309 +:10E88000000000001074002A8FA5005802D4B021A7 +:10E8900000B410233044FFFFAFA4005832A8000298 +:10E8A0001100002E32AB00103C15800836B00080FD +:10E8B0009216000832D30040526000FB8EE200083E +:10E8C0000E0015E502402021240A0018A20A0009C2 +:10E8D000921100052409FFFE024020210229902404 +:10E8E0000E0015EFA21200052404003900002821B3 +:10E8F0000E001689240600180A000DCA2403000120 +:10E9000092FE000C3C0A800835490080001EBB00C6 +:10E910008D27003836F10081024020213225F08118 +:10E920000E000C9B30C600FF0A000DC10000000065 +:10E930003AA7000130E300011460FFA402D4B02123 +:10E940000A000E1D00000000024020210E0016CB20 +:10E95000020028210A000D75004018211160FF7087 +:10E960003C0F80083C0D800835EE00808DC40038D7 +:10E970008FA300548DA60004006660231D80FF68ED +:10E98000000000000064C02307020001AFA400548F +:10E990003C1F08008FFF31E433F9000113200015FC +:10E9A0008FAC00583C07800094E3011A10600012FD +:10E9B0003C0680080E0020F8024020213C0308019C +:10E9C0009063952930640002148001450000000026 +:10E9D000306C0004118000078FAC0058306600FBDB +:10E9E0003C010801A026952932B500FCAFA00058D3 +:10E9F0008FAC00583C06800834D30080AFB40018B8 +:10EA0000AFB60010AFAC00143C088000950B01209D +:10EA10008E6F0030966A005C8FA3005C8FBF003061 +:10EA20003169FFFF3144FFFF8FAE005401341021E4 +:10EA3000350540000064382B0045C82103E7C02598 +:10EA4000AFB90020AFAF0028AFB80030AFAF00249F +:10EA5000AFA0002CAFAE0034926D000831B40008B6 +:10EA6000168000BB020020218EE200040040F8095D +:10EA700027A400108FAF003031F300025660000170 +:10EA800032B500FE3C048008349F008093F90008F2 +:10EA900033380040530000138FA400248C850004F9 +:10EAA0008FA7005410A700D52404001432B0000131 +:10EAB0001200000C8FA400242414000C1234011A3C +:10EAC0002A2D000D11A001022413000E240E000AAD +:10EAD000522E0001241E00088FAF002425E40001FF +:10EAE000AFA400248FAA00143C0B80083565008079 +:10EAF000008A48218CB10030ACA9003090A4004EAF +:10EB00008CA700303408FFFC0088180400E3F821CB +:10EB1000ACBF00348FA600308FB900548FB8005CB2 +:10EB200030C200081040000B033898218CAC002044 +:10EB3000119300D330C600FF92EE000C8FA7003473 +:10EB400002402021000E6B0035B400800E000C9BAB +:10EB50003285F0803C028008345000808E0F0030F7 +:10EB600001F1302318C00097264800803C070800B8 +:10EB70008CE731E42404FF80010418243118007F5D +:10EB80003C1F80003C19800430F10001AFE300908D +:10EB900012200006031928213C03080190639529DF +:10EBA00030690008152000C6306A00F73C10800864 +:10EBB00036040080908C004F318B000115600042BC +:10EBC000000000003C0608008CC6319830CE0010D2 +:10EBD00051C0004230F9000190AF006B55E0003F9A +:10EBE00030F9000124180001A0B8006B3C1180002E +:10EBF0009622007A24470064A48700123C0D800806 +:10EC000035A5008090B40008329000401600000442 +:10EC10003C03800832AE000115C0008B00000000EC +:10EC2000346400808C86002010D3000A3463010015 +:10EC30008C67000002C7782319E000978FBF00544B +:10EC4000AC93002024130001AC760000AFB3005059 +:10EC5000AC7F000417C0004E000000008FA90050D8 +:10EC60001520000B000000003C030801906395296B +:10EC7000306A00011140002E8FAB0058306400FE56 +:10EC80003C010801A02495290A000D7500001821F7 +:10EC90000E000CAC024020210A000F1300000000FF +:10ECA0000A000E200000A0210040F80924040017EB +:10ECB0000A000DCA240300010040F80924040016CC +:10ECC0000A000DCA240300019094004F240DFFFE9A +:10ECD000028D2824A085004F30F900011320000682 +:10ECE0003C0480083C03080190639529307F0010A4 +:10ECF00017E00051306800EF34900080240A0001D2 +:10ED0000024020210E0015E5A60A001292030025FC +:10ED100024090001AFA90050346200010240202103 +:10ED20000E0015EFA20200250A000EF93C0D800826 +:10ED30001160FE83000018218FA5003030AC000464 +:10ED40001180FE2C8FBF00840A000DCB240300012C +:10ED500027A500380E000CB6AFA000385440FF4382 +:10ED60008EE200048FB40038329001005200FF3F61 +:10ED70008EE200048FA3003C8E6E0058006E682364 +:10ED800005A3FF39AE6300580A000E948EE200041A +:10ED90000E0015E5024020213C0380083468008005 +:10EDA000024020210E0015EFA11E000903C03021F2 +:10EDB000240400370E001689000028210A000F11D4 +:10EDC0008FA900508FAB00185960FF8D3C0D800853 +:10EDD0000E0015E502402021920C002524050001BB +:10EDE000AFA5005035820004024020210E0015EF2F +:10EDF000A20200250A000EF93C0D800812240059D9 +:10EE00002A2300151060004D240900162408000C68 +:10EE10005628FF2732B000013C0A8008914C001BA5 +:10EE20002406FFBD241E000E01865824A14B001BA2 +:10EE30000A000EA532B000013C010801A028952966 +:10EE40000A000EF93C0D80088CB500308EFE0008DB +:10EE50002404001826B6000103C0F809ACB600303F +:10EE60003C030801906395293077000116E0FF818B +:10EE7000306A00018FB200300A000D753243000481 +:10EE80003C1080009605011A50A0FF2B34C60010DC +:10EE90000A000EC892EE000C8C6200001456FF6D42 +:10EEA000000000008C7800048FB9005403388823D8 +:10EEB0000621FF638FBF00540A000F0E0000000000 +:10EEC0003C010801A02A95290A000F3030F9000101 +:10EED0001633FF028FAF00240A000EB0241E00106C +:10EEE0000E0015E5024020213C0B800835680080AB +:10EEF00091090025240A0001AFAA0050353300040F +:10EF0000024020210E0015EFA11300253C05080149 +:10EF100090A5952930A200FD3C010801A022952969 +:10EF20000A000E6D004018212411000E53D1FEEA94 +:10EF3000241E00100A000EAF241E00165629FEDC07 +:10EF400032B000013C0A8008914C001B2406FFBD32 +:10EF5000241E001001865824A14B001B0A000EA598 +:10EF600032B000010A000EA4241E00123C038000EF +:10EF70008C6201B80440FFFE24040800AC6401B8B0 +:10EF800003E00008000000000080502130A5FFFFD2 +:10EF900030C6FFFF3C0480008C8201B80440FFFEB5 +:10EFA00034880180AD0A00003C078008AC8A00204C +:10EFB00094E300483067FFFF10E000423C0D800002 +:10EFC00024AB001200EB482B5120003F2404000327 +:10EFD00034820100945900208F8900002404001A13 +:10EFE0003338FFFF270BFFFE00EB782B39EE0001D3 +:10EFF00000096B8201AE6024A104000B518000491E +:10F000008F8B00048F830004A50B0014346800016B +:10F01000AF88000430CE004015C000333C048000AF +:10F020003C02800034420180A445000E3C07800071 +:10F0300034EC0180A585001A8F85000C310B80000F +:10F04000A5890010AD850028A58600081160000F75 +:10F050008F85001434EA0100954E001631CDFFFC77 +:10F0600025A40004008718218C67400030E6FFFFCC +:10F0700014C000073C0480003C18FFFF370F7FFFDF +:10F08000010F4024AF8800048F8500143C048000E9 +:10F090002402BFFF348301800102C824A479002622 +:10F0A00010A00004AC69002C00054402A465001007 +:10F0B000A46800263C091000AC8901B803E00008F0 +:10F0C000000000002404000335AC018030CE004075 +:10F0D0008F8900008F880004A184000B51C0FFD1EC +:10F0E0003C0280003C048000AC8A00203C0F800879 +:10F0F00095EA00403143FFFF5060000834820180F0 +:10F1000000A3C02B5700000100A0182134990180F2 +:10F11000A723000E0A0010053C0780000A00100318 +:10F1200030C6FFBF2407FFFE016740240A000FFE20 +:10F13000AF88000427BDFFE88FA2002830A5FFFF9D +:10F1400030C6FFFFAFBF0010AF87000CAF820014C6 +:10F15000AF8000040E000FDBAF8000008FBF0010F7 +:10F1600027BD001803E00008AF8000143C068000B3 +:10F1700034C4007034C701008C8A000090E500128E +:10F180008F84000027BDFFF030A300FF000318822A +:10F190003082400010400037246500030005C8801D +:10F1A0000326C0218F0E4000246F0004000F6880EA +:10F1B000AFAE000001A660218D8B4000AFAB000414 +:10F1C00094E900163128FFFC010638218CE6400046 +:10F1D000AFA600088FA900080000302100002821F8 +:10F1E0003C07080024E701000A00107E24080008FC +:10F1F0009059000024A500012CAC000C0079C0211E +:10F200000018788001E770218DCD00001180000684 +:10F2100000CD302603A5102114A8FFF500051A0023 +:10F220005520FFF4905900003C04800034870070A2 +:10F230003C0508008CA531048CE300002CA20020C2 +:10F2400010400009006A3823000548803C0B080084 +:10F25000256B3108012B402124AA0001AD070000D5 +:10F260003C010800AC2A310400C0102103E0000872 +:10F2700027BD0010308220001040000B0005588090 +:10F28000016648218D24400024680004000838806D +:10F29000AFA4000000E618218C654000AFA0000874 +:10F2A0000A00106EAFA500040000000D0A00106FE8 +:10F2B0008FA9000827BDFFD83C058000AFB100141E +:10F2C000AFB00010AFBF0024AFB40020AFB3001C3C +:10F2D000AFB200188F87000034A401009483000EA1 +:10F2E00030E2400000008021104000103071FFFF2C +:10F2F0003C08002000E8302410C0000D30EB8000F6 +:10F300008F890004240ABFFF00EA38243523100047 +:10F31000AF87000030F320001660000B3C1800049B +:10F320002419FFBF0A0010CF0079102430EB8000B1 +:10F330001560004D3C0D002030F320001260FFF8F6 +:10F340008F8300043C18000400F8A0241280FFF50D +:10F350002419FFBF3462004030FF010013E00010A9 +:10F36000AF8200048F820028104000063C0E80000F +:10F370003C04002000E41824146000CE3C06000485 +:10F380003C0E800035CD010095AC001E95AB001CF5 +:10F390003189FFFF000B5400012A4025AF88000C83 +:10F3A0003C138000367401009692000C8E6340007E +:10F3B000340FFFFF106F00843244FFFF30780100EC +:10F3C000570000012410001030F9100053200008ED +:10F3D0003612000130FF002017E000733C031000DC +:10F3E00000E310241440006A3C0A0C0036120001AD +:10F3F00030EC01001580000B3C0600018F880004F2 +:10F40000310D400015A0000800E628243C131F0120 +:10F4100000F378243C0E100011EE00AE3094020090 +:10F420003C06000100E6282410A000193C19100039 +:10F430003C0408008C84002430940002168000D91B +:10F44000240300018FBF00248FB400208FB3001C61 +:10F450008FB200188FB100148FB00010006010211F +:10F4600003E0000827BD002800ED60241180FFB3F1 +:10F4700030F320008F8E00043C12FFFF364F7FFFD9 +:10F4800000EF382435C380000A0010BEAF870000AB +:10F4900000F9C0241700004E00002021AF800010AA +:10F4A0003C0380003465010094AE000E8F91001083 +:10F4B00031CAFFFF108000C62553000430EF010061 +:10F4C00015E000703C180F003A2800022E7003EF80 +:10F4D0002D1900013A1F0001033F282414A0002227 +:10F4E000240400013C0308008C6300D02E25000C8E +:10F4F000001121C0386C00012D8B00010165102422 +:10F50000144000143270FFFF262DFFFC2DA40004D0 +:10F510001480010300002021386A00022D460001FA +:10F5200000C51824546000FF02002821262FFFF890 +:10F530002DEE000415C00007000000000007A242E5 +:10F540000011C02B0298482415200109020028212F +:10F55000001121C002002821364600020E000FDBF8 +:10F560000000000000002021008018218FBF00242F +:10F570008FB400208FB3001C8FB200188FB100141D +:10F580008FB000100060102103E0000827BD0028A4 +:10F590003C090BFF00EA40243526FFFF00C8282B5A +:10F5A00050A0FF93361200013C0B08008D6B002C1D +:10F5B00036120005257000013C010800AC30002C1B +:10F5C0000A0010F630EC01000A0010EB24100020B5 +:10F5D00000071602305F000F001F80C03C030801C7 +:10F5E00024639478020320211080FFADAF9F0010A8 +:10F5F000908800005100FFAB3C0380003C0D800070 +:10F6000035A90100952C000E240B00030240302187 +:10F61000318AFFFF25450004110B00D9000050215D +:10F620009088000124140002311100FF123400BF41 +:10F6300030F80040310300FF24080001106800C8C2 +:10F6400030E200408C8A00048F8B00245560000655 +:10F6500034C60002254DFE002DAC0381558000010B +:10F660003646004034C600020140202130A5FFFF8D +:10F670000E000FDB30C6FFFF000040210A00110A18 +:10F680000100182100F8A0243C0902001289FF8F14 +:10F690003A28000290B100133270FFFF02002821C7 +:10F6A000322700FF24F30004001321C00A00115088 +:10F6B0003646000200E6282414A0FF323C0E8000EB +:10F6C0000E0010543C1380008F8700000A0010E2E7 +:10F6D000AF82000C1680FF533C0600012624000474 +:10F6E0003085FFFF364600023C0380008C7101B874 +:10F6F0000620FFFE8F890008346A0180AD400000BB +:10F70000112000B23C0D800024B800120138902B6B +:10F71000124000AF240C0003347001009603002057 +:10F720002402001A30F94000307FFFFFA142000B95 +:10F73000132000AB27E3FFFE0123582B156000A91F +:10F740002409FFFE35080001A5430014AF8800041A +:10F750003C0E80002413BFFF0113782435C80180BC +:10F76000A505000EA505001AA5060008A50F002690 +:10F77000A50700103C071000ADC701B80000182114 +:10F780008FBF00248FB400208FB3001C8FB20018ED +:10F790008FB100148FB000100060102103E000084A +:10F7A00027BD00283C1208008E5200D802202821D4 +:10F7B00024040080265100013C010800AC3100D82F +:10F7C0000E000FDB240600030A0011D900001821E7 +:10F7D0008C65400030B1010012200046325900040F +:10F7E0003C1F08008FFF002424140004172000028F +:10F7F00033F0000D2414000200076AC239A400018E +:10F800002E6C03EF30820001398B0001004B402544 +:10F81000110000033251FFFB2412FFFB021280246F +:10F8200030E3010050600015321F00013C0A0F0058 +:10F8300000EA30243C07020010C7000F3C1980008A +:10F840003725010090A900132418FFFE0218802418 +:10F85000312F00FF25EE0004000E21C0120000022F +:10F86000023430253226FFFF0E000FDB3265FFFF2A +:10F870001200FF3D00002021321F000113E0000DA7 +:10F88000320B000424080001120800020234302563 +:10F890003226FFFF000020210E000FDB3265FFFF44 +:10F8A0002402FFFE020280241200FF2F000020210C +:10F8B000320B00045160000D240400010234302595 +:10F8C00024140004561400013226FFFF2411FFFB0C +:10F8D0003265FFFF240401000E000FDB02119824A3 +:10F8E0001260FF2100002021240400010A001154AD +:10F8F000008018213C0C08008D8C00243190000100 +:10F900005200FF19000020213265FFFF3646000239 +:10F910000E000FDB000020210A00115300002021FF +:10F92000020028210A00115036460002130000068A +:10F930000000000095300010949F000232190FFF64 +:10F9400013F9FF3D310300FF3C04080190849479D2 +:10F950001080FF3D240800010A00110A010018214F +:10F960005040FF398C8A00040A00124B000000004E +:10F970000E000FDB3246FFFB0A00114E001121C0C2 +:10F9800090830001240E0001106EFF3C240800014A +:10F99000240F0002106F000430F30040240800011F +:10F9A0000A00110A010018215260FFFD240800011D +:10F9B000952500109487000230A9FFFF50E9FEA1B1 +:10F9C000010018210A00126124080001240C000320 +:10F9D00035AA0180A14C000B0A0011CE3C0E80001C +:10F9E0002409FFFE0A0011CC0109402427BDFFC0F5 +:10F9F000AFB00018AFBF003C3C10600CAFBE003889 +:10FA0000AFB70034AFB60030AFB5002CAFB40028AC +:10FA1000AFB30024AFB20020AFB1001C8E0E500077 +:10FA2000240FFF7F3C06800001CF682435AC380CE2 +:10FA3000240B0003AE0C5000ACCB00083C010800C6 +:10FA4000AC2000200E0017B0000000003C0A00109F +:10FA5000354980513C066016AE09537C8CC70000C6 +:10FA60003C0860148D0500A03C03FFFF00E3202448 +:10FA70003C02535300051FC21082029B34C57C0018 +:10FA80008CBF007C8CA200783C1E600037C4202014 +:10FA90003C05080124A590C0AF820018AF9F001C50 +:10FAA0000E0016742406000A3C19000127399478C8 +:10FAB0003C010800AC3931DC0E00206BAF80001433 +:10FAC0008FD708082418FFF03C15570902F8B02416 +:10FAD00012D5028B24040001AF8000283C14800062 +:10FAE0003697010002E0F0218E90000032050003FD +:10FAF00010A0FFFD3207000114E0005D3206000295 +:10FB000010C0FFF93C07800034E501408CB90000CB +:10FB100024100040ACF9002090B8000833030070B6 +:10FB20001070010B286900411120000824080060B2 +:10FB3000241F0020107F000E3C0B40003C0680007C +:10FB4000ACCB01780A0012B3000000001468FFFB80 +:10FB50003C0B40000E001F88000000003C0B4000E2 +:10FB60003C068000ACCB01780A0012B30000000014 +:10FB700090AB0009241100048CA70000316800FF3D +:10FB80001111015D2512FFFA2E53000612600016B6 +:10FB90003C0680008CAA00048F86002494A3000AEF +:10FBA000000A3E02310500FF10C000053064FFFF6F +:10FBB0002CEC00081580000224E700042407000351 +:10FBC000240E000910AE01A128AF000A11E0018443 +:10FBD0002410000A2404000810A4001A000749C0D9 +:10FBE000012038213C0680008CD001B80600FFFEC1 +:10FBF00034C40180AC87000034C5014090B60008D1 +:10FC0000241900023C0B400032C200FF00028A00AF +:10FC10000228F825A49F0008A099000B94A7000AC9 +:10FC20003C081000A48700108CB80004AC98002495 +:10FC3000ACC801B83C068000ACCB01780A0012B316 +:10FC400000000000000AC202330300FF2405000187 +:10FC50005465FFE4012038218F990020AF830024F0 +:10FC600027270001AF8700200A0012F20120382167 +:10FC70008FD100283C0B8008AE9100208FC6000475 +:10FC80008FCA000095690048AF860000AF8A000463 +:10FC90003128FFFF0E000FD4AF8800083C03080096 +:10FCA0008C6300C0106000258F8700003C0E0800A8 +:10FCB0008DCE00C425CD00013C010800AC2D00C450 +:10FCC0003C1F800037E901008D3900243C0760208B +:10FCD000ACF90014000000003C0680003C08400025 +:10FCE000ACC80138000000005220FF853206000237 +:10FCF000262D0140262E00802404FF8001A4282404 +:10FD000001C47824000F194031CC007F00059940D0 +:10FD100031B2007F3C15200036A20002006C502555 +:10FD20000272B02502C2882501425825ACCB0830AA +:10FD3000ACD108300A0012B9320600023C120010A1 +:10FD400000F2782415E000708F8300043C1808004E +:10FD50008F18002097D6000E30F5400027130001C1 +:10FD60003C010800AC3300200000902112A000816B +:10FD700032D3FFFF3C1F002000FFC8241320007E69 +:10FD800030E580008F8200042404BFFF00E43824A3 +:10FD900034431000AF87000030EB20001160007387 +:10FDA000240EFFBF3C0D000400ED60241180000212 +:10FDB000006E10243462004030EF010011E00010AA +:10FDC000AF8200048F95002812A000073C18002085 +:10FDD00000F8B02412C000043C1F000400FFC82437 +:10FDE0001320016D0000000096E3001E96E8001C41 +:10FDF0003065FFFF0008140000A22025AF84000C2E +:10FE000096EA000C8E8440003409FFFF10890085BB +:10FE10003145FFFF3086010054C00001241200105C +:10FE200030EB1000116000133656000130EC00205A +:10FE30001580000A3C0E100000EE682411A0000D91 +:10FE40003C190C003C180BFF00F9B0243715FFFFDC +:10FE500002B6782B11E00007365600013C1F08005F +:10FE60008FFF002C3656000527F200013C010800E8 +:10FE7000AC32002C30E401001480000B3C06000181 +:10FE80008F880004310240005440000800E6282416 +:10FE90003C0A1F0100EA48243C0310001123010919 +:10FEA00030A602003C06000100E6282410A0003E17 +:10FEB0003C1810003C0D08008DAD002431AC000250 +:10FEC0001580000624030001006010211040FF830C +:10FED0003C0680000A00132A3C1F80003C0F0800EB +:10FEE0008DEF00D8026028212404008025EE000157 +:10FEF0003C010800AC2E00D80E000FDB24060003E6 +:10FF00000A0013AB000018212405BFFF0065682418 +:10FF100011A00007240F87FF006F702415C0000890 +:10FF20003C18006000F8202410800005000000004C +:10FF30000E000D42000000000A0013AC000000009B +:10FF40000E00159C000000000A0013AC0000000029 +:10FF50000E0015F4000000003C0B40003C06800041 +:10FF6000ACCB01780A0012B3000000000A0013674E +:10FF7000006E102430E5800010A0FF878F830004FE +:10FF80003C08002000E818245060FF838F830004A1 +:10FF90008F8900043C06FFFF34CA7FFF00EA382443 +:10FFA0000A00135E3523800000F8A82416A0001F65 +:10FFB00000004021AF8000103C0380003464010049 +:10FFC0009486000E8F93001030C5FFFF1100014E84 +:10FFD00024B5000430EA0100114000553A7F0002C8 +:10FFE0003C0E0F0000EE68243C0C020011AC0051E6 +:10FFF0002EB203EF908F001332B2FFFF31E400FF07 +:020000040001F9 +:1000000024870004000721C00240282136C60002D0 +:100010000E000FDB00000000000020210A0013ABDF +:10002000008018210A0013812412002000072602F4 +:100030003099000F0019F8C03C120801265294783C +:1000400003F240211100FFDCAF990010910900007C +:100050001120FFDA3C0380003C138000366A010067 +:10006000954B000E2403000302C030213162FFFFD4 +:1000700024450004112300EC000020219109000117 +:10008000240D0002312E00FF11CD00FA313200FFA5 +:10009000240900011249001030FF00408D040004C3 +:1000A0008F8300241460000634D30002248BFE00EA +:1000B0002D6203815440000136C6004034D3000253 +:1000C00030A5FFFF0E000FDB3266FFFF0000482166 +:1000D0000A0013AB0120182153E0FFF18D04000446 +:1000E0003C080801910894791100FFED24090001F2 +:1000F0000A0013AB012018213C0480008C8A01B84F +:100100000540FFFE349601802415001CAEC7000098 +:10011000A2D5000B3C021000AC8201B83C0B4000A1 +:100120003C068000ACCB01780A0012B3000000004E +:100130002EB203EF2FF900013A4900010329C02430 +:100140001700FFB6240400013C0308008C6300D0B4 +:100150002E65000C001321C0386B00012D620001D8 +:10016000004540241500FFA832B2FFFF266AFFFCBD +:100170002D46000414C0001300002021386D000239 +:100180002DAC0001018518241460000F02402821C5 +:10019000266EFFF82DC5000414A0FF9B0000000090 +:1001A00000077A420013382B01E7A82456A0000864 +:1001B00002402821001321C0024028210A0013FD1B +:1001C00036C60002024028210A0013FD36C600028E +:1001D0000E000FDB32C6FFFB0A001467001321C0BC +:1001E00010B0007200045A022406000B14A6FE7C14 +:1001F000000749C0314600FF00065600000A5E03B2 +:10020000056200B030C6007F000670C03C0F0801D8 +:1002100025EF947801CFA821A2A00001A2A00000A0 +:100220003C1360008E631820240D000100CD4804AB +:1002300000096027000749C0006C90240120382184 +:10024000AE7218200A0012F2A6A0000214C0004BE1 +:100250008F8C0020000749C03C0B8000AD69002056 +:100260003C118008963F004013E000022405000185 +:10027000240500413C0480008C8A01B80540FFFE43 +:100280003496018024120003AEC90000A2D2000BF4 +:10029000A6C0000EA6C0001AA6C00010AEC000285E +:1002A000A6C5000896D3002636750001A6D50026FF +:1002B000AEC0002C3C021000AC8201B80A0012F261 +:1002C0000120382114C0FEF83C060001266B000412 +:1002D0003165FFFF36C600023C0380008C7301B815 +:1002E0000660FFFE8F8900083C0D800035AC018060 +:1002F000AD800000512000DD3C09800024AF0012D9 +:10030000012F702B51C000D93C09800096F20020CB +:100310003C1980002418001A3256FFFF372A01804A +:1003200030F54000A158000B12A000D526C3FFFEF7 +:100330000123F82B17E000D32404FFFE3508000149 +:10034000A5430014AF8800042413BFFF3C0B8000BA +:100350000113502435680180A505000EA505001A7B +:10036000A5060008A50A0026A50700103C071000F6 +:10037000AE8701B80A0013AB00001821000749C07E +:100380002583FFFF1460FE16AF8300200120382173 +:100390000A0012F2AF8000240E001054000000008A +:1003A0008F8700000A001379AF82000C240300FF3E +:1003B0001163FE0B000749C010C00038000B760027 +:1003C000000B20C03C0908012529947800891821D8 +:1003D00024020001A06200003C16080126D6947891 +:1003E0003C0208012442947C00962821000749C061 +:1003F00000828821000AFC02AE290000A0BF000193 +:100400003C0460008C9818202419000101793804FC +:100410000307302501203821A4AA0002AC86182049 +:100420000A0012F33C06800091030001241600012B +:100430001076FF272409000124050002106500043E +:1004400030E60040240900010A0013AB0120182106 +:1004500050C0FFFD24090001954C0010950A0002D0 +:100460003187FFFF5147FE98012018210A00150B24 +:100470002409000130EF004011E0FF1900000000E6 +:10048000955900109518000233350FFF1715FF140A +:10049000313200FF0A00141E24090001000E6E0311 +:1004A00005A2000F316B007F10E30008000B20C095 +:1004B0003C10080126109478009018210A0014EED0 +:1004C000240200020A00147BAF8000203C0F0801C8 +:1004D00025EF9478008F18210A0014EE24020003FF +:1004E0000A001523AF8B00200003A080028698210C +:1004F0008E7200043C1160000A00129902512821FA +:100500000A0012B0AF8400288C64400030930100D0 +:100510001260004B240900043C1908008F390024A4 +:1005200032D80004AFA90010170000033332000DC9 +:10053000241F0002AFBF001000071AC2386A000172 +:100540002EA603EF3142000138CB0001004B4025BD +:100550001100000332D3FFFB2416FFFB0256902448 +:1005600030EC010011800016324800013C0E0F00F3 +:1005700000EE28243C0D020010AD00113C1F80004D +:1005800037E90100913800138FAF00102419FFFEE6 +:10059000330400FF2487000402599024000721C07F +:1005A00012400002026F30253266FFFF0E000FDBA3 +:1005B00032A5FFFF1240FE990000202132480001C1 +:1005C0001100000E324A00048FAB0010240200011B +:1005D00012420002026B30253266FFFF000020212C +:1005E0000E000FDB32A5FFFF2406FFFE024690241B +:1005F0001240FE8A00002021324A00045140000EC1 +:10060000240400018FB600102403000412430002EA +:10061000027630253266FFFF2413FFFB32A5FFFF71 +:10062000240401000E000FDB0253A82412A0FE7B5D +:1006300000002021240400010A0013AB00801821CF +:100640003C0C08008D8C0024319200015240FE7356 +:100650000000202132A5FFFF36C600020E000FDB8E +:10066000000020210A0014000000202124020003C1 +:1006700035230180A062000B0A0014CC2413BFFFB5 +:100680002404FFFE0A0014CA010440243C03800035 +:10069000346401008C85000030A2003E1440000844 +:1006A00000000000AC6000488C87000030E607C006 +:1006B00010C0000500000000AC60004CAC600050B1 +:1006C00003E0000824020001AC600054AC6000406C +:1006D0008C880000310438001080FFF90000000011 +:1006E0002402000103E00008AC6000443C038000E9 +:1006F0008C6201B80440FFFE34670180ACE4000066 +:1007000024080001ACE00004A4E500082405000270 +:10071000A0E8000A34640140A0E5000B9483000ABD +:1007200014C00008A4E30010ACE000243C078000E3 +:1007300034E901803C041000AD20002803E00008EB +:10074000ACE401B88C8600043C041000ACE6002444 +:100750003C07800034E90180AD20002803E0000858 +:10076000ACE401B83C0680008CC201B80440FFFE36 +:1007700034C7018024090002ACE40000ACE40004AA +:10078000A4E50008A0E9000A34C50140A0E9000B77 +:1007900094A8000A3C041000A4E80010ACE0002477 +:1007A0008CA30004ACE3002803E00008ACC401B84B +:1007B0003C03900034620001008220253C0380004D +:1007C000AC6400208C65002004A0FFFE0000000047 +:1007D00003E00008000000003C02800034430001F8 +:1007E0000083202503E00008AC44002027BDFFE083 +:1007F0003C098000AFBF0018AFB10014AFB00010CB +:10080000352801408D10000091040009910700086F +:1008100091050008308400FF30E600FF00061A0052 +:100820002C820081008330251040002A30A50080F2 +:10083000000460803C0D080125AD90E8018D582131 +:100840008D6A000001400008000000003C038000A9 +:10085000346201409445000A14A0001E8F91FCB838 +:100860009227000530E6000414C0001A00000000C2 +:100870000E0015E502002021922A00050200202129 +:10088000354900040E0015EFA22900059228000545 +:100890003104000414800002000000000000000D7C +:1008A000922D0000240B002031AC00FF158B0009B5 +:1008B0003C0580008CAE01B805C0FFFE34B101805C +:1008C000AE3000003C0F100024100005A230000BD9 +:1008D000ACAF01B80000000D8FBF00188FB100143D +:1008E0008FB0001003E0000827BD00200200202187 +:1008F00000C028218FBF00188FB100148FB00010E6 +:10090000240600010A0015B427BD00200000000DD8 +:100910000200202100C028218FBF00188FB10014D1 +:100920008FB00010000030210A0015B427BD002050 +:1009300014A0FFE800000000020020218FBF001873 +:100940008FB100148FB0001000C028210A0015D20A +:1009500027BD00203C0780008CEE01B805C0FFFEDB +:1009600034F00180241F0002A21F000B34F8014064 +:10097000A60600089719000A3C0F1000A6190010DF +:100980008F110004A6110012ACEF01B80A00163056 +:100990008FBF001827BDFFE8AFBF00100E000FD4B7 +:1009A000000000003C0280008FBF001000002021EA +:1009B000AC4001800A0010A627BD00183084FFFF5C +:1009C00030A5FFFF108000070000182130820001D1 +:1009D0001040000200042042006518211480FFFB33 +:1009E0000005284003E000080060102110C0000747 +:1009F000000000008CA2000024C6FFFF24A5000414 +:100A0000AC82000014C0FFFB2484000403E0000853 +:100A10000000000010A0000824A3FFFFAC86000027 +:100A200000000000000000002402FFFF2463FFFF1D +:100A30001462FFFA2484000403E0000800000000B0 +:100A40003C03800027BDFFF834620180AFA20000A4 +:100A5000308C00FF30AD00FF30CE00FF3C0B80003B +:100A60008D6401B80480FFFE000000008FA9000023 +:100A70008D6801288FAA00008FA700008FA40000B6 +:100A80002405000124020002A085000A8FA30000B3 +:100A9000359940003C051000A062000B8FB80000A3 +:100AA0008FAC00008FA600008FAF000027BD0008AC +:100AB000AD280000AD400004AD800024ACC000288B +:100AC000A4F90008A70D0010A5EE001203E000082D +:100AD000AD6501B83C06800827BDFFE834C500803D +:100AE000AFBF001090A700092402001230E300FFFE +:100AF0001062000B008030218CA800500088202359 +:100B0000048000088FBF00108CAA00342404003930 +:100B10000000282100CA48230520000524060012F1 +:100B20008FBF00102402000103E0000827BD001859 +:100B30000E001689000000008FBF00102402000183 +:100B400003E0000827BD001827BDFFC8AFB2003082 +:100B5000AFB00028AFBF0034AFB1002C00A080219F +:100B600090A5000D30A6001010C00010008090214C +:100B70003C0280088C4400048E0300081064000CC2 +:100B800030A7000530A6000510C000932404000122 +:100B90008FBF00348FB200308FB1002C8FB000288F +:100BA0000080102103E0000827BD003830A70005B1 +:100BB00010E0000F30AB001210C00006240400014A +:100BC0003C0980088E0800088D2500045105009C12 +:100BD000240400388FBF00348FB200308FB1002C56 +:100BE0008FB000280080102103E0000827BD0038E6 +:100BF000240A0012156AFFE62404000102002021E5 +:100C000027A500100E000CB6AFA000101440007C09 +:100C10003C198008372400809098000833110008A0 +:100C20001220000A8FA7001030FF010013E000A47B +:100C30008FA300148C860058006610230440000423 +:100C40003C0A8008AC8300588FA700103C0A80083B +:100C50003548008091090008312400081480000202 +:100C600024080003000040213C1F800893F100117C +:100C700093F9001237E600808CCC0054333800FF23 +:100C800003087821322D00FF000F708001AE28216B +:100C900000AC582B1160006F0000000094CA005C8B +:100CA0008CC900543144FFFF012510230082182B0A +:100CB00014600068000000008CCB0054016518230C +:100CC00030EC00041180006C000830808FA8001CFC +:100CD0000068102B1040006230ED00040066102305 +:100CE0002C46008010C000020040882124110080A2 +:100CF0000E0015E5024020213C0D800835A600803D +:100D000024070001ACC7000C90C80008001148403F +:100D100035A70100310C007FA0CC00088E0500042F +:100D200024AB0001ACCB0030A4D1005C8CCA003CE9 +:100D30009602000E01422021ACC400208CC3003C6E +:100D40000069F821ACDF001C8E190004ACF900002A +:100D50008E180008ACF800048FB10010322F000884 +:100D600055E0004793A60020A0C0004E90D8004E4A +:100D70002411FFDFA0F8000890CF000801F17024D3 +:100D8000A0CE00088E0500083C0B80083569008065 +:100D9000AD2500388D6A00148D22003024190050D2 +:100DA00001422021AD24003491230000307F00FF58 +:100DB00013F90036264F01000E0015EF02402021E6 +:100DC00024040038000028210E0016892406000A99 +:100DD0000A0016EE240400010E000D280000202158 +:100DE0008FBF00348FB200308FB1002C8FB000283D +:100DF000004020210080102103E0000827BD0038BA +:100E00008E0E00083C0F800835F00080AE0E0054B6 +:100E100002402021AE0000300E0015E50000000069 +:100E2000920D00250240202135AC00200E0015EF68 +:100E3000A20C00250E000CAC024020212404003836 +:100E40002405008D0E001689240600120A0016EEF5 +:100E50002404000194C5005C0A00172930A3FFFF99 +:100E60002407021811A0FF9E00E610238FAE001C7D +:100E70000A00173101C610230A00172E2C6202182F +:100E8000A0E600080A00175B8E0500082406FF8014 +:100E900001E6C0243C118000AE3800288E0D000809 +:100EA00031E7007F3C0E800C00EE6021AD8D00E04C +:100EB0008E080008AF8C00340A001767AD8800E484 +:100EC000AC800058908500082403FFF700A3382465 +:100ED000A08700080A00170C8FA700103C05080027 +:100EE00024A55F043C04080024846E503C020800E2 +:100EF00024425F0C240300063C010801AC2594F851 +:100F00003C010801AC2494FC3C010801AC22950092 +:100F10003C010801A023950403E000080000000044 +:100F200003E00008240200013C028000308800FF3A +:100F3000344701803C0680008CC301B80460FFFE8A +:100F4000000000008CC501282418FF803C0D800A99 +:100F500024AF010001F8702431EC007FACCE0024F6 +:100F6000018D2021ACE50000948B00EA350960007A +:100F700024080002316AFFFFACEA000424020001E9 +:100F8000A4E90008A0E8000BACE000243C07100036 +:100F9000ACC701B8AF84003403E00008AF85006837 +:100FA000938800448F89005C8F82003430C600FF34 +:100FB0000109382330E900FF0122182130A500FF84 +:100FC0002468008810C000020124382100803821E4 +:100FD00030E400031480000330AA00031140000D28 +:100FE000312B000310A000090000102190ED00003B +:100FF000244E000131C200FF0045602BA10D00000E +:1010000024E700011580FFF92508000103E000082E +:10101000000000001560FFF30000000010A0FFFBBF +:10102000000010218CF8000024590004332200FF36 +:101030000045782BAD18000024E7000415E0FFF907 +:101040002508000403E00008000000009385004428 +:10105000938800548F87005C000432003103007FC6 +:1010600000E5102B30C47F001040000F00642825DD +:101070008F8400343C0980008C8A00ECAD2A00A4E7 +:101080003C03800000A35825AC6B00A08C6C00A032 +:101090000580FFFE000000008C6D00ACAC8D00EC04 +:1010A00003E000088C6200A80A0018198F8400343D +:1010B000938800553C02800000805021310300FEDF +:1010C000A383005530ABFFFF30CC00FF30E7FFFFBC +:1010D000344801803C0980008D2401B80480FFFE63 +:1010E0008F8D006824180016AD0D00008D2201249C +:1010F0008F8D0034AD0200048D590020A507000833 +:10110000240201C4A119000AA118000B952F012087 +:101110008D4E00088D470004978300588D59002498 +:1011200001CF302100C7282100A320232418FFFF6E +:10113000A504000CA50B000EA5020010A50C0012C2 +:10114000AD190018AD18002495AF00E83C0B100055 +:101150002407FFF731EEFFFFAD0E00288DAC0084B1 +:10116000AD0C002CAD2B01B88D46002000C7282403 +:1011700003E00008AD4500208F880034008058212E +:1011800030E7FFFF910900D63C02800030A5FFFF49 +:10119000312400FF00041A000067502530C600FF0C +:1011A000344701803C0980008D2C01B80580FFFE8A +:1011B0008F820068240F0017ACE200008D390124F3 +:1011C000ACF900048D780020A4EA0008241901C4B9 +:1011D000A0F8000AA0EF000B952301208D6E0008F7 +:1011E0008D6D00049784005801C35021014D60218A +:1011F00001841023A4E2000CA4E5000EA4F9001061 +:10120000A4E60012ACE000148D780024240DFFFF4A +:10121000ACF800188D0F007CACEF001C8D0E007830 +:101220003C0F1000ACEE0020ACED0024950A00BE8F +:10123000240DFFF73146FFFFACE60028950C008037 +:101240009504008231837FFF0003CA003082FFFFD4 +:101250000322C021ACF8002CAD2F01B8950E0082FE +:101260008D6A002000AE3021014D2824A5060082A1 +:1012700003E00008AD6500203C0280003445018099 +:101280003C0480008C8301B80460FFFE8F8A00401C +:10129000240600199549001C3128FFFF000839C0B9 +:1012A000ACA70000A0A6000B3C05100003E000085E +:1012B000AC8501B88F8700480080402130C400FF12 +:1012C0003C0680008CC201B80440FFFE8F89006894 +:1012D0009383006434996000ACA90000A0A30005CA +:1012E0008CE20010240F00022403FFF7A4A20006E2 +:1012F000A4B900088D180020A0B8000AA0AF000B08 +:101300008CEE0000ACAE00108CED0004ACAD00140F +:101310008CEC001CACAC00248CEB0020ACAB0028A7 +:101320008CEA002C3C071000ACAA002C8D0900248C +:10133000ACA90018ACC701B88D05002000A320247B +:1013400003E00008AD0400208F86003427BDFFE0D5 +:10135000AFB10014AFBF0018AFB0001090C300D4FD +:1013600030A500FF30620020104000080080882176 +:101370008CCB00D02409FFDF256A0001ACCA00D065 +:1013800090C800D401093824A0C700D414A000409C +:101390003C0C80008F840034908700D42418FFBF59 +:1013A0002406FFEF30E3007FA08300D4979F00580E +:1013B0008F82005C8F8D003403E2C823A799005808 +:1013C000A5A000BC91AF00D401F87024A1AE00D458 +:1013D0008F8C0034A18000D78F8A0034A540008212 +:1013E000AD4000EC914500D400A65824A14B00D498 +:1013F0008F9000308F84005C97860058020428216B +:1014000010C0000FAF850030A38000543C0780005F +:101410008E2C000894ED01208E2B0004018D5021AC +:10142000014B8021020620233086FFFF30C8000FC9 +:10143000390900013131000116200009A388005448 +:10144000938600448FBF00188FB100148FB0001036 +:1014500027BD0020AF85006003E00008AF86005C78 +:1014600000C870238FBF0018938600448FB100140A +:101470008FB0001034EF0C00010F282127BD002091 +:10148000ACEE0084AF85006003E00008AF86005C2E +:1014900035900180020028210E0018A62406008243 +:1014A0008F840034908600D430C5004050A0FFBA2D +:1014B000A38000648F8500483C0680008CCD01B875 +:1014C00005A0FFFE8F8900682408608224070002BF +:1014D000AE090000A6080008A207000B8CA30008B4 +:1014E0003C0E1000AE0300108CA2000CAE020014E3 +:1014F0008CBF0014AE1F00188CB90018AE19002460 +:101500008CB80024AE1800288CAF0028AE0F002C39 +:10151000ACCE01B80A0018DFA38000648F8A0034C3 +:1015200027BDFFE0AFB10014AFB000108F88005CA2 +:10153000AFBF001893890038954200BC30D100FF3E +:101540000109182B0080802130AC00FF3047FFFFDD +:101550000000582114600003310600FF01203021F3 +:1015600001095823978300580068202B1480002716 +:101570000000000010680056241900011199006352 +:1015800034E708803165FFFF0E0018570200202164 +:101590008F8300683C07800034E601803C058000B2 +:1015A0008CAB01B80560FFFE240A00188F8400345C +:1015B000ACC30000A0CA000B948900BE3C08100018 +:1015C000A4C90010ACC00030ACA801B8948200805F +:1015D00024430001A4830080949F00803C060800FF +:1015E0008CC6318833EC7FFF1186005E000000005E +:1015F00002002021022028218FBF00188FB1001483 +:101600008FB000100A0018CB27BD0020914400D4F1 +:101610002403FF8000838825A15100D497840058BB +:101620003088FFFF51000023938C00388F850034F1 +:101630002402EFFF008B782394AE00BC0168502B8E +:1016400031E900FF01C26824A4AD00BC514000395B +:10165000010058213C1F800037E601008CD80004AF +:101660003C190001031940245500000134E74000F3 +:101670008E0A00202403FFFB2411000101432024D3 +:10168000AE0400201191002D34E7800002002021DB +:10169000012030210E0018573165FFFF9787005851 +:1016A0008F89005CA780005801278023AF90005CE1 +:1016B000938C00388F8B00348FBF00188FB10014CB +:1016C0008FB0001027BD002003E00008A16C00D7F8 +:1016D0003C0D800035AA01008D4800043C09000142 +:1016E0000109282454A0000134E740008E0F002097 +:1016F0002418FFFB34E7800001F87024241900014E +:10170000AE0E00201599FF9F34E7088002002021CB +:101710000E0018253165FFFF02002021022028213C +:101720008FBF00188FB100148FB000100A0018CBC3 +:1017300027BD00200A00198E000048210200202148 +:10174000012030210E0018253165FFFF97870058D2 +:101750008F89005CA7800058012780230A0019A503 +:10176000AF90005C948C0080241F8000019F302487 +:10177000A4860080908B0080908F0080316700FFEE +:101780000007C9C20019C027001871C031ED007FE1 +:1017900001AE2825A08500800A00197602002021CC +:1017A000938500642403000127BDFFE800A33004F3 +:1017B0002CA20020AFB00010AFBF001400C0182151 +:1017C000104000132410FFFE3C0708008CE7319006 +:1017D00000E610243C088000350501801440000517 +:1017E000240600848F890034240A00042410FFFF9B +:1017F000A12A00FC0E0018A6000000000200102123 +:101800008FBF00148FB0001003E0000827BD001840 +:101810003C0608008CC631940A0019EE00C310245F +:101820008F87004027BDFFE0AFB20018AFB10014B2 +:10183000AFB00010AFBF001C30D000FF90E6000D2D +:1018400000A088210080902130C5007FA0E5000D18 +:101850008F8500348E2300188CA200D01062002ED9 +:10186000240A000E0E0019E1A38A00642409FFFF78 +:10187000104900222404FFFF520000200000202114 +:101880008E2600003C0C001000CC58241560003956 +:101890003C0E000800CE682455A0003F02402021E5 +:1018A0003C18000200D880241200001F3C0A0004EB +:1018B0008F8700408CE200148CE300108CE500144C +:1018C0000043F82303E5C82B132000050240202124 +:1018D0008E24002C8CF10010109100310240202148 +:1018E00024020012A38200640E0019E12412FFFFFB +:1018F000105200022404FFFF000020218FBF001CB3 +:101900008FB200188FB100148FB00010008010212A +:1019100003E0000827BD002090A800D43504002073 +:101920000A001A17A0A400D400CA48241520000BEE +:101930008F8B00408F8D00408DAC00101580000B08 +:10194000024020218E2E002C51C0FFEC00002021EF +:10195000024020210A001A32240200178D6600106E +:1019600050C0FFE600002021024020210A001A3268 +:101970002402001102402021240200150E0019E16A +:10198000A3820064240FFFFF104FFFDC2404FFFF3D +:101990000A001A218E2600000A001A582402001498 +:1019A0003C08000400C8382450E0FFD40000202187 +:1019B000024020210A001A32240200138F850034CD +:1019C00027BDFFD8AFB3001CAFB20018AFB10014F1 +:1019D000AFB00010AFBF002090A700D48F90004898 +:1019E0002412FFFF34E2004092060000A0A200D4BF +:1019F0008E030010008098211072000630D1003F45 +:101A00002408000D0E0019E1A3880064105200257F +:101A10002404FFFF8F8A00348E0900188D4400D003 +:101A20001124000702602021240C000E0E0019E191 +:101A3000A38C0064240BFFFF104B001A2404FFFF4B +:101A400024040020122400048F8D003491AF00D4B0 +:101A500035EE0020A1AE00D48F85005010A00019F3 +:101A6000000000001224004A8F9800348F92FCB8C6 +:101A7000971000809651000A523000488F93003C26 +:101A80003C1F08008FFF318C03E5C82B1720001E78 +:101A900002602021000028210E00194024060001C8 +:101AA000000020218FBF00208FB3001C8FB20018D0 +:101AB0008FB100148FB000100080102103E00008E7 +:101AC00027BD00285224002A8E0500148F8400347C +:101AD000948A008025490001A489008094880080B0 +:101AE0003C0208008C42318831077FFF10E2000E73 +:101AF00000000000026020210E0018CB2405000128 +:101B00000A001AA2000020212402002D0E0019E173 +:101B1000A38200642403FFFF1443FFE12404FFFFBA +:101B20000A001AA38FBF002094990080241F800010 +:101B300024050001033FC024A498008090920080F7 +:101B4000908E0080325100FF001181C20010782772 +:101B5000000F69C031CC007F018D5825A08B00801B +:101B60000E0018CB026020210A001AA200002021DA +:101B70002406FFFF54A6FFD68F8400340260202184 +:101B80000E0018CB240500010A001AA20000202133 +:101B9000026020210A001ABC2402000A2404FFFD6E +:101BA0000A001AA2AF93005C8F88003427BDFFE8BB +:101BB000AFB00010AFBF0014910A00D48F87004867 +:101BC00000808021354900408CE60010A10900D436 +:101BD0003C0208008C4231B030C53FFF00A2182BF8 +:101BE000106000078F85004C240DFF8090AE000D23 +:101BF00001AE6024318B00FF156000080006C3822F +:101C0000020020212403000D8FBF00148FB00010AC +:101C100027BD00180A0019E1A383006433060003FE +:101C2000240F000254CFFFF70200202194A2001CD1 +:101C30008F85003424190023A4A200E88CE800005A +:101C400000081E02307F003F13F900353C0A008374 +:101C50008CE800188CA600D01106000800000000D7 +:101C60002405000E0E0019E1A38500642407FFFF80 +:101C7000104700182404FFFF8F85003490A900D47A +:101C800035240020A0A400D48F8C0040918E000D3C +:101C900031CD007FA18D000D8F8300501060001C9E +:101CA000020020218F84004C8C9800100303782BB5 +:101CB00011E0000D2419001802002021A3990064EE +:101CC0000E0019E12410FFFF105000022404FFFF52 +:101CD000000020218FBF00148FB000100080102161 +:101CE00003E0000827BD00188C8600108F9F00407D +:101CF0000200202100C31023AFE2001024050001E0 +:101D00000E001940240600010A001B2E00002021AD +:101D10000E0018CB240500010A001B2E0000202114 +:101D2000010A5824156AFFD98F8C0040A0A600FC38 +:101D30000A001B1BA386005630A500FF24060001E5 +:101D400024A9000100C9102B1040000C0000402104 +:101D5000240A000100A61823308B000124C60001CC +:101D6000006A3804000420421160000200C9182BE8 +:101D7000010740251460FFF800A6182303E00008BF +:101D80000100102127BDFFD8AFB000188F90004888 +:101D9000AFB1001CAFBF00202403FFFF2411002FB0 +:101DA000AFA30010920600002405000826100001D1 +:101DB000006620260E001B47308400FF00021E0034 +:101DC0003C021EDC34466F410A001B6F00001021EC +:101DD00010A00009008018212445000130A2FFFF57 +:101DE0002C4500080461FFFA0003204000862026ED +:101DF00014A0FFF9008018210E001B4724050020C5 +:101E00008FA300102629FFFF313100FF000342029B +:101E1000240700FF1627FFE20102182600035027BF +:101E2000AFAA0014AFAA00100000302127A80010AC +:101E300027A7001400E6782391ED000324CE0001CB +:101E400000C8602131C600FF2CCB00041560FFF9EB +:101E5000A18D00008FA200108FBF00208FB1001C49 +:101E60008FB0001803E0000827BD002827BDFFD071 +:101E7000AFB3001CAFB00010AFBF0028AFB5002457 +:101E8000AFB40020AFB20018AFB100143C0C80001A +:101E90008D880128240FFF803C06800A2510010050 +:101EA000250B0080020F68243205007F016F70242B +:101EB000AD8E009000A62821AD8D002490A600FCD8 +:101EC0003169007F3C0A8004012A1821A38600564C +:101ED0009067007C00809821AF83002C30E20002E4 +:101EE000AF880068AF85003400A0182114400002BC +:101EF0002404003424040030A38400448C7200DCE9 +:101F000030D100FF24040004AF92005C12240004CE +:101F1000A38000648E7400041680001E3C088000BC +:101F20009386005530C7000150E0000F8F86005C9B +:101F30008CA400848CA800842413FF800093602468 +:101F4000000C49403110007F013078253C192000F9 +:101F500001F9682530DF00FE3C038000AC6D0830DD +:101F6000A39F00558F86005C8FBF00288FB500248B +:101F70008FB400208FB3001C8FB200188FB10014F3 +:101F80008FB000102402000127BD003003E00008DC +:101F9000ACA600DC8E7F0008950201208E67001041 +:101FA00003E2C8213326FFFF30D8000F33150001AC +:101FB000AF87003016A00058A398005435090C00D4 +:101FC0000309382100D81823AD030084AF870060CF +:101FD0008E6A00043148FFFF1100007EA78A005876 +:101FE00090AC00D42407FF8000EC302430CB00FFFD +:101FF0001560004B97860058938E0056240D000202 +:1020000030D5FFFF11CD02A20000A0218F85005C1A +:1020100002A5802B160000BC938800443C11800070 +:1020200096240120310400FF148500888F8400600D +:102030008F980030331200035640008530A500FF12 +:102040008F900060310C00FF24060034118600954B +:10205000AF90004892040004148001198F8E003460 +:10206000A38000388E0D00048DC800D83C0600FF08 +:1020700034CCFFFF01AC30240106182B1460012181 +:10208000AF8600508F87005C97980058AF87003C60 +:102090000307402310C000C7A78800588F91002C69 +:1020A00030C3000300035823922A007C31710003DF +:1020B00002261021000A208230920001001248807E +:1020C00000492821311FFFFF03E5C82B1320012001 +:1020D0008F8800348F8500308F8800601105025A88 +:1020E0003C0E3F018E0600003C0C250000CE68240B +:1020F00011AC01638F84004830E500FF0E0017E14A +:10210000000030218F8800348F87005C8F8500307D +:102110000A001D4E8F8600500A001BEDAF8700603D +:1021200090AC00D400EC2024309000FF1200001688 +:102130009386005590B5008890B400D724A80088F5 +:1021400032A2003F2446FFE02CD10020A3940038A7 +:102150001220000CAF880048240E000100CE20049D +:10216000308A00191540012B3C06800034D800024B +:10217000009858241560022E309200201640023438 +:10218000000000009386005530CE000111C0000F02 +:10219000978800588CA900848CAF00842410FF809D +:1021A0000130C8240019194031ED007F006D382539 +:1021B0003C1F200000FF902530CB00FE3C18800023 +:1021C000AF120830A38B0055978800581500FF8484 +:1021D000000000008E630020306C00041180FF516D +:1021E000938600552404FFFB006430243C038000E8 +:1021F000AE660020346601808C7301B80660FFFE75 +:102200008F8E0068346A01003C150001ACCE0000DE +:102210008C62012424076085ACC200048D54000444 +:1022200002958824522000012407608324120002B2 +:102230003C1810003C0B8000A4C70008A0D2000B83 +:10224000AD7801B80A001BC29386005530A500FF87 +:102250000E0017E1240600018F8800683C0580000D +:1022600034A909002502018893880044304A0007F8 +:10227000304B00783C0340802407FF800163C82571 +:10228000014980210047F824310C00FF2406003466 +:10229000ACBF0800AF900048ACB908105586FF6E7F +:1022A000920400048F8400348E110030908E00D48C +:1022B00031CD001015A000108F83005C2C6F00053D +:1022C00015E000E400000000909800D42465FFFCB5 +:1022D000331200101640000830A400FF8F9F0060EA +:1022E0008F99003013F900043887000130E20001B3 +:1022F000144001C8000000000E001B5A000000003E +:102300000A001D8F000000008F84006030C500FFB0 +:102310000E0017E124060001938E0044240A0034C5 +:1023200011CA00A08F8500348F86005C9783005807 +:102330003062FFFF00C28823AF91005CA780005885 +:102340001280FF90028018212414FFFD5474FFA214 +:102350008E6300208E6900042403FFBF240BFFEF6F +:102360000135C823AE79000490AF00D431ED007F71 +:10237000A0AD00D48E6600208F980034A78000584E +:1023800034DF0002AE7F0020A70000BC931200D40F +:1023900002434024A30800D48F950034AEA000EC83 +:1023A00092AE00D401CB5024A2AA00D40A001C6E25 +:1023B0008F8500348F910030AF80005C0227582158 +:1023C000AF8B0030000020212403FFFF108301B4F5 +:1023D0008F8500348E0C00103C0D08008DAD31B09F +:1023E0009208000031843FFF008D802B12000023F3 +:1023F000310D003F3C1908008F3931A88F9F0068CC +:10240000000479802408FF80033F2021008FC82129 +:10241000938500550328F8243C0600803C0F80007B +:1024200034D80001001F91403331007F8F86003483 +:102430000251502535EE0940332B00783330000728 +:102440003C0310003C02800C01789025020E4821CC +:102450000143C0250222382134AE0001ADFF08043B +:10246000AF89004CADF20814AF870040ADFF0028E3 +:10247000ACD90084ADF80830A38E00559383005684 +:10248000240700035067002825A3FFE0240C000167 +:10249000146CFFAB8F8500342411002311B100842C +:1024A000000000002402000B026020210E0019E150 +:1024B000A38200640040A0210A001CC98F8500345B +:1024C00002602021240B000C0E0019E1A38B006494 +:1024D000240AFFFF104AFFBC2404FFFF8F8E003444 +:1024E000A38000388E0D00048DC800D83C0600FF84 +:1024F00034CCFFFF01AC30240106182B1060FEE144 +:10250000AF86005002602021241200190E0019E14C +:10251000A3920064240FFFFF104FFFAB2404FFFFC2 +:102520000A001C1A8F8600502C7400201280FFDED7 +:102530002402000B000328803C110801263192EC94 +:1025400000B148218D2D000001A00008000000000E +:102550008F85003000A7102193850038AF820030AE +:1025600002251821A3830038951F00BC02262821CC +:1025700037F91000A51900BC5240FF92AF85005CEE +:10258000246A0004A38A0038950900BC24A400042E +:10259000AF84005C35322000A51200BC0A001CEBA1 +:1025A000000020218F86005C2CCB00051560FF60A9 +:1025B000978300583072FFFF00D240232D1800058A +:1025C00013000003306400FF24DFFFFC33E400FF4E +:1025D0008F8500608F86003010A60004388F0001C0 +:1025E00031ED000115A00138000000008F84003497 +:1025F000908C00D435870010A08700D48F850034DC +:102600008F86005C97830058ACA000EC0A001CC6C3 +:102610003062FFFF8CAA00848CB500843C0410005B +:10262000014710240002894032B4007F0234302573 +:1026300000C460253C0880002405000102602021C0 +:10264000240600010E001940AD0C08300A001C5A87 +:102650008F8500348C8200EC1222FE7E02602021E5 +:1026600024090005A38900640E0019E12411FFFF6D +:102670001451FE782404FFFF0A001CEC2403FFFF22 +:102680008F8F00488F8800348DF80000AD180088C7 +:102690008DE70010AD0700988F87005C0A001D4E83 +:1026A0008F8600502407FFFF1187000500000000FF +:1026B0000E001AE3026020210A001D270040A0211D +:1026C0000E001A68026020210A001D270040A02188 +:1026D0008F9000483C0908008D2931B08E11001000 +:1026E00032323FFF0249682B11A0000C240AFF8000 +:1026F0008F85004C90AE000D014E1024304C00FF31 +:1027000011800007026020210011C38233030003FF +:10271000240B0001106B0105000000000260202165 +:102720002418000D0E0019E1A39800640040202138 +:102730008F8500340A001CC90080A0218F900048BA +:102740003C0A08008D4A31B08F85004C8E04001081 +:102750000000A0218CB1001430823FFF004A602BA2 +:102760008CB200205180FFEE0260202190B8000D55 +:10277000240BFF800178702431C300FF5060FFE814 +:1027800002602021000443823106000314C0FFE4EC +:102790000260202194BF001C8F9900348E0600280F +:1027A000A73F00E88CAF0010022F202314C401398A +:1027B000026020218F83005000C36821022D382B36 +:1027C00014E00135240200188F8A00408F82002C0B +:1027D000024390218D4B001001637023AD4E001019 +:1027E000AD5200208C4C00740192282B14A001568D +:1027F000026020218F84004C8E0800248C860024E7 +:1028000011060007026020212419001C0E0019E1A6 +:10281000A3990064240FFFFF104FFFC52404FFFF9E +:102820008F8400408C87002424FF0001AC9F00248B +:10283000125101338F8D002C8DB100741232013092 +:102840003C0B00808E0E000001CB5024154000751B +:10285000000000008E0300142411FFFF1071000619 +:10286000026020212418001B0E0019E1A3980064C7 +:102870001051FFAF2404FFFF8E0300003C0800014D +:102880000068302410C000133C0400800064A024C1 +:102890001680000902002821026020212419001A54 +:1028A0000E0019E1A3990064240FFFFF104FFFA051 +:1028B0002404FFFF02002821026020210E001A01DB +:1028C000240600012410FFFF1050FF992404FFFF8D +:1028D000241400018F9F00400260202102803021DB +:1028E00097F100342405000126270001A7E70034F2 +:1028F0000E00194000000000000020218F850034E8 +:102900000A001CC90080A0218F9000483C140800D8 +:102910008E9431B08E07001030E83FFF0114302B49 +:1029200010C000618F86004C241FFF8090C5000DF1 +:1029300003E52024309200FF5240005C0260202119 +:102940008F8D005011A0000700078B828F85003407 +:102950008F89FCB894AF00809539000A132F00F6D8 +:102960008F87003C322C00031580006300000000BC +:1029700092020002104000D7000000008E0A0024DE +:10298000154000D8026020219204000324060002B2 +:10299000308800FF15060005308500FF8F94005039 +:1029A000528000F202602021308500FF38AD001017 +:1029B0002DA400012CBF000103E4302502002821D2 +:1029C0000E001A01026020212410FFFF105000BEEB +:1029D0008F8500348F830050106000C424050001EF +:1029E0003C1908008F39318C0323782B15E000B196 +:1029F0002409002D02602021000028210E0019402A +:102A0000240600018F850034000018210A001CC92B +:102A10000060A0210E00180C000000000A001D8FAD +:102A200000000000AC8000200A001E0F8E0300147E +:102A300000002821026020210E0019402406000118 +:102A40000A001C5A8F8500340A001D4E8F880034FE +:102A50008CB000848CB900843C0310000207482429 +:102A600000096940332F007F01AFF82503E32825D3 +:102A7000ACC5083091070001240500010260202147 +:102A80000E00194030E600010A001C5A8F85003400 +:102A9000938F00442403FFFD0A001CCBAF8F005C22 +:102AA0000A001CCB2403FFFF026020212410000D2C +:102AB0000E0019E1A3900064004018218F850034B6 +:102AC0000A001CC90060A0210E00180C00000000C4 +:102AD000978300588F86005C3070FFFF00D048233A +:102AE0002D3900051320FE128F850034ACA200ECB6 +:102AF0000A001CC63062FFFF90C3000D307800084A +:102B00005700FFA29204000302602021240200105B +:102B10000E0019E1A38200642403FFFF5443FF9BCE +:102B2000920400030A001EA98F85003490A8000DAE +:102B30003106000810C000958F9400501680009E4A +:102B4000026020218E0F000C8CA4002055E40005AB +:102B5000026020218E1F00088CB9002413F9003A6E +:102B600002602021240200200E0019E1A3820064EB +:102B70002405FFFF1045FEEE2404FFFF8F8F004069 +:102B8000240CFFF72403FF8091E9000D3C14800E14 +:102B90003C0B8000012CC824A1F9000D8F8F002C64 +:102BA0003C0708008CE731AC8F8D006895E5007814 +:102BB0008F99004000ED902130BF7FFF001F204023 +:102BC0000244302130C8007F00C3C02401147021AA +:102BD000AD78002CA5D100008F2A002825420001E5 +:102BE000AF2200288F29002C8E0C002C012C68218C +:102BF000AF2D002C8E07002CAF2700308E0500145F +:102C0000AF250034973F003A27E40001A724003A9B +:102C100095F200783C1008008E1031B02643000178 +:102C200030717FFF1230005C006030218F83002CF8 +:102C300002602021240500010E0018CBA466007854 +:102C40000A001E38000020218E0700142412FFFF06 +:102C500010F200638F8C00348E0900188D8D00D027 +:102C6000152D005D026020218E0A00248CA2002810 +:102C700011420053240200210E0019E1A3820064D6 +:102C80001452FFBE2404FFFF8F8500340A001CC9C4 +:102C90000080A0212402001F0E0019E1A38200641D +:102CA0002409FFFF1049FEA22404FFFF0A001DEBC8 +:102CB0008F830050026020210E0019E1A389006477 +:102CC0001450FF518F8500342403FFFF0A001CC9F4 +:102CD0000060A0218CCE00248E0B0024116EFF2AF0 +:102CE000026020210A001EBD2402000F0E0018CB36 +:102CF000026020218F8500340A001E7C000018210C +:102D00008E0900003C050080012590241640FF45F7 +:102D10002402001A026020210E0019E1A38200643F +:102D2000240CFFFF144CFECB2404FFFF8F850034DE +:102D30000A001CC90080A0212403FFFD0060A0211F +:102D40000A001CC9AF87005C2418001D0E0019E1A1 +:102D5000A39800642403FFFF1443FEA62404FFFF8E +:102D60008F8500340A001CC90080A0212412002C89 +:102D70000E0019E1A39200642403FFFF1043FF50EB +:102D80008F8500340A001E63920400030260202134 +:102D90000A001ED324020024240B8000006B702440 +:102DA00031CAFFFF000A13C2305100FF0011802713 +:102DB0000A001F04001033C00A001ED3240200279B +:102DC0008E0600288CAE002C10CE00080260202158 +:102DD0000A001F172402001F0A001F172402000EFA +:102DE000026020210A001F17240200258E04002CF7 +:102DF0001080000D8F83002C8C7800740304582BF6 +:102E00005560000C026020218CA800140086A021CF +:102E10000114302B10C0FF5A8F8F00400260202118 +:102E20000A001F1724020022026020210A001F1737 +:102E3000240200230A001F172402002627BDFFD802 +:102E4000AFB3001CAFB10014AFBF0020AFB2001889 +:102E5000AFB000103C0280008C5201408C4B014806 +:102E60003C048000000B8C02322300FF317300FF12 +:102E70008C8501B804A0FFFE34900180AE120000E2 +:102E80008C8701442464FFF0240600022C83001385 +:102E9000AE070004A6110008A206000BAE13002422 +:102EA0001060004F8FBF0020000448803C0A0801DA +:102EB000254A936C012A40218D04000000800008FF +:102EC000000000003C0308008C6331A831693FFF1B +:102ED0000009998000728021021370212405FF806F +:102EE000264D0100264C00803C02800031B1007F5D +:102EF0003198007F31CA007F3C1F800A3C19800452 +:102F00003C0F800C01C5202401A530240185382404 +:102F1000014F1821AC460024023F402103194821EB +:102F2000AC470090AC440028AF830040AF88003429 +:102F3000AF89002C0E001897016080213C038000AF +:102F40008C6B01B80560FFFE8F8700408F860034D0 +:102F50003465018090E8000DACB20000A4B000061A +:102F6000000826000004160300029027001227C262 +:102F70001080008124C20088241F6082A4BF000842 +:102F8000A0A0000524020002A0A2000B8F8B002C41 +:102F9000000424003C08270000889025ACB20010F3 +:102FA000ACA00014ACA00024ACA00028ACA0002C65 +:102FB0008D6900382413FF80ACA9001890E3000D40 +:102FC00002638024320500FF10A000058FBF00209F +:102FD00090ED000D31AC007FA0EC000D8FBF002004 +:102FE0008FB3001C8FB200188FB100148FB0001087 +:102FF0003C0A10003C0E800027BD002803E00008BA +:10300000ADCA01B8265F01002405FF8033F8007FB8 +:103010003C06800003E578243C19800A031920212E +:10302000ACCF0024908E00D400AE682431AC00FFF9 +:1030300011800024AF840034248E008895CD0012C6 +:103040003C0C08008D8C31A831AB3FFF0192482128 +:10305000000B5180012A402101052024ACC4002826 +:103060003107007F3C06800C00E620219083000D94 +:1030700000A31024304500FF10A0FFD8AF8400400B +:103080009098000D330F001015E0FFD58FBF002082 +:103090000E001897000000003C0380008C7901B8F6 +:1030A0000720FFFE00000000AE1200008C7F0144EC +:1030B000AE1F0004A611000824110002A211000B8B +:1030C000AE1300243C13080192739528327000015E +:1030D0005200FFC38FBF00200E0020D402402021E9 +:1030E0000A001FF18FBF00203C1260008E452C08A3 +:1030F0003C03F0033462FFFF00A2F824AE5F2C080B +:103100008E582C083C1901C003199825AE532C0881 +:103110000A001FF18FBF0020264D010031AF007F54 +:103120003C10800A240EFF8001F0282101AE6024AB +:103130003C0B8000AD6C00241660FFA8AF85003406 +:1031400024110003A0B100FC0A001FF18FBF002072 +:1031500026480100310A007F3C0B800A2409FF80C9 +:10316000014B3021010920243C078000ACE40024FD +:103170000A001FF0AF860034944E0012320C3FFF5D +:1031800031CD3FFF15ACFF7D241F608290D900D464 +:103190002418FF800319782431EA00FF1140FF77DB +:1031A0000000000024070004A0C700FC8F87004037 +:1031B000241160842406000DA4B10008A0A6000517 +:1031C0000A001FDB240200023C0400012484951441 +:1031D00024030014240200FE3C010800AC2431EC5E +:1031E0003C010800AC2331E83C010801A4229530E1 +:1031F0003C0408012484953000001821006430212B +:10320000A0C30004246300012C6500FF54A0FFFC50 +:10321000006430213C07080024E7010003E00008B7 +:10322000AF87007400A058210080482100001021C1 +:1032300014A00012000050210A0020D0000000005D +:103240003C010801A42095303C05080194A5953067 +:103250008F8200743C0C0801258C953000E2182107 +:1032600000AC2021014B302BA0890004000010216C +:10327000A460000810C00039010048218F86007446 +:103280000009384000E940210008388000E6282184 +:1032900090A8000B90B9000A000820400088102177 +:1032A000000218800066C021A319000A8F850074EF +:1032B00000E5782191EE000A91E6000B000E6840CF +:1032C00001AE6021000C208000851021A046000B7B +:1032D0003C0308019063952A106000222462FFFFDE +:1032E0008F8300343C010801A022952A906C00FFD6 +:1032F0001180000400000000906E00FF25CDFFFF4C +:10330000A06D00FF3C190801973995302723000173 +:103310003078FFFF2F0F00FF11E0FFC9254A0001A1 +:103320003C010801A42395303C05080194A5953083 +:103330008F8200743C0C0801258C953000E2182126 +:1033400000AC2021014B302BA0890004000010218B +:10335000A460000814C0FFC90100482103E0000870 +:103360000000000003E000082402000227BDFFE087 +:10337000248501002407FF80AFB00010AFBF001804 +:10338000AFB1001400A718243C10800030A4007FC7 +:103390003C06800A008628218E110024AE030024FA +:1033A00090A200FF14400008AF850034A0A00009DF +:1033B0008FBF0018AE1100248FB100148FB0001021 +:1033C00003E0000827BD002090A900FD90A800FFA1 +:1033D000312400FF0E002082310500FF8F8500346C +:1033E0008FBF0018A0A00009AE1100248FB10014F7 +:1033F0008FB0001003E0000827BD002027BDFFD0DC +:10340000AFB20020AFB1001CAFB00018AFBF002CAE +:10341000AFB40028AFB300243C09800095330116F7 +:1034200035320C00952F011A3271FFFF02328021D4 +:103430008E08000431EEFFFF248B0100010E68218D +:10344000240CFF8025A5FFFF016C50243166007F0E +:103450003C07800AAD2A002400C73021AF850070E8 +:10346000AF88006C3C010801A020952990C3000999 +:103470000200D02100809821306300FF28620005FF +:1034800010400048AF860034286400021480008E8B +:1034900024140001240D00053C010801A02D950D08 +:1034A00090CC00FD3C010801A020950E3C010801D4 +:1034B000A020950F90CB000A240AFF80318500FFE1 +:1034C000014B4824312700FF10E0000C0000582178 +:1034D0003C128008365100808E2F00308CD0005C6A +:1034E00001F0702305C0018E8F87006C90D4000A14 +:1034F0003284007FA0C4000A8F8600343C1180080B +:10350000363000808E0F00308F87006C00EF702304 +:1035100019C000EE0000000090D40009241200023F +:10352000328400FF10920247000000008CC2005855 +:1035300000E2F82327F9FFFF1B2001300000000004 +:1035400090C500092408000430A300FF106800574C +:10355000240A00013C010801A02A950D90C900FF32 +:10356000252700013C010801A027950C3C03080118 +:103570009063950D240600051066006A2C780005FE +:10358000130000C4000090210003F8803C040801EF +:10359000248493B803E4C8218F25000000A000080C +:1035A00000000000241800FF1078005C00000000FC +:1035B00090CC000A90CA00093C080801910895299E +:1035C0003187008000EA48253C010801A0299514B4 +:1035D00090C500FD3C1408019294952A3111000118 +:1035E0003C010801A025951590DF00FE3C01080173 +:1035F000A03F951690D200FF3C010801A03295171C +:103600008CD900543C010801AC3995188CD0005875 +:103610003C010801AC30951C8CC3005C3C010801E6 +:10362000AC3495243C010801AC23952016200008F9 +:103630008FBF002C8FB400288FB300248FB20020DE +:103640008FB1001C8FB0001803E0000827BD0030C8 +:103650003C1180009624010E0E000FD43094FFFF21 +:103660003C0B08018D6B952C0260382102802821CB +:10367000AE2B01803C1308018E73950C0160202154 +:10368000240600830E001046AFB300108FBF002C3D +:103690008FB400288FB300248FB200208FB1001C9C +:1036A0008FB0001803E0000827BD00303C18080068 +:1036B0008F1831FC270F00013C010800AC2F31FCB2 +:1036C0000A002165000000001474FFB9000000002A +:1036D000A0C000FF3C0508008CA531E43C030800B5 +:1036E0008C6331E03C0208008C4232048F99003434 +:1036F00034A80001241F00023C010801AC23952CD2 +:103700003C010801A02895283C010801A022952B26 +:10371000A33F00090A00211E8F8600340E0020D42A +:10372000000000000A0021658F8600343C1F08015C +:1037300093FF950C2419000113F902298F87006C5F +:103740003C100801921095103C06080190C6950E99 +:1037500010C000050200A0213C04080190849511CE +:10376000109001E48F870074001088408F9F0074D0 +:10377000023048210009C880033F702195D8000815 +:10378000270F0001A5CF00083C0408019084951183 +:103790003C05080190A5950E0E0020820000000057 +:1037A0008F870074023020210004308000C7202160 +:1037B0008C8500048F82007000A240230502000661 +:1037C000AC8200048C8A00008F83006C01431023BC +:1037D0005C400001AC8300008F86003490CB00FF7A +:1037E0002D6C00025580002D241400010230F821B8 +:1037F000001F40800107282190B9000B8CAE000407 +:103800000019C04003197821000F188000671021AB +:103810008C4D000001AE88232630FFFF5E00001FA4 +:10382000241400018C4400048CAA0000008A482360 +:1038300019200019240E00043C010801A02E950D4A +:1038400090AD000B8CAB0004000D8840022D802150 +:1038500000101080004710218C4400040164602394 +:10386000058202009443000890DF00FE90B9000B2F +:1038700033E500FF54B900040107A021A0D400FEE5 +:103880008F8700740107A0219284000B0E00208214 +:10389000240500018F860034241400011254009680 +:1038A0002E500001160000423C08FFFF24190002C0 +:1038B0001659FF3F00000000A0C000FF8F860034B3 +:1038C000A0D200090A0021658F86003490C7000944 +:1038D0002404000230E300FF1064016F2409000497 +:1038E000106901528F8800708CCE0054010E68233D +:1038F00025B1000106200175241800043C010801CF +:10390000A038950D3C010801A020950C90D400FD35 +:1039100090D200FF2E4F000215E0FF14328400FF0A +:10392000000438408F89007490DF00FF00E410210C +:10393000000220800089C8212FE500029324000B9B +:1039400014A0FF0A2407000200041840006480212C +:1039500000105880016928218CAC0004010C502310 +:103960000540FF02000000003C0308019063950E33 +:1039700014600005246F00013C010801A02495118A +:103980003C010801A027950F3C010801A02F950ECE +:1039900090CE00FF24E7000131CD00FF01A7882B66 +:1039A0001220FFE990A4000B0A002154000000003F +:1039B0003C0508018CA5950C3C12000400A8F824D5 +:1039C00013F20006240200053C0908019129950D17 +:1039D0001520000224020003240200053C01080116 +:1039E000A022952990C700FF14E0012024020002C4 +:1039F000A0C200090A0021658F86003490CC00FF28 +:103A00001180FEDA240A00018F8C00708F89007407 +:103A1000240F0003018068211160001E240E0002A3 +:103A2000000540400105A02100142080008990215C +:103A30008E510004019180230600FECC000000009E +:103A40003C0208019042950E1440000524580001E4 +:103A50003C010801A02A950F3C010801A025951101 +:103A60003C010801A038950E90DF00FF01051021F0 +:103A70000002C88033E500FF254A00010329202108 +:103A800000AA402B1500FEB99085000B1560FFE5DC +:103A9000000540400005404001051821000310804A +:103AA0003C010801A02A950C3C010801A0259510B5 +:103AB000004918218C64000400E4F82327F9FFFF73 +:103AC0001F20FFE9000000008C63000000E3582382 +:103AD0000560013A01A3882310E301170184C02384 +:103AE0001B00FEA2000000003C010801A02E950D65 +:103AF0000A002293240B0001240E0004A0CE00092A +:103B00003C0D08008DAD31F88F86003425A20001F0 +:103B10003C010800AC2231F80A00216500000000D9 +:103B20008CD9005C00F9C0231F00FE7B0000000060 +:103B30008CDF005C10FFFF658F8400708CC3005C1D +:103B400000834023250200011C40FF6000000000AC +:103B50008CC9005C2487000100E9282B10A0FE948A +:103B60003C0D80008DAB01043C0C0001016C502425 +:103B70001140FE8F240200103C010801A02295296B +:103B80000A002165000000008F9100708F860034CC +:103B900026220001ACC2005C0A002220241400018D +:103BA0008F8700342404FF800000882190E9000AF8 +:103BB0002414000101243025A0E6000A3C05080178 +:103BC00090A5950E3C040801908495110E0020826A +:103BD000000000008F8600348F85007490C800FDBF +:103BE000310700FF000740400107F821001FC08097 +:103BF0000305C8219323000BA0C300FD8F8500742B +:103C00008F86003403056021918F000B000F7040F8 +:103C100001CF6821000D8080020510218C4B00002F +:103C2000ACCB00548D8400048F830070006450235B +:103C3000194000022482000124620001010748218A +:103C4000ACC2005C0009308000C5402100E02021AA +:103C5000240500010E0020829110000B8F86003495 +:103C600090C500FF10A0FF0C001070408F850074FD +:103C700001D06821000D1080004558218D6400009E +:103C80008F8C0070018450232547000104E0FF025F +:103C9000263100013C0308019063950E2E2F00028F +:103CA000247800013C010801A038950E3C01080170 +:103CB000A034950F11E0FEF8020038210A0022F32B +:103CC000000740408F8400348F8300708C8500583B +:103CD00000A340230502FE9AAC8300580A0021C9C4 +:103CE000000000003C07080190E7952A240200FF2D +:103CF00010E200BE8F8600343C11080196319532E7 +:103D00003C03080124639530262500013230FFFF73 +:103D100030ABFFFF020360212D6A00FF1540008DCC +:103D2000918700043C010801A42095328F8800345B +:103D30000007484001272821911800FF0005308026 +:103D40002405000127140001A11400FF3C12080102 +:103D50009252952A8F8800748F8E006C264F000136 +:103D600000C820213C010801A02F952AAC8E00003C +:103D70008F8D0070A4850008AC8D00043C03080101 +:103D80009063950C14600077000090213C010801BD +:103D9000A025950CA087000B8F8C007400CC5021BF +:103DA000A147000A8F820034A04700FD8F840034B1 +:103DB000A08700FE8F8600348F9F006CACDF00541C +:103DC0008F990070ACD900588F8D00740127C021E5 +:103DD00000185880016DA021928F000A000F7040DA +:103DE00001CF182100038880022D8021A207000B3B +:103DF0008F86007401666021918A000B000A1040D2 +:103E0000004A20210004288000A64021A107000AC2 +:103E10003C07800834E900808D2200308F86003412 +:103E2000ACC2005C0A0022202414000190CA00FFEA +:103E30001540FEAD8F880070A0C400090A002165FE +:103E40008F860034A0C000FD8F9800342406000146 +:103E5000A30000FE3C010801A026950D3C010801CD +:103E6000A020950C0A0021540000000090CB00FF18 +:103E70003C0408019084952B316C00FF0184502B89 +:103E80001540000F2402000324020004A0C2000910 +:103E90000A0021658F86003490C3000A2410FF8039 +:103EA00002035824316C00FF1180FDC100000000A6 +:103EB0003C010801A020950D0A00215400000000DB +:103EC000A0C200090A0021658F86003490D4000A40 +:103ED0002412FF8002544824312800FF1500FFF40B +:103EE000240200083C010801A02295290A0021654E +:103EF00000000000001088408F8B006C02301821F9 +:103F00000003688001A72021AC8B00008F8A00701D +:103F1000240C0001A48C0008AC8A00043C050801B4 +:103F200090A5950E2402000110A2FE1E24A5FFFFFD +:103F30000A0021DF9084000B0184A0231A80FD8BEE +:103F4000000000003C010801A02E950D0A002293FC +:103F5000240B00013C010801A42595320A002345E9 +:103F60008F880034240B0001106B00228F980034DE +:103F70008F85003490BF00FF33F900FF1079002BCC +:103F8000000000003C1F080193FF9510001FC8406F +:103F9000033FC0210018A0800288782191EE000A1A +:103FA000A08E000A8F8D00743C0308019063951069 +:103FB00000CD88210A00236BA223000B26300001CC +:103FC0000600003101A490230640002B24020003C8 +:103FD0003C010801A02F950D0A002293240B00013B +:103FE0008F8900340A0021C9AD2700540A00221F1E +:103FF00024120001931400FDA094000B8F8800345C +:104000008F8F0074910E00FE00CF6821A1AE000AD0 +:104010008F910034A22700FD8F83006C8F900034B5 +:10402000AE0300540A00236C8F8D007490B000FE24 +:10403000A090000A8F8B00348F8C0074916A00FD71 +:1040400000CC1021A04A000B8F840034A08700FE12 +:104050008F8600708F850034ACA600580A00236C50 +:104060008F8D007494B80008ACA400040303782179 +:104070000A002213A4AF00083C010801A022950DFC +:104080000A0021540000000090CF0009240D000414 +:1040900031EE00FF11CDFD85240200013C01080135 +:0C40A000A022950D0A0021540000000031 +:0440AC000800334491 +:1040B0000800334408003420080033F4080033D8E3 +:1040C0000800332808003328080033280800334C40 +:1040D0008008010080080080800800005F86543757 +:1040E000E4AC62CC50103A4536621985BF14C0E882 +:1040F0001BC27A1E84F4B556094EA6FE7DDA01E78E +:10410000C04D7481080058D008005914080058B8F0 +:10411000080058B8080058B8080058B8080058D027 +:10412000080058B8080058B80800591C080058B8CA +:1041300008005830080058B8080058B80800591C42 +:10414000080058B8080058B8080058B8080058B80F +:10415000080058B8080058B8080058B8080058B8FF +:10416000080058B8080058B8080058F0080058B8B7 +:10417000080058F0080058B8080058B8080058B8A7 +:10418000080058F4080058F0080058B8080058B85B +:10419000080058B8080058B8080058B8080058B8BF +:1041A000080058B8080058B8080058B8080058B8AF +:1041B000080058B8080058B8080058B8080058B89F +:1041C000080058B8080058B8080058B8080058B88F +:1041D000080058B8080058B8080058F4080058F407 +:1041E000080058B8080058F4080058B8080058B833 +:1041F000080058B8080058B8080058B8080058B85F +:10420000080058B8080058B8080058B8080058B84E +:10421000080058B8080058B8080058B8080058B83E +:10422000080058B8080058B8080058B8080058B82E +:10423000080058B8080058B8080058B8080058B81E +:10424000080058B8080058B8080058B8080058B80E +:10425000080058B8080058B8080058B8080058B8FE +:10426000080058B8080058B8080058B8080058B8EE +:10427000080058B8080058B8080058B8080058B8DE +:10428000080058B8080058B8080058B8080058B8CE +:10429000080058B8080058B8080058B8080058B8BE +:1042A000080058B8080058B8080058B8080058B8AE +:1042B000080058B8080058B8080058B8080058B89E +:1042C000080058B8080058B8080058B8080058B88E +:1042D000080058B8080058B8080058B8080058B87E +:1042E000080058B8080058B8080058B8080058B86E +:1042F000080058B8080058B8080058B8080058B85E +:10430000080058B80800593808007688080078EC8A +:1043100008007694080074880800769408007720D6 +:10432000080076940800748808007488080074886F +:10433000080074880800748808007488080074886D +:10434000080074880800748808007488080076B42F +:10435000080076A40800748808007488080074882F +:10436000080074880800748808007488080074883D +:10437000080074880800748808007488080074882D +:1043800008007488080076A40800813408007FC003 +:10439000080080FC08007FC0080080CC08007EA8D0 +:1043A00008007FC008007FC008007FC008007FC0F1 +:1043B00008007FC008007FC008007FC008007FC0E1 +:1043C00008007FC008007FC008007FC008007FC0D1 +:1043D00008007FE808008B6C08008CC808008CA8D7 +:0843E0000800871008008B841F +:0843E8000A000124000000009E +:1043F000000000000000000D747061362E302E3178 +:10440000370000000600110100000000000000005D +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000000006C +:10445000000000000000000000000000000000005C +:10446000000000000000000000000000000000004C +:104470000000000000000000000000001000000329 +:10448000000000000000000D0000000D3C020800CC +:10449000244217203C03080024632A10AC4000008B +:1044A0000043202B1480FFFD244200043C1D080023 +:1044B00037BD2FFC03A0F0213C100800261004900B +:1044C0003C1C0800279C17200E0002620000000020 +:1044D0000000000D2402FF8027BDFFE000821024B1 +:1044E000AFB00010AF420020AFBF0018AFB1001452 +:1044F000936500043084007F034418213C020008C7 +:104500000062182130A50020036080213C080111C1 +:10451000277B000814A000022466005C2466005873 +:104520009202000497430104920400043047000FF4 +:104530003063FFFF308400400067282310800009AB +:10454000000048219202000530420004104000059E +:104550000000000010A000030000000024A5FFFCE4 +:1045600024090004920200053042000410400012A9 +:104570000000000010A000100000000096020002E1 +:1045800000A72021010440252442FFFEA742101667 +:10459000920300042402FF8000431024304200FFF5 +:1045A000104000033C0204000A000174010240258F +:1045B0008CC20000AF4210188F4201780440FFFE09 +:1045C0002402000AA74201409602000224040009C6 +:1045D000304200070002102330420007A742014288 +:1045E000960200022442FFFEA7420144A740014672 +:1045F00097420104A74201488F420108304200203F +:1046000050400001240400019202000430420010D6 +:10461000144000023483001000801821A743014A8F +:10462000000000000000000000000000000000008A +:10463000AF48100000000000000000000000000073 +:10464000000000008F4210000441FFFE3102FFFF16 +:1046500010400007000000009202000430420040B9 +:1046600014400003000000008F421018ACC200008C +:10467000960200063042FFFF24420002000210436F +:104680000002104003628821962200001120000DD4 +:104690003044FFFF00A710218F8300388F45101C86 +:1046A000000210820002108000431021AC4500007F +:1046B00030A6FFFF0E00058D00052C0200402021D2 +:1046C000A6220000920300042402FF80004310246D +:1046D000304200FF1040001F000000009202000561 +:1046E000304200021040001B000000009742100CF6 +:1046F0002442FFFEA7421016000000003C02040006 +:1047000034420030AF421000000000000000000002 +:1047100000000000000000008F4210000441FFFE76 +:10472000000000009742100C8F45101C3042FFFF24 +:10473000244200300002108200021080005B102131 +:10474000AC45000030A6FFFF0E00058D00052C02D1 +:10475000A622000096040002248400080E0001E94D +:104760003084FFFF974401040E0001F73084FFFFFF +:104770008FBF00188FB100148FB000103C021000E2 +:1047800027BD002003E00008AF4201783084FFFF1E +:10479000308200078F850024104000022483000728 +:1047A0003064FFF800A4102130421FFF034218219B +:1047B000247B4000AF850028AF82002403E000087E +:1047C000AF4200843084FFFF3082000F8F85002CC1 +:1047D0008F860034104000022483000F3064FFF005 +:1047E00000A410210046182BAF850030004620237E +:1047F00014600002AF82002CAF84002C8F82002C4A +:10480000340480000342182100641821AF8300386B +:1048100003E00008AF4200808F82001410400008BF +:104820008F8200048F82FFDC144000058F82000419 +:104830003C02FFBF3442FFFF008220248F8200042D +:1048400030430006240200021062000F3C02010106 +:104850002C62000350400005240200041060000F89 +:104860003C0200010A000230000000001062000556 +:10487000240200061462000C3C0201110A00022905 +:10488000008210253C02001100821025AF4210006A +:10489000240200010A000230AF82000C00821025C1 +:1048A000AF421000AF80000C0000000000000000CC +:1048B0000000000003E00008000000008F82000CF0 +:1048C00010400004000000008F4210000441FFFE71 +:1048D0000000000003E00008000000008F820010CC +:1048E0002443F800000231C224C2FFF02C6303010C +:1048F00010600003000210420A000257AC82000060 +:104900008F85001800C5102B1440000B00001821E3 +:1049100000C51023244700018F82001C00A2102133 +:104920002442FFFF0046102B544000042402FFFFE6 +:104930000A000257AC8700002402FFFF0A00026051 +:10494000AC8200008C820000000219400062182135 +:104950000003188000621821000318803C02080040 +:104960002442175C0062182103E000080060102157 +:1049700027BDFFD8AFBF0020AFB1001CAFB00018FB +:104980003C0460088C8250002403FF7F3C066000DA +:10499000004310243442380CAC8250008CC24C1CB2 +:1049A0003C1A8000000216023042000F104000073F +:1049B000AF82001C8CC34C1C3C02001F3442FC0024 +:1049C00000621824000319C2AF8300188F42000848 +:1049D000275B400034420001AF420008AF80002452 +:1049E0003C02601CAF400080AF4000848C45000852 +:1049F0008CC3080834028000034220212402FFF007 +:104A0000006218243C0200803C010800AC22042013 +:104A10003C025709AF84003814620004AF850034AB +:104A2000240200010A000292AF820014AF80001439 +:104A30008F42000038420001304200011440FFFC68 +:104A40008F820014104000160000000097420104FD +:104A5000104000058F830000146000072462FFFFF0 +:104A60000A0002A72C62000A2C62001050400004C9 +:104A70008F83000024620001AF8200008F8300005A +:104A80002C62000A144000032C6200070A0002AEE8 +:104A9000AF80FFDC1040000224020001AF82FFDC87 +:104AA0008F4301088F44010030622000AF8300046F +:104AB00010400008AF8400103C0208008C42042C17 +:104AC000244200013C010800AC22042C0A00058AA3 +:104AD0003C0240003065020014A0000324020F00D5 +:104AE0001482026024020D0097420104104002C8A3 +:104AF0003C02400030624000144000AD8F8200381C +:104B00008C4400088F4201780440FFFE2402080014 +:104B1000AF42017824020008A7420140A7400142A9 +:104B2000974201048F8400043051FFFF308200015E +:104B300010400007022080212623FFFE24020002ED +:104B40003070FFFFA74201460A0002DBA74301487D +:104B5000A74001463C0208008C42043C1440000D72 +:104B60008F830010308200201440000224030009CB +:104B700024030001006020218F830010240209001B +:104B80005062000134840004A744014A0A0002F67E +:104B90000000000024020F00146200053082002093 +:104BA000144000062403000D0A0002F5240300054A +:104BB000144000022403000924030001A743014A12 +:104BC0003C0208008C4204203C0400480E00020C09 +:104BD000004420250E000235000000008F82000CEA +:104BE0001040003E000000008F4210003C030020F7 +:104BF00000431024104000398F820004304200022C +:104C0000104000360000000097421014144000339A +:104C100000000000974210088F8800383042FFFFE4 +:104C200024420006000218820003388000E8302188 +:104C3000304300018CC400001060000430420003C7 +:104C40000000000D0A00033700E810215440001056 +:104C50003084FFFF3C05FFFF0085202400851826D7 +:104C60000003182B0004102B0043102410400005F3 +:104C700000000000000000000000000D0000000027 +:104C8000240002228CC200000A00033600452025C1 +:104C90003883FFFF0003182B0004102B004310245F +:104CA0001040000500000000000000000000000DA2 +:104CB000000000002400022B8CC200003444FFFFDF +:104CC00000E81021AC4400003C0208008C42043093 +:104CD000244200013C010800AC2204308F62000035 +:104CE0008F840038AF8200088C8300003402FFFFFD +:104CF0001462000F000010213C0508008CA504542C +:104D00003C0408008C84045000B0282100B0302BF3 +:104D100000822021008620213C010800AC2504549B +:104D20003C010800AC2404500A000580240400085B +:104D30008C820000304201001040000F0000102162 +:104D40003C0508008CA5044C3C0408008C840448F5 +:104D500000B0282100B0302B0082202100862021C5 +:104D60003C010800AC25044C3C010800AC2404487C +:104D70000A000580240400083C0508008CA50444B2 +:104D80003C0408008C84044000B0282100B0302B83 +:104D900000822021008620213C010800AC2504442B +:104DA0003C010800AC2404400A00058024040008EB +:104DB0008F6200088F62000000021602304300F08C +:104DC000240200301062000524020040106200E05E +:104DD0008F8200200A0005882442000114A00005EB +:104DE00000000000000000000000000D00000000B6 +:104DF000240002568F4201780440FFFE00000000AC +:104E00000E00023D27A40010144000050040802140 +:104E1000000000000000000D000000002400025D02 +:104E20008E0200001040000500000000000000009D +:104E30000000000D00000000240002608F62000CE2 +:104E400004430003240200010A00042EAE00000007 +:104E5000AE0200008F8200388C480008A2000007D4 +:104E60008F65000C8F64000430A3FFFF0004240250 +:104E700000852023308200FF0043102124420005DA +:104E8000000230832CC20081A605000A14400005F0 +:104E9000A2040004000000000000000D000000005B +:104EA000240002788F8500380E0005AB260400141C +:104EB0008F6200048F430108A60200083C02100024 +:104EC00000621824106000080000000097420104EE +:104ED000920300072442FFEC346300023045FFFFD9 +:104EE0000A0003C3A2030007974201042442FFF013 +:104EF0003045FFFF960600082CC200135440000501 +:104F0000920300079202000734420001A202000748 +:104F1000920300072402000110620005240200032E +:104F20001062000B8F8200380A0003E030C6FFFFDA +:104F30008F8200383C04FFFF8C43000C006418246F +:104F400000651825AC43000C0A0003E030C6FFFFE3 +:104F50003C04FFFF8C4300100064182400651825F2 +:104F6000AC43001030C6FFFF24C2000200021083D1 +:104F7000A20200058F830038304200FF000210803B +:104F8000004328218CA800008CA200002403000408 +:104F900000021702144300120000000097420104AF +:104FA0003C03FFFF010318243042FFFF004610239B +:104FB0002442FFFE00624025ACA8000092030005D9 +:104FC000306200FF00021080005010219042001457 +:104FD0003042000F004310210A000415A20200060F +:104FE0008CA40004974201049603000A3088FFFF56 +:104FF0003042FFFF004610232442FFD60002140077 +:1050000001024025ACA800049202000792040005AA +:10501000246300280003188300641821344200042C +:10502000A2030006A20200078F8200042403FFFBF4 +:105030003442000200431024AF82000492030006B1 +:105040008F87003800031880007010218C440020E6 +:105050003C02FFF63442FFFF008240240067182123 +:10506000AE04000CAC68000C920500063C03FF7F08 +:105070008E02000C0005288000B020213463FFFF61 +:10508000010330249488002600A72821004310241F +:10509000AE02000CAC860020AC880024ACA8001046 +:1050A00024020010A742014024020002A74001424E +:1050B000A7400144A7420146974201043C0400086E +:1050C0002442FFFEA7420148240200010E00020C08 +:1050D000A742014A9603000A9202000400431021ED +:1050E0002442000230420007000210233042000731 +:1050F0000E000235AE0200108F6200003C03080073 +:105100008C63044424040010AF8200089742010419 +:105110003042FFFF2442FFFE00403821000237C327 +:105120003C0208008C420440006718210067282BCD +:1051300000461021004510213C010800AC23044426 +:105140003C010800AC2204400A00051500000000E4 +:1051500014A0000500000000000000000000000D89 +:10516000000000002400030A8F4201780440FFFE83 +:10517000000000000E00023D27A4001414400005AA +:1051800000408021000000000000000D0000000031 +:10519000240003118E020000544000069202000712 +:1051A000000000000000000D000000002400031CAF +:1051B0009202000730420004104000058F82000474 +:1051C0002403FFFB3442000200431024AF8200049A +:1051D0008F62000404430008920200079202000656 +:1051E0008E03000CAE000000000210800050102161 +:1051F000AC430020920200073042000454400009F2 +:105200009602000A920200053C0300010002108091 +:10521000005010218C46001800C33021AC46001805 +:105220009602000A9206000427710008022020213D +:1052300000C2302124C60005260500140E0005AB6F +:1052400000063082920400068F6500043C027FFF56 +:1052500000042080009120218C8300043442FFFF51 +:1052600000A2282400651821AC83000492020007E4 +:105270009204000592030004304200041040001420 +:1052800096070008308400FF000420800091202150 +:105290008C860004974201049605000A306300FFE3 +:1052A0003042FFFF004310210045102130E3FFFF93 +:1052B000004310232442FFD830C6FFFF0002140031 +:1052C00000C23025AC8600040A0004C9920300071E +:1052D000308500FF0005288000B128218CA4000043 +:1052E00097420104306300FF3042FFFF004310216A +:1052F000004710233C03FFFF008320243042FFFFC0 +:1053000000822025ACA400009203000724020001C3 +:105310001062000600000000240200031062001169 +:10532000000000000A0004EC8E0300109742010404 +:10533000920300049605000A8E24000C00431021FD +:10534000004510212442FFF23C03FFFF008320248C +:105350003042FFFF00822025AE24000C0A0004EC3E +:105360008E03001097420104920300049605000A80 +:105370008E24001000431021004510212442FFEE2E +:105380003C03FFFF008320243042FFFF00822025E2 +:10539000AE2400108E0300102402000AA742014030 +:1053A000A74301429603000A920200043C04004015 +:1053B00000431021A7420144A7400146974201043F +:1053C000A7420148240200010E00020CA742014A34 +:1053D0000E000235000000008F62000092030004FE +:1053E00000002021AF820008974201049606000ABF +:1053F0003042FFFF00621821006028213C030800B2 +:105400008C6304443C0208008C420440006518216F +:10541000004410210065382B004710213C01080092 +:10542000AC2304443C010800AC2204409204000474 +:10543000008620212484000A3084FFFF0E0001E949 +:1054400000000000974401043084FFFF0E0001F7C4 +:10545000000000003C021000AF4201780A000587FE +:105460008F820020148200273062000697420104D8 +:10547000104000673C0240003062400010400005D0 +:1054800000000000000000000000000D000000000F +:10549000240004208F4201780440FFFE240208000B +:1054A000AF42017824020008A7420140A740014210 +:1054B0008F8200049743010430420001104000072E +:1054C0003070FFFF2603FFFE24020002A7420146C0 +:1054D000A74301480A00053F2402000DA7400146EA +:1054E0002402000DA742014A8F6200002404000834 +:1054F000AF8200080E0001E9000000000A00051953 +:1055000002002021104000423C0240009362000053 +:10551000304300F0240200101062000524020070E5 +:10552000106200358F8200200A00058824420001A5 +:105530008F620000974301043050FFFF3071FFFF7E +:105540008F4201780440FFFE320200070002102360 +:10555000304200072403000A2604FFFEA74301404F +:10556000A7420142A7440144A7400146A751014870 +:105570008F42010830420020144000022403000939 +:1055800024030001A743014A0E00020C3C04004022 +:105590000E000235000000003C0708008CE70444C0 +:1055A000021110212442FFFE3C0608008CC6044074 +:1055B0000040182100E33821000010218F65000011 +:1055C00000E3402B00C230212604000800C830212F +:1055D0003084FFFFAF8500083C010800AC2704447D +:1055E0003C010800AC2604400E0001E90000000068 +:1055F0000A000519022020210E00013B00000000D6 +:105600008F82002024420001AF8200203C02400033 +:10561000AF4201380A000292000000003084FFFF10 +:1056200030C6FFFF00052C0000A628253882FFFFAA +:10563000004510210045282B0045102100021C02C6 +:105640003042FFFF0043102100021C023042FFFFE6 +:10565000004310213842FFFF03E000083042FFFF03 +:105660003084FFFF30A5FFFF0000182110800007E5 +:1056700000000000308200011040000200042042BF +:10568000006518210A0005A10005284003E0000874 +:105690000060102110C0000624C6FFFF8CA200008D +:1056A00024A50004AC8200000A0005AB2484000499 +:1056B00003E000080000000010A0000824A3FFFF82 +:1056C000AC86000000000000000000002402FFFF84 +:1056D0002463FFFF1462FFFA2484000403E000083F +:0456E00000000000C6 +:0456E40000000001C1 +:0856E8000A00002A0000000086 +:1056F000000000000000000D747870362E302E314E +:105700003700000006001100000000000000013614 +:105710000000EA600000000000000000000000003F +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000160000000043 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000138800000000000005DC000000009D +:105790000000000010000003000000000000000DE9 +:1057A0000000000D3C02080024423D883C03080034 +:1057B0002463403CAC4000000043202B1480FFFDDC +:1057C000244200043C1D080037BD7FFC03A0F021EB +:1057D0003C100800261000A83C1C0800279C3D88AF +:1057E0000E00044E000000000000000D27BDFFB4B5 +:1057F000AFA10000AFA20004AFA30008AFA4000C4B +:10580000AFA50010AFA60014AFA70018AFA8001CEA +:10581000AFA90020AFAA0024AFAB0028AFAC002C8A +:10582000AFAD0030AFAE0034AFAF0038AFB8003C22 +:10583000AFB90040AFBC0044AFBF00480E000591B7 +:10584000000000008FBF00488FBC00448FB90040AB +:105850008FB8003C8FAF00388FAE00348FAD003072 +:105860008FAC002C8FAB00288FAA00248FA90020BA +:105870008FA8001C8FA700188FA600148FA50010FA +:105880008FA4000C8FA300088FA200048FA100003A +:1058900027BD004C3C1B60048F7A5030377B50286A +:1058A00003400008AF7A00008F86003C3C03900064 +:1058B0003C0280000086282500A32025AC4400205F +:1058C0003C0380008C67002004E0FFFE0000000025 +:1058D00003E00008000000000A000070240400013A +:1058E0008F85003C3C0480003483000100A3102518 +:1058F00003E00008AC82002003E000080000102153 +:105900003084FFFF30A5FFFF108000070000182142 +:10591000308200011040000200042042006518217E +:105920001480FFFB0005284003E000080060102100 +:1059300010C00007000000008CA2000024C6FFFF7A +:1059400024A50004AC82000014C0FFFB24840004E2 +:1059500003E000080000000010A0000824A3FFFFDF +:10596000AC86000000000000000000002402FFFFE1 +:105970002463FFFF1462FFFA2484000403E000089C +:105980000000000090AA00318FAB00108CAC0040EA +:105990003C0300FF8D680004AD6C00208CAD00441A +:1059A00000E060213462FFFFAD6D00248CA7004849 +:1059B0003C09FF000109C024AD6700288CAE004CF3 +:1059C0000182C82403197825AD6F0004AD6E002C48 +:1059D0008CAD0038314A00FFAD6D001C94A9003237 +:1059E0003128FFFFAD68001090A70030A5600002CD +:1059F000A1600004A167000090A30032306200FFA4 +:105A00000002198210600005240500011065000ED7 +:105A10000000000003E00008A16A00018CD8002803 +:105A2000354A0080AD7800188CCF0014AD6F00149B +:105A30008CCE0030AD6E00088CC4002CA16A000131 +:105A400003E00008AD64000C8CCD001CAD6D0018A7 +:105A50008CC90014AD6900148CC80024AD6800081E +:105A60008CC70020AD67000C8CC200148C830070C2 +:105A70000043C82B13200007000000008CC2001454 +:105A8000144CFFE400000000354A008003E00008E9 +:105A9000A16A00018C8200700A0000E6000000008C +:105AA0009089003027BDFFF88FA8001CA3A9000033 +:105AB0008FA300003C0DFF8035A2FFFF8CAC002CB3 +:105AC00000625824AFAB0000A100000400C05821C0 +:105AD000A7A000028D06000400A048210167C8218C +:105AE0008FA50000008050213C18FF7F032C20264A +:105AF0003C0E00FF2C8C0001370FFFFF35CDFFFF60 +:105B00003C02FF0000AFC82400EDC02400C278248E +:105B1000000C1DC00323682501F87025AD0D0000A1 +:105B2000AD0E00048D240024AFAD0000AD040008CC +:105B30008D2C00202404FFFFAD0C000C9547003293 +:105B400030E6FFFFAD0600109145004830A200FF8F +:105B5000000219C2506000018D240034AD0400140D +:105B60008D4700388FAA001827BD0008AD0B00280C +:105B7000AD0A0024AD07001CAD00002CAD000018DC +:105B800003E00008AD00002027BDFFE0AFB2001821 +:105B9000AFB10014AFB00010AFBF001C9098003040 +:105BA00000C088213C0D00FF330F007FA0CF000014 +:105BB000908E003135ACFFFF3C0AFF00A0CE000103 +:105BC00094A6001EA22000048CAB00148E290004B1 +:105BD00000A08021016C2824012A4024008090210B +:105BE00001052025A6260002AE240004260500207B +:105BF000262400080E00009224060002924700307E +:105C0000260500282624001400071E0000031603A2 +:105C100024060004044000032403FFFF96590032C9 +:105C20003323FFFF0E000092AE2300102624002431 +:105C30008FBF001C8FB200188FB100148FB00010FE +:105C400024050003000030210A00009C27BD00202D +:105C500027BDFFD8AFB1001CAFB00018AFBF002008 +:105C600090A900302402000100E050213123003FC0 +:105C700000A040218FB000400080882100C0482152 +:105C8000106200148FA70038240B000500A020210B +:105C900000C02821106B0013020030210E000128E3 +:105CA000000000009225007C30A400021080000358 +:105CB00026030030AE000030260300348FBF0020E2 +:105CC0008FB1001C8FB000180060102103E00008A5 +:105CD00027BD00280E0000A7AFB000100A00016F1A +:105CE000000000008FA3003C01002021012028219A +:105CF00001403021AFA300100E0000EEAFB0001441 +:105D00000A00016F000000003C06800034C20E0053 +:105D10008C4400108F850044ACA400208C430018F4 +:105D200003E00008ACA300243C06800034C20E004F +:105D30008C4400148F850044ACA400208C43001CCC +:105D400003E00008ACA300249382000C1040001B69 +:105D50002483000F2404FFF00064382410E00019AD +:105D6000978B00109784000E9389000D3C0A601CED +:105D70000A0001AC01644023010370210064282360 +:105D80001126000231C2FFFF30A2FFFF0047302B77 +:105D900050C0000E00E448218D4D000C31A3FFFFE0 +:105DA00000036400000C2C0304A1FFF30000302169 +:105DB00030637FFF0A0001A42406000103E000080D +:105DC000000000009784000E00E448213123FFFF0B +:105DD0003168FFFF0068382B54E0FFF8A783000EFE +:105DE000938A000D11400005240F0001006BC023B1 +:105DF000A380000D03E00008A798000E006BC023ED +:105E0000A38F000D03E00008A798000E03E0000830 +:105E10000000000027BDFFE8AFB000103C1080007C +:105E200036030140308BFFFF93AA002BAFBF001455 +:105E3000A46B000436040E009488001630C600FFE0 +:105E40008FA90030A4680006AC650008A0660012A7 +:105E5000A46A001AAC6700208FA5002CA469001862 +:105E6000012020210E000198AC6500143C021000B6 +:105E7000AE0201788FBF00148FB0001003E000085D +:105E800027BD00188F8500002484000727BDFFF878 +:105E90003084FFF83C06800094CB008A316AFFFF13 +:105EA000AFAA00008FA90000012540232507FFFFAE +:105EB00030E31FFF0064102B1440FFF700056882D9 +:105EC000000D288034CC400000AC102103E0000815 +:105ED00027BD00088F8200002486000730C5FFF828 +:105EE00000A2182130641FFF03E00008AF84000007 +:105EF0008F87003C8F84004427BDFFB0AFB70044BC +:105F0000AFB40038AFB1002CAFBF0048AFB600400F +:105F1000AFB5003CAFB30034AFB20030AFB0002833 +:105F20003C0B80008C860024AD6700808C8A0020AA +:105F300035670E0035690100ACEA00108C8800243A +:105F40008D2500040000B821ACE800188CE3001097 +:105F500000A688230000A021ACE300148CE2001806 +:105F6000ACE2001C122000FE00E0B021936C00089F +:105F7000118000F400000000976F001031EEFFFF69 +:105F8000022E682B15A000EF000000009772001091 +:105F90003250FFFFAED000003C0380008C74000044 +:105FA000329300081260FFFD0000000096D8000840 +:105FB0008EC700043305FFFF30B5000112A000E4D6 +:105FC000000000000000000D30BFA0402419004078 +:105FD00013F9011B30B4A000128000DF00000000A4 +:105FE000937300081260000800000000976D001015 +:105FF00031ACFFFF00EC202B1080000330AE0040DE +:1060000011C000D500000000A7850040AF87003810 +:106010009363000802202821AFB10020146000F52E +:1060200027B40020AF60000C978F004031F1400092 +:1060300016200002240300162403000E2405400746 +:10604000A363000AAF650014938A00428F700014A6 +:10605000315500010015124002024825AF690014B5 +:10606000979F00408F78001433F9001003194025E2 +:10607000AF680014979200403247000810E0016EAC +:10608000000000008F6700143C1210003C118000DB +:1060900000F27825AF6F001436230E00946E000ACC +:1060A0003C0D81002406000E31CCFFFF018D202520 +:1060B000AF640004A36600029373000A3406FFFC79 +:1060C000266B0004A36B000A979800403308200059 +:1060D0001100015F000000003C05800034A90E00A3 +:1060E000979900409538000C97870040001940426E +:1060F0003312C0003103000300127B0330F11000A3 +:10610000006F68250011720301AE6025000C20C0ED +:10611000A764001297930040936A000A0013598203 +:106120003175003C02AA10212450003CA3700009E4 +:10613000953F000C33F93FFFA779001097700012CC +:10614000936900090130F82127E5000230B9000702 +:106150000019C02333080007A368000B93710009DE +:1061600097720012976F0010322700FF8F9100384E +:10617000978D004000F21821006F702101C6602148 +:1061800031A6004010C000053185FFFF00B1102B83 +:106190003C12800010400017000098210225A82B17 +:1061A00056A0013E8FA500203C048000348A0E00DA +:1061B0008D5300143C068000AD5300108D4B001C25 +:1061C000AD4B0018AD4500008CCD000031AC00088F +:1061D0001180FFFD34CE0E0095C3000800A0882179 +:1061E00000009021A78300408DC600042413000105 +:1061F000AF860038976F001031F5FFFF8E9F0000CB +:1062000003F1282310A0011FAE850000936200084F +:10621000144000DD000000000E0001E7240400101F +:106220008F900048004028213C023200320600FFD7 +:10623000000654000142F82526090001AF890048F4 +:10624000ACBF00009379000997780012936F000AA1 +:10625000332800FF3303FFFF0103382100076C00E0 +:1062600031EE00FF01AE6025ACAC00048F84004825 +:10627000978B0040316A20001140010AACA400084D +:1062800097640012308BFFFF06400108ACAB000C96 +:10629000978E004031C5000814A000022628000691 +:1062A000262800023C1F800037E70E0094F90014F6 +:1062B0008CE5001C8F670004937800023324FFFFF5 +:1062C000330300FFAFA300108F6F0014AFA80018B6 +:1062D0000E0001CBAFAF0014240400100E0001FB30 +:1062E000000000008E920000164000050000000033 +:1062F0008F7800142403FFBF0303A024AF7400149D +:106300008F67000C00F5C821AF79000C9375000869 +:1063100016A0000800000000126000060000000047 +:106320008F6800143C0AEFFF3549FFFE0109F8248D +:10633000AF7F0014A37300088FA500200A00034F4D +:1063400002202021AED100000A00022D3C03800073 +:1063500014E0FF1E30BFA0400E0001900000A021FD +:106360002E9100010237B02512C000188FBF0048DF +:106370008F87003C24170F0010F700D43C068000E4 +:106380008CD901780720FFFE241F0F0010FF00F6B4 +:1063900034CA0E008D56001434C701402408024050 +:1063A000ACF600048D49001C3C141000ACE9000858 +:1063B000A0E00012A4E0001AACE00020A4E0001865 +:1063C000ACE80014ACD401788FBF00488FB700440C +:1063D0008FB600408FB5003C8FB400388FB30034C7 +:1063E0008FB200308FB1002C8FB0002803E000087E +:1063F00027BD00508F910038978800403C128000E4 +:106400000220A8213107004014E0FF7C0000982101 +:10641000977900108F9200383338FFFF131200A8CD +:10642000000020210080A021108000F300A088211E +:106430001620FECE000000000A00031F2E9100016E +:106440003C0380008C6201780440FFFE24080800B1 +:106450008F860000AC6801783C038000946D008A50 +:1064600031ACFFFF01865823256AFFFF31441FFF2F +:106470002C8900081520FFF9000000008F8F0048CC +:10648000347040008F83003C00E0A021240E0F00F8 +:1064900025E70001AF87004800D03021023488236F +:1064A0003C08800031F500FF106E00052407000154 +:1064B00093980042331300010013924036470001C5 +:1064C000001524003C0A0100008A4825ACC90000E0 +:1064D0008F82004830BF003630B90008ACC20004DB +:1064E0001320009900FF982535120E009650000ADF +:1064F0008F8700003C0F81003203FFFF24ED00086E +:1065000035060140006F60253C0E100031AB1FFFC7 +:10651000269200062405000EACCC0020026E9825C1 +:10652000A4C5001AAF8B0000A4D2001816200008E2 +:106530003C1080008F89003C24020F005122000291 +:1065400024170001367300400E0001883C108000C3 +:1065500036060E008CCB0014360A01400240202182 +:10656000AD4B00048CC5001CAD450008A1550012C0 +:10657000AD5300140E0001983C151000AE150178C3 +:106580000A00035200000000936F0009976E00128A +:10659000936D000B31E500FF00AE202131AC00FF10 +:1065A000008C80212602000A3050FFFF0E0001E718 +:1065B000020020218F8600483C0341003C058000FA +:1065C00024CB0001AF8B0048936A00099769001241 +:1065D00030C600FF315F00FF3128FFFF03E838219C +:1065E00024F900020006C4000319782501E3702590 +:1065F000AC4E00008F6D000C34A40E00948B001480 +:1066000001B26025AC4C00048C85001C8F6700042F +:10661000936A00023164FFFF314900FFAFA9001007 +:106620008F680014AFB100180E0001CBAFA80014A2 +:106630000A0002FD02002021AF600004A3600002F6 +:1066400097980040330820001500FEA30000302179 +:10665000A760001297840040936B000A3C108000F2 +:1066600030931F0000135183014BA82126A200285C +:10667000A362000936090E00953F000C0A0002953E +:10668000A77F00108F700014360900400E000188AB +:10669000AF6900140A0002C9000000000A00034F9D +:1066A000000020210641FEFAACA0000C8CAC000CCE +:1066B0003C0D8000018D90250A0002EAACB2000C6E +:1066C000000090210A0002C5241300011280000777 +:1066D0003C028000344B0E009566000830D3004029 +:1066E00012600049000000003C0680008CD0017858 +:1066F0000600FFFE34C50E0094B500103C030500F3 +:1067000034CC014032B8FFFF03039025AD92000C5A +:106710008CAF0014240D20003C041000AD8F000449 +:106720008CAE001CAD8E0008A1800012A580001A5E +:10673000AD800020A5800018AD8D0014ACC4017898 +:106740000A0003263C0680008F9F00003518014098 +:106750002692000227F9000833281FFFA71200180D +:106760000A000391AF8800003C02800034450140DC +:10677000ACA0000C1280001B34530E0034510E00EC +:106780008E370010ACB700048E2400183C0B80003C +:10679000ACA400083570014024040040A20000129F +:1067A0008FBF0048A600001A8FB70044AE0000203B +:1067B0008FB60040A60000188FB5003CAE04001450 +:1067C0008FB400388FB300348FB200308FB1002CFB +:1067D0008FB000283C02100027BD005003E00008E5 +:1067E000AD6201788E660014ACA600048E64001CB5 +:1067F0000A00042A3C0B80000E0001902E9100013B +:106800000A0003200237B025000000000000000D40 +:1068100000000000240003690A0004013C06800017 +:1068200027BDFFD8AFBF00203C0980003C1F20FFE0 +:10683000AFB200183C07600035320E002402001091 +:1068400037F9FFFDACE23008AFB3001CAFB1001464 +:10685000AFB00010AE5900000000000000000000C2 +:106860000000000000000000000000003C1800FFD5 +:106870003713FFFDAE5300003C0B60048D705000D9 +:106880002411FF7F3C0E00020211782435EC380CF5 +:1068900035CD0109ACED4C18240A0009AD6C50004F +:1068A0008CE80438AD2A0008AD2000148CE54C1C9F +:1068B0003106FFFF38C42F7100051E023062000F41 +:1068C0002486C0B310400007AF8200088CE54C1C42 +:1068D0003C09001F3528FC0000A81824000321C231 +:1068E000AF8400048CF108083C0F57092412F00013 +:1068F0000232702435F0001001D0602601CF6826E6 +:106900002DAA00012D8B0001014B382550E0000914 +:10691000A380000C3C1F601C8FF8000824190001A4 +:10692000A399000C33137C00A7930010A780000EDE +:10693000A380000DAF80004814C00003AF800000AA +:106940003C066000ACC0442C0E0005B93C10800031 +:106950000E000F24361101003C12080026523DF0B3 +:106960003C13080026733E708E030000386400015B +:10697000308200011440FFFC3C0B800A8E26000090 +:106980002407FF8024C90240312A007F014B4021A7 +:1069900001272824AE060020AF880044AE0500245D +:1069A0003C048000AF86003C8C8C01780580FFFEA3 +:1069B00024180800922F0008AC980178A38F004299 +:1069C000938E004231CD000111A0000F24050D006F +:1069D00024DFF8002FF903011320001C000629C250 +:1069E00024A4FFF000041042000231400E00020215 +:1069F00000D2D8213C0240003C068000ACC20138E5 +:106A00000A0004A00000000010C50023240D0F00A0 +:106A100010CD00273C1F800837F900809338000014 +:106A2000240E0050330F00FF15EEFFF33C02400030 +:106A30000E000A40000000003C0240003C068000BE +:106A4000ACC201380A0004A0000000008F830004DB +:106A500000A3402B1500000B8F8B0008006B50210A +:106A60002547FFFF00E5482B1520000600A3602303 +:106A7000000C19400E0002020073D8210A0004C461 +:106A80003C0240000000000D0E0002020000000069 +:106A90000A0004C43C0240003C1B0800277B3F70F6 +:106AA0000E000202000000000A0004C43C02400084 +:106AB0003C1B0800277B3F900E00020200000000F4 +:106AC0000A0004C43C0240003C0660043C09080083 +:106AD00025290104ACC9502C8CC850003C0580000D +:106AE0003C02000235070080ACC750003C0408009F +:106AF000248415A43C0308002463155CACA500089D +:106B0000ACA2000C3C010800AC243D803C01080014 +:106B1000AC233D8403E000082402000100A03021E2 +:106B20003C1C0800279C3D883C0C04003C0B0002E8 +:106B3000008B3826008C40262CE200010007502BE9 +:106B40002D050001000A48803C03080024633D80B5 +:106B5000004520250123182110800003000010218A +:106B6000AC6600002402000103E000080000000001 +:106B70003C1C0800279C3D883C0B04003C0A00029A +:106B8000008A3026008B38262CC200010006482BD4 +:106B90002CE50001000940803C03080024633D808F +:106BA0000045202501031821108000050000102158 +:106BB0003C0C0800258C155CAC6C00002402000124 +:106BC00003E00008000000003C0900023C0804004B +:106BD00000883026008938262CC300010080282137 +:106BE0002CE40001008310251040000B0000302130 +:106BF0003C1C0800279C3D883C0A80008D4E000804 +:106C00002406000101CA6825AD4D00088D4C000C1A +:106C100001855825AD4B000C03E0000800C0102191 +:106C20003C1C0800279C3D883C0580008CA6000C7D +:106C3000000420272402000100C4182403E00008F7 +:106C4000ACA3000C3C0200021082000B3C0560006B +:106C50003C070400108700030000000003E0000868 +:106C6000000000008CA908D0240AFFFD012A40245E +:106C700003E00008ACA808D08CA408D02406FFFECE +:106C80000086182403E00008ACA308D03C05601A75 +:106C900034A600108CC3008027BDFFF88CC500848B +:106CA000AFA3000093A4000024020001108200039F +:106CB000AFA5000403E0000827BD000893A700016A +:106CC00014E0001497AC000297B800023C0F80005B +:106CD000330EFFFC01CF6821ADA50000A3A000008A +:106CE0003C0660008CC708D02408FFFE3C04601AF4 +:106CF00000E82824ACC508D08FA300048FA20000B0 +:106D00003499001027BD0008AF22008003E000087E +:106D1000AF2300843C0B8000318AFFFC014B4821EB +:106D20008D2800000A00057DAFA8000427BDFFE8FC +:106D3000AFBF00103C1C0800279C3D883C0580002C +:106D40008CA4000C8CA200043C0300020044282404 +:106D500010A0000A00A318243C0604003C04000212 +:106D60001460000900A610241440000F3C04040025 +:106D70000000000D3C1C0800279C3D888FBF0010C0 +:106D800003E0000827BD00183C0208008C423D804B +:106D90000040F809000000003C1C0800279C3D88CA +:106DA0000A0005A68FBF00103C0208008C423D84FB +:106DB0000040F809000000000A0005AC00000000D7 +:106DC000000411C003E00008244202403C04080013 +:106DD00024843FD42405001A0A00009C00003021BE +:106DE00027BDFFE0AFB000103C108000AFBF00181F +:106DF000AFB1001436110100922200090E0005B651 +:106E00003044007F8E3F00008F89003C3C0F0080A3 +:106E100003E26021258800400049F821240DFF800D +:106E2000310E00783198007835F9000135F1000213 +:106E30000319382501D14825010D302403ED5824CC +:106E4000018D2824240A004024040080240300C06B +:106E5000AE0B0024AE000810AE0A0814AE040818E9 +:106E6000AE03081CAE050804AE070820AE060808ED +:106E7000AE090824360909009539000C3605098049 +:106E800033ED007F3338FFFF001889C0AE110800D2 +:106E9000AE0F0828952C000C8FBF00188FB100147E +:106EA000318BFFFF000B51C0AE0A002C8CA40050A8 +:106EB0008FB000108CA3003C8D2700048CA8001C10 +:106EC0008CA600383C0E800A01AE102127BD0020A0 +:106ED000AF820044AF840050AF830054AF87004CB2 +:106EE000AF88005C03E00008AF8600603C09080042 +:106EF00091293FF924A800023C05110000093C003B +:106F000000E8302500C5182524820008AC83000065 +:106F100003E00008AC8000043C0980003523090030 +:106F20009128010B906A001124020028008048215A +:106F3000314700FF00A0702100C0682131080040E7 +:106F400010E20002340C86DD240C08003C0A8000AC +:106F500035420A9A94470000354B0A9C35460AA0F0 +:106F600030F9FFFFAD3900008D780000354B0A8005 +:106F700024040001AD3800048CCF0000AD2F0008C0 +:106F80009165001930A300031064009A2864000280 +:106F9000148000B924050002106500A8240F000326 +:106FA000106F00BE35450AA4240A0800118A004D5E +:106FB00000000000510000423C0B80003C048000B7 +:106FC000348309009067001230E200FF004D782101 +:106FD000000FC880272400013C0A8000354F0900BB +:106FE00091E50019354C09808D87002830A300FFFA +:106FF00000031500004758250004C4003C19600038 +:1070000001793025370806FFAD260000AD280004C1 +:107010008DEA002C25280028AD2A00088DEC0030D0 +:10702000AD2C000C8DE50034AD2500108DE400384A +:10703000AD2400148DE3001CAD2300188DE7002063 +:10704000AD27001C8DE20024AD2200208DF9002820 +:10705000AD3900243C0980003526093C8CCF000066 +:10706000352A0100AD0E0004AD0F00008D4E000C5E +:107070003523090035250980AD0E0008906C0012FB +:107080008D47000C8CB900343C18080093183FF869 +:10709000318200FF004D582103277823000B370071 +:1070A0000018240000C4702531E9FFFC01C96825DF +:1070B00025020014AD0D000C03E00008AD00001027 +:1070C00035780900930600123C05080094A53FE8B6 +:1070D00030C800FF010D5021000A60800A00063C04 +:1070E0000185202115000060000000003C08080018 +:1070F00095083FEE3C06080094C63FE801061021C3 +:107100003C0B80003579090093380011932A00194F +:1071100035660A80330800FF94CF002A0008608299 +:10712000314500FF978A0058000C1E00000524001E +:107130003047FFFF006410250047C02501EA3021D9 +:107140003C0B4000030B402500066400AD28000006 +:10715000AD2C0004932500183C03000625280014DC +:1071600000053E0000E31025AD2200088F24002C0E +:10717000254F000131EB7FFFAD24000C8F38001C40 +:10718000A78B0058AD3800103C0980003526093C1B +:107190008CCF0000352A0100AD0E0004AD0F0000B9 +:1071A0008D4E000C3523090035250980AD0E0008F1 +:1071B000906C00128D47000C8CB900343C1808000C +:1071C00093183FF8318200FF004D582103277823A0 +:1071D000000B37000018240000C4702531E9FFFCC3 +:1071E00001C9682525020014AD0D000C03E000085C +:1071F000AD0000103C02080094423FF23C0508003C +:1072000094A53FE835440AA43C07080094E73FE40E +:10721000948B00000045C8210327C023000B1C00ED +:107220002706FFF200665025AD2A000CAD200010A5 +:10723000AD2C00140A00063025290018354F0AA489 +:1072400095E50000956400280005140000043C004A +:107250003459810000EC5825AD39000CAD2B0010DD +:107260000A000630252900143C0C0800958C3FEEDE +:107270000A000686258200015460FF4C240A08009B +:1072800035580AA49706000000061C00006C502523 +:10729000AD2A000C0A000630252900103C03080026 +:1072A00094633FF23C07080094E73FE83C0F080076 +:1072B00095EF3FE494A40000957900280067102121 +:1072C000004F582300041C00001934002578FFEEFD +:1072D00000D87825346A8100AD2A000CAD2F00104B +:1072E000AD200014AD2C00180A0006302529001C22 +:1072F00003E00008240207D027BDFFE0AFB200186A +:10730000AFB10014AFB00010AFBF001C0E00007C86 +:10731000008088218F8800548F87004C3C058008AE +:1073200034B20080011128213C108000240200802A +:10733000240300C000A72023AE0208183C068008E2 +:10734000AE03081C18800004AF850054ACC50004CF +:107350008CC90004AF89004C122000093604098052 +:107360000E00070200000000924C00278E0B0074F4 +:1073700001825004014B3021AE46000C36040980D6 +:107380008C8E001C8F8F005C01CF682319A0000435 +:107390008FBF001C8C90001CAF90005C8FBF001C46 +:1073A0008FB200188FB100148FB000100A00007E59 +:1073B00027BD00208F8600508F8300548F82004CA1 +:1073C0003C05800834A40080AC860050AC83003CAF +:1073D00003E00008ACA200043C0308008C630054E6 +:1073E00027BDFFF8308400FF2462000130A500FFB4 +:1073F0003C010800AC22005430C600FF3C0780006E +:107400008CE801780500FFFE3C0C7FFFA3A400037D +:107410008FAA0000358BFFFF014B4824000627C0D0 +:1074200001244025AFA8000034E201009043000A87 +:10743000A3A000023C1980FFA3A300018FAF0000AE +:1074400030AE007F3738FFFF01F86024000E6E0079 +:107450003C0A002034E50140018D582535492000C3 +:107460002406FF803C04100027BD0008ACAB000CD4 +:10747000ACA90014A4A00018A0A6001203E0000804 +:10748000ACE40178308800FF30A700FF3C038000A7 +:107490008C6201780440FFFE3C0C8000358A0A00B3 +:1074A0008D4B00203584014035850980AC8B00046C +:1074B0008D4900240007302B00061540AC890008D8 +:1074C000A088001090A3004CA083002D03E00008CA +:1074D000A480001827BDFFE8308400FFAFBF001074 +:1074E0000E00076730A500FF8F8300548FBF001088 +:1074F0003C06800034C50140344700402404FF901E +:107500003C02100027BD0018ACA3000CA0A4001280 +:10751000ACA7001403E00008ACC2017827BDFFE06F +:107520003C088008AFBF001CAFB20018AFB1001418 +:10753000AFB00010351000808E0600183C078000A8 +:10754000309200FF00C72025AE0400180E00007C1A +:1075500030B100FF92030005346200080E00007E87 +:10756000A2020005024020210E00077B02202821F4 +:10757000024020218FBF001C8FB200188FB1001471 +:107580008FB0001024050005240600010A00073C06 +:1075900027BD00203C05800034A3098090660008C8 +:1075A00030C200081040000F3C0A01013549080AAA +:1075B000AC8900008CA80074AC8800043C0708006B +:1075C00090E73FF830E5001050A00008AC800008BC +:1075D0003C0D800835AC00808D8B0058AC8B0008CA +:1075E0002484000C03E00008008010210A0007BF7B +:1075F0002484000C27BDFFE83C098000AFB00010D8 +:10760000AFBF00143526098090C800092402000687 +:1076100000A05821310300FF352709000080802198 +:10762000240500041062007B2408000294CF005C53 +:107630003C0E020431EDFFFF01AE6025AE0C0000F0 +:1076400090CA0008314400201080000800000000AB +:1076500090C2004E3C1F010337F90300305800FF71 +:107660000319302524050008AE06000490F9001126 +:1076700090E6001290E40011333800FF0018708289 +:1076800030CF00FF01CF5021014B6821308900FF2E +:1076900031AAFFFF39230028000A60801460002C03 +:1076A000020C482390E400123C198000372F01009F +:1076B000308C00FF018B1821000310800045F82159 +:1076C000001F8400360706FFAD270004373F09007E +:1076D00093EC001193EE0012372609800005C0825A +:1076E0008DE4000C8CC5003431CD00FF01AB1021BE +:1076F0000058182100A4F8230008840000033F006C +:1077000000F0302533F9FFFF318F00FC00D97025E0 +:107710000158202101E9682100045080ADAE000C21 +:107720000E00007C012A80213C088008240B000404 +:10773000350500800E00007EA0AB0009020010217C +:107740008FBF00148FB0001003E0000827BD0018A1 +:1077500090EC001190E300193C18080097183FEED8 +:10776000318200FF0002F882307000FF001FCE005F +:1077700000103C000327302500D870253C0F400046 +:1077800001CF68253C198000AD2D0000373F09006E +:1077900093EC001193EE0012372F01003726098079 +:1077A0000005C0828DE4000C8CC5003431CD00FF93 +:1077B00001AB10210058182100A4F8230008840010 +:1077C00000033F0000F0302533F9FFFF318F00FC4C +:1077D00000D970250158202101E96821000450805A +:1077E000ADAE000C0E00007C012A80213C08800810 +:1077F000240B0004350500800E00007EA0AB0009BC +:10780000020010218FBF00148FB0001003E00008A9 +:1078100027BD00180A0007D12408001227BDFFD099 +:107820003C038000AFB60028AFB50024AFB4002001 +:10783000AFB10014AFBF002CAFB3001CAFB2001843 +:10784000AFB000103467010090E6000B309400FFE9 +:1078500030B500FF30C200300000B0211040009968 +:1078600000008821346409809088000800082E00F8 +:1078700000051E03046000C0240400048F86005429 +:107880003C010800A0243FF83C0C8000AD8000487B +:107890003C048000348E010091CD000B31A5002006 +:1078A00010A000073C078000349309809272000802 +:1078B0000012860000107E0305E000C43C1F800813 +:1078C00034EC0100918A000B34EB098091690008C7 +:1078D000314400400004402B3123000800C89823A5 +:1078E0001460000224120003000090213C1080006C +:1078F00036180A8036040900970E002C9083001178 +:107900009089001293050018307F00FF312800FF96 +:10791000024810210002C880930D0018033F78210F +:1079200001F1302130B100FF00D11821A78E00589D +:107930003C010800A4263FEE3C010800A4233FF0D0 +:1079400015A00002000000000000000D920B010BCA +:107950003065FFFF3C010800A4233FF2316A00407C +:107960003C010800A4203FE83C010800A4203FE4BB +:107970001140000224A4000A24A4000B3091FFFF50 +:107980000E0001E7022020219206010B3C0C0800AA +:10799000958C3FF2004020210006698231A700014A +:1079A0000E000601018728210040202102602821C5 +:1079B0000E00060C024030210E0007AB00402021D3 +:1079C00016C00069004020219212010B325600407F +:1079D00012C000053C0500FF8C93000034AEFFFF91 +:1079E000026E8024AC9000000E0001FB02202021DA +:1079F0003C0F080091EF3FF831F100031220001610 +:107A00003C1380088F8200543C0980083528008090 +:107A1000245F0001AD1F003C3C0580088CB90004C8 +:107A200003E02021033FC0231B000002AF9F00544E +:107A30008CA400040E000702ACA400043C078000E4 +:107A40008CEB00743C04800834830080004B502190 +:107A5000AC6A000C3C138008367000800280202144 +:107A600002A02821A200006B0E0007673C148000D2 +:107A70008F920054368C0140AD92000C8F860048E6 +:107A80003C151000344D000624D60001AF96004886 +:107A90008FBF002CA18600128FB60028AD8D001478 +:107AA0008FB3001CAE9501788FB200188FB50024FB +:107AB0008FB400208FB100148FB0001003E00008D5 +:107AC00027BD003034640980908F0008000F7600D5 +:107AD000000E6E0305A00033347F090093F8001BED +:107AE000241900103C010800A0393FF833130002AC +:107AF0001260FF678F8600548F8200601446FF6516 +:107B00003C0480000E00007C000000003C04800863 +:107B10003485008090A8000924060016310300FF78 +:107B20001066000D0000000090AB00093C07080043 +:107B300090E73FF824090008316400FF34EA0001AF +:107B40003C010800A02A3FF81089002F240C000AED +:107B5000108C00282402000C0E00007E00000000A3 +:107B60000A00086A8F8600540E0007C302402821CD +:107B70000A0008B8004020213C0B8008356A0080CC +:107B80008D4600548CE9000C1120FF3DAF86005457 +:107B9000240700143C010800A0273FF80A000869E8 +:107BA0003C0C800090910008241200023C01080067 +:107BB000A0323FF8323000201200000B24160001E2 +:107BC0008F8600540A00086A2411000837F80080E4 +:107BD0008F020038AFE200048FF90004AF19003CB7 +:107BE0000A0008763C0780008F8600540A00086A65 +:107BF00024110004A0A200090E00007E0000000075 +:107C00000A00086A8F860054240200140A000944FE +:107C1000A0A2000927BDFFE8AFB000103C10800013 +:107C2000AFBF001436020100904400090E00076740 +:107C3000240500013C0480089099000E34830080E4 +:107C4000909F000F906F00269089000A33F800FF84 +:107C500000196E000018740031EC00FF01AE5025D1 +:107C6000000C5A00014B3825312800FF3603014033 +:107C70003445600000E830252402FF813C041000F8 +:107C8000AC66000C8FBF0014AC650014A06200123B +:107C9000AE0401788FB0001003E0000827BD001883 +:107CA00027BDFFE8308400FFAFBF00100E0007675C +:107CB00030A500FF3C05800034A40140344700405B +:107CC0002406FF92AC870014A08600128F83005414 +:107CD0008FBF00103C02100027BD0018AC83000CC1 +:107CE00003E00008ACA2017827BDFFD8AFB00010B8 +:107CF000308400FF30B000FF3C058000AFB10014BD +:107D0000AFBF0020AFB3001CAFB20018000410C218 +:107D100034A6010032030002305100011460000754 +:107D200090D200093C098008353300809268000534 +:107D30003107000810E0000C308A001002402021BA +:107D40000E00078D02202821240200018FBF002091 +:107D50008FB3001C8FB200188FB100148FB00010C9 +:107D600003E0000827BD00281540003434A50A00B0 +:107D70008CB800248CAF0008130F004B0000382192 +:107D80003C0D800835B30080926C00682406000228 +:107D9000318B00FF116600843C06800034C2010074 +:107DA0009263004C90590009307F00FF53F90004A2 +:107DB0003213007C10E00069000000003213007CE8 +:107DC0005660005C0240202116200009320D00019F +:107DD0003C0C800035840100358B0A008D65002441 +:107DE0008C86000414A6FFD900001021320D00017A +:107DF00011A0000E024020213C1880003710010025 +:107E00008E0F000C8F8E005011EE00080000000055 +:107E10000E00084D022028218E19000C3C1F8008FE +:107E200037F00080AE190050024020210E00077B81 +:107E3000022028210A000999240200013C050800BB +:107E40008CA5006424A400013C010800AC2400645B +:107E50001600000D00000000022028210E00077B04 +:107E600002402021926E0068240C000231CD00FFF8 +:107E700011AC0022024020210E00094B000000003E +:107E80000A000999240200010E0000702404000178 +:107E9000926B0025020B30250E00007EA2660025A5 +:107EA0000A0009DD022028218E6200188CDF000400 +:107EB0008CB9002400021E0217F9FFB13065007F63 +:107EC0009268004C264400013093007F1265004008 +:107ED000310300FF1464FFAB3C0D8008264700010E +:107EE00030F1007F30E200FF1225000B2407000173 +:107EF000004090210A0009A6241100012405000475 +:107F00000E00073C240600010E00094B0000000093 +:107F10000A000999240200012405FF80024520245B +:107F200000859026324200FF004090210A0009A6F9 +:107F3000241100010E00084D0220282132070030D4 +:107F400010E0FFA132100082024020210E00078DB8 +:107F5000022028210A000999240200018E690018D4 +:107F60000240202102202821012640250E00096E12 +:107F7000AE6800189264004C24050003240600013A +:107F80000E00073C308400FF0E0000702404000146 +:107F900092710025021150250E00007EA26A002574 +:107FA0000A000999240200018E6F00183C18800015 +:107FB0000240202101F87025022028210E00077BB5 +:107FC000AE6E00189264004C0A000A2524050004D5 +:107FD000324A0080394900801469FF6A3C0D8008EC +:107FE0000A0009FE2647000127BDFFC0AFB00018F8 +:107FF0003C108000AFBF0038AFB70034AFB60030E0 +:10800000AFB5002CAFB40028AFB30024AFB200204E +:108010000E0005BEAFB1001C360201009045000BFA +:108020000E00098090440008144000E78FBF00381C +:108030003C08800835070080A0E0006B3606098008 +:1080400090C50000240300503C17080026F73FB0FD +:1080500030A400FF3C13080026733FC010830003C8 +:108060003C1080000000B82100009821241F00105F +:108070003611010036120A00361509808E58002488 +:108080008E3400048EAF00208F8C00543C01080019 +:10809000A03F3FF836190A80972B002C8EF600007F +:1080A000932A00180298702301EC68233C01080011 +:1080B000AC2E3FD43C010800AC2D3FD83C01080059 +:1080C000AC2C3FFCA78B005802C0F809315400FFCC +:1080D00030490002152000E930420001504000C440 +:1080E0009227000992A90008312800081500000213 +:1080F000241500030000A8213C0A80003543090034 +:1081000035440A008C8D002490720011907000128A +:10811000907F0011325900FF321100FF02B110218F +:108120000002C08033EF00FF0319B021028F7021DD +:1081300002D4602125CB00103C010800A4363FEE9C +:108140003C010800AC2D40003C010800A42C3FF08D +:108150003C010800A42B3FEC355601003554098042 +:1081600035510E008F8700548F89005C8E8500206A +:1081700024080006012730233C010800AC283FF406 +:1081800000A7282304C000B50000902104A000B37C +:1081900000C5502B114000B5000000003C01080054 +:1081A000AC263FD88E6200000040F80900000000B5 +:1081B0003046000214C0007400408021304B0001A2 +:1081C000556000118E6200043C0D08008DAD3FDC4F +:1081D0003C0EC0003C04800001AE6025AE2C0000C7 +:1081E0008C980000330F000811E0FFFD0000000034 +:1081F000963F000824120001A79F00408E3900041A +:10820000AF9900388E6200040040F80900000000B9 +:108210000202802532030002146000B30000000057 +:108220003C09080095293FE43C06080094C63FF04D +:108230003C0A0800954A3FE63C0708008CE73FDC13 +:10824000012670213C0308008C6340003C080800B4 +:1082500095083FFA01CA20218ED9000C00E9282197 +:10826000249F000200A878210067C02133E4FFFFAB +:10827000AF9900503C010800AC3840003C010800B8 +:10828000A42F3FE83C010800A42E3FF20E0001E7B6 +:10829000000000008F8D0048004020213C010800B4 +:1082A000A02D3FF98E62000825AC0001AF8C00487C +:1082B0000040F809000000008F85005402A0302122 +:1082C0000E00060C004020210E0007AB00402021CC +:1082D0008E6B000C0160F809004020213C0A080068 +:1082E000954A3FF23C06080094C63FE60146482105 +:1082F000252800020E0001FB3104FFFF3C050800A9 +:108300008CA53FD43C0708008CE73FDC00A7202366 +:108310003C010800AC243FD414800006000000009B +:108320003C0208008C423FF4344B00403C01080002 +:10833000AC2B3FF4124000438F8E00448E2D001072 +:108340008F920044AE4D00208E2C0018AE4C0024BD +:108350003C04080094843FE80E000704000000007D +:108360008F9F00548E6700103C010800AC3F3FFC1B +:1083700000E0F809000000003C1908008F393FD4E4 +:108380001720FF798F870054979300583C11800E77 +:10839000321601000E000733A633002C16C000452C +:1083A000320300105460004C8EE500043208004097 +:1083B0005500001D8EF000088EE4000C0080F809C6 +:1083C000000000008FBF00388FB700348FB6003038 +:1083D0008FB5002C8FB400288FB300248FB20020FB +:1083E0008FB1001C8FB0001803E0000827BD0040CB +:1083F0008F86003C36110E0000072E0000A62025B7 +:10840000AE0400808E4300208E500024AFA30010E5 +:10841000AE2300148FB20010AE320010AE30001C3C +:108420000A000A7FAE3000180200F80900000000C0 +:108430008EE4000C0080F809000000000A000B38F0 +:108440008FBF003824180001240F0001A5C00020B0 +:10845000A5D800220A000B1AADCF00243C01080069 +:10846000AC203FD80A000AB08E6200003C01080030 +:10847000AC253FD80A000AB08E62000092240009A1 +:108480000E00077B000028218FBF00388FB7003413 +:108490008FB600308FB5002C8FB400288FB3002426 +:1084A0008FB200208FB1001C8FB0001803E00008CD +:1084B00027BD00403C14800092950109000028214E +:1084C0000E00084D32A400FF320300105060FFB8C8 +:1084D000320800408EE5000400A0F809000000000A +:1084E0000A000B32320800405240FFA89793005810 +:1084F0008E3400148F930044AE7400208E35001C1F +:10850000AE7500240A000B29979300588F8200143F +:108510000004218003E00008008210213C0780084D +:1085200034E200809043006900804021106000091F +:108530003C0401003C0708008CE73FFC8F830030BF +:1085400000E32023048000089389001C14E3000347 +:108550000100202103E00008008010213C040100FC +:1085600003E00008008010211120000B0067382371 +:108570003C0D800035AC0980918B007C316A000293 +:10858000114000202409003400E9702B15C0FFF1D0 +:108590000100202100E938232403FFFC00A3C824A4 +:1085A00000E3C02400F9782B15E0FFEA030820213E +:1085B00030C400030004102314C000143049000329 +:1085C0000000302100A9782101E6702100EE682B1F +:1085D00011A0FFE03C0401002D3800010006C82B6B +:1085E000010548210319382414E0FFDA2524FFFC93 +:1085F0002402FFFC00A218240068202103E00008E8 +:10860000008010210A000BA8240900303C0C8000D7 +:108610003586098090CB007C316A00041540FFE963 +:10862000240600040A000BB7000030213C030800B8 +:108630008C63005C8F82001827BDFFE0AFBF00187D +:10864000AFB1001410620005AFB00010000329C0E4 +:1086500024A40280AF840014AF8300183C10800073 +:1086600036020A0094450032361101000E000B89D3 +:1086700030A43FFF8E240000241FFF803C110080A7 +:108680000082C021031F60243309007F000CC94011 +:1086900003294025330E0078362F00033C0D1000CF +:1086A000010D502501CF5825AE0C00283608098051 +:1086B000AE0C080CAE0B082CAE0A08309103006912 +:1086C0003C06800C0126382110600006AF8700347C +:1086D0008D09003C8D03006C0123382318E00082D3 +:1086E000000000003C0B8008356A00803C108000D0 +:1086F000A1400069360609808CC200383C06800023 +:1087000034C50A0090A8003C310C00201180001AEA +:10871000AF820030240D00013C0E800035D10A00EC +:10872000A38D001CAF8000248E2400248F8500249C +:10873000240D0008AF800020AF8000283C01080015 +:10874000A42D3FE63C010800A4203FFA0E000B8D4B +:10875000000030219228003C8FBF00188FB1001418 +:108760008FB0001000086142AF82002C27BD0020AE +:1087700003E000083182000190B80032240E0001AD +:10878000330F00FF000F2182108E004124190002D8 +:108790001099006434C40AC03C03800034640A00A9 +:1087A0008C8F002415E0001E34660900909F003075 +:1087B0002418000533F9003F1338004E240300014C +:1087C0008F860020A383001CAF860028AF8600247C +:1087D0003C0E800035D10A008E2400248F850024B1 +:1087E000240D00083C010800A42D3FE63C010800D0 +:1087F000A4203FFA0E000B8D000000009228003CE0 +:108800008FBF00188FB100148FB0001000086142B4 +:10881000AF82002C27BD002003E000083182000158 +:108820008C8A00088C8B00248CD000643C0E800065 +:1088300035D10A00014B2823AF900024A380001CEF +:10884000AF8500288E2400248F8600208F85002489 +:10885000240D00083C010800A42D3FE63C0108005F +:10886000A4203FFA0E000B8D000000009228003C6F +:108870008FBF00188FB100148FB000100008614244 +:10888000AF82002C27BD002003E0000831820001E8 +:1088900090A200303051003F5224002834C50AC055 +:1088A0008CB000241600002234CB09008CA60048AE +:1088B0003C0A7FFF3545FFFF00C510243C0E8000B9 +:1088C000AF82002035C509008F8800208CAD006084 +:1088D000010D602B15800002010020218CA4006096 +:1088E0000A000C2CAF8400208D02006C0A000C06DC +:1088F0003C0680008C8200488F8600203C097FFF68 +:108900003527FFFF004788243C048008240300012A +:10891000AF910028AC80006CA383001C0A000C3AC5 +:10892000AF8600248C9F00140A000C2CAF9F0020FF +:108930008D6200680A000C763C0E800034C4098009 +:108940008C8900708CA300140123382B10E00004E4 +:10895000000000008C8200700A000C763C0E800043 +:108960008CA200140A000C763C0E80008F85002437 +:1089700027BDFFE0AFBF0018AFB1001414A000087E +:10898000AFB000103C04800034870A0090E600304D +:108990002402000530C3003F106200B9348409008E +:1089A0008F91002000A080213C048000348E0A00BA +:1089B0008DCD00043C0608008CC63FD831A73FFF90 +:1089C00000E6602B5580000100E03021938F001CF1 +:1089D00011E0007800D0282B349F098093F9007CA7 +:1089E00033380002130000792403003400C3102B35 +:1089F000144000D90000000000C3302300D0282B11 +:108A00003C010800A4233FE414A0006E02001821DA +:108A10003C0408008C843FD40064402B55000001C6 +:108A2000006020213C05800034A90A00912A003C06 +:108A30003C010800AC243FDC3143002014600003FB +:108A40000000482134AB0E008D6900188F88002C7F +:108A50000128202B1080005F000000003C0508006A +:108A60008CA53FDC00A96821010D602B1180005C02 +:108A700000B0702B0109382300E028213C010800D8 +:108A8000AC273FDC12000003240AFFFC10B0008D6D +:108A90003224000300AA18243C010800A4203FFA55 +:108AA0003C010800AC233FDC006028218F840024B7 +:108AB000120400063C0B80088D6C006C0200202123 +:108AC000AF91002025900001AD70006C8F8D0028C3 +:108AD00000858823AF91002401A52023AF840028BE +:108AE0001220000224070018240700103C188008F8 +:108AF0003706008090CF00683C010800A0273FF8AF +:108B00002407000131EE00FF11C7004700000000FC +:108B100014800018000028213C06800034D1098010 +:108B200034CD010091A600098E2C001824C4000148 +:108B3000000C86023205007F308B007F1165007FBC +:108B40002407FF803C19800837290080A124004CAD +:108B50003C0808008D083FF4241800023C0108007E +:108B6000A0384039350F00083C010800AC2F3FF415 +:108B7000240500103C02800034440A009083003C2D +:108B8000307F002013E0000500A02021240A00010E +:108B90003C010800AC2A3FDC34A400018FBF001860 +:108BA0008FB100148FB000100080102103E0000886 +:108BB00027BD00203C010800A4203FE410A0FF9442 +:108BC000020018210A000CCA00C018210A000CC1BA +:108BD000240300303C0508008CA53FDC00B0702B5E +:108BE00011C0FFA8000000003C19080097393FE4BD +:108BF0000325C0210307782B11E000072CAA0004ED +:108C00003C0360008C625404305F003F17E0FFE3D8 +:108C1000240400422CAA00041140FF9A24040042BC +:108C20000A000D2E8FBF00181528FFB900000000A4 +:108C30008CCA00183C1F800024020002015F182526 +:108C4000ACC3001837F90A00A0C200689329003CA1 +:108C50002404000400A01021312800203C01080059 +:108C6000A024403911000002240500102402000154 +:108C70003C010800AC223FD40A000D243C028000D5 +:108C80008F8800288C8900600109282B14A000021D +:108C9000010088218C9100603C048000348B0E0020 +:108CA0008D640018240A00010220282102203021AE +:108CB000A38A001C0E000B8D022080210A000CB03C +:108CC000AF82002C000458231220000731640003F7 +:108CD0003C0E800035C7098090ED007C31AC00046B +:108CE00015800019248F00043C010800A4243FFAD9 +:108CF0003C1F080097FF3FFA03E5C82100D9C02BAD +:108D00001300FF6B8F8400242CA6000514C0FFA362 +:108D10002404004230A200031440000200A21823E1 +:108D200024A3FFFC3C010800AC233FDC3C0108000D +:108D3000A4203FFA0A000CF10060282100C770242B +:108D40000A000D1701C720263C010800A42F3FFA96 +:108D50000A000D82000000003C010800AC203FDC4E +:108D60000A000D2D240400428F8300283C0580005A +:108D700034AA0A0014600006000010219147003058 +:108D80002406000530E400FF108600030000000008 +:108D900003E0000800000000914B0048316900FF2B +:108DA000000941C21500FFFA3C0680083C04080097 +:108DB00094843FE43C0308008C633FFC3C190800AA +:108DC0008F393FDC3C0F080095EF3FFA0064C0216B +:108DD0008CCD00040319702101CF602134AB0E004B +:108DE000018D282318A0001D00000000914F004CA9 +:108DF0008F8C0034956D001031EE00FF8D890004DA +:108E000001AE30238D8A000030CEFFFF000E290016 +:108E10000125C82100003821014720210325182BF6 +:108E20000083C021AD990004AD980000918F000A25 +:108E300001CF6821A18D000A956500128F8A003448 +:108E4000A5450008954B003825690001A549003863 +:108E50009148000D35070008A147000D03E0000808 +:108E60000000000027BDFFD8AFB000189388001C99 +:108E70008FB000143C0A80003C197FFF8F870024CC +:108E80003738FFFFAFBF0020AFB1001C355F0A00CD +:108E90000218182493EB003C00087FC03C02BFFF7F +:108EA000006F60252CF000013449FFFF3C1F0800D3 +:108EB0008FFF3FFC8F9900303C18080097183FF255 +:108EC00001897824001047803C07EFFF3C05F0FF44 +:108ED00001E818253C1180003169002034E2FFFFD1 +:108EE00034ADFFFF362E098027A5001024060002AE +:108EF00003F96023270B0002354A0E000062182494 +:108F00000080802115200002000040218D48001CB7 +:108F1000A7AB0012058000392407000030E800FFED +:108F200000083F00006758253C028008AFAB0014E2 +:108F3000344F008091EA00683C08080091083FF92E +:108F40003C09DFFF352CFFFF000AF82B3C0208002C +:108F500094423FECA3A80011016CC024001FCF4035 +:108F6000031918258FA70010AFA300143C0C0800AC +:108F7000918C3FFBA7A200168FAB001400ED482494 +:108F80003C0F01003C0A0FFF012FC8253198000358 +:108F9000355FFFFF016D40243C027000033F382421 +:108FA00000181E0000E2482501037825AFAF001429 +:108FB000AFA9001091CC007C0E000092A3AC00156C +:108FC000362D0A0091A6003C30C400201080000617 +:108FD000260200083C11080096313FE8262EFFFFCC +:108FE0003C010800A42E3FE88FBF00208FB1001C79 +:108FF0008FB0001803E0000827BD00288F8B002CDD +:10900000010B502B5540FFC5240700010A000E0E2E +:1090100030E800FF9383001C3C02800027BDFFD88E +:1090200034480A0000805021AFBF002034460AC0F7 +:10903000010028211060000E34440980910700309F +:10904000240B00058F89002030EC003F118B000BB2 +:1090500000003821AFA900103C0B80088D69006C1E +:10906000AFAA00180E00015AAFA90014A380001C7B +:109070008FBF002003E0000827BD00288D1F004897 +:109080003C1808008F183FDC8F9900283C027FFFB6 +:109090008D0800443443FFFFAFA900103C0B80084B +:1090A0008D69006C03E370240319782101CF6823D4 +:1090B00001A83821AFAA00180E00015AAFA9001468 +:1090C0000A000E62A380001C3C05800034A60A0042 +:1090D00090C7003C3C06080094C63FFA3C020800DA +:1090E0008C423FF430E30020000624001060001E94 +:1090F000004438253C0880083505008090A30068AE +:109100000000482124080001000028212404000157 +:109110003C0680008CCD017805A0FFFE34CF0140D5 +:10912000ADE800083C0208008C423FFCA5E50004C5 +:10913000A5E40006ADE2000C3C04080090843FF971 +:109140003C03800834790080A1E40012ADE70014EC +:10915000A5E900189338004C3C0E1000A1F8002D32 +:1091600003E00008ACCE017834A90E008D28001C65 +:109170003C0C08008D8C3FDC952B0016952A0014C2 +:10918000018648213164FFFF0A000E8A3145FFFF46 +:109190003C04800034830A009065003C30A200202B +:1091A0001040001934870E000000402100003821D3 +:1091B000000020213C0680008CC901780520FFFEBC +:1091C00034CA014034CF010091EB0009AD480008DA +:1091D0003C0E08008DCE3FFC240DFF91240C004076 +:1091E0003C081000A5440004A5470006AD4E000C45 +:1091F000A14D0012AD4C0014A5400018A14B002D4C +:1092000003E00008ACC801788CE8001894E600126E +:1092100094E4001030C7FFFF0A000EB33084FFFF54 +:109220003C04800034830A009065003C30A200209A +:109230001040002727BDFFF8240900010000382155 +:10924000240800013C0680008CCA01780540FFFE1E +:109250003C0280FF34C40100908D00093C0C0800E2 +:10926000918C4039A3AD00038FAB00003185007FA6 +:109270003459FFFF01665025AFAA00009083000A11 +:10928000A3A0000200057E00A3A300018FB8000088 +:1092900034CB0140240C30000319702401CF682521 +:1092A000AD6D000C27BD0008AD6C0014A560001862 +:1092B000AD690008A56700042409FF80A5680006C1 +:1092C0003C081000A169001203E00008ACC8017856 +:1092D00034870E008CE9001894E6001294E4001024 +:1092E00030C8FFFF0A000ED73087FFFF27BDFFE021 +:1092F000AFB100143C118000AFB00010AFBF001838 +:1093000036380A00970F0032363001000E000B8904 +:1093100031E43FFF8E0E0000240DFF803C0420004E +:1093200001C25821016D6024000C4940316A007F60 +:10933000012A4025010438253C048008AE27083066 +:109340003486008090C500682403000230A200FF2C +:10935000104300048F9F00208F990024AC9F006869 +:10936000AC9900648FBF00188FB100148FB000104B +:1093700003E0000827BD00203C0A0800254A3AA85F +:109380003C09080025293B383C08080025082F44E3 +:109390003C07080024E73C043C06080024C6392C9E +:1093A0003C05080024A536803C040800248432844F +:1093B0003C030800246339E03C0208002442377C67 +:1093C0003C010800AC2A3FB83C010800AC293FB47E +:1093D0003C010800AC283FB03C010800AC273FBC72 +:1093E0003C010800AC263FCC3C010800AC253FC442 +:1093F0003C010800AC243FC03C010800AC233FD036 +:109400003C010800AC223FC803E000080000000057 +:109410008000094080000900800801008008008069 +:1094200080080000800E0000800800808008000096 +:1094300080000A8080000A00800009808000090006 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex deleted file mode 100644 index 52c496331de2..000000000000 --- a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex +++ /dev/null @@ -1,424 +0,0 @@ -:100000000000000000000C900000005800000009F3 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000CE000000CE80000000500000000DB -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F01030300000000080500FFFF5F -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F004D00000010213F000301 -:1000D0000000001020BF001C000000188000FFFD81 -:1000E00000000008B1000001000000082C8000B0F2 -:1000F000000000082D000008000000082D8000010D -:10010000000000188000006C0000000B2FDF0002D0 -:100110000000000C1F800002000000002C070000FF -:100120000000001091DE0000000000080500555599 -:10013000000000188000FFF00000000B2FDF00021D -:100140000000000C1F800000000000002C070000D1 -:100150000000001091DE0000000000080500555569 -:10016000000000188000FFEA0000000C1F80000261 -:100170000000000805005555000000188000FFE74A -:100180000000000C298000020000000C1F8000020B -:10019000000000002ADF0000000000082A0000051F -:1001A0000000000805005555000000188000FFE120 -:1001B000000000080224002C0000001800040000C9 -:1001C000000000188000001C000000188000001EC5 -:1001D000000000188000006500000018800000B0DA -:1001E00000000018800000AF000000188000000030 -:1001F00000000018800000000000001880000000CF -:1002000000000018800000000000001880000000BE -:1002100000000018800000000000001880000000AE -:10022000000000188000000000000018800000F6A8 -:10023000000000188000000000000018800000008E -:100240000000001880000015000000188000001B4E -:10025000000000188000000000000018800000C6A8 -:10026000000000188000002F00000018800000F639 -:10027000000000188000012100000018800000EC40 -:100280000000001880000145000000188000004EAA -:1002900000000018800000000000001880000083AB -:1002A0000000000C1F80000100000000050000009D -:1002B000000000188000FFC00000001091D4000072 -:1002C0000000000C298000010000000C1F800001CC -:1002D000000000082A0000020000000005000000E5 -:1002E000000000188000FFBA0000001091D4000048 -:1002F0000000000C298000010000000C1F8000019C -:100300000000000029420000000000082A0000024E -:100310000000000005000000000000188000FFB38E -:10032000000000188000FFB200000010B1BCB00A4D -:100330000000000B2FDF00020000000003D80000C7 -:10034000000000002C3C00000000001091D40000D0 -:100350000000000806005555000000188000001736 -:1003600000000018800000BF000000102C6201BADD -:100370000000001880000006000000082C8000B17A -:10038000000000082D0000090000001091D40000BA -:10039000000000082D8001070000001880000024E4 -:1003A0000000000C298000000000000C1F800000ED -:1003B0000000001091DE0000000000002ADF0000B5 -:1003C000000000082A00000600000008050055553E -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F000000000082A00000B0000000005000000BB -:10040000000000188000FF960000001800020000A5 -:10041000000000000682000000000010B18A000801 -:1004200000000010B18C14070000000B050AFFFF4C -:1004300000000010B18A000300000000860A1800C6 -:1004400000000010918C0000000000082A0000014C -:100450000000001091D4000000000018000D000002 -:1004600000000000050200000000001091DE000006 -:1004700000000018000A00000000000006820000D2 -:100480000000001091DE000000000010BEE1000539 -:10049000000000188000FF7D0000000105611400CD -:1004A00000000010918A000200000008B0E1000185 -:1004B00000000018000D000000000000068200008F -:1004C0000000001091DE000000000010BEE20005F8 -:1004D000000000188000FF75000000010562140094 -:1004E00000000010918A000200000008B1620001C3 -:1004F00000000018000D000000000010B1A0B013B3 -:100500000000000B2FDF0002000000002C20000084 -:10051000000000082C800000000000082D000000F2 -:100520000000001091D4000000000008060055559E -:10053000000000188000FFDC000000082D80011C76 -:1005400000000010001F0000000000188000FFE6FF -:100550000000000F476000080000000F060E0001B9 -:10056000000000000F580000000000000A640000B6 -:10057000000000000AE50000000000090B66FFFF14 -:10058000000000000D610000000000188000001352 -:100590000000000F476000080000000B2FDF000282 -:1005A000000000082C800000000000082D00000062 -:1005B0000000001091D40000000000082D80011CF4 -:1005C0000000000F060E000100000010001F0000D8 -:1005D000000000000F580000000000188000FFD449 -:1005E000000000000A640000000000000AE50000AE -:1005F000000000090B66FFFF000000000D61000015 -:1006000000000000026200000000000B2FDF00026B -:10061000000000003104000000000000309A0000DB -:10062000000000000C961800000000090C99FFFF64 -:1006300000000004CC99340000000010B196320292 -:10064000000000080F8000000000000C298000015D -:100650000000000C295200010000000C295200008B -:10066000000000080200000E000000080280001ACE -:1006700000000010B1C40A020000000802000003DC -:1006800000000008220000010000000C1F80000193 -:10069000000000002ADF0000000000002A0008001F -:1006A0000000000805005555000000188000FF41BB -:1006B0000000000B2FDF00020000001091D40000AA -:1006C000000000082A000001000000002C200000AB -:1006D0000000001091D40000000000082C800000F1 -:1006E000000000082D000000000000082D80011C03 -:1006F000000000188000FFAE000000082C800006FB -:10070000000000082D0000060000000030800000FE -:100710000000000031000000000000082D800006ED -:100720000000000C298000010000000C1F80000167 -:100730000000001091DE0000000000002ADF000031 -:10074000000000082A000010000000000500000062 -:10075000000000188000FF2C0000001091A0B009DC -:10076000000000082C8000B1000000082D000009E6 -:100770000000001091D40000000000082D80010747 -:10078000000000188000FFA7000000188000001083 -:1007900000000008AC000001000000188000000B01 -:1007A000000000000380B0000000000B2FDF0002FB -:1007B000000000002C0040000000001091D4000058 -:1007C0000000000806005555000000188000FF8951 -:1007D00000000018800000310000001880000006B2 -:1007E0000000000B2FDF0002000000002C000E00B4 -:1007F000000000082A000007000000080500555509 -:10080000000000188000FF160000000006820000B3 -:100810000000000C298000010000000C1F80000176 -:10082000000000100CE70007000000090562FFFF50 -:1008300000000010BA6C1405000000002ADF000060 -:100840000000000021000000000000082A00000550 -:100850000000001091D40000000000082C8000B0BF -:10086000000000082D0000080000000C3162001894 -:10087000000000082D800001000000188000FF7DAE -:1008800000000018000D000000000010B1A0B00E24 -:100890000000000B2FDF00020000000003D8000062 -:1008A000000000002C2000000000001091D4000087 -:1008B0000000001880000015000000102C620002EB -:1008C000000000188000000C0000000B2FDF000269 -:1008D000000000002C0700000000000C1F80000139 -:1008E0000000001091DE0000000000080500FFFF7E -:1008F000000000188000FEF8000000082C8000B105 -:10090000000000082D0000090000001091D4000034 -:10091000000000082D800107000000188000FF740F -:100920000000000C298000010000000C1F80000165 -:100930000000001091DE0000000000002ADF00002F -:10094000000000082A00000A000000000500000066 -:10095000000000188000FEEC00000000068200008D -:10096000000000082C8000B0000000082D000008E6 -:10097000000000082D800150000000000000000071 -:100980000000001091DE0000000000082C80000034 -:10099000000000082D000000000000082D80010567 -:1009A00000000010BEE20005000000188000FEDA22 -:1009B000000000010562140000000010918A00028E -:1009C00000000008B16200010000001091DE00008C -:1009D00000000018000D00000000001091D400007D -:1009E000000000080600AAAA000000188000FF45C9 -:1009F0000000000C298000010000000C1F80000195 -:100A0000000000082A000009000000080500AAAA4A -:100A1000000000188000FED40000001091D40000F7 -:100A20000000000806005555000000188000FF3D3A -:100A30000000001091A03C0200000010B1E6620727 -:100A40000000000B2FDF0002000000002C3100002E -:100A5000000000092CB1007F000000082CD9000024 -:100A6000000000082D000000000000082D80010D8E -:100A700000000010B1A8000600000010205F000078 -:100A8000000000002C200000000000002CA7000047 -:100A9000000000082D000010000000082D80010853 -:100AA000000000188000FF3800000010B1A6001000 -:100AB00000000010001F00000000000F0F300007B2 -:100AC000000000000A600000000000000AE10000D1 -:100AD0000000000F4B620008000000090B1600FF29 -:100AE000000000000D620000000000090D1A00FF68 -:100AF00000000010073000030000000C0D1A000871 -:100B00000000000C0B1600080000000F4CE300185A -:100B1000000000000C992C0000000004CC99340067 -:100B2000000000080F8000000000000C2980000178 -:100B30000000000033310000000000082200001611 -:100B4000000000002ADF0000000000082A00000C5E -:100B500000000010009F0000000000000F200000B7 -:100B60000000000C1F800001000000080500555522 -:100B7000000000188000FEA80000001091D40000C2 -:100B8000000000080600AAAA000000188000FF115B -:100B90000000000F4722000800000009070E000FA8 -:100BA00000000008070E0008000000080280000195 -:100BB0000000000702851C0000000008828500017B -:100BC0000000000002854C000000000742851C0068 -:100BD00000000003C3AA52000000000003B10E0091 -:100BE000000000074B071C000000000F0F3000073B -:100BF0000000000F0A960003000000000A955C0048 -:100C0000000000004A005A00000000000C960A0094 -:100C1000000000090C99FFFF000000080D00FFFF15 -:100C200000000010B1963202000000080F8000059D -:100C300000000010B1A8000800000010205F0000B4 -:100C40000000000B2FDF0002000000002C2000003D -:100C5000000000002CA70000000000082D0000107C -:100C6000000000082D800108000000188000FEFF31 -:100C70000000000C2980000100000010001F00008F -:100C80000000000C1F800001000000002ADF0000AF -:100C9000000000082A00000D000000080500AAAAB4 -:100CA000000000188000FE820000001091D40000B7 -:100CB0000000000806005555000000188000FEEBFB -:100CC0000000000C298000010000000C1F800001C2 -:100CD000000000082A000007000000080500555524 -:080CE000000000188000FE7AFC -:080CE80000000010B1800004BF -:100CF0000000001F0103030000000008050000FFC2 -:100D00000000001800020000000000002A0000009F -:100D100000000010B1D400000000001091DE0000BF -:100D2000000000102053000000000010001F000011 -:100D3000000000002F80AA000000000C29800001A4 -:100D4000000000080254000D000000002C400000CC -:100D500000000018000400000000001880000010CF -:100D60000000001880000011000000188000003909 -:100D700000000018800000DF00000018800000DE86 -:100D800000000018800000DD00000018800000DD79 -:100D9000000000188000000000000018800000F52E -:100DA00000000018800000D9000000188000000B2F -:100DB00000000018800000F90000001880000147C2 -:100DC000000000188000005900000018800000C4D6 -:100DD00000000018800000C5000000002A0000008C -:100DE000000000188000FFE6000000002A0000005C -:100DF0000000000C29800000000000188000FFE3C4 -:100E0000000000002A000000000000188000FFE140 -:100E100000000018000200000000000005020000B1 -:100E2000000000109196342100000010205F0000A7 -:100E3000000000002C1E0000000000082C800006AE -:100E4000000000082D000006000000082D800102AF -:100E500000000000000000000000001091DE000013 -:100E6000000000000D61000000000018000A0000F2 -:100E700000000000050200000000001091963416EA -:100E800000000010205F00000000000009D80000F2 -:100E9000000000002C1E0000000000082C8000B2A2 -:100EA000000000082D00000A000000082D8001024B -:100EB00000000000000000000000001091DE0000B3 -:100EC000000000000D620000000000002C13000074 -:100ED00000000018000A00000000000005020000E9 -:100EE000000000109196340900000010205F0000FF -:100EF000000000002C1E0000000000082C800006EE -:100F0000000000082D00006A000000082D8001028A -:100F100000000000000000000000001091DE000052 -:100F2000000000000D7A000000000018000A000018 -:100F3000000000002A000000000000000D61000019 -:100F4000000000000362000000000010234200A324 -:100F50000000000002638C00000000002646000034 -:100F6000000000080204001200000010B906081E6C -:100F7000000000000F580000000000000A6400009C -:100F8000000000000AE50000000000090B66FFFFFA -:100F9000000000000C000000000000000B800000BA -:100FA000000000080CC60012000000188000FFCEF0 -:100FB000000000080F800003000000000000000097 -:100FC00000000010009F0000000000082711001220 -:100FD000000000006690000000000008A31B001243 -:100FE00000000010B198000300000010001F000076 -:100FF000000000080F800004000000082200000329 -:10100000000000082C80000C000000082D00000CDF -:1010100000000010009F0000000000002596000066 -:101020000000000C298000000000000032140000C5 -:1010300000000000329500000000000573662C00DF -:101040000000000031E32E00000000082D80001099 -:10105000000000188000FF9800000000230000003E -:101060000000000925E6FFFF000000082200000B39 -:101070000000000C695200000000000C29800000F4 -:10108000000000188000FF92000000002A0000000D -:10109000000000082C800040000000082D00002007 -:1010A000000000082D80011C00000000000000006E -:1010B0000000001091DE00000000000F42EA001066 -:1010C00000000010004F000400000010B74692001E -:1010D000000000080249001200000010B5840A0058 -:1010E000000000000D61000000000010BA663457D7 -:1010F000000000088305001200000010004F0002ED -:1011000000000000034900000000000183068C007D -:101110000000000083C60C0000000010B187001121 -:10112000000000000B6E000000000010BEE900058A -:10113000000000188000FF7900000001056914001C -:1011400000000010918A000200000008B4E90001CC -:1011500000000010B1E92C4A0000000086692C0054 -:1011600000000000020000000000000902EAFFFF8A -:1011700000000010000C00020000000002040A0041 -:101180000000000F460C00010000000F0285000166 -:1011900000000010918C01FC00000010B7040E410B -:1011A000000000000F400000000000000D61000082 -:1011B000000000000A640000000000000AE50000D2 -:1011C000000000090B66FFFF000000000C0000009B -:1011D000000000000B800000000000080C860012D8 -:1011E000000000080F8000030000000C29520000DE -:1011F00000000010009F00000000000827110012EE -:10120000000000006690000000000000264600007C -:10121000000000002306000000000010B198000547 -:1012200000000010001F0000000000080F800004F4 -:10123000000000000000000000000010001F00007F -:101240000000000032140000000000003295000091 -:101250000000000031E32E000000000573662C0042 -:10126000000000002596000000000010B187001665 -:101270000000000C298000000000000F0F6B000729 -:10128000000000000D690000000000000A6C000072 -:10129000000000000AED0000000000000B6E0000DE -:1012A000000000000B800000000000000C87000020 -:1012B000000000080F800003000000102053000011 -:1012C0000000000C6952000100000010001F000027 -:1012D0000000000022C58C0000000000231B00005D -:1012E0000000000027110000000000002690000010 -:1012F00000000010B8170E030000000C2980000049 -:10130000000000188000FFF600000010B1980002F5 -:10131000000000080F800004000000082200001AEE -:10132000000000082C80000C000000082D00000CBC -:10133000000000082D80001000000010001F0000B9 -:10134000000000000D6E000000000003E7CF340035 -:101350000000000C298000000000001091DE000059 -:1013600000000010B18700070000000036140000E4 -:101370000000000036950000000000003716000055 -:10138000000000082C800050000000082D000030F4 -:10139000000000082D80000C000000188000FF2FC6 -:1013A00000000000264600000000000023000000AE -:1013B0000000000925E6FFFF000000000B6E0000A2 -:1013C00000000003E7CF2C00000000082200001BF3 -:1013D0000000000C695200000000000C2980000091 -:1013E000000000188000FF26000000002A00000016 -:1013F000000000188000FF24000000002A00000008 -:101400000000000C298000000000001091DE0000A8 -:10141000000000082C80001A000000082D00001AAF -:101420000000000573660000000000082D80000227 -:1014300000000000318000000000001091DE00007C -:10144000000000082C80000C000000082D00000C9B -:10145000000000082D800004000000188000FF1725 -:101460000000001800020000000000188000FF15B6 -:10147000000000002A00000000000010001F000013 -:10148000000000000F008000000000080F8000072F -:10149000000000188000001A00000000280A000068 -:1014A0000000000005020000000000082200000902 -:1014B00000000000290000000000000F6568001017 -:1014C00000000003F66C940000000010B972A00444 -:1014D0000000000C73E700190000000C214200041A -:1014E000000000003CF800000000000C2980000013 -:1014F0000000001020530000000000082200000837 -:101500000000000C6142000400000018000A000006 -:1015100000000000050200000000000C6142000015 -:1015200000000010014200030000000C33E7001D22 -:101530000000000C6142000200000018000A0000D8 -:10154000000000002A00000000000010001F000042 -:101550000000000F0F470007000000080F80000880 -:101560000000000C2980000000000010009F000017 -:10157000000000188000FEF400000000335100005D -:10158000000000002A00000000000010B1C6002387 -:101590000000000F0F500007000000000A6000006C -:1015A000000000000AE100000000000F4B6200088C -:1015B000000000090B1600FF0000000F4C62001035 -:1015C000000000000D620000000000090D1A00FF7D -:1015D00000000010075000030000000C0D1A000866 -:1015E0000000000C0B160008000000000CC60000F4 -:1015F000000000000B8000000000000006980000C2 -:10160000000000080F8000030000001006C2000464 -:101610000000000C29000002000000102642000219 -:101620000000000C29520003000000082200000105 -:1016300000000010009F000000000000231B0000BD -:101640000000000027111A00000000006690000052 -:101650000000000C2952000000000010B197320970 -:101660000000000C29800000000000000698000027 -:1016700000000010205300000000000C295200035D -:101680000000000022C58C0000000010001F0000B8 -:10169000000000080F800003000000188000FFF326 -:1016A00000000010B1C8001300000010B1C6000314 -:1016B0000000000C298000000000001020530000F2 -:1016C0000000000C295200000000000C2952000309 -:1016D0000000001006C200020000000C29520002A7 -:1016E0000000000022C58C000000000027650000FB -:1016F0000000000026E400000000000822000016A0 -:1017000000000010B1C600030000000023480000E4 -:1017100000000010B1800005000000002348000018 -:101720000000000C298000000000000F0F5000078F -:1017300000000018800000120000000822000016BF -:101740000000000C298000000000000030140000A0 -:10175000000000003095000000000010075000035A -:10176000000000090B1600FF000000090D1A00FF21 -:101770000000000F31160008000000003162340044 -:1017800000000003F162300000000010205F000044 -:10179000000000002C510000000000092CD1007F47 -:1017A000000000082CD90000000000082D000000F7 -:1017B000000000082D80000C000000000000000068 -:1017C0000000001091DE00000000001005C20004BF -:1017D000000000080F800007000000003300000038 -:1017E00000000010009F0000000000188000FEA50F -:1017F000000000002A0000000000000F0F5000074A -:1018000000000010B1C6002D0000000F4742000884 -:1018100000000009070E000F00000008070E000876 -:1018200000000010001F0000000000080900000177 -:101830000000000709121C0000000003CBCA920040 -:10184000000000000B97A2000000000742171C00D8 -:10185000000000000B0400000000000F0A840003D9 -:10186000000000000A959C00000000004A009A0059 -:101870000000000882120001000000010C1708009F -:10188000000000000C978C0000000000021800000F -:10189000000000080D00FFFF000000080F80000698 -:1018A0000000000C290000000000001006C2000427 -:1018B0000000000C29520002000000102642000225 -:1018C0000000000C29520003000000082200000163 -:1018D00000000010009F000000000010B197320CC3 -:1018E00000000000231B000000000000271108007A -:1018F00000000000669000000000000C298000003D -:10190000000000000218000000000010205300003A -:101910000000000C295200030000000022C5360020 -:1019200000000010001F0000000000080F800006EB -:10193000000000188000FFF400000000231B0000DE -:101940000000000027110800000000006690000061 -:1019500000000010B1C8000B0000000C298000003E -:1019600000000010205300000000000C295200006D -:101970000000000C295200030000001006C2000203 -:101980000000000C295200020000000022C58C005B -:1019900000000000276500000000000026E40000B1 -:1019A000000000002348000000000008220000178B -:1019B0000000000C2980000000000010001F000043 -:0819C000000000188000FE6A1F -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex new file mode 100644 index 000000000000..dcc443e210f5 --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex @@ -0,0 +1,366 @@ +:1000000000000000000008F800000058000000098F +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000CF000000950000000050000000066 +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F0106000F000000080500FFFF50 +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C8000B0E2 +:10010000000000082D000008000000082D800001FC +:10011000000000188000003C0000000B2FDF0002F0 +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000042D2 +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000008E000000188000000041 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000008D00000018800000B74A +:10024000000000188000008400000018800000DA20 +:10025000000000188000002B000000188000000043 +:10026000000000188000006B0000001091D4000016 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000180002000000000000068200009C +:1002C00000000010B18F000400000010B18F140373 +:1002D000000000082A0000010000001091D4000076 +:1002E000000000000780140000000018000D00004E +:1002F00000000000050200000000001091DE000078 +:1003000000000018000A0000000000000682000043 +:100310000000001091DE0000000000090561FFFFF1 +:1003200000000010918A00020000000830E1FFFF89 +:10033000000000188000FFA9000000010561140002 +:1003400000000010918A000200000008B0E10001E6 +:1003500000000018000D00000000000006820000F0 +:100360000000001091DE0000000000090562FFFFA0 +:1003700000000010918A0002000000083162FFFFB7 +:10038000000000188000FF9F0000000105621400BB +:1003900000000010918A000200000008B162000114 +:1003A00000000018000D000000000010B1A0B01304 +:1003B0000000000B2FDF0002000000002C200000D6 +:1003C000000000082C800000000000082D00000044 +:1003D0000000001091D40000000000080500005546 +:1003E000000000188000FFDB000000082D80011CC9 +:1003F00000000010001F0000000000188000FFE255 +:100400000000000F476000080000000F060E00010A +:10041000000000000F580000000000000A64000007 +:10042000000000000AE50000000000090B66FFFF65 +:10043000000000000D6100000000001880000015A1 +:100440000000000F476000080000000B2FDF0002D3 +:10045000000000082C800000000000082D000000B3 +:100460000000001091D40000000000082D80011C45 +:100470000000000F060E000100000010001F000029 +:10048000000000000F580000000000188000FFD09E +:10049000000000000A640000000000000AE50000FF +:1004A000000000090B66FFFF000000000D61000066 +:1004B00000000000026200000000000002E00000F6 +:1004C0000000000B2FDF00020000000030050000DC +:1004D000000000003104000000000000309A00001D +:1004E000000000100060000A00000008051600016E +:1004F00000000010BA9A140300000000030000007E +:100500000000001880000006000000188000FF6C4A +:1005100000000010B60614040000000803060001E5 +:10052000000000082A000001000000188000FF7190 +:10053000000000000C961800000000090C99FFFF55 +:1005400000000004CC99340000000010BA992C027D +:10055000000000080F8000000000000C298000014E +:100560000000000C295200010000000C295200007C +:100570000000000822800002000000080200000EB7 +:10058000000000080280001A00000010B1C40A0236 +:1005900000000008020000030000000C1F800001A2 +:1005A000000000002ADF0000000000002A00080010 +:1005B000000000188000FF600000000B2FDF000229 +:1005C0000000001091D40000000000082A00000183 +:1005D000000000002C2000000000001091D400005A +:1005E000000000082C800000000000082D00000022 +:1005F000000000082D80011C000000188000FF9FF3 +:10060000000000082C800006000000082D000006F5 +:1006100000000000308000000000000031000000F9 +:10062000000000082D8000060000000C2980000159 +:100630000000000C1F8000010000001091DE00008F +:10064000000000002ADF0000000000082A0000105F +:100650000000000807800000000000188000FF4B29 +:100660000000001091D4000000000008050000AA5E +:10067000000000188000FF890000000C29800001A4 +:100680000000000C1F800001000000082A00000983 +:10069000000000188000FF440000001091D400000A +:1006A0000000000805000055000000188000FF82CF +:1006B0000000001091A0B00200000010B1E6620737 +:1006C0000000000B2FDF0002000000002C310000B2 +:1006D000000000092CB1007F000000082CD90000A8 +:1006E000000000082D000000000000082D80010D12 +:1006F00000000010B1A8000600000010205F0000FC +:10070000000000002C200000000000002CA70000CA +:10071000000000082D000010000000082D800108D6 +:10072000000000188000FF7A00000010B1A6001041 +:1007300000000010001F00000000000F0F30000735 +:10074000000000000A600000000000000AE1000054 +:100750000000000F4B620008000000090B1600FFAC +:10076000000000000D620000000000090D1A00FFEB +:1007700000000010073000030000000C0D1A0008F4 +:100780000000000C0B1600080000000F4CE30018DE +:10079000000000000C992C0000000004CC993400EB +:1007A000000000080F8000000000000C29800001FC +:1007B0000000000033310000000000082200001695 +:1007C000000000002ADF0000000000082A00000CE2 +:1007D00000000010009F0000000000002C2000001E +:1007E0000000000C1F800001000000188000FF19AD +:1007F0000000001091D4000000000008050000AACD +:10080000000000188000FF570000000F472200087A +:1008100000000009070E000F00000008070E000886 +:1008200000000008028000010000000702851C0093 +:1008300000000008828500010000000002854C00D5 +:100840000000000742851C0000000003C3AA5200FC +:100850000000000003B10E00000000074B071C0061 +:100860000000000F0F3000070000000F0A96000381 +:10087000000000000A955C00000000004A005A00D9 +:10088000000000000C960A00000000090C99FFFF10 +:10089000000000080D00FFFF00000010BA992C02B4 +:1008A000000000080F80000500000010B1A800083B +:1008B00000000010205F00000000000B2FDF00028E +:1008C000000000002C200000000000002CA7000009 +:1008D000000000082D000010000000082D80010815 +:1008E000000000188000FF420000000C2980000179 +:1008F00000000010001F00000000000C1F8000011D +:10090000000000002ADF0000000000082A00000D9F +:10091000000000188000FEF40000001091D40000D8 +:100920000000000805000055000000188000FF329C +:100930000000000C298000010000000C1F80000155 +:10094000000000082A000007000000188000FEEDEB +:1009500000000010B18000040000001F0106000F1D +:1009600000000008050000FF000000180002000061 +:10097000000000002A00000000000010B1D40000B8 +:100980000000001091DE0000000000102053000065 +:1009900000000010001F0000000000002F80AA00CF +:1009A0000000000C29800001000000080254000E25 +:1009B000000000002C400000000000000F4000007C +:1009C0000000001800040000000000188000001162 +:1009D000000000188000001200000018800000389D +:1009E00000000018800000DF00000018800000DE1A +:1009F00000000018800000DD00000018800000DD0D +:100A0000000000188000000000000018800000F6C0 +:100A100000000018800000D90000001880000000CD +:100A200000000018800000FA000000188000014853 +:100A3000000000188000005A00000018800000C468 +:100A400000000018800000C500000018800000D2DF +:100A5000000000002A000000000000188000FFE4F1 +:100A6000000000002A0000000000000C29800000A7 +:100A7000000000188000FFE10000001800020000E4 +:100A8000000000000502000000000010B99A2C21AF +:100A900000000010205F0000000000002C1E00007D +:100AA000000000082C800006000000082D00000651 +:100AB000000000082D80010200000000000000007E +:100AC0000000001091DE0000000000000D61000039 +:100AD00000000018000A00000000000005020000ED +:100AE00000000010B99A2C1600000010205F0000D2 +:100AF0000000000009D80000000000002C1E0000CB +:100B0000000000082C8000B2000000082D00000A40 +:100B1000000000082D80010200000000000000001D +:100B20000000001091DE0000000000000D620000D7 +:100B3000000000002C13000000000018000A000054 +:100B4000000000000502000000000010B99A2C0906 +:100B500000000010205F0000000000002C1E0000BC +:100B6000000000082C800006000000082D00006A2C +:100B7000000000082D8001020000000000000000BD +:100B80000000001091DE0000000000000D7A00005F +:100B900000000018000A0000000000002A00000009 +:100BA0000000000822000001000000000D610000AC +:100BB0000000001021C2002400000010B1C6000295 +:100BC00000000010234200A2000000090B66FFFF96 +:100BD00000000010BA9A2C20000000000A640000F7 +:100BE000000000000AE50000000000000C0000000A +:100BF000000000000B800000000000080CC600127E +:100C0000000000188000FFD0000000080F800003E3 +:100C1000000000000000000000000010009F000025 +:100C2000000000082711001200000000669000007C +:100C300000000010B198000300000010001F000029 +:100C4000000000080F8000040000000822000003DC +:100C5000000000082C80000C000000082D00000C93 +:100C600000000010009F00000000001091C6000569 +:100C700000000010001F000000000010BA9A2C03B2 +:100C8000000000080F800004000000188000FFFD35 +:100C900000000000259600000000000C29800000E4 +:100CA0000000000032140000000000003295000037 +:100CB0000000000573662C000000000031E32E00E8 +:100CC000000000082D800010000000188000FF9632 +:100CD00000000000230000000000000925E6FFFFDF +:100CE000000000082200000B0000000C6952000008 +:100CF0000000000C29800000000000188000FF9018 +:100D0000000000002A000000000000082C800040C5 +:100D1000000000082D000020000000082D80011CAC +:100D200000000008220000010000001091DE000019 +:100D30000000000F42EA001000000010004F000405 +:100D400000000010B746920000000008024900129F +:100D500000000010B5840A00000000000D610000D2 +:100D600000000010BA663457000000088305001226 +:100D700000000010004F00020000000003490000C6 +:100D80000000000183068C000000000083C60C00F8 +:100D900000000010B1870013000000000B6E00007F +:100DA000000000090569FFFF00000010918A0002A1 +:100DB0000000000834E9FFFF000000188000FF7504 +:100DC000000000010569140000000010918A000273 +:100DD00000000008B4E9000100000010BAE92C4846 +:100DE0000000000086692C000000000002000000E6 +:100DF0000000000902EAFFFF00000010000C0002E2 +:100E00000000000002040A000000000F460C000170 +:100E10000000000F0285000100000010918C01FC11 +:100E200000000010B7040E3F000000000D6100003C +:100E3000000000000A640000000000000AE5000055 +:100E4000000000090B66FFFF000000000C0000001E +:100E5000000000000B800000000000080C8600125B +:100E6000000000080F8000030000000C2952000061 +:100E700000000010009F0000000000082711001271 +:100E80000000000066900000000000002306000043 +:100E900000000010B198000500000010001F0000C5 +:100EA000000000080F8000040000000000000000A7 +:100EB00000000010001F00000000000032140000BD +:100EC00000000000329500000000000031E32E0019 +:100ED0000000000573662C0000000000259600004D +:100EE00000000010B18700160000000C29800000EF +:100EF0000000000F0F6B0007000000000D690000EC +:100F0000000000000A6C0000000000000AED000074 +:100F1000000000000B6E0000000000000B800000CD +:100F2000000000000C870000000000080F80000394 +:100F300000000010205300000000000C6952000166 +:100F400000000010001F00000000000022C58C00FF +:100F500000000000231B000000000000271100001B +:100F6000000000002690000000000010B8170E03DB +:100F70000000000C29800000000000188000FFF62F +:100F800000000010B1980002000000080F8000046B +:100F9000000000082200001A000000082C80000C4D +:100FA000000000082D00000C000000082D8000103B +:100FB00000000010001F0000000000000D6E000087 +:100FC00000000003E7CF34000000000C298000007F +:100FD0000000001091DE000000000010B187000743 +:100FE00000000000361400000000000036950000EC +:100FF0000000000037160000000000082C800050A0 +:10100000000000082D000030000000082D80000CBA +:10101000000000188000FF2D0000000023000000E9 +:101020000000000925E6FFFF000000000B6E000035 +:1010300000000003E7CF2C00000000082200001B86 +:101040000000000C695200000000000C2980000024 +:10105000000000188000FF25000000002A000000AA +:10106000000000188000FF23000000002A0000009C +:101070000000000C298000000000001091DE00003C +:10108000000000082C80001A000000082D00001A43 +:101090000000000573660000000000082D800002BB +:1010A00000000000318000000000001091DE000010 +:1010B000000000082C80000C000000082D00000C2F +:1010C000000000082D800004000000188000FF16BA +:1010D0000000001880000000000000188000FF14CD +:1010E000000000002A00000000000010001F0000A7 +:1010F000000000000F008000000000080F800007C3 +:10110000000000188000001B00000000280A0000FA +:101110000000000005020000000000082200000995 +:1011200000000000290000000000000F65680010AA +:1011300000000000248A000000000003F66C940008 +:1011400000000010B972A0040000000C73E7001941 +:101150000000000C21420004000000003CF80000E8 +:101160000000000C29800000000000102053000047 +:1011700000000008220000080000000C614200048A +:1011800000000018000A0000000000000502000036 +:101190000000000C6142000000000010014200034A +:1011A0000000000C33E7001D0000000C614200024B +:1011B00000000018000A0000000000002A000000E3 +:1011C00000000010001F00000000000F0F47000784 +:1011D000000000080F8000080000000C29800000BB +:1011E00000000010009F0000000000188000FEF2C8 +:1011F0000000000033510000000000002A00000041 +:1012000000000010B1C600230000000F0F500007BF +:10121000000000000A600000000000000AE1000079 +:101220000000000F4B620008000000090B1600FFD1 +:101230000000000F4C620010000000000D62000072 +:10124000000000090D1A00FF000000100750000305 +:101250000000000C0D1A00080000000C0B1600081E +:10126000000000000CC60000000000000B80000021 +:101270000000000006980000000000080F80000336 +:101280000000001006C200040000000C290000024B +:1012900000000010264200020000000C295200034A +:1012A000000000082200000100000010009F000064 +:1012B00000000000231B00000000000027111A009E +:1012C00000000000669000000000000C29520000A1 +:1012D00000000010B19732090000000C29800000C6 +:1012E00000000000069800000000001020530000DD +:1012F0000000000C295200030000000022C58C00F1 +:1013000000000010001F0000000000080F80000314 +:10131000000000188000FFF300000010B1C80013A7 +:1013200000000010B1C600030000000C298000007E +:1013300000000010205300000000000C29520000A3 +:101340000000000C295200030000001006C2000239 +:101350000000000C295200020000000022C58C0091 +:1013600000000000276500000000000026E40000E7 +:10137000000000082200001600000010B1C60003A3 +:10138000000000002348000000000010B1800005AC +:1013900000000000234800000000000C298000002D +:1013A0000000000F0F50000700000018800000121E +:1013B00000000008220000160000000C2980000038 +:1013C0000000000030140000000000003095000014 +:1013D0000000001007500003000000090B1600FF7A +:1013E000000000090D1A00FF0000000F3116000870 +:1013F000000000003162340000000003F1623000A0 +:1014000000000010205F0000000000002C510000D0 +:10141000000000092CD1007F000000082CD900003A +:10142000000000082D000000000000082D80000CC6 +:1014300000000000000000000000001091DE00002D +:101440000000001005C20004000000080F80000723 +:10145000000000003300000000000010009F0000AA +:10146000000000188000FEA3000000002A00000019 +:101470000000000F0F50000700000010B1C6002D43 +:101480000000000F4742000800000009070E000F8F +:1014900000000008070E000800000010001F0000F8 +:1014A00000000008090000010000000709121C00EC +:1014B00000000003CBCA9200000000000B97A200BE +:1014C0000000000742171C00000000000B04000091 +:1014D0000000000F0A840003000000000A959C0031 +:1014E000000000004A009A0000000008821200017B +:1014F000000000010C170800000000000C978C0091 +:101500000000000002180000000000080D00FFFFAE +:10151000000000080F8000060000000C29000000F9 +:101520000000001006C200040000000C2952000256 +:1015300000000010264200020000000C29520003A7 +:10154000000000082200000100000010009F0000C1 +:1015500000000010B197320C00000000231B0000B7 +:101560000000000027110800000000006690000045 +:101570000000000C2980000000000000021800009C +:1015800000000010205300000000000C295200034E +:101590000000000022C5360000000010001F0000FF +:1015A000000000080F800006000000188000FFF413 +:1015B00000000000231B00000000000027110800AD +:1015C000000000006690000000000010B1C8000B91 +:1015D0000000000C298000000000001020530000D3 +:1015E0000000000C295200000000000C29520003EA +:1015F0000000001006C200020000000C2952000288 +:101600000000000022C58C000000000027650000DB +:101610000000000026E40000000000002348000055 +:1016200000000008220000170000000C29800000C4 +:1016300000000010001F0000000000188000FE687D +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex deleted file mode 100644 index fe59d16b594e..000000000000 --- a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex +++ /dev/null @@ -1,462 +0,0 @@ -:100000000000000000000E08000000580000000979 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000DD800000E60000000050000000068 -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F05030300000000080500FFFF5B -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F006B00000010213F0003E3 -:1000D0000000001020BF003A000000188000FFFD63 -:1000E00000000010B1B8B0150000000B2FDF0002B7 -:1000F0000000000003D80000000000002C380000C1 -:10010000000000082C800000000000082D00000006 -:100110000000001091D400000000000806005555B2 -:10012000000000188000007C000000082D80011CE9 -:1001300000000008020000010000001091DE000035 -:100140000000000F42E0001C0000001091840A161D -:1001500000000018800000830000000C29800002CD -:100160000000000C1F800002000000002ADF0000D9 -:10017000000000082A00000F000000000500000039 -:10018000000000188000FFE60000000802000001E7 -:100190000000000F42E0001C0000001091840A18CB -:1001A000000000082C800006000000082D0000065A -:1001B0000000001091D40000000000082D8001060E -:1001C0000000001880000072000000188000FFF19D -:1001D00000000008B1000001000000082C80010CA4 -:1001E000000000082D000008000000082D8000011C -:1001F000000000188000006C0000000B2FDF0002E0 -:100200000000000C1F800002000000002C0700000E -:100210000000001091DE00000000000805005555A8 -:10022000000000188000FFD20000000B2FDF00024A -:100230000000000C1F800000000000002C070000E0 -:100240000000001091DE0000000000080500555578 -:10025000000000188000FFCC0000000C1F8000028E -:100260000000000805005555000000188000FFC977 -:100270000000000C298000020000000C1F8000021A -:10028000000000002ADF0000000000082A0000052E -:100290000000000805005555000000188000FFC34D -:1002A000000000080224004A0000001800040000BA -:1002B000000000188000001C000000188000001ED4 -:1002C000000000188000006500000018800000BCDD -:1002D00000000018800000BB000000188000000033 -:1002E00000000018800000000000001880000000DE -:1002F00000000018800000000000001880000000CE -:1003000000000018800000000000001880000000BD -:1003100000000018800000000000001880000107A5 -:10032000000000188000000000000018800000009D -:100330000000001880000015000000188000001B5D -:10034000000000188000000000000018800000D2AB -:10035000000000188000002F000000188000010736 -:10036000000000188000013200000018800000FD2D -:100370000000001880000156000000188000004EA8 -:100380000000001880000000000000188000008FAE -:100390000000000C1F8000010000000005000000AC -:1003A000000000188000FFA20000001091D400009F -:1003B0000000000C298000010000000C1F800001DB -:1003C000000000082A0000020000000005000000F4 -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F0000000000029420000000000082A0000025E -:100400000000000005000000000000188000FF95BB -:10041000000000188000FF9400000010B1BCB00A7A -:100420000000000B2FDF00020000000003D80000D6 -:10043000000000002C3C00000000001091D40000DF -:100440000000000806005555000000188000001745 -:1004500000000018800000CB000000102C6201BAE0 -:100460000000001880000006000000082C80010D2C -:10047000000000082D0000090000001091D40000C9 -:10048000000000082D8001070000001880000024F3 -:100490000000000C298000000000000C1F800000FC -:1004A0000000001091DE0000000000002ADF0000C4 -:1004B000000000082A00000600000008050055554D -:1004C000000000188000FF7E0000001091D40000A2 -:1004D0000000000C298000010000000C1F800001BA -:1004E000000000082A00000B0000000005000000CA -:1004F000000000188000FF780000001800020000D3 -:10050000000000000682000000000010B18A000810 -:1005100000000010B18C14070000000B050AFFFF5B -:1005200000000010B18A000300000000860A1800D5 -:1005300000000010918C0000000000082A0000015B -:100540000000001091D4000000000018000D000011 -:1005500000000000050200000000001091DE000015 -:1005600000000018000A00000000000006820000E1 -:100570000000001091DE000000000010BEE1000548 -:10058000000000188000FF5F0000000105611400FA -:1005900000000010918A000200000008B0E1000194 -:1005A00000000018000D000000000000068200009E -:1005B0000000001091DE000000000010BEE2000507 -:1005C000000000188000FF570000000105621400C1 -:1005D00000000010918A000200000008B1620001D2 -:1005E00000000018000D000000000010B1A0B013C2 -:1005F0000000000B2FDF0002000000002C20000094 -:10060000000000082C800000000000082D00000001 -:100610000000001091D400000000000806005555AD -:10062000000000188000FFDC000000082D80011C85 -:1006300000000010001F0000000000188000FFE60E -:100640000000000F476000080000000F060E0001C8 -:10065000000000000F580000000000000A640000C5 -:10066000000000000AE50000000000090B66FFFF23 -:10067000000000000D610000000000188000001361 -:100680000000000F476000080000000B2FDF000291 -:10069000000000082C800000000000082D00000071 -:1006A0000000001091D40000000000082D80011C03 -:1006B0000000000F060E000100000010001F0000E7 -:1006C000000000000F580000000000188000FFD458 -:1006D000000000000A640000000000000AE50000BD -:1006E000000000090B66FFFF000000000D61000024 -:1006F00000000000026200000000000B2FDF00027B -:10070000000000003104000000000000309A0000EA -:10071000000000090560000F00000010B18A000B06 -:100720000000000005634C0000000008050A0012EC -:1007300000000010B9621403000000000300000074 -:100740000000001880000006000000188000FF2450 -:1007500000000010B60614040000000803060001A3 -:10076000000000082A000001000000188000FF2996 -:10077000000000000C961800000000090C99FFFF13 -:1007800000000004CC99340000000010B196320241 -:10079000000000080F8000000000000C298000010C -:1007A0000000000C295200010000000C295200003A -:1007B000000000080200000E000000080280001A7D -:1007C00000000010B1C40A0200000008020000038B -:1007D00000000008220000010000000C1F80000142 -:1007E000000000002ADF0000000000002A000800CE -:1007F0000000000805005555000000188000FF1794 -:100800000000000B2FDF00020000001091D4000058 -:10081000000000082A000001000000002C20000059 -:100820000000001091D40000000000082C8000009F -:10083000000000082D000000000000082D80011CB1 -:10084000000000188000FFA2000000082C800006B5 -:10085000000000082D0000060000000030800000AD -:100860000000000031000000000000082D8000069C -:100870000000000C298000010000000C1F80000116 -:100880000000001091DE0000000000002ADF0000E0 -:10089000000000082A000010000000000500000011 -:1008A000000000188000FF020000001091A0B009B5 -:1008B000000000082C80010D000000082D00000938 -:1008C0000000001091D40000000000082D800107F6 -:1008D000000000188000FF9B00000018800000103E -:1008E00000000008AC000001000000188000000BB0 -:1008F000000000000380B0000000000B2FDF0002AA -:10090000000000002C0040000000001091D4000006 -:100910000000000806005555000000188000FF7D0B -:100920000000001880000031000000188000000660 -:100930000000000B2FDF0002000000002C000E0062 -:10094000000000082A0000070000000805005555B7 -:10095000000000188000FEEC00000000068200008D -:100960000000000C298000010000000C1F80000125 -:10097000000000100CE70007000000090562FFFFFF -:1009800000000010BA6C1405000000002ADF00000F -:100990000000000021000000000000082A000005FF -:1009A0000000001091D40000000000082C80010C11 -:1009B000000000082D0000080000000C3162001843 -:1009C000000000082D800001000000188000FF7169 -:1009D00000000018000D000000000010B1A0B00ED3 -:1009E0000000000B2FDF00020000000003D8000011 -:1009F000000000002C2000000000001091D4000036 -:100A00000000001880000015000000102C62000299 -:100A1000000000188000000C0000000B2FDF000217 -:100A2000000000002C0700000000000C1F800001E7 -:100A30000000001091DE0000000000080500FFFF2C -:100A4000000000188000FECE000000082C80010D80 -:100A5000000000082D0000090000001091D40000E3 -:100A6000000000082D800107000000188000FF68CA -:100A70000000000C298000010000000C1F80000114 -:100A80000000001091DE0000000000002ADF0000DE -:100A9000000000082A00000A000000000500000015 -:100AA000000000188000FEC2000000000682000066 -:100AB000000000082C80010C000000082D00000838 -:100AC000000000082D80013400000000000000003C -:100AD00000000010205F0000000000082C80014092 -:100AE000000000082D00003C000000082D800124BB -:100AF00000000000000000000000001091DE000077 -:100B0000000000082C800080000000082D0000007C -:100B1000000000082D80010500000010BEE2000565 -:100B2000000000188000FEAB000000010562140008 -:100B300000000010918A000200000008B16200016C -:100B40000000001091DE000000000018000D000001 -:100B50000000001091D40000000000080600AAAABE -:100B6000000000188000FF340000000C2980000104 -:100B70000000000C1F800001000000082A0000098E -:100B8000000000080500AAAA000000188000FEA5C9 -:100B90000000001091D40000000000080600555528 -:100BA000000000188000FF2C0000001091A03C0203 -:100BB00000000010B1E662070000000B2FDF00020A -:100BC000000000002C310000000000092CB1007F63 -:100BD000000000082CD90000000000082D000000D3 -:100BE000000000082D80010D00000010B1A80006D3 -:100BF00000000010205F0000000000002C2000001A -:100C0000000000002CA70000000000082D000010CC -:100C1000000000082D800108000000188000FF2758 -:100C200000000010B1A6001000000010001F00001E -:100C30000000000F0F300007000000000A600000F5 -:100C4000000000000AE100000000000F4B620008F5 -:100C5000000000090B1600FF000000000D620000FC -:100C6000000000090D1A00FF00000010073000030B -:100C70000000000C0D1A00080000000C0B16000804 -:100C80000000000F4CE30018000000000C992C003D -:100C900000000004CC993400000000080F80000020 -:100CA0000000000C2980000100000000333100002A -:100CB0000000000822000016000000002ADF0000EB -:100CC000000000082A00000C00000010009F000037 -:100CD000000000000F2000000000000C1F80000139 -:100CE0000000000805005555000000188000FE793E -:100CF0000000001091D40000000000080600AAAA1D -:100D0000000000188000FF000000000F47220008CC -:100D100000000009070E000F00000008070E000881 -:100D200000000008028000010000000702851C008E -:100D300000000008828500010000000002854C00D0 -:100D40000000000742851C0000000003C3AA5200F7 -:100D50000000000003B10E00000000074B071C005C -:100D60000000000F0F3000070000000F0A9600037C -:100D7000000000000A955C00000000004A005A00D4 -:100D8000000000000C960A00000000090C99FFFF0B -:100D9000000000080D00FFFF00000010B1963202B5 -:100DA000000000080F80000500000010B1A8000836 -:100DB00000000010205F00000000000B2FDF000289 -:100DC000000000002C200000000000002CA7000004 -:100DD000000000082D000010000000082D80010810 -:100DE000000000188000FEEE0000000C29800001C9 -:100DF00000000010001F00000000000C1F80000118 -:100E0000000000002ADF0000000000082A00000D9A -:100E1000000000080500AAAA000000188000FE5388 -:100E20000000001091D40000000000080600555595 -:100E3000000000188000FEDA0000000C298000018C -:100E40000000000C1F800001000000082A000007BD -:100E50000000000805005555000000188000FE4BFA -:100E600000000010B18000040000001F0503030013 -:100E700000000008050000FF00000018000200004C -:100E8000000000002A00000000000010B1D40000A3 -:100E90000000001091DE0000000000102053000050 -:100EA00000000010001F0000000000002F80AA00BA -:100EB0000000000C29800001000000080254000E10 -:100EC000000000002C400000000000092952003FF3 -:100ED000000000180004000000000018800000104E -:100EE0000000001880000011000000188000003988 -:100EF00000000018800000FD00000018800000FCC9 -:100F000000000018800000FB00000018800000FBBB -:100F1000000000188000000000000018800001138D -:100F200000000018800000F7000000188000000B8F -:100F30000000001880000117000000188000016503 -:100F4000000000188000006300000018800000CE40 -:100F500000000018800000DE000000002A000000F1 -:100F6000000000188000FFE5000000002A000000DB -:100F70000000000C29800000000000188000FFE243 -:100F8000000000002A000000000000188000FFE0C0 -:100F90000000001800020000000000000502000030 -:100FA000000000109196342100000010205F000026 -:100FB000000000002C1E0000000000082C8000062D -:100FC000000000082D000006000000082D8001022E -:100FD00000000000000000000000001091DE000092 -:100FE000000000000D61000000000018000A000071 -:100FF0000000000005020000000000109196341669 -:1010000000000010205F00000000000009D8000070 -:10101000000000002C1E0000000000082C80010EC3 -:10102000000000082D00000A000000082D800102C9 -:1010300000000000000000000000001091DE000031 -:10104000000000000D620000000000002C130000F2 -:1010500000000018000A0000000000000502000067 -:10106000000000109196340900000010205F00007D -:10107000000000002C1E0000000000082C8000066C -:10108000000000082D00006A000000082D80010209 -:1010900000000000000000000000001091DE0000D1 -:1010A000000000000D7A000000000018000A000097 -:1010B000000000002A000000000000000D61000098 -:1010C000000000000362000000000010234200C185 -:1010D0000000000002638C000000000026460000B3 -:1010E000000000080204001200000010B9060827E2 -:1010F000000000000F580000000000000A6400001B -:10110000000000000AE50000000000090B66FFFF78 -:10111000000000000C000000000000000B80000038 -:10112000000000080CC60012000000188000FFCE6E -:10113000000000080F800003000000000000000015 -:1011400000000010009F000000000008271100129E -:10115000000000006690000000000008A31B0012C1 -:1011600000000010B198000300000010001F0000F4 -:10117000000000080F8000040000000822000003A7 -:10118000000000082C80000C000000082D00000C5E -:1011900000000010009F00000000000025960000E5 -:1011A0000000000C2980000000000000066600001E -:1011B0000000000086611800000000090260000FB6 -:1011C0000000000F0204000200000010B60C080529 -:1011D0000000000C1FBF0000000000102866000384 -:1011E00000000008078F00010000000C33660010AB -:1011F00000000000321400000000000032950000E2 -:101200000000000573662C000000000031E32E0092 -:10121000000000082D800010000000188000FF8EE4 -:1012200000000000230000000000000925E6FFFF89 -:10123000000000082200000B0000000C69520000B2 -:101240000000000C298000000000001028660075D6 -:10125000000000188000FF87000000002A00000046 -:10126000000000082C800040000000082D00002035 -:10127000000000082D80011C00000000000000009C -:101280000000001091DE00000000000F42EA001094 -:1012900000000010004F000400000010B74692004C -:1012A000000000080249001200000010B5840A0086 -:1012B000000000000D61000000000010BA66345705 -:1012C000000000088305001200000010004F00021B -:1012D00000000000034900000000000183068C00AC -:1012E0000000000083C60C0000000010B187001150 -:1012F000000000000B6E000000000010BEE90005B9 -:10130000000000188000FF6E000000010569140055 -:1013100000000010918A000200000008B4E90001FA -:1013200000000010B1E92C4A0000000086692C0082 -:1013300000000000020000000000000902EAFFFFB8 -:1013400000000010000C00020000000002040A006F -:101350000000000F460C00010000000F0285000194 -:1013600000000010918C01FC00000010B7040E4139 -:10137000000000000F400000000000000D610000B0 -:10138000000000000A640000000000000AE5000000 -:10139000000000090B66FFFF000000000C000000C9 -:1013A000000000000B800000000000080C86001206 -:1013B000000000080F8000030000000C295200000C -:1013C00000000010009F000000000008271100121C -:1013D00000000000669000000000000026460000AB -:1013E000000000002306000000000010B198000576 -:1013F00000000010001F0000000000080F80000423 -:10140000000000000000000000000010001F0000AD -:1014100000000000321400000000000032950000BF -:101420000000000031E32E000000000573662C0070 -:10143000000000002596000000000010B187001693 -:101440000000000C298000000000000F0F6B000757 -:10145000000000000D690000000000000A6C0000A0 -:10146000000000000AED0000000000000B6E00000C -:10147000000000000B800000000000000C8700004E -:10148000000000080F80000300000010205300003F -:101490000000000C6952000100000010001F000055 -:1014A0000000000022C58C0000000000231B00008B -:1014B000000000002711000000000000269000003E -:1014C00000000010B8170E030000000C2980000077 -:1014D000000000188000FFF600000010B198000224 -:1014E000000000080F800004000000082200001A1D -:1014F000000000082C80000C000000082D00000CEB -:10150000000000082D80001000000010001F0000E7 -:10151000000000000D6E000000000003E7CF340063 -:101520000000000C298000000000001091DE000087 -:1015300000000010B1870007000000003614000012 -:101540000000000036950000000000003716000083 -:10155000000000082C800050000000082D00003022 -:10156000000000082D80000C000000188000FF24FF -:1015700000000000264600000000000023000000DC -:101580000000000925E6FFFF000000000B6E0000D0 -:1015900000000003E7CF2C00000000082200001B21 -:1015A0000000000C695200000000000C29800000BF -:1015B000000000188000FF1B000000002A0000004F -:1015C000000000100866000500000000066600002C -:1015D000000000008661180000000009026000F0B1 -:1015E00000000010B60C0802000000188000FF1474 -:1015F000000000000682000000000010B18F000013 -:1016000000000008878F00010000000C73660010C6 -:10161000000000082C800018000000082D000018B1 -:10162000000000082D8000020000000C5FBF0000D9 -:101630000000001091DE000000000018000D000006 -:10164000000000002A00000000000010286601F5DC -:10165000000000082C800003000000082D0000039B -:10166000000000093060FFF0000000082D8000013C -:101670000000000C298000000000001091DE000036 -:10168000000000082C80001A000000082D00001A3D -:101690000000000573660000000000082D800002B5 -:1016A00000000000318000000000001091DE00000A -:1016B000000000082C80000C000000082D00000C29 -:1016C000000000082D800004000000188000FEF8D3 -:1016D0000000001800020000000000188000FEF664 -:1016E000000000002A00000000000010001F0000A1 -:1016F000000000000F008000000000080F800007BD -:10170000000000188000001A00000000280A0000F5 -:10171000000000000502000000000008220000098F -:1017200000000000290000000000000F65680010A4 -:1017300000000003F66C940000000010B972A004D1 -:101740000000000C73E700190000000C21420004A7 -:10175000000000003CF800000000000C29800000A0 -:1017600000000010205300000000000822000008C4 -:101770000000000C6142000400000018000A000094 -:1017800000000000050200000000000C61420000A3 -:1017900000000010014200030000000C33E7001DB0 -:1017A0000000000C6142000200000018000A000066 -:1017B000000000002A00000000000010001F0000D0 -:1017C0000000000F0F470007000000080F8000080E -:1017D0000000000C2980000000000010009F0000A5 -:1017E000000000188000FED500000000335100000A -:1017F000000000002A00000000000010B1C6002315 -:101800000000000F0F500007000000000A600000F9 -:10181000000000000AE100000000000F4B62000819 -:10182000000000090B1600FF0000000F4C620010C2 -:10183000000000000D620000000000090D1A00FF0A -:1018400000000010075000030000000C0D1A0008F3 -:101850000000000C0B160008000000000CC6000081 -:10186000000000000B80000000000000069800004F -:10187000000000080F8000030000001006C20004F2 -:101880000000000C290000020000001026420002A7 -:101890000000000C29520003000000082200000193 -:1018A00000000010009F000000000000231B00004B -:1018B0000000000027111A000000000066900000E0 -:1018C0000000000C2952000000000010B1973209FE -:1018D0000000000C298000000000000006980000B5 -:1018E00000000010205300000000000C29520003EB -:1018F0000000000022C58C0000000010001F000046 -:10190000000000080F800003000000188000FFF3B3 -:1019100000000010B1C8001300000010B1C60003A1 -:101920000000000C2980000000000010205300007F -:101930000000000C295200000000000C2952000396 -:101940000000001006C200020000000C2952000234 -:101950000000000022C58C00000000002765000088 -:101960000000000026E4000000000008220000162D -:1019700000000010B1C60003000000002348000072 -:1019800000000010B18000050000000023480000A6 -:101990000000000C298000000000000F0F5000071D -:1019A000000000188000001200000008220000164D -:1019B0000000000C2980000000000000301400002E -:1019C00000000000309500000000001007500003E8 -:1019D000000000090B1600FF000000090D1A00FFAF -:1019E0000000000F311600080000000031623400D2 -:1019F00000000003F162300000000010205F0000D2 -:101A0000000000002C510000000000092CD1007FD4 -:101A1000000000082CD90000000000082D00000084 -:101A2000000000082D80000C0000000000000000F5 -:101A30000000001091DE00000000001005C200044C -:101A4000000000080F8000070000000033000000C5 -:101A500000000010009F0000000000188000FE86BB -:101A6000000000002A0000000000000F0F500007D7 -:101A700000000010B1C6002D0000000F4742000812 -:101A800000000009070E000F00000008070E000804 -:101A900000000010001F0000000000080900000105 -:101AA0000000000709121C0000000003CBCA9200CE -:101AB000000000000B97A2000000000742171C0066 -:101AC000000000000B0400000000000F0A84000367 -:101AD000000000000A959C00000000004A009A00E7 -:101AE0000000000882120001000000010C1708002D -:101AF000000000000C978C0000000000021800009D -:101B0000000000080D00FFFF000000080F80000625 -:101B10000000000C290000000000001006C20004B4 -:101B20000000000C295200020000001026420002B2 -:101B30000000000C295200030000000822000001F0 -:101B400000000010009F000000000010B197320C50 -:101B500000000000231B0000000000002711080007 -:101B600000000000669000000000000C29800000CA -:101B700000000000021800000000001020530000C8 -:101B80000000000C295200030000000022C53600AE -:101B900000000010001F0000000000080F80000679 -:101BA000000000188000FFF400000000231B00006C -:101BB00000000000271108000000000066900000EF -:101BC00000000010B1C8000B0000000C29800000CC -:101BD00000000010205300000000000C29520000FB -:101BE0000000000C295200030000001006C2000291 -:101BF0000000000C295200020000000022C58C00E9 -:101C000000000000276500000000000026E400003E -:101C10000000000023480000000000082200001718 -:101C20000000000C2980000000000010001F0000D0 -:081C3000000000188000FE4BCB -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex new file mode 100644 index 000000000000..435203d64305 --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex @@ -0,0 +1,392 @@ +:1000000000000000000008F800000058000000098F +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000E88000009500000000500000000CC +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F05060011000000080500FFFF4A +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C80010C85 +:10010000000000082D000008000000082D800001FC +:10011000000000188000003C0000000B2FDF0002F0 +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000042D2 +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000008E000000188000000041 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000008D00000018800000B74A +:10024000000000188000008400000018800000DA20 +:10025000000000188000002B000000188000000043 +:10026000000000188000006B0000001091D4000016 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000180002000000000000068200009C +:1002C00000000010B18F000400000010B18F140373 +:1002D000000000082A0000010000001091D4000076 +:1002E000000000000780140000000018000D00004E +:1002F00000000000050200000000001091DE000078 +:1003000000000018000A0000000000000682000043 +:100310000000001091DE0000000000090561FFFFF1 +:1003200000000010918A00020000000830E1FFFF89 +:10033000000000188000FFA9000000010561140002 +:1003400000000010918A000200000008B0E10001E6 +:1003500000000018000D00000000000006820000F0 +:100360000000001091DE0000000000090562FFFFA0 +:1003700000000010918A0002000000083162FFFFB7 +:10038000000000188000FF9F0000000105621400BB +:1003900000000010918A000200000008B162000114 +:1003A00000000018000D000000000010B1A0B01304 +:1003B0000000000B2FDF0002000000002C200000D6 +:1003C000000000082C800000000000082D00000044 +:1003D0000000001091D40000000000080500005546 +:1003E000000000188000FFDB000000082D80011CC9 +:1003F00000000010001F0000000000188000FFE255 +:100400000000000F476000080000000F060E00010A +:10041000000000000F580000000000000A64000007 +:10042000000000000AE50000000000090B66FFFF65 +:10043000000000000D6100000000001880000015A1 +:100440000000000F476000080000000B2FDF0002D3 +:10045000000000082C800000000000082D000000B3 +:100460000000001091D40000000000082D80011C45 +:100470000000000F060E000100000010001F000029 +:10048000000000000F580000000000188000FFD09E +:10049000000000000A640000000000000AE50000FF +:1004A000000000090B66FFFF000000000D61000066 +:1004B00000000000026200000000000002E00000F6 +:1004C0000000000B2FDF00020000000030050000DC +:1004D000000000003104000000000000309A00001D +:1004E000000000100060000A00000008051600016E +:1004F00000000010BA9A140300000000030000007E +:100500000000001880000006000000188000FF6C4A +:1005100000000010B60614040000000803060001E5 +:10052000000000082A000001000000188000FF7190 +:10053000000000000C961800000000090C99FFFF55 +:1005400000000004CC99340000000010BA992C027D +:10055000000000080F8000000000000C298000014E +:100560000000000C295200010000000C295200007C +:100570000000000822800002000000080200000EB7 +:10058000000000080280001A00000010B1C40A0236 +:1005900000000008020000030000000C1F800001A2 +:1005A000000000002ADF0000000000002A00080010 +:1005B000000000188000FF600000000B2FDF000229 +:1005C0000000001091D40000000000082A00000183 +:1005D000000000002C2000000000001091D400005A +:1005E000000000082C800000000000082D00000022 +:1005F000000000082D80011C000000188000FF9FF3 +:10060000000000082C800006000000082D000006F5 +:1006100000000000308000000000000031000000F9 +:10062000000000082D8000060000000C2980000159 +:100630000000000C1F8000010000001091DE00008F +:10064000000000002ADF0000000000082A0000105F +:100650000000000807800000000000188000FF4B29 +:100660000000001091D4000000000008050000AA5E +:10067000000000188000FF890000000C29800001A4 +:100680000000000C1F800001000000082A00000983 +:10069000000000188000FF440000001091D400000A +:1006A0000000000805000055000000188000FF82CF +:1006B0000000001091A0B00200000010B1E6620737 +:1006C0000000000B2FDF0002000000002C310000B2 +:1006D000000000092CB1007F000000082CD90000A8 +:1006E000000000082D000000000000082D80010D12 +:1006F00000000010B1A8000600000010205F0000FC +:10070000000000002C200000000000002CA70000CA +:10071000000000082D000010000000082D800108D6 +:10072000000000188000FF7A00000010B1A6001041 +:1007300000000010001F00000000000F0F30000735 +:10074000000000000A600000000000000AE1000054 +:100750000000000F4B620008000000090B1600FFAC +:10076000000000000D620000000000090D1A00FFEB +:1007700000000010073000030000000C0D1A0008F4 +:100780000000000C0B1600080000000F4CE30018DE +:10079000000000000C992C0000000004CC993400EB +:1007A000000000080F8000000000000C29800001FC +:1007B0000000000033310000000000082200001695 +:1007C000000000002ADF0000000000082A00000CE2 +:1007D00000000010009F0000000000002C2000001E +:1007E0000000000C1F800001000000188000FF19AD +:1007F0000000001091D4000000000008050000AACD +:10080000000000188000FF570000000F472200087A +:1008100000000009070E000F00000008070E000886 +:1008200000000008028000010000000702851C0093 +:1008300000000008828500010000000002854C00D5 +:100840000000000742851C0000000003C3AA5200FC +:100850000000000003B10E00000000074B071C0061 +:100860000000000F0F3000070000000F0A96000381 +:10087000000000000A955C00000000004A005A00D9 +:10088000000000000C960A00000000090C99FFFF10 +:10089000000000080D00FFFF00000010BA992C02B4 +:1008A000000000080F80000500000010B1A800083B +:1008B00000000010205F00000000000B2FDF00028E +:1008C000000000002C200000000000002CA7000009 +:1008D000000000082D000010000000082D80010815 +:1008E000000000188000FF420000000C2980000179 +:1008F00000000010001F00000000000C1F8000011D +:10090000000000002ADF0000000000082A00000D9F +:10091000000000188000FEF40000001091D40000D8 +:100920000000000805000055000000188000FF329C +:100930000000000C298000010000000C1F80000155 +:10094000000000082A000007000000188000FEEDEB +:1009500000000010B18000040000001F0506001117 +:1009600000000008050000FF000000180002000061 +:10097000000000002A00000000000010B1D40000B8 +:100980000000001091DE0000000000102053000065 +:1009900000000010001F0000000000002F80AA00CF +:1009A0000000000C29800001000000080254000F24 +:1009B000000000002C400000000000000F4000007C +:1009C000000000092952003F000000180004000048 +:1009D00000000018800000110000001880000012C4 +:1009E000000000188000003800000018800001118D +:1009F0000000001880000110000000188000010FA6 +:100A0000000000188000010F0000001880000000A6 +:100A10000000001880000128000000188000010B71 +:100A20000000001880000000000000188000012C69 +:100A3000000000188000017A000000188000005AB1 +:100A400000000018800000C400000018800000C5ED +:100A50000000001880000104000000002A000000CF +:100A6000000000188000FFE3000000002A000000E2 +:100A70000000000C29800000000000188000FFE04A +:100A80000000001800020000000000000502000045 +:100A900000000010B99A2C2100000010205F000017 +:100AA000000000002C1E0000000000082C80000642 +:100AB000000000082D000006000000082D80010243 +:100AC00000000000000000000000001091DE0000A7 +:100AD000000000000D61000000000018000A000086 +:100AE000000000000502000000000010B99A2C165A +:100AF00000000010205F00000000000009D8000086 +:100B0000000000002C1E0000000000082C80010ED8 +:100B1000000000082D00000A000000082D800102DE +:100B200000000000000000000000001091DE000046 +:100B3000000000000D620000000000002C13000007 +:100B400000000018000A000000000000050200007C +:100B500000000010B99A2C0900000010205F00006E +:100B6000000000002C1E0000000000082C80000681 +:100B7000000000082D00006A000000082D8001021E +:100B800000000000000000000000001091DE0000E6 +:100B9000000000000D7A000000000018000A0000AC +:100BA000000000002A0000000000000822000001F0 +:100BB000000000000D6100000000001021C20024B0 +:100BC00000000010B1C6000200000010234200A285 +:100BD000000000090B66FFFF00000010BA9A2C20ED +:100BE000000000000A640000000000000AE50000A8 +:100BF000000000000C000000000000000B8000005E +:100C0000000000080CC60012000000188000FFD091 +:100C1000000000080F80000300000000000000003A +:100C200000000010009F00000000000827110012C3 +:100C3000000000006690000000000010B198000362 +:100C400000000010001F0000000000080F800004DA +:100C50000000000822000003000000082C80000CA7 +:100C6000000000082D00000C00000010009F000094 +:100C70000000001091C6000500000010001F0000D9 +:100C800000000010BA9A2C03000000080F80000436 +:100C9000000000188000FFFD000000002596000005 +:100CA0000000000C29800000000000003214000049 +:100CB00000000000329500000000000573662C0063 +:100CC0000000000031E32E00000000082D8000101D +:100CD000000000188000FF950000000023000000C5 +:100CE0000000000925E6FFFF000000082200000BBD +:100CF0000000000C695200000000000C2980000078 +:100D0000000000188000FF8F000000002A00000093 +:100D1000000000082C800040000000082D0000208A +:100D2000000000082D80011C0000000822000001C6 +:100D30000000001091DE00000000000F42EA0010E9 +:100D400000000010004F000400000010B7469200A1 +:100D5000000000080249001200000010B5840A00DB +:100D6000000000000D61000000000010BA6634575A +:100D7000000000088305001200000010004F000270 +:100D800000000000034900000000000183068C0001 +:100D90000000000083C60C0000000010B1870013A3 +:100DA000000000000B6E0000000000090569FFFF55 +:100DB00000000010918A00020000000834E9FFFFE3 +:100DC000000000188000FF74000000010569140095 +:100DD00000000010918A000200000008B4E9000140 +:100DE00000000010BAE92C480000000086692C00C1 +:100DF00000000000020000000000000902EAFFFFFE +:100E000000000010000C00020000000002040A00B4 +:100E10000000000F460C00010000000F02850001D9 +:100E200000000010918C01FC00000010B7040E3F80 +:100E3000000000000D610000000000000A640000D6 +:100E4000000000000AE50000000000090B66FFFF3B +:100E5000000000000C000000000000000B800000FB +:100E6000000000080C860012000000080F8000033C +:100E70000000000C2952000000000010009F00003C +:100E8000000000082711001200000000669000001A +:100E9000000000002306000000000010B1980005CB +:100EA00000000010001F0000000000080F80000478 +:100EB000000000000000000000000010001F000003 +:100EC0000000000032140000000000003295000015 +:100ED0000000000031E32E000000000573662C00C6 +:100EE000000000002596000000000010B1870016E9 +:100EF0000000000C298000000000000F0F6B0007AD +:100F0000000000000D690000000000000A6C0000F5 +:100F1000000000000AED0000000000000B6E000061 +:100F2000000000000B800000000000000C870000A3 +:100F3000000000080F800003000000102053000094 +:100F40000000000C6952000100000010001F0000AA +:100F50000000000022C58C0000000000231B0000E0 +:100F60000000000027110000000000002690000093 +:100F700000000010B8170E030000000C29800000CC +:100F8000000000188000FFF600000010B198000279 +:100F9000000000080F800004000000082200001A72 +:100FA000000000082C80000C000000082D00000C40 +:100FB000000000082D80001000000010001F00003D +:100FC000000000000D6E000000000003E7CF3400B9 +:100FD0000000000C298000000000001091DE0000DD +:100FE00000000010B1870007000000003614000068 +:100FF00000000000369500000000000037160000D9 +:10100000000000082C800050000000082D00003077 +:10101000000000082D80000C000000188000FF2C4C +:1010200000000000230000000000000925E6FFFF8B +:10103000000000000B6E000000000003E7CF2C0052 +:10104000000000082200001B0000000C6952000094 +:101050000000000C29800000000000188000FF2420 +:10106000000000002A000000000000188000FF229D +:10107000000000002A0000000000000C2980000091 +:101080000000001091DE0000000000082C80001A13 +:10109000000000082D00001A000000057366000023 +:1010A000000000082D8000020000000031800000D8 +:1010B0000000001091DE0000000000082C80000CF1 +:1010C000000000082D00000C000000082D80000426 +:1010D000000000188000FF150000000806660001EF +:1010E00000000010BA9A197F000000000A64000096 +:1010F000000000000AE50000000000090B66FFFF89 +:10110000000000000C000000000000000B80000048 +:10111000000000080CC60012000000188000FF2E1E +:10112000000000080F800003000000000000000025 +:1011300000000010009F00000000000827110012AE +:10114000000000006690000000000010919B32003B +:10115000000000100293000000000010B19800038E +:1011600000000010001F0000000000080F800004B5 +:101170000000000C2980000000000010001F00008B +:1011800000000010BA9A2C000000000031E32E008D +:10119000000000000B800000000000008CCC8C00E0 +:1011A00000000010B5CC8C02000000080C8000018B +:1011B000000000188000FF1B000000080F800003E3 +:1011C00000000010205300000000000C69520001D4 +:1011D0000000000022C58C0000000010009F0000ED +:1011E0000000000027110000000000002690000011 +:1011F00000000000231B000000000010B198000355 +:1012000000000010001F0000000000080F80000414 +:101210000000000822000003000000082C80000CE1 +:10122000000000082D00000C00000010009F0000CE +:1012300000000000259600000000000C298000003E +:101240000000000032140000000000003295000091 +:101250000000000573662C000000000031E32E0042 +:10126000000000082D800010000000188000FEE241 +:10127000000000188000FEE1000000002A000000CD +:1012800000000010001F0000000000000F008000A0 +:10129000000000080F800007000000188000001BFD +:1012A00000000000280A0000000000000502000005 +:1012B00000000008220000090000000029000000D2 +:1012C0000000000F6568001000000000248A000084 +:1012D00000000003F66C940000000010B972A00436 +:1012E0000000000C73E700190000000C214200040C +:1012F000000000003CF800000000000C2980000005 +:101300000000001020530000000000082200000828 +:101310000000000C6142000400000018000A0000F8 +:1013200000000000050200000000000C6142000007 +:1013300000000010014200030000000C33E7001D14 +:101340000000000C6142000200000018000A0000CA +:10135000000000002A00000000000010001F000034 +:101360000000000F0F470007000000080F80000872 +:101370000000000C2980000000000010009F000009 +:10138000000000188000FEBF000000003351000084 +:10139000000000002A00000000000010B1C6002379 +:1013A0000000000F0F500007000000000A6000005E +:1013B000000000000AE100000000000F4B6200087E +:1013C000000000090B1600FF0000000F4C62001027 +:1013D000000000000D620000000000090D1A00FF6F +:1013E00000000010075000030000000C0D1A000858 +:1013F0000000000C0B160008000000000CC60000E6 +:10140000000000000B8000000000000006980000B3 +:10141000000000080F8000030000001006C2000456 +:101420000000000C2900000200000010264200020B +:101430000000000C295200030000000822000001F7 +:1014400000000010009F000000000000231B0000AF +:101450000000000027111A00000000006690000044 +:101460000000000C2952000000000010B197320962 +:101470000000000C29800000000000000698000019 +:1014800000000010205300000000000C295200034F +:101490000000000022C58C0000000010001F0000AA +:1014A000000000080F800003000000188000FFF318 +:1014B00000000010B1C8001300000010B1C6000306 +:1014C0000000000C298000000000001020530000E4 +:1014D0000000000C295200000000000C29520003FB +:1014E0000000001006C200020000000C2952000299 +:1014F0000000000022C58C000000000027650000ED +:101500000000000026E40000000000082200001691 +:1015100000000010B1C600030000000023480000D6 +:1015200000000010B180000500000000234800000A +:101530000000000C298000000000000F0F50000781 +:1015400000000018800000120000000822000016B1 +:101550000000000C29800000000000003014000092 +:10156000000000003095000000000010075000034C +:10157000000000090B1600FF000000090D1A00FF13 +:101580000000000F31160008000000003162340036 +:1015900000000003F162300000000010205F000036 +:1015A000000000002C510000000000092CD1007F39 +:1015B000000000082CD90000000000082D000000E9 +:1015C000000000082D80000C00000000000000005A +:1015D0000000001091DE00000000001005C20004B1 +:1015E000000000080F80000700000000330000002A +:1015F00000000010009F0000000000188000FE7036 +:10160000000000002A0000000000000F0F5000073B +:1016100000000010B1C6002D0000000F4742000876 +:1016200000000009070E000F00000008070E000868 +:1016300000000010001F0000000000080900000169 +:101640000000000709121C0000000003CBCA920032 +:10165000000000000B97A2000000000742171C00CA +:10166000000000000B0400000000000F0A840003CB +:10167000000000000A959C00000000004A009A004B +:101680000000000882120001000000010C17080091 +:10169000000000000C978C00000000000218000001 +:1016A000000000080D00FFFF000000080F8000068A +:1016B0000000000C290000000000001006C2000419 +:1016C0000000000C29520002000000102642000217 +:1016D0000000000C29520003000000082200000155 +:1016E00000000010009F000000000010B197320CB5 +:1016F00000000000231B000000000000271108006C +:1017000000000000669000000000000C298000002E +:10171000000000000218000000000010205300002C +:101720000000000C295200030000000022C5360012 +:1017300000000010001F0000000000080F800006DD +:10174000000000188000FFF400000000231B0000D0 +:101750000000000027110800000000006690000053 +:1017600000000010B1C8000B0000000C2980000030 +:1017700000000010205300000000000C295200005F +:101780000000000C295200030000001006C20002F5 +:101790000000000C295200020000000022C58C004D +:1017A00000000000276500000000000026E40000A3 +:1017B000000000002348000000000008220000177D +:1017C0000000000C2980000000000010001F000035 +:0817D000000000188000FE3546 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex deleted file mode 100644 index f325e6904edb..000000000000 --- a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex +++ /dev/null @@ -1,499 +0,0 @@ -:100000000000000000000E80000000580000000901 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000FA800000ED800000005000000001E -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F03030300000000080500FFFF5D -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F006B00000010213F0003E3 -:1000D0000000001020BF003A000000188000FFFD63 -:1000E00000000010B1B8B0150000000B2FDF0002B7 -:1000F0000000000003D80000000000002C380000C1 -:10010000000000082C800000000000082D00000006 -:100110000000001091D400000000000806005555B2 -:10012000000000188000008F000000082D80011CD6 -:1001300000000008020000010000001091DE000035 -:100140000000000F42E0001C0000001091840A161D -:1001500000000018800000960000000C29800002BA -:100160000000000C1F800002000000002ADF0000D9 -:10017000000000082A00000F000000000500000039 -:10018000000000188000FFE60000000802000001E7 -:100190000000000F42E0001C0000001091840A18CB -:1001A000000000082C800006000000082D0000065A -:1001B0000000001091D40000000000082D8001060E -:1001C0000000001880000085000000188000FFF18A -:1001D00000000008B1000001000000082C80010CA4 -:1001E000000000082D000008000000082D8000011C -:1001F000000000188000007F0000000B2FDF0002CD -:100200000000000C1F800002000000002C0700000E -:100210000000001091DE00000000000805005555A8 -:10022000000000188000FFD20000000B2FDF00024A -:100230000000000C1F800000000000002C070000E0 -:100240000000001091DE0000000000080500555578 -:10025000000000188000FFCC0000000C1F8000028E -:100260000000000805005555000000188000FFC977 -:100270000000000C298000020000000C1F8000021A -:10028000000000002ADF0000000000082A0000052E -:100290000000000805005555000000188000FFC34D -:1002A000000000080224004A0000001800040000BA -:1002B000000000188000001C000000188000001ED4 -:1002C000000000188000007800000018800000CBBB -:1002D00000000018800000CA000000188000000024 -:1002E00000000018800000000000001880000000DE -:1002F00000000018800000000000001880000000CE -:1003000000000018800000000000001880000000BD -:100310000000001880000000000000188000011696 -:10032000000000188000000000000018800000009D -:100330000000001880000015000000188000001B5D -:10034000000000188000000000000018800000E19C -:10035000000000188000002F000000188000011627 -:100360000000001880000141000000188000010C0E -:100370000000001880000165000000188000006186 -:100380000000001880000000000000188000009E9F -:100390000000000C1F8000010000000005000000AC -:1003A000000000188000FFA20000001091D400009F -:1003B0000000000C298000010000000C1F800001DB -:1003C000000000082A0000020000000005000000F4 -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F0000000000029420000000000082A0000025E -:100400000000000005000000000000188000FF95BB -:10041000000000188000FF9400000010B1BCB00A7A -:100420000000000B2FDF00020000000003D80000D6 -:10043000000000002C3C00000000001091D40000DF -:100440000000000806005555000000188000002A32 -:1004500000000018800000DA000000102C6201BAD1 -:100460000000001880000006000000082C80010D2C -:10047000000000082D0000090000001091D40000C9 -:10048000000000082D8001070000001880000037E0 -:100490000000000C298000000000000C1F800000FC -:1004A0000000001091DE0000000000002ADF0000C4 -:1004B000000000082A00000600000008050055554D -:1004C000000000188000FF7E0000001091D40000A2 -:1004D0000000000C298000010000000C1F800001BA -:1004E000000000082A00000B0000000005000000CA -:1004F000000000188000FF780000000002020000E9 -:1005000000000000029A000000000000060C2C0011 -:1005100000000004C60C340000000010001F0000A2 -:1005200000000010B196180C0000000806960004A8 -:1005300000000009068DFFFC00000004CD051A0034 -:1005400000000004CC9A18000000001020D7000022 -:100550000000000C2B56000000000000000000000E -:1005600000000000000000000000001020D7000084 -:10057000000000080F80000100000010B18001F4AD -:1005800000000010001F00000000000C6B5600006F -:1005900000000018000400000000000006820000B7 -:1005A00000000010B18A000800000010B18C140790 -:1005B0000000000B050AFFFF00000010B18A0003D5 -:1005C00000000000860A180000000010918C000056 -:1005D000000000082A0000010000001091D4000073 -:1005E00000000018000D00000000000005020000DF -:1005F0000000001091DE000000000018000A00005A -:1006000000000000068200000000001091DE0000E3 -:1006100000000010BEE10005000000188000FF4C43 -:10062000000000010561140000000010918A000222 -:1006300000000008B0E1000100000018000D0000FB -:1006400000000000068200000000001091DE0000A3 -:1006500000000010BEE20005000000188000FF440A -:10066000000000010562140000000010918A0002E1 -:1006700000000008B162000100000018000D000039 -:1006800000000010B1A0B0130000000B2FDF00022B -:10069000000000002C200000000000082C8000005A -:1006A000000000082D0000000000001091D40000A0 -:1006B0000000000806005555000000188000FFDC0F -:1006C000000000082D80011C00000010001F000029 -:1006D000000000188000FFE60000000F47600008DF -:1006E0000000000F060E0001000000000F5800007F -:1006F000000000000A640000000000000AE500009D -:10070000000000090B66FFFF000000000D61000003 -:1007100000000018800000130000000F4760000870 -:100720000000000B2FDF0002000000082C800000FA -:10073000000000082D0000000000001091D400000F -:10074000000000082D80011C0000000F060E0001B3 -:1007500000000010001F0000000000000F58000003 -:10076000000000188000FFD4000000000A640000B0 -:10077000000000000AE50000000000090B66FFFF12 -:10078000000000000D610000000000000262000097 -:100790000000000B2FDF0002000000003104000009 -:1007A00000000000309A0000000000090560000F02 -:1007B00000000010B18A000B0000000005634C002F -:1007C00000000008050A001200000010B9621403BE -:1007D0000000000003000000000000188000000678 -:1007E000000000188000FF1100000010B60614047D -:1007F0000000000803060001000000082A000001B4 -:10080000000000188000FF16000000188000FF9E06 -:100810000000000C298000010000000C295200019A -:100820000000000C29520000000000080200000E29 -:10083000000000080280001A00000010B1C40A0283 -:100840000000000802000003000000082200000170 -:100850000000000C1F800001000000002ADF0000E3 -:10086000000000002A00080000000008050055559F -:10087000000000188000FF080000000B2FDF0002BE -:100880000000001091D40000000000082A000001C0 -:10089000000000002C2000000000001091D4000097 -:1008A000000000082C800000000000082D0000005F -:1008B000000000082D80011C000000188000FFA629 -:1008C000000000082C800006000000082D00000633 -:1008D0000000000030800000000000003100000037 -:1008E000000000082D8000060000000C2980000197 -:1008F0000000000C1F8000010000001091DE0000CD -:10090000000000002ADF0000000000082A0000109C -:100910000000000005000000000000188000FEF349 -:100920000000001091A0B009000000082C80010D0B -:10093000000000082D0000090000001091D4000004 -:10094000000000082D800107000000188000FF9FB4 -:10095000000000188000001000000008AC0000013A -:10096000000000188000000B000000000380B000B1 -:100970000000000B2FDF0002000000002C004000F0 -:100980000000001091D4000000000008060055553A -:10099000000000188000FF81000000188000003176 -:1009A00000000018800000060000000B2FDF00028E -:1009B000000000002C000E00000000082A000007C4 -:1009C0000000000805005555000000188000FEDDFD -:1009D00000000000068200000000000C29800001D9 -:1009E0000000000C1F800001000000100CE7000751 -:1009F000000000090562FFFF00000010BA6C14053A -:100A0000000000002ADF00000000000021000000BC -:100A1000000000082A0000050000001091D400002A -:100A2000000000082C80010C000000082D000008C8 -:100A30000000000C31620018000000082D80000149 -:100A4000000000188000FF7500000018000D000075 -:100A500000000010B1A0B00E0000000B2FDF00025C -:100A60000000000003D80000000000002C2000005F -:100A70000000001091D40000000000188000001554 -:100A8000000000102C620002000000188000000C22 -:100A90000000000B2FDF0002000000002C07000008 -:100AA0000000000C1F8000010000001091DE00001B -:100AB000000000080500FFFF000000188000FEBFD6 -:100AC000000000082C80010D000000082D00000926 -:100AD0000000001091D40000000000082D800107E4 -:100AE000000000188000FF6C0000000C298000014D -:100AF0000000000C1F8000010000001091DE0000CB -:100B0000000000002ADF0000000000082A00000AA0 -:100B10000000000005000000000000188000FEB387 -:100B20000000000006820000000000082C80010C7C -:100B3000000000082D000008000000082D8001348E -:100B4000000000000000000000000010205F000016 -:100B5000000000082C800140000000082D00003C2F -:100B6000000000082D80011C0000000000000000B3 -:100B70000000001091DE0000000000082C800080C2 -:100B8000000000082D000000000000082D80010575 -:100B900000000010BEE20005000000188000FE9C6E -:100BA000000000010562140000000010918A00029C -:100BB00000000008B16200010000001091DE00009A -:100BC00000000018000D00000000001091D400008B -:100BD000000000080600AAAA000000188000FF38E4 -:100BE0000000000C298000010000000C1F800001A3 -:100BF000000000082A000009000000080500AAAA59 -:100C0000000000188000FE960000001091D4000043 -:100C10000000000806005555000000188000FF3055 -:100C20000000001091A03C0200000010B1E6620735 -:100C30000000000B2FDF0002000000002C3100003C -:100C4000000000092CB1007F000000082CD9000032 -:100C5000000000082D000000000000082D80010D9C -:100C600000000010B1A8000600000010205F000086 -:100C7000000000002C200000000000002CA7000055 -:100C8000000000082D000010000000082D80010861 -:100C9000000000188000FF2B00000010B1A600101B -:100CA00000000010001F00000000000F0F300007C0 -:100CB000000000000A600000000000000AE10000DF -:100CC0000000000F4B620008000000090B1600FF37 -:100CD000000000000D620000000000090D1A00FF76 -:100CE00000000010073000030000000C0D1A00087F -:100CF0000000000C0B1600080000000F4CE3001869 -:100D0000000000000C992C0000000004CC99340075 -:100D1000000000080F8000000000000C2980000186 -:100D2000000000003331000000000008220000161F -:100D3000000000002ADF0000000000082A00000C6C -:100D400000000010009F0000000000000F200000C5 -:100D50000000000C1F800001000000080500555530 -:100D6000000000188000FE6A0000001091D400000E -:100D7000000000080600AAAA000000188000FF0476 -:100D80000000000F4722000800000009070E000FB6 -:100D900000000008070E00080000000802800001A3 -:100DA0000000000702851C00000000088285000189 -:100DB0000000000002854C000000000742851C0076 -:100DC00000000003C3AA52000000000003B10E009F -:100DD000000000074B071C000000000F0F30000749 -:100DE0000000000F0A960003000000000A955C0056 -:100DF000000000004A005A00000000000C960A00A3 -:100E0000000000090C99FFFF000000080D00FFFF23 -:100E100000000010B1963202000000080F800005AB -:100E200000000010B1A8000800000010205F0000C2 -:100E30000000000B2FDF0002000000002C2000004B -:100E4000000000002CA70000000000082D0000108A -:100E5000000000082D800108000000188000FEF24C -:100E60000000000C2980000100000010001F00009D -:100E70000000000C1F800001000000002ADF0000BD -:100E8000000000082A00000D000000080500AAAAC2 -:100E9000000000188000FE440000001091D4000003 -:100EA0000000000806005555000000188000FEDE16 -:100EB0000000000C298000010000000C1F800001D0 -:100EC000000000082A000007000000080500555532 -:080ED000000000188000FE3C48 -:080ED80000000010B1800004CD -:100EE0000000001F0303030000000008050000FFCE -:100EF0000000001800020000000000002A000000AE -:100F000000000010B1D400000000001091DE0000CD -:100F1000000000102053000000000010001F00001F -:100F20000000000C6BD70001000000002F80AA0019 -:100F30000000000C29800001000000080254000F8E -:100F4000000000002C400000000000092952003F72 -:100F500000000018000400000000001880000010CD -:100F60000000001880000011000000188000004AF6 -:100F700000000018800001280000001880000127F0 -:100F800000000018800001260000001880000126E3 -:100F90000000001880000000000000188000013FE1 -:100FA0000000001880000122000000188000000BE3 -:100FB0000000001880000145000000188000019A20 -:100FC000000000188000007B00000018800000F97D -:100FD0000000001880000109000000002A00000045 -:100FE000000000188000FFE4000000002A0000005C -:100FF0000000000C29800000000000188000FFE1C4 -:10100000000000002A000000000000188000FFDF40 -:101010000000000003820000000000188000FFDADA -:10102000000000010C161400000000008C181400D1 -:101030000000001091980003000000080C960002C8 -:1010400000000010B1800003000000080C960001B1 -:10105000000000000C000000000000000D1900005E -:1010600000000010205600000000000C2BD70001EB -:10107000000000080F8000010000000000000000D8 -:1010800000000010001F00000000000C6BD70001E2 -:1010900000000010011301F100000018000700001B -:1010A00000000000050200000000001091963421AD -:1010B00000000010205F0000000000002C1E000057 -:1010C000000000082C800006000000082D0000062B -:1010D000000000082D800102000000000000000058 -:1010E0000000001091DE0000000000000D61000013 -:1010F00000000018000A00000000000005020000C7 -:10110000000000109196341600000010205F0000CF -:101110000000000009D80000000000002C1E0000A4 -:10112000000000082C80010E000000082D00000ABD -:10113000000000082D8001020000000000000000F7 -:101140000000001091DE0000000000000D620000B1 -:10115000000000002C13000000000018000A00002E -:101160000000000005020000000000109196340904 -:1011700000000010205F0000000000002C1E000096 -:10118000000000082C800006000000082D00006A06 -:10119000000000082D800102000000000000000097 -:1011A0000000001091DE0000000000000D7A000039 -:1011B00000000018000A0000000000002A000000E3 -:1011C000000000000D61000000000000036200004C -:1011D00000000010234200DB0000000002638C00CE -:1011E0000000000026460000000000080204001273 -:1011F00000000010B906082E000000000F58000083 -:10120000000000000A640000000000000AE5000081 -:10121000000000090B66FFFF000000000C0000004A -:10122000000000000B800000000000080CC6001247 -:10123000000000188000FFCE0000001020560000C3 -:101240000000000C2BD70001000000080F800003F5 -:10125000000000000000000000000010001F00005F -:101260000000000C6BD700010000000827110012DD -:10127000000000006690000000000008A31B0012A0 -:1012800000000010B198000600000010001F0000D0 -:101290000000000C6BD70001000000102056000079 -:1012A0000000000C2BD70001000000080F80000494 -:1012B0000000000822000003000000082C80000C41 -:1012C000000000082D00000C00000010001F0000AE -:1012D0000000000C6BD70001000000002596000004 -:1012E0000000000C298000000000000006660000DD -:1012F0000000000086611800000000090260000F75 -:101300000000000F0204000200000010B60C0805E7 -:101310000000000C1FBF0000000000102866000342 -:1013200000000008078F00010000000C3366001069 -:1013300000000000321400000000000032950000A0 -:101340000000000573662C000000000031E32E0051 -:10135000000000082D800010000000188000FF75BC -:1013600000000000230000000000000925E6FFFF48 -:10137000000000082200000B0000000C6952000071 -:101380000000000C29800000000000102866008882 -:10139000000000188000FF6E000000002A0000001E -:1013A000000000082C800040000000082D000020F4 -:1013B000000000082D80011C00000000000000005B -:1013C0000000001091DE00000000000F42EA001053 -:1013D00000000010004F000400000010B74692000B -:1013E000000000080249001200000010B5840A0045 -:1013F000000000000D61000000000010BA66346AB1 -:10140000000000088305001200000010004F0002D9 -:1014100000000000034900000000000183068C006A -:101420000000000083C60C0000000010B18700110E -:10143000000000000B6E000000000010BEE9000577 -:10144000000000188000FF5500000001056914002D -:1014500000000010918A000200000008B4E90001B9 -:1014600000000010B1E92C5D0000000086692C002E -:1014700000000000020000000000000902EAFFFF77 -:1014800000000010000C00020000000002040A002E -:101490000000000F460C00010000000F0285000153 -:1014A00000000010918C01FC00000010B7040E54E5 -:1014B000000000000F400000000000000D6100006F -:1014C000000000000A640000000000000AE50000BF -:1014D000000000090B66FFFF000000000C00000088 -:1014E000000000000B800000000000080C860012C5 -:1014F00000000010205600000000000C2BD7000157 -:10150000000000080F8000030000000C29520000BA -:1015100000000010001F00000000000C6BD700014D -:101520000000000827110012000000006690000073 -:101530000000000026460000000000002306000016 -:1015400000000010B198000900000010001F00000A -:101550000000000C6BD700010000001020560000B6 -:101560000000000C2BD70001000000080F800004D1 -:10157000000000000000000000000010001F00003C -:101580000000000C6BD700010000000032140000C6 -:1015900000000000329500000000000031E32E0042 -:1015A0000000000573662C00000000002596000076 -:1015B00000000010B18700210000000C298000000D -:1015C0000000000F0F6B0007000000000D69000015 -:1015D000000000000A6C0000000000000AED00009E -:1015E000000000000B6E0000000000000B800000F7 -:1015F000000000000C870000000000188000FF1EA3 -:10160000000000010C161400000000008C181400EB -:10161000000000080C9600010000001091980002E4 -:10162000000000080C990001000000000D190000E6 -:10163000000000000C000000000000102056000018 -:101640000000000C2BD70001000000080F800001F3 -:1016500000000010205300000000000C695200013F -:1016600000000010001F00000000000C6BD70001FC -:101670000000000022C58C000000000023120000C2 -:10168000000000002711000000000000269000006C -:1016900000000010B8170E030000000C29800000A5 -:1016A000000000188000FFEB0000000082970E0091 -:1016B00000000000A3120A00000000082200001A27 -:1016C000000000082C80000C000000082D00000C19 -:1016D000000000082D80001000000010001F000016 -:1016E0000000000C6BD70001000000000D6E000030 -:1016F00000000003E7CF34000000000C2980000048 -:101700000000001091DE000000000010B18700070B -:1017100000000000361400000000000036950000B4 -:101720000000000037160000000000082C80005068 -:10173000000000082D000030000000082D80000C83 -:10174000000000188000FEF800000000264600009F -:1017500000000000230000000000000925E6FFFF54 -:10176000000000000B6E000000000003E7CF2C001B -:10177000000000082200001B0000000C695200005D -:101780000000000C29800000000000188000FEEF1F -:10179000000000002A00000000000010086600059C -:1017A00000000000066600000000000086611800CE -:1017B00000000009026000F000000010B60C0802F2 -:1017C000000000188000FEE8000000000682000013 -:1017D00000000010B18F000000000008878F00019A -:1017E0000000000C73660010000000082C80001838 -:1017F000000000082D000018000000082D800002E5 -:101800000000000C5FBF00000000001091DE00002F -:1018100000000018000D0000000000002A00000079 -:1018200000000010286601F5000000082C8000036D -:10183000000000082D000003000000093060FFF0E8 -:10184000000000082D8000010000000C298000002D -:101850000000001091DE0000000000082C80001A3B -:10186000000000082D00001A00000005736600004B -:10187000000000082D800002000000003180000000 -:101880000000001091DE0000000000082C80000C19 -:10189000000000082D00000C000000082D8000044E -:1018A000000000188000FECC0000001800020000BC -:1018B000000000188000FECA000000002A0000009E -:1018C00000000010001F00000000000C6BD700019A -:1018D000000000000F008000000000080F800007DB -:1018E000000000188000001B00000000280A000013 -:1018F00000000000050200000000000822000009AE -:1019000000000000290000000000000F65680010C2 -:1019100000000003F66C940000000010B972A004EF -:101920000000000C73E700190000000C21420004C5 -:10193000000000003CF800000000000C29800000BE -:1019400000000010205300000000000822000008E2 -:101950000000000C6142000400000018000A0000B2 -:1019600000000000050200000000000C61420000C1 -:1019700000000010014200030000000C33E7001DCE -:101980000000000C6142000200000018000A000084 -:10199000000000002A00000000000010001F0000EE -:1019A0000000000C6BD700010000000F0F4700077C -:1019B000000000080F8000080000000C29800000D3 -:1019C00000000010001F00000000000C6BD7000199 -:1019D000000000188000FEA6000000003351000047 -:1019E000000000002A00000000000010B1C600291D -:1019F0000000000F0F500007000000000A60000008 -:101A0000000000000AE100000000000F4B62000827 -:101A1000000000090B1600FF0000000F4C620010D0 -:101A2000000000000D620000000000090D1A00FF18 -:101A300000000010075000030000000C0D1A000801 -:101A40000000000C0B160008000000000CC600008F -:101A5000000000000B80000000000000069800005D -:101A600000000010205600000000000C2BD70001E1 -:101A7000000000080F8000030000001006C20004F0 -:101A80000000000C290000020000001026420002A5 -:101A90000000000C29520003000000082200000191 -:101AA00000000010001F00000000000C6BD70001B8 -:101AB00000000000231B00000000000027111A0096 -:101AC00000000000669000000000000C2952000099 -:101AD00000000010B197320C0000000C29800000BB -:101AE00000000000069800000000001020530000D5 -:101AF0000000000C295200030000000022C58C00E9 -:101B000000000010001F00000000000C6BD7000157 -:101B100000000010205600000000000C2BD7000130 -:101B2000000000080F800003000000188000FFEF95 -:101B300000000010B1C8001300000010B1C600037F -:101B40000000000C2980000000000010205300005D -:101B50000000000C295200000000000C2952000374 -:101B60000000001006C200020000000C2952000212 -:101B70000000000022C58C00000000002765000066 -:101B80000000000026E4000000000008220000160B -:101B900000000010B1C60003000000002348000050 -:101BA00000000010B1800005000000002348000084 -:101BB0000000000C298000000000000F0F500007FB -:101BC000000000188000001200000008220000162B -:101BD0000000000C2980000000000000301400000C -:101BE00000000000309500000000001007500003C6 -:101BF000000000090B1600FF000000090D1A00FF8D -:101C00000000000F311600080000000031623400AF -:101C100000000003F162300000000010205F0000AF -:101C2000000000002C510000000000092CD1007FB2 -:101C3000000000082CD90000000000082D00000062 -:101C4000000000082D80000C0000000000000000D3 -:101C50000000001091DE00000000001005C2000529 -:101C6000000000080F8000070000000033000000A3 -:101C700000000010001F00000000000C6BD70001E6 -:101C8000000000188000FE50000000002A00000044 -:101C90000000000F0F50000700000010B1C6003018 -:101CA0000000000F4742000800000009070E000F67 -:101CB00000000008070E000800000010001F0000D0 -:101CC0000000000C6BD700010000000809000001B3 -:101CD0000000000709121C0000000003CBCA92009C -:101CE000000000000B97A2000000000742171C0034 -:101CF000000000000B0400000000000F0A84000335 -:101D0000000000000A959C00000000004A009A00B4 -:101D10000000000882120001000000010C170800FA -:101D2000000000000C978C0000000000021800006A -:101D3000000000080D00FFFF000000080F800006F3 -:101D40000000000C290000000000001006C2000482 -:101D50000000000C29520002000000102642000280 -:101D60000000000C295200030000000822000001BE -:101D700000000010001F00000000000C6BD70001E5 -:101D800000000010B197320D00000000231B00007E -:101D9000000000002711080000000000669000000D -:101DA0000000000C29800000000000000218000064 -:101DB00000000010205300000000000C2952000316 -:101DC0000000000022C5360000000010001F0000C7 -:101DD0000000000C6BD70001000000080F80000617 -:101DE000000000188000FFF200000000231B00002C -:101DF00000000000271108000000000066900000AD -:101E000000000010B1C8000B0000000C2980000089 -:101E100000000010205300000000000C29520000B8 -:101E20000000000C295200030000001006C200024E -:101E30000000000C295200020000000022C58C00A6 -:101E400000000000276500000000000026E40000FC -:101E500000000000234800000000000822000017D6 -:101E60000000000C2980000000000010001F00008E -:101E70000000000C6BD70001000000188000FE116C -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex new file mode 100644 index 000000000000..d2f275788f16 --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex @@ -0,0 +1,425 @@ +:100000000000000000000970000000580000000916 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000001010000009C80000000500000000CA +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F03060011000000080500FFFF4C +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C80010C85 +:10010000000000082D000008000000082D800001FC +:10011000000000188000004F0000000B2FDF0002DD +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000055BF +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000009D000000188000000032 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000009C00000018800000C62C +:10024000000000188000009300000018800000E902 +:10025000000000188000003E000000188000000030 +:10026000000000188000007A0000001091D4000007 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000000202000000000000029A00009E +:1002C00000000000060C2C0000000004C60C3400E6 +:1002D00000000010001F000000000010BA8C2C0C61 +:1002E000000000080696000400000009068DFFFCCF +:1002F00000000004CD051A0000000004CC9A18008C +:100300000000001020D700000000000C2B56000059 +:1003100000000000000000000000000000000000DD +:100320000000001020D70000000000080F8000012E +:1003300000000010B18001F400000010001F000058 +:100340000000000C6B5600000000001800040000C4 +:10035000000000000682000000000010B18F0004C1 +:1003600000000010B18F1403000000082A000001F3 +:100370000000001091D4000000000000078014006D +:1003800000000018000D0000000000000502000041 +:100390000000001091DE000000000018000A0000BC +:1003A00000000000068200000000001091DE000046 +:1003B000000000090561FFFF00000010918A0002A3 +:1003C0000000000830E1FFFF000000188000FF96E9 +:1003D000000000010561140000000010918A000275 +:1003E00000000008B0E1000100000018000D00004E +:1003F00000000000068200000000001091DE0000F6 +:10040000000000090562FFFF00000010918A000251 +:10041000000000083162FFFF000000188000FF8C20 +:10042000000000010562140000000010918A000223 +:1004300000000008B162000100000018000D00007B +:1004400000000010B1A0B0130000000B2FDF00026D +:10045000000000002C200000000000082C8000009C +:10046000000000082D0000000000001091D40000E2 +:100470000000000805000055000000188000FFDBA8 +:10048000000000082D80011C00000010001F00006B +:10049000000000188000FFE20000000F4760000825 +:1004A0000000000F060E0001000000000F580000C1 +:1004B000000000000A640000000000000AE50000DF +:1004C000000000090B66FFFF000000000D61000046 +:1004D00000000018800000150000000F47600008B1 +:1004E0000000000B2FDF0002000000082C8000003D +:1004F000000000082D0000000000001091D4000052 +:10050000000000082D80011C0000000F060E0001F5 +:1005100000000010001F0000000000000F58000045 +:10052000000000188000FFD0000000000A640000F6 +:10053000000000000AE50000000000090B66FFFF54 +:10054000000000000D6100000000000002620000D9 +:100550000000000002E000000000000B2FDF00029E +:100560000000000030050000000000003104000021 +:1005700000000000309A0000000000100060000A37 +:10058000000000080516000100000010BA9A1403CC +:1005900000000000030000000000001880000006BA +:1005A000000000188000FF5900000010B606140477 +:1005B0000000000803060001000000082A000001F6 +:1005C000000000188000FF5E000000188000FF9D02 +:1005D0000000000C298000010000000C29520001DD +:1005E0000000000C295200000000000822800002D8 +:1005F000000000080200000E000000080280001A3F +:1006000000000010B1C40A0200000008020000034C +:100610000000000C1F800001000000002ADF000025 +:10062000000000002A000800000000188000FF51B0 +:100630000000000B2FDF00020000001091D400002A +:10064000000000082A000001000000002C2000002B +:100650000000001091D40000000000082C80000071 +:10066000000000082D000000000000082D80011C83 +:10067000000000188000FFA3000000082C80000686 +:10068000000000082D00000600000000308000007F +:100690000000000031000000000000082D8000066E +:1006A0000000000C298000010000000C1F800001E8 +:1006B0000000001091DE0000000000002ADF0000B2 +:1006C000000000082A000010000000080780000059 +:1006D000000000188000FF3C0000001091D40000D2 +:1006E00000000008050000AA000000188000FF8D2F +:1006F0000000000C298000010000000C1F80000198 +:10070000000000082A000009000000188000FF35E2 +:100710000000001091D40000000000080500005502 +:10072000000000188000FF860000001091A0B002B9 +:1007300000000010B1E662070000000B2FDF00028E +:10074000000000002C310000000000092CB1007FE7 +:10075000000000082CD90000000000082D00000057 +:10076000000000082D80010D00000010B1A8000657 +:1007700000000010205F0000000000002C2000009E +:10078000000000002CA70000000000082D00001051 +:10079000000000082D800108000000188000FF7E86 +:1007A00000000010B1A6001000000010001F0000A3 +:1007B0000000000F0F300007000000000A6000007A +:1007C000000000000AE100000000000F4B6200087A +:1007D000000000090B1600FF000000000D62000081 +:1007E000000000090D1A00FF000000100730000390 +:1007F0000000000C0D1A00080000000C0B16000889 +:100800000000000F4CE30018000000000C992C00C1 +:1008100000000004CC993400000000080F800000A4 +:100820000000000C298000010000000033310000AE +:100830000000000822000016000000002ADF00006F +:10084000000000082A00000C00000010009F0000BB +:10085000000000002C2000000000000C1F800001A0 +:10086000000000188000FF0A0000001091D4000072 +:1008700000000008050000AA000000188000FF5BCF +:100880000000000F4722000800000009070E000FBB +:1008900000000008070E00080000000802800001A8 +:1008A0000000000702851C0000000008828500018E +:1008B0000000000002854C000000000742851C007B +:1008C00000000003C3AA52000000000003B10E00A4 +:1008D000000000074B071C000000000F0F3000074E +:1008E0000000000F0A960003000000000A955C005B +:1008F000000000004A005A00000000000C960A00A8 +:10090000000000090C99FFFF000000080D00FFFF28 +:1009100000000010BA992C02000000080F800005AA +:1009200000000010B1A8000800000010205F0000C7 +:100930000000000B2FDF0002000000002C20000050 +:10094000000000002CA70000000000082D0000108F +:10095000000000082D800108000000188000FF46FC +:100960000000000C2980000100000010001F0000A2 +:100970000000000C1F800001000000002ADF0000C2 +:10098000000000082A00000D000000188000FEE5AD +:100990000000001091D40000000000080500005580 +:1009A000000000188000FF360000000C29800001C4 +:1009B0000000000C1F800001000000082A00000752 +:0809C000000000188000FEDEBB +:0809C80000000010B1800004E2 +:1009D0000000001F0306001100000008050000FFD2 +:1009E0000000001800020000000000002A000000C3 +:1009F00000000010B1D400000000001091DE0000E3 +:100A0000000000102053000000000010001F000034 +:100A10000000000C6BD70001000000002F80AA002E +:100A20000000000C298000010000000802540010A2 +:100A3000000000002C400000000000000F400000FB +:100A4000000000092952003F0000001800040000C7 +:100A50000000001880000011000000188000001243 +:100A600000000018800000470000001880000137D7 +:100A700000000018800001360000001880000135D9 +:100A80000000001880000135000000188000000000 +:100A9000000000188000014F0000001880000131A4 +:100AA00000000018800000000000001880000155C0 +:100AB00000000018800001A6000000188000006DF2 +:100AC00000000018800000E400000018800000E52D +:100AD000000000188000012A000000002A00000029 +:100AE000000000188000FFE2000000002A00000063 +:100AF0000000000C29800000000000188000FFDFCB +:100B00000000000003820000000000188000FFDAEF +:100B1000000000010C161400000000008C181400E6 +:100B20000000001091980003000000080C960002DD +:100B300000000010B1800003000000080C960001C6 +:100B4000000000000C000000000000000D19000073 +:100B5000000000080F8000010000000000000000FD +:100B600000000010001F00000000000C6BD7000107 +:100B700000000010011301F300000018000700003E +:100B8000000000000502000000000010B99A2C21AE +:100B900000000010205F0000000000002C1E00007C +:100BA000000000082C800006000000082D00000650 +:100BB000000000082D80010200000000000000007D +:100BC0000000001091DE0000000000000D61000038 +:100BD00000000018000A00000000000005020000EC +:100BE00000000010B99A2C1600000010205F0000D1 +:100BF0000000000009D80000000000002C1E0000CA +:100C0000000000082C80010E000000082D00000AE2 +:100C1000000000082D80010200000000000000001C +:100C20000000001091DE0000000000000D620000D6 +:100C3000000000002C13000000000018000A000053 +:100C4000000000000502000000000010B99A2C0905 +:100C500000000010205F0000000000002C1E0000BB +:100C6000000000082C800006000000082D00006A2B +:100C7000000000082D8001020000000000000000BC +:100C80000000001091DE0000000000000D7A00005E +:100C900000000018000A0000000000002A00000008 +:100CA0000000000822000001000000000D610000AB +:100CB0000000001021C2002800000010B1C6000290 +:100CC00000000010234200B3000000090B66FFFF84 +:100CD00000000010BA9A2C24000000000A640000F2 +:100CE000000000000AE50000000000000C00000009 +:100CF000000000000B800000000000080CC600127D +:100D0000000000188000FFD0000000080F800003E2 +:100D1000000000000000000000000010001F0000A4 +:100D20000000000C6BD70001000000082711001222 +:100D3000000000006690000000000010B198000460 +:100D400000000010001F00000000000C6BD7000125 +:100D5000000000080F8000040000000822000003CB +:100D6000000000082C80000C000000082D00000C82 +:100D700000000010001F00000000000C6BD70001F5 +:100D80000000001091C6000600000010001F0000C7 +:100D90000000000C6BD7000100000010BA9A2C0371 +:100DA000000000080F800004000000188000FFFC15 +:100DB00000000000259600000000000C29800000C3 +:100DC0000000000032140000000000003295000016 +:100DD0000000000573662C000000000031E32E00C7 +:100DE000000000082D800010000000188000FF8126 +:100DF00000000000230000000000000925E6FFFFBE +:100E0000000000082200000B0000000C69520000E6 +:100E10000000000C29800000000000188000FF7B0B +:100E2000000000002A000000000000082C800040A4 +:100E3000000000082D000020000000082D80011C8B +:100E400000000008220000010000001091DE0000F8 +:100E50000000000F42EA001000000010004F0004E4 +:100E600000000010B746920000000008024900127E +:100E700000000010B5840A00000000000D610000B1 +:100E800000000010BA6634640000000883050012F8 +:100E900000000010004F00020000000003490000A5 +:100EA0000000000183068C000000000083C60C00D7 +:100EB00000000010B1870013000000000B6E00005E +:100EC000000000090569FFFF00000010918A000280 +:100ED0000000000834E9FFFF000000188000FF60F8 +:100EE000000000010569140000000010918A000252 +:100EF00000000008B4E9000100000010BAE92C5518 +:100F00000000000086692C000000000002000000C4 +:100F10000000000902EAFFFF00000010000C0002C0 +:100F20000000000002040A000000000F460C00014F +:100F30000000000F0285000100000010918C01FCF0 +:100F400000000010B7040E4C000000000D6100000E +:100F5000000000000A640000000000000AE5000034 +:100F6000000000090B66FFFF000000000C000000FD +:100F7000000000000B800000000000080C8600123A +:100F8000000000080F8000030000000C2952000040 +:100F900000000010001F00000000000C6BD70001D3 +:100FA00000000008271100120000000066900000F9 +:100FB000000000002306000000000010B1980007A8 +:100FC00000000010001F00000000000C6BD70001A3 +:100FD000000000080F800004000000000000000076 +:100FE00000000010001F00000000000C6BD7000183 +:100FF00000000000321400000000000032950000E4 +:101000000000000031E32E000000000573662C0094 +:10101000000000002596000000000010B187001FAE +:101020000000000C298000000000000F0F6B00077B +:10103000000000000D690000000000000A6C0000C4 +:10104000000000000AED0000000000000B6E000030 +:10105000000000000B800000000000000C87000072 +:10106000000000188000FF2F000000010C16140083 +:10107000000000008C181400000000080C9600010D +:101080000000001091980002000000080C99000177 +:10109000000000000D190000000000000C0000001E +:1010A000000000080F800001000000102053000025 +:1010B0000000000C6952000100000010001F000039 +:1010C0000000000C6BD700010000000022C58C005E +:1010D00000000000231200000000000027110000A3 +:1010E000000000002690000000000010B8170E035A +:1010F0000000000C29800000000000188000FFEDB7 +:101100000000000082970E0000000000A3120A00F9 +:10111000000000082200001A000000082C80000CCB +:10112000000000082D00000C000000082D800010B9 +:1011300000000010001F00000000000C6BD7000131 +:10114000000000000D6E000000000003E7CF340037 +:101150000000000C298000000000001091DE00005B +:1011600000000010B18700070000000036140000E6 +:101170000000000036950000000000003716000057 +:10118000000000082C800050000000082D000030F6 +:10119000000000082D80000C000000188000FF0BEC +:1011A00000000000230000000000000925E6FFFF0A +:1011B000000000000B6E000000000003E7CF2C00D1 +:1011C000000000082200001B0000000C6952000013 +:1011D0000000000C29800000000000188000FF03C0 +:1011E000000000002A000000000000188000FF013D +:1011F000000000002A0000000000000C2980000010 +:101200000000001091DE0000000000082C80001A91 +:10121000000000082D00001A0000000573660000A1 +:10122000000000082D800002000000003180000056 +:101230000000001091DE0000000000082C80000C6F +:10124000000000082D00000C000000082D800004A4 +:10125000000000188000FEF400000008066600018F +:1012600000000010BA9A1972000000000A64000021 +:10127000000000000AE50000000000090B66FFFF07 +:10128000000000000C000000000000000B800000C7 +:10129000000000080CC60012000000188000FF1DAE +:1012A000000000080F8000030000000000000000A4 +:1012B00000000010001F00000000000C6BD70001B0 +:1012C00000000008271100120000000066900000D6 +:1012D00000000010919B32000000001002930000FB +:1012E00000000010B198000300000010001F000073 +:1012F0000000000C6BD70001000000080F80000404 +:101300000000000C2980000000000010001F0000F9 +:101310000000000C6BD7000100000010BA9A2C00EE +:101320000000000031E32E00000000000B800000F0 +:10133000000000008CCC8C0000000010B5CC8C02AA +:10134000000000080C800001000000188000FF076A +:10135000000000080F800003000000102053000070 +:101360000000000C695200010000000022C58C0042 +:1013700000000010001F00000000000C6BD70001EF +:10138000000000002711000000000000269000006F +:1013900000000000231B000000000010B1980003B3 +:1013A00000000010001F00000000000C6BD70001BF +:1013B000000000080F800004000000082200000365 +:1013C000000000082C80000C000000082D00000C1C +:1013D00000000010001F00000000000C6BD700018F +:1013E00000000000259600000000000C298000008D +:1013F00000000000321400000000000032950000E0 +:101400000000000573662C000000000031E32E0090 +:10141000000000082D800010000000188000FEBBB6 +:10142000000000188000FEBA000000002A00000042 +:1014300000000010001F00000000000C6BD700012E +:10144000000000000F008000000000080F8000076F +:10145000000000188000001C00000000280A0000A6 +:101460000000000005020000000000082200000942 +:1014700000000000290000000000000F6568001057 +:1014800000000000248A000000000003F66C9400B5 +:1014900000000010B972A0040000000C73E70019EE +:1014A0000000000C21420004000000003CF8000095 +:1014B0000000000C298000000000001020530000F4 +:1014C00000000008220000080000000C6142000437 +:1014D00000000018000A00000000000005020000E3 +:1014E0000000000C614200000000001001420003F7 +:1014F0000000000C33E7001D0000000C61420002F8 +:1015000000000018000A0000000000002A0000008F +:1015100000000010001F00000000000C6BD700014D +:101520000000000F0F470007000000080F800008B0 +:101530000000000C2980000000000010001F0000C7 +:101540000000000C6BD70001000000188000FE9521 +:101550000000000033510000000000002A000000DD +:1015600000000010B1C600250000000F0F5000075A +:10157000000000000A600000000000000AE1000016 +:101580000000000F4B620008000000090B1600FF6E +:101590000000000F4C620010000000000D6200000F +:1015A000000000090D1A00FF0000001007500003A2 +:1015B0000000000C0D1A00080000000C0B160008BB +:1015C000000000000CC60000000000000B800000BE +:1015D0000000000006980000000000080F800003D3 +:1015E0000000001006C200040000000C29000002E8 +:1015F00000000010264200020000000C29520003E7 +:10160000000000082200000100000010001F000080 +:101610000000000C6BD7000100000000231B00003D +:101620000000000027111A00000000006690000072 +:101630000000000C2952000000000010B197320A8F +:101640000000000C29800000000000000698000047 +:1016500000000010205300000000000C295200037D +:101660000000000022C58C0000000010001F0000D8 +:101670000000000C6BD70001000000080F80000381 +:10168000000000188000FFF100000010B1C8001336 +:1016900000000010B1C600030000000C298000000B +:1016A00000000010205300000000000C2952000030 +:1016B0000000000C295200030000001006C20002C6 +:1016C0000000000C295200020000000022C58C001E +:1016D00000000000276500000000000026E4000074 +:1016E000000000082200001600000010B1C6000330 +:1016F000000000002348000000000010B180000539 +:1017000000000000234800000000000C29800000B9 +:101710000000000F0F5000070000001880000012AA +:1017200000000008220000160000000C29800000C4 +:1017300000000000301400000000000030950000A0 +:101740000000001007500003000000090B1600FF06 +:10175000000000090D1A00FF0000000F31160008FC +:10176000000000003162340000000003F16230002C +:1017700000000010205F0000000000002C5100005D +:10178000000000092CD1007F000000082CD90000C7 +:10179000000000082D000000000000082D80000C53 +:1017A00000000000000000000000001091DE0000BA +:1017B0000000001005C20005000000080F800007AF +:1017C000000000003300000000000010001F0000B7 +:1017D0000000000C6BD70001000000188000FE43E1 +:1017E000000000002A0000000000000F0F5000075A +:1017F00000000010B1C600300000000F4742000892 +:1018000000000009070E000F00000008070E000886 +:1018100000000010001F00000000000C6BD700014A +:1018200000000008090000010000000709121C0068 +:1018300000000003CBCA9200000000000B97A2003A +:101840000000000742171C00000000000B0400000D +:101850000000000F0A840003000000000A959C00AD +:10186000000000004A009A000000000882120001F7 +:10187000000000010C170800000000000C978C000D +:101880000000000002180000000000080D00FFFF2B +:10189000000000080F8000060000000C2900000076 +:1018A0000000001006C200040000000C29520002D3 +:1018B00000000010264200020000000C2952000324 +:1018C000000000082200000100000010001F0000BE +:1018D0000000000C6BD7000100000010B197320D22 +:1018E00000000000231B000000000000271108007A +:1018F00000000000669000000000000C298000003D +:10190000000000000218000000000010205300003A +:101910000000000C295200030000000022C5360020 +:1019200000000010001F00000000000C6BD7000139 +:10193000000000080F800006000000188000FFF281 +:1019400000000000231B0000000000002711080019 +:10195000000000006690000000000010B1C8000BFD +:101960000000000C2980000000000010205300003F +:101970000000000C295200000000000C2952000356 +:101980000000001006C200020000000C29520002F4 +:101990000000000022C58C00000000002765000048 +:1019A0000000000026E400000000000023480000C2 +:1019B00000000008220000170000000C2980000031 +:1019C00000000010001F00000000000C6BD7000199 +:0819D000000000188000FE0475 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ -- cgit v1.2.3 From c239f279e571a272c1b32a1e84b8fa037b68f49c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 11 Oct 2010 16:12:28 -0700 Subject: bnx2: Enable AER on PCIE devices only To prevent unnecessary error message. pci_save_state() is also moved to the end of ->probe() so that all PCI config, including AER state, will be saved. Update version to 2.0.18. Signed-off-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 56f3dfe70038..ae894bca4afb 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -59,8 +59,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.17" -#define DRV_MODULE_RELDATE "July 18, 2010" +#define DRV_MODULE_VERSION "2.0.18" +#define DRV_MODULE_RELDATE "Oct 7, 2010" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" @@ -7915,16 +7915,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) goto err_out_disable; } - /* AER (Advanced Error Reporting) hooks */ - err = pci_enable_pcie_error_reporting(pdev); - if (err) { - dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed " - "0x%x\n", err); - /* non-fatal, continue */ - } - pci_set_master(pdev); - pci_save_state(pdev); bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (bp->pm_cap == 0) { @@ -7979,6 +7970,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->flags |= BNX2_FLAG_PCIE; if (CHIP_REV(bp) == CHIP_REV_Ax) bp->flags |= BNX2_FLAG_JUMBO_BROKEN; + + /* AER (Advanced Error Reporting) hooks */ + err = pci_enable_pcie_error_reporting(pdev); + if (err) { + dev_err(&pdev->dev, "pci_enable_pcie_error_reporting " + "failed 0x%x\n", err); + /* non-fatal, continue */ + } + } else { bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); if (bp->pcix_cap == 0) { @@ -8235,16 +8235,20 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2_timer; + pci_save_state(pdev); + return 0; err_out_unmap: + if (bp->flags & BNX2_FLAG_PCIE) + pci_disable_pcie_error_reporting(pdev); + if (bp->regview) { iounmap(bp->regview); bp->regview = NULL; } err_out_release: - pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable: @@ -8434,9 +8438,10 @@ bnx2_remove_one(struct pci_dev *pdev) kfree(bp->temp_stats_blk); - free_netdev(dev); + if (bp->flags & BNX2_FLAG_PCIE) + pci_disable_pcie_error_reporting(pdev); - pci_disable_pcie_error_reporting(pdev); + free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); @@ -8550,6 +8555,9 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) } rtnl_unlock(); + if (!(bp->flags & BNX2_FLAG_PCIE)) + return result; + err = pci_cleanup_aer_uncorrect_error_status(pdev); if (err) { dev_err(&pdev->dev, -- cgit v1.2.3 From 0b53d4604ac2b4f2faa9a62a04ea9b383ad2efe0 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 11 Oct 2010 20:35:40 +0200 Subject: dccp: fix the adjustments to AWL and SWL This fixes a problem and a potential loophole with regard to seqno/ackno validity: currently the initial adjustments to AWL/SWL are only performed once at the begin of the connection, during the handshake. Since the Sequence Window feature is always greater than Wmin=32 (7.5.2), it is however necessary to perform these adjustments at least for the first W/W' (variables as per 7.5.1) packets in the lifetime of a connection. This requirement is complicated by the fact that W/W' can change at any time during the lifetime of a connection. Therefore it is better to perform that safety check each time SWL/AWL are updated, as implemented by the patch. A second problem solved by this patch is that the remote/local Sequence Window feature values (which set the bounds for AWL/SWL/SWH) are undefined until the feature negotiation has completed. During the initial handshake we have more stringent sequence number protection; the changes added by this patch effect that {A,S}W{L,H} are within the correct bounds at the instant that feature negotiation completes (since the SeqWin feature activation handlers call dccp_update_gsr/gss()). Signed-off-by: Gerrit Renker --- net/dccp/dccp.h | 20 ++++++++++++++++++++ net/dccp/input.c | 18 ++++++------------ net/dccp/minisocks.c | 30 +++++++++--------------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 019d6ffee354..e051c774ef5c 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -414,6 +414,23 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq) dp->dccps_gsr = seq; /* Sequence validity window depends on remote Sequence Window (7.5.1) */ dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); + /* + * Adjust SWL so that it is not below ISR. In contrast to RFC 4340, + * 7.5.1 we perform this check beyond the initial handshake: W/W' are + * always > 32, so for the first W/W' packets in the lifetime of a + * connection we always have to adjust SWL. + * A second reason why we are doing this is that the window depends on + * the feature-remote value of Sequence Window: nothing stops the peer + * from updating this value while we are busy adjusting SWL for the + * first W packets (we would have to count from scratch again then). + * Therefore it is safer to always make sure that the Sequence Window + * is not artificially extended by a peer who grows SWL downwards by + * continually updating the feature-remote Sequence-Window. + * If sequence numbers wrap it is bad luck. But that will take a while + * (48 bit), and this measure prevents Sequence-number attacks. + */ + if (before48(dp->dccps_swl, dp->dccps_isr)) + dp->dccps_swl = dp->dccps_isr; dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4); } @@ -424,6 +441,9 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) dp->dccps_gss = seq; /* Ack validity window depends on local Sequence Window value (7.5.1) */ dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win); + /* Adjust AWL so that it is not below ISS - see comment above for SWL */ + if (before48(dp->dccps_awl, dp->dccps_iss)) + dp->dccps_awl = dp->dccps_iss; dp->dccps_awh = dp->dccps_gss; } diff --git a/net/dccp/input.c b/net/dccp/input.c index 10c957a88f4f..aecc8c7443c2 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -441,20 +441,14 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; - dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; - dccp_update_gsr(sk, dp->dccps_isr); /* - * SWL and AWL are initially adjusted so that they are not less than - * the initial Sequence Numbers received and sent, respectively: - * SWL := max(GSR + 1 - floor(W/4), ISR), - * AWL := max(GSS - W' + 1, ISS). - * These adjustments MUST be applied only at the beginning of the - * connection. - * - * AWL was adjusted in dccp_v4_connect -acme + * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect + * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH + * is done as part of activating the feature values below, since + * these settings depend on the local/remote Sequence Window + * features, which were undefined or not confirmed until now. */ - dccp_set_seqno(&dp->dccps_swl, - max48(dp->dccps_swl, dp->dccps_isr)); + dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 128b089d3aef..d7041a0963af 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -121,30 +121,18 @@ struct sock *dccp_create_openreq_child(struct sock *sk, * * Choose S.ISS (initial seqno) or set from Init Cookies * Initialize S.GAR := S.ISS - * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies - */ - newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; - dccp_update_gss(newsk, dreq->dreq_iss); - - newdp->dccps_isr = dreq->dreq_isr; - dccp_update_gsr(newsk, dreq->dreq_isr); - - /* - * SWL and AWL are initially adjusted so that they are not less than - * the initial Sequence Numbers received and sent, respectively: - * SWL := max(GSR + 1 - floor(W/4), ISR), - * AWL := max(GSS - W' + 1, ISS). - * These adjustments MUST be applied only at the beginning of the - * connection. + * Set S.ISR, S.GSR from packet (or Init Cookies) + * + * Setting AWL/AWH and SWL/SWH happens as part of the feature + * activation below, as these windows all depend on the local + * and remote Sequence Window feature values (7.5.2). */ - dccp_set_seqno(&newdp->dccps_swl, - max48(newdp->dccps_swl, newdp->dccps_isr)); - dccp_set_seqno(&newdp->dccps_awl, - max48(newdp->dccps_awl, newdp->dccps_iss)); + newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; + newdp->dccps_gar = newdp->dccps_iss; + newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; /* - * Activate features after initialising the sequence numbers, - * since CCID initialisation may depend on GSS, ISR, ISS etc. + * Activate features: initialise CCIDs, sequence windows etc. */ if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { /* It is still raw copy of parent, so invalidate -- cgit v1.2.3 From 93344af44c0f649582bf1e3b5ecc45b3d19e98c2 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 11 Oct 2010 20:36:33 +0200 Subject: dccp: merge now-reduced connect_init() function After moving the assignment of GAR/ISS from dccp_connect_init() to dccp_transmit_skb(), the former function becomes very small, so that a merger with dccp_connect() suggests itself. Signed-off-by: Gerrit Renker --- net/dccp/output.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/net/dccp/output.c b/net/dccp/output.c index aadbdb58758b..6993a9338cf7 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -474,8 +474,9 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code) /* * Do all connect socket setups that can be done AF independent. */ -static inline void dccp_connect_init(struct sock *sk) +int dccp_connect(struct sock *sk) { + struct sk_buff *skb; struct dccp_sock *dp = dccp_sk(sk); struct dst_entry *dst = __sk_dst_get(sk); struct inet_connection_sock *icsk = inet_csk(sk); @@ -485,22 +486,12 @@ static inline void dccp_connect_init(struct sock *sk) dccp_sync_mss(sk, dst_mtu(dst)); - /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ - dp->dccps_gar = dp->dccps_iss; - - icsk->icsk_retransmits = 0; -} - -int dccp_connect(struct sock *sk) -{ - struct sk_buff *skb; - struct inet_connection_sock *icsk = inet_csk(sk); - /* do not connect if feature negotiation setup fails */ if (dccp_feat_finalise_settings(dccp_sk(sk))) return -EPROTO; - dccp_connect_init(sk); + /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ + dp->dccps_gar = dp->dccps_iss; skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); if (unlikely(skb == NULL)) @@ -516,6 +507,7 @@ int dccp_connect(struct sock *sk) DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); /* Timer for repeating the REQUEST until an answer. */ + icsk->icsk_retransmits = 0; inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, DCCP_RTO_MAX); return 0; -- cgit v1.2.3 From baf9e782e1dc4991edecfa3b8700cf8739c40259 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 11 Oct 2010 20:37:38 +0200 Subject: dccp: remove unused argument in CCID tx function This removes the argument `more' from ccid_hc_tx_packet_sent, since it was nowhere used in the entire code. (Btw, this argument was not even used in the original KAME code where the function initially came from; compare the variable moreToSend in the freebsd61-dccp-kame-28.08.2006.patch kept by Emmanuel Lochin.) Signed-off-by: Gerrit Renker --- net/dccp/ccid.h | 6 +++--- net/dccp/ccids/ccid2.c | 2 +- net/dccp/ccids/ccid3.c | 3 +-- net/dccp/output.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 6d16a9070ff0..117fb093dcaf 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h @@ -73,7 +73,7 @@ struct ccid_operations { int (*ccid_hc_tx_send_packet)(struct sock *sk, struct sk_buff *skb); void (*ccid_hc_tx_packet_sent)(struct sock *sk, - int more, unsigned int len); + unsigned int len); void (*ccid_hc_rx_get_info)(struct sock *sk, struct tcp_info *info); void (*ccid_hc_tx_get_info)(struct sock *sk, @@ -144,10 +144,10 @@ static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, } static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, - int more, unsigned int len) + unsigned int len) { if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL) - ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len); + ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len); } static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk, diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index dc18172b1e59..d850e291f87c 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -151,7 +151,7 @@ out: sock_put(sk); } -static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) +static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) { struct dccp_sock *dp = dccp_sk(sk); struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index c3f3a25bbd7a..3060a60ed5ab 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -351,8 +351,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) return 0; } -static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, - unsigned int len) +static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); diff --git a/net/dccp/output.c b/net/dccp/output.c index 6993a9338cf7..a988fe9ffcba 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -304,7 +304,7 @@ void dccp_write_xmit(struct sock *sk, int block) dcb->dccpd_type = DCCP_PKT_DATA; err = dccp_transmit_skb(sk, skb); - ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); + ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); if (err) DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", err); -- cgit v1.2.3 From d196c9a5d4e150cdff675662214c80c69b906958 Mon Sep 17 00:00:00 2001 From: Ivo Calado Date: Mon, 11 Oct 2010 20:40:04 +0200 Subject: dccp: generalise data-loss condition This patch generalises the task of determining data loss from RFC 4340, 7.7.1. Let S_A, S_B be sequence numbers such that S_B is "after" S_A, and let N_B be the NDP count of packet S_B. Then, using modulo-2^48 arithmetic, D = S_B - S_A - 1 is an upper bound of the number of lost data packets, D - N_B is an approximation of the number of lost data packets (there are cases where this is not exact). The patch implements this as dccp_loss_count(S_A, S_B, N_B) := max(S_B - S_A - 1 - N_B, 0) Signed-off-by: Ivo Calado Signed-off-by: Erivaldo Xavier Signed-off-by: Leandro Sales Signed-off-by: Gerrit Renker --- net/dccp/dccp.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index e051c774ef5c..60f4f9622ab3 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -153,18 +153,27 @@ static inline u64 max48(const u64 seq1, const u64 seq2) } /** - * dccp_loss_free - Evaluates condition for data loss from RFC 4340, 7.7.1 - * @s1: start sequence number - * @s2: end sequence number + * dccp_loss_count - Approximate the number of lost data packets in a burst loss + * @s1: last known sequence number before the loss ('hole') + * @s2: first sequence number seen after the 'hole' * @ndp: NDP count on packet with sequence number @s2 - * Returns true if the sequence range s1...s2 has no data loss. */ -static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) +static inline u64 dccp_loss_count(const u64 s1, const u64 s2, const u64 ndp) { s64 delta = dccp_delta_seqno(s1, s2); WARN_ON(delta < 0); - return (u64)delta <= ndp + 1; + delta -= ndp + 1; + + return delta > 0 ? delta : 0; +} + +/** + * dccp_loss_free - Evaluate condition for data loss from RFC 4340, 7.7.1 + */ +static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) +{ + return dccp_loss_count(s1, s2, ndp) == 0; } enum { -- cgit v1.2.3 From ecdfbdabbe4e0cf0443cbbea2df1bf51bf67f3f3 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 11 Oct 2010 20:41:13 +0200 Subject: dccp: schedule an Ack when receiving timestamps This schedules an Ack when receiving a timestamp, exploiting the existing inet_csk_schedule_ack() function, saving one case in the `dccp_ack_pending()' function. Signed-off-by: Gerrit Renker --- net/dccp/dccp.h | 3 +-- net/dccp/options.c | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 60f4f9622ab3..3eb264b60823 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -459,8 +459,7 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) static inline int dccp_ack_pending(const struct sock *sk) { const struct dccp_sock *dp = dccp_sk(sk); - return dp->dccps_timestamp_echo != 0 || - (dp->dccps_hc_rx_ackvec != NULL && + return (dp->dccps_hc_rx_ackvec != NULL && dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || inet_csk_ack_scheduled(sk); } diff --git a/net/dccp/options.c b/net/dccp/options.c index d4b1ae0daacb..cd3061813009 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -163,6 +163,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, dccp_role(sk), ntohl(opt_val), (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq); + /* schedule an Ack in case this sender is quiescent */ + inet_csk_schedule_ack(sk); break; case DCCPO_TIMESTAMP_ECHO: if (len != 4 && len != 6 && len != 8) -- cgit v1.2.3 From 2f34b32977ade4249601f35f7eb0cdd56b4e0f89 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Mon, 11 Oct 2010 20:44:42 +0200 Subject: dccp: cosmetics - warning format This omits the redundant "DCCP:" in warning messages, since DCCP_WARN() already echoes the function name, avoiding messages like kernel: [10988.766503] dccp_close: DCCP: ABORT -- 209 bytes unread Signed-off-by: Gerrit Renker --- net/dccp/input.c | 2 +- net/dccp/proto.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dccp/input.c b/net/dccp/input.c index aecc8c7443c2..265985370fa1 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -259,7 +259,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) sysctl_dccp_sync_ratelimit))) return 0; - DCCP_WARN("DCCP: Step 6 failed for %s packet, " + DCCP_WARN("Step 6 failed for %s packet, " "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " "sending SYNC...\n", dccp_packet_name(dh->dccph_type), diff --git a/net/dccp/proto.c b/net/dccp/proto.c index b054ba1f55d2..7e5fc04eb6d1 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -944,7 +944,7 @@ void dccp_close(struct sock *sk, long timeout) if (data_was_unread) { /* Unread data was tossed, send an appropriate Reset Code */ - DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread); + DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread); dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED); dccp_set_state(sk, DCCP_CLOSED); } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { -- cgit v1.2.3 From 6d97e55f7172303082850c1de085d06fc1e57d17 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 11 Oct 2010 19:24:19 +0200 Subject: vhost: fix return code for log_access_ok() access_ok() returns 1 if it's OK otherwise it should return 0. Signed-off-by: Dan Carpenter Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index dd3d6f7406f8..158004e46e56 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -371,7 +371,7 @@ static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) /* Make sure 64 bit math will not overflow. */ if (a > ULONG_MAX - (unsigned long)log_base || a + (unsigned long)log_base > ULONG_MAX) - return -EFAULT; + return 0; return access_ok(VERIFY_WRITE, log_base + a, (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8); -- cgit v1.2.3 From a5901cbb5783b25fa71536503bfa4617d8ee41bd Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 23 Sep 2010 09:56:51 -0700 Subject: iiwlagn: always download priority table For advance BT/WiFi co-exist, always download bt priority table before sending bt_config command Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c4fe3f94c366..4470e8c80e9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2835,8 +2835,7 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; priv->cfg->ops->hcmd->send_bt_config(priv); priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; - if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) - iwlagn_send_prio_tbl(priv); + iwlagn_send_prio_tbl(priv); /* FIXME: w/a to force change uCode BT state machine */ iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, -- cgit v1.2.3 From bc795df1d225415c2ec6ff2a81c07a753681d945 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 11 Oct 2010 14:24:05 -0700 Subject: iwlagn: prio_tbl need to download before calibration For WiFi/BT combo devices, priority table always need to download before perform any calibration operation. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4470e8c80e9f..6771c404fa73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2809,9 +2809,6 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } - if (priv->hw_params.calib_rt_cfg) - iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); - /* After the ALIVE response, we can send host commands to the uCode */ set_bit(STATUS_ALIVE, &priv->status); @@ -2827,6 +2824,7 @@ static void iwl_alive_start(struct iwl_priv *priv) if (iwl_is_rfkill(priv)) return; + /* download priority table before any calibration request */ if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ @@ -2843,6 +2841,9 @@ static void iwl_alive_start(struct iwl_priv *priv) iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); } + if (priv->hw_params.calib_rt_cfg) + iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); + ieee80211_wake_queues(priv->hw); priv->active_rate = IWL_RATES_MASK; -- cgit v1.2.3 From fd74d065f43f88eedc7492886d84f0accb683653 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 12 Oct 2010 02:26:13 -0700 Subject: iwl3945: fix queue allocation commit 6f98613258b966ffe0e6def18129b386514d10e0 Author: Jay Sternberg Date: Sat Sep 18 09:07:04 2010 -0700 iwlagn: reduce redundant parameter definitions broke 3945 because Jay accidentally removed the num_of_queues parameter for 3945, so that we now attempt to allocate a zero-sized queue array, which leads to SLUB returning ZERO_SIZE_PTR (0x10) which we then try to dereference thus crashing the system. Restore the necessary num_of_queues param. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2254 Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7d74ae53950c..176e52577673 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2753,6 +2753,7 @@ static const struct iwl_ops iwl3945_ops = { static struct iwl_base_params iwl3945_base_params = { .eeprom_size = IWL3945_EEPROM_IMG_SIZE, + .num_of_queues = IWL39_NUM_QUEUES, .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, .set_l0s = false, .use_bsm = true, -- cgit v1.2.3 From 8f1e1742233cd1c3444dfc6c945a2efb2814e157 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 9 Aug 2010 17:38:10 -0400 Subject: Bluetooth: HCI devices are either BR/EDR or AMP radios HCI transport drivers may not know what type of radio an AMP device has so only say whether they're BR/EDR or AMP devices. Signed-off-by: David Vrabel Signed-off-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btmrvl_main.c | 4 ++-- include/net/bluetooth/hci.h | 2 +- net/bluetooth/hci_sysfs.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 0d32ec82e9bf..548d1d9e4dda 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -117,8 +117,8 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) (event->data[2] == MODULE_ALREADY_UP)) ? "Bring-up succeed" : "Bring-up failed"); - if (event->length > 3) - priv->btmrvl_dev.dev_type = event->data[3]; + if (event->length > 3 && event->data[3]) + priv->btmrvl_dev.dev_type = HCI_AMP; else priv->btmrvl_dev.dev_type = HCI_BREDR; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index bcbdd6d4e6dd..e30e00834340 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -54,7 +54,7 @@ /* HCI controller types */ #define HCI_BREDR 0x00 -#define HCI_80211 0x01 +#define HCI_AMP 0x01 /* HCI device quirks */ enum { diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 8fb967beee80..1a9f0db027da 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -196,8 +196,8 @@ static inline char *host_typetostr(int type) switch (type) { case HCI_BREDR: return "BR/EDR"; - case HCI_80211: - return "802.11"; + case HCI_AMP: + return "AMP"; default: return "UNKNOWN"; } -- cgit v1.2.3 From fb3d8eb47ce377d6d7a8fc58b8046ea9eb376a28 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 9 Aug 2010 17:42:21 -0400 Subject: Bluetooth: Support SDIO devices that are AMP controllers Signed-off-by: David Vrabel Signed-off-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btsdio.c | 8 ++++++++ include/linux/mmc/sdio_ids.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 76e5127884f0..792e32d29a1d 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -46,6 +46,9 @@ static const struct sdio_device_id btsdio_table[] = { /* Generic Bluetooth Type-B SDIO device */ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, + /* Generic Bluetooth AMP controller */ + { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) }, + { } /* Terminating entry */ }; @@ -329,6 +332,11 @@ static int btsdio_probe(struct sdio_func *func, hdev->bus = HCI_SDIO; hdev->driver_data = data; + if (id->class == SDIO_CLASS_BT_AMP) + hdev->dev_type = HCI_AMP; + else + hdev->dev_type = HCI_BREDR; + data->hdev = hdev; SET_HCIDEV_DEV(hdev, &func->dev); diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 33b2ea09a4ad..a36ab3bc7b03 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -18,6 +18,7 @@ #define SDIO_CLASS_PHS 0x06 /* PHS standard interface */ #define SDIO_CLASS_WLAN 0x07 /* WLAN interface */ #define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */ +#define SDIO_CLASS_BT_AMP 0x09 /* Type-A Bluetooth AMP interface */ /* * Vendors and devices. Sort key: vendor first, device next. -- cgit v1.2.3 From 08601469a5aac8b3453d8aca0b8f9bd8dfdae12c Mon Sep 17 00:00:00 2001 From: Yuri Kululin Date: Fri, 23 Jul 2010 13:57:12 +0400 Subject: Bluetooth: Fix RFCOMM RPN negotiation According to the ETSI 3GPP TS 07.10 the default bit rate value for RFCOMM is 9600 bit/s. Return this bit rate in case of RPN request and accept other sane bit rates proposed by the sender in RPM command. Signed-off-by: Yuri Kululin Signed-off-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 15ea84ba344e..b464843ed79e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1415,8 +1415,8 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_ return 0; if (len == 1) { - /* This is a request, return default settings */ - bit_rate = RFCOMM_RPN_BR_115200; + /* This is a request, return default (according to ETSI TS 07.10) settings */ + bit_rate = RFCOMM_RPN_BR_9600; data_bits = RFCOMM_RPN_DATA_8; stop_bits = RFCOMM_RPN_STOP_1; parity = RFCOMM_RPN_PARITY_NONE; @@ -1431,9 +1431,9 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_ if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) { bit_rate = rpn->bit_rate; - if (bit_rate != RFCOMM_RPN_BR_115200) { + if (bit_rate > RFCOMM_RPN_BR_230400) { BT_DBG("RPN bit rate mismatch 0x%x", bit_rate); - bit_rate = RFCOMM_RPN_BR_115200; + bit_rate = RFCOMM_RPN_BR_9600; rpn_mask ^= RFCOMM_RPN_PM_BITRATE; } } -- cgit v1.2.3 From 0fba2558cbb3fae3a09147b7d6e18a6204204e0e Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 8 Sep 2010 10:05:26 -0700 Subject: Bluetooth: Validate PSM values in calls to connect() and bind() Valid L2CAP PSMs are odd numbers, and the least significant bit of the most significant byte must be 0. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd8401..2f625b87a89e 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) goto done; } - if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 && - !capable(CAP_NET_BIND_SERVICE)) { - err = -EACCES; - goto done; + if (la.l2_psm) { + __u16 psm = __le16_to_cpu(la.l2_psm); + + /* PSM must be odd and lsb of upper byte must be 0 */ + if ((psm & 0x0101) != 0x0001) { + err = -EINVAL; + goto done; + } + + /* Restrict usage of well-known PSMs */ + if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { + err = -EACCES; + goto done; + } } write_lock_bh(&l2cap_sk_list.lock); @@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al goto done; } + /* PSM must be odd and lsb of upper byte must be 0 */ + if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && + sk->sk_type != SOCK_RAW) { + err = -EINVAL; + goto done; + } + /* Set destination address and psm */ bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); l2cap_pi(sk)->psm = la.l2_psm; -- cgit v1.2.3 From 796c86eec84ddfd02281c5071838ed1fefda6b90 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 8 Sep 2010 10:05:27 -0700 Subject: Bluetooth: Add common code for stream-oriented recvmsg() This commit adds a bt_sock_stream_recvmsg() function for use by any Bluetooth code that uses SOCK_STREAM sockets. This code is copied from rfcomm_sock_recvmsg() with minimal modifications to remove RFCOMM-specific functionality and improve readability. L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs when it comes to reading data. Proper stream read semantics require that applications can read from a stream one byte at a time and not lose any data. The RFCOMM code already operated on and pulled data from the underlying L2CAP socket, so very few changes were required to make the code more generic for use with non-RFCOMM data over L2CAP. Applications that need more awareness of L2CAP frame boundaries are still free to use SOCK_SEQPACKET sockets, and may verify that they connection did not fall back to basic mode by calling getsockopt(). Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/bluetooth.h | 2 + net/bluetooth/af_bluetooth.c | 109 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 30fce0128dd7..d81ea7997701 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -126,6 +126,8 @@ int bt_sock_unregister(int proto); void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); +int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len, int flags); uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ed0f22f57668..c4cf3f595004 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, } EXPORT_SYMBOL(bt_sock_recvmsg); +static long bt_sock_data_wait(struct sock *sk, long timeo) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(sk_sleep(sk), &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + + if (!skb_queue_empty(&sk->sk_receive_queue)) + break; + + if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN)) + break; + + if (signal_pending(current) || !timeo) + break; + + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + } + + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk_sleep(sk), &wait); + return timeo; +} + +int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size, int flags) +{ + struct sock *sk = sock->sk; + int err = 0; + size_t target, copied = 0; + long timeo; + + if (flags & MSG_OOB) + return -EOPNOTSUPP; + + msg->msg_namelen = 0; + + BT_DBG("sk %p size %zu", sk, size); + + lock_sock(sk); + + target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + + do { + struct sk_buff *skb; + int chunk; + + skb = skb_dequeue(&sk->sk_receive_queue); + if (!skb) { + if (copied >= target) + break; + + if ((err = sock_error(sk)) != 0) + break; + if (sk->sk_shutdown & RCV_SHUTDOWN) + break; + + err = -EAGAIN; + if (!timeo) + break; + + timeo = bt_sock_data_wait(sk, timeo); + + if (signal_pending(current)) { + err = sock_intr_errno(timeo); + goto out; + } + continue; + } + + chunk = min_t(unsigned int, skb->len, size); + if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + skb_queue_head(&sk->sk_receive_queue, skb); + if (!copied) + copied = -EFAULT; + break; + } + copied += chunk; + size -= chunk; + + sock_recv_ts_and_drops(msg, sk, skb); + + if (!(flags & MSG_PEEK)) { + skb_pull(skb, chunk); + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); + break; + } + kfree_skb(skb); + + } else { + /* put message back and return */ + skb_queue_head(&sk->sk_receive_queue, skb); + break; + } + } while (size); + +out: + release_sock(sk); + return copied ? : err; +} +EXPORT_SYMBOL(bt_sock_stream_recvmsg); + static inline unsigned int bt_accept_poll(struct sock *parent) { struct list_head *p, *n; -- cgit v1.2.3 From 3d7d01dffec4a6757ed1e3182f01c7ef5caa2539 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 8 Sep 2010 10:05:28 -0700 Subject: Bluetooth: Use common SOCK_STREAM receive code in RFCOMM To reduce code duplication, have rfcomm_sock_recvmsg() call bt_sock_stream_recvmsg(). The common bt_sock_stream_recvmsg() code is nearly identical, with the RFCOMM-specific functionality for deferred setup and connection unthrottling left in rfcomm_sock_recvmsg(). Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/sock.c | 104 +++----------------------------------------- 1 file changed, 6 insertions(+), 98 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 194b3a04cfd3..aec505f934df 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -621,121 +621,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, return sent; } -static long rfcomm_sock_data_wait(struct sock *sk, long timeo) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(sk_sleep(sk), &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!skb_queue_empty(&sk->sk_receive_queue) || - sk->sk_err || - (sk->sk_shutdown & RCV_SHUTDOWN) || - signal_pending(current) || - !timeo) - break; - - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(sk_sleep(sk), &wait); - return timeo; -} - static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) { struct sock *sk = sock->sk; struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - int err = 0; - size_t target, copied = 0; - long timeo; + int len; if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { rfcomm_dlc_accept(d); return 0; } - if (flags & MSG_OOB) - return -EOPNOTSUPP; - - msg->msg_namelen = 0; - - BT_DBG("sk %p size %zu", sk, size); + len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags); lock_sock(sk); + if (!(flags & MSG_PEEK) && len > 0) + atomic_sub(len, &sk->sk_rmem_alloc); - target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); - - do { - struct sk_buff *skb; - int chunk; - - skb = skb_dequeue(&sk->sk_receive_queue); - if (!skb) { - if (copied >= target) - break; - - if ((err = sock_error(sk)) != 0) - break; - if (sk->sk_shutdown & RCV_SHUTDOWN) - break; - - err = -EAGAIN; - if (!timeo) - break; - - timeo = rfcomm_sock_data_wait(sk, timeo); - - if (signal_pending(current)) { - err = sock_intr_errno(timeo); - goto out; - } - continue; - } - - chunk = min_t(unsigned int, skb->len, size); - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { - skb_queue_head(&sk->sk_receive_queue, skb); - if (!copied) - copied = -EFAULT; - break; - } - copied += chunk; - size -= chunk; - - sock_recv_ts_and_drops(msg, sk, skb); - - if (!(flags & MSG_PEEK)) { - atomic_sub(chunk, &sk->sk_rmem_alloc); - - skb_pull(skb, chunk); - if (skb->len) { - skb_queue_head(&sk->sk_receive_queue, skb); - break; - } - kfree_skb(skb); - - } else { - /* put message back and return */ - skb_queue_head(&sk->sk_receive_queue, skb); - break; - } - } while (size); - -out: if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2)) rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc); - release_sock(sk); - return copied ? : err; + + return len; } static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) -- cgit v1.2.3 From 6fdf482bb3298267816be59d9a3dce29632382d3 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 8 Sep 2010 10:05:29 -0700 Subject: Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets. L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type, which is a mandatory request for ERTM mode. However, these sockets still have SOCK_SEQPACKET read semantics when bt_sock_recvmsg() is used to pull data from the receive queue. If the application is only reading part of a frame, then the unread portion of the frame is discarded. If the application requests more bytes than are in the current frame, only the current frame's data is returned. This patch utilizes common code derived from RFCOMM's recvmsg() function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and other SOCK_STREAM sockets in general). The application may read one byte at a time from the input stream and not lose any data, and may also read across L2CAP frame boundaries. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 2f625b87a89e..a9e7470d3cea 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1951,6 +1951,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms release_sock(sk); + if (sock->type == SOCK_STREAM) + return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); + return bt_sock_recvmsg(iocb, sock, msg, len, flags); } -- cgit v1.2.3 From 5017d8dde13313cab1e607379536a7930ed682b0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 8 Sep 2010 16:26:53 +0300 Subject: Bluetooth: remove extra newline from debug output Signed-off-by: Andrei Emeltchenko Acked-by: Ville Tervo Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index b464843ed79e..4a22b14a2c60 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1698,7 +1698,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) break; default: - BT_ERR("Unknown packet type 0x%02x\n", type); + BT_ERR("Unknown packet type 0x%02x", type); break; } kfree_skb(skb); -- cgit v1.2.3 From 80e2c88803c72747cb19febe2ad708bf0ad557bf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 9 Sep 2010 10:32:39 +0300 Subject: Bluetooth: Don't clear the blacklist when closing the HCI device Clearing the blacklist in hci_dev_do_close() would mean that user space needs to do extra work to re-block devices after a DEVDOWN-DEVUP cycle. This patch removes the clearing of the blacklist in this case and thereby saves user space from the extra work. Signed-off-by: Johan Hedberg Acked-by: Ville Tervo Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c52f091ee6de..bc2a052e518b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -562,7 +562,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_dev_lock_bh(hdev); inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); - hci_blacklist_clear(hdev); hci_dev_unlock_bh(hdev); hci_notify(hdev, HCI_DEV_DOWN); -- cgit v1.2.3 From 9c047157a20521cd525527947b13b950d168d2e6 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 20 Aug 2010 16:24:06 +0900 Subject: Bluetooth: Add support Bluetooth controller of MacbookPro 6,2 Bluetooth controller of MacbookPro 6,2 does not work. Because Device Class of these controllers was set 255 (Vendor Sepecific Class). T: Bus=01 Lev=03 Prnt=03 Port=02 Cnt=03 Dev#= 8 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=05ac ProdID=8218 Rev=00.22 S: Manufacturer=Apple Inc. S: Product=Bluetooth USB Host Controller C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) Signed-off-by: Nobuhiro Iwamatsu Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d22ce3cc611e..d1bb809512fa 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -62,6 +62,9 @@ static struct usb_device_id btusb_table[] = { /* Apple iMac11,1 */ { USB_DEVICE(0x05ac, 0x8215) }, + /* Apple MacBookPro6,2 */ + { USB_DEVICE(0x05ac, 0x8218) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, -- cgit v1.2.3 From 3cd01976e702ccaffb907727caff4f8789353599 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 20 Aug 2010 16:24:07 +0900 Subject: Bluetooth: Add support Bluetooth controller of MacbookPro 7,1 Bluetooth controller of MacbookPro 7,1 does not work. Because Device Class of these controllers was set 255 (Vendor Sepecific Class). T: Bus=04 Lev=02 Prnt=04 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=05ac ProdID=8213 Rev=01.86 S: Manufacturer=Apple Inc. S: Product=Bluetooth USB Host Controller S: SerialNumber=5C5948C81B99 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=00 Driver=(none) Signed-off-by: Nobuhiro Iwamatsu Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d1bb809512fa..d120a5c1c093 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, + /* Apple MacBookPro 7,1 */ + { USB_DEVICE(0x05ac, 0x8213) }, + /* Apple iMac11,1 */ { USB_DEVICE(0x05ac, 0x8215) }, -- cgit v1.2.3 From 8979481328dc2e14cea9f99b3562ffcf8655998e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 15 Sep 2010 14:28:44 +0300 Subject: Bluetooth: check L2CAP length in first ACL fragment Current Bluetooth code assembles fragments of big L2CAP packets in l2cap_recv_acldata and then checks allowed L2CAP size in assemled L2CAP packet (pi->imtu < skb->len). The patch moves allowed L2CAP size check to the early stage when we receive the first fragment of L2CAP packet. We do not need to reserve and keep L2CAP fragments for bad packets. Updated version after comments from Mat Martineau and Gustavo Padovan . Trace below is received when using stress tools sending big fragmented L2CAP packets. ... [ 1712.798492] swapper: page allocation failure. order:4, mode:0x4020 [ 1712.804809] [] (unwind_backtrace+0x0/0xdc) from [] (__alloc_pages_nodemask+0x4) [ 1712.814666] [] (__alloc_pages_nodemask+0x47c/0x4d4) from [] (__get_free_pages+) [ 1712.824645] [] (__get_free_pages+0x10/0x3c) from [] (__alloc_skb+0x4c/0xfc) [ 1712.833465] [] (__alloc_skb+0x4c/0xfc) from [] (l2cap_recv_acldata+0xf0/0x1f8 ) [ 1712.843322] [] (l2cap_recv_acldata+0xf0/0x1f8 [l2cap]) from [] (hci_rx_task+0x) ... Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index a9e7470d3cea..5441083ff1ca 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -4663,6 +4663,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl if (flags & ACL_START) { struct l2cap_hdr *hdr; + struct sock *sk; + u16 cid; int len; if (conn->rx_len) { @@ -4681,6 +4683,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl hdr = (struct l2cap_hdr *) skb->data; len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE; + cid = __le16_to_cpu(hdr->cid); if (len == skb->len) { /* Complete frame received */ @@ -4697,6 +4700,19 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl goto drop; } + sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); + + if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { + BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", + len, l2cap_pi(sk)->imtu); + bh_unlock_sock(sk); + l2cap_conn_unreliable(conn, ECOMM); + goto drop; + } + + if (sk) + bh_unlock_sock(sk); + /* Allocate skb for the complete frame (with header) */ conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); if (!conn->rx_skb) -- cgit v1.2.3 From aae7fe22a875a84e328469e228cba033ebbf20cb Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 15 Sep 2010 14:28:43 +0300 Subject: Bluetooth: check for l2cap header in start fragment BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] page 36 mentioned "Note: Start Fragments always begin with the Basic L2CAP header of a PDU." Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 5441083ff1ca..7da6432f6799 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -4675,7 +4675,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl l2cap_conn_unreliable(conn, ECOMM); } - if (skb->len < 2) { + /* Start fragment always begin with Basic L2CAP header */ + if (skb->len < L2CAP_HDR_SIZE) { BT_ERR("Frame is too short (len %d)", skb->len); l2cap_conn_unreliable(conn, ECOMM); goto drop; -- cgit v1.2.3 From cb810a189da312d4074cb3fc8b0267b7115e7be1 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 3 Sep 2010 17:51:57 -0300 Subject: Bluetooth: remove unused variable from cmtp A value was attributed to 'src', but no one was using. Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index d4c6af082d48..d4616060a196 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -321,12 +321,11 @@ static int cmtp_session(void *arg) int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) { struct cmtp_session *session, *s; - bdaddr_t src, dst; + bdaddr_t dst; int i, err; BT_DBG(""); - baswap(&src, &bt_sk(sock->sk)->src); baswap(&dst, &bt_sk(sock->sk)->dst); session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); -- cgit v1.2.3 From d6b2eb2f893547d7488d31a7088d78dd77ab5995 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 3 Sep 2010 18:29:46 -0300 Subject: Bluetooth: make batostr() print in the right order The Bluetooth core uses the the BD_ADDR in the opposite order from the human readable order. So we are changing batostr() to print in the correct order and then removing some baswap(), as they are not needed anymore. Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 5 +---- net/bluetooth/hci_sysfs.c | 17 ++++------------- net/bluetooth/hidp/core.c | 8 ++------ net/bluetooth/lib.c | 4 ++-- net/bluetooth/rfcomm/tty.c | 4 +--- 5 files changed, 10 insertions(+), 28 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index d4616060a196..ec0a1347f933 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -321,13 +321,10 @@ static int cmtp_session(void *arg) int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) { struct cmtp_session *session, *s; - bdaddr_t dst; int i, err; BT_DBG(""); - baswap(&dst, &bt_sk(sock->sk)->dst); - session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); if (!session) return -ENOMEM; @@ -346,7 +343,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) BT_DBG("mtu %d", session->mtu); - sprintf(session->name, "%s", batostr(&dst)); + sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst)); session->sock = sock; session->state = BT_CONFIG; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 1a9f0db027da..5fce3d6d07b4 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -37,9 +37,7 @@ static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = dev_get_drvdata(dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &conn->dst); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&conn->dst)); } static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) @@ -238,9 +236,7 @@ static ssize_t show_class(struct device *dev, struct device_attribute *attr, cha static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &hdev->bdaddr); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); } static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) @@ -408,10 +404,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p) for (e = cache->list; e; e = e->next) { struct inquiry_data *data = &e->data; - bdaddr_t bdaddr; - baswap(&bdaddr, &data->bdaddr); seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", - batostr(&bdaddr), + batostr(&data->bdaddr), data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode, data->dev_class[2], data->dev_class[1], data->dev_class[0], @@ -445,13 +439,10 @@ static int blacklist_show(struct seq_file *f, void *p) list_for_each(l, &hdev->blacklist) { struct bdaddr_list *b; - bdaddr_t bdaddr; b = list_entry(l, struct bdaddr_list, list); - baswap(&bdaddr, &b->bdaddr); - - seq_printf(f, "%s\n", batostr(&bdaddr)); + seq_printf(f, "%s\n", batostr(&b->bdaddr)); } hci_dev_unlock_bh(hdev); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index bfe641b7dfaf..c0ee8b3928ed 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -758,7 +758,6 @@ static int hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) { struct hid_device *hid; - bdaddr_t src, dst; int err; session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); @@ -781,9 +780,6 @@ static int hidp_setup_hid(struct hidp_session *session, hid->driver_data = session; - baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); - baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); - hid->bus = BUS_BLUETOOTH; hid->vendor = req->vendor; hid->product = req->product; @@ -791,8 +787,8 @@ static int hidp_setup_hid(struct hidp_session *session, hid->country = req->country; strncpy(hid->name, req->name, 128); - strncpy(hid->phys, batostr(&src), 64); - strncpy(hid->uniq, batostr(&dst), 64); + strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); + strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); hid->dev.parent = hidp_get_device(session); hid->ll_driver = &hidp_hid_driver; diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index ad2af5814e40..b826d1bf10df 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -51,8 +51,8 @@ char *batostr(bdaddr_t *ba) i ^= 1; sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - ba->b[0], ba->b[1], ba->b[2], - ba->b[3], ba->b[4], ba->b[5]); + ba->b[5], ba->b[4], ba->b[3], + ba->b[2], ba->b[1], ba->b[0]); return str[i]; } diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index befc3a52aa04..26461639f133 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -183,9 +183,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) { struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &dev->dst); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&dev->dst)); } static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf) -- cgit v1.2.3 From 0175d629e096a5a59dde6cc91b32ac3160a44b9e Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 24 Sep 2010 20:30:57 -0300 Subject: Bluetooth: Use the proper error value from bt_skb_send_alloc() &err points to the proper error set by bt_skb_send_alloc() when it fails. Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 7da6432f6799..01c476239dd6 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1652,7 +1652,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err); if (!*frag) - return -EFAULT; + return err; if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) return -EFAULT; @@ -1678,7 +1678,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); @@ -1707,7 +1707,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); @@ -1744,7 +1744,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); -- cgit v1.2.3 From ab3e571564a5d8fa4923e2e858e574c931a014c7 Mon Sep 17 00:00:00 2001 From: Haijun Liu Date: Thu, 30 Sep 2010 16:52:40 +0800 Subject: Bluetooth: Update conf_state before send config_req out Update conf_state with L2CAP_CONF_REQ_SENT before send config_req out in l2cap_config_req(). Signed-off-by: Haijun Liu Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 01c476239dd6..16049de49896 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3171,6 +3171,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { u8 buf[64]; + l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, l2cap_build_conf_req(sk, buf), buf); l2cap_pi(sk)->num_conf_req++; -- cgit v1.2.3 From 534c92fde74c8d2143fc15b5f1d957f42cb43570 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 1 Oct 2010 12:05:11 +0300 Subject: Bluetooth: clean up rfcomm code Remove dead code and unused rfcomm thread events Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/rfcomm.h | 5 ----- net/bluetooth/rfcomm/core.c | 29 ++++++++++++++--------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index a140847d622c..71047bc0af84 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -213,11 +213,6 @@ struct rfcomm_dlc { #define RFCOMM_DEFER_SETUP 8 /* Scheduling flags and events */ -#define RFCOMM_SCHED_STATE 0 -#define RFCOMM_SCHED_RX 1 -#define RFCOMM_SCHED_TX 2 -#define RFCOMM_SCHED_TIMEO 3 -#define RFCOMM_SCHED_AUTH 4 #define RFCOMM_SCHED_WAKEUP 31 /* MSC exchange flags */ diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 4a22b14a2c60..39a5d87e33b4 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -113,11 +113,10 @@ static void rfcomm_session_del(struct rfcomm_session *s); #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1) #define __get_rpn_parity(line) (((line) >> 3) & 0x7) -static inline void rfcomm_schedule(uint event) +static inline void rfcomm_schedule(void) { if (!rfcomm_thread) return; - //set_bit(event, &rfcomm_event); set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); wake_up_process(rfcomm_thread); } @@ -203,13 +202,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs) static void rfcomm_l2state_change(struct sock *sk) { BT_DBG("%p state %d", sk, sk->sk_state); - rfcomm_schedule(RFCOMM_SCHED_STATE); + rfcomm_schedule(); } static void rfcomm_l2data_ready(struct sock *sk, int bytes) { BT_DBG("%p bytes %d", sk, bytes); - rfcomm_schedule(RFCOMM_SCHED_RX); + rfcomm_schedule(); } static int rfcomm_l2sock_create(struct socket **sock) @@ -255,7 +254,7 @@ static void rfcomm_session_timeout(unsigned long arg) BT_DBG("session %p state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); - rfcomm_schedule(RFCOMM_SCHED_TIMEO); + rfcomm_schedule(); } static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) @@ -283,7 +282,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) set_bit(RFCOMM_TIMED_OUT, &d->flags); rfcomm_dlc_put(d); - rfcomm_schedule(RFCOMM_SCHED_TIMEO); + rfcomm_schedule(); } static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) @@ -465,7 +464,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) case BT_CONFIG: if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { set_bit(RFCOMM_AUTH_REJECT, &d->flags); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); break; } /* Fall through */ @@ -485,7 +484,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) case BT_CONNECT2: if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { set_bit(RFCOMM_AUTH_REJECT, &d->flags); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); break; } /* Fall through */ @@ -533,7 +532,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) skb_queue_tail(&d->tx_queue, skb); if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags)) - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return len; } @@ -545,7 +544,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) d->v24_sig |= RFCOMM_V24_FC; set_bit(RFCOMM_MSC_PENDING, &d->flags); } - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); } void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) @@ -556,7 +555,7 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) d->v24_sig &= ~RFCOMM_V24_FC; set_bit(RFCOMM_MSC_PENDING, &d->flags); } - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); } /* @@ -577,7 +576,7 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) d->v24_sig = v24_sig; if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags)) - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return 0; } @@ -816,7 +815,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) cmd->fcs = __fcs2((u8 *) cmd); skb_queue_tail(&d->tx_queue, skb); - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return 0; } @@ -1884,7 +1883,7 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) * L2CAP MTU minus UIH header and FCS. */ s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5; - rfcomm_schedule(RFCOMM_SCHED_RX); + rfcomm_schedule(); } else sock_release(nsock); } @@ -2093,7 +2092,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) rfcomm_session_put(s); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); } static struct hci_cb rfcomm_cb = { -- cgit v1.2.3 From 7f8f2729ce6380a2735ddf45c04d5bb09eaca8a5 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Thu, 7 Oct 2010 21:57:10 +0200 Subject: Bluetooth: hci_uart: Fix typo in stats for sco tx s/stat.cmd_tx++/stat.sco_tx++ for HCI_SCODATA_PKT Signed-off-by: Karl Beldan Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_ldisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 998833d93c13..74cb6f3e86c5 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -101,7 +101,7 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) break; case HCI_SCODATA_PKT: - hdev->stat.cmd_tx++; + hdev->stat.sco_tx++; break; } } -- cgit v1.2.3 From b3c0598952e02f1f1f6d003574549d940ecbf31a Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 8 Oct 2010 09:13:28 -0300 Subject: Bluetooth: update MAINTAINERS for Bluetooth subsys Add myself to MAINTAINERS and update the git trees. Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- MAINTAINERS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ba8603ce4441..c539910b1f76 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1358,16 +1358,19 @@ F: drivers/mtd/devices/block2mtd.c BLUETOOTH DRIVERS M: Marcel Holtmann +M: Gustavo F. Padovan L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git S: Maintained F: drivers/bluetooth/ BLUETOOTH SUBSYSTEM M: Marcel Holtmann +M: Gustavo F. Padovan L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git S: Maintained F: net/bluetooth/ F: include/net/bluetooth/ -- cgit v1.2.3 From f0b9f4725180ea58c8da78b3de0b4e0ad180fc2c Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 12 Oct 2010 09:02:21 +0000 Subject: bnx2x: Fixing a typo: added a missing RSS enablement Reported-by: Eric Dumazet Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Tested-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 7a9556b5b55d..ead524bca8f2 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2486,6 +2486,7 @@ void bnx2x_pf_init(struct bnx2x *bp) * if (is_eth_multi(bp)) * flags |= FUNC_FLG_RSS; */ + flags |= FUNC_FLG_RSS; /* function setup */ if (flags & FUNC_FLG_RSS) { -- cgit v1.2.3 From 29b4433d991c88d86ca48a4c1cc33c671475be4b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Oct 2010 10:22:12 +0000 Subject: net: percpu net_device refcount We tried very hard to remove all possible dev_hold()/dev_put() pairs in network stack, using RCU conversions. There is still an unavoidable device refcount change for every dst we create/destroy, and this can slow down some workloads (routers or some app servers, mmap af_packet) We can switch to a percpu refcount implementation, now dynamic per_cpu infrastructure is mature. On a 64 cpus machine, this consumes 256 bytes per device. On x86, dev_hold(dev) code : before lock incl 0x280(%ebx) after: movl 0x260(%ebx),%eax incl fs:(%eax) Stress bench : (Sending 160.000.000 UDP frames, IP route cache disabled, dual E5540 @2.53GHz, 32bit kernel, FIB_TRIE) Before: real 1m1.662s user 0m14.373s sys 12m55.960s After: real 0m51.179s user 0m15.329s sys 10m15.942s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/infiniband/hw/nes/nes_cm.c | 4 ++-- drivers/infiniband/hw/nes/nes_verbs.c | 4 ++-- include/linux/netdevice.h | 7 +++--- net/core/dev.c | 40 +++++++++++++++++++++++++++++------ 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 61e0efd4ccfb..6220d9d75b58 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -2701,7 +2701,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt) nesibdev = nesvnic->nesibdev; nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); if (nesqp->active_conn) { @@ -2791,7 +2791,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) atomic_inc(&cm_accepts); nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); /* allocate the ietf frame and space for private data */ nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 9046e6675686..546fc22405fe 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -785,7 +785,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, nesadapter->max_pd, &pd_num, &nesadapter->next_pd); @@ -1416,7 +1416,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, /* update the QP table */ nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); return &nesqp->ibqp; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4160db3721ba..14fbb04c459d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1026,7 +1026,7 @@ struct net_device { struct timer_list watchdog_timer; /* Number of references to this device */ - atomic_t refcnt ____cacheline_aligned_in_smp; + int __percpu *pcpu_refcnt; /* delayed register/unregister */ struct list_head todo_list; @@ -1330,6 +1330,7 @@ static inline void unregister_netdevice(struct net_device *dev) unregister_netdevice_queue(dev, NULL); } +extern int netdev_refcnt_read(const struct net_device *dev); extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); @@ -1798,7 +1799,7 @@ extern void netdev_run_todo(void); */ static inline void dev_put(struct net_device *dev) { - atomic_dec(&dev->refcnt); + irqsafe_cpu_dec(*dev->pcpu_refcnt); } /** @@ -1809,7 +1810,7 @@ static inline void dev_put(struct net_device *dev) */ static inline void dev_hold(struct net_device *dev) { - atomic_inc(&dev->refcnt); + irqsafe_cpu_inc(*dev->pcpu_refcnt); } /* Carrier loss detection, dial on demand. The functions netif_carrier_on diff --git a/net/core/dev.c b/net/core/dev.c index 193eafaabd88..04972a4783e2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5192,9 +5192,6 @@ int init_dummy_netdev(struct net_device *dev) */ dev->reg_state = NETREG_DUMMY; - /* initialize the ref count */ - atomic_set(&dev->refcnt, 1); - /* NAPI wants this */ INIT_LIST_HEAD(&dev->napi_list); @@ -5202,6 +5199,11 @@ int init_dummy_netdev(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); set_bit(__LINK_STATE_START, &dev->state); + /* Note : We dont allocate pcpu_refcnt for dummy devices, + * because users of this 'device' dont need to change + * its refcount. + */ + return 0; } EXPORT_SYMBOL_GPL(init_dummy_netdev); @@ -5243,6 +5245,16 @@ out: } EXPORT_SYMBOL(register_netdev); +int netdev_refcnt_read(const struct net_device *dev) +{ + int i, refcnt = 0; + + for_each_possible_cpu(i) + refcnt += *per_cpu_ptr(dev->pcpu_refcnt, i); + return refcnt; +} +EXPORT_SYMBOL(netdev_refcnt_read); + /* * netdev_wait_allrefs - wait until all references are gone. * @@ -5257,11 +5269,14 @@ EXPORT_SYMBOL(register_netdev); static void netdev_wait_allrefs(struct net_device *dev) { unsigned long rebroadcast_time, warning_time; + int refcnt; linkwatch_forget_dev(dev); rebroadcast_time = warning_time = jiffies; - while (atomic_read(&dev->refcnt) != 0) { + refcnt = netdev_refcnt_read(dev); + + while (refcnt != 0) { if (time_after(jiffies, rebroadcast_time + 1 * HZ)) { rtnl_lock(); @@ -5288,11 +5303,13 @@ static void netdev_wait_allrefs(struct net_device *dev) msleep(250); + refcnt = netdev_refcnt_read(dev); + if (time_after(jiffies, warning_time + 10 * HZ)) { printk(KERN_EMERG "unregister_netdevice: " "waiting for %s to become free. Usage " "count = %d\n", - dev->name, atomic_read(&dev->refcnt)); + dev->name, refcnt); warning_time = jiffies; } } @@ -5350,7 +5367,7 @@ void netdev_run_todo(void) netdev_wait_allrefs(dev); /* paranoia */ - BUG_ON(atomic_read(&dev->refcnt)); + BUG_ON(netdev_refcnt_read(dev)); WARN_ON(rcu_dereference_raw(dev->ip_ptr)); WARN_ON(dev->ip6_ptr); WARN_ON(dev->dn_ptr); @@ -5520,9 +5537,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev = PTR_ALIGN(p, NETDEV_ALIGN); dev->padded = (char *)dev - (char *)p; - if (dev_addr_init(dev)) + dev->pcpu_refcnt = alloc_percpu(int); + if (!dev->pcpu_refcnt) goto free_tx; + if (dev_addr_init(dev)) + goto free_pcpu; + dev_mc_init(dev); dev_uc_init(dev); @@ -5553,6 +5574,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, free_tx: kfree(tx); +free_pcpu: + free_percpu(dev->pcpu_refcnt); free_p: kfree(p); return NULL; @@ -5586,6 +5609,9 @@ void free_netdev(struct net_device *dev) list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) netif_napi_del(p); + free_percpu(dev->pcpu_refcnt); + dev->pcpu_refcnt = NULL; + /* Compatibility with error handling in drivers */ if (dev->reg_state == NETREG_UNINITIALIZED) { kfree((char *)dev - dev->padded); -- cgit v1.2.3 From cfd8e12f42746df396ecbdf7a1d8e92e8e4dbb97 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 11 Oct 2010 10:28:59 -0700 Subject: wireless: Print wiphy name in sysfs. The index cannot be used to reliably reconstruct a phy name, so explicitly add the phy name to sysfs so that scripts can figure out the parent phy device for a particular wireless interface. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- net/wireless/sysfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 74a9e3cce452..4294fa22bb2d 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx); SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; + return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); +} + + static ssize_t addresses_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = { __ATTR_RO(macaddress), __ATTR_RO(address_mask), __ATTR_RO(addresses), + __ATTR_RO(name), {} }; -- cgit v1.2.3 From 908ebfb95d16bdf7f5f37ad911ccd9b7350ba780 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 12 Oct 2010 11:07:44 -0700 Subject: ath5k: fix build break from "ath5k: Print out opmode in debugfs" Also improve ath_opmode_to_string usage by having it return UNKNOWN rather than NULL in the event of failure to map the opmode value to a representative string. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 +--- drivers/net/wireless/ath/ath5k/debug.c | 16 ++++------------ drivers/net/wireless/ath/debug.c | 2 +- drivers/net/wireless/ath/debug.h | 7 +++++++ 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c9732a6ce87f..7baaf04f092d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -563,9 +563,7 @@ static void ath_do_set_opmode(struct ath5k_softc *sc) struct ath5k_hw *ah = sc->ah; ath5k_hw_set_opmode(ah, sc->opmode); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", - sc->opmode, - ath_opmode_to_string(sc->opmode) ? - ath_opmode_to_string(sc->opmode) : "UKNOWN"); + sc->opmode, ath_opmode_to_string(sc->opmode)); } void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index a3b217125331..7c77e5b7c9af 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -493,7 +493,6 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, char buf[700]; unsigned int len = 0; u32 filt = ath5k_hw_get_rx_filter(sc->ah); - const char *tmp; len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", sc->bssidmask); @@ -522,17 +521,10 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, if (filt & AR5K_RX_FILTER_PHYERR_5211) snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); if (filt & AR5K_RX_FILTER_RADARERR_5211) - len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n"); - else - len += snprintf(buf+len, sizeof(buf)-len, "\n"); - - tmp = ath_opmode_to_string(sc->opmode); - if (tmp) - len += snprintf(buf+len, sizeof(buf)-len, "opmode: %s\n", - tmp); - else - len += snprintf(buf+len, sizeof(buf)-len, - "opmode: UNKNOWN-%i\n", sc->opmode); + len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211"); + + len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n", + ath_opmode_to_string(sc->opmode), sc->opmode); if (len > sizeof(buf)) len = sizeof(buf); diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c index a9eb7876dbe1..dacfb234f491 100644 --- a/drivers/net/wireless/ath/debug.c +++ b/drivers/net/wireless/ath/debug.c @@ -55,7 +55,7 @@ const char *ath_opmode_to_string(enum nl80211_iftype opmode) case NL80211_IFTYPE_P2P_GO: return "P2P-GO"; default: - return NULL; + return "UNKNOWN"; } } EXPORT_SYMBOL(ath_opmode_to_string); diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index a3a5a628d24d..64e4af2c2887 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -78,6 +78,13 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) #endif /* CONFIG_ATH_DEBUG */ /** Returns string describing opmode, or NULL if unknown mode. */ +#ifdef CONFIG_ATH_DEBUG const char *ath_opmode_to_string(enum nl80211_iftype opmode); +#else +static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +{ + return "UNKNOWN"; +} +#endif #endif /* ATH_DEBUG_H */ -- cgit v1.2.3 From 12b00c2c025b8af697d9a022ea2e928cad889ef1 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Oct 2010 15:56:56 +0200 Subject: netfilter: xtables: resolve indirect macros 1/3 Many of the used macros are just there for userspace compatibility. Substitute the in-kernel code to directly use the terminal macro and stuff the defines into #ifndef __KERNEL__ sections. Signed-off-by: Jan Engelhardt --- include/linux/netfilter_arp/arp_tables.h | 10 ++++++---- include/linux/netfilter_ipv4/ip_tables.h | 10 ++++++---- include/linux/netfilter_ipv6/ip6_tables.h | 11 ++++++----- net/ipv4/netfilter/arp_tables.c | 10 +++++----- net/ipv4/netfilter/ip_tables.c | 12 ++++++------ net/ipv6/netfilter/ip6_tables.c | 12 ++++++------ 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index e9948c0560f6..81938600470d 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -21,8 +21,10 @@ #include +#ifndef __KERNEL__ #define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN +#endif #define ARPT_DEV_ADDR_LEN_MAX 16 @@ -134,7 +136,7 @@ struct arpt_entry /* The argument to ARPT_SO_GET_INFO */ struct arpt_getinfo { /* Which table: caller fills this in. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -156,7 +158,7 @@ struct arpt_getinfo { /* The argument to ARPT_SO_SET_REPLACE. */ struct arpt_replace { /* Which table. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -191,7 +193,7 @@ struct arpt_replace { /* The argument to ARPT_SO_GET_ENTRIES. */ struct arpt_get_entries { /* Which table: user fills this in. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; @@ -230,7 +232,7 @@ struct arpt_standard { struct arpt_error_target { struct arpt_entry_target target; - char errorname[ARPT_FUNCTION_MAXNAMELEN]; + char errorname[XT_FUNCTION_MAXNAMELEN]; }; struct arpt_error { diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 704a7b6e8169..1b7cdf1137e3 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -27,12 +27,14 @@ #include +#ifndef __KERNEL__ #define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN #define ipt_match xt_match #define ipt_target xt_target #define ipt_table xt_table #define ipt_get_revision xt_get_revision +#endif /* Yes, Virginia, you have to zero the padding. */ struct ipt_ip { @@ -146,7 +148,7 @@ struct ipt_icmp { /* The argument to IPT_SO_GET_INFO */ struct ipt_getinfo { /* Which table: caller fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -168,7 +170,7 @@ struct ipt_getinfo { /* The argument to IPT_SO_SET_REPLACE. */ struct ipt_replace { /* Which table. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -202,7 +204,7 @@ struct ipt_replace { /* The argument to IPT_SO_GET_ENTRIES. */ struct ipt_get_entries { /* Which table: user fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; @@ -254,7 +256,7 @@ struct ipt_standard { struct ipt_error_target { struct ipt_entry_target target; - char errorname[IPT_FUNCTION_MAXNAMELEN]; + char errorname[XT_FUNCTION_MAXNAMELEN]; }; struct ipt_error { diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 18442ff19c07..abe31d020e3c 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -27,13 +27,14 @@ #include +#ifndef __KERNEL__ #define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN - #define ip6t_match xt_match #define ip6t_target xt_target #define ip6t_table xt_table #define ip6t_get_revision xt_get_revision +#endif /* Yes, Virginia, you have to zero the padding. */ struct ip6t_ip6 { @@ -117,7 +118,7 @@ struct ip6t_standard { struct ip6t_error_target { struct ip6t_entry_target target; - char errorname[IP6T_FUNCTION_MAXNAMELEN]; + char errorname[XT_FUNCTION_MAXNAMELEN]; }; struct ip6t_error { @@ -203,7 +204,7 @@ struct ip6t_icmp { /* The argument to IP6T_SO_GET_INFO */ struct ip6t_getinfo { /* Which table: caller fills this in. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -225,7 +226,7 @@ struct ip6t_getinfo { /* The argument to IP6T_SO_SET_REPLACE. */ struct ip6t_replace { /* Which table. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -259,7 +260,7 @@ struct ip6t_replace { /* The argument to IP6T_SO_GET_ENTRIES. */ struct ip6t_get_entries { /* Which table: user fills this in. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index e8f4f9a57f12..e427a9e3c489 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -895,7 +895,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -908,7 +908,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(NFPROTO_ARP); @@ -1474,7 +1474,7 @@ out_unlock: } struct compat_arpt_replace { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; @@ -1628,7 +1628,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, } struct compat_arpt_get_entries { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_arpt_entry entrytable[0]; }; @@ -1840,7 +1840,7 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = { { .name = ARPT_ERROR_TARGET, .target = arpt_error, - .targetsize = ARPT_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_ARP, }, }; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d163f2e3b2e9..2efd41bef452 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1092,7 +1092,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -1105,7 +1105,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[IPT_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(AF_INET); @@ -1400,7 +1400,7 @@ do_add_counters(struct net *net, const void __user *user, #ifdef CONFIG_COMPAT struct compat_ipt_replace { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; @@ -1884,7 +1884,7 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, } struct compat_ipt_get_entries { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_ipt_entry entrytable[0]; }; @@ -2039,7 +2039,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IPT_SO_GET_REVISION_MATCH: case IPT_SO_GET_REVISION_TARGET: { - struct ipt_get_revision rev; + struct xt_get_revision rev; int target; if (*len != sizeof(rev)) { @@ -2188,7 +2188,7 @@ static struct xt_target ipt_builtin_tg[] __read_mostly = { { .name = IPT_ERROR_TARGET, .target = ipt_error, - .targetsize = IPT_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV4, }, }; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 8e754be92c24..4b973e13952d 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1105,7 +1105,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -1118,7 +1118,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(AF_INET6); @@ -1415,7 +1415,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, #ifdef CONFIG_COMPAT struct compat_ip6t_replace { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; @@ -1899,7 +1899,7 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, } struct compat_ip6t_get_entries { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_ip6t_entry entrytable[0]; }; @@ -2054,7 +2054,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IP6T_SO_GET_REVISION_MATCH: case IP6T_SO_GET_REVISION_TARGET: { - struct ip6t_get_revision rev; + struct xt_get_revision rev; int target; if (*len != sizeof(rev)) { @@ -2203,7 +2203,7 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = { { .name = IP6T_ERROR_TARGET, .target = ip6t_error, - .targetsize = IP6T_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV6, }, }; -- cgit v1.2.3 From 87a2e70db62fec7348c6e5545eb7b7650c33d81b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Oct 2010 16:11:22 +0200 Subject: netfilter: xtables: resolve indirect macros 2/3 Signed-off-by: Jan Engelhardt --- include/linux/netfilter_arp/arp_tables.h | 15 ++++----- include/linux/netfilter_ipv4/ip_tables.h | 18 +++++------ include/linux/netfilter_ipv6/ip6_tables.h | 20 ++++++------ net/ipv4/netfilter/arp_tables.c | 38 +++++++++++----------- net/ipv4/netfilter/ip_tables.c | 54 +++++++++++++++---------------- net/ipv6/netfilter/ip6_tables.c | 54 +++++++++++++++---------------- net/sched/act_ipt.c | 12 +++---- 7 files changed, 103 insertions(+), 108 deletions(-) diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index 81938600470d..7e193c9241b3 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -24,6 +24,8 @@ #ifndef __KERNEL__ #define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN +#define arpt_entry_target xt_entry_target +#define arpt_standard_target xt_standard_target #endif #define ARPT_DEV_ADDR_LEN_MAX 16 @@ -65,9 +67,6 @@ struct arpt_arp { u_int16_t invflags; }; -#define arpt_entry_target xt_entry_target -#define arpt_standard_target xt_standard_target - /* Values for "flag" field in struct arpt_ip (general arp structure). * No flags defined yet. */ @@ -208,7 +207,7 @@ struct arpt_get_entries { #define ARPT_ERROR_TARGET XT_ERROR_TARGET /* Helper functions */ -static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) +static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e) { return (void *)e + e->target_offset; } @@ -227,11 +226,11 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e /* Standard entry. */ struct arpt_standard { struct arpt_entry entry; - struct arpt_standard_target target; + struct xt_standard_target target; }; struct arpt_error_target { - struct arpt_entry_target target; + struct xt_entry_target target; char errorname[XT_FUNCTION_MAXNAMELEN]; }; @@ -250,7 +249,7 @@ struct arpt_error { { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_standard)), \ .target = XT_TARGET_INIT(ARPT_STANDARD_TARGET, \ - sizeof(struct arpt_standard_target)), \ + sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -287,7 +286,7 @@ struct compat_arpt_entry { unsigned char elems[0]; }; -static inline struct arpt_entry_target * +static inline struct xt_entry_target * compat_arpt_get_target(struct compat_arpt_entry *e) { return (void *)e + e->target_offset; diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 1b7cdf1137e3..ec506918a9b9 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -34,6 +34,10 @@ #define ipt_target xt_target #define ipt_table xt_table #define ipt_get_revision xt_get_revision +#define ipt_entry_match xt_entry_match +#define ipt_entry_target xt_entry_target +#define ipt_standard_target xt_standard_target +#define ipt_counters xt_counters #endif /* Yes, Virginia, you have to zero the padding. */ @@ -54,12 +58,6 @@ struct ipt_ip { u_int8_t invflags; }; -#define ipt_entry_match xt_entry_match -#define ipt_entry_target xt_entry_target -#define ipt_standard_target xt_standard_target - -#define ipt_counters xt_counters - /* Values for "flag" field in struct ipt_ip (general ip structure). */ #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ @@ -219,7 +217,7 @@ struct ipt_get_entries { #define IPT_ERROR_TARGET XT_ERROR_TARGET /* Helper functions */ -static __inline__ struct ipt_entry_target * +static __inline__ struct xt_entry_target * ipt_get_target(struct ipt_entry *e) { return (void *)e + e->target_offset; @@ -251,11 +249,11 @@ extern void ipt_unregister_table(struct net *net, struct xt_table *table); /* Standard entry. */ struct ipt_standard { struct ipt_entry entry; - struct ipt_standard_target target; + struct xt_standard_target target; }; struct ipt_error_target { - struct ipt_entry_target target; + struct xt_entry_target target; char errorname[XT_FUNCTION_MAXNAMELEN]; }; @@ -309,7 +307,7 @@ struct compat_ipt_entry { }; /* Helper functions */ -static inline struct ipt_entry_target * +static inline struct xt_entry_target * compat_ipt_get_target(struct compat_ipt_entry *e) { return (void *)e + e->target_offset; diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index abe31d020e3c..40d11fa05840 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -34,6 +34,10 @@ #define ip6t_target xt_target #define ip6t_table xt_table #define ip6t_get_revision xt_get_revision +#define ip6t_entry_match xt_entry_match +#define ip6t_entry_target xt_entry_target +#define ip6t_standard_target xt_standard_target +#define ip6t_counters xt_counters #endif /* Yes, Virginia, you have to zero the padding. */ @@ -63,12 +67,6 @@ struct ip6t_ip6 { u_int8_t invflags; }; -#define ip6t_entry_match xt_entry_match -#define ip6t_entry_target xt_entry_target -#define ip6t_standard_target xt_standard_target - -#define ip6t_counters xt_counters - /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper protocols */ @@ -113,11 +111,11 @@ struct ip6t_entry { /* Standard entry */ struct ip6t_standard { struct ip6t_entry entry; - struct ip6t_standard_target target; + struct xt_standard_target target; }; struct ip6t_error_target { - struct ip6t_entry_target target; + struct xt_entry_target target; char errorname[XT_FUNCTION_MAXNAMELEN]; }; @@ -136,7 +134,7 @@ struct ip6t_error { { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \ .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \ - sizeof(struct ip6t_standard_target)), \ + sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -275,7 +273,7 @@ struct ip6t_get_entries { #define IP6T_ERROR_TARGET XT_ERROR_TARGET /* Helper functions */ -static __inline__ struct ip6t_entry_target * +static __inline__ struct xt_entry_target * ip6t_get_target(struct ip6t_entry *e) { return (void *)e + e->target_offset; @@ -332,7 +330,7 @@ struct compat_ip6t_entry { unsigned char elems[0]; }; -static inline struct ip6t_entry_target * +static inline struct xt_entry_target * compat_ip6t_get_target(struct compat_ip6t_entry *e) { return (void *)e + e->target_offset; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index e427a9e3c489..ed178cbe6626 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -228,7 +228,7 @@ arpt_error(struct sk_buff *skb, const struct xt_action_param *par) return NF_DROP; } -static inline const struct arpt_entry_target * +static inline const struct xt_entry_target * arpt_get_target_c(const struct arpt_entry *e) { return arpt_get_target((struct arpt_entry *)e); @@ -282,7 +282,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, arp = arp_hdr(skb); do { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { e = arpt_next_entry(e); @@ -297,7 +297,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct arpt_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ if (v != ARPT_RETURN) { @@ -377,7 +377,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct arpt_standard_target *t + const struct xt_standard_target *t = (void *)arpt_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -464,14 +464,14 @@ static int mark_source_chains(const struct xt_table_info *newinfo, static inline int check_entry(const struct arpt_entry *e, const char *name) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; if (!arp_checkentry(&e->arp)) { duprintf("arp_tables: arp check failed %p %s.\n", e, name); return -EINVAL; } - if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset) + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; t = arpt_get_target_c(e); @@ -483,7 +483,7 @@ static inline int check_entry(const struct arpt_entry *e, const char *name) static inline int check_target(struct arpt_entry *e, const char *name) { - struct arpt_entry_target *t = arpt_get_target(e); + struct xt_entry_target *t = arpt_get_target(e); int ret; struct xt_tgchk_param par = { .table = name, @@ -506,7 +506,7 @@ static inline int check_target(struct arpt_entry *e, const char *name) static inline int find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; @@ -536,7 +536,7 @@ out: static bool check_underflow(const struct arpt_entry *e) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->arp)) @@ -544,7 +544,7 @@ static bool check_underflow(const struct arpt_entry *e) t = arpt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct arpt_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -566,7 +566,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, } if (e->next_offset - < sizeof(struct arpt_entry) + sizeof(struct arpt_entry_target)) { + < sizeof(struct arpt_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -598,7 +598,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, static inline void cleanup_entry(struct arpt_entry *e) { struct xt_tgdtor_param par; - struct arpt_entry_target *t; + struct xt_entry_target *t; t = arpt_get_target(e); par.target = t->u.kernel.target; @@ -794,7 +794,7 @@ static int copy_entries_to_user(unsigned int total_size, /* FIXME: use iterator macros --RR */ /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ - const struct arpt_entry_target *t; + const struct xt_entry_target *t; e = (struct arpt_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -807,7 +807,7 @@ static int copy_entries_to_user(unsigned int total_size, t = arpt_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct arpt_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -844,7 +844,7 @@ static int compat_calc_entry(const struct arpt_entry *e, const struct xt_table_info *info, const void *base, struct xt_table_info *newinfo) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -1204,7 +1204,7 @@ static int do_add_counters(struct net *net, const void __user *user, #ifdef CONFIG_COMPAT static inline void compat_release_entry(struct compat_arpt_entry *e) { - struct arpt_entry_target *t; + struct xt_entry_target *t; t = compat_arpt_get_target(e); module_put(t->u.kernel.target->me); @@ -1220,7 +1220,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, const unsigned int *underflows, const char *name) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; int ret, off, h; @@ -1288,7 +1288,7 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct arpt_entry *de; unsigned int origsize; @@ -1567,7 +1567,7 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr, struct xt_counters *counters, unsigned int i) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct compat_arpt_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2efd41bef452..cb108880050a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -186,7 +186,7 @@ static inline bool unconditional(const struct ipt_ip *ip) } /* for const-correctness */ -static inline const struct ipt_entry_target * +static inline const struct xt_entry_target * ipt_get_target_c(const struct ipt_entry *e) { return ipt_get_target((struct ipt_entry *)e); @@ -230,7 +230,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, const char *hookname, const char **chainname, const char **comment, unsigned int *rulenum) { - const struct ipt_standard_target *t = (void *)ipt_get_target_c(s); + const struct xt_standard_target *t = (void *)ipt_get_target_c(s); if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ @@ -346,7 +346,7 @@ ipt_do_table(struct sk_buff *skb, get_entry(table_base, private->underflow[hook])); do { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; const struct xt_entry_match *ematch; IP_NF_ASSERT(e); @@ -380,7 +380,7 @@ ipt_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct ipt_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ if (v != IPT_RETURN) { @@ -461,7 +461,7 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct ipt_standard_target *t + const struct xt_standard_target *t = (void *)ipt_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -552,7 +552,7 @@ mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static void cleanup_match(struct ipt_entry_match *m, struct net *net) +static void cleanup_match(struct xt_entry_match *m, struct net *net) { struct xt_mtdtor_param par; @@ -568,14 +568,14 @@ static void cleanup_match(struct ipt_entry_match *m, struct net *net) static int check_entry(const struct ipt_entry *e, const char *name) { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; if (!ip_checkentry(&e->ip)) { duprintf("ip check failed %p %s.\n", e, par->match->name); return -EINVAL; } - if (e->target_offset + sizeof(struct ipt_entry_target) > + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -587,7 +587,7 @@ check_entry(const struct ipt_entry *e, const char *name) } static int -check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) +check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ipt_ip *ip = par->entryinfo; int ret; @@ -605,7 +605,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) } static int -find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) +find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { struct xt_match *match; int ret; @@ -630,7 +630,7 @@ err: static int check_target(struct ipt_entry *e, struct net *net, const char *name) { - struct ipt_entry_target *t = ipt_get_target(e); + struct xt_entry_target *t = ipt_get_target(e); struct xt_tgchk_param par = { .net = net, .table = name, @@ -656,7 +656,7 @@ static int find_check_entry(struct ipt_entry *e, struct net *net, const char *name, unsigned int size) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; unsigned int j; @@ -707,7 +707,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, static bool check_underflow(const struct ipt_entry *e) { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->ip)) @@ -715,7 +715,7 @@ static bool check_underflow(const struct ipt_entry *e) t = ipt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct ipt_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -738,7 +738,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, } if (e->next_offset - < sizeof(struct ipt_entry) + sizeof(struct ipt_entry_target)) { + < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -771,7 +771,7 @@ static void cleanup_entry(struct ipt_entry *e, struct net *net) { struct xt_tgdtor_param par; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -972,8 +972,8 @@ copy_entries_to_user(unsigned int total_size, /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ unsigned int i; - const struct ipt_entry_match *m; - const struct ipt_entry_target *t; + const struct xt_entry_match *m; + const struct xt_entry_target *t; e = (struct ipt_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -990,7 +990,7 @@ copy_entries_to_user(unsigned int total_size, m = (void *)e + i; if (copy_to_user(userptr + off + i - + offsetof(struct ipt_entry_match, + + offsetof(struct xt_entry_match, u.user.name), m->u.kernel.match->name, strlen(m->u.kernel.match->name)+1) @@ -1002,7 +1002,7 @@ copy_entries_to_user(unsigned int total_size, t = ipt_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct ipt_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -1040,7 +1040,7 @@ static int compat_calc_entry(const struct ipt_entry *e, const void *base, struct xt_table_info *newinfo) { const struct xt_entry_match *ematch; - const struct ipt_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -1407,7 +1407,7 @@ struct compat_ipt_replace { u32 hook_entry[NF_INET_NUMHOOKS]; u32 underflow[NF_INET_NUMHOOKS]; u32 num_counters; - compat_uptr_t counters; /* struct ipt_counters * */ + compat_uptr_t counters; /* struct xt_counters * */ struct compat_ipt_entry entries[0]; }; @@ -1416,7 +1416,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, unsigned int *size, struct xt_counters *counters, unsigned int i) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct compat_ipt_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; @@ -1451,7 +1451,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, } static int -compat_find_calc_match(struct ipt_entry_match *m, +compat_find_calc_match(struct xt_entry_match *m, const char *name, const struct ipt_ip *ip, unsigned int hookmask, @@ -1473,7 +1473,7 @@ compat_find_calc_match(struct ipt_entry_match *m, static void compat_release_entry(struct compat_ipt_entry *e) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -1494,7 +1494,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, const char *name) { struct xt_entry_match *ematch; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; unsigned int j; @@ -1576,7 +1576,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct ipt_entry *de; unsigned int origsize; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4b973e13952d..c7334c10a4b3 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -215,7 +215,7 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6) return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; } -static inline const struct ip6t_entry_target * +static inline const struct xt_entry_target * ip6t_get_target_c(const struct ip6t_entry *e) { return ip6t_get_target((struct ip6t_entry *)e); @@ -260,7 +260,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, const char *hookname, const char **chainname, const char **comment, unsigned int *rulenum) { - const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s); + const struct xt_standard_target *t = (void *)ip6t_get_target_c(s); if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ @@ -369,7 +369,7 @@ ip6t_do_table(struct sk_buff *skb, e = get_entry(table_base, private->hook_entry[hook]); do { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; const struct xt_entry_match *ematch; IP_NF_ASSERT(e); @@ -403,7 +403,7 @@ ip6t_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct ip6t_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ if (v != IP6T_RETURN) { @@ -474,7 +474,7 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct ip6t_standard_target *t + const struct xt_standard_target *t = (void *)ip6t_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -565,7 +565,7 @@ mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static void cleanup_match(struct ip6t_entry_match *m, struct net *net) +static void cleanup_match(struct xt_entry_match *m, struct net *net) { struct xt_mtdtor_param par; @@ -581,14 +581,14 @@ static void cleanup_match(struct ip6t_entry_match *m, struct net *net) static int check_entry(const struct ip6t_entry *e, const char *name) { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; if (!ip6_checkentry(&e->ipv6)) { duprintf("ip_tables: ip check failed %p %s.\n", e, name); return -EINVAL; } - if (e->target_offset + sizeof(struct ip6t_entry_target) > + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -599,7 +599,7 @@ check_entry(const struct ip6t_entry *e, const char *name) return 0; } -static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) +static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ip6t_ip6 *ipv6 = par->entryinfo; int ret; @@ -618,7 +618,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) } static int -find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) +find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { struct xt_match *match; int ret; @@ -643,7 +643,7 @@ err: static int check_target(struct ip6t_entry *e, struct net *net, const char *name) { - struct ip6t_entry_target *t = ip6t_get_target(e); + struct xt_entry_target *t = ip6t_get_target(e); struct xt_tgchk_param par = { .net = net, .table = name, @@ -670,7 +670,7 @@ static int find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, unsigned int size) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; unsigned int j; @@ -721,7 +721,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, static bool check_underflow(const struct ip6t_entry *e) { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->ipv6)) @@ -729,7 +729,7 @@ static bool check_underflow(const struct ip6t_entry *e) t = ip6t_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct ip6t_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -752,7 +752,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, } if (e->next_offset - < sizeof(struct ip6t_entry) + sizeof(struct ip6t_entry_target)) { + < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -784,7 +784,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, static void cleanup_entry(struct ip6t_entry *e, struct net *net) { struct xt_tgdtor_param par; - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -985,8 +985,8 @@ copy_entries_to_user(unsigned int total_size, /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ unsigned int i; - const struct ip6t_entry_match *m; - const struct ip6t_entry_target *t; + const struct xt_entry_match *m; + const struct xt_entry_target *t; e = (struct ip6t_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -1003,7 +1003,7 @@ copy_entries_to_user(unsigned int total_size, m = (void *)e + i; if (copy_to_user(userptr + off + i - + offsetof(struct ip6t_entry_match, + + offsetof(struct xt_entry_match, u.user.name), m->u.kernel.match->name, strlen(m->u.kernel.match->name)+1) @@ -1015,7 +1015,7 @@ copy_entries_to_user(unsigned int total_size, t = ip6t_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct ip6t_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -1053,7 +1053,7 @@ static int compat_calc_entry(const struct ip6t_entry *e, const void *base, struct xt_table_info *newinfo) { const struct xt_entry_match *ematch; - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -1422,7 +1422,7 @@ struct compat_ip6t_replace { u32 hook_entry[NF_INET_NUMHOOKS]; u32 underflow[NF_INET_NUMHOOKS]; u32 num_counters; - compat_uptr_t counters; /* struct ip6t_counters * */ + compat_uptr_t counters; /* struct xt_counters * */ struct compat_ip6t_entry entries[0]; }; @@ -1431,7 +1431,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, unsigned int *size, struct xt_counters *counters, unsigned int i) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct compat_ip6t_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; @@ -1466,7 +1466,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, } static int -compat_find_calc_match(struct ip6t_entry_match *m, +compat_find_calc_match(struct xt_entry_match *m, const char *name, const struct ip6t_ip6 *ipv6, unsigned int hookmask, @@ -1488,7 +1488,7 @@ compat_find_calc_match(struct ip6t_entry_match *m, static void compat_release_entry(struct compat_ip6t_entry *e) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -1509,7 +1509,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, const char *name) { struct xt_entry_match *ematch; - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; unsigned int j; @@ -1591,7 +1591,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct ip6t_entry *de; unsigned int origsize; diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index c7e59e6ec349..f6d464f993ef 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -39,7 +39,7 @@ static struct tcf_hashinfo ipt_hash_info = { .lock = &ipt_lock, }; -static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) +static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) { struct xt_tgchk_param par; struct xt_target *target; @@ -66,7 +66,7 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int return 0; } -static void ipt_destroy_target(struct ipt_entry_target *t) +static void ipt_destroy_target(struct xt_entry_target *t) { struct xt_tgdtor_param par = { .target = t->u.kernel.target, @@ -99,7 +99,7 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ }, [TCA_IPT_HOOK] = { .type = NLA_U32 }, [TCA_IPT_INDEX] = { .type = NLA_U32 }, - [TCA_IPT_TARG] = { .len = sizeof(struct ipt_entry_target) }, + [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) }, }; static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, @@ -108,7 +108,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, struct nlattr *tb[TCA_IPT_MAX + 1]; struct tcf_ipt *ipt; struct tcf_common *pc; - struct ipt_entry_target *td, *t; + struct xt_entry_target *td, *t; char *tname; int ret = 0, err; u32 hook = 0; @@ -126,7 +126,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, if (tb[TCA_IPT_TARG] == NULL) return -EINVAL; - td = (struct ipt_entry_target *)nla_data(tb[TCA_IPT_TARG]); + td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) return -EINVAL; @@ -249,7 +249,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int { unsigned char *b = skb_tail_pointer(skb); struct tcf_ipt *ipt = a->priv; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct tcf_t tm; struct tc_cnt c; -- cgit v1.2.3 From 243bf6e29eef642de0ff62f1ebf58bc2396d6d6e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Oct 2010 16:28:00 +0200 Subject: netfilter: xtables: resolve indirect macros 3/3 --- include/linux/netfilter_arp/arp_tables.h | 33 +++++---------- include/linux/netfilter_ipv4/ip_tables.h | 69 ++++++++++++++----------------- include/linux/netfilter_ipv6/ip6_tables.h | 69 +++++++++++-------------------- net/ipv4/netfilter/arp_tables.c | 14 +++---- net/ipv4/netfilter/arpt_mangle.c | 2 +- net/ipv4/netfilter/ip_tables.c | 18 ++++---- net/ipv6/netfilter/ip6_tables.c | 18 ++++---- net/sched/act_ipt.c | 2 +- 8 files changed, 94 insertions(+), 131 deletions(-) diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index 7e193c9241b3..6e2341a811d6 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -26,6 +26,14 @@ #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN #define arpt_entry_target xt_entry_target #define arpt_standard_target xt_standard_target +#define ARPT_CONTINUE XT_CONTINUE +#define ARPT_RETURN XT_RETURN +#define arpt_counters_info xt_counters_info +#define arpt_counters xt_counters +#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET +#define ARPT_ERROR_TARGET XT_ERROR_TARGET +#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) #endif #define ARPT_DEV_ADDR_LEN_MAX 16 @@ -126,12 +134,6 @@ struct arpt_entry #define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) #define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET) -/* CONTINUE verdict for targets */ -#define ARPT_CONTINUE XT_CONTINUE - -/* For standard target */ -#define ARPT_RETURN XT_RETURN - /* The argument to ARPT_SO_GET_INFO */ struct arpt_getinfo { /* Which table: caller fills this in. */ @@ -185,10 +187,6 @@ struct arpt_replace { struct arpt_entry entries[0]; }; -/* The argument to ARPT_SO_ADD_COUNTERS. */ -#define arpt_counters_info xt_counters_info -#define arpt_counters xt_counters - /* The argument to ARPT_SO_GET_ENTRIES. */ struct arpt_get_entries { /* Which table: user fills this in. */ @@ -201,23 +199,12 @@ struct arpt_get_entries { struct arpt_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define ARPT_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e) { return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ @@ -248,7 +235,7 @@ struct arpt_error { #define ARPT_STANDARD_INIT(__verdict) \ { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_standard)), \ - .target = XT_TARGET_INIT(ARPT_STANDARD_TARGET, \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -256,7 +243,7 @@ struct arpt_error { #define ARPT_ERROR_INIT \ { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_error)), \ - .target = XT_TARGET_INIT(ARPT_ERROR_TARGET, \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ sizeof(struct arpt_error_target)), \ .target.errorname = "ERROR", \ } diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index ec506918a9b9..ee54b3b7e237 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -38,6 +38,36 @@ #define ipt_entry_target xt_entry_target #define ipt_standard_target xt_standard_target #define ipt_counters xt_counters +#define IPT_CONTINUE XT_CONTINUE +#define IPT_RETURN XT_RETURN + +/* This group is older than old (iptables < v1.4.0-rc1~89) */ +#include +#define ipt_udp xt_udp +#define ipt_tcp xt_tcp +#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT +#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT +#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS +#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION +#define IPT_TCP_INV_MASK XT_TCP_INV_MASK +#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT +#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT +#define IPT_UDP_INV_MASK XT_UDP_INV_MASK + +/* The argument to IPT_SO_ADD_COUNTERS. */ +#define ipt_counters_info xt_counters_info +/* Standard return verdict, or do jump. */ +#define IPT_STANDARD_TARGET XT_STANDARD_TARGET +/* Error verdict. */ +#define IPT_ERROR_TARGET XT_ERROR_TARGET + +/* fn returns 0 to continue iteration */ +#define IPT_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) + +/* fn returns 0 to continue iteration */ +#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) #endif /* Yes, Virginia, you have to zero the padding. */ @@ -116,23 +146,6 @@ struct ipt_entry { #define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) #define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET -#define IPT_CONTINUE XT_CONTINUE -#define IPT_RETURN XT_RETURN - -#include -#define ipt_udp xt_udp -#define ipt_tcp xt_tcp - -#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IPT_TCP_INV_MASK XT_TCP_INV_MASK - -#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IPT_UDP_INV_MASK XT_UDP_INV_MASK - /* ICMP matching stuff */ struct ipt_icmp { u_int8_t type; /* type to match */ @@ -196,9 +209,6 @@ struct ipt_replace { struct ipt_entry entries[0]; }; -/* The argument to IPT_SO_ADD_COUNTERS. */ -#define ipt_counters_info xt_counters_info - /* The argument to IPT_SO_GET_ENTRIES. */ struct ipt_get_entries { /* Which table: user fills this in. */ @@ -211,11 +221,6 @@ struct ipt_get_entries { struct ipt_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define IPT_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define IPT_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ static __inline__ struct xt_entry_target * ipt_get_target(struct ipt_entry *e) @@ -223,16 +228,6 @@ ipt_get_target(struct ipt_entry *e) return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define IPT_MATCH_ITERATE(e, fn, args...) \ - XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) - -/* fn returns 0 to continue iteration */ -#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ @@ -271,7 +266,7 @@ struct ipt_error { #define IPT_STANDARD_INIT(__verdict) \ { \ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \ - .target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -279,7 +274,7 @@ struct ipt_error { #define IPT_ERROR_INIT \ { \ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \ - .target = XT_TARGET_INIT(IPT_ERROR_TARGET, \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ sizeof(struct ipt_error_target)), \ .target.errorname = "ERROR", \ } diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 40d11fa05840..ac2b411ea63a 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -38,6 +38,29 @@ #define ip6t_entry_target xt_entry_target #define ip6t_standard_target xt_standard_target #define ip6t_counters xt_counters +#define IP6T_CONTINUE XT_CONTINUE +#define IP6T_RETURN XT_RETURN + +/* Pre-iptables-1.4.0 */ +#include +#define ip6t_tcp xt_tcp +#define ip6t_udp xt_udp +#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT +#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT +#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS +#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION +#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK +#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT +#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT +#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK + +#define ip6t_counters_info xt_counters_info +#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET +#define IP6T_ERROR_TARGET XT_ERROR_TARGET +#define IP6T_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) +#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) #endif /* Yes, Virginia, you have to zero the padding. */ @@ -133,7 +156,7 @@ struct ip6t_error { #define IP6T_STANDARD_INIT(__verdict) \ { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \ - .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -141,7 +164,7 @@ struct ip6t_error { #define IP6T_ERROR_INIT \ { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \ - .target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ sizeof(struct ip6t_error_target)), \ .target.errorname = "ERROR", \ } @@ -165,30 +188,6 @@ struct ip6t_error { #define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5) #define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET -/* CONTINUE verdict for targets */ -#define IP6T_CONTINUE XT_CONTINUE - -/* For standard target */ -#define IP6T_RETURN XT_RETURN - -/* TCP/UDP matching stuff */ -#include - -#define ip6t_tcp xt_tcp -#define ip6t_udp xt_udp - -/* Values for "inv" field in struct ipt_tcp. */ -#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK - -/* Values for "invflags" field in struct ipt_udp. */ -#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK - /* ICMP matching stuff */ struct ip6t_icmp { u_int8_t type; /* type to match */ @@ -252,9 +251,6 @@ struct ip6t_replace { struct ip6t_entry entries[0]; }; -/* The argument to IP6T_SO_ADD_COUNTERS. */ -#define ip6t_counters_info xt_counters_info - /* The argument to IP6T_SO_GET_ENTRIES. */ struct ip6t_get_entries { /* Which table: user fills this in. */ @@ -267,11 +263,6 @@ struct ip6t_get_entries { struct ip6t_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define IP6T_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ static __inline__ struct xt_entry_target * ip6t_get_target(struct ip6t_entry *e) @@ -279,16 +270,6 @@ ip6t_get_target(struct ip6t_entry *e) return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define IP6T_MATCH_ITERATE(e, fn, args...) \ - XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) - -/* fn returns 0 to continue iteration */ -#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index ed178cbe6626..d756edae59ec 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -300,7 +300,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != ARPT_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -332,7 +332,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, /* Target might have changed stuff. */ arp = arp_hdr(skb); - if (verdict == ARPT_CONTINUE) + if (verdict == XT_CONTINUE) e = arpt_next_entry(e); else /* Verdict */ @@ -392,13 +392,13 @@ static int mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct arpt_entry) && (strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->arp)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -433,7 +433,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct arpt_entry)) { @@ -1828,7 +1828,7 @@ void arpt_unregister_table(struct xt_table *table) /* The built-in targets: standard (NULL) and error. */ static struct xt_target arpt_builtin_tg[] __read_mostly = { { - .name = ARPT_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_ARP, #ifdef CONFIG_COMPAT @@ -1838,7 +1838,7 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = { #endif }, { - .name = ARPT_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = arpt_error, .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_ARP, diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index e1be7dd1171b..b8ddcc480ed9 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c @@ -63,7 +63,7 @@ static int checkentry(const struct xt_tgchk_param *par) return false; if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && - mangle->target != ARPT_CONTINUE) + mangle->target != XT_CONTINUE) return false; return true; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index cb108880050a..d31b007a6d80 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -232,7 +232,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, { const struct xt_standard_target *t = (void *)ipt_get_target_c(s); - if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { + if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -241,7 +241,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, if (s->target_offset == sizeof(struct ipt_entry) && strcmp(t->target.u.kernel.target->name, - IPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && t->verdict < 0 && unconditional(&s->ip)) { /* Tail of chains: STANDARD target (return/policy) */ @@ -383,7 +383,7 @@ ipt_do_table(struct sk_buff *skb, v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != IPT_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -421,7 +421,7 @@ ipt_do_table(struct sk_buff *skb, verdict = t->u.kernel.target->target(skb, &acpar); /* Target might have changed stuff. */ ip = ip_hdr(skb); - if (verdict == IPT_CONTINUE) + if (verdict == XT_CONTINUE) e = ipt_next_entry(e); else /* Verdict */ @@ -475,13 +475,13 @@ mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct ipt_entry) && (strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->ip)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -524,7 +524,7 @@ mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct ipt_entry)) { @@ -2176,7 +2176,7 @@ static int icmp_checkentry(const struct xt_mtchk_param *par) static struct xt_target ipt_builtin_tg[] __read_mostly = { { - .name = IPT_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_IPV4, #ifdef CONFIG_COMPAT @@ -2186,7 +2186,7 @@ static struct xt_target ipt_builtin_tg[] __read_mostly = { #endif }, { - .name = IPT_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = ipt_error, .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV4, diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index c7334c10a4b3..c683e9e7023b 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -262,7 +262,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, { const struct xt_standard_target *t = (void *)ip6t_get_target_c(s); - if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { + if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -271,7 +271,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, if (s->target_offset == sizeof(struct ip6t_entry) && strcmp(t->target.u.kernel.target->name, - IP6T_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && t->verdict < 0 && unconditional(&s->ipv6)) { /* Tail of chains: STANDARD target (return/policy) */ @@ -406,7 +406,7 @@ ip6t_do_table(struct sk_buff *skb, v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != IP6T_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -434,7 +434,7 @@ ip6t_do_table(struct sk_buff *skb, acpar.targinfo = t->data; verdict = t->u.kernel.target->target(skb, &acpar); - if (verdict == IP6T_CONTINUE) + if (verdict == XT_CONTINUE) e = ip6t_next_entry(e); else /* Verdict */ @@ -488,13 +488,13 @@ mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct ip6t_entry) && (strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->ipv6)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -537,7 +537,7 @@ mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct ip6t_entry)) { @@ -2191,7 +2191,7 @@ static int icmp6_checkentry(const struct xt_mtchk_param *par) /* The built-in targets: standard (NULL) and error. */ static struct xt_target ip6t_builtin_tg[] __read_mostly = { { - .name = IP6T_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_IPV6, #ifdef CONFIG_COMPAT @@ -2201,7 +2201,7 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = { #endif }, { - .name = IP6T_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = ip6t_error, .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV6, diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index f6d464f993ef..8daef9632255 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -230,7 +230,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a, result = TC_ACT_SHOT; ipt->tcf_qstats.drops++; break; - case IPT_CONTINUE: + case XT_CONTINUE: result = TC_ACT_PIPE; break; default: -- cgit v1.2.3 From 75f0a0fd787bfa3ea1a916ca632a5b9e0007cbb7 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Oct 2010 16:37:45 +0200 Subject: netfilter: xtables: unify {ip,ip6,arp}t_error_target Unification of struct *_error_target was forgotten in v2.6.16-1689-g1e30a01. Signed-off-by: Jan Engelhardt --- include/linux/netfilter/x_tables.h | 5 +++++ include/linux/netfilter_arp/arp_tables.h | 10 +++------- include/linux/netfilter_ipv4/ip_tables.h | 10 +++------- include/linux/netfilter_ipv6/ip6_tables.h | 10 +++------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 24e5d01d27d0..742bec051440 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -66,6 +66,11 @@ struct xt_standard_target { int verdict; }; +struct xt_error_target { + struct xt_entry_target target; + char errorname[XT_FUNCTION_MAXNAMELEN]; +}; + /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision * kernel supports, if >= revision. */ struct xt_get_revision { diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index 6e2341a811d6..f02d57436a34 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -26,6 +26,7 @@ #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN #define arpt_entry_target xt_entry_target #define arpt_standard_target xt_standard_target +#define arpt_error_target xt_error_target #define ARPT_CONTINUE XT_CONTINUE #define ARPT_RETURN XT_RETURN #define arpt_counters_info xt_counters_info @@ -216,14 +217,9 @@ struct arpt_standard { struct xt_standard_target target; }; -struct arpt_error_target { - struct xt_entry_target target; - char errorname[XT_FUNCTION_MAXNAMELEN]; -}; - struct arpt_error { struct arpt_entry entry; - struct arpt_error_target target; + struct xt_error_target target; }; #define ARPT_ENTRY_INIT(__size) \ @@ -244,7 +240,7 @@ struct arpt_error { { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_error)), \ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ - sizeof(struct arpt_error_target)), \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index ee54b3b7e237..d0fef0a436f9 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -37,6 +37,7 @@ #define ipt_entry_match xt_entry_match #define ipt_entry_target xt_entry_target #define ipt_standard_target xt_standard_target +#define ipt_error_target xt_error_target #define ipt_counters xt_counters #define IPT_CONTINUE XT_CONTINUE #define IPT_RETURN XT_RETURN @@ -247,14 +248,9 @@ struct ipt_standard { struct xt_standard_target target; }; -struct ipt_error_target { - struct xt_entry_target target; - char errorname[XT_FUNCTION_MAXNAMELEN]; -}; - struct ipt_error { struct ipt_entry entry; - struct ipt_error_target target; + struct xt_error_target target; }; #define IPT_ENTRY_INIT(__size) \ @@ -275,7 +271,7 @@ struct ipt_error { { \ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ - sizeof(struct ipt_error_target)), \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index ac2b411ea63a..dca11186e522 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -37,6 +37,7 @@ #define ip6t_entry_match xt_entry_match #define ip6t_entry_target xt_entry_target #define ip6t_standard_target xt_standard_target +#define ip6t_error_target xt_error_target #define ip6t_counters xt_counters #define IP6T_CONTINUE XT_CONTINUE #define IP6T_RETURN XT_RETURN @@ -137,14 +138,9 @@ struct ip6t_standard { struct xt_standard_target target; }; -struct ip6t_error_target { - struct xt_entry_target target; - char errorname[XT_FUNCTION_MAXNAMELEN]; -}; - struct ip6t_error { struct ip6t_entry entry; - struct ip6t_error_target target; + struct xt_error_target target; }; #define IP6T_ENTRY_INIT(__size) \ @@ -165,7 +161,7 @@ struct ip6t_error { { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ - sizeof(struct ip6t_error_target)), \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } -- cgit v1.2.3 From 9ecdafd883db3c43296797382fc0b2c868144070 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 13 Oct 2010 16:42:02 +0200 Subject: netfilter: xtables: remove unused defines Signed-off-by: Jan Engelhardt --- include/linux/netfilter_arp/arp_tables.h | 4 ---- include/linux/netfilter_ipv4/ip_tables.h | 4 ---- include/linux/netfilter_ipv6/ip6_tables.h | 4 ---- 3 files changed, 12 deletions(-) diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index f02d57436a34..adbf4bff87ed 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -255,8 +255,6 @@ extern unsigned int arpt_do_table(struct sk_buff *skb, const struct net_device *out, struct xt_table *table); -#define ARPT_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -275,8 +273,6 @@ compat_arpt_get_target(struct compat_arpt_entry *e) return (void *)e + e->target_offset; } -#define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _ARPTABLES_H */ diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index d0fef0a436f9..64a5d95c58e8 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -282,8 +282,6 @@ extern unsigned int ipt_do_table(struct sk_buff *skb, const struct net_device *out, struct xt_table *table); -#define IPT_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -304,8 +302,6 @@ compat_ipt_get_target(struct compat_ipt_entry *e) return (void *)e + e->target_offset; } -#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */ diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index dca11186e522..c9784f7a9c1f 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -292,8 +292,6 @@ extern int ip6t_ext_hdr(u8 nexthdr); extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target, unsigned short *fragoff); -#define IP6T_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -313,8 +311,6 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e) return (void *)e + e->target_offset; } -#define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IP6_TABLES_H */ -- cgit v1.2.3 From 9fbb711ee1a70826440502133903d4df025c0b78 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Oct 2010 09:11:26 -0700 Subject: s390: ctcm_mpc: Fix build after netdev refcount changes. Reported-by: Sachin Sant Signed-off-by: David S. Miller --- drivers/s390/net/ctcm_mpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 2861e78773cb..b64881f33f23 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -540,7 +540,7 @@ void ctc_mpc_dealloc_ch(int port_num) CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG, "%s: %s: refcount = %d\n", - CTCM_FUNTAIL, dev->name, atomic_read(&dev->refcnt)); + CTCM_FUNTAIL, dev->name, netdev_refcnt_read(dev)); fsm_deltimer(&priv->restart_timer); grp->channels_terminating = 0; -- cgit v1.2.3 From a91fd267e327ca7599654b4e9ed7b62c5adaccee Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 13 Oct 2010 21:22:35 +0200 Subject: IPVS: ip_vs_dbg_callid() is only needed for debugging ip_vs_dbg_callid() and IP_VS_DEBUG_CALLID() are only needed it CONFIG_IP_VS_DEBUG is defined. This resolves the following build warning when CONFIG_IP_VS_DEBUG is not defined. net/netfilter/ipvs/ip_vs_pe_sip.c:11: warning: 'ip_vs_dbg_callid' defined but not used Reported-by: Patrick McHardy Signed-off-by: Simon Horman Signed-off-by: Patrick McHardy --- net/netfilter/ipvs/ip_vs_pe_sip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c index a0539f13e2b4..b8b4e9620f3e 100644 --- a/net/netfilter/ipvs/ip_vs_pe_sip.c +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c @@ -8,6 +8,7 @@ #include #include +#ifdef CONFIG_IP_VS_DEBUG static const char *ip_vs_dbg_callid(char *buf, size_t buf_len, const char *callid, size_t callid_len, int *idx) @@ -22,6 +23,7 @@ static const char *ip_vs_dbg_callid(char *buf, size_t buf_len, #define IP_VS_DEBUG_CALLID(callid, len) \ ip_vs_dbg_callid(ip_vs_dbg_buf, sizeof(ip_vs_dbg_buf), \ callid, len, &ip_vs_dbg_idx) +#endif static int get_callid(const char *dptr, unsigned int dataoff, unsigned int datalen, -- cgit v1.2.3 From 10d8dad8453f8648a448960d7a2d3d983dfe0ed3 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 12 Oct 2010 07:07:42 +0200 Subject: wext: fix alignment problem in serializing 'struct iw_point' wext: fix alignment problem in serializing 'struct iw_point' This fixes a typo in the definition of the serialized length of struct iw_point: a) wireless.h is exported to userspace, the typo causes IW_EV_POINT_PK_LEN to be 12 on 64-bit, and 8 on 32-bit systems (causing misalignment); b) in compat-64 mode iwe_stream_add_point() memcpys overlap (see below). The second case in in compat-64 mode looks like (variable names are as in include/net/iw_handler.h:iwe_stream_add_point()): point_len = IW_EV_COMPAT_POINT_LEN = 8 lcp_len = IW_EV_COMPAT_LCP_LEN = 4 2nd memcpy: IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN = 12 - 4 = 8 IW_EV_LCP_PK_LEN <--------------> *---> 'extra' data area +-------+-------+-------+-------+---------------+------- ...-+ | len | cmd |length | flags | (empty) -> extra ... | +-------+-------+-------+-------+---------------+------- ...-+ 2 2 2 2 4 lcp_len <--------------> <-!! OVERLAP !!> <--1st memcpy--><------- 2nd memcpy -----------> <---- 3rd memcpy ------- ... > <--------- point_len ----------> This case could cause overrun whenever iw_point.length < 4. The other two cases are - * 32-bit systems: IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN = 8 - 4 = 4, the second memcpy copies exactly the 4 required bytes; * 64-bit systems: IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN = 12 - 4 = 8, the second memcpy copies a superfluous (but non overlapping) 4 bytes. The patch changes IW_EV_POINT_PK_LEN to be 8, so that in all 3 cases always only the requested iw_point.{length,flags} (both __u16) are copied, avoiding overrrun (compat-64) and superfluous copy (64-bit). In addition, the userspace header is sanitized (in agreement with version 30 of the wireless tools). Many thanks to Johannes Berg for help and review with this patch. Signed-off-by: Gerrit Renker Signed-off-by: John W. Linville --- include/linux/wireless.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/wireless.h b/include/linux/wireless.h index e6827eedf18b..4395b28bb86c 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h @@ -1157,6 +1157,6 @@ struct __compat_iw_event { #define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) #define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr)) #define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) -#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4) +#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4) #endif /* _LINUX_WIRELESS_H */ -- cgit v1.2.3 From d84a35d1323bc62f9b26a707072767a60da75015 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 12 Oct 2010 10:55:38 -0700 Subject: ath5k: Move debugfs under ieee80211/[wiphy-name] This automatically keeps things proper when wiphy is renamed. Based on patch by Johannes Berg Signed-off-by: Ben Greear Acked-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 +------ drivers/net/wireless/ath/ath5k/debug.c | 20 ++------------------ drivers/net/wireless/ath/ath5k/debug.h | 12 ------------ 3 files changed, 3 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 7baaf04f092d..f1ae75d35d5d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3541,8 +3541,6 @@ ath5k_pci_probe(struct pci_dev *pdev, sc->hw = hw; sc->pdev = pdev; - ath5k_debug_init_device(sc); - /* * Mark the device as detached to avoid processing * interrupts until setup is complete. @@ -3650,6 +3648,7 @@ ath5k_pci_probe(struct pci_dev *pdev, } } + ath5k_debug_init_device(sc); /* ready to process interrupts */ __clear_bit(ATH_STAT_INVALID, sc->status); @@ -3736,8 +3735,6 @@ init_ath5k_pci(void) { int ret; - ath5k_debug_init(); - ret = pci_register_driver(&ath5k_pci_driver); if (ret) { printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); @@ -3751,8 +3748,6 @@ static void __exit exit_ath5k_pci(void) { pci_unregister_driver(&ath5k_pci_driver); - - ath5k_debug_finish(); } module_init(init_ath5k_pci); diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 7c77e5b7c9af..42ea5b1bdb12 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -72,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0); #include "reg.h" #include "ani.h" -static struct dentry *ath5k_global_debugfs; - static int ath5k_debugfs_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -882,21 +880,13 @@ static const struct file_operations fops_queue = { }; -/* init */ - -void -ath5k_debug_init(void) -{ - ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL); -} - void ath5k_debug_init_device(struct ath5k_softc *sc) { sc->debug.level = ath5k_debug; - sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), - ath5k_global_debugfs); + sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", + sc->hw->wiphy->debugfsdir); sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUSR, @@ -936,12 +926,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc) &fops_queue); } -void -ath5k_debug_finish(void) -{ - debugfs_remove(ath5k_global_debugfs); -} - void ath5k_debug_finish_device(struct ath5k_softc *sc) { diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 4f078b134015..236edbd2507d 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -137,15 +137,9 @@ enum ath5k_debug_level { __func__, __LINE__, ##__VA_ARGS__); \ } while (0) -void -ath5k_debug_init(void); - void ath5k_debug_init_device(struct ath5k_softc *sc); -void -ath5k_debug_finish(void); - void ath5k_debug_finish_device(struct ath5k_softc *sc); @@ -173,15 +167,9 @@ static inline void __attribute__ ((format (printf, 3, 4))) ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} -static inline void -ath5k_debug_init(void) {} - static inline void ath5k_debug_init_device(struct ath5k_softc *sc) {} -static inline void -ath5k_debug_finish(void) {} - static inline void ath5k_debug_finish_device(struct ath5k_softc *sc) {} -- cgit v1.2.3 From 7a8266524af7ec70d1b3d10f964ce911d922d466 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 13 Oct 2010 11:47:09 +0530 Subject: ath9k: Fix documentation in rate control This fix updates the documenation in Rate Control Table structure Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/ath/ath9k/rc.h | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 13f9e88e1187..abebf2466a13 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = { [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, - 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ + 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */ [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 268072fd3c1c..fbb1d33ee4b7 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -135,20 +135,21 @@ enum { /** * struct ath_rate_table - Rate Control table - * @valid: valid for use in rate control - * @valid_single_stream: valid for use in rate control for - * single stream operation - * @phy: CCK/OFDM + * @rate_cnt: total number of rates for the given wireless mode + * @mcs_start: MCS rate index offset + * @rate_flags: Rate Control flags + * @phy: CCK/OFDM/HT20/HT40 * @ratekbps: rate in Kbits per second * @user_ratekbps: user rate in Kbits per second * @ratecode: rate that goes into HW descriptors - * @short_preamble: Mask for enabling short preamble in ratecode for CCK * @dot11rate: value that goes into supported * rates info element of MLME * @ctrl_rate: Index of next lower basic rate, used for duration computation - * @max_4ms_framelen: maximum frame length(bytes) for tx duration + * @cw40index: Index of rates having 40MHz channel width + * @sgi_index: Index of rates having Short Guard Interval + * @ht_index: high throughput rates having 40MHz channel width and + * Short Guard Interval * @probe_interval: interval for rate control to probe for other rates - * @rssi_reduce_interval: interval for rate control to reduce rssi * @initial_ratemax: initial ratemax value */ struct ath_rate_table { -- cgit v1.2.3 From 271733cf844a2f5f186ef3b40c26d6397b71039a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Oct 2010 12:06:23 +0200 Subject: cfg80211: notify drivers about frame registrations Drivers may need to adjust their filters according to frame registrations, so notify them about them. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 7 +++++++ net/wireless/mlme.c | 23 ++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 24d5b5869272..2a7936d7851d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1147,6 +1147,9 @@ struct cfg80211_pmksa { * allows the driver to adjust the dynamic ps timeout value. * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. * + * @mgmt_frame_register: Notify driver that a management frame type was + * registered. Note that this callback may not sleep, and cannot run + * concurrently with itself. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -1297,6 +1300,10 @@ struct cfg80211_ops { int (*set_cqm_rssi_config)(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst); + + void (*mgmt_frame_register)(struct wiphy *wiphy, + struct net_device *dev, + u16 frame_type, bool reg); }; /* diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index caf11a427507..26838d903b9a 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, u16 frame_type, const u8 *match_data, int match_len) { + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); struct cfg80211_mgmt_registration *reg, *nreg; int err = 0; u16 mgmt_type; @@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, nreg->frame_type = cpu_to_le16(frame_type); list_add(&nreg->list, &wdev->mgmt_registrations); + if (rdev->ops->mgmt_frame_register) + rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, + frame_type, true); + out: spin_unlock_bh(&wdev->mgmt_registrations_lock); + return err; } void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) { + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); struct cfg80211_mgmt_registration *reg, *tmp; spin_lock_bh(&wdev->mgmt_registrations_lock); list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { - if (reg->nlpid == nlpid) { - list_del(®->list); - kfree(reg); + if (reg->nlpid != nlpid) + continue; + + if (rdev->ops->mgmt_frame_register) { + u16 frame_type = le16_to_cpu(reg->frame_type); + + rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, + frame_type, false); } + + list_del(®->list); + kfree(reg); } spin_unlock_bh(&wdev->mgmt_registrations_lock); -- cgit v1.2.3 From 7be5086d4cb7cceb71d724a9524d5e927785d04f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Oct 2010 12:06:24 +0200 Subject: mac80211: add probe request filter flag Using the frame registration notification, we can see when probe requests are requested and notify the low-level driver via filtering. The flag is also set in AP and IBSS modes. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 9 ++++++--- net/mac80211/cfg.c | 18 ++++++++++++++++++ net/mac80211/ieee80211_i.h | 4 +++- net/mac80211/iface.c | 9 ++++++++- net/mac80211/main.c | 3 +++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 33aa2e39147b..9fdf982d1286 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1478,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * honour this flag if possible. * * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS - * is not set then only those addressed to this station. + * is not set then only those addressed to this station. * * @FIF_OTHER_BSS: pass frames destined to other BSSes * - * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only - * those addressed to this station. + * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only + * those addressed to this station. + * + * @FIF_PROBE_REQ: pass probe request frames */ enum ieee80211_filter_flags { FIF_PROMISC_IN_BSS = 1<<0, @@ -1494,6 +1496,7 @@ enum ieee80211_filter_flags { FIF_CONTROL = 1<<5, FIF_OTHER_BSS = 1<<6, FIF_PSPOLL = 1<<7, + FIF_PROBE_REQ = 1<<8, }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 25fb351e00f8..18bd0e550600 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1604,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, return 0; } +static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, + struct net_device *dev, + u16 frame_type, bool reg) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) + return; + + if (reg) + local->probe_req_reg++; + else + local->probe_req_reg--; + + ieee80211_queue_work(&local->hw, &local->reconfig_filter); +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1655,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = { .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, .mgmt_tx = ieee80211_mgmt_tx, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, + .mgmt_frame_register = ieee80211_mgmt_frame_register, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f0610fa4fbe0..b80c38689927 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -707,7 +707,9 @@ struct ieee80211_local { int open_count; int monitors, cooked_mntrs; /* number of interfaces with corresponding FIF_ flags */ - int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; + int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, + fif_probe_req; + int probe_req_reg; unsigned int filter_flags; /* FIF_* */ bool wiphy_ciphers_allocated; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e99d1b60557c..f9163b12c7f1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) ieee80211_start_mesh(sdata); } else if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll++; + local->fif_probe_req++; ieee80211_configure_filter(local); + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { + local->fif_probe_req++; } changed |= ieee80211_reset_erp_info(sdata); @@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, if (sdata->flags & IEEE80211_SDATA_PROMISC) atomic_dec(&local->iff_promiscs); - if (sdata->vif.type == NL80211_IFTYPE_AP) + if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll--; + local->fif_probe_req--; + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { + local->fif_probe_req--; + } netif_addr_lock_bh(sdata->dev); spin_lock_bh(&local->filter_lock); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 915ecf87e4ac..5162303a8b4a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) if (local->monitors || local->scanning) new_flags |= FIF_BCN_PRBRESP_PROMISC; + if (local->fif_probe_req || local->probe_req_reg) + new_flags |= FIF_PROBE_REQ; + if (local->fif_fcsfail) new_flags |= FIF_FCSFAIL; -- cgit v1.2.3 From 9c1d8e4affe6748d884a677cf5db19ae0c20ef07 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 13 Oct 2010 17:29:31 +0300 Subject: ath9k: Set RX filter for Probe Request based on filter flag This allows mac80211 to enable receiving of Probe Request frames in station mode which is needed for P2P. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + drivers/net/wireless/ath/ath9k/recv.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 865649120075..bcd3892dca8d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1739,6 +1739,7 @@ skip_chan_change: FIF_PSPOLL | \ FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC | \ + FIF_PROBE_REQ | \ FIF_FCSFAIL) /* FIXME: sc->sc_full_reset ? */ diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 9c166f3804ab..7c90eaf9ec55 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -430,8 +430,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; - /* If not a STA, enable processing of Probe Requests */ - if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) + if (sc->rx.rxfilter & FIF_PROBE_REQ) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* -- cgit v1.2.3 From e4b55957eb695b43055b6badec026628b24fe80a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 13 Oct 2010 19:23:21 +0200 Subject: mac80211: fix SMPS request It looks like I submitted a different patch than I tested, because clearly the code in mac80211 is missing actually propagating the requested SMPS mode. Fix that! Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ht.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 4214bb6e12fc..75d679d75e63 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) smps_mode = IEEE80211_SMPS_AUTOMATIC; + sdata->u.mgd.driver_smps_mode = smps_mode; + ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.request_smps_work); } -- cgit v1.2.3 From c23cc81a5e5c1d4486b662cedd0afcdf9145f154 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 13 Oct 2010 12:01:23 -0700 Subject: ath9k: Fix potential use-after-free. The ath_debug_stat_tx references bf->bf_mpdu, which is the skb consumed by ath_tx_complete. So, call the ath_debug_stat_tx method first. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9a11099dd86a..9b17108adc7c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1924,8 +1924,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, else complete(&sc->paprd_complete); } else { - ath_tx_complete(sc, skb, bf->aphy, tx_flags); ath_debug_stat_tx(sc, txq, bf, ts); + ath_tx_complete(sc, skb, bf->aphy, tx_flags); } /* -- cgit v1.2.3 From 7368ddf144afd79456fd853fa25f33e31da003a9 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 12 Oct 2010 14:25:58 +0000 Subject: tipc: clean out all instances of #if 0'd unused code Remove all instances of legacy, or as yet to be implemented code that is currently living within an #if 0 ... #endif block. In the rare instance that some of it be needed in the future, it can still be dragged out of history, but there is no need for it to sit in mainline. Signed-off-by: Paul Gortmaker Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/tipc/config.c | 141 -------------------------------------------------- net/tipc/discover.c | 20 ------- net/tipc/discover.h | 3 -- net/tipc/link.c | 112 +-------------------------------------- net/tipc/link.h | 4 -- net/tipc/name_table.c | 17 ------ net/tipc/net.c | 9 ---- net/tipc/node.c | 26 ---------- net/tipc/port.c | 44 ---------------- 9 files changed, 1 insertion(+), 375 deletions(-) diff --git a/net/tipc/config.c b/net/tipc/config.c index 961d1b097146..c429b0d488a3 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -120,139 +120,6 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) return buf; } - -#if 0 - -/* Now obsolete code for handling commands not yet implemented the new way */ - -/* - * Some of this code assumed that the manager structure contains two added - * fields: - * u32 link_subscriptions; - * struct list_head link_subscribers; - * which are currently not present. These fields may need to be re-introduced - * if and when support for link subscriptions is added. - */ - -void tipc_cfg_link_event(u32 addr, char *name, int up) -{ - /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */ -} - -int tipc_cfg_cmd(const struct tipc_cmd_msg * msg, - char *data, - u32 sz, - u32 *ret_size, - struct tipc_portid *orig) -{ - int rv = -EINVAL; - u32 cmd = msg->cmd; - - *ret_size = 0; - switch (cmd) { - case TIPC_REMOVE_LINK: - case TIPC_CMD_BLOCK_LINK: - case TIPC_CMD_UNBLOCK_LINK: - if (!cfg_check_connection(orig)) - rv = link_control(msg->argv.link_name, msg->cmd, 0); - break; - case TIPC_ESTABLISH: - { - int connected; - - tipc_isconnected(mng.conn_port_ref, &connected); - if (connected || !orig) { - rv = TIPC_FAILURE; - break; - } - rv = tipc_connect2port(mng.conn_port_ref, orig); - if (rv == TIPC_OK) - orig = 0; - break; - } - case TIPC_GET_PEER_ADDRESS: - *ret_size = link_peer_addr(msg->argv.link_name, data, sz); - break; - case TIPC_GET_ROUTES: - rv = TIPC_OK; - break; - default: {} - } - if (*ret_size) - rv = TIPC_OK; - return rv; -} - -static void cfg_cmd_event(struct tipc_cmd_msg *msg, - char *data, - u32 sz, - struct tipc_portid const *orig) -{ - int rv = -EINVAL; - struct tipc_cmd_result_msg rmsg; - struct iovec msg_sect[2]; - int *arg; - - msg->cmd = ntohl(msg->cmd); - - cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect, - data, 0); - if (ntohl(msg->magic) != TIPC_MAGIC) - goto exit; - - switch (msg->cmd) { - case TIPC_CREATE_LINK: - if (!cfg_check_connection(orig)) - rv = disc_create_link(&msg->argv.create_link); - break; - case TIPC_LINK_SUBSCRIBE: - { - struct subscr_data *sub; - - if (mng.link_subscriptions > 64) - break; - sub = kmalloc(sizeof(*sub), - GFP_ATOMIC); - if (sub == NULL) { - warn("Memory squeeze; dropped remote link subscription\n"); - break; - } - INIT_LIST_HEAD(&sub->subd_list); - tipc_createport(mng.user_ref, - (void *)sub, - TIPC_HIGH_IMPORTANCE, - 0, - 0, - (tipc_conn_shutdown_event)cfg_linksubscr_cancel, - 0, - 0, - (tipc_conn_msg_event)cfg_linksubscr_cancel, - 0, - &sub->port_ref); - if (!sub->port_ref) { - kfree(sub); - break; - } - memcpy(sub->usr_handle,msg->usr_handle, - sizeof(sub->usr_handle)); - sub->domain = msg->argv.domain; - list_add_tail(&sub->subd_list, &mng.link_subscribers); - tipc_connect2port(sub->port_ref, orig); - rmsg.retval = TIPC_OK; - tipc_send(sub->port_ref, 2u, msg_sect); - mng.link_subscriptions++; - return; - } - default: - rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig); - } -exit: - rmsg.result_len = htonl(msg_sect[1].iov_len); - rmsg.retval = htonl(rv); - tipc_cfg_respond(msg_sect, 2u, orig); -} -#endif - #define MAX_STATS_INFO 2000 static struct sk_buff *tipc_show_stats(void) @@ -557,14 +424,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SHOW_PORTS: rep_tlv_buf = tipc_port_get_ports(); break; -#if 0 - case TIPC_CMD_SHOW_PORT_STATS: - rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_RESET_PORT_STATS: - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED); - break; -#endif case TIPC_CMD_SET_LOG_SIZE: rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); break; diff --git a/net/tipc/discover.c b/net/tipc/discover.c index f28d1ae93125..dbd79c67d7c0 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -46,16 +46,6 @@ #define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ #define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */ -#if 0 -#define GET_NODE_INFO 300 -#define GET_NODE_INFO_RESULT 301 -#define FORWARD_LINK_PROBE 302 -#define LINK_REQUEST_REJECTED 303 -#define LINK_REQUEST_ACCEPTED 304 -#define DROP_LINK_REQUEST 305 -#define CHECK_LINK_COUNT 306 -#endif - /* * TODO: Most of the inter-cluster setup stuff should be * rewritten, and be made conformant with specification. @@ -79,16 +69,6 @@ struct link_req { }; -#if 0 -int disc_create_link(const struct tipc_link_create *argv) -{ - /* - * Code for inter cluster link setup here - */ - return TIPC_OK; -} -#endif - /* * disc_lost_link(): A link has lost contact */ diff --git a/net/tipc/discover.h b/net/tipc/discover.h index c36eaeb7d5d0..9d064c3639bf 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h @@ -51,8 +51,5 @@ void tipc_disc_stop_link_req(struct link_req *req); void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); void tipc_disc_link_event(u32 addr, char *name, int up); -#if 0 -int disc_create_link(const struct tipc_link_create *argv); -#endif #endif diff --git a/net/tipc/link.c b/net/tipc/link.c index b8cf1e9d0b86..4be78ecf4a67 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -99,23 +99,6 @@ struct link_name { char if_peer[TIPC_MAX_IF_NAME]; }; -#if 0 - -/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -/** - * struct link_event - link up/down event notification - */ - -struct link_event { - u32 addr; - int up; - void (*fcn)(u32, char *, int); - char name[TIPC_MAX_LINK_NAME]; -}; - -#endif - static void link_handle_out_of_seq_msg(struct link *l_ptr, struct sk_buff *buf); static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); @@ -634,39 +617,9 @@ void tipc_link_stop(struct link *l_ptr) l_ptr->proto_msg_queue = NULL; } -#if 0 - /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -static void link_recv_event(struct link_event *ev) -{ - ev->fcn(ev->addr, ev->name, ev->up); - kfree(ev); -} - -static void link_send_event(void (*fcn)(u32 a, char *n, int up), - struct link *l_ptr, int up) -{ - struct link_event *ev; - - ev = kmalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) { - warn("Link event allocation failure\n"); - return; - } - ev->addr = l_ptr->addr; - ev->up = up; - ev->fcn = fcn; - memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME); - tipc_k_signal((Handler)link_recv_event, (unsigned long)ev); -} - -#else - #define link_send_event(fcn, l_ptr, up) do { } while (0) -#endif - void tipc_link_reset(struct link *l_ptr) { struct sk_buff *buf; @@ -690,10 +643,7 @@ void tipc_link_reset(struct link *l_ptr) tipc_node_link_down(l_ptr->owner, l_ptr); tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); -#if 0 - tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name); - dbg_link_dump(); -#endif + if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && l_ptr->owner->permit_changeover) { l_ptr->reset_checkpoint = checkpoint; @@ -3197,44 +3147,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s return buf; } -#if 0 -int link_control(const char *name, u32 op, u32 val) -{ - int res = -EINVAL; - struct link *l_ptr; - u32 bearer_id; - struct tipc_node * node; - u32 a; - - a = link_name2addr(name, &bearer_id); - read_lock_bh(&tipc_net_lock); - node = tipc_node_find(a); - if (node) { - tipc_node_lock(node); - l_ptr = node->links[bearer_id]; - if (l_ptr) { - if (op == TIPC_REMOVE_LINK) { - struct bearer *b_ptr = l_ptr->b_ptr; - spin_lock_bh(&b_ptr->publ.lock); - tipc_link_delete(l_ptr); - spin_unlock_bh(&b_ptr->publ.lock); - } - if (op == TIPC_CMD_BLOCK_LINK) { - tipc_link_reset(l_ptr); - l_ptr->blocked = 1; - } - if (op == TIPC_CMD_UNBLOCK_LINK) { - l_ptr->blocked = 0; - } - res = 0; - } - tipc_node_unlock(node); - } - read_unlock_bh(&tipc_net_lock); - return res; -} -#endif - /** * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination * @dest: network address of destination node @@ -3265,28 +3177,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) return res; } -#if 0 -static void link_dump_rec_queue(struct link *l_ptr) -{ - struct sk_buff *crs; - - if (!l_ptr->oldest_deferred_in) { - info("Reception queue empty\n"); - return; - } - info("Contents of Reception queue:\n"); - crs = l_ptr->oldest_deferred_in; - while (crs) { - if (crs->data == (void *)0x0000a3a3) { - info("buffer %x invalid\n", crs); - return; - } - msg_dbg(buf_msg(crs), "In rec queue:\n"); - crs = crs->next; - } -} -#endif - static void link_dump_send_queue(struct link *l_ptr) { if (l_ptr->next_out) { diff --git a/net/tipc/link.h b/net/tipc/link.h index 26151d30589d..4e944ef4a540 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -210,10 +210,6 @@ struct link { u32 msg_length_counts; u32 msg_lengths_total; u32 msg_length_profile[7]; -#if 0 - u32 sent_tunneled; - u32 recv_tunneled; -#endif } stats; struct print_buf print_buf; diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 9ca4b0689237..3a8de4334da1 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -1009,16 +1009,6 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, } } -#if 0 -void tipc_nametbl_print(struct print_buf *buf, const char *str) -{ - tipc_printf(buf, str); - read_lock_bh(&tipc_nametbl_lock); - nametbl_list(buf, 0, 0, 0, 0); - read_unlock_bh(&tipc_nametbl_lock); -} -#endif - #define MAX_NAME_TBL_QUERY 32768 struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) @@ -1051,13 +1041,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) return buf; } -#if 0 -void tipc_nametbl_dump(void) -{ - nametbl_list(TIPC_CONS, 0, 0, 0, 0); -} -#endif - int tipc_nametbl_init(void) { table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), diff --git a/net/tipc/net.c b/net/tipc/net.c index 7e05af47a196..1a621cfd6604 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -129,15 +129,6 @@ u32 tipc_net_select_router(u32 addr, u32 ref) return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref); } -#if 0 -u32 tipc_net_next_node(u32 a) -{ - if (tipc_net.zones[tipc_zone(a)]) - return tipc_zone_next_node(a); - return 0; -} -#endif - void tipc_net_remove_as_router(u32 router) { u32 z_num; diff --git a/net/tipc/node.c b/net/tipc/node.c index 7c49cd056df7..823e9abb7ef5 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -125,16 +125,6 @@ void tipc_node_delete(struct tipc_node *n_ptr) if (!n_ptr) return; -#if 0 - /* Not needed because links are already deleted via tipc_bearer_stop() */ - - u32 l_num; - - for (l_num = 0; l_num < MAX_BEARERS; l_num++) { - link_delete(n_ptr->links[l_num]); - } -#endif - dbg("node %x deleted\n", n_ptr->addr); kfree(n_ptr); } @@ -597,22 +587,6 @@ void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router) node_lost_contact(n_ptr); } -#if 0 -void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str) -{ - u32 i; - - tipc_printf(buf, "\n\n%s", str); - for (i = 0; i < MAX_BEARERS; i++) { - if (!n_ptr->links[i]) - continue; - tipc_printf(buf, "Links[%u]: %x, ", i, n_ptr->links[i]); - } - tipc_printf(buf, "Active links: [%x,%x]\n", - n_ptr->active_links[0], n_ptr->active_links[1]); -} -#endif - u32 tipc_available_nodes(const u32 domain) { struct tipc_node *n_ptr; diff --git a/net/tipc/port.c b/net/tipc/port.c index d760336f2ca8..5c4285b2d555 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -710,50 +710,6 @@ struct sk_buff *tipc_port_get_ports(void) return buf; } -#if 0 - -#define MAX_PORT_STATS 2000 - -struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space) -{ - u32 ref; - struct port *p_ptr; - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - struct print_buf pb; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - ref = *(u32 *)TLV_DATA(req_tlv_area); - ref = ntohl(ref); - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return cfg_reply_error_string("port not found"); - - buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS)); - if (!buf) { - tipc_port_unlock(p_ptr); - return NULL; - } - rep_tlv = (struct tlv_desc *)buf->data; - - tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS); - port_print(p_ptr, &pb, 1); - /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */ - tipc_port_unlock(p_ptr); - str_len = tipc_printbuf_validate(&pb); - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -#endif - void tipc_port_reinit(void) { struct port *p_ptr; -- cgit v1.2.3 From b3d6255388de0680a14f0907deb7b7f4fa0d25d5 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Tue, 12 Oct 2010 20:14:43 +0000 Subject: Phonet: 'connect' socket implementation for Pipe controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on suggestion by Rémi Denis-Courmont to implement 'connect' for Pipe controller logic, this patch implements 'connect' socket call for the Pipe controller logic. The patch does following:- - Removes setsockopts for PNPIPE_CREATE and PNPIPE_DESTROY - Adds setsockopt for setting the Pipe handle value - Implements connect socket call - Updates the Pipe controller logic User-space should now follow below sequence with Pipe controller:- -socket -bind -setsockopt for PNPIPE_PIPE_HANDLE -connect -setsockopt for PNPIPE_ENCAP_IP -setsockopt for PNPIPE_ENABLE GPRS/3G data has been tested working fine with this. Signed-off-by: Kumar Sanghvi Acked-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 3 +- include/net/phonet/pep.h | 4 +- net/phonet/pep.c | 300 ++++++++++++++++++----------------------------- net/phonet/socket.c | 99 ++++++++++++++++ 4 files changed, 215 insertions(+), 191 deletions(-) diff --git a/include/linux/phonet.h b/include/linux/phonet.h index e27cbf931740..26c8df786918 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -36,10 +36,9 @@ /* Socket options for SOL_PNPIPE level */ #define PNPIPE_ENCAP 1 #define PNPIPE_IFINDEX 2 -#define PNPIPE_CREATE 3 +#define PNPIPE_PIPE_HANDLE 3 #define PNPIPE_ENABLE 4 /* unused slot */ -#define PNPIPE_DESTROY 6 #define PNADDR_ANY 0 #define PNADDR_BROADCAST 0xFC diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h index def6cfa3f451..b60b28c99e87 100644 --- a/include/net/phonet/pep.h +++ b/include/net/phonet/pep.h @@ -46,8 +46,8 @@ struct pep_sock { u8 init_enable; /* auto-enable at creation */ u8 aligned; #ifdef CONFIG_PHONET_PIPECTRLR - u16 remote_pep; - u8 pipe_state; + u8 pipe_state; + struct sockaddr_pn remote_pep; #endif }; diff --git a/net/phonet/pep.c b/net/phonet/pep.c index f818f76d297d..9c903f9e5079 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -88,15 +88,6 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, const struct pnpipehdr *oph = pnp_hdr(oskb); struct pnpipehdr *ph; struct sk_buff *skb; -#ifdef CONFIG_PHONET_PIPECTRLR - const struct phonethdr *hdr = pn_hdr(oskb); - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = hdr->pn_sdev, - .spn_obj = hdr->pn_sobj, - }; -#endif skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); if (!skb) @@ -114,11 +105,7 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, ph->pipe_handle = oph->pipe_handle; ph->error_code = code; -#ifdef CONFIG_PHONET_PIPECTRLR - return pn_skb_send(sk, skb, &spn); -#else return pn_skb_send(sk, skb, &pipe_srv); -#endif } #define PAD 0x00 @@ -188,18 +175,13 @@ static int pipe_get_flow_info(struct sock *sk, struct sk_buff *skb, return 0; } -static int pipe_handler_send_req(struct sock *sk, u16 dobj, u8 utid, - u8 msg_id, u8 p_handle, gfp_t priority) +static int pipe_handler_send_req(struct sock *sk, u8 utid, + u8 msg_id, gfp_t priority) { int len; struct pnpipehdr *ph; struct sk_buff *skb; - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = pn_dev(dobj), - .spn_obj = pn_obj(dobj), - }; + struct pep_sock *pn = pep_sk(sk); static const u8 data[4] = { PAD, PAD, PAD, PAD, @@ -235,30 +217,25 @@ static int pipe_handler_send_req(struct sock *sk, u16 dobj, u8 utid, ph = pnp_hdr(skb); ph->utid = utid; ph->message_id = msg_id; - ph->pipe_handle = p_handle; + ph->pipe_handle = pn->pipe_handle; ph->error_code = PN_PIPE_NO_ERROR; - return pn_skb_send(sk, skb, &spn); + return pn_skb_send(sk, skb, &pn->remote_pep); } -static int pipe_handler_send_created_ind(struct sock *sk, u16 dobj, - u8 utid, u8 p_handle, u8 msg_id, u8 tx_fc, u8 rx_fc) +static int pipe_handler_send_created_ind(struct sock *sk, + u8 utid, u8 msg_id) { int err_code; struct pnpipehdr *ph; struct sk_buff *skb; - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = pn_dev(dobj), - .spn_obj = pn_obj(dobj), - }; + struct pep_sock *pn = pep_sk(sk); static u8 data[4] = { 0x03, 0x04, }; - data[2] = tx_fc; - data[3] = rx_fc; + data[2] = pn->tx_fc; + data[3] = pn->rx_fc; /* * actually, below is number of sub-blocks and not error code. @@ -282,24 +259,18 @@ static int pipe_handler_send_created_ind(struct sock *sk, u16 dobj, ph = pnp_hdr(skb); ph->utid = utid; ph->message_id = msg_id; - ph->pipe_handle = p_handle; + ph->pipe_handle = pn->pipe_handle; ph->error_code = err_code; - return pn_skb_send(sk, skb, &spn); + return pn_skb_send(sk, skb, &pn->remote_pep); } -static int pipe_handler_send_ind(struct sock *sk, u16 dobj, u8 utid, - u8 p_handle, u8 msg_id) +static int pipe_handler_send_ind(struct sock *sk, u8 utid, u8 msg_id) { int err_code; struct pnpipehdr *ph; struct sk_buff *skb; - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = pn_dev(dobj), - .spn_obj = pn_obj(dobj), - }; + struct pep_sock *pn = pep_sk(sk); /* * actually, below is a filler. @@ -321,10 +292,10 @@ static int pipe_handler_send_ind(struct sock *sk, u16 dobj, u8 utid, ph = pnp_hdr(skb); ph->utid = utid; ph->message_id = msg_id; - ph->pipe_handle = p_handle; + ph->pipe_handle = pn->pipe_handle; ph->error_code = err_code; - return pn_skb_send(sk, skb, &spn); + return pn_skb_send(sk, skb, &pn->remote_pep); } static int pipe_handler_enable_pipe(struct sock *sk, int enable) @@ -339,34 +310,7 @@ static int pipe_handler_enable_pipe(struct sock *sk, int enable) utid = PNS_PIPE_DISABLE_UTID; req = PNS_PEP_DISABLE_REQ; } - return pipe_handler_send_req(sk, pn->pn_sk.sobject, utid, req, - pn->pipe_handle, GFP_ATOMIC); -} - -static int pipe_handler_create_pipe(struct sock *sk, int pipe_handle, int cmd) -{ - int ret; - struct pep_sock *pn = pep_sk(sk); - - switch (cmd) { - case PNPIPE_CREATE: - ret = pipe_handler_send_req(sk, pn->pn_sk.sobject, - PNS_PEP_CONNECT_UTID, PNS_PEP_CONNECT_REQ, - pipe_handle, GFP_ATOMIC); - break; - - case PNPIPE_DESTROY: - ret = pipe_handler_send_req(sk, pn->remote_pep, - PNS_PEP_DISCONNECT_UTID, - PNS_PEP_DISCONNECT_REQ, - pn->pipe_handle, GFP_ATOMIC); - break; - - default: - ret = -EINVAL; - } - - return ret; + return pipe_handler_send_req(sk, utid, req, GFP_ATOMIC); } #endif @@ -434,14 +378,6 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; struct sk_buff *skb; -#ifdef CONFIG_PHONET_PIPECTRLR - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = pn_dev(pn->remote_pep), - .spn_obj = pn_obj(pn->remote_pep), - }; -#endif skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority); if (!skb) @@ -462,7 +398,7 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) ph->data[4] = status; #ifdef CONFIG_PHONET_PIPECTRLR - return pn_skb_send(sk, skb, &spn); + return pn_skb_send(sk, skb, &pn->remote_pep); #else return pn_skb_send(sk, skb, &pipe_srv); #endif @@ -582,12 +518,6 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) struct pnpipehdr *hdr = pnp_hdr(skb); struct sk_buff_head *queue; int err = 0; -#ifdef CONFIG_PHONET_PIPECTRLR - struct phonethdr *ph = pn_hdr(skb); - static u8 host_pref_rx_fc[3], host_req_tx_fc[3]; - u8 remote_pref_rx_fc[3], remote_req_tx_fc[3]; - u8 negotiated_rx_fc, negotiated_tx_fc; -#endif BUG_ON(sk->sk_state == TCP_CLOSE_WAIT); @@ -596,40 +526,6 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE); break; -#ifdef CONFIG_PHONET_PIPECTRLR - case PNS_PEP_CONNECT_RESP: - if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && - (ph->pn_sobj == pn_obj(pn->remote_pep))) { - pipe_get_flow_info(sk, skb, remote_pref_rx_fc, - remote_req_tx_fc); - - negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc, - host_pref_rx_fc, - sizeof(host_pref_rx_fc)); - negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc, - remote_pref_rx_fc, - sizeof(host_pref_rx_fc)); - - pn->pipe_state = PIPE_DISABLED; - pipe_handler_send_created_ind(sk, pn->remote_pep, - PNS_PIPE_CREATED_IND_UTID, - pn->pipe_handle, PNS_PIPE_CREATED_IND, - negotiated_tx_fc, negotiated_rx_fc); - pipe_handler_send_created_ind(sk, pn->pn_sk.sobject, - PNS_PIPE_CREATED_IND_UTID, - pn->pipe_handle, PNS_PIPE_CREATED_IND, - negotiated_tx_fc, negotiated_rx_fc); - } else { - pipe_handler_send_req(sk, pn->remote_pep, - PNS_PEP_CONNECT_UTID, - PNS_PEP_CONNECT_REQ, pn->pipe_handle, - GFP_ATOMIC); - pipe_get_flow_info(sk, skb, host_pref_rx_fc, - host_req_tx_fc); - } - break; -#endif - case PNS_PEP_DISCONNECT_REQ: pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); sk->sk_state = TCP_CLOSE_WAIT; @@ -640,10 +536,7 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) #ifdef CONFIG_PHONET_PIPECTRLR case PNS_PEP_DISCONNECT_RESP: pn->pipe_state = PIPE_IDLE; - pipe_handler_send_req(sk, pn->pn_sk.sobject, - PNS_PEP_DISCONNECT_UTID, - PNS_PEP_DISCONNECT_REQ, pn->pipe_handle, - GFP_KERNEL); + sk->sk_state = TCP_CLOSE; break; #endif @@ -654,21 +547,18 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) #ifdef CONFIG_PHONET_PIPECTRLR case PNS_PEP_ENABLE_RESP: - if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && - (ph->pn_sobj == pn_obj(pn->remote_pep))) { - pn->pipe_state = PIPE_ENABLED; - pipe_handler_send_ind(sk, pn->remote_pep, - PNS_PIPE_ENABLED_IND_UTID, - pn->pipe_handle, PNS_PIPE_ENABLED_IND); - pipe_handler_send_ind(sk, pn->pn_sk.sobject, - PNS_PIPE_ENABLED_IND_UTID, - pn->pipe_handle, PNS_PIPE_ENABLED_IND); - } else - pipe_handler_send_req(sk, pn->remote_pep, - PNS_PIPE_ENABLE_UTID, - PNS_PEP_ENABLE_REQ, pn->pipe_handle, - GFP_KERNEL); + pn->pipe_state = PIPE_ENABLED; + pipe_handler_send_ind(sk, PNS_PIPE_ENABLED_IND_UTID, + PNS_PIPE_ENABLED_IND); + if (!pn_flow_safe(pn->tx_fc)) { + atomic_set(&pn->tx_credits, 1); + sk->sk_write_space(sk); + } + if (sk->sk_state == TCP_ESTABLISHED) + break; /* Nothing to do */ + sk->sk_state = TCP_ESTABLISHED; + pipe_grant_credits(sk); break; #endif @@ -692,22 +582,12 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) #ifdef CONFIG_PHONET_PIPECTRLR case PNS_PEP_DISABLE_RESP: - if ((ph->pn_sdev == pn_dev(pn->remote_pep)) && - (ph->pn_sobj == pn_obj(pn->remote_pep))) { - pn->pipe_state = PIPE_DISABLED; - pipe_handler_send_ind(sk, pn->remote_pep, - PNS_PIPE_DISABLED_IND_UTID, - pn->pipe_handle, - PNS_PIPE_DISABLED_IND); - pipe_handler_send_ind(sk, pn->pn_sk.sobject, - PNS_PIPE_DISABLED_IND_UTID, - pn->pipe_handle, - PNS_PIPE_DISABLED_IND); - } else - pipe_handler_send_req(sk, pn->remote_pep, - PNS_PIPE_DISABLE_UTID, - PNS_PEP_DISABLE_REQ, pn->pipe_handle, - GFP_KERNEL); + pn->pipe_state = PIPE_DISABLED; + atomic_set(&pn->tx_credits, 0); + pipe_handler_send_ind(sk, PNS_PIPE_DISABLED_IND_UTID, + PNS_PIPE_DISABLED_IND); + sk->sk_state = TCP_SYN_RECV; + pn->rx_credits = 0; break; #endif @@ -802,6 +682,42 @@ static void pipe_destruct(struct sock *sk) skb_queue_purge(&pn->ctrlreq_queue); } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb) +{ + struct pep_sock *pn = pep_sk(sk); + u8 host_pref_rx_fc[3] = {3, 2, 1}, host_req_tx_fc[3] = {3, 2, 1}; + u8 remote_pref_rx_fc[3], remote_req_tx_fc[3]; + u8 negotiated_rx_fc, negotiated_tx_fc; + int ret; + + pipe_get_flow_info(sk, skb, remote_pref_rx_fc, + remote_req_tx_fc); + negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc, + host_pref_rx_fc, + sizeof(host_pref_rx_fc)); + negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc, + remote_pref_rx_fc, + sizeof(host_pref_rx_fc)); + + pn->pipe_state = PIPE_DISABLED; + sk->sk_state = TCP_SYN_RECV; + sk->sk_backlog_rcv = pipe_do_rcv; + sk->sk_destruct = pipe_destruct; + pn->rx_credits = 0; + pn->rx_fc = negotiated_rx_fc; + pn->tx_fc = negotiated_tx_fc; + sk->sk_state_change(sk); + + ret = pipe_handler_send_created_ind(sk, + PNS_PIPE_CREATED_IND_UTID, + PNS_PIPE_CREATED_IND + ); + + return ret; +} +#endif + static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) { struct sock *newsk; @@ -884,9 +800,6 @@ static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL; newpn->init_enable = enabled; newpn->aligned = aligned; -#ifdef CONFIG_PHONET_PIPECTRLR - newpn->remote_pep = pn->remote_pep; -#endif BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue)); skb_queue_head(&newsk->sk_receive_queue, skb); @@ -968,6 +881,12 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb) err = pep_connreq_rcv(sk, skb); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_CONNECT_RESP: + err = pep_connresp_rcv(sk, skb); + break; +#endif + case PNS_PEP_DISCONNECT_REQ: pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; @@ -1032,6 +951,18 @@ static void pep_sock_close(struct sock *sk, long timeout) /* Forcefully remove dangling Phonet pipe */ pipe_do_remove(sk); +#ifdef CONFIG_PHONET_PIPECTRLR + if (pn->pipe_state != PIPE_IDLE) { + /* send pep disconnect request */ + pipe_handler_send_req(sk, + PNS_PEP_DISCONNECT_UTID, PNS_PEP_DISCONNECT_REQ, + GFP_KERNEL); + + pn->pipe_state = PIPE_IDLE; + sk->sk_state = TCP_CLOSE; + } +#endif + ifindex = pn->ifindex; pn->ifindex = 0; release_sock(sk); @@ -1108,6 +1039,20 @@ out: return newsk; } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len) +{ + struct pep_sock *pn = pep_sk(sk); + struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; + + memcpy(&pn->remote_pep, spn, sizeof(struct sockaddr_pn)); + + return pipe_handler_send_req(sk, + PNS_PEP_CONNECT_UTID, PNS_PEP_CONNECT_REQ, + GFP_ATOMIC); +} +#endif + static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) { struct pep_sock *pn = pep_sk(sk); @@ -1149,10 +1094,6 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, { struct pep_sock *pn = pep_sk(sk); int val = 0, err = 0; -#ifdef CONFIG_PHONET_PIPECTRLR - int remote_pep; - int pipe_handle; -#endif if (level != SOL_PNPIPE) return -ENOPROTOOPT; @@ -1164,28 +1105,15 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, lock_sock(sk); switch (optname) { #ifdef CONFIG_PHONET_PIPECTRLR - case PNPIPE_CREATE: + case PNPIPE_PIPE_HANDLE: if (val) { if (pn->pipe_state > PIPE_IDLE) { err = -EFAULT; break; } - remote_pep = val & 0xFFFF; - pipe_handle = (val >> 16) & 0xFF; - pn->remote_pep = remote_pep; - err = pipe_handler_create_pipe(sk, pipe_handle, - PNPIPE_CREATE); - break; - } - - case PNPIPE_DESTROY: - if (pn->pipe_state < PIPE_DISABLED) { - err = -EFAULT; + pn->pipe_handle = val; break; } - - err = pipe_handler_create_pipe(sk, 0x0, PNPIPE_DESTROY); - break; #endif case PNPIPE_ENCAP: @@ -1278,14 +1206,6 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; int err; -#ifdef CONFIG_PHONET_PIPECTRLR - struct sockaddr_pn spn = { - .spn_family = AF_PHONET, - .spn_resource = 0xD9, - .spn_dev = pn_dev(pn->remote_pep), - .spn_obj = pn_obj(pn->remote_pep), - }; -#endif if (pn_flow_safe(pn->tx_fc) && !atomic_add_unless(&pn->tx_credits, -1, 0)) { @@ -1304,7 +1224,7 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) ph->message_id = PNS_PIPE_DATA; ph->pipe_handle = pn->pipe_handle; #ifdef CONFIG_PHONET_PIPECTRLR - err = pn_skb_send(sk, skb, &spn); + err = pn_skb_send(sk, skb, &pn->remote_pep); #else err = pn_skb_send(sk, skb, &pipe_srv); #endif @@ -1504,6 +1424,8 @@ static void pep_sock_unhash(struct sock *sk) struct sock *skparent = NULL; lock_sock(sk); + +#ifndef CONFIG_PHONET_PIPECTRLR if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) { skparent = pn->listener; release_sock(sk); @@ -1513,6 +1435,7 @@ static void pep_sock_unhash(struct sock *sk) sk_del_node_init(sk); sk = skparent; } +#endif /* Unhash a listening sock only when it is closed * and all of its active connected pipes are closed. */ if (hlist_empty(&pn->hlist)) @@ -1526,6 +1449,9 @@ static void pep_sock_unhash(struct sock *sk) static struct proto pep_proto = { .close = pep_sock_close, .accept = pep_sock_accept, +#ifdef CONFIG_PHONET_PIPECTRLR + .connect = pep_sock_connect, +#endif .ioctl = pep_ioctl, .init = pep_init, .setsockopt = pep_setsockopt, diff --git a/net/phonet/socket.c b/net/phonet/socket.c index aca8fba099e9..25f746d20c1f 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -225,6 +225,101 @@ static int pn_socket_autobind(struct socket *sock) return 0; /* socket was already bound */ } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pn_socket_connect(struct socket *sock, struct sockaddr *addr, + int len, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; + long timeo; + int err; + + if (len < sizeof(struct sockaddr_pn)) + return -EINVAL; + if (spn->spn_family != AF_PHONET) + return -EAFNOSUPPORT; + + lock_sock(sk); + + switch (sock->state) { + case SS_UNCONNECTED: + sk->sk_state = TCP_CLOSE; + break; + case SS_CONNECTING: + switch (sk->sk_state) { + case TCP_SYN_RECV: + sock->state = SS_CONNECTED; + err = -EISCONN; + goto out; + case TCP_CLOSE: + err = -EALREADY; + if (flags & O_NONBLOCK) + goto out; + goto wait_connect; + } + break; + case SS_CONNECTED: + switch (sk->sk_state) { + case TCP_SYN_RECV: + err = -EISCONN; + goto out; + case TCP_CLOSE: + sock->state = SS_UNCONNECTED; + break; + } + break; + case SS_DISCONNECTING: + case SS_FREE: + break; + } + sk->sk_state = TCP_CLOSE; + sk_stream_kill_queues(sk); + + sock->state = SS_CONNECTING; + err = sk->sk_prot->connect(sk, addr, len); + if (err < 0) { + sock->state = SS_UNCONNECTED; + sk->sk_state = TCP_CLOSE; + goto out; + } + + err = -EINPROGRESS; +wait_connect: + if (sk->sk_state != TCP_SYN_RECV && (flags & O_NONBLOCK)) + goto out; + + timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); + release_sock(sk); + + err = -ERESTARTSYS; + timeo = wait_event_interruptible_timeout(*sk_sleep(sk), + sk->sk_state != TCP_CLOSE, + timeo); + + lock_sock(sk); + if (timeo < 0) + goto out; /* -ERESTARTSYS */ + + err = -ETIMEDOUT; + if (timeo == 0 && sk->sk_state != TCP_SYN_RECV) + goto out; + + if (sk->sk_state != TCP_SYN_RECV) { + sock->state = SS_UNCONNECTED; + err = sock_error(sk); + if (!err) + err = -ECONNREFUSED; + goto out; + } + sock->state = SS_CONNECTED; + err = 0; + +out: + release_sock(sk); + return err; +} +#endif + static int pn_socket_accept(struct socket *sock, struct socket *newsock, int flags) { @@ -393,7 +488,11 @@ const struct proto_ops phonet_stream_ops = { .owner = THIS_MODULE, .release = pn_socket_release, .bind = pn_socket_bind, +#ifdef CONFIG_PHONET_PIPECTRLR + .connect = pn_socket_connect, +#else .connect = sock_no_connect, +#endif .socketpair = sock_no_socketpair, .accept = pn_socket_accept, .getname = pn_socket_getname, -- cgit v1.2.3 From f20ce779bb31a90985b0daea2bf0aaf009d21b81 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Tue, 12 Oct 2010 20:17:25 +0000 Subject: Documentation: Update Phonet doc for Pipe controller changes Updates to Phonet doc for Pipe controller 'connect' socket implementation and changes related to socket options. Signed-off-by: Kumar Sanghvi Signed-off-by: David S. Miller --- Documentation/networking/phonet.txt | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt index 2d9bc2b711fc..24ad2adba6e5 100644 --- a/Documentation/networking/phonet.txt +++ b/Documentation/networking/phonet.txt @@ -199,33 +199,29 @@ between itself and a remote pipe-end point (e.g. modem). The implementation adds socket options at SOL_PNPIPE level: - PNPIPE_CREATE - It accepts an integer argument where-in - lower order 16 bits: pn_dev and pn_port pair for remote pep. - higher order 16 bits: 8 bit pipe-handle - - It sends a PNS_PEP_CONNECT_REQ on sequenced socket itself. On getting - PNS_PEP_CONNECT_RESP, it sends PNS_PEP_CONNECT_REQ to remote pep. On - getting response from remote pep, it selects the best possible Flow - control mechanism supported by remote-pep (modem) and then it sends - PNS_PEP_CREATED_IND to the sequenced socket and to the remote pep. - - It then updates the pipe state associated with the sequenced socket to - be PIPE_DISABLED. + PNPIPE_PIPE_HANDLE + It accepts an integer argument for setting value of pipe handle. PNPIPE_ENABLE accepts one integer value (int). If set to zero, the pipe is disabled. If the value is non-zero, the pipe is enabled. If the pipe is not (yet) connected, ENOTCONN is error is returned. - PNPIPE_DESTROY - This will send out PNS_PEP_DISCONNECT_REQ on the sequenced socket and - the remote pep. - It will also update the pipe state associated with the sequenced socket - to PIPE_IDLE +The implementation also adds socket 'connect'. On calling the 'connect', pipe +will be created between the source socket and the destination, and the pipe +state will be set to PIPE_DISABLED. After a pipe has been created and enabled successfully, the Pipe data can be exchanged between the host-pep and remote-pep (modem). +User-space would typically follow below sequence with Pipe controller:- +-socket +-bind +-setsockopt for PNPIPE_PIPE_HANDLE +-connect +-setsockopt for PNPIPE_ENCAP_IP +-setsockopt for PNPIPE_ENABLE + + Authors ------- -- cgit v1.2.3 From de05ead8f8649788603afc470eb1c2ea2b8b1655 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 23 Sep 2010 15:24:22 -0700 Subject: iwlgn: need longer tx queue stuck timer for coex devices For BT/WiFi combo devices, need longer tx stuck queue timer, so those devices won't reload firmware too often. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 38 ++++++++++++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-core.c | 11 ++++------ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 4810258aefd9..3eaea6fcdaa7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -509,6 +509,28 @@ static struct iwl_base_params iwl6050_base_params = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, }; +static struct iwl_base_params iwl6000_coex_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, + .max_event_log_size = 512, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, +}; static struct iwl_ht_params iwl6000_ht_params = { .ht_greenfield_support = true, @@ -587,7 +609,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -608,7 +630,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -628,7 +650,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -649,7 +671,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -669,7 +691,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -690,7 +712,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, @@ -829,7 +851,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, @@ -849,7 +871,7 @@ struct iwl_cfg iwl130_bg_cfg = { .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .base_params = &iwl6000_base_params, + .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b3efbe02df67..89b1827054e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2483,13 +2483,10 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) "queue %d, not read %d time\n", q->id, q->repeat_same_read_ptr); - if (priv->cfg->bt_params && - !priv->cfg->bt_params->advanced_bt_coexist) { - mod_timer(&priv->monitor_recover, - jiffies + msecs_to_jiffies( - IWL_ONE_HUNDRED_MSECS)); - return 1; - } + mod_timer(&priv->monitor_recover, + jiffies + msecs_to_jiffies( + IWL_ONE_HUNDRED_MSECS)); + return 1; } } else { q->last_read_ptr = q->read_ptr; -- cgit v1.2.3 From 085fbca29d7b4574c4e42189ee5789004e4beff7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 05:47:23 -0700 Subject: iwlwifi: allow probe-after-rx on 2.4 GHz There are two passive 2.4 GHz channels: 12 and 13. If you have a hidden SSID on those, you will not be able to connect to it because we don't send out probe requests there. We can allow this by using the firmware's probe-after-rx functionality on those channels as well. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=16462 Reported-by: Daniel J Blueman Tested-by: Daniel J Blueman Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 40 ++++++++++++++--------------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 16 ++++++------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c1a389883af0..b555edd53354 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1447,35 +1447,35 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; - scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; break; case IEEE80211_BAND_5GHZ: rate = IWL_RATE_6M_PLCP; - /* - * If active scanning is requested but a certain channel is - * marked passive, we can do active scanning if we detect - * transmissions. - * - * There is an issue with some firmware versions that triggers - * a sysassert on a "good CRC threshold" of zero (== disabled), - * on a radar channel even though this means that we should NOT - * send probes. - * - * The "good CRC threshold" is the number of frames that we - * need to receive during our dwell time on a channel before - * sending out probes -- setting this to a huge value will - * mean we never reach it, but at the same time work around - * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER - * here instead of IWL_GOOD_CRC_TH_DISABLED. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_NEVER; break; default: IWL_WARN(priv, "Invalid scan band\n"); return -EIO; } + /* + * If active scanning is requested but a certain channel is + * marked passive, we can do active scanning if we detect + * transmissions. + * + * There is an issue with some firmware versions that triggers + * a sysassert on a "good CRC threshold" of zero (== disabled), + * on a radar channel even though this means that we should NOT + * send probes. + * + * The "good CRC threshold" is the number of frames that we + * need to receive during our dwell time on a channel before + * sending out probes -- setting this to a huge value will + * mean we never reach it, but at the same time work around + * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER + * here instead of IWL_GOOD_CRC_TH_DISABLED. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_NEVER; + band = priv->scan_band; if (priv->cfg->scan_rx_antennas[band]) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 980c6096620a..3ee3e55fa546 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2938,18 +2938,10 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; scan->tx_cmd.rate = IWL_RATE_1M_PLCP; - scan->good_CRC_th = 0; band = IEEE80211_BAND_2GHZ; break; case IEEE80211_BAND_5GHZ: scan->tx_cmd.rate = IWL_RATE_6M_PLCP; - /* - * If active scaning is requested but a certain channel - * is marked passive, we can do active scanning if we - * detect transmissions. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_DISABLED; band = IEEE80211_BAND_5GHZ; break; default: @@ -2957,6 +2949,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) return -EIO; } + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_DISABLED; + if (!priv->is_internal_short_scan) { scan->tx_cmd.len = cpu_to_le16( iwl_fill_probe_req(priv, -- cgit v1.2.3 From 12e934dc602fafba946b33587c38077ebceb3698 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 05:50:06 -0700 Subject: iwlwifi: rename ibss_beacon variable Since we're also going to support AP (GO) mode, the variable isn't used for just IBSS beacons any more -- rename it to not mislead readers. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 26 +++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-core.c | 16 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 26 +++++++++++++------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6771c404fa73..0cc090b485a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -317,15 +317,15 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, int left) { - if (!priv->ibss_beacon) + if (!priv->beacon_skb) return 0; - if (priv->ibss_beacon->len > left) + if (priv->beacon_skb->len > left) return 0; - memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - return priv->ibss_beacon->len; + return priv->beacon_skb->len; } /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ @@ -653,10 +653,10 @@ static void iwl_bg_beacon_update(struct work_struct *work) } /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = beacon; + priv->beacon_skb = beacon; iwl_send_beacon_cmd(priv); out: @@ -2993,9 +2993,9 @@ static void __iwl_down(struct iwl_priv *priv) exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = NULL; + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; /* clear out any free frames */ iwl_clear_free_frames(priv); @@ -4131,7 +4131,7 @@ static int iwl_init_drv(struct iwl_priv *priv) { int ret; - priv->ibss_beacon = NULL; + priv->beacon_skb = NULL; spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -4645,8 +4645,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_free_isr_ict(priv); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); ieee80211_free_hw(priv->hw); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 89b1827054e5..09a4d1700952 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1552,10 +1552,10 @@ static void iwlcore_beacon_update(struct ieee80211_hw *hw, spin_lock_irqsave(&priv->lock, flags); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = skb; + priv->beacon_skb = skb; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; priv->timestamp = le64_to_cpu(timestamp); @@ -1610,8 +1610,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = ieee80211_beacon_get(hw, vif); + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(hw, vif); } if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) @@ -2060,10 +2060,10 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_lock_irqsave(&priv->lock, flags); /* new association get rid of ibss beacon skb */ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = NULL; + priv->beacon_skb = NULL; priv->timestamp = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index de43e1350ed1..70e07fa48405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1383,8 +1383,6 @@ struct iwl_priv { enum nl80211_iftype iw_mode; - struct sk_buff *ibss_beacon; - /* Last Rx'd beacon timestamp */ u64 timestamp; @@ -1496,8 +1494,10 @@ struct iwl_priv { struct work_struct scan_completed; struct work_struct rx_replenish; struct work_struct abort_scan; + struct work_struct beacon_update; struct iwl_rxon_context *beacon_ctx; + struct sk_buff *beacon_skb; struct work_struct tt_work; struct work_struct ct_enter; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3ee3e55fa546..8f8c4b73f8b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -317,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, int left) { - if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon) + if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) return 0; - if (priv->ibss_beacon->len > left) + if (priv->beacon_skb->len > left) return 0; - memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - return priv->ibss_beacon->len; + return priv->beacon_skb->len; } static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) @@ -813,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) mutex_lock(&priv->mutex); /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = beacon; + priv->beacon_skb = beacon; mutex_unlock(&priv->mutex); iwl3945_send_beacon_cmd(priv); @@ -2642,9 +2642,9 @@ static void __iwl3945_down(struct iwl_priv *priv) exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = NULL; + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; /* clear out any free frames */ iwl3945_clear_free_frames(priv); @@ -3848,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; priv->retry_rate = 1; - priv->ibss_beacon = NULL; + priv->beacon_skb = NULL; spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -4256,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) iwl_free_channel_map(priv); iwlcore_free_geos(priv); kfree(priv->scan_cmd); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); ieee80211_free_hw(priv->hw); } -- cgit v1.2.3 From 77834543a5278b55df6c2784cd5ed59970be3c44 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Oct 2010 05:50:36 -0700 Subject: iwlwifi: clean up some beacon handling There's no need to check for NULL before calling dev_kfree_skb() since it is valid to call it on NULL -- it becomes a no-op. There's also no need to initialise the beacon_skb variable to NULL just after the memory it is in has been kzalloc'ed. Some minor whitespace cleanups, and a lock assertion in a function that needs the mutex (to access the beacon_skb var) complete the patch. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0cc090b485a9..7079efbe34eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -314,9 +314,11 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) } static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - int left) + struct ieee80211_hdr *hdr, + int left) { + lockdep_assert_held(&priv->mutex); + if (!priv->beacon_skb) return 0; @@ -330,8 +332,8 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ static void iwl_set_beacon_tim(struct iwl_priv *priv, - struct iwl_tx_beacon_cmd *tx_beacon_cmd, - u8 *beacon, u32 frame_size) + struct iwl_tx_beacon_cmd *tx_beacon_cmd, + u8 *beacon, u32 frame_size) { u16 tim_idx; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; @@ -393,7 +395,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, /* Set up TX beacon command fields */ iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, - frame_size); + frame_size); /* Set up packet rate and flags */ rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); @@ -648,13 +650,12 @@ static void iwl_bg_beacon_update(struct work_struct *work) /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); if (!beacon) { - IWL_ERR(priv, "update beacon failed\n"); + IWL_ERR(priv, "update beacon failed -- keeping old\n"); goto out; } /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); + dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = beacon; @@ -2993,8 +2994,7 @@ static void __iwl_down(struct iwl_priv *priv) exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); + dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = NULL; /* clear out any free frames */ @@ -4131,8 +4131,6 @@ static int iwl_init_drv(struct iwl_priv *priv) { int ret; - priv->beacon_skb = NULL; - spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -4645,8 +4643,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_free_isr_ict(priv); - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); + dev_kfree_skb(priv->beacon_skb); ieee80211_free_hw(priv->hw); } -- cgit v1.2.3 From 34f5a70c08530bb0b4724991a712a0ef6bbec39a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Oct 2010 13:46:11 -0700 Subject: iwlagn: 6050 ops should be used; For 6050 series of devices, 6050 ops should be used; One of the 6050 config still use 6000 ops, fix it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 3eaea6fcdaa7..11e6532fc573 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -780,7 +780,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, - .ops = &iwl6000_ops, + .ops = &iwl6050_ops, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, .mod_params = &iwlagn_mod_params, -- cgit v1.2.3 From dacefedb34e538e9934556ffe5eaad177e7a9718 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 04:02:03 -0700 Subject: iwlwifi: rewrite RXON checks The RXON checking is a bit magical, and prints out too much information if something goes wrong. Make it less magical and print out only the items that were actually wrong. Also remove the comment about removing it -- the driver is constantly changing so these checks are useful. Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-core.c | 102 ++++++++++++++++---------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 09a4d1700952..ecf5c9b90089 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -510,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); -/** - * iwl_check_rxon_cmd - validate RXON structure is valid - * - * NOTE: This is really only useful during development and can eventually - * be #ifdef'd out once the driver is stable and folks aren't actively - * making changes - */ +/* validate RXON structure is valid */ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - int error = 0; - int counter = 1; struct iwl_rxon_cmd *rxon = &ctx->staging; + bool error = false; if (rxon->flags & RXON_FLG_BAND_24G_MSK) { - error |= le32_to_cpu(rxon->flags & - (RXON_FLG_TGJ_NARROW_BAND_MSK | - RXON_FLG_RADAR_DETECT_MSK)); - if (error) - IWL_WARN(priv, "check 24G fields %d | %d\n", - counter++, error); + if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { + IWL_WARN(priv, "check 2.4G: wrong narrow\n"); + error = true; + } + if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { + IWL_WARN(priv, "check 2.4G: wrong radar\n"); + error = true; + } } else { - error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? - 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); - if (error) - IWL_WARN(priv, "check 52 fields %d | %d\n", - counter++, error); - error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); - if (error) - IWL_WARN(priv, "check 52 CCK %d | %d\n", - counter++, error); - } - error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; - if (error) - IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error); + if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "check 5.2G: not short slot!\n"); + error = true; + } + if (rxon->flags & RXON_FLG_CCK_MSK) { + IWL_WARN(priv, "check 5.2G: CCK!\n"); + error = true; + } + } + if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { + IWL_WARN(priv, "mac/bssid mcast!\n"); + error = true; + } /* make sure basic rates 6Mbps and 1Mbps are supported */ - error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && - ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); - if (error) - IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error); + if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && + (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { + IWL_WARN(priv, "neither 1 nor 6 are basic\n"); + error = true; + } - error |= (le16_to_cpu(rxon->assoc_id) > 2007); - if (error) - IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error); + if (le16_to_cpu(rxon->assoc_id) > 2007) { + IWL_WARN(priv, "aid > 2007\n"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) - == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); - if (error) - IWL_WARN(priv, "check CCK and short slot %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "CCK and short slot\n"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) - == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); - if (error) - IWL_WARN(priv, "check CCK & auto detect %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { + IWL_WARN(priv, "CCK and auto detect"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | - RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); - if (error) - IWL_WARN(priv, "check TGG and auto detect %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | + RXON_FLG_TGG_PROTECT_MSK)) == + RXON_FLG_TGG_PROTECT_MSK) { + IWL_WARN(priv, "TGg but no auto-detect\n"); + error = true; + } if (error) IWL_WARN(priv, "Tuning to channel %d\n", le16_to_cpu(rxon->channel)); if (error) { - IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n"); - return -1; + IWL_ERR(priv, "Invalid RXON\n"); + return -EINVAL; } return 0; } -- cgit v1.2.3 From 657e11a47dede79cae1d2f72084f6f7303aec725 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 03:52:35 -0700 Subject: iwlwifi: blink LED in IBSS mode We recently found that contrary to expectations, the LED is not blinking in IBSS mode. Fix this. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ecf5c9b90089..25fb3912342c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1727,6 +1727,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + iwl_led_associate(priv); iwlcore_config_ap(priv, vif); } else iwl_set_no_assoc(priv, vif); -- cgit v1.2.3 From 40bbfd4c1b336b8841bef9933b6e09252ace56b8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Oct 2010 04:00:33 -0700 Subject: iwlagn: check beacon frame size When the beacon_skb is NULL, we might still attempt to use it in this code path (if we ever get here) -- make the code a bit more defensive and check the return value of iwl_fill_beacon_frame() against zero. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7079efbe34eb..c2636a7ab9ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -385,6 +385,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, sizeof(frame->u) - sizeof(*tx_beacon_cmd)); if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) return 0; + if (!frame_size) + return 0; /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); -- cgit v1.2.3 From 3be63ff0ae196b371728ba8fc8aca12eafcae218 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Oct 2010 16:05:19 -0700 Subject: iwlwifi: move agn only eeprom functions to separate file Some of the functions in iwl-eeprom.c file are for agn devices only, Those functions do not have to be part of iwlcore.ko, so move those to iwl-agn-eeprom.c file. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 454 ++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 6 + drivers/net/wireless/iwlwifi/iwl-eeprom.c | 374 +-------------------- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 7 +- 5 files changed, 476 insertions(+), 367 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index b4b24b67892c..63edbe2e557f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o -iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o +iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c new file mode 100644 index 000000000000..a650baba0809 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -0,0 +1,454 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" +#include "iwl-agn.h" +#include "iwl-io.h" + +/************************** EEPROM BANDS **************************** + * + * The iwl_eeprom_band definitions below provide the mapping from the + * EEPROM contents to the specific channel number supported for each + * band. + * + * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 + * definition below maps to physical channel 42 in the 5.2GHz spectrum. + * The specific geography and calibration information for that channel + * is contained in the eeprom map itself. + * + * During init, we copy the eeprom information and channel map + * information into priv->channel_info_24/52 and priv->channel_map_24/52 + * + * channel_map_24/52 provides the index in the channel_info array for a + * given channel. We have to have two separate maps as there is channel + * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and + * band_2 + * + * A value of 0xff stored in the channel_map indicates that the channel + * is not supported by the hardware at all. + * + * A value of 0xfe in the channel_map indicates that the channel is not + * valid for Tx with the current hardware. This means that + * while the system can tune and receive on a given channel, it may not + * be able to associate or transmit any frames on that + * channel. There is no corresponding channel information for that + * entry. + * + *********************************************************************/ + +/** + * struct iwl_txpwr_section: eeprom section information + * @offset: indirect address into eeprom image + * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section + * @band: band type for the section + * @is_common - true: common section, false: channel section + * @is_cck - true: cck section, false: not cck section + * @is_ht_40 - true: all channel in the section are HT40 channel, + * false: legacy or HT 20 MHz + * ignore if it is common section + * @iwl_eeprom_section_channel: channel array in the section, + * ignore if common section + */ +struct iwl_txpwr_section { + u32 offset; + u8 count; + enum ieee80211_band band; + bool is_common; + bool is_cck; + bool is_ht40; + u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; +}; + +/** + * section 1 - 3 are regulatory tx power apply to all channels based on + * modulation: CCK, OFDM + * Band: 2.4GHz, 5.2GHz + * section 4 - 10 are regulatory tx power apply to specified channels + * For example: + * 1L - Channel 1 Legacy + * 1HT - Channel 1 HT + * (1,+1) - Channel 1 HT40 "_above_" + * + * Section 1: all CCK channels + * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels + * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels + * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT + * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) + * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT + * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) + * Section 8: 2.4 GHz channel: 13L, 13HT + * Section 9: 2.4 GHz channel: 140L, 140HT + * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) + * + */ +static const struct iwl_txpwr_section enhinfo[] = { + { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, + { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, + { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, + { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, + false, false, false, + {1, 1, 2, 2, 10, 10, 11, 11 } }, + { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, + false, false, true, + { 1, 2, 6, 7, 9 } }, + { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, + false, false, false, + { 36, 64, 100, 36, 64, 100 } }, + { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, + false, false, true, + { 36, 60, 100 } }, + { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, + false, false, false, + { 13, 13 } }, + { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, + false, false, false, + { 140, 140 } }, + { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, + false, false, true, + { 132, 44 } }, +}; + +/****************************************************************************** + * + * EEPROM related functions + * +******************************************************************************/ + +/* + * The device's EEPROM semaphore prevents conflicts between driver and uCode + * when accessing the EEPROM; each access is a series of pulses to/from the + * EEPROM chip, not a single event, so even reads could conflict if they + * weren't arbitrated by the semaphore. + */ +int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) +{ + u16 count; + int ret; + + for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { + /* Request semaphore */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + + /* See if we got it */ + ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + EEPROM_SEM_TIMEOUT); + if (ret >= 0) { + IWL_DEBUG_IO(priv, + "Acquired semaphore after %d tries.\n", + count+1); + return ret; + } + } + + return ret; +} + +void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) +{ + iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + +} + +int iwl_eeprom_check_version(struct iwl_priv *priv) +{ + u16 eeprom_ver; + u16 calib_ver; + + eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); + calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); + + if (eeprom_ver < priv->cfg->eeprom_ver || + calib_ver < priv->cfg->eeprom_calib_ver) + goto err; + + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", + eeprom_ver, calib_ver); + + return 0; +err: + IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " + "CALIB=0x%x < 0x%x\n", + eeprom_ver, priv->cfg->eeprom_ver, + calib_ver, priv->cfg->eeprom_calib_ver); + return -EINVAL; + +} + +void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) +{ + const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, + EEPROM_MAC_ADDRESS); + memcpy(mac, addr, ETH_ALEN); +} + +/** + * iwl_get_max_txpower_avg - get the highest tx power from all chains. + * find the highest tx power from all chains for the channel + */ +static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int element, s8 *max_txpower_in_half_dbm) +{ + s8 max_txpower_avg = 0; /* (dBm) */ + + IWL_DEBUG_INFO(priv, "%d - " + "chain_a: %d dB chain_b: %d dB " + "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", + element, + enhanced_txpower[element].chain_a_max >> 1, + enhanced_txpower[element].chain_b_max >> 1, + enhanced_txpower[element].chain_c_max >> 1, + enhanced_txpower[element].mimo2_max >> 1, + enhanced_txpower[element].mimo3_max >> 1); + /* Take the highest tx power from any valid chains */ + if ((priv->cfg->valid_tx_ant & ANT_A) && + (enhanced_txpower[element].chain_a_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_a_max; + if ((priv->cfg->valid_tx_ant & ANT_B) && + (enhanced_txpower[element].chain_b_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_b_max; + if ((priv->cfg->valid_tx_ant & ANT_C) && + (enhanced_txpower[element].chain_c_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_c_max; + if (((priv->cfg->valid_tx_ant == ANT_AB) | + (priv->cfg->valid_tx_ant == ANT_BC) | + (priv->cfg->valid_tx_ant == ANT_AC)) && + (enhanced_txpower[element].mimo2_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo2_max; + if ((priv->cfg->valid_tx_ant == ANT_ABC) && + (enhanced_txpower[element].mimo3_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo3_max; + + /* + * max. tx power in EEPROM is in 1/2 dBm format + * convert from 1/2 dBm to dBm (round-up convert) + * but we also do not want to loss 1/2 dBm resolution which + * will impact performance + */ + *max_txpower_in_half_dbm = max_txpower_avg; + return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); +} + +/** + * iwl_update_common_txpower: update channel tx power + * update tx power per band based on EEPROM enhanced tx power info. + */ +static s8 iwl_update_common_txpower(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int section, int element, s8 *max_txpower_in_half_dbm) +{ + struct iwl_channel_info *ch_info; + int ch; + bool is_ht40 = false; + s8 max_txpower_avg; /* (dBm) */ + + /* it is common section, contain all type (Legacy, HT and HT40) + * based on the element in the section to determine + * is it HT 40 or not + */ + if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) + is_ht40 = true; + max_txpower_avg = + iwl_get_max_txpower_avg(priv, enhanced_txpower, + element, max_txpower_in_half_dbm); + + ch_info = priv->channel_info; + + for (ch = 0; ch < priv->channel_count; ch++) { + /* find matching band and update tx power if needed */ + if ((ch_info->band == enhinfo[section].band) && + (ch_info->max_power_avg < max_txpower_avg) && + (!is_ht40)) { + /* Update regulatory-based run-time data */ + ch_info->max_power_avg = ch_info->curr_txpow = + max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + if ((ch_info->band == enhinfo[section].band) && is_ht40 && + (ch_info->ht40_max_power_avg < max_txpower_avg)) { + /* Update regulatory-based run-time data */ + ch_info->ht40_max_power_avg = max_txpower_avg; + } + ch_info++; + } + return max_txpower_avg; +} + +/** + * iwl_update_channel_txpower: update channel tx power + * update channel tx power based on EEPROM enhanced tx power info. + */ +static s8 iwl_update_channel_txpower(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int section, int element, s8 *max_txpower_in_half_dbm) +{ + struct iwl_channel_info *ch_info; + int ch; + u8 channel; + s8 max_txpower_avg; /* (dBm) */ + + channel = enhinfo[section].iwl_eeprom_section_channel[element]; + max_txpower_avg = + iwl_get_max_txpower_avg(priv, enhanced_txpower, + element, max_txpower_in_half_dbm); + + ch_info = priv->channel_info; + for (ch = 0; ch < priv->channel_count; ch++) { + /* find matching channel and update tx power if needed */ + if (ch_info->channel == channel) { + if ((ch_info->max_power_avg < max_txpower_avg) && + (!enhinfo[section].is_ht40)) { + /* Update regulatory-based run-time data */ + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + if ((enhinfo[section].is_ht40) && + (ch_info->ht40_max_power_avg < max_txpower_avg)) { + /* Update regulatory-based run-time data */ + ch_info->ht40_max_power_avg = max_txpower_avg; + } + break; + } + ch_info++; + } + return max_txpower_avg; +} + +/** + * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info + */ +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + int eeprom_section_count = 0; + int section, element; + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; + u32 offset; + s8 max_txpower_avg; /* (dBm) */ + s8 max_txpower_in_half_dbm; /* (half-dBm) */ + + /* Loop through all the sections + * adjust bands and channel's max tx power + * Set the tx_power_user_lmt to the highest power + * supported by any channels and chains + */ + for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { + eeprom_section_count = enhinfo[section].count; + offset = enhinfo[section].offset; + enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) + iwl_eeprom_query_addr(priv, offset); + + /* + * check for valid entry - + * different version of EEPROM might contain different set + * of enhanced tx power table + * always check for valid entry before process + * the information + */ + if (!enhanced_txpower->common || enhanced_txpower->reserved) + continue; + + for (element = 0; element < eeprom_section_count; element++) { + if (enhinfo[section].is_common) + max_txpower_avg = + iwl_update_common_txpower(priv, + enhanced_txpower, section, + element, + &max_txpower_in_half_dbm); + else + max_txpower_avg = + iwl_update_channel_txpower(priv, + enhanced_txpower, section, + element, + &max_txpower_in_half_dbm); + + /* Update the tx_power_user_lmt to the highest power + * supported by any channel */ + if (max_txpower_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txpower_avg; + + /* + * Update the tx_power_lmt_in_half_dbm to + * the highest power supported by any channel + */ + if (max_txpower_in_half_dbm > + priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = + max_txpower_in_half_dbm; + } + } +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index b4deef4e91db..f525d55f2c0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -312,4 +312,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) return cpu_to_le32(flags|(u32)rate); } +/* eeprom */ +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); +void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); +int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); +void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 66eccb12159d..87cd10ff285d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -136,78 +136,6 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 }; -/** - * struct iwl_txpwr_section: eeprom section information - * @offset: indirect address into eeprom image - * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section - * @band: band type for the section - * @is_common - true: common section, false: channel section - * @is_cck - true: cck section, false: not cck section - * @is_ht_40 - true: all channel in the section are HT40 channel, - * false: legacy or HT 20 MHz - * ignore if it is common section - * @iwl_eeprom_section_channel: channel array in the section, - * ignore if common section - */ -struct iwl_txpwr_section { - u32 offset; - u8 count; - enum ieee80211_band band; - bool is_common; - bool is_cck; - bool is_ht40; - u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; -}; - -/** - * section 1 - 3 are regulatory tx power apply to all channels based on - * modulation: CCK, OFDM - * Band: 2.4GHz, 5.2GHz - * section 4 - 10 are regulatory tx power apply to specified channels - * For example: - * 1L - Channel 1 Legacy - * 1HT - Channel 1 HT - * (1,+1) - Channel 1 HT40 "_above_" - * - * Section 1: all CCK channels - * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels - * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels - * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT - * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) - * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT - * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) - * Section 8: 2.4 GHz channel: 13L, 13HT - * Section 9: 2.4 GHz channel: 140L, 140HT - * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) - * - */ -static const struct iwl_txpwr_section enhinfo[] = { - { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, - { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, - { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, - { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, - false, false, false, - {1, 1, 2, 2, 10, 10, 11, 11 } }, - { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, - false, false, true, - { 1, 2, 6, 7, 9 } }, - { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, - false, false, false, - { 36, 64, 100, 36, 64, 100 } }, - { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, - false, false, true, - { 36, 60, 100 } }, - { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, - false, false, false, - { 13, 13 } }, - { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, - false, false, false, - { 140, 140 } }, - { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, - false, false, true, - { 132, 44 } }, -}; - /****************************************************************************** * * EEPROM related functions @@ -289,46 +217,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv) return nvm_type; } -/* - * The device's EEPROM semaphore prevents conflicts between driver and uCode - * when accessing the EEPROM; each access is a series of pulses to/from the - * EEPROM chip, not a single event, so even reads could conflict if they - * weren't arbitrated by the semaphore. - */ -int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) -{ - u16 count; - int ret; - - for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { - /* Request semaphore */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - - /* See if we got it */ - ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - EEPROM_SEM_TIMEOUT); - if (ret >= 0) { - IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n", - count+1); - return ret; - } - } - - return ret; -} -EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore); - -void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) -{ - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - -} -EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); - const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { BUG_ON(offset >= priv->cfg->base_params->eeprom_size); @@ -490,6 +378,20 @@ static int iwl_find_otp_image(struct iwl_priv *priv, return -EINVAL; } +const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) +{ + return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); +} +EXPORT_SYMBOL(iwl_eeprom_query_addr); + +u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) +{ + if (!priv->eeprom) + return 0; + return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); +} +EXPORT_SYMBOL(iwl_eeprom_query16); + /** * iwl_eeprom_init - read EEPROM contents * @@ -616,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_eeprom_free); -int iwl_eeprom_check_version(struct iwl_priv *priv) -{ - u16 eeprom_ver; - u16 calib_ver; - - eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); - calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); - - if (eeprom_ver < priv->cfg->eeprom_ver || - calib_ver < priv->cfg->eeprom_calib_ver) - goto err; - - IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", - eeprom_ver, calib_ver); - - return 0; -err: - IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", - eeprom_ver, priv->cfg->eeprom_ver, - calib_ver, priv->cfg->eeprom_calib_ver); - return -EINVAL; - -} -EXPORT_SYMBOL(iwl_eeprom_check_version); - -const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) -{ - return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); -} -EXPORT_SYMBOL(iwl_eeprom_query_addr); - -u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) -{ - if (!priv->eeprom) - return 0; - return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); -} -EXPORT_SYMBOL(iwl_eeprom_query16); - -void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) -{ - const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, - EEPROM_MAC_ADDRESS); - memcpy(mac, addr, ETH_ALEN); -} -EXPORT_SYMBOL(iwl_eeprom_get_mac); - static void iwl_init_band_reference(const struct iwl_priv *priv, int eep_band, int *eeprom_ch_count, const struct iwl_eeprom_channel **eeprom_ch_info, @@ -721,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") - /** * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. * @@ -765,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, return 0; } -/** - * iwl_get_max_txpower_avg - get the highest tx power from all chains. - * find the highest tx power from all chains for the channel - */ -static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int element, s8 *max_txpower_in_half_dbm) -{ - s8 max_txpower_avg = 0; /* (dBm) */ - - IWL_DEBUG_INFO(priv, "%d - " - "chain_a: %d dB chain_b: %d dB " - "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", - element, - enhanced_txpower[element].chain_a_max >> 1, - enhanced_txpower[element].chain_b_max >> 1, - enhanced_txpower[element].chain_c_max >> 1, - enhanced_txpower[element].mimo2_max >> 1, - enhanced_txpower[element].mimo3_max >> 1); - /* Take the highest tx power from any valid chains */ - if ((priv->cfg->valid_tx_ant & ANT_A) && - (enhanced_txpower[element].chain_a_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((priv->cfg->valid_tx_ant & ANT_B) && - (enhanced_txpower[element].chain_b_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((priv->cfg->valid_tx_ant & ANT_C) && - (enhanced_txpower[element].chain_c_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((priv->cfg->valid_tx_ant == ANT_AB) | - (priv->cfg->valid_tx_ant == ANT_BC) | - (priv->cfg->valid_tx_ant == ANT_AC)) && - (enhanced_txpower[element].mimo2_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((priv->cfg->valid_tx_ant == ANT_ABC) && - (enhanced_txpower[element].mimo3_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo3_max; - - /* - * max. tx power in EEPROM is in 1/2 dBm format - * convert from 1/2 dBm to dBm (round-up convert) - * but we also do not want to loss 1/2 dBm resolution which - * will impact performance - */ - *max_txpower_in_half_dbm = max_txpower_avg; - return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); -} - -/** - * iwl_update_common_txpower: update channel tx power - * update tx power per band based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_common_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - bool is_ht40 = false; - s8 max_txpower_avg; /* (dBm) */ - - /* it is common section, contain all type (Legacy, HT and HT40) - * based on the element in the section to determine - * is it HT 40 or not - */ - if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) - is_ht40 = true; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching band and update tx power if needed */ - if ((ch_info->band == enhinfo[section].band) && - (ch_info->max_power_avg < max_txpower_avg) && - (!is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = ch_info->curr_txpow = - max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((ch_info->band == enhinfo[section].band) && is_ht40 && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwl_update_channel_txpower: update channel tx power - * update channel tx power based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_channel_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - u8 channel; - s8 max_txpower_avg; /* (dBm) */ - - channel = enhinfo[section].iwl_eeprom_section_channel[element]; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching channel and update tx power if needed */ - if (ch_info->channel == channel) { - if ((ch_info->max_power_avg < max_txpower_avg) && - (!enhinfo[section].is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = max_txpower_avg; - ch_info->curr_txpow = max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((enhinfo[section].is_ht40) && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - break; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info - */ -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) -{ - int eeprom_section_count = 0; - int section, element; - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; - u32 offset; - s8 max_txpower_avg; /* (dBm) */ - s8 max_txpower_in_half_dbm; /* (half-dBm) */ - - /* Loop through all the sections - * adjust bands and channel's max tx power - * Set the tx_power_user_lmt to the highest power - * supported by any channels and chains - */ - for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { - eeprom_section_count = enhinfo[section].count; - offset = enhinfo[section].offset; - enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) - iwl_eeprom_query_addr(priv, offset); - - /* - * check for valid entry - - * different version of EEPROM might contain different set - * of enhanced tx power table - * always check for valid entry before process - * the information - */ - if (!enhanced_txpower->common || enhanced_txpower->reserved) - continue; - - for (element = 0; element < eeprom_section_count; element++) { - if (enhinfo[section].is_common) - max_txpower_avg = - iwl_update_common_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - else - max_txpower_avg = - iwl_update_channel_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - - /* Update the tx_power_user_lmt to the highest power - * supported by any channel */ - if (max_txpower_avg > priv->tx_power_user_lmt) - priv->tx_power_user_lmt = max_txpower_avg; - - /* - * Update the tx_power_lmt_in_half_dbm to - * the highest power supported by any channel - */ - if (max_txpower_in_half_dbm > - priv->tx_power_lmt_in_half_dbm) - priv->tx_power_lmt_in_half_dbm = - max_txpower_in_half_dbm; - } - } -} -EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower); - #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") @@ -1161,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } EXPORT_SYMBOL(iwl_get_channel_info); - diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 2ae0a11e523b..d9b590625ae4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -501,18 +501,13 @@ struct iwl_eeprom_ops { }; -void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); int iwl_eeprom_init(struct iwl_priv *priv); void iwl_eeprom_free(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); -u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); - int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); -int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); -void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); +u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); int iwl_init_channel_map(struct iwl_priv *priv); void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( -- cgit v1.2.3 From 6e0dc64384298b29ac17de7362b7d6d2ef588304 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:44 +0000 Subject: cnic: Add common cnic_request_irq() to reduce some duplicate code. Also, use tasklet_kill() in cnic_free_irq() to wait for the cnic_irq_task to complete. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 27449bf775e3..0fab7203ffbd 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3428,11 +3428,24 @@ static void cnic_free_irq(struct cnic_dev *dev) if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { cp->disable_int_sync(dev); - tasklet_disable(&cp->cnic_irq_task); + tasklet_kill(&cp->cnic_irq_task); free_irq(ethdev->irq_arr[0].vector, dev); } } +static int cnic_request_irq(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + struct cnic_eth_dev *ethdev = cp->ethdev; + int err; + + err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, "cnic", dev); + if (err) + tasklet_disable(&cp->cnic_irq_task); + + return err; +} + static int cnic_init_bnx2_irq(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -3453,12 +3466,10 @@ static int cnic_init_bnx2_irq(struct cnic_dev *dev) cp->last_status_idx = cp->status_blk.bnx2->status_idx; tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2_msix, (unsigned long) dev); - err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, - "cnic", dev); - if (err) { - tasklet_disable(&cp->cnic_irq_task); + err = cnic_request_irq(dev); + if (err) return err; - } + while (cp->status_blk.bnx2->status_completion_producer_index && i < 10) { CNIC_WR(dev, BNX2_HC_COALESCE_NOW, @@ -3860,12 +3871,9 @@ static int cnic_init_bnx2x_irq(struct cnic_dev *dev) tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2x_bh, (unsigned long) dev); - if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { - err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, - "cnic", dev); - if (err) - tasklet_disable(&cp->cnic_irq_task); - } + if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) + err = cnic_request_irq(dev); + return err; } -- cgit v1.2.3 From 6e0dda0c467d6c66d64c146170ea35399ec34c15 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:45 +0000 Subject: cnic: Convert ctx_flags to bit fields so that we can additional bit definitions without requiring a spinlock. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 4 ++-- drivers/net/cnic.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 0fab7203ffbd..311b2e6620d6 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1721,7 +1721,7 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) struct kcqe *cqes[1]; u32 hw_cid, type; - if (!(ctx->ctx_flags & CTX_FL_OFFLD_START)) + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) goto skip_cfc_delete; while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) @@ -1943,7 +1943,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_TCP_CONNECT, kwqe1->cid, ISCSI_CONNECTION_TYPE, &l5_data); if (!ret) - ctx->ctx_flags |= CTX_FL_OFFLD_START; + set_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); return ret; } diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 676d008509c6..9907cc24807a 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -168,8 +168,8 @@ struct cnic_context { wait_queue_head_t waitq; int wait_cond; unsigned long timestamp; - u32 ctx_flags; -#define CTX_FL_OFFLD_START 0x00000001 + unsigned long ctx_flags; +#define CTX_FL_OFFLD_START 0 u8 ulp_proto_id; union { struct cnic_iscsi *iscsi; -- cgit v1.2.3 From a2c9e769dbb92336ddacba01d399ad0f509e7094 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:46 +0000 Subject: cnic: Add cnic_bnx2x_destroy_ramrod() Refactoring code for the next patch to defer connection clean up. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 311b2e6620d6..ee66c48e28bc 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1708,25 +1708,14 @@ static int cnic_bnx2x_iscsi_update(struct cnic_dev *dev, struct kwqe *kwqe) return ret; } -static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) +static int cnic_bnx2x_destroy_ramrod(struct cnic_dev *dev, u32 l5_cid) { struct cnic_local *cp = dev->cnic_priv; - struct iscsi_kwqe_conn_destroy *req = - (struct iscsi_kwqe_conn_destroy *) kwqe; - union l5cm_specific_data l5_data; - u32 l5_cid = req->reserved0; struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; - int ret = 0; - struct iscsi_kcqe kcqe; - struct kcqe *cqes[1]; + union l5cm_specific_data l5_data; + int ret; u32 hw_cid, type; - if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) - goto skip_cfc_delete; - - while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) - msleep(250); - init_waitqueue_head(&ctx->waitq); ctx->wait_cond = 0; memset(&l5_data, 0, sizeof(l5_data)); @@ -1742,6 +1731,28 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) if (ret == 0) wait_event(ctx->waitq, ctx->wait_cond); + return ret; +} + +static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) +{ + struct cnic_local *cp = dev->cnic_priv; + struct iscsi_kwqe_conn_destroy *req = + (struct iscsi_kwqe_conn_destroy *) kwqe; + u32 l5_cid = req->reserved0; + struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + int ret = 0; + struct iscsi_kcqe kcqe; + struct kcqe *cqes[1]; + + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + goto skip_cfc_delete; + + while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) + msleep(250); + + ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid); + skip_cfc_delete: cnic_free_bnx2x_conn_resc(dev, l5_cid); -- cgit v1.2.3 From fdf24086f4752aee5dfb40143c736250df017820 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:47 +0000 Subject: cnic: Defer iscsi connection cleanup The bnx2x devices require a 2 second quiet time before sending the last RAMROD command to destroy a connection. This sleep wait adds up to a long delay when iscsid is serially destroying maultiple connections. Create a workqueue to perform the final connection cleanup in the background to speed up the process. This significantly speeds up the process as the wait time can be done in parallel for multiple connections. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 110 ++++++++++++++++++++++++++++-- drivers/net/cnic.h | 3 + drivers/scsi/bnx2i/57xx_iscsi_constants.h | 2 + 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index ee66c48e28bc..b12bba795f2e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -81,6 +81,8 @@ static struct cnic_ops cnic_bnx2x_ops = { .cnic_ctl = cnic_ctl, }; +static struct workqueue_struct *cnic_wq; + static void cnic_shutdown_rings(struct cnic_dev *); static void cnic_init_rings(struct cnic_dev *); static int cnic_cm_set_pg(struct cnic_sock *); @@ -1629,10 +1631,11 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], struct iscsi_kwqe_conn_offload1 *req1; struct iscsi_kwqe_conn_offload2 *req2; struct cnic_local *cp = dev->cnic_priv; + struct cnic_context *ctx; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; u32 l5_cid; - int ret; + int ret = 0; if (num < 2) { *work = num; @@ -1656,9 +1659,15 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], kcqe.iscsi_conn_id = l5_cid; kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE; + ctx = &cp->ctx_tbl[l5_cid]; + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) { + kcqe.completion_status = + ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY; + goto done; + } + if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) { atomic_dec(&cp->iscsi_conn); - ret = 0; goto done; } ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid); @@ -1748,8 +1757,16 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) goto skip_cfc_delete; - while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) - msleep(250); + if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) { + unsigned long delta = ctx->timestamp + (2 * HZ) - jiffies; + + if (delta > (2 * HZ)) + delta = 0; + + set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags); + queue_delayed_work(cnic_wq, &cp->delete_task, delta); + goto destroy_reply; + } ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid); @@ -1757,7 +1774,9 @@ skip_cfc_delete: cnic_free_bnx2x_conn_resc(dev, l5_cid); atomic_dec(&cp->iscsi_conn); + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); +destroy_reply: memset(&kcqe, 0, sizeof(kcqe)); kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN; kcqe.iscsi_conn_id = l5_cid; @@ -2748,6 +2767,13 @@ static int cnic_cm_create(struct cnic_dev *dev, int ulp_type, u32 cid, if (l5_cid >= MAX_CM_SK_TBL_SZ) return -EINVAL; + if (cp->ctx_tbl) { + struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + return -EAGAIN; + } + csk1 = &cp->csk_tbl[l5_cid]; if (atomic_read(&csk1->ref_count)) return -EAGAIN; @@ -3299,6 +3325,32 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode) static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + int i; + + if (!cp->ctx_tbl) + return; + + if (!netif_running(dev->netdev)) + return; + + for (i = 0; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + + while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + msleep(10); + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + netdev_warn(dev->netdev, "CID %x not deleted\n", + ctx->cid); + } + + cancel_delayed_work(&cp->delete_task); + flush_workqueue(cnic_wq); + + if (atomic_read(&cp->iscsi_conn) != 0) + netdev_warn(dev->netdev, "%d iSCSI connections not destroyed\n", + atomic_read(&cp->iscsi_conn)); } static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) @@ -3333,6 +3385,46 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) return 0; } +static void cnic_delete_task(struct work_struct *work) +{ + struct cnic_local *cp; + struct cnic_dev *dev; + u32 i; + int need_resched = 0; + + cp = container_of(work, struct cnic_local, delete_task.work); + dev = cp->dev; + + for (i = 0; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags) || + !test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + continue; + + if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) { + need_resched = 1; + continue; + } + + if (!test_and_clear_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + continue; + + cnic_bnx2x_destroy_ramrod(dev, i); + + cnic_free_bnx2x_conn_resc(dev, i); + if (ctx->ulp_proto_id == CNIC_ULP_ISCSI) + atomic_dec(&cp->iscsi_conn); + + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + } + + if (need_resched) + queue_delayed_work(cnic_wq, &cp->delete_task, + msecs_to_jiffies(10)); + +} + static int cnic_cm_open(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -3347,6 +3439,8 @@ static int cnic_cm_open(struct cnic_dev *dev) if (err) goto err_out; + INIT_DELAYED_WORK(&cp->delete_task, cnic_delete_task); + dev->cm_create = cnic_cm_create; dev->cm_destroy = cnic_cm_destroy; dev->cm_connect = cnic_cm_connect; @@ -4735,6 +4829,13 @@ static int __init cnic_init(void) return rc; } + cnic_wq = create_singlethread_workqueue("cnic_wq"); + if (!cnic_wq) { + cnic_release(); + unregister_netdevice_notifier(&cnic_netdev_notifier); + return -ENOMEM; + } + return 0; } @@ -4742,6 +4843,7 @@ static void __exit cnic_exit(void) { unregister_netdevice_notifier(&cnic_netdev_notifier); cnic_release(); + destroy_workqueue(cnic_wq); } module_init(cnic_init); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 9907cc24807a..47cd801af857 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -170,6 +170,7 @@ struct cnic_context { unsigned long timestamp; unsigned long ctx_flags; #define CTX_FL_OFFLD_START 0 +#define CTX_FL_DELETE_WAIT 1 u8 ulp_proto_id; union { struct cnic_iscsi *iscsi; @@ -287,6 +288,8 @@ struct cnic_local { int hq_size; int num_cqs; + struct delayed_work delete_task; + struct cnic_ctx *ctx_arr; int ctx_blks; int ctx_blk_size; diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h index 2fceb19eb27b..1b6f86b2482d 100644 --- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h +++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h @@ -120,6 +120,8 @@ /* additional LOM specific iSCSI license not installed */ #define ISCSI_KCQE_COMPLETION_STATUS_LOM_ISCSI_NOT_ENABLED (0x51) +#define ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY (0x80) + /* SQ/RQ/CQ DB structure sizes */ #define ISCSI_SQ_DB_SIZE (16) #define ISCSI_RQ_DB_SIZE (16) -- cgit v1.2.3 From c06c0462250a5dbc9e58d00caab4cd7e6675128c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:48 +0000 Subject: cnic: Add cnic_free_uio() to free all UIO related structures. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index b12bba795f2e..739ffcb9bff0 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -770,20 +770,15 @@ static void cnic_free_context(struct cnic_dev *dev) } } -static void cnic_free_resc(struct cnic_dev *dev) +static void __cnic_free_uio(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int i = 0; - if (cp->cnic_uinfo) { - while (cp->uio_dev != -1 && i < 15) { - msleep(100); - i++; - } + if (cp->cnic_uinfo) uio_unregister_device(cp->cnic_uinfo); - kfree(cp->cnic_uinfo); - cp->cnic_uinfo = NULL; - } + + kfree(cp->cnic_uinfo); + cp->cnic_uinfo = NULL; if (cp->l2_buf) { dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size, @@ -796,6 +791,28 @@ static void cnic_free_resc(struct cnic_dev *dev) cp->l2_ring, cp->l2_ring_map); cp->l2_ring = NULL; } +} + +static void cnic_free_uio(struct cnic_dev *dev) +{ + if (!dev) + return; + + __cnic_free_uio(dev); +} + +static void cnic_free_resc(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + int i = 0; + + if (cp->cnic_uinfo) { + while (cp->uio_dev != -1 && i < 15) { + msleep(100); + i++; + } + cnic_free_uio(dev); + } cnic_free_context(dev); kfree(cp->ctx_arr); -- cgit v1.2.3 From cd801536c236e287f1d3eeee428abf9ffd523ede Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:49 +0000 Subject: cnic: Add cnic_uio_dev struct and put all uio related structures and ring buffers in it. This allows uio operations to be done independent of the cnic device structures. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 195 ++++++++++++++++++++++++++++------------------------- drivers/net/cnic.h | 29 +++++--- 2 files changed, 124 insertions(+), 100 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 739ffcb9bff0..e8f2836b6301 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -89,22 +89,24 @@ static int cnic_cm_set_pg(struct cnic_sock *); static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = uinfo->priv; + struct cnic_dev *dev; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (cp->uio_dev != -1) + if (udev->uio_dev != -1) return -EBUSY; rtnl_lock(); + dev = udev->dev; + if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) { rtnl_unlock(); return -ENODEV; } - cp->uio_dev = iminor(inode); + udev->uio_dev = iminor(inode); cnic_init_rings(dev); rtnl_unlock(); @@ -114,12 +116,12 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = uinfo->priv; + struct cnic_dev *dev = udev->dev; cnic_shutdown_rings(dev); - cp->uio_dev = -1; + udev->uio_dev = -1; return 0; } @@ -276,8 +278,9 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, u16 len = 0; u32 msg_type = ISCSI_KEVENT_IF_DOWN; struct cnic_ulp_ops *ulp_ops; + struct cnic_uio_dev *udev = cp->udev; - if (cp->uio_dev == -1) + if (!udev || udev->uio_dev == -1) return -ENODEV; if (csk) { @@ -408,8 +411,7 @@ static void cnic_uio_stop(void) list_for_each_entry(dev, &cnic_dev_list, list) { struct cnic_local *cp = dev->cnic_priv; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); } read_unlock(&cnic_dev_lock); } @@ -770,48 +772,44 @@ static void cnic_free_context(struct cnic_dev *dev) } } -static void __cnic_free_uio(struct cnic_dev *dev) +static void __cnic_free_uio(struct cnic_uio_dev *udev) { - struct cnic_local *cp = dev->cnic_priv; - - if (cp->cnic_uinfo) - uio_unregister_device(cp->cnic_uinfo); + uio_unregister_device(&udev->cnic_uinfo); - kfree(cp->cnic_uinfo); - cp->cnic_uinfo = NULL; - - if (cp->l2_buf) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size, - cp->l2_buf, cp->l2_buf_map); - cp->l2_buf = NULL; + if (udev->l2_buf) { + dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, + udev->l2_buf, udev->l2_buf_map); + udev->l2_buf = NULL; } - if (cp->l2_ring) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_ring_size, - cp->l2_ring, cp->l2_ring_map); - cp->l2_ring = NULL; + if (udev->l2_ring) { + dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, + udev->l2_ring, udev->l2_ring_map); + udev->l2_ring = NULL; } } -static void cnic_free_uio(struct cnic_dev *dev) +static void cnic_free_uio(struct cnic_uio_dev *udev) { - if (!dev) + if (!udev) return; - __cnic_free_uio(dev); + __cnic_free_uio(udev); } static void cnic_free_resc(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; int i = 0; - if (cp->cnic_uinfo) { - while (cp->uio_dev != -1 && i < 15) { + if (udev) { + while (udev->uio_dev != -1 && i < 15) { msleep(100); i++; } - cnic_free_uio(dev); + cnic_free_uio(udev); + cp->udev = NULL; } cnic_free_context(dev); @@ -913,37 +911,53 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info) return 0; } -static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages) +static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev; + + udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC); + if (!udev) + return -ENOMEM; + + udev->uio_dev = -1; - cp->l2_ring_size = pages * BCM_PAGE_SIZE; - cp->l2_ring = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_ring_size, - &cp->l2_ring_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_ring) + udev->dev = dev; + udev->pdev = dev->pcidev; + udev->l2_ring_size = pages * BCM_PAGE_SIZE; + udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, + &udev->l2_ring_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_ring) return -ENOMEM; - cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; - cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size); - cp->l2_buf = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_buf_size, - &cp->l2_buf_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_buf) + udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; + udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); + udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, + &udev->l2_buf_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_buf) return -ENOMEM; + cp->udev = udev; + return 0; } -static int cnic_alloc_uio(struct cnic_dev *dev) { +static int cnic_init_uio(struct cnic_dev *dev) +{ struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; struct uio_info *uinfo; - int ret; + int ret = 0; - uinfo = kzalloc(sizeof(*uinfo), GFP_ATOMIC); - if (!uinfo) + if (!udev) return -ENOMEM; + udev->uio_dev = -1; + + uinfo = &udev->cnic_uinfo; + uinfo->mem[0].addr = dev->netdev->base_addr; uinfo->mem[0].internal_addr = dev->regview; uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; @@ -951,7 +965,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & - PAGE_MASK; + PAGE_MASK; if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; else @@ -968,12 +982,12 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { uinfo->mem[1].memtype = UIO_MEM_LOGICAL; - uinfo->mem[2].addr = (unsigned long) cp->l2_ring; - uinfo->mem[2].size = cp->l2_ring_size; + uinfo->mem[2].addr = (unsigned long) udev->l2_ring; + uinfo->mem[2].size = udev->l2_ring_size; uinfo->mem[2].memtype = UIO_MEM_LOGICAL; - uinfo->mem[3].addr = (unsigned long) cp->l2_buf; - uinfo->mem[3].size = cp->l2_buf_size; + uinfo->mem[3].addr = (unsigned long) udev->l2_buf; + uinfo->mem[3].size = udev->l2_buf_size; uinfo->mem[3].memtype = UIO_MEM_LOGICAL; uinfo->version = CNIC_MODULE_VERSION; @@ -982,16 +996,11 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { uinfo->open = cnic_uio_open; uinfo->release = cnic_uio_close; - uinfo->priv = dev; + uinfo->priv = udev; - ret = uio_register_device(&dev->pcidev->dev, uinfo); - if (ret) { - kfree(uinfo); - return ret; - } + ret = uio_register_device(&udev->pdev->dev, uinfo); - cp->cnic_uinfo = uinfo; - return 0; + return ret; } static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) @@ -1012,11 +1021,11 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) if (ret) goto error; - ret = cnic_alloc_l2_rings(dev, 2); + ret = cnic_alloc_uio_rings(dev, 2); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -1150,11 +1159,11 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->l2_rx_ring_size = 15; - ret = cnic_alloc_l2_rings(dev, 4); + ret = cnic_alloc_uio_rings(dev, 4); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -2226,8 +2235,9 @@ static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info) static int cnic_l2_completion(struct cnic_local *cp) { u16 hw_cons, sw_cons; + struct cnic_uio_dev *udev = cp->udev; union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); u32 cmd; int comp = 0; @@ -2273,7 +2283,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp) cp->tx_cons = tx_cons; cp->rx_cons = rx_cons; - uio_event_notify(cp->cnic_uinfo); + if (cp->udev) + uio_event_notify(&cp->udev->cnic_uinfo); } if (comp) clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); @@ -2435,8 +2446,7 @@ static void cnic_ulp_stop(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int if_type; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { struct cnic_ulp_ops *ulp_ops; @@ -3658,11 +3668,12 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, tx_cid, sb_id; u32 val, offset0, offset1, offset2, offset3; int i; struct tx_bd *txbd; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; struct status_block *s_blk = cp->status_blk.gen; sb_id = cp->status_blk_num; @@ -3704,18 +3715,18 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16); cnic_ctx_wr(dev, cid_addr, offset1, val); - txbd = (struct tx_bd *) cp->l2_ring; + txbd = (struct tx_bd *) udev->l2_ring; - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i++, txbd++) { txbd->tx_bd_haddr_hi = (u64) buf_map >> 32; txbd->tx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; cnic_ctx_wr(dev, cid_addr, offset2, val); txbd->tx_bd_haddr_hi = val; - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; cnic_ctx_wr(dev, cid_addr, offset3, val); txbd->tx_bd_haddr_lo = val; } @@ -3724,10 +3735,12 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, sb_id, val, coal_reg, coal_val; int i; struct rx_bd *rxbd; struct status_block *s_blk = cp->status_blk.gen; + dma_addr_t ring_map = udev->l2_ring_map; sb_id = cp->status_blk_num; cnic_init_context(dev, 2); @@ -3761,22 +3774,22 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); - rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); + rxbd = (struct rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->rx_bd_len = cp->l2_single_buf_size; rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32; rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); rxbd->rx_bd_haddr_hi = val; - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); rxbd->rx_bd_haddr_lo = val; @@ -4038,8 +4051,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; - union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring; - dma_addr_t buf_map, ring_map = cp->l2_ring_map; + struct cnic_uio_dev *udev = cp->udev; + union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) udev->l2_ring; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int port = CNIC_PORT(cp); int i; @@ -4048,7 +4062,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, memset(txbd, 0, BCM_PAGE_SIZE); - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) { struct eth_tx_start_bd *start_bd = &txbd->start_bd; struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd); @@ -4096,17 +4110,18 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; - struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring + + struct cnic_uio_dev *udev = cp->udev; + struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; int port = CNIC_PORT(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; - dma_addr_t ring_map = cp->l2_ring_map; + dma_addr_t ring_map = udev->l2_ring_map; /* General data */ data->general.client_id = cli; @@ -4119,7 +4134,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32); rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); } @@ -4320,6 +4335,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) static void cnic_init_rings(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; if (test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) return; @@ -4350,15 +4366,15 @@ static void cnic_init_rings(struct cnic_dev *dev) set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); - data = cp->l2_buf; + data = udev->l2_buf; memset(data, 0, sizeof(*data)); cnic_init_bnx2x_tx_ring(dev, data); cnic_init_bnx2x_rx_ring(dev, data); - l5_data.phy_address.lo = cp->l2_buf_map & 0xffffffff; - l5_data.phy_address.hi = (u64) cp->l2_buf_map >> 32; + l5_data.phy_address.lo = udev->l2_buf_map & 0xffffffff; + l5_data.phy_address.hi = (u64) udev->l2_buf_map >> 32; type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE; @@ -4539,7 +4555,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) /* Need to wait for the ring shutdown event to complete * before clearing the CNIC_UP flag. */ - while (cp->uio_dev != -1 && i < 15) { + while (cp->udev->uio_dev != -1 && i < 15) { msleep(100); i++; } @@ -4591,7 +4607,6 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev, cp = cdev->cnic_priv; cp->dev = cdev; - cp->uio_dev = -1; cp->l2_single_buf_size = 0x400; cp->l2_rx_ring_size = 3; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 47cd801af857..928af9e64824 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -195,6 +195,23 @@ struct iro { u16 size; }; +struct cnic_uio_dev { + struct uio_info cnic_uinfo; + u32 uio_dev; + + int l2_ring_size; + void *l2_ring; + dma_addr_t l2_ring_map; + + int l2_buf_size; + void *l2_buf; + dma_addr_t l2_buf_map; + + struct cnic_dev *dev; + struct pci_dev *pdev; + struct list_head list; +}; + struct cnic_local { spinlock_t cnic_ulp_lock; @@ -214,14 +231,9 @@ struct cnic_local { struct cnic_eth_dev *ethdev; - void *l2_ring; - dma_addr_t l2_ring_map; - int l2_ring_size; - int l2_rx_ring_size; + struct cnic_uio_dev *udev; - void *l2_buf; - dma_addr_t l2_buf_map; - int l2_buf_size; + int l2_rx_ring_size; int l2_single_buf_size; u16 *rx_cons_ptr; @@ -301,9 +313,6 @@ struct cnic_local { u32 pfid; u32 shmem_base; - u32 uio_dev; - struct uio_info *cnic_uinfo; - struct cnic_ops *cnic_ops; int (*start_hw)(struct cnic_dev *); void (*stop_hw)(struct cnic_dev *); -- cgit v1.2.3 From a3ceeeb8f11d74f26e3dfca40ded911a82402db5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:50 +0000 Subject: cnic: Decouple uio close from cnic shutdown During cnic shutdown, the original driver code requires userspace to close the uio device within a few seconds. This doesn't always happen as the userapp may be hung or otherwise take a long time to close. The system may crash when this happens. We fix the problem by decoupling the uio structures from the cnic structures during cnic shutdown. We do not unregister the uio device until the cnic driver is unloaded. This eliminates the unreliable wait loop for uio to close. All uio structures are kept in a linked list. If the device is shutdown and later brought back up again, the uio strcture will be found in the linked list and coupled back to the cnic structures. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 56 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index e8f2836b6301..3f923a78e22e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -60,6 +60,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CNIC_MODULE_VERSION); static LIST_HEAD(cnic_dev_list); +static LIST_HEAD(cnic_udev_list); static DEFINE_RWLOCK(cnic_dev_lock); static DEFINE_MUTEX(cnic_lock); @@ -101,13 +102,14 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) rtnl_lock(); dev = udev->dev; - if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) { + if (!dev || !test_bit(CNIC_F_CNIC_UP, &dev->flags)) { rtnl_unlock(); return -ENODEV; } udev->uio_dev = iminor(inode); + cnic_shutdown_rings(dev); cnic_init_rings(dev); rtnl_unlock(); @@ -117,9 +119,6 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) { struct cnic_uio_dev *udev = uinfo->priv; - struct cnic_dev *dev = udev->dev; - - cnic_shutdown_rings(dev); udev->uio_dev = -1; return 0; @@ -787,6 +786,9 @@ static void __cnic_free_uio(struct cnic_uio_dev *udev) udev->l2_ring, udev->l2_ring_map); udev->l2_ring = NULL; } + + pci_dev_put(udev->pdev); + kfree(udev); } static void cnic_free_uio(struct cnic_uio_dev *udev) @@ -794,6 +796,9 @@ static void cnic_free_uio(struct cnic_uio_dev *udev) if (!udev) return; + write_lock(&cnic_dev_lock); + list_del_init(&udev->list); + write_unlock(&cnic_dev_lock); __cnic_free_uio(udev); } @@ -801,14 +806,9 @@ static void cnic_free_resc(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_uio_dev *udev = cp->udev; - int i = 0; if (udev) { - while (udev->uio_dev != -1 && i < 15) { - msleep(100); - i++; - } - cnic_free_uio(udev); + udev->dev = NULL; cp->udev = NULL; } @@ -916,6 +916,17 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) struct cnic_local *cp = dev->cnic_priv; struct cnic_uio_dev *udev; + read_lock(&cnic_dev_lock); + list_for_each_entry(udev, &cnic_udev_list, list) { + if (udev->pdev == dev->pcidev) { + udev->dev = dev; + cp->udev = udev; + read_unlock(&cnic_dev_lock); + return 0; + } + } + read_unlock(&cnic_dev_lock); + udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC); if (!udev) return -ENOMEM; @@ -939,6 +950,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) if (!udev->l2_buf) return -ENOMEM; + write_lock(&cnic_dev_lock); + list_add(&udev->list, &cnic_udev_list); + write_unlock(&cnic_dev_lock); + + pci_dev_get(udev->pdev); + cp->udev = udev; return 0; @@ -954,8 +971,6 @@ static int cnic_init_uio(struct cnic_dev *dev) if (!udev) return -ENOMEM; - udev->uio_dev = -1; - uinfo = &udev->cnic_uinfo; uinfo->mem[0].addr = dev->netdev->base_addr; @@ -996,9 +1011,15 @@ static int cnic_init_uio(struct cnic_dev *dev) uinfo->open = cnic_uio_open; uinfo->release = cnic_uio_close; - uinfo->priv = udev; + if (udev->uio_dev == -1) { + if (!uinfo->priv) { + uinfo->priv = udev; - ret = uio_register_device(&udev->pdev->dev, uinfo); + ret = uio_register_device(&udev->pdev->dev, uinfo); + } + } else { + cnic_init_rings(dev); + } return ret; } @@ -4559,6 +4580,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) msleep(100); i++; } + cnic_shutdown_rings(dev); clear_bit(CNIC_F_CNIC_UP, &dev->flags); rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL); synchronize_rcu(); @@ -4834,6 +4856,7 @@ static struct notifier_block cnic_netdev_notifier = { static void cnic_release(void) { struct cnic_dev *dev; + struct cnic_uio_dev *udev; while (!list_empty(&cnic_dev_list)) { dev = list_entry(cnic_dev_list.next, struct cnic_dev, list); @@ -4847,6 +4870,11 @@ static void cnic_release(void) list_del_init(&dev->list); cnic_free_dev(dev); } + while (!list_empty(&cnic_udev_list)) { + udev = list_entry(cnic_udev_list.next, struct cnic_uio_dev, + list); + cnic_free_uio(udev); + } } static int __init cnic_init(void) -- cgit v1.2.3 From ee87a82a28cddbb9267a294172ecb3d3d3bdaa6c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 13 Oct 2010 14:06:51 +0000 Subject: cnic: Add support for 57712 device Add new interrupt ack functions and other hardware interface logic to support the new device. Update version to 2.2.6. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 94 +++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/cnic.h | 22 ++++++++++++ drivers/net/cnic_if.h | 4 +-- 3 files changed, 103 insertions(+), 17 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 3f923a78e22e..92bac19ad60a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -1077,7 +1077,7 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev) cp->ctx_blks = blks; cp->ctx_blk_size = ctx_blk_size; - if (BNX2X_CHIP_IS_E1H(cp->chip_id)) + if (!BNX2X_CHIP_IS_57710(cp->chip_id)) cp->ctx_align = 0; else cp->ctx_align = ctx_blk_size; @@ -2406,6 +2406,22 @@ static inline void cnic_ack_bnx2x_int(struct cnic_dev *dev, u8 id, u8 storm, CNIC_WR(dev, hc_addr, (*(u32 *)&igu_ack)); } +static void cnic_ack_igu_sb(struct cnic_dev *dev, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + struct igu_regular cmd_data; + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id) * 8; + + cmd_data.sb_id_and_flags = + (index << IGU_REGULAR_SB_INDEX_SHIFT) | + (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | + (update << IGU_REGULAR_BUPDATE_SHIFT) | + (op << IGU_REGULAR_ENABLE_INT_SHIFT); + + + CNIC_WR(dev, igu_addr, cmd_data.sb_id_and_flags); +} + static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -2414,6 +2430,14 @@ static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) IGU_INT_DISABLE, 0); } +static void cnic_ack_bnx2x_e2_msix(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + + cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, 0, + IGU_INT_DISABLE, 0); +} + static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) { u32 last_status = *info->status_idx_ptr; @@ -2445,8 +2469,12 @@ static void cnic_service_bnx2x_bh(unsigned long data) status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, - status_idx, IGU_INT_ENABLE, 1); + if (BNX2X_CHIP_IS_E2(cp->chip_id)) + cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, + status_idx, IGU_INT_ENABLE, 1); + else + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, + status_idx, IGU_INT_ENABLE, 1); } static int cnic_service_bnx2x(void *data, void *status_blk) @@ -4208,7 +4236,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u32 base, addr, val; + u32 base, base2, addr, val; int port = CNIC_PORT(cp); dev->max_iscsi_conn = 0; @@ -4216,6 +4244,8 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) if (base == 0) return; + base2 = CNIC_RD(dev, (CNIC_PATH(cp) ? MISC_REG_GENERIC_CR_1 : + MISC_REG_GENERIC_CR_0)); addr = BNX2X_SHMEM_ADDR(base, dev_info.port_hw_config[port].iscsi_mac_upper); @@ -4248,11 +4278,15 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) val16 ^= 0x1e1e; dev->max_iscsi_conn = val16; } - if (BNX2X_CHIP_IS_E1H(cp->chip_id)) { + if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) { int func = CNIC_FUNC(cp); u32 mf_cfg_addr; - mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; + if (BNX2X_SHMEM2_HAS(base2, mf_cfg_addr)) + mf_cfg_addr = CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base2, + mf_cfg_addr)); + else + mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; addr = mf_cfg_addr + offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); @@ -4277,9 +4311,22 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) struct cnic_eth_dev *ethdev = cp->ethdev; int func = CNIC_FUNC(cp), ret, i; u32 pfid; - struct host_hc_status_block_e1x *sb = cp->status_blk.gen; - cp->pfid = func; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); + + if (!(val & 1)) + val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN); + else + val = (val >> 1) & 1; + + if (val) + cp->pfid = func >> 1; + else + cp->pfid = func & 0x6; + } else { + cp->pfid = func; + } pfid = cp->pfid; ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ, @@ -4294,10 +4341,21 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; - cp->kcq1.hw_prod_idx_ptr = - &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; - cp->kcq1.status_idx_ptr = - &sb->sb.running_index[SM_RX_ID]; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + struct host_hc_status_block_e2 *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } else { + struct host_hc_status_block_e1x *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } cnic_get_bnx2x_iscsi_info(dev); @@ -4380,7 +4438,9 @@ static void cnic_init_rings(struct cnic_dev *dev) cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); off = BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli); + (BNX2X_CHIP_IS_E2(cp->chip_id) ? + USTORM_RX_PRODS_E2_OFFSET(cl_qzone_id) : + USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli)); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]); @@ -4506,7 +4566,6 @@ static int cnic_start_hw(struct cnic_dev *dev) return -EALREADY; dev->regview = ethdev->io_base; - cp->chip_id = ethdev->chip_id; pci_dev_get(dev->pcidev); cp->func = PCI_FUNC(dev->pcidev->devfn); cp->status_blk.gen = ethdev->irq_arr[0].status_blk; @@ -4683,6 +4742,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) cp = cdev->cnic_priv; cp->ethdev = ethdev; cdev->pcidev = pdev; + cp->chip_id = ethdev->chip_id; cp->cnic_ops = &cnic_bnx2_ops; cp->start_hw = cnic_start_bnx2_hw; @@ -4737,6 +4797,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cp = cdev->cnic_priv; cp->ethdev = ethdev; cdev->pcidev = pdev; + cp->chip_id = ethdev->chip_id; cp->cnic_ops = &cnic_bnx2x_ops; cp->start_hw = cnic_start_bnx2x_hw; @@ -4748,7 +4809,10 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cp->stop_cm = cnic_cm_stop_bnx2x_hw; cp->enable_int = cnic_enable_bnx2x_int; cp->disable_int_sync = cnic_disable_bnx2x_int_sync; - cp->ack_int = cnic_ack_bnx2x_msix; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) + cp->ack_int = cnic_ack_bnx2x_e2_msix; + else + cp->ack_int = cnic_ack_bnx2x_msix; cp->close_conn = cnic_close_bnx2x_conn; cp->next_idx = cnic_bnx2x_next_idx; cp->hw_idx = cnic_bnx2x_hw_idx; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 928af9e64824..6a4a0ae5cfe3 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -372,15 +372,35 @@ struct bnx2x_bd_chain_next { #define BNX2X_ISCSI_PBL_NOT_CACHED 0xff #define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff +#define BNX2X_CHIP_NUM_57710 0x164e #define BNX2X_CHIP_NUM_57711 0x164f #define BNX2X_CHIP_NUM_57711E 0x1650 +#define BNX2X_CHIP_NUM_57712 0x1662 +#define BNX2X_CHIP_NUM_57712E 0x1663 +#define BNX2X_CHIP_NUM_57713 0x1651 +#define BNX2X_CHIP_NUM_57713E 0x1652 + #define BNX2X_CHIP_NUM(x) (x >> 16) +#define BNX2X_CHIP_IS_57710(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57710) #define BNX2X_CHIP_IS_57711(x) \ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711) #define BNX2X_CHIP_IS_57711E(x) \ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711E) #define BNX2X_CHIP_IS_E1H(x) \ (BNX2X_CHIP_IS_57711(x) || BNX2X_CHIP_IS_57711E(x)) +#define BNX2X_CHIP_IS_57712(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712) +#define BNX2X_CHIP_IS_57712E(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712E) +#define BNX2X_CHIP_IS_57713(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713) +#define BNX2X_CHIP_IS_57713E(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713E) +#define BNX2X_CHIP_IS_E2(x) \ + (BNX2X_CHIP_IS_57712(x) || BNX2X_CHIP_IS_57712E(x) || \ + BNX2X_CHIP_IS_57713(x) || BNX2X_CHIP_IS_57713E(x)) + #define IS_E1H_OFFSET BNX2X_CHIP_IS_E1H(cp->chip_id) #define BNX2X_RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd)) @@ -409,6 +429,8 @@ struct bnx2x_bd_chain_next { #define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) +#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ + (CNIC_FUNC(cp) & 1)) #define CNIC_E1HVN(cp) ((cp)->pfid >> 1) #define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \ diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 98ebac52013e..0dbeaec4f03a 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.5" -#define CNIC_MODULE_RELDATE "September 29, 2010" +#define CNIC_MODULE_VERSION "2.2.6" +#define CNIC_MODULE_RELDATE "Oct 12, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3 From f32f837b75233588cd4f8542214a30915ab7847b Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 12 Oct 2010 22:20:34 +0000 Subject: ixgbe: remove unused functions Remove functions that are declared, but not used in the driver. This patch fixes warnings reported by `make namespacecheck` Reported by Stephen Hemminger CC: Stephen Hemminger Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 147 ------------------------ drivers/net/ixgbe/ixgbe_common.c | 45 -------- drivers/net/ixgbe/ixgbe_dcb.c | 219 ------------------------------------ drivers/net/ixgbe/ixgbe_dcb.h | 18 --- drivers/net/ixgbe/ixgbe_dcb_82598.c | 59 ---------- drivers/net/ixgbe/ixgbe_dcb_82598.h | 4 - drivers/net/ixgbe/ixgbe_dcb_82599.c | 57 ---------- drivers/net/ixgbe/ixgbe_dcb_82599.h | 6 - 8 files changed, 555 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index e80657c75506..344c5d6ae02a 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1414,92 +1414,6 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) return 0; } -/** - * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address - * @input: input stream to modify - * @src_addr_1: the first 4 bytes of the IP address to load - * @src_addr_2: the second 4 bytes of the IP address to load - * @src_addr_3: the third 4 bytes of the IP address to load - * @src_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 src_addr_1, u32 src_addr_2, - u32 src_addr_3, u32 src_addr_4) -{ - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = - (src_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] = - (src_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] = - (src_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] = - (src_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] = - (src_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] = - (src_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] = - (src_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] = - (src_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24; - - return 0; -} - -/** - * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address - * @input: input stream to modify - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 dst_addr_1, u32 dst_addr_2, - u32 dst_addr_3, u32 dst_addr_4) -{ - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = - (dst_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] = - (dst_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] = - (dst_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] = - (dst_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] = - (dst_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] = - (dst_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] = - (dst_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] = - (dst_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24; - - return 0; -} - /** * ixgbe_atr_set_src_port_82599 - Sets the source port * @input: input stream to modify @@ -1539,19 +1453,6 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) return 0; } -/** - * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, - u8 vm_pool) -{ - input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; - - return 0; -} - /** * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type * @input: input stream to modify @@ -1644,41 +1545,6 @@ static s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, return 0; } -/** - * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address - * @input: input stream to search - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 *dst_addr_1, u32 *dst_addr_2, - u32 *dst_addr_3, u32 *dst_addr_4) -{ - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12]; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24; - - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8]; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24; - - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4]; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24; - - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET]; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24; - - return 0; -} - /** * ixgbe_atr_get_src_port_82599 - Gets the source port * @input: input stream to modify @@ -1731,19 +1597,6 @@ static s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, return 0; } -/** - * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, - u8 *vm_pool) -{ - *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET]; - - return 0; -} - /** * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type * @input: input stream to modify diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 9595b1bfb8dd..939e60f43fb9 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2704,48 +2704,3 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return 0; } - -/** - * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from - * the EEPROM - * @hw: pointer to hardware structure - * @wwnn_prefix: the alternative WWNN prefix - * @wwpn_prefix: the alternative WWPN prefix - * - * This function will read the EEPROM from the alternative SAN MAC address - * block to check the support for the alternative WWNN/WWPN prefix support. - **/ -s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, - u16 *wwpn_prefix) -{ - u16 offset, caps; - u16 alt_san_mac_blk_offset; - - /* clear output first */ - *wwnn_prefix = 0xFFFF; - *wwpn_prefix = 0xFFFF; - - /* check if alternative SAN MAC is supported */ - hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, - &alt_san_mac_blk_offset); - - if ((alt_san_mac_blk_offset == 0) || - (alt_san_mac_blk_offset == 0xFFFF)) - goto wwn_prefix_out; - - /* check capability in alternative san mac address block */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; - hw->eeprom.ops.read(hw, offset, &caps); - if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) - goto wwn_prefix_out; - - /* get the corresponding prefix for WWNN/WWPN */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwnn_prefix); - - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwpn_prefix); - -wwn_prefix_out: - return 0; -} diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 9aea4f04bbd2..8bb9ddb6dffe 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -33,98 +33,6 @@ #include "ixgbe_dcb_82598.h" #include "ixgbe_dcb_82599.h" -/** - * ixgbe_dcb_config - Struct containing DCB settings. - * @dcb_config: Pointer to DCB config structure - * - * This function checks DCB rules for DCB settings. - * The following rules are checked: - * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%. - * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth - * Group must total 100. - * 3. A Traffic Class should not be set to both Link Strict Priority - * and Group Strict Priority. - * 4. Link strict Bandwidth Groups can only have link strict traffic classes - * with zero bandwidth. - */ -s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *dcb_config) -{ - struct tc_bw_alloc *p; - s32 ret_val = 0; - u8 i, j, bw = 0, bw_id; - u8 bw_sum[2][MAX_BW_GROUP]; - bool link_strict[2][MAX_BW_GROUP]; - - memset(bw_sum, 0, sizeof(bw_sum)); - memset(link_strict, 0, sizeof(link_strict)); - - /* First Tx, then Rx */ - for (i = 0; i < 2; i++) { - /* Check each traffic class for rule violation */ - for (j = 0; j < MAX_TRAFFIC_CLASS; j++) { - p = &dcb_config->tc_config[j].path[i]; - - bw = p->bwg_percent; - bw_id = p->bwg_id; - - if (bw_id >= MAX_BW_GROUP) { - ret_val = DCB_ERR_CONFIG; - goto err_config; - } - if (p->prio_type == prio_link) { - link_strict[i][bw_id] = true; - /* Link strict should have zero bandwidth */ - if (bw) { - ret_val = DCB_ERR_LS_BW_NONZERO; - goto err_config; - } - } else if (!bw) { - /* - * Traffic classes without link strict - * should have non-zero bandwidth. - */ - ret_val = DCB_ERR_TC_BW_ZERO; - goto err_config; - } - bw_sum[i][bw_id] += bw; - } - - bw = 0; - - /* Check each bandwidth group for rule violation */ - for (j = 0; j < MAX_BW_GROUP; j++) { - bw += dcb_config->bw_percentage[i][j]; - /* - * Sum of bandwidth percentages of all traffic classes - * within a Bandwidth Group must total 100 except for - * link strict group (zero bandwidth). - */ - if (link_strict[i][j]) { - if (bw_sum[i][j]) { - /* - * Link strict group should have zero - * bandwidth. - */ - ret_val = DCB_ERR_LS_BWG_NONZERO; - goto err_config; - } - } else if (bw_sum[i][j] != BW_PERCENT && - bw_sum[i][j] != 0) { - ret_val = DCB_ERR_TC_BW; - goto err_config; - } - } - - if (bw != BW_PERCENT) { - ret_val = DCB_ERR_BW_GROUP; - goto err_config; - } - } - -err_config: - return ret_val; -} - /** * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits * @ixgbe_dcb_config: Struct containing DCB settings. @@ -202,133 +110,6 @@ out: return ret_val; } -/** - * ixgbe_dcb_get_tc_stats - Returns status of each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); - return ret; -} - -/** - * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class - * hw - pointer to hardware structure - * stats - pointer to statistics structure - * tc_count - Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); - return ret; -} - -/** - * ixgbe_dcb_config_rx_arbiter - Config Rx arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Rx Data Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tx_desc_arbiter - Config Tx Desc arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Tx Descriptor Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tx_data_arbiter - Config Tx data arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Tx Data Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_pfc - Config priority flow control - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Priority Flow Control for each traffic class. - */ -s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tc_stats - Config traffic class statistics - * @hw: pointer to hardware structure - * - * Configure queue statistics registers, all queues belonging to same traffic - * class uses a single set of queue statistics counters. - */ -s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tc_stats_82598(hw); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tc_stats_82599(hw); - return ret; -} - /** * ixgbe_dcb_hw_config - Config and enable DCB * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 5caafd4afbc3..eb1059f09da0 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -149,27 +149,9 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ -/* DCB rule checking function.*/ -s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *config); - /* DCB credits calculation */ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8); -/* DCB PFC functions */ -s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *, struct ixgbe_dcb_config *g); -s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); - -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *); -s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *, struct ixgbe_dcb_config *); - /* DCB hw initialization */ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index f0e9279d4669..6e9c8bb16dde 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -31,65 +31,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82598.h" -/** - * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - - /* Statistics pertaining to each traffic class */ - for (tc = 0; tc < tc_count; tc++) { - /* Transmitted Packets */ - stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); - /* Transmitted Bytes */ - stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); - /* Received Packets */ - stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); - /* Received Bytes */ - stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); - } - - return 0; -} - -/** - * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - - for (tc = 0; tc < tc_count; tc++) { - /* Priority XOFF Transmitted */ - stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); - /* Priority XOFF Received */ - stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc)); - } - - return 0; -} - /** * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index cc728fa092e2..def907f6cf20 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -72,13 +72,9 @@ /* DCB PFC functions */ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); -s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *, - u8); /* DCB traffic class stats */ s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *); -s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *, - u8); /* DCB config arbiters */ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 25b02fb425ac..13647186a406 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -30,63 +30,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82599.h" -/** - * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - /* Statistics pertaining to each traffic class */ - for (tc = 0; tc < tc_count; tc++) { - /* Transmitted Packets */ - stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); - /* Transmitted Bytes */ - stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); - /* Received Packets */ - stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); - /* Received Bytes */ - stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); - } - - return 0; -} - -/** - * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - for (tc = 0; tc < tc_count; tc++) { - /* Priority XOFF Transmitted */ - stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); - /* Priority XOFF Received */ - stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc)); - } - - return 0; -} - /** * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 0f3f791e1e1d..88819b2e562e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -101,15 +101,9 @@ /* DCB PFC functions */ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count); /* DCB traffic class stats */ s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw); -s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count); /* DCB config arbiters */ s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, -- cgit v1.2.3 From 5d5b7c39cfdc459c079ed75b65a537f40ffb82da Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 12 Oct 2010 22:20:59 +0000 Subject: ixgbe: declare functions as static Following patch fixes warnings reported by `make namespacecheck` Reported by Stephen Hemminger CC: Stephen Hemminger Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 30 +++++++++++++++--------------- drivers/net/ixgbe/ixgbe_common.c | 5 +++-- drivers/net/ixgbe/ixgbe_common.h | 1 - drivers/net/ixgbe/ixgbe_dcb_82598.c | 8 ++++---- drivers/net/ixgbe/ixgbe_dcb_82598.h | 11 ----------- drivers/net/ixgbe/ixgbe_dcb_82599.c | 12 ++++++------ drivers/net/ixgbe/ixgbe_dcb_82599.h | 12 ------------ drivers/net/ixgbe/ixgbe_mbx.c | 19 +++---------------- drivers/net/ixgbe/ixgbe_mbx.h | 3 --- drivers/net/ixgbe/ixgbe_sriov.c | 17 +++++++++-------- drivers/net/ixgbe/ixgbe_sriov.h | 8 -------- 11 files changed, 40 insertions(+), 86 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 344c5d6ae02a..0bd8fbb5bfd0 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -39,20 +39,20 @@ #define IXGBE_82599_MC_TBL_SIZE 128 #define IXGBE_82599_VFT_TBL_SIZE 128 -void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, - ixgbe_link_speed speed, - bool autoneg, - bool autoneg_wait_to_complete); +static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete); static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, - bool autoneg_wait_to_complete); -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); +static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); @@ -369,7 +369,7 @@ out: * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ -s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { u32 autoc_reg; @@ -418,7 +418,7 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, * PHY states. This includes selectively shutting down the Tx * laser on the PHY, effectively halting physical link. **/ -void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); @@ -437,7 +437,7 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) * PHY states. This includes selectively turning on the Tx * laser on the PHY, effectively starting physical link. **/ -void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); @@ -460,7 +460,7 @@ void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) * end. This is consistent with true clause 37 autoneg, which also * involves a loss of signal. **/ -void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); @@ -729,7 +729,7 @@ out: * * Set the link speed in the AUTOC register and restarts link. **/ -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 939e60f43fb9..e3eca1316389 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -52,6 +52,7 @@ static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); /** * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx @@ -637,7 +638,7 @@ out: * Polls the status bit (bit 1) of the EERD or EEWR to determine when the * read or write is done respectively. **/ -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; @@ -2449,7 +2450,7 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) * return the VLVF index where this VLAN id should be placed * **/ -s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) +static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) { u32 bits = 0; u32 first_empty_slot = 0; diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 5cf15aa11cac..424c223437dc 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -52,7 +52,6 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 6e9c8bb16dde..50288bcadc59 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -78,7 +78,7 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, * * Configure Rx Data Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -135,7 +135,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -183,7 +183,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Data Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -296,7 +296,7 @@ out: * Configure queue statistics registers, all queues belonging to same traffic * class uses a single set of queue statistics counters. */ -s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) { u32 reg = 0; u8 i = 0; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index def907f6cf20..abc03ccfa088 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -73,17 +73,6 @@ /* DCB PFC functions */ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); - /* DCB hw initialization */ s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 13647186a406..67c219f86c3a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -37,7 +37,7 @@ * * Configure packet buffers for DCB mode. */ -s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret_val = 0; @@ -79,7 +79,7 @@ s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, * * Configure Rx Packet Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -134,7 +134,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -181,7 +181,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, * * Configure Tx Packet Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -302,7 +302,7 @@ out: * Configure queue statistics registers, all queues belonging to same traffic * class uses a single set of queue statistics counters. */ -s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) { u32 reg = 0; u8 i = 0; @@ -355,7 +355,7 @@ s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) * * Configure general DCB parameters. */ -s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) { u32 reg; u32 q; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 88819b2e562e..18d7fbf6c292 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -102,18 +102,6 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config); -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); - - /* DCB hw initialization */ s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *config); diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index d75f9148eb1f..435e0281e1f8 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -200,7 +200,8 @@ out: * returns SUCCESS if it successfully received a message notification and * copied it into the receive buffer. **/ -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; s32 ret_val = IXGBE_ERR_MBX; @@ -227,7 +228,7 @@ out: * returns SUCCESS if it successfully copied message into the buffer and * received an ack to that message within delay * timeout period **/ -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, +static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; @@ -247,20 +248,6 @@ out: return ret_val; } -/** - * ixgbe_init_mbx_ops_generic - Initialize MB function pointers - * @hw: pointer to the HW structure - * - * Setup the mailbox read and write message function pointers - **/ -void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - - mbx->ops.read_posted = ixgbe_read_posted_mbx; - mbx->ops.write_posted = ixgbe_write_posted_mbx; -} - static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) { u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index be7ab3309ab7..c5ae4b4da83a 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -83,12 +83,9 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16); s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16); s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); -void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); extern struct ixgbe_mbx_operations mbx_ops_82599; diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 49661a138e22..a6b720ae7fea 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -43,8 +43,8 @@ #include "ixgbe_sriov.h" -int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, - int entries, u16 *hash_list, u32 vf) +static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, + int entries, u16 *hash_list, u32 vf) { struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; struct ixgbe_hw *hw = &adapter->hw; @@ -104,13 +104,14 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) } } -int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) +static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, + u32 vf) { return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); } -void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) +static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) { u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); vmolr |= (IXGBE_VMOLR_ROMPE | @@ -134,7 +135,7 @@ static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf) IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); } -inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) +static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); @@ -162,8 +163,8 @@ inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) hw->mac.ops.clear_rar(hw, rar_entry); } -int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, - int vf, unsigned char *mac_addr) +static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, + int vf, unsigned char *mac_addr) { struct ixgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); @@ -197,7 +198,7 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) return 0; } -inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) +static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; u32 reg; diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h index 184730ecdfb6..9a424bb688c0 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ixgbe/ixgbe_sriov.h @@ -28,16 +28,8 @@ #ifndef _IXGBE_SRIOV_H_ #define _IXGBE_SRIOV_H_ -int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, - int entries, u16 *hash_list, u32 vf); void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter); -int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf); -void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe); -void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf); -void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf); void ixgbe_msg_task(struct ixgbe_adapter *adapter); -int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, - int vf, unsigned char *mac_addr); int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); -- cgit v1.2.3 From cd2638a86c7b90e77ce623c09de2a26177f2a5c1 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Tue, 12 Oct 2010 22:27:02 +0000 Subject: igb: add check for fiber/serdes devices to igb_set_spd_dplx; Signed-off-by: Carolyn Wyborny Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 55edcb74abf4..5b04eff2fd23 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -6115,6 +6115,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx) mac->autoneg = 0; + /* Fiber NIC's only allow 1000 Gbps Full duplex */ + if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) && + spddplx != (SPEED_1000 + DUPLEX_FULL)) { + dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n"); + return -EINVAL; + } + switch (spddplx) { case SPEED_10 + DUPLEX_HALF: mac->forced_speed_duplex = ADVERTISE_10_HALF; -- cgit v1.2.3 From 7662ff46b7b3678162ce125903115e4ab0607a2d Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 15 Oct 2010 09:27:38 -0700 Subject: ixgbe: DCB: remove DCB check config Remove a DCB check config from DCB configuration we continue to configure DCB even if it fails so don't even bother to check. Plus user space (lldpad) checks this before programming the hw anyways. Worse case is we program some values into the hw that don't make total sense resulting in incorrect bandwidth allocation. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 95dbf60c8169..790a0dae1247 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3374,7 +3374,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82598EB) netif_set_gso_max_size(adapter->netdev, 32768); - ixgbe_dcb_check_config(&adapter->dcb_cfg); ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); -- cgit v1.2.3 From 898c914a0871ea7e5557b77156d4358c0f15d98a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Oct 2010 14:02:53 +0200 Subject: ath9k: do not track cycle counter updates in powersave mode While the chip is in powersave mode, the cycle counter updates do not contain useful values. While the chip is in full sleep, the rx_clear signal stays high, indicating a busy medium. To ensure sane values, update cycle counters before going into powersave, and clear them right after switching back to awake. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index bcd3892dca8d..74ff51d4c339 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -121,6 +121,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) void ath9k_ps_wakeup(struct ath_softc *sc) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); @@ -129,18 +130,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); + /* + * While the hardware is asleep, the cycle counters contain no + * useful data. Better clear them now so that they don't mess up + * survey data results. + */ + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + spin_unlock(&common->cc_lock); + unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } void ath9k_ps_restore(struct ath_softc *sc) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (--sc->ps_usecount != 0) goto unlock; + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + spin_unlock(&common->cc_lock); + if (sc->ps_idle) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); else if (sc->ps_enabled && @@ -196,7 +212,8 @@ static void ath_update_survey_stats(struct ath_softc *sc) struct ath_cycle_counters *cc = &common->cc_survey; unsigned int div = common->clockrate * 1000; - ath_hw_cycle_counters_update(common); + if (ah->power_mode == ATH9K_PM_AWAKE) + ath_hw_cycle_counters_update(common); if (cc->cycles > 0) { survey->filled |= SURVEY_INFO_CHANNEL_TIME | -- cgit v1.2.3 From e49f913750bb8745085cc4c547912c330cd3eacb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Oct 2010 16:08:01 +0200 Subject: ath9k_hw: fix division by zero in the ANI monitor code The commit "ath9k_hw: remove code duplication in phy error counter handling" split off some duplicate code into a separate function, but did not have a return code for aborting ANI processing based on counter values. This introduced a divide by zero issue. This patch adds the missing return code check in ath9k_hw_ani_monitor Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 3aa8fb1ad77f..9297f574b71c 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -633,7 +633,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) REGWRITE_BUFFER_FLUSH(ah); } -static void ath9k_hw_ani_read_counters(struct ath_hw *ah) +static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); struct ar5416AniState *aniState = &ah->curchan->ani; @@ -646,10 +646,10 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah) ath_hw_cycle_counters_update(common); listenTime = ath_hw_get_listen_time(common); - if (listenTime < 0) { + if (listenTime <= 0) { ah->stats.ast_ani_lneg++; ath9k_ani_restart(ah); - return; + return false; } if (!use_new_ani(ah)) { @@ -683,7 +683,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); } - return; + return false; } ofdmPhyErrCnt = phyCnt1 - ofdm_base; @@ -695,7 +695,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah) ah->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; - + return true; } void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) @@ -711,7 +711,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) if (WARN_ON(!aniState)) return; - ath9k_hw_ani_read_counters(ah); + if (!ath9k_hw_ani_read_counters(ah)) + return; ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / aniState->listenTime; -- cgit v1.2.3 From 431c74821432a6078d54f08de7cd561f8ef8f1ba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Oct 2010 16:08:02 +0200 Subject: ath9k_hw: fix PHY counter overflow handling in ANI v1 PHY counter overflows need to be checked for the old ANI version, because of its use of interrupt based counter overflow reports when the counters exceed the configured thresholds. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 9297f574b71c..63ccb39cdcd4 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -664,7 +664,7 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { + if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { if (phyCnt1 < ofdm_base) { ath_print(common, ATH_DBG_ANI, "phyCnt1 0x%x, resetting " -- cgit v1.2.3 From 88eac2dad876a58b9c6a4c4805c3fc27b02c048f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Oct 2010 16:08:03 +0200 Subject: ath9k: add missing locking around ath9k_hw_proc_mib_event ath9k_hw_proc_mib_event updates the cycle counters, so it common->cc_lock must be acquired. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 74ff51d4c339..2c7f28e022b8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -779,7 +779,9 @@ irqreturn_t ath_isr(int irq, void *dev) * it will clear whatever condition caused * the interrupt. */ + spin_lock(&common->cc_lock); ath9k_hw_proc_mib_event(ah); + spin_unlock(&common->cc_lock); ath9k_hw_set_interrupts(ah, ah->imask); } -- cgit v1.2.3 From 772d5515635fef5bc7a9d0efee785b58b0181ee5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Oct 2010 16:43:26 +0200 Subject: ath9k: make rate control debugfs stats per station Move them to the same debugfs file that the other rc modules use. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 93 -------------------------- drivers/net/wireless/ath/ath9k/debug.h | 21 ------ drivers/net/wireless/ath/ath9k/rc.c | 115 ++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/rc.h | 11 ++++ 4 files changed, 124 insertions(+), 116 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 74a4570dc87f..7f764e3d1c0a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = { .owner = THIS_MODULE }; -void ath_debug_stat_rc(struct ath_softc *sc, int final_rate) -{ - struct ath_rc_stats *stats; - - stats = &sc->debug.stats.rcstats[final_rate]; - stats->success++; -} - -void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per) -{ - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix]; - - stats->xretries += xretries; - stats->retries += retries; - stats->per = per; -} - -static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char *buf; - unsigned int len = 0, max; - int i = 0; - ssize_t retval; - - if (sc->cur_rate_table == NULL) - return 0; - - max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1; - buf = kmalloc(max, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - len += sprintf(buf, "%6s %6s %6s " - "%10s %10s %10s %10s\n", - "HT", "MCS", "Rate", - "Success", "Retries", "XRetries", "PER"); - - for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { - u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; - char mcs[5]; - char htmode[5]; - int used_mcs = 0, used_htmode = 0; - - if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) { - used_mcs = snprintf(mcs, 5, "%d", - sc->cur_rate_table->info[i].ratecode); - - if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy)) - used_htmode = snprintf(htmode, 5, "HT40"); - else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy)) - used_htmode = snprintf(htmode, 5, "HT20"); - else - used_htmode = snprintf(htmode, 5, "????"); - } - - mcs[used_mcs] = '\0'; - htmode[used_htmode] = '\0'; - - len += snprintf(buf + len, max - len, - "%6s %6s %3u.%d: " - "%10u %10u %10u %10u\n", - htmode, - mcs, - ratekbps / 1000, - (ratekbps % 1000) / 100, - stats->success, - stats->retries, - stats->xretries, - stats->per); - } - - if (len > max) - len = max; - - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return retval; -} - -static const struct file_operations fops_rcstat = { - .read = read_file_rcstat, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE -}; - static const char * ath_wiphy_state_str(enum ath_wiphy_state state) { switch (state) { @@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah) sc, &fops_interrupt)) goto err; - if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_rcstat)) - goto err; - if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_wiphy)) goto err; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 822b6f3f23c5..bb0823242ba0 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -80,13 +80,6 @@ struct ath_interrupt_stats { u32 bb_watchdog; }; -struct ath_rc_stats { - u32 success; - u32 retries; - u32 xretries; - u8 per; -}; - /** * struct ath_tx_stats - Statistics about TX * @tx_pkts_all: No. of total frames transmitted, including ones that @@ -160,7 +153,6 @@ struct ath_rx_stats { struct ath_stats { struct ath_interrupt_stats istats; - struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; struct ath_rx_stats rxstats; }; @@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah); int ath9k_debug_create_root(void); void ath9k_debug_remove_root(void); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); -void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct ath_tx_status *ts); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); -void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per); #else @@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, { } -static inline void ath_debug_stat_rc(struct ath_softc *sc, - int final_rate) -{ -} - static inline void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, @@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, { } -static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per) -{ -} - #endif /* CONFIG_ATH9K_DEBUGFS */ #endif /* DEBUG_H */ diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index abebf2466a13..5db3a12356ec 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1026,6 +1026,16 @@ static bool ath_rc_update_per(struct ath_softc *sc, return state_change; } +static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, + int xretries, int retries, u8 per) +{ + struct ath_rc_stats *stats = &rc->rcstats[rix]; + + stats->xretries += xretries; + stats->retries += retries; + stats->per = per; +} + /* Update PER, RSSI and whatever else that the code thinks it is doing. If you can make sense of all this, you really need to go out more. */ @@ -1098,7 +1108,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ath_rc_priv->per_down_time = now_msec; } - ath_debug_stat_retries(sc, tx_rate, xretries, retries, + ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries, ath_rc_priv->per[tx_rate]); } @@ -1294,6 +1304,7 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_sort_validrates(rate_table, ath_rc_priv); ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; sc->cur_rate_table = rate_table; + ath_rc_priv->rate_table = rate_table; ath_print(common, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n", @@ -1340,6 +1351,15 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, /* mac80211 Rate Control callbacks */ /***********************************/ +static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) +{ + struct ath_rc_stats *stats; + + stats = &rc->rcstats[final_rate]; + stats->success++; +} + + static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) @@ -1419,7 +1439,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, } } - ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table, + ath_debug_stat_rc(ath_rc_priv, ath_rc_get_rateindex(sc->cur_rate_table, &tx_info->status.rates[final_ts_idx])); } @@ -1521,6 +1541,94 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, } } +#ifdef CONFIG_ATH9K_DEBUGFS + +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_rate_priv *rc = file->private_data; + char *buf; + unsigned int len = 0, max; + int i = 0; + ssize_t retval; + + if (rc->rate_table == NULL) + return 0; + + max = 80 + rc->rate_table->rate_cnt * 1024 + 1; + buf = kmalloc(max, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + len += sprintf(buf, "%6s %6s %6s " + "%10s %10s %10s %10s\n", + "HT", "MCS", "Rate", + "Success", "Retries", "XRetries", "PER"); + + for (i = 0; i < rc->rate_table->rate_cnt; i++) { + u32 ratekbps = rc->rate_table->info[i].ratekbps; + struct ath_rc_stats *stats = &rc->rcstats[i]; + char mcs[5]; + char htmode[5]; + int used_mcs = 0, used_htmode = 0; + + if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) { + used_mcs = snprintf(mcs, 5, "%d", + rc->rate_table->info[i].ratecode); + + if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy)) + used_htmode = snprintf(htmode, 5, "HT40"); + else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy)) + used_htmode = snprintf(htmode, 5, "HT20"); + else + used_htmode = snprintf(htmode, 5, "????"); + } + + mcs[used_mcs] = '\0'; + htmode[used_htmode] = '\0'; + + len += snprintf(buf + len, max - len, + "%6s %6s %3u.%d: " + "%10u %10u %10u %10u\n", + htmode, + mcs, + ratekbps / 1000, + (ratekbps % 1000) / 100, + stats->success, + stats->retries, + stats->xretries, + stats->per); + } + + if (len > max) + len = max; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + return retval; +} + +static const struct file_operations fops_rcstat = { + .read = read_file_rcstat, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE +}; + +static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, + struct dentry *dir) +{ + struct ath_rate_priv *rc = priv_sta; + debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); +} + +#endif /* CONFIG_ATH9K_DEBUGFS */ + static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { struct ath_wiphy *aphy = hw->priv; @@ -1567,6 +1675,9 @@ static struct rate_control_ops ath_rate_ops = { .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, .free_sta = ath_rate_free_sta, +#ifdef CONFIG_ATH9K_DEBUGFS + .add_sta_debugfs = ath_rate_add_sta_debugfs, +#endif }; int ath_rate_control_register(void) diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index fbb1d33ee4b7..2f46a2266ba1 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -176,6 +176,13 @@ struct ath_rateset { u8 rs_rates[ATH_RATE_MAX]; }; +struct ath_rc_stats { + u32 success; + u32 retries; + u32 xretries; + u8 per; +}; + /** * struct ath_rate_priv - Rate Control priv data * @state: RC state @@ -212,6 +219,10 @@ struct ath_rate_priv { struct ath_rateset neg_rates; struct ath_rateset neg_ht_rates; struct ath_rate_softc *asc; + const struct ath_rate_table *rate_table; + + struct dentry *debugfs_rcstats; + struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; }; #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) -- cgit v1.2.3 From 4e9900180eb72b3b22fc9742999045b11607eb24 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Oct 2010 16:43:27 +0200 Subject: ath9k: remove sc->cur_rate_table and sc->cur_rate_mode Set the rate table in the rc module properly based on band and HT capabilities instead, which was already partially done, but not for every mode. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/main.c | 35 ---------------------------------- drivers/net/wireless/ath/ath9k/rc.c | 24 ++++++++--------------- 3 files changed, 8 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4e81fe35aa3f..e435c1d38826 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -623,8 +623,6 @@ struct ath_softc { struct ath_rx rx; struct ath_tx tx; struct ath_beacon beacon; - const struct ath_rate_table *cur_rate_table; - enum wireless_mode cur_rate_mode; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ath_led radio_led; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2c7f28e022b8..3ff0e476c2b3 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -18,36 +18,6 @@ #include "ath9k.h" #include "btcoex.h" -static void ath_cache_conf_rate(struct ath_softc *sc, - struct ieee80211_conf *conf) -{ - switch (conf->channel->band) { - case IEEE80211_BAND_2GHZ: - if (conf_is_ht20(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT20; - else if (conf_is_ht40_minus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS; - else if (conf_is_ht40_plus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS; - else - sc->cur_rate_mode = ATH9K_MODE_11G; - break; - case IEEE80211_BAND_5GHZ: - if (conf_is_ht20(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT20; - else if (conf_is_ht40_minus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS; - else if (conf_is_ht40_plus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS; - else - sc->cur_rate_mode = ATH9K_MODE_11A; - break; - default: - BUG_ON(1); - break; - } -} - static void ath_update_txpow(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; @@ -306,7 +276,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, goto ps_restore; } - ath_cache_conf_rate(sc, &hw->conf); ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); @@ -1013,8 +982,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) * that changes the channel so update any state that * might change as a result. */ - ath_cache_conf_rate(sc, &hw->conf); - ath_update_txpow(sc); if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) @@ -1221,8 +1188,6 @@ static int ath9k_start(struct ieee80211_hw *hw) if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) ah->imask |= ATH9K_INT_CST; - ath_cache_conf_rate(sc, &hw->conf); - sc->sc_flags &= ~SC_OP_INVALID; /* Disable BMISS interrupt when we're not associated */ diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 5db3a12356ec..2d3a67fc9bbf 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -791,7 +791,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, */ try_per_rate = 4; - rate_table = sc->cur_rate_table; + rate_table = ath_rc_priv->rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); /* @@ -1048,7 +1048,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, int rate; u8 last_per; bool state_change = false; - const struct ath_rate_table *rate_table = sc->cur_rate_table; + const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; int size = ath_rc_priv->rate_table_size; if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) @@ -1150,7 +1150,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, u8 flags; u32 i = 0, rix; - rate_table = sc->cur_rate_table; + rate_table = ath_rc_priv->rate_table; /* * If the first rate is not the final index, there @@ -1231,7 +1231,6 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, ath_print(common, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode); - sc->cur_rate_mode = mode; return hw_rate_table[mode]; } @@ -1303,7 +1302,6 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->max_valid_rate = k; ath_rc_sort_validrates(rate_table, ath_rc_priv); ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; - sc->cur_rate_table = rate_table; ath_rc_priv->rate_table = rate_table; ath_print(common, ATH_DBG_CONFIG, @@ -1439,8 +1437,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, } } - ath_debug_stat_rc(ath_rc_priv, ath_rc_get_rateindex(sc->cur_rate_table, - &tx_info->status.rates[final_ts_idx])); + ath_debug_stat_rc(ath_rc_priv, + ath_rc_get_rateindex(ath_rc_priv->rate_table, + &tx_info->status.rates[final_ts_idx])); } static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, @@ -1480,14 +1479,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, /* Choose rate table first */ - if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || - (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { - rate_table = ath_choose_rate_table(sc, sband->band, - sta->ht_cap.ht_supported, is_cw40); - } else { - rate_table = hw_rate_table[sc->cur_rate_mode]; - } + rate_table = ath_choose_rate_table(sc, sband->band, + sta->ht_cap.ht_supported, is_cw40); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); @@ -1536,7 +1529,6 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, "Operating HT Bandwidth changed to: %d\n", sc->hw->conf.channel_type); - sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode]; } } } -- cgit v1.2.3 From d4659912b557e9f68c0ad8be14e2cafd3210dd16 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 14 Oct 2010 16:02:39 +0200 Subject: ath9k_hw: remove enum wireless_mode and its users The wireless mode bitfield was only used to detect 2.4 and 5 GHz support, which can be simplified by using ATH9K_HW_CAP_* capabilities. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++++---- drivers/net/wireless/ath/ath9k/hw.c | 34 +++------------------- drivers/net/wireless/ath/ath9k/hw.h | 15 ++-------- drivers/net/wireless/ath/ath9k/init.c | 12 ++++---- drivers/net/wireless/ath/ath9k/rc.c | 41 +++++---------------------- 5 files changed, 25 insertions(+), 89 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index bbb54bc28a44..3d7b97f1b3ae 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) { - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) { + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { priv->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_channels; priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; @@ -577,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) ARRAY_SIZE(ath9k_legacy_rates); } - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) { + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels; priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; priv->sbands[IEEE80211_BAND_5GHZ].n_channels = @@ -740,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) + sizeof(struct htc_frame_hdr) + 4; - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->sbands[IEEE80211_BAND_2GHZ]; - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->sbands[IEEE80211_BAND_5GHZ]; if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) setup_ht_cap(priv, &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) setup_ht_cap(priv, &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f5d79177770c..cc13ee117823 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1800,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) return -EINVAL; } - bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); - - if (eeval & AR5416_OPFLAGS_11A) { - set_bit(ATH9K_MODE_11A, pCap->wireless_modes); - if (ah->config.ht_enable) { - if (!(eeval & AR5416_OPFLAGS_N_5G_HT20)) - set_bit(ATH9K_MODE_11NA_HT20, - pCap->wireless_modes); - if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) { - set_bit(ATH9K_MODE_11NA_HT40PLUS, - pCap->wireless_modes); - set_bit(ATH9K_MODE_11NA_HT40MINUS, - pCap->wireless_modes); - } - } - } + if (eeval & AR5416_OPFLAGS_11A) + pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; - if (eeval & AR5416_OPFLAGS_11G) { - set_bit(ATH9K_MODE_11G, pCap->wireless_modes); - if (ah->config.ht_enable) { - if (!(eeval & AR5416_OPFLAGS_N_2G_HT20)) - set_bit(ATH9K_MODE_11NG_HT20, - pCap->wireless_modes); - if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) { - set_bit(ATH9K_MODE_11NG_HT40PLUS, - pCap->wireless_modes); - set_bit(ATH9K_MODE_11NG_HT40MINUS, - pCap->wireless_modes); - } - } - } + if (eeval & AR5416_OPFLAGS_11G) + pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); /* diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6b9233472fbf..d032939768b0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -164,18 +164,6 @@ enum ath_ini_subsys { ATH_INI_NUM_SPLIT, }; -enum wireless_mode { - ATH9K_MODE_11A = 0, - ATH9K_MODE_11G, - ATH9K_MODE_11NA_HT20, - ATH9K_MODE_11NG_HT20, - ATH9K_MODE_11NA_HT40PLUS, - ATH9K_MODE_11NA_HT40MINUS, - ATH9K_MODE_11NG_HT40PLUS, - ATH9K_MODE_11NG_HT40MINUS, - ATH9K_MODE_MAX, -}; - enum ath9k_hw_caps { ATH9K_HW_CAP_HT = BIT(0), ATH9K_HW_CAP_RFSILENT = BIT(1), @@ -190,11 +178,12 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_SGI_20 = BIT(10), ATH9K_HW_CAP_PAPRD = BIT(11), ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), + ATH9K_HW_CAP_2GHZ = BIT(13), + ATH9K_HW_CAP_5GHZ = BIT(14), }; struct ath9k_hw_capabilities { u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ - DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */ u16 total_queues; u16 keycache_size; u16 low_5ghz_chan, high_5ghz_chan; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index a4c5ed41b176..bc6c4df9712c 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -485,7 +485,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) ARRAY_SIZE(ath9k_5ghz_chantable) != ATH9K_NUM_CHANNELS); - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { channels = kmemdup(ath9k_2ghz_chantable, sizeof(ath9k_2ghz_chantable), GFP_KERNEL); if (!channels) @@ -500,7 +500,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) ARRAY_SIZE(ath9k_legacy_rates); } - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { channels = kmemdup(ath9k_5ghz_chantable, sizeof(ath9k_5ghz_chantable), GFP_KERNEL); if (!channels) { @@ -681,17 +681,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->rate_control_algorithm = "ath9k_rate_control"; #endif - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &sc->sbands[IEEE80211_BAND_5GHZ]; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); } diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 2d3a67fc9bbf..0cee90cf8dc9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = { 0, /* Phy rates allowed initially */ }; -static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = { - [ATH9K_MODE_11A] = &ar5416_11a_ratetable, - [ATH9K_MODE_11G] = &ar5416_11g_ratetable, - [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable, - [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable, - [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable, -}; - static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate); @@ -1200,38 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc, static const struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, enum ieee80211_band band, - bool is_ht, - bool is_cw_40) + bool is_ht) { - int mode = 0; struct ath_common *common = ath9k_hw_common(sc->sc_ah); switch(band) { case IEEE80211_BAND_2GHZ: - mode = ATH9K_MODE_11G; if (is_ht) - mode = ATH9K_MODE_11NG_HT20; - if (is_cw_40) - mode = ATH9K_MODE_11NG_HT40PLUS; - break; + return &ar5416_11ng_ratetable; + return &ar5416_11g_ratetable; case IEEE80211_BAND_5GHZ: - mode = ATH9K_MODE_11A; if (is_ht) - mode = ATH9K_MODE_11NA_HT20; - if (is_cw_40) - mode = ATH9K_MODE_11NA_HT40PLUS; - break; + return &ar5416_11na_ratetable; + return &ar5416_11a_ratetable; default: ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); return NULL; } - - BUG_ON(mode >= ATH9K_MODE_MAX); - - ath_print(common, ATH_DBG_CONFIG, - "Choosing rate table for mode: %d\n", mode); - - return hw_rate_table[mode]; } static void ath_rc_init(struct ath_softc *sc, @@ -1480,7 +1454,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, /* Choose rate table first */ rate_table = ath_choose_rate_table(sc, sband->band, - sta->ht_cap.ht_supported, is_cw40); + sta->ht_cap.ht_supported); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); @@ -1520,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) { rate_table = ath_choose_rate_table(sc, sband->band, - sta->ht_cap.ht_supported, - oper_cw40); + sta->ht_cap.ht_supported); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, oper_cw40, oper_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); -- cgit v1.2.3 From 4f329c043ba3495f0f97ec782948cbba7bd01047 Mon Sep 17 00:00:00 2001 From: Paul Fox Date: Wed, 13 Oct 2010 20:14:56 +0100 Subject: libertas: Communicate USB transfer errors The return code was being overwritten with -1. Useful for debugging. Signed-off-by: Paul Fox Signed-off-by: Daniel Drake Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 238de10a4b57..b70f0f490118 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -484,11 +484,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp) */ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) { - int ret = -1; + int ret; /* check if device is removed */ if (cardp->surprise_removed) { lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); + ret = -ENODEV; goto tx_ret; } @@ -501,7 +502,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); - ret = -1; } else { lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); ret = 0; -- cgit v1.2.3 From 94a40c0c6bcc47ceba12e0247c5a23fb1e6c81e4 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 14 Oct 2010 10:50:26 +0530 Subject: ath9k_htc: set probe request rx filter This patch enables to receive probe request frames on p2p client mode. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 1 + drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f12591f5d02a..55c80866dfc6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1454,6 +1454,7 @@ out: FIF_PSPOLL | \ FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC | \ + FIF_PROBE_REQ | \ FIF_FCSFAIL) static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index c99600aff76d..3d19b5bc937f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; - /* If not a STA, enable processing of Probe Requests */ - if (ah->opmode != NL80211_IFTYPE_STATION) + if (priv->rxfilter & FIF_PROBE_REQ) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* -- cgit v1.2.3 From 9ebad4ab87f2ffa6eca825327721e647c7457264 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 14 Oct 2010 13:41:35 +0200 Subject: radiotap: fix vendor namespace parsing There's a bug with radiotap vendor namespace parsing if you don't register for the given namespace extensions. Fix this by passing only the unknown vendor namespaces and the registered data to frontends, but not both. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/radiotap.c | 58 +++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index c774bc0f155e..dbe35e138e94 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next( { while (1) { int hit = 0; - int pad, align, size, subns, vnslen; + int pad, align, size, subns; uint32_t oui; /* if no more EXT bits, that's it */ @@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next( if (pad) iterator->_arg += align - pad; + if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { + int vnslen; + + if ((unsigned long)iterator->_arg + size - + (unsigned long)iterator->_rtheader > + (unsigned long)iterator->_max_length) + return -EINVAL; + + oui = (*iterator->_arg << 16) | + (*(iterator->_arg + 1) << 8) | + *(iterator->_arg + 2); + subns = *(iterator->_arg + 3); + + find_ns(iterator, oui, subns); + + vnslen = get_unaligned_le16(iterator->_arg + 4); + iterator->_next_ns_data = iterator->_arg + size + vnslen; + if (!iterator->current_namespace) + size += vnslen; + } + /* * this is what we will return to user, but we need to * move on first so next call has something fresh to test @@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next( /* these special ones are valid in each bitmap word */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: - iterator->_bitmap_shifter >>= 1; - iterator->_arg_index++; - iterator->_reset_on_ext = 1; - vnslen = get_unaligned_le16(iterator->this_arg + 4); - iterator->_next_ns_data = iterator->_arg + vnslen; - oui = (*iterator->this_arg << 16) | - (*(iterator->this_arg + 1) << 8) | - *(iterator->this_arg + 2); - subns = *(iterator->this_arg + 3); - - find_ns(iterator, oui, subns); - iterator->is_radiotap_ns = 0; - /* allow parsers to show this information */ + /* + * If parser didn't register this vendor + * namespace with us, allow it to show it + * as 'raw. Do do that, set argument index + * to vendor namespace. + */ iterator->this_arg_index = IEEE80211_RADIOTAP_VENDOR_NAMESPACE; - iterator->this_arg_size += vnslen; - if ((unsigned long)iterator->this_arg + - iterator->this_arg_size - - (unsigned long)iterator->_rtheader > - (unsigned long)(unsigned long)iterator->_max_length) - return -EINVAL; - hit = 1; - break; + if (!iterator->current_namespace) + hit = 1; + goto next_entry; case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: - iterator->_bitmap_shifter >>= 1; - iterator->_arg_index++; - iterator->_reset_on_ext = 1; iterator->current_namespace = &radiotap_ns; iterator->is_radiotap_ns = 1; - break; + goto next_entry; case IEEE80211_RADIOTAP_EXT: /* * bit 31 was set, there is more -- cgit v1.2.3 From 204a665ba390bca861ad7b1a061f3ccded0e7eab Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 14 Oct 2010 19:33:34 +0200 Subject: b43: N-PHY: replace N-specific radio_chanspec with common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.h | 1 + drivers/net/wireless/b43/phy_n.c | 55 +++++++++++++++-------------------- drivers/net/wireless/b43/phy_n.h | 7 ++--- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 6dcd0334ed02..0e6194228845 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -253,6 +253,7 @@ struct b43_phy { /* Current channel */ unsigned int channel; + u16 channel_freq; enum nl80211_channel_type channel_type; /* PHY TX errors counter. */ diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e532901246b6..3ade0191f319 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -81,21 +81,6 @@ static inline bool b43_channel_type_is_40mhz( channel_type == NL80211_CHAN_HT40PLUS); } -static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) -{ - return !chanspec->channel && !chanspec->sideband && - !chanspec->b_width && !chanspec->b_freq; -} - -static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1, - struct b43_chanspec *chanspec2) -{ - return (chanspec1->channel == chanspec2->channel && - chanspec1->sideband == chanspec2->sideband && - chanspec1->b_width == chanspec2->b_width && - chanspec1->b_freq == chanspec2->b_freq); -} - void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) {//TODO } @@ -788,7 +773,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - u8 channel = nphy->radio_chanspec.channel; + u8 channel = dev->phy.channel; int tone[2] = { 57, 58 }; u32 noise[2] = { 0x3FF, 0x3FF }; @@ -862,9 +847,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) gain[0] = 6; gain[1] = 6; } else { - tmp = 40370 - 315 * nphy->radio_chanspec.channel; + tmp = 40370 - 315 * dev->phy.channel; gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); - tmp = 23242 - 224 * nphy->radio_chanspec.channel; + tmp = 23242 - 224 * dev->phy.channel; gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); } } else { @@ -2090,12 +2075,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) u16 *rssical_phy_regs = NULL; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (b43_empty_chanspec(&nphy->rssical_chanspec_2G)) + if (!nphy->rssical_chanspec_2G.center_freq) return; rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; } else { - if (b43_empty_chanspec(&nphy->rssical_chanspec_5G)) + if (!nphy->rssical_chanspec_5G.center_freq) return; rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; @@ -2551,7 +2536,8 @@ static void b43_nphy_save_cal(struct b43_wldev *dev) txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); } - *iqcal_chanspec = nphy->radio_chanspec; + iqcal_chanspec->center_freq = dev->phy.channel_freq; + iqcal_chanspec->channel_type = dev->phy.channel_type; b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); if (nphy->hang_avoid) @@ -2572,12 +2558,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G)) + if (!nphy->iqcal_chanspec_2G.center_freq) return; table = nphy->cal_cache.txcal_coeffs_2G; loft = &nphy->cal_cache.txcal_coeffs_2G[5]; } else { - if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G)) + if (!nphy->iqcal_chanspec_5G.center_freq) return; table = nphy->cal_cache.txcal_coeffs_5G; loft = &nphy->cal_cache.txcal_coeffs_5G[5]; @@ -2822,7 +2808,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, nphy->txiqlocal_bestc); nphy->txiqlocal_coeffsvalid = true; - nphy->txiqlocal_chanspec = nphy->radio_chanspec; + nphy->txiqlocal_chanspec.center_freq = + dev->phy.channel_freq; + nphy->txiqlocal_chanspec.channel_type = + dev->phy.channel_type; } else { length = 11; if (dev->phy.rev < 3) @@ -2858,7 +2847,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev) bool equal = true; if (!nphy->txiqlocal_coeffsvalid || - b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec)) + nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq || + nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type) return; b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); @@ -3264,11 +3254,9 @@ int b43_phy_initn(struct b43_wldev *dev) do_rssi_cal = false; if (phy->rev >= 3) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - do_rssi_cal = - b43_empty_chanspec(&nphy->rssical_chanspec_2G); + do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq; else - do_rssi_cal = - b43_empty_chanspec(&nphy->rssical_chanspec_5G); + do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq; if (do_rssi_cal) b43_nphy_rssi_cal(dev); @@ -3280,9 +3268,9 @@ int b43_phy_initn(struct b43_wldev *dev) if (!((nphy->measure_hold & 0x6) != 0)) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G); + do_cal = !nphy->iqcal_chanspec_2G.center_freq; else - do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G); + do_cal = !nphy->iqcal_chanspec_5G.center_freq; if (nphy->mute) do_cal = false; @@ -3411,7 +3399,10 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, return -ESRCH; } - nphy->radio_chanspec.channel = channel->hw_value; + /* Channel is set later in common code, but we need to set it on our + own to let this function's subcalls work properly. */ + phy->channel = channel->hw_value; + phy->channel_freq = channel->center_freq; if (b43_channel_type_is_40mhz(phy->channel_type) != b43_channel_type_is_40mhz(channel_type)) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index e7acae278be0..f915c83b46d7 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -927,10 +927,8 @@ struct b43_wldev; struct b43_chanspec { - u8 channel; - u8 sideband; - u8 b_width; - u8 b_freq; + u16 center_freq; + enum nl80211_channel_type channel_type; }; struct b43_phy_n_iq_comp { @@ -984,7 +982,6 @@ struct b43_phy_n { u16 papd_epsilon_offset[2]; s32 preamble_override; u32 bb_mult_save; - struct b43_chanspec radio_chanspec; bool gain_boost; bool elna_gain_config; -- cgit v1.2.3 From 5818e989360b06d249cf1d88e7d4601ca70a7322 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 14 Oct 2010 19:33:35 +0200 Subject: b43: N-PHY: fix typo: read table when caching IQ LO calibration (do not write) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 3ade0191f319..dd9cfe58f762 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2538,7 +2538,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev) } iqcal_chanspec->center_freq = dev->phy.channel_freq; iqcal_chanspec->channel_type = dev->phy.channel_type; - b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); + b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table); if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 0); -- cgit v1.2.3 From 6db507ff9232cc3874306f7b25b399cb2cdc1675 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 14 Oct 2010 19:33:36 +0200 Subject: b43: N-PHY: put radio-specific code in separated file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/phy_n.c | 1 + drivers/net/wireless/b43/phy_n.h | 210 ----- drivers/net/wireless/b43/radio_2055.c | 1332 ++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2055.h | 254 ++++++ drivers/net/wireless/b43/tables_nphy.c | 1309 ------------------------------- drivers/net/wireless/b43/tables_nphy.h | 44 -- 7 files changed, 1588 insertions(+), 1563 deletions(-) create mode 100644 drivers/net/wireless/b43/radio_2055.c create mode 100644 drivers/net/wireless/b43/radio_2055.h diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 5e83b6f0a3a0..0398c7cd2d15 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -1,6 +1,7 @@ b43-y += main.o b43-y += tables.o b43-$(CONFIG_B43_NPHY) += tables_nphy.o +b43-$(CONFIG_B43_NPHY) += radio_2055.o b43-y += phy_common.o b43-y += phy_g.o b43-y += phy_a.o diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index dd9cfe58f762..284b54fde41d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -29,6 +29,7 @@ #include "b43.h" #include "phy_n.h" #include "tables_nphy.h" +#include "radio_2055.h" #include "main.h" struct nphy_txgains { diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index f915c83b46d7..c144e59a708b 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -714,216 +714,6 @@ #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) - -/* Broadcom 2055 radio registers */ - -#define B2055_GEN_SPARE 0x00 /* GEN spare */ -#define B2055_SP_PINPD 0x02 /* SP PIN PD */ -#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */ -#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */ -#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */ -#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */ -#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */ -#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */ -#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */ -#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */ -#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */ -#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */ -#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */ -#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */ -#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */ -#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */ -#define B2055_MASTER1 0x11 /* Master control 1 */ -#define B2055_MASTER2 0x12 /* Master control 2 */ -#define B2055_PD_LGEN 0x13 /* PD LGEN */ -#define B2055_PD_PLLTS 0x14 /* PD PLL TS */ -#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */ -#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */ -#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */ -#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */ -#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */ -#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */ -#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */ -#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */ -#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */ -#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */ -#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */ -#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */ -#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */ -#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */ -#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */ -#define B2055_CAL_MISC 0x24 /* CAL MISC */ -#define B2055_CAL_COUT 0x25 /* CAL Counter out */ -#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */ -#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */ -#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */ -#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */ -#define B2055_CAL_TS 0x2A /* CAL TS */ -#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */ -#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */ -#define B2055_PADDRV 0x2D /* PAD driver */ -#define B2055_XOCTL1 0x2E /* XO Control 1 */ -#define B2055_XOCTL2 0x2F /* XO Control 2 */ -#define B2055_XOREGUL 0x30 /* XO Regulator */ -#define B2055_XOMISC 0x31 /* XO misc */ -#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */ -#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */ -#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */ -#define B2055_PLL_REF 0x35 /* PLL reference */ -#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */ -#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */ -#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */ -#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */ -#define B2055_PLL_RCAL 0x3A /* PLL RCAL */ -#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */ -#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */ -#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */ -#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */ -#define B2055_RF_MMDSP 0x3F /* RF MMD spare */ -#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */ -#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */ -#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */ -#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */ -#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */ -#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */ -#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */ -#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */ -#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */ -#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */ -#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */ -#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */ -#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */ -#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */ -#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */ -#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */ -#define B2055_VCO_KVCO 0x50 /* VCO KVCO */ -#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */ -#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */ -#define B2055_VCO_REG 0x53 /* VCO Regulator */ -#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */ -#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */ -#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */ -#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */ -#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */ -#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */ -#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */ -#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */ -#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */ -#define B2055_LGEN_DIV 0x5D /* LGEN div */ -#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */ -#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */ -#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */ -#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */ -#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */ -#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */ -#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */ -#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */ -#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */ -#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */ -#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */ -#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */ -#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */ -#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */ -#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */ -#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */ -#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */ -#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */ -#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */ -#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */ -#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */ -#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */ -#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */ -#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */ -#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */ -#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */ -#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */ -#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */ -#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */ -#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */ -#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */ -#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */ -#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */ -#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */ -#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */ -#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */ -#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */ -#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */ -#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */ -#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */ -#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */ -#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */ -#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */ -#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */ -#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */ -#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */ -#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */ -#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */ -#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */ -#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */ -#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */ -#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */ -#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */ -#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */ -#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */ -#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */ -#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */ -#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */ -#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */ -#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */ -#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */ -#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */ -#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */ -#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */ -#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */ -#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */ -#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */ -#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */ -#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */ -#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */ -#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */ -#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */ -#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */ -#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */ -#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */ -#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */ -#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */ -#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */ -#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */ -#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */ -#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */ -#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */ -#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */ -#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */ -#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */ -#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */ -#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */ -#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */ -#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */ -#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */ -#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */ -#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */ -#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */ -#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */ -#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */ -#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */ -#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */ -#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */ -#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */ -#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */ -#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */ -#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */ -#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */ -#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */ -#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */ -#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */ -#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */ -#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */ -#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */ -#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */ -#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */ - - - struct b43_wldev; struct b43_chanspec { diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c new file mode 100644 index 000000000000..1b5316586cbf --- /dev/null +++ b/drivers/net/wireless/b43/radio_2055.c @@ -0,0 +1,1332 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n PHY and radio device data tables + + Copyright (c) 2008 Michael Buesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "radio_2055.h" +#include "phy_common.h" + +struct b2055_inittab_entry { + /* Value to write if we use the 5GHz band. */ + u16 ghz5; + /* Value to write if we use the 2.4GHz band. */ + u16 ghz2; + /* Flags */ + u8 flags; +#define B2055_INITTAB_ENTRY_OK 0x01 +#define B2055_INITTAB_UPLOAD 0x02 +}; +#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD +#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK + +static const struct b2055_inittab_entry b2055_inittab [] = { + [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, + [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, + [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, + [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, + [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, + [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, + [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, }, + [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, }, + [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, }, + [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, + [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, }, + [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, }, + [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, + [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, }, + [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, + [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, + [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, }, + [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, }, + [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, }, + [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, }, + [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, + [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, + [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, + [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, + [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, + [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, + [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, + [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, + [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, + [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, + [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, + [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, + [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, + [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, + [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, + [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, + [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, + [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, + [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, + [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, + [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, + [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, + [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, }, + [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, }, + [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, }, + [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, }, + [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, }, + [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, }, + [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, }, + [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, }, + [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, }, + [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \ + r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \ + .radio_pll_ref = r0, \ + .radio_rf_pllmod0 = r1, \ + .radio_rf_pllmod1 = r2, \ + .radio_vco_captail = r3, \ + .radio_vco_cal1 = r4, \ + .radio_vco_cal2 = r5, \ + .radio_pll_lfc1 = r6, \ + .radio_pll_lfr1 = r7, \ + .radio_pll_lfc2 = r8, \ + .radio_lgbuf_cenbuf = r9, \ + .radio_lgen_tune1 = r10, \ + .radio_lgen_tune2 = r11, \ + .radio_c1_lgbuf_atune = r12, \ + .radio_c1_lgbuf_gtune = r13, \ + .radio_c1_rx_rfr1 = r14, \ + .radio_c1_tx_pgapadtn = r15, \ + .radio_c1_tx_mxbgtrim = r16, \ + .radio_c2_lgbuf_atune = r17, \ + .radio_c2_lgbuf_gtune = r18, \ + .radio_c2_rx_rfr1 = r19, \ + .radio_c2_tx_pgapadtn = r20, \ + .radio_c2_tx_mxbgtrim = r21 + +#define PHYREGS(r0, r1, r2, r3, r4, r5) \ + .phy_regs.phy_bw1a = r0, \ + .phy_regs.phy_bw2 = r1, \ + .phy_regs.phy_bw3 = r2, \ + .phy_regs.phy_bw4 = r3, \ + .phy_regs.phy_bw5 = r4, \ + .phy_regs.phy_bw6 = r5 + +static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { + { .channel = 184, + .freq = 4920, /* MHz */ + .unk2 = 3280, + RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602), + }, + { .channel = 186, + .freq = 4930, /* MHz */ + .unk2 = 3287, + RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502), + }, + { .channel = 188, + .freq = 4940, /* MHz */ + .unk2 = 3293, + RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402), + }, + { .channel = 190, + .freq = 4950, /* MHz */ + .unk2 = 3300, + RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302), + }, + { .channel = 192, + .freq = 4960, /* MHz */ + .unk2 = 3307, + RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202), + }, + { .channel = 194, + .freq = 4970, /* MHz */ + .unk2 = 3313, + RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102), + }, + { .channel = 196, + .freq = 4980, /* MHz */ + .unk2 = 3320, + RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02), + }, + { .channel = 198, + .freq = 4990, /* MHz */ + .unk2 = 3327, + RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02), + }, + { .channel = 200, + .freq = 5000, /* MHz */ + .unk2 = 3333, + RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02), + }, + { .channel = 202, + .freq = 5010, /* MHz */ + .unk2 = 3340, + RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02), + }, + { .channel = 204, + .freq = 5020, /* MHz */ + .unk2 = 3347, + RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02), + }, + { .channel = 206, + .freq = 5030, /* MHz */ + .unk2 = 3353, + RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02), + }, + { .channel = 208, + .freq = 5040, /* MHz */ + .unk2 = 3360, + RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902), + }, + { .channel = 210, + .freq = 5050, /* MHz */ + .unk2 = 3367, + RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802), + }, + { .channel = 212, + .freq = 5060, /* MHz */ + .unk2 = 3373, + RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, + 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), + PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702), + }, + { .channel = 214, + .freq = 5070, /* MHz */ + .unk2 = 3380, + RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, + 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), + PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602), + }, + { .channel = 216, + .freq = 5080, /* MHz */ + .unk2 = 3387, + RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, + 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), + PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502), + }, + { .channel = 218, + .freq = 5090, /* MHz */ + .unk2 = 3393, + RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, + 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), + PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402), + }, + { .channel = 220, + .freq = 5100, /* MHz */ + .unk2 = 3400, + RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, + 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), + PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302), + }, + { .channel = 222, + .freq = 5110, /* MHz */ + .unk2 = 3407, + RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, + 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), + PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202), + }, + { .channel = 224, + .freq = 5120, /* MHz */ + .unk2 = 3413, + RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, + 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), + PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102), + }, + { .channel = 226, + .freq = 5130, /* MHz */ + .unk2 = 3420, + RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, + 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), + PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002), + }, + { .channel = 228, + .freq = 5140, /* MHz */ + .unk2 = 3427, + RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, + 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B), + PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01), + }, + { .channel = 32, + .freq = 5160, /* MHz */ + .unk2 = 3440, + RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, + 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), + PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01), + }, + { .channel = 34, + .freq = 5170, /* MHz */ + .unk2 = 3447, + RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, + 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), + PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01), + }, + { .channel = 36, + .freq = 5180, /* MHz */ + .unk2 = 3453, + RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, + 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), + PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01), + }, + { .channel = 38, + .freq = 5190, /* MHz */ + .unk2 = 3460, + RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, + 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), + PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01), + }, + { .channel = 40, + .freq = 5200, /* MHz */ + .unk2 = 3467, + RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, + 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), + PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901), + }, + { .channel = 42, + .freq = 5210, /* MHz */ + .unk2 = 3473, + RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, + 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), + PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801), + }, + { .channel = 44, + .freq = 5220, /* MHz */ + .unk2 = 3480, + RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, + 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), + PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701), + }, + { .channel = 46, + .freq = 5230, /* MHz */ + .unk2 = 3487, + RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, + 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), + PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601), + }, + { .channel = 48, + .freq = 5240, /* MHz */ + .unk2 = 3493, + RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, + 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), + PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501), + }, + { .channel = 50, + .freq = 5250, /* MHz */ + .unk2 = 3500, + RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, + 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), + PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401), + }, + { .channel = 52, + .freq = 5260, /* MHz */ + .unk2 = 3507, + RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, + 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), + PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301), + }, + { .channel = 54, + .freq = 5270, /* MHz */ + .unk2 = 3513, + RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, + 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), + PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201), + }, + { .channel = 56, + .freq = 5280, /* MHz */ + .unk2 = 3520, + RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, + 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), + PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101), + }, + { .channel = 58, + .freq = 5290, /* MHz */ + .unk2 = 3527, + RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, + 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), + PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001), + }, + { .channel = 60, + .freq = 5300, /* MHz */ + .unk2 = 3533, + RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, + 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), + PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001), + }, + { .channel = 62, + .freq = 5310, /* MHz */ + .unk2 = 3540, + RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, + 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), + PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01), + }, + { .channel = 64, + .freq = 5320, /* MHz */ + .unk2 = 3547, + RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, + 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), + PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01), + }, + { .channel = 66, + .freq = 5330, /* MHz */ + .unk2 = 3553, + RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, + 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), + PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01), + }, + { .channel = 68, + .freq = 5340, /* MHz */ + .unk2 = 3560, + RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, + 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), + PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01), + }, + { .channel = 70, + .freq = 5350, /* MHz */ + .unk2 = 3567, + RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, + 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), + PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01), + }, + { .channel = 72, + .freq = 5360, /* MHz */ + .unk2 = 3573, + RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, + 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), + PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01), + }, + { .channel = 74, + .freq = 5370, /* MHz */ + .unk2 = 3580, + RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, + 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), + PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901), + }, + { .channel = 76, + .freq = 5380, /* MHz */ + .unk2 = 3587, + RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, + 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), + PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801), + }, + { .channel = 78, + .freq = 5390, /* MHz */ + .unk2 = 3593, + RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, + 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), + PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701), + }, + { .channel = 80, + .freq = 5400, /* MHz */ + .unk2 = 3600, + RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, + 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), + PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601), + }, + { .channel = 82, + .freq = 5410, /* MHz */ + .unk2 = 3607, + RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, + 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), + PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501), + }, + { .channel = 84, + .freq = 5420, /* MHz */ + .unk2 = 3613, + RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, + 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), + PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501), + }, + { .channel = 86, + .freq = 5430, /* MHz */ + .unk2 = 3620, + RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, + 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), + PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401), + }, + { .channel = 88, + .freq = 5440, /* MHz */ + .unk2 = 3627, + RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, + 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), + PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301), + }, + { .channel = 90, + .freq = 5450, /* MHz */ + .unk2 = 3633, + RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, + 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), + PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201), + }, + { .channel = 92, + .freq = 5460, /* MHz */ + .unk2 = 3640, + RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, + 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), + PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101), + }, + { .channel = 94, + .freq = 5470, /* MHz */ + .unk2 = 3647, + RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, + 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), + PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001), + }, + { .channel = 96, + .freq = 5480, /* MHz */ + .unk2 = 3653, + RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01), + }, + { .channel = 98, + .freq = 5490, /* MHz */ + .unk2 = 3660, + RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01), + }, + { .channel = 100, + .freq = 5500, /* MHz */ + .unk2 = 3667, + RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01), + }, + { .channel = 102, + .freq = 5510, /* MHz */ + .unk2 = 3673, + RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01), + }, + { .channel = 104, + .freq = 5520, /* MHz */ + .unk2 = 3680, + RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01), + }, + { .channel = 106, + .freq = 5530, /* MHz */ + .unk2 = 3687, + RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01), + }, + { .channel = 108, + .freq = 5540, /* MHz */ + .unk2 = 3693, + RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01), + }, + { .channel = 110, + .freq = 5550, /* MHz */ + .unk2 = 3700, + RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901), + }, + { .channel = 112, + .freq = 5560, /* MHz */ + .unk2 = 3707, + RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801), + }, + { .channel = 114, + .freq = 5570, /* MHz */ + .unk2 = 3713, + RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701), + }, + { .channel = 116, + .freq = 5580, /* MHz */ + .unk2 = 3720, + RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701), + }, + { .channel = 118, + .freq = 5590, /* MHz */ + .unk2 = 3727, + RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601), + }, + { .channel = 120, + .freq = 5600, /* MHz */ + .unk2 = 3733, + RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, + 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501), + }, + { .channel = 122, + .freq = 5610, /* MHz */ + .unk2 = 3740, + RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, + 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401), + }, + { .channel = 124, + .freq = 5620, /* MHz */ + .unk2 = 3747, + RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301), + }, + { .channel = 126, + .freq = 5630, /* MHz */ + .unk2 = 3753, + RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201), + }, + { .channel = 128, + .freq = 5640, /* MHz */ + .unk2 = 3760, + RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201), + }, + { .channel = 130, + .freq = 5650, /* MHz */ + .unk2 = 3767, + RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101), + }, + { .channel = 132, + .freq = 5660, /* MHz */ + .unk2 = 3773, + RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001), + }, + { .channel = 134, + .freq = 5670, /* MHz */ + .unk2 = 3780, + RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01), + }, + { .channel = 136, + .freq = 5680, /* MHz */ + .unk2 = 3787, + RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01), + }, + { .channel = 138, + .freq = 5690, /* MHz */ + .unk2 = 3793, + RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01), + }, + { .channel = 140, + .freq = 5700, /* MHz */ + .unk2 = 3800, + RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01), + }, + { .channel = 142, + .freq = 5710, /* MHz */ + .unk2 = 3807, + RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01), + }, + { .channel = 144, + .freq = 5720, /* MHz */ + .unk2 = 3813, + RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01), + }, + { .channel = 145, + .freq = 5725, /* MHz */ + .unk2 = 3817, + RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01), + }, + { .channel = 146, + .freq = 5730, /* MHz */ + .unk2 = 3820, + RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01), + }, + { .channel = 147, + .freq = 5735, /* MHz */ + .unk2 = 3823, + RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01), + }, + { .channel = 148, + .freq = 5740, /* MHz */ + .unk2 = 3827, + RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901), + }, + { .channel = 149, + .freq = 5745, /* MHz */ + .unk2 = 3830, + RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901), + }, + { .channel = 150, + .freq = 5750, /* MHz */ + .unk2 = 3833, + RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901), + }, + { .channel = 151, + .freq = 5755, /* MHz */ + .unk2 = 3837, + RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801), + }, + { .channel = 152, + .freq = 5760, /* MHz */ + .unk2 = 3840, + RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801), + }, + { .channel = 153, + .freq = 5765, /* MHz */ + .unk2 = 3843, + RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801), + }, + { .channel = 154, + .freq = 5770, /* MHz */ + .unk2 = 3847, + RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701), + }, + { .channel = 155, + .freq = 5775, /* MHz */ + .unk2 = 3850, + RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701), + }, + { .channel = 156, + .freq = 5780, /* MHz */ + .unk2 = 3853, + RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601), + }, + { .channel = 157, + .freq = 5785, /* MHz */ + .unk2 = 3857, + RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601), + }, + { .channel = 158, + .freq = 5790, /* MHz */ + .unk2 = 3860, + RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601), + }, + { .channel = 159, + .freq = 5795, /* MHz */ + .unk2 = 3863, + RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501), + }, + { .channel = 160, + .freq = 5800, /* MHz */ + .unk2 = 3867, + RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501), + }, + { .channel = 161, + .freq = 5805, /* MHz */ + .unk2 = 3870, + RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401), + }, + { .channel = 162, + .freq = 5810, /* MHz */ + .unk2 = 3873, + RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401), + }, + { .channel = 163, + .freq = 5815, /* MHz */ + .unk2 = 3877, + RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401), + }, + { .channel = 164, + .freq = 5820, /* MHz */ + .unk2 = 3880, + RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301), + }, + { .channel = 165, + .freq = 5825, /* MHz */ + .unk2 = 3883, + RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301), + }, + { .channel = 166, + .freq = 5830, /* MHz */ + .unk2 = 3887, + RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201), + }, + { .channel = 168, + .freq = 5840, /* MHz */ + .unk2 = 3893, + RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201), + }, + { .channel = 170, + .freq = 5850, /* MHz */ + .unk2 = 3900, + RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101), + }, + { .channel = 172, + .freq = 5860, /* MHz */ + .unk2 = 3907, + RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001), + }, + { .channel = 174, + .freq = 5870, /* MHz */ + .unk2 = 3913, + RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01), + }, + { .channel = 176, + .freq = 5880, /* MHz */ + .unk2 = 3920, + RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01), + }, + { .channel = 178, + .freq = 5890, /* MHz */ + .unk2 = 3927, + RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01), + }, + { .channel = 180, + .freq = 5900, /* MHz */ + .unk2 = 3933, + RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01), + }, + { .channel = 182, + .freq = 5910, /* MHz */ + .unk2 = 3940, + RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01), + }, + { .channel = 1, + .freq = 2412, /* MHz */ + .unk2 = 3216, + RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, + 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), + PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304), + }, + { .channel = 2, + .freq = 2417, /* MHz */ + .unk2 = 3223, + RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, + 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), + PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104), + }, + { .channel = 3, + .freq = 2422, /* MHz */ + .unk2 = 3229, + RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, + 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), + PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04), + }, + { .channel = 4, + .freq = 2427, /* MHz */ + .unk2 = 3236, + RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, + 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), + PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04), + }, + { .channel = 5, + .freq = 2432, /* MHz */ + .unk2 = 3243, + RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, + 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), + PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04), + }, + { .channel = 6, + .freq = 2437, /* MHz */ + .unk2 = 3249, + RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, + 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), + PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804), + }, + { .channel = 7, + .freq = 2442, /* MHz */ + .unk2 = 3256, + RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, + 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), + PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604), + }, + { .channel = 8, + .freq = 2447, /* MHz */ + .unk2 = 3263, + RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, + 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), + PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404), + }, + { .channel = 9, + .freq = 2452, /* MHz */ + .unk2 = 3269, + RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, + 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), + PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104), + }, + { .channel = 10, + .freq = 2457, /* MHz */ + .unk2 = 3276, + RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, + 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), + PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04), + }, + { .channel = 11, + .freq = 2462, /* MHz */ + .unk2 = 3283, + RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, + 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), + PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04), + }, + { .channel = 12, + .freq = 2467, /* MHz */ + .unk2 = 3289, + RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, + 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), + PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04), + }, + { .channel = 13, + .freq = 2472, /* MHz */ + .unk2 = 3296, + RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, + 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), + PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904), + }, + { .channel = 14, + .freq = 2484, /* MHz */ + .unk2 = 3312, + RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, + 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), + PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404), + }, +}; + +void b2055_upload_inittab(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag) +{ + const struct b2055_inittab_entry *e; + unsigned int i; + u16 value; + + for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { + e = &(b2055_inittab[i]); + if (!(e->flags & B2055_INITTAB_ENTRY_OK)) + continue; + if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) { + if (ghz5) + value = e->ghz5; + else + value = e->ghz2; + b43_radio_write16(dev, i, value); + } + } +} + +const struct b43_nphy_channeltab_entry_rev2 * +b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) +{ + const struct b43_nphy_channeltab_entry_rev2 *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) { + e = &(b43_nphy_channeltab_rev2[i]); + if (e->channel == channel) + return e; + } + + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h new file mode 100644 index 000000000000..d9bfa0f21b72 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2055.h @@ -0,0 +1,254 @@ +#ifndef B43_RADIO_2055_H_ +#define B43_RADIO_2055_H_ + +#include + +#include "tables_nphy.h" + +#define B2055_GEN_SPARE 0x00 /* GEN spare */ +#define B2055_SP_PINPD 0x02 /* SP PIN PD */ +#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */ +#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */ +#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */ +#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */ +#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */ +#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */ +#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */ +#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */ +#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */ +#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */ +#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */ +#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */ +#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */ +#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */ +#define B2055_MASTER1 0x11 /* Master control 1 */ +#define B2055_MASTER2 0x12 /* Master control 2 */ +#define B2055_PD_LGEN 0x13 /* PD LGEN */ +#define B2055_PD_PLLTS 0x14 /* PD PLL TS */ +#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */ +#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */ +#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */ +#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */ +#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */ +#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */ +#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */ +#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */ +#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */ +#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */ +#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */ +#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */ +#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */ +#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */ +#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */ +#define B2055_CAL_MISC 0x24 /* CAL MISC */ +#define B2055_CAL_COUT 0x25 /* CAL Counter out */ +#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */ +#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */ +#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */ +#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */ +#define B2055_CAL_TS 0x2A /* CAL TS */ +#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */ +#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */ +#define B2055_PADDRV 0x2D /* PAD driver */ +#define B2055_XOCTL1 0x2E /* XO Control 1 */ +#define B2055_XOCTL2 0x2F /* XO Control 2 */ +#define B2055_XOREGUL 0x30 /* XO Regulator */ +#define B2055_XOMISC 0x31 /* XO misc */ +#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */ +#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */ +#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */ +#define B2055_PLL_REF 0x35 /* PLL reference */ +#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */ +#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */ +#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */ +#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */ +#define B2055_PLL_RCAL 0x3A /* PLL RCAL */ +#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */ +#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */ +#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */ +#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */ +#define B2055_RF_MMDSP 0x3F /* RF MMD spare */ +#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */ +#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */ +#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */ +#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */ +#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */ +#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */ +#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */ +#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */ +#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */ +#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */ +#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */ +#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */ +#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */ +#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */ +#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */ +#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */ +#define B2055_VCO_KVCO 0x50 /* VCO KVCO */ +#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */ +#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */ +#define B2055_VCO_REG 0x53 /* VCO Regulator */ +#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */ +#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */ +#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */ +#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */ +#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */ +#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */ +#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */ +#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */ +#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */ +#define B2055_LGEN_DIV 0x5D /* LGEN div */ +#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */ +#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */ +#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */ +#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */ +#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */ +#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */ +#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */ +#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */ +#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */ +#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */ +#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */ +#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */ +#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */ +#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */ +#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */ +#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */ +#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */ +#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */ +#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */ +#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */ +#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */ +#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */ +#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */ +#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */ +#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */ +#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */ +#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */ +#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */ +#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */ +#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */ +#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */ +#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */ +#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */ +#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */ +#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */ +#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */ +#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */ +#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */ +#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */ +#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */ +#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */ +#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */ +#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */ +#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */ +#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */ +#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */ +#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */ +#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */ +#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */ +#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */ +#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */ +#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */ +#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */ +#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */ +#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */ +#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */ +#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */ +#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */ +#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */ +#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */ +#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */ +#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */ +#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */ +#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */ +#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */ +#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */ +#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */ +#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */ +#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */ +#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */ +#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */ +#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */ +#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */ +#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */ +#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */ +#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */ +#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */ +#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */ +#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */ +#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */ +#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */ +#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */ +#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */ +#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */ +#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */ +#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */ +#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */ +#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */ +#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */ +#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */ +#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */ +#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */ +#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */ +#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */ +#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */ +#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */ +#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */ +#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */ +#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */ +#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */ +#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */ +#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */ +#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */ +#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */ +#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */ +#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */ +#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */ +#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */ +#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */ +#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */ +#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */ + +struct b43_nphy_channeltab_entry_rev2 { + /* The channel number */ + u8 channel; + /* The channel frequency in MHz */ + u16 freq; + /* An unknown value */ + u16 unk2; + /* Radio register values on channelswitch */ + u8 radio_pll_ref; + u8 radio_rf_pllmod0; + u8 radio_rf_pllmod1; + u8 radio_vco_captail; + u8 radio_vco_cal1; + u8 radio_vco_cal2; + u8 radio_pll_lfc1; + u8 radio_pll_lfr1; + u8 radio_pll_lfc2; + u8 radio_lgbuf_cenbuf; + u8 radio_lgen_tune1; + u8 radio_lgen_tune2; + u8 radio_c1_lgbuf_atune; + u8 radio_c1_lgbuf_gtune; + u8 radio_c1_rx_rfr1; + u8 radio_c1_tx_pgapadtn; + u8 radio_c1_tx_mxbgtrim; + u8 radio_c2_lgbuf_atune; + u8 radio_c2_lgbuf_gtune; + u8 radio_c2_rx_rfr1; + u8 radio_c2_tx_pgapadtn; + u8 radio_c2_tx_mxbgtrim; + /* PHY register values on channelswitch */ + struct b43_phy_n_sfo_cfg phy_regs; +}; + +/* Upload the default register value table. + * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz + * table is uploaded. If "ignore_uploadflag" is true, we upload any value + * and ignore the "UPLOAD" flag. */ +void b2055_upload_inittab(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag); + +#endif /* B43_RADIO_2055_H_ */ diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index e74b8eb5795c..cff7bd379ad8 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -27,1314 +27,6 @@ #include "phy_common.h" #include "phy_n.h" - -struct b2055_inittab_entry { - /* Value to write if we use the 5GHz band. */ - u16 ghz5; - /* Value to write if we use the 2.4GHz band. */ - u16 ghz2; - /* Flags */ - u8 flags; -#define B2055_INITTAB_ENTRY_OK 0x01 -#define B2055_INITTAB_UPLOAD 0x02 -}; -#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD -#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK - -static const struct b2055_inittab_entry b2055_inittab [] = { - [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, - [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, - [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, - [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, - [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, - [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, - [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, - [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, - [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, - [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, - [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, }, - [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, - [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, }, - [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, - [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, - [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, }, - [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, - [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, - [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, - [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, }, - [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, - [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, }, - [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, - [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, }, - [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, - [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, - [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, - [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, - [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, - [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, }, - [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, }, - [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, }, - [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, }, - [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, - [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, - [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, - [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, - [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, - [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, - [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, - [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, - [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, - [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, - [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, - [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, - [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, - [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, - [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, - [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, - [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, - [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, - [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, - [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, - [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, - [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, - [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, - [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, - [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, - [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, - [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, }, - [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, }, - [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, }, - [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, }, - [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, }, - [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, }, - [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, - [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, }, - [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, }, - [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, }, - [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, -}; - - -void b2055_upload_inittab(struct b43_wldev *dev, - bool ghz5, bool ignore_uploadflag) -{ - const struct b2055_inittab_entry *e; - unsigned int i; - u16 value; - - for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { - e = &(b2055_inittab[i]); - if (!(e->flags & B2055_INITTAB_ENTRY_OK)) - continue; - if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) { - if (ghz5) - value = e->ghz5; - else - value = e->ghz2; - b43_radio_write16(dev, i, value); - } - } -} - - -#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \ - r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \ - .radio_pll_ref = r0, \ - .radio_rf_pllmod0 = r1, \ - .radio_rf_pllmod1 = r2, \ - .radio_vco_captail = r3, \ - .radio_vco_cal1 = r4, \ - .radio_vco_cal2 = r5, \ - .radio_pll_lfc1 = r6, \ - .radio_pll_lfr1 = r7, \ - .radio_pll_lfc2 = r8, \ - .radio_lgbuf_cenbuf = r9, \ - .radio_lgen_tune1 = r10, \ - .radio_lgen_tune2 = r11, \ - .radio_c1_lgbuf_atune = r12, \ - .radio_c1_lgbuf_gtune = r13, \ - .radio_c1_rx_rfr1 = r14, \ - .radio_c1_tx_pgapadtn = r15, \ - .radio_c1_tx_mxbgtrim = r16, \ - .radio_c2_lgbuf_atune = r17, \ - .radio_c2_lgbuf_gtune = r18, \ - .radio_c2_rx_rfr1 = r19, \ - .radio_c2_tx_pgapadtn = r20, \ - .radio_c2_tx_mxbgtrim = r21 - -#define PHYREGS(r0, r1, r2, r3, r4, r5) \ - .phy_regs.phy_bw1a = r0, \ - .phy_regs.phy_bw2 = r1, \ - .phy_regs.phy_bw3 = r2, \ - .phy_regs.phy_bw4 = r3, \ - .phy_regs.phy_bw5 = r4, \ - .phy_regs.phy_bw6 = r5 - -static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { - { .channel = 184, - .freq = 4920, /* MHz */ - .unk2 = 3280, - RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602), - }, - { .channel = 186, - .freq = 4930, /* MHz */ - .unk2 = 3287, - RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502), - }, - { .channel = 188, - .freq = 4940, /* MHz */ - .unk2 = 3293, - RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402), - }, - { .channel = 190, - .freq = 4950, /* MHz */ - .unk2 = 3300, - RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302), - }, - { .channel = 192, - .freq = 4960, /* MHz */ - .unk2 = 3307, - RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202), - }, - { .channel = 194, - .freq = 4970, /* MHz */ - .unk2 = 3313, - RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102), - }, - { .channel = 196, - .freq = 4980, /* MHz */ - .unk2 = 3320, - RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02), - }, - { .channel = 198, - .freq = 4990, /* MHz */ - .unk2 = 3327, - RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02), - }, - { .channel = 200, - .freq = 5000, /* MHz */ - .unk2 = 3333, - RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02), - }, - { .channel = 202, - .freq = 5010, /* MHz */ - .unk2 = 3340, - RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02), - }, - { .channel = 204, - .freq = 5020, /* MHz */ - .unk2 = 3347, - RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02), - }, - { .channel = 206, - .freq = 5030, /* MHz */ - .unk2 = 3353, - RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02), - }, - { .channel = 208, - .freq = 5040, /* MHz */ - .unk2 = 3360, - RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902), - }, - { .channel = 210, - .freq = 5050, /* MHz */ - .unk2 = 3367, - RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802), - }, - { .channel = 212, - .freq = 5060, /* MHz */ - .unk2 = 3373, - RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, - 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702), - }, - { .channel = 214, - .freq = 5070, /* MHz */ - .unk2 = 3380, - RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, - 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602), - }, - { .channel = 216, - .freq = 5080, /* MHz */ - .unk2 = 3387, - RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, - 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502), - }, - { .channel = 218, - .freq = 5090, /* MHz */ - .unk2 = 3393, - RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, - 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402), - }, - { .channel = 220, - .freq = 5100, /* MHz */ - .unk2 = 3400, - RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, - 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302), - }, - { .channel = 222, - .freq = 5110, /* MHz */ - .unk2 = 3407, - RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, - 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202), - }, - { .channel = 224, - .freq = 5120, /* MHz */ - .unk2 = 3413, - RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, - 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102), - }, - { .channel = 226, - .freq = 5130, /* MHz */ - .unk2 = 3420, - RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, - 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002), - }, - { .channel = 228, - .freq = 5140, /* MHz */ - .unk2 = 3427, - RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, - 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B), - PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01), - }, - { .channel = 32, - .freq = 5160, /* MHz */ - .unk2 = 3440, - RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, - 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01), - }, - { .channel = 34, - .freq = 5170, /* MHz */ - .unk2 = 3447, - RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, - 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01), - }, - { .channel = 36, - .freq = 5180, /* MHz */ - .unk2 = 3453, - RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, - 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01), - }, - { .channel = 38, - .freq = 5190, /* MHz */ - .unk2 = 3460, - RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, - 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01), - }, - { .channel = 40, - .freq = 5200, /* MHz */ - .unk2 = 3467, - RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, - 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901), - }, - { .channel = 42, - .freq = 5210, /* MHz */ - .unk2 = 3473, - RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, - 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801), - }, - { .channel = 44, - .freq = 5220, /* MHz */ - .unk2 = 3480, - RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, - 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701), - }, - { .channel = 46, - .freq = 5230, /* MHz */ - .unk2 = 3487, - RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, - 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601), - }, - { .channel = 48, - .freq = 5240, /* MHz */ - .unk2 = 3493, - RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, - 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501), - }, - { .channel = 50, - .freq = 5250, /* MHz */ - .unk2 = 3500, - RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, - 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401), - }, - { .channel = 52, - .freq = 5260, /* MHz */ - .unk2 = 3507, - RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, - 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301), - }, - { .channel = 54, - .freq = 5270, /* MHz */ - .unk2 = 3513, - RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, - 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201), - }, - { .channel = 56, - .freq = 5280, /* MHz */ - .unk2 = 3520, - RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, - 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101), - }, - { .channel = 58, - .freq = 5290, /* MHz */ - .unk2 = 3527, - RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, - 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001), - }, - { .channel = 60, - .freq = 5300, /* MHz */ - .unk2 = 3533, - RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, - 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001), - }, - { .channel = 62, - .freq = 5310, /* MHz */ - .unk2 = 3540, - RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, - 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01), - }, - { .channel = 64, - .freq = 5320, /* MHz */ - .unk2 = 3547, - RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, - 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01), - }, - { .channel = 66, - .freq = 5330, /* MHz */ - .unk2 = 3553, - RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, - 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01), - }, - { .channel = 68, - .freq = 5340, /* MHz */ - .unk2 = 3560, - RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, - 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01), - }, - { .channel = 70, - .freq = 5350, /* MHz */ - .unk2 = 3567, - RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, - 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01), - }, - { .channel = 72, - .freq = 5360, /* MHz */ - .unk2 = 3573, - RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, - 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01), - }, - { .channel = 74, - .freq = 5370, /* MHz */ - .unk2 = 3580, - RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, - 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901), - }, - { .channel = 76, - .freq = 5380, /* MHz */ - .unk2 = 3587, - RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, - 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801), - }, - { .channel = 78, - .freq = 5390, /* MHz */ - .unk2 = 3593, - RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, - 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701), - }, - { .channel = 80, - .freq = 5400, /* MHz */ - .unk2 = 3600, - RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, - 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601), - }, - { .channel = 82, - .freq = 5410, /* MHz */ - .unk2 = 3607, - RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, - 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501), - }, - { .channel = 84, - .freq = 5420, /* MHz */ - .unk2 = 3613, - RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, - 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501), - }, - { .channel = 86, - .freq = 5430, /* MHz */ - .unk2 = 3620, - RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, - 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401), - }, - { .channel = 88, - .freq = 5440, /* MHz */ - .unk2 = 3627, - RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, - 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301), - }, - { .channel = 90, - .freq = 5450, /* MHz */ - .unk2 = 3633, - RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, - 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201), - }, - { .channel = 92, - .freq = 5460, /* MHz */ - .unk2 = 3640, - RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, - 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101), - }, - { .channel = 94, - .freq = 5470, /* MHz */ - .unk2 = 3647, - RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, - 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001), - }, - { .channel = 96, - .freq = 5480, /* MHz */ - .unk2 = 3653, - RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01), - }, - { .channel = 98, - .freq = 5490, /* MHz */ - .unk2 = 3660, - RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01), - }, - { .channel = 100, - .freq = 5500, /* MHz */ - .unk2 = 3667, - RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01), - }, - { .channel = 102, - .freq = 5510, /* MHz */ - .unk2 = 3673, - RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01), - }, - { .channel = 104, - .freq = 5520, /* MHz */ - .unk2 = 3680, - RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01), - }, - { .channel = 106, - .freq = 5530, /* MHz */ - .unk2 = 3687, - RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01), - }, - { .channel = 108, - .freq = 5540, /* MHz */ - .unk2 = 3693, - RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01), - }, - { .channel = 110, - .freq = 5550, /* MHz */ - .unk2 = 3700, - RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901), - }, - { .channel = 112, - .freq = 5560, /* MHz */ - .unk2 = 3707, - RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801), - }, - { .channel = 114, - .freq = 5570, /* MHz */ - .unk2 = 3713, - RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701), - }, - { .channel = 116, - .freq = 5580, /* MHz */ - .unk2 = 3720, - RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701), - }, - { .channel = 118, - .freq = 5590, /* MHz */ - .unk2 = 3727, - RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601), - }, - { .channel = 120, - .freq = 5600, /* MHz */ - .unk2 = 3733, - RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, - 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501), - }, - { .channel = 122, - .freq = 5610, /* MHz */ - .unk2 = 3740, - RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, - 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401), - }, - { .channel = 124, - .freq = 5620, /* MHz */ - .unk2 = 3747, - RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301), - }, - { .channel = 126, - .freq = 5630, /* MHz */ - .unk2 = 3753, - RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201), - }, - { .channel = 128, - .freq = 5640, /* MHz */ - .unk2 = 3760, - RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201), - }, - { .channel = 130, - .freq = 5650, /* MHz */ - .unk2 = 3767, - RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101), - }, - { .channel = 132, - .freq = 5660, /* MHz */ - .unk2 = 3773, - RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001), - }, - { .channel = 134, - .freq = 5670, /* MHz */ - .unk2 = 3780, - RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01), - }, - { .channel = 136, - .freq = 5680, /* MHz */ - .unk2 = 3787, - RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01), - }, - { .channel = 138, - .freq = 5690, /* MHz */ - .unk2 = 3793, - RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01), - }, - { .channel = 140, - .freq = 5700, /* MHz */ - .unk2 = 3800, - RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01), - }, - { .channel = 142, - .freq = 5710, /* MHz */ - .unk2 = 3807, - RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01), - }, - { .channel = 144, - .freq = 5720, /* MHz */ - .unk2 = 3813, - RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01), - }, - { .channel = 145, - .freq = 5725, /* MHz */ - .unk2 = 3817, - RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01), - }, - { .channel = 146, - .freq = 5730, /* MHz */ - .unk2 = 3820, - RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01), - }, - { .channel = 147, - .freq = 5735, /* MHz */ - .unk2 = 3823, - RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01), - }, - { .channel = 148, - .freq = 5740, /* MHz */ - .unk2 = 3827, - RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901), - }, - { .channel = 149, - .freq = 5745, /* MHz */ - .unk2 = 3830, - RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901), - }, - { .channel = 150, - .freq = 5750, /* MHz */ - .unk2 = 3833, - RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901), - }, - { .channel = 151, - .freq = 5755, /* MHz */ - .unk2 = 3837, - RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801), - }, - { .channel = 152, - .freq = 5760, /* MHz */ - .unk2 = 3840, - RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801), - }, - { .channel = 153, - .freq = 5765, /* MHz */ - .unk2 = 3843, - RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801), - }, - { .channel = 154, - .freq = 5770, /* MHz */ - .unk2 = 3847, - RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701), - }, - { .channel = 155, - .freq = 5775, /* MHz */ - .unk2 = 3850, - RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701), - }, - { .channel = 156, - .freq = 5780, /* MHz */ - .unk2 = 3853, - RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601), - }, - { .channel = 157, - .freq = 5785, /* MHz */ - .unk2 = 3857, - RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601), - }, - { .channel = 158, - .freq = 5790, /* MHz */ - .unk2 = 3860, - RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601), - }, - { .channel = 159, - .freq = 5795, /* MHz */ - .unk2 = 3863, - RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501), - }, - { .channel = 160, - .freq = 5800, /* MHz */ - .unk2 = 3867, - RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501), - }, - { .channel = 161, - .freq = 5805, /* MHz */ - .unk2 = 3870, - RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401), - }, - { .channel = 162, - .freq = 5810, /* MHz */ - .unk2 = 3873, - RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401), - }, - { .channel = 163, - .freq = 5815, /* MHz */ - .unk2 = 3877, - RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401), - }, - { .channel = 164, - .freq = 5820, /* MHz */ - .unk2 = 3880, - RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301), - }, - { .channel = 165, - .freq = 5825, /* MHz */ - .unk2 = 3883, - RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301), - }, - { .channel = 166, - .freq = 5830, /* MHz */ - .unk2 = 3887, - RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201), - }, - { .channel = 168, - .freq = 5840, /* MHz */ - .unk2 = 3893, - RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201), - }, - { .channel = 170, - .freq = 5850, /* MHz */ - .unk2 = 3900, - RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101), - }, - { .channel = 172, - .freq = 5860, /* MHz */ - .unk2 = 3907, - RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001), - }, - { .channel = 174, - .freq = 5870, /* MHz */ - .unk2 = 3913, - RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01), - }, - { .channel = 176, - .freq = 5880, /* MHz */ - .unk2 = 3920, - RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01), - }, - { .channel = 178, - .freq = 5890, /* MHz */ - .unk2 = 3927, - RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01), - }, - { .channel = 180, - .freq = 5900, /* MHz */ - .unk2 = 3933, - RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01), - }, - { .channel = 182, - .freq = 5910, /* MHz */ - .unk2 = 3940, - RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01), - }, - { .channel = 1, - .freq = 2412, /* MHz */ - .unk2 = 3216, - RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, - 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), - PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304), - }, - { .channel = 2, - .freq = 2417, /* MHz */ - .unk2 = 3223, - RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, - 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), - PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104), - }, - { .channel = 3, - .freq = 2422, /* MHz */ - .unk2 = 3229, - RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, - 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04), - }, - { .channel = 4, - .freq = 2427, /* MHz */ - .unk2 = 3236, - RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, - 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04), - }, - { .channel = 5, - .freq = 2432, /* MHz */ - .unk2 = 3243, - RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, - 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), - PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04), - }, - { .channel = 6, - .freq = 2437, /* MHz */ - .unk2 = 3249, - RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, - 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), - PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804), - }, - { .channel = 7, - .freq = 2442, /* MHz */ - .unk2 = 3256, - RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, - 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), - PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604), - }, - { .channel = 8, - .freq = 2447, /* MHz */ - .unk2 = 3263, - RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, - 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), - PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404), - }, - { .channel = 9, - .freq = 2452, /* MHz */ - .unk2 = 3269, - RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, - 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), - PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104), - }, - { .channel = 10, - .freq = 2457, /* MHz */ - .unk2 = 3276, - RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, - 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), - PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04), - }, - { .channel = 11, - .freq = 2462, /* MHz */ - .unk2 = 3283, - RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, - 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), - PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04), - }, - { .channel = 12, - .freq = 2467, /* MHz */ - .unk2 = 3289, - RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, - 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), - PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04), - }, - { .channel = 13, - .freq = 2472, /* MHz */ - .unk2 = 3296, - RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, - 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), - PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904), - }, - { .channel = 14, - .freq = 2484, /* MHz */ - .unk2 = 3312, - RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, - 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), - PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404), - }, -}; - -const struct b43_nphy_channeltab_entry_rev2 * -b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) -{ - const struct b43_nphy_channeltab_entry_rev2 *e; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) { - e = &(b43_nphy_channeltab_rev2[i]); - if (e->channel == channel) - return e; - } - - return NULL; -} - static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { }; @@ -1353,7 +45,6 @@ b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) return NULL; } - static const u8 b43_ntab_adjustpower0[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 3eedb869f492..cb06d397ea2d 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -3,7 +3,6 @@ #include - struct b43_phy_n_sfo_cfg { u16 phy_bw1a; u16 phy_bw2; @@ -13,40 +12,6 @@ struct b43_phy_n_sfo_cfg { u16 phy_bw6; }; -struct b43_nphy_channeltab_entry_rev2 { - /* The channel number */ - u8 channel; - /* The channel frequency in MHz */ - u16 freq; - /* An unknown value */ - u16 unk2; - /* Radio register values on channelswitch */ - u8 radio_pll_ref; - u8 radio_rf_pllmod0; - u8 radio_rf_pllmod1; - u8 radio_vco_captail; - u8 radio_vco_cal1; - u8 radio_vco_cal2; - u8 radio_pll_lfc1; - u8 radio_pll_lfr1; - u8 radio_pll_lfc2; - u8 radio_lgbuf_cenbuf; - u8 radio_lgen_tune1; - u8 radio_lgen_tune2; - u8 radio_c1_lgbuf_atune; - u8 radio_c1_lgbuf_gtune; - u8 radio_c1_rx_rfr1; - u8 radio_c1_tx_pgapadtn; - u8 radio_c1_tx_mxbgtrim; - u8 radio_c2_lgbuf_atune; - u8 radio_c2_lgbuf_gtune; - u8 radio_c2_rx_rfr1; - u8 radio_c2_tx_pgapadtn; - u8 radio_c2_tx_mxbgtrim; - /* PHY register values on channelswitch */ - struct b43_phy_n_sfo_cfg phy_regs; -}; - struct b43_nphy_channeltab_entry_rev3 { /* The channel number */ u8 channel; @@ -58,7 +23,6 @@ struct b43_nphy_channeltab_entry_rev3 { struct b43_phy_n_sfo_cfg phy_regs; }; - struct b43_wldev; struct nphy_txiqcal_ladder { @@ -82,14 +46,6 @@ struct nphy_rf_control_override_rev3 { u8 val_addr1; }; -/* Upload the default register value table. - * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz - * table is uploaded. If "ignore_uploadflag" is true, we upload any value - * and ignore the "UPLOAD" flag. */ -void b2055_upload_inittab(struct b43_wldev *dev, - bool ghz5, bool ignore_uploadflag); - - /* Get the NPHY Channel Switch Table entry for a channel. * Returns NULL on failure to find an entry. */ const struct b43_nphy_channeltab_entry_rev2 * -- cgit v1.2.3 From 886b42bf5e54098061c8bae3d5e292a8b6897401 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 14 Oct 2010 11:44:27 -0700 Subject: ath9k_hw: remove AR9003 2.0 support These chipsets will not hit the market, all customers will be on >= AR9003 2.2. This shaves down the ath9k_hw size by 24161 bytes (24 KB) on my system. Before: $ size drivers/net/wireless/ath/ath9k/ath9k_hw.ko text data bss dec hex filename 292328 616 1824 294768 47f70 drivers/net/wireless/ath/ath9k/ath9k_hw.ko $ du -b drivers/net/wireless/ath/ath9k/ath9k_hw.ko 5987825 drivers/net/wireless/ath/ath9k/ath9k_hw.ko After: $ size drivers/net/wireless/ath/ath9k/ath9k_hw.ko text data bss dec hex filename 277192 616 1824 279632 44450 drivers/net/wireless/ath/ath9k/ath9k_hw.ko $ du -b drivers/net/wireless/ath/ath9k/ath9k_hw.ko 5963664 drivers/net/wireless/ath/ath9k/ath9k_hw.ko Cc: Yixiang Li Cc: Don Breslin Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_2p0_initvals.h | 1784 -------------------- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 162 +- drivers/net/wireless/ath/ath9k/reg.h | 3 - 3 files changed, 26 insertions(+), 1923 deletions(-) delete mode 100644 drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h deleted file mode 100644 index d3375fc4ce8b..000000000000 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h +++ /dev/null @@ -1,1784 +0,0 @@ -/* - * Copyright (c) 2010 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef INITVALS_9003_2P0_H -#define INITVALS_9003_2P0_H - -/* AR9003 2.0 */ - -static const u32 ar9300_2p0_radio_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, - {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, - {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, - {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, -}; - -static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300Modes_fast_clock_2p0[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x03721821, 0x03721821}, - {0x0000a230, 0x0000000b, 0x00000016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; - -static const u32 ar9300_2p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00016000, 0x36db6db6}, - {0x00016004, 0x6db6db40}, - {0x00016008, 0x73f00000}, - {0x0001600c, 0x00000000}, - {0x00016040, 0x7f80fff8}, - {0x0001604c, 0x76d005b5}, - {0x00016050, 0x556cf031}, - {0x00016054, 0x13449440}, - {0x00016058, 0x0c51c92c}, - {0x0001605c, 0x3db7fffc}, - {0x00016060, 0xfffffffc}, - {0x00016064, 0x000f0278}, - {0x0001606c, 0x6db60000}, - {0x00016080, 0x00000000}, - {0x00016084, 0x0e48048c}, - {0x00016088, 0x54214514}, - {0x0001608c, 0x119f481e}, - {0x00016090, 0x24926490}, - {0x00016098, 0xd2888888}, - {0x000160a0, 0x0a108ffe}, - {0x000160a4, 0x812fc370}, - {0x000160a8, 0x423c8000}, - {0x000160b4, 0x92480080}, - {0x000160c0, 0x00adb6d0}, - {0x000160c4, 0x6db6db60}, - {0x000160c8, 0x6db6db6c}, - {0x000160cc, 0x01e6c000}, - {0x00016100, 0x3fffbe01}, - {0x00016104, 0xfff80000}, - {0x00016108, 0x00080010}, - {0x00016144, 0x02084080}, - {0x00016148, 0x00000000}, - {0x00016280, 0x058a0001}, - {0x00016284, 0x3d840208}, - {0x00016288, 0x05a20408}, - {0x0001628c, 0x00038c07}, - {0x00016290, 0x40000004}, - {0x00016294, 0x458aa14f}, - {0x00016380, 0x00000000}, - {0x00016384, 0x00000000}, - {0x00016388, 0x00800700}, - {0x0001638c, 0x00800700}, - {0x00016390, 0x00800700}, - {0x00016394, 0x00000000}, - {0x00016398, 0x00000000}, - {0x0001639c, 0x00000000}, - {0x000163a0, 0x00000001}, - {0x000163a4, 0x00000001}, - {0x000163a8, 0x00000000}, - {0x000163ac, 0x00000000}, - {0x000163b0, 0x00000000}, - {0x000163b4, 0x00000000}, - {0x000163b8, 0x00000000}, - {0x000163bc, 0x00000000}, - {0x000163c0, 0x000000a0}, - {0x000163c4, 0x000c0000}, - {0x000163c8, 0x14021402}, - {0x000163cc, 0x00001402}, - {0x000163d0, 0x00000000}, - {0x000163d4, 0x00000000}, - {0x00016400, 0x36db6db6}, - {0x00016404, 0x6db6db40}, - {0x00016408, 0x73f00000}, - {0x0001640c, 0x00000000}, - {0x00016440, 0x7f80fff8}, - {0x0001644c, 0x76d005b5}, - {0x00016450, 0x556cf031}, - {0x00016454, 0x13449440}, - {0x00016458, 0x0c51c92c}, - {0x0001645c, 0x3db7fffc}, - {0x00016460, 0xfffffffc}, - {0x00016464, 0x000f0278}, - {0x0001646c, 0x6db60000}, - {0x00016500, 0x3fffbe01}, - {0x00016504, 0xfff80000}, - {0x00016508, 0x00080010}, - {0x00016544, 0x02084080}, - {0x00016548, 0x00000000}, - {0x00016780, 0x00000000}, - {0x00016784, 0x00000000}, - {0x00016788, 0x00800700}, - {0x0001678c, 0x00800700}, - {0x00016790, 0x00800700}, - {0x00016794, 0x00000000}, - {0x00016798, 0x00000000}, - {0x0001679c, 0x00000000}, - {0x000167a0, 0x00000001}, - {0x000167a4, 0x00000001}, - {0x000167a8, 0x00000000}, - {0x000167ac, 0x00000000}, - {0x000167b0, 0x00000000}, - {0x000167b4, 0x00000000}, - {0x000167b8, 0x00000000}, - {0x000167bc, 0x00000000}, - {0x000167c0, 0x000000a0}, - {0x000167c4, 0x000c0000}, - {0x000167c8, 0x14021402}, - {0x000167cc, 0x00001402}, - {0x000167d0, 0x00000000}, - {0x000167d4, 0x00000000}, - {0x00016800, 0x36db6db6}, - {0x00016804, 0x6db6db40}, - {0x00016808, 0x73f00000}, - {0x0001680c, 0x00000000}, - {0x00016840, 0x7f80fff8}, - {0x0001684c, 0x76d005b5}, - {0x00016850, 0x556cf031}, - {0x00016854, 0x13449440}, - {0x00016858, 0x0c51c92c}, - {0x0001685c, 0x3db7fffc}, - {0x00016860, 0xfffffffc}, - {0x00016864, 0x000f0278}, - {0x0001686c, 0x6db60000}, - {0x00016900, 0x3fffbe01}, - {0x00016904, 0xfff80000}, - {0x00016908, 0x00080010}, - {0x00016944, 0x02084080}, - {0x00016948, 0x00000000}, - {0x00016b80, 0x00000000}, - {0x00016b84, 0x00000000}, - {0x00016b88, 0x00800700}, - {0x00016b8c, 0x00800700}, - {0x00016b90, 0x00800700}, - {0x00016b94, 0x00000000}, - {0x00016b98, 0x00000000}, - {0x00016b9c, 0x00000000}, - {0x00016ba0, 0x00000001}, - {0x00016ba4, 0x00000001}, - {0x00016ba8, 0x00000000}, - {0x00016bac, 0x00000000}, - {0x00016bb0, 0x00000000}, - {0x00016bb4, 0x00000000}, - {0x00016bb8, 0x00000000}, - {0x00016bbc, 0x00000000}, - {0x00016bc0, 0x000000a0}, - {0x00016bc4, 0x000c0000}, - {0x00016bc8, 0x14021402}, - {0x00016bcc, 0x00001402}, - {0x00016bd0, 0x00000000}, - {0x00016bd4, 0x00000000}, -}; - -static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - -static const u32 ar9300_2p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; - -static const u32 ar9300_2p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, -}; - -static const u32 ar9200_merlin_2p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - -static const u32 ar9300_2p0_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, - {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, - {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, - {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, - {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, - {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, - {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, - {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, - {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, - {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, - {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, - {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, - {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, - {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, - {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, - {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, - {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, - {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, - {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, - {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, - {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, -}; - -static const u32 ar9300_2p0_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a9f6b}, - {0x0000980c, 0x04900000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x52440bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0xff55ff55}, - {0x00009c08, 0x0320ff55}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x9883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c0040b}, - {0x00009d18, 0x00000000}, - {0x00009e08, 0x0038230c}, - {0x00009e24, 0x990bb515}, - {0x00009e28, 0x0c6f0000}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e3c, 0xcf946222}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009e54, 0x00000000}, - {0x00009fc0, 0x803e4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x00009fd0, 0x01193b93}, - {0x0000a20c, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a22c, 0x01036a1e}, - {0x0000a234, 0x10000fff}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x00000000}, - {0x0000a3a8, 0xaaaaaaaa}, - {0x0000a3ac, 0x3c466478}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000246}, - {0x0000a3f8, 0x0cdbd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739ce}, - {0x0000a418, 0x2d001dce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000080}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a458, 0x00000000}, - {0x0000a600, 0x00000000}, - {0x0000a604, 0x00000000}, - {0x0000a608, 0x00000000}, - {0x0000a60c, 0x00000000}, - {0x0000a610, 0x00000000}, - {0x0000a614, 0x00000000}, - {0x0000a618, 0x00000000}, - {0x0000a61c, 0x00000000}, - {0x0000a620, 0x00000000}, - {0x0000a624, 0x00000000}, - {0x0000a628, 0x00000000}, - {0x0000a62c, 0x00000000}, - {0x0000a630, 0x00000000}, - {0x0000a634, 0x00000000}, - {0x0000a638, 0x00000000}, - {0x0000a63c, 0x00000000}, - {0x0000a640, 0x00000000}, - {0x0000a644, 0x3fad9d74}, - {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00000637}, - {0x0000a670, 0x03020100}, - {0x0000a674, 0x09080504}, - {0x0000a678, 0x0d0c0b0a}, - {0x0000a67c, 0x13121110}, - {0x0000a680, 0x31301514}, - {0x0000a684, 0x35343332}, - {0x0000a688, 0x00000036}, - {0x0000a690, 0x00000838}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000001}, - {0x0000a8d0, 0x004b6a8e}, - {0x0000a8d4, 0x00000820}, - {0x0000a8dc, 0x00000000}, - {0x0000a8f0, 0x00000000}, - {0x0000a8f4, 0x00000000}, - {0x0000b2d0, 0x00000080}, - {0x0000b2d4, 0x00000000}, - {0x0000b2dc, 0x00000000}, - {0x0000b2e0, 0x00000000}, - {0x0000b2e4, 0x00000000}, - {0x0000b2e8, 0x00000000}, - {0x0000b2ec, 0x00000000}, - {0x0000b2f0, 0x00000000}, - {0x0000b2f4, 0x00000000}, - {0x0000b2f8, 0x00000000}, - {0x0000b408, 0x0e79e5c0}, - {0x0000b40c, 0x00820820}, - {0x0000b420, 0x00000000}, - {0x0000b8d0, 0x004b6a8e}, - {0x0000b8d4, 0x00000820}, - {0x0000b8dc, 0x00000000}, - {0x0000b8f0, 0x00000000}, - {0x0000b8f4, 0x00000000}, - {0x0000c2d0, 0x00000080}, - {0x0000c2d4, 0x00000000}, - {0x0000c2dc, 0x00000000}, - {0x0000c2e0, 0x00000000}, - {0x0000c2e4, 0x00000000}, - {0x0000c2e8, 0x00000000}, - {0x0000c2ec, 0x00000000}, - {0x0000c2f0, 0x00000000}, - {0x0000c2f4, 0x00000000}, - {0x0000c2f8, 0x00000000}, - {0x0000c408, 0x0e79e5c0}, - {0x0000c40c, 0x00820820}, - {0x0000c420, 0x00000000}, -}; - -static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, - {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, - {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, -}; - -static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300Common_rx_gain_table_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300_2p0_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00020085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00000000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c20}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00000}, - {0x000080d8, 0x00400000}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486200}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c0, 0x00000000}, - {0x000081c4, 0x33332210}, - {0x000081c8, 0x00000000}, - {0x000081cc, 0x00000000}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008244, 0x0010f424}, - {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e848}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x98a00010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x00000007}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0x00ff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xaa48105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a0, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; - -static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9300_2p0_soc_preamble[][2] = { - /* Addr allmodes */ - {0x000040a4, 0x00a0c1c9}, - {0x00007008, 0x00000000}, - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, -}; - -static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08212e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08253e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08213e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -#endif /* INITVALS_9003_2P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 02c970819f79..c2a057156bfa 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -16,7 +16,6 @@ #include "hw.h" #include "ar9003_mac.h" -#include "ar9003_2p0_initvals.h" #include "ar9003_2p2_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion) return false; } -/* AR9003 2.0 */ -static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah) -{ - /* mac */ - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], - ar9300_2p0_mac_core, - ARRAY_SIZE(ar9300_2p0_mac_core), 2); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], - ar9300_2p0_mac_postamble, - ARRAY_SIZE(ar9300_2p0_mac_postamble), 5); - - /* bb */ - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], - ar9300_2p0_baseband_core, - ARRAY_SIZE(ar9300_2p0_baseband_core), 2); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], - ar9300_2p0_baseband_postamble, - ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5); - - /* radio */ - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], - ar9300_2p0_radio_core, - ARRAY_SIZE(ar9300_2p0_radio_core), 2); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], - ar9300_2p0_radio_postamble, - ARRAY_SIZE(ar9300_2p0_radio_postamble), 5); - - /* soc */ - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], - ar9300_2p0_soc_preamble, - ARRAY_SIZE(ar9300_2p0_soc_preamble), 2); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], - ar9300_2p0_soc_postamble, - ARRAY_SIZE(ar9300_2p0_soc_postamble), 5); - - /* rx/tx gain */ - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2); - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), - 5); - - /* Load PCIE SERDES settings from INI */ - - /* Awake Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9300PciePhy_pll_on_clkreq_disable_L1_2p0, - ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0), - 2); - - /* Sleep Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9300PciePhy_clkreq_enable_L1_2p0, - ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0), - 2); - - /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, - ar9300Modes_fast_clock_2p0, - ARRAY_SIZE(ar9300Modes_fast_clock_2p0), - 3); -} - -/* AR9003 2.2 */ -static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah) +/* + * The AR9003 family uses a new INI format (pre, core, post + * arrays per subsystem). This provides support for the + * AR9003 2.2 chipsets. + */ +static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah) 3); } -/* - * The AR9003 family uses a new INI format (pre, core, post - * arrays per subsystem). - */ -static void ar9003_hw_init_mode_regs(struct ath_hw *ah) -{ - if (AR_SREV_9300_20(ah)) - ar9003_2p0_hw_init_mode_regs(ah); - else - ar9003_2p2_hw_init_mode_regs(ah); -} - static void ar9003_tx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); break; case 1: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), + 5); break; case 2: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), + 5); break; } } @@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), - 2); + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), + 2); break; case 1: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), - 2); + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), + 2); break; } } diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 017617894533..42976b0a01c1 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -853,9 +853,6 @@ #define AR_SREV_9300(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) -#define AR_SREV_9300_20(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20)) #define AR_SREV_9300_20_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ -- cgit v1.2.3 From 5161bec5a8b3509b8cf69418129a191cf90bbd87 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 14 Oct 2010 21:16:33 +0200 Subject: b43: N-PHY: put 2056-radio's specific code in separated file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/phy_n.c | 1 + drivers/net/wireless/b43/radio_2056.c | 43 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/radio_2056.h | 42 +++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.c | 20 +--------------- drivers/net/wireless/b43/tables_nphy.h | 11 --------- 6 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 drivers/net/wireless/b43/radio_2056.c create mode 100644 drivers/net/wireless/b43/radio_2056.h diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 0398c7cd2d15..69d4af09a6cb 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -2,6 +2,7 @@ b43-y += main.o b43-y += tables.o b43-$(CONFIG_B43_NPHY) += tables_nphy.o b43-$(CONFIG_B43_NPHY) += radio_2055.o +b43-$(CONFIG_B43_NPHY) += radio_2056.o b43-y += phy_common.o b43-y += phy_g.o b43-y += phy_a.o diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 284b54fde41d..1bdf20c8c43b 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -30,6 +30,7 @@ #include "phy_n.h" #include "tables_nphy.h" #include "radio_2055.h" +#include "radio_2056.h" #include "main.h" struct nphy_txgains { diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c new file mode 100644 index 000000000000..d8563192ce56 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2056.c @@ -0,0 +1,43 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n 2056 radio device data tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "radio_2056.h" +#include "phy_common.h" + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { +}; + +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) +{ + const struct b43_nphy_channeltab_entry_rev3 *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) { + e = &(b43_nphy_channeltab_rev3[i]); + if (e->freq == freq) + return e; + } + + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h new file mode 100644 index 000000000000..fda6dafecb8c --- /dev/null +++ b/drivers/net/wireless/b43/radio_2056.h @@ -0,0 +1,42 @@ +/* + + Broadcom B43 wireless driver + + Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef B43_RADIO_2056_H_ +#define B43_RADIO_2056_H_ + +#include + +#include "tables_nphy.h" + +struct b43_nphy_channeltab_entry_rev3 { + /* The channel number */ + u8 channel; + /* The channel frequency in MHz */ + u16 freq; + /* Radio register values on channelswitch */ + /* TODO */ + /* PHY register values on channelswitch */ + struct b43_phy_n_sfo_cfg phy_regs; +}; + +#endif /* B43_RADIO_2056_H_ */ diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index cff7bd379ad8..d60db078eae2 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -1,7 +1,7 @@ /* Broadcom B43 wireless driver - IEEE 802.11n PHY and radio device data tables + IEEE 802.11n PHY data tables Copyright (c) 2008 Michael Buesch @@ -27,24 +27,6 @@ #include "phy_common.h" #include "phy_n.h" -static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { -}; - -const struct b43_nphy_channeltab_entry_rev3 * -b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) -{ - const struct b43_nphy_channeltab_entry_rev3 *e; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) { - e = &(b43_nphy_channeltab_rev3[i]); - if (e->freq == freq) - return e; - } - - return NULL; -} - static const u8 b43_ntab_adjustpower0[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index cb06d397ea2d..4ec593ba3eef 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -12,17 +12,6 @@ struct b43_phy_n_sfo_cfg { u16 phy_bw6; }; -struct b43_nphy_channeltab_entry_rev3 { - /* The channel number */ - u8 channel; - /* The channel frequency in MHz */ - u16 freq; - /* Radio register values on channelswitch */ - /* TODO */ - /* PHY register values on channelswitch */ - struct b43_phy_n_sfo_cfg phy_regs; -}; - struct b43_wldev; struct nphy_txiqcal_ladder { -- cgit v1.2.3 From c1739eb3e61e160f124bc842c219011916f63068 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 14 Oct 2010 12:45:29 -0700 Subject: ath9k: Remove bf_dmacontext. The bf_dmacontext seems to be totally useless and duplicated by bf_buf_addr. Remove it entirely, use bf_buf_addr in its place. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-- drivers/net/wireless/ath/ath9k/beacon.c | 16 +++++++--------- drivers/net/wireless/ath/ath9k/recv.c | 2 -- drivers/net/wireless/ath/ath9k/xmit.c | 11 ++++------- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e435c1d38826..973c919fdd27 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -239,12 +239,11 @@ struct ath_buf { struct sk_buff *bf_mpdu; /* enclosing frame structure */ void *bf_desc; /* virtual addr of desc */ dma_addr_t bf_daddr; /* physical addr of desc */ - dma_addr_t bf_buf_addr; /* physical addr of data buffer */ + dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ bool bf_stale; bool bf_tx_aborted; u16 bf_flags; struct ath_buf_state bf_state; - dma_addr_t bf_dmacontext; struct ath_wiphy *aphy; }; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 081192e78a46..af8fedda001b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -136,7 +136,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, bf = avp->av_bcbuf; skb = bf->bf_mpdu; if (skb) { - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); } @@ -162,9 +162,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } - bf->bf_buf_addr = bf->bf_dmacontext = - dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; @@ -252,7 +251,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { skb = bf->bf_mpdu; - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; @@ -296,9 +295,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) avp->tsf_adjust = cpu_to_le64(0); bf->bf_mpdu = skb; - bf->bf_buf_addr = bf->bf_dmacontext = - dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; @@ -324,7 +322,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { struct sk_buff *skb = bf->bf_mpdu; - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7c90eaf9ec55..2e427522672d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -363,7 +363,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) error = -ENOMEM; goto err; } - bf->bf_dmacontext = bf->bf_buf_addr; } sc->rx.rxlink = NULL; } @@ -1739,7 +1738,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ath_rx_send_to_mac80211(hw, sc, skb, rxs); break; } - bf->bf_dmacontext = bf->bf_buf_addr; /* * change the default rx antenna if rx diversity chooses the diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9b17108adc7c..b053058ae5ea 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -294,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) tbf->bf_buf_addr = bf->bf_buf_addr; memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); tbf->bf_state = bf->bf_state; - tbf->bf_dmacontext = bf->bf_dmacontext; return tbf; } @@ -1640,17 +1639,15 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_mpdu = skb; - bf->bf_dmacontext = dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { bf->bf_mpdu = NULL; ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, "dma_mapping_error() on TX\n"); return -ENOMEM; } - bf->bf_buf_addr = bf->bf_dmacontext; - bf->bf_tx_aborted = false; return 0; @@ -1914,7 +1911,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, tx_flags |= ATH_TX_XRETRY; } - dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); if (bf->bf_state.bfs_paprd) { if (time_after(jiffies, -- cgit v1.2.3 From 6cf9e995f91e5bbffb2bef85feef490e5b67605d Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 14 Oct 2010 12:45:30 -0700 Subject: ath9k: Null out references to stale pointers. This doesn't fix any problem that I'm aware of, but should make it harder to add use-after-free type bugs in the future. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 5 +++++ drivers/net/wireless/ath/ath9k/recv.c | 5 +++++ drivers/net/wireless/ath/ath9k/xmit.c | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index af8fedda001b..4ed010d4ef96 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -139,6 +139,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); + bf->bf_buf_addr = 0; } /* Get a new beacon from mac80211 */ @@ -167,6 +168,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n"); return NULL; @@ -255,6 +257,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; } /* NB: the beacon data buffer must be 32-bit aligned. */ @@ -300,6 +303,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error on beacon alloc\n"); return -ENOMEM; @@ -326,6 +330,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; } list_add_tail(&bf->list, &sc->beacon.bbuf); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 2e427522672d..fe73fc50082a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -268,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX init\n"); error = -ENOMEM; @@ -358,6 +359,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX init\n"); error = -ENOMEM; @@ -392,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc) common->rx_bufsize, DMA_FROM_DEVICE); dev_kfree_skb(skb); + bf->bf_buf_addr = 0; + bf->bf_mpdu = NULL; } } @@ -1733,6 +1737,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) bf->bf_buf_addr))) { dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX\n"); ath_rx_send_to_mac80211(hw, sc, skb, rxs); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b053058ae5ea..d077186da870 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1643,6 +1643,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, "dma_mapping_error() on TX\n"); return -ENOMEM; @@ -1912,6 +1913,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, } dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = 0; if (bf->bf_state.bfs_paprd) { if (time_after(jiffies, @@ -1924,6 +1926,10 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, ath_debug_stat_tx(sc, txq, bf, ts); ath_tx_complete(sc, skb, bf->aphy, tx_flags); } + /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't + * accidentally reference it later. + */ + bf->bf_mpdu = NULL; /* * Return the list of ath_buf of this mpdu to free queue -- cgit v1.2.3 From 0d91f22b75347d9503b17a42b6c74d3f7750acd6 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 15 Oct 2010 15:00:06 +0200 Subject: drivers/net/wireless/p54/eeprom.c: Return -ENOMEM on memory allocation failure In this code, 0 is returned on memory allocation failure, even though other failures return -ENOMEM or other similar values. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression ret; expression x,e1,e2,e3; @@ ret = 0 ... when != ret = e1 *x = \(kmalloc\|kcalloc\|kzalloc\)(...) ... when != ret = e2 if (x == NULL) { ... when != ret = e3 return ret; } // Signed-off-by: Julia Lawall Cc: Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/eeprom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 8c05266d37f4..35b09aa0529b 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -261,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) list->max_entries = max_channel_num; list->channels = kzalloc(sizeof(struct p54_channel_entry) * max_channel_num, GFP_KERNEL); - if (!list->channels) + if (!list->channels) { + ret = -ENOMEM; goto free; + } for (i = 0; i < max_channel_num; i++) { if (i < priv->iq_autocal_len) { -- cgit v1.2.3 From 6f0333b8fde44b8c04a53b2461504f0e8f1cebe6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Oct 2010 11:17:47 +0000 Subject: r8169: use 50% less ram for RX ring Using standard skb allocations in r8169 leads to order-3 allocations (if PAGE_SIZE=4096), because NIC needs 16383 bytes, and skb overhead makes this bigger than 16384 -> 32768 bytes per "skb" Using kmalloc() permits to reduce memory requirements of one r8169 nic by 4Mbytes. (256 frames * 16Kbytes). This is fine since a hardware bug requires us to copy incoming frames, so we build real skb when doing this copy. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/r8169.c | 183 ++++++++++++++++++---------------------------------- 1 file changed, 64 insertions(+), 119 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bc669a40ae96..1760533852a4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -187,12 +187,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); -/* - * we set our copybreak very high so that we don't have - * to allocate 16k frames all the time (see note in - * rtl8169_open() - */ -static int rx_copybreak = 16383; +static int rx_buf_sz = 16383; static int use_dac; static struct { u32 msg_enable; @@ -484,10 +479,8 @@ struct rtl8169_private { struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ dma_addr_t TxPhyAddr; dma_addr_t RxPhyAddr; - struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ + void *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ - unsigned align; - unsigned rx_buf_sz; struct timer_list timer; u16 cp_cmd; u16 intr_event; @@ -515,8 +508,6 @@ struct rtl8169_private { MODULE_AUTHOR("Realtek and the Linux r8169 crew "); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); -module_param(rx_copybreak, int, 0); -MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); @@ -3196,7 +3187,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= NETIF_F_GRO; tp->intr_mask = 0xffff; - tp->align = cfg->align; tp->hw_start = cfg->hw_start; tp->intr_event = cfg->intr_event; tp->napi_event = cfg->napi_event; @@ -3266,18 +3256,6 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, - unsigned int mtu) -{ - unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; - - if (max_frame != 16383) - printk(KERN_WARNING PFX "WARNING! Changing of MTU on this " - "NIC may lead to frame reception errors!\n"); - - tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; -} - static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3286,18 +3264,6 @@ static int rtl8169_open(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - /* - * Note that we use a magic value here, its wierd I know - * its done because, some subset of rtl8169 hardware suffers from - * a problem in which frames received that are longer than - * the size set in RxMaxSize register return garbage sizes - * when received. To avoid this we need to turn off filtering, - * which is done by setting a value of 16383 in the RxMaxSize register - * and allocating 16k frames to handle the largest possible rx value - * thats what the magic math below does. - */ - rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); - /* * Rx and Tx desscriptors needs 256 bytes alignment. * dma_alloc_coherent provides more. @@ -3474,7 +3440,7 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || @@ -3735,7 +3701,7 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; @@ -3915,7 +3881,7 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; @@ -3956,8 +3922,6 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) rtl8169_down(dev); - rtl8169_set_rxbufsize(tp, dev->mtu); - ret = rtl8169_init_ring(dev); if (ret < 0) goto out; @@ -3978,15 +3942,15 @@ static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); } -static void rtl8169_free_rx_skb(struct rtl8169_private *tp, - struct sk_buff **sk_buff, struct RxDesc *desc) +static void rtl8169_free_rx_databuff(struct rtl8169_private *tp, + void **data_buff, struct RxDesc *desc) { struct pci_dev *pdev = tp->pci_dev; - dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz, + dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), rx_buf_sz, PCI_DMA_FROMDEVICE); - dev_kfree_skb(*sk_buff); - *sk_buff = NULL; + kfree(*data_buff); + *data_buff = NULL; rtl8169_make_unusable_by_asic(desc); } @@ -4005,33 +3969,34 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, rtl8169_mark_to_asic(desc, rx_buf_sz); } -static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, +static inline void *rtl8169_align(void *data) +{ + return (void *)ALIGN((long)data, 16); +} + +static struct sk_buff *rtl8169_alloc_rx_data(struct pci_dev *pdev, struct net_device *dev, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align, gfp_t gfp) + struct RxDesc *desc) { - struct sk_buff *skb; + void *data; dma_addr_t mapping; - unsigned int pad; + int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; - pad = align ? align : NET_IP_ALIGN; + data = kmalloc_node(rx_buf_sz, GFP_KERNEL, node); + if (!data) + return NULL; - skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); - if (!skb) - goto err_out; - - skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); - - mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz, + if (rtl8169_align(data) != data) { + kfree(data); + data = kmalloc_node(rx_buf_sz + 15, GFP_KERNEL, node); + if (!data) + return NULL; + } + mapping = dma_map_single(&pdev->dev, rtl8169_align(data), rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); -out: - return skb; - -err_out: - rtl8169_make_unusable_by_asic(desc); - goto out; + return data; } static void rtl8169_rx_clear(struct rtl8169_private *tp) @@ -4039,8 +4004,8 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) unsigned int i; for (i = 0; i < NUM_RX_DESC; i++) { - if (tp->Rx_skbuff[i]) { - rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i, + if (tp->Rx_databuff[i]) { + rtl8169_free_rx_databuff(tp, tp->Rx_databuff + i, tp->RxDescArray + i); } } @@ -4052,21 +4017,21 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, u32 cur; for (cur = start; end - cur != 0; cur++) { - struct sk_buff *skb; + void *data; unsigned int i = cur % NUM_RX_DESC; WARN_ON((s32)(end - cur) < 0); - if (tp->Rx_skbuff[i]) + if (tp->Rx_databuff[i]) continue; - skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, - tp->RxDescArray + i, - tp->rx_buf_sz, tp->align, gfp); - if (!skb) + data = rtl8169_alloc_rx_data(tp->pci_dev, dev, + tp->RxDescArray + i); + if (!data) { + rtl8169_make_unusable_by_asic(tp->RxDescArray + i); break; - - tp->Rx_skbuff[i] = skb; + } + tp->Rx_databuff[i] = data; } return cur - start; } @@ -4088,7 +4053,7 @@ static int rtl8169_init_ring(struct net_device *dev) rtl8169_init_ring_indexes(tp); memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); - memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); + memset(tp->Rx_databuff, 0x0, NUM_RX_DESC * sizeof(void *)); if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) goto err_out; @@ -4473,27 +4438,23 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) skb_checksum_none_assert(skb); } -static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, - struct rtl8169_private *tp, int pkt_size, - dma_addr_t addr) +static struct sk_buff *rtl8169_try_rx_copy(void *data, + struct rtl8169_private *tp, + int pkt_size, + dma_addr_t addr) { struct sk_buff *skb; - bool done = false; - - if (pkt_size >= rx_copybreak) - goto out; - - skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size); - if (!skb) - goto out; + data = rtl8169_align(data); dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, PCI_DMA_FROMDEVICE); - skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); - *sk_buff = skb; - done = true; -out: - return done; + prefetch(data); + skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size); + if (skb) + memcpy(skb->data, data, pkt_size); + dma_sync_single_for_device(&tp->pci_dev->dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); + return skb; } /* @@ -4508,7 +4469,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, void __iomem *ioaddr, u32 budget) { unsigned int cur_rx, rx_left; - unsigned int delta, count; + unsigned int count; int polling = (budget != ~(u32)0) ? 1 : 0; cur_rx = tp->cur_rx; @@ -4537,12 +4498,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev, rtl8169_schedule_work(dev, rtl8169_reset_task); dev->stats.rx_fifo_errors++; } - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + rtl8169_mark_to_asic(desc, rx_buf_sz); } else { - struct sk_buff *skb = tp->Rx_skbuff[entry]; + struct sk_buff *skb; dma_addr_t addr = le64_to_cpu(desc->addr); int pkt_size = (status & 0x00001FFF) - 4; - struct pci_dev *pdev = tp->pci_dev; /* * The driver does not support incoming fragmented @@ -4552,18 +4512,16 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (unlikely(rtl8169_fragmented_frame(status))) { dev->stats.rx_dropped++; dev->stats.rx_length_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + rtl8169_mark_to_asic(desc, rx_buf_sz); continue; } - if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { - dma_sync_single_for_device(&pdev->dev, addr, - pkt_size, PCI_DMA_FROMDEVICE); - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - } else { - dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - tp->Rx_skbuff[entry] = NULL; + skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], + tp, pkt_size, addr); + rtl8169_mark_to_asic(desc, rx_buf_sz); + if (!skb) { + dev->stats.rx_dropped++; + continue; } rtl8169_rx_csum(skb, status); @@ -4592,20 +4550,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, count = cur_rx - tp->cur_rx; tp->cur_rx = cur_rx; - delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); - if (!delta && count) - netif_info(tp, intr, dev, "no Rx buffer allocated\n"); - tp->dirty_rx += delta; - - /* - * FIXME: until there is periodic timer to try and refill the ring, - * a temporary shortage may definitely kill the Rx process. - * - disable the asic to try and avoid an overflow and kick it again - * after refill ? - * - how do others driver handle this condition (Uh oh...). - */ - if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) - netif_emerg(tp, intr, dev, "Rx buffers exhausted\n"); + tp->dirty_rx += count; return count; } -- cgit v1.2.3 From 564824b0c52c34692d804bb6ea214451615b0b50 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 11 Oct 2010 19:05:25 +0000 Subject: net: allocate skbs on local node commit b30973f877 (node-aware skb allocation) spread a wrong habit of allocating net drivers skbs on a given memory node : The one closest to the NIC hardware. This is wrong because as soon as we try to scale network stack, we need to use many cpus to handle traffic and hit slub/slab management on cross-node allocations/frees when these cpus have to alloc/free skbs bound to a central node. skb allocated in RX path are ephemeral, they have a very short lifetime : Extra cost to maintain NUMA affinity is too expensive. What appeared as a nice idea four years ago is in fact a bad one. In 2010, NIC hardwares are multiqueue, or we use RPS to spread the load, and two 10Gb NIC might deliver more than 28 million packets per second, needing all the available cpus. Cost of cross-node handling in network and vm stacks outperforms the small benefit hardware had when doing its DMA transfert in its 'local' memory node at RX time. Even trying to differentiate the two allocations done for one skb (the sk_buff on local node, the data part on NIC hardware node) is not enough to bring good performance. Signed-off-by: Eric Dumazet Acked-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/skbuff.h | 20 ++++++++++++++++---- net/core/skbuff.c | 13 +------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 0b53c43ac92e..05a358f1ba11 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -496,13 +496,13 @@ extern struct sk_buff *__alloc_skb(unsigned int size, static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 0, -1); + return __alloc_skb(size, priority, 0, NUMA_NO_NODE); } static inline struct sk_buff *alloc_skb_fclone(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 1, -1); + return __alloc_skb(size, priority, 1, NUMA_NO_NODE); } extern bool skb_recycle_check(struct sk_buff *skb, int skb_size); @@ -1563,13 +1563,25 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, return skb; } -extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask); +/** + * __netdev_alloc_page - allocate a page for ps-rx on a specific device + * @dev: network device to receive on + * @gfp_mask: alloc_pages_node mask + * + * Allocate a new page. dev currently unused. + * + * %NULL is returned if there is no free memory. + */ +static inline struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask) +{ + return alloc_pages_node(NUMA_NO_NODE, gfp_mask, 0); +} /** * netdev_alloc_page - allocate a page for ps-rx on a specific device * @dev: network device to receive on * - * Allocate a new page node local to the specified device. + * Allocate a new page. dev currently unused. * * %NULL is returned if there is no free memory. */ diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 752c1972b3a7..4e8b82e167d8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -247,10 +247,9 @@ EXPORT_SYMBOL(__alloc_skb); struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, gfp_t gfp_mask) { - int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; struct sk_buff *skb; - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); + skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); skb->dev = dev; @@ -259,16 +258,6 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, } EXPORT_SYMBOL(__netdev_alloc_skb); -struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask) -{ - int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; - struct page *page; - - page = alloc_pages_node(node, gfp_mask, 0); - return page; -} -EXPORT_SYMBOL(__netdev_alloc_page); - void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size) { -- cgit v1.2.3 From 65495745d7d617893f368bf5580353f5d2d88908 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 12 Oct 2010 21:52:26 +0000 Subject: cxgb4vf: make single bit signed bitfields unsigned Single bit signed bitfields don't make a lot of sense, noticed by sparse: drivers/net/cxgb4vf/t4vf_common.h:135:31: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:136:36: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:137:36: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:138:36: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:139:36: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:140:31: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:141:31: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:142:35: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:143:35: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:154:27: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:155:26: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:156:27: error: dubious one-bit signed bitfield drivers/net/cxgb4vf/t4vf_common.h:157:26: error: dubious one-bit signed bitfield Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/t4vf_common.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/cxgb4vf/t4vf_common.h b/drivers/net/cxgb4vf/t4vf_common.h index 5c7bde7f9bae..873cb7d86c57 100644 --- a/drivers/net/cxgb4vf/t4vf_common.h +++ b/drivers/net/cxgb4vf/t4vf_common.h @@ -132,15 +132,15 @@ struct rss_params { unsigned int mode; /* RSS mode */ union { struct { - int synmapen:1; /* SYN Map Enable */ - int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */ - int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */ - int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */ - int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */ - int ofdmapen:1; /* Offload Map Enable */ - int tnlmapen:1; /* Tunnel Map Enable */ - int tnlalllookup:1; /* Tunnel All Lookup */ - int hashtoeplitz:1; /* use Toeplitz hash */ + unsigned int synmapen:1; /* SYN Map Enable */ + unsigned int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */ + unsigned int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */ + unsigned int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */ + unsigned int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */ + unsigned int ofdmapen:1; /* Offload Map Enable */ + unsigned int tnlmapen:1; /* Tunnel Map Enable */ + unsigned int tnlalllookup:1; /* Tunnel All Lookup */ + unsigned int hashtoeplitz:1; /* use Toeplitz hash */ } basicvirtual; } u; }; @@ -151,10 +151,10 @@ struct rss_params { union rss_vi_config { struct { u16 defaultq; /* Ingress Queue ID for !tnlalllookup */ - int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */ - int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */ - int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */ - int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */ + unsigned int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */ + unsigned int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */ + unsigned int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */ + unsigned int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */ int udpen; /* hash 4-tuple UDP ingress packets */ } basicvirtual; }; -- cgit v1.2.3 From 35f2516f0a1f9dddb339849c7a07e089322c18c3 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 12 Oct 2010 22:20:34 +0000 Subject: dnet: mark methods static and annotate for correct endianness Their doesn't appear to be bugs with the endianness handling here, just get the annotations right to keep sparse happy. Suppresses the following sparse warnings: drivers/net/dnet.c:30:5: warning: symbol 'dnet_readw_mac' was not declared. Should it be static? drivers/net/dnet.c:49:6: warning: symbol 'dnet_writew_mac' was not declared. Should it be static? drivers/net/dnet.c:364:5: warning: symbol 'dnet_phy_marvell_fixup' was not declared. Should it be static? drivers/net/dnet.c:66:13: warning: incorrect type in assignment (different base types) drivers/net/dnet.c:66:13: expected unsigned short [unsigned] [usertype] tmp drivers/net/dnet.c:66:13: got restricted __be16 [usertype] drivers/net/dnet.c:68:13: warning: incorrect type in assignment (different base types) drivers/net/dnet.c:68:13: expected unsigned short [unsigned] [usertype] tmp drivers/net/dnet.c:68:13: got restricted __be16 [usertype] drivers/net/dnet.c:70:13: warning: incorrect type in assignment (different base types) drivers/net/dnet.c:70:13: expected unsigned short [unsigned] [usertype] tmp drivers/net/dnet.c:70:13: got restricted __be16 [usertype] drivers/net/dnet.c:92:27: warning: cast to restricted __be16 drivers/net/dnet.c:94:33: warning: cast to restricted __be16 drivers/net/dnet.c:96:33: warning: cast to restricted __be16 Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- drivers/net/dnet.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 7c075756611a..9d8a20b72fa9 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -27,7 +27,7 @@ #undef DEBUG /* function for reading internal MAC register */ -u16 dnet_readw_mac(struct dnet *bp, u16 reg) +static u16 dnet_readw_mac(struct dnet *bp, u16 reg) { u16 data_read; @@ -46,7 +46,7 @@ u16 dnet_readw_mac(struct dnet *bp, u16 reg) } /* function for writing internal MAC register */ -void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) +static void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) { /* load data to write */ dnet_writel(bp, val, MACREG_DATA); @@ -63,11 +63,11 @@ static void __dnet_set_hwaddr(struct dnet *bp) { u16 tmp; - tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr)); + tmp = be16_to_cpup((__be16 *)bp->dev->dev_addr); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2))); + tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 2)); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4))); + tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 4)); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp); } @@ -89,11 +89,11 @@ static void __devinit dnet_get_hwaddr(struct dnet *bp) * Mac_addr[15:0]). */ tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG); - *((u16 *) addr) = be16_to_cpu(tmp); + *((__be16 *)addr) = cpu_to_be16(tmp); tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG); - *((u16 *) (addr + 2)) = be16_to_cpu(tmp); + *((__be16 *)(addr + 2)) = cpu_to_be16(tmp); tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG); - *((u16 *) (addr + 4)) = be16_to_cpu(tmp); + *((__be16 *)(addr + 4)) = cpu_to_be16(tmp); if (is_valid_ether_addr(addr)) memcpy(bp->dev->dev_addr, addr, sizeof(addr)); @@ -361,7 +361,7 @@ err_out: } /* For Neptune board: LINK1000 as Link LED and TX as activity LED */ -int dnet_phy_marvell_fixup(struct phy_device *phydev) +static int dnet_phy_marvell_fixup(struct phy_device *phydev) { return phy_write(phydev, 0x18, 0x4148); } -- cgit v1.2.3 From 89980827c7a1e3c2b36895c22c6ef0e92aea6b0c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 12 Oct 2010 23:36:19 +0000 Subject: pch_gbe: fix if condition in set_settings() There were no curly braces in this if condition so it always enabled full duplex. And ecmd->speed is an unsigned short so it is never equal to -1. The effect is that mii_ethtool_sset() fails with -EINVAL and an error is printed to dmesg. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c index e06c6aea4527..c8cc32c0edc9 100644 --- a/drivers/net/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -113,9 +113,10 @@ static int pch_gbe_set_settings(struct net_device *netdev, pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); - if (ecmd->speed == -1) + if (ecmd->speed == USHRT_MAX) { ecmd->speed = SPEED_1000; ecmd->duplex = DUPLEX_FULL; + } ret = mii_ethtool_sset(&adapter->mii, ecmd); if (ret) { pr_err("Error: mii_ethtool_sset\n"); -- cgit v1.2.3 From 725a4a465c943ab0f91fcffc3846acbcdb704aac Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Wed, 13 Oct 2010 00:56:09 +0000 Subject: sundance: Add initial ethtool stats support Add ethtool stats support. Signed-off-by: Denis Kirjanov Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/sundance.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 4283cc52a8c9..3ed2a67bd6d3 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -363,6 +363,19 @@ struct netdev_private { dma_addr_t tx_ring_dma; dma_addr_t rx_ring_dma; struct timer_list timer; /* Media monitoring timer. */ + /* ethtool extra stats */ + struct { + u64 tx_multiple_collisions; + u64 tx_single_collisions; + u64 tx_late_collisions; + u64 tx_deferred; + u64 tx_deferred_excessive; + u64 tx_aborted; + u64 tx_bcasts; + u64 rx_bcasts; + u64 tx_mcasts; + u64 rx_mcasts; + } xstats; /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; int msg_enable; @@ -1486,21 +1499,34 @@ static struct net_device_stats *get_stats(struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); void __iomem *ioaddr = np->base; - int i; unsigned long flags; + u8 late_coll, single_coll, mult_coll; spin_lock_irqsave(&np->statlock, flags); /* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK); - dev->stats.collisions += ioread8(ioaddr + StatsLateColl); - dev->stats.collisions += ioread8(ioaddr + StatsMultiColl); - dev->stats.collisions += ioread8(ioaddr + StatsOneColl); dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError); - ioread8(ioaddr + StatsTxDefer); - for (i = StatsTxDefer; i <= StatsMcastRx; i++) - ioread8(ioaddr + i); + + mult_coll = ioread8(ioaddr + StatsMultiColl); + np->xstats.tx_multiple_collisions += mult_coll; + single_coll = ioread8(ioaddr + StatsOneColl); + np->xstats.tx_single_collisions += single_coll; + late_coll = ioread8(ioaddr + StatsLateColl); + np->xstats.tx_late_collisions += late_coll; + dev->stats.collisions += mult_coll + + single_coll + + late_coll; + + np->xstats.tx_deferred += ioread8(ioaddr + StatsTxDefer); + np->xstats.tx_deferred_excessive += ioread8(ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted += ioread8(ioaddr + StatsTxAbort); + np->xstats.tx_bcasts += ioread8(ioaddr + StatsBcastTx); + np->xstats.rx_bcasts += ioread8(ioaddr + StatsBcastRx); + np->xstats.tx_mcasts += ioread8(ioaddr + StatsMcastTx); + np->xstats.rx_mcasts += ioread8(ioaddr + StatsMcastRx); + dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow); dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16; dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); @@ -1566,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev) return 0; } +static const struct { + const char name[ETH_GSTRING_LEN]; +} sundance_stats[] = { + { "tx_multiple_collisions" }, + { "tx_single_collisions" }, + { "tx_late_collisions" }, + { "tx_deferred" }, + { "tx_deferred_excessive" }, + { "tx_aborted" }, + { "tx_bcasts" }, + { "rx_bcasts" }, + { "tx_mcasts" }, + { "rx_mcasts" }, +}; + static int check_if_running(struct net_device *dev) { if (!netif_running(dev)) @@ -1624,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings(struct net_device *dev, u32 stringset, + u8 *data) +{ + if (stringset == ETH_SS_STATS) + memcpy(data, sundance_stats, sizeof(sundance_stats)); +} + +static int get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return ARRAY_SIZE(sundance_stats); + default: + return -EOPNOTSUPP; + } +} + +static void get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct netdev_private *np = netdev_priv(dev); + int i = 0; + + get_stats(dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_deferred; + data[i++] = np->xstats.tx_deferred_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} + static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo, @@ -1633,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -- cgit v1.2.3 From 2c1c00040af3d187b7d602dd53b5adbbf3a4caa4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Oct 2010 02:45:40 +0000 Subject: fib6: use FIB_LOOKUP_NOREF in fib6_rule_lookup() Avoid two atomic ops on found rule in fib6_rule_lookup() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/fib6_rules.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index b1108ede18e1..d829874d8946 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -34,11 +34,10 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, { struct fib_lookup_arg arg = { .lookup_ptr = lookup, + .flags = FIB_LOOKUP_NOREF, }; fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); - if (arg.rule) - fib_rule_put(arg.rule); if (arg.result) return arg.result; -- cgit v1.2.3 From a0a4a85a15df6335e3d11f83b2ac06ebebea313f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Oct 2010 04:43:04 +0000 Subject: fib: remove a useless synchronize_rcu() call fib_nl_delrule() calls synchronize_rcu() for no apparent reason, while rtnl is held. I suspect it was done to avoid an atomic_inc_not_zero() in fib_rules_lookup(), which commit 7fa7cb7109d07 added anyway. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/fib_rules.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 21698f8c49ee..1bc3f253ba6c 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -494,7 +494,6 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) } } - synchronize_rcu(); notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).pid); fib_rule_put(rule); -- cgit v1.2.3 From 874ffa8f72444d6253d2669fed304875c128f86b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Oct 2010 06:56:11 +0000 Subject: fib_trie: use fls() instead of open coded loop fib_table_lookup() might use fls() to speedup an open coded loop. Noticed while doing a profile analysis. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 271c89bdf049..31494f335686 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1384,8 +1384,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, t_key cindex = 0; int current_prefix_length = KEYLENGTH; struct tnode *cn; - t_key node_prefix, key_prefix, pref_mismatch; - int mp; + t_key pref_mismatch; rcu_read_lock(); @@ -1500,10 +1499,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, * matching prefix. */ - node_prefix = mask_pfx(cn->key, cn->pos); - key_prefix = mask_pfx(key, cn->pos); - pref_mismatch = key_prefix^node_prefix; - mp = 0; + pref_mismatch = mask_pfx(cn->key ^ key, cn->pos); /* * In short: If skipped bits in this node do not match @@ -1511,13 +1507,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, * state.directly. */ if (pref_mismatch) { - while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) { - mp++; - pref_mismatch = pref_mismatch << 1; - } - key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp); + int mp = KEYLENGTH - fls(pref_mismatch); - if (key_prefix != 0) + if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0) goto backtrace; if (current_prefix_length >= cn->pos) -- cgit v1.2.3 From 10da66f7552b3c7966c2f4f1f72009fb0b5539ec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 13 Oct 2010 08:22:03 +0000 Subject: fib: avoid false sharing on fib_table_hash While doing profile analysis, I found fib_hash_table was sometime in a cache line shared by a possibly often written kernel structure. (CONFIG_IP_ROUTE_MULTIPATH || !CONFIG_IPV6_MULTIPLE_TABLES) It's hard to detect because not easily reproductible. Make sure we allocate a full cache line to keep this shared in all cpus caches. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 11 +++++------ net/ipv6/ip6_fib.c | 9 ++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 919f2ad19b49..3df057e89640 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1016,16 +1016,15 @@ static struct notifier_block fib_netdev_notifier = { static int __net_init ip_fib_net_init(struct net *net) { int err; - unsigned int i; + size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ; + + /* Avoid false sharing : Use at least a full cache line */ + size = max_t(size_t, size, L1_CACHE_BYTES); - net->ipv4.fib_table_hash = kzalloc( - sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); + net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL); if (net->ipv4.fib_table_hash == NULL) return -ENOMEM; - for (i = 0; i < FIB_TABLE_HASHSZ; i++) - INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); - err = fib4_rules_init(net); if (err < 0) goto fail; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b6a585909d35..de382114609b 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1500,15 +1500,18 @@ static void fib6_gc_timer_cb(unsigned long arg) static int __net_init fib6_net_init(struct net *net) { + size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ; + setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); if (!net->ipv6.rt6_stats) goto out_timer; - net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ, - sizeof(*net->ipv6.fib_table_hash), - GFP_KERNEL); + /* Avoid false sharing : Use at least a full cache line */ + size = max_t(size_t, size, L1_CACHE_BYTES); + + net->ipv6.fib_table_hash = kzalloc(size, GFP_KERNEL); if (!net->ipv6.fib_table_hash) goto out_rt6_stats; -- cgit v1.2.3 From 15419227f773b6c1b5fae44bde876078a9204caa Mon Sep 17 00:00:00 2001 From: françois romieu Date: Wed, 13 Oct 2010 09:26:05 +0000 Subject: via-velocity: forced 1000 Mbps mode support. Full duplex only. Half duplex 1000 Mbps is not supported. Signed-off-by: David Lv Acked-by: Francois Romieu Tested-by: Seguier Regis Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 82 ++++++++++++++++++++++++++++++++++++++++++---- drivers/net/via-velocity.h | 5 +-- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 6884813b809c..f1995615dc84 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -312,13 +312,14 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability"); #define MED_LNK_DEF 0 #define MED_LNK_MIN 0 -#define MED_LNK_MAX 4 +#define MED_LNK_MAX 5 /* speed_duplex[] is used for setting the speed and duplex mode of NIC. 0: indicate autonegotiation for both speed and duplex mode 1: indicate 100Mbps half duplex mode 2: indicate 100Mbps full duplex mode 3: indicate 10Mbps half duplex mode 4: indicate 10Mbps full duplex mode + 5: indicate 1000Mbps full duplex mode Note: if EEPROM have been set to the force mode, this option is ignored @@ -617,6 +618,9 @@ static u32 velocity_get_opt_media_mode(struct velocity_info *vptr) case SPD_DPX_10_HALF: status = VELOCITY_SPEED_10; break; + case SPD_DPX_1000_FULL: + status = VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL; + break; } vptr->mii_status = status; return status; @@ -922,6 +926,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) /* enable AUTO-NEGO mode */ mii_set_auto_on(vptr); } else { + u16 CTRL1000; u16 ANAR; u8 CHIPGCR; @@ -936,7 +941,11 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); CHIPGCR = readb(®s->CHIPGCR); - CHIPGCR &= ~CHIPGCR_FCGMII; + + if (mii_status & VELOCITY_SPEED_1000) + CHIPGCR |= CHIPGCR_FCGMII; + else + CHIPGCR &= ~CHIPGCR_FCGMII; if (mii_status & VELOCITY_DUPLEX_FULL) { CHIPGCR |= CHIPGCR_FCFDX; @@ -952,7 +961,13 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR); } - MII_REG_BITS_OFF(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs); + velocity_mii_read(vptr->mac_regs, MII_CTRL1000, &CTRL1000); + CTRL1000 &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if ((mii_status & VELOCITY_SPEED_1000) && + (mii_status & VELOCITY_DUPLEX_FULL)) { + CTRL1000 |= ADVERTISE_1000FULL; + } + velocity_mii_write(vptr->mac_regs, MII_CTRL1000, CTRL1000); if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG); @@ -967,7 +982,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) ANAR |= ADVERTISE_100FULL; else ANAR |= ADVERTISE_100HALF; - } else { + } else if (mii_status & VELOCITY_SPEED_10) { if (mii_status & VELOCITY_DUPLEX_FULL) ANAR |= ADVERTISE_10FULL; else @@ -1013,6 +1028,9 @@ static void velocity_print_link_status(struct velocity_info *vptr) } else { VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name); switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n"); + break; case SPD_DPX_100_HALF: VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n"); break; @@ -3170,6 +3188,37 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + + cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; + if (vptr->options.spd_dpx == SPD_DPX_AUTO) { + cmd->advertising |= + ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full; + } else { + switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + cmd->advertising |= ADVERTISED_1000baseT_Full; + break; + case SPD_DPX_100_HALF: + cmd->advertising |= ADVERTISED_100baseT_Half; + break; + case SPD_DPX_100_FULL: + cmd->advertising |= ADVERTISED_100baseT_Full; + break; + case SPD_DPX_10_HALF: + cmd->advertising |= ADVERTISED_10baseT_Half; + break; + case SPD_DPX_10_FULL: + cmd->advertising |= ADVERTISED_10baseT_Full; + break; + default: + break; + } + } if (status & VELOCITY_SPEED_1000) cmd->speed = SPEED_1000; else if (status & VELOCITY_SPEED_100) @@ -3200,14 +3249,35 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd curr_status &= (~VELOCITY_LINK_FAIL); new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0); + new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0); new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0); new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0); new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0); - if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) + if ((new_status & VELOCITY_AUTONEG_ENABLE) && + (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) { ret = -EINVAL; - else + } else { + enum speed_opt spd_dpx; + + if (new_status & VELOCITY_AUTONEG_ENABLE) + spd_dpx = SPD_DPX_AUTO; + else if ((new_status & VELOCITY_SPEED_1000) && + (new_status & VELOCITY_DUPLEX_FULL)) { + spd_dpx = SPD_DPX_1000_FULL; + } else if (new_status & VELOCITY_SPEED_100) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_100_FULL : SPD_DPX_100_HALF; + else if (new_status & VELOCITY_SPEED_10) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_10_FULL : SPD_DPX_10_HALF; + else + return -EOPNOTSUPP; + + vptr->options.spd_dpx = spd_dpx; + velocity_set_media_mode(vptr, new_status); + } return ret; } diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index b5e120b0074b..aa2e69b9ff61 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -848,7 +848,7 @@ enum velocity_owner { * Bits in CHIPGCR register */ -#define CHIPGCR_FCGMII 0x80 +#define CHIPGCR_FCGMII 0x80 /* enable GMII mode */ #define CHIPGCR_FCFDX 0x40 #define CHIPGCR_FCRESV 0x20 #define CHIPGCR_FCMODE 0x10 @@ -1390,7 +1390,8 @@ enum speed_opt { SPD_DPX_100_HALF = 1, SPD_DPX_100_FULL = 2, SPD_DPX_10_HALF = 3, - SPD_DPX_10_FULL = 4 + SPD_DPX_10_FULL = 4, + SPD_DPX_1000_FULL = 5 }; enum velocity_init_type { -- cgit v1.2.3 From 31e3c3f6f1f9b154981a0e6620df700463db30ee Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 13 Oct 2010 13:20:35 +0000 Subject: tipc: cleanup function namespace Do some cleanups of TIPC based on make namespacecheck 1. Don't export unused symbols 2. Eliminate dead code 3. Make functions and variables local 4. Rename buf_acquire to tipc_buf_acquire since it is used in several files Compile tested only. This make break out of tree kernel modules that depend on TIPC routines. Signed-off-by: Stephen Hemminger Acked-by: Jon Maloy Acked-by: Paul Gortmaker Signed-off-by: David S. Miller --- include/net/tipc/tipc.h | 71 ------------- include/net/tipc/tipc_port.h | 2 - net/tipc/addr.c | 5 - net/tipc/bcast.c | 10 +- net/tipc/bcast.h | 3 - net/tipc/cluster.c | 21 +--- net/tipc/cluster.h | 2 +- net/tipc/config.c | 7 +- net/tipc/config.h | 6 -- net/tipc/core.c | 28 ++---- net/tipc/core.h | 9 +- net/tipc/dbg.c | 13 ++- net/tipc/dbg.h | 3 - net/tipc/discover.c | 16 +-- net/tipc/discover.h | 2 - net/tipc/link.c | 45 +++++---- net/tipc/link.h | 4 - net/tipc/msg.c | 2 +- net/tipc/name_distr.c | 2 +- net/tipc/node.c | 19 +--- net/tipc/node.h | 1 - net/tipc/port.c | 234 +++++-------------------------------------- net/tipc/port.h | 2 - net/tipc/ref.c | 17 ---- net/tipc/ref.h | 1 - net/tipc/subscr.c | 9 -- net/tipc/zone.c | 11 -- net/tipc/zone.h | 1 - 28 files changed, 84 insertions(+), 462 deletions(-) diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h index 15af6dca0b49..1e0645e1eed2 100644 --- a/include/net/tipc/tipc.h +++ b/include/net/tipc/tipc.h @@ -50,8 +50,6 @@ * TIPC operating mode routines */ -u32 tipc_get_addr(void); - #define TIPC_NOT_RUNNING 0 #define TIPC_NODE_MODE 1 #define TIPC_NET_MODE 2 @@ -62,8 +60,6 @@ int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); void tipc_detach(unsigned int userref); -int tipc_get_mode(void); - /* * TIPC port manipulation routines */ @@ -153,12 +149,6 @@ int tipc_disconnect(u32 portref); int tipc_shutdown(u32 ref); -int tipc_isconnected(u32 portref, int *isconnected); - -int tipc_peer(u32 portref, struct tipc_portid *peer); - -int tipc_ref_valid(u32 portref); - /* * TIPC messaging routines */ @@ -170,38 +160,12 @@ int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); -int tipc_send_buf(u32 portref, - struct sk_buff *buf, - unsigned int dsz); - int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, unsigned int num_sect, struct iovec const *msg_sect); -int tipc_send_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_forward2name(u32 portref, - struct tipc_name const *name, - u32 domain, - unsigned int section_count, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - int tipc_send2port(u32 portref, struct tipc_portid const *dest, unsigned int num_sect, @@ -212,46 +176,11 @@ int tipc_send_buf2port(u32 portref, struct sk_buff *buf, unsigned int dsz); -int tipc_forward2port(u32 portref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2port(u32 portref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, u32 domain, /* currently unused */ unsigned int section_count, struct iovec const *msg); - -#if 0 -int tipc_multicast_buf(u32 portref, - struct tipc_name_seq const *seq, - u32 domain, - void *buf, - unsigned int size); -#endif - -/* - * TIPC subscription routines - */ - -int tipc_ispublished(struct tipc_name const *name); - -/* - * Get number of available nodes within specified domain (excluding own node) - */ - -unsigned int tipc_available_nodes(const u32 domain); - #endif #endif diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h index c54917cbfa48..1893aaf49426 100644 --- a/include/net/tipc/tipc_port.h +++ b/include/net/tipc/tipc_port.h @@ -88,8 +88,6 @@ void tipc_acknowledge(u32 port_ref,u32 ack); struct tipc_port *tipc_get_port(const u32 ref); -void *tipc_get_handle(const u32 ref); - /* * The following routines require that the port be locked on entry */ diff --git a/net/tipc/addr.c b/net/tipc/addr.c index 2ddc351b3be9..8a2e89bffde5 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -41,11 +41,6 @@ #include "cluster.h" #include "net.h" -u32 tipc_get_addr(void) -{ - return tipc_own_addr; -} - /** * tipc_addr_domain_valid - validates a network domain address * diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index ecfaac10d0b4..22a60fc98392 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -121,6 +121,9 @@ static DEFINE_SPINLOCK(bc_lock); const char tipc_bclink_name[] = "broadcast-link"; +static void tipc_nmap_diff(struct tipc_node_map *nm_a, + struct tipc_node_map *nm_b, + struct tipc_node_map *nm_diff); static u32 buf_seqno(struct sk_buff *buf) { @@ -287,7 +290,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr) if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) return; - buf = buf_acquire(INT_H_SIZE); + buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { msg = buf_msg(buf); tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, @@ -871,8 +874,9 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node) * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) */ -void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, - struct tipc_node_map *nm_diff) +static void tipc_nmap_diff(struct tipc_node_map *nm_a, + struct tipc_node_map *nm_b, + struct tipc_node_map *nm_diff) { int stop = ARRAY_SIZE(nm_a->map); int w; diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index e8c2b81658c7..011c03f0a4ab 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -84,9 +84,6 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m return !memcmp(nm_a, nm_b, sizeof(*nm_a)); } -void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, - struct tipc_node_map *nm_diff); - void tipc_port_list_add(struct port_list *pl_ptr, u32 port); void tipc_port_list_free(struct port_list *pl_ptr); diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index e68f705381bc..7fea14b98b97 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -113,25 +113,6 @@ void tipc_cltr_delete(struct cluster *c_ptr) kfree(c_ptr); } -u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr) -{ - struct tipc_node *n_ptr; - u32 n_num = tipc_node(addr) + 1; - - if (!c_ptr) - return addr; - for (; n_num <= c_ptr->highest_node; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr->addr; - } - for (n_num = 1; n_num < tipc_node(addr); n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr->addr; - } - return 0; -} void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr) { @@ -232,7 +213,7 @@ struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector) static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest) { u32 size = INT_H_SIZE + data_size; - struct sk_buff *buf = buf_acquire(size); + struct sk_buff *buf = tipc_buf_acquire(size); struct tipc_msg *msg; if (buf) { diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h index 333efb0b9c44..32636d98c9c6 100644 --- a/net/tipc/cluster.h +++ b/net/tipc/cluster.h @@ -75,7 +75,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_broadcast(struct sk_buff *buf); int tipc_cltr_init(void); -u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr); + void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); diff --git a/net/tipc/config.c b/net/tipc/config.c index c429b0d488a3..50a6133a3668 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -95,7 +95,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, return 1; } -struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) +static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) { struct sk_buff *buf; __be32 value_net; @@ -109,6 +109,11 @@ struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) return buf; } +static struct sk_buff *tipc_cfg_reply_unsigned(u32 value) +{ + return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); +} + struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) { struct sk_buff *buf; diff --git a/net/tipc/config.h b/net/tipc/config.h index 5cd7cc56c54d..481e12ece715 100644 --- a/net/tipc/config.h +++ b/net/tipc/config.h @@ -45,7 +45,6 @@ struct sk_buff *tipc_cfg_reply_alloc(int payload_size); int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, void *tlv_data, int tlv_data_size); -struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value); struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string); static inline struct sk_buff *tipc_cfg_reply_none(void) @@ -53,11 +52,6 @@ static inline struct sk_buff *tipc_cfg_reply_none(void) return tipc_cfg_reply_alloc(0); } -static inline struct sk_buff *tipc_cfg_reply_unsigned(u32 value) -{ - return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); -} - static inline struct sk_buff *tipc_cfg_reply_error_string(char *string) { return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); diff --git a/net/tipc/core.c b/net/tipc/core.c index 466b861dab91..c00530386e3b 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -96,13 +96,13 @@ int tipc_net_id; int tipc_remote_management; -int tipc_get_mode(void) +static int tipc_get_mode(void) { return tipc_mode; } /** - * buf_acquire - creates a TIPC message buffer + * tipc_buf_acquire - creates a TIPC message buffer * @size: message size (including TIPC header) * * Returns a new buffer with data pointers set to the specified size. @@ -111,7 +111,7 @@ int tipc_get_mode(void) * There may also be unrequested tailroom present at the buffer's end. */ -struct sk_buff *buf_acquire(u32 size) +struct sk_buff *tipc_buf_acquire(u32 size) { struct sk_buff *skb; unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; @@ -129,7 +129,7 @@ struct sk_buff *buf_acquire(u32 size) * tipc_core_stop_net - shut down TIPC networking sub-systems */ -void tipc_core_stop_net(void) +static void tipc_core_stop_net(void) { tipc_eth_media_stop(); tipc_net_stop(); @@ -154,7 +154,7 @@ int tipc_core_start_net(unsigned long addr) * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode */ -void tipc_core_stop(void) +static void tipc_core_stop(void) { if (tipc_mode != TIPC_NODE_MODE) return; @@ -176,7 +176,7 @@ void tipc_core_stop(void) * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode */ -int tipc_core_start(void) +static int tipc_core_start(void) { int res; @@ -246,7 +246,6 @@ MODULE_VERSION(TIPC_MOD_VER); EXPORT_SYMBOL(tipc_attach); EXPORT_SYMBOL(tipc_detach); -EXPORT_SYMBOL(tipc_get_addr); EXPORT_SYMBOL(tipc_get_mode); EXPORT_SYMBOL(tipc_createport); EXPORT_SYMBOL(tipc_deleteport); @@ -262,23 +261,10 @@ EXPORT_SYMBOL(tipc_withdraw); EXPORT_SYMBOL(tipc_connect2port); EXPORT_SYMBOL(tipc_disconnect); EXPORT_SYMBOL(tipc_shutdown); -EXPORT_SYMBOL(tipc_isconnected); -EXPORT_SYMBOL(tipc_peer); -EXPORT_SYMBOL(tipc_ref_valid); EXPORT_SYMBOL(tipc_send); -EXPORT_SYMBOL(tipc_send_buf); EXPORT_SYMBOL(tipc_send2name); -EXPORT_SYMBOL(tipc_forward2name); -EXPORT_SYMBOL(tipc_send_buf2name); -EXPORT_SYMBOL(tipc_forward_buf2name); EXPORT_SYMBOL(tipc_send2port); -EXPORT_SYMBOL(tipc_forward2port); -EXPORT_SYMBOL(tipc_send_buf2port); -EXPORT_SYMBOL(tipc_forward_buf2port); EXPORT_SYMBOL(tipc_multicast); -/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */ -EXPORT_SYMBOL(tipc_ispublished); -EXPORT_SYMBOL(tipc_available_nodes); /* TIPC API for external bearers (see tipc_bearer.h) */ @@ -295,6 +281,4 @@ EXPORT_SYMBOL(tipc_createport_raw); EXPORT_SYMBOL(tipc_reject_msg); EXPORT_SYMBOL(tipc_send_buf_fast); EXPORT_SYMBOL(tipc_acknowledge); -EXPORT_SYMBOL(tipc_get_port); -EXPORT_SYMBOL(tipc_get_handle); diff --git a/net/tipc/core.h b/net/tipc/core.h index 188799017abd..e19389e57227 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -83,9 +83,7 @@ * Note: TIPC_LOG is configured to echo its output to the system console; * user-defined buffers can be configured to do the same thing. */ - extern struct print_buf *const TIPC_NULL; -extern struct print_buf *const TIPC_CONS; extern struct print_buf *const TIPC_LOG; void tipc_printf(struct print_buf *, const char *fmt, ...); @@ -204,10 +202,7 @@ extern atomic_t tipc_user_count; * Routines available to privileged subsystems */ -extern int tipc_core_start(void); -extern void tipc_core_stop(void); -extern int tipc_core_start_net(unsigned long addr); -extern void tipc_core_stop_net(void); +extern int tipc_core_start_net(unsigned long); extern int tipc_handler_start(void); extern void tipc_handler_stop(void); extern int tipc_netlink_start(void); @@ -328,7 +323,7 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb) return (struct tipc_msg *)skb->data; } -extern struct sk_buff *buf_acquire(u32 size); +extern struct sk_buff *tipc_buf_acquire(u32 size); /** * buf_discard - frees a TIPC message buffer diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 6569d45bfb9a..46f51d208e5e 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c @@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 }; struct print_buf *const TIPC_NULL = &null_buf; static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; -struct print_buf *const TIPC_CONS = &cons_buf; +static struct print_buf *const TIPC_CONS = &cons_buf; static struct print_buf log_buf = { NULL, 0, NULL, 1 }; struct print_buf *const TIPC_LOG = &log_buf; @@ -76,6 +76,10 @@ struct print_buf *const TIPC_LOG = &log_buf; static char print_string[TIPC_PB_MAX_STR]; static DEFINE_SPINLOCK(print_lock); +static void tipc_printbuf_reset(struct print_buf *pb); +static int tipc_printbuf_empty(struct print_buf *pb); +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from); #define FORMAT(PTR,LEN,FMT) \ {\ @@ -116,7 +120,7 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) * @pb: pointer to print buffer structure */ -void tipc_printbuf_reset(struct print_buf *pb) +static void tipc_printbuf_reset(struct print_buf *pb) { if (pb->buf) { pb->crs = pb->buf; @@ -132,7 +136,7 @@ void tipc_printbuf_reset(struct print_buf *pb) * Returns non-zero if print buffer is empty. */ -int tipc_printbuf_empty(struct print_buf *pb) +static int tipc_printbuf_empty(struct print_buf *pb) { return !pb->buf || (pb->crs == pb->buf); } @@ -181,7 +185,8 @@ int tipc_printbuf_validate(struct print_buf *pb) * Source print buffer becomes empty if a successful move occurs. */ -void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from) { int len; diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h index 5ef1bc8f64ef..3ba6ba8b434a 100644 --- a/net/tipc/dbg.h +++ b/net/tipc/dbg.h @@ -56,10 +56,7 @@ struct print_buf { #define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); -void tipc_printbuf_reset(struct print_buf *pb); -int tipc_printbuf_empty(struct print_buf *pb); int tipc_printbuf_validate(struct print_buf *pb); -void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); int tipc_log_resize(int log_size); diff --git a/net/tipc/discover.c b/net/tipc/discover.c index dbd79c67d7c0..4a7cd3719b78 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -68,20 +68,6 @@ struct link_req { unsigned int timer_intv; }; - -/* - * disc_lost_link(): A link has lost contact - */ - -void tipc_disc_link_event(u32 addr, char *name, int up) -{ - if (in_own_cluster(addr)) - return; - /* - * Code for inter cluster link setup here - */ -} - /** * tipc_disc_init_msg - initialize a link setup message * @type: message type (request or response) @@ -95,7 +81,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, u32 dest_domain, struct bearer *b_ptr) { - struct sk_buff *buf = buf_acquire(DSC_H_SIZE); + struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE); struct tipc_msg *msg; if (buf) { diff --git a/net/tipc/discover.h b/net/tipc/discover.h index 9d064c3639bf..f8e750636123 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h @@ -50,6 +50,4 @@ void tipc_disc_stop_link_req(struct link_req *req); void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); -void tipc_disc_link_event(u32 addr, char *name, int up); - #endif diff --git a/net/tipc/link.c b/net/tipc/link.c index 4be78ecf4a67..b31992ccd5d3 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -112,6 +112,9 @@ static void link_state_event(struct link *l_ptr, u32 event); static void link_reset_statistics(struct link *l_ptr); static void link_print(struct link *l_ptr, struct print_buf *buf, const char *str); +static void link_start(struct link *l_ptr); +static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); + /* * Debugging code used by link routines only @@ -442,7 +445,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); list_add_tail(&l_ptr->link_list, &b_ptr->links); - tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); + tipc_k_signal((Handler)link_start, (unsigned long)l_ptr); dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit); @@ -482,9 +485,9 @@ void tipc_link_delete(struct link *l_ptr) kfree(l_ptr); } -void tipc_link_start(struct link *l_ptr) +static void link_start(struct link *l_ptr) { - dbg("tipc_link_start %x\n", l_ptr); + dbg("link_start %x\n", l_ptr); link_state_event(l_ptr, STARTING_EVT); } @@ -1000,7 +1003,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) /* Fragmentation needed ? */ if (size > max_packet) - return tipc_link_send_long_buf(l_ptr, buf); + return link_send_long_buf(l_ptr, buf); /* Packet can be queued or sent: */ @@ -1036,7 +1039,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) /* Try creating a new bundle */ if (size <= max_packet * 2 / 3) { - struct sk_buff *bundler = buf_acquire(max_packet); + struct sk_buff *bundler = tipc_buf_acquire(max_packet); struct tipc_msg bundler_hdr; if (bundler) { @@ -1312,7 +1315,7 @@ again: /* Prepare header of first fragment: */ - buf_chain = buf = buf_acquire(max_pkt); + buf_chain = buf = tipc_buf_acquire(max_pkt); if (!buf) return -ENOMEM; buf->next = NULL; @@ -1369,7 +1372,7 @@ error: msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); msg_set_fragm_no(&fragm_hdr, ++fragm_no); prev = buf; - buf = buf_acquire(fragm_sz + INT_H_SIZE); + buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); if (!buf) goto error; @@ -2145,7 +2148,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { if (!l_ptr->proto_msg_queue) { l_ptr->proto_msg_queue = - buf_acquire(sizeof(l_ptr->proto_msg)); + tipc_buf_acquire(sizeof(l_ptr->proto_msg)); } buf = l_ptr->proto_msg_queue; if (!buf) @@ -2159,7 +2162,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, msg_dbg(msg, ">>"); - buf = buf_acquire(msg_size); + buf = tipc_buf_acquire(msg_size); if (!buf) return; @@ -2318,10 +2321,10 @@ exit: * tipc_link_tunnel(): Send one message via a link belonging to * another bearer. Owner node is locked. */ -void tipc_link_tunnel(struct link *l_ptr, - struct tipc_msg *tunnel_hdr, - struct tipc_msg *msg, - u32 selector) +static void tipc_link_tunnel(struct link *l_ptr, + struct tipc_msg *tunnel_hdr, + struct tipc_msg *msg, + u32 selector) { struct link *tunnel; struct sk_buff *buf; @@ -2334,7 +2337,7 @@ void tipc_link_tunnel(struct link *l_ptr, return; } msg_set_size(tunnel_hdr, length + INT_H_SIZE); - buf = buf_acquire(length + INT_H_SIZE); + buf = tipc_buf_acquire(length + INT_H_SIZE); if (!buf) { warn("Link changeover error, " "unable to send tunnel msg\n"); @@ -2380,7 +2383,7 @@ void tipc_link_changeover(struct link *l_ptr) if (!l_ptr->first_out) { struct sk_buff *buf; - buf = buf_acquire(INT_H_SIZE); + buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); msg_set_size(&tunnel_hdr, INT_H_SIZE); @@ -2441,7 +2444,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); msg_set_size(&tunnel_hdr, length + INT_H_SIZE); - outbuf = buf_acquire(length + INT_H_SIZE); + outbuf = tipc_buf_acquire(length + INT_H_SIZE); if (outbuf == NULL) { warn("Link changeover error, " "unable to send duplicate msg\n"); @@ -2477,7 +2480,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) u32 size = msg_size(msg); struct sk_buff *eb; - eb = buf_acquire(size); + eb = tipc_buf_acquire(size); if (eb) skb_copy_to_linear_data(eb, msg, size); return eb; @@ -2605,11 +2608,11 @@ void tipc_link_recv_bundle(struct sk_buff *buf) /* - * tipc_link_send_long_buf: Entry for buffers needing fragmentation. + * link_send_long_buf: Entry for buffers needing fragmentation. * The buffer is complete, inclusive total message length. * Returns user data length. */ -int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) +static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) { struct tipc_msg *inmsg = buf_msg(buf); struct tipc_msg fragm_hdr; @@ -2648,7 +2651,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) fragm_sz = rest; msg_set_type(&fragm_hdr, LAST_FRAGMENT); } - fragm = buf_acquire(fragm_sz + INT_H_SIZE); + fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); if (fragm == NULL) { warn("Link unable to fragment message\n"); dsz = -ENOMEM; @@ -2753,7 +2756,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, buf_discard(fbuf); return 0; } - pbuf = buf_acquire(msg_size(imsg)); + pbuf = tipc_buf_acquire(msg_size(imsg)); if (pbuf != NULL) { pbuf->next = *pending; *pending = pbuf; diff --git a/net/tipc/link.h b/net/tipc/link.h index 4e944ef4a540..f98bc613de67 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -225,7 +225,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest); void tipc_link_reset_fragments(struct link *l_ptr); int tipc_link_is_up(struct link *l_ptr); int tipc_link_is_active(struct link *l_ptr); -void tipc_link_start(struct link *l_ptr); u32 tipc_link_push_packet(struct link *l_ptr); void tipc_link_stop(struct link *l_ptr); struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd); @@ -239,9 +238,6 @@ int tipc_link_send_sections_fast(struct port* sender, struct iovec const *msg_sect, const u32 num_sect, u32 destnode); -int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); -void tipc_link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr, - struct tipc_msg *msg, u32 selector); void tipc_link_recv_bundle(struct sk_buff *buf); int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 381063817b41..ecb532fb0351 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -112,7 +112,7 @@ int tipc_msg_build(struct tipc_msg *hdr, return dsz; } - *buf = buf_acquire(sz); + *buf = tipc_buf_acquire(sz); if (!(*buf)) return -ENOMEM; skb_copy_to_linear_data(*buf, hdr, hsz); diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 6ac3c543250b..7b907171f879 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -98,7 +98,7 @@ static void publ_to_item(struct distr_item *i, struct publication *p) static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) { - struct sk_buff *buf = buf_acquire(LONG_H_SIZE + size); + struct sk_buff *buf = tipc_buf_acquire(LONG_H_SIZE + size); struct tipc_msg *msg; if (buf != NULL) { diff --git a/net/tipc/node.c b/net/tipc/node.c index 823e9abb7ef5..b4d87eb2dc5d 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -50,7 +50,8 @@ void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str); static void node_lost_contact(struct tipc_node *n_ptr); static void node_established_contact(struct tipc_node *n_ptr); -struct tipc_node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ +/* sorted list of nodes within cluster */ +static struct tipc_node *tipc_nodes = NULL; static DEFINE_SPINLOCK(node_create_lock); @@ -587,22 +588,6 @@ void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router) node_lost_contact(n_ptr); } -u32 tipc_available_nodes(const u32 domain) -{ - struct tipc_node *n_ptr; - u32 cnt = 0; - - read_lock_bh(&tipc_net_lock); - for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { - if (!tipc_in_scope(domain, n_ptr->addr)) - continue; - if (tipc_node_is_up(n_ptr)) - cnt++; - } - read_unlock_bh(&tipc_net_lock); - return cnt; -} - struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) { u32 domain; diff --git a/net/tipc/node.h b/net/tipc/node.h index 45f3db3a595d..fff331b2d26c 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -96,7 +96,6 @@ struct tipc_node { } bclink; }; -extern struct tipc_node *tipc_nodes; extern u32 tipc_own_tag; struct tipc_node *tipc_node_create(u32 addr); diff --git a/net/tipc/port.c b/net/tipc/port.c index 5c4285b2d555..82092eaa1536 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -293,34 +293,6 @@ int tipc_deleteport(u32 ref) return 0; } -/** - * tipc_get_port() - return port associated with 'ref' - * - * Note: Port is not locked. - */ - -struct tipc_port *tipc_get_port(const u32 ref) -{ - return (struct tipc_port *)tipc_ref_deref(ref); -} - -/** - * tipc_get_handle - return user handle associated to port 'ref' - */ - -void *tipc_get_handle(const u32 ref) -{ - struct port *p_ptr; - void * handle; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return NULL; - handle = p_ptr->publ.usr_handle; - tipc_port_unlock(p_ptr); - return handle; -} - static int port_unreliable(struct port *p_ptr) { return msg_src_droppable(&p_ptr->publ.phdr); @@ -392,7 +364,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, struct sk_buff *buf; struct tipc_msg *msg; - buf = buf_acquire(LONG_H_SIZE); + buf = tipc_buf_acquire(LONG_H_SIZE); if (buf) { msg = buf_msg(buf); tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); @@ -433,7 +405,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) hdr_sz = MCAST_H_SIZE; else hdr_sz = LONG_H_SIZE; - rbuf = buf_acquire(data_sz + hdr_sz); + rbuf = tipc_buf_acquire(data_sz + hdr_sz); if (rbuf == NULL) { buf_discard(buf); return data_sz; @@ -1242,50 +1214,13 @@ int tipc_shutdown(u32 ref) return tipc_disconnect(ref); } -int tipc_isconnected(u32 ref, int *isconnected) -{ - struct port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isconnected = p_ptr->publ.connected; - tipc_port_unlock(p_ptr); - return 0; -} - -int tipc_peer(u32 ref, struct tipc_portid *peer) -{ - struct port *p_ptr; - int res; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.connected) { - peer->ref = port_peerport(p_ptr); - peer->node = port_peernode(p_ptr); - res = 0; - } else - res = -ENOTCONN; - tipc_port_unlock(p_ptr); - return res; -} - -int tipc_ref_valid(u32 ref) -{ - /* Works irrespective of type */ - return !!tipc_ref_deref(ref); -} - - /* * tipc_port_recv_sections(): Concatenate and deliver sectioned * message for this node. */ -int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, - struct iovec const *msg_sect) +static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, + struct iovec const *msg_sect) { struct sk_buff *buf; int res; @@ -1335,66 +1270,17 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) return -ELINKCONG; } -/** - * tipc_send_buf - send message buffer on connection - */ - -int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode; - u32 hsz; - u32 sz; - u32 res; - - p_ptr = tipc_port_deref(ref); - if (!p_ptr || !p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - hsz = msg_hdr_sz(msg); - sz = hsz + dsz; - msg_set_size(msg, sz); - if (skb_cow(buf, hsz)) - return -ENOMEM; - - skb_push(buf, hsz); - skb_copy_to_linear_data(buf, msg, hsz); - destnode = msg_destnode(msg); - p_ptr->publ.congested = 1; - if (!tipc_port_congested(p_ptr)) { - if (likely(destnode != tipc_own_addr)) - res = tipc_send_buf_fast(buf, destnode); - else { - tipc_port_recv_msg(buf); - res = sz; - } - if (likely(res != -ELINKCONG)) { - port_incr_out_seqno(p_ptr); - p_ptr->sent++; - p_ptr->publ.congested = 0; - return res; - } - } - if (port_unreliable(p_ptr)) { - p_ptr->publ.congested = 0; - return dsz; - } - return -ELINKCONG; -} - /** * tipc_forward2name - forward message sections to port name */ -int tipc_forward2name(u32 ref, - struct tipc_name const *name, - u32 domain, - u32 num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward2name(u32 ref, + struct tipc_name const *name, + u32 domain, + u32 num_sect, + struct iovec const *msg_sect, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; @@ -1456,90 +1342,16 @@ int tipc_send2name(u32 ref, TIPC_PORT_IMPORTANCE); } -/** - * tipc_forward_buf2name - forward message buffer to port name - */ - -int tipc_forward_buf2name(u32 ref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode = domain; - u32 destport; - int res; - - p_ptr = (struct port *)tipc_ref_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); - msg_set_type(msg, TIPC_NAMED_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_nametype(msg, name->type); - msg_set_nameinst(msg, name->instance); - msg_set_lookup_scope(msg, tipc_addr_scope(domain)); - msg_set_hdr_sz(msg, LONG_H_SIZE); - msg_set_size(msg, LONG_H_SIZE + dsz); - destport = tipc_nametbl_translate(name->type, name->instance, &destnode); - msg_set_destnode(msg, destnode); - msg_set_destport(msg, destport); - msg_dbg(msg, "forw2name ==> "); - if (skb_cow(buf, LONG_H_SIZE)) - return -ENOMEM; - skb_push(buf, LONG_H_SIZE); - skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); - msg_dbg(buf_msg(buf),"PREP:"); - if (likely(destport)) { - p_ptr->sent++; - if (destnode == tipc_own_addr) - return tipc_port_recv_msg(buf); - res = tipc_send_buf_fast(buf, destnode); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) - return dsz; - return -ELINKCONG; - } - return tipc_reject_msg(buf, TIPC_ERR_NO_NAME); -} - -/** - * tipc_send_buf2name - send message buffer to port name - */ - -int tipc_send_buf2name(u32 ref, - struct tipc_name const *dest, - u32 domain, - struct sk_buff *buf, - unsigned int dsz) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig, - TIPC_PORT_IMPORTANCE); -} - /** * tipc_forward2port - forward message sections to port identity */ -int tipc_forward2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward2port(u32 ref, + struct tipc_portid const *dest, + unsigned int num_sect, + struct iovec const *msg_sect, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; @@ -1591,12 +1403,12 @@ int tipc_send2port(u32 ref, /** * tipc_forward_buf2port - forward message buffer to port identity */ -int tipc_forward_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward_buf2port(u32 ref, + struct tipc_portid const *dest, + struct sk_buff *buf, + unsigned int dsz, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; diff --git a/net/tipc/port.h b/net/tipc/port.h index e74bd9563739..73bbf442b346 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -109,8 +109,6 @@ struct port { extern spinlock_t tipc_port_list_lock; struct port_list; -int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect, - struct iovec const *msg_sect); int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, int err); diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 8dea66500cf5..ab8ad32d8c20 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -282,23 +282,6 @@ void *tipc_ref_lock(u32 ref) return NULL; } -/** - * tipc_ref_unlock - unlock referenced object - */ - -void tipc_ref_unlock(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely((entry->ref == ref) && (entry->object))) - spin_unlock_bh(&entry->lock); - else - err("Attempt to unlock non-existent reference\n"); - } -} /** * tipc_ref_deref - return pointer referenced object (without locking it) diff --git a/net/tipc/ref.h b/net/tipc/ref.h index 7e3798ea93b9..5bc8e7ab84de 100644 --- a/net/tipc/ref.h +++ b/net/tipc/ref.h @@ -44,7 +44,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock); void tipc_ref_discard(u32 ref); void *tipc_ref_lock(u32 ref); -void tipc_ref_unlock(u32 ref); void *tipc_ref_deref(u32 ref); #endif diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 1a5b9a6bd128..18813acc6bef 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -598,12 +598,3 @@ void tipc_subscr_stop(void) topsrv.user_ref = 0; } } - - -int tipc_ispublished(struct tipc_name const *name) -{ - u32 domain = 0; - - return tipc_nametbl_translate(name->type, name->instance, &domain) != 0; -} - diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 2c01ba2d86bf..83f8b5e91fc8 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -160,14 +160,3 @@ u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref) } return 0; } - - -u32 tipc_zone_next_node(u32 addr) -{ - struct cluster *c_ptr = tipc_cltr_find(addr); - - if (c_ptr) - return tipc_cltr_next_node(c_ptr, addr); - return 0; -} - diff --git a/net/tipc/zone.h b/net/tipc/zone.h index 7bdc3406ba9b..bd1c20ce9d06 100644 --- a/net/tipc/zone.h +++ b/net/tipc/zone.h @@ -61,7 +61,6 @@ void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest); struct _zone *tipc_zone_create(u32 addr); void tipc_zone_delete(struct _zone *z_ptr); void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr); -u32 tipc_zone_next_node(u32 addr); static inline struct _zone *tipc_zone_find(u32 addr) { -- cgit v1.2.3 From 8ee17ae68c0f1e281a432a4318fa2511e25c9492 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 13 Oct 2010 14:50:31 +0000 Subject: stmmac: make ethtool functions local Signed-off-by: Stephen Hemminger Acked-by: Gustavo F. Padovan Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_ethtool.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 25a7e385f8ec..de7589287fb8 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -89,8 +89,8 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { }; #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) -void stmmac_ethtool_getdrvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) +static void stmmac_ethtool_getdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct stmmac_priv *priv = netdev_priv(dev); @@ -104,7 +104,8 @@ void stmmac_ethtool_getdrvinfo(struct net_device *dev, info->n_stats = STMMAC_STATS_LEN; } -int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) +static int stmmac_ethtool_getsettings(struct net_device *dev, + struct ethtool_cmd *cmd) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phy = priv->phydev; @@ -126,7 +127,8 @@ int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) return rc; } -int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) +static int stmmac_ethtool_setsettings(struct net_device *dev, + struct ethtool_cmd *cmd) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phy = priv->phydev; @@ -139,32 +141,32 @@ int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) return rc; } -u32 stmmac_ethtool_getmsglevel(struct net_device *dev) +static u32 stmmac_ethtool_getmsglevel(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); return priv->msg_enable; } -void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level) +static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level) { struct stmmac_priv *priv = netdev_priv(dev); priv->msg_enable = level; } -int stmmac_check_if_running(struct net_device *dev) +static int stmmac_check_if_running(struct net_device *dev) { if (!netif_running(dev)) return -EBUSY; return 0; } -int stmmac_ethtool_get_regs_len(struct net_device *dev) +static int stmmac_ethtool_get_regs_len(struct net_device *dev) { return REG_SPACE_SIZE; } -void stmmac_ethtool_gregs(struct net_device *dev, +static void stmmac_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *space) { int i; @@ -195,7 +197,7 @@ void stmmac_ethtool_gregs(struct net_device *dev, } } -int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) +static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) { if (data) netdev->features |= NETIF_F_HW_CSUM; @@ -205,7 +207,7 @@ int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) return 0; } -u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) +static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); -- cgit v1.2.3 From cadb7924b10b2a3117dafe14d6d6d28035ec4ddb Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 13 Oct 2010 14:51:25 +0000 Subject: stmmac: make function tables const These tables only contain function pointers. Signed-off-by: Stephen Hemminger Acked-by: Gustavo F. Padovan Signed-off-by: David S. Miller --- drivers/net/stmmac/common.h | 6 +++--- drivers/net/stmmac/dwmac100.h | 2 +- drivers/net/stmmac/dwmac1000.h | 2 +- drivers/net/stmmac/dwmac1000_core.c | 2 +- drivers/net/stmmac/dwmac1000_dma.c | 2 +- drivers/net/stmmac/dwmac100_core.c | 2 +- drivers/net/stmmac/dwmac100_dma.c | 2 +- drivers/net/stmmac/enh_desc.c | 2 +- drivers/net/stmmac/norm_desc.c | 2 +- drivers/net/stmmac/stmmac.h | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index dec7ce40c27a..375ea193e139 100644 --- a/drivers/net/stmmac/common.h +++ b/drivers/net/stmmac/common.h @@ -235,9 +235,9 @@ struct mii_regs { }; struct mac_device_info { - struct stmmac_ops *mac; - struct stmmac_desc_ops *desc; - struct stmmac_dma_ops *dma; + const struct stmmac_ops *mac; + const struct stmmac_desc_ops *desc; + const struct stmmac_dma_ops *dma; struct mii_regs mii; /* MII register Addresses */ struct mac_link link; }; diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h index 97956cbf1cb4..7c6d857a9cc7 100644 --- a/drivers/net/stmmac/dwmac100.h +++ b/drivers/net/stmmac/dwmac100.h @@ -118,4 +118,4 @@ enum ttc_control { #define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */ #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ -extern struct stmmac_dma_ops dwmac100_dma_ops; +extern const struct stmmac_dma_ops dwmac100_dma_ops; diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h index 81ee4fd04386..cfcef0ea0fa5 100644 --- a/drivers/net/stmmac/dwmac1000.h +++ b/drivers/net/stmmac/dwmac1000.h @@ -205,4 +205,4 @@ enum rtc_control { #define GMAC_MMC_TX_INTR 0x108 #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 -extern struct stmmac_dma_ops dwmac1000_dma_ops; +extern const struct stmmac_dma_ops dwmac1000_dma_ops; diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 65667b692024..6ae4c3f4c63c 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -212,7 +212,7 @@ static void dwmac1000_irq_status(void __iomem *ioaddr) } } -struct stmmac_ops dwmac1000_ops = { +static const struct stmmac_ops dwmac1000_ops = { .core_init = dwmac1000_core_init, .rx_coe = dwmac1000_rx_coe_supported, .dump_regs = dwmac1000_dump_regs, diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c index ce6163e39cd5..2c47712d45d0 100644 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ b/drivers/net/stmmac/dwmac1000_dma.c @@ -138,7 +138,7 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) } } -struct stmmac_dma_ops dwmac1000_dma_ops = { +const struct stmmac_dma_ops dwmac1000_dma_ops = { .init = dwmac1000_dma_init, .dump_regs = dwmac1000_dump_dma_regs, .dma_mode = dwmac1000_dma_operation_mode, diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index 94eeccf3a8a0..c724fc36a24f 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -168,7 +168,7 @@ static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode) return; } -struct stmmac_ops dwmac100_ops = { +static const struct stmmac_ops dwmac100_ops = { .core_init = dwmac100_core_init, .rx_coe = dwmac100_rx_coe_supported, .dump_regs = dwmac100_dump_mac_regs, diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c index 96aac93b789b..e3e224b7d9e2 100644 --- a/drivers/net/stmmac/dwmac100_dma.c +++ b/drivers/net/stmmac/dwmac100_dma.c @@ -126,7 +126,7 @@ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x, } } -struct stmmac_dma_ops dwmac100_dma_ops = { +const struct stmmac_dma_ops dwmac100_dma_ops = { .init = dwmac100_dma_init, .dump_regs = dwmac100_dump_dma_regs, .dma_mode = dwmac100_dma_operation_mode, diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c index 5d1471d8f8f6..e5dfb6a30182 100644 --- a/drivers/net/stmmac/enh_desc.c +++ b/drivers/net/stmmac/enh_desc.c @@ -318,7 +318,7 @@ static int enh_desc_get_rx_frame_len(struct dma_desc *p) return p->des01.erx.frame_length; } -struct stmmac_desc_ops enh_desc_ops = { +const struct stmmac_desc_ops enh_desc_ops = { .tx_status = enh_desc_get_tx_status, .rx_status = enh_desc_get_rx_status, .get_tx_len = enh_desc_get_tx_len, diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c index 0dce90cb8124..cd0cc76f7a1c 100644 --- a/drivers/net/stmmac/norm_desc.c +++ b/drivers/net/stmmac/norm_desc.c @@ -202,7 +202,7 @@ static int ndesc_get_rx_frame_len(struct dma_desc *p) return p->des01.rx.frame_length; } -struct stmmac_desc_ops ndesc_ops = { +const struct stmmac_desc_ops ndesc_ops = { .tx_status = ndesc_get_tx_status, .rx_status = ndesc_get_rx_status, .get_tx_len = ndesc_get_tx_len, diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 92154ff7d702..79bdc2e13224 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -121,5 +121,5 @@ static inline int stmmac_claim_resource(struct platform_device *pdev) extern int stmmac_mdio_unregister(struct net_device *ndev); extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); -extern struct stmmac_desc_ops enh_desc_ops; -extern struct stmmac_desc_ops ndesc_ops; +extern const struct stmmac_desc_ops enh_desc_ops; +extern const struct stmmac_desc_ops ndesc_ops; -- cgit v1.2.3 From e00ce92e0bb966227e88d674d4f7311f4f3bacac Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 13 Oct 2010 15:12:53 +0000 Subject: infiniband: fix mlx4 kconfig dependency warning Fix kconfig dependency warning to satisfy dependencies: warning: (MLX4_EN && NETDEVICES && NETDEV_10000 && PCI && INET || MLX4_INFINIBAND && INFINIBAND) selects MLX4_CORE which has unmet direct dependencies (NETDEVICES && NETDEV_10000 && PCI) Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx4/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/hw/mlx4/Kconfig b/drivers/infiniband/hw/mlx4/Kconfig index 4175a4bd0c78..bd995b2b50d8 100644 --- a/drivers/infiniband/hw/mlx4/Kconfig +++ b/drivers/infiniband/hw/mlx4/Kconfig @@ -1,5 +1,6 @@ config MLX4_INFINIBAND tristate "Mellanox ConnectX HCA support" + depends on NETDEVICES && NETDEV_10000 && PCI select MLX4_CORE ---help--- This driver provides low-level InfiniBand support for -- cgit v1.2.3 From 81ccb499e7c5ae47e988e59a4e40a6d5ee66af79 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 13 Oct 2010 15:18:59 +0000 Subject: net: move MII outside of NET_ETHERNET, fix kconfig warning We have USB, PCMCIA, and gigabit ethernet drivers that select MII even though NET_ETHERNET is not enabled, so make MII not be dependent on NET_ETHERNET. It is still dependent on NET and NETDEVICES. Fixes kconfig unmet dependency warning (shortened, was very long string): warning: (ARM_AT91_ETHER && NETDEVICES && NET_ETHERNET && ARM && ARCH_AT91RM9200 || ARM_KS8695_ETHER && NETDEVICES && NET_ETHERNET && ARM && ARCH_KS8695 || ... || IP1000 && NETDEVICES && NETDEV_1000 && PCI && EXPERIMENTAL || HAMACHI && NETDEVICES && NETDEV_1000 && PCI || R8169 && NETDEVICES && NETDEV_1000 && PCI || SIS190 && NETDEVICES && NETDEV_1000 && PCI || VIA_VELOCITY && NETDEVICES && NETDEV_1000 && PCI || ATL1 && NETDEVICES && NETDEV_1000 && PCI || ATL1E && NETDEVICES && NETDEV_1000 && PCI && EXPERIMENTAL || ATL1C && NETDEVICES && NETDEV_1000 && PCI && EXPERIMENTAL || JME && NETDEVICES && NETDEV_1000 && PCI || STMMAC_ETH && NETDEV_1000 && NETDEVICES && HAS_IOMEM || USB_PEGASUS && NETDEVICES && USB && NET || USB_RTL8150 && NETDEVICES && USB && NET && EXPERIMENTAL || USB_USBNET && NETDEVICES && USB && NET || PCMCIA_SMC91C92 && NETDEVICES && NET_PCMCIA && PCMCIA) selects MII which has unmet direct dependencies (NETDEVICES && NET_ETHERNET) Signed-off-by: Randy Dunlap Acked-by: Jeff Garzik [2006-NOV-30] Signed-off-by: David S. Miller --- drivers/net/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 13d01f358f34..d24f54b8c19a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -177,6 +177,13 @@ config NET_SB1000 source "drivers/net/arcnet/Kconfig" +config MII + tristate "Generic Media Independent Interface device support" + help + Most ethernet controllers have MII transceiver either as an external + or internal device. It is safe to say Y or M here even if your + ethernet card lacks MII. + source "drivers/net/phy/Kconfig" # @@ -212,13 +219,6 @@ menuconfig NET_ETHERNET if NET_ETHERNET -config MII - tristate "Generic Media Independent Interface device support" - help - Most ethernet controllers have MII transceiver either as an external - or internal device. It is safe to say Y or M here even if your - ethernet card lack MII. - config MACB tristate "Atmel MACB support" depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 -- cgit v1.2.3 From ed440e82fee9652715a8145ffee8f56396017d9a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Oct 2010 18:59:13 +0000 Subject: niu: introduce temp variables to avoid sparse warnings when swapping in-situ Suppress a large block of warnings like: drivers/net/niu.c:7094:38: warning: incorrect type in assignment (different base types) drivers/net/niu.c:7094:38: expected restricted __be32 [usertype] ip4src drivers/net/niu.c:7094:38: got unsigned long long drivers/net/niu.c:7104:17: warning: cast from restricted __be32 ... Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- drivers/net/niu.c | 92 ++++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index c0437fd8d3f2..781e368329f9 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7090,24 +7090,20 @@ static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc) static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp, struct ethtool_rx_flow_spec *fsp) { + u32 tmp; + u16 prt; - fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >> - TCAM_V4KEY3_SADDR_SHIFT; - fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >> - TCAM_V4KEY3_DADDR_SHIFT; - fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >> - TCAM_V4KEY3_SADDR_SHIFT; - fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >> - TCAM_V4KEY3_DADDR_SHIFT; - - fsp->h_u.tcp_ip4_spec.ip4src = - cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src); - fsp->m_u.tcp_ip4_spec.ip4src = - cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src); - fsp->h_u.tcp_ip4_spec.ip4dst = - cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst); - fsp->m_u.tcp_ip4_spec.ip4dst = - cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst); + tmp = (tp->key[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT; + fsp->h_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp); + + tmp = (tp->key[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT; + fsp->h_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp); + + tmp = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT; + fsp->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp); + + tmp = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT; + fsp->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp); fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >> TCAM_V4KEY2_TOS_SHIFT; @@ -7118,54 +7114,40 @@ static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp, case TCP_V4_FLOW: case UDP_V4_FLOW: case SCTP_V4_FLOW: - fsp->h_u.tcp_ip4_spec.psrc = - ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; - fsp->h_u.tcp_ip4_spec.pdst = - ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; - fsp->m_u.tcp_ip4_spec.psrc = - ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; - fsp->m_u.tcp_ip4_spec.pdst = - ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; + fsp->h_u.tcp_ip4_spec.psrc = cpu_to_be16(prt); + + prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + fsp->h_u.tcp_ip4_spec.pdst = cpu_to_be16(prt); - fsp->h_u.tcp_ip4_spec.psrc = - cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc); - fsp->h_u.tcp_ip4_spec.pdst = - cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst); - fsp->m_u.tcp_ip4_spec.psrc = - cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc); - fsp->m_u.tcp_ip4_spec.pdst = - cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst); + prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; + fsp->m_u.tcp_ip4_spec.psrc = cpu_to_be16(prt); + + prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + fsp->m_u.tcp_ip4_spec.pdst = cpu_to_be16(prt); break; case AH_V4_FLOW: case ESP_V4_FLOW: - fsp->h_u.ah_ip4_spec.spi = - (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT; - fsp->m_u.ah_ip4_spec.spi = - (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->h_u.ah_ip4_spec.spi = cpu_to_be32(tmp); - fsp->h_u.ah_ip4_spec.spi = - cpu_to_be32(fsp->h_u.ah_ip4_spec.spi); - fsp->m_u.ah_ip4_spec.spi = - cpu_to_be32(fsp->m_u.ah_ip4_spec.spi); + tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->m_u.ah_ip4_spec.spi = cpu_to_be32(tmp); break; case IP_USER_FLOW: - fsp->h_u.usr_ip4_spec.l4_4_bytes = - (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT; - fsp->m_u.usr_ip4_spec.l4_4_bytes = - (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->h_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp); - fsp->h_u.usr_ip4_spec.l4_4_bytes = - cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes); - fsp->m_u.usr_ip4_spec.l4_4_bytes = - cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes); + tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->m_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp); fsp->h_u.usr_ip4_spec.proto = (tp->key[2] & TCAM_V4KEY2_PROTO) >> -- cgit v1.2.3 From f3e85df845a5da60fc461cf49537435b1d07cf6d Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Sun, 17 Oct 2010 13:43:56 -0700 Subject: stmmac: remove ifdef NETIF_F_TSO from stmmac_ethtool.c Signed-off-by: Giuseppe Cavallaro Reported-by: Armando Visconti Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_ethtool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index de7589287fb8..6d65482e789a 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -380,10 +380,8 @@ static struct ethtool_ops stmmac_ethtool_ops = { .get_wol = stmmac_get_wol, .set_wol = stmmac_set_wol, .get_sset_count = stmmac_get_sset_count, -#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, -#endif }; void stmmac_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.3 From 1fdb936101637c91819efea47e921bb592e07e34 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 14 Oct 2010 01:42:30 +0000 Subject: tcp: sack lost marking fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When only fast rexmit should be done, tcp_mark_head_lost marks L too far. Also, sacked_upto below 1 is perfectly valid number, the packets == 0 then needs to be trapped elsewhere. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e4fbdae066d5..ee0df4817498 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2495,7 +2495,7 @@ static void tcp_timeout_skbs(struct sock *sk) /* Mark head of queue up as lost. With RFC3517 SACK, the packets is * is against sacked "cnt", otherwise it's against facked "cnt" */ -static void tcp_mark_head_lost(struct sock *sk, int packets) +static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; @@ -2503,13 +2503,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) int err; unsigned int mss; - if (packets == 0) - return; - WARN_ON(packets > tp->packets_out); if (tp->lost_skb_hint) { skb = tp->lost_skb_hint; cnt = tp->lost_cnt_hint; + /* Head already handled? */ + if (mark_head && skb != tcp_write_queue_head(sk)) + return; } else { skb = tcp_write_queue_head(sk); cnt = 0; @@ -2544,6 +2544,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) } tcp_skb_mark_lost(tp, skb); + + if (mark_head) + break; } tcp_verify_left_out(tp); } @@ -2555,17 +2558,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit) struct tcp_sock *tp = tcp_sk(sk); if (tcp_is_reno(tp)) { - tcp_mark_head_lost(sk, 1); + tcp_mark_head_lost(sk, 1, 1); } else if (tcp_is_fack(tp)) { int lost = tp->fackets_out - tp->reordering; if (lost <= 0) lost = 1; - tcp_mark_head_lost(sk, lost); + tcp_mark_head_lost(sk, lost, 0); } else { int sacked_upto = tp->sacked_out - tp->reordering; - if (sacked_upto < fast_rexmit) - sacked_upto = fast_rexmit; - tcp_mark_head_lost(sk, sacked_upto); + if (sacked_upto >= 0) + tcp_mark_head_lost(sk, sacked_upto, 0); + else if (fast_rexmit) + tcp_mark_head_lost(sk, 1, 1); } tcp_timeout_skbs(sk); @@ -2971,7 +2975,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) before(tp->snd_una, tp->high_seq) && icsk->icsk_ca_state != TCP_CA_Open && tp->fackets_out > tp->reordering) { - tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); + tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); } -- cgit v1.2.3 From c60ce4e265404ca42ba860401f4b0f1e97332a67 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 14 Oct 2010 01:52:09 +0000 Subject: tcp: use correct counters in CA_CWR state too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As CWR is stronger than CA_Disorder state, we can miscount SACK/Reno failure into other timeouts. Not a bad problem as it can happen only due to ECN, FRTO detecting spurious RTO or xmit error which are the only callers of tcp_enter_cwr. And even then losses and RTO must still follow thereafter to actually end up into the relevant code paths. Compile tested. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- net/ipv4/tcp_timer.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index f3c8c6c019ae..74a6aa003657 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -367,18 +367,19 @@ void tcp_retransmit_timer(struct sock *sk) if (icsk->icsk_retransmits == 0) { int mib_idx; - if (icsk->icsk_ca_state == TCP_CA_Disorder) { - if (tcp_is_sack(tp)) - mib_idx = LINUX_MIB_TCPSACKFAILURES; - else - mib_idx = LINUX_MIB_TCPRENOFAILURES; - } else if (icsk->icsk_ca_state == TCP_CA_Recovery) { + if (icsk->icsk_ca_state == TCP_CA_Recovery) { if (tcp_is_sack(tp)) mib_idx = LINUX_MIB_TCPSACKRECOVERYFAIL; else mib_idx = LINUX_MIB_TCPRENORECOVERYFAIL; } else if (icsk->icsk_ca_state == TCP_CA_Loss) { mib_idx = LINUX_MIB_TCPLOSSFAILURES; + } else if ((icsk->icsk_ca_state == TCP_CA_Disorder) || + tp->sacked_out) { + if (tcp_is_sack(tp)) + mib_idx = LINUX_MIB_TCPSACKFAILURES; + else + mib_idx = LINUX_MIB_TCPRENOFAILURES; } else { mib_idx = LINUX_MIB_TCPTIMEOUTS; } -- cgit v1.2.3 From 8e602ce2980fd6941dc0d3dda12e5095e8206f34 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Oct 2010 05:56:18 +0000 Subject: netns: reorder fields in struct net In a network bench, I noticed an unfortunate false sharing between 'loopback_dev' and 'count' fields in "struct net". 'count' is written each time a socket is created or destroyed, while loopback_dev might be often read in routing code. Move loopback_dev in a read mostly section of "struct net" Note: struct netns_xfrm is cache line aligned on SMP. (It contains a "struct dst_ops") Move it at the end to avoid holes, and reduce sizeof(struct net) by 128 bytes on ia32. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/net_namespace.h | 17 ++++++++++------- include/net/netns/xfrm.h | 9 +++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index bd10a7908993..65af9a07cf76 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -41,6 +41,8 @@ struct net { * destroy on demand */ #endif + spinlock_t rules_mod_lock; + struct list_head list; /* list of network namespaces */ struct list_head cleanup_list; /* namespaces on death row */ struct list_head exit_list; /* Use only net_mutex */ @@ -52,7 +54,8 @@ struct net { struct ctl_table_set sysctls; #endif - struct net_device *loopback_dev; /* The loopback */ + struct sock *rtnl; /* rtnetlink socket */ + struct sock *genl_sock; struct list_head dev_base_head; struct hlist_head *dev_name_head; @@ -60,11 +63,9 @@ struct net { /* core fib_rules */ struct list_head rules_ops; - spinlock_t rules_mod_lock; - struct sock *rtnl; /* rtnetlink socket */ - struct sock *genl_sock; + struct net_device *loopback_dev; /* The loopback */ struct netns_core core; struct netns_mib mib; struct netns_packet packet; @@ -84,13 +85,15 @@ struct net { struct sock *nfnl; struct sock *nfnl_stash; #endif -#ifdef CONFIG_XFRM - struct netns_xfrm xfrm; -#endif #ifdef CONFIG_WEXT_CORE struct sk_buff_head wext_nlevents; #endif struct net_generic *gen; + + /* Note : following structs are cache line aligned */ +#ifdef CONFIG_XFRM + struct netns_xfrm xfrm; +#endif }; diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 74f119a2829a..748f91f87cd5 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -43,10 +43,6 @@ struct netns_xfrm { unsigned int policy_count[XFRM_POLICY_MAX * 2]; struct work_struct policy_hash_work; - struct dst_ops xfrm4_dst_ops; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - struct dst_ops xfrm6_dst_ops; -#endif struct sock *nlsk; struct sock *nlsk_stash; @@ -58,6 +54,11 @@ struct netns_xfrm { #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_hdr; #endif + + struct dst_ops xfrm4_dst_ops; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct dst_ops xfrm6_dst_ops; +#endif }; #endif -- cgit v1.2.3 From 7fc4463309faa087f5e41569a987d43b1d71b982 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 14 Oct 2010 09:55:50 +0000 Subject: drivers/net/pch_gbe: Use DEFINE_PCI_DEVICE_TABLE Use the standard macro to put this table in __devinitconst. Compiled, untested. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index e44644f169fd..cf4b49d6c6da 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -2394,7 +2394,7 @@ err_disable_device: return ret; } -static const struct pci_device_id pch_gbe_pcidev_id[] = { +static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = { {.vendor = PCI_VENDOR_ID_INTEL, .device = PCI_DEVICE_ID_INTEL_IOH1_GBE, .subvendor = PCI_ANY_ID, -- cgit v1.2.3 From 9bef83edfba72ba58b42c14fb046da2199574bc0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Oct 2010 20:53:04 +0000 Subject: fib_hash: embed initial hash table in fn_zone While looking for false sharing problems, I noticed sizeof(struct fn_zone) was small (28 bytes) and possibly sharing a cache line with an often written kernel structure. Most of the time, fn_zone uses its initial hash table of 16 slots. We can avoid the false sharing problem by embedding this initial hash table in fn_zone itself, so that sizeof(fn_zone) > L1_CACHE_BYTES We did a similar optimization in commit a6501e080c (Reduce memory needs and speedup lookups) Add a fz_revorder field to speedup fn_hash() a bit. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_hash.c | 52 +++++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 83cca68e259c..10001aa40692 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -54,23 +54,23 @@ struct fib_node { struct fib_alias fn_embedded_alias; }; +#define EMBEDDED_HASH_SIZE (L1_CACHE_BYTES / sizeof(struct hlist_head)) + struct fn_zone { struct fn_zone *fz_next; /* Next not empty zone */ struct hlist_head *fz_hash; /* Hash table pointer */ - int fz_nent; /* Number of entries */ - - int fz_divisor; /* Hash divisor */ u32 fz_hashmask; /* (fz_divisor - 1) */ -#define FZ_HASHMASK(fz) ((fz)->fz_hashmask) - int fz_order; /* Zone order */ - __be32 fz_mask; + u8 fz_order; /* Zone order (0..32) */ + u8 fz_revorder; /* 32 - fz_order */ + __be32 fz_mask; /* inet_make_mask(order) */ #define FZ_MASK(fz) ((fz)->fz_mask) -}; -/* NOTE. On fast computers evaluation of fz_hashmask and fz_mask - * can be cheaper than memory lookup, so that FZ_* macros are used. - */ + struct hlist_head fz_embedded_hash[EMBEDDED_HASH_SIZE]; + + int fz_nent; /* Number of entries */ + int fz_divisor; /* Hash size (mask+1) */ +}; struct fn_hash { struct fn_zone *fn_zones[33]; @@ -79,11 +79,11 @@ struct fn_hash { static inline u32 fn_hash(__be32 key, struct fn_zone *fz) { - u32 h = ntohl(key)>>(32 - fz->fz_order); + u32 h = ntohl(key) >> fz->fz_revorder; h ^= (h>>20); h ^= (h>>10); h ^= (h>>5); - h &= FZ_HASHMASK(fz); + h &= fz->fz_hashmask; return h; } @@ -147,14 +147,14 @@ static void fn_rehash_zone(struct fn_zone *fz) int old_divisor, new_divisor; u32 new_hashmask; - old_divisor = fz->fz_divisor; + new_divisor = old_divisor = fz->fz_divisor; switch (old_divisor) { - case 16: - new_divisor = 256; + case EMBEDDED_HASH_SIZE: + new_divisor *= EMBEDDED_HASH_SIZE; break; - case 256: - new_divisor = 1024; + case EMBEDDED_HASH_SIZE*EMBEDDED_HASH_SIZE: + new_divisor *= (EMBEDDED_HASH_SIZE/2); break; default: if ((old_divisor << 1) > FZ_MAX_DIVISOR) { @@ -184,7 +184,8 @@ static void fn_rehash_zone(struct fn_zone *fz) fib_hash_genid++; write_unlock_bh(&fib_hash_lock); - fz_hash_free(old_ht, old_divisor); + if (old_ht != fz->fz_embedded_hash) + fz_hash_free(old_ht, old_divisor); } } @@ -210,18 +211,11 @@ fn_new_zone(struct fn_hash *table, int z) if (!fz) return NULL; - if (z) { - fz->fz_divisor = 16; - } else { - fz->fz_divisor = 1; - } - fz->fz_hashmask = (fz->fz_divisor - 1); - fz->fz_hash = fz_hash_alloc(fz->fz_divisor); - if (!fz->fz_hash) { - kfree(fz); - return NULL; - } + fz->fz_divisor = z ? EMBEDDED_HASH_SIZE : 1; + fz->fz_hashmask = fz->fz_divisor - 1; + fz->fz_hash = fz->fz_embedded_hash; fz->fz_order = z; + fz->fz_revorder = 32 - z; fz->fz_mask = inet_make_mask(z); /* Find the first not empty zone with more specific mask */ -- cgit v1.2.3 From 117a8cdea3647e8e11fac10d14eafefc20f9bda5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Oct 2010 20:53:34 +0000 Subject: fib_hash: RCU conversion phase 1 First step for RCU conversion of fib_hash : struct fn_zone are created and never deleted. Very classic conversion, using rcu_assign_pointer(), rcu_dereference() and rtnl_dereference() verbs. __rcu markers on fz_next and fn_zone_list They are created under RTNL, we dont need fib_hash_lock anymore in fn_new_zone(). Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_hash.c | 57 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 10001aa40692..04f05a96b75b 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -57,7 +57,7 @@ struct fib_node { #define EMBEDDED_HASH_SIZE (L1_CACHE_BYTES / sizeof(struct hlist_head)) struct fn_zone { - struct fn_zone *fz_next; /* Next not empty zone */ + struct fn_zone __rcu *fz_next; /* Next not empty zone */ struct hlist_head *fz_hash; /* Hash table pointer */ u32 fz_hashmask; /* (fz_divisor - 1) */ @@ -73,8 +73,8 @@ struct fn_zone { }; struct fn_hash { - struct fn_zone *fn_zones[33]; - struct fn_zone *fn_zone_list; + struct fn_zone *fn_zones[33]; + struct fn_zone __rcu *fn_zone_list; }; static inline u32 fn_hash(__be32 key, struct fn_zone *fz) @@ -219,21 +219,21 @@ fn_new_zone(struct fn_hash *table, int z) fz->fz_mask = inet_make_mask(z); /* Find the first not empty zone with more specific mask */ - for (i=z+1; i<=32; i++) + for (i = z + 1; i <= 32; i++) if (table->fn_zones[i]) break; - write_lock_bh(&fib_hash_lock); - if (i>32) { + if (i > 32) { /* No more specific masks, we are the first. */ - fz->fz_next = table->fn_zone_list; - table->fn_zone_list = fz; + rcu_assign_pointer(fz->fz_next, + rtnl_dereference(table->fn_zone_list)); + rcu_assign_pointer(table->fn_zone_list, fz); } else { - fz->fz_next = table->fn_zones[i]->fz_next; - table->fn_zones[i]->fz_next = fz; + rcu_assign_pointer(fz->fz_next, + rtnl_dereference(table->fn_zones[i]->fz_next)); + rcu_assign_pointer(table->fn_zones[i]->fz_next, fz); } table->fn_zones[z] = fz; fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); return fz; } @@ -245,8 +245,11 @@ int fib_table_lookup(struct fib_table *tb, struct fn_zone *fz; struct fn_hash *t = (struct fn_hash *)tb->tb_data; + rcu_read_lock(); read_lock(&fib_hash_lock); - for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { + for (fz = rcu_dereference(t->fn_zone_list); + fz != NULL; + fz = rcu_dereference(fz->fz_next)) { struct hlist_head *head; struct hlist_node *node; struct fib_node *f; @@ -267,6 +270,7 @@ int fib_table_lookup(struct fib_table *tb, err = 1; out: read_unlock(&fib_hash_lock); + rcu_read_unlock(); return err; } @@ -362,6 +366,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) return NULL; } +/* Caller must hold RTNL. */ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; @@ -657,13 +662,16 @@ static int fn_flush_list(struct fn_zone *fz, int idx) return found; } +/* caller must hold RTNL. */ int fib_table_flush(struct fib_table *tb) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; struct fn_zone *fz; int found = 0; - for (fz = table->fn_zone_list; fz; fz = fz->fz_next) { + for (fz = rtnl_dereference(table->fn_zone_list); + fz != NULL; + fz = rtnl_dereference(fz->fz_next)) { int i; for (i = fz->fz_divisor - 1; i >= 0; i--) @@ -741,23 +749,29 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb, int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { - int m, s_m; + int m = 0, s_m; struct fn_zone *fz; struct fn_hash *table = (struct fn_hash *)tb->tb_data; s_m = cb->args[2]; + rcu_read_lock(); read_lock(&fib_hash_lock); - for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) { - if (m < s_m) continue; + for (fz = rcu_dereference(table->fn_zone_list); + fz != NULL; + fz = rcu_dereference(fz->fz_next), m++) { + if (m < s_m) + continue; if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { cb->args[2] = m; read_unlock(&fib_hash_lock); + rcu_read_unlock(); return -1; } memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0])); } read_unlock(&fib_hash_lock); + rcu_read_unlock(); cb->args[2] = m; return skb->len; } @@ -820,8 +834,9 @@ static struct fib_alias *fib_get_first(struct seq_file *seq) iter->genid = fib_hash_genid; iter->valid = 1; - for (iter->zone = table->fn_zone_list; iter->zone; - iter->zone = iter->zone->fz_next) { + for (iter->zone = rcu_dereference(table->fn_zone_list); + iter->zone != NULL; + iter->zone = rcu_dereference(iter->zone->fz_next)) { int maxslot; if (!iter->zone->fz_nent) @@ -906,7 +921,7 @@ static struct fib_alias *fib_get_next(struct seq_file *seq) } } - iter->zone = iter->zone->fz_next; + iter->zone = rcu_dereference(iter->zone->fz_next); if (!iter->zone) goto out; @@ -946,9 +961,11 @@ static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos) static void *fib_seq_start(struct seq_file *seq, loff_t *pos) __acquires(fib_hash_lock) + __acquires(RCU) { void *v = NULL; + rcu_read_lock(); read_lock(&fib_hash_lock); if (fib_get_table(seq_file_net(seq), RT_TABLE_MAIN)) v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; @@ -963,8 +980,10 @@ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void fib_seq_stop(struct seq_file *seq, void *v) __releases(fib_hash_lock) + __releases(RCU) { read_unlock(&fib_hash_lock); + rcu_read_unlock(); } static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi) -- cgit v1.2.3 From 19f572565ef66a0439574fd2299a7c804147e133 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Oct 2010 20:56:39 +0000 Subject: fib_hash: RCU conversion phase 2 Get rid of fib_hash_lock rwlock. The fn_zone hash table resize is the noticeable part of this patch. I added a seqlock per fn_zone, so that readers can restart their lookup in the (very rare) case a writer expanded the hash table. Add rcu heads in fib_alias and fib_node, use call_rcu() to defer their freeing, and use appropriate _rcu list manipulations. Stress test (160.000.000 udp frames sent, IP route cache disabled to mimic DDOS attack, FIB_HASH) Before: real 0m41.191s user 0m13.137s sys 8m55.241s After: real 0m38.091s user 0m13.189s sys 7m53.018s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_hash.c | 176 +++++++++++++++++++++++++++++--------------------- net/ipv4/fib_lookup.h | 2 - 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 04f05a96b75b..4f1aafd3ba89 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -58,7 +58,8 @@ struct fib_node { struct fn_zone { struct fn_zone __rcu *fz_next; /* Next not empty zone */ - struct hlist_head *fz_hash; /* Hash table pointer */ + struct hlist_head __rcu *fz_hash; /* Hash table pointer */ + seqlock_t fz_lock; u32 fz_hashmask; /* (fz_divisor - 1) */ u8 fz_order; /* Zone order (0..32) */ @@ -92,7 +93,6 @@ static inline __be32 fz_key(__be32 dst, struct fn_zone *fz) return dst & FZ_MASK(fz); } -static DEFINE_RWLOCK(fib_hash_lock); static unsigned int fib_hash_genid; #define FZ_MAX_DIVISOR ((PAGE_SIZE<fn_hash); + hlist_del_rcu(&f->fn_hash); new_head = &fz->fz_hash[fn_hash(f->fn_key, fz)]; - hlist_add_head(&f->fn_hash, new_head); + hlist_add_head_rcu(&f->fn_hash, new_head); } } } @@ -175,32 +174,55 @@ static void fn_rehash_zone(struct fn_zone *fz) ht = fz_hash_alloc(new_divisor); if (ht) { - write_lock_bh(&fib_hash_lock); + struct fn_zone nfz; + + memcpy(&nfz, fz, sizeof(nfz)); + + write_seqlock_bh(&fz->fz_lock); old_ht = fz->fz_hash; - fz->fz_hash = ht; + nfz.fz_hash = ht; + nfz.fz_hashmask = new_hashmask; + nfz.fz_divisor = new_divisor; + fn_rebuild_zone(&nfz, old_ht, old_divisor); + fib_hash_genid++; + rcu_assign_pointer(fz->fz_hash, ht); fz->fz_hashmask = new_hashmask; fz->fz_divisor = new_divisor; - fn_rebuild_zone(fz, old_ht, old_divisor); - fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); + write_sequnlock_bh(&fz->fz_lock); - if (old_ht != fz->fz_embedded_hash) + if (old_ht != fz->fz_embedded_hash) { + synchronize_rcu(); fz_hash_free(old_ht, old_divisor); + } } } -static inline void fn_free_node(struct fib_node * f) +static void fn_free_node_rcu(struct rcu_head *head) { + struct fib_node *f = container_of(head, struct fib_node, fn_embedded_alias.rcu); + kmem_cache_free(fn_hash_kmem, f); } +static inline void fn_free_node(struct fib_node *f) +{ + call_rcu(&f->fn_embedded_alias.rcu, fn_free_node_rcu); +} + +static void fn_free_alias_rcu(struct rcu_head *head) +{ + struct fib_alias *fa = container_of(head, struct fib_alias, rcu); + + kmem_cache_free(fn_alias_kmem, fa); +} + static inline void fn_free_alias(struct fib_alias *fa, struct fib_node *f) { fib_release_info(fa->fa_info); if (fa == &f->fn_embedded_alias) fa->fa_info = NULL; else - kmem_cache_free(fn_alias_kmem, fa); + call_rcu(&fa->rcu, fn_free_alias_rcu); } static struct fn_zone * @@ -211,6 +233,7 @@ fn_new_zone(struct fn_hash *table, int z) if (!fz) return NULL; + seqlock_init(&fz->fz_lock); fz->fz_divisor = z ? EMBEDDED_HASH_SIZE : 1; fz->fz_hashmask = fz->fz_divisor - 1; fz->fz_hash = fz->fz_embedded_hash; @@ -246,30 +269,34 @@ int fib_table_lookup(struct fib_table *tb, struct fn_hash *t = (struct fn_hash *)tb->tb_data; rcu_read_lock(); - read_lock(&fib_hash_lock); for (fz = rcu_dereference(t->fn_zone_list); fz != NULL; fz = rcu_dereference(fz->fz_next)) { - struct hlist_head *head; + struct hlist_head __rcu *head; struct hlist_node *node; struct fib_node *f; - __be32 k = fz_key(flp->fl4_dst, fz); + __be32 k; + unsigned int seq; - head = &fz->fz_hash[fn_hash(k, fz)]; - hlist_for_each_entry(f, node, head, fn_hash) { - if (f->fn_key != k) - continue; + do { + seq = read_seqbegin(&fz->fz_lock); + k = fz_key(flp->fl4_dst, fz); + + head = &fz->fz_hash[fn_hash(k, fz)]; + hlist_for_each_entry_rcu(f, node, head, fn_hash) { + if (f->fn_key != k) + continue; - err = fib_semantic_match(&f->fn_alias, + err = fib_semantic_match(&f->fn_alias, flp, res, fz->fz_order, fib_flags); - if (err <= 0) - goto out; - } + if (err <= 0) + goto out; + } + } while (read_seqretry(&fz->fz_lock, seq)); } err = 1; out: - read_unlock(&fib_hash_lock); rcu_read_unlock(); return err; } @@ -292,11 +319,11 @@ void fib_table_select_default(struct fib_table *tb, last_resort = NULL; order = -1; - read_lock(&fib_hash_lock); - hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) { + rcu_read_lock(); + hlist_for_each_entry_rcu(f, node, &fz->fz_hash[0], fn_hash) { struct fib_alias *fa; - list_for_each_entry(fa, &f->fn_alias, fa_list) { + list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) { struct fib_info *next_fi = fa->fa_info; if (fa->fa_scope != res->scope || @@ -340,7 +367,7 @@ void fib_table_select_default(struct fib_table *tb, fib_result_assign(res, last_resort); tb->tb_default = last_idx; out: - read_unlock(&fib_hash_lock); + rcu_read_unlock(); } /* Insert node F to FZ. */ @@ -348,7 +375,7 @@ static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f) { struct hlist_head *head = &fz->fz_hash[fn_hash(f->fn_key, fz)]; - hlist_add_head(&f->fn_hash, head); + hlist_add_head_rcu(&f->fn_hash, head); } /* Return the node in FZ matching KEY. */ @@ -358,7 +385,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) struct hlist_node *node; struct fib_node *f; - hlist_for_each_entry(f, node, head, fn_hash) { + hlist_for_each_entry_rcu(f, node, head, fn_hash) { if (f->fn_key == key) return f; } @@ -366,6 +393,16 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) return NULL; } + +static struct fib_alias *fib_fast_alloc(struct fib_node *f) +{ + struct fib_alias *fa = &f->fn_embedded_alias; + + if (fa->fa_info != NULL) + fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + return fa; +} + /* Caller must hold RTNL. */ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { @@ -451,7 +488,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) } if (cfg->fc_nlflags & NLM_F_REPLACE) { - struct fib_info *fi_drop; u8 state; fa = fa_first; @@ -460,21 +496,25 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) err = 0; goto out; } - write_lock_bh(&fib_hash_lock); - fi_drop = fa->fa_info; - fa->fa_info = fi; - fa->fa_type = cfg->fc_type; - fa->fa_scope = cfg->fc_scope; + err = -ENOBUFS; + new_fa = fib_fast_alloc(f); + if (new_fa == NULL) + goto out; + + new_fa->fa_tos = fa->fa_tos; + new_fa->fa_info = fi; + new_fa->fa_type = cfg->fc_type; + new_fa->fa_scope = cfg->fc_scope; state = fa->fa_state; - fa->fa_state &= ~FA_S_ACCESSED; + new_fa->fa_state = state & ~FA_S_ACCESSED; fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); + list_replace_rcu(&fa->fa_list, &new_fa->fa_list); - fib_release_info(fi_drop); + fn_free_alias(fa, f); if (state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); - rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id, - &cfg->fc_nlinfo, NLM_F_REPLACE); + rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, + tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE); return 0; } @@ -506,12 +546,10 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) f = new_f; } - new_fa = &f->fn_embedded_alias; - if (new_fa->fa_info != NULL) { - new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); - if (new_fa == NULL) - goto out; - } + new_fa = fib_fast_alloc(f); + if (new_fa == NULL) + goto out; + new_fa->fa_info = fi; new_fa->fa_tos = tos; new_fa->fa_type = cfg->fc_type; @@ -522,13 +560,11 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) * Insert new entry to the list. */ - write_lock_bh(&fib_hash_lock); if (new_f) fib_insert_node(fz, new_f); - list_add_tail(&new_fa->fa_list, + list_add_tail_rcu(&new_fa->fa_list, (fa ? &fa->fa_list : &f->fn_alias)); fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); if (new_f) fz->fz_nent++; @@ -603,14 +639,12 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) tb->tb_id, &cfg->fc_nlinfo, 0); kill_fn = 0; - write_lock_bh(&fib_hash_lock); - list_del(&fa->fa_list); + list_del_rcu(&fa->fa_list); if (list_empty(&f->fn_alias)) { - hlist_del(&f->fn_hash); + hlist_del_rcu(&f->fn_hash); kill_fn = 1; } fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); if (fa->fa_state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); @@ -641,14 +675,12 @@ static int fn_flush_list(struct fn_zone *fz, int idx) struct fib_info *fi = fa->fa_info; if (fi && (fi->fib_flags&RTNH_F_DEAD)) { - write_lock_bh(&fib_hash_lock); - list_del(&fa->fa_list); + list_del_rcu(&fa->fa_list); if (list_empty(&f->fn_alias)) { - hlist_del(&f->fn_hash); + hlist_del_rcu(&f->fn_hash); kill_f = 1; } fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); fn_free_alias(fa, f); found++; @@ -693,10 +725,10 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, s_i = cb->args[4]; i = 0; - hlist_for_each_entry(f, node, head, fn_hash) { + hlist_for_each_entry_rcu(f, node, head, fn_hash) { struct fib_alias *fa; - list_for_each_entry(fa, &f->fn_alias, fa_list) { + list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) { if (i < s_i) goto next; @@ -714,7 +746,7 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, cb->args[4] = i; return -1; } - next: +next: i++; } } @@ -755,7 +787,6 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, s_m = cb->args[2]; rcu_read_lock(); - read_lock(&fib_hash_lock); for (fz = rcu_dereference(table->fn_zone_list); fz != NULL; fz = rcu_dereference(fz->fz_next), m++) { @@ -763,14 +794,12 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, continue; if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { cb->args[2] = m; - read_unlock(&fib_hash_lock); rcu_read_unlock(); return -1; } memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0])); } - read_unlock(&fib_hash_lock); rcu_read_unlock(); cb->args[2] = m; return skb->len; @@ -960,13 +989,11 @@ static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos) } static void *fib_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(fib_hash_lock) __acquires(RCU) { void *v = NULL; rcu_read_lock(); - read_lock(&fib_hash_lock); if (fib_get_table(seq_file_net(seq), RT_TABLE_MAIN)) v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; return v; @@ -979,17 +1006,16 @@ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void fib_seq_stop(struct seq_file *seq, void *v) - __releases(fib_hash_lock) __releases(RCU) { - read_unlock(&fib_hash_lock); rcu_read_unlock(); } static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi) { static const unsigned type2flags[RTN_MAX + 1] = { - [7] = RTF_REJECT, [8] = RTF_REJECT, + [7] = RTF_REJECT, + [8] = RTF_REJECT, }; unsigned flags = type2flags[type]; diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index b9c9a9f2aee5..5072d8effd5d 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -12,9 +12,7 @@ struct fib_alias { u8 fa_type; u8 fa_scope; u8 fa_state; -#ifdef CONFIG_IP_FIB_TRIE struct rcu_head rcu; -#endif }; #define FA_S_ACCESSED 0x01 -- cgit v1.2.3 From bba226acf4d13586ce47cf8376db33bed7bc0bd6 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:38 +0000 Subject: tg3: Add support for selfboot format 1 v6 5718 B0 and 5719 devices will use a new selfboot firmware format. This patch adds code to detect the new format so that bootcode versions get reported correctly. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +++ drivers/net/tg3.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 943c28325444..978ba5d8c253 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12702,6 +12702,9 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val) case TG3_EEPROM_SB_REVISION_5: offset = TG3_EEPROM_SB_F1R5_EDH_OFF; break; + case TG3_EEPROM_SB_REVISION_6: + offset = TG3_EEPROM_SB_F1R6_EDH_OFF; + break; default: return; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index f6b709a3ca32..89553c42fd08 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1915,6 +1915,7 @@ #define TG3_EEPROM_SB_REVISION_3 0x00030000 #define TG3_EEPROM_SB_REVISION_4 0x00040000 #define TG3_EEPROM_SB_REVISION_5 0x00050000 +#define TG3_EEPROM_SB_REVISION_6 0x00060000 #define TG3_EEPROM_MAGIC_HW 0xabcd #define TG3_EEPROM_MAGIC_HW_MSK 0xffff @@ -1934,6 +1935,7 @@ #define TG3_EEPROM_SB_F1R3_EDH_OFF 0x18 #define TG3_EEPROM_SB_F1R4_EDH_OFF 0x1c #define TG3_EEPROM_SB_F1R5_EDH_OFF 0x20 +#define TG3_EEPROM_SB_F1R6_EDH_OFF 0x4c #define TG3_EEPROM_SB_EDH_MAJ_MASK 0x00000700 #define TG3_EEPROM_SB_EDH_MAJ_SHFT 8 #define TG3_EEPROM_SB_EDH_MIN_MASK 0x000000ff -- cgit v1.2.3 From 3d37728bc55994fdf2888f6c872bdeea03a84cc2 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:39 +0000 Subject: tg3: Disable unused transmit rings This patch allows the driver to disable the additional transmit rings available on the 5717 and 5719 devices. This is not strictly necessary, but is done anyways for correctness. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 978ba5d8c253..1c680ff51013 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7536,6 +7536,9 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable all transmit rings but the first. */ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2; else -- cgit v1.2.3 From ddfc87bfd16f370904c6ff7d23738335dd68d0ce Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:40 +0000 Subject: tg3: Add clause 45 register accessor methods This patch adds clause 45 register access methods. They will be used in the following patch. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/tg3.h | 4 ++++ 2 files changed, 50 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1c680ff51013..afcc593108ce 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1162,6 +1162,52 @@ static void tg3_mdio_fini(struct tg3 *tp) } } +static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, + MII_TG3_MMD_CTRL_DATA_NOINC | devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val); + +done: + return err; +} + +static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, + MII_TG3_MMD_CTRL_DATA_NOINC | devad); + if (err) + goto done; + + err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val); + +done: + return err; +} + /* tp->lock is held. */ static inline void tg3_generate_fw_event(struct tg3 *tp) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 89553c42fd08..99fc30680217 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2061,6 +2061,10 @@ #define MII_TG3_CTRL_AS_MASTER 0x0800 #define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000 +#define MII_TG3_MMD_CTRL 0x0d /* MMD Access Control register */ +#define MII_TG3_MMD_CTRL_DATA_NOINC 0x4000 +#define MII_TG3_MMD_ADDRESS 0x0e /* MMD Address Data register */ + #define MII_TG3_EXT_CTRL 0x10 /* Extended control register */ #define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001 #define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002 -- cgit v1.2.3 From 52b02d04c801fff51ca49ad033210846d1713253 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:41 +0000 Subject: tg3: Add EEE support This patch adds Energy Efficient Ethernet (EEE) support for the 5718 device ID and the 57765 B0 asic revision. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/tg3.h | 33 +++++++++++++++- 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index afcc593108ce..f2d96ddd464e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1584,6 +1584,17 @@ static void tg3_phy_fini(struct tg3 *tp) } } +static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); + if (!err) + err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val); + + return err; +} + static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) { int err; @@ -1747,6 +1758,42 @@ static void tg3_phy_apply_otp(struct tg3 *tp) tg3_writephy(tp, MII_TG3_AUX_CTRL, phy); } +static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) +{ + u32 val; + + if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) + return; + + tp->setlpicnt = 0; + + if (tp->link_config.autoneg == AUTONEG_ENABLE && + current_link_up == 1 && + (tp->link_config.active_speed == SPEED_1000 || + (tp->link_config.active_speed == SPEED_100 && + tp->link_config.active_duplex == DUPLEX_FULL))) { + u32 eeectl; + + if (tp->link_config.active_speed == SPEED_1000) + eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US; + else + eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US; + + tw32(TG3_CPMU_EEE_CTRL, eeectl); + + tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val); + + if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T || + val == TG3_CL45_D7_EEERES_STAT_LP_100TX) + tp->setlpicnt = 2; + } + + if (!tp->setlpicnt) { + val = tr32(TG3_CPMU_EEE_MODE); + tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE); + } +} + static int tg3_wait_macro_done(struct tg3 *tp) { int limit = 100; @@ -2921,6 +2968,44 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tg3_writephy(tp, MII_TG3_CTRL, new_adv); } + if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { + u32 val = 0; + + tw32(TG3_CPMU_EEE_MODE, + tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); + + /* Enable SM_DSP clock and tx 6dB coding. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_SMDSP_ENA | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && + !tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) + tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, + val | MII_TG3_DSP_CH34TP2_HIBW01); + + if (tp->link_config.autoneg == AUTONEG_ENABLE) { + /* Advertise 100-BaseTX EEE ability */ + if (tp->link_config.advertising & + (ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full)) + val |= TG3_CL45_D7_EEEADV_CAP_100TX; + /* Advertise 1000-BaseT EEE ability */ + if (tp->link_config.advertising & + (ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full)) + val |= TG3_CL45_D7_EEEADV_CAP_1000T; + } + tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, val); + + /* Turn off SM_DSP clock. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + } + if (tp->link_config.autoneg == AUTONEG_DISABLE && tp->link_config.speed != SPEED_INVALID) { u32 bmcr, orig_bmcr; @@ -3282,6 +3367,8 @@ relink: tw32_f(MAC_MODE, tp->mac_mode); udelay(40); + tg3_phy_eee_adjust(tp, current_link_up); + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { /* Polled via timer. */ tw32_f(MAC_EVENT, 0); @@ -7790,6 +7877,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(TG3_CPMU_LSPD_10MB_CLK, val); } + /* Enable MAC control of LPI */ + if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { + tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, + TG3_CPMU_EEE_LNKIDL_PCIE_NL0 | + TG3_CPMU_EEE_LNKIDL_UART_IDL); + + tw32_f(TG3_CPMU_EEE_CTRL, + TG3_CPMU_EEE_CTRL_EXIT_20_1_US); + + tw32_f(TG3_CPMU_EEE_MODE, + TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | + TG3_CPMU_EEEMD_LPI_IN_TX | + TG3_CPMU_EEEMD_LPI_IN_RX | + TG3_CPMU_EEEMD_EEE_ENABLE); + } + /* This works around an issue with Athlon chipsets on * B3 tigon3 silicon. This bit has no effect on any * other revision. But do not set this on PCI Express @@ -8598,6 +8701,12 @@ static void tg3_timer(unsigned long __opaque) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) tg3_periodic_fetch_stats(tp); + if (tp->setlpicnt && !--tp->setlpicnt) { + u32 val = tr32(TG3_CPMU_EEE_MODE); + tw32(TG3_CPMU_EEE_MODE, + val | TG3_CPMU_EEEMD_LPI_ENABLE); + } + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { u32 mac_stat; int phy_event; @@ -12432,6 +12541,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } } + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && + tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)) + tp->phy_flags |= TG3_PHYFLG_EEE_CAP; + if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 99fc30680217..8342190df0ff 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1091,7 +1091,26 @@ #define CPMU_MUTEX_GNT_DRIVER 0x00001000 #define TG3_CPMU_PHY_STRAP 0x00003664 #define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020 -/* 0x3664 --> 0x3800 unused */ +/* 0x3664 --> 0x36b0 unused */ + +#define TG3_CPMU_EEE_MODE 0x000036b0 +#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008 +#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080 +#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100 +#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200 +#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 +/* 0x36b4 --> 0x36b8 unused */ + +#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc +#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 +#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004 +/* 0x36c0 --> 0x36d0 unused */ + +#define TG3_CPMU_EEE_CTRL 0x000036d0 +#define TG3_CPMU_EEE_CTRL_EXIT_16_5_US 0x0000019d +#define TG3_CPMU_EEE_CTRL_EXIT_36_US 0x00000384 +#define TG3_CPMU_EEE_CTRL_EXIT_20_1_US 0x000001f8 +/* 0x36d4 --> 0x3800 unused */ /* Mbuf cluster free registers */ #define MBFREE_MODE 0x00003800 @@ -2082,6 +2101,8 @@ #define MII_TG3_DSP_TAP1 0x0001 #define MII_TG3_DSP_TAP1_AGCTGT_DFLT 0x0007 #define MII_TG3_DSP_AADJ1CH0 0x001f +#define MII_TG3_DSP_CH34TP2 0x4022 +#define MII_TG3_DSP_CH34TP2_HIBW01 0x0010 #define MII_TG3_DSP_AADJ1CH3 0x601f #define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 #define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 @@ -2148,6 +2169,14 @@ #define MII_TG3_TEST1_TRIM_EN 0x0010 #define MII_TG3_TEST1_CRC_EN 0x8000 +/* Clause 45 expansion registers */ +#define TG3_CL45_D7_EEEADV_CAP 0x003c +#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002 +#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004 +#define TG3_CL45_D7_EEERES_STAT 0x803e +#define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002 +#define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004 + /* Fast Ethernet Tranceiver definitions */ #define MII_TG3_FET_PTEST 0x17 @@ -2992,9 +3021,11 @@ struct tg3 { #define TG3_PHYFLG_BER_BUG 0x00008000 #define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 #define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 +#define TG3_PHYFLG_EEE_CAP 0x00040000 u32 led_ctrl; u32 phy_otp; + u32 setlpicnt; #define TG3_BPN_SIZE 24 char board_part_number[TG3_BPN_SIZE]; -- cgit v1.2.3 From f94e290eba2f98e8f759d273d9d04e8487fb4b6b Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:42 +0000 Subject: tg3: Cleanup tg3_alloc_rx_skb() src_map is no longer used in tg3_alloc_rx_skb(). Remove it. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f2d96ddd464e..84530d9f1f4b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4573,12 +4573,11 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, u32 opaque_key, u32 dest_idx_unmasked) { struct tg3_rx_buffer_desc *desc; - struct ring_info *map, *src_map; + struct ring_info *map; struct sk_buff *skb; dma_addr_t mapping; int skb_size, dest_idx; - src_map = NULL; switch (opaque_key) { case RXD_OPAQUE_RING_STD: dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; -- cgit v1.2.3 From 4803572815feea2dca9485a343a8556c9037e36e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:43 +0000 Subject: tg3: Don't allocate jumbo ring for 5780 class devs The 5714, 5715, and 5780 devices do not have a separate rx jumbo producer ring. This patch changes the code so that resources are not allocated for it. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 84530d9f1f4b..17ca0a37c9e7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6219,7 +6219,8 @@ static void tg3_rx_prodring_free(struct tg3 *tp, tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], tp->rx_pkt_map_sz); - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { + if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { for (i = 0; i <= tp->rx_jmb_ring_mask; i++) tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], TG3_RX_JMB_MAP_SZ); @@ -6246,7 +6247,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, if (tpr != &tp->napi[0].prodring) { memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE(tp)); - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) + if (tpr->rx_jmb_buffers) memset(&tpr->rx_jmb_buffers[0], 0, TG3_RX_JMB_BUFF_RING_SIZE(tp)); goto done; @@ -6289,7 +6290,8 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, } } - if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)) + if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) || + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) goto done; memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp)); @@ -6361,7 +6363,8 @@ static int tg3_rx_prodring_init(struct tg3 *tp, if (!tpr->rx_std) goto err_out; - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { + if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp), GFP_KERNEL); if (!tpr->rx_jmb_buffers) -- cgit v1.2.3 From 64c2218266996b562a8e940a95a887fc432daced Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:44 +0000 Subject: tg3: Report invalid link from tg3_get_settings() Currently the tg3 driver leaves the speed and duplex fields uninitialized in tg3_get_settings() if the device is not up. This can lead to some strange deductions in certain versions of ethtool. When the device is up and the link is down, the driver reports SPEED_INVALID and DUPLEX_INVALID for these fields. This patch makes the presentation consistent by returning SPEED_INVALID and DUPLEX_INVALID when the device has not been brought up as well. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 17ca0a37c9e7..5d30e67ffe69 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9807,6 +9807,9 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (netif_running(dev)) { cmd->speed = tp->link_config.active_speed; cmd->duplex = tp->link_config.active_duplex; + } else { + cmd->speed = SPEED_INVALID; + cmd->duplex = DUPLEX_INVALID; } cmd->phy_address = tp->phy_addr; cmd->transceiver = XCVR_INTERNAL; -- cgit v1.2.3 From 7c1a96a9966efc2eb33d1021569c5ef6ae6f5ecb Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 14 Oct 2010 10:37:45 +0000 Subject: tg3: Update version to 3.115 This patch updates the tg3 version to 3.115. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5d30e67ffe69..5b4c510dbced 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,10 +69,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 114 +#define TG3_MIN_NUM 115 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "September 30, 2010" +#define DRV_MODULE_RELDATE "October 14, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3 From d793fe8caa3911e6a1e826b45d4ee00d250cdec8 Mon Sep 17 00:00:00 2001 From: Nathan Holstein Date: Fri, 15 Oct 2010 11:54:02 -0400 Subject: Bluetooth: fix oops in l2cap_connect_req In error cases when the ACL is insecure or we fail to allocate a new struct sock, we jump to the "response" label. If so, "sk" will be null and the kernel crashes. Signed-off-by: Nathan Holstein Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd8401..dc6020570a32 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -2891,7 +2891,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd struct l2cap_chan_list *list = &conn->chan_list; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; - struct sock *parent, *uninitialized_var(sk); + struct sock *parent, *sk = NULL; int result, status = L2CAP_CS_NO_INFO; u16 dcid = 0, scid = __le16_to_cpu(req->scid); @@ -3000,7 +3000,7 @@ sendresp: L2CAP_INFO_REQ, sizeof(info), &info); } - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && + if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && result == L2CAP_CR_SUCCESS) { u8 buf[128]; l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; -- cgit v1.2.3 From 724829b3ad8e8aeb0aec46de383d35bfa1ad3875 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Oct 2010 01:06:20 -0700 Subject: tipc: Kill tipc_get_mode() completely. It's completely unused and exporting a static symbol makes no sense and breaks the build. Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- net/tipc/core.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/tipc/core.c b/net/tipc/core.c index c00530386e3b..e2a09eb8efd4 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -96,11 +96,6 @@ int tipc_net_id; int tipc_remote_management; -static int tipc_get_mode(void) -{ - return tipc_mode; -} - /** * tipc_buf_acquire - creates a TIPC message buffer * @size: message size (including TIPC header) @@ -246,7 +241,6 @@ MODULE_VERSION(TIPC_MOD_VER); EXPORT_SYMBOL(tipc_attach); EXPORT_SYMBOL(tipc_detach); -EXPORT_SYMBOL(tipc_get_mode); EXPORT_SYMBOL(tipc_createport); EXPORT_SYMBOL(tipc_deleteport); EXPORT_SYMBOL(tipc_ownidentity); -- cgit v1.2.3 From ccc901ee58cfb090a31216a6eda0f1e9dfc572fa Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Thu, 14 Oct 2010 13:58:26 +0000 Subject: tipc: Simplify bearer shutdown logic Optimize processing in TIPC's bearer shutdown code, including: 1. Remove an unnecessary check to see if TIPC bearer's can exist. 2. Don't release spinlocks before calling a media-specific disabling routine, since the routine can't sleep. 3. Make bearer_disable() operate directly on a struct bearer, instead of needlessly taking a name and then mapping that to the struct. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Reviewed-by: Neil Horman Signed-off-by: David S. Miller --- net/tipc/bearer.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 9c10c6b7c12b..fd9c06c68281 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -288,9 +288,6 @@ static struct bearer *bearer_find(const char *name) struct bearer *b_ptr; u32 i; - if (tipc_mode != TIPC_NET_MODE) - return NULL; - for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) return b_ptr; @@ -630,30 +627,17 @@ int tipc_block_bearer(const char *name) * Note: This routine assumes caller holds tipc_net_lock. */ -static int bearer_disable(const char *name) +static int bearer_disable(struct bearer *b_ptr) { - struct bearer *b_ptr; struct link *l_ptr; struct link *temp_l_ptr; - b_ptr = bearer_find(name); - if (!b_ptr) { - warn("Attempt to disable unknown bearer <%s>\n", name); - return -EINVAL; - } - - info("Disabling bearer <%s>\n", name); + info("Disabling bearer <%s>\n", b_ptr->publ.name); tipc_disc_stop_link_req(b_ptr->link_req); spin_lock_bh(&b_ptr->publ.lock); b_ptr->link_req = NULL; b_ptr->publ.blocked = 1; - if (b_ptr->media->disable_bearer) { - spin_unlock_bh(&b_ptr->publ.lock); - write_unlock_bh(&tipc_net_lock); - b_ptr->media->disable_bearer(&b_ptr->publ); - write_lock_bh(&tipc_net_lock); - spin_lock_bh(&b_ptr->publ.lock); - } + b_ptr->media->disable_bearer(&b_ptr->publ); list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { tipc_link_delete(l_ptr); } @@ -664,10 +648,16 @@ static int bearer_disable(const char *name) int tipc_disable_bearer(const char *name) { + struct bearer *b_ptr; int res; write_lock_bh(&tipc_net_lock); - res = bearer_disable(name); + b_ptr = bearer_find(name); + if (b_ptr == NULL) { + warn("Attempt to disable unknown bearer <%s>\n", name); + res = -EINVAL; + } else + res = bearer_disable(b_ptr); write_unlock_bh(&tipc_net_lock); return res; } @@ -680,13 +670,7 @@ void tipc_bearer_stop(void) for (i = 0; i < MAX_BEARERS; i++) { if (tipc_bearers[i].active) - tipc_bearers[i].publ.blocked = 1; - } - for (i = 0; i < MAX_BEARERS; i++) { - if (tipc_bearers[i].active) - bearer_disable(tipc_bearers[i].publ.name); + bearer_disable(&tipc_bearers[i]); } media_count = 0; } - - -- cgit v1.2.3 From cdd861d68d27a0d0ebe4e641d20d8cfa5cef405f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Oct 2010 09:18:53 +0000 Subject: ns83820: spin_lock_irq() => spin_lock() This is essentially cosmetic. At this point the IRQs are already disabled because we called spin_lock_irq(&dev->rx_info.lock). The real bug here was fixed back in 2006 in 3a10ccebe: "[PATCH] lock validator: fix ns83820.c irq-flags bug". Prior to that patch, it was a "spin_lock_irq is not nestable" type bug. The 2006 patch changes the unlock to not re-enable IRQs, which eliminates the potential deadlock. But this bit was missed. We should change the lock function as well so it balances nicely. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 3bbd0aab17e8..84134c766f3a 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -772,7 +772,7 @@ static int ns83820_setup_rx(struct net_device *ndev) phy_intr(ndev); /* Okay, let it rip */ - spin_lock_irq(&dev->misc_lock); + spin_lock(&dev->misc_lock); dev->IMR_cache |= ISR_PHY; dev->IMR_cache |= ISR_RXRCMP; //dev->IMR_cache |= ISR_RXERR; -- cgit v1.2.3 From 9756403b16cfeda85efe77e62832a2f6b5752fdf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Oct 2010 09:19:55 +0000 Subject: gianfar: fix double lock typo This should be a _restore() instead of a _save(). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/gianfar_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 9bda023c0235..ddab7036e375 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -538,7 +538,7 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) unlock_tx_qs(priv); unlock_rx_qs(priv); - local_irq_save(flags); + local_irq_restore(flags); for (i = 0; i < priv->num_rx_queues; i++) gfar_clean_rx_ring(priv->rx_queue[i], -- cgit v1.2.3 From 76b6717bc6ccb715b04e36efc26566a6313ede5f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 18 Oct 2010 11:13:30 +0200 Subject: netfilter: fix kconfig unmet dependency warning Fix netfilter kconfig unmet dependencies warning & spell out "compatible" while there. warning: (IP_NF_TARGET_TTL && NET && INET && NETFILTER && IP_NF_IPTABLES && NETFILTER_ADVANCED || IP6_NF_TARGET_HL && NET && INET && IPV6 && NETFILTER && IP6_NF_IPTABLES && NETFILTER_ADVANCED) selects NETFILTER_XT_TARGET_HL which has unmet direct dependencies ((IP_NF_MANGLE || IP6_NF_MANGLE) && NETFILTER_ADVANCED) Signed-off-by: Randy Dunlap Signed-off-by: Patrick McHardy --- net/ipv4/netfilter/Kconfig | 4 ++-- net/ipv6/netfilter/Kconfig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 1833bdbf9805..8e3350643b63 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -324,10 +324,10 @@ config IP_NF_TARGET_ECN config IP_NF_TARGET_TTL tristate '"TTL" target support' - depends on NETFILTER_ADVANCED + depends on NETFILTER_ADVANCED && IP_NF_MANGLE select NETFILTER_XT_TARGET_HL ---help--- - This is a backwards-compat option for the user's convenience + This is a backwards-compatible option for the user's convenience (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 29d643bcafa4..44d2eeac089b 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -132,10 +132,10 @@ config IP6_NF_MATCH_RT # The targets config IP6_NF_TARGET_HL tristate '"HL" hoplimit target support' - depends on NETFILTER_ADVANCED + depends on NETFILTER_ADVANCED && IP6_NF_MANGLE select NETFILTER_XT_TARGET_HL ---help--- - This is a backwards-compat option for the user's convenience + This is a backwards-compatible option for the user's convenience (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. -- cgit v1.2.3 From 57d3c7b09bd797b8db974557a71df8675a22601b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 4 Oct 2010 10:50:51 +0200 Subject: can: mcp251x: fix NOHZ local_softirq_pending 08 warning This patch replaces netif_rx() with netif_rx_ni() which has to be used from the threaded interrupt i.e. process context context. Thanks to Christian Pellegrin for pointing at the right fix: 481a8199142c050b72bff8a1956a49fd0a75bbe0 by Oliver Hartkopp. Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index b11a0cb5ed81..c06e02382eca 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -451,7 +451,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) priv->net->stats.rx_packets++; priv->net->stats.rx_bytes += frame->can_dlc; - netif_rx(skb); + netif_rx_ni(skb); } static void mcp251x_hw_sleep(struct spi_device *spi) @@ -676,7 +676,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) if (skb) { frame->can_id = can_id; frame->data[1] = data1; - netif_rx(skb); + netif_rx_ni(skb); } else { dev_err(&net->dev, "cannot allocate error skb\n"); -- cgit v1.2.3 From 711e4d6eccd72c57938228b8e0c29cb205527032 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 30 Sep 2010 09:46:00 +0200 Subject: can: mcp251x: increase rx_errors on overflow, not only rx_over_errors Signed-off-by: Sascha Hauer Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index c06e02382eca..fdea752f398f 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -816,10 +816,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf & CANINTF_ERRIF) { /* Handle overflow counters */ if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { - if (eflag & EFLG_RX0OVR) + if (eflag & EFLG_RX0OVR) { net->stats.rx_over_errors++; - if (eflag & EFLG_RX1OVR) + net->stats.rx_errors++; + } + if (eflag & EFLG_RX1OVR) { net->stats.rx_over_errors++; + net->stats.rx_errors++; + } can_id |= CAN_ERR_CRTL; data1 |= CAN_ERR_CRTL_RX_OVERFLOW; } -- cgit v1.2.3 From f3a3ed3115d39463dc6672454bfbeaff46811a37 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 28 Sep 2010 09:53:35 +0200 Subject: can: mcp251x: allow to read two registers in one spi transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch bases on work done earlier by David Jander. Signed-off-by: Sascha Hauer Acked-by: David Jander Signed-off-by: Uwe Kleine-König Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index fdea752f398f..9b3466aed06d 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -319,6 +319,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) return val; } +static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, + uint8_t *v1, uint8_t *v2) +{ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); + + priv->spi_tx_buf[0] = INSTRUCTION_READ; + priv->spi_tx_buf[1] = reg; + + mcp251x_spi_trans(spi, 4); + + *v1 = priv->spi_rx_buf[2]; + *v2 = priv->spi_rx_buf[3]; +} + static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); @@ -754,10 +768,11 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mutex_lock(&priv->mcp_lock); while (!priv->force_quit) { enum can_state new_state; - u8 intf = mcp251x_read_reg(spi, CANINTF); - u8 eflag; + u8 intf, eflag; int can_id = 0, data1 = 0; + mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); + if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); /* Free one buffer ASAP */ @@ -770,7 +785,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mcp251x_write_bits(spi, CANINTF, intf, 0x00); - eflag = mcp251x_read_reg(spi, EFLG); mcp251x_write_reg(spi, EFLG, 0x00); /* Update can state */ -- cgit v1.2.3 From 7e15de3a73899903f33975b1ce57cf59c616d1d9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 28 Sep 2010 10:00:47 +0200 Subject: can: mcp251x: read-modify-write eflag only when needed Use read-modify-write instead of a simple write to change the register contents, to close existing the race window between the original manual read and write. Signed-off-by: Sascha Hauer Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 9b3466aed06d..7e2f951002a5 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -785,7 +785,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mcp251x_write_bits(spi, CANINTF, intf, 0x00); - mcp251x_write_reg(spi, EFLG, 0x00); + if (eflag) + mcp251x_write_bits(spi, EFLG, eflag, 0x00); /* Update can state */ if (eflag & EFLG_TXBO) { -- cgit v1.2.3 From d3cd15657516141adce387810be8cb377baf020e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 28 Sep 2010 10:18:34 +0200 Subject: can: mcp251x: write intf only when needed This patch introduces a variable "clear_intf" that hold the bits that should be cleared. Only read-modify-write register if "clear_intf" is set. Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7e2f951002a5..f5e2edd09ce4 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -125,6 +125,8 @@ # define CANINTF_TX0IF 0x04 # define CANINTF_RX1IF 0x02 # define CANINTF_RX0IF 0x01 +# define CANINTF_ERR_TX \ + (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) #define EFLG 0x2d # define EFLG_EWARN 0x01 # define EFLG_RXWAR 0x02 @@ -769,10 +771,12 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) while (!priv->force_quit) { enum can_state new_state; u8 intf, eflag; + u8 clear_intf = 0; int can_id = 0, data1 = 0; mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); + /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); /* Free one buffer ASAP */ @@ -780,10 +784,17 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) 0x00); } - if (intf & CANINTF_RX1IF) + /* receive buffer 1 */ + if (intf & CANINTF_RX1IF) { mcp251x_hw_rx(spi, 1); + clear_intf |= CANINTF_RX1IF; + } - mcp251x_write_bits(spi, CANINTF, intf, 0x00); + /* any error or tx interrupt we need to clear? */ + if (intf & CANINTF_ERR_TX) + clear_intf |= intf & CANINTF_ERR_TX; + if (clear_intf) + mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); if (eflag) mcp251x_write_bits(spi, EFLG, eflag, 0x00); -- cgit v1.2.3 From 43f974cdb4ab6d65f849610deb9ef738d62b2e65 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 18 Oct 2010 11:22:05 +0200 Subject: netfilter: install missing ebtables headers for userspace The ebt_ip6.h and ebt_nflog.h headers are not not known to Kbuild and therefore not installed by make headers_install. Fix that up. Signed-off-by: Nick Bowler Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/Kbuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild index d4d78672873e..e48f1a3f5a4a 100644 --- a/include/linux/netfilter_bridge/Kbuild +++ b/include/linux/netfilter_bridge/Kbuild @@ -3,11 +3,13 @@ header-y += ebt_among.h header-y += ebt_arp.h header-y += ebt_arpreply.h header-y += ebt_ip.h +header-y += ebt_ip6.h header-y += ebt_limit.h header-y += ebt_log.h header-y += ebt_mark_m.h header-y += ebt_mark_t.h header-y += ebt_nat.h +header-y += ebt_nflog.h header-y += ebt_pkttype.h header-y += ebt_redirect.h header-y += ebt_stp.h -- cgit v1.2.3 From f1f8c6cbe6f08f93ac2a4ca19625891d8a82b7f8 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 18 Oct 2010 15:00:18 +0200 Subject: can: mcp251x: Don't use pdata->model for chip selection anymore Since commit e446630c960946b5c1762e4eadb618becef599e7, i.e. v2.6.35-rc1, the mcp251x chip model can be selected via the modalias member in the struct spi_board_info. The driver stores the actual model in the struct mcp251x_platform_data. From the driver point of view the platform_data should be read only. Since all in-tree users of the mcp251x have already been converted to the modalias method, this patch moves the "model" member from the struct mcp251x_platform_data to the driver's private data structure. Signed-off-by: Marc Kleine-Budde Cc: Christian Pellegrin Cc: Marc Zyngier --- drivers/net/can/mcp251x.c | 24 ++++++++++++------------ include/linux/can/platform/mcp251x.h | 4 ---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index f5e2edd09ce4..0386bed43551 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -38,14 +38,14 @@ * static struct mcp251x_platform_data mcp251x_info = { * .oscillator_frequency = 8000000, * .board_specific_setup = &mcp251x_setup, - * .model = CAN_MCP251X_MCP2510, * .power_enable = mcp251x_power_enable, * .transceiver_enable = NULL, * }; * * static struct spi_board_info spi_board_info[] = { * { - * .modalias = "mcp251x", + * .modalias = "mcp2510", + * // or "mcp2515" depending on your controller * .platform_data = &mcp251x_info, * .irq = IRQ_EINT13, * .max_speed_hz = 2*1000*1000, @@ -224,10 +224,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = { .brp_inc = 1, }; +enum mcp251x_model { + CAN_MCP251X_MCP2510 = 0x2510, + CAN_MCP251X_MCP2515 = 0x2515, +}; + struct mcp251x_priv { struct can_priv can; struct net_device *net; struct spi_device *spi; + enum mcp251x_model model; struct mutex mcp_lock; /* SPI device lock */ @@ -362,10 +368,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, int len, int tx_buf_idx) { - struct mcp251x_platform_data *pdata = spi->dev.platform_data; struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - if (pdata->model == CAN_MCP251X_MCP2510) { + if (priv->model == CAN_MCP251X_MCP2510) { int i; for (i = 1; i < TXBDAT_OFF + len; i++) @@ -408,9 +413,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, int buf_idx) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - struct mcp251x_platform_data *pdata = spi->dev.platform_data; - if (pdata->model == CAN_MCP251X_MCP2510) { + if (priv->model == CAN_MCP251X_MCP2510) { int i, len; for (i = 1; i < RXBDAT_OFF; i++) @@ -951,16 +955,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) struct net_device *net; struct mcp251x_priv *priv; struct mcp251x_platform_data *pdata = spi->dev.platform_data; - int model = spi_get_device_id(spi)->driver_data; int ret = -ENODEV; if (!pdata) /* Platform data is required for osc freq */ goto error_out; - if (model) - pdata->model = model; - /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); if (!net) { @@ -977,6 +977,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) priv->can.clock.freq = pdata->oscillator_frequency / 2; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; + priv->model = spi_get_device_id(spi)->driver_data; priv->net = net; dev_set_drvdata(&spi->dev, priv); @@ -1150,8 +1151,7 @@ static int mcp251x_can_resume(struct spi_device *spi) #define mcp251x_can_resume NULL #endif -static struct spi_device_id mcp251x_id_table[] = { - { "mcp251x", 0 /* Use pdata.model */ }, +static const struct spi_device_id mcp251x_id_table[] = { { "mcp2510", CAN_MCP251X_MCP2510 }, { "mcp2515", CAN_MCP251X_MCP2515 }, { }, diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h index dba28268e651..8e20540043f5 100644 --- a/include/linux/can/platform/mcp251x.h +++ b/include/linux/can/platform/mcp251x.h @@ -12,7 +12,6 @@ /** * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz - * @model: - actual type of chip * @board_specific_setup: - called before probing the chip (power,reset) * @transceiver_enable: - called to power on/off the transceiver * @power_enable: - called to power on/off the mcp *and* the @@ -25,9 +24,6 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; - int model; -#define CAN_MCP251X_MCP2510 0x2510 -#define CAN_MCP251X_MCP2515 0x2515 int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); -- cgit v1.2.3 From beab675cb45f28a4a76780e43fd03e33bc773555 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 23 Sep 2010 21:34:28 +0200 Subject: can: mcp251x: define helper functions mcp251x_is_2510, mcp251x_is_2515 Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 0386bed43551..7f8aa4ce02c5 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -258,6 +258,16 @@ struct mcp251x_priv { int restart_tx; }; +#define MCP251X_IS(_model) \ +static inline int mcp251x_is_##_model(struct spi_device *spi) \ +{ \ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \ + return priv->model == CAN_MCP251X_MCP##_model; \ +} + +MCP251X_IS(2510); +MCP251X_IS(2515); + static void mcp251x_clean(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); @@ -370,7 +380,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - if (priv->model == CAN_MCP251X_MCP2510) { + if (mcp251x_is_2510(spi)) { int i; for (i = 1; i < TXBDAT_OFF + len; i++) @@ -414,7 +424,7 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - if (priv->model == CAN_MCP251X_MCP2510) { + if (mcp251x_is_2510(spi)) { int i, len; for (i = 1; i < RXBDAT_OFF; i++) -- cgit v1.2.3 From 9c473fc33915ddb14b71a4929c838c22b20a24ce Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 4 Oct 2010 12:09:31 +0200 Subject: can: mcp251x: optimize 2515, rx int gets cleared automatically Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger --- drivers/net/can/mcp251x.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7f8aa4ce02c5..c664be261e98 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -793,15 +793,20 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); - /* Free one buffer ASAP */ - mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, - 0x00); + /* + * Free one buffer ASAP + * (The MCP2515 does this automatically.) + */ + if (mcp251x_is_2510(spi)) + mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); } /* receive buffer 1 */ if (intf & CANINTF_RX1IF) { mcp251x_hw_rx(spi, 1); - clear_intf |= CANINTF_RX1IF; + /* the MCP2515 does this automatically */ + if (mcp251x_is_2510(spi)) + clear_intf |= CANINTF_RX1IF; } /* any error or tx interrupt we need to clear? */ -- cgit v1.2.3 From fe78d2637ad9acc6414e36ce781aadc8c77d560d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 17 Oct 2010 23:02:20 +0000 Subject: bnx2x: Optimized the branching in the bnx2x_rx_int() Optimized the branching in the bnx2x_rx_int() based on the fact that FP CQE will always have at least one of START or STOP flags set, so if not both bits are set and START bit is not set, then it's a STOP bit that is set. Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 97ef674dcc34..cb2a3d625ad1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -507,8 +507,11 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); pad = cqe->fast_path_cqe.placement_offset; - /* If CQE is marked both TPA_START and TPA_END - it is a non-TPA CQE */ + /* - If CQE is marked both TPA_START and TPA_END it is + * a non-TPA CQE. + * - FP CQE will always have either TPA_START or/and + * TPA_STOP flags set. + */ if ((!fp->disable_tpa) && (TPA_TYPE(cqe_fp_flags) != (TPA_TYPE_START | TPA_TYPE_END))) { @@ -526,9 +529,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) bnx2x_set_skb_rxhash(bp, cqe, skb); goto next_rx; - } - - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) { + } else { /* TPA_STOP */ DP(NETIF_MSG_RX_STATUS, "calling tpa_stop on queue %d\n", queue); -- cgit v1.2.3 From e3dba8141b651dd8f560a2fd9513b1d26f447f9d Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:05:09 +0000 Subject: bnx2x: remove redundant commands during error handling Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index cb2a3d625ad1..b037dd2db8e5 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1289,8 +1289,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (rc) { BNX2X_ERR("HW init failed, aborting\n"); bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); goto load_error2; } -- cgit v1.2.3 From adf5f6a18f2cbb215394599981fb48473b526faa Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:10:02 +0000 Subject: bnx2x: do not deal with power if no capability Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index b037dd2db8e5..afff58c52d4f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1521,6 +1521,12 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) { u16 pmcsr; + /* If there is no power capability, silently succeed */ + if (!bp->pm_cap) { + DP(NETIF_MSG_HW, "No power capability. Breaking.\n"); + return 0; + } + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); switch (state) { -- cgit v1.2.3 From c8e4f48a8eb236eb672c6da0731ee01a633844f0 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:09:30 +0000 Subject: bnx2x: Use correct FW constant for header padding the value of the constant is the same, but it's clearer to use original constant provided by HSI Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index afff58c52d4f..1966ceeefcd4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -831,7 +831,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) int i, j; bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + - BNX2X_FW_IP_HDR_ALIGN_PAD; + IP_HEADER_ALIGNMENT_PADDING; DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 7f52cec9bb99..5bfe0ab1d2d4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1032,6 +1032,4 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -#define BNX2X_FW_IP_HDR_ALIGN_PAD 2 /* FW places hdr with this padding */ - #endif /* BNX2X_CMN_H */ -- cgit v1.2.3 From 030f3356b64a129a1ab34175491a8175bef98e6e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:08:53 +0000 Subject: bnx2x: remove unnecessary FUNC_FLG_RSS flag and related As suggested by: Joe Perches Although RSS is meaningless when there is a single HW queue we still need it enabled in order to have HW Rx hash generated. Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 13 +++----- drivers/net/bnx2x/bnx2x_main.c | 70 ++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 49 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index c49b643e009b..556cad5ed012 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1180,15 +1180,10 @@ struct bnx2x { TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY /* func init flags */ -#define FUNC_FLG_RSS 0x0001 -#define FUNC_FLG_STATS 0x0002 -/* removed FUNC_FLG_UNMATCHED 0x0004 */ -#define FUNC_FLG_TPA 0x0008 -#define FUNC_FLG_SPQ 0x0010 -#define FUNC_FLG_LEADING 0x0020 /* PF only */ - -#define FUNC_CONFIG(flgs) ((flgs) & (FUNC_FLG_RSS | FUNC_FLG_TPA | \ - FUNC_FLG_LEADING)) +#define FUNC_FLG_STATS 0x0001 +#define FUNC_FLG_TPA 0x0002 +#define FUNC_FLG_SPQ 0x0004 +#define FUNC_FLG_LEADING 0x0008 /* PF only */ struct rxq_pause_params { u16 bd_th_lo; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index ead524bca8f2..012c093cb432 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2284,35 +2284,31 @@ void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) { - if (FUNC_CONFIG(p->func_flgs)) { - struct tstorm_eth_function_common_config tcfg = {0}; - - /* tpa */ - if (p->func_flgs & FUNC_FLG_TPA) - tcfg.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - /* set rss flags */ - if (p->func_flgs & FUNC_FLG_RSS) { - u16 rss_flgs = (p->rss->mode << - TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); - - if (p->rss->cap & RSS_IPV4_CAP) - rss_flgs |= RSS_IPV4_CAP_MASK; - if (p->rss->cap & RSS_IPV4_TCP_CAP) - rss_flgs |= RSS_IPV4_TCP_CAP_MASK; - if (p->rss->cap & RSS_IPV6_CAP) - rss_flgs |= RSS_IPV6_CAP_MASK; - if (p->rss->cap & RSS_IPV6_TCP_CAP) - rss_flgs |= RSS_IPV6_TCP_CAP_MASK; - - tcfg.config_flags |= rss_flgs; - tcfg.rss_result_mask = p->rss->result_mask; + struct tstorm_eth_function_common_config tcfg = {0}; + u16 rss_flgs; - } + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - storm_memset_func_cfg(bp, &tcfg, p->func_id); - } + /* set rss flags */ + rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); + + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; + + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; + + storm_memset_func_cfg(bp, &tcfg, p->func_id); /* Enable the function in the FW */ storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); @@ -2479,23 +2475,17 @@ void bnx2x_pf_init(struct bnx2x *bp) else flags |= FUNC_FLG_TPA; + /* function setup */ + /** * Although RSS is meaningless when there is a single HW queue we * still need it enabled in order to have HW Rx hash generated. - * - * if (is_eth_multi(bp)) - * flags |= FUNC_FLG_RSS; */ - flags |= FUNC_FLG_RSS; - - /* function setup */ - if (flags & FUNC_FLG_RSS) { - rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | - RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); - rss.mode = bp->multi_mode; - rss.result_mask = MULTI_MASK; - func_init.rss = &rss; - } + rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | + RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); + rss.mode = bp->multi_mode; + rss.result_mask = MULTI_MASK; + func_init.rss = &rss; func_init.func_flgs = flags; func_init.pf_id = BP_FUNC(bp); -- cgit v1.2.3 From d8e62719ea63daf6afde2d2d09fb861c1559711e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 17 Oct 2010 23:08:55 +0000 Subject: bnx2x: update version to 1.60.00-2 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 556cad5ed012..01b8d8504773 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-1" -#define DRV_MODULE_RELDATE "2010/10/06" +#define DRV_MODULE_VERSION "1.60.00-2" +#define DRV_MODULE_RELDATE "2010/10/18" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- cgit v1.2.3 From 27a954bd560f3e385bbed38fde3051fe718b8d75 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 17 Oct 2010 15:11:22 +0000 Subject: IPv4: route.c: Change checks against 0xffffffff to ipv4_is_lbcast() Change a few checks against the hardcoded broadcast address, 0xffffffff, to ipv4_is_lbcast(). Remove some existing checks using ipv4_is_lbcast() that are now obviously superfluous. Signed-off-by: Andy Walls Signed-off-by: David S. Miller --- net/ipv4/route.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0755aa4af86c..ff98983d2a45 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2124,7 +2124,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, ipv4_is_loopback(saddr)) goto martian_source; - if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0)) + if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0)) goto brd_input; /* Accept zero addresses only to limited broadcast; @@ -2133,8 +2133,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (ipv4_is_zeronet(saddr)) goto martian_source; - if (ipv4_is_lbcast(daddr) || ipv4_is_zeronet(daddr) || - ipv4_is_loopback(daddr)) + if (ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr)) goto martian_destination; /* @@ -2367,11 +2366,11 @@ static int __mkroute_output(struct rtable **result, if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags & IFF_LOOPBACK)) return -EINVAL; - if (fl->fl4_dst == htonl(0xFFFFFFFF)) + if (ipv4_is_lbcast(fl->fl4_dst)) res->type = RTN_BROADCAST; else if (ipv4_is_multicast(fl->fl4_dst)) res->type = RTN_MULTICAST; - else if (ipv4_is_lbcast(fl->fl4_dst) || ipv4_is_zeronet(fl->fl4_dst)) + else if (ipv4_is_zeronet(fl->fl4_dst)) return -EINVAL; if (dev_out->flags & IFF_LOOPBACK) @@ -2530,7 +2529,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (oldflp->oif == 0 && (ipv4_is_multicast(oldflp->fl4_dst) || - oldflp->fl4_dst == htonl(0xFFFFFFFF))) { + ipv4_is_lbcast(oldflp->fl4_dst))) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ dev_out = __ip_dev_find(net, oldflp->fl4_src, false); if (dev_out == NULL) @@ -2574,7 +2573,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, goto out; /* Wrong error code */ if (ipv4_is_local_multicast(oldflp->fl4_dst) || - oldflp->fl4_dst == htonl(0xFFFFFFFF)) { + ipv4_is_lbcast(oldflp->fl4_dst)) { if (!fl.fl4_src) fl.fl4_src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK); -- cgit v1.2.3 From 3666e0b04f092f9d9da8a6d6a3820de6c870407c Mon Sep 17 00:00:00 2001 From: amit salecha Date: Mon, 18 Oct 2010 01:47:48 +0000 Subject: qlcnic: update ethtool stats Added statistics for Nic Partition supported adapter. These statistics are maintined in device. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 73 +++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 2568aa665024..25e93a53fca0 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -78,7 +78,25 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { }; +static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = { + "rx unicast frames", + "rx multicast frames", + "rx broadcast frames", + "rx dropped frames", + "rx errors", + "rx local frames", + "rx numbytes", + "tx unicast frames", + "tx multicast frames", + "tx broadcast frames", + "tx dropped frames", + "tx errors", + "tx local frames", + "tx numbytes", +}; + #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) +#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats) static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_on_offline", @@ -625,10 +643,13 @@ static int qlcnic_reg_test(struct net_device *dev) static int qlcnic_get_sset_count(struct net_device *dev, int sset) { + struct qlcnic_adapter *adapter = netdev_priv(dev); switch (sset) { case ETH_SS_TEST: return QLCNIC_TEST_LEN; case ETH_SS_STATS: + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN; return QLCNIC_STATS_LEN; default: return -EOPNOTSUPP; @@ -795,7 +816,8 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, static void qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data) { - int index; + struct qlcnic_adapter *adapter = netdev_priv(dev); + int index, i; switch (stringset) { case ETH_SS_TEST: @@ -808,16 +830,43 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data) qlcnic_gstrings_stats[index].stat_string, ETH_GSTRING_LEN); } - break; + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) { + memcpy(data + index * ETH_GSTRING_LEN, + qlcnic_device_gstrings_stats[i], + ETH_GSTRING_LEN); + } } } +#define QLCNIC_FILL_ESWITCH_STATS(VAL1) \ + (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1) + +static void +qlcnic_fill_device_stats(int *index, u64 *data, + struct __qlcnic_esw_statistics *stats) +{ + int ind = *index; + + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes); + + *index = ind; +} + static void qlcnic_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 * data) { struct qlcnic_adapter *adapter = netdev_priv(dev); - int index; + struct qlcnic_esw_statistics port_stats; + int index, ret; for (index = 0; index < QLCNIC_STATS_LEN; index++) { char *p = @@ -827,6 +876,24 @@ qlcnic_get_ethtool_stats(struct net_device *dev, (qlcnic_gstrings_stats[index].sizeof_stat == sizeof(u64)) ? *(u64 *)p:(*(u32 *)p); } + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + + memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics)); + ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + QLCNIC_QUERY_RX_COUNTER, &port_stats.rx); + if (ret) + return; + + qlcnic_fill_device_stats(&index, data, &port_stats.rx); + + ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + QLCNIC_QUERY_TX_COUNTER, &port_stats.tx); + if (ret) + return; + + qlcnic_fill_device_stats(&index, data, &port_stats.tx); } static int qlcnic_set_tx_csum(struct net_device *dev, u32 data) -- cgit v1.2.3 From 7a9905e64272c8021a8cfaf6015dd0fb8eeeb378 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Mon, 18 Oct 2010 02:03:41 +0000 Subject: netxen: fix race in tx stop queue There is race between netif_stop_queue and netif_stopped_queue check.So check once again if buffers are available to avoid race. With above logic we can also get rid of tx lock in process_cmd_ring. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 5 ++++- drivers/net/netxen/netxen_nic_hw.c | 10 ++++++++-- drivers/net/netxen/netxen_nic_init.c | 10 +++------- drivers/net/netxen/netxen_nic_main.c | 15 +++++++-------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6dca3574e355..92f89af0720e 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -175,7 +175,10 @@ #define MAX_NUM_CARDS 4 #define MAX_BUFFERS_PER_CMD 32 -#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4) +#define MAX_TSO_HEADER_DESC 2 +#define MGMT_CMD_DESC_RESV 4 +#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ + + MGMT_CMD_DESC_RESV) #define NX_MAX_TX_TIMEOUTS 2 /* diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 29d7b93d0493..10e2f13d8903 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -598,8 +598,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, if (nr_desc >= netxen_tx_avail(tx_ring)) { netif_tx_stop_queue(tx_ring->txq); - __netif_tx_unlock_bh(tx_ring->txq); - return -EBUSY; + smp_mb(); + if (netxen_tx_avail(tx_ring) > nr_desc) { + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) + netif_tx_wake_queue(tx_ring->txq); + } else { + __netif_tx_unlock_bh(tx_ring->txq); + return -EBUSY; + } } do { diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index a2d805aa75cd..95fe552aa279 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1763,14 +1763,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) smp_mb(); - if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { - __netif_tx_lock(tx_ring->txq, smp_processor_id()); - if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) { + if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) netif_wake_queue(netdev); - adapter->tx_timeo_cnt = 0; - } - __netif_tx_unlock(tx_ring->txq); - } + adapter->tx_timeo_cnt = 0; } /* * If everything is freed up to consumer then check if the ring is full diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2c6ceeb592b3..83ee5544aced 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -125,11 +125,6 @@ netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring) { NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer); - - if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) { - netif_stop_queue(adapter->netdev); - smp_mb(); - } } static uint32_t crb_cmd_consumer[4] = { @@ -1209,7 +1204,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter, adapter->max_mc_count = 16; netdev->netdev_ops = &netxen_netdev_ops; - netdev->watchdog_timeo = 2*HZ; + netdev->watchdog_timeo = 5*HZ; netxen_nic_change_mtu(netdev, netdev->mtu); @@ -1825,9 +1820,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* 4 fragments per cmd des */ no_of_desc = (frag_count + 3) >> 2; - if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) { + if (unlikely(netxen_tx_avail(tx_ring) <= TX_STOP_THRESH)) { netif_stop_queue(netdev); - return NETDEV_TX_BUSY; + smp_mb(); + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) + netif_start_queue(netdev); + else + return NETDEV_TX_BUSY; } producer = tx_ring->producer; -- cgit v1.2.3 From dce87b960cf4794141f067d8c8180ccc6716513f Mon Sep 17 00:00:00 2001 From: amit salecha Date: Mon, 18 Oct 2010 02:03:42 +0000 Subject: netxen: mask correctable error HW workaround: Disable logging of correctable error for some NX3031 based adapter. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 4 ++-- drivers/net/netxen/netxen_nic_main.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 10e2f13d8903..4b4ac7106786 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -1822,14 +1822,14 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) if (netxen_rom_fast_read(adapter, offset, &board_type)) return -EIO; - adapter->ahw.board_type = board_type; - if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I); if ((gpio & 0x8000) == 0) board_type = NETXEN_BRDTYPE_P3_10G_TP; } + adapter->ahw.board_type = board_type; + switch (board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.port_type = NETXEN_NIC_GBE; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 83ee5544aced..6f111691aca4 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1249,6 +1249,28 @@ netxen_setup_netdev(struct netxen_adapter *adapter, return 0; } +#ifdef CONFIG_PCIEAER +static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + struct pci_dev *root = pdev->bus->self; + u32 aer_pos; + + if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM && + adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) + return; + + if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT) + return; + + aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR); + if (!aer_pos) + return; + + pci_write_config_dword(root, aer_pos + PCI_ERR_COR_MASK, 0xffff); +} +#endif + static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1317,6 +1339,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iounmap; } +#ifdef CONFIG_PCIEAER + netxen_mask_aer_correctable(adapter); +#endif + /* Mezz cards have PCI function 0,2,3 enabled */ switch (adapter->ahw.board_type) { case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: -- cgit v1.2.3 From 12dcd86b75d571772512676ab301279952efc0b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Oct 2010 17:27:10 +0000 Subject: igb: fix stats handling There are currently some problems with igb. - On 32bit arches, maintaining 64bit counters without proper synchronization between writers and readers. - Stats updated every two seconds, as reported by Jesper. (Jesper provided a patch for this) - Potential problem between worker thread and ethtool -S This patch uses u64_stats_sync, and convert everything to be 64bit safe, SMP safe, even on 32bit arches. It integrates Jesper idea of providing accurate stats at the time user reads them. Signed-off-by: Eric Dumazet Tested-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb.h | 9 +++- drivers/net/igb/igb_ethtool.c | 52 +++++++++++++------ drivers/net/igb/igb_main.c | 113 +++++++++++++++++++++++++++++++----------- 3 files changed, 129 insertions(+), 45 deletions(-) diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 44e0ff1494e0..edab9c442399 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -159,6 +159,7 @@ struct igb_tx_queue_stats { u64 packets; u64 bytes; u64 restart_queue; + u64 restart_queue2; }; struct igb_rx_queue_stats { @@ -210,11 +211,14 @@ struct igb_ring { /* TX */ struct { struct igb_tx_queue_stats tx_stats; + struct u64_stats_sync tx_syncp; + struct u64_stats_sync tx_syncp2; bool detect_tx_hung; }; /* RX */ struct { struct igb_rx_queue_stats rx_stats; + struct u64_stats_sync rx_syncp; u32 rx_buffer_len; }; }; @@ -288,6 +292,9 @@ struct igb_adapter { struct timecompare compare; struct hwtstamp_config hwtstamp_config; + spinlock_t stats64_lock; + struct rtnl_link_stats64 stats64; + /* structs defined in e1000_hw.h */ struct e1000_hw hw; struct e1000_hw_stats stats; @@ -357,7 +364,7 @@ extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *); extern void igb_unmap_and_free_tx_resource(struct igb_ring *, struct igb_buffer *); extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int); -extern void igb_update_stats(struct igb_adapter *); +extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); extern bool igb_has_link(struct igb_adapter *adapter); extern void igb_set_ethtool_ops(struct net_device *); extern void igb_power_up_link(struct igb_adapter *); diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 26bf6a13d1c1..a70e16bcfa7e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -90,8 +90,8 @@ static const struct igb_stats igb_gstrings_stats[] = { #define IGB_NETDEV_STAT(_net_stat) { \ .stat_string = __stringify(_net_stat), \ - .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ - .stat_offset = offsetof(struct net_device_stats, _net_stat) \ + .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \ + .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \ } static const struct igb_stats igb_gstrings_net_stats[] = { IGB_NETDEV_STAT(rx_errors), @@ -111,8 +111,9 @@ static const struct igb_stats igb_gstrings_net_stats[] = { (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats)) #define IGB_RX_QUEUE_STATS_LEN \ (sizeof(struct igb_rx_queue_stats) / sizeof(u64)) -#define IGB_TX_QUEUE_STATS_LEN \ - (sizeof(struct igb_tx_queue_stats) / sizeof(u64)) + +#define IGB_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */ + #define IGB_QUEUE_STATS_LEN \ ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ IGB_RX_QUEUE_STATS_LEN) + \ @@ -2070,12 +2071,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct igb_adapter *adapter = netdev_priv(netdev); - struct net_device_stats *net_stats = &netdev->stats; - u64 *queue_stat; - int i, j, k; + struct rtnl_link_stats64 *net_stats = &adapter->stats64; + unsigned int start; + struct igb_ring *ring; + int i, j; char *p; - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, net_stats); for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { p = (char *)adapter + igb_gstrings_stats[i].stat_offset; @@ -2088,15 +2091,36 @@ static void igb_get_ethtool_stats(struct net_device *netdev, sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { - queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats; - for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++) - data[i] = queue_stat[k]; + u64 restart2; + + ring = adapter->tx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i+1] = ring->tx_stats.bytes; + data[i+2] = ring->tx_stats.restart_queue; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start)); + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp2, start)); + data[i+2] += restart2; + + i += IGB_TX_QUEUE_STATS_LEN; } for (j = 0; j < adapter->num_rx_queues; j++) { - queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats; - for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++) - data[i] = queue_stat[k]; + ring = adapter->rx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i+1] = ring->rx_stats.bytes; + data[i+2] = ring->rx_stats.drops; + data[i+3] = ring->rx_stats.csum_err; + data[i+4] = ring->rx_stats.alloc_failed; + } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start)); + i += IGB_RX_QUEUE_STATS_LEN; } + spin_unlock(&adapter->stats64_lock); } static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 5b04eff2fd23..b8dccc0ac089 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -96,7 +96,6 @@ static int igb_setup_all_rx_resources(struct igb_adapter *); static void igb_free_all_tx_resources(struct igb_adapter *); static void igb_free_all_rx_resources(struct igb_adapter *); static void igb_setup_mrqc(struct igb_adapter *); -void igb_update_stats(struct igb_adapter *); static int igb_probe(struct pci_dev *, const struct pci_device_id *); static void __devexit igb_remove(struct pci_dev *pdev); static int igb_sw_init(struct igb_adapter *); @@ -113,7 +112,8 @@ static void igb_update_phy_info(unsigned long); static void igb_watchdog(unsigned long); static void igb_watchdog_task(struct work_struct *); static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *); -static struct net_device_stats *igb_get_stats(struct net_device *); +static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats); static int igb_change_mtu(struct net_device *, int); static int igb_set_mac(struct net_device *, void *); static void igb_set_uta(struct igb_adapter *adapter); @@ -1536,7 +1536,9 @@ void igb_down(struct igb_adapter *adapter) netif_carrier_off(netdev); /* record the stats before reset*/ - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + spin_unlock(&adapter->stats64_lock); adapter->link_speed = 0; adapter->link_duplex = 0; @@ -1689,7 +1691,7 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_open = igb_open, .ndo_stop = igb_close, .ndo_start_xmit = igb_xmit_frame_adv, - .ndo_get_stats = igb_get_stats, + .ndo_get_stats64 = igb_get_stats64, .ndo_set_rx_mode = igb_set_rx_mode, .ndo_set_multicast_list = igb_set_rx_mode, .ndo_set_mac_address = igb_set_mac, @@ -2276,6 +2278,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + spin_lock_init(&adapter->stats64_lock); #ifdef CONFIG_PCI_IOV if (hw->mac.type == e1000_82576) adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs; @@ -3483,7 +3486,9 @@ static void igb_watchdog_task(struct work_struct *work) } } - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + spin_unlock(&adapter->stats64_lock); for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *tx_ring = adapter->tx_ring[i]; @@ -3550,6 +3555,8 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector) int new_val = q_vector->itr_val; int avg_wire_size = 0; struct igb_adapter *adapter = q_vector->adapter; + struct igb_ring *ring; + unsigned int packets; /* For non-gigabit speeds, just fix the interrupt rate at 4000 * ints/sec - ITR timer value of 120 ticks. @@ -3559,16 +3566,21 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector) goto set_itr_val; } - if (q_vector->rx_ring && q_vector->rx_ring->total_packets) { - struct igb_ring *ring = q_vector->rx_ring; - avg_wire_size = ring->total_bytes / ring->total_packets; + ring = q_vector->rx_ring; + if (ring) { + packets = ACCESS_ONCE(ring->total_packets); + + if (packets) + avg_wire_size = ring->total_bytes / packets; } - if (q_vector->tx_ring && q_vector->tx_ring->total_packets) { - struct igb_ring *ring = q_vector->tx_ring; - avg_wire_size = max_t(u32, avg_wire_size, - (ring->total_bytes / - ring->total_packets)); + ring = q_vector->tx_ring; + if (ring) { + packets = ACCESS_ONCE(ring->total_packets); + + if (packets) + avg_wire_size = max_t(u32, avg_wire_size, + ring->total_bytes / packets); } /* if avg_wire_size isn't set no work was done */ @@ -4077,7 +4089,11 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size) /* A reprieve! */ netif_wake_subqueue(netdev, tx_ring->queue_index); - tx_ring->tx_stats.restart_queue++; + + u64_stats_update_begin(&tx_ring->tx_syncp2); + tx_ring->tx_stats.restart_queue2++; + u64_stats_update_end(&tx_ring->tx_syncp2); + return 0; } @@ -4214,16 +4230,22 @@ static void igb_reset_task(struct work_struct *work) } /** - * igb_get_stats - Get System Network Statistics + * igb_get_stats64 - Get System Network Statistics * @netdev: network interface device structure + * @stats: rtnl_link_stats64 pointer * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. **/ -static struct net_device_stats *igb_get_stats(struct net_device *netdev) +static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { - /* only return the current stats */ - return &netdev->stats; + struct igb_adapter *adapter = netdev_priv(netdev); + + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + memcpy(stats, &adapter->stats64, sizeof(*stats)); + spin_unlock(&adapter->stats64_lock); + + return stats; } /** @@ -4305,15 +4327,17 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) * @adapter: board private structure **/ -void igb_update_stats(struct igb_adapter *adapter) +void igb_update_stats(struct igb_adapter *adapter, + struct rtnl_link_stats64 *net_stats) { - struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; u32 reg, mpc; u16 phy_tmp; int i; u64 bytes, packets; + unsigned int start; + u64 _bytes, _packets; #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF @@ -4331,10 +4355,17 @@ void igb_update_stats(struct igb_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) { u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF; struct igb_ring *ring = adapter->rx_ring[i]; + ring->rx_stats.drops += rqdpc_tmp; net_stats->rx_fifo_errors += rqdpc_tmp; - bytes += ring->rx_stats.bytes; - packets += ring->rx_stats.packets; + + do { + start = u64_stats_fetch_begin_bh(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; + } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; } net_stats->rx_bytes = bytes; @@ -4344,8 +4375,13 @@ void igb_update_stats(struct igb_adapter *adapter) packets = 0; for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *ring = adapter->tx_ring[i]; - bytes += ring->tx_stats.bytes; - packets += ring->tx_stats.packets; + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; } net_stats->tx_bytes = bytes; net_stats->tx_packets = packets; @@ -5397,7 +5433,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && !(test_bit(__IGB_DOWN, &adapter->state))) { netif_wake_subqueue(netdev, tx_ring->queue_index); + + u64_stats_update_begin(&tx_ring->tx_syncp); tx_ring->tx_stats.restart_queue++; + u64_stats_update_end(&tx_ring->tx_syncp); } } @@ -5437,8 +5476,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) } tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->tx_syncp); tx_ring->tx_stats.bytes += total_bytes; tx_ring->tx_stats.packets += total_packets; + u64_stats_update_end(&tx_ring->tx_syncp); return count < tx_ring->count; } @@ -5480,9 +5521,11 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring, * packets, (aka let the stack check the crc32c) */ if ((skb->len == 60) && - (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM)) + (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM)) { + u64_stats_update_begin(&ring->rx_syncp); ring->rx_stats.csum_err++; - + u64_stats_update_end(&ring->rx_syncp); + } /* let the stack verify checksum errors */ return; } @@ -5669,8 +5712,10 @@ next_desc: rx_ring->total_packets += total_packets; rx_ring->total_bytes += total_bytes; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.packets += total_packets; rx_ring->rx_stats.bytes += total_bytes; + u64_stats_update_end(&rx_ring->rx_syncp); return cleaned; } @@ -5698,8 +5743,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if ((bufsz < IGB_RXBUFFER_1024) && !buffer_info->page_dma) { if (!buffer_info->page) { buffer_info->page = netdev_alloc_page(netdev); - if (!buffer_info->page) { + if (unlikely(!buffer_info->page)) { + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } buffer_info->page_offset = 0; @@ -5714,7 +5761,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if (dma_mapping_error(rx_ring->dev, buffer_info->page_dma)) { buffer_info->page_dma = 0; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } } @@ -5722,8 +5771,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) skb = buffer_info->skb; if (!skb) { skb = netdev_alloc_skb_ip_align(netdev, bufsz); - if (!skb) { + if (unlikely(!skb)) { + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } @@ -5737,7 +5788,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if (dma_mapping_error(rx_ring->dev, buffer_info->dma)) { buffer_info->dma = 0; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } } -- cgit v1.2.3 From a7714338aa9332e569b38c7643dc4a7bb37a0ff5 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 15 Oct 2010 17:26:47 +0000 Subject: igbvf: Remove unneeded pm_qos* calls Power Management Quality of Service is not supported or used by the VF driver. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igbvf/netdev.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 265501348f33..6693323a6cf5 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -41,14 +41,12 @@ #include #include #include -#include #include "igbvf.h" #define DRV_VERSION "1.0.0-k0" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; -static struct pm_qos_request_list igbvf_driver_pm_qos_req; static const char igbvf_driver_string[] = "Intel(R) Virtual Function Network Driver"; static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; @@ -2904,8 +2902,6 @@ static int __init igbvf_init_module(void) printk(KERN_INFO "%s\n", igbvf_copyright); ret = pci_register_driver(&igbvf_driver); - pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); return ret; } @@ -2920,7 +2916,6 @@ module_init(igbvf_init_module); static void __exit igbvf_exit_module(void) { pci_unregister_driver(&igbvf_driver); - pm_qos_remove_request(&igbvf_driver_pm_qos_req); } module_exit(igbvf_exit_module); -- cgit v1.2.3 From c6ce3854f098e1307ecd3bde07903d65fb14a9cb Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 15 Oct 2010 17:35:31 +0000 Subject: e1000e: Fix for offline diag test failure at first call Move link test call to later in the offline sequence, move the restore settings block to afterwards and add another reset to ensure the hardware is in a known state afterwards. Signed-off-by: Carolyn Wyborny Acked-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/ethtool.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index b7f15b3f0e03..8984d165a39b 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1717,13 +1717,6 @@ static void e1000_diag_test(struct net_device *netdev, e_info("offline testing starting\n"); - /* - * Link test performed before hardware reset so autoneg doesn't - * interfere with test result - */ - if (e1000_link_test(adapter, &data[4])) - eth_test->flags |= ETH_TEST_FL_FAILED; - if (if_running) /* indicate we're in test mode */ dev_close(netdev); @@ -1747,15 +1740,19 @@ static void e1000_diag_test(struct net_device *netdev, if (e1000_loopback_test(adapter, &data[3])) eth_test->flags |= ETH_TEST_FL_FAILED; + /* force this routine to wait until autoneg complete/timeout */ + adapter->hw.phy.autoneg_wait_to_complete = 1; + e1000e_reset(adapter); + adapter->hw.phy.autoneg_wait_to_complete = 0; + + if (e1000_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + /* restore speed, duplex, autoneg settings */ adapter->hw.phy.autoneg_advertised = autoneg_advertised; adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; adapter->hw.mac.autoneg = autoneg; - - /* force this routine to wait until autoneg complete/timeout */ - adapter->hw.phy.autoneg_wait_to_complete = 1; e1000e_reset(adapter); - adapter->hw.phy.autoneg_wait_to_complete = 0; clear_bit(__E1000_TESTING, &adapter->state); if (if_running) -- cgit v1.2.3 From c2355e1ab910278a94d487b78590ee3c8eecd08a Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Oct 2010 16:01:49 +0000 Subject: bonding: Fix bonding drivers improper modification of netpoll structure The bonding driver currently modifies the netpoll structure in its xmit path while sending frames from netpoll. This is racy, as other cpus can access the netpoll structure in parallel. Since the bonding driver points np->dev to a slave device, other cpus can inadvertently attempt to send data directly to slave devices, leading to improper locking with the bonding master, lost frames, and deadlocks. This patch fixes that up. This patch also removes the real_dev pointer from the netpoll structure as that data is really only used by bonding in the poll_controller, and we can emulate its behavior by check each slave for IS_UP. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 15 +++++++++------ include/linux/netpoll.h | 9 +++++++-- net/core/netpoll.c | 6 +++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7703d35de65d..813cc2f8edd6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -449,11 +449,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { struct netpoll *np = bond->dev->npinfo->netpoll; slave_dev->npinfo = bond->dev->npinfo; - np->real_dev = np->dev = skb->dev; slave_dev->priv_flags |= IFF_IN_NETPOLL; - netpoll_send_skb(np, skb); + netpoll_send_skb_on_dev(np, skb, slave_dev); slave_dev->priv_flags &= ~IFF_IN_NETPOLL; - np->dev = bond->dev; } else #endif dev_queue_xmit(skb); @@ -1332,9 +1330,14 @@ static bool slaves_support_netpoll(struct net_device *bond_dev) static void bond_poll_controller(struct net_device *bond_dev) { - struct net_device *dev = bond_dev->npinfo->netpoll->real_dev; - if (dev != bond_dev) - netpoll_poll_dev(dev); + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave; + int i; + + bond_for_each_slave(bond, slave, i) { + if (slave->dev && IS_UP(slave->dev)) + netpoll_poll_dev(slave->dev); + } } static void bond_netpoll_cleanup(struct net_device *bond_dev) diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 50d8009be86c..79358bb712c6 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -14,7 +14,6 @@ struct netpoll { struct net_device *dev; - struct net_device *real_dev; char dev_name[IFNAMSIZ]; const char *name; void (*rx_hook)(struct netpoll *, int, char *, int); @@ -53,7 +52,13 @@ void netpoll_set_trap(int trap); void __netpoll_cleanup(struct netpoll *np); void netpoll_cleanup(struct netpoll *np); int __netpoll_rx(struct sk_buff *skb); -void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb); +void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, + struct net_device *dev); +static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +{ + netpoll_send_skb_on_dev(np, skb, np->dev); +} + #ifdef CONFIG_NETPOLL diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 537e01afd81b..4e98ffac3af0 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -288,11 +288,11 @@ static int netpoll_owner_active(struct net_device *dev) return 0; } -void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, + struct net_device *dev) { int status = NETDEV_TX_BUSY; unsigned long tries; - struct net_device *dev = np->dev; const struct net_device_ops *ops = dev->netdev_ops; /* It is up to the caller to keep npinfo alive. */ struct netpoll_info *npinfo = np->dev->npinfo; @@ -346,7 +346,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) schedule_delayed_work(&npinfo->tx_work,0); } } -EXPORT_SYMBOL(netpoll_send_skb); +EXPORT_SYMBOL(netpoll_send_skb_on_dev); void netpoll_send_udp(struct netpoll *np, const char *msg, int len) { -- cgit v1.2.3 From e843fa50887582c867d8b7995f81fe9c1a076806 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Oct 2010 16:01:50 +0000 Subject: bonding: Fix deadlock in bonding driver resulting from internal locking when using netpoll The monitoring paths in the bonding driver take write locks that are shared by the tx path. If netconsole is in use, these paths can call printk which puts us in the netpoll tx path, which, if netconsole is attached to the bonding driver, result in deadlock (the xmit_lock guards are useless in netpoll_send_skb, as the monitor paths in the bonding driver don't claim the xmit_lock, nor should they). The solution is to use a per cpu flag internal to the driver to indicate when a cpu is holding the lock in a path that might recusrse into the tx path for the driver via netconsole. By checking this flag on transmit, we can defer the sending of the netconsole frames until a later time using the retransmit feature of netpoll_send_skb that is triggered on the return code NETDEV_TX_BUSY. I've tested this and am able to transmit via netconsole while causing failover conditions on the bond slave links. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 46 ++++++++++++++++++++++++++++++++++++---- drivers/net/bonding/bond_sysfs.c | 8 +++++++ drivers/net/bonding/bonding.h | 30 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 813cc2f8edd6..b46cb139477d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,10 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link /*----------------------------- Global variables ----------------------------*/ +#ifdef CONFIG_NET_POLL_CONTROLLER +cpumask_var_t netpoll_block_tx; +#endif + static const char * const version = DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; @@ -310,6 +315,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id); + block_netpoll_tx(); write_lock_bh(&bond->lock); list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { @@ -344,6 +350,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) out: write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); return res; } @@ -1804,10 +1811,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_set_carrier(bond); #ifdef CONFIG_NET_POLL_CONTROLLER - /* - * Netpoll and bonding is broken, make sure it is not initialized - * until it is fixed. - */ if (disable_netpoll) { bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; } else { @@ -1892,6 +1895,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) return -EINVAL; } + block_netpoll_tx(); netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); write_lock_bh(&bond->lock); @@ -1901,6 +1905,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: %s not enslaved\n", bond_dev->name, slave_dev->name); write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); return -EINVAL; } @@ -1994,6 +1999,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); /* must do this from outside any spinlocks */ bond_destroy_slave_symlinks(bond_dev, slave_dev); @@ -2085,6 +2091,7 @@ static int bond_release_all(struct net_device *bond_dev) struct net_device *slave_dev; struct sockaddr addr; + block_netpoll_tx(); write_lock_bh(&bond->lock); netif_carrier_off(bond_dev); @@ -2183,6 +2190,7 @@ static int bond_release_all(struct net_device *bond_dev) out: write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); return 0; } @@ -2232,9 +2240,11 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi (old_active) && (new_active->link == BOND_LINK_UP) && IS_UP(new_active->dev)) { + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_change_active_slave(bond, new_active); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } else res = -EINVAL; @@ -2466,9 +2476,11 @@ static void bond_miimon_commit(struct bonding *bond) do_failover: ASSERT_RTNL(); + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } bond_set_carrier(bond); @@ -2911,11 +2923,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) } if (do_failover) { + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } re_arm: @@ -3074,9 +3088,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) do_failover: ASSERT_RTNL(); + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } bond_set_carrier(bond); @@ -4564,6 +4580,13 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bonding *bond = netdev_priv(dev); + /* + * If we risk deadlock from transmitting this in the + * netpoll path, tell netpoll to queue the frame for later tx + */ + if (is_netpoll_tx_blocked(dev)) + return NETDEV_TX_BUSY; + if (TX_QUEUE_OVERRIDE(bond->params.mode)) { if (!bond_slave_override(bond, skb)) return NETDEV_TX_OK; @@ -5286,6 +5309,13 @@ static int __init bonding_init(void) if (res) goto out; +#ifdef CONFIG_NET_POLL_CONTROLLER + if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { + res = -ENOMEM; + goto out; + } +#endif + res = register_pernet_subsys(&bond_net_ops); if (res) goto out; @@ -5304,6 +5334,7 @@ static int __init bonding_init(void) if (res) goto err; + register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); bond_register_ipv6_notifier(); @@ -5313,6 +5344,9 @@ err: rtnl_link_unregister(&bond_link_ops); err_link: unregister_pernet_subsys(&bond_net_ops); +#ifdef CONFIG_NET_POLL_CONTROLLER + free_cpumask_var(netpoll_block_tx); +#endif goto out; } @@ -5327,6 +5361,10 @@ static void __exit bonding_exit(void) rtnl_link_unregister(&bond_link_ops); unregister_pernet_subsys(&bond_net_ops); + +#ifdef CONFIG_NET_POLL_CONTROLLER + free_cpumask_var(netpoll_block_tx); +#endif } module_init(bonding_init); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 01b4c3f5d9e7..8fd0174c5380 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1066,6 +1066,7 @@ static ssize_t bonding_store_primary(struct device *d, if (!rtnl_trylock()) return restart_syscall(); + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); @@ -1101,6 +1102,7 @@ static ssize_t bonding_store_primary(struct device *d, out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); rtnl_unlock(); return count; @@ -1146,11 +1148,13 @@ static ssize_t bonding_store_primary_reselect(struct device *d, bond->dev->name, pri_reselect_tbl[new_value].modename, new_value); + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); out: rtnl_unlock(); return ret; @@ -1232,6 +1236,8 @@ static ssize_t bonding_store_active_slave(struct device *d, if (!rtnl_trylock()) return restart_syscall(); + + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); @@ -1288,6 +1294,8 @@ static ssize_t bonding_store_active_slave(struct device *d, out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); + rtnl_unlock(); return count; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c15f21347486..2c12a5f812f4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "bond_3ad.h" #include "bond_alb.h" @@ -117,6 +118,35 @@ bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave) +#ifdef CONFIG_NET_POLL_CONTROLLER +extern cpumask_var_t netpoll_block_tx; + +static inline void block_netpoll_tx(void) +{ + preempt_disable(); + BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), + netpoll_block_tx)); +} + +static inline void unblock_netpoll_tx(void) +{ + BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), + netpoll_block_tx)); + preempt_enable(); +} + +static inline int is_netpoll_tx_blocked(struct net_device *dev) +{ + if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) + return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); + return 0; +} +#else +#define block_netpoll_tx() +#define unblock_netpoll_tx() +#define is_netpoll_tx_blocked(dev) (0) +#endif + struct bond_params { int mode; int xmit_policy; -- cgit v1.2.3 From 990c3d6f9c4115347659fc2b163907c8c832ae44 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Oct 2010 16:01:51 +0000 Subject: bonding: Fix napi poll for bonding driver Usually the netpoll path, when preforming a napi poll can get away with just polling all the napi instances of the configured device. Thats not the case for the bonding driver however, as the napi instances which may wind up getting flagged as needing polling after the poll_controller call don't belong to the bonded device, but rather to the slave devices. Fix this by checking the device in question for the IFF_MASTER flag, if set, we know we need to check the full poll list for this cpu, rather than just the devices napi instance list. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- net/core/netpoll.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 4e98ffac3af0..d79d221fd1f4 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -156,8 +156,15 @@ static void poll_napi(struct net_device *dev) { struct napi_struct *napi; int budget = 16; + struct softnet_data *sd = &__get_cpu_var(softnet_data); + struct list_head *nlist; - list_for_each_entry(napi, &dev->napi_list, dev_list) { + if (dev->flags & IFF_MASTER) + nlist = &sd->poll_list; + else + nlist = &dev->napi_list; + + list_for_each_entry(napi, nlist, dev_list) { if (napi->poll_owner != smp_processor_id() && spin_trylock(&napi->poll_lock)) { budget = poll_one_napi(dev->npinfo, napi, budget); -- cgit v1.2.3 From 3b410a310b48a8e7de3438957635093596ad5ca5 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Oct 2010 16:01:52 +0000 Subject: bonding: Fix netconsole to not deadlock on rmmod Netconsole calls netpoll_cleanup on receipt of a NETDEVICE_UNREGISTER event. The notifier subsystem calls these event handlers with rtnl_lock held, which netpoll_cleanup also takes, resulting in deadlock. Fix this by calling the __netpoll_cleanup interior function instead, and fixing up the additional pointers. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index ca142c47b2e4..94255f09093d 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -678,7 +678,14 @@ static int netconsole_netdev_event(struct notifier_block *this, strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; case NETDEV_UNREGISTER: - netpoll_cleanup(&nt->np); + /* + * rtnl_lock already held + */ + if (nt->np.dev) { + __netpoll_cleanup(&nt->np); + dev_put(nt->np.dev); + nt->np.dev = NULL; + } /* Fall through */ case NETDEV_GOING_DOWN: case NETDEV_BONDING_DESLAVE: -- cgit v1.2.3 From 45b0cb8abdbdd425934f6b02dbb3963dd89fef55 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 13 Oct 2010 16:01:53 +0000 Subject: bonding: Re-enable netpoll over bonding With the inclusion of previous fixup patches, netpoll over bonding apears to work reliably with failover conditions. This reverts Gospos previous commit c22d7ac844f1cb9c6a5fd20f89ebadc2feef891b, and allows access again to the netpoll functionality in the bonding driver. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b46cb139477d..ecbe206f90d1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -184,9 +184,6 @@ static int arp_ip_count; static int bond_mode = BOND_MODE_ROUNDROBIN; static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2; static int lacp_fast; -#ifdef CONFIG_NET_POLL_CONTROLLER -static int disable_netpoll = 1; -#endif const struct bond_parm_tbl bond_lacp_tbl[] = { { "slow", AD_LACP_SLOW}, @@ -1811,19 +1808,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_set_carrier(bond); #ifdef CONFIG_NET_POLL_CONTROLLER - if (disable_netpoll) { + if (slaves_support_netpoll(bond_dev)) { + bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; + if (bond_dev->npinfo) + slave_dev->npinfo = bond_dev->npinfo; + } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; - } else { - if (slaves_support_netpoll(bond_dev)) { - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; - if (bond_dev->npinfo) - slave_dev->npinfo = bond_dev->npinfo; - } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { - bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; - pr_info("New slave device %s does not support netpoll\n", - slave_dev->name); - pr_info("Disabling netpoll support for %s\n", bond_dev->name); - } + pr_info("New slave device %s does not support netpoll\n", + slave_dev->name); + pr_info("Disabling netpoll support for %s\n", bond_dev->name); } #endif read_unlock(&bond->lock); @@ -2030,10 +2023,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) #ifdef CONFIG_NET_POLL_CONTROLLER read_lock_bh(&bond->lock); - /* Make sure netpoll over stays disabled until fixed. */ - if (!disable_netpoll) - if (slaves_support_netpoll(bond_dev)) - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; + if (slaves_support_netpoll(bond_dev)) + bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; read_unlock_bh(&bond->lock); if (slave_dev->netdev_ops->ndo_netpoll_cleanup) slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); -- cgit v1.2.3 From ebbf41df4aabb6d506fa18ea8cb4c2b4388a18b9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 19 Oct 2010 10:19:06 +0200 Subject: netfilter: ctnetlink: add expectation deletion events This patch allows to listen to events that inform about expectations destroyed. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_conntrack_common.h | 1 + include/net/netfilter/nf_conntrack_expect.h | 8 ++++++- net/netfilter/nf_conntrack_expect.c | 6 ++++-- net/netfilter/nf_conntrack_netlink.c | 30 +++++++++++++++++++-------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index 23a1a08578a8..50cdc2559a5a 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -98,6 +98,7 @@ enum ip_conntrack_events { enum ip_conntrack_expect_events { IPEXP_NEW, /* new expectation */ + IPEXP_DESTROY, /* destroyed expectation */ }; /* expectation flags */ diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 416b83844485..0f8a8c587532 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -82,7 +82,13 @@ struct nf_conntrack_expect * nf_ct_find_expectation(struct net *net, u16 zone, const struct nf_conntrack_tuple *tuple); -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report); +static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +{ + nf_ct_unlink_expect_report(exp, 0, 0); +} + void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); void nf_ct_remove_userspace_expectations(void); diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index b30a1f2aac00..46e8966912b1 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -41,7 +41,8 @@ static struct kmem_cache *nf_ct_expect_cachep __read_mostly; static HLIST_HEAD(nf_ct_userspace_expect_list); /* nf_conntrack_expect helper functions */ -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report) { struct nf_conn_help *master_help = nfct_help(exp->master); struct net *net = nf_ct_exp_net(exp); @@ -55,11 +56,12 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) if (!(exp->flags & NF_CT_EXPECT_USERSPACE)) master_help->expecting[exp->class]--; + nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report); nf_ct_expect_put(exp); NF_CT_STAT_INC(net, expect_delete); } -EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); +EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report); static void nf_ct_expectation_timed_out(unsigned long ul_expect) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b4077be5f663..62bad229106b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1632,17 +1632,20 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; struct sk_buff *skb; - unsigned int type; + unsigned int type, group; int flags = 0; - if (events & (1 << IPEXP_NEW)) { + if (events & (1 << IPEXP_DESTROY)) { + type = IPCTNL_MSG_EXP_DELETE; + group = NFNLGRP_CONNTRACK_EXP_DESTROY; + } else if (events & (1 << IPEXP_NEW)) { type = IPCTNL_MSG_EXP_NEW; flags = NLM_F_CREATE|NLM_F_EXCL; + group = NFNLGRP_CONNTRACK_EXP_NEW; } else return 0; - if (!item->report && - !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW)) + if (!item->report && !nfnetlink_has_listeners(net, group)) return 0; skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -1665,8 +1668,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) rcu_read_unlock(); nlmsg_end(skb, nlh); - nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, - item->report, GFP_ATOMIC); + nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC); return 0; nla_put_failure: @@ -1849,7 +1851,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, } /* after list removal, usage count == 1 */ - nf_ct_unexpect_related(exp); + spin_lock_bh(&nf_conntrack_lock); + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid, + nlmsg_report(nlh)); + nf_ct_expect_put(exp); + } + spin_unlock_bh(&nf_conntrack_lock); /* have to put what we 'get' above. * after this line usage count == 0 */ nf_ct_expect_put(exp); @@ -1866,7 +1874,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, m_help = nfct_help(exp->master); if (!strcmp(m_help->helper->name, name) && del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } @@ -1880,7 +1890,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, &net->ct.expect_hash[i], hnode) { if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } -- cgit v1.2.3 From 714f095f74582764d629785f03b459a3d0503624 Mon Sep 17 00:00:00 2001 From: Hans Schillstrom Date: Tue, 19 Oct 2010 10:38:48 +0200 Subject: ipvs: IPv6 tunnel mode IPv6 encapsulation uses a bad source address for the tunnel. i.e. VIP will be used as local-addr and encap. dst addr. Decapsulation will not accept this. Example LVS (eth1 2003::2:0:1/96, VIP 2003::2:0:100) (eth0 2003::1:0:1/96) RS (ethX 2003::1:0:5/96) tcpdump 2003::2:0:100 > 2003::1:0:5: IP6 (hlim 63, next-header TCP (6) payload length: 40) 2003::3:0:10.50991 > 2003::2:0:100.http: Flags [S], cksum 0x7312 (correct), seq 3006460279, win 5760, options [mss 1440,sackOK,TS val 1904932 ecr 0,nop,wscale 3], length 0 In Linux IPv6 impl. you can't have a tunnel with an any cast address receiving packets (I have not tried to interpret RFC 2473) To have receive capabilities the tunnel must have: - Local address set as multicast addr or an unicast addr - Remote address set as an unicast addr. - Loop back addres or Link local address are not allowed. This causes us to setup a tunnel in the Real Server with the LVS as the remote address, here you can't use the VIP address since it's used inside the tunnel. Solution Use outgoing interface IPv6 address (match against the destination). i.e. use ip6_route_output() to look up the route cache and then use ipv6_dev_get_saddr(...) to set the source address of the encapsulated packet. Additionally, cache the results in new destination fields: dst_cookie and dst_saddr and properly check the returned dst from ip6_route_output. We now add xfrm_lookup call only for the tunneling method where the source address is a local one. Signed-off-by:Hans Schillstrom Signed-off-by: Patrick McHardy --- include/net/ip_vs.h | 4 + net/netfilter/ipvs/ip_vs_xmit.c | 171 +++++++++++++++++++++------------------- 2 files changed, 96 insertions(+), 79 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 52fbe2308c38..6e8a6192e574 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -529,6 +529,10 @@ struct ip_vs_dest { spinlock_t dst_lock; /* lock of dst_cache */ struct dst_entry *dst_cache; /* destination cache entry */ u32 dst_rtos; /* RT_TOS(tos) for dst */ + u32 dst_cookie; +#ifdef CONFIG_IP_VS_IPV6 + struct in6_addr dst_saddr; +#endif /* for virtual service */ struct ip_vs_service *svc; /* service it belongs to */ diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 8817afa34e6a..b0bd8afbf368 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -26,6 +26,7 @@ #include /* for ip_route_output */ #include #include +#include #include #include #include @@ -37,26 +38,27 @@ * Destination cache to speed up outgoing route lookup */ static inline void -__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst) +__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst, + u32 dst_cookie) { struct dst_entry *old_dst; old_dst = dest->dst_cache; dest->dst_cache = dst; dest->dst_rtos = rtos; + dest->dst_cookie = dst_cookie; dst_release(old_dst); } static inline struct dst_entry * -__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie) +__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) { struct dst_entry *dst = dest->dst_cache; if (!dst) return NULL; - if ((dst->obsolete - || (dest->af == AF_INET && rtos != dest->dst_rtos)) && - dst->ops->check(dst, cookie) == NULL) { + if ((dst->obsolete || rtos != dest->dst_rtos) && + dst->ops->check(dst, dest->dst_cookie) == NULL) { dest->dst_cache = NULL; dst_release(dst); return NULL; @@ -66,15 +68,16 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie) } static struct rtable * -__ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) +__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_conn *cp, u32 rtos) { + struct net *net = dev_net(skb->dev); struct rtable *rt; /* Route to the other host */ struct ip_vs_dest *dest = cp->dest; if (dest) { spin_lock(&dest->dst_lock); if (!(rt = (struct rtable *) - __ip_vs_dst_check(dest, rtos, 0))) { + __ip_vs_dst_check(dest, rtos))) { struct flowi fl = { .oif = 0, .nl_u = { @@ -84,13 +87,13 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) .tos = rtos, } }, }; - if (ip_route_output_key(&init_net, &rt, &fl)) { + if (ip_route_output_key(net, &rt, &fl)) { spin_unlock(&dest->dst_lock); IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &dest->addr.ip); return NULL; } - __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst)); + __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0); IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n", &dest->addr.ip, atomic_read(&rt->dst.__refcnt), rtos); @@ -106,7 +109,7 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) .tos = rtos, } }, }; - if (ip_route_output_key(&init_net, &rt, &fl)) { + if (ip_route_output_key(net, &rt, &fl)) { IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &cp->daddr.ip); return NULL; @@ -117,62 +120,79 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) } #ifdef CONFIG_IP_VS_IPV6 + +static struct dst_entry * +__ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, + struct in6_addr *ret_saddr, int do_xfrm) +{ + struct dst_entry *dst; + struct flowi fl = { + .oif = 0, + .nl_u = { + .ip6_u = { + .daddr = *daddr, + }, + }, + }; + + dst = ip6_route_output(net, NULL, &fl); + if (dst->error) + goto out_err; + if (!ret_saddr) + return dst; + if (ipv6_addr_any(&fl.fl6_src) && + ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev, + &fl.fl6_dst, 0, &fl.fl6_src) < 0) + goto out_err; + if (do_xfrm && xfrm_lookup(net, &dst, &fl, NULL, 0) < 0) + goto out_err; + ipv6_addr_copy(ret_saddr, &fl.fl6_src); + return dst; + +out_err: + dst_release(dst); + IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", daddr); + return NULL; +} + static struct rt6_info * -__ip_vs_get_out_rt_v6(struct ip_vs_conn *cp) +__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_conn *cp, + struct in6_addr *ret_saddr, int do_xfrm) { + struct net *net = dev_net(skb->dev); struct rt6_info *rt; /* Route to the other host */ struct ip_vs_dest *dest = cp->dest; + struct dst_entry *dst; if (dest) { spin_lock(&dest->dst_lock); - rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0, 0); + rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0); if (!rt) { - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = dest->addr.in6, - .saddr = { - .s6_addr32 = - { 0, 0, 0, 0 }, - }, - }, - }, - }; + u32 cookie; - rt = (struct rt6_info *)ip6_route_output(&init_net, - NULL, &fl); - if (!rt) { + dst = __ip_vs_route_output_v6(net, &dest->addr.in6, + &dest->dst_saddr, + do_xfrm); + if (!dst) { spin_unlock(&dest->dst_lock); - IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", - &dest->addr.in6); return NULL; } - __ip_vs_dst_set(dest, 0, dst_clone(&rt->dst)); - IP_VS_DBG(10, "new dst %pI6, refcnt=%d\n", - &dest->addr.in6, + rt = (struct rt6_info *) dst; + cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; + __ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie); + IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", + &dest->addr.in6, &dest->dst_saddr, atomic_read(&rt->dst.__refcnt)); } + if (ret_saddr) + ipv6_addr_copy(ret_saddr, &dest->dst_saddr); spin_unlock(&dest->dst_lock); } else { - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = cp->daddr.in6, - .saddr = { - .s6_addr32 = { 0, 0, 0, 0 }, - }, - }, - }, - }; - - rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); - if (!rt) { - IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", - &cp->daddr.in6); + dst = __ip_vs_route_output_v6(net, &cp->daddr.in6, ret_saddr, + do_xfrm); + if (!dst) return NULL; - } + rt = (struct rt6_info *) dst; } return rt; @@ -248,6 +268,7 @@ int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { + struct net *net = dev_net(skb->dev); struct rtable *rt; /* Route to the other host */ struct iphdr *iph = ip_hdr(skb); u8 tos = iph->tos; @@ -263,7 +284,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (ip_route_output_key(&init_net, &rt, &fl)) { + if (ip_route_output_key(net, &rt, &fl)) { IP_VS_DBG_RL("%s(): ip_route_output error, dest: %pI4\n", __func__, &iph->daddr); goto tx_error_icmp; @@ -313,25 +334,18 @@ int ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { + struct net *net = dev_net(skb->dev); + struct dst_entry *dst; struct rt6_info *rt; /* Route to the other host */ struct ipv6hdr *iph = ipv6_hdr(skb); int mtu; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = iph->daddr, - .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } }, - }; EnterFunction(10); - rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); - if (!rt) { - IP_VS_DBG_RL("%s(): ip6_route_output error, dest: %pI6\n", - __func__, &iph->daddr); + dst = __ip_vs_route_output_v6(net, &iph->daddr, NULL, 0); + if (!dst) goto tx_error_icmp; - } + rt = (struct rt6_info *) dst; /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -397,7 +411,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(iph->tos)))) goto tx_error_icmp; /* MTU checking */ @@ -472,7 +486,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - rt = __ip_vs_get_out_rt_v6(cp); + rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); if (!rt) goto tx_error_icmp; @@ -557,7 +571,6 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct iphdr *old_iph = ip_hdr(skb); u8 tos = old_iph->tos; __be16 df = old_iph->frag_off; - sk_buff_data_t old_transport_header = skb->transport_header; struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; @@ -572,7 +585,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error; } - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(tos)))) goto tx_error_icmp; tdev = rt->dst.dev; @@ -616,7 +629,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, old_iph = ip_hdr(skb); } - skb->transport_header = old_transport_header; + skb->transport_header = skb->network_header; /* fix old IP header checksum */ ip_send_check(old_iph); @@ -670,9 +683,9 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { struct rt6_info *rt; /* Route to the other host */ + struct in6_addr saddr; /* Source for tunnel */ struct net_device *tdev; /* Device to other host */ struct ipv6hdr *old_iph = ipv6_hdr(skb); - sk_buff_data_t old_transport_header = skb->transport_header; struct ipv6hdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; @@ -687,17 +700,17 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error; } - rt = __ip_vs_get_out_rt_v6(cp); + rt = __ip_vs_get_out_rt_v6(skb, cp, &saddr, 1); if (!rt) goto tx_error_icmp; tdev = rt->dst.dev; mtu = dst_mtu(&rt->dst) - sizeof(struct ipv6hdr); - /* TODO IPv6: do we need this check in IPv6? */ - if (mtu < 1280) { + if (mtu < IPV6_MIN_MTU) { dst_release(&rt->dst); - IP_VS_DBG_RL("%s(): mtu less than 1280\n", __func__); + IP_VS_DBG_RL("%s(): mtu less than %d\n", __func__, + IPV6_MIN_MTU); goto tx_error; } if (skb_dst(skb)) @@ -730,7 +743,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, old_iph = ipv6_hdr(skb); } - skb->transport_header = old_transport_header; + skb->transport_header = skb->network_header; skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); @@ -750,8 +763,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, be16_add_cpu(&iph->payload_len, sizeof(*old_iph)); iph->priority = old_iph->priority; memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); - iph->daddr = rt->rt6i_dst.addr; - iph->saddr = cp->vaddr.in6; /* rt->rt6i_src.addr; */ + ipv6_addr_copy(&iph->daddr, &cp->daddr.in6); + ipv6_addr_copy(&iph->saddr, &saddr); iph->hop_limit = old_iph->hop_limit; /* Another hack: avoid icmp_send in ip_fragment */ @@ -791,7 +804,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(iph->tos)))) goto tx_error_icmp; /* MTU checking */ @@ -843,7 +856,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rt = __ip_vs_get_out_rt_v6(cp); + rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); if (!rt) goto tx_error_icmp; @@ -919,7 +932,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(ip_hdr(skb)->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(ip_hdr(skb)->tos)))) goto tx_error_icmp; /* MTU checking */ @@ -993,7 +1006,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - rt = __ip_vs_get_out_rt_v6(cp); + rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); if (!rt) goto tx_error_icmp; -- cgit v1.2.3 From 5d6076bb2e642bbcb1263c6cf239b9a1f3d0df08 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 14 Oct 2010 14:21:51 +0000 Subject: 3c52x: remove IRQF_SAMPLE_RANDOM from legacy MCA drivers. If you are genuinely using one of these legacy MCA drivers then you are tragically on hardware where you really don't have the extra CPU cycles to be wasting on this. In addition, it makes two less cases for people to inadvertently blindly copy flags from without explicitly thinking whether it makes sense -- see the addition to feature-removal.txt as per commit 9d9b8fb0e5ebf4b0398e579f6061d4451fea3242. Signed-off-by: Paul Gortmaker Signed-off-by: David S. Miller --- drivers/net/3c523.c | 2 +- drivers/net/3c527.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index ca00f0a11217..de579d043169 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -287,7 +287,7 @@ static int elmc_open(struct net_device *dev) elmc_id_attn586(); /* disable interrupts */ - ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, + ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED, dev->name, dev); if (ret) { pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 70705d1306b9..0d6ca1e407d0 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -443,7 +443,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) * Grab the IRQ */ - err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev); + err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev); if (err) { release_region(dev->base_addr, MC32_IO_EXTENT); pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); -- cgit v1.2.3 From 9e917dca74138cccf398ce8bb924c7fd2980ec1d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 19 Oct 2010 00:39:18 +0000 Subject: net: avoid a dev refcount in ip_mc_find_dev() We hold RTNL in ip_mc_find_dev(), no need to touch device refcount. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 2 +- net/ipv4/igmp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3df057e89640..36e27c2107de 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -153,7 +153,7 @@ static void fib_flush(struct net *net) * @addr: the source address * @devref: if true, take a reference on the found device * - * If a caller uses devref=false, it should be protected by RCU + * If a caller uses devref=false, it should be protected by RCU, or RTNL */ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 25f339672b28..a525328ec372 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1418,6 +1418,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev) write_unlock_bh(&in_dev->mc_list_lock); } +/* RTNL is locked */ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { struct flowi fl = { .nl_u = { .ip4_u = @@ -1433,10 +1434,9 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) return idev; } if (imr->imr_address.s_addr) { - dev = ip_dev_find(net, imr->imr_address.s_addr); + dev = __ip_dev_find(net, imr->imr_address.s_addr, false); if (!dev) return NULL; - dev_put(dev); } if (!dev && !ip_route_output_key(net, &rt, &fl)) { -- cgit v1.2.3 From 8723e1b4ad9be4444423b4d41509ce859a629649 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 19 Oct 2010 00:39:26 +0000 Subject: inet: RCU changes in inetdev_by_index() Convert inetdev_by_index() to not increment in_dev refcount. Callers hold RCU or RTNL, and should not decrement in_dev refcount. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/devinet.c | 7 ++++--- net/ipv4/fib_semantics.c | 25 +++++++++++-------------- net/ipv4/igmp.c | 2 -- net/ipv4/ip_gre.c | 4 +--- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index c2ff48fa18c7..dc94b0316b78 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -403,6 +403,9 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) return inet_insert_ifa(ifa); } +/* Caller must hold RCU or RTNL : + * We dont take a reference on found in_device + */ struct in_device *inetdev_by_index(struct net *net, int ifindex) { struct net_device *dev; @@ -411,7 +414,7 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex) rcu_read_lock(); dev = dev_get_by_index_rcu(net, ifindex); if (dev) - in_dev = in_dev_get(dev); + in_dev = rcu_dereference_rtnl(dev->ip_ptr); rcu_read_unlock(); return in_dev; } @@ -453,8 +456,6 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg goto errout; } - __in_dev_put(in_dev); - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0f80dfc2f7fb..6734c9cab248 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -590,32 +590,29 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, if (!dev) goto out; dev_hold(dev); - err = -ENETDOWN; - if (!(dev->flags & IFF_UP)) - goto out; - err = 0; -out: - rcu_read_unlock(); - return err; + err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; } else { struct in_device *in_dev; if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) return -EINVAL; + rcu_read_lock(); + err = -ENODEV; in_dev = inetdev_by_index(net, nh->nh_oif); if (in_dev == NULL) - return -ENODEV; - if (!(in_dev->dev->flags & IFF_UP)) { - in_dev_put(in_dev); - return -ENETDOWN; - } + goto out; + err = -ENETDOWN; + if (!(in_dev->dev->flags & IFF_UP)) + goto out; nh->nh_dev = in_dev->dev; dev_hold(nh->nh_dev); nh->nh_scope = RT_SCOPE_HOST; - in_dev_put(in_dev); + err = 0; } - return 0; +out: + rcu_read_unlock(); + return err; } static inline unsigned int fib_laddr_hashfn(__be32 val) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a525328ec372..c8877c6c7216 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1429,8 +1429,6 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) if (imr->imr_ifindex) { idev = inetdev_by_index(net, imr->imr_ifindex); - if (idev) - __in_dev_put(idev); return idev; } if (imr->imr_address.s_addr) { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 9d421f4cf3ef..d0ffcbe369b7 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1245,10 +1245,8 @@ static int ipgre_close(struct net_device *dev) if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { struct in_device *in_dev; in_dev = inetdev_by_index(dev_net(dev), t->mlink); - if (in_dev) { + if (in_dev) ip_mc_dec_group(in_dev, t->parms.iph.daddr); - in_dev_put(in_dev); - } } return 0; } -- cgit v1.2.3 From e2269308359d5863b6aa1fcb95a425a2ab255f1f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 14 Oct 2010 17:41:53 +0000 Subject: r6040: Fix multicast filter some more This code has been broken forever, but in several different and creative ways. So far as I can work out, the R6040 MAC filter has 4 exact-match entries, the first of which the driver uses for its assigned unicast address, plus a 64-entry hash-based filter for multicast addresses (maybe unicast as well?). The original version of this code would write the first 4 multicast addresses as exact-match entries from offset 1 (bug #1: there is no entry 4 so this could write to some PHY registers). It would fill the remainder of the exact-match entries with the broadcast address (bug #2: this would overwrite the last used entry). If more than 4 multicast addresses were configured, it would set up the hash table, write some random crap to the MAC control register (bug #3) and finally walk off the end of the list when filling the exact-match entries (bug #4). All of this seems to be pointless, since it sets the promiscuous bit when the interface is made promiscuous or if >4 multicast addresses are enabled, and never clears it (bug #5, masking bug #2). The recent(ish) changes to the multicast list fixed bug #4, but completely removed the limit on iteration over the exact-match entries (bug #6). Bug #4 was reported as and more recently as . Florian Fainelli attempted to fix these in commit 3bcf8229a8c49769e48d3e0bd1e20d8e003f8106, but that actually dealt with bugs #1-3, bug #4 having been fixed in mainline at that point. That commit fixes the most important current bug #6. Signed-off-by: Ben Hutchings Cc: stable@kernel.org [2.6.35 only] Signed-off-by: David S. Miller --- drivers/net/r6040.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 142c381e1d73..80666f097ce6 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -893,16 +893,18 @@ static void r6040_multicast_list(struct net_device *dev) /* Multicast Address 1~4 case */ i = 0; netdev_for_each_mc_addr(ha, dev) { - if (i < MCAST_MAX) { - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - } else { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); - } + if (i >= MCAST_MAX) + break; + adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + i++; + } + while (i < MCAST_MAX) { + iowrite16(0xffff, ioaddr + MID_1L + 8 * i); + iowrite16(0xffff, ioaddr + MID_1M + 8 * i); + iowrite16(0xffff, ioaddr + MID_1H + 8 * i); i++; } } -- cgit v1.2.3 From d86bef73b4a24e59e7c1f896a72bbf38430ac2c6 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Tue, 19 Oct 2010 10:26:47 +0100 Subject: Fixed race condition at ip_vs.ko module init. Lists were initialized after the module was registered. Multiple ipvsadm processes at module load triggered a race condition that resulted in a null pointer dereference in do_ip_vs_get_ctl(). As a result, __ip_vs_mutex was left locked preventing all further ipvsadm commands. Signed-off-by: Eduardo J. Blanco Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_ctl.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index a697591d0e23..0b884d3e192f 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -3400,6 +3400,16 @@ int __init ip_vs_control_init(void) EnterFunction(2); + /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */ + for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_svc_table[idx]); + INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); + } + for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_rtable[idx]); + } + smp_wmb(); + ret = nf_register_sockopt(&ip_vs_sockopts); if (ret) { pr_err("cannot register sockopt.\n"); @@ -3418,15 +3428,6 @@ int __init ip_vs_control_init(void) sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars); - /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */ - for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_svc_table[idx]); - INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); - } - for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_rtable[idx]); - } - ip_vs_new_estimator(&ip_vs_stats); /* Hook the defense timer */ -- cgit v1.2.3 From a0fd065cd5d8f758b27c13cafabbbcf59d1eb8ec Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Oct 2010 05:13:05 +0000 Subject: bnx2x: fix possible deadlock in HC hw block The possible deadlock (on 57710 devices only) will prevent from the device to generate interrupts. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 012c093cb432..3f49b551ff05 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1111,14 +1111,19 @@ static void bnx2x_hc_int_enable(struct bnx2x *bp) HC_CONFIG_0_REG_INT_LINE_EN_0 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); - DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", - val, port, addr); + if (!CHIP_IS_E1(bp)) { + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", + val, port, addr); - REG_WR(bp, addr, val); + REG_WR(bp, addr, val); - val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; + val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; + } } + if (CHIP_IS_E1(bp)) + REG_WR(bp, HC_REG_INT_MASK + port*4, 0x1FFFF); + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) mode %s\n", val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx"))); @@ -1212,10 +1217,26 @@ static void bnx2x_hc_int_disable(struct bnx2x *bp) u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; u32 val = REG_RD(bp, addr); - val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | - HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | - HC_CONFIG_0_REG_INT_LINE_EN_0 | - HC_CONFIG_0_REG_ATTN_BIT_EN_0); + /* + * in E1 we must use only PCI configuration space to disable + * MSI/MSIX capablility + * It's forbitten to disable IGU_PF_CONF_MSI_MSIX_EN in HC block + */ + if (CHIP_IS_E1(bp)) { + /* Since IGU_PF_CONF_MSI_MSIX_EN still always on + * Use mask register to prevent from HC sending interrupts + * after we exit the function + */ + REG_WR(bp, HC_REG_INT_MASK + port*4, 0); + + val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_INT_LINE_EN_0 | + HC_CONFIG_0_REG_ATTN_BIT_EN_0); + } else + val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | + HC_CONFIG_0_REG_INT_LINE_EN_0 | + HC_CONFIG_0_REG_ATTN_BIT_EN_0); DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", val, port, addr); -- cgit v1.2.3 From f4a66897e77277335ae98ffeb1f4ebb9cf24ed6d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Tue, 19 Oct 2010 05:13:09 +0000 Subject: bnx2x: prevent false parity error in MSI-X memory of HC block Signed-off-by: Dmitry Kravkov Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 28 +++++++++++++++++++++++++++- drivers/net/bnx2x/bnx2x_reg.h | 6 +++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 3f49b551ff05..f22e283cabef 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -5457,7 +5457,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) struct bnx2x_ilt *ilt = BP_ILT(bp); u16 cdu_ilt_start; u32 addr, val; - int i; + u32 main_mem_base, main_mem_size, main_mem_prty_clr; + int i, main_mem_width; DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); @@ -5706,6 +5707,31 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func); bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E1x(bp)) { + main_mem_size = HC_REG_MAIN_MEMORY_SIZE / 2; /*dwords*/ + main_mem_base = HC_REG_MAIN_MEMORY + + BP_PORT(bp) * (main_mem_size * 4); + main_mem_prty_clr = HC_REG_HC_PRTY_STS_CLR; + main_mem_width = 8; + + val = REG_RD(bp, main_mem_prty_clr); + if (val) + DP(BNX2X_MSG_MCP, "Hmmm... Parity errors in HC " + "block during " + "function init (0x%x)!\n", val); + + /* Clear "false" parity errors in MSI-X table */ + for (i = main_mem_base; + i < main_mem_base + main_mem_size * 4; + i += main_mem_width) { + bnx2x_read_dmae(bp, i, main_mem_width / 4); + bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), + i, main_mem_width / 4); + } + /* Clear HC parity attention */ + REG_RD(bp, main_mem_prty_clr); + } + bnx2x_phy_probe(&bp->link_params); return 0; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 18a86284ebcc..1cefe489a955 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -800,9 +800,13 @@ #define HC_REG_HC_PRTY_MASK 0x1080a0 /* [R 3] Parity register #0 read */ #define HC_REG_HC_PRTY_STS 0x108094 -#define HC_REG_INT_MASK 0x108108 +/* [RC 3] Parity register #0 read clear */ +#define HC_REG_HC_PRTY_STS_CLR 0x108098 +#define HC_REG_INT_MASK 0x108108 #define HC_REG_LEADING_EDGE_0 0x108040 #define HC_REG_LEADING_EDGE_1 0x108048 +#define HC_REG_MAIN_MEMORY 0x108800 +#define HC_REG_MAIN_MEMORY_SIZE 152 #define HC_REG_P0_PROD_CONS 0x108200 #define HC_REG_P1_PROD_CONS 0x108400 #define HC_REG_PBA_COMMAND 0x108140 -- cgit v1.2.3 From 0683e31ad5d9b4cab3cc32d033269e8cf675823a Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Tue, 19 Oct 2010 05:13:00 +0000 Subject: bnx2x: update version to 1.60.00-3 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 01b8d8504773..3bf236b160dd 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-2" -#define DRV_MODULE_RELDATE "2010/10/18" +#define DRV_MODULE_VERSION "1.60.00-3" +#define DRV_MODULE_RELDATE "2010/10/19" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -- cgit v1.2.3 From 9ff76c951c5194d44a7cdce51d807d67fc3ae514 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 19 Oct 2010 07:04:25 +0000 Subject: netpoll: Remove netpoll blocking from uninit path Some recent testing in netpoll with bonding showed this backtrace ------------[ cut here ]------------ kernel BUG at drivers/net/bonding/bonding.h:134! invalid opcode: 0000 [#1] SMP last sysfs file: /sys/devices/pci0000:00/0000:00:1d.2/usb7/devnum CPU 0 Pid: 1876, comm: rmmod Not tainted 2.6.36-rc3+ #10 D26928/ RIP: 0010:[] [] bond_uninit+0x6f4/0x7a0 RSP: 0018:ffff88003b1b5d58 EFLAGS: 00010296 RAX: ffff88003b9b6200 RBX: ffff8800373e8e00 RCX: 00000000000f4240 RDX: 00000000ffffffff RSI: 0000000000000286 RDI: 0000000000000286 RBP: ffff88003b1b5dc8 R08: 0000000000000000 R09: 00000001af7de920 R10: 0000000000000000 R11: ffff880002495e98 R12: ffff880037922700 R13: ffff880038c31000 R14: ffff880037922730 R15: 0000000000000286 FS: 00007f90e6d72700(0000) GS:ffff880002400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 000000346f0d9ad0 CR3: 000000003b263000 CR4: 00000000000006f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process rmmod (pid: 1876, threadinfo ffff88003b1b4000, task ffff88003b36aa80) Stack: 00000000ffffffff ffff88003b1b5d7a ffff8800379221e8 ffff880037922000 <0> ffff88003b1b5dc8 ffffffff813eb5fb ffff88003b1b5da8 0000000031b177a3 <0> ffff88003b1b5da8 ffff880037922000 ffff88003b1b5e48 ffff88003b1b5e48 Call Trace: [] ? rtmsg_ifinfo+0xcb/0xf0 [] rollback_registered_many+0x168/0x280 [] unregister_netdevice_many+0x19/0x80 [] __rtnl_kill_links+0x63/0x90 [] __rtnl_link_unregister+0x2b/0x60 [] rtnl_link_unregister+0x1e/0x30 [] bonding_exit+0x37/0x51 [bonding] [] sys_delete_module+0x19e/0x270 [] ? audit_syscall_entry+0x252/0x280 [] system_call_fastpath+0x16/0x1b RIP [] bond_uninit+0x6f4/0x7a0 [bonding] RSP ---[ end trace 1395ad691cea24d1 ]--- It occurs because of my recent netpoll blocking patches, which I added to avoid recursive deadlock in the bonding driver. It relies on some per cpu bits, but the shutdown path forces some rescheduling as we cancel workqueues for the driver and wait for some device refcounts. If after the forced reschedule, we wind up on a different cpu we trigger the bughalt in unblock_netpoll_tx. The fix is to remove the netpoll block/unblock calls from bond_release_all. This is safe to do because bond_uninit, which is called via ndo_uninit in rollback_registered_many, doesn't occur until we send a NETDEV_UNREGISTER event, which triggers netconsole to remove us as a netpoll client, so we are guaranteed not to recurse into our own tx path here. Signed-off-by: Neil Horman Reviewed-by: WANG Cong Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ecbe206f90d1..6b9a7bd8ec14 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2082,7 +2082,6 @@ static int bond_release_all(struct net_device *bond_dev) struct net_device *slave_dev; struct sockaddr addr; - block_netpoll_tx(); write_lock_bh(&bond->lock); netif_carrier_off(bond_dev); @@ -2181,8 +2180,6 @@ static int bond_release_all(struct net_device *bond_dev) out: write_unlock_bh(&bond->lock); - unblock_netpoll_tx(); - return 0; } -- cgit v1.2.3 From f13d493d9cf772d510d78ae00bb9f4d680b3170b Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 19 Oct 2010 07:04:26 +0000 Subject: netpoll: Revert napi_poll fix for bonding driver In an erlier patch I modified napi_poll so that devices with IFF_MASTER polled the per_cpu list instead of the device list for napi. I did this because the bonding driver has no napi instances to poll, it instead expects to check the slave devices napi instances, which napi_poll was unaware of. Looking at this more closely however, I now see this isn't strictly needed. As the bond driver poll_controller calls the slaves poll_controller via netpoll_poll_dev, which recursively calls poll_napi on each slave, allowing those napi instances to get serviced. The earlier patch isn't at all harmfull, its just not needed, so lets revert it to make the code cleaner. Sorry for the noise, Signed-off-by: Neil Horman Reviewed-by: WANG Cong Signed-off-by: David S. Miller --- net/core/netpoll.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index d79d221fd1f4..4e98ffac3af0 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -156,15 +156,8 @@ static void poll_napi(struct net_device *dev) { struct napi_struct *napi; int budget = 16; - struct softnet_data *sd = &__get_cpu_var(softnet_data); - struct list_head *nlist; - if (dev->flags & IFF_MASTER) - nlist = &sd->poll_list; - else - nlist = &dev->napi_list; - - list_for_each_entry(napi, nlist, dev_list) { + list_for_each_entry(napi, &dev->napi_list, dev_list) { if (napi->poll_owner != smp_processor_id() && spin_trylock(&napi->poll_lock)) { budget = poll_one_napi(dev->npinfo, napi, budget); -- cgit v1.2.3 From c5e90f562047ff9713183cf5e18f5e8997bc7373 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 19 Oct 2010 21:51:03 +0000 Subject: phonet: remove the unused variable pn Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- net/phonet/pep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 9c903f9e5079..3e60f2e4e6c2 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -300,7 +300,6 @@ static int pipe_handler_send_ind(struct sock *sk, u8 utid, u8 msg_id) static int pipe_handler_enable_pipe(struct sock *sk, int enable) { - struct pep_sock *pn = pep_sk(sk); int utid, req; if (enable) { -- cgit v1.2.3 From 55513fb4281464e97aa1ff2b9c906ca5aed917c5 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 18 Oct 2010 17:55:58 +0000 Subject: net: fail alloc_netdev_mq if queue count < 1 In alloc_netdev_mq fail if requested queue_count < 1. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index 04972a4783e2..f44d29ae5d67 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5511,6 +5511,12 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, BUG_ON(strlen(name) >= sizeof(dev->name)); + if (queue_count < 1) { + pr_err("alloc_netdev: Unable to allocate device " + "with zero queues.\n"); + return NULL; + } + alloc_size = sizeof(struct net_device); if (sizeof_priv) { /* ensure 32-byte alignment of private area */ -- cgit v1.2.3 From bd25fa7ba59cd26094319dfba0011b48465f7355 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 18 Oct 2010 18:00:16 +0000 Subject: net: cleanups in RX queue allocation Clean up in RX queue allocation. In netif_set_real_num_rx_queues return error on attempt to set zero queues, or requested number is greater than number of allocated queues. In netif_alloc_rx_queues, do BUG_ON if queue_count is zero. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index f44d29ae5d67..d33adecec44b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1583,12 +1583,12 @@ int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) { int rc; + if (rxq < 1 || rxq > dev->num_rx_queues) + return -EINVAL; + if (dev->reg_state == NETREG_REGISTERED) { ASSERT_RTNL(); - if (rxq > dev->num_rx_queues) - return -EINVAL; - rc = net_rx_queue_update_kobjects(dev, dev->real_num_rx_queues, rxq); if (rc) @@ -5013,25 +5013,23 @@ static int netif_alloc_rx_queues(struct net_device *dev) { #ifdef CONFIG_RPS unsigned int i, count = dev->num_rx_queues; + struct netdev_rx_queue *rx; - if (count) { - struct netdev_rx_queue *rx; - - rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL); - if (!rx) { - pr_err("netdev: Unable to allocate %u rx queues.\n", - count); - return -ENOMEM; - } - dev->_rx = rx; + BUG_ON(count < 1); - /* - * Set a pointer to first element in the array which holds the - * reference count. - */ - for (i = 0; i < count; i++) - rx[i].first = rx; + rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL); + if (!rx) { + pr_err("netdev: Unable to allocate %u rx queues.\n", count); + return -ENOMEM; } + dev->_rx = rx; + + /* + * Set a pointer to first element in the array which holds the + * reference count. + */ + for (i = 0; i < count; i++) + rx[i].first = rx; #endif return 0; } -- cgit v1.2.3 From e6484930d7c73d324bccda7d43d131088da697b9 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 18 Oct 2010 18:04:39 +0000 Subject: net: allocate tx queues in register_netdevice This patch introduces netif_alloc_netdev_queues which is called from register_device instead of alloc_netdev_mq. This makes TX queue allocation symmetric with RX allocation. Also, queue locks allocation is done in netdev_init_one_queue. Change set_real_num_tx_queues to fail if requested number < 1 or greater than number of allocated queues. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 +- net/core/dev.c | 106 +++++++++++++++++++++++----------------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 14fbb04c459d..880d56565828 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1696,8 +1696,8 @@ static inline int netif_is_multiqueue(const struct net_device *dev) return dev->num_tx_queues > 1; } -extern void netif_set_real_num_tx_queues(struct net_device *dev, - unsigned int txq); +extern int netif_set_real_num_tx_queues(struct net_device *dev, + unsigned int txq); #ifdef CONFIG_RPS extern int netif_set_real_num_rx_queues(struct net_device *dev, diff --git a/net/core/dev.c b/net/core/dev.c index d33adecec44b..4c3ac53e4b16 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1553,18 +1553,20 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. */ -void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) +int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) { - unsigned int real_num = dev->real_num_tx_queues; + if (txq < 1 || txq > dev->num_tx_queues) + return -EINVAL; - if (unlikely(txq > dev->num_tx_queues)) - ; - else if (txq > real_num) - dev->real_num_tx_queues = txq; - else if (txq < real_num) { - dev->real_num_tx_queues = txq; - qdisc_reset_all_tx_gt(dev, txq); + if (dev->reg_state == NETREG_REGISTERED) { + ASSERT_RTNL(); + + if (txq < dev->real_num_tx_queues) + qdisc_reset_all_tx_gt(dev, txq); } + + dev->real_num_tx_queues = txq; + return 0; } EXPORT_SYMBOL(netif_set_real_num_tx_queues); @@ -4928,20 +4930,6 @@ static void rollback_registered(struct net_device *dev) rollback_registered_many(&single); } -static void __netdev_init_queue_locks_one(struct net_device *dev, - struct netdev_queue *dev_queue, - void *_unused) -{ - spin_lock_init(&dev_queue->_xmit_lock); - netdev_set_xmit_lockdep_class(&dev_queue->_xmit_lock, dev->type); - dev_queue->xmit_lock_owner = -1; -} - -static void netdev_init_queue_locks(struct net_device *dev) -{ - netdev_for_each_tx_queue(dev, __netdev_init_queue_locks_one, NULL); -} - unsigned long netdev_fix_features(unsigned long features, const char *name) { /* Fix illegal SG+CSUM combinations. */ @@ -5034,6 +5022,41 @@ static int netif_alloc_rx_queues(struct net_device *dev) return 0; } +static int netif_alloc_netdev_queues(struct net_device *dev) +{ + unsigned int count = dev->num_tx_queues; + struct netdev_queue *tx; + + BUG_ON(count < 1); + + tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL); + if (!tx) { + pr_err("netdev: Unable to allocate %u tx queues.\n", + count); + return -ENOMEM; + } + dev->_tx = tx; + return 0; +} + +static void netdev_init_one_queue(struct net_device *dev, + struct netdev_queue *queue, + void *_unused) +{ + queue->dev = dev; + + /* Initialize queue lock */ + spin_lock_init(&queue->_xmit_lock); + netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); + queue->xmit_lock_owner = -1; +} + +static void netdev_init_queues(struct net_device *dev) +{ + netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); + spin_lock_init(&dev->tx_global_lock); +} + /** * register_netdevice - register a network device * @dev: device to register @@ -5067,7 +5090,6 @@ int register_netdevice(struct net_device *dev) spin_lock_init(&dev->addr_list_lock); netdev_set_addr_lockdep_class(dev); - netdev_init_queue_locks(dev); dev->iflink = -1; @@ -5075,6 +5097,12 @@ int register_netdevice(struct net_device *dev) if (ret) goto out; + ret = netif_alloc_netdev_queues(dev); + if (ret) + goto out; + + netdev_init_queues(dev); + /* Init, if this function is available */ if (dev->netdev_ops->ndo_init) { ret = dev->netdev_ops->ndo_init(dev); @@ -5456,19 +5484,6 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, } EXPORT_SYMBOL(dev_get_stats); -static void netdev_init_one_queue(struct net_device *dev, - struct netdev_queue *queue, - void *_unused) -{ - queue->dev = dev; -} - -static void netdev_init_queues(struct net_device *dev) -{ - netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); - spin_lock_init(&dev->tx_global_lock); -} - struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) { struct netdev_queue *queue = dev_ingress_queue(dev); @@ -5480,7 +5495,6 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) if (!queue) return NULL; netdev_init_one_queue(dev, queue, NULL); - __netdev_init_queue_locks_one(dev, queue, NULL); queue->qdisc = &noop_qdisc; queue->qdisc_sleeping = &noop_qdisc; rcu_assign_pointer(dev->ingress_queue, queue); @@ -5502,7 +5516,6 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, void (*setup)(struct net_device *), unsigned int queue_count) { - struct netdev_queue *tx; struct net_device *dev; size_t alloc_size; struct net_device *p; @@ -5530,20 +5543,12 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, return NULL; } - tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL); - if (!tx) { - printk(KERN_ERR "alloc_netdev: Unable to allocate " - "tx qdiscs.\n"); - goto free_p; - } - - dev = PTR_ALIGN(p, NETDEV_ALIGN); dev->padded = (char *)dev - (char *)p; dev->pcpu_refcnt = alloc_percpu(int); if (!dev->pcpu_refcnt) - goto free_tx; + goto free_p; if (dev_addr_init(dev)) goto free_pcpu; @@ -5553,7 +5558,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev_net_set(dev, &init_net); - dev->_tx = tx; dev->num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count; @@ -5564,8 +5568,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->gso_max_size = GSO_MAX_SIZE; - netdev_init_queues(dev); - INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); dev->ethtool_ntuple_list.count = 0; INIT_LIST_HEAD(&dev->napi_list); @@ -5576,8 +5578,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, strcpy(dev->name, name); return dev; -free_tx: - kfree(tx); free_pcpu: free_percpu(dev->pcpu_refcnt); free_p: -- cgit v1.2.3 From 27b75c95f10d249574d9c4cb9dab878107faede8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Oct 2010 05:44:11 +0000 Subject: net: avoid RCU for NOCACHE dst There is no point using RCU for dst we allocate for a very short time (used once). Change dst_release() to take DST_NOCACHE into account, but also change skb_dst_set_noref() to force a refcount increment for such dst. This is a _huge_ gain, because we dont waste memory to store xx thousand of dsts. Instead of queueing them to RCU, we can free them instantly. CPU caches can stay hot, re-using same memory blocks to hold temporary dsts. Note : remove unneeded smp_mb__before_atomic_dec(); in dst_release(), since atomic_dec_return() implies a full memory barrier. Stress test, 160.000.000 udp frames sent, IP route cache disabled (DDOS). Before: real 0m38.091s user 0m13.189s sys 7m53.018s After: real 0m29.946s user 0m12.157s sys 7m40.605s For reference, if IP route cache was enabled : real 0m32.030s user 0m10.521s sys 8m15.243s Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/skbuff.h | 14 +------------- net/core/dst.c | 29 ++++++++++++++++++++++++++++- net/ipv4/route.c | 9 ++++----- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 05a358f1ba11..e6ba898de61c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -460,19 +460,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) skb->_skb_refdst = (unsigned long)dst; } -/** - * skb_dst_set_noref - sets skb dst, without a reference - * @skb: buffer - * @dst: dst entry - * - * Sets skb dst, assuming a reference was not taken on dst - * skb_dst_drop() should not dst_release() this dst - */ -static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) -{ - WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); - skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; -} +extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst); /** * skb_dst_is_noref - Test if skb dst isnt refcounted diff --git a/net/core/dst.c b/net/core/dst.c index 32e542d7f472..8abe628b79f1 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -271,13 +271,40 @@ void dst_release(struct dst_entry *dst) if (dst) { int newrefcnt; - smp_mb__before_atomic_dec(); newrefcnt = atomic_dec_return(&dst->__refcnt); WARN_ON(newrefcnt < 0); + if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) { + dst = dst_destroy(dst); + if (dst) + __dst_free(dst); + } } } EXPORT_SYMBOL(dst_release); +/** + * skb_dst_set_noref - sets skb dst, without a reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst + * skb_dst_drop() should not dst_release() this dst + */ +void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) +{ + WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + /* If dst not in cache, we must take a reference, because + * dst_release() will destroy dst as soon as its refcount becomes zero + */ + if (unlikely(dst->flags & DST_NOCACHE)) { + dst_hold(dst); + skb_dst_set(skb, dst); + } else { + skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; + } +} +EXPORT_SYMBOL(skb_dst_set_noref); + /* Dirty hack. We did it in 2.2 (in __dst_free), * we have _very_ good reasons not to repeat * this mistake in 2.3, but we have no choice diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ff98983d2a45..d6cb2bfcd8e1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1105,9 +1105,9 @@ restart: * Note that we do rt_free on this new route entry, so that * once its refcount hits zero, we are still able to reap it * (Thanks Alexey) - * Note also the rt_free uses call_rcu. We don't actually - * need rcu protection here, this is just our path to get - * on the route gc list. + * Note: To avoid expensive rcu stuff for this uncached dst, + * we set DST_NOCACHE so that dst_release() can free dst without + * waiting a grace period. */ rt->dst.flags |= DST_NOCACHE; @@ -1117,12 +1117,11 @@ restart: if (net_ratelimit()) printk(KERN_WARNING "Neighbour table failure & not caching routes.\n"); - rt_drop(rt); + ip_rt_put(rt); return err; } } - rt_free(rt); goto skip_hashing; } -- cgit v1.2.3 From 88426f2acae0cf887446013db9eab776871610e7 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Wed, 20 Oct 2010 04:21:13 +0000 Subject: ibmveth: Cleanup error handling inside ibmveth_open Remove duplicated code in one place. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index b3e157ed6776..2ae8336478b3 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -546,9 +546,8 @@ static int ibmveth_open(struct net_device *netdev) if (!adapter->buffer_list_addr || !adapter->filter_list_addr) { netdev_err(netdev, "unable to allocate filter or buffer list " "pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + rc = -ENOMEM; + goto err_out; } adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * @@ -558,9 +557,8 @@ static int ibmveth_open(struct net_device *netdev) if (!adapter->rx_queue.queue_addr) { netdev_err(netdev, "unable to allocate rx queue pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + rc = -ENOMEM; + goto err_out; } dev = &adapter->vdev->dev; @@ -578,9 +576,8 @@ static int ibmveth_open(struct net_device *netdev) (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { netdev_err(netdev, "unable to map filter or buffer list " "pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + rc = -ENOMEM; + goto err_out; } adapter->rx_queue.index = 0; @@ -611,9 +608,8 @@ static int ibmveth_open(struct net_device *netdev) adapter->filter_list_dma, rxq_desc.desc, mac_address); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENONET; + rc = -ENONET; + goto err_out; } for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { @@ -622,9 +618,8 @@ static int ibmveth_open(struct net_device *netdev) if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { netdev_err(netdev, "unable to alloc pool\n"); adapter->rx_buff_pool[i].active = 0; - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM ; + rc = -ENOMEM; + goto err_out; } } @@ -638,27 +633,23 @@ static int ibmveth_open(struct net_device *netdev) rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return rc; + goto err_out; } adapter->bounce_buffer = kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL); if (!adapter->bounce_buffer) { netdev_err(netdev, "unable to allocate bounce buffer\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + rc = -ENOMEM; + goto err_out; } adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { netdev_err(netdev, "unable to map bounce buffer\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + rc = -ENOMEM; + goto err_out; } netdev_dbg(netdev, "initial replenish cycle\n"); @@ -669,6 +660,11 @@ static int ibmveth_open(struct net_device *netdev) netdev_dbg(netdev, "open complete\n"); return 0; + +err_out: + ibmveth_cleanup(adapter); + napi_disable(&adapter->napi); + return rc; } static int ibmveth_close(struct net_device *netdev) -- cgit v1.2.3 From e0e8ab596012d8c2147beb3c8b70d2d6ab90acda Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Wed, 20 Oct 2010 04:21:51 +0000 Subject: ibmveth: Free irq on error path Free irq on error path. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2ae8336478b3..c454b45ca7ec 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -641,7 +641,7 @@ static int ibmveth_open(struct net_device *netdev) if (!adapter->bounce_buffer) { netdev_err(netdev, "unable to allocate bounce buffer\n"); rc = -ENOMEM; - goto err_out; + goto err_out_free_irq; } adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, @@ -649,7 +649,7 @@ static int ibmveth_open(struct net_device *netdev) if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { netdev_err(netdev, "unable to map bounce buffer\n"); rc = -ENOMEM; - goto err_out; + goto err_out_free_irq; } netdev_dbg(netdev, "initial replenish cycle\n"); @@ -661,6 +661,8 @@ static int ibmveth_open(struct net_device *netdev) return 0; +err_out_free_irq: + free_irq(netdev->irq, netdev); err_out: ibmveth_cleanup(adapter); napi_disable(&adapter->napi); -- cgit v1.2.3 From 717258ba4b3ecca9c7c0ef2b76d7aa5800242bad Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 20 Oct 2010 10:16:59 +0000 Subject: enic: Add support for multiple hardware receive queues Add support for multiple hardware receive queues. The ingress traffic is hashed into one of the receive queues based on IP or TCP or both headers. The max no. of receive queues supported is 8. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 28 +--- drivers/net/enic/enic_main.c | 373 +++++++++++++++++++++++++++++++++---------- drivers/net/enic/enic_res.c | 49 +++--- drivers/net/enic/enic_res.h | 2 + drivers/net/enic/vnic_rss.h | 40 +++++ 5 files changed, 368 insertions(+), 124 deletions(-) create mode 100644 drivers/net/enic/vnic_rss.h diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index ae623206f180..c91d364c5527 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -28,10 +28,11 @@ #include "vnic_intr.h" #include "vnic_stats.h" #include "vnic_nic.h" +#include "vnic_rss.h" #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.2a" +#define DRV_VERSION "1.4.1.6" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -41,25 +42,6 @@ #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) -enum enic_cq_index { - ENIC_CQ_RQ, - ENIC_CQ_WQ, -}; - -enum enic_intx_intr_index { - ENIC_INTX_WQ_RQ, - ENIC_INTX_ERR, - ENIC_INTX_NOTIFY, -}; - -enum enic_msix_intr_index { - ENIC_MSIX_RQ, - ENIC_MSIX_WQ, - ENIC_MSIX_ERR, - ENIC_MSIX_NOTIFY, - ENIC_MSIX_MAX, -}; - struct enic_msix_entry { int requested; char devname[IFNAMSIZ]; @@ -90,8 +72,8 @@ struct enic { struct vnic_dev *vdev; struct timer_list notify_timer; struct work_struct reset; - struct msix_entry msix_entry[ENIC_MSIX_MAX]; - struct enic_msix_entry msix[ENIC_MSIX_MAX]; + struct msix_entry msix_entry[ENIC_INTR_MAX]; + struct enic_msix_entry msix[ENIC_INTR_MAX]; u32 msg_enable; spinlock_t devcmd_lock; u8 mac_addr[ETH_ALEN]; @@ -118,7 +100,7 @@ struct enic { int (*rq_alloc_buf)(struct vnic_rq *rq); u64 rq_truncated_pkts; u64 rq_bad_fcs; - struct napi_struct napi; + struct napi_struct napi[ENIC_RQ_MAX]; /* interrupt resource cache line section */ ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a1f92f193976..dcfc541291ef 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -122,6 +122,51 @@ static int enic_is_dynamic(struct enic *enic) return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN; } +static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) +{ + return rq; +} + +static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq) +{ + return enic->rq_count + wq; +} + +static inline unsigned int enic_legacy_io_intr(void) +{ + return 0; +} + +static inline unsigned int enic_legacy_err_intr(void) +{ + return 1; +} + +static inline unsigned int enic_legacy_notify_intr(void) +{ + return 2; +} + +static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq) +{ + return rq; +} + +static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq) +{ + return enic->rq_count + wq; +} + +static inline unsigned int enic_msix_err_intr(struct enic *enic) +{ + return enic->rq_count + enic->wq_count; +} + +static inline unsigned int enic_msix_notify_intr(struct enic *enic) +{ + return enic->rq_count + enic->wq_count + 1; +} + static int enic_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -306,6 +351,7 @@ static int enic_set_coalesce(struct net_device *netdev, struct enic *enic = netdev_priv(netdev); u32 tx_coalesce_usecs; u32 rx_coalesce_usecs; + unsigned int i, intr; tx_coalesce_usecs = min_t(u32, INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), @@ -319,7 +365,8 @@ static int enic_set_coalesce(struct net_device *netdev, if (tx_coalesce_usecs != rx_coalesce_usecs) return -EINVAL; - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ], + intr = enic_legacy_io_intr(); + vnic_intr_coalescing_timer_set(&enic->intr[intr], INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); break; case VNIC_DEV_INTR_MODE_MSI: @@ -330,10 +377,18 @@ static int enic_set_coalesce(struct net_device *netdev, INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); break; case VNIC_DEV_INTR_MODE_MSIX: - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ], - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ], - INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); + for (i = 0; i < enic->wq_count; i++) { + intr = enic_msix_wq_intr(enic, i); + vnic_intr_coalescing_timer_set(&enic->intr[intr], + INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); + } + + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + vnic_intr_coalescing_timer_set(&enic->intr[intr], + INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); + } + break; default: break; @@ -482,34 +537,37 @@ static irqreturn_t enic_isr_legacy(int irq, void *data) { struct net_device *netdev = data; struct enic *enic = netdev_priv(netdev); + unsigned int io_intr = enic_legacy_io_intr(); + unsigned int err_intr = enic_legacy_err_intr(); + unsigned int notify_intr = enic_legacy_notify_intr(); u32 pba; - vnic_intr_mask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_mask(&enic->intr[io_intr]); pba = vnic_intr_legacy_pba(enic->legacy_pba); if (!pba) { - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[io_intr]); return IRQ_NONE; /* not our interrupt */ } - if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) { - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]); + if (ENIC_TEST_INTR(pba, notify_intr)) { + vnic_intr_return_all_credits(&enic->intr[notify_intr]); enic_notify_check(enic); } - if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) { - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]); + if (ENIC_TEST_INTR(pba, err_intr)) { + vnic_intr_return_all_credits(&enic->intr[err_intr]); enic_log_q_error(enic); /* schedule recovery from WQ/RQ error */ schedule_work(&enic->reset); return IRQ_HANDLED; } - if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) { - if (napi_schedule_prep(&enic->napi)) - __napi_schedule(&enic->napi); + if (ENIC_TEST_INTR(pba, io_intr)) { + if (napi_schedule_prep(&enic->napi[0])) + __napi_schedule(&enic->napi[0]); } else { - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[io_intr]); } return IRQ_HANDLED; @@ -535,17 +593,17 @@ static irqreturn_t enic_isr_msi(int irq, void *data) * writes). */ - napi_schedule(&enic->napi); + napi_schedule(&enic->napi[0]); return IRQ_HANDLED; } static irqreturn_t enic_isr_msix_rq(int irq, void *data) { - struct enic *enic = data; + struct napi_struct *napi = data; /* schedule NAPI polling for RQ cleanup */ - napi_schedule(&enic->napi); + napi_schedule(napi); return IRQ_HANDLED; } @@ -553,13 +611,15 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data) static irqreturn_t enic_isr_msix_wq(int irq, void *data) { struct enic *enic = data; + unsigned int cq = enic_cq_wq(enic, 0); + unsigned int intr = enic_msix_wq_intr(enic, 0); unsigned int wq_work_to_do = -1; /* no limit */ unsigned int wq_work_done; - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], + wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do, enic_wq_service, NULL); - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ], + vnic_intr_return_credits(&enic->intr[intr], wq_work_done, 1 /* unmask intr */, 1 /* reset intr timer */); @@ -570,8 +630,9 @@ static irqreturn_t enic_isr_msix_wq(int irq, void *data) static irqreturn_t enic_isr_msix_err(int irq, void *data) { struct enic *enic = data; + unsigned int intr = enic_msix_err_intr(enic); - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]); + vnic_intr_return_all_credits(&enic->intr[intr]); enic_log_q_error(enic); @@ -584,8 +645,9 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data) static irqreturn_t enic_isr_msix_notify(int irq, void *data) { struct enic *enic = data; + unsigned int intr = enic_msix_notify_intr(enic); - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]); + vnic_intr_return_all_credits(&enic->intr[intr]); enic_notify_check(enic); return IRQ_HANDLED; @@ -1409,8 +1471,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) { if (netdev->features & NETIF_F_GRO) - vlan_gro_receive(&enic->napi, enic->vlan_group, - vlan_tci, skb); + vlan_gro_receive(&enic->napi[q_number], + enic->vlan_group, vlan_tci, skb); else vlan_hwaccel_receive_skb(skb, enic->vlan_group, vlan_tci); @@ -1418,12 +1480,11 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, } else { if (netdev->features & NETIF_F_GRO) - napi_gro_receive(&enic->napi, skb); + napi_gro_receive(&enic->napi[q_number], skb); else netif_receive_skb(skb); } - } else { /* Buffer overflow @@ -1447,7 +1508,11 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, static int enic_poll(struct napi_struct *napi, int budget) { - struct enic *enic = container_of(napi, struct enic, napi); + struct net_device *netdev = napi->dev; + struct enic *enic = netdev_priv(netdev); + unsigned int cq_rq = enic_cq_rq(enic, 0); + unsigned int cq_wq = enic_cq_wq(enic, 0); + unsigned int intr = enic_legacy_io_intr(); unsigned int rq_work_to_do = budget; unsigned int wq_work_to_do = -1; /* no limit */ unsigned int work_done, rq_work_done, wq_work_done; @@ -1456,10 +1521,10 @@ static int enic_poll(struct napi_struct *napi, int budget) /* Service RQ (first) and WQ */ - rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], + rq_work_done = vnic_cq_service(&enic->cq[cq_rq], rq_work_to_do, enic_rq_service, NULL); - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], + wq_work_done = vnic_cq_service(&enic->cq[cq_wq], wq_work_to_do, enic_wq_service, NULL); /* Accumulate intr event credits for this polling @@ -1470,7 +1535,7 @@ static int enic_poll(struct napi_struct *napi, int budget) work_done = rq_work_done + wq_work_done; if (work_done > 0) - vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ], + vnic_intr_return_credits(&enic->intr[intr], work_done, 0 /* don't unmask intr */, 0 /* don't reset intr timer */); @@ -1491,7 +1556,7 @@ static int enic_poll(struct napi_struct *napi, int budget) */ napi_complete(napi); - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[intr]); } return rq_work_done; @@ -1499,7 +1564,11 @@ static int enic_poll(struct napi_struct *napi, int budget) static int enic_poll_msix(struct napi_struct *napi, int budget) { - struct enic *enic = container_of(napi, struct enic, napi); + struct net_device *netdev = napi->dev; + struct enic *enic = netdev_priv(netdev); + unsigned int rq = (napi - &enic->napi[0]); + unsigned int cq = enic_cq_rq(enic, rq); + unsigned int intr = enic_msix_rq_intr(enic, rq); unsigned int work_to_do = budget; unsigned int work_done; int err; @@ -1507,7 +1576,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) /* Service RQ */ - work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], + work_done = vnic_cq_service(&enic->cq[cq], work_to_do, enic_rq_service, NULL); /* Return intr event credits for this polling @@ -1516,12 +1585,12 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) */ if (work_done > 0) - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ], + vnic_intr_return_credits(&enic->intr[intr], work_done, 0 /* don't unmask intr */, 0 /* don't reset intr timer */); - err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf); + err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf); /* Buffer allocation failed. Stay in polling mode * so we can try to fill the ring again. @@ -1537,7 +1606,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) */ napi_complete(napi); - vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); + vnic_intr_unmask(&enic->intr[intr]); } return work_done; @@ -1579,7 +1648,7 @@ static void enic_free_intr(struct enic *enic) static int enic_request_intr(struct enic *enic) { struct net_device *netdev = enic->netdev; - unsigned int i; + unsigned int i, intr; int err = 0; switch (vnic_dev_get_intr_mode(enic->vdev)) { @@ -1598,27 +1667,38 @@ static int enic_request_intr(struct enic *enic) case VNIC_DEV_INTR_MODE_MSIX: - sprintf(enic->msix[ENIC_MSIX_RQ].devname, - "%.11s-rx-0", netdev->name); - enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq; - enic->msix[ENIC_MSIX_RQ].devid = enic; + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + sprintf(enic->msix[intr].devname, + "%.11s-rx-%d", netdev->name, i); + enic->msix[intr].isr = enic_isr_msix_rq; + enic->msix[intr].devid = &enic->napi[i]; + } - sprintf(enic->msix[ENIC_MSIX_WQ].devname, - "%.11s-tx-0", netdev->name); - enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq; - enic->msix[ENIC_MSIX_WQ].devid = enic; + for (i = 0; i < enic->wq_count; i++) { + intr = enic_msix_wq_intr(enic, i); + sprintf(enic->msix[intr].devname, + "%.11s-tx-%d", netdev->name, i); + enic->msix[intr].isr = enic_isr_msix_wq; + enic->msix[intr].devid = enic; + } - sprintf(enic->msix[ENIC_MSIX_ERR].devname, + intr = enic_msix_err_intr(enic); + sprintf(enic->msix[intr].devname, "%.11s-err", netdev->name); - enic->msix[ENIC_MSIX_ERR].isr = enic_isr_msix_err; - enic->msix[ENIC_MSIX_ERR].devid = enic; + enic->msix[intr].isr = enic_isr_msix_err; + enic->msix[intr].devid = enic; - sprintf(enic->msix[ENIC_MSIX_NOTIFY].devname, + intr = enic_msix_notify_intr(enic); + sprintf(enic->msix[intr].devname, "%.11s-notify", netdev->name); - enic->msix[ENIC_MSIX_NOTIFY].isr = enic_isr_msix_notify; - enic->msix[ENIC_MSIX_NOTIFY].devid = enic; + enic->msix[intr].isr = enic_isr_msix_notify; + enic->msix[intr].devid = enic; + + for (i = 0; i < ARRAY_SIZE(enic->msix); i++) + enic->msix[i].requested = 0; - for (i = 0; i < ARRAY_SIZE(enic->msix); i++) { + for (i = 0; i < enic->intr_count; i++) { err = request_irq(enic->msix_entry[i].vector, enic->msix[i].isr, 0, enic->msix[i].devname, @@ -1664,10 +1744,12 @@ static int enic_dev_notify_set(struct enic *enic) spin_lock(&enic->devcmd_lock); switch (vnic_dev_get_intr_mode(enic->vdev)) { case VNIC_DEV_INTR_MODE_INTX: - err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY); + err = vnic_dev_notify_set(enic->vdev, + enic_legacy_notify_intr()); break; case VNIC_DEV_INTR_MODE_MSIX: - err = vnic_dev_notify_set(enic->vdev, ENIC_MSIX_NOTIFY); + err = vnic_dev_notify_set(enic->vdev, + enic_msix_notify_intr(enic)); break; default: err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */); @@ -1762,7 +1844,10 @@ static int enic_open(struct net_device *netdev) enic_set_multicast_list(netdev); netif_wake_queue(netdev); - napi_enable(&enic->napi); + + for (i = 0; i < enic->rq_count; i++) + napi_enable(&enic->napi[i]); + enic_dev_enable(enic); for (i = 0; i < enic->intr_count; i++) @@ -1797,7 +1882,10 @@ static int enic_stop(struct net_device *netdev) del_timer_sync(&enic->notify_timer); enic_dev_disable(enic); - napi_disable(&enic->napi); + + for (i = 0; i < enic->rq_count; i++) + napi_disable(&enic->napi[i]); + netif_carrier_off(netdev); netif_tx_disable(netdev); enic_dev_del_station_addr(enic); @@ -1857,11 +1945,16 @@ static void enic_poll_controller(struct net_device *netdev) { struct enic *enic = netdev_priv(netdev); struct vnic_dev *vdev = enic->vdev; + unsigned int i, intr; switch (vnic_dev_get_intr_mode(vdev)) { case VNIC_DEV_INTR_MODE_MSIX: - enic_isr_msix_rq(enic->pdev->irq, enic); - enic_isr_msix_wq(enic->pdev->irq, enic); + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); + } + intr = enic_msix_wq_intr(enic, i); + enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); break; case VNIC_DEV_INTR_MODE_MSI: enic_isr_msi(enic->pdev->irq, enic); @@ -1936,19 +2029,73 @@ static int enic_dev_hang_reset(struct enic *enic) return err; } -static int enic_set_niccfg(struct enic *enic) +static int enic_set_rsskey(struct enic *enic) +{ + u64 rss_key_buf_pa; + union vnic_rss_key *rss_key_buf_va = NULL; + union vnic_rss_key rss_key = { + .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101}, + .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101}, + .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115}, + .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108}, + }; + int err; + + rss_key_buf_va = pci_alloc_consistent(enic->pdev, + sizeof(union vnic_rss_key), &rss_key_buf_pa); + if (!rss_key_buf_va) + return -ENOMEM; + + memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key)); + + spin_lock(&enic->devcmd_lock); + err = enic_set_rss_key(enic, + rss_key_buf_pa, + sizeof(union vnic_rss_key)); + spin_unlock(&enic->devcmd_lock); + + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key), + rss_key_buf_va, rss_key_buf_pa); + + return err; +} + +static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) +{ + u64 rss_cpu_buf_pa; + union vnic_rss_cpu *rss_cpu_buf_va = NULL; + unsigned int i; + int err; + + rss_cpu_buf_va = pci_alloc_consistent(enic->pdev, + sizeof(union vnic_rss_cpu), &rss_cpu_buf_pa); + if (!rss_cpu_buf_va) + return -ENOMEM; + + for (i = 0; i < (1 << rss_hash_bits); i++) + (*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count; + + spin_lock(&enic->devcmd_lock); + err = enic_set_rss_cpu(enic, + rss_cpu_buf_pa, + sizeof(union vnic_rss_cpu)); + spin_unlock(&enic->devcmd_lock); + + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu), + rss_cpu_buf_va, rss_cpu_buf_pa); + + return err; +} + +static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu, + u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable) { - const u8 rss_default_cpu = 0; - const u8 rss_hash_type = 0; - const u8 rss_hash_bits = 0; - const u8 rss_base_cpu = 0; - const u8 rss_enable = 0; const u8 tso_ipid_split_en = 0; const u8 ig_vlan_strip_en = 1; int err; - /* Enable VLAN tag stripping. RSS not enabled (yet). - */ + /* Enable VLAN tag stripping. + */ spin_lock(&enic->devcmd_lock); err = enic_set_nic_cfg(enic, @@ -1961,6 +2108,35 @@ static int enic_set_niccfg(struct enic *enic) return err; } +static int enic_set_rss_nic_cfg(struct enic *enic) +{ + struct device *dev = enic_get_dev(enic); + const u8 rss_default_cpu = 0; + const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 | + NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 | + NIC_CFG_RSS_HASH_TYPE_IPV6 | + NIC_CFG_RSS_HASH_TYPE_TCP_IPV6; + const u8 rss_hash_bits = 7; + const u8 rss_base_cpu = 0; + u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1); + + if (rss_enable) { + if (!enic_set_rsskey(enic)) { + if (enic_set_rsscpu(enic, rss_hash_bits)) { + rss_enable = 0; + dev_warn(dev, "RSS disabled, " + "Failed to set RSS cpu indirection table."); + } + } else { + rss_enable = 0; + dev_warn(dev, "RSS disabled, Failed to set RSS key.\n"); + } + } + + return enic_set_niccfg(enic, rss_default_cpu, rss_hash_type, + rss_hash_bits, rss_base_cpu, rss_enable); +} + static int enic_dev_hang_notify(struct enic *enic) { int err; @@ -1998,7 +2174,7 @@ static void enic_reset(struct work_struct *work) enic_dev_hang_reset(enic); enic_reset_multicast_list(enic); enic_init_vnic_resources(enic); - enic_set_niccfg(enic); + enic_set_rss_nic_cfg(enic); enic_dev_set_ig_vlan_rewrite_mode(enic); enic_open(enic->netdev); @@ -2007,12 +2183,12 @@ static void enic_reset(struct work_struct *work) static int enic_set_intr_mode(struct enic *enic) { - unsigned int n = 1; + unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX); unsigned int m = 1; unsigned int i; /* Set interrupt mode (INTx, MSI, MSI-X) depending - * system capabilities. + * on system capabilities. * * Try MSI-X first * @@ -2025,21 +2201,47 @@ static int enic_set_intr_mode(struct enic *enic) for (i = 0; i < n + m + 2; i++) enic->msix_entry[i].entry = i; - if (enic->config.intr_mode < 1 && + /* Use multiple RQs if RSS is enabled + */ + + if (ENIC_SETTING(enic, RSS) && + enic->config.intr_mode < 1 && enic->rq_count >= n && enic->wq_count >= m && enic->cq_count >= n + m && - enic->intr_count >= n + m + 2 && - !pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) { + enic->intr_count >= n + m + 2) { - enic->rq_count = n; - enic->wq_count = m; - enic->cq_count = n + m; - enic->intr_count = n + m + 2; + if (!pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) { - vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSIX); + enic->rq_count = n; + enic->wq_count = m; + enic->cq_count = n + m; + enic->intr_count = n + m + 2; - return 0; + vnic_dev_set_intr_mode(enic->vdev, + VNIC_DEV_INTR_MODE_MSIX); + + return 0; + } + } + + if (enic->config.intr_mode < 1 && + enic->rq_count >= 1 && + enic->wq_count >= m && + enic->cq_count >= 1 + m && + enic->intr_count >= 1 + m + 2) { + if (!pci_enable_msix(enic->pdev, enic->msix_entry, 1 + m + 2)) { + + enic->rq_count = 1; + enic->wq_count = m; + enic->cq_count = 1 + m; + enic->intr_count = 1 + m + 2; + + vnic_dev_set_intr_mode(enic->vdev, + VNIC_DEV_INTR_MODE_MSIX); + + return 0; + } } /* Next try MSI @@ -2149,7 +2351,11 @@ static const struct net_device_ops enic_netdev_ops = { static void enic_dev_deinit(struct enic *enic) { - netif_napi_del(&enic->napi); + unsigned int i; + + for (i = 0; i < enic->rq_count; i++) + netif_napi_del(&enic->napi[i]); + enic_free_vnic_resources(enic); enic_clear_intr_mode(enic); } @@ -2158,6 +2364,7 @@ static int enic_dev_init(struct enic *enic) { struct device *dev = enic_get_dev(enic); struct net_device *netdev = enic->netdev; + unsigned int i; int err; /* Get vNIC configuration @@ -2202,7 +2409,7 @@ static int enic_dev_init(struct enic *enic) goto err_out_free_vnic_resources; } - err = enic_set_niccfg(enic); + err = enic_set_rss_nic_cfg(enic); if (err) { dev_err(dev, "Failed to config nic, aborting\n"); goto err_out_free_vnic_resources; @@ -2217,10 +2424,12 @@ static int enic_dev_init(struct enic *enic) switch (vnic_dev_get_intr_mode(enic->vdev)) { default: - netif_napi_add(netdev, &enic->napi, enic_poll, 64); + netif_napi_add(netdev, &enic->napi[0], enic_poll, 64); break; case VNIC_DEV_INTR_MODE_MSIX: - netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64); + for (i = 0; i < enic->rq_count; i++) + netif_napi_add(netdev, &enic->napi[i], + enic_poll_msix, 64); break; } diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 19a276cf7681..f111a37419ce 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -35,6 +35,7 @@ #include "vnic_intr.h" #include "vnic_stats.h" #include "vnic_nic.h" +#include "vnic_rss.h" #include "enic_res.h" #include "enic.h" @@ -93,13 +94,14 @@ int enic_get_vnic_config(struct enic *enic) INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), c->intr_timer_usec); - dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n", - enic->mac_addr, c->wq_desc_count, c->rq_desc_count); - dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d " - "tso/lro %d/%d intr timer %d usec\n", - c->mtu, ENIC_SETTING(enic, TXCSUM), - ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO), - ENIC_SETTING(enic, LRO), c->intr_timer_usec); + dev_info(enic_get_dev(enic), + "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", + enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu); + dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d " + "tso/lro %d/%d intr timer %d usec rss %d\n", + ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM), + ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO), + c->intr_timer_usec, ENIC_SETTING(enic, RSS)); return 0; } @@ -148,6 +150,22 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait); } +int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len) +{ + u64 a0 = (u64)key_pa, a1 = len; + int wait = 1000; + + return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait); +} + +int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len) +{ + u64 a0 = (u64)cpu_pa, a1 = len; + int wait = 1000; + + return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait); +} + void enic_free_vnic_resources(struct enic *enic) { unsigned int i; @@ -164,18 +182,11 @@ void enic_free_vnic_resources(struct enic *enic) void enic_get_res_counts(struct enic *enic) { - enic->wq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ), - ENIC_WQ_MAX); - enic->rq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ), - ENIC_RQ_MAX); - enic->cq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ), - ENIC_CQ_MAX); - enic->intr_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL), - ENIC_INTR_MAX); + enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ); + enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ); + enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ); + enic->intr_count = vnic_dev_get_res_count(enic->vdev, + RES_TYPE_INTR_CTRL); dev_info(enic_get_dev(enic), "vNIC resources avail: wq %d rq %d cq %d intr %d\n", diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 3c59f541cb5d..83bd172c356c 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -137,6 +137,8 @@ int enic_del_vlan(struct enic *enic, u16 vlanid); int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en, u8 ig_vlan_strip_en); +int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len); +int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len); void enic_get_res_counts(struct enic *enic); void enic_init_vnic_resources(struct enic *enic); int enic_alloc_vnic_resources(struct enic *); diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h new file mode 100644 index 000000000000..fa421baf45b8 --- /dev/null +++ b/drivers/net/enic/vnic_rss.h @@ -0,0 +1,40 @@ +/* + * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved. + * Copyright 2007 Nuova Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _VNIC_RSS_H_ +#define _VNIC_RSS_H_ + +/* RSS key array */ +union vnic_rss_key { + struct { + u8 b[10]; + u8 b_pad[6]; + } key[4]; + u64 raw[8]; +}; + +/* RSS cpu array */ +union vnic_rss_cpu { + struct { + u8 b[4] ; + u8 b_pad[4]; + } cpu[32]; + u64 raw[32]; +}; + +#endif /* _VNIC_RSS_H_ */ -- cgit v1.2.3 From c76fd32d0504c0450edb0e00890aa32e3ff1f73d Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 20 Oct 2010 10:17:04 +0000 Subject: enic: Make firmware cognizant of the user set mac address Let the firmware know about the mac address set by the user using ndo_set_mac_address Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index dcfc541291ef..622106d8c055 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -974,8 +974,19 @@ static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p) static int enic_set_mac_address(struct net_device *netdev, void *p) { struct sockaddr *saddr = p; + char *addr = saddr->sa_data; + struct enic *enic = netdev_priv(netdev); + int err; + + err = enic_dev_del_station_addr(enic); + if (err) + return err; + + err = enic_set_mac_addr(netdev, addr); + if (err) + return err; - return enic_set_mac_addr(netdev, (char *)saddr->sa_data); + return enic_dev_add_station_addr(enic); } static int enic_dev_packet_filter(struct enic *enic, int directed, -- cgit v1.2.3 From 2db77e0f331d343511d08e204be5e22f934e1a68 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 20 Oct 2010 10:17:09 +0000 Subject: enic: Replace firmware devcmd CMD_ENABLE with CMD_ENABLE_WAIT Replace no wait CMD_ENABLE firmware devcmd with CMD_ENABLE_WAIT Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 2 +- drivers/net/enic/vnic_dev.c | 10 ++++++++-- drivers/net/enic/vnic_dev.h | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 622106d8c055..a63d2babdd8d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1787,7 +1787,7 @@ static int enic_dev_enable(struct enic *enic) int err; spin_lock(&enic->devcmd_lock); - err = vnic_dev_enable(enic->vdev); + err = vnic_dev_enable_wait(enic->vdev); spin_unlock(&enic->devcmd_lock); return err; diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 11dc8f73e4be..fb35d8b17668 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -487,11 +487,17 @@ int vnic_dev_close(struct vnic_dev *vdev) return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); } -int vnic_dev_enable(struct vnic_dev *vdev) +int vnic_dev_enable_wait(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; int wait = 1000; - return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); + int err; + + err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); + if (err == ERR_ECMDUNKNOWN) + return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); + + return err; } int vnic_dev_disable(struct vnic_dev *vdev) diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 3f0014312080..05f9a24cd459 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -111,7 +111,7 @@ u32 vnic_dev_port_speed(struct vnic_dev *vdev); u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); u32 vnic_dev_mtu(struct vnic_dev *vdev); int vnic_dev_close(struct vnic_dev *vdev); -int vnic_dev_enable(struct vnic_dev *vdev); +int vnic_dev_enable_wait(struct vnic_dev *vdev); int vnic_dev_disable(struct vnic_dev *vdev); int vnic_dev_open(struct vnic_dev *vdev, int arg); int vnic_dev_open_done(struct vnic_dev *vdev, int *done); -- cgit v1.2.3 From d058590976cb76defb636d78999cca353a09695b Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 20 Oct 2010 10:17:14 +0000 Subject: enic: Change min MTU Change min MTU to 68. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_res.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 83bd172c356c..9a103d9ef9e2 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -30,7 +30,7 @@ #define ENIC_MIN_RQ_DESCS 64 #define ENIC_MAX_RQ_DESCS 4096 -#define ENIC_MIN_MTU 576 /* minimum for IPv4 */ +#define ENIC_MIN_MTU 68 #define ENIC_MAX_MTU 9000 #define ENIC_MULTICAST_PERFECT_FILTERS 32 -- cgit v1.2.3 From 53c90536e96218ed6d60e7ea7a69a92b68805cdf Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 20 Oct 2010 10:17:19 +0000 Subject: enic: Fix log message Fix a log message Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a63d2babdd8d..f47fbb63d8b6 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2428,7 +2428,7 @@ static int enic_dev_init(struct enic *enic) err = enic_dev_set_ig_vlan_rewrite_mode(enic); if (err) { - netdev_err(netdev, + dev_err(dev, "Failed to set ingress vlan rewrite mode, aborting.\n"); goto err_out_free_vnic_resources; } -- cgit v1.2.3 From 13937911f93ef52ae652f4652761aea6a58d3193 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:01 +0000 Subject: ebtables: Allow filtering of hardware accelerated vlan frames. An upcoming commit will allow packets with hardware vlan acceleration information to be passed though more parts of the network stack, including packets trunked through the bridge. This adds support for matching and filtering those packets through ebtables. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 16 +++++++++------- net/bridge/netfilter/ebt_vlan.c | 21 ++++++++++++++------- net/bridge/netfilter/ebtables.c | 15 +++++++++++---- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 7f9ce9600ef3..47c2dabe8669 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -64,22 +64,24 @@ static int brnf_filter_pppoe_tagged __read_mostly = 0; static inline __be16 vlan_proto(const struct sk_buff *skb) { - return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + if (vlan_tx_tag_present(skb)) + return skb->protocol; + else if (skb->protocol == htons(ETH_P_8021Q)) + return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + return 0; } #define IS_VLAN_IP(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_IP) && \ + (vlan_proto(skb) == htons(ETH_P_IP) && \ brnf_filter_vlan_tagged) #define IS_VLAN_IPV6(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_IPV6) &&\ + (vlan_proto(skb) == htons(ETH_P_IPV6) && \ brnf_filter_vlan_tagged) #define IS_VLAN_ARP(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_ARP) && \ + (vlan_proto(skb) == htons(ETH_P_ARP) && \ brnf_filter_vlan_tagged) static inline __be16 pppoe_proto(const struct sk_buff *skb) diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index 87b53b3a921d..cc11d6b8e507 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c @@ -39,8 +39,6 @@ static bool ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct ebt_vlan_info *info = par->matchinfo; - const struct vlan_hdr *fp; - struct vlan_hdr _frame; unsigned short TCI; /* Whole TCI, given from parsed frame */ unsigned short id; /* VLAN ID, given from frame TCI */ @@ -48,9 +46,20 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) /* VLAN encapsulated Type/Length field, given from orig frame */ __be16 encap; - fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); - if (fp == NULL) - return false; + if (vlan_tx_tag_present(skb)) { + TCI = vlan_tx_tag_get(skb); + encap = skb->protocol; + } else { + const struct vlan_hdr *fp; + struct vlan_hdr _frame; + + fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); + if (fp == NULL) + return false; + + TCI = ntohs(fp->h_vlan_TCI); + encap = fp->h_vlan_encapsulated_proto; + } /* Tag Control Information (TCI) consists of the following elements: * - User_priority. The user_priority field is three bits in length, @@ -59,10 +68,8 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) * (CFI) is a single bit flag value. Currently ignored. * - VLAN Identifier (VID). The VID is encoded as * an unsigned binary number. */ - TCI = ntohs(fp->h_vlan_TCI); id = TCI & VLAN_VID_MASK; prio = (TCI >> 13) & 0x7; - encap = fp->h_vlan_encapsulated_proto; /* Checking VLAN Identifier (VID) */ if (GET_BITMASK(EBT_VLAN_ID)) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bcc102e3be4d..a1dcf83f0d58 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -124,16 +124,23 @@ ebt_dev_check(const char *entry, const struct net_device *device) #define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg)) /* process standard matches */ static inline int -ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h, +ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out) { + const struct ethhdr *h = eth_hdr(skb); + __be16 ethproto; int verdict, i; + if (vlan_tx_tag_present(skb)) + ethproto = htons(ETH_P_8021Q); + else + ethproto = h->h_proto; + if (e->bitmask & EBT_802_3) { - if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO)) + if (FWINV2(ntohs(ethproto) >= 1536, EBT_IPROTO)) return 1; } else if (!(e->bitmask & EBT_NOPROTO) && - FWINV2(e->ethproto != h->h_proto, EBT_IPROTO)) + FWINV2(e->ethproto != ethproto, EBT_IPROTO)) return 1; if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN)) @@ -213,7 +220,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, base = private->entries; i = 0; while (i < nentries) { - if (ebt_basic_match(point, eth_hdr(skb), in, out)) + if (ebt_basic_match(point, skb, in, out)) goto letscontinue; if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0) -- cgit v1.2.3 From b738127dfb469bb9f595cdace30e7f881e8146b2 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:02 +0000 Subject: vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID. VLAN_GROUP_ARRAY_LEN is simply the number of possible vlan VIDs. Since vlan groups will soon be more of an implementation detail for vlan devices, rename the constant to be descriptive of its actual purpose. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- drivers/net/benet/be_main.c | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/igb/igb_main.c | 2 +- drivers/net/igbvf/netdev.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/qlcnic/qlcnic_main.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 6 +++--- include/linux/if_vlan.h | 4 ++-- net/8021q/vlan.c | 16 ++++++++-------- net/bridge/netfilter/ebt_vlan.c | 4 ++-- 16 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 1afabb1e6620..59a17b569b7f 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -263,7 +263,7 @@ struct be_adapter { struct vlan_group *vlan_grp; u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ - u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; + u8 vlan_tag[VLAN_N_VID]; struct be_dma_mem mc_cmd_mem; struct be_dma_mem stats_cmd; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9a1cd28b426d..4b59e53890b2 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -626,7 +626,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) if (adapter->vlans_added <= adapter->max_vlans) { /* Construct VLAN Table to give to HW */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { if (adapter->vlan_tag[i]) { vtag[ntags] = cpu_to_le16(i); ntags++; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index cb3f84b81793..232ac2dcb497 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4541,7 +4541,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; e1000_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 992b622fe205..5d6cdea0eb14 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2545,7 +2545,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter) if (!adapter->vlgrp) return; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; e1000_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b8dccc0ac089..0f0939caf091 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -6153,7 +6153,7 @@ static void igb_restore_vlan(struct igb_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; igb_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 6693323a6cf5..ebfaa68ee630 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1254,7 +1254,7 @@ static void igbvf_restore_vlan(struct igbvf_adapter *adapter) if (!adapter->vlgrp) return; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; igbvf_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 80e62578ffa0..666207a9c039 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -2223,7 +2223,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgb_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 790a0dae1247..1d424428079f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3185,7 +3185,7 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgbe_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 0866a1cf4d7b..78bfbe42ca9b 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -1495,7 +1495,7 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4aada0b8ceb1..f047c7c48314 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -4093,7 +4093,7 @@ qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) if (!adapter->vlgrp) return; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { dev = vlan_group_get_device(adapter->vlgrp, vid); if (!dev) continue; diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 198ce92af0c3..b1de73b1bf1a 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1634,7 +1634,7 @@ vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter) u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; bool activeVlan = false; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (vlan_group_get_device(adapter->vlan_grp, vid)) { VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); activeVlan = true; diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 5378b849f54f..0bda7fe05d4b 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -1862,7 +1862,7 @@ enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) if (vdev->vlgrp && vpath->is_open) { - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(vdev->vlgrp, vid)) continue; /* Add these vlan to the vid table */ diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index c094707fcbff..74d1401a5d5e 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1820,7 +1820,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) return; vg = card->vlangrp; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { struct net_device *netdev = vlan_group_get_device(vg, i); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -1883,7 +1883,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card) return; vg = card->vlangrp; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { struct net_device *netdev = vlan_group_get_device(vg, i); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -2247,7 +2247,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, if (!vg) return rc; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { if (vlan_group_get_device(vg, i) == dev) { rc = QETH_VLAN_CARD; break; diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index a52320751bfc..494cce866564 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -68,6 +68,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */ #define VLAN_TAG_PRESENT VLAN_CFI_MASK #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ +#define VLAN_N_VID 4096 /* found in socket.c */ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); @@ -76,9 +77,8 @@ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); * depends on completely exhausting the VLAN identifier space. Thus * it gives constant time look-up, but in many cases it wastes memory. */ -#define VLAN_GROUP_ARRAY_LEN 4096 #define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 -#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS) +#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) struct vlan_group { struct net_device *real_dev; /* The ethernet(like) device diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 25c21332e9c3..54f22d820ef5 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -439,7 +439,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, switch (event) { case NETDEV_CHANGE: /* Propagate real device state to vlan devices */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -450,7 +450,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_CHANGEADDR: /* Adjust unicast filters on underlying device */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -464,7 +464,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, break; case NETDEV_CHANGEMTU: - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -478,7 +478,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_FEAT_CHANGE: /* Propagate device features to underlying device */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -490,7 +490,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_DOWN: /* Put all VLANs for this dev in the down state too. */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -508,7 +508,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UP: /* Put all VLANs for this dev in the up state too. */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -532,7 +532,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, /* Delete all VLANs for this dev. */ grp->killall = 1; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -540,7 +540,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, /* unregistration of last vlan destroys group, abort * afterwards */ if (grp->nr_vlans == 1) - i = VLAN_GROUP_ARRAY_LEN; + i = VLAN_N_VID; unregister_vlan_dev(vlandev, &list); } diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index cc11d6b8e507..eae67bf0446c 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c @@ -118,10 +118,10 @@ static int ebt_vlan_mt_check(const struct xt_mtchk_param *par) * 0 - The null VLAN ID. * 1 - The default Port VID (PVID) * 0x0FFF - Reserved for implementation use. - * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. */ + * if_vlan.h: VLAN_N_VID 4096. */ if (GET_BITMASK(EBT_VLAN_ID)) { if (!!info->id) { /* if id!=0 => check vid range */ - if (info->id > VLAN_GROUP_ARRAY_LEN) { + if (info->id > VLAN_N_VID) { pr_debug("id %d is out of range (1-4096)\n", info->id); return -EINVAL; -- cgit v1.2.3 From eab6d18d20fc5b5ba04a7e7fcd6f357197870e51 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:03 +0000 Subject: vlan: Don't check for vlan group before vlan_tx_tag_present. Many (but not all) drivers check to see whether there is a vlan group configured before using a tag stored in the skb. There's not much point in this check since it just throws away data that should only be present in the expected circumstances. However, it will soon be legal and expected to get a vlan tag when no vlan group is configured, so remove this check from all drivers to avoid dropping the tags. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 2 +- drivers/net/amd8111e.c | 2 +- drivers/net/atl1c/atl1c_main.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl1.c | 2 +- drivers/net/atlx/atl2.c | 2 +- drivers/net/benet/be_main.c | 7 +++---- drivers/net/bna/bnad.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_cmn.c | 3 +-- drivers/net/chelsio/sge.c | 2 +- drivers/net/cxgb3/sge.c | 4 ++-- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/ehea/ehea_main.c | 2 +- drivers/net/enic/enic_main.c | 2 +- drivers/net/forcedeth.c | 11 ++++------- drivers/net/gianfar.c | 4 ++-- drivers/net/igb/igb_main.c | 2 +- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/mlx4/en_tx.c | 4 ++-- drivers/net/qlge/qlge_main.c | 2 +- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/sky2.c | 2 +- drivers/net/tg3.c | 4 ++-- drivers/net/via-velocity.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- 29 files changed, 38 insertions(+), 43 deletions(-) diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 237d4ea5a416..ac422cd332ea 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -754,7 +754,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, } #if CP_VLAN_TAG_USED - if (cp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb)); #endif diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 58a0ab4923ee..2ca880b4c0db 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1315,7 +1315,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb, lp->tx_ring[tx_index].tx_flags = 0; #if AMD8111E_VLAN_TAG_USED - if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){ + if (vlan_tx_tag_present(skb)) { lp->tx_ring[tx_index].tag_ctrl_cmd |= cpu_to_le16(TCC_VLAN_INSERT); lp->tx_ring[tx_index].tag_ctrl_info = diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 553230eb365c..99ffcf667d1f 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2243,7 +2243,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan = vlan_tx_tag_get(skb); __le16 tag; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 56ace3fbe40d..ef6349bf3b33 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1814,7 +1814,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, tpd = atl1e_get_tpd(adapter); - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan_tag = vlan_tx_tag_get(skb); u16 atl1e_vlan_tag; diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index b8c053f76878..dbd27b8e66bd 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2408,7 +2408,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, (u16) atomic_read(&tpd_ring->next_to_use)); memset(ptpd, 0, sizeof(struct tx_packet_desc)); - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | ((vlan_tag >> 9) & 0x8); diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 29c0265ccc5d..35b14bec1207 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -870,7 +870,7 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb, offset = ((u32)(skb->len-copy_len + 3) & ~3); } #ifdef NETIF_F_HW_VLAN_TX - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 4b59e53890b2..d5e796832fdd 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -430,7 +430,7 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) } static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, - bool vlan, u32 wrb_cnt, u32 len) + u32 wrb_cnt, u32 len) { memset(hdr, 0, sizeof(*hdr)); @@ -449,7 +449,7 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); } - if (vlan && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tx_tag_get(skb)); @@ -532,8 +532,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, queue_head_inc(txq); } - wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, - wrb_cnt, copied); + wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied); be_dws_cpu_to_le(hdr, sizeof(*hdr)); return copied; diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 74c64d6c8801..7e839b9cec22 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -2501,7 +2501,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO : BNA_TXQ_WI_SEND)); - if (bnad->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag = (u16) vlan_tx_tag_get(skb); flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); } diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ae894bca4afb..363ca8bcc974 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6429,7 +6429,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } #ifdef BCM_VLAN - if (bp->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 1966ceeefcd4..6905b2e0609e 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -2026,8 +2026,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && - (bp->flags & HW_VLAN_TX_FLAG)) { + if (vlan_tx_tag_present(skb)) { tx_start_bd->vlan_or_ethertype = cpu_to_le16(vlan_tx_tag_get(skb)); tx_start_bd->bd_flags.as_bitfield |= diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 340b537dc97e..70221ca32683 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1870,7 +1870,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl->iff = dev->if_port; #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { cpl->vlan_valid = 1; cpl->vlan = htons(vlan_tx_tag_get(skb)); st->vlan_insert++; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index c5a142bea5e9..7ad4625dac62 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1145,7 +1145,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, cpl->len = htonl(skb->len); cntrl = V_TXPKT_INTF(pi->port_id); - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb)); tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size); @@ -1279,7 +1279,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) qs->port_stats[SGE_PSTAT_TX_CSUM]++; if (skb_shinfo(skb)->gso_size) qs->port_stats[SGE_PSTAT_TSO]++; - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) qs->port_stats[SGE_PSTAT_VLANINS]++; /* diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 232ac2dcb497..a117f2a0252e 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3119,7 +3119,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5d6cdea0eb14..ec8cf3f51423 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4800,7 +4800,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (e1000_maybe_stop_tx(netdev, count + 2)) return NETDEV_TX_BUSY; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 6932578816d3..a0d117022be6 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2272,7 +2272,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - if (port->vgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { swqe->tx_control |= EHEA_SWQE_VLAN_INSERT; swqe->vlan_tag = vlan_tx_tag_get(skb); } diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index f47fbb63d8b6..a466ef91dd43 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -805,7 +805,7 @@ static inline void enic_queue_wq_skb(struct enic *enic, int vlan_tag_insert = 0; int loopback = 0; - if (enic->vlan_group && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { /* VLAN tag from trunking driver */ vlan_tag_insert = 1; vlan_tag = vlan_tx_tag_get(skb); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index ddac63cefbaa..0fa1776563a3 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2321,14 +2321,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; /* vlan tag */ - if (likely(!np->vlangrp)) { + if (vlan_tx_tag_present(skb)) + start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | + vlan_tx_tag_get(skb)); + else start_tx->txvlan = 0; - } else { - if (vlan_tx_tag_present(skb)) - start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb)); - else - start_tx->txvlan = 0; - } spin_lock_irqsave(&np->lock, flags); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6180089bf67a..4c4cc80ec0a1 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2075,7 +2075,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* make space for additional header when fcb is needed */ if (((skb->ip_summed == CHECKSUM_PARTIAL) || - (priv->vlgrp && vlan_tx_tag_present(skb)) || + vlan_tx_tag_present(skb) || unlikely(do_tstamp)) && (skb_headroom(skb) < GMAC_FCB_LEN)) { struct sk_buff *skb_new; @@ -2161,7 +2161,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) gfar_tx_checksum(skb, fcb); } - if (priv->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (unlikely(NULL == fcb)) { fcb = gfar_add_fcb(skb); lstatus |= BD_LFLAG(TXBD_TOE); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0f0939caf091..75155a27fdde 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4128,7 +4128,7 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, tx_flags |= IGB_TX_FLAGS_TSTAMP; } - if (vlan_tx_tag_present(skb) && adapter->vlgrp) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IGB_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1d424428079f..998debe8023b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6311,7 +6311,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev int count = 0; unsigned int f; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 78bfbe42ca9b..dc03c9652389 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -3134,7 +3134,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_ring = &adapter->tx_ring[r_idx]; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 98dd620042a8..a680cd4a5ab6 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -583,7 +583,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) /* If we support per priority flow control and the packet contains * a vlan tag, send the packet to the TX ring assigned to that priority */ - if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) { + if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); } @@ -634,7 +634,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) tx_ind = skb->queue_mapping; ring = &priv->tx_ring[tx_ind]; - if (priv->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); /* Check available TXBBs And 2K spare for prefetch */ diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 4ffebe83d883..ba0053d8515e 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2572,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len); - if (qdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb)); mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1760533852a4..242748b2c357 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1034,7 +1034,7 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { - return (tp->vlgrp && vlan_tx_tag_present(skb)) ? + return (vlan_tx_tag_present(skb)) ? TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index c70ad515383a..ecc25aab896a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -4101,7 +4101,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) } queue = 0; - if (sp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) { if (skb->protocol == htons(ETH_P_IP)) { diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3ef9b67ac6e6..d6577084ce70 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1782,7 +1782,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, ctrl = 0; #ifdef SKY2_VLAN_TAG_USED /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ - if (sky2->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (!le) { le = get_tx_le(sky2, &slot); le->addr = 0; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5b4c510dbced..22720eeabddb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5745,7 +5745,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif @@ -5991,7 +5991,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, } } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f1995615dc84..cab96ad49e60 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2592,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16; - if (vptr->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb)); td_ptr->tdesc1.TCR |= TCR0_VETAG; } diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0bda7fe05d4b..a69542ecb68d 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -822,7 +822,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, __func__, __LINE__, fifo_hw, dtr, dtr_priv); - if (vdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag); } -- cgit v1.2.3 From 7b9c60903714bf0a19d746b228864bad3497284e Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:04 +0000 Subject: vlan: Enable software emulation for vlan accleration. Currently users of hardware vlan accleration need to know whether the device supports it before generating packets. However, vlan acceleration will soon be available in a more flexible manner so knowing ahead of time becomes much more difficult. This adds a software fallback path for vlan packets on devices without the necessary offloading support, similar to other types of hardware accleration. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/netdevice.h | 14 +++++++++++--- net/core/dev.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 880d56565828..2861565a27d9 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2248,9 +2248,17 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features) static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { - return skb_is_gso(skb) && - (!skb_gso_ok(skb, dev->features) || - unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); + if (skb_is_gso(skb)) { + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci) + features &= dev->vlan_features; + + return (!skb_gso_ok(skb, features) || + unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); + } + + return 0; } static inline void netif_set_gso_max_size(struct net_device *dev, diff --git a/net/core/dev.c b/net/core/dev.c index 4c3ac53e4b16..1bfd96b1fbd4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1694,7 +1694,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) { - if (can_checksum_protocol(dev->features, skb->protocol)) + int features = dev->features; + + if (vlan_tx_tag_present(skb)) + features &= dev->vlan_features; + + if (can_checksum_protocol(features, skb->protocol)) return true; if (skb->protocol == htons(ETH_P_8021Q)) { @@ -1793,6 +1798,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) __be16 type = skb->protocol; int err; + if (type == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veh; + + if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) + return ERR_PTR(-EINVAL); + + veh = (struct vlan_ethhdr *)skb->data; + type = veh->h_vlan_encapsulated_proto; + } + skb_reset_mac_header(skb); skb->mac_len = skb->network_header - skb->mac_header; __skb_pull(skb, skb->mac_len); @@ -1964,9 +1979,14 @@ static inline void skb_orphan_try(struct sk_buff *skb) static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) + features &= dev->vlan_features; + return skb_is_nonlinear(skb) && - ((skb_has_frag_list(skb) && !(dev->features & NETIF_F_FRAGLIST)) || - (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || + ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || illegal_highdma(dev, skb)))); } @@ -1989,6 +2009,15 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, skb_orphan_try(skb); + if (vlan_tx_tag_present(skb) && + !(dev->features & NETIF_F_HW_VLAN_TX)) { + skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); + if (unlikely(!skb)) + goto out; + + skb->vlan_tci = 0; + } + if (netif_needs_gso(dev, skb)) { if (unlikely(dev_gso_segment(skb))) goto out_kfree_skb; @@ -2050,6 +2079,7 @@ out_kfree_gso_skb: skb->destructor = DEV_GSO_CB(skb)->destructor; out_kfree_skb: kfree_skb(skb); +out: return rc; } -- cgit v1.2.3 From 65ac6a5fa658b90f1be700c55e7cd72e4611015d Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:05 +0000 Subject: vlan: Avoid hash table lookup to find group. A struct net_device always maps to zero or one vlan groups and we always know the device when we are looking up a group. We currently do a hash table lookup on the device to find the group but it is much simpler to just store a pointer. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 19 ++++++++++++++ include/linux/netdevice.h | 5 +++- net/8021q/vlan.c | 64 ++++++++--------------------------------------- net/8021q/vlan.h | 17 ------------- net/8021q/vlan_dev.c | 2 +- 5 files changed, 34 insertions(+), 73 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 494cce866564..4047781da727 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -16,6 +16,7 @@ #ifdef __KERNEL__ #include #include +#include #define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header) * that VLAN requires. @@ -114,6 +115,18 @@ static inline void vlan_group_set_device(struct vlan_group *vg, #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +/* Must be invoked with rcu_read_lock or with RTNL. */ +static inline struct net_device *vlan_find_dev(struct net_device *real_dev, + u16 vlan_id) +{ + struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); + + if (grp) + return vlan_group_get_device(grp, vlan_id); + + return NULL; +} + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); @@ -128,6 +141,12 @@ vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci); #else +static inline struct net_device *vlan_find_dev(struct net_device *real_dev, + u16 vlan_id) +{ + return NULL; +} + static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) { BUG(); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2861565a27d9..9c78312ce142 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -942,7 +942,10 @@ struct net_device { /* Protocol specific pointers */ - + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + struct vlan_group *vlgrp; /* VLAN group */ +#endif #ifdef CONFIG_NET_DSA void *dsa_ptr; /* dsa specific data */ #endif diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 54f22d820ef5..f862dccf6bb0 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -44,9 +44,6 @@ int vlan_net_id __read_mostly; -/* Our listing of VLAN group(s) */ -static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; - const char vlan_fullname[] = "802.1Q VLAN Support"; const char vlan_version[] = DRV_VERSION; static const char vlan_copyright[] = "Ben Greear "; @@ -59,40 +56,6 @@ static struct packet_type vlan_packet_type __read_mostly = { /* End of global variables definitions. */ -static inline unsigned int vlan_grp_hashfn(unsigned int idx) -{ - return ((idx >> VLAN_GRP_HASH_SHIFT) ^ idx) & VLAN_GRP_HASH_MASK; -} - -/* Must be invoked with RCU read lock (no preempt) */ -static struct vlan_group *__vlan_find_group(struct net_device *real_dev) -{ - struct vlan_group *grp; - struct hlist_node *n; - int hash = vlan_grp_hashfn(real_dev->ifindex); - - hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { - if (grp->real_dev == real_dev) - return grp; - } - - return NULL; -} - -/* Find the protocol handler. Assumes VID < VLAN_VID_MASK. - * - * Must be invoked with RCU read lock (no preempt) - */ -struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id) -{ - struct vlan_group *grp = __vlan_find_group(real_dev); - - if (grp) - return vlan_group_get_device(grp, vlan_id); - - return NULL; -} - static void vlan_group_free(struct vlan_group *grp) { int i; @@ -111,8 +74,6 @@ static struct vlan_group *vlan_group_alloc(struct net_device *real_dev) return NULL; grp->real_dev = real_dev; - hlist_add_head_rcu(&grp->hlist, - &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]); return grp; } @@ -151,7 +112,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) ASSERT_RTNL(); - grp = __vlan_find_group(real_dev); + grp = real_dev->vlgrp; BUG_ON(!grp); /* Take it out of our own structures, but be sure to interlock with @@ -173,11 +134,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) if (grp->nr_vlans == 0) { vlan_gvrp_uninit_applicant(real_dev); + rcu_assign_pointer(real_dev->vlgrp, NULL); if (real_dev->features & NETIF_F_HW_VLAN_RX) ops->ndo_vlan_rx_register(real_dev, NULL); - hlist_del_rcu(&grp->hlist); - /* Free the group, after all cpu's are done. */ call_rcu(&grp->rcu, vlan_rcu_free); } @@ -207,7 +167,7 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) return -EOPNOTSUPP; } - if (__find_vlan_dev(real_dev, vlan_id) != NULL) + if (vlan_find_dev(real_dev, vlan_id) != NULL) return -EEXIST; return 0; @@ -222,7 +182,7 @@ int register_vlan_dev(struct net_device *dev) struct vlan_group *grp, *ngrp = NULL; int err; - grp = __vlan_find_group(real_dev); + grp = real_dev->vlgrp; if (!grp) { ngrp = grp = vlan_group_alloc(real_dev); if (!grp) @@ -252,8 +212,11 @@ int register_vlan_dev(struct net_device *dev) vlan_group_set_device(grp, vlan_id, dev); grp->nr_vlans++; - if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX) - ops->ndo_vlan_rx_register(real_dev, ngrp); + if (ngrp) { + if (real_dev->features & NETIF_F_HW_VLAN_RX) + ops->ndo_vlan_rx_register(real_dev, ngrp); + rcu_assign_pointer(real_dev->vlgrp, ngrp); + } if (real_dev->features & NETIF_F_HW_VLAN_FILTER) ops->ndo_vlan_rx_add_vid(real_dev, vlan_id); @@ -264,7 +227,6 @@ out_uninit_applicant: vlan_gvrp_uninit_applicant(real_dev); out_free_group: if (ngrp) { - hlist_del_rcu(&ngrp->hlist); /* Free the group, after all cpu's are done. */ call_rcu(&ngrp->rcu, vlan_rcu_free); } @@ -428,7 +390,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); } - grp = __vlan_find_group(dev); + grp = dev->vlgrp; if (!grp) goto out; @@ -746,8 +708,6 @@ err0: static void __exit vlan_cleanup_module(void) { - unsigned int i; - vlan_ioctl_set(NULL); vlan_netlink_fini(); @@ -755,10 +715,6 @@ static void __exit vlan_cleanup_module(void) dev_remove_pack(&vlan_packet_type); - /* This table must be empty if there are no module references left. */ - for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) - BUG_ON(!hlist_empty(&vlan_group_hash[i])); - unregister_pernet_subsys(&vlan_net_ops); rcu_barrier(); /* Wait for completion of call_rcu()'s */ diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 8d9503ad01da..db01b3181fdc 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -72,23 +72,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) return netdev_priv(dev); } -#define VLAN_GRP_HASH_SHIFT 5 -#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) -#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) - -/* Find a VLAN device by the MAC address of its Ethernet device, and - * it's VLAN ID. The default configuration is to have VLAN's scope - * to be box-wide, so the MAC will be ignored. The mac will only be - * looked at if we are configured to have a separate set of VLANs per - * each MAC addressable interface. Note that this latter option does - * NOT follow the spec for VLANs, but may be useful for doing very - * large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs. - * - * Must be invoked with rcu_read_lock (ie preempt disabled) - * or with RTNL. - */ -struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id); - /* found in vlan_dev.c */ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f54251edd40d..14e3d1fa07a0 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -158,7 +158,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, vlan_id = vlan_tci & VLAN_VID_MASK; rcu_read_lock(); - vlan_dev = __find_vlan_dev(dev, vlan_id); + vlan_dev = vlan_find_dev(dev, vlan_id); /* If the VLAN device is defined, we use it. * If not, and the VID is 0, it is a 802.1p packet (not -- cgit v1.2.3 From 3701e51382a026cba10c60b03efabe534fba4ca4 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:06 +0000 Subject: vlan: Centralize handling of hardware acceleration. Currently each driver that is capable of vlan hardware acceleration must be aware of the vlan groups that are configured and then pass the stripped tag to a specialized receive function. This is different from other types of hardware offload in that it places a significant amount of knowledge in the driver itself rather keeping it in the networking core. This makes vlan offloading function more similarly to other forms of offloading (such as checksum offloading or TSO) by doing the following: * On receive, stripped vlans are passed directly to the network core, without attempting to check for vlan groups or reconstructing the header if no group * vlans are made less special by folding the logic into the main receive routines * On transmit, the device layer will add the vlan header in software if the hardware doesn't support it, instead of spreading that logic out in upper layers, such as bonding. There are a number of advantages to this: * Fixes all bugs with drivers incorrectly dropping vlan headers at once. * Avoids having to disable VLAN acceleration when in promiscuous mode (good for bridging since it always puts devices in promiscuous mode). * Keeps VLAN tag separate until given to ultimate consumer, which avoids needing to do header reconstruction as in tg3 unless absolutely necessary. * Consolidates common code in core networking. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 6 ++- include/linux/netdevice.h | 1 - net/8021q/vlan.c | 9 +--- net/8021q/vlan_core.c | 125 ++++++++++------------------------------------ net/core/dev.c | 47 ++++++----------- 5 files changed, 48 insertions(+), 140 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 4047781da727..a0d9786c202d 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -132,7 +132,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); -extern void vlan_hwaccel_do_receive(struct sk_buff *skb); +extern bool vlan_hwaccel_do_receive(struct sk_buff **skb); extern gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); @@ -166,8 +166,10 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_XMIT_SUCCESS; } -static inline void vlan_hwaccel_do_receive(struct sk_buff *skb) +static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb) { + BUG(); + return false; } static inline gro_result_t diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9c78312ce142..ed7db7eebbf3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1768,7 +1768,6 @@ extern int netdev_rx_handler_register(struct net_device *dev, void *rx_handler_data); extern void netdev_rx_handler_unregister(struct net_device *dev); -extern void netif_nit_deliver(struct sk_buff *skb); extern int dev_valid_name(const char *name); extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); extern int dev_ethtool(struct net *net, struct ifreq *); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index f862dccf6bb0..05b867e43757 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -135,7 +135,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) vlan_gvrp_uninit_applicant(real_dev); rcu_assign_pointer(real_dev->vlgrp, NULL); - if (real_dev->features & NETIF_F_HW_VLAN_RX) + if (ops->ndo_vlan_rx_register) ops->ndo_vlan_rx_register(real_dev, NULL); /* Free the group, after all cpu's are done. */ @@ -156,11 +156,6 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) return -EOPNOTSUPP; } - if ((real_dev->features & NETIF_F_HW_VLAN_RX) && !ops->ndo_vlan_rx_register) { - pr_info("8021q: device %s has buggy VLAN hw accel\n", name); - return -EOPNOTSUPP; - } - if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { pr_info("8021q: Device %s has buggy VLAN hw accel\n", name); @@ -213,7 +208,7 @@ int register_vlan_dev(struct net_device *dev) grp->nr_vlans++; if (ngrp) { - if (real_dev->features & NETIF_F_HW_VLAN_RX) + if (ops->ndo_vlan_rx_register) ops->ndo_vlan_rx_register(real_dev, ngrp); rcu_assign_pointer(real_dev->vlgrp, ngrp); } diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index dee727ce0291..69b2f79800a5 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -4,54 +4,29 @@ #include #include "vlan.h" -/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ -int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, - u16 vlan_tci, int polling) +bool vlan_hwaccel_do_receive(struct sk_buff **skbp) { + struct sk_buff *skb = *skbp; + u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; struct net_device *vlan_dev; - u16 vlan_id; - - if (netpoll_rx(skb)) - return NET_RX_DROP; - - if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - skb->deliver_no_wcard = 1; + struct vlan_rx_stats *rx_stats; - skb->skb_iif = skb->dev->ifindex; - __vlan_hwaccel_put_tag(skb, vlan_tci); - vlan_id = vlan_tci & VLAN_VID_MASK; - vlan_dev = vlan_group_get_device(grp, vlan_id); - - if (vlan_dev) - skb->dev = vlan_dev; - else if (vlan_id) { - if (!(skb->dev->flags & IFF_PROMISC)) - goto drop; - skb->pkt_type = PACKET_OTHERHOST; + vlan_dev = vlan_find_dev(skb->dev, vlan_id); + if (!vlan_dev) { + if (vlan_id) + skb->pkt_type = PACKET_OTHERHOST; + return false; } - return polling ? netif_receive_skb(skb) : netif_rx(skb); + skb = *skbp = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return false; -drop: - atomic_long_inc(&skb->dev->rx_dropped); - dev_kfree_skb_any(skb); - return NET_RX_DROP; -} -EXPORT_SYMBOL(__vlan_hwaccel_rx); - -void vlan_hwaccel_do_receive(struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - struct vlan_rx_stats *rx_stats; - - skb->dev = vlan_dev_real_dev(dev); - netif_nit_deliver(skb); - - skb->dev = dev; - skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci); + skb->dev = vlan_dev; + skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); skb->vlan_tci = 0; - rx_stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; @@ -68,11 +43,13 @@ void vlan_hwaccel_do_receive(struct sk_buff *skb) * This allows the VLAN to have a different MAC than the * underlying device, and still route correctly. */ if (!compare_ether_addr(eth_hdr(skb)->h_dest, - dev->dev_addr)) + vlan_dev->dev_addr)) skb->pkt_type = PACKET_HOST; break; } u64_stats_update_end(&rx_stats->syncp); + + return true; } struct net_device *vlan_dev_real_dev(const struct net_device *dev) @@ -87,75 +64,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev) } EXPORT_SYMBOL(vlan_dev_vlan_id); -static gro_result_t -vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct sk_buff *skb) +/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ +int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, + u16 vlan_tci, int polling) { - struct sk_buff *p; - struct net_device *vlan_dev; - u16 vlan_id; - - if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - skb->deliver_no_wcard = 1; - - skb->skb_iif = skb->dev->ifindex; __vlan_hwaccel_put_tag(skb, vlan_tci); - vlan_id = vlan_tci & VLAN_VID_MASK; - vlan_dev = vlan_group_get_device(grp, vlan_id); - - if (vlan_dev) - skb->dev = vlan_dev; - else if (vlan_id) { - if (!(skb->dev->flags & IFF_PROMISC)) - goto drop; - skb->pkt_type = PACKET_OTHERHOST; - } - - for (p = napi->gro_list; p; p = p->next) { - unsigned long diffs; - - diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; - diffs |= compare_ether_header(skb_mac_header(p), - skb_gro_mac_header(skb)); - NAPI_GRO_CB(p)->same_flow = !diffs; - NAPI_GRO_CB(p)->flush = 0; - } - - return dev_gro_receive(napi, skb); - -drop: - atomic_long_inc(&skb->dev->rx_dropped); - return GRO_DROP; + return polling ? netif_receive_skb(skb) : netif_rx(skb); } +EXPORT_SYMBOL(__vlan_hwaccel_rx); gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb) { - if (netpoll_rx_on(skb)) - return vlan_hwaccel_receive_skb(skb, grp, vlan_tci) - ? GRO_DROP : GRO_NORMAL; - - skb_gro_reset_offset(skb); - - return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb); + __vlan_hwaccel_put_tag(skb, vlan_tci); + return napi_gro_receive(napi, skb); } EXPORT_SYMBOL(vlan_gro_receive); gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci) { - struct sk_buff *skb = napi_frags_skb(napi); - - if (!skb) - return GRO_DROP; - - if (netpoll_rx_on(skb)) { - skb->protocol = eth_type_trans(skb, skb->dev); - return vlan_hwaccel_receive_skb(skb, grp, vlan_tci) - ? GRO_DROP : GRO_NORMAL; - } - - return napi_frags_finish(napi, skb, - vlan_gro_common(napi, grp, vlan_tci, skb)); + __vlan_hwaccel_put_tag(napi->skb, vlan_tci); + return napi_gro_frags(napi); } EXPORT_SYMBOL(vlan_gro_frags); diff --git a/net/core/dev.c b/net/core/dev.c index 1bfd96b1fbd4..97fd6bc2004c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2789,33 +2789,6 @@ out: } #endif -/* - * netif_nit_deliver - deliver received packets to network taps - * @skb: buffer - * - * This function is used to deliver incoming packets to network - * taps. It should be used when the normal netif_receive_skb path - * is bypassed, for example because of VLAN acceleration. - */ -void netif_nit_deliver(struct sk_buff *skb) -{ - struct packet_type *ptype; - - if (list_empty(&ptype_all)) - return; - - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb->mac_len = skb->network_header - skb->mac_header; - - rcu_read_lock(); - list_for_each_entry_rcu(ptype, &ptype_all, list) { - if (!ptype->dev || ptype->dev == skb->dev) - deliver_skb(skb, ptype, skb->dev); - } - rcu_read_unlock(); -} - /** * netdev_rx_handler_register - register receive handler * @dev: device to register a handler for @@ -2925,9 +2898,6 @@ static int __netif_receive_skb(struct sk_buff *skb) if (!netdev_tstamp_prequeue) net_timestamp_check(skb); - if (vlan_tx_tag_present(skb)) - vlan_hwaccel_do_receive(skb); - /* if we've gotten here through NAPI, check netpoll */ if (netpoll_receive_skb(skb)) return NET_RX_DROP; @@ -2940,8 +2910,7 @@ static int __netif_receive_skb(struct sk_buff *skb) * be delivered to pkt handlers that are exact matches. Also * the deliver_no_wcard flag will be set. If packet handlers * are sensitive to duplicate packets these skbs will need to - * be dropped at the handler. The vlan accel path may have - * already set the deliver_no_wcard flag. + * be dropped at the handler. */ null_or_orig = NULL; orig_dev = skb->dev; @@ -3000,6 +2969,18 @@ ncls: goto out; } + if (vlan_tx_tag_present(skb)) { + if (pt_prev) { + ret = deliver_skb(skb, pt_prev, orig_dev); + pt_prev = NULL; + } + if (vlan_hwaccel_do_receive(&skb)) { + ret = __netif_receive_skb(skb); + goto out; + } else if (unlikely(!skb)) + goto out; + } + /* * Make sure frames received on VLAN interfaces stacked on * bonding interfaces still make their way to any base bonding @@ -3264,6 +3245,7 @@ __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) unsigned long diffs; diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; + diffs |= p->vlan_tci ^ skb->vlan_tci; diffs |= compare_ether_header(skb_mac_header(p), skb_gro_mac_header(skb)); NAPI_GRO_CB(p)->same_flow = !diffs; @@ -3323,6 +3305,7 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) { __skb_pull(skb, skb_headlen(skb)); skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); + skb->vlan_tci = 0; napi->skb = skb; } -- cgit v1.2.3 From d5dbda23804156ae6f35025ade5307a49d1db6d7 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:07 +0000 Subject: ethtool: Add support for vlan accleration. Now that vlan acceleration is handled consistently regardless of usage, it is possible to enable and disable it at will. This adds support for Ethtool operations that change the offloading status for debugging purposes, similar to other forms of hardware acceleration. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/ethtool.h | 2 ++ net/core/ethtool.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 8a3338ceb438..6628a507fd3b 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -309,6 +309,8 @@ struct ethtool_perm_addr { * flag differs from the read-only value. */ enum ethtool_flags { + ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */ + ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */ ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */ ETH_FLAG_RXHASH = (1 << 28), diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 685c7005e87f..956a9f4971cb 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -132,7 +132,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo); * NETIF_F_xxx values in include/linux/netdevice.h */ static const u32 flags_dup_features = - (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH); + (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE | + ETH_FLAG_RXHASH); u32 ethtool_op_get_flags(struct net_device *dev) { -- cgit v1.2.3 From 361ff8a6cf90d62c0071b7e532e37369bfd3ae77 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:08 +0000 Subject: bridge: Add support for TX vlan offload. If some of the underlying devices support it, enable vlan offload on transmit for bridge devices. This allows senders to take advantage of the hardware support, similar to other forms of acceleration. Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- net/bridge/br_device.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index cf09fe591fc2..17cb0b633576 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -212,6 +212,11 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) return 0; } +static int br_set_flags(struct net_device *netdev, u32 data) +{ + return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN); +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void br_poll_controller(struct net_device *br_dev) { @@ -304,6 +309,7 @@ static const struct ethtool_ops br_ethtool_ops = { .get_ufo = ethtool_op_get_ufo, .set_ufo = ethtool_op_set_ufo, .get_flags = ethtool_op_get_flags, + .set_flags = br_set_flags, }; static const struct net_device_ops br_netdev_ops = { @@ -343,5 +349,5 @@ void br_dev_setup(struct net_device *dev) dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | - NETIF_F_NETNS_LOCAL | NETIF_F_GSO; + NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX; } -- cgit v1.2.3 From 7d0fd2117e3d0550d7987b3aff2bfbc0244cf7c6 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:09 +0000 Subject: bnx2: Update bnx2 to use new vlan accleration. Make the bnx2 driver use the new vlan accleration model. Signed-off-by: Jesse Gross CC: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 97 ++++++++++++++++-------------------------------------- drivers/net/bnx2.h | 4 --- 2 files changed, 28 insertions(+), 73 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 363ca8bcc974..bf3c830e7dda 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -37,9 +37,6 @@ #include #include #include -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define BCM_VLAN 1 -#endif #include #include #include @@ -3087,8 +3084,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) struct sw_bd *rx_buf, *next_rx_buf; struct sk_buff *skb; dma_addr_t dma_addr; - u16 vtag = 0; - int hw_vlan __maybe_unused = 0; sw_ring_cons = RX_RING_IDX(sw_cons); sw_ring_prod = RX_RING_IDX(sw_prod); @@ -3168,23 +3163,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) goto next_rx; if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && - !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) { - vtag = rx_hdr->l2_fhdr_vlan_tag; -#ifdef BCM_VLAN - if (bp->vlgrp) - hw_vlan = 1; - else -#endif - { - struct vlan_ethhdr *ve = (struct vlan_ethhdr *) - __skb_push(skb, 4); - - memmove(ve, skb->data + 4, ETH_ALEN * 2); - ve->h_vlan_proto = htons(ETH_P_8021Q); - ve->h_vlan_TCI = htons(vtag); - len += 4; - } - } + !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) + __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag); skb->protocol = eth_type_trans(skb, bp->dev); @@ -3211,14 +3191,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) skb->rxhash = rx_hdr->l2_fhdr_hash; skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]); - -#ifdef BCM_VLAN - if (hw_vlan) - vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb); - else -#endif - napi_gro_receive(&bnapi->napi, skb); - + napi_gro_receive(&bnapi->napi, skb); rx_pkt++; next_rx: @@ -3533,13 +3506,9 @@ bnx2_set_rx_mode(struct net_device *dev) rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; -#ifdef BCM_VLAN - if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) + if (!(dev->features & NETIF_F_HW_VLAN_RX) && + (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; -#else - if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) - rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; -#endif if (dev->flags & IFF_PROMISC) { /* Promiscuous mode. */ rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; @@ -6365,29 +6334,6 @@ bnx2_tx_timeout(struct net_device *dev) schedule_work(&bp->reset_task); } -#ifdef BCM_VLAN -/* Called with rtnl_lock */ -static void -bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (netif_running(dev)) - bnx2_netif_stop(bp, false); - - bp->vlgrp = vlgrp; - - if (!netif_running(dev)) - return; - - bnx2_set_rx_mode(dev); - if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) - bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); - - bnx2_netif_start(bp, false); -} -#endif - /* Called with netif_tx_lock. * bnx2_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue(). @@ -6428,12 +6374,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; } -#ifdef BCM_VLAN if (vlan_tx_tag_present(skb)) { vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } -#endif + if ((mss = skb_shinfo(skb)->gso_size)) { u32 tcp_opt_len; struct iphdr *iph; @@ -7578,7 +7523,28 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data) static int bnx2_set_flags(struct net_device *dev, u32 data) { - return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH); + struct bnx2 *bp = netdev_priv(dev); + int rc; + + if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) && + !(data & ETH_FLAG_RXVLAN)) + return -EOPNOTSUPP; + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN); + if (rc) + return rc; + + if ((!!(data & ETH_FLAG_RXVLAN) != + !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) && + netif_running(dev)) { + bnx2_netif_stop(bp, false); + bnx2_set_rx_mode(dev); + bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); + bnx2_netif_start(bp, false); + } + + return 0; } static const struct ethtool_ops bnx2_ethtool_ops = { @@ -8318,9 +8284,6 @@ static const struct net_device_ops bnx2_netdev_ops = { .ndo_set_mac_address = bnx2_change_mac_addr, .ndo_change_mtu = bnx2_change_mtu, .ndo_tx_timeout = bnx2_tx_timeout, -#ifdef BCM_VLAN - .ndo_vlan_rx_register = bnx2_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2, #endif @@ -8328,9 +8291,7 @@ static const struct net_device_ops bnx2_netdev_ops = { static void inline vlan_features_add(struct net_device *dev, unsigned long flags) { -#ifdef BCM_VLAN dev->vlan_features |= flags; -#endif } static int __devinit @@ -8379,9 +8340,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= NETIF_F_IPV6_CSUM; vlan_features_add(dev, NETIF_F_IPV6_CSUM); } -#ifdef BCM_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN); if (CHIP_NUM(bp) == CHIP_NUM_5709) { diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index efdfbc2a9e37..4f44db68c802 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6742,10 +6742,6 @@ struct bnx2 { struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC]; -#ifdef BCM_VLAN - struct vlan_group *vlgrp; -#endif - u32 rx_buf_use_size; /* useable size */ u32 rx_buf_size; /* with alignment */ u32 rx_copy_thresh; -- cgit v1.2.3 From f62bbb5e62c6e4a91fb222d22bc46e8d4d7e59ef Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 20 Oct 2010 13:56:10 +0000 Subject: ixgbe: Update ixgbe to use new vlan accleration. Make the ixgbe driver use the new vlan accleration model. Signed-off-by: Jesse Gross CC: Peter Waskiewicz CC: Emil Tantilov CC: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 4 +- drivers/net/ixgbe/ixgbe_ethtool.c | 12 +++- drivers/net/ixgbe/ixgbe_main.c | 137 +++++++++++++++++--------------------- 3 files changed, 74 insertions(+), 79 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index a8c47b01a6fa..5e38de79fbbd 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -28,11 +28,13 @@ #ifndef _IXGBE_H_ #define _IXGBE_H_ +#include #include #include #include #include #include +#include #include "ixgbe_type.h" #include "ixgbe_common.h" @@ -287,7 +289,7 @@ struct ixgbe_q_vector { /* board specific private data structure */ struct ixgbe_adapter { struct timer_list watchdog_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 bd_number; struct work_struct reset_task; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index d4ac94324fa0..dbfd62fd40eb 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2113,7 +2113,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) bool need_reset = false; int rc; - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE); +#ifdef CONFIG_IXGBE_DCB + if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && + !(data & ETH_FLAG_RXVLAN)) + return -EINVAL; +#endif + + need_reset = (data & ETH_FLAG_RXVLAN) != + (netdev->features & NETIF_F_HW_VLAN_RX); + + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | + ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); if (rc) return rc; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 998debe8023b..56f6b80e1084 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, bool is_vlan = (status & IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { - if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) - vlan_gro_receive(napi, adapter->vlgrp, tag, skb); - else - napi_gro_receive(napi, skb); - } else { - if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) - vlan_hwaccel_rx(skb, adapter->vlgrp, tag); - else - netif_rx(skb); - } + if (is_vlan && (tag & VLAN_VID_MASK)) + __vlan_hwaccel_put_tag(skb, tag); + + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) + napi_gro_receive(napi, skb); + else + netif_rx(skb); } /** @@ -3065,6 +3061,7 @@ static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add VID to filter table */ hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true); + set_bit(vid, adapter->active_vlans); } static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -3073,16 +3070,9 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct ixgbe_hw *hw = &adapter->hw; int pool_ndx = adapter->num_vfs; - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter, true, true); - /* remove VID from filter table */ hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); + clear_bit(vid, adapter->active_vlans); } /** @@ -3092,27 +3082,45 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + u32 vlnctrl; + + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); +} + +/** + * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering + * @adapter: driver data + */ +static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; + + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VFE; + vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); +} + +/** + * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping + * @adapter: driver data + */ +static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; int i, j; switch (hw->mac.type) { case ixgbe_mac_82598EB: - vlnctrl &= ~IXGBE_VLNCTRL_VFE; -#ifdef CONFIG_IXGBE_DCB - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - vlnctrl &= ~IXGBE_VLNCTRL_VME; -#endif - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl &= ~IXGBE_VLNCTRL_VME; IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - vlnctrl &= ~IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); -#ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) - break; -#endif for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3126,25 +3134,22 @@ static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) } /** - * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering + * ixgbe_vlan_strip_enable - helper to enable hw vlan stripping * @adapter: driver data */ -static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) +static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + u32 vlnctrl; int i, j; switch (hw->mac.type) { case ixgbe_mac_82598EB: - vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VME; IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - vlnctrl |= IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3157,40 +3162,14 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) } } -static void ixgbe_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - adapter->vlgrp = grp; - - /* - * For a DCB driver, always enable VLAN tag stripping so we can - * still receive traffic from a DCB-enabled host even if we're - * not in DCB mode. - */ - ixgbe_vlan_filter_enable(adapter); - - ixgbe_vlan_rx_add_vid(netdev, 0); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter, true, true); -} - static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) { - ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - ixgbe_vlan_rx_add_vid(adapter->netdev, vid); - } - } + ixgbe_vlan_rx_add_vid(adapter->netdev, 0); + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + ixgbe_vlan_rx_add_vid(adapter->netdev, vid); } /** @@ -3305,6 +3284,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev) } IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + if (netdev->features & NETIF_F_HW_VLAN_RX) + ixgbe_vlan_strip_enable(adapter); + else + ixgbe_vlan_strip_disable(adapter); } static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) @@ -3388,7 +3372,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); } /* Enable VLAN tag insert/strip */ - ixgbe_vlan_filter_enable(adapter); + adapter->netdev->features |= NETIF_F_HW_VLAN_RX; hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); } @@ -3400,13 +3384,13 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; int i; - ixgbe_set_rx_mode(netdev); - - ixgbe_restore_vlan(adapter); #ifdef CONFIG_IXGBE_DCB ixgbe_configure_dcb(adapter); #endif + ixgbe_set_rx_mode(netdev); + ixgbe_restore_vlan(adapter); + #ifdef IXGBE_FCOE if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) ixgbe_configure_fcoe(adapter); @@ -6569,7 +6553,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_mac_address = ixgbe_set_mac, .ndo_change_mtu = ixgbe_change_mtu, .ndo_tx_timeout = ixgbe_tx_timeout, - .ndo_vlan_rx_register = ixgbe_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, .ndo_do_ioctl = ixgbe_ioctl, -- cgit v1.2.3 From 9bcc08939223c5a2bad42748ee53ab69f5338a32 Mon Sep 17 00:00:00 2001 From: Hao Zheng Date: Wed, 20 Oct 2010 13:56:11 +0000 Subject: bnx2x: Update bnx2x to use new vlan accleration. Make the bnx2x driver use the new vlan accleration model. Signed-off-by: Hao Zheng Signed-off-by: Jesse Gross CC: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 10 ------- drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++++-------------------------------- drivers/net/bnx2x/bnx2x_ethtool.c | 33 +++++++++++---------- drivers/net/bnx2x/bnx2x_main.c | 8 ------ 4 files changed, 27 insertions(+), 84 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 3bf236b160dd..9571ecf48f35 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -24,10 +24,6 @@ #define DRV_MODULE_RELDATE "2010/10/19" #define BNX2X_BC_VER 0x040200 -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define BCM_VLAN 1 -#endif - #define BNX2X_MULTI_QUEUE #define BNX2X_NEW_NAPI @@ -858,10 +854,6 @@ struct bnx2x { int tx_ring_size; -#ifdef BCM_VLAN - struct vlan_group *vlgrp; -#endif - u32 rx_csum; u32 rx_buf_size; /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ @@ -925,8 +917,6 @@ struct bnx2x { #define NO_MCP_FLAG 0x100 #define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) -#define HW_VLAN_TX_FLAG 0x400 -#define HW_VLAN_RX_FLAG 0x800 #define MF_FUNC_DIS 0x1000 int pf_num; /* absolute PF number */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 6905b2e0609e..bc5837514074 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -16,16 +16,13 @@ */ #include +#include #include #include #include #include #include "bnx2x_cmn.h" -#ifdef BCM_VLAN -#include -#endif - #include "bnx2x_init.h" @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ -#ifdef BCM_VLAN - int is_vlan_cqe = - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN); - int is_not_hwaccel_vlan_cqe = - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); -#endif prefetch(skb); prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct iphdr *iph; iph = (struct iphdr *)skb->data; -#ifdef BCM_VLAN - /* If there is no Rx VLAN offloading - - take VLAN tag into an account */ - if (unlikely(is_not_hwaccel_vlan_cqe)) - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); -#endif iph->check = 0; iph->check = ip_fast_csum((u8 *)iph, iph->ihl); } if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && - (le16_to_cpu(cqe->fast_path_cqe. - pars_flags.flags) & PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, + if ((le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) + __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe. - vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + vlan_tag)); + napi_gro_receive(&fp->napi, skb); } else { DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" " - dropping packet!\n"); @@ -633,15 +613,11 @@ reuse_rx: skb_record_rx_queue(skb, fp->index); -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN) + __vlan_hwaccel_put_tag(skb, + le16_to_cpu(cqe->fast_path_cqe.vlan_tag)); + napi_gro_receive(&fp->napi, skb); next_rx: @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) "sending pkt %u @%p next_idx %u bd %u @%p\n", pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); -#ifdef BCM_VLAN if (vlan_tx_tag_present(skb)) { tx_start_bd->vlan_or_ethertype = cpu_to_le16(vlan_tx_tag_get(skb)); tx_start_bd->bd_flags.as_bitfield |= (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); } else -#endif tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); /* turn on parsing and get a BD */ @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev) schedule_delayed_work(&bp->reset_task, 0); } -#ifdef BCM_VLAN -/* called with rtnl_lock */ -void bnx2x_vlan_rx_register(struct net_device *dev, - struct vlan_group *vlgrp) -{ - struct bnx2x *bp = netdev_priv(dev); - - bp->vlgrp = vlgrp; -} - -#endif - int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 54fe0615a8b9..daefef618ef7 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data) int changed = 0; int rc = 0; - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH)) - return -EINVAL; - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); return -EAGAIN; } + if (!(data & ETH_FLAG_RXVLAN)) + return -EOPNOTSUPP; + + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa) + return -EINVAL; + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH); + if (rc) + return rc; + /* TPA requires Rx CSUM offloading */ if ((data & ETH_FLAG_LRO) && bp->rx_csum) { - if (!bp->disable_tpa) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - bp->flags |= TPA_ENABLE_FLAG; - changed = 1; - } - } else - rc = -EINVAL; - } else if (dev->features & NETIF_F_LRO) { + if (!(bp->flags & TPA_ENABLE_FLAG)) { + bp->flags |= TPA_ENABLE_FLAG; + changed = 1; + } + } else if (bp->flags & TPA_ENABLE_FLAG) { dev->features &= ~NETIF_F_LRO; bp->flags &= ~TPA_ENABLE_FLAG; changed = 1; } - if (data & ETH_FLAG_RXHASH) - dev->features |= NETIF_F_RXHASH; - else - dev->features &= ~NETIF_F_RXHASH; - if (changed && netif_running(dev)) { bnx2x_nic_unload(bp, UNLOAD_NORMAL); rc = bnx2x_nic_load(bp, LOAD_NORMAL); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f22e283cabef..ff99a2fc0426 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, flags |= QUEUE_FLG_HC; flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; -#ifdef BCM_VLAN flags |= QUEUE_FLG_VLAN; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); -#endif if (!fp->disable_tpa) flags |= QUEUE_FLG_TPA; @@ -8630,9 +8628,6 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_do_ioctl = bnx2x_ioctl, .ndo_change_mtu = bnx2x_change_mtu, .ndo_tx_timeout = bnx2x_tx_timeout, -#ifdef BCM_VLAN - .ndo_vlan_rx_register = bnx2x_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2x, #endif @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->features |= NETIF_F_TSO6; -#ifdef BCM_VLAN dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); dev->vlan_features |= NETIF_F_SG; dev->vlan_features |= NETIF_F_HW_CSUM; @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |= NETIF_F_HIGHDMA; dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; -#endif /* get_port_hwinfo() will set prtad and mmds properly */ bp->mdio.prtad = MDIO_PRTAD_NONE; -- cgit v1.2.3 From 3eafe50708deca10d155ccff597a91dcecc2d869 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:36 +0000 Subject: r8169: check dma mapping failures Check possible dma mapping errors and do clean up if it happens. Fix overwrap bug in rtl8169_tx_clear on the way. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 66 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 242748b2c357..88d5826ce93d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3992,11 +3992,18 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct pci_dev *pdev, if (!data) return NULL; } + mapping = dma_map_single(&pdev->dev, rtl8169_align(data), rx_buf_sz, PCI_DMA_FROMDEVICE); + if (unlikely(dma_mapping_error(&pdev->dev, mapping))) + goto err_out; rtl8169_map_to_asic(desc, mapping, rx_buf_sz); return data; + +err_out: + kfree(data); + return NULL; } static void rtl8169_rx_clear(struct rtl8169_private *tp) @@ -4080,12 +4087,13 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, tx_skb->len = 0; } -static void rtl8169_tx_clear(struct rtl8169_private *tp) +static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, + unsigned int n) { unsigned int i; - for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) { - unsigned int entry = i % NUM_TX_DESC; + for (i = 0; i < n; i++) { + unsigned int entry = (start + i) % NUM_TX_DESC; struct ring_info *tx_skb = tp->tx_skb + entry; unsigned int len = tx_skb->len; @@ -4101,6 +4109,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->dev->stats.tx_dropped++; } } +} + +static void rtl8169_tx_clear(struct rtl8169_private *tp) +{ + rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); tp->cur_tx = tp->dirty_tx = 0; } @@ -4219,6 +4232,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, addr = ((void *) page_address(frag->page)) + frag->page_offset; mapping = dma_map_single(&tp->pci_dev->dev, addr, len, PCI_DMA_TODEVICE); + if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) + goto err_out; /* anti gcc 2.95.3 bugware (sic) */ status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); @@ -4235,6 +4250,10 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, } return cur_frag; + +err_out: + rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); + return -EIO; } static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) @@ -4261,40 +4280,44 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC; + unsigned int entry = tp->cur_tx % NUM_TX_DESC; struct TxDesc *txd = tp->TxDescArray + entry; void __iomem *ioaddr = tp->mmio_addr; dma_addr_t mapping; u32 status, len; u32 opts1; + int frags; if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); - goto err_stop; + goto err_stop_0; } if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) - goto err_stop; + goto err_stop_0; + + len = skb_headlen(skb); + mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, + PCI_DMA_TODEVICE); + if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) + goto err_dma_0; + + tp->tx_skb[entry].len = len; + txd->addr = cpu_to_le64(mapping); + txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); opts1 = DescOwn | rtl8169_tso_csum(skb, dev); frags = rtl8169_xmit_frags(tp, skb, opts1); - if (frags) { - len = skb_headlen(skb); + if (frags < 0) + goto err_dma_1; + else if (frags) opts1 |= FirstFrag; - } else { - len = skb->len; + else { opts1 |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; } - mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, - PCI_DMA_TODEVICE); - - tp->tx_skb[entry].len = len; - txd->addr = cpu_to_le64(mapping); - txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); - wmb(); /* anti gcc 2.95.3 bugware (sic) */ @@ -4316,7 +4339,14 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; -err_stop: +err_dma_1: + rtl8169_unmap_tx_skb(tp->pci_dev, tp->tx_skb + entry, txd); +err_dma_0: + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + +err_stop_0: netif_stop_queue(dev); dev->stats.tx_dropped++; return NETDEV_TX_BUSY; -- cgit v1.2.3 From 0ecbe1cadd406cb48424c796450bfaa18cb0b3ac Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:37 +0000 Subject: r8169: init rx ring cleanup Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 88d5826ce93d..20deeeaab5d9 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3974,12 +3974,12 @@ static inline void *rtl8169_align(void *data) return (void *)ALIGN((long)data, 16); } -static struct sk_buff *rtl8169_alloc_rx_data(struct pci_dev *pdev, - struct net_device *dev, - struct RxDesc *desc) +static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, + struct RxDesc *desc) { void *data; dma_addr_t mapping; + struct net_device *dev = tp->dev; int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; data = kmalloc_node(rx_buf_sz, GFP_KERNEL, node); @@ -3993,9 +3993,9 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct pci_dev *pdev, return NULL; } - mapping = dma_map_single(&pdev->dev, rtl8169_align(data), rx_buf_sz, + mapping = dma_map_single(&tp->pci_dev->dev, rtl8169_align(data), rx_buf_sz, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(&pdev->dev, mapping))) + if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) goto err_out; rtl8169_map_to_asic(desc, mapping, rx_buf_sz); @@ -4018,34 +4018,35 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) } } -static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, - u32 start, u32 end, gfp_t gfp) +static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc) { - u32 cur; + desc->opts1 |= cpu_to_le32(RingEnd); +} - for (cur = start; end - cur != 0; cur++) { - void *data; - unsigned int i = cur % NUM_RX_DESC; +static int rtl8169_rx_fill(struct rtl8169_private *tp) +{ + unsigned int i; - WARN_ON((s32)(end - cur) < 0); + for (i = 0; i < NUM_RX_DESC; i++) { + void *data; if (tp->Rx_databuff[i]) continue; - data = rtl8169_alloc_rx_data(tp->pci_dev, dev, - tp->RxDescArray + i); + data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i); if (!data) { rtl8169_make_unusable_by_asic(tp->RxDescArray + i); - break; + goto err_out; } tp->Rx_databuff[i] = data; } - return cur - start; -} -static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc) -{ - desc->opts1 |= cpu_to_le32(RingEnd); + rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); + return 0; + +err_out: + rtl8169_rx_clear(tp); + return -ENOMEM; } static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) @@ -4062,16 +4063,7 @@ static int rtl8169_init_ring(struct net_device *dev) memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); memset(tp->Rx_databuff, 0x0, NUM_RX_DESC * sizeof(void *)); - if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) - goto err_out; - - rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); - - return 0; - -err_out: - rtl8169_rx_clear(tp); - return -ENOMEM; + return rtl8169_rx_fill(tp); } static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, -- cgit v1.2.3 From 231aee63c1e270353fc0dc7fd4d5605a96562ec0 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:38 +0000 Subject: r8169: replace PCI_DMA_{TO,FROM}DEVICE to DMA_{TO,FROM}_DEVICE Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 20deeeaab5d9..981b195811bb 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3948,7 +3948,7 @@ static void rtl8169_free_rx_databuff(struct rtl8169_private *tp, struct pci_dev *pdev = tp->pci_dev; dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), rx_buf_sz, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); kfree(*data_buff); *data_buff = NULL; rtl8169_make_unusable_by_asic(desc); @@ -3994,7 +3994,7 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, } mapping = dma_map_single(&tp->pci_dev->dev, rtl8169_align(data), rx_buf_sz, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) goto err_out; @@ -4072,7 +4072,7 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, unsigned int len = tx_skb->len; dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); desc->opts1 = 0x00; desc->opts2 = 0x00; desc->addr = 0x00; @@ -4223,7 +4223,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, len = frag->size; addr = ((void *) page_address(frag->page)) + frag->page_offset; mapping = dma_map_single(&tp->pci_dev->dev, addr, len, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) goto err_out; @@ -4290,7 +4290,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, len = skb_headlen(skb); mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) goto err_dma_0; @@ -4469,13 +4469,13 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data, data = rtl8169_align(data); dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); prefetch(data); skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size); if (skb) memcpy(skb->data, data, pkt_size); dma_sync_single_for_device(&tp->pci_dev->dev, addr, pkt_size, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); return skb; } -- cgit v1.2.3 From 48addcc9edd551d09063148886bd6f3467d74c15 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:39 +0000 Subject: r8169: use pointer to struct device as local variable Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 981b195811bb..c36f64264300 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1200,6 +1200,7 @@ static void rtl8169_update_counters(struct net_device *dev) dma_addr_t paddr; u32 cmd; int wait = 1000; + struct device *d = &tp->pci_dev->dev; /* * Some chips are unable to dump tally counters when the receiver @@ -1208,8 +1209,7 @@ static void rtl8169_update_counters(struct net_device *dev) if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) return; - counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters), - &paddr, GFP_KERNEL); + counters = dma_alloc_coherent(d, sizeof(*counters), &paddr, GFP_KERNEL); if (!counters) return; @@ -1230,8 +1230,7 @@ static void rtl8169_update_counters(struct net_device *dev) RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrHigh, 0); - dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters, - paddr); + dma_free_coherent(d, sizeof(*counters), counters, paddr); } static void rtl8169_get_ethtool_stats(struct net_device *dev, @@ -3945,10 +3944,9 @@ static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) static void rtl8169_free_rx_databuff(struct rtl8169_private *tp, void **data_buff, struct RxDesc *desc) { - struct pci_dev *pdev = tp->pci_dev; - - dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), rx_buf_sz, + dma_unmap_single(&tp->pci_dev->dev, le64_to_cpu(desc->addr), rx_buf_sz, DMA_FROM_DEVICE); + kfree(*data_buff); *data_buff = NULL; rtl8169_make_unusable_by_asic(desc); @@ -3979,6 +3977,7 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, { void *data; dma_addr_t mapping; + struct device *d = &tp->pci_dev->dev; struct net_device *dev = tp->dev; int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; @@ -3993,9 +3992,9 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, return NULL; } - mapping = dma_map_single(&tp->pci_dev->dev, rtl8169_align(data), rx_buf_sz, + mapping = dma_map_single(d, rtl8169_align(data), rx_buf_sz, DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) + if (unlikely(dma_mapping_error(d, mapping))) goto err_out; rtl8169_map_to_asic(desc, mapping, rx_buf_sz); @@ -4066,13 +4065,13 @@ static int rtl8169_init_ring(struct net_device *dev) return rtl8169_rx_fill(tp); } -static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, +static void rtl8169_unmap_tx_skb(struct device *d, struct ring_info *tx_skb, struct TxDesc *desc) { unsigned int len = tx_skb->len; - dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, - DMA_TO_DEVICE); + dma_unmap_single(d, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE); + desc->opts1 = 0x00; desc->opts2 = 0x00; desc->addr = 0x00; @@ -4092,7 +4091,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, if (len) { struct sk_buff *skb = tx_skb->skb; - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, + rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, tp->TxDescArray + entry); if (skb) { dev_kfree_skb(skb); @@ -4209,6 +4208,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, struct skb_shared_info *info = skb_shinfo(skb); unsigned int cur_frag, entry; struct TxDesc * uninitialized_var(txd); + struct device *d = &tp->pci_dev->dev; entry = tp->cur_tx; for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { @@ -4222,9 +4222,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, txd = tp->TxDescArray + entry; len = frag->size; addr = ((void *) page_address(frag->page)) + frag->page_offset; - mapping = dma_map_single(&tp->pci_dev->dev, addr, len, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) + mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) goto err_out; /* anti gcc 2.95.3 bugware (sic) */ @@ -4275,6 +4274,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, unsigned int entry = tp->cur_tx % NUM_TX_DESC; struct TxDesc *txd = tp->TxDescArray + entry; void __iomem *ioaddr = tp->mmio_addr; + struct device *d = &tp->pci_dev->dev; dma_addr_t mapping; u32 status, len; u32 opts1; @@ -4289,9 +4289,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, goto err_stop_0; len = skb_headlen(skb); - mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(&tp->pci_dev->dev, mapping))) + mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) goto err_dma_0; tp->tx_skb[entry].len = len; @@ -4332,7 +4331,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; err_dma_1: - rtl8169_unmap_tx_skb(tp->pci_dev, tp->tx_skb + entry, txd); + rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd); err_dma_0: dev_kfree_skb(skb); dev->stats.tx_dropped++; @@ -4414,8 +4413,8 @@ static void rtl8169_tx_interrupt(struct net_device *dev, dev->stats.tx_bytes += len; dev->stats.tx_packets++; - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); - + rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, + tp->TxDescArray + entry); if (status & LastFrag) { dev_kfree_skb(tx_skb->skb); tx_skb->skb = NULL; @@ -4466,16 +4465,16 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data, dma_addr_t addr) { struct sk_buff *skb; + struct device *d = &tp->pci_dev->dev; data = rtl8169_align(data); - dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); prefetch(data); skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size); if (skb) memcpy(skb->data, data, pkt_size); - dma_sync_single_for_device(&tp->pci_dev->dev, addr, pkt_size, - DMA_FROM_DEVICE); + dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); + return skb; } -- cgit v1.2.3 From cac4b22f3d6a2601d896e9ae5147d173342c66f8 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:40 +0000 Subject: r8169: do not account fragments as packets Only increase tx_{packets,dropped} statistics when transmit or drop full skb, not just fragment. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index c36f64264300..a8be98cad579 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4094,10 +4094,10 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, tp->TxDescArray + entry); if (skb) { + tp->dev->stats.tx_dropped++; dev_kfree_skb(skb); tx_skb->skb = NULL; } - tp->dev->stats.tx_dropped++; } } } @@ -4402,7 +4402,6 @@ static void rtl8169_tx_interrupt(struct net_device *dev, while (tx_left > 0) { unsigned int entry = dirty_tx % NUM_TX_DESC; struct ring_info *tx_skb = tp->tx_skb + entry; - u32 len = tx_skb->len; u32 status; rmb(); @@ -4410,12 +4409,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev, if (status & DescOwn) break; - dev->stats.tx_bytes += len; - dev->stats.tx_packets++; - rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, tp->TxDescArray + entry); if (status & LastFrag) { + dev->stats.tx_packets++; + dev->stats.tx_bytes += tx_skb->skb->len; dev_kfree_skb(tx_skb->skb); tx_skb->skb = NULL; } -- cgit v1.2.3 From 323bb6857533d7132e1d4fd9cc8edc599a06f5e6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:41 +0000 Subject: r8169: changing mtu clean up Since we do not change rx buffer size any longer, we can clean up rtl8169_change_mtu and in consequence rtl8169_down. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 47 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a8be98cad579..8715ec3a25a8 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3908,31 +3908,11 @@ static void rtl_hw_start_8101(struct net_device *dev) static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { - struct rtl8169_private *tp = netdev_priv(dev); - int ret = 0; - if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) return -EINVAL; dev->mtu = new_mtu; - - if (!netif_running(dev)) - goto out; - - rtl8169_down(dev); - - ret = rtl8169_init_ring(dev); - if (ret < 0) - goto out; - - napi_enable(&tp->napi); - - rtl_hw_start(dev); - - rtl8169_request_timer(dev); - -out: - return ret; + return 0; } static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) @@ -4684,7 +4664,6 @@ static void rtl8169_down(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned int intrmask; rtl8169_delete_timer(dev); @@ -4692,11 +4671,14 @@ static void rtl8169_down(struct net_device *dev) napi_disable(&tp->napi); -core_down: spin_lock_irq(&tp->lock); rtl8169_asic_down(ioaddr); - + /* + * At this point device interrupts can not be enabled in any function, + * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, + * rtl8169_reinit_task) and napi is disabled (rtl8169_poll). + */ rtl8169_rx_missed(dev, ioaddr); spin_unlock_irq(&tp->lock); @@ -4706,23 +4688,6 @@ core_down: /* Give a racing hard_start_xmit a few cycles to complete. */ synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ - /* - * And now for the 50k$ question: are IRQ disabled or not ? - * - * Two paths lead here: - * 1) dev->close - * -> netif_running() is available to sync the current code and the - * IRQ handler. See rtl8169_interrupt for details. - * 2) dev->change_mtu - * -> rtl8169_poll can not be issued again and re-enable the - * interruptions. Let's simply issue the IRQ down sequence again. - * - * No loop if hotpluged or major error (0xffff). - */ - intrmask = RTL_R16(IntrMask); - if (intrmask && (intrmask != 0xffff)) - goto core_down; - rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); -- cgit v1.2.3 From fccec10b33503a2b1197c8e7a3abd30443bedb08 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:42 +0000 Subject: r8169: (re)init phy on resume Fix switching device to low-speed mode after resume reported in: https://bugzilla.redhat.com/show_bug.cgi?id=502974 Reported-and-tested-by: Laurentiu Badea Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 8715ec3a25a8..0204fe2b2490 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4824,6 +4824,9 @@ static int rtl8169_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8169_private *tp = netdev_priv(dev); + + rtl8169_init_phy(dev, tp); if (netif_running(dev)) __rtl8169_resume(dev); @@ -4864,6 +4867,8 @@ static int rtl8169_runtime_resume(struct device *device) tp->saved_wolopts = 0; spin_unlock_irq(&tp->lock); + rtl8169_init_phy(dev, tp); + __rtl8169_resume(dev); return 0; -- cgit v1.2.3 From d827d86b6fe87b420ef3c0685ab580290ae64beb Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 20 Oct 2010 22:25:43 +0000 Subject: r8169: print errors when dma mapping fail If dma mapping fail we are dropping packages or fail to open device. But exact reason of drop/fail stays unknow for a user, so print errors. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0204fe2b2490..d88ce9fb1cbd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3974,8 +3974,11 @@ static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, mapping = dma_map_single(d, rtl8169_align(data), rx_buf_sz, DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(d, mapping))) + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n"); goto err_out; + } rtl8169_map_to_asic(desc, mapping, rx_buf_sz); return data; @@ -4203,8 +4206,12 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, len = frag->size; addr = ((void *) page_address(frag->page)) + frag->page_offset; mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(d, mapping))) + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, tp->dev, + "Failed to map TX fragments DMA!\n"); goto err_out; + } /* anti gcc 2.95.3 bugware (sic) */ status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); @@ -4270,8 +4277,11 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, len = skb_headlen(skb); mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(d, mapping))) + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, dev, "Failed to map TX DMA!\n"); goto err_dma_0; + } tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); -- cgit v1.2.3 From 5bc9068e9d962ca6b8bec3f0eb6f60ab4dee1d04 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:14:31 +0300 Subject: ipvs: fix CHECKSUM_PARTIAL for TCP, UDP Fix CHECKSUM_PARTIAL handling. Tested for IPv4 TCP, UDP not tested because it needs network card with HW CSUM support. May be fixes problem where IPVS can not be used in virtual boxes. Problem appears with DNAT to local address when the local stack sends reply in CHECKSUM_PARTIAL mode. Fix tcp_dnat_handler and udp_dnat_handler to provide vaddr and daddr in right order (old and new IP) when calling tcp_partial_csum_update/udp_partial_csum_update (CHECKSUM_PARTIAL). Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_proto_tcp.c | 10 +++++----- net/netfilter/ipvs/ip_vs_proto_udp.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 282d24de8592..318d011036db 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -101,15 +101,15 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) tcph->check = - csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, + ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(tcph->check)))); + csum_unfold(tcph->check)))); else #endif tcph->check = - csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, + ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(tcph->check)))); + csum_unfold(tcph->check)))); } @@ -223,7 +223,7 @@ tcp_dnat_handler(struct sk_buff *skb, * Adjust TCP checksums */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, + tcp_partial_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - tcphoff)); } else if (!cp->app) { diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 8553231b5d41..f9290893bd93 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -102,15 +102,15 @@ udp_partial_csum_update(int af, struct udphdr *uhdr, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) uhdr->check = - csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, + ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(uhdr->check)))); + csum_unfold(uhdr->check)))); else #endif uhdr->check = - csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, + ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(uhdr->check)))); + csum_unfold(uhdr->check)))); } @@ -229,7 +229,7 @@ udp_dnat_handler(struct sk_buff *skb, * Adjust UDP checksums */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, + udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - udphoff)); } else if (!cp->app && (udph->check != 0)) { -- cgit v1.2.3 From 8b27b10f5863a5b63e46304a71aa01463d1efac4 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:17:20 +0300 Subject: ipvs: optimize checksums for apps Avoid full checksum calculation for apps that can provide info whether csum was broken after payload mangling. For now only ip_vs_ftp mangles payload and it updates the csum, so the full recalculation is avoided for all packets. Add CHECKSUM_UNNECESSARY for snat_handler (TCP and UDP). It is needed to support SNAT from local address for the case when csum is fully recalculated. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 12 ++++++++++-- net/netfilter/ipvs/ip_vs_ftp.c | 7 ++++++- net/netfilter/ipvs/ip_vs_proto_tcp.c | 31 +++++++++++++++++++++++++------ net/netfilter/ipvs/ip_vs_proto_udp.c | 31 +++++++++++++++++++++++++------ 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 6e8a6192e574..adcdba9dd183 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -597,11 +597,19 @@ struct ip_vs_app { __be16 port; /* port number in net order */ atomic_t usecnt; /* usage counter */ - /* output hook: return false if can't linearize. diff set for TCP. */ + /* + * output hook: Process packet in inout direction, diff set for TCP. + * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, + * 2=Mangled but checksum was not updated + */ int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, struct sk_buff *, int *diff); - /* input hook: return false if can't linearize. diff set for TCP. */ + /* + * input hook: Process packet in outin direction, diff set for TCP. + * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, + * 2=Mangled but checksum was not updated + */ int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, struct sk_buff *, int *diff); diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 090889a3b3af..75455000ad1c 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -242,9 +242,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo, start-data, end-start, buf, buf_len); - if (ret) + if (ret) { ip_vs_nfct_expect_related(skb, ct, n_cp, IPPROTO_TCP, 0, 0); + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->ip_summed = CHECKSUM_UNNECESSARY; + /* csum is updated */ + ret = 1; + } } /* diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 318d011036db..64dc2954cf78 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -120,6 +120,7 @@ tcp_snat_handler(struct sk_buff *skb, struct tcphdr *tcph; unsigned int tcphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -134,13 +135,20 @@ tcp_snat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; /* Call application helper if needed */ - if (!ip_vs_app_pkt_out(cp, skb)) + if (!(ret = ip_vs_app_pkt_out(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - tcphoff; + else + payload_csum = 1; } tcph = (void *)skb_network_header(skb) + tcphoff; @@ -151,12 +159,13 @@ tcp_snat_handler(struct sk_buff *skb, tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, htons(oldlen), htons(skb->len - tcphoff)); - } else if (!cp->app) { + } else if (!payload_csum) { /* Only port and addr are changed, do fast csum update */ tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, cp->dport, cp->vport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ tcph->check = 0; @@ -174,6 +183,7 @@ tcp_snat_handler(struct sk_buff *skb, skb->len - tcphoff, cp->protocol, skb->csum); + skb->ip_summed = CHECKSUM_UNNECESSARY; IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", pp->name, tcph->check, @@ -190,6 +200,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct tcphdr *tcph; unsigned int tcphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -204,6 +215,8 @@ tcp_dnat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -212,8 +225,13 @@ tcp_dnat_handler(struct sk_buff *skb, * Attempt ip_vs_app call. * It will fix ip_vs_conn and iph ack_seq stuff */ - if (!ip_vs_app_pkt_in(cp, skb)) + if (!(ret = ip_vs_app_pkt_in(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - tcphoff; + else + payload_csum = 1; } tcph = (void *)skb_network_header(skb) + tcphoff; @@ -226,12 +244,13 @@ tcp_dnat_handler(struct sk_buff *skb, tcp_partial_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - tcphoff)); - } else if (!cp->app) { + } else if (!payload_csum) { /* Only port and addr are changed, do fast csum update */ tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr, cp->vport, cp->dport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ tcph->check = 0; diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index f9290893bd93..9c558c40bfbb 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -121,6 +121,7 @@ udp_snat_handler(struct sk_buff *skb, struct udphdr *udph; unsigned int udphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -135,6 +136,8 @@ udp_snat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -142,8 +145,13 @@ udp_snat_handler(struct sk_buff *skb, /* * Call application helper if needed */ - if (!ip_vs_app_pkt_out(cp, skb)) + if (!(ret = ip_vs_app_pkt_out(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - udphoff; + else + payload_csum = 1; } udph = (void *)skb_network_header(skb) + udphoff; @@ -156,12 +164,13 @@ udp_snat_handler(struct sk_buff *skb, udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, htons(oldlen), htons(skb->len - udphoff)); - } else if (!cp->app && (udph->check != 0)) { + } else if (!payload_csum && (udph->check != 0)) { /* Only port and addr are changed, do fast csum update */ udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, cp->dport, cp->vport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ udph->check = 0; @@ -181,6 +190,7 @@ udp_snat_handler(struct sk_buff *skb, skb->csum); if (udph->check == 0) udph->check = CSUM_MANGLED_0; + skb->ip_summed = CHECKSUM_UNNECESSARY; IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", pp->name, udph->check, (char*)&(udph->check) - (char*)udph); @@ -196,6 +206,7 @@ udp_dnat_handler(struct sk_buff *skb, struct udphdr *udph; unsigned int udphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -210,6 +221,8 @@ udp_dnat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -218,8 +231,13 @@ udp_dnat_handler(struct sk_buff *skb, * Attempt ip_vs_app call. * It will fix ip_vs_conn */ - if (!ip_vs_app_pkt_in(cp, skb)) + if (!(ret = ip_vs_app_pkt_in(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - udphoff; + else + payload_csum = 1; } udph = (void *)skb_network_header(skb) + udphoff; @@ -232,12 +250,13 @@ udp_dnat_handler(struct sk_buff *skb, udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - udphoff)); - } else if (!cp->app && (udph->check != 0)) { + } else if (!payload_csum && (udph->check != 0)) { /* Only port and addr are changed, do fast csum update */ udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr, cp->vport, cp->dport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ udph->check = 0; -- cgit v1.2.3 From cf356d69db0afef692cd640917bc70f708c27f14 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:21:07 +0300 Subject: ipvs: switch to notrack mode Change skb->ipvs_property semantic. This is preparation to support ip_vs_out processing in LOCAL_OUT. ipvs_property=1 will be used to avoid expensive lookups for traffic sent by transmitters. Now when conntrack support is not used we call ip_vs_notrack method to avoid problems in OUTPUT and POST_ROUTING hooks instead of exiting POST_ROUTING as before. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 20 +++++++++++++++++++- net/netfilter/ipvs/ip_vs_core.c | 39 ++++----------------------------------- net/netfilter/ipvs/ip_vs_xmit.c | 7 +++++-- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index adcdba9dd183..0e4618470cee 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -25,7 +25,7 @@ #include #include /* for struct ipv6hdr */ #include /* for ipv6_addr_copy */ -#ifdef CONFIG_IP_VS_NFCT +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #include #endif @@ -1021,6 +1021,24 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) return csum_partial(diff, sizeof(diff), oldsum); } +/* + * Forget current conntrack (unconfirmed) and attach notrack entry + */ +static inline void ip_vs_notrack(struct sk_buff *skb) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (!ct || !nf_ct_is_untracked(ct)) { + nf_reset(skb); + skb->nfct = &nf_ct_untracked_get()->ct_general; + skb->nfctinfo = IP_CT_NEW; + nf_conntrack_get(skb->nfct); + } +#endif +} + #ifdef CONFIG_IP_VS_NFCT /* * Netfilter connection tracking diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index e5fef7aef0d4..222453029b9e 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -507,23 +507,6 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, return NF_DROP; } -/* - * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING - * chain and is used to avoid double NAT and confirmation when we do - * not want to keep the conntrack structure - */ -static unsigned int ip_vs_post_routing(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -{ - if (!skb->ipvs_property) - return NF_ACCEPT; - /* The packet was sent from IPVS, exit this chain */ - return NF_STOP; -} - __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) { return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); @@ -682,8 +665,9 @@ static int handle_response_icmp(int af, struct sk_buff *skb, /* do the statistics and put it back */ ip_vs_out_stats(cp, skb); + skb->ipvs_property = 1; if (!(cp->flags & IP_VS_CONN_F_NFCT)) - skb->ipvs_property = 1; + ip_vs_notrack(skb); else ip_vs_update_conntrack(skb, cp, 0); verdict = NF_ACCEPT; @@ -929,8 +913,9 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ip_vs_out_stats(cp, skb); ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); + skb->ipvs_property = 1; if (!(cp->flags & IP_VS_CONN_F_NFCT)) - skb->ipvs_property = 1; + ip_vs_notrack(skb); else ip_vs_update_conntrack(skb, cp, 0); ip_vs_conn_put(cp); @@ -1496,14 +1481,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, - /* Before the netfilter connection tracking, exit from POST_ROUTING */ - { - .hook = ip_vs_post_routing, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_INET_POST_ROUTING, - .priority = NF_IP_PRI_NAT_SRC-1, - }, #ifdef CONFIG_IP_VS_IPV6 /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be @@ -1532,14 +1509,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, - /* Before the netfilter connection tracking, exit from POST_ROUTING */ - { - .hook = ip_vs_post_routing, - .owner = THIS_MODULE, - .pf = PF_INET6, - .hooknum = NF_INET_POST_ROUTING, - .priority = NF_IP6_PRI_NAT_SRC-1, - }, #endif }; diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index b0bd8afbf368..94b53b441028 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -217,6 +217,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) ({ \ int __ret = NF_ACCEPT; \ \ + (skb)->ipvs_property = 1; \ if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \ __ret = ip_vs_confirm_conntrack(skb, cp); \ if (__ret == NF_ACCEPT) { \ @@ -228,8 +229,9 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) #define IP_VS_XMIT_NAT(pf, skb, cp) \ do { \ + (skb)->ipvs_property = 1; \ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ - (skb)->ipvs_property = 1; \ + ip_vs_notrack(skb); \ else \ ip_vs_update_conntrack(skb, cp, 1); \ skb_forward_csum(skb); \ @@ -239,8 +241,9 @@ do { \ #define IP_VS_XMIT(pf, skb, cp) \ do { \ + (skb)->ipvs_property = 1; \ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ - (skb)->ipvs_property = 1; \ + ip_vs_notrack(skb); \ skb_forward_csum(skb); \ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ skb_dst(skb)->dev, dst_output); \ -- cgit v1.2.3 From 190ecd27cd7294105e3b26ca71663c7d940acbbb Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:24:37 +0300 Subject: ipvs: do not schedule conns from real servers This patch is needed to avoid scheduling of packets from local real server when we add ip_vs_in in LOCAL_OUT hook to support local client. Currently, when ip_vs_in can not find existing connection it tries to create new one by calling ip_vs_schedule. The default indication from ip_vs_schedule was if connection was scheduled to real server. If real server is not available we try to use the bypass forwarding method or to send ICMP error. But in some cases we do not want to use the bypass feature. So, add flag 'ignored' to indicate if the scheduler ignores this packet. Make sure we do not create new connections from replies. We can hit this problem for persistent services and local real server when ip_vs_in is added to LOCAL_OUT hook to handle local clients. Also, make sure ip_vs_schedule ignores SYN packets for Active FTP DATA from local real server. The FTP DATA connection should be created on SYN+ACK from client to assign correct connection daddr. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 3 ++- net/netfilter/ipvs/ip_vs_core.c | 34 ++++++++++++++++++++++++++++++++-- net/netfilter/ipvs/ip_vs_proto_sctp.c | 6 ++++-- net/netfilter/ipvs/ip_vs_proto_tcp.c | 7 +++++-- net/netfilter/ipvs/ip_vs_proto_udp.c | 6 ++++-- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 0e4618470cee..9d5c1b965304 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -849,7 +849,8 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); extern struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb); +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, + struct ip_vs_protocol *pp, int *ignored); extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, struct ip_vs_protocol *pp); diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 222453029b9e..0090d6d25e95 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -342,7 +342,8 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * Protocols supported: TCP, UDP */ struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb) +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, + struct ip_vs_protocol *pp, int *ignored) { struct ip_vs_conn *cp = NULL; struct ip_vs_iphdr iph; @@ -350,16 +351,43 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb) __be16 _ports[2], *pptr; unsigned int flags; + *ignored = 1; ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); if (pptr == NULL) return NULL; + /* + * FTPDATA needs this check when using local real server. + * Never schedule Active FTPDATA connections from real server. + * For LVS-NAT they must be already created. For other methods + * with persistence the connection is created on SYN+ACK. + */ + if (pptr[0] == FTPDATA) { + IP_VS_DBG_PKT(12, pp, skb, 0, "Not scheduling FTPDATA"); + return NULL; + } + + /* + * Do not schedule replies from local real server. It is risky + * for fwmark services but mostly for persistent services. + */ + if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && + (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) && + (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) { + IP_VS_DBG_PKT(12, pp, skb, 0, + "Not scheduling reply for existing connection"); + __ip_vs_conn_put(cp); + return NULL; + } + /* * Persistent service */ - if (svc->flags & IP_VS_SVC_F_PERSISTENT) + if (svc->flags & IP_VS_SVC_F_PERSISTENT) { + *ignored = 0; return ip_vs_sched_persist(svc, skb, pptr); + } /* * Non-persistent service @@ -372,6 +400,8 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb) return NULL; } + *ignored = 0; + dest = svc->scheduler->schedule(svc, skb); if (dest == NULL) { IP_VS_DBG(1, "Schedule: no dest found.\n"); diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 4c0855cb006e..9ab5232ce019 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -31,6 +31,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, if ((sch->type == SCTP_CID_INIT) && (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, sh->dest))) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -44,8 +46,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 64dc2954cf78..85d80a66b492 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -43,9 +43,12 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, return 0; } + /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ if (th->syn && (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, th->dest))) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -60,8 +63,8 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 9c558c40bfbb..5d21f08155ed 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -46,6 +46,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, uh->dest); if (svc) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -60,8 +62,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } -- cgit v1.2.3 From 489fdedaed5ddb437dd2840eb93df37a6dd8c7de Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:27:31 +0300 Subject: ipvs: stop ICMP from FORWARD to local Delivering locally ICMP from FORWARD hook is not supported. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_core.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 0090d6d25e95..27ecb258ea70 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -48,6 +48,7 @@ #ifdef CONFIG_IP_VS_IPV6 #include #include +#include #endif #include @@ -1191,7 +1192,14 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) offset += 2 * sizeof(__u16); verdict = ip_vs_icmp_xmit(skb, cp, pp, offset); - /* do not touch skb anymore */ + /* LOCALNODE from FORWARD hook is not supported */ + if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD && + skb_rtable(skb)->rt_flags & RTCF_LOCAL) { + IP_VS_DBG(1, "%s(): " + "local delivery to %pI4 but in FORWARD\n", + __func__, &skb_rtable(skb)->rt_dst); + verdict = NF_DROP; + } out: __ip_vs_conn_put(cp); @@ -1212,6 +1220,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) struct ip_vs_protocol *pp; unsigned int offset, verdict; union nf_inet_addr snet; + struct rt6_info *rt; *related = 1; @@ -1290,7 +1299,15 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) IPPROTO_SCTP == cih->nexthdr) offset += 2 * sizeof(__u16); verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset); - /* do not touch skb anymore */ + /* LOCALNODE from FORWARD hook is not supported */ + if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD && + (rt = (struct rt6_info *) skb_dst(skb)) && + rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) { + IP_VS_DBG(1, "%s(): " + "local delivery to %pI6 but in FORWARD\n", + __func__, &rt->rt6i_dst); + verdict = NF_DROP; + } __ip_vs_conn_put(cp); -- cgit v1.2.3 From 4256f1aaa662697c1faa0984b7a698c2c8c57735 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:29:40 +0300 Subject: ipvs: fix CHECKSUM_PARTIAL for TUN method The recent change in IP_VS_XMIT_TUNNEL to set CHECKSUM_NONE is not correct. After adding IPIP header skb->csum becomes invalid but the CHECKSUM_PARTIAL case must be supported. So, use skb_forward_csum() which is most suitable for us to allow local clients to send IPIP to remote real server. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 94b53b441028..63cc0feaaef6 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -222,7 +222,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) __ret = ip_vs_confirm_conntrack(skb, cp); \ if (__ret == NF_ACCEPT) { \ nf_reset(skb); \ - (skb)->ip_summed = CHECKSUM_NONE; \ + skb_forward_csum(skb); \ } \ __ret; \ }) -- cgit v1.2.3 From 1ca5bb5450aa2401fa272efeb741ebb260d0fbb0 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:32:29 +0300 Subject: ipvs: create ip_vs_defrag_user Create new function ip_vs_defrag_user to return correct IP_DEFRAG_xxx user depending on the hooknum. It will be needed when we add handlers in LOCAL_OUT. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_core.c | 55 +++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 27ecb258ea70..f7f52831c4a6 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -543,6 +543,15 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); } +static inline enum ip_defrag_users ip_vs_defrag_user(unsigned int hooknum) +{ + if (NF_INET_LOCAL_IN == hooknum) + return IP_DEFRAG_VS_IN; + if (NF_INET_FORWARD == hooknum) + return IP_DEFRAG_VS_FWD; + return IP_DEFRAG_VS_OUT; +} + static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) { int err = ip_defrag(skb, user); @@ -714,7 +723,8 @@ out: * Find any that might be relevant, check against existing connections. * Currently handles error types - unreachable, quench, ttl exceeded. */ -static int ip_vs_out_icmp(struct sk_buff *skb, int *related) +static int ip_vs_out_icmp(struct sk_buff *skb, int *related, + unsigned int hooknum) { struct iphdr *iph; struct icmphdr _icmph, *ic; @@ -729,7 +739,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) /* reassemble IP fragments */ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { - if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -788,7 +798,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) } #ifdef CONFIG_IP_VS_IPV6 -static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) +static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, + unsigned int hooknum) { struct ipv6hdr *iph; struct icmp6hdr _icmph, *ic; @@ -804,7 +815,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) /* reassemble IP fragments */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { - if (ip_vs_gather_frags_v6(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -986,7 +997,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_out_icmp_v6(skb, &related); + int related; + int verdict = ip_vs_out_icmp_v6(skb, &related, + hooknum); if (related) { if (sysctl_ip_vs_snat_reroute && @@ -1000,7 +1013,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, } else #endif if (unlikely(iph.protocol == IPPROTO_ICMP)) { - int related, verdict = ip_vs_out_icmp(skb, &related); + int related; + int verdict = ip_vs_out_icmp(skb, &related, hooknum); if (related) { if (sysctl_ip_vs_snat_reroute && @@ -1019,19 +1033,19 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, /* reassemble IP fragments */ #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { - if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_out_icmp_v6(skb, &related); - - if (related) - return verdict; - - ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { + if (ip_vs_gather_frags_v6(skb, + ip_vs_defrag_user(hooknum))) + return NF_STOLEN; } + + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } else #endif if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) && !pp->dont_defrag)) { - if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags(skb, + ip_vs_defrag_user(hooknum))) return NF_STOLEN; ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); @@ -1114,8 +1128,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) /* reassemble IP fragments */ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { - if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ? - IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD)) + if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -1226,9 +1239,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) /* reassemble IP fragments */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { - if (ip_vs_gather_frags_v6(skb, hooknum == NF_INET_LOCAL_IN ? - IP_DEFRAG_VS_IN : - IP_DEFRAG_VS_FWD)) + if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -1349,7 +1360,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); + int related; + int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); if (related) return verdict; @@ -1358,7 +1370,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, } else #endif if (unlikely(iph.protocol == IPPROTO_ICMP)) { - int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); + int related; + int verdict = ip_vs_in_icmp(skb, &related, hooknum); if (related) return verdict; -- cgit v1.2.3 From f5a41847acc535e2e2018e397b1876ba7577d9d9 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:35:46 +0300 Subject: ipvs: move ip_route_me_harder for ICMP Currently, ip_route_me_harder after ip_vs_out_icmp is called even if packet is not related to IPVS connection. Move it into handle_response_icmp. Also, force rerouting if sending to local client because IPv4 stack uses addresses from the route. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_core.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index f7f52831c4a6..c4f091d5a628 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -702,6 +702,17 @@ static int handle_response_icmp(int af, struct sk_buff *skb, #endif ip_vs_nat_icmp(skb, pp, cp, 1); +#ifdef CONFIG_IP_VS_IPV6 + if (af == AF_INET6) { + if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) + goto out; + } else +#endif + if ((sysctl_ip_vs_snat_reroute || + skb_rtable(skb)->rt_flags & RTCF_LOCAL) && + ip_route_me_harder(skb, RTN_LOCAL) != 0) + goto out; + /* do the statistics and put it back */ ip_vs_out_stats(cp, skb); @@ -940,16 +951,16 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * if it came from this machine itself. So re-compute * the routing information. */ - if (sysctl_ip_vs_snat_reroute) { #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) { - if (ip6_route_me_harder(skb) != 0) - goto drop; - } else + if (af == AF_INET6) { + if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) + goto drop; + } else #endif - if (ip_route_me_harder(skb, RTN_LOCAL) != 0) - goto drop; - } + if ((sysctl_ip_vs_snat_reroute || + skb_rtable(skb)->rt_flags & RTCF_LOCAL) && + ip_route_me_harder(skb, RTN_LOCAL) != 0) + goto drop; IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT"); @@ -1001,13 +1012,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int verdict = ip_vs_out_icmp_v6(skb, &related, hooknum); - if (related) { - if (sysctl_ip_vs_snat_reroute && - NF_ACCEPT == verdict && - ip6_route_me_harder(skb)) - verdict = NF_DROP; + if (related) return verdict; - } ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } } else @@ -1016,13 +1022,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int related; int verdict = ip_vs_out_icmp(skb, &related, hooknum); - if (related) { - if (sysctl_ip_vs_snat_reroute && - NF_ACCEPT == verdict && - ip_route_me_harder(skb, RTN_LOCAL)) - verdict = NF_DROP; + if (related) return verdict; - } ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } -- cgit v1.2.3 From fc604767613b6d2036cdc35b660bc39451040a47 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:38:15 +0300 Subject: ipvs: changes for local real server This patch deals with local real servers: - Add support for DNAT to local address (different real server port). It needs ip_vs_out hook in LOCAL_OUT for both families because skb->protocol is not set for locally generated packets and can not be used to set 'af'. - Skip packets in ip_vs_in marked with skb->ipvs_property because ip_vs_out processing can be executed in LOCAL_OUT but we still have the conn_out_get check in ip_vs_in. - Ignore packets with inet->nodefrag from local stack - Require skb_dst(skb) != NULL because we use it to get struct net - Add support for changing the route to local IPv4 stack after DNAT depending on the source address type. Local client sets output route and the remote client sets input route. It looks like IPv6 does not need such rerouting because the replies use addresses from initial incoming header, not from skb route. - All transmitters now have strict checks for the destination address type: redirect from non-local address to local real server requires NAT method, local address can not be used as source address when talking to remote real server. - Now LOCALNODE is not set explicitly as forwarding method in real server to allow the connections to provide correct forwarding method to the backup server. Not sure if this breaks tools that expect to see 'Local' real server type. If needed, this can be supported with new flag IP_VS_DEST_F_LOCAL. Now it should be possible connections in backup that lost their fwmark information during sync to be forwarded properly to their daddr, even if it is local address in the backup server. By this way backup could be used as real server for DR or TUN, for NAT there are some restrictions because tuple collisions in conntracks can create problems for the traffic. - Call ip_vs_dst_reset when destination is updated in case some real server IP type is changed between local and remote. [ horms@verge.net.au: removed trailing whitespace ] Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_core.c | 123 ++++++++++-- net/netfilter/ipvs/ip_vs_ctl.c | 18 +- net/netfilter/ipvs/ip_vs_xmit.c | 433 ++++++++++++++++++++++++++++++++-------- 4 files changed, 458 insertions(+), 117 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 9d5c1b965304..2f88d5942332 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -409,6 +409,7 @@ struct ip_vs_conn { /* packet transmitter for different forwarding methods. If it mangles the packet, it must return NF_DROP or better NF_STOLEN, otherwise this must be changed to a sk_buff **. + NF_ACCEPT can be returned when destination is local. */ int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index c4f091d5a628..a6c8aff1b47e 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -984,26 +984,34 @@ drop: } /* - * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. * Check if outgoing packet belongs to the established ip_vs_conn. */ static unsigned int -ip_vs_out(unsigned int hooknum, struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - int (*okfn)(struct sk_buff *)) +ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) { struct ip_vs_iphdr iph; struct ip_vs_protocol *pp; struct ip_vs_conn *cp; - int af; EnterFunction(11); - af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; - + /* Already marked as IPVS request or reply? */ if (skb->ipvs_property) return NF_ACCEPT; + /* Bad... Do not break raw sockets */ + if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && + af == AF_INET)) { + struct sock *sk = skb->sk; + struct inet_sock *inet = inet_sk(skb->sk); + + if (inet && sk->sk_family == PF_INET && inet->nodefrag) + return NF_ACCEPT; + } + + if (unlikely(!skb_dst(skb))) + return NF_ACCEPT; + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { @@ -1106,6 +1114,69 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, return handle_response(af, skb, pp, cp, iph.len); } +/* + * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_reply4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_out(hooknum, skb, AF_INET); +} + +/* + * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_local_reply4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_out(hooknum, skb, AF_INET); + local_bh_enable(); + return verdict; +} + +#ifdef CONFIG_IP_VS_IPV6 + +/* + * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_reply6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_out(hooknum, skb, AF_INET6); +} + +/* + * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_local_reply6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_out(hooknum, skb, AF_INET6); + local_bh_enable(); + return verdict; +} + +#endif /* * Handle ICMP messages in the outside-to-inside direction (incoming). @@ -1342,6 +1413,10 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, struct ip_vs_conn *cp; int ret, restart, af, pkts; + /* Already marked as IPVS request or reply? */ + if (skb->ipvs_property) + return NF_ACCEPT; + af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); @@ -1525,13 +1600,13 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_IN, .priority = 100, }, - /* After packet filtering, change source only for VS/NAT */ + /* Before ip_vs_in, change source only for VS/NAT */ { - .hook = ip_vs_out, + .hook = ip_vs_local_reply4, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_FORWARD, - .priority = 100, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -99, }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ @@ -1542,6 +1617,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_FORWARD, + .priority = 100, + }, #ifdef CONFIG_IP_VS_IPV6 /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be @@ -1553,13 +1636,13 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_IN, .priority = 100, }, - /* After packet filtering, change source only for VS/NAT */ + /* Before ip_vs_in, change source only for VS/NAT */ { - .hook = ip_vs_out, + .hook = ip_vs_local_reply6, .owner = THIS_MODULE, - .pf = PF_INET6, - .hooknum = NF_INET_FORWARD, - .priority = 100, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -99, }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ @@ -1570,6 +1653,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply6, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_FORWARD, + .priority = 100, + }, #endif }; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 0b884d3e192f..5f5daa30b0af 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -777,20 +777,6 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK; conn_flags |= IP_VS_CONN_F_INACTIVE; - /* check if local node and update the flags */ -#ifdef CONFIG_IP_VS_IPV6 - if (svc->af == AF_INET6) { - if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) { - conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) - | IP_VS_CONN_F_LOCALNODE; - } - } else -#endif - if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) { - conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) - | IP_VS_CONN_F_LOCALNODE; - } - /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */ if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) { conn_flags |= IP_VS_CONN_F_NOOUTPUT; @@ -824,6 +810,10 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, dest->u_threshold = udest->u_threshold; dest->l_threshold = udest->l_threshold; + spin_lock(&dest->dst_lock); + ip_vs_dst_reset(dest); + spin_unlock(&dest->dst_lock); + if (add) ip_vs_new_estimator(&dest->stats); diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 63cc0feaaef6..8608882f89e3 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -67,12 +67,19 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) return dst; } +/* + * Get route to destination or remote server + * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest, + * &4=Allow redirect from remote daddr to local + */ static struct rtable * -__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_conn *cp, u32 rtos) +__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, + __be32 daddr, u32 rtos, int rt_mode) { - struct net *net = dev_net(skb->dev); + struct net *net = dev_net(skb_dst(skb)->dev); struct rtable *rt; /* Route to the other host */ - struct ip_vs_dest *dest = cp->dest; + struct rtable *ort; /* Original route */ + int local; if (dest) { spin_lock(&dest->dst_lock); @@ -104,23 +111,95 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_conn *cp, u32 rtos) .oif = 0, .nl_u = { .ip4_u = { - .daddr = cp->daddr.ip, + .daddr = daddr, .saddr = 0, .tos = rtos, } }, }; if (ip_route_output_key(net, &rt, &fl)) { IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", - &cp->daddr.ip); + &daddr); return NULL; } } + local = rt->rt_flags & RTCF_LOCAL; + if (!((local ? 1 : 2) & rt_mode)) { + IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n", + (rt->rt_flags & RTCF_LOCAL) ? + "local":"non-local", &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + if (local && !(rt_mode & 4) && !((ort = skb_rtable(skb)) && + ort->rt_flags & RTCF_LOCAL)) { + IP_VS_DBG_RL("Redirect from non-local address %pI4 to local " + "requires NAT method, dest: %pI4\n", + &ip_hdr(skb)->daddr, &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + if (unlikely(!local && ipv4_is_loopback(ip_hdr(skb)->saddr))) { + IP_VS_DBG_RL("Stopping traffic from loopback address %pI4 " + "to non-local address, dest: %pI4\n", + &ip_hdr(skb)->saddr, &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + return rt; } +/* Reroute packet to local IPv4 stack after DNAT */ +static int +__ip_vs_reroute_locally(struct sk_buff *skb) +{ + struct rtable *rt = skb_rtable(skb); + struct net_device *dev = rt->dst.dev; + struct net *net = dev_net(dev); + struct iphdr *iph = ip_hdr(skb); + + if (rt->fl.iif) { + unsigned long orefdst = skb->_skb_refdst; + + if (ip_route_input(skb, iph->daddr, iph->saddr, + iph->tos, skb->dev)) + return 0; + refdst_drop(orefdst); + } else { + struct flowi fl = { + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos), + } + }, + .mark = skb->mark, + }; + struct rtable *rt; + + if (ip_route_output_key(net, &rt, &fl)) + return 0; + if (!(rt->rt_flags & RTCF_LOCAL)) { + ip_rt_put(rt); + return 0; + } + /* Drop old route. */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } + return 1; +} + #ifdef CONFIG_IP_VS_IPV6 +static inline int __ip_vs_is_local_route6(struct rt6_info *rt) +{ + return rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK; +} + static struct dst_entry * __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, struct in6_addr *ret_saddr, int do_xfrm) @@ -155,14 +234,21 @@ out_err: return NULL; } +/* + * Get route to destination or remote server + * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest, + * &4=Allow redirect from remote daddr to local + */ static struct rt6_info * -__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_conn *cp, - struct in6_addr *ret_saddr, int do_xfrm) +__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, + struct in6_addr *daddr, struct in6_addr *ret_saddr, + int do_xfrm, int rt_mode) { - struct net *net = dev_net(skb->dev); + struct net *net = dev_net(skb_dst(skb)->dev); struct rt6_info *rt; /* Route to the other host */ - struct ip_vs_dest *dest = cp->dest; + struct rt6_info *ort; /* Original route */ struct dst_entry *dst; + int local; if (dest) { spin_lock(&dest->dst_lock); @@ -188,13 +274,38 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_conn *cp, ipv6_addr_copy(ret_saddr, &dest->dst_saddr); spin_unlock(&dest->dst_lock); } else { - dst = __ip_vs_route_output_v6(net, &cp->daddr.in6, ret_saddr, - do_xfrm); + dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm); if (!dst) return NULL; rt = (struct rt6_info *) dst; } + local = __ip_vs_is_local_route6(rt); + if (!((local ? 1 : 2) & rt_mode)) { + IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n", + local ? "local":"non-local", daddr); + dst_release(&rt->dst); + return NULL; + } + if (local && !(rt_mode & 4) && + !((ort = (struct rt6_info *) skb_dst(skb)) && + __ip_vs_is_local_route6(ort))) { + IP_VS_DBG_RL("Redirect from non-local address %pI6 to local " + "requires NAT method, dest: %pI6\n", + &ipv6_hdr(skb)->daddr, daddr); + dst_release(&rt->dst); + return NULL; + } + if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&ipv6_hdr(skb)->saddr) & + IPV6_ADDR_LOOPBACK)) { + IP_VS_DBG_RL("Stopping traffic from loopback address %pI6 " + "to non-local address, dest: %pI6\n", + &ipv6_hdr(skb)->saddr, daddr); + dst_release(&rt->dst); + return NULL; + } + return rt; } #endif @@ -227,23 +338,27 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) __ret; \ }) -#define IP_VS_XMIT_NAT(pf, skb, cp) \ +#define IP_VS_XMIT_NAT(pf, skb, cp, local) \ do { \ (skb)->ipvs_property = 1; \ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ ip_vs_notrack(skb); \ else \ ip_vs_update_conntrack(skb, cp, 1); \ + if (local) \ + return NF_ACCEPT; \ skb_forward_csum(skb); \ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ skb_dst(skb)->dev, dst_output); \ } while (0) -#define IP_VS_XMIT(pf, skb, cp) \ +#define IP_VS_XMIT(pf, skb, cp, local) \ do { \ (skb)->ipvs_property = 1; \ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ ip_vs_notrack(skb); \ + if (local) \ + return NF_ACCEPT; \ skb_forward_csum(skb); \ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ skb_dst(skb)->dev, dst_output); \ @@ -258,7 +373,7 @@ ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { /* we do not touch skb and do not need pskb ptr */ - return NF_ACCEPT; + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); } @@ -271,27 +386,15 @@ int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { - struct net *net = dev_net(skb->dev); struct rtable *rt; /* Route to the other host */ struct iphdr *iph = ip_hdr(skb); - u8 tos = iph->tos; int mtu; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = 0, - .tos = RT_TOS(tos), } }, - }; EnterFunction(10); - if (ip_route_output_key(net, &rt, &fl)) { - IP_VS_DBG_RL("%s(): ip_route_output error, dest: %pI4\n", - __func__, &iph->daddr); + if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, + RT_TOS(iph->tos), 2))) goto tx_error_icmp; - } /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -319,7 +422,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, cp); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -337,18 +440,14 @@ int ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { - struct net *net = dev_net(skb->dev); - struct dst_entry *dst; struct rt6_info *rt; /* Route to the other host */ struct ipv6hdr *iph = ipv6_hdr(skb); int mtu; EnterFunction(10); - dst = __ip_vs_route_output_v6(net, &iph->daddr, NULL, 0); - if (!dst) + if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, 2))) goto tx_error_icmp; - rt = (struct rt6_info *) dst; /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -376,7 +475,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, cp); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -401,6 +500,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct rtable *rt; /* Route to the other host */ int mtu; struct iphdr *iph = ip_hdr(skb); + int local; EnterFunction(10); @@ -414,16 +514,40 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(iph->tos), 1|2|4))) goto tx_error_icmp; + local = rt->rt_flags & RTCF_LOCAL; + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG_RL_PKT(10, pp, skb, 0, "ip_vs_nat_xmit(): " + "stopping DNAT to local address"); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + IP_VS_DBG_RL_PKT(1, pp, skb, 0, "ip_vs_nat_xmit(): " + "stopping DNAT to loopback address"); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) { - ip_rt_put(rt); icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for"); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -433,16 +557,27 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) - goto tx_error; + goto tx_error_put; ip_hdr(skb)->daddr = cp->daddr.ip; ip_send_check(ip_hdr(skb)); + if (!local) { + /* drop old route */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + ip_rt_put(rt); + /* + * Some IPv4 replies get local address from routes, + * not from iph, so while we DNAT after routing + * we need this second input/output route. + */ + if (!__ip_vs_reroute_locally(skb)) + goto tx_error; + } + IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); /* FIXME: when application helper enlarges the packet and the length @@ -452,7 +587,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp); + IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local); LeaveFunction(10); return NF_STOLEN; @@ -475,6 +610,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, { struct rt6_info *rt; /* Route to the other host */ int mtu; + int local; EnterFunction(10); @@ -489,18 +625,44 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2|4))) goto tx_error_icmp; + local = __ip_vs_is_local_route6(rt); + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG_RL_PKT(10, pp, skb, 0, + "ip_vs_nat_xmit_v6(): " + "stopping DNAT to local address"); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { + IP_VS_DBG_RL_PKT(1, pp, skb, 0, + "ip_vs_nat_xmit_v6(): " + "stopping DNAT to loopback address"); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit_v6(): frag needed for"); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -510,14 +672,19 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) goto tx_error; - ipv6_hdr(skb)->daddr = cp->daddr.in6; + ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &cp->daddr.in6); + + if (!local || !skb->dev) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + /* destined to loopback, do we need to change route? */ + dst_release(&rt->dst); + } IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); @@ -528,7 +695,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp); + IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local); LeaveFunction(10); return NF_STOLEN; @@ -588,16 +755,20 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error; } - if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(tos), 1|2))) goto tx_error_icmp; + if (rt->rt_flags & RTCF_LOCAL) { + ip_rt_put(rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); + } tdev = rt->dst.dev; mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - ip_rt_put(rt); IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__); - goto tx_error; + goto tx_error_put; } if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); @@ -607,9 +778,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if ((old_iph->frag_off & htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); - ip_rt_put(rt); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* @@ -678,6 +848,9 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, kfree_skb(skb); LeaveFunction(10); return NF_STOLEN; +tx_error_put: + ip_rt_put(rt); + goto tx_error; } #ifdef CONFIG_IP_VS_IPV6 @@ -703,27 +876,29 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error; } - rt = __ip_vs_get_out_rt_v6(skb, cp, &saddr, 1); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, + &saddr, 1, 1|2))) goto tx_error_icmp; + if (__ip_vs_is_local_route6(rt)) { + dst_release(&rt->dst); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1); + } tdev = rt->dst.dev; mtu = dst_mtu(&rt->dst) - sizeof(struct ipv6hdr); if (mtu < IPV6_MIN_MTU) { - dst_release(&rt->dst); IP_VS_DBG_RL("%s(): mtu less than %d\n", __func__, IPV6_MIN_MTU); - goto tx_error; + goto tx_error_put; } if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) { icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); - dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* @@ -789,6 +964,9 @@ tx_error: kfree_skb(skb); LeaveFunction(10); return NF_STOLEN; +tx_error_put: + dst_release(&rt->dst); + goto tx_error; } #endif @@ -807,8 +985,13 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(iph->tos), 1|2))) goto tx_error_icmp; + if (rt->rt_flags & RTCF_LOCAL) { + ip_rt_put(rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); + } /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -836,7 +1019,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, cp); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -859,9 +1042,13 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2))) goto tx_error_icmp; + if (__ip_vs_is_local_route6(rt)) { + dst_release(&rt->dst); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1); + } /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -889,7 +1076,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, cp); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -915,6 +1102,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct rtable *rt; /* Route to the other host */ int mtu; int rc; + int local; EnterFunction(10); @@ -935,16 +1123,43 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - if (!(rt = __ip_vs_get_out_rt(skb, cp, RT_TOS(ip_hdr(skb)->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(ip_hdr(skb)->tos), 1|2|4))) goto tx_error_icmp; + local = rt->rt_flags & RTCF_LOCAL; + + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG(10, "%s(): " + "stopping DNAT to local address %pI4\n", + __func__, &cp->daddr.ip); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + IP_VS_DBG(1, "%s(): " + "stopping DNAT to loopback %pI4\n", + __func__, &cp->daddr.ip); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF))) { - ip_rt_put(rt); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -954,16 +1169,27 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - ip_vs_nat_icmp(skb, pp, cp, 0); + if (!local) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + ip_rt_put(rt); + /* + * Some IPv4 replies get local address from routes, + * not from iph, so while we DNAT after routing + * we need this second input/output route. + */ + if (!__ip_vs_reroute_locally(skb)) + goto tx_error; + } + /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, cp); + IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local); rc = NF_STOLEN; goto out; @@ -989,6 +1215,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct rt6_info *rt; /* Route to the other host */ int mtu; int rc; + int local; EnterFunction(10); @@ -1009,17 +1236,44 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - rt = __ip_vs_get_out_rt_v6(skb, cp, NULL, 0); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2|4))) goto tx_error_icmp; + local = __ip_vs_is_local_route6(rt); + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG(10, "%s(): " + "stopping DNAT to local address %pI6\n", + __func__, &cp->daddr.in6); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { + IP_VS_DBG(1, "%s(): " + "stopping DNAT to loopback %pI6\n", + __func__, &cp->daddr.in6); + goto tx_error_put; + } + /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -1029,16 +1283,21 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - ip_vs_nat_icmp_v6(skb, pp, cp, 0); + if (!local || !skb->dev) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + /* destined to loopback, do we need to change route? */ + dst_release(&rt->dst); + } + /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, cp); + IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local); rc = NF_STOLEN; goto out; -- cgit v1.2.3 From cb59155f21d4c0507d2034c2953f6a3f7806913d Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:40:51 +0300 Subject: ipvs: changes for local client This patch deals with local client processing. Prefer LOCAL_OUT hook for scheduling connections from local clients. LOCAL_IN is still supported if the packets are not marked as processed in LOCAL_OUT. The idea to process requests in LOCAL_OUT is to alter conntrack reply before it is confirmed at POST_ROUTING. If the local requests are processed in LOCAL_IN the conntrack can not be updated and matching by state is impossible. Add the following handlers: - ip_vs_reply[46] at LOCAL_IN:99 to process replies from remote real servers to local clients. Now when both replies from remote real servers (ip_vs_reply*) and local real servers (ip_vs_local_reply*) are handled it is safe to remove the conn_out_get call from ip_vs_in because it does not support related ICMP packets. - ip_vs_local_request[46] at LOCAL_OUT:-98 to process requests from local client Handling in LOCAL_OUT causes some changes: - as skb->dev, skb->protocol and skb->pkt_type are not defined in LOCAL_OUT make sure we set skb->dev before calling icmpv6_send, prefer skb_dst(skb) for struct net and remove the skb->protocol checks from TUN transmitters. [ horms@verge.net.au: removed trailing whitespace ] Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_core.c | 266 ++++++++++++++++++++++++++++------------ net/netfilter/ipvs/ip_vs_xmit.c | 51 +++++--- 2 files changed, 225 insertions(+), 92 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index a6c8aff1b47e..5fbcf67af8ec 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -529,9 +529,14 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, * ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ */ #ifdef CONFIG_IP_VS_IPV6 - if (svc->af == AF_INET6) + if (svc->af == AF_INET6) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); - else + } else #endif icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -1065,57 +1070,61 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) */ cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0); - if (unlikely(!cp)) { - if (sysctl_ip_vs_nat_icmp_send && - (pp->protocol == IPPROTO_TCP || - pp->protocol == IPPROTO_UDP || - pp->protocol == IPPROTO_SCTP)) { - __be16 _ports[2], *pptr; - - pptr = skb_header_pointer(skb, iph.len, - sizeof(_ports), _ports); - if (pptr == NULL) - return NF_ACCEPT; /* Not for me */ - if (ip_vs_lookup_real_service(af, iph.protocol, - &iph.saddr, - pptr[0])) { - /* - * Notify the real server: there is no - * existing entry if it is not RST - * packet or not TCP packet. - */ - if ((iph.protocol != IPPROTO_TCP && - iph.protocol != IPPROTO_SCTP) - || ((iph.protocol == IPPROTO_TCP - && !is_tcp_reset(skb, iph.len)) - || (iph.protocol == IPPROTO_SCTP - && !is_sctp_abort(skb, - iph.len)))) { + if (likely(cp)) + return handle_response(af, skb, pp, cp, iph.len); + if (sysctl_ip_vs_nat_icmp_send && + (pp->protocol == IPPROTO_TCP || + pp->protocol == IPPROTO_UDP || + pp->protocol == IPPROTO_SCTP)) { + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, iph.len, + sizeof(_ports), _ports); + if (pptr == NULL) + return NF_ACCEPT; /* Not for me */ + if (ip_vs_lookup_real_service(af, iph.protocol, + &iph.saddr, + pptr[0])) { + /* + * Notify the real server: there is no + * existing entry if it is not RST + * packet or not TCP packet. + */ + if ((iph.protocol != IPPROTO_TCP && + iph.protocol != IPPROTO_SCTP) + || ((iph.protocol == IPPROTO_TCP + && !is_tcp_reset(skb, iph.len)) + || (iph.protocol == IPPROTO_SCTP + && !is_sctp_abort(skb, + iph.len)))) { #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) - icmpv6_send(skb, - ICMPV6_DEST_UNREACH, - ICMPV6_PORT_UNREACH, - 0); - else + if (af == AF_INET6) { + struct net *net = + dev_net(skb_dst(skb)->dev); + + if (!skb->dev) + skb->dev = net->loopback_dev; + icmpv6_send(skb, + ICMPV6_DEST_UNREACH, + ICMPV6_PORT_UNREACH, + 0); + } else #endif - icmp_send(skb, - ICMP_DEST_UNREACH, - ICMP_PORT_UNREACH, 0); - return NF_DROP; - } + icmp_send(skb, + ICMP_DEST_UNREACH, + ICMP_PORT_UNREACH, 0); + return NF_DROP; } } - IP_VS_DBG_PKT(12, pp, skb, 0, - "packet continues traversal as normal"); - return NF_ACCEPT; } - - return handle_response(af, skb, pp, cp, iph.len); + IP_VS_DBG_PKT(12, pp, skb, 0, + "ip_vs_out: packet continues traversal as normal"); + return NF_ACCEPT; } /* - * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. + * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain, + * used only for VS/NAT. * Check if packet is reply for established ip_vs_conn. */ static unsigned int @@ -1147,7 +1156,8 @@ ip_vs_local_reply4(unsigned int hooknum, struct sk_buff *skb, #ifdef CONFIG_IP_VS_IPV6 /* - * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. + * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain, + * used only for VS/NAT. * Check if packet is reply for established ip_vs_conn. */ static unsigned int @@ -1404,34 +1414,43 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) * and send it on its way... */ static unsigned int -ip_vs_in(unsigned int hooknum, struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - int (*okfn)(struct sk_buff *)) +ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) { struct ip_vs_iphdr iph; struct ip_vs_protocol *pp; struct ip_vs_conn *cp; - int ret, restart, af, pkts; + int ret, restart, pkts; /* Already marked as IPVS request or reply? */ if (skb->ipvs_property) return NF_ACCEPT; - af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; - - ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); - /* - * Big tappo: only PACKET_HOST, including loopback for local client - * Don't handle local packets on IPv6 for now + * Big tappo: + * - remote client: only PACKET_HOST + * - route: used for struct net when skb->dev is unset */ - if (unlikely(skb->pkt_type != PACKET_HOST)) { - IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s ignored\n", - skb->pkt_type, - iph.protocol, - IP_VS_DBG_ADDR(af, &iph.daddr)); + if (unlikely((skb->pkt_type != PACKET_HOST && + hooknum != NF_INET_LOCAL_OUT) || + !skb_dst(skb))) { + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s" + " ignored in hook %u\n", + skb->pkt_type, iph.protocol, + IP_VS_DBG_ADDR(af, &iph.daddr), hooknum); return NF_ACCEPT; } + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + + /* Bad... Do not break raw sockets */ + if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && + af == AF_INET)) { + struct sock *sk = skb->sk; + struct inet_sock *inet = inet_sk(skb->sk); + + if (inet && sk->sk_family == PF_INET && inet->nodefrag) + return NF_ACCEPT; + } #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { @@ -1467,11 +1486,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, if (unlikely(!cp)) { int v; - /* For local client packets, it could be a response */ - cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0); - if (cp) - return handle_response(af, skb, pp, cp, iph.len); - if (!pp->conn_schedule(af, skb, pp, &v, &cp)) return v; } @@ -1479,7 +1493,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, if (unlikely(!cp)) { /* sorry, all this trouble for a no-hit :) */ IP_VS_DBG_PKT(12, pp, skb, 0, - "packet continues traversal as normal"); + "ip_vs_in: packet continues traversal as normal"); return NF_ACCEPT; } @@ -1550,6 +1564,72 @@ out: return ret; } +/* + * AF_INET handler in NF_INET_LOCAL_IN chain + * Schedule and forward packets from remote clients + */ +static unsigned int +ip_vs_remote_request4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_in(hooknum, skb, AF_INET); +} + +/* + * AF_INET handler in NF_INET_LOCAL_OUT chain + * Schedule and forward packets from local clients + */ +static unsigned int +ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_in(hooknum, skb, AF_INET); + local_bh_enable(); + return verdict; +} + +#ifdef CONFIG_IP_VS_IPV6 + +/* + * AF_INET6 handler in NF_INET_LOCAL_IN chain + * Schedule and forward packets from remote clients + */ +static unsigned int +ip_vs_remote_request6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_in(hooknum, skb, AF_INET6); +} + +/* + * AF_INET6 handler in NF_INET_LOCAL_OUT chain + * Schedule and forward packets from local clients + */ +static unsigned int +ip_vs_local_request6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_in(hooknum, skb, AF_INET6); + local_bh_enable(); + return verdict; +} + +#endif + /* * It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP @@ -1590,15 +1670,23 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, static struct nf_hook_ops ip_vs_ops[] __read_mostly = { + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_IN, + .priority = 99, + }, /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be * applied to IPVS. */ { - .hook = ip_vs_in, + .hook = ip_vs_remote_request4, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_LOCAL_IN, - .priority = 100, + .hooknum = NF_INET_LOCAL_IN, + .priority = 101, }, /* Before ip_vs_in, change source only for VS/NAT */ { @@ -1608,14 +1696,22 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = -99, }, + /* After mangle, schedule and forward local requests */ + { + .hook = ip_vs_local_request4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -98, + }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ { .hook = ip_vs_forward_icmp, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_FORWARD, - .priority = 99, + .hooknum = NF_INET_FORWARD, + .priority = 99, }, /* After packet filtering, change source only for VS/NAT */ { @@ -1626,15 +1722,23 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .priority = 100, }, #ifdef CONFIG_IP_VS_IPV6 + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply6, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_LOCAL_IN, + .priority = 99, + }, /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be * applied to IPVS. */ { - .hook = ip_vs_in, + .hook = ip_vs_remote_request6, .owner = THIS_MODULE, .pf = PF_INET6, - .hooknum = NF_INET_LOCAL_IN, - .priority = 100, + .hooknum = NF_INET_LOCAL_IN, + .priority = 101, }, /* Before ip_vs_in, change source only for VS/NAT */ { @@ -1644,14 +1748,22 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = -99, }, + /* After mangle, schedule and forward local requests */ + { + .hook = ip_vs_local_request6, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -98, + }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ { .hook = ip_vs_forward_icmp_v6, .owner = THIS_MODULE, .pf = PF_INET6, - .hooknum = NF_INET_FORWARD, - .priority = 99, + .hooknum = NF_INET_FORWARD, + .priority = 99, }, /* After packet filtering, change source only for VS/NAT */ { diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 8608882f89e3..97b5361c036e 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -11,6 +11,16 @@ * * Changes: * + * Description of forwarding methods: + * - all transmitters are called from LOCAL_IN (remote clients) and + * LOCAL_OUT (local clients) but for ICMP can be called from FORWARD + * - not all connections have destination server, for example, + * connections in backup server when fwmark is used + * - bypass connections use daddr from packet + * LOCAL_OUT rules: + * - skb->dev is NULL, skb->protocol is not set (both are set in POST_ROUTING) + * - skb->pkt_type is not set yet + * - the only place where we can see skb->sk != NULL */ #define KMSG_COMPONENT "IPVS" @@ -452,8 +462,13 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; } @@ -659,6 +674,11 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit_v6(): frag needed for"); @@ -748,13 +768,6 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (skb->protocol != htons(ETH_P_IP)) { - IP_VS_DBG_RL("%s(): protocol error, " - "ETH_P_IP: %d, skb protocol: %d\n", - __func__, htons(ETH_P_IP), skb->protocol); - goto tx_error; - } - if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, RT_TOS(tos), 1|2))) goto tx_error_icmp; @@ -869,13 +882,6 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (skb->protocol != htons(ETH_P_IPV6)) { - IP_VS_DBG_RL("%s(): protocol error, " - "ETH_P_IPV6: %d, skb protocol: %d\n", - __func__, htons(ETH_P_IPV6), skb->protocol); - goto tx_error; - } - if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, &saddr, 1, 1|2))) goto tx_error_icmp; @@ -896,6 +902,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error_put; @@ -1053,6 +1064,11 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); @@ -1271,6 +1287,11 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error_put; -- cgit v1.2.3 From 3233759be7eeca9998c514b8f49e8cf2b85e64d3 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:43:36 +0300 Subject: ipvs: inherit forwarding method in backup Connections in backup server should inherit the forwarding method from real server. It is a way to fix a problem where the forwarding method in backup connection is damaged by logical OR operation with the real server's connection flags. And the change is needed for setups where the backup server uses different forwarding method for the same real servers. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_conn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 1d1a529dbe24..e9adecdc8ca4 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -563,6 +563,8 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) */ if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) conn_flags &= ~IP_VS_CONN_F_INACTIVE; + /* connections inherit forwarding method from dest */ + cp->flags &= ~IP_VS_CONN_F_FWD_MASK; } cp->flags |= conn_flags; cp->dest = dest; -- cgit v1.2.3 From 0d79641a96d612aaa6d57a4d4f521d7ed9c9ccdd Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 17 Oct 2010 16:46:17 +0300 Subject: ipvs: provide address family for debugging As skb->protocol is not valid in LOCAL_OUT add parameter for address family in packet debugging functions. Even if ports are not present in AH and ESP change them to use ip_vs_tcpudp_debug_packet to show at least valid addresses as before. This patch removes the last user of skb->protocol in IPVS. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- include/net/ip_vs.h | 17 ++++++----- net/netfilter/ipvs/ip_vs_core.c | 41 +++++++++++++++----------- net/netfilter/ipvs/ip_vs_proto.c | 8 ++--- net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 52 ++------------------------------- net/netfilter/ipvs/ip_vs_proto_sctp.c | 2 +- net/netfilter/ipvs/ip_vs_proto_tcp.c | 4 +-- net/netfilter/ipvs/ip_vs_proto_udp.c | 4 +-- net/netfilter/ipvs/ip_vs_xmit.c | 18 +++++++----- 8 files changed, 54 insertions(+), 92 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 2f88d5942332..b7bbd6c28cfa 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -136,24 +136,24 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len, if (net_ratelimit()) \ printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ } while (0) -#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) \ +#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level()) \ - pp->debug_packet(pp, skb, ofs, msg); \ + pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0) -#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) \ +#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level() && \ net_ratelimit()) \ - pp->debug_packet(pp, skb, ofs, msg); \ + pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0) #else /* NO DEBUGGING at ALL */ #define IP_VS_DBG_BUF(level, msg...) do {} while (0) #define IP_VS_ERR_BUF(msg...) do {} while (0) #define IP_VS_DBG(level, msg...) do {} while (0) #define IP_VS_DBG_RL(msg...) do {} while (0) -#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0) -#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) do {} while (0) +#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) do {} while (0) +#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) do {} while (0) #endif #define IP_VS_BUG() BUG() @@ -345,7 +345,7 @@ struct ip_vs_protocol { int (*app_conn_bind)(struct ip_vs_conn *cp); - void (*debug_packet)(struct ip_vs_protocol *pp, + void (*debug_packet)(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg); @@ -828,7 +828,8 @@ extern int ip_vs_set_state_timeout(int *table, int num, const char *const *names, const char *name, int to); extern void -ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, +ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, + const struct sk_buff *skb, int offset, const char *msg); extern struct ip_vs_protocol ip_vs_protocol_tcp; diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 5fbcf67af8ec..b4e51e9c5a04 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -365,7 +365,8 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, * with persistence the connection is created on SYN+ACK. */ if (pptr[0] == FTPDATA) { - IP_VS_DBG_PKT(12, pp, skb, 0, "Not scheduling FTPDATA"); + IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, + "Not scheduling FTPDATA"); return NULL; } @@ -376,7 +377,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) && (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) { - IP_VS_DBG_PKT(12, pp, skb, 0, + IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, "Not scheduling reply for existing connection"); __ip_vs_conn_put(cp); return NULL; @@ -617,10 +618,10 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, skb->ip_summed = CHECKSUM_UNNECESSARY; if (inout) - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, + IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph, "Forwarding altered outgoing ICMP"); else - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, + IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph, "Forwarding altered incoming ICMP"); } @@ -662,11 +663,13 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, skb->ip_summed = CHECKSUM_PARTIAL; if (inout) - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, - "Forwarding altered outgoing ICMPv6"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, + (void *)ciph - (void *)iph, + "Forwarding altered outgoing ICMPv6"); else - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, - "Forwarding altered incoming ICMPv6"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, + (void *)ciph - (void *)iph, + "Forwarding altered incoming ICMPv6"); } #endif @@ -798,7 +801,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related, pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMP for"); + IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, + "Checking outgoing ICMP for"); offset += cih->ihl * 4; @@ -874,7 +878,8 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMPv6 for"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, + "Checking outgoing ICMPv6 for"); offset += sizeof(struct ipv6hdr); @@ -922,7 +927,7 @@ static unsigned int handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp, int ihl) { - IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet"); + IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); if (!skb_make_writable(skb, ihl)) goto drop; @@ -967,7 +972,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ip_route_me_harder(skb, RTN_LOCAL) != 0) goto drop; - IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT"); + IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); ip_vs_out_stats(cp, skb); ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); @@ -1117,7 +1122,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) } } } - IP_VS_DBG_PKT(12, pp, skb, 0, + IP_VS_DBG_PKT(12, af, pp, skb, 0, "ip_vs_out: packet continues traversal as normal"); return NF_ACCEPT; } @@ -1253,7 +1258,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMP for"); + IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, + "Checking incoming ICMP for"); offset += cih->ihl * 4; @@ -1364,7 +1370,8 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMPv6 for"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, + "Checking incoming ICMPv6 for"); offset += sizeof(struct ipv6hdr); @@ -1492,12 +1499,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) if (unlikely(!cp)) { /* sorry, all this trouble for a no-hit :) */ - IP_VS_DBG_PKT(12, pp, skb, 0, + IP_VS_DBG_PKT(12, af, pp, skb, 0, "ip_vs_in: packet continues traversal as normal"); return NF_ACCEPT; } - IP_VS_DBG_PKT(11, pp, skb, 0, "Incoming packet"); + IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); /* Check the server status */ if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index 027f654799fe..c53998390877 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c @@ -172,8 +172,8 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp, else if (ih->frag_off & htons(IP_OFFSET)) sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr); else { - __be16 _ports[2], *pptr -; + __be16 _ports[2], *pptr; + pptr = skb_header_pointer(skb, offset + ih->ihl*4, sizeof(_ports), _ports); if (pptr == NULL) @@ -223,13 +223,13 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp, void -ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, +ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg) { #ifdef CONFIG_IP_VS_IPV6 - if (skb->protocol == htons(ETH_P_IPV6)) + if (af == AF_INET6) ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg); else #endif diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c index 8956ef33ea6c..3a0461117d3f 100644 --- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c +++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c @@ -117,54 +117,6 @@ ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, return 0; } - -static void -ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ - char buf[256]; - struct iphdr _iph, *ih; - - ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); - if (ih == NULL) - sprintf(buf, "TRUNCATED"); - else - sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr); - - pr_debug("%s: %s %s\n", msg, pp->name, buf); -} - -#ifdef CONFIG_IP_VS_IPV6 -static void -ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ - char buf[256]; - struct ipv6hdr _iph, *ih; - - ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); - if (ih == NULL) - sprintf(buf, "TRUNCATED"); - else - sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr); - - pr_debug("%s: %s %s\n", msg, pp->name, buf); -} -#endif - -static void -ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ -#ifdef CONFIG_IP_VS_IPV6 - if (skb->protocol == htons(ETH_P_IPV6)) - ah_esp_debug_packet_v6(pp, skb, offset, msg); - else -#endif - ah_esp_debug_packet_v4(pp, skb, offset, msg); -} - - static void ah_esp_init(struct ip_vs_protocol *pp) { /* nothing to do now */ @@ -195,7 +147,7 @@ struct ip_vs_protocol ip_vs_protocol_ah = { .register_app = NULL, .unregister_app = NULL, .app_conn_bind = NULL, - .debug_packet = ah_esp_debug_packet, + .debug_packet = ip_vs_tcpudp_debug_packet, .timeout_change = NULL, /* ISAKMP */ .set_state_timeout = NULL, }; @@ -219,7 +171,7 @@ struct ip_vs_protocol ip_vs_protocol_esp = { .register_app = NULL, .unregister_app = NULL, .app_conn_bind = NULL, - .debug_packet = ah_esp_debug_packet, + .debug_packet = ip_vs_tcpudp_debug_packet, .timeout_change = NULL, /* ISAKMP */ }; #endif diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 9ab5232ce019..d254345bfda7 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -176,7 +176,7 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) if (val != cmp) { /* CRC failure, dump it. */ - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 85d80a66b492..f6c5200e2146 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -300,7 +300,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - tcphoff, ipv6_hdr(skb)->nexthdr, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } @@ -311,7 +311,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - tcphoff, ip_hdr(skb)->protocol, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 5d21f08155ed..9d106a06bb0a 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -314,7 +314,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - udphoff, ipv6_hdr(skb)->nexthdr, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } @@ -325,7 +325,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - udphoff, ip_hdr(skb)->protocol, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 97b5361c036e..de04ea39cde8 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -543,7 +543,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); if (ct && !nf_ct_is_untracked(ct)) { - IP_VS_DBG_RL_PKT(10, pp, skb, 0, "ip_vs_nat_xmit(): " + IP_VS_DBG_RL_PKT(10, AF_INET, pp, skb, 0, + "ip_vs_nat_xmit(): " "stopping DNAT to local address"); goto tx_error_put; } @@ -552,7 +553,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* From world but DNAT to loopback address? */ if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { - IP_VS_DBG_RL_PKT(1, pp, skb, 0, "ip_vs_nat_xmit(): " + IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): " "stopping DNAT to loopback address"); goto tx_error_put; } @@ -561,7 +562,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, mtu = dst_mtu(&rt->dst); if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) { icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); - IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for"); + IP_VS_DBG_RL_PKT(0, AF_INET, pp, skb, 0, + "ip_vs_nat_xmit(): frag needed for"); goto tx_error_put; } @@ -593,7 +595,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error; } - IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); + IP_VS_DBG_PKT(10, AF_INET, pp, skb, 0, "After DNAT"); /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still @@ -654,7 +656,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); if (ct && !nf_ct_is_untracked(ct)) { - IP_VS_DBG_RL_PKT(10, pp, skb, 0, + IP_VS_DBG_RL_PKT(10, AF_INET6, pp, skb, 0, "ip_vs_nat_xmit_v6(): " "stopping DNAT to local address"); goto tx_error_put; @@ -665,7 +667,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* From world but DNAT to loopback address? */ if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { - IP_VS_DBG_RL_PKT(1, pp, skb, 0, + IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0, "ip_vs_nat_xmit_v6(): " "stopping DNAT to loopback address"); goto tx_error_put; @@ -680,7 +682,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, skb->dev = net->loopback_dev; } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0, "ip_vs_nat_xmit_v6(): frag needed for"); goto tx_error_put; } @@ -706,7 +708,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, dst_release(&rt->dst); } - IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); + IP_VS_DBG_PKT(10, AF_INET6, pp, skb, 0, "After DNAT"); /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still -- cgit v1.2.3 From 7b5edbc4cfe2297b0915adea5aa1eafcafadbf06 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Oct 2010 19:22:34 +0000 Subject: net/sched: fix missing spinlock init Under network load, doing : tc qdisc del dev eth0 root triggers : [ 167.193087] BUG: spinlock bad magic on CPU#3, udpflood/4928 [ 167.193139] lock: c15bc324, .magic: 00000000, .owner: /-1, .owner_cpu: -1 [ 167.193193] Pid: 4928, comm: udpflood Not tainted 2.6.36-rc7-11417-g215340c-dirty #323 [ 167.193245] Call Trace: [ 167.193292] [] ? printk+0x18/0x20 [ 167.193342] [] spin_bug+0xa3/0xf0 [ 167.193389] [] do_raw_spin_lock+0x7d/0x160 [ 167.193440] [] ? __dev_xmit_skb+0x27e/0x2b0 [ 167.193496] [] ? trace_hardirqs_on+0xb/0x10 [ 167.193545] [] _raw_spin_lock+0x3a/0x40 [ 167.193593] [] ? __dev_xmit_skb+0x27e/0x2b0 [ 167.193641] [] __dev_xmit_skb+0x27e/0x2b0 commit 79640a4ca695 (add additional lock to qdisc to increase throughput) forgot to initialize noop_qdisc and noqueue_qdisc busylock Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_generic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 3d57681bdb76..0abcc492fbf9 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -383,6 +383,7 @@ struct Qdisc noop_qdisc = { .list = LIST_HEAD_INIT(noop_qdisc.list), .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock), .dev_queue = &noop_netdev_queue, + .busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock), }; EXPORT_SYMBOL(noop_qdisc); @@ -409,6 +410,7 @@ static struct Qdisc noqueue_qdisc = { .list = LIST_HEAD_INIT(noqueue_qdisc.list), .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock), .dev_queue = &noqueue_netdev_queue, + .busylock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.busylock), }; -- cgit v1.2.3 From 9b0c290e78d667e6a483bde8c7cef7dd15f49017 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Oct 2010 22:03:38 +0000 Subject: fib: introduce fib_alias_accessed() helper Perf tools session at NFWS 2010 pointed out a false sharing on struct fib_alias that can be avoided pretty easily, if we set FA_S_ACCESSED bit only if needed (ie : not already set) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_hash.c | 3 ++- net/ipv4/fib_lookup.h | 7 +++++++ net/ipv4/fib_semantics.c | 2 +- net/ipv4/fib_trie.c | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 4f1aafd3ba89..43e1c594ce8f 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -335,7 +335,8 @@ void fib_table_select_default(struct fib_table *tb, if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) continue; - fa->fa_state |= FA_S_ACCESSED; + + fib_alias_accessed(fa); if (fi == NULL) { if (next_fi != res->fi) diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 5072d8effd5d..a29edf2219c8 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -17,6 +17,13 @@ struct fib_alias { #define FA_S_ACCESSED 0x01 +/* Dont write on fa_state unless needed, to keep it shared on all cpus */ +static inline void fib_alias_accessed(struct fib_alias *fa) +{ + if (!(fa->fa_state & FA_S_ACCESSED)) + fa->fa_state |= FA_S_ACCESSED; +} + /* Exported by fib_semantics.c */ extern int fib_semantic_match(struct list_head *head, const struct flowi *flp, diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 6734c9cab248..3e0da3ef6116 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -901,7 +901,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, if (fa->fa_scope < flp->fl4_scope) continue; - fa->fa_state |= FA_S_ACCESSED; + fib_alias_accessed(fa); err = fib_props[fa->fa_type].error; if (err == 0) { diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 31494f335686..cd5e13aee7d5 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1838,7 +1838,8 @@ void fib_table_select_default(struct fib_table *tb, if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) continue; - fa->fa_state |= FA_S_ACCESSED; + + fib_alias_accessed(fa); if (fi == NULL) { if (next_fi != res->fi) -- cgit v1.2.3 From 7e12bb0adb5b3114a73098d3536b3c45635e6c95 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 17:40:10 +0000 Subject: netxen: make local function static. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 18 +----------------- drivers/net/netxen/netxen_nic_hw.c | 29 +++++++++++------------------ drivers/net/netxen/netxen_nic_main.c | 6 ++++-- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 92f89af0720e..8e8a97839cb0 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1256,19 +1256,9 @@ struct netxen_adapter { const struct firmware *fw; }; -int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port); -int netxen_niu_disable_xg_port(struct netxen_adapter *adapter); - int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val); int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val); -/* Functions available from netxen_nic_hw.c */ -int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); -int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); - -int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); -int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); - #define NXRD32(adapter, off) \ (adapter->crb_read(adapter, off)) #define NXWR32(adapter, off, val) \ @@ -1348,11 +1338,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, struct nx_host_rds_ring *rds_ring); int netxen_process_cmd_ring(struct netxen_adapter *adapter); int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max); -void netxen_p2_nic_set_multi(struct net_device *netdev); -void netxen_p3_nic_set_multi(struct net_device *netdev); + void netxen_p3_free_mac_list(struct netxen_adapter *adapter); -int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode); -int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); int netxen_config_rss(struct netxen_adapter *adapter, int enable); int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd); @@ -1367,9 +1354,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable); int netxen_send_lro_cleanup(struct netxen_adapter *adapter); -int netxen_nic_set_mac(struct net_device *netdev, void *p); -struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); - void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 4b4ac7106786..37d3ebd65be8 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -319,6 +319,8 @@ static unsigned crb_hub_agt[64] = #define NETXEN_PCIE_SEM_TIMEOUT 10000 +static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); + int netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) { @@ -345,7 +347,7 @@ netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); } -int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) +static int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) { if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); @@ -356,7 +358,7 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) } /* Disable an XG interface */ -int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) +static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) { __u32 mac_cfg; u32 port = adapter->physical_port; @@ -383,7 +385,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) #define MAC_LO(addr) \ ((addr[5] << 16) | (addr[4] << 8) | (addr[3])) -int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) +static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { u32 mac_cfg; u32 cnt = 0; @@ -434,7 +436,7 @@ int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) return 0; } -int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) +static int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) { u32 mac_hi, mac_lo; u32 reg_hi, reg_lo; @@ -531,7 +533,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter, return 0; } -void netxen_p2_nic_set_multi(struct net_device *netdev) +static void netxen_p2_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; @@ -680,7 +682,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, cur->mac_addr, NETXEN_MAC_ADD); } -void netxen_p3_nic_set_multi(struct net_device *netdev) +static void netxen_p3_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; @@ -727,7 +729,7 @@ send_fw_cmd: } } -int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) +static int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { nx_nic_req_t req; u64 word; @@ -760,7 +762,7 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter) } } -int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) +static int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) { /* assuming caller has already copied new addr to netdev */ netxen_p3_nic_set_multi(adapter->netdev); @@ -1873,16 +1875,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) } /* NIU access sections */ - -int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) -{ - new_mtu += MTU_FUDGE_FACTOR; - NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), - new_mtu); - return 0; -} - -int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) +static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += MTU_FUDGE_FACTOR; if (adapter->physical_port == 0) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6f111691aca4..50820beac3aa 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -95,6 +95,8 @@ static irqreturn_t netxen_msi_intr(int irq, void *data); static irqreturn_t netxen_msix_intr(int irq, void *data); static void netxen_config_indev_addr(struct net_device *dev, unsigned long); +static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); +static int netxen_nic_set_mac(struct net_device *netdev, void *p); /* PCI Device ID Table */ #define ENTRY(device) \ @@ -455,7 +457,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) return 0; } -int netxen_nic_set_mac(struct net_device *netdev, void *p) +static int netxen_nic_set_mac(struct net_device *netdev, void *p) { struct netxen_adapter *adapter = netdev_priv(netdev); struct sockaddr *addr = p; @@ -2052,7 +2054,7 @@ request_reset: clear_bit(__NX_RESETTING, &adapter->state); } -struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) +static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct net_device_stats *stats = &netdev->stats; -- cgit v1.2.3 From 11165f1457181e4499e5eada442434a07827ffd8 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 14:27:29 +0000 Subject: socket: localize functions A couple of functions in socket.c are only used there and should be localized. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/socket.h | 1 - net/socket.c | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index a8f56e1ec760..5146b50202ce 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -326,7 +326,6 @@ extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *a extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, int offset, int len); -extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); diff --git a/net/socket.c b/net/socket.c index 717a5f1c8792..72da57d6ab7b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -209,8 +209,8 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr) * specified. Zero is returned for a success. */ -int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, - int __user *ulen) +static int move_addr_to_user(struct sockaddr *kaddr, int klen, + void __user *uaddr, int __user *ulen) { int err; int len; @@ -661,7 +661,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, } EXPORT_SYMBOL_GPL(__sock_recv_timestamp); -inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) +static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, + struct sk_buff *skb) { if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount) put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, -- cgit v1.2.3 From d0280232813a6a5e2bfca6e9257b866352115c09 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 14:03:21 +0000 Subject: bridge: make br_parse_ip_options static Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 47c2dabe8669..865fd7634b67 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -215,7 +215,7 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb) * expected format */ -int br_parse_ip_options(struct sk_buff *skb) +static int br_parse_ip_options(struct sk_buff *skb) { struct ip_options *opt; struct iphdr *iph; -- cgit v1.2.3 From d215697fe14a0c5a96765c6279b4751e632587a5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 05:27:31 +0000 Subject: sfc: make functions static Make local functions and variable static. Do some rearrangement of the string table stuff to put it where it gets used. Signed-off-by: Stephen Hemminger Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 16 +++------------- drivers/net/sfc/efx.h | 10 +--------- drivers/net/sfc/ethtool.c | 10 +++++----- drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/mac.h | 1 - drivers/net/sfc/mcdi.c | 4 ++-- drivers/net/sfc/mcdi.h | 2 -- drivers/net/sfc/mcdi_phy.c | 3 ++- drivers/net/sfc/net_driver.h | 5 ----- drivers/net/sfc/nic.c | 2 +- drivers/net/sfc/selftest.c | 10 ++++++++++ drivers/net/sfc/siena.c | 2 +- 12 files changed, 26 insertions(+), 41 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index fa6e0207de17..05df20e47976 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -68,14 +68,6 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; -/* Interrupt mode names (see INT_MODE())) */ -const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; -const char *efx_interrupt_mode_names[] = { - [EFX_INT_MODE_MSIX] = "MSI-X", - [EFX_INT_MODE_MSI] = "MSI", - [EFX_INT_MODE_LEGACY] = "legacy", -}; - const unsigned int efx_reset_type_max = RESET_TYPE_MAX; const char *efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", @@ -128,7 +120,7 @@ static int napi_weight = 64; * - Check the on-board hardware monitor; * - Poll the link state and reconfigure the hardware as necessary. */ -unsigned int efx_monitor_interval = 1 * HZ; +static unsigned int efx_monitor_interval = 1 * HZ; /* This controls whether or not the driver will initialise devices * with invalid MAC addresses stored in the EEPROM or flash. If true, @@ -2180,10 +2172,8 @@ int efx_port_dummy_op_int(struct efx_nic *efx) return 0; } void efx_port_dummy_op_void(struct efx_nic *efx) {} -void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) -{ -} -bool efx_port_dummy_op_poll(struct efx_nic *efx) + +static bool efx_port_dummy_op_poll(struct efx_nic *efx) { return false; } diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index f502b14eb22c..10a1bf40da96 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -88,10 +88,6 @@ extern int efx_reconfigure_port(struct efx_nic *efx); extern int __efx_reconfigure_port(struct efx_nic *efx); /* Ethtool support */ -extern int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); -extern int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); extern const struct ethtool_ops efx_ethtool_ops; /* Reset handling */ @@ -107,9 +103,7 @@ extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, /* Dummy PHY ops for PHY drivers */ extern int efx_port_dummy_op_int(struct efx_nic *efx); extern void efx_port_dummy_op_void(struct efx_nic *efx); -extern void -efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -extern bool efx_port_dummy_op_poll(struct efx_nic *efx); + /* MTD */ #ifdef CONFIG_SFC_MTD @@ -122,8 +116,6 @@ static inline void efx_mtd_rename(struct efx_nic *efx) {} static inline void efx_mtd_remove(struct efx_nic *efx) {} #endif -extern unsigned int efx_monitor_interval; - static inline void efx_schedule_channel(struct efx_channel *channel) { netif_vdbg(channel->efx, intr, channel->efx->net_dev, diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index c95328fa3ee8..edb9d16b8b47 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -187,8 +187,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) } /* This must be called with rtnl_lock held. */ -int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_get_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; @@ -211,8 +211,8 @@ int efx_ethtool_get_settings(struct net_device *net_dev, } /* This must be called with rtnl_lock held. */ -int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_set_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); int rc; @@ -891,7 +891,7 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, return efx->type->set_wol(efx, wol->wolopts); } -extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) +static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { struct efx_nic *efx = netdev_priv(net_dev); enum reset_type method; diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index bae656dd2c4e..b31f595ebb5b 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -143,7 +143,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx) efx_mdio_phyxgxs_lane_sync(efx)); } -void falcon_reconfigure_xmac_core(struct efx_nic *efx) +static void falcon_reconfigure_xmac_core(struct efx_nic *efx) { unsigned int max_frame_len; efx_oword_t reg; diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index 7a6e5ca0290e..6886cdf87c12 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h @@ -15,7 +15,6 @@ extern struct efx_mac_operations falcon_xmac_operations; extern struct efx_mac_operations efx_mcdi_mac_operations; -extern void falcon_reconfigure_xmac_core(struct efx_nic *efx); extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 dma_len, int enable, int clear); diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 3912b8fed912..12cf910c2ce7 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -1093,8 +1093,8 @@ int efx_mcdi_reset_mc(struct efx_nic *efx) return rc; } -int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out) +static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, + const u8 *mac, int *id_out) { u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN]; u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN]; diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index f1f89ad4075a..c792f1d65e48 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -121,8 +121,6 @@ extern int efx_mcdi_handle_assertion(struct efx_nic *efx); extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); extern int efx_mcdi_reset_port(struct efx_nic *efx); extern int efx_mcdi_reset_mc(struct efx_nic *efx); -extern int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0121e71702bf..c992742446b1 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -713,7 +713,8 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, return 0; } -const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index) +static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, + unsigned int index) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 44f4d58a39a6..0a7e26d73b52 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -387,11 +387,6 @@ extern const unsigned int efx_loopback_mode_max; #define LOOPBACK_MODE(efx) \ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode) -extern const char *efx_interrupt_mode_names[]; -extern const unsigned int efx_interrupt_mode_max; -#define INT_MODE(efx) \ - STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) - extern const char *efx_reset_type_names[]; extern const unsigned int efx_reset_type_max; #define RESET_TYPE(type) \ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 394dd929fee7..41c36b9a4244 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -653,7 +653,7 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel) } /* Use HW to insert a SW defined event */ -void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) +static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) { efx_oword_t drv_ev_reg; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index da4473b71058..0ebfb99f1299 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -48,6 +48,16 @@ static const unsigned char payload_source[ETH_ALEN] = { static const char payload_msg[] = "Hello world! This is an Efx loopback test in progress!"; +/* Interrupt mode names */ +static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; +static const char *efx_interrupt_mode_names[] = { + [EFX_INT_MODE_MSIX] = "MSI-X", + [EFX_INT_MODE_MSI] = "MSI", + [EFX_INT_MODE_LEGACY] = "legacy", +}; +#define INT_MODE(efx) \ + STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) + /** * efx_loopback_state - persistent state during a loopback selftest * @flush: Drop all packets in efx_loopback_rx_packet diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 2115f95ddc88..45236f58a258 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -129,7 +129,7 @@ static int siena_probe_port(struct efx_nic *efx) return 0; } -void siena_remove_port(struct efx_nic *efx) +static void siena_remove_port(struct efx_nic *efx) { efx->phy_op->remove(efx); efx_nic_free_buffer(efx, &efx->stats_buffer); -- cgit v1.2.3 From 379b7383413d883ffc4db55914626ca303e6f7f5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 11:02:56 +0000 Subject: bonding: make bond_resend_igmp_join_requests_delayed static Signed-off-by: Stephen Hemminger Acked-by: Flavio Leitner Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6b9a7bd8ec14..f80f13260b32 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -916,7 +916,7 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) read_unlock(&bond->lock); } -void bond_resend_igmp_join_requests_delayed(struct work_struct *work) +static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) { struct bonding *bond = container_of(work, struct bonding, mcast_work.work); -- cgit v1.2.3 From ae316bb57d25d73ae9c1ddc9c59fe56d733849bf Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 11:06:20 +0000 Subject: vmxnet3: make bit twiddle routines inline Gcc doesn't usually handle inline across compilation units, and the functions don't have to be global in scope. Move the set/reset flag functions int the existing vmxnet3 header. Signed-off-by: Stephen Hemminger Acked-by: Shreyas Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 17 ----------------- drivers/net/vmxnet3/vmxnet3_int.h | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index b1de73b1bf1a..3f60e0e3097b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1548,23 +1548,6 @@ vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) } } - -inline void set_flag_le16(__le16 *data, u16 flag) -{ - *data = cpu_to_le16(le16_to_cpu(*data) | flag); -} - -inline void set_flag_le64(__le64 *data, u64 flag) -{ - *data = cpu_to_le64(le64_to_cpu(*data) | flag); -} - -inline void reset_flag_le64(__le64 *data, u64 flag) -{ - *data = cpu_to_le64(le64_to_cpu(*data) & ~flag); -} - - static void vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 2121c735cabd..c88ea5cbba0d 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -353,9 +353,20 @@ struct vmxnet3_adapter { #define VMXNET3_MAX_ETH_HDR_SIZE 22 #define VMXNET3_MAX_SKB_BUF_SIZE (3*1024) -void set_flag_le16(__le16 *data, u16 flag); -void set_flag_le64(__le64 *data, u64 flag); -void reset_flag_le64(__le64 *data, u64 flag); +static inline void set_flag_le16(__le16 *data, u16 flag) +{ + *data = cpu_to_le16(le16_to_cpu(*data) | flag); +} + +static inline void set_flag_le64(__le64 *data, u64 flag) +{ + *data = cpu_to_le64(le64_to_cpu(*data) | flag); +} + +static inline void reset_flag_le64(__le64 *data, u64 flag) +{ + *data = cpu_to_le64(le64_to_cpu(*data) & ~flag); +} int vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter); -- cgit v1.2.3 From 191cc6877408348e90f4adb64726b60a93246b8b Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 11:09:14 +0000 Subject: pch_gbe: make local functions static Make routines that are only used in one file static. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe.h | 4 +--- drivers/net/pch_gbe/pch_gbe_api.c | 2 +- drivers/net/pch_gbe/pch_gbe_main.c | 26 +++++++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index 9a940a940a4a..a0c26a99520f 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -644,9 +644,7 @@ extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, struct pch_gbe_rx_ring *rx_ring); extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); -extern int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); -extern void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, - int data); + /* pch_gbe_param.c */ extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); diff --git a/drivers/net/pch_gbe/pch_gbe_api.c b/drivers/net/pch_gbe/pch_gbe_api.c index db53d2a943e0..e48f084ad226 100644 --- a/drivers/net/pch_gbe/pch_gbe_api.c +++ b/drivers/net/pch_gbe/pch_gbe_api.c @@ -97,7 +97,7 @@ static const struct pch_gbe_functions pch_gbe_ops = { * pch_gbe_plat_init_function_pointers - Init func ptrs * @hw: Pointer to the HW structure */ -void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw) +static void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw) { /* Set PHY parameter */ hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US; diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index cf4b49d6c6da..472056b47440 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -85,6 +85,9 @@ const char pch_driver_version[] = DRV_VERSION; static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; +static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); +static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, + int data); /** * pch_gbe_mac_read_mac_addr - Read MAC address * @hw: Pointer to the HW structure @@ -114,7 +117,7 @@ s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) * @reg: Pointer of register * @busy: Busy bit */ -void pch_gbe_wait_clr_bit(void *reg, u32 bit) +static void pch_gbe_wait_clr_bit(void *reg, u32 bit) { u32 tmp; /* wait busy */ @@ -130,7 +133,7 @@ void pch_gbe_wait_clr_bit(void *reg, u32 bit) * @addr: Pointer to the MAC address * @index: MAC address array register */ -void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) +static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) { u32 mar_low, mar_high, adrmask; @@ -161,7 +164,7 @@ void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) * pch_gbe_mac_reset_hw - Reset hardware * @hw: Pointer to the HW structure */ -void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) +static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) { /* Read the MAC address. and store to the private data */ pch_gbe_mac_read_mac_addr(hw); @@ -180,7 +183,7 @@ void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) * @hw: Pointer to the HW structure * @mar_count: Receive address registers */ -void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count) +static void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count) { u32 i; @@ -206,9 +209,9 @@ void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count) * @mar_used_count: The first MAC Address register free to program * @mar_total_num: Total number of supported MAC Address Registers */ -void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count, - u32 mar_used_count, u32 mar_total_num) +static void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 mar_used_count, u32 mar_total_num) { u32 i, adrmask; @@ -285,7 +288,7 @@ s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw) * @hw: Pointer to the HW structure * @wu_evt: Wake up event */ -void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt) +static void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt) { u32 addr_mask; @@ -359,7 +362,7 @@ u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg, * pch_gbe_mac_set_pause_packet - Set pause packet * @hw: Pointer to the HW structure */ -void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw) +static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw) { unsigned long tmp2, tmp3; @@ -482,7 +485,7 @@ static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter) * 0: Successfully * Negative value: Failed */ -int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg) +static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_hw *hw = &adapter->hw; @@ -498,7 +501,8 @@ int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg) * @reg: Access location * @data: Write data */ -void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data) +static void pch_gbe_mdio_write(struct net_device *netdev, + int addr, int reg, int data) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_hw *hw = &adapter->hw; -- cgit v1.2.3 From 6f747aca5e61778190d1e27bdc469f49149f0230 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 05:15:59 +0000 Subject: xfrm6: make xfrm6_tunnel_free_spi local Function only defined and used in one file. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/xfrm.h | 1 - net/ipv6/xfrm6_tunnel.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 4f53532d4c2f..36fdcb3fab9e 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1419,7 +1419,6 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); -extern void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr); extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr); extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index ac7584b946a5..2969cad408de 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -199,7 +199,7 @@ static void x6spi_destroy_rcu(struct rcu_head *head) container_of(head, struct xfrm6_tunnel_spi, rcu_head)); } -void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) +static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) { struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); struct xfrm6_tunnel_spi *x6spi; @@ -223,8 +223,6 @@ void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) spin_unlock_bh(&xfrm6_tunnel_spi_lock); } -EXPORT_SYMBOL(xfrm6_tunnel_free_spi); - static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { skb_push(skb, -skb_network_offset(skb)); -- cgit v1.2.3 From 8d8a0b1cc2a8f9794a3f1f747089b6a93774408d Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 05:12:01 +0000 Subject: rtnetlink: remove rtnl_kill_links The function rtnl_kill_links is defined but never used. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/rtnetlink.h | 1 - net/core/rtnetlink.c | 8 -------- 2 files changed, 9 deletions(-) diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index af60fd050844..e013c68bfb00 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -79,7 +79,6 @@ struct rtnl_link_ops { extern int __rtnl_link_register(struct rtnl_link_ops *ops); extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); -extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b2a718dfd720..8121268ddbdd 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -299,14 +299,6 @@ static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) unregister_netdevice_many(&list_kill); } -void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) -{ - rtnl_lock(); - __rtnl_kill_links(net, ops); - rtnl_unlock(); -} -EXPORT_SYMBOL_GPL(rtnl_kill_links); - /** * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. * @ops: struct rtnl_link_ops * to unregister -- cgit v1.2.3 From 1c4c40c42da468ef02dc04940930c1926c964558 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 05:14:19 +0000 Subject: xfrm: make xfrm_bundle_ok local Only used in one place. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/xfrm.h | 2 -- net/xfrm/xfrm_policy.c | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 36fdcb3fab9e..f28d7c9b9f8d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1465,8 +1465,6 @@ struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark, xfrm_address_t *saddr, int create, unsigned short family); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); -extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, - struct flowi *fl, int family, int strict); #ifdef CONFIG_XFRM_MIGRATE extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cbab6e1a8c9c..044e77898512 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -50,6 +50,9 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); static void xfrm_init_pmtu(struct dst_entry *dst); static int stale_bundle(struct dst_entry *dst); +static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, + struct flowi *fl, int family, int strict); + static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, int dir); @@ -2276,7 +2279,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst) * still valid. */ -int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, +static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, struct flowi *fl, int family, int strict) { struct dst_entry *dst = &first->u.dst; @@ -2358,8 +2361,6 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, return 1; } -EXPORT_SYMBOL(xfrm_bundle_ok); - int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) { struct net *net; -- cgit v1.2.3 From 26d8ee75e08cfca8b65ade871d68c8cd96e4ea23 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 05:09:34 +0000 Subject: bonding: make release_and_destroy static Only used in main file. Signed-off-by: Stephen Hemminger Acked-by: Andy Gospodarek Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/bonding/bonding.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f80f13260b32..beb3b7cecd52 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2057,8 +2057,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) * First release a slave and than destroy the bond if no more slaves are left. * Must be under rtnl_lock when this function is called. */ -int bond_release_and_destroy(struct net_device *bond_dev, - struct net_device *slave_dev) +static int bond_release_and_destroy(struct net_device *bond_dev, + struct net_device *slave_dev) { struct bonding *bond = netdev_priv(bond_dev); int ret; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 2c12a5f812f4..4eedb12df6ca 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -364,7 +364,6 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond) struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); int bond_create(struct net *net, const char *name); -int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev); int bond_create_sysfs(void); void bond_destroy_sysfs(void); void bond_prepare_sysfs_group(struct bonding *bond); -- cgit v1.2.3 From 3511c9132f8b1e1b5634e41a3331c44b0c13be70 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 16 Oct 2010 13:04:08 +0000 Subject: net_sched: remove the unused parameter of qdisc_create_dflt() The first parameter dev isn't in use in qdisc_create_dflt(). Signed-off-by: Changli Gao Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/sch_generic.h | 3 +-- net/sched/sch_atm.c | 5 ++--- net/sched/sch_cbq.c | 12 ++++++------ net/sched/sch_drr.c | 4 ++-- net/sched/sch_dsmark.c | 6 ++---- net/sched/sch_fifo.c | 3 +-- net/sched/sch_generic.c | 10 ++++------ net/sched/sch_hfsc.c | 8 +++----- net/sched/sch_htb.c | 8 +++----- net/sched/sch_mq.c | 2 +- net/sched/sch_multiq.c | 3 +-- net/sched/sch_netem.c | 3 +-- net/sched/sch_prio.c | 2 +- 13 files changed, 28 insertions(+), 41 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index eda8808fdacd..ea1f8a83160d 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -328,8 +328,7 @@ extern void qdisc_destroy(struct Qdisc *qdisc); extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n); extern struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, struct Qdisc_ops *ops); -extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, - struct netdev_queue *dev_queue, +extern struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, struct Qdisc_ops *ops, u32 parentid); extern void qdisc_calculate_pkt_len(struct sk_buff *skb, struct qdisc_size_table *stab); diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 6318e1136b83..282540778aa8 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -275,8 +275,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, goto err_out; } flow->filter_list = NULL; - flow->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, classid); + flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (!flow->q) flow->q = &noop_qdisc; pr_debug("atm_tc_change: qdisc %p\n", flow->q); @@ -543,7 +542,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt) INIT_LIST_HEAD(&p->flows); INIT_LIST_HEAD(&p->link.list); list_add(&p->link.list, &p->flows); - p->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + p->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (!p->link.q) p->link.q = &noop_qdisc; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 28c01ef5abc8..eb7631590865 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1379,9 +1379,9 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) q->link.sibling = &q->link; q->link.common.classid = sch->handle; q->link.qdisc = sch; - if (!(q->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, - sch->handle))) + q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, + sch->handle); + if (!q->link.q) q->link.q = &noop_qdisc; q->link.priority = TC_CBQ_MAXPRIO-1; @@ -1623,7 +1623,7 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct cbq_class *cl = (struct cbq_class*)arg; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid); if (new == NULL) return -ENOBUFS; @@ -1874,8 +1874,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t cl->R_tab = rtab; rtab = NULL; cl->refcnt = 1; - if (!(cl->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, classid))) + cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); + if (!cl->q) cl->q = &noop_qdisc; cl->common.classid = classid; cl->tparent = parent; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index b74046a95397..aa8b5313f8cf 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -110,7 +110,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->refcnt = 1; cl->common.classid = classid; cl->quantum = quantum; - cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (cl->qdisc == NULL) cl->qdisc = &noop_qdisc; @@ -218,7 +218,7 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg, struct drr_class *cl = (struct drr_class *)arg; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid); if (new == NULL) new = &noop_qdisc; diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 63d41f86679c..1d295d62bb5c 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -61,8 +61,7 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg, sch, p, new, old); if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (new == NULL) new = &noop_qdisc; @@ -384,8 +383,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) p->default_index = default_index; p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]); - p->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, sch->handle); + p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (p->q == NULL) p->q = &noop_qdisc; diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 5948bafa8ce2..4dfecb0cba37 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -172,8 +172,7 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops, struct Qdisc *q; int err = -ENOMEM; - q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - ops, TC_H_MAKE(sch->handle, 1)); + q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1)); if (q) { err = fifo_set_limit(q, limit); if (err < 0) { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 0abcc492fbf9..5dbb3cd96e59 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -576,10 +576,8 @@ errout: return ERR_PTR(err); } -struct Qdisc * qdisc_create_dflt(struct net_device *dev, - struct netdev_queue *dev_queue, - struct Qdisc_ops *ops, - unsigned int parentid) +struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, + struct Qdisc_ops *ops, unsigned int parentid) { struct Qdisc *sch; @@ -684,7 +682,7 @@ static void attach_one_default_qdisc(struct net_device *dev, struct Qdisc *qdisc; if (dev->tx_queue_len) { - qdisc = qdisc_create_dflt(dev, dev_queue, + qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops, TC_H_ROOT); if (!qdisc) { printk(KERN_INFO "%s: activation failed\n", dev->name); @@ -711,7 +709,7 @@ static void attach_default_qdiscs(struct net_device *dev) dev->qdisc = txq->qdisc_sleeping; atomic_inc(&dev->qdisc->refcnt); } else { - qdisc = qdisc_create_dflt(dev, txq, &mq_qdisc_ops, TC_H_ROOT); + qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT); if (qdisc) { qdisc->ops->attach(qdisc); dev->qdisc = qdisc; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 47496098d35c..069c62b7bb36 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1088,7 +1088,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->refcnt = 1; cl->sched = q; cl->cl_parent = parent; - cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (cl->qdisc == NULL) cl->qdisc = &noop_qdisc; @@ -1209,8 +1209,7 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, if (cl->level > 0) return -EINVAL; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->cl_common.classid); if (new == NULL) new = &noop_qdisc; @@ -1452,8 +1451,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) q->root.cl_common.classid = sch->handle; q->root.refcnt = 1; q->root.sched = q; - q->root.qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (q->root.qdisc == NULL) q->root.qdisc = &noop_qdisc; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 87d944941867..01b519d6c52d 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1121,8 +1121,7 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, if (cl->level) return -EINVAL; if (new == NULL && - (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid)) == NULL) return -ENOBUFS; @@ -1247,8 +1246,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) return -EBUSY; if (!cl->level && htb_parent_last_child(cl)) { - new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->parent->common.classid); last_child = 1; } @@ -1377,7 +1375,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) so that can't be used inside of sch_tree_lock -- thanks to Karlis Peisenieks */ - new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); sch_tree_lock(sch); if (parent && !parent->level) { diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index fe91e50f9d98..ecc302f4d2a1 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -56,7 +56,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { dev_queue = netdev_get_tx_queue(dev, ntx); - qdisc = qdisc_create_dflt(dev, dev_queue, &pfifo_fast_ops, + qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops, TC_H_MAKE(TC_H_MAJ(sch->handle), TC_H_MIN(ntx + 1))); if (qdisc == NULL) diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 6ae251279fc2..32690deab5d0 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -227,8 +227,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt) for (i = 0; i < q->bands; i++) { if (q->queues[i] == &noop_qdisc) { struct Qdisc *child, *old; - child = qdisc_create_dflt(qdisc_dev(sch), - sch->dev_queue, + child = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, TC_H_MAKE(sch->handle, i + 1)); diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 4714ff162bbd..e5593c083a78 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -538,8 +538,7 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt) qdisc_watchdog_init(&q->watchdog, sch); - q->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &tfifo_qdisc_ops, + q->qdisc = qdisc_create_dflt(sch->dev_queue, &tfifo_qdisc_ops, TC_H_MAKE(sch->handle, 1)); if (!q->qdisc) { pr_debug("netem: qdisc create failed\n"); diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 0748fb1e3a49..b1c95bce33ce 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -200,7 +200,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) for (i=0; ibands; i++) { if (q->queues[i] == &noop_qdisc) { struct Qdisc *child, *old; - child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + child = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, TC_H_MAKE(sch->handle, i + 1)); if (child) { -- cgit v1.2.3 From fdb246f526e422b18b48d578085c01ab28ec2c33 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 18 Oct 2010 14:30:54 +0000 Subject: bnx2: Increase max rx ring size from 1K to 2K A number of customers are reporting packet loss under certain workloads (e.g. heavy bursts of small packets) with flow control disabled. A larger rx ring helps to prevent these losses. No change in default rx ring size and memory consumption. Signed-off-by: Andy Gospodarek Acked-by: John Feeney Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 4f44db68c802..bf4c3421067d 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6502,8 +6502,8 @@ struct l2_fhdr { #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) -#define MAX_RX_RINGS 4 -#define MAX_RX_PG_RINGS 16 +#define MAX_RX_RINGS 8 +#define MAX_RX_PG_RINGS 32 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) #define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS) -- cgit v1.2.3 From f4e8ab7cc4e819011ca6325e54383b3da7a5d130 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Mon, 18 Oct 2010 13:16:39 +0000 Subject: smsc95xx: generate random MAC address once, not every ifup The smsc95xx driver currently generates a new random MAC address every time the interface is brought up. This makes it impossible to override using the standard `ifconfig hw ether` approach. Past patches tried to make the MAC address a module parameter or base it off the die ID, but it seems to me much simpler (and hopefully less controversial) to stick with the current random generation scheme, but allow the user to change the address. This patch does exactly that - it moves the random address generation from smsc95xx_reset() into smsc95xx_bind(), so that it is done once on module load, not on every ifup. The user can then override this using the standard mechanisms. Applies against 2.6.35 and linux-2.6 head. Signed-off-by: Bernard Blackham Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 12a3c88c5282..65cb1abfbe57 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -805,8 +805,6 @@ static int smsc95xx_reset(struct usbnet *dev) return ret; } - smsc95xx_init_mac_address(dev); - ret = smsc95xx_set_mac_address(dev); if (ret < 0) return ret; @@ -1047,6 +1045,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE; pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; + smsc95xx_init_mac_address(dev); + /* Init all registers */ ret = smsc95xx_reset(dev); -- cgit v1.2.3 From 7453da829786061e81c9c11b7a34a2834146894f Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Fri, 15 Oct 2010 17:53:29 +0000 Subject: Drivers: atm: Makefile: replace the use of -objs with -y Changed -objs to -y in Makefile. Signed-off-by: Tracey Dent Signed-off-by: David S. Miller --- drivers/atm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 62c3cc1075ae..c6c9ee9f5da2 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux network (ATM) device drivers. # -fore_200e-objs := fore200e.o +fore_200e-y := fore200e.o obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o obj-$(CONFIG_ATM_NICSTAR) += nicstar.o -- cgit v1.2.3 From 128ea6c3eece8e87c05813d3a57f4ea079c3dbc7 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Sat, 16 Oct 2010 20:19:58 +0000 Subject: bonding: cleanup : add space around operators checkpatch.pl cleanup: Added spaces around operators at various places. Also fixed some c99 style comments that I came across. Signed-off-by: Bandan Das Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 111 +++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 44 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 079b9d1eead5..6b06b00af359 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -93,7 +93,7 @@ // compare MAC addresses #define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) -static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}}; +static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } }; static u16 ad_ticks_per_sec; static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000; @@ -329,7 +329,7 @@ static u16 __get_link_speed(struct port *port) * This is done in spite of the fact that the e100 driver reports 0 to be * compatible with MVT in the future.*/ if (slave->link != BOND_LINK_UP) { - speed=0; + speed = 0; } else { switch (slave->speed) { case SPEED_10: @@ -376,17 +376,17 @@ static u8 __get_duplex(struct port *port) // handling a special case: when the configuration starts with // link down, it sets the duplex to 0. if (slave->link != BOND_LINK_UP) { - retval=0x0; + retval = 0x0; } else { switch (slave->duplex) { case DUPLEX_FULL: - retval=0x1; + retval = 0x1; pr_debug("Port %d Received status full duplex update from adapter\n", port->actor_port_number); break; case DUPLEX_HALF: default: - retval=0x0; + retval = 0x0; pr_debug("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number); break; @@ -419,7 +419,7 @@ static inline void __initialize_port_locks(struct port *port) */ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) { - u16 retval=0; //to silence the compiler + u16 retval = 0; /* to silence the compiler */ switch (timer_type) { case AD_CURRENT_WHILE_TIMER: // for rx machine usage @@ -653,7 +653,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) */ static void __attach_bond_to_agg(struct port *port) { - port=NULL; // just to satisfy the compiler + port = NULL; /* just to satisfy the compiler */ // This function does nothing since the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } @@ -668,7 +668,7 @@ static void __attach_bond_to_agg(struct port *port) */ static void __detach_bond_from_agg(struct port *port) { - port=NULL; // just to satisfy the compiler + port = NULL; /* just to satisfy the compiler */ // This function does nothing sience the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } @@ -685,7 +685,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator) if (aggregator) { // scan all ports in this aggregator to verfy if they are all ready - for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + for (port = aggregator->lag_ports; + port; + port = port->next_port_in_aggregator) { if (!(port->sm_vars & AD_PORT_READY_N)) { retval = 0; break; @@ -706,7 +708,8 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) { struct port *port; - for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + for (port = aggregator->lag_ports; port; + port = port->next_port_in_aggregator) { if (val) { port->sm_vars |= AD_PORT_READY; } else { @@ -722,7 +725,7 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) */ static u32 __get_agg_bandwidth(struct aggregator *aggregator) { - u32 bandwidth=0; + u32 bandwidth = 0; u32 basic_speed; if (aggregator->num_of_ports) { @@ -744,7 +747,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) bandwidth = aggregator->num_of_ports * 10000; break; default: - bandwidth=0; // to silent the compilor .... + bandwidth = 0; /*to silence the compiler ....*/ } } return bandwidth; @@ -1183,7 +1186,8 @@ static void ad_tx_machine(struct port *port) } } // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND - port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; + port->sm_tx_timer_counter = + ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; } } @@ -1294,20 +1298,24 @@ static void ad_port_selection_logic(struct port *port) // if the port is connected to other aggregator, detach it if (port->aggregator) { // detach the port from its former aggregator - temp_aggregator=port->aggregator; - for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) { + temp_aggregator = port->aggregator; + for (curr_port = temp_aggregator->lag_ports; curr_port; + last_port = curr_port, + curr_port = curr_port->next_port_in_aggregator) { if (curr_port == port) { temp_aggregator->num_of_ports--; if (!last_port) {// if it is the first port attached to the aggregator - temp_aggregator->lag_ports=port->next_port_in_aggregator; + temp_aggregator->lag_ports = + port->next_port_in_aggregator; } else {// not the first port attached to the aggregator - last_port->next_port_in_aggregator=port->next_port_in_aggregator; + last_port->next_port_in_aggregator = + port->next_port_in_aggregator; } // clear the port's relations to this aggregator port->aggregator = NULL; - port->next_port_in_aggregator=NULL; - port->actor_port_aggregator_identifier=0; + port->next_port_in_aggregator = NULL; + port->actor_port_aggregator_identifier = 0; pr_debug("Port %d left LAG %d\n", port->actor_port_number, @@ -1334,7 +1342,7 @@ static void ad_port_selection_logic(struct port *port) // keep a free aggregator for later use(if needed) if (!aggregator->lag_ports) { if (!free_aggregator) { - free_aggregator=aggregator; + free_aggregator = aggregator; } continue; } @@ -1350,10 +1358,11 @@ static void ad_port_selection_logic(struct port *port) ) { // attach to the founded aggregator port->aggregator = aggregator; - port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; - port->next_port_in_aggregator=aggregator->lag_ports; + port->actor_port_aggregator_identifier = + port->aggregator->aggregator_identifier; + port->next_port_in_aggregator = aggregator->lag_ports; port->aggregator->num_of_ports++; - aggregator->lag_ports=port; + aggregator->lag_ports = port; pr_debug("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier); @@ -1370,7 +1379,8 @@ static void ad_port_selection_logic(struct port *port) if (free_aggregator) { // assign port a new aggregator port->aggregator = free_aggregator; - port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; + port->actor_port_aggregator_identifier = + port->aggregator->aggregator_identifier; // update the new aggregator's parameters // if port was responsed from the end-user @@ -1382,8 +1392,10 @@ static void ad_port_selection_logic(struct port *port) port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; - port->aggregator->partner_system=port->partner_oper.system; - port->aggregator->partner_system_priority = port->partner_oper.system_priority; + port->aggregator->partner_system = + port->partner_oper.system; + port->aggregator->partner_system_priority = + port->partner_oper.system_priority; port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; port->aggregator->receive_state = 1; port->aggregator->transmit_state = 1; @@ -1785,13 +1797,16 @@ static void ad_marker_info_send(struct port *port) marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); marker.requester_system = port->actor_system; // convert requester_port(u32) to Big Endian - marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24)); + marker.requester_transaction_id = + (((++port->transaction_id & 0xFF) << 24) + | ((port->transaction_id & 0xFF00) << 8) + | ((port->transaction_id & 0xFF0000) >> 8) + | ((port->transaction_id & 0xFF000000) >> 24)); marker.pad = 0; marker.tlv_type_terminator = 0x00; marker.terminator_length = 0x00; - for (index=0; index<90; index++) { - marker.reserved_90[index]=0; - } + for (index = 0; index < 90; index++) + marker.reserved_90[index] = 0; // send the marker information if (ad_marker_send(port, &marker) >= 0) { @@ -1816,7 +1831,7 @@ static void ad_marker_info_received(struct bond_marker *marker_info, //marker = *marker_info; memcpy(&marker, marker_info, sizeof(struct bond_marker)); // change the marker subtype to marker response - marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE; + marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE; // send the marker response if (ad_marker_send(port, &marker) >= 0) { @@ -1837,8 +1852,8 @@ static void ad_marker_info_received(struct bond_marker *marker_info, static void ad_marker_response_received(struct bond_marker *marker, struct port *port) { - marker=NULL; // just to satisfy the compiler - port=NULL; // just to satisfy the compiler + marker = NULL; /* just to satisfy the compiler */ + port = NULL; /* just to satisfy the compiler */ // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW } @@ -2037,8 +2052,9 @@ void bond_3ad_unbind_slave(struct slave *slave) new_aggregator->num_of_ports = aggregator->num_of_ports; // update the information that is written on the ports about the aggregator - for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) { - temp_port->aggregator=new_aggregator; + for (temp_port = aggregator->lag_ports; temp_port; + temp_port = temp_port->next_port_in_aggregator) { + temp_port->aggregator = new_aggregator; temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; } @@ -2071,7 +2087,9 @@ void bond_3ad_unbind_slave(struct slave *slave) for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { prev_port = NULL; // search the port in the aggregator's related ports - for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) { + for (temp_port = temp_aggregator->lag_ports; temp_port; + prev_port = temp_port, + temp_port = temp_port->next_port_in_aggregator) { if (temp_port == port) { // the aggregator found - detach the port from this aggregator if (prev_port) { prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; @@ -2079,7 +2097,7 @@ void bond_3ad_unbind_slave(struct slave *slave) temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; } temp_aggregator->num_of_ports--; - if (temp_aggregator->num_of_ports==0) { + if (temp_aggregator->num_of_ports == 0) { select_new_active_agg = temp_aggregator->is_active; // clear the aggregator ad_clear_agg(temp_aggregator); @@ -2094,7 +2112,7 @@ void bond_3ad_unbind_slave(struct slave *slave) } } } - port->slave=NULL; + port->slave = NULL; } /** @@ -2245,7 +2263,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) } port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + port->actor_oper_port_key = port->actor_admin_port_key |= + (__get_link_speed(port) << 1); pr_debug("Port %d changed speed\n", port->actor_port_number); // there is no need to reselect a new aggregator, just signal the // state machines to reinitialize @@ -2262,7 +2281,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) { struct port *port; - port=&(SLAVE_AD_INFO(slave).port); + port = &(SLAVE_AD_INFO(slave).port); // if slave is null, the whole port is not initialized if (!port->slave) { @@ -2272,7 +2291,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) } port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + port->actor_oper_port_key = port->actor_admin_port_key |= + __get_duplex(port); pr_debug("Port %d changed duplex\n", port->actor_port_number); // there is no need to reselect a new aggregator, just signal the // state machines to reinitialize @@ -2304,14 +2324,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) if (link == BOND_LINK_UP) { port->is_enabled = true; port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + port->actor_oper_port_key = port->actor_admin_port_key |= + __get_duplex(port); port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + port->actor_oper_port_key = port->actor_admin_port_key |= + (__get_link_speed(port) << 1); } else { /* link has failed */ port->is_enabled = false; port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS); + port->actor_oper_port_key = (port->actor_admin_port_key &= + ~AD_SPEED_KEY_BITS); } //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN"))); // there is no need to reselect a new aggregator, just signal the -- cgit v1.2.3 From 7bfc47532301a84c575cfc20b4531f5de5c326bc Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Sat, 16 Oct 2010 20:19:59 +0000 Subject: bonding: cleanup: remove braces from single block statements checkpatch.pl cleanup : Remove braces from single statement blocks. Signed-off-by: Bandan Das Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 163 ++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 91 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6b06b00af359..881914bc4e9c 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -129,9 +129,8 @@ static void ad_marker_response_received(struct bond_marker *marker, struct port */ static inline struct bonding *__get_bond_by_port(struct port *port) { - if (port->slave == NULL) { + if (port->slave == NULL) return NULL; - } return bond_get_bond_by_slave(port->slave); } @@ -144,9 +143,8 @@ static inline struct bonding *__get_bond_by_port(struct port *port) */ static inline struct port *__get_first_port(struct bonding *bond) { - if (bond->slave_cnt == 0) { + if (bond->slave_cnt == 0) return NULL; - } return &(SLAVE_AD_INFO(bond->first_slave).port); } @@ -164,9 +162,8 @@ static inline struct port *__get_next_port(struct port *port) struct slave *slave = port->slave; // If there's no bond for this port, or this is the last slave - if ((bond == NULL) || (slave->next == bond->first_slave)) { + if ((bond == NULL) || (slave->next == bond->first_slave)) return NULL; - } return &(SLAVE_AD_INFO(slave->next).port); } @@ -183,9 +180,8 @@ static inline struct aggregator *__get_first_agg(struct port *port) struct bonding *bond = __get_bond_by_port(port); // If there's no bond for this port, or bond has no slaves - if ((bond == NULL) || (bond->slave_cnt == 0)) { + if ((bond == NULL) || (bond->slave_cnt == 0)) return NULL; - } return &(SLAVE_AD_INFO(bond->first_slave).aggregator); } @@ -203,9 +199,8 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) struct bonding *bond = bond_get_bond_by_slave(slave); // If there's no bond for this aggregator, or this is the last slave - if ((bond == NULL) || (slave->next == bond->first_slave)) { + if ((bond == NULL) || (slave->next == bond->first_slave)) return NULL; - } return &(SLAVE_AD_INFO(slave->next).aggregator); } @@ -240,9 +235,8 @@ static inline void __enable_port(struct port *port) { struct slave *slave = port->slave; - if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { + if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) bond_set_slave_active_flags(slave); - } } /** @@ -265,9 +259,8 @@ static inline u32 __get_agg_selection_mode(struct port *port) { struct bonding *bond = __get_bond_by_port(port); - if (bond == NULL) { + if (bond == NULL) return BOND_AD_STABLE; - } return BOND_AD_INFO(bond).agg_select_mode; } @@ -281,9 +274,8 @@ static inline int __check_agg_selection_timer(struct port *port) { struct bonding *bond = __get_bond_by_port(port); - if (bond == NULL) { + if (bond == NULL) return 0; - } return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; } @@ -328,9 +320,9 @@ static u16 __get_link_speed(struct port *port) * link down, it sets the speed to 0. * This is done in spite of the fact that the e100 driver reports 0 to be * compatible with MVT in the future.*/ - if (slave->link != BOND_LINK_UP) { + if (slave->link != BOND_LINK_UP) speed = 0; - } else { + else { switch (slave->speed) { case SPEED_10: speed = AD_LINK_SPEED_BITMASK_10MBPS; @@ -375,9 +367,9 @@ static u8 __get_duplex(struct port *port) // handling a special case: when the configuration starts with // link down, it sets the duplex to 0. - if (slave->link != BOND_LINK_UP) { + if (slave->link != BOND_LINK_UP) retval = 0x0; - } else { + else { switch (slave->duplex) { case DUPLEX_FULL: retval = 0x1; @@ -423,11 +415,10 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) switch (timer_type) { case AD_CURRENT_WHILE_TIMER: // for rx machine usage - if (par) { // for short or long timeout + if (par) retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout - } else { + else retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout - } break; case AD_ACTOR_CHURN_TIMER: // for local churn machine retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); @@ -519,11 +510,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; // set the partner sync. to on if the partner is sync. and the port is matched - if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { + if ((port->sm_vars & AD_PORT_MATCHED) + && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) partner->port_state |= AD_STATE_SYNCHRONIZATION; - } else { + else partner->port_state &= ~AD_STATE_SYNCHRONIZATION; - } } } @@ -710,11 +701,10 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) for (port = aggregator->lag_ports; port; port = port->next_port_in_aggregator) { - if (val) { + if (val) port->sm_vars |= AD_PORT_READY; - } else { + else port->sm_vars &= ~AD_PORT_READY; - } } } @@ -838,9 +828,8 @@ static int ad_lacpdu_send(struct port *port) int length = sizeof(struct lacpdu_header); skb = dev_alloc_skb(length); - if (!skb) { + if (!skb) return -ENOMEM; - } skb->dev = slave->dev; skb_reset_mac_header(skb); @@ -879,9 +868,8 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) int length = sizeof(struct bond_marker_header); skb = dev_alloc_skb(length + 16); - if (!skb) { + if (!skb) return -ENOMEM; - } skb_reserve(skb, 16); @@ -922,9 +910,10 @@ static void ad_mux_machine(struct port *port) } else { switch (port->sm_mux_state) { case AD_MUX_DETACHED: - if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY + if ((port->sm_vars & AD_PORT_SELECTED) + || (port->sm_vars & AD_PORT_STANDBY)) + /* if SELECTED or STANDBY */ port->sm_mux_state = AD_MUX_WAITING; // next state - } break; case AD_MUX_WAITING: // if SELECTED == FALSE return to DETACH state @@ -938,18 +927,18 @@ static void ad_mux_machine(struct port *port) } // check if the wait_while_timer expired - if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) { + if (port->sm_mux_timer_counter + && !(--port->sm_mux_timer_counter)) port->sm_vars |= AD_PORT_READY_N; - } // in order to withhold the selection logic to check all ports READY_N value // every callback cycle to update ready variable, we check READY_N and update READY here __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state - if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) { + if ((port->sm_vars & AD_PORT_READY) + && !port->sm_mux_timer_counter) port->sm_mux_state = AD_MUX_ATTACHED; // next state - } break; case AD_MUX_ATTACHED: // check also if agg_select_timer expired(so the edable port will take place only after this timer) @@ -1044,13 +1033,14 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // check if state machine should change state // first, check if port was reinitialized - if (port->sm_vars & AD_PORT_BEGIN) { - port->sm_rx_state = AD_RX_INITIALIZE; // next state - } + if (port->sm_vars & AD_PORT_BEGIN) + /* next state */ + port->sm_rx_state = AD_RX_INITIALIZE; // check if port is not enabled - else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) { - port->sm_rx_state = AD_RX_PORT_DISABLED; // next state - } + else if (!(port->sm_vars & AD_PORT_BEGIN) + && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) + /* next state */ + port->sm_rx_state = AD_RX_PORT_DISABLED; // check if new lacpdu arrived else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { port->sm_rx_timer_counter = 0; // zero timer @@ -1072,13 +1062,16 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // if no lacpdu arrived and no timer is on switch (port->sm_rx_state) { case AD_RX_PORT_DISABLED: - if (port->sm_vars & AD_PORT_MOVED) { + if (port->sm_vars & AD_PORT_MOVED) port->sm_rx_state = AD_RX_INITIALIZE; // next state - } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) { + else if (port->is_enabled + && (port->sm_vars + & AD_PORT_LACP_ENABLED)) port->sm_rx_state = AD_RX_EXPIRED; // next state - } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) { + else if (port->is_enabled + && ((port->sm_vars + & AD_PORT_LACP_ENABLED) == 0)) port->sm_rx_state = AD_RX_LACP_DISABLED; // next state - } break; default: //to silence the compiler break; @@ -1094,11 +1087,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) port->sm_rx_state); switch (port->sm_rx_state) { case AD_RX_INITIALIZE: - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; - } else { + else port->sm_vars |= AD_PORT_LACP_ENABLED; - } port->sm_vars &= ~AD_PORT_SELECTED; __record_default(port); port->actor_oper_port_state &= ~AD_STATE_EXPIRED; @@ -1152,9 +1144,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // verify that if the aggregator is enabled, the port is enabled too. //(because if the link goes down for a short time, the 802.3ad will not // catch it, and the port will continue to be disabled) - if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { + if (port->aggregator + && port->aggregator->is_active + && !__port_is_enabled(port)) __enable_port(port); - } break; default: //to silence the compiler break; @@ -1220,9 +1213,9 @@ static void ad_periodic_machine(struct port *port) // If not expired, check if there is some new timeout parameter from the partner state switch (port->sm_periodic_state) { case AD_FAST_PERIODIC: - if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { + if (!(port->partner_oper.port_state + & AD_STATE_LACP_TIMEOUT)) port->sm_periodic_state = AD_SLOW_PERIODIC; // next state - } break; case AD_SLOW_PERIODIC: if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { @@ -1241,11 +1234,11 @@ static void ad_periodic_machine(struct port *port) port->sm_periodic_state = AD_FAST_PERIODIC; // next state break; case AD_PERIODIC_TX: - if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { + if (!(port->partner_oper.port_state + & AD_STATE_LACP_TIMEOUT)) port->sm_periodic_state = AD_SLOW_PERIODIC; // next state - } else { + else port->sm_periodic_state = AD_FAST_PERIODIC; // next state - } break; default: //to silence the compiler break; @@ -1291,9 +1284,8 @@ static void ad_port_selection_logic(struct port *port) int found = 0; // if the port is already Selected, do nothing - if (port->sm_vars & AD_PORT_SELECTED) { + if (port->sm_vars & AD_PORT_SELECTED) return; - } // if the port is connected to other aggregator, detach it if (port->aggregator) { @@ -1321,9 +1313,8 @@ static void ad_port_selection_logic(struct port *port) port->actor_port_number, temp_aggregator->aggregator_identifier); // if the aggregator is empty, clear its parameters, and set it ready to be attached - if (!temp_aggregator->lag_ports) { + if (!temp_aggregator->lag_ports) ad_clear_agg(temp_aggregator); - } break; } } @@ -1341,9 +1332,8 @@ static void ad_port_selection_logic(struct port *port) // keep a free aggregator for later use(if needed) if (!aggregator->lag_ports) { - if (!free_aggregator) { + if (!free_aggregator) free_aggregator = aggregator; - } continue; } // check if current aggregator suits us @@ -1384,11 +1374,11 @@ static void ad_port_selection_logic(struct port *port) // update the new aggregator's parameters // if port was responsed from the end-user - if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex + if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) + /* if port is full duplex */ port->aggregator->is_individual = false; - } else { + else port->aggregator->is_individual = true; - } port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; @@ -1716,9 +1706,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast) port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; - if (lacp_fast) { + if (lacp_fast) port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; - } memcpy(&port->partner_admin, &tmpl, sizeof(tmpl)); memcpy(&port->partner_oper, &tmpl, sizeof(tmpl)); @@ -1947,9 +1936,8 @@ int bond_3ad_bind_slave(struct slave *slave) port->actor_admin_port_key |= (__get_link_speed(port) << 1); port->actor_oper_port_key = port->actor_admin_port_key; // if the port is not full duplex, then the port should be not lacp Enabled - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; - } // actor system is the bond's system port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) @@ -2021,9 +2009,10 @@ void bond_3ad_unbind_slave(struct slave *slave) new_aggregator = __get_first_agg(port); for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { // if the new aggregator is empty, or it is connected to our port only - if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) { + if (!new_aggregator->lag_ports + || ((new_aggregator->lag_ports == port) + && !new_aggregator->lag_ports->next_port_in_aggregator)) break; - } } // if new aggregator found, copy the aggregator's parameters // and connect the related lag_ports to the new aggregator @@ -2061,9 +2050,8 @@ void bond_3ad_unbind_slave(struct slave *slave) // clear the aggregator ad_clear_agg(aggregator); - if (select_new_active_agg) { + if (select_new_active_agg) ad_agg_selection_logic(__get_first_agg(port)); - } } else { pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", slave->dev->master->name); @@ -2091,11 +2079,10 @@ void bond_3ad_unbind_slave(struct slave *slave) prev_port = temp_port, temp_port = temp_port->next_port_in_aggregator) { if (temp_port == port) { // the aggregator found - detach the port from this aggregator - if (prev_port) { + if (prev_port) prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; - } else { + else temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; - } temp_aggregator->num_of_ports--; if (temp_aggregator->num_of_ports == 0) { select_new_active_agg = temp_aggregator->is_active; @@ -2137,14 +2124,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) read_lock(&bond->lock); - if (bond->kill_timers) { + if (bond->kill_timers) goto out; - } //check if there are any slaves - if (bond->slave_cnt == 0) { + if (bond->slave_cnt == 0) goto re_arm; - } // check if agg_select_timer timer after initialize is timed out if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { @@ -2177,9 +2162,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ad_tx_machine(port); // turn off the BEGIN bit, since we already handled it - if (port->sm_vars & AD_PORT_BEGIN) { + if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; - } } re_arm: @@ -2417,9 +2401,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) */ read_lock(&bond->lock); - if (!BOND_IS_OK(bond)) { + if (!BOND_IS_OK(bond)) goto out; - } if (bond_3ad_get_active_agg_info(bond, &ad_info)) { pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", @@ -2443,9 +2426,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) if (agg && (agg->aggregator_identifier == agg_id)) { slave_agg_no--; - if (slave_agg_no < 0) { + if (slave_agg_no < 0) break; - } } } @@ -2461,9 +2443,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) int slave_agg_id = 0; struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; - if (agg) { + if (agg) slave_agg_id = agg->aggregator_identifier; - } if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); -- cgit v1.2.3 From 106e4c26b1529e559d1aae777f11b4f8f7bafc26 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 12:45:14 +0200 Subject: tproxy: kick out TIME_WAIT sockets in case a new connection comes in with the same tuple Without tproxy redirections an incoming SYN kicks out conflicting TIME_WAIT sockets, in order to handle clients that reuse ports within the TIME_WAIT period. The same mechanism didn't work in case TProxy is involved in finding the proper socket, as the time_wait processing code looked up the listening socket assuming that the listener addr/port matches those of the established connection. This is not the case with TProxy as the listener addr/port is possibly changed with the tproxy rule. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_tproxy_core.h | 6 ++- net/netfilter/nf_tproxy_core.c | 29 +++++++++++---- net/netfilter/xt_TPROXY.c | 68 +++++++++++++++++++++++++++++++--- net/netfilter/xt_socket.c | 2 +- 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 208b46f4d6d2..b3a8942a4e6a 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h @@ -8,12 +8,16 @@ #include #include +#define NFT_LOOKUP_ANY 0 +#define NFT_LOOKUP_LISTENER 1 +#define NFT_LOOKUP_ESTABLISHED 2 + /* look up and get a reference to a matching socket */ extern struct sock * nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, const __be32 saddr, const __be32 daddr, const __be16 sport, const __be16 dport, - const struct net_device *in, bool listening); + const struct net_device *in, int lookup_type); static inline void nf_tproxy_put_sock(struct sock *sk) diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 5490fc37c92d..8589e5e08115 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c @@ -22,21 +22,34 @@ struct sock * nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, const __be32 saddr, const __be32 daddr, const __be16 sport, const __be16 dport, - const struct net_device *in, bool listening_only) + const struct net_device *in, int lookup_type) { struct sock *sk; /* look up socket */ switch (protocol) { case IPPROTO_TCP: - if (listening_only) - sk = __inet_lookup_listener(net, &tcp_hashinfo, - daddr, ntohs(dport), - in->ifindex); - else + switch (lookup_type) { + case NFT_LOOKUP_ANY: sk = __inet_lookup(net, &tcp_hashinfo, saddr, sport, daddr, dport, in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet_lookup_listener(net, &tcp_hashinfo, + daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_ESTABLISHED: + sk = inet_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } break; case IPPROTO_UDP: sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, @@ -47,8 +60,8 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, sk = NULL; } - pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n", - protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk); + pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n", + protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk); return sk; } diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index 21bb2aff6b8f..e0b6900a92c1 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -24,6 +24,57 @@ #include #include +/** + * tproxy_handle_time_wait() - handle TCP TIME_WAIT reopen redirections + * @skb: The skb being processed. + * @par: Iptables target parameters. + * @sk: The TIME_WAIT TCP socket found by the lookup. + * + * We have to handle SYN packets arriving to TIME_WAIT sockets + * differently: instead of reopening the connection we should rather + * redirect the new connection to the proxy if there's a listener + * socket present. + * + * tproxy_handle_time_wait() consumes the socket reference passed in. + * + * Returns the listener socket if there's one, the TIME_WAIT socket if + * no such listener is found, or NULL if the TCP header is incomplete. + */ +static struct sock * +tproxy_handle_time_wait(struct sk_buff *skb, const struct xt_action_param *par, struct sock *sk) +{ + const struct iphdr *iph = ip_hdr(skb); + const struct xt_tproxy_target_info *tgi = par->targinfo; + struct tcphdr _hdr, *hp; + + hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr); + if (hp == NULL) { + inet_twsk_put(inet_twsk(sk)); + return NULL; + } + + if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { + /* SYN to a TIME_WAIT socket, we'd rather redirect it + * to a listener socket if there's one */ + struct sock *sk2; + + sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, + hp->source, tgi->lport ? tgi->lport : hp->dest, + par->in, NFT_LOOKUP_LISTENER); + if (sk2) { + /* yeah, there's one, let's kill the TIME_WAIT + * socket and redirect to the listener + */ + inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); + inet_twsk_put(inet_twsk(sk)); + sk = sk2; + } + } + + return sk; +} + static unsigned int tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) { @@ -37,11 +88,18 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) return NF_DROP; sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, - tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, - tgi->lport ? tgi->lport : hp->dest, - par->in, true); + iph->saddr, iph->daddr, + hp->source, hp->dest, + par->in, NFT_LOOKUP_ESTABLISHED); + + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ + if (sk && sk->sk_state == TCP_TIME_WAIT) + sk = tproxy_handle_time_wait(skb, par, sk); + else if (!sk) + sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, + hp->source, tgi->lport ? tgi->lport : hp->dest, + par->in, NFT_LOOKUP_LISTENER); /* NOTE: assign_sock consumes our sk reference */ if (sk && nf_tproxy_assign_sock(skb, sk)) { diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 1ca89908cbad..266faa0a2fbf 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -142,7 +142,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, #endif sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol, - saddr, daddr, sport, dport, par->in, false); + saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); if (sk != NULL) { bool wildcard; bool transparent = true; -- cgit v1.2.3 From 6006db84a91838813cdad8a6622a4e39efe9ea47 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 12:47:34 +0200 Subject: tproxy: add lookup type checks for UDP in nf_tproxy_get_sock_v4() Also, inline this function as the lookup_type is always a literal and inlining removes branches performed at runtime. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_tproxy_core.h | 116 ++++++++++++++++++++++++++++++++- net/netfilter/nf_tproxy_core.c | 48 -------------- 2 files changed, 114 insertions(+), 50 deletions(-) diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index b3a8942a4e6a..1027d7f901a0 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h @@ -13,11 +13,123 @@ #define NFT_LOOKUP_ESTABLISHED 2 /* look up and get a reference to a matching socket */ -extern struct sock * + + +/* This function is used by the 'TPROXY' target and the 'socket' + * match. The following lookups are supported: + * + * Explicit TProxy target rule + * =========================== + * + * This is used when the user wants to intercept a connection matching + * an explicit iptables rule. In this case the sockets are assumed + * matching in preference order: + * + * - match: if there's a fully established connection matching the + * _packet_ tuple, it is returned, assuming the redirection + * already took place and we process a packet belonging to an + * established connection + * + * - match: if there's a listening socket matching the redirection + * (e.g. on-port & on-ip of the connection), it is returned, + * regardless if it was bound to 0.0.0.0 or an explicit + * address. The reasoning is that if there's an explicit rule, it + * does not really matter if the listener is bound to an interface + * or to 0. The user already stated that he wants redirection + * (since he added the rule). + * + * "socket" match based redirection (no specific rule) + * =================================================== + * + * There are connections with dynamic endpoints (e.g. FTP data + * connection) that the user is unable to add explicit rules + * for. These are taken care of by a generic "socket" rule. It is + * assumed that the proxy application is trusted to open such + * connections without explicit iptables rule (except of course the + * generic 'socket' rule). In this case the following sockets are + * matched in preference order: + * + * - match: if there's a fully established connection matching the + * _packet_ tuple + * + * - match: if there's a non-zero bound listener (possibly with a + * non-local address) We don't accept zero-bound listeners, since + * then local services could intercept traffic going through the + * box. + * + * Please note that there's an overlap between what a TPROXY target + * and a socket match will match. Normally if you have both rules the + * "socket" match will be the first one, effectively all packets + * belonging to established connections going through that one. + */ +static inline struct sock * nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, const __be32 saddr, const __be32 daddr, const __be16 sport, const __be16 dport, - const struct net_device *in, int lookup_type); + const struct net_device *in, int lookup_type) +{ + struct sock *sk; + + /* look up socket */ + switch (protocol) { + case IPPROTO_TCP: + switch (lookup_type) { + case NFT_LOOKUP_ANY: + sk = __inet_lookup(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet_lookup_listener(net, &tcp_hashinfo, + daddr, dport, + in->ifindex); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + + break; + case NFT_LOOKUP_ESTABLISHED: + sk = inet_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } + break; + case IPPROTO_UDP: + sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, + in->ifindex); + if (sk && lookup_type != NFT_LOOKUP_ANY) { + int connected = (sk->sk_state == TCP_ESTABLISHED); + int wildcard = (inet_sk(sk)->inet_rcv_saddr == 0); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type == NFT_LOOKUP_LISTENER && connected)) { + sock_put(sk); + sk = NULL; + } + } + break; + default: + WARN_ON(1); + sk = NULL; + } + + pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n", + protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk); + + return sk; +} + static inline void nf_tproxy_put_sock(struct sock *sk) diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 8589e5e08115..db655638d76d 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c @@ -18,54 +18,6 @@ #include #include -struct sock * -nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, - const __be32 saddr, const __be32 daddr, - const __be16 sport, const __be16 dport, - const struct net_device *in, int lookup_type) -{ - struct sock *sk; - - /* look up socket */ - switch (protocol) { - case IPPROTO_TCP: - switch (lookup_type) { - case NFT_LOOKUP_ANY: - sk = __inet_lookup(net, &tcp_hashinfo, - saddr, sport, daddr, dport, - in->ifindex); - break; - case NFT_LOOKUP_LISTENER: - sk = inet_lookup_listener(net, &tcp_hashinfo, - daddr, dport, - in->ifindex); - break; - case NFT_LOOKUP_ESTABLISHED: - sk = inet_lookup_established(net, &tcp_hashinfo, - saddr, sport, daddr, dport, - in->ifindex); - break; - default: - WARN_ON(1); - sk = NULL; - break; - } - break; - case IPPROTO_UDP: - sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, - in->ifindex); - break; - default: - WARN_ON(1); - sk = NULL; - } - - pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n", - protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk); - - return sk; -} -EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4); static void nf_tproxy_destructor(struct sk_buff *skb) -- cgit v1.2.3 From c8a8684d5cfb0f110a962c93586630c0bf91ebc1 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 18 Oct 2010 14:10:40 +0000 Subject: jme: Fix PHY power-off error Adding phy_on in opposition to phy_off. Signed-off-by: Guo-Fu Tseng Cc: Signed-off-by: David S. Miller --- drivers/net/jme.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index c04c096bc6a9..e04f180965ae 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -1574,6 +1574,16 @@ jme_free_irq(struct jme_adapter *jme) } } +static inline void +jme_phy_on(struct jme_adapter *jme) +{ + u32 bmcr; + + bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); + bmcr &= ~BMCR_PDOWN; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); +} + static int jme_open(struct net_device *netdev) { @@ -1594,10 +1604,12 @@ jme_open(struct net_device *netdev) jme_start_irq(jme); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_reset_link(jme); @@ -3005,10 +3017,12 @@ jme_resume(struct pci_dev *pdev) jme_clear_pm(jme); pci_restore_state(pdev); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_start_irq(jme); netif_device_attach(netdev); -- cgit v1.2.3 From 3ee94018a9f49ca98e3f77f54a769c784115dbb8 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 18 Oct 2010 14:10:41 +0000 Subject: jme: Add comment in jme_set_settings Explains what `fdc` variable is for. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index e04f180965ae..0ea0da32d7d8 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2394,6 +2394,10 @@ jme_set_settings(struct net_device *netdev, if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE) return -EINVAL; + /* + * Check If user changed duplex only while force_media. + * Hardware would not generate link change interrupt. + */ if (jme->mii_if.force_media && ecmd->autoneg != AUTONEG_ENABLE && (jme->mii_if.full_duplex != ecmd->duplex)) @@ -2403,10 +2407,9 @@ jme_set_settings(struct net_device *netdev, rc = mii_ethtool_sset(&(jme->mii_if), ecmd); spin_unlock_bh(&jme->phy_lock); - if (!rc && fdc) - jme_reset_link(jme); - if (!rc) { + if (fdc) + jme_reset_link(jme); set_bit(JME_FLAG_SSET, &jme->flags); jme->old_ecmd = *ecmd; } -- cgit v1.2.3 From ea192aa89c3b26d56113e70c72238f6951d4097f Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 18 Oct 2010 14:10:42 +0000 Subject: jme: Prevent possible read re-order error Adding read memory barrier in between flag reading and data reading of receive descriptors. This prevents the data being read before hardware complete writing informations. Reported-by: Stefan Hajnoczi Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 0ea0da32d7d8..095f8998714f 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -989,6 +989,7 @@ jme_process_receive(struct jme_adapter *jme, int limit) goto out; --limit; + rmb(); desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; if (unlikely(desccnt > 1 || -- cgit v1.2.3 From 334fbbb747c978ae9171b9c29dfcea881f4a8d57 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 18 Oct 2010 14:10:43 +0000 Subject: jme: Adding mii-tool support Adding mii-tool support for some distribution only have mii-tool installed by default. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 095f8998714f..c34c70f84ee3 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2411,8 +2411,37 @@ jme_set_settings(struct net_device *netdev, if (!rc) { if (fdc) jme_reset_link(jme); - set_bit(JME_FLAG_SSET, &jme->flags); jme->old_ecmd = *ecmd; + set_bit(JME_FLAG_SSET, &jme->flags); + } + + return rc; +} + +static int +jme_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +{ + int rc; + struct jme_adapter *jme = netdev_priv(netdev); + struct mii_ioctl_data *mii_data = if_mii(rq); + unsigned int duplex_chg; + + if (cmd == SIOCSMIIREG) { + u16 val = mii_data->val_in; + if (!(val & (BMCR_RESET|BMCR_ANENABLE)) && + (val & BMCR_SPEED1000)) + return -EINVAL; + } + + spin_lock_bh(&jme->phy_lock); + rc = generic_mii_ioctl(&jme->mii_if, mii_data, cmd, &duplex_chg); + spin_unlock_bh(&jme->phy_lock); + + if (!rc && (cmd == SIOCSMIIREG)) { + if (duplex_chg) + jme_reset_link(jme); + jme_get_settings(netdev, &jme->old_ecmd); + set_bit(JME_FLAG_SSET, &jme->flags); } return rc; @@ -2692,6 +2721,7 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_open = jme_open, .ndo_stop = jme_close, .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = jme_ioctl, .ndo_start_xmit = jme_start_xmit, .ndo_set_mac_address = jme_set_macaddr, .ndo_set_multicast_list = jme_set_multi, @@ -2883,6 +2913,8 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.supports_gmii = true; else jme->mii_if.supports_gmii = false; + jme->mii_if.phy_id_mask = 0x1F; + jme->mii_if.reg_num_mask = 0x1F; jme->mii_if.mdio_read = jme_mdio_read; jme->mii_if.mdio_write = jme_mdio_write; -- cgit v1.2.3 From e47dfcd81edb7c6065fd2219c818b3b526bd624d Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Mon, 18 Oct 2010 14:10:44 +0000 Subject: jme: Advance version number Advance version number and update copyright info Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 1 + drivers/net/jme.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index c34c70f84ee3..d7a975ee2add 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -3,6 +3,7 @@ * * Copyright 2008 JMicron Technology Corporation * http://www.jmicron.com/ + * Copyright (c) 2009 - 2010 Guo-Fu Tseng * * Author: Guo-Fu Tseng * diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 1360f68861b8..eac09264bf2a 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -3,6 +3,7 @@ * * Copyright 2008 JMicron Technology Corporation * http://www.jmicron.com/ + * Copyright (c) 2009 - 2010 Guo-Fu Tseng * * Author: Guo-Fu Tseng * @@ -25,7 +26,7 @@ #define __JME_H_INCLUDED__ #define DRV_NAME "jme" -#define DRV_VERSION "1.0.6" +#define DRV_VERSION "1.0.7" #define PFX DRV_NAME ": " #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 -- cgit v1.2.3 From 3a338cbb8bb46a6b86f4dca54bf73b9c78751659 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 20 Oct 2010 22:59:40 +0000 Subject: ixgbe: update copyright info Update copyright notice Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_mbx.c | 2 +- drivers/net/ixgbe/ixgbe_mbx.h | 2 +- drivers/net/ixgbe/ixgbe_sriov.c | 2 +- drivers/net/ixgbe/ixgbe_sriov.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index 435e0281e1f8..471f0f2cdb98 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index c5ae4b4da83a..7e0d08ff5b53 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index a6b720ae7fea..5428153af8f3 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h index 9a424bb688c0..49dc14debef7 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ixgbe/ixgbe_sriov.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3 From de1036b1cea147c5049c65f5bd26fb451f1624cd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Oct 2010 23:00:04 +0000 Subject: ixgbe: fix stats handling Current ixgbe stats have following problems : - Not 64 bit safe (on 32bit arches) - Not safe in ixgbe_clean_rx_irq() : All cpus dirty a common location (netdev->stats.rx_bytes & netdev->stats.rx_packets) without proper synchronization. This slow down a bit multiqueue operations, and possibly miss some updates. Fixes : Implement ndo_get_stats64() method to provide accurate 64bit rx|tx bytes/packets counters, using 64bit safe infrastructure. ixgbe_get_ethtool_stats() also use this infrastructure to provide 64bit safe counters. Signed-off-by: Eric Dumazet Acked-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 3 ++- drivers/net/ixgbe/ixgbe_ethtool.c | 29 ++++++++++++++++------------ drivers/net/ixgbe/ixgbe_main.c | 40 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 5e38de79fbbd..ed8703cfffb7 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -182,8 +182,9 @@ struct ixgbe_ring { */ struct ixgbe_queue_stats stats; - unsigned long reinit_state; + struct u64_stats_sync syncp; int numa_node; + unsigned long reinit_state; u64 rsc_count; /* stat for coalesced packets */ u64 rsc_flush; /* stats for flushed packets */ u32 restart_queue; /* track tx queue restarts */ diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index dbfd62fd40eb..3dc731c22ff2 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -999,12 +999,11 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u64 *queue_stat; - int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *net_stats; - int j, k; - int i; + unsigned int start; + struct ixgbe_ring *ring; + int i, j; char *p = NULL; ixgbe_update_stats(adapter); @@ -1025,16 +1024,22 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { - queue_stat = (u64 *)&adapter->tx_ring[j]->stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; + ring = adapter->tx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + i += 2; } for (j = 0; j < adapter->num_rx_queues; j++) { - queue_stat = (u64 *)&adapter->rx_ring[j]->stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; + ring = adapter->rx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + i += 2; } if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 56f6b80e1084..f85631263af8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -824,8 +824,10 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); tx_ring->stats.packets += total_packets; tx_ring->stats.bytes += total_bytes; + u64_stats_update_end(&tx_ring->syncp); return count < tx_ring->work_limit; } @@ -1168,7 +1170,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, int *work_done, int work_to_do) { struct ixgbe_adapter *adapter = q_vector->adapter; - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; @@ -1294,8 +1295,10 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_ring->rsc_count++; rx_ring->rsc_flush++; } + u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets++; rx_ring->stats.bytes += skb->len; + u64_stats_update_end(&rx_ring->syncp); } else { if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { rx_buffer_info->skb = next_buffer->skb; @@ -1371,8 +1374,6 @@ next_desc: rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - netdev->stats.rx_bytes += total_rx_bytes; - netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -6542,6 +6543,38 @@ static void ixgbe_netpoll(struct net_device *netdev) } #endif +static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; + + /* accurate rx/tx bytes/packets stats */ + dev_txq_stats_fold(netdev, stats); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + u64 bytes, packets; + unsigned int start; + + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + + /* following stats updated by ixgbe_watchdog_task() */ + stats->multicast = netdev->stats.multicast; + stats->rx_errors = netdev->stats.rx_errors; + stats->rx_length_errors = netdev->stats.rx_length_errors; + stats->rx_crc_errors = netdev->stats.rx_crc_errors; + stats->rx_missed_errors = netdev->stats.rx_missed_errors; + return stats; +} + + static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, @@ -6560,6 +6593,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, .ndo_get_vf_config = ixgbe_ndo_get_vf_config, + .ndo_get_stats64 = ixgbe_get_stats64, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif -- cgit v1.2.3 From 27ab76065c0c6734ea98ccc7080046a72d98455b Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Wed, 20 Oct 2010 23:00:30 +0000 Subject: ixgbe: add a refcnt when turning on/off FCoE offload capability The FCoE offload is enabled/disabled per adapter, but upper FCoE protocol stack could have multiple FCoE instances created on the same physical network interface, e.g., FCoE on multiple VLAN interfaces on the same physical network interface. In this case we want to turn on FCoE offload at the first request from ndo_fcoe_enable() but only turn off FCoE offload at the very last call to ndo_fcoe_disable(). This is fixed by adding a refcnt in the per adapter FCoE structure and tear down FCoE offload when refcnt decrements to zero. Signed-off-by: Yi Zou Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_fcoe.c | 6 ++++++ drivers/net/ixgbe/ixgbe_fcoe.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 2f1de8b90f9e..05efa6a8ce8e 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -604,11 +604,13 @@ int ixgbe_fcoe_enable(struct net_device *netdev) { int rc = -EINVAL; struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_fcoe *fcoe = &adapter->fcoe; if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) goto out_enable; + atomic_inc(&fcoe->refcnt); if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) goto out_enable; @@ -648,6 +650,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev) { int rc = -EINVAL; struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_fcoe *fcoe = &adapter->fcoe; if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) goto out_disable; @@ -655,6 +658,9 @@ int ixgbe_fcoe_disable(struct net_device *netdev) if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) goto out_disable; + if (!atomic_dec_and_test(&fcoe->refcnt)) + goto out_disable; + e_info(drv, "Disabling FCoE offload features.\n"); netdev->features &= ~NETIF_F_FCOE_CRC; netdev->features &= ~NETIF_F_FSO; diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index abf4b2b3f252..4bc2c551c8db 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -66,6 +66,7 @@ struct ixgbe_fcoe { u8 tc; u8 up; #endif + atomic_t refcnt; spinlock_t lock; struct pci_pool *pool; struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; -- cgit v1.2.3 From be8c648051048bc66fbca590d00f3e8543ec32af Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 21 Oct 2010 03:59:57 -0700 Subject: phy/marvell: fix 88e1121 support Commit c477d0447db08068a497e7beb892b2b2a7bff64b added support for RGMII rx/tx delays except that it ends up clearing rx/tx delays bit for modes differents that RGMII*ID. Due to this, ethernet is not working anymore on my guruplug server +. This patch is fixing that. Signed-off-by: Arnaud Patard Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index ed43c0016c64..e2afdce0a437 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -196,20 +196,27 @@ static int m88e1121_config_aneg(struct phy_device *phydev) MII_88E1121_PHY_MSCR_PAGE); if (err < 0) return err; - mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & - MII_88E1121_PHY_MSCR_DELAY_MASK; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | - MII_88E1121_PHY_MSCR_TX_DELAY); - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) - mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) - mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); - if (err < 0) - return err; + mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & + MII_88E1121_PHY_MSCR_DELAY_MASK; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | + MII_88E1121_PHY_MSCR_TX_DELAY); + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + + err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); + if (err < 0) + return err; + } phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); -- cgit v1.2.3 From d2ed817766987fd05e69b7da65d4861b38f1aa2a Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 21 Oct 2010 04:06:29 -0700 Subject: net/core: Allow tagged VLAN packets to flow through VETH devices. When there are VLANs on a VETH device, the packets being transmitted through the VETH device may be 4 bytes bigger than MTU. A check in dev_forward_skb did not take this into account and so dropped these packets. This patch is needed at least as far back as 2.6.34.7 and should be considered for -stable. Signed-off-by: Ben Greear Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 660dd41aaaa6..8e07109cc0ef 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1485,7 +1485,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) nf_reset(skb); if (!(dev->flags & IFF_UP) || - (skb->len > (dev->mtu + dev->hard_header_len))) { + (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN))) { kfree_skb(skb); return NET_RX_DROP; } -- cgit v1.2.3 From 093d282321daeb19c107e5f1f16d7f68484f3ade Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 13:06:43 +0200 Subject: tproxy: fix hash locking issue when using port redirection in __inet_inherit_port() When __inet_inherit_port() is called on a tproxy connection the wrong locks are held for the inet_bind_bucket it is added to. __inet_inherit_port() made an implicit assumption that the listener's port number (and thus its bind bucket). Unfortunately, if you're using the TPROXY target to redirect skbs to a transparent proxy that assumption is not true anymore and things break. This patch adds code to __inet_inherit_port() so that it can handle this case by looking up or creating a new bind bucket for the child socket and updates callers of __inet_inherit_port() to gracefully handle __inet_inherit_port() failing. Reported by and original patch from Stephen Buck . See http://marc.info/?t=128169268200001&r=1&w=2 for the original discussion. Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/inet_hashtables.h | 2 +- net/dccp/ipv4.c | 10 +++++++--- net/dccp/ipv6.c | 10 +++++++--- net/ipv4/inet_hashtables.c | 28 ++++++++++++++++++++++++++-- net/ipv4/tcp_ipv4.c | 10 +++++++--- net/ipv6/tcp_ipv6.c | 12 ++++++++---- 6 files changed, 56 insertions(+), 16 deletions(-) diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 74358d1b3f43..e9c2ed8af864 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -245,7 +245,7 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk) } /* Caller must disable local BH processing. */ -extern void __inet_inherit_port(struct sock *sk, struct sock *child); +extern int __inet_inherit_port(struct sock *sk, struct sock *child); extern void inet_put_port(struct sock *sk); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index d4a166f0f391..3f69ea114829 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -392,7 +392,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = dccp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto exit; + goto exit_nonewsk; sk_setup_caps(newsk, dst); @@ -409,16 +409,20 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, dccp_sync_mss(newsk, dst_mtu(dst)); + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto exit; + } __inet_hash_nolisten(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; exit_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +exit_nonewsk: + dst_release(dst); exit: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); - dst_release(dst); return NULL; } diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6e3f32575df7..dca711df9b60 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -564,7 +564,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, newsk = dccp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto out; + goto out_nonewsk; /* * No need to charge this sock to the relevant IPv6 refcnt debug socks @@ -632,18 +632,22 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; newinet->inet_rcv_saddr = LOOPBACK4_IPV6; + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto out; + } __inet6_hash(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; out_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +out_nonewsk: + dst_release(dst); out: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); if (opt != NULL && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); - dst_release(dst); return NULL; } diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index fb7ad5a21ff3..1b344f30b463 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -101,19 +101,43 @@ void inet_put_port(struct sock *sk) } EXPORT_SYMBOL(inet_put_port); -void __inet_inherit_port(struct sock *sk, struct sock *child) +int __inet_inherit_port(struct sock *sk, struct sock *child) { struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; - const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->inet_num, + unsigned short port = inet_sk(child)->inet_num; + const int bhash = inet_bhashfn(sock_net(sk), port, table->bhash_size); struct inet_bind_hashbucket *head = &table->bhash[bhash]; struct inet_bind_bucket *tb; spin_lock(&head->lock); tb = inet_csk(sk)->icsk_bind_hash; + if (tb->port != port) { + /* NOTE: using tproxy and redirecting skbs to a proxy + * on a different listener port breaks the assumption + * that the listener socket's icsk_bind_hash is the same + * as that of the child socket. We have to look up or + * create a new bind bucket for the child here. */ + struct hlist_node *node; + inet_bind_bucket_for_each(tb, node, &head->chain) { + if (net_eq(ib_net(tb), sock_net(sk)) && + tb->port == port) + break; + } + if (!node) { + tb = inet_bind_bucket_create(table->bind_bucket_cachep, + sock_net(sk), head, port); + if (!tb) { + spin_unlock(&head->lock); + return -ENOMEM; + } + } + } sk_add_bind_node(child, &tb->owners); inet_csk(child)->icsk_bind_hash = tb; spin_unlock(&head->lock); + + return 0; } EXPORT_SYMBOL_GPL(__inet_inherit_port); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a0232f3a358b..8f8527d41682 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1422,7 +1422,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = tcp_create_openreq_child(sk, req, skb); if (!newsk) - goto exit; + goto exit_nonewsk; newsk->sk_gso_type = SKB_GSO_TCPV4; sk_setup_caps(newsk, dst); @@ -1469,16 +1469,20 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, } #endif + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto exit; + } __inet_hash_nolisten(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; exit_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +exit_nonewsk: + dst_release(dst); exit: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); - dst_release(dst); return NULL; } EXPORT_SYMBOL(tcp_v4_syn_recv_sock); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fe6d40418c0b..ba5258ef1c57 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1409,7 +1409,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = tcp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto out; + goto out_nonewsk; /* * No need to charge this sock to the relevant IPv6 refcnt debug socks @@ -1497,18 +1497,22 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, } #endif + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto out; + } __inet6_hash(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; out_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); -out: - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); +out_nonewsk: if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); dst_release(dst); +out: + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); return NULL; } -- cgit v1.2.3 From 8c974438085d2c81b006daeaab8801eedbd19758 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 21 Oct 2010 01:06:15 +0000 Subject: Revert c6537d6742985da1fbf12ae26cde6a096fd35b5c Backout the tipc changes to the flags int he subscription message. These changees, while reasonable on the surface, interefere with user space ABI compatibility which is a no-no. This was part of the changes to fix the endianess issues in the TIPC protocol, which would be really nice to do but we need to do so in a way that is backwards compatible with user space. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- include/linux/tipc.h | 30 ++++++++++++++++++------------ net/tipc/subscr.c | 15 +++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/linux/tipc.h b/include/linux/tipc.h index 181c8d0e6f73..d10614b29d59 100644 --- a/include/linux/tipc.h +++ b/include/linux/tipc.h @@ -127,17 +127,23 @@ static inline unsigned int tipc_node(__u32 addr) * TIPC topology subscription service definitions */ -#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */ -#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */ -#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */ +#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ +#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ +#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ +#if 0 +/* The following filter options are not currently implemented */ +#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ +#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */ +#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */ +#endif #define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */ struct tipc_subscr { - struct tipc_name_seq seq; /* NBO. Name sequence of interest */ - __u32 timeout; /* NBO. Subscription duration (in ms) */ - __u32 filter; /* NBO. Bitmask of filter options */ - char usr_handle[8]; /* Opaque. Available for subscriber use */ + struct tipc_name_seq seq; /* name sequence of interest */ + __u32 timeout; /* subscription duration (in ms) */ + __u32 filter; /* bitmask of filter options */ + char usr_handle[8]; /* available for subscriber use */ }; #define TIPC_PUBLISHED 1 /* publication event */ @@ -145,11 +151,11 @@ struct tipc_subscr { #define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ struct tipc_event { - __u32 event; /* NBO. Event type, as defined above */ - __u32 found_lower; /* NBO. Matching name seq instances */ - __u32 found_upper; /* " " " " " */ - struct tipc_portid port; /* NBO. Associated port */ - struct tipc_subscr s; /* Original, associated subscription */ + __u32 event; /* event type */ + __u32 found_lower; /* matching name seq instances */ + __u32 found_upper; /* " " " " */ + struct tipc_portid port; /* associated port */ + struct tipc_subscr s; /* associated subscription */ }; /* diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ab6eab4c45e2..ff123e56114a 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -274,7 +274,7 @@ static void subscr_cancel(struct tipc_subscr *s, { struct subscription *sub; struct subscription *sub_temp; - __u32 type, lower, upper, timeout, filter; + __u32 type, lower, upper; int found = 0; /* Find first matching subscription, exit if not found */ @@ -282,18 +282,12 @@ static void subscr_cancel(struct tipc_subscr *s, type = ntohl(s->seq.type); lower = ntohl(s->seq.lower); upper = ntohl(s->seq.upper); - timeout = ntohl(s->timeout); - filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL; list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, subscription_list) { if ((type == sub->seq.type) && (lower == sub->seq.lower) && - (upper == sub->seq.upper) && - (timeout == sub->timeout) && - (filter == sub->filter) && - !memcmp(s->usr_handle,sub->evt.s.usr_handle, - sizeof(s->usr_handle)) ){ + (upper == sub->seq.upper)) { found = 1; break; } @@ -310,7 +304,7 @@ static void subscr_cancel(struct tipc_subscr *s, k_term_timer(&sub->timer); spin_lock_bh(subscriber->lock); } - dbg("Cancel: removing sub %u,%u,%u from subscriber %p list\n", + dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); subscr_del(sub); } @@ -358,7 +352,8 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, sub->seq.upper = ntohl(s->seq.upper); sub->timeout = ntohl(s->timeout); sub->filter = ntohl(s->filter); - if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) || + if ((!(sub->filter & TIPC_SUB_PORTS) == + !(sub->filter & TIPC_SUB_SERVICE)) || (sub->seq.lower > sub->seq.upper)) { warn("Subscription rejected, illegal request\n"); kfree(sub); -- cgit v1.2.3 From db5a753bf198ef7a50e17d2ff358adf37efe8648 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 21 Oct 2010 01:06:16 +0000 Subject: Revert d88dca79d3852a3623f606f781e013d61486828a TIPC needs to have its endianess issues fixed. Unfortunately, the format of a subscriber message is passed in directly from user space, so requiring this message to be in network byte order breaks user space ABI. Revert this change until such time as we can determine how to do this in a backwards compatible manner. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- net/tipc/subscr.c | 57 ++++++++++++++++++++++++++++++++++--------------------- net/tipc/subscr.h | 2 ++ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ff123e56114a..ac91f0dfa144 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -75,6 +75,19 @@ struct top_srv { static struct top_srv topsrv = { 0 }; +/** + * htohl - convert value to endianness used by destination + * @in: value to convert + * @swap: non-zero if endianness must be reversed + * + * Returns converted value + */ + +static u32 htohl(u32 in, int swap) +{ + return swap ? swab32(in) : in; +} + /** * subscr_send_event - send a message containing a tipc_event to the subscriber * @@ -94,11 +107,11 @@ static void subscr_send_event(struct subscription *sub, msg_sect.iov_base = (void *)&sub->evt; msg_sect.iov_len = sizeof(struct tipc_event); - sub->evt.event = htonl(event); - sub->evt.found_lower = htonl(found_lower); - sub->evt.found_upper = htonl(found_upper); - sub->evt.port.ref = htonl(port_ref); - sub->evt.port.node = htonl(node); + sub->evt.event = htohl(event, sub->swap); + sub->evt.found_lower = htohl(found_lower, sub->swap); + sub->evt.found_upper = htohl(found_upper, sub->swap); + sub->evt.port.ref = htohl(port_ref, sub->swap); + sub->evt.port.node = htohl(node, sub->swap); tipc_send(sub->server_ref, 1, &msg_sect); } @@ -274,23 +287,16 @@ static void subscr_cancel(struct tipc_subscr *s, { struct subscription *sub; struct subscription *sub_temp; - __u32 type, lower, upper; int found = 0; /* Find first matching subscription, exit if not found */ - type = ntohl(s->seq.type); - lower = ntohl(s->seq.lower); - upper = ntohl(s->seq.upper); - list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, subscription_list) { - if ((type == sub->seq.type) && - (lower == sub->seq.lower) && - (upper == sub->seq.upper)) { - found = 1; - break; - } + if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { + found = 1; + break; + } } if (!found) return; @@ -319,10 +325,16 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, struct subscriber *subscriber) { struct subscription *sub; + int swap; + + /* Determine subscriber's endianness */ + + swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); /* Detect & process a subscription cancellation request */ - if (ntohl(s->filter) & TIPC_SUB_CANCEL) { + if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { + s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); subscr_cancel(s, subscriber); return NULL; } @@ -347,11 +359,11 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, /* Initialize subscription object */ - sub->seq.type = ntohl(s->seq.type); - sub->seq.lower = ntohl(s->seq.lower); - sub->seq.upper = ntohl(s->seq.upper); - sub->timeout = ntohl(s->timeout); - sub->filter = ntohl(s->filter); + sub->seq.type = htohl(s->seq.type, swap); + sub->seq.lower = htohl(s->seq.lower, swap); + sub->seq.upper = htohl(s->seq.upper, swap); + sub->timeout = htohl(s->timeout, swap); + sub->filter = htohl(s->filter, swap); if ((!(sub->filter & TIPC_SUB_PORTS) == !(sub->filter & TIPC_SUB_SERVICE)) || (sub->seq.lower > sub->seq.upper)) { @@ -364,6 +376,7 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, INIT_LIST_HEAD(&sub->nameseq_list); list_add(&sub->subscription_list, &subscriber->subscription_list); sub->server_ref = subscriber->port_ref; + sub->swap = swap; memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); atomic_inc(&topsrv.subscription_count); if (sub->timeout != TIPC_WAIT_FOREVER) { diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index c20f496d95b2..45d89bf4d202 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h @@ -53,6 +53,7 @@ typedef void (*tipc_subscr_event) (struct subscription *sub, * @nameseq_list: adjacent subscriptions in name sequence's subscription list * @subscription_list: adjacent subscriptions in subscriber's subscription list * @server_ref: object reference of server port associated with subscription + * @swap: indicates if subscriber uses opposite endianness in its messages * @evt: template for events generated by subscription */ @@ -65,6 +66,7 @@ struct subscription { struct list_head nameseq_list; struct list_head subscription_list; u32 server_ref; + int swap; struct tipc_event evt; }; -- cgit v1.2.3 From a5c30b349b872aa2ac13babbd5ceb26737f17e95 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Oct 2010 06:04:42 +0000 Subject: net/neighbour: cancel_delayed_work() + flush_scheduled_work() -> cancel_delayed_work_sync() flush_scheduled_work() is going away. Prepare for it. Signed-off-by: Tejun Heo Signed-off-by: David S. Miller --- net/core/neighbour.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b165b96355bf..8cc8f9a79db9 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1588,8 +1588,7 @@ int neigh_table_clear(struct neigh_table *tbl) struct neigh_table **tp; /* It is not clean... Fix it to unload IPv6 module safely */ - cancel_delayed_work(&tbl->gc_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&tbl->gc_work); del_timer_sync(&tbl->proxy_timer); pneigh_queue_purge(&tbl->proxy_queue); neigh_ifdown(tbl, NULL); -- cgit v1.2.3 From 1e253c3b8a1aeed51eef6fc366812f219b97de65 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Mon, 18 Oct 2010 16:09:35 +0000 Subject: bridge: Forward reserved group addresses if !STP Make all frames sent to reserved group MAC addresses (01:80:c2:00:00:00 to 01:80:c2:00:00:0f) be forwarded if STP is disabled. This enables forwarding EAPOL frames, among other things. Signed-off-by: Benjamin Poirier Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 6d04cfdf4541..25207a1f182b 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -159,7 +159,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) goto drop; /* If STP is turned off, then forward */ - if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) + if (p->br->stp_enabled == BR_NO_STP) goto forward; if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, -- cgit v1.2.3 From b003f4e171304234eae9cc11c9fd7f1cbaaf0d6b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 17 Oct 2010 05:18:15 +0000 Subject: CAPI: Silence lockdep warning on get_capi_appl_by_nr usage As long as we hold capi_controller_lock, we can safely access capi_applications without RCU protection as no one can modify the application list underneath us. Introduce an RCU-free __get_capi_appl_by_nr for this purpose. This silences lockdep warnings on suspicious rcu_dereference usage. Signed-off-by: Jan Kiszka Signed-off-by: David S. Miller --- drivers/isdn/capi/kcapi.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index b054494df846..3acf94cc5acd 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -98,6 +98,16 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) return capi_controller[contr - 1]; } +static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) +{ + lockdep_assert_held(&capi_controller_lock); + + if (applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return capi_applications[applid - 1]; +} + static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) { if (applid - 1 >= CAPI_MAXAPPL) @@ -185,10 +195,9 @@ static void notify_up(u32 contr) ctr->state = CAPI_CTR_RUNNING; for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { - ap = get_capi_appl_by_nr(applid); - if (!ap) - continue; - register_appl(ctr, applid, &ap->rparam); + ap = __get_capi_appl_by_nr(applid); + if (ap) + register_appl(ctr, applid, &ap->rparam); } wake_up_interruptible_all(&ctr->state_wait_queue); @@ -215,7 +224,7 @@ static void ctr_down(struct capi_ctr *ctr, int new_state) memset(ctr->serial, 0, sizeof(ctr->serial)); for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { - ap = get_capi_appl_by_nr(applid); + ap = __get_capi_appl_by_nr(applid); if (ap) capi_ctr_put(ctr); } -- cgit v1.2.3 From 31b9c19bfe32bed7fdf80cd0b1aa9d0f0569844a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 05:39:18 +0000 Subject: cxgb4: function namespace cleanup (v3) Make functions only used in one file local. Remove lots of dead code, relating to unsupported functions in mainline driver like RSS, IPv6, and TCP offload. Signed-off-by: Stephen Hemminger Acked-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 15 -- drivers/net/cxgb4/cxgb4_main.c | 68 +-------- drivers/net/cxgb4/cxgb4_uld.h | 6 - drivers/net/cxgb4/l2t.c | 34 ----- drivers/net/cxgb4/l2t.h | 3 - drivers/net/cxgb4/t4_hw.c | 332 ----------------------------------------- 6 files changed, 3 insertions(+), 455 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 3ece9f5069fa..eaa49e4119f1 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -592,7 +592,6 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id); void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat); void *t4_alloc_mem(size_t size); -void t4_free_mem(void *addr); void t4_free_sge_resources(struct adapter *adap); irq_handler_t t4_intr_handler(struct adapter *adap); @@ -651,7 +650,6 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, void t4_intr_enable(struct adapter *adapter); void t4_intr_disable(struct adapter *adapter); -void t4_intr_clear(struct adapter *adapter); int t4_slow_intr_handler(struct adapter *adapter); int t4_wait_dev_ready(struct adapter *adap); @@ -664,24 +662,16 @@ int t4_check_fw_version(struct adapter *adapter); int t4_prep_adapter(struct adapter *adapter); int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); void t4_fatal_err(struct adapter *adapter); -int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp, - int filter_index, int enable); -void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp, - int filter_index, int *enabled); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, unsigned int flags); -int t4_read_rss(struct adapter *adapter, u16 *entries); int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity); int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity); void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); -void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p); - void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); -void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st); void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, struct tp_tcp_stats *v6); void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, @@ -711,8 +701,6 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, unsigned int *rss_size); -int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, - unsigned int vf, unsigned int viid); int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, int mtu, int promisc, int all_multi, int bcast, int vlanex, bool sleep_ok); @@ -731,9 +719,6 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 val); -int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, - unsigned int pf, unsigned int vf, unsigned int iqid, - unsigned int fl0id, unsigned int fl1id); int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 22169a73b7f7..930bd075a43e 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -880,7 +880,7 @@ void *t4_alloc_mem(size_t size) /* * Free memory allocated through alloc_mem(). */ -void t4_free_mem(void *addr) +static void t4_free_mem(void *addr) { if (is_vmalloc_addr(addr)) vfree(addr); @@ -2206,8 +2206,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan, * Queue a TID release request and if necessary schedule a work queue to * process it. */ -void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, - unsigned int tid) +static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, + unsigned int tid) { void **p = &t->tid_tab[tid]; struct adapter *adap = container_of(t, struct adapter, tids); @@ -2222,7 +2222,6 @@ void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, } spin_unlock_bh(&adap->tid_release_lock); } -EXPORT_SYMBOL(cxgb4_queue_tid_release); /* * Process the list of pending TID release requests. @@ -2354,48 +2353,6 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid, } EXPORT_SYMBOL(cxgb4_create_server); -/** - * cxgb4_create_server6 - create an IPv6 server - * @dev: the device - * @stid: the server TID - * @sip: local IPv6 address to bind server to - * @sport: the server's TCP port - * @queue: queue to direct messages from this server to - * - * Create an IPv6 server for the given port and address. - * Returns <0 on error and one of the %NET_XMIT_* values on success. - */ -int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, - const struct in6_addr *sip, __be16 sport, - unsigned int queue) -{ - unsigned int chan; - struct sk_buff *skb; - struct adapter *adap; - struct cpl_pass_open_req6 *req; - - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - return -ENOMEM; - - adap = netdev2adap(dev); - req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req)); - INIT_TP_WR(req, 0); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid)); - req->local_port = sport; - req->peer_port = htons(0); - req->local_ip_hi = *(__be64 *)(sip->s6_addr); - req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8); - req->peer_ip_hi = cpu_to_be64(0); - req->peer_ip_lo = cpu_to_be64(0); - chan = rxq_to_chan(&adap->sge, queue); - req->opt0 = cpu_to_be64(TX_CHAN(chan)); - req->opt1 = cpu_to_be64(CONN_POLICY_ASK | - SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); - return t4_mgmt_tx(adap, skb); -} -EXPORT_SYMBOL(cxgb4_create_server6); - /** * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU * @mtus: the HW MTU table @@ -2455,25 +2412,6 @@ unsigned int cxgb4_port_idx(const struct net_device *dev) } EXPORT_SYMBOL(cxgb4_port_idx); -/** - * cxgb4_netdev_by_hwid - return the net device of a HW port - * @pdev: identifies the adapter - * @id: the HW port id - * - * Return the net device associated with the interface with the given HW - * id. - */ -struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id) -{ - const struct adapter *adap = pci_get_drvdata(pdev); - - if (!adap || id >= NCHAN) - return NULL; - id = adap->chan_map[id]; - return id < MAX_NPORTS ? adap->port[id] : NULL; -} -EXPORT_SYMBOL(cxgb4_netdev_by_hwid); - void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, struct tp_tcp_stats *v6) { diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h index 85d74e751ce0..1b48c0170145 100644 --- a/drivers/net/cxgb4/cxgb4_uld.h +++ b/drivers/net/cxgb4/cxgb4_uld.h @@ -139,16 +139,11 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); void cxgb4_free_atid(struct tid_info *t, unsigned int atid); void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); -void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, - unsigned int tid); struct in6_addr; int cxgb4_create_server(const struct net_device *dev, unsigned int stid, __be32 sip, __be16 sport, unsigned int queue); -int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, - const struct in6_addr *sip, __be16 sport, - unsigned int queue); static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) { @@ -233,7 +228,6 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); unsigned int cxgb4_port_chan(const struct net_device *dev); unsigned int cxgb4_port_viid(const struct net_device *dev); unsigned int cxgb4_port_idx(const struct net_device *dev); -struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id); unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, unsigned int *idx); void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c index e8f0f55e9d08..a2d323c473f8 100644 --- a/drivers/net/cxgb4/l2t.c +++ b/drivers/net/cxgb4/l2t.c @@ -481,40 +481,6 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) handle_failed_resolution(adap, arpq); } -/* - * Allocate an L2T entry for use by a switching rule. Such entries need to be - * explicitly freed and while busy they are not on any hash chain, so normal - * address resolution updates do not see them. - */ -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d) -{ - struct l2t_entry *e; - - write_lock_bh(&d->lock); - e = alloc_l2e(d); - if (e) { - spin_lock(&e->lock); /* avoid race with t4_l2t_free */ - e->state = L2T_STATE_SWITCHING; - atomic_set(&e->refcnt, 1); - spin_unlock(&e->lock); - } - write_unlock_bh(&d->lock); - return e; -} - -/* - * Sets/updates the contents of a switching L2T entry that has been allocated - * with an earlier call to @t4_l2t_alloc_switching. - */ -int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, - u8 port, u8 *eth_addr) -{ - e->vlan = vlan; - e->lport = port; - memcpy(e->dmac, eth_addr, ETH_ALEN); - return write_l2e(adap, e, 0); -} - struct l2t_data *t4_init_l2t(void) { int i; diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h index 643f27ed3cf4..7bd8f42378ff 100644 --- a/drivers/net/cxgb4/l2t.h +++ b/drivers/net/cxgb4/l2t.h @@ -100,9 +100,6 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, unsigned int priority); void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d); -int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, - u8 port, u8 *eth_addr); struct l2t_data *t4_init_l2t(void); void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index 9e1a4b49b47a..bb813d94aea8 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -120,30 +120,6 @@ static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, } } -#if 0 -/** - * t4_write_indirect - write indirectly addressed registers - * @adap: the adapter - * @addr_reg: register holding the indirect addresses - * @data_reg: register holding the value for the indirect registers - * @vals: values to write - * @nregs: how many indirect registers to write - * @start_idx: address of first indirect register to write - * - * Writes a sequential block of registers that are accessed indirectly - * through an address/data register pair. - */ -static void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, - unsigned int data_reg, const u32 *vals, - unsigned int nregs, unsigned int start_idx) -{ - while (nregs--) { - t4_write_reg(adap, addr_reg, start_idx++); - t4_write_reg(adap, data_reg, *vals++); - } -} -#endif - /* * Get the reply to a mailbox command and store it in @rpl in big-endian order. */ @@ -1559,44 +1535,6 @@ void t4_intr_disable(struct adapter *adapter) t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0); } -/** - * t4_intr_clear - clear all interrupts - * @adapter: the adapter whose interrupts should be cleared - * - * Clears all interrupts. The caller must be a PCI function managing - * global interrupts. - */ -void t4_intr_clear(struct adapter *adapter) -{ - static const unsigned int cause_reg[] = { - SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3, - PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, - PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, - PCIE_NONFAT_ERR, PCIE_INT_CAUSE, - MC_INT_CAUSE, - MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE, - EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1), - CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE, - MYPF_REG(CIM_PF_HOST_INT_CAUSE), - TP_INT_CAUSE, - ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE, - PM_RX_INT_CAUSE, PM_TX_INT_CAUSE, - MPS_RX_PERR_INT_CAUSE, - CPL_INTR_CAUSE, - MYPF_REG(PL_PF_INT_CAUSE), - PL_PL_INT_CAUSE, - LE_DB_INT_CAUSE, - }; - - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(cause_reg); ++i) - t4_write_reg(adapter, cause_reg[i], 0xffffffff); - - t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK); - (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */ -} - /** * hash_mac_addr - return the hash value of a MAC address * @addr: the 48-bit Ethernet MAC address @@ -1709,36 +1647,6 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); } -/* Read an RSS table row */ -static int rd_rss_row(struct adapter *adap, int row, u32 *val) -{ - t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row); - return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1, - 5, 0, val); -} - -/** - * t4_read_rss - read the contents of the RSS mapping table - * @adapter: the adapter - * @map: holds the contents of the RSS mapping table - * - * Reads the contents of the RSS hash->queue mapping table. - */ -int t4_read_rss(struct adapter *adapter, u16 *map) -{ - u32 val; - int i, ret; - - for (i = 0; i < RSS_NENTRIES / 2; ++i) { - ret = rd_rss_row(adapter, i, &val); - if (ret) - return ret; - *map++ = LKPTBLQUEUE0_GET(val); - *map++ = LKPTBLQUEUE1_GET(val); - } - return 0; -} - /** * t4_tp_get_tcp_stats - read TP's TCP MIB counters * @adap: the adapter @@ -1778,29 +1686,6 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, #undef STAT_IDX } -/** - * t4_tp_get_err_stats - read TP's error MIB counters - * @adap: the adapter - * @st: holds the counter values - * - * Returns the values of TP's error counters. - */ -void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st) -{ - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs, - 12, TP_MIB_MAC_IN_ERR_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops, - 8, TP_MIB_TNL_CNG_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops, - 4, TP_MIB_TNL_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops, - 4, TP_MIB_OFD_VLN_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs, - 4, TP_MIB_TCP_V6IN_ERR_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh, - 2, TP_MIB_OFD_ARP_DROP); -} - /** * t4_read_mtu_tbl - returns the values in the HW path MTU table * @adap: the adapter @@ -1915,122 +1800,6 @@ void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, } } -/** - * t4_set_trace_filter - configure one of the tracing filters - * @adap: the adapter - * @tp: the desired trace filter parameters - * @idx: which filter to configure - * @enable: whether to enable or disable the filter - * - * Configures one of the tracing filters available in HW. If @enable is - * %0 @tp is not examined and may be %NULL. - */ -int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp, - int idx, int enable) -{ - int i, ofst = idx * 4; - u32 data_reg, mask_reg, cfg; - u32 multitrc = TRCMULTIFILTER; - - if (!enable) { - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); - goto out; - } - - if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f || - tp->skip_ofst > 0x1f || tp->min_len > 0x1ff || - tp->snap_len > 9600 || (idx && tp->snap_len > 256)) - return -EINVAL; - - if (tp->snap_len > 256) { /* must be tracer 0 */ - if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) | - t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) | - t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN) - return -EINVAL; /* other tracers are enabled */ - multitrc = 0; - } else if (idx) { - i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B); - if (TFCAPTUREMAX_GET(i) > 256 && - (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN)) - return -EINVAL; - } - - /* stop the tracer we'll be changing */ - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); - - /* disable tracing globally if running in the wrong single/multi mode */ - cfg = t4_read_reg(adap, MPS_TRC_CFG); - if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) { - t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN); - t4_read_reg(adap, MPS_TRC_CFG); /* flush */ - msleep(1); - if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY)) - return -ETIMEDOUT; - } - /* - * At this point either the tracing is enabled and in the right mode or - * disabled. - */ - - idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH); - data_reg = MPS_TRC_FILTER0_MATCH + idx; - mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx; - - for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { - t4_write_reg(adap, data_reg, tp->data[i]); - t4_write_reg(adap, mask_reg, ~tp->mask[i]); - } - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst, - TFCAPTUREMAX(tp->snap_len) | - TFMINPKTSIZE(tp->min_len)); - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, - TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) | - TFPORT(tp->port) | TFEN | - (tp->invert ? TFINVERTMATCH : 0)); - - cfg &= ~TRCMULTIFILTER; - t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc); -out: t4_read_reg(adap, MPS_TRC_CFG); /* flush */ - return 0; -} - -/** - * t4_get_trace_filter - query one of the tracing filters - * @adap: the adapter - * @tp: the current trace filter parameters - * @idx: which trace filter to query - * @enabled: non-zero if the filter is enabled - * - * Returns the current settings of one of the HW tracing filters. - */ -void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx, - int *enabled) -{ - u32 ctla, ctlb; - int i, ofst = idx * 4; - u32 data_reg, mask_reg; - - ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst); - ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst); - - *enabled = !!(ctla & TFEN); - tp->snap_len = TFCAPTUREMAX_GET(ctlb); - tp->min_len = TFMINPKTSIZE_GET(ctlb); - tp->skip_ofst = TFOFFSET_GET(ctla); - tp->skip_len = TFLENGTH_GET(ctla); - tp->invert = !!(ctla & TFINVERTMATCH); - tp->port = TFPORT_GET(ctla); - - ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx; - data_reg = MPS_TRC_FILTER0_MATCH + ofst; - mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst; - - for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { - tp->mask[i] = ~t4_read_reg(adap, mask_reg); - tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i]; - } -} - /** * get_mps_bg_map - return the buffer groups associated with a port * @adap: the adapter @@ -2132,52 +1901,6 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) #undef GET_STAT_COM } -/** - * t4_get_lb_stats - collect loopback port statistics - * @adap: the adapter - * @idx: the loopback port index - * @p: the stats structure to fill - * - * Return HW statistics for the given loopback port. - */ -void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p) -{ - u32 bgmap = get_mps_bg_map(adap, idx); - -#define GET_STAT(name) \ - t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)) -#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) - - p->octets = GET_STAT(BYTES); - p->frames = GET_STAT(FRAMES); - p->bcast_frames = GET_STAT(BCAST); - p->mcast_frames = GET_STAT(MCAST); - p->ucast_frames = GET_STAT(UCAST); - p->error_frames = GET_STAT(ERROR); - - p->frames_64 = GET_STAT(64B); - p->frames_65_127 = GET_STAT(65B_127B); - p->frames_128_255 = GET_STAT(128B_255B); - p->frames_256_511 = GET_STAT(256B_511B); - p->frames_512_1023 = GET_STAT(512B_1023B); - p->frames_1024_1518 = GET_STAT(1024B_1518B); - p->frames_1519_max = GET_STAT(1519B_MAX); - p->drop = t4_read_reg(adap, PORT_REG(idx, - MPS_PORT_STAT_LB_PORT_DROP_FRAMES)); - - p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0; - p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0; - p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0; - p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0; - p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0; - p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0; - p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0; - p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0; - -#undef GET_STAT -#undef GET_STAT_COM -} - /** * t4_wol_magic_enable - enable/disable magic packet WoL * @adap: the adapter @@ -2583,30 +2306,6 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, return FW_VI_CMD_VIID_GET(ntohs(c.type_viid)); } -/** - * t4_free_vi - free a virtual interface - * @adap: the adapter - * @mbox: mailbox to use for the FW command - * @pf: the PF owning the VI - * @vf: the VF owning the VI - * @viid: virtual interface identifiler - * - * Free a previously allocated virtual interface. - */ -int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, - unsigned int vf, unsigned int viid) -{ - struct fw_vi_cmd c; - - memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_VI_CMD_PFN(pf) | - FW_VI_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c)); - c.type_viid = htons(FW_VI_CMD_VIID(viid)); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); -} - /** * t4_set_rxmode - set Rx properties of a virtual interface * @adap: the adapter @@ -2832,37 +2531,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } -/** - * t4_iq_start_stop - enable/disable an ingress queue and its FLs - * @adap: the adapter - * @mbox: mailbox to use for the FW command - * @start: %true to enable the queues, %false to disable them - * @pf: the PF owning the queues - * @vf: the VF owning the queues - * @iqid: ingress queue id - * @fl0id: FL0 queue id or 0xffff if no attached FL0 - * @fl1id: FL1 queue id or 0xffff if no attached FL1 - * - * Starts or stops an ingress queue and its associated FLs, if any. - */ -int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, - unsigned int pf, unsigned int vf, unsigned int iqid, - unsigned int fl0id, unsigned int fl1id) -{ - struct fw_iq_cmd c; - - memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) | - FW_IQ_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) | - FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c)); - c.iqid = htons(iqid); - c.fl0id = htons(fl0id); - c.fl1id = htons(fl1id); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); -} - /** * t4_iq_free - free an ingress queue and its FLs * @adap: the adapter -- cgit v1.2.3 From afed4ccb0d975f1d3c98880ecf19a24f3d842394 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Sun, 17 Oct 2010 01:48:59 +0000 Subject: b44: fix resume, request_irq after hw reset On resume, call request_irq() after resetting the hardware rather than before. It's a shared interrupt so the handler could be called immediately if another device on the same irq interrupts (and will be called immediately if CONFIG_DEBUG_SHIRQ=y), but unless the hardware is reinitialised with b44_init_hw() the read of the interrupt status register will hang the system. Signed-off-by: James Hogan Signed-off-by: David S. Miller --- drivers/net/b44.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 8e7c8a8e61c7..171da7f75108 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2296,18 +2296,27 @@ static int b44_resume(struct ssb_device *sdev) if (!netif_running(dev)) return 0; + spin_lock_irq(&bp->lock); + b44_init_rings(bp); + b44_init_hw(bp, B44_FULL_RESET); + spin_unlock_irq(&bp->lock); + + /* + * As a shared interrupt, the handler can be called immediately. To be + * able to check the interrupt status the hardware must already be + * powered back on (b44_init_hw). + */ rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); if (rc) { netdev_err(dev, "request_irq failed\n"); + spin_lock_irq(&bp->lock); + b44_halt(bp); + b44_free_rings(bp); + spin_unlock_irq(&bp->lock); return rc; } - spin_lock_irq(&bp->lock); - - b44_init_rings(bp); - b44_init_hw(bp, B44_FULL_RESET); netif_device_attach(bp->dev); - spin_unlock_irq(&bp->lock); b44_enable_ints(bp); netif_wake_queue(dev); -- cgit v1.2.3 From 13eea19213c1f4b711124ddc08c4bb9344442b64 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 18 Oct 2010 04:11:14 +0000 Subject: drivers/net/ax88796.c: Return error code in failure In this code, 0 is returned on failure, even though other failures return -ENOMEM or other similar values. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @a@ identifier alloc; identifier ret; constant C; expression x; @@ x = alloc(...); if (x == NULL) { <+... \(ret = -C; \| return -C; \) ...+> } @@ identifier f, a.alloc; expression ret; expression x,e1,e2,e3; @@ ret = 0 ... when != ret = e1 *x = alloc(...) ... when != ret = e2 if (x == NULL) { ... when != ret = e3 return ret; } // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/ax88796.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 20e946b1e744..b6da4cf3694b 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -864,6 +864,7 @@ static int ax_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "no IRQ specified\n"); + ret = -ENXIO; goto exit_mem; } -- cgit v1.2.3 From a0e00369f1e1ff9142a20efe4785890e52b2e525 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Mon, 18 Oct 2010 11:43:56 +0000 Subject: tipc: delete needless memset from bearer enabling. Eliminates zeroing out of the new bearer structure at the start of activation, since it is already in that state. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/tipc/bearer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index fd9c06c68281..9927d1d56c4f 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -556,8 +556,6 @@ restart: } b_ptr = &tipc_bearers[bearer_id]; - memset(b_ptr, 0, sizeof(struct bearer)); - strcpy(b_ptr->publ.name, name); res = m_ptr->enable_bearer(&b_ptr->publ); if (res) { -- cgit v1.2.3 From d0c2b0d265a0f1f92922a99a31def9da582197ac Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 19 Oct 2010 07:12:10 +0000 Subject: napi: unexport napi_reuse_skb The function napi_reuse_skb is only used inside core. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 -- net/core/dev.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ed7db7eebbf3..fcd3dda86322 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1748,8 +1748,6 @@ extern gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb); extern gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); extern void napi_gro_flush(struct napi_struct *napi); -extern void napi_reuse_skb(struct napi_struct *napi, - struct sk_buff *skb); extern struct sk_buff * napi_get_frags(struct napi_struct *napi); extern gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, diff --git a/net/core/dev.c b/net/core/dev.c index 97fd6bc2004c..b2269ac04cb8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3301,7 +3301,7 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) } EXPORT_SYMBOL(napi_gro_receive); -void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) +static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) { __skb_pull(skb, skb_headlen(skb)); skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); @@ -3309,7 +3309,6 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) napi->skb = skb; } -EXPORT_SYMBOL(napi_reuse_skb); struct sk_buff *napi_get_frags(struct napi_struct *napi) { -- cgit v1.2.3 From ff51bf841587c75b58d25ed77263158619784dd3 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 19 Oct 2010 08:08:33 +0000 Subject: rds: make local functions/variables static The RDS protocol has lots of functions that should be declared static. rds_message_get/add_version_extension is removed since it defined but never used. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/rds/connection.c | 2 +- net/rds/ib.c | 10 +++++----- net/rds/ib.h | 4 ---- net/rds/ib_rdma.c | 2 +- net/rds/ib_sysctl.c | 2 +- net/rds/iw.c | 4 ++-- net/rds/iw.h | 4 ---- net/rds/iw_rdma.c | 3 ++- net/rds/iw_sysctl.c | 2 +- net/rds/message.c | 24 ++---------------------- net/rds/page.c | 3 ++- net/rds/rdma_transport.c | 4 ++-- net/rds/rdma_transport.h | 4 ---- net/rds/rds.h | 5 ----- net/rds/recv.c | 3 +-- net/rds/send.c | 4 +++- net/rds/tcp.c | 6 +++--- net/rds/tcp.h | 2 -- net/rds/tcp_recv.c | 3 ++- net/rds/tcp_send.c | 2 +- 20 files changed, 29 insertions(+), 64 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 870992e08cae..9334d892366e 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -88,7 +88,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, * and receiving over this connection again in the future. It is up to * the transport to have serialized this call with its send and recv. */ -void rds_conn_reset(struct rds_connection *conn) +static void rds_conn_reset(struct rds_connection *conn) { rdsdebug("connection %pI4 to %pI4 reset\n", &conn->c_laddr, &conn->c_faddr); diff --git a/net/rds/ib.c b/net/rds/ib.c index b12a3951167d..4123967d4d65 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -42,7 +42,7 @@ #include "rds.h" #include "ib.h" -unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE; +static unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE; unsigned int fmr_message_size = RDS_FMR_SIZE + 1; /* +1 allows for unaligned MRs */ unsigned int rds_ib_retry_count = RDS_IB_DEFAULT_RETRY_COUNT; @@ -65,7 +65,7 @@ struct list_head rds_ib_devices; DEFINE_SPINLOCK(ib_nodev_conns_lock); LIST_HEAD(ib_nodev_conns); -void rds_ib_nodev_connect(void) +static void rds_ib_nodev_connect(void) { struct rds_ib_connection *ic; @@ -75,7 +75,7 @@ void rds_ib_nodev_connect(void) spin_unlock(&ib_nodev_conns_lock); } -void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev) +static void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev) { struct rds_ib_connection *ic; unsigned long flags; @@ -118,7 +118,7 @@ void rds_ib_dev_put(struct rds_ib_device *rds_ibdev) queue_work(rds_wq, &rds_ibdev->free_work); } -void rds_ib_add_one(struct ib_device *device) +static void rds_ib_add_one(struct ib_device *device) { struct rds_ib_device *rds_ibdev; struct ib_device_attr *dev_attr; @@ -229,7 +229,7 @@ struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device) * * This can be called at any time and can be racing with any other RDS path. */ -void rds_ib_remove_one(struct ib_device *device) +static void rds_ib_remove_one(struct ib_device *device) { struct rds_ib_device *rds_ibdev; diff --git a/net/rds/ib.h b/net/rds/ib.h index 7ad3d57e06a5..e34ad032b66d 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -265,13 +265,10 @@ static inline void rds_ib_dma_sync_sg_for_device(struct ib_device *dev, /* ib.c */ extern struct rds_transport rds_ib_transport; -extern void rds_ib_add_one(struct ib_device *device); -extern void rds_ib_remove_one(struct ib_device *device); struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device); void rds_ib_dev_put(struct rds_ib_device *rds_ibdev); extern struct ib_client rds_ib_client; -extern unsigned int fmr_pool_size; extern unsigned int fmr_message_size; extern unsigned int rds_ib_retry_count; @@ -374,6 +371,5 @@ extern unsigned long rds_ib_sysctl_max_unsig_wrs; extern unsigned long rds_ib_sysctl_max_unsig_bytes; extern unsigned long rds_ib_sysctl_max_recv_allocation; extern unsigned int rds_ib_sysctl_flow_control; -extern ctl_table rds_ib_sysctl_table[]; #endif diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index b5a88415a18e..18a833c450c8 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -38,7 +38,7 @@ #include "ib.h" #include "xlist.h" -struct workqueue_struct *rds_ib_fmr_wq; +static struct workqueue_struct *rds_ib_fmr_wq; static DEFINE_PER_CPU(unsigned long, clean_list_grace); #define CLEAN_LIST_BUSY_BIT 0 diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c index fc3da37220fd..1253b006efdb 100644 --- a/net/rds/ib_sysctl.c +++ b/net/rds/ib_sysctl.c @@ -61,7 +61,7 @@ static unsigned long rds_ib_sysctl_max_unsig_wr_max = 64; */ unsigned int rds_ib_sysctl_flow_control = 0; -ctl_table rds_ib_sysctl_table[] = { +static ctl_table rds_ib_sysctl_table[] = { { .procname = "max_send_wr", .data = &rds_ib_sysctl_max_send_wr, diff --git a/net/rds/iw.c b/net/rds/iw.c index 56808cac0fc7..5a9676fe594f 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -56,7 +56,7 @@ struct list_head rds_iw_devices; DEFINE_SPINLOCK(iw_nodev_conns_lock); LIST_HEAD(iw_nodev_conns); -void rds_iw_add_one(struct ib_device *device) +static void rds_iw_add_one(struct ib_device *device) { struct rds_iw_device *rds_iwdev; struct ib_device_attr *dev_attr; @@ -124,7 +124,7 @@ free_attr: kfree(dev_attr); } -void rds_iw_remove_one(struct ib_device *device) +static void rds_iw_remove_one(struct ib_device *device) { struct rds_iw_device *rds_iwdev; struct rds_iw_cm_id *i_cm_id, *next; diff --git a/net/rds/iw.h b/net/rds/iw.h index 543e665fafe3..90151922178c 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -268,8 +268,6 @@ static inline u32 rds_iw_local_dma_lkey(struct rds_iw_connection *ic) /* ib.c */ extern struct rds_transport rds_iw_transport; -extern void rds_iw_add_one(struct ib_device *device); -extern void rds_iw_remove_one(struct ib_device *device); extern struct ib_client rds_iw_client; extern unsigned int fastreg_pool_size; @@ -318,7 +316,6 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents, void rds_iw_sync_mr(void *trans_private, int dir); void rds_iw_free_mr(void *trans_private, int invalidate); void rds_iw_flush_mrs(void); -void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id); /* ib_recv.c */ int rds_iw_recv_init(void); @@ -378,7 +375,6 @@ extern unsigned long rds_iw_sysctl_max_unsig_wrs; extern unsigned long rds_iw_sysctl_max_unsig_bytes; extern unsigned long rds_iw_sysctl_max_recv_allocation; extern unsigned int rds_iw_sysctl_flow_control; -extern ctl_table rds_iw_sysctl_table[]; /* * Helper functions for getting/setting the header and data SGEs in diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index 0e7accc23ee2..59509e9a9e72 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c @@ -157,7 +157,8 @@ static int rds_iw_add_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id * return 0; } -void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id) +static void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, + struct rdma_cm_id *cm_id) { struct rds_iw_cm_id *i_cm_id; diff --git a/net/rds/iw_sysctl.c b/net/rds/iw_sysctl.c index 23e3a9a26aaf..e2e47176e729 100644 --- a/net/rds/iw_sysctl.c +++ b/net/rds/iw_sysctl.c @@ -55,7 +55,7 @@ static unsigned long rds_iw_sysctl_max_unsig_bytes_max = ~0UL; unsigned int rds_iw_sysctl_flow_control = 1; -ctl_table rds_iw_sysctl_table[] = { +static ctl_table rds_iw_sysctl_table[] = { { .procname = "max_send_wr", .data = &rds_iw_sysctl_max_send_wr, diff --git a/net/rds/message.c b/net/rds/message.c index 84f937f11d47..a84545dae370 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -106,8 +106,8 @@ void rds_message_populate_header(struct rds_header *hdr, __be16 sport, } EXPORT_SYMBOL_GPL(rds_message_populate_header); -int rds_message_add_extension(struct rds_header *hdr, - unsigned int type, const void *data, unsigned int len) +int rds_message_add_extension(struct rds_header *hdr, unsigned int type, + const void *data, unsigned int len) { unsigned int ext_len = sizeof(u8) + len; unsigned char *dst; @@ -177,26 +177,6 @@ none: return RDS_EXTHDR_NONE; } -int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version) -{ - struct rds_ext_header_version ext_hdr; - - ext_hdr.h_version = cpu_to_be32(version); - return rds_message_add_extension(hdr, RDS_EXTHDR_VERSION, &ext_hdr, sizeof(ext_hdr)); -} - -int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version) -{ - struct rds_ext_header_version ext_hdr; - unsigned int pos = 0, len = sizeof(ext_hdr); - - /* We assume the version extension is the only one present */ - if (rds_message_next_extension(hdr, &pos, &ext_hdr, &len) != RDS_EXTHDR_VERSION) - return 0; - *version = be32_to_cpu(ext_hdr.h_version); - return 1; -} - int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset) { struct rds_ext_header_rdma_dest ext_hdr; diff --git a/net/rds/page.c b/net/rds/page.c index 5e44f5ae7898..a3e2e0ac8a60 100644 --- a/net/rds/page.c +++ b/net/rds/page.c @@ -40,7 +40,8 @@ struct rds_page_remainder { unsigned long r_offset; }; -DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, rds_page_remainders); +static DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, + rds_page_remainders); /* * returns 0 on success or -errno on failure. diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index e6ed10aee190..4195a0539829 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -207,7 +207,7 @@ static void rds_rdma_listen_stop(void) } } -int rds_rdma_init(void) +static int rds_rdma_init(void) { int ret; @@ -234,7 +234,7 @@ out: } module_init(rds_rdma_init); -void rds_rdma_exit(void) +static void rds_rdma_exit(void) { /* stop listening first to ensure no new connections are attempted */ rds_rdma_listen_stop(); diff --git a/net/rds/rdma_transport.h b/net/rds/rdma_transport.h index 2f2c7d976c21..faba4e382695 100644 --- a/net/rds/rdma_transport.h +++ b/net/rds/rdma_transport.h @@ -11,10 +11,6 @@ int rds_rdma_conn_connect(struct rds_connection *conn); int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event); -/* from rdma_transport.c */ -int rds_rdma_init(void); -void rds_rdma_exit(void); - /* from ib.c */ extern struct rds_transport rds_ib_transport; int rds_ib_init(void); diff --git a/net/rds/rds.h b/net/rds/rds.h index 8103dcf8b976..9542449c0720 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -619,7 +619,6 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); void rds_conn_shutdown(struct rds_connection *conn); void rds_conn_destroy(struct rds_connection *conn); -void rds_conn_reset(struct rds_connection *conn); void rds_conn_drop(struct rds_connection *conn); void rds_conn_connect_if_down(struct rds_connection *conn); void rds_for_each_conn_info(struct socket *sock, unsigned int len, @@ -668,8 +667,6 @@ int rds_message_add_extension(struct rds_header *hdr, unsigned int type, const void *data, unsigned int len); int rds_message_next_extension(struct rds_header *hdr, unsigned int *pos, void *buf, unsigned int *buflen); -int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version); -int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version); int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, size_t size); @@ -706,7 +703,6 @@ void rds_page_exit(void); /* recv.c */ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, __be32 saddr); -void rds_inc_addref(struct rds_incoming *inc); void rds_inc_put(struct rds_incoming *inc); void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr, struct rds_incoming *inc, gfp_t gfp, enum km_type km); @@ -728,7 +724,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest); typedef int (*is_acked_func)(struct rds_message *rm, uint64_t ack); void rds_send_drop_acked(struct rds_connection *conn, u64 ack, is_acked_func is_acked); -void rds_send_remove_from_sock(struct list_head *messages, int status); int rds_send_pong(struct rds_connection *conn, __be16 dport); struct rds_message *rds_send_get_message(struct rds_connection *, struct rm_rdma_op *); diff --git a/net/rds/recv.c b/net/rds/recv.c index 68800f02aa30..596689e59272 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -48,12 +48,11 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, } EXPORT_SYMBOL_GPL(rds_inc_init); -void rds_inc_addref(struct rds_incoming *inc) +static void rds_inc_addref(struct rds_incoming *inc) { rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount)); atomic_inc(&inc->i_refcount); } -EXPORT_SYMBOL_GPL(rds_inc_addref); void rds_inc_put(struct rds_incoming *inc) { diff --git a/net/rds/send.c b/net/rds/send.c index 9b951a0ab6b7..0bc9db17a87d 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -52,6 +52,8 @@ static int send_batch_count = 64; module_param(send_batch_count, int, 0444); MODULE_PARM_DESC(send_batch_count, " batch factor when working the send queue"); +static void rds_send_remove_from_sock(struct list_head *messages, int status); + /* * Reset the send state. Callers must ensure that this doesn't race with * rds_send_xmit(). @@ -555,7 +557,7 @@ EXPORT_SYMBOL_GPL(rds_send_get_message); * removing the messages from the 'messages' list regardless of if it found * the messages on the socket list or not. */ -void rds_send_remove_from_sock(struct list_head *messages, int status) +static void rds_send_remove_from_sock(struct list_head *messages, int status) { unsigned long flags; struct rds_sock *rs = NULL; diff --git a/net/rds/tcp.c b/net/rds/tcp.c index eeb08e6ab96b..08a8c6cf2d10 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -41,7 +41,7 @@ /* only for info exporting */ static DEFINE_SPINLOCK(rds_tcp_tc_list_lock); static LIST_HEAD(rds_tcp_tc_list); -unsigned int rds_tcp_tc_count; +static unsigned int rds_tcp_tc_count; /* Track rds_tcp_connection structs so they can be cleaned up */ static DEFINE_SPINLOCK(rds_tcp_conn_lock); @@ -243,7 +243,7 @@ static void rds_tcp_destroy_conns(void) } } -void rds_tcp_exit(void) +static void rds_tcp_exit(void) { rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); rds_tcp_listen_stop(); @@ -274,7 +274,7 @@ struct rds_transport rds_tcp_transport = { .t_prefer_loopback = 1, }; -int rds_tcp_init(void) +static int rds_tcp_init(void) { int ret; diff --git a/net/rds/tcp.h b/net/rds/tcp.h index f5e6f7bebb50..9cf2927d0021 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -43,8 +43,6 @@ struct rds_tcp_statistics { }; /* tcp.c */ -int rds_tcp_init(void); -void rds_tcp_exit(void); void rds_tcp_tune(struct socket *sock); void rds_tcp_nonagle(struct socket *sock); void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn); diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 67263fbee623..78205e25500a 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -272,7 +272,8 @@ out: } /* the caller has to hold the sock lock */ -int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, enum km_type km) +static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, + enum km_type km) { struct rds_tcp_connection *tc = conn->c_transport_data; struct socket *sock = tc->t_sock; diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index aa16841afbdf..1b4fd68f0c7c 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -63,7 +63,7 @@ void rds_tcp_xmit_complete(struct rds_connection *conn) } /* the core send_sem serializes this with other xmit and shutdown */ -int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) +static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) { struct kvec vec = { .iov_base = data, -- cgit v1.2.3 From 32a875adcdcf5f470bf967250cfd01722e23844f Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 19 Oct 2010 06:48:16 +0000 Subject: 9p: client code cleanup Make p9_client_version static since only used in one file. Remove p9_client_auth because it is defined but never used. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/9p/client.h | 3 --- net/9p/client.c | 51 +------------------------------------------------ 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/include/net/9p/client.h b/include/net/9p/client.h index d1aa2cfb30f0..7f63d5ab7b44 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -212,15 +212,12 @@ struct p9_dirent { int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name); -int p9_client_version(struct p9_client *); struct p9_client *p9_client_create(const char *dev_name, char *options); void p9_client_destroy(struct p9_client *clnt); void p9_client_disconnect(struct p9_client *clnt); void p9_client_begin_disconnect(struct p9_client *clnt); struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname); -struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, - u32 n_uname, char *aname); struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone); int p9_client_open(struct p9_fid *fid, int mode); diff --git a/net/9p/client.c b/net/9p/client.c index b5e1aa8d718e..83bf0541d66f 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -671,7 +671,7 @@ static void p9_fid_destroy(struct p9_fid *fid) kfree(fid); } -int p9_client_version(struct p9_client *c) +static int p9_client_version(struct p9_client *c) { int err = 0; struct p9_req_t *req; @@ -730,7 +730,6 @@ error: return err; } -EXPORT_SYMBOL(p9_client_version); struct p9_client *p9_client_create(const char *dev_name, char *options) { @@ -887,54 +886,6 @@ error: } EXPORT_SYMBOL(p9_client_attach); -struct p9_fid * -p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname) -{ - int err; - struct p9_req_t *req; - struct p9_qid qid; - struct p9_fid *afid; - - P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname); - err = 0; - - afid = p9_fid_create(clnt); - if (IS_ERR(afid)) { - err = PTR_ERR(afid); - afid = NULL; - goto error; - } - - req = p9_client_rpc(clnt, P9_TAUTH, "dss?d", - afid ? afid->fid : P9_NOFID, uname, aname, n_uname); - if (IS_ERR(req)) { - err = PTR_ERR(req); - goto error; - } - - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); - if (err) { - p9pdu_dump(1, req->rc); - p9_free_req(clnt, req); - goto error; - } - - P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n", - qid.type, - (unsigned long long)qid.path, - qid.version); - - memmove(&afid->qid, &qid, sizeof(struct p9_qid)); - p9_free_req(clnt, req); - return afid; - -error: - if (afid) - p9_fid_destroy(afid); - return ERR_PTR(err); -} -EXPORT_SYMBOL(p9_client_auth); - struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone) { -- cgit v1.2.3 From 1e55659ce6ddb5247cee0b1f720d77a799902b85 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 19 Oct 2010 09:32:04 +0000 Subject: can-raw: add msg_flags to distinguish local traffic CAN has no addressing scheme. It is currently impossible for userspace to tell is a received CAN frame comes from another process on the local host, or from a remote CAN device. This patch add support for userspace applications to distinguish between 'own', 'local' and 'remote' CAN traffic. The distinction is made by returning flags in msg->msg_flags in the call to recvmsg(). The added documentation explains the introduced flags. Signed-off-by: Kurt Van Dijck Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- Documentation/networking/can.txt | 12 ++++++++++++ net/can/raw.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index cd79735013f9..5b04b67ddca2 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -22,6 +22,7 @@ This file contains 4.1.2 RAW socket option CAN_RAW_ERR_FILTER 4.1.3 RAW socket option CAN_RAW_LOOPBACK 4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS + 4.1.5 RAW socket returned message flags 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) @@ -471,6 +472,17 @@ solution for a couple of reasons: setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs, sizeof(recv_own_msgs)); + 4.1.5 RAW socket returned message flags + + When using recvmsg() call, the msg->msg_flags may contain following flags: + + MSG_DONTROUTE: set when the received frame was created on the local host. + + MSG_CONFIRM: set when the frame was sent via the socket it is received on. + This flag can be interpreted as a 'transmission confirmation' when the + CAN driver supports the echo of frames on driver level, see 3.2 and 6.2. + In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set. + 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) diff --git a/net/can/raw.c b/net/can/raw.c index 7d77e67e57af..e88f610fdb7b 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -90,23 +90,39 @@ struct raw_sock { can_err_mask_t err_mask; }; +/* + * Return pointer to store the extra msg flags for raw_recvmsg(). + * We use the space of one unsigned int beyond the 'struct sockaddr_can' + * in skb->cb. + */ +static inline unsigned int *raw_flags(struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) + + sizeof(unsigned int))); + + /* return pointer after struct sockaddr_can */ + return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]); +} + static inline struct raw_sock *raw_sk(const struct sock *sk) { return (struct raw_sock *)sk; } -static void raw_rcv(struct sk_buff *skb, void *data) +static void raw_rcv(struct sk_buff *oskb, void *data) { struct sock *sk = (struct sock *)data; struct raw_sock *ro = raw_sk(sk); struct sockaddr_can *addr; + struct sk_buff *skb; + unsigned int *pflags; /* check the received tx sock reference */ - if (!ro->recv_own_msgs && skb->sk == sk) + if (!ro->recv_own_msgs && oskb->sk == sk) return; /* clone the given skb to be able to enqueue it into the rcv queue */ - skb = skb_clone(skb, GFP_ATOMIC); + skb = skb_clone(oskb, GFP_ATOMIC); if (!skb) return; @@ -123,6 +139,14 @@ static void raw_rcv(struct sk_buff *skb, void *data) addr->can_family = AF_CAN; addr->can_ifindex = skb->dev->ifindex; + /* add CAN specific message flags for raw_recvmsg() */ + pflags = raw_flags(skb); + *pflags = 0; + if (oskb->sk) + *pflags |= MSG_DONTROUTE; + if (oskb->sk == sk) + *pflags |= MSG_CONFIRM; + if (sock_queue_rcv_skb(sk, skb) < 0) kfree_skb(skb); } @@ -707,6 +731,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, memcpy(msg->msg_name, skb->cb, msg->msg_namelen); } + /* assign the flags that have been recorded in raw_rcv() */ + msg->msg_flags |= *(raw_flags(skb)); + skb_free_datagram(sk, skb); return size; -- cgit v1.2.3 From 5601b2dfae86198667dd6e075a074fbef0c83423 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 20 Oct 2010 00:02:25 +0000 Subject: can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set Commit d3cd15657516141adce387810be8cb377baf020e introduced a bug, the interrupt handler would loop endlessly if the CANINTF_MERRF bit is set, because it's not cleared. This patch fixes the problem by masking out the CANINTF_MERRF and all other non interesting bits. Signed-off-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/mcp251x.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index c664be261e98..59f40bce1ffc 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -125,8 +125,9 @@ # define CANINTF_TX0IF 0x04 # define CANINTF_RX1IF 0x02 # define CANINTF_RX0IF 0x01 -# define CANINTF_ERR_TX \ - (CANINTF_ERRIF | CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) +# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF) +# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) +# define CANINTF_ERR (CANINTF_ERRIF) #define EFLG 0x2d # define EFLG_EWARN 0x01 # define EFLG_RXWAR 0x02 @@ -790,6 +791,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); + /* mask out flags we don't care about */ + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; + /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); @@ -810,8 +814,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) } /* any error or tx interrupt we need to clear? */ - if (intf & CANINTF_ERR_TX) - clear_intf |= intf & CANINTF_ERR_TX; + if (intf & (CANINTF_ERR | CANINTF_TX)) + clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); if (clear_intf) mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); @@ -887,7 +891,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf == 0) break; - if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) { + if (intf & CANINTF_TX) { net->stats.tx_packets++; net->stats.tx_bytes += priv->tx_len - 1; if (priv->tx_len) { -- cgit v1.2.3 From 612eef4f4714d5c0e7127b7b245dbfc444d14a4b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 20 Oct 2010 00:02:26 +0000 Subject: can: mcp251x: fix generation of error frames The function "mcp251x_error_skb" is used to generate error frames. They are identified by the "CAN_ERR_FLAG" in can_id. The function overwrites the can_id so that the frames show up as normal frames instead of error frames. This patch fixes the problem by or'ing the can_id instead of overwriting it. Signed-off-by: Marc Kleine-Budde Tested-by: Jargalan Nermunkh Signed-off-by: David S. Miller --- drivers/net/can/mcp251x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 59f40bce1ffc..6aadc3e32bd5 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -705,7 +705,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) skb = alloc_can_err_skb(net, &frame); if (skb) { - frame->can_id = can_id; + frame->can_id |= can_id; frame->data[1] = data1; netif_rx_ni(skb); } else { -- cgit v1.2.3 From b0aeef30433ea6854e985c2e9842fa19f51b95cc Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Mon, 11 Oct 2010 11:23:07 +0300 Subject: nf_nat: restrict ICMP translation for embedded header Skip ICMP translation of embedded protocol header if NAT bits are not set. Needed for IPVS to see the original embedded addresses because for IPVS traffic the IPS_SRC_NAT_BIT and IPS_DST_NAT_BIT bits are not set. It happens when IPVS performs DNAT for client packets after using nf_conntrack_alter_reply to expect replies from real server. Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/ipv4/netfilter/nf_nat_core.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index e2e00c4da883..0047923c1f22 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -462,6 +462,18 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, return 0; } + if (manip == IP_NAT_MANIP_SRC) + statusbit = IPS_SRC_NAT; + else + statusbit = IPS_DST_NAT; + + /* Invert if this is reply dir. */ + if (dir == IP_CT_DIR_REPLY) + statusbit ^= IPS_NAT_MASK; + + if (!(ct->status & statusbit)) + return 1; + pr_debug("icmp_reply_translation: translating error %p manip %u " "dir %s\n", skb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY"); @@ -496,20 +508,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, /* Change outer to look the reply to an incoming packet * (proto 0 means don't invert per-proto part). */ - if (manip == IP_NAT_MANIP_SRC) - statusbit = IPS_SRC_NAT; - else - statusbit = IPS_DST_NAT; - - /* Invert if this is reply dir. */ - if (dir == IP_CT_DIR_REPLY) - statusbit ^= IPS_NAT_MASK; - - if (ct->status & statusbit) { - nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); - if (!manip_pkt(0, skb, 0, &target, manip)) - return 0; - } + nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); + if (!manip_pkt(0, skb, 0, &target, manip)) + return 0; return 1; } -- cgit v1.2.3 From e83726b0460f4741c8f10e1488fbcc0a9e5f0b7e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 21 Oct 2010 04:39:09 -0700 Subject: l2tp: small cleanup Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/l2tp/l2tp_ip.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 226a0ae3bcfd..1c770c0644d1 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -65,9 +65,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif continue; if ((l2tp->conn_id == tunnel_id) && -#ifdef CONFIG_NET_NS - (sk->sk_net == net) && -#endif + net_eq(sock_net(sk), net) && !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; -- cgit v1.2.3 From e97c3e278e951501c2f385de70c3ceacdea78c4a Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:03:43 +0200 Subject: tproxy: split off ipv6 defragmentation to a separate module Like with IPv4, TProxy needs IPv6 defragmentation but does not require connection tracking. Since defragmentation was coupled with conntrack, I split off the two, creating an nf_defrag_ipv6 module, similar to the already existing nf_defrag_ipv4. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/netfilter/ipv6/nf_defrag_ipv6.h | 6 ++ net/ipv6/netfilter/Makefile | 5 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 78 +-------------- net/ipv6/netfilter/nf_conntrack_reasm.c | 14 ++- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 131 +++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 78 deletions(-) create mode 100644 include/net/netfilter/ipv6/nf_defrag_ipv6.h create mode 100644 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h new file mode 100644 index 000000000000..94dd54d76b48 --- /dev/null +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h @@ -0,0 +1,6 @@ +#ifndef _NF_DEFRAG_IPV6_H +#define _NF_DEFRAG_IPV6_H + +extern void nf_defrag_ipv6_enable(void); + +#endif /* _NF_DEFRAG_IPV6_H */ diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index aafbba30c899..3f8e4a3d83ce 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o # objects for l3 independent conntrack -nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o +nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o +nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o # l3 independent conntrack -obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o +obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o # matches obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ff43461704be..c8af58b22562 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, @@ -189,53 +189,6 @@ out: return nf_conntrack_confirm(skb); } -static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, - struct sk_buff *skb) -{ - u16 zone = NF_CT_DEFAULT_ZONE; - - if (skb->nfct) - zone = nf_ct_zone((struct nf_conn *)skb->nfct); - -#ifdef CONFIG_BRIDGE_NETFILTER - if (skb->nf_bridge && - skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) - return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; -#endif - if (hooknum == NF_INET_PRE_ROUTING) - return IP6_DEFRAG_CONNTRACK_IN + zone; - else - return IP6_DEFRAG_CONNTRACK_OUT + zone; - -} - -static unsigned int ipv6_defrag(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -{ - struct sk_buff *reasm; - - /* Previously seen (loopback)? */ - if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) - return NF_ACCEPT; - - reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); - /* queued */ - if (reasm == NULL) - return NF_STOLEN; - - /* error occured or not fragmented */ - if (reasm == skb) - return NF_ACCEPT; - - nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, - (struct net_device *)out, okfn); - - return NF_STOLEN; -} - static unsigned int __ipv6_conntrack_in(struct net *net, unsigned int hooknum, struct sk_buff *skb, @@ -287,13 +240,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, } static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { - { - .hook = ipv6_defrag, - .owner = THIS_MODULE, - .pf = NFPROTO_IPV6, - .hooknum = NF_INET_PRE_ROUTING, - .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, - }, { .hook = ipv6_conntrack_in, .owner = THIS_MODULE, @@ -308,13 +254,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_CONNTRACK, }, - { - .hook = ipv6_defrag, - .owner = THIS_MODULE, - .pf = NFPROTO_IPV6, - .hooknum = NF_INET_LOCAL_OUT, - .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, - }, { .hook = ipv6_confirm, .owner = THIS_MODULE, @@ -386,10 +325,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { .nlattr_tuple_size = ipv6_nlattr_tuple_size, .nlattr_to_tuple = ipv6_nlattr_to_tuple, .nla_policy = ipv6_nla_policy, -#endif -#ifdef CONFIG_SYSCTL - .ctl_table_path = nf_net_netfilter_sysctl_path, - .ctl_table = nf_ct_ipv6_sysctl_table, #endif .me = THIS_MODULE, }; @@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) int ret = 0; need_conntrack(); + nf_defrag_ipv6_enable(); - ret = nf_ct_frag6_init(); - if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't initialize frag6.\n"); - return ret; - } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register tcp.\n"); - goto cleanup_frag6; + return ret; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); @@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); cleanup_tcp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); - cleanup_frag6: - nf_ct_frag6_cleanup(); return ret; } @@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); - nf_ct_frag6_cleanup(); } module_init(nf_conntrack_l3proto_ipv6_init); diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 138a8b362706..489d71b844ac 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -73,7 +73,7 @@ static struct inet_frags nf_frags; static struct netns_frags nf_init_frags; #ifdef CONFIG_SYSCTL -struct ctl_table nf_ct_ipv6_sysctl_table[] = { +struct ctl_table nf_ct_frag6_sysctl_table[] = { { .procname = "nf_conntrack_frag6_timeout", .data = &nf_init_frags.timeout, @@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { }, { } }; + +static struct ctl_table_header *nf_ct_frag6_sysctl_header; #endif static unsigned int nf_hashfn(struct inet_frag_queue *q) @@ -623,11 +625,21 @@ int nf_ct_frag6_init(void) inet_frags_init_net(&nf_init_frags); inet_frags_init(&nf_frags); + nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, + nf_ct_frag6_sysctl_table); + if (!nf_ct_frag6_sysctl_header) { + inet_frags_fini(&nf_frags); + return -ENOMEM; + } + return 0; } void nf_ct_frag6_cleanup(void) { + unregister_sysctl_table(nf_ct_frag6_sysctl_header); + nf_ct_frag6_sysctl_header = NULL; + inet_frags_fini(&nf_frags); nf_init_frags.low_thresh = 0; diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c new file mode 100644 index 000000000000..99abfb53bab9 --- /dev/null +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -0,0 +1,131 @@ +/* (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2004 Netfilter Core Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, + struct sk_buff *skb) +{ + u16 zone = NF_CT_DEFAULT_ZONE; + + if (skb->nfct) + zone = nf_ct_zone((struct nf_conn *)skb->nfct); + +#ifdef CONFIG_BRIDGE_NETFILTER + if (skb->nf_bridge && + skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) + return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; +#endif + if (hooknum == NF_INET_PRE_ROUTING) + return IP6_DEFRAG_CONNTRACK_IN + zone; + else + return IP6_DEFRAG_CONNTRACK_OUT + zone; + +} + +static unsigned int ipv6_defrag(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct sk_buff *reasm; + + /* Previously seen (loopback)? */ + if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) + return NF_ACCEPT; + + reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); + /* queued */ + if (reasm == NULL) + return NF_STOLEN; + + /* error occured or not fragmented */ + if (reasm == skb) + return NF_ACCEPT; + + nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, + (struct net_device *)out, okfn); + + return NF_STOLEN; +} + +static struct nf_hook_ops ipv6_defrag_ops[] = { + { + .hook = ipv6_defrag, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ipv6_defrag, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_LOCAL_OUT, + .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, + }, +}; + +static int __init nf_defrag_init(void) +{ + int ret = 0; + + ret = nf_ct_frag6_init(); + if (ret < 0) { + pr_err("nf_defrag_ipv6: can't initialize frag6.\n"); + return ret; + } + ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); + if (ret < 0) { + pr_err("nf_defrag_ipv6: can't register hooks\n"); + goto cleanup_frag6; + } + return ret; + +cleanup_frag6: + nf_ct_frag6_cleanup(); + return ret; + +} + +static void __exit nf_defrag_fini(void) +{ + nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); + nf_ct_frag6_cleanup(); +} + +void nf_defrag_ipv6_enable(void) +{ +} +EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); + +module_init(nf_defrag_init); +module_exit(nf_defrag_fini); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 88440ae70eda83d0cc94148d404f4990c9f1289c Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:04:33 +0200 Subject: tproxy: added const specifiers to udp lookup functions The parameters for various UDP lookup functions were non-const, even though they could be const. TProxy has some const references and instead of downcasting it, I added const specifiers along the path. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- net/ipv6/udp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5acb3560ff15..33e368318d47 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -122,8 +122,8 @@ static void udp_v6_rehash(struct sock *sk) static inline int compute_score(struct sock *sk, struct net *net, unsigned short hnum, - struct in6_addr *saddr, __be16 sport, - struct in6_addr *daddr, __be16 dport, + const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif) { int score = -1; @@ -239,8 +239,8 @@ exact_match: } static struct sock *__udp6_lib_lookup(struct net *net, - struct in6_addr *saddr, __be16 sport, - struct in6_addr *daddr, __be16 dport, + const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif, struct udp_table *udptable) { struct sock *sk, *result; -- cgit v1.2.3 From aa976fc011efa1f0e3290c6c9addf7c20757f885 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:05:41 +0200 Subject: tproxy: added udp6_lib_lookup function Just like with IPv4, we need access to the UDP hash table to look up local sockets, but instead of exporting the global udp_table, export a lookup function. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/udp.h | 3 +++ net/ipv6/udp.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/include/net/udp.h b/include/net/udp.h index a184d3496b13..200b82848c9a 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -183,6 +183,9 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, __be32 daddr, __be16 dport, int dif); +extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, + int dif); /* * SNMP statistics for UDP and UDP-Lite diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 33e368318d47..c84dad432114 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -320,6 +320,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, udptable); } +struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif) +{ + return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table); +} +EXPORT_SYMBOL_GPL(udp6_lib_lookup); + + /* * This should be easy, if there is something there we * return it, otherwise we block. -- cgit v1.2.3 From 6c46862280c5f55eda7750391bc65cd7e08c7535 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:08:28 +0200 Subject: tproxy: added tproxy sockopt interface in the IPV6 layer Support for IPV6_RECVORIGDSTADDR sockopt for UDP sockets were contributed by Harry Mason. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/linux/in6.h | 4 ++++ include/linux/ipv6.h | 4 +++- net/ipv6/datagram.c | 19 +++++++++++++++++++ net/ipv6/ipv6_sockglue.c | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/linux/in6.h b/include/linux/in6.h index c4bf46f764bf..097a34b55560 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -268,6 +268,10 @@ struct in6_flowlabel_req { /* RFC5082: Generalized Ttl Security Mechanism */ #define IPV6_MINHOPCOUNT 73 +#define IPV6_ORIGDSTADDR 74 +#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR +#define IPV6_TRANSPARENT 75 + /* * Multicast Routing: * see include/linux/mroute6.h. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e62683ba88e6..8e429d0e0405 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -341,7 +341,9 @@ struct ipv6_pinfo { odstopts:1, rxflow:1, rxtclass:1, - rxpmtu:1; + rxpmtu:1, + rxorigdstaddr:1; + /* 2 bits hole */ } bits; __u16 all; } rxopt; diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index ef371aa01ac5..320bdb877eed 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -577,6 +577,25 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) u8 *ptr = nh + opt->dst1; put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); } + if (np->rxopt.bits.rxorigdstaddr) { + struct sockaddr_in6 sin6; + u16 *ports = (u16 *) skb_transport_header(skb); + + if (skb_transport_offset(skb) + 4 <= skb->len) { + /* All current transport protocols have the port numbers in the + * first four bytes of the transport header and this function is + * written with this assumption in mind. + */ + + sin6.sin6_family = AF_INET6; + ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr); + sin6.sin6_port = ports[1]; + sin6.sin6_flowinfo = 0; + sin6.sin6_scope_id = 0; + + put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6); + } + } return 0; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index a7f66bc8f0b0..0553867a317f 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -342,6 +342,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; break; + case IPV6_TRANSPARENT: + if (optlen < sizeof(int)) + goto e_inval; + /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */ + inet_sk(sk)->transparent = valbool; + retv = 0; + break; + + case IPV6_RECVORIGDSTADDR: + if (optlen < sizeof(int)) + goto e_inval; + np->rxopt.bits.rxorigdstaddr = valbool; + retv = 0; + break; + case IPV6_HOPOPTS: case IPV6_RTHDRDSTOPTS: case IPV6_RTHDR: @@ -1104,6 +1119,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; } + case IPV6_TRANSPARENT: + val = inet_sk(sk)->transparent; + break; + + case IPV6_RECVORIGDSTADDR: + val = np->rxopt.bits.rxorigdstaddr; + break; + case IPV6_UNICAST_HOPS: case IPV6_MULTICAST_HOPS: { -- cgit v1.2.3 From 0a513f6af962525ed4b3395f8c8d5daae8682aa9 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:10:03 +0200 Subject: tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- net/ipv6/af_inet6.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 56b9bf2516f4..4869797c1afa 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -343,7 +343,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) */ v4addr = LOOPBACK4_IPV6; if (!(addr_type & IPV6_ADDR_MULTICAST)) { - if (!ipv6_chk_addr(net, &addr->sin6_addr, + if (!inet->transparent && + !ipv6_chk_addr(net, &addr->sin6_addr, dev, 0)) { err = -EADDRNOTAVAIL; goto out_unlock; -- cgit v1.2.3 From cc4ce020935eab2d261b7b8d24a9843b56ad594c Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Thu, 21 Oct 2010 07:11:14 -0700 Subject: be2net: Changes to use only priority codes allowed by f/w Changes to use one of the priority codes allowed by CNA f/w for NIC traffic from host. The driver gets the bit map of the priority codes allowed for host traffic through a asynchronous message from the f/w that the driver subscribes to. Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 ++ drivers/net/benet/be_cmds.c | 61 ++++++++++++++++++++++++++++++++++++++++++--- drivers/net/benet/be_cmds.h | 33 +++++++++++++++++++++++- drivers/net/benet/be_main.c | 20 ++++++++++----- 4 files changed, 106 insertions(+), 10 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 59a17b569b7f..4594a28b1f66 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -264,6 +264,8 @@ struct be_adapter { u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ u8 vlan_tag[VLAN_N_VID]; + u8 vlan_prio_bmap; /* Available Priority BitMap */ + u16 recommended_prio; /* Recommended Priority */ struct be_dma_mem mc_cmd_mem; struct be_dma_mem stats_cmd; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index bf2dc269de12..1e7f305ed00b 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -96,6 +96,50 @@ static void be_async_link_state_process(struct be_adapter *adapter, evt->port_link_status == ASYNC_EVENT_LINK_UP); } +/* Grp5 CoS Priority evt */ +static void be_async_grp5_cos_priority_process(struct be_adapter *adapter, + struct be_async_event_grp5_cos_priority *evt) +{ + if (evt->valid) { + adapter->vlan_prio_bmap = evt->available_priority_bmap; + adapter->recommended_prio = + evt->reco_default_priority << VLAN_PRIO_SHIFT; + } +} + +/* Grp5 QOS Speed evt */ +static void be_async_grp5_qos_speed_process(struct be_adapter *adapter, + struct be_async_event_grp5_qos_link_speed *evt) +{ + if (evt->physical_port == adapter->port_num) { + /* qos_link_speed is in units of 10 Mbps */ + adapter->link_speed = evt->qos_link_speed * 10; + } +} + +static void be_async_grp5_evt_process(struct be_adapter *adapter, + u32 trailer, struct be_mcc_compl *evt) +{ + u8 event_type = 0; + + event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) & + ASYNC_TRAILER_EVENT_TYPE_MASK; + + switch (event_type) { + case ASYNC_EVENT_COS_PRIORITY: + be_async_grp5_cos_priority_process(adapter, + (struct be_async_event_grp5_cos_priority *)evt); + break; + case ASYNC_EVENT_QOS_SPEED: + be_async_grp5_qos_speed_process(adapter, + (struct be_async_event_grp5_qos_link_speed *)evt); + break; + default: + dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n"); + break; + } +} + static inline bool is_link_state_evt(u32 trailer) { return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & @@ -103,6 +147,13 @@ static inline bool is_link_state_evt(u32 trailer) ASYNC_EVENT_CODE_LINK_STATE; } +static inline bool is_grp5_evt(u32 trailer) +{ + return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & + ASYNC_TRAILER_EVENT_CODE_MASK) == + ASYNC_EVENT_CODE_GRP_5); +} + static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) { struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq; @@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status) if (is_link_state_evt(compl->flags)) be_async_link_state_process(adapter, (struct be_async_event_link_state *) compl); + else if (is_grp5_evt(compl->flags)) + be_async_grp5_evt_process(adapter, + compl->flags, compl); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { *status = be_mcc_compl_process(adapter, compl); atomic_dec(&mcc_obj->q.used); @@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter, ctxt = &req->context; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, - OPCODE_COMMON_MCC_CREATE); + OPCODE_COMMON_MCC_CREATE_EXT); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_MCC_CREATE, sizeof(*req)); + OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); @@ -688,7 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, be_encoded_q_len(mccq->len)); AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); - + /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ + req->async_event_bitmap[0] |= 0x00000022; be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index b7a40b172d1a..c7f6cdfe1c73 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -82,7 +82,12 @@ struct be_mcc_compl { */ #define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */ #define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF +#define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16 +#define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF #define ASYNC_EVENT_CODE_LINK_STATE 0x1 +#define ASYNC_EVENT_CODE_GRP_5 0x5 +#define ASYNC_EVENT_QOS_SPEED 0x1 +#define ASYNC_EVENT_COS_PRIORITY 0x2 struct be_async_event_trailer { u32 code; }; @@ -105,6 +110,30 @@ struct be_async_event_link_state { struct be_async_event_trailer trailer; } __packed; +/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED + * the mcc_compl must be interpreted as follows + */ +struct be_async_event_grp5_qos_link_speed { + u8 physical_port; + u8 rsvd[5]; + u16 qos_link_speed; + u32 event_tag; + struct be_async_event_trailer trailer; +} __packed; + +/* When the event code of an async trailer is GRP5 and event type is + * CoS-Priority, the mcc_compl must be interpreted as follows + */ +struct be_async_event_grp5_cos_priority { + u8 physical_port; + u8 available_priority_bmap; + u8 reco_default_priority; + u8 valid; + u8 rsvd0; + u8 event_tag; + struct be_async_event_trailer trailer; +} __packed; + struct be_mcc_mailbox { struct be_mcc_wrb wrb; struct be_mcc_compl compl; @@ -123,8 +152,9 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_WRITE_FLASHROM 7 #define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_EQ_CREATE 13 -#define OPCODE_COMMON_MCC_CREATE 21 +#define OPCODE_COMMON_MCC_CREATE 21 #define OPCODE_COMMON_SET_QOS 28 +#define OPCODE_COMMON_MCC_CREATE_EXT 90 #define OPCODE_COMMON_SEEPROM_READ 30 #define OPCODE_COMMON_NTWK_RX_FILTER 34 #define OPCODE_COMMON_GET_FW_VERSION 35 @@ -338,6 +368,7 @@ struct be_cmd_req_mcc_create { struct be_cmd_req_hdr hdr; u16 num_pages; u16 rsvd0; + u32 async_event_bitmap[1]; u8 context[sizeof(struct amap_mcc_context) / 8]; struct phys_addr pages[8]; } __packed; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index d5e796832fdd..45b1f6635282 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -429,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; } -static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, - u32 wrb_cnt, u32 len) +static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, + struct sk_buff *skb, u32 wrb_cnt, u32 len) { + u8 vlan_prio = 0; + u16 vlan_tag = 0; + memset(hdr, 0, sizeof(*hdr)); AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); @@ -449,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); } - if (vlan_tx_tag_present(skb)) { + if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, - hdr, vlan_tx_tag_get(skb)); + vlan_tag = vlan_tx_tag_get(skb); + vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + /* If vlan priority provided by OS is NOT in available bmap */ + if (!(adapter->vlan_prio_bmap & (1 << vlan_prio))) + vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) | + adapter->recommended_prio; + AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag); } AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); @@ -532,7 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, queue_head_inc(txq); } - wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied); + wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied); be_dws_cpu_to_le(hdr, sizeof(*hdr)); return copied; -- cgit v1.2.3 From 3b9afb29917f4ab08decf358ecfd354a72a91ac0 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:12:14 +0200 Subject: tproxy: added IPv6 socket lookup function to nf_tproxy_core Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_tproxy_core.h | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 1027d7f901a0..cd85b3bc8327 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include #include #define NFT_LOOKUP_ANY 0 @@ -130,6 +131,75 @@ nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, return sk; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static inline struct sock * +nf_tproxy_get_sock_v6(struct net *net, const u8 protocol, + const struct in6_addr *saddr, const struct in6_addr *daddr, + const __be16 sport, const __be16 dport, + const struct net_device *in, int lookup_type) +{ + struct sock *sk; + + /* look up socket */ + switch (protocol) { + case IPPROTO_TCP: + switch (lookup_type) { + case NFT_LOOKUP_ANY: + sk = inet6_lookup(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet6_lookup_listener(net, &tcp_hashinfo, + daddr, ntohs(dport), + in->ifindex); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + + break; + case NFT_LOOKUP_ESTABLISHED: + sk = __inet6_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, ntohs(dport), + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } + break; + case IPPROTO_UDP: + sk = udp6_lib_lookup(net, saddr, sport, daddr, dport, + in->ifindex); + if (sk && lookup_type != NFT_LOOKUP_ANY) { + int connected = (sk->sk_state == TCP_ESTABLISHED); + int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type == NFT_LOOKUP_LISTENER && connected)) { + sock_put(sk); + sk = NULL; + } + } + break; + default: + WARN_ON(1); + sk = NULL; + } + + pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n", + protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk); + + return sk; +} +#endif static inline void nf_tproxy_put_sock(struct sock *sk) -- cgit v1.2.3 From 6ad7889327a5ee6ab4220bd34e4428c7d0de0f32 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:17:26 +0200 Subject: tproxy: added IPv6 support to the TPROXY target This requires a new revision as the old target structure was IPv4 specific. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/linux/netfilter/xt_TPROXY.h | 13 +- net/netfilter/xt_TPROXY.c | 262 +++++++++++++++++++++++++++++++----- 2 files changed, 235 insertions(+), 40 deletions(-) diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h index 152e8f97132b..3f3d69361289 100644 --- a/include/linux/netfilter/xt_TPROXY.h +++ b/include/linux/netfilter/xt_TPROXY.h @@ -1,5 +1,5 @@ -#ifndef _XT_TPROXY_H_target -#define _XT_TPROXY_H_target +#ifndef _XT_TPROXY_H +#define _XT_TPROXY_H /* TPROXY target is capable of marking the packet to perform * redirection. We can get rid of that whenever we get support for @@ -11,4 +11,11 @@ struct xt_tproxy_target_info { __be16 lport; }; -#endif /* _XT_TPROXY_H_target */ +struct xt_tproxy_target_info_v1 { + u_int32_t mark_mask; + u_int32_t mark_value; + union nf_inet_addr laddr; + __be16 lport; +}; + +#endif /* _XT_TPROXY_H */ diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index e0b6900a92c1..d5f97e2302b8 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -1,7 +1,7 @@ /* * Transparent proxy support for Linux/iptables * - * Copyright (c) 2006-2007 BalaBit IT Ltd. + * Copyright (c) 2006-2010 BalaBit IT Ltd. * Author: Balazs Scheidler, Krisztian Kovacs * * This program is free software; you can redistribute it and/or modify @@ -19,15 +19,18 @@ #include #include +#include #include #include +#include #include /** - * tproxy_handle_time_wait() - handle TCP TIME_WAIT reopen redirections + * tproxy_handle_time_wait4() - handle IPv4 TCP TIME_WAIT reopen redirections * @skb: The skb being processed. - * @par: Iptables target parameters. + * @laddr: IPv4 address to redirect to or zero. + * @lport: TCP port to redirect to or zero. * @sk: The TIME_WAIT TCP socket found by the lookup. * * We have to handle SYN packets arriving to TIME_WAIT sockets @@ -35,16 +38,16 @@ * redirect the new connection to the proxy if there's a listener * socket present. * - * tproxy_handle_time_wait() consumes the socket reference passed in. + * tproxy_handle_time_wait4() consumes the socket reference passed in. * * Returns the listener socket if there's one, the TIME_WAIT socket if * no such listener is found, or NULL if the TCP header is incomplete. */ static struct sock * -tproxy_handle_time_wait(struct sk_buff *skb, const struct xt_action_param *par, struct sock *sk) +tproxy_handle_time_wait4(struct sk_buff *skb, __be32 laddr, __be16 lport, + struct sock *sk) { const struct iphdr *iph = ip_hdr(skb); - const struct xt_tproxy_target_info *tgi = par->targinfo; struct tcphdr _hdr, *hp; hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr); @@ -59,13 +62,64 @@ tproxy_handle_time_wait(struct sk_buff *skb, const struct xt_action_param *par, struct sock *sk2; sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, tgi->lport ? tgi->lport : hp->dest, - par->in, NFT_LOOKUP_LISTENER); + iph->saddr, laddr ? laddr : iph->daddr, + hp->source, lport ? lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); + if (sk2) { + inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); + inet_twsk_put(inet_twsk(sk)); + sk = sk2; + } + } + + return sk; +} + +/** + * tproxy_handle_time_wait6() - handle IPv6 TCP TIME_WAIT reopen redirections + * @skb: The skb being processed. + * @tproto: Transport protocol. + * @thoff: Transport protocol header offset. + * @par: Iptables target parameters. + * @sk: The TIME_WAIT TCP socket found by the lookup. + * + * We have to handle SYN packets arriving to TIME_WAIT sockets + * differently: instead of reopening the connection we should rather + * redirect the new connection to the proxy if there's a listener + * socket present. + * + * tproxy_handle_time_wait6() consumes the socket reference passed in. + * + * Returns the listener socket if there's one, the TIME_WAIT socket if + * no such listener is found, or NULL if the TCP header is incomplete. + */ +static struct sock * +tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff, + const struct xt_action_param *par, + struct sock *sk) +{ + const struct ipv6hdr *iph = ipv6_hdr(skb); + struct tcphdr _hdr, *hp; + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + + hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + if (hp == NULL) { + inet_twsk_put(inet_twsk(sk)); + return NULL; + } + + if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { + /* SYN to a TIME_WAIT socket, we'd rather redirect it + * to a listener socket if there's one */ + struct sock *sk2; + + sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, + !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr, + hp->source, + tgi->lport ? tgi->lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); if (sk2) { - /* yeah, there's one, let's kill the TIME_WAIT - * socket and redirect to the listener - */ inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); inet_twsk_put(inet_twsk(sk)); sk = sk2; @@ -76,10 +130,10 @@ tproxy_handle_time_wait(struct sk_buff *skb, const struct xt_action_param *par, } static unsigned int -tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) +tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, + u_int32_t mark_mask, u_int32_t mark_value) { const struct iphdr *iph = ip_hdr(skb); - const struct xt_tproxy_target_info *tgi = par->targinfo; struct udphdr _hdr, *hp; struct sock *sk; @@ -87,18 +141,105 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) if (hp == NULL) return NF_DROP; + /* check if there's an ongoing connection on the packet + * addresses, this happens if the redirect already happened + * and the current packet belongs to an already established + * connection */ sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, iph->saddr, iph->daddr, hp->source, hp->dest, - par->in, NFT_LOOKUP_ESTABLISHED); + skb->dev, NFT_LOOKUP_ESTABLISHED); /* UDP has no TCP_TIME_WAIT state, so we never enter here */ if (sk && sk->sk_state == TCP_TIME_WAIT) - sk = tproxy_handle_time_wait(skb, par, sk); + /* reopening a TIME_WAIT connection needs special handling */ + sk = tproxy_handle_time_wait4(skb, laddr, lport, sk); else if (!sk) + /* no, there's no established connection, check if + * there's a listener on the redirected addr/port */ sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, tgi->lport ? tgi->lport : hp->dest, + iph->saddr, laddr ? laddr : iph->daddr, + hp->source, lport ? lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); + + /* NOTE: assign_sock consumes our sk reference */ + if (sk && nf_tproxy_assign_sock(skb, sk)) { + /* This should be in a separate target, but we don't do multiple + targets on the same rule yet */ + skb->mark = (skb->mark & ~mark_mask) ^ mark_value; + + pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", + iph->protocol, &iph->daddr, ntohs(hp->dest), + &laddr, ntohs(lport), skb->mark); + return NF_ACCEPT; + } + + pr_debug("no socket, dropping: proto %hhu %08x:%hu -> %08x:%hu, mark: %x\n", + iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), + ntohl(laddr), ntohs(lport), skb->mark); + return NF_DROP; +} + +static unsigned int +tproxy_tg4_v0(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_tproxy_target_info *tgi = par->targinfo; + + return tproxy_tg4(skb, tgi->laddr, tgi->lport, tgi->mark_mask, tgi->mark_value); +} + +static unsigned int +tproxy_tg4_v1(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + + return tproxy_tg4(skb, tgi->laddr.ip, tgi->lport, tgi->mark_mask, tgi->mark_value); +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static unsigned int +tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct ipv6hdr *iph = ipv6_hdr(skb); + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + struct udphdr _hdr, *hp; + struct sock *sk; + int thoff; + int tproto; + + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + if (tproto < 0) { + pr_debug("unable to find transport header in IPv6 packet, dropping\n"); + return NF_DROP; + } + + hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + if (hp == NULL) { + pr_debug("unable to grab transport header contents in IPv6 packet, dropping\n"); + return NF_DROP; + } + + /* check if there's an ongoing connection on the packet + * addresses, this happens if the redirect already happened + * and the current packet belongs to an already established + * connection */ + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, &iph->daddr, + hp->source, hp->dest, + par->in, NFT_LOOKUP_ESTABLISHED); + + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ + if (sk && sk->sk_state == TCP_TIME_WAIT) + /* reopening a TIME_WAIT connection needs special handling */ + sk = tproxy_handle_time_wait6(skb, tproto, thoff, par, sk); + else if (!sk) + /* no there's no established connection, check if + * there's a listener on the redirected addr/port */ + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, + !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr, + hp->source, + tgi->lport ? tgi->lport : hp->dest, par->in, NFT_LOOKUP_LISTENER); /* NOTE: assign_sock consumes our sk reference */ @@ -107,19 +248,33 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) targets on the same rule yet */ skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value; - pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n", - iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), - ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark); + pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", + tproto, &iph->saddr, ntohs(hp->dest), + &tgi->laddr.in6, ntohs(tgi->lport), skb->mark); return NF_ACCEPT; } - pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n", - iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), - ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark); + pr_debug("no socket, dropping: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", + tproto, &iph->saddr, ntohs(hp->dest), + &tgi->laddr.in6, ntohs(tgi->lport), skb->mark); return NF_DROP; } -static int tproxy_tg_check(const struct xt_tgchk_param *par) +static int tproxy_tg6_check(const struct xt_tgchk_param *par) +{ + const struct ip6t_ip6 *i = par->entryinfo; + + if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) + && !(i->flags & IP6T_INV_PROTO)) + return 0; + + pr_info("Can be used only in combination with " + "either -p tcp or -p udp\n"); + return -EINVAL; +} +#endif + +static int tproxy_tg4_check(const struct xt_tgchk_param *par) { const struct ipt_ip *i = par->entryinfo; @@ -132,31 +287,64 @@ static int tproxy_tg_check(const struct xt_tgchk_param *par) return -EINVAL; } -static struct xt_target tproxy_tg_reg __read_mostly = { - .name = "TPROXY", - .family = NFPROTO_IPV4, - .table = "mangle", - .target = tproxy_tg, - .targetsize = sizeof(struct xt_tproxy_target_info), - .checkentry = tproxy_tg_check, - .hooks = 1 << NF_INET_PRE_ROUTING, - .me = THIS_MODULE, +static struct xt_target tproxy_tg_reg[] __read_mostly = { + { + .name = "TPROXY", + .family = NFPROTO_IPV4, + .table = "mangle", + .target = tproxy_tg4_v0, + .revision = 0, + .targetsize = sizeof(struct xt_tproxy_target_info), + .checkentry = tproxy_tg4_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, + { + .name = "TPROXY", + .family = NFPROTO_IPV4, + .table = "mangle", + .target = tproxy_tg4_v1, + .revision = 1, + .targetsize = sizeof(struct xt_tproxy_target_info_v1), + .checkentry = tproxy_tg4_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + { + .name = "TPROXY", + .family = NFPROTO_IPV6, + .table = "mangle", + .target = tproxy_tg6_v1, + .revision = 1, + .targetsize = sizeof(struct xt_tproxy_target_info_v1), + .checkentry = tproxy_tg6_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, +#endif + }; static int __init tproxy_tg_init(void) { nf_defrag_ipv4_enable(); - return xt_register_target(&tproxy_tg_reg); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + nf_defrag_ipv6_enable(); +#endif + + return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); } static void __exit tproxy_tg_exit(void) { - xt_unregister_target(&tproxy_tg_reg); + xt_unregister_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); } module_init(tproxy_tg_init); module_exit(tproxy_tg_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Krisztian Kovacs"); +MODULE_AUTHOR("Balazs Scheidler, Krisztian Kovacs"); MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module."); MODULE_ALIAS("ipt_TPROXY"); +MODULE_ALIAS("ip6t_TPROXY"); -- cgit v1.2.3 From a5190b4eea1f1c53ee26b3d1176441cafa8e7f79 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Fri, 15 Oct 2010 12:43:10 +0000 Subject: cxgb3: function namespace cleanup Make local functions static. Remove functions that are defined and never used. Compile tested only. Signed-off-by: Stephen Hemminger Acked-by: Divy Le Ray Signed-off-by: David S. Miller --- drivers/net/cxgb3/adapter.h | 3 - drivers/net/cxgb3/common.h | 18 ---- drivers/net/cxgb3/cxgb3_defs.h | 3 - drivers/net/cxgb3/cxgb3_offload.c | 9 +- drivers/net/cxgb3/mc5.c | 38 -------- drivers/net/cxgb3/sge.c | 39 +------- drivers/net/cxgb3/t3_hw.c | 197 +++----------------------------------- 7 files changed, 18 insertions(+), 289 deletions(-) diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 4cd7f420766a..ef67be59680f 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -336,9 +336,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, int irq_vec_idx, const struct qset_params *p, int ntxq, struct net_device *dev, struct netdev_queue *netdevq); -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data); -irqreturn_t t3_sge_intr_msix(int irq, void *cookie); extern struct workqueue_struct *cxgb3_wq; int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index fe08a004b0dd..5ccb77d078aa 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -673,7 +673,6 @@ void t3_xgm_intr_enable(struct adapter *adapter, int idx); void t3_xgm_intr_disable(struct adapter *adapter, int idx); void t3_port_intr_enable(struct adapter *adapter, int idx); void t3_port_intr_disable(struct adapter *adapter, int idx); -void t3_port_intr_clear(struct adapter *adapter, int idx); int t3_slow_intr_handler(struct adapter *adapter); int t3_phy_intr_handler(struct adapter *adapter); @@ -689,14 +688,10 @@ int t3_check_tpsram_version(struct adapter *adapter); int t3_check_tpsram(struct adapter *adapter, const u8 *tp_ram, unsigned int size); int t3_set_proto_sram(struct adapter *adap, const u8 *data); -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented); int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); int t3_get_fw_version(struct adapter *adapter, u32 *vers); int t3_check_fw_version(struct adapter *adapter); int t3_init_hw(struct adapter *adapter, u32 fw_params); -void mac_prep(struct cmac *mac, struct adapter *adapter, int index); -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); int t3_reset_adapter(struct adapter *adapter); int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, int reset); @@ -706,8 +701,6 @@ void t3_fatal_err(struct adapter *adapter); void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); void t3_config_rss(struct adapter *adapter, unsigned int rss_config, const u8 * cpus, const u16 *rspq); -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map); -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask); int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr, unsigned int n, unsigned int *valp); int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, @@ -731,19 +724,12 @@ void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode); int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, unsigned int nroutes); void t3_mc5_intr_handler(struct mc5 *mc5); -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, unsigned int n, - u32 *buf); -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh); -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size); void t3_tp_set_offload_mode(struct adapter *adap, int enable); void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps); void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], unsigned short alpha[NCCTRL_WIN], unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap); -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]); -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]); void t3_config_trace_filter(struct adapter *adapter, const struct trace_params *tp, int filter_index, int invert, int enable); @@ -769,10 +755,6 @@ int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable); int t3_sge_disable_fl(struct adapter *adapter, unsigned int id); int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id); int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id); -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]); int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, unsigned int credits); diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h index 47e53769af5b..920d918ed193 100644 --- a/drivers/net/cxgb3/cxgb3_defs.h +++ b/drivers/net/cxgb3/cxgb3_defs.h @@ -43,8 +43,6 @@ void *cxgb_alloc_mem(unsigned long size); void cxgb_free_mem(void *addr); -void cxgb_neigh_update(struct neighbour *neigh); -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); /* * Map an ATID or STID to their entries in the corresponding TID tables. @@ -111,7 +109,6 @@ static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t, return &e->t3c_tid; } -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n); int attach_t3cdev(struct t3cdev *dev); void detach_t3cdev(struct t3cdev *dev); #endif diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 21db7491f613..bcf07532953d 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -60,6 +60,9 @@ static LIST_HEAD(adapter_list); static const unsigned int MAX_ATIDS = 64 * 1024; static const unsigned int ATID_BASE = 0x10000; +static void cxgb_neigh_update(struct neighbour *neigh); +static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); + static inline int offload_activated(struct t3cdev *tdev) { const struct adapter *adapter = tdev2adap(tdev); @@ -1015,7 +1018,7 @@ EXPORT_SYMBOL(t3_register_cpl_handler); /* * T3CDEV's receive method. */ -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) +static int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) { while (n--) { struct sk_buff *skb = *skbs++; @@ -1070,7 +1073,7 @@ static int is_offloading(struct net_device *dev) return 0; } -void cxgb_neigh_update(struct neighbour *neigh) +static void cxgb_neigh_update(struct neighbour *neigh) { struct net_device *dev = neigh->dev; @@ -1104,7 +1107,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e) tdev->send(tdev, skb); } -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) +static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) { struct net_device *olddev, *newdev; struct tid_info *ti; diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c index 3b5517b8fbde..a8766fb2f9ab 100644 --- a/drivers/net/cxgb3/mc5.c +++ b/drivers/net/cxgb3/mc5.c @@ -374,44 +374,6 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, return err; } -/* - * read_mc5_range - dump a part of the memory managed by MC5 - * @mc5: the MC5 handle - * @start: the start address for the dump - * @n: number of 72-bit words to read - * @buf: result buffer - * - * Read n 72-bit words from MC5 memory from the given start location. - */ -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, - unsigned int n, u32 *buf) -{ - u32 read_cmd; - int err = 0; - struct adapter *adap = mc5->adapter; - - if (mc5->part_type == IDT75P52100) - read_cmd = IDT_CMD_READ; - else if (mc5->part_type == IDT75N43102) - read_cmd = IDT4_CMD_READ; - else - return -EINVAL; - - mc5_dbgi_mode_enable(mc5); - - while (n--) { - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); - if (mc5_cmd_write(adap, read_cmd)) { - err = -EIO; - break; - } - dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); - buf += 3; - } - - mc5_dbgi_mode_disable(mc5); - return 0; -} #define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 7ad4625dac62..5d72bda54389 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2554,7 +2554,7 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q) * The MSI-X interrupt handler for an SGE response queue for the non-NAPI case * (i.e., response queue serviced in hard interrupt). */ -irqreturn_t t3_sge_intr_msix(int irq, void *cookie) +static irqreturn_t t3_sge_intr_msix(int irq, void *cookie) { struct sge_qset *qs = cookie; struct adapter *adap = qs->adap; @@ -3320,40 +3320,3 @@ void t3_sge_prep(struct adapter *adap, struct sge_params *p) spin_lock_init(&adap->sge.reg_lock); } - -/** - * t3_get_desc - dump an SGE descriptor for debugging purposes - * @qs: the queue set - * @qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx) - * @idx: the descriptor index in the queue - * @data: where to dump the descriptor contents - * - * Dumps the contents of a HW descriptor of an SGE queue. Returns the - * size of the descriptor. - */ -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data) -{ - if (qnum >= 6) - return -EINVAL; - - if (qnum < 3) { - if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size) - return -EINVAL; - memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc)); - return sizeof(struct tx_desc); - } - - if (qnum == 3) { - if (!qs->rspq.desc || idx >= qs->rspq.size) - return -EINVAL; - memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc)); - return sizeof(struct rsp_desc); - } - - qnum -= 4; - if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size) - return -EINVAL; - memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc)); - return sizeof(struct rx_desc); -} diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 421d5589cecd..3a6adf0b3e9d 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -34,6 +34,8 @@ #include "sge_defs.h" #include "firmware_exports.h" +static void t3_port_intr_clear(struct adapter *adapter, int idx); + /** * t3_wait_op_done_val - wait until an operation is completed * @adapter: the adapter performing the operation @@ -840,8 +842,8 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * (i.e., big-endian), otherwise as 32-bit words in the platform's * natural endianess. */ -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented) +static int t3_read_flash(struct adapter *adapter, unsigned int addr, + unsigned int nwords, u32 *data, int byte_oriented) { int ret; @@ -2111,7 +2113,7 @@ void t3_port_intr_disable(struct adapter *adapter, int idx) * Clear port-specific (i.e., MAC and PHY) interrupts for the given * adapter port. */ -void t3_port_intr_clear(struct adapter *adapter, int idx) +static void t3_port_intr_clear(struct adapter *adapter, int idx) { struct cphy *phy = &adap2pinfo(adapter, idx)->phy; @@ -2483,98 +2485,6 @@ int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, return 0; } -/** - * t3_sge_read_context - read an SGE context - * @type: the context type - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -static int t3_sge_read_context(unsigned int type, struct adapter *adapter, - unsigned int id, u32 data[4]) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id)); - if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0, - SG_CONTEXT_CMD_ATTEMPTS, 1)) - return -EIO; - data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0); - data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1); - data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2); - data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3); - return 0; -} - -/** - * t3_sge_read_ecntxt - read an SGE egress context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_EGRESS, adapter, id, data); -} - -/** - * t3_sge_read_cq - read an SGE CQ context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE CQ context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_CQ, adapter, id, data); -} - -/** - * t3_sge_read_fl - read an SGE free-list context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE free-list context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS * 2) - return -EINVAL; - return t3_sge_read_context(F_FREELIST, adapter, id, data); -} - -/** - * t3_sge_read_rspq - read an SGE response queue context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE response queue context. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS) - return -EINVAL; - return t3_sge_read_context(F_RESPONSEQ, adapter, id, data); -} - /** * t3_config_rss - configure Rx packet steering * @adapter: the adapter @@ -2615,42 +2525,6 @@ void t3_config_rss(struct adapter *adapter, unsigned int rss_config, t3_write_reg(adapter, A_TP_RSS_CONFIG, rss_config); } -/** - * t3_read_rss - read the contents of the RSS tables - * @adapter: the adapter - * @lkup: holds the contents of the RSS lookup table - * @map: holds the contents of the RSS map table - * - * Reads the contents of the receive packet steering tables. - */ -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map) -{ - int i; - u32 val; - - if (lkup) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *lkup++ = val; - *lkup++ = (val >> 8); - } - - if (map) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_MAP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *map++ = val; - } - return 0; -} - /** * t3_tp_set_offload_mode - put TP in NIC/offload mode * @adap: the adapter @@ -2868,7 +2742,8 @@ static void tp_set_timers(struct adapter *adap, unsigned int core_clk) * * Set the receive coalescing size and PSH bit handling. */ -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) +static int t3_tp_set_coalescing_size(struct adapter *adap, + unsigned int size, int psh) { u32 val; @@ -2898,7 +2773,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) * Set TP's max receive size. This is the limit that applies when * receive coalescing is disabled. */ -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size) +static void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size) { t3_write_reg(adap, A_TP_PARA_REG7, V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size)); @@ -3017,48 +2892,6 @@ void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], } } -/** - * t3_read_hw_mtus - returns the values in the HW MTU table - * @adap: the adapter - * @mtus: where to store the HW MTU values - * - * Reads the HW MTU table. - */ -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]) -{ - int i; - - for (i = 0; i < NMTUS; ++i) { - unsigned int val; - - t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i); - val = t3_read_reg(adap, A_TP_MTU_TABLE); - mtus[i] = val & 0x3fff; - } -} - -/** - * t3_get_cong_cntl_tab - reads the congestion control table - * @adap: the adapter - * @incr: where to store the alpha values - * - * Reads the additive increments programmed into the HW congestion - * control table. - */ -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]) -{ - unsigned int mtu, w; - - for (mtu = 0; mtu < NMTUS; ++mtu) - for (w = 0; w < NCCTRL_WIN; ++w) { - t3_write_reg(adap, A_TP_CCTRL_TABLE, - 0xffff0000 | (mtu << 5) | w); - incr[mtu][w] = t3_read_reg(adap, A_TP_CCTRL_TABLE) & - 0x1fff; - } -} - /** * t3_tp_get_mib_stats - read TP's MIB counters * @adap: the adapter @@ -3223,15 +3056,6 @@ static int tp_init(struct adapter *adap, const struct tp_params *p) return busy; } -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask) -{ - if (port_mask & ~((1 << adap->params.nports) - 1)) - return -EINVAL; - t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE, - port_mask << S_PORT0ACTIVE); - return 0; -} - /* * Perform the bits of HW initialization that are dependent on the Tx * channels being used. @@ -3687,7 +3511,7 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7, mc7->width = G_WIDTH(cfg); } -void mac_prep(struct cmac *mac, struct adapter *adapter, int index) +static void mac_prep(struct cmac *mac, struct adapter *adapter, int index) { u16 devid; @@ -3707,7 +3531,8 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index) } } -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai) +static void early_hw_init(struct adapter *adapter, + const struct adapter_info *ai) { u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2); -- cgit v1.2.3 From b64c9256a9b76fc9f059f71bd08ba88fb0cbba2e Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:19:42 +0200 Subject: tproxy: added IPv6 support to the socket match The ICMP extraction bits were contributed by Harry Mason. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- net/netfilter/xt_socket.c | 165 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 11 deletions(-) diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 266faa0a2fbf..2dbd4c857735 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include @@ -30,7 +32,7 @@ #endif static int -extract_icmp_fields(const struct sk_buff *skb, +extract_icmp4_fields(const struct sk_buff *skb, u8 *protocol, __be32 *raddr, __be32 *laddr, @@ -86,7 +88,6 @@ extract_icmp_fields(const struct sk_buff *skb, return 0; } - static bool socket_match(const struct sk_buff *skb, struct xt_action_param *par, const struct xt_socket_mtinfo1 *info) @@ -115,7 +116,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, dport = hp->dest; } else if (iph->protocol == IPPROTO_ICMP) { - if (extract_icmp_fields(skb, &protocol, &saddr, &daddr, + if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr, &sport, &dport)) return false; } else { @@ -165,32 +166,157 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, sk = NULL; } - pr_debug("proto %u %08x:%u -> %08x:%u (orig %08x:%u) sock %p\n", - protocol, ntohl(saddr), ntohs(sport), - ntohl(daddr), ntohs(dport), - ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk); + pr_debug("proto %hhu %pI4:%hu -> %pI4:%hu (orig %pI4:%hu) sock %p\n", + protocol, &saddr, ntohs(sport), + &daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); return (sk != NULL); } static bool -socket_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) +socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par) { return socket_match(skb, par, NULL); } static bool -socket_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) +socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par) { return socket_match(skb, par, par->matchinfo); } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static int +extract_icmp6_fields(const struct sk_buff *skb, + unsigned int outside_hdrlen, + u8 *protocol, + struct in6_addr **raddr, + struct in6_addr **laddr, + __be16 *rport, + __be16 *lport) +{ + struct ipv6hdr *inside_iph, _inside_iph; + struct icmp6hdr *icmph, _icmph; + __be16 *ports, _ports[2]; + u8 inside_nexthdr; + int inside_hdrlen; + + icmph = skb_header_pointer(skb, outside_hdrlen, + sizeof(_icmph), &_icmph); + if (icmph == NULL) + return 1; + + if (icmph->icmp6_type & ICMPV6_INFOMSG_MASK) + return 1; + + inside_iph = skb_header_pointer(skb, outside_hdrlen + sizeof(_icmph), sizeof(_inside_iph), &_inside_iph); + if (inside_iph == NULL) + return 1; + inside_nexthdr = inside_iph->nexthdr; + + inside_hdrlen = ipv6_skip_exthdr(skb, outside_hdrlen + sizeof(_icmph) + sizeof(_inside_iph), &inside_nexthdr); + if (inside_hdrlen < 0) + return 1; /* hjm: Packet has no/incomplete transport layer headers. */ + + if (inside_nexthdr != IPPROTO_TCP && + inside_nexthdr != IPPROTO_UDP) + return 1; + + ports = skb_header_pointer(skb, inside_hdrlen, + sizeof(_ports), &_ports); + if (ports == NULL) + return 1; + + /* the inside IP packet is the one quoted from our side, thus + * its saddr is the local address */ + *protocol = inside_nexthdr; + *laddr = &inside_iph->saddr; + *lport = ports[0]; + *raddr = &inside_iph->daddr; + *rport = ports[1]; + + return 0; +} + +static bool +socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) +{ + struct ipv6hdr *iph = ipv6_hdr(skb); + struct udphdr _hdr, *hp = NULL; + struct sock *sk; + struct in6_addr *daddr, *saddr; + __be16 dport, sport; + int thoff; + u8 tproto; + const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; + + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + if (tproto < 0) { + pr_debug("unable to find transport header in IPv6 packet, dropping\n"); + return NF_DROP; + } + + if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) { + hp = skb_header_pointer(skb, thoff, + sizeof(_hdr), &_hdr); + if (hp == NULL) + return false; + + saddr = &iph->saddr; + sport = hp->source; + daddr = &iph->daddr; + dport = hp->dest; + + } else if (tproto == IPPROTO_ICMPV6) { + if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr, + &sport, &dport)) + return false; + } else { + return false; + } + + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); + if (sk != NULL) { + bool wildcard; + bool transparent = true; + + /* Ignore sockets listening on INADDR_ANY */ + wildcard = (sk->sk_state != TCP_TIME_WAIT && + ipv6_addr_any(&inet6_sk(sk)->rcv_saddr)); + + /* Ignore non-transparent sockets, + if XT_SOCKET_TRANSPARENT is used */ + if (info && info->flags & XT_SOCKET_TRANSPARENT) + transparent = ((sk->sk_state != TCP_TIME_WAIT && + inet_sk(sk)->transparent) || + (sk->sk_state == TCP_TIME_WAIT && + inet_twsk(sk)->tw_transparent)); + + nf_tproxy_put_sock(sk); + + if (wildcard || !transparent) + sk = NULL; + } + + pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu " + "(orig %pI6:%hu) sock %p\n", + tproto, saddr, ntohs(sport), + daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); + + return (sk != NULL); +} +#endif + static struct xt_match socket_mt_reg[] __read_mostly = { { .name = "socket", .revision = 0, .family = NFPROTO_IPV4, - .match = socket_mt_v0, + .match = socket_mt4_v0, .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, @@ -199,17 +325,33 @@ static struct xt_match socket_mt_reg[] __read_mostly = { .name = "socket", .revision = 1, .family = NFPROTO_IPV4, - .match = socket_mt_v1, + .match = socket_mt4_v1, .matchsize = sizeof(struct xt_socket_mtinfo1), .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, }, +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + { + .name = "socket", + .revision = 1, + .family = NFPROTO_IPV6, + .match = socket_mt6_v1, + .matchsize = sizeof(struct xt_socket_mtinfo1), + .hooks = (1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN), + .me = THIS_MODULE, + }, +#endif }; static int __init socket_mt_init(void) { nf_defrag_ipv4_enable(); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + nf_defrag_ipv6_enable(); +#endif + return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg)); } @@ -225,3 +367,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler"); MODULE_DESCRIPTION("x_tables socket match module"); MODULE_ALIAS("ipt_socket"); +MODULE_ALIAS("ip6t_socket"); -- cgit v1.2.3 From cc6eb433856983e91071469c4ce57accb6947ccb Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Thu, 21 Oct 2010 16:21:10 +0200 Subject: tproxy: use the interface primary IP address as a default value for --on-ip The REDIRECT target and the older TProxy versions used the primary address of the incoming interface as the default value of the --on-ip parameter. This was unintentionally changed during the initial TProxy submission and caused confusion among users. Since IPv6 has no notion of primary address, we just select the first address on the list: this way the socket lookup finds wildcard bound sockets properly and we cannot really do better without the user telling us the IPv6 address of the proxy. This is implemented for both IPv4 and IPv6. Signed-off-by: Balazs Scheidler Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- net/netfilter/xt_TPROXY.c | 202 ++++++++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 70 deletions(-) diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index d5f97e2302b8..19c482caf30b 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -16,15 +16,41 @@ #include #include #include - +#include #include #include -#include -#include #include +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include +#include +#include #include +#endif + #include +#include + +static inline __be32 +tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr) +{ + struct in_device *indev; + __be32 laddr; + + if (user_laddr) + return user_laddr; + + laddr = 0; + rcu_read_lock(); + indev = __in_dev_get_rcu(skb->dev); + for_primary_ifa(indev) { + laddr = ifa->ifa_local; + break; + } endfor_ifa(indev); + rcu_read_unlock(); + + return laddr ? laddr : daddr; +} /** * tproxy_handle_time_wait4() - handle IPv4 TCP TIME_WAIT reopen redirections @@ -75,60 +101,6 @@ tproxy_handle_time_wait4(struct sk_buff *skb, __be32 laddr, __be16 lport, return sk; } -/** - * tproxy_handle_time_wait6() - handle IPv6 TCP TIME_WAIT reopen redirections - * @skb: The skb being processed. - * @tproto: Transport protocol. - * @thoff: Transport protocol header offset. - * @par: Iptables target parameters. - * @sk: The TIME_WAIT TCP socket found by the lookup. - * - * We have to handle SYN packets arriving to TIME_WAIT sockets - * differently: instead of reopening the connection we should rather - * redirect the new connection to the proxy if there's a listener - * socket present. - * - * tproxy_handle_time_wait6() consumes the socket reference passed in. - * - * Returns the listener socket if there's one, the TIME_WAIT socket if - * no such listener is found, or NULL if the TCP header is incomplete. - */ -static struct sock * -tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff, - const struct xt_action_param *par, - struct sock *sk) -{ - const struct ipv6hdr *iph = ipv6_hdr(skb); - struct tcphdr _hdr, *hp; - const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; - - hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); - if (hp == NULL) { - inet_twsk_put(inet_twsk(sk)); - return NULL; - } - - if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { - /* SYN to a TIME_WAIT socket, we'd rather redirect it - * to a listener socket if there's one */ - struct sock *sk2; - - sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, - &iph->saddr, - !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr, - hp->source, - tgi->lport ? tgi->lport : hp->dest, - skb->dev, NFT_LOOKUP_LISTENER); - if (sk2) { - inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); - inet_twsk_put(inet_twsk(sk)); - sk = sk2; - } - } - - return sk; -} - static unsigned int tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, u_int32_t mark_mask, u_int32_t mark_value) @@ -150,6 +122,10 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, hp->source, hp->dest, skb->dev, NFT_LOOKUP_ESTABLISHED); + laddr = tproxy_laddr4(skb, laddr, iph->daddr); + if (!lport) + lport = hp->dest; + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ if (sk && sk->sk_state == TCP_TIME_WAIT) /* reopening a TIME_WAIT connection needs special handling */ @@ -158,8 +134,8 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, /* no, there's no established connection, check if * there's a listener on the redirected addr/port */ sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, laddr ? laddr : iph->daddr, - hp->source, lport ? lport : hp->dest, + iph->saddr, laddr, + hp->source, lport, skb->dev, NFT_LOOKUP_LISTENER); /* NOTE: assign_sock consumes our sk reference */ @@ -174,9 +150,9 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, return NF_ACCEPT; } - pr_debug("no socket, dropping: proto %hhu %08x:%hu -> %08x:%hu, mark: %x\n", - iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), - ntohl(laddr), ntohs(lport), skb->mark); + pr_debug("no socket, dropping: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", + iph->protocol, &iph->saddr, ntohs(hp->source), + &iph->daddr, ntohs(hp->dest), skb->mark); return NF_DROP; } @@ -197,6 +173,88 @@ tproxy_tg4_v1(struct sk_buff *skb, const struct xt_action_param *par) } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static inline const struct in6_addr * +tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr, + const struct in6_addr *daddr) +{ + struct inet6_dev *indev; + struct inet6_ifaddr *ifa; + struct in6_addr *laddr; + + if (!ipv6_addr_any(user_laddr)) + return user_laddr; + laddr = NULL; + + rcu_read_lock(); + indev = __in6_dev_get(skb->dev); + if (indev) + list_for_each_entry(ifa, &indev->addr_list, if_list) { + if (ifa->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) + continue; + + laddr = &ifa->addr; + break; + } + rcu_read_unlock(); + + return laddr ? laddr : daddr; +} + +/** + * tproxy_handle_time_wait6() - handle IPv6 TCP TIME_WAIT reopen redirections + * @skb: The skb being processed. + * @tproto: Transport protocol. + * @thoff: Transport protocol header offset. + * @par: Iptables target parameters. + * @sk: The TIME_WAIT TCP socket found by the lookup. + * + * We have to handle SYN packets arriving to TIME_WAIT sockets + * differently: instead of reopening the connection we should rather + * redirect the new connection to the proxy if there's a listener + * socket present. + * + * tproxy_handle_time_wait6() consumes the socket reference passed in. + * + * Returns the listener socket if there's one, the TIME_WAIT socket if + * no such listener is found, or NULL if the TCP header is incomplete. + */ +static struct sock * +tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff, + const struct xt_action_param *par, + struct sock *sk) +{ + const struct ipv6hdr *iph = ipv6_hdr(skb); + struct tcphdr _hdr, *hp; + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + + hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + if (hp == NULL) { + inet_twsk_put(inet_twsk(sk)); + return NULL; + } + + if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { + /* SYN to a TIME_WAIT socket, we'd rather redirect it + * to a listener socket if there's one */ + struct sock *sk2; + + sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, + tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr), + hp->source, + tgi->lport ? tgi->lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); + if (sk2) { + inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); + inet_twsk_put(inet_twsk(sk)); + sk = sk2; + } + } + + return sk; +} + static unsigned int tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) { @@ -204,6 +262,8 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; struct udphdr _hdr, *hp; struct sock *sk; + const struct in6_addr *laddr; + __be16 lport; int thoff; int tproto; @@ -228,6 +288,9 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) hp->source, hp->dest, par->in, NFT_LOOKUP_ESTABLISHED); + laddr = tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr); + lport = tgi->lport ? tgi->lport : hp->dest; + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ if (sk && sk->sk_state == TCP_TIME_WAIT) /* reopening a TIME_WAIT connection needs special handling */ @@ -236,10 +299,8 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) /* no there's no established connection, check if * there's a listener on the redirected addr/port */ sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, - &iph->saddr, - !ipv6_addr_any(&tgi->laddr.in6) ? &tgi->laddr.in6 : &iph->daddr, - hp->source, - tgi->lport ? tgi->lport : hp->dest, + &iph->saddr, laddr, + hp->source, lport, par->in, NFT_LOOKUP_LISTENER); /* NOTE: assign_sock consumes our sk reference */ @@ -249,14 +310,15 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value; pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", - tproto, &iph->saddr, ntohs(hp->dest), - &tgi->laddr.in6, ntohs(tgi->lport), skb->mark); + tproto, &iph->saddr, ntohs(hp->source), + laddr, ntohs(lport), skb->mark); return NF_ACCEPT; } pr_debug("no socket, dropping: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", - tproto, &iph->saddr, ntohs(hp->dest), - &tgi->laddr.in6, ntohs(tgi->lport), skb->mark); + tproto, &iph->saddr, ntohs(hp->source), + &iph->daddr, ntohs(hp->dest), skb->mark); + return NF_DROP; } -- cgit v1.2.3 From 0988c4c7fb5881377ec20a6452f739a722e97c6b Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 21 Oct 2010 11:30:42 +0000 Subject: vlan: Calling vlan_hwaccel_do_receive() is always valid. It is now acceptable to receive vlan tagged packets at any time, even if CONFIG_VLAN_8021Q is not set. This means that calling vlan_hwaccel_do_receive() should not result in BUG() but rather just behave as if there were no vlan devices configured. Reported-by: Vladislav Zolotarov Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index a0d9786c202d..c2f3a72712ce 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -168,7 +168,8 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb) { - BUG(); + if ((*skb)->vlan_tci & VLAN_VID_MASK) + (*skb)->pkt_type = PACKET_OTHERHOST; return false; } -- cgit v1.2.3 From ec37a48d1d16c30b655ac5280209edf52a6775d4 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 21 Oct 2010 11:30:43 +0000 Subject: bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL. Some cards don't support changing vlan offloading settings. Make Ethtool set_flags return -EINVAL in those cases. Reported-by: Ben Hutchings Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index bf3c830e7dda..062600be073b 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7528,7 +7528,7 @@ bnx2_set_flags(struct net_device *dev, u32 data) if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) && !(data & ETH_FLAG_RXVLAN)) - return -EOPNOTSUPP; + return -EINVAL; rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index daefef618ef7..d02ffbdc9f0e 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1123,7 +1123,7 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data) } if (!(data & ETH_FLAG_RXVLAN)) - return -EOPNOTSUPP; + return -EINVAL; if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa) return -EINVAL; -- cgit v1.2.3